summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-08-05 17:04:01 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-08-05 17:04:01 -0300
commit57f0f512b273f60d52568b8c6b77e17f5636edc0 (patch)
tree5e910f0e82173f4ef4f51111366a3f1299037a7b /arch/arm
Initial import
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig2121
-rw-r--r--arch/arm/Kconfig-nommu64
-rw-r--r--arch/arm/Kconfig.debug1604
-rw-r--r--arch/arm/Makefile355
-rw-r--r--arch/arm/boot/.gitignore6
-rw-r--r--arch/arm/boot/Makefile118
-rw-r--r--arch/arm/boot/bootp/Makefile29
-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/.gitignore21
-rw-r--r--arch/arm/boot/compressed/Makefile190
-rw-r--r--arch/arm/boot/compressed/atags_to_fdt.c191
-rw-r--r--arch/arm/boot/compressed/big-endian.S13
-rw-r--r--arch/arm/boot/compressed/debug.S40
-rw-r--r--arch/arm/boot/compressed/decompress.c61
-rw-r--r--arch/arm/boot/compressed/head-sa1100.S48
-rw-r--r--arch/arm/boot/compressed/head-sharpsl.S150
-rw-r--r--arch/arm/boot/compressed/head-shmobile.S71
-rw-r--r--arch/arm/boot/compressed/head-xscale.S34
-rw-r--r--arch/arm/boot/compressed/head.S1359
-rw-r--r--arch/arm/boot/compressed/libfdt_env.h15
-rw-r--r--arch/arm/boot/compressed/ll_char_wr.S134
-rw-r--r--arch/arm/boot/compressed/misc.c168
-rw-r--r--arch/arm/boot/compressed/piggy.gzip.S6
-rw-r--r--arch/arm/boot/compressed/piggy.lz4.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/piggy.xzkern.S6
-rw-r--r--arch/arm/boot/compressed/string.c127
-rw-r--r--arch/arm/boot/compressed/vmlinux.lds.S87
-rw-r--r--arch/arm/boot/dts/Makefile666
-rw-r--r--arch/arm/boot/dts/aks-cdu.dts119
-rw-r--r--arch/arm/boot/dts/alphascale-asm9260-devkit.dts13
-rw-r--r--arch/arm/boot/dts/alphascale-asm9260.dtsi63
-rw-r--r--arch/arm/boot/dts/alpine-db.dts35
-rw-r--r--arch/arm/boot/dts/alpine.dtsi160
-rw-r--r--arch/arm/boot/dts/am335x-base0033.dts95
-rw-r--r--arch/arm/boot/dts/am335x-bone-common.dtsi330
-rw-r--r--arch/arm/boot/dts/am335x-bone.dts26
-rw-r--r--arch/arm/boot/dts/am335x-boneblack.dts82
-rw-r--r--arch/arm/boot/dts/am335x-chiliboard.dts112
-rw-r--r--arch/arm/boot/dts/am335x-chilisom.dtsi239
-rw-r--r--arch/arm/boot/dts/am335x-evm.dts680
-rw-r--r--arch/arm/boot/dts/am335x-evmsk.dts691
-rw-r--r--arch/arm/boot/dts/am335x-igep0033.dtsi320
-rw-r--r--arch/arm/boot/dts/am335x-lxm.dts366
-rw-r--r--arch/arm/boot/dts/am335x-nano.dts440
-rw-r--r--arch/arm/boot/dts/am335x-pepper.dts653
-rw-r--r--arch/arm/boot/dts/am33xx-clocks.dtsi646
-rw-r--r--arch/arm/boot/dts/am33xx.dtsi876
-rw-r--r--arch/arm/boot/dts/am3517-craneboard.dts174
-rw-r--r--arch/arm/boot/dts/am3517-evm.dts61
-rw-r--r--arch/arm/boot/dts/am3517.dtsi83
-rw-r--r--arch/arm/boot/dts/am3517_mt_ventoux.dts27
-rw-r--r--arch/arm/boot/dts/am35xx-clocks.dtsi128
-rw-r--r--arch/arm/boot/dts/am4372.dtsi992
-rw-r--r--arch/arm/boot/dts/am437x-gp-evm.dts652
-rw-r--r--arch/arm/boot/dts/am437x-idk-evm.dts406
-rw-r--r--arch/arm/boot/dts/am437x-sk-evm.dts700
-rw-r--r--arch/arm/boot/dts/am43x-epos-evm.dts688
-rw-r--r--arch/arm/boot/dts/am43xx-clocks.dtsi757
-rw-r--r--arch/arm/boot/dts/am57xx-beagle-x15.dts610
-rw-r--r--arch/arm/boot/dts/animeo_ip.dts175
-rw-r--r--arch/arm/boot/dts/arm-realview-pb1176.dts412
-rw-r--r--arch/arm/boot/dts/armada-370-db.dts248
-rw-r--r--arch/arm/boot/dts/armada-370-mirabox.dts206
-rw-r--r--arch/arm/boot/dts/armada-370-netgear-rn102.dts293
-rw-r--r--arch/arm/boot/dts/armada-370-netgear-rn104.dts305
-rw-r--r--arch/arm/boot/dts/armada-370-rd.dts249
-rw-r--r--arch/arm/boot/dts/armada-370-synology-ds213j.dts348
-rw-r--r--arch/arm/boot/dts/armada-370-xp.dtsi335
-rw-r--r--arch/arm/boot/dts/armada-370.dtsi408
-rw-r--r--arch/arm/boot/dts/armada-375-db.dts204
-rw-r--r--arch/arm/boot/dts/armada-375.dtsi617
-rw-r--r--arch/arm/boot/dts/armada-380.dtsi152
-rw-r--r--arch/arm/boot/dts/armada-385-db-ap.dts218
-rw-r--r--arch/arm/boot/dts/armada-385.dtsi184
-rw-r--r--arch/arm/boot/dts/armada-388-db.dts186
-rw-r--r--arch/arm/boot/dts/armada-388-gp.dts413
-rw-r--r--arch/arm/boot/dts/armada-388-rd.dts142
-rw-r--r--arch/arm/boot/dts/armada-388.dtsi70
-rw-r--r--arch/arm/boot/dts/armada-38x.dtsi598
-rw-r--r--arch/arm/boot/dts/armada-390.dtsi57
-rw-r--r--arch/arm/boot/dts/armada-398-db.dts153
-rw-r--r--arch/arm/boot/dts/armada-398.dtsi60
-rw-r--r--arch/arm/boot/dts/armada-39x.dtsi508
-rw-r--r--arch/arm/boot/dts/armada-xp-axpwifiap.dts179
-rw-r--r--arch/arm/boot/dts/armada-xp-db.dts232
-rw-r--r--arch/arm/boot/dts/armada-xp-gp.dts245
-rw-r--r--arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts325
-rw-r--r--arch/arm/boot/dts/armada-xp-linksys-mamba.dts398
-rw-r--r--arch/arm/boot/dts/armada-xp-matrix.dts114
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78230.dtsi231
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78260.dtsi333
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78460.dtsi371
-rw-r--r--arch/arm/boot/dts/armada-xp-netgear-rn2120.dts370
-rw-r--r--arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts229
-rw-r--r--arch/arm/boot/dts/armada-xp-synology-ds414.dts362
-rw-r--r--arch/arm/boot/dts/armada-xp.dtsi312
-rw-r--r--arch/arm/boot/dts/armv7-m.dtsi18
-rw-r--r--arch/arm/boot/dts/at91-ariag25.dts187
-rw-r--r--arch/arm/boot/dts/at91-cosino.dtsi129
-rw-r--r--arch/arm/boot/dts/at91-cosino_mega2560.dts78
-rw-r--r--arch/arm/boot/dts/at91-foxg20.dts165
-rw-r--r--arch/arm/boot/dts/at91-qil_a9260.dts193
-rw-r--r--arch/arm/boot/dts/at91-sama5d3_xplained.dts315
-rw-r--r--arch/arm/boot/dts/at91-sama5d4_xplained.dts241
-rw-r--r--arch/arm/boot/dts/at91-sama5d4ek.dts311
-rw-r--r--arch/arm/boot/dts/at91rm9200.dtsi963
-rw-r--r--arch/arm/boot/dts/at91rm9200_pqfp.dtsi17
-rw-r--r--arch/arm/boot/dts/at91rm9200ek.dts141
-rw-r--r--arch/arm/boot/dts/at91sam9260.dtsi1031
-rw-r--r--arch/arm/boot/dts/at91sam9261.dtsi873
-rw-r--r--arch/arm/boot/dts/at91sam9261ek.dts219
-rw-r--r--arch/arm/boot/dts/at91sam9263.dtsi1031
-rw-r--r--arch/arm/boot/dts/at91sam9263ek.dts235
-rw-r--r--arch/arm/boot/dts/at91sam9g15.dtsi28
-rw-r--r--arch/arm/boot/dts/at91sam9g15ek.dts16
-rw-r--r--arch/arm/boot/dts/at91sam9g20.dtsi68
-rw-r--r--arch/arm/boot/dts/at91sam9g20ek.dts29
-rw-r--r--arch/arm/boot/dts/at91sam9g20ek_2mmc.dts55
-rw-r--r--arch/arm/boot/dts/at91sam9g20ek_common.dtsi233
-rw-r--r--arch/arm/boot/dts/at91sam9g25.dtsi31
-rw-r--r--arch/arm/boot/dts/at91sam9g25ek.dts43
-rw-r--r--arch/arm/boot/dts/at91sam9g35.dtsi29
-rw-r--r--arch/arm/boot/dts/at91sam9g35ek.dts25
-rw-r--r--arch/arm/boot/dts/at91sam9g45.dtsi1321
-rw-r--r--arch/arm/boot/dts/at91sam9m10g45ek.dts316
-rw-r--r--arch/arm/boot/dts/at91sam9n12.dtsi971
-rw-r--r--arch/arm/boot/dts/at91sam9n12ek.dts213
-rw-r--r--arch/arm/boot/dts/at91sam9rl.dtsi1118
-rw-r--r--arch/arm/boot/dts/at91sam9rlek.dts247
-rw-r--r--arch/arm/boot/dts/at91sam9x25.dtsi32
-rw-r--r--arch/arm/boot/dts/at91sam9x25ek.dts30
-rw-r--r--arch/arm/boot/dts/at91sam9x35.dtsi30
-rw-r--r--arch/arm/boot/dts/at91sam9x35ek.dts25
-rw-r--r--arch/arm/boot/dts/at91sam9x5.dtsi1238
-rw-r--r--arch/arm/boot/dts/at91sam9x5_can.dtsi71
-rw-r--r--arch/arm/boot/dts/at91sam9x5_isi.dtsi72
-rw-r--r--arch/arm/boot/dts/at91sam9x5_lcd.dtsi26
-rw-r--r--arch/arm/boot/dts/at91sam9x5_macb0.dtsi67
-rw-r--r--arch/arm/boot/dts/at91sam9x5_macb1.dtsi55
-rw-r--r--arch/arm/boot/dts/at91sam9x5_usart3.dtsi69
-rw-r--r--arch/arm/boot/dts/at91sam9x5cm.dtsi111
-rw-r--r--arch/arm/boot/dts/at91sam9x5ek.dtsi189
-rw-r--r--arch/arm/boot/dts/at91sam9xe.dtsi60
-rw-r--r--arch/arm/boot/dts/atlas6-evb.dts78
-rw-r--r--arch/arm/boot/dts/atlas6.dtsi802
-rw-r--r--arch/arm/boot/dts/atlas7-evb.dts110
-rw-r--r--arch/arm/boot/dts/atlas7.dtsi813
-rw-r--r--arch/arm/boot/dts/axm5516-amarillo.dts51
-rw-r--r--arch/arm/boot/dts/axm5516-cpus.dtsi204
-rw-r--r--arch/arm/boot/dts/axm55xx.dtsi204
-rw-r--r--arch/arm/boot/dts/axp209.dtsi97
-rw-r--r--arch/arm/boot/dts/bcm-cygnus-clock.dtsi91
-rw-r--r--arch/arm/boot/dts/bcm-cygnus.dtsi238
-rw-r--r--arch/arm/boot/dts/bcm11351.dtsi424
-rw-r--r--arch/arm/boot/dts/bcm21664-garnet.dts56
-rw-r--r--arch/arm/boot/dts/bcm21664.dtsi357
-rw-r--r--arch/arm/boot/dts/bcm28155-ap.dts121
-rw-r--r--arch/arm/boot/dts/bcm2835-rpi-b-plus.dts30
-rw-r--r--arch/arm/boot/dts/bcm2835-rpi-b.dts23
-rw-r--r--arch/arm/boot/dts/bcm2835-rpi.dtsi51
-rw-r--r--arch/arm/boot/dts/bcm2835.dtsi183
-rw-r--r--arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts130
-rw-r--r--arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts60
-rw-r--r--arch/arm/boot/dts/bcm4708-netgear-r6250.dts93
-rw-r--r--arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts83
-rw-r--r--arch/arm/boot/dts/bcm4708.dtsi34
-rw-r--r--arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts77
-rw-r--r--arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts123
-rw-r--r--arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts37
-rw-r--r--arch/arm/boot/dts/bcm47081.dtsi26
-rw-r--r--arch/arm/boot/dts/bcm4709-netgear-r8000.dts77
-rw-r--r--arch/arm/boot/dts/bcm5301x.dtsi146
-rw-r--r--arch/arm/boot/dts/bcm59056.dtsi95
-rw-r--r--arch/arm/boot/dts/bcm63138.dtsi135
-rw-r--r--arch/arm/boot/dts/bcm7445-bcm97445svmb.dts14
-rw-r--r--arch/arm/boot/dts/bcm7445.dtsi123
-rw-r--r--arch/arm/boot/dts/bcm911360_entphn.dts66
-rw-r--r--arch/arm/boot/dts/bcm911360k.dts53
-rw-r--r--arch/arm/boot/dts/bcm958300k.dts61
-rw-r--r--arch/arm/boot/dts/bcm958305k.dts53
-rw-r--r--arch/arm/boot/dts/bcm963138dvt.dts30
-rw-r--r--arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts45
-rw-r--r--arch/arm/boot/dts/berlin2.dtsi474
-rw-r--r--arch/arm/boot/dts/berlin2cd-google-chromecast.dts59
-rw-r--r--arch/arm/boot/dts/berlin2cd.dtsi406
-rw-r--r--arch/arm/boot/dts/berlin2q-marvell-dmp.dts114
-rw-r--r--arch/arm/boot/dts/berlin2q.dtsi563
-rw-r--r--arch/arm/boot/dts/cros-adc-thermistors.dtsi44
-rw-r--r--arch/arm/boot/dts/cros-ec-keyboard.dtsi105
-rw-r--r--arch/arm/boot/dts/cx92755.dtsi113
-rw-r--r--arch/arm/boot/dts/cx92755_equinox.dts74
-rw-r--r--arch/arm/boot/dts/da850-enbw-cmc.dts30
-rw-r--r--arch/arm/boot/dts/da850-evm.dts244
-rw-r--r--arch/arm/boot/dts/da850.dtsi306
-rw-r--r--arch/arm/boot/dts/dm8168-evm.dts173
-rw-r--r--arch/arm/boot/dts/dm816x-clocks.dtsi250
-rw-r--r--arch/arm/boot/dts/dm816x.dtsi488
-rw-r--r--arch/arm/boot/dts/dove-cm-a510.dts38
-rw-r--r--arch/arm/boot/dts/dove-cubox-es.dts12
-rw-r--r--arch/arm/boot/dts/dove-cubox.dts134
-rw-r--r--arch/arm/boot/dts/dove-d2plug.dts69
-rw-r--r--arch/arm/boot/dts/dove-d3plug.dts103
-rw-r--r--arch/arm/boot/dts/dove-dove-db.dts38
-rw-r--r--arch/arm/boot/dts/dove.dtsi704
-rw-r--r--arch/arm/boot/dts/dra7-evm.dts692
-rw-r--r--arch/arm/boot/dts/dra7.dtsi1486
-rw-r--r--arch/arm/boot/dts/dra72-evm.dts568
-rw-r--r--arch/arm/boot/dts/dra72x.dtsi36
-rw-r--r--arch/arm/boot/dts/dra74x.dtsi75
-rw-r--r--arch/arm/boot/dts/dra7xx-clocks.dtsi2138
-rw-r--r--arch/arm/boot/dts/ea3250.dts281
-rw-r--r--arch/arm/boot/dts/ecx-2000.dts114
-rw-r--r--arch/arm/boot/dts/ecx-common.dtsi241
-rw-r--r--arch/arm/boot/dts/efm32gg-dk3750.dts86
-rw-r--r--arch/arm/boot/dts/efm32gg.dtsi172
-rw-r--r--arch/arm/boot/dts/elpida_ecb240abacn.dtsi67
-rw-r--r--arch/arm/boot/dts/emev2-kzm9d.dts109
-rw-r--r--arch/arm/boot/dts/emev2.dtsi237
-rw-r--r--arch/arm/boot/dts/ethernut5.dts94
-rw-r--r--arch/arm/boot/dts/evk-pro3.dts59
-rw-r--r--arch/arm/boot/dts/exynos3250-monk.dts636
-rw-r--r--arch/arm/boot/dts/exynos3250-pinctrl.dtsi491
-rw-r--r--arch/arm/boot/dts/exynos3250-rinato.dts809
-rw-r--r--arch/arm/boot/dts/exynos3250.dtsi631
-rw-r--r--arch/arm/boot/dts/exynos4-cpu-thermal.dtsi52
-rw-r--r--arch/arm/boot/dts/exynos4.dtsi822
-rw-r--r--arch/arm/boot/dts/exynos4210-origen.dts337
-rw-r--r--arch/arm/boot/dts/exynos4210-pinctrl.dtsi847
-rw-r--r--arch/arm/boot/dts/exynos4210-smdkv310.dts210
-rw-r--r--arch/arm/boot/dts/exynos4210-trats.dts485
-rw-r--r--arch/arm/boot/dts/exynos4210-universal_c210.dts569
-rw-r--r--arch/arm/boot/dts/exynos4210.dtsi247
-rw-r--r--arch/arm/boot/dts/exynos4212.dtsi52
-rw-r--r--arch/arm/boot/dts/exynos4412-odroid-common.dtsi509
-rw-r--r--arch/arm/boot/dts/exynos4412-odroidu3.dts63
-rw-r--r--arch/arm/boot/dts/exynos4412-odroidx.dts85
-rw-r--r--arch/arm/boot/dts/exynos4412-odroidx2.dts36
-rw-r--r--arch/arm/boot/dts/exynos4412-origen.dts534
-rw-r--r--arch/arm/boot/dts/exynos4412-smdk4412.dts162
-rw-r--r--arch/arm/boot/dts/exynos4412-tiny4412.dts97
-rw-r--r--arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi24
-rw-r--r--arch/arm/boot/dts/exynos4412-trats2.dts1306
-rw-r--r--arch/arm/boot/dts/exynos4412.dtsi72
-rw-r--r--arch/arm/boot/dts/exynos4415-pinctrl.dtsi573
-rw-r--r--arch/arm/boot/dts/exynos4415.dtsi638
-rw-r--r--arch/arm/boot/dts/exynos4x12-pinctrl.dtsi972
-rw-r--r--arch/arm/boot/dts/exynos4x12.dtsi312
-rw-r--r--arch/arm/boot/dts/exynos5.dtsi110
-rw-r--r--arch/arm/boot/dts/exynos5250-arndale.dts562
-rw-r--r--arch/arm/boot/dts/exynos5250-pinctrl.dtsi818
-rw-r--r--arch/arm/boot/dts/exynos5250-smdk5250.dts412
-rw-r--r--arch/arm/boot/dts/exynos5250-snow.dts703
-rw-r--r--arch/arm/boot/dts/exynos5250-spring.dts559
-rw-r--r--arch/arm/boot/dts/exynos5250.dtsi814
-rw-r--r--arch/arm/boot/dts/exynos5260-pinctrl.dtsi574
-rw-r--r--arch/arm/boot/dts/exynos5260-xyref5260.dts95
-rw-r--r--arch/arm/boot/dts/exynos5260.dtsi313
-rw-r--r--arch/arm/boot/dts/exynos5410-smdk5410.dts74
-rw-r--r--arch/arm/boot/dts/exynos5410.dtsi221
-rw-r--r--arch/arm/boot/dts/exynos5420-arndale-octa.dts378
-rw-r--r--arch/arm/boot/dts/exynos5420-peach-pit.dts1060
-rw-r--r--arch/arm/boot/dts/exynos5420-pinctrl.dtsi722
-rw-r--r--arch/arm/boot/dts/exynos5420-smdk5420.dts422
-rw-r--r--arch/arm/boot/dts/exynos5420-trip-points.dtsi35
-rw-r--r--arch/arm/boot/dts/exynos5420.dtsi965
-rw-r--r--arch/arm/boot/dts/exynos5422-odroidxu3.dts388
-rw-r--r--arch/arm/boot/dts/exynos5440-sd5v1.dts39
-rw-r--r--arch/arm/boot/dts/exynos5440-ssdk5440.dts78
-rw-r--r--arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi24
-rw-r--r--arch/arm/boot/dts/exynos5440-trip-points.dtsi25
-rw-r--r--arch/arm/boot/dts/exynos5440.dtsi323
-rw-r--r--arch/arm/boot/dts/exynos5800-peach-pi.dts1023
-rw-r--r--arch/arm/boot/dts/exynos5800.dtsi28
-rw-r--r--arch/arm/boot/dts/ge863-pro3.dtsi56
-rw-r--r--arch/arm/boot/dts/hi3620-hi4511.dts649
-rw-r--r--arch/arm/boot/dts/hi3620.dtsi566
-rw-r--r--arch/arm/boot/dts/highbank.dts142
-rw-r--r--arch/arm/boot/dts/hip01-ca9x2.dts51
-rw-r--r--arch/arm/boot/dts/hip01.dtsi110
-rw-r--r--arch/arm/boot/dts/hip04-d01.dts32
-rw-r--r--arch/arm/boot/dts/hip04.dtsi983
-rw-r--r--arch/arm/boot/dts/hisi-x5hd2-dkb.dts86
-rw-r--r--arch/arm/boot/dts/hisi-x5hd2.dtsi556
-rw-r--r--arch/arm/boot/dts/imx1-ads.dts152
-rw-r--r--arch/arm/boot/dts/imx1-apf9328.dts129
-rw-r--r--arch/arm/boot/dts/imx1-pinfunc.h302
-rw-r--r--arch/arm/boot/dts/imx1.dtsi266
-rw-r--r--arch/arm/boot/dts/imx23-evk.dts159
-rw-r--r--arch/arm/boot/dts/imx23-olinuxino.dts130
-rw-r--r--arch/arm/boot/dts/imx23-pinfunc.h333
-rw-r--r--arch/arm/boot/dts/imx23-stmp378x_devb.dts81
-rw-r--r--arch/arm/boot/dts/imx23.dtsi536
-rw-r--r--arch/arm/boot/dts/imx25-eukrea-cpuimx25.dtsi73
-rw-r--r--arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-cmo-qvga.dts73
-rw-r--r--arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-dvi-svga.dts45
-rw-r--r--arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dts45
-rw-r--r--arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts186
-rw-r--r--arch/arm/boot/dts/imx25-karo-tx25.dts113
-rw-r--r--arch/arm/boot/dts/imx25-pdk.dts315
-rw-r--r--arch/arm/boot/dts/imx25-pinfunc.h577
-rw-r--r--arch/arm/boot/dts/imx25.dtsi570
-rw-r--r--arch/arm/boot/dts/imx27-apf27.dts124
-rw-r--r--arch/arm/boot/dts/imx27-apf27dev.dts264
-rw-r--r--arch/arm/boot/dts/imx27-eukrea-cpuimx27.dtsi296
-rw-r--r--arch/arm/boot/dts/imx27-eukrea-mbimxsd27-baseboard.dts273
-rw-r--r--arch/arm/boot/dts/imx27-pdk.dts197
-rw-r--r--arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts168
-rw-r--r--arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi103
-rw-r--r--arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts324
-rw-r--r--arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi349
-rw-r--r--arch/arm/boot/dts/imx27-pinfunc.h480
-rw-r--r--arch/arm/boot/dts/imx27.dtsi577
-rw-r--r--arch/arm/boot/dts/imx28-apf28.dts85
-rw-r--r--arch/arm/boot/dts/imx28-apf28dev.dts231
-rw-r--r--arch/arm/boot/dts/imx28-apx4devkit.dts226
-rw-r--r--arch/arm/boot/dts/imx28-cfa10036.dts141
-rw-r--r--arch/arm/boot/dts/imx28-cfa10037.dts89
-rw-r--r--arch/arm/boot/dts/imx28-cfa10049.dts436
-rw-r--r--arch/arm/boot/dts/imx28-cfa10055.dts167
-rw-r--r--arch/arm/boot/dts/imx28-cfa10056.dts119
-rw-r--r--arch/arm/boot/dts/imx28-cfa10057.dts177
-rw-r--r--arch/arm/boot/dts/imx28-cfa10058.dts144
-rw-r--r--arch/arm/boot/dts/imx28-duckbill.dts121
-rw-r--r--arch/arm/boot/dts/imx28-eukrea-mbmx283lc.dts71
-rw-r--r--arch/arm/boot/dts/imx28-eukrea-mbmx287lc.dts50
-rw-r--r--arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi326
-rw-r--r--arch/arm/boot/dts/imx28-evk.dts378
-rw-r--r--arch/arm/boot/dts/imx28-m28.dtsi87
-rw-r--r--arch/arm/boot/dts/imx28-m28cu3.dts271
-rw-r--r--arch/arm/boot/dts/imx28-m28evk.dts275
-rw-r--r--arch/arm/boot/dts/imx28-pinfunc.h506
-rw-r--r--arch/arm/boot/dts/imx28-sps1.dts171
-rw-r--r--arch/arm/boot/dts/imx28-tx28.dts722
-rw-r--r--arch/arm/boot/dts/imx28.dtsi1250
-rw-r--r--arch/arm/boot/dts/imx31-bug.dts27
-rw-r--r--arch/arm/boot/dts/imx31.dtsi138
-rw-r--r--arch/arm/boot/dts/imx35-eukrea-cpuimx35.dtsi96
-rw-r--r--arch/arm/boot/dts/imx35-eukrea-mbimxsd35-baseboard.dts164
-rw-r--r--arch/arm/boot/dts/imx35-pdk.dts68
-rw-r--r--arch/arm/boot/dts/imx35-pinfunc.h970
-rw-r--r--arch/arm/boot/dts/imx35.dtsi386
-rw-r--r--arch/arm/boot/dts/imx50-evk.dts119
-rw-r--r--arch/arm/boot/dts/imx50-pinfunc.h923
-rw-r--r--arch/arm/boot/dts/imx50.dtsi492
-rw-r--r--arch/arm/boot/dts/imx51-apf51.dts89
-rw-r--r--arch/arm/boot/dts/imx51-apf51dev.dts225
-rw-r--r--arch/arm/boot/dts/imx51-babbage.dts655
-rw-r--r--arch/arm/boot/dts/imx51-digi-connectcore-jsk.dts108
-rw-r--r--arch/arm/boot/dts/imx51-digi-connectcore-som.dtsi377
-rw-r--r--arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi104
-rw-r--r--arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts294
-rw-r--r--arch/arm/boot/dts/imx51-pinfunc.h773
-rw-r--r--arch/arm/boot/dts/imx51.dtsi592
-rw-r--r--arch/arm/boot/dts/imx53-ard.dts183
-rw-r--r--arch/arm/boot/dts/imx53-m53.dtsi140
-rw-r--r--arch/arm/boot/dts/imx53-m53evk.dts356
-rw-r--r--arch/arm/boot/dts/imx53-mba53.dts255
-rw-r--r--arch/arm/boot/dts/imx53-pinfunc.h1189
-rw-r--r--arch/arm/boot/dts/imx53-qsb-common.dtsi366
-rw-r--r--arch/arm/boot/dts/imx53-qsb.dts115
-rw-r--r--arch/arm/boot/dts/imx53-qsrb.dts166
-rw-r--r--arch/arm/boot/dts/imx53-smd.dts279
-rw-r--r--arch/arm/boot/dts/imx53-tqma53.dtsi288
-rw-r--r--arch/arm/boot/dts/imx53-tx53-x03x.dts324
-rw-r--r--arch/arm/boot/dts/imx53-tx53-x13x.dts243
-rw-r--r--arch/arm/boot/dts/imx53-tx53.dtsi549
-rw-r--r--arch/arm/boot/dts/imx53-voipac-bsb.dts158
-rw-r--r--arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi277
-rw-r--r--arch/arm/boot/dts/imx53.dtsi793
-rw-r--r--arch/arm/boot/dts/imx6dl-aristainetos_4.dts89
-rw-r--r--arch/arm/boot/dts/imx6dl-aristainetos_7.dts78
-rw-r--r--arch/arm/boot/dts/imx6dl-cubox-i.dts50
-rw-r--r--arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts23
-rw-r--r--arch/arm/boot/dts/imx6dl-gw51xx.dts19
-rw-r--r--arch/arm/boot/dts/imx6dl-gw52xx.dts19
-rw-r--r--arch/arm/boot/dts/imx6dl-gw53xx.dts19
-rw-r--r--arch/arm/boot/dts/imx6dl-gw54xx.dts19
-rw-r--r--arch/arm/boot/dts/imx6dl-gw552x.dts20
-rw-r--r--arch/arm/boot/dts/imx6dl-hummingboard.dts51
-rw-r--r--arch/arm/boot/dts/imx6dl-nitrogen6x.dts21
-rw-r--r--arch/arm/boot/dts/imx6dl-phytec-pbab01.dts19
-rw-r--r--arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi22
-rw-r--r--arch/arm/boot/dts/imx6dl-pinfunc.h1091
-rw-r--r--arch/arm/boot/dts/imx6dl-rex-basic.dts30
-rw-r--r--arch/arm/boot/dts/imx6dl-riotboard.dts538
-rw-r--r--arch/arm/boot/dts/imx6dl-sabreauto.dts17
-rw-r--r--arch/arm/boot/dts/imx6dl-sabrelite.dts20
-rw-r--r--arch/arm/boot/dts/imx6dl-sabresd.dts17
-rw-r--r--arch/arm/boot/dts/imx6dl-tx6dl-comtft.dts103
-rw-r--r--arch/arm/boot/dts/imx6dl-tx6u-801x.dts177
-rw-r--r--arch/arm/boot/dts/imx6dl-tx6u-811x.dts150
-rw-r--r--arch/arm/boot/dts/imx6dl-udoo.dts18
-rw-r--r--arch/arm/boot/dts/imx6dl-wandboard-revb1.dts22
-rw-r--r--arch/arm/boot/dts/imx6dl-wandboard.dts22
-rw-r--r--arch/arm/boot/dts/imx6dl.dtsi124
-rw-r--r--arch/arm/boot/dts/imx6q-arm2.dts228
-rw-r--r--arch/arm/boot/dts/imx6q-cm-fx6.dts107
-rw-r--r--arch/arm/boot/dts/imx6q-cubox-i.dts58
-rw-r--r--arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts23
-rw-r--r--arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts487
-rw-r--r--arch/arm/boot/dts/imx6q-gk802.dts176
-rw-r--r--arch/arm/boot/dts/imx6q-gw51xx.dts19
-rw-r--r--arch/arm/boot/dts/imx6q-gw52xx.dts23
-rw-r--r--arch/arm/boot/dts/imx6q-gw53xx.dts23
-rw-r--r--arch/arm/boot/dts/imx6q-gw5400-a.dts524
-rw-r--r--arch/arm/boot/dts/imx6q-gw54xx.dts23
-rw-r--r--arch/arm/boot/dts/imx6q-gw552x.dts24
-rw-r--r--arch/arm/boot/dts/imx6q-hummingboard.dts59
-rw-r--r--arch/arm/boot/dts/imx6q-nitrogen6x.dts25
-rw-r--r--arch/arm/boot/dts/imx6q-phytec-pbab01.dts27
-rw-r--r--arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi22
-rw-r--r--arch/arm/boot/dts/imx6q-pinfunc.h1047
-rw-r--r--arch/arm/boot/dts/imx6q-rex-pro.dts34
-rw-r--r--arch/arm/boot/dts/imx6q-sabreauto.dts25
-rw-r--r--arch/arm/boot/dts/imx6q-sabrelite.dts24
-rw-r--r--arch/arm/boot/dts/imx6q-sabresd.dts25
-rw-r--r--arch/arm/boot/dts/imx6q-sbc6x.dts94
-rw-r--r--arch/arm/boot/dts/imx6q-tbs2910.dts432
-rw-r--r--arch/arm/boot/dts/imx6q-tx6q-1010-comtft.dts103
-rw-r--r--arch/arm/boot/dts/imx6q-tx6q-1010.dts177
-rw-r--r--arch/arm/boot/dts/imx6q-tx6q-1020-comtft.dts136
-rw-r--r--arch/arm/boot/dts/imx6q-tx6q-1020.dts210
-rw-r--r--arch/arm/boot/dts/imx6q-tx6q-1110.dts154
-rw-r--r--arch/arm/boot/dts/imx6q-udoo.dts22
-rw-r--r--arch/arm/boot/dts/imx6q-wandboard-revb1.dts26
-rw-r--r--arch/arm/boot/dts/imx6q-wandboard.dts26
-rw-r--r--arch/arm/boot/dts/imx6q.dtsi318
-rw-r--r--arch/arm/boot/dts/imx6qdl-aristainetos.dtsi418
-rw-r--r--arch/arm/boot/dts/imx6qdl-cubox-i.dtsi264
-rw-r--r--arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi199
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw51xx.dtsi333
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw52xx.dtsi476
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw53xx.dtsi483
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw54xx.dtsi574
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw552x.dtsi267
-rw-r--r--arch/arm/boot/dts/imx6qdl-hummingboard.dtsi293
-rw-r--r--arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi100
-rw-r--r--arch/arm/boot/dts/imx6qdl-microsom.dtsi58
-rw-r--r--arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi463
-rw-r--r--arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi181
-rw-r--r--arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi424
-rw-r--r--arch/arm/boot/dts/imx6qdl-rex.dtsi356
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabreauto.dtsi492
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabrelite.dtsi459
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabresd.dtsi586
-rw-r--r--arch/arm/boot/dts/imx6qdl-tx6.dtsi696
-rw-r--r--arch/arm/boot/dts/imx6qdl-udoo.dtsi134
-rw-r--r--arch/arm/boot/dts/imx6qdl-wandboard-revb1.dtsi42
-rw-r--r--arch/arm/boot/dts/imx6qdl-wandboard-revc1.dtsi41
-rw-r--r--arch/arm/boot/dts/imx6qdl-wandboard.dtsi262
-rw-r--r--arch/arm/boot/dts/imx6qdl.dtsi1193
-rw-r--r--arch/arm/boot/dts/imx6sl-evk.dts642
-rw-r--r--arch/arm/boot/dts/imx6sl-pinfunc.h1077
-rw-r--r--arch/arm/boot/dts/imx6sl-warp.dts262
-rw-r--r--arch/arm/boot/dts/imx6sl.dtsi836
-rw-r--r--arch/arm/boot/dts/imx6sx-pinfunc.h1544
-rw-r--r--arch/arm/boot/dts/imx6sx-sabreauto.dts146
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb-reva.dts143
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb.dts145
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb.dtsi562
-rw-r--r--arch/arm/boot/dts/imx6sx.dtsi1226
l---------arch/arm/boot/dts/include/dt-bindings1
-rw-r--r--arch/arm/boot/dts/integrator.dtsi132
-rw-r--r--arch/arm/boot/dts/integratorap.dts153
-rw-r--r--arch/arm/boot/dts/integratorcp.dts215
-rw-r--r--arch/arm/boot/dts/k2e-clocks.dtsi78
-rw-r--r--arch/arm/boot/dts/k2e-evm.dts153
-rw-r--r--arch/arm/boot/dts/k2e.dtsi138
-rw-r--r--arch/arm/boot/dts/k2hk-clocks.dtsi426
-rw-r--r--arch/arm/boot/dts/k2hk-evm.dts181
-rw-r--r--arch/arm/boot/dts/k2hk.dtsi102
-rw-r--r--arch/arm/boot/dts/k2l-clocks.dtsi267
-rw-r--r--arch/arm/boot/dts/k2l-evm.dts130
-rw-r--r--arch/arm/boot/dts/k2l.dtsi101
-rw-r--r--arch/arm/boot/dts/keystone-clocks.dtsi414
-rw-r--r--arch/arm/boot/dts/keystone.dtsi334
-rw-r--r--arch/arm/boot/dts/kirkwood-6192.dtsi86
-rw-r--r--arch/arm/boot/dts/kirkwood-6281.dtsi88
-rw-r--r--arch/arm/boot/dts/kirkwood-6282.dtsi138
-rw-r--r--arch/arm/boot/dts/kirkwood-98dx4122.dtsi51
-rw-r--r--arch/arm/boot/dts/kirkwood-b3.dts201
-rw-r--r--arch/arm/boot/dts/kirkwood-blackarmor-nas220.dts173
-rw-r--r--arch/arm/boot/dts/kirkwood-cloudbox.dts102
-rw-r--r--arch/arm/boot/dts/kirkwood-d2net.dts42
-rw-r--r--arch/arm/boot/dts/kirkwood-db-88f6281.dts30
-rw-r--r--arch/arm/boot/dts/kirkwood-db-88f6282.dts34
-rw-r--r--arch/arm/boot/dts/kirkwood-db.dtsi92
-rw-r--r--arch/arm/boot/dts/kirkwood-dir665.dts278
-rw-r--r--arch/arm/boot/dts/kirkwood-dns320.dts58
-rw-r--r--arch/arm/boot/dts/kirkwood-dns325.dts62
-rw-r--r--arch/arm/boot/dts/kirkwood-dnskw.dtsi234
-rw-r--r--arch/arm/boot/dts/kirkwood-dockstar.dts109
-rw-r--r--arch/arm/boot/dts/kirkwood-dreamplug.dts126
-rw-r--r--arch/arm/boot/dts/kirkwood-ds109.dts42
-rw-r--r--arch/arm/boot/dts/kirkwood-ds110jv10.dts42
-rw-r--r--arch/arm/boot/dts/kirkwood-ds111.dts45
-rw-r--r--arch/arm/boot/dts/kirkwood-ds112.dts49
-rw-r--r--arch/arm/boot/dts/kirkwood-ds209.dts45
-rw-r--r--arch/arm/boot/dts/kirkwood-ds210.dts47
-rw-r--r--arch/arm/boot/dts/kirkwood-ds212.dts48
-rw-r--r--arch/arm/boot/dts/kirkwood-ds212j.dts42
-rw-r--r--arch/arm/boot/dts/kirkwood-ds409.dts49
-rw-r--r--arch/arm/boot/dts/kirkwood-ds409slim.dts41
-rw-r--r--arch/arm/boot/dts/kirkwood-ds411.dts53
-rw-r--r--arch/arm/boot/dts/kirkwood-ds411j.dts49
-rw-r--r--arch/arm/boot/dts/kirkwood-ds411slim.dts49
-rw-r--r--arch/arm/boot/dts/kirkwood-goflexnet.dts189
-rw-r--r--arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts132
-rw-r--r--arch/arm/boot/dts/kirkwood-ib62x0.dts145
-rw-r--r--arch/arm/boot/dts/kirkwood-iconnect.dts196
-rw-r--r--arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts225
-rw-r--r--arch/arm/boot/dts/kirkwood-is2.dts34
-rw-r--r--arch/arm/boot/dts/kirkwood-km_common.dtsi48
-rw-r--r--arch/arm/boot/dts/kirkwood-km_fixedeth.dts23
-rw-r--r--arch/arm/boot/dts/kirkwood-km_kirkwood.dts30
-rw-r--r--arch/arm/boot/dts/kirkwood-laplug.dts171
-rw-r--r--arch/arm/boot/dts/kirkwood-lschlv2.dts19
-rw-r--r--arch/arm/boot/dts/kirkwood-lsxhl.dts19
-rw-r--r--arch/arm/boot/dts/kirkwood-lsxl.dtsi236
-rw-r--r--arch/arm/boot/dts/kirkwood-mplcec4.dts217
-rw-r--r--arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts181
-rw-r--r--arch/arm/boot/dts/kirkwood-nas2big.dts143
-rw-r--r--arch/arm/boot/dts/kirkwood-net2big.dts65
-rw-r--r--arch/arm/boot/dts/kirkwood-net5big.dts111
-rw-r--r--arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts253
-rw-r--r--arch/arm/boot/dts/kirkwood-netgear_readynas_nv+_v2.dts267
-rw-r--r--arch/arm/boot/dts/kirkwood-netxbig.dtsi154
-rw-r--r--arch/arm/boot/dts/kirkwood-ns2-common.dtsi96
-rw-r--r--arch/arm/boot/dts/kirkwood-ns2.dts34
-rw-r--r--arch/arm/boot/dts/kirkwood-ns2lite.dts34
-rw-r--r--arch/arm/boot/dts/kirkwood-ns2max.dts53
-rw-r--r--arch/arm/boot/dts/kirkwood-ns2mini.dts54
-rw-r--r--arch/arm/boot/dts/kirkwood-nsa310.dts140
-rw-r--r--arch/arm/boot/dts/kirkwood-nsa310a.dts114
-rw-r--r--arch/arm/boot/dts/kirkwood-nsa320.dts215
-rw-r--r--arch/arm/boot/dts/kirkwood-nsa3x0-common.dtsi159
-rw-r--r--arch/arm/boot/dts/kirkwood-openblocks_a6.dts176
-rw-r--r--arch/arm/boot/dts/kirkwood-openblocks_a7.dts205
-rw-r--r--arch/arm/boot/dts/kirkwood-openrd-base.dts42
-rw-r--r--arch/arm/boot/dts/kirkwood-openrd-client.dts73
-rw-r--r--arch/arm/boot/dts/kirkwood-openrd-ultimate.dts58
-rw-r--r--arch/arm/boot/dts/kirkwood-openrd.dtsi90
-rw-r--r--arch/arm/boot/dts/kirkwood-pogo_e02.dts134
-rw-r--r--arch/arm/boot/dts/kirkwood-rd88f6192.dts111
-rw-r--r--arch/arm/boot/dts/kirkwood-rd88f6281-a.dts43
-rw-r--r--arch/arm/boot/dts/kirkwood-rd88f6281-z0.dts35
-rw-r--r--arch/arm/boot/dts/kirkwood-rd88f6281.dtsi136
-rw-r--r--arch/arm/boot/dts/kirkwood-rs212.dts49
-rw-r--r--arch/arm/boot/dts/kirkwood-rs409.dts45
-rw-r--r--arch/arm/boot/dts/kirkwood-rs411.dts45
-rw-r--r--arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi105
-rw-r--r--arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts43
-rw-r--r--arch/arm/boot/dts/kirkwood-sheevaplug.dts43
-rw-r--r--arch/arm/boot/dts/kirkwood-synology.dtsi863
-rw-r--r--arch/arm/boot/dts/kirkwood-t5325.dts231
-rw-r--r--arch/arm/boot/dts/kirkwood-topkick.dts215
-rw-r--r--arch/arm/boot/dts/kirkwood-ts219-6281.dts55
-rw-r--r--arch/arm/boot/dts/kirkwood-ts219-6282.dts65
-rw-r--r--arch/arm/boot/dts/kirkwood-ts219.dtsi107
-rw-r--r--arch/arm/boot/dts/kirkwood-ts419-6281.dts20
-rw-r--r--arch/arm/boot/dts/kirkwood-ts419-6282.dts32
-rw-r--r--arch/arm/boot/dts/kirkwood-ts419.dtsi75
-rw-r--r--arch/arm/boot/dts/kirkwood.dtsi383
-rw-r--r--arch/arm/boot/dts/kizbox.dts150
-rw-r--r--arch/arm/boot/dts/lpc32xx.dtsi299
-rw-r--r--arch/arm/boot/dts/ls1021a-qds.dts240
-rw-r--r--arch/arm/boot/dts/ls1021a-twr.dts127
-rw-r--r--arch/arm/boot/dts/ls1021a.dtsi409
-rw-r--r--arch/arm/boot/dts/meson.dtsi174
-rw-r--r--arch/arm/boot/dts/meson6-atv1200.dts70
-rw-r--r--arch/arm/boot/dts/meson6.dtsi80
-rw-r--r--arch/arm/boot/dts/meson8-minix-neo-x8.dts128
-rw-r--r--arch/arm/boot/dts/meson8.dtsi160
-rw-r--r--arch/arm/boot/dts/mmp2-brownstone.dts196
-rw-r--r--arch/arm/boot/dts/mmp2.dtsi254
-rw-r--r--arch/arm/boot/dts/moxart-uc7112lx.dts117
-rw-r--r--arch/arm/boot/dts/moxart.dtsi148
-rw-r--r--arch/arm/boot/dts/mpa1600.dts77
-rw-r--r--arch/arm/boot/dts/mt6589-aquaris5.dts40
-rw-r--r--arch/arm/boot/dts/mt6589.dtsi147
-rw-r--r--arch/arm/boot/dts/mt6592-evb.dts26
-rw-r--r--arch/arm/boot/dts/mt6592.dtsi143
-rw-r--r--arch/arm/boot/dts/mt8127-moose.dts29
-rw-r--r--arch/arm/boot/dts/mt8127.dtsi142
-rw-r--r--arch/arm/boot/dts/mt8135-evbp1.dts29
-rw-r--r--arch/arm/boot/dts/mt8135.dtsi166
-rw-r--r--arch/arm/boot/dts/mxs-pinfunc.h31
-rw-r--r--arch/arm/boot/dts/nspire-classic.dtsi79
-rw-r--r--arch/arm/boot/dts/nspire-clp.dts45
-rw-r--r--arch/arm/boot/dts/nspire-cx.dts116
-rw-r--r--arch/arm/boot/dts/nspire-tp.dts44
-rw-r--r--arch/arm/boot/dts/nspire.dtsi196
-rw-r--r--arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi54
-rw-r--r--arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi58
-rw-r--r--arch/arm/boot/dts/omap-zoom-common.dtsi91
-rw-r--r--arch/arm/boot/dts/omap2.dtsi298
-rw-r--r--arch/arm/boot/dts/omap2420-clocks.dtsi270
-rw-r--r--arch/arm/boot/dts/omap2420-h4.dts66
-rw-r--r--arch/arm/boot/dts/omap2420-n800.dts8
-rw-r--r--arch/arm/boot/dts/omap2420-n810-wimax.dts8
-rw-r--r--arch/arm/boot/dts/omap2420-n810.dts15
-rw-r--r--arch/arm/boot/dts/omap2420-n8x0-common.dtsi105
-rw-r--r--arch/arm/boot/dts/omap2420.dtsi216
-rw-r--r--arch/arm/boot/dts/omap2430-clocks.dtsi344
-rw-r--r--arch/arm/boot/dts/omap2430-sdp.dts73
-rw-r--r--arch/arm/boot/dts/omap2430.dtsi313
-rw-r--r--arch/arm/boot/dts/omap24xx-clocks.dtsi1244
-rw-r--r--arch/arm/boot/dts/omap3-beagle-xm-ab.dts16
-rw-r--r--arch/arm/boot/dts/omap3-beagle-xm.dts392
-rw-r--r--arch/arm/boot/dts/omap3-beagle.dts431
-rw-r--r--arch/arm/boot/dts/omap3-cm-t3517.dts157
-rw-r--r--arch/arm/boot/dts/omap3-cm-t3530.dts59
-rw-r--r--arch/arm/boot/dts/omap3-cm-t3730.dts97
-rw-r--r--arch/arm/boot/dts/omap3-cm-t3x.dtsi319
-rw-r--r--arch/arm/boot/dts/omap3-cm-t3x30.dtsi130
-rw-r--r--arch/arm/boot/dts/omap3-devkit8000.dts159
-rw-r--r--arch/arm/boot/dts/omap3-evm-37xx.dts211
-rw-r--r--arch/arm/boot/dts/omap3-evm-common.dtsi160
-rw-r--r--arch/arm/boot/dts/omap3-evm.dts21
-rw-r--r--arch/arm/boot/dts/omap3-gta04.dtsi519
-rw-r--r--arch/arm/boot/dts/omap3-gta04a3.dts48
-rw-r--r--arch/arm/boot/dts/omap3-gta04a4.dts13
-rw-r--r--arch/arm/boot/dts/omap3-gta04a5.dts17
-rw-r--r--arch/arm/boot/dts/omap3-ha-common.dtsi88
-rw-r--r--arch/arm/boot/dts/omap3-ha-lcd.dts165
-rw-r--r--arch/arm/boot/dts/omap3-ha.dts28
-rw-r--r--arch/arm/boot/dts/omap3-igep.dtsi216
-rw-r--r--arch/arm/boot/dts/omap3-igep0020-common.dtsi246
-rw-r--r--arch/arm/boot/dts/omap3-igep0020-rev-f.dts54
-rw-r--r--arch/arm/boot/dts/omap3-igep0020.dts67
-rw-r--r--arch/arm/boot/dts/omap3-igep0030-common.dtsi60
-rw-r--r--arch/arm/boot/dts/omap3-igep0030-rev-g.dts76
-rw-r--r--arch/arm/boot/dts/omap3-igep0030.dts70
-rw-r--r--arch/arm/boot/dts/omap3-ldp.dts304
-rw-r--r--arch/arm/boot/dts/omap3-lilly-a83x.dtsi458
-rw-r--r--arch/arm/boot/dts/omap3-lilly-dbb056.dts170
-rw-r--r--arch/arm/boot/dts/omap3-n9.dts55
-rw-r--r--arch/arm/boot/dts/omap3-n900.dts990
-rw-r--r--arch/arm/boot/dts/omap3-n950-n9.dtsi193
-rw-r--r--arch/arm/boot/dts/omap3-n950.dts55
-rw-r--r--arch/arm/boot/dts/omap3-overo-alto35-common.dtsi78
-rw-r--r--arch/arm/boot/dts/omap3-overo-alto35.dts22
-rw-r--r--arch/arm/boot/dts/omap3-overo-base.dtsi220
-rw-r--r--arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi70
-rw-r--r--arch/arm/boot/dts/omap3-overo-chestnut43.dts38
-rw-r--r--arch/arm/boot/dts/omap3-overo-common-dvi.dtsi111
-rw-r--r--arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi165
-rw-r--r--arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi178
-rw-r--r--arch/arm/boot/dts/omap3-overo-common-peripherals.dtsi95
-rw-r--r--arch/arm/boot/dts/omap3-overo-gallop43-common.dtsi58
-rw-r--r--arch/arm/boot/dts/omap3-overo-gallop43.dts38
-rw-r--r--arch/arm/boot/dts/omap3-overo-palo43-common.dtsi54
-rw-r--r--arch/arm/boot/dts/omap3-overo-palo43.dts38
-rw-r--r--arch/arm/boot/dts/omap3-overo-storm-alto35.dts21
-rw-r--r--arch/arm/boot/dts/omap3-overo-storm-chestnut43.dts38
-rw-r--r--arch/arm/boot/dts/omap3-overo-storm-gallop43.dts38
-rw-r--r--arch/arm/boot/dts/omap3-overo-storm-palo43.dts38
-rw-r--r--arch/arm/boot/dts/omap3-overo-storm-summit.dts30
-rw-r--r--arch/arm/boot/dts/omap3-overo-storm-tobi.dts22
-rw-r--r--arch/arm/boot/dts/omap3-overo-storm.dtsi35
-rw-r--r--arch/arm/boot/dts/omap3-overo-summit-common.dtsi32
-rw-r--r--arch/arm/boot/dts/omap3-overo-summit.dts30
-rw-r--r--arch/arm/boot/dts/omap3-overo-tobi-common.dtsi42
-rw-r--r--arch/arm/boot/dts/omap3-overo-tobi.dts22
-rw-r--r--arch/arm/boot/dts/omap3-overo.dtsi38
-rw-r--r--arch/arm/boot/dts/omap3-pandora-1ghz.dts70
-rw-r--r--arch/arm/boot/dts/omap3-pandora-600mhz.dts65
-rw-r--r--arch/arm/boot/dts/omap3-pandora-common.dtsi640
-rw-r--r--arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi71
-rw-r--r--arch/arm/boot/dts/omap3-sb-t35.dtsi138
-rw-r--r--arch/arm/boot/dts/omap3-sbc-t3517.dts75
-rw-r--r--arch/arm/boot/dts/omap3-sbc-t3530.dts47
-rw-r--r--arch/arm/boot/dts/omap3-sbc-t3730.dts43
-rw-r--r--arch/arm/boot/dts/omap3-tao3530.dtsi345
-rw-r--r--arch/arm/boot/dts/omap3-thunder.dts129
-rw-r--r--arch/arm/boot/dts/omap3-zoom3.dts234
-rw-r--r--arch/arm/boot/dts/omap3.dtsi835
-rw-r--r--arch/arm/boot/dts/omap3430-sdp.dts193
-rw-r--r--arch/arm/boot/dts/omap3430es1-clocks.dtsi208
-rw-r--r--arch/arm/boot/dts/omap34xx-omap36xx-clocks.dtsi268
-rw-r--r--arch/arm/boot/dts/omap34xx.dtsi73
-rw-r--r--arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi242
-rw-r--r--arch/arm/boot/dts/omap36xx-clocks.dtsi110
-rw-r--r--arch/arm/boot/dts/omap36xx-omap3430es2plus-clocks.dtsi198
-rw-r--r--arch/arm/boot/dts/omap36xx.dtsi112
-rw-r--r--arch/arm/boot/dts/omap3xxx-clocks.dtsi1665
-rw-r--r--arch/arm/boot/dts/omap4-cpu-thermal.dtsi41
-rw-r--r--arch/arm/boot/dts/omap4-duovero-parlor.dts191
-rw-r--r--arch/arm/boot/dts/omap4-duovero.dtsi260
-rw-r--r--arch/arm/boot/dts/omap4-panda-a4.dts20
-rw-r--r--arch/arm/boot/dts/omap4-panda-common.dtsi543
-rw-r--r--arch/arm/boot/dts/omap4-panda-es.dts73
-rw-r--r--arch/arm/boot/dts/omap4-panda.dts16
-rw-r--r--arch/arm/boot/dts/omap4-sdp-es23plus.dts17
-rw-r--r--arch/arm/boot/dts/omap4-sdp.dts699
-rw-r--r--arch/arm/boot/dts/omap4-var-dvk-om44.dts71
-rw-r--r--arch/arm/boot/dts/omap4-var-om44customboard.dtsi235
-rw-r--r--arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi78
-rw-r--r--arch/arm/boot/dts/omap4-var-som-om44.dtsi341
-rw-r--r--arch/arm/boot/dts/omap4-var-stk-om44.dts17
-rw-r--r--arch/arm/boot/dts/omap4.dtsi1009
-rw-r--r--arch/arm/boot/dts/omap443x-clocks.dtsi18
-rw-r--r--arch/arm/boot/dts/omap443x.dtsi74
-rw-r--r--arch/arm/boot/dts/omap4460.dtsi93
-rw-r--r--arch/arm/boot/dts/omap446x-clocks.dtsi27
-rw-r--r--arch/arm/boot/dts/omap44xx-clocks.dtsi1643
-rw-r--r--arch/arm/boot/dts/omap5-cm-t54.dts679
-rw-r--r--arch/arm/boot/dts/omap5-core-thermal.dtsi28
-rw-r--r--arch/arm/boot/dts/omap5-gpu-thermal.dtsi28
-rw-r--r--arch/arm/boot/dts/omap5-sbc-t54.dts51
-rw-r--r--arch/arm/boot/dts/omap5-uevm.dts634
-rw-r--r--arch/arm/boot/dts/omap5.dtsi1136
-rw-r--r--arch/arm/boot/dts/omap54xx-clocks.dtsi1390
-rw-r--r--arch/arm/boot/dts/orion5x-lacie-d2-network.dts236
-rw-r--r--arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts174
-rw-r--r--arch/arm/boot/dts/orion5x-maxtor-shared-storage-2.dts178
-rw-r--r--arch/arm/boot/dts/orion5x-mv88f5182.dtsi45
-rw-r--r--arch/arm/boot/dts/orion5x-rd88f5182-nas.dts177
-rw-r--r--arch/arm/boot/dts/orion5x.dtsi232
-rw-r--r--arch/arm/boot/dts/phy3250.dts202
-rw-r--r--arch/arm/boot/dts/picoxcell-pc3x2.dtsi249
-rw-r--r--arch/arm/boot/dts/picoxcell-pc3x3.dtsi365
-rw-r--r--arch/arm/boot/dts/picoxcell-pc7302-pc3x2.dts86
-rw-r--r--arch/arm/boot/dts/picoxcell-pc7302-pc3x3.dts92
-rw-r--r--arch/arm/boot/dts/pm9g45.dts173
-rw-r--r--arch/arm/boot/dts/prima2-evb.dts37
-rw-r--r--arch/arm/boot/dts/prima2.dtsi840
-rw-r--r--arch/arm/boot/dts/pxa168-aspenite.dts38
-rw-r--r--arch/arm/boot/dts/pxa168.dtsi158
-rw-r--r--arch/arm/boot/dts/pxa27x.dtsi56
-rw-r--r--arch/arm/boot/dts/pxa2xx.dtsi135
-rw-r--r--arch/arm/boot/dts/pxa3xx.dtsi43
-rw-r--r--arch/arm/boot/dts/pxa910-dkb.dts175
-rw-r--r--arch/arm/boot/dts/pxa910.dtsi175
-rw-r--r--arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts59
-rw-r--r--arch/arm/boot/dts/qcom-apq8064-ifc6410.dts71
-rw-r--r--arch/arm/boot/dts/qcom-apq8064-v2.0.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom-apq8064.dtsi388
-rw-r--r--arch/arm/boot/dts/qcom-apq8074-dragonboard.dts68
-rw-r--r--arch/arm/boot/dts/qcom-apq8084-ifc6540.dts24
-rw-r--r--arch/arm/boot/dts/qcom-apq8084-mtp.dts13
-rw-r--r--arch/arm/boot/dts/qcom-apq8084.dtsi284
-rw-r--r--arch/arm/boot/dts/qcom-ipq8064-ap148.dts93
-rw-r--r--arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom-ipq8064.dtsi333
-rw-r--r--arch/arm/boot/dts/qcom-msm8660-surf.dts58
-rw-r--r--arch/arm/boot/dts/qcom-msm8660.dtsi209
-rw-r--r--arch/arm/boot/dts/qcom-msm8960-cdp.dts43
-rw-r--r--arch/arm/boot/dts/qcom-msm8960.dtsi257
-rw-r--r--arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts19
-rw-r--r--arch/arm/boot/dts/qcom-msm8974.dtsi305
-rw-r--r--arch/arm/boot/dts/qcom-pm8841.dtsi18
-rw-r--r--arch/arm/boot/dts/qcom-pm8941.dtsi18
-rw-r--r--arch/arm/boot/dts/qcom-pma8084.dtsi18
-rw-r--r--arch/arm/boot/dts/r7s72100-genmai.dts74
-rw-r--r--arch/arm/boot/dts/r7s72100.dtsi407
-rw-r--r--arch/arm/boot/dts/r8a73a4-ape6evm.dts251
-rw-r--r--arch/arm/boot/dts/r8a73a4.dtsi891
-rw-r--r--arch/arm/boot/dts/r8a7740-armadillo800eva.dts305
-rw-r--r--arch/arm/boot/dts/r8a7740.dtsi728
-rw-r--r--arch/arm/boot/dts/r8a7778-bockw-reference.dts139
-rw-r--r--arch/arm/boot/dts/r8a7778-bockw.dts206
-rw-r--r--arch/arm/boot/dts/r8a7778.dtsi590
-rw-r--r--arch/arm/boot/dts/r8a7779-marzen.dts238
-rw-r--r--arch/arm/boot/dts/r8a7779.dtsi549
-rw-r--r--arch/arm/boot/dts/r8a7790-lager.dts686
-rw-r--r--arch/arm/boot/dts/r8a7790.dtsi1651
-rw-r--r--arch/arm/boot/dts/r8a7791-henninger.dts320
-rw-r--r--arch/arm/boot/dts/r8a7791-koelsch.dts687
-rw-r--r--arch/arm/boot/dts/r8a7791.dtsi1643
-rw-r--r--arch/arm/boot/dts/r8a7794-alt.dts61
-rw-r--r--arch/arm/boot/dts/r8a7794.dtsi733
-rw-r--r--arch/arm/boot/dts/r8a77xx-aa104xd12-panel.dtsi41
-rw-r--r--arch/arm/boot/dts/rk3066a-bqcurie2.dts193
-rw-r--r--arch/arm/boot/dts/rk3066a-marsboard.dts206
-rw-r--r--arch/arm/boot/dts/rk3066a-rayeager.dts468
-rw-r--r--arch/arm/boot/dts/rk3066a.dtsi611
-rw-r--r--arch/arm/boot/dts/rk3188-radxarock.dts342
-rw-r--r--arch/arm/boot/dts/rk3188.dtsi536
-rw-r--r--arch/arm/boot/dts/rk3288-evb-act8846.dts163
-rw-r--r--arch/arm/boot/dts/rk3288-evb-rk808.dts234
-rw-r--r--arch/arm/boot/dts/rk3288-evb.dtsi276
-rw-r--r--arch/arm/boot/dts/rk3288-firefly-beta.dts71
-rw-r--r--arch/arm/boot/dts/rk3288-firefly.dts71
-rw-r--r--arch/arm/boot/dts/rk3288-firefly.dtsi510
-rw-r--r--arch/arm/boot/dts/rk3288-popmetal.dts447
-rw-r--r--arch/arm/boot/dts/rk3288-thermal.dtsi74
-rw-r--r--arch/arm/boot/dts/rk3288.dtsi1273
-rw-r--r--arch/arm/boot/dts/rk3xxx.dtsi388
-rw-r--r--arch/arm/boot/dts/s3c2416-pinctrl.dtsi173
-rw-r--r--arch/arm/boot/dts/s3c2416-smdk2416.dts85
-rw-r--r--arch/arm/boot/dts/s3c2416.dtsi125
-rw-r--r--arch/arm/boot/dts/s3c24xx.dtsi95
-rw-r--r--arch/arm/boot/dts/s3c6400.dtsi41
-rw-r--r--arch/arm/boot/dts/s3c6410-mini6410.dts224
-rw-r--r--arch/arm/boot/dts/s3c6410-smdk6410.dts103
-rw-r--r--arch/arm/boot/dts/s3c6410.dtsi57
-rw-r--r--arch/arm/boot/dts/s3c64xx-pinctrl.dtsi687
-rw-r--r--arch/arm/boot/dts/s3c64xx.dtsi202
-rw-r--r--arch/arm/boot/dts/s5pv210-aquila.dts393
-rw-r--r--arch/arm/boot/dts/s5pv210-goni.dts450
-rw-r--r--arch/arm/boot/dts/s5pv210-pinctrl.dtsi839
-rw-r--r--arch/arm/boot/dts/s5pv210-smdkc110.dts78
-rw-r--r--arch/arm/boot/dts/s5pv210-smdkv210.dts239
-rw-r--r--arch/arm/boot/dts/s5pv210-torbreck.dts92
-rw-r--r--arch/arm/boot/dts/s5pv210.dtsi633
-rw-r--r--arch/arm/boot/dts/sama5d3.dtsi1489
-rw-r--r--arch/arm/boot/dts/sama5d31.dtsi16
-rw-r--r--arch/arm/boot/dts/sama5d31ek.dts52
-rw-r--r--arch/arm/boot/dts/sama5d33.dtsi14
-rw-r--r--arch/arm/boot/dts/sama5d33ek.dts45
-rw-r--r--arch/arm/boot/dts/sama5d34.dtsi16
-rw-r--r--arch/arm/boot/dts/sama5d34ek.dts62
-rw-r--r--arch/arm/boot/dts/sama5d35.dtsi18
-rw-r--r--arch/arm/boot/dts/sama5d35ek.dts55
-rw-r--r--arch/arm/boot/dts/sama5d36.dtsi20
-rw-r--r--arch/arm/boot/dts/sama5d36ek.dts53
-rw-r--r--arch/arm/boot/dts/sama5d3_can.dtsi74
-rw-r--r--arch/arm/boot/dts/sama5d3_emac.dtsi55
-rw-r--r--arch/arm/boot/dts/sama5d3_gmac.dtsi88
-rw-r--r--arch/arm/boot/dts/sama5d3_lcd.dtsi215
-rw-r--r--arch/arm/boot/dts/sama5d3_mci2.dtsi59
-rw-r--r--arch/arm/boot/dts/sama5d3_tcb1.dtsi39
-rw-r--r--arch/arm/boot/dts/sama5d3_uart.dtsi79
-rw-r--r--arch/arm/boot/dts/sama5d3xcm.dtsi128
-rw-r--r--arch/arm/boot/dts/sama5d3xdm.dtsi41
-rw-r--r--arch/arm/boot/dts/sama5d3xmb.dtsi219
-rw-r--r--arch/arm/boot/dts/sama5d4.dtsi1675
-rw-r--r--arch/arm/boot/dts/samsung_k3pe0e000b.dtsi67
-rw-r--r--arch/arm/boot/dts/sh73a0-kzm9g.dts400
-rw-r--r--arch/arm/boot/dts/sh73a0.dtsi902
-rw-r--r--arch/arm/boot/dts/skeleton.dtsi13
-rw-r--r--arch/arm/boot/dts/skeleton64.dtsi13
-rw-r--r--arch/arm/boot/dts/socfpga.dtsi788
-rw-r--r--arch/arm/boot/dts/socfpga_arria10.dtsi374
-rwxr-xr-xarch/arm/boot/dts/socfpga_arria10_socdk.dts48
-rw-r--r--arch/arm/boot/dts/socfpga_arria5.dtsi44
-rw-r--r--arch/arm/boot/dts/socfpga_arria5_socdk.dts85
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5.dtsi55
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_socdk.dts90
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_sockit.dts70
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_socrates.dts50
-rw-r--r--arch/arm/boot/dts/socfpga_vt.dts90
-rw-r--r--arch/arm/boot/dts/spear1310-evb.dts427
-rw-r--r--arch/arm/boot/dts/spear1310.dtsi316
-rw-r--r--arch/arm/boot/dts/spear1340-evb.dts525
-rw-r--r--arch/arm/boot/dts/spear1340.dtsi174
-rw-r--r--arch/arm/boot/dts/spear13xx.dtsi343
-rw-r--r--arch/arm/boot/dts/spear300-evb.dts255
-rw-r--r--arch/arm/boot/dts/spear300.dtsi89
-rw-r--r--arch/arm/boot/dts/spear310-evb.dts208
-rw-r--r--arch/arm/boot/dts/spear310.dtsi118
-rw-r--r--arch/arm/boot/dts/spear320-evb.dts207
-rw-r--r--arch/arm/boot/dts/spear320-hmi.dts305
-rw-r--r--arch/arm/boot/dts/spear320.dtsi147
-rw-r--r--arch/arm/boot/dts/spear3xx.dtsi157
-rw-r--r--arch/arm/boot/dts/spear600-evb.dts116
-rw-r--r--arch/arm/boot/dts/spear600.dtsi209
-rw-r--r--arch/arm/boot/dts/st-pincfg.h71
-rw-r--r--arch/arm/boot/dts/ste-ccu8540-pinctrl.dtsi196
-rw-r--r--arch/arm/boot/dts/ste-ccu8540.dts87
-rw-r--r--arch/arm/boot/dts/ste-ccu9540.dts72
-rw-r--r--arch/arm/boot/dts/ste-dbx5x0.dtsi1054
-rw-r--r--arch/arm/boot/dts/ste-href-ab8500.dtsi428
-rw-r--r--arch/arm/boot/dts/ste-href-ab8505.dtsi240
-rw-r--r--arch/arm/boot/dts/ste-href-family-pinctrl.dtsi745
-rw-r--r--arch/arm/boot/dts/ste-href-stuib.dtsi121
-rw-r--r--arch/arm/boot/dts/ste-href-tvk1281618.dtsi178
-rw-r--r--arch/arm/boot/dts/ste-href.dtsi283
-rw-r--r--arch/arm/boot/dts/ste-hrefprev60-stuib.dts34
-rw-r--r--arch/arm/boot/dts/ste-hrefprev60-tvk.dts19
-rw-r--r--arch/arm/boot/dts/ste-hrefprev60.dtsi128
-rw-r--r--arch/arm/boot/dts/ste-hrefv60plus-stuib.dts36
-rw-r--r--arch/arm/boot/dts/ste-hrefv60plus-tvk.dts21
-rw-r--r--arch/arm/boot/dts/ste-hrefv60plus.dtsi218
-rw-r--r--arch/arm/boot/dts/ste-nomadik-nhk15.dts151
-rw-r--r--arch/arm/boot/dts/ste-nomadik-pinctrl.dtsi175
-rw-r--r--arch/arm/boot/dts/ste-nomadik-s8815.dts141
-rw-r--r--arch/arm/boot/dts/ste-nomadik-stn8815.dtsi814
-rw-r--r--arch/arm/boot/dts/ste-snowball.dts538
-rw-r--r--arch/arm/boot/dts/ste-u300.dts473
-rw-r--r--arch/arm/boot/dts/stih407-b2120.dts30
-rw-r--r--arch/arm/boot/dts/stih407-clock.dtsi326
-rw-r--r--arch/arm/boot/dts/stih407-family.dtsi340
-rw-r--r--arch/arm/boot/dts/stih407-pinctrl.dtsi615
-rw-r--r--arch/arm/boot/dts/stih407.dtsi151
-rw-r--r--arch/arm/boot/dts/stih410-b2120.dts29
-rw-r--r--arch/arm/boot/dts/stih410-clock.dtsi338
-rw-r--r--arch/arm/boot/dts/stih410-pinctrl.dtsi34
-rw-r--r--arch/arm/boot/dts/stih410.dtsi222
-rw-r--r--arch/arm/boot/dts/stih415-b2000.dts15
-rw-r--r--arch/arm/boot/dts/stih415-b2020.dts15
-rw-r--r--arch/arm/boot/dts/stih415-clock.dtsi533
-rw-r--r--arch/arm/boot/dts/stih415-pinctrl.dtsi545
-rw-r--r--arch/arm/boot/dts/stih415.dtsi234
-rw-r--r--arch/arm/boot/dts/stih416-b2000.dts15
-rw-r--r--arch/arm/boot/dts/stih416-b2020.dts37
-rw-r--r--arch/arm/boot/dts/stih416-b2020e.dts55
-rw-r--r--arch/arm/boot/dts/stih416-clock.dtsi756
-rw-r--r--arch/arm/boot/dts/stih416-pinctrl.dtsi637
-rw-r--r--arch/arm/boot/dts/stih416.dtsi449
-rw-r--r--arch/arm/boot/dts/stih418-b2199.dts78
-rw-r--r--arch/arm/boot/dts/stih418-clock.dtsi348
-rw-r--r--arch/arm/boot/dts/stih418.dtsi99
-rw-r--r--arch/arm/boot/dts/stih41x-b2000.dtsi95
-rw-r--r--arch/arm/boot/dts/stih41x-b2020.dtsi82
-rw-r--r--arch/arm/boot/dts/stih41x-b2020x.dtsi32
-rw-r--r--arch/arm/boot/dts/stih41x.dtsi47
-rw-r--r--arch/arm/boot/dts/stihxxx-b2120.dtsi70
-rw-r--r--arch/arm/boot/dts/sun4i-a10-a1000.dts192
-rw-r--r--arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts148
-rw-r--r--arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts100
-rw-r--r--arch/arm/boot/dts/sun4i-a10-cubieboard.dts217
-rw-r--r--arch/arm/boot/dts/sun4i-a10-hackberry.dts175
-rw-r--r--arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts105
-rw-r--r--arch/arm/boot/dts/sun4i-a10-inet97fv2.dts126
-rw-r--r--arch/arm/boot/dts/sun4i-a10-marsboard.dts183
-rw-r--r--arch/arm/boot/dts/sun4i-a10-mini-xplus.dts136
-rw-r--r--arch/arm/boot/dts/sun4i-a10-mk802.dts109
-rw-r--r--arch/arm/boot/dts/sun4i-a10-mk802ii.dts113
-rw-r--r--arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts191
-rw-r--r--arch/arm/boot/dts/sun4i-a10-pcduino.dts196
-rw-r--r--arch/arm/boot/dts/sun4i-a10.dtsi968
-rw-r--r--arch/arm/boot/dts/sun5i-a10s-mk802.dts125
-rw-r--r--arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts248
-rw-r--r--arch/arm/boot/dts/sun5i-a10s-r7-tv-dongle.dts139
-rw-r--r--arch/arm/boot/dts/sun5i-a10s.dtsi659
-rw-r--r--arch/arm/boot/dts/sun5i-a13-hsg-h702.dts167
-rw-r--r--arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts153
-rw-r--r--arch/arm/boot/dts/sun5i-a13-olinuxino.dts203
-rw-r--r--arch/arm/boot/dts/sun5i-a13.dtsi621
-rw-r--r--arch/arm/boot/dts/sun6i-a31-app4-evb1.dts96
-rw-r--r--arch/arm/boot/dts/sun6i-a31-colombus.dts136
-rw-r--r--arch/arm/boot/dts/sun6i-a31-hummingbird.dts156
-rw-r--r--arch/arm/boot/dts/sun6i-a31-m9.dts152
-rw-r--r--arch/arm/boot/dts/sun6i-a31.dtsi978
-rw-r--r--arch/arm/boot/dts/sun6i-a31s-cs908.dts104
-rw-r--r--arch/arm/boot/dts/sun6i-a31s.dtsi58
-rw-r--r--arch/arm/boot/dts/sun7i-a20-bananapi.dts224
-rw-r--r--arch/arm/boot/dts/sun7i-a20-bananapro.dts262
-rw-r--r--arch/arm/boot/dts/sun7i-a20-cubieboard2.dts210
-rw-r--r--arch/arm/boot/dts/sun7i-a20-cubietruck.dts287
-rw-r--r--arch/arm/boot/dts/sun7i-a20-hummingbird.dts248
-rw-r--r--arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts238
-rw-r--r--arch/arm/boot/dts/sun7i-a20-m3.dts172
-rw-r--r--arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts177
-rw-r--r--arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts232
-rw-r--r--arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts247
-rw-r--r--arch/arm/boot/dts/sun7i-a20-pcduino3.dts212
-rw-r--r--arch/arm/boot/dts/sun7i-a20.dtsi1233
-rw-r--r--arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts59
-rw-r--r--arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts134
-rw-r--r--arch/arm/boot/dts/sun8i-a23.dtsi611
-rw-r--r--arch/arm/boot/dts/sun9i-a80-optimus.dts152
-rw-r--r--arch/arm/boot/dts/sun9i-a80.dtsi632
-rw-r--r--arch/arm/boot/dts/sunxi-common-regulators.dtsi153
-rw-r--r--arch/arm/boot/dts/tegra114-dalmore.dts1287
-rw-r--r--arch/arm/boot/dts/tegra114-roth.dts1126
-rw-r--r--arch/arm/boot/dts/tegra114-tn7.dts351
-rw-r--r--arch/arm/boot/dts/tegra114.dtsi784
-rw-r--r--arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi2421
-rw-r--r--arch/arm/boot/dts/tegra124-jetson-tk1.dts1949
-rw-r--r--arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi2023
-rw-r--r--arch/arm/boot/dts/tegra124-nyan-big.dts1338
-rw-r--r--arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi2049
-rw-r--r--arch/arm/boot/dts/tegra124-nyan-blaze.dts1334
-rw-r--r--arch/arm/boot/dts/tegra124-nyan.dtsi695
-rw-r--r--arch/arm/boot/dts/tegra124-venice2.dts1156
-rw-r--r--arch/arm/boot/dts/tegra124.dtsi992
-rw-r--r--arch/arm/boot/dts/tegra20-colibri-512.dtsi533
-rw-r--r--arch/arm/boot/dts/tegra20-harmony.dts777
-rw-r--r--arch/arm/boot/dts/tegra20-iris-512.dts101
-rw-r--r--arch/arm/boot/dts/tegra20-medcom-wide.dts130
-rw-r--r--arch/arm/boot/dts/tegra20-paz00.dts598
-rw-r--r--arch/arm/boot/dts/tegra20-plutux.dts102
-rw-r--r--arch/arm/boot/dts/tegra20-seaboard.dts924
-rw-r--r--arch/arm/boot/dts/tegra20-tamonten.dtsi529
-rw-r--r--arch/arm/boot/dts/tegra20-tec.dts111
-rw-r--r--arch/arm/boot/dts/tegra20-trimslice.dts468
-rw-r--r--arch/arm/boot/dts/tegra20-ventana.dts702
-rw-r--r--arch/arm/boot/dts/tegra20-whistler.dts632
-rw-r--r--arch/arm/boot/dts/tegra20.dtsi792
-rw-r--r--arch/arm/boot/dts/tegra30-apalis-eval.dts264
-rw-r--r--arch/arm/boot/dts/tegra30-apalis.dtsi687
-rw-r--r--arch/arm/boot/dts/tegra30-beaver.dts2104
-rw-r--r--arch/arm/boot/dts/tegra30-cardhu-a02.dts94
-rw-r--r--arch/arm/boot/dts/tegra30-cardhu-a04.dts105
-rw-r--r--arch/arm/boot/dts/tegra30-cardhu.dtsi618
-rw-r--r--arch/arm/boot/dts/tegra30-colibri-eval-v3.dts208
-rw-r--r--arch/arm/boot/dts/tegra30-colibri.dtsi386
-rw-r--r--arch/arm/boot/dts/tegra30.dtsi926
-rw-r--r--arch/arm/boot/dts/tny_a9260.dts15
-rw-r--r--arch/arm/boot/dts/tny_a9260_common.dtsi91
-rw-r--r--arch/arm/boot/dts/tny_a9263.dts105
-rw-r--r--arch/arm/boot/dts/tny_a9g20.dts15
-rw-r--r--arch/arm/boot/dts/tps6507x.dtsi47
-rw-r--r--arch/arm/boot/dts/tps65217.dtsi56
-rw-r--r--arch/arm/boot/dts/tps65910.dtsi91
-rw-r--r--arch/arm/boot/dts/twl4030.dtsi161
-rw-r--r--arch/arm/boot/dts/twl4030_omap3.dtsi42
-rw-r--r--arch/arm/boot/dts/twl6030.dtsi102
-rw-r--r--arch/arm/boot/dts/twl6030_omap4.dtsi38
-rw-r--r--arch/arm/boot/dts/usb_a9260.dts32
-rw-r--r--arch/arm/boot/dts/usb_a9260_common.dtsi125
-rw-r--r--arch/arm/boot/dts/usb_a9263.dts153
-rw-r--r--arch/arm/boot/dts/usb_a9g20-dab-mmx.dtsi96
-rw-r--r--arch/arm/boot/dts/usb_a9g20.dts14
-rw-r--r--arch/arm/boot/dts/usb_a9g20_common.dtsi27
-rw-r--r--arch/arm/boot/dts/usb_a9g20_lpw.dts31
-rw-r--r--arch/arm/boot/dts/versatile-ab.dts292
-rw-r--r--arch/arm/boot/dts/versatile-pb.dts95
-rw-r--r--arch/arm/boot/dts/vexpress-v2m-rs1.dtsi440
-rw-r--r--arch/arm/boot/dts/vexpress-v2m.dtsi439
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts283
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts620
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca5s.dts253
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca9.dts362
-rw-r--r--arch/arm/boot/dts/vf-colibri-eval-v3.dtsi127
-rw-r--r--arch/arm/boot/dts/vf-colibri.dtsi202
-rw-r--r--arch/arm/boot/dts/vf500-colibri-eval-v3.dts17
-rw-r--r--arch/arm/boot/dts/vf500-colibri.dtsi20
-rw-r--r--arch/arm/boot/dts/vf500.dtsi55
-rw-r--r--arch/arm/boot/dts/vf610-colibri-eval-v3.dts17
-rw-r--r--arch/arm/boot/dts/vf610-colibri.dtsi25
-rw-r--r--arch/arm/boot/dts/vf610-cosmic.dts93
-rw-r--r--arch/arm/boot/dts/vf610-pinfunc.h810
-rw-r--r--arch/arm/boot/dts/vf610-twr.dts326
-rw-r--r--arch/arm/boot/dts/vf610.dtsi25
-rw-r--r--arch/arm/boot/dts/vfxxx.dtsi525
-rw-r--r--arch/arm/boot/dts/vt8500-bv07.dts36
-rw-r--r--arch/arm/boot/dts/vt8500.dtsi175
-rw-r--r--arch/arm/boot/dts/wm8505-ref.dts36
-rw-r--r--arch/arm/boot/dts/wm8505.dtsi290
-rw-r--r--arch/arm/boot/dts/wm8650-mid.dts37
-rw-r--r--arch/arm/boot/dts/wm8650.dtsi228
-rw-r--r--arch/arm/boot/dts/wm8750-apc8750.dts30
-rw-r--r--arch/arm/boot/dts/wm8750.dtsi347
-rw-r--r--arch/arm/boot/dts/wm8850-w70v2.dts48
-rw-r--r--arch/arm/boot/dts/wm8850.dtsi308
-rw-r--r--arch/arm/boot/dts/xenvm-4.2.dts81
-rw-r--r--arch/arm/boot/dts/zynq-7000.dtsi352
-rw-r--r--arch/arm/boot/dts/zynq-parallella.dts90
-rw-r--r--arch/arm/boot/dts/zynq-zc702.dts365
-rw-r--r--arch/arm/boot/dts/zynq-zc706.dts314
-rw-r--r--arch/arm/boot/dts/zynq-zed.dts67
-rw-r--r--arch/arm/boot/dts/zynq-zybo.dts52
-rw-r--r--arch/arm/boot/install.sh66
-rw-r--r--arch/arm/common/Kconfig22
-rw-r--r--arch/arm/common/Makefile21
-rw-r--r--arch/arm/common/bL_switcher.c802
-rw-r--r--arch/arm/common/bL_switcher_dummy_if.c71
-rw-r--r--arch/arm/common/dmabounce.c579
-rw-r--r--arch/arm/common/edma.c1873
-rw-r--r--arch/arm/common/firmware.c18
-rw-r--r--arch/arm/common/icst.c100
-rw-r--r--arch/arm/common/it8152.c355
-rw-r--r--arch/arm/common/locomo.c914
-rw-r--r--arch/arm/common/mcpm_entry.c486
-rw-r--r--arch/arm/common/mcpm_head.S233
-rw-r--r--arch/arm/common/mcpm_platsmp.c103
-rw-r--r--arch/arm/common/sa1111.c1456
-rw-r--r--arch/arm/common/scoop.c275
-rw-r--r--arch/arm/common/sharpsl_param.c65
-rw-r--r--arch/arm/common/timer-sp.c304
-rw-r--r--arch/arm/common/vlock.S108
-rw-r--r--arch/arm/common/vlock.h29
-rw-r--r--arch/arm/configs/acs5k_defconfig86
-rw-r--r--arch/arm/configs/acs5k_tiny_defconfig80
-rw-r--r--arch/arm/configs/am200epdkit_defconfig108
-rw-r--r--arch/arm/configs/armadillo800eva_defconfig162
-rw-r--r--arch/arm/configs/assabet_defconfig60
-rw-r--r--arch/arm/configs/at91_dt_defconfig221
-rw-r--r--arch/arm/configs/axm55xx_defconfig248
-rw-r--r--arch/arm/configs/badge4_defconfig119
-rw-r--r--arch/arm/configs/bcm2835_defconfig141
-rw-r--r--arch/arm/configs/bcm_defconfig142
-rw-r--r--arch/arm/configs/bockw_defconfig133
-rw-r--r--arch/arm/configs/cerfcube_defconfig75
-rw-r--r--arch/arm/configs/clps711x_defconfig91
-rw-r--r--arch/arm/configs/cm_x2xx_defconfig188
-rw-r--r--arch/arm/configs/cm_x300_defconfig177
-rw-r--r--arch/arm/configs/cns3420vb_defconfig75
-rw-r--r--arch/arm/configs/colibri_pxa270_defconfig179
-rw-r--r--arch/arm/configs/colibri_pxa300_defconfig71
-rw-r--r--arch/arm/configs/collie_defconfig94
-rw-r--r--arch/arm/configs/corgi_defconfig272
-rw-r--r--arch/arm/configs/davinci_all_defconfig222
-rw-r--r--arch/arm/configs/dove_defconfig146
-rw-r--r--arch/arm/configs/ebsa110_defconfig75
-rw-r--r--arch/arm/configs/efm32_defconfig103
-rw-r--r--arch/arm/configs/em_x270_defconfig193
-rw-r--r--arch/arm/configs/ep93xx_defconfig112
-rw-r--r--arch/arm/configs/eseries_pxa_defconfig118
-rw-r--r--arch/arm/configs/exynos_defconfig231
-rw-r--r--arch/arm/configs/ezx_defconfig418
-rw-r--r--arch/arm/configs/footbridge_defconfig125
-rw-r--r--arch/arm/configs/h3600_defconfig69
-rw-r--r--arch/arm/configs/h5000_defconfig82
-rw-r--r--arch/arm/configs/hackkit_defconfig49
-rw-r--r--arch/arm/configs/hisi_defconfig91
-rw-r--r--arch/arm/configs/imote2_defconfig390
-rw-r--r--arch/arm/configs/imx_v4_v5_defconfig192
-rw-r--r--arch/arm/configs/imx_v6_v7_defconfig356
-rw-r--r--arch/arm/configs/integrator_defconfig91
-rw-r--r--arch/arm/configs/iop13xx_defconfig124
-rw-r--r--arch/arm/configs/iop32x_defconfig136
-rw-r--r--arch/arm/configs/iop33x_defconfig92
-rw-r--r--arch/arm/configs/ixp4xx_defconfig205
-rw-r--r--arch/arm/configs/jornada720_defconfig112
-rw-r--r--arch/arm/configs/keystone_defconfig204
-rw-r--r--arch/arm/configs/ks8695_defconfig75
-rw-r--r--arch/arm/configs/kzm9g_defconfig154
-rw-r--r--arch/arm/configs/lart_defconfig75
-rw-r--r--arch/arm/configs/lpc32xx_defconfig211
-rw-r--r--arch/arm/configs/lpd270_defconfig65
-rw-r--r--arch/arm/configs/lubbock_defconfig56
-rw-r--r--arch/arm/configs/magician_defconfig182
-rw-r--r--arch/arm/configs/mainstone_defconfig55
-rw-r--r--arch/arm/configs/marzen_defconfig124
-rw-r--r--arch/arm/configs/mini2440_defconfig384
-rw-r--r--arch/arm/configs/mmp2_defconfig98
-rw-r--r--arch/arm/configs/moxart_defconfig149
-rw-r--r--arch/arm/configs/multi_v5_defconfig195
-rw-r--r--arch/arm/configs/multi_v7_defconfig592
-rw-r--r--arch/arm/configs/mv78xx0_defconfig139
-rw-r--r--arch/arm/configs/mvebu_v5_defconfig192
-rw-r--r--arch/arm/configs/mvebu_v7_defconfig144
-rw-r--r--arch/arm/configs/mxs_defconfig185
-rw-r--r--arch/arm/configs/neponset_defconfig88
-rw-r--r--arch/arm/configs/netwinder_defconfig87
-rw-r--r--arch/arm/configs/netx_defconfig86
-rw-r--r--arch/arm/configs/nhk8815_defconfig134
-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_defconfig258
-rw-r--r--arch/arm/configs/omap2plus_defconfig451
-rw-r--r--arch/arm/configs/orion5x_defconfig165
-rw-r--r--arch/arm/configs/palmz72_defconfig85
-rw-r--r--arch/arm/configs/pcm027_defconfig101
-rw-r--r--arch/arm/configs/pleb_defconfig57
-rw-r--r--arch/arm/configs/prima2_defconfig71
-rw-r--r--arch/arm/configs/pxa168_defconfig70
-rw-r--r--arch/arm/configs/pxa255-idp_defconfig59
-rw-r--r--arch/arm/configs/pxa3xx_defconfig132
-rw-r--r--arch/arm/configs/pxa910_defconfig80
-rw-r--r--arch/arm/configs/qcom_defconfig172
-rw-r--r--arch/arm/configs/raumfeld_defconfig207
-rw-r--r--arch/arm/configs/realview-smp_defconfig103
-rw-r--r--arch/arm/configs/realview_defconfig102
-rw-r--r--arch/arm/configs/rpc_defconfig134
-rw-r--r--arch/arm/configs/s3c2410_defconfig466
-rw-r--r--arch/arm/configs/s3c6400_defconfig95
-rw-r--r--arch/arm/configs/s5pv210_defconfig73
-rw-r--r--arch/arm/configs/sama5_defconfig216
-rw-r--r--arch/arm/configs/shannon_defconfig48
-rw-r--r--arch/arm/configs/shmobile_defconfig199
-rw-r--r--arch/arm/configs/simpad_defconfig111
-rw-r--r--arch/arm/configs/socfpga_defconfig110
-rw-r--r--arch/arm/configs/spear13xx_defconfig110
-rw-r--r--arch/arm/configs/spear3xx_defconfig89
-rw-r--r--arch/arm/configs/spear6xx_defconfig78
-rw-r--r--arch/arm/configs/spitz_defconfig273
-rw-r--r--arch/arm/configs/sunxi_defconfig121
-rw-r--r--arch/arm/configs/tct_hammer_defconfig69
-rw-r--r--arch/arm/configs/tegra_defconfig294
-rw-r--r--arch/arm/configs/trizeps4_defconfig225
-rw-r--r--arch/arm/configs/u300_defconfig71
-rw-r--r--arch/arm/configs/u8500_defconfig140
-rw-r--r--arch/arm/configs/versatile_defconfig87
-rw-r--r--arch/arm/configs/vexpress_defconfig161
-rw-r--r--arch/arm/configs/viper_defconfig173
-rw-r--r--arch/arm/configs/vt8500_v6_v7_defconfig89
-rw-r--r--arch/arm/configs/xcep_defconfig99
-rw-r--r--arch/arm/configs/zeus_defconfig188
-rw-r--r--arch/arm/crypto/.gitignore1
-rw-r--r--arch/arm/crypto/Kconfig130
-rw-r--r--arch/arm/crypto/Makefile48
-rw-r--r--arch/arm/crypto/aes-armv4.S1089
-rw-r--r--arch/arm/crypto/aes-ce-core.S518
-rw-r--r--arch/arm/crypto/aes-ce-glue.c524
-rw-r--r--arch/arm/crypto/aes_glue.c98
-rw-r--r--arch/arm/crypto/aes_glue.h19
-rw-r--r--arch/arm/crypto/aesbs-core.S_shipped2548
-rw-r--r--arch/arm/crypto/aesbs-glue.c437
-rw-r--r--arch/arm/crypto/bsaes-armv7.pl2471
-rw-r--r--arch/arm/crypto/ghash-ce-core.S94
-rw-r--r--arch/arm/crypto/ghash-ce-glue.c320
-rw-r--r--arch/arm/crypto/sha1-armv4-large.S497
-rw-r--r--arch/arm/crypto/sha1-armv7-neon.S639
-rw-r--r--arch/arm/crypto/sha1-ce-core.S125
-rw-r--r--arch/arm/crypto/sha1-ce-glue.c96
-rw-r--r--arch/arm/crypto/sha1.h13
-rw-r--r--arch/arm/crypto/sha1_glue.c95
-rw-r--r--arch/arm/crypto/sha1_neon_glue.c110
-rw-r--r--arch/arm/crypto/sha2-ce-core.S125
-rw-r--r--arch/arm/crypto/sha2-ce-glue.c114
-rw-r--r--arch/arm/crypto/sha256-armv4.pl716
-rw-r--r--arch/arm/crypto/sha256-core.S_shipped2808
-rw-r--r--arch/arm/crypto/sha256_glue.c128
-rw-r--r--arch/arm/crypto/sha256_glue.h14
-rw-r--r--arch/arm/crypto/sha256_neon_glue.c101
-rw-r--r--arch/arm/crypto/sha512-armv7-neon.S455
-rw-r--r--arch/arm/crypto/sha512_neon_glue.c305
-rw-r--r--arch/arm/firmware/Kconfig29
-rw-r--r--arch/arm/firmware/Makefile1
-rw-r--r--arch/arm/firmware/trusted_foundations.c99
-rw-r--r--arch/arm/include/asm/Kbuild39
-rw-r--r--arch/arm/include/asm/arch_timer.h113
-rw-r--r--arch/arm/include/asm/arm-cci.h42
-rw-r--r--arch/arm/include/asm/asm-offsets.h1
-rw-r--r--arch/arm/include/asm/assembler.h454
-rw-r--r--arch/arm/include/asm/atomic.h446
-rw-r--r--arch/arm/include/asm/auxvec.h1
-rw-r--r--arch/arm/include/asm/bL_switcher.h77
-rw-r--r--arch/arm/include/asm/barrier.h90
-rw-r--r--arch/arm/include/asm/bitops.h349
-rw-r--r--arch/arm/include/asm/bitrev.h20
-rw-r--r--arch/arm/include/asm/bug.h92
-rw-r--r--arch/arm/include/asm/bugs.h21
-rw-r--r--arch/arm/include/asm/cache.h28
-rw-r--r--arch/arm/include/asm/cacheflush.h502
-rw-r--r--arch/arm/include/asm/cachetype.h59
-rw-r--r--arch/arm/include/asm/checksum.h153
-rw-r--r--arch/arm/include/asm/clkdev.h31
-rw-r--r--arch/arm/include/asm/cmpxchg.h288
-rw-r--r--arch/arm/include/asm/compiler.h28
-rw-r--r--arch/arm/include/asm/cp15.h119
-rw-r--r--arch/arm/include/asm/cpu.h26
-rw-r--r--arch/arm/include/asm/cpuidle.h51
-rw-r--r--arch/arm/include/asm/cputype.h272
-rw-r--r--arch/arm/include/asm/cti.h159
-rw-r--r--arch/arm/include/asm/dcc.h41
-rw-r--r--arch/arm/include/asm/delay.h72
-rw-r--r--arch/arm/include/asm/device.h37
-rw-r--r--arch/arm/include/asm/div64.h227
-rw-r--r--arch/arm/include/asm/dma-contiguous.h14
-rw-r--r--arch/arm/include/asm/dma-iommu.h37
-rw-r--r--arch/arm/include/asm/dma-mapping.h338
-rw-r--r--arch/arm/include/asm/dma.h151
-rw-r--r--arch/arm/include/asm/domain.h109
-rw-r--r--arch/arm/include/asm/ecard.h218
-rw-r--r--arch/arm/include/asm/edac.h48
-rw-r--r--arch/arm/include/asm/elf.h143
-rw-r--r--arch/arm/include/asm/entry-macro-multi.S39
-rw-r--r--arch/arm/include/asm/exception.h19
-rw-r--r--arch/arm/include/asm/fb.h19
-rw-r--r--arch/arm/include/asm/fiq.h56
-rw-r--r--arch/arm/include/asm/firmware.h78
-rw-r--r--arch/arm/include/asm/fixmap.h25
-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.h59
-rw-r--r--arch/arm/include/asm/futex.h166
-rw-r--r--arch/arm/include/asm/glue-cache.h166
-rw-r--r--arch/arm/include/asm/glue-df.h102
-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.h25
-rw-r--r--arch/arm/include/asm/hardirq.h32
-rw-r--r--arch/arm/include/asm/hardware/arm_timer.h35
-rw-r--r--arch/arm/include/asm/hardware/cache-feroceon-l2.h13
-rw-r--r--arch/arm/include/asm/hardware/cache-l2x0.h181
-rw-r--r--arch/arm/include/asm/hardware/cache-tauros2.h14
-rw-r--r--arch/arm/include/asm/hardware/cp14.h542
-rw-r--r--arch/arm/include/asm/hardware/dec21285.h147
-rw-r--r--arch/arm/include/asm/hardware/entry-macro-iomd.S131
-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.h932
-rw-r--r--arch/arm/include/asm/hardware/iop3xx.h312
-rw-r--r--arch/arm/include/asm/hardware/iop_adma.h119
-rw-r--r--arch/arm/include/asm/hardware/it8152.h115
-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/sa1111.h475
-rw-r--r--arch/arm/include/asm/hardware/scoop.h71
-rw-r--r--arch/arm/include/asm/hardware/ssp.h28
-rw-r--r--arch/arm/include/asm/hardware/timer-sp.h23
-rw-r--r--arch/arm/include/asm/highmem.h74
-rw-r--r--arch/arm/include/asm/hugetlb-3level.h71
-rw-r--r--arch/arm/include/asm/hugetlb.h84
-rw-r--r--arch/arm/include/asm/hw_breakpoint.h139
-rw-r--r--arch/arm/include/asm/hw_irq.h22
-rw-r--r--arch/arm/include/asm/hwcap.h15
-rw-r--r--arch/arm/include/asm/hypervisor.h6
-rw-r--r--arch/arm/include/asm/ide.h23
-rw-r--r--arch/arm/include/asm/idmap.h14
-rw-r--r--arch/arm/include/asm/insn.h29
-rw-r--r--arch/arm/include/asm/io.h406
-rw-r--r--arch/arm/include/asm/irq.h41
-rw-r--r--arch/arm/include/asm/irq_work.h11
-rw-r--r--arch/arm/include/asm/irqflags.h165
-rw-r--r--arch/arm/include/asm/jump_label.h39
-rw-r--r--arch/arm/include/asm/kexec.h60
-rw-r--r--arch/arm/include/asm/kgdb.h106
-rw-r--r--arch/arm/include/asm/kmap_types.h9
-rw-r--r--arch/arm/include/asm/kprobes.h86
-rw-r--r--arch/arm/include/asm/kvm_arm.h221
-rw-r--r--arch/arm/include/asm/kvm_asm.h104
-rw-r--r--arch/arm/include/asm/kvm_coproc.h47
-rw-r--r--arch/arm/include/asm/kvm_emulate.h246
-rw-r--r--arch/arm/include/asm/kvm_host.h239
-rw-r--r--arch/arm/include/asm/kvm_mmio.h35
-rw-r--r--arch/arm/include/asm/kvm_mmu.h284
-rw-r--r--arch/arm/include/asm/kvm_psci.h27
-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/mach-types.h1
-rw-r--r--arch/arm/include/asm/mach/arch.h101
-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/irq.h33
-rw-r--r--arch/arm/include/asm/mach/map.h65
-rw-r--r--arch/arm/include/asm/mach/pci.h105
-rw-r--r--arch/arm/include/asm/mach/sharpsl_param.h37
-rw-r--r--arch/arm/include/asm/mach/time.h19
-rw-r--r--arch/arm/include/asm/mc146818rtc.h30
-rw-r--r--arch/arm/include/asm/mcpm.h358
-rw-r--r--arch/arm/include/asm/mcs_spinlock.h23
-rw-r--r--arch/arm/include/asm/memblock.h9
-rw-r--r--arch/arm/include/asm/memory.h359
-rw-r--r--arch/arm/include/asm/mmu.h40
-rw-r--r--arch/arm/include/asm/mmu_context.h142
-rw-r--r--arch/arm/include/asm/module.h49
-rw-r--r--arch/arm/include/asm/mpu.h76
-rw-r--r--arch/arm/include/asm/mtd-xip.h23
-rw-r--r--arch/arm/include/asm/mutex.h21
-rw-r--r--arch/arm/include/asm/neon.h36
-rw-r--r--arch/arm/include/asm/nwflash.h9
-rw-r--r--arch/arm/include/asm/opcodes-sec.h24
-rw-r--r--arch/arm/include/asm/opcodes-virt.h39
-rw-r--r--arch/arm/include/asm/opcodes.h231
-rw-r--r--arch/arm/include/asm/outercache.h149
-rw-r--r--arch/arm/include/asm/page-nommu.h46
-rw-r--r--arch/arm/include/asm/page.h173
-rw-r--r--arch/arm/include/asm/patch.h17
-rw-r--r--arch/arm/include/asm/pci.h55
-rw-r--r--arch/arm/include/asm/percpu.h52
-rw-r--r--arch/arm/include/asm/perf_event.h22
-rw-r--r--arch/arm/include/asm/pgalloc.h174
-rw-r--r--arch/arm/include/asm/pgtable-2level-hwdef.h95
-rw-r--r--arch/arm/include/asm/pgtable-2level-types.h67
-rw-r--r--arch/arm/include/asm/pgtable-2level.h198
-rw-r--r--arch/arm/include/asm/pgtable-3level-hwdef.h108
-rw-r--r--arch/arm/include/asm/pgtable-3level-types.h70
-rw-r--r--arch/arm/include/asm/pgtable-3level.h299
-rw-r--r--arch/arm/include/asm/pgtable-hwdef.h19
-rw-r--r--arch/arm/include/asm/pgtable-nommu.h114
-rw-r--r--arch/arm/include/asm/pgtable.h363
-rw-r--r--arch/arm/include/asm/pmu.h163
-rw-r--r--arch/arm/include/asm/probes.h58
-rw-r--r--arch/arm/include/asm/proc-fns.h160
-rw-r--r--arch/arm/include/asm/processor.h136
-rw-r--r--arch/arm/include/asm/procinfo.h49
-rw-r--r--arch/arm/include/asm/prom.h29
-rw-r--r--arch/arm/include/asm/psci.h48
-rw-r--r--arch/arm/include/asm/ptrace.h162
-rw-r--r--arch/arm/include/asm/setup.h28
-rw-r--r--arch/arm/include/asm/shmparam.h16
-rw-r--r--arch/arm/include/asm/signal.h22
-rw-r--r--arch/arm/include/asm/smp.h126
-rw-r--r--arch/arm/include/asm/smp_plat.h110
-rw-r--r--arch/arm/include/asm/smp_scu.h48
-rw-r--r--arch/arm/include/asm/smp_twd.h37
-rw-r--r--arch/arm/include/asm/sparsemem.h24
-rw-r--r--arch/arm/include/asm/spinlock.h287
-rw-r--r--arch/arm/include/asm/spinlock_types.h33
-rw-r--r--arch/arm/include/asm/stackprotector.h38
-rw-r--r--arch/arm/include/asm/stacktrace.h30
-rw-r--r--arch/arm/include/asm/string.h41
-rw-r--r--arch/arm/include/asm/suspend.h12
-rw-r--r--arch/arm/include/asm/swab.h38
-rw-r--r--arch/arm/include/asm/switch_to.h28
-rw-r--r--arch/arm/include/asm/sync_bitops.h26
-rw-r--r--arch/arm/include/asm/syscall.h112
-rw-r--r--arch/arm/include/asm/system_info.h28
-rw-r--r--arch/arm/include/asm/system_misc.h27
-rw-r--r--arch/arm/include/asm/tcm.h33
-rw-r--r--arch/arm/include/asm/therm.h28
-rw-r--r--arch/arm/include/asm/thread_info.h181
-rw-r--r--arch/arm/include/asm/thread_notify.h49
-rw-r--r--arch/arm/include/asm/timex.h18
-rw-r--r--arch/arm/include/asm/tlb.h267
-rw-r--r--arch/arm/include/asm/tlbflush.h686
-rw-r--r--arch/arm/include/asm/tls.h127
-rw-r--r--arch/arm/include/asm/topology.h36
-rw-r--r--arch/arm/include/asm/traps.h55
-rw-r--r--arch/arm/include/asm/trusted_foundations.h74
-rw-r--r--arch/arm/include/asm/types.h40
-rw-r--r--arch/arm/include/asm/uaccess.h519
-rw-r--r--arch/arm/include/asm/ucontext.h102
-rw-r--r--arch/arm/include/asm/unified.h142
-rw-r--r--arch/arm/include/asm/unistd.h62
-rw-r--r--arch/arm/include/asm/unwind.h61
-rw-r--r--arch/arm/include/asm/uprobes.h45
-rw-r--r--arch/arm/include/asm/user.h103
-rw-r--r--arch/arm/include/asm/v7m.h56
-rw-r--r--arch/arm/include/asm/vdso.h32
-rw-r--r--arch/arm/include/asm/vdso_datapage.h60
-rw-r--r--arch/arm/include/asm/vfp.h89
-rw-r--r--arch/arm/include/asm/vfpmacros.h65
-rw-r--r--arch/arm/include/asm/vga.h13
-rw-r--r--arch/arm/include/asm/virt.h81
-rw-r--r--arch/arm/include/asm/word-at-a-time.h98
-rw-r--r--arch/arm/include/asm/xen/events.h23
-rw-r--r--arch/arm/include/asm/xen/hypercall.h77
-rw-r--r--arch/arm/include/asm/xen/hypervisor.h21
-rw-r--r--arch/arm/include/asm/xen/interface.h82
-rw-r--r--arch/arm/include/asm/xen/page-coherent.h87
-rw-r--r--arch/arm/include/asm/xen/page.h115
-rw-r--r--arch/arm/include/asm/xor.h214
-rw-r--r--arch/arm/include/debug/8250.S54
-rw-r--r--arch/arm/include/debug/asm9260.S29
-rw-r--r--arch/arm/include/debug/at91.S52
-rw-r--r--arch/arm/include/debug/bcm63xx.S33
-rw-r--r--arch/arm/include/debug/clps711x.S38
-rw-r--r--arch/arm/include/debug/digicolor.S35
-rw-r--r--arch/arm/include/debug/efm32.S45
-rw-r--r--arch/arm/include/debug/exynos.S39
-rw-r--r--arch/arm/include/debug/icedcc.S90
-rw-r--r--arch/arm/include/debug/imx-uart.h119
-rw-r--r--arch/arm/include/debug/imx.S47
-rw-r--r--arch/arm/include/debug/ks8695.S40
-rw-r--r--arch/arm/include/debug/meson.S35
-rw-r--r--arch/arm/include/debug/msm.S54
-rw-r--r--arch/arm/include/debug/netx.S36
-rw-r--r--arch/arm/include/debug/omap2plus.S190
-rw-r--r--arch/arm/include/debug/pl01x.S38
-rw-r--r--arch/arm/include/debug/renesas-scif.S52
-rw-r--r--arch/arm/include/debug/s3c24xx.S46
-rw-r--r--arch/arm/include/debug/s5pv210.S34
-rw-r--r--arch/arm/include/debug/sa1100.S68
-rw-r--r--arch/arm/include/debug/samsung.S87
-rw-r--r--arch/arm/include/debug/sirf.S38
-rw-r--r--arch/arm/include/debug/sti.S61
-rw-r--r--arch/arm/include/debug/tegra.S226
-rw-r--r--arch/arm/include/debug/uncompress.h7
-rw-r--r--arch/arm/include/debug/ux500.S48
-rw-r--r--arch/arm/include/debug/vexpress.S51
-rw-r--r--arch/arm/include/debug/vf.S37
-rw-r--r--arch/arm/include/debug/vt8500.S37
-rw-r--r--arch/arm/include/debug/zynq.S56
-rw-r--r--arch/arm/include/uapi/asm/Kbuild20
-rw-r--r--arch/arm/include/uapi/asm/auxvec.h7
-rw-r--r--arch/arm/include/uapi/asm/byteorder.h25
-rw-r--r--arch/arm/include/uapi/asm/fcntl.h11
-rw-r--r--arch/arm/include/uapi/asm/hwcap.h40
-rw-r--r--arch/arm/include/uapi/asm/ioctls.h8
-rw-r--r--arch/arm/include/uapi/asm/kvm.h224
-rw-r--r--arch/arm/include/uapi/asm/kvm_para.h1
-rw-r--r--arch/arm/include/uapi/asm/mman.h4
-rw-r--r--arch/arm/include/uapi/asm/perf_regs.h23
-rw-r--r--arch/arm/include/uapi/asm/posix_types.h37
-rw-r--r--arch/arm/include/uapi/asm/ptrace.h157
-rw-r--r--arch/arm/include/uapi/asm/setup.h187
-rw-r--r--arch/arm/include/uapi/asm/sigcontext.h34
-rw-r--r--arch/arm/include/uapi/asm/signal.h120
-rw-r--r--arch/arm/include/uapi/asm/stat.h87
-rw-r--r--arch/arm/include/uapi/asm/statfs.h12
-rw-r--r--arch/arm/include/uapi/asm/swab.h53
-rw-r--r--arch/arm/include/uapi/asm/unistd.h448
-rw-r--r--arch/arm/kernel/.gitignore1
-rw-r--r--arch/arm/kernel/Makefile93
-rw-r--r--arch/arm/kernel/arch_timer.c44
-rw-r--r--arch/arm/kernel/armksyms.c171
-rw-r--r--arch/arm/kernel/asm-offsets.c214
-rw-r--r--arch/arm/kernel/atags.h20
-rw-r--r--arch/arm/kernel/atags_compat.c217
-rw-r--r--arch/arm/kernel/atags_parse.c238
-rw-r--r--arch/arm/kernel/atags_proc.c75
-rw-r--r--arch/arm/kernel/bios32.c647
-rw-r--r--arch/arm/kernel/calls.S406
-rw-r--r--arch/arm/kernel/cpuidle.c152
-rw-r--r--arch/arm/kernel/crash_dump.c57
-rw-r--r--arch/arm/kernel/debug.S138
-rw-r--r--arch/arm/kernel/devtree.c250
-rw-r--r--arch/arm/kernel/dma-isa.c222
-rw-r--r--arch/arm/kernel/dma.c298
-rw-r--r--arch/arm/kernel/early_printk.c46
-rw-r--r--arch/arm/kernel/elf.c91
-rw-r--r--arch/arm/kernel/entry-armv.S1238
-rw-r--r--arch/arm/kernel/entry-common.S388
-rw-r--r--arch/arm/kernel/entry-ftrace.S243
-rw-r--r--arch/arm/kernel/entry-header.S401
-rw-r--r--arch/arm/kernel/entry-v7m.S143
-rw-r--r--arch/arm/kernel/fiq.c164
-rw-r--r--arch/arm/kernel/fiqasm.S49
-rw-r--r--arch/arm/kernel/ftrace.c274
-rw-r--r--arch/arm/kernel/head-common.S223
-rw-r--r--arch/arm/kernel/head-nommu.S260
-rw-r--r--arch/arm/kernel/head.S712
-rw-r--r--arch/arm/kernel/hibernate.c106
-rw-r--r--arch/arm/kernel/hw_breakpoint.c1134
-rw-r--r--arch/arm/kernel/hyp-stub.S222
-rw-r--r--arch/arm/kernel/insn.c62
-rw-r--r--arch/arm/kernel/io.c84
-rw-r--r--arch/arm/kernel/irq.c198
-rw-r--r--arch/arm/kernel/isa.c70
-rw-r--r--arch/arm/kernel/iwmmxt.S372
-rw-r--r--arch/arm/kernel/jump_label.c38
-rw-r--r--arch/arm/kernel/kgdb.c287
-rw-r--r--arch/arm/kernel/machine_kexec.c195
-rw-r--r--arch/arm/kernel/module.c366
-rw-r--r--arch/arm/kernel/opcodes.c72
-rw-r--r--arch/arm/kernel/patch.c128
-rw-r--r--arch/arm/kernel/perf_callchain.c136
-rw-r--r--arch/arm/kernel/perf_event.c553
-rw-r--r--arch/arm/kernel/perf_event_cpu.c421
-rw-r--r--arch/arm/kernel/perf_event_v6.c566
-rw-r--r--arch/arm/kernel/perf_event_v7.c1908
-rw-r--r--arch/arm/kernel/perf_event_xscale.c753
-rw-r--r--arch/arm/kernel/perf_regs.c38
-rw-r--r--arch/arm/kernel/pj4-cp0.c133
-rw-r--r--arch/arm/kernel/process.c423
-rw-r--r--arch/arm/kernel/psci-call.S31
-rw-r--r--arch/arm/kernel/psci.c299
-rw-r--r--arch/arm/kernel/psci_smp.c115
-rw-r--r--arch/arm/kernel/ptrace.c977
-rw-r--r--arch/arm/kernel/reboot.c155
-rw-r--r--arch/arm/kernel/reboot.h7
-rw-r--r--arch/arm/kernel/relocate_kernel.S93
-rw-r--r--arch/arm/kernel/return_address.c61
-rw-r--r--arch/arm/kernel/setup.c1138
-rw-r--r--arch/arm/kernel/signal.c624
-rw-r--r--arch/arm/kernel/sigreturn_codes.S102
-rw-r--r--arch/arm/kernel/sleep.S162
-rw-r--r--arch/arm/kernel/smp.c724
-rw-r--r--arch/arm/kernel/smp_scu.c96
-rw-r--r--arch/arm/kernel/smp_tlb.c213
-rw-r--r--arch/arm/kernel/smp_twd.c414
-rw-r--r--arch/arm/kernel/stacktrace.c179
-rw-r--r--arch/arm/kernel/suspend.c102
-rw-r--r--arch/arm/kernel/swp_emulate.c269
-rw-r--r--arch/arm/kernel/sys_arm.c39
-rw-r--r--arch/arm/kernel/sys_oabi-compat.c456
-rw-r--r--arch/arm/kernel/tcm.c336
-rw-r--r--arch/arm/kernel/thumbee.c82
-rw-r--r--arch/arm/kernel/time.c125
-rw-r--r--arch/arm/kernel/topology.c318
-rw-r--r--arch/arm/kernel/traps.c889
-rw-r--r--arch/arm/kernel/unwind.c551
-rw-r--r--arch/arm/kernel/v7m.c19
-rw-r--r--arch/arm/kernel/vdso.c337
-rw-r--r--arch/arm/kernel/vmlinux.lds.S353
-rw-r--r--arch/arm/kernel/xscale-cp0.c177
-rw-r--r--arch/arm/kvm/Kconfig58
-rw-r--r--arch/arm/kvm/Makefile26
-rw-r--r--arch/arm/kvm/arm.c1154
-rw-r--r--arch/arm/kvm/coproc.c1262
-rw-r--r--arch/arm/kvm/coproc.h160
-rw-r--r--arch/arm/kvm/coproc_a15.c51
-rw-r--r--arch/arm/kvm/coproc_a7.c54
-rw-r--r--arch/arm/kvm/emulate.c402
-rw-r--r--arch/arm/kvm/guest.c292
-rw-r--r--arch/arm/kvm/handle_exit.c173
-rw-r--r--arch/arm/kvm/init.S159
-rw-r--r--arch/arm/kvm/interrupts.S524
-rw-r--r--arch/arm/kvm/interrupts_head.S649
-rw-r--r--arch/arm/kvm/mmio.c218
-rw-r--r--arch/arm/kvm/mmu.c1926
-rw-r--r--arch/arm/kvm/perf.c68
-rw-r--r--arch/arm/kvm/psci.c320
-rw-r--r--arch/arm/kvm/reset.c83
-rw-r--r--arch/arm/kvm/trace.h328
-rw-r--r--arch/arm/lib/Makefile41
-rw-r--r--arch/arm/lib/ashldi3.S54
-rw-r--r--arch/arm/lib/ashrdi3.S54
-rw-r--r--arch/arm/lib/backtrace.S152
-rw-r--r--arch/arm/lib/bitops.h106
-rw-r--r--arch/arm/lib/bswapsdi2.S37
-rw-r--r--arch/arm/lib/call_with_stack.S44
-rw-r--r--arch/arm/lib/changebit.S15
-rw-r--r--arch/arm/lib/clear_user.S54
-rw-r--r--arch/arm/lib/clearbit.S15
-rw-r--r--arch/arm/lib/copy_from_user.S109
-rw-r--r--arch/arm/lib/copy_page.S47
-rw-r--r--arch/arm/lib/copy_template.S297
-rw-r--r--arch/arm/lib/copy_to_user.S111
-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.S333
-rw-r--r--arch/arm/lib/csumpartialcopyuser.S83
-rw-r--r--arch/arm/lib/delay-loop.S68
-rw-r--r--arch/arm/lib/delay.c117
-rw-r--r--arch/arm/lib/div64.S212
-rw-r--r--arch/arm/lib/ecard.S44
-rw-r--r--arch/arm/lib/findbit.S196
-rw-r--r--arch/arm/lib/floppydma.S32
-rw-r--r--arch/arm/lib/getuser.S149
-rw-r--r--arch/arm/lib/io-acorn.S32
-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.S106
-rw-r--r--arch/arm/lib/io-readsw-armv4.S131
-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.S126
-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.S54
-rw-r--r--arch/arm/lib/memchr.S26
-rw-r--r--arch/arm/lib/memcpy.S68
-rw-r--r--arch/arm/lib/memmove.S227
-rw-r--r--arch/arm/lib/memset.S135
-rw-r--r--arch/arm/lib/memzero.S137
-rw-r--r--arch/arm/lib/muldi3.S48
-rw-r--r--arch/arm/lib/putuser.S98
-rw-r--r--arch/arm/lib/setbit.S15
-rw-r--r--arch/arm/lib/strchr.S27
-rw-r--r--arch/arm/lib/strrchr.S26
-rw-r--r--arch/arm/lib/testchangebit.S15
-rw-r--r--arch/arm/lib/testclearbit.S15
-rw-r--r--arch/arm/lib/testsetbit.S15
-rw-r--r--arch/arm/lib/uaccess_with_memcpy.c270
-rw-r--r--arch/arm/lib/ucmpdi2.S53
-rw-r--r--arch/arm/lib/xor-neon.c46
-rw-r--r--arch/arm/mach-alpine/Kconfig12
-rw-r--r--arch/arm/mach-alpine/Makefile2
-rw-r--r--arch/arm/mach-alpine/alpine_cpu_pm.c70
-rw-r--r--arch/arm/mach-alpine/alpine_cpu_pm.h26
-rw-r--r--arch/arm/mach-alpine/alpine_cpu_resume.h38
-rw-r--r--arch/arm/mach-alpine/alpine_machine.c28
-rw-r--r--arch/arm/mach-alpine/platsmp.c49
-rw-r--r--arch/arm/mach-asm9260/Kconfig8
-rw-r--r--arch/arm/mach-at91/Kconfig107
-rw-r--r--arch/arm/mach-at91/Makefile25
-rw-r--r--arch/arm/mach-at91/Makefile.boot8
-rw-r--r--arch/arm/mach-at91/at91rm9200.c49
-rw-r--r--arch/arm/mach-at91/at91sam9.c119
-rw-r--r--arch/arm/mach-at91/generic.h37
-rw-r--r--arch/arm/mach-at91/include/mach/at91_ramc.h28
-rw-r--r--arch/arm/mach-at91/include/mach/at91rm9200_mc.h116
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9_smc.h98
-rw-r--r--arch/arm/mach-at91/pm.c447
-rw-r--r--arch/arm/mach-at91/pm.h30
-rw-r--r--arch/arm/mach-at91/pm_suspend.S337
-rw-r--r--arch/arm/mach-at91/sam9_smc.c136
-rw-r--r--arch/arm/mach-at91/sam9_smc.h11
-rw-r--r--arch/arm/mach-at91/sama5.c76
-rw-r--r--arch/arm/mach-at91/soc.c97
-rw-r--r--arch/arm/mach-at91/soc.h78
-rw-r--r--arch/arm/mach-axxia/Kconfig16
-rw-r--r--arch/arm/mach-axxia/Makefile2
-rw-r--r--arch/arm/mach-axxia/axxia.c28
-rw-r--r--arch/arm/mach-axxia/platsmp.c89
-rw-r--r--arch/arm/mach-bcm/Kconfig154
-rw-r--r--arch/arm/mach-bcm/Makefile47
-rw-r--r--arch/arm/mach-bcm/bcm63xx.c27
-rw-r--r--arch/arm/mach-bcm/bcm_5301x.c56
-rw-r--r--arch/arm/mach-bcm/bcm_cygnus.c25
-rw-r--r--arch/arm/mach-bcm/bcm_kona_smc.c182
-rw-r--r--arch/arm/mach-bcm/bcm_kona_smc.h32
-rw-r--r--arch/arm/mach-bcm/board_bcm21664.c76
-rw-r--r--arch/arm/mach-bcm/board_bcm281xx.c74
-rw-r--r--arch/arm/mach-bcm/board_bcm2835.c137
-rw-r--r--arch/arm/mach-bcm/brcmstb.c28
-rw-r--r--arch/arm/mach-bcm/brcmstb.h19
-rw-r--r--arch/arm/mach-bcm/headsmp-brcmstb.S33
-rw-r--r--arch/arm/mach-bcm/kona_l2_cache.c47
-rw-r--r--arch/arm/mach-bcm/kona_l2_cache.h18
-rw-r--r--arch/arm/mach-bcm/kona_smp.c202
-rw-r--r--arch/arm/mach-bcm/platsmp-brcmstb.c370
-rw-r--r--arch/arm/mach-berlin/Kconfig35
-rw-r--r--arch/arm/mach-berlin/Makefile2
-rw-r--r--arch/arm/mach-berlin/berlin.c34
-rw-r--r--arch/arm/mach-berlin/headsmp.S30
-rw-r--r--arch/arm/mach-berlin/platsmp.c99
-rw-r--r--arch/arm/mach-clps711x/Kconfig38
-rw-r--r--arch/arm/mach-clps711x/Makefile13
-rw-r--r--arch/arm/mach-clps711x/Makefile.boot5
-rw-r--r--arch/arm/mach-clps711x/board-autcpu12.c275
-rw-r--r--arch/arm/mach-clps711x/board-cdb89712.c147
-rw-r--r--arch/arm/mach-clps711x/board-clep7312.c45
-rw-r--r--arch/arm/mach-clps711x/board-edb7211.c188
-rw-r--r--arch/arm/mach-clps711x/board-p720t.c373
-rw-r--r--arch/arm/mach-clps711x/common.c65
-rw-r--r--arch/arm/mach-clps711x/common.h23
-rw-r--r--arch/arm/mach-clps711x/devices.c149
-rw-r--r--arch/arm/mach-clps711x/devices.h12
-rw-r--r--arch/arm/mach-clps711x/include/mach/clps711x.h204
-rw-r--r--arch/arm/mach-clps711x/include/mach/hardware.h53
-rw-r--r--arch/arm/mach-clps711x/include/mach/uncompress.h55
-rw-r--r--arch/arm/mach-cns3xxx/Kconfig19
-rw-r--r--arch/arm/mach-cns3xxx/Makefile5
-rw-r--r--arch/arm/mach-cns3xxx/Makefile.boot3
-rw-r--r--arch/arm/mach-cns3xxx/cns3420vb.c255
-rw-r--r--arch/arm/mach-cns3xxx/cns3xxx.h602
-rw-r--r--arch/arm/mach-cns3xxx/core.c409
-rw-r--r--arch/arm/mach-cns3xxx/core.h35
-rw-r--r--arch/arm/mach-cns3xxx/devices.c111
-rw-r--r--arch/arm/mach-cns3xxx/devices.h20
-rw-r--r--arch/arm/mach-cns3xxx/pcie.c304
-rw-r--r--arch/arm/mach-cns3xxx/pm.c123
-rw-r--r--arch/arm/mach-cns3xxx/pm.h23
-rw-r--r--arch/arm/mach-davinci/Kconfig260
-rw-r--r--arch/arm/mach-davinci/Makefile40
-rw-r--r--arch/arm/mach-davinci/Makefile.boot7
-rw-r--r--arch/arm/mach-davinci/aemif.c218
-rw-r--r--arch/arm/mach-davinci/asp.h56
-rw-r--r--arch/arm/mach-davinci/board-da830-evm.c677
-rw-r--r--arch/arm/mach-davinci/board-da850-evm.c1510
-rw-r--r--arch/arm/mach-davinci/board-dm355-evm.c428
-rw-r--r--arch/arm/mach-davinci/board-dm355-leopard.c281
-rw-r--r--arch/arm/mach-davinci/board-dm365-evm.c787
-rw-r--r--arch/arm/mach-davinci/board-dm644x-evm.c823
-rw-r--r--arch/arm/mach-davinci/board-dm646x-evm.c809
-rw-r--r--arch/arm/mach-davinci/board-mityomapl138.c582
-rw-r--r--arch/arm/mach-davinci/board-neuros-osd2.c235
-rw-r--r--arch/arm/mach-davinci/board-omapl138-hawk.c348
-rw-r--r--arch/arm/mach-davinci/board-sffsdr.c158
-rw-r--r--arch/arm/mach-davinci/clock.c713
-rw-r--r--arch/arm/mach-davinci/clock.h140
-rw-r--r--arch/arm/mach-davinci/common.c124
-rw-r--r--arch/arm/mach-davinci/cp_intc.c222
-rw-r--r--arch/arm/mach-davinci/cpuidle.c102
-rw-r--r--arch/arm/mach-davinci/da830.c1217
-rw-r--r--arch/arm/mach-davinci/da850.c1348
-rw-r--r--arch/arm/mach-davinci/da8xx-dt.c79
-rw-r--r--arch/arm/mach-davinci/davinci.h123
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c1095
-rw-r--r--arch/arm/mach-davinci/devices.c350
-rw-r--r--arch/arm/mach-davinci/dm355.c1078
-rw-r--r--arch/arm/mach-davinci/dm365.c1439
-rw-r--r--arch/arm/mach-davinci/dm644x.c969
-rw-r--r--arch/arm/mach-davinci/dm646x.c966
-rw-r--r--arch/arm/mach-davinci/include/mach/clock.h24
-rw-r--r--arch/arm/mach-davinci/include/mach/common.h107
-rw-r--r--arch/arm/mach-davinci/include/mach/cp_intc.h57
-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.h86
-rw-r--r--arch/arm/mach-davinci/include/mach/da8xx.h154
-rw-r--r--arch/arm/mach-davinci/include/mach/ddr2.h4
-rw-r--r--arch/arm/mach-davinci/include/mach/entry-macro.S39
-rw-r--r--arch/arm/mach-davinci/include/mach/hardware.h33
-rw-r--r--arch/arm/mach-davinci/include/mach/irqs.h409
-rw-r--r--arch/arm/mach-davinci/include/mach/mux.h990
-rw-r--r--arch/arm/mach-davinci/include/mach/pm.h54
-rw-r--r--arch/arm/mach-davinci/include/mach/psc.h217
-rw-r--r--arch/arm/mach-davinci/include/mach/serial.h37
-rw-r--r--arch/arm/mach-davinci/include/mach/sram.h30
-rw-r--r--arch/arm/mach-davinci/include/mach/time.h35
-rw-r--r--arch/arm/mach-davinci/include/mach/uncompress.h97
-rw-r--r--arch/arm/mach-davinci/irq.c117
-rw-r--r--arch/arm/mach-davinci/mux.c116
-rw-r--r--arch/arm/mach-davinci/mux.h51
-rw-r--r--arch/arm/mach-davinci/pm.c158
-rw-r--r--arch/arm/mach-davinci/pm_domain.c65
-rw-r--r--arch/arm/mach-davinci/psc.c137
-rw-r--r--arch/arm/mach-davinci/serial.c106
-rw-r--r--arch/arm/mach-davinci/sleep.S228
-rw-r--r--arch/arm/mach-davinci/sram.c81
-rw-r--r--arch/arm/mach-davinci/time.c455
-rw-r--r--arch/arm/mach-davinci/usb.c175
-rw-r--r--arch/arm/mach-digicolor/Kconfig7
-rw-r--r--arch/arm/mach-digicolor/Makefile1
-rw-r--r--arch/arm/mach-digicolor/digicolor.c18
-rw-r--r--arch/arm/mach-dove/Kconfig25
-rw-r--r--arch/arm/mach-dove/Makefile5
-rw-r--r--arch/arm/mach-dove/Makefile.boot3
-rw-r--r--arch/arm/mach-dove/cm-a510.c97
-rw-r--r--arch/arm/mach-dove/common.c411
-rw-r--r--arch/arm/mach-dove/common.h49
-rw-r--r--arch/arm/mach-dove/dove-db-setup.c103
-rw-r--r--arch/arm/mach-dove/include/mach/bridge-regs.h57
-rw-r--r--arch/arm/mach-dove/include/mach/dove.h190
-rw-r--r--arch/arm/mach-dove/include/mach/entry-macro.S33
-rw-r--r--arch/arm/mach-dove/include/mach/hardware.h19
-rw-r--r--arch/arm/mach-dove/include/mach/irqs.h96
-rw-r--r--arch/arm/mach-dove/include/mach/pm.h72
-rw-r--r--arch/arm/mach-dove/include/mach/uncompress.h36
-rw-r--r--arch/arm/mach-dove/irq.c178
-rw-r--r--arch/arm/mach-dove/mpp.c162
-rw-r--r--arch/arm/mach-dove/mpp.h196
-rw-r--r--arch/arm/mach-dove/pcie.c216
-rw-r--r--arch/arm/mach-ebsa110/Makefile7
-rw-r--r--arch/arm/mach-ebsa110/Makefile.boot4
-rw-r--r--arch/arm/mach-ebsa110/core.c329
-rw-r--r--arch/arm/mach-ebsa110/core.h41
-rw-r--r--arch/arm/mach-ebsa110/include/mach/entry-macro.S33
-rw-r--r--arch/arm/mach-ebsa110/include/mach/hardware.h24
-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.h25
-rw-r--r--arch/arm/mach-ebsa110/include/mach/uncompress.h44
-rw-r--r--arch/arm/mach-ebsa110/io.c439
-rw-r--r--arch/arm/mach-ebsa110/leds.c71
-rw-r--r--arch/arm/mach-efm32/Makefile1
-rw-r--r--arch/arm/mach-efm32/Makefile.boot3
-rw-r--r--arch/arm/mach-efm32/dtmachine.c15
-rw-r--r--arch/arm/mach-ep93xx/Kconfig200
-rw-r--r--arch/arm/mach-ep93xx/Makefile18
-rw-r--r--arch/arm/mach-ep93xx/Makefile.boot14
-rw-r--r--arch/arm/mach-ep93xx/adssphere.c45
-rw-r--r--arch/arm/mach-ep93xx/clock.c563
-rw-r--r--arch/arm/mach-ep93xx/core.c1076
-rw-r--r--arch/arm/mach-ep93xx/crunch-bits.S313
-rw-r--r--arch/arm/mach-ep93xx/crunch.c88
-rw-r--r--arch/arm/mach-ep93xx/dma.c118
-rw-r--r--arch/arm/mach-ep93xx/edb93xx.c374
-rw-r--r--arch/arm/mach-ep93xx/gesbc9312.c45
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h41
-rw-r--r--arch/arm/mach-ep93xx/include/mach/gpio-ep93xx.h110
-rw-r--r--arch/arm/mach-ep93xx/include/mach/hardware.h24
-rw-r--r--arch/arm/mach-ep93xx/include/mach/irqs.h78
-rw-r--r--arch/arm/mach-ep93xx/include/mach/platform.h70
-rw-r--r--arch/arm/mach-ep93xx/include/mach/uncompress.h82
-rw-r--r--arch/arm/mach-ep93xx/micro9.c128
-rw-r--r--arch/arm/mach-ep93xx/simone.c89
-rw-r--r--arch/arm/mach-ep93xx/snappercl15.c182
-rw-r--r--arch/arm/mach-ep93xx/soc.h214
-rw-r--r--arch/arm/mach-ep93xx/ts72xx.c252
-rw-r--r--arch/arm/mach-ep93xx/ts72xx.h98
-rw-r--r--arch/arm/mach-ep93xx/vision_ep9307.c323
-rw-r--r--arch/arm/mach-exynos/Kconfig137
-rw-r--r--arch/arm/mach-exynos/Makefile25
-rw-r--r--arch/arm/mach-exynos/Makefile.boot2
-rw-r--r--arch/arm/mach-exynos/common.h178
-rw-r--r--arch/arm/mach-exynos/exynos-pmu.h24
-rw-r--r--arch/arm/mach-exynos/exynos-smc.S22
-rw-r--r--arch/arm/mach-exynos/exynos.c309
-rw-r--r--arch/arm/mach-exynos/firmware.c239
-rw-r--r--arch/arm/mach-exynos/headsmp.S40
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h43
-rw-r--r--arch/arm/mach-exynos/mcpm-exynos.c279
-rw-r--r--arch/arm/mach-exynos/mfc.h16
-rw-r--r--arch/arm/mach-exynos/platsmp.c458
-rw-r--r--arch/arm/mach-exynos/pm.c316
-rw-r--r--arch/arm/mach-exynos/pm_domains.c213
-rw-r--r--arch/arm/mach-exynos/pmu.c1005
-rw-r--r--arch/arm/mach-exynos/regs-pmu.h696
-rw-r--r--arch/arm/mach-exynos/sleep.S132
-rw-r--r--arch/arm/mach-exynos/smc.h44
-rw-r--r--arch/arm/mach-exynos/suspend.c746
-rw-r--r--arch/arm/mach-footbridge/Kconfig99
-rw-r--r--arch/arm/mach-footbridge/Makefile22
-rw-r--r--arch/arm/mach-footbridge/Makefile.boot4
-rw-r--r--arch/arm/mach-footbridge/cats-hw.c97
-rw-r--r--arch/arm/mach-footbridge/cats-pci.c63
-rw-r--r--arch/arm/mach-footbridge/common.c268
-rw-r--r--arch/arm/mach-footbridge/common.h14
-rw-r--r--arch/arm/mach-footbridge/dc21285-timer.c142
-rw-r--r--arch/arm/mach-footbridge/dc21285.c376
-rw-r--r--arch/arm/mach-footbridge/dma.c57
-rw-r--r--arch/arm/mach-footbridge/ebsa285-pci.c47
-rw-r--r--arch/arm/mach-footbridge/ebsa285.c123
-rw-r--r--arch/arm/mach-footbridge/include/mach/debug-macro.S42
-rw-r--r--arch/arm/mach-footbridge/include/mach/entry-macro.S107
-rw-r--r--arch/arm/mach-footbridge/include/mach/hardware.h99
-rw-r--r--arch/arm/mach-footbridge/include/mach/io.h23
-rw-r--r--arch/arm/mach-footbridge/include/mach/irqs.h96
-rw-r--r--arch/arm/mach-footbridge/include/mach/isa-dma.h25
-rw-r--r--arch/arm/mach-footbridge/include/mach/memory.h64
-rw-r--r--arch/arm/mach-footbridge/include/mach/uncompress.h37
-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.c40
-rw-r--r--arch/arm/mach-footbridge/isa.c101
-rw-r--r--arch/arm/mach-footbridge/netwinder-hw.c771
-rw-r--r--arch/arm/mach-footbridge/netwinder-pci.c61
-rw-r--r--arch/arm/mach-footbridge/personal-pci.c57
-rw-r--r--arch/arm/mach-footbridge/personal.c24
-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.c107
-rw-r--r--arch/arm/mach-gemini/board-rut1xx.c92
-rw-r--r--arch/arm/mach-gemini/board-wbd111.c134
-rw-r--r--arch/arm/mach-gemini/board-wbd222.c134
-rw-r--r--arch/arm/mach-gemini/common.h33
-rw-r--r--arch/arm/mach-gemini/devices.c118
-rw-r--r--arch/arm/mach-gemini/gpio.c231
-rw-r--r--arch/arm/mach-gemini/idle.c31
-rw-r--r--arch/arm/mach-gemini/include/mach/entry-macro.S33
-rw-r--r--arch/arm/mach-gemini/include/mach/global_reg.h278
-rw-r--r--arch/arm/mach-gemini/include/mach/hardware.h74
-rw-r--r--arch/arm/mach-gemini/include/mach/irqs.h53
-rw-r--r--arch/arm/mach-gemini/include/mach/uncompress.h42
-rw-r--r--arch/arm/mach-gemini/irq.c105
-rw-r--r--arch/arm/mach-gemini/mm.c82
-rw-r--r--arch/arm/mach-gemini/reset.c25
-rw-r--r--arch/arm/mach-gemini/time.c170
-rw-r--r--arch/arm/mach-highbank/Kconfig18
-rw-r--r--arch/arm/mach-highbank/Makefile6
-rw-r--r--arch/arm/mach-highbank/core.h17
-rw-r--r--arch/arm/mach-highbank/highbank.c189
-rw-r--r--arch/arm/mach-highbank/pm.c58
-rw-r--r--arch/arm/mach-highbank/smc.S27
-rw-r--r--arch/arm/mach-highbank/sysregs.h86
-rw-r--r--arch/arm/mach-highbank/system.c33
-rw-r--r--arch/arm/mach-hisi/Kconfig53
-rw-r--r--arch/arm/mach-hisi/Makefile9
-rw-r--r--arch/arm/mach-hisi/core.h23
-rw-r--r--arch/arm/mach-hisi/headsmp.S16
-rw-r--r--arch/arm/mach-hisi/hisilicon.c84
-rw-r--r--arch/arm/mach-hisi/hotplug.c291
-rw-r--r--arch/arm/mach-hisi/platmcpm.c386
-rw-r--r--arch/arm/mach-hisi/platsmp.c186
-rw-r--r--arch/arm/mach-imx/3ds_debugboard.c213
-rw-r--r--arch/arm/mach-imx/3ds_debugboard.h18
-rw-r--r--arch/arm/mach-imx/Kconfig630
-rw-r--r--arch/arm/mach-imx/Makefile108
-rw-r--r--arch/arm/mach-imx/anatop.c167
-rw-r--r--arch/arm/mach-imx/avic.c201
-rw-r--r--arch/arm/mach-imx/board-mx31lilly.h41
-rw-r--r--arch/arm/mach-imx/board-mx31lite.h42
-rw-r--r--arch/arm/mach-imx/board-mx31moboard.h43
-rw-r--r--arch/arm/mach-imx/clk-busy.c189
-rw-r--r--arch/arm/mach-imx/clk-cpu.c107
-rw-r--r--arch/arm/mach-imx/clk-fixup-div.c129
-rw-r--r--arch/arm/mach-imx/clk-fixup-mux.c108
-rw-r--r--arch/arm/mach-imx/clk-gate-exclusive.c94
-rw-r--r--arch/arm/mach-imx/clk-gate2.c160
-rw-r--r--arch/arm/mach-imx/clk-imx1.c117
-rw-r--r--arch/arm/mach-imx/clk-imx21.c171
-rw-r--r--arch/arm/mach-imx/clk-imx25.c264
-rw-r--r--arch/arm/mach-imx/clk-imx27.c258
-rw-r--r--arch/arm/mach-imx/clk-imx31.c204
-rw-r--r--arch/arm/mach-imx/clk-imx35.c296
-rw-r--r--arch/arm/mach-imx/clk-imx51-imx53.c573
-rw-r--r--arch/arm/mach-imx/clk-imx6q.c534
-rw-r--r--arch/arm/mach-imx/clk-imx6sl.c450
-rw-r--r--arch/arm/mach-imx/clk-imx6sx.c567
-rw-r--r--arch/arm/mach-imx/clk-pfd.c158
-rw-r--r--arch/arm/mach-imx/clk-pllv1.c126
-rw-r--r--arch/arm/mach-imx/clk-pllv2.c266
-rw-r--r--arch/arm/mach-imx/clk-pllv3.c331
-rw-r--r--arch/arm/mach-imx/clk-vf610.c412
-rw-r--r--arch/arm/mach-imx/clk.c75
-rw-r--r--arch/arm/mach-imx/clk.h139
-rw-r--r--arch/arm/mach-imx/common.h161
-rw-r--r--arch/arm/mach-imx/cpu-imx25.c51
-rw-r--r--arch/arm/mach-imx/cpu-imx27.c74
-rw-r--r--arch/arm/mach-imx/cpu-imx31.c63
-rw-r--r--arch/arm/mach-imx/cpu-imx35.c43
-rw-r--r--arch/arm/mach-imx/cpu-imx5.c127
-rw-r--r--arch/arm/mach-imx/cpu.c155
-rw-r--r--arch/arm/mach-imx/cpuidle-imx5.c36
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6q.c71
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6sl.c55
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6sx.c104
-rw-r--r--arch/arm/mach-imx/cpuidle.h35
-rw-r--r--arch/arm/mach-imx/crmregs-imx3.h261
-rw-r--r--arch/arm/mach-imx/devices-imx1.h30
-rw-r--r--arch/arm/mach-imx/devices-imx21.h59
-rw-r--r--arch/arm/mach-imx/devices-imx27.h89
-rw-r--r--arch/arm/mach-imx/devices-imx31.h83
-rw-r--r--arch/arm/mach-imx/devices-imx35.h90
-rw-r--r--arch/arm/mach-imx/devices/Kconfig74
-rw-r--r--arch/arm/mach-imx/devices/Makefile28
-rw-r--r--arch/arm/mach-imx/devices/devices-common.h309
-rw-r--r--arch/arm/mach-imx/devices/devices.c45
-rw-r--r--arch/arm/mach-imx/devices/platform-fec.c52
-rw-r--r--arch/arm/mach-imx/devices/platform-flexcan.c57
-rw-r--r--arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c54
-rw-r--r--arch/arm/mach-imx/devices/platform-gpio-mxc.c32
-rw-r--r--arch/arm/mach-imx/devices/platform-gpio_keys.c28
-rw-r--r--arch/arm/mach-imx/devices/platform-imx-dma.c51
-rw-r--r--arch/arm/mach-imx/devices/platform-imx-fb.c55
-rw-r--r--arch/arm/mach-imx/devices/platform-imx-i2c.c82
-rw-r--r--arch/arm/mach-imx/devices/platform-imx-keypad.c57
-rw-r--r--arch/arm/mach-imx/devices/platform-imx-ssi.c89
-rw-r--r--arch/arm/mach-imx/devices/platform-imx-uart.c132
-rw-r--r--arch/arm/mach-imx/devices/platform-imx2-wdt.c55
-rw-r--r--arch/arm/mach-imx/devices/platform-imx21-hcd.c41
-rw-r--r--arch/arm/mach-imx/devices/platform-imx27-coda.c37
-rw-r--r--arch/arm/mach-imx/devices/platform-ipu-core.c130
-rw-r--r--arch/arm/mach-imx/devices/platform-mx2-camera.c62
-rw-r--r--arch/arm/mach-imx/devices/platform-mx2-emma.c40
-rw-r--r--arch/arm/mach-imx/devices/platform-mxc-ehci.c64
-rw-r--r--arch/arm/mach-imx/devices/platform-mxc-mmc.c75
-rw-r--r--arch/arm/mach-imx/devices/platform-mxc_nand.c75
-rw-r--r--arch/arm/mach-imx/devices/platform-mxc_rnga.c53
-rw-r--r--arch/arm/mach-imx/devices/platform-mxc_rtc.c46
-rw-r--r--arch/arm/mach-imx/devices/platform-mxc_w1.c50
-rw-r--r--arch/arm/mach-imx/devices/platform-pata_imx.c49
-rw-r--r--arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c76
-rw-r--r--arch/arm/mach-imx/devices/platform-spi_imx.c89
-rw-r--r--arch/arm/mach-imx/ehci-imx27.c83
-rw-r--r--arch/arm/mach-imx/ehci-imx31.c83
-rw-r--r--arch/arm/mach-imx/ehci-imx35.c98
-rw-r--r--arch/arm/mach-imx/ehci.h43
-rw-r--r--arch/arm/mach-imx/epit.c225
-rw-r--r--arch/arm/mach-imx/eukrea-baseboards.h42
-rw-r--r--arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c318
-rw-r--r--arch/arm/mach-imx/gpc.c487
-rw-r--r--arch/arm/mach-imx/hardware.h127
-rw-r--r--arch/arm/mach-imx/headsmp.S31
-rw-r--r--arch/arm/mach-imx/hotplug.c70
-rw-r--r--arch/arm/mach-imx/iim.h77
-rw-r--r--arch/arm/mach-imx/imx1-dt.c26
-rw-r--r--arch/arm/mach-imx/imx27-dt.c41
-rw-r--r--arch/arm/mach-imx/imx31-dt.c37
-rw-r--r--arch/arm/mach-imx/imx35-dt.c39
-rw-r--r--arch/arm/mach-imx/iomux-imx31.c174
-rw-r--r--arch/arm/mach-imx/iomux-mx1.h155
-rw-r--r--arch/arm/mach-imx/iomux-mx21.h122
-rw-r--r--arch/arm/mach-imx/iomux-mx27.h205
-rw-r--r--arch/arm/mach-imx/iomux-mx2x.h230
-rw-r--r--arch/arm/mach-imx/iomux-mx3.h753
-rw-r--r--arch/arm/mach-imx/iomux-mx35.h1267
-rw-r--r--arch/arm/mach-imx/iomux-v1.c187
-rw-r--r--arch/arm/mach-imx/iomux-v1.h94
-rw-r--r--arch/arm/mach-imx/iomux-v3.c78
-rw-r--r--arch/arm/mach-imx/iomux-v3.h143
-rw-r--r--arch/arm/mach-imx/irq-common.c42
-rw-r--r--arch/arm/mach-imx/irq-common.h30
-rw-r--r--arch/arm/mach-imx/mach-apf9328.c148
-rw-r--r--arch/arm/mach-imx/mach-armadillo5x0.c569
-rw-r--r--arch/arm/mach-imx/mach-bug.c63
-rw-r--r--arch/arm/mach-imx/mach-cpuimx35.c206
-rw-r--r--arch/arm/mach-imx/mach-imx25.c46
-rw-r--r--arch/arm/mach-imx/mach-imx27_visstrim_m10.c611
-rw-r--r--arch/arm/mach-imx/mach-imx50.c27
-rw-r--r--arch/arm/mach-imx/mach-imx51.c80
-rw-r--r--arch/arm/mach-imx/mach-imx53.c58
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c411
-rw-r--r--arch/arm/mach-imx/mach-imx6sl.c81
-rw-r--r--arch/arm/mach-imx/mach-imx6sx.c109
-rw-r--r--arch/arm/mach-imx/mach-kzm_arm11_01.c295
-rw-r--r--arch/arm/mach-imx/mach-ls1021a.c22
-rw-r--r--arch/arm/mach-imx/mach-mx21ads.c333
-rw-r--r--arch/arm/mach-imx/mach-mx27_3ds.c551
-rw-r--r--arch/arm/mach-imx/mach-mx27ads.c397
-rw-r--r--arch/arm/mach-imx/mach-mx31_3ds.c783
-rw-r--r--arch/arm/mach-imx/mach-mx31ads.c588
-rw-r--r--arch/arm/mach-imx/mach-mx31lilly.c315
-rw-r--r--arch/arm/mach-imx/mach-mx31lite.c298
-rw-r--r--arch/arm/mach-imx/mach-mx31moboard.c605
-rw-r--r--arch/arm/mach-imx/mach-mx35_3ds.c623
-rw-r--r--arch/arm/mach-imx/mach-pca100.c427
-rw-r--r--arch/arm/mach-imx/mach-pcm037.c711
-rw-r--r--arch/arm/mach-imx/mach-pcm037_eet.c177
-rw-r--r--arch/arm/mach-imx/mach-pcm043.c407
-rw-r--r--arch/arm/mach-imx/mach-qong.c272
-rw-r--r--arch/arm/mach-imx/mach-scb9328.c143
-rw-r--r--arch/arm/mach-imx/mach-vf610.c27
-rw-r--r--arch/arm/mach-imx/mach-vpr200.c317
-rw-r--r--arch/arm/mach-imx/mm-imx1.c67
-rw-r--r--arch/arm/mach-imx/mm-imx21.c99
-rw-r--r--arch/arm/mach-imx/mm-imx27.c101
-rw-r--r--arch/arm/mach-imx/mm-imx3.c298
-rw-r--r--arch/arm/mach-imx/mmdc.c88
-rw-r--r--arch/arm/mach-imx/mx1.h172
-rw-r--r--arch/arm/mach-imx/mx21.h189
-rw-r--r--arch/arm/mach-imx/mx27.h238
-rw-r--r--arch/arm/mach-imx/mx2x.h145
-rw-r--r--arch/arm/mach-imx/mx31.h196
-rw-r--r--arch/arm/mach-imx/mx31lilly-db.c211
-rw-r--r--arch/arm/mach-imx/mx31lite-db.c196
-rw-r--r--arch/arm/mach-imx/mx31moboard-devboard.c246
-rw-r--r--arch/arm/mach-imx/mx31moboard-marxbot.c370
-rw-r--r--arch/arm/mach-imx/mx31moboard-smartbot.c207
-rw-r--r--arch/arm/mach-imx/mx35.h190
-rw-r--r--arch/arm/mach-imx/mx3x.h195
-rw-r--r--arch/arm/mach-imx/mxc.h200
-rw-r--r--arch/arm/mach-imx/pcm037.h17
-rw-r--r--arch/arm/mach-imx/platsmp.c129
-rw-r--r--arch/arm/mach-imx/pm-imx27.c49
-rw-r--r--arch/arm/mach-imx/pm-imx3.c38
-rw-r--r--arch/arm/mach-imx/pm-imx5.c235
-rw-r--r--arch/arm/mach-imx/pm-imx6.c600
-rw-r--r--arch/arm/mach-imx/src.c142
-rw-r--r--arch/arm/mach-imx/ssi-fiq-ksym.c20
-rw-r--r--arch/arm/mach-imx/ssi-fiq.S147
-rw-r--r--arch/arm/mach-imx/suspend-imx6.S346
-rw-r--r--arch/arm/mach-imx/system.c131
-rw-r--r--arch/arm/mach-imx/time.c385
-rw-r--r--arch/arm/mach-imx/tzic.c226
-rw-r--r--arch/arm/mach-imx/ulpi.h19
-rw-r--r--arch/arm/mach-integrator/Kconfig68
-rw-r--r--arch/arm/mach-integrator/Makefile12
-rw-r--r--arch/arm/mach-integrator/Makefile.boot4
-rw-r--r--arch/arm/mach-integrator/cm.h40
-rw-r--r--arch/arm/mach-integrator/common.h6
-rw-r--r--arch/arm/mach-integrator/core.c99
-rw-r--r--arch/arm/mach-integrator/hardware.h354
-rw-r--r--arch/arm/mach-integrator/impd1.c478
-rw-r--r--arch/arm/mach-integrator/impd1.h14
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c342
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c301
-rw-r--r--arch/arm/mach-integrator/lm.c99
-rw-r--r--arch/arm/mach-integrator/lm.h23
-rw-r--r--arch/arm/mach-integrator/pci_v3.c900
-rw-r--r--arch/arm/mach-integrator/pci_v3.h9
-rw-r--r--arch/arm/mach-iop13xx/Kconfig20
-rw-r--r--arch/arm/mach-iop13xx/Makefile8
-rw-r--r--arch/arm/mach-iop13xx/Makefile.boot3
-rw-r--r--arch/arm/mach-iop13xx/include/mach/adma.h621
-rw-r--r--arch/arm/mach-iop13xx/include/mach/entry-macro.S42
-rw-r--r--arch/arm/mach-iop13xx/include/mach/hardware.h21
-rw-r--r--arch/arm/mach-iop13xx/include/mach/iop13xx.h507
-rw-r--r--arch/arm/mach-iop13xx/include/mach/iq81340.h28
-rw-r--r--arch/arm/mach-iop13xx/include/mach/irqs.h194
-rw-r--r--arch/arm/mach-iop13xx/include/mach/memory.h67
-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/time.h126
-rw-r--r--arch/arm/mach-iop13xx/include/mach/uncompress.h22
-rw-r--r--arch/arm/mach-iop13xx/io.c90
-rw-r--r--arch/arm/mach-iop13xx/iq81340mc.c97
-rw-r--r--arch/arm/mach-iop13xx/iq81340sc.c99
-rw-r--r--arch/arm/mach-iop13xx/irq.c240
-rw-r--r--arch/arm/mach-iop13xx/msi.c165
-rw-r--r--arch/arm/mach-iop13xx/pci.c1119
-rw-r--r--arch/arm/mach-iop13xx/pci.h6
-rw-r--r--arch/arm/mach-iop13xx/setup.c608
-rw-r--r--arch/arm/mach-iop13xx/tpmi.c257
-rw-r--r--arch/arm/mach-iop32x/Kconfig46
-rw-r--r--arch/arm/mach-iop32x/Makefile11
-rw-r--r--arch/arm/mach-iop32x/Makefile.boot3
-rw-r--r--arch/arm/mach-iop32x/em7210.c231
-rw-r--r--arch/arm/mach-iop32x/glantank.c213
-rw-r--r--arch/arm/mach-iop32x/gpio-iop32x.h10
-rw-r--r--arch/arm/mach-iop32x/include/mach/adma.h5
-rw-r--r--arch/arm/mach-iop32x/include/mach/entry-macro.S33
-rw-r--r--arch/arm/mach-iop32x/include/mach/glantank.h13
-rw-r--r--arch/arm/mach-iop32x/include/mach/hardware.h41
-rw-r--r--arch/arm/mach-iop32x/include/mach/iop32x.h34
-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/n2100.h19
-rw-r--r--arch/arm/mach-iop32x/include/mach/time.h4
-rw-r--r--arch/arm/mach-iop32x/include/mach/uncompress.h38
-rw-r--r--arch/arm/mach-iop32x/iq31244.c333
-rw-r--r--arch/arm/mach-iop32x/iq80321.c192
-rw-r--r--arch/arm/mach-iop32x/irq.c74
-rw-r--r--arch/arm/mach-iop32x/n2100.c370
-rw-r--r--arch/arm/mach-iop33x/Kconfig21
-rw-r--r--arch/arm/mach-iop33x/Makefile8
-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/entry-macro.S34
-rw-r--r--arch/arm/mach-iop33x/include/mach/hardware.h43
-rw-r--r--arch/arm/mach-iop33x/include/mach/iop33x.h40
-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/time.h4
-rw-r--r--arch/arm/mach-iop33x/include/mach/uncompress.h36
-rw-r--r--arch/arm/mach-iop33x/iq80331.c152
-rw-r--r--arch/arm/mach-iop33x/iq80332.c152
-rw-r--r--arch/arm/mach-iop33x/irq.c118
-rw-r--r--arch/arm/mach-iop33x/uart.c103
-rw-r--r--arch/arm/mach-ixp4xx/Kconfig240
-rw-r--r--arch/arm/mach-ixp4xx/Makefile43
-rw-r--r--arch/arm/mach-ixp4xx/Makefile.boot3
-rw-r--r--arch/arm/mach-ixp4xx/avila-pci.c81
-rw-r--r--arch/arm/mach-ixp4xx/avila-setup.c199
-rw-r--r--arch/arm/mach-ixp4xx/common-pci.c455
-rw-r--r--arch/arm/mach-ixp4xx/common.c672
-rw-r--r--arch/arm/mach-ixp4xx/coyote-pci.c64
-rw-r--r--arch/arm/mach-ixp4xx/coyote-setup.c141
-rw-r--r--arch/arm/mach-ixp4xx/dsmg600-pci.c79
-rw-r--r--arch/arm/mach-ixp4xx/dsmg600-setup.c299
-rw-r--r--arch/arm/mach-ixp4xx/fsg-pci.c75
-rw-r--r--arch/arm/mach-ixp4xx/fsg-setup.c281
-rw-r--r--arch/arm/mach-ixp4xx/gateway7001-pci.c63
-rw-r--r--arch/arm/mach-ixp4xx/gateway7001-setup.c110
-rw-r--r--arch/arm/mach-ixp4xx/goramo_mlr.c517
-rw-r--r--arch/arm/mach-ixp4xx/gtwx5715-pci.c84
-rw-r--r--arch/arm/mach-ixp4xx/gtwx5715-setup.c179
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/cpu.h58
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/entry-macro.S41
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/hardware.h36
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/io.h530
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/irqs.h75
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/ixp46x_ts.h81
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h652
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/npe.h39
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/platform.h135
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/qmgr.h204
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/udc.h8
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/uncompress.h56
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-pci.c77
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-setup.c310
-rw-r--r--arch/arm/mach-ixp4xx/ixdpg425-pci.c58
-rw-r--r--arch/arm/mach-ixp4xx/ixp4xx_npe.c740
-rw-r--r--arch/arm/mach-ixp4xx/ixp4xx_qmgr.c372
-rw-r--r--arch/arm/mach-ixp4xx/miccpt-pci.c77
-rw-r--r--arch/arm/mach-ixp4xx/nas100d-pci.c75
-rw-r--r--arch/arm/mach-ixp4xx/nas100d-setup.c336
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-pci.c71
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-setup.c313
-rw-r--r--arch/arm/mach-ixp4xx/omixp-setup.c279
-rw-r--r--arch/arm/mach-ixp4xx/vulcan-pci.c72
-rw-r--r--arch/arm/mach-ixp4xx/vulcan-setup.c250
-rw-r--r--arch/arm/mach-ixp4xx/wg302v2-pci.c62
-rw-r--r--arch/arm/mach-ixp4xx/wg302v2-setup.c111
-rw-r--r--arch/arm/mach-keystone/Kconfig16
-rw-r--r--arch/arm/mach-keystone/Makefile9
-rw-r--r--arch/arm/mach-keystone/Makefile.boot1
-rw-r--r--arch/arm/mach-keystone/keystone.c119
-rw-r--r--arch/arm/mach-keystone/keystone.h24
-rw-r--r--arch/arm/mach-keystone/memory.h24
-rw-r--r--arch/arm/mach-keystone/platsmp.c57
-rw-r--r--arch/arm/mach-keystone/pm_domain.c80
-rw-r--r--arch/arm/mach-keystone/smc.S28
-rw-r--r--arch/arm/mach-ks8695/Kconfig87
-rw-r--r--arch/arm/mach-ks8695/Makefile22
-rw-r--r--arch/arm/mach-ks8695/Makefile.boot8
-rw-r--r--arch/arm/mach-ks8695/board-acs5k.c232
-rw-r--r--arch/arm/mach-ks8695/board-dsm320.c130
-rw-r--r--arch/arm/mach-ks8695/board-micrel.c62
-rw-r--r--arch/arm/mach-ks8695/board-og.c200
-rw-r--r--arch/arm/mach-ks8695/board-sg.c121
-rw-r--r--arch/arm/mach-ks8695/cpu.c73
-rw-r--r--arch/arm/mach-ks8695/devices.c197
-rw-r--r--arch/arm/mach-ks8695/generic.h16
-rw-r--r--arch/arm/mach-ks8695/include/mach/devices.h32
-rw-r--r--arch/arm/mach-ks8695/include/mach/entry-macro.S47
-rw-r--r--arch/arm/mach-ks8695/include/mach/gpio-ks8695.h39
-rw-r--r--arch/arm/mach-ks8695/include/mach/hardware.h45
-rw-r--r--arch/arm/mach-ks8695/include/mach/irqs.h54
-rw-r--r--arch/arm/mach-ks8695/include/mach/memory.h51
-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-uart.h92
-rw-r--r--arch/arm/mach-ks8695/include/mach/regs-wan.h65
-rw-r--r--arch/arm/mach-ks8695/include/mach/uncompress.h36
-rw-r--r--arch/arm/mach-ks8695/irq.c177
-rw-r--r--arch/arm/mach-ks8695/pci.c260
-rw-r--r--arch/arm/mach-ks8695/time.c173
-rw-r--r--arch/arm/mach-lpc32xx/Makefile8
-rw-r--r--arch/arm/mach-lpc32xx/Makefile.boot3
-rw-r--r--arch/arm/mach-lpc32xx/clock.c1287
-rw-r--r--arch/arm/mach-lpc32xx/clock.h38
-rw-r--r--arch/arm/mach-lpc32xx/common.c228
-rw-r--r--arch/arm/mach-lpc32xx/common.h66
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/board.h24
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/entry-macro.S37
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/hardware.h34
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/irqs.h117
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/platform.h712
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/uncompress.h59
-rw-r--r--arch/arm/mach-lpc32xx/irq.c477
-rw-r--r--arch/arm/mach-lpc32xx/phy3250.c267
-rw-r--r--arch/arm/mach-lpc32xx/pm.c146
-rw-r--r--arch/arm/mach-lpc32xx/serial.c130
-rw-r--r--arch/arm/mach-lpc32xx/suspend.S151
-rw-r--r--arch/arm/mach-lpc32xx/timer.c156
-rw-r--r--arch/arm/mach-mediatek/Kconfig27
-rw-r--r--arch/arm/mach-mediatek/Makefile1
-rw-r--r--arch/arm/mach-mediatek/mediatek.c30
-rw-r--r--arch/arm/mach-meson/Kconfig22
-rw-r--r--arch/arm/mach-meson/Makefile1
-rw-r--r--arch/arm/mach-meson/meson.c29
-rw-r--r--arch/arm/mach-mmp/Kconfig142
-rw-r--r--arch/arm/mach-mmp/Makefile36
-rw-r--r--arch/arm/mach-mmp/Makefile.boot1
-rw-r--r--arch/arm/mach-mmp/aspenite.c282
-rw-r--r--arch/arm/mach-mmp/avengers_lite.c58
-rw-r--r--arch/arm/mach-mmp/brownstone.c231
-rw-r--r--arch/arm/mach-mmp/clock-mmp2.c111
-rw-r--r--arch/arm/mach-mmp/clock-pxa168.c91
-rw-r--r--arch/arm/mach-mmp/clock-pxa910.c67
-rw-r--r--arch/arm/mach-mmp/clock.c105
-rw-r--r--arch/arm/mach-mmp/clock.h71
-rw-r--r--arch/arm/mach-mmp/common.c53
-rw-r--r--arch/arm/mach-mmp/common.h10
-rw-r--r--arch/arm/mach-mmp/devices.c351
-rw-r--r--arch/arm/mach-mmp/flint.c134
-rw-r--r--arch/arm/mach-mmp/gplugd.c209
-rw-r--r--arch/arm/mach-mmp/include/mach/addr-map.h46
-rw-r--r--arch/arm/mach-mmp/include/mach/cputype.h55
-rw-r--r--arch/arm/mach-mmp/include/mach/devices.h56
-rw-r--r--arch/arm/mach-mmp/include/mach/dma.h13
-rw-r--r--arch/arm/mach-mmp/include/mach/hardware.h4
-rw-r--r--arch/arm/mach-mmp/include/mach/irqs.h239
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp-mmp2.h395
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp-pxa168.h354
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp-pxa910.h169
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp.h34
-rw-r--r--arch/arm/mach-mmp/include/mach/mmp2.h102
-rw-r--r--arch/arm/mach-mmp/include/mach/pm-mmp2.h61
-rw-r--r--arch/arm/mach-mmp/include/mach/pm-pxa910.h77
-rw-r--r--arch/arm/mach-mmp/include/mach/pxa168.h137
-rw-r--r--arch/arm/mach-mmp/include/mach/pxa910.h87
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-apbc.h24
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-apmu.h33
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-icu.h71
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-rtc.h23
-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/regs-usb.h253
-rw-r--r--arch/arm/mach-mmp/include/mach/teton_bga.h27
-rw-r--r--arch/arm/mach-mmp/include/mach/uncompress.h45
-rw-r--r--arch/arm/mach-mmp/jasper.c188
-rw-r--r--arch/arm/mach-mmp/mmp-dt.c52
-rw-r--r--arch/arm/mach-mmp/mmp2-dt.c42
-rw-r--r--arch/arm/mach-mmp/mmp2.c177
-rw-r--r--arch/arm/mach-mmp/pm-mmp2.c250
-rw-r--r--arch/arm/mach-mmp/pm-pxa910.c273
-rw-r--r--arch/arm/mach-mmp/pxa168.c178
-rw-r--r--arch/arm/mach-mmp/pxa910.c191
-rw-r--r--arch/arm/mach-mmp/sram.c168
-rw-r--r--arch/arm/mach-mmp/tavorevb.c116
-rw-r--r--arch/arm/mach-mmp/teton_bga.c103
-rw-r--r--arch/arm/mach-mmp/time.c247
-rw-r--r--arch/arm/mach-mmp/ttc_dkb.c315
-rw-r--r--arch/arm/mach-moxart/Kconfig25
-rw-r--r--arch/arm/mach-moxart/Makefile3
-rw-r--r--arch/arm/mach-moxart/moxart.c15
-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/buffalo-wxl-setup.c155
-rw-r--r--arch/arm/mach-mv78xx0/common.c430
-rw-r--r--arch/arm/mach-mv78xx0/common.h55
-rw-r--r--arch/arm/mach-mv78xx0/db78x00-bp-setup.c103
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/bridge-regs.h37
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/entry-macro.S41
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/hardware.h14
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/irqs.h94
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/mv78xx0.h127
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/uncompress.h46
-rw-r--r--arch/arm/mach-mv78xx0/irq.c40
-rw-r--r--arch/arm/mach-mv78xx0/mpp.c37
-rw-r--r--arch/arm/mach-mv78xx0/mpp.h341
-rw-r--r--arch/arm/mach-mv78xx0/pcie.c269
-rw-r--r--arch/arm/mach-mv78xx0/rd78x00-masa-setup.c88
-rw-r--r--arch/arm/mach-mvebu/Kconfig126
-rw-r--r--arch/arm/mach-mvebu/Makefile16
-rw-r--r--arch/arm/mach-mvebu/armada-370-xp.h23
-rw-r--r--arch/arm/mach-mvebu/board-v7.c248
-rw-r--r--arch/arm/mach-mvebu/board.h21
-rw-r--r--arch/arm/mach-mvebu/coherency.c252
-rw-r--r--arch/arm/mach-mvebu/coherency.h23
-rw-r--r--arch/arm/mach-mvebu/coherency_ll.S166
-rw-r--r--arch/arm/mach-mvebu/common.h30
-rw-r--r--arch/arm/mach-mvebu/cpu-reset.c102
-rw-r--r--arch/arm/mach-mvebu/dove.c39
-rw-r--r--arch/arm/mach-mvebu/headsmp-a9.S27
-rw-r--r--arch/arm/mach-mvebu/headsmp.S40
-rw-r--r--arch/arm/mach-mvebu/include/mach/gpio.h1
-rw-r--r--arch/arm/mach-mvebu/kirkwood-pm.c76
-rw-r--r--arch/arm/mach-mvebu/kirkwood-pm.h26
-rw-r--r--arch/arm/mach-mvebu/kirkwood.c199
-rw-r--r--arch/arm/mach-mvebu/kirkwood.h22
-rw-r--r--arch/arm/mach-mvebu/mvebu-soc-id.c178
-rw-r--r--arch/arm/mach-mvebu/mvebu-soc-id.h54
-rw-r--r--arch/arm/mach-mvebu/netxbig.c191
-rw-r--r--arch/arm/mach-mvebu/platsmp-a9.c114
-rw-r--r--arch/arm/mach-mvebu/platsmp.c185
-rw-r--r--arch/arm/mach-mvebu/pm-board.c144
-rw-r--r--arch/arm/mach-mvebu/pm.c218
-rw-r--r--arch/arm/mach-mvebu/pmsu.c670
-rw-r--r--arch/arm/mach-mvebu/pmsu.h24
-rw-r--r--arch/arm/mach-mvebu/pmsu_ll.S75
-rw-r--r--arch/arm/mach-mvebu/system-controller.c180
-rw-r--r--arch/arm/mach-mxs/Kconfig26
-rw-r--r--arch/arm/mach-mxs/Makefile2
-rw-r--r--arch/arm/mach-mxs/mach-mxs.c543
-rw-r--r--arch/arm/mach-mxs/pm.c41
-rw-r--r--arch/arm/mach-mxs/pm.h18
-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.c79
-rw-r--r--arch/arm/mach-netx/fb.h24
-rw-r--r--arch/arm/mach-netx/generic.c195
-rw-r--r--arch/arm/mach-netx/generic.h26
-rw-r--r--arch/arm/mach-netx/include/mach/hardware.h39
-rw-r--r--arch/arm/mach-netx/include/mach/irqs.h70
-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/uncompress.h75
-rw-r--r--arch/arm/mach-netx/include/mach/xc.h42
-rw-r--r--arch/arm/mach-netx/nxdb500.c209
-rw-r--r--arch/arm/mach-netx/nxdkn.c102
-rw-r--r--arch/arm/mach-netx/nxeb500hmi.c186
-rw-r--r--arch/arm/mach-netx/pfifo.c68
-rw-r--r--arch/arm/mach-netx/time.c150
-rw-r--r--arch/arm/mach-netx/xc.c258
-rw-r--r--arch/arm/mach-nomadik/Kconfig30
-rw-r--r--arch/arm/mach-nomadik/Makefile11
-rw-r--r--arch/arm/mach-nomadik/cpu-8815.c159
-rw-r--r--arch/arm/mach-nspire/Kconfig11
-rw-r--r--arch/arm/mach-nspire/Makefile2
-rw-r--r--arch/arm/mach-nspire/Makefile.boot0
-rw-r--r--arch/arm/mach-nspire/clcd.c119
-rw-r--r--arch/arm/mach-nspire/clcd.h14
-rw-r--r--arch/arm/mach-nspire/mmio.h20
-rw-r--r--arch/arm/mach-nspire/nspire.c80
-rw-r--r--arch/arm/mach-omap1/Kconfig169
-rw-r--r--arch/arm/mach-omap1/Makefile63
-rw-r--r--arch/arm/mach-omap1/Makefile.boot3
-rw-r--r--arch/arm/mach-omap1/ams-delta-fiq-handler.S281
-rw-r--r--arch/arm/mach-omap1/ams-delta-fiq.c155
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c633
-rw-r--r--arch/arm/mach-omap1/board-fsample.c369
-rw-r--r--arch/arm/mach-omap1/board-generic.c89
-rw-r--r--arch/arm/mach-omap1/board-h2-mmc.c77
-rw-r--r--arch/arm/mach-omap1/board-h2.c433
-rw-r--r--arch/arm/mach-omap1/board-h2.h38
-rw-r--r--arch/arm/mach-omap1/board-h3-mmc.c66
-rw-r--r--arch/arm/mach-omap1/board-h3.c459
-rw-r--r--arch/arm/mach-omap1/board-h3.h35
-rw-r--r--arch/arm/mach-omap1/board-htcherald.c608
-rw-r--r--arch/arm/mach-omap1/board-innovator.c463
-rw-r--r--arch/arm/mach-omap1/board-nand.c37
-rw-r--r--arch/arm/mach-omap1/board-nokia770.c301
-rw-r--r--arch/arm/mach-omap1/board-osk.c617
-rw-r--r--arch/arm/mach-omap1/board-palmte.c242
-rw-r--r--arch/arm/mach-omap1/board-palmtt.c289
-rw-r--r--arch/arm/mach-omap1/board-palmz71.c304
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c331
-rw-r--r--arch/arm/mach-omap1/board-sx1-mmc.c67
-rw-r--r--arch/arm/mach-omap1/board-sx1.c350
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c295
-rw-r--r--arch/arm/mach-omap1/clock.c1104
-rw-r--r--arch/arm/mach-omap1/clock.h293
-rw-r--r--arch/arm/mach-omap1/clock_data.c924
-rw-r--r--arch/arm/mach-omap1/common.h104
-rw-r--r--arch/arm/mach-omap1/devices.c478
-rw-r--r--arch/arm/mach-omap1/dma.c378
-rw-r--r--arch/arm/mach-omap1/fb.c80
-rw-r--r--arch/arm/mach-omap1/flash.c28
-rw-r--r--arch/arm/mach-omap1/fpga.c190
-rw-r--r--arch/arm/mach-omap1/fpga.h52
-rw-r--r--arch/arm/mach-omap1/gpio15xx.c123
-rw-r--r--arch/arm/mach-omap1/gpio16xx.c257
-rw-r--r--arch/arm/mach-omap1/gpio7xx.c279
-rw-r--r--arch/arm/mach-omap1/i2c.c99
-rw-r--r--arch/arm/mach-omap1/id.c210
-rw-r--r--arch/arm/mach-omap1/include/mach/ams-delta-fiq.h77
-rw-r--r--arch/arm/mach-omap1/include/mach/board-ams-delta.h71
-rw-r--r--arch/arm/mach-omap1/include/mach/board-sx1.h52
-rw-r--r--arch/arm/mach-omap1/include/mach/board-voiceblue.h19
-rw-r--r--arch/arm/mach-omap1/include/mach/camera.h13
-rw-r--r--arch/arm/mach-omap1/include/mach/entry-macro.S39
-rw-r--r--arch/arm/mach-omap1/include/mach/flash.h17
-rw-r--r--arch/arm/mach-omap1/include/mach/hardware.h321
-rw-r--r--arch/arm/mach-omap1/include/mach/io.h45
-rw-r--r--arch/arm/mach-omap1/include/mach/irqs.h268
-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.h52
-rw-r--r--arch/arm/mach-omap1/include/mach/mtd-xip.h61
-rw-r--r--arch/arm/mach-omap1/include/mach/mux.h454
-rw-r--r--arch/arm/mach-omap1/include/mach/omap1510.h162
-rw-r--r--arch/arm/mach-omap1/include/mach/omap16xx.h201
-rw-r--r--arch/arm/mach-omap1/include/mach/omap7xx.h106
-rw-r--r--arch/arm/mach-omap1/include/mach/serial.h53
-rw-r--r--arch/arm/mach-omap1/include/mach/soc.h230
-rw-r--r--arch/arm/mach-omap1/include/mach/tc.h89
-rw-r--r--arch/arm/mach-omap1/include/mach/uncompress.h117
-rw-r--r--arch/arm/mach-omap1/include/mach/usb.h129
-rw-r--r--arch/arm/mach-omap1/io.c182
-rw-r--r--arch/arm/mach-omap1/iomap.h33
-rw-r--r--arch/arm/mach-omap1/irq.c245
-rw-r--r--arch/arm/mach-omap1/lcd_dma.c445
-rw-r--r--arch/arm/mach-omap1/mcbsp.c446
-rw-r--r--arch/arm/mach-omap1/mmc.h18
-rw-r--r--arch/arm/mach-omap1/mux.c525
-rw-r--r--arch/arm/mach-omap1/ocpi.c111
-rw-r--r--arch/arm/mach-omap1/opp.h29
-rw-r--r--arch/arm/mach-omap1/opp_data.c54
-rw-r--r--arch/arm/mach-omap1/pm.c708
-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.c63
-rw-r--r--arch/arm/mach-omap1/serial.c262
-rw-r--r--arch/arm/mach-omap1/sleep.S370
-rw-r--r--arch/arm/mach-omap1/soc.h4
-rw-r--r--arch/arm/mach-omap1/sram-init.c76
-rw-r--r--arch/arm/mach-omap1/sram.S61
-rw-r--r--arch/arm/mach-omap1/sram.h7
-rw-r--r--arch/arm/mach-omap1/time.c236
-rw-r--r--arch/arm/mach-omap1/timer.c174
-rw-r--r--arch/arm/mach-omap1/timer32k.c197
-rw-r--r--arch/arm/mach-omap1/usb.c653
-rw-r--r--arch/arm/mach-omap2/Kconfig269
-rw-r--r--arch/arm/mach-omap2/Makefile284
-rw-r--r--arch/arm/mach-omap2/Makefile.boot3
-rw-r--r--arch/arm/mach-omap2/am33xx-restart.c27
-rw-r--r--arch/arm/mach-omap2/am33xx.h27
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c769
-rw-r--r--arch/arm/mach-omap2/board-flash.c244
-rw-r--r--arch/arm/mach-omap2/board-flash.h61
-rw-r--r--arch/arm/mach-omap2/board-generic.c328
-rw-r--r--arch/arm/mach-omap2/board-ldp.c429
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c602
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c595
-rw-r--r--arch/arm/mach-omap2/board-omap3logic.c249
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c633
-rw-r--r--arch/arm/mach-omap2/board-overo.c571
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c1286
-rw-r--r--arch/arm/mach-omap2/board-rx51-video.c67
-rw-r--r--arch/arm/mach-omap2/board-rx51.c141
-rw-r--r--arch/arm/mach-omap2/board-rx51.h11
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_dpll.c59
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_dpllcore.c195
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c263
-rw-r--r--arch/arm/mach-omap2/clkt34xx_dpll3m2.c119
-rw-r--r--arch/arm/mach-omap2/clkt_clksel.c466
-rw-r--r--arch/arm/mach-omap2/clkt_dpll.c370
-rw-r--r--arch/arm/mach-omap2/clkt_iclk.c68
-rw-r--r--arch/arm/mach-omap2/clock.c849
-rw-r--r--arch/arm/mach-omap2/clock.h284
-rw-r--r--arch/arm/mach-omap2/clock2430.c57
-rw-r--r--arch/arm/mach-omap2/clock2xxx.c57
-rw-r--r--arch/arm/mach-omap2/clock2xxx.h45
-rw-r--r--arch/arm/mach-omap2/clock34xx.c138
-rw-r--r--arch/arm/mach-omap2/clock34xx.h18
-rw-r--r--arch/arm/mach-omap2/clock3517.c118
-rw-r--r--arch/arm/mach-omap2/clock3517.h14
-rw-r--r--arch/arm/mach-omap2/clock36xx.c69
-rw-r--r--arch/arm/mach-omap2/clock36xx.h13
-rw-r--r--arch/arm/mach-omap2/clock3xxx.c135
-rw-r--r--arch/arm/mach-omap2/clock3xxx.h20
-rw-r--r--arch/arm/mach-omap2/clock44xx.h20
-rw-r--r--arch/arm/mach-omap2/clock_common_data.c115
-rw-r--r--arch/arm/mach-omap2/clockdomain.c1297
-rw-r--r--arch/arm/mach-omap2/clockdomain.h238
-rw-r--r--arch/arm/mach-omap2/clockdomains2420_data.c153
-rw-r--r--arch/arm/mach-omap2/clockdomains2430_data.c180
-rw-r--r--arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c92
-rw-r--r--arch/arm/mach-omap2/clockdomains33xx_data.c196
-rw-r--r--arch/arm/mach-omap2/clockdomains3xxx_data.c525
-rw-r--r--arch/arm/mach-omap2/clockdomains43xx_data.c196
-rw-r--r--arch/arm/mach-omap2/clockdomains44xx_data.c443
-rw-r--r--arch/arm/mach-omap2/clockdomains54xx_data.c464
-rw-r--r--arch/arm/mach-omap2/clockdomains7xx_data.c740
-rw-r--r--arch/arm/mach-omap2/clockdomains81xx_data.c194
-rw-r--r--arch/arm/mach-omap2/cm-regbits-24xx.h135
-rw-r--r--arch/arm/mach-omap2/cm-regbits-33xx.h68
-rw-r--r--arch/arm/mach-omap2/cm-regbits-34xx.h217
-rw-r--r--arch/arm/mach-omap2/cm-regbits-44xx.h146
-rw-r--r--arch/arm/mach-omap2/cm-regbits-54xx.h104
-rw-r--r--arch/arm/mach-omap2/cm-regbits-7xx.h51
-rw-r--r--arch/arm/mach-omap2/cm.h78
-rw-r--r--arch/arm/mach-omap2/cm1_44xx.h220
-rw-r--r--arch/arm/mach-omap2/cm1_54xx.h211
-rw-r--r--arch/arm/mach-omap2/cm1_7xx.h322
-rw-r--r--arch/arm/mach-omap2/cm2_44xx.h452
-rw-r--r--arch/arm/mach-omap2/cm2_54xx.h387
-rw-r--r--arch/arm/mach-omap2/cm2_7xx.h515
-rw-r--r--arch/arm/mach-omap2/cm2xxx.c405
-rw-r--r--arch/arm/mach-omap2/cm2xxx.h70
-rw-r--r--arch/arm/mach-omap2/cm2xxx_3xxx.h120
-rw-r--r--arch/arm/mach-omap2/cm33xx.c364
-rw-r--r--arch/arm/mach-omap2/cm33xx.h380
-rw-r--r--arch/arm/mach-omap2/cm3xxx.c684
-rw-r--r--arch/arm/mach-omap2/cm3xxx.h79
-rw-r--r--arch/arm/mach-omap2/cm44xx.h28
-rw-r--r--arch/arm/mach-omap2/cm81xx.h61
-rw-r--r--arch/arm/mach-omap2/cm_common.c370
-rw-r--r--arch/arm/mach-omap2/cminst44xx.c528
-rw-r--r--arch/arm/mach-omap2/common-board-devices.c103
-rw-r--r--arch/arm/mach-omap2/common-board-devices.h20
-rw-r--r--arch/arm/mach-omap2/common.c33
-rw-r--r--arch/arm/mach-omap2/common.h325
-rw-r--r--arch/arm/mach-omap2/control.c748
-rw-r--r--arch/arm/mach-omap2/control.h481
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c337
-rw-r--r--arch/arm/mach-omap2/cpuidle44xx.c248
-rw-r--r--arch/arm/mach-omap2/ctrl_module_wkup_44xx.h92
-rw-r--r--arch/arm/mach-omap2/devices.c338
-rw-r--r--arch/arm/mach-omap2/devices.h19
-rw-r--r--arch/arm/mach-omap2/display.c680
-rw-r--r--arch/arm/mach-omap2/display.h36
-rw-r--r--arch/arm/mach-omap2/dma.c293
-rw-r--r--arch/arm/mach-omap2/dpll3xxx.c818
-rw-r--r--arch/arm/mach-omap2/dpll44xx.c232
-rw-r--r--arch/arm/mach-omap2/drm.c53
-rw-r--r--arch/arm/mach-omap2/dss-common.c37
-rw-r--r--arch/arm/mach-omap2/dss-common.h13
-rw-r--r--arch/arm/mach-omap2/fb.c115
-rw-r--r--arch/arm/mach-omap2/gpio.c160
-rw-r--r--arch/arm/mach-omap2/gpmc-nand.c159
-rw-r--r--arch/arm/mach-omap2/gpmc-onenand.c403
-rw-r--r--arch/arm/mach-omap2/gpmc-smsc911x.c100
-rw-r--r--arch/arm/mach-omap2/gpmc-smsc911x.h35
-rw-r--r--arch/arm/mach-omap2/gpmc.h14
-rw-r--r--arch/arm/mach-omap2/hdq1w.c99
-rw-r--r--arch/arm/mach-omap2/hdq1w.h36
-rw-r--r--arch/arm/mach-omap2/hsmmc.c505
-rw-r--r--arch/arm/mach-omap2/hsmmc.h46
-rw-r--r--arch/arm/mach-omap2/hwspinlock.c60
-rw-r--r--arch/arm/mach-omap2/i2c.c191
-rw-r--r--arch/arm/mach-omap2/i2c.h42
-rw-r--r--arch/arm/mach-omap2/id.c769
-rw-r--r--arch/arm/mach-omap2/id.h22
-rw-r--r--arch/arm/mach-omap2/include/mach/barriers.h33
-rw-r--r--arch/arm/mach-omap2/include/mach/hardware.h3
-rw-r--r--arch/arm/mach-omap2/include/mach/irqs.h3
-rw-r--r--arch/arm/mach-omap2/include/mach/serial.h66
-rw-r--r--arch/arm/mach-omap2/io.c745
-rw-r--r--arch/arm/mach-omap2/iomap.h196
-rw-r--r--arch/arm/mach-omap2/l3_2xxx.h20
-rw-r--r--arch/arm/mach-omap2/l3_3xxx.h20
-rw-r--r--arch/arm/mach-omap2/l4_2xxx.h24
-rw-r--r--arch/arm/mach-omap2/l4_3xxx.h34
-rw-r--r--arch/arm/mach-omap2/mcbsp.c122
-rw-r--r--arch/arm/mach-omap2/mmc.h13
-rw-r--r--arch/arm/mach-omap2/msdi.c90
-rw-r--r--arch/arm/mach-omap2/mux.c1153
-rw-r--r--arch/arm/mach-omap2/mux.h352
-rw-r--r--arch/arm/mach-omap2/mux34xx.c2061
-rw-r--r--arch/arm/mach-omap2/mux34xx.h402
-rw-r--r--arch/arm/mach-omap2/omap-headsmp.S123
-rw-r--r--arch/arm/mach-omap2/omap-hotplug.c66
-rw-r--r--arch/arm/mach-omap2/omap-iommu.c77
-rw-r--r--arch/arm/mach-omap2/omap-mpuss-lowpower.c446
-rw-r--r--arch/arm/mach-omap2/omap-pm-noop.c175
-rw-r--r--arch/arm/mach-omap2/omap-pm.h160
-rw-r--r--arch/arm/mach-omap2/omap-secure.c148
-rw-r--r--arch/arm/mach-omap2/omap-secure.h82
-rw-r--r--arch/arm/mach-omap2/omap-smc.S99
-rw-r--r--arch/arm/mach-omap2/omap-smp.c252
-rw-r--r--arch/arm/mach-omap2/omap-wakeupgen.c544
-rw-r--r--arch/arm/mach-omap2/omap-wakeupgen.h38
-rw-r--r--arch/arm/mach-omap2/omap2-restart.c65
-rw-r--r--arch/arm/mach-omap2/omap24xx.h87
-rw-r--r--arch/arm/mach-omap2/omap3-restart.c34
-rw-r--r--arch/arm/mach-omap2/omap34xx.h69
-rw-r--r--arch/arm/mach-omap2/omap4-common.c231
-rw-r--r--arch/arm/mach-omap2/omap4-restart.c26
-rw-r--r--arch/arm/mach-omap2/omap4-sar-layout.h60
-rw-r--r--arch/arm/mach-omap2/omap44xx.h61
-rw-r--r--arch/arm/mach-omap2/omap54xx.h37
-rw-r--r--arch/arm/mach-omap2/omap_device.c929
-rw-r--r--arch/arm/mach-omap2/omap_device.h104
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c3907
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.h758
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2420_data.c488
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2430_data.c711
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c172
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c285
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c272
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c882
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h163
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c633
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c1470
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_33xx_data.c642
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c3967
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_43xx_data.c1006
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c4864
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_54xx_data.c2854
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_7xx_data.c3422
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_81xx_data.c1136
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_common_data.c65
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_common_data.h171
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_common_ipblock_data.c55
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_reset.c53
-rw-r--r--arch/arm/mach-omap2/omap_opp_data.h99
-rw-r--r--arch/arm/mach-omap2/omap_phy_internal.c154
-rw-r--r--arch/arm/mach-omap2/omap_twl.c254
-rw-r--r--arch/arm/mach-omap2/opp.c104
-rw-r--r--arch/arm/mach-omap2/opp2420_data.c130
-rw-r--r--arch/arm/mach-omap2/opp2430_data.c135
-rw-r--r--arch/arm/mach-omap2/opp2xxx.h429
-rw-r--r--arch/arm/mach-omap2/opp3xxx_data.c171
-rw-r--r--arch/arm/mach-omap2/opp4xxx_data.c180
-rw-r--r--arch/arm/mach-omap2/pdata-quirks.c388
-rw-r--r--arch/arm/mach-omap2/pm-debug.c282
-rw-r--r--arch/arm/mach-omap2/pm.c321
-rw-r--r--arch/arm/mach-omap2/pm.h157
-rw-r--r--arch/arm/mach-omap2/pm24xx.c317
-rw-r--r--arch/arm/mach-omap2/pm34xx.c580
-rw-r--r--arch/arm/mach-omap2/pm44xx.c295
-rw-r--r--arch/arm/mach-omap2/pmu.c97
-rw-r--r--arch/arm/mach-omap2/powerdomain-common.c109
-rw-r--r--arch/arm/mach-omap2/powerdomain.c1208
-rw-r--r--arch/arm/mach-omap2/powerdomain.h276
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c65
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.h22
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_data.c137
-rw-r--r--arch/arm/mach-omap2/powerdomains33xx_data.c185
-rw-r--r--arch/arm/mach-omap2/powerdomains3xxx_data.c504
-rw-r--r--arch/arm/mach-omap2/powerdomains43xx_data.c136
-rw-r--r--arch/arm/mach-omap2/powerdomains44xx_data.c358
-rw-r--r--arch/arm/mach-omap2/powerdomains54xx_data.c330
-rw-r--r--arch/arm/mach-omap2/powerdomains7xx_data.c454
-rw-r--r--arch/arm/mach-omap2/prcm-common.h551
-rw-r--r--arch/arm/mach-omap2/prcm43xx.h149
-rw-r--r--arch/arm/mach-omap2/prcm44xx.h53
-rw-r--r--arch/arm/mach-omap2/prcm_mpu44xx.c62
-rw-r--r--arch/arm/mach-omap2/prcm_mpu44xx.h97
-rw-r--r--arch/arm/mach-omap2/prcm_mpu54xx.h87
-rw-r--r--arch/arm/mach-omap2/prcm_mpu7xx.h78
-rw-r--r--arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h36
-rw-r--r--arch/arm/mach-omap2/prm-regbits-24xx.h42
-rw-r--r--arch/arm/mach-omap2/prm-regbits-33xx.h52
-rw-r--r--arch/arm/mach-omap2/prm-regbits-34xx.h144
-rw-r--r--arch/arm/mach-omap2/prm-regbits-44xx.h102
-rw-r--r--arch/arm/mach-omap2/prm.h187
-rw-r--r--arch/arm/mach-omap2/prm2xxx.c232
-rw-r--r--arch/arm/mach-omap2/prm2xxx.h131
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c240
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.h248
-rw-r--r--arch/arm/mach-omap2/prm33xx.c390
-rw-r--r--arch/arm/mach-omap2/prm33xx.h124
-rw-r--r--arch/arm/mach-omap2/prm3xxx.c727
-rw-r--r--arch/arm/mach-omap2/prm3xxx.h153
-rw-r--r--arch/arm/mach-omap2/prm44xx.c764
-rw-r--r--arch/arm/mach-omap2/prm44xx.h747
-rw-r--r--arch/arm/mach-omap2/prm44xx_54xx.h43
-rw-r--r--arch/arm/mach-omap2/prm54xx.h420
-rw-r--r--arch/arm/mach-omap2/prm7xx.h682
-rw-r--r--arch/arm/mach-omap2/prm_common.c817
-rw-r--r--arch/arm/mach-omap2/prminst44xx.c196
-rw-r--r--arch/arm/mach-omap2/prminst44xx.h40
-rw-r--r--arch/arm/mach-omap2/scrm44xx.h177
-rw-r--r--arch/arm/mach-omap2/scrm54xx.h231
-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.c299
-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.c157
-rw-r--r--arch/arm/mach-omap2/sdrc.h213
-rw-r--r--arch/arm/mach-omap2/sdrc2xxx.c169
-rw-r--r--arch/arm/mach-omap2/serial.c332
-rw-r--r--arch/arm/mach-omap2/serial.h1
-rw-r--r--arch/arm/mach-omap2/sleep24xx.S105
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S598
-rw-r--r--arch/arm/mach-omap2/sleep44xx.S385
-rw-r--r--arch/arm/mach-omap2/smartreflex-class3.c62
-rw-r--r--arch/arm/mach-omap2/soc.h558
-rw-r--r--arch/arm/mach-omap2/sr_device.c177
-rw-r--r--arch/arm/mach-omap2/sram.c271
-rw-r--r--arch/arm/mach-omap2/sram.h76
-rw-r--r--arch/arm/mach-omap2/sram242x.S331
-rw-r--r--arch/arm/mach-omap2/sram243x.S331
-rw-r--r--arch/arm/mach-omap2/sram34xx.S346
-rw-r--r--arch/arm/mach-omap2/ti81xx-restart.c34
-rw-r--r--arch/arm/mach-omap2/ti81xx.h36
-rw-r--r--arch/arm/mach-omap2/timer.c801
-rw-r--r--arch/arm/mach-omap2/twl-common.c565
-rw-r--r--arch/arm/mach-omap2/twl-common.h66
-rw-r--r--arch/arm/mach-omap2/usb-host.c496
-rw-r--r--arch/arm/mach-omap2/usb-musb.c106
-rw-r--r--arch/arm/mach-omap2/usb-tusb6010.c255
-rw-r--r--arch/arm/mach-omap2/usb.h70
-rw-r--r--arch/arm/mach-omap2/vc.c847
-rw-r--r--arch/arm/mach-omap2/vc.h136
-rw-r--r--arch/arm/mach-omap2/vc3xxx_data.c96
-rw-r--r--arch/arm/mach-omap2/vc44xx_data.c118
-rw-r--r--arch/arm/mach-omap2/voltage.c336
-rw-r--r--arch/arm/mach-omap2/voltage.h173
-rw-r--r--arch/arm/mach-omap2/voltagedomains2xxx_data.c32
-rw-r--r--arch/arm/mach-omap2/voltagedomains3xxx_data.c134
-rw-r--r--arch/arm/mach-omap2/voltagedomains44xx_data.c130
-rw-r--r--arch/arm/mach-omap2/voltagedomains54xx_data.c92
-rw-r--r--arch/arm/mach-omap2/vp.c282
-rw-r--r--arch/arm/mach-omap2/vp.h126
-rw-r--r--arch/arm/mach-omap2/vp3xxx_data.c89
-rw-r--r--arch/arm/mach-omap2/vp44xx_data.c104
-rw-r--r--arch/arm/mach-omap2/wd_timer.c132
-rw-r--r--arch/arm/mach-omap2/wd_timer.h18
-rw-r--r--arch/arm/mach-orion5x/Kconfig165
-rw-r--r--arch/arm/mach-orion5x/Makefile25
-rw-r--r--arch/arm/mach-orion5x/Makefile.boot3
-rw-r--r--arch/arm/mach-orion5x/board-d2net.c109
-rw-r--r--arch/arm/mach-orion5x/board-dt.c82
-rw-r--r--arch/arm/mach-orion5x/board-mss2.c90
-rw-r--r--arch/arm/mach-orion5x/board-rd88f5182.c116
-rw-r--r--arch/arm/mach-orion5x/common.c379
-rw-r--r--arch/arm/mach-orion5x/common.h86
-rw-r--r--arch/arm/mach-orion5x/db88f5281-setup.c378
-rw-r--r--arch/arm/mach-orion5x/dns323-setup.c725
-rw-r--r--arch/arm/mach-orion5x/include/mach/bridge-regs.h37
-rw-r--r--arch/arm/mach-orion5x/include/mach/entry-macro.S25
-rw-r--r--arch/arm/mach-orion5x/include/mach/hardware.h14
-rw-r--r--arch/arm/mach-orion5x/include/mach/irqs.h60
-rw-r--r--arch/arm/mach-orion5x/include/mach/orion5x.h146
-rw-r--r--arch/arm/mach-orion5x/include/mach/uncompress.h48
-rw-r--r--arch/arm/mach-orion5x/irq.c65
-rw-r--r--arch/arm/mach-orion5x/kurobox_pro-setup.c408
-rw-r--r--arch/arm/mach-orion5x/ls-chl-setup.c330
-rw-r--r--arch/arm/mach-orion5x/ls_hgl-setup.c277
-rw-r--r--arch/arm/mach-orion5x/lsmini-setup.c280
-rw-r--r--arch/arm/mach-orion5x/mpp.c44
-rw-r--r--arch/arm/mach-orion5x/mpp.h129
-rw-r--r--arch/arm/mach-orion5x/mv2120-setup.c242
-rw-r--r--arch/arm/mach-orion5x/net2big-setup.c434
-rw-r--r--arch/arm/mach-orion5x/pci.c583
-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.c290
-rw-r--r--arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c129
-rw-r--r--arch/arm/mach-orion5x/terastation_pro2-setup.c369
-rw-r--r--arch/arm/mach-orion5x/ts209-setup.c334
-rw-r--r--arch/arm/mach-orion5x/ts409-setup.c323
-rw-r--r--arch/arm/mach-orion5x/ts78xx-fpga.h41
-rw-r--r--arch/arm/mach-orion5x/ts78xx-setup.c624
-rw-r--r--arch/arm/mach-orion5x/tsx09-common.c135
-rw-r--r--arch/arm/mach-orion5x/tsx09-common.h20
-rw-r--r--arch/arm/mach-orion5x/wnr854t-setup.c184
-rw-r--r--arch/arm/mach-orion5x/wrt350n-v2-setup.c272
-rw-r--r--arch/arm/mach-picoxcell/Kconfig7
-rw-r--r--arch/arm/mach-picoxcell/Makefile1
-rw-r--r--arch/arm/mach-picoxcell/common.c86
-rw-r--r--arch/arm/mach-prima2/Kconfig44
-rw-r--r--arch/arm/mach-prima2/Makefile8
-rw-r--r--arch/arm/mach-prima2/Makefile.boot3
-rw-r--r--arch/arm/mach-prima2/common.c65
-rw-r--r--arch/arm/mach-prima2/common.h31
-rw-r--r--arch/arm/mach-prima2/headsmp.S38
-rw-r--r--arch/arm/mach-prima2/hotplug.c38
-rw-r--r--arch/arm/mach-prima2/platsmp.c121
-rw-r--r--arch/arm/mach-prima2/pm.c153
-rw-r--r--arch/arm/mach-prima2/pm.h29
-rw-r--r--arch/arm/mach-prima2/rstc.c108
-rw-r--r--arch/arm/mach-prima2/rtciobrg.c138
-rw-r--r--arch/arm/mach-prima2/sleep.S64
-rw-r--r--arch/arm/mach-pxa/Kconfig703
-rw-r--r--arch/arm/mach-pxa/Makefile94
-rw-r--r--arch/arm/mach-pxa/Makefile.boot2
-rw-r--r--arch/arm/mach-pxa/am200epd.c386
-rw-r--r--arch/arm/mach-pxa/am300epd.c296
-rw-r--r--arch/arm/mach-pxa/balloon3.c828
-rw-r--r--arch/arm/mach-pxa/capc7117.c159
-rw-r--r--arch/arm/mach-pxa/clock-pxa2xx.c55
-rw-r--r--arch/arm/mach-pxa/clock-pxa3xx.c212
-rw-r--r--arch/arm/mach-pxa/clock.c86
-rw-r--r--arch/arm/mach-pxa/clock.h80
-rw-r--r--arch/arm/mach-pxa/cm-x255.c236
-rw-r--r--arch/arm/mach-pxa/cm-x270.c412
-rw-r--r--arch/arm/mach-pxa/cm-x2xx-pci.c199
-rw-r--r--arch/arm/mach-pxa/cm-x2xx-pci.h13
-rw-r--r--arch/arm/mach-pxa/cm-x2xx.c529
-rw-r--r--arch/arm/mach-pxa/cm-x300.c861
-rw-r--r--arch/arm/mach-pxa/colibri-evalboard.c120
-rw-r--r--arch/arm/mach-pxa/colibri-pxa270-income.c224
-rw-r--r--arch/arm/mach-pxa/colibri-pxa270.c330
-rw-r--r--arch/arm/mach-pxa/colibri-pxa300.c195
-rw-r--r--arch/arm/mach-pxa/colibri-pxa320.c265
-rw-r--r--arch/arm/mach-pxa/colibri-pxa3xx.c153
-rw-r--r--arch/arm/mach-pxa/corgi.c807
-rw-r--r--arch/arm/mach-pxa/corgi_pm.c231
-rw-r--r--arch/arm/mach-pxa/csb701.c66
-rw-r--r--arch/arm/mach-pxa/csb726.c283
-rw-r--r--arch/arm/mach-pxa/devices.c1195
-rw-r--r--arch/arm/mach-pxa/devices.h56
-rw-r--r--arch/arm/mach-pxa/em-x270.c1331
-rw-r--r--arch/arm/mach-pxa/eseries.c982
-rw-r--r--arch/arm/mach-pxa/ezx.c1268
-rw-r--r--arch/arm/mach-pxa/generic.c104
-rw-r--r--arch/arm/mach-pxa/generic.h80
-rw-r--r--arch/arm/mach-pxa/gumstix.c243
-rw-r--r--arch/arm/mach-pxa/h5000.c214
-rw-r--r--arch/arm/mach-pxa/himalaya.c169
-rw-r--r--arch/arm/mach-pxa/hx4700.c909
-rw-r--r--arch/arm/mach-pxa/icontrol.c199
-rw-r--r--arch/arm/mach-pxa/idp.c291
-rw-r--r--arch/arm/mach-pxa/include/mach/addr-map.h53
-rw-r--r--arch/arm/mach-pxa/include/mach/audio.h30
-rw-r--r--arch/arm/mach-pxa/include/mach/balloon3.h184
-rw-r--r--arch/arm/mach-pxa/include/mach/bitfield.h113
-rw-r--r--arch/arm/mach-pxa/include/mach/colibri.h69
-rw-r--r--arch/arm/mach-pxa/include/mach/corgi.h114
-rw-r--r--arch/arm/mach-pxa/include/mach/csb726.h28
-rw-r--r--arch/arm/mach-pxa/include/mach/dma.h21
-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/generic.h1
-rw-r--r--arch/arm/mach-pxa/include/mach/gumstix.h92
-rw-r--r--arch/arm/mach-pxa/include/mach/h5000.h113
-rw-r--r--arch/arm/mach-pxa/include/mach/hardware.h310
-rw-r--r--arch/arm/mach-pxa/include/mach/hx4700.h133
-rw-r--r--arch/arm/mach-pxa/include/mach/idp.h198
-rw-r--r--arch/arm/mach-pxa/include/mach/io.h17
-rw-r--r--arch/arm/mach-pxa/include/mach/irqs.h112
-rw-r--r--arch/arm/mach-pxa/include/mach/littleton.h13
-rw-r--r--arch/arm/mach-pxa/include/mach/lpd270.h43
-rw-r--r--arch/arm/mach-pxa/include/mach/lubbock.h56
-rw-r--r--arch/arm/mach-pxa/include/mach/magician.h120
-rw-r--r--arch/arm/mach-pxa/include/mach/mainstone.h141
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa25x.h225
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa27x.h471
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h142
-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.h75
-rw-r--r--arch/arm/mach-pxa/include/mach/mtd-xip.h35
-rw-r--r--arch/arm/mach-pxa/include/mach/mxm8x10.h21
-rw-r--r--arch/arm/mach-pxa/include/mach/palm27x.h81
-rw-r--r--arch/arm/mach-pxa/include/mach/palmld.h111
-rw-r--r--arch/arm/mach-pxa/include/mach/palmt5.h86
-rw-r--r--arch/arm/mach-pxa/include/mach/palmtc.h88
-rw-r--r--arch/arm/mach-pxa/include/mach/palmte2.h68
-rw-r--r--arch/arm/mach-pxa/include/mach/palmtreo.h68
-rw-r--r--arch/arm/mach-pxa/include/mach/palmtx.h114
-rw-r--r--arch/arm/mach-pxa/include/mach/palmz72.h84
-rw-r--r--arch/arm/mach-pxa/include/mach/pcm027.h86
-rw-r--r--arch/arm/mach-pxa/include/mach/pcm990_baseboard.h212
-rw-r--r--arch/arm/mach-pxa/include/mach/pm.h40
-rw-r--r--arch/arm/mach-pxa/include/mach/poodle.h94
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa25x-udc.h163
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa25x.h9
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa27x-udc.h257
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa27x.h25
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa2xx-regs.h197
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa300.h7
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa320.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa3xx-regs.h206
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa3xx.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa930.h7
-rw-r--r--arch/arm/mach-pxa/include/mach/regs-ac97.h101
-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.h75
-rw-r--r--arch/arm/mach-pxa/include/mach/spitz.h189
-rw-r--r--arch/arm/mach-pxa/include/mach/tosa.h202
-rw-r--r--arch/arm/mach-pxa/include/mach/tosa_bt.h22
-rw-r--r--arch/arm/mach-pxa/include/mach/trizeps4.h164
-rw-r--r--arch/arm/mach-pxa/include/mach/udc.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/uncompress.h74
-rw-r--r--arch/arm/mach-pxa/include/mach/viper.h94
-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.c274
-rw-r--r--arch/arm/mach-pxa/littleton.c453
-rw-r--r--arch/arm/mach-pxa/lpd270.c516
-rw-r--r--arch/arm/mach-pxa/lubbock.c606
-rw-r--r--arch/arm/mach-pxa/magician.c780
-rw-r--r--arch/arm/mach-pxa/mainstone.c667
-rw-r--r--arch/arm/mach-pxa/mfp-pxa2xx.c439
-rw-r--r--arch/arm/mach-pxa/mfp-pxa3xx.c59
-rw-r--r--arch/arm/mach-pxa/mioa701.c782
-rw-r--r--arch/arm/mach-pxa/mioa701_bootresume.S37
-rw-r--r--arch/arm/mach-pxa/mp900.c104
-rw-r--r--arch/arm/mach-pxa/mxm8x10.c475
-rw-r--r--arch/arm/mach-pxa/palm27x.c478
-rw-r--r--arch/arm/mach-pxa/palmld.c357
-rw-r--r--arch/arm/mach-pxa/palmt5.c218
-rw-r--r--arch/arm/mach-pxa/palmtc.c515
-rw-r--r--arch/arm/mach-pxa/palmte2.c370
-rw-r--r--arch/arm/mach-pxa/palmtreo.c560
-rw-r--r--arch/arm/mach-pxa/palmtx.c376
-rw-r--r--arch/arm/mach-pxa/palmz72.c414
-rw-r--r--arch/arm/mach-pxa/pcm027.c269
-rw-r--r--arch/arm/mach-pxa/pcm990-baseboard.c566
-rw-r--r--arch/arm/mach-pxa/pm.c118
-rw-r--r--arch/arm/mach-pxa/poodle.c477
-rw-r--r--arch/arm/mach-pxa/pxa-dt.c75
-rw-r--r--arch/arm/mach-pxa/pxa25x.c402
-rw-r--r--arch/arm/mach-pxa/pxa27x.c487
-rw-r--r--arch/arm/mach-pxa/pxa2xx.c56
-rw-r--r--arch/arm/mach-pxa/pxa300.c117
-rw-r--r--arch/arm/mach-pxa/pxa320.c100
-rw-r--r--arch/arm/mach-pxa/pxa3xx-ulpi.c390
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c507
-rw-r--r--arch/arm/mach-pxa/pxa930.c219
-rw-r--r--arch/arm/mach-pxa/pxa_cplds_irqs.c200
-rw-r--r--arch/arm/mach-pxa/raumfeld.c1131
-rw-r--r--arch/arm/mach-pxa/reset.c113
-rw-r--r--arch/arm/mach-pxa/saar.c607
-rw-r--r--arch/arm/mach-pxa/sharpsl_pm.c955
-rw-r--r--arch/arm/mach-pxa/sleep.S171
-rw-r--r--arch/arm/mach-pxa/smemc.c71
-rw-r--r--arch/arm/mach-pxa/spitz.c1029
-rw-r--r--arch/arm/mach-pxa/spitz_pm.c262
-rw-r--r--arch/arm/mach-pxa/standby.S114
-rw-r--r--arch/arm/mach-pxa/stargate2.c1028
-rw-r--r--arch/arm/mach-pxa/tavorevb.c506
-rw-r--r--arch/arm/mach-pxa/tosa-bt.c147
-rw-r--r--arch/arm/mach-pxa/tosa.c952
-rw-r--r--arch/arm/mach-pxa/trizeps4.c577
-rw-r--r--arch/arm/mach-pxa/viper.c1001
-rw-r--r--arch/arm/mach-pxa/vpac270.c725
-rw-r--r--arch/arm/mach-pxa/xcep.c191
-rw-r--r--arch/arm/mach-pxa/z2.c734
-rw-r--r--arch/arm/mach-pxa/zeus.c928
-rw-r--r--arch/arm/mach-pxa/zylonite.c439
-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-qcom/Kconfig25
-rw-r--r--arch/arm/mach-qcom/Makefile2
-rw-r--r--arch/arm/mach-qcom/board.c30
-rw-r--r--arch/arm/mach-qcom/platsmp.c363
-rw-r--r--arch/arm/mach-realview/Kconfig129
-rw-r--r--arch/arm/mach-realview/Makefile13
-rw-r--r--arch/arm/mach-realview/Makefile.boot9
-rw-r--r--arch/arm/mach-realview/core.c407
-rw-r--r--arch/arm/mach-realview/core.h60
-rw-r--r--arch/arm/mach-realview/hotplug.c111
-rw-r--r--arch/arm/mach-realview/include/mach/barriers.h8
-rw-r--r--arch/arm/mach-realview/include/mach/board-eb.h96
-rw-r--r--arch/arm/mach-realview/include/mach/board-pb1176.h83
-rw-r--r--arch/arm/mach-realview/include/mach/board-pb11mp.h98
-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/hardware.h42
-rw-r--r--arch/arm/mach-realview/include/mach/irqs-eb.h132
-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.h64
-rw-r--r--arch/arm/mach-realview/include/mach/platform.h249
-rw-r--r--arch/arm/mach-realview/include/mach/uncompress.h77
-rw-r--r--arch/arm/mach-realview/platsmp.c86
-rw-r--r--arch/arm/mach-realview/realview-dt.c32
-rw-r--r--arch/arm/mach-realview/realview_eb.c485
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c395
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c379
-rw-r--r--arch/arm/mach-realview/realview_pba8.c315
-rw-r--r--arch/arm/mach-realview/realview_pbx.c408
-rw-r--r--arch/arm/mach-rockchip/Kconfig20
-rw-r--r--arch/arm/mach-rockchip/Makefile5
-rw-r--r--arch/arm/mach-rockchip/core.h20
-rw-r--r--arch/arm/mach-rockchip/headsmp.S33
-rw-r--r--arch/arm/mach-rockchip/platsmp.c342
-rw-r--r--arch/arm/mach-rockchip/pm.c275
-rw-r--r--arch/arm/mach-rockchip/pm.h115
-rw-r--r--arch/arm/mach-rockchip/rockchip.c95
-rw-r--r--arch/arm/mach-rockchip/sleep.S73
-rw-r--r--arch/arm/mach-rpc/Makefile7
-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/ecard.c1140
-rw-r--r--arch/arm/mach-rpc/ecard.h69
-rw-r--r--arch/arm/mach-rpc/fiq.S16
-rw-r--r--arch/arm/mach-rpc/include/mach/acornfb.h140
-rw-r--r--arch/arm/mach-rpc/include/mach/entry-macro.S12
-rw-r--r--arch/arm/mach-rpc/include/mach/hardware.h76
-rw-r--r--arch/arm/mach-rpc/include/mach/io.h31
-rw-r--r--arch/arm/mach-rpc/include/mach/irqs.h45
-rw-r--r--arch/arm/mach-rpc/include/mach/isa-dma.h29
-rw-r--r--arch/arm/mach-rpc/include/mach/memory.h35
-rw-r--r--arch/arm/mach-rpc/include/mach/uncompress.h191
-rw-r--r--arch/arm/mach-rpc/irq.c168
-rw-r--r--arch/arm/mach-rpc/riscpc.c226
-rw-r--r--arch/arm/mach-rpc/time.c92
-rw-r--r--arch/arm/mach-s3c24xx/Kconfig590
-rw-r--r--arch/arm/mach-s3c24xx/Makefile101
-rw-r--r--arch/arm/mach-s3c24xx/Makefile.boot7
-rw-r--r--arch/arm/mach-s3c24xx/anubis.h53
-rw-r--r--arch/arm/mach-s3c24xx/bast-ide.c86
-rw-r--r--arch/arm/mach-s3c24xx/bast-irq.c157
-rw-r--r--arch/arm/mach-s3c24xx/bast.h197
-rw-r--r--arch/arm/mach-s3c24xx/common-smdk.c210
-rw-r--r--arch/arm/mach-s3c24xx/common-smdk.h14
-rw-r--r--arch/arm/mach-s3c24xx/common.c565
-rw-r--r--arch/arm/mach-s3c24xx/common.h129
-rw-r--r--arch/arm/mach-s3c24xx/cpufreq-utils.c66
-rw-r--r--arch/arm/mach-s3c24xx/gta02.h23
-rw-r--r--arch/arm/mach-s3c24xx/h1940-bluetooth.c147
-rw-r--r--arch/arm/mach-s3c24xx/h1940.h55
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/dma.h55
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/fb.h1
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/gpio-samsung.h104
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/hardware.h24
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/io.h211
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/irqs.h217
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/map.h172
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/pm-core.h87
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/regs-clock.h148
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/regs-gpio.h610
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/regs-irq.h53
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/regs-lcd.h162
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h192
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/rtc-core.h26
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/s3c2412.h26
-rw-r--r--arch/arm/mach-s3c24xx/iotiming-s3c2410.c478
-rw-r--r--arch/arm/mach-s3c24xx/iotiming-s3c2412.c284
-rw-r--r--arch/arm/mach-s3c24xx/irq-pm.c129
-rw-r--r--arch/arm/mach-s3c24xx/mach-amlm5900.c250
-rw-r--r--arch/arm/mach-s3c24xx/mach-anubis.c433
-rw-r--r--arch/arm/mach-s3c24xx/mach-at2440evb.c221
-rw-r--r--arch/arm/mach-s3c24xx/mach-bast.c594
-rw-r--r--arch/arm/mach-s3c24xx/mach-gta02.c600
-rw-r--r--arch/arm/mach-s3c24xx/mach-h1940.c751
-rw-r--r--arch/arm/mach-s3c24xx/mach-jive.c673
-rw-r--r--arch/arm/mach-s3c24xx/mach-mini2440.c698
-rw-r--r--arch/arm/mach-s3c24xx/mach-n30.c612
-rw-r--r--arch/arm/mach-s3c24xx/mach-nexcoder.c162
-rw-r--r--arch/arm/mach-s3c24xx/mach-osiris-dvs.c183
-rw-r--r--arch/arm/mach-s3c24xx/mach-osiris.c415
-rw-r--r--arch/arm/mach-s3c24xx/mach-otom.c125
-rw-r--r--arch/arm/mach-s3c24xx/mach-qt2410.c355
-rw-r--r--arch/arm/mach-s3c24xx/mach-rx1950.c816
-rw-r--r--arch/arm/mach-s3c24xx/mach-rx3715.c218
-rw-r--r--arch/arm/mach-s3c24xx/mach-s3c2416-dt.c54
-rw-r--r--arch/arm/mach-s3c24xx/mach-smdk2410.c127
-rw-r--r--arch/arm/mach-s3c24xx/mach-smdk2413.c163
-rw-r--r--arch/arm/mach-s3c24xx/mach-smdk2416.c265
-rw-r--r--arch/arm/mach-s3c24xx/mach-smdk2440.c188
-rw-r--r--arch/arm/mach-s3c24xx/mach-smdk2443.c153
-rw-r--r--arch/arm/mach-s3c24xx/mach-tct_hammer.c160
-rw-r--r--arch/arm/mach-s3c24xx/mach-vr1000.c343
-rw-r--r--arch/arm/mach-s3c24xx/mach-vstms.c168
-rw-r--r--arch/arm/mach-s3c24xx/osiris.h53
-rw-r--r--arch/arm/mach-s3c24xx/otom.h28
-rw-r--r--arch/arm/mach-s3c24xx/pll-s3c2410.c96
-rw-r--r--arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c98
-rw-r--r--arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c125
-rw-r--r--arch/arm/mach-s3c24xx/pm-h1940.S33
-rw-r--r--arch/arm/mach-s3c24xx/pm-s3c2410.c186
-rw-r--r--arch/arm/mach-s3c24xx/pm-s3c2412.c131
-rw-r--r--arch/arm/mach-s3c24xx/pm-s3c2416.c86
-rw-r--r--arch/arm/mach-s3c24xx/pm.c136
-rw-r--r--arch/arm/mach-s3c24xx/regs-dsc.h25
-rw-r--r--arch/arm/mach-s3c24xx/regs-mem.h54
-rw-r--r--arch/arm/mach-s3c24xx/s3c2410.c136
-rw-r--r--arch/arm/mach-s3c24xx/s3c2412-power.h37
-rw-r--r--arch/arm/mach-s3c24xx/s3c2412.c181
-rw-r--r--arch/arm/mach-s3c24xx/s3c2416.c147
-rw-r--r--arch/arm/mach-s3c24xx/s3c2440.c77
-rw-r--r--arch/arm/mach-s3c24xx/s3c2442.c78
-rw-r--r--arch/arm/mach-s3c24xx/s3c2443.c114
-rw-r--r--arch/arm/mach-s3c24xx/s3c244x.c135
-rw-r--r--arch/arm/mach-s3c24xx/setup-i2c.c28
-rw-r--r--arch/arm/mach-s3c24xx/setup-sdhci-gpio.c35
-rw-r--r--arch/arm/mach-s3c24xx/setup-spi.c31
-rw-r--r--arch/arm/mach-s3c24xx/setup-ts.c32
-rw-r--r--arch/arm/mach-s3c24xx/simtec-audio.c76
-rw-r--r--arch/arm/mach-s3c24xx/simtec-nor.c79
-rw-r--r--arch/arm/mach-s3c24xx/simtec-pm.c67
-rw-r--r--arch/arm/mach-s3c24xx/simtec-usb.c130
-rw-r--r--arch/arm/mach-s3c24xx/simtec.h21
-rw-r--r--arch/arm/mach-s3c24xx/sleep-s3c2410.S69
-rw-r--r--arch/arm/mach-s3c24xx/sleep-s3c2412.S68
-rw-r--r--arch/arm/mach-s3c24xx/sleep.S83
-rw-r--r--arch/arm/mach-s3c24xx/vr1000.h118
-rw-r--r--arch/arm/mach-s3c64xx/Kconfig316
-rw-r--r--arch/arm/mach-s3c64xx/Makefile56
-rw-r--r--arch/arm/mach-s3c64xx/Makefile.boot2
-rw-r--r--arch/arm/mach-s3c64xx/common.c442
-rw-r--r--arch/arm/mach-s3c64xx/common.h59
-rw-r--r--arch/arm/mach-s3c64xx/cpuidle.c62
-rw-r--r--arch/arm/mach-s3c64xx/crag6410.h25
-rw-r--r--arch/arm/mach-s3c64xx/dev-audio.c228
-rw-r--r--arch/arm/mach-s3c64xx/dev-uart.c71
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/debug-macro.S38
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/dma.h56
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h94
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/hardware.h16
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/irqs.h185
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/map.h126
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pm-core.h121
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-clock.h38
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-gpio.h187
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-irq.h19
-rw-r--r--arch/arm/mach-s3c64xx/irq-pm.c124
-rw-r--r--arch/arm/mach-s3c64xx/mach-anw6410.c238
-rw-r--r--arch/arm/mach-s3c64xx/mach-crag6410-module.c404
-rw-r--r--arch/arm/mach-s3c64xx/mach-crag6410.c863
-rw-r--r--arch/arm/mach-s3c64xx/mach-hmt.c282
-rw-r--r--arch/arm/mach-s3c64xx/mach-mini6410.c371
-rw-r--r--arch/arm/mach-s3c64xx/mach-ncp.c108
-rw-r--r--arch/arm/mach-s3c64xx/mach-real6410.c340
-rw-r--r--arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c76
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq.c400
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq.h20
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq5.c161
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq7.c177
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6400.c97
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c710
-rw-r--r--arch/arm/mach-s3c64xx/pl080.c244
-rw-r--r--arch/arm/mach-s3c64xx/pm.c351
-rw-r--r--arch/arm/mach-s3c64xx/regs-gpio-memport.h24
-rw-r--r--arch/arm/mach-s3c64xx/regs-modem.h30
-rw-r--r--arch/arm/mach-s3c64xx/regs-srom.h58
-rw-r--r--arch/arm/mach-s3c64xx/regs-sys.h30
-rw-r--r--arch/arm/mach-s3c64xx/regs-syscon-power.h115
-rw-r--r--arch/arm/mach-s3c64xx/s3c6400.c97
-rw-r--r--arch/arm/mach-s3c64xx/s3c6410.c100
-rw-r--r--arch/arm/mach-s3c64xx/setup-fb-24bpp.c28
-rw-r--r--arch/arm/mach-s3c64xx/setup-i2c0.c29
-rw-r--r--arch/arm/mach-s3c64xx/setup-i2c1.c29
-rw-r--r--arch/arm/mach-s3c64xx/setup-ide.c44
-rw-r--r--arch/arm/mach-s3c64xx/setup-keypad.c25
-rw-r--r--arch/arm/mach-s3c64xx/setup-sdhci-gpio.c58
-rw-r--r--arch/arm/mach-s3c64xx/setup-spi.c31
-rw-r--r--arch/arm/mach-s3c64xx/setup-usb-phy.c91
-rw-r--r--arch/arm/mach-s3c64xx/sleep.S72
-rw-r--r--arch/arm/mach-s5pv210/Kconfig34
-rw-r--r--arch/arm/mach-s5pv210/Makefile16
-rw-r--r--arch/arm/mach-s5pv210/common.h23
-rw-r--r--arch/arm/mach-s5pv210/pm.c179
-rw-r--r--arch/arm/mach-s5pv210/regs-clock.h201
-rw-r--r--arch/arm/mach-s5pv210/s5pv210.c77
-rw-r--r--arch/arm/mach-s5pv210/sleep.S36
-rw-r--r--arch/arm/mach-sa1100/Kconfig172
-rw-r--r--arch/arm/mach-sa1100/Makefile40
-rw-r--r--arch/arm/mach-sa1100/Makefile.boot8
-rw-r--r--arch/arm/mach-sa1100/assabet.c764
-rw-r--r--arch/arm/mach-sa1100/badge4.c344
-rw-r--r--arch/arm/mach-sa1100/cerf.c181
-rw-r--r--arch/arm/mach-sa1100/clock.c148
-rw-r--r--arch/arm/mach-sa1100/collie.c437
-rw-r--r--arch/arm/mach-sa1100/generic.c418
-rw-r--r--arch/arm/mach-sa1100/generic.h46
-rw-r--r--arch/arm/mach-sa1100/h3100.c143
-rw-r--r--arch/arm/mach-sa1100/h3600.c151
-rw-r--r--arch/arm/mach-sa1100/h3xxx.c317
-rw-r--r--arch/arm/mach-sa1100/hackkit.c236
-rw-r--r--arch/arm/mach-sa1100/include/mach/SA-1100.h1831
-rw-r--r--arch/arm/mach-sa1100/include/mach/SA-1101.h925
-rw-r--r--arch/arm/mach-sa1100/include/mach/assabet.h104
-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.h23
-rw-r--r--arch/arm/mach-sa1100/include/mach/collie.h95
-rw-r--r--arch/arm/mach-sa1100/include/mach/generic.h1
-rw-r--r--arch/arm/mach-sa1100/include/mach/h3xxx.h85
-rw-r--r--arch/arm/mach-sa1100/include/mach/hardware.h81
-rw-r--r--arch/arm/mach-sa1100/include/mach/irqs.h100
-rw-r--r--arch/arm/mach-sa1100/include/mach/jornada720.h32
-rw-r--r--arch/arm/mach-sa1100/include/mach/memory.h36
-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.h30
-rw-r--r--arch/arm/mach-sa1100/include/mach/reset.h18
-rw-r--r--arch/arm/mach-sa1100/include/mach/shannon.h39
-rw-r--r--arch/arm/mach-sa1100/include/mach/simpad.h158
-rw-r--r--arch/arm/mach-sa1100/include/mach/uncompress.h51
-rw-r--r--arch/arm/mach-sa1100/irq.c178
-rw-r--r--arch/arm/mach-sa1100/jornada720.c356
-rw-r--r--arch/arm/mach-sa1100/jornada720_ssp.c203
-rw-r--r--arch/arm/mach-sa1100/lart.c176
-rw-r--r--arch/arm/mach-sa1100/nanoengine.c117
-rw-r--r--arch/arm/mach-sa1100/neponset.c441
-rw-r--r--arch/arm/mach-sa1100/pci-nanoengine.c204
-rw-r--r--arch/arm/mach-sa1100/pleb.c147
-rw-r--r--arch/arm/mach-sa1100/pm.c126
-rw-r--r--arch/arm/mach-sa1100/shannon.c109
-rw-r--r--arch/arm/mach-sa1100/simpad.c402
-rw-r--r--arch/arm/mach-sa1100/sleep.S143
-rw-r--r--arch/arm/mach-sa1100/ssp.c243
-rw-r--r--arch/arm/mach-shmobile/Kconfig213
-rw-r--r--arch/arm/mach-shmobile/Makefile65
-rw-r--r--arch/arm/mach-shmobile/Makefile.boot15
-rw-r--r--arch/arm/mach-shmobile/board-armadillo800eva.c1365
-rw-r--r--arch/arm/mach-shmobile/board-bockw-reference.c86
-rw-r--r--arch/arm/mach-shmobile/board-bockw.c737
-rw-r--r--arch/arm/mach-shmobile/board-kzm9g.c916
-rw-r--r--arch/arm/mach-shmobile/board-marzen-reference.c56
-rw-r--r--arch/arm/mach-shmobile/board-marzen.c347
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7740.c675
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7778.c342
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7779.c271
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c752
-rw-r--r--arch/arm/mach-shmobile/clock.c47
-rw-r--r--arch/arm/mach-shmobile/clock.h42
-rw-r--r--arch/arm/mach-shmobile/common.h48
-rw-r--r--arch/arm/mach-shmobile/console.c27
-rw-r--r--arch/arm/mach-shmobile/cpufreq.c17
-rw-r--r--arch/arm/mach-shmobile/dma-register.h84
-rw-r--r--arch/arm/mach-shmobile/headsmp-scu.S46
-rw-r--r--arch/arm/mach-shmobile/headsmp.S98
-rw-r--r--arch/arm/mach-shmobile/include/mach/head-kzm9g.txt410
-rw-r--r--arch/arm/mach-shmobile/include/mach/irqs.h10
-rw-r--r--arch/arm/mach-shmobile/include/mach/zboot.h19
-rw-r--r--arch/arm/mach-shmobile/include/mach/zboot_macros.h108
-rw-r--r--arch/arm/mach-shmobile/intc-sh73a0.c337
-rw-r--r--arch/arm/mach-shmobile/intc.h295
-rw-r--r--arch/arm/mach-shmobile/irqs.h15
-rw-r--r--arch/arm/mach-shmobile/platsmp-apmu.c238
-rw-r--r--arch/arm/mach-shmobile/platsmp-apmu.h32
-rw-r--r--arch/arm/mach-shmobile/platsmp-scu.c97
-rw-r--r--arch/arm/mach-shmobile/platsmp.c38
-rw-r--r--arch/arm/mach-shmobile/pm-r8a7740.c129
-rw-r--r--arch/arm/mach-shmobile/pm-r8a7779.c143
-rw-r--r--arch/arm/mach-shmobile/pm-rcar-gen2.c115
-rw-r--r--arch/arm/mach-shmobile/pm-rcar.c137
-rw-r--r--arch/arm/mach-shmobile/pm-rcar.h15
-rw-r--r--arch/arm/mach-shmobile/pm-rmobile.c434
-rw-r--r--arch/arm/mach-shmobile/pm-rmobile.h64
-rw-r--r--arch/arm/mach-shmobile/pm-sh73a0.c32
-rw-r--r--arch/arm/mach-shmobile/r8a7740.h58
-rw-r--r--arch/arm/mach-shmobile/r8a7778.h78
-rw-r--r--arch/arm/mach-shmobile/r8a7779.h35
-rw-r--r--arch/arm/mach-shmobile/r8a7790.h6
-rw-r--r--arch/arm/mach-shmobile/r8a7791.h6
-rw-r--r--arch/arm/mach-shmobile/rcar-gen2.h10
-rw-r--r--arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c147
-rw-r--r--arch/arm/mach-shmobile/setup-emev2.c53
-rw-r--r--arch/arm/mach-shmobile/setup-r7s72100.c32
-rw-r--r--arch/arm/mach-shmobile/setup-r8a73a4.c32
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7740.c859
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7778.c633
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7779.c771
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7790.c37
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7791.c38
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7794.c33
-rw-r--r--arch/arm/mach-shmobile/setup-rcar-gen2.c203
-rw-r--r--arch/arm/mach-shmobile/setup-sh73a0.c810
-rw-r--r--arch/arm/mach-shmobile/sh-gpio.h29
-rw-r--r--arch/arm/mach-shmobile/sh73a0.h89
-rw-r--r--arch/arm/mach-shmobile/smp-emev2.c55
-rw-r--r--arch/arm/mach-shmobile/smp-r8a7779.c136
-rw-r--r--arch/arm/mach-shmobile/smp-r8a7790.c71
-rw-r--r--arch/arm/mach-shmobile/smp-r8a7791.c65
-rw-r--r--arch/arm/mach-shmobile/smp-sh73a0.c75
-rw-r--r--arch/arm/mach-shmobile/suspend.c48
-rw-r--r--arch/arm/mach-shmobile/timer.c112
-rw-r--r--arch/arm/mach-socfpga/Kconfig10
-rw-r--r--arch/arm/mach-socfpga/Makefile6
-rw-r--r--arch/arm/mach-socfpga/core.h50
-rw-r--r--arch/arm/mach-socfpga/headsmp.S37
-rw-r--r--arch/arm/mach-socfpga/platsmp.c105
-rw-r--r--arch/arm/mach-socfpga/socfpga.c119
-rw-r--r--arch/arm/mach-spear/Kconfig95
-rw-r--r--arch/arm/mach-spear/Makefile26
-rw-r--r--arch/arm/mach-spear/Makefile.boot3
-rw-r--r--arch/arm/mach-spear/generic.h56
-rw-r--r--arch/arm/mach-spear/headsmp.S47
-rw-r--r--arch/arm/mach-spear/hotplug.c101
-rw-r--r--arch/arm/mach-spear/include/mach/irqs.h35
-rw-r--r--arch/arm/mach-spear/include/mach/misc_regs.h22
-rw-r--r--arch/arm/mach-spear/include/mach/spear.h91
-rw-r--r--arch/arm/mach-spear/include/mach/uncompress.h42
-rw-r--r--arch/arm/mach-spear/pl080.c78
-rw-r--r--arch/arm/mach-spear/pl080.h21
-rw-r--r--arch/arm/mach-spear/platsmp.c131
-rw-r--r--arch/arm/mach-spear/restart.c35
-rw-r--r--arch/arm/mach-spear/spear1310.c67
-rw-r--r--arch/arm/mach-spear/spear1340.c39
-rw-r--r--arch/arm/mach-spear/spear13xx.c128
-rw-r--r--arch/arm/mach-spear/spear300.c218
-rw-r--r--arch/arm/mach-spear/spear310.c260
-rw-r--r--arch/arm/mach-spear/spear320.c275
-rw-r--r--arch/arm/mach-spear/spear3xx.c116
-rw-r--r--arch/arm/mach-spear/spear6xx.c429
-rw-r--r--arch/arm/mach-spear/time.c245
-rw-r--r--arch/arm/mach-sti/Kconfig56
-rw-r--r--arch/arm/mach-sti/Makefile2
-rw-r--r--arch/arm/mach-sti/board-dt.c34
-rw-r--r--arch/arm/mach-sti/headsmp.S42
-rw-r--r--arch/arm/mach-sti/platsmp.c116
-rw-r--r--arch/arm/mach-sti/smp.h17
-rw-r--r--arch/arm/mach-sunxi/Kconfig48
-rw-r--r--arch/arm/mach-sunxi/Makefile2
-rw-r--r--arch/arm/mach-sunxi/platsmp.c123
-rw-r--r--arch/arm/mach-sunxi/sunxi.c85
-rw-r--r--arch/arm/mach-tegra/Kconfig67
-rw-r--r--arch/arm/mach-tegra/Makefile36
-rw-r--r--arch/arm/mach-tegra/board-paz00.c52
-rw-r--r--arch/arm/mach-tegra/board.h33
-rw-r--r--arch/arm/mach-tegra/common.h4
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra114.c88
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra20.c226
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra30.c147
-rw-r--r--arch/arm/mach-tegra/cpuidle.c59
-rw-r--r--arch/arm/mach-tegra/cpuidle.h30
-rw-r--r--arch/arm/mach-tegra/flowctrl.c171
-rw-r--r--arch/arm/mach-tegra/flowctrl.h66
-rw-r--r--arch/arm/mach-tegra/headsmp.S12
-rw-r--r--arch/arm/mach-tegra/hotplug.c76
-rw-r--r--arch/arm/mach-tegra/io.c64
-rw-r--r--arch/arm/mach-tegra/iomap.h141
-rw-r--r--arch/arm/mach-tegra/irammap.h32
-rw-r--r--arch/arm/mach-tegra/irq.c102
-rw-r--r--arch/arm/mach-tegra/irq.h22
-rw-r--r--arch/arm/mach-tegra/platsmp.c203
-rw-r--r--arch/arm/mach-tegra/pm-tegra20.c35
-rw-r--r--arch/arm/mach-tegra/pm-tegra30.c35
-rw-r--r--arch/arm/mach-tegra/pm.c400
-rw-r--r--arch/arm/mach-tegra/pm.h49
-rw-r--r--arch/arm/mach-tegra/reset-handler.S290
-rw-r--r--arch/arm/mach-tegra/reset.c108
-rw-r--r--arch/arm/mach-tegra/reset.h67
-rw-r--r--arch/arm/mach-tegra/sleep-tegra20.S580
-rw-r--r--arch/arm/mach-tegra/sleep-tegra30.S831
-rw-r--r--arch/arm/mach-tegra/sleep.S161
-rw-r--r--arch/arm/mach-tegra/sleep.h154
-rw-r--r--arch/arm/mach-tegra/tegra.c168
-rw-r--r--arch/arm/mach-u300/Kconfig44
-rw-r--r--arch/arm/mach-u300/Makefile8
-rw-r--r--arch/arm/mach-u300/Makefile.boot4
-rw-r--r--arch/arm/mach-u300/core.c415
-rw-r--r--arch/arm/mach-u300/dummyspichip.c277
-rw-r--r--arch/arm/mach-u300/regulator.c132
-rw-r--r--arch/arm/mach-ux500/Kconfig76
-rw-r--r--arch/arm/mach-ux500/Makefile14
-rw-r--r--arch/arm/mach-ux500/Makefile.boot3
-rw-r--r--arch/arm/mach-ux500/board-mop500-audio.c77
-rw-r--r--arch/arm/mach-ux500/board-mop500-regulators.c1065
-rw-r--r--arch/arm/mach-ux500/board-mop500-regulators.h24
-rw-r--r--arch/arm/mach-ux500/board-mop500.h17
-rw-r--r--arch/arm/mach-ux500/cache-l2x0.c57
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c212
-rw-r--r--arch/arm/mach-ux500/cpu.c153
-rw-r--r--arch/arm/mach-ux500/db8500-regs.h200
-rw-r--r--arch/arm/mach-ux500/headsmp.S37
-rw-r--r--arch/arm/mach-ux500/hotplug.c37
-rw-r--r--arch/arm/mach-ux500/id.c116
-rw-r--r--arch/arm/mach-ux500/id.h144
-rw-r--r--arch/arm/mach-ux500/platsmp.c169
-rw-r--r--arch/arm/mach-ux500/pm.c198
-rw-r--r--arch/arm/mach-ux500/pm_domains.c79
-rw-r--r--arch/arm/mach-ux500/pm_domains.h17
-rw-r--r--arch/arm/mach-ux500/setup.h46
-rw-r--r--arch/arm/mach-ux500/ste-dma40-db8500.h85
-rw-r--r--arch/arm/mach-ux500/timer.c48
-rw-r--r--arch/arm/mach-versatile/Kconfig33
-rw-r--r--arch/arm/mach-versatile/Makefile9
-rw-r--r--arch/arm/mach-versatile/Makefile.boot4
-rw-r--r--arch/arm/mach-versatile/core.c808
-rw-r--r--arch/arm/mach-versatile/core.h46
-rw-r--r--arch/arm/mach-versatile/include/mach/clkdev.h16
-rw-r--r--arch/arm/mach-versatile/include/mach/hardware.h38
-rw-r--r--arch/arm/mach-versatile/include/mach/irqs.h134
-rw-r--r--arch/arm/mach-versatile/include/mach/platform.h416
-rw-r--r--arch/arm/mach-versatile/include/mach/uncompress.h45
-rw-r--r--arch/arm/mach-versatile/pci.c368
-rw-r--r--arch/arm/mach-versatile/versatile_ab.c44
-rw-r--r--arch/arm/mach-versatile/versatile_dt.c50
-rw-r--r--arch/arm/mach-versatile/versatile_pb.c91
-rw-r--r--arch/arm/mach-vexpress/Kconfig82
-rw-r--r--arch/arm/mach-vexpress/Makefile17
-rw-r--r--arch/arm/mach-vexpress/core.h5
-rw-r--r--arch/arm/mach-vexpress/dcscb.c174
-rw-r--r--arch/arm/mach-vexpress/dcscb_setup.S38
-rw-r--r--arch/arm/mach-vexpress/hotplug.c106
-rw-r--r--arch/arm/mach-vexpress/platsmp.c74
-rw-r--r--arch/arm/mach-vexpress/spc.c592
-rw-r--r--arch/arm/mach-vexpress/spc.h25
-rw-r--r--arch/arm/mach-vexpress/tc2_pm.c266
-rw-r--r--arch/arm/mach-vexpress/v2m.c16
-rw-r--r--arch/arm/mach-vt8500/Kconfig29
-rw-r--r--arch/arm/mach-vt8500/Makefile1
-rw-r--r--arch/arm/mach-vt8500/Makefile.boot3
-rw-r--r--arch/arm/mach-vt8500/vt8500.c180
-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.c242
-rw-r--r--arch/arm/mach-w90x900/cpu.h60
-rw-r--r--arch/arm/mach-w90x900/dev.c541
-rw-r--r--arch/arm/mach-w90x900/gpio.c154
-rw-r--r--arch/arm/mach-w90x900/include/mach/entry-macro.S26
-rw-r--r--arch/arm/mach-w90x900/include/mach/hardware.h24
-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/mfp.h25
-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/uncompress.h48
-rw-r--r--arch/arm/mach-w90x900/irq.c216
-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.c200
-rw-r--r--arch/arm/mach-w90x900/nuc910.c62
-rw-r--r--arch/arm/mach-w90x900/nuc910.h21
-rw-r--r--arch/arm/mach-w90x900/nuc950.c56
-rw-r--r--arch/arm/mach-w90x900/nuc950.h21
-rw-r--r--arch/arm/mach-w90x900/nuc960.c54
-rw-r--r--arch/arm/mach-w90x900/nuc960.h21
-rw-r--r--arch/arm/mach-w90x900/nuc9xx.h26
-rw-r--r--arch/arm/mach-w90x900/time.c168
-rw-r--r--arch/arm/mach-zynq/Kconfig16
-rw-r--r--arch/arm/mach-zynq/Makefile7
-rw-r--r--arch/arm/mach-zynq/Makefile.boot3
-rw-r--r--arch/arm/mach-zynq/common.c216
-rw-r--r--arch/arm/mach-zynq/common.h54
-rw-r--r--arch/arm/mach-zynq/headsmp.S29
-rw-r--r--arch/arm/mach-zynq/platsmp.c170
-rw-r--r--arch/arm/mach-zynq/pm.c83
-rw-r--r--arch/arm/mach-zynq/slcr.c227
-rw-r--r--arch/arm/mm/Kconfig1040
-rw-r--r--arch/arm/mm/Makefile102
-rw-r--r--arch/arm/mm/abort-ev4.S25
-rw-r--r--arch/arm/mm/abort-ev4t.S27
-rw-r--r--arch/arm/mm/abort-ev5t.S28
-rw-r--r--arch/arm/mm/abort-ev5tj.S30
-rw-r--r--arch/arm/mm/abort-ev6.S41
-rw-r--r--arch/arm/mm/abort-ev7.S45
-rw-r--r--arch/arm/mm/abort-lv4t.S220
-rw-r--r--arch/arm/mm/abort-macro.S40
-rw-r--r--arch/arm/mm/abort-nommu.S20
-rw-r--r--arch/arm/mm/alignment.c1008
-rw-r--r--arch/arm/mm/cache-aurora-l2.h55
-rw-r--r--arch/arm/mm/cache-fa.S250
-rw-r--r--arch/arm/mm/cache-feroceon-l2.c396
-rw-r--r--arch/arm/mm/cache-l2x0.c1705
-rw-r--r--arch/arm/mm/cache-nop.S51
-rw-r--r--arch/arm/mm/cache-tauros2.c302
-rw-r--r--arch/arm/mm/cache-tauros3.h41
-rw-r--r--arch/arm/mm/cache-v4.S150
-rw-r--r--arch/arm/mm/cache-v4wb.S261
-rw-r--r--arch/arm/mm/cache-v4wt.S206
-rw-r--r--arch/arm/mm/cache-v6.S335
-rw-r--r--arch/arm/mm/cache-v7.S448
-rw-r--r--arch/arm/mm/cache-xsc3l2.c220
-rw-r--r--arch/arm/mm/context.c266
-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-v4mc.c115
-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.c140
-rw-r--r--arch/arm/mm/copypage-xsc3.c114
-rw-r--r--arch/arm/mm/copypage-xscale.c135
-rw-r--r--arch/arm/mm/dma-mapping.c2128
-rw-r--r--arch/arm/mm/dump.c360
-rw-r--r--arch/arm/mm/extable.c21
-rw-r--r--arch/arm/mm/fault-armv.c269
-rw-r--r--arch/arm/mm/fault.c619
-rw-r--r--arch/arm/mm/fault.h28
-rw-r--r--arch/arm/mm/flush.c417
-rw-r--r--arch/arm/mm/fsr-2level.c78
-rw-r--r--arch/arm/mm/fsr-3level.c68
-rw-r--r--arch/arm/mm/highmem.c156
-rw-r--r--arch/arm/mm/hugetlbpage.c52
-rw-r--r--arch/arm/mm/idmap.c136
-rw-r--r--arch/arm/mm/init.c752
-rw-r--r--arch/arm/mm/iomap.c42
-rw-r--r--arch/arm/mm/ioremap.c458
-rw-r--r--arch/arm/mm/l2c-common.c20
-rw-r--r--arch/arm/mm/l2c-l2x0-resume.S59
-rw-r--r--arch/arm/mm/mm.h99
-rw-r--r--arch/arm/mm/mmap.c240
-rw-r--r--arch/arm/mm/mmu.c1536
-rw-r--r--arch/arm/mm/nommu.c389
-rw-r--r--arch/arm/mm/pabort-legacy.S21
-rw-r--r--arch/arm/mm/pabort-v6.S21
-rw-r--r--arch/arm/mm/pabort-v7.S21
-rw-r--r--arch/arm/mm/pageattr.c94
-rw-r--r--arch/arm/mm/pgd.c164
-rw-r--r--arch/arm/mm/proc-arm1020.S529
-rw-r--r--arch/arm/mm/proc-arm1020e.S489
-rw-r--r--arch/arm/mm/proc-arm1022.S474
-rw-r--r--arch/arm/mm/proc-arm1026.S468
-rw-r--r--arch/arm/mm/proc-arm720.S219
-rw-r--r--arch/arm/mm/proc-arm740.S151
-rw-r--r--arch/arm/mm/proc-arm7tdmi.S114
-rw-r--r--arch/arm/mm/proc-arm920.S480
-rw-r--r--arch/arm/mm/proc-arm922.S458
-rw-r--r--arch/arm/mm/proc-arm925.S523
-rw-r--r--arch/arm/mm/proc-arm926.S502
-rw-r--r--arch/arm/mm/proc-arm940.S364
-rw-r--r--arch/arm/mm/proc-arm946.S419
-rw-r--r--arch/arm/mm/proc-arm9tdmi.S95
-rw-r--r--arch/arm/mm/proc-fa526.S218
-rw-r--r--arch/arm/mm/proc-feroceon.S626
-rw-r--r--arch/arm/mm/proc-macros.S361
-rw-r--r--arch/arm/mm/proc-mohawk.S455
-rw-r--r--arch/arm/mm/proc-sa110.S225
-rw-r--r--arch/arm/mm/proc-sa1100.S273
-rw-r--r--arch/arm/mm/proc-syms.c53
-rw-r--r--arch/arm/mm/proc-v6.S300
-rw-r--r--arch/arm/mm/proc-v7-2level.S169
-rw-r--r--arch/arm/mm/proc-v7-3level.S165
-rw-r--r--arch/arm/mm/proc-v7.S636
-rw-r--r--arch/arm/mm/proc-v7m.S159
-rw-r--r--arch/arm/mm/proc-xsc3.S532
-rw-r--r--arch/arm/mm/proc-xscale.S660
-rw-r--r--arch/arm/mm/tcm.h17
-rw-r--r--arch/arm/mm/tlb-fa.S70
-rw-r--r--arch/arm/mm/tlb-v4.S62
-rw-r--r--arch/arm/mm/tlb-v4wb.S74
-rw-r--r--arch/arm/mm/tlb-v4wbi.S65
-rw-r--r--arch/arm/mm/tlb-v6.S93
-rw-r--r--arch/arm/mm/tlb-v7.S95
-rw-r--r--arch/arm/net/Makefile3
-rw-r--r--arch/arm/net/bpf_jit_32.c991
-rw-r--r--arch/arm/net/bpf_jit_32.h210
-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.S124
-rw-r--r--arch/arm/nwfpe/extended_cpdo.c154
-rw-r--r--arch/arm/nwfpe/fpa11.c128
-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.c63
-rw-r--r--arch/arm/nwfpe/fpopcode.h481
-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.c132
-rw-r--r--arch/arm/plat-iop/Makefile27
-rw-r--r--arch/arm/plat-iop/adma.c205
-rw-r--r--arch/arm/plat-iop/cp6.c51
-rw-r--r--arch/arm/plat-iop/i2c.c79
-rw-r--r--arch/arm/plat-iop/pci.c404
-rw-r--r--arch/arm/plat-iop/pmu.c39
-rw-r--r--arch/arm/plat-iop/restart.c20
-rw-r--r--arch/arm/plat-iop/setup.c34
-rw-r--r--arch/arm/plat-iop/time.c170
-rw-r--r--arch/arm/plat-omap/Kconfig161
-rw-r--r--arch/arm/plat-omap/Makefile16
-rw-r--r--arch/arm/plat-omap/counter_32k.c117
-rw-r--r--arch/arm/plat-omap/debug-leds.c174
-rw-r--r--arch/arm/plat-omap/dma.c1466
-rw-r--r--arch/arm/plat-omap/dmtimer.c965
-rw-r--r--arch/arm/plat-omap/i2c.c116
-rw-r--r--arch/arm/plat-omap/include/plat/counter-32k.h1
-rw-r--r--arch/arm/plat-omap/include/plat/cpu.h35
-rw-r--r--arch/arm/plat-omap/include/plat/dmtimer.h418
-rw-r--r--arch/arm/plat-omap/include/plat/i2c.h53
-rw-r--r--arch/arm/plat-omap/include/plat/sram.h16
-rw-r--r--arch/arm/plat-omap/sram.c98
-rw-r--r--arch/arm/plat-orion/Makefile8
-rw-r--r--arch/arm/plat-orion/common.c884
-rw-r--r--arch/arm/plat-orion/gpio.c628
-rw-r--r--arch/arm/plat-orion/include/plat/addr-map.h54
-rw-r--r--arch/arm/plat-orion/include/plat/common.h113
-rw-r--r--arch/arm/plat-orion/include/plat/irq.h15
-rw-r--r--arch/arm/plat-orion/include/plat/mpp.h34
-rw-r--r--arch/arm/plat-orion/include/plat/orion-gpio.h39
-rw-r--r--arch/arm/plat-orion/include/plat/pcie.h34
-rw-r--r--arch/arm/plat-orion/include/plat/time.h20
-rw-r--r--arch/arm/plat-orion/irq.c40
-rw-r--r--arch/arm/plat-orion/mpp.c78
-rw-r--r--arch/arm/plat-orion/pcie.c288
-rw-r--r--arch/arm/plat-orion/time.c226
-rw-r--r--arch/arm/plat-pxa/Kconfig8
-rw-r--r--arch/arm/plat-pxa/Makefile10
-rw-r--r--arch/arm/plat-pxa/dma.c386
-rw-r--r--arch/arm/plat-pxa/include/plat/dma.h85
-rw-r--r--arch/arm/plat-pxa/include/plat/mfp.h475
-rw-r--r--arch/arm/plat-pxa/mfp.c285
-rw-r--r--arch/arm/plat-pxa/ssp.c292
-rw-r--r--arch/arm/plat-samsung/Kconfig323
-rw-r--r--arch/arm/plat-samsung/Makefile39
-rw-r--r--arch/arm/plat-samsung/adc.c525
-rw-r--r--arch/arm/plat-samsung/cpu.c53
-rw-r--r--arch/arm/plat-samsung/dev-backlight.c152
-rw-r--r--arch/arm/plat-samsung/dev-uart.c46
-rw-r--r--arch/arm/plat-samsung/devs.c1229
-rw-r--r--arch/arm/plat-samsung/include/plat/adc-core.h28
-rw-r--r--arch/arm/plat-samsung/include/plat/adc.h36
-rw-r--r--arch/arm/plat-samsung/include/plat/ata-core.h28
-rw-r--r--arch/arm/plat-samsung/include/plat/backlight.h26
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu-freq-core.h291
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu-freq.h145
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h143
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h100
-rw-r--r--arch/arm/plat-samsung/include/plat/fb-core.h29
-rw-r--r--arch/arm/plat-samsung/include/plat/fb-s3c2410.h72
-rw-r--r--arch/arm/plat-samsung/include/plat/fb.h35
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h163
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg.h182
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-core.h145
-rw-r--r--arch/arm/plat-samsung/include/plat/iic-core.h42
-rw-r--r--arch/arm/plat-samsung/include/plat/irq-uart.h20
-rw-r--r--arch/arm/plat-samsung/include/plat/keypad-core.h31
-rw-r--r--arch/arm/plat-samsung/include/plat/keypad.h31
-rw-r--r--arch/arm/plat-samsung/include/plat/map-base.h46
-rw-r--r--arch/arm/plat-samsung/include/plat/map-s3c.h84
-rw-r--r--arch/arm/plat-samsung/include/plat/map-s5p.h40
-rw-r--r--arch/arm/plat-samsung/include/plat/nand-core.h28
-rw-r--r--arch/arm/plat-samsung/include/plat/onenand-core.h37
-rw-r--r--arch/arm/plat-samsung/include/plat/pm-common.h110
-rw-r--r--arch/arm/plat-samsung/include/plat/pm.h121
-rw-r--r--arch/arm/plat-samsung/include/plat/pwm-core.h22
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-adc.h68
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-irqtype.h21
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-spi.h48
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-srom.h54
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-udc.h151
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h51
-rw-r--r--arch/arm/plat-samsung/include/plat/samsung-time.h30
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h166
-rw-r--r--arch/arm/plat-samsung/include/plat/spi-core.h30
-rw-r--r--arch/arm/plat-samsung/include/plat/usb-phy.h19
-rw-r--r--arch/arm/plat-samsung/include/plat/wakeup-mask.h44
-rw-r--r--arch/arm/plat-samsung/include/plat/watchdog-reset.h20
-rw-r--r--arch/arm/plat-samsung/init.c173
-rw-r--r--arch/arm/plat-samsung/platformdata.c60
-rw-r--r--arch/arm/plat-samsung/pm-check.c237
-rw-r--r--arch/arm/plat-samsung/pm-common.c75
-rw-r--r--arch/arm/plat-samsung/pm-debug.c99
-rw-r--r--arch/arm/plat-samsung/pm-gpio.c386
-rw-r--r--arch/arm/plat-samsung/pm.c208
-rw-r--r--arch/arm/plat-samsung/s5p-dev-mfc.c94
-rw-r--r--arch/arm/plat-samsung/setup-camif.c71
-rw-r--r--arch/arm/plat-samsung/wakeup-mask.c47
-rw-r--r--arch/arm/plat-samsung/watchdog-reset.c97
-rw-r--r--arch/arm/plat-versatile/Kconfig9
-rw-r--r--arch/arm/plat-versatile/Makefile5
-rw-r--r--arch/arm/plat-versatile/clock.c74
-rw-r--r--arch/arm/plat-versatile/headsmp.S41
-rw-r--r--arch/arm/plat-versatile/include/plat/clock.h15
-rw-r--r--arch/arm/plat-versatile/include/plat/platsmp.h14
-rw-r--r--arch/arm/plat-versatile/include/plat/sched_clock.h6
-rw-r--r--arch/arm/plat-versatile/platsmp.c91
-rw-r--r--arch/arm/plat-versatile/sched-clock.c41
-rw-r--r--arch/arm/probes/Makefile7
-rw-r--r--arch/arm/probes/decode-arm.c736
-rw-r--r--arch/arm/probes/decode-arm.h74
-rw-r--r--arch/arm/probes/decode-thumb.c884
-rw-r--r--arch/arm/probes/decode-thumb.h101
-rw-r--r--arch/arm/probes/decode.c521
-rw-r--r--arch/arm/probes/decode.h416
-rw-r--r--arch/arm/probes/kprobes/Makefile12
-rw-r--r--arch/arm/probes/kprobes/actions-arm.c344
-rw-r--r--arch/arm/probes/kprobes/actions-common.c171
-rw-r--r--arch/arm/probes/kprobes/actions-thumb.c670
-rw-r--r--arch/arm/probes/kprobes/checkers-arm.c192
-rw-r--r--arch/arm/probes/kprobes/checkers-common.c101
-rw-r--r--arch/arm/probes/kprobes/checkers-thumb.c110
-rw-r--r--arch/arm/probes/kprobes/checkers.h55
-rw-r--r--arch/arm/probes/kprobes/core.c653
-rw-r--r--arch/arm/probes/kprobes/core.h58
-rw-r--r--arch/arm/probes/kprobes/opt-arm.c370
-rw-r--r--arch/arm/probes/kprobes/test-arm.c1366
-rw-r--r--arch/arm/probes/kprobes/test-core.c1727
-rw-r--r--arch/arm/probes/kprobes/test-core.h458
-rw-r--r--arch/arm/probes/kprobes/test-thumb.c1200
-rw-r--r--arch/arm/probes/uprobes/Makefile1
-rw-r--r--arch/arm/probes/uprobes/actions-arm.c232
-rw-r--r--arch/arm/probes/uprobes/core.c230
-rw-r--r--arch/arm/probes/uprobes/core.h35
-rw-r--r--arch/arm/tools/Makefile10
-rw-r--r--arch/arm/tools/gen-mach-types72
-rw-r--r--arch/arm/tools/mach-types1008
-rw-r--r--arch/arm/vdso/.gitignore3
-rw-r--r--arch/arm/vdso/Makefile74
-rw-r--r--arch/arm/vdso/datapage.S15
-rw-r--r--arch/arm/vdso/vdso.S35
-rw-r--r--arch/arm/vdso/vdso.lds.S87
-rw-r--r--arch/arm/vdso/vdsomunge.c211
-rw-r--r--arch/arm/vdso/vgettimeofday.c282
-rw-r--r--arch/arm/vfp/Makefile15
-rw-r--r--arch/arm/vfp/entry.S59
-rw-r--r--arch/arm/vfp/vfp.h380
-rw-r--r--arch/arm/vfp/vfpdouble.c1206
-rw-r--r--arch/arm/vfp/vfphw.S323
-rw-r--r--arch/arm/vfp/vfpinstr.h88
-rw-r--r--arch/arm/vfp/vfpmodule.c811
-rw-r--r--arch/arm/vfp/vfpsingle.c1246
-rw-r--r--arch/arm/xen/Makefile1
-rw-r--r--arch/arm/xen/enlighten.c290
-rw-r--r--arch/arm/xen/grant-table.c51
-rw-r--r--arch/arm/xen/hypercall.S105
-rw-r--r--arch/arm/xen/mm.c201
-rw-r--r--arch/arm/xen/p2m.c177
3780 files changed, 813566 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
new file mode 100644
index 000000000..45df48ba0
--- /dev/null
+++ b/arch/arm/Kconfig
@@ -0,0 +1,2121 @@
+config ARM
+ bool
+ default y
+ select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
+ select ARCH_HAS_ELF_RANDOMIZE
+ select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
+ select ARCH_HAVE_CUSTOM_GPIO_H
+ select ARCH_HAS_GCOV_PROFILE_ALL
+ select ARCH_MIGHT_HAVE_PC_PARPORT
+ select ARCH_SUPPORTS_ATOMIC_RMW
+ select ARCH_USE_BUILTIN_BSWAP
+ select ARCH_USE_CMPXCHG_LOCKREF
+ select ARCH_WANT_IPC_PARSE_VERSION
+ select BUILDTIME_EXTABLE_SORT if MMU
+ select CLONE_BACKWARDS
+ select CPU_PM if (SUSPEND || CPU_IDLE)
+ select DCACHE_WORD_ACCESS if HAVE_EFFICIENT_UNALIGNED_ACCESS
+ select GENERIC_ALLOCATOR
+ select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI)
+ select GENERIC_CLOCKEVENTS_BROADCAST if SMP
+ select GENERIC_IDLE_POLL_SETUP
+ select GENERIC_IRQ_PROBE
+ select GENERIC_IRQ_SHOW
+ select GENERIC_IRQ_SHOW_LEVEL
+ select GENERIC_PCI_IOMAP
+ select GENERIC_SCHED_CLOCK
+ select GENERIC_SMP_IDLE_THREAD
+ select GENERIC_STRNCPY_FROM_USER
+ select GENERIC_STRNLEN_USER
+ select HANDLE_DOMAIN_IRQ
+ select HARDIRQS_SW_RESEND
+ select HAVE_ARCH_AUDITSYSCALL if (AEABI && !OABI_COMPAT)
+ select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6
+ select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
+ select HAVE_ARCH_KGDB
+ select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT)
+ select HAVE_ARCH_TRACEHOOK
+ select HAVE_BPF_JIT
+ select HAVE_CC_STACKPROTECTOR
+ select HAVE_CONTEXT_TRACKING
+ select HAVE_C_RECORDMCOUNT
+ select HAVE_DEBUG_KMEMLEAK
+ select HAVE_DMA_API_DEBUG
+ select HAVE_DMA_ATTRS
+ select HAVE_DMA_CONTIGUOUS if MMU
+ select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL)
+ select HAVE_EFFICIENT_UNALIGNED_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU
+ select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL)
+ select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL)
+ select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
+ select HAVE_GENERIC_DMA_COHERENT
+ select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
+ select HAVE_IDE if PCI || ISA || PCMCIA
+ select HAVE_IRQ_TIME_ACCOUNTING
+ select HAVE_KERNEL_GZIP
+ select HAVE_KERNEL_LZ4
+ select HAVE_KERNEL_LZMA
+ select HAVE_KERNEL_LZO
+ select HAVE_KERNEL_XZ
+ select HAVE_KPROBES if !XIP_KERNEL
+ select HAVE_KRETPROBES if (HAVE_KPROBES)
+ select HAVE_MEMBLOCK
+ select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND
+ select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
+ select HAVE_OPTPROBES if !THUMB2_KERNEL
+ select HAVE_PERF_EVENTS
+ select HAVE_PERF_REGS
+ select HAVE_PERF_USER_STACK_DUMP
+ select HAVE_RCU_TABLE_FREE if (SMP && ARM_LPAE)
+ select HAVE_REGS_AND_STACK_ACCESS_API
+ select HAVE_SYSCALL_TRACEPOINTS
+ select HAVE_UID16
+ select HAVE_VIRT_CPU_ACCOUNTING_GEN
+ select IRQ_FORCED_THREADING
+ select MODULES_USE_ELF_REL
+ select NO_BOOTMEM
+ select OLD_SIGACTION
+ select OLD_SIGSUSPEND3
+ select PERF_USE_VMALLOC
+ select RTC_LIB
+ select SYS_SUPPORTS_APM_EMULATION
+ # Above selects are sorted alphabetically; please add new ones
+ # according to that. Thanks.
+ 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 ARM_HAS_SG_CHAIN
+ select ARCH_HAS_SG_CHAIN
+ bool
+
+config NEED_SG_DMA_LENGTH
+ bool
+
+config ARM_DMA_USE_IOMMU
+ bool
+ select ARM_HAS_SG_CHAIN
+ select NEED_SG_DMA_LENGTH
+
+if ARM_DMA_USE_IOMMU
+
+config ARM_DMA_IOMMU_ALIGNMENT
+ int "Maximum PAGE_SIZE order of alignment for DMA IOMMU buffers"
+ range 4 9
+ default 8
+ help
+ DMA mapping framework by default aligns all buffers to the smallest
+ PAGE_SIZE order which is greater than or equal to the requested buffer
+ size. This works well for buffers up to a few hundreds kilobytes, but
+ for larger buffers it just a waste of address space. Drivers which has
+ relatively small addressing window (like 64Mib) might run out of
+ virtual space with just a few allocations.
+
+ With this parameter you can specify the maximum PAGE_SIZE order for
+ DMA IOMMU buffers. Larger buffers will be aligned only to this
+ specified order. The order is expressed as a power of two multiplied
+ by the PAGE_SIZE.
+
+endif
+
+config MIGHT_HAVE_PCI
+ bool
+
+config SYS_SUPPORTS_APM_EMULATION
+ bool
+
+config HAVE_TCM
+ bool
+ select GENERIC_ALLOCATOR
+
+config HAVE_PROC_CPU
+ bool
+
+config NO_IOPORT_MAP
+ 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 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 RWSEM_XCHGADD_ALGORITHM
+ bool
+ default y
+
+config ARCH_HAS_ILOG2_U32
+ bool
+
+config ARCH_HAS_ILOG2_U64
+ bool
+
+config ARCH_HAS_BANDGAP
+ bool
+
+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 ARCH_SUPPORTS_UPROBES
+ def_bool y
+
+config ARCH_HAS_DMA_SET_COHERENT_MASK
+ bool
+
+config GENERIC_ISA_DMA
+ bool
+
+config FIQ
+ bool
+
+config NEED_RET_TO_USER
+ 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. This must be two pages
+ in size.
+
+config ARM_PATCH_PHYS_VIRT
+ bool "Patch physical to virtual translations at runtime" if EMBEDDED
+ default y
+ 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.
+
+ Only disable this option if you know that you do not require
+ this feature (eg, building a kernel for a single machine) and
+ you need to shrink the kernel to the minimal size.
+
+config NEED_MACH_IO_H
+ bool
+ help
+ Select this when mach/io.h is required to provide special
+ definitions for this platform. The need for mach/io.h should
+ be avoided when possible.
+
+config NEED_MACH_MEMORY_H
+ bool
+ help
+ Select this when mach/memory.h is required to provide special
+ definitions for this platform. The need for mach/memory.h should
+ be avoided when possible.
+
+config PHYS_OFFSET
+ hex "Physical address of main memory" if MMU
+ depends on !ARM_PATCH_PHYS_VIRT
+ default DRAM_BASE if !MMU
+ default 0x00000000 if ARCH_EBSA110 || \
+ EP93XX_SDCE3_SYNC_PHYS_OFFSET || \
+ ARCH_FOOTBRIDGE || \
+ ARCH_INTEGRATOR || \
+ ARCH_IOP13XX || \
+ ARCH_KS8695 || \
+ (ARCH_REALVIEW && !REALVIEW_HIGH_PHYS_OFFSET)
+ default 0x10000000 if ARCH_OMAP1 || ARCH_RPC
+ default 0x20000000 if ARCH_S5PV210
+ default 0x70000000 if REALVIEW_HIGH_PHYS_OFFSET
+ default 0xc0000000 if EP93XX_SDCE0_PHYS_OFFSET || ARCH_SA1100
+ default 0xd0000000 if EP93XX_SDCE1_PHYS_OFFSET
+ default 0xe0000000 if EP93XX_SDCE2_PHYS_OFFSET
+ default 0xf0000000 if EP93XX_SDCE3_ASYNC_PHYS_OFFSET
+ help
+ Please provide the physical address corresponding to the
+ location of main memory in your system.
+
+config GENERIC_BUG
+ def_bool y
+ depends on BUG
+
+config PGTABLE_LEVELS
+ int
+ default 3 if ARM_LPAE
+ default 2
+
+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 if !MMU
+ default ARCH_MULTIPLATFORM if MMU
+
+config ARCH_MULTIPLATFORM
+ bool "Allow multiple platforms to be selected"
+ depends on MMU
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARM_HAS_SG_CHAIN
+ select ARM_PATCH_PHYS_VIRT
+ select AUTO_ZRELADDR
+ select CLKSRC_OF
+ select COMMON_CLK
+ select GENERIC_CLOCKEVENTS
+ select MIGHT_HAVE_PCI
+ select MULTI_IRQ_HANDLER
+ select SPARSE_IRQ
+ select USE_OF
+
+config ARCH_REALVIEW
+ bool "ARM Ltd. RealView family"
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARM_AMBA
+ select ARM_TIMER_SP804
+ select COMMON_CLK
+ select COMMON_CLK_VERSATILE
+ select GENERIC_CLOCKEVENTS
+ select GPIO_PL061 if GPIOLIB
+ select ICST
+ select NEED_MACH_MEMORY_H
+ select PLAT_VERSATILE
+ select PLAT_VERSATILE_SCHED_CLOCK
+ help
+ This enables support for ARM Ltd RealView boards.
+
+config ARCH_VERSATILE
+ bool "ARM Ltd. Versatile family"
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARM_AMBA
+ select ARM_TIMER_SP804
+ select ARM_VIC
+ select CLKDEV_LOOKUP
+ select GENERIC_CLOCKEVENTS
+ select HAVE_MACH_CLKDEV
+ select ICST
+ select PLAT_VERSATILE
+ select PLAT_VERSATILE_CLOCK
+ select PLAT_VERSATILE_SCHED_CLOCK
+ select VERSATILE_FPGA_IRQ
+ help
+ This enables support for ARM Ltd Versatile board.
+
+config ARCH_CLPS711X
+ bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
+ select ARCH_REQUIRE_GPIOLIB
+ select AUTO_ZRELADDR
+ select CLKSRC_MMIO
+ select COMMON_CLK
+ select CPU_ARM720T
+ select GENERIC_CLOCKEVENTS
+ select MFD_SYSCON
+ select SOC_BUS
+ help
+ Support for Cirrus Logic 711x/721x/731x based boards.
+
+config ARCH_GEMINI
+ bool "Cortina Systems Gemini"
+ select ARCH_REQUIRE_GPIOLIB
+ select CLKSRC_MMIO
+ select CPU_FA526
+ select GENERIC_CLOCKEVENTS
+ help
+ Support for the Cortina Systems Gemini family SoCs
+
+config ARCH_EBSA110
+ bool "EBSA-110"
+ select ARCH_USES_GETTIMEOFFSET
+ select CPU_SA110
+ select ISA
+ select NEED_MACH_IO_H
+ select NEED_MACH_MEMORY_H
+ select NO_IOPORT_MAP
+ 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_EFM32
+ bool "Energy Micro efm32"
+ depends on !MMU
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_NVIC
+ select AUTO_ZRELADDR
+ select CLKSRC_OF
+ select COMMON_CLK
+ select CPU_V7M
+ select GENERIC_CLOCKEVENTS
+ select NO_DMA
+ select NO_IOPORT_MAP
+ select SPARSE_IRQ
+ select USE_OF
+ help
+ Support for Energy Micro's (now Silicon Labs) efm32 Giant Gecko
+ processors.
+
+config ARCH_EP93XX
+ bool "EP93xx-based"
+ select ARCH_HAS_HOLES_MEMORYMODEL
+ select ARCH_REQUIRE_GPIOLIB
+ select ARCH_USES_GETTIMEOFFSET
+ select ARM_AMBA
+ select ARM_VIC
+ select CLKDEV_LOOKUP
+ select CPU_ARM920T
+ help
+ This enables support for the Cirrus EP93xx series of CPUs.
+
+config ARCH_FOOTBRIDGE
+ bool "FootBridge"
+ select CPU_SA110
+ select FOOTBRIDGE
+ select GENERIC_CLOCKEVENTS
+ select HAVE_IDE
+ select NEED_MACH_IO_H if !MMU
+ select NEED_MACH_MEMORY_H
+ help
+ Support for systems based on the DC21285 companion chip
+ ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
+
+config ARCH_NETX
+ bool "Hilscher NetX based"
+ select ARM_VIC
+ select CLKSRC_MMIO
+ select CPU_ARM926T
+ select GENERIC_CLOCKEVENTS
+ help
+ This enables support for systems based on the Hilscher NetX Soc
+
+config ARCH_IOP13XX
+ bool "IOP13xx-based"
+ depends on MMU
+ select CPU_XSC3
+ select NEED_MACH_MEMORY_H
+ select NEED_RET_TO_USER
+ select PCI
+ select PLAT_IOP
+ select VMSPLIT_1G
+ select SPARSE_IRQ
+ help
+ Support for Intel's IOP13XX (XScale) family of processors.
+
+config ARCH_IOP32X
+ bool "IOP32x-based"
+ depends on MMU
+ select ARCH_REQUIRE_GPIOLIB
+ select CPU_XSCALE
+ select GPIO_IOP
+ select NEED_RET_TO_USER
+ select PCI
+ select PLAT_IOP
+ help
+ Support for Intel's 80219 and IOP32X (XScale) family of
+ processors.
+
+config ARCH_IOP33X
+ bool "IOP33x-based"
+ depends on MMU
+ select ARCH_REQUIRE_GPIOLIB
+ select CPU_XSCALE
+ select GPIO_IOP
+ select NEED_RET_TO_USER
+ select PCI
+ select PLAT_IOP
+ help
+ Support for Intel's IOP33X (XScale) family of processors.
+
+config ARCH_IXP4XX
+ bool "IXP4xx-based"
+ depends on MMU
+ select ARCH_HAS_DMA_SET_COHERENT_MASK
+ select ARCH_REQUIRE_GPIOLIB
+ select ARCH_SUPPORTS_BIG_ENDIAN
+ select CLKSRC_MMIO
+ select CPU_XSCALE
+ select DMABOUNCE if PCI
+ select GENERIC_CLOCKEVENTS
+ select MIGHT_HAVE_PCI
+ select NEED_MACH_IO_H
+ select USB_EHCI_BIG_ENDIAN_DESC
+ select USB_EHCI_BIG_ENDIAN_MMIO
+ help
+ Support for Intel's IXP4XX (XScale) family of processors.
+
+config ARCH_DOVE
+ bool "Marvell Dove"
+ select ARCH_REQUIRE_GPIOLIB
+ select CPU_PJ4
+ select GENERIC_CLOCKEVENTS
+ select MIGHT_HAVE_PCI
+ select MVEBU_MBUS
+ select PINCTRL
+ select PINCTRL_DOVE
+ select PLAT_ORION_LEGACY
+ help
+ Support for the Marvell Dove SoC 88AP510
+
+config ARCH_MV78XX0
+ bool "Marvell MV78xx0"
+ select ARCH_REQUIRE_GPIOLIB
+ select CPU_FEROCEON
+ select GENERIC_CLOCKEVENTS
+ select MVEBU_MBUS
+ select PCI
+ select PLAT_ORION_LEGACY
+ help
+ Support for the following Marvell MV78xx0 series SoCs:
+ MV781x0, MV782x0.
+
+config ARCH_ORION5X
+ bool "Marvell Orion"
+ depends on MMU
+ select ARCH_REQUIRE_GPIOLIB
+ select CPU_FEROCEON
+ select GENERIC_CLOCKEVENTS
+ select MVEBU_MBUS
+ select PCI
+ select PLAT_ORION_LEGACY
+ 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_ALLOCATOR
+ select GENERIC_CLOCKEVENTS
+ select GPIO_PXA
+ select IRQ_DOMAIN
+ select MULTI_IRQ_HANDLER
+ select PINCTRL
+ 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 ARCH_REQUIRE_GPIOLIB
+ select CLKSRC_MMIO
+ select CPU_ARM922T
+ select GENERIC_CLOCKEVENTS
+ select NEED_MACH_MEMORY_H
+ help
+ Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
+ System-on-Chip devices.
+
+config ARCH_W90X900
+ bool "Nuvoton W90X900 CPU"
+ select ARCH_REQUIRE_GPIOLIB
+ select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
+ select CPU_ARM926T
+ 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_LPC32XX
+ bool "NXP LPC32XX"
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_AMBA
+ select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
+ select CPU_ARM926T
+ select GENERIC_CLOCKEVENTS
+ select HAVE_IDE
+ select USE_OF
+ help
+ Support for the NXP LPC32XX family of processors
+
+config ARCH_PXA
+ bool "PXA2xx/PXA3xx-based"
+ depends on MMU
+ select ARCH_MTD_XIP
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_CPU_SUSPEND if PM
+ select AUTO_ZRELADDR
+ select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
+ select CLKSRC_OF
+ select GENERIC_CLOCKEVENTS
+ select GPIO_PXA
+ select HAVE_IDE
+ select IRQ_DOMAIN
+ select MULTI_IRQ_HANDLER
+ select PLAT_PXA
+ select SPARSE_IRQ
+ help
+ Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
+
+config ARCH_SHMOBILE_LEGACY
+ bool "Renesas ARM SoCs (non-multiplatform)"
+ select ARCH_SHMOBILE
+ select ARM_PATCH_PHYS_VIRT if MMU
+ select CLKDEV_LOOKUP
+ select CPU_V7
+ select GENERIC_CLOCKEVENTS
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select HAVE_SMP
+ select MIGHT_HAVE_CACHE_L2X0
+ select MULTI_IRQ_HANDLER
+ select NO_IOPORT_MAP
+ select PINCTRL
+ select PM_GENERIC_DOMAINS if PM
+ select SH_CLK_CPG
+ select SPARSE_IRQ
+ help
+ Support for Renesas ARM SoC platforms using a non-multiplatform
+ kernel. This includes the SH-Mobile, R-Mobile, EMMA-Mobile, R-Car
+ and RZ families.
+
+config ARCH_RPC
+ bool "RiscPC"
+ select ARCH_ACORN
+ select ARCH_MAY_HAVE_PC_FDC
+ select ARCH_SPARSEMEM_ENABLE
+ select ARCH_USES_GETTIMEOFFSET
+ select CPU_SA110
+ select FIQ
+ select HAVE_IDE
+ select HAVE_PATA_PLATFORM
+ select ISA_DMA_API
+ select NEED_MACH_IO_H
+ select NEED_MACH_MEMORY_H
+ select NO_IOPORT_MAP
+ select VIRT_TO_BUS
+ 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 ARCH_MTD_XIP
+ select ARCH_REQUIRE_GPIOLIB
+ select ARCH_SPARSEMEM_ENABLE
+ select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
+ select CPU_FREQ
+ select CPU_SA1100
+ select GENERIC_CLOCKEVENTS
+ select HAVE_IDE
+ select IRQ_DOMAIN
+ select ISA
+ select MULTI_IRQ_HANDLER
+ select NEED_MACH_MEMORY_H
+ select SPARSE_IRQ
+ help
+ Support for StrongARM 11x0 based boards.
+
+config ARCH_S3C24XX
+ bool "Samsung S3C24XX SoCs"
+ select ARCH_REQUIRE_GPIOLIB
+ select ATAGS
+ select CLKDEV_LOOKUP
+ select CLKSRC_SAMSUNG_PWM
+ select GENERIC_CLOCKEVENTS
+ select GPIO_SAMSUNG
+ select HAVE_S3C2410_I2C if I2C
+ select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select HAVE_S3C_RTC if RTC_CLASS
+ select MULTI_IRQ_HANDLER
+ select NEED_MACH_IO_H
+ select SAMSUNG_ATAGS
+ help
+ Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443
+ and S3C2450 SoCs 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).
+
+config ARCH_S3C64XX
+ bool "Samsung S3C64XX"
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_AMBA
+ select ARM_VIC
+ select ATAGS
+ select CLKDEV_LOOKUP
+ select CLKSRC_SAMSUNG_PWM
+ select COMMON_CLK_SAMSUNG
+ select CPU_V6K
+ select GENERIC_CLOCKEVENTS
+ select GPIO_SAMSUNG
+ select HAVE_S3C2410_I2C if I2C
+ select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select HAVE_TCM
+ select NO_IOPORT_MAP
+ select PLAT_SAMSUNG
+ select PM_GENERIC_DOMAINS if PM
+ select S3C_DEV_NAND
+ select S3C_GPIO_TRACK
+ select SAMSUNG_ATAGS
+ select SAMSUNG_WAKEMASK
+ select SAMSUNG_WDT_RESET
+ help
+ Samsung S3C64XX series based systems
+
+config ARCH_DAVINCI
+ bool "TI DaVinci"
+ select ARCH_HAS_HOLES_MEMORYMODEL
+ select ARCH_REQUIRE_GPIOLIB
+ select CLKDEV_LOOKUP
+ select GENERIC_ALLOCATOR
+ select GENERIC_CLOCKEVENTS
+ select GENERIC_IRQ_CHIP
+ select HAVE_IDE
+ select TI_PRIV_EDMA
+ select USE_OF
+ select ZONE_DMA
+ help
+ Support for TI's DaVinci platform.
+
+config ARCH_OMAP1
+ bool "TI OMAP1"
+ depends on MMU
+ select ARCH_HAS_HOLES_MEMORYMODEL
+ select ARCH_OMAP
+ select ARCH_REQUIRE_GPIOLIB
+ select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
+ select GENERIC_CLOCKEVENTS
+ select GENERIC_IRQ_CHIP
+ select HAVE_IDE
+ select IRQ_DOMAIN
+ select NEED_MACH_IO_H if PCCARD
+ select NEED_MACH_MEMORY_H
+ help
+ Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx)
+
+endchoice
+
+menu "Multiple platform selection"
+ depends on ARCH_MULTIPLATFORM
+
+comment "CPU Core family selection"
+
+config ARCH_MULTI_V4
+ bool "ARMv4 based platforms (FA526)"
+ depends on !ARCH_MULTI_V6_V7
+ select ARCH_MULTI_V4_V5
+ select CPU_FA526
+
+config ARCH_MULTI_V4T
+ bool "ARMv4T based platforms (ARM720T, ARM920T, ...)"
+ depends on !ARCH_MULTI_V6_V7
+ select ARCH_MULTI_V4_V5
+ select CPU_ARM920T if !(CPU_ARM7TDMI || CPU_ARM720T || \
+ CPU_ARM740T || CPU_ARM9TDMI || CPU_ARM922T || \
+ CPU_ARM925T || CPU_ARM940T)
+
+config ARCH_MULTI_V5
+ bool "ARMv5 based platforms (ARM926T, XSCALE, PJ1, ...)"
+ depends on !ARCH_MULTI_V6_V7
+ select ARCH_MULTI_V4_V5
+ select CPU_ARM926T if !(CPU_ARM946E || CPU_ARM1020 || \
+ CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || \
+ CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_FEROCEON)
+
+config ARCH_MULTI_V4_V5
+ bool
+
+config ARCH_MULTI_V6
+ bool "ARMv6 based platforms (ARM11)"
+ select ARCH_MULTI_V6_V7
+ select CPU_V6K
+
+config ARCH_MULTI_V7
+ bool "ARMv7 based platforms (Cortex-A, PJ4, Scorpion, Krait)"
+ default y
+ select ARCH_MULTI_V6_V7
+ select CPU_V7
+ select HAVE_SMP
+
+config ARCH_MULTI_V6_V7
+ bool
+ select MIGHT_HAVE_CACHE_L2X0
+
+config ARCH_MULTI_CPU_AUTO
+ def_bool !(ARCH_MULTI_V4 || ARCH_MULTI_V4T || ARCH_MULTI_V6_V7)
+ select ARCH_MULTI_V5
+
+endmenu
+
+config ARCH_VIRT
+ bool "Dummy Virtual Machine" if ARCH_MULTI_V7
+ select ARM_AMBA
+ select ARM_GIC
+ select ARM_PSCI
+ select HAVE_ARM_ARCH_TIMER
+
+#
+# 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-mvebu/Kconfig"
+
+source "arch/arm/mach-alpine/Kconfig"
+
+source "arch/arm/mach-asm9260/Kconfig"
+
+source "arch/arm/mach-at91/Kconfig"
+
+source "arch/arm/mach-axxia/Kconfig"
+
+source "arch/arm/mach-bcm/Kconfig"
+
+source "arch/arm/mach-berlin/Kconfig"
+
+source "arch/arm/mach-clps711x/Kconfig"
+
+source "arch/arm/mach-cns3xxx/Kconfig"
+
+source "arch/arm/mach-davinci/Kconfig"
+
+source "arch/arm/mach-digicolor/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-highbank/Kconfig"
+
+source "arch/arm/mach-hisi/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-keystone/Kconfig"
+
+source "arch/arm/mach-ks8695/Kconfig"
+
+source "arch/arm/mach-meson/Kconfig"
+
+source "arch/arm/mach-moxart/Kconfig"
+
+source "arch/arm/mach-mv78xx0/Kconfig"
+
+source "arch/arm/mach-imx/Kconfig"
+
+source "arch/arm/mach-mediatek/Kconfig"
+
+source "arch/arm/mach-mxs/Kconfig"
+
+source "arch/arm/mach-netx/Kconfig"
+
+source "arch/arm/mach-nomadik/Kconfig"
+
+source "arch/arm/mach-nspire/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-picoxcell/Kconfig"
+
+source "arch/arm/mach-pxa/Kconfig"
+source "arch/arm/plat-pxa/Kconfig"
+
+source "arch/arm/mach-mmp/Kconfig"
+
+source "arch/arm/mach-qcom/Kconfig"
+
+source "arch/arm/mach-realview/Kconfig"
+
+source "arch/arm/mach-rockchip/Kconfig"
+
+source "arch/arm/mach-sa1100/Kconfig"
+
+source "arch/arm/mach-socfpga/Kconfig"
+
+source "arch/arm/mach-spear/Kconfig"
+
+source "arch/arm/mach-sti/Kconfig"
+
+source "arch/arm/mach-s3c24xx/Kconfig"
+
+source "arch/arm/mach-s3c64xx/Kconfig"
+
+source "arch/arm/mach-s5pv210/Kconfig"
+
+source "arch/arm/mach-exynos/Kconfig"
+source "arch/arm/plat-samsung/Kconfig"
+
+source "arch/arm/mach-shmobile/Kconfig"
+
+source "arch/arm/mach-sunxi/Kconfig"
+
+source "arch/arm/mach-prima2/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"
+
+source "arch/arm/mach-zynq/Kconfig"
+
+# Definitions to make life easier
+config ARCH_ACORN
+ bool
+
+config PLAT_IOP
+ bool
+ select GENERIC_CLOCKEVENTS
+
+config PLAT_ORION
+ bool
+ select CLKSRC_MMIO
+ select COMMON_CLK
+ select GENERIC_IRQ_CHIP
+ select IRQ_DOMAIN
+
+config PLAT_ORION_LEGACY
+ bool
+ select PLAT_ORION
+
+config PLAT_PXA
+ bool
+
+config PLAT_VERSATILE
+ bool
+
+config ARM_TIMER_SP804
+ bool
+ select CLKSRC_MMIO
+ select CLKSRC_OF if OF
+
+source "arch/arm/firmware/Kconfig"
+
+source arch/arm/mm/Kconfig
+
+config IWMMXT
+ bool "Enable iWMMXt support"
+ depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 || CPU_PJ4B
+ default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 || CPU_PJ4B
+ help
+ Enable support for iWMMXt context switching at run time if
+ running on a CPU that supports it.
+
+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 PJ4B_ERRATA_4742
+ bool "PJ4B Errata 4742: IDLE Wake Up Commands can Cause the CPU Core to Cease Operation"
+ depends on CPU_PJ4B && MACH_ARMADA_370
+ default y
+ help
+ When coming out of either a Wait for Interrupt (WFI) or a Wait for
+ Event (WFE) IDLE states, a specific timing sensitivity exists between
+ the retiring WFI/WFE instructions and the newly issued subsequent
+ instructions. This sensitivity can result in a CPU hang scenario.
+ Workaround:
+ The software must insert either a Data Synchronization Barrier (DSB)
+ or Data Memory Barrier (DMB) command immediately after the WFI/WFE
+ instruction
+
+config ARM_ERRATA_326103
+ bool "ARM errata: FSR write bit incorrect on a SWP to read-only memory"
+ depends on CPU_V6
+ help
+ Executing a SWP instruction to read-only memory does not set bit 11
+ of the FSR on the ARM 1136 prior to r1p0. This causes the kernel to
+ treat the access as a read, preventing a COW from occurring and
+ causing the faulting task to livelock.
+
+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_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
+ r1p* 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
+ depends on !ARCH_MULTIPLATFORM
+ 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
+ depends on !ARCH_MULTIPLATFORM
+ 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
+ depends on !ARCH_MULTIPLATFORM
+ 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
+ depends on !ARCH_MULTIPLATFORM
+ 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 ARM_ERRATA_643719
+ bool "ARM errata: LoUIS bit field in CLIDR register is incorrect"
+ depends on CPU_V7 && SMP
+ default y
+ help
+ This option enables the workaround for the 643719 Cortex-A9 (prior to
+ r1p0) erratum. On affected cores the LoUIS bit field of the CLIDR
+ register returns zero when it should return one. The workaround
+ corrects this value, ensuring cache maintenance operations which use
+ it behave as intended and avoiding data corruption.
+
+config ARM_ERRATA_720789
+ bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID"
+ depends on CPU_V7
+ 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 ARM_ERRATA_743622
+ bool "ARM errata: Faulty hazard checking in the Store Buffer may lead to data corruption"
+ depends on CPU_V7
+ depends on !ARCH_MULTIPLATFORM
+ 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
+ depends on !ARCH_MULTIPLATFORM
+ 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_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_364296
+ bool "ARM errata: Possible cache data corruption with hit-under-miss enabled"
+ depends on CPU_V6
+ help
+ This options enables the workaround for the 364296 ARM1136
+ r0p2 erratum (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_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 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.
+
+config ARM_ERRATA_798181
+ bool "ARM errata: TLBI/DSB failure on Cortex-A15"
+ depends on CPU_V7 && SMP
+ help
+ On Cortex-A15 (r0p0..r3p2) the TLBI*IS/DSB operations are not
+ adequately shooting down all use of the old entries. This
+ option enables the Linux kernel workaround for this erratum
+ which sends an IPI to the CPUs that are running the same ASID
+ as the one being invalidated.
+
+config ARM_ERRATA_773022
+ bool "ARM errata: incorrect instructions may be executed from loop buffer"
+ depends on CPU_V7
+ help
+ This option enables the workaround for the 773022 Cortex-A15
+ (up to r0p4) erratum. In certain rare sequences of code, the
+ loop buffer may deliver incorrect instructions. This
+ workaround disables the loop buffer to avoid the erratum.
+
+endmenu
+
+source "arch/arm/common/Kconfig"
+
+menu "Bus support"
+
+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_DOMAINS_GENERIC
+ def_bool PCI_DOMAINS
+
+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
+
+config PCI_HOST_ITE8152
+ bool
+ depends on PCI && MACH_ARMCORE
+ default y
+ select DMABOUNCE
+
+source "drivers/pci/Kconfig"
+source "drivers/pci/pcie/Kconfig"
+
+source "drivers/pcmcia/Kconfig"
+
+endmenu
+
+menu "Kernel Features"
+
+config HAVE_SMP
+ bool
+ help
+ This option should be selected by machines which have an SMP-
+ capable CPU.
+
+ The only effect of this option is to make the SMP-related
+ options available to the user for configuration.
+
+config SMP
+ bool "Symmetric Multi-Processing"
+ depends on CPU_V6K || CPU_V7
+ depends on GENERIC_CLOCKEVENTS
+ depends on HAVE_SMP
+ depends on MMU || ARM_MPU
+ help
+ This enables support for systems with more than one CPU. If you have
+ a system with only one CPU, say N. If you have a system with more
+ than one CPU, say Y.
+
+ If you say N here, the kernel will run on uni- 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,
+ uniprocessor machines. On a uniprocessor machine, the kernel
+ will run faster if you say N here.
+
+ See also <file:Documentation/x86/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"
+ depends on SMP && !XIP_KERNEL && MMU
+ 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 ARM_CPU_TOPOLOGY
+ bool "Support cpu topology definition"
+ depends on SMP && CPU_V7
+ default y
+ help
+ Support ARM cpu topology definition. The MPIDR register defines
+ affinity between processors which is then used to describe the cpu
+ topology of an ARM System.
+
+config SCHED_MC
+ bool "Multi-core scheduler support"
+ depends on ARM_CPU_TOPOLOGY
+ help
+ Multi-core scheduler support improves the CPU scheduler's decision
+ making when dealing with multi-core CPU chips at a cost of slightly
+ increased overhead in some places. If unsure say N here.
+
+config SCHED_SMT
+ bool "SMT scheduler support"
+ depends on ARM_CPU_TOPOLOGY
+ help
+ Improves the CPU scheduler's decision making when dealing with
+ MultiThreading at a cost of slightly increased overhead in some
+ places. If unsure say N here.
+
+config HAVE_ARM_SCU
+ bool
+ help
+ This option enables support for the ARM system coherency unit
+
+config HAVE_ARM_ARCH_TIMER
+ bool "Architected timer support"
+ depends on CPU_V7
+ select ARM_ARCH_TIMER
+ select GENERIC_CLOCKEVENTS
+ help
+ This option enables support for the ARM architected timer
+
+config HAVE_ARM_TWD
+ bool
+ depends on SMP
+ select CLKSRC_OF if OF
+ help
+ This options enables support for the ARM timer and watchdog unit
+
+config MCPM
+ bool "Multi-Cluster Power Management"
+ depends on CPU_V7 && SMP
+ help
+ This option provides the common power management infrastructure
+ for (multi-)cluster based systems, such as big.LITTLE based
+ systems.
+
+config MCPM_QUAD_CLUSTER
+ bool
+ depends on MCPM
+ help
+ To avoid wasting resources unnecessarily, MCPM only supports up
+ to 2 clusters by default.
+ Platforms with 3 or 4 clusters that use MCPM must select this
+ option to allow the additional clusters to be managed.
+
+config BIG_LITTLE
+ bool "big.LITTLE support (Experimental)"
+ depends on CPU_V7 && SMP
+ select MCPM
+ help
+ This option enables support selections for the big.LITTLE
+ system architecture.
+
+config BL_SWITCHER
+ bool "big.LITTLE switcher support"
+ depends on BIG_LITTLE && MCPM && HOTPLUG_CPU
+ select ARM_CPU_SUSPEND
+ select CPU_PM
+ help
+ The big.LITTLE "switcher" provides the core functionality to
+ transparently handle transition between a cluster of A15's
+ and a cluster of A7's in a big.LITTLE system.
+
+config BL_SWITCHER_DUMMY_IF
+ tristate "Simple big.LITTLE switcher user interface"
+ depends on BL_SWITCHER && DEBUG_KERNEL
+ help
+ This is a simple and dummy char dev interface to control
+ the big.LITTLE switcher core code. It is meant for
+ debugging purposes only.
+
+choice
+ prompt "Memory split"
+ depends on MMU
+ 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 PHYS_OFFSET if !MMU
+ 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"
+ depends on SMP
+ help
+ Say Y here to experiment with turning CPUs off and on. CPUs
+ can be controlled through /sys/devices/system/cpu.
+
+config ARM_PSCI
+ bool "Support for the ARM Power State Coordination Interface (PSCI)"
+ depends on CPU_V7
+ help
+ Say Y here if you want Linux to communicate with system firmware
+ implementing the PSCI specification for CPU-centric power
+ management operations described in ARM document number ARM DEN
+ 0022A ("Power State Coordination Interface System Software on
+ ARM processors").
+
+# The GPIO number here must be sorted by descending number. In case of
+# a multiplatform kernel, we just want the highest value required by the
+# selected platforms.
+config ARCH_NR_GPIO
+ int
+ default 1024 if ARCH_SHMOBILE || ARCH_TEGRA || ARCH_ZYNQ
+ default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || \
+ SOC_DRA7XX || ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210
+ default 416 if ARCH_SUNXI
+ default 392 if ARCH_U8500
+ default 352 if ARCH_VT8500
+ default 288 if ARCH_ROCKCHIP
+ default 264 if MACH_H4700
+ default 0
+ help
+ Maximum number of GPIOs in the system.
+
+ If unsure, leave the default value.
+
+source kernel/Kconfig.preempt
+
+config HZ_FIXED
+ int
+ default 200 if ARCH_EBSA110 || ARCH_S3C24XX || \
+ ARCH_S5PV210 || ARCH_EXYNOS4
+ default 128 if SOC_AT91RM9200
+ default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE_LEGACY
+ default 0
+
+choice
+ depends on HZ_FIXED = 0
+ prompt "Timer frequency"
+
+config HZ_100
+ bool "100 Hz"
+
+config HZ_200
+ bool "200 Hz"
+
+config HZ_250
+ bool "250 Hz"
+
+config HZ_300
+ bool "300 Hz"
+
+config HZ_500
+ bool "500 Hz"
+
+config HZ_1000
+ bool "1000 Hz"
+
+endchoice
+
+config HZ
+ int
+ default HZ_FIXED if HZ_FIXED != 0
+ default 100 if HZ_100
+ default 200 if HZ_200
+ default 250 if HZ_250
+ default 300 if HZ_300
+ default 500 if HZ_500
+ default 1000
+
+config SCHED_HRTICK
+ def_bool HIGH_RES_TIMERS
+
+config THUMB2_KERNEL
+ bool "Compile the kernel in Thumb-2 mode" if !CPU_THUMBONLY
+ depends on (CPU_V7 || CPU_V7M) && !CPU_V6 && !CPU_V6K
+ default y if CPU_THUMBONLY
+ select AEABI
+ select ARM_ASM_UNIFIED
+ select ARM_UNWIND
+ 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 && !THUMB2_KERNEL
+ 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.
+
+ The seccomp filter system will not be available when this is
+ selected, since there is no way yet to sensibly distinguish
+ between calling conventions during filtering.
+
+ 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 N.
+
+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 HAVE_GENERIC_RCU_GUP
+ def_bool y
+ depends on ARM_LPAE
+
+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
+ default y
+ help
+ Enable hardware performance counter support for perf events. If
+ disabled, perf events will use software events only.
+
+config SYS_SUPPORTS_HUGETLBFS
+ def_bool y
+ depends on ARM_LPAE
+
+config HAVE_ARCH_TRANSPARENT_HUGEPAGE
+ def_bool y
+ depends on ARM_LPAE
+
+config ARCH_WANT_GENERAL_HUGETLB
+ def_bool y
+
+source "mm/Kconfig"
+
+config FORCE_MAX_ZONEORDER
+ int "Maximum zone order" if ARCH_SHMOBILE_LEGACY
+ range 11 64 if ARCH_SHMOBILE_LEGACY
+ default "12" if SOC_AM33XX
+ default "9" if SA1111 || ARCH_EFM32
+ 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 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()"
+ depends on MMU
+ 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 SWIOTLB
+ def_bool y
+
+config IOMMU_HELPER
+ def_bool SWIOTLB
+
+config XEN_DOM0
+ def_bool y
+ depends on XEN
+
+config XEN
+ bool "Xen guest support on ARM"
+ depends on ARM && AEABI && OF
+ depends on CPU_V7 && !CPU_V6
+ depends on !GENERIC_ATOMIC64
+ depends on MMU
+ select ARCH_DMA_ADDR_T_64BIT
+ select ARM_PSCI
+ select SWIOTLB_XEN
+ help
+ Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
+
+endmenu
+
+menu "Boot options"
+
+config USE_OF
+ bool "Flattened Device Tree support"
+ select IRQ_DOMAIN
+ select OF
+ select OF_EARLY_FLATTREE
+ select OF_RESERVED_MEM
+ help
+ Include support for flattened device tree machine descriptions.
+
+config ATAGS
+ bool "Support for the traditional ATAGS boot data passing" if USE_OF
+ default y
+ help
+ This is the traditional way of passing data to the kernel at boot
+ time. If you are solely relying on the flattened device tree (or
+ the ARM_ATAG_DTB_COMPAT option) then you may unselect this option
+ to remove ATAGS support from your kernel binary. If unsure,
+ leave this to y.
+
+config DEPRECATED_PARAM_STRUCT
+ bool "Provide old way to pass kernel parameters"
+ depends on ATAGS
+ help
+ This was deprecated in 2001 and announced to live on for 5 years.
+ Some old boot loaders still use this way.
+
+# 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
+ depends on !ARM_APPENDED_DTB && !XIP_KERNEL && !AUTO_ZRELADDR
+ help
+ Say Y here if you intend to execute your compressed kernel image
+ (zImage) directly from ROM or flash. If unsure, say N.
+
+config ARM_APPENDED_DTB
+ bool "Use appended device tree blob to zImage (EXPERIMENTAL)"
+ depends on OF
+ help
+ With this option, the boot code will look for a device tree binary
+ (DTB) appended to zImage
+ (e.g. cat zImage <filename>.dtb > zImage_w_dtb).
+
+ This is meant as a backward compatibility convenience for those
+ systems with a bootloader that can't be upgraded to accommodate
+ the documented boot protocol using a device tree.
+
+ Beware that there is very little in terms of protection against
+ this option being confused by leftover garbage in memory that might
+ look like a DTB header after a reboot if no actual DTB is appended
+ to zImage. Do not leave this option active in a production kernel
+ if you don't intend to always append a DTB. Proper passing of the
+ location into r2 of a bootloader provided DTB is always preferable
+ to this option.
+
+config ARM_ATAG_DTB_COMPAT
+ bool "Supplement the appended DTB with traditional ATAG information"
+ depends on ARM_APPENDED_DTB
+ help
+ Some old bootloaders can't be updated to a DTB capable one, yet
+ they provide ATAGs with memory configuration, the ramdisk address,
+ the kernel cmdline string, etc. Such information is dynamically
+ provided by the bootloader and can't always be stored in a static
+ DTB. To allow a device tree enabled kernel to be used with such
+ bootloaders, this option allows zImage to extract the information
+ from the ATAG list and store it at run time into the appended DTB.
+
+choice
+ prompt "Kernel command line type" if ARM_ATAG_DTB_COMPAT
+ default ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER
+
+config ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER
+ bool "Use bootloader kernel arguments if available"
+ help
+ Uses the command-line options passed by the boot loader instead of
+ the device tree bootargs property. If the boot loader doesn't provide
+ any, the device tree bootargs property will be used.
+
+config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND
+ bool "Extend with bootloader kernel arguments"
+ help
+ The command-line arguments provided by the boot loader will be
+ appended to the the device tree bootargs property.
+
+endchoice
+
+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
+ depends on ATAGS
+
+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 !ARM_LPAE && !ARCH_MULTIPLATFORM
+ 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 (!SMP || PM_SLEEP_SMP)
+ 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.
+
+config ATAGS_PROC
+ bool "Export atags in procfs"
+ depends on ATAGS && 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)"
+ 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"
+ 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"
+
+source "drivers/cpufreq/Kconfig"
+
+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
+ ---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.
+
+config KERNEL_MODE_NEON
+ bool "Support for NEON in kernel mode"
+ depends on NEON && AEABI
+ help
+ Say Y to include support for NEON in kernel mode.
+
+endmenu
+
+menu "Userspace binary formats"
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+menu "Power management options"
+
+source "kernel/power/Kconfig"
+
+config ARCH_SUSPEND_POSSIBLE
+ depends on CPU_ARM920T || CPU_ARM926T || CPU_FEROCEON || CPU_SA1100 || \
+ CPU_V6 || CPU_V6K || CPU_V7 || CPU_V7M || CPU_XSC3 || CPU_XSCALE || CPU_MOHAWK
+ def_bool y
+
+config ARM_CPU_SUSPEND
+ def_bool PM_SLEEP
+
+config ARCH_HIBERNATION_POSSIBLE
+ bool
+ depends on MMU
+ default y if ARCH_SUSPEND_POSSIBLE
+
+endmenu
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "drivers/firmware/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/arm/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+if CRYPTO
+source "arch/arm/crypto/Kconfig"
+endif
+
+source "lib/Kconfig"
+
+source "arch/arm/kvm/Kconfig"
diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu
new file mode 100644
index 000000000..aed66d5df
--- /dev/null
+++ b/arch/arm/Kconfig-nommu
@@ -0,0 +1,64 @@
+#
+# 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 || CPU_V7M)
+ 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.
+
+config ARM_MPU
+ bool 'Use the ARM v7 PMSA Compliant MPU'
+ depends on CPU_V7
+ default y
+ help
+ Some ARM systems without an MMU have instead a Memory Protection
+ Unit (MPU) that defines the type and permissions for regions of
+ memory.
+
+ If your CPU has an MPU then you should choose 'y' here unless you
+ know that you do not want to use the MPU.
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
new file mode 100644
index 000000000..0c12ffb15
--- /dev/null
+++ b/arch/arm/Kconfig.debug
@@ -0,0 +1,1604 @@
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+config ARM_PTDUMP
+ bool "Export kernel pagetable layout to userspace via debugfs"
+ depends on DEBUG_KERNEL
+ select DEBUG_FS
+ ---help---
+ Say Y here if you want to show the kernel pagetable layout in a
+ debugfs file. This information is only useful for kernel developers
+ who are working in architecture specific areas of the kernel.
+ It is probably not a good idea to enable this feature in a production
+ kernel.
+ If in doubt, say "N"
+
+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
+ 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 (read help!)"
+ 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.
+
+ Note that selecting this option will limit the kernel to a single
+ UART definition, as specified below. Attempting to boot the kernel
+ image on a different platform *will not work*, so this option should
+ not be enabled for kernels that are intended to be portable.
+
+choice
+ prompt "Kernel low-level debugging port"
+ depends on DEBUG_LL
+
+ config DEBUG_ALPINE_UART0
+ bool "Kernel low-level debugging messages via Alpine UART0"
+ depends on ARCH_ALPINE
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Alpine based platforms.
+
+ config DEBUG_ASM9260_UART
+ bool "Kernel low-level debugging via asm9260 UART"
+ depends on MACH_ASM9260
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to an UART or USART port on asm9260 based
+ machines.
+
+ DEBUG_UART_PHYS | DEBUG_UART_VIRT
+
+ 0x80000000 | 0xf0000000 | UART0
+ 0x80004000 | 0xf0004000 | UART1
+ 0x80008000 | 0xf0008000 | UART2
+ 0x8000c000 | 0xf000c000 | UART3
+ 0x80010000 | 0xf0010000 | UART4
+ 0x80014000 | 0xf0014000 | UART5
+ 0x80018000 | 0xf0018000 | UART6
+ 0x8001c000 | 0xf001c000 | UART7
+ 0x80020000 | 0xf0020000 | UART8
+ 0x80024000 | 0xf0024000 | UART9
+
+ config AT91_DEBUG_LL_DBGU0
+ bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10, 9rl, 9x5, 9n12"
+ select DEBUG_AT91_UART
+ depends on ARCH_AT91
+ depends on SOC_AT91RM9200 || SOC_AT91SAM9
+
+ config AT91_DEBUG_LL_DBGU1
+ bool "Kernel low-level debugging on 9263, 9g45 and sama5d3"
+ select DEBUG_AT91_UART
+ depends on ARCH_AT91
+ depends on SOC_AT91SAM9 || SOC_SAMA5
+
+ config AT91_DEBUG_LL_DBGU2
+ bool "Kernel low-level debugging on sama5d4"
+ select DEBUG_AT91_UART
+ depends on ARCH_AT91
+ depends on SOC_SAMA5
+
+ config DEBUG_BCM2835
+ bool "Kernel low-level debugging on BCM2835 PL011 UART"
+ depends on ARCH_BCM2835
+ select DEBUG_UART_PL01X
+
+ config DEBUG_BCM_5301X
+ bool "Kernel low-level debugging on BCM5301X UART1"
+ depends on ARCH_BCM_5301X
+ select DEBUG_UART_8250
+
+ config DEBUG_BCM_KONA_UART
+ bool "Kernel low-level debugging messages via BCM KONA UART"
+ depends on ARCH_BCM_MOBILE
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Broadcom SoC platforms.
+ This low level debug works for Broadcom
+ mobile SoCs in the Kona family of chips (e.g. bcm28155,
+ bcm11351, etc...)
+
+ config DEBUG_BCM63XX
+ bool "Kernel low-level debugging on BCM63XX UART"
+ depends on ARCH_BCM_63XX
+ select DEBUG_UART_BCM63XX
+
+ config DEBUG_BERLIN_UART
+ bool "Marvell Berlin SoC Debug UART"
+ depends on ARCH_BERLIN
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Marvell Berlin SoC based platforms.
+
+ config DEBUG_BRCMSTB_UART
+ bool "Use BRCMSTB UART for low-level debug"
+ depends on ARCH_BRCMSTB
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the first serial port on these devices.
+
+ If you have a Broadcom STB chip and would like early print
+ messages to appear over the UART, select this option.
+
+ config DEBUG_CLPS711X_UART1
+ bool "Kernel low-level debugging messages via UART1"
+ depends on ARCH_CLPS711X
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the first serial port on these devices.
+
+ config DEBUG_CLPS711X_UART2
+ bool "Kernel low-level debugging messages via UART2"
+ depends on 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.
+
+ config DEBUG_CNS3XXX
+ bool "Kernel Kernel low-level debugging on Cavium Networks CNS3xxx"
+ depends on ARCH_CNS3XXX
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the CNS3xxx UART0.
+
+ config DEBUG_DAVINCI_DA8XX_UART1
+ bool "Kernel low-level debugging on DaVinci DA8XX using UART1"
+ depends on ARCH_DAVINCI_DA8XX
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART1 serial port on DaVinci DA8XX devices.
+
+ config DEBUG_DAVINCI_DA8XX_UART2
+ bool "Kernel low-level debugging on DaVinci DA8XX using UART2"
+ depends on ARCH_DAVINCI_DA8XX
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART2 serial port on DaVinci DA8XX devices.
+
+ config DEBUG_DAVINCI_DMx_UART0
+ bool "Kernel low-level debugging on DaVinci DMx using UART0"
+ depends on ARCH_DAVINCI_DMx
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART0 serial port on DaVinci DMx devices.
+
+ config DEBUG_ZYNQ_UART0
+ bool "Kernel low-level debugging on Xilinx Zynq using UART0"
+ depends on ARCH_ZYNQ
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART0 on the Zynq platform.
+
+ config DEBUG_ZYNQ_UART1
+ bool "Kernel low-level debugging on Xilinx Zynq using UART1"
+ depends on ARCH_ZYNQ
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART1 on the Zynq platform.
+
+ If you have a ZC702 board and want early boot messages to
+ appear on the USB serial adaptor, select this option.
+
+ config DEBUG_DC21285_PORT
+ bool "Kernel low-level debugging messages via footbridge serial port"
+ depends on FOOTBRIDGE
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the serial port in the DC21285 (Footbridge).
+
+ config DEBUG_DIGICOLOR_UA0
+ bool "Kernel low-level debugging messages via Digicolor UA0"
+ depends on ARCH_DIGICOLOR
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the UA0 serial port in the CX92755.
+
+ config DEBUG_FOOTBRIDGE_COM1
+ bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1"
+ depends on FOOTBRIDGE
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the 8250 at PCI COM1.
+
+ config DEBUG_HI3620_UART
+ bool "Hisilicon HI3620 Debug UART"
+ depends on ARCH_HI3xxx
+ select DEBUG_UART_PL01X
+ help
+ Say Y here if you want kernel low-level debugging support
+ on HI3620 UART.
+
+ config DEBUG_HI3716_UART
+ bool "Hisilicon Hi3716 Debug UART"
+ depends on ARCH_HI3xxx
+ select DEBUG_UART_PL01X
+ help
+ Say Y here if you want kernel low-level debugging support
+ on HI3716 UART.
+
+ config DEBUG_HIGHBANK_UART
+ bool "Kernel low-level debugging messages via Highbank UART"
+ depends on ARCH_HIGHBANK
+ select DEBUG_UART_PL01X
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the UART on Highbank based devices.
+
+ config DEBUG_HIP01_UART
+ bool "Hisilicon Hip01 Debug UART"
+ depends on ARCH_HIP01
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on HIP01 UART.
+
+ config DEBUG_HIP04_UART
+ bool "Hisilicon HiP04 Debug UART"
+ depends on ARCH_HIP04
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on HIP04 UART.
+
+ config DEBUG_HIX5HD2_UART
+ bool "Hisilicon Hix5hd2 Debug UART"
+ depends on ARCH_HIX5HD2
+ select DEBUG_UART_PL01X
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Hix5hd2 UART.
+
+ config DEBUG_IMX1_UART
+ bool "i.MX1 Debug UART"
+ depends on SOC_IMX1
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX1.
+
+ config DEBUG_IMX23_UART
+ bool "i.MX23 Debug UART"
+ depends on SOC_IMX23
+ select DEBUG_UART_PL01X
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX23.
+
+ config DEBUG_IMX25_UART
+ bool "i.MX25 Debug UART"
+ depends on SOC_IMX25
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX25.
+
+ config DEBUG_IMX21_IMX27_UART
+ bool "i.MX21 and i.MX27 Debug UART"
+ depends on SOC_IMX21 || SOC_IMX27
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX21 or i.MX27.
+
+ config DEBUG_IMX28_UART
+ bool "i.MX28 Debug UART"
+ depends on SOC_IMX28
+ select DEBUG_UART_PL01X
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX28.
+
+ config DEBUG_IMX31_UART
+ bool "i.MX31 Debug UART"
+ depends on SOC_IMX31
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX31.
+
+ config DEBUG_IMX35_UART
+ bool "i.MX35 Debug UART"
+ depends on SOC_IMX35
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX35.
+
+ config DEBUG_IMX50_UART
+ bool "i.MX50 Debug UART"
+ depends on SOC_IMX50
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX50.
+
+ config DEBUG_IMX51_UART
+ bool "i.MX51 Debug UART"
+ depends on SOC_IMX51
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX51.
+
+ config DEBUG_IMX53_UART
+ bool "i.MX53 Debug UART"
+ depends on SOC_IMX53
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX53.
+
+ config DEBUG_IMX6Q_UART
+ bool "i.MX6Q/DL Debug UART"
+ depends on SOC_IMX6Q
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX6Q/DL.
+
+ config DEBUG_IMX6SL_UART
+ bool "i.MX6SL Debug UART"
+ depends on SOC_IMX6SL
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX6SL.
+
+ config DEBUG_IMX6SX_UART
+ bool "i.MX6SX Debug UART"
+ depends on SOC_IMX6SX
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX6SX.
+
+ config DEBUG_KEYSTONE_UART0
+ bool "Kernel low-level debugging on KEYSTONE2 using UART0"
+ depends on ARCH_KEYSTONE
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART0 serial port on KEYSTONE2 devices.
+
+ config DEBUG_KEYSTONE_UART1
+ bool "Kernel low-level debugging on KEYSTONE2 using UART1"
+ depends on ARCH_KEYSTONE
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART1 serial port on KEYSTONE2 devices.
+
+ config DEBUG_KS8695_UART
+ bool "KS8695 Debug UART"
+ depends on ARCH_KS8695
+ help
+ Say Y here if you want kernel low-level debugging support
+ on KS8695.
+
+ config DEBUG_MESON_UARTAO
+ bool "Kernel low-level debugging via Meson6 UARTAO"
+ depends on ARCH_MESON
+ help
+ Say Y here if you want kernel low-lever debugging support
+ on Amlogic Meson6 based platforms on the UARTAO.
+
+ config DEBUG_MMP_UART2
+ bool "Kernel low-level debugging message via MMP UART2"
+ depends on ARCH_MMP
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on MMP UART2.
+
+ config DEBUG_MMP_UART3
+ bool "Kernel low-level debugging message via MMP UART3"
+ depends on ARCH_MMP
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on MMP UART3.
+
+ config DEBUG_QCOM_UARTDM
+ bool "Kernel low-level debugging messages via QCOM UARTDM"
+ depends on ARCH_QCOM
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the serial port on Qualcomm devices.
+
+ ARCH DEBUG_UART_PHYS DEBUG_UART_VIRT
+ APQ8064 0x16640000 0xf0040000
+ APQ8084 0xf995e000 0xfa75e000
+ MSM8X60 0x19c40000 0xf0040000
+ MSM8960 0x16440000 0xf0040000
+ MSM8974 0xf991e000 0xfa71e000
+
+ Please adjust DEBUG_UART_PHYS and DEBUG_UART_BASE configuration
+ options based on your needs.
+
+ config DEBUG_MVEBU_UART0
+ bool "Kernel low-level debugging messages via MVEBU UART0 (old bootloaders)"
+ depends on ARCH_MVEBU
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on MVEBU based platforms on UART0.
+
+ This option should be used with the old bootloaders
+ that left the internal registers mapped at
+ 0xd0000000. As of today, this is the case on
+ platforms such as the Globalscale Mirabox or the
+ Plathome OpenBlocks AX3, when using the original
+ bootloader.
+
+ If the wrong DEBUG_MVEBU_UART* option is selected,
+ when u-boot hands over to the kernel, the system
+ silently crashes, with no serial output at all.
+
+ config DEBUG_MVEBU_UART0_ALTERNATE
+ bool "Kernel low-level debugging messages via MVEBU UART0 (new bootloaders)"
+ depends on ARCH_MVEBU
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on MVEBU based platforms on UART0.
+
+ This option should be used with the new bootloaders
+ that remap the internal registers at 0xf1000000.
+
+ If the wrong DEBUG_MVEBU_UART* option is selected,
+ when u-boot hands over to the kernel, the system
+ silently crashes, with no serial output at all.
+
+ config DEBUG_MVEBU_UART1_ALTERNATE
+ bool "Kernel low-level debugging messages via MVEBU UART1 (new bootloaders)"
+ depends on ARCH_MVEBU
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on MVEBU based platforms on UART1.
+
+ This option should be used with the new bootloaders
+ that remap the internal registers at 0xf1000000.
+
+ If the wrong DEBUG_MVEBU_UART* option is selected,
+ when u-boot hands over to the kernel, the system
+ silently crashes, with no serial output at all.
+
+ config DEBUG_VF_UART
+ bool "Vybrid UART"
+ depends on SOC_VF610
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Vybrid based platforms.
+
+ config DEBUG_NETX_UART
+ bool "Kernel low-level debugging messages via NetX UART"
+ depends on ARCH_NETX
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Hilscher NetX based platforms.
+
+ config DEBUG_NOMADIK_UART
+ bool "Kernel low-level debugging messages via NOMADIK UART"
+ depends on ARCH_NOMADIK
+ select DEBUG_UART_PL01X
+ help
+ Say Y here if you want kernel low-level debugging support
+ on NOMADIK based platforms.
+
+ config DEBUG_NSPIRE_CLASSIC_UART
+ bool "Kernel low-level debugging via TI-NSPIRE 8250 UART"
+ depends on ARCH_NSPIRE
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on TI-NSPIRE classic models.
+
+ config DEBUG_NSPIRE_CX_UART
+ bool "Kernel low-level debugging via TI-NSPIRE PL011 UART"
+ depends on ARCH_NSPIRE
+ select DEBUG_UART_PL01X
+ help
+ Say Y here if you want kernel low-level debugging support
+ on TI-NSPIRE CX models.
+
+ config DEBUG_OMAP1UART1
+ bool "Kernel low-level debugging via OMAP1 UART1"
+ depends on ARCH_OMAP1
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on OMAP1 based platforms (except OMAP730) on the UART1.
+
+ config DEBUG_OMAP1UART2
+ bool "Kernel low-level debugging via OMAP1 UART2"
+ depends on ARCH_OMAP1
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on OMAP1 based platforms (except OMAP730) on the UART2.
+
+ config DEBUG_OMAP1UART3
+ bool "Kernel low-level debugging via OMAP1 UART3"
+ depends on ARCH_OMAP1
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on OMAP1 based platforms (except OMAP730) on the UART3.
+
+ config DEBUG_OMAP2UART1
+ bool "OMAP2/3/4 UART1 (omap2/3 sdp boards and some omap3 boards)"
+ depends on ARCH_OMAP2PLUS
+ select DEBUG_OMAP2PLUS_UART
+ help
+ This covers at least h4, 2430sdp, 3430sdp, 3630sdp,
+ omap3 torpedo and 3530 lv som.
+
+ config DEBUG_OMAP2UART2
+ bool "Kernel low-level debugging messages via OMAP2/3/4 UART2"
+ depends on ARCH_OMAP2PLUS
+ select DEBUG_OMAP2PLUS_UART
+
+ config DEBUG_OMAP2UART3
+ bool "Kernel low-level debugging messages via OMAP2 UART3 (n8x0)"
+ depends on ARCH_OMAP2PLUS
+ select DEBUG_OMAP2PLUS_UART
+
+ config DEBUG_OMAP3UART3
+ bool "Kernel low-level debugging messages via OMAP3 UART3 (most omap3 boards)"
+ depends on ARCH_OMAP2PLUS
+ select DEBUG_OMAP2PLUS_UART
+ help
+ This covers at least cm_t3x, beagle, crane, devkit8000,
+ igep00x0, ldp, n900, n9(50), pandora, overo, touchbook,
+ and 3517evm.
+
+ config DEBUG_OMAP4UART3
+ bool "Kernel low-level debugging messages via OMAP4/5 UART3 (omap4 blaze, panda, omap5 sevm)"
+ depends on ARCH_OMAP2PLUS
+ select DEBUG_OMAP2PLUS_UART
+
+ config DEBUG_OMAP3UART4
+ bool "Kernel low-level debugging messages via OMAP36XX UART4"
+ depends on ARCH_OMAP2PLUS
+ select DEBUG_OMAP2PLUS_UART
+
+ config DEBUG_OMAP4UART4
+ bool "Kernel low-level debugging messages via OMAP4/5 UART4"
+ depends on ARCH_OMAP2PLUS
+ select DEBUG_OMAP2PLUS_UART
+
+ config DEBUG_OMAP7XXUART1
+ bool "Kernel low-level debugging via OMAP730 UART1"
+ depends on ARCH_OMAP730
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on OMAP730 based platforms on the UART1.
+
+ config DEBUG_OMAP7XXUART2
+ bool "Kernel low-level debugging via OMAP730 UART2"
+ depends on ARCH_OMAP730
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on OMAP730 based platforms on the UART2.
+
+ config DEBUG_OMAP7XXUART3
+ bool "Kernel low-level debugging via OMAP730 UART3"
+ depends on ARCH_OMAP730
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on OMAP730 based platforms on the UART3.
+
+ config DEBUG_TI81XXUART1
+ bool "Kernel low-level debugging messages via TI81XX UART1 (ti8148evm)"
+ depends on ARCH_OMAP2PLUS
+ select DEBUG_OMAP2PLUS_UART
+
+ config DEBUG_TI81XXUART2
+ bool "Kernel low-level debugging messages via TI81XX UART2"
+ depends on ARCH_OMAP2PLUS
+ select DEBUG_OMAP2PLUS_UART
+
+ config DEBUG_TI81XXUART3
+ bool "Kernel low-level debugging messages via TI81XX UART3 (ti8168evm)"
+ depends on ARCH_OMAP2PLUS
+ select DEBUG_OMAP2PLUS_UART
+
+ config DEBUG_AM33XXUART1
+ bool "Kernel low-level debugging messages via AM33XX UART1"
+ depends on ARCH_OMAP2PLUS
+ select DEBUG_OMAP2PLUS_UART
+
+ config DEBUG_ZOOM_UART
+ bool "Kernel low-level debugging messages via Zoom2/3 UART"
+ depends on ARCH_OMAP2PLUS
+ select DEBUG_OMAP2PLUS_UART
+
+ config DEBUG_PICOXCELL_UART
+ depends on ARCH_PICOXCELL
+ bool "Use PicoXcell UART for low-level debug"
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on PicoXcell based platforms.
+
+ config DEBUG_PXA_UART1
+ depends on ARCH_PXA
+ bool "Use PXA UART1 for low-level debug"
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on PXA UART1.
+
+ config DEBUG_REALVIEW_STD_PORT
+ bool "RealView Default UART"
+ depends on ARCH_REALVIEW
+ select DEBUG_UART_PL01X
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the serial port on RealView EB, PB11MP, PBA8
+ and PBX platforms.
+
+ config DEBUG_REALVIEW_PB1176_PORT
+ bool "RealView PB1176 UART"
+ depends on MACH_REALVIEW_PB1176
+ select DEBUG_UART_PL01X
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the standard serial port on the RealView
+ PB1176 platform.
+
+ config DEBUG_RK29_UART0
+ bool "Kernel low-level debugging messages via Rockchip RK29 UART0"
+ depends on ARCH_ROCKCHIP
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Rockchip based platforms.
+
+ config DEBUG_RK29_UART1
+ bool "Kernel low-level debugging messages via Rockchip RK29 UART1"
+ depends on ARCH_ROCKCHIP
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Rockchip based platforms.
+
+ config DEBUG_RK29_UART2
+ bool "Kernel low-level debugging messages via Rockchip RK29 UART2"
+ depends on ARCH_ROCKCHIP
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Rockchip based platforms.
+
+ config DEBUG_RK3X_UART0
+ bool "Kernel low-level debugging messages via Rockchip RK30/RK31 UART0"
+ depends on ARCH_ROCKCHIP
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Rockchip based platforms.
+
+ config DEBUG_RK3X_UART1
+ bool "Kernel low-level debugging messages via Rockchip RK30/RK31 UART1"
+ depends on ARCH_ROCKCHIP
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Rockchip based platforms.
+
+ config DEBUG_RK3X_UART2
+ bool "Kernel low-level debugging messages via Rockchip RK30/RK31 UART2"
+ depends on ARCH_ROCKCHIP
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Rockchip based platforms.
+
+ config DEBUG_RK3X_UART3
+ bool "Kernel low-level debugging messages via Rockchip RK30/RK31 UART3"
+ depends on ARCH_ROCKCHIP
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Rockchip based platforms.
+
+ config DEBUG_RK32_UART2
+ bool "Kernel low-level debugging messages via Rockchip RK32 UART2"
+ depends on ARCH_ROCKCHIP
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Rockchip RK32xx based platforms.
+
+ config DEBUG_R7S72100_SCIF2
+ bool "Kernel low-level debugging messages via SCIF2 on R7S72100"
+ depends on ARCH_R7S72100
+ help
+ Say Y here if you want kernel low-level debugging support
+ via SCIF2 on Renesas RZ/A1H (R7S72100).
+
+ config DEBUG_RCAR_GEN1_SCIF0
+ bool "Kernel low-level debugging messages via SCIF0 on R8A7778"
+ depends on ARCH_R8A7778
+ help
+ Say Y here if you want kernel low-level debugging support
+ via SCIF0 on Renesas R-Car M1A (R8A7778).
+
+ config DEBUG_RCAR_GEN1_SCIF2
+ bool "Kernel low-level debugging messages via SCIF2 on R8A7779"
+ depends on ARCH_R8A7779
+ help
+ Say Y here if you want kernel low-level debugging support
+ via SCIF2 on Renesas R-Car H1 (R8A7779).
+
+ config DEBUG_RCAR_GEN2_SCIF0
+ bool "Kernel low-level debugging messages via SCIF0 on R8A7790/R8A7791/R8A7793"
+ depends on ARCH_R8A7790 || ARCH_R8A7791 || ARCH_R8A7793
+ help
+ Say Y here if you want kernel low-level debugging support
+ via SCIF0 on Renesas R-Car H2 (R8A7790), M2-W (R8A7791), or
+ M2-N (R8A7793).
+
+ config DEBUG_RCAR_GEN2_SCIF2
+ bool "Kernel low-level debugging messages via SCIF2 on R8A7794"
+ depends on ARCH_R8A7794
+ help
+ Say Y here if you want kernel low-level debugging support
+ via SCIF2 on Renesas R-Car E2 (R8A7794).
+
+ config DEBUG_RMOBILE_SCIFA0
+ bool "Kernel low-level debugging messages via SCIFA0 on R8A73A4"
+ depends on ARCH_R8A73A4
+ help
+ Say Y here if you want kernel low-level debugging support
+ via SCIFA0 on Renesas R-Mobile APE6 (R8A73A4).
+
+ config DEBUG_RMOBILE_SCIFA1
+ bool "Kernel low-level debugging messages via SCIFA1 on R8A7740"
+ depends on ARCH_R8A7740
+ help
+ Say Y here if you want kernel low-level debugging support
+ via SCIFA1 on Renesas R-Mobile A1 (R8A7740).
+
+ config DEBUG_RMOBILE_SCIFA4
+ bool "Kernel low-level debugging messages via SCIFA4 on SH73A0"
+ depends on ARCH_SH73A0
+ help
+ Say Y here if you want kernel low-level debugging support
+ via SCIFA4 on Renesas SH-Mobile AG5 (SH73A0).
+
+ config DEBUG_S3C_UART0
+ depends on PLAT_SAMSUNG
+ select DEBUG_EXYNOS_UART if ARCH_EXYNOS
+ select DEBUG_S3C24XX_UART if ARCH_S3C24XX
+ select DEBUG_S5PV210_UART if ARCH_S5PV210
+ bool "Use Samsung S3C UART 0 for low-level debug"
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART 0. The port must have been initialised
+ by the boot-loader before use.
+
+ config DEBUG_S3C_UART1
+ depends on PLAT_SAMSUNG
+ select DEBUG_EXYNOS_UART if ARCH_EXYNOS
+ select DEBUG_S3C24XX_UART if ARCH_S3C24XX
+ select DEBUG_S5PV210_UART if ARCH_S5PV210
+ bool "Use Samsung S3C UART 1 for low-level debug"
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART 1. The port must have been initialised
+ by the boot-loader before use.
+
+ config DEBUG_S3C_UART2
+ depends on PLAT_SAMSUNG
+ select DEBUG_EXYNOS_UART if ARCH_EXYNOS
+ select DEBUG_S3C24XX_UART if ARCH_S3C24XX
+ select DEBUG_S5PV210_UART if ARCH_S5PV210
+ bool "Use Samsung S3C UART 2 for low-level debug"
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART 2. The port must have been initialised
+ by the boot-loader before use.
+
+ config DEBUG_S3C_UART3
+ depends on PLAT_SAMSUNG && (ARCH_EXYNOS || ARCH_S5PV210)
+ select DEBUG_EXYNOS_UART if ARCH_EXYNOS
+ select DEBUG_S5PV210_UART if ARCH_S5PV210
+ bool "Use Samsung S3C UART 3 for low-level debug"
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART 3. The port must have been initialised
+ by the boot-loader before use.
+
+ config DEBUG_S3C2410_UART0
+ depends on ARCH_S3C24XX
+ select DEBUG_S3C2410_UART
+ bool "Use S3C2410/S3C2412 UART 0 for low-level debug"
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART 0. The port must have been initialised
+ by the boot-loader before use.
+
+ config DEBUG_S3C2410_UART1
+ depends on ARCH_S3C24XX
+ select DEBUG_S3C2410_UART
+ bool "Use S3C2410/S3C2412 UART 1 for low-level debug"
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART 1. The port must have been initialised
+ by the boot-loader before use.
+
+ config DEBUG_S3C2410_UART2
+ depends on ARCH_S3C24XX
+ select DEBUG_S3C2410_UART
+ bool "Use S3C2410/S3C2412 UART 2 for low-level debug"
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART 2. The port must have been initialised
+ by the boot-loader before use.
+
+ config DEBUG_SA1100
+ depends on ARCH_SA1100
+ bool "Use SA1100 UARTs for low-level debug"
+ help
+ Say Y here if you want kernel low-level debugging support
+ on SA-11x0 UART ports. The kernel will check for the first
+ enabled UART in a sequence 3-1-2.
+
+ config DEBUG_SOCFPGA_UART
+ depends on ARCH_SOCFPGA
+ bool "Use SOCFPGA UART for low-level debug"
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on SOCFPGA based platforms.
+
+ config DEBUG_SUN9I_UART0
+ bool "Kernel low-level debugging messages via sun9i UART0"
+ depends on MACH_SUN9I
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Allwinner A80 based platforms on the UART0.
+
+ config DEBUG_SUNXI_UART0
+ bool "Kernel low-level debugging messages via sunXi UART0"
+ depends on ARCH_SUNXI
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Allwinner A1X based platforms on the UART0.
+
+ config DEBUG_SUNXI_UART1
+ bool "Kernel low-level debugging messages via sunXi UART1"
+ depends on ARCH_SUNXI
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Allwinner A1X based platforms on the UART1.
+
+ config DEBUG_SUNXI_R_UART
+ bool "Kernel low-level debugging messages via sunXi R_UART"
+ depends on MACH_SUN6I || MACH_SUN8I
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Allwinner A31/A23 based platforms on the R_UART.
+
+ config TEGRA_DEBUG_UART_AUTO_ODMDATA
+ bool "Kernel low-level debugging messages via Tegra UART via ODMDATA"
+ depends on ARCH_TEGRA
+ select DEBUG_TEGRA_UART
+ help
+ Automatically determines which UART to use for low-level
+ debug based on the ODMDATA value. This value is part of
+ the BCT, and is written to the boot memory device using
+ nvflash, or other flashing tool. When bits 19:18 are 3,
+ then bits 17:15 indicate which UART to use; 0/1/2/3/4
+ are UART A/B/C/D/E.
+
+ config TEGRA_DEBUG_UARTA
+ bool "Kernel low-level debugging messages via Tegra UART A"
+ depends on ARCH_TEGRA
+ select DEBUG_TEGRA_UART
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Tegra based platforms.
+
+ config TEGRA_DEBUG_UARTB
+ bool "Kernel low-level debugging messages via Tegra UART B"
+ depends on ARCH_TEGRA
+ select DEBUG_TEGRA_UART
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Tegra based platforms.
+
+ config TEGRA_DEBUG_UARTC
+ bool "Kernel low-level debugging messages via Tegra UART C"
+ depends on ARCH_TEGRA
+ select DEBUG_TEGRA_UART
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Tegra based platforms.
+
+ config TEGRA_DEBUG_UARTD
+ bool "Kernel low-level debugging messages via Tegra UART D"
+ depends on ARCH_TEGRA
+ select DEBUG_TEGRA_UART
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Tegra based platforms.
+
+ config TEGRA_DEBUG_UARTE
+ bool "Kernel low-level debugging messages via Tegra UART E"
+ depends on ARCH_TEGRA
+ select DEBUG_TEGRA_UART
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Tegra based platforms.
+
+ config DEBUG_SIRFPRIMA2_UART1
+ bool "Kernel low-level debugging messages via SiRFprimaII UART1"
+ depends on ARCH_PRIMA2
+ select DEBUG_SIRFSOC_UART
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the uart1 port on SiRFprimaII devices.
+
+ config DEBUG_SIRFATLAS7_UART0
+ bool "Kernel low-level debugging messages via SiRFatlas7 UART0"
+ depends on ARCH_ATLAS7
+ select DEBUG_SIRFSOC_UART
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the uart0 port on SiRFATLAS7 devices.The uart0
+ is used on SiRFATLAS7 as a extra debug port.sometimes an extra
+ debug port can be very useful.
+
+ config DEBUG_SIRFATLAS7_UART1
+ bool "Kernel low-level debugging messages via SiRFatlas7 UART1"
+ depends on ARCH_ATLAS7
+ select DEBUG_SIRFSOC_UART
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the uart1 port on SiRFATLAS7 devices.
+
+ config STIH41X_DEBUG_ASC2
+ bool "Use StiH415/416 ASC2 UART for low-level debug"
+ depends on ARCH_STI
+ select DEBUG_STI_UART
+ help
+ Say Y here if you want kernel low-level debugging support
+ on STiH415/416 based platforms like b2000, which has
+ default UART wired up to ASC2.
+
+ If unsure, say N.
+
+ config STIH41X_DEBUG_SBC_ASC1
+ bool "Use StiH415/416 SBC ASC1 UART for low-level debug"
+ depends on ARCH_STI
+ select DEBUG_STI_UART
+ help
+ Say Y here if you want kernel low-level debugging support
+ on STiH415/416 based platforms like b2020. which has
+ default UART wired up to SBC ASC1.
+
+ If unsure, say N.
+
+ config DEBUG_U300_UART
+ bool "Kernel low-level debugging messages via U300 UART0"
+ depends on ARCH_U300
+ select DEBUG_UART_PL01X
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the uart port on U300 devices.
+
+ config DEBUG_UX500_UART
+ depends on ARCH_U8500
+ bool "Use Ux500 UART for low-level debug"
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Ux500 based platforms.
+
+ config DEBUG_MT6589_UART0
+ bool "Mediatek mt6589 UART0"
+ depends on ARCH_MEDIATEK
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ for Mediatek mt6589 based platforms on UART0.
+
+ config DEBUG_MT8127_UART0
+ bool "Mediatek mt8127/mt6592 UART0"
+ depends on ARCH_MEDIATEK
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ for Mediatek mt8127 based platforms on UART0.
+
+ config DEBUG_MT8135_UART3
+ bool "Mediatek mt8135 UART3"
+ depends on ARCH_MEDIATEK
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ for Mediatek mt8135 based platforms on UART3.
+
+ config DEBUG_VEXPRESS_UART0_DETECT
+ bool "Autodetect UART0 on Versatile Express Cortex-A core tiles"
+ depends on ARCH_VEXPRESS && CPU_CP15_MMU
+ help
+ This option enables a simple heuristic which tries to determine
+ the motherboard's memory map variant (original or RS1) and then
+ choose the relevant UART0 base address.
+
+ Note that this will only work with standard A-class core tiles,
+ and may fail with non-standard SMM or custom software models.
+
+ config DEBUG_VEXPRESS_UART0_CA9
+ bool "Use PL011 UART0 at 0x10009000 (V2P-CA9 core tile)"
+ depends on ARCH_VEXPRESS
+ select DEBUG_UART_PL01X
+ help
+ This option selects UART0 at 0x10009000. Except for custom models,
+ this applies only to the V2P-CA9 tile.
+
+ config DEBUG_VEXPRESS_UART0_RS1
+ bool "Use PL011 UART0 at 0x1c090000 (RS1 complaint tiles)"
+ depends on ARCH_VEXPRESS
+ select DEBUG_UART_PL01X
+ help
+ This option selects UART0 at 0x1c090000. This applies to most
+ of the tiles using the RS1 memory map, including all new A-class
+ core tiles, FPGA-based SMMs and software models.
+
+ config DEBUG_VEXPRESS_UART0_CRX
+ bool "Use PL011 UART0 at 0xb0090000 (Cortex-R compliant tiles)"
+ depends on ARCH_VEXPRESS && !MMU
+ select DEBUG_UART_PL01X
+ help
+ This option selects UART0 at 0xb0090000. This is appropriate for
+ Cortex-R series tiles and SMMs, such as Cortex-R5 and Cortex-R7
+
+ config DEBUG_VT8500_UART0
+ bool "Use UART0 on VIA/Wondermedia SoCs"
+ depends on ARCH_VT8500
+ help
+ This option selects UART0 on VIA/Wondermedia System-on-a-chip
+ devices, including VT8500, WM8505, WM8650 and WM8850.
+
+ config DEBUG_ICEDCC
+ bool "Kernel low-level debugging via EmbeddedICE DCC channel"
+ 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.
+
+ Note that the system will appear to hang during boot if there
+ is nothing connected to read from the DCC.
+
+ config DEBUG_SEMIHOSTING
+ bool "Kernel low-level debug output via semihosting I/O"
+ help
+ Semihosting enables code running on an ARM target to use
+ the I/O facilities on a host debugger/emulator through a
+ simple SVC call. The host debugger or emulator must have
+ semihosting enabled for the special svc call to be trapped
+ otherwise the kernel will crash.
+
+ This is known to work with OpenOCD, as well as
+ ARM's Fast Models, or any other controlling environment
+ that implements semihosting.
+
+ For more details about semihosting, please see
+ chapter 8 of DUI0203I_rvct_developer_guide.pdf from ARM Ltd.
+
+ config DEBUG_LL_UART_8250
+ bool "Kernel low-level debugging via 8250 UART"
+ help
+ Say Y here if you wish the debug print routes to direct
+ their output to an 8250 UART. You can use this option
+ to provide the parameters for the 8250 UART rather than
+ selecting one of the platform specific options above if
+ you know the parameters for the port.
+
+ This option is preferred over the platform specific
+ options; the platform specific options are deprecated
+ and will be soon removed.
+
+ config DEBUG_LL_UART_EFM32
+ bool "Kernel low-level debugging via efm32 UART"
+ depends on ARCH_EFM32
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to an UART or USART port on efm32 based
+ machines. Use the following addresses for DEBUG_UART_PHYS:
+
+ 0x4000c000 | USART0
+ 0x4000c400 | USART1
+ 0x4000c800 | USART2
+ 0x4000e000 | UART0
+ 0x4000e400 | UART1
+
+ config DEBUG_LL_UART_PL01X
+ bool "Kernel low-level debugging via ARM Ltd PL01x Primecell UART"
+ help
+ Say Y here if you wish the debug print routes to direct
+ their output to a PL01x Primecell UART. You can use
+ this option to provide the parameters for the UART
+ rather than selecting one of the platform specific
+ options above if you know the parameters for the port.
+
+ This option is preferred over the platform specific
+ options; the platform specific options are deprecated
+ and will be soon removed.
+
+endchoice
+
+config DEBUG_AT91_UART
+ bool
+ depends on ARCH_AT91
+
+config DEBUG_EXYNOS_UART
+ bool
+
+config DEBUG_S3C2410_UART
+ bool
+ select DEBUG_S3C24XX_UART
+
+config DEBUG_S3C24XX_UART
+ bool
+
+config DEBUG_S5PV210_UART
+ bool
+
+config DEBUG_OMAP2PLUS_UART
+ bool
+ depends on ARCH_OMAP2PLUS
+
+config DEBUG_IMX_UART_PORT
+ int "i.MX Debug UART Port Selection" if DEBUG_IMX1_UART || \
+ DEBUG_IMX25_UART || \
+ DEBUG_IMX21_IMX27_UART || \
+ DEBUG_IMX31_UART || \
+ DEBUG_IMX35_UART || \
+ DEBUG_IMX50_UART || \
+ DEBUG_IMX51_UART || \
+ DEBUG_IMX53_UART || \
+ DEBUG_IMX6Q_UART || \
+ DEBUG_IMX6SL_UART || \
+ DEBUG_IMX6SX_UART
+ default 1
+ depends on ARCH_MXC
+ help
+ Choose UART port on which kernel low-level debug messages
+ should be output.
+
+config DEBUG_VF_UART_PORT
+ int "Vybrid Debug UART Port Selection" if DEBUG_VF_UART
+ default 1
+ range 0 3
+ depends on SOC_VF610
+ help
+ Choose UART port on which kernel low-level debug messages
+ should be output.
+
+config DEBUG_TEGRA_UART
+ bool
+ depends on ARCH_TEGRA
+
+config DEBUG_STI_UART
+ bool
+ depends on ARCH_STI
+
+config DEBUG_SIRFSOC_UART
+ bool
+ depends on ARCH_SIRF
+
+config DEBUG_LL_INCLUDE
+ string
+ default "debug/sa1100.S" if DEBUG_SA1100
+ default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250
+ default "debug/at91.S" if DEBUG_AT91_UART
+ default "debug/asm9260.S" if DEBUG_ASM9260_UART
+ default "debug/clps711x.S" if DEBUG_CLPS711X_UART1 || DEBUG_CLPS711X_UART2
+ default "debug/meson.S" if DEBUG_MESON_UARTAO
+ default "debug/pl01x.S" if DEBUG_LL_UART_PL01X || DEBUG_UART_PL01X
+ default "debug/exynos.S" if DEBUG_EXYNOS_UART
+ default "debug/efm32.S" if DEBUG_LL_UART_EFM32
+ default "debug/icedcc.S" if DEBUG_ICEDCC
+ default "debug/imx.S" if DEBUG_IMX1_UART || \
+ DEBUG_IMX25_UART || \
+ DEBUG_IMX21_IMX27_UART || \
+ DEBUG_IMX31_UART || \
+ DEBUG_IMX35_UART || \
+ DEBUG_IMX50_UART || \
+ DEBUG_IMX51_UART || \
+ DEBUG_IMX53_UART ||\
+ DEBUG_IMX6Q_UART || \
+ DEBUG_IMX6SL_UART || \
+ DEBUG_IMX6SX_UART
+ default "debug/ks8695.S" if DEBUG_KS8695_UART
+ default "debug/msm.S" if DEBUG_QCOM_UARTDM
+ default "debug/netx.S" if DEBUG_NETX_UART
+ default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART
+ default "debug/renesas-scif.S" if DEBUG_R7S72100_SCIF2
+ default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF0
+ default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF2
+ default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF0
+ default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF2
+ default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA0
+ default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA1
+ default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA4
+ default "debug/s3c24xx.S" if DEBUG_S3C24XX_UART
+ default "debug/s5pv210.S" if DEBUG_S5PV210_UART
+ default "debug/sirf.S" if DEBUG_SIRFSOC_UART
+ default "debug/sti.S" if DEBUG_STI_UART
+ default "debug/tegra.S" if DEBUG_TEGRA_UART
+ default "debug/ux500.S" if DEBUG_UX500_UART
+ default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT
+ default "debug/vf.S" if DEBUG_VF_UART
+ default "debug/vt8500.S" if DEBUG_VT8500_UART0
+ default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1
+ default "debug/bcm63xx.S" if DEBUG_UART_BCM63XX
+ default "debug/digicolor.S" if DEBUG_DIGICOLOR_UA0
+ default "mach/debug-macro.S"
+
+# Compatibility options for PL01x
+config DEBUG_UART_PL01X
+ bool
+
+# Compatibility options for 8250
+config DEBUG_UART_8250
+ def_bool ARCH_DOVE || ARCH_EBSA110 || \
+ (FOOTBRIDGE && !DEBUG_DC21285_PORT) || \
+ ARCH_GEMINI || ARCH_IOP13XX || ARCH_IOP32X || \
+ ARCH_IOP33X || ARCH_IXP4XX || \
+ ARCH_LPC32XX || ARCH_MV78XX0 || ARCH_ORION5X || ARCH_RPC
+
+# Compatibility options for BCM63xx
+config DEBUG_UART_BCM63XX
+ def_bool ARCH_BCM_63XX
+
+config DEBUG_UART_PHYS
+ hex "Physical base address of debug UART"
+ default 0x00100a00 if DEBUG_NETX_UART
+ default 0x01c20000 if DEBUG_DAVINCI_DMx_UART0
+ default 0x01c28000 if DEBUG_SUNXI_UART0
+ default 0x01c28400 if DEBUG_SUNXI_UART1
+ default 0x01d0c000 if DEBUG_DAVINCI_DA8XX_UART1
+ default 0x01d0d000 if DEBUG_DAVINCI_DA8XX_UART2
+ default 0x01f02800 if DEBUG_SUNXI_R_UART
+ default 0x02530c00 if DEBUG_KEYSTONE_UART0
+ default 0x02531000 if DEBUG_KEYSTONE_UART1
+ default 0x03010fe0 if ARCH_RPC
+ default 0x07000000 if DEBUG_SUN9I_UART0
+ default 0x10009000 if DEBUG_REALVIEW_STD_PORT || \
+ DEBUG_VEXPRESS_UART0_CA9
+ default 0x1010c000 if DEBUG_REALVIEW_PB1176_PORT
+ default 0x10124000 if DEBUG_RK3X_UART0
+ default 0x10126000 if DEBUG_RK3X_UART1
+ default 0x101f1000 if ARCH_VERSATILE
+ default 0x101fb000 if DEBUG_NOMADIK_UART
+ default 0x11002000 if DEBUG_MT8127_UART0
+ default 0x11006000 if DEBUG_MT6589_UART0
+ default 0x11009000 if DEBUG_MT8135_UART3
+ default 0x16000000 if ARCH_INTEGRATOR
+ default 0x18000300 if DEBUG_BCM_5301X
+ default 0x18010000 if DEBUG_SIRFATLAS7_UART0
+ default 0x18020000 if DEBUG_SIRFATLAS7_UART1
+ default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1
+ default 0x20001000 if DEBUG_HIP01_UART
+ default 0x20060000 if DEBUG_RK29_UART0
+ default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
+ default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
+ default 0x20201000 if DEBUG_BCM2835
+ default 0x3e000000 if DEBUG_BCM_KONA_UART
+ default 0x4000e400 if DEBUG_LL_UART_EFM32
+ default 0x40090000 if ARCH_LPC32XX
+ default 0x40100000 if DEBUG_PXA_UART1
+ default 0x42000000 if ARCH_GEMINI
+ default 0x50000000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART0 || \
+ DEBUG_S3C2410_UART0)
+ default 0x50004000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART1 || \
+ DEBUG_S3C2410_UART1)
+ default 0x50008000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART2 || \
+ DEBUG_S3C2410_UART2)
+ default 0x78000000 if DEBUG_CNS3XXX
+ default 0x7c0003f8 if FOOTBRIDGE
+ default 0x80010000 if DEBUG_ASM9260_UART
+ default 0x80070000 if DEBUG_IMX23_UART
+ default 0x80074000 if DEBUG_IMX28_UART
+ default 0x80230000 if DEBUG_PICOXCELL_UART
+ default 0x808c0000 if ARCH_EP93XX
+ default 0x90020000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART
+ default 0xb0060000 if DEBUG_SIRFPRIMA2_UART1
+ default 0xb0090000 if DEBUG_VEXPRESS_UART0_CRX
+ default 0xc0013000 if DEBUG_U300_UART
+ default 0xc8000000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN
+ default 0xc8000003 if ARCH_IXP4XX && CPU_BIG_ENDIAN
+ default 0xd0000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX
+ default 0xd0012000 if DEBUG_MVEBU_UART0
+ default 0xc81004c0 if DEBUG_MESON_UARTAO
+ default 0xd4017000 if DEBUG_MMP_UART2
+ default 0xd4018000 if DEBUG_MMP_UART3
+ default 0xe0000000 if ARCH_SPEAR13XX
+ default 0xe4007000 if DEBUG_HIP04_UART
+ default 0xe6c40000 if DEBUG_RMOBILE_SCIFA0
+ default 0xe6c50000 if DEBUG_RMOBILE_SCIFA1
+ default 0xe6c80000 if DEBUG_RMOBILE_SCIFA4
+ default 0xe6e58000 if DEBUG_RCAR_GEN2_SCIF2
+ default 0xe6e60000 if DEBUG_RCAR_GEN2_SCIF0
+ default 0xe8008000 if DEBUG_R7S72100_SCIF2
+ default 0xf0000be0 if ARCH_EBSA110
+ default 0xf040ab00 if DEBUG_BRCMSTB_UART
+ default 0xf1012000 if DEBUG_MVEBU_UART0_ALTERNATE
+ default 0xf1012100 if DEBUG_MVEBU_UART1_ALTERNATE
+ default 0xf1012000 if ARCH_DOVE || ARCH_MV78XX0 || \
+ ARCH_ORION5X
+ default 0xf7fc9000 if DEBUG_BERLIN_UART
+ default 0xf8b00000 if DEBUG_HIX5HD2_UART
+ default 0xf991e000 if DEBUG_QCOM_UARTDM
+ default 0xfcb00000 if DEBUG_HI3620_UART
+ default 0xfd883000 if DEBUG_ALPINE_UART0
+ default 0xfe800000 if ARCH_IOP32X
+ default 0xff690000 if DEBUG_RK32_UART2
+ default 0xffc02000 if DEBUG_SOCFPGA_UART
+ default 0xffd82340 if ARCH_IOP13XX
+ default 0xffe40000 if DEBUG_RCAR_GEN1_SCIF0
+ default 0xffe42000 if DEBUG_RCAR_GEN1_SCIF2
+ default 0xfff36000 if DEBUG_HIGHBANK_UART
+ default 0xfffb0000 if DEBUG_OMAP1UART1 || DEBUG_OMAP7XXUART1
+ default 0xfffb0800 if DEBUG_OMAP1UART2 || DEBUG_OMAP7XXUART2
+ default 0xfffb9800 if DEBUG_OMAP1UART3 || DEBUG_OMAP7XXUART3
+ default 0xfffe8600 if DEBUG_UART_BCM63XX
+ default 0xfffff700 if ARCH_IOP33X
+ depends on ARCH_EP93XX || \
+ DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
+ DEBUG_LL_UART_EFM32 || \
+ DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
+ DEBUG_NETX_UART || \
+ DEBUG_QCOM_UARTDM || DEBUG_R7S72100_SCIF2 || \
+ DEBUG_RCAR_GEN1_SCIF0 || DEBUG_RCAR_GEN1_SCIF2 || \
+ DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF2 || \
+ DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \
+ DEBUG_RMOBILE_SCIFA4 || DEBUG_S3C24XX_UART || \
+ DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \
+ DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0
+
+config DEBUG_UART_VIRT
+ hex "Virtual base address of debug UART"
+ default 0xe0000a00 if DEBUG_NETX_UART
+ default 0xe0010fe0 if ARCH_RPC
+ default 0xf0000be0 if ARCH_EBSA110
+ default 0xf0010000 if DEBUG_ASM9260_UART
+ default 0xf01fb000 if DEBUG_NOMADIK_UART
+ default 0xf0201000 if DEBUG_BCM2835
+ default 0xf1000300 if DEBUG_BCM_5301X
+ default 0xf1002000 if DEBUG_MT8127_UART0
+ default 0xf1006000 if DEBUG_MT6589_UART0
+ default 0xf1009000 if DEBUG_MT8135_UART3
+ default 0xf11f1000 if ARCH_VERSATILE
+ default 0xf1600000 if ARCH_INTEGRATOR
+ default 0xf1c28000 if DEBUG_SUNXI_UART0
+ default 0xf1c28400 if DEBUG_SUNXI_UART1
+ default 0xf1f02800 if DEBUG_SUNXI_R_UART
+ default 0xf6200000 if DEBUG_PXA_UART1
+ default 0xf4090000 if ARCH_LPC32XX
+ default 0xf4200000 if ARCH_GEMINI
+ default 0xf7000000 if DEBUG_SUN9I_UART0
+ default 0xf7000000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART0 || \
+ DEBUG_S3C2410_UART0)
+ default 0xf7004000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART1 || \
+ DEBUG_S3C2410_UART1)
+ default 0xf7008000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART2 || \
+ DEBUG_S3C2410_UART2)
+ default 0xf7fc9000 if DEBUG_BERLIN_UART
+ default 0xf8007000 if DEBUG_HIP04_UART
+ default 0xf8009000 if DEBUG_VEXPRESS_UART0_CA9
+ default 0xf8090000 if DEBUG_VEXPRESS_UART0_RS1
+ default 0xfa71e000 if DEBUG_QCOM_UARTDM
+ default 0xfb002000 if DEBUG_CNS3XXX
+ default 0xfb009000 if DEBUG_REALVIEW_STD_PORT
+ default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT
+ default 0xfc40ab00 if DEBUG_BRCMSTB_UART
+ default 0xfcfe8600 if DEBUG_UART_BCM63XX
+ default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX
+ default 0xfd000000 if ARCH_SPEAR13XX
+ default 0xfd012000 if ARCH_MV78XX0
+ default 0xfd883000 if DEBUG_ALPINE_UART0
+ default 0xfde12000 if ARCH_DOVE
+ default 0xfe012000 if ARCH_ORION5X
+ default 0xf31004c0 if DEBUG_MESON_UARTAO
+ default 0xfe017000 if DEBUG_MMP_UART2
+ default 0xfe018000 if DEBUG_MMP_UART3
+ default 0xfe100000 if DEBUG_IMX23_UART || DEBUG_IMX28_UART
+ default 0xfe230000 if DEBUG_PICOXCELL_UART
+ default 0xfe300000 if DEBUG_BCM_KONA_UART
+ default 0xfe800000 if ARCH_IOP32X
+ default 0xfeb00000 if DEBUG_HI3620_UART || DEBUG_HIX5HD2_UART
+ default 0xfeb24000 if DEBUG_RK3X_UART0
+ default 0xfeb26000 if DEBUG_RK3X_UART1
+ default 0xfeb30c00 if DEBUG_KEYSTONE_UART0
+ default 0xfeb31000 if DEBUG_KEYSTONE_UART1
+ default 0xfec02000 if DEBUG_SOCFPGA_UART
+ default 0xfec12000 if DEBUG_MVEBU_UART0 || DEBUG_MVEBU_UART0_ALTERNATE
+ default 0xfec12100 if DEBUG_MVEBU_UART1_ALTERNATE
+ default 0xfec10000 if DEBUG_SIRFATLAS7_UART0
+ default 0xfec20000 if DEBUG_DAVINCI_DMx_UART0
+ default 0xfec20000 if DEBUG_SIRFATLAS7_UART1
+ default 0xfec60000 if DEBUG_SIRFPRIMA2_UART1
+ default 0xfec90000 if DEBUG_RK32_UART2
+ default 0xfed0c000 if DEBUG_DAVINCI_DA8XX_UART1
+ default 0xfed0d000 if DEBUG_DAVINCI_DA8XX_UART2
+ default 0xfed60000 if DEBUG_RK29_UART0
+ default 0xfed64000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
+ default 0xfed68000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
+ default 0xfedc0000 if ARCH_EP93XX
+ default 0xfee003f8 if FOOTBRIDGE
+ default 0xfee20000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART
+ default 0xfee82340 if ARCH_IOP13XX
+ default 0xfef00000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN
+ default 0xfef00003 if ARCH_IXP4XX && CPU_BIG_ENDIAN
+ default 0xfef36000 if DEBUG_HIGHBANK_UART
+ default 0xfefb0000 if DEBUG_OMAP1UART1 || DEBUG_OMAP7XXUART1
+ default 0xfefb0800 if DEBUG_OMAP1UART2 || DEBUG_OMAP7XXUART2
+ default 0xfefb9800 if DEBUG_OMAP1UART3 || DEBUG_OMAP7XXUART3
+ default 0xfefff700 if ARCH_IOP33X
+ default 0xff003000 if DEBUG_U300_UART
+ default 0xffd01000 if DEBUG_HIP01_UART
+ default DEBUG_UART_PHYS if !MMU
+ depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
+ DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
+ DEBUG_NETX_UART || \
+ DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \
+ DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \
+ DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0
+
+config DEBUG_UART_8250_SHIFT
+ int "Register offset shift for the 8250 debug UART"
+ depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
+ default 0 if FOOTBRIDGE || ARCH_IOP32X || DEBUG_BCM_5301X || \
+ DEBUG_OMAP7XXUART1 || DEBUG_OMAP7XXUART2 || DEBUG_OMAP7XXUART3
+ default 2
+
+config DEBUG_UART_8250_WORD
+ bool "Use 32-bit accesses for 8250 UART"
+ depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
+ depends on DEBUG_UART_8250_SHIFT >= 2
+ default y if DEBUG_PICOXCELL_UART || DEBUG_SOCFPGA_UART || \
+ ARCH_KEYSTONE || DEBUG_ALPINE_UART0 || \
+ DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \
+ DEBUG_DAVINCI_DA8XX_UART2 || \
+ DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2 || \
+ DEBUG_BRCMSTB_UART
+
+config DEBUG_UART_8250_FLOW_CONTROL
+ bool "Enable flow control for 8250 UART"
+ depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
+ default y if ARCH_EBSA110 || FOOTBRIDGE || ARCH_GEMINI || ARCH_RPC
+
+config DEBUG_UNCOMPRESS
+ bool
+ depends on ARCH_MULTIPLATFORM || PLAT_SAMSUNG
+ default y if DEBUG_LL && !DEBUG_OMAP2PLUS_UART && \
+ (!DEBUG_TEGRA_UART || !ZBOOT_ROM)
+ help
+ This option influences the normal decompressor output for
+ multiplatform kernels. Normally, multiplatform kernels disable
+ decompressor output because it is not possible to know where to
+ send the decompressor output.
+
+ When this option is set, the selected DEBUG_LL output method
+ will be re-used for normal decompressor output on multiplatform
+ kernels.
+
+
+config UNCOMPRESS_INCLUDE
+ string
+ default "debug/uncompress.h" if ARCH_MULTIPLATFORM || ARCH_MSM || \
+ PLAT_SAMSUNG || ARCH_EFM32 || \
+ ARCH_SHMOBILE_LEGACY
+ default "mach/uncompress.h"
+
+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 ARM_KPROBES_TEST
+ tristate "Kprobes test module"
+ depends on KPROBES && MODULES
+ help
+ Perform tests of kprobes API and instruction set simulation.
+
+config PID_IN_CONTEXTIDR
+ bool "Write the current PID to the CONTEXTIDR register"
+ depends on CPU_COPY_V6
+ help
+ Enabling this option causes the kernel to write the current PID to
+ the PROCID field of the CONTEXTIDR register, at the expense of some
+ additional instructions during context switch. Say Y here only if you
+ are planning to use hardware trace tools with this kernel.
+
+config DEBUG_SET_MODULE_RONX
+ bool "Set loadable kernel module data as NX and text as RO"
+ depends on MODULES
+ ---help---
+ This option helps catch unintended modifications to loadable
+ kernel module's text and read-only data. It also prevents execution
+ of module data. Such protection may interfere with run-time code
+ patching and dynamic kernel tracing - and they might also protect
+ against certain classes of kernel exploits.
+ If in doubt, say "N".
+
+source "drivers/hwtracing/coresight/Kconfig"
+
+endmenu
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
new file mode 100644
index 000000000..985227cbb
--- /dev/null
+++ b/arch/arm/Makefile
@@ -0,0 +1,355 @@
+#
+# 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
+
+# Ensure linker flags are correct
+LDFLAGS :=
+
+LDFLAGS_vmlinux :=-p --no-undefined -X --pic-veneer
+ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
+LDFLAGS_vmlinux += --be8
+LDFLAGS_MODULE += --be8
+endif
+
+OBJCOPYFLAGS :=-O binary -R .comment -S
+GZFLAGS :=-9
+#KBUILD_CFLAGS +=-pipe
+
+# 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
+KBUILD_CFLAGS += $(call cc-option,-mno-unaligned-access)
+endif
+
+ifeq ($(CONFIG_FRAME_POINTER),y)
+KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
+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
+
+# 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_32v7M) =-D__LINUX_ARM_ARCH__=7 -march=armv7-m -Wa,-march=armv7-m
+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
+
+# Evaluate arch cc-option calls now
+arch-y := $(arch-y)
+
+# This selects how we optimise for the processor.
+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)
+
+# Evaluate tune cc-option calls now
+tune-y := $(tune-y)
+
+ifeq ($(CONFIG_AEABI),y)
+CFLAGS_ABI :=-mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp
+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_ISA :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN)
+AFLAGS_ISA :=$(CFLAGS_ISA) -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
+else
+CFLAGS_ISA :=$(call cc-option,-marm,)
+AFLAGS_ISA :=$(CFLAGS_ISA)
+endif
+
+# Need -Uarm for gcc < 3.x
+KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
+KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
+
+CHECKFLAGS += -D__arm__
+
+#Default value
+head-y := arch/arm/kernel/head$(MMUEXT).o
+
+# Text offset. This list is sorted numerically by address in order to
+# provide a means to avoid/resolve conflicts in multi-arch kernels.
+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
+textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
+textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
+textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
+
+# Machine directory name. This list is sorted alphanumerically
+# by CONFIG_* macro name.
+machine-$(CONFIG_ARCH_ALPINE) += alpine
+machine-$(CONFIG_ARCH_AT91) += at91
+machine-$(CONFIG_ARCH_AXXIA) += axxia
+machine-$(CONFIG_ARCH_BCM) += bcm
+machine-$(CONFIG_ARCH_BERLIN) += berlin
+machine-$(CONFIG_ARCH_CLPS711X) += clps711x
+machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx
+machine-$(CONFIG_ARCH_DAVINCI) += davinci
+machine-$(CONFIG_ARCH_DIGICOLOR) += digicolor
+machine-$(CONFIG_ARCH_DOVE) += dove
+machine-$(CONFIG_ARCH_EBSA110) += ebsa110
+machine-$(CONFIG_ARCH_EFM32) += efm32
+machine-$(CONFIG_ARCH_EP93XX) += ep93xx
+machine-$(CONFIG_ARCH_EXYNOS) += exynos
+machine-$(CONFIG_ARCH_FOOTBRIDGE) += footbridge
+machine-$(CONFIG_ARCH_GEMINI) += gemini
+machine-$(CONFIG_ARCH_HIGHBANK) += highbank
+machine-$(CONFIG_ARCH_HISI) += hisi
+machine-$(CONFIG_ARCH_INTEGRATOR) += integrator
+machine-$(CONFIG_ARCH_IOP13XX) += iop13xx
+machine-$(CONFIG_ARCH_IOP32X) += iop32x
+machine-$(CONFIG_ARCH_IOP33X) += iop33x
+machine-$(CONFIG_ARCH_IXP4XX) += ixp4xx
+machine-$(CONFIG_ARCH_KEYSTONE) += keystone
+machine-$(CONFIG_ARCH_KS8695) += ks8695
+machine-$(CONFIG_ARCH_LPC32XX) += lpc32xx
+machine-$(CONFIG_ARCH_MESON) += meson
+machine-$(CONFIG_ARCH_MMP) += mmp
+machine-$(CONFIG_ARCH_MOXART) += moxart
+machine-$(CONFIG_ARCH_MV78XX0) += mv78xx0
+machine-$(CONFIG_ARCH_MVEBU) += mvebu
+machine-$(CONFIG_ARCH_MXC) += imx
+machine-$(CONFIG_ARCH_MEDIATEK) += mediatek
+machine-$(CONFIG_ARCH_MXS) += mxs
+machine-$(CONFIG_ARCH_NETX) += netx
+machine-$(CONFIG_ARCH_NOMADIK) += nomadik
+machine-$(CONFIG_ARCH_NSPIRE) += nspire
+machine-$(CONFIG_ARCH_OMAP1) += omap1
+machine-$(CONFIG_ARCH_OMAP2PLUS) += omap2
+machine-$(CONFIG_ARCH_ORION5X) += orion5x
+machine-$(CONFIG_ARCH_PICOXCELL) += picoxcell
+machine-$(CONFIG_ARCH_PXA) += pxa
+machine-$(CONFIG_ARCH_QCOM) += qcom
+machine-$(CONFIG_ARCH_REALVIEW) += realview
+machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip
+machine-$(CONFIG_ARCH_RPC) += rpc
+machine-$(CONFIG_ARCH_S3C24XX) += s3c24xx
+machine-$(CONFIG_ARCH_S3C64XX) += s3c64xx
+machine-$(CONFIG_ARCH_S5PV210) += s5pv210
+machine-$(CONFIG_ARCH_SA1100) += sa1100
+machine-$(CONFIG_ARCH_SHMOBILE) += shmobile
+machine-$(CONFIG_ARCH_SIRF) += prima2
+machine-$(CONFIG_ARCH_SOCFPGA) += socfpga
+machine-$(CONFIG_ARCH_STI) += sti
+machine-$(CONFIG_ARCH_SUNXI) += sunxi
+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_ZYNQ) += zynq
+machine-$(CONFIG_PLAT_SPEAR) += spear
+
+# Platform directory name. This list is sorted alphanumerically
+# by CONFIG_* macro name.
+plat-$(CONFIG_ARCH_EXYNOS) += samsung
+plat-$(CONFIG_ARCH_OMAP) += omap
+plat-$(CONFIG_ARCH_S3C64XX) += samsung
+plat-$(CONFIG_ARCH_S5PV210) += samsung
+plat-$(CONFIG_PLAT_IOP) += iop
+plat-$(CONFIG_PLAT_ORION) += orion
+plat-$(CONFIG_PLAT_PXA) += pxa
+plat-$(CONFIG_PLAT_S3C24XX) += samsung
+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
+ifeq ($(CONFIG_ARCH_MULTIPLATFORM),y)
+MACHINE :=
+endif
+
+machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
+platdirs := $(patsubst %,arch/arm/plat-%/,$(sort $(plat-y)))
+
+ifneq ($(CONFIG_ARCH_MULTIPLATFORM),y)
+ifeq ($(KBUILD_SRC),)
+KBUILD_CPPFLAGS += $(patsubst %,-I%include,$(machdirs) $(platdirs))
+else
+KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs) $(platdirs))
+endif
+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/
+core-$(CONFIG_XEN) += arch/arm/xen/
+core-$(CONFIG_KVM_ARM_HOST) += arch/arm/kvm/
+core-$(CONFIG_VDSO) += arch/arm/vdso/
+
+# 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 += arch/arm/probes/
+core-y += arch/arm/net/
+core-y += arch/arm/crypto/
+core-y += arch/arm/firmware/
+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
+
+# Build the DT binary blobs if we have OF configured
+ifeq ($(CONFIG_USE_OF),y)
+KBUILD_DTBS := dtbs
+endif
+
+all: $(KBUILD_IMAGE) $(KBUILD_DTBS)
+
+boot := arch/arm/boot
+
+archprepare:
+ $(Q)$(MAKE) $(build)=arch/arm/tools include/generated/mach-types.h
+
+# Convert bzImage to zImage
+bzImage: zImage
+
+BOOT_TARGETS = zImage Image xipImage bootpImage uImage
+INSTALL_TARGETS = zinstall uinstall install
+
+PHONY += bzImage $(BOOT_TARGETS) $(INSTALL_TARGETS)
+
+$(BOOT_TARGETS): vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+
+$(INSTALL_TARGETS):
+ $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
+
+%.dtb: | scripts
+ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@
+
+PHONY += dtbs dtbs_install
+
+dtbs: prepare scripts
+ $(Q)$(MAKE) $(build)=$(boot)/dts
+
+dtbs_install:
+ $(Q)$(MAKE) $(dtbinst)=$(boot)/dts
+
+PHONY += vdso_install
+vdso_install:
+ifeq ($(CONFIG_VDSO),y)
+ $(Q)$(MAKE) $(build)=arch/arm/vdso $@
+endif
+
+# 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 '* dtbs - Build device tree blobs for enabled boards'
+ echo ' dtbs_install - Install dtbs to $(INSTALL_DTBS_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'
+ echo ' vdso_install - Install unstripped vdso.so to $$(INSTALL_MOD_PATH)/vdso'
+endef
diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore
new file mode 100644
index 000000000..3c79f8597
--- /dev/null
+++ b/arch/arm/boot/.gitignore
@@ -0,0 +1,6 @@
+Image
+zImage
+xipImage
+bootpImage
+uImage
+*.dtb
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
new file mode 100644
index 000000000..9eca7aee9
--- /dev/null
+++ b/arch/arm/boot/Makefile
@@ -0,0 +1,118 @@
+#
+# 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
+#
+
+ifneq ($(MACHINE),)
+include $(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)
+ @$(kecho) ' 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)
+ @$(kecho) ' Kernel: $@ is ready'
+
+$(obj)/compressed/vmlinux: $(obj)/Image FORCE
+ $(Q)$(MAKE) $(build)=$(obj)/compressed $@
+
+$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
+ $(call if_changed,objcopy)
+ @$(kecho) ' Kernel: $@ is ready'
+
+endif
+
+ifneq ($(LOADADDR),)
+ UIMAGE_LOADADDR=$(LOADADDR)
+else
+ ifeq ($(CONFIG_ZBOOT_ROM),y)
+ UIMAGE_LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT)
+ else
+ UIMAGE_LOADADDR=$(ZRELADDR)
+ endif
+endif
+
+check_for_multiple_loadaddr = \
+if [ $(words $(UIMAGE_LOADADDR)) -ne 1 ]; then \
+ echo 'multiple (or no) load addresses: $(UIMAGE_LOADADDR)'; \
+ echo 'This is incompatible with uImages'; \
+ echo 'Specify LOADADDR on the commandline to build an uImage'; \
+ false; \
+fi
+
+$(obj)/uImage: $(obj)/zImage FORCE
+ @$(check_for_multiple_loadaddr)
+ $(call if_changed,uimage)
+ @$(kecho) ' 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)
+ @$(kecho) ' 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:
+ $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \
+ $(obj)/Image System.map "$(INSTALL_PATH)"
+
+zinstall:
+ $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \
+ $(obj)/zImage System.map "$(INSTALL_PATH)"
+
+uinstall:
+ $(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 dts
diff --git a/arch/arm/boot/bootp/Makefile b/arch/arm/boot/bootp/Makefile
new file mode 100644
index 000000000..5761f0039
--- /dev/null
+++ b/arch/arm/boot/bootp/Makefile
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+GCOV_PROFILE := n
+
+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 000000000..fc54394f4
--- /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 000000000..78b508075
--- /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 000000000..d81ea1837
--- /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 000000000..b87a25c7e
--- /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 000000000..0714e0334
--- /dev/null
+++ b/arch/arm/boot/compressed/.gitignore
@@ -0,0 +1,21 @@
+ashldi3.S
+bswapsdi2.S
+font.c
+lib1funcs.S
+hyp-stub.S
+piggy.gzip
+piggy.lzo
+piggy.lzma
+piggy.xzkern
+piggy.lz4
+vmlinux
+vmlinux.lds
+
+# borrowed libfdt files
+fdt.c
+fdt.h
+fdt_ro.c
+fdt_rw.c
+fdt_wip.c
+libfdt.h
+libfdt_internal.h
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
new file mode 100644
index 000000000..6e1fb2b2e
--- /dev/null
+++ b/arch/arm/boot/compressed/Makefile
@@ -0,0 +1,190 @@
+#
+# linux/arch/arm/boot/compressed/Makefile
+#
+# create a compressed vmlinuz image from the original vmlinux
+#
+
+OBJS =
+
+AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
+HEAD = head.o
+OBJS += misc.o decompress.o
+ifeq ($(CONFIG_DEBUG_UNCOMPRESS),y)
+OBJS += debug.o
+endif
+FONTC = $(srctree)/lib/fonts/font_acorn_8x8.c
+
+# string library code (-Os is enforced to keep it much smaller)
+OBJS += string.o
+CFLAGS_string.o := -Os
+
+ifeq ($(CONFIG_ARM_VIRT_EXT),y)
+OBJS += hyp-stub.o
+endif
+
+GCOV_PROFILE := n
+
+#
+# Architecture dependencies
+#
+ifeq ($(CONFIG_ARCH_ACORN),y)
+OBJS += ll_char_wr.o font.o
+endif
+
+ifeq ($(CONFIG_ARCH_SA1100),y)
+OBJS += head-sa1100.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_LEGACY),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
+
+CPPFLAGS_vmlinux.lds := -DTEXT_START="$(ZTEXTADDR)" -DBSS_START="$(ZBSSADDR)"
+
+suffix_$(CONFIG_KERNEL_GZIP) = gzip
+suffix_$(CONFIG_KERNEL_LZO) = lzo
+suffix_$(CONFIG_KERNEL_LZMA) = lzma
+suffix_$(CONFIG_KERNEL_XZ) = xzkern
+suffix_$(CONFIG_KERNEL_LZ4) = lz4
+
+# Borrowed libfdt files for the ATAG compatibility mode
+
+libfdt := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c
+libfdt_hdrs := fdt.h libfdt.h libfdt_internal.h
+
+libfdt_objs := $(addsuffix .o, $(basename $(libfdt)))
+
+$(addprefix $(obj)/,$(libfdt) $(libfdt_hdrs)): $(obj)/%: $(srctree)/scripts/dtc/libfdt/%
+ $(call cmd,shipped)
+
+$(addprefix $(obj)/,$(libfdt_objs) atags_to_fdt.o): \
+ $(addprefix $(obj)/,$(libfdt_hdrs))
+
+ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y)
+OBJS += $(libfdt_objs) atags_to_fdt.o
+endif
+
+targets := vmlinux vmlinux.lds \
+ piggy.$(suffix_y) piggy.$(suffix_y).o \
+ lib1funcs.o lib1funcs.S ashldi3.o ashldi3.S bswapsdi2.o \
+ bswapsdi2.S font.o font.c head.o misc.o $(OBJS)
+
+# Make sure files are removed during clean
+extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern piggy.lz4 \
+ lib1funcs.S ashldi3.S bswapsdi2.S $(libfdt) $(libfdt_hdrs) \
+ hyp-stub.S
+
+ifeq ($(CONFIG_FUNCTION_TRACER),y)
+ORIG_CFLAGS := $(KBUILD_CFLAGS)
+KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
+endif
+
+ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj)
+asflags-y := -DZIMAGE
+
+# Supply kernel BSS size to the decompressor via a linker symbol.
+KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \
+ awk 'END{print $$3}')
+LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
+# 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
+ $(call cmd,shipped)
+
+# For __aeabi_llsl
+ashldi3 = $(obj)/ashldi3.o
+
+$(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S
+ $(call cmd,shipped)
+
+# For __bswapsi2, __bswapdi2
+bswapsdi2 = $(obj)/bswapsdi2.o
+
+$(obj)/bswapsdi2.S: $(srctree)/arch/$(SRCARCH)/lib/bswapsdi2.S
+ $(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 )
+
+check_for_multiple_zreladdr = \
+if [ $(words $(ZRELADDR)) -gt 1 -a "$(CONFIG_AUTO_ZRELADDR)" = "" ]; then \
+ echo 'multiple zreladdrs: $(ZRELADDR)'; \
+ echo 'This needs CONFIG_AUTO_ZRELADDR to be set'; \
+ false; \
+fi
+
+$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
+ $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) \
+ $(bswapsdi2) FORCE
+ @$(check_for_multiple_zreladdr)
+ $(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)/hyp-stub.S: $(srctree)/arch/$(SRCARCH)/kernel/hyp-stub.S
+ $(call cmd,shipped)
diff --git a/arch/arm/boot/compressed/atags_to_fdt.c b/arch/arm/boot/compressed/atags_to_fdt.c
new file mode 100644
index 000000000..9448aa0c6
--- /dev/null
+++ b/arch/arm/boot/compressed/atags_to_fdt.c
@@ -0,0 +1,191 @@
+#include <asm/setup.h>
+#include <libfdt.h>
+
+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND)
+#define do_extend_cmdline 1
+#else
+#define do_extend_cmdline 0
+#endif
+
+#define NR_BANKS 16
+
+static int node_offset(void *fdt, const char *node_path)
+{
+ int offset = fdt_path_offset(fdt, node_path);
+ if (offset == -FDT_ERR_NOTFOUND)
+ offset = fdt_add_subnode(fdt, 0, node_path);
+ return offset;
+}
+
+static int setprop(void *fdt, const char *node_path, const char *property,
+ uint32_t *val_array, int size)
+{
+ int offset = node_offset(fdt, node_path);
+ if (offset < 0)
+ return offset;
+ return fdt_setprop(fdt, offset, property, val_array, size);
+}
+
+static int setprop_string(void *fdt, const char *node_path,
+ const char *property, const char *string)
+{
+ int offset = node_offset(fdt, node_path);
+ if (offset < 0)
+ return offset;
+ return fdt_setprop_string(fdt, offset, property, string);
+}
+
+static int setprop_cell(void *fdt, const char *node_path,
+ const char *property, uint32_t val)
+{
+ int offset = node_offset(fdt, node_path);
+ if (offset < 0)
+ return offset;
+ return fdt_setprop_cell(fdt, offset, property, val);
+}
+
+static const void *getprop(const void *fdt, const char *node_path,
+ const char *property, int *len)
+{
+ int offset = fdt_path_offset(fdt, node_path);
+
+ if (offset == -FDT_ERR_NOTFOUND)
+ return NULL;
+
+ return fdt_getprop(fdt, offset, property, len);
+}
+
+static uint32_t get_cell_size(const void *fdt)
+{
+ int len;
+ uint32_t cell_size = 1;
+ const uint32_t *size_len = getprop(fdt, "/", "#size-cells", &len);
+
+ if (size_len)
+ cell_size = fdt32_to_cpu(*size_len);
+ return cell_size;
+}
+
+static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
+{
+ char cmdline[COMMAND_LINE_SIZE];
+ const char *fdt_bootargs;
+ char *ptr = cmdline;
+ int len = 0;
+
+ /* copy the fdt command line into the buffer */
+ fdt_bootargs = getprop(fdt, "/chosen", "bootargs", &len);
+ if (fdt_bootargs)
+ if (len < COMMAND_LINE_SIZE) {
+ memcpy(ptr, fdt_bootargs, len);
+ /* len is the length of the string
+ * including the NULL terminator */
+ ptr += len - 1;
+ }
+
+ /* and append the ATAG_CMDLINE */
+ if (fdt_cmdline) {
+ len = strlen(fdt_cmdline);
+ if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
+ *ptr++ = ' ';
+ memcpy(ptr, fdt_cmdline, len);
+ ptr += len;
+ }
+ }
+ *ptr = '\0';
+
+ setprop_string(fdt, "/chosen", "bootargs", cmdline);
+}
+
+/*
+ * Convert and fold provided ATAGs into the provided FDT.
+ *
+ * REturn values:
+ * = 0 -> pretend success
+ * = 1 -> bad ATAG (may retry with another possible ATAG pointer)
+ * < 0 -> error from libfdt
+ */
+int atags_to_fdt(void *atag_list, void *fdt, int total_space)
+{
+ struct tag *atag = atag_list;
+ /* In the case of 64 bits memory size, need to reserve 2 cells for
+ * address and size for each bank */
+ uint32_t mem_reg_property[2 * 2 * NR_BANKS];
+ int memcount = 0;
+ int ret, memsize;
+
+ /* make sure we've got an aligned pointer */
+ if ((u32)atag_list & 0x3)
+ return 1;
+
+ /* if we get a DTB here we're done already */
+ if (*(u32 *)atag_list == fdt32_to_cpu(FDT_MAGIC))
+ return 0;
+
+ /* validate the ATAG */
+ if (atag->hdr.tag != ATAG_CORE ||
+ (atag->hdr.size != tag_size(tag_core) &&
+ atag->hdr.size != 2))
+ return 1;
+
+ /* let's give it all the room it could need */
+ ret = fdt_open_into(fdt, fdt, total_space);
+ if (ret < 0)
+ return ret;
+
+ for_each_tag(atag, atag_list) {
+ if (atag->hdr.tag == ATAG_CMDLINE) {
+ /* Append the ATAGS command line to the device tree
+ * command line.
+ * NB: This means that if the same parameter is set in
+ * the device tree and in the tags, the one from the
+ * tags will be chosen.
+ */
+ if (do_extend_cmdline)
+ merge_fdt_bootargs(fdt,
+ atag->u.cmdline.cmdline);
+ else
+ setprop_string(fdt, "/chosen", "bootargs",
+ atag->u.cmdline.cmdline);
+ } else if (atag->hdr.tag == ATAG_MEM) {
+ if (memcount >= sizeof(mem_reg_property)/4)
+ continue;
+ if (!atag->u.mem.size)
+ continue;
+ memsize = get_cell_size(fdt);
+
+ if (memsize == 2) {
+ /* if memsize is 2, that means that
+ * each data needs 2 cells of 32 bits,
+ * so the data are 64 bits */
+ uint64_t *mem_reg_prop64 =
+ (uint64_t *)mem_reg_property;
+ mem_reg_prop64[memcount++] =
+ cpu_to_fdt64(atag->u.mem.start);
+ mem_reg_prop64[memcount++] =
+ cpu_to_fdt64(atag->u.mem.size);
+ } else {
+ mem_reg_property[memcount++] =
+ cpu_to_fdt32(atag->u.mem.start);
+ mem_reg_property[memcount++] =
+ cpu_to_fdt32(atag->u.mem.size);
+ }
+
+ } else if (atag->hdr.tag == ATAG_INITRD2) {
+ uint32_t initrd_start, initrd_size;
+ initrd_start = atag->u.initrd.start;
+ initrd_size = atag->u.initrd.size;
+ setprop_cell(fdt, "/chosen", "linux,initrd-start",
+ initrd_start);
+ setprop_cell(fdt, "/chosen", "linux,initrd-end",
+ initrd_start + initrd_size);
+ }
+ }
+
+ if (memcount) {
+ setprop(fdt, "/memory", "reg", mem_reg_property,
+ 4 * memcount * memsize);
+ }
+
+ return fdt_pack(fdt);
+}
diff --git a/arch/arm/boot/compressed/big-endian.S b/arch/arm/boot/compressed/big-endian.S
new file mode 100644
index 000000000..25ab26f1c
--- /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/debug.S b/arch/arm/boot/compressed/debug.S
new file mode 100644
index 000000000..5392ee633
--- /dev/null
+++ b/arch/arm/boot/compressed/debug.S
@@ -0,0 +1,40 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+#ifndef CONFIG_DEBUG_SEMIHOSTING
+
+#include CONFIG_DEBUG_LL_INCLUDE
+
+ENTRY(putc)
+ addruart r1, r2, r3
+ waituart r3, r1
+ senduart r0, r1
+ busyuart r3, r1
+ mov pc, lr
+ENDPROC(putc)
+
+#else
+
+ENTRY(putc)
+ adr r1, 1f
+ ldmia r1, {r2, r3}
+ add r2, r2, r1
+ ldr r1, [r2, r3]
+ strb r0, [r1]
+ mov r0, #0x03 @ SYS_WRITEC
+ ARM( svc #0x123456 )
+ THUMB( svc #0xab )
+ mov pc, lr
+ .align 2
+1: .word _GLOBAL_OFFSET_TABLE_ - .
+ .word semi_writec_buf(GOT)
+ENDPROC(putc)
+
+ .bss
+ .global semi_writec_buf
+ .type semi_writec_buf, %object
+semi_writec_buf:
+ .space 4
+ .size semi_writec_buf, 4
+
+#endif
diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c
new file mode 100644
index 000000000..bd245d349
--- /dev/null
+++ b/arch/arm/boot/compressed/decompress.c
@@ -0,0 +1,61 @@
+#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 */
+
+/* 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
+
+/* Not needed, but used in some headers pulled in by decompressors */
+extern char * strstr(const char * s1, const char *s2);
+
+#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
+
+#ifdef CONFIG_KERNEL_XZ
+#define memmove memmove
+#define memcpy memcpy
+#include "../../../../lib/decompress_unxz.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZ4
+#include "../../../../lib/decompress_unlz4.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 000000000..3115e313d
--- /dev/null
+++ b/arch/arm/boot/compressed/head-sa1100.S
@@ -0,0 +1,48 @@
+/*
+ * 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"
+ .arch armv4
+
+__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-sharpsl.S b/arch/arm/boot/compressed/head-sharpsl.S
new file mode 100644
index 000000000..eb0084ea1
--- /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 000000000..22a75259f
--- /dev/null
+++ b/arch/arm/boot/compressed/head-shmobile.S
@@ -0,0 +1,71 @@
+/*
+ * 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>
+
+ adr r0, dtb_info
+ ldmia r0, {r1, r3, r4, r5, r7}
+
+ sub r0, r0, r1 @ calculate the delta offset
+ add r5, r5, r0 @ _edata
+
+ ldr lr, [r5, #0] @ check if valid DTB is present
+ cmp lr, r3
+ bne 0f
+
+ add r9, r7, #31 @ rounded up to a multiple
+ bic r9, r9, #31 @ ... of 32 bytes
+
+ add r6, r9, r5 @ copy from _edata
+ add r9, r9, r4 @ to MEMORY_START
+
+1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
+ cmp r6, r5
+ stmdb r9!, {r0 - r3, r10 - r12, lr}
+ bhi 1b
+
+ /* Success: Zero board ID, pointer to start of memory for atag/dtb */
+ mov r7, #0
+ mov r8, r4
+ b 2f
+
+ .align 2
+dtb_info:
+ .word dtb_info
+#ifndef __ARMEB__
+ .word 0xedfe0dd0 @ sig is 0xd00dfeed big endian
+#else
+ .word 0xd00dfeed
+#endif
+ .word MEMORY_START
+ .word _edata
+ .word 0x4000 @ maximum DTB size
+0:
+ /* Failure: Zero board ID, NULL atag/dtb */
+ mov r7, #0
+ mov r8, #0 @ pass null pointer as atag
+2 :
+
+#endif /* CONFIG_ZBOOT_ROM */
diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S
new file mode 100644
index 000000000..6ab0599c0
--- /dev/null
+++ b/arch/arm/boot/compressed/head-xscale.S
@@ -0,0 +1,34 @@
+/*
+ * 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
+
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
new file mode 100644
index 000000000..2c45b5709
--- /dev/null
+++ b/arch/arm/boot/compressed/head.S
@@ -0,0 +1,1359 @@
+/*
+ * 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>
+#include <asm/assembler.h>
+#include <asm/v7m.h>
+
+ AR_CLASS( .arch armv7-a )
+ M_CLASS( .arch armv7-m )
+
+/*
+ * 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 CONFIG_DEBUG_LL_INCLUDE
+
+ .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
+#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
+ /*
+ * Always enter in ARM state for CPUs that support the ARM ISA.
+ * As of today (2014) that's exactly the members of the A and R
+ * classes.
+ */
+ AR_CLASS( .arm )
+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 _magic_sig @ Magic numbers to help the loader
+ .word _magic_start @ absolute load/run zImage address
+ .word _magic_end @ zImage end address
+ .word 0x04030201 @ endianness flag
+
+ THUMB( .thumb )
+1:
+ ARM_BE8( setend be ) @ go BE8 if compiled for BE8
+ AR_CLASS( mrs r9, cpsr )
+#ifdef CONFIG_ARM_VIRT_EXT
+ bl __hyp_stub_install @ get into SVC mode, reversibly
+#endif
+ mov r7, r1 @ save architecture ID
+ mov r8, r2 @ save atags pointer
+
+#ifndef CONFIG_CPU_V7M
+ /*
+ * 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:
+ safe_svcmode_maskall r0
+ msr spsr_cxsf, r9 @ Save the CPU boot mode in
+ @ SPSR
+#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
+ /*
+ * Find the start of physical memory. As we are executing
+ * without the MMU on, we are in the physical address space.
+ * We just need to get rid of any offset by aligning the
+ * address.
+ *
+ * This alignment is a balance between the requirements of
+ * different platforms - we have chosen 128MB to allow
+ * platforms which align the start of their physical memory
+ * to 128MB to use this feature, while allowing the zImage
+ * to be placed within the first 128MB of memory on other
+ * platforms. Increasing the alignment means we place
+ * stricter alignment requirements on the start of physical
+ * memory, but relaxing it means that we break people who
+ * are already placing their zImage in (eg) the top 64MB
+ * of this range.
+ */
+ mov r4, pc
+ and r4, r4, #0xf8000000
+ /* Determine final kernel image address. */
+ add r4, r4, #TEXT_OFFSET
+#else
+ ldr r4, =zreladdr
+#endif
+
+ /*
+ * Set up a page table only if it won't overwrite ourself.
+ * That means r4 < pc || r4 - 16k page directory > &_end.
+ * Given that r4 > &_end is most unfrequent, we add a rough
+ * additional 1MB of room for a possible appended DTB.
+ */
+ mov r0, pc
+ cmp r0, r4
+ ldrcc r0, LC0+32
+ addcc r0, r0, pc
+ cmpcc r4, r0
+ orrcc r4, r4, #1 @ remember we skipped cache_on
+ blcs 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
+
+ mov r5, #0 @ init dtb size to 0
+#ifdef CONFIG_ARM_APPENDED_DTB
+/*
+ * r0 = delta
+ * r2 = BSS start
+ * r3 = BSS end
+ * r4 = final kernel address (possibly with LSB set)
+ * r5 = appended dtb size (still unknown)
+ * r6 = _edata
+ * r7 = architecture ID
+ * r8 = atags/device tree pointer
+ * r9 = size of decompressed image
+ * r10 = end of this image, including bss/stack/malloc space if non XIP
+ * r11 = GOT start
+ * r12 = GOT end
+ * sp = stack pointer
+ *
+ * if there are device trees (dtb) appended to zImage, advance r10 so that the
+ * dtb data will get relocated along with the kernel if necessary.
+ */
+
+ ldr lr, [r6, #0]
+#ifndef __ARMEB__
+ ldr r1, =0xedfe0dd0 @ sig is 0xd00dfeed big endian
+#else
+ ldr r1, =0xd00dfeed
+#endif
+ cmp lr, r1
+ bne dtb_check_done @ not found
+
+#ifdef CONFIG_ARM_ATAG_DTB_COMPAT
+ /*
+ * OK... Let's do some funky business here.
+ * If we do have a DTB appended to zImage, and we do have
+ * an ATAG list around, we want the later to be translated
+ * and folded into the former here. No GOT fixup has occurred
+ * yet, but none of the code we're about to call uses any
+ * global variable.
+ */
+
+ /* Get the initial DTB size */
+ ldr r5, [r6, #4]
+#ifndef __ARMEB__
+ /* convert to little endian */
+ eor r1, r5, r5, ror #16
+ bic r1, r1, #0x00ff0000
+ mov r5, r5, ror #8
+ eor r5, r5, r1, lsr #8
+#endif
+ /* 50% DTB growth should be good enough */
+ add r5, r5, r5, lsr #1
+ /* preserve 64-bit alignment */
+ add r5, r5, #7
+ bic r5, r5, #7
+ /* clamp to 32KB min and 1MB max */
+ cmp r5, #(1 << 15)
+ movlo r5, #(1 << 15)
+ cmp r5, #(1 << 20)
+ movhi r5, #(1 << 20)
+ /* temporarily relocate the stack past the DTB work space */
+ add sp, sp, r5
+
+ stmfd sp!, {r0-r3, ip, lr}
+ mov r0, r8
+ mov r1, r6
+ mov r2, r5
+ bl atags_to_fdt
+
+ /*
+ * If returned value is 1, there is no ATAG at the location
+ * pointed by r8. Try the typical 0x100 offset from start
+ * of RAM and hope for the best.
+ */
+ cmp r0, #1
+ sub r0, r4, #TEXT_OFFSET
+ bic r0, r0, #1
+ add r0, r0, #0x100
+ mov r1, r6
+ mov r2, r5
+ bleq atags_to_fdt
+
+ ldmfd sp!, {r0-r3, ip, lr}
+ sub sp, sp, r5
+#endif
+
+ mov r8, r6 @ use the appended device tree
+
+ /*
+ * Make sure that the DTB doesn't end up in the final
+ * kernel's .bss area. To do so, we adjust the decompressed
+ * kernel size to compensate if that .bss size is larger
+ * than the relocated code.
+ */
+ ldr r5, =_kernel_bss_size
+ adr r1, wont_overwrite
+ sub r1, r6, r1
+ subs r1, r5, r1
+ addhi r9, r9, r1
+
+ /* Get the current DTB size */
+ ldr r5, [r6, #4]
+#ifndef __ARMEB__
+ /* convert r5 (dtb size) to little endian */
+ eor r1, r5, r5, ror #16
+ bic r1, r1, #0x00ff0000
+ mov r5, r5, ror #8
+ eor r5, r5, r1, lsr #8
+#endif
+
+ /* preserve 64-bit alignment */
+ add r5, r5, #7
+ bic r5, r5, #7
+
+ /* relocate some pointers past the appended dtb */
+ add r6, r6, r5
+ add r10, r10, r5
+ add sp, sp, r5
+dtb_check_done:
+#endif
+
+/*
+ * Check to see if we will overwrite ourselves.
+ * r4 = final kernel address (possibly with LSB set)
+ * 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 <= address of wont_overwrite -> OK
+ * Note: the possible LSB in r4 is harmless here.
+ */
+ add r10, r10, #16384
+ cmp r4, r10
+ bhs wont_overwrite
+ add r10, r4, r9
+ adr r9, wont_overwrite
+ cmp r10, r9
+ 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
+
+/* Relocate the hyp vector base if necessary */
+#ifdef CONFIG_ARM_VIRT_EXT
+ mrs r0, spsr
+ and r0, r0, #MODE_MASK
+ cmp r0, #HYP_MODE
+ bne 1f
+
+ bl __hyp_get_vectors
+ sub r0, r0, r5
+ add r0, r0, r10
+ bl __hyp_set_vectors
+1:
+#endif
+
+ 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 (possibly with LSB set)
+ * r5 = appended dtb size (0 if not present)
+ * r7 = architecture ID
+ * r8 = atags pointer
+ * r11 = GOT start
+ * r12 = GOT end
+ * sp = stack pointer
+ */
+ orrs r1, r0, r5
+ 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.
+ * Bump bss entries to _edata + dtb size
+ */
+1: ldr r1, [r11, #0] @ relocate entries in the GOT
+ add r1, r1, r0 @ This fixes up C references
+ cmp r1, r2 @ if entry >= bss_start &&
+ cmphs r3, r1 @ bss_end > entry
+ addhi r1, r1, r5 @ entry += dtb size
+ str r1, [r11], #4 @ next entry
+ cmp r11, r12
+ blo 1b
+
+ /* bump our bss pointers too */
+ add r2, r2, r5
+ add r3, r3, r5
+
+#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
+
+ /*
+ * Did we skip the cache setup earlier?
+ * That is indicated by the LSB in r4.
+ * Do it now if so.
+ */
+ tst r4, #1
+ bic r4, r4, #1
+ blne cache_on
+
+/*
+ * 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 r1, r7 @ restore architecture number
+ mov r2, r8 @ restore atags pointer
+
+#ifdef CONFIG_ARM_VIRT_EXT
+ mrs r0, spsr @ Get saved CPU boot mode
+ and r0, r0, #MODE_MASK
+ cmp r0, #HYP_MODE @ if not booted in HYP mode...
+ bne __enter_kernel @ boot kernel directly
+
+ adr r12, .L__hyp_reentry_vectors_offset
+ ldr r0, [r12]
+ add r0, r0, r12
+
+ bl __hyp_set_vectors
+ __HVC(0) @ otherwise bounce to hyp mode
+
+ b . @ should never be reached
+
+ .align 2
+.L__hyp_reentry_vectors_offset: .long __hyp_reentry_vectors - .
+#else
+ b __enter_kernel
+#endif
+
+ .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
+ .word _end - restart + 16384 + 1024*1024
+ .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
+
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+#define CB_BITS 0x08
+#else
+#define CB_BITS 0x0c
+#endif
+
+__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 @ XN|U + section mapping
+ orr r1, r1, #3 << 10 @ AP=11
+ add r2, r3, #16384
+1: cmp r1, r9 @ if virt > start of RAM
+ cmphs r10, r1 @ && end of RAM > virt
+ bic r1, r1, #0x1c @ clear XN|U + C + B
+ orrlo r1, r1, #0x10 @ Set XN|U for non-RAM
+ orrhs r1, r1, r6 @ set RAM section settings
+ 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.
+ */
+ orr r1, r6, #0x04 @ ensure B is set for this
+ 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)
+
+@ Enable unaligned access on v6, to allow better code generation
+@ for the decompressor C code:
+__armv6_mmu_cache_on:
+ mrc p15, 0, r0, c1, c0, 0 @ read SCTLR
+ bic r0, r0, #2 @ A (no unaligned access fault)
+ orr r0, r0, #1 << 22 @ U (v6 unaligned access model)
+ mcr p15, 0, r0, c1, c0, 0 @ write SCTLR
+ b __armv4_mmu_cache_on
+
+__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
+ mov r6, #CB_BITS | 0x12 @ U
+ 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
+ ARM_BE8( orr r0, r0, #1 << 25 ) @ big-endian page tables
+ 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
+ movne r6, #CB_BITS | 0x02 @ !XN
+ 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
+ bic r0, r0, #1 << 28 @ clear SCTLR.TRE
+ orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
+ orr r0, r0, #0x003c @ write buffer
+ bic r0, r0, #2 @ A (no unaligned access fault)
+ orr r0, r0, #1 << 22 @ U (v6 unaligned access model)
+ @ (needed for ARM1176)
+#ifdef CONFIG_MMU
+ ARM_BE8( orr r0, r0, #1 << 25 ) @ big-endian page tables
+ mrcne p15, 0, r6, c2, c0, 2 @ read ttb control reg
+ orrne r0, r0, #1 @ MMU enabled
+ movne r1, #0xfffffffd @ domain 0 = client
+ bic r6, r6, #1 << 31 @ 32-bit translation system
+ bic r6, r6, #3 << 0 @ use only ttbr0
+ mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer
+ mcrne p15, 0, r1, c3, c0, 0 @ load domain access control
+ mcrne p15, 0, r6, c2, c0, 2 @ load ttb control
+#endif
+ mcr p15, 0, r0, c7, c5, 4 @ ISB
+ 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
+ mov r6, #CB_BITS | 0x12 @ U
+ 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
+
+__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
+#elif defined(CONFIG_CPU_V7M)
+ /*
+ * On v7-M the processor id is located in the V7M_SCB_CPUID
+ * register, but as cache handling is IMPLEMENTATION DEFINED on
+ * v7-M (if existant at all) we just return early here.
+ * If V7M_SCB_CPUID were used the cpu ID functions (i.e.
+ * __armv7_mmu_cache_{on,off,flush}) would be selected which
+ * use cp15 registers that are not implemented on v7-M.
+ */
+ bx lr
+#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 0x41000000 @ old ARM ID
+ .word 0xff00f000
+ mov pc, lr
+ THUMB( nop )
+ mov pc, lr
+ THUMB( nop )
+ mov pc, lr
+ THUMB( nop )
+
+ .word 0x41007000 @ ARM7/710
+ .word 0xfff8fe00
+ mov pc, lr
+ THUMB( nop )
+ mov pc, lr
+ THUMB( nop )
+ 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) __armv6_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
+
+/*
+ * 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:
+ tst r4, #1
+ movne pc, lr
+ 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:
+ tst r4, #1
+ movne pc, lr
+ 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
+ tst r4, #1
+ mcreq p15, 0, r1, c7, c14, 0 @ clean+invalidate D
+ mcr p15, 0, r1, c7, c5, 0 @ invalidate I+BTB
+ mcreq 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:
+ tst r4, #1
+ bne iflush
+ 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:
+ tst r4, #1
+ movne pc, lr
+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:
+ tst r4, #1
+ movne pc, lr
+ 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:
+ tst r4, #1
+ movne pc, lr
+ 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
+
+#ifdef CONFIG_ARM_VIRT_EXT
+.align 5
+__hyp_reentry_vectors:
+ W(b) . @ reset
+ W(b) . @ undef
+ W(b) . @ svc
+ W(b) . @ pabort
+ W(b) . @ dabort
+ W(b) __enter_kernel @ hyp
+ W(b) . @ irq
+ W(b) . @ fiq
+#endif /* CONFIG_ARM_VIRT_EXT */
+
+__enter_kernel:
+ mov r0, #0 @ must be 0
+ ARM( mov pc, r4 ) @ call kernel
+ M_CLASS( add r4, r4, #1 ) @ enter in Thumb mode for M class
+ THUMB( bx r4 ) @ entry point is always ARM for A/R classes
+
+reloc_code_end:
+
+ .align
+ .section ".stack", "aw", %nobits
+.L_user_stack: .space 4096
+.L_user_stack_end:
diff --git a/arch/arm/boot/compressed/libfdt_env.h b/arch/arm/boot/compressed/libfdt_env.h
new file mode 100644
index 000000000..1f4e71876
--- /dev/null
+++ b/arch/arm/boot/compressed/libfdt_env.h
@@ -0,0 +1,15 @@
+#ifndef _ARM_LIBFDT_ENV_H
+#define _ARM_LIBFDT_ENV_H
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <asm/byteorder.h>
+
+#define fdt16_to_cpu(x) be16_to_cpu(x)
+#define cpu_to_fdt16(x) cpu_to_be16(x)
+#define fdt32_to_cpu(x) be32_to_cpu(x)
+#define cpu_to_fdt32(x) cpu_to_be32(x)
+#define fdt64_to_cpu(x) be64_to_cpu(x)
+#define cpu_to_fdt64(x) cpu_to_be64(x)
+
+#endif
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 000000000..8517c8606
--- /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 000000000..d4f891f56
--- /dev/null
+++ b/arch/arm/boot/compressed/misc.c
@@ -0,0 +1,168 @@
+/*
+ * 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;
+
+#include <linux/compiler.h> /* for inline */
+#include <linux/types.h>
+#include <linux/linkage.h>
+
+static void putstr(const char *ptr);
+extern void error(char *x);
+
+#include CONFIG_UNCOMPRESS_INCLUDE
+
+#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();
+}
+
+/*
+ * 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!");
+}
+
+unsigned long __stack_chk_guard;
+
+void __stack_chk_guard_setup(void)
+{
+ __stack_chk_guard = 0x000a0dff;
+}
+
+void __stack_chk_fail(void)
+{
+ error("stack-protector: Kernel stack is corrupted\n");
+}
+
+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;
+
+ __stack_chk_guard_setup();
+
+ 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/piggy.gzip.S b/arch/arm/boot/compressed/piggy.gzip.S
new file mode 100644
index 000000000..a68adf91a
--- /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.lz4.S b/arch/arm/boot/compressed/piggy.lz4.S
new file mode 100644
index 000000000..3d9a57561
--- /dev/null
+++ b/arch/arm/boot/compressed/piggy.lz4.S
@@ -0,0 +1,6 @@
+ .section .piggydata,#alloc
+ .globl input_data
+input_data:
+ .incbin "arch/arm/boot/compressed/piggy.lz4"
+ .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 000000000..d7e69cffb
--- /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 000000000..a425ad959
--- /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/piggy.xzkern.S b/arch/arm/boot/compressed/piggy.xzkern.S
new file mode 100644
index 000000000..5703f300d
--- /dev/null
+++ b/arch/arm/boot/compressed/piggy.xzkern.S
@@ -0,0 +1,6 @@
+ .section .piggydata,#alloc
+ .globl input_data
+input_data:
+ .incbin "arch/arm/boot/compressed/piggy.xzkern"
+ .globl input_data_end
+input_data_end:
diff --git a/arch/arm/boot/compressed/string.c b/arch/arm/boot/compressed/string.c
new file mode 100644
index 000000000..36e53ef92
--- /dev/null
+++ b/arch/arm/boot/compressed/string.c
@@ -0,0 +1,127 @@
+/*
+ * arch/arm/boot/compressed/string.c
+ *
+ * Small subset of simple string routines
+ */
+
+#include <linux/string.h>
+
+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;
+}
+
+void *memmove(void *__dest, __const void *__src, size_t count)
+{
+ unsigned char *d = __dest;
+ const unsigned char *s = __src;
+
+ if (__dest == __src)
+ return __dest;
+
+ if (__dest < __src)
+ return memcpy(__dest, __src, count);
+
+ while (count--)
+ d[count] = s[count];
+ return __dest;
+}
+
+size_t strlen(const char *s)
+{
+ const char *sc = s;
+
+ while (*sc != '\0')
+ sc++;
+ return sc - s;
+}
+
+int memcmp(const void *cs, const void *ct, size_t count)
+{
+ const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count;
+ int res = 0;
+
+ while (su1 < end) {
+ res = *su1++ - *su2++;
+ if (res)
+ break;
+ }
+ return res;
+}
+
+int strcmp(const char *cs, const char *ct)
+{
+ unsigned char c1, c2;
+ int res = 0;
+
+ do {
+ c1 = *cs++;
+ c2 = *ct++;
+ res = c1 - c2;
+ if (res)
+ break;
+ } while (c1);
+ return res;
+}
+
+void *memchr(const void *s, int c, size_t count)
+{
+ const unsigned char *p = s;
+
+ while (count--)
+ if ((unsigned char)c == *p++)
+ return (void *)(p - 1);
+ return NULL;
+}
+
+char *strchr(const char *s, int c)
+{
+ while (*s != (char)c)
+ if (*s++ == '\0')
+ return NULL;
+ return (char *)s;
+}
+
+#undef memset
+
+void *memset(void *s, int c, size_t count)
+{
+ char *xs = s;
+ while (count--)
+ *xs++ = c;
+ return s;
+}
+
+void __memzero(void *s, size_t count)
+{
+ memset(s, 0, count);
+}
diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S
new file mode 100644
index 000000000..2b60b843a
--- /dev/null
+++ b/arch/arm/boot/compressed/vmlinux.lds.S
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#ifdef CONFIG_CPU_ENDIAN_BE8
+#define ZIMAGE_MAGIC(x) ( (((x) >> 24) & 0x000000ff) | \
+ (((x) >> 8) & 0x0000ff00) | \
+ (((x) << 8) & 0x00ff0000) | \
+ (((x) << 24) & 0xff000000) )
+#else
+#define ZIMAGE_MAGIC(x) (x)
+#endif
+
+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)
+ *(.glue_7t)
+ *(.glue_7)
+ }
+ .rodata : {
+ *(.rodata)
+ *(.rodata.*)
+ }
+ .piggydata : {
+ *(.piggydata)
+ }
+
+ . = ALIGN(4);
+ _etext = .;
+
+ .got.plt : { *(.got.plt) }
+ _got_start = .;
+ .got : { *(.got) }
+ _got_end = .;
+
+ /* ensure the zImage file size is always a multiple of 64 bits */
+ /* (without a dummy byte, ld just ignores the empty section) */
+ .pad : { BYTE(0); . = ALIGN(8); }
+ _edata = .;
+
+ _magic_sig = ZIMAGE_MAGIC(0x016f2818);
+ _magic_start = ZIMAGE_MAGIC(_start);
+ _magic_end = ZIMAGE_MAGIC(_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/dts/Makefile b/arch/arm/boot/dts/Makefile
new file mode 100644
index 000000000..992736b52
--- /dev/null
+++ b/arch/arm/boot/dts/Makefile
@@ -0,0 +1,666 @@
+ifeq ($(CONFIG_OF),y)
+
+dtb-$(CONFIG_ARCH_ALPINE) += \
+ alpine-db.dtb
+dtb-$(CONFIG_MACH_ASM9260) += \
+ alphascale-asm9260-devkit.dtb
+# Keep at91 dtb files sorted alphabetically for each SoC
+dtb-$(CONFIG_SOC_SAM_V4_V5) += \
+ at91rm9200ek.dtb \
+ mpa1600.dtb \
+ animeo_ip.dtb \
+ at91-qil_a9260.dtb \
+ aks-cdu.dtb \
+ ethernut5.dtb \
+ evk-pro3.dtb \
+ tny_a9260.dtb \
+ usb_a9260.dtb \
+ at91sam9261ek.dtb \
+ at91sam9263ek.dtb \
+ tny_a9263.dtb \
+ usb_a9263.dtb \
+ at91-foxg20.dtb \
+ at91sam9g20ek.dtb \
+ at91sam9g20ek_2mmc.dtb \
+ kizbox.dtb \
+ tny_a9g20.dtb \
+ usb_a9g20.dtb \
+ usb_a9g20_lpw.dtb \
+ at91sam9m10g45ek.dtb \
+ pm9g45.dtb \
+ at91sam9n12ek.dtb \
+ at91sam9rlek.dtb \
+ at91-ariag25.dtb \
+ at91-cosino_mega2560.dtb \
+ at91sam9g15ek.dtb \
+ at91sam9g25ek.dtb \
+ at91sam9g35ek.dtb \
+ at91sam9x25ek.dtb \
+ at91sam9x35ek.dtb
+dtb-$(CONFIG_SOC_SAM_V7) += \
+ at91-sama5d3_xplained.dtb \
+ sama5d31ek.dtb \
+ sama5d33ek.dtb \
+ sama5d34ek.dtb \
+ sama5d35ek.dtb \
+ sama5d36ek.dtb \
+ at91-sama5d4_xplained.dtb \
+ at91-sama5d4ek.dtb
+dtb-$(CONFIG_ARCH_ATLAS6) += \
+ atlas6-evb.dtb
+dtb-$(CONFIG_ARCH_ATLAS7) += \
+ atlas7-evb.dtb
+dtb-$(CONFIG_ARCH_AXXIA) += \
+ axm5516-amarillo.dtb
+dtb-$(CONFIG_ARCH_BCM2835) += \
+ bcm2835-rpi-b.dtb \
+ bcm2835-rpi-b-plus.dtb
+dtb-$(CONFIG_ARCH_BCM_5301X) += \
+ bcm4708-buffalo-wzr-1750dhp.dtb \
+ bcm4708-luxul-xwc-1000.dtb \
+ bcm4708-netgear-r6250.dtb \
+ bcm4708-netgear-r6300-v2.dtb \
+ bcm47081-asus-rt-n18u.dtb \
+ bcm47081-buffalo-wzr-600dhp2.dtb \
+ bcm47081-buffalo-wzr-900dhp.dtb \
+ bcm4709-netgear-r8000.dtb
+dtb-$(CONFIG_ARCH_BCM_63XX) += \
+ bcm963138dvt.dtb
+dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \
+ bcm911360_entphn.dtb \
+ bcm911360k.dtb \
+ bcm958300k.dtb \
+ bcm958305k.dtb
+dtb-$(CONFIG_ARCH_BCM_MOBILE) += \
+ bcm28155-ap.dtb \
+ bcm21664-garnet.dtb
+dtb-$(CONFIG_ARCH_BERLIN) += \
+ berlin2-sony-nsz-gs7.dtb \
+ berlin2cd-google-chromecast.dtb \
+ berlin2q-marvell-dmp.dtb
+dtb-$(CONFIG_ARCH_BRCMSTB) += \
+ bcm7445-bcm97445svmb.dtb
+dtb-$(CONFIG_ARCH_DAVINCI) += \
+ da850-enbw-cmc.dtb \
+ da850-evm.dtb
+dtb-$(CONFIG_ARCH_DIGICOLOR) += \
+ cx92755_equinox.dtb
+dtb-$(CONFIG_ARCH_EFM32) += \
+ efm32gg-dk3750.dtb
+dtb-$(CONFIG_ARCH_EXYNOS3) += \
+ exynos3250-monk.dtb \
+ exynos3250-rinato.dtb
+dtb-$(CONFIG_ARCH_EXYNOS4) += \
+ exynos4210-origen.dtb \
+ exynos4210-smdkv310.dtb \
+ exynos4210-trats.dtb \
+ exynos4210-universal_c210.dtb \
+ exynos4412-odroidu3.dtb \
+ exynos4412-odroidx.dtb \
+ exynos4412-odroidx2.dtb \
+ exynos4412-origen.dtb \
+ exynos4412-smdk4412.dtb \
+ exynos4412-tiny4412.dtb \
+ exynos4412-trats2.dtb
+dtb-$(CONFIG_ARCH_EXYNOS5) += \
+ exynos5250-arndale.dtb \
+ exynos5250-smdk5250.dtb \
+ exynos5250-snow.dtb \
+ exynos5250-spring.dtb \
+ exynos5260-xyref5260.dtb \
+ exynos5410-smdk5410.dtb \
+ exynos5420-arndale-octa.dtb \
+ exynos5420-peach-pit.dtb \
+ exynos5420-smdk5420.dtb \
+ exynos5422-odroidxu3.dtb \
+ exynos5440-sd5v1.dtb \
+ exynos5440-ssdk5440.dtb \
+ exynos5800-peach-pi.dtb
+dtb-$(CONFIG_ARCH_HI3xxx) += \
+ hi3620-hi4511.dtb
+dtb-$(CONFIG_ARCH_HIX5HD2) += \
+ hisi-x5hd2-dkb.dtb
+dtb-$(CONFIG_ARCH_HIGHBANK) += \
+ highbank.dtb \
+ ecx-2000.dtb
+dtb-$(CONFIG_ARCH_HIP01) += \
+ hip01-ca9x2.dtb
+dtb-$(CONFIG_ARCH_HIP04) += \
+ hip04-d01.dtb
+dtb-$(CONFIG_ARCH_INTEGRATOR) += \
+ integratorap.dtb \
+ integratorcp.dtb
+dtb-$(CONFIG_ARCH_KEYSTONE) += \
+ k2hk-evm.dtb \
+ k2l-evm.dtb \
+ k2e-evm.dtb
+dtb-$(CONFIG_MACH_KIRKWOOD) += \
+ kirkwood-b3.dtb \
+ kirkwood-blackarmor-nas220.dtb \
+ kirkwood-cloudbox.dtb \
+ kirkwood-d2net.dtb \
+ kirkwood-db-88f6281.dtb \
+ kirkwood-db-88f6282.dtb \
+ kirkwood-dir665.dtb \
+ kirkwood-dns320.dtb \
+ kirkwood-dns325.dtb \
+ kirkwood-dockstar.dtb \
+ kirkwood-dreamplug.dtb \
+ kirkwood-ds109.dtb \
+ kirkwood-ds110jv10.dtb \
+ kirkwood-ds111.dtb \
+ kirkwood-ds209.dtb \
+ kirkwood-ds210.dtb \
+ kirkwood-ds212.dtb \
+ kirkwood-ds212j.dtb \
+ kirkwood-ds409.dtb \
+ kirkwood-ds409slim.dtb \
+ kirkwood-ds411.dtb \
+ kirkwood-ds411j.dtb \
+ kirkwood-ds411slim.dtb \
+ kirkwood-goflexnet.dtb \
+ kirkwood-guruplug-server-plus.dtb \
+ kirkwood-ib62x0.dtb \
+ kirkwood-iconnect.dtb \
+ kirkwood-iomega_ix2_200.dtb \
+ kirkwood-is2.dtb \
+ kirkwood-km_kirkwood.dtb \
+ kirkwood-laplug.dtb \
+ kirkwood-lschlv2.dtb \
+ kirkwood-lsxhl.dtb \
+ kirkwood-mplcec4.dtb \
+ kirkwood-mv88f6281gtw-ge.dtb \
+ kirkwood-nas2big.dtb \
+ kirkwood-net2big.dtb \
+ kirkwood-net5big.dtb \
+ kirkwood-netgear_readynas_duo_v2.dtb \
+ kirkwood-netgear_readynas_nv+_v2.dtb \
+ kirkwood-ns2.dtb \
+ kirkwood-ns2lite.dtb \
+ kirkwood-ns2max.dtb \
+ kirkwood-ns2mini.dtb \
+ kirkwood-nsa310.dtb \
+ kirkwood-nsa310a.dtb \
+ kirkwood-openblocks_a6.dtb \
+ kirkwood-openblocks_a7.dtb \
+ kirkwood-openrd-base.dtb \
+ kirkwood-openrd-client.dtb \
+ kirkwood-openrd-ultimate.dtb \
+ kirkwood-pogo_e02.dtb \
+ kirkwood-rd88f6192.dtb \
+ kirkwood-rd88f6281-z0.dtb \
+ kirkwood-rd88f6281-a.dtb \
+ kirkwood-rs212.dtb \
+ kirkwood-rs409.dtb \
+ kirkwood-rs411.dtb \
+ kirkwood-sheevaplug.dtb \
+ kirkwood-sheevaplug-esata.dtb \
+ kirkwood-t5325.dtb \
+ kirkwood-topkick.dtb \
+ kirkwood-ts219-6281.dtb \
+ kirkwood-ts219-6282.dtb \
+ kirkwood-ts419-6281.dtb \
+ kirkwood-ts419-6282.dtb
+dtb-$(CONFIG_ARCH_LPC32XX) += \
+ ea3250.dtb phy3250.dtb
+dtb-$(CONFIG_MACH_MESON6) += \
+ meson6-atv1200.dtb
+dtb-$(CONFIG_MACH_MESON8) += \
+ meson8-minix-neo-x8.dtb
+dtb-$(CONFIG_ARCH_MMP) += \
+ pxa168-aspenite.dtb \
+ pxa910-dkb.dtb \
+ mmp2-brownstone.dtb
+dtb-$(CONFIG_ARCH_MOXART) += \
+ moxart-uc7112lx.dtb
+dtb-$(CONFIG_SOC_IMX1) += \
+ imx1-ads.dtb \
+ imx1-apf9328.dtb
+dtb-$(CONFIG_SOC_IMX25) += \
+ imx25-eukrea-mbimxsd25-baseboard.dtb \
+ imx25-eukrea-mbimxsd25-baseboard-cmo-qvga.dtb \
+ imx25-eukrea-mbimxsd25-baseboard-dvi-svga.dtb \
+ imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dtb \
+ imx25-karo-tx25.dtb \
+ imx25-pdk.dtb
+dtb-$(CONFIG_SOC_IMX27) += \
+ imx27-apf27.dtb \
+ imx27-apf27dev.dtb \
+ imx27-eukrea-mbimxsd27-baseboard.dtb \
+ imx27-pdk.dtb \
+ imx27-phytec-phycore-rdk.dtb \
+ imx27-phytec-phycard-s-rdk.dtb
+dtb-$(CONFIG_SOC_IMX31) += \
+ imx31-bug.dtb
+dtb-$(CONFIG_SOC_IMX35) += \
+ imx35-eukrea-mbimxsd35-baseboard.dtb \
+ imx35-pdk.dtb
+dtb-$(CONFIG_SOC_IMX50) += \
+ imx50-evk.dtb
+dtb-$(CONFIG_SOC_IMX51) += \
+ imx51-apf51.dtb \
+ imx51-apf51dev.dtb \
+ imx51-babbage.dtb \
+ imx51-digi-connectcore-jsk.dtb \
+ imx51-eukrea-mbimxsd51-baseboard.dtb
+dtb-$(CONFIG_SOC_IMX53) += \
+ imx53-ard.dtb \
+ imx53-m53evk.dtb \
+ imx53-mba53.dtb \
+ imx53-qsb.dtb \
+ imx53-qsrb.dtb \
+ imx53-smd.dtb \
+ imx53-tx53-x03x.dtb \
+ imx53-tx53-x13x.dtb \
+ imx53-voipac-bsb.dtb
+dtb-$(CONFIG_SOC_IMX6Q) += \
+ imx6dl-aristainetos_4.dtb \
+ imx6dl-aristainetos_7.dtb \
+ imx6dl-cubox-i.dtb \
+ imx6dl-dfi-fs700-m60.dtb \
+ imx6dl-gw51xx.dtb \
+ imx6dl-gw52xx.dtb \
+ imx6dl-gw53xx.dtb \
+ imx6dl-gw54xx.dtb \
+ imx6dl-gw552x.dtb \
+ imx6dl-hummingboard.dtb \
+ imx6dl-nitrogen6x.dtb \
+ imx6dl-phytec-pbab01.dtb \
+ imx6dl-rex-basic.dtb \
+ imx6dl-riotboard.dtb \
+ imx6dl-sabreauto.dtb \
+ imx6dl-sabrelite.dtb \
+ imx6dl-sabresd.dtb \
+ imx6dl-tx6dl-comtft.dtb \
+ imx6dl-tx6u-801x.dtb \
+ imx6dl-tx6u-811x.dtb \
+ imx6dl-udoo.dtb \
+ imx6dl-wandboard.dtb \
+ imx6dl-wandboard-revb1.dtb \
+ imx6q-arm2.dtb \
+ imx6q-cm-fx6.dtb \
+ imx6q-cubox-i.dtb \
+ imx6q-dfi-fs700-m60.dtb \
+ imx6q-dmo-edmqmx6.dtb \
+ imx6q-gk802.dtb \
+ imx6q-gw51xx.dtb \
+ imx6q-gw52xx.dtb \
+ imx6q-gw53xx.dtb \
+ imx6q-gw5400-a.dtb \
+ imx6q-gw54xx.dtb \
+ imx6q-gw552x.dtb \
+ imx6q-hummingboard.dtb \
+ imx6q-nitrogen6x.dtb \
+ imx6q-phytec-pbab01.dtb \
+ imx6q-rex-pro.dtb \
+ imx6q-sabreauto.dtb \
+ imx6q-sabrelite.dtb \
+ imx6q-sabresd.dtb \
+ imx6q-sbc6x.dtb \
+ imx6q-tbs2910.dtb \
+ imx6q-tx6q-1010.dtb \
+ imx6q-tx6q-1010-comtft.dtb \
+ imx6q-tx6q-1020.dtb \
+ imx6q-tx6q-1020-comtft.dtb \
+ imx6q-tx6q-1110.dtb \
+ imx6q-udoo.dtb \
+ imx6q-wandboard.dtb \
+ imx6q-wandboard-revb1.dtb
+dtb-$(CONFIG_SOC_IMX6SL) += \
+ imx6sl-evk.dtb \
+ imx6sl-warp.dtb
+dtb-$(CONFIG_SOC_IMX6SX) += \
+ imx6sx-sabreauto.dtb \
+ imx6sx-sdb-reva.dtb \
+ imx6sx-sdb.dtb
+dtb-$(CONFIG_SOC_LS1021A) += \
+ ls1021a-qds.dtb \
+ ls1021a-twr.dtb
+dtb-$(CONFIG_SOC_VF610) += \
+ vf500-colibri-eval-v3.dtb \
+ vf610-colibri-eval-v3.dtb \
+ vf610-cosmic.dtb \
+ vf610-twr.dtb
+dtb-$(CONFIG_ARCH_MXS) += \
+ imx23-evk.dtb \
+ imx23-olinuxino.dtb \
+ imx23-stmp378x_devb.dtb \
+ imx28-apf28.dtb \
+ imx28-apf28dev.dtb \
+ imx28-apx4devkit.dtb \
+ imx28-cfa10036.dtb \
+ imx28-cfa10037.dtb \
+ imx28-cfa10049.dtb \
+ imx28-cfa10055.dtb \
+ imx28-cfa10056.dtb \
+ imx28-cfa10057.dtb \
+ imx28-cfa10058.dtb \
+ imx28-duckbill.dtb \
+ imx28-eukrea-mbmx283lc.dtb \
+ imx28-eukrea-mbmx287lc.dtb \
+ imx28-evk.dtb \
+ imx28-m28cu3.dtb \
+ imx28-m28evk.dtb \
+ imx28-sps1.dtb \
+ imx28-tx28.dtb
+dtb-$(CONFIG_ARCH_NOMADIK) += \
+ ste-nomadik-s8815.dtb \
+ ste-nomadik-nhk15.dtb
+dtb-$(CONFIG_ARCH_NSPIRE) += \
+ nspire-cx.dtb \
+ nspire-tp.dtb \
+ nspire-clp.dtb
+dtb-$(CONFIG_ARCH_OMAP2) += \
+ omap2420-h4.dtb \
+ omap2420-n800.dtb \
+ omap2420-n810.dtb \
+ omap2420-n810-wimax.dtb \
+ omap2430-sdp.dtb
+dtb-$(CONFIG_ARCH_OMAP3) += \
+ am3517-craneboard.dtb \
+ am3517-evm.dtb \
+ am3517_mt_ventoux.dtb \
+ omap3430-sdp.dtb \
+ omap3-beagle.dtb \
+ omap3-beagle-xm.dtb \
+ omap3-beagle-xm-ab.dtb \
+ omap3-cm-t3517.dtb \
+ omap3-cm-t3530.dtb \
+ omap3-cm-t3730.dtb \
+ omap3-devkit8000.dtb \
+ omap3-evm.dtb \
+ omap3-evm-37xx.dtb \
+ omap3-gta04a3.dtb \
+ omap3-gta04a4.dtb \
+ omap3-gta04a5.dtb \
+ omap3-ha.dtb \
+ omap3-ha-lcd.dtb \
+ omap3-igep0020.dtb \
+ omap3-igep0020-rev-f.dtb \
+ omap3-igep0030.dtb \
+ omap3-igep0030-rev-g.dtb \
+ omap3-ldp.dtb \
+ omap3-lilly-dbb056.dtb \
+ omap3-n900.dtb \
+ omap3-n9.dtb \
+ omap3-n950.dtb \
+ omap3-overo-alto35.dtb \
+ omap3-overo-chestnut43.dtb \
+ omap3-overo-gallop43.dtb \
+ omap3-overo-palo43.dtb \
+ omap3-overo-storm-alto35.dtb \
+ omap3-overo-storm-chestnut43.dtb \
+ omap3-overo-storm-gallop43.dtb \
+ omap3-overo-storm-palo43.dtb \
+ omap3-overo-storm-summit.dtb \
+ omap3-overo-storm-tobi.dtb \
+ omap3-overo-summit.dtb \
+ omap3-overo-tobi.dtb \
+ omap3-pandora-600mhz.dtb \
+ omap3-pandora-1ghz.dtb \
+ omap3-sbc-t3517.dtb \
+ omap3-sbc-t3530.dtb \
+ omap3-sbc-t3730.dtb \
+ omap3-thunder.dtb \
+ omap3-zoom3.dtb
+dtb-$(CONFIG_SOC_TI81XX) += \
+ dm8168-evm.dtb
+dtb-$(CONFIG_SOC_AM33XX) += \
+ am335x-base0033.dtb \
+ am335x-bone.dtb \
+ am335x-boneblack.dtb \
+ am335x-evm.dtb \
+ am335x-evmsk.dtb \
+ am335x-nano.dtb \
+ am335x-pepper.dtb \
+ am335x-lxm.dtb \
+ am335x-chiliboard.dtb
+dtb-$(CONFIG_ARCH_OMAP4) += \
+ omap4-duovero-parlor.dtb \
+ omap4-panda.dtb \
+ omap4-panda-a4.dtb \
+ omap4-panda-es.dtb \
+ omap4-sdp.dtb \
+ omap4-sdp-es23plus.dtb \
+ omap4-var-dvk-om44.dtb \
+ omap4-var-stk-om44.dtb
+dtb-$(CONFIG_SOC_AM43XX) += \
+ am43x-epos-evm.dtb \
+ am437x-sk-evm.dtb \
+ am437x-idk-evm.dtb \
+ am437x-gp-evm.dtb
+dtb-$(CONFIG_SOC_OMAP5) += \
+ omap5-cm-t54.dtb \
+ omap5-sbc-t54.dtb \
+ omap5-uevm.dtb
+dtb-$(CONFIG_SOC_DRA7XX) += \
+ dra7-evm.dtb \
+ am57xx-beagle-x15.dtb \
+ dra72-evm.dtb
+dtb-$(CONFIG_ARCH_ORION5X) += \
+ orion5x-lacie-d2-network.dtb \
+ orion5x-lacie-ethernet-disk-mini-v2.dtb \
+ orion5x-maxtor-shared-storage-2.dtb \
+ orion5x-rd88f5182-nas.dtb
+dtb-$(CONFIG_ARCH_PRIMA2) += \
+ prima2-evb.dtb
+dtb-$(CONFIG_ARCH_QCOM) += \
+ qcom-apq8064-cm-qs600.dtb \
+ qcom-apq8064-ifc6410.dtb \
+ qcom-apq8074-dragonboard.dtb \
+ qcom-apq8084-ifc6540.dtb \
+ qcom-apq8084-mtp.dtb \
+ qcom-ipq8064-ap148.dtb \
+ qcom-msm8660-surf.dtb \
+ qcom-msm8960-cdp.dtb \
+ qcom-msm8974-sony-xperia-honami.dtb
+dtb-$(CONFIG_ARCH_REALVIEW) += \
+ arm-realview-pb1176.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += \
+ rk3066a-bqcurie2.dtb \
+ rk3066a-marsboard.dtb \
+ rk3066a-rayeager.dtb \
+ rk3188-radxarock.dtb \
+ rk3288-evb-act8846.dtb \
+ rk3288-evb-rk808.dtb \
+ rk3288-firefly-beta.dtb \
+ rk3288-firefly.dtb
+dtb-$(CONFIG_ARCH_S3C24XX) += \
+ s3c2416-smdk2416.dtb
+dtb-$(CONFIG_ARCH_S3C64XX) += \
+ s3c6410-mini6410.dtb \
+ s3c6410-smdk6410.dtb
+dtb-$(CONFIG_ARCH_S5PV210) += \
+ s5pv210-aquila.dtb \
+ s5pv210-goni.dtb \
+ s5pv210-smdkc110.dtb \
+ s5pv210-smdkv210.dtb \
+ s5pv210-torbreck.dtb
+dtb-$(CONFIG_ARCH_SHMOBILE_LEGACY) += \
+ r8a7740-armadillo800eva.dtb \
+ r8a7778-bockw.dtb \
+ r8a7778-bockw-reference.dtb \
+ r8a7779-marzen.dtb \
+ sh73a0-kzm9g.dtb
+dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
+ emev2-kzm9d.dtb \
+ r7s72100-genmai.dtb \
+ r8a73a4-ape6evm.dtb \
+ r8a7740-armadillo800eva.dtb \
+ r8a7778-bockw.dtb \
+ r8a7779-marzen.dtb \
+ r8a7790-lager.dtb \
+ r8a7791-henninger.dtb \
+ r8a7791-koelsch.dtb \
+ r8a7794-alt.dtb \
+ sh73a0-kzm9g.dtb
+dtb-$(CONFIG_ARCH_SOCFPGA) += \
+ socfpga_arria5_socdk.dtb \
+ socfpga_arria10_socdk.dtb \
+ socfpga_cyclone5_socdk.dtb \
+ socfpga_cyclone5_sockit.dtb \
+ socfpga_cyclone5_socrates.dtb \
+ socfpga_vt.dtb
+dtb-$(CONFIG_ARCH_SPEAR13XX) += \
+ spear1310-evb.dtb \
+ spear1340-evb.dtb
+dtb-$(CONFIG_ARCH_SPEAR3XX) += \
+ spear300-evb.dtb \
+ spear310-evb.dtb \
+ spear320-evb.dtb \
+ spear320-hmi.dtb
+dtb-$(CONFIG_ARCH_SPEAR6XX) += \
+ spear600-evb.dtb
+dtb-$(CONFIG_ARCH_STI) += \
+ stih407-b2120.dtb \
+ stih410-b2120.dtb \
+ stih415-b2000.dtb \
+ stih415-b2020.dtb \
+ stih416-b2000.dtb \
+ stih416-b2020.dtb \
+ stih416-b2020e.dtb \
+ stih418-b2199.dtb
+dtb-$(CONFIG_MACH_SUN4I) += \
+ sun4i-a10-a1000.dtb \
+ sun4i-a10-ba10-tvbox.dtb \
+ sun4i-a10-chuwi-v7-cw0825.dtb \
+ sun4i-a10-cubieboard.dtb \
+ sun4i-a10-marsboard.dtb \
+ sun4i-a10-mini-xplus.dtb \
+ sun4i-a10-mk802.dtb \
+ sun4i-a10-mk802ii.dtb \
+ sun4i-a10-hackberry.dtb \
+ sun4i-a10-hyundai-a7hd.dtb \
+ sun4i-a10-inet97fv2.dtb \
+ sun4i-a10-olinuxino-lime.dtb \
+ sun4i-a10-pcduino.dtb
+dtb-$(CONFIG_MACH_SUN5I) += \
+ sun5i-a10s-mk802.dtb \
+ sun5i-a10s-olinuxino-micro.dtb \
+ sun5i-a10s-r7-tv-dongle.dtb \
+ sun5i-a13-hsg-h702.dtb \
+ sun5i-a13-olinuxino.dtb \
+ sun5i-a13-olinuxino-micro.dtb
+dtb-$(CONFIG_MACH_SUN6I) += \
+ sun6i-a31-app4-evb1.dtb \
+ sun6i-a31-colombus.dtb \
+ sun6i-a31-hummingbird.dtb \
+ sun6i-a31-m9.dtb \
+ sun6i-a31s-cs908.dtb
+dtb-$(CONFIG_MACH_SUN7I) += \
+ sun7i-a20-bananapi.dtb \
+ sun7i-a20-bananapro.dtb \
+ sun7i-a20-cubieboard2.dtb \
+ sun7i-a20-cubietruck.dtb \
+ sun7i-a20-hummingbird.dtb \
+ sun7i-a20-i12-tvbox.dtb \
+ sun7i-a20-m3.dtb \
+ sun7i-a20-olinuxino-lime.dtb \
+ sun7i-a20-olinuxino-lime2.dtb \
+ sun7i-a20-olinuxino-micro.dtb \
+ sun7i-a20-pcduino3.dtb
+dtb-$(CONFIG_MACH_SUN8I) += \
+ sun8i-a23-ippo-q8h-v5.dtb \
+ sun8i-a23-ippo-q8h-v1.2.dtb
+dtb-$(CONFIG_MACH_SUN9I) += \
+ sun9i-a80-optimus.dtb
+dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += \
+ tegra20-harmony.dtb \
+ tegra20-iris-512.dtb \
+ tegra20-medcom-wide.dtb \
+ tegra20-paz00.dtb \
+ tegra20-plutux.dtb \
+ tegra20-seaboard.dtb \
+ tegra20-tec.dtb \
+ tegra20-trimslice.dtb \
+ tegra20-ventana.dtb \
+ tegra20-whistler.dtb
+dtb-$(CONFIG_ARCH_TEGRA_3x_SOC) += \
+ tegra30-apalis-eval.dtb \
+ tegra30-beaver.dtb \
+ tegra30-cardhu-a02.dtb \
+ tegra30-cardhu-a04.dtb \
+ tegra30-colibri-eval-v3.dtb
+dtb-$(CONFIG_ARCH_TEGRA_114_SOC) += \
+ tegra114-dalmore.dtb \
+ tegra114-roth.dtb \
+ tegra114-tn7.dtb
+dtb-$(CONFIG_ARCH_TEGRA_124_SOC) += \
+ tegra124-jetson-tk1.dtb \
+ tegra124-nyan-big.dtb \
+ tegra124-nyan-blaze.dtb \
+ tegra124-venice2.dtb
+dtb-$(CONFIG_ARCH_U300) += \
+ ste-u300.dtb
+dtb-$(CONFIG_ARCH_U8500) += \
+ ste-snowball.dtb \
+ ste-hrefprev60-stuib.dtb \
+ ste-hrefprev60-tvk.dtb \
+ ste-hrefv60plus-stuib.dtb \
+ ste-hrefv60plus-tvk.dtb \
+ ste-ccu8540.dtb \
+ ste-ccu9540.dtb
+dtb-$(CONFIG_ARCH_VERSATILE) += \
+ versatile-ab.dtb \
+ versatile-pb.dtb
+dtb-$(CONFIG_ARCH_VEXPRESS) += \
+ vexpress-v2p-ca5s.dtb \
+ vexpress-v2p-ca9.dtb \
+ vexpress-v2p-ca15-tc1.dtb \
+ vexpress-v2p-ca15_a7.dtb
+dtb-$(CONFIG_ARCH_VIRT) += \
+ xenvm-4.2.dtb
+dtb-$(CONFIG_ARCH_VT8500) += \
+ vt8500-bv07.dtb \
+ wm8505-ref.dtb \
+ wm8650-mid.dtb \
+ wm8750-apc8750.dtb \
+ wm8850-w70v2.dtb
+dtb-$(CONFIG_ARCH_ZYNQ) += \
+ zynq-parallella.dtb \
+ zynq-zc702.dtb \
+ zynq-zc706.dtb \
+ zynq-zed.dtb \
+ zynq-zybo.dtb
+dtb-$(CONFIG_MACH_ARMADA_370) += \
+ armada-370-db.dtb \
+ armada-370-mirabox.dtb \
+ armada-370-netgear-rn102.dtb \
+ armada-370-netgear-rn104.dtb \
+ armada-370-rd.dtb \
+ armada-370-synology-ds213j.dtb
+dtb-$(CONFIG_MACH_ARMADA_375) += \
+ armada-375-db.dtb
+dtb-$(CONFIG_MACH_ARMADA_38X) += \
+ armada-385-db-ap.dtb \
+ armada-388-db.dtb \
+ armada-388-gp.dtb \
+ armada-388-rd.dtb
+dtb-$(CONFIG_MACH_ARMADA_39X) += \
+ armada-398-db.dtb
+dtb-$(CONFIG_MACH_ARMADA_XP) += \
+ armada-xp-axpwifiap.dtb \
+ armada-xp-db.dtb \
+ armada-xp-gp.dtb \
+ armada-xp-lenovo-ix4-300d.dtb \
+ armada-xp-linksys-mamba.dtb \
+ armada-xp-matrix.dtb \
+ armada-xp-netgear-rn2120.dtb \
+ armada-xp-openblocks-ax3-4.dtb \
+ armada-xp-synology-ds414.dtb
+dtb-$(CONFIG_MACH_DOVE) += \
+ dove-cm-a510.dtb \
+ dove-cubox.dtb \
+ dove-cubox-es.dtb \
+ dove-d2plug.dtb \
+ dove-d3plug.dtb \
+ dove-dove-db.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += \
+ mt6589-aquaris5.dtb \
+ mt6592-evb.dtb \
+ mt8127-moose.dtb \
+ mt8135-evbp1.dtb
+endif
+
+always := $(dtb-y)
+clean-files := *.dtb
diff --git a/arch/arm/boot/dts/aks-cdu.dts b/arch/arm/boot/dts/aks-cdu.dts
new file mode 100644
index 000000000..d9c50fbb4
--- /dev/null
+++ b/arch/arm/boot/dts/aks-cdu.dts
@@ -0,0 +1,119 @@
+/*
+ * aks-cdu.dts - Device Tree file for AK signal CDU
+ *
+ * Copyright (C) 2012 AK signal Brno a.s.
+ * 2012 Jiri Prchal <jiri.prchal@aksignal.cz>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/dts-v1/;
+
+#include "ge863-pro3.dtsi"
+
+/ {
+ chosen {
+ bootargs = "console=ttyS0,115200 ubi.mtd=4 root=ubi0:rootfs rootfstype=ubifs";
+ };
+
+ clocks {
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+ };
+
+ ahb {
+ apb {
+ usart0: serial@fffb0000 {
+ status = "okay";
+ };
+
+ usart1: serial@fffb4000 {
+ status = "okay";
+ linux,rs485-enabled-at-boot-time;
+ rs485-rts-delay = <0 0>;
+ };
+
+ usart2: serial@fffb8000 {
+ status = "okay";
+ linux,rs485-enabled-at-boot-time;
+ rs485-rts-delay = <0 0>;
+ };
+
+ usart3: serial@fffd0000 {
+ status = "okay";
+ linux,rs485-enabled-at-boot-time;
+ rs485-rts-delay = <0 0>;
+ };
+
+ macb0: ethernet@fffc4000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ usb1: gadget@fffa4000 {
+ atmel,vbus-gpio = <&pioC 15 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+ };
+
+ usb0: ohci@00500000 {
+ num-ports = <2>;
+ status = "okay";
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ status = "okay";
+
+ bootstrap@0 {
+ label = "bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ uboot@40000 {
+ label = "uboot";
+ reg = <0x40000 0x80000>;
+ };
+ ubootenv@c0000 {
+ label = "ubootenv";
+ reg = <0xc0000 0x40000>;
+ };
+ kernel@100000 {
+ label = "kernel";
+ reg = <0x100000 0x400000>;
+ };
+ rootfs@500000 {
+ label = "rootfs";
+ reg = <0x500000 0x7b00000>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ red {
+ gpios = <&pioC 10 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "none";
+ };
+
+ green {
+ gpios = <&pioA 5 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "none";
+ default-state = "on";
+ };
+
+ yellow {
+ gpios = <&pioB 20 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "none";
+ };
+
+ blue {
+ gpios = <&pioB 21 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "none";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/alphascale-asm9260-devkit.dts b/arch/arm/boot/dts/alphascale-asm9260-devkit.dts
new file mode 100644
index 000000000..c77e2c902
--- /dev/null
+++ b/arch/arm/boot/dts/alphascale-asm9260-devkit.dts
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * Licensed under the X11 license or the GPL v2 (or later)
+ */
+
+/dts-v1/;
+#include "alphascale-asm9260.dtsi"
+
+/ {
+ model = "Alphascale asm9260 Development Kit";
+ compatible = "alphascale,asm9260devkit", "alphascale,asm9260";
+};
diff --git a/arch/arm/boot/dts/alphascale-asm9260.dtsi b/arch/arm/boot/dts/alphascale-asm9260.dtsi
new file mode 100644
index 000000000..907fc7bfc
--- /dev/null
+++ b/arch/arm/boot/dts/alphascale-asm9260.dtsi
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * Licensed under the X11 license or the GPL v2 (or later)
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/alphascale,asm9260.h>
+
+/ {
+ interrupt-parent = <&icoll>;
+
+ memory {
+ device_type = "memory";
+ reg = <0x20000000 0x2000000>;
+ };
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm926ej-s";
+ device_type = "cpu";
+ clocks = <&acc CLKID_SYS_CPU>;
+ };
+ };
+
+ osc24m: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-accuracy = <30000>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+
+ acc: clock-controller@80040000 {
+ compatible = "alphascale,asm9260-clock-controller";
+ #clock-cells = <1>;
+ clocks = <&osc24m>;
+ reg = <0x80040000 0x204>;
+ };
+
+ icoll: interrupt-controller@80054000 {
+ compatible = "alphascale,asm9260-icoll";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x80054000 0x200>;
+ };
+
+ timer0: timer@80088000 {
+ compatible = "alphascale,asm9260-timer";
+ reg = <0x80088000 0x4000>;
+ clocks = <&acc CLKID_AHB_TIMER0>;
+ interrupts = <29>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/alpine-db.dts b/arch/arm/boot/dts/alpine-db.dts
new file mode 100644
index 000000000..dfb5a0802
--- /dev/null
+++ b/arch/arm/boot/dts/alpine-db.dts
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2015 Annapurna Labs Ltd.
+ *
+ * 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.
+ *
+ * Alternatively, redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 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.
+ *
+ */
+
+/dts-v1/;
+
+#include "alpine.dtsi"
+
+/ {
+ model = "Annapurna Labs Alpine Dev Board";
+ /* no need for anything outside SOC */
+};
+
diff --git a/arch/arm/boot/dts/alpine.dtsi b/arch/arm/boot/dts/alpine.dtsi
new file mode 100644
index 000000000..9af2d60e9
--- /dev/null
+++ b/arch/arm/boot/dts/alpine.dtsi
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2015 Annapurna Labs Ltd.
+ *
+ * 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.
+ *
+ * Alternatively, redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 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.
+ *
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "skeleton64.dtsi"
+
+/ {
+ /* SOC compatibility */
+ compatible = "al,alpine";
+
+ /* CPU Configuration */
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "al,alpine-smp";
+
+ cpu@0 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <0>;
+ clock-frequency = <0>; /* Filled by loader */
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <1>;
+ clock-frequency = <0>; /* Filled by loader */
+ };
+
+ cpu@2 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <2>;
+ clock-frequency = <0>; /* Filled by loader */
+ };
+
+ cpu@3 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <3>;
+ clock-frequency = <0>; /* Filled by loader */
+ };
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+ ranges;
+
+ arch-timer {
+ compatible = "arm,cortex-a15-timer",
+ "arm,armv7-timer";
+ interrupts =
+ <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ clock-frequency = <0>; /* Filled by loader */
+ };
+
+ /* Interrupt Controller */
+ gic: gic@fb001000 {
+ compatible = "arm,cortex-a15-gic";
+ #interrupt-cells = <3>;
+ #size-cells = <0>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x0 0xfb001000 0x0 0x1000>,
+ <0x0 0xfb002000 0x0 0x2000>,
+ <0x0 0xfb004000 0x0 0x1000>,
+ <0x0 0xfb006000 0x0 0x2000>;
+ interrupts =
+ <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ /* CPU Resume registers */
+ cpu-resume@fbff5ec0 {
+ compatible = "al,alpine-cpu-resume";
+ reg = <0x0 0xfbff5ec0 0x0 0x30>;
+ };
+
+ /* North Bridge Service Registers */
+ sysfabric-service@fb070000 {
+ compatible = "al,alpine-sysfabric-service", "syscon";
+ reg = <0x0 0xfb070000 0x0 0x10000>;
+ };
+
+ /* Performance Monitor Unit */
+ pmu {
+ compatible = "arm,cortex-a15-pmu";
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ uart0:uart@fd883000 {
+ compatible = "ns16550a";
+ reg = <0x0 0xfd883000 0x0 0x1000>;
+ clock-frequency = <0>; /* Filled by loader */
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ uart1:uart@0xfd884000 {
+ compatible = "ns16550a";
+ reg = <0x0 0xfd884000 0x0 0x1000>;
+ clock-frequency = <0>; /* Filled by loader */
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ /* Internal PCIe Controller */
+ pcie-internal@0xfbc00000 {
+ compatible = "pci-host-ecam-generic";
+ device_type = "pci";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ #interrupt-cells = <1>;
+ reg = <0x0 0xfbc00000 0x0 0x100000>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ /* Add legacy interrupts for SATA devices only */
+ interrupt-map = <0x4000 0 0 1 &gic 0 43 4>,
+ <0x4800 0 0 1 &gic 0 44 4>;
+
+ /* 32 bit non prefetchable memory space */
+ ranges = <0x02000000 0x0 0xfe000000 0x0 0xfe000000 0x0 0x1000000>;
+
+ bus-range = <0x00 0x00>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/am335x-base0033.dts b/arch/arm/boot/dts/am335x-base0033.dts
new file mode 100644
index 000000000..72a9b3fc4
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-base0033.dts
@@ -0,0 +1,95 @@
+/*
+ * am335x-base0033.dts - Device Tree file for IGEP AQUILA EXPANSION
+ *
+ * Copyright (C) 2013 ISEE 2007 SL - http://www.isee.biz
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "am335x-igep0033.dtsi"
+
+/ {
+ model = "IGEP COM AM335x on AQUILA Expansion";
+ compatible = "isee,am335x-base0033", "isee,am335x-igep0033", "ti,am33xx";
+
+ hdmi {
+ compatible = "ti,tilcdc,slave";
+ i2c = <&i2c0>;
+ pinctrl-names = "default", "off";
+ pinctrl-0 = <&nxp_hdmi_pins>;
+ pinctrl-1 = <&nxp_hdmi_off_pins>;
+ status = "okay";
+ };
+
+ leds_base {
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_base_pins>;
+
+ compatible = "gpio-leds";
+
+ led@0 {
+ label = "base:red:user";
+ gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>; /* gpio1_21 */
+ default-state = "off";
+ };
+
+ led@1 {
+ label = "base:green:user";
+ gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>; /* gpio2_0 */
+ default-state = "off";
+ };
+ };
+};
+
+&am33xx_pinmux {
+ nxp_hdmi_pins: pinmux_nxp_hdmi_pins {
+ pinctrl-single,pins = <
+ 0x1b0 (PIN_OUTPUT | MUX_MODE3) /* xdma_event_intr0.clkout1 */
+ 0xa0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data0 */
+ 0xa4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data1 */
+ 0xa8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data2 */
+ 0xac (PIN_OUTPUT | MUX_MODE0) /* lcd_data3 */
+ 0xb0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data4 */
+ 0xb4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data5 */
+ 0xb8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data6 */
+ 0xbc (PIN_OUTPUT | MUX_MODE0) /* lcd_data7 */
+ 0xc0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data8 */
+ 0xc4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data9 */
+ 0xc8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data10 */
+ 0xcc (PIN_OUTPUT | MUX_MODE0) /* lcd_data11 */
+ 0xd0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data12 */
+ 0xd4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data13 */
+ 0xd8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data14 */
+ 0xdc (PIN_OUTPUT | MUX_MODE0) /* lcd_data15 */
+ 0xe0 (PIN_OUTPUT | MUX_MODE0) /* lcd_vsync */
+ 0xe4 (PIN_OUTPUT | MUX_MODE0) /* lcd_hsync */
+ 0xe8 (PIN_OUTPUT | MUX_MODE0) /* lcd_pclk */
+ 0xec (PIN_OUTPUT | MUX_MODE0) /* lcd_ac_bias_en */
+ >;
+ };
+ nxp_hdmi_off_pins: pinmux_nxp_hdmi_off_pins {
+ pinctrl-single,pins = <
+ 0x1b0 (PIN_OUTPUT | MUX_MODE3) /* xdma_event_intr0.clkout1 */
+ >;
+ };
+
+ leds_base_pins: pinmux_leds_base_pins {
+ pinctrl-single,pins = <
+ 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */
+ 0x88 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn3.gpio2_0 */
+ >;
+ };
+};
+
+&lcdc {
+ status = "okay";
+};
+
+&i2c0 {
+ eeprom: eeprom@50 {
+ compatible = "at,24c256";
+ reg = <0x50>;
+ };
+};
diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
new file mode 100644
index 000000000..dbb3f4d2b
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/ {
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&dcdc2_reg>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ leds {
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_leds_s0>;
+
+ compatible = "gpio-leds";
+
+ led@2 {
+ label = "beaglebone:green:heartbeat";
+ gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+
+ led@3 {
+ label = "beaglebone:green:mmc0";
+ gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "mmc0";
+ default-state = "off";
+ };
+
+ led@4 {
+ label = "beaglebone:green:usr2";
+ gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "cpu0";
+ default-state = "off";
+ };
+
+ led@5 {
+ label = "beaglebone:green:usr3";
+ gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "mmc1";
+ default-state = "off";
+ };
+ };
+
+ vmmcsd_fixed: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsd_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&am33xx_pinmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&clkout2_pin>;
+
+ user_leds_s0: user_leds_s0 {
+ pinctrl-single,pins = <
+ 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */
+ 0x58 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a6.gpio1_22 */
+ 0x5c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a7.gpio1_23 */
+ 0x60 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a8.gpio1_24 */
+ >;
+ };
+
+ i2c0_pins: pinmux_i2c0_pins {
+ pinctrl-single,pins = <
+ 0x188 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ 0x18c (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ >;
+ };
+
+ uart0_pins: pinmux_uart0_pins {
+ pinctrl-single,pins = <
+ 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+ >;
+ };
+
+ clkout2_pin: pinmux_clkout2_pin {
+ pinctrl-single,pins = <
+ 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */
+ >;
+ };
+
+ cpsw_default: cpsw_default {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ 0x110 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxerr.mii1_rxerr */
+ 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txen.mii1_txen */
+ 0x118 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxdv.mii1_rxdv */
+ 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd3.mii1_txd3 */
+ 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd2.mii1_txd2 */
+ 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd1.mii1_txd1 */
+ 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd0.mii1_txd0 */
+ 0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_txclk.mii1_txclk */
+ 0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxclk.mii1_rxclk */
+ 0x134 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd3.mii1_rxd3 */
+ 0x138 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd2.mii1_rxd2 */
+ 0x13c (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd1.mii1_rxd1 */
+ 0x140 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd0.mii1_rxd0 */
+ >;
+ };
+
+ cpsw_sleep: cpsw_sleep {
+ pinctrl-single,pins = <
+ /* Slave 1 reset value */
+ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ davinci_mdio_default: davinci_mdio_default {
+ pinctrl-single,pins = <
+ /* MDIO */
+ 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
+ >;
+ };
+
+ davinci_mdio_sleep: davinci_mdio_sleep {
+ pinctrl-single,pins = <
+ /* MDIO reset value */
+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ 0x160 (PIN_INPUT | MUX_MODE7) /* GPIO0_6 */
+ >;
+ };
+
+ emmc_pins: pinmux_emmc_pins {
+ pinctrl-single,pins = <
+ 0x80 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+ 0x84 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+ 0x00 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+ 0x04 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+ 0x08 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+ 0x0c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+ 0x10 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
+ 0x14 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
+ 0x18 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
+ 0x1c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
+ >;
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+
+ status = "okay";
+};
+
+&usb {
+ status = "okay";
+};
+
+&usb_ctrl_mod {
+ status = "okay";
+};
+
+&usb0_phy {
+ status = "okay";
+};
+
+&usb1_phy {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+ dr_mode = "peripheral";
+};
+
+&usb1 {
+ status = "okay";
+ dr_mode = "host";
+};
+
+&cppi41dma {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+
+ status = "okay";
+ clock-frequency = <400000>;
+
+ tps: tps@24 {
+ reg = <0x24>;
+ };
+
+};
+
+/include/ "tps65217.dtsi"
+
+&tps {
+ /*
+ * Configure pmic to enter OFF-state instead of SLEEP-state ("RTC-only
+ * mode") at poweroff. Most BeagleBone versions do not support RTC-only
+ * mode and risk hardware damage if this mode is entered.
+ *
+ * For details, see linux-omap mailing list May 2015 thread
+ * [PATCH] ARM: dts: am335x-bone* enable pmic-shutdown-controller
+ * In particular, messages:
+ * http://www.spinics.net/lists/linux-omap/msg118585.html
+ * http://www.spinics.net/lists/linux-omap/msg118615.html
+ *
+ * You can override this later with
+ * &tps { /delete-property/ ti,pmic-shutdown-controller; }
+ * if you want to use RTC-only mode and made sure you are not affected
+ * by the hardware problems. (Tip: double-check by performing a current
+ * measurement after shutdown: it should be less than 1 mA.)
+ */
+ ti,pmic-shutdown-controller;
+
+ regulators {
+ dcdc1_reg: regulator@0 {
+ regulator-name = "vdds_dpr";
+ regulator-always-on;
+ };
+
+ dcdc2_reg: regulator@1 {
+ /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
+ regulator-name = "vdd_mpu";
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <1325000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ dcdc3_reg: regulator@2 {
+ /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
+ regulator-name = "vdd_core";
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1_reg: regulator@3 {
+ regulator-name = "vio,vrtc,vdds";
+ regulator-always-on;
+ };
+
+ ldo2_reg: regulator@4 {
+ regulator-name = "vdd_3v3aux";
+ regulator-always-on;
+ };
+
+ ldo3_reg: regulator@5 {
+ regulator-name = "vdd_1v8";
+ regulator-always-on;
+ };
+
+ ldo4_reg: regulator@6 {
+ regulator-name = "vdd_3v3a";
+ regulator-always-on;
+ };
+ };
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <0>;
+ phy-mode = "mii";
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <1>;
+ phy-mode = "mii";
+};
+
+&mac {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ status = "okay";
+};
+
+&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
+ status = "okay";
+};
+
+&mmc1 {
+ status = "okay";
+ bus-width = <0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+};
+
+&aes {
+ status = "okay";
+};
+
+&sham {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts
new file mode 100644
index 000000000..6b8493720
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-bone.dts
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include "am335x-bone-common.dtsi"
+
+/ {
+ model = "TI AM335x BeagleBone";
+ compatible = "ti,am335x-bone", "ti,am33xx";
+};
+
+&ldo3_reg {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+};
+
+&mmc1 {
+ vmmc-supply = <&ldo3_reg>;
+};
diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts
new file mode 100644
index 000000000..901739fcb
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-boneblack.dts
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include "am335x-bone-common.dtsi"
+
+/ {
+ model = "TI AM335x BeagleBone Black";
+ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
+};
+
+&ldo3_reg {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+};
+
+&mmc1 {
+ vmmc-supply = <&vmmcsd_fixed>;
+};
+
+&mmc2 {
+ vmmc-supply = <&vmmcsd_fixed>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_pins>;
+ bus-width = <8>;
+ status = "okay";
+};
+
+&am33xx_pinmux {
+ nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins {
+ pinctrl-single,pins = <
+ 0x1b0 0x03 /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */
+ 0xa0 0x08 /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xa4 0x08 /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xa8 0x08 /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xac 0x08 /* lcd_data3.lcd_data3, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xb0 0x08 /* lcd_data4.lcd_data4, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xb4 0x08 /* lcd_data5.lcd_data5, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xb8 0x08 /* lcd_data6.lcd_data6, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xbc 0x08 /* lcd_data7.lcd_data7, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xc0 0x08 /* lcd_data8.lcd_data8, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xc4 0x08 /* lcd_data9.lcd_data9, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xc8 0x08 /* lcd_data10.lcd_data10, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xcc 0x08 /* lcd_data11.lcd_data11, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xd0 0x08 /* lcd_data12.lcd_data12, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xd4 0x08 /* lcd_data13.lcd_data13, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xd8 0x08 /* lcd_data14.lcd_data14, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xdc 0x08 /* lcd_data15.lcd_data15, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xe0 0x00 /* lcd_vsync.lcd_vsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+ 0xe4 0x00 /* lcd_hsync.lcd_hsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+ 0xe8 0x00 /* lcd_pclk.lcd_pclk, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+ 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+ >;
+ };
+ nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins {
+ pinctrl-single,pins = <
+ 0x1b0 0x03 /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */
+ >;
+ };
+};
+
+&lcdc {
+ status = "okay";
+};
+
+/ {
+ hdmi {
+ compatible = "ti,tilcdc,slave";
+ i2c = <&i2c0>;
+ pinctrl-names = "default", "off";
+ pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
+ pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/am335x-chiliboard.dts b/arch/arm/boot/dts/am335x-chiliboard.dts
new file mode 100644
index 000000000..310da20a8
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-chiliboard.dts
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2015 Jablotron s.r.o. -- http://www.jablotron.com/
+ * Author: Rostislav Lisovy <lisovy@jablotron.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.
+ */
+/dts-v1/;
+#include "am335x-chilisom.dtsi"
+
+/ {
+ model = "AM335x Chiliboard";
+ compatible = "grinn,am335x-chiliboard", "grinn,am335x-chilisom",
+ "ti,am33xx";
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_gpio_pins>;
+
+ led0 {
+ label = "led0";
+ gpios = <&gpio3 7 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ linux,default-trigger = "heartbeat";
+ };
+
+ led1 {
+ label = "led1";
+ gpios = <&gpio3 8 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+ };
+};
+
+&am33xx_pinmux {
+ usb1_drvvbus: usb1_drvvbus {
+ pinctrl-single,pins = <
+ 0x234 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* usb1_drvvbus.usb1_drvvbus */
+ >;
+ };
+
+ sd_pins: pinmux_sd_card {
+ pinctrl-single,pins = <
+ 0xf0 (PIN_INPUT | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+ 0xf4 (PIN_INPUT | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+ 0xf8 (PIN_INPUT | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+ 0xfc (PIN_INPUT | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+ 0x100 (PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+ 0x104 (PIN_INPUT | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+ 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+ >;
+ };
+
+ led_gpio_pins: led_gpio_pins {
+ pinctrl-single,pins = <
+ 0x1e4 (PIN_OUTPUT | MUX_MODE7) /* emu0.gpio3_7 */
+ 0x1e8 (PIN_OUTPUT | MUX_MODE7) /* emu1.gpio3_8 */
+ >;
+ };
+};
+
+&ldo4_reg {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+};
+
+/* Ethernet */
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <0>;
+ phy-mode = "rmii";
+};
+
+&phy_sel {
+ rmii-clock-ext;
+};
+
+/* USB */
+&usb {
+ status = "okay";
+};
+
+&usb_ctrl_mod {
+ status = "okay";
+};
+
+&usb1_phy {
+ status = "okay";
+};
+
+&usb1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_drvvbus>;
+
+ status = "okay";
+ dr_mode = "host";
+};
+
+&cppi41dma {
+ status = "okay";
+};
+
+/* microSD */
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd_pins>;
+ vmmc-supply = <&ldo4_reg>;
+ bus-width = <0x4>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/am335x-chilisom.dtsi b/arch/arm/boot/dts/am335x-chilisom.dtsi
new file mode 100644
index 000000000..7e9a34dff
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-chilisom.dtsi
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2015 Jablotron s.r.o. -- http://www.jablotron.com/
+ * Author: Rostislav Lisovy <lisovy@jablotron.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 "am33xx.dtsi"
+
+/ {
+ model = "Grinn AM335x ChiliSOM";
+ compatible = "grinn,am335x-chilisom", "ti,am33xx";
+
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&dcdc2_reg>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>; /* 512 MB */
+ };
+};
+
+&am33xx_pinmux {
+ pinctrl-names = "default";
+
+ i2c0_pins: pinmux_i2c0_pins {
+ pinctrl-single,pins = <
+ 0x188 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ 0x18c (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ >;
+ };
+
+ uart0_pins: pinmux_uart0_pins {
+ pinctrl-single,pins = <
+ 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+ >;
+ };
+
+ cpsw_default: cpsw_default {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_crs.rmii1_crs */
+ 0x110 (PIN_INPUT_PULLUP | MUX_MODE1) /* mii1_rxerr.rmii1_rxerr */
+ 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txen.rmii1_txen */
+ 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd1.rmii1_txd1 */
+ 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd0.rmii1_txd0 */
+ 0x13c (PIN_INPUT_PULLUP | MUX_MODE1) /* mii1_rxd1.rmii1_rxd1 */
+ 0x140 (PIN_INPUT_PULLUP | MUX_MODE1) /* mii1_rxd0.rmii1_rxd0 */
+ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii1_ref_clk.rmii_ref_clk */
+ >;
+ };
+
+ cpsw_sleep: cpsw_sleep {
+ pinctrl-single,pins = <
+ /* Slave 1 reset value */
+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ davinci_mdio_default: davinci_mdio_default {
+ pinctrl-single,pins = <
+ /* mdio_data.mdio_data */
+ 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)
+ /* mdio_clk.mdio_clk */
+ 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ >;
+ };
+
+ davinci_mdio_sleep: davinci_mdio_sleep {
+ pinctrl-single,pins = <
+ /* MDIO reset value */
+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ nandflash_pins: nandflash_pins {
+ pinctrl-single,pins = <
+ 0x00 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
+ 0x04 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
+ 0x08 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
+ 0x0c (PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
+ 0x10 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
+ 0x14 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
+ 0x18 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
+ 0x1c (PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
+
+ 0x70 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
+ 0x7c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
+ 0x90 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
+ 0x94 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
+ 0x98 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_wen.gpmc_wen */
+ 0x9c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_be0n_cle.gpmc_be0n_cle */
+ >;
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+
+ status = "okay";
+ clock-frequency = <400000>;
+
+ tps: tps@24 {
+ reg = <0x24>;
+ };
+
+};
+
+/include/ "tps65217.dtsi"
+
+&tps {
+ regulators {
+ dcdc1_reg: regulator@0 {
+ regulator-name = "vdds_dpr";
+ regulator-always-on;
+ };
+
+ dcdc2_reg: regulator@1 {
+ /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
+ regulator-name = "vdd_mpu";
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <1325000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ dcdc3_reg: regulator@2 {
+ /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
+ regulator-name = "vdd_core";
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1_reg: regulator@3 {
+ regulator-name = "vio,vrtc,vdds";
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo2_reg: regulator@4 {
+ regulator-name = "vdd_3v3aux";
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3_reg: regulator@5 {
+ regulator-name = "vdd_1v8";
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo4_reg: regulator@6 {
+ regulator-name = "vdd_3v3d";
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+};
+
+/* Ethernet MAC */
+&mac {
+ slaves = <1>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ status = "okay";
+};
+
+&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
+ status = "okay";
+};
+
+/* NAND Flash */
+&elm {
+ status = "okay";
+};
+
+&gpmc {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&nandflash_pins>;
+ ranges = <0 0 0x08000000 0x01000000>; /* CS0 0 @addr 0x08000000, size 0x01000000 */
+ nand@0,0 {
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ ti,nand-ecc-opt = "bch8";
+ ti,elm-id = <&elm>;
+ nand-bus-width = <8>;
+ gpmc,device-width = <1>;
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <44>;
+ gpmc,cs-wr-off-ns = <44>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <34>;
+ gpmc,adv-wr-off-ns = <44>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <40>;
+ gpmc,oe-on-ns = <0>;
+ gpmc,oe-off-ns = <54>;
+ gpmc,access-ns = <64>;
+ gpmc,rd-cycle-ns = <82>;
+ gpmc,wr-cycle-ns = <82>;
+ gpmc,wait-on-read = "true";
+ gpmc,wait-on-write = "true";
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
new file mode 100644
index 000000000..66342515d
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -0,0 +1,680 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+
+/ {
+ model = "TI AM335x EVM";
+ compatible = "ti,am335x-evm", "ti,am33xx";
+
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vdd1_reg>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ vbat: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vbat";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ };
+
+ lis3_reg: fixedregulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "lis3_reg";
+ regulator-boot-on;
+ };
+
+ matrix_keypad: matrix_keypad@0 {
+ compatible = "gpio-matrix-keypad";
+ debounce-delay-ms = <5>;
+ col-scan-delay-us = <2>;
+
+ row-gpios = <&gpio1 25 GPIO_ACTIVE_HIGH /* Bank1, pin25 */
+ &gpio1 26 GPIO_ACTIVE_HIGH /* Bank1, pin26 */
+ &gpio1 27 GPIO_ACTIVE_HIGH>; /* Bank1, pin27 */
+
+ col-gpios = <&gpio1 21 GPIO_ACTIVE_HIGH /* Bank1, pin21 */
+ &gpio1 22 GPIO_ACTIVE_HIGH>; /* Bank1, pin22 */
+
+ linux,keymap = <0x0000008b /* MENU */
+ 0x0100009e /* BACK */
+ 0x02000069 /* LEFT */
+ 0x0001006a /* RIGHT */
+ 0x0101001c /* ENTER */
+ 0x0201006c>; /* DOWN */
+ };
+
+ gpio_keys: volume_keys@0 {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ autorepeat;
+
+ switch@9 {
+ label = "volume-up";
+ linux,code = <115>;
+ gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+ gpio-key,wakeup;
+ };
+
+ switch@10 {
+ label = "volume-down";
+ linux,code = <114>;
+ gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
+ gpio-key,wakeup;
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&ecap0 0 50000 0>;
+ brightness-levels = <0 51 53 56 62 75 101 152 255>;
+ default-brightness-level = <8>;
+ };
+
+ panel {
+ compatible = "ti,tilcdc,panel";
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_pins_s0>;
+ panel-info {
+ ac-bias = <255>;
+ ac-bias-intrpt = <0>;
+ dma-burst-sz = <16>;
+ bpp = <32>;
+ fdd = <0x80>;
+ sync-edge = <0>;
+ sync-ctrl = <1>;
+ raster-order = <0>;
+ fifo-th = <0>;
+ };
+
+ display-timings {
+ 800x480p62 {
+ clock-frequency = <30000000>;
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <39>;
+ hback-porch = <39>;
+ hsync-len = <47>;
+ vback-porch = <29>;
+ vfront-porch = <13>;
+ vsync-len = <2>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ };
+ };
+ };
+
+ sound {
+ compatible = "ti,da830-evm-audio";
+ ti,model = "AM335x-EVM";
+ ti,audio-codec = <&tlv320aic3106>;
+ ti,mcasp-controller = <&mcasp1>;
+ ti,codec-clock-rate = <12000000>;
+ ti,audio-routing =
+ "Headphone Jack", "HPLOUT",
+ "Headphone Jack", "HPROUT",
+ "LINE1L", "Line In",
+ "LINE1R", "Line In";
+ };
+};
+
+&am33xx_pinmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&matrix_keypad_s0 &volume_keys_s0 &clkout2_pin>;
+
+ matrix_keypad_s0: matrix_keypad_s0 {
+ pinctrl-single,pins = <
+ 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */
+ 0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a6.gpio1_22 */
+ 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a9.gpio1_25 */
+ 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a10.gpio1_26 */
+ 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.gpio1_27 */
+ >;
+ };
+
+ volume_keys_s0: volume_keys_s0 {
+ pinctrl-single,pins = <
+ 0x150 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* spi0_sclk.gpio0_2 */
+ 0x154 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* spi0_d0.gpio0_3 */
+ >;
+ };
+
+ i2c0_pins: pinmux_i2c0_pins {
+ pinctrl-single,pins = <
+ 0x188 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ 0x18c (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ 0x158 (PIN_INPUT_PULLUP | MUX_MODE2) /* spi0_d1.i2c1_sda */
+ 0x15c (PIN_INPUT_PULLUP | MUX_MODE2) /* spi0_cs0.i2c1_scl */
+ >;
+ };
+
+ uart0_pins: pinmux_uart0_pins {
+ pinctrl-single,pins = <
+ 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+ >;
+ };
+
+ clkout2_pin: pinmux_clkout2_pin {
+ pinctrl-single,pins = <
+ 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */
+ >;
+ };
+
+ nandflash_pins_s0: nandflash_pins_s0 {
+ pinctrl-single,pins = <
+ 0x0 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
+ 0x4 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
+ 0x8 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
+ 0xc (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
+ 0x10 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
+ 0x14 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
+ 0x18 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
+ 0x1c (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
+ 0x70 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
+ 0x74 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_30 */
+ 0x7c (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
+ 0x90 (PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
+ 0x94 (PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
+ 0x98 (PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */
+ 0x9c (PIN_OUTPUT | MUX_MODE0) /* gpmc_be0n_cle.gpmc_be0n_cle */
+ >;
+ };
+
+ ecap0_pins: backlight_pins {
+ pinctrl-single,pins = <
+ 0x164 0x0 /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */
+ >;
+ };
+
+ cpsw_default: cpsw_default {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */
+ 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */
+ 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */
+ 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
+ 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
+ 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */
+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rgmii1_rclk */
+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd3.rgmii1_rd3 */
+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd2.rgmii1_rd2 */
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rd0 */
+ >;
+ };
+
+ cpsw_sleep: cpsw_sleep {
+ pinctrl-single,pins = <
+ /* Slave 1 reset value */
+ 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ davinci_mdio_default: davinci_mdio_default {
+ pinctrl-single,pins = <
+ /* MDIO */
+ 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
+ >;
+ };
+
+ davinci_mdio_sleep: davinci_mdio_sleep {
+ pinctrl-single,pins = <
+ /* MDIO reset value */
+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+ >;
+ };
+
+ lcd_pins_s0: lcd_pins_s0 {
+ pinctrl-single,pins = <
+ 0x20 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad8.lcd_data23 */
+ 0x24 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad9.lcd_data22 */
+ 0x28 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad10.lcd_data21 */
+ 0x2c (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad11.lcd_data20 */
+ 0x30 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad12.lcd_data19 */
+ 0x34 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad13.lcd_data18 */
+ 0x38 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad14.lcd_data17 */
+ 0x3c (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad15.lcd_data16 */
+ 0xa0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */
+ 0xa4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */
+ 0xa8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */
+ 0xac (PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */
+ 0xb0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */
+ 0xb4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */
+ 0xb8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */
+ 0xbc (PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */
+ 0xc0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */
+ 0xc4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */
+ 0xc8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */
+ 0xcc (PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */
+ 0xd0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */
+ 0xd4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */
+ 0xd8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */
+ 0xdc (PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */
+ 0xe0 (PIN_OUTPUT | MUX_MODE0) /* lcd_vsync.lcd_vsync */
+ 0xe4 (PIN_OUTPUT | MUX_MODE0) /* lcd_hsync.lcd_hsync */
+ 0xe8 (PIN_OUTPUT | MUX_MODE0) /* lcd_pclk.lcd_pclk */
+ 0xec (PIN_OUTPUT | MUX_MODE0) /* lcd_ac_bias_en.lcd_ac_bias_en */
+ >;
+ };
+
+ am335x_evm_audio_pins: am335x_evm_audio_pins {
+ pinctrl-single,pins = <
+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */
+ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */
+ 0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
+ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
+ >;
+ };
+
+ dcan1_pins_default: dcan1_pins_default {
+ pinctrl-single,pins = <
+ 0x168 (PIN_OUTPUT | MUX_MODE2) /* uart0_ctsn.d_can1_tx */
+ 0x16c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* uart0_rtsn.d_can1_rx */
+ >;
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+
+ status = "okay";
+ clock-frequency = <400000>;
+
+ tps: tps@2d {
+ reg = <0x2d>;
+ };
+};
+
+&usb {
+ status = "okay";
+};
+
+&usb_ctrl_mod {
+ status = "okay";
+};
+
+&usb0_phy {
+ status = "okay";
+};
+
+&usb1_phy {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+ dr_mode = "host";
+};
+
+&cppi41dma {
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+
+ status = "okay";
+ clock-frequency = <100000>;
+
+ lis331dlh: lis331dlh@18 {
+ compatible = "st,lis331dlh", "st,lis3lv02d";
+ reg = <0x18>;
+ Vdd-supply = <&lis3_reg>;
+ Vdd_IO-supply = <&lis3_reg>;
+
+ st,click-single-x;
+ st,click-single-y;
+ st,click-single-z;
+ st,click-thresh-x = <10>;
+ st,click-thresh-y = <10>;
+ st,click-thresh-z = <10>;
+ st,irq1-click;
+ st,irq2-click;
+ st,wakeup-x-lo;
+ st,wakeup-x-hi;
+ st,wakeup-y-lo;
+ st,wakeup-y-hi;
+ st,wakeup-z-lo;
+ st,wakeup-z-hi;
+ st,min-limit-x = <120>;
+ st,min-limit-y = <120>;
+ st,min-limit-z = <140>;
+ st,max-limit-x = <550>;
+ st,max-limit-y = <550>;
+ st,max-limit-z = <750>;
+ };
+
+ tsl2550: tsl2550@39 {
+ compatible = "taos,tsl2550";
+ reg = <0x39>;
+ };
+
+ tmp275: tmp275@48 {
+ compatible = "ti,tmp275";
+ reg = <0x48>;
+ };
+
+ tlv320aic3106: tlv320aic3106@1b {
+ compatible = "ti,tlv320aic3106";
+ reg = <0x1b>;
+ status = "okay";
+
+ /* Regulators */
+ AVDD-supply = <&vaux2_reg>;
+ IOVDD-supply = <&vaux2_reg>;
+ DRVDD-supply = <&vaux2_reg>;
+ DVDD-supply = <&vbat>;
+ };
+};
+
+&lcdc {
+ status = "okay";
+};
+
+&elm {
+ status = "okay";
+};
+
+&epwmss0 {
+ status = "okay";
+
+ ecap0: ecap@48300100 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ecap0_pins>;
+ };
+};
+
+&gpmc {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&nandflash_pins_s0>;
+ ranges = <0 0 0x08000000 0x1000000>; /* CS0: 16MB for NAND */
+ nand@0,0 {
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ ti,nand-ecc-opt = "bch8";
+ ti,elm-id = <&elm>;
+ nand-bus-width = <8>;
+ gpmc,device-width = <1>;
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <44>;
+ gpmc,cs-wr-off-ns = <44>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <34>;
+ gpmc,adv-wr-off-ns = <44>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <40>;
+ gpmc,oe-on-ns = <0>;
+ gpmc,oe-off-ns = <54>;
+ gpmc,access-ns = <64>;
+ gpmc,rd-cycle-ns = <82>;
+ gpmc,wr-cycle-ns = <82>;
+ gpmc,wait-on-read = "true";
+ gpmc,wait-on-write = "true";
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+ /* MTD partition table */
+ /* All SPL-* partitions are sized to minimal length
+ * which can be independently programmable. For
+ * NAND flash this is equal to size of erase-block */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "NAND.SPL";
+ reg = <0x00000000 0x000020000>;
+ };
+ partition@1 {
+ label = "NAND.SPL.backup1";
+ reg = <0x00020000 0x00020000>;
+ };
+ partition@2 {
+ label = "NAND.SPL.backup2";
+ reg = <0x00040000 0x00020000>;
+ };
+ partition@3 {
+ label = "NAND.SPL.backup3";
+ reg = <0x00060000 0x00020000>;
+ };
+ partition@4 {
+ label = "NAND.u-boot-spl-os";
+ reg = <0x00080000 0x00040000>;
+ };
+ partition@5 {
+ label = "NAND.u-boot";
+ reg = <0x000C0000 0x00100000>;
+ };
+ partition@6 {
+ label = "NAND.u-boot-env";
+ reg = <0x001C0000 0x00020000>;
+ };
+ partition@7 {
+ label = "NAND.u-boot-env.backup1";
+ reg = <0x001E0000 0x00020000>;
+ };
+ partition@8 {
+ label = "NAND.kernel";
+ reg = <0x00200000 0x00800000>;
+ };
+ partition@9 {
+ label = "NAND.file-system";
+ reg = <0x00A00000 0x0F600000>;
+ };
+ };
+};
+
+#include "tps65910.dtsi"
+
+&mcasp1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&am335x_evm_audio_pins>;
+
+ status = "okay";
+
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ tdm-slots = <2>;
+ /* 4 serializers */
+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+ 0 0 1 2
+ >;
+ tx-num-evt = <32>;
+ rx-num-evt = <32>;
+};
+
+&tps {
+ vcc1-supply = <&vbat>;
+ vcc2-supply = <&vbat>;
+ vcc3-supply = <&vbat>;
+ vcc4-supply = <&vbat>;
+ vcc5-supply = <&vbat>;
+ vcc6-supply = <&vbat>;
+ vcc7-supply = <&vbat>;
+ vccio-supply = <&vbat>;
+
+ regulators {
+ vrtc_reg: regulator@0 {
+ regulator-always-on;
+ };
+
+ vio_reg: regulator@1 {
+ regulator-always-on;
+ };
+
+ vdd1_reg: regulator@2 {
+ /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
+ regulator-name = "vdd_mpu";
+ regulator-min-microvolt = <912500>;
+ regulator-max-microvolt = <1312500>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd2_reg: regulator@3 {
+ /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
+ regulator-name = "vdd_core";
+ regulator-min-microvolt = <912500>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd3_reg: regulator@4 {
+ regulator-always-on;
+ };
+
+ vdig1_reg: regulator@5 {
+ regulator-always-on;
+ };
+
+ vdig2_reg: regulator@6 {
+ regulator-always-on;
+ };
+
+ vpll_reg: regulator@7 {
+ regulator-always-on;
+ };
+
+ vdac_reg: regulator@8 {
+ regulator-always-on;
+ };
+
+ vaux1_reg: regulator@9 {
+ regulator-always-on;
+ };
+
+ vaux2_reg: regulator@10 {
+ regulator-always-on;
+ };
+
+ vaux33_reg: regulator@11 {
+ regulator-always-on;
+ };
+
+ vmmc_reg: regulator@12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+};
+
+&mac {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ status = "okay";
+};
+
+&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
+ status = "okay";
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <0>;
+ phy-mode = "rgmii-txid";
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <1>;
+ phy-mode = "rgmii-txid";
+};
+
+&tscadc {
+ status = "okay";
+ tsc {
+ ti,wires = <4>;
+ ti,x-plate-resistance = <200>;
+ ti,coordinate-readouts = <5>;
+ ti,wire-config = <0x00 0x11 0x22 0x33>;
+ ti,charge-delay = <0x400>;
+ };
+
+ adc {
+ ti,adc-channels = <4 5 6 7>;
+ };
+};
+
+&mmc1 {
+ status = "okay";
+ vmmc-supply = <&vmmc_reg>;
+ bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+};
+
+&sham {
+ status = "okay";
+};
+
+&aes {
+ status = "okay";
+};
+
+&dcan1 {
+ status = "disabled"; /* Enable only if Profile 1 is selected */
+ pinctrl-names = "default";
+ pinctrl-0 = <&dcan1_pins_default>;
+};
diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts
new file mode 100644
index 000000000..156d05efc
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-evmsk.dts
@@ -0,0 +1,691 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/*
+ * AM335x Starter Kit
+ * http://www.ti.com/tool/tmdssk3358
+ */
+
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ model = "TI AM335x EVM-SK";
+ compatible = "ti,am335x-evmsk", "ti,am33xx";
+
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vdd1_reg>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ vbat: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vbat";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ };
+
+ lis3_reg: fixedregulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "lis3_reg";
+ regulator-boot-on;
+ };
+
+ wl12xx_vmmc: fixedregulator@2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wl12xx_gpio>;
+ compatible = "regulator-fixed";
+ regulator-name = "vwl1271";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio1 29 0>;
+ startup-delay-us = <70000>;
+ enable-active-high;
+ };
+
+ vtt_fixed: fixedregulator@3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vtt";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ gpio = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ };
+
+ leds {
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_leds_s0>;
+
+ compatible = "gpio-leds";
+
+ led@1 {
+ label = "evmsk:green:usr0";
+ gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led@2 {
+ label = "evmsk:green:usr1";
+ gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led@3 {
+ label = "evmsk:green:mmc0";
+ gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "mmc0";
+ default-state = "off";
+ };
+
+ led@4 {
+ label = "evmsk:green:heartbeat";
+ gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+ };
+
+ gpio_buttons: gpio_buttons@0 {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ switch@1 {
+ label = "button0";
+ linux,code = <0x100>;
+ gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+ };
+
+ switch@2 {
+ label = "button1";
+ linux,code = <0x101>;
+ gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ switch@3 {
+ label = "button2";
+ linux,code = <0x102>;
+ gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>;
+ gpio-key,wakeup;
+ };
+
+ switch@4 {
+ label = "button3";
+ linux,code = <0x103>;
+ gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&ecap2 0 50000 PWM_POLARITY_INVERTED>;
+ brightness-levels = <0 58 61 66 75 90 125 170 255>;
+ default-brightness-level = <8>;
+ };
+
+ sound {
+ compatible = "ti,da830-evm-audio";
+ ti,model = "AM335x-EVMSK";
+ ti,audio-codec = <&tlv320aic3106>;
+ ti,mcasp-controller = <&mcasp1>;
+ ti,codec-clock-rate = <24000000>;
+ ti,audio-routing =
+ "Headphone Jack", "HPLOUT",
+ "Headphone Jack", "HPROUT";
+ };
+
+ panel {
+ compatible = "ti,tilcdc,panel";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&lcd_pins_default>;
+ pinctrl-1 = <&lcd_pins_sleep>;
+ status = "okay";
+ panel-info {
+ ac-bias = <255>;
+ ac-bias-intrpt = <0>;
+ dma-burst-sz = <16>;
+ bpp = <32>;
+ fdd = <0x80>;
+ sync-edge = <0>;
+ sync-ctrl = <1>;
+ raster-order = <0>;
+ fifo-th = <0>;
+ };
+ display-timings {
+ 480x272 {
+ hactive = <480>;
+ vactive = <272>;
+ hback-porch = <43>;
+ hfront-porch = <8>;
+ hsync-len = <4>;
+ vback-porch = <12>;
+ vfront-porch = <4>;
+ vsync-len = <10>;
+ clock-frequency = <9000000>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ };
+ };
+ };
+};
+
+&am33xx_pinmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_keys_s0 &clkout2_pin>;
+
+ lcd_pins_default: lcd_pins_default {
+ pinctrl-single,pins = <
+ 0x20 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad8.lcd_data23 */
+ 0x24 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad9.lcd_data22 */
+ 0x28 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad10.lcd_data21 */
+ 0x2c (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad11.lcd_data20 */
+ 0x30 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad12.lcd_data19 */
+ 0x34 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad13.lcd_data18 */
+ 0x38 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad14.lcd_data17 */
+ 0x3c (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad15.lcd_data16 */
+ 0xa0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */
+ 0xa4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */
+ 0xa8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */
+ 0xac (PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */
+ 0xb0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */
+ 0xb4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */
+ 0xb8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */
+ 0xbc (PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */
+ 0xc0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */
+ 0xc4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */
+ 0xc8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */
+ 0xcc (PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */
+ 0xd0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */
+ 0xd4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */
+ 0xd8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */
+ 0xdc (PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */
+ 0xe0 (PIN_OUTPUT | MUX_MODE0) /* lcd_vsync.lcd_vsync */
+ 0xe4 (PIN_OUTPUT | MUX_MODE0) /* lcd_hsync.lcd_hsync */
+ 0xe8 (PIN_OUTPUT | MUX_MODE0) /* lcd_pclk.lcd_pclk */
+ 0xec (PIN_OUTPUT | MUX_MODE0) /* lcd_ac_bias_en.lcd_ac_bias_en */
+ >;
+ };
+
+ lcd_pins_sleep: lcd_pins_sleep {
+ pinctrl-single,pins = <
+ 0x20 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad8.lcd_data23 */
+ 0x24 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad9.lcd_data22 */
+ 0x28 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad10.lcd_data21 */
+ 0x2c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad11.lcd_data20 */
+ 0x30 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad12.lcd_data19 */
+ 0x34 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad13.lcd_data18 */
+ 0x38 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad14.lcd_data17 */
+ 0x3c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad15.lcd_data16 */
+ 0xa0 (PULL_DISABLE | MUX_MODE7) /* lcd_data0.lcd_data0 */
+ 0xa4 (PULL_DISABLE | MUX_MODE7) /* lcd_data1.lcd_data1 */
+ 0xa8 (PULL_DISABLE | MUX_MODE7) /* lcd_data2.lcd_data2 */
+ 0xac (PULL_DISABLE | MUX_MODE7) /* lcd_data3.lcd_data3 */
+ 0xb0 (PULL_DISABLE | MUX_MODE7) /* lcd_data4.lcd_data4 */
+ 0xb4 (PULL_DISABLE | MUX_MODE7) /* lcd_data5.lcd_data5 */
+ 0xb8 (PULL_DISABLE | MUX_MODE7) /* lcd_data6.lcd_data6 */
+ 0xbc (PULL_DISABLE | MUX_MODE7) /* lcd_data7.lcd_data7 */
+ 0xc0 (PULL_DISABLE | MUX_MODE7) /* lcd_data8.lcd_data8 */
+ 0xc4 (PULL_DISABLE | MUX_MODE7) /* lcd_data9.lcd_data9 */
+ 0xc8 (PULL_DISABLE | MUX_MODE7) /* lcd_data10.lcd_data10 */
+ 0xcc (PULL_DISABLE | MUX_MODE7) /* lcd_data11.lcd_data11 */
+ 0xd0 (PULL_DISABLE | MUX_MODE7) /* lcd_data12.lcd_data12 */
+ 0xd4 (PULL_DISABLE | MUX_MODE7) /* lcd_data13.lcd_data13 */
+ 0xd8 (PULL_DISABLE | MUX_MODE7) /* lcd_data14.lcd_data14 */
+ 0xdc (PULL_DISABLE | MUX_MODE7) /* lcd_data15.lcd_data15 */
+ 0xe0 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_vsync.lcd_vsync */
+ 0xe4 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_hsync.lcd_hsync */
+ 0xe8 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_pclk.lcd_pclk */
+ 0xec (PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_ac_bias_en.lcd_ac_bias_en */
+ >;
+ };
+
+
+ user_leds_s0: user_leds_s0 {
+ pinctrl-single,pins = <
+ 0x10 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad4.gpio1_4 */
+ 0x14 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad5.gpio1_5 */
+ 0x18 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad6.gpio1_6 */
+ 0x1c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad7.gpio1_7 */
+ >;
+ };
+
+ gpio_keys_s0: gpio_keys_s0 {
+ pinctrl-single,pins = <
+ 0x94 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_oen_ren.gpio2_3 */
+ 0x90 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_advn_ale.gpio2_2 */
+ 0x70 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_wait0.gpio0_30 */
+ 0x9c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ben0_cle.gpio2_5 */
+ >;
+ };
+
+ i2c0_pins: pinmux_i2c0_pins {
+ pinctrl-single,pins = <
+ 0x188 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ 0x18c (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ >;
+ };
+
+ uart0_pins: pinmux_uart0_pins {
+ pinctrl-single,pins = <
+ 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+ >;
+ };
+
+ clkout2_pin: pinmux_clkout2_pin {
+ pinctrl-single,pins = <
+ 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */
+ >;
+ };
+
+ ecap2_pins: backlight_pins {
+ pinctrl-single,pins = <
+ 0x19c 0x4 /* mcasp0_ahclkr.ecap2_in_pwm2_out MODE4 */
+ >;
+ };
+
+ cpsw_default: cpsw_default {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */
+ 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */
+ 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */
+ 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
+ 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
+ 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */
+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rgmii1_rclk */
+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd3.rgmii1_rd3 */
+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd2.rgmii1_rd2 */
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rd0 */
+
+ /* Slave 2 */
+ 0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a0.rgmii2_tctl */
+ 0x44 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a1.rgmii2_rctl */
+ 0x48 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a2.rgmii2_td3 */
+ 0x4c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a3.rgmii2_td2 */
+ 0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a4.rgmii2_td1 */
+ 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a5.rgmii2_td0 */
+ 0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a6.rgmii2_tclk */
+ 0x5c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a7.rgmii2_rclk */
+ 0x60 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a8.rgmii2_rd3 */
+ 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a9.rgmii2_rd2 */
+ 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a10.rgmii2_rd1 */
+ 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a11.rgmii2_rd0 */
+ >;
+ };
+
+ cpsw_sleep: cpsw_sleep {
+ pinctrl-single,pins = <
+ /* Slave 1 reset value */
+ 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+
+ /* Slave 2 reset value*/
+ 0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x44 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x48 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x4c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x58 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x5c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x60 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ davinci_mdio_default: davinci_mdio_default {
+ pinctrl-single,pins = <
+ /* MDIO */
+ 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
+ >;
+ };
+
+ davinci_mdio_sleep: davinci_mdio_sleep {
+ pinctrl-single,pins = <
+ /* MDIO reset value */
+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+ >;
+ };
+
+ mcasp1_pins: mcasp1_pins {
+ pinctrl-single,pins = <
+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */
+ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */
+ 0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
+ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
+ >;
+ };
+
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ 0x74 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_31 */
+ 0x80 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+ 0x84 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+ 0x00 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+ 0x04 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+ 0x08 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+ 0x0c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+ >;
+ };
+
+ wl12xx_gpio: pinmux_wl12xx_gpio {
+ pinctrl-single,pins = <
+ 0x7c (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_csn0.gpio1_29 */
+ >;
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+
+ status = "okay";
+ clock-frequency = <400000>;
+
+ tps: tps@2d {
+ reg = <0x2d>;
+ };
+
+ lis331dlh: lis331dlh@18 {
+ compatible = "st,lis331dlh", "st,lis3lv02d";
+ reg = <0x18>;
+ Vdd-supply = <&lis3_reg>;
+ Vdd_IO-supply = <&lis3_reg>;
+
+ st,click-single-x;
+ st,click-single-y;
+ st,click-single-z;
+ st,click-thresh-x = <10>;
+ st,click-thresh-y = <10>;
+ st,click-thresh-z = <10>;
+ st,irq1-click;
+ st,irq2-click;
+ st,wakeup-x-lo;
+ st,wakeup-x-hi;
+ st,wakeup-y-lo;
+ st,wakeup-y-hi;
+ st,wakeup-z-lo;
+ st,wakeup-z-hi;
+ st,min-limit-x = <120>;
+ st,min-limit-y = <120>;
+ st,min-limit-z = <140>;
+ st,max-limit-x = <550>;
+ st,max-limit-y = <550>;
+ st,max-limit-z = <750>;
+ };
+
+ tlv320aic3106: tlv320aic3106@1b {
+ compatible = "ti,tlv320aic3106";
+ reg = <0x1b>;
+ status = "okay";
+
+ /* Regulators */
+ AVDD-supply = <&vaux2_reg>;
+ IOVDD-supply = <&vaux2_reg>;
+ DRVDD-supply = <&vaux2_reg>;
+ DVDD-supply = <&vbat>;
+ };
+};
+
+&usb {
+ status = "okay";
+};
+
+&usb_ctrl_mod {
+ status = "okay";
+};
+
+&usb0_phy {
+ status = "okay";
+};
+
+&usb1_phy {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+ dr_mode = "host";
+};
+
+&cppi41dma {
+ status = "okay";
+};
+
+&epwmss2 {
+ status = "okay";
+
+ ecap2: ecap@48304100 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ecap2_pins>;
+ };
+};
+
+#include "tps65910.dtsi"
+
+&tps {
+ vcc1-supply = <&vbat>;
+ vcc2-supply = <&vbat>;
+ vcc3-supply = <&vbat>;
+ vcc4-supply = <&vbat>;
+ vcc5-supply = <&vbat>;
+ vcc6-supply = <&vbat>;
+ vcc7-supply = <&vbat>;
+ vccio-supply = <&vbat>;
+
+ regulators {
+ vrtc_reg: regulator@0 {
+ regulator-always-on;
+ };
+
+ vio_reg: regulator@1 {
+ regulator-always-on;
+ };
+
+ vdd1_reg: regulator@2 {
+ /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
+ regulator-name = "vdd_mpu";
+ regulator-min-microvolt = <912500>;
+ regulator-max-microvolt = <1312500>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd2_reg: regulator@3 {
+ /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
+ regulator-name = "vdd_core";
+ regulator-min-microvolt = <912500>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd3_reg: regulator@4 {
+ regulator-always-on;
+ };
+
+ vdig1_reg: regulator@5 {
+ regulator-always-on;
+ };
+
+ vdig2_reg: regulator@6 {
+ regulator-always-on;
+ };
+
+ vpll_reg: regulator@7 {
+ regulator-always-on;
+ };
+
+ vdac_reg: regulator@8 {
+ regulator-always-on;
+ };
+
+ vaux1_reg: regulator@9 {
+ regulator-always-on;
+ };
+
+ vaux2_reg: regulator@10 {
+ regulator-always-on;
+ };
+
+ vaux33_reg: regulator@11 {
+ regulator-always-on;
+ };
+
+ vmmc_reg: regulator@12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+};
+
+&mac {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ dual_emac = <1>;
+ status = "okay";
+};
+
+&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
+ status = "okay";
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <0>;
+ phy-mode = "rgmii-txid";
+ dual_emac_res_vlan = <1>;
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <1>;
+ phy-mode = "rgmii-txid";
+ dual_emac_res_vlan = <2>;
+};
+
+&mmc1 {
+ status = "okay";
+ vmmc-supply = <&vmmc_reg>;
+ bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+};
+
+&sham {
+ status = "okay";
+};
+
+&aes {
+ status = "okay";
+};
+
+&gpio0 {
+ ti,no-reset-on-init;
+};
+
+&mmc2 {
+ status = "okay";
+ vmmc-supply = <&wl12xx_vmmc>;
+ ti,non-removable;
+ bus-width = <4>;
+ cap-power-off-card;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1271";
+ reg = <2>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <31 IRQ_TYPE_LEVEL_HIGH>; /* gpio 31 */
+ ref-clock-frequency = <38400000>;
+ };
+};
+
+&mcasp1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcasp1_pins>;
+
+ status = "okay";
+
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ tdm-slots = <2>;
+ /* 4 serializers */
+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+ 0 0 1 2
+ >;
+ tx-num-evt = <32>;
+ rx-num-evt = <32>;
+};
+
+&tscadc {
+ status = "okay";
+ tsc {
+ ti,wires = <4>;
+ ti,x-plate-resistance = <200>;
+ ti,coordinate-readouts = <5>;
+ ti,wire-config = <0x00 0x11 0x22 0x33>;
+ };
+};
+
+&lcdc {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/am335x-igep0033.dtsi b/arch/arm/boot/dts/am335x-igep0033.dtsi
new file mode 100644
index 000000000..c0e113525
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-igep0033.dtsi
@@ -0,0 +1,320 @@
+/*
+ * am335x-igep0033.dtsi - Device Tree file for IGEP COM AQUILA AM335x
+ *
+ * Copyright (C) 2013 ISEE 2007 SL - http://www.isee.biz
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+#include "am33xx.dtsi"
+
+/ {
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vdd1_reg>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ leds {
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_pins>;
+
+ compatible = "gpio-leds";
+
+ led@0 {
+ label = "com:green:user";
+ gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ vbat: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vbat";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ };
+
+ vmmc: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&am33xx_pinmux {
+ i2c0_pins: pinmux_i2c0_pins {
+ pinctrl-single,pins = <
+ 0x188 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ 0x18c (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ >;
+ };
+
+ nandflash_pins: pinmux_nandflash_pins {
+ pinctrl-single,pins = <
+ 0x0 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
+ 0x4 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
+ 0x8 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
+ 0xc (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
+ 0x10 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
+ 0x14 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
+ 0x18 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
+ 0x1c (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
+ 0x70 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
+ 0x74 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_30 */
+ 0x7c (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
+ 0x90 (PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
+ 0x94 (PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
+ 0x98 (PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */
+ 0x9c (PIN_OUTPUT | MUX_MODE0) /* gpmc_be0n_cle.gpmc_be0n_cle */
+ >;
+ };
+
+ uart0_pins: pinmux_uart0_pins {
+ pinctrl-single,pins = <
+ 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+ >;
+ };
+
+ leds_pins: pinmux_leds_pins {
+ pinctrl-single,pins = <
+ 0x5c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a7.gpio1_23 */
+ >;
+ };
+};
+
+&mac {
+ status = "okay";
+};
+
+&davinci_mdio {
+ status = "okay";
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <0>;
+ phy-mode = "rmii";
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <1>;
+ phy-mode = "rmii";
+};
+
+&phy_sel {
+ rmii-clock-ext;
+};
+
+&elm {
+ status = "okay";
+};
+
+&gpmc {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&nandflash_pins>;
+
+ ranges = <0 0 0x08000000 0x1000000>; /* CS0: 16MB for NAND */
+
+ nand@0,0 {
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ nand-bus-width = <8>;
+ ti,nand-ecc-opt = "bch8";
+ gpmc,device-width = <1>;
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <44>;
+ gpmc,cs-wr-off-ns = <44>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <34>;
+ gpmc,adv-wr-off-ns = <44>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <40>;
+ gpmc,oe-on-ns = <0>;
+ gpmc,oe-off-ns = <54>;
+ gpmc,access-ns = <64>;
+ gpmc,rd-cycle-ns = <82>;
+ gpmc,wr-cycle-ns = <82>;
+ gpmc,wait-on-read = "true";
+ gpmc,wait-on-write = "true";
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ elm_id = <&elm>;
+
+ /* MTD partition table */
+ partition@0 {
+ label = "SPL";
+ reg = <0x00000000 0x000080000>;
+ };
+
+ partition@1 {
+ label = "U-boot";
+ reg = <0x00080000 0x001e0000>;
+ };
+
+ partition@2 {
+ label = "U-Boot Env";
+ reg = <0x00260000 0x00020000>;
+ };
+
+ partition@3 {
+ label = "Kernel";
+ reg = <0x00280000 0x00500000>;
+ };
+
+ partition@4 {
+ label = "File System";
+ reg = <0x00780000 0x007880000>;
+ };
+ };
+};
+
+&i2c0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+
+ clock-frequency = <400000>;
+
+ tps: tps@2d {
+ reg = <0x2d>;
+ };
+};
+
+&mmc1 {
+ status = "okay";
+ vmmc-supply = <&vmmc>;
+ bus-width = <4>;
+};
+
+&uart0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+};
+
+&usb {
+ status = "okay";
+};
+
+&usb_ctrl_mod {
+ status = "okay";
+};
+
+&usb0_phy {
+ status = "okay";
+};
+
+&usb1_phy {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+ dr_mode = "host";
+};
+
+&cppi41dma {
+ status = "okay";
+};
+
+#include "tps65910.dtsi"
+
+&tps {
+ vcc1-supply = <&vbat>;
+ vcc2-supply = <&vbat>;
+ vcc3-supply = <&vbat>;
+ vcc4-supply = <&vbat>;
+ vcc5-supply = <&vbat>;
+ vcc6-supply = <&vbat>;
+ vcc7-supply = <&vbat>;
+ vccio-supply = <&vbat>;
+
+ regulators {
+ vrtc_reg: regulator@0 {
+ regulator-always-on;
+ };
+
+ vio_reg: regulator@1 {
+ regulator-always-on;
+ };
+
+ vdd1_reg: regulator@2 {
+ /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
+ regulator-name = "vdd_mpu";
+ regulator-min-microvolt = <912500>;
+ regulator-max-microvolt = <1312500>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd2_reg: regulator@3 {
+ /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
+ regulator-name = "vdd_core";
+ regulator-min-microvolt = <912500>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd3_reg: regulator@4 {
+ regulator-always-on;
+ };
+
+ vdig1_reg: regulator@5 {
+ regulator-always-on;
+ };
+
+ vdig2_reg: regulator@6 {
+ regulator-always-on;
+ };
+
+ vpll_reg: regulator@7 {
+ regulator-always-on;
+ };
+
+ vdac_reg: regulator@8 {
+ regulator-always-on;
+ };
+
+ vaux1_reg: regulator@9 {
+ regulator-always-on;
+ };
+
+ vaux2_reg: regulator@10 {
+ regulator-always-on;
+ };
+
+ vaux33_reg: regulator@11 {
+ regulator-always-on;
+ };
+
+ vmmc_reg: regulator@12 {
+ regulator-always-on;
+ };
+ };
+};
+
diff --git a/arch/arm/boot/dts/am335x-lxm.dts b/arch/arm/boot/dts/am335x-lxm.dts
new file mode 100644
index 000000000..5c5667a36
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-lxm.dts
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2014 NovaTech LLC - http://www.novatechweb.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.
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+
+/ {
+ model = "NovaTech OrionLXm";
+ compatible = "novatech,am335x-lxm", "ti,am33xx";
+
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vdd1_reg>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>; /* 512 MB */
+ };
+
+ /* Power supply provides a fixed 5V @2A */
+ vbat: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vbat";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ };
+
+ /* Power supply provides a fixed 3.3V @3A */
+ vmmcsd_fixed: fixedregulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsd_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ };
+};
+
+&am33xx_pinmux {
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ 0xf0 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat3 */
+ 0xf4 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat2 */
+ 0xf8 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat1 */
+ 0xfc (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat0 */
+ 0x100 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_clk */
+ 0x104 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_cmd */
+ >;
+ };
+
+ i2c0_pins: pinmux_i2c0_pins {
+ pinctrl-single,pins = <
+ 0x188 (PIN_INPUT | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ 0x18c (PIN_INPUT | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ >;
+ };
+
+ cpsw_default: cpsw_default {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_int */
+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* rmii1_crs_dv */
+ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* rmii1_rxer */
+ 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* rmii1_txen */
+ 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* rmii1_td1 */
+ 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* rmii1_td0 */
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* rmii1_rd1 */
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* rmii1_rd0 */
+ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii1_refclk */
+
+ /* Slave 2 */
+ 0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* rmii2_txen */
+ 0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* rmii2_td1 */
+ 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* rmii2_td0 */
+ 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* rmii2_rd1 */
+ 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE3) /* rmii2_rd0 */
+ 0x70 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* rmii2_crs_dv */
+ 0x74 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* rmii2_rxer */
+ 0x78 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_int */
+ 0x108 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* rmii2_refclk */
+ >;
+ };
+
+ cpsw_sleep: cpsw_sleep {
+ pinctrl-single,pins = <
+ /* Slave 1 reset value */
+ 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_int */
+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_crs_dv */
+ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_rxer */
+ 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_txen */
+ 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_td1 */
+ 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_td0 */
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_rd1 */
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_rd0 */
+ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_refclk */
+
+ /* Slave 2 reset value*/
+ 0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_txen */
+ 0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_td1 */
+ 0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_td0 */
+ 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_rd1 */
+ 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_rd0 */
+ 0x70 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_crs_dv */
+ 0x74 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_rxer */
+ 0x78 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_int */
+ 0x108 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_refclk */
+ >;
+ };
+
+ davinci_mdio_default: davinci_mdio_default {
+ pinctrl-single,pins = <
+ /* MDIO */
+ 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
+ >;
+ };
+
+ davinci_mdio_sleep: davinci_mdio_sleep {
+ pinctrl-single,pins = <
+ /* MDIO reset value */
+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ emmc_pins: pinmux_emmc_pins {
+ pinctrl-single,pins = <
+ 0x80 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+ 0x84 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+ 0x00 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+ 0x04 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+ 0x08 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+ 0x0c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+ 0x10 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
+ 0x14 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
+ 0x18 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
+ 0x1c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
+ >;
+ };
+
+ uart0_pins: pinmux_uart0_pins {
+ pinctrl-single,pins = <
+ 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+ >;
+ };
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+
+ status = "okay";
+ clock-frequency = <400000>;
+
+ serial_config1: serial_config1@20 {
+ compatible = "nxp,pca9539";
+ reg = <0x20>;
+ };
+
+ serial_config2: serial_config2@21 {
+ compatible = "nxp,pca9539";
+ reg = <0x21>;
+ };
+
+ tps: tps@2d {
+ compatible = "ti,tps65910";
+ reg = <0x2d>;
+ };
+};
+
+/include/ "tps65910.dtsi"
+
+&tps {
+ vcc1-supply = <&vbat>;
+ vcc2-supply = <&vbat>;
+ vcc3-supply = <&vbat>;
+ vcc4-supply = <&vbat>;
+ vcc5-supply = <&vbat>;
+ vcc6-supply = <&vbat>;
+ vcc7-supply = <&vbat>;
+ vccio-supply = <&vbat>;
+
+ regulators {
+ /* vrtc - unused */
+
+ vio_reg: regulator@1 {
+ regulator-name = "vio_1v5,ddr";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd1_reg: regulator@2 {
+ regulator-name = "vdd1,mpu";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd2_reg: regulator@3 {
+ regulator-name = "vdd2_1v1,core";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ /* vdd3 - unused */
+
+ /* vdig1 - unused */
+
+ vdig2_reg: regulator@6 {
+ regulator-name = "vdig2_1v8,vdds_pll";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ /* vpll - unused */
+
+ vdac_reg: regulator@8 {
+ regulator-name = "vdac_1v8,vdds";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vaux1_reg: regulator@9 {
+ regulator-name = "vaux1_1v8,usb";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vaux2_reg: regulator@10 {
+ regulator-name = "vaux2_3v3,io";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vaux33_reg: regulator@11 {
+ regulator-name = "vaux33_3v3,usb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vmmc_reg: regulator@12 {
+ regulator-name = "vmmc_3v3,io";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+};
+
+&sham {
+ status = "okay";
+};
+
+&aes {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+
+ status = "okay";
+};
+
+&usb {
+ status = "okay";
+};
+
+&usb_ctrl_mod {
+ status = "okay";
+};
+
+&usb0_phy {
+ status = "okay";
+};
+
+&usb1_phy {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+ dr_mode = "host";
+};
+
+&usb1 {
+ status = "okay";
+ dr_mode = "host";
+};
+
+&cppi41dma {
+ status = "okay";
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <5>;
+ phy-mode = "rmii";
+ dual_emac_res_vlan = <2>;
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <4>;
+ phy-mode = "rmii";
+ dual_emac_res_vlan = <3>;
+};
+
+&phy_sel {
+ rmii-clock-ext;
+};
+
+&mac {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ dual_emac = <1>;
+ status = "okay";
+};
+
+&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
+ status = "okay";
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&vmmcsd_fixed>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_pins>;
+ vmmc-supply = <&vmmcsd_fixed>;
+ bus-width = <8>;
+ ti,non-removable;
+ status = "okay";
+};
+
diff --git a/arch/arm/boot/dts/am335x-nano.dts b/arch/arm/boot/dts/am335x-nano.dts
new file mode 100644
index 000000000..5ed4ca6ea
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-nano.dts
@@ -0,0 +1,440 @@
+/*
+ * Copyright (C) 2013 Newflow Ltd - http://www.newflow.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.
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+
+/ {
+ model = "Newflow AM335x NanoBone";
+ compatible = "ti,am33xx";
+
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&dcdc2_reg>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led@0 {
+ label = "nanobone:green:usr1";
+ gpios = <&gpio1 5 0>;
+ default-state = "off";
+ };
+ };
+};
+
+&am33xx_pinmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&misc_pins>;
+
+ misc_pins: misc_pins {
+ pinctrl-single,pins = <
+ 0x15c (PIN_OUTPUT | MUX_MODE7) /* spi0_cs0.gpio0_5 */
+ >;
+ };
+
+ gpmc_pins: gpmc_pins {
+ pinctrl-single,pins = <
+ 0x0 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
+ 0x4 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
+ 0x8 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
+ 0xc (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
+ 0x10 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
+ 0x14 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
+ 0x18 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
+ 0x1c (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
+ 0x20 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad8.gpmc_ad8 */
+ 0x24 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad9.gpmc_ad9 */
+ 0x28 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad10.gpmc_ad10 */
+ 0x2c (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad11.gpmc_ad11 */
+ 0x30 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad12.gpmc_ad12 */
+ 0x34 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad13.gpmc_ad13 */
+ 0x38 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad14.gpmc_ad14 */
+ 0x3c (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad15.gpmc_ad15 */
+
+ 0x70 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
+ 0x7c (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
+ 0x80 (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn1.gpmc_csn1 */
+ 0x84 (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn2.gpmc_csn2 */
+ 0x88 (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn3.gpmc_csn3 */
+
+ 0x90 (PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
+ 0x94 (PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
+ 0x98 (PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */
+ 0x9c (PIN_OUTPUT | MUX_MODE0) /* gpmc_ben0_cle.gpmc_ben0_cle */
+
+ 0xa4 (PIN_OUTPUT | MUX_MODE1) /* lcd_data1.gpmc_a1 */
+ 0xa8 (PIN_OUTPUT | MUX_MODE1) /* lcd_data2.gpmc_a2 */
+ 0xac (PIN_OUTPUT | MUX_MODE1) /* lcd_data3.gpmc_a3 */
+ 0xb0 (PIN_OUTPUT | MUX_MODE1) /* lcd_data4.gpmc_a4 */
+ 0xb4 (PIN_OUTPUT | MUX_MODE1) /* lcd_data5.gpmc_a5 */
+ 0xb8 (PIN_OUTPUT | MUX_MODE1) /* lcd_data6.gpmc_a6 */
+ 0xbc (PIN_OUTPUT | MUX_MODE1) /* lcd_data7.gpmc_a7 */
+
+ 0xe0 (PIN_OUTPUT | MUX_MODE1) /* lcd_vsync.gpmc_a8 */
+ 0xe4 (PIN_OUTPUT | MUX_MODE1) /* lcd_hsync.gpmc_a9 */
+ 0xe8 (PIN_OUTPUT | MUX_MODE1) /* lcd_pclk.gpmc_a10 */
+ >;
+ };
+
+ i2c0_pins: i2c0_pins {
+ pinctrl-single,pins = <
+ 0x188 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ 0x18c (PIN_INPUT_PULLDOWN | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ >;
+ };
+
+ uart0_pins: uart0_pins {
+ pinctrl-single,pins = <
+ 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ 0x174 (PIN_OUTPUT | MUX_MODE0) /* uart0_txd.uart0_txd */
+ >;
+ };
+
+ uart1_pins: uart1_pins {
+ pinctrl-single,pins = <
+ 0x178 (PIN_OUTPUT | MUX_MODE7) /* uart1_ctsn.uart1_ctsn */
+ 0x17c (PIN_OUTPUT | MUX_MODE7) /* uart1_rtsn.uart1_rtsn */
+ 0x180 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rxd.uart1_rxd */
+ 0x184 (PIN_OUTPUT | MUX_MODE0) /* uart1_txd.uart1_txd */
+ >;
+ };
+
+ uart2_pins: uart2_pins {
+ pinctrl-single,pins = <
+ 0xc0 (PIN_INPUT_PULLUP | MUX_MODE7) /* lcd_data8.gpio2[14] */
+ 0xc4 (PIN_OUTPUT | MUX_MODE7) /* lcd_data9.gpio2[15] */
+ 0x150 (PIN_INPUT | MUX_MODE1) /* spi0_sclk.uart2_rxd */
+ 0x154 (PIN_OUTPUT | MUX_MODE1) /* spi0_d0.uart2_txd */
+ >;
+ };
+
+ uart3_pins: uart3_pins {
+ pinctrl-single,pins = <
+ 0xc8 (PIN_INPUT_PULLUP | MUX_MODE6) /* lcd_data10.uart3_ctsn */
+ 0xcc (PIN_OUTPUT | MUX_MODE6) /* lcd_data11.uart3_rtsn */
+ 0x160 (PIN_INPUT | MUX_MODE1) /* spi0_cs1.uart3_rxd */
+ 0x164 (PIN_OUTPUT | MUX_MODE1) /* ecap0_in_pwm0_out.uart3_txd */
+ >;
+ };
+
+ uart4_pins: uart4_pins {
+ pinctrl-single,pins = <
+ 0xd0 (PIN_INPUT_PULLUP | MUX_MODE6) /* lcd_data12.uart4_ctsn */
+ 0xd4 (PIN_OUTPUT | MUX_MODE6) /* lcd_data13.uart4_rtsn */
+ 0x168 (PIN_INPUT | MUX_MODE1) /* uart0_ctsn.uart4_rxd */
+ 0x16c (PIN_OUTPUT | MUX_MODE1) /* uart0_rtsn.uart4_txd */
+ >;
+ };
+
+ uart5_pins: uart5_pins {
+ pinctrl-single,pins = <
+ 0xd8 (PIN_INPUT | MUX_MODE4) /* lcd_data14.uart5_rxd */
+ 0x144 (PIN_OUTPUT | MUX_MODE3) /* rmiii1_refclk.uart5_txd */
+ >;
+ };
+
+ mmc1_pins: mmc1_pins {
+ pinctrl-single,pins = <
+ 0xf0 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+ 0xf4 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+ 0xf8 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+ 0xfc (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+ 0x100 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+ 0x104 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+ 0x1e8 (PIN_INPUT_PULLUP | MUX_MODE7) /* emu1.gpio3[8] */
+ 0x1a0 (PIN_INPUT_PULLUP | MUX_MODE7) /* mcasp0_aclkr.gpio3[18] */
+ >;
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "okay";
+ rts-gpio = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+ rs485-rts-active-high;
+ rs485-rx-during-tx;
+ rs485-rts-delay = <1 1>;
+ linux,rs485-enabled-at-boot-time;
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+ status = "okay";
+ rts-gpio = <&gpio2 15 GPIO_ACTIVE_HIGH>;
+ rs485-rts-active-high;
+ rs485-rts-delay = <1 1>;
+ linux,rs485-enabled-at-boot-time;
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins>;
+ status = "okay";
+};
+
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart5_pins>;
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+ pinctrl-names = "default";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+
+ gpio@20 {
+ compatible = "microchip,mcp23017";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x20>;
+ };
+
+ tps: tps@24 {
+ reg = <0x24>;
+ };
+
+ eeprom@53 {
+ compatible = "microchip,24c02";
+ reg = <0x53>;
+ pagesize = <8>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1307";
+ reg = <0x68>;
+ };
+};
+
+&elm {
+ status = "okay";
+};
+
+&gpmc {
+ compatible = "ti,am3352-gpmc";
+ ti,hwmods = "gpmc";
+ status = "okay";
+ gpmc,num-waitpins = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpmc_pins>;
+
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0x08000000 0x08000000>; /* CS0: NOR 128M */
+
+ nor@0,0 {
+ reg = <0 0x00000000 0x08000000>;
+ compatible = "cfi-flash";
+ linux,mtd-name = "spansion,s29gl010p11t";
+ bank-width = <2>;
+
+ gpmc,mux-add-data = <2>;
+
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <160>;
+ gpmc,cs-wr-off-ns = <160>;
+ gpmc,adv-on-ns = <10>;
+ gpmc,adv-rd-off-ns = <30>;
+ gpmc,adv-wr-off-ns = <30>;
+ gpmc,oe-on-ns = <40>;
+ gpmc,oe-off-ns = <160>;
+ gpmc,we-on-ns = <40>;
+ gpmc,we-off-ns = <160>;
+ gpmc,rd-cycle-ns = <160>;
+ gpmc,wr-cycle-ns = <160>;
+ gpmc,access-ns = <150>;
+ gpmc,page-burst-access-ns = <10>;
+ gpmc,cycle2cycle-samecsen;
+ gpmc,cycle2cycle-delay-ns = <20>;
+ gpmc,wr-data-mux-bus-ns = <70>;
+ gpmc,wr-access-ns = <80>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /*
+ MTD partition table
+ ===================
+ +------------+-->0x00000000-> U-Boot start
+ | |
+ | |-->0x000BFFFF-> U-Boot end
+ | |-->0x000C0000-> ENV1 start
+ | |
+ | |-->0x000DFFFF-> ENV1 end
+ | |-->0x000E0000-> ENV2 start
+ | |
+ | |-->0x000FFFFF-> ENV2 end
+ | |-->0x00100000-> Kernel start
+ | |
+ | |-->0x004FFFFF-> Kernel end
+ | |-->0x00500000-> File system start
+ | |
+ | |-->0x01FFFFFF-> File system end
+ | |-->0x02000000-> User data start
+ | |
+ | |-->0x03FFFFFF-> User data end
+ | |-->0x04000000-> Data storage start
+ | |
+ +------------+-->0x08000000-> NOR end (Free end)
+ */
+ partition@0 {
+ label = "boot";
+ reg = <0x00000000 0x000c0000>; /* 768KB */
+ };
+
+ partition@1 {
+ label = "env1";
+ reg = <0x000c0000 0x00020000>; /* 128KB */
+ };
+
+ partition@2 {
+ label = "env2";
+ reg = <0x000e0000 0x00020000>; /* 128KB */
+ };
+
+ partition@3 {
+ label = "kernel";
+ reg = <0x00100000 0x00400000>; /* 4MB */
+ };
+
+ partition@4 {
+ label = "rootfs";
+ reg = <0x00500000 0x01b00000>; /* 27MB */
+ };
+
+ partition@5 {
+ label = "user";
+ reg = <0x02000000 0x02000000>; /* 32MB */
+ };
+
+ partition@6 {
+ label = "data";
+ reg = <0x04000000 0x04000000>; /* 64MB */
+ };
+ };
+};
+
+&mac {
+ dual_emac;
+ status = "okay";
+};
+
+&davinci_mdio {
+ status = "okay";
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <0>;
+ phy-mode = "mii";
+ dual_emac_res_vlan = <1>;
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <1>;
+ phy-mode = "mii";
+ dual_emac_res_vlan = <2>;
+};
+
+&mmc1 {
+ status = "okay";
+ vmmc-supply = <&ldo4_reg>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ bus-width = <4>;
+ cd-gpios = <&gpio3 8 0>;
+ wp-gpios = <&gpio3 18 0>;
+};
+
+#include "tps65217.dtsi"
+
+&tps {
+ regulators {
+ dcdc1_reg: regulator@0 {
+ /* +1.5V voltage with ±4% tolerance */
+ regulator-min-microvolt = <1450000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ dcdc2_reg: regulator@1 {
+ /* VDD_MPU voltage limits 0.95V - 1.1V with ±4% tolerance */
+ regulator-name = "vdd_mpu";
+ regulator-min-microvolt = <915000>;
+ regulator-max-microvolt = <1140000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ dcdc3_reg: regulator@2 {
+ /* VDD_CORE voltage limits 0.95V - 1.1V with ±4% tolerance */
+ regulator-name = "vdd_core";
+ regulator-min-microvolt = <915000>;
+ regulator-max-microvolt = <1140000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1_reg: regulator@3 {
+ /* +1.8V voltage with ±4% tolerance */
+ regulator-min-microvolt = <1750000>;
+ regulator-max-microvolt = <1870000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo2_reg: regulator@4 {
+ /* +3.3V voltage with ±4% tolerance */
+ regulator-min-microvolt = <3175000>;
+ regulator-max-microvolt = <3430000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3_reg: regulator@5 {
+ /* +1.8V voltage with ±4% tolerance */
+ regulator-min-microvolt = <1750000>;
+ regulator-max-microvolt = <1870000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo4_reg: regulator@6 {
+ /* +3.3V voltage with ±4% tolerance */
+ regulator-min-microvolt = <3175000>;
+ regulator-max-microvolt = <3430000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/am335x-pepper.dts b/arch/arm/boot/dts/am335x-pepper.dts
new file mode 100644
index 000000000..0d35ab646
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-pepper.dts
@@ -0,0 +1,653 @@
+/*
+ * Copyright (C) 2014 Gumstix, Inc. - https://www.gumstix.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.
+ */
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "am33xx.dtsi"
+
+/ {
+ model = "Gumstix Pepper";
+ compatible = "gumstix,am335x-pepper", "ti,am33xx";
+
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&dcdc3_reg>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>; /* 512 MB */
+ };
+
+ buttons: user_buttons {
+ compatible = "gpio-keys";
+ };
+
+ leds: user_leds {
+ compatible = "gpio-leds";
+ };
+
+ panel: lcd_panel {
+ compatible = "ti,tilcdc,panel";
+ };
+
+ sound: sound_iface {
+ compatible = "ti,da830-evm-audio";
+ };
+
+ vbat: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ };
+
+ v3v3c_reg: fixedregulator@1 {
+ compatible = "regulator-fixed";
+ };
+
+ vdd5_reg: fixedregulator@2 {
+ compatible = "regulator-fixed";
+ };
+};
+
+/* I2C Busses */
+&i2c0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+
+ clock-frequency = <400000>;
+
+ tps: tps@24 {
+ reg = <0x24>;
+ };
+
+ eeprom: eeprom@50 {
+ compatible = "at,24c256";
+ reg = <0x50>;
+ };
+
+ audio_codec: tlv320aic3106@1b {
+ compatible = "ti,tlv320aic3106";
+ reg = <0x1b>;
+ };
+
+ accel: lis331dlh@1d {
+ compatible = "st,lis3lv02d";
+ reg = <0x1d>;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <400000>;
+};
+
+&am33xx_pinmux {
+ i2c0_pins: pinmux_i2c0 {
+ pinctrl-single,pins = <
+ 0x188 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ 0x18c (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ >;
+ };
+ i2c1_pins: pinmux_i2c1 {
+ pinctrl-single,pins = <
+ 0x10C (PIN_INPUT_PULLUP | MUX_MODE3) /* mii1_crs,i2c1_sda */
+ 0x110 (PIN_INPUT_PULLUP | MUX_MODE3) /* mii1_rxerr,i2c1_scl */
+ >;
+ };
+};
+
+/* Accelerometer */
+&accel {
+ pinctrl-names = "default";
+ pinctrl-0 = <&accel_pins>;
+
+ Vdd-supply = <&ldo3_reg>;
+ Vdd_IO-supply = <&ldo3_reg>;
+ st,irq1-click;
+ st,wakeup-x-lo;
+ st,wakeup-x-hi;
+ st,wakeup-y-lo;
+ st,wakeup-y-hi;
+ st,wakeup-z-lo;
+ st,wakeup-z-hi;
+ st,min-limit-x = <92>;
+ st,max-limit-x = <14>;
+ st,min-limit-y = <14>;
+ st,max-limit-y = <92>;
+ st,min-limit-z = <92>;
+ st,max-limit-z = <14>;
+};
+
+&am33xx_pinmux {
+ accel_pins: pinmux_accel {
+ pinctrl-single,pins = <
+ 0x98 (PIN_INPUT | MUX_MODE7) /* gpmc_wen.gpio2_4 */
+ >;
+ };
+};
+
+/* Audio */
+&audio_codec {
+ status = "okay";
+
+ gpio-reset = <&gpio1 16 GPIO_ACTIVE_LOW>;
+ AVDD-supply = <&ldo3_reg>;
+ IOVDD-supply = <&ldo3_reg>;
+ DRVDD-supply = <&ldo3_reg>;
+ DVDD-supply = <&dcdc1_reg>;
+};
+
+&sound {
+ ti,model = "AM335x-EVM";
+ ti,audio-codec = <&audio_codec>;
+ ti,mcasp-controller = <&mcasp0>;
+ ti,codec-clock-rate = <12000000>;
+ ti,audio-routing =
+ "Headphone Jack", "HPLOUT",
+ "Headphone Jack", "HPROUT",
+ "LINE1L", "Line In";
+};
+
+&mcasp0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&audio_pins>;
+
+ op-mode = <0>; /* MCASP_ISS_MODE */
+ tdm-slots = <2>;
+ serial-dir = <
+ 1 2 0 0
+ 0 0 0 0
+ 0 0 0 0
+ 0 0 0 0
+ >;
+ tx-num-evt = <1>;
+ rx-num-evt = <1>;
+};
+
+&am33xx_pinmux {
+ audio_pins: pinmux_audio {
+ pinctrl-single,pins = <
+ 0x1AC (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_ahcklx.mcasp0_ahclkx */
+ 0x194 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */
+ 0x190 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */
+ 0x198 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_axr0.mcasp0_axr0 */
+ 0x1A8 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_axr1.mcasp0_axr1 */
+ 0x40 (PIN_OUTPUT | MUX_MODE7) /* gpmc_a0.gpio1_16 */
+ >;
+ };
+};
+
+/* Display: 24-bit LCD Screen */
+&panel {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_pins>;
+ panel-info {
+ ac-bias = <255>;
+ ac-bias-intrpt = <0>;
+ dma-burst-sz = <16>;
+ bpp = <32>;
+ fdd = <0x80>;
+ sync-edge = <0>;
+ sync-ctrl = <1>;
+ raster-order = <0>;
+ fifo-th = <0>;
+ };
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: 480x272 {
+ clock-frequency = <18400000>;
+ hactive = <480>;
+ vactive = <272>;
+ hfront-porch = <8>;
+ hback-porch = <4>;
+ hsync-len = <41>;
+ vfront-porch = <4>;
+ vback-porch = <2>;
+ vsync-len = <10>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ };
+ };
+};
+
+&lcdc {
+ status = "okay";
+};
+
+&am33xx_pinmux {
+ lcd_pins: pinmux_lcd {
+ pinctrl-single,pins = <
+ 0xa0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */
+ 0xa4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */
+ 0xa8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */
+ 0xac (PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */
+ 0xb0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */
+ 0xb4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */
+ 0xb8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */
+ 0xbc (PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */
+ 0xc0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */
+ 0xc4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */
+ 0xc8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */
+ 0xcc (PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */
+ 0xd0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */
+ 0xd4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */
+ 0xd8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */
+ 0xdc (PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */
+ 0x20 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad8.lcd_data16 */
+ 0x24 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad9.lcd_data17 */
+ 0x28 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad10.lcd_data18 */
+ 0x2c (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad11.lcd_data19 */
+ 0x30 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad12.lcd_data20 */
+ 0x34 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad13.lcd_data21 */
+ 0x38 (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad14.lcd_data22 */
+ 0x3c (PIN_OUTPUT | MUX_MODE1) /* gpmc_ad15.lcd_data23 */
+ 0xe0 (PIN_OUTPUT | MUX_MODE0) /* lcd_vsync.lcd_vsync */
+ 0xe4 (PIN_OUTPUT | MUX_MODE0) /* lcd_hsync.lcd_hsync */
+ 0xe8 (PIN_OUTPUT | MUX_MODE0) /* lcd_pclk.lcd_pclk */
+ 0xec (PIN_OUTPUT | MUX_MODE0) /* lcd_ac_bias_en.lcd_ac_bias_en */
+ /* Display Enable */
+ 0x6c (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a11.gpio1_27 */
+ >;
+ };
+};
+
+/* Ethernet */
+&cpsw_emac0 {
+ status = "okay";
+ phy_id = <&davinci_mdio>, <0>;
+ phy-mode = "rgmii";
+};
+
+&cpsw_emac1 {
+ status = "okay";
+ phy_id = <&davinci_mdio>, <1>;
+ phy-mode = "rgmii";
+};
+
+&davinci_mdio {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+};
+
+&mac {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ethernet_pins>;
+};
+
+
+&am33xx_pinmux {
+ ethernet_pins: pinmux_ethernet {
+ pinctrl-single,pins = <
+ 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
+ 0x118 (PIN_INPUT_PULLUP | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */
+ 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */
+ 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */
+ 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
+ 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
+ 0x12c (PIN_INPUT_PULLUP | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */
+ 0x130 (PIN_INPUT_PULLUP | MUX_MODE2) /* mii1_rxclk.rgmii1_rclk */
+ 0x134 (PIN_INPUT_PULLUP | MUX_MODE2) /* mii1_rxd3.rgmii1_rxd3 */
+ 0x138 (PIN_INPUT_PULLUP | MUX_MODE2) /* mii1_rxd2.rgmii1_rxd2 */
+ 0x13c (PIN_INPUT_PULLUP | MUX_MODE2) /* mii1_rxd1.rgmii1_rxd1 */
+ 0x140 (PIN_INPUT_PULLUP | MUX_MODE2) /* mii1_rxd0.rgmii1_rxd0 */
+ /* ethernet interrupt */
+ 0x144 (PIN_INPUT_PULLUP | MUX_MODE7) /* rmii2_refclk.gpio0_29 */
+ /* ethernet PHY nReset */
+ 0x108 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* mii1_col.gpio3_0 */
+ >;
+ };
+
+ mdio_pins: pinmux_mdio {
+ pinctrl-single,pins = <
+ 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
+ >;
+ };
+};
+
+/* MMC */
+&mmc1 {
+ /* Bootable SD card slot */
+ status = "okay";
+ vmmc-supply = <&ldo3_reg>;
+ bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd_pins>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
+};
+
+&mmc2 {
+ /* eMMC (not populated) on MMC #2 */
+ status = "disabled";
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_pins>;
+ vmmc-supply = <&ldo3_reg>;
+ bus-width = <8>;
+ ti,non-removable;
+};
+
+&edma {
+ /* Map eDMA MMC2 Events from Crossbar */
+ ti,edma-xbar-event-map = /bits/ 16 <1 12
+ 2 13>;
+};
+
+
+&mmc3 {
+ /* Wifi & Bluetooth on MMC #3 */
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wireless_pins>;
+ vmmmc-supply = <&v3v3c_reg>;
+ bus-width = <4>;
+ ti,non-removable;
+ dmas = <&edma 12
+ &edma 13>;
+ dma-names = "tx", "rx";
+};
+
+
+&am33xx_pinmux {
+ sd_pins: pinmux_sd_card {
+ pinctrl-single,pins = <
+ 0xf0 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+ 0xf4 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+ 0xf8 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+ 0xfc (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+ 0x100 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+ 0x104 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+ 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+ >;
+ };
+ emmc_pins: pinmux_emmc {
+ pinctrl-single,pins = <
+ 0x80 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+ 0x84 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+ 0x00 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+ 0x04 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+ 0x08 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+ 0x0c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+ 0x10 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
+ 0x14 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
+ 0x18 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
+ 0x1c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
+ /* EMMC nReset */
+ 0x74 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_31 */
+ >;
+ };
+ wireless_pins: pinmux_wireless {
+ pinctrl-single,pins = <
+ 0x44 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a1.mmc2_dat0 */
+ 0x48 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a2.mmc2_dat1 */
+ 0x4c (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a3.mmc2_dat2 */
+ 0x78 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ben1.mmc2_dat3 */
+ 0x88 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_csn3.mmc2_cmd */
+ 0x8c (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_clk.mmc1_clk */
+ /* WLAN nReset */
+ 0x60 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a8.gpio1_24 */
+ /* WLAN nPower down */
+ 0x70 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_wait0.gpio0_30 */
+ /* 32kHz Clock */
+ 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */
+ >;
+ };
+};
+
+/* Power */
+&vbat {
+ regulator-name = "vbat";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+};
+
+&v3v3c_reg {
+ regulator-name = "v3v3c_reg";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vbat>;
+};
+
+&vdd5_reg {
+ regulator-name = "vdd5_reg";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vbat>;
+};
+
+/include/ "tps65217.dtsi"
+
+&tps {
+ backlight {
+ isel = <1>; /* ISET1 */
+ fdim = <200>; /* TPS65217_BL_FDIM_200HZ */
+ default-brightness = <80>;
+ };
+
+ regulators {
+ dcdc1_reg: regulator@0 {
+ /* VDD_1V8 system supply */
+ };
+
+ dcdc2_reg: regulator@1 {
+ /* VDD_CORE voltage limits 0.95V - 1.26V with +/-4% tolerance */
+ regulator-name = "vdd_core";
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <1325000>;
+ regulator-boot-on;
+ };
+
+ dcdc3_reg: regulator@2 {
+ /* VDD_MPU voltage limits 0.95V - 1.1V with +/-4% tolerance */
+ regulator-name = "vdd_mpu";
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+ };
+
+ ldo1_reg: regulator@3 {
+ /* VRTC 1.8V always-on supply */
+ regulator-always-on;
+ };
+
+ ldo2_reg: regulator@4 {
+ /* 3.3V rail */
+ };
+
+ ldo3_reg: regulator@5 {
+ /* VDD_3V3A 3.3V rail */
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo4_reg: regulator@6 {
+ /* VDD_3V3B 3.3V rail */
+ };
+ };
+};
+
+/* SPI Busses */
+&spi0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+};
+
+&am33xx_pinmux {
+ spi0_pins: pinmux_spi0 {
+ pinctrl-single,pins = <
+ 0x150 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_sclk.spi0_sclk */
+ 0x15C (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_cs0.spi0_cs0 */
+ 0x154 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d0.spi0_d0 */
+ 0x158 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d1.spi0_d1 */
+ >;
+ };
+};
+
+/* Touch Screen */
+&tscadc {
+ status = "okay";
+ tsc {
+ ti,wires = <4>;
+ ti,x-plate-resistance = <200>;
+ ti,coordinate-readouts = <5>;
+ ti,wire-config = <0x00 0x11 0x22 0x33>;
+ };
+
+ adc {
+ ti,adc-channels = <4 5 6 7>;
+ };
+};
+
+/* UARTs */
+&uart0 {
+ /* Serial Console */
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+};
+
+&uart1 {
+ /* Broken out to J6 header */
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+};
+
+&am33xx_pinmux {
+ uart0_pins: pinmux_uart0 {
+ pinctrl-single,pins = <
+ 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+ >;
+ };
+ uart1_pins: pinmux_uart1 {
+ pinctrl-single,pins = <
+ 0x178 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_ctsn.uart1_ctsn */
+ 0x17C (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_rtsn.uart1_rtsn */
+ 0x180 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rxd.uart1_rxd */
+ 0x184 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_txd.uart1_txd */
+ >;
+ };
+};
+
+/* USB */
+&usb {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_pins>;
+};
+
+&usb_ctrl_mod {
+ status = "okay";
+};
+
+&usb0_phy {
+ status = "okay";
+};
+
+&usb1_phy {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+ dr_mode = "host";
+};
+
+&usb1 {
+ status = "okay";
+ dr_mode = "host";
+};
+
+&cppi41dma {
+ status = "okay";
+};
+
+&am33xx_pinmux {
+ usb_pins: pinmux_usb {
+ pinctrl-single,pins = <
+ /* USB0 Over-Current (active low) */
+ 0x64 (PIN_INPUT | MUX_MODE7) /* gpmc_a9.gpio1_25 */
+ /* USB1 Over-Current (active low) */
+ 0x68 (PIN_INPUT | MUX_MODE7) /* gpmc_a10.gpio1_26 */
+ >;
+ };
+};
+
+/* User IO */
+&leds {
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_leds_pins>;
+
+ led@0 {
+ label = "pepper:user0:blue";
+ gpios = <&gpio1 20 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "none";
+ default-state = "off";
+ };
+
+ led@1 {
+ label = "pepper:user1:red";
+ gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "none";
+ default-state = "off";
+ };
+};
+
+&buttons {
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_buttons_pins>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@0 {
+ label = "home";
+ linux,code = <KEY_HOME>;
+ gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
+ gpio-key,wakeup;
+ };
+
+ button@1 {
+ label = "menu";
+ linux,code = <KEY_MENU>;
+ gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
+ gpio-key,wakeup;
+ };
+
+ buttons@2 {
+ label = "power";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+ gpio-key,wakeup;
+ };
+};
+
+&am33xx_pinmux {
+ user_leds_pins: pinmux_user_leds {
+ pinctrl-single,pins = <
+ 0x50 (PIN_OUTPUT | MUX_MODE7) /* gpmc_a4.gpio1_20 */
+ 0x54 (PIN_OUTPUT | MUX_MODE7) /* gpmc_a5.gpio1_21 */
+ >;
+ };
+
+ user_buttons_pins: pinmux_user_buttons {
+ pinctrl-single,pins = <
+ 0x58 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a6.gpio1_22 */
+ 0x5C (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a7.gpio1_21 */
+ 0x164 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a8.gpio0_7 */
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/am33xx-clocks.dtsi b/arch/arm/boot/dts/am33xx-clocks.dtsi
new file mode 100644
index 000000000..afb4b3a7b
--- /dev/null
+++ b/arch/arm/boot/dts/am33xx-clocks.dtsi
@@ -0,0 +1,646 @@
+/*
+ * Device Tree Source for AM33xx clock data
+ *
+ * Copyright (C) 2013 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.
+ */
+&scm_clocks {
+ sys_clkin_ck: sys_clkin_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&virt_19200000_ck>, <&virt_24000000_ck>, <&virt_25000000_ck>, <&virt_26000000_ck>;
+ ti,bit-shift = <22>;
+ reg = <0x0040>;
+ };
+
+ adc_tsc_fck: adc_tsc_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dcan0_fck: dcan0_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dcan1_fck: dcan1_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ mcasp0_fck: mcasp0_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ mcasp1_fck: mcasp1_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ smartreflex0_fck: smartreflex0_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ smartreflex1_fck: smartreflex1_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ sha0_fck: sha0_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ aes0_fck: aes0_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ rng_fck: rng_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ ehrpwm0_tbclk: ehrpwm0_tbclk@44e10664 {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l4ls_gclk>;
+ ti,bit-shift = <0>;
+ reg = <0x0664>;
+ };
+
+ ehrpwm1_tbclk: ehrpwm1_tbclk@44e10664 {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l4ls_gclk>;
+ ti,bit-shift = <1>;
+ reg = <0x0664>;
+ };
+
+ ehrpwm2_tbclk: ehrpwm2_tbclk@44e10664 {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l4ls_gclk>;
+ ti,bit-shift = <2>;
+ reg = <0x0664>;
+ };
+};
+&prcm_clocks {
+ clk_32768_ck: clk_32768_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ clk_rc32k_ck: clk_rc32k_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32000>;
+ };
+
+ virt_19200000_ck: virt_19200000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <19200000>;
+ };
+
+ virt_24000000_ck: virt_24000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ virt_25000000_ck: virt_25000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <25000000>;
+ };
+
+ virt_26000000_ck: virt_26000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ };
+
+ tclkin_ck: tclkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ dpll_core_ck: dpll_core_ck {
+ #clock-cells = <0>;
+ compatible = "ti,am3-dpll-core-clock";
+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>;
+ reg = <0x0490>, <0x045c>, <0x0468>;
+ };
+
+ dpll_core_x2_ck: dpll_core_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,am3-dpll-x2-clock";
+ clocks = <&dpll_core_ck>;
+ };
+
+ dpll_core_m4_ck: dpll_core_m4_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <31>;
+ reg = <0x0480>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_core_m5_ck: dpll_core_m5_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <31>;
+ reg = <0x0484>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_core_m6_ck: dpll_core_m6_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <31>;
+ reg = <0x04d8>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_mpu_ck: dpll_mpu_ck {
+ #clock-cells = <0>;
+ compatible = "ti,am3-dpll-clock";
+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>;
+ reg = <0x0488>, <0x0420>, <0x042c>;
+ };
+
+ dpll_mpu_m2_ck: dpll_mpu_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_mpu_ck>;
+ ti,max-div = <31>;
+ reg = <0x04a8>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_ddr_ck: dpll_ddr_ck {
+ #clock-cells = <0>;
+ compatible = "ti,am3-dpll-no-gate-clock";
+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>;
+ reg = <0x0494>, <0x0434>, <0x0440>;
+ };
+
+ dpll_ddr_m2_ck: dpll_ddr_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_ddr_ck>;
+ ti,max-div = <31>;
+ reg = <0x04a0>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_ddr_m2_div2_ck: dpll_ddr_m2_div2_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_ddr_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ dpll_disp_ck: dpll_disp_ck {
+ #clock-cells = <0>;
+ compatible = "ti,am3-dpll-no-gate-clock";
+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>;
+ reg = <0x0498>, <0x0448>, <0x0454>;
+ };
+
+ dpll_disp_m2_ck: dpll_disp_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_disp_ck>;
+ ti,max-div = <31>;
+ reg = <0x04a4>;
+ ti,index-starts-at-one;
+ ti,set-rate-parent;
+ };
+
+ dpll_per_ck: dpll_per_ck {
+ #clock-cells = <0>;
+ compatible = "ti,am3-dpll-no-gate-j-type-clock";
+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>;
+ reg = <0x048c>, <0x0470>, <0x049c>;
+ };
+
+ dpll_per_m2_ck: dpll_per_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_ck>;
+ ti,max-div = <31>;
+ reg = <0x04ac>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_per_m2_div4_wkupdm_ck: dpll_per_m2_div4_wkupdm_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ dpll_per_m2_div4_ck: dpll_per_m2_div4_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ cefuse_fck: cefuse_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_clkin_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0a20>;
+ };
+
+ clk_24mhz: clk_24mhz {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <8>;
+ };
+
+ clkdiv32k_ck: clkdiv32k_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&clk_24mhz>;
+ clock-mult = <1>;
+ clock-div = <732>;
+ };
+
+ clkdiv32k_ick: clkdiv32k_ick {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&clkdiv32k_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x014c>;
+ };
+
+ l3_gclk: l3_gclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m4_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ pruss_ocp_gclk: pruss_ocp_gclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&l3_gclk>, <&dpll_disp_m2_ck>;
+ reg = <0x0530>;
+ };
+
+ mmu_fck: mmu_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_core_m4_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0914>;
+ };
+
+ timer1_fck: timer1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&clkdiv32k_ick>, <&tclkin_ck>, <&clk_rc32k_ck>, <&clk_32768_ck>;
+ reg = <0x0528>;
+ };
+
+ timer2_fck: timer2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>;
+ reg = <0x0508>;
+ };
+
+ timer3_fck: timer3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>;
+ reg = <0x050c>;
+ };
+
+ timer4_fck: timer4_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>;
+ reg = <0x0510>;
+ };
+
+ timer5_fck: timer5_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>;
+ reg = <0x0518>;
+ };
+
+ timer6_fck: timer6_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>;
+ reg = <0x051c>;
+ };
+
+ timer7_fck: timer7_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>;
+ reg = <0x0504>;
+ };
+
+ usbotg_fck: usbotg_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_per_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x047c>;
+ };
+
+ dpll_core_m4_div2_ck: dpll_core_m4_div2_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m4_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ ieee5000_fck: ieee5000_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_core_m4_div2_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x00e4>;
+ };
+
+ wdt1_fck: wdt1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&clk_rc32k_ck>, <&clkdiv32k_ick>;
+ reg = <0x0538>;
+ };
+
+ l4_rtc_gclk: l4_rtc_gclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m4_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ l4hs_gclk: l4hs_gclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m4_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ l3s_gclk: l3s_gclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m4_div2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ l4fw_gclk: l4fw_gclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m4_div2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ l4ls_gclk: l4ls_gclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m4_div2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ sysclk_div_ck: sysclk_div_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m4_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ cpsw_125mhz_gclk: cpsw_125mhz_gclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m5_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ cpsw_cpts_rft_clk: cpsw_cpts_rft_clk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dpll_core_m5_ck>, <&dpll_core_m4_ck>;
+ reg = <0x0520>;
+ };
+
+ gpio0_dbclk_mux_ck: gpio0_dbclk_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&clk_rc32k_ck>, <&clk_32768_ck>, <&clkdiv32k_ick>;
+ reg = <0x053c>;
+ };
+
+ gpio0_dbclk: gpio0_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&gpio0_dbclk_mux_ck>;
+ ti,bit-shift = <18>;
+ reg = <0x0408>;
+ };
+
+ gpio1_dbclk: gpio1_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&clkdiv32k_ick>;
+ ti,bit-shift = <18>;
+ reg = <0x00ac>;
+ };
+
+ gpio2_dbclk: gpio2_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&clkdiv32k_ick>;
+ ti,bit-shift = <18>;
+ reg = <0x00b0>;
+ };
+
+ gpio3_dbclk: gpio3_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&clkdiv32k_ick>;
+ ti,bit-shift = <18>;
+ reg = <0x00b4>;
+ };
+
+ lcd_gclk: lcd_gclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dpll_disp_m2_ck>, <&dpll_core_m5_ck>, <&dpll_per_m2_ck>;
+ reg = <0x0534>;
+ ti,set-rate-parent;
+ };
+
+ mmc_clk: mmc_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ gfx_fclk_clksel_ck: gfx_fclk_clksel_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dpll_core_m4_ck>, <&dpll_per_m2_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x052c>;
+ };
+
+ gfx_fck_div_ck: gfx_fck_div_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&gfx_fclk_clksel_ck>;
+ reg = <0x052c>;
+ ti,max-div = <2>;
+ };
+
+ sysclkout_pre_ck: sysclkout_pre_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&clk_32768_ck>, <&l3_gclk>, <&dpll_ddr_m2_ck>, <&dpll_per_m2_ck>, <&lcd_gclk>;
+ reg = <0x0700>;
+ };
+
+ clkout2_div_ck: clkout2_div_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&sysclkout_pre_ck>;
+ ti,bit-shift = <3>;
+ ti,max-div = <8>;
+ reg = <0x0700>;
+ };
+
+ dbg_sysclk_ck: dbg_sysclk_ck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_clkin_ck>;
+ ti,bit-shift = <19>;
+ reg = <0x0414>;
+ };
+
+ dbg_clka_ck: dbg_clka_ck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_core_m4_ck>;
+ ti,bit-shift = <30>;
+ reg = <0x0414>;
+ };
+
+ stm_pmd_clock_mux_ck: stm_pmd_clock_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dbg_sysclk_ck>, <&dbg_clka_ck>;
+ ti,bit-shift = <22>;
+ reg = <0x0414>;
+ };
+
+ trace_pmd_clk_mux_ck: trace_pmd_clk_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dbg_sysclk_ck>, <&dbg_clka_ck>;
+ ti,bit-shift = <20>;
+ reg = <0x0414>;
+ };
+
+ stm_clk_div_ck: stm_clk_div_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&stm_pmd_clock_mux_ck>;
+ ti,bit-shift = <27>;
+ ti,max-div = <64>;
+ reg = <0x0414>;
+ ti,index-power-of-two;
+ };
+
+ trace_clk_div_ck: trace_clk_div_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&trace_pmd_clk_mux_ck>;
+ ti,bit-shift = <24>;
+ ti,max-div = <64>;
+ reg = <0x0414>;
+ ti,index-power-of-two;
+ };
+
+ clkout2_ck: clkout2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&clkout2_div_ck>;
+ ti,bit-shift = <7>;
+ reg = <0x0700>;
+ };
+};
+
+&prcm_clockdomains {
+ clk_24mhz_clkdm: clk_24mhz_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&clkdiv32k_ick>;
+ };
+};
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
new file mode 100644
index 000000000..21fcc440f
--- /dev/null
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -0,0 +1,876 @@
+/*
+ * Device Tree Source for AM33XX SoC
+ *
+ * Copyright (C) 2012 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "ti,am33xx";
+ interrupt-parent = <&intc>;
+
+ aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ serial5 = &uart5;
+ d_can0 = &dcan0;
+ d_can1 = &dcan1;
+ usb0 = &usb0;
+ usb1 = &usb1;
+ phy0 = &usb0_phy;
+ phy1 = &usb1_phy;
+ ethernet0 = &cpsw_emac0;
+ ethernet1 = &cpsw_emac1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ compatible = "arm,cortex-a8";
+ device_type = "cpu";
+ reg = <0>;
+
+ /*
+ * To consider voltage drop between PMIC and SoC,
+ * tolerance value is reduced to 2% from 4% and
+ * voltage value is increased as a precaution.
+ */
+ operating-points = <
+ /* kHz uV */
+ 720000 1285000
+ 600000 1225000
+ 500000 1125000
+ 275000 1125000
+ >;
+ voltage-tolerance = <2>; /* 2 percentage */
+
+ clocks = <&dpll_mpu_ck>;
+ clock-names = "cpu";
+
+ clock-latency = <300000>; /* From omap-cpufreq driver */
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a8-pmu";
+ interrupts = <3>;
+ };
+
+ /*
+ * The soc node represents the soc top level view. It is used for IPs
+ * that are not memory mapped in the MPU view or for the MPU itself.
+ */
+ soc {
+ compatible = "ti,omap-infra";
+ mpu {
+ compatible = "ti,omap3-mpu";
+ ti,hwmods = "mpu";
+ };
+ };
+
+ /*
+ * XXX: Use a flat representation of the AM33XX interconnect.
+ * The real AM33XX interconnect network is quite complex. Since
+ * it will not bring real advantage to represent that in DT
+ * for the moment, just use a fake OCP bus entry to represent
+ * the whole bus hierarchy.
+ */
+ ocp {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "l3_main";
+
+ l4_wkup: l4_wkup@44c00000 {
+ compatible = "ti,am3-l4-wkup", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x44c00000 0x280000>;
+
+ prcm: prcm@200000 {
+ compatible = "ti,am3-prcm";
+ reg = <0x200000 0x4000>;
+
+ prcm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ prcm_clockdomains: clockdomains {
+ };
+ };
+
+ scm: scm@210000 {
+ compatible = "ti,am3-scm", "simple-bus";
+ reg = <0x210000 0x2000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x210000 0x2000>;
+
+ am33xx_pinmux: pinmux@800 {
+ compatible = "pinctrl-single";
+ reg = <0x800 0x238>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0x7f>;
+ };
+
+ scm_conf: scm_conf@0 {
+ compatible = "syscon";
+ reg = <0x0 0x800>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ scm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ scm_clockdomains: clockdomains {
+ };
+ };
+ };
+
+ intc: interrupt-controller@48200000 {
+ compatible = "ti,am33xx-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x48200000 0x1000>;
+ };
+
+ edma: edma@49000000 {
+ compatible = "ti,edma3";
+ ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
+ reg = <0x49000000 0x10000>,
+ <0x44e10f90 0x40>;
+ interrupts = <12 13 14>;
+ #dma-cells = <1>;
+ };
+
+ gpio0: gpio@44e07000 {
+ compatible = "ti,omap4-gpio";
+ ti,hwmods = "gpio1";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x44e07000 0x1000>;
+ interrupts = <96>;
+ };
+
+ gpio1: gpio@4804c000 {
+ compatible = "ti,omap4-gpio";
+ ti,hwmods = "gpio2";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x4804c000 0x1000>;
+ interrupts = <98>;
+ };
+
+ gpio2: gpio@481ac000 {
+ compatible = "ti,omap4-gpio";
+ ti,hwmods = "gpio3";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x481ac000 0x1000>;
+ interrupts = <32>;
+ };
+
+ gpio3: gpio@481ae000 {
+ compatible = "ti,omap4-gpio";
+ ti,hwmods = "gpio4";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x481ae000 0x1000>;
+ interrupts = <62>;
+ };
+
+ uart0: serial@44e09000 {
+ compatible = "ti,omap3-uart";
+ ti,hwmods = "uart1";
+ clock-frequency = <48000000>;
+ reg = <0x44e09000 0x2000>;
+ interrupts = <72>;
+ status = "disabled";
+ dmas = <&edma 26>, <&edma 27>;
+ dma-names = "tx", "rx";
+ };
+
+ uart1: serial@48022000 {
+ compatible = "ti,omap3-uart";
+ ti,hwmods = "uart2";
+ clock-frequency = <48000000>;
+ reg = <0x48022000 0x2000>;
+ interrupts = <73>;
+ status = "disabled";
+ dmas = <&edma 28>, <&edma 29>;
+ dma-names = "tx", "rx";
+ };
+
+ uart2: serial@48024000 {
+ compatible = "ti,omap3-uart";
+ ti,hwmods = "uart3";
+ clock-frequency = <48000000>;
+ reg = <0x48024000 0x2000>;
+ interrupts = <74>;
+ status = "disabled";
+ dmas = <&edma 30>, <&edma 31>;
+ dma-names = "tx", "rx";
+ };
+
+ uart3: serial@481a6000 {
+ compatible = "ti,omap3-uart";
+ ti,hwmods = "uart4";
+ clock-frequency = <48000000>;
+ reg = <0x481a6000 0x2000>;
+ interrupts = <44>;
+ status = "disabled";
+ };
+
+ uart4: serial@481a8000 {
+ compatible = "ti,omap3-uart";
+ ti,hwmods = "uart5";
+ clock-frequency = <48000000>;
+ reg = <0x481a8000 0x2000>;
+ interrupts = <45>;
+ status = "disabled";
+ };
+
+ uart5: serial@481aa000 {
+ compatible = "ti,omap3-uart";
+ ti,hwmods = "uart6";
+ clock-frequency = <48000000>;
+ reg = <0x481aa000 0x2000>;
+ interrupts = <46>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@44e0b000 {
+ compatible = "ti,omap4-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c1";
+ reg = <0x44e0b000 0x1000>;
+ interrupts = <70>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@4802a000 {
+ compatible = "ti,omap4-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c2";
+ reg = <0x4802a000 0x1000>;
+ interrupts = <71>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@4819c000 {
+ compatible = "ti,omap4-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c3";
+ reg = <0x4819c000 0x1000>;
+ interrupts = <30>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@48060000 {
+ compatible = "ti,omap4-hsmmc";
+ ti,hwmods = "mmc1";
+ ti,dual-volt;
+ ti,needs-special-reset;
+ ti,needs-special-hs-handling;
+ dmas = <&edma 24
+ &edma 25>;
+ dma-names = "tx", "rx";
+ interrupts = <64>;
+ interrupt-parent = <&intc>;
+ reg = <0x48060000 0x1000>;
+ status = "disabled";
+ };
+
+ mmc2: mmc@481d8000 {
+ compatible = "ti,omap4-hsmmc";
+ ti,hwmods = "mmc2";
+ ti,needs-special-reset;
+ dmas = <&edma 2
+ &edma 3>;
+ dma-names = "tx", "rx";
+ interrupts = <28>;
+ interrupt-parent = <&intc>;
+ reg = <0x481d8000 0x1000>;
+ status = "disabled";
+ };
+
+ mmc3: mmc@47810000 {
+ compatible = "ti,omap4-hsmmc";
+ ti,hwmods = "mmc3";
+ ti,needs-special-reset;
+ interrupts = <29>;
+ interrupt-parent = <&intc>;
+ reg = <0x47810000 0x1000>;
+ status = "disabled";
+ };
+
+ hwspinlock: spinlock@480ca000 {
+ compatible = "ti,omap4-hwspinlock";
+ reg = <0x480ca000 0x1000>;
+ ti,hwmods = "spinlock";
+ #hwlock-cells = <1>;
+ };
+
+ wdt2: wdt@44e35000 {
+ compatible = "ti,omap3-wdt";
+ ti,hwmods = "wd_timer2";
+ reg = <0x44e35000 0x1000>;
+ interrupts = <91>;
+ };
+
+ dcan0: can@481cc000 {
+ compatible = "ti,am3352-d_can";
+ ti,hwmods = "d_can0";
+ reg = <0x481cc000 0x2000>;
+ clocks = <&dcan0_fck>;
+ clock-names = "fck";
+ syscon-raminit = <&scm_conf 0x644 0>;
+ interrupts = <52>;
+ status = "disabled";
+ };
+
+ dcan1: can@481d0000 {
+ compatible = "ti,am3352-d_can";
+ ti,hwmods = "d_can1";
+ reg = <0x481d0000 0x2000>;
+ clocks = <&dcan1_fck>;
+ clock-names = "fck";
+ syscon-raminit = <&scm_conf 0x644 1>;
+ interrupts = <55>;
+ status = "disabled";
+ };
+
+ mailbox: mailbox@480C8000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x480C8000 0x200>;
+ interrupts = <77>;
+ ti,hwmods = "mailbox";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <8>;
+ mbox_wkupm3: wkup_m3 {
+ ti,mbox-tx = <0 0 0>;
+ ti,mbox-rx = <0 0 3>;
+ };
+ };
+
+ timer1: timer@44e31000 {
+ compatible = "ti,am335x-timer-1ms";
+ reg = <0x44e31000 0x400>;
+ interrupts = <67>;
+ ti,hwmods = "timer1";
+ ti,timer-alwon;
+ };
+
+ timer2: timer@48040000 {
+ compatible = "ti,am335x-timer";
+ reg = <0x48040000 0x400>;
+ interrupts = <68>;
+ ti,hwmods = "timer2";
+ };
+
+ timer3: timer@48042000 {
+ compatible = "ti,am335x-timer";
+ reg = <0x48042000 0x400>;
+ interrupts = <69>;
+ ti,hwmods = "timer3";
+ };
+
+ timer4: timer@48044000 {
+ compatible = "ti,am335x-timer";
+ reg = <0x48044000 0x400>;
+ interrupts = <92>;
+ ti,hwmods = "timer4";
+ ti,timer-pwm;
+ };
+
+ timer5: timer@48046000 {
+ compatible = "ti,am335x-timer";
+ reg = <0x48046000 0x400>;
+ interrupts = <93>;
+ ti,hwmods = "timer5";
+ ti,timer-pwm;
+ };
+
+ timer6: timer@48048000 {
+ compatible = "ti,am335x-timer";
+ reg = <0x48048000 0x400>;
+ interrupts = <94>;
+ ti,hwmods = "timer6";
+ ti,timer-pwm;
+ };
+
+ timer7: timer@4804a000 {
+ compatible = "ti,am335x-timer";
+ reg = <0x4804a000 0x400>;
+ interrupts = <95>;
+ ti,hwmods = "timer7";
+ ti,timer-pwm;
+ };
+
+ rtc: rtc@44e3e000 {
+ compatible = "ti,am3352-rtc", "ti,da830-rtc";
+ reg = <0x44e3e000 0x1000>;
+ interrupts = <75
+ 76>;
+ ti,hwmods = "rtc";
+ };
+
+ spi0: spi@48030000 {
+ compatible = "ti,omap4-mcspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x48030000 0x400>;
+ interrupts = <65>;
+ ti,spi-num-cs = <2>;
+ ti,hwmods = "spi0";
+ dmas = <&edma 16
+ &edma 17
+ &edma 18
+ &edma 19>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
+ status = "disabled";
+ };
+
+ spi1: spi@481a0000 {
+ compatible = "ti,omap4-mcspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x481a0000 0x400>;
+ interrupts = <125>;
+ ti,spi-num-cs = <2>;
+ ti,hwmods = "spi1";
+ dmas = <&edma 42
+ &edma 43
+ &edma 44
+ &edma 45>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
+ status = "disabled";
+ };
+
+ usb: usb@47400000 {
+ compatible = "ti,am33xx-usb";
+ reg = <0x47400000 0x1000>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ti,hwmods = "usb_otg_hs";
+ status = "disabled";
+
+ usb_ctrl_mod: control@44e10620 {
+ compatible = "ti,am335x-usb-ctrl-module";
+ reg = <0x44e10620 0x10
+ 0x44e10648 0x4>;
+ reg-names = "phy_ctrl", "wakeup";
+ status = "disabled";
+ };
+
+ usb0_phy: usb-phy@47401300 {
+ compatible = "ti,am335x-usb-phy";
+ reg = <0x47401300 0x100>;
+ reg-names = "phy";
+ status = "disabled";
+ ti,ctrl_mod = <&usb_ctrl_mod>;
+ };
+
+ usb0: usb@47401000 {
+ compatible = "ti,musb-am33xx";
+ status = "disabled";
+ reg = <0x47401400 0x400
+ 0x47401000 0x200>;
+ reg-names = "mc", "control";
+
+ interrupts = <18>;
+ interrupt-names = "mc";
+ dr_mode = "otg";
+ mentor,multipoint = <1>;
+ mentor,num-eps = <16>;
+ mentor,ram-bits = <12>;
+ mentor,power = <500>;
+ phys = <&usb0_phy>;
+
+ dmas = <&cppi41dma 0 0 &cppi41dma 1 0
+ &cppi41dma 2 0 &cppi41dma 3 0
+ &cppi41dma 4 0 &cppi41dma 5 0
+ &cppi41dma 6 0 &cppi41dma 7 0
+ &cppi41dma 8 0 &cppi41dma 9 0
+ &cppi41dma 10 0 &cppi41dma 11 0
+ &cppi41dma 12 0 &cppi41dma 13 0
+ &cppi41dma 14 0 &cppi41dma 0 1
+ &cppi41dma 1 1 &cppi41dma 2 1
+ &cppi41dma 3 1 &cppi41dma 4 1
+ &cppi41dma 5 1 &cppi41dma 6 1
+ &cppi41dma 7 1 &cppi41dma 8 1
+ &cppi41dma 9 1 &cppi41dma 10 1
+ &cppi41dma 11 1 &cppi41dma 12 1
+ &cppi41dma 13 1 &cppi41dma 14 1>;
+ dma-names =
+ "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7",
+ "rx8", "rx9", "rx10", "rx11", "rx12", "rx13",
+ "rx14", "rx15",
+ "tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7",
+ "tx8", "tx9", "tx10", "tx11", "tx12", "tx13",
+ "tx14", "tx15";
+ };
+
+ usb1_phy: usb-phy@47401b00 {
+ compatible = "ti,am335x-usb-phy";
+ reg = <0x47401b00 0x100>;
+ reg-names = "phy";
+ status = "disabled";
+ ti,ctrl_mod = <&usb_ctrl_mod>;
+ };
+
+ usb1: usb@47401800 {
+ compatible = "ti,musb-am33xx";
+ status = "disabled";
+ reg = <0x47401c00 0x400
+ 0x47401800 0x200>;
+ reg-names = "mc", "control";
+ interrupts = <19>;
+ interrupt-names = "mc";
+ dr_mode = "otg";
+ mentor,multipoint = <1>;
+ mentor,num-eps = <16>;
+ mentor,ram-bits = <12>;
+ mentor,power = <500>;
+ phys = <&usb1_phy>;
+
+ dmas = <&cppi41dma 15 0 &cppi41dma 16 0
+ &cppi41dma 17 0 &cppi41dma 18 0
+ &cppi41dma 19 0 &cppi41dma 20 0
+ &cppi41dma 21 0 &cppi41dma 22 0
+ &cppi41dma 23 0 &cppi41dma 24 0
+ &cppi41dma 25 0 &cppi41dma 26 0
+ &cppi41dma 27 0 &cppi41dma 28 0
+ &cppi41dma 29 0 &cppi41dma 15 1
+ &cppi41dma 16 1 &cppi41dma 17 1
+ &cppi41dma 18 1 &cppi41dma 19 1
+ &cppi41dma 20 1 &cppi41dma 21 1
+ &cppi41dma 22 1 &cppi41dma 23 1
+ &cppi41dma 24 1 &cppi41dma 25 1
+ &cppi41dma 26 1 &cppi41dma 27 1
+ &cppi41dma 28 1 &cppi41dma 29 1>;
+ dma-names =
+ "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7",
+ "rx8", "rx9", "rx10", "rx11", "rx12", "rx13",
+ "rx14", "rx15",
+ "tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7",
+ "tx8", "tx9", "tx10", "tx11", "tx12", "tx13",
+ "tx14", "tx15";
+ };
+
+ cppi41dma: dma-controller@47402000 {
+ compatible = "ti,am3359-cppi41";
+ reg = <0x47400000 0x1000
+ 0x47402000 0x1000
+ 0x47403000 0x1000
+ 0x47404000 0x4000>;
+ reg-names = "glue", "controller", "scheduler", "queuemgr";
+ interrupts = <17>;
+ interrupt-names = "glue";
+ #dma-cells = <2>;
+ #dma-channels = <30>;
+ #dma-requests = <256>;
+ status = "disabled";
+ };
+ };
+
+ epwmss0: epwmss@48300000 {
+ compatible = "ti,am33xx-pwmss";
+ reg = <0x48300000 0x10>;
+ ti,hwmods = "epwmss0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+ ranges = <0x48300100 0x48300100 0x80 /* ECAP */
+ 0x48300180 0x48300180 0x80 /* EQEP */
+ 0x48300200 0x48300200 0x80>; /* EHRPWM */
+
+ ecap0: ecap@48300100 {
+ compatible = "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x48300100 0x80>;
+ interrupts = <31>;
+ interrupt-names = "ecap0";
+ ti,hwmods = "ecap0";
+ status = "disabled";
+ };
+
+ ehrpwm0: ehrpwm@48300200 {
+ compatible = "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48300200 0x80>;
+ ti,hwmods = "ehrpwm0";
+ status = "disabled";
+ };
+ };
+
+ epwmss1: epwmss@48302000 {
+ compatible = "ti,am33xx-pwmss";
+ reg = <0x48302000 0x10>;
+ ti,hwmods = "epwmss1";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+ ranges = <0x48302100 0x48302100 0x80 /* ECAP */
+ 0x48302180 0x48302180 0x80 /* EQEP */
+ 0x48302200 0x48302200 0x80>; /* EHRPWM */
+
+ ecap1: ecap@48302100 {
+ compatible = "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x48302100 0x80>;
+ interrupts = <47>;
+ interrupt-names = "ecap1";
+ ti,hwmods = "ecap1";
+ status = "disabled";
+ };
+
+ ehrpwm1: ehrpwm@48302200 {
+ compatible = "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48302200 0x80>;
+ ti,hwmods = "ehrpwm1";
+ status = "disabled";
+ };
+ };
+
+ epwmss2: epwmss@48304000 {
+ compatible = "ti,am33xx-pwmss";
+ reg = <0x48304000 0x10>;
+ ti,hwmods = "epwmss2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+ ranges = <0x48304100 0x48304100 0x80 /* ECAP */
+ 0x48304180 0x48304180 0x80 /* EQEP */
+ 0x48304200 0x48304200 0x80>; /* EHRPWM */
+
+ ecap2: ecap@48304100 {
+ compatible = "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x48304100 0x80>;
+ interrupts = <61>;
+ interrupt-names = "ecap2";
+ ti,hwmods = "ecap2";
+ status = "disabled";
+ };
+
+ ehrpwm2: ehrpwm@48304200 {
+ compatible = "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48304200 0x80>;
+ ti,hwmods = "ehrpwm2";
+ status = "disabled";
+ };
+ };
+
+ mac: ethernet@4a100000 {
+ compatible = "ti,cpsw";
+ ti,hwmods = "cpgmac0";
+ clocks = <&cpsw_125mhz_gclk>, <&cpsw_cpts_rft_clk>;
+ clock-names = "fck", "cpts";
+ cpdma_channels = <8>;
+ ale_entries = <1024>;
+ bd_ram_size = <0x2000>;
+ no_bd_ram = <0>;
+ rx_descs = <64>;
+ mac_control = <0x20>;
+ slaves = <2>;
+ active_slave = <0>;
+ cpts_clock_mult = <0x80000000>;
+ cpts_clock_shift = <29>;
+ reg = <0x4a100000 0x800
+ 0x4a101200 0x100>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&intc>;
+ /*
+ * c0_rx_thresh_pend
+ * c0_rx_pend
+ * c0_tx_pend
+ * c0_misc_pend
+ */
+ interrupts = <40 41 42 43>;
+ ranges;
+ syscon = <&scm_conf>;
+ status = "disabled";
+
+ davinci_mdio: mdio@4a101000 {
+ compatible = "ti,davinci_mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "davinci_mdio";
+ bus_freq = <1000000>;
+ reg = <0x4a101000 0x100>;
+ status = "disabled";
+ };
+
+ cpsw_emac0: slave@4a100200 {
+ /* Filled in by U-Boot */
+ mac-address = [ 00 00 00 00 00 00 ];
+ };
+
+ cpsw_emac1: slave@4a100300 {
+ /* Filled in by U-Boot */
+ mac-address = [ 00 00 00 00 00 00 ];
+ };
+
+ phy_sel: cpsw-phy-sel@44e10650 {
+ compatible = "ti,am3352-cpsw-phy-sel";
+ reg= <0x44e10650 0x4>;
+ reg-names = "gmii-sel";
+ };
+ };
+
+ ocmcram: ocmcram@40300000 {
+ compatible = "mmio-sram";
+ reg = <0x40300000 0x10000>; /* 64k */
+ };
+
+ wkup_m3: wkup_m3@44d00000 {
+ compatible = "ti,am3353-wkup-m3";
+ reg = <0x44d00000 0x4000 /* M3 UMEM */
+ 0x44d80000 0x2000>; /* M3 DMEM */
+ ti,hwmods = "wkup_m3";
+ ti,no-reset-on-init;
+ };
+
+ elm: elm@48080000 {
+ compatible = "ti,am3352-elm";
+ reg = <0x48080000 0x2000>;
+ interrupts = <4>;
+ ti,hwmods = "elm";
+ status = "disabled";
+ };
+
+ lcdc: lcdc@4830e000 {
+ compatible = "ti,am33xx-tilcdc";
+ reg = <0x4830e000 0x1000>;
+ interrupt-parent = <&intc>;
+ interrupts = <36>;
+ ti,hwmods = "lcdc";
+ status = "disabled";
+ };
+
+ tscadc: tscadc@44e0d000 {
+ compatible = "ti,am3359-tscadc";
+ reg = <0x44e0d000 0x1000>;
+ interrupt-parent = <&intc>;
+ interrupts = <16>;
+ ti,hwmods = "adc_tsc";
+ status = "disabled";
+
+ tsc {
+ compatible = "ti,am3359-tsc";
+ };
+ am335x_adc: adc {
+ #io-channel-cells = <1>;
+ compatible = "ti,am3359-adc";
+ };
+ };
+
+ gpmc: gpmc@50000000 {
+ compatible = "ti,am3352-gpmc";
+ ti,hwmods = "gpmc";
+ ti,no-idle-on-init;
+ reg = <0x50000000 0x2000>;
+ interrupts = <100>;
+ gpmc,num-cs = <7>;
+ gpmc,num-waitpins = <2>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ status = "disabled";
+ };
+
+ sham: sham@53100000 {
+ compatible = "ti,omap4-sham";
+ ti,hwmods = "sham";
+ reg = <0x53100000 0x200>;
+ interrupts = <109>;
+ dmas = <&edma 36>;
+ dma-names = "rx";
+ };
+
+ aes: aes@53500000 {
+ compatible = "ti,omap4-aes";
+ ti,hwmods = "aes";
+ reg = <0x53500000 0xa0>;
+ interrupts = <103>;
+ dmas = <&edma 6>,
+ <&edma 5>;
+ dma-names = "tx", "rx";
+ };
+
+ mcasp0: mcasp@48038000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ ti,hwmods = "mcasp0";
+ reg = <0x48038000 0x2000>,
+ <0x46000000 0x400000>;
+ reg-names = "mpu", "dat";
+ interrupts = <80>, <81>;
+ interrupt-names = "tx", "rx";
+ status = "disabled";
+ dmas = <&edma 8>,
+ <&edma 9>;
+ dma-names = "tx", "rx";
+ };
+
+ mcasp1: mcasp@4803C000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ ti,hwmods = "mcasp1";
+ reg = <0x4803C000 0x2000>,
+ <0x46400000 0x400000>;
+ reg-names = "mpu", "dat";
+ interrupts = <82>, <83>;
+ interrupt-names = "tx", "rx";
+ status = "disabled";
+ dmas = <&edma 10>,
+ <&edma 11>;
+ dma-names = "tx", "rx";
+ };
+
+ rng: rng@48310000 {
+ compatible = "ti,omap4-rng";
+ ti,hwmods = "rng";
+ reg = <0x48310000 0x2000>;
+ interrupts = <111>;
+ };
+ };
+};
+
+/include/ "am33xx-clocks.dtsi"
diff --git a/arch/arm/boot/dts/am3517-craneboard.dts b/arch/arm/boot/dts/am3517-craneboard.dts
new file mode 100644
index 000000000..2d40b3f24
--- /dev/null
+++ b/arch/arm/boot/dts/am3517-craneboard.dts
@@ -0,0 +1,174 @@
+/*
+ * See craneboard.org for more details
+ *
+ * Copyright (C) 2013 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.
+ */
+/dts-v1/;
+
+#include "am3517.dtsi"
+
+/ {
+ model = "TI AM3517 CraneBoard (TMDSEVM3517)";
+ compatible = "ti,am3517-craneboard", "ti,am3517", "ti,omap3";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ vbat: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vbat";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ };
+};
+
+&davinci_emac {
+ status = "okay";
+};
+
+&davinci_mdio {
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <2600000>;
+
+ tps: tps@2d {
+ reg = <0x2d>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ /* goes to expansion connector */
+ status = "disabled";
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+ /* goes to expansion connector */
+ status = "disabled";
+};
+
+&mmc1 {
+ vmmc-supply = <&vdd2_reg>;
+ bus-width = <8>;
+};
+
+&mmc2 {
+ /* goes to expansion connector */
+ status = "disabled";
+};
+
+&mmc3 {
+ /* goes to expansion connector */
+ status = "disabled";
+};
+
+#include "tps65910.dtsi"
+
+&omap3_pmx_core {
+ tps_pins: pinmux_tps_pins {
+ pinctrl-single,pins = <
+ 0x1b0 (PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq.sys_nirq */
+ >;
+ };
+};
+
+&tps {
+ pinctrl-names = "default";
+ pinctrl-0 = <&tps_pins>;
+
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+
+ ti,en-ck32k-xtal;
+
+ vcc1-supply = <&vbat>;
+ vcc2-supply = <&vbat>;
+ vcc3-supply = <&vbat>;
+ vcc4-supply = <&vbat>;
+ vcc5-supply = <&vbat>;
+ vcc6-supply = <&vbat>;
+ vcc7-supply = <&vbat>;
+ vccio-supply = <&vbat>;
+
+ regulators {
+ vrtc_reg: regulator@0 {
+ regulator-always-on;
+ };
+
+ vio_reg: regulator@1 {
+ regulator-always-on;
+ };
+
+ /*
+ * Unused:
+ * VDIG1=2.7V,300mA max
+ * VDIG2=1.8V,300mA max
+ */
+
+ vpll_reg: regulator@7 {
+ /* VDDS_DPLL_1V8 */
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vaux1_reg: regulator@9 {
+ /* VDDS_SRAM_1V8 */
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vaux2_reg: regulator@10 {
+ /* VDDA1P8V_USBPHY */
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ /* VAUX33 unused */
+
+ vdac_reg: regulator@8 {
+ /* VDDA_DAC_1V8 */
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vmmc_reg: regulator@12 {
+ /* VDDA3P3V_USBPHY */
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd1_reg: regulator@2 {
+ /* VDD_CORE */
+ regulator-name = "vdd_core";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd2_reg: regulator@3 {
+ /* VDDSHV_3V3 */
+ regulator-name = "vdd_shv";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ /* VDD3 unused */
+ };
+};
diff --git a/arch/arm/boot/dts/am3517-evm.dts b/arch/arm/boot/dts/am3517-evm.dts
new file mode 100644
index 000000000..b4127c649
--- /dev/null
+++ b/arch/arm/boot/dts/am3517-evm.dts
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+/dts-v1/;
+
+#include "am3517.dtsi"
+
+/ {
+ model = "TI AM3517 EVM (AM3517/05 TMDSEVM3517)";
+ compatible = "ti,am3517-evm", "ti,am3517", "ti,omap3";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ vmmc_fixed: vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmc_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&davinci_emac {
+ status = "okay";
+};
+
+&davinci_mdio {
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+};
+
+&mmc1 {
+ vmmc-supply = <&vmmc_fixed>;
+ bus-width = <4>;
+};
+
+&mmc2 {
+ status = "disabled";
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
diff --git a/arch/arm/boot/dts/am3517.dtsi b/arch/arm/boot/dts/am3517.dtsi
new file mode 100644
index 000000000..f164dce08
--- /dev/null
+++ b/arch/arm/boot/dts/am3517.dtsi
@@ -0,0 +1,83 @@
+/*
+ * Device Tree Source for am3517 SoC
+ *
+ * Copyright (C) 2013 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 "omap3.dtsi"
+
+/ {
+ aliases {
+ serial3 = &uart4;
+ };
+
+ ocp {
+ am35x_otg_hs: am35x_otg_hs@5c040000 {
+ compatible = "ti,omap3-musb";
+ ti,hwmods = "am35x_otg_hs";
+ status = "disabled";
+ reg = <0x5c040000 0x1000>;
+ interrupts = <71>;
+ interrupt-names = "mc";
+ };
+
+ davinci_emac: ethernet@0x5c000000 {
+ compatible = "ti,am3517-emac";
+ ti,hwmods = "davinci_emac";
+ status = "disabled";
+ reg = <0x5c000000 0x30000>;
+ interrupts = <67 68 69 70>;
+ syscon = <&scm_conf>;
+ ti,davinci-ctrl-reg-offset = <0x10000>;
+ ti,davinci-ctrl-mod-reg-offset = <0>;
+ ti,davinci-ctrl-ram-offset = <0x20000>;
+ ti,davinci-ctrl-ram-size = <0x2000>;
+ ti,davinci-rmii-en = /bits/ 8 <1>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+
+ davinci_mdio: ethernet@0x5c030000 {
+ compatible = "ti,davinci_mdio";
+ ti,hwmods = "davinci_mdio";
+ status = "disabled";
+ reg = <0x5c030000 0x1000>;
+ bus_freq = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ uart4: serial@4809e000 {
+ compatible = "ti,omap3-uart";
+ ti,hwmods = "uart4";
+ status = "disabled";
+ reg = <0x4809e000 0x400>;
+ interrupts = <84>;
+ dmas = <&sdma 55 &sdma 54>;
+ dma-names = "tx", "rx";
+ clock-frequency = <48000000>;
+ };
+ };
+};
+
+&iva {
+ status = "disabled";
+};
+
+&mailbox {
+ status = "disabled";
+};
+
+&mmu_isp {
+ status = "disabled";
+};
+
+&smartreflex_mpu_iva {
+ status = "disabled";
+};
+
+/include/ "am35xx-clocks.dtsi"
+/include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi"
diff --git a/arch/arm/boot/dts/am3517_mt_ventoux.dts b/arch/arm/boot/dts/am3517_mt_ventoux.dts
new file mode 100644
index 000000000..fdf5ce63c
--- /dev/null
+++ b/arch/arm/boot/dts/am3517_mt_ventoux.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 Ilya Yanok, EmCraft Systems
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "omap34xx.dtsi"
+
+/ {
+ model = "TeeJet Mt.Ventoux";
+ compatible = "teejet,mt_ventoux", "ti,omap3";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ /* AM35xx doesn't have IVA */
+ soc {
+ iva {
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/am35xx-clocks.dtsi b/arch/arm/boot/dts/am35xx-clocks.dtsi
new file mode 100644
index 000000000..18cc826e9
--- /dev/null
+++ b/arch/arm/boot/dts/am35xx-clocks.dtsi
@@ -0,0 +1,128 @@
+/*
+ * Device Tree Source for OMAP3 clock data
+ *
+ * Copyright (C) 2013 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.
+ */
+&scm_clocks {
+ emac_ick: emac_ick {
+ #clock-cells = <0>;
+ compatible = "ti,am35xx-gate-clock";
+ clocks = <&ipss_ick>;
+ reg = <0x032c>;
+ ti,bit-shift = <1>;
+ };
+
+ emac_fck: emac_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&rmii_ck>;
+ reg = <0x032c>;
+ ti,bit-shift = <9>;
+ };
+
+ vpfe_ick: vpfe_ick {
+ #clock-cells = <0>;
+ compatible = "ti,am35xx-gate-clock";
+ clocks = <&ipss_ick>;
+ reg = <0x032c>;
+ ti,bit-shift = <2>;
+ };
+
+ vpfe_fck: vpfe_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&pclk_ck>;
+ reg = <0x032c>;
+ ti,bit-shift = <10>;
+ };
+
+ hsotgusb_ick_am35xx: hsotgusb_ick_am35xx {
+ #clock-cells = <0>;
+ compatible = "ti,am35xx-gate-clock";
+ clocks = <&ipss_ick>;
+ reg = <0x032c>;
+ ti,bit-shift = <0>;
+ };
+
+ hsotgusb_fck_am35xx: hsotgusb_fck_am35xx {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_ck>;
+ reg = <0x032c>;
+ ti,bit-shift = <8>;
+ };
+
+ hecc_ck: hecc_ck {
+ #clock-cells = <0>;
+ compatible = "ti,am35xx-gate-clock";
+ clocks = <&sys_ck>;
+ reg = <0x032c>;
+ ti,bit-shift = <3>;
+ };
+};
+&cm_clocks {
+ ipss_ick: ipss_ick {
+ #clock-cells = <0>;
+ compatible = "ti,am35xx-interface-clock";
+ clocks = <&core_l3_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <4>;
+ };
+
+ rmii_ck: rmii_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <50000000>;
+ };
+
+ pclk_ck: pclk_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <27000000>;
+ };
+
+ uart4_ick_am35xx: uart4_ick_am35xx {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <23>;
+ };
+
+ uart4_fck_am35xx: uart4_fck_am35xx {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_48m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <23>;
+ };
+};
+
+&cm_clockdomains {
+ core_l3_clkdm: core_l3_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&sdrc_ick>, <&ipss_ick>, <&emac_ick>, <&vpfe_ick>,
+ <&hsotgusb_ick_am35xx>, <&hsotgusb_fck_am35xx>,
+ <&hecc_ck>;
+ };
+
+ core_l4_clkdm: core_l4_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&cpefuse_fck>, <&ts_fck>, <&usbtll_fck>,
+ <&usbtll_ick>, <&mmchs3_ick>, <&mmchs3_fck>,
+ <&mmchs2_fck>, <&mmchs1_fck>, <&i2c3_fck>, <&i2c2_fck>,
+ <&i2c1_fck>, <&mcspi4_fck>, <&mcspi3_fck>,
+ <&mcspi2_fck>, <&mcspi1_fck>, <&uart2_fck>,
+ <&uart1_fck>, <&hdq_fck>, <&mmchs2_ick>, <&mmchs1_ick>,
+ <&hdq_ick>, <&mcspi4_ick>, <&mcspi3_ick>,
+ <&mcspi2_ick>, <&mcspi1_ick>, <&i2c3_ick>, <&i2c2_ick>,
+ <&i2c1_ick>, <&uart2_ick>, <&uart1_ick>, <&gpt11_ick>,
+ <&gpt10_ick>, <&mcbsp5_ick>, <&mcbsp1_ick>,
+ <&omapctrl_ick>, <&aes2_ick>, <&sha12_ick>,
+ <&uart4_ick_am35xx>, <&uart4_fck_am35xx>;
+ };
+};
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
new file mode 100644
index 000000000..c80a3e233
--- /dev/null
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -0,0 +1,992 @@
+/*
+ * Device Tree Source for AM4372 SoC
+ *
+ * Copyright (C) 2013 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "ti,am4372", "ti,am43";
+ interrupt-parent = <&wakeupgen>;
+
+
+ aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ serial0 = &uart0;
+ ethernet0 = &cpsw_emac0;
+ ethernet1 = &cpsw_emac1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu: cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0>;
+
+ clocks = <&dpll_mpu_ck>;
+ clock-names = "cpu";
+
+ clock-latency = <300000>; /* From omap-cpufreq driver */
+ };
+ };
+
+ gic: interrupt-controller@48241000 {
+ compatible = "arm,cortex-a9-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x48241000 0x1000>,
+ <0x48240100 0x0100>;
+ interrupt-parent = <&gic>;
+ };
+
+ wakeupgen: interrupt-controller@48281000 {
+ compatible = "ti,omap4-wugen-mpu";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x48281000 0x1000>;
+ interrupt-parent = <&gic>;
+ };
+
+ l2-cache-controller@48242000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x48242000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ ocp {
+ compatible = "ti,am4372-l3-noc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "l3_main";
+ reg = <0x44000000 0x400000
+ 0x44800000 0x400000>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+
+ l4_wkup: l4_wkup@44c00000 {
+ compatible = "ti,am4-l4-wkup", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x44c00000 0x287000>;
+
+ prcm: prcm@1f0000 {
+ compatible = "ti,am4-prcm";
+ reg = <0x1f0000 0x11000>;
+
+ prcm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ prcm_clockdomains: clockdomains {
+ };
+ };
+
+ scm: scm@210000 {
+ compatible = "ti,am4-scm", "simple-bus";
+ reg = <0x210000 0x4000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x210000 0x4000>;
+
+ am43xx_pinmux: pinmux@800 {
+ compatible = "ti,am437-padconf",
+ "pinctrl-single";
+ reg = <0x800 0x31c>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0xffffffff>;
+ };
+
+ scm_conf: scm_conf@0 {
+ compatible = "syscon";
+ reg = <0x0 0x800>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ scm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ scm_clockdomains: clockdomains {
+ };
+ };
+ };
+
+ edma: edma@49000000 {
+ compatible = "ti,edma3";
+ ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
+ reg = <0x49000000 0x10000>,
+ <0x44e10f90 0x10>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ };
+
+ uart0: serial@44e09000 {
+ compatible = "ti,am4372-uart","ti,omap2-uart";
+ reg = <0x44e09000 0x2000>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart1";
+ };
+
+ uart1: serial@48022000 {
+ compatible = "ti,am4372-uart","ti,omap2-uart";
+ reg = <0x48022000 0x2000>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart2";
+ status = "disabled";
+ };
+
+ uart2: serial@48024000 {
+ compatible = "ti,am4372-uart","ti,omap2-uart";
+ reg = <0x48024000 0x2000>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart3";
+ status = "disabled";
+ };
+
+ uart3: serial@481a6000 {
+ compatible = "ti,am4372-uart","ti,omap2-uart";
+ reg = <0x481a6000 0x2000>;
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart4";
+ status = "disabled";
+ };
+
+ uart4: serial@481a8000 {
+ compatible = "ti,am4372-uart","ti,omap2-uart";
+ reg = <0x481a8000 0x2000>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart5";
+ status = "disabled";
+ };
+
+ uart5: serial@481aa000 {
+ compatible = "ti,am4372-uart","ti,omap2-uart";
+ reg = <0x481aa000 0x2000>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart6";
+ status = "disabled";
+ };
+
+ mailbox: mailbox@480C8000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x480C8000 0x200>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mailbox";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <8>;
+ mbox_wkupm3: wkup_m3 {
+ ti,mbox-tx = <0 0 0>;
+ ti,mbox-rx = <0 0 3>;
+ };
+ };
+
+ timer1: timer@44e31000 {
+ compatible = "ti,am4372-timer-1ms","ti,am335x-timer-1ms";
+ reg = <0x44e31000 0x400>;
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ ti,timer-alwon;
+ ti,hwmods = "timer1";
+ };
+
+ timer2: timer@48040000 {
+ compatible = "ti,am4372-timer","ti,am335x-timer";
+ reg = <0x48040000 0x400>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer2";
+ };
+
+ timer3: timer@48042000 {
+ compatible = "ti,am4372-timer","ti,am335x-timer";
+ reg = <0x48042000 0x400>;
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer3";
+ status = "disabled";
+ };
+
+ timer4: timer@48044000 {
+ compatible = "ti,am4372-timer","ti,am335x-timer";
+ reg = <0x48044000 0x400>;
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+ ti,timer-pwm;
+ ti,hwmods = "timer4";
+ status = "disabled";
+ };
+
+ timer5: timer@48046000 {
+ compatible = "ti,am4372-timer","ti,am335x-timer";
+ reg = <0x48046000 0x400>;
+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+ ti,timer-pwm;
+ ti,hwmods = "timer5";
+ status = "disabled";
+ };
+
+ timer6: timer@48048000 {
+ compatible = "ti,am4372-timer","ti,am335x-timer";
+ reg = <0x48048000 0x400>;
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ ti,timer-pwm;
+ ti,hwmods = "timer6";
+ status = "disabled";
+ };
+
+ timer7: timer@4804a000 {
+ compatible = "ti,am4372-timer","ti,am335x-timer";
+ reg = <0x4804a000 0x400>;
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+ ti,timer-pwm;
+ ti,hwmods = "timer7";
+ status = "disabled";
+ };
+
+ timer8: timer@481c1000 {
+ compatible = "ti,am4372-timer","ti,am335x-timer";
+ reg = <0x481c1000 0x400>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer8";
+ status = "disabled";
+ };
+
+ timer9: timer@4833d000 {
+ compatible = "ti,am4372-timer","ti,am335x-timer";
+ reg = <0x4833d000 0x400>;
+ interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer9";
+ status = "disabled";
+ };
+
+ timer10: timer@4833f000 {
+ compatible = "ti,am4372-timer","ti,am335x-timer";
+ reg = <0x4833f000 0x400>;
+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer10";
+ status = "disabled";
+ };
+
+ timer11: timer@48341000 {
+ compatible = "ti,am4372-timer","ti,am335x-timer";
+ reg = <0x48341000 0x400>;
+ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer11";
+ status = "disabled";
+ };
+
+ counter32k: counter@44e86000 {
+ compatible = "ti,am4372-counter32k","ti,omap-counter32k";
+ reg = <0x44e86000 0x40>;
+ ti,hwmods = "counter_32k";
+ };
+
+ rtc: rtc@44e3e000 {
+ compatible = "ti,am4372-rtc","ti,da830-rtc";
+ reg = <0x44e3e000 0x1000>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "rtc";
+ status = "disabled";
+ };
+
+ wdt: wdt@44e35000 {
+ compatible = "ti,am4372-wdt","ti,omap3-wdt";
+ reg = <0x44e35000 0x1000>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "wd_timer2";
+ };
+
+ gpio0: gpio@44e07000 {
+ compatible = "ti,am4372-gpio","ti,omap4-gpio";
+ reg = <0x44e07000 0x1000>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ti,hwmods = "gpio1";
+ status = "disabled";
+ };
+
+ gpio1: gpio@4804c000 {
+ compatible = "ti,am4372-gpio","ti,omap4-gpio";
+ reg = <0x4804c000 0x1000>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ti,hwmods = "gpio2";
+ status = "disabled";
+ };
+
+ gpio2: gpio@481ac000 {
+ compatible = "ti,am4372-gpio","ti,omap4-gpio";
+ reg = <0x481ac000 0x1000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ti,hwmods = "gpio3";
+ status = "disabled";
+ };
+
+ gpio3: gpio@481ae000 {
+ compatible = "ti,am4372-gpio","ti,omap4-gpio";
+ reg = <0x481ae000 0x1000>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ti,hwmods = "gpio4";
+ status = "disabled";
+ };
+
+ gpio4: gpio@48320000 {
+ compatible = "ti,am4372-gpio","ti,omap4-gpio";
+ reg = <0x48320000 0x1000>;
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ti,hwmods = "gpio5";
+ status = "disabled";
+ };
+
+ gpio5: gpio@48322000 {
+ compatible = "ti,am4372-gpio","ti,omap4-gpio";
+ reg = <0x48322000 0x1000>;
+ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ti,hwmods = "gpio6";
+ status = "disabled";
+ };
+
+ hwspinlock: spinlock@480ca000 {
+ compatible = "ti,omap4-hwspinlock";
+ reg = <0x480ca000 0x1000>;
+ ti,hwmods = "spinlock";
+ #hwlock-cells = <1>;
+ };
+
+ i2c0: i2c@44e0b000 {
+ compatible = "ti,am4372-i2c","ti,omap4-i2c";
+ reg = <0x44e0b000 0x1000>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "i2c1";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@4802a000 {
+ compatible = "ti,am4372-i2c","ti,omap4-i2c";
+ reg = <0x4802a000 0x1000>;
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "i2c2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@4819c000 {
+ compatible = "ti,am4372-i2c","ti,omap4-i2c";
+ reg = <0x4819c000 0x1000>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "i2c3";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi0: spi@48030000 {
+ compatible = "ti,am4372-mcspi","ti,omap4-mcspi";
+ reg = <0x48030000 0x400>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "spi0";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@48060000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x48060000 0x1000>;
+ ti,hwmods = "mmc1";
+ ti,dual-volt;
+ ti,needs-special-reset;
+ dmas = <&edma 24
+ &edma 25>;
+ dma-names = "tx", "rx";
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc2: mmc@481d8000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x481d8000 0x1000>;
+ ti,hwmods = "mmc2";
+ ti,needs-special-reset;
+ dmas = <&edma 2
+ &edma 3>;
+ dma-names = "tx", "rx";
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc3: mmc@47810000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x47810000 0x1000>;
+ ti,hwmods = "mmc3";
+ ti,needs-special-reset;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ spi1: spi@481a0000 {
+ compatible = "ti,am4372-mcspi","ti,omap4-mcspi";
+ reg = <0x481a0000 0x400>;
+ interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "spi1";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi2: spi@481a2000 {
+ compatible = "ti,am4372-mcspi","ti,omap4-mcspi";
+ reg = <0x481a2000 0x400>;
+ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "spi2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi3: spi@481a4000 {
+ compatible = "ti,am4372-mcspi","ti,omap4-mcspi";
+ reg = <0x481a4000 0x400>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "spi3";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi4: spi@48345000 {
+ compatible = "ti,am4372-mcspi","ti,omap4-mcspi";
+ reg = <0x48345000 0x400>;
+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "spi4";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ mac: ethernet@4a100000 {
+ compatible = "ti,am4372-cpsw","ti,cpsw";
+ reg = <0x4a100000 0x800
+ 0x4a101200 0x100>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ti,hwmods = "cpgmac0";
+ clocks = <&cpsw_125mhz_gclk>, <&cpsw_cpts_rft_clk>;
+ clock-names = "fck", "cpts";
+ status = "disabled";
+ cpdma_channels = <8>;
+ ale_entries = <1024>;
+ bd_ram_size = <0x2000>;
+ no_bd_ram = <0>;
+ rx_descs = <64>;
+ mac_control = <0x20>;
+ slaves = <2>;
+ active_slave = <0>;
+ cpts_clock_mult = <0x80000000>;
+ cpts_clock_shift = <29>;
+ ranges;
+
+ davinci_mdio: mdio@4a101000 {
+ compatible = "ti,am4372-mdio","ti,davinci_mdio";
+ reg = <0x4a101000 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "davinci_mdio";
+ bus_freq = <1000000>;
+ status = "disabled";
+ };
+
+ cpsw_emac0: slave@4a100200 {
+ /* Filled in by U-Boot */
+ mac-address = [ 00 00 00 00 00 00 ];
+ };
+
+ cpsw_emac1: slave@4a100300 {
+ /* Filled in by U-Boot */
+ mac-address = [ 00 00 00 00 00 00 ];
+ };
+
+ phy_sel: cpsw-phy-sel@44e10650 {
+ compatible = "ti,am43xx-cpsw-phy-sel";
+ reg= <0x44e10650 0x4>;
+ reg-names = "gmii-sel";
+ };
+ };
+
+ epwmss0: epwmss@48300000 {
+ compatible = "ti,am4372-pwmss","ti,am33xx-pwmss";
+ reg = <0x48300000 0x10>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "epwmss0";
+ status = "disabled";
+
+ ecap0: ecap@48300100 {
+ compatible = "ti,am4372-ecap","ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x48300100 0x80>;
+ ti,hwmods = "ecap0";
+ status = "disabled";
+ };
+
+ ehrpwm0: ehrpwm@48300200 {
+ compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48300200 0x80>;
+ ti,hwmods = "ehrpwm0";
+ status = "disabled";
+ };
+ };
+
+ epwmss1: epwmss@48302000 {
+ compatible = "ti,am4372-pwmss","ti,am33xx-pwmss";
+ reg = <0x48302000 0x10>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "epwmss1";
+ status = "disabled";
+
+ ecap1: ecap@48302100 {
+ compatible = "ti,am4372-ecap","ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x48302100 0x80>;
+ ti,hwmods = "ecap1";
+ status = "disabled";
+ };
+
+ ehrpwm1: ehrpwm@48302200 {
+ compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48302200 0x80>;
+ ti,hwmods = "ehrpwm1";
+ status = "disabled";
+ };
+ };
+
+ epwmss2: epwmss@48304000 {
+ compatible = "ti,am4372-pwmss","ti,am33xx-pwmss";
+ reg = <0x48304000 0x10>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "epwmss2";
+ status = "disabled";
+
+ ecap2: ecap@48304100 {
+ compatible = "ti,am4372-ecap","ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x48304100 0x80>;
+ ti,hwmods = "ecap2";
+ status = "disabled";
+ };
+
+ ehrpwm2: ehrpwm@48304200 {
+ compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48304200 0x80>;
+ ti,hwmods = "ehrpwm2";
+ status = "disabled";
+ };
+ };
+
+ epwmss3: epwmss@48306000 {
+ compatible = "ti,am4372-pwmss","ti,am33xx-pwmss";
+ reg = <0x48306000 0x10>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "epwmss3";
+ status = "disabled";
+
+ ehrpwm3: ehrpwm@48306200 {
+ compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48306200 0x80>;
+ ti,hwmods = "ehrpwm3";
+ status = "disabled";
+ };
+ };
+
+ epwmss4: epwmss@48308000 {
+ compatible = "ti,am4372-pwmss","ti,am33xx-pwmss";
+ reg = <0x48308000 0x10>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "epwmss4";
+ status = "disabled";
+
+ ehrpwm4: ehrpwm@48308200 {
+ compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48308200 0x80>;
+ ti,hwmods = "ehrpwm4";
+ status = "disabled";
+ };
+ };
+
+ epwmss5: epwmss@4830a000 {
+ compatible = "ti,am4372-pwmss","ti,am33xx-pwmss";
+ reg = <0x4830a000 0x10>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "epwmss5";
+ status = "disabled";
+
+ ehrpwm5: ehrpwm@4830a200 {
+ compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x4830a200 0x80>;
+ ti,hwmods = "ehrpwm5";
+ status = "disabled";
+ };
+ };
+
+ tscadc: tscadc@44e0d000 {
+ compatible = "ti,am3359-tscadc";
+ reg = <0x44e0d000 0x1000>;
+ ti,hwmods = "adc_tsc";
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&adc_tsc_fck>;
+ clock-names = "fck";
+ status = "disabled";
+
+ tsc {
+ compatible = "ti,am3359-tsc";
+ };
+
+ adc {
+ #io-channel-cells = <1>;
+ compatible = "ti,am3359-adc";
+ };
+
+ };
+
+ sham: sham@53100000 {
+ compatible = "ti,omap5-sham";
+ ti,hwmods = "sham";
+ reg = <0x53100000 0x300>;
+ dmas = <&edma 36>;
+ dma-names = "rx";
+ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ aes: aes@53501000 {
+ compatible = "ti,omap4-aes";
+ ti,hwmods = "aes";
+ reg = <0x53501000 0xa0>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&edma 6
+ &edma 5>;
+ dma-names = "tx", "rx";
+ };
+
+ des: des@53701000 {
+ compatible = "ti,omap4-des";
+ ti,hwmods = "des";
+ reg = <0x53701000 0xa0>;
+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&edma 34
+ &edma 33>;
+ dma-names = "tx", "rx";
+ };
+
+ mcasp0: mcasp@48038000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ ti,hwmods = "mcasp0";
+ reg = <0x48038000 0x2000>,
+ <0x46000000 0x400000>;
+ reg-names = "mpu", "dat";
+ interrupts = <80>, <81>;
+ interrupt-names = "tx", "rx";
+ status = "disabled";
+ dmas = <&edma 8>,
+ <&edma 9>;
+ dma-names = "tx", "rx";
+ };
+
+ mcasp1: mcasp@4803C000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ ti,hwmods = "mcasp1";
+ reg = <0x4803C000 0x2000>,
+ <0x46400000 0x400000>;
+ reg-names = "mpu", "dat";
+ interrupts = <82>, <83>;
+ interrupt-names = "tx", "rx";
+ status = "disabled";
+ dmas = <&edma 10>,
+ <&edma 11>;
+ dma-names = "tx", "rx";
+ };
+
+ elm: elm@48080000 {
+ compatible = "ti,am3352-elm";
+ reg = <0x48080000 0x2000>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "elm";
+ clocks = <&l4ls_gclk>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ gpmc: gpmc@50000000 {
+ compatible = "ti,am3352-gpmc";
+ ti,hwmods = "gpmc";
+ clocks = <&l3s_gclk>;
+ clock-names = "fck";
+ reg = <0x50000000 0x2000>;
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+ gpmc,num-cs = <7>;
+ gpmc,num-waitpins = <2>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ status = "disabled";
+ };
+
+ am43xx_control_usb2phy1: control-phy@44e10620 {
+ compatible = "ti,control-phy-usb2-am437";
+ reg = <0x44e10620 0x4>;
+ reg-names = "power";
+ };
+
+ am43xx_control_usb2phy2: control-phy@0x44e10628 {
+ compatible = "ti,control-phy-usb2-am437";
+ reg = <0x44e10628 0x4>;
+ reg-names = "power";
+ };
+
+ ocp2scp0: ocp2scp@483a8000 {
+ compatible = "ti,am437x-ocp2scp", "ti,omap-ocp2scp";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "ocp2scp0";
+
+ usb2_phy1: phy@483a8000 {
+ compatible = "ti,am437x-usb2";
+ reg = <0x483a8000 0x8000>;
+ ctrl-module = <&am43xx_control_usb2phy1>;
+ clocks = <&usb_phy0_always_on_clk32k>,
+ <&usb_otg_ss0_refclk960m>;
+ clock-names = "wkupclk", "refclk";
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+ };
+
+ ocp2scp1: ocp2scp@483e8000 {
+ compatible = "ti,am437x-ocp2scp", "ti,omap-ocp2scp";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "ocp2scp1";
+
+ usb2_phy2: phy@483e8000 {
+ compatible = "ti,am437x-usb2";
+ reg = <0x483e8000 0x8000>;
+ ctrl-module = <&am43xx_control_usb2phy2>;
+ clocks = <&usb_phy1_always_on_clk32k>,
+ <&usb_otg_ss1_refclk960m>;
+ clock-names = "wkupclk", "refclk";
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+ };
+
+ dwc3_1: omap_dwc3@48380000 {
+ compatible = "ti,am437x-dwc3";
+ ti,hwmods = "usb_otg_ss0";
+ reg = <0x48380000 0x10000>;
+ interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ utmi-mode = <1>;
+ ranges;
+
+ usb1: usb@48390000 {
+ compatible = "synopsys,dwc3";
+ reg = <0x48390000 0x10000>;
+ interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb2_phy1>;
+ phy-names = "usb2-phy";
+ maximum-speed = "high-speed";
+ dr_mode = "otg";
+ status = "disabled";
+ snps,dis_u3_susphy_quirk;
+ snps,dis_u2_susphy_quirk;
+ };
+ };
+
+ dwc3_2: omap_dwc3@483c0000 {
+ compatible = "ti,am437x-dwc3";
+ ti,hwmods = "usb_otg_ss1";
+ reg = <0x483c0000 0x10000>;
+ interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ utmi-mode = <1>;
+ ranges;
+
+ usb2: usb@483d0000 {
+ compatible = "synopsys,dwc3";
+ reg = <0x483d0000 0x10000>;
+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb2_phy2>;
+ phy-names = "usb2-phy";
+ maximum-speed = "high-speed";
+ dr_mode = "otg";
+ status = "disabled";
+ snps,dis_u3_susphy_quirk;
+ snps,dis_u2_susphy_quirk;
+ };
+ };
+
+ qspi: qspi@47900000 {
+ compatible = "ti,am4372-qspi";
+ reg = <0x47900000 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "qspi";
+ interrupts = <0 138 0x4>;
+ num-cs = <4>;
+ status = "disabled";
+ };
+
+ hdq: hdq@48347000 {
+ compatible = "ti,am4372-hdq";
+ reg = <0x48347000 0x1000>;
+ interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&func_12m_clk>;
+ clock-names = "fck";
+ ti,hwmods = "hdq1w";
+ status = "disabled";
+ };
+
+ dss: dss@4832a000 {
+ compatible = "ti,omap3-dss";
+ reg = <0x4832a000 0x200>;
+ status = "disabled";
+ ti,hwmods = "dss_core";
+ clocks = <&disp_clk>;
+ clock-names = "fck";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dispc: dispc@4832a400 {
+ compatible = "ti,omap3-dispc";
+ reg = <0x4832a400 0x400>;
+ interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "dss_dispc";
+ clocks = <&disp_clk>;
+ clock-names = "fck";
+ };
+
+ rfbi: rfbi@4832a800 {
+ compatible = "ti,omap3-rfbi";
+ reg = <0x4832a800 0x100>;
+ ti,hwmods = "dss_rfbi";
+ clocks = <&disp_clk>;
+ clock-names = "fck";
+ };
+ };
+
+ ocmcram: ocmcram@40300000 {
+ compatible = "mmio-sram";
+ reg = <0x40300000 0x40000>; /* 256k */
+ };
+
+ dcan0: can@481cc000 {
+ compatible = "ti,am4372-d_can", "ti,am3352-d_can";
+ ti,hwmods = "d_can0";
+ clocks = <&dcan0_fck>;
+ clock-names = "fck";
+ reg = <0x481cc000 0x2000>;
+ syscon-raminit = <&scm_conf 0x644 0>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ dcan1: can@481d0000 {
+ compatible = "ti,am4372-d_can", "ti,am3352-d_can";
+ ti,hwmods = "d_can1";
+ clocks = <&dcan1_fck>;
+ clock-names = "fck";
+ reg = <0x481d0000 0x2000>;
+ syscon-raminit = <&scm_conf 0x644 1>;
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ vpfe0: vpfe@48326000 {
+ compatible = "ti,am437x-vpfe";
+ reg = <0x48326000 0x2000>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "vpfe0";
+ status = "disabled";
+ };
+
+ vpfe1: vpfe@48328000 {
+ compatible = "ti,am437x-vpfe";
+ reg = <0x48328000 0x2000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "vpfe1";
+ status = "disabled";
+ };
+ };
+};
+
+/include/ "am43xx-clocks.dtsi"
diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts
new file mode 100644
index 000000000..26956cb50
--- /dev/null
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@ -0,0 +1,652 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+/* AM437x GP EVM */
+
+/dts-v1/;
+
+#include "am4372.dtsi"
+#include <dt-bindings/pinctrl/am43xx.h>
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "TI AM437x GP EVM";
+ compatible = "ti,am437x-gp-evm","ti,am4372","ti,am43";
+
+ aliases {
+ display0 = &lcd0;
+ };
+
+ vmmcsd_fixed: fixedregulator-sd {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsd_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ };
+
+ vtt_fixed: fixedregulator-vtt {
+ compatible = "regulator-fixed";
+ regulator-name = "vtt_fixed";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&gpio5 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&ecap0 0 50000 PWM_POLARITY_INVERTED>;
+ brightness-levels = <0 51 53 56 62 75 101 152 255>;
+ default-brightness-level = <8>;
+ };
+
+ matrix_keypad: matrix_keypad@0 {
+ compatible = "gpio-matrix-keypad";
+ debounce-delay-ms = <5>;
+ col-scan-delay-us = <2>;
+
+ row-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH /* Bank3, pin21 */
+ &gpio4 3 GPIO_ACTIVE_HIGH /* Bank4, pin3 */
+ &gpio4 2 GPIO_ACTIVE_HIGH>; /* Bank4, pin2 */
+
+ col-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH /* Bank3, pin19 */
+ &gpio3 20 GPIO_ACTIVE_HIGH>; /* Bank3, pin20 */
+
+ linux,keymap = <0x00000201 /* P1 */
+ 0x00010202 /* P2 */
+ 0x01000067 /* UP */
+ 0x0101006a /* RIGHT */
+ 0x02000069 /* LEFT */
+ 0x0201006c>; /* DOWN */
+ };
+
+ lcd0: display {
+ compatible = "osddisplays,osd057T0559-34ts", "panel-dpi";
+ label = "lcd";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_pins>;
+
+ /*
+ * SelLCDorHDMI, LOW to select HDMI. This is not really the
+ * panel's enable GPIO, but we don't have HDMI driver support nor
+ * support to switch between two displays, so using this gpio as
+ * panel's enable should be safe.
+ */
+ enable-gpios = <&gpio5 8 GPIO_ACTIVE_HIGH>;
+
+ panel-timing {
+ clock-frequency = <33000000>;
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <210>;
+ hback-porch = <16>;
+ hsync-len = <30>;
+ vback-porch = <10>;
+ vfront-porch = <22>;
+ vsync-len = <13>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+ };
+};
+
+&am43xx_pinmux {
+ i2c0_pins: i2c0_pins {
+ pinctrl-single,pins = <
+ 0x188 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ 0x18c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ >;
+ };
+
+ i2c1_pins: i2c1_pins {
+ pinctrl-single,pins = <
+ 0x15c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2) /* spi0_cs0.i2c1_scl */
+ 0x158 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2) /* spi0_d1.i2c1_sda */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+ >;
+ };
+
+ ecap0_pins: backlight_pins {
+ pinctrl-single,pins = <
+ 0x164 MUX_MODE0 /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */
+ >;
+ };
+
+ pixcir_ts_pins: pixcir_ts_pins {
+ pinctrl-single,pins = <
+ 0x264 (PIN_INPUT_PULLUP | MUX_MODE7) /* spi2_d0.gpio3_22 */
+ >;
+ };
+
+ cpsw_default: cpsw_default {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_txen */
+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rxctl */
+ 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_txd3 */
+ 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_txd2 */
+ 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_txd1 */
+ 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_txd0 */
+ 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rmii1_tclk */
+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rmii1_rclk */
+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rxd3 */
+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rxd2 */
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rxd1 */
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rxd0 */
+ >;
+ };
+
+ cpsw_sleep: cpsw_sleep {
+ pinctrl-single,pins = <
+ /* Slave 1 reset value */
+ 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ davinci_mdio_default: davinci_mdio_default {
+ pinctrl-single,pins = <
+ /* MDIO */
+ 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
+ >;
+ };
+
+ davinci_mdio_sleep: davinci_mdio_sleep {
+ pinctrl-single,pins = <
+ /* MDIO reset value */
+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ nand_flash_x8: nand_flash_x8 {
+ pinctrl-single,pins = <
+ 0x26c(PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* spi2_cs0.gpio/eMMCorNANDsel */
+ 0x0 (PIN_INPUT | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
+ 0x4 (PIN_INPUT | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
+ 0x8 (PIN_INPUT | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
+ 0xc (PIN_INPUT | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
+ 0x10 (PIN_INPUT | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
+ 0x14 (PIN_INPUT | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
+ 0x18 (PIN_INPUT | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
+ 0x1c (PIN_INPUT | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
+ 0x70 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
+ 0x74 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpmc_wpn */
+ 0x7c (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
+ 0x90 (PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
+ 0x94 (PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
+ 0x98 (PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */
+ 0x9c (PIN_OUTPUT | MUX_MODE0) /* gpmc_be0n_cle.gpmc_be0n_cle */
+ >;
+ };
+
+ dss_pins: dss_pins {
+ pinctrl-single,pins = <
+ 0x020 (PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 8 -> DSS DATA 23 */
+ 0x024 (PIN_OUTPUT_PULLUP | MUX_MODE1)
+ 0x028 (PIN_OUTPUT_PULLUP | MUX_MODE1)
+ 0x02c (PIN_OUTPUT_PULLUP | MUX_MODE1)
+ 0x030 (PIN_OUTPUT_PULLUP | MUX_MODE1)
+ 0x034 (PIN_OUTPUT_PULLUP | MUX_MODE1)
+ 0x038 (PIN_OUTPUT_PULLUP | MUX_MODE1)
+ 0x03c (PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 15 -> DSS DATA 16 */
+ 0x0a0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 0 */
+ 0x0a4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0a8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0ac (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0b0 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0b4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0b8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0bc (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0c0 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0c4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0c8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0cc (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0d0 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0d4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0d8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0dc (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 15 */
+ 0x0e0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS VSYNC */
+ 0x0e4 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS HSYNC */
+ 0x0e8 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS PCLK */
+ 0x0ec (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS AC BIAS EN */
+
+ >;
+ };
+
+ lcd_pins: lcd_pins {
+ pinctrl-single,pins = <
+ /* GPIO 5_8 to select LCD / HDMI */
+ 0x238 (PIN_OUTPUT_PULLUP | MUX_MODE7)
+ >;
+ };
+
+ dcan0_default: dcan0_default_pins {
+ pinctrl-single,pins = <
+ 0x178 (PIN_OUTPUT | MUX_MODE2) /* uart1_ctsn.d_can0_tx */
+ 0x17c (PIN_INPUT_PULLUP | MUX_MODE2) /* uart1_rtsn.d_can0_rx */
+ >;
+ };
+
+ dcan1_default: dcan1_default_pins {
+ pinctrl-single,pins = <
+ 0x180 (PIN_OUTPUT | MUX_MODE2) /* uart1_rxd.d_can1_tx */
+ 0x184 (PIN_INPUT_PULLUP | MUX_MODE2) /* uart1_txd.d_can1_rx */
+ >;
+ };
+
+ vpfe0_pins_default: vpfe0_pins_default {
+ pinctrl-single,pins = <
+ 0x1B0 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_hd mode 0*/
+ 0x1B4 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_vd mode 0*/
+ 0x1C0 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_pclk mode 0*/
+ 0x1C4 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data8 mode 0*/
+ 0x1C8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data9 mode 0*/
+ 0x208 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data0 mode 0*/
+ 0x20C (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data1 mode 0*/
+ 0x210 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data2 mode 0*/
+ 0x214 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data3 mode 0*/
+ 0x218 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data4 mode 0*/
+ 0x21C (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data5 mode 0*/
+ 0x220 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data6 mode 0*/
+ 0x224 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data7 mode 0*/
+ >;
+ };
+
+ vpfe0_pins_sleep: vpfe0_pins_sleep {
+ pinctrl-single,pins = <
+ 0x1B0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_hd mode 0*/
+ 0x1B4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_vd mode 0*/
+ 0x1C0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_pclk mode 0*/
+ 0x1C4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data8 mode 0*/
+ 0x1C8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data9 mode 0*/
+ 0x208 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data0 mode 0*/
+ 0x20C (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data1 mode 0*/
+ 0x210 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data2 mode 0*/
+ 0x214 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data3 mode 0*/
+ 0x218 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data4 mode 0*/
+ 0x21C (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data5 mode 0*/
+ 0x220 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data6 mode 0*/
+ 0x224 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data7 mode 0*/
+ >;
+ };
+
+ vpfe1_pins_default: vpfe1_pins_default {
+ pinctrl-single,pins = <
+ 0x1CC (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data9 mode 0*/
+ 0x1D0 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data8 mode 0*/
+ 0x1D4 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_hd mode 0*/
+ 0x1D8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_vd mode 0*/
+ 0x1DC (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_pclk mode 0*/
+ 0x1E8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data0 mode 0*/
+ 0x1EC (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data1 mode 0*/
+ 0x1F0 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data2 mode 0*/
+ 0x1F4 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data3 mode 0*/
+ 0x1F8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data4 mode 0*/
+ 0x1FC (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data5 mode 0*/
+ 0x200 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data6 mode 0*/
+ 0x204 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data7 mode 0*/
+ >;
+ };
+
+ vpfe1_pins_sleep: vpfe1_pins_sleep {
+ pinctrl-single,pins = <
+ 0x1CC (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data9 mode 0*/
+ 0x1D0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data8 mode 0*/
+ 0x1D4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_hd mode 0*/
+ 0x1D8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_vd mode 0*/
+ 0x1DC (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_pclk mode 0*/
+ 0x1E8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data0 mode 0*/
+ 0x1EC (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data1 mode 0*/
+ 0x1F0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data2 mode 0*/
+ 0x1F4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data3 mode 0*/
+ 0x1F8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data4 mode 0*/
+ 0x1FC (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data5 mode 0*/
+ 0x200 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data6 mode 0*/
+ 0x204 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data7 mode 0*/
+ >;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <100000>;
+
+ tps65218: tps65218@24 {
+ reg = <0x24>;
+ compatible = "ti,tps65218";
+ interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* NMIn */
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ dcdc1: regulator-dcdc1 {
+ compatible = "ti,tps65218-dcdc1";
+ regulator-name = "vdd_core";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <1144000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ dcdc2: regulator-dcdc2 {
+ compatible = "ti,tps65218-dcdc2";
+ regulator-name = "vdd_mpu";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <1378000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ dcdc3: regulator-dcdc3 {
+ compatible = "ti,tps65218-dcdc3";
+ regulator-name = "vdcdc3";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ dcdc5: regulator-dcdc5 {
+ compatible = "ti,tps65218-dcdc5";
+ regulator-name = "v1_0bat";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ dcdc6: regulator-dcdc6 {
+ compatible = "ti,tps65218-dcdc6";
+ regulator-name = "v1_8bat";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo1: regulator-ldo1 {
+ compatible = "ti,tps65218-ldo1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+};
+
+&i2c1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ pixcir_ts@5c {
+ compatible = "pixcir,pixcir_tangoc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pixcir_ts_pins>;
+ reg = <0x5c>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <22 0>;
+
+ attb-gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+
+ touchscreen-size-x = <1024>;
+ touchscreen-size-y = <600>;
+ };
+};
+
+&epwmss0 {
+ status = "okay";
+};
+
+&tscadc {
+ status = "okay";
+
+ adc {
+ ti,adc-channels = <0 1 2 3 4 5 6 7>;
+ };
+};
+
+&ecap0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ecap0_pins>;
+};
+
+&gpio0 {
+ status = "okay";
+};
+
+&gpio3 {
+ status = "okay";
+};
+
+&gpio4 {
+ status = "okay";
+};
+
+&gpio5 {
+ status = "okay";
+ ti,no-reset-on-init;
+};
+
+&mmc1 {
+ status = "okay";
+ vmmc-supply = <&vmmcsd_fixed>;
+ bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+};
+
+&usb2_phy1 {
+ status = "okay";
+};
+
+&usb1 {
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usb2_phy2 {
+ status = "okay";
+};
+
+&usb2 {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&mac {
+ slaves = <1>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ status = "okay";
+};
+
+&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
+ status = "okay";
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <0>;
+ phy-mode = "rgmii";
+};
+
+&elm {
+ status = "okay";
+};
+
+&gpmc {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand_flash_x8>;
+ ranges = <0 0 0 0x01000000>; /* minimum GPMC partition = 16MB */
+ nand@0,0 {
+ reg = <0 0 4>; /* device IO registers */
+ ti,nand-ecc-opt = "bch16";
+ ti,elm-id = <&elm>;
+ nand-bus-width = <8>;
+ gpmc,device-width = <1>;
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <40>;
+ gpmc,cs-wr-off-ns = <40>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <25>;
+ gpmc,adv-wr-off-ns = <25>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <20>;
+ gpmc,oe-on-ns = <3>;
+ gpmc,oe-off-ns = <30>;
+ gpmc,access-ns = <30>;
+ gpmc,rd-cycle-ns = <40>;
+ gpmc,wr-cycle-ns = <40>;
+ gpmc,wait-pin = <0>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+ /* MTD partition table */
+ /* All SPL-* partitions are sized to minimal length
+ * which can be independently programmable. For
+ * NAND flash this is equal to size of erase-block */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "NAND.SPL";
+ reg = <0x00000000 0x00040000>;
+ };
+ partition@1 {
+ label = "NAND.SPL.backup1";
+ reg = <0x00040000 0x00040000>;
+ };
+ partition@2 {
+ label = "NAND.SPL.backup2";
+ reg = <0x00080000 0x00040000>;
+ };
+ partition@3 {
+ label = "NAND.SPL.backup3";
+ reg = <0x000c0000 0x00040000>;
+ };
+ partition@4 {
+ label = "NAND.u-boot-spl-os";
+ reg = <0x00100000 0x00080000>;
+ };
+ partition@5 {
+ label = "NAND.u-boot";
+ reg = <0x00180000 0x00100000>;
+ };
+ partition@6 {
+ label = "NAND.u-boot-env";
+ reg = <0x00280000 0x00040000>;
+ };
+ partition@7 {
+ label = "NAND.u-boot-env.backup1";
+ reg = <0x002c0000 0x00040000>;
+ };
+ partition@8 {
+ label = "NAND.kernel";
+ reg = <0x00300000 0x00700000>;
+ };
+ partition@9 {
+ label = "NAND.file-system";
+ reg = <0x00a00000 0x1f600000>;
+ };
+ };
+};
+
+&dss {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_pins>;
+
+ port {
+ dpi_out: endpoint@0 {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+&dcan0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&dcan0_default>;
+ status = "okay";
+};
+
+&dcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&dcan1_default>;
+ status = "okay";
+};
+
+&vpfe0 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&vpfe0_pins_default>;
+ pinctrl-1 = <&vpfe0_pins_sleep>;
+
+ port {
+ vpfe0_ep: endpoint {
+ /* remote-endpoint = <&sensor>; add once we have it */
+ ti,am437x-vpfe-interface = <0>;
+ bus-width = <8>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ };
+ };
+};
+
+&vpfe1 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&vpfe1_pins_default>;
+ pinctrl-1 = <&vpfe1_pins_sleep>;
+
+ port {
+ vpfe1_ep: endpoint {
+ /* remote-endpoint = <&sensor>; add once we have it */
+ ti,am437x-vpfe-interface = <0>;
+ bus-width = <8>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/am437x-idk-evm.dts b/arch/arm/boot/dts/am437x-idk-evm.dts
new file mode 100644
index 000000000..378344271
--- /dev/null
+++ b/arch/arm/boot/dts/am437x-idk-evm.dts
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/dts-v1/;
+
+#include "am4372.dtsi"
+#include <dt-bindings/pinctrl/am43xx.h>
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "TI AM437x Industrial Development Kit";
+ compatible = "ti,am437x-idk-evm","ti,am4372","ti,am43";
+
+ v24_0d: fixed-regulator-v24_0d {
+ compatible = "regulator-fixed";
+ regulator-name = "V24_0D";
+ regulator-min-microvolt = <24000000>;
+ regulator-max-microvolt = <24000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ v3_3d: fixed-regulator-v3_3d {
+ compatible = "regulator-fixed";
+ regulator-name = "V3_3D";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&v24_0d>;
+ };
+
+ vdd_corereg: fixed-regulator-vdd_corereg {
+ compatible = "regulator-fixed";
+ regulator-name = "VDD_COREREG";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&v24_0d>;
+ };
+
+ vdd_core: fixed-regulator-vdd_core {
+ compatible = "regulator-fixed";
+ regulator-name = "VDD_CORE";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vdd_corereg>;
+ };
+
+ v1_8dreg: fixed-regulator-v1_8dreg{
+ compatible = "regulator-fixed";
+ regulator-name = "V1_8DREG";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&v24_0d>;
+ };
+
+ v1_8d: fixed-regulator-v1_8d{
+ compatible = "regulator-fixed";
+ regulator-name = "V1_8D";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&v1_8dreg>;
+ };
+
+ v1_5dreg: fixed-regulator-v1_5dreg{
+ compatible = "regulator-fixed";
+ regulator-name = "V1_5DREG";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&v24_0d>;
+ };
+
+ v1_5d: fixed-regulator-v1_5d{
+ compatible = "regulator-fixed";
+ regulator-name = "V1_5D";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&v1_5dreg>;
+ };
+
+ gpio_keys: gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_keys_pins_default>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ switch@0 {
+ label = "power-button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio4 2 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&am43xx_pinmux {
+ gpio_keys_pins_default: gpio_keys_pins_default {
+ pinctrl-single,pins = <
+ 0x1b8 (PIN_INPUT | MUX_MODE7) /* cam0_field.gpio4_2 */
+ >;
+ };
+
+ i2c0_pins_default: i2c0_pins_default {
+ pinctrl-single,pins = <
+ 0x188 (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ 0x18c (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ >;
+ };
+
+ i2c0_pins_sleep: i2c0_pins_sleep {
+ pinctrl-single,pins = <
+ 0x188 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x18c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ i2c2_pins_default: i2c2_pins_default {
+ pinctrl-single,pins = <
+ 0x1e8 (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE3) /* cam1_data1.i2c2_scl */
+ 0x1ec (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE3) /* cam1_data0.i2c2_sda */
+ >;
+ };
+
+ i2c2_pins_sleep: i2c2_pins_sleep {
+ pinctrl-single,pins = <
+ 0x1e8 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x1ec (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ mmc1_pins_default: pinmux_mmc1_pins_default {
+ pinctrl-single,pins = <
+ 0x100 (PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+ 0x104 (PIN_INPUT | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+ 0x1f0 (PIN_INPUT | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+ 0x1f4 (PIN_INPUT | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+ 0x1f8 (PIN_INPUT | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+ 0x1fc (PIN_INPUT | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+ 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+ >;
+ };
+
+ mmc1_pins_sleep: pinmux_mmc1_pins_sleep {
+ pinctrl-single,pins = <
+ 0x100 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x104 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x1f0 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x1f4 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x1f8 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x1fc (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x160 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ ecap0_pins_default: backlight_pins_default {
+ pinctrl-single,pins = <
+ 0x164 (PIN_OUTPUT | MUX_MODE0) /* ecap0_in_pwm0_out.ecap0_in_pwm0_out */
+ >;
+ };
+
+ cpsw_default: cpsw_default {
+ pinctrl-single,pins = <
+ 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */
+ 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
+ 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
+ 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
+ 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td2 */
+ 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td3 */
+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rmii1_rclk */
+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rd0 */
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */
+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rd2 */
+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd3 */
+ >;
+ };
+
+ cpsw_sleep: cpsw_sleep {
+ pinctrl-single,pins = <
+ 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ davinci_mdio_default: davinci_mdio_default {
+ pinctrl-single,pins = <
+ /* MDIO */
+ 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
+ >;
+ };
+
+ davinci_mdio_sleep: davinci_mdio_sleep {
+ pinctrl-single,pins = <
+ /* MDIO reset value */
+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ qspi_pins_default: qspi_pins_default {
+ pinctrl-single,pins = <
+ 0x7c (PIN_OUTPUT_PULLUP | MUX_MODE3) /* gpmc_csn0.qspi_csn */
+ 0x88 (PIN_OUTPUT | MUX_MODE2) /* gpmc_csn3.qspi_clk */
+ 0x90 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_advn_ale.qspi_d0 */
+ 0x94 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_oen_ren.qspi_d1 */
+ 0x98 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_wen.qspi_d2 */
+ 0x9c (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_be0n_cle.qspi_d3 */
+ >;
+ };
+
+ qspi_pins_sleep: qspi_pins_sleep{
+ pinctrl-single,pins = <
+ 0x7c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x88 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x90 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x94 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x98 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x9c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c0_pins_default>;
+ pinctrl-1 = <&i2c0_pins_sleep>;
+ clock-frequency = <400000>;
+
+ at24@50 {
+ compatible = "at24,24c256";
+ pagesize = <64>;
+ reg = <0x50>;
+ };
+
+ tps: tps62362@60 {
+ compatible = "ti,tps62362";
+ reg = <0x60>;
+ regulator-name = "VDD_MPU";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1330000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ti,vsel0-state-high;
+ ti,vsel1-state-high;
+ vin-supply = <&v3_3d>;
+ };
+};
+
+&i2c2 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c2_pins_default>;
+ pinctrl-1 = <&i2c2_pins_sleep>;
+ clock-frequency = <100000>;
+};
+
+&epwmss0 {
+ status = "okay";
+};
+
+&ecap0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ecap0_pins_default>;
+};
+
+&gpio0 {
+ status = "okay";
+};
+
+&gpio1 {
+ status = "okay";
+};
+
+&gpio4 {
+ status = "okay";
+};
+
+&gpio5 {
+ status = "okay";
+};
+
+&mmc1 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&mmc1_pins_default>;
+ pinctrl-1 = <&mmc1_pins_sleep>;
+ vmmc-supply = <&v3_3d>;
+ bus-width = <4>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+};
+
+&qspi {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&qspi_pins_default>;
+ pinctrl-1 = <&qspi_pins_sleep>;
+
+ spi-max-frequency = <48000000>;
+ m25p80@0 {
+ compatible = "mx66l51235l";
+ spi-max-frequency = <48000000>;
+ reg = <0>;
+ spi-cpol;
+ spi-cpha;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /*
+ * MTD partition table. The ROM checks the first 512KiB for a
+ * valid file to boot(XIP).
+ */
+ partition@0 {
+ label = "QSPI.U_BOOT";
+ reg = <0x00000000 0x000080000>;
+ };
+ partition@1 {
+ label = "QSPI.U_BOOT.backup";
+ reg = <0x00080000 0x00080000>;
+ };
+ partition@2 {
+ label = "QSPI.U-BOOT-SPL_OS";
+ reg = <0x00100000 0x00010000>;
+ };
+ partition@3 {
+ label = "QSPI.U_BOOT_ENV";
+ reg = <0x00110000 0x00010000>;
+ };
+ partition@4 {
+ label = "QSPI.U-BOOT-ENV.backup";
+ reg = <0x00120000 0x00010000>;
+ };
+ partition@5 {
+ label = "QSPI.KERNEL";
+ reg = <0x00130000 0x0800000>;
+ };
+ partition@6 {
+ label = "QSPI.FILESYSTEM";
+ reg = <0x00930000 0x36D0000>;
+ };
+ };
+};
+
+&mac {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ status = "okay";
+};
+
+&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
+ status = "okay";
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <0>;
+ phy-mode = "rgmii";
+};
+
+&rtc {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
+
+&cpu {
+ cpu0-supply = <&tps>;
+};
diff --git a/arch/arm/boot/dts/am437x-sk-evm.dts b/arch/arm/boot/dts/am437x-sk-evm.dts
new file mode 100644
index 000000000..c17097d2c
--- /dev/null
+++ b/arch/arm/boot/dts/am437x-sk-evm.dts
@@ -0,0 +1,700 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/* AM437x SK EVM */
+
+/dts-v1/;
+
+#include "am4372.dtsi"
+#include <dt-bindings/pinctrl/am43xx.h>
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "TI AM437x SK EVM";
+ compatible = "ti,am437x-sk-evm","ti,am4372","ti,am43";
+
+ aliases {
+ display0 = &lcd0;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&ecap0 0 50000 PWM_POLARITY_INVERTED>;
+ brightness-levels = <0 51 53 56 62 75 101 152 255>;
+ default-brightness-level = <8>;
+ };
+
+ sound {
+ compatible = "ti,da830-evm-audio";
+ ti,model = "AM437x-SK-EVM";
+ ti,audio-codec = <&tlv320aic3106>;
+ ti,mcasp-controller = <&mcasp1>;
+ ti,codec-clock-rate = <24000000>;
+ ti,audio-routing =
+ "Headphone Jack", "HPLOUT",
+ "Headphone Jack", "HPROUT";
+ };
+
+ matrix_keypad: matrix_keypad@0 {
+ compatible = "gpio-matrix-keypad";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&matrix_keypad_pins>;
+
+ debounce-delay-ms = <5>;
+ col-scan-delay-us = <5>;
+
+ row-gpios = <&gpio5 5 GPIO_ACTIVE_HIGH /* Bank5, pin5 */
+ &gpio5 6 GPIO_ACTIVE_HIGH>; /* Bank5, pin6 */
+
+ col-gpios = <&gpio5 13 GPIO_ACTIVE_HIGH /* Bank5, pin13 */
+ &gpio5 4 GPIO_ACTIVE_HIGH>; /* Bank5, pin4 */
+
+ linux,keymap = <
+ MATRIX_KEY(0, 0, KEY_DOWN)
+ MATRIX_KEY(0, 1, KEY_RIGHT)
+ MATRIX_KEY(1, 0, KEY_LEFT)
+ MATRIX_KEY(1, 1, KEY_UP)
+ >;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_pins>;
+
+ led@0 {
+ label = "am437x-sk:red:heartbeat";
+ gpios = <&gpio5 0 GPIO_ACTIVE_HIGH>; /* Bank 5, pin 0 */
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+
+ led@1 {
+ label = "am437x-sk:green:mmc1";
+ gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; /* Bank 5, pin 1 */
+ linux,default-trigger = "mmc0";
+ default-state = "off";
+ };
+
+ led@2 {
+ label = "am437x-sk:blue:cpu0";
+ gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>; /* Bank 5, pin 2 */
+ linux,default-trigger = "cpu0";
+ default-state = "off";
+ };
+
+ led@3 {
+ label = "am437x-sk:blue:usr3";
+ gpios = <&gpio5 3 GPIO_ACTIVE_HIGH>; /* Bank 5, pin 3 */
+ default-state = "off";
+ };
+ };
+
+ lcd0: display {
+ compatible = "newhaven,nhd-4.3-480272ef-atxl", "panel-dpi";
+ label = "lcd";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_pins>;
+
+ enable-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+
+ panel-timing {
+ clock-frequency = <9000000>;
+ hactive = <480>;
+ vactive = <272>;
+ hfront-porch = <2>;
+ hback-porch = <2>;
+ hsync-len = <41>;
+ vfront-porch = <2>;
+ vback-porch = <2>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+ };
+};
+
+&am43xx_pinmux {
+ matrix_keypad_pins: matrix_keypad_pins {
+ pinctrl-single,pins = <
+ 0x24c (PIN_OUTPUT | MUX_MODE7) /* gpio5_13.gpio5_13 */
+ 0x250 (PIN_OUTPUT | MUX_MODE7) /* spi4_sclk.gpio5_4 */
+ 0x254 (PIN_INPUT | MUX_MODE7) /* spi4_d0.gpio5_5 */
+ 0x258 (PIN_INPUT | MUX_MODE7) /* spi4_d1.gpio5_5 */
+ >;
+ };
+
+ leds_pins: leds_pins {
+ pinctrl-single,pins = <
+ 0x228 (PIN_OUTPUT | MUX_MODE7) /* uart3_rxd.gpio5_2 */
+ 0x22c (PIN_OUTPUT | MUX_MODE7) /* uart3_txd.gpio5_3 */
+ 0x230 (PIN_OUTPUT | MUX_MODE7) /* uart3_ctsn.gpio5_0 */
+ 0x234 (PIN_OUTPUT | MUX_MODE7) /* uart3_rtsn.gpio5_1 */
+ >;
+ };
+
+ i2c0_pins: i2c0_pins {
+ pinctrl-single,pins = <
+ 0x188 (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ 0x18c (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ >;
+ };
+
+ i2c1_pins: i2c1_pins {
+ pinctrl-single,pins = <
+ 0x15c (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE2) /* spi0_cs0.i2c1_scl */
+ 0x158 (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE2) /* spi0_d1.i2c1_sda */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ 0x0f0 (PIN_INPUT | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+ 0x0f4 (PIN_INPUT | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+ 0x0f8 (PIN_INPUT | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+ 0x0fc (PIN_INPUT | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+ 0x100 (PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+ 0x104 (PIN_INPUT | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+ 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+ >;
+ };
+
+ ecap0_pins: backlight_pins {
+ pinctrl-single,pins = <
+ 0x164 (PIN_OUTPUT | MUX_MODE0) /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out */
+ >;
+ };
+
+ edt_ft5306_ts_pins: edt_ft5306_ts_pins {
+ pinctrl-single,pins = <
+ 0x74 (PIN_INPUT | MUX_MODE7) /* gpmc_wpn.gpio0_31 */
+ 0x78 (PIN_OUTPUT | MUX_MODE7) /* gpmc_be1n.gpio1_28 */
+ >;
+ };
+
+ vpfe0_pins_default: vpfe0_pins_default {
+ pinctrl-single,pins = <
+ 0x1b0 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_hd mode 0*/
+ 0x1b4 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_vd mode 0*/
+ 0x1b8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_field mode 0*/
+ 0x1bc (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_wen mode 0*/
+ 0x1c0 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_pclk mode 0*/
+ 0x1c4 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data8 mode 0*/
+ 0x1c8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data9 mode 0*/
+ 0x208 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data0 mode 0*/
+ 0x20c (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data1 mode 0*/
+ 0x210 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data2 mode 0*/
+ 0x214 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data3 mode 0*/
+ 0x218 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data4 mode 0*/
+ 0x21c (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data5 mode 0*/
+ 0x220 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data6 mode 0*/
+ 0x224 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data7 mode 0*/
+ >;
+ };
+
+ vpfe0_pins_sleep: vpfe0_pins_sleep {
+ pinctrl-single,pins = <
+ 0x1b0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1b4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1b8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1bc (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1c0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1c4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1c8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x208 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x20c (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x210 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x214 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x218 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x21c (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x220 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x224 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ >;
+ };
+
+ cpsw_default: cpsw_default {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ 0x12c (PIN_OUTPUT | MUX_MODE2) /* mii1_txclk.rmii1_tclk */
+ 0x114 (PIN_OUTPUT | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
+ 0x128 (PIN_OUTPUT | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
+ 0x124 (PIN_OUTPUT | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
+ 0x120 (PIN_OUTPUT | MUX_MODE2) /* mii1_txd0.rgmii1_td2 */
+ 0x11c (PIN_OUTPUT | MUX_MODE2) /* mii1_txd1.rgmii1_td3 */
+ 0x130 (PIN_INPUT | MUX_MODE2) /* mii1_rxclk.rmii1_rclk */
+ 0x118 (PIN_INPUT | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */
+ 0x140 (PIN_INPUT | MUX_MODE2) /* mii1_rxd0.rgmii1_rd0 */
+ 0x13c (PIN_INPUT | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */
+ 0x138 (PIN_INPUT | MUX_MODE2) /* mii1_rxd0.rgmii1_rd2 */
+ 0x134 (PIN_INPUT | MUX_MODE2) /* mii1_rxd1.rgmii1_rd3 */
+
+ /* Slave 2 */
+ 0x58 (PIN_OUTPUT | MUX_MODE2) /* gpmc_a6.rgmii2_tclk */
+ 0x40 (PIN_OUTPUT | MUX_MODE2) /* gpmc_a0.rgmii2_tctl */
+ 0x54 (PIN_OUTPUT | MUX_MODE2) /* gpmc_a5.rgmii2_td0 */
+ 0x50 (PIN_OUTPUT | MUX_MODE2) /* gpmc_a4.rgmii2_td1 */
+ 0x4c (PIN_OUTPUT | MUX_MODE2) /* gpmc_a3.rgmii2_td2 */
+ 0x48 (PIN_OUTPUT | MUX_MODE2) /* gpmc_a2.rgmii2_td3 */
+ 0x5c (PIN_INPUT | MUX_MODE2) /* gpmc_a7.rgmii2_rclk */
+ 0x44 (PIN_INPUT | MUX_MODE2) /* gpmc_a1.rgmii2_rtcl */
+ 0x6c (PIN_INPUT | MUX_MODE2) /* gpmc_a11.rgmii2_rd0 */
+ 0x68 (PIN_INPUT | MUX_MODE2) /* gpmc_a10.rgmii2_rd1 */
+ 0x64 (PIN_INPUT | MUX_MODE2) /* gpmc_a9.rgmii2_rd2 */
+ 0x60 (PIN_INPUT | MUX_MODE2) /* gpmc_a8.rgmii2_rd3 */
+ >;
+ };
+
+ cpsw_sleep: cpsw_sleep {
+ pinctrl-single,pins = <
+ /* Slave 1 reset value */
+ 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+
+ /* Slave 2 reset value */
+ 0x58 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x4c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x48 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x5c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x44 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x60 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ davinci_mdio_default: davinci_mdio_default {
+ pinctrl-single,pins = <
+ /* MDIO */
+ 0x148 (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ 0x14c (PIN_OUTPUT | MUX_MODE0) /* mdio_clk.mdio_clk */
+ >;
+ };
+
+ davinci_mdio_sleep: davinci_mdio_sleep {
+ pinctrl-single,pins = <
+ /* MDIO reset value */
+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ dss_pins: dss_pins {
+ pinctrl-single,pins = <
+ 0x020 (PIN_OUTPUT | MUX_MODE1) /* gpmc ad 8 -> DSS DATA 23 */
+ 0x024 (PIN_OUTPUT | MUX_MODE1)
+ 0x028 (PIN_OUTPUT | MUX_MODE1)
+ 0x02c (PIN_OUTPUT | MUX_MODE1)
+ 0x030 (PIN_OUTPUT | MUX_MODE1)
+ 0x034 (PIN_OUTPUT | MUX_MODE1)
+ 0x038 (PIN_OUTPUT | MUX_MODE1)
+ 0x03c (PIN_OUTPUT | MUX_MODE1) /* gpmc ad 15 -> DSS DATA 16 */
+ 0x0a0 (PIN_OUTPUT | MUX_MODE0) /* DSS DATA 0 */
+ 0x0a4 (PIN_OUTPUT | MUX_MODE0)
+ 0x0a8 (PIN_OUTPUT | MUX_MODE0)
+ 0x0ac (PIN_OUTPUT | MUX_MODE0)
+ 0x0b0 (PIN_OUTPUT | MUX_MODE0)
+ 0x0b4 (PIN_OUTPUT | MUX_MODE0)
+ 0x0b8 (PIN_OUTPUT | MUX_MODE0)
+ 0x0bc (PIN_OUTPUT | MUX_MODE0)
+ 0x0c0 (PIN_OUTPUT | MUX_MODE0)
+ 0x0c4 (PIN_OUTPUT | MUX_MODE0)
+ 0x0c8 (PIN_OUTPUT | MUX_MODE0)
+ 0x0cc (PIN_OUTPUT | MUX_MODE0)
+ 0x0d0 (PIN_OUTPUT | MUX_MODE0)
+ 0x0d4 (PIN_OUTPUT | MUX_MODE0)
+ 0x0d8 (PIN_OUTPUT | MUX_MODE0)
+ 0x0dc (PIN_OUTPUT | MUX_MODE0) /* DSS DATA 15 */
+ 0x0e0 (PIN_OUTPUT | MUX_MODE0) /* DSS VSYNC */
+ 0x0e4 (PIN_OUTPUT | MUX_MODE0) /* DSS HSYNC */
+ 0x0e8 (PIN_OUTPUT | MUX_MODE0) /* DSS PCLK */
+ 0x0ec (PIN_OUTPUT | MUX_MODE0) /* DSS AC BIAS EN */
+
+ >;
+ };
+
+ qspi_pins: qspi_pins {
+ pinctrl-single,pins = <
+ 0x7c (PIN_OUTPUT | MUX_MODE3) /* gpmc_csn0.qspi_csn */
+ 0x88 (PIN_OUTPUT | MUX_MODE2) /* gpmc_csn3.qspi_clk */
+ 0x90 (PIN_INPUT | MUX_MODE3) /* gpmc_advn_ale.qspi_d0 */
+ 0x94 (PIN_INPUT | MUX_MODE3) /* gpmc_oen_ren.qspi_d1 */
+ 0x98 (PIN_INPUT | MUX_MODE3) /* gpmc_wen.qspi_d2 */
+ 0x9c (PIN_INPUT | MUX_MODE3) /* gpmc_be0n_cle.qspi_d3 */
+ >;
+ };
+
+ mcasp1_pins: mcasp1_pins {
+ pinctrl-single,pins = <
+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */
+ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */
+ 0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
+ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
+ >;
+ };
+
+ lcd_pins: lcd_pins {
+ pinctrl-single,pins = <
+ 0x1c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpcm_ad7.gpio1_7 */
+ >;
+ };
+
+ usb1_pins: usb1_pins {
+ pinctrl-single,pins = <
+ 0x2c0 (PIN_OUTPUT | MUX_MODE0) /* usb0_drvvbus.usb0_drvvbus */
+ >;
+ };
+
+ usb2_pins: usb2_pins {
+ pinctrl-single,pins = <
+ 0x2c4 (PIN_OUTPUT | MUX_MODE0) /* usb0_drvvbus.usb0_drvvbus */
+ >;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <400000>;
+
+ tps@24 {
+ compatible = "ti,tps65218";
+ reg = <0x24>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ dcdc1: regulator-dcdc1 {
+ compatible = "ti,tps65218-dcdc1";
+ /* VDD_CORE limits min of OPP50 and max of OPP100 */
+ regulator-name = "vdd_core";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <1144000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ dcdc2: regulator-dcdc2 {
+ compatible = "ti,tps65218-dcdc2";
+ /* VDD_MPU limits min of OPP50 and max of OPP_NITRO */
+ regulator-name = "vdd_mpu";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <1378000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ dcdc3: regulator-dcdc3 {
+ compatible = "ti,tps65218-dcdc3";
+ regulator-name = "vdds_ddr";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ dcdc4: regulator-dcdc4 {
+ compatible = "ti,tps65218-dcdc4";
+ regulator-name = "v3_3d";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1: regulator-ldo1 {
+ compatible = "ti,tps65218-ldo1";
+ regulator-name = "v1_8d";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ power-button {
+ compatible = "ti,tps65218-pwrbutton";
+ status = "okay";
+ interrupts = <3 IRQ_TYPE_EDGE_BOTH>;
+ };
+ };
+
+ at24@50 {
+ compatible = "at24,24c256";
+ pagesize = <64>;
+ reg = <0x50>;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <400000>;
+
+ edt-ft5306@38 {
+ status = "okay";
+ compatible = "edt,edt-ft5306", "edt,edt-ft5x06";
+ pinctrl-names = "default";
+ pinctrl-0 = <&edt_ft5306_ts_pins>;
+
+ reg = <0x38>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <31 0>;
+
+ reset-gpios = <&gpio1 28 GPIO_ACTIVE_LOW>;
+
+ touchscreen-size-x = <480>;
+ touchscreen-size-y = <272>;
+ };
+
+ tlv320aic3106: tlv320aic3106@1b {
+ compatible = "ti,tlv320aic3106";
+ reg = <0x1b>;
+ status = "okay";
+
+ /* Regulators */
+ AVDD-supply = <&dcdc4>;
+ IOVDD-supply = <&dcdc4>;
+ DRVDD-supply = <&dcdc4>;
+ DVDD-supply = <&ldo1>;
+ };
+
+ lis331dlh@18 {
+ compatible = "st,lis331dlh";
+ reg = <0x18>;
+ status = "okay";
+
+ Vdd-supply = <&dcdc4>;
+ Vdd_IO-supply = <&dcdc4>;
+ interrupts-extended = <&gpio1 6 0>, <&gpio2 1 0>;
+ };
+};
+
+&epwmss0 {
+ status = "okay";
+};
+
+&ecap0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ecap0_pins>;
+};
+
+&gpio0 {
+ status = "okay";
+};
+
+&gpio1 {
+ status = "okay";
+};
+
+&gpio5 {
+ status = "okay";
+};
+
+&mmc1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+
+ vmmc-supply = <&dcdc4>;
+ bus-width = <4>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+};
+
+&usb2_phy1 {
+ status = "okay";
+};
+
+&usb1 {
+ dr_mode = "peripheral";
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_pins>;
+};
+
+&usb2_phy2 {
+ status = "okay";
+};
+
+&usb2 {
+ dr_mode = "host";
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb2_pins>;
+};
+
+&qspi {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&qspi_pins>;
+
+ spi-max-frequency = <48000000>;
+ m25p80@0 {
+ compatible = "mx66l51235l";
+ spi-max-frequency = <48000000>;
+ reg = <0>;
+ spi-cpol;
+ spi-cpha;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /* MTD partition table.
+ * The ROM checks the first 512KiB
+ * for a valid file to boot(XIP).
+ */
+ partition@0 {
+ label = "QSPI.U_BOOT";
+ reg = <0x00000000 0x000080000>;
+ };
+ partition@1 {
+ label = "QSPI.U_BOOT.backup";
+ reg = <0x00080000 0x00080000>;
+ };
+ partition@2 {
+ label = "QSPI.U-BOOT-SPL_OS";
+ reg = <0x00100000 0x00010000>;
+ };
+ partition@3 {
+ label = "QSPI.U_BOOT_ENV";
+ reg = <0x00110000 0x00010000>;
+ };
+ partition@4 {
+ label = "QSPI.U-BOOT-ENV.backup";
+ reg = <0x00120000 0x00010000>;
+ };
+ partition@5 {
+ label = "QSPI.KERNEL";
+ reg = <0x00130000 0x0800000>;
+ };
+ partition@6 {
+ label = "QSPI.FILESYSTEM";
+ reg = <0x00930000 0x36D0000>;
+ };
+ };
+};
+
+&mac {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ dual_emac = <1>;
+ status = "okay";
+};
+
+&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
+ status = "okay";
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <4>;
+ phy-mode = "rgmii";
+ dual_emac_res_vlan = <1>;
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <5>;
+ phy-mode = "rgmii";
+ dual_emac_res_vlan = <2>;
+};
+
+&elm {
+ status = "okay";
+};
+
+&mcasp1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcasp1_pins>;
+
+ status = "okay";
+
+ op-mode = <0>;
+ tdm-slots = <2>;
+ serial-dir = <
+ 0 0 1 2
+ >;
+
+ tx-num-evt = <1>;
+ rx-num-evt = <1>;
+};
+
+&dss {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_pins>;
+
+ port {
+ dpi_out: endpoint@0 {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+&rtc {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
+
+&cpu {
+ cpu0-supply = <&dcdc2>;
+};
+
+&vpfe0 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&vpfe0_pins_default>;
+ pinctrl-1 = <&vpfe0_pins_sleep>;
+
+ /* Camera port */
+ port {
+ vpfe0_ep: endpoint {
+ /* remote-endpoint = <&sensor>; add once we have it */
+ ti,am437x-vpfe-interface = <0>;
+ bus-width = <8>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts
new file mode 100644
index 000000000..795d68af6
--- /dev/null
+++ b/arch/arm/boot/dts/am43x-epos-evm.dts
@@ -0,0 +1,688 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+/* AM43x EPOS EVM */
+
+/dts-v1/;
+
+#include "am4372.dtsi"
+#include <dt-bindings/pinctrl/am43xx.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ model = "TI AM43x EPOS EVM";
+ compatible = "ti,am43x-epos-evm","ti,am4372","ti,am43";
+
+ aliases {
+ display0 = &lcd0;
+ };
+
+ vmmcsd_fixed: fixedregulator-sd {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsd_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ };
+
+ lcd0: display {
+ compatible = "osddisplays,osd057T0559-34ts", "panel-dpi";
+ label = "lcd";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_pins>;
+
+ /*
+ * SelLCDorHDMI, LOW to select HDMI. This is not really the
+ * panel's enable GPIO, but we don't have HDMI driver support nor
+ * support to switch between two displays, so using this gpio as
+ * panel's enable should be safe.
+ */
+ enable-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+
+ panel-timing {
+ clock-frequency = <33000000>;
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <210>;
+ hback-porch = <16>;
+ hsync-len = <30>;
+ vback-porch = <10>;
+ vfront-porch = <22>;
+ vsync-len = <13>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+ };
+
+ matrix_keypad: matrix_keypad@0 {
+ compatible = "gpio-matrix-keypad";
+ debounce-delay-ms = <5>;
+ col-scan-delay-us = <2>;
+
+ row-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH /* Bank0, pin12 */
+ &gpio0 13 GPIO_ACTIVE_HIGH /* Bank0, pin13 */
+ &gpio0 14 GPIO_ACTIVE_HIGH /* Bank0, pin14 */
+ &gpio0 15 GPIO_ACTIVE_HIGH>; /* Bank0, pin15 */
+
+ col-gpios = <&gpio3 9 GPIO_ACTIVE_HIGH /* Bank3, pin9 */
+ &gpio3 10 GPIO_ACTIVE_HIGH /* Bank3, pin10 */
+ &gpio2 18 GPIO_ACTIVE_HIGH /* Bank2, pin18 */
+ &gpio2 19 GPIO_ACTIVE_HIGH>; /* Bank2, pin19 */
+
+ linux,keymap = <0x00000201 /* P1 */
+ 0x01000204 /* P4 */
+ 0x02000207 /* P7 */
+ 0x0300020a /* NUMERIC_STAR */
+ 0x00010202 /* P2 */
+ 0x01010205 /* P5 */
+ 0x02010208 /* P8 */
+ 0x03010200 /* P0 */
+ 0x00020203 /* P3 */
+ 0x01020206 /* P6 */
+ 0x02020209 /* P9 */
+ 0x0302020b /* NUMERIC_POUND */
+ 0x00030067 /* UP */
+ 0x0103006a /* RIGHT */
+ 0x0203006c /* DOWN */
+ 0x03030069>; /* LEFT */
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&ecap0 0 50000 PWM_POLARITY_INVERTED>;
+ brightness-levels = <0 51 53 56 62 75 101 152 255>;
+ default-brightness-level = <8>;
+ };
+};
+
+&am43xx_pinmux {
+ cpsw_default: cpsw_default {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_crs.rmii1_crs */
+ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxerr.rmii1_rxerr */
+ 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txen.rmii1_txen */
+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxdv.rmii1_rxdv */
+ 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd1.rmii1_txd1 */
+ 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd0.rmii1_txd0 */
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxd1.rmii1_rxd1 */
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxd0.rmii1_rxd0 */
+ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii1_refclk.rmii1_refclk */
+ >;
+ };
+
+ cpsw_sleep: cpsw_sleep {
+ pinctrl-single,pins = <
+ /* Slave 1 reset value */
+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ davinci_mdio_default: davinci_mdio_default {
+ pinctrl-single,pins = <
+ /* MDIO */
+ 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
+ >;
+ };
+
+ davinci_mdio_sleep: davinci_mdio_sleep {
+ pinctrl-single,pins = <
+ /* MDIO reset value */
+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ i2c0_pins: pinmux_i2c0_pins {
+ pinctrl-single,pins = <
+ 0x188 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ 0x18c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ >;
+ };
+
+ nand_flash_x8: nand_flash_x8 {
+ pinctrl-single,pins = <
+ 0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a0.SELQSPIorNAND/GPIO */
+ 0x0 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
+ 0x4 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
+ 0x8 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
+ 0xc (PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
+ 0x10 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
+ 0x14 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
+ 0x18 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
+ 0x1c (PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
+ 0x70 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
+ 0x74 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpmc_wpn */
+ 0x7c (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
+ 0x90 (PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
+ 0x94 (PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
+ 0x98 (PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */
+ 0x9c (PIN_OUTPUT | MUX_MODE0) /* gpmc_be0n_cle.gpmc_be0n_cle */
+ >;
+ };
+
+ ecap0_pins: backlight_pins {
+ pinctrl-single,pins = <
+ 0x164 MUX_MODE0 /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */
+ >;
+ };
+
+ i2c2_pins: pinmux_i2c2_pins {
+ pinctrl-single,pins = <
+ 0x1c0 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE8) /* i2c2_sda.i2c2_sda */
+ 0x1c4 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE8) /* i2c2_scl.i2c2_scl */
+ >;
+ };
+
+ spi0_pins: pinmux_spi0_pins {
+ pinctrl-single,pins = <
+ 0x150 (PIN_INPUT | MUX_MODE0) /* spi0_clk.spi0_clk */
+ 0x154 (PIN_OUTPUT | MUX_MODE0) /* spi0_d0.spi0_d0 */
+ 0x158 (PIN_INPUT | MUX_MODE0) /* spi0_d1.spi0_d1 */
+ 0x15c (PIN_OUTPUT | MUX_MODE0) /* spi0_cs0.spi0_cs0 */
+ >;
+ };
+
+ spi1_pins: pinmux_spi1_pins {
+ pinctrl-single,pins = <
+ 0x190 (PIN_INPUT | MUX_MODE3) /* mcasp0_aclkx.spi1_clk */
+ 0x194 (PIN_OUTPUT | MUX_MODE3) /* mcasp0_fsx.spi1_d0 */
+ 0x198 (PIN_INPUT | MUX_MODE3) /* mcasp0_axr0.spi1_d1 */
+ 0x19c (PIN_OUTPUT | MUX_MODE3) /* mcasp0_ahclkr.spi1_cs0 */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+ >;
+ };
+
+ qspi1_default: qspi1_default {
+ pinctrl-single,pins = <
+ 0x7c (PIN_INPUT_PULLUP | MUX_MODE3)
+ 0x88 (PIN_INPUT_PULLUP | MUX_MODE2)
+ 0x90 (PIN_INPUT_PULLUP | MUX_MODE3)
+ 0x94 (PIN_INPUT_PULLUP | MUX_MODE3)
+ 0x98 (PIN_INPUT_PULLUP | MUX_MODE3)
+ 0x9c (PIN_INPUT_PULLUP | MUX_MODE3)
+ >;
+ };
+
+ pixcir_ts_pins: pixcir_ts_pins {
+ pinctrl-single,pins = <
+ 0x44 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a1.gpio1_17 */
+ >;
+ };
+
+ hdq_pins: pinmux_hdq_pins {
+ pinctrl-single,pins = <
+ 0x234 (PIN_INPUT_PULLUP | MUX_MODE1) /* cam1_wen.hdq_gpio */
+ >;
+ };
+
+ dss_pins: dss_pins {
+ pinctrl-single,pins = <
+ 0x020 (PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 8 -> DSS DATA 23 */
+ 0x024 (PIN_OUTPUT_PULLUP | MUX_MODE1)
+ 0x028 (PIN_OUTPUT_PULLUP | MUX_MODE1)
+ 0x02C (PIN_OUTPUT_PULLUP | MUX_MODE1)
+ 0x030 (PIN_OUTPUT_PULLUP | MUX_MODE1)
+ 0x034 (PIN_OUTPUT_PULLUP | MUX_MODE1)
+ 0x038 (PIN_OUTPUT_PULLUP | MUX_MODE1)
+ 0x03C (PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 15 -> DSS DATA 16 */
+ 0x0A0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 0 */
+ 0x0A4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0A8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0AC (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0B0 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0B4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0B8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0BC (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0C0 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0C4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0C8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0CC (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0D0 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0D4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0D8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ 0x0DC (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 15 */
+ 0x0E0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS VSYNC */
+ 0x0E4 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS HSYNC */
+ 0x0E8 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS PCLK */
+ 0x0EC (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS AC BIAS EN */
+ >;
+ };
+
+ lcd_pins: lcd_pins {
+ pinctrl-single,pins = <
+ /* GPMC CLK -> GPIO 2_1 to select LCD / HDMI */
+ 0x08C (PIN_OUTPUT_PULLUP | MUX_MODE7)
+ >;
+ };
+
+ vpfe1_pins_default: vpfe1_pins_default {
+ pinctrl-single,pins = <
+ 0x1cc (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data9 mode 0 */
+ 0x1d0 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data8 mode 0 */
+ 0x1d4 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_hd mode 0 */
+ 0x1d8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_vd mode 0 */
+ 0x1dc (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_pclk mode 0 */
+ 0x1e8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data0 mode 0 */
+ 0x1ec (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data1 mode 0 */
+ 0x1f0 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data2 mode 0 */
+ 0x1f4 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data3 mode 0 */
+ 0x1f8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data4 mode 0 */
+ 0x1fc (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data5 mode 0 */
+ 0x200 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data6 mode 0 */
+ 0x204 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data7 mode 0 */
+ >;
+ };
+
+ vpfe1_pins_sleep: vpfe1_pins_sleep {
+ pinctrl-single,pins = <
+ 0x1cc (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1d0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1d4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1d8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1dc (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1e8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1ec (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1f0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1f4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1f8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1fc (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x200 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x204 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ >;
+ };
+};
+
+&mmc1 {
+ status = "okay";
+ vmmc-supply = <&vmmcsd_fixed>;
+ bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+};
+
+&mac {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ status = "okay";
+};
+
+&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
+ status = "okay";
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <16>;
+ phy-mode = "rmii";
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <1>;
+ phy-mode = "rmii";
+};
+
+&phy_sel {
+ rmii-clock-ext;
+};
+
+&i2c0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <400000>;
+
+ tps65218: tps65218@24 {
+ reg = <0x24>;
+ compatible = "ti,tps65218";
+ interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* NMIn */
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ dcdc1: regulator-dcdc1 {
+ compatible = "ti,tps65218-dcdc1";
+ regulator-name = "vdd_core";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <1144000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ dcdc2: regulator-dcdc2 {
+ compatible = "ti,tps65218-dcdc2";
+ regulator-name = "vdd_mpu";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <1378000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ dcdc3: regulator-dcdc3 {
+ compatible = "ti,tps65218-dcdc3";
+ regulator-name = "vdcdc3";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ dcdc5: regulator-dcdc5 {
+ compatible = "ti,tps65218-dcdc5";
+ regulator-name = "v1_0bat";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ dcdc6: regulator-dcdc6 {
+ compatible = "ti,tps65218-dcdc6";
+ regulator-name = "v1_8bat";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo1: regulator-ldo1 {
+ compatible = "ti,tps65218-ldo1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+
+ at24@50 {
+ compatible = "at24,24c256";
+ pagesize = <64>;
+ reg = <0x50>;
+ };
+
+ pixcir_ts@5c {
+ compatible = "pixcir,pixcir_tangoc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pixcir_ts_pins>;
+ reg = <0x5c>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <17 0>;
+
+ attb-gpio = <&gpio1 17 GPIO_ACTIVE_HIGH>;
+
+ touchscreen-size-x = <1024>;
+ touchscreen-size-y = <600>;
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+ status = "okay";
+};
+
+&gpio0 {
+ status = "okay";
+};
+
+&gpio1 {
+ status = "okay";
+};
+
+&gpio2 {
+ status = "okay";
+};
+
+&gpio3 {
+ status = "okay";
+};
+
+&elm {
+ status = "okay";
+};
+
+&gpmc {
+ status = "okay"; /* Disable QSPI when enabling GPMC (NAND) */
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand_flash_x8>;
+ ranges = <0 0 0x08000000 0x1000000>; /* CS0: 16MB for NAND */
+ nand@0,0 {
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ ti,nand-ecc-opt = "bch16";
+ ti,elm-id = <&elm>;
+ nand-bus-width = <8>;
+ gpmc,device-width = <1>;
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <40>; /* tCEA + tCHZ + 1 */
+ gpmc,cs-wr-off-ns = <40>;
+ gpmc,adv-on-ns = <0>; /* cs-on-ns */
+ gpmc,adv-rd-off-ns = <25>; /* min( tALH + tALS + 1) */
+ gpmc,adv-wr-off-ns = <25>; /* min( tALH + tALS + 1) */
+ gpmc,we-on-ns = <0>; /* cs-on-ns */
+ gpmc,we-off-ns = <20>; /* we-on-time + tWP + 2 */
+ gpmc,oe-on-ns = <3>; /* cs-on-ns + tRR + 2 */
+ gpmc,oe-off-ns = <30>; /* oe-on-ns + tRP + 2 */
+ gpmc,access-ns = <30>; /* tCEA + 4*/
+ gpmc,rd-cycle-ns = <40>;
+ gpmc,wr-cycle-ns = <40>;
+ gpmc,wait-pin = <0>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+ /* MTD partition table */
+ /* All SPL-* partitions are sized to minimal length
+ * which can be independently programmable. For
+ * NAND flash this is equal to size of erase-block */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "NAND.SPL";
+ reg = <0x00000000 0x00040000>;
+ };
+ partition@1 {
+ label = "NAND.SPL.backup1";
+ reg = <0x00040000 0x00040000>;
+ };
+ partition@2 {
+ label = "NAND.SPL.backup2";
+ reg = <0x00080000 0x00040000>;
+ };
+ partition@3 {
+ label = "NAND.SPL.backup3";
+ reg = <0x000C0000 0x00040000>;
+ };
+ partition@4 {
+ label = "NAND.u-boot-spl-os";
+ reg = <0x00100000 0x00080000>;
+ };
+ partition@5 {
+ label = "NAND.u-boot";
+ reg = <0x00180000 0x00100000>;
+ };
+ partition@6 {
+ label = "NAND.u-boot-env";
+ reg = <0x00280000 0x00040000>;
+ };
+ partition@7 {
+ label = "NAND.u-boot-env.backup1";
+ reg = <0x002C0000 0x00040000>;
+ };
+ partition@8 {
+ label = "NAND.kernel";
+ reg = <0x00300000 0x00700000>;
+ };
+ partition@9 {
+ label = "NAND.file-system";
+ reg = <0x00a00000 0x1f600000>;
+ };
+ };
+};
+
+&epwmss0 {
+ status = "okay";
+};
+
+&tscadc {
+ status = "okay";
+
+ adc {
+ ti,adc-channels = <0 1 2 3 4 5 6 7>;
+ };
+};
+
+&ecap0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ecap0_pins>;
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ status = "okay";
+};
+
+&spi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins>;
+ status = "okay";
+};
+
+&usb2_phy1 {
+ status = "okay";
+};
+
+&usb1 {
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usb2_phy2 {
+ status = "okay";
+};
+
+&usb2 {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&qspi {
+ status = "disabled"; /* Disable GPMC (NAND) when enabling QSPI */
+ pinctrl-names = "default";
+ pinctrl-0 = <&qspi1_default>;
+
+ spi-max-frequency = <48000000>;
+ m25p80@0 {
+ compatible = "mx66l51235l";
+ spi-max-frequency = <48000000>;
+ reg = <0>;
+ spi-cpol;
+ spi-cpha;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /* MTD partition table.
+ * The ROM checks the first 512KiB
+ * for a valid file to boot(XIP).
+ */
+ partition@0 {
+ label = "QSPI.U_BOOT";
+ reg = <0x00000000 0x000080000>;
+ };
+ partition@1 {
+ label = "QSPI.U_BOOT.backup";
+ reg = <0x00080000 0x00080000>;
+ };
+ partition@2 {
+ label = "QSPI.U-BOOT-SPL_OS";
+ reg = <0x00100000 0x00010000>;
+ };
+ partition@3 {
+ label = "QSPI.U_BOOT_ENV";
+ reg = <0x00110000 0x00010000>;
+ };
+ partition@4 {
+ label = "QSPI.U-BOOT-ENV.backup";
+ reg = <0x00120000 0x00010000>;
+ };
+ partition@5 {
+ label = "QSPI.KERNEL";
+ reg = <0x00130000 0x0800000>;
+ };
+ partition@6 {
+ label = "QSPI.FILESYSTEM";
+ reg = <0x00930000 0x36D0000>;
+ };
+ };
+};
+
+&hdq {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdq_pins>;
+};
+
+&dss {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_pins>;
+
+ port {
+ dpi_out: endpoint@0 {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+&vpfe1 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&vpfe1_pins_default>;
+ pinctrl-1 = <&vpfe1_pins_sleep>;
+
+ port {
+ vpfe1_ep: endpoint {
+ /* remote-endpoint = <&sensor>; add once we have it */
+ ti,am437x-vpfe-interface = <0>;
+ bus-width = <8>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/am43xx-clocks.dtsi b/arch/arm/boot/dts/am43xx-clocks.dtsi
new file mode 100644
index 000000000..d0c0dfa4e
--- /dev/null
+++ b/arch/arm/boot/dts/am43xx-clocks.dtsi
@@ -0,0 +1,757 @@
+/*
+ * Device Tree Source for AM43xx clock data
+ *
+ * Copyright (C) 2013 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.
+ */
+&scm_clocks {
+ sys_clkin_ck: sys_clkin_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sysboot_freq_sel_ck>, <&crystal_freq_sel_ck>;
+ ti,bit-shift = <31>;
+ reg = <0x0040>;
+ };
+
+ crystal_freq_sel_ck: crystal_freq_sel_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&virt_19200000_ck>, <&virt_24000000_ck>, <&virt_25000000_ck>, <&virt_26000000_ck>;
+ ti,bit-shift = <29>;
+ reg = <0x0040>;
+ };
+
+ sysboot_freq_sel_ck: sysboot_freq_sel_ck@44e10040 {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&virt_19200000_ck>, <&virt_24000000_ck>, <&virt_25000000_ck>, <&virt_26000000_ck>;
+ ti,bit-shift = <22>;
+ reg = <0x0040>;
+ };
+
+ adc_tsc_fck: adc_tsc_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dcan0_fck: dcan0_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dcan1_fck: dcan1_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ mcasp0_fck: mcasp0_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ mcasp1_fck: mcasp1_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ smartreflex0_fck: smartreflex0_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ smartreflex1_fck: smartreflex1_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ sha0_fck: sha0_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ aes0_fck: aes0_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ ehrpwm0_tbclk: ehrpwm0_tbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l4ls_gclk>;
+ ti,bit-shift = <0>;
+ reg = <0x0664>;
+ };
+
+ ehrpwm1_tbclk: ehrpwm1_tbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l4ls_gclk>;
+ ti,bit-shift = <1>;
+ reg = <0x0664>;
+ };
+
+ ehrpwm2_tbclk: ehrpwm2_tbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l4ls_gclk>;
+ ti,bit-shift = <2>;
+ reg = <0x0664>;
+ };
+
+ ehrpwm3_tbclk: ehrpwm3_tbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l4ls_gclk>;
+ ti,bit-shift = <4>;
+ reg = <0x0664>;
+ };
+
+ ehrpwm4_tbclk: ehrpwm4_tbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l4ls_gclk>;
+ ti,bit-shift = <5>;
+ reg = <0x0664>;
+ };
+
+ ehrpwm5_tbclk: ehrpwm5_tbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l4ls_gclk>;
+ ti,bit-shift = <6>;
+ reg = <0x0664>;
+ };
+};
+&prcm_clocks {
+ clk_32768_ck: clk_32768_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ clk_rc32k_ck: clk_rc32k_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ virt_19200000_ck: virt_19200000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <19200000>;
+ };
+
+ virt_24000000_ck: virt_24000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ virt_25000000_ck: virt_25000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <25000000>;
+ };
+
+ virt_26000000_ck: virt_26000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ };
+
+ tclkin_ck: tclkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ };
+
+ dpll_core_ck: dpll_core_ck {
+ #clock-cells = <0>;
+ compatible = "ti,am3-dpll-core-clock";
+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>;
+ reg = <0x2d20>, <0x2d24>, <0x2d2c>;
+ };
+
+ dpll_core_x2_ck: dpll_core_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,am3-dpll-x2-clock";
+ clocks = <&dpll_core_ck>;
+ };
+
+ dpll_core_m4_ck: dpll_core_m4_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x2d38>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_core_m5_ck: dpll_core_m5_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x2d3c>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_core_m6_ck: dpll_core_m6_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x2d40>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_mpu_ck: dpll_mpu_ck {
+ #clock-cells = <0>;
+ compatible = "ti,am3-dpll-clock";
+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>;
+ reg = <0x2d60>, <0x2d64>, <0x2d6c>;
+ };
+
+ dpll_mpu_m2_ck: dpll_mpu_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_mpu_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x2d70>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_ddr_ck: dpll_ddr_ck {
+ #clock-cells = <0>;
+ compatible = "ti,am3-dpll-clock";
+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>;
+ reg = <0x2da0>, <0x2da4>, <0x2dac>;
+ };
+
+ dpll_ddr_m2_ck: dpll_ddr_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_ddr_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x2db0>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_disp_ck: dpll_disp_ck {
+ #clock-cells = <0>;
+ compatible = "ti,am3-dpll-clock";
+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>;
+ reg = <0x2e20>, <0x2e24>, <0x2e2c>;
+ };
+
+ dpll_disp_m2_ck: dpll_disp_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_disp_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x2e30>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ ti,set-rate-parent;
+ };
+
+ dpll_per_ck: dpll_per_ck {
+ #clock-cells = <0>;
+ compatible = "ti,am3-dpll-j-type-clock";
+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>;
+ reg = <0x2de0>, <0x2de4>, <0x2dec>;
+ };
+
+ dpll_per_m2_ck: dpll_per_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_ck>;
+ ti,max-div = <127>;
+ ti,autoidle-shift = <8>;
+ reg = <0x2df0>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_per_m2_div4_wkupdm_ck: dpll_per_m2_div4_wkupdm_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ dpll_per_m2_div4_ck: dpll_per_m2_div4_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ clk_24mhz: clk_24mhz {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <8>;
+ };
+
+ clkdiv32k_ck: clkdiv32k_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&clk_24mhz>;
+ clock-mult = <1>;
+ clock-div = <732>;
+ };
+
+ clkdiv32k_ick: clkdiv32k_ick {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&clkdiv32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x2a38>;
+ };
+
+ sysclk_div: sysclk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m4_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ pruss_ocp_gclk: pruss_ocp_gclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sysclk_div>, <&dpll_disp_m2_ck>;
+ reg = <0x4248>;
+ };
+
+ clk_32k_tpm_ck: clk_32k_tpm_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ timer1_fck: timer1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&clkdiv32k_ick>, <&tclkin_ck>, <&clk_rc32k_ck>, <&clk_32768_ck>, <&clk_32k_tpm_ck>;
+ reg = <0x4200>;
+ };
+
+ timer2_fck: timer2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>;
+ reg = <0x4204>;
+ };
+
+ timer3_fck: timer3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>;
+ reg = <0x4208>;
+ };
+
+ timer4_fck: timer4_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>;
+ reg = <0x420c>;
+ };
+
+ timer5_fck: timer5_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>;
+ reg = <0x4210>;
+ };
+
+ timer6_fck: timer6_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>;
+ reg = <0x4214>;
+ };
+
+ timer7_fck: timer7_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>;
+ reg = <0x4218>;
+ };
+
+ wdt1_fck: wdt1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&clk_rc32k_ck>, <&clkdiv32k_ick>;
+ reg = <0x422c>;
+ };
+
+ l3_gclk: l3_gclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m4_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll_core_m4_div2_ck: dpll_core_m4_div2_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sysclk_div>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ l4hs_gclk: l4hs_gclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m4_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ l3s_gclk: l3s_gclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m4_div2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ l4ls_gclk: l4ls_gclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m4_div2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ cpsw_125mhz_gclk: cpsw_125mhz_gclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m5_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ cpsw_cpts_rft_clk: cpsw_cpts_rft_clk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sysclk_div>, <&dpll_core_m5_ck>, <&dpll_disp_m2_ck>;
+ reg = <0x4238>;
+ };
+
+ clk_32k_mosc_ck: clk_32k_mosc_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ gpio0_dbclk_mux_ck: gpio0_dbclk_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&clk_rc32k_ck>, <&clk_32768_ck>, <&clkdiv32k_ick>, <&clk_32k_mosc_ck>, <&clk_32k_tpm_ck>;
+ reg = <0x4240>;
+ };
+
+ gpio0_dbclk: gpio0_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&gpio0_dbclk_mux_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x2b68>;
+ };
+
+ gpio1_dbclk: gpio1_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&clkdiv32k_ick>;
+ ti,bit-shift = <8>;
+ reg = <0x8c78>;
+ };
+
+ gpio2_dbclk: gpio2_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&clkdiv32k_ick>;
+ ti,bit-shift = <8>;
+ reg = <0x8c80>;
+ };
+
+ gpio3_dbclk: gpio3_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&clkdiv32k_ick>;
+ ti,bit-shift = <8>;
+ reg = <0x8c88>;
+ };
+
+ gpio4_dbclk: gpio4_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&clkdiv32k_ick>;
+ ti,bit-shift = <8>;
+ reg = <0x8c90>;
+ };
+
+ gpio5_dbclk: gpio5_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&clkdiv32k_ick>;
+ ti,bit-shift = <8>;
+ reg = <0x8c98>;
+ };
+
+ mmc_clk: mmc_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ gfx_fclk_clksel_ck: gfx_fclk_clksel_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sysclk_div>, <&dpll_per_m2_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x423c>;
+ };
+
+ gfx_fck_div_ck: gfx_fck_div_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&gfx_fclk_clksel_ck>;
+ reg = <0x423c>;
+ ti,max-div = <2>;
+ };
+
+ disp_clk: disp_clk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dpll_disp_m2_ck>, <&dpll_core_m5_ck>, <&dpll_per_m2_ck>;
+ reg = <0x4244>;
+ ti,set-rate-parent;
+ };
+
+ dpll_extdev_ck: dpll_extdev_ck {
+ #clock-cells = <0>;
+ compatible = "ti,am3-dpll-clock";
+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>;
+ reg = <0x2e60>, <0x2e64>, <0x2e6c>;
+ };
+
+ dpll_extdev_m2_ck: dpll_extdev_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_extdev_ck>;
+ ti,max-div = <127>;
+ ti,autoidle-shift = <8>;
+ reg = <0x2e70>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ mux_synctimer32k_ck: mux_synctimer32k_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&clk_32768_ck>, <&clk_32k_tpm_ck>, <&clkdiv32k_ick>;
+ reg = <0x4230>;
+ };
+
+ synctimer_32kclk: synctimer_32kclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&mux_synctimer32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x2a30>;
+ };
+
+ timer8_fck: timer8_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>, <&clk_32k_tpm_ck>;
+ reg = <0x421c>;
+ };
+
+ timer9_fck: timer9_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>, <&clk_32k_tpm_ck>;
+ reg = <0x4220>;
+ };
+
+ timer10_fck: timer10_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>, <&clk_32k_tpm_ck>;
+ reg = <0x4224>;
+ };
+
+ timer11_fck: timer11_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>, <&clk_32k_tpm_ck>;
+ reg = <0x4228>;
+ };
+
+ cpsw_50m_clkdiv: cpsw_50m_clkdiv {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m5_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ cpsw_5m_clkdiv: cpsw_5m_clkdiv {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&cpsw_50m_clkdiv>;
+ clock-mult = <1>;
+ clock-div = <10>;
+ };
+
+ dpll_ddr_x2_ck: dpll_ddr_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,am3-dpll-x2-clock";
+ clocks = <&dpll_ddr_ck>;
+ };
+
+ dpll_ddr_m4_ck: dpll_ddr_m4_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_ddr_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x2db8>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_per_clkdcoldo: dpll_per_clkdcoldo {
+ #clock-cells = <0>;
+ compatible = "ti,fixed-factor-clock";
+ clocks = <&dpll_per_ck>;
+ ti,clock-mult = <1>;
+ ti,clock-div = <1>;
+ ti,autoidle-shift = <8>;
+ reg = <0x2e14>;
+ ti,invert-autoidle-bit;
+ };
+
+ dll_aging_clk_div: dll_aging_clk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&sys_clkin_ck>;
+ reg = <0x4250>;
+ ti,dividers = <8>, <16>, <32>;
+ };
+
+ div_core_25m_ck: div_core_25m_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sysclk_div>;
+ clock-mult = <1>;
+ clock-div = <8>;
+ };
+
+ func_12m_clk: func_12m_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <16>;
+ };
+
+ vtp_clk_div: vtp_clk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ usbphy_32khz_clkmux: usbphy_32khz_clkmux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&clk_32768_ck>, <&clk_32k_tpm_ck>;
+ reg = <0x4260>;
+ };
+
+ usb_phy0_always_on_clk32k: usb_phy0_always_on_clk32k {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&usbphy_32khz_clkmux>;
+ ti,bit-shift = <8>;
+ reg = <0x2a40>;
+ };
+
+ usb_phy1_always_on_clk32k: usb_phy1_always_on_clk32k {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&usbphy_32khz_clkmux>;
+ ti,bit-shift = <8>;
+ reg = <0x2a48>;
+ };
+
+ usb_otg_ss0_refclk960m: usb_otg_ss0_refclk960m {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_per_clkdcoldo>;
+ ti,bit-shift = <8>;
+ reg = <0x8a60>;
+ };
+
+ usb_otg_ss1_refclk960m: usb_otg_ss1_refclk960m {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_per_clkdcoldo>;
+ ti,bit-shift = <8>;
+ reg = <0x8a68>;
+ };
+};
diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts
new file mode 100644
index 000000000..7128fad99
--- /dev/null
+++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts
@@ -0,0 +1,610 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+/dts-v1/;
+
+#include "dra74x.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ model = "TI AM5728 BeagleBoard-X15";
+ compatible = "ti,am572x-beagle-x15", "ti,am5728", "ti,dra742", "ti,dra74", "ti,dra7";
+
+ aliases {
+ rtc0 = &mcp_rtc;
+ rtc1 = &tps659038_rtc;
+ rtc2 = &rtc;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x80000000>;
+ };
+
+ vdd_3v3: fixedregulator-vdd_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_3v3";
+ vin-supply = <&regen1>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vtt_fixed: fixedregulator-vtt {
+ /* TPS51200 */
+ compatible = "regulator-fixed";
+ regulator-name = "vtt_fixed";
+ vin-supply = <&smps3_reg>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&gpio7 11 GPIO_ACTIVE_HIGH>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_pins_default>;
+
+ led@0 {
+ label = "beagle-x15:usr0";
+ gpios = <&gpio7 9 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+
+ led@1 {
+ label = "beagle-x15:usr1";
+ gpios = <&gpio7 8 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "cpu0";
+ default-state = "off";
+ };
+
+ led@2 {
+ label = "beagle-x15:usr2";
+ gpios = <&gpio7 14 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "mmc0";
+ default-state = "off";
+ };
+
+ led@3 {
+ label = "beagle-x15:usr3";
+ gpios = <&gpio7 15 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "ide-disk";
+ default-state = "off";
+ };
+ };
+
+ gpio_fan: gpio_fan {
+ /* Based on 5v 500mA AFB02505HHB */
+ compatible = "gpio-fan";
+ gpios = <&tps659038_gpio 2 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = <0 0>,
+ <13000 1>;
+ #cooling-cells = <2>;
+ };
+
+ extcon_usb1: extcon_usb1 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&gpio7 25 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&extcon_usb1_pins>;
+ };
+
+ extcon_usb2: extcon_usb2 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&gpio7 24 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&extcon_usb2_pins>;
+ };
+};
+
+&dra7_pmx_core {
+ leds_pins_default: leds_pins_default {
+ pinctrl-single,pins = <
+ 0x3a8 (PIN_OUTPUT | MUX_MODE14) /* spi1_d1.gpio7_8 */
+ 0x3ac (PIN_OUTPUT | MUX_MODE14) /* spi1_d0.gpio7_9 */
+ 0x3c0 (PIN_OUTPUT | MUX_MODE14) /* spi2_sclk.gpio7_14 */
+ 0x3c4 (PIN_OUTPUT | MUX_MODE14) /* spi2_d1.gpio7_15 */
+ >;
+ };
+
+ i2c1_pins_default: i2c1_pins_default {
+ pinctrl-single,pins = <
+ 0x400 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda.sda */
+ 0x404 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl.scl */
+ >;
+ };
+
+ i2c3_pins_default: i2c3_pins_default {
+ pinctrl-single,pins = <
+ 0x2a4 (PIN_INPUT| MUX_MODE10) /* mcasp1_aclkx.i2c3_sda */
+ 0x2a8 (PIN_INPUT| MUX_MODE10) /* mcasp1_fsx.i2c3_scl */
+ >;
+ };
+
+ uart3_pins_default: uart3_pins_default {
+ pinctrl-single,pins = <
+ 0x3f8 (PIN_INPUT_SLEW | MUX_MODE2) /* uart2_ctsn.uart3_rxd */
+ 0x3fc (PIN_INPUT_SLEW | MUX_MODE1) /* uart2_rtsn.uart3_txd */
+ >;
+ };
+
+ mmc1_pins_default: mmc1_pins_default {
+ pinctrl-single,pins = <
+ 0x36c (PIN_INPUT | MUX_MODE14) /* mmc1sdcd.gpio219 */
+ 0x354 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */
+ 0x358 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
+ 0x35c (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
+ 0x360 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
+ 0x364 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
+ 0x368 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */
+ >;
+ };
+
+ mmc2_pins_default: mmc2_pins_default {
+ pinctrl-single,pins = <
+ 0x9c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */
+ 0xb0 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */
+ 0xa0 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */
+ 0xa4 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */
+ 0xa8 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */
+ 0xac (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */
+ 0x8c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */
+ 0x90 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */
+ 0x94 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */
+ 0x98 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */
+ >;
+ };
+
+ cpsw_pins_default: cpsw_pins_default {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ 0x250 (PIN_OUTPUT | MUX_MODE0) /* rgmii1_tclk */
+ 0x254 (PIN_OUTPUT | MUX_MODE0) /* rgmii1_tctl */
+ 0x258 (PIN_OUTPUT | MUX_MODE0) /* rgmii1_td3 */
+ 0x25c (PIN_OUTPUT | MUX_MODE0) /* rgmii1_td2 */
+ 0x260 (PIN_OUTPUT | MUX_MODE0) /* rgmii1_td1 */
+ 0x264 (PIN_OUTPUT | MUX_MODE0) /* rgmii1_td0 */
+ 0x268 (PIN_INPUT | MUX_MODE0) /* rgmii1_rclk */
+ 0x26c (PIN_INPUT | MUX_MODE0) /* rgmii1_rctl */
+ 0x270 (PIN_INPUT | MUX_MODE0) /* rgmii1_rd3 */
+ 0x274 (PIN_INPUT | MUX_MODE0) /* rgmii1_rd2 */
+ 0x278 (PIN_INPUT | MUX_MODE0) /* rgmii1_rd1 */
+ 0x27c (PIN_INPUT | MUX_MODE0) /* rgmii1_rd0 */
+
+ /* Slave 2 */
+ 0x198 (PIN_OUTPUT | MUX_MODE3) /* rgmii2_tclk */
+ 0x19c (PIN_OUTPUT | MUX_MODE3) /* rgmii2_tctl */
+ 0x1a0 (PIN_OUTPUT | MUX_MODE3) /* rgmii2_td3 */
+ 0x1a4 (PIN_OUTPUT | MUX_MODE3) /* rgmii2_td2 */
+ 0x1a8 (PIN_OUTPUT | MUX_MODE3) /* rgmii2_td1 */
+ 0x1ac (PIN_OUTPUT | MUX_MODE3) /* rgmii2_td0 */
+ 0x1b0 (PIN_INPUT | MUX_MODE3) /* rgmii2_rclk */
+ 0x1b4 (PIN_INPUT | MUX_MODE3) /* rgmii2_rctl */
+ 0x1b8 (PIN_INPUT | MUX_MODE3) /* rgmii2_rd3 */
+ 0x1bc (PIN_INPUT | MUX_MODE3) /* rgmii2_rd2 */
+ 0x1c0 (PIN_INPUT | MUX_MODE3) /* rgmii2_rd1 */
+ 0x1c4 (PIN_INPUT | MUX_MODE3) /* rgmii2_rd0 */
+ >;
+
+ };
+
+ cpsw_pins_sleep: cpsw_pins_sleep {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ 0x250 (PIN_INPUT | MUX_MODE15)
+ 0x254 (PIN_INPUT | MUX_MODE15)
+ 0x258 (PIN_INPUT | MUX_MODE15)
+ 0x25c (PIN_INPUT | MUX_MODE15)
+ 0x260 (PIN_INPUT | MUX_MODE15)
+ 0x264 (PIN_INPUT | MUX_MODE15)
+ 0x268 (PIN_INPUT | MUX_MODE15)
+ 0x26c (PIN_INPUT | MUX_MODE15)
+ 0x270 (PIN_INPUT | MUX_MODE15)
+ 0x274 (PIN_INPUT | MUX_MODE15)
+ 0x278 (PIN_INPUT | MUX_MODE15)
+ 0x27c (PIN_INPUT | MUX_MODE15)
+
+ /* Slave 2 */
+ 0x198 (PIN_INPUT | MUX_MODE15)
+ 0x19c (PIN_INPUT | MUX_MODE15)
+ 0x1a0 (PIN_INPUT | MUX_MODE15)
+ 0x1a4 (PIN_INPUT | MUX_MODE15)
+ 0x1a8 (PIN_INPUT | MUX_MODE15)
+ 0x1ac (PIN_INPUT | MUX_MODE15)
+ 0x1b0 (PIN_INPUT | MUX_MODE15)
+ 0x1b4 (PIN_INPUT | MUX_MODE15)
+ 0x1b8 (PIN_INPUT | MUX_MODE15)
+ 0x1bc (PIN_INPUT | MUX_MODE15)
+ 0x1c0 (PIN_INPUT | MUX_MODE15)
+ 0x1c4 (PIN_INPUT | MUX_MODE15)
+ >;
+ };
+
+ davinci_mdio_pins_default: davinci_mdio_pins_default {
+ pinctrl-single,pins = <
+ /* MDIO */
+ 0x23c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_mclk */
+ 0x240 (PIN_INPUT_PULLUP | MUX_MODE0) /* mdio_d */
+ >;
+ };
+
+ davinci_mdio_pins_sleep: davinci_mdio_pins_sleep {
+ pinctrl-single,pins = <
+ 0x23c (PIN_INPUT | MUX_MODE15)
+ 0x240 (PIN_INPUT | MUX_MODE15)
+ >;
+ };
+
+ tps659038_pins_default: tps659038_pins_default {
+ pinctrl-single,pins = <
+ 0x418 (PIN_INPUT_PULLUP | MUX_MODE14) /* wakeup0.gpio1_0 */
+ >;
+ };
+
+ tmp102_pins_default: tmp102_pins_default {
+ pinctrl-single,pins = <
+ 0x3C8 (PIN_INPUT_PULLUP | MUX_MODE14) /* spi2_d0.gpio7_16 */
+ >;
+ };
+
+ mcp79410_pins_default: mcp79410_pins_default {
+ pinctrl-single,pins = <
+ 0x424 (PIN_INPUT_PULLUP | MUX_MODE1) /* wakeup3.sys_nirq1 */
+ >;
+ };
+
+ usb1_pins: pinmux_usb1_pins {
+ pinctrl-single,pins = <
+ 0x280 (PIN_INPUT_SLEW | MUX_MODE0) /* usb1_drvvbus */
+ >;
+ };
+
+ extcon_usb1_pins: extcon_usb1_pins {
+ pinctrl-single,pins = <
+ 0x3ec (PIN_INPUT_PULLUP | MUX_MODE14) /* uart1_rtsn.gpio7_25 */
+ >;
+ };
+
+ extcon_usb2_pins: extcon_usb2_pins {
+ pinctrl-single,pins = <
+ 0x3e8 (PIN_INPUT_PULLUP | MUX_MODE14) /* uart1_ctsn.gpio7_24 */
+ >;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_default>;
+ clock-frequency = <400000>;
+
+ tps659038: tps659038@58 {
+ compatible = "ti,tps659038";
+ reg = <0x58>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&tps659038_pins_default>;
+
+ #interrupt-cells = <2>;
+ interrupt-controller;
+
+ ti,system-power-controller;
+
+ tps659038_pmic {
+ compatible = "ti,tps659038-pmic";
+
+ regulators {
+ smps12_reg: smps12 {
+ /* VDD_MPU */
+ regulator-name = "smps12";
+ regulator-min-microvolt = < 850000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps3_reg: smps3 {
+ /* VDD_DDR */
+ regulator-name = "smps3";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps45_reg: smps45 {
+ /* VDD_DSPEVE, VDD_IVA, VDD_GPU */
+ regulator-name = "smps45";
+ regulator-min-microvolt = < 850000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps6_reg: smps6 {
+ /* VDD_CORE */
+ regulator-name = "smps6";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1030000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ /* SMPS7 unused */
+
+ smps8_reg: smps8 {
+ /* VDD_1V8 */
+ regulator-name = "smps8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ /* SMPS9 unused */
+
+ ldo1_reg: ldo1 {
+ /* VDD_SD */
+ regulator-name = "ldo1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ };
+
+ ldo2_reg: ldo2 {
+ /* VDD_SHV5 */
+ regulator-name = "ldo2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo3_reg: ldo3 {
+ /* VDDA_1V8_PHY */
+ regulator-name = "ldo3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo9_reg: ldo9 {
+ /* VDD_RTC */
+ regulator-name = "ldo9";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldoln_reg: ldoln {
+ /* VDDA_1V8_PLL */
+ regulator-name = "ldoln";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldousb_reg: ldousb {
+ /* VDDA_3V_USB: VDDA_USBHS33 */
+ regulator-name = "ldousb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ };
+
+ regen1: regen1 {
+ /* VDD_3V3_ON */
+ regulator-name = "regen1";
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+
+ tps659038_rtc: tps659038_rtc {
+ compatible = "ti,palmas-rtc";
+ interrupt-parent = <&tps659038>;
+ interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
+ wakeup-source;
+ };
+
+ tps659038_pwr_button: tps659038_pwr_button {
+ compatible = "ti,palmas-pwrbutton";
+ interrupt-parent = <&tps659038>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+ wakeup-source;
+ ti,palmas-long-press-seconds = <12>;
+ };
+
+ tps659038_gpio: tps659038_gpio {
+ compatible = "ti,palmas-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ tmp102: tmp102@48 {
+ compatible = "ti,tmp102";
+ reg = <0x48>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&tmp102_pins_default>;
+ interrupt-parent = <&gpio7>;
+ interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
+ #thermal-sensor-cells = <1>;
+ };
+};
+
+&i2c3 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins_default>;
+ clock-frequency = <400000>;
+
+ mcp_rtc: rtc@6f {
+ compatible = "microchip,mcp7941x";
+ reg = <0x6f>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_EDGE_RISING>; /* IRQ_SYS_1N */
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcp79410_pins_default>;
+
+ vcc-supply = <&vdd_3v3>;
+ wakeup-source;
+ };
+};
+
+&gpio7 {
+ ti,no-reset-on-init;
+ ti,no-idle-on-init;
+};
+
+&cpu0 {
+ cpu0-supply = <&smps12_reg>;
+ voltage-tolerance = <1>;
+};
+
+&uart3 {
+ status = "okay";
+ interrupts-extended = <&crossbar_mpu GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
+ <&dra7_pmx_core 0x3f8>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins_default>;
+};
+
+&mac {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_pins_default>;
+ pinctrl-1 = <&cpsw_pins_sleep>;
+ dual_emac;
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <1>;
+ phy-mode = "rgmii";
+ dual_emac_res_vlan = <1>;
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <2>;
+ phy-mode = "rgmii";
+ dual_emac_res_vlan = <2>;
+};
+
+&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_pins_default>;
+ pinctrl-1 = <&davinci_mdio_pins_sleep>;
+};
+
+&mmc1 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins_default>;
+
+ vmmc-supply = <&ldo1_reg>;
+ vmmc_aux-supply = <&vdd_3v3>;
+ pbias-supply = <&pbias_mmc_reg>;
+ bus-width = <4>;
+ cd-gpios = <&gpio6 27 0>; /* gpio 219 */
+};
+
+&mmc2 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins_default>;
+
+ vmmc-supply = <&vdd_3v3>;
+ bus-width = <8>;
+ ti,non-removable;
+ cap-mmc-dual-data-rate;
+};
+
+&sata {
+ status = "okay";
+};
+
+&usb2_phy1 {
+ phy-supply = <&ldousb_reg>;
+};
+
+&usb1 {
+ dr_mode = "host";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_pins>;
+};
+
+&omap_dwc3_1 {
+ extcon = <&extcon_usb1>;
+};
+
+&omap_dwc3_2 {
+ extcon = <&extcon_usb2>;
+};
+
+&usb2 {
+ dr_mode = "peripheral";
+};
+
+&cpu_trips {
+ cpu_alert1: cpu_alert1 {
+ temperature = <50000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "active";
+ };
+};
+
+&cpu_cooling_maps {
+ map1 {
+ trip = <&cpu_alert1>;
+ cooling-device = <&gpio_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+};
+
+&thermal_zones {
+ board_thermal: board_thermal {
+ polling-delay-passive = <1250>; /* milliseconds */
+ polling-delay = <1500>; /* milliseconds */
+
+ /* sensor ID */
+ thermal-sensors = <&tmp102 0>;
+
+ board_trips: trips {
+ board_alert0: board_alert {
+ temperature = <40000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "active";
+ };
+
+ board_crit: board_crit {
+ temperature = <105000>; /* millicelsius */
+ hysteresis = <0>; /* millicelsius */
+ type = "critical";
+ };
+ };
+
+ board_cooling_maps: cooling-maps {
+ map0 {
+ trip = <&board_alert0>;
+ cooling-device =
+ <&gpio_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/animeo_ip.dts b/arch/arm/boot/dts/animeo_ip.dts
new file mode 100644
index 000000000..4e0ad3b82
--- /dev/null
+++ b/arch/arm/boot/dts/animeo_ip.dts
@@ -0,0 +1,175 @@
+/*
+ * animeo_ip.dts - Device Tree file for Somfy Animeo IP Boards
+ *
+ * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 only.
+ */
+
+/dts-v1/;
+#include "at91sam9260.dtsi"
+
+/ {
+ model = "Somfy Animeo IP";
+ compatible = "somfy,animeo-ip", "atmel,at91sam9260", "atmel,at91sam9";
+
+ aliases {
+ serial0 = &usart1;
+ serial1 = &usart2;
+ serial2 = &usart0;
+ serial3 = &dbgu;
+ serial4 = &usart3;
+ serial5 = &uart0;
+ serial6 = &uart1;
+ };
+
+ chosen {
+ linux,stdout-path = &usart2;
+ };
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <18432000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <18432000>;
+ };
+ };
+
+ ahb {
+ apb {
+ usart0: serial@fffb0000 {
+ pinctrl-0 = <&pinctrl_usart0 &pinctrl_usart0_rts>;
+ linux,rs485-enabled-at-boot-time;
+ status = "okay";
+ };
+
+ usart1: serial@fffb4000 {
+ pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts>;
+ linux,rs485-enabled-at-boot-time;
+ status = "okay";
+ };
+
+ usart2: serial@fffb8000 {
+ pinctrl-0 = <&pinctrl_usart2>;
+ status = "okay";
+ };
+
+ macb0: ethernet@fffc4000 {
+ pinctrl-0 = <&pinctrl_macb_rmii &pinctrl_macb_rmii_mii>;
+ phy-mode = "mii";
+ status = "okay";
+ };
+
+ mmc0: mmc@fffa8000 {
+ pinctrl-0 = <&pinctrl_mmc0_clk
+ &pinctrl_mmc0_slot1_cmd_dat0
+ &pinctrl_mmc0_slot1_dat1_3>;
+ status = "okay";
+
+ slot@1 {
+ reg = <1>;
+ bus-width = <4>;
+ };
+ };
+
+ watchdog@fffffd40 {
+ status = "okay";
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ status = "okay";
+
+ barebox@0 {
+ label = "barebox";
+ reg = <0x0 0x58000>;
+ };
+
+ u_boot_env@58000 {
+ label = "u_boot_env";
+ reg = <0x58000 0x8000>;
+ };
+
+ ubi@60000 {
+ label = "ubi";
+ reg = <0x60000 0x1FA0000>;
+ };
+ };
+
+ usb0: ohci@00500000 {
+ num-ports = <2>;
+ atmel,vbus-gpio = <&pioB 15 GPIO_ACTIVE_LOW>;
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ power_green {
+ label = "power_green";
+ gpios = <&pioC 17 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ power_red {
+ label = "power_red";
+ gpios = <&pioA 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ tx_green {
+ label = "tx_green";
+ gpios = <&pioC 19 GPIO_ACTIVE_HIGH>;
+ };
+
+ tx_red {
+ label = "tx_red";
+ gpios = <&pioC 18 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ keyswitch_in {
+ label = "keyswitch_in";
+ gpios = <&pioB 1 GPIO_ACTIVE_HIGH>;
+ linux,code = <28>;
+ gpio-key,wakeup;
+ };
+
+ error_in {
+ label = "error_in";
+ gpios = <&pioB 2 GPIO_ACTIVE_HIGH>;
+ linux,code = <29>;
+ gpio-key,wakeup;
+ };
+
+ btn {
+ label = "btn";
+ gpios = <&pioC 23 GPIO_ACTIVE_HIGH>;
+ linux,code = <31>;
+ gpio-key,wakeup;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/arm-realview-pb1176.dts b/arch/arm/boot/dts/arm-realview-pb1176.dts
new file mode 100644
index 000000000..ff26c7ed8
--- /dev/null
+++ b/arch/arm/boot/dts/arm-realview-pb1176.dts
@@ -0,0 +1,412 @@
+/*
+ * Copyright 2014 Linaro Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "skeleton.dtsi"
+
+/ {
+ model = "ARM RealView PB1176";
+ compatible = "arm,realview-pb1176";
+
+ chosen { };
+
+ aliases {
+ serial0 = &pb1176_serial0;
+ serial1 = &pb1176_serial1;
+ serial2 = &pb1176_serial2;
+ serial3 = &pb1176_serial3;
+ serial4 = &fpga_serial;
+ };
+
+ memory {
+ /* 128 MiB memory @ 0x0 */
+ reg = <0x00000000 0x08000000>;
+ };
+
+ /* The voltage to the MMC card is hardwired at 3.3V */
+ vmmc: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ };
+
+ xtal24mhz: xtal24mhz@24M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ timclk: timclk@1M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <24>;
+ clock-mult = <1>;
+ clocks = <&xtal24mhz>;
+ };
+
+ mclk: mclk@24M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <1>;
+ clock-mult = <1>;
+ clocks = <&xtal24mhz>;
+ };
+
+ kmiclk: kmiclk@24M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <1>;
+ clock-mult = <1>;
+ clocks = <&xtal24mhz>;
+ };
+
+ sspclk: sspclk@24M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <1>;
+ clock-mult = <1>;
+ clocks = <&xtal24mhz>;
+ };
+
+ uartclk: uartclk@24M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <1>;
+ clock-mult = <1>;
+ clocks = <&xtal24mhz>;
+ };
+
+ /* FIXME: this actually hangs off the PLL clocks */
+ pclk: pclk@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "arm,realview-pb1176-soc", "simple-bus";
+ regmap = <&syscon>;
+ ranges;
+
+ syscon: syscon@10000000 {
+ compatible = "arm,realview-pb1176-syscon", "syscon";
+ reg = <0x10000000 0x1000>;
+
+ led@08.0 {
+ compatible = "register-bit-led";
+ offset = <0x08>;
+ mask = <0x01>;
+ label = "versatile:0";
+ linux,default-trigger = "heartbeat";
+ default-state = "on";
+ };
+ led@08.1 {
+ compatible = "register-bit-led";
+ offset = <0x08>;
+ mask = <0x02>;
+ label = "versatile:1";
+ linux,default-trigger = "mmc0";
+ default-state = "off";
+ };
+ led@08.2 {
+ compatible = "register-bit-led";
+ offset = <0x08>;
+ mask = <0x04>;
+ label = "versatile:2";
+ linux,default-trigger = "cpu0";
+ default-state = "off";
+ };
+ led@08.3 {
+ compatible = "register-bit-led";
+ offset = <0x08>;
+ mask = <0x08>;
+ label = "versatile:3";
+ default-state = "off";
+ };
+ led@08.4 {
+ compatible = "register-bit-led";
+ offset = <0x08>;
+ mask = <0x10>;
+ label = "versatile:4";
+ default-state = "off";
+ };
+ led@08.5 {
+ compatible = "register-bit-led";
+ offset = <0x08>;
+ mask = <0x20>;
+ label = "versatile:5";
+ default-state = "off";
+ };
+ led@08.6 {
+ compatible = "register-bit-led";
+ offset = <0x08>;
+ mask = <0x40>;
+ label = "versatile:6";
+ default-state = "off";
+ };
+ led@08.7 {
+ compatible = "register-bit-led";
+ offset = <0x08>;
+ mask = <0x80>;
+ label = "versatile:7";
+ default-state = "off";
+ };
+ };
+
+ /* Primary DevChip GIC synthesized with the CPU */
+ intc_dc1176: interrupt-controller@10120000 {
+ compatible = "arm,arm1176jzf-devchip-gic", "arm,arm11mp-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <1>;
+ interrupt-controller;
+ reg = <0x10121000 0x1000>,
+ <0x10120000 0x100>;
+ };
+
+ L2: l2-cache {
+ compatible = "arm,l220-cache";
+ reg = <0x10110000 0x1000>;
+ interrupt-parent = <&intc_dc1176>;
+ interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>;
+ cache-unified;
+ cache-level = <2>;
+ /*
+ * Override default cache size, sets and
+ * associativity as these may be erroneously set
+ * up by boot loader(s).
+ */
+ arm,override-auxreg;
+ cache-size = <131072>; // 128kB
+ cache-sets = <512>;
+ cache-line-size = <32>;
+ };
+
+ pmu {
+ compatible = "arm,arm1176-pmu";
+ interrupt-parent = <&intc_dc1176>;
+ interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ timer01: timer@10104000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x10104000 0x1000>;
+ interrupt-parent = <&intc_dc1176>;
+ interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>, <0 9 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&timclk>, <&timclk>, <&pclk>;
+ clock-names = "timer1", "timer2", "apb_pclk";
+ };
+
+ timer23: timer@10105000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x10105000 0x1000>;
+ interrupt-parent = <&intc_dc1176>;
+ interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>;
+ arm,sp804-has-irq = <1>;
+ clocks = <&timclk>, <&timclk>, <&pclk>;
+ clock-names = "timer1", "timer2", "apb_pclk";
+ };
+
+ pb1176_rtc: rtc@10108000 {
+ compatible = "arm,pl031", "arm,primecell";
+ reg = <0x10108000 0x1000>;
+ interrupt-parent = <&intc_dc1176>;
+ interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ pb1176_gpio0: gpio@1010a000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x1010a000 0x1000>;
+ gpio-controller;
+ interrupt-parent = <&intc_dc1176>;
+ interrupts = <0 16 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ pb1176_ssp: ssp@1010b000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x1010b000 0x1000>;
+ interrupt-parent = <&intc_dc1176>;
+ interrupts = <0 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sspclk>, <&pclk>;
+ clock-names = "SSPCLK", "apb_pclk";
+ };
+
+ pb1176_serial0: serial@1010c000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x1010c000 0x1000>;
+ interrupt-parent = <&intc_dc1176>;
+ interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ pb1176_serial1: serial@1010d000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x1010d000 0x1000>;
+ interrupt-parent = <&intc_dc1176>;
+ interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ pb1176_serial2: serial@1010e000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x1010e000 0x1000>;
+ interrupt-parent = <&intc_dc1176>;
+ interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ pb1176_serial3: serial@1010f000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x1010f000 0x1000>;
+ interrupt-parent = <&intc_dc1176>;
+ interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+ };
+
+ /* These peripherals are inside the FPGA rather than the DevChip */
+ fpga {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+
+ fpga_mci: mmcsd@10005000 {
+ compatible = "arm,pl18x", "arm,primecell";
+ reg = <0x10005000 0x1000>;
+ interrupt-parent = <&intc_fpga1176>;
+ interrupts = <0 1 IRQ_TYPE_LEVEL_HIGH>,
+ <0 2 IRQ_TYPE_LEVEL_HIGH>;
+ /* Due to frequent FIFO overruns, use just 500 kHz */
+ max-frequency = <500000>;
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ clocks = <&mclk>, <&pclk>;
+ clock-names = "mclk", "apb_pclk";
+ vmmc-supply = <&vmmc>;
+ cd-gpios = <&fpga_gpio1 0 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&fpga_gpio1 1 GPIO_ACTIVE_HIGH>;
+ };
+
+ fpga_kmi0: kmi@10006000 {
+ compatible = "arm,pl050", "arm,primecell";
+ reg = <0x10006000 0x1000>;
+ interrupt-parent = <&intc_fpga1176>;
+ interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&kmiclk>, <&pclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+
+ fpga_kmi1: kmi@10007000 {
+ compatible = "arm,pl050", "arm,primecell";
+ reg = <0x10007000 0x1000>;
+ interrupt-parent = <&intc_fpga1176>;
+ interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&kmiclk>, <&pclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+
+ fpga_charlcd: charlcd@10008000 {
+ compatible = "arm,versatile-lcd";
+ reg = <0x10008000 0x1000>;
+ interrupt-parent = <&intc_fpga1176>;
+ interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ fpga_serial: serial@10009000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x10009000 0x1000>;
+ interrupt-parent = <&intc_fpga1176>;
+ interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ /* This GIC on the board is cascaded off the DevChip GIC */
+ intc_fpga1176: interrupt-controller@10040000 {
+ compatible = "arm,arm1176jzf-devchip-gic", "arm,arm11mp-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <1>;
+ interrupt-controller;
+ reg = <0x10041000 0x1000>,
+ <0x10040000 0x100>;
+ interrupt-parent = <&intc_dc1176>;
+ interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ fpga_gpio0: gpio@10014000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x10014000 0x1000>;
+ gpio-controller;
+ interrupt-parent = <&intc_fpga1176>;
+ interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ fpga_gpio1: gpio@10015000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x10015000 0x1000>;
+ gpio-controller;
+ interrupt-parent = <&intc_fpga1176>;
+ interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ fpga_rtc: rtc@10017000 {
+ compatible = "arm,pl031", "arm,primecell";
+ reg = <0x10017000 0x1000>;
+ interrupt-parent = <&intc_fpga1176>;
+ interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+
+ };
+};
diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts
new file mode 100644
index 000000000..19f3bf271
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-db.dts
@@ -0,0 +1,248 @@
+/*
+ * Device Tree file for Marvell Armada 370 evaluation board
+ * (DB-88F6710-BP-DDR3)
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Note: this Device Tree assumes that the bootloader has remapped the
+ * internal registers to 0xf1000000 (instead of the default
+ * 0xd0000000). The 0xf1000000 is the default used by the recent,
+ * DT-capable, U-Boot bootloaders provided by Marvell. Some earlier
+ * boards were delivered with an older version of the bootloader that
+ * left internal registers mapped at 0xd0000000. If you are in this
+ * situation, you should either update your bootloader (preferred
+ * solution) or the below Device Tree should be adjusted.
+ */
+
+/dts-v1/;
+#include "armada-370.dtsi"
+
+/ {
+ model = "Marvell Armada 370 Evaluation Board";
+ compatible = "marvell,a370-db", "marvell,armada370", "marvell,armada-370-xp";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>; /* 1 GB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+
+ internal-regs {
+ serial@12000 {
+ status = "okay";
+ };
+ sata@a0000 {
+ nr-ports = <2>;
+ status = "okay";
+ };
+
+ mdio {
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+
+ ethernet@70000 {
+ pinctrl-0 = <&ge0_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+ ethernet@74000 {
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+
+ i2c@11000 {
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+ clock-frequency = <100000>;
+ status = "okay";
+ audio_codec: audio-codec@4a {
+ #sound-dai-cells = <0>;
+ compatible = "cirrus,cs42l51";
+ reg = <0x4a>;
+ };
+ };
+
+ audio-controller@30000 {
+ pinctrl-0 = <&i2s_pins2>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ mvsdio@d4000 {
+ pinctrl-0 = <&sdio_pins1>;
+ pinctrl-names = "default";
+ /*
+ * This device is disabled by default, because
+ * using the SD card connector requires
+ * changing the default CON40 connector
+ * "DB-88F6710_MPP_2xRGMII_DEVICE_Jumper" to a
+ * different connector
+ * "DB-88F6710_MPP_RGMII_SD_Jumper".
+ */
+ status = "disabled";
+ /* No CD or WP GPIOs */
+ broken-cd;
+ };
+
+ usb@50000 {
+ status = "okay";
+ };
+
+ usb@51000 {
+ status = "okay";
+ };
+
+ spi0: spi@10600 {
+ pinctrl-0 = <&spi0_pins2>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mx25l25635e";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <50000000>;
+ };
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+ /*
+ * The two PCIe units are accessible through
+ * both standard PCIe slots and mini-PCIe
+ * slots on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "Armada 370 DB Audio";
+ simple-audio-card,mclk-fs = <256>;
+ simple-audio-card,widgets =
+ "Headphone", "Out Jack",
+ "Line", "In Jack";
+ simple-audio-card,routing =
+ "Out Jack", "HPL",
+ "Out Jack", "HPR",
+ "AIN1L", "In Jack",
+ "AIN1L", "In Jack";
+ status = "okay";
+
+ simple-audio-card,dai-link@0 {
+ format = "i2s";
+ cpu {
+ sound-dai = <&audio_controller 0>;
+ };
+
+ codec {
+ sound-dai = <&audio_codec>;
+ };
+ };
+
+ simple-audio-card,dai-link@1 {
+ format = "i2s";
+ cpu {
+ sound-dai = <&audio_controller 1>;
+ };
+
+ codec {
+ sound-dai = <&spdif_out>;
+ };
+ };
+
+ simple-audio-card,dai-link@2 {
+ format = "i2s";
+ cpu {
+ sound-dai = <&audio_controller 1>;
+ };
+
+ codec {
+ sound-dai = <&spdif_in>;
+ };
+ };
+ };
+
+ spdif_out: spdif-out {
+ #sound-dai-cells = <0>;
+ compatible = "linux,spdif-dit";
+ };
+
+ spdif_in: spdif-in {
+ #sound-dai-cells = <0>;
+ compatible = "linux,spdif-dir";
+ };
+};
diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts
new file mode 100644
index 000000000..0f40d5da2
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-mirabox.dts
@@ -0,0 +1,206 @@
+/*
+ * Device Tree file for Globalscale Mirabox
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include "armada-370.dtsi"
+
+/ {
+ model = "Globalscale Mirabox";
+ compatible = "globalscale,mirabox", "marvell,armada370", "marvell,armada-370-xp";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>; /* 512 MB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+
+ pcie-controller {
+ status = "okay";
+
+ /* Internal mini-PCIe connector */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* Connected on the PCB to a USB 3.0 XHCI controller */
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+ };
+
+ internal-regs {
+ serial@12000 {
+ status = "okay";
+ };
+ timer@20300 {
+ clock-frequency = <600000000>;
+ status = "okay";
+ };
+
+ gpio_leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwr_led_pin &stat_led_pins>;
+
+ green_pwr_led {
+ label = "mirabox:green:pwr";
+ gpios = <&gpio1 31 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+
+ blue_stat_led {
+ label = "mirabox:blue:stat";
+ gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ green_stat_led {
+ label = "mirabox:green:stat";
+ gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+ };
+
+ mdio {
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+ ethernet@70000 {
+ pinctrl-0 = <&ge0_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+ ethernet@74000 {
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+
+ mvsdio@d4000 {
+ pinctrl-0 = <&sdio_pins3>;
+ pinctrl-names = "default";
+ status = "okay";
+ /*
+ * No CD or WP GPIOs: SDIO interface used for
+ * Wifi/Bluetooth chip
+ */
+ broken-cd;
+ };
+
+ usb@50000 {
+ status = "okay";
+ };
+
+ usb@51000 {
+ status = "okay";
+ };
+
+ i2c@11000 {
+ status = "okay";
+ clock-frequency = <100000>;
+ pca9505: pca9505@25 {
+ compatible = "nxp,pca9505";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x25>;
+ };
+ };
+
+ nand@d0000 {
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0 0x400000>;
+ };
+ partition@400000 {
+ label = "Linux";
+ reg = <0x400000 0x400000>;
+ };
+ partition@800000 {
+ label = "Filesystem";
+ reg = <0x800000 0x3f800000>;
+ };
+ };
+ };
+ };
+};
+
+&pinctrl {
+ pwr_led_pin: pwr-led-pin {
+ marvell,pins = "mpp63";
+ marvell,function = "gpo";
+ };
+
+ stat_led_pins: stat-led-pins {
+ marvell,pins = "mpp64", "mpp65";
+ marvell,function = "gpio";
+ };
+};
+
diff --git a/arch/arm/boot/dts/armada-370-netgear-rn102.dts b/arch/arm/boot/dts/armada-370-netgear-rn102.dts
new file mode 100644
index 000000000..a31207860
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-netgear-rn102.dts
@@ -0,0 +1,293 @@
+/*
+ * Device Tree file for NETGEAR ReadyNAS 102
+ *
+ * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "armada-370.dtsi"
+
+/ {
+ model = "NETGEAR ReadyNAS 102";
+ compatible = "netgear,readynas-102", "marvell,armada370", "marvell,armada-370-xp";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>; /* 512 MB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+
+ pcie-controller {
+ status = "okay";
+
+ /* Connected to Marvell 88SE9170 SATA controller */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* Connected to FL1009 USB 3.0 controller */
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+ };
+
+ internal-regs {
+ serial@12000 {
+ status = "okay";
+ };
+
+ /* eSATA interface */
+ sata@a0000 {
+ nr-ports = <1>;
+ status = "okay";
+ };
+
+ mdio {
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ phy0: ethernet-phy@0 { /* Marvell 88E1318 */
+ reg = <0>;
+ };
+ };
+
+ ethernet@74000 {
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+
+ usb@50000 {
+ status = "okay";
+ };
+
+ i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ clock-frequency = <100000>;
+ status = "okay";
+
+ isl12057: isl12057@68 {
+ compatible = "isil,isl12057";
+ reg = <0x68>;
+ isil,irq2-can-wakeup-machine;
+ };
+
+ g762: g762@3e {
+ compatible = "gmt,g762";
+ reg = <0x3e>;
+ clocks = <&g762_clk>; /* input clock */
+ fan_gear_mode = <0>;
+ fan_startv = <1>;
+ pwm_polarity = <0>;
+ };
+ };
+
+ nand@d0000 {
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+
+ /* Use Hardware BCH ECC */
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x180000>; /* 1.5MB */
+ read-only;
+ };
+
+ partition@180000 {
+ label = "u-boot-env";
+ reg = <0x180000 0x20000>; /* 128KB */
+ read-only;
+ };
+
+ partition@200000 {
+ label = "uImage";
+ reg = <0x0200000 0x600000>; /* 6MB */
+ };
+
+ partition@800000 {
+ label = "minirootfs";
+ reg = <0x0800000 0x400000>; /* 4MB */
+ };
+
+ /* Last MB is for the BBT, i.e. not writable */
+ partition@c00000 {
+ label = "ubifs";
+ reg = <0x0c00000 0x7400000>; /* 116MB */
+ };
+ };
+ };
+ };
+
+ clocks {
+ g762_clk: g762-oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <8192>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&power_led_pin
+ &sata1_led_pin
+ &sata2_led_pin
+ &backup_led_pin>;
+ pinctrl-names = "default";
+
+ blue-power-led {
+ label = "rn102:blue:pwr";
+ gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+
+ blue-sata1-led {
+ label = "rn102:blue:sata1";
+ gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
+ default-state = "on";
+ };
+
+ blue-sata2-led {
+ label = "rn102:blue:sata2";
+ gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+ default-state = "on";
+ };
+
+ blue-backup-led {
+ label = "rn102:blue:backup";
+ gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;
+ default-state = "on";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&power_button_pin
+ &reset_button_pin
+ &backup_button_pin>;
+ pinctrl-names = "default";
+
+ power-button {
+ label = "Power Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
+ };
+
+ reset-button {
+ label = "Reset Button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
+ };
+
+ backup-button {
+ label = "Backup Button";
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 26 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ pinctrl-0 = <&poweroff>;
+ pinctrl-names = "default";
+ gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pinctrl {
+ power_led_pin: power-led-pin {
+ marvell,pins = "mpp57";
+ marvell,function = "gpio";
+ };
+
+ sata1_led_pin: sata1-led-pin {
+ marvell,pins = "mpp15";
+ marvell,function = "gpio";
+ };
+
+ sata2_led_pin: sata2-led-pin {
+ marvell,pins = "mpp14";
+ marvell,function = "gpio";
+ };
+
+ backup_led_pin: backup-led-pin {
+ marvell,pins = "mpp56";
+ marvell,function = "gpio";
+ };
+
+ backup_button_pin: backup-button-pin {
+ marvell,pins = "mpp58";
+ marvell,function = "gpio";
+ };
+
+ power_button_pin: power-button-pin {
+ marvell,pins = "mpp62";
+ marvell,function = "gpio";
+ };
+
+ reset_button_pin: reset-button-pin {
+ marvell,pins = "mpp6";
+ marvell,function = "gpio";
+ };
+
+ poweroff: poweroff {
+ marvell,pins = "mpp8";
+ marvell,function = "gpio";
+ };
+};
diff --git a/arch/arm/boot/dts/armada-370-netgear-rn104.dts b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
new file mode 100644
index 000000000..00540f292
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
@@ -0,0 +1,305 @@
+/*
+ * Device Tree file for NETGEAR ReadyNAS 104
+ *
+ * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "armada-370.dtsi"
+
+/ {
+ model = "NETGEAR ReadyNAS 104";
+ compatible = "netgear,readynas-104", "marvell,armada370", "marvell,armada-370-xp";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>; /* 512 MB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+
+ pcie-controller {
+ status = "okay";
+
+ /* Connected to FL1009 USB 3.0 controller */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* Connected to Marvell 88SE9215 SATA controller */
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+ };
+
+ internal-regs {
+ serial@12000 {
+ status = "okay";
+ };
+
+ mdio {
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ phy0: ethernet-phy@0 { /* Marvell 88E1318 */
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 { /* Marvell 88E1318 */
+ reg = <1>;
+ };
+ };
+
+ ethernet@70000 {
+ pinctrl-0 = <&ge0_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+
+ ethernet@74000 {
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+
+ usb@50000 {
+ status = "okay";
+ };
+
+ i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ clock-frequency = <100000>;
+ status = "okay";
+
+ isl12057: isl12057@68 {
+ compatible = "isil,isl12057";
+ reg = <0x68>;
+ isil,irq2-can-wakeup-machine;
+ };
+
+ g762: g762@3e {
+ compatible = "gmt,g762";
+ reg = <0x3e>;
+ clocks = <&g762_clk>; /* input clock */
+ fan_gear_mode = <0>;
+ fan_startv = <1>;
+ pwm_polarity = <0>;
+ };
+
+ pca9554: pca9554@23 {
+ compatible = "nxp,pca9554";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x23>;
+ };
+ };
+
+ nand@d0000 {
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+
+ /* Use Hardware BCH ECC */
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x180000>; /* 1.5MB */
+ read-only;
+ };
+
+ partition@180000 {
+ label = "u-boot-env";
+ reg = <0x180000 0x20000>; /* 128KB */
+ read-only;
+ };
+
+ partition@200000 {
+ label = "uImage";
+ reg = <0x0200000 0x600000>; /* 6MB */
+ };
+
+ partition@800000 {
+ label = "minirootfs";
+ reg = <0x0800000 0x400000>; /* 4MB */
+ };
+
+ /* Last MB is for the BBT, i.e. not writable */
+ partition@c00000 {
+ label = "ubifs";
+ reg = <0x0c00000 0x7400000>; /* 116MB */
+ };
+ };
+ };
+ };
+
+ clocks {
+ g762_clk: g762-oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <8192>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&backup_led_pin &power_led_pin>;
+ pinctrl-names = "default";
+
+ blue-backup-led {
+ label = "rn104:blue:backup";
+ gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ blue-power-led {
+ label = "rn104:blue:pwr";
+ gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "keep";
+ };
+
+ blue-sata1-led {
+ label = "rn104:blue:sata1";
+ gpios = <&pca9554 0 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ blue-sata2-led {
+ label = "rn104:blue:sata2";
+ gpios = <&pca9554 1 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ blue-sata3-led {
+ label = "rn104:blue:sata3";
+ gpios = <&pca9554 2 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ blue-sata4-led {
+ label = "rn104:blue:sata4";
+ gpios = <&pca9554 3 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&backup_button_pin
+ &power_button_pin
+ &reset_button_pin>;
+ pinctrl-names = "default";
+
+ backup-button {
+ label = "Backup Button";
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
+ };
+
+ power-button {
+ label = "Power Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
+ };
+
+ reset-button {
+ label = "Reset Button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ pinctrl-0 = <&poweroff>;
+ pinctrl-names = "default";
+ gpios = <&gpio1 28 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pinctrl {
+ poweroff: poweroff {
+ marvell,pins = "mpp60";
+ marvell,function = "gpio";
+ };
+
+ backup_button_pin: backup-button-pin {
+ marvell,pins = "mpp52";
+ marvell,function = "gpio";
+ };
+
+ power_button_pin: power-button-pin {
+ marvell,pins = "mpp62";
+ marvell,function = "gpio";
+ };
+
+ backup_led_pin: backup-led-pin {
+ marvell,pins = "mpp63";
+ marvell,function = "gpo";
+ };
+
+ power_led_pin: power-led-pin {
+ marvell,pins = "mpp64";
+ marvell,function = "gpio";
+ };
+
+ reset_button_pin: reset-button-pin {
+ marvell,pins = "mpp65";
+ marvell,function = "gpio";
+ };
+};
diff --git a/arch/arm/boot/dts/armada-370-rd.dts b/arch/arm/boot/dts/armada-370-rd.dts
new file mode 100644
index 000000000..19475e68b
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-rd.dts
@@ -0,0 +1,249 @@
+/*
+ * Device Tree file for Marvell Armada 370 Reference Design board
+ * (RD-88F6710-A1)
+ *
+ * Copied from arch/arm/boot/dts/armada-370-db.dts
+ *
+ * Copyright (C) 2013 Florian Fainelli <florian@openwrt.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Note: this Device Tree assumes that the bootloader has remapped the
+ * internal registers to 0xf1000000 (instead of the default
+ * 0xd0000000). The 0xf1000000 is the default used by the recent,
+ * DT-capable, U-Boot bootloaders provided by Marvell. Some earlier
+ * boards were delivered with an older version of the bootloader that
+ * left internal registers mapped at 0xd0000000. If you are in this
+ * situation, you should either update your bootloader (preferred
+ * solution) or the below Device Tree should be adjusted.
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "armada-370.dtsi"
+
+/ {
+ model = "Marvell Armada 370 Reference Design";
+ compatible = "marvell,a370-rd", "marvell,armada370", "marvell,armada-370-xp";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>; /* 512 MB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+
+ pcie-controller {
+ status = "okay";
+
+ /* Internal mini-PCIe connector */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* Internal mini-PCIe connector */
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+ };
+
+ internal-regs {
+ serial@12000 {
+ status = "okay";
+ };
+ sata@a0000 {
+ nr-ports = <2>;
+ status = "okay";
+ };
+
+ mdio {
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+ ethernet@70000 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "sgmii";
+ };
+ ethernet@74000 {
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy-mode = "rgmii-id";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+
+ mvsdio@d4000 {
+ pinctrl-0 = <&sdio_pins1>;
+ pinctrl-names = "default";
+ status = "okay";
+ /* No CD or WP GPIOs */
+ broken-cd;
+ };
+
+ usb@50000 {
+ status = "okay";
+ };
+
+ usb@51000 {
+ status = "okay";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ button@1 {
+ label = "Software Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-fan {
+ compatible = "gpio-fan";
+ gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = <0 0 3000 1>;
+ pinctrl-0 = <&fan_pins>;
+ pinctrl-names = "default";
+ };
+
+ gpio_leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+
+ sw_led {
+ label = "370rd:green:sw";
+ gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+ };
+
+ nand@d0000 {
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0 0x800000>;
+ };
+ partition@800000 {
+ label = "Linux";
+ reg = <0x800000 0x800000>;
+ };
+ partition@1000000 {
+ label = "Filesystem";
+ reg = <0x1000000 0x3f000000>;
+ };
+ };
+ };
+ };
+
+ dsa@0 {
+ compatible = "marvell,dsa";
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ dsa,ethernet = <&eth1>;
+ dsa,mii-bus = <&mdio>;
+
+ switch@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10 0>; /* MDIO address 16, switch 0 in tree */
+
+ port@0 {
+ reg = <0>;
+ label = "lan0";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan1";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan2";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan3";
+ };
+
+ port@5 {
+ reg = <5>;
+ label = "cpu";
+ };
+ };
+ };
+ };
+
+&pinctrl {
+ fan_pins: fan-pins {
+ marvell,pins = "mpp8";
+ marvell,function = "gpio";
+ };
+
+ led_pins: led-pins {
+ marvell,pins = "mpp32";
+ marvell,function = "gpio";
+ };
+};
diff --git a/arch/arm/boot/dts/armada-370-synology-ds213j.dts b/arch/arm/boot/dts/armada-370-synology-ds213j.dts
new file mode 100644
index 000000000..b42b76776
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-synology-ds213j.dts
@@ -0,0 +1,348 @@
+/*
+ * Device Tree file for Synology DS213j
+ *
+ * Copyright (C) 2014, Arnaud EBALARD <arno@natisbad.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Note: this Device Tree assumes that the bootloader has remapped the
+ * internal registers to 0xf1000000 (instead of the old 0xd0000000).
+ * The 0xf1000000 is the default used by the recent, DT-capable, U-Boot
+ * bootloaders provided by Marvell. It is used in recent versions of
+ * DSM software provided by Synology. Nonetheless, some earlier boards
+ * were delivered with an older version of u-boot that left internal
+ * registers mapped at 0xd0000000. If you have such a device you will
+ * not be able to directly boot a kernel based on this Device Tree. In
+ * that case, the preferred solution is to update your bootloader (e.g.
+ * by upgrading to latest version of DSM, or building a new one and
+ * installing it from u-boot prompt) or adjust the Devive Tree
+ * (s/0xf1000000/0xd0000000/ in 'ranges' below).
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "armada-370.dtsi"
+
+/ {
+ model = "Synology DS213j";
+ compatible = "synology,ds213j", "marvell,armada370",
+ "marvell,armada-370-xp";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>; /* 512 MB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+
+ internal-regs {
+
+ /* RTC provided by Seiko S-35390A I2C RTC chip below */
+ rtc@10300 {
+ status = "disabled";
+ };
+
+ spi0: spi@10600 {
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q064";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <20000000>;
+
+ /*
+ * Warning!
+ *
+ * Synology u-boot uses its compiled-in environment
+ * and it seems Synology did not care to change u-boot
+ * default configuration in order to allow saving a
+ * modified environment at a sensible location. So,
+ * if you do a 'saveenv' under u-boot, your modified
+ * environment will be saved at 1MB after the start
+ * of the flash, i.e. in the middle of the uImage.
+ * For that reason, it is strongly advised not to
+ * change the default environment, unless you know
+ * what you are doing.
+ */
+ partition@00000000 { /* u-boot */
+ label = "RedBoot";
+ reg = <0x00000000 0x000c0000>; /* 768KB */
+ };
+
+ partition@000c0000 { /* uImage */
+ label = "zImage";
+ reg = <0x000c0000 0x002d0000>; /* 2880KB */
+ };
+
+ partition@00390000 { /* uInitramfs */
+ label = "rd.gz";
+ reg = <0x00390000 0x00440000>; /* 4250KB */
+ };
+
+ partition@007d0000 { /* MAC address and serial number */
+ label = "vendor";
+ reg = <0x007d0000 0x00010000>; /* 64KB */
+ };
+
+ partition@007e0000 {
+ label = "RedBoot config";
+ reg = <0x007e0000 0x00010000>; /* 64KB */
+ };
+
+ partition@007f0000 {
+ label = "FIS directory";
+ reg = <0x007f0000 0x00010000>; /* 64KB */
+ };
+ };
+ };
+
+ i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+ clock-frequency = <400000>;
+ status = "okay";
+
+ /* Main device RTC chip */
+ s35390a: s35390a@30 {
+ compatible = "sii,s35390a";
+ reg = <0x30>;
+ };
+ };
+
+ /* Connected to a header on device's PCB */
+ serial@12000 {
+ status = "okay";
+ };
+
+ /* Connected to a TI MSP430F2111 for power control */
+ serial@12100 {
+ status = "okay";
+ };
+
+ poweroff@12100 {
+ compatible = "synology,power-off";
+ reg = <0x12100 0x100>;
+ clocks = <&coreclk 0>;
+ };
+
+ /* rear USB port, near reset button */
+ usb@50000 {
+ status = "okay";
+ };
+
+ /* rear USB port, near RJ45 port */
+ usb@51000 {
+ status = "okay";
+ };
+
+ mdio {
+ phy1: ethernet-phy@1 { /* Marvell 88E1512 */
+ reg = <1>;
+ };
+ };
+
+ ethernet@70000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "sgmii";
+ };
+
+ sata@a0000 {
+ nr-ports = <2>;
+ status = "okay";
+ };
+ };
+ };
+
+ gpio-fan-32-38 {
+ status = "okay";
+ compatible = "gpio-fan";
+ pinctrl-0 = <&fan_ctrl_low_pin &fan_ctrl_mid_pin
+ &fan_ctrl_high_pin &fan_alarm_pin>;
+ pinctrl-names = "default";
+ gpios = <&gpio1 31 GPIO_ACTIVE_HIGH
+ &gpio2 0 GPIO_ACTIVE_HIGH
+ &gpio2 1 GPIO_ACTIVE_HIGH>;
+ alarm-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = < 0 0
+ 1000 1
+ 1150 2
+ 1350 4
+ 1500 3
+ 1650 5
+ 1750 6
+ 1900 7 >;
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&disk1_led_pin
+ &disk2_led_pin>;
+ pinctrl-names = "default";
+
+ disk1-led-amber {
+ label = "synology:amber:disk1";
+ gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+
+ disk2-led-amber {
+ label = "synology:amber:disk2";
+ gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&sata1_pwr_pin &sata2_pwr_pin>;
+ pinctrl-names = "default";
+
+ sata1_regulator: sata1-regulator {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "SATA1 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ startup-delay-us = <2000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+ };
+
+ sata2_regulator: sata2-regulator {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "SATA2 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ startup-delay-us = <4000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 30 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&pinctrl {
+ disk1_led_pin: disk1-led-pin {
+ marvell,pins = "mpp31";
+ marvell,function = "gpio";
+ };
+
+ disk2_led_pin: disk2-led-pin {
+ marvell,pins = "mpp32";
+ marvell,function = "gpio";
+ };
+
+ sata1_pwr_pin: sata1-pwr-pin {
+ marvell,pins = "mpp37";
+ marvell,function = "gpio";
+ };
+
+ sata2_pwr_pin: sata2-pwr-pin {
+ marvell,pins = "mpp62";
+ marvell,function = "gpio";
+ };
+
+ sata1_pres_pin: sata1-pres-pin {
+ marvell,pins = "mpp60";
+ marvell,function = "gpio";
+ };
+
+ sata2_pres_pin: sata2-pres-pin {
+ marvell,pins = "mpp48";
+ marvell,function = "gpio";
+ };
+
+ syno_id_bit0_pin: syno-id-bit0-pin {
+ marvell,pins = "mpp55";
+ marvell,function = "gpio";
+ };
+
+ syno_id_bit1_pin: syno-id-bit1-pin {
+ marvell,pins = "mpp56";
+ marvell,function = "gpio";
+ };
+
+ syno_id_bit2_pin: syno-id-bit2-pin {
+ marvell,pins = "mpp57";
+ marvell,function = "gpio";
+ };
+
+ syno_id_bit3_pin: syno-id-bit3-pin {
+ marvell,pins = "mpp58";
+ marvell,function = "gpio";
+ };
+
+ fan_ctrl_low_pin: fan-ctrl-low-pin {
+ marvell,pins = "mpp65";
+ marvell,function = "gpio";
+ };
+
+ fan_ctrl_mid_pin: fan-ctrl-mid-pin {
+ marvell,pins = "mpp64";
+ marvell,function = "gpio";
+ };
+
+ fan_ctrl_high_pin: fan-ctrl-high-pin {
+ marvell,pins = "mpp63";
+ marvell,function = "gpo";
+ };
+
+ fan_alarm_pin: fan-alarm-pin {
+ marvell,pins = "mpp38";
+ marvell,function = "gpio";
+ };
+};
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
new file mode 100644
index 000000000..06a2f2ae9
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -0,0 +1,335 @@
+/*
+ * Device Tree Include file for Marvell Armada 370 and Armada XP SoC
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ * Ben Dooks <ben.dooks@codethink.co.uk>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file contains the definitions that are common to the Armada
+ * 370 and Armada XP SoC.
+ */
+
+/include/ "skeleton64.dtsi"
+
+#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
+
+/ {
+ model = "Marvell Armada 370 and XP SoC";
+ compatible = "marvell,armada-370-xp";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ compatible = "marvell,sheeva-v7";
+ device_type = "cpu";
+ reg = <0>;
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts-extended = <&mpic 3>;
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ controller = <&mbusc>;
+ interrupt-parent = <&mpic>;
+ pcie-mem-aperture = <0xf8000000 0x7e00000>;
+ pcie-io-aperture = <0xffe00000 0x100000>;
+
+ devbus-bootcs {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10400 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x2f) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs0 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10408 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x3e) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs1 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10410 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x3d) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs2 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10418 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x3b) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs3 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10420 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x37) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ internal-regs {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
+
+ rtc@10300 {
+ compatible = "marvell,orion-rtc";
+ reg = <0x10300 0x20>;
+ interrupts = <50>;
+ };
+
+ spi0: spi@10600 {
+ compatible = "marvell,armada-370-spi", "marvell,orion-spi";
+ reg = <0x10600 0x28>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ interrupts = <30>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ spi1: spi@10680 {
+ compatible = "marvell,armada-370-spi", "marvell,orion-spi";
+ reg = <0x10680 0x28>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ interrupts = <92>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <31>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@11100 {
+ compatible = "marvell,mv64xxx-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <32>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ uart0: serial@12000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x12000 0x100>;
+ reg-shift = <2>;
+ interrupts = <41>;
+ reg-io-width = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ uart1: serial@12100 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x12100 0x100>;
+ reg-shift = <2>;
+ interrupts = <42>;
+ reg-io-width = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ pinctrl: pin-ctrl@18000 {
+ reg = <0x18000 0x38>;
+ };
+
+ coredivclk: corediv-clock@18740 {
+ compatible = "marvell,armada-370-corediv-clock";
+ reg = <0x18740 0xc>;
+ #clock-cells = <1>;
+ clocks = <&mainpll>;
+ clock-output-names = "nand";
+ };
+
+ mbusc: mbus-controller@20000 {
+ compatible = "marvell,mbus-controller";
+ reg = <0x20000 0x100>, <0x20180 0x20>,
+ <0x20250 0x8>;
+ };
+
+ mpic: interrupt-controller@20a00 {
+ compatible = "marvell,mpic";
+ #interrupt-cells = <1>;
+ #size-cells = <1>;
+ interrupt-controller;
+ msi-controller;
+ };
+
+ coherency-fabric@20200 {
+ compatible = "marvell,coherency-fabric";
+ reg = <0x20200 0xb0>, <0x21010 0x1c>;
+ };
+
+ timer@20300 {
+ reg = <0x20300 0x30>, <0x21040 0x30>;
+ interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
+ };
+
+ watchdog@20300 {
+ reg = <0x20300 0x34>, <0x20704 0x4>;
+ };
+
+ pmsu@22000 {
+ compatible = "marvell,armada-370-pmsu";
+ reg = <0x22000 0x1000>;
+ };
+
+ usb@50000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x50000 0x500>;
+ interrupts = <45>;
+ status = "disabled";
+ };
+
+ usb@51000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x51000 0x500>;
+ interrupts = <46>;
+ status = "disabled";
+ };
+
+ eth0: ethernet@70000 {
+ reg = <0x70000 0x4000>;
+ interrupts = <8>;
+ clocks = <&gateclk 4>;
+ status = "disabled";
+ };
+
+ mdio: mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "marvell,orion-mdio";
+ reg = <0x72004 0x4>;
+ clocks = <&gateclk 4>;
+ };
+
+ eth1: ethernet@74000 {
+ reg = <0x74000 0x4000>;
+ interrupts = <10>;
+ clocks = <&gateclk 3>;
+ status = "disabled";
+ };
+
+ sata@a0000 {
+ compatible = "marvell,armada-370-sata";
+ reg = <0xa0000 0x5000>;
+ interrupts = <55>;
+ clocks = <&gateclk 15>, <&gateclk 30>;
+ clock-names = "0", "1";
+ status = "disabled";
+ };
+
+ nand@d0000 {
+ compatible = "marvell,armada370-nand";
+ reg = <0xd0000 0x54>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupts = <113>;
+ clocks = <&coredivclk 0>;
+ status = "disabled";
+ };
+
+ mvsdio@d4000 {
+ compatible = "marvell,orion-sdio";
+ reg = <0xd4000 0x200>;
+ interrupts = <54>;
+ clocks = <&gateclk 17>;
+ bus-width = <4>;
+ cap-sdio-irq;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ status = "disabled";
+ };
+ };
+ };
+
+ clocks {
+ /* 2 GHz fixed main PLL */
+ mainpll: mainpll {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <2000000000>;
+ };
+ };
+ };
diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
new file mode 100644
index 000000000..ca4257b2f
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -0,0 +1,408 @@
+/*
+ * Device Tree Include file for Marvell Armada 370 family SoC
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contains definitions specific to the Armada 370 SoC that are not
+ * common to all Armada SoCs.
+ */
+
+#include "armada-370-xp.dtsi"
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "Marvell Armada 370 family SoC";
+ compatible = "marvell,armada370", "marvell,armada-370-xp";
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ };
+
+ soc {
+ compatible = "marvell,armada370-mbus", "simple-bus";
+
+ bootrom {
+ compatible = "marvell,bootrom";
+ reg = <MBUS_ID(0x01, 0xe0) 0 0x100000>;
+ };
+
+ pcie-controller {
+ compatible = "marvell,armada-370-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ msi-parent = <&mpic>;
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
+ 0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000
+ 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
+ 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */
+ 0x82000000 0x2 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
+ 0x81000000 0x2 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */>;
+
+ pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 58>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 5>;
+ status = "disabled";
+ };
+
+ pcie@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+ 0x81000000 0 0 0x81000000 0x2 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 62>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 9>;
+ status = "disabled";
+ };
+ };
+
+ internal-regs {
+ L2: l2-cache {
+ compatible = "marvell,aurora-outer-cache";
+ reg = <0x08000 0x1000>;
+ cache-id-part = <0x100>;
+ cache-level = <2>;
+ cache-unified;
+ wt-override;
+ };
+
+ /*
+ * Default SPI pinctrl setting, can be overwritten on
+ * board level if a different configuration is used.
+ */
+ spi0: spi@10600 {
+ pinctrl-0 = <&spi0_pins1>;
+ pinctrl-names = "default";
+ };
+
+ spi1: spi@10680 {
+ pinctrl-0 = <&spi1_pins>;
+ pinctrl-names = "default";
+ };
+
+ i2c0: i2c@11000 {
+ reg = <0x11000 0x20>;
+ };
+
+ i2c1: i2c@11100 {
+ reg = <0x11100 0x20>;
+ };
+
+ gpio0: gpio@18100 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18100 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <82>, <83>, <84>, <85>;
+ };
+
+ gpio1: gpio@18140 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18140 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <87>, <88>, <89>, <90>;
+ };
+
+ gpio2: gpio@18180 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18180 0x40>;
+ ngpios = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <91>;
+ };
+
+ /*
+ * Default UART pinctrl setting without RTS/CTS, can
+ * be overwritten on board level if a different
+ * configuration is used.
+ */
+ uart0: serial@12000 {
+ pinctrl-0 = <&uart0_pins>;
+ pinctrl-names = "default";
+ };
+
+ uart1: serial@12100 {
+ pinctrl-0 = <&uart1_pins>;
+ pinctrl-names = "default";
+ };
+
+ system-controller@18200 {
+ compatible = "marvell,armada-370-xp-system-controller";
+ reg = <0x18200 0x100>;
+ };
+
+ gateclk: clock-gating-control@18220 {
+ compatible = "marvell,armada-370-gating-clock";
+ reg = <0x18220 0x4>;
+ clocks = <&coreclk 0>;
+ #clock-cells = <1>;
+ };
+
+ coreclk: mvebu-sar@18230 {
+ compatible = "marvell,armada-370-core-clock";
+ reg = <0x18230 0x08>;
+ #clock-cells = <1>;
+ };
+
+ thermal@18300 {
+ compatible = "marvell,armada370-thermal";
+ reg = <0x18300 0x4
+ 0x18304 0x4>;
+ status = "okay";
+ };
+
+ sscg@18330 {
+ reg = <0x18330 0x4>;
+ };
+
+ interrupt-controller@20a00 {
+ reg = <0x20a00 0x1d0>, <0x21870 0x58>;
+ };
+
+ timer@20300 {
+ compatible = "marvell,armada-370-timer";
+ clocks = <&coreclk 2>;
+ };
+
+ watchdog@20300 {
+ compatible = "marvell,armada-370-wdt";
+ clocks = <&coreclk 2>;
+ };
+
+ cpurst@20800 {
+ compatible = "marvell,armada-370-cpu-reset";
+ reg = <0x20800 0x8>;
+ };
+
+ audio_controller: audio-controller@30000 {
+ #sound-dai-cells = <1>;
+ compatible = "marvell,armada370-audio";
+ reg = <0x30000 0x4000>;
+ interrupts = <93>;
+ clocks = <&gateclk 0>;
+ clock-names = "internal";
+ status = "disabled";
+ };
+
+ usb@50000 {
+ clocks = <&coreclk 0>;
+ };
+
+ usb@51000 {
+ clocks = <&coreclk 0>;
+ };
+
+ xor@60800 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60800 0x100
+ 0x60A00 0x100>;
+ status = "okay";
+
+ xor00 {
+ interrupts = <51>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor01 {
+ interrupts = <52>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+
+ xor@60900 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60900 0x100
+ 0x60b00 0x100>;
+ status = "okay";
+
+ xor10 {
+ interrupts = <94>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor11 {
+ interrupts = <95>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+
+ ethernet@70000 {
+ compatible = "marvell,armada-370-neta";
+ };
+
+ ethernet@74000 {
+ compatible = "marvell,armada-370-neta";
+ };
+ };
+ };
+};
+
+&pinctrl {
+ compatible = "marvell,mv88f6710-pinctrl";
+
+ spi0_pins1: spi0-pins1 {
+ marvell,pins = "mpp33", "mpp34",
+ "mpp35", "mpp36";
+ marvell,function = "spi0";
+ };
+
+ spi0_pins2: spi0_pins2 {
+ marvell,pins = "mpp32", "mpp63",
+ "mpp64", "mpp65";
+ marvell,function = "spi0";
+ };
+
+ spi1_pins: spi1-pins {
+ marvell,pins = "mpp49", "mpp50",
+ "mpp51", "mpp52";
+ marvell,function = "spi1";
+ };
+
+ uart0_pins: uart0-pins {
+ marvell,pins = "mpp0", "mpp1";
+ marvell,function = "uart0";
+ };
+
+ uart1_pins: uart1-pins {
+ marvell,pins = "mpp41", "mpp42";
+ marvell,function = "uart1";
+ };
+
+ sdio_pins1: sdio-pins1 {
+ marvell,pins = "mpp9", "mpp11", "mpp12",
+ "mpp13", "mpp14", "mpp15";
+ marvell,function = "sd0";
+ };
+
+ sdio_pins2: sdio-pins2 {
+ marvell,pins = "mpp47", "mpp48", "mpp49",
+ "mpp50", "mpp51", "mpp52";
+ marvell,function = "sd0";
+ };
+
+ sdio_pins3: sdio-pins3 {
+ marvell,pins = "mpp48", "mpp49", "mpp50",
+ "mpp51", "mpp52", "mpp53";
+ marvell,function = "sd0";
+ };
+
+ i2c0_pins: i2c0-pins {
+ marvell,pins = "mpp2", "mpp3";
+ marvell,function = "i2c0";
+ };
+
+ i2s_pins1: i2s-pins1 {
+ marvell,pins = "mpp5", "mpp6", "mpp7",
+ "mpp8", "mpp9", "mpp10",
+ "mpp12", "mpp13";
+ marvell,function = "audio";
+ };
+
+ i2s_pins2: i2s-pins2 {
+ marvell,pins = "mpp49", "mpp47", "mpp50",
+ "mpp59", "mpp57", "mpp61",
+ "mpp62", "mpp60", "mpp58";
+ marvell,function = "audio";
+ };
+
+ mdio_pins: mdio-pins {
+ marvell,pins = "mpp17", "mpp18";
+ marvell,function = "ge";
+ };
+
+ ge0_rgmii_pins: ge0-rgmii-pins {
+ marvell,pins = "mpp5", "mpp6", "mpp7", "mpp8",
+ "mpp9", "mpp10", "mpp11", "mpp12",
+ "mpp13", "mpp14", "mpp15", "mpp16";
+ marvell,function = "ge0";
+ };
+
+ ge1_rgmii_pins: ge1-rgmii-pins {
+ marvell,pins = "mpp19", "mpp20", "mpp21", "mpp22",
+ "mpp23", "mpp24", "mpp25", "mpp26",
+ "mpp27", "mpp28", "mpp29", "mpp30";
+ marvell,function = "ge1";
+ };
+};
diff --git a/arch/arm/boot/dts/armada-375-db.dts b/arch/arm/boot/dts/armada-375-db.dts
new file mode 100644
index 000000000..4eabc9c21
--- /dev/null
+++ b/arch/arm/boot/dts/armada-375-db.dts
@@ -0,0 +1,204 @@
+/*
+ * Device Tree file for Marvell Armada 375 evaluation board
+ * (DB-88F6720)
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include "armada-375.dtsi"
+
+/ {
+ model = "Marvell Armada 375 Development Board";
+ compatible = "marvell,a375-db", "marvell,armada375";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>; /* 1 GB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+
+ internal-regs {
+ spi@10600 {
+ pinctrl-0 = <&spi0_pins>;
+ pinctrl-names = "default";
+ /*
+ * SPI conflicts with NAND, so we disable it
+ * here, and select NAND as the enabled device
+ * by default.
+ */
+ status = "disabled";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q128a13";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <108000000>;
+ };
+ };
+
+ i2c@11000 {
+ status = "okay";
+ clock-frequency = <100000>;
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+ };
+
+ i2c@11100 {
+ status = "okay";
+ clock-frequency = <100000>;
+ pinctrl-0 = <&i2c1_pins>;
+ pinctrl-names = "default";
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ pinctrl {
+ sdio_st_pins: sdio-st-pins {
+ marvell,pins = "mpp44", "mpp45";
+ marvell,function = "gpio";
+ };
+ };
+
+ sata@a0000 {
+ status = "okay";
+ nr-ports = <2>;
+ };
+
+ nand: nand@d0000 {
+ pinctrl-0 = <&nand_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0 0x800000>;
+ };
+ partition@800000 {
+ label = "Linux";
+ reg = <0x800000 0x800000>;
+ };
+ partition@1000000 {
+ label = "Filesystem";
+ reg = <0x1000000 0x3f000000>;
+ };
+ };
+
+ usb@54000 {
+ status = "okay";
+ };
+
+ usb3@58000 {
+ status = "okay";
+ };
+
+ mvsdio@d4000 {
+ pinctrl-0 = <&sdio_pins &sdio_st_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ cd-gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ wp-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ };
+
+ mdio {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy3: ethernet-phy@3 {
+ reg = <3>;
+ };
+ };
+
+ ethernet@f0000 {
+ status = "okay";
+
+ eth0@c4000 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+
+ eth1@c5000 {
+ status = "okay";
+ phy = <&phy3>;
+ phy-mode = "gmii";
+ };
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+ /*
+ * The two PCIe units are accessible through
+ * standard PCIe slots on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi
new file mode 100644
index 000000000..f076ff856
--- /dev/null
+++ b/arch/arm/boot/dts/armada-375.dtsi
@@ -0,0 +1,617 @@
+/*
+ * Device Tree Include file for Marvell Armada 375 family SoC
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/phy/phy.h>
+
+#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
+
+/ {
+ model = "Marvell Armada 375 family SoC";
+ compatible = "marvell,armada375";
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ };
+
+ clocks {
+ /* 2 GHz fixed main PLL */
+ mainpll: mainpll {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1000000000>;
+ };
+ /* 25 MHz reference crystal */
+ refclk: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "marvell,armada-375-smp";
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts-extended = <&mpic 3>;
+ };
+
+ soc {
+ compatible = "marvell,armada375-mbus", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ controller = <&mbusc>;
+ interrupt-parent = <&gic>;
+ pcie-mem-aperture = <0xe0000000 0x8000000>;
+ pcie-io-aperture = <0xe8000000 0x100000>;
+
+ bootrom {
+ compatible = "marvell,bootrom";
+ reg = <MBUS_ID(0x01, 0x1d) 0 0x100000>;
+ };
+
+ devbus-bootcs {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10400 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x2f) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs0 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10408 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x3e) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs1 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10410 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x3d) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs2 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10418 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x3b) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs3 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10420 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x37) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ internal-regs {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
+
+ L2: cache-controller@8000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x8000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ scu@c000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0xc000 0x58>;
+ };
+
+ timer@c600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xc600 0x20>;
+ interrupts = <GIC_PPI 13 (IRQ_TYPE_EDGE_RISING | GIC_CPU_MASK_SIMPLE(2))>;
+ clocks = <&coreclk 2>;
+ };
+
+ gic: interrupt-controller@d000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #size-cells = <0>;
+ interrupt-controller;
+ reg = <0xd000 0x1000>,
+ <0xc100 0x100>;
+ };
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "marvell,orion-mdio";
+ reg = <0xc0054 0x4>;
+ clocks = <&gateclk 19>;
+ };
+
+ /* Network controller */
+ ethernet@f0000 {
+ compatible = "marvell,armada-375-pp2";
+ reg = <0xf0000 0xa000>, /* Packet Processor regs */
+ <0xc0000 0x3060>, /* LMS regs */
+ <0xc4000 0x100>, /* eth0 regs */
+ <0xc5000 0x100>; /* eth1 regs */
+ clocks = <&gateclk 3>, <&gateclk 19>;
+ clock-names = "pp_clk", "gop_clk";
+ status = "disabled";
+
+ eth0: eth0@c4000 {
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ port-id = <0>;
+ status = "disabled";
+ };
+
+ eth1: eth1@c5000 {
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ port-id = <1>;
+ status = "disabled";
+ };
+ };
+
+ rtc@10300 {
+ compatible = "marvell,orion-rtc";
+ reg = <0x10300 0x20>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ spi0: spi@10600 {
+ compatible = "marvell,orion-spi";
+ reg = <0x10600 0x50>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ spi1: spi@10680 {
+ compatible = "marvell,orion-spi";
+ reg = <0x10680 0x50>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@11100 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11100 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ uart0: serial@12000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x12000 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ uart1: serial@12100 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x12100 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ pinctrl {
+ compatible = "marvell,mv88f6720-pinctrl";
+ reg = <0x18000 0x24>;
+
+ i2c0_pins: i2c0-pins {
+ marvell,pins = "mpp14", "mpp15";
+ marvell,function = "i2c0";
+ };
+
+ i2c1_pins: i2c1-pins {
+ marvell,pins = "mpp61", "mpp62";
+ marvell,function = "i2c1";
+ };
+
+ nand_pins: nand-pins {
+ marvell,pins = "mpp0", "mpp1", "mpp2",
+ "mpp3", "mpp4", "mpp5",
+ "mpp6", "mpp7", "mpp8",
+ "mpp9", "mpp10", "mpp11",
+ "mpp12", "mpp13";
+ marvell,function = "nand";
+ };
+
+ sdio_pins: sdio-pins {
+ marvell,pins = "mpp24", "mpp25", "mpp26",
+ "mpp27", "mpp28", "mpp29";
+ marvell,function = "sd";
+ };
+
+ spi0_pins: spi0-pins {
+ marvell,pins = "mpp0", "mpp1", "mpp4",
+ "mpp5", "mpp8", "mpp9";
+ marvell,function = "spi0";
+ };
+ };
+
+ gpio0: gpio@18100 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18100 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpio1: gpio@18140 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18140 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpio2: gpio@18180 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18180 0x40>;
+ ngpios = <3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ system-controller@18200 {
+ compatible = "marvell,armada-375-system-controller";
+ reg = <0x18200 0x100>;
+ };
+
+ gateclk: clock-gating-control@18220 {
+ compatible = "marvell,armada-375-gating-clock";
+ reg = <0x18220 0x4>;
+ clocks = <&coreclk 0>;
+ #clock-cells = <1>;
+ };
+
+ usbcluster: usb-cluster@18400 {
+ compatible = "marvell,armada-375-usb-cluster";
+ reg = <0x18400 0x4>;
+ #phy-cells = <1>;
+ };
+
+ mbusc: mbus-controller@20000 {
+ compatible = "marvell,mbus-controller";
+ reg = <0x20000 0x100>, <0x20180 0x20>;
+ };
+
+ mpic: interrupt-controller@20a00 {
+ compatible = "marvell,mpic";
+ reg = <0x20a00 0x2d0>, <0x21070 0x58>;
+ #interrupt-cells = <1>;
+ #size-cells = <1>;
+ interrupt-controller;
+ msi-controller;
+ interrupts = <GIC_PPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ timer@20300 {
+ compatible = "marvell,armada-375-timer", "marvell,armada-370-timer";
+ reg = <0x20300 0x30>, <0x21040 0x30>;
+ interrupts-extended = <&gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <&gic GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <&gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <&gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <&mpic 5>,
+ <&mpic 6>;
+ clocks = <&coreclk 0>, <&refclk>;
+ clock-names = "nbclk", "fixed";
+ };
+
+ watchdog@20300 {
+ compatible = "marvell,armada-375-wdt";
+ reg = <0x20300 0x34>, <0x20704 0x4>, <0x18254 0x4>;
+ clocks = <&coreclk 0>, <&refclk>;
+ clock-names = "nbclk", "fixed";
+ };
+
+ cpurst@20800 {
+ compatible = "marvell,armada-370-cpu-reset";
+ reg = <0x20800 0x10>;
+ };
+
+ coherency-fabric@21010 {
+ compatible = "marvell,armada-375-coherency-fabric";
+ reg = <0x21010 0x1c>;
+ };
+
+ usb@50000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x50000 0x500>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 18>;
+ phys = <&usbcluster PHY_TYPE_USB2>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ usb@54000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x54000 0x500>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 26>;
+ status = "disabled";
+ };
+
+ usb3@58000 {
+ compatible = "marvell,armada-375-xhci";
+ reg = <0x58000 0x20000>,<0x5b880 0x80>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 16>;
+ phys = <&usbcluster PHY_TYPE_USB3>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ xor@60800 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60800 0x100
+ 0x60A00 0x100>;
+ clocks = <&gateclk 22>;
+ status = "okay";
+
+ xor00 {
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor01 {
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+
+ xor@60900 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60900 0x100
+ 0x60b00 0x100>;
+ clocks = <&gateclk 23>;
+ status = "okay";
+
+ xor10 {
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor11 {
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+
+ sata@a0000 {
+ compatible = "marvell,orion-sata";
+ reg = <0xa0000 0x5000>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 14>, <&gateclk 20>;
+ clock-names = "0", "1";
+ status = "disabled";
+ };
+
+ nand@d0000 {
+ compatible = "marvell,armada370-nand";
+ reg = <0xd0000 0x54>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 11>;
+ status = "disabled";
+ };
+
+ mvsdio@d4000 {
+ compatible = "marvell,orion-sdio";
+ reg = <0xd4000 0x200>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 17>;
+ bus-width = <4>;
+ cap-sdio-irq;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ status = "disabled";
+ };
+
+ thermal@e8078 {
+ compatible = "marvell,armada375-thermal";
+ reg = <0xe8078 0x4>, <0xe807c 0x8>;
+ status = "okay";
+ };
+
+ coreclk: mvebu-sar@e8204 {
+ compatible = "marvell,armada-375-core-clock";
+ reg = <0xe8204 0x04>;
+ #clock-cells = <1>;
+ };
+
+ coredivclk: corediv-clock@e8250 {
+ compatible = "marvell,armada-375-corediv-clock";
+ reg = <0xe8250 0xc>;
+ #clock-cells = <1>;
+ clocks = <&mainpll>;
+ clock-output-names = "nand";
+ };
+ };
+
+ pcie-controller {
+ compatible = "marvell,armada-370-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ msi-parent = <&mpic>;
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
+ 0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000
+ 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0 MEM */
+ 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0 IO */
+ 0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 1 MEM */
+ 0x81000000 0x2 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 1 IO */>;
+
+ pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 5>;
+ status = "disabled";
+ };
+
+ pcie@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+ 0x81000000 0 0 0x81000000 0x2 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <1>;
+ clocks = <&gateclk 6>;
+ status = "disabled";
+ };
+
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-380.dtsi b/arch/arm/boot/dts/armada-380.dtsi
new file mode 100644
index 000000000..5102d19cc
--- /dev/null
+++ b/arch/arm/boot/dts/armada-380.dtsi
@@ -0,0 +1,152 @@
+/*
+ * Device Tree Include file for Marvell Armada 380 SoC.
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "armada-38x.dtsi"
+
+/ {
+ model = "Marvell Armada 380 family SoC";
+ compatible = "marvell,armada380";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "marvell,armada-380-smp";
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+ };
+
+ soc {
+ internal-regs {
+ pinctrl@18000 {
+ compatible = "marvell,mv88f6810-pinctrl";
+ };
+ };
+
+ pcie-controller {
+ compatible = "marvell,armada-370-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ msi-parent = <&mpic>;
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000
+ 0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
+ 0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000
+ 0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000
+ 0x82000000 0x1 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 0 MEM */
+ 0x81000000 0x1 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 0 IO */
+ 0x82000000 0x2 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 1 MEM */
+ 0x81000000 0x2 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 1 IO */
+ 0x82000000 0x3 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 2 MEM */
+ 0x81000000 0x3 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 2 IO */>;
+
+ /* x1 port */
+ pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 8>;
+ status = "disabled";
+ };
+
+ /* x1 port */
+ pcie@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+ 0x81000000 0 0 0x81000000 0x2 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 5>;
+ status = "disabled";
+ };
+
+ /* x1 port */
+ pcie@3,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
+ reg = <0x1800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
+ 0x81000000 0 0 0x81000000 0x3 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ marvell,pcie-port = <2>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 6>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-385-db-ap.dts b/arch/arm/boot/dts/armada-385-db-ap.dts
new file mode 100644
index 000000000..7219ac3a3
--- /dev/null
+++ b/arch/arm/boot/dts/armada-385-db-ap.dts
@@ -0,0 +1,218 @@
+/*
+ * Device Tree file for Marvell Armada 385 Access Point Development board
+ * (DB-88F6820-AP)
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Nadav Haklai <nadavh@marvell.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "armada-385.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Marvell Armada 385 Access Point Development Board";
+ compatible = "marvell,a385-db-ap", "marvell,armada385", "marvell,armada38x";
+
+ chosen {
+ stdout-path = "serial1:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000>; /* 2GB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+
+ internal-regs {
+ spi1: spi@10680 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins>;
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p128";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <54000000>;
+ };
+ };
+
+ i2c0: i2c@11000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+
+ /*
+ * This bus is wired to two EEPROM
+ * sockets, one of which holding the
+ * board ID used by the bootloader.
+ * Erasing this EEPROM's content will
+ * brick the board.
+ * Use this bus with caution.
+ */
+ };
+
+ mdio@72004 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+
+ phy0: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ phy1: ethernet-phy@4 {
+ reg = <4>;
+ };
+
+ phy2: ethernet-phy@6 {
+ reg = <6>;
+ };
+ };
+
+ /* UART0 is exposed through the JP8 connector */
+ uart0: serial@12000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+ };
+
+ /*
+ * UART1 is exposed through a FTDI chip
+ * wired to the mini-USB connector
+ */
+ uart1: serial@12100 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "okay";
+ };
+
+ pinctrl@18000 {
+ xhci0_vbus_pins: xhci0-vbus-pins {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+ };
+
+ ethernet@30000 {
+ status = "okay";
+ phy = <&phy2>;
+ phy-mode = "sgmii";
+ };
+
+ ethernet@34000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "sgmii";
+ };
+
+ ethernet@70000 {
+ pinctrl-names = "default";
+
+ /*
+ * The Reference Clock 0 is used to
+ * provide a clock to the PHY
+ */
+ pinctrl-0 = <&ge0_rgmii_pins>, <&ref_clk0_pins>;
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+
+ nfc: flash@d0000 {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ num-cs = <1>;
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+ };
+
+ usb3@f0000 {
+ status = "okay";
+ usb-phy = <&usb3_phy>;
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+
+ /*
+ * The three PCIe units are accessible through
+ * standard mini-PCIe slots on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+
+ pcie@3,0 {
+ /* Port 2, Lane 0 */
+ status = "okay";
+ };
+ };
+ };
+
+ usb3_phy: usb3_phy {
+ compatible = "usb-nop-xceiv";
+ vcc-supply = <&reg_xhci0_vbus>;
+ };
+
+ reg_xhci0_vbus: xhci0-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&xhci0_vbus_pins>;
+ regulator-name = "xhci0-vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ };
+};
diff --git a/arch/arm/boot/dts/armada-385.dtsi b/arch/arm/boot/dts/armada-385.dtsi
new file mode 100644
index 000000000..8e67d2c08
--- /dev/null
+++ b/arch/arm/boot/dts/armada-385.dtsi
@@ -0,0 +1,184 @@
+/*
+ * Device Tree Include file for Marvell Armada 385 SoC.
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "armada-38x.dtsi"
+
+/ {
+ model = "Marvell Armada 385 family SoC";
+ compatible = "marvell,armada385", "marvell,armada380";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "marvell,armada-380-smp";
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ };
+ };
+
+ soc {
+ internal-regs {
+ pinctrl@18000 {
+ compatible = "marvell,mv88f6820-pinctrl";
+ };
+ };
+
+ pcie-controller {
+ compatible = "marvell,armada-370-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ msi-parent = <&mpic>;
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000
+ 0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
+ 0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000
+ 0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000
+ 0x82000000 0x1 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 0 MEM */
+ 0x81000000 0x1 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 0 IO */
+ 0x82000000 0x2 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 1 MEM */
+ 0x81000000 0x2 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 1 IO */
+ 0x82000000 0x3 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 2 MEM */
+ 0x81000000 0x3 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 2 IO */
+ 0x82000000 0x4 0 MBUS_ID(0x04, 0xb8) 0 1 0 /* Port 3 MEM */
+ 0x81000000 0x4 0 MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 3 IO */>;
+
+ /*
+ * This port can be either x4 or x1. When
+ * configured in x4 by the bootloader, then
+ * pcie@4,0 is not available.
+ */
+ pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 8>;
+ status = "disabled";
+ };
+
+ /* x1 port */
+ pcie@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+ 0x81000000 0 0 0x81000000 0x2 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 5>;
+ status = "disabled";
+ };
+
+ /* x1 port */
+ pcie@3,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
+ reg = <0x1800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
+ 0x81000000 0 0 0x81000000 0x3 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ marvell,pcie-port = <2>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 6>;
+ status = "disabled";
+ };
+
+ /*
+ * x1 port only available when pcie@1,0 is
+ * configured as a x1 port
+ */
+ pcie@4,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
+ reg = <0x2000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0
+ 0x81000000 0 0 0x81000000 0x4 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ marvell,pcie-port = <3>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 7>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-388-db.dts b/arch/arm/boot/dts/armada-388-db.dts
new file mode 100644
index 000000000..51d1623de
--- /dev/null
+++ b/arch/arm/boot/dts/armada-388-db.dts
@@ -0,0 +1,186 @@
+/*
+ * Device Tree file for Marvell Armada 388 evaluation board
+ * (DB-88F6820)
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "armada-388.dtsi"
+
+/ {
+ model = "Marvell Armada 385 Development Board";
+ compatible = "marvell,a385-db", "marvell,armada388",
+ "marvell,armada385", "marvell,armada380";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>; /* 256 MB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+
+ internal-regs {
+ spi@10600 {
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "w25q32";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <108000000>;
+ };
+ };
+
+ i2c@11000 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@11100 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ ethernet@30000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+
+ usb@58000 {
+ status = "ok";
+ };
+
+ ethernet@70000 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+
+ mdio@72004 {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+
+ sata@a8000 {
+ status = "okay";
+ };
+
+ sata@e0000 {
+ status = "okay";
+ };
+
+ flash@d0000 {
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0 0x800000>;
+ };
+ partition@800000 {
+ label = "Linux";
+ reg = <0x800000 0x800000>;
+ };
+ partition@1000000 {
+ label = "Filesystem";
+ reg = <0x1000000 0x3f000000>;
+ };
+ };
+
+ sdhci@d8000 {
+ broken-cd;
+ wp-inverted;
+ bus-width = <8>;
+ status = "okay";
+ no-1-8-v;
+ };
+
+ usb3@f0000 {
+ status = "okay";
+ };
+
+ usb3@f8000 {
+ status = "okay";
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+ /*
+ * The two PCIe units are accessible through
+ * standard PCIe slots on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts
new file mode 100644
index 000000000..78514ab0b
--- /dev/null
+++ b/arch/arm/boot/dts/armada-388-gp.dts
@@ -0,0 +1,413 @@
+/*
+ * Device Tree file for Marvell Armada 385 development board
+ * (RD-88F6820-GP)
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "armada-388.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Marvell Armada 385 GP";
+ compatible = "marvell,a385-gp", "marvell,armada388", "marvell,armada380";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000>; /* 2 GB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+
+ internal-regs {
+ spi@10600 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p128";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <50000000>;
+ m25p,fast-read;
+ };
+ };
+
+ i2c@11000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+ clock-frequency = <100000>;
+ /*
+ * The EEPROM located at adresse 54 is needed
+ * for the boot - DO NOT ERASE IT -
+ */
+
+ expander0: pca9555@20 {
+ compatible = "nxp,pca9555";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pca0_pins>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x20>;
+ };
+
+ expander1: pca9555@21 {
+ compatible = "nxp,pca9555";
+ pinctrl-names = "default";
+ interrupt-parent = <&gpio0>;
+ interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x21>;
+ };
+
+ };
+
+ serial@12000 {
+ /*
+ * Exported on the micro USB connector CON16
+ * through an FTDI
+ */
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+ };
+
+ /* GE1 CON15 */
+ ethernet@30000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+
+ /* CON4 */
+ usb@58000 {
+ vcc-supply = <&reg_usb2_0_vbus>;
+ status = "okay";
+ };
+
+ /* GE0 CON1 */
+ ethernet@70000 {
+ pinctrl-names = "default";
+ /*
+ * The Reference Clock 0 is used to provide a
+ * clock to the PHY
+ */
+ pinctrl-0 = <&ge0_rgmii_pins>, <&ref_clk0_pins>;
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+
+
+ mdio@72004 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+
+ phy0: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ phy1: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+ sata@a8000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sata0_pins>, <&sata1_pins>;
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sata0: sata-port@0 {
+ reg = <0>;
+ target-supply = <&reg_5v_sata0>;
+ };
+
+ sata1: sata-port@1 {
+ reg = <1>;
+ target-supply = <&reg_5v_sata1>;
+ };
+ };
+
+ sata@e0000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sata2_pins>, <&sata3_pins>;
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sata2: sata-port@0 {
+ reg = <0>;
+ target-supply = <&reg_5v_sata2>;
+ };
+
+ sata3: sata-port@1 {
+ reg = <1>;
+ target-supply = <&reg_5v_sata3>;
+ };
+ };
+
+ sdhci@d8000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhci_pins>;
+ cd-gpios = <&expander0 5 GPIO_ACTIVE_LOW>;
+ no-1-8-v;
+ wp-inverted;
+ bus-width = <8>;
+ status = "okay";
+ };
+
+ /* CON5 */
+ usb3@f0000 {
+ vcc-supply = <&reg_usb2_1_vbus>;
+ status = "okay";
+ };
+
+ /* CON7 */
+ usb3@f8000 {
+ vcc-supply = <&reg_usb3_vbus>;
+ status = "okay";
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+ /*
+ * One PCIe units is accessible through
+ * standard PCIe slot on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /*
+ * The two other PCIe units are accessible
+ * through mini PCIe slot on the board.
+ */
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+ pcie@3,0 {
+ /* Port 2, Lane 0 */
+ status = "okay";
+ };
+ };
+
+ gpio-fan {
+ compatible = "gpio-fan";
+ gpios = <&expander1 3 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = < 0 0
+ 3000 1>;
+ };
+ };
+
+ reg_usb3_vbus: usb3-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb3-vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander1 15 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_usb2_0_vbus: v5-vbus0 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-vbus0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander1 14 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_usb2_1_vbus: v5-vbus1 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-vbus1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander0 4 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_usb2_1_vbus: v5-vbus1 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-vbus1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander0 4 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_sata0: pwr-sata0 {
+ compatible = "regulator-fixed";
+ regulator-name = "pwr_en_sata0";
+ enable-active-high;
+ regulator-always-on;
+
+ };
+
+ reg_5v_sata0: v5-sata0 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-sata0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata0>;
+ };
+
+ reg_12v_sata0: v12-sata0 {
+ compatible = "regulator-fixed";
+ regulator-name = "v12.0-sata0";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata0>;
+ };
+
+ reg_sata1: pwr-sata1 {
+ regulator-name = "pwr_en_sata1";
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander0 3 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_5v_sata1: v5-sata1 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-sata1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata1>;
+ };
+
+ reg_12v_sata1: v12-sata1 {
+ compatible = "regulator-fixed";
+ regulator-name = "v12.0-sata1";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata1>;
+ };
+
+ reg_sata2: pwr-sata2 {
+ compatible = "regulator-fixed";
+ regulator-name = "pwr_en_sata2";
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander0 11 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_5v_sata2: v5-sata2 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-sata2";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata2>;
+ };
+
+ reg_12v_sata2: v12-sata2 {
+ compatible = "regulator-fixed";
+ regulator-name = "v12.0-sata2";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata2>;
+ };
+
+ reg_sata3: pwr-sata3 {
+ compatible = "regulator-fixed";
+ regulator-name = "pwr_en_sata3";
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander0 12 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_5v_sata3: v5-sata3 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-sata3";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata3>;
+ };
+
+ reg_12v_sata3: v12-sata3 {
+ compatible = "regulator-fixed";
+ regulator-name = "v12.0-sata3";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata3>;
+ };
+};
+
+&pinctrl {
+ pca0_pins: pca0_pins {
+ marvell,pins = "mpp18";
+ marvell,function = "gpio";
+ };
+};
diff --git a/arch/arm/boot/dts/armada-388-rd.dts b/arch/arm/boot/dts/armada-388-rd.dts
new file mode 100644
index 000000000..1dc6e2341
--- /dev/null
+++ b/arch/arm/boot/dts/armada-388-rd.dts
@@ -0,0 +1,142 @@
+/*
+ * Device Tree file for Marvell Armada 388 Reference Design board
+ * (RD-88F6820-AP)
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "armada-388.dtsi"
+
+/ {
+ model = "Marvell Armada 385 Reference Design";
+ compatible = "marvell,a385-rd", "marvell,armada388",
+ "marvell,armada385","marvell,armada380";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>; /* 256 MB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+
+ internal-regs {
+ spi@10600 {
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p128";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <108000000>;
+ };
+ };
+
+ i2c@11000 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ sdhci@d8000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhci_pins>;
+ broken-cd;
+ no-1-8-v;
+ wp-inverted;
+ bus-width = <8>;
+ status = "okay";
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ ethernet@30000 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+
+ ethernet@70000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+
+
+ mdio@72004 {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+
+ usb3@f0000 {
+ status = "okay";
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+ /*
+ * One PCIe units is accessible through
+ * standard PCIe slot on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-388.dtsi b/arch/arm/boot/dts/armada-388.dtsi
new file mode 100644
index 000000000..564fa5937
--- /dev/null
+++ b/arch/arm/boot/dts/armada-388.dtsi
@@ -0,0 +1,70 @@
+/*
+ * Device Tree Include file for Marvell Armada 388 SoC.
+ *
+ * Copyright (C) 2015 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ * The main difference with the Armada 385 is that the 388 can handle two more
+ * SATA ports. So we can reuse the dtsi of the Armada 385, override the pinctrl
+ * property and the name of the SoC, and add the second SATA host which control
+ * the 2 other ports.
+ */
+
+#include "armada-385.dtsi"
+
+/ {
+ model = "Marvell Armada 388 family SoC";
+ compatible = "marvell,armada388", "marvell,armada385",
+ "marvell,armada380";
+
+ soc {
+ internal-regs {
+ pinctrl@18000 {
+ compatible = "marvell,mv88f6828-pinctrl";
+ };
+
+ sata@e0000 {
+ compatible = "marvell,armada-380-ahci";
+ reg = <0xe0000 0x2000>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 30>;
+ status = "disabled";
+ };
+
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
new file mode 100644
index 000000000..218a2acd3
--- /dev/null
+++ b/arch/arm/boot/dts/armada-38x.dtsi
@@ -0,0 +1,598 @@
+/*
+ * Device Tree Include file for Marvell Armada 38x family of SoCs.
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
+
+/ {
+ model = "Marvell Armada 38x family SoC";
+ compatible = "marvell,armada380";
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts-extended = <&mpic 3>;
+ };
+
+ soc {
+ compatible = "marvell,armada380-mbus", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ controller = <&mbusc>;
+ interrupt-parent = <&gic>;
+ pcie-mem-aperture = <0xe0000000 0x8000000>;
+ pcie-io-aperture = <0xe8000000 0x100000>;
+
+ bootrom {
+ compatible = "marvell,bootrom";
+ reg = <MBUS_ID(0x01, 0x1d) 0 0x200000>;
+ };
+
+ devbus-bootcs {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10400 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x2f) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs0 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10408 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x3e) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs1 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10410 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x3d) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs2 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10418 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x3b) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs3 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10420 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x37) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ internal-regs {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
+
+ L2: cache-controller@8000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x8000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ scu@c000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0xc000 0x58>;
+ };
+
+ timer@c600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xc600 0x20>;
+ interrupts = <GIC_PPI 13 (IRQ_TYPE_EDGE_RISING | GIC_CPU_MASK_SIMPLE(2))>;
+ clocks = <&coreclk 2>;
+ };
+
+ gic: interrupt-controller@d000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #size-cells = <0>;
+ interrupt-controller;
+ reg = <0xd000 0x1000>,
+ <0xc100 0x100>;
+ };
+
+ spi0: spi@10600 {
+ compatible = "marvell,orion-spi";
+ reg = <0x10600 0x50>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ spi1: spi@10680 {
+ compatible = "marvell,orion-spi";
+ reg = <0x10680 0x50>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@11100 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11100 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ uart0: serial@12000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x12000 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ uart1: serial@12100 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x12100 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ pinctrl: pinctrl@18000 {
+ reg = <0x18000 0x20>;
+
+ ge0_rgmii_pins: ge-rgmii-pins-0 {
+ marvell,pins = "mpp6", "mpp7", "mpp8",
+ "mpp9", "mpp10", "mpp11",
+ "mpp12", "mpp13", "mpp14",
+ "mpp15", "mpp16", "mpp17";
+ marvell,function = "ge0";
+ };
+
+ ge1_rgmii_pins: ge-rgmii-pins-1 {
+ marvell,pins = "mpp21", "mpp27", "mpp28",
+ "mpp29", "mpp30", "mpp31",
+ "mpp32", "mpp37", "mpp38",
+ "mpp39", "mpp40", "mpp41";
+ marvell,function = "ge1";
+ };
+
+ i2c0_pins: i2c-pins-0 {
+ marvell,pins = "mpp2", "mpp3";
+ marvell,function = "i2c0";
+ };
+
+ mdio_pins: mdio-pins {
+ marvell,pins = "mpp4", "mpp5";
+ marvell,function = "ge";
+ };
+
+ ref_clk0_pins: ref-clk-pins-0 {
+ marvell,pins = "mpp45";
+ marvell,function = "ref";
+ };
+
+ ref_clk1_pins: ref-clk-pins-1 {
+ marvell,pins = "mpp46";
+ marvell,function = "ref";
+ };
+
+ spi0_pins: spi-pins-0 {
+ marvell,pins = "mpp22", "mpp23", "mpp24",
+ "mpp25";
+ marvell,function = "spi0";
+ };
+
+ spi1_pins: spi-pins-1 {
+ marvell,pins = "mpp56", "mpp57", "mpp58",
+ "mpp59";
+ marvell,function = "spi1";
+ };
+
+ uart0_pins: uart-pins-0 {
+ marvell,pins = "mpp0", "mpp1";
+ marvell,function = "ua0";
+ };
+
+ uart1_pins: uart-pins-1 {
+ marvell,pins = "mpp19", "mpp20";
+ marvell,function = "ua1";
+ };
+
+ sdhci_pins: sdhci-pins {
+ marvell,pins = "mpp48", "mpp49", "mpp50",
+ "mpp52", "mpp53", "mpp54",
+ "mpp55", "mpp57", "mpp58",
+ "mpp59";
+ marvell,function = "sd0";
+ };
+
+ sata0_pins: sata-pins-0 {
+ marvell,pins = "mpp20";
+ marvell,function = "sata0";
+ };
+
+ sata1_pins: sata-pins-1 {
+ marvell,pins = "mpp19";
+ marvell,function = "sata1";
+ };
+
+ sata2_pins: sata-pins-2 {
+ marvell,pins = "mpp47";
+ marvell,function = "sata2";
+ };
+
+ sata3_pins: sata-pins-3 {
+ marvell,pins = "mpp44";
+ marvell,function = "sata3";
+ };
+ };
+
+ gpio0: gpio@18100 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18100 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpio1: gpio@18140 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18140 0x40>;
+ ngpios = <28>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ system-controller@18200 {
+ compatible = "marvell,armada-380-system-controller",
+ "marvell,armada-370-xp-system-controller";
+ reg = <0x18200 0x100>;
+ };
+
+ gateclk: clock-gating-control@18220 {
+ compatible = "marvell,armada-380-gating-clock";
+ reg = <0x18220 0x4>;
+ clocks = <&coreclk 0>;
+ #clock-cells = <1>;
+ };
+
+ coreclk: mvebu-sar@18600 {
+ compatible = "marvell,armada-380-core-clock";
+ reg = <0x18600 0x04>;
+ #clock-cells = <1>;
+ };
+
+ mbusc: mbus-controller@20000 {
+ compatible = "marvell,mbus-controller";
+ reg = <0x20000 0x100>, <0x20180 0x20>;
+ };
+
+ mpic: interrupt-controller@20a00 {
+ compatible = "marvell,mpic";
+ reg = <0x20a00 0x2d0>, <0x21070 0x58>;
+ #interrupt-cells = <1>;
+ #size-cells = <1>;
+ interrupt-controller;
+ msi-controller;
+ interrupts = <GIC_PPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ timer@20300 {
+ compatible = "marvell,armada-380-timer",
+ "marvell,armada-xp-timer";
+ reg = <0x20300 0x30>, <0x21040 0x30>;
+ interrupts-extended = <&gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <&gic GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <&gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <&gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <&mpic 5>,
+ <&mpic 6>;
+ clocks = <&coreclk 2>, <&refclk>;
+ clock-names = "nbclk", "fixed";
+ };
+
+ watchdog@20300 {
+ compatible = "marvell,armada-380-wdt";
+ reg = <0x20300 0x34>, <0x20704 0x4>, <0x18260 0x4>;
+ clocks = <&coreclk 2>, <&refclk>;
+ clock-names = "nbclk", "fixed";
+ };
+
+ cpurst@20800 {
+ compatible = "marvell,armada-370-cpu-reset";
+ reg = <0x20800 0x10>;
+ };
+
+ mpcore-soc-ctrl@20d20 {
+ compatible = "marvell,armada-380-mpcore-soc-ctrl";
+ reg = <0x20d20 0x6c>;
+ };
+
+ coherency-fabric@21010 {
+ compatible = "marvell,armada-380-coherency-fabric";
+ reg = <0x21010 0x1c>;
+ };
+
+ pmsu@22000 {
+ compatible = "marvell,armada-380-pmsu";
+ reg = <0x22000 0x1000>;
+ };
+
+ eth1: ethernet@30000 {
+ compatible = "marvell,armada-370-neta";
+ reg = <0x30000 0x4000>;
+ interrupts-extended = <&mpic 10>;
+ clocks = <&gateclk 3>;
+ status = "disabled";
+ };
+
+ eth2: ethernet@34000 {
+ compatible = "marvell,armada-370-neta";
+ reg = <0x34000 0x4000>;
+ interrupts-extended = <&mpic 12>;
+ clocks = <&gateclk 2>;
+ status = "disabled";
+ };
+
+ usb@58000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x58000 0x500>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 18>;
+ status = "disabled";
+ };
+
+ xor@60800 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60800 0x100
+ 0x60a00 0x100>;
+ clocks = <&gateclk 22>;
+ status = "okay";
+
+ xor00 {
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor01 {
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+
+ xor@60900 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60900 0x100
+ 0x60b00 0x100>;
+ clocks = <&gateclk 28>;
+ status = "okay";
+
+ xor10 {
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor11 {
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+
+ eth0: ethernet@70000 {
+ compatible = "marvell,armada-370-neta";
+ reg = <0x70000 0x4000>;
+ interrupts-extended = <&mpic 8>;
+ clocks = <&gateclk 4>;
+ status = "disabled";
+ };
+
+ mdio@72004 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "marvell,orion-mdio";
+ reg = <0x72004 0x4>;
+ clocks = <&gateclk 4>;
+ };
+
+ rtc@a3800 {
+ compatible = "marvell,armada-380-rtc";
+ reg = <0xa3800 0x20>, <0x184a0 0x0c>;
+ reg-names = "rtc", "rtc-soc";
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sata@a8000 {
+ compatible = "marvell,armada-380-ahci";
+ reg = <0xa8000 0x2000>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 15>;
+ status = "disabled";
+ };
+
+ sata@e0000 {
+ compatible = "marvell,armada-380-ahci";
+ reg = <0xe0000 0x2000>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 30>;
+ status = "disabled";
+ };
+
+ coredivclk: clock@e4250 {
+ compatible = "marvell,armada-380-corediv-clock";
+ reg = <0xe4250 0xc>;
+ #clock-cells = <1>;
+ clocks = <&mainpll>;
+ clock-output-names = "nand";
+ };
+
+ thermal@e8078 {
+ compatible = "marvell,armada380-thermal";
+ reg = <0xe4078 0x4>, <0xe4074 0x4>;
+ status = "okay";
+ };
+
+ flash@d0000 {
+ compatible = "marvell,armada370-nand";
+ reg = <0xd0000 0x54>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&coredivclk 0>;
+ status = "disabled";
+ };
+
+ sdhci@d8000 {
+ compatible = "marvell,armada-380-sdhci";
+ reg-names = "sdhci", "mbus", "conf-sdio3";
+ reg = <0xd8000 0x1000>,
+ <0xdc000 0x100>,
+ <0x18454 0x4>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 17>;
+ mrvl,clk-delay-cycles = <0x1F>;
+ status = "disabled";
+ };
+
+ usb3@f0000 {
+ compatible = "marvell,armada-380-xhci";
+ reg = <0xf0000 0x4000>,<0xf4000 0x4000>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 9>;
+ status = "disabled";
+ };
+
+ usb3@f8000 {
+ compatible = "marvell,armada-380-xhci";
+ reg = <0xf8000 0x4000>,<0xfc000 0x4000>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 10>;
+ status = "disabled";
+ };
+ };
+ };
+
+ clocks {
+ /* 2 GHz fixed main PLL */
+ mainpll: mainpll {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1000000000>;
+ };
+
+ /* 25 MHz reference crystal */
+ refclk: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-390.dtsi b/arch/arm/boot/dts/armada-390.dtsi
new file mode 100644
index 000000000..094e39c66
--- /dev/null
+++ b/arch/arm/boot/dts/armada-390.dtsi
@@ -0,0 +1,57 @@
+/*
+ * Device Tree Include file for Marvell Armada 390 SoC.
+ *
+ * Copyright (C) 2015 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "armada-39x.dtsi"
+
+/ {
+ soc {
+ internal-regs {
+ pinctrl@18000 {
+ compatible = "marvell,mv88f6920-pinctrl";
+ reg = <0x18000 0x20>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-398-db.dts b/arch/arm/boot/dts/armada-398-db.dts
new file mode 100644
index 000000000..bbf83756c
--- /dev/null
+++ b/arch/arm/boot/dts/armada-398-db.dts
@@ -0,0 +1,153 @@
+/*
+ * Device Tree Include file for Marvell Armada 398 Development Board
+ *
+ * Copyright (C) 2015 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "armada-398.dtsi"
+
+/ {
+ model = "Marvell Armada 398 Development Board";
+ compatible = "marvell,a398-db", "marvell,armada398", "marvell,armada390";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000>; /* 2 GB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+
+ internal-regs {
+ spi@10680 {
+ status = "okay";
+ pinctrl-0 = <&spi1_pins>;
+ pinctrl-names = "default";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "n25q128a13";
+ reg = <0>;
+ spi-max-frequency = <108000000>;
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0 0x400000>;
+ };
+
+ partition@400000 {
+ label = "Filesystem";
+ reg = <0x400000 0x1000000>;
+ };
+ };
+ };
+
+ i2c@11000 {
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ serial@12000 {
+ pinctrl-0 = <&uart0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ serial@12100 {
+ pinctrl-0 = <&uart1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ flash@d0000 {
+ status = "okay";
+ pinctrl-0 = <&nand_pins>;
+ pinctrl-names = "default";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+ nand-ecc-strength = <8>;
+ nand-ecc-step-size = <512>;
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0 0x800000>;
+ };
+ partition@800000 {
+ label = "Linux";
+ reg = <0x800000 0x800000>;
+ };
+ partition@1000000 {
+ label = "Filesystem";
+ reg = <0x1000000 0x3f000000>;
+ };
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+
+ pcie@2,0 {
+ status = "okay";
+ };
+
+ pcie@3,0 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-398.dtsi b/arch/arm/boot/dts/armada-398.dtsi
new file mode 100644
index 000000000..fdc25914e
--- /dev/null
+++ b/arch/arm/boot/dts/armada-398.dtsi
@@ -0,0 +1,60 @@
+/*
+ * Device Tree Include file for Marvell Armada 398 SoC.
+ *
+ * Copyright (C) 2015 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "armada-39x.dtsi"
+
+/ {
+ compatible = "marvell,armada398", "marvell,armada390";
+
+ soc {
+ internal-regs {
+ pinctrl@18000 {
+ compatible = "marvell,mv88f6928-pinctrl";
+ reg = <0x18000 0x20>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-39x.dtsi b/arch/arm/boot/dts/armada-39x.dtsi
new file mode 100644
index 000000000..ecd131810
--- /dev/null
+++ b/arch/arm/boot/dts/armada-39x.dtsi
@@ -0,0 +1,508 @@
+/*
+ * Device Tree Include file for Marvell Armada 39x family of SoCs.
+ *
+ * Copyright (C) 2015 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
+
+/ {
+ model = "Marvell Armada 39x family SoC";
+ compatible = "marvell,armada390";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "marvell,armada-390-smp";
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ };
+ };
+
+ soc {
+ compatible = "marvell,armada390-mbus", "marvell,armadaxp-mbus",
+ "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ controller = <&mbusc>;
+ interrupt-parent = <&gic>;
+ pcie-mem-aperture = <0xe0000000 0x8000000>;
+ pcie-io-aperture = <0xe8000000 0x100000>;
+
+ bootrom {
+ compatible = "marvell,bootrom";
+ reg = <MBUS_ID(0x01, 0x1d) 0 0x200000>;
+ };
+
+ internal-regs {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
+
+ L2: cache-controller@8000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x8000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ scu@c000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0xc000 0x100>;
+ };
+
+ timer@c600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xc600 0x20>;
+ interrupts = <GIC_PPI 13 (IRQ_TYPE_EDGE_RISING | GIC_CPU_MASK_SIMPLE(2))>;
+ clocks = <&coreclk 2>;
+ };
+
+ gic: interrupt-controller@d000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #size-cells = <0>;
+ interrupt-controller;
+ reg = <0xd000 0x1000>,
+ <0xc100 0x100>;
+ };
+
+ spi0: spi@10600 {
+ compatible = "marvell,orion-spi";
+ reg = <0x10600 0x50>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ spi1: spi@10680 {
+ compatible = "marvell,orion-spi";
+ reg = <0x10680 0x50>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@11100 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11100 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@11200 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11200 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@11300 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11300 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ uart0: serial@12000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x12000 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ uart1: serial@12100 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x12100 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ uart2: serial@12200 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x12200 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ uart3: serial@12300 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x12300 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ pinctrl@18000 {
+ i2c0_pins: i2c0-pins {
+ marvell,pins = "mpp2", "mpp3";
+ marvell,function = "i2c0";
+ };
+
+ uart0_pins: uart0-pins {
+ marvell,pins = "mpp0", "mpp1";
+ marvell,function = "ua0";
+ };
+
+ uart1_pins: uart1-pins {
+ marvell,pins = "mpp19", "mpp20";
+ marvell,function = "ua1";
+ };
+
+ spi1_pins: spi1-pins {
+ marvell,pins = "mpp56", "mpp57", "mpp58", "mpp59";
+ marvell,function = "spi1";
+ };
+
+ nand_pins: nand-pins {
+ marvell,pins = "mpp22", "mpp34", "mpp23", "mpp33",
+ "mpp38", "mpp28", "mpp40", "mpp42",
+ "mpp35", "mpp36", "mpp25", "mpp30",
+ "mpp32";
+ marvell,function = "dev";
+ };
+ };
+
+ system-controller@18200 {
+ compatible = "marvell,armada-390-system-controller",
+ "marvell,armada-370-xp-system-controller";
+ reg = <0x18200 0x100>;
+ };
+
+ gateclk: clock-gating-control@18220 {
+ compatible = "marvell,armada-390-gating-clock";
+ reg = <0x18220 0x4>;
+ clocks = <&coreclk 0>;
+ #clock-cells = <1>;
+ };
+
+ coreclk: mvebu-sar@18600 {
+ compatible = "marvell,armada-390-core-clock";
+ reg = <0x18600 0x04>;
+ #clock-cells = <1>;
+ };
+
+ mbusc: mbus-controller@20000 {
+ compatible = "marvell,mbus-controller";
+ reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>;
+ };
+
+ mpic: interrupt-controller@20a00 {
+ compatible = "marvell,mpic";
+ reg = <0x20a00 0x2d0>, <0x21070 0x58>;
+ #interrupt-cells = <1>;
+ #size-cells = <1>;
+ interrupt-controller;
+ msi-controller;
+ interrupts = <GIC_PPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ timer@20300 {
+ compatible = "marvell,armada-380-timer",
+ "marvell,armada-xp-timer";
+ reg = <0x20300 0x30>, <0x21040 0x30>;
+ interrupts-extended = <&gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <&gic GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <&gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <&gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <&mpic 5>,
+ <&mpic 6>;
+ clocks = <&coreclk 2>, <&coreclk 5>;
+ clock-names = "nbclk", "fixed";
+ };
+
+ cpurst@20800 {
+ compatible = "marvell,armada-370-cpu-reset";
+ reg = <0x20800 0x10>;
+ };
+
+ pmsu@22000 {
+ compatible = "marvell,armada-390-pmsu",
+ "marvell,armada-380-pmsu";
+ reg = <0x22000 0x1000>;
+ };
+
+ xor@60800 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60800 0x100
+ 0x60a00 0x100>;
+ clocks = <&gateclk 22>;
+ status = "okay";
+
+ xor00 {
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor01 {
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+
+ xor@60900 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60900 0x100
+ 0x60b00 0x100>;
+ clocks = <&gateclk 28>;
+ status = "okay";
+
+ xor10 {
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor11 {
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+
+ flash@d0000 {
+ compatible = "marvell,armada370-nand";
+ reg = <0xd0000 0x54>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&coredivclk 0>;
+ status = "disabled";
+ };
+
+ sdhci@d8000 {
+ compatible = "marvell,armada-380-sdhci";
+ reg = <0xd8000 0x1000>, <0xdc000 0x100>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 17>;
+ mrvl,clk-delay-cycles = <0x1F>;
+ status = "disabled";
+ };
+
+ coredivclk: clock@e4250 {
+ compatible = "marvell,armada-390-corediv-clock",
+ "marvell,armada-380-corediv-clock";
+ reg = <0xe4250 0xc>;
+ #clock-cells = <1>;
+ clocks = <&mainpll>;
+ clock-output-names = "nand";
+ };
+ };
+
+ pcie-controller {
+ compatible = "marvell,armada-370-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ msi-parent = <&mpic>;
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000
+ 0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
+ 0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000
+ 0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000
+ 0x82000000 0x1 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 0 MEM */
+ 0x81000000 0x1 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 0 IO */
+ 0x82000000 0x2 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 1 MEM */
+ 0x81000000 0x2 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 1 IO */
+ 0x82000000 0x3 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 2 MEM */
+ 0x81000000 0x3 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 2 IO */
+ 0x82000000 0x4 0 MBUS_ID(0x04, 0xb8) 0 1 0 /* Port 3 MEM */
+ 0x81000000 0x4 0 MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 3 IO */>;
+
+ /*
+ * This port can be either x4 or x1. When
+ * configured in x4 by the bootloader, then
+ * pcie@4,0 is not available.
+ */
+ pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 8>;
+ status = "disabled";
+ };
+
+ /* x1 port */
+ pcie@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+ 0x81000000 0 0 0x81000000 0x2 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 5>;
+ status = "disabled";
+ };
+
+ /* x1 port */
+ pcie@3,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
+ reg = <0x1800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
+ 0x81000000 0 0 0x81000000 0x3 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ marvell,pcie-port = <2>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 6>;
+ status = "disabled";
+ };
+
+ /*
+ * x1 port only available when pcie@1,0 is
+ * configured as a x1 port
+ */
+ pcie@4,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
+ reg = <0x2000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0
+ 0x81000000 0 0 0x81000000 0x4 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ marvell,pcie-port = <3>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 7>;
+ status = "disabled";
+ };
+ };
+ };
+
+ clocks {
+ /* 2 GHz fixed main PLL */
+ mainpll: mainpll {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1000000000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-xp-axpwifiap.dts b/arch/arm/boot/dts/armada-xp-axpwifiap.dts
new file mode 100644
index 000000000..dfd782b44
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-axpwifiap.dts
@@ -0,0 +1,179 @@
+/*
+ * Device Tree file for Marvell RD-AXPWiFiAP.
+ *
+ * Note: this board is shipped with a new generation boot loader that
+ * remaps internal registers at 0xf1000000. Therefore, if earlyprintk
+ * is used, the CONFIG_DEBUG_MVEBU_UART0_ALTERNATE option or the
+ * CONFIG_DEBUG_MVEBU_UART1_ALTERNATE option should be used.
+ *
+ * Copyright (C) 2013 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "armada-xp-mv78230.dtsi"
+
+/ {
+ model = "Marvell RD-AXPWiFiAP";
+ compatible = "marvell,rd-axpwifiap", "marvell,armadaxp-mv78230", "marvell,armadaxp", "marvell,armada-370-xp";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x00000000 0x00000000 0x40000000>; /* 1GB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+
+ pcie-controller {
+ status = "okay";
+
+ /* First mini-PCIe port */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* Second mini-PCIe port */
+ pcie@2,0 {
+ /* Port 0, Lane 1 */
+ status = "okay";
+ };
+
+ /* Renesas uPD720202 USB 3.0 controller */
+ pcie@3,0 {
+ /* Port 0, Lane 3 */
+ status = "okay";
+ };
+ };
+
+ internal-regs {
+ /* UART0 */
+ serial@12000 {
+ status = "okay";
+ };
+
+ /* UART1 */
+ serial@12100 {
+ status = "okay";
+ };
+
+ sata@a0000 {
+ nr-ports = <1>;
+ status = "okay";
+ };
+
+ mdio {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+
+ ethernet@70000 {
+ pinctrl-0 = <&ge0_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+ ethernet@74000 {
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+
+ spi0: spi@10600 {
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q128a13";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <108000000>;
+ };
+ };
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&keys_pin>;
+ pinctrl-names = "default";
+
+ button@1 {
+ label = "Factory Reset Button";
+ linux,code = <KEY_SETUP>;
+ gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&pinctrl {
+ pinctrl-0 = <&phy_int_pin>;
+ pinctrl-names = "default";
+
+ keys_pin: keys-pin {
+ marvell,pins = "mpp33";
+ marvell,function = "gpio";
+ };
+
+ phy_int_pin: phy-int-pin {
+ marvell,pins = "mpp32";
+ marvell,function = "gpio";
+ };
+};
diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts
new file mode 100644
index 000000000..103782407
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-db.dts
@@ -0,0 +1,232 @@
+/*
+ * Device Tree file for Marvell Armada XP evaluation board
+ * (DB-78460-BP)
+ *
+ * Copyright (C) 2012-2014 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Note: this Device Tree assumes that the bootloader has remapped the
+ * internal registers to 0xf1000000 (instead of the default
+ * 0xd0000000). The 0xf1000000 is the default used by the recent,
+ * DT-capable, U-Boot bootloaders provided by Marvell. Some earlier
+ * boards were delivered with an older version of the bootloader that
+ * left internal registers mapped at 0xd0000000. If you are in this
+ * situation, you should either update your bootloader (preferred
+ * solution) or the below Device Tree should be adjusted.
+ */
+
+/dts-v1/;
+#include "armada-xp-mv78460.dtsi"
+
+/ {
+ model = "Marvell Armada XP Evaluation Board";
+ compatible = "marvell,axp-db", "marvell,armadaxp-mv78460", "marvell,armadaxp", "marvell,armada-370-xp";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x00000000 0 0x80000000>; /* 2 GB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+ MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000>;
+
+ devbus-bootcs {
+ status = "okay";
+
+ /* Device Bus parameters are required */
+
+ /* Read parameters */
+ devbus,bus-width = <16>;
+ devbus,turn-off-ps = <60000>;
+ devbus,badr-skew-ps = <0>;
+ devbus,acc-first-ps = <124000>;
+ devbus,acc-next-ps = <248000>;
+ devbus,rd-setup-ps = <0>;
+ devbus,rd-hold-ps = <0>;
+
+ /* Write parameters */
+ devbus,sync-enable = <0>;
+ devbus,wr-high-ps = <60000>;
+ devbus,wr-low-ps = <60000>;
+ devbus,ale-wr-ps = <60000>;
+
+ /* NOR 16 MiB */
+ nor@0 {
+ compatible = "cfi-flash";
+ reg = <0 0x1000000>;
+ bank-width = <2>;
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+
+ /*
+ * All 6 slots are physically present as
+ * standard PCIe slots on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ pcie@2,0 {
+ /* Port 0, Lane 1 */
+ status = "okay";
+ };
+ pcie@3,0 {
+ /* Port 0, Lane 2 */
+ status = "okay";
+ };
+ pcie@4,0 {
+ /* Port 0, Lane 3 */
+ status = "okay";
+ };
+ pcie@9,0 {
+ /* Port 2, Lane 0 */
+ status = "okay";
+ };
+ pcie@10,0 {
+ /* Port 3, Lane 0 */
+ status = "okay";
+ };
+ };
+
+ internal-regs {
+ serial@12000 {
+ status = "okay";
+ };
+ serial@12100 {
+ status = "okay";
+ };
+ serial@12200 {
+ status = "okay";
+ };
+ serial@12300 {
+ status = "okay";
+ };
+
+ sata@a0000 {
+ nr-ports = <2>;
+ status = "okay";
+ };
+
+ mdio {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ phy2: ethernet-phy@2 {
+ reg = <25>;
+ };
+
+ phy3: ethernet-phy@3 {
+ reg = <27>;
+ };
+ };
+
+ ethernet@70000 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+ ethernet@74000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+ ethernet@30000 {
+ status = "okay";
+ phy = <&phy2>;
+ phy-mode = "sgmii";
+ };
+ ethernet@34000 {
+ status = "okay";
+ phy = <&phy3>;
+ phy-mode = "sgmii";
+ };
+
+ mvsdio@d4000 {
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ /* No CD or WP GPIOs */
+ broken-cd;
+ };
+
+ usb@50000 {
+ status = "okay";
+ };
+
+ usb@51000 {
+ status = "okay";
+ };
+
+ usb@52000 {
+ status = "okay";
+ };
+
+ spi0: spi@10600 {
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p64";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <20000000>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts
new file mode 100644
index 000000000..565227eac
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
@@ -0,0 +1,245 @@
+/*
+ * Device Tree file for Marvell Armada XP development board
+ * (DB-MV784MP-GP)
+ *
+ * Copyright (C) 2013-2014 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Note: this Device Tree assumes that the bootloader has remapped the
+ * internal registers to 0xf1000000 (instead of the default
+ * 0xd0000000). The 0xf1000000 is the default used by the recent,
+ * DT-capable, U-Boot bootloaders provided by Marvell. Some earlier
+ * boards were delivered with an older version of the bootloader that
+ * left internal registers mapped at 0xd0000000. If you are in this
+ * situation, you should either update your bootloader (preferred
+ * solution) or the below Device Tree should be adjusted.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include "armada-xp-mv78460.dtsi"
+
+/ {
+ model = "Marvell Armada XP Development Board DB-MV784MP-GP";
+ compatible = "marvell,axp-gp", "marvell,armadaxp-mv78460", "marvell,armadaxp", "marvell,armada-370-xp";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ /*
+ * 8 GB of plug-in RAM modules by default.The amount
+ * of memory available can be changed by the
+ * bootloader according the size of the module
+ * actually plugged. However, memory between
+ * 0xF0000000 to 0xFFFFFFFF cannot be used, as it is
+ * the address range used for I/O (internal registers,
+ * MBus windows).
+ */
+ reg = <0x00000000 0x00000000 0x00000000 0xf0000000>,
+ <0x00000001 0x00000000 0x00000001 0x00000000>;
+ };
+
+ cpus {
+ pm_pic {
+ ctrl-gpios = <&gpio0 16 GPIO_ACTIVE_LOW>,
+ <&gpio0 17 GPIO_ACTIVE_LOW>,
+ <&gpio0 18 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+ MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000>;
+
+ devbus-bootcs {
+ status = "okay";
+
+ /* Device Bus parameters are required */
+
+ /* Read parameters */
+ devbus,bus-width = <16>;
+ devbus,turn-off-ps = <60000>;
+ devbus,badr-skew-ps = <0>;
+ devbus,acc-first-ps = <124000>;
+ devbus,acc-next-ps = <248000>;
+ devbus,rd-setup-ps = <0>;
+ devbus,rd-hold-ps = <0>;
+
+ /* Write parameters */
+ devbus,sync-enable = <0>;
+ devbus,wr-high-ps = <60000>;
+ devbus,wr-low-ps = <60000>;
+ devbus,ale-wr-ps = <60000>;
+
+ /* NOR 16 MiB */
+ nor@0 {
+ compatible = "cfi-flash";
+ reg = <0 0x1000000>;
+ bank-width = <2>;
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+
+ /*
+ * The 3 slots are physically present as
+ * standard PCIe slots on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ pcie@9,0 {
+ /* Port 2, Lane 0 */
+ status = "okay";
+ };
+ pcie@10,0 {
+ /* Port 3, Lane 0 */
+ status = "okay";
+ };
+ };
+
+ internal-regs {
+ serial@12000 {
+ status = "okay";
+ };
+ serial@12100 {
+ status = "okay";
+ };
+ serial@12200 {
+ status = "okay";
+ };
+ serial@12300 {
+ status = "okay";
+ };
+ pinctrl {
+ pinctrl-0 = <&pic_pins>;
+ pinctrl-names = "default";
+ pic_pins: pic-pins-0 {
+ marvell,pins = "mpp16", "mpp17",
+ "mpp18";
+ marvell,function = "gpio";
+ };
+ };
+ sata@a0000 {
+ nr-ports = <2>;
+ status = "okay";
+ };
+
+ mdio {
+ phy0: ethernet-phy@0 {
+ reg = <16>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <17>;
+ };
+
+ phy2: ethernet-phy@2 {
+ reg = <18>;
+ };
+
+ phy3: ethernet-phy@3 {
+ reg = <19>;
+ };
+ };
+
+ ethernet@70000 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "qsgmii";
+ };
+ ethernet@74000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "qsgmii";
+ };
+ ethernet@30000 {
+ status = "okay";
+ phy = <&phy2>;
+ phy-mode = "qsgmii";
+ };
+ ethernet@34000 {
+ status = "okay";
+ phy = <&phy3>;
+ phy-mode = "qsgmii";
+ };
+
+ /* Front-side USB slot */
+ usb@50000 {
+ status = "okay";
+ };
+
+ /* Back-side USB slot */
+ usb@51000 {
+ status = "okay";
+ };
+
+ spi0: spi@10600 {
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q128a13";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <108000000>;
+ };
+ };
+
+ nand@d0000 {
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
new file mode 100644
index 000000000..06a6a6c1f
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
@@ -0,0 +1,325 @@
+/*
+ * Device Tree file for Lenovo Iomega ix4-300d
+ *
+ * Copyright (C) 2014, Benoit Masson <yahoo@perenite.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "armada-xp-mv78230.dtsi"
+
+/ {
+ model = "Lenovo Iomega ix4-300d";
+ compatible = "lenovo,ix4-300d", "marvell,armadaxp-mv78230",
+ "marvell,armadaxp", "marvell,armada-370-xp";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x00000000 0 0x20000000>; /* 512MB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+
+ pcie-controller {
+ status = "okay";
+
+ /* Quad port sata: Marvell 88SX7042 */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* USB 3.0 xHCI controller: NEC D720200F1 */
+ pcie@5,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+ };
+
+ internal-regs {
+ serial@12000 {
+ status = "okay";
+ };
+
+ mdio {
+ phy0: ethernet-phy@0 { /* Marvell 88E1318 */
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 { /* Marvell 88E1318 */
+ reg = <1>;
+ };
+ };
+
+ ethernet@70000 {
+ pinctrl-0 = <&ge0_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+
+ ethernet@74000 {
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+
+ usb@50000 {
+ status = "okay";
+ };
+
+ usb@51000 {
+ status = "okay";
+ };
+
+ i2c@11000 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ adt7473@2e {
+ compatible = "adi,adt7473";
+ reg = <0x2e>;
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c64";
+ reg = <0x50>;
+ };
+
+ pcf8563@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+
+ };
+
+ nand@d0000 {
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0xe0000>;
+ read-only;
+ };
+
+ partition@e0000 {
+ label = "u-boot-env";
+ reg = <0xe0000 0x20000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "u-boot-env2";
+ reg = <0x100000 0x20000>;
+ read-only;
+ };
+
+ partition@120000 {
+ label = "zImage";
+ reg = <0x120000 0x400000>;
+ };
+
+ partition@520000 {
+ label = "initrd";
+ reg = <0x520000 0x400000>;
+ };
+
+ partition@xE00000 {
+ label = "boot";
+ reg = <0xE00000 0x3F200000>;
+ };
+
+ partition@flash {
+ label = "flash";
+ reg = <0x0 0x40000000>;
+ };
+ };
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&power_button_pin &reset_button_pin
+ &select_button_pin &scroll_button_pin>;
+ pinctrl-names = "default";
+
+ power-button {
+ label = "Power Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ };
+
+ reset-button {
+ label = "Reset Button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+ };
+
+ select-button {
+ label = "Select Button";
+ linux,code = <BTN_SELECT>;
+ gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ };
+
+ scroll-button {
+ label = "Scroll Button";
+ linux,code = <KEY_SCROLLDOWN>;
+ gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ spi3 {
+ compatible = "spi-gpio";
+ status = "okay";
+ gpio-sck = <&gpio0 25 GPIO_ACTIVE_LOW>;
+ gpio-mosi = <&gpio1 15 GPIO_ACTIVE_LOW>; /*gpio 47*/
+ cs-gpios = <&gpio0 27 GPIO_ACTIVE_LOW>;
+ num-chipselects = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio_spi: gpio_spi@0 {
+ compatible = "fairchild,74hc595";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0>;
+ registers-number = <1>;
+ spi-max-frequency = <100000>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&hdd_led_pin>;
+ pinctrl-names = "default";
+
+ hdd-led {
+ label = "ix4-300d:hdd:blue";
+ gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ power-led {
+ label = "ix4-300d:power:white";
+ gpios = <&gpio_spi 1 GPIO_ACTIVE_LOW>;
+ /* init blinking while booting */
+ linux,default-trigger = "timer";
+ default-state = "on";
+ };
+
+ sysfail-led {
+ label = "ix4-300d:sysfail:red";
+ gpios = <&gpio_spi 2 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ sys-led {
+ label = "ix4-300d:sys:blue";
+ gpios = <&gpio_spi 3 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ hddfail-led {
+ label = "ix4-300d:hddfail:red";
+ gpios = <&gpio_spi 4 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ };
+
+ /*
+ * Warning: you need both eth1 & 0 PHY initialized (i.e having
+ * them up does the tweak) for poweroff to shutdown otherwise it
+ * reboots
+ */
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ pinctrl-0 = <&poweroff_pin>;
+ pinctrl-names = "default";
+ gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&pinctrl {
+ poweroff_pin: poweroff-pin {
+ marvell,pins = "mpp24";
+ marvell,function = "gpio";
+ };
+
+ power_button_pin: power-button-pin {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+
+ reset_button_pin: reset-button-pin {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+ select_button_pin: select-button-pin {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+
+ scroll_button_pin: scroll-button-pin {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+
+ hdd_led_pin: hdd-led-pin {
+ marvell,pins = "mpp26";
+ marvell,function = "gpio";
+ };
+};
diff --git a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
new file mode 100644
index 000000000..fdd187c55
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
@@ -0,0 +1,398 @@
+/*
+ * Device Tree file for the Linksys WRT1900AC (Mamba).
+ *
+ * Note: this board is shipped with a new generation boot loader that
+ * remaps internal registers at 0xf1000000. Therefore, if earlyprintk
+ * is used, the CONFIG_DEBUG_MVEBU_UART0_ALTERNATE option should be
+ * used.
+ *
+ * Copyright (C) 2014 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Based on armada-xp-axpwifiap.dts:
+ *
+ * Copyright (C) 2013 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "armada-xp-mv78230.dtsi"
+
+/ {
+ model = "Linksys WRT1900AC";
+ compatible = "linksys,mamba", "marvell,armadaxp-mv78230",
+ "marvell,armadaxp", "marvell,armada-370-xp";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ stdout-path = &uart0;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x00000000 0x00000000 0x10000000>; /* 256MB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+
+ pcie-controller {
+ status = "okay";
+
+ /* Etron EJ168 USB 3.0 controller */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* First mini-PCIe port */
+ pcie@2,0 {
+ /* Port 0, Lane 1 */
+ status = "okay";
+ };
+
+ /* Second mini-PCIe port */
+ pcie@3,0 {
+ /* Port 0, Lane 3 */
+ status = "okay";
+ };
+ };
+
+ internal-regs {
+
+ rtc@10300 {
+ /* No crystal connected to the internal RTC */
+ status = "disabled";
+ };
+
+ /* J10: VCC, NC, RX, NC, TX, GND */
+ serial@12000 {
+ status = "okay";
+ };
+
+ sata@a0000 {
+ nr-ports = <1>;
+ status = "okay";
+ };
+
+ ethernet@70000 {
+ pinctrl-0 = <&ge0_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy-mode = "rgmii-id";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+
+ ethernet@74000 {
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy-mode = "rgmii-id";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+
+ /* USB part of the eSATA/USB 2.0 port */
+ usb@50000 {
+ status = "okay";
+ };
+
+ i2c@11000 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ tmp421@4c {
+ compatible = "ti,tmp421";
+ reg = <0x4c>;
+ };
+
+ tlc59116@68 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #gpio-cells = <2>;
+ compatible = "ti,tlc59116";
+ reg = <0x68>;
+
+ wan_amber@0 {
+ label = "mamba:amber:wan";
+ reg = <0x0>;
+ };
+
+ wan_white@1 {
+ label = "mamba:white:wan";
+ reg = <0x1>;
+ };
+
+ wlan_2g@2 {
+ label = "mamba:white:wlan_2g";
+ reg = <0x2>;
+ };
+
+ wlan_5g@3 {
+ label = "mamba:white:wlan_5g";
+ reg = <0x3>;
+ };
+
+ esata@4 {
+ label = "mamba:white:esata";
+ reg = <0x4>;
+ };
+
+ usb2@5 {
+ label = "mamba:white:usb2";
+ reg = <0x5>;
+ };
+
+ usb3_1@6 {
+ label = "mamba:white:usb3_1";
+ reg = <0x6>;
+ };
+
+ usb3_2@7 {
+ label = "mamba:white:usb3_2";
+ reg = <0x7>;
+ };
+
+ wps_white@8 {
+ label = "mamba:white:wps";
+ reg = <0x8>;
+ };
+
+ wps_amber@9 {
+ label = "mamba:amber:wps";
+ reg = <0x9>;
+ };
+ };
+ };
+
+ nand@d0000 {
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x100000>; /* 1MB */
+ read-only;
+ };
+
+ partition@100000 {
+ label = "u_env";
+ reg = <0x100000 0x40000>; /* 256KB */
+ };
+
+ partition@140000 {
+ label = "s_env";
+ reg = <0x140000 0x40000>; /* 256KB */
+ };
+
+ partition@900000 {
+ label = "devinfo";
+ reg = <0x900000 0x100000>; /* 1MB */
+ read-only;
+ };
+
+ /* kernel1 overlaps with rootfs1 by design */
+ partition@a00000 {
+ label = "kernel1";
+ reg = <0xa00000 0x2800000>; /* 40MB */
+ };
+
+ partition@d00000 {
+ label = "rootfs1";
+ reg = <0xd00000 0x2500000>; /* 37MB */
+ };
+
+ /* kernel2 overlaps with rootfs2 by design */
+ partition@3200000 {
+ label = "kernel2";
+ reg = <0x3200000 0x2800000>; /* 40MB */
+ };
+
+ partition@3500000 {
+ label = "rootfs2";
+ reg = <0x3500000 0x2500000>; /* 37MB */
+ };
+
+ /*
+ * 38MB, last MB is for the BBT, not writable
+ */
+ partition@5a00000 {
+ label = "syscfg";
+ reg = <0x5a00000 0x2600000>;
+ };
+
+ /*
+ * Unused area between "s_env" and "devinfo".
+ * Moved here because otherwise the renumbered
+ * partitions would break the bootloader
+ * supplied bootargs
+ */
+ partition@180000 {
+ label = "unused_area";
+ reg = <0x180000 0x780000>; /* 7.5MB */
+ };
+ };
+
+ spi0: spi@10600 {
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "everspin,mr25h256";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <40000000>;
+ };
+ };
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&keys_pin>;
+ pinctrl-names = "default";
+
+ button@1 {
+ label = "WPS";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ button@2 {
+ label = "Factory Reset Button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&power_led_pin>;
+ pinctrl-names = "default";
+
+ power {
+ label = "mamba:white:power";
+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ gpio_fan {
+ /* SUNON HA4010V4-0000-C99 */
+ compatible = "gpio-fan";
+ gpios = <&gpio0 24 0>;
+
+ gpio-fan,speed-map = <0 0
+ 4500 1>;
+ };
+
+ dsa@0 {
+ compatible = "marvell,dsa";
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ dsa,ethernet = <&eth0>;
+ dsa,mii-bus = <&mdio>;
+
+ switch@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0>; /* MDIO address 0, switch 0 in tree */
+
+ port@0 {
+ reg = <0>;
+ label = "lan4";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan3";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan2";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan1";
+ };
+
+ port@4 {
+ reg = <4>;
+ label = "internet";
+ };
+
+ port@5 {
+ reg = <5>;
+ label = "cpu";
+ };
+ };
+ };
+};
+
+&pinctrl {
+
+ keys_pin: keys-pin {
+ marvell,pins = "mpp32", "mpp33";
+ marvell,function = "gpio";
+ };
+
+ power_led_pin: power-led-pin {
+ marvell,pins = "mpp40";
+ marvell,function = "gpio";
+ };
+
+ gpio_fan_pin: gpio-fan-pin {
+ marvell,pins = "mpp24";
+ marvell,function = "gpio";
+ };
+};
diff --git a/arch/arm/boot/dts/armada-xp-matrix.dts b/arch/arm/boot/dts/armada-xp-matrix.dts
new file mode 100644
index 000000000..f894bc83e
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-matrix.dts
@@ -0,0 +1,114 @@
+/*
+ * Device Tree file for Marvell Armada XP Matrix board
+ *
+ * Copyright (C) 2013 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "armada-xp-mv78460.dtsi"
+
+/ {
+ model = "Marvell Armada XP Matrix Board";
+ compatible = "marvell,axp-matrix", "marvell,armadaxp-mv78460", "marvell,armadaxp", "marvell,armada-370-xp";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ /*
+ * This board has 4 GB of RAM, but the last 256 MB of
+ * RAM are not usable due to the overlap with the MBus
+ * Window address range
+ */
+ reg = <0 0x00000000 0 0xf0000000>;
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+
+ internal-regs {
+ serial@12000 {
+ status = "okay";
+ };
+ serial@12100 {
+ status = "okay";
+ };
+ serial@12200 {
+ status = "okay";
+ };
+ serial@12300 {
+ status = "okay";
+ };
+
+ sata@a0000 {
+ nr-ports = <2>;
+ status = "okay";
+ };
+
+ ethernet@30000 {
+ status = "okay";
+ phy-mode = "sgmii";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ };
+
+ usb@50000 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
new file mode 100644
index 000000000..6e6d0f04b
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
@@ -0,0 +1,231 @@
+/*
+ * Device Tree Include file for Marvell Armada XP family SoC
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contains definitions specific to the Armada XP MV78230 SoC that are not
+ * common to all Armada XP SoCs.
+ */
+
+#include "armada-xp.dtsi"
+
+/ {
+ model = "Marvell Armada XP MV78230 SoC";
+ compatible = "marvell,armadaxp-mv78230", "marvell,armadaxp", "marvell,armada-370-xp";
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "marvell,armada-xp-smp";
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <0>;
+ clocks = <&cpuclk 0>;
+ clock-latency = <1000000>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <1>;
+ clocks = <&cpuclk 1>;
+ clock-latency = <1000000>;
+ };
+ };
+
+ soc {
+ /*
+ * MV78230 has 2 PCIe units Gen2.0: One unit can be
+ * configured as x4 or quad x1 lanes. One unit is
+ * x1 only.
+ */
+ pcie-controller {
+ compatible = "marvell,armada-xp-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ msi-parent = <&mpic>;
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */
+ 0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000 /* Port 0.1 registers */
+ 0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000 /* Port 0.2 registers */
+ 0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000 /* Port 0.3 registers */
+ 0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000 /* Port 1.0 registers */
+ 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
+ 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */
+ 0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */
+ 0x81000000 0x2 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 0.1 IO */
+ 0x82000000 0x3 0 MBUS_ID(0x04, 0xb8) 0 1 0 /* Port 0.2 MEM */
+ 0x81000000 0x3 0 MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO */
+ 0x82000000 0x4 0 MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */
+ 0x81000000 0x4 0 MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO */
+ 0x82000000 0x5 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
+ 0x81000000 0x5 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */>;
+
+ pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 58>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 5>;
+ status = "disabled";
+ };
+
+ pcie@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+ 0x81000000 0 0 0x81000000 0x2 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 59>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <1>;
+ clocks = <&gateclk 6>;
+ status = "disabled";
+ };
+
+ pcie@3,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
+ reg = <0x1800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
+ 0x81000000 0 0 0x81000000 0x3 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 60>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <2>;
+ clocks = <&gateclk 7>;
+ status = "disabled";
+ };
+
+ pcie@4,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>;
+ reg = <0x2000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0
+ 0x81000000 0 0 0x81000000 0x4 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 61>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <3>;
+ clocks = <&gateclk 8>;
+ status = "disabled";
+ };
+
+ pcie@5,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
+ reg = <0x2800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0
+ 0x81000000 0 0 0x81000000 0x5 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 62>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 9>;
+ status = "disabled";
+ };
+ };
+
+ internal-regs {
+ gpio0: gpio@18100 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18100 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <82>, <83>, <84>, <85>;
+ };
+
+ gpio1: gpio@18140 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18140 0x40>;
+ ngpios = <17>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <87>, <88>, <89>;
+ };
+ };
+ };
+};
+
+&pinctrl {
+ compatible = "marvell,mv78230-pinctrl";
+};
diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
new file mode 100644
index 000000000..c5fdc99f0
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
@@ -0,0 +1,333 @@
+/*
+ * Device Tree Include file for Marvell Armada XP family SoC
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contains definitions specific to the Armada XP MV78260 SoC that are not
+ * common to all Armada XP SoCs.
+ */
+
+#include "armada-xp.dtsi"
+
+/ {
+ model = "Marvell Armada XP MV78260 SoC";
+ compatible = "marvell,armadaxp-mv78260", "marvell,armadaxp", "marvell,armada-370-xp";
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "marvell,armada-xp-smp";
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <0>;
+ clocks = <&cpuclk 0>;
+ clock-latency = <1000000>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <1>;
+ clocks = <&cpuclk 1>;
+ clock-latency = <1000000>;
+ };
+ };
+
+ soc {
+ /*
+ * MV78260 has 3 PCIe units Gen2.0: Two units can be
+ * configured as x4 or quad x1 lanes. One unit is
+ * x4 only.
+ */
+ pcie-controller {
+ compatible = "marvell,armada-xp-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ msi-parent = <&mpic>;
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */
+ 0x82000000 0 0x42000 MBUS_ID(0xf0, 0x01) 0x42000 0 0x00002000 /* Port 2.0 registers */
+ 0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000 /* Port 0.1 registers */
+ 0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000 /* Port 0.2 registers */
+ 0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000 /* Port 0.3 registers */
+ 0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000 /* Port 1.0 registers */
+ 0x82000000 0 0x84000 MBUS_ID(0xf0, 0x01) 0x84000 0 0x00002000 /* Port 1.1 registers */
+ 0x82000000 0 0x88000 MBUS_ID(0xf0, 0x01) 0x88000 0 0x00002000 /* Port 1.2 registers */
+ 0x82000000 0 0x8c000 MBUS_ID(0xf0, 0x01) 0x8c000 0 0x00002000 /* Port 1.3 registers */
+ 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
+ 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */
+ 0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */
+ 0x81000000 0x2 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 0.1 IO */
+ 0x82000000 0x3 0 MBUS_ID(0x04, 0xb8) 0 1 0 /* Port 0.2 MEM */
+ 0x81000000 0x3 0 MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO */
+ 0x82000000 0x4 0 MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */
+ 0x81000000 0x4 0 MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO */
+
+ 0x82000000 0x5 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
+ 0x81000000 0x5 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */
+ 0x82000000 0x6 0 MBUS_ID(0x08, 0xd8) 0 1 0 /* Port 1.1 MEM */
+ 0x81000000 0x6 0 MBUS_ID(0x08, 0xd0) 0 1 0 /* Port 1.1 IO */
+ 0x82000000 0x7 0 MBUS_ID(0x08, 0xb8) 0 1 0 /* Port 1.2 MEM */
+ 0x81000000 0x7 0 MBUS_ID(0x08, 0xb0) 0 1 0 /* Port 1.2 IO */
+ 0x82000000 0x8 0 MBUS_ID(0x08, 0x78) 0 1 0 /* Port 1.3 MEM */
+ 0x81000000 0x8 0 MBUS_ID(0x08, 0x70) 0 1 0 /* Port 1.3 IO */
+
+ 0x82000000 0x9 0 MBUS_ID(0x04, 0xf8) 0 1 0 /* Port 2.0 MEM */
+ 0x81000000 0x9 0 MBUS_ID(0x04, 0xf0) 0 1 0 /* Port 2.0 IO */>;
+
+ pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 58>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 5>;
+ status = "disabled";
+ };
+
+ pcie@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+ 0x81000000 0 0 0x81000000 0x2 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 59>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <1>;
+ clocks = <&gateclk 6>;
+ status = "disabled";
+ };
+
+ pcie@3,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
+ reg = <0x1800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
+ 0x81000000 0 0 0x81000000 0x3 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 60>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <2>;
+ clocks = <&gateclk 7>;
+ status = "disabled";
+ };
+
+ pcie@4,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>;
+ reg = <0x2000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0
+ 0x81000000 0 0 0x81000000 0x4 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 61>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <3>;
+ clocks = <&gateclk 8>;
+ status = "disabled";
+ };
+
+ pcie@5,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
+ reg = <0x2800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0
+ 0x81000000 0 0 0x81000000 0x5 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 62>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 9>;
+ status = "disabled";
+ };
+
+ pcie@6,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x84000 0 0x2000>;
+ reg = <0x3000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x6 0 1 0
+ 0x81000000 0 0 0x81000000 0x6 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 63>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <1>;
+ clocks = <&gateclk 10>;
+ status = "disabled";
+ };
+
+ pcie@7,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x88000 0 0x2000>;
+ reg = <0x3800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x7 0 1 0
+ 0x81000000 0 0 0x81000000 0x7 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 64>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <2>;
+ clocks = <&gateclk 11>;
+ status = "disabled";
+ };
+
+ pcie@8,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x8c000 0 0x2000>;
+ reg = <0x4000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x8 0 1 0
+ 0x81000000 0 0 0x81000000 0x8 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 65>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <3>;
+ clocks = <&gateclk 12>;
+ status = "disabled";
+ };
+
+ pcie@9,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
+ reg = <0x4800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0
+ 0x81000000 0 0 0x81000000 0x9 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 99>;
+ marvell,pcie-port = <2>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 26>;
+ status = "disabled";
+ };
+ };
+
+ internal-regs {
+ gpio0: gpio@18100 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18100 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <82>, <83>, <84>, <85>;
+ };
+
+ gpio1: gpio@18140 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18140 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <87>, <88>, <89>, <90>;
+ };
+
+ gpio2: gpio@18180 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18180 0x40>;
+ ngpios = <3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <91>;
+ };
+
+ eth3: ethernet@34000 {
+ compatible = "marvell,armada-xp-neta";
+ reg = <0x34000 0x4000>;
+ interrupts = <14>;
+ clocks = <&gateclk 1>;
+ status = "disabled";
+ };
+ };
+ };
+};
+
+&pinctrl {
+ compatible = "marvell,mv78260-pinctrl";
+};
diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
new file mode 100644
index 000000000..0e24f1a38
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
@@ -0,0 +1,371 @@
+/*
+ * Device Tree Include file for Marvell Armada XP family SoC
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contains definitions specific to the Armada XP MV78460 SoC that are not
+ * common to all Armada XP SoCs.
+ */
+
+#include "armada-xp.dtsi"
+
+/ {
+ model = "Marvell Armada XP MV78460 SoC";
+ compatible = "marvell,armadaxp-mv78460", "marvell,armadaxp", "marvell,armada-370-xp";
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ };
+
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "marvell,armada-xp-smp";
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <0>;
+ clocks = <&cpuclk 0>;
+ clock-latency = <1000000>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <1>;
+ clocks = <&cpuclk 1>;
+ clock-latency = <1000000>;
+ };
+
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <2>;
+ clocks = <&cpuclk 2>;
+ clock-latency = <1000000>;
+ };
+
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <3>;
+ clocks = <&cpuclk 3>;
+ clock-latency = <1000000>;
+ };
+ };
+
+ soc {
+ /*
+ * MV78460 has 4 PCIe units Gen2.0: Two units can be
+ * configured as x4 or quad x1 lanes. Two units are
+ * x4/x1.
+ */
+ pcie-controller {
+ compatible = "marvell,armada-xp-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ msi-parent = <&mpic>;
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */
+ 0x82000000 0 0x42000 MBUS_ID(0xf0, 0x01) 0x42000 0 0x00002000 /* Port 2.0 registers */
+ 0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000 /* Port 0.1 registers */
+ 0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000 /* Port 0.2 registers */
+ 0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000 /* Port 0.3 registers */
+ 0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000 /* Port 1.0 registers */
+ 0x82000000 0 0x82000 MBUS_ID(0xf0, 0x01) 0x82000 0 0x00002000 /* Port 3.0 registers */
+ 0x82000000 0 0x84000 MBUS_ID(0xf0, 0x01) 0x84000 0 0x00002000 /* Port 1.1 registers */
+ 0x82000000 0 0x88000 MBUS_ID(0xf0, 0x01) 0x88000 0 0x00002000 /* Port 1.2 registers */
+ 0x82000000 0 0x8c000 MBUS_ID(0xf0, 0x01) 0x8c000 0 0x00002000 /* Port 1.3 registers */
+ 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
+ 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */
+ 0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */
+ 0x81000000 0x2 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 0.1 IO */
+ 0x82000000 0x3 0 MBUS_ID(0x04, 0xb8) 0 1 0 /* Port 0.2 MEM */
+ 0x81000000 0x3 0 MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO */
+ 0x82000000 0x4 0 MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */
+ 0x81000000 0x4 0 MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO */
+
+ 0x82000000 0x5 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
+ 0x81000000 0x5 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */
+ 0x82000000 0x6 0 MBUS_ID(0x08, 0xd8) 0 1 0 /* Port 1.1 MEM */
+ 0x81000000 0x6 0 MBUS_ID(0x08, 0xd0) 0 1 0 /* Port 1.1 IO */
+ 0x82000000 0x7 0 MBUS_ID(0x08, 0xb8) 0 1 0 /* Port 1.2 MEM */
+ 0x81000000 0x7 0 MBUS_ID(0x08, 0xb0) 0 1 0 /* Port 1.2 IO */
+ 0x82000000 0x8 0 MBUS_ID(0x08, 0x78) 0 1 0 /* Port 1.3 MEM */
+ 0x81000000 0x8 0 MBUS_ID(0x08, 0x70) 0 1 0 /* Port 1.3 IO */
+
+ 0x82000000 0x9 0 MBUS_ID(0x04, 0xf8) 0 1 0 /* Port 2.0 MEM */
+ 0x81000000 0x9 0 MBUS_ID(0x04, 0xf0) 0 1 0 /* Port 2.0 IO */
+
+ 0x82000000 0xa 0 MBUS_ID(0x08, 0xf8) 0 1 0 /* Port 3.0 MEM */
+ 0x81000000 0xa 0 MBUS_ID(0x08, 0xf0) 0 1 0 /* Port 3.0 IO */>;
+
+ pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 58>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 5>;
+ status = "disabled";
+ };
+
+ pcie@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82001000 0 0x44000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+ 0x81000000 0 0 0x81000000 0x2 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 59>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <1>;
+ clocks = <&gateclk 6>;
+ status = "disabled";
+ };
+
+ pcie@3,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82001800 0 0x48000 0 0x2000>;
+ reg = <0x1800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
+ 0x81000000 0 0 0x81000000 0x3 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 60>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <2>;
+ clocks = <&gateclk 7>;
+ status = "disabled";
+ };
+
+ pcie@4,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>;
+ reg = <0x2000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0
+ 0x81000000 0 0 0x81000000 0x4 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 61>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <3>;
+ clocks = <&gateclk 8>;
+ status = "disabled";
+ };
+
+ pcie@5,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
+ reg = <0x2800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0
+ 0x81000000 0 0 0x81000000 0x5 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 62>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 9>;
+ status = "disabled";
+ };
+
+ pcie@6,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82003000 0 0x84000 0 0x2000>;
+ reg = <0x3000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x6 0 1 0
+ 0x81000000 0 0 0x81000000 0x6 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 63>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <1>;
+ clocks = <&gateclk 10>;
+ status = "disabled";
+ };
+
+ pcie@7,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82003800 0 0x88000 0 0x2000>;
+ reg = <0x3800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x7 0 1 0
+ 0x81000000 0 0 0x81000000 0x7 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 64>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <2>;
+ clocks = <&gateclk 11>;
+ status = "disabled";
+ };
+
+ pcie@8,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82004000 0 0x8c000 0 0x2000>;
+ reg = <0x4000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x8 0 1 0
+ 0x81000000 0 0 0x81000000 0x8 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 65>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <3>;
+ clocks = <&gateclk 12>;
+ status = "disabled";
+ };
+
+ pcie@9,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82004800 0 0x42000 0 0x2000>;
+ reg = <0x4800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0
+ 0x81000000 0 0 0x81000000 0x9 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 99>;
+ marvell,pcie-port = <2>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 26>;
+ status = "disabled";
+ };
+
+ pcie@10,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82005000 0 0x82000 0 0x2000>;
+ reg = <0x5000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0xa 0 1 0
+ 0x81000000 0 0 0x81000000 0xa 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 103>;
+ marvell,pcie-port = <3>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 27>;
+ status = "disabled";
+ };
+ };
+
+ internal-regs {
+ gpio0: gpio@18100 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18100 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <82>, <83>, <84>, <85>;
+ };
+
+ gpio1: gpio@18140 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18140 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <87>, <88>, <89>, <90>;
+ };
+
+ gpio2: gpio@18180 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18180 0x40>;
+ ngpios = <3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <91>;
+ };
+
+ eth3: ethernet@34000 {
+ compatible = "marvell,armada-xp-neta";
+ reg = <0x34000 0x4000>;
+ interrupts = <14>;
+ clocks = <&gateclk 1>;
+ status = "disabled";
+ };
+ };
+ };
+};
+
+&pinctrl {
+ compatible = "marvell,mv78460-pinctrl";
+};
diff --git a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
new file mode 100644
index 000000000..1516fc262
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
@@ -0,0 +1,370 @@
+/*
+ * Device Tree file for NETGEAR ReadyNAS 2120
+ *
+ * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "armada-xp-mv78230.dtsi"
+
+/ {
+ model = "NETGEAR ReadyNAS 2120";
+ compatible = "netgear,readynas-2120", "marvell,armadaxp-mv78230", "marvell,armadaxp", "marvell,armada-370-xp";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x00000000 0 0x80000000>; /* 2GB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+
+ pcie-controller {
+ status = "okay";
+
+ /* Connected to first Marvell 88SE9170 SATA controller */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* Connected to second Marvell 88SE9170 SATA controller */
+ pcie@2,0 {
+ /* Port 0, Lane 1 */
+ status = "okay";
+ };
+
+ /* Connected to Fresco Logic FL1009 USB 3.0 controller */
+ pcie@5,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+ };
+
+ internal-regs {
+ /* Two rear eSATA ports */
+ sata@a0000 {
+ nr-ports = <2>;
+ status = "okay";
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ mdio {
+ phy0: ethernet-phy@0 { /* Marvell 88E1318 */
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 { /* Marvell 88E1318 */
+ reg = <1>;
+ };
+ };
+
+ ethernet@70000 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+
+ ethernet@74000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+
+ /* Front USB 2.0 port */
+ usb@50000 {
+ status = "okay";
+ };
+
+ i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ clock-frequency = <400000>;
+ status = "okay";
+
+ isl12057: isl12057@68 {
+ compatible = "isil,isl12057";
+ reg = <0x68>;
+ isil,irq2-can-wakeup-machine;
+ };
+
+ /* Controller for rear fan #1 of 3 (Protechnic
+ * MGT4012XB-O20, 8000RPM) near eSATA port */
+ g762_fan1: g762@3e {
+ compatible = "gmt,g762";
+ reg = <0x3e>;
+ clocks = <&g762_clk>; /* input clock */
+ fan_gear_mode = <0>;
+ fan_startv = <1>;
+ pwm_polarity = <0>;
+ };
+
+ /* Controller for rear (center) fan #2 of 3 */
+ g762_fan2: g762@48 {
+ compatible = "gmt,g762";
+ reg = <0x48>;
+ clocks = <&g762_clk>; /* input clock */
+ fan_gear_mode = <0>;
+ fan_startv = <1>;
+ pwm_polarity = <0>;
+ };
+
+ /* Controller for rear fan #3 of 3 */
+ g762_fan3: g762@49 {
+ compatible = "gmt,g762";
+ reg = <0x49>;
+ clocks = <&g762_clk>; /* input clock */
+ fan_gear_mode = <0>;
+ fan_startv = <1>;
+ pwm_polarity = <0>;
+ };
+
+ /* Temperature sensor */
+ g751: g751@4c {
+ compatible = "gmt,g751";
+ reg = <0x4c>;
+ };
+ };
+
+ nand@d0000 {
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+
+ /* Use Hardware BCH ECC */
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x180000>; /* 1.5MB */
+ read-only;
+ };
+
+ partition@180000 {
+ label = "u-boot-env";
+ reg = <0x180000 0x20000>; /* 128KB */
+ read-only;
+ };
+
+ partition@200000 {
+ label = "uImage";
+ reg = <0x0200000 0x600000>; /* 6MB */
+ };
+
+ partition@800000 {
+ label = "minirootfs";
+ reg = <0x0800000 0x400000>; /* 4MB */
+ };
+
+ /* Last MB is for the BBT, i.e. not writable */
+ partition@c00000 {
+ label = "ubifs";
+ reg = <0x0c00000 0x7400000>; /* 116MB */
+ };
+ };
+ };
+ };
+
+ clocks {
+ g762_clk: g762-oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&sata1_led_pin &sata2_led_pin &err_led_pin
+ &sata3_led_pin &sata4_led_pin>;
+ pinctrl-names = "default";
+
+ red-sata1-led {
+ label = "rn2120:red:sata1";
+ gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ red-sata2-led {
+ label = "rn2120:red:sata2";
+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ red-sata3-led {
+ label = "rn2120:red:sata3";
+ gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ red-sata4-led {
+ label = "rn2120:red:sata4";
+ gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ red-err-led {
+ label = "rn2120:red:err";
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&power_button_pin &reset_button_pin>;
+ pinctrl-names = "default";
+
+ power-button {
+ label = "Power Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;
+ };
+
+ reset-button {
+ label = "Reset Button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ pinctrl-0 = <&poweroff>;
+ pinctrl-names = "default";
+ gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pinctrl {
+ poweroff: poweroff {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+
+ power_button_pin: power-button-pin {
+ marvell,pins = "mpp27";
+ marvell,function = "gpio";
+ };
+
+ reset_button_pin: reset-button-pin {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+
+ sata1_led_pin: sata1-led-pin {
+ marvell,pins = "mpp31";
+ marvell,function = "gpio";
+ };
+
+ sata2_led_pin: sata2-led-pin {
+ marvell,pins = "mpp40";
+ marvell,function = "gpio";
+ };
+
+ sata3_led_pin: sata3-led-pin {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+
+ sata4_led_pin: sata4-led-pin {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+
+ sata1_power_pin: sata1-power-pin {
+ marvell,pins = "mpp24";
+ marvell,function = "gpio";
+ };
+
+ sata2_power_pin: sata2-power-pin {
+ marvell,pins = "mpp25";
+ marvell,function = "gpio";
+ };
+
+ sata3_power_pin: sata3-power-pin {
+ marvell,pins = "mpp26";
+ marvell,function = "gpio";
+ };
+
+ sata4_power_pin: sata4-power-pin {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+
+ sata1_pres_pin: sata1-pres-pin {
+ marvell,pins = "mpp32";
+ marvell,function = "gpio";
+ };
+
+ sata2_pres_pin: sata2-pres-pin {
+ marvell,pins = "mpp33";
+ marvell,function = "gpio";
+ };
+
+ sata3_pres_pin: sata3-pres-pin {
+ marvell,pins = "mpp34";
+ marvell,function = "gpio";
+ };
+
+ sata4_pres_pin: sata4-pres-pin {
+ marvell,pins = "mpp35";
+ marvell,function = "gpio";
+ };
+
+ err_led_pin: err-led-pin {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+};
diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
new file mode 100644
index 000000000..990e8a210
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
@@ -0,0 +1,229 @@
+/*
+ * Device Tree file for OpenBlocks AX3-4 board
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "armada-xp-mv78260.dtsi"
+
+/ {
+ model = "PlatHome OpenBlocks AX3-4 board";
+ compatible = "plathome,openblocks-ax3-4", "marvell,armadaxp-mv78260", "marvell,armadaxp", "marvell,armada-370-xp";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x00000000 0 0x40000000>; /* 1 GB soldered on */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+ MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x8000000>;
+
+ devbus-bootcs {
+ status = "okay";
+
+ /* Device Bus parameters are required */
+
+ /* Read parameters */
+ devbus,bus-width = <16>;
+ devbus,turn-off-ps = <60000>;
+ devbus,badr-skew-ps = <0>;
+ devbus,acc-first-ps = <124000>;
+ devbus,acc-next-ps = <248000>;
+ devbus,rd-setup-ps = <0>;
+ devbus,rd-hold-ps = <0>;
+
+ /* Write parameters */
+ devbus,sync-enable = <0>;
+ devbus,wr-high-ps = <60000>;
+ devbus,wr-low-ps = <60000>;
+ devbus,ale-wr-ps = <60000>;
+
+ /* NOR 128 MiB */
+ nor@0 {
+ compatible = "cfi-flash";
+ reg = <0 0x8000000>;
+ bank-width = <2>;
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+ /* Internal mini-PCIe connector */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ };
+
+ internal-regs {
+ rtc@10300 {
+ /* No crystal connected to the internal RTC */
+ status = "disabled";
+ };
+ serial@12000 {
+ status = "okay";
+ };
+ serial@12100 {
+ status = "okay";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+
+ red_led {
+ label = "red_led";
+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ yellow_led {
+ label = "yellow_led";
+ gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ green_led {
+ label = "green_led";
+ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@1 {
+ label = "Init Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ mdio {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ phy2: ethernet-phy@2 {
+ reg = <2>;
+ };
+
+ phy3: ethernet-phy@3 {
+ reg = <3>;
+ };
+ };
+
+ ethernet@70000 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "sgmii";
+ };
+ ethernet@74000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "sgmii";
+ };
+ ethernet@30000 {
+ status = "okay";
+ phy = <&phy2>;
+ phy-mode = "sgmii";
+ };
+ ethernet@34000 {
+ status = "okay";
+ phy = <&phy3>;
+ phy-mode = "sgmii";
+ };
+ i2c@11000 {
+ status = "okay";
+ clock-frequency = <400000>;
+ };
+ i2c@11100 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ s35390a: s35390a@30 {
+ compatible = "s35390a";
+ reg = <0x30>;
+ };
+ };
+ sata@a0000 {
+ nr-ports = <2>;
+ status = "okay";
+ };
+
+ /* Front side USB 0 */
+ usb@50000 {
+ status = "okay";
+ };
+
+ /* Front side USB 1 */
+ usb@51000 {
+ status = "okay";
+ };
+ };
+ };
+};
+
+&pinctrl {
+ led_pins: led-pins-0 {
+ marvell,pins = "mpp49", "mpp51", "mpp53";
+ marvell,function = "gpio";
+ };
+};
diff --git a/arch/arm/boot/dts/armada-xp-synology-ds414.dts b/arch/arm/boot/dts/armada-xp-synology-ds414.dts
new file mode 100644
index 000000000..6063428fa
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-synology-ds414.dts
@@ -0,0 +1,362 @@
+/*
+ * Device Tree file for Synology DS414
+ *
+ * Copyright (C) 2014, Arnaud EBALARD <arno@natisbad.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Note: this Device Tree assumes that the bootloader has remapped the
+ * internal registers to 0xf1000000 (instead of the old 0xd0000000).
+ * The 0xf1000000 is the default used by the recent, DT-capable, U-Boot
+ * bootloaders provided by Marvell. It is used in recent versions of
+ * DSM software provided by Synology. Nonetheless, some earlier boards
+ * were delivered with an older version of u-boot that left internal
+ * registers mapped at 0xd0000000. If you have such a device you will
+ * not be able to directly boot a kernel based on this Device Tree. In
+ * that case, the preferred solution is to update your bootloader (e.g.
+ * by upgrading to latest version of DSM, or building a new one and
+ * installing it from u-boot prompt) or adjust the Devive Tree
+ * (s/0xf1000000/0xd0000000/ in 'ranges' below).
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "armada-xp-mv78230.dtsi"
+
+/ {
+ model = "Synology DS414";
+ compatible = "synology,ds414", "marvell,armadaxp-mv78230",
+ "marvell,armadaxp", "marvell,armada-370-xp";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x00000000 0 0x40000000>; /* 1GB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+
+ pcie-controller {
+ status = "okay";
+
+ /*
+ * Connected to Marvell 88SX7042 SATA-II controller
+ * handling the four disks.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /*
+ * Connected to EtronTech EJ168A XHCI controller
+ * providing the two rear USB 3.0 ports.
+ */
+ pcie@5,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+ };
+
+ internal-regs {
+
+ /* RTC is provided by Seiko S-35390A below */
+ rtc@10300 {
+ status = "disabled";
+ };
+
+ spi0: spi@10600 {
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q064";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <20000000>;
+
+ /*
+ * Warning!
+ *
+ * Synology u-boot uses its compiled-in environment
+ * and it seems Synology did not care to change u-boot
+ * default configuration in order to allow saving a
+ * modified environment at a sensible location. So,
+ * if you do a 'saveenv' under u-boot, your modified
+ * environment will be saved at 1MB after the start
+ * of the flash, i.e. in the middle of the uImage.
+ * For that reason, it is strongly advised not to
+ * change the default environment, unless you know
+ * what you are doing.
+ */
+ partition@00000000 { /* u-boot */
+ label = "RedBoot";
+ reg = <0x00000000 0x000d0000>; /* 832KB */
+ };
+
+ partition@000c0000 { /* uImage */
+ label = "zImage";
+ reg = <0x000d0000 0x002d0000>; /* 2880KB */
+ };
+
+ partition@003a0000 { /* uInitramfs */
+ label = "rd.gz";
+ reg = <0x003a0000 0x00430000>; /* 4250KB */
+ };
+
+ partition@007d0000 { /* MAC address and serial number */
+ label = "vendor";
+ reg = <0x007d0000 0x00010000>; /* 64KB */
+ };
+
+ partition@007e0000 {
+ label = "RedBoot config";
+ reg = <0x007e0000 0x00010000>; /* 64KB */
+ };
+
+ partition@007f0000 {
+ label = "FIS directory";
+ reg = <0x007f0000 0x00010000>; /* 64KB */
+ };
+ };
+ };
+
+ i2c@11000 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ s35390a: s35390a@30 {
+ compatible = "sii,s35390a";
+ reg = <0x30>;
+ };
+ };
+
+ /* Connected to a header on device's PCB. This
+ * provides the main console for the device.
+ *
+ * Warning: the device may not boot with a 3.3V
+ * USB-serial converter connected when the power
+ * button is pressed. The converter needs to be
+ * connected a few seconds after pressing the
+ * power button. This is possibly due to UART0_TXD
+ * pin being sampled at reset (bit 0 of SAR).
+ */
+ serial@12000 {
+ status = "okay";
+ };
+
+ /* Connected to a Microchip PIC16F883 for power control */
+ serial@12100 {
+ status = "okay";
+ };
+
+ poweroff@12100 {
+ compatible = "synology,power-off";
+ reg = <0x12100 0x100>;
+ clocks = <&coreclk 0>;
+ };
+
+ /* Front USB 2.0 port */
+ usb@50000 {
+ status = "okay";
+ };
+
+ mdio {
+ phy0: ethernet-phy@0 { /* Marvell 88E1512 */
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 { /* Marvell 88E1512 */
+ reg = <1>;
+ };
+ };
+
+ ethernet@70000 {
+ status = "okay";
+ pinctrl-0 = <&ge0_rgmii_pins>;
+ pinctrl-names = "default";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+
+ ethernet@74000 {
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&sata1_pwr_pin &sata2_pwr_pin
+ &sata3_pwr_pin &sata4_pwr_pin>;
+ pinctrl-names = "default";
+
+ sata1_regulator: sata1-regulator {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "SATA1 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ startup-delay-us = <2000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+ };
+
+ sata2_regulator: sata2-regulator {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "SATA2 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ startup-delay-us = <4000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ };
+
+ sata3_regulator: sata3-regulator {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "SATA3 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ startup-delay-us = <6000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ };
+
+ sata4_regulator: sata4-regulator {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "SATA4 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ startup-delay-us = <8000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&pinctrl {
+ sata1_pwr_pin: sata1-pwr-pin {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+
+ sata2_pwr_pin: sata2-pwr-pin {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+
+ sata3_pwr_pin: sata3-pwr-pin {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+
+ sata4_pwr_pin: sata4-pwr-pin {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
+ };
+
+ sata1_pres_pin: sata1-pres-pin {
+ marvell,pins = "mpp34";
+ marvell,function = "gpio";
+ };
+
+ sata2_pres_pin: sata2-pres-pin {
+ marvell,pins = "mpp35";
+ marvell,function = "gpio";
+ };
+
+ sata3_pres_pin: sata3-pres-pin {
+ marvell,pins = "mpp40";
+ marvell,function = "gpio";
+ };
+
+ sata4_pres_pin: sata4-pres-pin {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+
+ syno_id_bit0_pin: syno-id-bit0-pin {
+ marvell,pins = "mpp26";
+ marvell,function = "gpio";
+ };
+
+ syno_id_bit1_pin: syno-id-bit1-pin {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+
+ syno_id_bit2_pin: syno-id-bit2-pin {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+
+ fan1_alarm_pin: fan1-alarm-pin {
+ marvell,pins = "mpp33";
+ marvell,function = "gpio";
+ };
+
+ fan2_alarm_pin: fan2-alarm-pin {
+ marvell,pins = "mpp32";
+ marvell,function = "gpio";
+ };
+};
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
new file mode 100644
index 000000000..8fdd6d7c0
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -0,0 +1,312 @@
+/*
+ * Device Tree Include file for Marvell Armada XP family SoC
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ * Ben Dooks <ben.dooks@codethink.co.uk>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contains definitions specific to the Armada XP SoC that are not
+ * common to all Armada SoCs.
+ */
+
+#include "armada-370-xp.dtsi"
+
+/ {
+ model = "Marvell Armada XP family SoC";
+ compatible = "marvell,armadaxp", "marvell,armada-370-xp";
+
+ aliases {
+ serial2 = &uart2;
+ serial3 = &uart3;
+ };
+
+ soc {
+ compatible = "marvell,armadaxp-mbus", "simple-bus";
+
+ bootrom {
+ compatible = "marvell,bootrom";
+ reg = <MBUS_ID(0x01, 0x1d) 0 0x100000>;
+ };
+
+ internal-regs {
+ sdramc@1400 {
+ compatible = "marvell,armada-xp-sdram-controller";
+ reg = <0x1400 0x500>;
+ };
+
+ L2: l2-cache {
+ compatible = "marvell,aurora-system-cache";
+ reg = <0x08000 0x1000>;
+ cache-id-part = <0x100>;
+ cache-level = <2>;
+ cache-unified;
+ wt-override;
+ };
+
+ spi0: spi@10600 {
+ pinctrl-0 = <&spi0_pins>;
+ pinctrl-names = "default";
+ };
+
+ i2c0: i2c@11000 {
+ compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x100>;
+ };
+
+ i2c1: i2c@11100 {
+ compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+ reg = <0x11100 0x100>;
+ };
+
+ uart2: serial@12200 {
+ compatible = "snps,dw-apb-uart";
+ pinctrl-0 = <&uart2_pins>;
+ pinctrl-names = "default";
+ reg = <0x12200 0x100>;
+ reg-shift = <2>;
+ interrupts = <43>;
+ reg-io-width = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ uart3: serial@12300 {
+ compatible = "snps,dw-apb-uart";
+ pinctrl-0 = <&uart3_pins>;
+ pinctrl-names = "default";
+ reg = <0x12300 0x100>;
+ reg-shift = <2>;
+ interrupts = <44>;
+ reg-io-width = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ system-controller@18200 {
+ compatible = "marvell,armada-370-xp-system-controller";
+ reg = <0x18200 0x500>;
+ };
+
+ gateclk: clock-gating-control@18220 {
+ compatible = "marvell,armada-xp-gating-clock";
+ reg = <0x18220 0x4>;
+ clocks = <&coreclk 0>;
+ #clock-cells = <1>;
+ };
+
+ coreclk: mvebu-sar@18230 {
+ compatible = "marvell,armada-xp-core-clock";
+ reg = <0x18230 0x08>;
+ #clock-cells = <1>;
+ };
+
+ thermal@182b0 {
+ compatible = "marvell,armadaxp-thermal";
+ reg = <0x182b0 0x4
+ 0x184d0 0x4>;
+ status = "okay";
+ };
+
+ cpuclk: clock-complex@18700 {
+ #clock-cells = <1>;
+ compatible = "marvell,armada-xp-cpu-clock";
+ reg = <0x18700 0x24>, <0x1c054 0x10>;
+ clocks = <&coreclk 1>;
+ };
+
+ interrupt-controller@20a00 {
+ reg = <0x20a00 0x2d0>, <0x21070 0x58>;
+ };
+
+ timer@20300 {
+ compatible = "marvell,armada-xp-timer";
+ clocks = <&coreclk 2>, <&refclk>;
+ clock-names = "nbclk", "fixed";
+ };
+
+ watchdog@20300 {
+ compatible = "marvell,armada-xp-wdt";
+ clocks = <&coreclk 2>, <&refclk>;
+ clock-names = "nbclk", "fixed";
+ };
+
+ cpurst@20800 {
+ compatible = "marvell,armada-370-cpu-reset";
+ reg = <0x20800 0x20>;
+ };
+
+ eth2: ethernet@30000 {
+ compatible = "marvell,armada-xp-neta";
+ reg = <0x30000 0x4000>;
+ interrupts = <12>;
+ clocks = <&gateclk 2>;
+ status = "disabled";
+ };
+
+ usb@50000 {
+ clocks = <&gateclk 18>;
+ };
+
+ usb@51000 {
+ clocks = <&gateclk 19>;
+ };
+
+ usb@52000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x52000 0x500>;
+ interrupts = <47>;
+ clocks = <&gateclk 20>;
+ status = "disabled";
+ };
+
+ xor@60900 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60900 0x100
+ 0x60b00 0x100>;
+ clocks = <&gateclk 22>;
+ status = "okay";
+
+ xor10 {
+ interrupts = <51>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor11 {
+ interrupts = <52>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+
+ ethernet@70000 {
+ compatible = "marvell,armada-xp-neta";
+ };
+
+ ethernet@74000 {
+ compatible = "marvell,armada-xp-neta";
+ };
+
+ xor@f0900 {
+ compatible = "marvell,orion-xor";
+ reg = <0xF0900 0x100
+ 0xF0B00 0x100>;
+ clocks = <&gateclk 28>;
+ status = "okay";
+
+ xor00 {
+ interrupts = <94>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor01 {
+ interrupts = <95>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+ };
+ };
+
+ clocks {
+ /* 25 MHz reference crystal */
+ refclk: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+ };
+};
+
+&pinctrl {
+ ge0_gmii_pins: ge0-gmii-pins {
+ marvell,pins =
+ "mpp0", "mpp1", "mpp2", "mpp3",
+ "mpp4", "mpp5", "mpp6", "mpp7",
+ "mpp8", "mpp9", "mpp10", "mpp11",
+ "mpp12", "mpp13", "mpp14", "mpp15",
+ "mpp16", "mpp17", "mpp18", "mpp19",
+ "mpp20", "mpp21", "mpp22", "mpp23";
+ marvell,function = "ge0";
+ };
+
+ ge0_rgmii_pins: ge0-rgmii-pins {
+ marvell,pins =
+ "mpp0", "mpp1", "mpp2", "mpp3",
+ "mpp4", "mpp5", "mpp6", "mpp7",
+ "mpp8", "mpp9", "mpp10", "mpp11";
+ marvell,function = "ge0";
+ };
+
+ ge1_rgmii_pins: ge1-rgmii-pins {
+ marvell,pins =
+ "mpp12", "mpp13", "mpp14", "mpp15",
+ "mpp16", "mpp17", "mpp18", "mpp19",
+ "mpp20", "mpp21", "mpp22", "mpp23";
+ marvell,function = "ge1";
+ };
+
+ sdio_pins: sdio-pins {
+ marvell,pins = "mpp30", "mpp31", "mpp32",
+ "mpp33", "mpp34", "mpp35";
+ marvell,function = "sd0";
+ };
+
+ spi0_pins: spi0-pins {
+ marvell,pins = "mpp36", "mpp37",
+ "mpp38", "mpp39";
+ marvell,function = "spi";
+ };
+
+ uart2_pins: uart2-pins {
+ marvell,pins = "mpp42", "mpp43";
+ marvell,function = "uart2";
+ };
+
+ uart3_pins: uart3-pins {
+ marvell,pins = "mpp44", "mpp45";
+ marvell,function = "uart3";
+ };
+};
diff --git a/arch/arm/boot/dts/armv7-m.dtsi b/arch/arm/boot/dts/armv7-m.dtsi
new file mode 100644
index 000000000..5a660d0fa
--- /dev/null
+++ b/arch/arm/boot/dts/armv7-m.dtsi
@@ -0,0 +1,18 @@
+#include "skeleton.dtsi"
+
+/ {
+ nvic: nv-interrupt-controller {
+ compatible = "arm,armv7m-nvic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xe000e100 0xc00>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&nvic>;
+ ranges;
+ };
+};
diff --git a/arch/arm/boot/dts/at91-ariag25.dts b/arch/arm/boot/dts/at91-ariag25.dts
new file mode 100644
index 000000000..e9ced3015
--- /dev/null
+++ b/arch/arm/boot/dts/at91-ariag25.dts
@@ -0,0 +1,187 @@
+/*
+ * at91-ariag25.dts - Device Tree file for Acme Systems Aria G25 (AT91SAM9G25 based)
+ *
+ * Copyright (C) 2013 Douglas Gilbert <dgilbert@interlog.com>,
+ * Robert Nelson <robertcnelson@gmail.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "at91sam9g25.dtsi"
+
+/ {
+ model = "Acme Systems Aria G25";
+ compatible = "acme,ariag25", "atmel,at91sam9x5ek",
+ "atmel,at91sam9x5", "atmel,at91sam9";
+
+ aliases {
+ serial0 = &dbgu;
+ serial1 = &usart0;
+ serial2 = &usart1;
+ serial3 = &usart2;
+ serial4 = &usart3;
+ serial5 = &uart0;
+ serial6 = &uart1;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait";
+ };
+
+ memory {
+ /* 128 MB, change this for 256 MB revision */
+ reg = <0x20000000 0x8000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ mmc0: mmc@f0008000 {
+ /* N.B. Aria has no SD card detect (CD), assumed present */
+
+ pinctrl-0 = <
+ &pinctrl_mmc0_slot0_clk_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ };
+ };
+
+ i2c0: i2c@f8010000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@f8014000 {
+ status = "okay";
+ };
+
+ /* TWD2+TCLK2 hidden behind ethernet, so no i2c2 */
+
+ usart0: serial@f801c000 {
+ pinctrl-0 = <&pinctrl_usart0
+ &pinctrl_usart0_rts
+ &pinctrl_usart0_cts>;
+ status = "okay";
+ };
+
+ usart1: serial@f8020000 {
+ pinctrl-0 = <&pinctrl_usart1
+ /* &pinctrl_usart1_rts */
+ /* &pinctrl_usart1_cts */
+ >;
+ status = "okay";
+ };
+
+ usart2: serial@f8024000 {
+ /* cannot activate RTS2+CTS2, clash with
+ * ethernet on PB0 and PB1 */
+ pinctrl-0 = <&pinctrl_usart2>;
+ status = "okay";
+ };
+
+ usart3: serial@f8028000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf8028000 0x200>;
+ interrupts = <8 4 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart3
+ /* &pinctrl_usart3_rts */
+ /* &pinctrl_usart3_cts */
+ >;
+ status = "okay";
+ };
+
+ macb0: ethernet@f802c000 {
+ phy-mode = "rmii";
+ /*
+ * following can be overwritten by bootloader:
+ * for example u-boot 'ftd set' command
+ */
+ local-mac-address = [00 00 00 00 00 00];
+ status = "okay";
+ };
+
+ /*
+ * UART0/1 pins are marked as GPIO on
+ * Aria documentation.
+ * Change to "okay" if you need additional serial ports
+ */
+ uart0: serial@f8040000 {
+ status = "disabled";
+ };
+
+ uart1: serial@f8044000 {
+ status = "disabled";
+ };
+
+ adc0: adc@f804c000 {
+ status = "okay";
+ atmel,adc-channels-used = <0xf>;
+ };
+
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ pinctrl@fffff400 {
+ w1_0 {
+ pinctrl_w1_0: w1_0-0 {
+ atmel,pins = <0 21 0x0 0x1>; /* PA21 PIO, pull-up */
+ };
+ };
+ };
+
+ rtc@fffffeb0 {
+ status = "okay";
+ };
+ };
+
+ usb0: ohci@00600000 {
+ status = "okay";
+ num-ports = <3>;
+ };
+
+ usb1: ehci@00700000 {
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ /* little green LED in middle of Aria G25 module */
+ aria_led {
+ label = "aria_led";
+ gpios = <&pioB 8 GPIO_ACTIVE_HIGH>; /* PB8 */
+ linux,default-trigger = "heartbeat";
+ };
+
+ };
+
+ onewire@0 {
+ compatible = "w1-gpio";
+ gpios = <&pioA 21 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_w1_0>;
+ };
+};
diff --git a/arch/arm/boot/dts/at91-cosino.dtsi b/arch/arm/boot/dts/at91-cosino.dtsi
new file mode 100644
index 000000000..b6ea3f4a7
--- /dev/null
+++ b/arch/arm/boot/dts/at91-cosino.dtsi
@@ -0,0 +1,129 @@
+/*
+ * at91-cosino.dtsi - Device Tree file for Cosino core module
+ *
+ * Copyright (C) 2013 - Rodolfo Giometti <giometti@linux.it>
+ * HCE Engineering
+ *
+ * Derived from at91sam9x5ek.dtsi by:
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include "at91sam9g35.dtsi"
+
+/ {
+ model = "HCE Cosino core module";
+ compatible = "hce,cosino", "atmel,at91sam9x5", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait";
+ };
+
+ memory {
+ reg = <0x20000000 0x8000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ mmc0: mmc@f0008000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0
+ &pinctrl_mmc0_slot0_clk_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ usart0: serial@f801c000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@f8010000 {
+ status = "okay";
+ };
+
+ adc0: adc@f804c000 {
+ atmel,adc-ts-wires = <4>;
+ atmel,adc-ts-pressure-threshold = <10000>;
+ status = "okay";
+ };
+
+ pinctrl@fffff400 {
+ mmc0 {
+ pinctrl_board_mmc0: mmc0-board {
+ atmel,pins =
+ <AT91_PIOD 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PD15 gpio CD pin pull up and deglitch */
+ };
+ };
+ };
+
+ watchdog@fffffe40 {
+ status = "okay";
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ atmel,has-pmecc; /* Enable PMECC */
+ atmel,pmecc-cap = <4>;
+ atmel,pmecc-sector-size = <512>;
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ uboot@40000 {
+ label = "u-boot";
+ reg = <0x40000 0x80000>;
+ };
+
+ ubootenv@c0000 {
+ label = "U-Boot Env";
+ reg = <0xc0000 0x140000>;
+ };
+
+ kernel@200000 {
+ label = "kernel";
+ reg = <0x200000 0x600000>;
+ };
+
+ rootfs@800000 {
+ label = "rootfs";
+ reg = <0x800000 0x0f800000>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91-cosino_mega2560.dts b/arch/arm/boot/dts/at91-cosino_mega2560.dts
new file mode 100644
index 000000000..27ebb0f72
--- /dev/null
+++ b/arch/arm/boot/dts/at91-cosino_mega2560.dts
@@ -0,0 +1,78 @@
+/*
+ * at91-cosino_mega2560.dts - Device Tree file for Cosino board with
+ * Mega 2560 extension
+ *
+ * Copyright (C) 2013 - Rodolfo Giometti <giometti@linux.it>
+ * HCE Engineering
+ *
+ * Derived from at91sam9g35ek.dts by:
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/dts-v1/;
+#include "at91-cosino.dtsi"
+
+/ {
+ model = "HCE Cosino Mega 2560";
+ compatible = "hce,cosino_mega2560", "atmel,at91sam9x5", "atmel,at91sam9";
+
+ ahb {
+ apb {
+ macb0: ethernet@f802c000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ adc0: adc@f804c000 {
+ atmel,adc-ts-wires = <4>;
+ atmel,adc-ts-pressure-threshold = <10000>;
+ status = "okay";
+ };
+
+ rtc@fffffeb0 {
+ status = "okay";
+ };
+
+ usart1: serial@f8020000 {
+ status = "okay";
+ };
+
+ usart2: serial@f8024000 {
+ status = "okay";
+ };
+
+ usb2: gadget@f803c000 {
+ atmel,vbus-gpio = <&pioB 16 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ mmc1: mmc@f000c000 {
+ pinctrl-0 = <
+ &pinctrl_mmc1_slot0_clk_cmd_dat0
+ &pinctrl_mmc1_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ non-removable;
+ };
+ };
+ };
+
+ usb0: ohci@00600000 {
+ status = "okay";
+ num-ports = <3>;
+ atmel,vbus-gpio = <0 /* &pioD 18 GPIO_ACTIVE_LOW */
+ &pioD 19 GPIO_ACTIVE_LOW
+ &pioD 20 GPIO_ACTIVE_LOW
+ >;
+ };
+
+ usb1: ehci@00700000 {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91-foxg20.dts b/arch/arm/boot/dts/at91-foxg20.dts
new file mode 100644
index 000000000..f89598af4
--- /dev/null
+++ b/arch/arm/boot/dts/at91-foxg20.dts
@@ -0,0 +1,165 @@
+/*
+ * at91-foxg20.dts - Device Tree file for Acme Systems FoxG20 board
+ *
+ * Based on DT files for at91sam9g20ek evaluation board (AT91SAM9G20 SoC)
+ *
+ * Copyright (C) 2013 Douglas Gilbert <dgilbert@interlog.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "at91sam9g20.dtsi"
+
+/ {
+ model = "Acme Systems FoxG20";
+ compatible = "acme,foxg20", "atmel,at91sam9g20", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait";
+ };
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <18432000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <18432000>;
+ };
+ };
+
+ ahb {
+ apb {
+ usb1: gadget@fffa4000 {
+ atmel,vbus-gpio = <&pioC 6 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ mmc0: mmc@fffa8000 {
+ pinctrl-0 = <
+ &pinctrl_mmc0_clk
+ &pinctrl_mmc0_slot1_cmd_dat0
+ &pinctrl_mmc0_slot1_dat1_3>;
+ status = "okay";
+
+ slot@1 {
+ reg = <1>;
+ bus-width = <4>;
+ };
+ };
+
+ usart0: serial@fffb0000 {
+ pinctrl-0 =
+ <&pinctrl_usart0
+ &pinctrl_usart0_rts
+ &pinctrl_usart0_cts
+ >;
+ status = "okay";
+ };
+
+ usart1: serial@fffb4000 {
+ status = "okay";
+ };
+
+ usart2: serial@fffb8000 {
+ status = "okay";
+ };
+
+ macb0: ethernet@fffc4000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ usart3: serial@fffd0000 {
+ status = "okay";
+ };
+
+ uart0: serial@fffd4000 {
+ status = "okay";
+ };
+
+ uart1: serial@fffd8000 {
+ status = "okay";
+ };
+
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ pinctrl@fffff400 {
+ board {
+ pinctrl_pck0_as_mck: pck0_as_mck {
+ atmel,pins =
+ <AT91_PIOC 1 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ mmc0_slot1 {
+ pinctrl_board_mmc0_slot1: mmc0_slot1-board {
+ atmel,pins =
+ <AT91_PIOC 9 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* CD pin */
+ };
+ };
+
+ i2c0 {
+ pinctrl_i2c0: i2c0-0 {
+ atmel,pins =
+ <AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_MULTI_DRIVE /* TWD (SDA), open drain */
+ AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_MULTI_DRIVE>; /* TWCK (SCL), open drain */
+ };
+ };
+ };
+
+ watchdog@fffffd40 {
+ status = "okay";
+ };
+ };
+
+ usb0: ohci@00500000 {
+ num-ports = <2>;
+ status = "okay";
+ };
+ };
+
+ i2c@0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ i2c-gpio,delay-us = <5>; /* ~85 kHz */
+ status = "okay";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ /* red LED marked "PC7" near mini USB (device) receptacle */
+ user_led {
+ label = "user_led";
+ gpios = <&pioC 7 GPIO_ACTIVE_HIGH>; /* PC7 */
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ btn {
+ label = "Button";
+ gpios = <&pioC 4 GPIO_ACTIVE_LOW>;
+ linux,code = <0x103>;
+ gpio-key,wakeup;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91-qil_a9260.dts b/arch/arm/boot/dts/at91-qil_a9260.dts
new file mode 100644
index 000000000..a9aef53ab
--- /dev/null
+++ b/arch/arm/boot/dts/at91-qil_a9260.dts
@@ -0,0 +1,193 @@
+/*
+ * at91-qil_a9260.dts - Device Tree file for Calao QIL A9260 board
+ *
+ * Copyright (C) 2011-2013 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+/dts-v1/;
+#include "at91sam9260.dtsi"
+/ {
+ model = "Calao QIL A9260";
+ compatible = "calao,qil-a9260", "atmel,at91sam9260", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ usb1: gadget@fffa4000 {
+ atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ mmc0: mmc@fffa8000 {
+ pinctrl-0 = <
+ &pinctrl_mmc0_clk
+ &pinctrl_mmc0_slot0_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ };
+ };
+
+ usart0: serial@fffb0000 {
+ pinctrl-0 =
+ <&pinctrl_usart0
+ &pinctrl_usart0_rts
+ &pinctrl_usart0_cts
+ &pinctrl_usart0_dtr_dsr
+ &pinctrl_usart0_dcd
+ &pinctrl_usart0_ri>;
+ status = "okay";
+ };
+
+ usart1: serial@fffb4000 {
+ pinctrl-0 =
+ <&pinctrl_usart1
+ &pinctrl_usart1_rts
+ &pinctrl_usart1_cts>;
+ status = "okay";
+ };
+
+ usart2: serial@fffb8000 {
+ pinctrl-0 =
+ <&pinctrl_usart2
+ &pinctrl_usart2_rts
+ &pinctrl_usart2_cts>;
+ status = "okay";
+ };
+
+ macb0: ethernet@fffc4000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ spi0: spi@fffc8000 {
+ status = "okay";
+ cs-gpios = <&pioA 3 GPIO_ACTIVE_HIGH>;
+
+ m41t94@0 {
+ compatible = "st,m41t94";
+ reg = <0>;
+ spi-max-frequency = <1000000>;
+ };
+
+ };
+
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ shdwc@fffffd10 {
+ atmel,wakeup-counter = <10>;
+ atmel,wakeup-rtt-timer;
+ };
+ };
+
+ usb0: ohci@00500000 {
+ num-ports = <2>;
+ status = "okay";
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x20000>;
+ };
+
+ barebox@20000 {
+ label = "barebox";
+ reg = <0x20000 0x40000>;
+ };
+
+ bareboxenv@60000 {
+ label = "bareboxenv";
+ reg = <0x60000 0x20000>;
+ };
+
+ bareboxenv2@80000 {
+ label = "bareboxenv2";
+ reg = <0x80000 0x20000>;
+ };
+
+ oftree@a0000 {
+ label = "oftree";
+ reg = <0xa0000 0x20000>;
+ };
+
+ kernel@c0000 {
+ label = "kernel";
+ reg = <0xc0000 0x400000>;
+ };
+
+ rootfs@4c0000 {
+ label = "rootfs";
+ reg = <0x4c0000 0x7800000>;
+ };
+
+ data@7cc0000 {
+ label = "data";
+ reg = <0x7cc0000 0x8340000>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ user_led {
+ label = "user_led";
+ gpios = <&pioB 21 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ user_pb {
+ label = "user_pb";
+ gpios = <&pioB 10 GPIO_ACTIVE_LOW>;
+ linux,code = <28>;
+ gpio-key,wakeup;
+ };
+ };
+
+ i2c@0 {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
new file mode 100644
index 000000000..9991240b7
--- /dev/null
+++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
@@ -0,0 +1,315 @@
+/*
+ * at91-sama5d3_xplained.dts - Device Tree file for the SAMA5D3 Xplained board
+ *
+ * Copyright (C) 2014 Atmel,
+ * 2014 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "sama5d36.dtsi"
+
+/ {
+ model = "SAMA5D3 Xplained";
+ compatible = "atmel,sama5d3-xplained", "atmel,sama5d3", "atmel,sama5";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x20000000 0x10000000>;
+ };
+
+ clocks {
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ mmc0: mmc@f0000000 {
+ pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_dat4_7 &pinctrl_mmc0_cd>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <8>;
+ cd-gpios = <&pioE 0 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ spi0: spi@f0004000 {
+ cs-gpios = <&pioD 13 0>, <0>, <0>, <&pioD 16 0>;
+ status = "okay";
+ };
+
+ can0: can@f000c000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@f0014000 {
+ pinctrl-0 = <&pinctrl_i2c0_pu>;
+ status = "okay";
+ };
+
+ i2c1: i2c@f0018000 {
+ status = "okay";
+
+ pmic: act8865@5b {
+ compatible = "active-semi,act8865";
+ reg = <0x5b>;
+ status = "okay";
+
+ regulators {
+ vcc_1v8_reg: DCDC_REG1 {
+ regulator-name = "VCC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vcc_1v2_reg: DCDC_REG2 {
+ regulator-name = "VCC_1V2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ vcc_3v3_reg: DCDC_REG3 {
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vddfuse_reg: LDO_REG1 {
+ regulator-name = "FUSE_2V5";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ };
+
+ vddana_reg: LDO_REG2 {
+ regulator-name = "VDDANA";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+ };
+
+ macb0: ethernet@f0028000 {
+ phy-mode = "rgmii";
+ status = "okay";
+ };
+
+ pwm0: pwm@f002c000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm0_pwmh0_0 &pinctrl_pwm0_pwmh1_0>;
+ status = "okay";
+ };
+
+ usart0: serial@f001c000 {
+ status = "okay";
+ };
+
+ usart1: serial@f0020000 {
+ pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>;
+ status = "okay";
+ };
+
+ uart0: serial@f0024000 {
+ status = "okay";
+ };
+
+ mmc1: mmc@f8000000 {
+ pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioE 1 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ spi1: spi@f8008000 {
+ cs-gpios = <&pioC 25 0>;
+ status = "okay";
+ };
+
+ adc0: adc@f8018000 {
+ pinctrl-0 = <
+ &pinctrl_adc0_adtrg
+ &pinctrl_adc0_ad0
+ &pinctrl_adc0_ad1
+ &pinctrl_adc0_ad2
+ &pinctrl_adc0_ad3
+ &pinctrl_adc0_ad4
+ &pinctrl_adc0_ad5
+ &pinctrl_adc0_ad6
+ &pinctrl_adc0_ad7
+ &pinctrl_adc0_ad8
+ &pinctrl_adc0_ad9
+ >;
+ status = "okay";
+ };
+
+ i2c2: i2c@f801c000 {
+ dmas = <0>, <0>; /* Do not use DMA for i2c2 */
+ pinctrl-0 = <&pinctrl_i2c2_pu>;
+ status = "okay";
+ };
+
+ macb1: ethernet@f802c000 {
+ phy-mode = "rmii";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ };
+
+ dbgu: serial@ffffee00 {
+ status = "okay";
+ };
+
+ pinctrl@fffff200 {
+ board {
+ pinctrl_i2c0_pu: i2c0_pu {
+ atmel,pins =
+ <AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
+ };
+
+ pinctrl_i2c2_pu: i2c2_pu {
+ atmel,pins =
+ <AT91_PIOA 18 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOA 19 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;
+ };
+
+ pinctrl_key_gpio: key_gpio_0 {
+ atmel,pins =
+ <AT91_PIOE 29 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
+
+ pinctrl_mmc0_cd: mmc0_cd {
+ atmel,pins =
+ <AT91_PIOE 0 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
+
+ pinctrl_mmc1_cd: mmc1_cd {
+ atmel,pins =
+ <AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
+
+ pinctrl_usba_vbus: usba_vbus {
+ atmel,pins =
+ <AT91_PIOE 9 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PE9, conflicts with A9 */
+ };
+ };
+ };
+
+ pmc: pmc@fffffc00 {
+ main: mainck {
+ clock-frequency = <12000000>;
+ };
+ };
+ };
+
+ nand0: nand@60000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ atmel,has-pmecc;
+ atmel,pmecc-cap = <4>;
+ atmel,pmecc-sector-size = <512>;
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ bootloader@40000 {
+ label = "bootloader";
+ reg = <0x40000 0x80000>;
+ };
+
+ bootloaderenv@c0000 {
+ label = "bootloader env";
+ reg = <0xc0000 0xc0000>;
+ };
+
+ dtb@180000 {
+ label = "device tree";
+ reg = <0x180000 0x80000>;
+ };
+
+ kernel@200000 {
+ label = "kernel";
+ reg = <0x200000 0x600000>;
+ };
+
+ rootfs@800000 {
+ label = "rootfs";
+ reg = <0x800000 0x0f800000>;
+ };
+ };
+
+ usb0: gadget@00500000 {
+ atmel,vbus-gpio = <&pioE 9 GPIO_ACTIVE_HIGH>; /* PE9, conflicts with A9 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usba_vbus>;
+ status = "okay";
+ };
+
+ usb1: ohci@00600000 {
+ num-ports = <3>;
+ atmel,vbus-gpio = <0
+ &pioE 3 GPIO_ACTIVE_LOW
+ &pioE 4 GPIO_ACTIVE_LOW
+ >;
+ status = "okay";
+ };
+
+ usb2: ehci@00700000 {
+ status = "okay";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_key_gpio>;
+
+ bp3 {
+ label = "PB_USER";
+ gpios = <&pioE 29 GPIO_ACTIVE_LOW>;
+ linux,code = <0x104>;
+ gpio-key,wakeup;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ d2 {
+ label = "d2";
+ gpios = <&pioE 23 GPIO_ACTIVE_LOW>; /* PE23, conflicts with A23, CTS2 */
+ linux,default-trigger = "heartbeat";
+ };
+
+ d3 {
+ label = "d3";
+ gpios = <&pioE 24 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91-sama5d4_xplained.dts b/arch/arm/boot/dts/at91-sama5d4_xplained.dts
new file mode 100644
index 000000000..c740e1a2a
--- /dev/null
+++ b/arch/arm/boot/dts/at91-sama5d4_xplained.dts
@@ -0,0 +1,241 @@
+/*
+ * at91-sama5d4_xplained.dts - Device Tree file for SAMA5D4 Xplained board
+ *
+ * Copyright (C) 2015 Atmel,
+ * 2015 Josh Wu <josh.wu@atmel.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+/dts-v1/;
+#include "sama5d4.dtsi"
+
+/ {
+ model = "Atmel SAMA5D4 Xplained";
+ compatible = "atmel,sama5d4-xplained", "atmel,sama5d4", "atmel,sama5";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 ignore_loglevel earlyprintk";
+ };
+
+ memory {
+ reg = <0x20000000 0x20000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ spi0: spi@f8010000 {
+ cs-gpios = <&pioC 3 0>, <0>, <0>, <0>;
+ status = "okay";
+ m25p80@0 {
+ compatible = "atmel,at25df321a";
+ spi-max-frequency = <50000000>;
+ reg = <0>;
+ };
+ };
+
+ i2c0: i2c@f8014000 {
+ status = "okay";
+ };
+
+ macb0: ethernet@f8020000 {
+ phy-mode = "rmii";
+ status = "okay";
+
+ phy0: ethernet-phy@1 {
+ interrupt-parent = <&pioE>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+ reg = <1>;
+ };
+ };
+
+ mmc1: mmc@fc000000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioE 3 0>;
+ };
+ };
+
+ usart3: serial@fc00c000 {
+ status = "okay";
+ };
+
+ usart4: serial@fc010000 {
+ status = "okay";
+ };
+
+ adc0: adc@fc034000 {
+ atmel,adc-vref = <3300>;
+ status = "okay";
+ };
+
+ watchdog@fc068640 {
+ status = "okay";
+ };
+
+ pinctrl@fc06a000 {
+ board {
+ pinctrl_mmc1_cd: mmc1_cd {
+ atmel,pins =
+ <AT91_PIOE 3 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
+ pinctrl_usba_vbus: usba_vbus {
+ atmel,pins =
+ <AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;
+ };
+ pinctrl_key_gpio: key_gpio_0 {
+ atmel,pins =
+ <AT91_PIOE 8 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
+ };
+ };
+ };
+
+ usb0: gadget@00400000 {
+ atmel,vbus-gpio = <&pioE 31 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usba_vbus>;
+ status = "okay";
+ };
+
+ usb1: ohci@00500000 {
+ num-ports = <3>;
+ atmel,vbus-gpio = <0
+ &pioE 11 GPIO_ACTIVE_HIGH
+ &pioE 14 GPIO_ACTIVE_HIGH
+ >;
+ status = "okay";
+ };
+
+ usb2: ehci@00600000 {
+ status = "okay";
+ };
+
+ nand0: nand@80000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ nand-on-flash-bbt;
+ atmel,has-pmecc;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ bootloader@40000 {
+ label = "bootloader";
+ reg = <0x40000 0x80000>;
+ };
+
+ bootloaderenv@c0000 {
+ label = "bootloader env";
+ reg = <0xc0000 0xc0000>;
+ };
+
+ dtb@180000 {
+ label = "device tree";
+ reg = <0x180000 0x80000>;
+ };
+
+ kernel@200000 {
+ label = "kernel";
+ reg = <0x200000 0x600000>;
+ };
+
+ rootfs@800000 {
+ label = "rootfs";
+ reg = <0x800000 0x0f800000>;
+ };
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_key_gpio>;
+
+ pb_user1 {
+ label = "pb_user1";
+ gpios = <&pioE 8 GPIO_ACTIVE_HIGH>;
+ linux,code = <0x100>;
+ gpio-key,wakeup;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ status = "okay";
+
+ d8 {
+ label = "d8";
+ gpios = <&pioD 30 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+ };
+
+ d10 {
+ label = "d10";
+ gpios = <&pioE 15 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91-sama5d4ek.dts b/arch/arm/boot/dts/at91-sama5d4ek.dts
new file mode 100644
index 000000000..45e7761b7
--- /dev/null
+++ b/arch/arm/boot/dts/at91-sama5d4ek.dts
@@ -0,0 +1,311 @@
+/*
+ * at91-sama5d4ek.dts - Device Tree file for SAMA5D4 Evaluation Kit
+ *
+ * Copyright (C) 2014 Atmel,
+ * 2014 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+/dts-v1/;
+#include "sama5d4.dtsi"
+
+/ {
+ model = "Atmel SAMA5D4-EK";
+ compatible = "atmel,sama5d4ek", "atmel,sama5d4", "atmel,sama5";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 ignore_loglevel earlyprintk";
+ };
+
+ memory {
+ reg = <0x20000000 0x20000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ lcd_bus@f0000000 {
+ status = "okay";
+
+ lcd@f0000000 {
+ status = "okay";
+ };
+
+ lcdovl1@f0000140 {
+ status = "okay";
+ };
+
+ lcdovl2@f0000240 {
+ status = "okay";
+ };
+
+ lcdheo1@f0000340 {
+ status = "okay";
+ };
+ };
+
+ adc0: adc@fc034000 {
+ /* The vref depends on JP22 of EK. If connect 1-2 then use 3.3V. connect 2-3 use 3.0V */
+ atmel,adc-vref = <3300>;
+ /*atmel,adc-ts-wires = <4>;*/ /* Set up ADC touch screen */
+ status = "okay"; /* Enable ADC IIO support */
+ };
+
+ mmc0: mmc@f8000000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_cd>;
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioE 5 0>;
+ };
+ };
+
+ ssc0: ssc@f8008000 {
+ status = "okay";
+ };
+
+ spi0: spi@f8010000 {
+ cs-gpios = <&pioC 3 0>, <0>, <0>, <0>;
+ status = "okay";
+ m25p80@0 {
+ compatible = "atmel,at25df321a";
+ spi-max-frequency = <50000000>;
+ reg = <0>;
+ };
+ };
+
+ i2c0: i2c@f8014000 {
+ status = "okay";
+
+ wm8904: codec@1a {
+ compatible = "wlf,wm8904";
+ reg = <0x1a>;
+ clocks = <&pck2>;
+ clock-names = "mclk";
+ };
+ };
+
+ macb0: ethernet@f8020000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ mmc1: mmc@fc000000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioE 6 0>;
+ };
+ };
+
+ usart2: serial@fc008000 {
+ status = "okay";
+ };
+
+ usart3: serial@fc00c000 {
+ status = "okay";
+ };
+
+ usart4: serial@fc010000 {
+ status = "okay";
+ };
+
+ watchdog@fc068640 {
+ status = "okay";
+ };
+
+ pinctrl@fc06a000 {
+ board {
+ pinctrl_mmc0_cd: mmc0_cd {
+ atmel,pins =
+ <AT91_PIOE 5 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
+ pinctrl_mmc1_cd: mmc1_cd {
+ atmel,pins =
+ <AT91_PIOE 6 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
+ pinctrl_pck2_as_audio_mck: pck2_as_audio_mck {
+ atmel,pins =
+ <AT91_PIOB 10 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ pinctrl_usba_vbus: usba_vbus {
+ atmel,pins =
+ <AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;
+ };
+ pinctrl_key_gpio: key_gpio_0 {
+ atmel,pins =
+ <AT91_PIOE 13 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PE13 gpio */
+ };
+ };
+ };
+ };
+
+ usb0: gadget@00400000 {
+ atmel,vbus-gpio = <&pioE 31 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usba_vbus>;
+ status = "okay";
+ };
+
+ usb1: ohci@00500000 {
+ num-ports = <3>;
+ atmel,vbus-gpio = <0 /* &pioE 10 GPIO_ACTIVE_LOW */
+ &pioE 11 GPIO_ACTIVE_LOW
+ &pioE 12 GPIO_ACTIVE_LOW
+ >;
+ status = "okay";
+ };
+
+ usb2: ehci@00600000 {
+ status = "okay";
+ };
+
+ nand0: nand@80000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ nand-on-flash-bbt;
+ atmel,has-pmecc;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ bootloader@40000 {
+ label = "bootloader";
+ reg = <0x40000 0x80000>;
+ };
+
+ bootloaderenv@c0000 {
+ label = "bootloader env";
+ reg = <0xc0000 0xc0000>;
+ };
+
+ dtb@180000 {
+ label = "device tree";
+ reg = <0x180000 0x80000>;
+ };
+
+ kernel@200000 {
+ label = "kernel";
+ reg = <0x200000 0x600000>;
+ };
+
+ rootfs@800000 {
+ label = "rootfs";
+ reg = <0x800000 0x0f800000>;
+ };
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_key_gpio>;
+
+ pb_user1 {
+ label = "pb_user1";
+ gpios = <&pioE 13 GPIO_ACTIVE_HIGH>;
+ linux,code = <0x100>;
+ gpio-key,wakeup;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ status = "okay";
+
+ d8 {
+ label = "d8";
+ /* PE28, conflicts with usart4 rts pin */
+ gpios = <&pioE 28 GPIO_ACTIVE_LOW>;
+ };
+
+ d9 {
+ label = "d9";
+ gpios = <&pioE 9 GPIO_ACTIVE_HIGH>;
+ };
+
+ d10 {
+ label = "d10";
+ gpios = <&pioE 8 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ sound {
+ compatible = "atmel,asoc-wm8904";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pck2_as_audio_mck>;
+
+ atmel,model = "wm8904 @ SAMA5D4EK";
+ atmel,audio-routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "IN1L", "Line In Jack",
+ "IN1R", "Line In Jack";
+
+ atmel,ssc-controller = <&ssc0>;
+ atmel,audio-codec = <&wm8904>;
+ };
+};
diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi
new file mode 100644
index 000000000..4fb333bd1
--- /dev/null
+++ b/arch/arm/boot/dts/at91rm9200.dtsi
@@ -0,0 +1,963 @@
+/*
+ * at91rm9200.dtsi - Device Tree Include file for AT91RM9200 family SoC
+ *
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>,
+ * 2012 Joachim Eastwood <manabian@gmail.com>
+ *
+ * Based on at91sam9260.dtsi
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/at91.h>
+
+/ {
+ model = "Atmel AT91RM9200 family SoC";
+ compatible = "atmel,at91rm9200";
+ interrupt-parent = <&aic>;
+
+ aliases {
+ serial0 = &dbgu;
+ serial1 = &usart0;
+ serial2 = &usart1;
+ serial3 = &usart2;
+ serial4 = &usart3;
+ gpio0 = &pioA;
+ gpio1 = &pioB;
+ gpio2 = &pioC;
+ gpio3 = &pioD;
+ tcb0 = &tcb0;
+ tcb1 = &tcb1;
+ i2c0 = &i2c0;
+ ssc0 = &ssc0;
+ ssc1 = &ssc1;
+ ssc2 = &ssc2;
+ };
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm920t";
+ device_type = "cpu";
+ };
+ };
+
+ memory {
+ reg = <0x20000000 0x04000000>;
+ };
+
+ clocks {
+ slow_xtal: slow_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ main_xtal: main_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ sram: sram@00200000 {
+ compatible = "mmio-sram";
+ reg = <0x00200000 0x4000>;
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ aic: interrupt-controller@fffff000 {
+ #interrupt-cells = <3>;
+ compatible = "atmel,at91rm9200-aic";
+ interrupt-controller;
+ reg = <0xfffff000 0x200>;
+ atmel,external-irqs = <25 26 27 28 29 30 31>;
+ };
+
+ ramc0: ramc@ffffff00 {
+ compatible = "atmel,at91rm9200-sdramc";
+ reg = <0xffffff00 0x100>;
+ };
+
+ pmc: pmc@fffffc00 {
+ compatible = "atmel,at91rm9200-pmc";
+ reg = <0xfffffc00 0x100>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ main_osc: main_osc {
+ compatible = "atmel,at91rm9200-clk-main-osc";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MOSCS>;
+ clocks = <&main_xtal>;
+ };
+
+ main: mainck {
+ compatible = "atmel,at91rm9200-clk-main";
+ #clock-cells = <0>;
+ clocks = <&main_osc>;
+ };
+
+ plla: pllack {
+ compatible = "atmel,at91rm9200-clk-pll";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_LOCKA>;
+ clocks = <&main>;
+ reg = <0>;
+ atmel,clk-input-range = <1000000 32000000>;
+ #atmel,pll-clk-output-range-cells = <3>;
+ atmel,pll-clk-output-ranges = <80000000 160000000 0>,
+ <150000000 180000000 2>;
+ };
+
+ pllb: pllbck {
+ compatible = "atmel,at91rm9200-clk-pll";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_LOCKB>;
+ clocks = <&main>;
+ reg = <1>;
+ atmel,clk-input-range = <1000000 32000000>;
+ #atmel,pll-clk-output-range-cells = <3>;
+ atmel,pll-clk-output-ranges = <80000000 160000000 0>,
+ <150000000 180000000 2>;
+ };
+
+ mck: masterck {
+ compatible = "atmel,at91rm9200-clk-master";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MCKRDY>;
+ clocks = <&slow_xtal>, <&main>, <&plla>, <&pllb>;
+ atmel,clk-output-range = <0 80000000>;
+ atmel,clk-divisors = <1 2 3 4>;
+ };
+
+ usb: usbck {
+ compatible = "atmel,at91rm9200-clk-usb";
+ #clock-cells = <0>;
+ atmel,clk-divisors = <1 2 0 0>;
+ clocks = <&pllb>;
+ };
+
+ prog: progck {
+ compatible = "atmel,at91rm9200-clk-programmable";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-parent = <&pmc>;
+ clocks = <&slow_xtal>, <&main>, <&plla>, <&pllb>;
+
+ prog0: prog0 {
+ #clock-cells = <0>;
+ reg = <0>;
+ interrupts = <AT91_PMC_PCKRDY(0)>;
+ };
+
+ prog1: prog1 {
+ #clock-cells = <0>;
+ reg = <1>;
+ interrupts = <AT91_PMC_PCKRDY(1)>;
+ };
+
+ prog2: prog2 {
+ #clock-cells = <0>;
+ reg = <2>;
+ interrupts = <AT91_PMC_PCKRDY(2)>;
+ };
+
+ prog3: prog3 {
+ #clock-cells = <0>;
+ reg = <3>;
+ interrupts = <AT91_PMC_PCKRDY(3)>;
+ };
+ };
+
+ systemck {
+ compatible = "atmel,at91rm9200-clk-system";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ udpck: udpck {
+ #clock-cells = <0>;
+ reg = <2>;
+ clocks = <&usb>;
+ };
+
+ uhpck: uhpck {
+ #clock-cells = <0>;
+ reg = <4>;
+ clocks = <&usb>;
+ };
+
+ pck0: pck0 {
+ #clock-cells = <0>;
+ reg = <8>;
+ clocks = <&prog0>;
+ };
+
+ pck1: pck1 {
+ #clock-cells = <0>;
+ reg = <9>;
+ clocks = <&prog1>;
+ };
+
+ pck2: pck2 {
+ #clock-cells = <0>;
+ reg = <10>;
+ clocks = <&prog2>;
+ };
+
+ pck3: pck3 {
+ #clock-cells = <0>;
+ reg = <11>;
+ clocks = <&prog3>;
+ };
+ };
+
+ periphck {
+ compatible = "atmel,at91rm9200-clk-peripheral";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mck>;
+
+ pioA_clk: pioA_clk {
+ #clock-cells = <0>;
+ reg = <2>;
+ };
+
+ pioB_clk: pioB_clk {
+ #clock-cells = <0>;
+ reg = <3>;
+ };
+
+ pioC_clk: pioC_clk {
+ #clock-cells = <0>;
+ reg = <4>;
+ };
+
+ pioD_clk: pioD_clk {
+ #clock-cells = <0>;
+ reg = <5>;
+ };
+
+ usart0_clk: usart0_clk {
+ #clock-cells = <0>;
+ reg = <6>;
+ };
+
+ usart1_clk: usart1_clk {
+ #clock-cells = <0>;
+ reg = <7>;
+ };
+
+ usart2_clk: usart2_clk {
+ #clock-cells = <0>;
+ reg = <8>;
+ };
+
+ usart3_clk: usart3_clk {
+ #clock-cells = <0>;
+ reg = <9>;
+ };
+
+ mci0_clk: mci0_clk {
+ #clock-cells = <0>;
+ reg = <10>;
+ };
+
+ udc_clk: udc_clk {
+ #clock-cells = <0>;
+ reg = <11>;
+ };
+
+ twi0_clk: twi0_clk {
+ reg = <12>;
+ #clock-cells = <0>;
+ };
+
+ spi0_clk: spi0_clk {
+ #clock-cells = <0>;
+ reg = <13>;
+ };
+
+ ssc0_clk: ssc0_clk {
+ #clock-cells = <0>;
+ reg = <14>;
+ };
+
+ ssc1_clk: ssc1_clk {
+ #clock-cells = <0>;
+ reg = <15>;
+ };
+
+ ssc2_clk: ssc2_clk {
+ #clock-cells = <0>;
+ reg = <16>;
+ };
+
+ tc0_clk: tc0_clk {
+ #clock-cells = <0>;
+ reg = <17>;
+ };
+
+ tc1_clk: tc1_clk {
+ #clock-cells = <0>;
+ reg = <18>;
+ };
+
+ tc2_clk: tc2_clk {
+ #clock-cells = <0>;
+ reg = <19>;
+ };
+
+ tc3_clk: tc3_clk {
+ #clock-cells = <0>;
+ reg = <20>;
+ };
+
+ tc4_clk: tc4_clk {
+ #clock-cells = <0>;
+ reg = <21>;
+ };
+
+ tc5_clk: tc5_clk {
+ #clock-cells = <0>;
+ reg = <22>;
+ };
+
+ ohci_clk: ohci_clk {
+ #clock-cells = <0>;
+ reg = <23>;
+ };
+
+ macb0_clk: macb0_clk {
+ #clock-cells = <0>;
+ reg = <24>;
+ };
+ };
+ };
+
+ st: timer@fffffd00 {
+ compatible = "atmel,at91rm9200-st", "syscon", "simple-mfd";
+ reg = <0xfffffd00 0x100>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+
+ watchdog {
+ compatible = "atmel,at91rm9200-wdt";
+ };
+ };
+
+ rtc: rtc@fffffe00 {
+ compatible = "atmel,at91rm9200-rtc";
+ reg = <0xfffffe00 0x40>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ status = "disabled";
+ };
+
+ tcb0: timer@fffa0000 {
+ compatible = "atmel,at91rm9200-tcb";
+ reg = <0xfffa0000 0x100>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH 0
+ 18 IRQ_TYPE_LEVEL_HIGH 0
+ 19 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tc0_clk>, <&tc1_clk>, <&tc2_clk>;
+ clock-names = "t0_clk", "t1_clk", "t2_clk";
+ };
+
+ tcb1: timer@fffa4000 {
+ compatible = "atmel,at91rm9200-tcb";
+ reg = <0xfffa4000 0x100>;
+ interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0
+ 21 IRQ_TYPE_LEVEL_HIGH 0
+ 22 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tc3_clk>, <&tc4_clk>, <&tc5_clk>;
+ clock-names = "t0_clk", "t1_clk", "t2_clk";
+ };
+
+ i2c0: i2c@fffb8000 {
+ compatible = "atmel,at91rm9200-i2c";
+ reg = <0xfffb8000 0x4000>;
+ interrupts = <12 IRQ_TYPE_LEVEL_HIGH 6>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_twi>;
+ clocks = <&twi0_clk>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ mmc0: mmc@fffb4000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfffb4000 0x4000>;
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&mci0_clk>;
+ clock-names = "mci_clk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ ssc0: ssc@fffd0000 {
+ compatible = "atmel,at91rm9200-ssc";
+ reg = <0xfffd0000 0x4000>;
+ interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
+ clocks = <&ssc0_clk>;
+ clock-names = "pclk";
+ status = "disable";
+ };
+
+ ssc1: ssc@fffd4000 {
+ compatible = "atmel,at91rm9200-ssc";
+ reg = <0xfffd4000 0x4000>;
+ interrupts = <15 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
+ clocks = <&ssc1_clk>;
+ clock-names = "pclk";
+ status = "disable";
+ };
+
+ ssc2: ssc@fffd8000 {
+ compatible = "atmel,at91rm9200-ssc";
+ reg = <0xfffd8000 0x4000>;
+ interrupts = <16 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc2_tx &pinctrl_ssc2_rx>;
+ clocks = <&ssc2_clk>;
+ clock-names = "pclk";
+ status = "disable";
+ };
+
+ macb0: ethernet@fffbc000 {
+ compatible = "cdns,at91rm9200-emac", "cdns,emac";
+ reg = <0xfffbc000 0x4000>;
+ interrupts = <24 IRQ_TYPE_LEVEL_HIGH 3>;
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb_rmii>;
+ clocks = <&macb0_clk>;
+ clock-names = "ether_clk";
+ status = "disabled";
+ };
+
+ pinctrl@fffff400 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff400 0xfffff400 0x800>;
+
+ atmel,mux-mask = <
+ /* A B */
+ 0xffffffff 0xffffffff /* pioA */
+ 0xffffffff 0x083fffff /* pioB */
+ 0xffff3fff 0x00000000 /* pioC */
+ 0x03ff87ff 0x0fffff80 /* pioD */
+ >;
+
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA30 periph A */
+ AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA31 periph with pullup */
+ };
+ };
+
+ uart0 {
+ pinctrl_uart0: uart0-0 {
+ atmel,pins =
+ <AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA17 periph A */
+ AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA18 periph A */
+ };
+
+ pinctrl_uart0_cts: uart0_cts-0 {
+ atmel,pins =
+ <AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA20 periph A */
+ };
+
+ pinctrl_uart0_rts: uart0_rts-0 {
+ atmel,pins =
+ <AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA21 periph A */
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1: uart1-0 {
+ atmel,pins =
+ <AT91_PIOB 20 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PB20 periph A with pullup */
+ AT91_PIOB 21 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB21 periph A */
+ };
+
+ pinctrl_uart1_rts: uart1_rts-0 {
+ atmel,pins =
+ <AT91_PIOB 24 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB24 periph A */
+ };
+
+ pinctrl_uart1_cts: uart1_cts-0 {
+ atmel,pins =
+ <AT91_PIOB 26 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB26 periph A */
+ };
+
+ pinctrl_uart1_dtr_dsr: uart1_dtr_dsr-0 {
+ atmel,pins =
+ <AT91_PIOB 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB19 periph A */
+ AT91_PIOB 25 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB25 periph A */
+ };
+
+ pinctrl_uart1_dcd: uart1_dcd-0 {
+ atmel,pins =
+ <AT91_PIOB 23 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB23 periph A */
+ };
+
+ pinctrl_uart1_ri: uart1_ri-0 {
+ atmel,pins =
+ <AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB18 periph A */
+ };
+ };
+
+ uart2 {
+ pinctrl_uart2: uart2-0 {
+ atmel,pins =
+ <AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA22 periph A */
+ AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA23 periph A with pullup */
+ };
+
+ pinctrl_uart2_rts: uart2_rts-0 {
+ atmel,pins =
+ <AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PA30 periph B */
+ };
+
+ pinctrl_uart2_cts: uart2_cts-0 {
+ atmel,pins =
+ <AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PA31 periph B */
+ };
+ };
+
+ uart3 {
+ pinctrl_uart3: uart3-0 {
+ atmel,pins =
+ <AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PA5 periph B with pullup */
+ AT91_PIOA 6 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PA6 periph B */
+ };
+
+ pinctrl_uart3_rts: uart3_rts-0 {
+ atmel,pins =
+ <AT91_PIOB 0 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB0 periph B */
+ };
+
+ pinctrl_uart3_cts: uart3_cts-0 {
+ atmel,pins =
+ <AT91_PIOB 1 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB1 periph B */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <AT91_PIOC 2 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP /* PC2 gpio RDY pin pull_up */
+ AT91_PIOB 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>; /* PB1 gpio CD pin pull_up */
+ };
+ };
+
+ macb {
+ pinctrl_macb_rmii: macb_rmii-0 {
+ atmel,pins =
+ <AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA7 periph A */
+ AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA8 periph A */
+ AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA9 periph A */
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA10 periph A */
+ AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA11 periph A */
+ AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA12 periph A */
+ AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA13 periph A */
+ AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA14 periph A */
+ AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA15 periph A */
+ AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA16 periph A */
+ };
+
+ pinctrl_macb_rmii_mii: macb_rmii_mii-0 {
+ atmel,pins =
+ <AT91_PIOB 12 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB12 periph B */
+ AT91_PIOB 13 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB13 periph B */
+ AT91_PIOB 14 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB14 periph B */
+ AT91_PIOB 15 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB15 periph B */
+ AT91_PIOB 16 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB16 periph B */
+ AT91_PIOB 17 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB17 periph B */
+ AT91_PIOB 18 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB18 periph B */
+ AT91_PIOB 19 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB19 periph B */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_clk: mmc0_clk-0 {
+ atmel,pins =
+ <AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA27 periph A */
+ };
+
+ pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 {
+ atmel,pins =
+ <AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA28 periph A with pullup */
+ AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA29 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <AT91_PIOB 3 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PB3 periph B with pullup */
+ AT91_PIOB 4 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PB4 periph B with pullup */
+ AT91_PIOB 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* PB5 periph B with pullup */
+ };
+
+ pinctrl_mmc0_slot1_cmd_dat0: mmc0_slot1_cmd_dat0-0 {
+ atmel,pins =
+ <AT91_PIOA 8 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PA8 periph B with pullup */
+ AT91_PIOA 9 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* PA9 periph B with pullup */
+ };
+
+ pinctrl_mmc0_slot1_dat1_3: mmc0_slot1_dat1_3-0 {
+ atmel,pins =
+ <AT91_PIOA 10 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PA10 periph B with pullup */
+ AT91_PIOA 11 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PA11 periph B with pullup */
+ AT91_PIOA 12 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* PA12 periph B with pullup */
+ };
+ };
+
+ ssc0 {
+ pinctrl_ssc0_tx: ssc0_tx-0 {
+ atmel,pins =
+ <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB0 periph A */
+ AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB1 periph A */
+ AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB2 periph A */
+ };
+
+ pinctrl_ssc0_rx: ssc0_rx-0 {
+ atmel,pins =
+ <AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB3 periph A */
+ AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB4 periph A */
+ AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB5 periph A */
+ };
+ };
+
+ ssc1 {
+ pinctrl_ssc1_tx: ssc1_tx-0 {
+ atmel,pins =
+ <AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB6 periph A */
+ AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB7 periph A */
+ AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB8 periph A */
+ };
+
+ pinctrl_ssc1_rx: ssc1_rx-0 {
+ atmel,pins =
+ <AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB9 periph A */
+ AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB10 periph A */
+ AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB11 periph A */
+ };
+ };
+
+ ssc2 {
+ pinctrl_ssc2_tx: ssc2_tx-0 {
+ atmel,pins =
+ <AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB12 periph A */
+ AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB13 periph A */
+ AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB14 periph A */
+ };
+
+ pinctrl_ssc2_rx: ssc2_rx-0 {
+ atmel,pins =
+ <AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB15 periph A */
+ AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB16 periph A */
+ AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB17 periph A */
+ };
+ };
+
+ twi {
+ pinctrl_twi: twi-0 {
+ atmel,pins =
+ <AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_MULTI_DRIVE /* PA25 periph A with multi drive */
+ AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_MULTI_DRIVE>; /* PA26 periph A with multi drive */
+ };
+
+ pinctrl_twi_gpio: twi_gpio-0 {
+ atmel,pins =
+ <AT91_PIOA 25 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE /* PA25 GPIO with multi drive */
+ AT91_PIOA 26 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>; /* PA26 GPIO with multi drive */
+ };
+ };
+
+ tcb0 {
+ pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
+ atmel,pins = <AT91_PIOA 13 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
+ atmel,pins = <AT91_PIOA 14 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
+ atmel,pins = <AT91_PIOA 15 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
+ atmel,pins = <AT91_PIOA 17 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
+ atmel,pins = <AT91_PIOA 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
+ atmel,pins = <AT91_PIOA 21 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
+ atmel,pins = <AT91_PIOA 18 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
+ atmel,pins = <AT91_PIOA 20 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
+ atmel,pins = <AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ tcb1 {
+ pinctrl_tcb1_tclk0: tcb1_tclk0-0 {
+ atmel,pins = <AT91_PIOA 27 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tclk1: tcb1_tclk1-0 {
+ atmel,pins = <AT91_PIOA 28 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tclk2: tcb1_tclk2-0 {
+ atmel,pins = <AT91_PIOA 29 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tioa0: tcb1_tioa0-0 {
+ atmel,pins = <AT91_PIOB 6 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tioa1: tcb1_tioa1-0 {
+ atmel,pins = <AT91_PIOB 8 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tioa2: tcb1_tioa2-0 {
+ atmel,pins = <AT91_PIOB 10 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tiob0: tcb1_tiob0-0 {
+ atmel,pins = <AT91_PIOB 7 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tiob1: tcb1_tiob1-0 {
+ atmel,pins = <AT91_PIOB 9 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tiob2: tcb1_tiob2-0 {
+ atmel,pins = <AT91_PIOB 11 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ spi0 {
+ pinctrl_spi0: spi0-0 {
+ atmel,pins =
+ <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA0 periph A SPI0_MISO pin */
+ AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA1 periph A SPI0_MOSI pin */
+ AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA2 periph A SPI0_SPCK pin */
+ };
+ };
+
+ pioA: gpio@fffff400 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioA_clk>;
+ };
+
+ pioB: gpio@fffff600 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioB_clk>;
+ };
+
+ pioC: gpio@fffff800 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioC_clk>;
+ };
+
+ pioD: gpio@fffffa00 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x200>;
+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioD_clk>;
+ };
+ };
+
+ dbgu: serial@fffff200 {
+ compatible = "atmel,at91rm9200-dbgu", "atmel,at91rm9200-usart";
+ reg = <0xfffff200 0x200>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
+ clocks = <&mck>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart0: serial@fffc0000 {
+ compatible = "atmel,at91rm9200-usart";
+ reg = <0xfffc0000 0x200>;
+ interrupts = <6 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ clocks = <&usart0_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart1: serial@fffc4000 {
+ compatible = "atmel,at91rm9200-usart";
+ reg = <0xfffc4000 0x200>;
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ clocks = <&usart1_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart2: serial@fffc8000 {
+ compatible = "atmel,at91rm9200-usart";
+ reg = <0xfffc8000 0x200>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ clocks = <&usart2_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart3: serial@fffcc000 {
+ compatible = "atmel,at91rm9200-usart";
+ reg = <0xfffcc000 0x200>;
+ interrupts = <23 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ clocks = <&usart3_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usb1: gadget@fffb0000 {
+ compatible = "atmel,at91rm9200-udc";
+ reg = <0xfffb0000 0x4000>;
+ interrupts = <11 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&udc_clk>, <&udpck>;
+ clock-names = "pclk", "hclk";
+ status = "disabled";
+ };
+
+ spi0: spi@fffe0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xfffe0000 0x200>;
+ interrupts = <13 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi0>;
+ clocks = <&spi0_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+ };
+
+ nand0: nand@40000000 {
+ compatible = "atmel,at91rm9200-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x40000000 0x10000000>;
+ atmel,nand-addr-offset = <21>;
+ atmel,nand-cmd-offset = <22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
+ nand-ecc-mode = "soft";
+ gpios = <&pioC 2 GPIO_ACTIVE_HIGH
+ 0
+ &pioB 1 GPIO_ACTIVE_HIGH
+ >;
+ status = "disabled";
+ };
+
+ usb0: ohci@00300000 {
+ compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+ reg = <0x00300000 0x100000>;
+ interrupts = <23 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&usb>, <&ohci_clk>, <&ohci_clk>, <&uhpck>;
+ clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck";
+ status = "disabled";
+ };
+ };
+
+ i2c@0 {
+ compatible = "i2c-gpio";
+ gpios = <&pioA 25 GPIO_ACTIVE_HIGH /* sda */
+ &pioA 26 GPIO_ACTIVE_HIGH /* scl */
+ >;
+ i2c-gpio,sda-open-drain;
+ i2c-gpio,scl-open-drain;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_twi_gpio>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/at91rm9200_pqfp.dtsi b/arch/arm/boot/dts/at91rm9200_pqfp.dtsi
new file mode 100644
index 000000000..93ca66f80
--- /dev/null
+++ b/arch/arm/boot/dts/at91rm9200_pqfp.dtsi
@@ -0,0 +1,17 @@
+/*
+ * at91rm9200_pqfp.dtsi - Device Tree Include file for AT91RM9200 PQFP family SoC
+ *
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include "at91rm9200.dtsi"
+
+/ {
+ compatible = "atmel,at91rm9200-pqfp", "atmel,at91rm9200";
+};
+
+&pioD {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/at91rm9200ek.dts b/arch/arm/boot/dts/at91rm9200ek.dts
new file mode 100644
index 000000000..2a5d21247
--- /dev/null
+++ b/arch/arm/boot/dts/at91rm9200ek.dts
@@ -0,0 +1,141 @@
+/*
+ * at91rm9200ek.dts - Device Tree file for Atmel AT91RM9200 evaluation kit
+ *
+ * Copyright (C) 2012 Joachim Eastwood <manabian@gmail.com>
+ *
+ * Licensed under GPLv2 only
+ */
+/dts-v1/;
+#include "at91rm9200.dtsi"
+
+/ {
+ model = "Atmel AT91RM9200 evaluation kit";
+ compatible = "atmel,at91rm9200ek", "atmel,at91rm9200";
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <18432000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <18432000>;
+ };
+ };
+
+ ahb {
+ apb {
+ usb1: gadget@fffb0000 {
+ atmel,vbus-gpio = <&pioD 4 GPIO_ACTIVE_HIGH>;
+ atmel,pullup-gpio = <&pioD 5 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ macb0: ethernet@fffbc000 {
+ phy-mode = "rmii";
+ status = "okay";
+
+ phy0: ethernet-phy {
+ interrupt-parent = <&pioC>;
+ interrupts = <4 IRQ_TYPE_EDGE_BOTH>;
+ };
+ };
+
+ usart1: serial@fffc4000 {
+ pinctrl-0 =
+ <&pinctrl_uart1
+ &pinctrl_uart1_rts
+ &pinctrl_uart1_cts
+ &pinctrl_uart1_dtr_dsr
+ &pinctrl_uart1_dcd
+ &pinctrl_uart1_ri>;
+ status = "okay";
+ };
+
+ spi0: spi@fffe0000 {
+ status = "okay";
+ cs-gpios = <&pioA 3 0>, <0>, <0>, <0>;
+ mtd_dataflash@0 {
+ compatible = "atmel,at45", "atmel,dataflash";
+ spi-max-frequency = <15000000>;
+ reg = <0>;
+ };
+ };
+
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ rtc: rtc@fffffe00 {
+ status = "okay";
+ };
+ };
+
+ usb0: ohci@00300000 {
+ num-ports = <2>;
+ status = "okay";
+ };
+
+ nor_flash@10000000 {
+ compatible = "cfi-flash";
+ reg = <0x10000000 0x800000>;
+ linux,mtd-name = "physmap-flash.0";
+ bank-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ barebox@0 {
+ label = "barebox";
+ reg = <0x00000 0x40000>;
+ };
+
+ bareboxenv@40000 {
+ label = "bareboxenv";
+ reg = <0x40000 0x10000>;
+ };
+
+ kernel@50000 {
+ label = "kernel";
+ reg = <0x50000 0x300000>;
+ };
+
+ root@350000 {
+ label = "root";
+ reg = <0x350000 0x4B0000>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ ds2 {
+ label = "green";
+ gpios = <&pioB 0 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "mmc0";
+ };
+
+ ds4 {
+ label = "yellow";
+ gpios = <&pioB 1 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ ds6 {
+ label = "red";
+ gpios = <&pioB 2 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi
new file mode 100644
index 000000000..d88fe62a2
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -0,0 +1,1031 @@
+/*
+ * at91sam9260.dtsi - Device Tree Include file for AT91SAM9260 family SoC
+ *
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>,
+ * 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/at91.h>
+
+/ {
+ model = "Atmel AT91SAM9260 family SoC";
+ compatible = "atmel,at91sam9260";
+ interrupt-parent = <&aic>;
+
+ aliases {
+ serial0 = &dbgu;
+ serial1 = &usart0;
+ serial2 = &usart1;
+ serial3 = &usart2;
+ serial4 = &usart3;
+ serial5 = &uart0;
+ serial6 = &uart1;
+ gpio0 = &pioA;
+ gpio1 = &pioB;
+ gpio2 = &pioC;
+ tcb0 = &tcb0;
+ tcb1 = &tcb1;
+ i2c0 = &i2c0;
+ ssc0 = &ssc0;
+ };
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm926ej-s";
+ device_type = "cpu";
+ };
+ };
+
+ memory {
+ reg = <0x20000000 0x04000000>;
+ };
+
+ clocks {
+ slow_xtal: slow_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ main_xtal: main_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ adc_op_clk: adc_op_clk{
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <5000000>;
+ };
+ };
+
+ sram0: sram@002ff000 {
+ compatible = "mmio-sram";
+ reg = <0x002ff000 0x2000>;
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ aic: interrupt-controller@fffff000 {
+ #interrupt-cells = <3>;
+ compatible = "atmel,at91rm9200-aic";
+ interrupt-controller;
+ reg = <0xfffff000 0x200>;
+ atmel,external-irqs = <29 30 31>;
+ };
+
+ ramc0: ramc@ffffea00 {
+ compatible = "atmel,at91sam9260-sdramc";
+ reg = <0xffffea00 0x200>;
+ };
+
+ pmc: pmc@fffffc00 {
+ compatible = "atmel,at91sam9260-pmc";
+ reg = <0xfffffc00 0x100>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ main_osc: main_osc {
+ compatible = "atmel,at91rm9200-clk-main-osc";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MOSCS>;
+ clocks = <&main_xtal>;
+ };
+
+ main: mainck {
+ compatible = "atmel,at91rm9200-clk-main";
+ #clock-cells = <0>;
+ clocks = <&main_osc>;
+ };
+
+ slow_rc_osc: slow_rc_osc {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-accuracy = <50000000>;
+ };
+
+ clk32k: slck {
+ compatible = "atmel,at91sam9260-clk-slow";
+ #clock-cells = <0>;
+ clocks = <&slow_rc_osc>, <&slow_xtal>;
+ };
+
+ plla: pllack {
+ compatible = "atmel,at91rm9200-clk-pll";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_LOCKA>;
+ clocks = <&main>;
+ reg = <0>;
+ atmel,clk-input-range = <1000000 32000000>;
+ #atmel,pll-clk-output-range-cells = <4>;
+ atmel,pll-clk-output-ranges = <80000000 160000000 0 1>,
+ <150000000 240000000 2 1>;
+ };
+
+ pllb: pllbck {
+ compatible = "atmel,at91rm9200-clk-pll";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_LOCKB>;
+ clocks = <&main>;
+ reg = <1>;
+ atmel,clk-input-range = <1000000 5000000>;
+ #atmel,pll-clk-output-range-cells = <4>;
+ atmel,pll-clk-output-ranges = <70000000 130000000 1 1>;
+ };
+
+ mck: masterck {
+ compatible = "atmel,at91rm9200-clk-master";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MCKRDY>;
+ clocks = <&clk32k>, <&main>, <&plla>, <&pllb>;
+ atmel,clk-output-range = <0 105000000>;
+ atmel,clk-divisors = <1 2 4 0>;
+ };
+
+ usb: usbck {
+ compatible = "atmel,at91rm9200-clk-usb";
+ #clock-cells = <0>;
+ atmel,clk-divisors = <1 2 4 0>;
+ clocks = <&pllb>;
+ };
+
+ prog: progck {
+ compatible = "atmel,at91rm9200-clk-programmable";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-parent = <&pmc>;
+ clocks = <&clk32k>, <&main>, <&plla>, <&pllb>;
+
+ prog0: prog0 {
+ #clock-cells = <0>;
+ reg = <0>;
+ interrupts = <AT91_PMC_PCKRDY(0)>;
+ };
+
+ prog1: prog1 {
+ #clock-cells = <0>;
+ reg = <1>;
+ interrupts = <AT91_PMC_PCKRDY(1)>;
+ };
+ };
+
+ systemck {
+ compatible = "atmel,at91rm9200-clk-system";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ uhpck: uhpck {
+ #clock-cells = <0>;
+ reg = <6>;
+ clocks = <&usb>;
+ };
+
+ udpck: udpck {
+ #clock-cells = <0>;
+ reg = <7>;
+ clocks = <&usb>;
+ };
+
+ pck0: pck0 {
+ #clock-cells = <0>;
+ reg = <8>;
+ clocks = <&prog0>;
+ };
+
+ pck1: pck1 {
+ #clock-cells = <0>;
+ reg = <9>;
+ clocks = <&prog1>;
+ };
+ };
+
+ periphck {
+ compatible = "atmel,at91rm9200-clk-peripheral";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mck>;
+
+ pioA_clk: pioA_clk {
+ #clock-cells = <0>;
+ reg = <2>;
+ };
+
+ pioB_clk: pioB_clk {
+ #clock-cells = <0>;
+ reg = <3>;
+ };
+
+ pioC_clk: pioC_clk {
+ #clock-cells = <0>;
+ reg = <4>;
+ };
+
+ adc_clk: adc_clk {
+ #clock-cells = <0>;
+ reg = <5>;
+ };
+
+ usart0_clk: usart0_clk {
+ #clock-cells = <0>;
+ reg = <6>;
+ };
+
+ usart1_clk: usart1_clk {
+ #clock-cells = <0>;
+ reg = <7>;
+ };
+
+ usart2_clk: usart2_clk {
+ #clock-cells = <0>;
+ reg = <8>;
+ };
+
+ mci0_clk: mci0_clk {
+ #clock-cells = <0>;
+ reg = <9>;
+ };
+
+ udc_clk: udc_clk {
+ #clock-cells = <0>;
+ reg = <10>;
+ };
+
+ twi0_clk: twi0_clk {
+ reg = <11>;
+ #clock-cells = <0>;
+ };
+
+ spi0_clk: spi0_clk {
+ #clock-cells = <0>;
+ reg = <12>;
+ };
+
+ spi1_clk: spi1_clk {
+ #clock-cells = <0>;
+ reg = <13>;
+ };
+
+ ssc0_clk: ssc0_clk {
+ #clock-cells = <0>;
+ reg = <14>;
+ };
+
+ tc0_clk: tc0_clk {
+ #clock-cells = <0>;
+ reg = <17>;
+ };
+
+ tc1_clk: tc1_clk {
+ #clock-cells = <0>;
+ reg = <18>;
+ };
+
+ tc2_clk: tc2_clk {
+ #clock-cells = <0>;
+ reg = <19>;
+ };
+
+ ohci_clk: ohci_clk {
+ #clock-cells = <0>;
+ reg = <20>;
+ };
+
+ macb0_clk: macb0_clk {
+ #clock-cells = <0>;
+ reg = <21>;
+ };
+
+ isi_clk: isi_clk {
+ #clock-cells = <0>;
+ reg = <22>;
+ };
+
+ usart3_clk: usart3_clk {
+ #clock-cells = <0>;
+ reg = <23>;
+ };
+
+ uart0_clk: uart0_clk {
+ #clock-cells = <0>;
+ reg = <24>;
+ };
+
+ uart1_clk: uart1_clk {
+ #clock-cells = <0>;
+ reg = <25>;
+ };
+
+ tc3_clk: tc3_clk {
+ #clock-cells = <0>;
+ reg = <26>;
+ };
+
+ tc4_clk: tc4_clk {
+ #clock-cells = <0>;
+ reg = <27>;
+ };
+
+ tc5_clk: tc5_clk {
+ #clock-cells = <0>;
+ reg = <28>;
+ };
+ };
+ };
+
+ rstc@fffffd00 {
+ compatible = "atmel,at91sam9260-rstc";
+ reg = <0xfffffd00 0x10>;
+ };
+
+ shdwc@fffffd10 {
+ compatible = "atmel,at91sam9260-shdwc";
+ reg = <0xfffffd10 0x10>;
+ };
+
+ pit: timer@fffffd30 {
+ compatible = "atmel,at91sam9260-pit";
+ reg = <0xfffffd30 0xf>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ clocks = <&mck>;
+ };
+
+ tcb0: timer@fffa0000 {
+ compatible = "atmel,at91rm9200-tcb";
+ reg = <0xfffa0000 0x100>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH 0
+ 18 IRQ_TYPE_LEVEL_HIGH 0
+ 19 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tc0_clk>, <&tc1_clk>, <&tc2_clk>;
+ clock-names = "t0_clk", "t1_clk", "t2_clk";
+ };
+
+ tcb1: timer@fffdc000 {
+ compatible = "atmel,at91rm9200-tcb";
+ reg = <0xfffdc000 0x100>;
+ interrupts = <26 IRQ_TYPE_LEVEL_HIGH 0
+ 27 IRQ_TYPE_LEVEL_HIGH 0
+ 28 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tc3_clk>, <&tc4_clk>, <&tc5_clk>;
+ clock-names = "t0_clk", "t1_clk", "t2_clk";
+ };
+
+ pinctrl@fffff400 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff400 0xfffff400 0x600>;
+
+ atmel,mux-mask = <
+ /* A B */
+ 0xffffffff 0xffc00c3b /* pioA */
+ 0xffffffff 0x7fff3ccf /* pioB */
+ 0xffffffff 0x007fffff /* pioC */
+ >;
+
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB14 periph A */
+ AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PB15 periph with pullup */
+ };
+ };
+
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB4 periph A */
+ AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB5 periph A */
+ };
+
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <AT91_PIOB 26 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB26 periph A */
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <AT91_PIOB 27 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB27 periph A */
+ };
+
+ pinctrl_usart0_dtr_dsr: usart0_dtr_dsr-0 {
+ atmel,pins =
+ <AT91_PIOB 24 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB24 periph A */
+ AT91_PIOB 22 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB22 periph A */
+ };
+
+ pinctrl_usart0_dcd: usart0_dcd-0 {
+ atmel,pins =
+ <AT91_PIOB 23 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB23 periph A */
+ };
+
+ pinctrl_usart0_ri: usart0_ri-0 {
+ atmel,pins =
+ <AT91_PIOB 25 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB25 periph A */
+ };
+ };
+
+ usart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PB6 periph A with pullup */
+ AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB7 periph A */
+ };
+
+ pinctrl_usart1_rts: usart1_rts-0 {
+ atmel,pins =
+ <AT91_PIOB 28 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB28 periph A */
+ };
+
+ pinctrl_usart1_cts: usart1_cts-0 {
+ atmel,pins =
+ <AT91_PIOB 29 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB29 periph A */
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PB8 periph A with pullup */
+ AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB9 periph A */
+ };
+
+ pinctrl_usart2_rts: usart2_rts-0 {
+ atmel,pins =
+ <AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA4 periph A */
+ };
+
+ pinctrl_usart2_cts: usart2_cts-0 {
+ atmel,pins =
+ <AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA5 periph A */
+ };
+ };
+
+ usart3 {
+ pinctrl_usart3: usart3-0 {
+ atmel,pins =
+ <AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PB10 periph A with pullup */
+ AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB11 periph A */
+ };
+
+ pinctrl_usart3_rts: usart3_rts-0 {
+ atmel,pins =
+ <AT91_PIOC 8 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart3_cts: usart3_cts-0 {
+ atmel,pins =
+ <AT91_PIOC 10 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ uart0 {
+ pinctrl_uart0: uart0-0 {
+ atmel,pins =
+ <AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PA31 periph B with pullup */
+ AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PA30 periph B */
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1: uart1-0 {
+ atmel,pins =
+ <AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PB12 periph A with pullup */
+ AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB13 periph A */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <AT91_PIOC 13 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP /* PC13 gpio RDY pin pull_up */
+ AT91_PIOC 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>; /* PC14 gpio enable pin pull_up */
+ };
+ };
+
+ macb {
+ pinctrl_macb_rmii: macb_rmii-0 {
+ atmel,pins =
+ <AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA12 periph A */
+ AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA13 periph A */
+ AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA14 periph A */
+ AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA15 periph A */
+ AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA16 periph A */
+ AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA17 periph A */
+ AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA18 periph A */
+ AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA19 periph A */
+ AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA20 periph A */
+ AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA21 periph A */
+ };
+
+ pinctrl_macb_rmii_mii: macb_rmii_mii-0 {
+ atmel,pins =
+ <AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA22 periph B */
+ AT91_PIOA 23 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA23 periph B */
+ AT91_PIOA 24 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA24 periph B */
+ AT91_PIOA 25 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA25 periph B */
+ AT91_PIOA 26 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA26 periph B */
+ AT91_PIOA 27 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA27 periph B */
+ AT91_PIOA 28 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA28 periph B */
+ AT91_PIOA 29 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PA29 periph B */
+ };
+
+ pinctrl_macb_rmii_mii_alt: macb_rmii_mii-1 {
+ atmel,pins =
+ <AT91_PIOA 10 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA10 periph B */
+ AT91_PIOA 11 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA11 periph B */
+ AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA22 periph B */
+ AT91_PIOA 25 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA25 periph B */
+ AT91_PIOA 26 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA26 periph B */
+ AT91_PIOA 27 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA27 periph B */
+ AT91_PIOA 28 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA28 periph B */
+ AT91_PIOA 29 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PA29 periph B */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_clk: mmc0_clk-0 {
+ atmel,pins =
+ <AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA8 periph A */
+ };
+
+ pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 {
+ atmel,pins =
+ <AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA7 periph A with pullup */
+ AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA6 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA9 periph A with pullup */
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA10 periph A with pullup */
+ AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA11 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot1_cmd_dat0: mmc0_slot1_cmd_dat0-0 {
+ atmel,pins =
+ <AT91_PIOA 1 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PA1 periph B with pullup */
+ AT91_PIOA 0 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* PA0 periph B with pullup */
+ };
+
+ pinctrl_mmc0_slot1_dat1_3: mmc0_slot1_dat1_3-0 {
+ atmel,pins =
+ <AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PA5 periph B with pullup */
+ AT91_PIOA 4 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PA4 periph B with pullup */
+ AT91_PIOA 3 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* PA3 periph B with pullup */
+ };
+ };
+
+ ssc0 {
+ pinctrl_ssc0_tx: ssc0_tx-0 {
+ atmel,pins =
+ <AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB16 periph A */
+ AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB17 periph A */
+ AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB18 periph A */
+ };
+
+ pinctrl_ssc0_rx: ssc0_rx-0 {
+ atmel,pins =
+ <AT91_PIOB 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB19 periph A */
+ AT91_PIOB 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB20 periph A */
+ AT91_PIOB 21 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB21 periph A */
+ };
+ };
+
+ spi0 {
+ pinctrl_spi0: spi0-0 {
+ atmel,pins =
+ <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA0 periph A SPI0_MISO pin */
+ AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA1 periph A SPI0_MOSI pin */
+ AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA2 periph A SPI0_SPCK pin */
+ };
+ };
+
+ spi1 {
+ pinctrl_spi1: spi1-0 {
+ atmel,pins =
+ <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB0 periph A SPI1_MISO pin */
+ AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB1 periph A SPI1_MOSI pin */
+ AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB2 periph A SPI1_SPCK pin */
+ };
+ };
+
+ i2c_gpio0 {
+ pinctrl_i2c_gpio0: i2c_gpio0-0 {
+ atmel,pins =
+ <AT91_PIOA 23 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE
+ AT91_PIOA 24 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>;
+ };
+ };
+
+ tcb0 {
+ pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
+ atmel,pins = <AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
+ atmel,pins = <AT91_PIOB 6 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
+ atmel,pins = <AT91_PIOB 7 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
+ atmel,pins = <AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
+ atmel,pins = <AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
+ atmel,pins = <AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
+ atmel,pins = <AT91_PIOC 9 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
+ atmel,pins = <AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
+ atmel,pins = <AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ tcb1 {
+ pinctrl_tcb1_tclk0: tcb1_tclk0-0 {
+ atmel,pins = <AT91_PIOB 16 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tclk1: tcb1_tclk1-0 {
+ atmel,pins = <AT91_PIOB 17 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tclk2: tcb1_tclk2-0 {
+ atmel,pins = <AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tioa0: tcb1_tioa0-0 {
+ atmel,pins = <AT91_PIOB 0 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tioa1: tcb1_tioa1-0 {
+ atmel,pins = <AT91_PIOB 2 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tioa2: tcb1_tioa2-0 {
+ atmel,pins = <AT91_PIOB 3 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tiob0: tcb1_tiob0-0 {
+ atmel,pins = <AT91_PIOB 1 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tiob1: tcb1_tiob1-0 {
+ atmel,pins = <AT91_PIOB 18 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tiob2: tcb1_tiob2-0 {
+ atmel,pins = <AT91_PIOB 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ pioA: gpio@fffff400 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioA_clk>;
+ };
+
+ pioB: gpio@fffff600 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioB_clk>;
+ };
+
+ pioC: gpio@fffff800 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioC_clk>;
+ };
+ };
+
+ dbgu: serial@fffff200 {
+ compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
+ reg = <0xfffff200 0x200>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
+ clocks = <&mck>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart0: serial@fffb0000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffb0000 0x200>;
+ interrupts = <6 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
+ clocks = <&usart0_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart1: serial@fffb4000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffb4000 0x200>;
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
+ clocks = <&usart1_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart2: serial@fffb8000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffb8000 0x200>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
+ clocks = <&usart2_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart3: serial@fffd0000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffd0000 0x200>;
+ interrupts = <23 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart3>;
+ clocks = <&usart3_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ uart0: serial@fffd4000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffd4000 0x200>;
+ interrupts = <24 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ clocks = <&uart0_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ uart1: serial@fffd8000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffd8000 0x200>;
+ interrupts = <25 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ clocks = <&uart1_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ macb0: ethernet@fffc4000 {
+ compatible = "cdns,at91sam9260-macb", "cdns,macb";
+ reg = <0xfffc4000 0x100>;
+ interrupts = <21 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb_rmii>;
+ clocks = <&macb0_clk>, <&macb0_clk>;
+ clock-names = "hclk", "pclk";
+ status = "disabled";
+ };
+
+ usb1: gadget@fffa4000 {
+ compatible = "atmel,at91sam9260-udc";
+ reg = <0xfffa4000 0x4000>;
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&udc_clk>, <&udpck>;
+ clock-names = "pclk", "hclk";
+ status = "disabled";
+ };
+
+ i2c0: i2c@fffac000 {
+ compatible = "atmel,at91sam9260-i2c";
+ reg = <0xfffac000 0x100>;
+ interrupts = <11 IRQ_TYPE_LEVEL_HIGH 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&twi0_clk>;
+ status = "disabled";
+ };
+
+ mmc0: mmc@fffa8000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfffa8000 0x600>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ clocks = <&mci0_clk>;
+ clock-names = "mci_clk";
+ status = "disabled";
+ };
+
+ ssc0: ssc@fffbc000 {
+ compatible = "atmel,at91rm9200-ssc";
+ reg = <0xfffbc000 0x4000>;
+ interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
+ clocks = <&ssc0_clk>;
+ clock-names = "pclk";
+ status = "disabled";
+ };
+
+ spi0: spi@fffc8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xfffc8000 0x200>;
+ interrupts = <12 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi0>;
+ clocks = <&spi0_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+
+ spi1: spi@fffcc000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xfffcc000 0x200>;
+ interrupts = <13 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi1>;
+ clocks = <&spi1_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+
+ adc0: adc@fffe0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91sam9260-adc";
+ reg = <0xfffe0000 0x100>;
+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&adc_clk>, <&adc_op_clk>;
+ clock-names = "adc_clk", "adc_op_clk";
+ atmel,adc-use-external-triggers;
+ atmel,adc-channels-used = <0xf>;
+ atmel,adc-vref = <3300>;
+ atmel,adc-startup-time = <15>;
+ atmel,adc-res = <8 10>;
+ atmel,adc-res-names = "lowres", "highres";
+ atmel,adc-use-res = "highres";
+
+ trigger@0 {
+ reg = <0>;
+ trigger-name = "timer-counter-0";
+ trigger-value = <0x1>;
+ };
+ trigger@1 {
+ reg = <1>;
+ trigger-name = "timer-counter-1";
+ trigger-value = <0x3>;
+ };
+
+ trigger@2 {
+ reg = <2>;
+ trigger-name = "timer-counter-2";
+ trigger-value = <0x5>;
+ };
+
+ trigger@3 {
+ reg = <3>;
+ trigger-name = "external";
+ trigger-value = <0xd>;
+ trigger-external;
+ };
+ };
+
+ rtc@fffffd20 {
+ compatible = "atmel,at91sam9260-rtt";
+ reg = <0xfffffd20 0x10>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ clocks = <&clk32k>;
+ status = "disabled";
+ };
+
+ watchdog@fffffd40 {
+ compatible = "atmel,at91sam9260-wdt";
+ reg = <0xfffffd40 0x10>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ atmel,watchdog-type = "hardware";
+ atmel,reset-type = "all";
+ atmel,dbg-halt;
+ status = "disabled";
+ };
+
+ gpbr: syscon@fffffd50 {
+ compatible = "atmel,at91sam9260-gpbr", "syscon";
+ reg = <0xfffffd50 0x10>;
+ status = "disabled";
+ };
+ };
+
+ nand0: nand@40000000 {
+ compatible = "atmel,at91rm9200-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x40000000 0x10000000
+ 0xffffe800 0x200
+ >;
+ atmel,nand-addr-offset = <21>;
+ atmel,nand-cmd-offset = <22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
+ gpios = <&pioC 13 GPIO_ACTIVE_HIGH
+ &pioC 14 GPIO_ACTIVE_HIGH
+ 0
+ >;
+ status = "disabled";
+ };
+
+ usb0: ohci@00500000 {
+ compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+ reg = <0x00500000 0x100000>;
+ interrupts = <20 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&usb>, <&ohci_clk>, <&ohci_clk>, <&uhpck>;
+ clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck";
+ status = "disabled";
+ };
+ };
+
+ i2c@0 {
+ compatible = "i2c-gpio";
+ gpios = <&pioA 23 GPIO_ACTIVE_HIGH /* sda */
+ &pioA 24 GPIO_ACTIVE_HIGH /* scl */
+ >;
+ i2c-gpio,sda-open-drain;
+ i2c-gpio,scl-open-drain;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c_gpio0>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi
new file mode 100644
index 000000000..bf8d1856a
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9261.dtsi
@@ -0,0 +1,873 @@
+/*
+ * at91sam9261.dtsi - Device Tree Include file for AT91SAM9261 SoC
+ *
+ * Copyright (C) 2013 Jean-Jacques Hiblot <jjhiblot@traphandler.com>
+ *
+ * Licensed under GPLv2 only.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/at91.h>
+
+/ {
+ model = "Atmel AT91SAM9261 family SoC";
+ compatible = "atmel,at91sam9261";
+ interrupt-parent = <&aic>;
+
+ aliases {
+ serial0 = &dbgu;
+ serial1 = &usart0;
+ serial2 = &usart1;
+ serial3 = &usart2;
+ gpio0 = &pioA;
+ gpio1 = &pioB;
+ gpio2 = &pioC;
+ tcb0 = &tcb0;
+ i2c0 = &i2c0;
+ ssc0 = &ssc0;
+ ssc1 = &ssc1;
+ ssc2 = &ssc2;
+ };
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm926ej-s";
+ device_type = "cpu";
+ };
+ };
+
+ memory {
+ reg = <0x20000000 0x08000000>;
+ };
+
+ clocks {
+ main_xtal: main_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ slow_xtal: slow_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ sram: sram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x28000>;
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ usb0: ohci@00500000 {
+ compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+ reg = <0x00500000 0x100000>;
+ interrupts = <20 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&usb>, <&ohci_clk>, <&hclk0>, <&uhpck>;
+ clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck";
+ status = "disabled";
+ };
+
+ fb0: fb@0x00600000 {
+ compatible = "atmel,at91sam9261-lcdc";
+ reg = <0x00600000 0x1000>;
+ interrupts = <21 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fb>;
+ clocks = <&lcd_clk>, <&hclk1>;
+ clock-names = "lcdc_clk", "hclk";
+ status = "disabled";
+ };
+
+ nand0: nand@40000000 {
+ compatible = "atmel,at91rm9200-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x40000000 0x10000000>;
+ atmel,nand-addr-offset = <22>;
+ atmel,nand-cmd-offset = <21>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
+
+ gpios = <&pioC 15 GPIO_ACTIVE_HIGH>,
+ <&pioC 14 GPIO_ACTIVE_HIGH>,
+ <0>;
+ status = "disabled";
+ };
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ tcb0: timer@fffa0000 {
+ compatible = "atmel,at91rm9200-tcb";
+ reg = <0xfffa0000 0x100>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH 0>,
+ <18 IRQ_TYPE_LEVEL_HIGH 0>,
+ <19 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tc0_clk>, <&tc1_clk>, <&tc2_clk>;
+ clock-names = "t0_clk", "t1_clk", "t2_clk";
+ };
+
+ usb1: gadget@fffa4000 {
+ compatible = "atmel,at91sam9261-udc";
+ reg = <0xfffa4000 0x4000>;
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&udc_clk>, <&udpck>;
+ clock-names = "pclk", "hclk";
+ atmel,matrix = <&matrix>;
+ status = "disabled";
+ };
+
+ mmc0: mmc@fffa8000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfffa8000 0x600>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc0_clk>, <&pinctrl_mmc0_slot0_cmd_dat0>, <&pinctrl_mmc0_slot0_dat1_3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mci0_clk>;
+ clock-names = "mci_clk";
+ status = "disabled";
+ };
+
+ i2c0: i2c@fffac000 {
+ compatible = "atmel,at91sam9261-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c_twi>;
+ reg = <0xfffac000 0x100>;
+ interrupts = <11 IRQ_TYPE_LEVEL_HIGH 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&twi0_clk>;
+ status = "disabled";
+ };
+
+ usart0: serial@fffb0000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffb0000 0x200>;
+ interrupts = <6 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
+ clocks = <&usart0_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart1: serial@fffb4000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffb4000 0x200>;
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
+ clocks = <&usart1_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart2: serial@fffb8000{
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffb8000 0x200>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
+ clocks = <&usart2_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ ssc0: ssc@fffbc000 {
+ compatible = "atmel,at91rm9200-ssc";
+ reg = <0xfffbc000 0x4000>;
+ interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
+ clocks = <&ssc0_clk>;
+ clock-names = "pclk";
+ status = "disabled";
+ };
+
+ ssc1: ssc@fffc0000 {
+ compatible = "atmel,at91rm9200-ssc";
+ reg = <0xfffc0000 0x4000>;
+ interrupts = <15 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
+ clocks = <&ssc1_clk>;
+ clock-names = "pclk";
+ status = "disabled";
+ };
+
+ ssc2: ssc@fffc4000 {
+ compatible = "atmel,at91rm9200-ssc";
+ reg = <0xfffc4000 0x4000>;
+ interrupts = <16 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc2_tx &pinctrl_ssc2_rx>;
+ clocks = <&ssc2_clk>;
+ clock-names = "pclk";
+ status = "disabled";
+ };
+
+ spi0: spi@fffc8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xfffc8000 0x200>;
+ cs-gpios = <0>, <0>, <0>, <0>;
+ interrupts = <12 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi0>;
+ clocks = <&spi0_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+
+ spi1: spi@fffcc000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xfffcc000 0x200>;
+ interrupts = <13 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi1>;
+ clocks = <&spi1_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+
+ ramc: ramc@ffffea00 {
+ compatible = "atmel,at91sam9260-sdramc";
+ reg = <0xffffea00 0x200>;
+ };
+
+ matrix: matrix@ffffee00 {
+ compatible = "atmel,at91sam9260-bus-matrix", "syscon";
+ reg = <0xffffee00 0x200>;
+ };
+
+ aic: interrupt-controller@fffff000 {
+ #interrupt-cells = <3>;
+ compatible = "atmel,at91rm9200-aic";
+ interrupt-controller;
+ reg = <0xfffff000 0x200>;
+ atmel,external-irqs = <29 30 31>;
+ };
+
+ dbgu: serial@fffff200 {
+ compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
+ reg = <0xfffff200 0x200>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
+ clocks = <&mck>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ pinctrl@fffff400 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff400 0xfffff400 0x600>;
+
+ atmel,mux-mask =
+ /* A B */
+ <0xffffffff 0xfffffff7>, /* pioA */
+ <0xffffffff 0xfffffff4>, /* pioB */
+ <0xffffffff 0xffffff07>; /* pioC */
+
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
+ };
+ };
+
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ usart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart1_rts: usart1_rts-0 {
+ atmel,pins =
+ <AT91_PIOA 12 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart1_cts: usart1_cts-0 {
+ atmel,pins =
+ <AT91_PIOA 13 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart2_rts: usart2_rts-0 {
+ atmel,pins =
+ <AT91_PIOA 15 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart2_cts: usart2_cts-0 {
+ atmel,pins =
+ <AT91_PIOA 16 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <AT91_PIOC 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOC 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_clk: mmc0_clk-0 {
+ atmel,pins =
+ <AT91_PIOA 2 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 {
+ atmel,pins =
+ <AT91_PIOA 1 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOA 0 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <AT91_PIOA 4 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOA 6 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;
+ };
+ };
+
+ ssc0 {
+ pinctrl_ssc0_tx: ssc0_tx-0 {
+ atmel,pins =
+ <AT91_PIOB 21 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 22 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 23 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_ssc0_rx: ssc0_rx-0 {
+ atmel,pins =
+ <AT91_PIOB 24 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 25 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 26 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ ssc1 {
+ pinctrl_ssc1_tx: ssc1_tx-0 {
+ atmel,pins =
+ <AT91_PIOA 17 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOA 18 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOA 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_ssc1_rx: ssc1_rx-0 {
+ atmel,pins =
+ <AT91_PIOA 20 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOA 21 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ ssc2 {
+ pinctrl_ssc2_tx: ssc2_tx-0 {
+ atmel,pins =
+ <AT91_PIOC 25 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 26 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 27 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_ssc2_rx: ssc2_rx-0 {
+ atmel,pins =
+ <AT91_PIOC 28 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 29 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 30 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ spi0 {
+ pinctrl_spi0: spi0-0 {
+ atmel,pins =
+ <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ spi1 {
+ pinctrl_spi1: spi1-0 {
+ atmel,pins =
+ <AT91_PIOB 30 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 31 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ tcb0 {
+ pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
+ atmel,pins = <AT91_PIOC 16 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
+ atmel,pins = <AT91_PIOC 17 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
+ atmel,pins = <AT91_PIOC 18 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
+ atmel,pins = <AT91_PIOC 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
+ atmel,pins = <AT91_PIOC 21 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
+ atmel,pins = <AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
+ atmel,pins = <AT91_PIOC 20 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
+ atmel,pins = <AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
+ atmel,pins = <AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ i2c0 {
+ pinctrl_i2c_bitbang: i2c-0-bitbang {
+ atmel,pins =
+ <AT91_PIOA 7 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>,
+ <AT91_PIOA 8 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+ };
+ pinctrl_i2c_twi: i2c-0-twi {
+ atmel,pins =
+ <AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ fb {
+ pinctrl_fb: fb-0 {
+ atmel,pins =
+ <AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 19 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 20 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 23 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOB 24 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOB 25 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOB 26 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOB 27 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOB 28 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ pioA: gpio@fffff400 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioA_clk>;
+ };
+
+ pioB: gpio@fffff600 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioB_clk>;
+ };
+
+ pioC: gpio@fffff800 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioC_clk>;
+ };
+ };
+
+ pmc: pmc@fffffc00 {
+ compatible = "atmel,at91rm9200-pmc";
+ reg = <0xfffffc00 0x100>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ main_osc: main_osc {
+ compatible = "atmel,at91rm9200-clk-main-osc";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MOSCS>;
+ clocks = <&main_xtal>;
+ };
+
+ main: mainck {
+ compatible = "atmel,at91rm9200-clk-main";
+ #clock-cells = <0>;
+ clocks = <&main_osc>;
+ };
+
+ plla: pllack {
+ compatible = "atmel,at91rm9200-clk-pll";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_LOCKA>;
+ clocks = <&main>;
+ reg = <0>;
+ atmel,clk-input-range = <1000000 32000000>;
+ #atmel,pll-clk-output-range-cells = <4>;
+ atmel,pll-clk-output-ranges = <80000000 200000000 0 1>,
+ <190000000 240000000 2 1>;
+ };
+
+ pllb: pllbck {
+ compatible = "atmel,at91rm9200-clk-pll";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_LOCKB>;
+ clocks = <&main>;
+ reg = <1>;
+ atmel,clk-input-range = <1000000 5000000>;
+ #atmel,pll-clk-output-range-cells = <4>;
+ atmel,pll-clk-output-ranges = <70000000 130000000 1 1>;
+ };
+
+ mck: masterck {
+ compatible = "atmel,at91rm9200-clk-master";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MCKRDY>;
+ clocks = <&slow_xtal>, <&main>, <&plla>, <&pllb>;
+ atmel,clk-output-range = <0 94000000>;
+ atmel,clk-divisors = <1 2 4 0>;
+ };
+
+ usb: usbck {
+ compatible = "atmel,at91rm9200-clk-usb";
+ #clock-cells = <0>;
+ atmel,clk-divisors = <1 2 4 0>;
+ clocks = <&pllb>;
+ };
+
+ prog: progck {
+ compatible = "atmel,at91rm9200-clk-programmable";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-parent = <&pmc>;
+ clocks = <&slow_xtal>, <&main>, <&plla>, <&pllb>;
+
+ prog0: prog0 {
+ #clock-cells = <0>;
+ reg = <0>;
+ interrupts = <AT91_PMC_PCKRDY(0)>;
+ };
+
+ prog1: prog1 {
+ #clock-cells = <0>;
+ reg = <1>;
+ interrupts = <AT91_PMC_PCKRDY(1)>;
+ };
+
+ prog2: prog2 {
+ #clock-cells = <0>;
+ reg = <2>;
+ interrupts = <AT91_PMC_PCKRDY(2)>;
+ };
+
+ prog3: prog3 {
+ #clock-cells = <0>;
+ reg = <3>;
+ interrupts = <AT91_PMC_PCKRDY(3)>;
+ };
+ };
+
+ systemck {
+ compatible = "atmel,at91rm9200-clk-system";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ uhpck: uhpck {
+ #clock-cells = <0>;
+ reg = <6>;
+ clocks = <&usb>;
+ };
+
+ udpck: udpck {
+ #clock-cells = <0>;
+ reg = <7>;
+ clocks = <&usb>;
+ };
+
+ pck0: pck0 {
+ #clock-cells = <0>;
+ reg = <8>;
+ clocks = <&prog0>;
+ };
+
+ pck1: pck1 {
+ #clock-cells = <0>;
+ reg = <9>;
+ clocks = <&prog1>;
+ };
+
+ pck2: pck2 {
+ #clock-cells = <0>;
+ reg = <10>;
+ clocks = <&prog2>;
+ };
+
+ pck3: pck3 {
+ #clock-cells = <0>;
+ reg = <11>;
+ clocks = <&prog3>;
+ };
+
+ hclk0: hclk0 {
+ #clock-cells = <0>;
+ reg = <16>;
+ clocks = <&mck>;
+ };
+
+ hclk1: hclk1 {
+ #clock-cells = <0>;
+ reg = <17>;
+ clocks = <&mck>;
+ };
+ };
+
+ periphck {
+ compatible = "atmel,at91rm9200-clk-peripheral";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mck>;
+
+ pioA_clk: pioA_clk {
+ #clock-cells = <0>;
+ reg = <2>;
+ };
+
+ pioB_clk: pioB_clk {
+ #clock-cells = <0>;
+ reg = <3>;
+ };
+
+ pioC_clk: pioC_clk {
+ #clock-cells = <0>;
+ reg = <4>;
+ };
+
+ usart0_clk: usart0_clk {
+ #clock-cells = <0>;
+ reg = <6>;
+ };
+
+ usart1_clk: usart1_clk {
+ #clock-cells = <0>;
+ reg = <7>;
+ };
+
+ usart2_clk: usart2_clk {
+ #clock-cells = <0>;
+ reg = <8>;
+ };
+
+ mci0_clk: mci0_clk {
+ #clock-cells = <0>;
+ reg = <9>;
+ };
+
+ udc_clk: udc_clk {
+ #clock-cells = <0>;
+ reg = <10>;
+ };
+
+ twi0_clk: twi0_clk {
+ reg = <11>;
+ #clock-cells = <0>;
+ };
+
+ spi0_clk: spi0_clk {
+ #clock-cells = <0>;
+ reg = <12>;
+ };
+
+ spi1_clk: spi1_clk {
+ #clock-cells = <0>;
+ reg = <13>;
+ };
+
+ ssc0_clk: ssc0_clk {
+ #clock-cells = <0>;
+ reg = <14>;
+ };
+
+ ssc1_clk: ssc1_clk {
+ #clock-cells = <0>;
+ reg = <15>;
+ };
+
+ ssc2_clk: ssc2_clk {
+ #clock-cells = <0>;
+ reg = <16>;
+ };
+
+ tc0_clk: tc0_clk {
+ #clock-cells = <0>;
+ reg = <17>;
+ };
+
+ tc1_clk: tc1_clk {
+ #clock-cells = <0>;
+ reg = <18>;
+ };
+
+ tc2_clk: tc2_clk {
+ #clock-cells = <0>;
+ reg = <19>;
+ };
+
+ ohci_clk: ohci_clk {
+ #clock-cells = <0>;
+ reg = <20>;
+ };
+
+ lcd_clk: lcd_clk {
+ #clock-cells = <0>;
+ reg = <21>;
+ };
+ };
+ };
+
+ rstc@fffffd00 {
+ compatible = "atmel,at91sam9260-rstc";
+ reg = <0xfffffd00 0x10>;
+ };
+
+ shdwc@fffffd10 {
+ compatible = "atmel,at91sam9260-shdwc";
+ reg = <0xfffffd10 0x10>;
+ };
+
+ pit: timer@fffffd30 {
+ compatible = "atmel,at91sam9260-pit";
+ reg = <0xfffffd30 0xf>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ clocks = <&mck>;
+ };
+
+ rtc@fffffd20 {
+ compatible = "atmel,at91sam9260-rtt";
+ reg = <0xfffffd20 0x10>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ clocks = <&slow_xtal>;
+ status = "disabled";
+ };
+
+ watchdog@fffffd40 {
+ compatible = "atmel,at91sam9260-wdt";
+ reg = <0xfffffd40 0x10>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ status = "disabled";
+ };
+
+ gpbr: syscon@fffffd50 {
+ compatible = "atmel,at91sam9260-gpbr", "syscon";
+ reg = <0xfffffd50 0x10>;
+ status = "disabled";
+ };
+ };
+ };
+
+ i2c@0 {
+ compatible = "i2c-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c_bitbang>;
+ gpios = <&pioA 7 GPIO_ACTIVE_HIGH>, /* sda */
+ <&pioA 8 GPIO_ACTIVE_HIGH>; /* scl */
+ i2c-gpio,sda-open-drain;
+ i2c-gpio,scl-open-drain;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9261ek.dts b/arch/arm/boot/dts/at91sam9261ek.dts
new file mode 100644
index 000000000..f4a765729
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9261ek.dts
@@ -0,0 +1,219 @@
+/*
+ * at91sam9261ek.dts - Device Tree file for Atmel at91sam9261 reference board
+ *
+ * Copyright (C) 2013 Jean-Jacques Hiblot <jjhiblot@traphandler.com>
+ *
+ * Licensed under GPLv2 only.
+ */
+/dts-v1/;
+#include "at91sam9261.dtsi"
+
+/ {
+ model = "Atmel at91sam9261ek";
+ compatible = "atmel,at91sam9261ek", "atmel,at91sam9261", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 rootfstype=ubifs ubi.mtd=5 root=ubi0:rootfs rw";
+ };
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <18432000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <18432000>;
+ };
+ };
+
+ ahb {
+ usb0: ohci@00500000 {
+ status = "okay";
+ };
+
+ fb0: fb@0x00600000 {
+ display = <&display0>;
+ atmel,power-control-gpio = <&pioA 12 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ display0: display {
+ bits-per-pixel = <16>;
+ atmel,lcdcon-backlight;
+ atmel,dmacon = <0x1>;
+ atmel,lcdcon2 = <0x80008002>;
+ atmel,guard-time = <1>;
+ atmel,lcd-wiring-mode = "BRG";
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <4965000>;
+ hactive = <240>;
+ vactive = <320>;
+ hback-porch = <1>;
+ hfront-porch = <33>;
+ vback-porch = <1>;
+ vfront-porch = <0>;
+ hsync-len = <5>;
+ vsync-len = <1>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ };
+ };
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ bootloader@40000 {
+ label = "bootloader";
+ reg = <0x40000 0x80000>;
+ };
+
+ bootloaderenv@c0000 {
+ label = "bootloader env";
+ reg = <0xc0000 0xc0000>;
+ };
+
+ dtb@180000 {
+ label = "device tree";
+ reg = <0x180000 0x80000>;
+ };
+
+ kernel@200000 {
+ label = "kernel";
+ reg = <0x200000 0x600000>;
+ };
+
+ rootfs@800000 {
+ label = "rootfs";
+ reg = <0x800000 0x0f800000>;
+ };
+ };
+
+ apb {
+ usb1: gadget@fffa4000 {
+ atmel,vbus-gpio = <&pioB 29 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ spi0: spi@fffc8000 {
+ cs-gpios = <&pioA 3 0>, <0>, <&pioA 28 0>, <0>;
+ status = "okay";
+
+ mtd_dataflash@0 {
+ compatible = "atmel,at45", "atmel,dataflash";
+ reg = <0>;
+ spi-max-frequency = <15000000>;
+ };
+
+ tsc2046@0 {
+ reg = <2>;
+ compatible = "ti,ads7843";
+ interrupts-extended = <&pioC 2 IRQ_TYPE_EDGE_BOTH>;
+ spi-max-frequency = <3000000>;
+ pendown-gpio = <&pioC 2 GPIO_ACTIVE_HIGH>;
+
+ ti,x-min = /bits/ 16 <150>;
+ ti,x-max = /bits/ 16 <3830>;
+ ti,y-min = /bits/ 16 <190>;
+ ti,y-max = /bits/ 16 <3830>;
+ ti,vref-delay-usecs = /bits/ 16 <450>;
+ ti,x-plate-ohms = /bits/ 16 <450>;
+ ti,y-plate-ohms = /bits/ 16 <250>;
+ ti,pressure-max = /bits/ 16 <15000>;
+ ti,debounce-rep = /bits/ 16 <0>;
+ ti,debounce-tol = /bits/ 16 <65535>;
+ ti,debounce-max = /bits/ 16 <1>;
+
+ linux,wakeup;
+ };
+ };
+
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ watchdog@fffffd40 {
+ status = "okay";
+ };
+
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ ds8 {
+ label = "ds8";
+ gpios = <&pioA 13 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "none";
+ };
+
+ ds7 {
+ label = "ds7";
+ gpios = <&pioA 14 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "nand-disk";
+ };
+
+ ds1 {
+ label = "ds1";
+ gpios = <&pioA 23 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ button_0 {
+ label = "button_0";
+ gpios = <&pioA 27 GPIO_ACTIVE_LOW>;
+ linux,code = <256>;
+ gpio-key,wakeup;
+ };
+
+ button_1 {
+ label = "button_1";
+ gpios = <&pioA 26 GPIO_ACTIVE_LOW>;
+ linux,code = <257>;
+ gpio-key,wakeup;
+ };
+
+ button_2 {
+ label = "button_2";
+ gpios = <&pioA 25 GPIO_ACTIVE_LOW>;
+ linux,code = <258>;
+ gpio-key,wakeup;
+ };
+
+ button_3 {
+ label = "button_3";
+ gpios = <&pioA 24 GPIO_ACTIVE_LOW>;
+ linux,code = <259>;
+ gpio-key,wakeup;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
new file mode 100644
index 000000000..111889b55
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -0,0 +1,1031 @@
+/*
+ * at91sam9263.dtsi - Device Tree Include file for AT91SAM9263 family SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 only.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/at91.h>
+
+/ {
+ model = "Atmel AT91SAM9263 family SoC";
+ compatible = "atmel,at91sam9263";
+ interrupt-parent = <&aic>;
+
+ aliases {
+ serial0 = &dbgu;
+ serial1 = &usart0;
+ serial2 = &usart1;
+ serial3 = &usart2;
+ gpio0 = &pioA;
+ gpio1 = &pioB;
+ gpio2 = &pioC;
+ gpio3 = &pioD;
+ gpio4 = &pioE;
+ tcb0 = &tcb0;
+ i2c0 = &i2c0;
+ ssc0 = &ssc0;
+ ssc1 = &ssc1;
+ pwm0 = &pwm0;
+ };
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm926ej-s";
+ device_type = "cpu";
+ };
+ };
+
+ memory {
+ reg = <0x20000000 0x08000000>;
+ };
+
+ clocks {
+ main_xtal: main_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ slow_xtal: slow_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ sram0: sram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x14000>;
+ };
+
+ sram1: sram@00500000 {
+ compatible = "mmio-sram";
+ reg = <0x00500000 0x4000>;
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ aic: interrupt-controller@fffff000 {
+ #interrupt-cells = <3>;
+ compatible = "atmel,at91rm9200-aic";
+ interrupt-controller;
+ reg = <0xfffff000 0x200>;
+ atmel,external-irqs = <30 31>;
+ };
+
+ pmc: pmc@fffffc00 {
+ compatible = "atmel,at91rm9200-pmc";
+ reg = <0xfffffc00 0x100>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ main_osc: main_osc {
+ compatible = "atmel,at91rm9200-clk-main-osc";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MOSCS>;
+ clocks = <&main_xtal>;
+ };
+
+ main: mainck {
+ compatible = "atmel,at91rm9200-clk-main";
+ #clock-cells = <0>;
+ clocks = <&main_osc>;
+ };
+
+ plla: pllack {
+ compatible = "atmel,at91rm9200-clk-pll";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_LOCKA>;
+ clocks = <&main>;
+ reg = <0>;
+ atmel,clk-input-range = <1000000 32000000>;
+ #atmel,pll-clk-output-range-cells = <4>;
+ atmel,pll-clk-output-ranges = <80000000 200000000 0 1>,
+ <190000000 240000000 2 1>;
+ };
+
+ pllb: pllbck {
+ compatible = "atmel,at91rm9200-clk-pll";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_LOCKB>;
+ clocks = <&main>;
+ reg = <1>;
+ atmel,clk-input-range = <1000000 32000000>;
+ #atmel,pll-clk-output-range-cells = <4>;
+ atmel,pll-clk-output-ranges = <80000000 200000000 0 1>,
+ <190000000 240000000 2 1>;
+ };
+
+ mck: masterck {
+ compatible = "atmel,at91rm9200-clk-master";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MCKRDY>;
+ clocks = <&slow_xtal>, <&main>, <&plla>, <&pllb>;
+ atmel,clk-output-range = <0 120000000>;
+ atmel,clk-divisors = <1 2 4 0>;
+ };
+
+ usb: usbck {
+ compatible = "atmel,at91rm9200-clk-usb";
+ #clock-cells = <0>;
+ atmel,clk-divisors = <1 2 4 0>;
+ clocks = <&pllb>;
+ };
+
+ prog: progck {
+ compatible = "atmel,at91rm9200-clk-programmable";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-parent = <&pmc>;
+ clocks = <&slow_xtal>, <&main>, <&plla>, <&pllb>;
+
+ prog0: prog0 {
+ #clock-cells = <0>;
+ reg = <0>;
+ interrupts = <AT91_PMC_PCKRDY(0)>;
+ };
+
+ prog1: prog1 {
+ #clock-cells = <0>;
+ reg = <1>;
+ interrupts = <AT91_PMC_PCKRDY(1)>;
+ };
+
+ prog2: prog2 {
+ #clock-cells = <0>;
+ reg = <2>;
+ interrupts = <AT91_PMC_PCKRDY(2)>;
+ };
+
+ prog3: prog3 {
+ #clock-cells = <0>;
+ reg = <3>;
+ interrupts = <AT91_PMC_PCKRDY(3)>;
+ };
+ };
+
+ systemck {
+ compatible = "atmel,at91rm9200-clk-system";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ uhpck: uhpck {
+ #clock-cells = <0>;
+ reg = <6>;
+ clocks = <&usb>;
+ };
+
+ udpck: udpck {
+ #clock-cells = <0>;
+ reg = <7>;
+ clocks = <&usb>;
+ };
+
+ pck0: pck0 {
+ #clock-cells = <0>;
+ reg = <8>;
+ clocks = <&prog0>;
+ };
+
+ pck1: pck1 {
+ #clock-cells = <0>;
+ reg = <9>;
+ clocks = <&prog1>;
+ };
+
+ pck2: pck2 {
+ #clock-cells = <0>;
+ reg = <10>;
+ clocks = <&prog2>;
+ };
+
+ pck3: pck3 {
+ #clock-cells = <0>;
+ reg = <11>;
+ clocks = <&prog3>;
+ };
+ };
+
+ periphck {
+ compatible = "atmel,at91rm9200-clk-peripheral";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mck>;
+
+ pioA_clk: pioA_clk {
+ #clock-cells = <0>;
+ reg = <2>;
+ };
+
+ pioB_clk: pioB_clk {
+ #clock-cells = <0>;
+ reg = <3>;
+ };
+
+ pioCDE_clk: pioCDE_clk {
+ #clock-cells = <0>;
+ reg = <4>;
+ };
+
+ usart0_clk: usart0_clk {
+ #clock-cells = <0>;
+ reg = <7>;
+ };
+
+ usart1_clk: usart1_clk {
+ #clock-cells = <0>;
+ reg = <8>;
+ };
+
+ usart2_clk: usart2_clk {
+ #clock-cells = <0>;
+ reg = <9>;
+ };
+
+ mci0_clk: mci0_clk {
+ #clock-cells = <0>;
+ reg = <10>;
+ };
+
+ mci1_clk: mci1_clk {
+ #clock-cells = <0>;
+ reg = <11>;
+ };
+
+ can_clk: can_clk {
+ #clock-cells = <0>;
+ reg = <12>;
+ };
+
+ twi0_clk: twi0_clk {
+ #clock-cells = <0>;
+ reg = <13>;
+ };
+
+ spi0_clk: spi0_clk {
+ #clock-cells = <0>;
+ reg = <14>;
+ };
+
+ spi1_clk: spi1_clk {
+ #clock-cells = <0>;
+ reg = <15>;
+ };
+
+ ssc0_clk: ssc0_clk {
+ #clock-cells = <0>;
+ reg = <16>;
+ };
+
+ ssc1_clk: ssc1_clk {
+ #clock-cells = <0>;
+ reg = <17>;
+ };
+
+ ac97_clk: ac97_clk {
+ #clock-cells = <0>;
+ reg = <18>;
+ };
+
+ tcb_clk: tcb_clk {
+ #clock-cells = <0>;
+ reg = <19>;
+ };
+
+ pwm_clk: pwm_clk {
+ #clock-cells = <0>;
+ reg = <20>;
+ };
+
+ macb0_clk: macb0_clk {
+ #clock-cells = <0>;
+ reg = <21>;
+ };
+
+ g2de_clk: g2de_clk {
+ #clock-cells = <0>;
+ reg = <23>;
+ };
+
+ udc_clk: udc_clk {
+ #clock-cells = <0>;
+ reg = <24>;
+ };
+
+ isi_clk: isi_clk {
+ #clock-cells = <0>;
+ reg = <25>;
+ };
+
+ lcd_clk: lcd_clk {
+ #clock-cells = <0>;
+ reg = <26>;
+ };
+
+ dma_clk: dma_clk {
+ #clock-cells = <0>;
+ reg = <27>;
+ };
+
+ ohci_clk: ohci_clk {
+ #clock-cells = <0>;
+ reg = <29>;
+ };
+ };
+ };
+
+ ramc0: ramc@ffffe200 {
+ compatible = "atmel,at91sam9260-sdramc";
+ reg = <0xffffe200 0x200>;
+ };
+
+ ramc1: ramc@ffffe800 {
+ compatible = "atmel,at91sam9260-sdramc";
+ reg = <0xffffe800 0x200>;
+ };
+
+ pit: timer@fffffd30 {
+ compatible = "atmel,at91sam9260-pit";
+ reg = <0xfffffd30 0xf>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ clocks = <&mck>;
+ };
+
+ tcb0: timer@fff7c000 {
+ compatible = "atmel,at91rm9200-tcb";
+ reg = <0xfff7c000 0x100>;
+ interrupts = <19 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tcb_clk>;
+ clock-names = "t0_clk";
+ };
+
+ rstc@fffffd00 {
+ compatible = "atmel,at91sam9260-rstc";
+ reg = <0xfffffd00 0x10>;
+ };
+
+ shdwc@fffffd10 {
+ compatible = "atmel,at91sam9260-shdwc";
+ reg = <0xfffffd10 0x10>;
+ };
+
+ pinctrl@fffff200 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff200 0xfffff200 0xa00>;
+
+ atmel,mux-mask = <
+ /* A B */
+ 0xfffffffb 0xffffe07f /* pioA */
+ 0x0007ffff 0x39072fff /* pioB */
+ 0xffffffff 0x3ffffff8 /* pioC */
+ 0xfffffbff 0xffffffff /* pioD */
+ 0xffe00fff 0xfbfcff00 /* pioE */
+ >;
+
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC30 periph A */
+ AT91_PIOC 31 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PC31 periph with pullup */
+ };
+ };
+
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA26 periph A with pullup */
+ AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA27 periph A */
+ };
+
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA28 periph A */
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA29 periph A */
+ };
+ };
+
+ usart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <AT91_PIOD 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PD0 periph A with pullup */
+ AT91_PIOD 1 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD1 periph A */
+ };
+
+ pinctrl_usart1_rts: usart1_rts-0 {
+ atmel,pins =
+ <AT91_PIOD 7 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PD7 periph B */
+ };
+
+ pinctrl_usart1_cts: usart1_cts-0 {
+ atmel,pins =
+ <AT91_PIOD 8 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PD8 periph B */
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <AT91_PIOD 2 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PD2 periph A with pullup */
+ AT91_PIOD 3 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD3 periph A */
+ };
+
+ pinctrl_usart2_rts: usart2_rts-0 {
+ atmel,pins =
+ <AT91_PIOD 5 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PD5 periph B */
+ };
+
+ pinctrl_usart2_cts: usart2_cts-0 {
+ atmel,pins =
+ <AT91_PIOD 6 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PD6 periph B */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <AT91_PIOA 22 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP /* PA22 gpio RDY pin pull_up*/
+ AT91_PIOD 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>; /* PD15 gpio enable pin pull_up */
+ };
+ };
+
+ macb {
+ pinctrl_macb_rmii: macb_rmii-0 {
+ atmel,pins =
+ <AT91_PIOC 25 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC25 periph B */
+ AT91_PIOE 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE21 periph A */
+ AT91_PIOE 23 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE23 periph A */
+ AT91_PIOE 24 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE24 periph A */
+ AT91_PIOE 25 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE25 periph A */
+ AT91_PIOE 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE26 periph A */
+ AT91_PIOE 27 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE27 periph A */
+ AT91_PIOE 28 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE28 periph A */
+ AT91_PIOE 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE29 periph A */
+ AT91_PIOE 30 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PE30 periph A */
+ };
+
+ pinctrl_macb_rmii_mii: macb_rmii_mii-0 {
+ atmel,pins =
+ <AT91_PIOC 20 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC20 periph B */
+ AT91_PIOC 21 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC21 periph B */
+ AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC22 periph B */
+ AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC23 periph B */
+ AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC24 periph B */
+ AT91_PIOC 25 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC25 periph B */
+ AT91_PIOC 27 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC27 periph B */
+ AT91_PIOE 22 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PE22 periph B */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_clk: mmc0_clk-0 {
+ atmel,pins =
+ <AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA12 periph A */
+ };
+
+ pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 {
+ atmel,pins =
+ <AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA1 periph A with pullup */
+ AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA0 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA3 periph A with pullup */
+ AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA4 periph A with pullup */
+ AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA5 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot1_cmd_dat0: mmc0_slot1_cmd_dat0-0 {
+ atmel,pins =
+ <AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA16 periph A with pullup */
+ AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA17 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot1_dat1_3: mmc0_slot1_dat1_3-0 {
+ atmel,pins =
+ <AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA18 periph A with pullup */
+ AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA19 periph A with pullup */
+ AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA20 periph A with pullup */
+ };
+ };
+
+ mmc1 {
+ pinctrl_mmc1_clk: mmc1_clk-0 {
+ atmel,pins =
+ <AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA6 periph A */
+ };
+
+ pinctrl_mmc1_slot0_cmd_dat0: mmc1_slot0_cmd_dat0-0 {
+ atmel,pins =
+ <AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA7 periph A with pullup */
+ AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA8 periph A with pullup */
+ };
+
+ pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 {
+ atmel,pins =
+ <AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA9 periph A with pullup */
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA10 periph A with pullup */
+ AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA11 periph A with pullup */
+ };
+
+ pinctrl_mmc1_slot1_cmd_dat0: mmc1_slot1_cmd_dat0-0 {
+ atmel,pins =
+ <AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA21 periph A with pullup */
+ AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA22 periph A with pullup */
+ };
+
+ pinctrl_mmc1_slot1_dat1_3: mmc1_slot1_dat1_3-0 {
+ atmel,pins =
+ <AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA23 periph A with pullup */
+ AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA24 periph A with pullup */
+ AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA25 periph A with pullup */
+ };
+ };
+
+ ssc0 {
+ pinctrl_ssc0_tx: ssc0_tx-0 {
+ atmel,pins =
+ <AT91_PIOB 0 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB0 periph B */
+ AT91_PIOB 1 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB1 periph B */
+ AT91_PIOB 2 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB2 periph B */
+ };
+
+ pinctrl_ssc0_rx: ssc0_rx-0 {
+ atmel,pins =
+ <AT91_PIOB 3 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB3 periph B */
+ AT91_PIOB 4 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB4 periph B */
+ AT91_PIOB 5 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB5 periph B */
+ };
+ };
+
+ ssc1 {
+ pinctrl_ssc1_tx: ssc1_tx-0 {
+ atmel,pins =
+ <AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB6 periph A */
+ AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB7 periph A */
+ AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB8 periph A */
+ };
+
+ pinctrl_ssc1_rx: ssc1_rx-0 {
+ atmel,pins =
+ <AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB9 periph A */
+ AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB10 periph A */
+ AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB11 periph A */
+ };
+ };
+
+ spi0 {
+ pinctrl_spi0: spi0-0 {
+ atmel,pins =
+ <AT91_PIOA 0 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA0 periph B SPI0_MISO pin */
+ AT91_PIOA 1 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA1 periph B SPI0_MOSI pin */
+ AT91_PIOA 2 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PA2 periph B SPI0_SPCK pin */
+ };
+ };
+
+ spi1 {
+ pinctrl_spi1: spi1-0 {
+ atmel,pins =
+ <AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB12 periph A SPI1_MISO pin */
+ AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB13 periph A SPI1_MOSI pin */
+ AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB14 periph A SPI1_SPCK pin */
+ };
+ };
+
+ tcb0 {
+ pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
+ atmel,pins = <AT91_PIOB 28 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
+ atmel,pins = <AT91_PIOC 28 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
+ atmel,pins = <AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
+ atmel,pins = <AT91_PIOE 18 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
+ atmel,pins = <AT91_PIOE 8 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
+ atmel,pins = <AT91_PIOB 17 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
+ atmel,pins = <AT91_PIOE 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
+ atmel,pins = <AT91_PIOE 9 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
+ atmel,pins = <AT91_PIOB 18 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ fb {
+ pinctrl_fb: fb-0 {
+ atmel,pins =
+ <AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC1 periph A */
+ AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC2 periph A */
+ AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC3 periph A */
+ AT91_PIOB 9 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB9 periph B */
+ AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC6 periph A */
+ AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC7 periph A */
+ AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC8 periph A */
+ AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC9 periph A */
+ AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC10 periph A */
+ AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC11 periph A */
+ AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC14 periph A */
+ AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC15 periph A */
+ AT91_PIOC 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC16 periph A */
+ AT91_PIOC 12 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC12 periph B */
+ AT91_PIOC 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC18 periph A */
+ AT91_PIOC 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC19 periph A */
+ AT91_PIOC 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC22 periph A */
+ AT91_PIOC 23 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC23 periph A */
+ AT91_PIOC 24 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC24 periph A */
+ AT91_PIOC 17 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC17 periph B */
+ AT91_PIOC 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC26 periph A */
+ AT91_PIOC 27 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PC27 periph A */
+ };
+ };
+
+ can {
+ pinctrl_can_rx_tx: can_rx_tx {
+ atmel,pins =
+ <AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* CANRX, conflicts with IRQ0 */
+ AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* CANTX, conflicts with PCK0 */
+ };
+ };
+
+ ac97 {
+ pinctrl_ac97: ac97-0 {
+ atmel,pins =
+ <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB12 periph A AC97FS pin */
+ AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB13 periph A AC97CK pin */
+ AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB14 periph A AC97TX pin */
+ AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB14 periph A AC97RX pin */
+ };
+ };
+
+ pioA: gpio@fffff200 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff200 0x200>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioA_clk>;
+ };
+
+ pioB: gpio@fffff400 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioB_clk>;
+ };
+
+ pioC: gpio@fffff600 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioCDE_clk>;
+ };
+
+ pioD: gpio@fffff800 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioCDE_clk>;
+ };
+
+ pioE: gpio@fffffa00 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x200>;
+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioCDE_clk>;
+ };
+ };
+
+ dbgu: serial@ffffee00 {
+ compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
+ reg = <0xffffee00 0x200>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
+ clocks = <&mck>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart0: serial@fff8c000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfff8c000 0x200>;
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
+ clocks = <&usart0_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart1: serial@fff90000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfff90000 0x200>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
+ clocks = <&usart1_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart2: serial@fff94000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfff94000 0x200>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
+ clocks = <&usart2_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ ssc0: ssc@fff98000 {
+ compatible = "atmel,at91rm9200-ssc";
+ reg = <0xfff98000 0x4000>;
+ interrupts = <16 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
+ clocks = <&ssc0_clk>;
+ clock-names = "pclk";
+ status = "disabled";
+ };
+
+ ssc1: ssc@fff9c000 {
+ compatible = "atmel,at91rm9200-ssc";
+ reg = <0xfff9c000 0x4000>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
+ clocks = <&ssc1_clk>;
+ clock-names = "pclk";
+ status = "disabled";
+ };
+
+ ac97: sound@fffa0000 {
+ compatible = "atmel,at91sam9263-ac97c";
+ reg = <0xfffa0000 0x4000>;
+ interrupts = <18 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ac97>;
+ clocks = <&ac97_clk>;
+ clock-names = "ac97_clk";
+ status = "disabled";
+ };
+
+ macb0: ethernet@fffbc000 {
+ compatible = "cdns,at91sam9260-macb", "cdns,macb";
+ reg = <0xfffbc000 0x100>;
+ interrupts = <21 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb_rmii>;
+ clocks = <&macb0_clk>, <&macb0_clk>;
+ clock-names = "hclk", "pclk";
+ status = "disabled";
+ };
+
+ usb1: gadget@fff78000 {
+ compatible = "atmel,at91sam9263-udc";
+ reg = <0xfff78000 0x4000>;
+ interrupts = <24 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&udc_clk>, <&udpck>;
+ clock-names = "pclk", "hclk";
+ status = "disabled";
+ };
+
+ i2c0: i2c@fff88000 {
+ compatible = "atmel,at91sam9260-i2c";
+ reg = <0xfff88000 0x100>;
+ interrupts = <13 IRQ_TYPE_LEVEL_HIGH 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&twi0_clk>;
+ status = "disabled";
+ };
+
+ mmc0: mmc@fff80000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfff80000 0x600>;
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mci0_clk>;
+ clock-names = "mci_clk";
+ status = "disabled";
+ };
+
+ mmc1: mmc@fff84000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfff84000 0x600>;
+ interrupts = <11 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mci1_clk>;
+ clock-names = "mci_clk";
+ status = "disabled";
+ };
+
+ watchdog@fffffd40 {
+ compatible = "atmel,at91sam9260-wdt";
+ reg = <0xfffffd40 0x10>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ atmel,watchdog-type = "hardware";
+ atmel,reset-type = "all";
+ atmel,dbg-halt;
+ status = "disabled";
+ };
+
+ spi0: spi@fffa4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xfffa4000 0x200>;
+ interrupts = <14 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi0>;
+ clocks = <&spi0_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+
+ spi1: spi@fffa8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xfffa8000 0x200>;
+ interrupts = <15 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi1>;
+ clocks = <&spi1_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+
+ pwm0: pwm@fffb8000 {
+ compatible = "atmel,at91sam9rl-pwm";
+ reg = <0xfffb8000 0x300>;
+ interrupts = <20 IRQ_TYPE_LEVEL_HIGH 4>;
+ #pwm-cells = <3>;
+ clocks = <&pwm_clk>;
+ clock-names = "pwm_clk";
+ status = "disabled";
+ };
+
+ can: can@fffac000 {
+ compatible = "atmel,at91sam9263-can";
+ reg = <0xfffac000 0x300>;
+ interrupts = <12 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can_rx_tx>;
+ clocks = <&can_clk>;
+ clock-names = "can_clk";
+ };
+
+ rtc@fffffd20 {
+ compatible = "atmel,at91sam9260-rtt";
+ reg = <0xfffffd20 0x10>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ clocks = <&slow_xtal>;
+ status = "disabled";
+ };
+
+ rtc@fffffd50 {
+ compatible = "atmel,at91sam9260-rtt";
+ reg = <0xfffffd50 0x10>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ clocks = <&slow_xtal>;
+ status = "disabled";
+ };
+
+ gpbr: syscon@fffffd60 {
+ compatible = "atmel,at91sam9260-gpbr", "syscon";
+ reg = <0xfffffd60 0x50>;
+ status = "disabled";
+ };
+ };
+
+ fb0: fb@0x00700000 {
+ compatible = "atmel,at91sam9263-lcdc";
+ reg = <0x00700000 0x1000>;
+ interrupts = <26 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fb>;
+ clocks = <&lcd_clk>, <&lcd_clk>;
+ clock-names = "lcdc_clk", "hclk";
+ status = "disabled";
+ };
+
+ nand0: nand@40000000 {
+ compatible = "atmel,at91rm9200-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x40000000 0x10000000
+ 0xffffe000 0x200
+ >;
+ atmel,nand-addr-offset = <21>;
+ atmel,nand-cmd-offset = <22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
+ gpios = <&pioA 22 GPIO_ACTIVE_HIGH
+ &pioD 15 GPIO_ACTIVE_HIGH
+ 0
+ >;
+ status = "disabled";
+ };
+
+ usb0: ohci@00a00000 {
+ compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+ reg = <0x00a00000 0x100000>;
+ interrupts = <29 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&usb>, <&ohci_clk>, <&ohci_clk>, <&uhpck>;
+ clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck";
+ status = "disabled";
+ };
+ };
+
+ i2c@0 {
+ compatible = "i2c-gpio";
+ gpios = <&pioB 4 GPIO_ACTIVE_HIGH /* sda */
+ &pioB 5 GPIO_ACTIVE_HIGH /* scl */
+ >;
+ i2c-gpio,sda-open-drain;
+ i2c-gpio,scl-open-drain;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9263ek.dts b/arch/arm/boot/dts/at91sam9263ek.dts
new file mode 100644
index 000000000..5cf93eecd
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9263ek.dts
@@ -0,0 +1,235 @@
+/*
+ * at91sam9263ek.dts - Device Tree file for Atmel at91sam9263 reference board
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 only
+ */
+/dts-v1/;
+#include "at91sam9263.dtsi"
+
+/ {
+ model = "Atmel at91sam9263ek";
+ compatible = "atmel,at91sam9263ek", "atmel,at91sam9263", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock5 rw rootfstype=ubifs";
+ };
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <16367660>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <16367660>;
+ };
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@ffffee00 {
+ status = "okay";
+ };
+
+ usart0: serial@fff8c000 {
+ pinctrl-0 = <
+ &pinctrl_usart0
+ &pinctrl_usart0_rts
+ &pinctrl_usart0_cts>;
+ status = "okay";
+ };
+
+ macb0: ethernet@fffbc000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ usb1: gadget@fff78000 {
+ atmel,vbus-gpio = <&pioA 25 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ mmc0: mmc@fff80000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0
+ &pinctrl_mmc0_clk
+ &pinctrl_mmc0_slot0_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioE 18 GPIO_ACTIVE_HIGH>;
+ wp-gpios = <&pioE 19 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ pinctrl@fffff200 {
+ mmc0 {
+ pinctrl_board_mmc0: mmc0-board {
+ atmel,pins =
+ <AT91_PIOE 18 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH /* PE18 gpio CD pin pull up and deglitch */
+ AT91_PIOE 19 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>; /* PE19 gpio WP pin pull up */
+ };
+ };
+ };
+
+ spi0: spi@fffa4000 {
+ status = "okay";
+ cs-gpios = <&pioA 5 0>, <0>, <0>, <0>;
+ mtd_dataflash@0 {
+ compatible = "atmel,at45", "atmel,dataflash";
+ spi-max-frequency = <50000000>;
+ reg = <0>;
+ };
+ };
+
+ watchdog@fffffd40 {
+ status = "okay";
+ };
+ };
+
+ fb0: fb@0x00700000 {
+ display = <&display0>;
+ status = "okay";
+
+ display0: display {
+ bits-per-pixel = <16>;
+ atmel,lcdcon-backlight;
+ atmel,dmacon = <0x1>;
+ atmel,lcdcon2 = <0x80008002>;
+ atmel,guard-time = <1>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <4965000>;
+ hactive = <240>;
+ vactive = <320>;
+ hback-porch = <1>;
+ hfront-porch = <33>;
+ vback-porch = <1>;
+ vfront-porch = <0>;
+ hsync-len = <5>;
+ vsync-len = <1>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ };
+ };
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt = <1>;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x20000>;
+ };
+
+ barebox@20000 {
+ label = "barebox";
+ reg = <0x20000 0x40000>;
+ };
+
+ bareboxenv@60000 {
+ label = "bareboxenv";
+ reg = <0x60000 0x20000>;
+ };
+
+ bareboxenv2@80000 {
+ label = "bareboxenv2";
+ reg = <0x80000 0x20000>;
+ };
+
+ oftree@80000 {
+ label = "oftree";
+ reg = <0xa0000 0x20000>;
+ };
+
+ kernel@a0000 {
+ label = "kernel";
+ reg = <0xc0000 0x400000>;
+ };
+
+ rootfs@4a0000 {
+ label = "rootfs";
+ reg = <0x4c0000 0x7800000>;
+ };
+
+ data@7ca0000 {
+ label = "data";
+ reg = <0x7cc0000 0x8340000>;
+ };
+ };
+
+ usb0: ohci@00a00000 {
+ num-ports = <2>;
+ status = "okay";
+ atmel,vbus-gpio = <&pioA 24 GPIO_ACTIVE_HIGH
+ &pioA 21 GPIO_ACTIVE_HIGH
+ >;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ d3 {
+ label = "d3";
+ gpios = <&pioB 7 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ d2 {
+ label = "d2";
+ gpios = <&pioC 29 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "nand-disk";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ left_click {
+ label = "left_click";
+ gpios = <&pioC 5 GPIO_ACTIVE_LOW>;
+ linux,code = <272>;
+ gpio-key,wakeup;
+ };
+
+ right_click {
+ label = "right_click";
+ gpios = <&pioC 4 GPIO_ACTIVE_LOW>;
+ linux,code = <273>;
+ gpio-key,wakeup;
+ };
+ };
+
+ i2c@0 {
+ status = "okay";
+
+ 24c512@50 {
+ compatible = "24c512";
+ reg = <0x50>;
+ pagesize = <128>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g15.dtsi b/arch/arm/boot/dts/at91sam9g15.dtsi
new file mode 100644
index 000000000..cfd704461
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g15.dtsi
@@ -0,0 +1,28 @@
+/*
+ * at91sam9g15.dtsi - Device Tree Include file for AT91SAM9G15 SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include "at91sam9x5.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G15 SoC";
+ compatible = "atmel,at91sam9g15", "atmel,at91sam9x5";
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe0399f 0x00000000 /* pioA */
+ 0x00040000 0x00047e3f 0x00000000 /* pioB */
+ 0xfdffffff 0x00000000 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g15ek.dts b/arch/arm/boot/dts/at91sam9g15ek.dts
new file mode 100644
index 000000000..26b0444b0
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g15ek.dts
@@ -0,0 +1,16 @@
+/*
+ * at91sam9g15ek.dts - Device Tree file for AT91SAM9G15-EK board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "at91sam9g15.dtsi"
+#include "at91sam9x5ek.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G15-EK";
+ compatible = "atmel,at91sam9g15ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+};
diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi
new file mode 100644
index 000000000..f59301618
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g20.dtsi
@@ -0,0 +1,68 @@
+/*
+ * at91sam9g20.dtsi - Device Tree Include file for AT91SAM9G20 family SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include "at91sam9260.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G20 family SoC";
+ compatible = "atmel,at91sam9g20";
+
+ memory {
+ reg = <0x20000000 0x08000000>;
+ };
+
+ sram0: sram@002ff000 {
+ status = "disabled";
+ };
+
+ sram1: sram@002fc000 {
+ compatible = "mmio-sram";
+ reg = <0x002fc000 0x8000>;
+ };
+
+ ahb {
+ apb {
+ i2c0: i2c@fffac000 {
+ compatible = "atmel,at91sam9g20-i2c";
+ };
+
+ ssc0: ssc@fffbc000 {
+ compatible = "atmel,at91sam9rl-ssc";
+ };
+
+ adc0: adc@fffe0000 {
+ atmel,adc-startup-time = <40>;
+ };
+
+ pmc: pmc@fffffc00 {
+ plla: pllack {
+ atmel,clk-input-range = <2000000 32000000>;
+ atmel,pll-clk-output-ranges = <745000000 800000000 0 0>,
+ <695000000 750000000 1 0>,
+ <645000000 700000000 2 0>,
+ <595000000 650000000 3 0>,
+ <545000000 600000000 0 1>,
+ <495000000 550000000 1 1>,
+ <445000000 500000000 2 1>,
+ <400000000 450000000 3 1>;
+ };
+
+ pllb: pllbck {
+ compatible = "atmel,at91sam9g20-clk-pllb";
+ atmel,clk-input-range = <2000000 32000000>;
+ atmel,pll-clk-output-ranges = <30000000 100000000 0 0>;
+ };
+
+ mck: masterck {
+ atmel,clk-output-range = <0 133000000>;
+ atmel,clk-divisors = <1 2 4 6>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g20ek.dts b/arch/arm/boot/dts/at91sam9g20ek.dts
new file mode 100644
index 000000000..bbfd75311
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g20ek.dts
@@ -0,0 +1,29 @@
+/*
+ * at91sam9g20ek.dts - Device Tree file for Atmel at91sam9g20ek board
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+/dts-v1/;
+#include "at91sam9g20ek_common.dtsi"
+
+/ {
+ model = "Atmel at91sam9g20ek";
+ compatible = "atmel,at91sam9g20ek", "atmel,at91sam9g20", "atmel,at91sam9";
+
+ leds {
+ compatible = "gpio-leds";
+
+ ds1 {
+ label = "ds1";
+ gpios = <&pioA 9 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ ds5 {
+ label = "ds5";
+ gpios = <&pioA 6 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts b/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts
new file mode 100644
index 000000000..bdb799bad
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts
@@ -0,0 +1,55 @@
+/*
+ * at91sam9g20ek_2mmc.dts - Device Tree file for Atmel at91sam9g20ek 2 MMC board
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+/dts-v1/;
+#include "at91sam9g20ek_common.dtsi"
+
+/ {
+ model = "Atmel at91sam9g20ek 2 mmc";
+ compatible = "atmel,at91sam9g20ek_2mmc", "atmel,at91sam9g20", "atmel,at91sam9";
+
+ ahb {
+ apb{
+ mmc0: mmc@fffa8000 {
+ /* clk already mux wuth slot0 */
+ pinctrl-0 = <
+ &pinctrl_board_mmc0_slot0
+ &pinctrl_mmc0_slot0_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioC 2 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ pinctrl@fffff400 {
+ mmc0_slot0 {
+ pinctrl_board_mmc0_slot0: mmc0_slot0-board {
+ atmel,pins =
+ <AT91_PIOC 2 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PC2 gpio CD pin pull up and deglitch */
+ };
+ };
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ ds1 {
+ label = "ds1";
+ gpios = <&pioB 9 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ ds5 {
+ label = "ds5";
+ gpios = <&pioB 8 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
new file mode 100644
index 000000000..dfaacb113
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
@@ -0,0 +1,233 @@
+/*
+ * at91sam9g20ek_common.dtsi - Device Tree file for Atmel at91sam9g20ek board
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+#include "at91sam9g20.dtsi"
+
+/ {
+
+ chosen {
+ bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock5 rw rootfstype=ubifs";
+ };
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <18432000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <18432000>;
+ };
+ };
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ board {
+ pinctrl_pck0_as_mck: pck0_as_mck {
+ atmel,pins =
+ <AT91_PIOC 1 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC1 periph B */
+ };
+
+ };
+
+ mmc0_slot1 {
+ pinctrl_board_mmc0_slot1: mmc0_slot1-board {
+ atmel,pins =
+ <AT91_PIOC 9 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PC9 gpio CD pin pull up and deglitch */
+ };
+ };
+ };
+
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ usart0: serial@fffb0000 {
+ pinctrl-0 =
+ <&pinctrl_usart0
+ &pinctrl_usart0_rts
+ &pinctrl_usart0_cts
+ &pinctrl_usart0_dtr_dsr
+ &pinctrl_usart0_dcd
+ &pinctrl_usart0_ri>;
+ status = "okay";
+ };
+
+ usart1: serial@fffb4000 {
+ status = "okay";
+ };
+
+ macb0: ethernet@fffc4000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ usb1: gadget@fffa4000 {
+ atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ mmc0: mmc@fffa8000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0_slot1
+ &pinctrl_mmc0_clk
+ &pinctrl_mmc0_slot1_cmd_dat0
+ &pinctrl_mmc0_slot1_dat1_3>;
+ status = "okay";
+ slot@1 {
+ reg = <1>;
+ bus-width = <4>;
+ cd-gpios = <&pioC 9 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ ssc0: ssc@fffbc000 {
+ status = "okay";
+ pinctrl-0 = <&pinctrl_ssc0_tx>;
+ };
+
+ spi0: spi@fffc8000 {
+ cs-gpios = <0>, <&pioC 11 0>, <0>, <0>;
+ mtd_dataflash@0 {
+ compatible = "atmel,at45", "atmel,dataflash";
+ spi-max-frequency = <50000000>;
+ reg = <1>;
+ };
+ };
+
+ shdwc@fffffd10 {
+ atmel,wakeup-counter = <10>;
+ atmel,wakeup-rtt-timer;
+ };
+
+ rtc@fffffd20 {
+ atmel,rtt-rtc-time-reg = <&gpbr 0x0>;
+ status = "okay";
+ };
+
+ watchdog@fffffd40 {
+ status = "okay";
+ };
+
+ gpbr: syscon@fffffd50 {
+ status = "okay";
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x20000>;
+ };
+
+ barebox@20000 {
+ label = "barebox";
+ reg = <0x20000 0x40000>;
+ };
+
+ bareboxenv@60000 {
+ label = "bareboxenv";
+ reg = <0x60000 0x20000>;
+ };
+
+ bareboxenv2@80000 {
+ label = "bareboxenv2";
+ reg = <0x80000 0x20000>;
+ };
+
+ oftree@80000 {
+ label = "oftree";
+ reg = <0xa0000 0x20000>;
+ };
+
+ kernel@a0000 {
+ label = "kernel";
+ reg = <0xc0000 0x400000>;
+ };
+
+ rootfs@4a0000 {
+ label = "rootfs";
+ reg = <0x4c0000 0x7800000>;
+ };
+
+ data@7ca0000 {
+ label = "data";
+ reg = <0x7cc0000 0x8340000>;
+ };
+ };
+
+ usb0: ohci@00500000 {
+ num-ports = <2>;
+ status = "okay";
+ };
+ };
+
+ i2c@0 {
+ status = "okay";
+
+ 24c512@50 {
+ compatible = "24c512";
+ reg = <0x50>;
+ };
+
+ wm8731: wm8731@1b {
+ compatible = "wm8731";
+ reg = <0x1b>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ btn3 {
+ label = "Button 3";
+ gpios = <&pioA 30 GPIO_ACTIVE_LOW>;
+ linux,code = <0x103>;
+ gpio-key,wakeup;
+ };
+
+ btn4 {
+ label = "Button 4";
+ gpios = <&pioA 31 GPIO_ACTIVE_LOW>;
+ linux,code = <0x104>;
+ gpio-key,wakeup;
+ };
+ };
+
+ sound {
+ compatible = "atmel,at91sam9g20ek-wm8731-audio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pck0_as_mck>;
+
+ atmel,model = "wm8731 @ AT91SAMG20EK";
+
+ atmel,audio-routing =
+ "Ext Spk", "LHPOUT",
+ "Int Mic", "MICIN";
+
+ atmel,ssc-controller = <&ssc0>;
+ atmel,audio-codec = <&wm8731>;
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g25.dtsi b/arch/arm/boot/dts/at91sam9g25.dtsi
new file mode 100644
index 000000000..a7da0dd0c
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g25.dtsi
@@ -0,0 +1,31 @@
+/*
+ * at91sam9g25.dtsi - Device Tree Include file for AT91SAM9G25 SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include "at91sam9x5.dtsi"
+#include "at91sam9x5_isi.dtsi"
+#include "at91sam9x5_usart3.dtsi"
+#include "at91sam9x5_macb0.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G25 SoC";
+ compatible = "atmel,at91sam9g25", "atmel,at91sam9x5";
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe0399f 0xc000001c /* pioA */
+ 0x0007ffff 0x8000fe3f 0x00000000 /* pioB */
+ 0x80000000 0x07c0ffff 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g25ek.dts b/arch/arm/boot/dts/at91sam9g25ek.dts
new file mode 100644
index 000000000..707fd4ea5
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g25ek.dts
@@ -0,0 +1,43 @@
+/*
+ * at91sam9g25ek.dts - Device Tree file for AT91SAM9G25-EK board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "at91sam9g25.dtsi"
+#include "at91sam9x5ek.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G25-EK";
+ compatible = "atmel,at91sam9g25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+
+ ahb {
+ apb {
+ spi0: spi@f0000000 {
+ status = "disabled";
+ };
+
+ mmc1: mmc@f000c000 {
+ status = "disabled";
+ };
+
+ i2c0: i2c@f8010000 {
+ ov2640: camera@0x30 {
+ status = "okay";
+ };
+ };
+
+ macb0: ethernet@f802c000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ isi: isi@f8048000 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g35.dtsi b/arch/arm/boot/dts/at91sam9g35.dtsi
new file mode 100644
index 000000000..e35c2fcf8
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g35.dtsi
@@ -0,0 +1,29 @@
+/*
+ * at91sam9g35.dtsi - Device Tree Include file for AT91SAM9G35 SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include "at91sam9x5.dtsi"
+#include "at91sam9x5_macb0.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G35 SoC";
+ compatible = "atmel,at91sam9g35", "atmel,at91sam9x5";
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe0399f 0xc000000c /* pioA */
+ 0x000406ff 0x00047e3f 0x00000000 /* pioB */
+ 0xfdffffff 0x00000000 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g35ek.dts b/arch/arm/boot/dts/at91sam9g35ek.dts
new file mode 100644
index 000000000..641a9bf89
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g35ek.dts
@@ -0,0 +1,25 @@
+/*
+ * at91sam9g35ek.dts - Device Tree file for AT91SAM9G35-EK board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "at91sam9g35.dtsi"
+#include "at91sam9x5ek.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G35-EK";
+ compatible = "atmel,at91sam9g35ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+
+ ahb {
+ apb {
+ macb0: ethernet@f802c000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
new file mode 100644
index 000000000..e54421176
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -0,0 +1,1321 @@
+/*
+ * at91sam9g45.dtsi - Device Tree Include file for AT91SAM9G45 family SoC
+ * applies to AT91SAM9G45, AT91SAM9M10,
+ * AT91SAM9G46, AT91SAM9M11 SoC
+ *
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/dma/at91.h>
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/at91.h>
+
+/ {
+ model = "Atmel AT91SAM9G45 family SoC";
+ compatible = "atmel,at91sam9g45";
+ interrupt-parent = <&aic>;
+
+ aliases {
+ serial0 = &dbgu;
+ serial1 = &usart0;
+ serial2 = &usart1;
+ serial3 = &usart2;
+ serial4 = &usart3;
+ gpio0 = &pioA;
+ gpio1 = &pioB;
+ gpio2 = &pioC;
+ gpio3 = &pioD;
+ gpio4 = &pioE;
+ tcb0 = &tcb0;
+ tcb1 = &tcb1;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ ssc0 = &ssc0;
+ ssc1 = &ssc1;
+ pwm0 = &pwm0;
+ };
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm926ej-s";
+ device_type = "cpu";
+ };
+ };
+
+ memory {
+ reg = <0x70000000 0x10000000>;
+ };
+
+ clocks {
+ slow_xtal: slow_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ main_xtal: main_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ adc_op_clk: adc_op_clk{
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <300000>;
+ };
+ };
+
+ sram: sram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x10000>;
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ aic: interrupt-controller@fffff000 {
+ #interrupt-cells = <3>;
+ compatible = "atmel,at91rm9200-aic";
+ interrupt-controller;
+ reg = <0xfffff000 0x200>;
+ atmel,external-irqs = <31>;
+ };
+
+ ramc0: ramc@ffffe400 {
+ compatible = "atmel,at91sam9g45-ddramc";
+ reg = <0xffffe400 0x200>;
+ clocks = <&ddrck>;
+ clock-names = "ddrck";
+ };
+
+ ramc1: ramc@ffffe600 {
+ compatible = "atmel,at91sam9g45-ddramc";
+ reg = <0xffffe600 0x200>;
+ clocks = <&ddrck>;
+ clock-names = "ddrck";
+ };
+
+ pmc: pmc@fffffc00 {
+ compatible = "atmel,at91sam9g45-pmc";
+ reg = <0xfffffc00 0x100>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ main_osc: main_osc {
+ compatible = "atmel,at91rm9200-clk-main-osc";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MOSCS>;
+ clocks = <&main_xtal>;
+ };
+
+ main: mainck {
+ compatible = "atmel,at91rm9200-clk-main";
+ #clock-cells = <0>;
+ clocks = <&main_osc>;
+ };
+
+ plla: pllack {
+ compatible = "atmel,at91rm9200-clk-pll";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_LOCKA>;
+ clocks = <&main>;
+ reg = <0>;
+ atmel,clk-input-range = <2000000 32000000>;
+ #atmel,pll-clk-output-range-cells = <4>;
+ atmel,pll-clk-output-ranges = <745000000 800000000 0 0
+ 695000000 750000000 1 0
+ 645000000 700000000 2 0
+ 595000000 650000000 3 0
+ 545000000 600000000 0 1
+ 495000000 555000000 1 1
+ 445000000 500000000 2 1
+ 400000000 450000000 3 1>;
+ };
+
+ plladiv: plladivck {
+ compatible = "atmel,at91sam9x5-clk-plldiv";
+ #clock-cells = <0>;
+ clocks = <&plla>;
+ };
+
+ utmi: utmick {
+ compatible = "atmel,at91sam9x5-clk-utmi";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_LOCKU>;
+ clocks = <&main>;
+ };
+
+ mck: masterck {
+ compatible = "atmel,at91rm9200-clk-master";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MCKRDY>;
+ clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>;
+ atmel,clk-output-range = <0 133333333>;
+ atmel,clk-divisors = <1 2 4 3>;
+ };
+
+ usb: usbck {
+ compatible = "atmel,at91sam9x5-clk-usb";
+ #clock-cells = <0>;
+ clocks = <&plladiv>, <&utmi>;
+ };
+
+ prog: progck {
+ compatible = "atmel,at91sam9g45-clk-programmable";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-parent = <&pmc>;
+ clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>;
+
+ prog0: prog0 {
+ #clock-cells = <0>;
+ reg = <0>;
+ interrupts = <AT91_PMC_PCKRDY(0)>;
+ };
+
+ prog1: prog1 {
+ #clock-cells = <0>;
+ reg = <1>;
+ interrupts = <AT91_PMC_PCKRDY(1)>;
+ };
+ };
+
+ systemck {
+ compatible = "atmel,at91rm9200-clk-system";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ddrck: ddrck {
+ #clock-cells = <0>;
+ reg = <2>;
+ clocks = <&mck>;
+ };
+
+ uhpck: uhpck {
+ #clock-cells = <0>;
+ reg = <6>;
+ clocks = <&usb>;
+ };
+
+ pck0: pck0 {
+ #clock-cells = <0>;
+ reg = <8>;
+ clocks = <&prog0>;
+ };
+
+ pck1: pck1 {
+ #clock-cells = <0>;
+ reg = <9>;
+ clocks = <&prog1>;
+ };
+ };
+
+ periphck {
+ compatible = "atmel,at91rm9200-clk-peripheral";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mck>;
+
+ pioA_clk: pioA_clk {
+ #clock-cells = <0>;
+ reg = <2>;
+ };
+
+ pioB_clk: pioB_clk {
+ #clock-cells = <0>;
+ reg = <3>;
+ };
+
+ pioC_clk: pioC_clk {
+ #clock-cells = <0>;
+ reg = <4>;
+ };
+
+ pioDE_clk: pioDE_clk {
+ #clock-cells = <0>;
+ reg = <5>;
+ };
+
+ trng_clk: trng_clk {
+ #clock-cells = <0>;
+ reg = <6>;
+ };
+
+ usart0_clk: usart0_clk {
+ #clock-cells = <0>;
+ reg = <7>;
+ };
+
+ usart1_clk: usart1_clk {
+ #clock-cells = <0>;
+ reg = <8>;
+ };
+
+ usart2_clk: usart2_clk {
+ #clock-cells = <0>;
+ reg = <9>;
+ };
+
+ usart3_clk: usart3_clk {
+ #clock-cells = <0>;
+ reg = <10>;
+ };
+
+ mci0_clk: mci0_clk {
+ #clock-cells = <0>;
+ reg = <11>;
+ };
+
+ twi0_clk: twi0_clk {
+ #clock-cells = <0>;
+ reg = <12>;
+ };
+
+ twi1_clk: twi1_clk {
+ #clock-cells = <0>;
+ reg = <13>;
+ };
+
+ spi0_clk: spi0_clk {
+ #clock-cells = <0>;
+ reg = <14>;
+ };
+
+ spi1_clk: spi1_clk {
+ #clock-cells = <0>;
+ reg = <15>;
+ };
+
+ ssc0_clk: ssc0_clk {
+ #clock-cells = <0>;
+ reg = <16>;
+ };
+
+ ssc1_clk: ssc1_clk {
+ #clock-cells = <0>;
+ reg = <17>;
+ };
+
+ tcb0_clk: tcb0_clk {
+ #clock-cells = <0>;
+ reg = <18>;
+ };
+
+ pwm_clk: pwm_clk {
+ #clock-cells = <0>;
+ reg = <19>;
+ };
+
+ adc_clk: adc_clk {
+ #clock-cells = <0>;
+ reg = <20>;
+ };
+
+ dma0_clk: dma0_clk {
+ #clock-cells = <0>;
+ reg = <21>;
+ };
+
+ uhphs_clk: uhphs_clk {
+ #clock-cells = <0>;
+ reg = <22>;
+ };
+
+ lcd_clk: lcd_clk {
+ #clock-cells = <0>;
+ reg = <23>;
+ };
+
+ ac97_clk: ac97_clk {
+ #clock-cells = <0>;
+ reg = <24>;
+ };
+
+ macb0_clk: macb0_clk {
+ #clock-cells = <0>;
+ reg = <25>;
+ };
+
+ isi_clk: isi_clk {
+ #clock-cells = <0>;
+ reg = <26>;
+ };
+
+ udphs_clk: udphs_clk {
+ #clock-cells = <0>;
+ reg = <27>;
+ };
+
+ aestdessha_clk: aestdessha_clk {
+ #clock-cells = <0>;
+ reg = <28>;
+ };
+
+ mci1_clk: mci1_clk {
+ #clock-cells = <0>;
+ reg = <29>;
+ };
+
+ vdec_clk: vdec_clk {
+ #clock-cells = <0>;
+ reg = <30>;
+ };
+ };
+ };
+
+ rstc@fffffd00 {
+ compatible = "atmel,at91sam9g45-rstc";
+ reg = <0xfffffd00 0x10>;
+ };
+
+ pit: timer@fffffd30 {
+ compatible = "atmel,at91sam9260-pit";
+ reg = <0xfffffd30 0xf>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ clocks = <&mck>;
+ };
+
+
+ shdwc@fffffd10 {
+ compatible = "atmel,at91sam9rl-shdwc";
+ reg = <0xfffffd10 0x10>;
+ };
+
+ tcb0: timer@fff7c000 {
+ compatible = "atmel,at91rm9200-tcb";
+ reg = <0xfff7c000 0x100>;
+ interrupts = <18 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tcb0_clk>, <&tcb0_clk>, <&tcb0_clk>;
+ clock-names = "t0_clk", "t1_clk", "t2_clk";
+ };
+
+ tcb1: timer@fffd4000 {
+ compatible = "atmel,at91rm9200-tcb";
+ reg = <0xfffd4000 0x100>;
+ interrupts = <18 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tcb0_clk>, <&tcb0_clk>, <&tcb0_clk>;
+ clock-names = "t0_clk", "t1_clk", "t2_clk";
+ };
+
+ dma: dma-controller@ffffec00 {
+ compatible = "atmel,at91sam9g45-dma";
+ reg = <0xffffec00 0x200>;
+ interrupts = <21 IRQ_TYPE_LEVEL_HIGH 0>;
+ #dma-cells = <2>;
+ clocks = <&dma0_clk>;
+ clock-names = "dma_clk";
+ };
+
+ pinctrl@fffff200 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff200 0xfffff200 0xa00>;
+
+ atmel,mux-mask = <
+ /* A B */
+ 0xffffffff 0xffc003ff /* pioA */
+ 0xffffffff 0x800f8f00 /* pioB */
+ 0xffffffff 0x00000e00 /* pioC */
+ 0xffffffff 0xff0c1381 /* pioD */
+ 0xffffffff 0x81ffff81 /* pioE */
+ >;
+
+ /* shared pinctrl settings */
+ adc0 {
+ pinctrl_adc0_adtrg: adc0_adtrg {
+ atmel,pins = <AT91_PIOD 28 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ pinctrl_adc0_ad0: adc0_ad0 {
+ atmel,pins = <AT91_PIOD 20 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+ };
+ pinctrl_adc0_ad1: adc0_ad1 {
+ atmel,pins = <AT91_PIOD 21 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+ };
+ pinctrl_adc0_ad2: adc0_ad2 {
+ atmel,pins = <AT91_PIOD 22 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+ };
+ pinctrl_adc0_ad3: adc0_ad3 {
+ atmel,pins = <AT91_PIOD 23 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+ };
+ pinctrl_adc0_ad4: adc0_ad4 {
+ atmel,pins = <AT91_PIOD 24 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+ };
+ pinctrl_adc0_ad5: adc0_ad5 {
+ atmel,pins = <AT91_PIOD 25 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+ };
+ pinctrl_adc0_ad6: adc0_ad6 {
+ atmel,pins = <AT91_PIOD 26 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+ };
+ pinctrl_adc0_ad7: adc0_ad7 {
+ atmel,pins = <AT91_PIOD 27 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+ };
+ };
+
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB12 periph A */
+ AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB13 periph A */
+ };
+ };
+
+ i2c0 {
+ pinctrl_i2c0: i2c0-0 {
+ atmel,pins =
+ <AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA21 periph A TWCK0 */
+ AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA20 periph A TWD0 */
+ };
+ };
+
+ i2c1 {
+ pinctrl_i2c1: i2c1-0 {
+ atmel,pins =
+ <AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB11 periph A TWCK1 */
+ AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB10 periph A TWD1 */
+ };
+ };
+
+ isi {
+ pinctrl_isi: isi-0 {
+ atmel,pins = <AT91_PIOB 8 AT91_PERIPH_B AT91_PINCTRL_NONE /* D8 */
+ AT91_PIOB 9 AT91_PERIPH_B AT91_PINCTRL_NONE /* D9 */
+ AT91_PIOB 10 AT91_PERIPH_B AT91_PINCTRL_NONE /* D10 */
+ AT91_PIOB 11 AT91_PERIPH_B AT91_PINCTRL_NONE /* D11 */
+ AT91_PIOB 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* D0 */
+ AT91_PIOB 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* D1 */
+ AT91_PIOB 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* D2 */
+ AT91_PIOB 23 AT91_PERIPH_A AT91_PINCTRL_NONE /* D3 */
+ AT91_PIOB 24 AT91_PERIPH_A AT91_PINCTRL_NONE /* D4 */
+ AT91_PIOB 25 AT91_PERIPH_A AT91_PINCTRL_NONE /* D5 */
+ AT91_PIOB 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* D6 */
+ AT91_PIOB 27 AT91_PERIPH_A AT91_PINCTRL_NONE /* D7 */
+ AT91_PIOB 28 AT91_PERIPH_A AT91_PINCTRL_NONE /* PCK */
+ AT91_PIOB 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* VSYNC */
+ AT91_PIOB 30 AT91_PERIPH_A AT91_PINCTRL_NONE /* HSYNC */
+ AT91_PIOB 31 AT91_PERIPH_A AT91_PINCTRL_NONE /* MCK */>;
+ };
+ };
+
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <AT91_PIOB 19 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PB19 periph A with pullup */
+ AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB18 periph A */
+ };
+
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <AT91_PIOB 17 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB17 periph B */
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <AT91_PIOB 15 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB15 periph B */
+ };
+ };
+
+ uart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PB4 periph A with pullup */
+ AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB5 periph A */
+ };
+
+ pinctrl_usart1_rts: usart1_rts-0 {
+ atmel,pins =
+ <AT91_PIOD 16 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD16 periph A */
+ };
+
+ pinctrl_usart1_cts: usart1_cts-0 {
+ atmel,pins =
+ <AT91_PIOD 17 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD17 periph A */
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PB6 periph A with pullup */
+ AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB7 periph A */
+ };
+
+ pinctrl_usart2_rts: usart2_rts-0 {
+ atmel,pins =
+ <AT91_PIOC 9 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC9 periph B */
+ };
+
+ pinctrl_usart2_cts: usart2_cts-0 {
+ atmel,pins =
+ <AT91_PIOC 11 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC11 periph B */
+ };
+ };
+
+ usart3 {
+ pinctrl_usart3: usart3-0 {
+ atmel,pins =
+ <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PB9 periph A with pullup */
+ AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB8 periph A */
+ };
+
+ pinctrl_usart3_rts: usart3_rts-0 {
+ atmel,pins =
+ <AT91_PIOA 23 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PA23 periph B */
+ };
+
+ pinctrl_usart3_cts: usart3_cts-0 {
+ atmel,pins =
+ <AT91_PIOA 24 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PA24 periph B */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <AT91_PIOC 8 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP /* PC8 gpio RDY pin pull_up*/
+ AT91_PIOC 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>; /* PC14 gpio enable pin pull_up */
+ };
+ };
+
+ macb {
+ pinctrl_macb_rmii: macb_rmii-0 {
+ atmel,pins =
+ <AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA10 periph A */
+ AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA11 periph A */
+ AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA12 periph A */
+ AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA13 periph A */
+ AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA14 periph A */
+ AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA15 periph A */
+ AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA16 periph A */
+ AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA17 periph A */
+ AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA18 periph A */
+ AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA19 periph A */
+ };
+
+ pinctrl_macb_rmii_mii: macb_rmii_mii-0 {
+ atmel,pins =
+ <AT91_PIOA 6 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA6 periph B */
+ AT91_PIOA 7 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA7 periph B */
+ AT91_PIOA 8 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA8 periph B */
+ AT91_PIOA 9 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA9 periph B */
+ AT91_PIOA 27 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA27 periph B */
+ AT91_PIOA 28 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA28 periph B */
+ AT91_PIOA 29 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA29 periph B */
+ AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PA30 periph B */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 {
+ atmel,pins =
+ <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA0 periph A */
+ AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA1 periph A with pullup */
+ AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA2 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA3 periph A with pullup */
+ AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA4 periph A with pullup */
+ AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA5 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat4_7: mmc0_slot0_dat4_7-0 {
+ atmel,pins =
+ <AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA6 periph A with pullup */
+ AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA7 periph A with pullup */
+ AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA8 periph A with pullup */
+ AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA9 periph A with pullup */
+ };
+ };
+
+ mmc1 {
+ pinctrl_mmc1_slot0_clk_cmd_dat0: mmc1_slot0_clk_cmd_dat0-0 {
+ atmel,pins =
+ <AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA31 periph A */
+ AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA22 periph A with pullup */
+ AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA23 periph A with pullup */
+ };
+
+ pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 {
+ atmel,pins =
+ <AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA24 periph A with pullup */
+ AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA25 periph A with pullup */
+ AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA26 periph A with pullup */
+ };
+
+ pinctrl_mmc1_slot0_dat4_7: mmc1_slot0_dat4_7-0 {
+ atmel,pins =
+ <AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA27 periph A with pullup */
+ AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA28 periph A with pullup */
+ AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA29 periph A with pullup */
+ AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA30 periph A with pullup */
+ };
+ };
+
+ ssc0 {
+ pinctrl_ssc0_tx: ssc0_tx-0 {
+ atmel,pins =
+ <AT91_PIOD 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD0 periph A */
+ AT91_PIOD 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD1 periph A */
+ AT91_PIOD 2 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD2 periph A */
+ };
+
+ pinctrl_ssc0_rx: ssc0_rx-0 {
+ atmel,pins =
+ <AT91_PIOD 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD3 periph A */
+ AT91_PIOD 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD4 periph A */
+ AT91_PIOD 5 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD5 periph A */
+ };
+ };
+
+ ssc1 {
+ pinctrl_ssc1_tx: ssc1_tx-0 {
+ atmel,pins =
+ <AT91_PIOD 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD10 periph A */
+ AT91_PIOD 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD11 periph A */
+ AT91_PIOD 12 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD12 periph A */
+ };
+
+ pinctrl_ssc1_rx: ssc1_rx-0 {
+ atmel,pins =
+ <AT91_PIOD 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD13 periph A */
+ AT91_PIOD 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD14 periph A */
+ AT91_PIOD 15 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD15 periph A */
+ };
+ };
+
+ spi0 {
+ pinctrl_spi0: spi0-0 {
+ atmel,pins =
+ <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB0 periph A SPI0_MISO pin */
+ AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB1 periph A SPI0_MOSI pin */
+ AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB2 periph A SPI0_SPCK pin */
+ };
+ };
+
+ spi1 {
+ pinctrl_spi1: spi1-0 {
+ atmel,pins =
+ <AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB14 periph A SPI1_MISO pin */
+ AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB15 periph A SPI1_MOSI pin */
+ AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB16 periph A SPI1_SPCK pin */
+ };
+ };
+
+ tcb0 {
+ pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
+ atmel,pins = <AT91_PIOD 23 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
+ atmel,pins = <AT91_PIOD 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
+ atmel,pins = <AT91_PIOC 10 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
+ atmel,pins = <AT91_PIOD 20 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
+ atmel,pins = <AT91_PIOD 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
+ atmel,pins = <AT91_PIOD 22 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
+ atmel,pins = <AT91_PIOD 30 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
+ atmel,pins = <AT91_PIOD 31 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
+ atmel,pins = <AT91_PIOA 26 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ tcb1 {
+ pinctrl_tcb1_tclk0: tcb1_tclk0-0 {
+ atmel,pins = <AT91_PIOA 0 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tclk1: tcb1_tclk1-0 {
+ atmel,pins = <AT91_PIOA 3 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tclk2: tcb1_tclk2-0 {
+ atmel,pins = <AT91_PIOD 9 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tioa0: tcb1_tioa0-0 {
+ atmel,pins = <AT91_PIOA 1 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tioa1: tcb1_tioa1-0 {
+ atmel,pins = <AT91_PIOA 4 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tioa2: tcb1_tioa2-0 {
+ atmel,pins = <AT91_PIOD 7 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tiob0: tcb1_tiob0-0 {
+ atmel,pins = <AT91_PIOA 2 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tiob1: tcb1_tiob1-0 {
+ atmel,pins = <AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tiob2: tcb1_tiob2-0 {
+ atmel,pins = <AT91_PIOD 8 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ fb {
+ pinctrl_fb: fb-0 {
+ atmel,pins =
+ <AT91_PIOE 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE0 periph A */
+ AT91_PIOE 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE2 periph A */
+ AT91_PIOE 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE3 periph A */
+ AT91_PIOE 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE4 periph A */
+ AT91_PIOE 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE5 periph A */
+ AT91_PIOE 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE6 periph A */
+ AT91_PIOE 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE7 periph A */
+ AT91_PIOE 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE8 periph A */
+ AT91_PIOE 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE9 periph A */
+ AT91_PIOE 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE10 periph A */
+ AT91_PIOE 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE11 periph A */
+ AT91_PIOE 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE12 periph A */
+ AT91_PIOE 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE13 periph A */
+ AT91_PIOE 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE14 periph A */
+ AT91_PIOE 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE15 periph A */
+ AT91_PIOE 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE16 periph A */
+ AT91_PIOE 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE17 periph A */
+ AT91_PIOE 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE18 periph A */
+ AT91_PIOE 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE19 periph A */
+ AT91_PIOE 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE20 periph A */
+ AT91_PIOE 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE21 periph A */
+ AT91_PIOE 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE22 periph A */
+ AT91_PIOE 23 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE23 periph A */
+ AT91_PIOE 24 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE24 periph A */
+ AT91_PIOE 25 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE25 periph A */
+ AT91_PIOE 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE26 periph A */
+ AT91_PIOE 27 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE27 periph A */
+ AT91_PIOE 28 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE28 periph A */
+ AT91_PIOE 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE29 periph A */
+ AT91_PIOE 30 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PE30 periph A */
+ };
+ };
+
+ pioA: gpio@fffff200 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff200 0x200>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioA_clk>;
+ };
+
+ pioB: gpio@fffff400 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioB_clk>;
+ };
+
+ pioC: gpio@fffff600 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioC_clk>;
+ };
+
+ pioD: gpio@fffff800 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioDE_clk>;
+ };
+
+ pioE: gpio@fffffa00 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x200>;
+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioDE_clk>;
+ };
+ };
+
+ dbgu: serial@ffffee00 {
+ compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
+ reg = <0xffffee00 0x200>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
+ clocks = <&mck>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart0: serial@fff8c000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfff8c000 0x200>;
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
+ clocks = <&usart0_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart1: serial@fff90000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfff90000 0x200>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
+ clocks = <&usart1_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart2: serial@fff94000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfff94000 0x200>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
+ clocks = <&usart2_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart3: serial@fff98000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfff98000 0x200>;
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart3>;
+ clocks = <&usart3_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ macb0: ethernet@fffbc000 {
+ compatible = "cdns,at91sam9260-macb", "cdns,macb";
+ reg = <0xfffbc000 0x100>;
+ interrupts = <25 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb_rmii>;
+ clocks = <&macb0_clk>, <&macb0_clk>;
+ clock-names = "hclk", "pclk";
+ status = "disabled";
+ };
+
+ trng@fffcc000 {
+ compatible = "atmel,at91sam9g45-trng";
+ reg = <0xfffcc000 0x4000>;
+ interrupts = <6 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&trng_clk>;
+ };
+
+ i2c0: i2c@fff84000 {
+ compatible = "atmel,at91sam9g10-i2c";
+ reg = <0xfff84000 0x100>;
+ interrupts = <12 IRQ_TYPE_LEVEL_HIGH 6>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&twi0_clk>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@fff88000 {
+ compatible = "atmel,at91sam9g10-i2c";
+ reg = <0xfff88000 0x100>;
+ interrupts = <13 IRQ_TYPE_LEVEL_HIGH 6>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&twi1_clk>;
+ status = "disabled";
+ };
+
+ ssc0: ssc@fff9c000 {
+ compatible = "atmel,at91sam9g45-ssc";
+ reg = <0xfff9c000 0x4000>;
+ interrupts = <16 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
+ clocks = <&ssc0_clk>;
+ clock-names = "pclk";
+ status = "disabled";
+ };
+
+ ssc1: ssc@fffa0000 {
+ compatible = "atmel,at91sam9g45-ssc";
+ reg = <0xfffa0000 0x4000>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
+ clocks = <&ssc1_clk>;
+ clock-names = "pclk";
+ status = "disabled";
+ };
+
+ adc0: adc@fffb0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91sam9g45-adc";
+ reg = <0xfffb0000 0x100>;
+ interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&adc_clk>, <&adc_op_clk>;
+ clock-names = "adc_clk", "adc_op_clk";
+ atmel,adc-channels-used = <0xff>;
+ atmel,adc-vref = <3300>;
+ atmel,adc-startup-time = <40>;
+ atmel,adc-res = <8 10>;
+ atmel,adc-res-names = "lowres", "highres";
+ atmel,adc-use-res = "highres";
+
+ trigger@0 {
+ reg = <0>;
+ trigger-name = "external-rising";
+ trigger-value = <0x1>;
+ trigger-external;
+ };
+ trigger@1 {
+ reg = <1>;
+ trigger-name = "external-falling";
+ trigger-value = <0x2>;
+ trigger-external;
+ };
+
+ trigger@2 {
+ reg = <2>;
+ trigger-name = "external-any";
+ trigger-value = <0x3>;
+ trigger-external;
+ };
+
+ trigger@3 {
+ reg = <3>;
+ trigger-name = "continuous";
+ trigger-value = <0x6>;
+ };
+ };
+
+ isi@fffb4000 {
+ compatible = "atmel,at91sam9g45-isi";
+ reg = <0xfffb4000 0x4000>;
+ interrupts = <26 IRQ_TYPE_LEVEL_HIGH 5>;
+ clocks = <&isi_clk>;
+ clock-names = "isi_clk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_isi>;
+ status = "disabled";
+ };
+
+ pwm0: pwm@fffb8000 {
+ compatible = "atmel,at91sam9rl-pwm";
+ reg = <0xfffb8000 0x300>;
+ interrupts = <19 IRQ_TYPE_LEVEL_HIGH 4>;
+ #pwm-cells = <3>;
+ clocks = <&pwm_clk>;
+ status = "disabled";
+ };
+
+ mmc0: mmc@fff80000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfff80000 0x600>;
+ interrupts = <11 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-names = "default";
+ dmas = <&dma 1 AT91_DMA_CFG_PER_ID(0)>;
+ dma-names = "rxtx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mci0_clk>;
+ clock-names = "mci_clk";
+ status = "disabled";
+ };
+
+ mmc1: mmc@fffd0000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfffd0000 0x600>;
+ interrupts = <29 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-names = "default";
+ dmas = <&dma 1 AT91_DMA_CFG_PER_ID(13)>;
+ dma-names = "rxtx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mci1_clk>;
+ clock-names = "mci_clk";
+ status = "disabled";
+ };
+
+ watchdog@fffffd40 {
+ compatible = "atmel,at91sam9260-wdt";
+ reg = <0xfffffd40 0x10>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ atmel,watchdog-type = "hardware";
+ atmel,reset-type = "all";
+ atmel,dbg-halt;
+ status = "disabled";
+ };
+
+ spi0: spi@fffa4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xfffa4000 0x200>;
+ interrupts = <14 4 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi0>;
+ clocks = <&spi0_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+
+ spi1: spi@fffa8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xfffa8000 0x200>;
+ interrupts = <15 4 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi1>;
+ clocks = <&spi1_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+
+ usb2: gadget@fff78000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91sam9g45-udc";
+ reg = <0x00600000 0x80000
+ 0xfff78000 0x400>;
+ interrupts = <27 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&udphs_clk>, <&utmi>;
+ clock-names = "pclk", "hclk";
+ status = "disabled";
+
+ ep0 {
+ reg = <0>;
+ atmel,fifo-size = <64>;
+ atmel,nb-banks = <1>;
+ };
+
+ ep1 {
+ reg = <1>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep2 {
+ reg = <2>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep3 {
+ reg = <3>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <3>;
+ atmel,can-dma;
+ };
+
+ ep4 {
+ reg = <4>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <3>;
+ atmel,can-dma;
+ };
+
+ ep5 {
+ reg = <5>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <3>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep6 {
+ reg = <6>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <3>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+ };
+
+ sckc@fffffd50 {
+ compatible = "atmel,at91sam9x5-sckc";
+ reg = <0xfffffd50 0x4>;
+
+ slow_osc: slow_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-osc";
+ #clock-cells = <0>;
+ atmel,startup-time-usec = <1200000>;
+ clocks = <&slow_xtal>;
+ };
+
+ slow_rc_osc: slow_rc_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-rc-osc";
+ #clock-cells = <0>;
+ atmel,startup-time-usec = <75>;
+ clock-frequency = <32768>;
+ clock-accuracy = <50000000>;
+ };
+
+ clk32k: slck {
+ compatible = "atmel,at91sam9x5-clk-slow";
+ #clock-cells = <0>;
+ clocks = <&slow_rc_osc &slow_osc>;
+ };
+ };
+
+ rtc@fffffd20 {
+ compatible = "atmel,at91sam9260-rtt";
+ reg = <0xfffffd20 0x10>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ clocks = <&clk32k>;
+ status = "disabled";
+ };
+
+ rtc@fffffdb0 {
+ compatible = "atmel,at91rm9200-rtc";
+ reg = <0xfffffdb0 0x30>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ status = "disabled";
+ };
+
+ gpbr: syscon@fffffd60 {
+ compatible = "atmel,at91sam9260-gpbr", "syscon";
+ reg = <0xfffffd60 0x10>;
+ status = "disabled";
+ };
+ };
+
+ fb0: fb@0x00500000 {
+ compatible = "atmel,at91sam9g45-lcdc";
+ reg = <0x00500000 0x1000>;
+ interrupts = <23 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fb>;
+ clocks = <&lcd_clk>, <&lcd_clk>;
+ clock-names = "hclk", "lcdc_clk";
+ status = "disabled";
+ };
+
+ nand0: nand@40000000 {
+ compatible = "atmel,at91rm9200-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x40000000 0x10000000
+ 0xffffe200 0x200
+ >;
+ atmel,nand-addr-offset = <21>;
+ atmel,nand-cmd-offset = <22>;
+ atmel,nand-has-dma;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
+ gpios = <&pioC 8 GPIO_ACTIVE_HIGH
+ &pioC 14 GPIO_ACTIVE_HIGH
+ 0
+ >;
+ status = "disabled";
+ };
+
+ usb0: ohci@00700000 {
+ compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+ reg = <0x00700000 0x100000>;
+ interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>, <&uhpck>;
+ clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck";
+ status = "disabled";
+ };
+
+ usb1: ehci@00800000 {
+ compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
+ reg = <0x00800000 0x100000>;
+ interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&utmi>, <&uhphs_clk>, <&uhphs_clk>, <&uhpck>;
+ clock-names = "usb_clk", "ehci_clk", "hclk", "uhpck";
+ status = "disabled";
+ };
+ };
+
+ i2c@0 {
+ compatible = "i2c-gpio";
+ gpios = <&pioA 20 GPIO_ACTIVE_HIGH /* sda */
+ &pioA 21 GPIO_ACTIVE_HIGH /* scl */
+ >;
+ i2c-gpio,sda-open-drain;
+ i2c-gpio,scl-open-drain;
+ i2c-gpio,delay-us = <5>; /* ~100 kHz */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts
new file mode 100644
index 000000000..33ce7ca2c
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts
@@ -0,0 +1,316 @@
+/*
+ * at91sam9m10g45ek.dts - Device Tree file for AT91SAM9M10G45-EK board
+ *
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "at91sam9g45.dtsi"
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ model = "Atmel AT91SAM9M10G45-EK";
+ compatible = "atmel,at91sam9m10g45ek", "atmel,at91sam9g45", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2";
+ };
+
+ memory {
+ reg = <0x70000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@ffffee00 {
+ status = "okay";
+ };
+
+ usart1: serial@fff90000 {
+ pinctrl-0 =
+ <&pinctrl_usart1
+ &pinctrl_usart1_rts
+ &pinctrl_usart1_cts>;
+ status = "okay";
+ };
+
+ macb0: ethernet@fffbc000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ i2c0: i2c@fff84000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@fff88000 {
+ status = "okay";
+ };
+
+ watchdog@fffffd40 {
+ status = "okay";
+ };
+
+ mmc0: mmc@fff80000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0
+ &pinctrl_mmc0_slot0_clk_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 10 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ mmc1: mmc@fffd0000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc1
+ &pinctrl_mmc1_slot0_clk_cmd_dat0
+ &pinctrl_mmc1_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 11 GPIO_ACTIVE_HIGH>;
+ wp-gpios = <&pioD 29 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ pinctrl@fffff200 {
+ mmc0 {
+ pinctrl_board_mmc0: mmc0-board {
+ atmel,pins =
+ <AT91_PIOD 10 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PD10 gpio CD pin pull up and deglitch */
+ };
+ };
+
+ mmc1 {
+ pinctrl_board_mmc1: mmc1-board {
+ atmel,pins =
+ <AT91_PIOD 11 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH /* PD11 gpio CD pin pull up and deglitch */
+ AT91_PIOD 29 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>; /* PD29 gpio WP pin pull up */
+ };
+ };
+
+ pwm0 {
+ pinctrl_pwm_leds: pwm-led {
+ atmel,pins =
+ <AT91_PIOD 0 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PD0 periph B */
+ AT91_PIOD 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* PD31 periph B */
+ };
+ };
+ };
+
+ spi0: spi@fffa4000{
+ status = "okay";
+ cs-gpios = <&pioB 3 0>, <0>, <0>, <0>;
+ mtd_dataflash@0 {
+ compatible = "atmel,at45", "atmel,dataflash";
+ spi-max-frequency = <13000000>;
+ reg = <0>;
+ };
+ };
+
+ usb2: gadget@fff78000 {
+ atmel,vbus-gpio = <&pioB 19 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ adc0: adc@fffb0000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &pinctrl_adc0_ad0
+ &pinctrl_adc0_ad1
+ &pinctrl_adc0_ad2
+ &pinctrl_adc0_ad3
+ &pinctrl_adc0_ad4
+ &pinctrl_adc0_ad5
+ &pinctrl_adc0_ad6
+ &pinctrl_adc0_ad7>;
+ atmel,adc-ts-wires = <4>;
+ status = "okay";
+ };
+
+ pwm0: pwm@fffb8000 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_leds>;
+ };
+
+ rtc@fffffd20 {
+ atmel,rtt-rtc-time-reg = <&gpbr 0x0>;
+ status = "okay";
+ };
+
+ gpbr: syscon@fffffd60 {
+ status = "okay";
+ };
+
+ rtc@fffffdb0 {
+ status = "okay";
+ };
+ };
+
+ fb0: fb@0x00500000 {
+ display = <&display0>;
+ status = "okay";
+
+ display0: display {
+ bits-per-pixel = <32>;
+ atmel,lcdcon-backlight;
+ atmel,dmacon = <0x1>;
+ atmel,lcdcon2 = <0x80008002>;
+ atmel,guard-time = <9>;
+ atmel,lcd-wiring-mode = "RGB";
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <9000000>;
+ hactive = <480>;
+ vactive = <272>;
+ hback-porch = <1>;
+ hfront-porch = <1>;
+ vback-porch = <40>;
+ vfront-porch = <1>;
+ hsync-len = <45>;
+ vsync-len = <1>;
+ };
+ };
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ status = "okay";
+
+ boot@0 {
+ label = "bootstrap/uboot/kernel";
+ reg = <0x0 0x400000>;
+ };
+
+ rootfs@400000 {
+ label = "rootfs";
+ reg = <0x400000 0x3C00000>;
+ };
+
+ data@4000000 {
+ label = "data";
+ reg = <0x4000000 0xC000000>;
+ };
+ };
+
+ usb0: ohci@00700000 {
+ status = "okay";
+ num-ports = <2>;
+ atmel,vbus-gpio = <&pioD 1 GPIO_ACTIVE_LOW
+ &pioD 3 GPIO_ACTIVE_LOW>;
+ };
+
+ usb1: ehci@00800000 {
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ d8 {
+ label = "d8";
+ gpios = <&pioD 30 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ pwmleds {
+ compatible = "pwm-leds";
+
+ d6 {
+ label = "d6";
+ pwms = <&pwm0 3 5000 PWM_POLARITY_INVERTED>;
+ max-brightness = <255>;
+ linux,default-trigger = "nand-disk";
+ };
+
+ d7 {
+ label = "d7";
+ pwms = <&pwm0 1 5000 PWM_POLARITY_INVERTED>;
+ max-brightness = <255>;
+ linux,default-trigger = "mmc0";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ left_click {
+ label = "left_click";
+ gpios = <&pioB 6 GPIO_ACTIVE_LOW>;
+ linux,code = <272>;
+ gpio-key,wakeup;
+ };
+
+ right_click {
+ label = "right_click";
+ gpios = <&pioB 7 GPIO_ACTIVE_LOW>;
+ linux,code = <273>;
+ gpio-key,wakeup;
+ };
+
+ left {
+ label = "Joystick Left";
+ gpios = <&pioB 14 GPIO_ACTIVE_LOW>;
+ linux,code = <105>;
+ };
+
+ right {
+ label = "Joystick Right";
+ gpios = <&pioB 15 GPIO_ACTIVE_LOW>;
+ linux,code = <106>;
+ };
+
+ up {
+ label = "Joystick Up";
+ gpios = <&pioB 16 GPIO_ACTIVE_LOW>;
+ linux,code = <103>;
+ };
+
+ down {
+ label = "Joystick Down";
+ gpios = <&pioB 17 GPIO_ACTIVE_LOW>;
+ linux,code = <108>;
+ };
+
+ enter {
+ label = "Joystick Press";
+ gpios = <&pioB 18 GPIO_ACTIVE_LOW>;
+ linux,code = <28>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi
new file mode 100644
index 000000000..a9e35dfc1
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9n12.dtsi
@@ -0,0 +1,971 @@
+/*
+ * at91sam9n12.dtsi - Device Tree include file for AT91SAM9N12 SoC
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Hong Xu <hong.xu@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/dma/at91.h>
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/at91.h>
+
+/ {
+ model = "Atmel AT91SAM9N12 SoC";
+ compatible = "atmel,at91sam9n12";
+ interrupt-parent = <&aic>;
+
+ aliases {
+ serial0 = &dbgu;
+ serial1 = &usart0;
+ serial2 = &usart1;
+ serial3 = &usart2;
+ serial4 = &usart3;
+ gpio0 = &pioA;
+ gpio1 = &pioB;
+ gpio2 = &pioC;
+ gpio3 = &pioD;
+ tcb0 = &tcb0;
+ tcb1 = &tcb1;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ ssc0 = &ssc0;
+ pwm0 = &pwm0;
+ };
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm926ej-s";
+ device_type = "cpu";
+ };
+ };
+
+ memory {
+ reg = <0x20000000 0x10000000>;
+ };
+
+ clocks {
+ slow_xtal: slow_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ main_xtal: main_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ sram: sram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x8000>;
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ aic: interrupt-controller@fffff000 {
+ #interrupt-cells = <3>;
+ compatible = "atmel,at91rm9200-aic";
+ interrupt-controller;
+ reg = <0xfffff000 0x200>;
+ atmel,external-irqs = <31>;
+ };
+
+ ramc0: ramc@ffffe800 {
+ compatible = "atmel,at91sam9g45-ddramc";
+ reg = <0xffffe800 0x200>;
+ clocks = <&ddrck>;
+ clock-names = "ddrck";
+ };
+
+ pmc: pmc@fffffc00 {
+ compatible = "atmel,at91sam9n12-pmc";
+ reg = <0xfffffc00 0x200>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ main_rc_osc: main_rc_osc {
+ compatible = "atmel,at91sam9x5-clk-main-rc-osc";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MOSCRCS>;
+ clock-frequency = <12000000>;
+ clock-accuracy = <50000000>;
+ };
+
+ main_osc: main_osc {
+ compatible = "atmel,at91rm9200-clk-main-osc";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MOSCS>;
+ clocks = <&main_xtal>;
+ };
+
+ main: mainck {
+ compatible = "atmel,at91sam9x5-clk-main";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MOSCSELS>;
+ clocks = <&main_rc_osc>, <&main_osc>;
+ };
+
+ plla: pllack {
+ compatible = "atmel,at91rm9200-clk-pll";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_LOCKA>;
+ clocks = <&main>;
+ reg = <0>;
+ atmel,clk-input-range = <2000000 32000000>;
+ #atmel,pll-clk-output-range-cells = <4>;
+ atmel,pll-clk-output-ranges = <745000000 800000000 0 0>,
+ <695000000 750000000 1 0>,
+ <645000000 700000000 2 0>,
+ <595000000 650000000 3 0>,
+ <545000000 600000000 0 1>,
+ <495000000 555000000 1 1>,
+ <445000000 500000000 2 1>,
+ <400000000 450000000 3 1>;
+ };
+
+ plladiv: plladivck {
+ compatible = "atmel,at91sam9x5-clk-plldiv";
+ #clock-cells = <0>;
+ clocks = <&plla>;
+ };
+
+ pllb: pllbck {
+ compatible = "atmel,at91rm9200-clk-pll";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_LOCKB>;
+ clocks = <&main>;
+ reg = <1>;
+ atmel,clk-input-range = <2000000 32000000>;
+ #atmel,pll-clk-output-range-cells = <3>;
+ atmel,pll-clk-output-ranges = <30000000 100000000 0>;
+ };
+
+ mck: masterck {
+ compatible = "atmel,at91sam9x5-clk-master";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MCKRDY>;
+ clocks = <&clk32k>, <&main>, <&plladiv>, <&pllb>;
+ atmel,clk-output-range = <0 133333333>;
+ atmel,clk-divisors = <1 2 4 3>;
+ atmel,master-clk-have-div3-pres;
+ };
+
+ usb: usbck {
+ compatible = "atmel,at91sam9n12-clk-usb";
+ #clock-cells = <0>;
+ clocks = <&pllb>;
+ };
+
+ prog: progck {
+ compatible = "atmel,at91sam9x5-clk-programmable";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-parent = <&pmc>;
+ clocks = <&clk32k>, <&main>, <&plladiv>, <&pllb>, <&mck>;
+
+ prog0: prog0 {
+ #clock-cells = <0>;
+ reg = <0>;
+ interrupts = <AT91_PMC_PCKRDY(0)>;
+ };
+
+ prog1: prog1 {
+ #clock-cells = <0>;
+ reg = <1>;
+ interrupts = <AT91_PMC_PCKRDY(1)>;
+ };
+ };
+
+ systemck {
+ compatible = "atmel,at91rm9200-clk-system";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ddrck: ddrck {
+ #clock-cells = <0>;
+ reg = <2>;
+ clocks = <&mck>;
+ };
+
+ lcdck: lcdck {
+ #clock-cells = <0>;
+ reg = <3>;
+ clocks = <&mck>;
+ };
+
+ uhpck: uhpck {
+ #clock-cells = <0>;
+ reg = <6>;
+ clocks = <&usb>;
+ };
+
+ udpck: udpck {
+ #clock-cells = <0>;
+ reg = <7>;
+ clocks = <&usb>;
+ };
+
+ pck0: pck0 {
+ #clock-cells = <0>;
+ reg = <8>;
+ clocks = <&prog0>;
+ };
+
+ pck1: pck1 {
+ #clock-cells = <0>;
+ reg = <9>;
+ clocks = <&prog1>;
+ };
+ };
+
+ periphck {
+ compatible = "atmel,at91sam9x5-clk-peripheral";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mck>;
+
+ pioAB_clk: pioAB_clk {
+ #clock-cells = <0>;
+ reg = <2>;
+ };
+
+ pioCD_clk: pioCD_clk {
+ #clock-cells = <0>;
+ reg = <3>;
+ };
+
+ fuse_clk: fuse_clk {
+ #clock-cells = <0>;
+ reg = <4>;
+ };
+
+ usart0_clk: usart0_clk {
+ #clock-cells = <0>;
+ reg = <5>;
+ };
+
+ usart1_clk: usart1_clk {
+ #clock-cells = <0>;
+ reg = <6>;
+ };
+
+ usart2_clk: usart2_clk {
+ #clock-cells = <0>;
+ reg = <7>;
+ };
+
+ usart3_clk: usart3_clk {
+ #clock-cells = <0>;
+ reg = <8>;
+ };
+
+ twi0_clk: twi0_clk {
+ reg = <9>;
+ #clock-cells = <0>;
+ };
+
+ twi1_clk: twi1_clk {
+ #clock-cells = <0>;
+ reg = <10>;
+ };
+
+ mci0_clk: mci0_clk {
+ #clock-cells = <0>;
+ reg = <12>;
+ };
+
+ spi0_clk: spi0_clk {
+ #clock-cells = <0>;
+ reg = <13>;
+ };
+
+ spi1_clk: spi1_clk {
+ #clock-cells = <0>;
+ reg = <14>;
+ };
+
+ uart0_clk: uart0_clk {
+ #clock-cells = <0>;
+ reg = <15>;
+ };
+
+ uart1_clk: uart1_clk {
+ #clock-cells = <0>;
+ reg = <16>;
+ };
+
+ tcb_clk: tcb_clk {
+ #clock-cells = <0>;
+ reg = <17>;
+ };
+
+ pwm_clk: pwm_clk {
+ #clock-cells = <0>;
+ reg = <18>;
+ };
+
+ adc_clk: adc_clk {
+ #clock-cells = <0>;
+ reg = <19>;
+ };
+
+ dma0_clk: dma0_clk {
+ #clock-cells = <0>;
+ reg = <20>;
+ };
+
+ uhphs_clk: uhphs_clk {
+ #clock-cells = <0>;
+ reg = <22>;
+ };
+
+ udphs_clk: udphs_clk {
+ #clock-cells = <0>;
+ reg = <23>;
+ };
+
+ lcdc_clk: lcdc_clk {
+ #clock-cells = <0>;
+ reg = <25>;
+ };
+
+ sha_clk: sha_clk {
+ #clock-cells = <0>;
+ reg = <27>;
+ };
+
+ ssc0_clk: ssc0_clk {
+ #clock-cells = <0>;
+ reg = <28>;
+ };
+
+ aes_clk: aes_clk {
+ #clock-cells = <0>;
+ reg = <29>;
+ };
+
+ trng_clk: trng_clk {
+ #clock-cells = <0>;
+ reg = <30>;
+ };
+ };
+ };
+
+ rstc@fffffe00 {
+ compatible = "atmel,at91sam9g45-rstc";
+ reg = <0xfffffe00 0x10>;
+ };
+
+ pit: timer@fffffe30 {
+ compatible = "atmel,at91sam9260-pit";
+ reg = <0xfffffe30 0xf>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ clocks = <&mck>;
+ };
+
+ shdwc@fffffe10 {
+ compatible = "atmel,at91sam9x5-shdwc";
+ reg = <0xfffffe10 0x10>;
+ };
+
+ sckc@fffffe50 {
+ compatible = "atmel,at91sam9x5-sckc";
+ reg = <0xfffffe50 0x4>;
+
+ slow_osc: slow_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-osc";
+ #clock-cells = <0>;
+ clocks = <&slow_xtal>;
+ };
+
+ slow_rc_osc: slow_rc_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-rc-osc";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-accuracy = <50000000>;
+ };
+
+ clk32k: slck {
+ compatible = "atmel,at91sam9x5-clk-slow";
+ #clock-cells = <0>;
+ clocks = <&slow_rc_osc>, <&slow_osc>;
+ };
+ };
+
+ mmc0: mmc@f0008000 {
+ compatible = "atmel,hsmci";
+ reg = <0xf0008000 0x600>;
+ interrupts = <12 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma 1 AT91_DMA_CFG_PER_ID(0)>;
+ dma-names = "rxtx";
+ clocks = <&mci0_clk>;
+ clock-names = "mci_clk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ tcb0: timer@f8008000 {
+ compatible = "atmel,at91sam9x5-tcb";
+ reg = <0xf8008000 0x100>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tcb_clk>;
+ clock-names = "t0_clk";
+ };
+
+ tcb1: timer@f800c000 {
+ compatible = "atmel,at91sam9x5-tcb";
+ reg = <0xf800c000 0x100>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tcb_clk>;
+ clock-names = "t0_clk";
+ };
+
+ dma: dma-controller@ffffec00 {
+ compatible = "atmel,at91sam9g45-dma";
+ reg = <0xffffec00 0x200>;
+ interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0>;
+ #dma-cells = <2>;
+ clocks = <&dma0_clk>;
+ clock-names = "dma_clk";
+ };
+
+ pinctrl@fffff400 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff400 0xfffff400 0x800>;
+
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe07983 0x00000000 /* pioA */
+ 0x00040000 0x00047e0f 0x00000000 /* pioB */
+ 0xfdffffff 0x07c00000 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
+
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA9 periph A */
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA10 periph with pullup */
+ };
+ };
+
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA1 periph A with pullup */
+ AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA0 periph A */
+ };
+
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA2 periph A */
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA3 periph A */
+ };
+ };
+
+ usart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA6 periph A with pullup */
+ AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA5 periph A */
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA8 periph A with pullup */
+ AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA7 periph A */
+ };
+
+ pinctrl_usart2_rts: usart2_rts-0 {
+ atmel,pins =
+ <AT91_PIOB 0 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB0 periph B */
+ };
+
+ pinctrl_usart2_cts: usart2_cts-0 {
+ atmel,pins =
+ <AT91_PIOB 1 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB1 periph B */
+ };
+ };
+
+ usart3 {
+ pinctrl_usart3: usart3-0 {
+ atmel,pins =
+ <AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PC23 periph B with pullup */
+ AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC22 periph B */
+ };
+
+ pinctrl_usart3_rts: usart3_rts-0 {
+ atmel,pins =
+ <AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC24 periph B */
+ };
+
+ pinctrl_usart3_cts: usart3_cts-0 {
+ atmel,pins =
+ <AT91_PIOC 25 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC25 periph B */
+ };
+ };
+
+ uart0 {
+ pinctrl_uart0: uart0-0 {
+ atmel,pins =
+ <AT91_PIOC 9 AT91_PERIPH_C AT91_PINCTRL_PULL_UP /* PC9 periph C with pullup */
+ AT91_PIOC 8 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC8 periph C */
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1: uart1-0 {
+ atmel,pins =
+ <AT91_PIOC 16 AT91_PERIPH_C AT91_PINCTRL_PULL_UP /* PC17 periph C with pullup */
+ AT91_PIOC 17 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC16 periph C */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <AT91_PIOD 5 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP /* PD5 gpio RDY pin pull_up*/
+ AT91_PIOD 4 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>; /* PD4 gpio enable pin pull_up */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 {
+ atmel,pins =
+ <AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA17 periph A */
+ AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA16 periph A with pullup */
+ AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA15 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA18 periph A with pullup */
+ AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA19 periph A with pullup */
+ AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA20 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat4_7: mmc0_slot0_dat4_7-0 {
+ atmel,pins =
+ <AT91_PIOA 11 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PA11 periph B with pullup */
+ AT91_PIOA 12 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PA12 periph B with pullup */
+ AT91_PIOA 13 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PA13 periph B with pullup */
+ AT91_PIOA 14 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* PA14 periph B with pullup */
+ };
+ };
+
+ ssc0 {
+ pinctrl_ssc0_tx: ssc0_tx-0 {
+ atmel,pins =
+ <AT91_PIOA 24 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA24 periph B */
+ AT91_PIOA 25 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA25 periph B */
+ AT91_PIOA 26 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PA26 periph B */
+ };
+
+ pinctrl_ssc0_rx: ssc0_rx-0 {
+ atmel,pins =
+ <AT91_PIOA 27 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA27 periph B */
+ AT91_PIOA 28 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA28 periph B */
+ AT91_PIOA 29 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PA29 periph B */
+ };
+ };
+
+ spi0 {
+ pinctrl_spi0: spi0-0 {
+ atmel,pins =
+ <AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA11 periph A SPI0_MISO pin */
+ AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA12 periph A SPI0_MOSI pin */
+ AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA13 periph A SPI0_SPCK pin */
+ };
+ };
+
+ spi1 {
+ pinctrl_spi1: spi1-0 {
+ atmel,pins =
+ <AT91_PIOA 21 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA21 periph B SPI1_MISO pin */
+ AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA22 periph B SPI1_MOSI pin */
+ AT91_PIOA 23 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PA23 periph B SPI1_SPCK pin */
+ };
+ };
+
+ i2c0 {
+ pinctrl_i2c0: i2c0-0 {
+ atmel,pins =
+ <AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_NONE
+ AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ i2c1 {
+ pinctrl_i2c1: i2c1-0 {
+ atmel,pins =
+ <AT91_PIOC 0 AT91_PERIPH_C AT91_PINCTRL_NONE
+ AT91_PIOC 1 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+ };
+
+ tcb0 {
+ pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
+ atmel,pins = <AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
+ atmel,pins = <AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
+ atmel,pins = <AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
+ atmel,pins = <AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
+ atmel,pins = <AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
+ atmel,pins = <AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
+ atmel,pins = <AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
+ atmel,pins = <AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
+ atmel,pins = <AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ tcb1 {
+ pinctrl_tcb1_tclk0: tcb1_tclk0-0 {
+ atmel,pins = <AT91_PIOC 4 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tclk1: tcb1_tclk1-0 {
+ atmel,pins = <AT91_PIOC 7 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tclk2: tcb1_tclk2-0 {
+ atmel,pins = <AT91_PIOC 14 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tioa0: tcb1_tioa0-0 {
+ atmel,pins = <AT91_PIOC 2 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tioa1: tcb1_tioa1-0 {
+ atmel,pins = <AT91_PIOC 5 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tioa2: tcb1_tioa2-0 {
+ atmel,pins = <AT91_PIOC 12 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tiob0: tcb1_tiob0-0 {
+ atmel,pins = <AT91_PIOC 3 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tiob1: tcb1_tiob1-0 {
+ atmel,pins = <AT91_PIOC 6 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tiob2: tcb1_tiob2-0 {
+ atmel,pins = <AT91_PIOC 13 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+ };
+
+ pioA: gpio@fffff400 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioAB_clk>;
+ };
+
+ pioB: gpio@fffff600 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioAB_clk>;
+ };
+
+ pioC: gpio@fffff800 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioCD_clk>;
+ };
+
+ pioD: gpio@fffffa00 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x200>;
+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioCD_clk>;
+ };
+ };
+
+ dbgu: serial@fffff200 {
+ compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
+ reg = <0xfffff200 0x200>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
+ clocks = <&mck>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ ssc0: ssc@f0010000 {
+ compatible = "atmel,at91sam9g45-ssc";
+ reg = <0xf0010000 0x4000>;
+ interrupts = <28 IRQ_TYPE_LEVEL_HIGH 5>;
+ dmas = <&dma 0 AT91_DMA_CFG_PER_ID(21)>,
+ <&dma 0 AT91_DMA_CFG_PER_ID(22)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
+ clocks = <&ssc0_clk>;
+ clock-names = "pclk";
+ status = "disabled";
+ };
+
+ usart0: serial@f801c000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf801c000 0x4000>;
+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
+ clocks = <&usart0_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart1: serial@f8020000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf8020000 0x4000>;
+ interrupts = <6 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
+ clocks = <&usart1_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart2: serial@f8024000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf8024000 0x4000>;
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
+ clocks = <&usart2_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart3: serial@f8028000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf8028000 0x4000>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart3>;
+ clocks = <&usart3_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ i2c0: i2c@f8010000 {
+ compatible = "atmel,at91sam9x5-i2c";
+ reg = <0xf8010000 0x100>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH 6>;
+ dmas = <&dma 1 AT91_DMA_CFG_PER_ID(13)>,
+ <&dma 1 AT91_DMA_CFG_PER_ID(14)>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ clocks = <&twi0_clk>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@f8014000 {
+ compatible = "atmel,at91sam9x5-i2c";
+ reg = <0xf8014000 0x100>;
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH 6>;
+ dmas = <&dma 1 AT91_DMA_CFG_PER_ID(15)>,
+ <&dma 1 AT91_DMA_CFG_PER_ID(16)>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ clocks = <&twi1_clk>;
+ status = "disabled";
+ };
+
+ spi0: spi@f0000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xf0000000 0x100>;
+ interrupts = <13 IRQ_TYPE_LEVEL_HIGH 3>;
+ dmas = <&dma 1 AT91_DMA_CFG_PER_ID(1)>,
+ <&dma 1 AT91_DMA_CFG_PER_ID(2)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi0>;
+ clocks = <&spi0_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+
+ spi1: spi@f0004000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xf0004000 0x100>;
+ interrupts = <14 IRQ_TYPE_LEVEL_HIGH 3>;
+ dmas = <&dma 1 AT91_DMA_CFG_PER_ID(3)>,
+ <&dma 1 AT91_DMA_CFG_PER_ID(4)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi1>;
+ clocks = <&spi1_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+
+ watchdog@fffffe40 {
+ compatible = "atmel,at91sam9260-wdt";
+ reg = <0xfffffe40 0x10>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ atmel,watchdog-type = "hardware";
+ atmel,reset-type = "all";
+ atmel,dbg-halt;
+ status = "disabled";
+ };
+
+ rtc@fffffeb0 {
+ compatible = "atmel,at91rm9200-rtc";
+ reg = <0xfffffeb0 0x40>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ status = "disabled";
+ };
+
+ pwm0: pwm@f8034000 {
+ compatible = "atmel,at91sam9rl-pwm";
+ reg = <0xf8034000 0x300>;
+ interrupts = <18 IRQ_TYPE_LEVEL_HIGH 4>;
+ #pwm-cells = <3>;
+ clocks = <&pwm_clk>;
+ status = "disabled";
+ };
+
+ usb1: gadget@f803c000 {
+ compatible = "atmel,at91sam9260-udc";
+ reg = <0xf803c000 0x4000>;
+ interrupts = <23 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&udphs_clk>, <&udpck>;
+ clock-names = "pclk", "hclk";
+ status = "disabled";
+ };
+ };
+
+ nand0: nand@40000000 {
+ compatible = "atmel,at91rm9200-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x40000000 0x10000000
+ 0xffffe000 0x00000600
+ 0xffffe600 0x00000200
+ 0x00108000 0x00018000
+ >;
+ atmel,pmecc-lookup-table-offset = <0x0 0x8000>;
+ atmel,nand-addr-offset = <21>;
+ atmel,nand-cmd-offset = <22>;
+ atmel,nand-has-dma;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
+ gpios = <&pioD 5 GPIO_ACTIVE_HIGH
+ &pioD 4 GPIO_ACTIVE_HIGH
+ 0
+ >;
+ status = "disabled";
+ };
+
+ usb0: ohci@00500000 {
+ compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+ reg = <0x00500000 0x00100000>;
+ interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>,
+ <&uhpck>;
+ clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck";
+ status = "disabled";
+ };
+ };
+
+ i2c@0 {
+ compatible = "i2c-gpio";
+ gpios = <&pioA 30 GPIO_ACTIVE_HIGH /* sda */
+ &pioA 31 GPIO_ACTIVE_HIGH /* scl */
+ >;
+ i2c-gpio,sda-open-drain;
+ i2c-gpio,scl-open-drain;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts
new file mode 100644
index 000000000..6e067c8a3
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9n12ek.dts
@@ -0,0 +1,213 @@
+/*
+ * at91sam9n12ek.dts - Device Tree file for AT91SAM9N12-EK board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Hong Xu <hong.xu@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "at91sam9n12.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9N12-EK";
+ compatible = "atmel,at91sam9n12ek", "atmel,at91sam9n12", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2";
+ };
+
+ memory {
+ reg = <0x20000000 0x8000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <16000000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <16000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ ssc0: ssc@f0010000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@f8010000 {
+ status = "okay";
+
+ wm8904: codec@1a {
+ compatible = "wlf,wm8904";
+ reg = <0x1a>;
+ clocks = <&pck0>;
+ clock-names = "mclk";
+ };
+
+ qt1070: keyboard@1b {
+ compatible = "qt1070";
+ reg = <0x1b>;
+ interrupt-parent = <&pioA>;
+ interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qt1070_irq>;
+ };
+ };
+
+ i2c1: i2c@f8014000 {
+ status = "okay";
+ };
+
+ mmc0: mmc@f0008000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0
+ &pinctrl_mmc0_slot0_clk_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioA 7 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ pinctrl@fffff400 {
+ mmc0 {
+ pinctrl_board_mmc0: mmc0-board {
+ atmel,pins =
+ <AT91_PIOA 7 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PA7 gpio CD pin pull up and deglitch */
+ };
+ };
+
+ qt1070 {
+ pinctrl_qt1070_irq: qt1070_irq {
+ atmel,pins =
+ <AT91_PIOA 2 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
+ };
+
+ sound {
+ pinctrl_pck0_as_audio_mck: pck0_as_audio_mck {
+ atmel,pins =
+ <AT91_PIOB 10 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ usb1 {
+ pinctrl_usb1_vbus_sense: usb1_vbus_sense {
+ atmel,pins =
+ <AT91_PIOB 16 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PB16 gpio usb vbus sense, no pull up and deglitch */
+ };
+ };
+ };
+
+ spi0: spi@f0000000 {
+ status = "okay";
+ cs-gpios = <&pioA 14 0>, <0>, <0>, <0>;
+ m25p80@0 {
+ compatible = "atmel,at25df321a";
+ spi-max-frequency = <50000000>;
+ reg = <0>;
+ };
+ };
+
+ usb1: gadget@f803c000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb1_vbus_sense>;
+ atmel,vbus-gpio = <&pioB 16 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ watchdog@fffffe40 {
+ status = "okay";
+ };
+
+ rtc@fffffeb0 {
+ status = "okay";
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ atmel,has-pmecc;
+ atmel,pmecc-cap = <2>;
+ atmel,pmecc-sector-size = <512>;
+ nand-on-flash-bbt;
+ status = "okay";
+ };
+
+ usb0: ohci@00500000 {
+ num-ports = <1>;
+ atmel,vbus-gpio = <&pioB 7 GPIO_ACTIVE_LOW>;
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ d8 {
+ label = "d8";
+ gpios = <&pioB 4 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "mmc0";
+ };
+
+ d9 {
+ label = "d6";
+ gpios = <&pioB 5 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "nand-disk";
+ };
+
+ d10 {
+ label = "d7";
+ gpios = <&pioB 6 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ enter {
+ label = "Enter";
+ gpios = <&pioB 3 GPIO_ACTIVE_LOW>;
+ linux,code = <28>;
+ gpio-key,wakeup;
+ };
+ };
+
+ sound {
+ compatible = "atmel,asoc-wm8904";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pck0_as_audio_mck>;
+
+ atmel,model = "wm8904 @ AT91SAM9N12";
+ atmel,audio-routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "IN2L", "Line In Jack",
+ "IN2R", "Line In Jack",
+ "Mic", "MICBIAS",
+ "IN1L", "Mic";
+
+ atmel,ssc-controller = <&ssc0>;
+ atmel,audio-codec = <&wm8904>;
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi
new file mode 100644
index 000000000..ebfd5ce9c
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9rl.dtsi
@@ -0,0 +1,1118 @@
+/*
+ * at91sam9rl.dtsi - Device Tree Include file for AT91SAM9RL family SoC
+ *
+ * Copyright (C) 2014 Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/clock/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ model = "Atmel AT91SAM9RL family SoC";
+ compatible = "atmel,at91sam9rl", "atmel,at91sam9";
+ interrupt-parent = <&aic>;
+
+ aliases {
+ serial0 = &dbgu;
+ serial1 = &usart0;
+ serial2 = &usart1;
+ serial3 = &usart2;
+ serial4 = &usart3;
+ gpio0 = &pioA;
+ gpio1 = &pioB;
+ gpio2 = &pioC;
+ gpio3 = &pioD;
+ tcb0 = &tcb0;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ ssc0 = &ssc0;
+ ssc1 = &ssc1;
+ pwm0 = &pwm0;
+ };
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm926ej-s";
+ device_type = "cpu";
+ };
+ };
+
+ memory {
+ reg = <0x20000000 0x04000000>;
+ };
+
+ clocks {
+ slow_xtal: slow_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ main_xtal: main_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ adc_op_clk: adc_op_clk{
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1000000>;
+ };
+ };
+
+ sram: sram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x10000>;
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ fb0: fb@00500000 {
+ compatible = "atmel,at91sam9rl-lcdc";
+ reg = <0x00500000 0x1000>;
+ interrupts = <23 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fb>;
+ clocks = <&lcd_clk>, <&lcd_clk>;
+ clock-names = "hclk", "lcdc_clk";
+ status = "disabled";
+ };
+
+ nand0: nand@40000000 {
+ compatible = "atmel,at91rm9200-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x40000000 0x10000000>,
+ <0xffffe800 0x200>;
+ atmel,nand-addr-offset = <21>;
+ atmel,nand-cmd-offset = <22>;
+ atmel,nand-has-dma;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
+ gpios = <&pioD 17 GPIO_ACTIVE_HIGH>,
+ <&pioB 6 GPIO_ACTIVE_HIGH>,
+ <0>;
+ status = "disabled";
+ };
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ tcb0: timer@fffa0000 {
+ compatible = "atmel,at91rm9200-tcb";
+ reg = <0xfffa0000 0x100>;
+ interrupts = <16 IRQ_TYPE_LEVEL_HIGH 0>,
+ <17 IRQ_TYPE_LEVEL_HIGH 0>,
+ <18 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tc0_clk>, <&tc1_clk>, <&tc2_clk>;
+ clock-names = "t0_clk", "t1_clk", "t2_clk";
+ };
+
+ mmc0: mmc@fffa4000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfffa4000 0x600>;
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ clocks = <&mci0_clk>;
+ clock-names = "mci_clk";
+ status = "disabled";
+ };
+
+ i2c0: i2c@fffa8000 {
+ compatible = "atmel,at91sam9260-i2c";
+ reg = <0xfffa8000 0x100>;
+ interrupts = <11 IRQ_TYPE_LEVEL_HIGH 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&twi0_clk>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@fffac000 {
+ compatible = "atmel,at91sam9260-i2c";
+ reg = <0xfffac000 0x100>;
+ interrupts = <12 IRQ_TYPE_LEVEL_HIGH 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ usart0: serial@fffb0000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffb0000 0x200>;
+ interrupts = <6 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
+ clocks = <&usart0_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart1: serial@fffb4000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffb4000 0x200>;
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
+ clocks = <&usart1_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart2: serial@fffb8000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffb8000 0x200>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
+ clocks = <&usart2_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart3: serial@fffbc000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffbc000 0x200>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart3>;
+ clocks = <&usart3_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ ssc0: ssc@fffc0000 {
+ compatible = "atmel,at91sam9rl-ssc";
+ reg = <0xfffc0000 0x4000>;
+ interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
+ status = "disabled";
+ };
+
+ ssc1: ssc@fffc4000 {
+ compatible = "atmel,at91sam9rl-ssc";
+ reg = <0xfffc4000 0x4000>;
+ interrupts = <15 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
+ status = "disabled";
+ };
+
+ pwm0: pwm@fffc8000 {
+ compatible = "atmel,at91sam9rl-pwm";
+ reg = <0xfffc8000 0x300>;
+ interrupts = <19 IRQ_TYPE_LEVEL_HIGH 4>;
+ #pwm-cells = <3>;
+ clocks = <&pwm_clk>;
+ clock-names = "pwm_clk";
+ status = "disabled";
+ };
+
+ spi0: spi@fffcc000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xfffcc000 0x200>;
+ interrupts = <13 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi0>;
+ clocks = <&spi0_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+
+ adc0: adc@fffd0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91sam9rl-adc";
+ reg = <0xfffd0000 0x100>;
+ interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&adc_clk>, <&adc_op_clk>;
+ clock-names = "adc_clk", "adc_op_clk";
+ atmel,adc-use-external-triggers;
+ atmel,adc-channels-used = <0x3f>;
+ atmel,adc-vref = <3300>;
+ atmel,adc-startup-time = <40>;
+ atmel,adc-res = <8 10>;
+ atmel,adc-res-names = "lowres", "highres";
+ atmel,adc-use-res = "highres";
+
+ trigger@0 {
+ reg = <0>;
+ trigger-name = "timer-counter-0";
+ trigger-value = <0x1>;
+ };
+ trigger@1 {
+ reg = <1>;
+ trigger-name = "timer-counter-1";
+ trigger-value = <0x3>;
+ };
+
+ trigger@2 {
+ reg = <2>;
+ trigger-name = "timer-counter-2";
+ trigger-value = <0x5>;
+ };
+
+ trigger@3 {
+ reg = <3>;
+ trigger-name = "external";
+ trigger-value = <0x13>;
+ trigger-external;
+ };
+ };
+
+ usb0: gadget@fffd4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91sam9rl-udc";
+ reg = <0x00600000 0x100000>,
+ <0xfffd4000 0x4000>;
+ interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&udphs_clk>, <&utmi>;
+ clock-names = "pclk", "hclk";
+ status = "disabled";
+
+ ep0 {
+ reg = <0>;
+ atmel,fifo-size = <64>;
+ atmel,nb-banks = <1>;
+ };
+
+ ep1 {
+ reg = <1>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep2 {
+ reg = <2>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep3 {
+ reg = <3>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <3>;
+ atmel,can-dma;
+ };
+
+ ep4 {
+ reg = <4>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <3>;
+ atmel,can-dma;
+ };
+
+ ep5 {
+ reg = <5>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <3>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep6 {
+ reg = <6>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <3>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+ };
+
+ dma0: dma-controller@ffffe600 {
+ compatible = "atmel,at91sam9rl-dma";
+ reg = <0xffffe600 0x200>;
+ interrupts = <21 IRQ_TYPE_LEVEL_HIGH 0>;
+ #dma-cells = <2>;
+ clocks = <&dma0_clk>;
+ clock-names = "dma_clk";
+ };
+
+ ramc0: ramc@ffffea00 {
+ compatible = "atmel,at91sam9260-sdramc";
+ reg = <0xffffea00 0x200>;
+ };
+
+ aic: interrupt-controller@fffff000 {
+ #interrupt-cells = <3>;
+ compatible = "atmel,at91rm9200-aic";
+ interrupt-controller;
+ reg = <0xfffff000 0x200>;
+ atmel,external-irqs = <31>;
+ };
+
+ dbgu: serial@fffff200 {
+ compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
+ reg = <0xfffff200 0x200>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
+ clocks = <&mck>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ pinctrl@fffff400 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff400 0xfffff400 0x800>;
+
+ atmel,mux-mask =
+ /* A B */
+ <0xffffffff 0xe05c6738>, /* pioA */
+ <0xffffffff 0x0000c780>, /* pioB */
+ <0xffffffff 0xe3ffff0e>, /* pioC */
+ <0x003fffff 0x0001ff3c>; /* pioD */
+
+ /* shared pinctrl settings */
+ adc0 {
+ pinctrl_adc0_ts: adc0_ts-0 {
+ atmel,pins =
+ <AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_adc0_ad0: adc0_ad0-0 {
+ atmel,pins = <AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_adc0_ad1: adc0_ad1-0 {
+ atmel,pins = <AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_adc0_ad2: adc0_ad2-0 {
+ atmel,pins = <AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_adc0_ad3: adc0_ad3-0 {
+ atmel,pins = <AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_adc0_ad4: adc0_ad4-0 {
+ atmel,pins = <AT91_PIOD 6 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_adc0_ad5: adc0_ad5-0 {
+ atmel,pins = <AT91_PIOD 7 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_adc0_adtrg: adc0_adtrg-0 {
+ atmel,pins = <AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
+ };
+ };
+
+ fb {
+ pinctrl_fb: fb-0 {
+ atmel,pins =
+ <AT91_PIOC 1 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOC 9 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 10 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 11 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 12 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 13 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 15 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 16 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 17 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 18 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 19 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 20 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 21 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOC 25 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ i2c_gpio0 {
+ pinctrl_i2c_gpio0: i2c_gpio0-0 {
+ atmel,pins =
+ <AT91_PIOA 23 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>,
+ <AT91_PIOA 24 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>;
+ };
+ };
+
+ i2c_gpio1 {
+ pinctrl_i2c_gpio1: i2c_gpio1-0 {
+ atmel,pins =
+ <AT91_PIOD 10 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>,
+ <AT91_PIOD 11 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>;
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_clk: mmc0_clk-0 {
+ atmel,pins =
+ <AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 {
+ atmel,pins =
+ <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <AT91_PIOD 17 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOB 6 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;
+ };
+
+ pinctrl_nand0_ale_cle: nand_ale_cle-0 {
+ atmel,pins =
+ <AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_nand0_oe_we: nand_oe_we-0 {
+ atmel,pins =
+ <AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_nand0_cs: nand_cs-0 {
+ atmel,pins =
+ <AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ pwm0 {
+ pinctrl_pwm0_pwm0_0: pwm0_pwm0-0 {
+ atmel,pins = <AT91_PIOB 8 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_pwm0_pwm0_1: pwm0_pwm0-1 {
+ atmel,pins = <AT91_PIOC 2 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_pwm0_pwm0_2: pwm0_pwm0-2 {
+ atmel,pins = <AT91_PIOD 14 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_pwm0_pwm1_0: pwm0_pwm1-0 {
+ atmel,pins = <AT91_PIOB 9 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_pwm0_pwm1_1: pwm0_pwm1-1 {
+ atmel,pins = <AT91_PIOC 3 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_pwm0_pwm1_2: pwm0_pwm1-2 {
+ atmel,pins = <AT91_PIOD 15 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_pwm0_pwm2_0: pwm0_pwm2-0 {
+ atmel,pins = <AT91_PIOD 5 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_pwm0_pwm2_1: pwm0_pwm2-1 {
+ atmel,pins = <AT91_PIOD 12 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_pwm0_pwm2_2: pwm0_pwm2-2 {
+ atmel,pins = <AT91_PIOD 16 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_pwm0_pwm3_0: pwm0_pwm3-0 {
+ atmel,pins = <AT91_PIOD 8 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_pwm0_pwm3_1: pwm0_pwm3-1 {
+ atmel,pins = <AT91_PIOD 18 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ spi0 {
+ pinctrl_spi0: spi0-0 {
+ atmel,pins =
+ <AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ ssc0 {
+ pinctrl_ssc0_tx: ssc0_tx-0 {
+ atmel,pins =
+ <AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_ssc0_rx: ssc0_rx-0 {
+ atmel,pins =
+ <AT91_PIOA 10 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ ssc1 {
+ pinctrl_ssc1_tx: ssc1_tx-0 {
+ atmel,pins =
+ <AT91_PIOA 13 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOA 29 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_ssc1_rx: ssc1_rx-0 {
+ atmel,pins =
+ <AT91_PIOA 8 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOA 9 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+ <AT91_PIOA 14 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ tcb0 {
+ pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
+ atmel,pins = <AT91_PIOA 3 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
+ atmel,pins = <AT91_PIOC 31 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
+ atmel,pins = <AT91_PIOD 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
+ atmel,pins = <AT91_PIOA 4 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
+ atmel,pins = <AT91_PIOC 29 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
+ atmel,pins = <AT91_PIOD 10 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
+ atmel,pins = <AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
+ atmel,pins = <AT91_PIOC 30 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
+ atmel,pins = <AT91_PIOD 11 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
+ };
+
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart0_dtr_dsr: usart0_dtr_dsr-0 {
+ atmel,pins =
+ <AT91_PIOD 14 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+ <AT91_PIOD 15 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart0_dcd: usart0_dcd-0 {
+ atmel,pins =
+ <AT91_PIOD 16 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart0_ri: usart0_ri-0 {
+ atmel,pins =
+ <AT91_PIOD 17 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart0_sck: usart0_sck-0 {
+ atmel,pins =
+ <AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ usart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart1_rts: usart1_rts-0 {
+ atmel,pins =
+ <AT91_PIOA 18 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart1_cts: usart1_cts-0 {
+ atmel,pins =
+ <AT91_PIOA 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart1_sck: usart1_sck-0 {
+ atmel,pins =
+ <AT91_PIOD 2 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart2_rts: usart2_rts-0 {
+ atmel,pins =
+ <AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart2_cts: usart2_cts-0 {
+ atmel,pins =
+ <AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart2_sck: usart2_sck-0 {
+ atmel,pins =
+ <AT91_PIOD 9 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ usart3 {
+ pinctrl_usart3: usart3-0 {
+ atmel,pins =
+ <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart3_rts: usart3_rts-0 {
+ atmel,pins =
+ <AT91_PIOD 4 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart3_cts: usart3_cts-0 {
+ atmel,pins =
+ <AT91_PIOD 3 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usart3_sck: usart3_sck-0 {
+ atmel,pins =
+ <AT91_PIOA 20 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+ };
+
+ pioA: gpio@fffff400 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioA_clk>;
+ };
+
+ pioB: gpio@fffff600 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioB_clk>;
+ };
+
+ pioC: gpio@fffff800 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioC_clk>;
+ };
+
+ pioD: gpio@fffffa00 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x200>;
+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioD_clk>;
+ };
+ };
+
+ pmc: pmc@fffffc00 {
+ compatible = "atmel,at91sam9g45-pmc";
+ reg = <0xfffffc00 0x100>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ main: mainck {
+ compatible = "atmel,at91rm9200-clk-main";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MOSCS>;
+ clocks = <&main_xtal>;
+ };
+
+ plla: pllack {
+ compatible = "atmel,at91rm9200-clk-pll";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_LOCKA>;
+ clocks = <&main>;
+ reg = <0>;
+ atmel,clk-input-range = <1000000 32000000>;
+ #atmel,pll-clk-output-range-cells = <3>;
+ atmel,pll-clk-output-ranges = <80000000 200000000 0>,
+ <190000000 240000000 2>;
+ };
+
+ utmi: utmick {
+ compatible = "atmel,at91sam9x5-clk-utmi";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_LOCKU>;
+ clocks = <&main>;
+ };
+
+ mck: masterck {
+ compatible = "atmel,at91rm9200-clk-master";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MCKRDY>;
+ clocks = <&clk32k>, <&main>, <&plla>, <&utmi>;
+ atmel,clk-output-range = <0 94000000>;
+ atmel,clk-divisors = <1 2 4 0>;
+ };
+
+ prog: progck {
+ compatible = "atmel,at91rm9200-clk-programmable";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-parent = <&pmc>;
+ clocks = <&clk32k>, <&main>, <&plla>, <&utmi>, <&mck>;
+
+ prog0: prog0 {
+ #clock-cells = <0>;
+ reg = <0>;
+ interrupts = <AT91_PMC_PCKRDY(0)>;
+ };
+
+ prog1: prog1 {
+ #clock-cells = <0>;
+ reg = <1>;
+ interrupts = <AT91_PMC_PCKRDY(1)>;
+ };
+ };
+
+ systemck {
+ compatible = "atmel,at91rm9200-clk-system";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pck0: pck0 {
+ #clock-cells = <0>;
+ reg = <8>;
+ clocks = <&prog0>;
+ };
+
+ pck1: pck1 {
+ #clock-cells = <0>;
+ reg = <9>;
+ clocks = <&prog1>;
+ };
+
+ };
+
+ periphck {
+ compatible = "atmel,at91rm9200-clk-peripheral";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mck>;
+
+ pioA_clk: pioA_clk {
+ #clock-cells = <0>;
+ reg = <2>;
+ };
+
+ pioB_clk: pioB_clk {
+ #clock-cells = <0>;
+ reg = <3>;
+ };
+
+ pioC_clk: pioC_clk {
+ #clock-cells = <0>;
+ reg = <4>;
+ };
+
+ pioD_clk: pioD_clk {
+ #clock-cells = <0>;
+ reg = <5>;
+ };
+
+ usart0_clk: usart0_clk {
+ #clock-cells = <0>;
+ reg = <6>;
+ };
+
+ usart1_clk: usart1_clk {
+ #clock-cells = <0>;
+ reg = <7>;
+ };
+
+ usart2_clk: usart2_clk {
+ #clock-cells = <0>;
+ reg = <8>;
+ };
+
+ usart3_clk: usart3_clk {
+ #clock-cells = <0>;
+ reg = <9>;
+ };
+
+ mci0_clk: mci0_clk {
+ #clock-cells = <0>;
+ reg = <10>;
+ };
+
+ twi0_clk: twi0_clk {
+ #clock-cells = <0>;
+ reg = <11>;
+ };
+
+ twi1_clk: twi1_clk {
+ #clock-cells = <0>;
+ reg = <12>;
+ };
+
+ spi0_clk: spi0_clk {
+ #clock-cells = <0>;
+ reg = <13>;
+ };
+
+ ssc0_clk: ssc0_clk {
+ #clock-cells = <0>;
+ reg = <14>;
+ };
+
+ ssc1_clk: ssc1_clk {
+ #clock-cells = <0>;
+ reg = <15>;
+ };
+
+ tc0_clk: tc0_clk {
+ #clock-cells = <0>;
+ reg = <16>;
+ };
+
+ tc1_clk: tc1_clk {
+ #clock-cells = <0>;
+ reg = <17>;
+ };
+
+ tc2_clk: tc2_clk {
+ #clock-cells = <0>;
+ reg = <18>;
+ };
+
+ pwm_clk: pwm_clk {
+ #clock-cells = <0>;
+ reg = <19>;
+ };
+
+ adc_clk: adc_clk {
+ #clock-cells = <0>;
+ reg = <20>;
+ };
+
+ dma0_clk: dma0_clk {
+ #clock-cells = <0>;
+ reg = <21>;
+ };
+
+ udphs_clk: udphs_clk {
+ #clock-cells = <0>;
+ reg = <22>;
+ };
+
+ lcd_clk: lcd_clk {
+ #clock-cells = <0>;
+ reg = <23>;
+ };
+ };
+ };
+
+ rstc@fffffd00 {
+ compatible = "atmel,at91sam9260-rstc";
+ reg = <0xfffffd00 0x10>;
+ };
+
+ shdwc@fffffd10 {
+ compatible = "atmel,at91sam9260-shdwc";
+ reg = <0xfffffd10 0x10>;
+ };
+
+ pit: timer@fffffd30 {
+ compatible = "atmel,at91sam9260-pit";
+ reg = <0xfffffd30 0xf>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ clocks = <&mck>;
+ };
+
+ watchdog@fffffd40 {
+ compatible = "atmel,at91sam9260-wdt";
+ reg = <0xfffffd40 0x10>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ status = "disabled";
+ };
+
+ sckc@fffffd50 {
+ compatible = "atmel,at91sam9x5-sckc";
+ reg = <0xfffffd50 0x4>;
+
+ slow_osc: slow_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-osc";
+ #clock-cells = <0>;
+ atmel,startup-time-usec = <1200000>;
+ clocks = <&slow_xtal>;
+ };
+
+ slow_rc_osc: slow_rc_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-rc-osc";
+ #clock-cells = <0>;
+ atmel,startup-time-usec = <75>;
+ clock-frequency = <32768>;
+ clock-accuracy = <50000000>;
+ };
+
+ clk32k: slck {
+ compatible = "atmel,at91sam9x5-clk-slow";
+ #clock-cells = <0>;
+ clocks = <&slow_rc_osc &slow_osc>;
+ };
+ };
+
+ rtc@fffffeb0 {
+ compatible = "atmel,at91rm9200-rtc";
+ reg = <0xfffffeb0 0x40>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ status = "disabled";
+ };
+
+ rtc@fffffd20 {
+ compatible = "atmel,at91sam9260-rtt";
+ reg = <0xfffffd20 0x10>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ clocks = <&clk32k>;
+ status = "disabled";
+ };
+
+ gpbr: syscon@fffffd60 {
+ compatible = "atmel,at91sam9260-gpbr", "syscon";
+ reg = <0xfffffd60 0x10>;
+ status = "disabled";
+ };
+ };
+ };
+
+ i2c@0 {
+ compatible = "i2c-gpio";
+ gpios = <&pioA 23 GPIO_ACTIVE_HIGH>, /* sda */
+ <&pioA 24 GPIO_ACTIVE_HIGH>; /* scl */
+ i2c-gpio,sda-open-drain;
+ i2c-gpio,scl-open-drain;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c_gpio0>;
+ status = "disabled";
+ };
+
+ i2c@1 {
+ compatible = "i2c-gpio";
+ gpios = <&pioD 10 GPIO_ACTIVE_HIGH>, /* sda */
+ <&pioD 11 GPIO_ACTIVE_HIGH>; /* scl */
+ i2c-gpio,sda-open-drain;
+ i2c-gpio,scl-open-drain;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c_gpio1>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9rlek.dts b/arch/arm/boot/dts/at91sam9rlek.dts
new file mode 100644
index 000000000..9be5b540e
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9rlek.dts
@@ -0,0 +1,247 @@
+/*
+ * at91sam9rlek.dts - Device Tree file for Atmel at91sam9rl reference board
+ *
+ * Copyright (C) 2014 Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ *
+ * Licensed under GPLv2 only
+ */
+/dts-v1/;
+#include "at91sam9rl.dtsi"
+
+/ {
+ model = "Atmel at91sam9rlek";
+ compatible = "atmel,at91sam9rlek", "atmel,at91sam9rl", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 rootfstype=ubifs root=ubi0:rootfs ubi.mtd=5 rw";
+ };
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ fb0: fb@00500000 {
+ display = <&display0>;
+ status = "okay";
+
+ display0: display {
+ bits-per-pixel = <16>;
+ atmel,lcdcon-backlight;
+ atmel,dmacon = <0x1>;
+ atmel,lcdcon2 = <0x80008002>;
+ atmel,guard-time = <1>;
+ atmel,lcd-wiring-mode = "RGB";
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <4965000>;
+ hactive = <240>;
+ vactive = <320>;
+ hback-porch = <1>;
+ hfront-porch = <33>;
+ vback-porch = <1>;
+ vfront-porch = <0>;
+ hsync-len = <5>;
+ vsync-len = <1>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ };
+ };
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt = <1>;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ bootloader@40000 {
+ label = "bootloader";
+ reg = <0x40000 0x80000>;
+ };
+
+ bootloaderenv@c0000 {
+ label = "bootloader env";
+ reg = <0xc0000 0xc0000>;
+ };
+
+ dtb@180000 {
+ label = "device tree";
+ reg = <0x180000 0x80000>;
+ };
+
+ kernel@200000 {
+ label = "kernel";
+ reg = <0x200000 0x600000>;
+ };
+
+ rootfs@800000 {
+ label = "rootfs";
+ reg = <0x800000 0x0f800000>;
+ };
+ };
+
+ apb {
+ mmc0: mmc@fffa4000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0
+ &pinctrl_mmc0_clk
+ &pinctrl_mmc0_slot0_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioA 15 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ usart0: serial@fffb0000 {
+ pinctrl-0 = <
+ &pinctrl_usart0
+ &pinctrl_usart0_rts
+ &pinctrl_usart0_cts>;
+ status = "okay";
+ };
+
+ adc0: adc@fffd0000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &pinctrl_adc0_ad0
+ &pinctrl_adc0_ad1
+ &pinctrl_adc0_ad2
+ &pinctrl_adc0_ad3
+ &pinctrl_adc0_ad4
+ &pinctrl_adc0_ad5
+ &pinctrl_adc0_adtrg>;
+ atmel,adc-ts-wires = <4>;
+ status = "okay";
+ };
+
+ usb0: gadget@fffd4000 {
+ atmel,vbus-gpio = <&pioA 8 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ spi0: spi@fffcc000 {
+ status = "okay";
+ cs-gpios = <&pioA 28 0>, <0>, <0>, <0>;
+ mtd_dataflash@0 {
+ compatible = "atmel,at45", "atmel,dataflash";
+ spi-max-frequency = <15000000>;
+ reg = <0>;
+ };
+ };
+
+ pwm0: pwm@fffc8000 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm0_pwm1_2>,
+ <&pinctrl_pwm0_pwm2_2>;
+ };
+
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ pinctrl@fffff400 {
+ mmc0 {
+ pinctrl_board_mmc0: mmc0-board {
+ atmel,pins =
+ <AT91_PIOA 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
+ };
+ };
+
+ pmc: pmc@fffffc00 {
+ main: mainck {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ watchdog@fffffd40 {
+ status = "okay";
+ };
+ };
+ };
+
+ pwmleds {
+ compatible = "pwm-leds";
+
+ ds1 {
+ label = "ds1";
+ pwms = <&pwm0 1 5000 PWM_POLARITY_INVERTED>;
+ max-brightness = <255>;
+ };
+
+ ds2 {
+ label = "ds2";
+ pwms = <&pwm0 2 5000 PWM_POLARITY_INVERTED>;
+ max-brightness = <255>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ ds3 {
+ label = "ds3";
+ gpios = <&pioD 14 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ right_click {
+ label = "right_click";
+ gpios = <&pioB 0 GPIO_ACTIVE_LOW>;
+ linux,code = <273>;
+ gpio-key,wakeup;
+ };
+
+ left_click {
+ label = "left_click";
+ gpios = <&pioB 1 GPIO_ACTIVE_LOW>;
+ linux,code = <272>;
+ gpio-key,wakeup;
+ };
+ };
+
+ i2c@0 {
+ status = "okay";
+ };
+
+ i2c@1 {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9x25.dtsi b/arch/arm/boot/dts/at91sam9x25.dtsi
new file mode 100644
index 000000000..3c5fa3388
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x25.dtsi
@@ -0,0 +1,32 @@
+/*
+ * at91sam9x25.dtsi - Device Tree Include file for AT91SAM9X25 SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include "at91sam9x5.dtsi"
+#include "at91sam9x5_usart3.dtsi"
+#include "at91sam9x5_macb0.dtsi"
+#include "at91sam9x5_macb1.dtsi"
+#include "at91sam9x5_can.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9X25 SoC";
+ compatible = "atmel,at91sam9x25", "atmel,at91sam9x5";
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe03fff 0xc000001c /* pioA */
+ 0x0007ffff 0x00047e3f 0x00000000 /* pioB */
+ 0x80000000 0xfffd0000 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9x25ek.dts b/arch/arm/boot/dts/at91sam9x25ek.dts
new file mode 100644
index 000000000..494864836
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x25ek.dts
@@ -0,0 +1,30 @@
+/*
+ * at91sam9x25ek.dts - Device Tree file for AT91SAM9X25-EK board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "at91sam9x25.dtsi"
+#include "at91sam9x5ek.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9X25-EK";
+ compatible = "atmel,at91sam9x25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+
+ ahb {
+ apb {
+ macb0: ethernet@f802c000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ macb1: ethernet@f8030000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9x35.dtsi b/arch/arm/boot/dts/at91sam9x35.dtsi
new file mode 100644
index 000000000..499cdc81f
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x35.dtsi
@@ -0,0 +1,30 @@
+/*
+ * at91sam9x35.dtsi - Device Tree Include file for AT91SAM9X35 SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include "at91sam9x5.dtsi"
+#include "at91sam9x5_macb0.dtsi"
+#include "at91sam9x5_can.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9X35 SoC";
+ compatible = "atmel,at91sam9x35", "atmel,at91sam9x5";
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe03fff 0xc000000c /* pioA */
+ 0x000406ff 0x00047e3f 0x00000000 /* pioB */
+ 0xfdffffff 0x00000000 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9x35ek.dts b/arch/arm/boot/dts/at91sam9x35ek.dts
new file mode 100644
index 000000000..343d32818
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x35ek.dts
@@ -0,0 +1,25 @@
+/*
+ * at91sam9x35ek.dts - Device Tree file for AT91SAM9X35-EK board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "at91sam9x35.dtsi"
+#include "at91sam9x5ek.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9X35-EK";
+ compatible = "atmel,at91sam9x35ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+
+ ahb {
+ apb {
+ macb0: ethernet@f802c000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
new file mode 100644
index 000000000..3314a7303
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -0,0 +1,1238 @@
+/*
+ * at91sam9x5.dtsi - Device Tree Include file for AT91SAM9x5 family SoC
+ * applies to AT91SAM9G15, AT91SAM9G25, AT91SAM9G35,
+ * AT91SAM9X25, AT91SAM9X35 SoC
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/dma/at91.h>
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/at91.h>
+
+/ {
+ model = "Atmel AT91SAM9x5 family SoC";
+ compatible = "atmel,at91sam9x5";
+ interrupt-parent = <&aic>;
+
+ aliases {
+ serial0 = &dbgu;
+ serial1 = &usart0;
+ serial2 = &usart1;
+ serial3 = &usart2;
+ gpio0 = &pioA;
+ gpio1 = &pioB;
+ gpio2 = &pioC;
+ gpio3 = &pioD;
+ tcb0 = &tcb0;
+ tcb1 = &tcb1;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ ssc0 = &ssc0;
+ pwm0 = &pwm0;
+ };
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm926ej-s";
+ device_type = "cpu";
+ };
+ };
+
+ memory {
+ reg = <0x20000000 0x10000000>;
+ };
+
+ clocks {
+ slow_xtal: slow_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ main_xtal: main_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ adc_op_clk: adc_op_clk{
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <5000000>;
+ };
+ };
+
+ sram: sram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x8000>;
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ aic: interrupt-controller@fffff000 {
+ #interrupt-cells = <3>;
+ compatible = "atmel,at91rm9200-aic";
+ interrupt-controller;
+ reg = <0xfffff000 0x200>;
+ atmel,external-irqs = <31>;
+ };
+
+ ramc0: ramc@ffffe800 {
+ compatible = "atmel,at91sam9g45-ddramc";
+ reg = <0xffffe800 0x200>;
+ clocks = <&ddrck>;
+ clock-names = "ddrck";
+ };
+
+ pmc: pmc@fffffc00 {
+ compatible = "atmel,at91sam9x5-pmc";
+ reg = <0xfffffc00 0x100>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ main_rc_osc: main_rc_osc {
+ compatible = "atmel,at91sam9x5-clk-main-rc-osc";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MOSCRCS>;
+ clock-frequency = <12000000>;
+ clock-accuracy = <50000000>;
+ };
+
+ main_osc: main_osc {
+ compatible = "atmel,at91rm9200-clk-main-osc";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MOSCS>;
+ clocks = <&main_xtal>;
+ };
+
+ main: mainck {
+ compatible = "atmel,at91sam9x5-clk-main";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MOSCSELS>;
+ clocks = <&main_rc_osc>, <&main_osc>;
+ };
+
+ plla: pllack {
+ compatible = "atmel,at91rm9200-clk-pll";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_LOCKA>;
+ clocks = <&main>;
+ reg = <0>;
+ atmel,clk-input-range = <2000000 32000000>;
+ #atmel,pll-clk-output-range-cells = <4>;
+ atmel,pll-clk-output-ranges = <745000000 800000000 0 0
+ 695000000 750000000 1 0
+ 645000000 700000000 2 0
+ 595000000 650000000 3 0
+ 545000000 600000000 0 1
+ 495000000 555000000 1 1
+ 445000000 500000000 2 1
+ 400000000 450000000 3 1>;
+ };
+
+ plladiv: plladivck {
+ compatible = "atmel,at91sam9x5-clk-plldiv";
+ #clock-cells = <0>;
+ clocks = <&plla>;
+ };
+
+ utmi: utmick {
+ compatible = "atmel,at91sam9x5-clk-utmi";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_LOCKU>;
+ clocks = <&main>;
+ };
+
+ mck: masterck {
+ compatible = "atmel,at91sam9x5-clk-master";
+ #clock-cells = <0>;
+ interrupts-extended = <&pmc AT91_PMC_MCKRDY>;
+ clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>;
+ atmel,clk-output-range = <0 133333333>;
+ atmel,clk-divisors = <1 2 4 3>;
+ atmel,master-clk-have-div3-pres;
+ };
+
+ usb: usbck {
+ compatible = "atmel,at91sam9x5-clk-usb";
+ #clock-cells = <0>;
+ clocks = <&plladiv>, <&utmi>;
+ };
+
+ prog: progck {
+ compatible = "atmel,at91sam9x5-clk-programmable";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-parent = <&pmc>;
+ clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>;
+
+ prog0: prog0 {
+ #clock-cells = <0>;
+ reg = <0>;
+ interrupts = <AT91_PMC_PCKRDY(0)>;
+ };
+
+ prog1: prog1 {
+ #clock-cells = <0>;
+ reg = <1>;
+ interrupts = <AT91_PMC_PCKRDY(1)>;
+ };
+ };
+
+ smd: smdclk {
+ compatible = "atmel,at91sam9x5-clk-smd";
+ #clock-cells = <0>;
+ clocks = <&plladiv>, <&utmi>;
+ };
+
+ systemck {
+ compatible = "atmel,at91rm9200-clk-system";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ddrck: ddrck {
+ #clock-cells = <0>;
+ reg = <2>;
+ clocks = <&mck>;
+ };
+
+ smdck: smdck {
+ #clock-cells = <0>;
+ reg = <4>;
+ clocks = <&smd>;
+ };
+
+ uhpck: uhpck {
+ #clock-cells = <0>;
+ reg = <6>;
+ clocks = <&usb>;
+ };
+
+ udpck: udpck {
+ #clock-cells = <0>;
+ reg = <7>;
+ clocks = <&usb>;
+ };
+
+ pck0: pck0 {
+ #clock-cells = <0>;
+ reg = <8>;
+ clocks = <&prog0>;
+ };
+
+ pck1: pck1 {
+ #clock-cells = <0>;
+ reg = <9>;
+ clocks = <&prog1>;
+ };
+ };
+
+ periphck {
+ compatible = "atmel,at91sam9x5-clk-peripheral";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mck>;
+
+ pioAB_clk: pioAB_clk {
+ #clock-cells = <0>;
+ reg = <2>;
+ };
+
+ pioCD_clk: pioCD_clk {
+ #clock-cells = <0>;
+ reg = <3>;
+ };
+
+ smd_clk: smd_clk {
+ #clock-cells = <0>;
+ reg = <4>;
+ };
+
+ usart0_clk: usart0_clk {
+ #clock-cells = <0>;
+ reg = <5>;
+ };
+
+ usart1_clk: usart1_clk {
+ #clock-cells = <0>;
+ reg = <6>;
+ };
+
+ usart2_clk: usart2_clk {
+ #clock-cells = <0>;
+ reg = <7>;
+ };
+
+ twi0_clk: twi0_clk {
+ reg = <9>;
+ #clock-cells = <0>;
+ };
+
+ twi1_clk: twi1_clk {
+ #clock-cells = <0>;
+ reg = <10>;
+ };
+
+ twi2_clk: twi2_clk {
+ #clock-cells = <0>;
+ reg = <11>;
+ };
+
+ mci0_clk: mci0_clk {
+ #clock-cells = <0>;
+ reg = <12>;
+ };
+
+ spi0_clk: spi0_clk {
+ #clock-cells = <0>;
+ reg = <13>;
+ };
+
+ spi1_clk: spi1_clk {
+ #clock-cells = <0>;
+ reg = <14>;
+ };
+
+ uart0_clk: uart0_clk {
+ #clock-cells = <0>;
+ reg = <15>;
+ };
+
+ uart1_clk: uart1_clk {
+ #clock-cells = <0>;
+ reg = <16>;
+ };
+
+ tcb0_clk: tcb0_clk {
+ #clock-cells = <0>;
+ reg = <17>;
+ };
+
+ pwm_clk: pwm_clk {
+ #clock-cells = <0>;
+ reg = <18>;
+ };
+
+ adc_clk: adc_clk {
+ #clock-cells = <0>;
+ reg = <19>;
+ };
+
+ dma0_clk: dma0_clk {
+ #clock-cells = <0>;
+ reg = <20>;
+ };
+
+ dma1_clk: dma1_clk {
+ #clock-cells = <0>;
+ reg = <21>;
+ };
+
+ uhphs_clk: uhphs_clk {
+ #clock-cells = <0>;
+ reg = <22>;
+ };
+
+ udphs_clk: udphs_clk {
+ #clock-cells = <0>;
+ reg = <23>;
+ };
+
+ mci1_clk: mci1_clk {
+ #clock-cells = <0>;
+ reg = <26>;
+ };
+
+ ssc0_clk: ssc0_clk {
+ #clock-cells = <0>;
+ reg = <28>;
+ };
+ };
+ };
+
+ rstc@fffffe00 {
+ compatible = "atmel,at91sam9g45-rstc";
+ reg = <0xfffffe00 0x10>;
+ };
+
+ shdwc@fffffe10 {
+ compatible = "atmel,at91sam9x5-shdwc";
+ reg = <0xfffffe10 0x10>;
+ };
+
+ pit: timer@fffffe30 {
+ compatible = "atmel,at91sam9260-pit";
+ reg = <0xfffffe30 0xf>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ clocks = <&mck>;
+ };
+
+ sckc@fffffe50 {
+ compatible = "atmel,at91sam9x5-sckc";
+ reg = <0xfffffe50 0x4>;
+
+ slow_osc: slow_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-osc";
+ #clock-cells = <0>;
+ clocks = <&slow_xtal>;
+ };
+
+ slow_rc_osc: slow_rc_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-rc-osc";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-accuracy = <50000000>;
+ };
+
+ clk32k: slck {
+ compatible = "atmel,at91sam9x5-clk-slow";
+ #clock-cells = <0>;
+ clocks = <&slow_rc_osc>, <&slow_osc>;
+ };
+ };
+
+ tcb0: timer@f8008000 {
+ compatible = "atmel,at91sam9x5-tcb";
+ reg = <0xf8008000 0x100>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tcb0_clk>;
+ clock-names = "t0_clk";
+ };
+
+ tcb1: timer@f800c000 {
+ compatible = "atmel,at91sam9x5-tcb";
+ reg = <0xf800c000 0x100>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tcb0_clk>;
+ clock-names = "t0_clk";
+ };
+
+ dma0: dma-controller@ffffec00 {
+ compatible = "atmel,at91sam9g45-dma";
+ reg = <0xffffec00 0x200>;
+ interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0>;
+ #dma-cells = <2>;
+ clocks = <&dma0_clk>;
+ clock-names = "dma_clk";
+ };
+
+ dma1: dma-controller@ffffee00 {
+ compatible = "atmel,at91sam9g45-dma";
+ reg = <0xffffee00 0x200>;
+ interrupts = <21 IRQ_TYPE_LEVEL_HIGH 0>;
+ #dma-cells = <2>;
+ clocks = <&dma1_clk>;
+ clock-names = "dma_clk";
+ };
+
+ pinctrl@fffff400 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff400 0xfffff400 0x800>;
+
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA9 periph A */
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA10 periph A with pullup */
+ };
+ };
+
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA0 periph A with pullup */
+ AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA1 periph A */
+ };
+
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA2 periph A */
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA3 periph A */
+ };
+
+ pinctrl_usart0_sck: usart0_sck-0 {
+ atmel,pins =
+ <AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA4 periph A */
+ };
+ };
+
+ usart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA5 periph A with pullup */
+ AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA6 periph A */
+ };
+
+ pinctrl_usart1_rts: usart1_rts-0 {
+ atmel,pins =
+ <AT91_PIOC 27 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC27 periph C */
+ };
+
+ pinctrl_usart1_cts: usart1_cts-0 {
+ atmel,pins =
+ <AT91_PIOC 28 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC28 periph C */
+ };
+
+ pinctrl_usart1_sck: usart1_sck-0 {
+ atmel,pins =
+ <AT91_PIOC 28 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC29 periph C */
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA7 periph A with pullup */
+ AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA8 periph A */
+ };
+
+ pinctrl_usart2_rts: usart2_rts-0 {
+ atmel,pins =
+ <AT91_PIOB 0 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB0 periph B */
+ };
+
+ pinctrl_usart2_cts: usart2_cts-0 {
+ atmel,pins =
+ <AT91_PIOB 1 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB1 periph B */
+ };
+
+ pinctrl_usart2_sck: usart2_sck-0 {
+ atmel,pins =
+ <AT91_PIOB 2 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB2 periph B */
+ };
+ };
+
+ uart0 {
+ pinctrl_uart0: uart0-0 {
+ atmel,pins =
+ <AT91_PIOC 8 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC8 periph C */
+ AT91_PIOC 9 AT91_PERIPH_C AT91_PINCTRL_PULL_UP>; /* PC9 periph C with pullup */
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1: uart1-0 {
+ atmel,pins =
+ <AT91_PIOC 16 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC16 periph C */
+ AT91_PIOC 17 AT91_PERIPH_C AT91_PINCTRL_PULL_UP>; /* PC17 periph C with pullup */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <AT91_PIOD 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD0 periph A Read Enable */
+ AT91_PIOD 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD1 periph A Write Enable */
+ AT91_PIOD 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD2 periph A Address Latch Enable */
+ AT91_PIOD 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD3 periph A Command Latch Enable */
+ AT91_PIOD 4 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP /* PD4 gpio Chip Enable pin pull_up */
+ AT91_PIOD 5 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP /* PD5 gpio RDY/BUSY pin pull_up */
+ AT91_PIOD 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD6 periph A Data bit 0 */
+ AT91_PIOD 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD7 periph A Data bit 1 */
+ AT91_PIOD 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD8 periph A Data bit 2 */
+ AT91_PIOD 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD9 periph A Data bit 3 */
+ AT91_PIOD 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD10 periph A Data bit 4 */
+ AT91_PIOD 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD11 periph A Data bit 5 */
+ AT91_PIOD 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD12 periph A Data bit 6 */
+ AT91_PIOD 13 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD13 periph A Data bit 7 */
+ };
+
+ pinctrl_nand_16bits: nand_16bits-0 {
+ atmel,pins =
+ <AT91_PIOD 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD14 periph A Data bit 8 */
+ AT91_PIOD 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD15 periph A Data bit 9 */
+ AT91_PIOD 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD16 periph A Data bit 10 */
+ AT91_PIOD 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD17 periph A Data bit 11 */
+ AT91_PIOD 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD18 periph A Data bit 12 */
+ AT91_PIOD 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD19 periph A Data bit 13 */
+ AT91_PIOD 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD20 periph A Data bit 14 */
+ AT91_PIOD 21 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD21 periph A Data bit 15 */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 {
+ atmel,pins =
+ <AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA17 periph A */
+ AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA16 periph A with pullup */
+ AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA15 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA18 periph A with pullup */
+ AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PA19 periph A with pullup */
+ AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA20 periph A with pullup */
+ };
+ };
+
+ mmc1 {
+ pinctrl_mmc1_slot0_clk_cmd_dat0: mmc1_slot0_clk_cmd_dat0-0 {
+ atmel,pins =
+ <AT91_PIOA 13 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA13 periph B */
+ AT91_PIOA 12 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PA12 periph B with pullup */
+ AT91_PIOA 11 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* PA11 periph B with pullup */
+ };
+
+ pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 {
+ atmel,pins =
+ <AT91_PIOA 2 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PA2 periph B with pullup */
+ AT91_PIOA 3 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PA3 periph B with pullup */
+ AT91_PIOA 4 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* PA4 periph B with pullup */
+ };
+ };
+
+ ssc0 {
+ pinctrl_ssc0_tx: ssc0_tx-0 {
+ atmel,pins =
+ <AT91_PIOA 24 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA24 periph B */
+ AT91_PIOA 25 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA25 periph B */
+ AT91_PIOA 26 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PA26 periph B */
+ };
+
+ pinctrl_ssc0_rx: ssc0_rx-0 {
+ atmel,pins =
+ <AT91_PIOA 27 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA27 periph B */
+ AT91_PIOA 28 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA28 periph B */
+ AT91_PIOA 29 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PA29 periph B */
+ };
+ };
+
+ spi0 {
+ pinctrl_spi0: spi0-0 {
+ atmel,pins =
+ <AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA11 periph A SPI0_MISO pin */
+ AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA12 periph A SPI0_MOSI pin */
+ AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA13 periph A SPI0_SPCK pin */
+ };
+ };
+
+ spi1 {
+ pinctrl_spi1: spi1-0 {
+ atmel,pins =
+ <AT91_PIOA 21 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA21 periph B SPI1_MISO pin */
+ AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA22 periph B SPI1_MOSI pin */
+ AT91_PIOA 23 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PA23 periph B SPI1_SPCK pin */
+ };
+ };
+
+ i2c0 {
+ pinctrl_i2c0: i2c0-0 {
+ atmel,pins =
+ <AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA30 periph A I2C0 data */
+ AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA31 periph A I2C0 clock */
+ };
+ };
+
+ i2c1 {
+ pinctrl_i2c1: i2c1-0 {
+ atmel,pins =
+ <AT91_PIOC 0 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC0 periph C I2C1 data */
+ AT91_PIOC 1 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC1 periph C I2C1 clock */
+ };
+ };
+
+ i2c2 {
+ pinctrl_i2c2: i2c2-0 {
+ atmel,pins =
+ <AT91_PIOB 4 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB4 periph B I2C2 data */
+ AT91_PIOB 5 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB5 periph B I2C2 clock */
+ };
+ };
+
+ i2c_gpio0 {
+ pinctrl_i2c_gpio0: i2c_gpio0-0 {
+ atmel,pins =
+ <AT91_PIOA 30 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE /* PA30 gpio multidrive I2C0 data */
+ AT91_PIOA 31 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>; /* PA31 gpio multidrive I2C0 clock */
+ };
+ };
+
+ i2c_gpio1 {
+ pinctrl_i2c_gpio1: i2c_gpio1-0 {
+ atmel,pins =
+ <AT91_PIOC 0 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE /* PC0 gpio multidrive I2C1 data */
+ AT91_PIOC 1 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>; /* PC1 gpio multidrive I2C1 clock */
+ };
+ };
+
+ i2c_gpio2 {
+ pinctrl_i2c_gpio2: i2c_gpio2-0 {
+ atmel,pins =
+ <AT91_PIOB 4 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE /* PB4 gpio multidrive I2C2 data */
+ AT91_PIOB 5 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>; /* PB5 gpio multidrive I2C2 clock */
+ };
+ };
+
+ tcb0 {
+ pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
+ atmel,pins = <AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
+ atmel,pins = <AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
+ atmel,pins = <AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
+ atmel,pins = <AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
+ atmel,pins = <AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
+ atmel,pins = <AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
+ atmel,pins = <AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
+ atmel,pins = <AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
+ atmel,pins = <AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ tcb1 {
+ pinctrl_tcb1_tclk0: tcb1_tclk0-0 {
+ atmel,pins = <AT91_PIOC 4 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tclk1: tcb1_tclk1-0 {
+ atmel,pins = <AT91_PIOC 7 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tclk2: tcb1_tclk2-0 {
+ atmel,pins = <AT91_PIOC 14 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tioa0: tcb1_tioa0-0 {
+ atmel,pins = <AT91_PIOC 2 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tioa1: tcb1_tioa1-0 {
+ atmel,pins = <AT91_PIOC 5 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tioa2: tcb1_tioa2-0 {
+ atmel,pins = <AT91_PIOC 12 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tiob0: tcb1_tiob0-0 {
+ atmel,pins = <AT91_PIOC 3 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tiob1: tcb1_tiob1-0 {
+ atmel,pins = <AT91_PIOC 6 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_tcb1_tiob2: tcb1_tiob2-0 {
+ atmel,pins = <AT91_PIOC 13 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+ };
+ };
+
+ pioA: gpio@fffff400 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioAB_clk>;
+ };
+
+ pioB: gpio@fffff600 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #gpio-lines = <19>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioAB_clk>;
+ };
+
+ pioC: gpio@fffff800 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioCD_clk>;
+ };
+
+ pioD: gpio@fffffa00 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x200>;
+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #gpio-lines = <22>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioCD_clk>;
+ };
+ };
+
+ ssc0: ssc@f0010000 {
+ compatible = "atmel,at91sam9g45-ssc";
+ reg = <0xf0010000 0x4000>;
+ interrupts = <28 IRQ_TYPE_LEVEL_HIGH 5>;
+ dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(13)>,
+ <&dma0 1 AT91_DMA_CFG_PER_ID(14)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
+ clocks = <&ssc0_clk>;
+ clock-names = "pclk";
+ status = "disabled";
+ };
+
+ mmc0: mmc@f0008000 {
+ compatible = "atmel,hsmci";
+ reg = <0xf0008000 0x600>;
+ interrupts = <12 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(0)>;
+ dma-names = "rxtx";
+ pinctrl-names = "default";
+ clocks = <&mci0_clk>;
+ clock-names = "mci_clk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@f000c000 {
+ compatible = "atmel,hsmci";
+ reg = <0xf000c000 0x600>;
+ interrupts = <26 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma1 1 AT91_DMA_CFG_PER_ID(0)>;
+ dma-names = "rxtx";
+ pinctrl-names = "default";
+ clocks = <&mci1_clk>;
+ clock-names = "mci_clk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ dbgu: serial@fffff200 {
+ compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
+ reg = <0xfffff200 0x200>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
+ dmas = <&dma1 1 AT91_DMA_CFG_PER_ID(8)>,
+ <&dma1 1 (AT91_DMA_CFG_PER_ID(9) | AT91_DMA_CFG_FIFOCFG_ASAP)>;
+ dma-names = "tx", "rx";
+ clocks = <&mck>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart0: serial@f801c000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf801c000 0x200>;
+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
+ dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(3)>,
+ <&dma0 1 (AT91_DMA_CFG_PER_ID(4) | AT91_DMA_CFG_FIFOCFG_ASAP)>;
+ dma-names = "tx", "rx";
+ clocks = <&usart0_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart1: serial@f8020000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf8020000 0x200>;
+ interrupts = <6 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
+ dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(5)>,
+ <&dma0 1 (AT91_DMA_CFG_PER_ID(6) | AT91_DMA_CFG_FIFOCFG_ASAP)>;
+ dma-names = "tx", "rx";
+ clocks = <&usart1_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart2: serial@f8024000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf8024000 0x200>;
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
+ dmas = <&dma1 1 AT91_DMA_CFG_PER_ID(12)>,
+ <&dma1 1 (AT91_DMA_CFG_PER_ID(13) | AT91_DMA_CFG_FIFOCFG_ASAP)>;
+ dma-names = "tx", "rx";
+ clocks = <&usart2_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ i2c0: i2c@f8010000 {
+ compatible = "atmel,at91sam9x5-i2c";
+ reg = <0xf8010000 0x100>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH 6>;
+ dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(7)>,
+ <&dma0 1 AT91_DMA_CFG_PER_ID(8)>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ clocks = <&twi0_clk>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@f8014000 {
+ compatible = "atmel,at91sam9x5-i2c";
+ reg = <0xf8014000 0x100>;
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH 6>;
+ dmas = <&dma1 1 AT91_DMA_CFG_PER_ID(5)>,
+ <&dma1 1 AT91_DMA_CFG_PER_ID(6)>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ clocks = <&twi1_clk>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@f8018000 {
+ compatible = "atmel,at91sam9x5-i2c";
+ reg = <0xf8018000 0x100>;
+ interrupts = <11 IRQ_TYPE_LEVEL_HIGH 6>;
+ dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(9)>,
+ <&dma0 1 AT91_DMA_CFG_PER_ID(10)>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ clocks = <&twi2_clk>;
+ status = "disabled";
+ };
+
+ uart0: serial@f8040000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf8040000 0x200>;
+ interrupts = <15 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ clocks = <&uart0_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ uart1: serial@f8044000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf8044000 0x200>;
+ interrupts = <16 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ clocks = <&uart1_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ adc0: adc@f804c000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91sam9x5-adc";
+ reg = <0xf804c000 0x100>;
+ interrupts = <19 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&adc_clk>,
+ <&adc_op_clk>;
+ clock-names = "adc_clk", "adc_op_clk";
+ atmel,adc-use-external-triggers;
+ atmel,adc-channels-used = <0xffff>;
+ atmel,adc-vref = <3300>;
+ atmel,adc-startup-time = <40>;
+ atmel,adc-res = <8 10>;
+ atmel,adc-res-names = "lowres", "highres";
+ atmel,adc-use-res = "highres";
+
+ trigger@0 {
+ reg = <0>;
+ trigger-name = "external-rising";
+ trigger-value = <0x1>;
+ trigger-external;
+ };
+
+ trigger@1 {
+ reg = <1>;
+ trigger-name = "external-falling";
+ trigger-value = <0x2>;
+ trigger-external;
+ };
+
+ trigger@2 {
+ reg = <2>;
+ trigger-name = "external-any";
+ trigger-value = <0x3>;
+ trigger-external;
+ };
+
+ trigger@3 {
+ reg = <3>;
+ trigger-name = "continuous";
+ trigger-value = <0x6>;
+ };
+ };
+
+ spi0: spi@f0000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xf0000000 0x100>;
+ interrupts = <13 IRQ_TYPE_LEVEL_HIGH 3>;
+ dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(1)>,
+ <&dma0 1 AT91_DMA_CFG_PER_ID(2)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi0>;
+ clocks = <&spi0_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+
+ spi1: spi@f0004000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xf0004000 0x100>;
+ interrupts = <14 IRQ_TYPE_LEVEL_HIGH 3>;
+ dmas = <&dma1 1 AT91_DMA_CFG_PER_ID(1)>,
+ <&dma1 1 AT91_DMA_CFG_PER_ID(2)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi1>;
+ clocks = <&spi1_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+
+ usb2: gadget@f803c000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91sam9g45-udc";
+ reg = <0x00500000 0x80000
+ 0xf803c000 0x400>;
+ interrupts = <23 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&utmi>, <&udphs_clk>;
+ clock-names = "hclk", "pclk";
+ status = "disabled";
+
+ ep0 {
+ reg = <0>;
+ atmel,fifo-size = <64>;
+ atmel,nb-banks = <1>;
+ };
+
+ ep1 {
+ reg = <1>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep2 {
+ reg = <2>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep3 {
+ reg = <3>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <3>;
+ atmel,can-dma;
+ };
+
+ ep4 {
+ reg = <4>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <3>;
+ atmel,can-dma;
+ };
+
+ ep5 {
+ reg = <5>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <3>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep6 {
+ reg = <6>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <3>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+ };
+
+ watchdog@fffffe40 {
+ compatible = "atmel,at91sam9260-wdt";
+ reg = <0xfffffe40 0x10>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ atmel,watchdog-type = "hardware";
+ atmel,reset-type = "all";
+ atmel,dbg-halt;
+ status = "disabled";
+ };
+
+ rtc@fffffeb0 {
+ compatible = "atmel,at91sam9x5-rtc";
+ reg = <0xfffffeb0 0x40>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ status = "disabled";
+ };
+
+ pwm0: pwm@f8034000 {
+ compatible = "atmel,at91sam9rl-pwm";
+ reg = <0xf8034000 0x300>;
+ interrupts = <18 IRQ_TYPE_LEVEL_HIGH 4>;
+ clocks = <&pwm_clk>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+ };
+
+ nand0: nand@40000000 {
+ compatible = "atmel,at91rm9200-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x40000000 0x10000000
+ 0xffffe000 0x600 /* PMECC Registers */
+ 0xffffe600 0x200 /* PMECC Error Location Registers */
+ 0x00108000 0x18000 /* PMECC looup table in ROM code */
+ >;
+ atmel,pmecc-lookup-table-offset = <0x0 0x8000>;
+ atmel,nand-addr-offset = <21>;
+ atmel,nand-cmd-offset = <22>;
+ atmel,nand-has-dma;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
+ gpios = <&pioD 5 GPIO_ACTIVE_HIGH
+ &pioD 4 GPIO_ACTIVE_HIGH
+ 0
+ >;
+ status = "disabled";
+ };
+
+ usb0: ohci@00600000 {
+ compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+ reg = <0x00600000 0x100000>;
+ interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>, <&uhpck>;
+ clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck";
+ status = "disabled";
+ };
+
+ usb1: ehci@00700000 {
+ compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
+ reg = <0x00700000 0x100000>;
+ interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&utmi>, <&uhphs_clk>, <&uhpck>;
+ clock-names = "usb_clk", "ehci_clk", "uhpck";
+ status = "disabled";
+ };
+ };
+
+ i2c@0 {
+ compatible = "i2c-gpio";
+ gpios = <&pioA 30 GPIO_ACTIVE_HIGH /* sda */
+ &pioA 31 GPIO_ACTIVE_HIGH /* scl */
+ >;
+ i2c-gpio,sda-open-drain;
+ i2c-gpio,scl-open-drain;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c_gpio0>;
+ status = "disabled";
+ };
+
+ i2c@1 {
+ compatible = "i2c-gpio";
+ gpios = <&pioC 0 GPIO_ACTIVE_HIGH /* sda */
+ &pioC 1 GPIO_ACTIVE_HIGH /* scl */
+ >;
+ i2c-gpio,sda-open-drain;
+ i2c-gpio,scl-open-drain;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c_gpio1>;
+ status = "disabled";
+ };
+
+ i2c@2 {
+ compatible = "i2c-gpio";
+ gpios = <&pioB 4 GPIO_ACTIVE_HIGH /* sda */
+ &pioB 5 GPIO_ACTIVE_HIGH /* scl */
+ >;
+ i2c-gpio,sda-open-drain;
+ i2c-gpio,scl-open-drain;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c_gpio2>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9x5_can.dtsi b/arch/arm/boot/dts/at91sam9x5_can.dtsi
new file mode 100644
index 000000000..8eb2f9c1b
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x5_can.dtsi
@@ -0,0 +1,71 @@
+/*
+ * at91sam9x5_can.dtsi - Device Tree Include file for AT91SAM9x5 SoC with 1
+ * Ethernet interface.
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ ahb {
+ apb {
+ pmc: pmc@fffffc00 {
+ periphck {
+ can0_clk: can0_clk {
+ #clock-cells = <0>;
+ reg = <29>;
+ };
+
+ can1_clk: can1_clk {
+ #clock-cells = <0>;
+ reg = <30>;
+ };
+ };
+ };
+
+ can0: can@f8000000 {
+ compatible = "atmel,at91sam9x5-can";
+ reg = <0xf8000000 0x300>;
+ interrupts = <29 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can0_rx_tx>;
+ clocks = <&can0_clk>;
+ clock-names = "can_clk";
+ status = "disabled";
+ };
+
+ can1: can@f8004000 {
+ compatible = "atmel,at91sam9x5-can";
+ reg = <0xf8004000 0x300>;
+ interrupts = <30 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can1_rx_tx>;
+ clocks = <&can1_clk>;
+ clock-names = "can_clk";
+ status = "disabled";
+ };
+
+ pinctrl@fffff400 {
+ can0 {
+ pinctrl_can0_rx_tx: can0_rx_tx {
+ atmel,pins =
+ <AT91_PIOA 9 AT91_PERIPH_B AT91_PINCTRL_NONE /* CANRX0, conflicts with DRXD */
+ AT91_PIOA 10 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* CANTX0, conflicts with DTXD */
+ };
+ };
+
+ can1 {
+ pinctrl_can1_rx_tx: can1_rx_tx {
+ atmel,pins =
+ <AT91_PIOA 6 AT91_PERIPH_B AT91_PINCTRL_NONE /* CANRX1, conflicts with RXD1 */
+ AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* CANTX1, conflicts with TXD1 */
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9x5_isi.dtsi b/arch/arm/boot/dts/at91sam9x5_isi.dtsi
new file mode 100644
index 000000000..8fc45ca4d
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x5_isi.dtsi
@@ -0,0 +1,72 @@
+/*
+ * at91sam9x5_isi.dtsi - Device Tree Include file for AT91SAM9x5 SoC with an
+ * Image Sensor Interface.
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ isi {
+ pinctrl_isi_data_0_7: isi-0-data-0-7 {
+ atmel,pins =
+ <AT91_PIOC 0 AT91_PERIPH_B AT91_PINCTRL_NONE /* ISI_D0, conflicts with LCDDAT0 */
+ AT91_PIOC 1 AT91_PERIPH_B AT91_PINCTRL_NONE /* ISI_D1, conflicts with LCDDAT1 */
+ AT91_PIOC 2 AT91_PERIPH_B AT91_PINCTRL_NONE /* ISI_D2, conflicts with LCDDAT2 */
+ AT91_PIOC 3 AT91_PERIPH_B AT91_PINCTRL_NONE /* ISI_D3, conflicts with LCDDAT3 */
+ AT91_PIOC 4 AT91_PERIPH_B AT91_PINCTRL_NONE /* ISI_D4, conflicts with LCDDAT4 */
+ AT91_PIOC 5 AT91_PERIPH_B AT91_PINCTRL_NONE /* ISI_D5, conflicts with LCDDAT5 */
+ AT91_PIOC 6 AT91_PERIPH_B AT91_PINCTRL_NONE /* ISI_D6, conflicts with LCDDAT6 */
+ AT91_PIOC 7 AT91_PERIPH_B AT91_PINCTRL_NONE /* ISI_D7, conflicts with LCDDAT7 */
+ AT91_PIOC 12 AT91_PERIPH_B AT91_PINCTRL_NONE /* ISI_PCK, conflicts with LCDDAT12 */
+ AT91_PIOC 14 AT91_PERIPH_B AT91_PINCTRL_NONE /* ISI_HSYNC, conflicts with LCDDAT14 */
+ AT91_PIOC 13 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* ISI_VSYNC, conflicts with LCDDAT13 */
+ };
+
+ pinctrl_isi_data_8_9: isi-0-data-8-9 {
+ atmel,pins =
+ <AT91_PIOC 8 AT91_PERIPH_B AT91_PINCTRL_NONE /* ISI_D8, conflicts with LCDDAT8 */
+ AT91_PIOC 9 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* ISI_D9, conflicts with LCDDAT9 */
+ };
+
+ pinctrl_isi_data_10_11: isi-0-data-10-11 {
+ atmel,pins =
+ <AT91_PIOC 10 AT91_PERIPH_B AT91_PINCTRL_NONE /* ISI_D10, conflicts with LCDDAT10 */
+ AT91_PIOC 11 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* ISI_D11, conflicts with LCDDAT11 */
+ };
+ };
+ };
+
+ pmc: pmc@fffffc00 {
+ periphck {
+ isi_clk: isi_clk {
+ #clock-cells = <0>;
+ reg = <25>;
+ };
+ };
+ };
+
+ isi: isi@f8048000 {
+ compatible = "atmel,at91sam9g45-isi";
+ reg = <0xf8048000 0x4000>;
+ interrupts = <25 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_isi_data_0_7>;
+ clocks = <&isi_clk>;
+ clock-names = "isi_clk";
+ status = "disabled";
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9x5_lcd.dtsi b/arch/arm/boot/dts/at91sam9x5_lcd.dtsi
new file mode 100644
index 000000000..485302e82
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x5_lcd.dtsi
@@ -0,0 +1,26 @@
+/*
+ * at91sam9x5_lcd.dtsi - Device Tree Include file for AT91SAM9x5 SoC with an
+ * LCD controller.
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ ahb {
+ apb {
+ pmc: pmc@fffffc00 {
+ periphck {
+ lcdc_clk: lcdc_clk {
+ #clock-cells = <0>;
+ reg = <25>;
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9x5_macb0.dtsi b/arch/arm/boot/dts/at91sam9x5_macb0.dtsi
new file mode 100644
index 000000000..73d7e3096
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x5_macb0.dtsi
@@ -0,0 +1,67 @@
+/*
+ * at91sam9x5_macb0.dtsi - Device Tree Include file for AT91SAM9x5 SoC with 1
+ * Ethernet interface.
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ macb0 {
+ pinctrl_macb0_rmii: macb0_rmii-0 {
+ atmel,pins =
+ <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB0 periph A */
+ AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB1 periph A */
+ AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB2 periph A */
+ AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB3 periph A */
+ AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB4 periph A */
+ AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB5 periph A */
+ AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB6 periph A */
+ AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB7 periph A */
+ AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB9 periph A */
+ AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB10 periph A */
+ };
+
+ pinctrl_macb0_rmii_mii: macb0_rmii_mii-0 {
+ atmel,pins =
+ <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB8 periph A */
+ AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB11 periph A */
+ AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB12 periph A */
+ AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB13 periph A */
+ AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB14 periph A */
+ AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB15 periph A */
+ AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB16 periph A */
+ AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB17 periph A */
+ };
+ };
+ };
+
+ pmc: pmc@fffffc00 {
+ periphck {
+ macb0_clk: macb0_clk {
+ #clock-cells = <0>;
+ reg = <24>;
+ };
+ };
+ };
+
+ macb0: ethernet@f802c000 {
+ compatible = "cdns,at91sam9260-macb", "cdns,macb";
+ reg = <0xf802c000 0x100>;
+ interrupts = <24 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb0_rmii>;
+ clocks = <&macb0_clk>, <&macb0_clk>;
+ clock-names = "hclk", "pclk";
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9x5_macb1.dtsi b/arch/arm/boot/dts/at91sam9x5_macb1.dtsi
new file mode 100644
index 000000000..d81980c40
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x5_macb1.dtsi
@@ -0,0 +1,55 @@
+/*
+ * at91sam9x5_macb1.dtsi - Device Tree Include file for AT91SAM9x5 SoC with 2
+ * Ethernet interfaces.
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ macb1 {
+ pinctrl_macb1_rmii: macb1_rmii-0 {
+ atmel,pins =
+ <AT91_PIOC 16 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC16 periph B */
+ AT91_PIOC 18 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC18 periph B */
+ AT91_PIOC 19 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC19 periph B */
+ AT91_PIOC 20 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC20 periph B */
+ AT91_PIOC 21 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC21 periph B */
+ AT91_PIOC 27 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC27 periph B */
+ AT91_PIOC 28 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC28 periph B */
+ AT91_PIOC 29 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC29 periph B */
+ AT91_PIOC 30 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC30 periph B */
+ AT91_PIOC 31 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC31 periph B */
+ };
+ };
+ };
+
+ pmc: pmc@fffffc00 {
+ periphck {
+ macb1_clk: macb1_clk {
+ #clock-cells = <0>;
+ reg = <27>;
+ };
+ };
+ };
+
+ macb1: ethernet@f8030000 {
+ compatible = "cdns,at91sam9260-macb", "cdns,macb";
+ reg = <0xf8030000 0x100>;
+ interrupts = <27 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb1_rmii>;
+ clocks = <&macb1_clk>, <&macb1_clk>;
+ clock-names = "hclk", "pclk";
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9x5_usart3.dtsi b/arch/arm/boot/dts/at91sam9x5_usart3.dtsi
new file mode 100644
index 000000000..43bb5b51c
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x5_usart3.dtsi
@@ -0,0 +1,69 @@
+/*
+ * at91sam9x5_usart3.dtsi - Device Tree Include file for AT91SAM9x5 SoC with
+ * 4 USART.
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ aliases {
+ serial4 = &usart3;
+ };
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ usart3 {
+ pinctrl_usart3: usart3-0 {
+ atmel,pins =
+ <AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PC22 periph B with pullup */
+ AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC23 periph B */
+ };
+
+ pinctrl_usart3_rts: usart3_rts-0 {
+ atmel,pins =
+ <AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC24 periph B */
+ };
+
+ pinctrl_usart3_cts: usart3_cts-0 {
+ atmel,pins =
+ <AT91_PIOC 25 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC25 periph B */
+ };
+
+ pinctrl_usart3_sck: usart3_sck-0 {
+ atmel,pins =
+ <AT91_PIOC 26 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC26 periph B */
+ };
+ };
+ };
+
+ pmc: pmc@fffffc00 {
+ periphck {
+ usart3_clk: usart3_clk {
+ #clock-cells = <0>;
+ reg = <8>;
+ };
+ };
+ };
+
+ usart3: serial@f8028000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf8028000 0x200>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart3>;
+ dmas = <&dma1 1 AT91_DMA_CFG_PER_ID(14)>,
+ <&dma1 1 (AT91_DMA_CFG_PER_ID(15) | AT91_DMA_CFG_FIFOCFG_ASAP)>;
+ dma-names = "tx", "rx";
+ clocks = <&usart3_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9x5cm.dtsi b/arch/arm/boot/dts/at91sam9x5cm.dtsi
new file mode 100644
index 000000000..26112ebd1
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x5cm.dtsi
@@ -0,0 +1,111 @@
+/*
+ * at91sam9x5cm.dtsi - Device Tree Include file for AT91SAM9x5 CPU Module
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/ {
+ memory {
+ reg = <0x20000000 0x8000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+ };
+
+ clocks {
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ 1wire_cm {
+ pinctrl_1wire_cm: 1wire_cm-0 {
+ atmel,pins = <AT91_PIOB 18 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>; /* PB18 multidrive, conflicts with led */
+ };
+ };
+ };
+
+ rtc@fffffeb0 {
+ status = "okay";
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ atmel,has-pmecc; /* Enable PMECC */
+ atmel,pmecc-cap = <2>;
+ atmel,pmecc-sector-size = <512>;
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ uboot@40000 {
+ label = "u-boot";
+ reg = <0x40000 0x80000>;
+ };
+
+ ubootenv@c0000 {
+ label = "U-Boot Env";
+ reg = <0xc0000 0x140000>;
+ };
+
+ kernel@200000 {
+ label = "kernel";
+ reg = <0x200000 0x600000>;
+ };
+
+ rootfs@800000 {
+ label = "rootfs";
+ reg = <0x800000 0x1f800000>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ pb18 {
+ label = "pb18";
+ gpios = <&pioB 18 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ pd21 {
+ label = "pd21";
+ gpios = <&pioD 21 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ 1wire_cm {
+ compatible = "w1-gpio";
+ gpios = <&pioB 18 GPIO_ACTIVE_HIGH>;
+ linux,open-drain;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_1wire_cm>;
+ status = "okay";
+ };
+
+};
diff --git a/arch/arm/boot/dts/at91sam9x5ek.dtsi b/arch/arm/boot/dts/at91sam9x5ek.dtsi
new file mode 100644
index 000000000..cc83a37a7
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x5ek.dtsi
@@ -0,0 +1,189 @@
+/*
+ * at91sam9x5ek.dtsi - Device Tree file for AT91SAM9x5CM Base board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+#include "at91sam9x5cm.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9X5-EK";
+ compatible = "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs";
+ };
+
+ ahb {
+ apb {
+ mmc0: mmc@f0008000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0
+ &pinctrl_mmc0_slot0_clk_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ mmc1: mmc@f000c000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc1
+ &pinctrl_mmc1_slot0_clk_cmd_dat0
+ &pinctrl_mmc1_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 14 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ usart0: serial@f801c000 {
+ status = "okay";
+ };
+
+ usb2: gadget@f803c000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_board_usb2>;
+ atmel,vbus-gpio = <&pioB 16 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ isi: isi@f8048000 {
+ status = "disabled";
+ port {
+ isi_0: endpoint@0 {
+ remote-endpoint = <&ov2640_0>;
+ bus-width = <8>;
+ };
+ };
+ };
+
+ i2c0: i2c@f8010000 {
+ status = "okay";
+
+ wm8731: wm8731@1a {
+ compatible = "wm8731";
+ reg = <0x1a>;
+ };
+
+ ov2640: camera@0x30 {
+ compatible = "ovti,ov2640";
+ reg = <0x30>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pck0_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>;
+ resetb-gpios = <&pioA 7 GPIO_ACTIVE_LOW>;
+ pwdn-gpios = <&pioA 13 GPIO_ACTIVE_HIGH>;
+ clocks = <&pck0>;
+ clock-names = "xvclk";
+ assigned-clocks = <&pck0>;
+ assigned-clock-rates = <25000000>;
+ status = "disabled";
+
+ port {
+ ov2640_0: endpoint {
+ remote-endpoint = <&isi_0>;
+ bus-width = <8>;
+ };
+ };
+ };
+ };
+
+ pinctrl@fffff400 {
+ camera_sensor {
+ pinctrl_pck0_as_isi_mck: pck0_as_isi_mck-0 {
+ atmel,pins =
+ <AT91_PIOC 15 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* ISI_MCK */
+ };
+
+ pinctrl_sensor_power: sensor_power-0 {
+ atmel,pins =
+ <AT91_PIOA 13 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_sensor_reset: sensor_reset-0 {
+ atmel,pins =
+ <AT91_PIOA 7 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+ };
+ };
+
+ mmc0 {
+ pinctrl_board_mmc0: mmc0-board {
+ atmel,pins =
+ <AT91_PIOD 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PD15 gpio CD pin pull up and deglitch */
+ };
+ };
+
+ mmc1 {
+ pinctrl_board_mmc1: mmc1-board {
+ atmel,pins =
+ <AT91_PIOD 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PD14 gpio CD pin pull up and deglitch */
+ };
+ };
+
+ usb2 {
+ pinctrl_board_usb2: usb2-board {
+ atmel,pins =
+ <AT91_PIOB 16 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PB16 gpio vbus sense, deglitch */
+ };
+ };
+ };
+
+ spi0: spi@f0000000 {
+ status = "okay";
+ cs-gpios = <&pioA 14 0>, <0>, <0>, <0>;
+ m25p80@0 {
+ compatible = "atmel,at25df321a";
+ spi-max-frequency = <50000000>;
+ reg = <0>;
+ };
+ };
+
+ watchdog@fffffe40 {
+ status = "okay";
+ };
+
+ ssc0: ssc@f0010000 {
+ status = "okay";
+ };
+ };
+
+ usb0: ohci@00600000 {
+ status = "okay";
+ num-ports = <3>;
+ atmel,vbus-gpio = <0 /* &pioD 18 GPIO_ACTIVE_LOW *//* Activate to have access to port A */
+ &pioD 19 GPIO_ACTIVE_LOW
+ &pioD 20 GPIO_ACTIVE_LOW
+ >;
+ };
+
+ usb1: ehci@00700000 {
+ status = "okay";
+ };
+ };
+
+ sound {
+ compatible = "atmel,sam9x5-wm8731-audio";
+
+ atmel,model = "wm8731 @ AT91SAM9X5EK";
+
+ atmel,audio-routing =
+ "Headphone Jack", "RHPOUT",
+ "Headphone Jack", "LHPOUT",
+ "LLINEIN", "Line In Jack",
+ "RLINEIN", "Line In Jack";
+
+ atmel,ssc-controller = <&ssc0>;
+ atmel,audio-codec = <&wm8731>;
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9xe.dtsi b/arch/arm/boot/dts/at91sam9xe.dtsi
new file mode 100644
index 000000000..0278f63b2
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9xe.dtsi
@@ -0,0 +1,60 @@
+/*
+ * at91sam9xe.dtsi - Device Tree Include file for AT91SAM9XE family SoC
+ *
+ * Copyright (C) 2015 Atmel,
+ * 2015 Alexandre Belloni <alexandre.Belloni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "at91sam9260.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9XE family SoC";
+ compatible = "atmel,at91sam9xe", "atmel,at91sam9260";
+
+ sram0: sram@002ff000 {
+ status = "disabled";
+ };
+
+ sram1: sram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x4000>;
+ };
+};
diff --git a/arch/arm/boot/dts/atlas6-evb.dts b/arch/arm/boot/dts/atlas6-evb.dts
new file mode 100644
index 000000000..ab042ca8d
--- /dev/null
+++ b/arch/arm/boot/dts/atlas6-evb.dts
@@ -0,0 +1,78 @@
+/*
+ * DTS file for CSR SiRFatlas6 Evaluation Board
+ *
+ * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/dts-v1/;
+
+/include/ "atlas6.dtsi"
+
+/ {
+ model = "CSR SiRFatlas6 Evaluation Board";
+ compatible = "sirf,atlas6-cb", "sirf,atlas6";
+
+ memory {
+ reg = <0x00000000 0x20000000>;
+ };
+
+ axi {
+ peri-iobg {
+ uart@b0060000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_a>;
+ };
+ spi@b00d0000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins_a>;
+ spi@0 {
+ compatible = "spidev";
+ reg = <0>;
+ spi-max-frequency = <1000000>;
+ };
+ };
+ spi@b0170000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins_a>;
+ };
+ i2c0: i2c@b00e0000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ lcd@40 {
+ compatible = "sirf,lcd";
+ reg = <0x40>;
+ };
+ };
+
+ };
+ disp-iobg {
+ lcd@90010000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_24pins_a>;
+ };
+ };
+ };
+ display: display@0 {
+ panels {
+ panel0: panel@0 {
+ panel-name = "Innolux TFT";
+ hactive = <800>;
+ vactive = <480>;
+ left_margin = <20>;
+ right_margin = <234>;
+ upper_margin = <3>;
+ lower_margin = <41>;
+ hsync_len = <3>;
+ vsync_len = <2>;
+ pixclock = <33264000>;
+ sync = <3>;
+ timing = <0x88>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/atlas6.dtsi b/arch/arm/boot/dts/atlas6.dtsi
new file mode 100644
index 000000000..295986674
--- /dev/null
+++ b/arch/arm/boot/dts/atlas6.dtsi
@@ -0,0 +1,802 @@
+/*
+ * DTS file for CSR SiRFatlas6 SoC
+ *
+ * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/include/ "skeleton.dtsi"
+/ {
+ compatible = "sirf,atlas6";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&intc>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ reg = <0x0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <32768>;
+ i-cache-size = <32768>;
+ /* from bootloader */
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ clocks = <&clks 12>;
+ operating-points = <
+ /* kHz uV */
+ 200000 1025000
+ 400000 1025000
+ 600000 1050000
+ 800000 1100000
+ >;
+ clock-latency = <150000>;
+ };
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <29>;
+ };
+
+ axi {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x40000000 0x40000000 0x80000000>;
+
+ intc: interrupt-controller@80020000 {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "sirf,prima2-intc";
+ reg = <0x80020000 0x1000>;
+ };
+
+ sys-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x88000000 0x88000000 0x40000>;
+
+ clks: clock-controller@88000000 {
+ compatible = "sirf,atlas6-clkc";
+ reg = <0x88000000 0x1000>;
+ interrupts = <3>;
+ #clock-cells = <1>;
+ };
+
+ rstc: reset-controller@88010000 {
+ compatible = "sirf,prima2-rstc";
+ reg = <0x88010000 0x1000>;
+ #reset-cells = <1>;
+ };
+
+ rsc-controller@88020000 {
+ compatible = "sirf,prima2-rsc";
+ reg = <0x88020000 0x1000>;
+ };
+
+ cphifbg@88030000 {
+ compatible = "sirf,prima2-cphifbg";
+ reg = <0x88030000 0x1000>;
+ clocks = <&clks 42>;
+ };
+ };
+
+ mem-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x90000000 0x90000000 0x10000>;
+
+ memory-controller@90000000 {
+ compatible = "sirf,prima2-memc";
+ reg = <0x90000000 0x2000>;
+ interrupts = <27>;
+ clocks = <&clks 5>;
+ };
+
+ memc-monitor {
+ compatible = "sirf,prima2-memcmon";
+ reg = <0x90002000 0x200>;
+ interrupts = <4>;
+ clocks = <&clks 32>;
+ };
+ };
+
+ disp-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x90010000 0x90010000 0x30000>;
+
+ lcd@90010000 {
+ compatible = "sirf,prima2-lcd";
+ reg = <0x90010000 0x20000>;
+ interrupts = <30>;
+ clocks = <&clks 34>;
+ display=<&display>;
+ /* later transfer to pwm */
+ bl-gpio = <&gpio 7 0>;
+ default-panel = <&panel0>;
+ };
+
+ vpp@90020000 {
+ compatible = "sirf,prima2-vpp";
+ reg = <0x90020000 0x10000>;
+ interrupts = <31>;
+ clocks = <&clks 35>;
+ resets = <&rstc 6>;
+ };
+ };
+
+ graphics-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x98000000 0x98000000 0x8000000>;
+
+ graphics@98000000 {
+ compatible = "powervr,sgx510";
+ reg = <0x98000000 0x8000000>;
+ interrupts = <6>;
+ clocks = <&clks 32>;
+ };
+ };
+
+ graphics2d-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0xa0000000 0xa0000000 0x8000000>;
+
+ ble@a0000000 {
+ compatible = "sirf,atlas6-ble";
+ reg = <0xa0000000 0x2000>;
+ interrupts = <5>;
+ clocks = <&clks 33>;
+ };
+ };
+
+ dsp-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0xa8000000 0xa8000000 0x2000000>;
+
+ dspif@a8000000 {
+ compatible = "sirf,prima2-dspif";
+ reg = <0xa8000000 0x10000>;
+ interrupts = <9>;
+ resets = <&rstc 1>;
+ };
+
+ gps@a8010000 {
+ compatible = "sirf,prima2-gps";
+ reg = <0xa8010000 0x10000>;
+ interrupts = <7>;
+ clocks = <&clks 9>;
+ resets = <&rstc 2>;
+ };
+
+ dsp@a9000000 {
+ compatible = "sirf,prima2-dsp";
+ reg = <0xa9000000 0x1000000>;
+ interrupts = <8>;
+ clocks = <&clks 8>;
+ resets = <&rstc 0>;
+ };
+ };
+
+ peri-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0xb0000000 0xb0000000 0x180000>,
+ <0x56000000 0x56000000 0x1b00000>;
+
+ timer@b0020000 {
+ compatible = "sirf,prima2-tick";
+ reg = <0xb0020000 0x1000>;
+ interrupts = <0>;
+ clocks = <&clks 11>;
+ };
+
+ nand@b0030000 {
+ compatible = "sirf,prima2-nand";
+ reg = <0xb0030000 0x10000>;
+ interrupts = <41>;
+ clocks = <&clks 26>;
+ };
+
+ audio@b0040000 {
+ compatible = "sirf,prima2-audio";
+ reg = <0xb0040000 0x10000>;
+ interrupts = <35>;
+ clocks = <&clks 27>;
+ };
+
+ uart0: uart@b0050000 {
+ cell-index = <0>;
+ compatible = "sirf,prima2-uart";
+ reg = <0xb0050000 0x1000>;
+ interrupts = <17>;
+ fifosize = <128>;
+ clocks = <&clks 13>;
+ dmas = <&dmac1 5>, <&dmac0 2>;
+ dma-names = "rx", "tx";
+ };
+
+ uart1: uart@b0060000 {
+ cell-index = <1>;
+ compatible = "sirf,prima2-uart";
+ reg = <0xb0060000 0x1000>;
+ interrupts = <18>;
+ fifosize = <32>;
+ clocks = <&clks 14>;
+ dma-names = "no-rx", "no-tx";
+ };
+
+ uart2: uart@b0070000 {
+ cell-index = <2>;
+ compatible = "sirf,prima2-uart";
+ reg = <0xb0070000 0x1000>;
+ interrupts = <19>;
+ fifosize = <128>;
+ clocks = <&clks 15>;
+ dmas = <&dmac0 6>, <&dmac0 7>;
+ dma-names = "rx", "tx";
+ };
+
+ usp0: usp@b0080000 {
+ cell-index = <0>;
+ compatible = "sirf,prima2-usp";
+ reg = <0xb0080000 0x10000>;
+ interrupts = <20>;
+ fifosize = <128>;
+ clocks = <&clks 28>;
+ dmas = <&dmac1 1>, <&dmac1 2>;
+ dma-names = "rx", "tx";
+ };
+
+ usp1: usp@b0090000 {
+ cell-index = <1>;
+ compatible = "sirf,prima2-usp";
+ reg = <0xb0090000 0x10000>;
+ interrupts = <21>;
+ fifosize = <128>;
+ clocks = <&clks 29>;
+ dmas = <&dmac0 14>, <&dmac0 15>;
+ dma-names = "rx", "tx";
+ };
+
+ dmac0: dma-controller@b00b0000 {
+ cell-index = <0>;
+ compatible = "sirf,prima2-dmac";
+ reg = <0xb00b0000 0x10000>;
+ interrupts = <12>;
+ clocks = <&clks 24>;
+ #dma-cells = <1>;
+ };
+
+ dmac1: dma-controller@b0160000 {
+ cell-index = <1>;
+ compatible = "sirf,prima2-dmac";
+ reg = <0xb0160000 0x10000>;
+ interrupts = <13>;
+ clocks = <&clks 25>;
+ #dma-cells = <1>;
+ };
+
+ vip@b00C0000 {
+ compatible = "sirf,prima2-vip";
+ reg = <0xb00C0000 0x10000>;
+ clocks = <&clks 31>;
+ interrupts = <14>;
+ sirf,vip-dma-rx-channel = <16>;
+ };
+
+ spi0: spi@b00d0000 {
+ cell-index = <0>;
+ compatible = "sirf,prima2-spi";
+ reg = <0xb00d0000 0x10000>;
+ interrupts = <15>;
+ sirf,spi-num-chipselects = <1>;
+ dmas = <&dmac1 9>,
+ <&dmac1 4>;
+ dma-names = "rx", "tx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clks 19>;
+ resets = <&rstc 26>;
+ status = "disabled";
+ };
+
+ spi1: spi@b0170000 {
+ cell-index = <1>;
+ compatible = "sirf,prima2-spi";
+ reg = <0xb0170000 0x10000>;
+ interrupts = <16>;
+ sirf,spi-num-chipselects = <1>;
+ dmas = <&dmac0 12>,
+ <&dmac0 13>;
+ dma-names = "rx", "tx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clks 20>;
+ resets = <&rstc 27>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@b00e0000 {
+ cell-index = <0>;
+ compatible = "sirf,prima2-i2c";
+ reg = <0xb00e0000 0x10000>;
+ interrupts = <24>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clks 17>;
+ };
+
+ i2c1: i2c@b00f0000 {
+ cell-index = <1>;
+ compatible = "sirf,prima2-i2c";
+ reg = <0xb00f0000 0x10000>;
+ interrupts = <25>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clks 18>;
+ };
+
+ tsc@b0110000 {
+ compatible = "sirf,prima2-tsc";
+ reg = <0xb0110000 0x10000>;
+ interrupts = <33>;
+ clocks = <&clks 16>;
+ };
+
+ gpio: pinctrl@b0120000 {
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ compatible = "sirf,atlas6-pinctrl";
+ reg = <0xb0120000 0x10000>;
+ interrupts = <43 44 45 46 47>;
+ gpio-controller;
+ interrupt-controller;
+
+ lcd_16pins_a: lcd0@0 {
+ lcd {
+ sirf,pins = "lcd_16bitsgrp";
+ sirf,function = "lcd_16bits";
+ };
+ };
+ lcd_18pins_a: lcd0@1 {
+ lcd {
+ sirf,pins = "lcd_18bitsgrp";
+ sirf,function = "lcd_18bits";
+ };
+ };
+ lcd_24pins_a: lcd0@2 {
+ lcd {
+ sirf,pins = "lcd_24bitsgrp";
+ sirf,function = "lcd_24bits";
+ };
+ };
+ lcdrom_pins_a: lcdrom0@0 {
+ lcd {
+ sirf,pins = "lcdromgrp";
+ sirf,function = "lcdrom";
+ };
+ };
+ uart0_pins_a: uart0@0 {
+ uart {
+ sirf,pins = "uart0grp";
+ sirf,function = "uart0";
+ };
+ };
+ uart0_noflow_pins_a: uart0@1 {
+ uart {
+ sirf,pins = "uart0_nostreamctrlgrp";
+ sirf,function = "uart0_nostreamctrl";
+ };
+ };
+ uart1_pins_a: uart1@0 {
+ uart {
+ sirf,pins = "uart1grp";
+ sirf,function = "uart1";
+ };
+ };
+ uart2_pins_a: uart2@0 {
+ uart {
+ sirf,pins = "uart2grp";
+ sirf,function = "uart2";
+ };
+ };
+ uart2_noflow_pins_a: uart2@1 {
+ uart {
+ sirf,pins = "uart2_nostreamctrlgrp";
+ sirf,function = "uart2_nostreamctrl";
+ };
+ };
+ spi0_pins_a: spi0@0 {
+ spi {
+ sirf,pins = "spi0grp";
+ sirf,function = "spi0";
+ };
+ };
+ spi1_pins_a: spi1@0 {
+ spi {
+ sirf,pins = "spi1grp";
+ sirf,function = "spi1";
+ };
+ };
+ i2c0_pins_a: i2c0@0 {
+ i2c {
+ sirf,pins = "i2c0grp";
+ sirf,function = "i2c0";
+ };
+ };
+ i2c1_pins_a: i2c1@0 {
+ i2c {
+ sirf,pins = "i2c1grp";
+ sirf,function = "i2c1";
+ };
+ };
+ pwm0_pins_a: pwm0@0 {
+ pwm {
+ sirf,pins = "pwm0grp";
+ sirf,function = "pwm0";
+ };
+ };
+ pwm1_pins_a: pwm1@0 {
+ pwm {
+ sirf,pins = "pwm1grp";
+ sirf,function = "pwm1";
+ };
+ };
+ pwm2_pins_a: pwm2@0 {
+ pwm {
+ sirf,pins = "pwm2grp";
+ sirf,function = "pwm2";
+ };
+ };
+ pwm3_pins_a: pwm3@0 {
+ pwm {
+ sirf,pins = "pwm3grp";
+ sirf,function = "pwm3";
+ };
+ };
+ pwm4_pins_a: pwm4@0 {
+ pwm {
+ sirf,pins = "pwm4grp";
+ sirf,function = "pwm4";
+ };
+ };
+ gps_pins_a: gps@0 {
+ gps {
+ sirf,pins = "gpsgrp";
+ sirf,function = "gps";
+ };
+ };
+ vip_pins_a: vip@0 {
+ vip {
+ sirf,pins = "vipgrp";
+ sirf,function = "vip";
+ };
+ };
+ sdmmc0_pins_a: sdmmc0@0 {
+ sdmmc0 {
+ sirf,pins = "sdmmc0grp";
+ sirf,function = "sdmmc0";
+ };
+ };
+ sdmmc1_pins_a: sdmmc1@0 {
+ sdmmc1 {
+ sirf,pins = "sdmmc1grp";
+ sirf,function = "sdmmc1";
+ };
+ };
+ sdmmc2_pins_a: sdmmc2@0 {
+ sdmmc2 {
+ sirf,pins = "sdmmc2grp";
+ sirf,function = "sdmmc2";
+ };
+ };
+ sdmmc2_nowp_pins_a: sdmmc2_nowp@0 {
+ sdmmc2_nowp {
+ sirf,pins = "sdmmc2_nowpgrp";
+ sirf,function = "sdmmc2_nowp";
+ };
+ };
+ sdmmc3_pins_a: sdmmc3@0 {
+ sdmmc3 {
+ sirf,pins = "sdmmc3grp";
+ sirf,function = "sdmmc3";
+ };
+ };
+ sdmmc5_pins_a: sdmmc5@0 {
+ sdmmc5 {
+ sirf,pins = "sdmmc5grp";
+ sirf,function = "sdmmc5";
+ };
+ };
+ i2s_mclk_pins_a: i2s_mclk@0 {
+ i2s_mclk {
+ sirf,pins = "i2smclkgrp";
+ sirf,function = "i2s_mclk";
+ };
+ };
+ i2s_ext_clk_input_pins_a: i2s_ext_clk_input@0 {
+ i2s_ext_clk_input {
+ sirf,pins = "i2s_ext_clk_inputgrp";
+ sirf,function = "i2s_ext_clk_input";
+ };
+ };
+ i2s_pins_a: i2s@0 {
+ i2s {
+ sirf,pins = "i2sgrp";
+ sirf,function = "i2s";
+ };
+ };
+ i2s_no_din_pins_a: i2s_no_din@0 {
+ i2s_no_din {
+ sirf,pins = "i2s_no_dingrp";
+ sirf,function = "i2s_no_din";
+ };
+ };
+ i2s_6chn_pins_a: i2s_6chn@0 {
+ i2s_6chn {
+ sirf,pins = "i2s_6chngrp";
+ sirf,function = "i2s_6chn";
+ };
+ };
+ ac97_pins_a: ac97@0 {
+ ac97 {
+ sirf,pins = "ac97grp";
+ sirf,function = "ac97";
+ };
+ };
+ nand_pins_a: nand@0 {
+ nand {
+ sirf,pins = "nandgrp";
+ sirf,function = "nand";
+ };
+ };
+ usp0_pins_a: usp0@0 {
+ usp0 {
+ sirf,pins = "usp0grp";
+ sirf,function = "usp0";
+ };
+ };
+ usp0_uart_nostreamctrl_pins_a: usp0@1 {
+ usp0 {
+ sirf,pins = "usp0_uart_nostreamctrl_grp";
+ sirf,function = "usp0_uart_nostreamctrl";
+ };
+ };
+ usp0_only_utfs_pins_a: usp0@2 {
+ usp0 {
+ sirf,pins = "usp0_only_utfs_grp";
+ sirf,function = "usp0_only_utfs";
+ };
+ };
+ usp0_only_urfs_pins_a: usp0@3 {
+ usp0 {
+ sirf,pins = "usp0_only_urfs_grp";
+ sirf,function = "usp0_only_urfs";
+ };
+ };
+ usp1_pins_a: usp1@0 {
+ usp1 {
+ sirf,pins = "usp1grp";
+ sirf,function = "usp1";
+ };
+ };
+ usp1_uart_nostreamctrl_pins_a: usp1@1 {
+ usp1 {
+ sirf,pins = "usp1_uart_nostreamctrl_grp";
+ sirf,function = "usp1_uart_nostreamctrl";
+ };
+ };
+ usb0_upli_drvbus_pins_a: usb0_upli_drvbus@0 {
+ usb0_upli_drvbus {
+ sirf,pins = "usb0_upli_drvbusgrp";
+ sirf,function = "usb0_upli_drvbus";
+ };
+ };
+ usb1_utmi_drvbus_pins_a: usb1_utmi_drvbus@0 {
+ usb1_utmi_drvbus {
+ sirf,pins = "usb1_utmi_drvbusgrp";
+ sirf,function = "usb1_utmi_drvbus";
+ };
+ };
+ usb1_dp_dn_pins_a: usb1_dp_dn@0 {
+ usb1_dp_dn {
+ sirf,pins = "usb1_dp_dngrp";
+ sirf,function = "usb1_dp_dn";
+ };
+ };
+ uart1_route_io_usb1_pins_a: uart1_route_io_usb1@0 {
+ uart1_route_io_usb1 {
+ sirf,pins = "uart1_route_io_usb1grp";
+ sirf,function = "uart1_route_io_usb1";
+ };
+ };
+ warm_rst_pins_a: warm_rst@0 {
+ warm_rst {
+ sirf,pins = "warm_rstgrp";
+ sirf,function = "warm_rst";
+ };
+ };
+ pulse_count_pins_a: pulse_count@0 {
+ pulse_count {
+ sirf,pins = "pulse_countgrp";
+ sirf,function = "pulse_count";
+ };
+ };
+ cko0_pins_a: cko0@0 {
+ cko0 {
+ sirf,pins = "cko0grp";
+ sirf,function = "cko0";
+ };
+ };
+ cko1_pins_a: cko1@0 {
+ cko1 {
+ sirf,pins = "cko1grp";
+ sirf,function = "cko1";
+ };
+ };
+ };
+
+ pwm@b0130000 {
+ compatible = "sirf,prima2-pwm";
+ reg = <0xb0130000 0x10000>;
+ clocks = <&clks 21>;
+ };
+
+ efusesys@b0140000 {
+ compatible = "sirf,prima2-efuse";
+ reg = <0xb0140000 0x10000>;
+ clocks = <&clks 22>;
+ };
+
+ pulsec@b0150000 {
+ compatible = "sirf,prima2-pulsec";
+ reg = <0xb0150000 0x10000>;
+ interrupts = <48>;
+ clocks = <&clks 23>;
+ };
+
+ pci-iobg {
+ compatible = "sirf,prima2-pciiobg", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x56000000 0x56000000 0x1b00000>;
+
+ sd0: sdhci@56000000 {
+ cell-index = <0>;
+ compatible = "sirf,prima2-sdhc";
+ reg = <0x56000000 0x100000>;
+ interrupts = <38>;
+ bus-width = <8>;
+ clocks = <&clks 36>;
+ };
+
+ sd1: sdhci@56100000 {
+ cell-index = <1>;
+ compatible = "sirf,prima2-sdhc";
+ reg = <0x56100000 0x100000>;
+ interrupts = <38>;
+ status = "disabled";
+ bus-width = <4>;
+ clocks = <&clks 36>;
+ };
+
+ sd2: sdhci@56200000 {
+ cell-index = <2>;
+ compatible = "sirf,prima2-sdhc";
+ reg = <0x56200000 0x100000>;
+ interrupts = <23>;
+ status = "disabled";
+ bus-width = <4>;
+ clocks = <&clks 37>;
+ };
+
+ sd3: sdhci@56300000 {
+ cell-index = <3>;
+ compatible = "sirf,prima2-sdhc";
+ reg = <0x56300000 0x100000>;
+ interrupts = <23>;
+ status = "disabled";
+ bus-width = <4>;
+ clocks = <&clks 37>;
+ };
+
+ sd5: sdhci@56500000 {
+ cell-index = <5>;
+ compatible = "sirf,prima2-sdhc";
+ reg = <0x56500000 0x100000>;
+ interrupts = <39>;
+ status = "disabled";
+ bus-width = <4>;
+ clocks = <&clks 38>;
+ };
+
+ pci-copy@57900000 {
+ compatible = "sirf,prima2-pcicp";
+ reg = <0x57900000 0x100000>;
+ interrupts = <40>;
+ };
+
+ rom-interface@57a00000 {
+ compatible = "sirf,prima2-romif";
+ reg = <0x57a00000 0x100000>;
+ };
+ };
+ };
+
+ rtc-iobg {
+ compatible = "sirf,prima2-rtciobg", "sirf-prima2-rtciobg-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80030000 0x10000>;
+
+ gpsrtc@1000 {
+ compatible = "sirf,prima2-gpsrtc";
+ reg = <0x1000 0x1000>;
+ interrupts = <55 56 57>;
+ };
+
+ sysrtc@2000 {
+ compatible = "sirf,prima2-sysrtc";
+ reg = <0x2000 0x1000>;
+ interrupts = <52 53 54>;
+ };
+
+ minigpsrtc@2000 {
+ compatible = "sirf,prima2-minigpsrtc";
+ reg = <0x2000 0x1000>;
+ interrupts = <54>;
+ };
+
+ pwrc@3000 {
+ compatible = "sirf,prima2-pwrc";
+ reg = <0x3000 0x1000>;
+ interrupts = <32>;
+ };
+ };
+
+ uus-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0xb8000000 0xb8000000 0x40000>;
+
+ usb0: usb@b00e0000 {
+ compatible = "chipidea,ci13611a-prima2";
+ reg = <0xb8000000 0x10000>;
+ interrupts = <10>;
+ clocks = <&clks 40>;
+ };
+
+ usb1: usb@b00f0000 {
+ compatible = "chipidea,ci13611a-prima2";
+ reg = <0xb8010000 0x10000>;
+ interrupts = <11>;
+ clocks = <&clks 41>;
+ };
+
+ security@b00f0000 {
+ compatible = "sirf,prima2-security";
+ reg = <0xb8030000 0x10000>;
+ interrupts = <42>;
+ clocks = <&clks 7>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/atlas7-evb.dts b/arch/arm/boot/dts/atlas7-evb.dts
new file mode 100644
index 000000000..49cf59a95
--- /dev/null
+++ b/arch/arm/boot/dts/atlas7-evb.dts
@@ -0,0 +1,110 @@
+/*
+ * DTS file for CSR SiRFatlas7 Evaluation Board
+ *
+ * Copyright (c) 2014 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/dts-v1/;
+
+/include/ "atlas7.dtsi"
+
+/ {
+ model = "CSR SiRFatlas7 Evaluation Board";
+ compatible = "sirf,atlas7-cb", "sirf,atlas7";
+
+ chosen {
+ bootargs = "console=ttySiRF1,115200 earlyprintk";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x40000000 0x20000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ vpp_reserved: vpp_mem@5e800000 {
+ compatible = "sirf,reserved-memory";
+ reg = <0x5e800000 0x800000>;
+ };
+
+ nanddisk_reserved: nanddisk@46000000 {
+ reg = <0x46000000 0x200000>;
+ no-map;
+ };
+ };
+
+
+ noc {
+ mediam {
+ nand@17050000 {
+ memory-region = <&nanddisk_reserved>;
+ };
+ };
+
+ gnssm {
+ spi1: spi@18200000 {
+ status = "okay";
+ spiflash: macronix@0{
+ status = "okay";
+ compatible = "macronix,mx25l6405d";
+ reg = <0>;
+ spi-max-frequency = <37500000>;
+ spi-cpha;
+ spi-cpol;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partitions@0 {
+ label = "myspiboot";
+ reg = <0x0 0x800000>;
+ };
+ };
+ };
+ };
+
+ btm {
+ uart6: uart@11000000 {
+ status = "okay";
+ sirf,uart-has-rtscts;
+ };
+ };
+
+ disp-iobg {
+ vpp@13110000 {
+ memory-region = <&vpp_reserved>;
+ };
+ };
+
+ display0: display@0 {
+ compatible = "lvds-panel";
+ source = "lvds.0";
+
+ bl-gpios = <&gpio_1 63 0>;
+ data-lines = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <60000000>;
+ hactive = <1024>;
+ vactive = <600>;
+ hfront-porch = <220>;
+ hback-porch = <100>;
+ hsync-len = <1>;
+ vback-porch = <10>;
+ vfront-porch = <25>;
+ vsync-len = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/atlas7.dtsi b/arch/arm/boot/dts/atlas7.dtsi
new file mode 100644
index 000000000..a753178ab
--- /dev/null
+++ b/arch/arm/boot/dts/atlas7.dtsi
@@ -0,0 +1,813 @@
+/*
+ * DTS file for CSR SiRFatlas7 SoC
+ *
+ * Copyright (c) 2014 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/include/ "skeleton.dtsi"
+/ {
+ compatible = "sirf,atlas7";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&gic>;
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ serial5 = &uart5;
+ serial6 = &uart6;
+ serial9 = &usp2;
+ };
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <1>;
+ };
+ };
+
+ noc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x10000000 0x10000000 0xc0000000>;
+
+ gic: interrupt-controller@10301000 {
+ compatible = "arm,cortex-a9-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x10301000 0x1000>,
+ <0x10302000 0x0100>;
+ };
+
+ pmu_regulator: pmu_regulator@10E30020 {
+ compatible = "sirf,atlas7-pmu-ldo";
+ reg = <0x10E30020 0x4>;
+ ldo: ldo {
+ regulator-name = "ldo";
+ };
+ };
+
+ atlas7_codec: atlas7_codec@10E30000 {
+ #sound-dai-cells = <0>;
+ compatible = "sirf,atlas7-codec";
+ reg = <0x10E30000 0x400>;
+ clocks = <&car 62>;
+ ldo-supply = <&ldo>;
+ };
+
+ atlas7_iacc: atlas7_iacc@10D01000 {
+ #sound-dai-cells = <0>;
+ compatible = "sirf,atlas7-iacc";
+ reg = <0x10D01000 0x100>;
+ dmas = <&dmac3 0>, <&dmac3 7>, <&dmac3 8>,
+ <&dmac3 3>, <&dmac3 9>;
+ dma-names = "rx", "tx0", "tx1", "tx2", "tx3";
+ clocks = <&car 62>;
+ };
+
+ ipc@13240000 {
+ compatible = "sirf,atlas7-ipc";
+ ranges = <0x13240000 0x13240000 0x00010000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ hwspinlock {
+ compatible = "sirf,hwspinlock";
+ reg = <0x13240000 0x00010000>;
+
+ num-spinlocks = <30>;
+ };
+
+ ns_m3_rproc@0 {
+ compatible = "sirf,ns2m30-rproc";
+ reg = <0x13240000 0x00010000>;
+ interrupts = <0 123 0>;
+ };
+
+ ns_m3_rproc@1 {
+ compatible = "sirf,ns2m31-rproc";
+ reg = <0x13240000 0x00010000>;
+ interrupts = <0 126 0>;
+ };
+
+ ns_kal_rproc@0 {
+ compatible = "sirf,ns2kal0-rproc";
+ reg = <0x13240000 0x00010000>;
+ interrupts = <0 124 0>;
+ };
+
+ ns_kal_rproc@1 {
+ compatible = "sirf,ns2kal1-rproc";
+ reg = <0x13240000 0x00010000>;
+ interrupts = <0 127 0>;
+ };
+ };
+
+ pinctrl: ioc@18880000 {
+ compatible = "sirf,atlas7-ioc";
+ reg = <0x18880000 0x1000>,
+ <0x10E40000 0x1000>;
+ };
+
+ pmipc {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x13240000 0x13240000 0x00010000>;
+ pmipc@0x13240000 {
+ compatible = "sirf,atlas7-pmipc";
+ reg = <0x13240000 0x00010000>;
+ };
+ };
+
+ dramfw {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x10830000 0x10830000 0x18000>;
+ dramfw@10820000 {
+ compatible = "sirf,nocfw-dramfw";
+ reg = <0x10830000 0x18000>;
+ };
+ };
+
+ spramfw {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x10250000 0x10250000 0x3000>;
+ spramfw@10820000 {
+ compatible = "sirf,nocfw-spramfw";
+ reg = <0x10250000 0x3000>;
+ };
+ };
+
+ cpum {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x10200000 0x10200000 0x3000>;
+ cpum@10200000 {
+ compatible = "sirf,nocfw-cpum";
+ reg = <0x10200000 0x3000>;
+ };
+ };
+
+ cgum {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x18641000 0x18641000 0x3000>,
+ <0x18620000 0x18620000 0x1000>;
+
+ cgum@18641000 {
+ compatible = "sirf,nocfw-cgum";
+ reg = <0x18641000 0x3000>;
+ };
+
+ car: clock-controller@18620000 {
+ compatible = "sirf,atlas7-car";
+ reg = <0x18620000 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+ };
+
+ gnssm {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x18000000 0x18000000 0x0000ffff>,
+ <0x18010000 0x18010000 0x1000>,
+ <0x18020000 0x18020000 0x1000>,
+ <0x18030000 0x18030000 0x1000>,
+ <0x18040000 0x18040000 0x1000>,
+ <0x18050000 0x18050000 0x1000>,
+ <0x18060000 0x18060000 0x1000>,
+ <0x18100000 0x18100000 0x3000>,
+ <0x18250000 0x18250000 0x10000>,
+ <0x18200000 0x18200000 0x1000>;
+
+ dmac0: dma-controller@18000000 {
+ cell-index = <0>;
+ compatible = "sirf,atlas7-dmac";
+ reg = <0x18000000 0x1000>;
+ interrupts = <0 12 0>;
+ clocks = <&car 89>;
+ dma-channels = <16>;
+ #dma-cells = <1>;
+ };
+
+ gnssmfw@0x18100000 {
+ compatible = "sirf,nocfw-gnssm";
+ reg = <0x18100000 0x3000>;
+ };
+
+ uart0: uart@18010000 {
+ cell-index = <0>;
+ compatible = "sirf,atlas7-uart";
+ reg = <0x18010000 0x1000>;
+ interrupts = <0 17 0>;
+ clocks = <&car 90>;
+ fifosize = <128>;
+ dmas = <&dmac0 3>, <&dmac0 2>;
+ dma-names = "rx", "tx";
+ };
+
+ uart1: uart@18020000 {
+ cell-index = <1>;
+ compatible = "sirf,atlas7-uart";
+ reg = <0x18020000 0x1000>;
+ interrupts = <0 18 0>;
+ clocks = <&car 88>;
+ fifosize = <32>;
+ };
+
+ uart2: uart@18030000 {
+ cell-index = <2>;
+ compatible = "sirf,atlas7-uart";
+ reg = <0x18030000 0x1000>;
+ interrupts = <0 19 0>;
+ clocks = <&car 91>;
+ fifosize = <128>;
+ dmas = <&dmac0 6>, <&dmac0 7>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ uart3: uart@18040000 {
+ cell-index = <3>;
+ compatible = "sirf,atlas7-uart";
+ reg = <0x18040000 0x1000>;
+ interrupts = <0 66 0>;
+ clocks = <&car 92>;
+ fifosize = <128>;
+ dmas = <&dmac0 4>, <&dmac0 5>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ uart4: uart@18050000 {
+ cell-index = <4>;
+ compatible = "sirf,atlas7-uart";
+ reg = <0x18050000 0x1000>;
+ interrupts = <0 69 0>;
+ clocks = <&car 93>;
+ fifosize = <128>;
+ dmas = <&dmac0 0>, <&dmac0 1>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ uart5: uart@18060000 {
+ cell-index = <5>;
+ compatible = "sirf,atlas7-uart";
+ reg = <0x18060000 0x1000>;
+ interrupts = <0 71 0>;
+ clocks = <&car 94>;
+ fifosize = <128>;
+ dmas = <&dmac0 8>, <&dmac0 9>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ dspub@18250000 {
+ compatible = "dx,cc44p";
+ reg = <0x18250000 0x10000>;
+ interrupts = <0 27 0>;
+ };
+
+ spi1: spi@18200000 {
+ compatible = "sirf,prima2-spi";
+ reg = <0x18200000 0x1000>;
+ interrupts = <0 16 0>;
+ clocks = <&car 95>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dmas = <&dmac0 12>, <&dmac0 13>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ };
+
+
+ gpum {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x13000000 0x13000000 0x3000>;
+ gpum@0x13000000 {
+ compatible = "sirf,nocfw-gpum";
+ reg = <0x13000000 0x3000>;
+ };
+ };
+
+ mediam {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x16000000 0x16000000 0x00200000>,
+ <0x17020000 0x17020000 0x1000>,
+ <0x17030000 0x17030000 0x1000>,
+ <0x17040000 0x17040000 0x1000>,
+ <0x17050000 0x17050000 0x10000>,
+ <0x17060000 0x17060000 0x200>,
+ <0x17060200 0x17060200 0x100>,
+ <0x17070000 0x17070000 0x200>,
+ <0x17070200 0x17070200 0x100>,
+ <0x170A0000 0x170A0000 0x3000>;
+
+ mediam@170A0000 {
+ compatible = "sirf,nocfw-mediam";
+ reg = <0x170A0000 0x3000>;
+ };
+
+ gpio_0: gpio_mediam@17040000 {
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ compatible = "sirf,atlas7-gpio";
+ reg = <0x17040000 0x1000>;
+ interrupts = <0 13 0>, <0 14 0>;
+ clocks = <&car 107>;
+ clock-names = "gpio0_io";
+ gpio-controller;
+ interrupt-controller;
+ };
+
+ nand@17050000 {
+ compatible = "sirf,atlas7-nand";
+ reg = <0x17050000 0x10000>;
+ interrupts = <0 41 0>;
+ clocks = <&car 108>, <&car 112>;
+ clock-names = "nand_io", "nand_nand";
+ };
+
+ sd0: sdhci@16000000 {
+ cell-index = <0>;
+ compatible = "sirf,atlas7-sdhc";
+ reg = <0x16000000 0x100000>;
+ interrupts = <0 38 0>;
+ clocks = <&car 109>, <&car 111>;
+ clock-names = "core", "iface";
+ wp-inverted;
+ non-removable;
+ status = "disabled";
+ bus-width = <8>;
+ };
+
+ sd1: sdhci@16100000 {
+ cell-index = <1>;
+ compatible = "sirf,atlas7-sdhc";
+ reg = <0x16100000 0x100000>;
+ interrupts = <0 38 0>;
+ clocks = <&car 109>, <&car 111>;
+ clock-names = "core", "iface";
+ non-removable;
+ status = "disabled";
+ bus-width = <8>;
+ };
+
+ usb0: usb@17060000 {
+ cell-index = <0>;
+ compatible = "sirf,atlas7-usb";
+ reg = <0x17060000 0x200>;
+ interrupts = <0 10 0>;
+ clocks = <&car 113>;
+ sirf,usbphy = <&usbphy0>;
+ phy_type = "utmi";
+ dr_mode = "otg";
+ maximum-speed = "high-speed";
+ status = "okay";
+ };
+
+ usb1: usb@17070000 {
+ cell-index = <1>;
+ compatible = "sirf,atlas7-usb";
+ reg = <0x17070000 0x200>;
+ interrupts = <0 11 0>;
+ clocks = <&car 114>;
+ sirf,usbphy = <&usbphy1>;
+ phy_type = "utmi";
+ dr_mode = "host";
+ maximum-speed = "high-speed";
+ status = "okay";
+ };
+
+ usbphy0: usbphy@0 {
+ compatible = "sirf,atlas7-usbphy";
+ reg = <0x17060200 0x100>;
+ clocks = <&car 115>;
+ status = "okay";
+ };
+
+ usbphy1: usbphy@1 {
+ compatible = "sirf,atlas7-usbphy";
+ reg = <0x17070200 0x100>;
+ clocks = <&car 116>;
+ status = "okay";
+ };
+
+ i2c0: i2c@17020000 {
+ cell-index = <0>;
+ compatible = "sirf,prima2-i2c";
+ reg = <0x17020000 0x1000>;
+ interrupts = <0 24 0>;
+ clocks = <&car 105>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ };
+
+ vdifm {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x13290000 0x13290000 0x3000>,
+ <0x13300000 0x13300000 0x1000>,
+ <0x14200000 0x14200000 0x600000>;
+
+ vdifm@13290000 {
+ compatible = "sirf,nocfw-vdifm";
+ reg = <0x13290000 0x3000>;
+ };
+
+ gpio_1: gpio_vdifm@13300000 {
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ compatible = "sirf,atlas7-gpio";
+ reg = <0x13300000 0x1000>;
+ interrupts = <0 43 0>, <0 44 0>, <0 45 0>;
+ clocks = <&car 84>;
+ clock-names = "gpio1_io";
+ gpio-controller;
+ interrupt-controller;
+ };
+
+ sd2: sdhci@14200000 {
+ cell-index = <2>;
+ compatible = "sirf,atlas7-sdhc";
+ reg = <0x14200000 0x100000>;
+ interrupts = <0 23 0>;
+ clocks = <&car 70>, <&car 75>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ bus-width = <4>;
+ sd-uhs-sdr50;
+ vqmmc-supply = <&vqmmc>;
+ vqmmc: vqmmc@2 {
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <1950000>;
+ regulator-name = "vqmmc-ldo";
+ regulator-type = "voltage";
+ regulator-boot-on;
+ regulator-allow-bypass;
+ };
+ };
+
+ sd3: sdhci@14300000 {
+ cell-index = <3>;
+ compatible = "sirf,atlas7-sdhc";
+ reg = <0x14300000 0x100000>;
+ interrupts = <0 23 0>;
+ clocks = <&car 76>, <&car 81>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ bus-width = <4>;
+ };
+
+ sd5: sdhci@14500000 {
+ cell-index = <5>;
+ compatible = "sirf,atlas7-sdhc";
+ reg = <0x14500000 0x100000>;
+ interrupts = <0 39 0>;
+ clocks = <&car 71>, <&car 76>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ bus-width = <4>;
+ loop-dma;
+ };
+
+ sd6: sdhci@14600000 {
+ cell-index = <6>;
+ compatible = "sirf,atlas7-sdhc";
+ reg = <0x14600000 0x100000>;
+ interrupts = <0 98 0>;
+ clocks = <&car 72>, <&car 77>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ bus-width = <4>;
+ };
+
+ sd7: sdhci@14700000 {
+ cell-index = <7>;
+ compatible = "sirf,atlas7-sdhc";
+ reg = <0x14700000 0x100000>;
+ interrupts = <0 98 0>;
+ clocks = <&car 72>, <&car 77>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ bus-width = <4>;
+ };
+ };
+
+ audiom {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x10d50000 0x10d50000 0x0000ffff>,
+ <0x10d60000 0x10d60000 0x0000ffff>,
+ <0x10d80000 0x10d80000 0x0000ffff>,
+ <0x10d90000 0x10d90000 0x0000ffff>,
+ <0x10ED0000 0x10ED0000 0x3000>,
+ <0x10dc8000 0x10dc8000 0x1000>,
+ <0x10dc0000 0x10dc0000 0x1000>,
+ <0x10db0000 0x10db0000 0x4000>,
+ <0x10d40000 0x10d40000 0x1000>,
+ <0x10d30000 0x10d30000 0x1000>;
+
+ timer@10dc0000 {
+ compatible = "sirf,atlas7-tick";
+ reg = <0x10dc0000 0x1000>;
+ interrupts = <0 0 0>,
+ <0 1 0>,
+ <0 2 0>,
+ <0 49 0>,
+ <0 50 0>,
+ <0 51 0>;
+ clocks = <&car 47>;
+ };
+
+ timerb@10dc8000 {
+ compatible = "sirf,atlas7-tick";
+ reg = <0x10dc8000 0x1000>;
+ interrupts = <0 74 0>,
+ <0 75 0>,
+ <0 76 0>,
+ <0 77 0>,
+ <0 78 0>,
+ <0 79 0>;
+ clocks = <&car 47>;
+ };
+
+ vip0@10db0000 {
+ compatible = "sirf,atlas7-vip0";
+ reg = <0x10db0000 0x2000>;
+ interrupts = <0 85 0>;
+ sirf,vip_cma_size = <0xC00000>;
+ };
+
+ cvd@10db2000 {
+ compatible = "sirf,cvd";
+ reg = <0x10db2000 0x2000>;
+ clocks = <&car 46>;
+ };
+
+ dmac2: dma-controller@10d50000 {
+ cell-index = <2>;
+ compatible = "sirf,atlas7-dmac";
+ reg = <0x10d50000 0xffff>;
+ interrupts = <0 55 0>;
+ clocks = <&car 60>;
+ dma-channels = <16>;
+ #dma-cells = <1>;
+ };
+
+ dmac3: dma-controller@10d60000 {
+ cell-index = <3>;
+ compatible = "sirf,atlas7-dmac";
+ reg = <0x10d60000 0xffff>;
+ interrupts = <0 56 0>;
+ clocks = <&car 61>;
+ dma-channels = <16>;
+ #dma-cells = <1>;
+ };
+
+ adc: adc@10d80000 {
+ compatible = "sirf,atlas7-adc";
+ reg = <0x10d80000 0xffff>;
+ interrupts = <0 34 0>;
+ clocks = <&car 49>;
+ #io-channel-cells = <1>;
+ };
+
+ pulsec@10d90000 {
+ compatible = "sirf,prima2-pulsec";
+ reg = <0x10d90000 0xffff>;
+ interrupts = <0 42 0>;
+ clocks = <&car 54>;
+ };
+
+ audiom@10ED0000 {
+ compatible = "sirf,nocfw-audiom";
+ reg = <0x10ED0000 0x3000>;
+ interrupts = <0 102 0>;
+ };
+
+ usp1: usp@10d30000 {
+ cell-index = <1>;
+ reg = <0x10d30000 0x1000>;
+ fifosize = <512>;
+ clocks = <&car 58>;
+ dmas = <&dmac2 6>, <&dmac2 7>;
+ dma-names = "rx", "tx";
+ };
+
+ usp2: usp@10d40000 {
+ cell-index = <2>;
+ reg = <0x10d40000 0x1000>;
+ interrupts = <0 22 0>;
+ clocks = <&car 59>;
+ dmas = <&dmac2 12>, <&dmac2 13>;
+ dma-names = "rx", "tx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ };
+
+ ddrm {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x10820000 0x10820000 0x3000>,
+ <0x10800000 0x10800000 0x2000>;
+ ddrm@10820000 {
+ compatible = "sirf,nocfw-ddrm";
+ reg = <0x10820000 0x3000>;
+ interrupts = <0 105 0>;
+ };
+
+ memory-controller@0x10800000 {
+ compatible = "sirf,atlas7-memc";
+ reg = <0x10800000 0x2000>;
+ };
+
+ };
+
+ btm {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x11002000 0x11002000 0x0000ffff>,
+ <0x11010000 0x11010000 0x3000>,
+ <0x11000000 0x11000000 0x1000>,
+ <0x11001000 0x11001000 0x1000>;
+
+ dmac4: dma-controller@11002000 {
+ cell-index = <4>;
+ compatible = "sirf,atlas7-dmac";
+ reg = <0x11002000 0x1000>;
+ interrupts = <0 99 0>;
+ clocks = <&car 130>;
+ dma-channels = <16>;
+ #dma-cells = <1>;
+ };
+ uart6: uart@11000000 {
+ cell-index = <6>;
+ compatible = "sirf,atlas7-bt-uart",
+ "sirf,atlas7-uart";
+ reg = <0x11000000 0x1000>;
+ interrupts = <0 100 0>;
+ clocks = <&car 131>, <&car 133>, <&car 134>;
+ clock-names = "uart", "general", "noc";
+ fifosize = <128>;
+ dmas = <&dmac4 12>, <&dmac4 13>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ usp3: usp@11001000 {
+ compatible = "sirf,atlas7-bt-usp",
+ "sirf,prima2-usp-pcm";
+ cell-index = <3>;
+ reg = <0x11001000 0x1000>;
+ fifosize = <512>;
+ clocks = <&car 132>, <&car 129>, <&car 133>,
+ <&car 134>, <&car 135>;
+ clock-names = "usp3_io", "a7ca_btss", "a7ca_io",
+ "noc_btm_io", "thbtm_io";
+ dmas = <&dmac4 0>, <&dmac4 1>;
+ dma-names = "rx", "tx";
+ };
+
+ btm@11010000 {
+ compatible = "sirf,nocfw-btm";
+ reg = <0x11010000 0x3000>;
+ };
+ };
+
+ rtcm {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x18810000 0x18810000 0x3000>,
+ <0x18840000 0x18840000 0x1000>,
+ <0x18890000 0x18890000 0x1000>,
+ <0x188B0000 0x188B0000 0x10000>,
+ <0x188D0000 0x188D0000 0x1000>;
+ rtcm@18810000 {
+ compatible = "sirf,nocfw-rtcm";
+ reg = <0x18810000 0x3000>;
+ interrupts = <0 109 0>;
+ };
+
+ gpio_2: gpio_rtcm@18890000 {
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ compatible = "sirf,atlas7-gpio";
+ reg = <0x18890000 0x1000>;
+ interrupts = <0 47 0>;
+ gpio-controller;
+ interrupt-controller;
+ };
+
+ rtc-iobg@18840000 {
+ compatible = "sirf,prima2-rtciobg",
+ "sirf-prima2-rtciobg-bus",
+ "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x18840000 0x1000>;
+
+ sysrtc@2000 {
+ compatible = "sirf,prima2-sysrtc";
+ reg = <0x2000 0x100>;
+ interrupts = <0 52 0>;
+ };
+ pwrc@3000 {
+ compatible = "sirf,atlas7-pwrc";
+ reg = <0x3000 0x100>;
+ };
+ };
+
+ qspi: flash@188B0000 {
+ cell-index = <0>;
+ compatible = "sirf,atlas7-qspi-nor";
+ reg = <0x188B0000 0x10000>;
+ interrupts = <0 15 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ retain@0x188D0000 {
+ compatible = "sirf,atlas7-retain";
+ reg = <0x188D0000 0x1000>;
+ };
+
+ };
+ disp-iobg {
+ /* lcdc0 */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x13100000 0x13100000 0x20000>,
+ <0x10e10000 0x10e10000 0x10000>;
+
+ lcd@13100000 {
+ compatible = "sirf,atlas7-lcdc";
+ reg = <0x13100000 0x10000>;
+ interrupts = <0 30 0>;
+ clocks = <&car 79>;
+ };
+ vpp@13110000 {
+ compatible = "sirf,atlas7-vpp";
+ reg = <0x13110000 0x10000>;
+ interrupts = <0 31 0>;
+ clocks = <&car 78>;
+ resets = <&car 29>;
+ };
+ lvds@10e10000 {
+ compatible = "sirf,atlas7-lvdsc";
+ reg = <0x10e10000 0x10000>;
+ interrupts = <0 64 0>;
+ clocks = <&car 54>;
+ resets = <&car 29>;
+ };
+
+ };
+
+ graphics-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x12000000 0x12000000 0x1000000>;
+
+ graphics@12000000 {
+ compatible = "powervr,sgx531";
+ reg = <0x12000000 0x1000000>;
+ interrupts = <0 6 0>;
+ clocks = <&car 126>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/axm5516-amarillo.dts b/arch/arm/boot/dts/axm5516-amarillo.dts
new file mode 100644
index 000000000..a9d60471d
--- /dev/null
+++ b/arch/arm/boot/dts/axm5516-amarillo.dts
@@ -0,0 +1,51 @@
+/*
+ * arch/arm/boot/dts/axm5516-amarillo.dts
+ *
+ * Copyright (C) 2013 LSI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x00000000 0x00400000;
+
+#include "axm55xx.dtsi"
+#include "axm5516-cpus.dtsi"
+
+/ {
+ model = "Amarillo AXM5516";
+ compatible = "lsi,axm5516-amarillo", "lsi,axm5516";
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x00000000 0x02 0x00000000>;
+ };
+};
+
+&serial0 {
+ status = "okay";
+};
+
+&serial1 {
+ status = "okay";
+};
+
+&serial2 {
+ status = "okay";
+};
+
+&serial3 {
+ status = "okay";
+};
+
+&gpio0 {
+ status = "okay";
+};
+
+&gpio1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/axm5516-cpus.dtsi b/arch/arm/boot/dts/axm5516-cpus.dtsi
new file mode 100644
index 000000000..b85f360cb
--- /dev/null
+++ b/arch/arm/boot/dts/axm5516-cpus.dtsi
@@ -0,0 +1,204 @@
+/*
+ * arch/arm/boot/dts/axm5516-cpus.dtsi
+ *
+ * Copyright (C) 2013 LSI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&CPU0>;
+ };
+ core1 {
+ cpu = <&CPU1>;
+ };
+ core2 {
+ cpu = <&CPU2>;
+ };
+ core3 {
+ cpu = <&CPU3>;
+ };
+ };
+ cluster1 {
+ core0 {
+ cpu = <&CPU4>;
+ };
+ core1 {
+ cpu = <&CPU5>;
+ };
+ core2 {
+ cpu = <&CPU6>;
+ };
+ core3 {
+ cpu = <&CPU7>;
+ };
+ };
+ cluster2 {
+ core0 {
+ cpu = <&CPU8>;
+ };
+ core1 {
+ cpu = <&CPU9>;
+ };
+ core2 {
+ cpu = <&CPU10>;
+ };
+ core3 {
+ cpu = <&CPU11>;
+ };
+ };
+ cluster3 {
+ core0 {
+ cpu = <&CPU12>;
+ };
+ core1 {
+ cpu = <&CPU13>;
+ };
+ core2 {
+ cpu = <&CPU14>;
+ };
+ core3 {
+ cpu = <&CPU15>;
+ };
+ };
+ };
+
+ CPU0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x00>;
+ clock-frequency= <1400000000>;
+ cpu-release-addr = <0>; // Fixed by the boot loader
+ };
+
+ CPU1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x01>;
+ clock-frequency= <1400000000>;
+ cpu-release-addr = <0>; // Fixed by the boot loader
+ };
+
+ CPU2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x02>;
+ clock-frequency= <1400000000>;
+ cpu-release-addr = <0>; // Fixed by the boot loader
+ };
+
+ CPU3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x03>;
+ clock-frequency= <1400000000>;
+ cpu-release-addr = <0>; // Fixed by the boot loader
+ };
+
+ CPU4: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x100>;
+ clock-frequency= <1400000000>;
+ cpu-release-addr = <0>; // Fixed by the boot loader
+ };
+
+ CPU5: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x101>;
+ clock-frequency= <1400000000>;
+ cpu-release-addr = <0>; // Fixed by the boot loader
+ };
+
+ CPU6: cpu@102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x102>;
+ clock-frequency= <1400000000>;
+ cpu-release-addr = <0>; // Fixed by the boot loader
+ };
+
+ CPU7: cpu@103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x103>;
+ clock-frequency= <1400000000>;
+ cpu-release-addr = <0>; // Fixed by the boot loader
+ };
+
+ CPU8: cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x200>;
+ clock-frequency= <1400000000>;
+ cpu-release-addr = <0>; // Fixed by the boot loader
+ };
+
+ CPU9: cpu@201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x201>;
+ clock-frequency= <1400000000>;
+ cpu-release-addr = <0>; // Fixed by the boot loader
+ };
+
+ CPU10: cpu@202 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x202>;
+ clock-frequency= <1400000000>;
+ cpu-release-addr = <0>; // Fixed by the boot loader
+ };
+
+ CPU11: cpu@203 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x203>;
+ clock-frequency= <1400000000>;
+ cpu-release-addr = <0>; // Fixed by the boot loader
+ };
+
+ CPU12: cpu@300 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x300>;
+ clock-frequency= <1400000000>;
+ cpu-release-addr = <0>; // Fixed by the boot loader
+ };
+
+ CPU13: cpu@301 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x301>;
+ clock-frequency= <1400000000>;
+ cpu-release-addr = <0>; // Fixed by the boot loader
+ };
+
+ CPU14: cpu@302 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x302>;
+ clock-frequency= <1400000000>;
+ cpu-release-addr = <0>; // Fixed by the boot loader
+ };
+
+ CPU15: cpu@303 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x303>;
+ clock-frequency= <1400000000>;
+ cpu-release-addr = <0>; // Fixed by the boot loader
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/axm55xx.dtsi b/arch/arm/boot/dts/axm55xx.dtsi
new file mode 100644
index 000000000..ea288f0a1
--- /dev/null
+++ b/arch/arm/boot/dts/axm55xx.dtsi
@@ -0,0 +1,204 @@
+/*
+ * arch/arm/boot/dts/axm55xx.dtsi
+ *
+ * Copyright (C) 2013 LSI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/lsi,axm5516-clks.h>
+
+#include "skeleton64.dtsi"
+
+/ {
+ interrupt-parent = <&gic>;
+
+ aliases {
+ serial0 = &serial0;
+ serial1 = &serial1;
+ serial2 = &serial2;
+ serial3 = &serial3;
+ timer = &timer0;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ clk_ref0: clk_ref0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <125000000>;
+ };
+
+ clk_ref1: clk_ref1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <125000000>;
+ };
+
+ clk_ref2: clk_ref2 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <125000000>;
+ };
+
+ clks: clock-controller@2010020000 {
+ compatible = "lsi,axm5516-clks";
+ #clock-cells = <1>;
+ reg = <0x20 0x10020000 0 0x20000>;
+ };
+ };
+
+ gic: interrupt-controller@2001001000 {
+ compatible = "arm,cortex-a15-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x20 0x01001000 0 0x1000>,
+ <0x20 0x01002000 0 0x1000>,
+ <0x20 0x01004000 0 0x2000>,
+ <0x20 0x01006000 0 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
+ IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts =
+ <GIC_PPI 13
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+
+ pmu {
+ compatible = "arm,cortex-a15-pmu";
+ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ device_type = "soc";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&gic>;
+ ranges;
+
+ syscon: syscon@2010030000 {
+ compatible = "lsi,axxia-syscon", "syscon";
+ reg = <0x20 0x10030000 0 0x2000>;
+ };
+
+ reset: reset@2010031000 {
+ compatible = "lsi,axm55xx-reset";
+ syscon = <&syscon>;
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ serial0: uart@2010080000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x20 0x10080000 0 0x1000>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks AXXIA_CLK_PER>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ serial1: uart@2010081000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x20 0x10081000 0 0x1000>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks AXXIA_CLK_PER>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ serial2: uart@2010082000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x20 0x10082000 0 0x1000>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks AXXIA_CLK_PER>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ serial3: uart@2010083000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x20 0x10083000 0 0x1000>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks AXXIA_CLK_PER>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ timer0: timer@2010091000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x20 0x10091000 0 0x1000>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks AXXIA_CLK_PER>;
+ clock-names = "apb_pclk";
+ status = "okay";
+ };
+
+ gpio0: gpio@2010092000 {
+ #gpio-cells = <2>;
+ compatible = "arm,pl061", "arm,primecell";
+ gpio-controller;
+ reg = <0x20 0x10092000 0x00 0x1000>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks AXXIA_CLK_PER>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ gpio1: gpio@2010093000 {
+ #gpio-cells = <2>;
+ compatible = "arm,pl061", "arm,primecell";
+ gpio-controller;
+ reg = <0x20 0x10093000 0x00 0x1000>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks AXXIA_CLK_PER>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+ };
+ };
+};
+
+/*
+ Local Variables:
+ mode: C
+ End:
+*/
diff --git a/arch/arm/boot/dts/axp209.dtsi b/arch/arm/boot/dts/axp209.dtsi
new file mode 100644
index 000000000..c20cf537f
--- /dev/null
+++ b/arch/arm/boot/dts/axp209.dtsi
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2015 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai <wens@csie.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * AXP202/209 Integrated Power Management Chip
+ * http://www.x-powers.com/product/AXP20X.php
+ * http://dl.linux-sunxi.org/AXP/AXP209%20Datasheet%20v1.0_cn.pdf
+ */
+
+&axp209 {
+ compatible = "x-powers,axp209";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ regulators {
+ /* Default work frequency for buck regulators */
+ x-powers,dcdc-freq = <1500>;
+
+ reg_dcdc2: dcdc2 {
+ regulator-name = "dcdc2";
+ };
+
+ reg_dcdc3: dcdc3 {
+ regulator-name = "dcdc3";
+ };
+
+ reg_ldo1: ldo1 {
+ /* LDO1 is a fixed output regulator */
+ regulator-always-on;
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-name = "ldo1";
+ };
+
+ reg_ldo2: ldo2 {
+ regulator-name = "ldo2";
+ };
+
+ reg_ldo3: ldo3 {
+ regulator-name = "ldo3";
+ };
+
+ reg_ldo4: ldo4 {
+ regulator-name = "ldo4";
+ };
+
+ reg_ldo5: ldo5 {
+ regulator-name = "ldo5";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm-cygnus-clock.dtsi b/arch/arm/boot/dts/bcm-cygnus-clock.dtsi
new file mode 100644
index 000000000..60d8389fd
--- /dev/null
+++ b/arch/arm/boot/dts/bcm-cygnus-clock.dtsi
@@ -0,0 +1,91 @@
+/*
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014 Broadcom Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ osc: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <1>;
+ clock-frequency = <25000000>;
+ };
+
+ apb_clk: apb_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1000000000>;
+ };
+
+ periph_clk: periph_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <500000000>;
+ };
+
+ sdio_clk: lcpll_ch2 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <200000000>;
+ };
+
+ axi81_clk: axi81_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
+ keypad_clk: keypad_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <31806>;
+ };
+
+ adc_clk: adc_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1562500>;
+ };
+
+ pwm_clk: pwm_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1000000>;
+ };
+
+ lcd_clk: mipipll_ch1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi b/arch/arm/boot/dts/bcm-cygnus.dtsi
new file mode 100644
index 000000000..7b52c33ea
--- /dev/null
+++ b/arch/arm/boot/dts/bcm-cygnus.dtsi
@@ -0,0 +1,238 @@
+/*
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014 Broadcom Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "brcm,cygnus";
+ model = "Broadcom Cygnus SoC";
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x0>;
+ };
+ };
+
+ /include/ "bcm-cygnus-clock.dtsi"
+
+ pinctrl: pinctrl@0x0301d0c8 {
+ compatible = "brcm,cygnus-pinmux";
+ reg = <0x0301d0c8 0x30>,
+ <0x0301d24c 0x2c>;
+ };
+
+ gpio_crmu: gpio@03024800 {
+ compatible = "brcm,cygnus-crmu-gpio";
+ reg = <0x03024800 0x50>,
+ <0x03024008 0x18>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ };
+
+ gpio_ccm: gpio@1800a000 {
+ compatible = "brcm,cygnus-ccm-gpio";
+ reg = <0x1800a000 0x50>,
+ <0x0301d164 0x20>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ };
+
+ gpio_asiu: gpio@180a5000 {
+ compatible = "brcm,cygnus-asiu-gpio";
+ reg = <0x180a5000 0x668>;
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ pinmux = <&pinctrl>;
+
+ interrupt-controller;
+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ amba {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "arm,amba-bus", "simple-bus";
+ interrupt-parent = <&gic>;
+ ranges;
+
+ wdt@18009000 {
+ compatible = "arm,sp805" , "arm,primecell";
+ reg = <0x18009000 0x1000>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&axi81_clk>;
+ clock-names = "apb_pclk";
+ };
+ };
+
+ i2c0: i2c@18008000 {
+ compatible = "brcm,cygnus-iproc-i2c", "brcm,iproc-i2c";
+ reg = <0x18008000 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@1800b000 {
+ compatible = "brcm,cygnus-iproc-i2c", "brcm,iproc-i2c";
+ reg = <0x1800b000 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ pcie0: pcie@18012000 {
+ compatible = "brcm,iproc-pcie";
+ reg = <0x18012000 0x1000>;
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 100 IRQ_TYPE_NONE>;
+
+ linux,pci-domain = <0>;
+
+ bus-range = <0x00 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x81000000 0 0 0x28000000 0 0x00010000
+ 0x82000000 0 0x20000000 0x20000000 0 0x04000000>;
+
+ status = "disabled";
+ };
+
+ pcie1: pcie@18013000 {
+ compatible = "brcm,iproc-pcie";
+ reg = <0x18013000 0x1000>;
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 106 IRQ_TYPE_NONE>;
+
+ linux,pci-domain = <1>;
+
+ bus-range = <0x00 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x81000000 0 0 0x48000000 0 0x00010000
+ 0x82000000 0 0x40000000 0x40000000 0 0x04000000>;
+
+ status = "disabled";
+ };
+
+ uart0: serial@18020000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x18020000 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&axi81_clk>;
+ clock-frequency = <100000000>;
+ status = "disabled";
+ };
+
+ uart1: serial@18021000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x18021000 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&axi81_clk>;
+ clock-frequency = <100000000>;
+ status = "disabled";
+ };
+
+ uart2: serial@18022000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x18020000 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&axi81_clk>;
+ clock-frequency = <100000000>;
+ status = "disabled";
+ };
+
+ uart3: serial@18023000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x18023000 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&axi81_clk>;
+ clock-frequency = <100000000>;
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@19021000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x19021000 0x1000>,
+ <0x19020100 0x100>;
+ };
+
+ L2: l2-cache {
+ compatible = "arm,pl310-cache";
+ reg = <0x19022000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ timer@19020200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x19020200 0x100>;
+ interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&periph_clk>;
+ };
+
+};
diff --git a/arch/arm/boot/dts/bcm11351.dtsi b/arch/arm/boot/dts/bcm11351.dtsi
new file mode 100644
index 000000000..2ddaa5136
--- /dev/null
+++ b/arch/arm/boot/dts/bcm11351.dtsi
@@ -0,0 +1,424 @@
+/*
+ * Copyright (C) 2012-2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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 <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "dt-bindings/clock/bcm281xx.h"
+
+#include "skeleton.dtsi"
+
+/ {
+ model = "BCM11351 SoC";
+ compatible = "brcm,bcm11351";
+ interrupt-parent = <&gic>;
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "brcm,bcm11351-cpu-method";
+ secondary-boot-reg = <0x3500417c>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ };
+ };
+
+ gic: interrupt-controller@3ff00100 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x3ff01000 0x1000>,
+ <0x3ff00100 0x100>;
+ };
+
+ smc@0x3404c000 {
+ compatible = "brcm,bcm11351-smc", "brcm,kona-smc";
+ reg = <0x3404c000 0x400>; /* 1 KiB in SRAM */
+ };
+
+ uart@3e000000 {
+ compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart";
+ status = "disabled";
+ reg = <0x3e000000 0x1000>;
+ clocks = <&slave_ccu BCM281XX_SLAVE_CCU_UARTB>;
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ uart@3e001000 {
+ compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart";
+ status = "disabled";
+ reg = <0x3e001000 0x1000>;
+ clocks = <&slave_ccu BCM281XX_SLAVE_CCU_UARTB2>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ uart@3e002000 {
+ compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart";
+ status = "disabled";
+ reg = <0x3e002000 0x1000>;
+ clocks = <&slave_ccu BCM281XX_SLAVE_CCU_UARTB3>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ uart@3e003000 {
+ compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart";
+ status = "disabled";
+ reg = <0x3e003000 0x1000>;
+ clocks = <&slave_ccu BCM281XX_SLAVE_CCU_UARTB4>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ L2: l2-cache {
+ compatible = "brcm,bcm11351-a2-pl310-cache";
+ reg = <0x3ff20000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ watchdog@35002f40 {
+ compatible = "brcm,bcm11351-wdt", "brcm,kona-wdt";
+ reg = <0x35002f40 0x6c>;
+ };
+
+ timer@35006000 {
+ compatible = "brcm,kona-timer";
+ reg = <0x35006000 0x1000>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&aon_ccu BCM281XX_AON_CCU_HUB_TIMER>;
+ };
+
+ gpio: gpio@35003000 {
+ compatible = "brcm,bcm11351-gpio", "brcm,kona-gpio";
+ reg = <0x35003000 0x800>;
+ interrupts =
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ };
+
+ sdio1: sdio@3f180000 {
+ compatible = "brcm,kona-sdhci";
+ reg = <0x3f180000 0x10000>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&master_ccu BCM281XX_MASTER_CCU_SDIO1>;
+ status = "disabled";
+ };
+
+ sdio2: sdio@3f190000 {
+ compatible = "brcm,kona-sdhci";
+ reg = <0x3f190000 0x10000>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&master_ccu BCM281XX_MASTER_CCU_SDIO2>;
+ status = "disabled";
+ };
+
+ sdio3: sdio@3f1a0000 {
+ compatible = "brcm,kona-sdhci";
+ reg = <0x3f1a0000 0x10000>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&master_ccu BCM281XX_MASTER_CCU_SDIO3>;
+ status = "disabled";
+ };
+
+ sdio4: sdio@3f1b0000 {
+ compatible = "brcm,kona-sdhci";
+ reg = <0x3f1b0000 0x10000>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&master_ccu BCM281XX_MASTER_CCU_SDIO4>;
+ status = "disabled";
+ };
+
+ pinctrl@35004800 {
+ compatible = "brcm,bcm11351-pinctrl";
+ reg = <0x35004800 0x430>;
+ };
+
+ i2c@3e016000 {
+ compatible = "brcm,bcm11351-i2c", "brcm,kona-i2c";
+ reg = <0x3e016000 0x80>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&slave_ccu BCM281XX_SLAVE_CCU_BSC1>;
+ status = "disabled";
+ };
+
+ i2c@3e017000 {
+ compatible = "brcm,bcm11351-i2c", "brcm,kona-i2c";
+ reg = <0x3e017000 0x80>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&slave_ccu BCM281XX_SLAVE_CCU_BSC2>;
+ status = "disabled";
+ };
+
+ i2c@3e018000 {
+ compatible = "brcm,bcm11351-i2c", "brcm,kona-i2c";
+ reg = <0x3e018000 0x80>;
+ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&slave_ccu BCM281XX_SLAVE_CCU_BSC3>;
+ status = "disabled";
+ };
+
+ i2c@3500d000 {
+ compatible = "brcm,bcm11351-i2c", "brcm,kona-i2c";
+ reg = <0x3500d000 0x80>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&aon_ccu BCM281XX_AON_CCU_PMU_BSC>;
+ status = "disabled";
+ };
+
+ pwm: pwm@3e01a000 {
+ compatible = "brcm,bcm11351-pwm", "brcm,kona-pwm";
+ reg = <0x3e01a000 0xcc>;
+ clocks = <&slave_ccu BCM281XX_SLAVE_CCU_PWM>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ root_ccu: root_ccu {
+ compatible = "brcm,bcm11351-root-ccu";
+ reg = <0x35001000 0x0f00>;
+ #clock-cells = <1>;
+ clock-output-names = "frac_1m";
+ };
+
+ hub_ccu: hub_ccu {
+ compatible = "brcm,bcm11351-hub-ccu";
+ reg = <0x34000000 0x0f00>;
+ #clock-cells = <1>;
+ clock-output-names = "tmon_1m";
+ };
+
+ aon_ccu: aon_ccu {
+ compatible = "brcm,bcm11351-aon-ccu";
+ reg = <0x35002000 0x0f00>;
+ #clock-cells = <1>;
+ clock-output-names = "hub_timer",
+ "pmu_bsc",
+ "pmu_bsc_var";
+ };
+
+ master_ccu: master_ccu {
+ compatible = "brcm,bcm11351-master-ccu";
+ reg = <0x3f001000 0x0f00>;
+ #clock-cells = <1>;
+ clock-output-names = "sdio1",
+ "sdio2",
+ "sdio3",
+ "sdio4",
+ "usb_ic",
+ "hsic2_48m",
+ "hsic2_12m";
+ };
+
+ slave_ccu: slave_ccu {
+ compatible = "brcm,bcm11351-slave-ccu";
+ reg = <0x3e011000 0x0f00>;
+ #clock-cells = <1>;
+ clock-output-names = "uartb",
+ "uartb2",
+ "uartb3",
+ "uartb4",
+ "ssp0",
+ "ssp2",
+ "bsc1",
+ "bsc2",
+ "bsc3",
+ "pwm";
+ };
+
+ ref_1m_clk: ref_1m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <1000000>;
+ };
+
+ ref_32k_clk: ref_32k {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ bbl_32k_clk: bbl_32k {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ ref_13m_clk: ref_13m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ };
+
+ var_13m_clk: var_13m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ };
+
+ dft_19_5m_clk: dft_19_5m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <19500000>;
+ };
+
+ ref_crystal_clk: ref_crystal {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ };
+
+ ref_cx40_clk: ref_cx40 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <40000000>;
+ };
+
+ ref_52m_clk: ref_52m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <52000000>;
+ };
+
+ var_52m_clk: var_52m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <52000000>;
+ };
+
+ usb_otg_ahb_clk: usb_otg_ahb {
+ compatible = "fixed-clock";
+ clock-frequency = <52000000>;
+ #clock-cells = <0>;
+ };
+
+ ref_96m_clk: ref_96m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <96000000>;
+ };
+
+ var_96m_clk: var_96m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <96000000>;
+ };
+
+ ref_104m_clk: ref_104m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <104000000>;
+ };
+
+ var_104m_clk: var_104m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <104000000>;
+ };
+
+ ref_156m_clk: ref_156m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <156000000>;
+ };
+
+ var_156m_clk: var_156m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <156000000>;
+ };
+
+ ref_208m_clk: ref_208m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <208000000>;
+ };
+
+ var_208m_clk: var_208m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <208000000>;
+ };
+
+ ref_312m_clk: ref_312m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <312000000>;
+ };
+
+ var_312m_clk: var_312m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <312000000>;
+ };
+ };
+
+ usbotg: usb@3f120000 {
+ compatible = "snps,dwc2";
+ reg = <0x3f120000 0x10000>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&usb_otg_ahb_clk>;
+ clock-names = "otg";
+ phys = <&usbphy>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ usbphy: usb-phy@3f130000 {
+ compatible = "brcm,kona-usb2-phy";
+ reg = <0x3f130000 0x28>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/bcm21664-garnet.dts b/arch/arm/boot/dts/bcm21664-garnet.dts
new file mode 100644
index 000000000..e87cb26dd
--- /dev/null
+++ b/arch/arm/boot/dts/bcm21664-garnet.dts
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "bcm21664.dtsi"
+
+/ {
+ model = "BCM21664 Garnet board";
+ compatible = "brcm,bcm21664-garnet", "brcm,bcm21664";
+
+ memory {
+ reg = <0x80000000 0x40000000>; /* 1 GB */
+ };
+
+ uart@3e000000 {
+ status = "okay";
+ };
+
+ sdio1: sdio@3f180000 {
+ max-frequency = <48000000>;
+ status = "okay";
+ };
+
+ sdio2: sdio@3f190000 {
+ non-removable;
+ max-frequency = <48000000>;
+ status = "okay";
+ };
+
+ sdio4: sdio@3f1b0000 {
+ max-frequency = <48000000>;
+ cd-gpios = <&gpio 91 GPIO_ACTIVE_LOW>;
+ status = "okay";
+ };
+
+ usbotg: usb@3f120000 {
+ status = "okay";
+ };
+
+ usbphy: usb-phy@3f130000 {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/bcm21664.dtsi b/arch/arm/boot/dts/bcm21664.dtsi
new file mode 100644
index 000000000..2016b72a8
--- /dev/null
+++ b/arch/arm/boot/dts/bcm21664.dtsi
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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 <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "dt-bindings/clock/bcm21664.h"
+
+#include "skeleton.dtsi"
+
+/ {
+ model = "BCM21664 SoC";
+ compatible = "brcm,bcm21664";
+ interrupt-parent = <&gic>;
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "brcm,bcm11351-cpu-method";
+ secondary-boot-reg = <0x35004178>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ };
+ };
+
+ gic: interrupt-controller@3ff00100 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x3ff01000 0x1000>,
+ <0x3ff00100 0x100>;
+ };
+
+ smc@0x3404e000 {
+ compatible = "brcm,bcm21664-smc", "brcm,kona-smc";
+ reg = <0x3404e000 0x400>; /* 1 KiB in SRAM */
+ };
+
+ uart@3e000000 {
+ compatible = "brcm,bcm21664-dw-apb-uart", "snps,dw-apb-uart";
+ status = "disabled";
+ reg = <0x3e000000 0x118>;
+ clocks = <&slave_ccu BCM21664_SLAVE_CCU_UARTB>;
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ uart@3e001000 {
+ compatible = "brcm,bcm21664-dw-apb-uart", "snps,dw-apb-uart";
+ status = "disabled";
+ reg = <0x3e001000 0x118>;
+ clocks = <&slave_ccu BCM21664_SLAVE_CCU_UARTB2>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ uart@3e002000 {
+ compatible = "brcm,bcm21664-dw-apb-uart", "snps,dw-apb-uart";
+ status = "disabled";
+ reg = <0x3e002000 0x118>;
+ clocks = <&slave_ccu BCM21664_SLAVE_CCU_UARTB3>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ L2: l2-cache {
+ compatible = "arm,pl310-cache";
+ reg = <0x3ff20000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ brcm,resetmgr@35001f00 {
+ compatible = "brcm,bcm21664-resetmgr";
+ reg = <0x35001f00 0x24>;
+ };
+
+ timer@35006000 {
+ compatible = "brcm,kona-timer";
+ reg = <0x35006000 0x1c>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&aon_ccu BCM21664_AON_CCU_HUB_TIMER>;
+ };
+
+ gpio: gpio@35003000 {
+ compatible = "brcm,bcm21664-gpio", "brcm,kona-gpio";
+ reg = <0x35003000 0x524>;
+ interrupts =
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ };
+
+ sdio1: sdio@3f180000 {
+ compatible = "brcm,kona-sdhci";
+ reg = <0x3f180000 0x801c>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&master_ccu BCM21664_MASTER_CCU_SDIO1>;
+ status = "disabled";
+ };
+
+ sdio2: sdio@3f190000 {
+ compatible = "brcm,kona-sdhci";
+ reg = <0x3f190000 0x801c>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&master_ccu BCM21664_MASTER_CCU_SDIO2>;
+ status = "disabled";
+ };
+
+ sdio3: sdio@3f1a0000 {
+ compatible = "brcm,kona-sdhci";
+ reg = <0x3f1a0000 0x801c>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&master_ccu BCM21664_MASTER_CCU_SDIO3>;
+ status = "disabled";
+ };
+
+ sdio4: sdio@3f1b0000 {
+ compatible = "brcm,kona-sdhci";
+ reg = <0x3f1b0000 0x801c>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&master_ccu BCM21664_MASTER_CCU_SDIO4>;
+ status = "disabled";
+ };
+
+ i2c@3e016000 {
+ compatible = "brcm,bcm21664-i2c", "brcm,kona-i2c";
+ reg = <0x3e016000 0x70>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&slave_ccu BCM21664_SLAVE_CCU_BSC1>;
+ status = "disabled";
+ };
+
+ i2c@3e017000 {
+ compatible = "brcm,bcm21664-i2c", "brcm,kona-i2c";
+ reg = <0x3e017000 0x70>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&slave_ccu BCM21664_SLAVE_CCU_BSC2>;
+ status = "disabled";
+ };
+
+ i2c@3e018000 {
+ compatible = "brcm,bcm21664-i2c", "brcm,kona-i2c";
+ reg = <0x3e018000 0x70>;
+ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&slave_ccu BCM21664_SLAVE_CCU_BSC3>;
+ status = "disabled";
+ };
+
+ i2c@3e01c000 {
+ compatible = "brcm,bcm21664-i2c", "brcm,kona-i2c";
+ reg = <0x3e01c000 0x70>;
+ interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&slave_ccu BCM21664_SLAVE_CCU_BSC4>;
+ status = "disabled";
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /*
+ * Fixed clocks are defined before CCUs whose
+ * clocks may depend on them.
+ */
+
+ ref_32k_clk: ref_32k {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ bbl_32k_clk: bbl_32k {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ ref_13m_clk: ref_13m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ };
+
+ var_13m_clk: var_13m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ };
+
+ dft_19_5m_clk: dft_19_5m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <19500000>;
+ };
+
+ ref_crystal_clk: ref_crystal {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ };
+
+ ref_52m_clk: ref_52m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <52000000>;
+ };
+
+ var_52m_clk: var_52m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <52000000>;
+ };
+
+ usb_otg_ahb_clk: usb_otg_ahb {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <52000000>;
+ };
+
+ ref_96m_clk: ref_96m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <96000000>;
+ };
+
+ var_96m_clk: var_96m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <96000000>;
+ };
+
+ ref_104m_clk: ref_104m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <104000000>;
+ };
+
+ var_104m_clk: var_104m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <104000000>;
+ };
+
+ ref_156m_clk: ref_156m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <156000000>;
+ };
+
+ var_156m_clk: var_156m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <156000000>;
+ };
+
+ root_ccu: root_ccu {
+ compatible = BCM21664_DT_ROOT_CCU_COMPAT;
+ reg = <0x35001000 0x0f00>;
+ #clock-cells = <1>;
+ clock-output-names = "frac_1m";
+ };
+
+ aon_ccu: aon_ccu {
+ compatible = BCM21664_DT_AON_CCU_COMPAT;
+ reg = <0x35002000 0x0f00>;
+ #clock-cells = <1>;
+ clock-output-names = "hub_timer";
+ };
+
+ master_ccu: master_ccu {
+ compatible = BCM21664_DT_MASTER_CCU_COMPAT;
+ reg = <0x3f001000 0x0f00>;
+ #clock-cells = <1>;
+ clock-output-names = "sdio1",
+ "sdio2",
+ "sdio3",
+ "sdio4",
+ "sdio1_sleep",
+ "sdio2_sleep",
+ "sdio3_sleep",
+ "sdio4_sleep";
+ };
+
+ slave_ccu: slave_ccu {
+ compatible = BCM21664_DT_SLAVE_CCU_COMPAT;
+ reg = <0x3e011000 0x0f00>;
+ #clock-cells = <1>;
+ clock-output-names = "uartb",
+ "uartb2",
+ "uartb3",
+ "bsc1",
+ "bsc2",
+ "bsc3",
+ "bsc4";
+ };
+ };
+
+ usbotg: usb@3f120000 {
+ compatible = "snps,dwc2";
+ reg = <0x3f120000 0x10000>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&usb_otg_ahb_clk>;
+ clock-names = "otg";
+ phys = <&usbphy>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ usbphy: usb-phy@3f130000 {
+ compatible = "brcm,kona-usb2-phy";
+ reg = <0x3f130000 0x28>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/bcm28155-ap.dts b/arch/arm/boot/dts/bcm28155-ap.dts
new file mode 100644
index 000000000..9ce91dd60
--- /dev/null
+++ b/arch/arm/boot/dts/bcm28155-ap.dts
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "bcm11351.dtsi"
+
+/ {
+ model = "BCM28155 AP board";
+ compatible = "brcm,bcm28155-ap", "brcm,bcm11351";
+
+ memory {
+ reg = <0x80000000 0x40000000>; /* 1 GB */
+ };
+
+ uart@3e000000 {
+ status = "okay";
+ };
+
+ i2c@3e016000 {
+ status="okay";
+ clock-frequency = <400000>;
+ };
+
+ i2c@3e017000 {
+ status="okay";
+ clock-frequency = <400000>;
+ };
+
+ i2c@3e018000 {
+ status="okay";
+ clock-frequency = <400000>;
+ };
+
+ i2c@3500d000 {
+ status="okay";
+ clock-frequency = <100000>;
+
+ pmu: pmu@8 {
+ reg = <0x08>;
+ };
+ };
+
+ sdio2: sdio@3f190000 {
+ non-removable;
+ max-frequency = <48000000>;
+ vmmc-supply = <&camldo1_reg>;
+ vqmmc-supply = <&iosr1_reg>;
+ status = "okay";
+ };
+
+ sdio4: sdio@3f1b0000 {
+ max-frequency = <48000000>;
+ cd-gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&sdldo_reg>;
+ vqmmc-supply = <&sdxldo_reg>;
+ status = "okay";
+ };
+
+ pwm: pwm@3e01a000 {
+ status = "okay";
+ };
+
+ usbotg: usb@3f120000 {
+ vusb_d-supply = <&usbldo_reg>;
+ vusb_a-supply = <&iosr1_reg>;
+ status = "okay";
+ };
+
+ usbphy: usb-phy@3f130000 {
+ status = "okay";
+ };
+};
+
+#include "bcm59056.dtsi"
+
+&pmu {
+ compatible = "brcm,bcm59056";
+ interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
+ regulators {
+ camldo1_reg: camldo1 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ sdldo_reg: sdldo {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ sdxldo_reg: sdxldo {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ usbldo_reg: usbldo {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ iosr1_reg: iosr1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
new file mode 100644
index 000000000..e47951509
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
@@ -0,0 +1,30 @@
+/dts-v1/;
+/include/ "bcm2835-rpi.dtsi"
+
+/ {
+ compatible = "raspberrypi,model-b-plus", "brcm,bcm2835";
+ model = "Raspberry Pi Model B+";
+
+ leds {
+ act {
+ gpios = <&gpio 47 0>;
+ };
+
+ pwr {
+ label = "PWR";
+ gpios = <&gpio 35 0>;
+ default-state = "keep";
+ linux,default-trigger = "default-on";
+ };
+ };
+};
+
+&gpio {
+ pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>;
+
+ /* I2S interface */
+ i2s_alt0: i2s_alt0 {
+ brcm,pins = <18 19 20 21>;
+ brcm,function = <4>; /* alt0 */
+ };
+};
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts
new file mode 100644
index 000000000..bafa46fc2
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
@@ -0,0 +1,23 @@
+/dts-v1/;
+/include/ "bcm2835-rpi.dtsi"
+
+/ {
+ compatible = "raspberrypi,model-b", "brcm,bcm2835";
+ model = "Raspberry Pi Model B";
+
+ leds {
+ act {
+ gpios = <&gpio 16 1>;
+ };
+ };
+};
+
+&gpio {
+ pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>;
+
+ /* I2S interface */
+ i2s_alt2: i2s_alt2 {
+ brcm,pins = <28 29 30 31>;
+ brcm,function = <6>; /* alt2 */
+ };
+};
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
new file mode 100644
index 000000000..c70644870
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -0,0 +1,51 @@
+/include/ "bcm2835.dtsi"
+
+/ {
+ memory {
+ reg = <0 0x10000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ act {
+ label = "ACT";
+ default-state = "keep";
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
+
+&gpio {
+ pinctrl-names = "default";
+
+ gpioout: gpioout {
+ brcm,pins = <6>;
+ brcm,function = <1>; /* GPIO out */
+ };
+
+ alt0: alt0 {
+ brcm,pins = <0 1 2 3 4 5 7 8 9 10 11 14 15 40 45>;
+ brcm,function = <4>; /* alt0 */
+ };
+
+ alt3: alt3 {
+ brcm,pins = <48 49 50 51 52 53>;
+ brcm,function = <7>; /* alt3 */
+ };
+};
+
+&i2c0 {
+ status = "okay";
+ clock-frequency = <100000>;
+};
+
+&i2c1 {
+ status = "okay";
+ clock-frequency = <100000>;
+};
+
+&sdhci {
+ status = "okay";
+ bus-width = <4>;
+};
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
new file mode 100644
index 000000000..3342cb140
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -0,0 +1,183 @@
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "brcm,bcm2835";
+ model = "BCM2835";
+ interrupt-parent = <&intc>;
+
+ chosen {
+ bootargs = "earlyprintk console=ttyAMA0";
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x7e000000 0x20000000 0x02000000>;
+
+ timer@7e003000 {
+ compatible = "brcm,bcm2835-system-timer";
+ reg = <0x7e003000 0x1000>;
+ interrupts = <1 0>, <1 1>, <1 2>, <1 3>;
+ clock-frequency = <1000000>;
+ };
+
+ dma: dma@7e007000 {
+ compatible = "brcm,bcm2835-dma";
+ reg = <0x7e007000 0xf00>;
+ interrupts = <1 16>,
+ <1 17>,
+ <1 18>,
+ <1 19>,
+ <1 20>,
+ <1 21>,
+ <1 22>,
+ <1 23>,
+ <1 24>,
+ <1 25>,
+ <1 26>,
+ <1 27>,
+ <1 28>;
+
+ #dma-cells = <1>;
+ brcm,dma-channel-mask = <0x7f35>;
+ };
+
+ intc: interrupt-controller@7e00b200 {
+ compatible = "brcm,bcm2835-armctrl-ic";
+ reg = <0x7e00b200 0x200>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ watchdog@7e100000 {
+ compatible = "brcm,bcm2835-pm-wdt";
+ reg = <0x7e100000 0x28>;
+ };
+
+ rng@7e104000 {
+ compatible = "brcm,bcm2835-rng";
+ reg = <0x7e104000 0x10>;
+ };
+
+ gpio: gpio@7e200000 {
+ compatible = "brcm,bcm2835-gpio";
+ reg = <0x7e200000 0xb4>;
+ /*
+ * The GPIO IP block is designed for 3 banks of GPIOs.
+ * Each bank has a GPIO interrupt for itself.
+ * There is an overall "any bank" interrupt.
+ * In order, these are GIC interrupts 17, 18, 19, 20.
+ * Since the BCM2835 only has 2 banks, the 2nd bank
+ * interrupt output appears to be mirrored onto the
+ * 3rd bank's interrupt signal.
+ * So, a bank0 interrupt shows up on 17, 20, and
+ * a bank1 interrupt shows up on 18, 19, 20!
+ */
+ interrupts = <2 17>, <2 18>, <2 19>, <2 20>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart@7e201000 {
+ compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
+ reg = <0x7e201000 0x1000>;
+ interrupts = <2 25>;
+ clock-frequency = <3000000>;
+ arm,primecell-periphid = <0x00241011>;
+ };
+
+ i2s: i2s@7e203000 {
+ compatible = "brcm,bcm2835-i2s";
+ reg = <0x7e203000 0x20>,
+ <0x7e101098 0x02>;
+
+ dmas = <&dma 2>,
+ <&dma 3>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ spi: spi@7e204000 {
+ compatible = "brcm,bcm2835-spi";
+ reg = <0x7e204000 0x1000>;
+ interrupts = <2 22>;
+ clocks = <&clk_spi>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@20205000 {
+ compatible = "brcm,bcm2835-i2c";
+ reg = <0x7e205000 0x1000>;
+ interrupts = <2 21>;
+ clocks = <&clk_i2c>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ sdhci: sdhci@7e300000 {
+ compatible = "brcm,bcm2835-sdhci";
+ reg = <0x7e300000 0x100>;
+ interrupts = <2 30>;
+ clocks = <&clk_mmc>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@7e804000 {
+ compatible = "brcm,bcm2835-i2c";
+ reg = <0x7e804000 0x1000>;
+ interrupts = <2 21>;
+ clocks = <&clk_i2c>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ usb@7e980000 {
+ compatible = "brcm,bcm2835-usb";
+ reg = <0x7e980000 0x10000>;
+ interrupts = <1 9>;
+ };
+
+ arm-pmu {
+ compatible = "arm,arm1176-pmu";
+ };
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk_mmc: clock@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ #clock-cells = <0>;
+ clock-output-names = "mmc";
+ clock-frequency = <100000000>;
+ };
+
+ clk_i2c: clock@1 {
+ compatible = "fixed-clock";
+ reg = <1>;
+ #clock-cells = <0>;
+ clock-output-names = "i2c";
+ clock-frequency = <250000000>;
+ };
+
+ clk_spi: clock@2 {
+ compatible = "fixed-clock";
+ reg = <2>;
+ #clock-cells = <0>;
+ clock-output-names = "spi";
+ clock-frequency = <250000000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
new file mode 100644
index 000000000..b359c1e61
--- /dev/null
+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
@@ -0,0 +1,130 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ * DTS for Buffalo WZR-1750DHP
+ *
+ * Copyright (C) 2014 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+/dts-v1/;
+
+#include "bcm4708.dtsi"
+
+/ {
+ compatible = "buffalo,wzr-1750dhp", "brcm,bcm4708";
+ model = "Buffalo WZR-1750DHP (BCM4708)";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ spi {
+ compatible = "spi-gpio";
+ num-chipselects = <1>;
+ gpio-sck = <&chipcommon 7 0>;
+ gpio-mosi = <&chipcommon 4 0>;
+ cs-gpios = <&chipcommon 6 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hc595: gpio_spi@0 {
+ compatible = "fairchild,74hc595";
+ reg = <0>;
+ registers-number = <1>;
+ spi-max-frequency = <100000>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ power0 {
+ label = "bcm53xx:red:power";
+ gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ power1 {
+ label = "bcm53xx:white:power";
+ gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ router0 {
+ label = "bcm53xx:blue:router";
+ gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ router1 {
+ label = "bcm53xx:amber:router";
+ gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ wan {
+ label = "bcm53xx:blue:wan";
+ gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ wireless0 {
+ label = "bcm53xx:blue:wireless";
+ gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ wireless1 {
+ label = "bcm53xx:amber:wireless";
+ gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ restart {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+ };
+
+ aoss {
+ label = "AOSS";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
+ };
+
+ /* Commit mode set by switch? */
+ mode {
+ label = "Mode";
+ linux,code = <KEY_SETUP>;
+ gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
+ };
+
+ /* Switch: AP mode */
+ sw_ap {
+ label = "AP";
+ linux,code = <BTN_0>;
+ gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
+ };
+
+ eject {
+ label = "USB eject";
+ linux,code = <KEY_EJECTCD>;
+ gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
new file mode 100644
index 000000000..946c728c4
--- /dev/null
+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
@@ -0,0 +1,60 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ * DTS for Luxul XWC-1000
+ *
+ * Copyright 2014 Luxul Inc.
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+/dts-v1/;
+
+#include "bcm4708.dtsi"
+
+/ {
+ compatible = "luxul,xwc-1000", "brcm,bcm4708";
+ model = "Luxul XWC-1000 (BCM4708)";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ axi@18000000 {
+ nand@28000 {
+ reg = <0x00028000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "ubi";
+ reg = <0x00000000 0x08000000>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ status {
+ label = "bcm53xx:green:status";
+ gpios = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "timer";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ restart {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
new file mode 100644
index 000000000..2ed9e5794
--- /dev/null
+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
@@ -0,0 +1,93 @@
+/*
+ * Broadcom BCM470X / BCM5301X arm platform code.
+ * DTS for Netgear R6250 V1
+ *
+ * Copyright 2013 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+/dts-v1/;
+
+#include "bcm4708.dtsi"
+
+/ {
+ compatible = "netgear,r6250v1", "brcm,bcm4708";
+ model = "Netgear R6250 V1 (BCM4708)";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ chipcommonA {
+ uart0: serial@0300 {
+ status = "okay";
+ };
+
+ uart1: serial@0400 {
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ logo {
+ label = "bcm53xx:white:logo";
+ gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ power0 {
+ label = "bcm53xx:green:power";
+ gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+
+ power1 {
+ label = "bcm53xx:amber:power";
+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ usb {
+ label = "bcm53xx:blue:usb";
+ gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ wireless {
+ label = "bcm53xx:blue:wireless";
+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ wps {
+ label = "WPS";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
+ };
+
+ rfkill {
+ label = "WiFi";
+ linux,code = <KEY_RFKILL>;
+ gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
+ };
+
+ restart {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
new file mode 100644
index 000000000..399104282
--- /dev/null
+++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
@@ -0,0 +1,83 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ * DTS for Netgear R6300 V2
+ *
+ * Copyright (C) 2014 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+/dts-v1/;
+
+#include "bcm4708.dtsi"
+
+/ {
+ compatible = "netgear,r6300v2", "brcm,bcm4708";
+ model = "Netgear R6300 V2 (BCM4708)";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ logo {
+ label = "bcm53xx:white:logo";
+ gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ power0 {
+ label = "bcm53xx:green:power";
+ gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ power1 {
+ label = "bcm53xx:amber:power";
+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+
+ usb {
+ label = "bcm53xx:blue:usb";
+ gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ wireless {
+ label = "bcm53xx:blue:wireless";
+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ wps {
+ label = "WPS";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
+ };
+
+ rfkill {
+ label = "WiFi";
+ linux,code = <KEY_RFKILL>;
+ gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
+ };
+
+ restart {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm4708.dtsi b/arch/arm/boot/dts/bcm4708.dtsi
new file mode 100644
index 000000000..31141e83f
--- /dev/null
+++ b/arch/arm/boot/dts/bcm4708.dtsi
@@ -0,0 +1,34 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ * DTS for BCM4708 SoC.
+ *
+ * Copyright 2013-2014 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcm5301x.dtsi"
+
+/ {
+ compatible = "brcm,bcm4708";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x1>;
+ };
+ };
+
+};
diff --git a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
new file mode 100644
index 000000000..0ee85ea10
--- /dev/null
+++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
@@ -0,0 +1,77 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ * DTS for Asus RT-N18U
+ *
+ * Copyright (C) 2014 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+/dts-v1/;
+
+#include "bcm47081.dtsi"
+
+/ {
+ compatible = "asus,rt-n18u", "brcm,bcm47081", "brcm,bcm4708";
+ model = "Asus RT-N18U (BCM47081)";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ power {
+ label = "bcm53xx:blue:power";
+ gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+
+ usb2 {
+ label = "bcm53xx:blue:usb2";
+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ wan {
+ label = "bcm53xx:blue:wan";
+ gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+
+ lan {
+ label = "bcm53xx:blue:lan";
+ gpios = <&chipcommon 9 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+
+ usb3 {
+ label = "bcm53xx:blue:usb3";
+ gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ restart {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
+ };
+
+ wps {
+ label = "WPS";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
new file mode 100644
index 000000000..db9131e03
--- /dev/null
+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
@@ -0,0 +1,123 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ * DTS for Buffalo WZR-600DHP2
+ *
+ * Copyright (C) 2014 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+/dts-v1/;
+
+#include "bcm47081.dtsi"
+
+/ {
+ compatible = "buffalo,wzr-600dhp2", "brcm,bcm47081", "brcm,bcm4708";
+ model = "Buffalo WZR-600DHP2 (BCM47081)";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ spi {
+ compatible = "spi-gpio";
+ num-chipselects = <1>;
+ gpio-sck = <&chipcommon 7 0>;
+ gpio-mosi = <&chipcommon 4 0>;
+ cs-gpios = <&chipcommon 6 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hc595: gpio_spi@0 {
+ compatible = "fairchild,74hc595";
+ reg = <0>;
+ registers-number = <1>;
+ spi-max-frequency = <100000>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ power0 {
+ label = "bcm53xx:green:power";
+ gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ power1 {
+ label = "bcm53xx:red:power";
+ gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ router0 {
+ label = "bcm53xx:green:router";
+ gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ router1 {
+ label = "bcm53xx:amber:router";
+ gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ wan {
+ label = "bcm53xx:green:wan";
+ gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ wireless0 {
+ label = "bcm53xx:green:wireless";
+ gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ wireless1 {
+ label = "bcm53xx:amber:wireless";
+ gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ aoss {
+ label = "AOSS";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&chipcommon 9 GPIO_ACTIVE_LOW>;
+ };
+
+ restart {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+ };
+
+ /* Switch device mode? */
+ mode {
+ label = "Mode";
+ linux,code = <KEY_SETUP>;
+ gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
+ };
+
+ eject {
+ label = "USB eject";
+ linux,code = <KEY_EJECTCD>;
+ gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
new file mode 100644
index 000000000..7d6868acb
--- /dev/null
+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
@@ -0,0 +1,37 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ * DTS for Buffalo WZR-900DHP
+ *
+ * Copyright (C) 2015 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+/dts-v1/;
+
+#include "bcm47081.dtsi"
+
+/ {
+ compatible = "buffalo,wzr-900dhp", "brcm,bcm47081", "brcm,bcm4708";
+ model = "Buffalo WZR-900DHP (BCM47081)";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ restart {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm47081.dtsi b/arch/arm/boot/dts/bcm47081.dtsi
new file mode 100644
index 000000000..f720012ee
--- /dev/null
+++ b/arch/arm/boot/dts/bcm47081.dtsi
@@ -0,0 +1,26 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ * DTS for BCM47081 SoC.
+ *
+ * Copyright © 2014 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcm5301x.dtsi"
+
+/ {
+ compatible = "brcm,bcm47081";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
new file mode 100644
index 000000000..ea26dd3ec
--- /dev/null
+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
@@ -0,0 +1,77 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ * DTS for Netgear R8000
+ *
+ * Copyright (C) 2015 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+/dts-v1/;
+
+#include "bcm4708.dtsi"
+
+/ {
+ compatible = "netgear,r8000", "brcm,bcm4709", "brcm,bcm4708";
+ model = "Netgear R8000 (BCM4709)";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ power0 {
+ label = "bcm53xx:white:power";
+ gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+
+ power1 {
+ label = "bcm53xx:amber:power";
+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ 5ghz-1 {
+ label = "bcm53xx:white:5ghz-1";
+ gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ 2ghz {
+ label = "bcm53xx:white:2ghz";
+ gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rfkill {
+ label = "WiFi";
+ linux,code = <KEY_RFKILL>;
+ gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
+ };
+
+ wps {
+ label = "WPS";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
+ };
+
+ restart {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi
new file mode 100644
index 000000000..78aec6270
--- /dev/null
+++ b/arch/arm/boot/dts/bcm5301x.dtsi
@@ -0,0 +1,146 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ * Generic DTS part for all BCM53010, BCM53011, BCM53012, BCM53014, BCM53015,
+ * BCM53016, BCM53017, BCM53018, BCM4707, BCM4708 and BCM4709 SoCs
+ *
+ * Copyright 2013-2014 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&gic>;
+
+ chipcommonA {
+ compatible = "simple-bus";
+ ranges = <0x00000000 0x18000000 0x00001000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ uart0: serial@0300 {
+ compatible = "ns16550";
+ reg = <0x0300 0x100>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <100000000>;
+ status = "disabled";
+ };
+
+ uart1: serial@0400 {
+ compatible = "ns16550";
+ reg = <0x0400 0x100>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <100000000>;
+ status = "disabled";
+ };
+ };
+
+ mpcore {
+ compatible = "simple-bus";
+ ranges = <0x00000000 0x19020000 0x00003000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ scu@0000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0x0000 0x100>;
+ };
+
+ timer@0200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x0200 0x100>;
+ interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_periph>;
+ };
+
+ local-timer@0600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x0600 0x100>;
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_periph>;
+ };
+
+ gic: interrupt-controller@1000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x1000 0x1000>,
+ <0x0100 0x100>;
+ };
+
+ L2: cache-controller@2000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x2000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* As long as we do not have a real clock driver us this
+ * fixed clock */
+ clk_periph: periph {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <400000000>;
+ };
+ };
+
+ axi@18000000 {
+ compatible = "brcm,bus-axi";
+ reg = <0x18000000 0x1000>;
+ ranges = <0x00000000 0x18000000 0x00100000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0x000fffff 0xffff>;
+ interrupt-map =
+ /* ChipCommon */
+ <0x00000000 0 &gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+
+ /* USB 2.0 Controller */
+ <0x00021000 0 &gic GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
+
+ /* USB 3.0 Controller */
+ <0x00023000 0 &gic GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
+
+ /* Ethernet Controller 0 */
+ <0x00024000 0 &gic GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+
+ /* Ethernet Controller 1 */
+ <0x00025000 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+
+ /* Ethernet Controller 2 */
+ <0x00026000 0 &gic GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+
+ /* Ethernet Controller 3 */
+ <0x00027000 0 &gic GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
+
+ /* NAND Controller */
+ <0x00028000 0 &gic GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
+ <0x00028000 1 &gic GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+ <0x00028000 2 &gic GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+ <0x00028000 3 &gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+ <0x00028000 4 &gic GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+ <0x00028000 5 &gic GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
+ <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+ <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+
+ chipcommon: chipcommon@0 {
+ reg = <0x00000000 0x1000>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm59056.dtsi b/arch/arm/boot/dts/bcm59056.dtsi
new file mode 100644
index 000000000..066adfb10
--- /dev/null
+++ b/arch/arm/boot/dts/bcm59056.dtsi
@@ -0,0 +1,95 @@
+/*
+* Copyright 2014 Linaro Limited
+* Author: Matt Porter <mporter@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.
+*/
+
+&pmu {
+ compatible = "brcm,bcm59056";
+ regulators {
+ rfldo_reg: rfldo {
+ };
+
+ camldo1_reg: camldo1 {
+ };
+
+ camldo2_reg: camldo2 {
+ };
+
+ simldo1_reg: simldo1 {
+ };
+
+ simldo2_reg: simldo2 {
+ };
+
+ sdldo_reg: sdldo {
+ };
+
+ sdxldo_reg: sdxldo {
+ };
+
+ mmcldo1_reg: mmcldo1 {
+ };
+
+ mmcldo2_reg: mmcldo2 {
+ };
+
+ audldo_reg: audldo {
+ };
+
+ micldo_reg: micldo {
+ };
+
+ usbldo_reg: usbldo {
+ };
+
+ vibldo_reg: vibldo {
+ };
+
+ csr_reg: csr {
+ };
+
+ iosr1_reg: iosr1 {
+ };
+
+ iosr2_reg: iosr2 {
+ };
+
+ msr_reg: msr {
+ };
+
+ sdsr1_reg: sdsr1 {
+ };
+
+ sdsr2_reg: sdsr2 {
+ };
+
+ vsr_reg: vsr {
+ };
+
+ gpldo1_reg: gpldo1 {
+ };
+
+ gpldo2_reg: gpldo2 {
+ };
+
+ gpldo3_reg: gpldo3 {
+ };
+
+ gpldo4_reg: gpldo4 {
+ };
+
+ gpldo5_reg: gpldo5 {
+ };
+
+ gpldo6_reg: gpldo6 {
+ };
+
+ vbus_reg: vbus {
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm63138.dtsi b/arch/arm/boot/dts/bcm63138.dtsi
new file mode 100644
index 000000000..f46329c8a
--- /dev/null
+++ b/arch/arm/boot/dts/bcm63138.dtsi
@@ -0,0 +1,135 @@
+/*
+ * Broadcom BCM63138 DSL SoCs Device Tree
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "brcm,bcm63138";
+ model = "Broadcom BCM63138 DSL SoC";
+ interrupt-parent = <&gic>;
+
+ aliases {
+ uart0 = &serial0;
+ uart1 = &serial1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <1>;
+ };
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ arm_timer_clk: arm_timer_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <500000000>;
+ };
+
+ periph_clk: periph_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <50000000>;
+ clock-output-names = "periph";
+ };
+ };
+
+ /* ARM bus */
+ axi@80000000 {
+ compatible = "simple-bus";
+ ranges = <0 0x80000000 0x784000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ L2: cache-controller@1d000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x1d000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ cache-size = <524288>;
+ cache-sets = <1024>;
+ cache-line-size = <32>;
+ interrupts = <GIC_PPI 0 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ scu: scu@1e000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0x1e000 0x100>;
+ };
+
+ gic: interrupt-controller@1e100 {
+ compatible = "arm,cortex-a9-gic";
+ reg = <0x1f000 0x1000
+ 0x1e100 0x100>;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ };
+
+ global_timer: timer@1e200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x1e200 0x20>;
+ interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&arm_timer_clk>;
+ };
+
+ local_timer: local-timer@1e600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x1e600 0x20>;
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&arm_timer_clk>;
+ };
+
+ twd_watchdog: watchdog@1e620 {
+ compatible = "arm,cortex-a9-twd-wdt";
+ reg = <0x1e620 0x20>;
+ interrupts = <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ /* Legacy UBUS base */
+ ubus@fffe8000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0xfffe8000 0x8100>;
+
+ serial0: serial@600 {
+ compatible = "brcm,bcm6345-uart";
+ reg = <0x600 0x1b>;
+ interrupts = <GIC_SPI 32 0>;
+ clocks = <&periph_clk>;
+ clock-names = "periph";
+ status = "disabled";
+ };
+
+ serial1: serial@620 {
+ compatible = "brcm,bcm6345-uart";
+ reg = <0x620 0x1b>;
+ interrupts = <GIC_SPI 33 0>;
+ clocks = <&periph_clk>;
+ clock-names = "periph";
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm7445-bcm97445svmb.dts b/arch/arm/boot/dts/bcm7445-bcm97445svmb.dts
new file mode 100644
index 000000000..9eec2ac11
--- /dev/null
+++ b/arch/arm/boot/dts/bcm7445-bcm97445svmb.dts
@@ -0,0 +1,14 @@
+/dts-v1/;
+#include "bcm7445.dtsi"
+
+/ {
+ model = "Broadcom STB (bcm7445), SVMB reference board";
+ compatible = "brcm,bcm7445", "brcm,brcmstb";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00 0x00000000 0x00 0x40000000>,
+ <0x00 0x40000000 0x00 0x40000000>,
+ <0x00 0x80000000 0x00 0x40000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/bcm7445.dtsi b/arch/arm/boot/dts/bcm7445.dtsi
new file mode 100644
index 000000000..39ac7840d
--- /dev/null
+++ b/arch/arm/boot/dts/bcm7445.dtsi
@@ -0,0 +1,123 @@
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ model = "Broadcom STB (bcm7445)";
+ compatible = "brcm,bcm7445", "brcm,brcmstb";
+ interrupt-parent = <&gic>;
+
+ chosen {
+ bootargs = "console=ttyS0,115200 earlyprintk";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "brcm,brahma-b15";
+ device_type = "cpu";
+ enable-method = "brcm,brahma-b15";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ compatible = "brcm,brahma-b15";
+ device_type = "cpu";
+ enable-method = "brcm,brahma-b15";
+ reg = <1>;
+ };
+
+ cpu@2 {
+ compatible = "brcm,brahma-b15";
+ device_type = "cpu";
+ enable-method = "brcm,brahma-b15";
+ reg = <2>;
+ };
+
+ cpu@3 {
+ compatible = "brcm,brahma-b15";
+ device_type = "cpu";
+ enable-method = "brcm,brahma-b15";
+ reg = <3>;
+ };
+ };
+
+ gic: interrupt-controller@ffd00000 {
+ compatible = "brcm,brahma-b15-gic", "arm,cortex-a15-gic";
+ reg = <0x00 0xffd01000 0x00 0x1000>,
+ <0x00 0xffd02000 0x00 0x2000>,
+ <0x00 0xffd04000 0x00 0x2000>,
+ <0x00 0xffd06000 0x00 0x2000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(15) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_RAW(15) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_RAW(15) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_RAW(15) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ rdb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0 0x00 0xf0000000 0x1000000>;
+
+ serial@40ab00 {
+ compatible = "ns16550a";
+ reg = <0x40ab00 0x20>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <81000000>;
+ };
+
+ sun_top_ctrl: syscon@404000 {
+ compatible = "brcm,bcm7445-sun-top-ctrl",
+ "syscon";
+ reg = <0x404000 0x51c>;
+ };
+
+ hif_cpubiuctrl: syscon@3e2400 {
+ compatible = "brcm,bcm7445-hif-cpubiuctrl",
+ "syscon";
+ reg = <0x3e2400 0x5b4>;
+ };
+
+ hif_continuation: syscon@452000 {
+ compatible = "brcm,bcm7445-hif-continuation",
+ "syscon";
+ reg = <0x452000 0x100>;
+ };
+
+ irq0_intc: interrupt-controller@40a780 {
+ compatible = "brcm,bcm7120-l2-intc";
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <1>;
+ reg = <0x40a780 0x8>;
+ interrupt-controller;
+ interrupts = <GIC_SPI 0x45 0x0>,
+ <GIC_SPI 0x43 0x0>;
+ brcm,int-map-mask = <0x25c>, <0x7000000>;
+ brcm,int-fwd-mask = <0x70000>;
+ };
+ };
+
+ smpboot {
+ compatible = "brcm,brcmstb-smpboot";
+ syscon-cpu = <&hif_cpubiuctrl 0x88 0x178>;
+ syscon-cont = <&hif_continuation>;
+ };
+
+ reboot {
+ compatible = "brcm,brcmstb-reboot";
+ syscon = <&sun_top_ctrl 0x304 0x308>;
+ };
+};
diff --git a/arch/arm/boot/dts/bcm911360_entphn.dts b/arch/arm/boot/dts/bcm911360_entphn.dts
new file mode 100644
index 000000000..7db484323
--- /dev/null
+++ b/arch/arm/boot/dts/bcm911360_entphn.dts
@@ -0,0 +1,66 @@
+/*
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014 Broadcom Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+#include "bcm-cygnus.dtsi"
+#include "dt-bindings/input/input.h"
+
+/ {
+ model = "Cygnus Enterprise Phone (BCM911360_ENTPHN)";
+ compatible = "brcm,bcm11360", "brcm,cygnus";
+
+ aliases {
+ serial0 = &uart3;
+ };
+
+ chosen {
+ stdout-path = &uart3;
+ bootargs = "console=ttyS0,115200";
+ };
+
+ uart3: serial@18023000 {
+ status = "okay";
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hook {
+ label = "HOOK";
+ linux,code = <KEY_O>;
+ gpios = <&gpio_asiu 48 0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm911360k.dts b/arch/arm/boot/dts/bcm911360k.dts
new file mode 100644
index 000000000..9658d4f62
--- /dev/null
+++ b/arch/arm/boot/dts/bcm911360k.dts
@@ -0,0 +1,53 @@
+/*
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014 Broadcom Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+#include "bcm-cygnus.dtsi"
+
+/ {
+ model = "Cygnus SVK (BCM911360K)";
+ compatible = "brcm,bcm11360", "brcm,cygnus";
+
+ aliases {
+ serial0 = &uart3;
+ };
+
+ chosen {
+ stdout-path = &uart3;
+ bootargs = "console=ttyS0,115200";
+ };
+
+ uart3: serial@18023000 {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/bcm958300k.dts b/arch/arm/boot/dts/bcm958300k.dts
new file mode 100644
index 000000000..c9eb8565e
--- /dev/null
+++ b/arch/arm/boot/dts/bcm958300k.dts
@@ -0,0 +1,61 @@
+/*
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014 Broadcom Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+#include "bcm-cygnus.dtsi"
+
+/ {
+ model = "Cygnus SVK (BCM958300K)";
+ compatible = "brcm,bcm58300", "brcm,cygnus";
+
+ aliases {
+ serial0 = &uart3;
+ };
+
+ chosen {
+ stdout-path = &uart3;
+ bootargs = "console=ttyS0,115200";
+ };
+
+ pcie0: pcie@18012000 {
+ status = "okay";
+ };
+
+ pcie1: pcie@18013000 {
+ status = "okay";
+ };
+
+ uart3: serial@18023000 {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/bcm958305k.dts b/arch/arm/boot/dts/bcm958305k.dts
new file mode 100644
index 000000000..56b429abb
--- /dev/null
+++ b/arch/arm/boot/dts/bcm958305k.dts
@@ -0,0 +1,53 @@
+/*
+ * BSD LICENSE
+ *
+ * Copyright(c) 2015 Broadcom Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+#include "bcm-cygnus.dtsi"
+
+/ {
+ model = "Cygnus Wireless Audio (BCM958305K)";
+ compatible = "brcm,bcm58305", "brcm,cygnus";
+
+ aliases {
+ serial0 = &uart3;
+ };
+
+ chosen {
+ stdout-path = &uart3;
+ bootargs = "console=ttyS0,115200";
+ };
+
+ uart3: serial@18023000 {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/bcm963138dvt.dts b/arch/arm/boot/dts/bcm963138dvt.dts
new file mode 100644
index 000000000..69c93395e
--- /dev/null
+++ b/arch/arm/boot/dts/bcm963138dvt.dts
@@ -0,0 +1,30 @@
+/*
+ * Broadcom BCM63138 Reference Board DTS
+ */
+
+/dts-v1/;
+
+#include "bcm63138.dtsi"
+
+/ {
+ compatible = "brcm,BCM963138DVT", "brcm,bcm63138";
+ model = "Broadcom BCM963138DVT";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ stdout-path = &serial0;
+ };
+
+ memory {
+ reg = <0x0 0x08000000>;
+ };
+
+};
+
+&serial0 {
+ status = "okay";
+};
+
+&serial1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts b/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts
new file mode 100644
index 000000000..86d85d889
--- /dev/null
+++ b/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts
@@ -0,0 +1,45 @@
+/*
+ * Device Tree file for Sony NSZ-GS7
+ *
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.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.
+ */
+
+/dts-v1/;
+
+#include "berlin2.dtsi"
+
+/ {
+ model = "Sony NSZ-GS7";
+ compatible = "sony,nsz-gs7", "marvell,berlin2", "marvell,berlin";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 earlyprintk";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>; /* 1 GB */
+ };
+};
+
+&ahci { status = "okay"; };
+
+&eth1 { status = "okay"; };
+
+/* Unpopulated SATA plug on solder side */
+&sata0 { status = "okay"; };
+
+&sata_phy { status = "okay"; };
+
+/* Samsung M8G2FA 8GB eMMC */
+&sdhci2 {
+ non-removable;
+ bus-width = <8>;
+ status = "okay";
+};
+
+&uart0 { status = "okay"; };
diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
new file mode 100644
index 000000000..63d00a63c
--- /dev/null
+++ b/arch/arm/boot/dts/berlin2.dtsi
@@ -0,0 +1,474 @@
+/*
+ * Device Tree Include file for Marvell Armada 1500 (Berlin BG2) SoC
+ *
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * based on GPL'ed 2.6 kernel sources
+ * (c) Marvell International 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.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/berlin2.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ model = "Marvell Armada 1500 (BG2) SoC";
+ compatible = "marvell,berlin2", "marvell,berlin";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "marvell,berlin-smp";
+
+ cpu@0 {
+ compatible = "marvell,pj4b";
+ device_type = "cpu";
+ next-level-cache = <&l2>;
+ reg = <0>;
+ };
+
+ cpu@1 {
+ compatible = "marvell,pj4b";
+ device_type = "cpu";
+ next-level-cache = <&l2>;
+ reg = <1>;
+ };
+ };
+
+ refclk: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&gic>;
+
+ ranges = <0 0xf7000000 0x1000000>;
+
+ sdhci0: sdhci@ab0000 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xab0000 0x200>;
+ clocks = <&chip CLKID_SDIO0XIN>, <&chip CLKID_SDIO0>;
+ clock-names = "io", "core";
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ sdhci1: sdhci@ab0800 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xab0800 0x200>;
+ clocks = <&chip CLKID_SDIO1XIN>, <&chip CLKID_SDIO1>;
+ clock-names = "io", "core";
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ sdhci2: sdhci@ab1000 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xab1000 0x200>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&chip CLKID_NFC_ECC>, <&chip CLKID_NFC>;
+ clock-names = "io", "core";
+ pinctrl-0 = <&emmc_pmux>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ l2: l2-cache-controller@ac0000 {
+ compatible = "marvell,tauros3-cache", "arm,pl310-cache";
+ reg = <0xac0000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ scu: snoop-control-unit@ad0000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0xad0000 0x58>;
+ };
+
+ gic: interrupt-controller@ad1000 {
+ compatible = "arm,cortex-a9-gic";
+ reg = <0xad1000 0x1000>, <0xad0100 0x0100>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
+
+ local-timer@ad0600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xad0600 0x20>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+ clocks = <&chip CLKID_TWD>;
+ };
+
+ eth1: ethernet@b90000 {
+ compatible = "marvell,pxa168-eth";
+ reg = <0xb90000 0x10000>;
+ clocks = <&chip CLKID_GETH1>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ /* set by bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy-connection-type = "mii";
+ phy-handle = <&ethphy1>;
+ status = "disabled";
+
+ ethphy1: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+ cpu-ctrl@dd0000 {
+ compatible = "marvell,berlin-cpu-ctrl";
+ reg = <0xdd0000 0x10000>;
+ };
+
+ eth0: ethernet@e50000 {
+ compatible = "marvell,pxa168-eth";
+ reg = <0xe50000 0x10000>;
+ clocks = <&chip CLKID_GETH0>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ /* set by bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy-connection-type = "mii";
+ phy-handle = <&ethphy0>;
+ status = "disabled";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+ apb@e80000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0 0xe80000 0x10000>;
+ interrupt-parent = <&aic>;
+
+ gpio0: gpio@0400 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x0400 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ porta: gpio-port@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <8>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <0>;
+ };
+ };
+
+ gpio1: gpio@0800 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x0800 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portb: gpio-port@1 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <8>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <1>;
+ };
+ };
+
+ gpio2: gpio@0c00 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x0c00 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portc: gpio-port@2 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <8>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <2>;
+ };
+ };
+
+ gpio3: gpio@1000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x1000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portd: gpio-port@3 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <8>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <3>;
+ };
+ };
+
+ timer0: timer@2c00 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c00 0x14>;
+ interrupts = <8>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "okay";
+ };
+
+ timer1: timer@2c14 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c14 0x14>;
+ interrupts = <9>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "okay";
+ };
+
+ timer2: timer@2c28 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c28 0x14>;
+ interrupts = <10>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ timer3: timer@2c3c {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c3c 0x14>;
+ interrupts = <11>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ timer4: timer@2c50 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c50 0x14>;
+ interrupts = <12>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ timer5: timer@2c64 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c64 0x14>;
+ interrupts = <13>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ timer6: timer@2c78 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c78 0x14>;
+ interrupts = <14>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ timer7: timer@2c8c {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c8c 0x14>;
+ interrupts = <15>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ aic: interrupt-controller@3000 {
+ compatible = "snps,dw-apb-ictl";
+ reg = <0x3000 0xc00>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ ahci: sata@e90000 {
+ compatible = "marvell,berlin2-ahci", "generic-ahci";
+ reg = <0xe90000 0x1000>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&chip CLKID_SATA>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sata0: sata-port@0 {
+ reg = <0>;
+ phys = <&sata_phy 0>;
+ status = "disabled";
+ };
+
+ sata1: sata-port@1 {
+ reg = <1>;
+ phys = <&sata_phy 1>;
+ status = "disabled";
+ };
+ };
+
+ sata_phy: phy@e900a0 {
+ compatible = "marvell,berlin2-sata-phy";
+ reg = <0xe900a0 0x200>;
+ clocks = <&chip CLKID_SATA>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #phy-cells = <1>;
+ status = "disabled";
+
+ sata-phy@0 {
+ reg = <0>;
+ };
+
+ sata-phy@1 {
+ reg = <1>;
+ };
+ };
+
+ chip: chip-control@ea0000 {
+ compatible = "marvell,berlin2-chip-ctrl";
+ #clock-cells = <1>;
+ #reset-cells = <2>;
+ reg = <0xea0000 0x400>;
+ clocks = <&refclk>;
+ clock-names = "refclk";
+
+ emmc_pmux: emmc-pmux {
+ groups = "G26";
+ function = "emmc";
+ };
+ };
+
+ apb@fc0000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0 0xfc0000 0x10000>;
+ interrupt-parent = <&sic>;
+
+ sm_gpio1: gpio@5000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x5000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portf: gpio-port@5 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <8>;
+ reg = <0>;
+ };
+ };
+
+ sm_gpio0: gpio@c000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xc000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ porte: gpio-port@4 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <8>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <11>;
+ };
+ };
+
+ uart0: serial@9000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x9000 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ interrupts = <8>;
+ clocks = <&refclk>;
+ pinctrl-0 = <&uart0_pmux>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ uart1: serial@a000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xa000 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ interrupts = <9>;
+ clocks = <&refclk>;
+ pinctrl-0 = <&uart1_pmux>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ uart2: serial@b000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xb000 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ interrupts = <10>;
+ clocks = <&refclk>;
+ pinctrl-0 = <&uart2_pmux>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ sysctrl: system-controller@d000 {
+ compatible = "marvell,berlin2-system-ctrl";
+ reg = <0xd000 0x100>;
+
+ uart0_pmux: uart0-pmux {
+ groups = "GSM4";
+ function = "uart0";
+ };
+
+ uart1_pmux: uart1-pmux {
+ groups = "GSM5";
+ function = "uart1";
+ };
+
+ uart2_pmux: uart2-pmux {
+ groups = "GSM3";
+ function = "uart2";
+ };
+ };
+
+ sic: interrupt-controller@e000 {
+ compatible = "snps,dw-apb-ictl";
+ reg = <0xe000 0x400>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/berlin2cd-google-chromecast.dts b/arch/arm/boot/dts/berlin2cd-google-chromecast.dts
new file mode 100644
index 000000000..30270be4d
--- /dev/null
+++ b/arch/arm/boot/dts/berlin2cd-google-chromecast.dts
@@ -0,0 +1,59 @@
+/*
+ * Device Tree file for Google Chromecast
+ *
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.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.
+ */
+
+/dts-v1/;
+
+#include "berlin2cd.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Google Chromecast";
+ compatible = "google,chromecast", "marvell,berlin2cd", "marvell,berlin";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 earlyprintk";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>; /* 512 MB */
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ white {
+ label = "white";
+ gpios = <&portc 1 GPIO_ACTIVE_HIGH>;
+ default-state = "keep";
+ };
+
+ red {
+ label = "red";
+ gpios = <&portc 2 GPIO_ACTIVE_HIGH>;
+ default-state = "keep";
+ };
+ };
+};
+
+/*
+ * AzureWave AW-NH387 (Marvell 88W8787)
+ * 802.11b/g/n + Bluetooth 2.1
+ */
+&sdhci0 {
+ non-removable;
+ status = "okay";
+};
+
+&uart0 { status = "okay"; };
+
+&usb_phy1 { status = "okay"; };
+
+&usb1 { status = "okay"; };
diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi
new file mode 100644
index 000000000..81b670ac4
--- /dev/null
+++ b/arch/arm/boot/dts/berlin2cd.dtsi
@@ -0,0 +1,406 @@
+/*
+ * Device Tree Include file for Marvell Armada 1500-mini (Berlin BG2CD) SoC
+ *
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * based on GPL'ed 2.6 kernel sources
+ * (c) Marvell International 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.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/berlin2.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ model = "Marvell Armada 1500-mini (BG2CD) SoC";
+ compatible = "marvell,berlin2cd", "marvell,berlin";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ next-level-cache = <&l2>;
+ reg = <0>;
+ };
+ };
+
+ refclk: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&gic>;
+
+ ranges = <0 0xf7000000 0x1000000>;
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sdhci0: sdhci@ab0000 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xab0000 0x200>;
+ clocks = <&chip CLKID_SDIO0XIN>, <&chip CLKID_SDIO0>;
+ clock-names = "io", "core";
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ l2: l2-cache-controller@ac0000 {
+ compatible = "arm,pl310-cache";
+ reg = <0xac0000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ gic: interrupt-controller@ad1000 {
+ compatible = "arm,cortex-a9-gic";
+ reg = <0xad1000 0x1000>, <0xad0100 0x0100>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
+
+ local-timer@ad0600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xad0600 0x20>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
+ clocks = <&chip CLKID_TWD>;
+ };
+
+ usb_phy0: usb-phy@b74000 {
+ compatible = "marvell,berlin2cd-usb-phy";
+ reg = <0xb74000 0x128>;
+ #phy-cells = <0>;
+ resets = <&chip 0x178 23>;
+ status = "disabled";
+ };
+
+ usb_phy1: usb-phy@b78000 {
+ compatible = "marvell,berlin2cd-usb-phy";
+ reg = <0xb78000 0x128>;
+ #phy-cells = <0>;
+ resets = <&chip 0x178 24>;
+ status = "disabled";
+ };
+
+ eth1: ethernet@b90000 {
+ compatible = "marvell,pxa168-eth";
+ reg = <0xb90000 0x10000>;
+ clocks = <&chip CLKID_GETH1>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ /* set by bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy-connection-type = "mii";
+ phy-handle = <&ethphy1>;
+ status = "disabled";
+
+ ethphy1: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+ eth0: ethernet@e50000 {
+ compatible = "marvell,pxa168-eth";
+ reg = <0xe50000 0x10000>;
+ clocks = <&chip CLKID_GETH0>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ /* set by bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy-connection-type = "mii";
+ phy-handle = <&ethphy0>;
+ status = "disabled";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+ apb@e80000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0 0xe80000 0x10000>;
+ interrupt-parent = <&aic>;
+
+ gpio0: gpio@0400 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x0400 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ porta: gpio-port@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <8>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <0>;
+ };
+ };
+
+ gpio1: gpio@0800 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x0800 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portb: gpio-port@1 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <8>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <1>;
+ };
+ };
+
+ gpio2: gpio@0c00 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x0c00 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portc: gpio-port@2 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <8>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <2>;
+ };
+ };
+
+ gpio3: gpio@1000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x1000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portd: gpio-port@3 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <8>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <3>;
+ };
+ };
+
+ timer0: timer@2c00 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c00 0x14>;
+ interrupts = <8>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "okay";
+ };
+
+ timer1: timer@2c14 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c14 0x14>;
+ interrupts = <9>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "okay";
+ };
+
+ timer2: timer@2c28 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c28 0x14>;
+ interrupts = <10>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ timer3: timer@2c3c {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c3c 0x14>;
+ interrupts = <11>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ timer4: timer@2c50 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c50 0x14>;
+ interrupts = <12>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ timer5: timer@2c64 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c64 0x14>;
+ interrupts = <13>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ timer6: timer@2c78 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c78 0x14>;
+ interrupts = <14>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ timer7: timer@2c8c {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c8c 0x14>;
+ interrupts = <15>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ aic: interrupt-controller@3000 {
+ compatible = "snps,dw-apb-ictl";
+ reg = <0x3000 0xc00>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ chip: chip-control@ea0000 {
+ compatible = "marvell,berlin2cd-chip-ctrl";
+ #clock-cells = <1>;
+ #reset-cells = <2>;
+ reg = <0xea0000 0x400>;
+ clocks = <&refclk>;
+ clock-names = "refclk";
+
+ uart0_pmux: uart0-pmux {
+ groups = "G6";
+ function = "uart0";
+ };
+ };
+
+ usb0: usb@ed0000 {
+ compatible = "chipidea,usb2";
+ reg = <0xed0000 0x200>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&chip CLKID_USB0>;
+ phys = <&usb_phy0>;
+ phy-names = "usb-phy";
+ status = "disabled";
+ };
+
+ usb1: usb@ee0000 {
+ compatible = "chipidea,usb2";
+ reg = <0xee0000 0x200>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&chip CLKID_USB1>;
+ phys = <&usb_phy1>;
+ phy-names = "usb-phy";
+ status = "disabled";
+ };
+
+ apb@fc0000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0 0xfc0000 0x10000>;
+ interrupt-parent = <&sic>;
+
+ sm_gpio1: gpio@5000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x5000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portf: gpio-port@5 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <8>;
+ reg = <0>;
+ };
+ };
+
+ sm_gpio0: gpio@c000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xc000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ porte: gpio-port@4 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <8>;
+ reg = <0>;
+ };
+ };
+
+ uart0: serial@9000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x9000 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ interrupts = <8>;
+ clocks = <&refclk>;
+ pinctrl-0 = <&uart0_pmux>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ uart1: serial@a000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xa000 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ interrupts = <9>;
+ clocks = <&refclk>;
+ status = "disabled";
+ };
+
+ sysctrl: system-controller@d000 {
+ compatible = "marvell,berlin2cd-system-ctrl";
+ reg = <0xd000 0x100>;
+ };
+
+ sic: interrupt-controller@e000 {
+ compatible = "snps,dw-apb-ictl";
+ reg = <0xe000 0x400>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/berlin2q-marvell-dmp.dts b/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
new file mode 100644
index 000000000..a98ac1bd8
--- /dev/null
+++ b/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2014 Antoine TĂ©nart <antoine.tenart@free-electrons.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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "berlin2q.dtsi"
+
+/ {
+ model = "Marvell BG2-Q DMP";
+ compatible = "marvell,berlin2q-dmp", "marvell,berlin2q", "marvell,berlin";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000>;
+ };
+
+ choosen {
+ bootargs = "console=ttyS0,115200 earlyprintk";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb0_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "usb0_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&portb 8 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb1_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&portb 10 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb2_vbus: regulator@2 {
+ compatible = "regulator-fixed";
+ regulator-name = "usb2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&portb 12 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+};
+
+&sdhci1 {
+ broken-cd;
+ sdhci,wp-inverted;
+ status = "okay";
+};
+
+&sdhci2 {
+ broken-cd;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+&i2c2 {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usb_phy0 {
+ status = "okay";
+};
+
+&usb_phy2 {
+ status = "okay";
+};
+
+&usb0 {
+ vbus-supply = <&reg_usb0_vbus>;
+ status = "okay";
+};
+
+&usb2 {
+ vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
+
+&eth0 {
+ status = "okay";
+};
+
+&sata0 {
+ status = "okay";
+};
+
+&sata_phy {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi
new file mode 100644
index 000000000..be5397288
--- /dev/null
+++ b/arch/arm/boot/dts/berlin2q.dtsi
@@ -0,0 +1,563 @@
+/*
+ * Copyright (C) 2014 Antoine TĂ©nart <antoine.tenart@free-electrons.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 <dt-bindings/clock/berlin2q.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ model = "Marvell Armada 1500 pro (BG2-Q) SoC";
+ compatible = "marvell,berlin2q", "marvell,berlin";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "marvell,berlin-smp";
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ next-level-cache = <&l2>;
+ reg = <0>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ next-level-cache = <&l2>;
+ reg = <1>;
+ };
+
+ cpu@2 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ next-level-cache = <&l2>;
+ reg = <2>;
+ };
+
+ cpu@3 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ next-level-cache = <&l2>;
+ reg = <3>;
+ };
+ };
+
+ refclk: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0 0xf7000000 0x1000000>;
+ interrupt-parent = <&gic>;
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sdhci0: sdhci@ab0000 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xab0000 0x200>;
+ clocks = <&chip CLKID_SDIO1XIN>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ sdhci1: sdhci@ab0800 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xab0800 0x200>;
+ clocks = <&chip CLKID_SDIO1XIN>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ sdhci2: sdhci@ab1000 {
+ compatible = "mrvl,pxav3-mmc";
+ reg = <0xab1000 0x200>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&chip CLKID_NFC_ECC>, <&chip CLKID_NFC>;
+ clock-names = "io", "core";
+ status = "disabled";
+ };
+
+ l2: l2-cache-controller@ac0000 {
+ compatible = "arm,pl310-cache";
+ reg = <0xac0000 0x1000>;
+ cache-level = <2>;
+ arm,data-latency = <2 2 2>;
+ arm,tag-latency = <2 2 2>;
+ };
+
+ scu: snoop-control-unit@ad0000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0xad0000 0x58>;
+ };
+
+ local-timer@ad0600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xad0600 0x20>;
+ clocks = <&chip CLKID_TWD>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ gic: interrupt-controller@ad1000 {
+ compatible = "arm,cortex-a9-gic";
+ reg = <0xad1000 0x1000>, <0xad0100 0x100>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
+
+ usb_phy2: phy@a2f400 {
+ compatible = "marvell,berlin2-usb-phy";
+ reg = <0xa2f400 0x128>;
+ #phy-cells = <0>;
+ resets = <&chip 0x104 14>;
+ status = "disabled";
+ };
+
+ usb2: usb@a30000 {
+ compatible = "chipidea,usb2";
+ reg = <0xa30000 0x10000>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&chip CLKID_USB2>;
+ phys = <&usb_phy2>;
+ phy-names = "usb-phy";
+ status = "disabled";
+ };
+
+ usb_phy0: phy@b74000 {
+ compatible = "marvell,berlin2-usb-phy";
+ reg = <0xb74000 0x128>;
+ #phy-cells = <0>;
+ resets = <&chip 0x104 12>;
+ status = "disabled";
+ };
+
+ usb_phy1: phy@b78000 {
+ compatible = "marvell,berlin2-usb-phy";
+ reg = <0xb78000 0x128>;
+ #phy-cells = <0>;
+ resets = <&chip 0x104 13>;
+ status = "disabled";
+ };
+
+ eth0: ethernet@b90000 {
+ compatible = "marvell,pxa168-eth";
+ reg = <0xb90000 0x10000>;
+ clocks = <&chip CLKID_GETH0>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ /* set by bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy-connection-type = "mii";
+ phy-handle = <&ethphy0>;
+ status = "disabled";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+ cpu-ctrl@dd0000 {
+ compatible = "marvell,berlin-cpu-ctrl";
+ reg = <0xdd0000 0x10000>;
+ };
+
+ apb@e80000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0 0xe80000 0x10000>;
+ interrupt-parent = <&aic>;
+
+ gpio0: gpio@0400 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x0400 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ porta: gpio-port@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <32>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <0>;
+ };
+ };
+
+ gpio1: gpio@0800 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x0800 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portb: gpio-port@1 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <32>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <1>;
+ };
+ };
+
+ gpio2: gpio@0c00 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x0c00 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portc: gpio-port@2 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <32>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <2>;
+ };
+ };
+
+ gpio3: gpio@1000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x1000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portd: gpio-port@3 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <32>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <3>;
+ };
+ };
+
+ i2c0: i2c@1400 {
+ compatible = "snps,designware-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x1400 0x100>;
+ interrupt-parent = <&aic>;
+ interrupts = <4>;
+ clocks = <&chip CLKID_CFG>;
+ pinctrl-0 = <&twsi0_pmux>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ i2c1: i2c@1800 {
+ compatible = "snps,designware-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x1800 0x100>;
+ interrupt-parent = <&aic>;
+ interrupts = <5>;
+ clocks = <&chip CLKID_CFG>;
+ pinctrl-0 = <&twsi1_pmux>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ timer0: timer@2c00 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c00 0x14>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ interrupts = <8>;
+ };
+
+ timer1: timer@2c14 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c14 0x14>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ };
+
+ timer2: timer@2c28 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c28 0x14>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ timer3: timer@2c3c {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c3c 0x14>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ timer4: timer@2c50 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c50 0x14>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ timer5: timer@2c64 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c64 0x14>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ timer6: timer@2c78 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c78 0x14>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ timer7: timer@2c8c {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2c8c 0x14>;
+ clocks = <&chip CLKID_CFG>;
+ clock-names = "timer";
+ status = "disabled";
+ };
+
+ aic: interrupt-controller@3800 {
+ compatible = "snps,dw-apb-ictl";
+ reg = <0x3800 0x30>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ chip: chip-control@ea0000 {
+ compatible = "marvell,berlin2q-chip-ctrl";
+ #clock-cells = <1>;
+ #reset-cells = <2>;
+ reg = <0xea0000 0x400>, <0xdd0170 0x10>;
+ clocks = <&refclk>;
+ clock-names = "refclk";
+
+ twsi0_pmux: twsi0-pmux {
+ groups = "G6";
+ function = "twsi0";
+ };
+
+ twsi1_pmux: twsi1-pmux {
+ groups = "G7";
+ function = "twsi1";
+ };
+ };
+
+ ahci: sata@e90000 {
+ compatible = "marvell,berlin2q-ahci", "generic-ahci";
+ reg = <0xe90000 0x1000>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&chip CLKID_SATA>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sata0: sata-port@0 {
+ reg = <0>;
+ phys = <&sata_phy 0>;
+ status = "disabled";
+ };
+
+ sata1: sata-port@1 {
+ reg = <1>;
+ phys = <&sata_phy 1>;
+ status = "disabled";
+ };
+ };
+
+ sata_phy: phy@e900a0 {
+ compatible = "marvell,berlin2q-sata-phy";
+ reg = <0xe900a0 0x200>;
+ clocks = <&chip CLKID_SATA>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #phy-cells = <1>;
+ status = "disabled";
+
+ sata-phy@0 {
+ reg = <0>;
+ };
+
+ sata-phy@1 {
+ reg = <1>;
+ };
+ };
+
+ usb0: usb@ed0000 {
+ compatible = "chipidea,usb2";
+ reg = <0xed0000 0x10000>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&chip CLKID_USB0>;
+ phys = <&usb_phy0>;
+ phy-names = "usb-phy";
+ status = "disabled";
+ };
+
+ usb1: usb@ee0000 {
+ compatible = "chipidea,usb2";
+ reg = <0xee0000 0x10000>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&chip CLKID_USB1>;
+ phys = <&usb_phy1>;
+ phy-names = "usb-phy";
+ status = "disabled";
+ };
+
+ apb@fc0000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0 0xfc0000 0x10000>;
+ interrupt-parent = <&sic>;
+
+ sm_gpio1: gpio@5000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x5000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portf: gpio-port@5 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <32>;
+ reg = <0>;
+ };
+ };
+
+ i2c2: i2c@7000 {
+ compatible = "snps,designware-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x7000 0x100>;
+ interrupt-parent = <&sic>;
+ interrupts = <6>;
+ clocks = <&refclk>;
+ pinctrl-0 = <&twsi2_pmux>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ i2c3: i2c@8000 {
+ compatible = "snps,designware-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x8000 0x100>;
+ interrupt-parent = <&sic>;
+ interrupts = <7>;
+ clocks = <&refclk>;
+ pinctrl-0 = <&twsi3_pmux>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ uart0: uart@9000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x9000 0x100>;
+ interrupt-parent = <&sic>;
+ interrupts = <8>;
+ clocks = <&refclk>;
+ reg-shift = <2>;
+ pinctrl-0 = <&uart0_pmux>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ uart1: uart@a000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xa000 0x100>;
+ interrupt-parent = <&sic>;
+ interrupts = <9>;
+ clocks = <&refclk>;
+ reg-shift = <2>;
+ pinctrl-0 = <&uart1_pmux>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ sm_gpio0: gpio@c000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xc000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ porte: gpio-port@4 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <32>;
+ reg = <0>;
+ };
+ };
+
+ sysctrl: pin-controller@d000 {
+ compatible = "marvell,berlin2q-system-ctrl";
+ reg = <0xd000 0x100>;
+
+ uart0_pmux: uart0-pmux {
+ groups = "GSM12";
+ function = "uart0";
+ };
+
+ uart1_pmux: uart1-pmux {
+ groups = "GSM14";
+ function = "uart1";
+ };
+
+ twsi2_pmux: twsi2-pmux {
+ groups = "GSM13";
+ function = "twsi2";
+ };
+
+ twsi3_pmux: twsi3-pmux {
+ groups = "GSM14";
+ function = "twsi3";
+ };
+ };
+
+ sic: interrupt-controller@e000 {
+ compatible = "snps,dw-apb-ictl";
+ reg = <0xe000 0x30>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/cros-adc-thermistors.dtsi b/arch/arm/boot/dts/cros-adc-thermistors.dtsi
new file mode 100644
index 000000000..acd4fe183
--- /dev/null
+++ b/arch/arm/boot/dts/cros-adc-thermistors.dtsi
@@ -0,0 +1,44 @@
+/*
+ * Thermistor dts fragment for devices that use Thermistors as
+ * children of the IIO based ADC.
+ *
+ * Currently, used by Exynos5420 based Peach PIT and
+ * Exynos5800 based Peach PI.
+ *
+ * Copyright (c) 2014 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.
+*/
+
+&adc {
+ ncp15wb473@3 {
+ compatible = "murata,ncp15wb473";
+ pullup-uv = <1800000>;
+ pullup-ohm = <47000>;
+ pulldown-ohm = <0>;
+ io-channels = <&adc 3>;
+ };
+ ncp15wb473@4 {
+ compatible = "murata,ncp15wb473";
+ pullup-uv = <1800000>;
+ pullup-ohm = <47000>;
+ pulldown-ohm = <0>;
+ io-channels = <&adc 4>;
+ };
+ ncp15wb473@5 {
+ compatible = "murata,ncp15wb473";
+ pullup-uv = <1800000>;
+ pullup-ohm = <47000>;
+ pulldown-ohm = <0>;
+ io-channels = <&adc 5>;
+ };
+ ncp15wb473@6 {
+ compatible = "murata,ncp15wb473";
+ pullup-uv = <1800000>;
+ pullup-ohm = <47000>;
+ pulldown-ohm = <0>;
+ io-channels = <&adc 6>;
+ };
+};
diff --git a/arch/arm/boot/dts/cros-ec-keyboard.dtsi b/arch/arm/boot/dts/cros-ec-keyboard.dtsi
new file mode 100644
index 000000000..9c7fb0aca
--- /dev/null
+++ b/arch/arm/boot/dts/cros-ec-keyboard.dtsi
@@ -0,0 +1,105 @@
+/*
+ * Keyboard dts fragment for devices that use cros-ec-keyboard
+ *
+ * Copyright (c) 2014 Google, 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 <dt-bindings/input/input.h>
+
+&cros_ec {
+ keyboard-controller {
+ compatible = "google,cros-ec-keyb";
+ keypad,num-rows = <8>;
+ keypad,num-columns = <13>;
+ google,needs-ghost-filter;
+
+ linux,keymap = <
+ MATRIX_KEY(0x00, 0x01, KEY_LEFTMETA)
+ MATRIX_KEY(0x00, 0x02, KEY_F1)
+ MATRIX_KEY(0x00, 0x03, KEY_B)
+ MATRIX_KEY(0x00, 0x04, KEY_F10)
+ MATRIX_KEY(0x00, 0x06, KEY_N)
+ MATRIX_KEY(0x00, 0x08, KEY_EQUAL)
+ MATRIX_KEY(0x00, 0x0a, KEY_RIGHTALT)
+
+ MATRIX_KEY(0x01, 0x01, KEY_ESC)
+ MATRIX_KEY(0x01, 0x02, KEY_F4)
+ MATRIX_KEY(0x01, 0x03, KEY_G)
+ MATRIX_KEY(0x01, 0x04, KEY_F7)
+ MATRIX_KEY(0x01, 0x06, KEY_H)
+ MATRIX_KEY(0x01, 0x08, KEY_APOSTROPHE)
+ MATRIX_KEY(0x01, 0x09, KEY_F9)
+ MATRIX_KEY(0x01, 0x0b, KEY_BACKSPACE)
+
+ MATRIX_KEY(0x02, 0x00, KEY_LEFTCTRL)
+ MATRIX_KEY(0x02, 0x01, KEY_TAB)
+ MATRIX_KEY(0x02, 0x02, KEY_F3)
+ MATRIX_KEY(0x02, 0x03, KEY_T)
+ MATRIX_KEY(0x02, 0x04, KEY_F6)
+ MATRIX_KEY(0x02, 0x05, KEY_RIGHTBRACE)
+ MATRIX_KEY(0x02, 0x06, KEY_Y)
+ MATRIX_KEY(0x02, 0x07, KEY_102ND)
+ MATRIX_KEY(0x02, 0x08, KEY_LEFTBRACE)
+ MATRIX_KEY(0x02, 0x09, KEY_F8)
+
+ MATRIX_KEY(0x03, 0x01, KEY_GRAVE)
+ MATRIX_KEY(0x03, 0x02, KEY_F2)
+ MATRIX_KEY(0x03, 0x03, KEY_5)
+ MATRIX_KEY(0x03, 0x04, KEY_F5)
+ MATRIX_KEY(0x03, 0x06, KEY_6)
+ MATRIX_KEY(0x03, 0x08, KEY_MINUS)
+ MATRIX_KEY(0x03, 0x0b, KEY_BACKSLASH)
+
+ MATRIX_KEY(0x04, 0x00, KEY_RIGHTCTRL)
+ MATRIX_KEY(0x04, 0x01, KEY_A)
+ MATRIX_KEY(0x04, 0x02, KEY_D)
+ MATRIX_KEY(0x04, 0x03, KEY_F)
+ MATRIX_KEY(0x04, 0x04, KEY_S)
+ MATRIX_KEY(0x04, 0x05, KEY_K)
+ MATRIX_KEY(0x04, 0x06, KEY_J)
+ MATRIX_KEY(0x04, 0x08, KEY_SEMICOLON)
+ MATRIX_KEY(0x04, 0x09, KEY_L)
+ MATRIX_KEY(0x04, 0x0a, KEY_BACKSLASH)
+ MATRIX_KEY(0x04, 0x0b, KEY_ENTER)
+
+ MATRIX_KEY(0x05, 0x01, KEY_Z)
+ MATRIX_KEY(0x05, 0x02, KEY_C)
+ MATRIX_KEY(0x05, 0x03, KEY_V)
+ MATRIX_KEY(0x05, 0x04, KEY_X)
+ MATRIX_KEY(0x05, 0x05, KEY_COMMA)
+ MATRIX_KEY(0x05, 0x06, KEY_M)
+ MATRIX_KEY(0x05, 0x07, KEY_LEFTSHIFT)
+ MATRIX_KEY(0x05, 0x08, KEY_SLASH)
+ MATRIX_KEY(0x05, 0x09, KEY_DOT)
+ MATRIX_KEY(0x05, 0x0b, KEY_SPACE)
+
+ MATRIX_KEY(0x06, 0x01, KEY_1)
+ MATRIX_KEY(0x06, 0x02, KEY_3)
+ MATRIX_KEY(0x06, 0x03, KEY_4)
+ MATRIX_KEY(0x06, 0x04, KEY_2)
+ MATRIX_KEY(0x06, 0x05, KEY_8)
+ MATRIX_KEY(0x06, 0x06, KEY_7)
+ MATRIX_KEY(0x06, 0x08, KEY_0)
+ MATRIX_KEY(0x06, 0x09, KEY_9)
+ MATRIX_KEY(0x06, 0x0a, KEY_LEFTALT)
+ MATRIX_KEY(0x06, 0x0b, KEY_DOWN)
+ MATRIX_KEY(0x06, 0x0c, KEY_RIGHT)
+
+ MATRIX_KEY(0x07, 0x01, KEY_Q)
+ MATRIX_KEY(0x07, 0x02, KEY_E)
+ MATRIX_KEY(0x07, 0x03, KEY_R)
+ MATRIX_KEY(0x07, 0x04, KEY_W)
+ MATRIX_KEY(0x07, 0x05, KEY_I)
+ MATRIX_KEY(0x07, 0x06, KEY_U)
+ MATRIX_KEY(0x07, 0x07, KEY_RIGHTSHIFT)
+ MATRIX_KEY(0x07, 0x08, KEY_P)
+ MATRIX_KEY(0x07, 0x09, KEY_O)
+ MATRIX_KEY(0x07, 0x0b, KEY_UP)
+ MATRIX_KEY(0x07, 0x0c, KEY_LEFT)
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/cx92755.dtsi b/arch/arm/boot/dts/cx92755.dtsi
new file mode 100644
index 000000000..490c08075
--- /dev/null
+++ b/arch/arm/boot/dts/cx92755.dtsi
@@ -0,0 +1,113 @@
+/*
+ * Device Tree Include file for the Conexant Digicolor CX92755 SoC
+ *
+ * Author: Baruch Siach <baruch@tkos.co.il>
+ *
+ * Copyright (C) 2014 Paradox Innovation Ltd.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "cnxt,cx92755";
+
+ interrupt-parent = <&intc>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a8";
+ reg = <0x0>;
+ };
+ };
+
+ main_clk: main_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <200000000>;
+ };
+
+ intc: interrupt-controller@f0000040 {
+ compatible = "cnxt,cx92755-ic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xf0000040 0x40>;
+ syscon = <&uc_regs>;
+ };
+
+ timer@f0000fc0 {
+ compatible = "cnxt,cx92755-timer";
+ reg = <0xf0000fc0 0x40>;
+ interrupts = <19>, <31>, <34>, <35>, <52>, <53>, <54>, <55>;
+ clocks = <&main_clk>;
+ };
+
+ uc_regs: syscon@f00003a0 {
+ compatible = "cnxt,cx92755-uc", "syscon";
+ reg = <0xf00003a0 0x10>;
+ };
+
+ uart0: uart@f0000740 {
+ compatible = "cnxt,cx92755-usart";
+ reg = <0xf0000740 0x20>;
+ clocks = <&main_clk>;
+ interrupts = <44>;
+ status = "disabled";
+ };
+
+ uart1: uart@f0000760 {
+ compatible = "cnxt,cx92755-usart";
+ reg = <0xf0000760 0x20>;
+ clocks = <&main_clk>;
+ interrupts = <45>;
+ status = "disabled";
+ };
+
+ uart2: uart@f0000780 {
+ compatible = "cnxt,cx92755-usart";
+ reg = <0xf0000780 0x20>;
+ clocks = <&main_clk>;
+ interrupts = <46>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/cx92755_equinox.dts b/arch/arm/boot/dts/cx92755_equinox.dts
new file mode 100644
index 000000000..f33bf5635
--- /dev/null
+++ b/arch/arm/boot/dts/cx92755_equinox.dts
@@ -0,0 +1,74 @@
+/*
+ * Device Tree file for the Conexant Equinox CX92755 EVK
+ *
+ * Author: Baruch Siach <baruch@tkos.co.il>
+ *
+ * Copyright (C) 2014 Paradox Innovation Ltd.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "cx92755.dtsi"
+
+/ {
+ model = "Conexant Equinox CX92755 EVK";
+ compatible = "cnxt,equinox", "cnxt,cx92755";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ };
+
+ memory@0 {
+ reg = <0 0x8000000>;
+ device_type = "memory";
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ stdout-path = &uart0;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/da850-enbw-cmc.dts b/arch/arm/boot/dts/da850-enbw-cmc.dts
new file mode 100644
index 000000000..e750ab908
--- /dev/null
+++ b/arch/arm/boot/dts/da850-enbw-cmc.dts
@@ -0,0 +1,30 @@
+/*
+ * Device Tree for AM1808 EnBW CMC board
+ *
+ * Copyright 2012 DENX Software Engineering GmbH
+ * Heiko Schocher <hs@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.
+ */
+/dts-v1/;
+#include "da850.dtsi"
+
+/ {
+ compatible = "enbw,cmc", "ti,da850";
+ model = "EnBW CMC";
+
+ soc {
+ serial0: serial@1c42000 {
+ status = "okay";
+ };
+ serial1: serial@1d0c000 {
+ status = "okay";
+ };
+ serial2: serial@1d0d000 {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts
new file mode 100644
index 000000000..4f935ad9f
--- /dev/null
+++ b/arch/arm/boot/dts/da850-evm.dts
@@ -0,0 +1,244 @@
+/*
+ * Device Tree for DA850 EVM board
+ *
+ * Copyright (C) 2012 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, version 2.
+ */
+/dts-v1/;
+#include "da850.dtsi"
+
+/ {
+ compatible = "ti,da850-evm", "ti,da850";
+ model = "DA850/AM1808/OMAP-L138 EVM";
+
+ soc {
+ pmx_core: pinmux@1c14120 {
+ status = "okay";
+
+ mcasp0_pins: pinmux_mcasp0_pins {
+ pinctrl-single,bits = <
+ /*
+ * AHCLKX, ACLKX, AFSX, AHCLKR, ACLKR,
+ * AFSR, AMUTE
+ */
+ 0x00 0x11111111 0xffffffff
+ /* AXR11, AXR12 */
+ 0x04 0x00011000 0x000ff000
+ >;
+ };
+ };
+ serial0: serial@1c42000 {
+ status = "okay";
+ };
+ serial1: serial@1d0c000 {
+ status = "okay";
+ };
+ serial2: serial@1d0d000 {
+ status = "okay";
+ };
+ rtc0: rtc@1c23000 {
+ status = "okay";
+ };
+ i2c0: i2c@1c22000 {
+ status = "okay";
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+
+ tps: tps@48 {
+ reg = <0x48>;
+ };
+ tlv320aic3106: tlv320aic3106@18 {
+ #sound-dai-cells = <0>;
+ compatible = "ti,tlv320aic3106";
+ reg = <0x18>;
+ status = "okay";
+
+ /* Regulators */
+ IOVDD-supply = <&vdcdc2_reg>;
+ /* Derived from VBAT: Baseboard 3.3V / 1.8V */
+ AVDD-supply = <&vbat>;
+ DRVDD-supply = <&vbat>;
+ DVDD-supply = <&vbat>;
+ };
+
+ };
+ wdt: wdt@1c21000 {
+ status = "okay";
+ };
+ mmc0: mmc@1c40000 {
+ max-frequency = <50000000>;
+ bus-width = <4>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins>;
+ };
+ spi1: spi@1f0e000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins &spi1_cs0_pin>;
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p64";
+ spi-max-frequency = <30000000>;
+ reg = <0>;
+ partition@0 {
+ label = "U-Boot-SPL";
+ reg = <0x00000000 0x00010000>;
+ read-only;
+ };
+ partition@1 {
+ label = "U-Boot";
+ reg = <0x00010000 0x00080000>;
+ read-only;
+ };
+ partition@2 {
+ label = "U-Boot-Env";
+ reg = <0x00090000 0x00010000>;
+ read-only;
+ };
+ partition@3 {
+ label = "Kernel";
+ reg = <0x000a0000 0x00280000>;
+ };
+ partition@4 {
+ label = "Filesystem";
+ reg = <0x00320000 0x00400000>;
+ };
+ partition@5 {
+ label = "MAC-Address";
+ reg = <0x007f0000 0x00010000>;
+ read-only;
+ };
+ };
+ };
+ mdio: mdio@1e24000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+ bus_freq = <2200000>;
+ };
+ eth0: ethernet@1e20000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mii_pins>;
+ };
+ gpio: gpio@1e26000 {
+ status = "okay";
+ };
+ };
+ nand_cs3@62000000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand_cs3_pins>;
+ };
+ vbat: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vbat";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "DA850/OMAP-L138 EVM";
+ simple-audio-card,widgets =
+ "Line", "Line In",
+ "Line", "Line Out";
+ simple-audio-card,routing =
+ "LINE1L", "Line In",
+ "LINE1R", "Line In",
+ "Line Out", "LLOUT",
+ "Line Out", "RLOUT";
+ simple-audio-card,format = "dsp_b";
+ simple-audio-card,bitclock-master = <&link0_codec>;
+ simple-audio-card,frame-master = <&link0_codec>;
+ simple-audio-card,bitclock-inversion;
+
+ simple-audio-card,cpu {
+ sound-dai = <&mcasp0>;
+ system-clock-frequency = <24576000>;
+ };
+
+ link0_codec: simple-audio-card,codec {
+ sound-dai = <&tlv320aic3106>;
+ system-clock-frequency = <24576000>;
+ };
+ };
+};
+
+/include/ "tps6507x.dtsi"
+
+&tps {
+ vdcdc1_2-supply = <&vbat>;
+ vdcdc3-supply = <&vbat>;
+ vldo1_2-supply = <&vbat>;
+
+ regulators {
+ vdcdc1_reg: regulator@0 {
+ regulator-name = "VDCDC1_3.3V";
+ regulator-min-microvolt = <3150000>;
+ regulator-max-microvolt = <3450000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdcdc2_reg: regulator@1 {
+ regulator-name = "VDCDC2_3.3V";
+ regulator-min-microvolt = <1710000>;
+ regulator-max-microvolt = <3450000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ti,defdcdc_default = <1>;
+ };
+
+ vdcdc3_reg: regulator@2 {
+ regulator-name = "VDCDC3_1.2V";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ti,defdcdc_default = <1>;
+ };
+
+ ldo1_reg: regulator@3 {
+ regulator-name = "LDO1_1.8V";
+ regulator-min-microvolt = <1710000>;
+ regulator-max-microvolt = <1890000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo2_reg: regulator@4 {
+ regulator-name = "LDO2_1.2V";
+ regulator-min-microvolt = <1140000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+};
+
+&mcasp0 {
+ #sound-dai-cells = <0>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcasp0_pins>;
+
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ tdm-slots = <2>;
+ /* 4 serializer */
+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+ 0 0 0 0
+ 0 0 0 0
+ 0 0 0 1
+ 2 0 0 0
+ >;
+ tx-num-evt = <32>;
+ rx-num-evt = <32>;
+};
diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
new file mode 100644
index 000000000..0bd98cd00
--- /dev/null
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -0,0 +1,306 @@
+/*
+ * Copyright 2012 DENX Software Engineering GmbH
+ * Heiko Schocher <hs@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.
+ */
+#include "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ arm {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ intc: interrupt-controller {
+ compatible = "ti,cp-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ ti,intc-size = <100>;
+ reg = <0xfffee000 0x2000>;
+ };
+ };
+ soc {
+ compatible = "simple-bus";
+ model = "da850";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x01c00000 0x400000>;
+ interrupt-parent = <&intc>;
+
+ pmx_core: pinmux@1c14120 {
+ compatible = "pinctrl-single";
+ reg = <0x14120 0x50>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-single,bit-per-mux;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0xf>;
+ status = "disabled";
+
+ nand_cs3_pins: pinmux_nand_pins {
+ pinctrl-single,bits = <
+ /* EMA_OE, EMA_WE */
+ 0x1c 0x00110000 0x00ff0000
+ /* EMA_CS[4],EMA_CS[3]*/
+ 0x1c 0x00000110 0x00000ff0
+ /*
+ * EMA_D[0], EMA_D[1], EMA_D[2],
+ * EMA_D[3], EMA_D[4], EMA_D[5],
+ * EMA_D[6], EMA_D[7]
+ */
+ 0x24 0x11111111 0xffffffff
+ /* EMA_A[1], EMA_A[2] */
+ 0x30 0x01100000 0x0ff00000
+ >;
+ };
+ i2c0_pins: pinmux_i2c0_pins {
+ pinctrl-single,bits = <
+ /* I2C0_SDA,I2C0_SCL */
+ 0x10 0x00002200 0x0000ff00
+ >;
+ };
+ mmc0_pins: pinmux_mmc_pins {
+ pinctrl-single,bits = <
+ /* MMCSD0_DAT[3] MMCSD0_DAT[2]
+ * MMCSD0_DAT[1] MMCSD0_DAT[0]
+ * MMCSD0_CMD MMCSD0_CLK
+ */
+ 0x28 0x00222222 0x00ffffff
+ >;
+ };
+ ehrpwm0a_pins: pinmux_ehrpwm0a_pins {
+ pinctrl-single,bits = <
+ /* EPWM0A */
+ 0xc 0x00000002 0x0000000f
+ >;
+ };
+ ehrpwm0b_pins: pinmux_ehrpwm0b_pins {
+ pinctrl-single,bits = <
+ /* EPWM0B */
+ 0xc 0x00000020 0x000000f0
+ >;
+ };
+ ehrpwm1a_pins: pinmux_ehrpwm1a_pins {
+ pinctrl-single,bits = <
+ /* EPWM1A */
+ 0x14 0x00000002 0x0000000f
+ >;
+ };
+ ehrpwm1b_pins: pinmux_ehrpwm1b_pins {
+ pinctrl-single,bits = <
+ /* EPWM1B */
+ 0x14 0x00000020 0x000000f0
+ >;
+ };
+ ecap0_pins: pinmux_ecap0_pins {
+ pinctrl-single,bits = <
+ /* ECAP0_APWM0 */
+ 0x8 0x20000000 0xf0000000
+ >;
+ };
+ ecap1_pins: pinmux_ecap1_pins {
+ pinctrl-single,bits = <
+ /* ECAP1_APWM1 */
+ 0x4 0x40000000 0xf0000000
+ >;
+ };
+ ecap2_pins: pinmux_ecap2_pins {
+ pinctrl-single,bits = <
+ /* ECAP2_APWM2 */
+ 0x4 0x00000004 0x0000000f
+ >;
+ };
+ spi1_pins: pinmux_spi_pins {
+ pinctrl-single,bits = <
+ /* SIMO, SOMI, CLK */
+ 0x14 0x00110100 0x00ff0f00
+ >;
+ };
+ spi1_cs0_pin: pinmux_spi1_cs0 {
+ pinctrl-single,bits = <
+ /* CS0 */
+ 0x14 0x00000010 0x000000f0
+ >;
+ };
+ mdio_pins: pinmux_mdio_pins {
+ pinctrl-single,bits = <
+ /* MDIO_CLK, MDIO_D */
+ 0x10 0x00000088 0x000000ff
+ >;
+ };
+ mii_pins: pinmux_mii_pins {
+ pinctrl-single,bits = <
+ /*
+ * MII_TXEN, MII_TXCLK, MII_COL
+ * MII_TXD_3, MII_TXD_2, MII_TXD_1
+ * MII_TXD_0
+ */
+ 0x8 0x88888880 0xfffffff0
+ /*
+ * MII_RXER, MII_CRS, MII_RXCLK
+ * MII_RXDV, MII_RXD_3, MII_RXD_2
+ * MII_RXD_1, MII_RXD_0
+ */
+ 0xc 0x88888888 0xffffffff
+ >;
+ };
+
+ };
+ edma0: edma@01c00000 {
+ compatible = "ti,edma3";
+ reg = <0x0 0x10000>;
+ interrupts = <11 13 12>;
+ #dma-cells = <1>;
+ };
+ serial0: serial@1c42000 {
+ compatible = "ns16550a";
+ reg = <0x42000 0x100>;
+ reg-shift = <2>;
+ interrupts = <25>;
+ status = "disabled";
+ };
+ serial1: serial@1d0c000 {
+ compatible = "ns16550a";
+ reg = <0x10c000 0x100>;
+ reg-shift = <2>;
+ interrupts = <53>;
+ status = "disabled";
+ };
+ serial2: serial@1d0d000 {
+ compatible = "ns16550a";
+ reg = <0x10d000 0x100>;
+ reg-shift = <2>;
+ interrupts = <61>;
+ status = "disabled";
+ };
+ rtc0: rtc@1c23000 {
+ compatible = "ti,da830-rtc";
+ reg = <0x23000 0x1000>;
+ interrupts = <19
+ 19>;
+ status = "disabled";
+ };
+ i2c0: i2c@1c22000 {
+ compatible = "ti,davinci-i2c";
+ reg = <0x22000 0x1000>;
+ interrupts = <15>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ wdt: wdt@1c21000 {
+ compatible = "ti,davinci-wdt";
+ reg = <0x21000 0x1000>;
+ status = "disabled";
+ };
+ mmc0: mmc@1c40000 {
+ compatible = "ti,da830-mmc";
+ reg = <0x40000 0x1000>;
+ interrupts = <16>;
+ status = "disabled";
+ };
+ ehrpwm0: ehrpwm@01f00000 {
+ compatible = "ti,da850-ehrpwm", "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x300000 0x2000>;
+ status = "disabled";
+ };
+ ehrpwm1: ehrpwm@01f02000 {
+ compatible = "ti,da850-ehrpwm", "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x302000 0x2000>;
+ status = "disabled";
+ };
+ ecap0: ecap@01f06000 {
+ compatible = "ti,da850-ecap", "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x306000 0x80>;
+ status = "disabled";
+ };
+ ecap1: ecap@01f07000 {
+ compatible = "ti,da850-ecap", "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x307000 0x80>;
+ status = "disabled";
+ };
+ ecap2: ecap@01f08000 {
+ compatible = "ti,da850-ecap", "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x308000 0x80>;
+ status = "disabled";
+ };
+ spi1: spi@1f0e000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "ti,da830-spi";
+ reg = <0x30e000 0x1000>;
+ num-cs = <4>;
+ ti,davinci-spi-intr-line = <1>;
+ interrupts = <56>;
+ status = "disabled";
+ };
+ mdio: mdio@1e24000 {
+ compatible = "ti,davinci_mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x224000 0x1000>;
+ };
+ eth0: ethernet@1e20000 {
+ compatible = "ti,davinci-dm6467-emac";
+ reg = <0x220000 0x4000>;
+ ti,davinci-ctrl-reg-offset = <0x3000>;
+ ti,davinci-ctrl-mod-reg-offset = <0x2000>;
+ ti,davinci-ctrl-ram-offset = <0>;
+ ti,davinci-ctrl-ram-size = <0x2000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <33
+ 34
+ 35
+ 36
+ >;
+ };
+ gpio: gpio@1e26000 {
+ compatible = "ti,dm6441-gpio";
+ gpio-controller;
+ reg = <0x226000 0x1000>;
+ interrupts = <42 IRQ_TYPE_EDGE_BOTH
+ 43 IRQ_TYPE_EDGE_BOTH 44 IRQ_TYPE_EDGE_BOTH
+ 45 IRQ_TYPE_EDGE_BOTH 46 IRQ_TYPE_EDGE_BOTH
+ 47 IRQ_TYPE_EDGE_BOTH 48 IRQ_TYPE_EDGE_BOTH
+ 49 IRQ_TYPE_EDGE_BOTH 50 IRQ_TYPE_EDGE_BOTH>;
+ ti,ngpio = <144>;
+ ti,davinci-gpio-unbanked = <0>;
+ status = "disabled";
+ };
+
+ mcasp0: mcasp@01d00000 {
+ compatible = "ti,da830-mcasp-audio";
+ reg = <0x100000 0x2000>,
+ <0x102000 0x400000>;
+ reg-names = "mpu", "dat";
+ interrupts = <54>;
+ interrupt-names = "common";
+ status = "disabled";
+ dmas = <&edma0 1>,
+ <&edma0 0>;
+ dma-names = "tx", "rx";
+ };
+ };
+ nand_cs3@62000000 {
+ compatible = "ti,davinci-nand";
+ reg = <0x62000000 0x807ff
+ 0x68000000 0x8000>;
+ ti,davinci-chipselect = <1>;
+ ti,davinci-mask-ale = <0>;
+ ti,davinci-mask-cle = <0>;
+ ti,davinci-mask-chipsel = <0>;
+ ti,davinci-ecc-mode = "hw";
+ ti,davinci-ecc-bits = <4>;
+ ti,davinci-nand-use-bbt;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/dm8168-evm.dts b/arch/arm/boot/dts/dm8168-evm.dts
new file mode 100644
index 000000000..169a85578
--- /dev/null
+++ b/arch/arm/boot/dts/dm8168-evm.dts
@@ -0,0 +1,173 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "dm816x.dtsi"
+
+/ {
+ model = "DM8168 EVM";
+ compatible = "ti,dm8168-evm", "ti,dm8168";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000 /* 1 GB */
+ 0xc0000000 0x40000000>; /* 1 GB */
+ };
+
+ /* FDC6331L controlled by SD_POW pin */
+ vmmcsd_fixed: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsd_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&dm816x_pinmux {
+ mcspi1_pins: pinmux_mcspi1_pins {
+ pinctrl-single,pins = <
+ DM816X_IOPAD(0x0a94, MUX_MODE0) /* SPI_SCLK */
+ DM816X_IOPAD(0x0a98, MUX_MODE0) /* SPI_SCS0 */
+ DM816X_IOPAD(0x0aa8, MUX_MODE0) /* SPI_D0 */
+ DM816X_IOPAD(0x0aac, MUX_MODE0) /* SPI_D1 */
+ >;
+ };
+
+ mmc_pins: pinmux_mmc_pins {
+ pinctrl-single,pins = <
+ DM816X_IOPAD(0x0a70, MUX_MODE0) /* SD_POW */
+ DM816X_IOPAD(0x0a74, MUX_MODE0) /* SD_CLK */
+ DM816X_IOPAD(0x0a78, MUX_MODE0) /* SD_CMD */
+ DM816X_IOPAD(0x0a7C, MUX_MODE0) /* SD_DAT0 */
+ DM816X_IOPAD(0x0a80, MUX_MODE0) /* SD_DAT1 */
+ DM816X_IOPAD(0x0a84, MUX_MODE0) /* SD_DAT2 */
+ DM816X_IOPAD(0x0a88, MUX_MODE0) /* SD_DAT2 */
+ DM816X_IOPAD(0x0a8c, MUX_MODE2) /* GP1[7] */
+ DM816X_IOPAD(0x0a90, MUX_MODE2) /* GP1[8] */
+ >;
+ };
+
+ usb0_pins: pinmux_usb0_pins {
+ pinctrl-single,pins = <
+ DM816X_IOPAD(0x0d04, MUX_MODE0) /* USB0_DRVVBUS */
+ >;
+ };
+
+ usb1_pins: pinmux_usb1_pins {
+ pinctrl-single,pins = <
+ DM816X_IOPAD(0x0d08, MUX_MODE0) /* USB1_DRVVBUS */
+ >;
+ };
+};
+
+&i2c1 {
+ extgpio0: pcf8575@20 {
+ compatible = "nxp,pcf8575";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&i2c2 {
+ extgpio1: pcf8575@20 {
+ compatible = "nxp,pcf8575";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&gpmc {
+ ranges = <0 0 0x04000000 0x01000000>; /* CS0: 16MB for NAND */
+
+ nand@0,0 {
+ linux,mtd-name= "micron,mt29f2g16aadwp";
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ti,nand-ecc-opt = "bch8";
+ nand-bus-width = <16>;
+ gpmc,device-width = <2>;
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <44>;
+ gpmc,cs-wr-off-ns = <44>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <34>;
+ gpmc,adv-wr-off-ns = <44>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <40>;
+ gpmc,oe-on-ns = <0>;
+ gpmc,oe-off-ns = <54>;
+ gpmc,access-ns = <64>;
+ gpmc,rd-cycle-ns = <82>;
+ gpmc,wr-cycle-ns = <82>;
+ gpmc,wait-on-read = "true";
+ gpmc,wait-on-write = "true";
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+ partition@0 {
+ label = "X-Loader";
+ reg = <0 0x80000>;
+ };
+ partition@0x80000 {
+ label = "U-Boot";
+ reg = <0x80000 0x1c0000>;
+ };
+ partition@0x1c0000 {
+ label = "Environment";
+ reg = <0x240000 0x40000>;
+ };
+ partition@0x280000 {
+ label = "Kernel";
+ reg = <0x280000 0x500000>;
+ };
+ partition@0x780000 {
+ label = "Filesystem";
+ reg = <0x780000 0xf880000>;
+ };
+ };
+};
+
+&mcspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi1_pins>;
+
+ m25p80@0 {
+ compatible = "w25x32";
+ spi-max-frequency = <48000000>;
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc_pins>;
+ vmmc-supply = <&vmmcsd_fixed>;
+ bus-width = <4>;
+ cd-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
+};
+
+/* At least dm8168-evm rev c won't support multipoint, later may */
+&usb0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_pins>;
+ mentor,multipoint = <0>;
+};
+
+&usb1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_pins>;
+ mentor,multipoint = <0>;
+};
diff --git a/arch/arm/boot/dts/dm816x-clocks.dtsi b/arch/arm/boot/dts/dm816x-clocks.dtsi
new file mode 100644
index 000000000..50d9d338f
--- /dev/null
+++ b/arch/arm/boot/dts/dm816x-clocks.dtsi
@@ -0,0 +1,250 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+&scrm {
+ main_fapll: main_fapll {
+ #clock-cells = <1>;
+ compatible = "ti,dm816-fapll-clock";
+ reg = <0x400 0x40>;
+ clocks = <&sys_clkin_ck &sys_clkin_ck>;
+ clock-indices = <1>, <2>, <3>, <4>, <5>,
+ <6>, <7>;
+ clock-output-names = "main_pll_clk1",
+ "main_pll_clk2",
+ "main_pll_clk3",
+ "main_pll_clk4",
+ "main_pll_clk5",
+ "main_pll_clk6",
+ "main_pll_clk7";
+ };
+
+ ddr_fapll: ddr_fapll {
+ #clock-cells = <1>;
+ compatible = "ti,dm816-fapll-clock";
+ reg = <0x440 0x30>;
+ clocks = <&sys_clkin_ck &sys_clkin_ck>;
+ clock-indices = <1>, <2>, <3>, <4>;
+ clock-output-names = "ddr_pll_clk1",
+ "ddr_pll_clk2",
+ "ddr_pll_clk3",
+ "ddr_pll_clk4";
+ };
+
+ video_fapll: video_fapll {
+ #clock-cells = <1>;
+ compatible = "ti,dm816-fapll-clock";
+ reg = <0x470 0x30>;
+ clocks = <&sys_clkin_ck &sys_clkin_ck>;
+ clock-indices = <1>, <2>, <3>;
+ clock-output-names = "video_pll_clk1",
+ "video_pll_clk2",
+ "video_pll_clk3";
+ };
+
+ audio_fapll: audio_fapll {
+ #clock-cells = <1>;
+ compatible = "ti,dm816-fapll-clock";
+ reg = <0x4a0 0x30>;
+ clocks = <&main_fapll 7>, < &sys_clkin_ck>;
+ clock-indices = <1>, <2>, <3>, <4>, <5>;
+ clock-output-names = "audio_pll_clk1",
+ "audio_pll_clk2",
+ "audio_pll_clk3",
+ "audio_pll_clk4",
+ "audio_pll_clk5";
+ };
+};
+
+&scrm_clocks {
+ secure_32k_ck: secure_32k_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ sys_32k_ck: sys_32k_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ tclkin_ck: tclkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ sys_clkin_ck: sys_clkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <27000000>;
+ };
+};
+
+/* 0x48180000 */
+&prcm_clocks {
+ clkout_pre_ck: clkout_pre_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&main_fapll 5 &ddr_fapll 1 &video_fapll 1
+ &audio_fapll 1>;
+ reg = <0x100>;
+ };
+
+ clkout_div_ck: clkout_div_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&clkout_pre_ck>;
+ ti,bit-shift = <3>;
+ ti,max-div = <8>;
+ reg = <0x100>;
+ };
+
+ clkout_ck: clkout_ck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&clkout_div_ck>;
+ ti,bit-shift = <7>;
+ reg = <0x100>;
+ };
+
+ /* CM_DPLL clocks p1795 */
+ sysclk1_ck: sysclk1_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&main_fapll 1>;
+ ti,max-div = <7>;
+ reg = <0x0300>;
+ };
+
+ sysclk2_ck: sysclk2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&main_fapll 2>;
+ ti,max-div = <7>;
+ reg = <0x0304>;
+ };
+
+ sysclk3_ck: sysclk3_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&main_fapll 3>;
+ ti,max-div = <7>;
+ reg = <0x0308>;
+ };
+
+ sysclk4_ck: sysclk4_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&main_fapll 4>;
+ ti,max-div = <1>;
+ reg = <0x030c>;
+ };
+
+ sysclk5_ck: sysclk5_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&sysclk4_ck>;
+ ti,max-div = <1>;
+ reg = <0x0310>;
+ };
+
+ sysclk6_ck: sysclk6_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&main_fapll 4>;
+ ti,dividers = <2>, <4>;
+ reg = <0x0314>;
+ };
+
+ sysclk10_ck: sysclk10_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&ddr_fapll 2>;
+ ti,max-div = <7>;
+ reg = <0x0324>;
+ };
+
+ sysclk24_ck: sysclk24_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&main_fapll 5>;
+ ti,max-div = <7>;
+ reg = <0x03b4>;
+ };
+
+ mpu_ck: mpu_ck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sysclk2_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x15dc>;
+ };
+
+ audio_pll_a_ck: audio_pll_a_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&audio_fapll 1>;
+ ti,max-div = <7>;
+ reg = <0x035c>;
+ };
+
+ sysclk18_ck: sysclk18_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_32k_ck>, <&audio_pll_a_ck>;
+ reg = <0x0378>;
+ };
+
+ timer1_fck: timer1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sysclk18_ck>, <&sys_clkin_ck>;
+ reg = <0x0390>;
+ };
+
+ timer2_fck: timer2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sysclk18_ck>, <&sys_clkin_ck>;
+ reg = <0x0394>;
+ };
+
+ timer3_fck: timer3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sysclk18_ck>, <&sys_clkin_ck>;
+ reg = <0x0398>;
+ };
+
+ timer4_fck: timer4_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sysclk18_ck>, <&sys_clkin_ck>;
+ reg = <0x039c>;
+ };
+
+ timer5_fck: timer5_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sysclk18_ck>, <&sys_clkin_ck>;
+ reg = <0x03a0>;
+ };
+
+ timer6_fck: timer6_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sysclk18_ck>, <&sys_clkin_ck>;
+ reg = <0x03a4>;
+ };
+
+ timer7_fck: timer7_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sysclk18_ck>, <&sys_clkin_ck>;
+ reg = <0x03a8>;
+ };
+};
diff --git a/arch/arm/boot/dts/dm816x.dtsi b/arch/arm/boot/dts/dm816x.dtsi
new file mode 100644
index 000000000..289806adb
--- /dev/null
+++ b/arch/arm/boot/dts/dm816x.dtsi
@@ -0,0 +1,488 @@
+/*
+ * This file is licensed under the terms 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/omap.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "ti,dm816";
+ interrupt-parent = <&intc>;
+
+ aliases {
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ ethernet0 = &eth0;
+ ethernet1 = &eth1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ compatible = "arm,cortex-a8";
+ device_type = "cpu";
+ reg = <0>;
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a8-pmu";
+ interrupts = <3>;
+ };
+
+ /*
+ * The soc node represents the soc top level view. It is used for IPs
+ * that are not memory mapped in the MPU view or for the MPU itself.
+ */
+ soc {
+ compatible = "ti,omap-infra";
+ mpu {
+ compatible = "ti,omap3-mpu";
+ ti,hwmods = "mpu";
+ };
+ };
+
+ /*
+ * XXX: Use a flat representation of the dm816x interconnect.
+ * The real dm816x interconnect network is quite complex. Since
+ * it will not bring real advantage to represent that in DT
+ * for the moment, just use a fake OCP bus entry to represent
+ * the whole bus hierarchy.
+ */
+ ocp {
+ compatible = "ti,omap3-l3-smx", "simple-bus";
+ reg = <0x44000000 0x10000>;
+ interrupts = <9 10>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "l3_main";
+
+ prcm: prcm@48180000 {
+ compatible = "ti,dm816-prcm";
+ reg = <0x48180000 0x4000>;
+
+ prcm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ prcm_clockdomains: clockdomains {
+ };
+ };
+
+ scrm: scrm@48140000 {
+ compatible = "ti,dm816-scrm", "simple-bus";
+ reg = <0x48140000 0x21000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x48140000 0x21000>;
+
+ dm816x_pinmux: pinmux@800 {
+ compatible = "pinctrl-single";
+ reg = <0x800 0x50a>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-single,register-width = <16>;
+ pinctrl-single,function-mask = <0xf>;
+ };
+
+ /* Device Configuration Registers */
+ scm_conf: syscon@600 {
+ compatible = "syscon", "simple-bus";
+ reg = <0x600 0x110>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x600 0x110>;
+
+ usb_phy0: usb-phy@20 {
+ compatible = "ti,dm8168-usb-phy";
+ reg = <0x20 0x8>;
+ reg-names = "phy";
+ clocks = <&main_fapll 6>;
+ clock-names = "refclk";
+ #phy-cells = <0>;
+ syscon = <&scm_conf>;
+ };
+
+ usb_phy1: usb-phy@28 {
+ compatible = "ti,dm8168-usb-phy";
+ reg = <0x28 0x8>;
+ reg-names = "phy";
+ clocks = <&main_fapll 6>;
+ clock-names = "refclk";
+ #phy-cells = <0>;
+ syscon = <&scm_conf>;
+ };
+ };
+
+ scrm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ scrm_clockdomains: clockdomains {
+ };
+ };
+
+ edma: edma@49000000 {
+ compatible = "ti,edma3";
+ ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2", "tptc3";
+ reg = <0x49000000 0x10000>,
+ <0x44e10f90 0x40>;
+ interrupts = <12 13 14>;
+ #dma-cells = <1>;
+ };
+
+ elm: elm@48080000 {
+ compatible = "ti,816-elm";
+ ti,hwmods = "elm";
+ reg = <0x48080000 0x2000>;
+ interrupts = <4>;
+ };
+
+ gpio1: gpio@48032000 {
+ compatible = "ti,omap4-gpio";
+ ti,hwmods = "gpio1";
+ ti,gpio-always-on;
+ reg = <0x48032000 0x1000>;
+ interrupts = <96>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@4804c000 {
+ compatible = "ti,omap4-gpio";
+ ti,hwmods = "gpio2";
+ ti,gpio-always-on;
+ reg = <0x4804c000 0x1000>;
+ interrupts = <98>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpmc: gpmc@50000000 {
+ compatible = "ti,am3352-gpmc";
+ ti,hwmods = "gpmc";
+ reg = <0x50000000 0x2000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ interrupts = <100>;
+ gpmc,num-cs = <6>;
+ gpmc,num-waitpins = <2>;
+ };
+
+ i2c1: i2c@48028000 {
+ compatible = "ti,omap4-i2c";
+ ti,hwmods = "i2c1";
+ reg = <0x48028000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <70>;
+ dmas = <&edma 58 &edma 59>;
+ dma-names = "tx", "rx";
+ };
+
+ i2c2: i2c@4802a000 {
+ compatible = "ti,omap4-i2c";
+ ti,hwmods = "i2c2";
+ reg = <0x4802a000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <71>;
+ dmas = <&edma 60 &edma 61>;
+ dma-names = "tx", "rx";
+ };
+
+ intc: interrupt-controller@48200000 {
+ compatible = "ti,dm816-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x48200000 0x1000>;
+ };
+
+ mailbox: mailbox@480c8000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x480c8000 0x2000>;
+ interrupts = <77>;
+ ti,hwmods = "mailbox";
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <12>;
+ mbox_dsp: mbox_dsp {
+ ti,mbox-tx = <3 0 0>;
+ ti,mbox-rx = <0 0 0>;
+ };
+ };
+
+ mdio: mdio@4a100800 {
+ compatible = "ti,davinci_mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x4a100800 0x100>;
+ ti,hwmods = "davinci_mdio";
+ bus_freq = <1000000>;
+ phy0: ethernet-phy@0 {
+ reg = <1>;
+ };
+ phy1: ethernet-phy@1 {
+ reg = <2>;
+ };
+ };
+
+ eth0: ethernet@4a100000 {
+ compatible = "ti,dm816-emac";
+ ti,hwmods = "emac0";
+ reg = <0x4a100000 0x800
+ 0x4a100900 0x3700>;
+ clocks = <&sysclk24_ck>;
+ syscon = <&scm_conf>;
+ ti,davinci-ctrl-reg-offset = <0>;
+ ti,davinci-ctrl-mod-reg-offset = <0x900>;
+ ti,davinci-ctrl-ram-offset = <0x2000>;
+ ti,davinci-ctrl-ram-size = <0x2000>;
+ interrupts = <40 41 42 43>;
+ phy-handle = <&phy0>;
+ };
+
+ eth1: ethernet@4a120000 {
+ compatible = "ti,dm816-emac";
+ ti,hwmods = "emac1";
+ reg = <0x4a120000 0x4000>;
+ clocks = <&sysclk24_ck>;
+ syscon = <&scm_conf>;
+ ti,davinci-ctrl-reg-offset = <0>;
+ ti,davinci-ctrl-mod-reg-offset = <0x900>;
+ ti,davinci-ctrl-ram-offset = <0x2000>;
+ ti,davinci-ctrl-ram-size = <0x2000>;
+ interrupts = <44 45 46 47>;
+ phy-handle = <&phy1>;
+ };
+
+ mcspi1: spi@48030000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x48030000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <65>;
+ ti,spi-num-cs = <4>;
+ ti,hwmods = "mcspi1";
+ dmas = <&edma 16 &edma 17
+ &edma 18 &edma 19>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
+ };
+
+ mmc1: mmc@48060000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x48060000 0x11000>;
+ ti,hwmods = "mmc1";
+ interrupts = <64>;
+ dmas = <&edma 24 &edma 25>;
+ dma-names = "tx", "rx";
+ };
+
+ timer1: timer@4802e000 {
+ compatible = "ti,dm816-timer";
+ reg = <0x4802e000 0x2000>;
+ interrupts = <67>;
+ ti,hwmods = "timer1";
+ ti,timer-alwon;
+ };
+
+ timer2: timer@48040000 {
+ compatible = "ti,dm816-timer";
+ reg = <0x48040000 0x2000>;
+ interrupts = <68>;
+ ti,hwmods = "timer2";
+ };
+
+ timer3: timer@48042000 {
+ compatible = "ti,dm816-timer";
+ reg = <0x48042000 0x2000>;
+ interrupts = <69>;
+ ti,hwmods = "timer3";
+ };
+
+ timer4: timer@48044000 {
+ compatible = "ti,dm816-timer";
+ reg = <0x48044000 0x2000>;
+ interrupts = <92>;
+ ti,hwmods = "timer4";
+ };
+
+ timer5: timer@48046000 {
+ compatible = "ti,dm816-timer";
+ reg = <0x48046000 0x2000>;
+ interrupts = <93>;
+ ti,hwmods = "timer5";
+ };
+
+ timer6: timer@48048000 {
+ compatible = "ti,dm816-timer";
+ reg = <0x48048000 0x2000>;
+ interrupts = <94>;
+ ti,hwmods = "timer6";
+ };
+
+ timer7: timer@4804a000 {
+ compatible = "ti,dm816-timer";
+ reg = <0x4804a000 0x2000>;
+ interrupts = <95>;
+ ti,hwmods = "timer7";
+ };
+
+ uart1: uart@48020000 {
+ compatible = "ti,omap3-uart";
+ ti,hwmods = "uart1";
+ reg = <0x48020000 0x2000>;
+ clock-frequency = <48000000>;
+ interrupts = <72>;
+ dmas = <&edma 26 &edma 27>;
+ dma-names = "tx", "rx";
+ };
+
+ uart2: uart@48022000 {
+ compatible = "ti,omap3-uart";
+ ti,hwmods = "uart2";
+ reg = <0x48022000 0x2000>;
+ clock-frequency = <48000000>;
+ interrupts = <73>;
+ dmas = <&edma 28 &edma 29>;
+ dma-names = "tx", "rx";
+ };
+
+ uart3: uart@48024000 {
+ compatible = "ti,omap3-uart";
+ ti,hwmods = "uart3";
+ reg = <0x48024000 0x2000>;
+ clock-frequency = <48000000>;
+ interrupts = <74>;
+ dmas = <&edma 30 &edma 31>;
+ dma-names = "tx", "rx";
+ };
+
+ /* NOTE: USB needs a transceiver driver for phys to work */
+ usb: usb_otg_hs@47401000 {
+ compatible = "ti,am33xx-usb";
+ reg = <0x47401000 0x400000>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ti,hwmods = "usb_otg_hs";
+
+ usb0: usb@47401000 {
+ compatible = "ti,musb-dm816";
+ reg = <0x47401400 0x400
+ 0x47401000 0x200>;
+ reg-names = "mc", "control";
+ interrupts = <18>;
+ interrupt-names = "mc";
+ dr_mode = "host";
+ interface-type = <0>;
+ phys = <&usb_phy0>;
+ phy-names = "usb2-phy";
+ mentor,multipoint = <1>;
+ mentor,num-eps = <16>;
+ mentor,ram-bits = <12>;
+ mentor,power = <500>;
+
+ dmas = <&cppi41dma 0 0 &cppi41dma 1 0
+ &cppi41dma 2 0 &cppi41dma 3 0
+ &cppi41dma 4 0 &cppi41dma 5 0
+ &cppi41dma 6 0 &cppi41dma 7 0
+ &cppi41dma 8 0 &cppi41dma 9 0
+ &cppi41dma 10 0 &cppi41dma 11 0
+ &cppi41dma 12 0 &cppi41dma 13 0
+ &cppi41dma 14 0 &cppi41dma 0 1
+ &cppi41dma 1 1 &cppi41dma 2 1
+ &cppi41dma 3 1 &cppi41dma 4 1
+ &cppi41dma 5 1 &cppi41dma 6 1
+ &cppi41dma 7 1 &cppi41dma 8 1
+ &cppi41dma 9 1 &cppi41dma 10 1
+ &cppi41dma 11 1 &cppi41dma 12 1
+ &cppi41dma 13 1 &cppi41dma 14 1>;
+ dma-names =
+ "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7",
+ "rx8", "rx9", "rx10", "rx11", "rx12", "rx13",
+ "rx14", "rx15",
+ "tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7",
+ "tx8", "tx9", "tx10", "tx11", "tx12", "tx13",
+ "tx14", "tx15";
+ };
+
+ usb1: usb@47401800 {
+ compatible = "ti,musb-dm816";
+ reg = <0x47401c00 0x400
+ 0x47401800 0x200>;
+ reg-names = "mc", "control";
+ interrupts = <19>;
+ interrupt-names = "mc";
+ dr_mode = "host";
+ interface-type = <0>;
+ phys = <&usb_phy1>;
+ phy-names = "usb2-phy";
+ mentor,multipoint = <1>;
+ mentor,num-eps = <16>;
+ mentor,ram-bits = <12>;
+ mentor,power = <500>;
+
+ dmas = <&cppi41dma 15 0 &cppi41dma 16 0
+ &cppi41dma 17 0 &cppi41dma 18 0
+ &cppi41dma 19 0 &cppi41dma 20 0
+ &cppi41dma 21 0 &cppi41dma 22 0
+ &cppi41dma 23 0 &cppi41dma 24 0
+ &cppi41dma 25 0 &cppi41dma 26 0
+ &cppi41dma 27 0 &cppi41dma 28 0
+ &cppi41dma 29 0 &cppi41dma 15 1
+ &cppi41dma 16 1 &cppi41dma 17 1
+ &cppi41dma 18 1 &cppi41dma 19 1
+ &cppi41dma 20 1 &cppi41dma 21 1
+ &cppi41dma 22 1 &cppi41dma 23 1
+ &cppi41dma 24 1 &cppi41dma 25 1
+ &cppi41dma 26 1 &cppi41dma 27 1
+ &cppi41dma 28 1 &cppi41dma 29 1>;
+ dma-names =
+ "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7",
+ "rx8", "rx9", "rx10", "rx11", "rx12", "rx13",
+ "rx14", "rx15",
+ "tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7",
+ "tx8", "tx9", "tx10", "tx11", "tx12", "tx13",
+ "tx14", "tx15";
+ };
+
+ cppi41dma: dma-controller@47402000 {
+ compatible = "ti,am3359-cppi41";
+ reg = <0x47400000 0x1000
+ 0x47402000 0x1000
+ 0x47403000 0x1000
+ 0x47404000 0x4000>;
+ reg-names = "glue", "controller", "scheduler", "queuemgr";
+ interrupts = <17>;
+ interrupt-names = "glue";
+ #dma-cells = <2>;
+ #dma-channels = <30>;
+ #dma-requests = <256>;
+ };
+ };
+
+ wd_timer2: wd_timer@480c2000 {
+ compatible = "ti,omap3-wdt";
+ ti,hwmods = "wd_timer";
+ reg = <0x480c2000 0x1000>;
+ interrupts = <0>;
+ };
+ };
+};
+
+#include "dm816x-clocks.dtsi"
diff --git a/arch/arm/boot/dts/dove-cm-a510.dts b/arch/arm/boot/dts/dove-cm-a510.dts
new file mode 100644
index 000000000..50c0d6904
--- /dev/null
+++ b/arch/arm/boot/dts/dove-cm-a510.dts
@@ -0,0 +1,38 @@
+/dts-v1/;
+
+#include "dove.dtsi"
+
+/ {
+ model = "Compulab CM-A510";
+ compatible = "compulab,cm-a510", "marvell,dove";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ };
+};
+
+&uart0 { status = "okay"; };
+&uart1 { status = "okay"; };
+&sdio0 { status = "okay"; };
+&sdio1 { status = "okay"; };
+&sata0 { status = "okay"; };
+
+&spi0 {
+ status = "okay";
+
+ /* spi0.0: 4M Flash Winbond W25Q32BV */
+ spi-flash@0 {
+ compatible = "st,w25q32";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/dove-cubox-es.dts b/arch/arm/boot/dts/dove-cubox-es.dts
new file mode 100644
index 000000000..e28ef056d
--- /dev/null
+++ b/arch/arm/boot/dts/dove-cubox-es.dts
@@ -0,0 +1,12 @@
+#include "dove-cubox.dts"
+
+/ {
+ model = "SolidRun CuBox (Engineering Sample)";
+ compatible = "solidrun,cubox-es", "solidrun,cubox", "marvell,dove";
+};
+
+&sdio0 {
+ /* sdio0 card detect is connected to wrong pin on CuBox ES */
+ cd-gpios = <&gpio0 12 1>;
+ pinctrl-0 = <&pmx_sdio0 &pmx_gpio_12>;
+};
diff --git a/arch/arm/boot/dts/dove-cubox.dts b/arch/arm/boot/dts/dove-cubox.dts
new file mode 100644
index 000000000..e6fa251e1
--- /dev/null
+++ b/arch/arm/boot/dts/dove-cubox.dts
@@ -0,0 +1,134 @@
+/dts-v1/;
+
+#include "dove.dtsi"
+
+/ {
+ model = "SolidRun CuBox";
+ compatible = "solidrun,cubox", "marvell,dove";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_gpio_18>;
+ pinctrl-names = "default";
+
+ power {
+ label = "Power";
+ gpios = <&gpio0 18 1>;
+ default-state = "keep";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb_power: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "USB Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 1 0>;
+ pinctrl-0 = <&pmx_gpio_1>;
+ pinctrl-names = "default";
+ };
+ };
+
+ clocks {
+ /* 25MHz reference crystal */
+ ref25: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+ };
+
+ ir_recv: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio0 19 1>;
+ pinctrl-0 = <&pmx_gpio_19>;
+ pinctrl-names = "default";
+ };
+};
+
+&uart0 { status = "okay"; };
+&sata0 { status = "okay"; };
+&mdio { status = "okay"; };
+&eth { status = "okay"; };
+
+&ethphy {
+ compatible = "marvell,88e1310";
+ reg = <1>;
+};
+
+&i2c0 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ si5351: clock-generator {
+ compatible = "silabs,si5351a-msop";
+ reg = <0x60>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <1>;
+
+ /* connect xtal input to 25MHz reference */
+ clocks = <&ref25>;
+ clock-names = "xtal";
+
+ /* connect xtal input as source of pll0 and pll1 */
+ silabs,pll-source = <0 0>, <1 0>;
+
+ clkout0 {
+ reg = <0>;
+ silabs,drive-strength = <8>;
+ silabs,multisynth-source = <0>;
+ silabs,clock-source = <0>;
+ silabs,pll-master;
+ };
+
+ clkout2 {
+ reg = <2>;
+ silabs,drive-strength = <8>;
+ silabs,multisynth-source = <1>;
+ silabs,clock-source = <0>;
+ silabs,pll-master;
+ };
+ };
+};
+
+&sdio0 {
+ status = "okay";
+};
+
+&spi0 {
+ status = "okay";
+
+ /* spi0.0: 4M Flash Winbond W25Q32BV */
+ spi-flash@0 {
+ compatible = "st,w25q32";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&audio1 {
+ status = "okay";
+ clocks = <&gate_clk 13>, <&si5351 2>;
+ clock-names = "internal", "extclk";
+ pinctrl-0 = <&pmx_audio1_i2s1_spdifo &pmx_audio1_extclk>;
+ pinctrl-names = "default";
+};
diff --git a/arch/arm/boot/dts/dove-d2plug.dts b/arch/arm/boot/dts/dove-d2plug.dts
new file mode 100644
index 000000000..c11d3636c
--- /dev/null
+++ b/arch/arm/boot/dts/dove-d2plug.dts
@@ -0,0 +1,69 @@
+/dts-v1/;
+
+#include "dove.dtsi"
+
+/ {
+ model = "Globalscale D2Plug";
+ compatible = "globalscale,d2plug", "marvell,dove";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_gpio_0 &pmx_gpio_1 &pmx_gpio_2>;
+ pinctrl-names = "default";
+
+ wlan-ap {
+ label = "wlan-ap";
+ gpios = <&gpio0 0 1>;
+ };
+
+ wlan-act {
+ label = "wlan-act";
+ gpios = <&gpio0 1 1>;
+ };
+
+ bluetooth-act {
+ label = "bt-act";
+ gpios = <&gpio0 2 1>;
+ };
+ };
+};
+
+&uart0 { status = "okay"; };
+&sata0 { status = "okay"; };
+&i2c0 { status = "okay"; };
+&mdio { status = "okay"; };
+&eth { status = "okay"; };
+
+/* Samsung M8G2F eMMC */
+&sdio0 {
+ status = "okay";
+ non-removable;
+ bus-width = <4>;
+};
+
+/* Marvell SD8787 WLAN/BT */
+&sdio1 {
+ status = "okay";
+ non-removable;
+ bus-width = <4>;
+};
+
+&spi0 {
+ status = "okay";
+
+ /* spi0.0: 4M Flash Macronix MX25L3205D */
+ spi-flash@0 {
+ compatible = "st,m25l3205d";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/dove-d3plug.dts b/arch/arm/boot/dts/dove-d3plug.dts
new file mode 100644
index 000000000..f5f59bb5a
--- /dev/null
+++ b/arch/arm/boot/dts/dove-d3plug.dts
@@ -0,0 +1,103 @@
+/dts-v1/;
+
+#include "dove.dtsi"
+
+/ {
+ model = "Globalscale D3Plug";
+ compatible = "globalscale,d3plug", "marvell,dove";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk root=/dev/mmcblk0p2 rw rootwait";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_gpio_0 &pmx_gpio_1 &pmx_gpio_2>;
+ pinctrl-names = "default";
+
+ wlan-act {
+ label = "wlan-act";
+ gpios = <&gpio0 0 1>;
+ };
+
+ wlan-ap {
+ label = "wlan-ap";
+ gpios = <&gpio0 1 1>;
+ };
+
+ status {
+ label = "status";
+ gpios = <&gpio0 2 1>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb_power: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "USB Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 8 0>;
+ pinctrl-0 = <&pmx_gpio_8>;
+ pinctrl-names = "default";
+ };
+ };
+};
+
+&uart0 { status = "okay"; };
+&sata0 { status = "okay"; };
+&i2c0 { status = "okay"; };
+
+/* Samsung M8G2F eMMC */
+&sdio0 {
+ status = "okay";
+ non-removable;
+ bus-width = <4>;
+};
+
+/* Marvell SD8787 WLAN/BT */
+&sdio1 {
+ status = "okay";
+ non-removable;
+};
+
+&spi0 {
+ status = "okay";
+
+ /* spi0.0: 2M Flash Macronix MX25L1605D */
+ spi-flash@0 {
+ compatible = "st,m25l1605d";
+ spi-max-frequency = <86000000>;
+ reg = <0>;
+ };
+};
+
+&pcie {
+ status = "okay";
+ /* Fresco Logic USB3.0 xHCI controller */
+ pcie-port@0 {
+ status = "okay";
+ reset-gpios = <&gpio0 26 1>;
+ reset-delay-us = <20000>;
+ pinctrl-0 = <&pmx_camera_gpio>;
+ pinctrl-names = "default";
+ };
+ /* Mini-PCIe slot */
+ pcie-port@1 {
+ status = "okay";
+ reset-gpios = <&gpio0 25 1>;
+ };
+};
diff --git a/arch/arm/boot/dts/dove-dove-db.dts b/arch/arm/boot/dts/dove-dove-db.dts
new file mode 100644
index 000000000..bb725dca3
--- /dev/null
+++ b/arch/arm/boot/dts/dove-dove-db.dts
@@ -0,0 +1,38 @@
+/dts-v1/;
+
+#include "dove.dtsi"
+
+/ {
+ model = "Marvell DB-MV88AP510-BP Development Board";
+ compatible = "marvell,dove-db", "marvell,dove";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ };
+};
+
+&uart0 { status = "okay"; };
+&uart1 { status = "okay"; };
+&sdio0 { status = "okay"; };
+&sdio1 { status = "okay"; };
+&sata0 { status = "okay"; };
+
+&spi0 {
+ status = "okay";
+
+ /* spi0.0: 4M Flash ST-M25P32-VMF6P */
+ spi-flash@0 {
+ compatible = "st,m25p32";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi
new file mode 100644
index 000000000..9ad829523
--- /dev/null
+++ b/arch/arm/boot/dts/dove.dtsi
@@ -0,0 +1,704 @@
+/include/ "skeleton.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
+
+/ {
+ compatible = "marvell,dove";
+ model = "Marvell Armada 88AP510 SoC";
+ interrupt-parent = <&intc>;
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "marvell,pj4a", "marvell,sheeva-v7";
+ device_type = "cpu";
+ next-level-cache = <&l2>;
+ reg = <0>;
+ };
+ };
+
+ l2: l2-cache {
+ compatible = "marvell,tauros2-cache";
+ marvell,tauros2-cache-features = <0>;
+ };
+
+ mbus {
+ compatible = "marvell,dove-mbus", "marvell,mbus", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ controller = <&mbusc>;
+ pcie-mem-aperture = <0xe0000000 0x10000000>; /* 256M MEM space */
+ pcie-io-aperture = <0xf2000000 0x00200000>; /* 2M I/O space */
+
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x0100000 /* MBUS regs 1M */
+ MBUS_ID(0xf0, 0x02) 0 0xf1800000 0x1000000 /* AXI regs 16M */
+ MBUS_ID(0x01, 0xfd) 0 0xf8000000 0x8000000 /* BootROM 128M */
+ MBUS_ID(0x03, 0x01) 0 0xc8000000 0x0100000 /* CESA SRAM 1M */
+ MBUS_ID(0x0d, 0x00) 0 0xf0000000 0x0100000>; /* PMU SRAM 1M */
+
+ pcie: pcie-controller {
+ compatible = "marvell,dove-pcie";
+ status = "disabled";
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ msi-parent = <&intc>;
+ bus-range = <0x00 0xff>;
+
+ ranges = <0x82000000 0x0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x2000
+ 0x82000000 0x0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x2000
+ 0x82000000 0x1 0x0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 Mem */
+ 0x81000000 0x1 0x0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 I/O */
+ 0x82000000 0x2 0x0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 Mem */
+ 0x81000000 0x2 0x0 MBUS_ID(0x08, 0xe0) 0 1 0>; /* Port 1.0 I/O */
+
+ pcie0: pcie-port@0 {
+ device_type = "pci";
+ status = "disabled";
+ assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ clocks = <&gate_clk 4>;
+ marvell,pcie-port = <0>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &intc 16>;
+ };
+
+ pcie1: pcie-port@1 {
+ device_type = "pci";
+ status = "disabled";
+ assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ clocks = <&gate_clk 5>;
+ marvell,pcie-port = <1>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+ 0x81000000 0 0 0x81000000 0x2 0 1 0>;
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &intc 18>;
+ };
+ };
+
+ internal-regs {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x00000000 MBUS_ID(0xf0, 0x01) 0 0x0100000 /* MBUS regs 1M */
+ 0x00800000 MBUS_ID(0xf0, 0x02) 0 0x1000000 /* AXI regs 16M */
+ 0xffffe000 MBUS_ID(0x03, 0x01) 0 0x0000800 /* CESA SRAM 2k */
+ 0xfffff000 MBUS_ID(0x0d, 0x00) 0 0x0000800>; /* PMU SRAM 2k */
+
+ spi0: spi-ctrl@10600 {
+ compatible = "marvell,orion-spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ interrupts = <6>;
+ reg = <0x10600 0x28>;
+ clocks = <&core_clk 0>;
+ pinctrl-0 = <&pmx_spi0>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ i2c0: i2c-ctrl@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <11>;
+ clock-frequency = <400000>;
+ timeout-ms = <1000>;
+ clocks = <&core_clk 0>;
+ status = "disabled";
+ };
+
+ uart0: serial@12000 {
+ compatible = "ns16550a";
+ reg = <0x12000 0x100>;
+ reg-shift = <2>;
+ interrupts = <7>;
+ clocks = <&core_clk 0>;
+ status = "disabled";
+ };
+
+ uart1: serial@12100 {
+ compatible = "ns16550a";
+ reg = <0x12100 0x100>;
+ reg-shift = <2>;
+ interrupts = <8>;
+ clocks = <&core_clk 0>;
+ pinctrl-0 = <&pmx_uart1>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ uart2: serial@12200 {
+ compatible = "ns16550a";
+ reg = <0x12200 0x100>;
+ reg-shift = <2>;
+ interrupts = <9>;
+ clocks = <&core_clk 0>;
+ status = "disabled";
+ };
+
+ uart3: serial@12300 {
+ compatible = "ns16550a";
+ reg = <0x12300 0x100>;
+ reg-shift = <2>;
+ interrupts = <10>;
+ clocks = <&core_clk 0>;
+ status = "disabled";
+ };
+
+ spi1: spi-ctrl@14600 {
+ compatible = "marvell,orion-spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ interrupts = <5>;
+ reg = <0x14600 0x28>;
+ clocks = <&core_clk 0>;
+ status = "disabled";
+ };
+
+ mbusc: mbus-ctrl@20000 {
+ compatible = "marvell,mbus-controller";
+ reg = <0x20000 0x80>, <0x800100 0x8>;
+ };
+
+ sysc: system-ctrl@20000 {
+ compatible = "marvell,orion-system-controller";
+ reg = <0x20000 0x110>;
+ };
+
+ bridge_intc: bridge-interrupt-ctrl@20110 {
+ compatible = "marvell,orion-bridge-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x20110 0x8>;
+ interrupts = <0>;
+ marvell,#interrupts = <5>;
+ };
+
+ intc: main-interrupt-ctrl@20200 {
+ compatible = "marvell,orion-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x20200 0x10>, <0x20210 0x10>;
+ };
+
+ timer: timer@20300 {
+ compatible = "marvell,orion-timer";
+ reg = <0x20300 0x20>;
+ interrupt-parent = <&bridge_intc>;
+ interrupts = <1>, <2>;
+ clocks = <&core_clk 0>;
+ };
+
+ watchdog@20300 {
+ compatible = "marvell,orion-wdt";
+ reg = <0x20300 0x28>, <0x20108 0x4>;
+ interrupt-parent = <&bridge_intc>;
+ interrupts = <3>;
+ clocks = <&core_clk 0>;
+ };
+
+ crypto: crypto-engine@30000 {
+ compatible = "marvell,orion-crypto";
+ reg = <0x30000 0x10000>,
+ <0xffffe000 0x800>;
+ reg-names = "regs", "sram";
+ interrupts = <31>;
+ clocks = <&gate_clk 15>;
+ status = "okay";
+ };
+
+ ehci0: usb-host@50000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <24>;
+ clocks = <&gate_clk 0>;
+ status = "okay";
+ };
+
+ ehci1: usb-host@51000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x51000 0x1000>;
+ interrupts = <25>;
+ clocks = <&gate_clk 1>;
+ status = "okay";
+ };
+
+ xor0: dma-engine@60800 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60800 0x100
+ 0x60a00 0x100>;
+ clocks = <&gate_clk 23>;
+ status = "okay";
+
+ channel0 {
+ interrupts = <39>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+
+ channel1 {
+ interrupts = <40>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ };
+
+ xor1: dma-engine@60900 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60900 0x100
+ 0x60b00 0x100>;
+ clocks = <&gate_clk 24>;
+ status = "okay";
+
+ channel0 {
+ interrupts = <42>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+
+ channel1 {
+ interrupts = <43>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ };
+
+ sdio1: sdio-host@90000 {
+ compatible = "marvell,dove-sdhci";
+ reg = <0x90000 0x100>;
+ interrupts = <36>, <38>;
+ clocks = <&gate_clk 9>;
+ pinctrl-0 = <&pmx_sdio1>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ eth: ethernet-ctrl@72000 {
+ compatible = "marvell,orion-eth";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x72000 0x4000>;
+ clocks = <&gate_clk 2>;
+ marvell,tx-checksum-limit = <1600>;
+ status = "disabled";
+
+ ethernet-port@0 {
+ compatible = "marvell,orion-eth-port";
+ reg = <0>;
+ interrupts = <29>;
+ /* overwrite MAC address in bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ phy-handle = <&ethphy>;
+ };
+ };
+
+ mdio: mdio-bus@72004 {
+ compatible = "marvell,orion-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x72004 0x84>;
+ interrupts = <30>;
+ clocks = <&gate_clk 2>;
+ status = "disabled";
+
+ ethphy: ethernet-phy {
+ /* set phy address in board file */
+ };
+ };
+
+ sdio0: sdio-host@92000 {
+ compatible = "marvell,dove-sdhci";
+ reg = <0x92000 0x100>;
+ interrupts = <35>, <37>;
+ clocks = <&gate_clk 8>;
+ pinctrl-0 = <&pmx_sdio0>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ sata0: sata-host@a0000 {
+ compatible = "marvell,orion-sata";
+ reg = <0xa0000 0x2400>;
+ interrupts = <62>;
+ clocks = <&gate_clk 3>;
+ phys = <&sata_phy0>;
+ phy-names = "port0";
+ nr-ports = <1>;
+ status = "disabled";
+ };
+
+ sata_phy0: sata-phy@a2000 {
+ compatible = "marvell,mvebu-sata-phy";
+ reg = <0xa2000 0x0334>;
+ clocks = <&gate_clk 3>;
+ clock-names = "sata";
+ #phy-cells = <0>;
+ status = "ok";
+ };
+
+ audio0: audio-controller@b0000 {
+ compatible = "marvell,dove-audio";
+ reg = <0xb0000 0x2210>;
+ interrupts = <19>, <20>;
+ clocks = <&gate_clk 12>;
+ clock-names = "internal";
+ status = "disabled";
+ };
+
+ audio1: audio-controller@b4000 {
+ compatible = "marvell,dove-audio";
+ reg = <0xb4000 0x2210>;
+ interrupts = <21>, <22>;
+ clocks = <&gate_clk 13>;
+ clock-names = "internal";
+ status = "disabled";
+ };
+
+ thermal: thermal-diode@d001c {
+ compatible = "marvell,dove-thermal";
+ reg = <0xd001c 0x0c>, <0xd005c 0x08>;
+ };
+
+ gate_clk: clock-gating-ctrl@d0038 {
+ compatible = "marvell,dove-gating-clock";
+ reg = <0xd0038 0x4>;
+ clocks = <&core_clk 0>;
+ #clock-cells = <1>;
+ };
+
+ pinctrl: pin-ctrl@d0200 {
+ compatible = "marvell,dove-pinctrl";
+ reg = <0xd0200 0x14>,
+ <0xd0440 0x04>;
+ clocks = <&gate_clk 22>;
+
+ pmx_gpio_0: pmx-gpio-0 {
+ marvell,pins = "mpp0";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_1: pmx-gpio-1 {
+ marvell,pins = "mpp1";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_2: pmx-gpio-2 {
+ marvell,pins = "mpp2";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_3: pmx-gpio-3 {
+ marvell,pins = "mpp3";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_4: pmx-gpio-4 {
+ marvell,pins = "mpp4";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_5: pmx-gpio-5 {
+ marvell,pins = "mpp5";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_6: pmx-gpio-6 {
+ marvell,pins = "mpp6";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_7: pmx-gpio-7 {
+ marvell,pins = "mpp7";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_8: pmx-gpio-8 {
+ marvell,pins = "mpp8";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_9: pmx-gpio-9 {
+ marvell,pins = "mpp9";
+ marvell,function = "gpio";
+ };
+
+ pmx_pcie1_clkreq: pmx-pcie1-clkreq {
+ marvell,pins = "mpp9";
+ marvell,function = "pex1";
+ };
+
+ pmx_gpio_10: pmx-gpio-10 {
+ marvell,pins = "mpp10";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_11: pmx-gpio-11 {
+ marvell,pins = "mpp11";
+ marvell,function = "gpio";
+ };
+
+ pmx_pcie0_clkreq: pmx-pcie0-clkreq {
+ marvell,pins = "mpp11";
+ marvell,function = "pex0";
+ };
+
+ pmx_gpio_12: pmx-gpio-12 {
+ marvell,pins = "mpp12";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_13: pmx-gpio-13 {
+ marvell,pins = "mpp13";
+ marvell,function = "gpio";
+ };
+
+ pmx_audio1_extclk: pmx-audio1-extclk {
+ marvell,pins = "mpp13";
+ marvell,function = "audio1";
+ };
+
+ pmx_gpio_14: pmx-gpio-14 {
+ marvell,pins = "mpp14";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_15: pmx-gpio-15 {
+ marvell,pins = "mpp15";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_16: pmx-gpio-16 {
+ marvell,pins = "mpp16";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_17: pmx-gpio-17 {
+ marvell,pins = "mpp17";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_18: pmx-gpio-18 {
+ marvell,pins = "mpp18";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_19: pmx-gpio-19 {
+ marvell,pins = "mpp19";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_20: pmx-gpio-20 {
+ marvell,pins = "mpp20";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_21: pmx-gpio-21 {
+ marvell,pins = "mpp21";
+ marvell,function = "gpio";
+ };
+
+ pmx_camera: pmx-camera {
+ marvell,pins = "mpp_camera";
+ marvell,function = "camera";
+ };
+
+ pmx_camera_gpio: pmx-camera-gpio {
+ marvell,pins = "mpp_camera";
+ marvell,function = "gpio";
+ };
+
+ pmx_sdio0: pmx-sdio0 {
+ marvell,pins = "mpp_sdio0";
+ marvell,function = "sdio0";
+ };
+
+ pmx_sdio0_gpio: pmx-sdio0-gpio {
+ marvell,pins = "mpp_sdio0";
+ marvell,function = "gpio";
+ };
+
+ pmx_sdio1: pmx-sdio1 {
+ marvell,pins = "mpp_sdio1";
+ marvell,function = "sdio1";
+ };
+
+ pmx_sdio1_gpio: pmx-sdio1-gpio {
+ marvell,pins = "mpp_sdio1";
+ marvell,function = "gpio";
+ };
+
+ pmx_audio1_gpio: pmx-audio1-gpio {
+ marvell,pins = "mpp_audio1";
+ marvell,function = "gpio";
+ };
+
+ pmx_audio1_i2s1_spdifo: pmx-audio1-i2s1-spdifo {
+ marvell,pins = "mpp_audio1";
+ marvell,function = "i2s1/spdifo";
+ };
+
+ pmx_spi0: pmx-spi0 {
+ marvell,pins = "mpp_spi0";
+ marvell,function = "spi0";
+ };
+
+ pmx_spi0_gpio: pmx-spi0-gpio {
+ marvell,pins = "mpp_spi0";
+ marvell,function = "gpio";
+ };
+
+ pmx_spi1_4_7: pmx-spi1-4-7 {
+ marvell,pins = "mpp4", "mpp5",
+ "mpp6", "mpp7";
+ marvell,function = "spi1";
+ };
+
+ pmx_spi1_20_23: pmx-spi1-20-23 {
+ marvell,pins = "mpp20", "mpp21",
+ "mpp22", "mpp23";
+ marvell,function = "spi1";
+ };
+
+ pmx_uart1: pmx-uart1 {
+ marvell,pins = "mpp_uart1";
+ marvell,function = "uart1";
+ };
+
+ pmx_uart1_gpio: pmx-uart1-gpio {
+ marvell,pins = "mpp_uart1";
+ marvell,function = "gpio";
+ };
+
+ pmx_nand: pmx-nand {
+ marvell,pins = "mpp_nand";
+ marvell,function = "nand";
+ };
+
+ pmx_nand_gpo: pmx-nand-gpo {
+ marvell,pins = "mpp_nand";
+ marvell,function = "gpo";
+ };
+
+ pmx_i2c1: pmx-i2c1 {
+ marvell,pins = "mpp17", "mpp19";
+ marvell,function = "twsi";
+ };
+
+ pmx_i2c2: pmx-i2c2 {
+ marvell,pins = "mpp_audio1";
+ marvell,function = "twsi";
+ };
+
+ pmx_ssp_i2c2: pmx-ssp-i2c2 {
+ marvell,pins = "mpp_audio1";
+ marvell,function = "ssp/twsi";
+ };
+
+ pmx_i2cmux_0: pmx-i2cmux-0 {
+ marvell,pins = "twsi";
+ marvell,function = "twsi-opt1";
+ };
+
+ pmx_i2cmux_1: pmx-i2cmux-1 {
+ marvell,pins = "twsi";
+ marvell,function = "twsi-opt2";
+ };
+
+ pmx_i2cmux_2: pmx-i2cmux-2 {
+ marvell,pins = "twsi";
+ marvell,function = "twsi-opt3";
+ };
+ };
+
+ core_clk: core-clocks@d0214 {
+ compatible = "marvell,dove-core-clock";
+ reg = <0xd0214 0x4>;
+ #clock-cells = <1>;
+ };
+
+ gpio0: gpio-ctrl@d0400 {
+ compatible = "marvell,orion-gpio";
+ #gpio-cells = <2>;
+ gpio-controller;
+ reg = <0xd0400 0x20>;
+ ngpios = <32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <12>, <13>, <14>, <60>;
+ };
+
+ gpio1: gpio-ctrl@d0420 {
+ compatible = "marvell,orion-gpio";
+ #gpio-cells = <2>;
+ gpio-controller;
+ reg = <0xd0420 0x20>;
+ ngpios = <32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <61>;
+ };
+
+ rtc: real-time-clock@d8500 {
+ compatible = "marvell,orion-rtc";
+ reg = <0xd8500 0x20>;
+ };
+
+ gconf: global-config@e802c {
+ compatible = "marvell,dove-global-config",
+ "syscon";
+ reg = <0xe802c 0x14>;
+ };
+
+ gpio2: gpio-ctrl@e8400 {
+ compatible = "marvell,orion-gpio";
+ #gpio-cells = <2>;
+ gpio-controller;
+ reg = <0xe8400 0x0c>;
+ ngpios = <8>;
+ };
+
+ lcd1: lcd-controller@810000 {
+ compatible = "marvell,dove-lcd";
+ reg = <0x810000 0x1000>;
+ interrupts = <46>;
+ status = "disabled";
+ };
+
+ lcd0: lcd-controller@820000 {
+ compatible = "marvell,dove-lcd";
+ reg = <0x820000 0x1000>;
+ interrupts = <47>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
new file mode 100644
index 000000000..aa465904f
--- /dev/null
+++ b/arch/arm/boot/dts/dra7-evm.dts
@@ -0,0 +1,692 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+/dts-v1/;
+
+#include "dra74x.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "TI DRA742";
+ compatible = "ti,dra7-evm", "ti,dra742", "ti,dra74", "ti,dra7";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x60000000>; /* 1536 MB */
+ };
+
+ mmc2_3v3: fixedregulator-mmc2 {
+ compatible = "regulator-fixed";
+ regulator-name = "mmc2_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ extcon_usb1: extcon_usb1 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&pcf_gpio_21 1 GPIO_ACTIVE_HIGH>;
+ };
+
+ extcon_usb2: extcon_usb2 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&pcf_gpio_21 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ vtt_fixed: fixedregulator-vtt {
+ compatible = "regulator-fixed";
+ regulator-name = "vtt_fixed";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&gpio7 11 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&dra7_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <&vtt_pin>;
+
+ vtt_pin: pinmux_vtt_pin {
+ pinctrl-single,pins = <
+ 0x3b4 (PIN_OUTPUT | MUX_MODE14) /* spi1_cs1.gpio7_11 */
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ 0x400 (PIN_INPUT | MUX_MODE0) /* i2c1_sda */
+ 0x404 (PIN_INPUT | MUX_MODE0) /* i2c1_scl */
+ >;
+ };
+
+ i2c2_pins: pinmux_i2c2_pins {
+ pinctrl-single,pins = <
+ 0x408 (PIN_INPUT | MUX_MODE0) /* i2c2_sda */
+ 0x40c (PIN_INPUT | MUX_MODE0) /* i2c2_scl */
+ >;
+ };
+
+ i2c3_pins: pinmux_i2c3_pins {
+ pinctrl-single,pins = <
+ 0x288 (PIN_INPUT | MUX_MODE9) /* gpio6_14.i2c3_sda */
+ 0x28c (PIN_INPUT | MUX_MODE9) /* gpio6_15.i2c3_scl */
+ >;
+ };
+
+ mcspi1_pins: pinmux_mcspi1_pins {
+ pinctrl-single,pins = <
+ 0x3a4 (PIN_INPUT | MUX_MODE0) /* spi1_sclk */
+ 0x3a8 (PIN_INPUT | MUX_MODE0) /* spi1_d1 */
+ 0x3ac (PIN_INPUT | MUX_MODE0) /* spi1_d0 */
+ 0x3b0 (PIN_INPUT_SLEW | MUX_MODE0) /* spi1_cs0 */
+ 0x3b8 (PIN_INPUT_SLEW | MUX_MODE6) /* spi1_cs2.hdmi1_hpd */
+ 0x3bc (PIN_INPUT_SLEW | MUX_MODE6) /* spi1_cs3.hdmi1_cec */
+ >;
+ };
+
+ mcspi2_pins: pinmux_mcspi2_pins {
+ pinctrl-single,pins = <
+ 0x3c0 (PIN_INPUT | MUX_MODE0) /* spi2_sclk */
+ 0x3c4 (PIN_INPUT_SLEW | MUX_MODE0) /* spi2_d1 */
+ 0x3c8 (PIN_INPUT_SLEW | MUX_MODE0) /* spi2_d1 */
+ 0x3cc (PIN_INPUT_SLEW | MUX_MODE0) /* spi2_cs0 */
+ >;
+ };
+
+ uart1_pins: pinmux_uart1_pins {
+ pinctrl-single,pins = <
+ 0x3e0 (PIN_INPUT_SLEW | MUX_MODE0) /* uart1_rxd */
+ 0x3e4 (PIN_INPUT_SLEW | MUX_MODE0) /* uart1_txd */
+ 0x3e8 (PIN_INPUT | MUX_MODE3) /* uart1_ctsn */
+ 0x3ec (PIN_INPUT | MUX_MODE3) /* uart1_rtsn */
+ >;
+ };
+
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ 0x3f0 (PIN_INPUT | MUX_MODE0) /* uart2_rxd */
+ 0x3f4 (PIN_INPUT | MUX_MODE0) /* uart2_txd */
+ 0x3f8 (PIN_INPUT | MUX_MODE0) /* uart2_ctsn */
+ 0x3fc (PIN_INPUT | MUX_MODE0) /* uart2_rtsn */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ 0x248 (PIN_INPUT_SLEW | MUX_MODE0) /* uart3_rxd */
+ 0x24c (PIN_INPUT_SLEW | MUX_MODE0) /* uart3_txd */
+ >;
+ };
+
+ qspi1_pins: pinmux_qspi1_pins {
+ pinctrl-single,pins = <
+ 0x4c (PIN_INPUT | MUX_MODE1) /* gpmc_a3.qspi1_cs2 */
+ 0x50 (PIN_INPUT | MUX_MODE1) /* gpmc_a4.qspi1_cs3 */
+ 0x74 (PIN_INPUT | MUX_MODE1) /* gpmc_a13.qspi1_rtclk */
+ 0x78 (PIN_INPUT | MUX_MODE1) /* gpmc_a14.qspi1_d3 */
+ 0x7c (PIN_INPUT | MUX_MODE1) /* gpmc_a15.qspi1_d2 */
+ 0x80 (PIN_INPUT | MUX_MODE1) /* gpmc_a16.qspi1_d1 */
+ 0x84 (PIN_INPUT | MUX_MODE1) /* gpmc_a17.qspi1_d0 */
+ 0x88 (PIN_INPUT | MUX_MODE1) /* qpmc_a18.qspi1_sclk */
+ 0xb8 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs2.qspi1_cs0 */
+ 0xbc (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs3.qspi1_cs1 */
+ >;
+ };
+
+ usb1_pins: pinmux_usb1_pins {
+ pinctrl-single,pins = <
+ 0x280 (PIN_INPUT_SLEW | MUX_MODE0) /* usb1_drvvbus */
+ >;
+ };
+
+ usb2_pins: pinmux_usb2_pins {
+ pinctrl-single,pins = <
+ 0x284 (PIN_INPUT_SLEW | MUX_MODE0) /* usb2_drvvbus */
+ >;
+ };
+
+ nand_flash_x16: nand_flash_x16 {
+ /* On DRA7 EVM, GPMC_WPN and NAND_BOOTn comes from DIP switch
+ * So NAND flash requires following switch settings:
+ * SW5.9 (GPMC_WPN) = LOW
+ * SW5.1 (NAND_BOOTn) = HIGH */
+ pinctrl-single,pins = <
+ 0x0 (PIN_INPUT | MUX_MODE0) /* gpmc_ad0 */
+ 0x4 (PIN_INPUT | MUX_MODE0) /* gpmc_ad1 */
+ 0x8 (PIN_INPUT | MUX_MODE0) /* gpmc_ad2 */
+ 0xc (PIN_INPUT | MUX_MODE0) /* gpmc_ad3 */
+ 0x10 (PIN_INPUT | MUX_MODE0) /* gpmc_ad4 */
+ 0x14 (PIN_INPUT | MUX_MODE0) /* gpmc_ad5 */
+ 0x18 (PIN_INPUT | MUX_MODE0) /* gpmc_ad6 */
+ 0x1c (PIN_INPUT | MUX_MODE0) /* gpmc_ad7 */
+ 0x20 (PIN_INPUT | MUX_MODE0) /* gpmc_ad8 */
+ 0x24 (PIN_INPUT | MUX_MODE0) /* gpmc_ad9 */
+ 0x28 (PIN_INPUT | MUX_MODE0) /* gpmc_ad10 */
+ 0x2c (PIN_INPUT | MUX_MODE0) /* gpmc_ad11 */
+ 0x30 (PIN_INPUT | MUX_MODE0) /* gpmc_ad12 */
+ 0x34 (PIN_INPUT | MUX_MODE0) /* gpmc_ad13 */
+ 0x38 (PIN_INPUT | MUX_MODE0) /* gpmc_ad14 */
+ 0x3c (PIN_INPUT | MUX_MODE0) /* gpmc_ad15 */
+ 0xd8 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0 */
+ 0xcc (PIN_OUTPUT | MUX_MODE0) /* gpmc_wen */
+ 0xb4 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_csn0 */
+ 0xc4 (PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale */
+ 0xc8 (PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren */
+ 0xd0 (PIN_OUTPUT | MUX_MODE0) /* gpmc_be0n_cle */
+ >;
+ };
+
+ cpsw_default: cpsw_default {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ 0x250 (PIN_OUTPUT | MUX_MODE0) /* rgmii0_txc.rgmii0_txc */
+ 0x254 (PIN_OUTPUT | MUX_MODE0) /* rgmii0_txctl.rgmii0_txctl */
+ 0x258 (PIN_OUTPUT | MUX_MODE0) /* rgmii0_td3.rgmii0_txd3 */
+ 0x25c (PIN_OUTPUT | MUX_MODE0) /* rgmii0_txd2.rgmii0_txd2 */
+ 0x260 (PIN_OUTPUT | MUX_MODE0) /* rgmii0_txd1.rgmii0_txd1 */
+ 0x264 (PIN_OUTPUT | MUX_MODE0) /* rgmii0_txd0.rgmii0_txd0 */
+ 0x268 (PIN_INPUT | MUX_MODE0) /* rgmii0_rxc.rgmii0_rxc */
+ 0x26c (PIN_INPUT | MUX_MODE0) /* rgmii0_rxctl.rgmii0_rxctl */
+ 0x270 (PIN_INPUT | MUX_MODE0) /* rgmii0_rxd3.rgmii0_rxd3 */
+ 0x274 (PIN_INPUT | MUX_MODE0) /* rgmii0_rxd2.rgmii0_rxd2 */
+ 0x278 (PIN_INPUT | MUX_MODE0) /* rgmii0_rxd1.rgmii0_rxd1 */
+ 0x27c (PIN_INPUT | MUX_MODE0) /* rgmii0_rxd0.rgmii0_rxd0 */
+
+ /* Slave 2 */
+ 0x198 (PIN_OUTPUT | MUX_MODE3) /* vin2a_d12.rgmii1_txc */
+ 0x19c (PIN_OUTPUT | MUX_MODE3) /* vin2a_d13.rgmii1_tctl */
+ 0x1a0 (PIN_OUTPUT | MUX_MODE3) /* vin2a_d14.rgmii1_td3 */
+ 0x1a4 (PIN_OUTPUT | MUX_MODE3) /* vin2a_d15.rgmii1_td2 */
+ 0x1a8 (PIN_OUTPUT | MUX_MODE3) /* vin2a_d16.rgmii1_td1 */
+ 0x1ac (PIN_OUTPUT | MUX_MODE3) /* vin2a_d17.rgmii1_td0 */
+ 0x1b0 (PIN_INPUT | MUX_MODE3) /* vin2a_d18.rgmii1_rclk */
+ 0x1b4 (PIN_INPUT | MUX_MODE3) /* vin2a_d19.rgmii1_rctl */
+ 0x1b8 (PIN_INPUT | MUX_MODE3) /* vin2a_d20.rgmii1_rd3 */
+ 0x1bc (PIN_INPUT | MUX_MODE3) /* vin2a_d21.rgmii1_rd2 */
+ 0x1c0 (PIN_INPUT | MUX_MODE3) /* vin2a_d22.rgmii1_rd1 */
+ 0x1c4 (PIN_INPUT | MUX_MODE3) /* vin2a_d23.rgmii1_rd0 */
+ >;
+
+ };
+
+ cpsw_sleep: cpsw_sleep {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ 0x250 (MUX_MODE15)
+ 0x254 (MUX_MODE15)
+ 0x258 (MUX_MODE15)
+ 0x25c (MUX_MODE15)
+ 0x260 (MUX_MODE15)
+ 0x264 (MUX_MODE15)
+ 0x268 (MUX_MODE15)
+ 0x26c (MUX_MODE15)
+ 0x270 (MUX_MODE15)
+ 0x274 (MUX_MODE15)
+ 0x278 (MUX_MODE15)
+ 0x27c (MUX_MODE15)
+
+ /* Slave 2 */
+ 0x198 (MUX_MODE15)
+ 0x19c (MUX_MODE15)
+ 0x1a0 (MUX_MODE15)
+ 0x1a4 (MUX_MODE15)
+ 0x1a8 (MUX_MODE15)
+ 0x1ac (MUX_MODE15)
+ 0x1b0 (MUX_MODE15)
+ 0x1b4 (MUX_MODE15)
+ 0x1b8 (MUX_MODE15)
+ 0x1bc (MUX_MODE15)
+ 0x1c0 (MUX_MODE15)
+ 0x1c4 (MUX_MODE15)
+ >;
+ };
+
+ davinci_mdio_default: davinci_mdio_default {
+ pinctrl-single,pins = <
+ 0x23c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_d.mdio_d */
+ 0x240 (PIN_INPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
+ >;
+ };
+
+ davinci_mdio_sleep: davinci_mdio_sleep {
+ pinctrl-single,pins = <
+ 0x23c (MUX_MODE15)
+ 0x240 (MUX_MODE15)
+ >;
+ };
+
+ dcan1_pins_default: dcan1_pins_default {
+ pinctrl-single,pins = <
+ 0x3d0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */
+ 0x418 (PULL_UP | MUX_MODE1) /* wakeup0.dcan1_rx */
+ >;
+ };
+
+ dcan1_pins_sleep: dcan1_pins_sleep {
+ pinctrl-single,pins = <
+ 0x3d0 (MUX_MODE15 | PULL_UP) /* dcan1_tx.off */
+ 0x418 (MUX_MODE15 | PULL_UP) /* wakeup0.off */
+ >;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <400000>;
+
+ tps659038: tps659038@58 {
+ compatible = "ti,tps659038";
+ reg = <0x58>;
+
+ tps659038_pmic {
+ compatible = "ti,tps659038-pmic";
+
+ regulators {
+ smps123_reg: smps123 {
+ /* VDD_MPU */
+ regulator-name = "smps123";
+ regulator-min-microvolt = < 850000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps45_reg: smps45 {
+ /* VDD_DSPEVE */
+ regulator-name = "smps45";
+ regulator-min-microvolt = < 850000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps6_reg: smps6 {
+ /* VDD_GPU - over VDD_SMPS6 */
+ regulator-name = "smps6";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps7_reg: smps7 {
+ /* CORE_VDD */
+ regulator-name = "smps7";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1060000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps8_reg: smps8 {
+ /* VDD_IVAHD */
+ regulator-name = "smps8";
+ regulator-min-microvolt = < 850000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps9_reg: smps9 {
+ /* VDDS1V8 */
+ regulator-name = "smps9";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo1_reg: ldo1 {
+ /* LDO1_OUT --> SDIO */
+ regulator-name = "ldo1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ };
+
+ ldo2_reg: ldo2 {
+ /* VDD_RTCIO */
+ /* LDO2 -> VDDSHV5, LDO2 also goes to CAN_PHY_3V3 */
+ regulator-name = "ldo2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo3_reg: ldo3 {
+ /* VDDA_1V8_PHY */
+ regulator-name = "ldo3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo9_reg: ldo9 {
+ /* VDD_RTC */
+ regulator-name = "ldo9";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldoln_reg: ldoln {
+ /* VDDA_1V8_PLL */
+ regulator-name = "ldoln";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldousb_reg: ldousb {
+ /* VDDA_3V_USB: VDDA_USBHS33 */
+ regulator-name = "ldousb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ };
+ };
+ };
+ };
+
+ pcf_gpio_21: gpio@21 {
+ compatible = "ti,pcf8575";
+ reg = <0x21>;
+ lines-initial-states = <0x1408>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+};
+
+&i2c2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+ clock-frequency = <400000>;
+};
+
+&i2c3 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+ clock-frequency = <400000>;
+};
+
+&mcspi1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi1_pins>;
+};
+
+&mcspi2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi2_pins>;
+};
+
+&uart1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ interrupts-extended = <&crossbar_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+ <&dra7_pmx_core 0x3e0>;
+};
+
+&uart2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+};
+
+&uart3 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+};
+
+&mmc1 {
+ status = "okay";
+ vmmc-supply = <&ldo1_reg>;
+ bus-width = <4>;
+};
+
+&mmc2 {
+ status = "okay";
+ vmmc-supply = <&mmc2_3v3>;
+ bus-width = <8>;
+};
+
+&cpu0 {
+ cpu0-supply = <&smps123_reg>;
+};
+
+&qspi {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&qspi1_pins>;
+
+ spi-max-frequency = <48000000>;
+ m25p80@0 {
+ compatible = "s25fl256s1";
+ spi-max-frequency = <48000000>;
+ reg = <0>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ spi-cpol;
+ spi-cpha;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /* MTD partition table.
+ * The ROM checks the first four physical blocks
+ * for a valid file to boot and the flash here is
+ * 64KiB block size.
+ */
+ partition@0 {
+ label = "QSPI.SPL";
+ reg = <0x00000000 0x000010000>;
+ };
+ partition@1 {
+ label = "QSPI.SPL.backup1";
+ reg = <0x00010000 0x00010000>;
+ };
+ partition@2 {
+ label = "QSPI.SPL.backup2";
+ reg = <0x00020000 0x00010000>;
+ };
+ partition@3 {
+ label = "QSPI.SPL.backup3";
+ reg = <0x00030000 0x00010000>;
+ };
+ partition@4 {
+ label = "QSPI.u-boot";
+ reg = <0x00040000 0x00100000>;
+ };
+ partition@5 {
+ label = "QSPI.u-boot-spl-os";
+ reg = <0x00140000 0x00080000>;
+ };
+ partition@6 {
+ label = "QSPI.u-boot-env";
+ reg = <0x001c0000 0x00010000>;
+ };
+ partition@7 {
+ label = "QSPI.u-boot-env.backup1";
+ reg = <0x001d0000 0x0010000>;
+ };
+ partition@8 {
+ label = "QSPI.kernel";
+ reg = <0x001e0000 0x0800000>;
+ };
+ partition@9 {
+ label = "QSPI.file-system";
+ reg = <0x009e0000 0x01620000>;
+ };
+ };
+};
+
+&omap_dwc3_1 {
+ extcon = <&extcon_usb1>;
+};
+
+&omap_dwc3_2 {
+ extcon = <&extcon_usb2>;
+};
+
+&usb1 {
+ dr_mode = "peripheral";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_pins>;
+};
+
+&usb2 {
+ dr_mode = "host";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb2_pins>;
+};
+
+&elm {
+ status = "okay";
+};
+
+&gpmc {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand_flash_x16>;
+ ranges = <0 0 0 0x01000000>; /* minimum GPMC partition = 16MB */
+ nand@0,0 {
+ reg = <0 0 4>; /* device IO registers */
+ ti,nand-ecc-opt = "bch8";
+ ti,elm-id = <&elm>;
+ nand-bus-width = <16>;
+ gpmc,device-width = <2>;
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <80>;
+ gpmc,cs-wr-off-ns = <80>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <60>;
+ gpmc,adv-wr-off-ns = <60>;
+ gpmc,we-on-ns = <10>;
+ gpmc,we-off-ns = <50>;
+ gpmc,oe-on-ns = <4>;
+ gpmc,oe-off-ns = <40>;
+ gpmc,access-ns = <40>;
+ gpmc,wr-access-ns = <80>;
+ gpmc,rd-cycle-ns = <80>;
+ gpmc,wr-cycle-ns = <80>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+ /* MTD partition table */
+ /* All SPL-* partitions are sized to minimal length
+ * which can be independently programmable. For
+ * NAND flash this is equal to size of erase-block */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "NAND.SPL";
+ reg = <0x00000000 0x000020000>;
+ };
+ partition@1 {
+ label = "NAND.SPL.backup1";
+ reg = <0x00020000 0x00020000>;
+ };
+ partition@2 {
+ label = "NAND.SPL.backup2";
+ reg = <0x00040000 0x00020000>;
+ };
+ partition@3 {
+ label = "NAND.SPL.backup3";
+ reg = <0x00060000 0x00020000>;
+ };
+ partition@4 {
+ label = "NAND.u-boot-spl-os";
+ reg = <0x00080000 0x00040000>;
+ };
+ partition@5 {
+ label = "NAND.u-boot";
+ reg = <0x000c0000 0x00100000>;
+ };
+ partition@6 {
+ label = "NAND.u-boot-env";
+ reg = <0x001c0000 0x00020000>;
+ };
+ partition@7 {
+ label = "NAND.u-boot-env.backup1";
+ reg = <0x001e0000 0x00020000>;
+ };
+ partition@8 {
+ label = "NAND.kernel";
+ reg = <0x00200000 0x00800000>;
+ };
+ partition@9 {
+ label = "NAND.file-system";
+ reg = <0x00a00000 0x0f600000>;
+ };
+ };
+};
+
+&usb2_phy1 {
+ phy-supply = <&ldousb_reg>;
+};
+
+&usb2_phy2 {
+ phy-supply = <&ldousb_reg>;
+};
+
+&gpio7 {
+ ti,no-reset-on-init;
+ ti,no-idle-on-init;
+};
+
+&mac {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ dual_emac;
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <2>;
+ phy-mode = "rgmii";
+ dual_emac_res_vlan = <1>;
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <3>;
+ phy-mode = "rgmii";
+ dual_emac_res_vlan = <2>;
+};
+
+&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
+};
+
+&dcan1 {
+ status = "ok";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&dcan1_pins_default>;
+ pinctrl-1 = <&dcan1_pins_sleep>;
+};
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
new file mode 100644
index 000000000..f03a091cd
--- /dev/null
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -0,0 +1,1486 @@
+/*
+ * Copyright (C) 2013 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.
+ * Based on "omap4.dtsi"
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/dra.h>
+
+#include "skeleton.dtsi"
+
+#define MAX_SOURCES 400
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ compatible = "ti,dra7xx";
+ interrupt-parent = <&crossbar_mpu>;
+
+ aliases {
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ i2c2 = &i2c3;
+ i2c3 = &i2c4;
+ i2c4 = &i2c5;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ serial5 = &uart6;
+ serial6 = &uart7;
+ serial7 = &uart8;
+ serial8 = &uart9;
+ serial9 = &uart10;
+ ethernet0 = &cpsw_emac0;
+ ethernet1 = &cpsw_emac1;
+ d_can0 = &dcan1;
+ d_can1 = &dcan2;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-parent = <&gic>;
+ };
+
+ gic: interrupt-controller@48211000 {
+ compatible = "arm,cortex-a15-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x48211000 0x1000>,
+ <0x48212000 0x1000>,
+ <0x48214000 0x2000>,
+ <0x48216000 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-parent = <&gic>;
+ };
+
+ wakeupgen: interrupt-controller@48281000 {
+ compatible = "ti,omap5-wugen-mpu", "ti,omap4-wugen-mpu";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x48281000 0x1000>;
+ interrupt-parent = <&gic>;
+ };
+
+ /*
+ * The soc node represents the soc top level view. It is used for IPs
+ * that are not memory mapped in the MPU view or for the MPU itself.
+ */
+ soc {
+ compatible = "ti,omap-infra";
+ mpu {
+ compatible = "ti,omap5-mpu";
+ ti,hwmods = "mpu";
+ };
+ };
+
+ /*
+ * XXX: Use a flat representation of the SOC interconnect.
+ * The real OMAP interconnect network is quite complex.
+ * Since it will not bring real advantage to represent that in DT for
+ * the moment, just use a fake OCP bus entry to represent the whole bus
+ * hierarchy.
+ */
+ ocp {
+ compatible = "ti,dra7-l3-noc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "l3_main_1", "l3_main_2";
+ reg = <0x44000000 0x1000000>,
+ <0x45000000 0x1000>;
+ interrupts-extended = <&crossbar_mpu GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <&wakeupgen GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+
+ l4_cfg: l4@4a000000 {
+ compatible = "ti,dra7-l4-cfg", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x4a000000 0x22c000>;
+
+ scm: scm@2000 {
+ compatible = "ti,dra7-scm-core", "simple-bus";
+ reg = <0x2000 0x2000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x2000 0x2000>;
+
+ scm_conf: scm_conf@0 {
+ compatible = "syscon";
+ reg = <0x0 0x1400>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ pbias_regulator: pbias_regulator {
+ compatible = "ti,pbias-omap";
+ reg = <0xe00 0x4>;
+ syscon = <&scm_conf>;
+ pbias_mmc_reg: pbias_mmc_omap5 {
+ regulator-name = "pbias_mmc_omap5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ };
+ };
+ };
+
+ dra7_pmx_core: pinmux@1400 {
+ compatible = "ti,dra7-padconf",
+ "pinctrl-single";
+ reg = <0x1400 0x0464>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0x3fffffff>;
+ };
+ };
+
+ cm_core_aon: cm_core_aon@5000 {
+ compatible = "ti,dra7-cm-core-aon";
+ reg = <0x5000 0x2000>;
+
+ cm_core_aon_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cm_core_aon_clockdomains: clockdomains {
+ };
+ };
+
+ cm_core: cm_core@8000 {
+ compatible = "ti,dra7-cm-core";
+ reg = <0x8000 0x3000>;
+
+ cm_core_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cm_core_clockdomains: clockdomains {
+ };
+ };
+ };
+
+ l4_wkup: l4@4ae00000 {
+ compatible = "ti,dra7-l4-wkup", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x4ae00000 0x3f000>;
+
+ counter32k: counter@4000 {
+ compatible = "ti,omap-counter32k";
+ reg = <0x4000 0x40>;
+ ti,hwmods = "counter_32k";
+ };
+
+ prm: prm@6000 {
+ compatible = "ti,dra7-prm";
+ reg = <0x6000 0x3000>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+
+ prm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ prm_clockdomains: clockdomains {
+ };
+ };
+ };
+
+ axi@0 {
+ compatible = "simple-bus";
+ #size-cells = <1>;
+ #address-cells = <1>;
+ ranges = <0x51000000 0x51000000 0x3000
+ 0x0 0x20000000 0x10000000>;
+ pcie@51000000 {
+ compatible = "ti,dra7-pcie";
+ reg = <0x51000000 0x2000>, <0x51002000 0x14c>, <0x1000 0x2000>;
+ reg-names = "rc_dbics", "ti_conf", "config";
+ interrupts = <0 232 0x4>, <0 233 0x4>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x81000000 0 0 0x03000 0 0x00010000
+ 0x82000000 0 0x20013000 0x13000 0 0xffed000>;
+ #interrupt-cells = <1>;
+ num-lanes = <1>;
+ ti,hwmods = "pcie1";
+ phys = <&pcie1_phy>;
+ phy-names = "pcie-phy0";
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie1_intc 1>,
+ <0 0 0 2 &pcie1_intc 2>,
+ <0 0 0 3 &pcie1_intc 3>,
+ <0 0 0 4 &pcie1_intc 4>;
+ pcie1_intc: interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+ };
+ };
+
+ axi@1 {
+ compatible = "simple-bus";
+ #size-cells = <1>;
+ #address-cells = <1>;
+ ranges = <0x51800000 0x51800000 0x3000
+ 0x0 0x30000000 0x10000000>;
+ status = "disabled";
+ pcie@51000000 {
+ compatible = "ti,dra7-pcie";
+ reg = <0x51800000 0x2000>, <0x51802000 0x14c>, <0x1000 0x2000>;
+ reg-names = "rc_dbics", "ti_conf", "config";
+ interrupts = <0 355 0x4>, <0 356 0x4>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x81000000 0 0 0x03000 0 0x00010000
+ 0x82000000 0 0x30013000 0x13000 0 0xffed000>;
+ #interrupt-cells = <1>;
+ num-lanes = <1>;
+ ti,hwmods = "pcie2";
+ phys = <&pcie2_phy>;
+ phy-names = "pcie-phy0";
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie2_intc 1>,
+ <0 0 0 2 &pcie2_intc 2>,
+ <0 0 0 3 &pcie2_intc 3>,
+ <0 0 0 4 &pcie2_intc 4>;
+ pcie2_intc: interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+ };
+ };
+
+ bandgap: bandgap@4a0021e0 {
+ reg = <0x4a0021e0 0xc
+ 0x4a00232c 0xc
+ 0x4a002380 0x2c
+ 0x4a0023C0 0x3c
+ 0x4a002564 0x8
+ 0x4a002574 0x50>;
+ compatible = "ti,dra752-bandgap";
+ interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+ #thermal-sensor-cells = <1>;
+ };
+
+ dra7_ctrl_core: ctrl_core@4a002000 {
+ compatible = "syscon";
+ reg = <0x4a002000 0x6d0>;
+ };
+
+ dra7_ctrl_general: tisyscon@4a002e00 {
+ compatible = "syscon";
+ reg = <0x4a002e00 0x7c>;
+ };
+
+ sdma: dma-controller@4a056000 {
+ compatible = "ti,omap4430-sdma";
+ reg = <0x4a056000 0x1000>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ dma-channels = <32>;
+ dma-requests = <127>;
+ };
+
+ gpio1: gpio@4ae10000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x4ae10000 0x200>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio1";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@48055000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x48055000 0x200>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio2";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@48057000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x48057000 0x200>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio3";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@48059000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x48059000 0x200>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio4";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio5: gpio@4805b000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x4805b000 0x200>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio5";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio6: gpio@4805d000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x4805d000 0x200>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio6";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio7: gpio@48051000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x48051000 0x200>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio7";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio8: gpio@48053000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x48053000 0x200>;
+ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio8";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart1: serial@4806a000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x4806a000 0x100>;
+ interrupts-extended = <&crossbar_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart1";
+ clock-frequency = <48000000>;
+ status = "disabled";
+ dmas = <&sdma 49>, <&sdma 50>;
+ dma-names = "tx", "rx";
+ };
+
+ uart2: serial@4806c000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x4806c000 0x100>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart2";
+ clock-frequency = <48000000>;
+ status = "disabled";
+ dmas = <&sdma 51>, <&sdma 52>;
+ dma-names = "tx", "rx";
+ };
+
+ uart3: serial@48020000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x48020000 0x100>;
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart3";
+ clock-frequency = <48000000>;
+ status = "disabled";
+ dmas = <&sdma 53>, <&sdma 54>;
+ dma-names = "tx", "rx";
+ };
+
+ uart4: serial@4806e000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x4806e000 0x100>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart4";
+ clock-frequency = <48000000>;
+ status = "disabled";
+ dmas = <&sdma 55>, <&sdma 56>;
+ dma-names = "tx", "rx";
+ };
+
+ uart5: serial@48066000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x48066000 0x100>;
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart5";
+ clock-frequency = <48000000>;
+ status = "disabled";
+ dmas = <&sdma 63>, <&sdma 64>;
+ dma-names = "tx", "rx";
+ };
+
+ uart6: serial@48068000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x48068000 0x100>;
+ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart6";
+ clock-frequency = <48000000>;
+ status = "disabled";
+ dmas = <&sdma 79>, <&sdma 80>;
+ dma-names = "tx", "rx";
+ };
+
+ uart7: serial@48420000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x48420000 0x100>;
+ interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart7";
+ clock-frequency = <48000000>;
+ status = "disabled";
+ };
+
+ uart8: serial@48422000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x48422000 0x100>;
+ interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart8";
+ clock-frequency = <48000000>;
+ status = "disabled";
+ };
+
+ uart9: serial@48424000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x48424000 0x100>;
+ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart9";
+ clock-frequency = <48000000>;
+ status = "disabled";
+ };
+
+ uart10: serial@4ae2b000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x4ae2b000 0x100>;
+ interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart10";
+ clock-frequency = <48000000>;
+ status = "disabled";
+ };
+
+ mailbox1: mailbox@4a0f4000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x4a0f4000 0x200>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mailbox1";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <3>;
+ ti,mbox-num-fifos = <8>;
+ status = "disabled";
+ };
+
+ mailbox2: mailbox@4883a000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x4883a000 0x200>;
+ interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mailbox2";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <12>;
+ status = "disabled";
+ };
+
+ mailbox3: mailbox@4883c000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x4883c000 0x200>;
+ interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mailbox3";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <12>;
+ status = "disabled";
+ };
+
+ mailbox4: mailbox@4883e000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x4883e000 0x200>;
+ interrupts = <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mailbox4";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <12>;
+ status = "disabled";
+ };
+
+ mailbox5: mailbox@48840000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x48840000 0x200>;
+ interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mailbox5";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <12>;
+ status = "disabled";
+ };
+
+ mailbox6: mailbox@48842000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x48842000 0x200>;
+ interrupts = <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mailbox6";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <12>;
+ status = "disabled";
+ };
+
+ mailbox7: mailbox@48844000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x48844000 0x200>;
+ interrupts = <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mailbox7";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <12>;
+ status = "disabled";
+ };
+
+ mailbox8: mailbox@48846000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x48846000 0x200>;
+ interrupts = <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mailbox8";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <12>;
+ status = "disabled";
+ };
+
+ mailbox9: mailbox@4885e000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x4885e000 0x200>;
+ interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mailbox9";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <12>;
+ status = "disabled";
+ };
+
+ mailbox10: mailbox@48860000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x48860000 0x200>;
+ interrupts = <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mailbox10";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <12>;
+ status = "disabled";
+ };
+
+ mailbox11: mailbox@48862000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x48862000 0x200>;
+ interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mailbox11";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <12>;
+ status = "disabled";
+ };
+
+ mailbox12: mailbox@48864000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x48864000 0x200>;
+ interrupts = <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mailbox12";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <12>;
+ status = "disabled";
+ };
+
+ mailbox13: mailbox@48802000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x48802000 0x200>;
+ interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 380 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mailbox13";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <12>;
+ status = "disabled";
+ };
+
+ timer1: timer@4ae18000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x4ae18000 0x80>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer1";
+ ti,timer-alwon;
+ };
+
+ timer2: timer@48032000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x48032000 0x80>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer2";
+ };
+
+ timer3: timer@48034000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x48034000 0x80>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer3";
+ };
+
+ timer4: timer@48036000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x48036000 0x80>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer4";
+ };
+
+ timer5: timer@48820000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x48820000 0x80>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer5";
+ };
+
+ timer6: timer@48822000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x48822000 0x80>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer6";
+ };
+
+ timer7: timer@48824000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x48824000 0x80>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer7";
+ };
+
+ timer8: timer@48826000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x48826000 0x80>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer8";
+ };
+
+ timer9: timer@4803e000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x4803e000 0x80>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer9";
+ };
+
+ timer10: timer@48086000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x48086000 0x80>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer10";
+ };
+
+ timer11: timer@48088000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x48088000 0x80>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer11";
+ };
+
+ timer13: timer@48828000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x48828000 0x80>;
+ interrupts = <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer13";
+ status = "disabled";
+ };
+
+ timer14: timer@4882a000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x4882a000 0x80>;
+ interrupts = <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer14";
+ status = "disabled";
+ };
+
+ timer15: timer@4882c000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x4882c000 0x80>;
+ interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer15";
+ status = "disabled";
+ };
+
+ timer16: timer@4882e000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x4882e000 0x80>;
+ interrupts = <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer16";
+ status = "disabled";
+ };
+
+ wdt2: wdt@4ae14000 {
+ compatible = "ti,omap3-wdt";
+ reg = <0x4ae14000 0x80>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "wd_timer2";
+ };
+
+ hwspinlock: spinlock@4a0f6000 {
+ compatible = "ti,omap4-hwspinlock";
+ reg = <0x4a0f6000 0x1000>;
+ ti,hwmods = "spinlock";
+ #hwlock-cells = <1>;
+ };
+
+ dmm@4e000000 {
+ compatible = "ti,omap5-dmm";
+ reg = <0x4e000000 0x800>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "dmm";
+ };
+
+ i2c1: i2c@48070000 {
+ compatible = "ti,omap4-i2c";
+ reg = <0x48070000 0x100>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c1";
+ status = "disabled";
+ };
+
+ i2c2: i2c@48072000 {
+ compatible = "ti,omap4-i2c";
+ reg = <0x48072000 0x100>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c2";
+ status = "disabled";
+ };
+
+ i2c3: i2c@48060000 {
+ compatible = "ti,omap4-i2c";
+ reg = <0x48060000 0x100>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c3";
+ status = "disabled";
+ };
+
+ i2c4: i2c@4807a000 {
+ compatible = "ti,omap4-i2c";
+ reg = <0x4807a000 0x100>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c4";
+ status = "disabled";
+ };
+
+ i2c5: i2c@4807c000 {
+ compatible = "ti,omap4-i2c";
+ reg = <0x4807c000 0x100>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c5";
+ status = "disabled";
+ };
+
+ mmc1: mmc@4809c000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x4809c000 0x400>;
+ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmc1";
+ ti,dual-volt;
+ ti,needs-special-reset;
+ dmas = <&sdma 61>, <&sdma 62>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ pbias-supply = <&pbias_mmc_reg>;
+ };
+
+ mmc2: mmc@480b4000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x480b4000 0x400>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmc2";
+ ti,needs-special-reset;
+ dmas = <&sdma 47>, <&sdma 48>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mmc3: mmc@480ad000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x480ad000 0x400>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmc3";
+ ti,needs-special-reset;
+ dmas = <&sdma 77>, <&sdma 78>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mmc4: mmc@480d1000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x480d1000 0x400>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmc4";
+ ti,needs-special-reset;
+ dmas = <&sdma 57>, <&sdma 58>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ abb_mpu: regulator-abb-mpu {
+ compatible = "ti,abb-v3";
+ regulator-name = "abb_mpu";
+ #address-cells = <0>;
+ #size-cells = <0>;
+ clocks = <&sys_clkin1>;
+ ti,settling-time = <50>;
+ ti,clock-cycles = <16>;
+
+ reg = <0x4ae07ddc 0x4>, <0x4ae07de0 0x4>,
+ <0x4ae06014 0x4>, <0x4a003b20 0xc>,
+ <0x4ae0c158 0x4>;
+ reg-names = "setup-address", "control-address",
+ "int-address", "efuse-address",
+ "ldo-address";
+ ti,tranxdone-status-mask = <0x80>;
+ /* LDOVBBMPU_FBB_MUX_CTRL */
+ ti,ldovbb-override-mask = <0x400>;
+ /* LDOVBBMPU_FBB_VSET_OUT */
+ ti,ldovbb-vset-mask = <0x1F>;
+
+ /*
+ * NOTE: only FBB mode used but actual vset will
+ * determine final biasing
+ */
+ ti,abb_info = <
+ /*uV ABB efuse rbb_m fbb_m vset_m*/
+ 1060000 0 0x0 0 0x02000000 0x01F00000
+ 1160000 0 0x4 0 0x02000000 0x01F00000
+ 1210000 0 0x8 0 0x02000000 0x01F00000
+ >;
+ };
+
+ abb_ivahd: regulator-abb-ivahd {
+ compatible = "ti,abb-v3";
+ regulator-name = "abb_ivahd";
+ #address-cells = <0>;
+ #size-cells = <0>;
+ clocks = <&sys_clkin1>;
+ ti,settling-time = <50>;
+ ti,clock-cycles = <16>;
+
+ reg = <0x4ae07e34 0x4>, <0x4ae07e24 0x4>,
+ <0x4ae06010 0x4>, <0x4a0025cc 0xc>,
+ <0x4a002470 0x4>;
+ reg-names = "setup-address", "control-address",
+ "int-address", "efuse-address",
+ "ldo-address";
+ ti,tranxdone-status-mask = <0x40000000>;
+ /* LDOVBBIVA_FBB_MUX_CTRL */
+ ti,ldovbb-override-mask = <0x400>;
+ /* LDOVBBIVA_FBB_VSET_OUT */
+ ti,ldovbb-vset-mask = <0x1F>;
+
+ /*
+ * NOTE: only FBB mode used but actual vset will
+ * determine final biasing
+ */
+ ti,abb_info = <
+ /*uV ABB efuse rbb_m fbb_m vset_m*/
+ 1055000 0 0x0 0 0x02000000 0x01F00000
+ 1150000 0 0x4 0 0x02000000 0x01F00000
+ 1250000 0 0x8 0 0x02000000 0x01F00000
+ >;
+ };
+
+ abb_dspeve: regulator-abb-dspeve {
+ compatible = "ti,abb-v3";
+ regulator-name = "abb_dspeve";
+ #address-cells = <0>;
+ #size-cells = <0>;
+ clocks = <&sys_clkin1>;
+ ti,settling-time = <50>;
+ ti,clock-cycles = <16>;
+
+ reg = <0x4ae07e30 0x4>, <0x4ae07e20 0x4>,
+ <0x4ae06010 0x4>, <0x4a0025e0 0xc>,
+ <0x4a00246c 0x4>;
+ reg-names = "setup-address", "control-address",
+ "int-address", "efuse-address",
+ "ldo-address";
+ ti,tranxdone-status-mask = <0x20000000>;
+ /* LDOVBBDSPEVE_FBB_MUX_CTRL */
+ ti,ldovbb-override-mask = <0x400>;
+ /* LDOVBBDSPEVE_FBB_VSET_OUT */
+ ti,ldovbb-vset-mask = <0x1F>;
+
+ /*
+ * NOTE: only FBB mode used but actual vset will
+ * determine final biasing
+ */
+ ti,abb_info = <
+ /*uV ABB efuse rbb_m fbb_m vset_m*/
+ 1055000 0 0x0 0 0x02000000 0x01F00000
+ 1150000 0 0x4 0 0x02000000 0x01F00000
+ 1250000 0 0x8 0 0x02000000 0x01F00000
+ >;
+ };
+
+ abb_gpu: regulator-abb-gpu {
+ compatible = "ti,abb-v3";
+ regulator-name = "abb_gpu";
+ #address-cells = <0>;
+ #size-cells = <0>;
+ clocks = <&sys_clkin1>;
+ ti,settling-time = <50>;
+ ti,clock-cycles = <16>;
+
+ reg = <0x4ae07de4 0x4>, <0x4ae07de8 0x4>,
+ <0x4ae06010 0x4>, <0x4a003b08 0xc>,
+ <0x4ae0c154 0x4>;
+ reg-names = "setup-address", "control-address",
+ "int-address", "efuse-address",
+ "ldo-address";
+ ti,tranxdone-status-mask = <0x10000000>;
+ /* LDOVBBGPU_FBB_MUX_CTRL */
+ ti,ldovbb-override-mask = <0x400>;
+ /* LDOVBBGPU_FBB_VSET_OUT */
+ ti,ldovbb-vset-mask = <0x1F>;
+
+ /*
+ * NOTE: only FBB mode used but actual vset will
+ * determine final biasing
+ */
+ ti,abb_info = <
+ /*uV ABB efuse rbb_m fbb_m vset_m*/
+ 1090000 0 0x0 0 0x02000000 0x01F00000
+ 1210000 0 0x4 0 0x02000000 0x01F00000
+ 1280000 0 0x8 0 0x02000000 0x01F00000
+ >;
+ };
+
+ mcspi1: spi@48098000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x48098000 0x200>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi1";
+ ti,spi-num-cs = <4>;
+ dmas = <&sdma 35>,
+ <&sdma 36>,
+ <&sdma 37>,
+ <&sdma 38>,
+ <&sdma 39>,
+ <&sdma 40>,
+ <&sdma 41>,
+ <&sdma 42>;
+ dma-names = "tx0", "rx0", "tx1", "rx1",
+ "tx2", "rx2", "tx3", "rx3";
+ status = "disabled";
+ };
+
+ mcspi2: spi@4809a000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x4809a000 0x200>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi2";
+ ti,spi-num-cs = <2>;
+ dmas = <&sdma 43>,
+ <&sdma 44>,
+ <&sdma 45>,
+ <&sdma 46>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
+ status = "disabled";
+ };
+
+ mcspi3: spi@480b8000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x480b8000 0x200>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi3";
+ ti,spi-num-cs = <2>;
+ dmas = <&sdma 15>, <&sdma 16>;
+ dma-names = "tx0", "rx0";
+ status = "disabled";
+ };
+
+ mcspi4: spi@480ba000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x480ba000 0x200>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi4";
+ ti,spi-num-cs = <1>;
+ dmas = <&sdma 70>, <&sdma 71>;
+ dma-names = "tx0", "rx0";
+ status = "disabled";
+ };
+
+ qspi: qspi@4b300000 {
+ compatible = "ti,dra7xxx-qspi";
+ reg = <0x4b300000 0x100>;
+ reg-names = "qspi_base";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "qspi";
+ clocks = <&qspi_gfclk_div>;
+ clock-names = "fck";
+ num-cs = <4>;
+ interrupts = <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ omap_control_sata: control-phy@4a002374 {
+ compatible = "ti,control-phy-pipe3";
+ reg = <0x4a002374 0x4>;
+ reg-names = "power";
+ clocks = <&sys_clkin1>;
+ clock-names = "sysclk";
+ };
+
+ /* OCP2SCP3 */
+ ocp2scp@4a090000 {
+ compatible = "ti,omap-ocp2scp";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ reg = <0x4a090000 0x20>;
+ ti,hwmods = "ocp2scp3";
+ sata_phy: phy@4A096000 {
+ compatible = "ti,phy-pipe3-sata";
+ reg = <0x4A096000 0x80>, /* phy_rx */
+ <0x4A096400 0x64>, /* phy_tx */
+ <0x4A096800 0x40>; /* pll_ctrl */
+ reg-names = "phy_rx", "phy_tx", "pll_ctrl";
+ ctrl-module = <&omap_control_sata>;
+ clocks = <&sys_clkin1>, <&sata_ref_clk>;
+ clock-names = "sysclk", "refclk";
+ #phy-cells = <0>;
+ };
+
+ pcie1_phy: pciephy@4a094000 {
+ compatible = "ti,phy-pipe3-pcie";
+ reg = <0x4a094000 0x80>, /* phy_rx */
+ <0x4a094400 0x64>; /* phy_tx */
+ reg-names = "phy_rx", "phy_tx";
+ ctrl-module = <&omap_control_pcie1phy>;
+ clocks = <&dpll_pcie_ref_ck>,
+ <&dpll_pcie_ref_m2ldo_ck>,
+ <&optfclk_pciephy1_32khz>,
+ <&optfclk_pciephy1_clk>,
+ <&optfclk_pciephy1_div_clk>,
+ <&optfclk_pciephy_div>;
+ clock-names = "dpll_ref", "dpll_ref_m2",
+ "wkupclk", "refclk",
+ "div-clk", "phy-div";
+ #phy-cells = <0>;
+ };
+
+ pcie2_phy: pciephy@4a095000 {
+ compatible = "ti,phy-pipe3-pcie";
+ reg = <0x4a095000 0x80>, /* phy_rx */
+ <0x4a095400 0x64>; /* phy_tx */
+ reg-names = "phy_rx", "phy_tx";
+ ctrl-module = <&omap_control_pcie2phy>;
+ clocks = <&dpll_pcie_ref_ck>,
+ <&dpll_pcie_ref_m2ldo_ck>,
+ <&optfclk_pciephy2_32khz>,
+ <&optfclk_pciephy2_clk>,
+ <&optfclk_pciephy2_div_clk>,
+ <&optfclk_pciephy_div>;
+ clock-names = "dpll_ref", "dpll_ref_m2",
+ "wkupclk", "refclk",
+ "div-clk", "phy-div";
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+ };
+
+ sata: sata@4a141100 {
+ compatible = "snps,dwc-ahci";
+ reg = <0x4a140000 0x1100>, <0x4a141100 0x7>;
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&sata_phy>;
+ phy-names = "sata-phy";
+ clocks = <&sata_ref_clk>;
+ ti,hwmods = "sata";
+ };
+
+ omap_control_pcie1phy: control-phy@0x4a003c40 {
+ compatible = "ti,control-phy-pcie";
+ reg = <0x4a003c40 0x4>, <0x4a003c14 0x4>, <0x4a003c34 0x4>;
+ reg-names = "power", "control_sma", "pcie_pcs";
+ clocks = <&sys_clkin1>;
+ clock-names = "sysclk";
+ };
+
+ omap_control_pcie2phy: control-pcie@0x4a003c44 {
+ compatible = "ti,control-phy-pcie";
+ reg = <0x4a003c44 0x4>, <0x4a003c14 0x4>, <0x4a003c34 0x4>;
+ reg-names = "power", "control_sma", "pcie_pcs";
+ clocks = <&sys_clkin1>;
+ clock-names = "sysclk";
+ status = "disabled";
+ };
+
+ rtc: rtc@48838000 {
+ compatible = "ti,am3352-rtc";
+ reg = <0x48838000 0x100>;
+ interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "rtcss";
+ clocks = <&sys_32k_ck>;
+ };
+
+ omap_control_usb2phy1: control-phy@4a002300 {
+ compatible = "ti,control-phy-usb2";
+ reg = <0x4a002300 0x4>;
+ reg-names = "power";
+ };
+
+ omap_control_usb3phy1: control-phy@4a002370 {
+ compatible = "ti,control-phy-pipe3";
+ reg = <0x4a002370 0x4>;
+ reg-names = "power";
+ };
+
+ omap_control_usb2phy2: control-phy@0x4a002e74 {
+ compatible = "ti,control-phy-usb2-dra7";
+ reg = <0x4a002e74 0x4>;
+ reg-names = "power";
+ };
+
+ /* OCP2SCP1 */
+ ocp2scp@4a080000 {
+ compatible = "ti,omap-ocp2scp";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ reg = <0x4a080000 0x20>;
+ ti,hwmods = "ocp2scp1";
+
+ usb2_phy1: phy@4a084000 {
+ compatible = "ti,omap-usb2";
+ reg = <0x4a084000 0x400>;
+ ctrl-module = <&omap_control_usb2phy1>;
+ clocks = <&usb_phy1_always_on_clk32k>,
+ <&usb_otg_ss1_refclk960m>;
+ clock-names = "wkupclk",
+ "refclk";
+ #phy-cells = <0>;
+ };
+
+ usb2_phy2: phy@4a085000 {
+ compatible = "ti,omap-usb2";
+ reg = <0x4a085000 0x400>;
+ ctrl-module = <&omap_control_usb2phy2>;
+ clocks = <&usb_phy2_always_on_clk32k>,
+ <&usb_otg_ss2_refclk960m>;
+ clock-names = "wkupclk",
+ "refclk";
+ #phy-cells = <0>;
+ };
+
+ usb3_phy1: phy@4a084400 {
+ compatible = "ti,omap-usb3";
+ reg = <0x4a084400 0x80>,
+ <0x4a084800 0x64>,
+ <0x4a084c00 0x40>;
+ reg-names = "phy_rx", "phy_tx", "pll_ctrl";
+ ctrl-module = <&omap_control_usb3phy1>;
+ clocks = <&usb_phy3_always_on_clk32k>,
+ <&sys_clkin1>,
+ <&usb_otg_ss1_refclk960m>;
+ clock-names = "wkupclk",
+ "sysclk",
+ "refclk";
+ #phy-cells = <0>;
+ };
+ };
+
+ omap_dwc3_1: omap_dwc3_1@48880000 {
+ compatible = "ti,dwc3";
+ ti,hwmods = "usb_otg_ss1";
+ reg = <0x48880000 0x10000>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ utmi-mode = <2>;
+ ranges;
+ usb1: usb@48890000 {
+ compatible = "snps,dwc3";
+ reg = <0x48890000 0x17000>;
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb2_phy1>, <&usb3_phy1>;
+ phy-names = "usb2-phy", "usb3-phy";
+ tx-fifo-resize;
+ maximum-speed = "super-speed";
+ dr_mode = "otg";
+ snps,dis_u3_susphy_quirk;
+ snps,dis_u2_susphy_quirk;
+ };
+ };
+
+ omap_dwc3_2: omap_dwc3_2@488c0000 {
+ compatible = "ti,dwc3";
+ ti,hwmods = "usb_otg_ss2";
+ reg = <0x488c0000 0x10000>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ utmi-mode = <2>;
+ ranges;
+ usb2: usb@488d0000 {
+ compatible = "snps,dwc3";
+ reg = <0x488d0000 0x17000>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb2_phy2>;
+ phy-names = "usb2-phy";
+ tx-fifo-resize;
+ maximum-speed = "high-speed";
+ dr_mode = "otg";
+ snps,dis_u3_susphy_quirk;
+ snps,dis_u2_susphy_quirk;
+ };
+ };
+
+ /* IRQ for DWC3_3 and DWC3_4 need IRQ crossbar */
+ omap_dwc3_3: omap_dwc3_3@48900000 {
+ compatible = "ti,dwc3";
+ ti,hwmods = "usb_otg_ss3";
+ reg = <0x48900000 0x10000>;
+ interrupts = <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ utmi-mode = <2>;
+ ranges;
+ status = "disabled";
+ usb3: usb@48910000 {
+ compatible = "snps,dwc3";
+ reg = <0x48910000 0x17000>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+ tx-fifo-resize;
+ maximum-speed = "high-speed";
+ dr_mode = "otg";
+ snps,dis_u3_susphy_quirk;
+ snps,dis_u2_susphy_quirk;
+ };
+ };
+
+ elm: elm@48078000 {
+ compatible = "ti,am3352-elm";
+ reg = <0x48078000 0xfc0>; /* device IO registers */
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "elm";
+ status = "disabled";
+ };
+
+ gpmc: gpmc@50000000 {
+ compatible = "ti,am3352-gpmc";
+ ti,hwmods = "gpmc";
+ reg = <0x50000000 0x37c>; /* device IO registers */
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ gpmc,num-cs = <8>;
+ gpmc,num-waitpins = <2>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ status = "disabled";
+ };
+
+ atl: atl@4843c000 {
+ compatible = "ti,dra7-atl";
+ reg = <0x4843c000 0x3ff>;
+ ti,hwmods = "atl";
+ ti,provided-clocks = <&atl_clkin0_ck>, <&atl_clkin1_ck>,
+ <&atl_clkin2_ck>, <&atl_clkin3_ck>;
+ clocks = <&atl_gfclk_mux>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ crossbar_mpu: crossbar@4a002a48 {
+ compatible = "ti,irq-crossbar";
+ reg = <0x4a002a48 0x130>;
+ interrupt-controller;
+ interrupt-parent = <&wakeupgen>;
+ #interrupt-cells = <3>;
+ ti,max-irqs = <160>;
+ ti,max-crossbar-sources = <MAX_SOURCES>;
+ ti,reg-size = <2>;
+ ti,irqs-reserved = <0 1 2 3 5 6 131 132>;
+ ti,irqs-skip = <10 133 139 140>;
+ ti,irqs-safe-map = <0>;
+ };
+
+ mac: ethernet@4a100000 {
+ compatible = "ti,cpsw";
+ ti,hwmods = "gmac";
+ clocks = <&dpll_gmac_ck>, <&gmac_gmii_ref_clk_div>;
+ clock-names = "fck", "cpts";
+ cpdma_channels = <8>;
+ ale_entries = <1024>;
+ bd_ram_size = <0x2000>;
+ no_bd_ram = <0>;
+ rx_descs = <64>;
+ mac_control = <0x20>;
+ slaves = <2>;
+ active_slave = <0>;
+ cpts_clock_mult = <0x80000000>;
+ cpts_clock_shift = <29>;
+ reg = <0x48484000 0x1000
+ 0x48485200 0x2E00>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ /*
+ * rx_thresh_pend
+ * rx_pend
+ * tx_pend
+ * misc_pend
+ */
+ interrupts = <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>;
+ ranges;
+ status = "disabled";
+
+ davinci_mdio: mdio@48485000 {
+ compatible = "ti,davinci_mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "davinci_mdio";
+ bus_freq = <1000000>;
+ reg = <0x48485000 0x100>;
+ };
+
+ cpsw_emac0: slave@48480200 {
+ /* Filled in by U-Boot */
+ mac-address = [ 00 00 00 00 00 00 ];
+ };
+
+ cpsw_emac1: slave@48480300 {
+ /* Filled in by U-Boot */
+ mac-address = [ 00 00 00 00 00 00 ];
+ };
+
+ phy_sel: cpsw-phy-sel@4a002554 {
+ compatible = "ti,dra7xx-cpsw-phy-sel";
+ reg= <0x4a002554 0x4>;
+ reg-names = "gmii-sel";
+ };
+ };
+
+ dcan1: can@481cc000 {
+ compatible = "ti,dra7-d_can";
+ ti,hwmods = "dcan1";
+ reg = <0x4ae3c000 0x2000>;
+ syscon-raminit = <&scm_conf 0x558 0>;
+ interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&dcan1_sys_clk_mux>;
+ status = "disabled";
+ };
+
+ dcan2: can@481d0000 {
+ compatible = "ti,dra7-d_can";
+ ti,hwmods = "dcan2";
+ reg = <0x48480000 0x2000>;
+ syscon-raminit = <&scm_conf 0x558 1>;
+ interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sys_clkin1>;
+ status = "disabled";
+ };
+ };
+
+ thermal_zones: thermal-zones {
+ #include "omap4-cpu-thermal.dtsi"
+ #include "omap5-gpu-thermal.dtsi"
+ #include "omap5-core-thermal.dtsi"
+ };
+
+};
+
+&cpu_thermal {
+ polling-delay = <500>; /* milliseconds */
+};
+
+/include/ "dra7xx-clocks.dtsi"
diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts
new file mode 100644
index 000000000..ce0390f08
--- /dev/null
+++ b/arch/arm/boot/dts/dra72-evm.dts
@@ -0,0 +1,568 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+/dts-v1/;
+
+#include "dra72x.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "TI DRA722";
+ compatible = "ti,dra72-evm", "ti,dra722", "ti,dra72", "ti,dra7";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>; /* 1024 MB */
+ };
+
+ evm_3v3: fixedregulator-evm_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "evm_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ extcon_usb1: extcon_usb1 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&pcf_gpio_21 1 GPIO_ACTIVE_HIGH>;
+ };
+
+ extcon_usb2: extcon_usb2 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&pcf_gpio_21 2 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&dra7_pmx_core {
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ 0x400 (PIN_INPUT | MUX_MODE0) /* i2c1_sda.i2c1_sda */
+ 0x404 (PIN_INPUT | MUX_MODE0) /* i2c1_scl.i2c1_scl */
+ >;
+ };
+
+ nand_default: nand_default {
+ pinctrl-single,pins = <
+ 0x0 (PIN_INPUT | MUX_MODE0) /* gpmc_ad0 */
+ 0x4 (PIN_INPUT | MUX_MODE0) /* gpmc_ad1 */
+ 0x8 (PIN_INPUT | MUX_MODE0) /* gpmc_ad2 */
+ 0xc (PIN_INPUT | MUX_MODE0) /* gpmc_ad3 */
+ 0x10 (PIN_INPUT | MUX_MODE0) /* gpmc_ad4 */
+ 0x14 (PIN_INPUT | MUX_MODE0) /* gpmc_ad5 */
+ 0x18 (PIN_INPUT | MUX_MODE0) /* gpmc_ad6 */
+ 0x1c (PIN_INPUT | MUX_MODE0) /* gpmc_ad7 */
+ 0x20 (PIN_INPUT | MUX_MODE0) /* gpmc_ad8 */
+ 0x24 (PIN_INPUT | MUX_MODE0) /* gpmc_ad9 */
+ 0x28 (PIN_INPUT | MUX_MODE0) /* gpmc_ad10 */
+ 0x2c (PIN_INPUT | MUX_MODE0) /* gpmc_ad11 */
+ 0x30 (PIN_INPUT | MUX_MODE0) /* gpmc_ad12 */
+ 0x34 (PIN_INPUT | MUX_MODE0) /* gpmc_ad13 */
+ 0x38 (PIN_INPUT | MUX_MODE0) /* gpmc_ad14 */
+ 0x3c (PIN_INPUT | MUX_MODE0) /* gpmc_ad15 */
+ 0xb4 (PIN_OUTPUT | MUX_MODE0) /* gpmc_cs0 */
+ 0xc4 (PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale */
+ 0xcc (PIN_OUTPUT | MUX_MODE0) /* gpmc_wen */
+ 0xc8 (PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren */
+ 0xd0 (PIN_OUTPUT | MUX_MODE0) /* gpmc_ben0 */
+ 0xd8 (PIN_INPUT | MUX_MODE0) /* gpmc_wait0 */
+ >;
+ };
+
+ usb1_pins: pinmux_usb1_pins {
+ pinctrl-single,pins = <
+ 0x280 (PIN_INPUT_SLEW | MUX_MODE0) /* usb1_drvvbus */
+ >;
+ };
+
+ usb2_pins: pinmux_usb2_pins {
+ pinctrl-single,pins = <
+ 0x284 (PIN_INPUT_SLEW | MUX_MODE0) /* usb2_drvvbus */
+ >;
+ };
+
+ tps65917_pins_default: tps65917_pins_default {
+ pinctrl-single,pins = <
+ 0x424 (PIN_INPUT_PULLUP | MUX_MODE1) /* wakeup3.sys_nirq1 */
+ >;
+ };
+
+ mmc1_pins_default: mmc1_pins_default {
+ pinctrl-single,pins = <
+ 0x36c (PIN_INPUT | MUX_MODE14) /* mmc1sdcd.gpio219 */
+ 0x354 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */
+ 0x358 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
+ 0x35c (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
+ 0x360 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
+ 0x364 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
+ 0x368 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */
+ >;
+ };
+
+ mmc2_pins_default: mmc2_pins_default {
+ pinctrl-single,pins = <
+ 0x9c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */
+ 0xb0 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */
+ 0xa0 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */
+ 0xa4 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */
+ 0xa8 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */
+ 0xac (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */
+ 0x8c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */
+ 0x90 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */
+ 0x94 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */
+ 0x98 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */
+ >;
+ };
+
+ dcan1_pins_default: dcan1_pins_default {
+ pinctrl-single,pins = <
+ 0x3d0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */
+ 0x418 (PULL_UP | MUX_MODE1) /* wakeup0.dcan1_rx */
+ >;
+ };
+
+ dcan1_pins_sleep: dcan1_pins_sleep {
+ pinctrl-single,pins = <
+ 0x3d0 (MUX_MODE15 | PULL_UP) /* dcan1_tx.off */
+ 0x418 (MUX_MODE15 | PULL_UP) /* wakeup0.off */
+ >;
+ };
+
+ qspi1_pins: pinmux_qspi1_pins {
+ pinctrl-single,pins = <
+ 0x74 (PIN_OUTPUT | MUX_MODE1) /* gpmc_a13.qspi1_rtclk */
+ 0x78 (PIN_INPUT | MUX_MODE1) /* gpmc_a14.qspi1_d3 */
+ 0x7c (PIN_INPUT | MUX_MODE1) /* gpmc_a15.qspi1_d2 */
+ 0x80 (PIN_INPUT | MUX_MODE1) /* gpmc_a16.qspi1_d1 */
+ 0x84 (PIN_INPUT | MUX_MODE1) /* gpmc_a17.qspi1_d0 */
+ 0x88 (PIN_OUTPUT | MUX_MODE1) /* qpmc_a18.qspi1_sclk */
+ 0xb8 (PIN_OUTPUT | MUX_MODE1) /* gpmc_cs2.qspi1_cs0 */
+ >;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <400000>;
+
+ tps65917: tps65917@58 {
+ compatible = "ti,tps65917";
+ reg = <0x58>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&tps65917_pins_default>;
+
+ interrupts = <GIC_SPI 2 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ ti,system-power-controller;
+
+ tps65917_pmic {
+ compatible = "ti,tps65917-pmic";
+
+ regulators {
+ smps1_reg: smps1 {
+ /* VDD_MPU */
+ regulator-name = "smps1";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps2_reg: smps2 {
+ /* VDD_CORE */
+ regulator-name = "smps2";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1060000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ smps3_reg: smps3 {
+ /* VDD_GPU IVA DSPEVE */
+ regulator-name = "smps3";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ smps4_reg: smps4 {
+ /* VDDS1V8 */
+ regulator-name = "smps4";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps5_reg: smps5 {
+ /* VDD_DDR */
+ regulator-name = "smps5";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1_reg: ldo1 {
+ /* LDO1_OUT --> SDIO */
+ regulator-name = "ldo1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ };
+
+ ldo2_reg: ldo2 {
+ /* LDO2_OUT --> TP1017 (UNUSED) */
+ regulator-name = "ldo2";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo3_reg: ldo3 {
+ /* VDDA_1V8_PHY */
+ regulator-name = "ldo3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo5_reg: ldo5 {
+ /* VDDA_1V8_PLL */
+ regulator-name = "ldo5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo4_reg: ldo4 {
+ /* VDDA_3V_USB: VDDA_USBHS33 */
+ regulator-name = "ldo4";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ };
+ };
+ };
+
+ tps65917_power_button {
+ compatible = "ti,palmas-pwrbutton";
+ interrupt-parent = <&tps65917>;
+ interrupts = <1 IRQ_TYPE_NONE>;
+ wakeup-source;
+ ti,palmas-long-press-seconds = <6>;
+ };
+ };
+
+ pcf_gpio_21: gpio@21 {
+ compatible = "ti,pcf8575";
+ reg = <0x21>;
+ lines-initial-states = <0x1408>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&elm {
+ status = "okay";
+};
+
+&gpmc {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand_default>;
+ ranges = <0 0 0 0x01000000>; /* minimum GPMC partition = 16MB */
+ nand@0,0 {
+ /* To use NAND, DIP switch SW5 must be set like so:
+ * SW5.1 (NAND_SELn) = ON (LOW)
+ * SW5.9 (GPMC_WPN) = OFF (HIGH)
+ */
+ reg = <0 0 4>; /* device IO registers */
+ ti,nand-ecc-opt = "bch8";
+ ti,elm-id = <&elm>;
+ nand-bus-width = <16>;
+ gpmc,device-width = <2>;
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <80>;
+ gpmc,cs-wr-off-ns = <80>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <60>;
+ gpmc,adv-wr-off-ns = <60>;
+ gpmc,we-on-ns = <10>;
+ gpmc,we-off-ns = <50>;
+ gpmc,oe-on-ns = <4>;
+ gpmc,oe-off-ns = <40>;
+ gpmc,access-ns = <40>;
+ gpmc,wr-access-ns = <80>;
+ gpmc,rd-cycle-ns = <80>;
+ gpmc,wr-cycle-ns = <80>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+ /* MTD partition table */
+ /* All SPL-* partitions are sized to minimal length
+ * which can be independently programmable. For
+ * NAND flash this is equal to size of erase-block */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "NAND.SPL";
+ reg = <0x00000000 0x000020000>;
+ };
+ partition@1 {
+ label = "NAND.SPL.backup1";
+ reg = <0x00020000 0x00020000>;
+ };
+ partition@2 {
+ label = "NAND.SPL.backup2";
+ reg = <0x00040000 0x00020000>;
+ };
+ partition@3 {
+ label = "NAND.SPL.backup3";
+ reg = <0x00060000 0x00020000>;
+ };
+ partition@4 {
+ label = "NAND.u-boot-spl-os";
+ reg = <0x00080000 0x00040000>;
+ };
+ partition@5 {
+ label = "NAND.u-boot";
+ reg = <0x000c0000 0x00100000>;
+ };
+ partition@6 {
+ label = "NAND.u-boot-env";
+ reg = <0x001c0000 0x00020000>;
+ };
+ partition@7 {
+ label = "NAND.u-boot-env.backup1";
+ reg = <0x001e0000 0x00020000>;
+ };
+ partition@8 {
+ label = "NAND.kernel";
+ reg = <0x00200000 0x00800000>;
+ };
+ partition@9 {
+ label = "NAND.file-system";
+ reg = <0x00a00000 0x0f600000>;
+ };
+ };
+};
+
+&usb2_phy1 {
+ phy-supply = <&ldo4_reg>;
+};
+
+&usb2_phy2 {
+ phy-supply = <&ldo4_reg>;
+};
+
+&omap_dwc3_1 {
+ extcon = <&extcon_usb1>;
+};
+
+&omap_dwc3_2 {
+ extcon = <&extcon_usb2>;
+};
+
+&usb1 {
+ dr_mode = "peripheral";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_pins>;
+};
+
+&usb2 {
+ dr_mode = "host";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb2_pins>;
+};
+
+&mmc1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins_default>;
+
+ vmmc-supply = <&ldo1_reg>;
+ bus-width = <4>;
+ /*
+ * SDCD signal is not being used here - using the fact that GPIO mode
+ * is a viable alternative
+ */
+ cd-gpios = <&gpio6 27 0>;
+};
+
+&mmc2 {
+ /* SW5-3 in ON position */
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins_default>;
+
+ vmmc-supply = <&evm_3v3>;
+ bus-width = <8>;
+ ti,non-removable;
+};
+
+&dra7_pmx_core {
+ cpsw_default: cpsw_default {
+ pinctrl-single,pins = <
+ /* Slave 2 */
+ 0x198 (PIN_OUTPUT | MUX_MODE3) /* vin2a_d12.rgmii1_txc */
+ 0x19c (PIN_OUTPUT | MUX_MODE3) /* vin2a_d13.rgmii1_tctl */
+ 0x1a0 (PIN_OUTPUT | MUX_MODE3) /* vin2a_d14.rgmii1_td3 */
+ 0x1a4 (PIN_OUTPUT | MUX_MODE3) /* vin2a_d15.rgmii1_td2 */
+ 0x1a8 (PIN_OUTPUT | MUX_MODE3) /* vin2a_d16.rgmii1_td1 */
+ 0x1ac (PIN_OUTPUT | MUX_MODE3) /* vin2a_d17.rgmii1_td0 */
+ 0x1b0 (PIN_INPUT | MUX_MODE3) /* vin2a_d18.rgmii1_rclk */
+ 0x1b4 (PIN_INPUT | MUX_MODE3) /* vin2a_d19.rgmii1_rctl */
+ 0x1b8 (PIN_INPUT | MUX_MODE3) /* vin2a_d20.rgmii1_rd3 */
+ 0x1bc (PIN_INPUT | MUX_MODE3) /* vin2a_d21.rgmii1_rd2 */
+ 0x1c0 (PIN_INPUT | MUX_MODE3) /* vin2a_d22.rgmii1_rd1 */
+ 0x1c4 (PIN_INPUT | MUX_MODE3) /* vin2a_d23.rgmii1_rd0 */
+ >;
+
+ };
+
+ cpsw_sleep: cpsw_sleep {
+ pinctrl-single,pins = <
+ /* Slave 2 */
+ 0x198 (MUX_MODE15)
+ 0x19c (MUX_MODE15)
+ 0x1a0 (MUX_MODE15)
+ 0x1a4 (MUX_MODE15)
+ 0x1a8 (MUX_MODE15)
+ 0x1ac (MUX_MODE15)
+ 0x1b0 (MUX_MODE15)
+ 0x1b4 (MUX_MODE15)
+ 0x1b8 (MUX_MODE15)
+ 0x1bc (MUX_MODE15)
+ 0x1c0 (MUX_MODE15)
+ 0x1c4 (MUX_MODE15)
+ >;
+ };
+
+ davinci_mdio_default: davinci_mdio_default {
+ pinctrl-single,pins = <
+ /* MDIO */
+ 0x23c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_d.mdio_d */
+ 0x240 (PIN_INPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
+ >;
+ };
+
+ davinci_mdio_sleep: davinci_mdio_sleep {
+ pinctrl-single,pins = <
+ 0x23c (MUX_MODE15)
+ 0x240 (MUX_MODE15)
+ >;
+ };
+};
+
+&mac {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <3>;
+ phy-mode = "rgmii";
+};
+
+&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
+ active_slave = <1>;
+};
+
+&dcan1 {
+ status = "ok";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&dcan1_pins_default>;
+ pinctrl-1 = <&dcan1_pins_sleep>;
+};
+
+&qspi {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&qspi1_pins>;
+
+ spi-max-frequency = <48000000>;
+ m25p80@0 {
+ compatible = "s25fl256s1";
+ spi-max-frequency = <48000000>;
+ reg = <0>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ spi-cpol;
+ spi-cpha;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /* MTD partition table.
+ * The ROM checks the first four physical blocks
+ * for a valid file to boot and the flash here is
+ * 64KiB block size.
+ */
+ partition@0 {
+ label = "QSPI.SPL";
+ reg = <0x00000000 0x000010000>;
+ };
+ partition@1 {
+ label = "QSPI.SPL.backup1";
+ reg = <0x00010000 0x00010000>;
+ };
+ partition@2 {
+ label = "QSPI.SPL.backup2";
+ reg = <0x00020000 0x00010000>;
+ };
+ partition@3 {
+ label = "QSPI.SPL.backup3";
+ reg = <0x00030000 0x00010000>;
+ };
+ partition@4 {
+ label = "QSPI.u-boot";
+ reg = <0x00040000 0x00100000>;
+ };
+ partition@5 {
+ label = "QSPI.u-boot-spl-os";
+ reg = <0x00140000 0x00080000>;
+ };
+ partition@6 {
+ label = "QSPI.u-boot-env";
+ reg = <0x001c0000 0x00010000>;
+ };
+ partition@7 {
+ label = "QSPI.u-boot-env.backup1";
+ reg = <0x001d0000 0x0010000>;
+ };
+ partition@8 {
+ label = "QSPI.kernel";
+ reg = <0x001e0000 0x0800000>;
+ };
+ partition@9 {
+ label = "QSPI.file-system";
+ reg = <0x009e0000 0x01620000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/dra72x.dtsi b/arch/arm/boot/dts/dra72x.dtsi
new file mode 100644
index 000000000..03d742f8d
--- /dev/null
+++ b/arch/arm/boot/dts/dra72x.dtsi
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014 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.
+ * Based on "omap4.dtsi"
+ */
+
+#include "dra7.dtsi"
+
+/ {
+ compatible = "ti,dra722", "ti,dra72", "ti,dra7";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0>;
+
+ /* cooling options */
+ cooling-min-level = <0>;
+ cooling-max-level = <2>;
+ #cooling-cells = <2>; /* min followed by max */
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a15-pmu";
+ interrupt-parent = <&wakeupgen>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+ };
+};
diff --git a/arch/arm/boot/dts/dra74x.dtsi b/arch/arm/boot/dts/dra74x.dtsi
new file mode 100644
index 000000000..cc560a709
--- /dev/null
+++ b/arch/arm/boot/dts/dra74x.dtsi
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2014 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.
+ * Based on "omap4.dtsi"
+ */
+
+#include "dra7.dtsi"
+
+/ {
+ compatible = "ti,dra742", "ti,dra74", "ti,dra7";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0>;
+
+ operating-points = <
+ /* kHz uV */
+ 1000000 1060000
+ 1176000 1160000
+ >;
+
+ clocks = <&dpll_mpu_ck>;
+ clock-names = "cpu";
+
+ clock-latency = <300000>; /* From omap-cpufreq driver */
+
+ /* cooling options */
+ cooling-min-level = <0>;
+ cooling-max-level = <2>;
+ #cooling-cells = <2>; /* min followed by max */
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <1>;
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a15-pmu";
+ interrupt-parent = <&wakeupgen>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ ocp {
+ omap_dwc3_4: omap_dwc3_4@48940000 {
+ compatible = "ti,dwc3";
+ ti,hwmods = "usb_otg_ss4";
+ reg = <0x48940000 0x10000>;
+ interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ utmi-mode = <2>;
+ ranges;
+ status = "disabled";
+ usb4: usb@48950000 {
+ compatible = "snps,dwc3";
+ reg = <0x48950000 0x17000>;
+ interrupts = <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>;
+ tx-fifo-resize;
+ maximum-speed = "high-speed";
+ dr_mode = "otg";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/dra7xx-clocks.dtsi b/arch/arm/boot/dts/dra7xx-clocks.dtsi
new file mode 100644
index 000000000..3b933f74d
--- /dev/null
+++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi
@@ -0,0 +1,2138 @@
+/*
+ * Device Tree Source for DRA7xx clock data
+ *
+ * Copyright (C) 2013 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.
+ */
+&cm_core_aon_clocks {
+ atl_clkin0_ck: atl_clkin0_ck {
+ #clock-cells = <0>;
+ compatible = "ti,dra7-atl-clock";
+ clocks = <&atl_gfclk_mux>;
+ };
+
+ atl_clkin1_ck: atl_clkin1_ck {
+ #clock-cells = <0>;
+ compatible = "ti,dra7-atl-clock";
+ clocks = <&atl_gfclk_mux>;
+ };
+
+ atl_clkin2_ck: atl_clkin2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,dra7-atl-clock";
+ clocks = <&atl_gfclk_mux>;
+ };
+
+ atl_clkin3_ck: atl_clkin3_ck {
+ #clock-cells = <0>;
+ compatible = "ti,dra7-atl-clock";
+ clocks = <&atl_gfclk_mux>;
+ };
+
+ hdmi_clkin_ck: hdmi_clkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ mlb_clkin_ck: mlb_clkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ mlbp_clkin_ck: mlbp_clkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ pciesref_acs_clk_ck: pciesref_acs_clk_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <100000000>;
+ };
+
+ ref_clkin0_ck: ref_clkin0_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ ref_clkin1_ck: ref_clkin1_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ ref_clkin2_ck: ref_clkin2_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ ref_clkin3_ck: ref_clkin3_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ rmii_clk_ck: rmii_clk_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ sdvenc_clkin_ck: sdvenc_clkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ secure_32k_clk_src_ck: secure_32k_clk_src_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ sys_32k_ck: sys_32k_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ virt_12000000_ck: virt_12000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ virt_13000000_ck: virt_13000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ };
+
+ virt_16800000_ck: virt_16800000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <16800000>;
+ };
+
+ virt_19200000_ck: virt_19200000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <19200000>;
+ };
+
+ virt_20000000_ck: virt_20000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <20000000>;
+ };
+
+ virt_26000000_ck: virt_26000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ };
+
+ virt_27000000_ck: virt_27000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <27000000>;
+ };
+
+ virt_38400000_ck: virt_38400000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <38400000>;
+ };
+
+ sys_clkin2: sys_clkin2 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <22579200>;
+ };
+
+ usb_otg_clkin_ck: usb_otg_clkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ video1_clkin_ck: video1_clkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ video1_m2_clkin_ck: video1_m2_clkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ video2_clkin_ck: video2_clkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ video2_m2_clkin_ck: video2_m2_clkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ dpll_abe_ck: dpll_abe_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-m4xen-clock";
+ clocks = <&abe_dpll_clk_mux>, <&abe_dpll_bypass_clk_mux>;
+ reg = <0x01e0>, <0x01e4>, <0x01ec>, <0x01e8>;
+ };
+
+ dpll_abe_x2_ck: dpll_abe_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-x2-clock";
+ clocks = <&dpll_abe_ck>;
+ };
+
+ dpll_abe_m2x2_ck: dpll_abe_m2x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_abe_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x01f0>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ abe_clk: abe_clk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_abe_m2x2_ck>;
+ ti,max-div = <4>;
+ reg = <0x0108>;
+ ti,index-power-of-two;
+ };
+
+ dpll_abe_m2_ck: dpll_abe_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_abe_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x01f0>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_abe_m3x2_ck: dpll_abe_m3x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_abe_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x01f4>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_core_byp_mux: dpll_core_byp_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+ ti,bit-shift = <23>;
+ reg = <0x012c>;
+ };
+
+ dpll_core_ck: dpll_core_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-core-clock";
+ clocks = <&sys_clkin1>, <&dpll_core_byp_mux>;
+ reg = <0x0120>, <0x0124>, <0x012c>, <0x0128>;
+ };
+
+ dpll_core_x2_ck: dpll_core_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-x2-clock";
+ clocks = <&dpll_core_ck>;
+ };
+
+ dpll_core_h12x2_ck: dpll_core_h12x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <63>;
+ ti,autoidle-shift = <8>;
+ reg = <0x013c>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ mpu_dpll_hs_clk_div: mpu_dpll_hs_clk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_h12x2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll_mpu_ck: dpll_mpu_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap5-mpu-dpll-clock";
+ clocks = <&sys_clkin1>, <&mpu_dpll_hs_clk_div>;
+ reg = <0x0160>, <0x0164>, <0x016c>, <0x0168>;
+ };
+
+ dpll_mpu_m2_ck: dpll_mpu_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_mpu_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0170>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ mpu_dclk_div: mpu_dclk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_mpu_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dsp_dpll_hs_clk_div: dsp_dpll_hs_clk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_h12x2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll_dsp_byp_mux: dpll_dsp_byp_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>;
+ ti,bit-shift = <23>;
+ reg = <0x0240>;
+ };
+
+ dpll_dsp_ck: dpll_dsp_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-clock";
+ clocks = <&sys_clkin1>, <&dpll_dsp_byp_mux>;
+ reg = <0x0234>, <0x0238>, <0x0240>, <0x023c>;
+ };
+
+ dpll_dsp_m2_ck: dpll_dsp_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_dsp_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0244>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ iva_dpll_hs_clk_div: iva_dpll_hs_clk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_h12x2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll_iva_byp_mux: dpll_iva_byp_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>;
+ ti,bit-shift = <23>;
+ reg = <0x01ac>;
+ };
+
+ dpll_iva_ck: dpll_iva_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-clock";
+ clocks = <&sys_clkin1>, <&dpll_iva_byp_mux>;
+ reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>;
+ };
+
+ dpll_iva_m2_ck: dpll_iva_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_iva_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x01b0>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ iva_dclk: iva_dclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_iva_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll_gpu_byp_mux: dpll_gpu_byp_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+ ti,bit-shift = <23>;
+ reg = <0x02e4>;
+ };
+
+ dpll_gpu_ck: dpll_gpu_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-clock";
+ clocks = <&sys_clkin1>, <&dpll_gpu_byp_mux>;
+ reg = <0x02d8>, <0x02dc>, <0x02e4>, <0x02e0>;
+ };
+
+ dpll_gpu_m2_ck: dpll_gpu_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_gpu_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x02e8>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_core_m2_ck: dpll_core_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0130>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ core_dpll_out_dclk_div: core_dpll_out_dclk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll_ddr_byp_mux: dpll_ddr_byp_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+ ti,bit-shift = <23>;
+ reg = <0x021c>;
+ };
+
+ dpll_ddr_ck: dpll_ddr_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-clock";
+ clocks = <&sys_clkin1>, <&dpll_ddr_byp_mux>;
+ reg = <0x0210>, <0x0214>, <0x021c>, <0x0218>;
+ };
+
+ dpll_ddr_m2_ck: dpll_ddr_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_ddr_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0220>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_gmac_byp_mux: dpll_gmac_byp_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+ ti,bit-shift = <23>;
+ reg = <0x02b4>;
+ };
+
+ dpll_gmac_ck: dpll_gmac_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-clock";
+ clocks = <&sys_clkin1>, <&dpll_gmac_byp_mux>;
+ reg = <0x02a8>, <0x02ac>, <0x02b4>, <0x02b0>;
+ };
+
+ dpll_gmac_m2_ck: dpll_gmac_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_gmac_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x02b8>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ video2_dclk_div: video2_dclk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&video2_m2_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ video1_dclk_div: video1_dclk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&video1_m2_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ hdmi_dclk_div: hdmi_dclk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&hdmi_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ per_dpll_hs_clk_div: per_dpll_hs_clk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_abe_m3x2_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ usb_dpll_hs_clk_div: usb_dpll_hs_clk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_abe_m3x2_ck>;
+ clock-mult = <1>;
+ clock-div = <3>;
+ };
+
+ eve_dpll_hs_clk_div: eve_dpll_hs_clk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_h12x2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll_eve_byp_mux: dpll_eve_byp_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>;
+ ti,bit-shift = <23>;
+ reg = <0x0290>;
+ };
+
+ dpll_eve_ck: dpll_eve_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-clock";
+ clocks = <&sys_clkin1>, <&dpll_eve_byp_mux>;
+ reg = <0x0284>, <0x0288>, <0x0290>, <0x028c>;
+ };
+
+ dpll_eve_m2_ck: dpll_eve_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_eve_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0294>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ eve_dclk_div: eve_dclk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_eve_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll_core_h13x2_ck: dpll_core_h13x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <63>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0140>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_core_h14x2_ck: dpll_core_h14x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <63>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0144>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_core_h22x2_ck: dpll_core_h22x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <63>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0154>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_core_h23x2_ck: dpll_core_h23x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <63>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0158>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_core_h24x2_ck: dpll_core_h24x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <63>;
+ ti,autoidle-shift = <8>;
+ reg = <0x015c>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_ddr_x2_ck: dpll_ddr_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-x2-clock";
+ clocks = <&dpll_ddr_ck>;
+ };
+
+ dpll_ddr_h11x2_ck: dpll_ddr_h11x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_ddr_x2_ck>;
+ ti,max-div = <63>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0228>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_dsp_x2_ck: dpll_dsp_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-x2-clock";
+ clocks = <&dpll_dsp_ck>;
+ };
+
+ dpll_dsp_m3x2_ck: dpll_dsp_m3x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_dsp_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0248>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_gmac_x2_ck: dpll_gmac_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-x2-clock";
+ clocks = <&dpll_gmac_ck>;
+ };
+
+ dpll_gmac_h11x2_ck: dpll_gmac_h11x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_gmac_x2_ck>;
+ ti,max-div = <63>;
+ ti,autoidle-shift = <8>;
+ reg = <0x02c0>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_gmac_h12x2_ck: dpll_gmac_h12x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_gmac_x2_ck>;
+ ti,max-div = <63>;
+ ti,autoidle-shift = <8>;
+ reg = <0x02c4>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_gmac_h13x2_ck: dpll_gmac_h13x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_gmac_x2_ck>;
+ ti,max-div = <63>;
+ ti,autoidle-shift = <8>;
+ reg = <0x02c8>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_gmac_m3x2_ck: dpll_gmac_m3x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_gmac_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x02bc>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ gmii_m_clk_div: gmii_m_clk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_gmac_h11x2_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ hdmi_clk2_div: hdmi_clk2_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&hdmi_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ hdmi_div_clk: hdmi_div_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&hdmi_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ l3_iclk_div: l3_iclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ ti,max-div = <2>;
+ ti,bit-shift = <4>;
+ reg = <0x0100>;
+ clocks = <&dpll_core_h12x2_ck>;
+ ti,index-power-of-two;
+ };
+
+ l4_root_clk_div: l4_root_clk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&l3_iclk_div>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ video1_clk2_div: video1_clk2_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&video1_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ video1_div_clk: video1_div_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&video1_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ video2_clk2_div: video2_clk2_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&video2_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ video2_div_clk: video2_div_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&video2_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ ipu1_gfclk_mux: ipu1_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dpll_abe_m2x2_ck>, <&dpll_core_h22x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x0520>;
+ };
+
+ mcasp1_ahclkr_mux: mcasp1_ahclkr_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>;
+ ti,bit-shift = <28>;
+ reg = <0x0550>;
+ };
+
+ mcasp1_ahclkx_mux: mcasp1_ahclkx_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x0550>;
+ };
+
+ mcasp1_aux_gfclk_mux: mcasp1_aux_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>;
+ ti,bit-shift = <22>;
+ reg = <0x0550>;
+ };
+
+ timer5_gfclk_mux: timer5_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>, <&clkoutmux0_clk_mux>;
+ ti,bit-shift = <24>;
+ reg = <0x0558>;
+ };
+
+ timer6_gfclk_mux: timer6_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>, <&clkoutmux0_clk_mux>;
+ ti,bit-shift = <24>;
+ reg = <0x0560>;
+ };
+
+ timer7_gfclk_mux: timer7_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>, <&clkoutmux0_clk_mux>;
+ ti,bit-shift = <24>;
+ reg = <0x0568>;
+ };
+
+ timer8_gfclk_mux: timer8_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>, <&clkoutmux0_clk_mux>;
+ ti,bit-shift = <24>;
+ reg = <0x0570>;
+ };
+
+ uart6_gfclk_mux: uart6_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x0580>;
+ };
+
+ dummy_ck: dummy_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+};
+&prm_clocks {
+ sys_clkin1: sys_clkin1 {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&virt_12000000_ck>, <&virt_20000000_ck>, <&virt_16800000_ck>, <&virt_19200000_ck>, <&virt_26000000_ck>, <&virt_27000000_ck>, <&virt_38400000_ck>;
+ reg = <0x0110>;
+ ti,index-starts-at-one;
+ };
+
+ abe_dpll_sys_clk_mux: abe_dpll_sys_clk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin1>, <&sys_clkin2>;
+ reg = <0x0118>;
+ };
+
+ abe_dpll_bypass_clk_mux: abe_dpll_bypass_clk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_dpll_sys_clk_mux>, <&sys_32k_ck>;
+ reg = <0x0114>;
+ };
+
+ abe_dpll_clk_mux: abe_dpll_clk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_dpll_sys_clk_mux>, <&sys_32k_ck>;
+ reg = <0x010c>;
+ };
+
+ abe_24m_fclk: abe_24m_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_abe_m2x2_ck>;
+ reg = <0x011c>;
+ ti,dividers = <8>, <16>;
+ };
+
+ aess_fclk: aess_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&abe_clk>;
+ reg = <0x0178>;
+ ti,max-div = <2>;
+ };
+
+ abe_giclk_div: abe_giclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&aess_fclk>;
+ reg = <0x0174>;
+ ti,max-div = <2>;
+ };
+
+ abe_lp_clk_div: abe_lp_clk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_abe_m2x2_ck>;
+ reg = <0x01d8>;
+ ti,dividers = <16>, <32>;
+ };
+
+ abe_sys_clk_div: abe_sys_clk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&sys_clkin1>;
+ reg = <0x0120>;
+ ti,max-div = <2>;
+ };
+
+ adc_gfclk_mux: adc_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin1>, <&sys_clkin2>, <&sys_32k_ck>;
+ reg = <0x01dc>;
+ };
+
+ sys_clk1_dclk_div: sys_clk1_dclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&sys_clkin1>;
+ ti,max-div = <64>;
+ reg = <0x01c8>;
+ ti,index-power-of-two;
+ };
+
+ sys_clk2_dclk_div: sys_clk2_dclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&sys_clkin2>;
+ ti,max-div = <64>;
+ reg = <0x01cc>;
+ ti,index-power-of-two;
+ };
+
+ per_abe_x1_dclk_div: per_abe_x1_dclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_abe_m2_ck>;
+ ti,max-div = <64>;
+ reg = <0x01bc>;
+ ti,index-power-of-two;
+ };
+
+ dsp_gclk_div: dsp_gclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_dsp_m2_ck>;
+ ti,max-div = <64>;
+ reg = <0x018c>;
+ ti,index-power-of-two;
+ };
+
+ gpu_dclk: gpu_dclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_gpu_m2_ck>;
+ ti,max-div = <64>;
+ reg = <0x01a0>;
+ ti,index-power-of-two;
+ };
+
+ emif_phy_dclk_div: emif_phy_dclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_ddr_m2_ck>;
+ ti,max-div = <64>;
+ reg = <0x0190>;
+ ti,index-power-of-two;
+ };
+
+ gmac_250m_dclk_div: gmac_250m_dclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_gmac_m2_ck>;
+ ti,max-div = <64>;
+ reg = <0x019c>;
+ ti,index-power-of-two;
+ };
+
+ l3init_480m_dclk_div: l3init_480m_dclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_usb_m2_ck>;
+ ti,max-div = <64>;
+ reg = <0x01ac>;
+ ti,index-power-of-two;
+ };
+
+ usb_otg_dclk_div: usb_otg_dclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&usb_otg_clkin_ck>;
+ ti,max-div = <64>;
+ reg = <0x0184>;
+ ti,index-power-of-two;
+ };
+
+ sata_dclk_div: sata_dclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&sys_clkin1>;
+ ti,max-div = <64>;
+ reg = <0x01c0>;
+ ti,index-power-of-two;
+ };
+
+ pcie2_dclk_div: pcie2_dclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_pcie_ref_m2_ck>;
+ ti,max-div = <64>;
+ reg = <0x01b8>;
+ ti,index-power-of-two;
+ };
+
+ pcie_dclk_div: pcie_dclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&apll_pcie_m2_ck>;
+ ti,max-div = <64>;
+ reg = <0x01b4>;
+ ti,index-power-of-two;
+ };
+
+ emu_dclk_div: emu_dclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&sys_clkin1>;
+ ti,max-div = <64>;
+ reg = <0x0194>;
+ ti,index-power-of-two;
+ };
+
+ secure_32k_dclk_div: secure_32k_dclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&secure_32k_clk_src_ck>;
+ ti,max-div = <64>;
+ reg = <0x01c4>;
+ ti,index-power-of-two;
+ };
+
+ clkoutmux0_clk_mux: clkoutmux0_clk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clk1_dclk_div>, <&sys_clk2_dclk_div>, <&per_abe_x1_dclk_div>, <&mpu_dclk_div>, <&dsp_gclk_div>, <&iva_dclk>, <&gpu_dclk>, <&core_dpll_out_dclk_div>, <&emif_phy_dclk_div>, <&gmac_250m_dclk_div>, <&video2_dclk_div>, <&video1_dclk_div>, <&hdmi_dclk_div>, <&func_96m_aon_dclk_div>, <&l3init_480m_dclk_div>, <&usb_otg_dclk_div>, <&sata_dclk_div>, <&pcie2_dclk_div>, <&pcie_dclk_div>, <&emu_dclk_div>, <&secure_32k_dclk_div>, <&eve_dclk_div>;
+ reg = <0x0158>;
+ };
+
+ clkoutmux1_clk_mux: clkoutmux1_clk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clk1_dclk_div>, <&sys_clk2_dclk_div>, <&per_abe_x1_dclk_div>, <&mpu_dclk_div>, <&dsp_gclk_div>, <&iva_dclk>, <&gpu_dclk>, <&core_dpll_out_dclk_div>, <&emif_phy_dclk_div>, <&gmac_250m_dclk_div>, <&video2_dclk_div>, <&video1_dclk_div>, <&hdmi_dclk_div>, <&func_96m_aon_dclk_div>, <&l3init_480m_dclk_div>, <&usb_otg_dclk_div>, <&sata_dclk_div>, <&pcie2_dclk_div>, <&pcie_dclk_div>, <&emu_dclk_div>, <&secure_32k_dclk_div>, <&eve_dclk_div>;
+ reg = <0x015c>;
+ };
+
+ clkoutmux2_clk_mux: clkoutmux2_clk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clk1_dclk_div>, <&sys_clk2_dclk_div>, <&per_abe_x1_dclk_div>, <&mpu_dclk_div>, <&dsp_gclk_div>, <&iva_dclk>, <&gpu_dclk>, <&core_dpll_out_dclk_div>, <&emif_phy_dclk_div>, <&gmac_250m_dclk_div>, <&video2_dclk_div>, <&video1_dclk_div>, <&hdmi_dclk_div>, <&func_96m_aon_dclk_div>, <&l3init_480m_dclk_div>, <&usb_otg_dclk_div>, <&sata_dclk_div>, <&pcie2_dclk_div>, <&pcie_dclk_div>, <&emu_dclk_div>, <&secure_32k_dclk_div>, <&eve_dclk_div>;
+ reg = <0x0160>;
+ };
+
+ custefuse_sys_gfclk_div: custefuse_sys_gfclk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin1>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ eve_clk: eve_clk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dpll_eve_m2_ck>, <&dpll_dsp_m3x2_ck>;
+ reg = <0x0180>;
+ };
+
+ hdmi_dpll_clk_mux: hdmi_dpll_clk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin1>, <&sys_clkin2>;
+ reg = <0x0164>;
+ };
+
+ mlb_clk: mlb_clk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&mlb_clkin_ck>;
+ ti,max-div = <64>;
+ reg = <0x0134>;
+ ti,index-power-of-two;
+ };
+
+ mlbp_clk: mlbp_clk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&mlbp_clkin_ck>;
+ ti,max-div = <64>;
+ reg = <0x0130>;
+ ti,index-power-of-two;
+ };
+
+ per_abe_x1_gfclk2_div: per_abe_x1_gfclk2_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_abe_m2_ck>;
+ ti,max-div = <64>;
+ reg = <0x0138>;
+ ti,index-power-of-two;
+ };
+
+ timer_sys_clk_div: timer_sys_clk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&sys_clkin1>;
+ reg = <0x0144>;
+ ti,max-div = <2>;
+ };
+
+ video1_dpll_clk_mux: video1_dpll_clk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin1>, <&sys_clkin2>;
+ reg = <0x0168>;
+ };
+
+ video2_dpll_clk_mux: video2_dpll_clk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin1>, <&sys_clkin2>;
+ reg = <0x016c>;
+ };
+
+ wkupaon_iclk_mux: wkupaon_iclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin1>, <&abe_lp_clk_div>;
+ reg = <0x0108>;
+ };
+
+ gpio1_dbclk: gpio1_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1838>;
+ };
+
+ dcan1_sys_clk_mux: dcan1_sys_clk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin1>, <&sys_clkin2>;
+ ti,bit-shift = <24>;
+ reg = <0x1888>;
+ };
+
+ timer1_gfclk_mux: timer1_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x1840>;
+ };
+
+ uart10_gfclk_mux: uart10_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1880>;
+ };
+};
+&cm_core_clocks {
+ dpll_pcie_ref_ck: dpll_pcie_ref_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-clock";
+ clocks = <&sys_clkin1>, <&sys_clkin1>;
+ reg = <0x0200>, <0x0204>, <0x020c>, <0x0208>;
+ };
+
+ dpll_pcie_ref_m2ldo_ck: dpll_pcie_ref_m2ldo_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_pcie_ref_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0210>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ apll_pcie_in_clk_mux: apll_pcie_in_clk_mux@4ae06118 {
+ compatible = "ti,mux-clock";
+ clocks = <&dpll_pcie_ref_m2ldo_ck>, <&pciesref_acs_clk_ck>;
+ #clock-cells = <0>;
+ reg = <0x021c 0x4>;
+ ti,bit-shift = <7>;
+ };
+
+ apll_pcie_ck: apll_pcie_ck {
+ #clock-cells = <0>;
+ compatible = "ti,dra7-apll-clock";
+ clocks = <&apll_pcie_in_clk_mux>, <&dpll_pcie_ref_ck>;
+ reg = <0x021c>, <0x0220>;
+ };
+
+ optfclk_pciephy1_32khz: optfclk_pciephy1_32khz@4a0093b0 {
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ #clock-cells = <0>;
+ reg = <0x13b0>;
+ ti,bit-shift = <8>;
+ };
+
+ optfclk_pciephy2_32khz: optfclk_pciephy2_32khz@4a0093b8 {
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ #clock-cells = <0>;
+ reg = <0x13b8>;
+ ti,bit-shift = <8>;
+ };
+
+ optfclk_pciephy_div: optfclk_pciephy_div@4a00821c {
+ compatible = "ti,divider-clock";
+ clocks = <&apll_pcie_ck>;
+ #clock-cells = <0>;
+ reg = <0x021c>;
+ ti,dividers = <2>, <1>;
+ ti,bit-shift = <8>;
+ ti,max-div = <2>;
+ };
+
+ optfclk_pciephy1_clk: optfclk_pciephy1_clk@4a0093b0 {
+ compatible = "ti,gate-clock";
+ clocks = <&apll_pcie_ck>;
+ #clock-cells = <0>;
+ reg = <0x13b0>;
+ ti,bit-shift = <9>;
+ };
+
+ optfclk_pciephy2_clk: optfclk_pciephy2_clk@4a0093b8 {
+ compatible = "ti,gate-clock";
+ clocks = <&apll_pcie_ck>;
+ #clock-cells = <0>;
+ reg = <0x13b8>;
+ ti,bit-shift = <9>;
+ };
+
+ optfclk_pciephy1_div_clk: optfclk_pciephy1_div_clk@4a0093b0 {
+ compatible = "ti,gate-clock";
+ clocks = <&optfclk_pciephy_div>;
+ #clock-cells = <0>;
+ reg = <0x13b0>;
+ ti,bit-shift = <10>;
+ };
+
+ optfclk_pciephy2_div_clk: optfclk_pciephy2_div_clk@4a0093b8 {
+ compatible = "ti,gate-clock";
+ clocks = <&optfclk_pciephy_div>;
+ #clock-cells = <0>;
+ reg = <0x13b8>;
+ ti,bit-shift = <10>;
+ };
+
+ apll_pcie_clkvcoldo: apll_pcie_clkvcoldo {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&apll_pcie_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ apll_pcie_clkvcoldo_div: apll_pcie_clkvcoldo_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&apll_pcie_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ apll_pcie_m2_ck: apll_pcie_m2_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&apll_pcie_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll_per_byp_mux: dpll_per_byp_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>;
+ ti,bit-shift = <23>;
+ reg = <0x014c>;
+ };
+
+ dpll_per_ck: dpll_per_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-clock";
+ clocks = <&sys_clkin1>, <&dpll_per_byp_mux>;
+ reg = <0x0140>, <0x0144>, <0x014c>, <0x0148>;
+ };
+
+ dpll_per_m2_ck: dpll_per_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0150>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ func_96m_aon_dclk_div: func_96m_aon_dclk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll_usb_byp_mux: dpll_usb_byp_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>;
+ ti,bit-shift = <23>;
+ reg = <0x018c>;
+ };
+
+ dpll_usb_ck: dpll_usb_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-j-type-clock";
+ clocks = <&sys_clkin1>, <&dpll_usb_byp_mux>;
+ reg = <0x0180>, <0x0184>, <0x018c>, <0x0188>;
+ };
+
+ dpll_usb_m2_ck: dpll_usb_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_usb_ck>;
+ ti,max-div = <127>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0190>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_pcie_ref_m2_ck: dpll_pcie_ref_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_pcie_ref_ck>;
+ ti,max-div = <127>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0210>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_per_x2_ck: dpll_per_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-x2-clock";
+ clocks = <&dpll_per_ck>;
+ };
+
+ dpll_per_h11x2_ck: dpll_per_h11x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,max-div = <63>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0158>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_per_h12x2_ck: dpll_per_h12x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,max-div = <63>;
+ ti,autoidle-shift = <8>;
+ reg = <0x015c>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_per_h13x2_ck: dpll_per_h13x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,max-div = <63>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0160>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_per_h14x2_ck: dpll_per_h14x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,max-div = <63>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0164>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_per_m2x2_ck: dpll_per_m2x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0150>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_usb_clkdcoldo: dpll_usb_clkdcoldo {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_usb_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ func_128m_clk: func_128m_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_h11x2_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ func_12m_fclk: func_12m_fclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2x2_ck>;
+ clock-mult = <1>;
+ clock-div = <16>;
+ };
+
+ func_24m_clk: func_24m_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ func_48m_fclk: func_48m_fclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2x2_ck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ func_96m_fclk: func_96m_fclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2x2_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ l3init_60m_fclk: l3init_60m_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_usb_m2_ck>;
+ reg = <0x0104>;
+ ti,dividers = <1>, <8>;
+ };
+
+ clkout2_clk: clkout2_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&clkoutmux2_clk_mux>;
+ ti,bit-shift = <8>;
+ reg = <0x06b0>;
+ };
+
+ l3init_960m_gfclk: l3init_960m_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_usb_clkdcoldo>;
+ ti,bit-shift = <8>;
+ reg = <0x06c0>;
+ };
+
+ dss_32khz_clk: dss_32khz_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <11>;
+ reg = <0x1120>;
+ };
+
+ dss_48mhz_clk: dss_48mhz_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&func_48m_fclk>;
+ ti,bit-shift = <9>;
+ reg = <0x1120>;
+ };
+
+ dss_dss_clk: dss_dss_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_per_h12x2_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1120>;
+ };
+
+ dss_hdmi_clk: dss_hdmi_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&hdmi_dpll_clk_mux>;
+ ti,bit-shift = <10>;
+ reg = <0x1120>;
+ };
+
+ dss_video1_clk: dss_video1_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&video1_dpll_clk_mux>;
+ ti,bit-shift = <12>;
+ reg = <0x1120>;
+ };
+
+ dss_video2_clk: dss_video2_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&video2_dpll_clk_mux>;
+ ti,bit-shift = <13>;
+ reg = <0x1120>;
+ };
+
+ gpio2_dbclk: gpio2_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1760>;
+ };
+
+ gpio3_dbclk: gpio3_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1768>;
+ };
+
+ gpio4_dbclk: gpio4_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1770>;
+ };
+
+ gpio5_dbclk: gpio5_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1778>;
+ };
+
+ gpio6_dbclk: gpio6_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1780>;
+ };
+
+ gpio7_dbclk: gpio7_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1810>;
+ };
+
+ gpio8_dbclk: gpio8_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1818>;
+ };
+
+ mmc1_clk32k: mmc1_clk32k {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1328>;
+ };
+
+ mmc2_clk32k: mmc2_clk32k {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1330>;
+ };
+
+ mmc3_clk32k: mmc3_clk32k {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1820>;
+ };
+
+ mmc4_clk32k: mmc4_clk32k {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1828>;
+ };
+
+ sata_ref_clk: sata_ref_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_clkin1>;
+ ti,bit-shift = <8>;
+ reg = <0x1388>;
+ };
+
+ usb_otg_ss1_refclk960m: usb_otg_ss1_refclk960m {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l3init_960m_gfclk>;
+ ti,bit-shift = <8>;
+ reg = <0x13f0>;
+ };
+
+ usb_otg_ss2_refclk960m: usb_otg_ss2_refclk960m {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l3init_960m_gfclk>;
+ ti,bit-shift = <8>;
+ reg = <0x1340>;
+ };
+
+ usb_phy1_always_on_clk32k: usb_phy1_always_on_clk32k {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0640>;
+ };
+
+ usb_phy2_always_on_clk32k: usb_phy2_always_on_clk32k {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0688>;
+ };
+
+ usb_phy3_always_on_clk32k: usb_phy3_always_on_clk32k {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0698>;
+ };
+
+ atl_dpll_clk_mux: atl_dpll_clk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_32k_ck>, <&video1_clkin_ck>, <&video2_clkin_ck>, <&hdmi_clkin_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x0c00>;
+ };
+
+ atl_gfclk_mux: atl_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&l3_iclk_div>, <&dpll_abe_m2_ck>, <&atl_dpll_clk_mux>;
+ ti,bit-shift = <26>;
+ reg = <0x0c00>;
+ };
+
+ gmac_gmii_ref_clk_div: gmac_gmii_ref_clk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_gmac_m2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x13d0>;
+ ti,dividers = <2>;
+ };
+
+ gmac_rft_clk_mux: gmac_rft_clk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&video1_clkin_ck>, <&video2_clkin_ck>, <&dpll_abe_m2_ck>, <&hdmi_clkin_ck>, <&l3_iclk_div>;
+ ti,bit-shift = <25>;
+ reg = <0x13d0>;
+ };
+
+ gpu_core_gclk_mux: gpu_core_gclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dpll_core_h14x2_ck>, <&dpll_per_h14x2_ck>, <&dpll_gpu_m2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1220>;
+ };
+
+ gpu_hyd_gclk_mux: gpu_hyd_gclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dpll_core_h14x2_ck>, <&dpll_per_h14x2_ck>, <&dpll_gpu_m2_ck>;
+ ti,bit-shift = <26>;
+ reg = <0x1220>;
+ };
+
+ l3instr_ts_gclk_div: l3instr_ts_gclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&wkupaon_iclk_mux>;
+ ti,bit-shift = <24>;
+ reg = <0x0e50>;
+ ti,dividers = <8>, <16>, <32>;
+ };
+
+ mcasp2_ahclkr_mux: mcasp2_ahclkr_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>;
+ ti,bit-shift = <28>;
+ reg = <0x1860>;
+ };
+
+ mcasp2_ahclkx_mux: mcasp2_ahclkx_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x1860>;
+ };
+
+ mcasp2_aux_gfclk_mux: mcasp2_aux_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>;
+ ti,bit-shift = <22>;
+ reg = <0x1860>;
+ };
+
+ mcasp3_ahclkx_mux: mcasp3_ahclkx_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x1868>;
+ };
+
+ mcasp3_aux_gfclk_mux: mcasp3_aux_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>;
+ ti,bit-shift = <22>;
+ reg = <0x1868>;
+ };
+
+ mcasp4_ahclkx_mux: mcasp4_ahclkx_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x1898>;
+ };
+
+ mcasp4_aux_gfclk_mux: mcasp4_aux_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>;
+ ti,bit-shift = <22>;
+ reg = <0x1898>;
+ };
+
+ mcasp5_ahclkx_mux: mcasp5_ahclkx_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x1878>;
+ };
+
+ mcasp5_aux_gfclk_mux: mcasp5_aux_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>;
+ ti,bit-shift = <22>;
+ reg = <0x1878>;
+ };
+
+ mcasp6_ahclkx_mux: mcasp6_ahclkx_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x1904>;
+ };
+
+ mcasp6_aux_gfclk_mux: mcasp6_aux_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>;
+ ti,bit-shift = <22>;
+ reg = <0x1904>;
+ };
+
+ mcasp7_ahclkx_mux: mcasp7_ahclkx_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x1908>;
+ };
+
+ mcasp7_aux_gfclk_mux: mcasp7_aux_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>;
+ ti,bit-shift = <22>;
+ reg = <0x1908>;
+ };
+
+ mcasp8_ahclk_mux: mcasp8_ahclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>;
+ ti,bit-shift = <22>;
+ reg = <0x1890>;
+ };
+
+ mcasp8_aux_gfclk_mux: mcasp8_aux_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>;
+ ti,bit-shift = <24>;
+ reg = <0x1890>;
+ };
+
+ mmc1_fclk_mux: mmc1_fclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_128m_clk>, <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1328>;
+ };
+
+ mmc1_fclk_div: mmc1_fclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&mmc1_fclk_mux>;
+ ti,bit-shift = <25>;
+ ti,max-div = <4>;
+ reg = <0x1328>;
+ ti,index-power-of-two;
+ };
+
+ mmc2_fclk_mux: mmc2_fclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_128m_clk>, <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1330>;
+ };
+
+ mmc2_fclk_div: mmc2_fclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&mmc2_fclk_mux>;
+ ti,bit-shift = <25>;
+ ti,max-div = <4>;
+ reg = <0x1330>;
+ ti,index-power-of-two;
+ };
+
+ mmc3_gfclk_mux: mmc3_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1820>;
+ };
+
+ mmc3_gfclk_div: mmc3_gfclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&mmc3_gfclk_mux>;
+ ti,bit-shift = <25>;
+ ti,max-div = <4>;
+ reg = <0x1820>;
+ ti,index-power-of-two;
+ };
+
+ mmc4_gfclk_mux: mmc4_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1828>;
+ };
+
+ mmc4_gfclk_div: mmc4_gfclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&mmc4_gfclk_mux>;
+ ti,bit-shift = <25>;
+ ti,max-div = <4>;
+ reg = <0x1828>;
+ ti,index-power-of-two;
+ };
+
+ qspi_gfclk_mux: qspi_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_128m_clk>, <&dpll_per_h13x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1838>;
+ };
+
+ qspi_gfclk_div: qspi_gfclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&qspi_gfclk_mux>;
+ ti,bit-shift = <25>;
+ ti,max-div = <4>;
+ reg = <0x1838>;
+ ti,index-power-of-two;
+ };
+
+ timer10_gfclk_mux: timer10_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x1728>;
+ };
+
+ timer11_gfclk_mux: timer11_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x1730>;
+ };
+
+ timer13_gfclk_mux: timer13_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x17c8>;
+ };
+
+ timer14_gfclk_mux: timer14_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x17d0>;
+ };
+
+ timer15_gfclk_mux: timer15_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x17d8>;
+ };
+
+ timer16_gfclk_mux: timer16_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x1830>;
+ };
+
+ timer2_gfclk_mux: timer2_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x1738>;
+ };
+
+ timer3_gfclk_mux: timer3_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x1740>;
+ };
+
+ timer4_gfclk_mux: timer4_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x1748>;
+ };
+
+ timer9_gfclk_mux: timer9_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x1750>;
+ };
+
+ uart1_gfclk_mux: uart1_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1840>;
+ };
+
+ uart2_gfclk_mux: uart2_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1848>;
+ };
+
+ uart3_gfclk_mux: uart3_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1850>;
+ };
+
+ uart4_gfclk_mux: uart4_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1858>;
+ };
+
+ uart5_gfclk_mux: uart5_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1870>;
+ };
+
+ uart7_gfclk_mux: uart7_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x18d0>;
+ };
+
+ uart8_gfclk_mux: uart8_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x18e0>;
+ };
+
+ uart9_gfclk_mux: uart9_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x18e8>;
+ };
+
+ vip1_gclk_mux: vip1_gclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&l3_iclk_div>, <&dpll_core_h23x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1020>;
+ };
+
+ vip2_gclk_mux: vip2_gclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&l3_iclk_div>, <&dpll_core_h23x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1028>;
+ };
+
+ vip3_gclk_mux: vip3_gclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&l3_iclk_div>, <&dpll_core_h23x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1030>;
+ };
+};
+
+&cm_core_clockdomains {
+ coreaon_clkdm: coreaon_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&dpll_usb_ck>;
+ };
+};
diff --git a/arch/arm/boot/dts/ea3250.dts b/arch/arm/boot/dts/ea3250.dts
new file mode 100644
index 000000000..a4ba31b23
--- /dev/null
+++ b/arch/arm/boot/dts/ea3250.dts
@@ -0,0 +1,281 @@
+/*
+ * Embedded Artists LPC3250 board
+ *
+ * Copyright 2012 Roland Stigge <stigge@antcom.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
+ */
+
+/dts-v1/;
+/include/ "lpc32xx.dtsi"
+
+/ {
+ model = "Embedded Artists LPC3250 board based on NXP LPC3250";
+ compatible = "ea,ea3250", "nxp,lpc3250";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x4000000>;
+ };
+
+ ahb {
+ mac: ethernet@31060000 {
+ phy-mode = "rmii";
+ use-iram;
+ };
+
+ /* Here, choose exactly one from: ohci, usbd */
+ ohci@31020000 {
+ transceiver = <&isp1301>;
+ status = "okay";
+ };
+
+/*
+ usbd@31020000 {
+ transceiver = <&isp1301>;
+ status = "okay";
+ };
+*/
+
+ /* 128MB Flash via SLC NAND controller */
+ slc: flash@20020000 {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ nxp,wdr-clks = <14>;
+ nxp,wwidth = <260000000>;
+ nxp,whold = <104000000>;
+ nxp,wsetup = <200000000>;
+ nxp,rdr-clks = <14>;
+ nxp,rwidth = <34666666>;
+ nxp,rhold = <104000000>;
+ nxp,rsetup = <200000000>;
+ nand-on-flash-bbt;
+ gpios = <&gpio 5 19 1>; /* GPO_P3 19, active low */
+
+ mtd0@00000000 {
+ label = "ea3250-boot";
+ reg = <0x00000000 0x00080000>;
+ read-only;
+ };
+
+ mtd1@00080000 {
+ label = "ea3250-uboot";
+ reg = <0x00080000 0x000c0000>;
+ read-only;
+ };
+
+ mtd2@00140000 {
+ label = "ea3250-kernel";
+ reg = <0x00140000 0x00400000>;
+ };
+
+ mtd3@00540000 {
+ label = "ea3250-rootfs";
+ reg = <0x00540000 0x07ac0000>;
+ };
+ };
+
+ apb {
+ uart5: serial@40090000 {
+ status = "okay";
+ };
+
+ uart3: serial@40080000 {
+ status = "okay";
+ };
+
+ uart6: serial@40098000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@400A0000 {
+ clock-frequency = <100000>;
+
+ eeprom@50 {
+ compatible = "at,24c256";
+ reg = <0x50>;
+ };
+
+ eeprom@57 {
+ compatible = "at,24c64";
+ reg = <0x57>;
+ };
+
+ uda1380: uda1380@18 {
+ compatible = "nxp,uda1380";
+ reg = <0x18>;
+ power-gpio = <&gpio 0x59 0>;
+ reset-gpio = <&gpio 0x51 0>;
+ dac-clk = "wspll";
+ };
+
+ pca9532: pca9532@60 {
+ compatible = "nxp,pca9532";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x60>;
+ };
+ };
+
+ i2c2: i2c@400A8000 {
+ clock-frequency = <100000>;
+ };
+
+ i2cusb: i2c@31020300 {
+ clock-frequency = <100000>;
+
+ isp1301: usb-transceiver@2d {
+ compatible = "nxp,isp1301";
+ reg = <0x2d>;
+ };
+ };
+
+ sd@20098000 {
+ wp-gpios = <&pca9532 5 0>;
+ cd-gpios = <&pca9532 4 0>;
+ cd-inverted;
+ bus-width = <4>;
+ status = "okay";
+ };
+ };
+
+ fab {
+ uart1: serial@40014000 {
+ status = "okay";
+ };
+
+ /* 3-axis accelerometer X,Y,Z (or AD-IN instead of Z) */
+ adc@40048000 {
+ status = "okay";
+ };
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ autorepeat;
+ button@21 {
+ label = "Interrupt Key";
+ linux,code = <103>;
+ gpios = <&gpio 4 1 0>; /* GPI_P3 1 */
+ };
+ key1 {
+ label = "KEY1";
+ linux,code = <1>;
+ gpios = <&pca9532 0 0>;
+ };
+ key2 {
+ label = "KEY2";
+ linux,code = <2>;
+ gpios = <&pca9532 1 0>;
+ };
+ key3 {
+ label = "KEY3";
+ linux,code = <3>;
+ gpios = <&pca9532 2 0>;
+ };
+ key4 {
+ label = "KEY4";
+ linux,code = <4>;
+ gpios = <&pca9532 3 0>;
+ };
+ joy0 {
+ label = "Joystick Key 0";
+ linux,code = <10>;
+ gpios = <&gpio 2 0 0>; /* P2.0 */
+ };
+ joy1 {
+ label = "Joystick Key 1";
+ linux,code = <11>;
+ gpios = <&gpio 2 1 0>; /* P2.1 */
+ };
+ joy2 {
+ label = "Joystick Key 2";
+ linux,code = <12>;
+ gpios = <&gpio 2 2 0>; /* P2.2 */
+ };
+ joy3 {
+ label = "Joystick Key 3";
+ linux,code = <13>;
+ gpios = <&gpio 2 3 0>; /* P2.3 */
+ };
+ joy4 {
+ label = "Joystick Key 4";
+ linux,code = <14>;
+ gpios = <&gpio 2 4 0>; /* P2.4 */
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ /* LEDs on OEM Board */
+
+ led1 {
+ gpios = <&gpio 5 14 1>; /* GPO_P3 14, GPIO 93, active low */
+ linux,default-trigger = "timer";
+ default-state = "off";
+ };
+
+ led2 {
+ gpios = <&gpio 2 10 1>; /* P2.10, active low */
+ default-state = "off";
+ };
+
+ led3 {
+ gpios = <&gpio 2 11 1>; /* P2.11, active low */
+ default-state = "off";
+ };
+
+ led4 {
+ gpios = <&gpio 2 12 1>; /* P2.12, active low */
+ default-state = "off";
+ };
+
+ /* LEDs on Base Board */
+
+ lede1 {
+ gpios = <&pca9532 8 0>;
+ default-state = "off";
+ };
+ lede2 {
+ gpios = <&pca9532 9 0>;
+ default-state = "off";
+ };
+ lede3 {
+ gpios = <&pca9532 10 0>;
+ default-state = "off";
+ };
+ lede4 {
+ gpios = <&pca9532 11 0>;
+ default-state = "off";
+ };
+ lede5 {
+ gpios = <&pca9532 12 0>;
+ default-state = "off";
+ };
+ lede6 {
+ gpios = <&pca9532 13 0>;
+ default-state = "off";
+ };
+ lede7 {
+ gpios = <&pca9532 14 0>;
+ default-state = "off";
+ };
+ lede8 {
+ gpios = <&pca9532 15 0>;
+ default-state = "off";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ecx-2000.dts b/arch/arm/boot/dts/ecx-2000.dts
new file mode 100644
index 000000000..2ccbb57fb
--- /dev/null
+++ b/arch/arm/boot/dts/ecx-2000.dts
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2011-2012 Calxeda, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/dts-v1/;
+
+/* First 4KB has pen for secondary cores. */
+/memreserve/ 0x00000000 0x0001000;
+
+/ {
+ model = "Calxeda ECX-2000";
+ compatible = "calxeda,ecx-2000";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ clock-ranges;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <0>;
+ clocks = <&a9pll>;
+ clock-names = "cpu";
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <1>;
+ clocks = <&a9pll>;
+ clock-names = "cpu";
+ };
+
+ cpu@2 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <2>;
+ clocks = <&a9pll>;
+ clock-names = "cpu";
+ };
+
+ cpu@3 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <3>;
+ clocks = <&a9pll>;
+ clock-names = "cpu";
+ };
+ };
+
+ memory@0 {
+ name = "memory";
+ device_type = "memory";
+ reg = <0x00000000 0x00000000 0x00000000 0xff800000>;
+ };
+
+ memory@200000000 {
+ name = "memory";
+ device_type = "memory";
+ reg = <0x00000002 0x00000000 0x00000003 0x00000000>;
+ };
+
+ soc {
+ ranges = <0x00000000 0x00000000 0x00000000 0xffffffff>;
+
+ timer {
+ compatible = "arm,cortex-a15-timer", "arm,armv7-timer"; interrupts = <1 13 0xf08>,
+ <1 14 0xf08>,
+ <1 11 0xf08>,
+ <1 10 0xf08>;
+ };
+
+ memory-controller@fff00000 {
+ compatible = "calxeda,ecx-2000-ddr-ctrl";
+ reg = <0xfff00000 0x1000>;
+ interrupts = <0 91 4>;
+ };
+
+ intc: interrupt-controller@fff11000 {
+ compatible = "arm,cortex-a15-gic";
+ #interrupt-cells = <3>;
+ #size-cells = <0>;
+ #address-cells = <1>;
+ interrupt-controller;
+ interrupts = <1 9 0xf04>;
+ reg = <0xfff11000 0x1000>,
+ <0xfff12000 0x1000>,
+ <0xfff14000 0x2000>,
+ <0xfff16000 0x2000>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 76 4 0 75 4 0 74 4 0 73 4>;
+ };
+ };
+};
+
+/include/ "ecx-common.dtsi"
diff --git a/arch/arm/boot/dts/ecx-common.dtsi b/arch/arm/boot/dts/ecx-common.dtsi
new file mode 100644
index 000000000..b90045a8f
--- /dev/null
+++ b/arch/arm/boot/dts/ecx-common.dtsi
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2011-2012 Calxeda, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/ {
+ chosen {
+ bootargs = "console=ttyAMA0";
+ };
+
+ psci {
+ compatible = "arm,psci";
+ method = "smc";
+ cpu_suspend = <0x84000002>;
+ cpu_off = <0x84000004>;
+ cpu_on = <0x84000006>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&intc>;
+
+ sata@ffe08000 {
+ compatible = "calxeda,hb-ahci";
+ reg = <0xffe08000 0x10000>;
+ interrupts = <0 83 4>;
+ dma-coherent;
+ calxeda,port-phys = <&combophy5 0 &combophy0 0
+ &combophy0 1 &combophy0 2
+ &combophy0 3>;
+ calxeda,sgpio-gpio =<&gpioh 5 1 &gpioh 6 1 &gpioh 7 1>;
+ calxeda,led-order = <4 0 1 2 3>;
+ };
+
+ sdhci@ffe0e000 {
+ compatible = "calxeda,hb-sdhci";
+ reg = <0xffe0e000 0x1000>;
+ interrupts = <0 90 4>;
+ clocks = <&eclk>;
+ status = "disabled";
+ };
+
+ ipc@fff20000 {
+ compatible = "arm,pl320", "arm,primecell";
+ reg = <0xfff20000 0x1000>;
+ interrupts = <0 7 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ gpioe: gpio@fff30000 {
+ #gpio-cells = <2>;
+ compatible = "arm,pl061", "arm,primecell";
+ gpio-controller;
+ reg = <0xfff30000 0x1000>;
+ interrupts = <0 14 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ gpiof: gpio@fff31000 {
+ #gpio-cells = <2>;
+ compatible = "arm,pl061", "arm,primecell";
+ gpio-controller;
+ reg = <0xfff31000 0x1000>;
+ interrupts = <0 15 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ gpiog: gpio@fff32000 {
+ #gpio-cells = <2>;
+ compatible = "arm,pl061", "arm,primecell";
+ gpio-controller;
+ reg = <0xfff32000 0x1000>;
+ interrupts = <0 16 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ gpioh: gpio@fff33000 {
+ #gpio-cells = <2>;
+ compatible = "arm,pl061", "arm,primecell";
+ gpio-controller;
+ reg = <0xfff33000 0x1000>;
+ interrupts = <0 17 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ timer@fff34000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0xfff34000 0x1000>;
+ interrupts = <0 18 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ rtc@fff35000 {
+ compatible = "arm,pl031", "arm,primecell";
+ reg = <0xfff35000 0x1000>;
+ interrupts = <0 19 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ serial@fff36000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xfff36000 0x1000>;
+ interrupts = <0 20 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ smic@fff3a000 {
+ compatible = "ipmi-smic";
+ device_type = "ipmi";
+ reg = <0xfff3a000 0x1000>;
+ interrupts = <0 24 4>;
+ reg-size = <4>;
+ reg-spacing = <4>;
+ };
+
+ sregs@fff3c000 {
+ compatible = "calxeda,hb-sregs";
+ reg = <0xfff3c000 0x1000>;
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ osc: oscillator {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <33333000>;
+ };
+
+ ddrpll: ddrpll {
+ #clock-cells = <0>;
+ compatible = "calxeda,hb-pll-clock";
+ clocks = <&osc>;
+ reg = <0x108>;
+ };
+
+ a9pll: a9pll {
+ #clock-cells = <0>;
+ compatible = "calxeda,hb-pll-clock";
+ clocks = <&osc>;
+ reg = <0x100>;
+ };
+
+ a9periphclk: a9periphclk {
+ #clock-cells = <0>;
+ compatible = "calxeda,hb-a9periph-clock";
+ clocks = <&a9pll>;
+ reg = <0x104>;
+ };
+
+ a9bclk: a9bclk {
+ #clock-cells = <0>;
+ compatible = "calxeda,hb-a9bus-clock";
+ clocks = <&a9pll>;
+ reg = <0x104>;
+ };
+
+ emmcpll: emmcpll {
+ #clock-cells = <0>;
+ compatible = "calxeda,hb-pll-clock";
+ clocks = <&osc>;
+ reg = <0x10C>;
+ };
+
+ eclk: eclk {
+ #clock-cells = <0>;
+ compatible = "calxeda,hb-emmc-clock";
+ clocks = <&emmcpll>;
+ reg = <0x114>;
+ };
+
+ pclk: pclk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <150000000>;
+ };
+ };
+ };
+
+ dma@fff3d000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0xfff3d000 0x1000>;
+ interrupts = <0 92 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ ethernet@fff50000 {
+ compatible = "calxeda,hb-xgmac";
+ reg = <0xfff50000 0x1000>;
+ interrupts = <0 77 4 0 78 4 0 79 4>;
+ dma-coherent;
+ };
+
+ ethernet@fff51000 {
+ compatible = "calxeda,hb-xgmac";
+ reg = <0xfff51000 0x1000>;
+ interrupts = <0 80 4 0 81 4 0 82 4>;
+ dma-coherent;
+ };
+
+ combophy0: combo-phy@fff58000 {
+ compatible = "calxeda,hb-combophy";
+ #phy-cells = <1>;
+ reg = <0xfff58000 0x1000>;
+ phydev = <5>;
+ };
+
+ combophy5: combo-phy@fff5d000 {
+ compatible = "calxeda,hb-combophy";
+ #phy-cells = <1>;
+ reg = <0xfff5d000 0x1000>;
+ phydev = <31>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/efm32gg-dk3750.dts b/arch/arm/boot/dts/efm32gg-dk3750.dts
new file mode 100644
index 000000000..b4031fa4a
--- /dev/null
+++ b/arch/arm/boot/dts/efm32gg-dk3750.dts
@@ -0,0 +1,86 @@
+/*
+ * Device tree for EFM32GG-DK3750 development board.
+ *
+ * Documentation available from
+ * http://www.silabs.com/Support%20Documents/TechnicalDocs/efm32gg-dk3750-ug.pdf
+ */
+
+/dts-v1/;
+#include "efm32gg.dtsi"
+
+/ {
+ model = "Energy Micro Giant Gecko Development Kit";
+ compatible = "efm32,dk3750";
+
+ chosen {
+ bootargs = "console=ttyefm4,115200 init=/linuxrc ignore_loglevel ihash_entries=64 dhash_entries=64 earlyprintk uclinux.physaddr=0x8c400000 root=/dev/mtdblock0";
+ };
+
+ memory {
+ reg = <0x88000000 0x400000>;
+ };
+
+ soc {
+ adc@40002000 {
+ status = "ok";
+ };
+
+ i2c@4000a000 {
+ efm32,location = <3>;
+ status = "ok";
+
+ temp@48 {
+ compatible = "st,stds75";
+ reg = <0x48>;
+ };
+
+ eeprom@50 {
+ compatible = "microchip,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+ };
+
+ spi0: spi@4000c000 { /* USART0 */
+ cs-gpios = <&gpio 68 1>; // E4
+ location = <1>;
+ status = "ok";
+
+ microsd@0 {
+ compatible = "mmc-spi-slot";
+ spi-max-frequency = <100000>;
+ voltage-ranges = <3200 3400>;
+ broken-cd;
+ reg = <0>;
+ };
+ };
+
+ spi1: spi@4000c400 { /* USART1 */
+ cs-gpios = <&gpio 51 1>; // D3
+ location = <1>;
+ status = "ok";
+
+ ks8851@0 {
+ compatible = "ks8851";
+ spi-max-frequency = <6000000>;
+ reg = <0>;
+ interrupt-parent = <&boardfpga>;
+ interrupts = <4>;
+ };
+ };
+
+ uart4: uart@4000e400 { /* UART1 */
+ location = <2>;
+ status = "ok";
+ };
+
+ boardfpga: boardfpga {
+ compatible = "efm32board";
+ reg = <0x80000000 0x400>;
+ irq-gpios = <&gpio 64 1>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ status = "ok";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/efm32gg.dtsi b/arch/arm/boot/dts/efm32gg.dtsi
new file mode 100644
index 000000000..106d505c5
--- /dev/null
+++ b/arch/arm/boot/dts/efm32gg.dtsi
@@ -0,0 +1,172 @@
+/*
+ * Device tree for Energy Micro EFM32 Giant Gecko SoC.
+ *
+ * Documentation available from
+ * http://www.silabs.com/Support%20Documents/TechnicalDocs/EFM32GG-RM.pdf
+ */
+#include "armv7-m.dtsi"
+#include "dt-bindings/clock/efm32-cmu.h"
+
+/ {
+ aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ spi2 = &spi2;
+ };
+
+ soc {
+ adc: adc@40002000 {
+ compatible = "efm32,adc";
+ reg = <0x40002000 0x400>;
+ interrupts = <7>;
+ clocks = <&cmu clk_HFPERCLKADC0>;
+ status = "disabled";
+ };
+
+ gpio: gpio@40006000 {
+ compatible = "efm32,gpio";
+ reg = <0x40006000 0x1000>;
+ interrupts = <1 11>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ clocks = <&cmu clk_HFPERCLKGPIO>;
+ status = "ok";
+ };
+
+ i2c0: i2c@4000a000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "efm32,i2c";
+ reg = <0x4000a000 0x400>;
+ interrupts = <9>;
+ clocks = <&cmu clk_HFPERCLKI2C0>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@4000a400 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "efm32,i2c";
+ reg = <0x4000a400 0x400>;
+ interrupts = <10>;
+ clocks = <&cmu clk_HFPERCLKI2C1>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ spi0: spi@4000c000 { /* USART0 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "efm32,spi";
+ reg = <0x4000c000 0x400>;
+ interrupts = <3 4>;
+ clocks = <&cmu clk_HFPERCLKUSART0>;
+ status = "disabled";
+ };
+
+ spi1: spi@4000c400 { /* USART1 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "efm32,spi";
+ reg = <0x4000c400 0x400>;
+ interrupts = <15 16>;
+ clocks = <&cmu clk_HFPERCLKUSART1>;
+ status = "disabled";
+ };
+
+ spi2: spi@4000c800 { /* USART2 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "efm32,spi";
+ reg = <0x4000c800 0x400>;
+ interrupts = <18 19>;
+ clocks = <&cmu clk_HFPERCLKUSART2>;
+ status = "disabled";
+ };
+
+ uart0: uart@4000c000 { /* USART0 */
+ compatible = "efm32,uart";
+ reg = <0x4000c000 0x400>;
+ interrupts = <3 4>;
+ clocks = <&cmu clk_HFPERCLKUSART0>;
+ status = "disabled";
+ };
+
+ uart1: uart@4000c400 { /* USART1 */
+ compatible = "efm32,uart";
+ reg = <0x4000c400 0x400>;
+ interrupts = <15 16>;
+ clocks = <&cmu clk_HFPERCLKUSART1>;
+ status = "disabled";
+ };
+
+ uart2: uart@4000c800 { /* USART2 */
+ compatible = "efm32,uart";
+ reg = <0x4000c800 0x400>;
+ interrupts = <18 19>;
+ clocks = <&cmu clk_HFPERCLKUSART2>;
+ status = "disabled";
+ };
+
+ uart3: uart@4000e000 { /* UART0 */
+ compatible = "efm32,uart";
+ reg = <0x4000e000 0x400>;
+ interrupts = <20 21>;
+ clocks = <&cmu clk_HFPERCLKUART0>;
+ status = "disabled";
+ };
+
+ uart4: uart@4000e400 { /* UART1 */
+ compatible = "efm32,uart";
+ reg = <0x4000e400 0x400>;
+ interrupts = <22 23>;
+ clocks = <&cmu clk_HFPERCLKUART1>;
+ status = "disabled";
+ };
+
+ timer0: timer@40010000 {
+ compatible = "efm32,timer";
+ reg = <0x40010000 0x400>;
+ interrupts = <2>;
+ clocks = <&cmu clk_HFPERCLKTIMER0>;
+ };
+
+ timer1: timer@40010400 {
+ compatible = "efm32,timer";
+ reg = <0x40010400 0x400>;
+ interrupts = <12>;
+ clocks = <&cmu clk_HFPERCLKTIMER1>;
+ };
+
+ timer2: timer@40010800 {
+ compatible = "efm32,timer";
+ reg = <0x40010800 0x400>;
+ interrupts = <13>;
+ clocks = <&cmu clk_HFPERCLKTIMER2>;
+ };
+
+ timer3: timer@40010c00 {
+ compatible = "efm32,timer";
+ reg = <0x40010c00 0x400>;
+ interrupts = <14>;
+ clocks = <&cmu clk_HFPERCLKTIMER3>;
+ };
+
+ cmu: cmu@400c8000 {
+ compatible = "efm32gg,cmu";
+ reg = <0x400c8000 0x400>;
+ interrupts = <32>;
+ #clock-cells = <1>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/elpida_ecb240abacn.dtsi b/arch/arm/boot/dts/elpida_ecb240abacn.dtsi
new file mode 100644
index 000000000..f97f70f83
--- /dev/null
+++ b/arch/arm/boot/dts/elpida_ecb240abacn.dtsi
@@ -0,0 +1,67 @@
+/*
+ * Common devices used in different OMAP boards
+ */
+
+/ {
+ elpida_ECB240ABACN: lpddr2 {
+ compatible = "Elpida,ECB240ABACN","jedec,lpddr2-s4";
+ density = <2048>;
+ io-width = <32>;
+
+ tRPab-min-tck = <3>;
+ tRCD-min-tck = <3>;
+ tWR-min-tck = <3>;
+ tRASmin-min-tck = <3>;
+ tRRD-min-tck = <2>;
+ tWTR-min-tck = <2>;
+ tXP-min-tck = <2>;
+ tRTP-min-tck = <2>;
+ tCKE-min-tck = <3>;
+ tCKESR-min-tck = <3>;
+ tFAW-min-tck = <8>;
+
+ timings_elpida_ECB240ABACN_400mhz: lpddr2-timings@0 {
+ compatible = "jedec,lpddr2-timings";
+ min-freq = <10000000>;
+ max-freq = <400000000>;
+ tRPab = <21000>;
+ tRCD = <18000>;
+ tWR = <15000>;
+ tRAS-min = <42000>;
+ tRRD = <10000>;
+ tWTR = <7500>;
+ tXP = <7500>;
+ tRTP = <7500>;
+ tCKESR = <15000>;
+ tDQSCK-max = <5500>;
+ tFAW = <50000>;
+ tZQCS = <90000>;
+ tZQCL = <360000>;
+ tZQinit = <1000000>;
+ tRAS-max-ns = <70000>;
+ tDQSCK-max-derated = <6000>;
+ };
+
+ timings_elpida_ECB240ABACN_200mhz: lpddr2-timings@1 {
+ compatible = "jedec,lpddr2-timings";
+ min-freq = <10000000>;
+ max-freq = <200000000>;
+ tRPab = <21000>;
+ tRCD = <18000>;
+ tWR = <15000>;
+ tRAS-min = <42000>;
+ tRRD = <10000>;
+ tWTR = <10000>;
+ tXP = <7500>;
+ tRTP = <7500>;
+ tCKESR = <15000>;
+ tDQSCK-max = <5500>;
+ tFAW = <50000>;
+ tZQCS = <90000>;
+ tZQCL = <360000>;
+ tZQinit = <1000000>;
+ tRAS-max-ns = <70000>;
+ tDQSCK-max-derated = <6000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/emev2-kzm9d.dts b/arch/arm/boot/dts/emev2-kzm9d.dts
new file mode 100644
index 000000000..19446273e
--- /dev/null
+++ b/arch/arm/boot/dts/emev2-kzm9d.dts
@@ -0,0 +1,109 @@
+/*
+ * Device Tree Source for the KZM9D board
+ *
+ * Copyright (C) 2013 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.
+ */
+/dts-v1/;
+
+#include "emev2.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ model = "EMEV2 KZM9D Board";
+ compatible = "renesas,kzm9d", "renesas,emev2";
+
+ memory {
+ device_type = "memory";
+ reg = <0x40000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS1,115200n81 ignore_loglevel root=/dev/nfs ip=dhcp";
+ stdout-path = &uart1;
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@1 {
+ debounce_interval = <50>;
+ wakeup = <1>;
+ label = "DSW2-1";
+ linux,code = <KEY_1>;
+ gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+ };
+ button@2 {
+ debounce_interval = <50>;
+ wakeup = <1>;
+ label = "DSW2-2";
+ linux,code = <KEY_2>;
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
+ };
+ button@3 {
+ debounce_interval = <50>;
+ wakeup = <1>;
+ label = "DSW2-3";
+ linux,code = <KEY_3>;
+ gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
+ };
+ button@4 {
+ debounce_interval = <50>;
+ wakeup = <1>;
+ label = "DSW2-4";
+ linux,code = <KEY_4>;
+ gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ reg_1p8v: regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ reg_3p3v: regulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ lan9220@20000000 {
+ compatible = "smsc,lan9220", "smsc,lan9115";
+ reg = <0x20000000 0x10000>;
+ phy-mode = "mii";
+ interrupt-parent = <&gpio0>;
+ interrupts = <1 IRQ_TYPE_EDGE_RISING>;
+ reg-io-width = <4>;
+ smsc,irq-active-high;
+ smsc,irq-push-pull;
+ vddvario-supply = <&reg_1p8v>;
+ vdd33a-supply = <&reg_3p3v>;
+ };
+};
+
+&pfc {
+ uart1_pins: uart@e1030000 {
+ renesas,groups = "uart1_ctrl", "uart1_data";
+ renesas,function = "uart1";
+ };
+};
+
+&uart1 {
+ pinctrl-0 = <&uart1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/emev2.dtsi b/arch/arm/boot/dts/emev2.dtsi
new file mode 100644
index 000000000..bb45694d9
--- /dev/null
+++ b/arch/arm/boot/dts/emev2.dtsi
@@ -0,0 +1,237 @@
+/*
+ * Device Tree Source for the EMEV2 SoC
+ *
+ * Copyright (C) 2012 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 "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "renesas,emev2";
+ interrupt-parent = <&gic>;
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ gpio3 = &gpio3;
+ gpio4 = &gpio4;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ clock-frequency = <533000000>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ clock-frequency = <533000000>;
+ };
+ };
+
+ gic: interrupt-controller@e0020000 {
+ compatible = "arm,cortex-a9-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0xe0028000 0x1000>,
+ <0xe0020000 0x0100>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>,
+ <0 121 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ clocks@e0110000 {
+ compatible = "renesas,emev2-smu";
+ reg = <0xe0110000 0x10000>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ c32ki: c32ki {
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ #clock-cells = <0>;
+ };
+ pll3_fo: pll3_fo {
+ compatible = "fixed-factor-clock";
+ clocks = <&c32ki>;
+ clock-div = <1>;
+ clock-mult = <7000>;
+ #clock-cells = <0>;
+ };
+ usia_u0_sclkdiv: usia_u0_sclkdiv {
+ compatible = "renesas,emev2-smu-clkdiv";
+ reg = <0x610 0>;
+ clocks = <&pll3_fo>;
+ #clock-cells = <0>;
+ };
+ usib_u1_sclkdiv: usib_u1_sclkdiv {
+ compatible = "renesas,emev2-smu-clkdiv";
+ reg = <0x65c 0>;
+ clocks = <&pll3_fo>;
+ #clock-cells = <0>;
+ };
+ usib_u2_sclkdiv: usib_u2_sclkdiv {
+ compatible = "renesas,emev2-smu-clkdiv";
+ reg = <0x65c 16>;
+ clocks = <&pll3_fo>;
+ #clock-cells = <0>;
+ };
+ usib_u3_sclkdiv: usib_u3_sclkdiv {
+ compatible = "renesas,emev2-smu-clkdiv";
+ reg = <0x660 0>;
+ clocks = <&pll3_fo>;
+ #clock-cells = <0>;
+ };
+ usia_u0_sclk: usia_u0_sclk {
+ compatible = "renesas,emev2-smu-gclk";
+ reg = <0x4a0 1>;
+ clocks = <&usia_u0_sclkdiv>;
+ #clock-cells = <0>;
+ };
+ usib_u1_sclk: usib_u1_sclk {
+ compatible = "renesas,emev2-smu-gclk";
+ reg = <0x4b8 1>;
+ clocks = <&usib_u1_sclkdiv>;
+ #clock-cells = <0>;
+ };
+ usib_u2_sclk: usib_u2_sclk {
+ compatible = "renesas,emev2-smu-gclk";
+ reg = <0x4bc 1>;
+ clocks = <&usib_u2_sclkdiv>;
+ #clock-cells = <0>;
+ };
+ usib_u3_sclk: usib_u3_sclk {
+ compatible = "renesas,emev2-smu-gclk";
+ reg = <0x4c0 1>;
+ clocks = <&usib_u3_sclkdiv>;
+ #clock-cells = <0>;
+ };
+ sti_sclk: sti_sclk {
+ compatible = "renesas,emev2-smu-gclk";
+ reg = <0x528 1>;
+ clocks = <&c32ki>;
+ #clock-cells = <0>;
+ };
+ };
+
+ timer@e0180000 {
+ compatible = "renesas,em-sti";
+ reg = <0xe0180000 0x54>;
+ interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sti_sclk>;
+ clock-names = "sclk";
+ };
+
+ uart0: serial@e1020000 {
+ compatible = "renesas,em-uart";
+ reg = <0xe1020000 0x38>;
+ interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&usia_u0_sclk>;
+ clock-names = "sclk";
+ };
+
+ uart1: serial@e1030000 {
+ compatible = "renesas,em-uart";
+ reg = <0xe1030000 0x38>;
+ interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&usib_u1_sclk>;
+ clock-names = "sclk";
+ };
+
+ uart2: serial@e1040000 {
+ compatible = "renesas,em-uart";
+ reg = <0xe1040000 0x38>;
+ interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&usib_u2_sclk>;
+ clock-names = "sclk";
+ };
+
+ uart3: serial@e1050000 {
+ compatible = "renesas,em-uart";
+ reg = <0xe1050000 0x38>;
+ interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&usib_u3_sclk>;
+ clock-names = "sclk";
+ };
+
+ pfc: pfc@e0140200 {
+ compatible = "renesas,pfc-emev2";
+ reg = <0xe0140200 0x100>;
+ };
+
+ gpio0: gpio@e0050000 {
+ compatible = "renesas,em-gio";
+ reg = <0xe0050000 0x2c>, <0xe0050040 0x20>;
+ interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>,
+ <0 68 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 0 32>;
+ #gpio-cells = <2>;
+ ngpios = <32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ gpio1: gpio@e0050080 {
+ compatible = "renesas,em-gio";
+ reg = <0xe0050080 0x2c>, <0xe00500c0 0x20>;
+ interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>,
+ <0 70 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 32 32>;
+ #gpio-cells = <2>;
+ ngpios = <32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ gpio2: gpio@e0050100 {
+ compatible = "renesas,em-gio";
+ reg = <0xe0050100 0x2c>, <0xe0050140 0x20>;
+ interrupts = <0 71 IRQ_TYPE_LEVEL_HIGH>,
+ <0 72 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 64 32>;
+ #gpio-cells = <2>;
+ ngpios = <32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ gpio3: gpio@e0050180 {
+ compatible = "renesas,em-gio";
+ reg = <0xe0050180 0x2c>, <0xe00501c0 0x20>;
+ interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>,
+ <0 74 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 96 32>;
+ #gpio-cells = <2>;
+ ngpios = <32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ gpio4: gpio@e0050200 {
+ compatible = "renesas,em-gio";
+ reg = <0xe0050200 0x2c>, <0xe0050240 0x20>;
+ interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>,
+ <0 76 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 128 31>;
+ #gpio-cells = <2>;
+ ngpios = <31>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+};
diff --git a/arch/arm/boot/dts/ethernut5.dts b/arch/arm/boot/dts/ethernut5.dts
new file mode 100644
index 000000000..243044343
--- /dev/null
+++ b/arch/arm/boot/dts/ethernut5.dts
@@ -0,0 +1,94 @@
+/*
+ * ethernut5.dts - Device Tree file for Ethernut 5 board
+ *
+ * Copyright (C) 2012 egnite GmbH <info@egnite.de>
+ *
+ * Licensed under GPLv2.
+ */
+/dts-v1/;
+#include "at91sam9xe.dtsi"
+
+/ {
+ model = "Ethernut 5";
+ compatible = "egnite,ethernut5", "atmel,at91sam9260", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=/dev/mtdblock0 rw rootfstype=jffs2";
+ };
+
+ memory {
+ reg = <0x20000000 0x08000000>;
+ };
+
+ clocks {
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <18432000>;
+ };
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ usart0: serial@fffb0000 {
+ status = "okay";
+ };
+
+ usart1: serial@fffb4000 {
+ status = "okay";
+ };
+
+ macb0: ethernet@fffc4000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ usb1: gadget@fffa4000 {
+ atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ status = "okay";
+
+ gpios = <0
+ &pioC 14 GPIO_ACTIVE_HIGH
+ 0
+ >;
+
+ root@0 {
+ label = "root";
+ reg = <0x0 0x08000000>;
+ };
+
+ data@20000 {
+ label = "data";
+ reg = <0x08000000 0x38000000>;
+ };
+ };
+
+ usb0: ohci@00500000 {
+ num-ports = <2>;
+ status = "okay";
+ };
+ };
+
+ i2c@0 {
+ status = "okay";
+
+ pcf8563@50 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/evk-pro3.dts b/arch/arm/boot/dts/evk-pro3.dts
new file mode 100644
index 000000000..f72969efe
--- /dev/null
+++ b/arch/arm/boot/dts/evk-pro3.dts
@@ -0,0 +1,59 @@
+/*
+ * evk-pro3.dts - Device Tree file for Telit EVK-PRO3 with Telit GE863-PRO3
+ *
+ * Copyright (C) 2012 Telit,
+ * 2012 Fabio Porcedda <fabio.porcedda@gmail.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/dts-v1/;
+
+#include "ge863-pro3.dtsi"
+
+/ {
+ model = "Telit EVK-PRO3 for Telit GE863-PRO3";
+ compatible = "telit,evk-pro3", "atmel,at91sam9260", "atmel,at91sam9";
+
+ clocks {
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+ };
+
+ ahb {
+ apb {
+ macb0: ethernet@fffc4000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ usart0: serial@fffb0000 {
+ status = "okay";
+ };
+
+ usart2: serial@fffb8000 {
+ status = "okay";
+ };
+
+ usb1: gadget@fffa4000 {
+ atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ watchdog@fffffd40 {
+ status = "okay";
+ };
+ };
+
+ usb0: ohci@00500000 {
+ num-ports = <2>;
+ status = "okay";
+ };
+ };
+
+ i2c@0 {
+ status = "okay";
+ };
+
+};
diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts
new file mode 100644
index 000000000..1d483c1c8
--- /dev/null
+++ b/arch/arm/boot/dts/exynos3250-monk.dts
@@ -0,0 +1,636 @@
+/*
+ * Samsung's Exynos3250 based Monk board device tree source
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Device tree source file for Samsung's Monk board which is based on
+ * Samsung Exynos3250 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+#include "exynos3250.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Samsung Monk board";
+ compatible = "samsung,monk", "samsung,exynos3250", "samsung,exynos3";
+
+ aliases {
+ i2c7 = &i2c_max77836;
+ };
+
+ memory {
+ reg = <0x40000000 0x1ff00000>;
+ };
+
+ firmware@0205F000 {
+ compatible = "samsung,secure-firmware";
+ reg = <0x0205F000 0x1000>;
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ power_key {
+ gpios = <&gpx2 7 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ label = "power key";
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ vemmc_reg: voltage-regulator-0 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_EMMC_2.8V-fixed";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpk0 2 0>;
+ enable-active-high;
+ };
+
+ i2c_max77836: i2c-gpio-0 {
+ compatible = "i2c-gpio";
+ gpios = <&gpd0 2 0>, <&gpd0 3 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ max77836: subpmic@25 {
+ compatible = "maxim,max77836";
+ interrupt-parent = <&gpx1>;
+ interrupts = <5 0>;
+ reg = <0x25>;
+ wakeup;
+
+ muic: max77836-muic {
+ compatible = "maxim,max77836-muic";
+ };
+
+ regulators {
+ compatible = "maxim,max77836-regulator";
+ safeout_reg: SAFEOUT {
+ regulator-name = "SAFEOUT";
+ };
+
+ charger_reg: CHARGER {
+ regulator-name = "CHARGER";
+ regulator-min-microamp = <45000>;
+ regulator-max-microamp = <475000>;
+ regulator-boot-on;
+ };
+
+ motor_reg: LDO1 {
+ regulator-name = "MOT_2.7V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <2700000>;
+ };
+
+ LDO2 {
+ regulator-name = "UNUSED_LDO2";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3950000>;
+ };
+ };
+
+ charger {
+ compatible = "maxim,max77836-charger";
+
+ maxim,constant-uvolt = <4350000>;
+ maxim,fast-charge-uamp = <225000>;
+ maxim,eoc-uamp = <7500>;
+ maxim,ovp-uvolt = <6500000>;
+ };
+ };
+ };
+
+ haptics {
+ compatible = "regulator-haptic";
+ haptic-supply = <&motor_reg>;
+ min-microvolt = <1100000>;
+ max-microvolt = <2700000>;
+ };
+};
+
+&adc {
+ vdd-supply = <&ldo3_reg>;
+ status = "okay";
+ assigned-clocks = <&cmu CLK_SCLK_TSADC>;
+ assigned-clock-rates = <6000000>;
+
+ thermistor-ap {
+ compatible = "ntc,ncp15wb473";
+ pullup-uv = <1800000>;
+ pullup-ohm = <100000>;
+ pulldown-ohm = <100000>;
+ io-channels = <&adc 0>;
+ };
+
+ thermistor-battery {
+ compatible = "ntc,ncp15wb473";
+ pullup-uv = <1800000>;
+ pullup-ohm = <100000>;
+ pulldown-ohm = <100000>;
+ io-channels = <&adc 1>;
+ };
+};
+
+&exynos_usbphy {
+ status = "okay";
+};
+
+&hsotg {
+ vusb_d-supply = <&ldo15_reg>;
+ vusb_a-supply = <&ldo12_reg>;
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&i2c_0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-slave-addr = <0x10>;
+ samsung,i2c-max-bus-freq = <100000>;
+ status = "okay";
+
+ s2mps14_pmic@66 {
+ compatible = "samsung,s2mps14-pmic";
+ interrupt-parent = <&gpx0>;
+ interrupts = <7 0>;
+ reg = <0x66>;
+ wakeup;
+
+ s2mps14_osc: clocks {
+ compatible = "samsung,s2mps14-clk";
+ #clock-cells = <1>;
+ clock-output-names = "s2mps14_ap", "unused",
+ "s2mps14_bt";
+ };
+
+ regulators {
+ ldo1_reg: LDO1 {
+ regulator-name = "VAP_ALIVE_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "VAP_M1_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "VCC_AP_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "VAP_AVDD_PLL1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "VAP_PLL_ISO_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "VAP_MIPI_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "VAP_AVDD_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "VAP_USB_3.0V";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "V_LPDDR_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "UNUSED_LDO10";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "V_EMMC_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ samsung,ext-control-gpios = <&gpk0 2 0>;
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "V_EMMC_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ samsung,ext-control-gpios = <&gpk0 2 0>;
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "VSENSOR_2.85V";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "UNUSED_LDO14";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "TSP_AVDD_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "LCD_VDD_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "UNUSED_LDO17";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo18_reg: LDO18 {
+ regulator-name = "UNUSED_LDO18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo19_reg: LDO19 {
+ regulator-name = "TSP_VDD_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo20_reg: LDO20 {
+ regulator-name = "LCD_VDD_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo21_reg: LDO21 {
+ regulator-name = "UNUSED_LDO21";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ ldo22_reg: LDO22 {
+ regulator-name = "UNUSED_LDO22";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ ldo23_reg: LDO23 {
+ regulator-name = "UNUSED_LDO23";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo24_reg: LDO24 {
+ regulator-name = "UNUSED_LDO24";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo25_reg: LDO25 {
+ regulator-name = "UNUSED_LDO25";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "VAP_MIF_1.0V";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <900000>;
+ regulator-always-on;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "VAP_ARM_1.0V";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-always-on;
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "VAP_INT3D_1.0V";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "VCC_SUB_1.95V";
+ regulator-min-microvolt = <1950000>;
+ regulator-max-microvolt = <1950000>;
+ regulator-always-on;
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "VCC_SUB_1.35V";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c_1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-slave-addr = <0x10>;
+ samsung,i2c-max-bus-freq = <400000>;
+ status = "okay";
+
+ fuelgauge@36 {
+ compatible = "maxim,max77836-battery";
+ interrupt-parent = <&gpx1>;
+ interrupts = <2 8>;
+ reg = <0x36>;
+ };
+};
+
+&i2s2 {
+ status = "okay";
+};
+
+&mshc_0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ num-slots = <1>;
+ broken-cd;
+ non-removable;
+ cap-mmc-highspeed;
+ desc-num = <4>;
+ mmc-hs200-1_8v;
+ card-detect-delay = <200>;
+ vmmc-supply = <&vemmc_reg>;
+ clock-frequency = <100000000>;
+ clock-freq-min-max = <400000 100000000>;
+ samsung,dw-mshc-ciu-div = <1>;
+ samsung,dw-mshc-sdr-timing = <0 1>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8>;
+ bus-width = <8>;
+ status = "okay";
+};
+
+&serial_0 {
+ assigned-clocks = <&cmu CLK_SCLK_UART0>;
+ assigned-clock-rates = <100000000>;
+ status = "okay";
+};
+
+&serial_1 {
+ status = "okay";
+};
+
+&tmu {
+ vtmu-supply = <&ldo7_reg>;
+ status = "okay";
+};
+
+&rtc {
+ clocks = <&cmu CLK_RTC>, <&s2mps14_osc 0>;
+ clock-names = "rtc", "rtc_src";
+ status = "okay";
+};
+
+&ppmu_dmc0 {
+ status = "okay";
+
+ events {
+ ppmu_dmc0_3: ppmu-event3-dmc0 {
+ event-name = "ppmu-event3-dmc0";
+ };
+ };
+};
+
+&ppmu_dmc1 {
+ status = "okay";
+
+ events {
+ ppmu_dmc1_3: ppmu-event3-dmc1 {
+ event-name = "ppmu-event3-dmc1";
+ };
+ };
+};
+
+&ppmu_leftbus {
+ status = "okay";
+
+ events {
+ ppmu_leftbus_3: ppmu-event3-leftbus {
+ event-name = "ppmu-event3-leftbus";
+ };
+ };
+};
+
+&ppmu_rightbus {
+ status = "okay";
+
+ events {
+ ppmu_rightbus_3: ppmu-event3-rightbus {
+ event-name = "ppmu-event3-rightbus";
+ };
+ };
+};
+
+&xusbxti {
+ clock-frequency = <24000000>;
+};
+
+&pinctrl_0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sleep0>;
+
+ sleep0: sleep-state {
+ PIN_SLP(gpa0-0, INPUT, DOWN);
+ PIN_SLP(gpa0-1, INPUT, DOWN);
+ PIN_SLP(gpa0-2, INPUT, DOWN);
+ PIN_SLP(gpa0-3, INPUT, DOWN);
+ PIN_SLP(gpa0-4, INPUT, DOWN);
+ PIN_SLP(gpa0-5, INPUT, DOWN);
+ PIN_SLP(gpa0-6, INPUT, DOWN);
+ PIN_SLP(gpa0-7, INPUT, DOWN);
+
+ PIN_SLP(gpa1-0, INPUT, DOWN);
+ PIN_SLP(gpa1-1, INPUT, DOWN);
+ PIN_SLP(gpa1-2, INPUT, DOWN);
+ PIN_SLP(gpa1-3, INPUT, DOWN);
+ PIN_SLP(gpa1-4, INPUT, DOWN);
+ PIN_SLP(gpa1-5, INPUT, DOWN);
+
+ PIN_SLP(gpb-0, PREV, NONE);
+ PIN_SLP(gpb-1, PREV, NONE);
+ PIN_SLP(gpb-2, PREV, NONE);
+ PIN_SLP(gpb-3, PREV, NONE);
+ PIN_SLP(gpb-4, INPUT, DOWN);
+ PIN_SLP(gpb-5, INPUT, DOWN);
+ PIN_SLP(gpb-6, INPUT, DOWN);
+ PIN_SLP(gpb-7, INPUT, DOWN);
+
+ PIN_SLP(gpc0-0, INPUT, DOWN);
+ PIN_SLP(gpc0-1, INPUT, DOWN);
+ PIN_SLP(gpc0-2, INPUT, DOWN);
+ PIN_SLP(gpc0-3, INPUT, DOWN);
+ PIN_SLP(gpc0-4, INPUT, DOWN);
+
+ PIN_SLP(gpc1-0, INPUT, DOWN);
+ PIN_SLP(gpc1-1, INPUT, DOWN);
+ PIN_SLP(gpc1-2, INPUT, DOWN);
+ PIN_SLP(gpc1-3, INPUT, DOWN);
+ PIN_SLP(gpc1-4, INPUT, DOWN);
+
+ PIN_SLP(gpd0-0, INPUT, DOWN);
+ PIN_SLP(gpd0-1, INPUT, DOWN);
+ PIN_SLP(gpd0-2, INPUT, NONE);
+ PIN_SLP(gpd0-3, INPUT, NONE);
+
+ PIN_SLP(gpd1-0, INPUT, NONE);
+ PIN_SLP(gpd1-1, INPUT, NONE);
+ PIN_SLP(gpd1-2, INPUT, NONE);
+ PIN_SLP(gpd1-3, INPUT, NONE);
+ };
+};
+
+&pinctrl_1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sleep1>;
+
+ sleep1: sleep-state {
+ PIN_SLP(gpe0-0, PREV, NONE);
+ PIN_SLP(gpe0-1, PREV, NONE);
+ PIN_SLP(gpe0-2, INPUT, DOWN);
+ PIN_SLP(gpe0-3, INPUT, DOWN);
+ PIN_SLP(gpe0-4, PREV, NONE);
+ PIN_SLP(gpe0-5, INPUT, DOWN);
+ PIN_SLP(gpe0-6, INPUT, DOWN);
+ PIN_SLP(gpe0-7, INPUT, DOWN);
+
+ PIN_SLP(gpe1-0, INPUT, DOWN);
+ PIN_SLP(gpe1-1, PREV, NONE);
+ PIN_SLP(gpe1-2, INPUT, DOWN);
+ PIN_SLP(gpe1-3, INPUT, DOWN);
+ PIN_SLP(gpe1-4, INPUT, DOWN);
+ PIN_SLP(gpe1-5, INPUT, DOWN);
+ PIN_SLP(gpe1-6, INPUT, DOWN);
+ PIN_SLP(gpe1-7, INPUT, NONE);
+
+ PIN_SLP(gpe2-0, INPUT, NONE);
+ PIN_SLP(gpe2-1, INPUT, NONE);
+ PIN_SLP(gpe2-2, INPUT, NONE);
+
+ PIN_SLP(gpk0-0, INPUT, DOWN);
+ PIN_SLP(gpk0-1, INPUT, DOWN);
+ PIN_SLP(gpk0-2, OUT0, NONE);
+ PIN_SLP(gpk0-3, INPUT, DOWN);
+ PIN_SLP(gpk0-4, INPUT, DOWN);
+ PIN_SLP(gpk0-5, INPUT, DOWN);
+ PIN_SLP(gpk0-6, INPUT, DOWN);
+ PIN_SLP(gpk0-7, INPUT, DOWN);
+
+ PIN_SLP(gpk1-0, PREV, NONE);
+ PIN_SLP(gpk1-1, PREV, NONE);
+ PIN_SLP(gpk1-2, INPUT, DOWN);
+ PIN_SLP(gpk1-3, PREV, NONE);
+ PIN_SLP(gpk1-4, PREV, NONE);
+ PIN_SLP(gpk1-5, PREV, NONE);
+ PIN_SLP(gpk1-6, PREV, NONE);
+
+ PIN_SLP(gpk2-0, INPUT, DOWN);
+ PIN_SLP(gpk2-1, INPUT, DOWN);
+ PIN_SLP(gpk2-2, INPUT, DOWN);
+ PIN_SLP(gpk2-3, INPUT, DOWN);
+ PIN_SLP(gpk2-4, INPUT, DOWN);
+ PIN_SLP(gpk2-5, INPUT, DOWN);
+ PIN_SLP(gpk2-6, INPUT, DOWN);
+
+ PIN_SLP(gpl0-0, INPUT, DOWN);
+ PIN_SLP(gpl0-1, INPUT, DOWN);
+ PIN_SLP(gpl0-2, INPUT, DOWN);
+ PIN_SLP(gpl0-3, INPUT, DOWN);
+
+ PIN_SLP(gpm0-0, INPUT, DOWN);
+ PIN_SLP(gpm0-1, INPUT, DOWN);
+ PIN_SLP(gpm0-2, INPUT, DOWN);
+ PIN_SLP(gpm0-3, INPUT, DOWN);
+ PIN_SLP(gpm0-4, INPUT, DOWN);
+ PIN_SLP(gpm0-5, INPUT, DOWN);
+ PIN_SLP(gpm0-6, INPUT, DOWN);
+ PIN_SLP(gpm0-7, INPUT, DOWN);
+
+ PIN_SLP(gpm1-0, INPUT, DOWN);
+ PIN_SLP(gpm1-1, INPUT, DOWN);
+ PIN_SLP(gpm1-2, INPUT, DOWN);
+ PIN_SLP(gpm1-3, INPUT, DOWN);
+ PIN_SLP(gpm1-4, INPUT, DOWN);
+ PIN_SLP(gpm1-5, INPUT, DOWN);
+ PIN_SLP(gpm1-6, INPUT, DOWN);
+
+ PIN_SLP(gpm2-0, INPUT, DOWN);
+ PIN_SLP(gpm2-1, INPUT, DOWN);
+ PIN_SLP(gpm2-2, INPUT, DOWN);
+ PIN_SLP(gpm2-3, INPUT, DOWN);
+ PIN_SLP(gpm2-4, INPUT, DOWN);
+
+ PIN_SLP(gpm3-0, INPUT, DOWN);
+ PIN_SLP(gpm3-1, INPUT, DOWN);
+ PIN_SLP(gpm3-2, INPUT, DOWN);
+ PIN_SLP(gpm3-3, INPUT, DOWN);
+ PIN_SLP(gpm3-4, INPUT, DOWN);
+ PIN_SLP(gpm3-5, INPUT, DOWN);
+ PIN_SLP(gpm3-6, INPUT, DOWN);
+ PIN_SLP(gpm3-7, INPUT, DOWN);
+
+ PIN_SLP(gpm4-0, INPUT, DOWN);
+ PIN_SLP(gpm4-1, INPUT, DOWN);
+ PIN_SLP(gpm4-2, INPUT, DOWN);
+ PIN_SLP(gpm4-3, INPUT, DOWN);
+ PIN_SLP(gpm4-4, INPUT, DOWN);
+ PIN_SLP(gpm4-5, INPUT, DOWN);
+ PIN_SLP(gpm4-6, INPUT, DOWN);
+ PIN_SLP(gpm4-7, INPUT, DOWN);
+ };
+};
diff --git a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
new file mode 100644
index 000000000..5ab81c39e
--- /dev/null
+++ b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
@@ -0,0 +1,491 @@
+/*
+ * Samsung's Exynos3250 SoCs pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung's Exynos3250 SoCs pin-mux and pin-config optiosn are listed as device
+ * tree nodes are listed in this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define PIN_PULL_NONE 0
+#define PIN_PULL_DOWN 1
+#define PIN_PULL_UP 3
+
+#define PIN_PDN_OUT0 0
+#define PIN_PDN_OUT1 1
+#define PIN_PDN_INPUT 2
+#define PIN_PDN_PREV 3
+
+#define PIN_SLP(_pin, _mode, _pull) \
+ _pin { \
+ samsung,pins = #_pin; \
+ samsung,pin-con-pdn = <PIN_PDN_ ##_mode>; \
+ samsung,pin-pud-pdn = <PIN_PULL_ ##_pull>; \
+ }
+
+&pinctrl_0 {
+ gpa0: gpa0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpa1: gpa1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb: gpb {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc0: gpc0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc1: gpc1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd0: gpd0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd1: gpd1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart0_data: uart0-data {
+ samsung,pins = "gpa0-0", "gpa0-1";
+ samsung,pin-function = <0x2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart0_fctl: uart0-fctl {
+ samsung,pins = "gpa0-2", "gpa0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_data: uart1-data {
+ samsung,pins = "gpa0-4", "gpa0-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_fctl: uart1-fctl {
+ samsung,pins = "gpa0-6", "gpa0-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c2_bus: i2c2-bus {
+ samsung,pins = "gpa0-6", "gpa0-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c3_bus: i2c3-bus {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi0_bus: spi0-bus {
+ samsung,pins = "gpb-0", "gpb-2", "gpb-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c4_bus: i2c4-bus {
+ samsung,pins = "gpb-0", "gpb-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi1_bus: spi1-bus {
+ samsung,pins = "gpb-4", "gpb-6", "gpb-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c5_bus: i2c5-bus {
+ samsung,pins = "gpb-2", "gpb-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s2_bus: i2s2-bus {
+ samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+ "gpc1-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm2_bus: pcm2-bus {
+ samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+ "gpc1-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c6_bus: i2c6-bus {
+ samsung,pins = "gpc1-3", "gpc1-4";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm0_out: pwm0-out {
+ samsung,pins = "gpd0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm1_out: pwm1-out {
+ samsung,pins = "gpd0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c7_bus: i2c7-bus {
+ samsung,pins = "gpd0-2", "gpd0-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm2_out: pwm2-out {
+ samsung,pins = "gpd0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm3_out: pwm3-out {
+ samsung,pins = "gpd0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c0_bus: i2c0-bus {
+ samsung,pins = "gpd1-0", "gpd1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ mipi0_clk: mipi0-clk {
+ samsung,pins = "gpd1-0", "gpd1-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c1_bus: i2c1-bus {
+ samsung,pins = "gpd1-2", "gpd1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_1 {
+ gpe0: gpe0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpe1: gpe1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpe2: gpe2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpk0: gpk0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpk1: gpk1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpk2: gpk2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpl0: gpl0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpm0: gpm0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpm1: gpm1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpm2: gpm2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpm3: gpm3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpm4: gpm4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx0: gpx0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <0 32 0>, <0 33 0>, <0 34 0>, <0 35 0>,
+ <0 36 0>, <0 37 0>, <0 38 0>, <0 39 0>;
+ #interrupt-cells = <2>;
+ };
+
+ gpx1: gpx1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <0 40 0>, <0 41 0>, <0 42 0>, <0 43 0>,
+ <0 44 0>, <0 45 0>, <0 46 0>, <0 47 0>;
+ #interrupt-cells = <2>;
+ };
+
+ gpx2: gpx2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx3: gpx3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ sd0_clk: sd0-clk {
+ samsung,pins = "gpk0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ samsung,pins = "gpk0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cd: sd0-cd {
+ samsung,pins = "gpk0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_rdqs: sd0-rdqs {
+ samsung,pins = "gpk0-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ samsung,pins = "gpk0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ samsung,pins = "gpk0-4", "gpk0-5", "gpk0-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus8: sd0-bus-width8 {
+ samsung,pins = "gpl0-0", "gpl0-1", "gpl0-2", "gpl0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_clk: sd1-clk {
+ samsung,pins = "gpk1-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ samsung,pins = "gpk1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cd: sd1-cd {
+ samsung,pins = "gpk1-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ samsung,pins = "gpk1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ samsung,pins = "gpk1-4", "gpk1-5", "gpk1-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ cam_port_b_io: cam-port-b-io {
+ samsung,pins = "gpm0-0", "gpm0-1", "gpm0-2", "gpm0-3",
+ "gpm0-4", "gpm0-5", "gpm0-6", "gpm0-7",
+ "gpm1-0", "gpm1-1", "gpm2-0", "gpm2-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_port_b_clk_active: cam-port-b-clk-active {
+ samsung,pins = "gpm2-2";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ cam_port_b_clk_idle: cam-port-b-clk-idle {
+ samsung,pins = "gpm2-2";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_i2c0: fimc-is-i2c0 {
+ samsung,pins = "gpm4-0", "gpm4-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_i2c1: fimc-is-i2c1 {
+ samsung,pins = "gpm4-2", "gpm4-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_uart: fimc-is-uart {
+ samsung,pins = "gpm3-5", "gpm3-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
new file mode 100644
index 000000000..0b9906880
--- /dev/null
+++ b/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -0,0 +1,809 @@
+/*
+ * Samsung's Exynos3250 based Rinato board device tree source
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Device tree source file for Samsung's Rinato board which is based on
+ * Samsung Exynos3250 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+#include "exynos3250.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Samsung Rinato board";
+ compatible = "samsung,rinato", "samsung,exynos3250", "samsung,exynos3";
+
+ aliases {
+ i2c7 = &i2c_max77836;
+ };
+
+ memory {
+ reg = <0x40000000 0x1ff00000>;
+ };
+
+ firmware@0205F000 {
+ compatible = "samsung,secure-firmware";
+ reg = <0x0205F000 0x1000>;
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ power_key {
+ gpios = <&gpx2 7 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ label = "power key";
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ i2c_max77836: i2c-gpio-0 {
+ compatible = "i2c-gpio";
+ gpios = <&gpd0 2 0>, <&gpd0 3 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ max77836: subpmic@25 {
+ compatible = "maxim,max77836";
+ interrupt-parent = <&gpx1>;
+ interrupts = <5 0>;
+ reg = <0x25>;
+ wakeup;
+
+ muic: max77836-muic {
+ compatible = "maxim,max77836-muic";
+ };
+
+ regulators {
+ compatible = "maxim,max77836-regulator";
+ safeout_reg: SAFEOUT {
+ regulator-name = "SAFEOUT";
+ };
+
+ charger_reg: CHARGER {
+ regulator-name = "CHARGER";
+ regulator-min-microamp = <45000>;
+ regulator-max-microamp = <475000>;
+ regulator-boot-on;
+ };
+
+ motor_reg: LDO1 {
+ regulator-name = "MOT_2.7V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <2700000>;
+ };
+
+ LDO2 {
+ regulator-name = "UNUSED_LDO2";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3950000>;
+ };
+ };
+
+ charger {
+ compatible = "maxim,max77836-charger";
+
+ maxim,constant-uvolt = <4350000>;
+ maxim,fast-charge-uamp = <225000>;
+ maxim,eoc-uamp = <7500>;
+ maxim,ovp-uvolt = <6500000>;
+ };
+ };
+ };
+
+ haptics {
+ compatible = "regulator-haptic";
+ haptic-supply = <&motor_reg>;
+ min-microvolt = <1100000>;
+ max-microvolt = <2700000>;
+ };
+};
+
+&adc {
+ vdd-supply = <&ldo3_reg>;
+ status = "okay";
+ assigned-clocks = <&cmu CLK_SCLK_TSADC>;
+ assigned-clock-rates = <6000000>;
+
+ thermistor-ap {
+ compatible = "ntc,ncp15wb473";
+ pullup-uv = <1800000>;
+ pullup-ohm = <100000>;
+ pulldown-ohm = <100000>;
+ io-channels = <&adc 0>;
+ };
+
+ thermistor-battery {
+ compatible = "ntc,ncp15wb473";
+ pullup-uv = <1800000>;
+ pullup-ohm = <100000>;
+ pulldown-ohm = <100000>;
+ io-channels = <&adc 1>;
+ };
+};
+
+&exynos_usbphy {
+ status = "okay";
+};
+
+&hsotg {
+ vusb_d-supply = <&ldo15_reg>;
+ vusb_a-supply = <&ldo12_reg>;
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&dsi_0 {
+ vddcore-supply = <&ldo6_reg>;
+ vddio-supply = <&ldo6_reg>;
+ samsung,pll-clock-frequency = <24000000>;
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+
+ dsi_out: endpoint {
+ remote-endpoint = <&dsi_in>;
+ samsung,burst-clock-frequency = <250000000>;
+ samsung,esc-clock-frequency = <20000000>;
+ };
+ };
+ };
+
+ panel@0 {
+ compatible = "samsung,s6e63j0x03";
+ reg = <0>;
+ vdd3-supply = <&ldo16_reg>;
+ vci-supply = <&ldo20_reg>;
+ reset-gpios = <&gpe0 1 0>;
+ te-gpios = <&gpx0 6 0>;
+ power-on-delay= <30>;
+ power-off-delay= <120>;
+ reset-delay = <5>;
+ init-delay = <100>;
+ flip-horizontal;
+ flip-vertical;
+ panel-width-mm = <29>;
+ panel-height-mm = <29>;
+
+ display-timings {
+ timing-0 {
+ clock-frequency = <0>;
+ hactive = <320>;
+ vactive = <320>;
+ hfront-porch = <1>;
+ hback-porch = <1>;
+ hsync-len = <1>;
+ vfront-porch = <150>;
+ vback-porch = <1>;
+ vsync-len = <2>;
+ };
+ };
+
+ port {
+ dsi_in: endpoint {
+ remote-endpoint = <&dsi_out>;
+ };
+ };
+ };
+};
+
+&fimd {
+ status = "okay";
+
+ i80-if-timings {
+ cs-setup = <0>;
+ wr-setup = <0>;
+ wr-act = <1>;
+ wr-hold = <0>;
+ };
+};
+
+&i2c_0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-slave-addr = <0x10>;
+ samsung,i2c-max-bus-freq = <100000>;
+ status = "okay";
+
+ s2mps14_pmic@66 {
+ compatible = "samsung,s2mps14-pmic";
+ interrupt-parent = <&gpx0>;
+ interrupts = <7 0>;
+ reg = <0x66>;
+ wakeup;
+
+ s2mps14_osc: clocks {
+ compatible = "samsung,s2mps14-clk";
+ #clock-cells = <1>;
+ clock-output-names = "s2mps14_ap", "unused",
+ "s2mps14_bt";
+ };
+
+ regulators {
+ ldo1_reg: LDO1 {
+ regulator-name = "VAP_ALIVE_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "VAP_M1_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "VCC_AP_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "VAP_AVDD_PLL1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "VAP_PLL_ISO_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "VAP_VMIPI_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "VAP_AVDD_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "VAP_USB_3.0V";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "V_LPDDR_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "UNUSED_LDO10";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "V_EMMC_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ samsung,ext-control-gpios = <&gpk0 2 0>;
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "V_EMMC_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ samsung,ext-control-gpios = <&gpk0 2 0>;
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "CAM_AVDD_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "UNUSED_LDO14";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "TSP_AVDD_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "LCD_VDD_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "V_IRLED_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo18_reg: LDO18 {
+ regulator-name = "CAM_AF_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo19_reg: LDO19 {
+ regulator-name = "TSP_VDD_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo20_reg: LDO20 {
+ regulator-name = "LCD_VDD_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo21_reg: LDO21 {
+ regulator-name = "CAM_IO_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo22_reg: LDO22 {
+ regulator-name = "CAM_DVDD_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo23_reg: LDO23 {
+ regulator-name = "HRM_VCC_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo24_reg: LDO24 {
+ regulator-name = "HRM_VCC_3.3V";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo25_reg: LDO25 {
+ regulator-name = "UNUSED_LDO25";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "VAP_MIF_1.0V";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <900000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "VAP_ARM_1.0V";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "VAP_INT3D_1.0V";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "VCC_SUB_1.95V";
+ regulator-min-microvolt = <1950000>;
+ regulator-max-microvolt = <1950000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "VCC_SUB_1.35V";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&i2c_1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-slave-addr = <0x10>;
+ samsung,i2c-max-bus-freq = <400000>;
+ status = "okay";
+
+ fuelgauge@36 {
+ compatible = "maxim,max77836-battery";
+ interrupt-parent = <&gpx1>;
+ interrupts = <2 8>;
+ reg = <0x36>;
+ };
+};
+
+&i2s2 {
+ status = "okay";
+};
+
+&mfc {
+ status = "okay";
+};
+
+&mshc_0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ num-slots = <1>;
+ broken-cd;
+ non-removable;
+ cap-mmc-highspeed;
+ desc-num = <4>;
+ mmc-hs200-1_8v;
+ card-detect-delay = <200>;
+ vmmc-supply = <&ldo12_reg>;
+ clock-frequency = <100000000>;
+ clock-freq-min-max = <400000 100000000>;
+ samsung,dw-mshc-ciu-div = <1>;
+ samsung,dw-mshc-sdr-timing = <0 1>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8>;
+ bus-width = <8>;
+ status = "okay";
+};
+
+&serial_0 {
+ assigned-clocks = <&cmu CLK_SCLK_UART0>;
+ assigned-clock-rates = <100000000>;
+ status = "okay";
+};
+
+&serial_1 {
+ status = "okay";
+};
+
+&tmu {
+ vtmu-supply = <&ldo7_reg>;
+ status = "okay";
+};
+
+&rtc {
+ clocks = <&cmu CLK_RTC>, <&s2mps14_osc 0>;
+ clock-names = "rtc", "rtc_src";
+ status = "okay";
+};
+
+&ppmu_dmc0 {
+ status = "okay";
+
+ events {
+ ppmu_dmc0_3: ppmu-event3-dmc0 {
+ event-name = "ppmu-event3-dmc0";
+ };
+ };
+};
+
+&ppmu_dmc1 {
+ status = "okay";
+
+ events {
+ ppmu_dmc1_3: ppmu-event3-dmc1 {
+ event-name = "ppmu-event3-dmc1";
+ };
+ };
+};
+
+&ppmu_leftbus {
+ status = "okay";
+
+ events {
+ ppmu_leftbus_3: ppmu-event3-leftbus {
+ event-name = "ppmu-event3-leftbus";
+ };
+ };
+};
+
+&ppmu_rightbus {
+ status = "okay";
+
+ events {
+ ppmu_rightbus_3: ppmu-event3-rightbus {
+ event-name = "ppmu-event3-rightbus";
+ };
+ };
+};
+
+&xusbxti {
+ clock-frequency = <24000000>;
+};
+
+&pinctrl_0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sleep0>;
+
+ sleep0: sleep-state {
+ PIN_SLP(gpa0-0, INPUT, DOWN);
+ PIN_SLP(gpa0-1, INPUT, DOWN);
+ PIN_SLP(gpa0-2, INPUT, DOWN);
+ PIN_SLP(gpa0-3, INPUT, DOWN);
+ PIN_SLP(gpa0-4, INPUT, DOWN);
+ PIN_SLP(gpa0-5, INPUT, DOWN);
+ PIN_SLP(gpa0-6, INPUT, DOWN);
+ PIN_SLP(gpa0-7, INPUT, DOWN);
+
+ PIN_SLP(gpa1-0, INPUT, DOWN);
+ PIN_SLP(gpa1-1, INPUT, DOWN);
+ PIN_SLP(gpa1-2, INPUT, DOWN);
+ PIN_SLP(gpa1-3, INPUT, DOWN);
+ PIN_SLP(gpa1-4, INPUT, DOWN);
+ PIN_SLP(gpa1-5, INPUT, DOWN);
+
+ PIN_SLP(gpb-0, PREV, NONE);
+ PIN_SLP(gpb-1, PREV, NONE);
+ PIN_SLP(gpb-2, PREV, NONE);
+ PIN_SLP(gpb-3, PREV, NONE);
+ PIN_SLP(gpb-4, INPUT, DOWN);
+ PIN_SLP(gpb-5, INPUT, DOWN);
+ PIN_SLP(gpb-6, INPUT, DOWN);
+ PIN_SLP(gpb-7, INPUT, DOWN);
+
+ PIN_SLP(gpc0-0, INPUT, DOWN);
+ PIN_SLP(gpc0-1, INPUT, DOWN);
+ PIN_SLP(gpc0-2, INPUT, DOWN);
+ PIN_SLP(gpc0-3, INPUT, DOWN);
+ PIN_SLP(gpc0-4, INPUT, DOWN);
+
+ PIN_SLP(gpc1-0, INPUT, DOWN);
+ PIN_SLP(gpc1-1, INPUT, DOWN);
+ PIN_SLP(gpc1-2, INPUT, DOWN);
+ PIN_SLP(gpc1-3, INPUT, DOWN);
+ PIN_SLP(gpc1-4, INPUT, DOWN);
+
+ PIN_SLP(gpd0-0, INPUT, DOWN);
+ PIN_SLP(gpd0-1, INPUT, DOWN);
+ PIN_SLP(gpd0-2, INPUT, NONE);
+ PIN_SLP(gpd0-3, INPUT, NONE);
+
+ PIN_SLP(gpd1-0, INPUT, NONE);
+ PIN_SLP(gpd1-1, INPUT, NONE);
+ PIN_SLP(gpd1-2, INPUT, NONE);
+ PIN_SLP(gpd1-3, INPUT, NONE);
+ };
+};
+
+&pinctrl_1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sleep1>;
+
+ sleep1: sleep-state {
+ PIN_SLP(gpe0-0, PREV, NONE);
+ PIN_SLP(gpe0-1, PREV, NONE);
+ PIN_SLP(gpe0-2, INPUT, DOWN);
+ PIN_SLP(gpe0-3, INPUT, UP);
+ PIN_SLP(gpe0-4, INPUT, DOWN);
+ PIN_SLP(gpe0-5, INPUT, DOWN);
+ PIN_SLP(gpe0-6, INPUT, DOWN);
+ PIN_SLP(gpe0-7, INPUT, DOWN);
+
+ PIN_SLP(gpe1-0, INPUT, DOWN);
+ PIN_SLP(gpe1-1, PREV, NONE);
+ PIN_SLP(gpe1-2, INPUT, DOWN);
+ PIN_SLP(gpe1-3, INPUT, DOWN);
+ PIN_SLP(gpe1-4, INPUT, DOWN);
+ PIN_SLP(gpe1-5, INPUT, DOWN);
+ PIN_SLP(gpe1-6, INPUT, DOWN);
+ PIN_SLP(gpe1-7, INPUT, NONE);
+
+ PIN_SLP(gpe2-0, INPUT, NONE);
+ PIN_SLP(gpe2-1, INPUT, NONE);
+ PIN_SLP(gpe2-2, INPUT, NONE);
+
+ PIN_SLP(gpk0-0, INPUT, DOWN);
+ PIN_SLP(gpk0-1, INPUT, DOWN);
+ PIN_SLP(gpk0-2, OUT0, NONE);
+ PIN_SLP(gpk0-3, INPUT, DOWN);
+ PIN_SLP(gpk0-4, INPUT, DOWN);
+ PIN_SLP(gpk0-5, INPUT, DOWN);
+ PIN_SLP(gpk0-6, INPUT, DOWN);
+ PIN_SLP(gpk0-7, INPUT, DOWN);
+
+ PIN_SLP(gpk1-0, INPUT, DOWN);
+ PIN_SLP(gpk1-1, INPUT, DOWN);
+ PIN_SLP(gpk1-2, INPUT, DOWN);
+ PIN_SLP(gpk1-3, INPUT, DOWN);
+ PIN_SLP(gpk1-4, INPUT, DOWN);
+ PIN_SLP(gpk1-5, INPUT, DOWN);
+ PIN_SLP(gpk1-6, INPUT, DOWN);
+
+ PIN_SLP(gpk2-0, INPUT, DOWN);
+ PIN_SLP(gpk2-1, INPUT, DOWN);
+ PIN_SLP(gpk2-2, INPUT, DOWN);
+ PIN_SLP(gpk2-3, INPUT, DOWN);
+ PIN_SLP(gpk2-4, INPUT, DOWN);
+ PIN_SLP(gpk2-5, INPUT, DOWN);
+ PIN_SLP(gpk2-6, INPUT, DOWN);
+
+ PIN_SLP(gpl0-0, INPUT, DOWN);
+ PIN_SLP(gpl0-1, INPUT, DOWN);
+ PIN_SLP(gpl0-2, INPUT, DOWN);
+ PIN_SLP(gpl0-3, INPUT, DOWN);
+
+ PIN_SLP(gpm0-0, INPUT, DOWN);
+ PIN_SLP(gpm0-1, INPUT, DOWN);
+ PIN_SLP(gpm0-2, INPUT, DOWN);
+ PIN_SLP(gpm0-3, INPUT, DOWN);
+ PIN_SLP(gpm0-4, INPUT, DOWN);
+ PIN_SLP(gpm0-5, INPUT, DOWN);
+ PIN_SLP(gpm0-6, INPUT, DOWN);
+ PIN_SLP(gpm0-7, INPUT, DOWN);
+
+ PIN_SLP(gpm1-0, INPUT, DOWN);
+ PIN_SLP(gpm1-1, INPUT, DOWN);
+ PIN_SLP(gpm1-2, INPUT, DOWN);
+ PIN_SLP(gpm1-3, INPUT, DOWN);
+ PIN_SLP(gpm1-4, INPUT, DOWN);
+ PIN_SLP(gpm1-5, INPUT, DOWN);
+ PIN_SLP(gpm1-6, INPUT, DOWN);
+
+ PIN_SLP(gpm2-0, INPUT, DOWN);
+ PIN_SLP(gpm2-1, INPUT, DOWN);
+ PIN_SLP(gpm2-2, INPUT, DOWN);
+ PIN_SLP(gpm2-3, INPUT, DOWN);
+ PIN_SLP(gpm2-4, INPUT, DOWN);
+
+ PIN_SLP(gpm3-0, INPUT, DOWN);
+ PIN_SLP(gpm3-1, INPUT, DOWN);
+ PIN_SLP(gpm3-2, INPUT, DOWN);
+ PIN_SLP(gpm3-3, INPUT, DOWN);
+ PIN_SLP(gpm3-4, INPUT, DOWN);
+ PIN_SLP(gpm3-5, INPUT, DOWN);
+ PIN_SLP(gpm3-6, INPUT, DOWN);
+ PIN_SLP(gpm3-7, INPUT, DOWN);
+
+ PIN_SLP(gpm4-0, INPUT, DOWN);
+ PIN_SLP(gpm4-1, INPUT, DOWN);
+ PIN_SLP(gpm4-2, INPUT, DOWN);
+ PIN_SLP(gpm4-3, INPUT, DOWN);
+ PIN_SLP(gpm4-4, INPUT, DOWN);
+ PIN_SLP(gpm4-5, INPUT, DOWN);
+ PIN_SLP(gpm4-6, INPUT, DOWN);
+ PIN_SLP(gpm4-7, INPUT, DOWN);
+ };
+};
diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
new file mode 100644
index 000000000..e3bfb11c6
--- /dev/null
+++ b/arch/arm/boot/dts/exynos3250.dtsi
@@ -0,0 +1,631 @@
+/*
+ * Samsung's Exynos3250 SoC device tree source
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung's Exynos3250 SoC device nodes are listed in this file. Exynos3250
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * Exynos3250 SoC. As device tree coverage for Exynos3250 increases, additional
+ * nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "skeleton.dtsi"
+#include "exynos4-cpu-thermal.dtsi"
+#include <dt-bindings/clock/exynos3250.h>
+
+/ {
+ compatible = "samsung,exynos3250";
+ interrupt-parent = <&gic>;
+
+ aliases {
+ pinctrl0 = &pinctrl_0;
+ pinctrl1 = &pinctrl_1;
+ mshc0 = &mshc_0;
+ mshc1 = &mshc_1;
+ spi0 = &spi_0;
+ spi1 = &spi_1;
+ i2c0 = &i2c_0;
+ i2c1 = &i2c_1;
+ i2c2 = &i2c_2;
+ i2c3 = &i2c_3;
+ i2c4 = &i2c_4;
+ i2c5 = &i2c_5;
+ i2c6 = &i2c_6;
+ i2c7 = &i2c_7;
+ serial0 = &serial_0;
+ serial1 = &serial_1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0>;
+ clock-frequency = <1000000000>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <1>;
+ clock-frequency = <1000000000>;
+ };
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ fixed-rate-clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ xusbxti: clock@0 {
+ compatible = "fixed-clock";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ clock-frequency = <0>;
+ #clock-cells = <0>;
+ clock-output-names = "xusbxti";
+ };
+
+ xxti: clock@1 {
+ compatible = "fixed-clock";
+ reg = <1>;
+ clock-frequency = <0>;
+ #clock-cells = <0>;
+ clock-output-names = "xxti";
+ };
+
+ xtcxo: clock@2 {
+ compatible = "fixed-clock";
+ reg = <2>;
+ clock-frequency = <0>;
+ #clock-cells = <0>;
+ clock-output-names = "xtcxo";
+ };
+ };
+
+ sysram@02020000 {
+ compatible = "mmio-sram";
+ reg = <0x02020000 0x40000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x02020000 0x40000>;
+
+ smp-sysram@0 {
+ compatible = "samsung,exynos4210-sysram";
+ reg = <0x0 0x1000>;
+ };
+
+ smp-sysram@3f000 {
+ compatible = "samsung,exynos4210-sysram-ns";
+ reg = <0x3f000 0x1000>;
+ };
+ };
+
+ chipid@10000000 {
+ compatible = "samsung,exynos4210-chipid";
+ reg = <0x10000000 0x100>;
+ };
+
+ sys_reg: syscon@10010000 {
+ compatible = "samsung,exynos3-sysreg", "syscon";
+ reg = <0x10010000 0x400>;
+ };
+
+ pmu_system_controller: system-controller@10020000 {
+ compatible = "samsung,exynos3250-pmu", "syscon";
+ reg = <0x10020000 0x4000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ };
+
+ mipi_phy: video-phy@10020710 {
+ compatible = "samsung,s5pv210-mipi-video-phy";
+ reg = <0x10020710 8>;
+ #phy-cells = <1>;
+ };
+
+ pd_cam: cam-power-domain@10023C00 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10023C00 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_mfc: mfc-power-domain@10023C40 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10023C40 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_g3d: g3d-power-domain@10023C60 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10023C60 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_lcd0: lcd0-power-domain@10023C80 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10023C80 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_isp: isp-power-domain@10023CA0 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10023CA0 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ cmu: clock-controller@10030000 {
+ compatible = "samsung,exynos3250-cmu";
+ reg = <0x10030000 0x20000>;
+ #clock-cells = <1>;
+ assigned-clocks = <&cmu CLK_MOUT_ACLK_400_MCUISP_SUB>,
+ <&cmu CLK_MOUT_ACLK_266_SUB>;
+ assigned-clock-parents = <&cmu CLK_FIN_PLL>,
+ <&cmu CLK_FIN_PLL>;
+ };
+
+ cmu_dmc: clock-controller@105C0000 {
+ compatible = "samsung,exynos3250-cmu-dmc";
+ reg = <0x105C0000 0x2000>;
+ #clock-cells = <1>;
+ };
+
+ rtc: rtc@10070000 {
+ compatible = "samsung,exynos3250-rtc";
+ reg = <0x10070000 0x100>;
+ interrupts = <0 73 0>, <0 74 0>;
+ interrupt-parent = <&pmu_system_controller>;
+ status = "disabled";
+ };
+
+ tmu: tmu@100C0000 {
+ compatible = "samsung,exynos3250-tmu";
+ reg = <0x100C0000 0x100>;
+ interrupts = <0 216 0>;
+ clocks = <&cmu CLK_TMU_APBIF>;
+ clock-names = "tmu_apbif";
+ #include "exynos4412-tmu-sensor-conf.dtsi"
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@10481000 {
+ compatible = "arm,cortex-a15-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x10481000 0x1000>,
+ <0x10482000 0x1000>,
+ <0x10484000 0x2000>,
+ <0x10486000 0x2000>;
+ interrupts = <1 9 0xf04>;
+ };
+
+ mct@10050000 {
+ compatible = "samsung,exynos4210-mct";
+ reg = <0x10050000 0x800>;
+ interrupts = <0 218 0>, <0 219 0>, <0 220 0>, <0 221 0>,
+ <0 223 0>, <0 226 0>, <0 227 0>, <0 228 0>;
+ clocks = <&cmu CLK_FIN_PLL>, <&cmu CLK_MCT>;
+ clock-names = "fin_pll", "mct";
+ };
+
+ pinctrl_1: pinctrl@11000000 {
+ compatible = "samsung,exynos3250-pinctrl";
+ reg = <0x11000000 0x1000>;
+ interrupts = <0 225 0>;
+
+ wakeup-interrupt-controller {
+ compatible = "samsung,exynos4210-wakeup-eint";
+ interrupts = <0 48 0>;
+ };
+ };
+
+ pinctrl_0: pinctrl@11400000 {
+ compatible = "samsung,exynos3250-pinctrl";
+ reg = <0x11400000 0x1000>;
+ interrupts = <0 240 0>;
+ };
+
+ fimd: fimd@11c00000 {
+ compatible = "samsung,exynos3250-fimd";
+ reg = <0x11c00000 0x30000>;
+ interrupt-names = "fifo", "vsync", "lcd_sys";
+ interrupts = <0 84 0>, <0 85 0>, <0 86 0>;
+ clocks = <&cmu CLK_SCLK_FIMD0>, <&cmu CLK_FIMD0>;
+ clock-names = "sclk_fimd", "fimd";
+ power-domains = <&pd_lcd0>;
+ samsung,sysreg = <&sys_reg>;
+ status = "disabled";
+ };
+
+ dsi_0: dsi@11C80000 {
+ compatible = "samsung,exynos3250-mipi-dsi";
+ reg = <0x11C80000 0x10000>;
+ interrupts = <0 83 0>;
+ samsung,phy-type = <0>;
+ power-domains = <&pd_lcd0>;
+ phys = <&mipi_phy 1>;
+ phy-names = "dsim";
+ clocks = <&cmu CLK_DSIM0>, <&cmu CLK_SCLK_MIPI0>;
+ clock-names = "bus_clk", "pll_clk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ hsotg: hsotg@12480000 {
+ compatible = "snps,dwc2";
+ reg = <0x12480000 0x20000>;
+ interrupts = <0 141 0>;
+ clocks = <&cmu CLK_USBOTG>;
+ clock-names = "otg";
+ phys = <&exynos_usbphy 0>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ mshc_0: mshc@12510000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ reg = <0x12510000 0x1000>;
+ interrupts = <0 142 0>;
+ clocks = <&cmu CLK_SDMMC0>, <&cmu CLK_SCLK_MMC0>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ mshc_1: mshc@12520000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ reg = <0x12520000 0x1000>;
+ interrupts = <0 143 0>;
+ clocks = <&cmu CLK_SDMMC1>, <&cmu CLK_SCLK_MMC1>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ exynos_usbphy: exynos-usbphy@125B0000 {
+ compatible = "samsung,exynos3250-usb2-phy";
+ reg = <0x125B0000 0x100>;
+ samsung,pmureg-phandle = <&pmu_system_controller>;
+ clocks = <&cmu CLK_USBOTG>, <&cmu CLK_SCLK_UPLL>;
+ clock-names = "phy", "ref";
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pdma0: pdma@12680000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x12680000 0x1000>;
+ interrupts = <0 138 0>;
+ clocks = <&cmu CLK_PDMA0>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+
+ pdma1: pdma@12690000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x12690000 0x1000>;
+ interrupts = <0 139 0>;
+ clocks = <&cmu CLK_PDMA1>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+ };
+
+ adc: adc@126C0000 {
+ compatible = "samsung,exynos3250-adc",
+ "samsung,exynos-adc-v2";
+ reg = <0x126C0000 0x100>;
+ interrupts = <0 137 0>;
+ clock-names = "adc", "sclk";
+ clocks = <&cmu CLK_TSADC>, <&cmu CLK_SCLK_TSADC>;
+ #io-channel-cells = <1>;
+ io-channel-ranges;
+ samsung,syscon-phandle = <&pmu_system_controller>;
+ status = "disabled";
+ };
+
+ mfc: codec@13400000 {
+ compatible = "samsung,mfc-v7";
+ reg = <0x13400000 0x10000>;
+ interrupts = <0 102 0>;
+ clock-names = "mfc", "sclk_mfc";
+ clocks = <&cmu CLK_MFC>, <&cmu CLK_SCLK_MFC>;
+ power-domains = <&pd_mfc>;
+ status = "disabled";
+ };
+
+ serial_0: serial@13800000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x13800000 0x100>;
+ interrupts = <0 109 0>;
+ clocks = <&cmu CLK_UART0>, <&cmu CLK_SCLK_UART0>;
+ clock-names = "uart", "clk_uart_baud0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_data &uart0_fctl>;
+ status = "disabled";
+ };
+
+ serial_1: serial@13810000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x13810000 0x100>;
+ interrupts = <0 110 0>;
+ clocks = <&cmu CLK_UART1>, <&cmu CLK_SCLK_UART1>;
+ clock-names = "uart", "clk_uart_baud0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_data>;
+ status = "disabled";
+ };
+
+ i2c_0: i2c@13860000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13860000 0x100>;
+ interrupts = <0 113 0>;
+ clocks = <&cmu CLK_I2C0>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_bus>;
+ status = "disabled";
+ };
+
+ i2c_1: i2c@13870000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13870000 0x100>;
+ interrupts = <0 114 0>;
+ clocks = <&cmu CLK_I2C1>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_bus>;
+ status = "disabled";
+ };
+
+ i2c_2: i2c@13880000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13880000 0x100>;
+ interrupts = <0 115 0>;
+ clocks = <&cmu CLK_I2C2>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_bus>;
+ status = "disabled";
+ };
+
+ i2c_3: i2c@13890000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13890000 0x100>;
+ interrupts = <0 116 0>;
+ clocks = <&cmu CLK_I2C3>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_bus>;
+ status = "disabled";
+ };
+
+ i2c_4: i2c@138A0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x138A0000 0x100>;
+ interrupts = <0 117 0>;
+ clocks = <&cmu CLK_I2C4>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_bus>;
+ status = "disabled";
+ };
+
+ i2c_5: i2c@138B0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x138B0000 0x100>;
+ interrupts = <0 118 0>;
+ clocks = <&cmu CLK_I2C5>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5_bus>;
+ status = "disabled";
+ };
+
+ i2c_6: i2c@138C0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x138C0000 0x100>;
+ interrupts = <0 119 0>;
+ clocks = <&cmu CLK_I2C6>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c6_bus>;
+ status = "disabled";
+ };
+
+ i2c_7: i2c@138D0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x138D0000 0x100>;
+ interrupts = <0 120 0>;
+ clocks = <&cmu CLK_I2C7>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c7_bus>;
+ status = "disabled";
+ };
+
+ spi_0: spi@13920000 {
+ compatible = "samsung,exynos4210-spi";
+ reg = <0x13920000 0x100>;
+ interrupts = <0 121 0>;
+ dmas = <&pdma0 7>, <&pdma0 6>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu CLK_SPI0>, <&cmu CLK_SCLK_SPI0>;
+ clock-names = "spi", "spi_busclk0";
+ samsung,spi-src-clk = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_bus>;
+ status = "disabled";
+ };
+
+ spi_1: spi@13930000 {
+ compatible = "samsung,exynos4210-spi";
+ reg = <0x13930000 0x100>;
+ interrupts = <0 122 0>;
+ dmas = <&pdma1 7>, <&pdma1 6>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu CLK_SPI1>, <&cmu CLK_SCLK_SPI1>;
+ clock-names = "spi", "spi_busclk0";
+ samsung,spi-src-clk = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_bus>;
+ status = "disabled";
+ };
+
+ i2s2: i2s@13970000 {
+ compatible = "samsung,s3c6410-i2s";
+ reg = <0x13970000 0x100>;
+ interrupts = <0 126 0>;
+ clocks = <&cmu CLK_I2S>, <&cmu CLK_SCLK_I2S>;
+ clock-names = "iis", "i2s_opclk0";
+ dmas = <&pdma0 14>, <&pdma0 13>;
+ dma-names = "tx", "rx";
+ pinctrl-0 = <&i2s2_bus>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ pwm: pwm@139D0000 {
+ compatible = "samsung,exynos4210-pwm";
+ reg = <0x139D0000 0x1000>;
+ interrupts = <0 104 0>, <0 105 0>, <0 106 0>,
+ <0 107 0>, <0 108 0>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pmu {
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <0 18 0>, <0 19 0>;
+ };
+
+ ppmu_dmc0: ppmu_dmc0@106a0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x106a0000 0x2000>;
+ status = "disabled";
+ };
+
+ ppmu_dmc1: ppmu_dmc1@106b0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x106b0000 0x2000>;
+ status = "disabled";
+ };
+
+ ppmu_cpu: ppmu_cpu@106c0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x106c0000 0x2000>;
+ status = "disabled";
+ };
+
+ ppmu_rightbus: ppmu_rightbus@112a0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x112a0000 0x2000>;
+ clocks = <&cmu CLK_PPMURIGHT>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_leftbus: ppmu_leftbus0@116a0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x116a0000 0x2000>;
+ clocks = <&cmu CLK_PPMULEFT>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_camif: ppmu_camif@11ac0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x11ac0000 0x2000>;
+ clocks = <&cmu CLK_PPMUCAMIF>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_lcd0: ppmu_lcd0@11e40000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x11e40000 0x2000>;
+ clocks = <&cmu CLK_PPMULCD0>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_fsys: ppmu_fsys@12630000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x12630000 0x2000>;
+ clocks = <&cmu CLK_PPMUFILE>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_g3d: ppmu_g3d@13220000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x13220000 0x2000>;
+ clocks = <&cmu CLK_PPMUG3D>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_mfc: ppmu_mfc@13660000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x13660000 0x2000>;
+ clocks = <&cmu CLK_PPMUMFC_L>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+ };
+};
+
+#include "exynos3250-pinctrl.dtsi"
diff --git a/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi b/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi
new file mode 100644
index 000000000..735cb2f10
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi
@@ -0,0 +1,52 @@
+/*
+ * Device tree sources for Exynos4 thermal zone
+ *
+ * Copyright (c) 2014 Lukasz Majewski <l.majewski@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 <dt-bindings/thermal/thermal.h>
+
+/ {
+thermal-zones {
+ cpu_thermal: cpu-thermal {
+ thermal-sensors = <&tmu 0>;
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ trips {
+ cpu_alert0: cpu-alert-0 {
+ temperature = <70000>; /* millicelsius */
+ hysteresis = <10000>; /* millicelsius */
+ type = "active";
+ };
+ cpu_alert1: cpu-alert-1 {
+ temperature = <95000>; /* millicelsius */
+ hysteresis = <10000>; /* millicelsius */
+ type = "active";
+ };
+ cpu_alert2: cpu-alert-2 {
+ temperature = <110000>; /* millicelsius */
+ hysteresis = <10000>; /* millicelsius */
+ type = "active";
+ };
+ cpu_crit0: cpu-crit-0 {
+ temperature = <120000>; /* millicelsius */
+ hysteresis = <0>; /* millicelsius */
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ };
+ map1 {
+ trip = <&cpu_alert1>;
+ };
+ };
+ };
+};
+};
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
new file mode 100644
index 000000000..e20cdc24c
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -0,0 +1,822 @@
+/*
+ * Samsung's Exynos4 SoC series common device tree source
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Copyright (c) 2010-2011 Linaro Ltd.
+ * www.linaro.org
+ *
+ * Samsung's Exynos4 SoC series device nodes are listed in this file. Particular
+ * SoCs from Exynos4 series can include this file and provide values for SoCs
+ * specfic bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * Exynos4 SoCs. As device tree coverage for Exynos4 increases, additional
+ * nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <dt-bindings/clock/exynos4.h>
+#include <dt-bindings/clock/exynos-audss-clk.h>
+#include "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&gic>;
+
+ aliases {
+ spi0 = &spi_0;
+ spi1 = &spi_1;
+ spi2 = &spi_2;
+ i2c0 = &i2c_0;
+ i2c1 = &i2c_1;
+ i2c2 = &i2c_2;
+ i2c3 = &i2c_3;
+ i2c4 = &i2c_4;
+ i2c5 = &i2c_5;
+ i2c6 = &i2c_6;
+ i2c7 = &i2c_7;
+ i2c8 = &i2c_8;
+ csis0 = &csis_0;
+ csis1 = &csis_1;
+ fimc0 = &fimc_0;
+ fimc1 = &fimc_1;
+ fimc2 = &fimc_2;
+ fimc3 = &fimc_3;
+ serial0 = &serial_0;
+ serial1 = &serial_1;
+ serial2 = &serial_2;
+ serial3 = &serial_3;
+ };
+
+ clock_audss: clock-controller@03810000 {
+ compatible = "samsung,exynos4210-audss-clock";
+ reg = <0x03810000 0x0C>;
+ #clock-cells = <1>;
+ };
+
+ i2s0: i2s@03830000 {
+ compatible = "samsung,s5pv210-i2s";
+ reg = <0x03830000 0x100>;
+ clocks = <&clock_audss EXYNOS_I2S_BUS>;
+ clock-names = "iis";
+ #clock-cells = <1>;
+ clock-output-names = "i2s_cdclk0";
+ dmas = <&pdma0 12>, <&pdma0 11>, <&pdma0 10>;
+ dma-names = "tx", "rx", "tx-sec";
+ samsung,idma-addr = <0x03000000>;
+ #sound-dai-cells = <1>;
+ status = "disabled";
+ };
+
+ chipid@10000000 {
+ compatible = "samsung,exynos4210-chipid";
+ reg = <0x10000000 0x100>;
+ };
+
+ mipi_phy: video-phy@10020710 {
+ compatible = "samsung,s5pv210-mipi-video-phy";
+ reg = <0x10020710 8>;
+ #phy-cells = <1>;
+ syscon = <&pmu_system_controller>;
+ };
+
+ pd_mfc: mfc-power-domain@10023C40 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10023C40 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_g3d: g3d-power-domain@10023C60 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10023C60 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_lcd0: lcd0-power-domain@10023C80 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10023C80 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_tv: tv-power-domain@10023C20 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10023C20 0x20>;
+ #power-domain-cells = <0>;
+ power-domains = <&pd_lcd0>;
+ };
+
+ pd_cam: cam-power-domain@10023C00 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10023C00 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_gps: gps-power-domain@10023CE0 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10023CE0 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_gps_alive: gps-alive-power-domain@10023D00 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10023D00 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ gic: interrupt-controller@10490000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x10490000 0x10000>, <0x10480000 0x10000>;
+ };
+
+ combiner: interrupt-controller@10440000 {
+ compatible = "samsung,exynos4210-combiner";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0x10440000 0x1000>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupt-parent = <&combiner>;
+ interrupts = <2 2>, <3 2>;
+ };
+
+ sys_reg: syscon@10010000 {
+ compatible = "samsung,exynos4-sysreg", "syscon";
+ reg = <0x10010000 0x400>;
+ };
+
+ pmu_system_controller: system-controller@10020000 {
+ compatible = "samsung,exynos4210-pmu", "syscon";
+ reg = <0x10020000 0x4000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ };
+
+ dsi_0: dsi@11C80000 {
+ compatible = "samsung,exynos4210-mipi-dsi";
+ reg = <0x11C80000 0x10000>;
+ interrupts = <0 79 0>;
+ power-domains = <&pd_lcd0>;
+ phys = <&mipi_phy 1>;
+ phy-names = "dsim";
+ clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI0>;
+ clock-names = "bus_clk", "pll_clk";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ camera {
+ compatible = "samsung,fimc", "simple-bus";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #clock-cells = <1>;
+ clock-output-names = "cam_a_clkout", "cam_b_clkout";
+ ranges;
+
+ fimc_0: fimc@11800000 {
+ compatible = "samsung,exynos4210-fimc";
+ reg = <0x11800000 0x1000>;
+ interrupts = <0 84 0>;
+ clocks = <&clock CLK_FIMC0>, <&clock CLK_SCLK_FIMC0>;
+ clock-names = "fimc", "sclk_fimc";
+ power-domains = <&pd_cam>;
+ samsung,sysreg = <&sys_reg>;
+ status = "disabled";
+ };
+
+ fimc_1: fimc@11810000 {
+ compatible = "samsung,exynos4210-fimc";
+ reg = <0x11810000 0x1000>;
+ interrupts = <0 85 0>;
+ clocks = <&clock CLK_FIMC1>, <&clock CLK_SCLK_FIMC1>;
+ clock-names = "fimc", "sclk_fimc";
+ power-domains = <&pd_cam>;
+ samsung,sysreg = <&sys_reg>;
+ status = "disabled";
+ };
+
+ fimc_2: fimc@11820000 {
+ compatible = "samsung,exynos4210-fimc";
+ reg = <0x11820000 0x1000>;
+ interrupts = <0 86 0>;
+ clocks = <&clock CLK_FIMC2>, <&clock CLK_SCLK_FIMC2>;
+ clock-names = "fimc", "sclk_fimc";
+ power-domains = <&pd_cam>;
+ samsung,sysreg = <&sys_reg>;
+ status = "disabled";
+ };
+
+ fimc_3: fimc@11830000 {
+ compatible = "samsung,exynos4210-fimc";
+ reg = <0x11830000 0x1000>;
+ interrupts = <0 87 0>;
+ clocks = <&clock CLK_FIMC3>, <&clock CLK_SCLK_FIMC3>;
+ clock-names = "fimc", "sclk_fimc";
+ power-domains = <&pd_cam>;
+ samsung,sysreg = <&sys_reg>;
+ status = "disabled";
+ };
+
+ csis_0: csis@11880000 {
+ compatible = "samsung,exynos4210-csis";
+ reg = <0x11880000 0x4000>;
+ interrupts = <0 78 0>;
+ clocks = <&clock CLK_CSIS0>, <&clock CLK_SCLK_CSIS0>;
+ clock-names = "csis", "sclk_csis";
+ bus-width = <4>;
+ power-domains = <&pd_cam>;
+ phys = <&mipi_phy 0>;
+ phy-names = "csis";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ csis_1: csis@11890000 {
+ compatible = "samsung,exynos4210-csis";
+ reg = <0x11890000 0x4000>;
+ interrupts = <0 80 0>;
+ clocks = <&clock CLK_CSIS1>, <&clock CLK_SCLK_CSIS1>;
+ clock-names = "csis", "sclk_csis";
+ bus-width = <2>;
+ power-domains = <&pd_cam>;
+ phys = <&mipi_phy 2>;
+ phy-names = "csis";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ watchdog@10060000 {
+ compatible = "samsung,s3c2410-wdt";
+ reg = <0x10060000 0x100>;
+ interrupts = <0 43 0>;
+ clocks = <&clock CLK_WDT>;
+ clock-names = "watchdog";
+ status = "disabled";
+ };
+
+ rtc@10070000 {
+ compatible = "samsung,s3c6410-rtc";
+ reg = <0x10070000 0x100>;
+ interrupt-parent = <&pmu_system_controller>;
+ interrupts = <0 44 0>, <0 45 0>;
+ clocks = <&clock CLK_RTC>;
+ clock-names = "rtc";
+ status = "disabled";
+ };
+
+ keypad@100A0000 {
+ compatible = "samsung,s5pv210-keypad";
+ reg = <0x100A0000 0x100>;
+ interrupts = <0 109 0>;
+ clocks = <&clock CLK_KEYIF>;
+ clock-names = "keypad";
+ status = "disabled";
+ };
+
+ sdhci@12510000 {
+ compatible = "samsung,exynos4210-sdhci";
+ reg = <0x12510000 0x100>;
+ interrupts = <0 73 0>;
+ clocks = <&clock CLK_SDMMC0>, <&clock CLK_SCLK_MMC0>;
+ clock-names = "hsmmc", "mmc_busclk.2";
+ status = "disabled";
+ };
+
+ sdhci@12520000 {
+ compatible = "samsung,exynos4210-sdhci";
+ reg = <0x12520000 0x100>;
+ interrupts = <0 74 0>;
+ clocks = <&clock CLK_SDMMC1>, <&clock CLK_SCLK_MMC1>;
+ clock-names = "hsmmc", "mmc_busclk.2";
+ status = "disabled";
+ };
+
+ sdhci@12530000 {
+ compatible = "samsung,exynos4210-sdhci";
+ reg = <0x12530000 0x100>;
+ interrupts = <0 75 0>;
+ clocks = <&clock CLK_SDMMC2>, <&clock CLK_SCLK_MMC2>;
+ clock-names = "hsmmc", "mmc_busclk.2";
+ status = "disabled";
+ };
+
+ sdhci@12540000 {
+ compatible = "samsung,exynos4210-sdhci";
+ reg = <0x12540000 0x100>;
+ interrupts = <0 76 0>;
+ clocks = <&clock CLK_SDMMC3>, <&clock CLK_SCLK_MMC3>;
+ clock-names = "hsmmc", "mmc_busclk.2";
+ status = "disabled";
+ };
+
+ exynos_usbphy: exynos-usbphy@125B0000 {
+ compatible = "samsung,exynos4210-usb2-phy";
+ reg = <0x125B0000 0x100>;
+ samsung,pmureg-phandle = <&pmu_system_controller>;
+ clocks = <&clock CLK_USB_DEVICE>, <&clock CLK_XUSBXTI>;
+ clock-names = "phy", "ref";
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
+ hsotg@12480000 {
+ compatible = "samsung,s3c6400-hsotg";
+ reg = <0x12480000 0x20000>;
+ interrupts = <0 71 0>;
+ clocks = <&clock CLK_USB_DEVICE>;
+ clock-names = "otg";
+ phys = <&exynos_usbphy 0>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ ehci@12580000 {
+ compatible = "samsung,exynos4210-ehci";
+ reg = <0x12580000 0x100>;
+ interrupts = <0 70 0>;
+ clocks = <&clock CLK_USB_HOST>;
+ clock-names = "usbhost";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ phys = <&exynos_usbphy 1>;
+ status = "disabled";
+ };
+ port@1 {
+ reg = <1>;
+ phys = <&exynos_usbphy 2>;
+ status = "disabled";
+ };
+ port@2 {
+ reg = <2>;
+ phys = <&exynos_usbphy 3>;
+ status = "disabled";
+ };
+ };
+
+ ohci@12590000 {
+ compatible = "samsung,exynos4210-ohci";
+ reg = <0x12590000 0x100>;
+ interrupts = <0 70 0>;
+ clocks = <&clock CLK_USB_HOST>;
+ clock-names = "usbhost";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ phys = <&exynos_usbphy 1>;
+ status = "disabled";
+ };
+ };
+
+ i2s1: i2s@13960000 {
+ compatible = "samsung,s3c6410-i2s";
+ reg = <0x13960000 0x100>;
+ clocks = <&clock CLK_I2S1>;
+ clock-names = "iis";
+ #clock-cells = <1>;
+ clock-output-names = "i2s_cdclk1";
+ dmas = <&pdma1 12>, <&pdma1 11>;
+ dma-names = "tx", "rx";
+ #sound-dai-cells = <1>;
+ status = "disabled";
+ };
+
+ i2s2: i2s@13970000 {
+ compatible = "samsung,s3c6410-i2s";
+ reg = <0x13970000 0x100>;
+ clocks = <&clock CLK_I2S2>;
+ clock-names = "iis";
+ #clock-cells = <1>;
+ clock-output-names = "i2s_cdclk2";
+ dmas = <&pdma0 14>, <&pdma0 13>;
+ dma-names = "tx", "rx";
+ #sound-dai-cells = <1>;
+ status = "disabled";
+ };
+
+ mfc: codec@13400000 {
+ compatible = "samsung,mfc-v5";
+ reg = <0x13400000 0x10000>;
+ interrupts = <0 94 0>;
+ power-domains = <&pd_mfc>;
+ clocks = <&clock CLK_MFC>, <&clock CLK_SCLK_MFC>;
+ clock-names = "mfc", "sclk_mfc";
+ status = "disabled";
+ };
+
+ serial_0: serial@13800000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x13800000 0x100>;
+ interrupts = <0 52 0>;
+ clocks = <&clock CLK_UART0>, <&clock CLK_SCLK_UART0>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ serial_1: serial@13810000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x13810000 0x100>;
+ interrupts = <0 53 0>;
+ clocks = <&clock CLK_UART1>, <&clock CLK_SCLK_UART1>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ serial_2: serial@13820000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x13820000 0x100>;
+ interrupts = <0 54 0>;
+ clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ serial_3: serial@13830000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x13830000 0x100>;
+ interrupts = <0 55 0>;
+ clocks = <&clock CLK_UART3>, <&clock CLK_SCLK_UART3>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ i2c_0: i2c@13860000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13860000 0x100>;
+ interrupts = <0 58 0>;
+ clocks = <&clock CLK_I2C0>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_bus>;
+ status = "disabled";
+ };
+
+ i2c_1: i2c@13870000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13870000 0x100>;
+ interrupts = <0 59 0>;
+ clocks = <&clock CLK_I2C1>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_bus>;
+ status = "disabled";
+ };
+
+ i2c_2: i2c@13880000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13880000 0x100>;
+ interrupts = <0 60 0>;
+ clocks = <&clock CLK_I2C2>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_bus>;
+ status = "disabled";
+ };
+
+ i2c_3: i2c@13890000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13890000 0x100>;
+ interrupts = <0 61 0>;
+ clocks = <&clock CLK_I2C3>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_bus>;
+ status = "disabled";
+ };
+
+ i2c_4: i2c@138A0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x138A0000 0x100>;
+ interrupts = <0 62 0>;
+ clocks = <&clock CLK_I2C4>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_bus>;
+ status = "disabled";
+ };
+
+ i2c_5: i2c@138B0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x138B0000 0x100>;
+ interrupts = <0 63 0>;
+ clocks = <&clock CLK_I2C5>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5_bus>;
+ status = "disabled";
+ };
+
+ i2c_6: i2c@138C0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x138C0000 0x100>;
+ interrupts = <0 64 0>;
+ clocks = <&clock CLK_I2C6>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c6_bus>;
+ status = "disabled";
+ };
+
+ i2c_7: i2c@138D0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x138D0000 0x100>;
+ interrupts = <0 65 0>;
+ clocks = <&clock CLK_I2C7>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c7_bus>;
+ status = "disabled";
+ };
+
+ i2c_8: i2c@138E0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-hdmiphy-i2c";
+ reg = <0x138E0000 0x100>;
+ interrupts = <0 93 0>;
+ clocks = <&clock CLK_I2C_HDMI>;
+ clock-names = "i2c";
+ status = "disabled";
+
+ hdmi_i2c_phy: hdmiphy@38 {
+ compatible = "exynos4210-hdmiphy";
+ reg = <0x38>;
+ };
+ };
+
+ spi_0: spi@13920000 {
+ compatible = "samsung,exynos4210-spi";
+ reg = <0x13920000 0x100>;
+ interrupts = <0 66 0>;
+ dmas = <&pdma0 7>, <&pdma0 6>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_SPI0>, <&clock CLK_SCLK_SPI0>;
+ clock-names = "spi", "spi_busclk0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_bus>;
+ status = "disabled";
+ };
+
+ spi_1: spi@13930000 {
+ compatible = "samsung,exynos4210-spi";
+ reg = <0x13930000 0x100>;
+ interrupts = <0 67 0>;
+ dmas = <&pdma1 7>, <&pdma1 6>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_SPI1>, <&clock CLK_SCLK_SPI1>;
+ clock-names = "spi", "spi_busclk0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_bus>;
+ status = "disabled";
+ };
+
+ spi_2: spi@13940000 {
+ compatible = "samsung,exynos4210-spi";
+ reg = <0x13940000 0x100>;
+ interrupts = <0 68 0>;
+ dmas = <&pdma0 9>, <&pdma0 8>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_SPI2>, <&clock CLK_SCLK_SPI2>;
+ clock-names = "spi", "spi_busclk0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_bus>;
+ status = "disabled";
+ };
+
+ pwm@139D0000 {
+ compatible = "samsung,exynos4210-pwm";
+ reg = <0x139D0000 0x1000>;
+ interrupts = <0 37 0>, <0 38 0>, <0 39 0>, <0 40 0>, <0 41 0>;
+ clocks = <&clock CLK_PWM>;
+ clock-names = "timers";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ amba {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "arm,amba-bus";
+ interrupt-parent = <&gic>;
+ ranges;
+
+ pdma0: pdma@12680000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x12680000 0x1000>;
+ interrupts = <0 35 0>;
+ clocks = <&clock CLK_PDMA0>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+
+ pdma1: pdma@12690000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x12690000 0x1000>;
+ interrupts = <0 36 0>;
+ clocks = <&clock CLK_PDMA1>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+
+ mdma1: mdma@12850000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x12850000 0x1000>;
+ interrupts = <0 34 0>;
+ clocks = <&clock CLK_MDMA>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <1>;
+ };
+ };
+
+ fimd: fimd@11c00000 {
+ compatible = "samsung,exynos4210-fimd";
+ interrupt-parent = <&combiner>;
+ reg = <0x11c00000 0x20000>;
+ interrupt-names = "fifo", "vsync", "lcd_sys";
+ interrupts = <11 0>, <11 1>, <11 2>;
+ clocks = <&clock CLK_SCLK_FIMD0>, <&clock CLK_FIMD0>;
+ clock-names = "sclk_fimd", "fimd";
+ power-domains = <&pd_lcd0>;
+ samsung,sysreg = <&sys_reg>;
+ status = "disabled";
+ };
+
+ tmu: tmu@100C0000 {
+ #include "exynos4412-tmu-sensor-conf.dtsi"
+ };
+
+ hdmi: hdmi@12D00000 {
+ compatible = "samsung,exynos4210-hdmi";
+ reg = <0x12D00000 0x70000>;
+ interrupts = <0 92 0>;
+ clock-names = "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy",
+ "mout_hdmi";
+ clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>,
+ <&clock CLK_SCLK_PIXEL>, <&clock CLK_SCLK_HDMIPHY>,
+ <&clock CLK_MOUT_HDMI>;
+ phy = <&hdmi_i2c_phy>;
+ power-domains = <&pd_tv>;
+ samsung,syscon-phandle = <&pmu_system_controller>;
+ status = "disabled";
+ };
+
+ mixer: mixer@12C10000 {
+ compatible = "samsung,exynos4210-mixer";
+ interrupts = <0 91 0>;
+ reg = <0x12C10000 0x2100>, <0x12c00000 0x300>;
+ power-domains = <&pd_tv>;
+ status = "disabled";
+ };
+
+ ppmu_dmc0: ppmu_dmc0@106a0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x106a0000 0x2000>;
+ clocks = <&clock CLK_PPMUDMC0>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_dmc1: ppmu_dmc1@106b0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x106b0000 0x2000>;
+ clocks = <&clock CLK_PPMUDMC1>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_cpu: ppmu_cpu@106c0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x106c0000 0x2000>;
+ clocks = <&clock CLK_PPMUCPU>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_acp: ppmu_acp@10ae0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x106e0000 0x2000>;
+ status = "disabled";
+ };
+
+ ppmu_rightbus: ppmu_rightbus@112a0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x112a0000 0x2000>;
+ clocks = <&clock CLK_PPMURIGHT>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_leftbus: ppmu_leftbus0@116a0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x116a0000 0x2000>;
+ clocks = <&clock CLK_PPMULEFT>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_camif: ppmu_camif@11ac0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x11ac0000 0x2000>;
+ clocks = <&clock CLK_PPMUCAMIF>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_lcd0: ppmu_lcd0@11e40000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x11e40000 0x2000>;
+ clocks = <&clock CLK_PPMULCD0>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_fsys: ppmu_g3d@12630000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x12630000 0x2000>;
+ status = "disabled";
+ };
+
+ ppmu_image: ppmu_image@12aa0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x12aa0000 0x2000>;
+ clocks = <&clock CLK_PPMUIMAGE>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_tv: ppmu_tv@12e40000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x12e40000 0x2000>;
+ clocks = <&clock CLK_PPMUTV>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_g3d: ppmu_g3d@13220000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x13220000 0x2000>;
+ clocks = <&clock CLK_PPMUG3D>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_mfc_left: ppmu_mfc_left@13660000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x13660000 0x2000>;
+ clocks = <&clock CLK_PPMUMFC_L>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_mfc_right: ppmu_mfc_right@13670000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x13670000 0x2000>;
+ clocks = <&clock CLK_PPMUMFC_R>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
new file mode 100644
index 000000000..b81146141
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -0,0 +1,337 @@
+/*
+ * Samsung's Exynos4210 based Origen board device tree source
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Copyright (c) 2010-2011 Linaro Ltd.
+ * www.linaro.org
+ *
+ * Device tree source file for Insignal's Origen board which is based on
+ * Samsung's Exynos4210 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+#include "exynos4210.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "Insignal Origen evaluation board based on Exynos4210";
+ compatible = "insignal,origen", "samsung,exynos4210", "samsung,exynos4";
+
+ memory {
+ reg = <0x40000000 0x10000000
+ 0x50000000 0x10000000
+ 0x60000000 0x10000000
+ 0x70000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc";
+ stdout-path = &serial_2;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ mmc_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "VMEM_VDD_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpx1 1 0>;
+ enable-active-high;
+ };
+ };
+
+ watchdog@10060000 {
+ status = "okay";
+ };
+
+ rtc@10070000 {
+ status = "okay";
+ };
+
+ tmu@100C0000 {
+ status = "okay";
+ };
+
+ sdhci@12530000 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sd2_cd>;
+ pinctrl-names = "default";
+ vmmc-supply = <&mmc_reg>;
+ status = "okay";
+ };
+
+ sdhci@12510000 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_cd>;
+ pinctrl-names = "default";
+ vmmc-supply = <&mmc_reg>;
+ status = "okay";
+ };
+
+ g2d@12800000 {
+ status = "okay";
+ };
+
+ codec@13400000 {
+ samsung,mfc-r = <0x43000000 0x800000>;
+ samsung,mfc-l = <0x51000000 0x800000>;
+ status = "okay";
+ };
+
+ serial@13800000 {
+ status = "okay";
+ };
+
+ serial@13810000 {
+ status = "okay";
+ };
+
+ serial@13820000 {
+ status = "okay";
+ };
+
+ serial@13830000 {
+ status = "okay";
+ };
+
+ i2c@13860000 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <20000>;
+ pinctrl-0 = <&i2c0_bus>;
+ pinctrl-names = "default";
+
+ max8997_pmic@66 {
+ compatible = "maxim,max8997-pmic";
+ reg = <0x66>;
+ interrupt-parent = <&gpx0>;
+ interrupts = <4 0>, <3 0>;
+
+ max8997,pmic-buck1-dvs-voltage = <1350000>;
+ max8997,pmic-buck2-dvs-voltage = <1100000>;
+ max8997,pmic-buck5-dvs-voltage = <1200000>;
+
+ regulators {
+ ldo1_reg: LDO1 {
+ regulator-name = "VDD_ABB_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "VDD_ALIVE_1.1V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "VMIPI_1.1V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "VDD_RTC_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "VMIPI_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "VDD_AUD_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "VADC_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "DVDD_SWB_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "VDD_PLL_1.1V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "VDD_AUD_3V";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "AVDD18_SWB_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "VDD_SWB_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo21_reg: LDO21 {
+ regulator-name = "VDD_MIF_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ buck1_reg: BUCK1 {
+ /*
+ * HACK: The real name is VDD_ARM_1.2V,
+ * but exynos-cpufreq does not support
+ * DT-based regulator lookup yet.
+ */
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "VDD_INT_1.1V";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "VDD_G3D_1.1V";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1100000>;
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "VDDQ_M1M2_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ buck7_reg: BUCK7 {
+ regulator-name = "VDD_LCD_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ up {
+ label = "Up";
+ gpios = <&gpx2 0 1>;
+ linux,code = <KEY_UP>;
+ gpio-key,wakeup;
+ };
+
+ down {
+ label = "Down";
+ gpios = <&gpx2 1 1>;
+ linux,code = <KEY_DOWN>;
+ gpio-key,wakeup;
+ };
+
+ back {
+ label = "Back";
+ gpios = <&gpx1 7 1>;
+ linux,code = <KEY_BACK>;
+ gpio-key,wakeup;
+ };
+
+ home {
+ label = "Home";
+ gpios = <&gpx1 6 1>;
+ linux,code = <KEY_HOME>;
+ gpio-key,wakeup;
+ };
+
+ menu {
+ label = "Menu";
+ gpios = <&gpx1 5 1>;
+ linux,code = <KEY_MENU>;
+ gpio-key,wakeup;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ status {
+ gpios = <&gpx1 3 1>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti";
+ clock-frequency = <0>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ fimd@11c00000 {
+ pinctrl-0 = <&lcd_en &lcd_clk &lcd_data24 &pwm0_out>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing {
+ clock-frequency = <47500000>;
+ hactive = <1024>;
+ vactive = <600>;
+ hfront-porch = <64>;
+ hback-porch = <16>;
+ hsync-len = <48>;
+ vback-porch = <64>;
+ vfront-porch = <16>;
+ vsync-len = <3>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
new file mode 100644
index 000000000..a7c212891
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
@@ -0,0 +1,847 @@
+/*
+ * Samsung's Exynos4210 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Copyright (c) 2011-2012 Linaro Ltd.
+ * www.linaro.org
+ *
+ * Samsung's Exynos4210 SoC pin-mux and pin-config optiosn are listed as device
+ * tree nodes are listed in this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/ {
+ pinctrl@11400000 {
+ gpa0: gpa0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpa1: gpa1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb: gpb {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc0: gpc0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc1: gpc1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd0: gpd0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd1: gpd1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpe0: gpe0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpe1: gpe1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpe2: gpe2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpe3: gpe3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpe4: gpe4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf0: gpf0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf1: gpf1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf2: gpf2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf3: gpf3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart0_data: uart0-data {
+ samsung,pins = "gpa0-0", "gpa0-1";
+ samsung,pin-function = <0x2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart0_fctl: uart0-fctl {
+ samsung,pins = "gpa0-2", "gpa0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_data: uart1-data {
+ samsung,pins = "gpa0-4", "gpa0-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_fctl: uart1-fctl {
+ samsung,pins = "gpa0-6", "gpa0-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c2_bus: i2c2-bus {
+ samsung,pins = "gpa0-6", "gpa0-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart2_data: uart2-data {
+ samsung,pins = "gpa1-0", "gpa1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart2_fctl: uart2-fctl {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart_audio_a: uart-audio-a {
+ samsung,pins = "gpa1-0", "gpa1-1";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c3_bus: i2c3-bus {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart3_data: uart3-data {
+ samsung,pins = "gpa1-4", "gpa1-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart_audio_b: uart-audio-b {
+ samsung,pins = "gpa1-4", "gpa1-5";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi0_bus: spi0-bus {
+ samsung,pins = "gpb-0", "gpb-2", "gpb-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c4_bus: i2c4-bus {
+ samsung,pins = "gpb-2", "gpb-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi1_bus: spi1-bus {
+ samsung,pins = "gpb-4", "gpb-6", "gpb-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c5_bus: i2c5-bus {
+ samsung,pins = "gpb-6", "gpb-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s1_bus: i2s1-bus {
+ samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+ "gpc0-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm1_bus: pcm1-bus {
+ samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+ "gpc0-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ ac97_bus: ac97-bus {
+ samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+ "gpc0-4";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s2_bus: i2s2-bus {
+ samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+ "gpc1-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm2_bus: pcm2-bus {
+ samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+ "gpc1-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ spdif_bus: spdif-bus {
+ samsung,pins = "gpc1-0", "gpc1-1";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c6_bus: i2c6-bus {
+ samsung,pins = "gpc1-3", "gpc1-4";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi2_bus: spi2-bus {
+ samsung,pins = "gpc1-1", "gpc1-2", "gpc1-3", "gpc1-4";
+ samsung,pin-function = <5>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c7_bus: i2c7-bus {
+ samsung,pins = "gpd0-2", "gpd0-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c0_bus: i2c0-bus {
+ samsung,pins = "gpd1-0", "gpd1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c1_bus: i2c1-bus {
+ samsung,pins = "gpd1-2", "gpd1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm0_out: pwm0-out {
+ samsung,pins = "gpd0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm1_out: pwm1-out {
+ samsung,pins = "gpd0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm2_out: pwm2-out {
+ samsung,pins = "gpd0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm3_out: pwm3-out {
+ samsung,pins = "gpd0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_ctrl: lcd-ctrl {
+ samsung,pins = "gpd0-0", "gpd0-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_sync: lcd-sync {
+ samsung,pins = "gpf0-0", "gpf0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_en: lcd-en {
+ samsung,pins = "gpe3-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_clk: lcd-clk {
+ samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_data16: lcd-data-width16 {
+ samsung,pins = "gpf0-7", "gpf1-0", "gpf1-1", "gpf1-2",
+ "gpf1-3", "gpf1-6", "gpf1-7", "gpf2-0",
+ "gpf2-1", "gpf2-2", "gpf2-3", "gpf2-7",
+ "gpf3-0", "gpf3-1", "gpf3-2", "gpf3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_data18: lcd-data-width18 {
+ samsung,pins = "gpf0-6", "gpf0-7", "gpf1-0", "gpf1-1",
+ "gpf1-2", "gpf1-3", "gpf1-6", "gpf1-7",
+ "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
+ "gpf2-6", "gpf2-7", "gpf3-0", "gpf3-1",
+ "gpf3-2", "gpf3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_data24: lcd-data-width24 {
+ samsung,pins = "gpf0-4", "gpf0-5", "gpf0-6", "gpf0-7",
+ "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3",
+ "gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7",
+ "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
+ "gpf2-4", "gpf2-5", "gpf2-6", "gpf2-7",
+ "gpf3-0", "gpf3-1", "gpf3-2", "gpf3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ pinctrl@11000000 {
+ gpj0: gpj0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpj1: gpj1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpk0: gpk0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpk1: gpk1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpk2: gpk2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpk3: gpk3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpl0: gpl0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpl1: gpl1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpl2: gpl2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpy0: gpy0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy1: gpy1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy2: gpy2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy3: gpy3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy4: gpy4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy5: gpy5 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy6: gpy6 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpx0: gpx0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+ <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
+ #interrupt-cells = <2>;
+ };
+
+ gpx1: gpx1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
+ <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
+ #interrupt-cells = <2>;
+ };
+
+ gpx2: gpx2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx3: gpx3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ sd0_clk: sd0-clk {
+ samsung,pins = "gpk0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ samsung,pins = "gpk0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cd: sd0-cd {
+ samsung,pins = "gpk0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ samsung,pins = "gpk0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus8: sd0-bus-width8 {
+ samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd4_clk: sd4-clk {
+ samsung,pins = "gpk0-0";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd4_cmd: sd4-cmd {
+ samsung,pins = "gpk0-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd4_cd: sd4-cd {
+ samsung,pins = "gpk0-2";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd4_bus1: sd4-bus-width1 {
+ samsung,pins = "gpk0-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd4_bus4: sd4-bus-width4 {
+ samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd4_bus8: sd4-bus-width8 {
+ samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <4>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_clk: sd1-clk {
+ samsung,pins = "gpk1-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ samsung,pins = "gpk1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cd: sd1-cd {
+ samsung,pins = "gpk1-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ samsung,pins = "gpk1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_clk: sd2-clk {
+ samsung,pins = "gpk2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cmd: sd2-cmd {
+ samsung,pins = "gpk2-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cd: sd2-cd {
+ samsung,pins = "gpk2-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus1: sd2-bus-width1 {
+ samsung,pins = "gpk2-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus4: sd2-bus-width4 {
+ samsung,pins = "gpk2-3", "gpk2-4", "gpk2-5", "gpk2-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus8: sd2-bus-width8 {
+ samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_clk: sd3-clk {
+ samsung,pins = "gpk3-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_cmd: sd3-cmd {
+ samsung,pins = "gpk3-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_cd: sd3-cd {
+ samsung,pins = "gpk3-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_bus1: sd3-bus-width1 {
+ samsung,pins = "gpk3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_bus4: sd3-bus-width4 {
+ samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ eint0: ext-int0 {
+ samsung,pins = "gpx0-0";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ eint8: ext-int8 {
+ samsung,pins = "gpx1-0";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ eint15: ext-int15 {
+ samsung,pins = "gpx1-7";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ eint16: ext-int16 {
+ samsung,pins = "gpx2-0";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ eint31: ext-int31 {
+ samsung,pins = "gpx3-7";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_port_a_io: cam-port-a-io {
+ samsung,pins = "gpj0-0", "gpj0-1", "gpj0-2", "gpj0-3",
+ "gpj0-4", "gpj0-5", "gpj0-6", "gpj0-7",
+ "gpj1-0", "gpj1-1", "gpj1-2", "gpj1-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_port_a_clk_active: cam-port-a-clk-active {
+ samsung,pins = "gpj1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ cam_port_a_clk_idle: cam-port-a-clk-idle {
+ samsung,pins = "gpj1-3";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ pinctrl@03860000 {
+ gpz: gpz {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ i2s0_bus: i2s0-bus {
+ samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
+ "gpz-4", "gpz-5", "gpz-6";
+ samsung,pin-function = <0x2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm0_bus: pcm0-bus {
+ samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
+ "gpz-4";
+ samsung,pin-function = <0x3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts
new file mode 100644
index 000000000..86216fff1
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -0,0 +1,210 @@
+/*
+ * Samsung's Exynos4210 based SMDKV310 board device tree source
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Copyright (c) 2010-2011 Linaro Ltd.
+ * www.linaro.org
+ *
+ * Device tree source file for Samsung's SMDKV310 board which is based on
+ * Samsung's Exynos4210 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+#include "exynos4210.dtsi"
+
+/ {
+ model = "Samsung smdkv310 evaluation board based on Exynos4210";
+ compatible = "samsung,smdkv310", "samsung,exynos4210", "samsung,exynos4";
+
+ memory {
+ reg = <0x40000000 0x80000000>;
+ };
+
+ chosen {
+ bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
+ stdout-path = &serial_1;
+ };
+
+ sdhci@12530000 {
+ bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+ status = "okay";
+ };
+
+ g2d@12800000 {
+ status = "okay";
+ };
+
+ codec@13400000 {
+ samsung,mfc-r = <0x43000000 0x800000>;
+ samsung,mfc-l = <0x51000000 0x800000>;
+ status = "okay";
+ };
+
+ serial@13800000 {
+ status = "okay";
+ };
+
+ serial@13810000 {
+ status = "okay";
+ };
+
+ serial@13820000 {
+ status = "okay";
+ };
+
+ serial@13830000 {
+ status = "okay";
+ };
+
+ pinctrl@11000000 {
+ keypad_rows: keypad-rows {
+ samsung,pins = "gpx2-0", "gpx2-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_cols: keypad-cols {
+ samsung,pins = "gpx1-0", "gpx1-1", "gpx1-2", "gpx1-3",
+ "gpx1-4", "gpx1-5", "gpx1-6", "gpx1-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ keypad@100A0000 {
+ samsung,keypad-num-rows = <2>;
+ samsung,keypad-num-columns = <8>;
+ linux,keypad-no-autorepeat;
+ linux,keypad-wakeup;
+ pinctrl-names = "default";
+ pinctrl-0 = <&keypad_rows &keypad_cols>;
+ status = "okay";
+
+ key_1 {
+ keypad,row = <0>;
+ keypad,column = <3>;
+ linux,code = <2>;
+ };
+
+ key_2 {
+ keypad,row = <0>;
+ keypad,column = <4>;
+ linux,code = <3>;
+ };
+
+ key_3 {
+ keypad,row = <0>;
+ keypad,column = <5>;
+ linux,code = <4>;
+ };
+
+ key_4 {
+ keypad,row = <0>;
+ keypad,column = <6>;
+ linux,code = <5>;
+ };
+
+ key_5 {
+ keypad,row = <0>;
+ keypad,column = <7>;
+ linux,code = <6>;
+ };
+
+ key_a {
+ keypad,row = <1>;
+ keypad,column = <3>;
+ linux,code = <30>;
+ };
+
+ key_b {
+ keypad,row = <1>;
+ keypad,column = <4>;
+ linux,code = <48>;
+ };
+
+ key_c {
+ keypad,row = <1>;
+ keypad,column = <5>;
+ linux,code = <46>;
+ };
+
+ key_d {
+ keypad,row = <1>;
+ keypad,column = <6>;
+ linux,code = <32>;
+ };
+
+ key_e {
+ keypad,row = <1>;
+ keypad,column = <7>;
+ linux,code = <18>;
+ };
+ };
+
+ i2c@13860000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <100000>;
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "samsung,24ad0xd1";
+ reg = <0x50>;
+ };
+
+ eeprom@52 {
+ compatible = "samsung,24ad0xd1";
+ reg = <0x52>;
+ };
+ };
+
+ spi_2: spi@13940000 {
+ cs-gpios = <&gpc1 2 0>;
+ status = "okay";
+
+ w25x80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "w25x80";
+ reg = <0>;
+ spi-max-frequency = <1000000>;
+
+ controller-data {
+ samsung,spi-feedback-delay = <0>;
+ };
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0x0 0x40000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "Kernel";
+ reg = <0x40000 0xc0000>;
+ };
+ };
+ };
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti";
+ clock-frequency = <12000000>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti";
+ clock-frequency = <24000000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
new file mode 100644
index 000000000..32c5fd8f6
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -0,0 +1,485 @@
+/*
+ * Samsung's Exynos4210 based Trats board device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Device tree source file for Samsung's Trats board which is based on
+ * Samsung's Exynos4210 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+#include "exynos4210.dtsi"
+
+/ {
+ model = "Samsung Trats based on Exynos4210";
+ compatible = "samsung,trats", "samsung,exynos4210", "samsung,exynos4";
+
+ memory {
+ reg = <0x40000000 0x10000000
+ 0x50000000 0x10000000
+ 0x60000000 0x10000000
+ 0x70000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
+ stdout-path = &serial_2;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+
+ vemmc_reg: regulator-0 {
+ compatible = "regulator-fixed";
+ regulator-name = "VMEM_VDD_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpk0 2 0>;
+ enable-active-high;
+ };
+
+ tsp_reg: regulator-1 {
+ compatible = "regulator-fixed";
+ regulator-name = "TSP_FIXED_VOLTAGES";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpl0 3 0>;
+ enable-active-high;
+ };
+
+ cam_af_28v_reg: regulator-2 {
+ compatible = "regulator-fixed";
+ regulator-name = "8M_AF_2.8V_EN";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpk1 1 0>;
+ enable-active-high;
+ };
+
+ cam_io_en_reg: regulator-3 {
+ compatible = "regulator-fixed";
+ regulator-name = "CAM_IO_EN";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpe2 1 0>;
+ enable-active-high;
+ };
+
+ cam_io_12v_reg: regulator-4 {
+ compatible = "regulator-fixed";
+ regulator-name = "8M_1.2V_EN";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ gpio = <&gpe2 5 0>;
+ enable-active-high;
+ };
+
+ vt_core_15v_reg: regulator-5 {
+ compatible = "regulator-fixed";
+ regulator-name = "VT_CORE_1.5V";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ gpio = <&gpe2 2 0>;
+ enable-active-high;
+ };
+ };
+
+ hsotg@12480000 {
+ vusb_d-supply = <&vusb_reg>;
+ vusb_a-supply = <&vusbdac_reg>;
+ dr_mode = "peripheral";
+ status = "okay";
+ };
+
+ sdhci_emmc: sdhci@12510000 {
+ bus-width = <8>;
+ non-removable;
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus8>;
+ pinctrl-names = "default";
+ vmmc-supply = <&vemmc_reg>;
+ status = "okay";
+ };
+
+ exynos-usbphy@125B0000 {
+ status = "okay";
+ };
+
+ serial@13800000 {
+ status = "okay";
+ };
+
+ serial@13810000 {
+ status = "okay";
+ };
+
+ serial@13820000 {
+ status = "okay";
+ };
+
+ serial@13830000 {
+ status = "okay";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ vol-down-key {
+ gpios = <&gpx2 1 1>;
+ linux,code = <114>;
+ label = "volume down";
+ debounce-interval = <10>;
+ };
+
+ vol-up-key {
+ gpios = <&gpx2 0 1>;
+ linux,code = <115>;
+ label = "volume up";
+ debounce-interval = <10>;
+ };
+
+ power-key {
+ gpios = <&gpx2 7 1>;
+ linux,code = <116>;
+ label = "power";
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+
+ ok-key {
+ gpios = <&gpx3 5 1>;
+ linux,code = <352>;
+ label = "ok";
+ debounce-interval = <10>;
+ };
+ };
+
+ i2c@13890000 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-slave-addr = <0x10>;
+ samsung,i2c-max-bus-freq = <400000>;
+ pinctrl-0 = <&i2c3_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ mms114-touchscreen@48 {
+ compatible = "melfas,mms114";
+ reg = <0x48>;
+ interrupt-parent = <&gpx0>;
+ interrupts = <4 2>;
+ x-size = <720>;
+ y-size = <1280>;
+ avdd-supply = <&tsp_reg>;
+ vdd-supply = <&tsp_reg>;
+ };
+ };
+
+ i2c@138B0000 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-slave-addr = <0x10>;
+ samsung,i2c-max-bus-freq = <100000>;
+ pinctrl-0 = <&i2c5_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ max8997_pmic@66 {
+ compatible = "maxim,max8997-pmic";
+
+ reg = <0x66>;
+
+ max8997,pmic-buck1-uses-gpio-dvs;
+ max8997,pmic-buck2-uses-gpio-dvs;
+ max8997,pmic-buck5-uses-gpio-dvs;
+
+ max8997,pmic-ignore-gpiodvs-side-effect;
+ max8997,pmic-buck125-default-dvs-idx = <0>;
+
+ max8997,pmic-buck125-dvs-gpios = <&gpx0 5 0>,
+ <&gpx0 6 0>,
+ <&gpl0 0 0>;
+
+ max8997,pmic-buck1-dvs-voltage = <1350000>, <1300000>,
+ <1250000>, <1200000>,
+ <1150000>, <1100000>,
+ <1000000>, <950000>;
+
+ max8997,pmic-buck2-dvs-voltage = <1100000>, <1000000>,
+ <950000>, <900000>,
+ <1100000>, <1000000>,
+ <950000>, <900000>;
+
+ max8997,pmic-buck5-dvs-voltage = <1200000>, <1200000>,
+ <1200000>, <1200000>,
+ <1200000>, <1200000>,
+ <1200000>, <1200000>;
+
+ regulators {
+ valive_reg: LDO2 {
+ regulator-name = "VALIVE_1.1V_C210";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ vusb_reg: LDO3 {
+ regulator-name = "VUSB_1.1V_C210";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ };
+
+ vmipi_reg: LDO4 {
+ regulator-name = "VMIPI_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vpda_reg: LDO6 {
+ regulator-name = "VCC_1.8V_PDA";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vcam_reg: LDO7 {
+ regulator-name = "CAM_ISP_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vusbdac_reg: LDO8 {
+ regulator-name = "VUSB/VDAC_3.3V_C210";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vccpda_reg: LDO9 {
+ regulator-name = "VCC_2.8V_PDA";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ vpll_reg: LDO10 {
+ regulator-name = "VPLL_1.1V_C210";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ vtcam_reg: LDO12 {
+ regulator-name = "VT_CAM_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vcclcd_reg: LDO13 {
+ regulator-name = "VCC_3.3V_LCD";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vlcd_reg: LDO15 {
+ regulator-name = "VLCD_2.2V";
+ regulator-min-microvolt = <2200000>;
+ regulator-max-microvolt = <2200000>;
+ };
+
+ camsensor_reg: LDO16 {
+ regulator-name = "CAM_SENSOR_IO_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vddq_reg: LDO21 {
+ regulator-name = "VDDQ_M1M2_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ varm_breg: BUCK1 {
+ /*
+ * HACK: The real name is VARM_1.2V_C210,
+ * but exynos-cpufreq does not support
+ * DT-based regulator lookup yet.
+ */
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+
+ vint_breg: BUCK2 {
+ regulator-name = "VINT_1.1V_C210";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ camisp_breg: BUCK4 {
+ regulator-name = "CAM_ISP_CORE_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vmem_breg: BUCK5 {
+ regulator-name = "VMEM_1.2V_C210";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ vccsub_breg: BUCK7 {
+ regulator-name = "VCC_SUB_2.0V";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-always-on;
+ };
+
+ safe1_sreg: ESAFEOUT1 {
+ regulator-name = "SAFEOUT1";
+ regulator-always-on;
+ };
+
+ safe2_sreg: ESAFEOUT2 {
+ regulator-name = "SAFEOUT2";
+ regulator-boot-on;
+ };
+ };
+ };
+ };
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti";
+ clock-frequency = <0>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ dsi_0: dsi@11C80000 {
+ vddcore-supply = <&vusb_reg>;
+ vddio-supply = <&vmipi_reg>;
+ samsung,pll-clock-frequency = <24000000>;
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+
+ dsi_out: endpoint {
+ remote-endpoint = <&dsi_in>;
+ samsung,burst-clock-frequency = <500000000>;
+ samsung,esc-clock-frequency = <20000000>;
+ };
+ };
+ };
+
+ panel@0 {
+ reg = <0>;
+ compatible = "samsung,s6e8aa0";
+ vdd3-supply = <&vcclcd_reg>;
+ vci-supply = <&vlcd_reg>;
+ reset-gpios = <&gpy4 5 0>;
+ power-on-delay= <50>;
+ reset-delay = <100>;
+ init-delay = <100>;
+ flip-horizontal;
+ flip-vertical;
+ panel-width-mm = <58>;
+ panel-height-mm = <103>;
+
+ display-timings {
+ timing-0 {
+ clock-frequency = <57153600>;
+ hactive = <720>;
+ vactive = <1280>;
+ hfront-porch = <5>;
+ hback-porch = <5>;
+ hsync-len = <5>;
+ vfront-porch = <13>;
+ vback-porch = <1>;
+ vsync-len = <2>;
+ };
+ };
+
+ port {
+ dsi_in: endpoint {
+ remote-endpoint = <&dsi_out>;
+ };
+ };
+ };
+ };
+
+ fimd@11c00000 {
+ status = "okay";
+ };
+
+ tmu@100C0000 {
+ status = "okay";
+ };
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ cooling-maps {
+ map0 {
+ /* Corresponds to 800MHz at freq_table */
+ cooling-device = <&cpu0 2 2>;
+ };
+ map1 {
+ /* Corresponds to 200MHz at freq_table */
+ cooling-device = <&cpu0 4 4>;
+ };
+ };
+ };
+ };
+
+ camera {
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ status = "okay";
+
+ fimc_0: fimc@11800000 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC0>,
+ <&clock CLK_SCLK_FIMC0>;
+ assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+ assigned-clock-rates = <0>, <160000000>;
+ };
+
+ fimc_1: fimc@11810000 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC1>,
+ <&clock CLK_SCLK_FIMC1>;
+ assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+ assigned-clock-rates = <0>, <160000000>;
+ };
+
+ fimc_2: fimc@11820000 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC2>,
+ <&clock CLK_SCLK_FIMC2>;
+ assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+ assigned-clock-rates = <0>, <160000000>;
+ };
+
+ fimc_3: fimc@11830000 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC3>,
+ <&clock CLK_SCLK_FIMC3>;
+ assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+ assigned-clock-rates = <0>, <160000000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
new file mode 100644
index 000000000..d4f2b1131
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -0,0 +1,569 @@
+/*
+ * Samsung's Exynos4210 based Universal C210 board device tree source
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Device tree source file for Samsung's Universal C210 board which is based on
+ * Samsung's Exynos4210 rev0 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+#include "exynos4210.dtsi"
+
+/ {
+ model = "Samsung Universal C210 based on Exynos4210 rev0";
+ compatible = "samsung,universal_c210", "samsung,exynos4210", "samsung,exynos4";
+
+ memory {
+ reg = <0x40000000 0x10000000
+ 0x50000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rw rootwait earlyprintk panic=5 maxcpus=1";
+ stdout-path = &serial_2;
+ };
+
+ sysram@02020000 {
+ smp-sysram@0 {
+ status = "disabled";
+ };
+
+ smp-sysram@5000 {
+ compatible = "samsung,exynos4210-sysram";
+ reg = <0x5000 0x1000>;
+ };
+
+ smp-sysram@1f000 {
+ status = "disabled";
+ };
+ };
+
+ mct@10050000 {
+ compatible = "none";
+ };
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti";
+ clock-frequency = <0>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ vemmc_reg: voltage-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "VMEM_VDD_2_8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpe1 3 0>;
+ enable-active-high;
+ };
+
+ hsotg@12480000 {
+ vusb_d-supply = <&ldo3_reg>;
+ vusb_a-supply = <&ldo8_reg>;
+ dr_mode = "peripheral";
+ status = "okay";
+ };
+
+ sdhci_emmc: sdhci@12510000 {
+ bus-width = <8>;
+ non-removable;
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus8>;
+ pinctrl-names = "default";
+ vmmc-supply = <&vemmc_reg>;
+ status = "okay";
+ };
+
+ sdhci_sd: sdhci@12530000 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4>;
+ pinctrl-names = "default";
+ vmmc-supply = <&ldo5_reg>;
+ cd-gpios = <&gpx3 4 0>;
+ cd-inverted;
+ status = "okay";
+ };
+
+ ehci@12580000 {
+ status = "okay";
+ port@0 {
+ status = "okay";
+ };
+ };
+
+ ohci@12590000 {
+ status = "okay";
+ port@0 {
+ status = "okay";
+ };
+ };
+
+ exynos-usbphy@125B0000 {
+ status = "okay";
+ };
+
+ serial@13800000 {
+ status = "okay";
+ };
+
+ serial@13810000 {
+ status = "okay";
+ };
+
+ serial@13820000 {
+ status = "okay";
+ };
+
+ serial@13830000 {
+ status = "okay";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ vol-up-key {
+ gpios = <&gpx2 0 1>;
+ linux,code = <115>;
+ label = "volume up";
+ debounce-interval = <1>;
+ };
+
+ vol-down-key {
+ gpios = <&gpx2 1 1>;
+ linux,code = <114>;
+ label = "volume down";
+ debounce-interval = <1>;
+ };
+
+ config-key {
+ gpios = <&gpx2 2 1>;
+ linux,code = <171>;
+ label = "config";
+ debounce-interval = <1>;
+ gpio-key,wakeup;
+ };
+
+ camera-key {
+ gpios = <&gpx2 3 1>;
+ linux,code = <212>;
+ label = "camera";
+ debounce-interval = <1>;
+ };
+
+ power-key {
+ gpios = <&gpx2 7 1>;
+ linux,code = <116>;
+ label = "power";
+ debounce-interval = <1>;
+ gpio-key,wakeup;
+ };
+
+ ok-key {
+ gpios = <&gpx3 5 1>;
+ linux,code = <352>;
+ label = "ok";
+ debounce-interval = <1>;
+ };
+ };
+
+ tsp_reg: voltage-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "TSP_2_8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpe2 3 0>;
+ enable-active-high;
+ };
+
+ i2c@13890000 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-slave-addr = <0x10>;
+ samsung,i2c-max-bus-freq = <100000>;
+ pinctrl-0 = <&i2c3_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ tsp@4a {
+ /* TBD: Atmel maXtouch touchscreen */
+ reg = <0x4a>;
+ };
+ };
+
+ i2c@138B0000 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-slave-addr = <0x10>;
+ samsung,i2c-max-bus-freq = <100000>;
+ pinctrl-0 = <&i2c5_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ vdd_arm_reg: pmic@60 {
+ compatible = "maxim,max8952";
+ reg = <0x60>;
+
+ max8952,vid-gpios = <&gpx0 3 0>, <&gpx0 4 0>;
+ max8952,default-mode = <0>;
+ max8952,dvs-mode-microvolt = <1250000>, <1200000>,
+ <1050000>, <950000>;
+ max8952,sync-freq = <0>;
+ max8952,ramp-speed = <0>;
+
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <770000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ pmic@66 {
+ compatible = "national,lp3974";
+ reg = <0x66>;
+
+ max8998,pmic-buck1-default-dvs-idx = <0>;
+ max8998,pmic-buck1-dvs-gpios = <&gpx0 5 0>,
+ <&gpx0 6 0>;
+ max8998,pmic-buck1-dvs-voltage = <1100000>, <1000000>,
+ <1100000>, <1000000>;
+
+ max8998,pmic-buck2-default-dvs-idx = <0>;
+ max8998,pmic-buck2-dvs-gpio = <&gpe2 0 0>;
+ max8998,pmic-buck2-dvs-voltage = <1200000>, <1100000>;
+
+ regulators {
+ ldo2_reg: LDO2 {
+ regulator-name = "VALIVE_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "VUSB+MIPI_1.1V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "VADC_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "VTF_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "LDO6";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "VLCD+VMIPI_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "VUSB+VDAC_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "VCC_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "VPLL_1.1V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "CAM_AF_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "PS_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "VHIC_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "CAM_I_HOST_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "CAM_S_DIG+FM33_CORE_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "CAM_S_ANA_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "VCC_3.0V_LCD";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "VINT_1.1V";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "VG3D_1.1V";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "VCC_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "VMEM_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ ap32khz_reg: EN32KHz-AP {
+ regulator-name = "32KHz AP";
+ regulator-always-on;
+ };
+
+ cp32khz_reg: EN32KHz-CP {
+ regulator-name = "32KHz CP";
+ };
+
+ vichg_reg: ENVICHG {
+ regulator-name = "VICHG";
+ };
+
+ safeout1_reg: ESAFEOUT1 {
+ regulator-name = "SAFEOUT1";
+ regulator-always-on;
+ };
+
+ safeout2_reg: ESAFEOUT2 {
+ regulator-name = "SAFEOUT2";
+ regulator-boot-on;
+ };
+ };
+ };
+ };
+
+ spi-lcd {
+ compatible = "spi-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio-sck = <&gpy3 1 0>;
+ gpio-mosi = <&gpy3 3 0>;
+ num-chipselects = <1>;
+ cs-gpios = <&gpy4 3 0>;
+
+ lcd@0 {
+ compatible = "samsung,ld9040";
+ reg = <0>;
+ vdd3-supply = <&ldo7_reg>;
+ vci-supply = <&ldo17_reg>;
+ reset-gpios = <&gpy4 5 0>;
+ spi-max-frequency = <1200000>;
+ spi-cpol;
+ spi-cpha;
+ power-on-delay = <10>;
+ reset-delay = <10>;
+ panel-width-mm = <90>;
+ panel-height-mm = <154>;
+ display-timings {
+ timing {
+ clock-frequency = <23492370>;
+ hactive = <480>;
+ vactive = <800>;
+ hback-porch = <16>;
+ hfront-porch = <16>;
+ vback-porch = <2>;
+ vfront-porch = <28>;
+ hsync-len = <2>;
+ vsync-len = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <0>;
+ pixelclk-active = <0>;
+ };
+ };
+ port {
+ lcd_ep: endpoint {
+ remote-endpoint = <&fimd_dpi_ep>;
+ };
+ };
+ };
+ };
+
+ fimd: fimd@11c00000 {
+ pinctrl-0 = <&lcd_clk>, <&lcd_data24>;
+ pinctrl-names = "default";
+ status = "okay";
+ samsung,invert-vden;
+ samsung,invert-vclk;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@3 {
+ reg = <3>;
+ fimd_dpi_ep: endpoint {
+ remote-endpoint = <&lcd_ep>;
+ };
+ };
+ };
+
+ pwm@139D0000 {
+ compatible = "samsung,s5p6440-pwm";
+ status = "okay";
+ };
+
+ camera {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+
+ fimc_0: fimc@11800000 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC0>,
+ <&clock CLK_SCLK_FIMC0>;
+ assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+ assigned-clock-rates = <0>, <160000000>;
+ };
+
+ fimc_1: fimc@11810000 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC1>,
+ <&clock CLK_SCLK_FIMC1>;
+ assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+ assigned-clock-rates = <0>, <160000000>;
+ };
+
+ fimc_2: fimc@11820000 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC2>,
+ <&clock CLK_SCLK_FIMC2>;
+ assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+ assigned-clock-rates = <0>, <160000000>;
+ };
+
+ fimc_3: fimc@11830000 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC3>,
+ <&clock CLK_SCLK_FIMC3>;
+ assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+ assigned-clock-rates = <0>, <160000000>;
+ };
+ };
+
+ hdmi_en: voltage-regulator-hdmi-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "HDMI_5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpe0 1 0>;
+ enable-active-high;
+ };
+
+ hdmi_ddc: i2c-ddc {
+ compatible = "i2c-gpio";
+ gpios = <&gpe4 2 0 &gpe4 3 0>;
+ i2c-gpio,delay-us = <100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pinctrl-0 = <&i2c_ddc_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ mixer@12C10000 {
+ status = "okay";
+ };
+
+ hdmi@12D00000 {
+ hpd-gpio = <&gpx3 7 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_hpd>;
+ hdmi-en-supply = <&hdmi_en>;
+ vdd-supply = <&ldo3_reg>;
+ vdd_osc-supply = <&ldo4_reg>;
+ vdd_pll-supply = <&ldo3_reg>;
+ ddc = <&hdmi_ddc>;
+ status = "okay";
+ };
+
+ i2c@138E0000 {
+ status = "okay";
+ };
+};
+
+&pinctrl_1 {
+ hdmi_hpd: hdmi-hpd {
+ samsung,pins = "gpx3-7";
+ samsung,pin-pud = <0>;
+ };
+};
+
+&pinctrl_0 {
+ i2c_ddc_bus: i2c-ddc-bus {
+ samsung,pins = "gpe4-2", "gpe4-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&mdma1 {
+ reg = <0x12840000 0x1000>;
+};
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
new file mode 100644
index 000000000..be89f83f7
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -0,0 +1,247 @@
+/*
+ * Samsung's Exynos4210 SoC device tree source
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Copyright (c) 2010-2011 Linaro Ltd.
+ * www.linaro.org
+ *
+ * Samsung's Exynos4210 SoC device nodes are listed in this file. Exynos4210
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * Exynos4210 SoC. As device tree coverage for Exynos4210 increases, additional
+ * nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include "exynos4.dtsi"
+#include "exynos4210-pinctrl.dtsi"
+#include "exynos4-cpu-thermal.dtsi"
+
+/ {
+ compatible = "samsung,exynos4210", "samsung,exynos4";
+
+ aliases {
+ pinctrl0 = &pinctrl_0;
+ pinctrl1 = &pinctrl_1;
+ pinctrl2 = &pinctrl_2;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@900 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0x900>;
+ cooling-min-level = <4>;
+ cooling-max-level = <2>;
+ #cooling-cells = <2>; /* min followed by max */
+ };
+
+ cpu@901 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0x901>;
+ };
+ };
+
+ pmu_system_controller: system-controller@10020000 {
+ clock-names = "clkout0", "clkout1", "clkout2", "clkout3",
+ "clkout4", "clkout8", "clkout9";
+ clocks = <&clock CLK_OUT_DMC>, <&clock CLK_OUT_TOP>,
+ <&clock CLK_OUT_LEFTBUS>, <&clock CLK_OUT_RIGHTBUS>,
+ <&clock CLK_OUT_CPU>, <&clock CLK_XXTI>,
+ <&clock CLK_XUSBXTI>;
+ #clock-cells = <1>;
+ };
+
+ sysram@02020000 {
+ compatible = "mmio-sram";
+ reg = <0x02020000 0x20000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x02020000 0x20000>;
+
+ smp-sysram@0 {
+ compatible = "samsung,exynos4210-sysram";
+ reg = <0x0 0x1000>;
+ };
+
+ smp-sysram@1f000 {
+ compatible = "samsung,exynos4210-sysram-ns";
+ reg = <0x1f000 0x1000>;
+ };
+ };
+
+ pd_lcd1: lcd1-power-domain@10023CA0 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10023CA0 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ l2c: l2-cache-controller@10502000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x10502000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ arm,tag-latency = <2 2 1>;
+ arm,data-latency = <2 2 1>;
+ };
+
+ gic: interrupt-controller@10490000 {
+ cpu-offset = <0x8000>;
+ };
+
+ combiner: interrupt-controller@10440000 {
+ samsung,combiner-nr = <16>;
+ interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
+ <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
+ <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
+ <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>;
+ };
+
+ mct@10050000 {
+ compatible = "samsung,exynos4210-mct";
+ reg = <0x10050000 0x800>;
+ interrupt-parent = <&mct_map>;
+ interrupts = <0>, <1>, <2>, <3>, <4>, <5>;
+ clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MCT>;
+ clock-names = "fin_pll", "mct";
+
+ mct_map: mct-map {
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = <0 &gic 0 57 0>,
+ <1 &gic 0 69 0>,
+ <2 &combiner 12 6>,
+ <3 &combiner 12 7>,
+ <4 &gic 0 42 0>,
+ <5 &gic 0 48 0>;
+ };
+ };
+
+ clock: clock-controller@10030000 {
+ compatible = "samsung,exynos4210-clock";
+ reg = <0x10030000 0x20000>;
+ #clock-cells = <1>;
+ };
+
+ pinctrl_0: pinctrl@11400000 {
+ compatible = "samsung,exynos4210-pinctrl";
+ reg = <0x11400000 0x1000>;
+ interrupts = <0 47 0>;
+ };
+
+ pinctrl_1: pinctrl@11000000 {
+ compatible = "samsung,exynos4210-pinctrl";
+ reg = <0x11000000 0x1000>;
+ interrupts = <0 46 0>;
+
+ wakup_eint: wakeup-interrupt-controller {
+ compatible = "samsung,exynos4210-wakeup-eint";
+ interrupt-parent = <&gic>;
+ interrupts = <0 32 0>;
+ };
+ };
+
+ pinctrl_2: pinctrl@03860000 {
+ compatible = "samsung,exynos4210-pinctrl";
+ reg = <0x03860000 0x1000>;
+ };
+
+ tmu: tmu@100C0000 {
+ compatible = "samsung,exynos4210-tmu";
+ interrupt-parent = <&combiner>;
+ reg = <0x100C0000 0x100>;
+ interrupts = <2 4>;
+ clocks = <&clock CLK_TMU_APBIF>;
+ clock-names = "tmu_apbif";
+ samsung,tmu_gain = <15>;
+ samsung,tmu_reference_voltage = <7>;
+ status = "disabled";
+ };
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tmu 0>;
+
+ trips {
+ cpu_alert0: cpu-alert-0 {
+ temperature = <85000>; /* millicelsius */
+ };
+ cpu_alert1: cpu-alert-1 {
+ temperature = <100000>; /* millicelsius */
+ };
+ cpu_alert2: cpu-alert-2 {
+ temperature = <110000>; /* millicelsius */
+ };
+ };
+ };
+ };
+
+ g2d@12800000 {
+ compatible = "samsung,s5pv210-g2d";
+ reg = <0x12800000 0x1000>;
+ interrupts = <0 89 0>;
+ clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
+ clock-names = "sclk_fimg2d", "fimg2d";
+ status = "disabled";
+ };
+
+ camera {
+ clocks = <&clock CLK_SCLK_CAM0>, <&clock CLK_SCLK_CAM1>,
+ <&clock CLK_PIXELASYNCM0>, <&clock CLK_PIXELASYNCM1>;
+ clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0", "pxl_async1";
+
+ fimc_0: fimc@11800000 {
+ samsung,pix-limits = <4224 8192 1920 4224>;
+ samsung,mainscaler-ext;
+ samsung,cam-if;
+ };
+
+ fimc_1: fimc@11810000 {
+ samsung,pix-limits = <4224 8192 1920 4224>;
+ samsung,mainscaler-ext;
+ samsung,cam-if;
+ };
+
+ fimc_2: fimc@11820000 {
+ samsung,pix-limits = <4224 8192 1920 4224>;
+ samsung,mainscaler-ext;
+ samsung,lcd-wb;
+ };
+
+ fimc_3: fimc@11830000 {
+ samsung,pix-limits = <1920 8192 1366 1920>;
+ samsung,rotators = <0>;
+ samsung,mainscaler-ext;
+ samsung,lcd-wb;
+ };
+ };
+
+ mixer: mixer@12C10000 {
+ clock-names = "mixer", "hdmi", "sclk_hdmi", "vp", "mout_mixer",
+ "sclk_mixer";
+ clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
+ <&clock CLK_SCLK_HDMI>, <&clock CLK_VP>,
+ <&clock CLK_MOUT_MIXER>, <&clock CLK_SCLK_MIXER>;
+ };
+
+ ppmu_lcd1: ppmu_lcd1@12240000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x12240000 0x2000>;
+ clocks = <&clock CLK_PPMULCD1>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/exynos4212.dtsi b/arch/arm/boot/dts/exynos4212.dtsi
new file mode 100644
index 000000000..5be03288f
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4212.dtsi
@@ -0,0 +1,52 @@
+/*
+ * Samsung's Exynos4212 SoC device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung's Exynos4212 SoC device nodes are listed in this file. Exynos4212
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * Exynos4212 SoC. As device tree coverage for Exynos4212 increases, additional
+ * nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include "exynos4x12.dtsi"
+
+/ {
+ compatible = "samsung,exynos4212", "samsung,exynos4";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@A00 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0xA00>;
+ cooling-min-level = <13>;
+ cooling-max-level = <7>;
+ #cooling-cells = <2>; /* min followed by max */
+ };
+
+ cpu@A01 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0xA01>;
+ };
+ };
+
+ combiner: interrupt-controller@10440000 {
+ samsung,combiner-nr = <18>;
+ };
+
+ gic: interrupt-controller@10490000 {
+ cpu-offset = <0x8000>;
+ };
+};
diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
new file mode 100644
index 000000000..d6b49e5b3
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -0,0 +1,509 @@
+/*
+ * Common definition for Hardkernel's Exynos4412 based ODROID-X/X2/U2/U3 boards
+ * device tree source
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <dt-bindings/sound/samsung-i2s.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/clock/maxim,max77686.h>
+#include "exynos4412.dtsi"
+
+/ {
+ chosen {
+ stdout-path = &serial_1;
+ };
+
+ firmware@0204F000 {
+ compatible = "samsung,secure-firmware";
+ reg = <0x0204F000 0x1000>;
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_power_key>;
+
+ power_key {
+ interrupt-parent = <&gpx1>;
+ interrupts = <3 0>;
+ gpios = <&gpx1 3 1>;
+ linux,code = <KEY_POWER>;
+ label = "power key";
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ i2s0: i2s@03830000 {
+ pinctrl-0 = <&i2s0_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+ clocks = <&clock_audss EXYNOS_I2S_BUS>,
+ <&clock_audss EXYNOS_DOUT_AUD_BUS>,
+ <&clock_audss EXYNOS_SCLK_I2S>;
+ clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
+ };
+
+ sound: sound {
+ compatible = "simple-audio-card";
+ assigned-clocks = <&clock_audss EXYNOS_MOUT_AUDSS>,
+ <&clock_audss EXYNOS_MOUT_I2S>,
+ <&clock_audss EXYNOS_DOUT_SRP>,
+ <&clock_audss EXYNOS_DOUT_AUD_BUS>;
+ assigned-clock-parents = <&clock CLK_FOUT_EPLL>,
+ <&clock_audss EXYNOS_MOUT_AUDSS>;
+ assigned-clock-rates = <0>,
+ <0>,
+ <192000000>,
+ <19200000>;
+
+ simple-audio-card,format = "i2s";
+ simple-audio-card,bitclock-master = <&link0_codec>;
+ simple-audio-card,frame-master = <&link0_codec>;
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s0 0>;
+ system-clock-frequency = <19200000>;
+ };
+
+ link0_codec: simple-audio-card,codec {
+ sound-dai = <&max98090>;
+ clocks = <&i2s0 CLK_I2S_CDCLK>;
+ };
+ };
+
+ emmc_pwrseq: pwrseq {
+ pinctrl-0 = <&sd1_cd>;
+ pinctrl-names = "default";
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpk1 2 1>;
+ };
+
+ mmc@12550000 {
+ pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
+ pinctrl-names = "default";
+ vmmc-supply = <&ldo20_reg &buck8_reg>;
+ mmc-pwrseq = <&emmc_pwrseq>;
+ status = "okay";
+
+ num-slots = <1>;
+ broken-cd;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ };
+
+ watchdog@10060000 {
+ status = "okay";
+ };
+
+ rtc@10070000 {
+ status = "okay";
+ clocks = <&clock CLK_RTC>, <&max77686 MAX77686_CLK_AP>;
+ clock-names = "rtc", "rtc_src";
+ };
+
+ g2d@10800000 {
+ status = "okay";
+ };
+
+ camera {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+
+ fimc_0: fimc@11800000 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC0>,
+ <&clock CLK_SCLK_FIMC0>;
+ assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+ assigned-clock-rates = <0>, <176000000>;
+ };
+
+ fimc_1: fimc@11810000 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC1>,
+ <&clock CLK_SCLK_FIMC1>;
+ assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+ assigned-clock-rates = <0>, <176000000>;
+ };
+
+ fimc_2: fimc@11820000 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC2>,
+ <&clock CLK_SCLK_FIMC2>;
+ assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+ assigned-clock-rates = <0>, <176000000>;
+ };
+
+ fimc_3: fimc@11830000 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC3>,
+ <&clock CLK_SCLK_FIMC3>;
+ assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+ assigned-clock-rates = <0>, <176000000>;
+ };
+ };
+
+ sdhci@12530000 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+ pinctrl-names = "default";
+ vmmc-supply = <&ldo4_reg &ldo21_reg>;
+ cd-gpios = <&gpk2 2 0>;
+ cd-inverted;
+ status = "okay";
+ };
+
+ serial@13800000 {
+ status = "okay";
+ };
+
+ serial@13810000 {
+ status = "okay";
+ };
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti";
+ clock-frequency = <0>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ i2c@13860000 {
+ pinctrl-0 = <&i2c0_bus>;
+ pinctrl-names = "default";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <400000>;
+ status = "okay";
+
+ usb3503: usb3503@08 {
+ compatible = "smsc,usb3503";
+ reg = <0x08>;
+
+ intn-gpios = <&gpx3 0 0>;
+ connect-gpios = <&gpx3 4 0>;
+ reset-gpios = <&gpx3 5 0>;
+ initial-mode = <1>;
+ };
+
+ max77686: pmic@09 {
+ compatible = "maxim,max77686";
+ interrupt-parent = <&gpx3>;
+ interrupts = <2 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&max77686_irq>;
+ reg = <0x09>;
+ #clock-cells = <1>;
+
+ voltage-regulators {
+ ldo1_reg: LDO1 {
+ regulator-name = "VDD_ALIVE_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "VDDQ_M1_2_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "VDDQ_EXT_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "VDDQ_MMC2_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "VDDQ_MMC1_3_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "VDD10_MPLL_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "VDD10_XPLL_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo8_reg: ldo@8 {
+ regulator-compatible = "LDO8";
+ regulator-name = "VDD10_HDMI_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ ldo10_reg: ldo@10 {
+ regulator-compatible = "LDO10";
+ regulator-name = "VDDQ_MIPIHSI_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "VDD18_ABB1_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "VDD33_USB_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "VDDQ_C2C_W_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "VDD18_ABB0_2_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "VDD10_HSIC_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "VDD18_HSIC_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo20_reg: LDO20 {
+ regulator-name = "LDO20_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ };
+
+ ldo21_reg: LDO21 {
+ regulator-name = "LDO21_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo25_reg: LDO25 {
+ regulator-name = "VDDQ_LCD_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "vdd_mif";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "vdd_int";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "vdd_g3d";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-microvolt-offset = <50000>;
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "VDDQ_CKEM1_2_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck6_reg: BUCK6 {
+ regulator-name = "BUCK6_1.35V";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck7_reg: BUCK7 {
+ regulator-name = "BUCK7_2.0V";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-always-on;
+ };
+
+ buck8_reg: BUCK8 {
+ regulator-name = "BUCK8_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+ };
+ };
+ };
+
+ i2c@13870000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_bus>;
+ status = "okay";
+ max98090: max98090@10 {
+ compatible = "maxim,max98090";
+ reg = <0x10>;
+ interrupt-parent = <&gpx0>;
+ interrupts = <0 0>;
+ clocks = <&i2s0 CLK_I2S_CDCLK>;
+ clock-names = "mclk";
+ #sound-dai-cells = <0>;
+ };
+ };
+
+ exynos-usbphy@125B0000 {
+ status = "okay";
+ };
+
+ hsotg@12480000 {
+ dr_mode = "peripheral";
+ status = "okay";
+ vusb_d-supply = <&ldo15_reg>;
+ vusb_a-supply = <&ldo12_reg>;
+ };
+
+ ehci: ehci@12580000 {
+ status = "okay";
+ };
+
+ tmu@100C0000 {
+ vtmu-supply = <&ldo10_reg>;
+ status = "okay";
+ };
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ cooling-maps {
+ map0 {
+ /* Corresponds to 800MHz at freq_table */
+ cooling-device = <&cpu0 7 7>;
+ };
+ map1 {
+ /* Corresponds to 200MHz at freq_table */
+ cooling-device = <&cpu0 13 13>;
+ };
+ };
+ };
+ };
+
+ mixer: mixer@12C10000 {
+ status = "okay";
+ };
+
+ hdmi@12D00000 {
+ hpd-gpio = <&gpx3 7 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_hpd>;
+ vdd-supply = <&ldo8_reg>;
+ vdd_osc-supply = <&ldo10_reg>;
+ vdd_pll-supply = <&ldo8_reg>;
+ ddc = <&hdmi_ddc>;
+ status = "okay";
+ };
+
+ hdmi_ddc: i2c@13880000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_bus>;
+ };
+
+ i2c@138E0000 {
+ status = "okay";
+ };
+};
+
+/* RSTN signal for eMMC */
+&sd1_cd {
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+};
+
+&pinctrl_1 {
+ gpio_power_key: power_key {
+ samsung,pins = "gpx1-3";
+ samsung,pin-pud = <0>;
+ };
+
+ max77686_irq: max77686-irq {
+ samsung,pins = "gpx3-2";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ hdmi_hpd: hdmi-hpd {
+ samsung,pins = "gpx3-7";
+ samsung,pin-pud = <1>;
+ };
+};
diff --git a/arch/arm/boot/dts/exynos4412-odroidu3.dts b/arch/arm/boot/dts/exynos4412-odroidu3.dts
new file mode 100644
index 000000000..44684e57e
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-odroidu3.dts
@@ -0,0 +1,63 @@
+/*
+ * Hardkernel's Exynos4412 based ODROID-U3 board device tree source
+ *
+ * Copyright (c) 2014 Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * Device tree source file for Hardkernel's ODROID-U3 board which is based
+ * on Samsung's Exynos4412 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+#include "exynos4412-odroid-common.dtsi"
+
+/ {
+ model = "Hardkernel ODROID-U3 board based on Exynos4412";
+ compatible = "hardkernel,odroid-u3", "samsung,exynos4412", "samsung,exynos4";
+
+ memory {
+ reg = <0x40000000 0x7FF00000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ led1 {
+ label = "led1:heart";
+ gpios = <&gpc1 0 1>;
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
+
+&usb3503 {
+ clock-names = "refclk";
+ clocks = <&pmu_system_controller 0>;
+ refclk-frequency = <24000000>;
+};
+
+&ehci {
+ port@1 {
+ status = "okay";
+ };
+ port@2 {
+ status = "okay";
+ };
+};
+
+&sound {
+ simple-audio-card,name = "Odroid-U3";
+ simple-audio-card,widgets =
+ "Headphone", "Headphone Jack",
+ "Speakers", "Speakers";
+ simple-audio-card,routing =
+ "Headphone Jack", "HPL",
+ "Headphone Jack", "HPR",
+ "Headphone Jack", "MICBIAS",
+ "IN1", "Headphone Jack",
+ "Speakers", "SPKL",
+ "Speakers", "SPKR";
+};
diff --git a/arch/arm/boot/dts/exynos4412-odroidx.dts b/arch/arm/boot/dts/exynos4412-odroidx.dts
new file mode 100644
index 000000000..cb1cfe723
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-odroidx.dts
@@ -0,0 +1,85 @@
+/*
+ * Hardkernel's Exynos4412 based ODROID-X board device tree source
+ *
+ * Copyright (c) 2012 Dongjin Kim <tobetter@gmail.com>
+ *
+ * Device tree source file for Hardkernel's ODROID-X board which is based
+ * on Samsung's Exynos4412 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+#include "exynos4412-odroid-common.dtsi"
+
+/ {
+ model = "Hardkernel ODROID-X board based on Exynos4412";
+ compatible = "hardkernel,odroid-x", "samsung,exynos4412", "samsung,exynos4";
+
+ memory {
+ reg = <0x40000000 0x3FF00000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ led1 {
+ label = "led1:heart";
+ gpios = <&gpc1 0 1>;
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+ led2 {
+ label = "led2:mmc0";
+ gpios = <&gpc1 2 1>;
+ default-state = "on";
+ linux,default-trigger = "mmc0";
+ };
+ };
+
+ serial@13820000 {
+ status = "okay";
+ };
+
+ serial@13830000 {
+ status = "okay";
+ };
+
+ gpio_keys {
+ pinctrl-0 = <&gpio_power_key &gpio_home_key>;
+
+ home_key {
+ interrupt-parent = <&gpx2>;
+ interrupts = <2 0>;
+ gpios = <&gpx2 2 0>;
+ linux,code = <KEY_HOME>;
+ label = "home key";
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ regulator_p3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "p3v3_en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpa1 1 1>;
+ enable-active-high;
+ regulator-always-on;
+ };
+};
+
+&ehci {
+ port@1 {
+ status = "okay";
+ };
+};
+
+&pinctrl_1 {
+ gpio_home_key: home_key {
+ samsung,pins = "gpx2-2";
+ samsung,pin-pud = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/exynos4412-odroidx2.dts b/arch/arm/boot/dts/exynos4412-odroidx2.dts
new file mode 100644
index 000000000..6e3367856
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-odroidx2.dts
@@ -0,0 +1,36 @@
+/*
+ * Hardkernel's Exynos4412 based ODROID-X2 board device tree source
+ *
+ * Copyright (c) 2012 Dongjin Kim <tobetter@gmail.com>
+ *
+ * Device tree source file for Hardkernel's ODROID-X2 board which is based
+ * on Samsung's Exynos4412 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include "exynos4412-odroidx.dts"
+
+/ {
+ model = "Hardkernel ODROID-X2 board based on Exynos4412";
+ compatible = "hardkernel,odroid-x2", "samsung,exynos4412", "samsung,exynos4";
+
+ memory {
+ reg = <0x40000000 0x7FF00000>;
+ };
+};
+
+&sound {
+ simple-audio-card,name = "Odroid-X2";
+ simple-audio-card,widgets =
+ "Headphone", "Headphone Jack",
+ "Microphone", "Mic Jack",
+ "Microphone", "DMIC";
+ simple-audio-card,routing =
+ "Headphone Jack", "HPL",
+ "Headphone Jack", "HPR",
+ "IN1", "Mic Jack",
+ "Mic Jack", "MICBIAS";
+};
diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts
new file mode 100644
index 000000000..bd8b73077
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-origen.dts
@@ -0,0 +1,534 @@
+/*
+ * Insignal's Exynos4412 based Origen board device tree source
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Device tree source file for Insignal's Origen board which is based on
+ * Samsung's Exynos4412 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+#include "exynos4412.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "Insignal Origen evaluation board based on Exynos4412";
+ compatible = "insignal,origen4412", "samsung,exynos4412", "samsung,exynos4";
+
+ memory {
+ reg = <0x40000000 0x40000000>;
+ };
+
+ chosen {
+ bootargs ="console=ttySAC2,115200";
+ stdout-path = &serial_2;
+ };
+
+ firmware@0203F000 {
+ compatible = "samsung,secure-firmware";
+ reg = <0x0203F000 0x1000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ mmc_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "VMEM_VDD_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpx1 1 0>;
+ enable-active-high;
+ };
+ };
+
+ watchdog@10060000 {
+ status = "okay";
+ };
+
+ rtc@10070000 {
+ status = "okay";
+ };
+
+ pinctrl@11000000 {
+ keypad_rows: keypad-rows {
+ samsung,pins = "gpx2-0", "gpx2-1", "gpx2-2";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_cols: keypad-cols {
+ samsung,pins = "gpx1-0", "gpx1-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ keypad@100A0000 {
+ samsung,keypad-num-rows = <3>;
+ samsung,keypad-num-columns = <2>;
+ linux,keypad-no-autorepeat;
+ linux,keypad-wakeup;
+ pinctrl-0 = <&keypad_rows &keypad_cols>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ key_home {
+ keypad,row = <0>;
+ keypad,column = <0>;
+ linux,code = <KEY_HOME>;
+ };
+
+ key_down {
+ keypad,row = <0>;
+ keypad,column = <1>;
+ linux,code = <KEY_DOWN>;
+ };
+
+ key_up {
+ keypad,row = <1>;
+ keypad,column = <0>;
+ linux,code = <KEY_UP>;
+ };
+
+ key_menu {
+ keypad,row = <1>;
+ keypad,column = <1>;
+ linux,code = <KEY_MENU>;
+ };
+
+ key_back {
+ keypad,row = <2>;
+ keypad,column = <0>;
+ linux,code = <KEY_BACK>;
+ };
+
+ key_enter {
+ keypad,row = <2>;
+ keypad,column = <1>;
+ linux,code = <KEY_ENTER>;
+ };
+ };
+
+ g2d@10800000 {
+ status = "okay";
+ };
+
+ sdhci@12530000 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sd2_cd>;
+ pinctrl-names = "default";
+ vmmc-supply = <&mmc_reg>;
+ status = "okay";
+ };
+
+ mmc@12550000 {
+ pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ num-slots = <1>;
+ broken-cd;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ };
+
+ codec@13400000 {
+ samsung,mfc-r = <0x43000000 0x800000>;
+ samsung,mfc-l = <0x51000000 0x800000>;
+ status = "okay";
+ };
+
+ fimd@11c00000 {
+ pinctrl-0 = <&lcd_clk &lcd_data24 &pwm1_out>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing {
+ clock-frequency = <47500000>;
+ hactive = <1024>;
+ vactive = <600>;
+ hfront-porch = <64>;
+ hback-porch = <16>;
+ hsync-len = <48>;
+ vback-porch = <64>;
+ vfront-porch = <16>;
+ vsync-len = <3>;
+ };
+ };
+
+ serial@13800000 {
+ status = "okay";
+ };
+
+ serial@13810000 {
+ status = "okay";
+ };
+
+ serial@13820000 {
+ status = "okay";
+ };
+
+ serial@13830000 {
+ status = "okay";
+ };
+
+ i2c@13860000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <20000>;
+ pinctrl-0 = <&i2c0_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ s5m8767_pmic@66 {
+ compatible = "samsung,s5m8767-pmic";
+ reg = <0x66>;
+
+ s5m8767,pmic-buck-default-dvs-idx = <3>;
+
+ s5m8767,pmic-buck-dvs-gpios = <&gpx2 3 0>,
+ <&gpx2 4 0>,
+ <&gpx2 5 0>;
+
+ s5m8767,pmic-buck-ds-gpios = <&gpm3 5 0>,
+ <&gpm3 6 0>,
+ <&gpm3 7 0>;
+
+ s5m8767,pmic-buck2-dvs-voltage = <1250000>, <1200000>,
+ <1200000>, <1200000>,
+ <1200000>, <1200000>,
+ <1200000>, <1200000>;
+
+ s5m8767,pmic-buck3-dvs-voltage = <1100000>, <1100000>,
+ <1100000>, <1100000>,
+ <1100000>, <1100000>,
+ <1100000>, <1100000>;
+
+ s5m8767,pmic-buck4-dvs-voltage = <1200000>, <1200000>,
+ <1200000>, <1200000>,
+ <1200000>, <1200000>,
+ <1200000>, <1200000>;
+
+ regulators {
+ ldo1_reg: LDO1 {
+ regulator-name = "VDD_ALIVE";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "VDDQ_M12";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "VDDIOAP_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "VDDQ_PRE";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "VDD18_2M";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "VDD10_MPLL";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "VDD10_XPLL";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "VDD10_MIPI";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "VDD33_LCD";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "VDD18_MIPI";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "VDD18_ABB1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "VDD33_UOTG";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "VDDIOPERI_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "VDD18_ABB02";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "VDD10_USH";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "VDD18_HSIC";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "VDDIOAP_MMC012_28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo18_reg: LDO18 {
+ regulator-name = "VDDIOPERI_28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo19_reg: LDO19 {
+ regulator-name = "DVDD25";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo20_reg: LDO20 {
+ regulator-name = "VDD28_CAM";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo21_reg: LDO21 {
+ regulator-name = "VDD28_AF";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo22_reg: LDO22 {
+ regulator-name = "VDDA28_2M";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo23_reg: LDO23 {
+ regulator-name = "VDD28_TF";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo24_reg: LDO24 {
+ regulator-name = "VDD33_A31";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo25_reg: LDO25 {
+ regulator-name = "VDD18_CAM";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo26_reg: LDO26 {
+ regulator-name = "VDD18_A31";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo27_reg: LDO27 {
+ regulator-name = "GPS_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo28_reg: LDO28 {
+ regulator-name = "DVDD12";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "vdd_mif";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "vdd_int";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "vdd_g3d";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "vdd_m12";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ buck6_reg: BUCK6 {
+ regulator-name = "vdd12_5m";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ buck9_reg: BUCK9 {
+ regulator-name = "vddf28_emmc";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+ };
+ };
+ };
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti";
+ clock-frequency = <0>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti";
+ clock-frequency = <24000000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts
new file mode 100644
index 000000000..b9256afbc
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts
@@ -0,0 +1,162 @@
+/*
+ * Samsung's Exynos4412 based SMDK board device tree source
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Device tree source file for Samsung's SMDK4412 board which is based on
+ * Samsung's Exynos4412 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+#include "exynos4412.dtsi"
+
+/ {
+ model = "Samsung SMDK evaluation board based on Exynos4412";
+ compatible = "samsung,smdk4412", "samsung,exynos4412", "samsung,exynos4";
+
+ memory {
+ reg = <0x40000000 0x40000000>;
+ };
+
+ chosen {
+ bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
+ stdout-path = &serial_1;
+ };
+
+ g2d@10800000 {
+ status = "okay";
+ };
+
+ pinctrl@11000000 {
+ keypad_rows: keypad-rows {
+ samsung,pins = "gpx2-0", "gpx2-1", "gpx2-2";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_cols: keypad-cols {
+ samsung,pins = "gpx1-0", "gpx1-1", "gpx1-2", "gpx1-3",
+ "gpx1-4", "gpx1-5", "gpx1-6", "gpx1-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ keypad@100A0000 {
+ samsung,keypad-num-rows = <3>;
+ samsung,keypad-num-columns = <8>;
+ linux,keypad-no-autorepeat;
+ linux,keypad-wakeup;
+ pinctrl-0 = <&keypad_rows &keypad_cols>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ key_1 {
+ keypad,row = <1>;
+ keypad,column = <3>;
+ linux,code = <2>;
+ };
+
+ key_2 {
+ keypad,row = <1>;
+ keypad,column = <4>;
+ linux,code = <3>;
+ };
+
+ key_3 {
+ keypad,row = <1>;
+ keypad,column = <5>;
+ linux,code = <4>;
+ };
+
+ key_4 {
+ keypad,row = <1>;
+ keypad,column = <6>;
+ linux,code = <5>;
+ };
+
+ key_5 {
+ keypad,row = <1>;
+ keypad,column = <7>;
+ linux,code = <6>;
+ };
+
+ key_A {
+ keypad,row = <2>;
+ keypad,column = <6>;
+ linux,code = <30>;
+ };
+
+ key_B {
+ keypad,row = <2>;
+ keypad,column = <7>;
+ linux,code = <48>;
+ };
+
+ key_C {
+ keypad,row = <0>;
+ keypad,column = <5>;
+ linux,code = <46>;
+ };
+
+ key_D {
+ keypad,row = <2>;
+ keypad,column = <5>;
+ linux,code = <32>;
+ };
+
+ key_E {
+ keypad,row = <0>;
+ keypad,column = <7>;
+ linux,code = <18>;
+ };
+ };
+
+ sdhci@12530000 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sd2_cd>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ codec@13400000 {
+ samsung,mfc-r = <0x43000000 0x800000>;
+ samsung,mfc-l = <0x51000000 0x800000>;
+ status = "okay";
+ };
+
+ serial@13800000 {
+ status = "okay";
+ };
+
+ serial@13810000 {
+ status = "okay";
+ };
+
+ serial@13820000 {
+ status = "okay";
+ };
+
+ serial@13830000 {
+ status = "okay";
+ };
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti";
+ clock-frequency = <0>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti";
+ clock-frequency = <24000000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/exynos4412-tiny4412.dts b/arch/arm/boot/dts/exynos4412-tiny4412.dts
new file mode 100644
index 000000000..d46fd4c2a
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-tiny4412.dts
@@ -0,0 +1,97 @@
+/*
+ * FriendlyARM's Exynos4412 based TINY4412 board device tree source
+ *
+ * Copyright (c) 2013 Alex Ling <kasimling@gmail.com>
+ *
+ * Device tree source file for FriendlyARM's TINY4412 board which is based on
+ * Samsung's Exynos4412 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+#include "exynos4412.dtsi"
+
+/ {
+ model = "FriendlyARM TINY4412 board based on Exynos4412";
+ compatible = "friendlyarm,tiny4412", "samsung,exynos4412", "samsung,exynos4";
+
+ chosen {
+ stdout-path = &serial_0;
+ };
+
+ memory {
+ reg = <0x40000000 0x40000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led1 {
+ label = "led1";
+ gpios = <&gpm4 0 1>;
+ default-state = "off";
+ linux,default-trigger = "heartbeat";
+ };
+
+ led2 {
+ label = "led2";
+ gpios = <&gpm4 1 1>;
+ default-state = "off";
+ };
+
+ led3 {
+ label = "led3";
+ gpios = <&gpm4 2 1>;
+ default-state = "off";
+ };
+
+ led4 {
+ label = "led4";
+ gpios = <&gpm4 3 1>;
+ default-state = "off";
+ linux,default-trigger = "mmc0";
+ };
+ };
+
+ rtc@10070000 {
+ status = "okay";
+ };
+
+ sdhci@12530000 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ serial@13800000 {
+ status = "okay";
+ };
+
+ serial@13810000 {
+ status = "okay";
+ };
+
+ serial@13820000 {
+ status = "okay";
+ };
+
+ serial@13830000 {
+ status = "okay";
+ };
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti";
+ clock-frequency = <0>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti";
+ clock-frequency = <24000000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi b/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi
new file mode 100644
index 000000000..e3f7934d1
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi
@@ -0,0 +1,24 @@
+/*
+ * Device tree sources for Exynos4412 TMU sensor configuration
+ *
+ * Copyright (c) 2014 Lukasz Majewski <l.majewski@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 <dt-bindings/thermal/thermal_exynos.h>
+
+#thermal-sensor-cells = <0>;
+samsung,tmu_gain = <8>;
+samsung,tmu_reference_voltage = <16>;
+samsung,tmu_noise_cancel_mode = <4>;
+samsung,tmu_efuse_value = <55>;
+samsung,tmu_min_efuse_value = <40>;
+samsung,tmu_max_efuse_value = <100>;
+samsung,tmu_first_point_trim = <25>;
+samsung,tmu_second_point_trim = <85>;
+samsung,tmu_default_temp_offset = <50>;
+samsung,tmu_cal_type = <TYPE_ONE_POINT_TRIMMING>;
diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
new file mode 100644
index 000000000..792394dd0
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -0,0 +1,1306 @@
+/*
+ * Samsung's Exynos4412 based Trats 2 board device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Device tree source file for Samsung's Trats 2 board which is based on
+ * Samsung's Exynos4412 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+#include "exynos4412.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ model = "Samsung Trats 2 based on Exynos4412";
+ compatible = "samsung,trats2", "samsung,exynos4412", "samsung,exynos4";
+
+ aliases {
+ i2c9 = &i2c_ak8975;
+ i2c10 = &i2c_cm36651;
+ i2c11 = &i2c_max77693;
+ i2c12 = &i2c_max77693_fuel;
+ };
+
+ memory {
+ reg = <0x40000000 0x40000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
+ stdout-path = &serial_2;
+ };
+
+ firmware@0204F000 {
+ compatible = "samsung,secure-firmware";
+ reg = <0x0204F000 0x1000>;
+ };
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti", "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti", "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cam_io_reg: voltage-regulator-1 {
+ compatible = "regulator-fixed";
+ regulator-name = "CAM_SENSOR_A";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpm0 2 0>;
+ enable-active-high;
+ };
+
+ lcd_vdd3_reg: voltage-regulator-2 {
+ compatible = "regulator-fixed";
+ regulator-name = "LCD_VDD_2.2V";
+ regulator-min-microvolt = <2200000>;
+ regulator-max-microvolt = <2200000>;
+ gpio = <&gpc0 1 0>;
+ enable-active-high;
+ };
+
+ cam_af_reg: voltage-regulator-3 {
+ compatible = "regulator-fixed";
+ regulator-name = "CAM_AF";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpm0 4 0>;
+ enable-active-high;
+ };
+
+ ps_als_reg: voltage-regulator-5 {
+ compatible = "regulator-fixed";
+ regulator-name = "LED_A_3.0V";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpj0 5 0>;
+ enable-active-high;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ key-down {
+ gpios = <&gpx3 3 1>;
+ linux,code = <114>;
+ label = "volume down";
+ debounce-interval = <10>;
+ };
+
+ key-up {
+ gpios = <&gpx2 2 1>;
+ linux,code = <115>;
+ label = "volume up";
+ debounce-interval = <10>;
+ };
+
+ key-power {
+ gpios = <&gpx2 7 1>;
+ linux,code = <116>;
+ label = "power";
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+
+ key-ok {
+ gpios = <&gpx0 1 1>;
+ linux,code = <139>;
+ label = "ok";
+ debounce-inteval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ adc: adc@126C0000 {
+ vdd-supply = <&ldo3_reg>;
+ status = "okay";
+ };
+
+ i2c@13890000 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-slave-addr = <0x10>;
+ samsung,i2c-max-bus-freq = <400000>;
+ pinctrl-0 = <&i2c3_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ mms114-touchscreen@48 {
+ compatible = "melfas,mms114";
+ reg = <0x48>;
+ interrupt-parent = <&gpm2>;
+ interrupts = <3 2>;
+ x-size = <720>;
+ y-size = <1280>;
+ avdd-supply = <&ldo23_reg>;
+ vdd-supply = <&ldo24_reg>;
+ };
+ };
+
+ i2c_0: i2c@13860000 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-slave-addr = <0x10>;
+ samsung,i2c-max-bus-freq = <400000>;
+ pinctrl-0 = <&i2c0_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ s5c73m3@3c {
+ compatible = "samsung,s5c73m3";
+ reg = <0x3c>;
+ standby-gpios = <&gpm0 1 1>; /* ISP_STANDBY */
+ xshutdown-gpios = <&gpf1 3 1>; /* ISP_RESET */
+ vdd-int-supply = <&buck9_reg>;
+ vddio-cis-supply = <&ldo9_reg>;
+ vdda-supply = <&ldo17_reg>;
+ vddio-host-supply = <&ldo18_reg>;
+ vdd-af-supply = <&cam_af_reg>;
+ vdd-reg-supply = <&cam_io_reg>;
+ clock-frequency = <24000000>;
+ /* CAM_A_CLKOUT */
+ clocks = <&camera 0>;
+ clock-names = "cis_extclk";
+ port {
+ s5c73m3_ep: endpoint {
+ remote-endpoint = <&csis0_ep>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+ };
+ };
+
+ i2c@138A0000 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-slave-addr = <0x10>;
+ samsung,i2c-max-bus-freq = <100000>;
+ pinctrl-0 = <&i2c4_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ wm1811: wm1811@1a {
+ compatible = "wlf,wm1811";
+ reg = <0x1a>;
+ clocks = <&pmu_system_controller 0>;
+ clock-names = "MCLK1";
+ DCVDD-supply = <&ldo3_reg>;
+ DBVDD1-supply = <&ldo3_reg>;
+ wlf,ldo1ena = <&gpj0 4 0>;
+ };
+ };
+
+ i2c@138D0000 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-slave-addr = <0x10>;
+ samsung,i2c-max-bus-freq = <100000>;
+ pinctrl-0 = <&i2c7_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ max77686_pmic@09 {
+ compatible = "maxim,max77686";
+ interrupt-parent = <&gpx0>;
+ interrupts = <7 0>;
+ reg = <0x09>;
+ #clock-cells = <1>;
+
+ voltage-regulators {
+ ldo1_reg: ldo1 {
+ regulator-compatible = "LDO1";
+ regulator-name = "VALIVE_1.0V_AP";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo2_reg: ldo2 {
+ regulator-compatible = "LDO2";
+ regulator-name = "VM1M2_1.2V_AP";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo3_reg: ldo3 {
+ regulator-compatible = "LDO3";
+ regulator-name = "VCC_1.8V_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo4_reg: ldo4 {
+ regulator-compatible = "LDO4";
+ regulator-name = "VCC_2.8V_AP";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo5_reg: ldo5 {
+ regulator-compatible = "LDO5";
+ regulator-name = "VCC_1.8V_IO";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo6_reg: ldo6 {
+ regulator-compatible = "LDO6";
+ regulator-name = "VMPLL_1.0V_AP";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo7_reg: ldo7 {
+ regulator-compatible = "LDO7";
+ regulator-name = "VPLL_1.0V_AP";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo8_reg: ldo8 {
+ regulator-compatible = "LDO8";
+ regulator-name = "VMIPI_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo9_reg: ldo9 {
+ regulator-compatible = "LDO9";
+ regulator-name = "CAM_ISP_MIPI_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo10_reg: ldo10 {
+ regulator-compatible = "LDO10";
+ regulator-name = "VMIPI_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo11_reg: ldo11 {
+ regulator-compatible = "LDO11";
+ regulator-name = "VABB1_1.95V";
+ regulator-min-microvolt = <1950000>;
+ regulator-max-microvolt = <1950000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo12_reg: ldo12 {
+ regulator-compatible = "LDO12";
+ regulator-name = "VUOTG_3.0V";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo13_reg: ldo13 {
+ regulator-compatible = "LDO13";
+ regulator-name = "NFC_AVDD_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo14_reg: ldo14 {
+ regulator-compatible = "LDO14";
+ regulator-name = "VABB2_1.95V";
+ regulator-min-microvolt = <1950000>;
+ regulator-max-microvolt = <1950000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo15_reg: ldo15 {
+ regulator-compatible = "LDO15";
+ regulator-name = "VHSIC_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo16_reg: ldo16 {
+ regulator-compatible = "LDO16";
+ regulator-name = "VHSIC_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo17_reg: ldo17 {
+ regulator-compatible = "LDO17";
+ regulator-name = "CAM_SENSOR_CORE_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo18_reg: ldo18 {
+ regulator-compatible = "LDO18";
+ regulator-name = "CAM_ISP_SEN_IO_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo19_reg: ldo19 {
+ regulator-compatible = "LDO19";
+ regulator-name = "VT_CAM_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo20_reg: ldo20 {
+ regulator-compatible = "LDO20";
+ regulator-name = "VDDQ_PRE_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo21_reg: ldo21 {
+ regulator-compatible = "LDO21";
+ regulator-name = "VTF_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ maxim,ena-gpios = <&gpy2 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ ldo22_reg: ldo22 {
+ regulator-compatible = "LDO22";
+ regulator-name = "VMEM_VDD_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ maxim,ena-gpios = <&gpk0 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ ldo23_reg: ldo23 {
+ regulator-compatible = "LDO23";
+ regulator-name = "TSP_AVDD_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo24_reg: ldo24 {
+ regulator-compatible = "LDO24";
+ regulator-name = "TSP_VDD_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo25_reg: ldo25 {
+ regulator-compatible = "LDO25";
+ regulator-name = "LCD_VCC_3.3V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo26_reg: ldo26 {
+ regulator-compatible = "LDO26";
+ regulator-name = "MOTOR_VCC_3.0V";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ buck1_reg: buck1 {
+ regulator-compatible = "BUCK1";
+ regulator-name = "vdd_mif";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck2_reg: buck2 {
+ regulator-compatible = "BUCK2";
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ buck3_reg: buck3 {
+ regulator-compatible = "BUCK3";
+ regulator-name = "vdd_int";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck4_reg: buck4 {
+ regulator-compatible = "BUCK4";
+ regulator-name = "vdd_g3d";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck5_reg: buck5 {
+ regulator-compatible = "BUCK5";
+ regulator-name = "VMEM_1.2V_AP";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ buck6_reg: buck6 {
+ regulator-compatible = "BUCK6";
+ regulator-name = "VCC_SUB_1.35V";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+
+ buck7_reg: buck7 {
+ regulator-compatible = "BUCK7";
+ regulator-name = "VCC_SUB_2.0V";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-always-on;
+ };
+
+ buck8_reg: buck8 {
+ regulator-compatible = "BUCK8";
+ regulator-name = "VMEM_VDDF_3.0V";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ maxim,ena-gpios = <&gpk0 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ buck9_reg: buck9 {
+ regulator-compatible = "BUCK9";
+ regulator-name = "CAM_ISP_CORE_1.2V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1200000>;
+ maxim,ena-gpios = <&gpm0 3 GPIO_ACTIVE_HIGH>;
+ };
+ };
+ };
+ };
+
+ i2c_max77693: i2c-gpio-1 {
+ compatible = "i2c-gpio";
+ gpios = <&gpm2 0 GPIO_ACTIVE_HIGH>, <&gpm2 1 GPIO_ACTIVE_HIGH>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ max77693@66 {
+ compatible = "maxim,max77693";
+ interrupt-parent = <&gpx1>;
+ interrupts = <5 2>;
+ reg = <0x66>;
+
+ regulators {
+ esafeout1_reg: ESAFEOUT1@1 {
+ regulator-name = "ESAFEOUT1";
+ };
+ esafeout2_reg: ESAFEOUT2@2 {
+ regulator-name = "ESAFEOUT2";
+ };
+ charger_reg: CHARGER@0 {
+ regulator-name = "CHARGER";
+ regulator-min-microamp = <60000>;
+ regulator-max-microamp = <2580000>;
+ };
+ };
+
+ max77693_haptic {
+ compatible = "maxim,max77693-haptic";
+ haptic-supply = <&ldo26_reg>;
+ pwms = <&pwm 0 38022 0>;
+ };
+
+ charger {
+ compatible = "maxim,max77693-charger";
+
+ maxim,constant-microvolt = <4350000>;
+ maxim,min-system-microvolt = <3600000>;
+ maxim,thermal-regulation-celsius = <100>;
+ maxim,battery-overcurrent-microamp = <3500000>;
+ maxim,charge-input-threshold-microvolt = <4300000>;
+ };
+ };
+ };
+
+ i2c_max77693_fuel: i2c-gpio-3 {
+ compatible = "i2c-gpio";
+ gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>, <&gpf1 4 GPIO_ACTIVE_HIGH>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ max77693-fuel-gauge@36 {
+ compatible = "maxim,max17047";
+ interrupt-parent = <&gpx2>;
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+ reg = <0x36>;
+ };
+ };
+
+ mmc@12550000 {
+ num-slots = <1>;
+ broken-cd;
+ non-removable;
+ card-detect-delay = <200>;
+ vmmc-supply = <&ldo22_reg>;
+ clock-frequency = <400000000>;
+ samsung,dw-mshc-ciu-div = <0>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
+ pinctrl-names = "default";
+ status = "okay";
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ };
+
+ sdhci@12530000 {
+ bus-width = <4>;
+ cd-gpios = <&gpx3 4 0>;
+ cd-inverted;
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4>;
+ pinctrl-names = "default";
+ vmmc-supply = <&ldo21_reg>;
+ status = "okay";
+ };
+
+ serial@13800000 {
+ status = "okay";
+ };
+
+ serial@13810000 {
+ status = "okay";
+ };
+
+ serial@13820000 {
+ status = "okay";
+ };
+
+ serial@13830000 {
+ status = "okay";
+ };
+
+ tmu@100C0000 {
+ vtmu-supply = <&ldo10_reg>;
+ status = "okay";
+ };
+
+ i2c_ak8975: i2c-gpio-0 {
+ compatible = "i2c-gpio";
+ gpios = <&gpy2 4 0>, <&gpy2 5 0>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ ak8975@0c {
+ compatible = "asahi-kasei,ak8975";
+ reg = <0x0c>;
+ gpios = <&gpj0 7 0>;
+ };
+ };
+
+ i2c_cm36651: i2c-gpio-2 {
+ compatible = "i2c-gpio";
+ gpios = <&gpf0 0 1>, <&gpf0 1 1>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cm36651@18 {
+ compatible = "capella,cm36651";
+ reg = <0x18>;
+ interrupt-parent = <&gpx0>;
+ interrupts = <2 2>;
+ vled-supply = <&ps_als_reg>;
+ };
+ };
+
+ spi_1: spi@13930000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_bus>;
+ cs-gpios = <&gpb 5 0>;
+ status = "okay";
+
+ s5c73m3_spi: s5c73m3 {
+ compatible = "samsung,s5c73m3";
+ spi-max-frequency = <50000000>;
+ reg = <0>;
+ controller-data {
+ samsung,spi-feedback-delay = <2>;
+ };
+ };
+ };
+
+ pwm: pwm@139D0000 {
+ pinctrl-0 = <&pwm0_out>;
+ pinctrl-names = "default";
+ samsung,pwm-outputs = <0>;
+ status = "okay";
+ };
+
+ dsi_0: dsi@11C80000 {
+ vddcore-supply = <&ldo8_reg>;
+ vddio-supply = <&ldo10_reg>;
+ samsung,pll-clock-frequency = <24000000>;
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+
+ dsi_out: endpoint {
+ remote-endpoint = <&dsi_in>;
+ samsung,burst-clock-frequency = <500000000>;
+ samsung,esc-clock-frequency = <20000000>;
+ };
+ };
+ };
+
+ panel@0 {
+ compatible = "samsung,s6e8aa0";
+ reg = <0>;
+ vdd3-supply = <&lcd_vdd3_reg>;
+ vci-supply = <&ldo25_reg>;
+ reset-gpios = <&gpy4 5 0>;
+ power-on-delay= <50>;
+ reset-delay = <100>;
+ init-delay = <100>;
+ flip-horizontal;
+ flip-vertical;
+ panel-width-mm = <58>;
+ panel-height-mm = <103>;
+
+ display-timings {
+ timing-0 {
+ clock-frequency = <57153600>;
+ hactive = <720>;
+ vactive = <1280>;
+ hfront-porch = <5>;
+ hback-porch = <5>;
+ hsync-len = <5>;
+ vfront-porch = <13>;
+ vback-porch = <1>;
+ vsync-len = <2>;
+ };
+ };
+
+ port {
+ dsi_in: endpoint {
+ remote-endpoint = <&dsi_out>;
+ };
+ };
+ };
+ };
+
+ fimd@11c00000 {
+ status = "okay";
+ };
+
+ camera: camera {
+ pinctrl-0 = <&cam_port_a_clk_active &cam_port_b_clk_active>;
+ pinctrl-names = "default";
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_CAM0>,
+ <&clock CLK_MOUT_CAM1>;
+ assigned-clock-parents = <&clock CLK_XUSBXTI>,
+ <&clock CLK_XUSBXTI>;
+
+ fimc_0: fimc@11800000 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC0>,
+ <&clock CLK_SCLK_FIMC0>;
+ assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+ assigned-clock-rates = <0>, <176000000>;
+ };
+
+ fimc_1: fimc@11810000 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC1>,
+ <&clock CLK_SCLK_FIMC1>;
+ assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+ assigned-clock-rates = <0>, <176000000>;
+ };
+
+ fimc_2: fimc@11820000 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC2>,
+ <&clock CLK_SCLK_FIMC2>;
+ assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+ assigned-clock-rates = <0>, <176000000>;
+ };
+
+ fimc_3: fimc@11830000 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC3>,
+ <&clock CLK_SCLK_FIMC3>;
+ assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+ assigned-clock-rates = <0>, <176000000>;
+ };
+
+ csis_0: csis@11880000 {
+ status = "okay";
+ vddcore-supply = <&ldo8_reg>;
+ vddio-supply = <&ldo10_reg>;
+ assigned-clocks = <&clock CLK_MOUT_CSIS0>,
+ <&clock CLK_SCLK_CSIS0>;
+ assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+ assigned-clock-rates = <0>, <176000000>;
+
+ /* Camera C (3) MIPI CSI-2 (CSIS0) */
+ port@3 {
+ reg = <3>;
+ csis0_ep: endpoint {
+ remote-endpoint = <&s5c73m3_ep>;
+ data-lanes = <1 2 3 4>;
+ samsung,csis-hs-settle = <12>;
+ };
+ };
+ };
+
+ csis_1: csis@11890000 {
+ status = "okay";
+ vddcore-supply = <&ldo8_reg>;
+ vddio-supply = <&ldo10_reg>;
+ assigned-clocks = <&clock CLK_MOUT_CSIS1>,
+ <&clock CLK_SCLK_CSIS1>;
+ assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+ assigned-clock-rates = <0>, <176000000>;
+
+ /* Camera D (4) MIPI CSI-2 (CSIS1) */
+ port@4 {
+ reg = <4>;
+ csis1_ep: endpoint {
+ remote-endpoint = <&is_s5k6a3_ep>;
+ data-lanes = <1>;
+ samsung,csis-hs-settle = <18>;
+ samsung,csis-wclk;
+ };
+ };
+ };
+
+ fimc_lite_0: fimc-lite@12390000 {
+ status = "okay";
+ };
+
+ fimc_lite_1: fimc-lite@123A0000 {
+ status = "okay";
+ };
+
+ fimc-is@12000000 {
+ pinctrl-0 = <&fimc_is_uart>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ i2c1_isp: i2c-isp@12140000 {
+ pinctrl-0 = <&fimc_is_i2c1>;
+ pinctrl-names = "default";
+
+ s5k6a3@10 {
+ compatible = "samsung,s5k6a3";
+ reg = <0x10>;
+ svdda-supply = <&cam_io_reg>;
+ svddio-supply = <&ldo19_reg>;
+ afvdd-supply = <&ldo19_reg>;
+ clock-frequency = <24000000>;
+ /* CAM_B_CLKOUT */
+ clocks = <&camera 1>;
+ clock-names = "extclk";
+ samsung,camclk-out = <1>;
+ gpios = <&gpm1 6 0>;
+
+ port {
+ is_s5k6a3_ep: endpoint {
+ remote-endpoint = <&csis1_ep>;
+ data-lanes = <1>;
+ };
+ };
+ };
+ };
+ };
+ };
+
+ i2s0: i2s@03830000 {
+ pinctrl-0 = <&i2s0_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ sound {
+ compatible = "samsung,trats2-audio";
+ samsung,i2s-controller = <&i2s0>;
+ samsung,model = "Trats2";
+ samsung,audio-codec = <&wm1811>;
+ samsung,audio-routing =
+ "SPK", "SPKOUTLN",
+ "SPK", "SPKOUTLP",
+ "SPK", "SPKOUTRN",
+ "SPK", "SPKOUTRP";
+ };
+
+ exynos-usbphy@125B0000 {
+ status = "okay";
+ };
+
+ hsotg@12480000 {
+ vusb_d-supply = <&ldo15_reg>;
+ vusb_a-supply = <&ldo12_reg>;
+ dr_mode = "peripheral";
+ status = "okay";
+ };
+
+ thermistor-ap@0 {
+ compatible = "ntc,ncp15wb473";
+ pullup-uv = <1800000>; /* VCC_1.8V_AP */
+ pullup-ohm = <100000>; /* 100K */
+ pulldown-ohm = <100000>; /* 100K */
+ io-channels = <&adc 1>; /* AP temperature */
+ };
+
+ thermistor-battery@1 {
+ compatible = "ntc,ncp15wb473";
+ pullup-uv = <1800000>; /* VCC_1.8V_AP */
+ pullup-ohm = <100000>; /* 100K */
+ pulldown-ohm = <100000>; /* 100K */
+ io-channels = <&adc 2>; /* Battery temperature */
+ };
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ cooling-maps {
+ map0 {
+ /* Corresponds to 800MHz at freq_table */
+ cooling-device = <&cpu0 7 7>;
+ };
+ map1 {
+ /* Corresponds to 200MHz at freq_table */
+ cooling-device = <&cpu0 13 13>;
+ };
+ };
+ };
+ };
+};
+
+&pmu_system_controller {
+ assigned-clocks = <&pmu_system_controller 0>;
+ assigned-clock-parents = <&clock CLK_XUSBXTI>;
+};
+
+&ppmu_dmc0 {
+ status = "okay";
+
+ events {
+ ppmu_dmc0_3: ppmu-event3-dmc0 {
+ event-name = "ppmu-event3-dmc0";
+ };
+ };
+};
+
+&ppmu_dmc1 {
+ status = "okay";
+
+ events {
+ ppmu_dmc1_3: ppmu-event3-dmc1 {
+ event-name = "ppmu-event3-dmc1";
+ };
+ };
+};
+
+&ppmu_leftbus {
+ status = "okay";
+
+ events {
+ ppmu_leftbus_3: ppmu-event3-leftbus {
+ event-name = "ppmu-event3-leftbus";
+ };
+ };
+};
+
+&ppmu_rightbus {
+ status = "okay";
+
+ events {
+ ppmu_rightbus_3: ppmu-event3-rightbus {
+ event-name = "ppmu-event3-rightbus";
+ };
+ };
+};
+
+&pinctrl_0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sleep0>;
+
+ sleep0: sleep-states {
+ PIN_SLP(gpa0-0, INPUT, NONE);
+ PIN_SLP(gpa0-1, OUT0, NONE);
+ PIN_SLP(gpa0-2, INPUT, NONE);
+ PIN_SLP(gpa0-3, INPUT, UP);
+ PIN_SLP(gpa0-4, INPUT, NONE);
+ PIN_SLP(gpa0-5, INPUT, DOWN);
+ PIN_SLP(gpa0-6, INPUT, DOWN);
+ PIN_SLP(gpa0-7, INPUT, UP);
+
+ PIN_SLP(gpa1-0, INPUT, DOWN);
+ PIN_SLP(gpa1-1, INPUT, DOWN);
+ PIN_SLP(gpa1-2, INPUT, DOWN);
+ PIN_SLP(gpa1-3, INPUT, DOWN);
+ PIN_SLP(gpa1-4, INPUT, DOWN);
+ PIN_SLP(gpa1-5, INPUT, DOWN);
+
+ PIN_SLP(gpb-0, INPUT, NONE);
+ PIN_SLP(gpb-1, INPUT, NONE);
+ PIN_SLP(gpb-2, INPUT, NONE);
+ PIN_SLP(gpb-3, INPUT, NONE);
+ PIN_SLP(gpb-4, INPUT, DOWN);
+ PIN_SLP(gpb-5, INPUT, UP);
+ PIN_SLP(gpb-6, INPUT, DOWN);
+ PIN_SLP(gpb-7, INPUT, DOWN);
+
+ PIN_SLP(gpc0-0, INPUT, DOWN);
+ PIN_SLP(gpc0-1, INPUT, DOWN);
+ PIN_SLP(gpc0-2, INPUT, DOWN);
+ PIN_SLP(gpc0-3, INPUT, DOWN);
+ PIN_SLP(gpc0-4, INPUT, DOWN);
+
+ PIN_SLP(gpc1-0, INPUT, NONE);
+ PIN_SLP(gpc1-1, PREV, NONE);
+ PIN_SLP(gpc1-2, INPUT, NONE);
+ PIN_SLP(gpc1-3, INPUT, NONE);
+ PIN_SLP(gpc1-4, INPUT, NONE);
+
+ PIN_SLP(gpd0-0, INPUT, DOWN);
+ PIN_SLP(gpd0-1, INPUT, DOWN);
+ PIN_SLP(gpd0-2, INPUT, NONE);
+ PIN_SLP(gpd0-3, INPUT, NONE);
+
+ PIN_SLP(gpd1-0, INPUT, DOWN);
+ PIN_SLP(gpd1-1, INPUT, DOWN);
+ PIN_SLP(gpd1-2, INPUT, NONE);
+ PIN_SLP(gpd1-3, INPUT, NONE);
+
+ PIN_SLP(gpf0-0, INPUT, NONE);
+ PIN_SLP(gpf0-1, INPUT, NONE);
+ PIN_SLP(gpf0-2, INPUT, DOWN);
+ PIN_SLP(gpf0-3, INPUT, DOWN);
+ PIN_SLP(gpf0-4, INPUT, NONE);
+ PIN_SLP(gpf0-5, INPUT, DOWN);
+ PIN_SLP(gpf0-6, INPUT, NONE);
+ PIN_SLP(gpf0-7, INPUT, DOWN);
+
+ PIN_SLP(gpf1-0, INPUT, DOWN);
+ PIN_SLP(gpf1-1, INPUT, DOWN);
+ PIN_SLP(gpf1-2, INPUT, DOWN);
+ PIN_SLP(gpf1-3, INPUT, DOWN);
+ PIN_SLP(gpf1-4, INPUT, NONE);
+ PIN_SLP(gpf1-5, INPUT, NONE);
+ PIN_SLP(gpf1-6, INPUT, DOWN);
+ PIN_SLP(gpf1-7, PREV, NONE);
+
+ PIN_SLP(gpf2-0, PREV, NONE);
+ PIN_SLP(gpf2-1, INPUT, DOWN);
+ PIN_SLP(gpf2-2, INPUT, DOWN);
+ PIN_SLP(gpf2-3, INPUT, DOWN);
+ PIN_SLP(gpf2-4, INPUT, DOWN);
+ PIN_SLP(gpf2-5, INPUT, DOWN);
+ PIN_SLP(gpf2-6, INPUT, NONE);
+ PIN_SLP(gpf2-7, INPUT, NONE);
+
+ PIN_SLP(gpf3-0, INPUT, NONE);
+ PIN_SLP(gpf3-1, PREV, NONE);
+ PIN_SLP(gpf3-2, PREV, NONE);
+ PIN_SLP(gpf3-3, PREV, NONE);
+ PIN_SLP(gpf3-4, OUT1, NONE);
+ PIN_SLP(gpf3-5, INPUT, DOWN);
+
+ PIN_SLP(gpj0-0, PREV, NONE);
+ PIN_SLP(gpj0-1, PREV, NONE);
+ PIN_SLP(gpj0-2, PREV, NONE);
+ PIN_SLP(gpj0-3, INPUT, DOWN);
+ PIN_SLP(gpj0-4, PREV, NONE);
+ PIN_SLP(gpj0-5, PREV, NONE);
+ PIN_SLP(gpj0-6, INPUT, DOWN);
+ PIN_SLP(gpj0-7, INPUT, DOWN);
+
+ PIN_SLP(gpj1-0, INPUT, DOWN);
+ PIN_SLP(gpj1-1, PREV, NONE);
+ PIN_SLP(gpj1-2, PREV, NONE);
+ PIN_SLP(gpj1-3, INPUT, DOWN);
+ PIN_SLP(gpj1-4, INPUT, DOWN);
+ };
+};
+
+&pinctrl_1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sleep1>;
+
+ sleep1: sleep-states {
+ PIN_SLP(gpk0-0, PREV, NONE);
+ PIN_SLP(gpk0-1, PREV, NONE);
+ PIN_SLP(gpk0-2, OUT0, NONE);
+ PIN_SLP(gpk0-3, PREV, NONE);
+ PIN_SLP(gpk0-4, PREV, NONE);
+ PIN_SLP(gpk0-5, PREV, NONE);
+ PIN_SLP(gpk0-6, PREV, NONE);
+
+ PIN_SLP(gpk1-0, INPUT, DOWN);
+ PIN_SLP(gpk1-1, INPUT, DOWN);
+ PIN_SLP(gpk1-2, INPUT, DOWN);
+ PIN_SLP(gpk1-3, PREV, NONE);
+ PIN_SLP(gpk1-4, PREV, NONE);
+ PIN_SLP(gpk1-5, PREV, NONE);
+ PIN_SLP(gpk1-6, PREV, NONE);
+
+ PIN_SLP(gpk2-0, INPUT, DOWN);
+ PIN_SLP(gpk2-1, INPUT, DOWN);
+ PIN_SLP(gpk2-2, INPUT, DOWN);
+ PIN_SLP(gpk2-3, INPUT, DOWN);
+ PIN_SLP(gpk2-4, INPUT, DOWN);
+ PIN_SLP(gpk2-5, INPUT, DOWN);
+ PIN_SLP(gpk2-6, INPUT, DOWN);
+
+ PIN_SLP(gpk3-0, OUT0, NONE);
+ PIN_SLP(gpk3-1, INPUT, NONE);
+ PIN_SLP(gpk3-2, INPUT, DOWN);
+ PIN_SLP(gpk3-3, INPUT, NONE);
+ PIN_SLP(gpk3-4, INPUT, NONE);
+ PIN_SLP(gpk3-5, INPUT, NONE);
+ PIN_SLP(gpk3-6, INPUT, NONE);
+
+ PIN_SLP(gpl0-0, INPUT, DOWN);
+ PIN_SLP(gpl0-1, INPUT, DOWN);
+ PIN_SLP(gpl0-2, INPUT, DOWN);
+ PIN_SLP(gpl0-3, INPUT, DOWN);
+ PIN_SLP(gpl0-4, PREV, NONE);
+ PIN_SLP(gpl0-6, PREV, NONE);
+
+ PIN_SLP(gpl1-0, INPUT, DOWN);
+ PIN_SLP(gpl1-1, INPUT, DOWN);
+ PIN_SLP(gpl2-0, INPUT, DOWN);
+ PIN_SLP(gpl2-1, INPUT, DOWN);
+ PIN_SLP(gpl2-2, INPUT, DOWN);
+ PIN_SLP(gpl2-3, INPUT, DOWN);
+ PIN_SLP(gpl2-4, INPUT, DOWN);
+ PIN_SLP(gpl2-5, INPUT, DOWN);
+ PIN_SLP(gpl2-6, PREV, NONE);
+ PIN_SLP(gpl2-7, INPUT, DOWN);
+
+ PIN_SLP(gpm0-0, INPUT, DOWN);
+ PIN_SLP(gpm0-1, INPUT, DOWN);
+ PIN_SLP(gpm0-2, INPUT, DOWN);
+ PIN_SLP(gpm0-3, INPUT, DOWN);
+ PIN_SLP(gpm0-4, INPUT, DOWN);
+ PIN_SLP(gpm0-5, INPUT, DOWN);
+ PIN_SLP(gpm0-6, INPUT, DOWN);
+ PIN_SLP(gpm0-7, INPUT, DOWN);
+
+ PIN_SLP(gpm1-0, INPUT, DOWN);
+ PIN_SLP(gpm1-1, INPUT, DOWN);
+ PIN_SLP(gpm1-2, INPUT, NONE);
+ PIN_SLP(gpm1-3, INPUT, NONE);
+ PIN_SLP(gpm1-4, INPUT, NONE);
+ PIN_SLP(gpm1-5, INPUT, NONE);
+ PIN_SLP(gpm1-6, INPUT, DOWN);
+
+ PIN_SLP(gpm2-0, INPUT, NONE);
+ PIN_SLP(gpm2-1, INPUT, NONE);
+ PIN_SLP(gpm2-2, INPUT, DOWN);
+ PIN_SLP(gpm2-3, INPUT, DOWN);
+ PIN_SLP(gpm2-4, INPUT, DOWN);
+
+ PIN_SLP(gpm3-0, PREV, NONE);
+ PIN_SLP(gpm3-1, PREV, NONE);
+ PIN_SLP(gpm3-2, PREV, NONE);
+ PIN_SLP(gpm3-3, OUT1, NONE);
+ PIN_SLP(gpm3-4, INPUT, DOWN);
+ PIN_SLP(gpm3-5, INPUT, DOWN);
+ PIN_SLP(gpm3-6, INPUT, DOWN);
+ PIN_SLP(gpm3-7, INPUT, DOWN);
+
+ PIN_SLP(gpm4-0, INPUT, DOWN);
+ PIN_SLP(gpm4-1, INPUT, DOWN);
+ PIN_SLP(gpm4-2, INPUT, DOWN);
+ PIN_SLP(gpm4-3, INPUT, DOWN);
+ PIN_SLP(gpm4-4, INPUT, DOWN);
+ PIN_SLP(gpm4-5, INPUT, DOWN);
+ PIN_SLP(gpm4-6, INPUT, DOWN);
+ PIN_SLP(gpm4-7, INPUT, DOWN);
+
+ PIN_SLP(gpy0-0, INPUT, DOWN);
+ PIN_SLP(gpy0-1, INPUT, DOWN);
+ PIN_SLP(gpy0-2, INPUT, DOWN);
+ PIN_SLP(gpy0-3, INPUT, DOWN);
+ PIN_SLP(gpy0-4, INPUT, DOWN);
+ PIN_SLP(gpy0-5, INPUT, DOWN);
+
+ PIN_SLP(gpy1-0, INPUT, DOWN);
+ PIN_SLP(gpy1-1, INPUT, DOWN);
+ PIN_SLP(gpy1-2, INPUT, DOWN);
+ PIN_SLP(gpy1-3, INPUT, DOWN);
+
+ PIN_SLP(gpy2-0, PREV, NONE);
+ PIN_SLP(gpy2-1, INPUT, DOWN);
+ PIN_SLP(gpy2-2, INPUT, NONE);
+ PIN_SLP(gpy2-3, INPUT, NONE);
+ PIN_SLP(gpy2-4, INPUT, NONE);
+ PIN_SLP(gpy2-5, INPUT, NONE);
+
+ PIN_SLP(gpy3-0, INPUT, DOWN);
+ PIN_SLP(gpy3-1, INPUT, DOWN);
+ PIN_SLP(gpy3-2, INPUT, DOWN);
+ PIN_SLP(gpy3-3, INPUT, DOWN);
+ PIN_SLP(gpy3-4, INPUT, DOWN);
+ PIN_SLP(gpy3-5, INPUT, DOWN);
+ PIN_SLP(gpy3-6, INPUT, DOWN);
+ PIN_SLP(gpy3-7, INPUT, DOWN);
+
+ PIN_SLP(gpy4-0, INPUT, DOWN);
+ PIN_SLP(gpy4-1, INPUT, DOWN);
+ PIN_SLP(gpy4-2, INPUT, DOWN);
+ PIN_SLP(gpy4-3, INPUT, DOWN);
+ PIN_SLP(gpy4-4, INPUT, DOWN);
+ PIN_SLP(gpy4-5, INPUT, DOWN);
+ PIN_SLP(gpy4-6, INPUT, DOWN);
+ PIN_SLP(gpy4-7, INPUT, DOWN);
+
+ PIN_SLP(gpy5-0, INPUT, DOWN);
+ PIN_SLP(gpy5-1, INPUT, DOWN);
+ PIN_SLP(gpy5-2, INPUT, DOWN);
+ PIN_SLP(gpy5-3, INPUT, DOWN);
+ PIN_SLP(gpy5-4, INPUT, DOWN);
+ PIN_SLP(gpy5-5, INPUT, DOWN);
+ PIN_SLP(gpy5-6, INPUT, DOWN);
+ PIN_SLP(gpy5-7, INPUT, DOWN);
+
+ PIN_SLP(gpy6-0, INPUT, DOWN);
+ PIN_SLP(gpy6-1, INPUT, DOWN);
+ PIN_SLP(gpy6-2, INPUT, DOWN);
+ PIN_SLP(gpy6-3, INPUT, DOWN);
+ PIN_SLP(gpy6-4, INPUT, DOWN);
+ PIN_SLP(gpy6-5, INPUT, DOWN);
+ PIN_SLP(gpy6-6, INPUT, DOWN);
+ PIN_SLP(gpy6-7, INPUT, DOWN);
+ };
+};
+
+&pinctrl_2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sleep2>;
+
+ sleep2: sleep-states {
+ PIN_SLP(gpz-0, INPUT, DOWN);
+ PIN_SLP(gpz-1, INPUT, DOWN);
+ PIN_SLP(gpz-2, INPUT, DOWN);
+ PIN_SLP(gpz-3, INPUT, DOWN);
+ PIN_SLP(gpz-4, INPUT, DOWN);
+ PIN_SLP(gpz-5, INPUT, DOWN);
+ PIN_SLP(gpz-6, INPUT, DOWN);
+ };
+};
+
+&pinctrl_3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sleep3>;
+
+ sleep3: sleep-states {
+ PIN_SLP(gpv0-0, INPUT, DOWN);
+ PIN_SLP(gpv0-1, INPUT, DOWN);
+ PIN_SLP(gpv0-2, INPUT, DOWN);
+ PIN_SLP(gpv0-3, INPUT, DOWN);
+ PIN_SLP(gpv0-4, INPUT, DOWN);
+ PIN_SLP(gpv0-5, INPUT, DOWN);
+ PIN_SLP(gpv0-6, INPUT, DOWN);
+ PIN_SLP(gpv0-7, INPUT, DOWN);
+
+ PIN_SLP(gpv1-0, INPUT, DOWN);
+ PIN_SLP(gpv1-1, INPUT, DOWN);
+ PIN_SLP(gpv1-2, INPUT, DOWN);
+ PIN_SLP(gpv1-3, INPUT, DOWN);
+ PIN_SLP(gpv1-4, INPUT, DOWN);
+ PIN_SLP(gpv1-5, INPUT, DOWN);
+ PIN_SLP(gpv1-6, INPUT, DOWN);
+ PIN_SLP(gpv1-7, INPUT, DOWN);
+
+ PIN_SLP(gpv2-0, INPUT, DOWN);
+ PIN_SLP(gpv2-1, INPUT, DOWN);
+ PIN_SLP(gpv2-2, INPUT, DOWN);
+ PIN_SLP(gpv2-3, INPUT, DOWN);
+ PIN_SLP(gpv2-4, INPUT, DOWN);
+ PIN_SLP(gpv2-5, INPUT, DOWN);
+ PIN_SLP(gpv2-6, INPUT, DOWN);
+ PIN_SLP(gpv2-7, INPUT, DOWN);
+
+ PIN_SLP(gpv3-0, INPUT, DOWN);
+ PIN_SLP(gpv3-1, INPUT, DOWN);
+ PIN_SLP(gpv3-2, INPUT, DOWN);
+ PIN_SLP(gpv3-3, INPUT, DOWN);
+ PIN_SLP(gpv3-4, INPUT, DOWN);
+ PIN_SLP(gpv3-5, INPUT, DOWN);
+ PIN_SLP(gpv3-6, INPUT, DOWN);
+ PIN_SLP(gpv3-7, INPUT, DOWN);
+
+ PIN_SLP(gpv4-0, INPUT, DOWN);
+ };
+};
diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
new file mode 100644
index 000000000..68ad43b39
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412.dtsi
@@ -0,0 +1,72 @@
+/*
+ * Samsung's Exynos4412 SoC device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung's Exynos4412 SoC device nodes are listed in this file. Exynos4412
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * Exynos4412 SoC. As device tree coverage for Exynos4412 increases, additional
+ * nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include "exynos4x12.dtsi"
+
+/ {
+ compatible = "samsung,exynos4412", "samsung,exynos4";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@A00 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0xA00>;
+ cooling-min-level = <13>;
+ cooling-max-level = <7>;
+ #cooling-cells = <2>; /* min followed by max */
+ };
+
+ cpu@A01 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0xA01>;
+ };
+
+ cpu@A02 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0xA02>;
+ };
+
+ cpu@A03 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0xA03>;
+ };
+ };
+
+ combiner: interrupt-controller@10440000 {
+ samsung,combiner-nr = <20>;
+ };
+
+ pmu {
+ interrupts = <2 2>, <3 2>, <18 2>, <19 2>;
+ };
+
+ gic: interrupt-controller@10490000 {
+ cpu-offset = <0x4000>;
+ };
+
+ pmu_system_controller: system-controller@10020000 {
+ compatible = "samsung,exynos4412-pmu", "syscon";
+ };
+};
diff --git a/arch/arm/boot/dts/exynos4415-pinctrl.dtsi b/arch/arm/boot/dts/exynos4415-pinctrl.dtsi
new file mode 100644
index 000000000..75af9c561
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4415-pinctrl.dtsi
@@ -0,0 +1,573 @@
+/*
+ * Samsung's Exynos4415 SoCs pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Samsung's Exynos4415 SoCs pin-mux and pin-config optiosn are listed as device
+ * tree nodes are listed in this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+&pinctrl_0 {
+ gpa0: gpa0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpa1: gpa1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb: gpb {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc0: gpc0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc1: gpc1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd0: gpd0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd1: gpd1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf0: gpf0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf1: gpf1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf2: gpf2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart0_data: uart0-data {
+ samsung,pins = "gpa0-0", "gpa0-1";
+ samsung,pin-function = <0x2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart0_fctl: uart0-fctl {
+ samsung,pins = "gpa0-2", "gpa0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_data: uart1-data {
+ samsung,pins = "gpa0-4", "gpa0-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_fctl: uart1-fctl {
+ samsung,pins = "gpa0-6", "gpa0-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart2_data: uart2-data {
+ samsung,pins = "gpa1-0", "gpa1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart2_fctl: uart2-fctl {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart3_data: uart3-data {
+ samsung,pins = "gpa1-4", "gpa1-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c2_bus: i2c2-bus {
+ samsung,pins = "gpa0-6", "gpa0-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c3_bus: i2c3-bus {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi0_bus: spi0-bus {
+ samsung,pins = "gpb-0", "gpb-2", "gpb-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c4_bus: i2c4-bus {
+ samsung,pins = "gpb-0", "gpb-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi1_bus: spi1-bus {
+ samsung,pins = "gpb-4", "gpb-6", "gpb-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c5_bus: i2c5-bus {
+ samsung,pins = "gpb-2", "gpb-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s1_bus: i2s1-bus {
+ samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+ "gpc0-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s2_bus: i2s2-bus {
+ samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+ "gpc1-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm2_bus: pcm2-bus {
+ samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+ "gpc1-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c6_bus: i2c6-bus {
+ samsung,pins = "gpc1-3", "gpc1-4";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi2_bus: spi2-bus {
+ samsung,pins = "gpc1-1", "gpc1-3", "gpc1-4";
+ samsung,pin-function = <5>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm0_out: pwm0-out {
+ samsung,pins = "gpd0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm1_out: pwm1-out {
+ samsung,pins = "gpd0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm2_out: pwm2-out {
+ samsung,pins = "gpd0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm3_out: pwm3-out {
+ samsung,pins = "gpd0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c7_bus: i2c7-bus {
+ samsung,pins = "gpd0-2", "gpd0-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c0_bus: i2c0-bus {
+ samsung,pins = "gpd1-0", "gpd1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c1_bus: i2c1-bus {
+ samsung,pins = "gpd1-2", "gpd1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_1 {
+ gpk0: gpk0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpk1: gpk1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpk2: gpk2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpk3: gpk3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpl0: gpl0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpm0: gpm0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpm1: gpm1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpm2: gpm2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpm3: gpm3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpm4: gpm4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx0: gpx0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <0 32 0>, <0 33 0>, <0 34 0>, <0 35 0>,
+ <0 36 0>, <0 37 0>, <0 38 0>, <0 39 0>;
+ #interrupt-cells = <2>;
+ };
+
+ gpx1: gpx1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <0 40 0>, <0 41 0>, <0 42 0>, <0 43 0>,
+ <0 44 0>, <0 45 0>, <0 46 0>, <0 47 0>;
+ #interrupt-cells = <2>;
+ };
+
+ gpx2: gpx2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx3: gpx3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ sd0_clk: sd0-clk {
+ samsung,pins = "gpk0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ samsung,pins = "gpk0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cd: sd0-cd {
+ samsung,pins = "gpk0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_rdqs: sd0-rdqs {
+ samsung,pins = "gpk0-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ samsung,pins = "gpk0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ samsung,pins = "gpk0-4", "gpk0-5", "gpk0-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus8: sd0-bus-width8 {
+ samsung,pins = "gpl0-0", "gpl0-1", "gpl0-2", "gpl0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_clk: sd1-clk {
+ samsung,pins = "gpk1-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ samsung,pins = "gpk1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cd: sd1-cd {
+ samsung,pins = "gpk1-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ samsung,pins = "gpk1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ samsung,pins = "gpk1-4", "gpk1-5", "gpk1-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_clk: sd2-clk {
+ samsung,pins = "gpk2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <4>;
+ };
+
+ sd2_cmd: sd2-cmd {
+ samsung,pins = "gpk2-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <4>;
+ };
+
+ sd2_cd: sd2-cd {
+ samsung,pins = "gpk2-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus1: sd2-bus-width1 {
+ samsung,pins = "gpk2-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <4>;
+ };
+
+ sd2_bus4: sd2-bus-width4 {
+ samsung,pins = "gpk2-4", "gpk2-5", "gpk2-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <4>;
+ };
+
+ cam_port_b_io: cam-port-b-io {
+ samsung,pins = "gpm0-0", "gpm0-1", "gpm0-2", "gpm0-3",
+ "gpm0-4", "gpm0-5", "gpm0-6", "gpm0-7",
+ "gpm1-0", "gpm1-1", "gpm2-0", "gpm2-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_port_b_clk_active: cam-port-b-clk-active {
+ samsung,pins = "gpm2-2";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ cam_port_b_clk_idle: cam-port-b-clk-idle {
+ samsung,pins = "gpm2-2";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_i2c0: fimc-is-i2c0 {
+ samsung,pins = "gpm4-0", "gpm4-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_i2c1: fimc-is-i2c1 {
+ samsung,pins = "gpm4-2", "gpm4-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_uart: fimc-is-uart {
+ samsung,pins = "gpm3-5", "gpm3-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_2 {
+ gpz: gpz {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ i2s0_bus: i2s0-bus {
+ samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
+ "gpz-4", "gpz-5", "gpz-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/exynos4415.dtsi b/arch/arm/boot/dts/exynos4415.dtsi
new file mode 100644
index 000000000..5caea996e
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4415.dtsi
@@ -0,0 +1,638 @@
+/*
+ * Samsung's Exynos4415 SoC device tree source
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Samsung's Exynos4415 SoC device nodes are listed in this file. Exynos4415
+ * based board files can include this file and provide values for board
+ * specific bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * Exynos4415 SoC. As device tree coverage for Exynos4415 increases, additional
+ * nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/exynos4415.h>
+#include <dt-bindings/clock/exynos-audss-clk.h>
+
+/ {
+ compatible = "samsung,exynos4415";
+ interrupt-parent = <&gic>;
+
+ aliases {
+ pinctrl0 = &pinctrl_0;
+ pinctrl1 = &pinctrl_1;
+ pinctrl2 = &pinctrl_2;
+ mshc0 = &mshc_0;
+ mshc1 = &mshc_1;
+ mshc2 = &mshc_2;
+ spi0 = &spi_0;
+ spi1 = &spi_1;
+ spi2 = &spi_2;
+ i2c0 = &i2c_0;
+ i2c1 = &i2c_1;
+ i2c2 = &i2c_2;
+ i2c3 = &i2c_3;
+ i2c4 = &i2c_4;
+ i2c5 = &i2c_5;
+ i2c6 = &i2c_6;
+ i2c7 = &i2c_7;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@a00 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0xa00>;
+ clock-frequency = <1600000000>;
+ };
+
+ cpu1: cpu@a01 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0xa01>;
+ clock-frequency = <1600000000>;
+ };
+
+ cpu2: cpu@a02 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0xa02>;
+ clock-frequency = <1600000000>;
+ };
+
+ cpu3: cpu@a03 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0xa03>;
+ clock-frequency = <1600000000>;
+ };
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ sysram@02020000 {
+ compatible = "mmio-sram";
+ reg = <0x02020000 0x50000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x02020000 0x50000>;
+
+ smp-sysram@0 {
+ compatible = "samsung,exynos4210-sysram";
+ reg = <0x0 0x1000>;
+ };
+
+ smp-sysram@4f000 {
+ compatible = "samsung,exynos4210-sysram-ns";
+ reg = <0x4f000 0x1000>;
+ };
+ };
+
+ pinctrl_2: pinctrl@03860000 {
+ compatible = "samsung,exynos4415-pinctrl";
+ reg = <0x03860000 0x1000>;
+ interrupts = <0 242 0>;
+ };
+
+ chipid@10000000 {
+ compatible = "samsung,exynos4210-chipid";
+ reg = <0x10000000 0x100>;
+ };
+
+ sysreg_system_controller: syscon@10010000 {
+ compatible = "samsung,exynos4-sysreg", "syscon";
+ reg = <0x10010000 0x400>;
+ };
+
+ pmu_system_controller: system-controller@10020000 {
+ compatible = "samsung,exynos4415-pmu", "syscon";
+ reg = <0x10020000 0x4000>;
+ };
+
+ mipi_phy: video-phy@10020710 {
+ compatible = "samsung,s5pv210-mipi-video-phy";
+ reg = <0x10020710 8>;
+ #phy-cells = <1>;
+ };
+
+ pd_cam: cam-power-domain@10024000 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10024000 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_tv: tv-power-domain@10024020 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10024020 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_mfc: mfc-power-domain@10024040 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10024040 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_g3d: g3d-power-domain@10024060 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10024060 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_lcd0: lcd0-power-domain@10024080 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10024080 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_isp0: isp0-power-domain@100240A0 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x100240A0 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_isp1: isp1-power-domain@100240E0 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x100240E0 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ cmu: clock-controller@10030000 {
+ compatible = "samsung,exynos4415-cmu";
+ reg = <0x10030000 0x18000>;
+ #clock-cells = <1>;
+ };
+
+ rtc: rtc@10070000 {
+ compatible = "samsung,exynos3250-rtc";
+ reg = <0x10070000 0x100>;
+ interrupts = <0 73 0>, <0 74 0>;
+ status = "disabled";
+ };
+
+ mct@10050000 {
+ compatible = "samsung,exynos4210-mct";
+ reg = <0x10050000 0x800>;
+ interrupts = <0 218 0>, <0 219 0>, <0 220 0>, <0 221 0>,
+ <0 223 0>, <0 226 0>, <0 227 0>, <0 228 0>;
+ clocks = <&cmu CLK_FIN_PLL>, <&cmu CLK_MCT>;
+ clock-names = "fin_pll", "mct";
+ };
+
+ gic: interrupt-controller@10481000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x10481000 0x1000>,
+ <0x10482000 0x1000>,
+ <0x10484000 0x2000>,
+ <0x10486000 0x2000>;
+ interrupts = <1 9 0xf04>;
+ };
+
+ l2c: l2-cache-controller@10502000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x10502000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ arm,tag-latency = <2 2 1>;
+ arm,data-latency = <3 2 1>;
+ arm,double-linefill = <1>;
+ arm,double-linefill-incr = <0>;
+ arm,double-linefill-wrap = <1>;
+ arm,prefetch-drop = <1>;
+ arm,prefetch-offset = <7>;
+ };
+
+ cmu_dmc: clock-controller@105C0000 {
+ compatible = "samsung,exynos4415-cmu-dmc";
+ reg = <0x105C0000 0x3000>;
+ #clock-cells = <1>;
+ };
+
+ pinctrl_1: pinctrl@11000000 {
+ compatible = "samsung,exynos4415-pinctrl";
+ reg = <0x11000000 0x1000>;
+ interrupts = <0 225 0>;
+
+ wakeup-interrupt-controller {
+ compatible = "samsung,exynos4210-wakeup-eint";
+ interrupt-parent = <&gic>;
+ interrupts = <0 48 0>;
+ };
+ };
+
+ pinctrl_0: pinctrl@11400000 {
+ compatible = "samsung,exynos4415-pinctrl";
+ reg = <0x11400000 0x1000>;
+ interrupts = <0 240 0>;
+ };
+
+ fimd: fimd@11C00000 {
+ compatible = "samsung,exynos4415-fimd";
+ reg = <0x11C00000 0x30000>;
+ interrupt-names = "fifo", "vsync", "lcd_sys";
+ interrupts = <0 84 0>, <0 85 0>, <0 86 0>;
+ clocks = <&cmu CLK_SCLK_FIMD0>, <&cmu CLK_FIMD0>;
+ clock-names = "sclk_fimd", "fimd";
+ samsung,power-domain = <&pd_lcd0>;
+ samsung,sysreg = <&sysreg_system_controller>;
+ status = "disabled";
+ };
+
+ dsi_0: dsi@11C80000 {
+ compatible = "samsung,exynos4415-mipi-dsi";
+ reg = <0x11C80000 0x10000>;
+ interrupts = <0 83 0>;
+ samsung,phy-type = <0>;
+ samsung,power-domain = <&pd_lcd0>;
+ phys = <&mipi_phy 1>;
+ phy-names = "dsim";
+ clocks = <&cmu CLK_DSIM0>, <&cmu CLK_SCLK_MIPI0>;
+ clock-names = "bus_clk", "pll_clk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ hsotg: hsotg@12480000 {
+ compatible = "samsung,s3c6400-hsotg";
+ reg = <0x12480000 0x20000>;
+ interrupts = <0 141 0>;
+ clocks = <&cmu CLK_USBDEVICE>;
+ clock-names = "otg";
+ phys = <&exynos_usbphy 0>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ mshc_0: mshc@12510000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ reg = <0x12510000 0x1000>;
+ interrupts = <0 142 0>;
+ clocks = <&cmu CLK_SDMMC0>, <&cmu CLK_SCLK_MMC0>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ mshc_1: mshc@12520000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ reg = <0x12520000 0x1000>;
+ interrupts = <0 143 0>;
+ clocks = <&cmu CLK_SDMMC1>, <&cmu CLK_SCLK_MMC1>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ mshc_2: mshc@12530000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ reg = <0x12530000 0x1000>;
+ interrupts = <0 144 0>;
+ clocks = <&cmu CLK_SDMMC2>, <&cmu CLK_SCLK_MMC2>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ ehci: ehci@12580000 {
+ compatible = "samsung,exynos4210-ehci";
+ reg = <0x12580000 0x100>;
+ interrupts = <0 140 0>;
+ clocks = <&cmu CLK_USBHOST>;
+ clock-names = "usbhost";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ phys = <&exynos_usbphy 1>;
+ status = "disabled";
+ };
+ port@1 {
+ reg = <1>;
+ phys = <&exynos_usbphy 2>;
+ status = "disabled";
+ };
+ port@2 {
+ reg = <2>;
+ phys = <&exynos_usbphy 3>;
+ status = "disabled";
+ };
+ };
+
+ ohci: ohci@12590000 {
+ compatible = "samsung,exynos4210-ohci";
+ reg = <0x12590000 0x100>;
+ interrupts = <0 140 0>;
+ clocks = <&cmu CLK_USBHOST>;
+ clock-names = "usbhost";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ phys = <&exynos_usbphy 1>;
+ status = "disabled";
+ };
+ };
+
+ exynos_usbphy: exynos-usbphy@125B0000 {
+ compatible = "samsung,exynos4x12-usb2-phy";
+ reg = <0x125B0000 0x100>;
+ samsung,pmureg-phandle = <&pmu_system_controller>;
+ samsung,sysreg-phandle = <&sysreg_system_controller>;
+ clocks = <&cmu CLK_USBDEVICE>, <&xusbxti>;
+ clock-names = "phy", "ref";
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&gic>;
+ ranges;
+
+ pdma0: pdma@12680000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x12680000 0x1000>;
+ interrupts = <0 138 0>;
+ clocks = <&cmu CLK_PDMA0>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+
+ pdma1: pdma@12690000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x12690000 0x1000>;
+ interrupts = <0 139 0>;
+ clocks = <&cmu CLK_PDMA1>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+ };
+
+ adc: adc@126C0000 {
+ compatible = "samsung,exynos3250-adc",
+ "samsung,exynos-adc-v2";
+ reg = <0x126C0000 0x100>, <0x10020718 0x4>;
+ interrupts = <0 137 0>;
+ clock-names = "adc", "sclk";
+ clocks = <&cmu CLK_TSADC>, <&cmu CLK_SCLK_TSADC>;
+ #io-channel-cells = <1>;
+ io-channel-ranges;
+ status = "disabled";
+ };
+
+ serial_0: serial@13800000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x13800000 0x100>;
+ interrupts = <0 109 0>;
+ clocks = <&cmu CLK_UART0>, <&cmu CLK_SCLK_UART0>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ serial_1: serial@13810000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x13810000 0x100>;
+ interrupts = <0 110 0>;
+ clocks = <&cmu CLK_UART1>, <&cmu CLK_SCLK_UART1>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ serial_2: serial@13820000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x13820000 0x100>;
+ interrupts = <0 111 0>;
+ clocks = <&cmu CLK_UART2>, <&cmu CLK_SCLK_UART2>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ serial_3: serial@13830000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x13830000 0x100>;
+ interrupts = <0 112 0>;
+ clocks = <&cmu CLK_UART3>, <&cmu CLK_SCLK_UART3>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ i2c_0: i2c@13860000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13860000 0x100>;
+ interrupts = <0 113 0>;
+ clocks = <&cmu CLK_I2C0>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_bus>;
+ status = "disabled";
+ };
+
+ i2c_1: i2c@13870000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13870000 0x100>;
+ interrupts = <0 114 0>;
+ clocks = <&cmu CLK_I2C1>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_bus>;
+ status = "disabled";
+ };
+
+ i2c_2: i2c@13880000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13880000 0x100>;
+ interrupts = <0 115 0>;
+ clocks = <&cmu CLK_I2C2>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_bus>;
+ status = "disabled";
+ };
+
+ i2c_3: i2c@13890000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13890000 0x100>;
+ interrupts = <0 116 0>;
+ clocks = <&cmu CLK_I2C3>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_bus>;
+ status = "disabled";
+ };
+
+ i2c_4: i2c@138A0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x138A0000 0x100>;
+ interrupts = <0 117 0>;
+ clocks = <&cmu CLK_I2C4>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_bus>;
+ status = "disabled";
+ };
+
+ i2c_5: i2c@138B0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x138B0000 0x100>;
+ interrupts = <0 118 0>;
+ clocks = <&cmu CLK_I2C5>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5_bus>;
+ status = "disabled";
+ };
+
+ i2c_6: i2c@138C0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x138C0000 0x100>;
+ interrupts = <0 119 0>;
+ clocks = <&cmu CLK_I2C6>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c6_bus>;
+ status = "disabled";
+ };
+
+ i2c_7: i2c@138D0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x138D0000 0x100>;
+ interrupts = <0 120 0>;
+ clocks = <&cmu CLK_I2C7>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c7_bus>;
+ status = "disabled";
+ };
+
+ spi_0: spi@13920000 {
+ compatible = "samsung,exynos4210-spi";
+ reg = <0x13920000 0x100>;
+ interrupts = <0 121 0>;
+ dmas = <&pdma0 7>, <&pdma0 6>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu CLK_SPI0>, <&cmu CLK_SCLK_SPI0>;
+ clock-names = "spi", "spi_busclk0";
+ samsung,spi-src-clk = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_bus>;
+ status = "disabled";
+ };
+
+ spi_1: spi@13930000 {
+ compatible = "samsung,exynos4210-spi";
+ reg = <0x13930000 0x100>;
+ interrupts = <0 122 0>;
+ dmas = <&pdma1 7>, <&pdma1 6>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu CLK_SPI1>, <&cmu CLK_SCLK_SPI1>;
+ clock-names = "spi", "spi_busclk0";
+ samsung,spi-src-clk = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_bus>;
+ status = "disabled";
+ };
+
+ spi_2: spi@13940000 {
+ compatible = "samsung,exynos4210-spi";
+ reg = <0x13940000 0x100>;
+ interrupts = <0 123 0>;
+ dmas = <&pdma0 9>, <&pdma0 8>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu CLK_SPI2>, <&cmu CLK_SCLK_SPI2>;
+ clock-names = "spi", "spi_busclk0";
+ samsung,spi-src-clk = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_bus>;
+ status = "disabled";
+ };
+
+ clock_audss: clock-controller@03810000 {
+ compatible = "samsung,exynos4210-audss-clock";
+ reg = <0x03810000 0x0C>;
+ #clock-cells = <1>;
+ };
+
+ i2s0: i2s@3830000 {
+ compatible = "samsung,s5pv210-i2s";
+ reg = <0x03830000 0x100>;
+ interrupts = <0 124 0>;
+ clocks = <&clock_audss EXYNOS_I2S_BUS>,
+ <&clock_audss EXYNOS_SCLK_I2S>;
+ clock-names = "iis", "i2s_opclk0";
+ dmas = <&pdma1 10>, <&pdma1 9>, <&pdma1 8>;
+ dma-names = "tx", "rx", "tx-sec";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_bus>;
+ samsung,idma-addr = <0x03000000>;
+ status = "disabled";
+ };
+
+ pwm: pwm@139D0000 {
+ compatible = "samsung,exynos4210-pwm";
+ reg = <0x139D0000 0x1000>;
+ interrupts = <0 104 0>, <0 105 0>, <0 106 0>,
+ <0 107 0>, <0 108 0>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 18 0>, <0 19 0>, <0 20 0>, <0 21 0>;
+ };
+ };
+};
+
+#include "exynos4415-pinctrl.dtsi"
diff --git a/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi b/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
new file mode 100644
index 000000000..c14193137
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
@@ -0,0 +1,972 @@
+/*
+ * Samsung's Exynos4x12 SoCs pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung's Exynos4x12 SoCs pin-mux and pin-config optiosn are listed as device
+ * tree nodes are listed in this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define PIN_PULL_NONE 0
+#define PIN_PULL_DOWN 1
+#define PIN_PULL_UP 3
+
+#define PIN_PDN_OUT0 0
+#define PIN_PDN_OUT1 1
+#define PIN_PDN_INPUT 2
+#define PIN_PDN_PREV 3
+
+#define PIN_SLP(_pin, _mode, _pull) \
+ _pin { \
+ samsung,pins = #_pin; \
+ samsung,pin-con-pdn = <PIN_PDN_ ##_mode>; \
+ samsung,pin-pud-pdn = <PIN_PULL_ ##_pull>; \
+ }
+
+/ {
+ pinctrl@11400000 {
+ gpa0: gpa0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpa1: gpa1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb: gpb {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc0: gpc0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc1: gpc1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd0: gpd0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd1: gpd1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf0: gpf0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf1: gpf1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf2: gpf2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf3: gpf3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpj0: gpj0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpj1: gpj1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart0_data: uart0-data {
+ samsung,pins = "gpa0-0", "gpa0-1";
+ samsung,pin-function = <0x2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart0_fctl: uart0-fctl {
+ samsung,pins = "gpa0-2", "gpa0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_data: uart1-data {
+ samsung,pins = "gpa0-4", "gpa0-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_fctl: uart1-fctl {
+ samsung,pins = "gpa0-6", "gpa0-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c2_bus: i2c2-bus {
+ samsung,pins = "gpa0-6", "gpa0-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart2_data: uart2-data {
+ samsung,pins = "gpa1-0", "gpa1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart2_fctl: uart2-fctl {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart_audio_a: uart-audio-a {
+ samsung,pins = "gpa1-0", "gpa1-1";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c3_bus: i2c3-bus {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart3_data: uart3-data {
+ samsung,pins = "gpa1-4", "gpa1-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart_audio_b: uart-audio-b {
+ samsung,pins = "gpa1-4", "gpa1-5";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi0_bus: spi0-bus {
+ samsung,pins = "gpb-0", "gpb-2", "gpb-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c4_bus: i2c4-bus {
+ samsung,pins = "gpb-0", "gpb-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi1_bus: spi1-bus {
+ samsung,pins = "gpb-4", "gpb-6", "gpb-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c5_bus: i2c5-bus {
+ samsung,pins = "gpb-2", "gpb-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s1_bus: i2s1-bus {
+ samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+ "gpc0-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm1_bus: pcm1-bus {
+ samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+ "gpc0-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ ac97_bus: ac97-bus {
+ samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+ "gpc0-4";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s2_bus: i2s2-bus {
+ samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+ "gpc1-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm2_bus: pcm2-bus {
+ samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+ "gpc1-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ spdif_bus: spdif-bus {
+ samsung,pins = "gpc1-0", "gpc1-1";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c6_bus: i2c6-bus {
+ samsung,pins = "gpc1-3", "gpc1-4";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi2_bus: spi2-bus {
+ samsung,pins = "gpc1-1", "gpc1-3", "gpc1-4";
+ samsung,pin-function = <5>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm0_out: pwm0-out {
+ samsung,pins = "gpd0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm1_out: pwm1-out {
+ samsung,pins = "gpd0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_ctrl: lcd-ctrl {
+ samsung,pins = "gpd0-0", "gpd0-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c7_bus: i2c7-bus {
+ samsung,pins = "gpd0-2", "gpd0-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm2_out: pwm2-out {
+ samsung,pins = "gpd0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm3_out: pwm3-out {
+ samsung,pins = "gpd0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c0_bus: i2c0-bus {
+ samsung,pins = "gpd1-0", "gpd1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ mipi0_clk: mipi0-clk {
+ samsung,pins = "gpd1-0", "gpd1-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c1_bus: i2c1-bus {
+ samsung,pins = "gpd1-2", "gpd1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ mipi1_clk: mipi1-clk {
+ samsung,pins = "gpd1-2", "gpd1-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_clk: lcd-clk {
+ samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_data16: lcd-data-width16 {
+ samsung,pins = "gpf0-7", "gpf1-0", "gpf1-1", "gpf1-2",
+ "gpf1-3", "gpf1-6", "gpf1-7", "gpf2-0",
+ "gpf2-1", "gpf2-2", "gpf2-3", "gpf2-7",
+ "gpf3-0", "gpf3-1", "gpf3-2", "gpf3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_data18: lcd-data-width18 {
+ samsung,pins = "gpf0-6", "gpf0-7", "gpf1-0", "gpf1-1",
+ "gpf1-2", "gpf1-3", "gpf1-6", "gpf1-7",
+ "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
+ "gpf2-6", "gpf2-7", "gpf3-0", "gpf3-1",
+ "gpf3-2", "gpf3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_data24: lcd-data-width24 {
+ samsung,pins = "gpf0-4", "gpf0-5", "gpf0-6", "gpf0-7",
+ "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3",
+ "gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7",
+ "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
+ "gpf2-4", "gpf2-5", "gpf2-6", "gpf2-7",
+ "gpf3-0", "gpf3-1", "gpf3-2", "gpf3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_ldi: lcd-ldi {
+ samsung,pins = "gpf3-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_port_a_io: cam-port-a-io {
+ samsung,pins = "gpj0-0", "gpj0-1", "gpj0-2", "gpj0-3",
+ "gpj0-4", "gpj0-5", "gpj0-6", "gpj0-7",
+ "gpj1-0", "gpj1-1", "gpj1-2", "gpj1-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_port_a_clk_active: cam-port-a-clk-active {
+ samsung,pins = "gpj1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ cam_port_a_clk_idle: cam-port-a-clk-idle {
+ samsung,pins = "gpj1-3";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ pinctrl@11000000 {
+ gpk0: gpk0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpk1: gpk1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpk2: gpk2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpk3: gpk3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpl0: gpl0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpl1: gpl1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpl2: gpl2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpm0: gpm0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpm1: gpm1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpm2: gpm2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpm3: gpm3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpm4: gpm4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpy0: gpy0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy1: gpy1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy2: gpy2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy3: gpy3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy4: gpy4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy5: gpy5 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy6: gpy6 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpx0: gpx0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+ <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
+ #interrupt-cells = <2>;
+ };
+
+ gpx1: gpx1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
+ <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
+ #interrupt-cells = <2>;
+ };
+
+ gpx2: gpx2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx3: gpx3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ sd0_clk: sd0-clk {
+ samsung,pins = "gpk0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ samsung,pins = "gpk0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cd: sd0-cd {
+ samsung,pins = "gpk0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ samsung,pins = "gpk0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus8: sd0-bus-width8 {
+ samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd4_clk: sd4-clk {
+ samsung,pins = "gpk0-0";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd4_cmd: sd4-cmd {
+ samsung,pins = "gpk0-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd4_cd: sd4-cd {
+ samsung,pins = "gpk0-2";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd4_bus1: sd4-bus-width1 {
+ samsung,pins = "gpk0-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd4_bus4: sd4-bus-width4 {
+ samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd4_bus8: sd4-bus-width8 {
+ samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_clk: sd1-clk {
+ samsung,pins = "gpk1-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ samsung,pins = "gpk1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cd: sd1-cd {
+ samsung,pins = "gpk1-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ samsung,pins = "gpk1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_clk: sd2-clk {
+ samsung,pins = "gpk2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cmd: sd2-cmd {
+ samsung,pins = "gpk2-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cd: sd2-cd {
+ samsung,pins = "gpk2-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus1: sd2-bus-width1 {
+ samsung,pins = "gpk2-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus4: sd2-bus-width4 {
+ samsung,pins = "gpk2-3", "gpk2-4", "gpk2-5", "gpk2-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus8: sd2-bus-width8 {
+ samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_clk: sd3-clk {
+ samsung,pins = "gpk3-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_cmd: sd3-cmd {
+ samsung,pins = "gpk3-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_cd: sd3-cd {
+ samsung,pins = "gpk3-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_bus1: sd3-bus-width1 {
+ samsung,pins = "gpk3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_bus4: sd3-bus-width4 {
+ samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ cam_port_b_io: cam-port-b-io {
+ samsung,pins = "gpm0-0", "gpm0-1", "gpm0-2", "gpm0-3",
+ "gpm0-4", "gpm0-5", "gpm0-6", "gpm0-7",
+ "gpm1-0", "gpm1-1", "gpm2-0", "gpm2-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_port_b_clk_active: cam-port-b-clk-active {
+ samsung,pins = "gpm2-2";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ cam_port_b_clk_idle: cam-port-b-clk-idle {
+ samsung,pins = "gpm2-2";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+
+ eint0: ext-int0 {
+ samsung,pins = "gpx0-0";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ eint8: ext-int8 {
+ samsung,pins = "gpx1-0";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ eint15: ext-int15 {
+ samsung,pins = "gpx1-7";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ eint16: ext-int16 {
+ samsung,pins = "gpx2-0";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ eint31: ext-int31 {
+ samsung,pins = "gpx3-7";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_i2c0: fimc-is-i2c0 {
+ samsung,pins = "gpm4-0", "gpm4-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_i2c1: fimc-is-i2c1 {
+ samsung,pins = "gpm4-2", "gpm4-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_uart: fimc-is-uart {
+ samsung,pins = "gpm3-5", "gpm3-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ pinctrl@03860000 {
+ gpz: gpz {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ i2s0_bus: i2s0-bus {
+ samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
+ "gpz-4", "gpz-5", "gpz-6";
+ samsung,pin-function = <0x2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm0_bus: pcm0-bus {
+ samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
+ "gpz-4";
+ samsung,pin-function = <0x3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ pinctrl@106E0000 {
+ gpv0: gpv0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpv1: gpv1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpv2: gpv2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpv3: gpv3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpv4: gpv4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ c2c_bus: c2c-bus {
+ samsung,pins = "gpv0-0", "gpv0-1", "gpv0-2", "gpv0-3",
+ "gpv0-4", "gpv0-5", "gpv0-6", "gpv0-7",
+ "gpv1-0", "gpv1-1", "gpv1-2", "gpv1-3",
+ "gpv1-4", "gpv1-5", "gpv1-6", "gpv1-7",
+ "gpv2-0", "gpv2-1", "gpv2-2", "gpv2-3",
+ "gpv2-4", "gpv2-5", "gpv2-6", "gpv2-7",
+ "gpv3-0", "gpv3-1", "gpv3-2", "gpv3-3",
+ "gpv3-4", "gpv3-5", "gpv3-6", "gpv3-7",
+ "gpv4-0", "gpv4-1";
+ samsung,pin-function = <0x2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
new file mode 100644
index 000000000..6a6abe14f
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -0,0 +1,312 @@
+/*
+ * Samsung's Exynos4x12 SoCs device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung's Exynos4x12 SoCs device nodes are listed in this file. Exynos4x12
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * Exynos4x12 SoC. As device tree coverage for Exynos4x12 increases, additional
+ * nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include "exynos4.dtsi"
+#include "exynos4x12-pinctrl.dtsi"
+#include "exynos4-cpu-thermal.dtsi"
+
+/ {
+ aliases {
+ pinctrl0 = &pinctrl_0;
+ pinctrl1 = &pinctrl_1;
+ pinctrl2 = &pinctrl_2;
+ pinctrl3 = &pinctrl_3;
+ fimc-lite0 = &fimc_lite_0;
+ fimc-lite1 = &fimc_lite_1;
+ mshc0 = &mshc_0;
+ };
+
+ sysram@02020000 {
+ compatible = "mmio-sram";
+ reg = <0x02020000 0x40000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x02020000 0x40000>;
+
+ smp-sysram@0 {
+ compatible = "samsung,exynos4210-sysram";
+ reg = <0x0 0x1000>;
+ };
+
+ smp-sysram@2f000 {
+ compatible = "samsung,exynos4210-sysram-ns";
+ reg = <0x2f000 0x1000>;
+ };
+ };
+
+ pd_isp: isp-power-domain@10023CA0 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10023CA0 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ l2c: l2-cache-controller@10502000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x10502000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ arm,tag-latency = <2 2 1>;
+ arm,data-latency = <3 2 1>;
+ arm,double-linefill = <1>;
+ arm,double-linefill-incr = <0>;
+ arm,double-linefill-wrap = <1>;
+ arm,prefetch-drop = <1>;
+ arm,prefetch-offset = <7>;
+ };
+
+ clock: clock-controller@10030000 {
+ compatible = "samsung,exynos4412-clock";
+ reg = <0x10030000 0x20000>;
+ #clock-cells = <1>;
+ };
+
+ mct@10050000 {
+ compatible = "samsung,exynos4412-mct";
+ reg = <0x10050000 0x800>;
+ interrupt-parent = <&mct_map>;
+ interrupts = <0>, <1>, <2>, <3>, <4>;
+ clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MCT>;
+ clock-names = "fin_pll", "mct";
+
+ mct_map: mct-map {
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = <0 &gic 0 57 0>,
+ <1 &combiner 12 5>,
+ <2 &combiner 12 6>,
+ <3 &combiner 12 7>,
+ <4 &gic 1 12 0>;
+ };
+ };
+
+ combiner: interrupt-controller@10440000 {
+ interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
+ <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
+ <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
+ <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
+ <0 107 0>, <0 108 0>, <0 48 0>, <0 42 0>;
+ };
+
+ pinctrl_0: pinctrl@11400000 {
+ compatible = "samsung,exynos4x12-pinctrl";
+ reg = <0x11400000 0x1000>;
+ interrupts = <0 47 0>;
+ };
+
+ pinctrl_1: pinctrl@11000000 {
+ compatible = "samsung,exynos4x12-pinctrl";
+ reg = <0x11000000 0x1000>;
+ interrupts = <0 46 0>;
+
+ wakup_eint: wakeup-interrupt-controller {
+ compatible = "samsung,exynos4210-wakeup-eint";
+ interrupt-parent = <&gic>;
+ interrupts = <0 32 0>;
+ };
+ };
+
+ adc: adc@126C0000 {
+ compatible = "samsung,exynos-adc-v1";
+ reg = <0x126C0000 0x100>;
+ interrupt-parent = <&combiner>;
+ interrupts = <10 3>;
+ clocks = <&clock CLK_TSADC>;
+ clock-names = "adc";
+ #io-channel-cells = <1>;
+ io-channel-ranges;
+ samsung,syscon-phandle = <&pmu_system_controller>;
+ status = "disabled";
+ };
+
+ pinctrl_2: pinctrl@03860000 {
+ compatible = "samsung,exynos4x12-pinctrl";
+ reg = <0x03860000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <10 0>;
+ };
+
+ pinctrl_3: pinctrl@106E0000 {
+ compatible = "samsung,exynos4x12-pinctrl";
+ reg = <0x106E0000 0x1000>;
+ interrupts = <0 72 0>;
+ };
+
+ pmu_system_controller: system-controller@10020000 {
+ compatible = "samsung,exynos4212-pmu", "syscon";
+ clock-names = "clkout0", "clkout1", "clkout2", "clkout3",
+ "clkout4", "clkout8", "clkout9";
+ clocks = <&clock CLK_OUT_DMC>, <&clock CLK_OUT_TOP>,
+ <&clock CLK_OUT_LEFTBUS>, <&clock CLK_OUT_RIGHTBUS>,
+ <&clock CLK_OUT_CPU>, <&clock CLK_XXTI>,
+ <&clock CLK_XUSBXTI>;
+ #clock-cells = <1>;
+ };
+
+ g2d@10800000 {
+ compatible = "samsung,exynos4212-g2d";
+ reg = <0x10800000 0x1000>;
+ interrupts = <0 89 0>;
+ clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
+ clock-names = "sclk_fimg2d", "fimg2d";
+ status = "disabled";
+ };
+
+ camera {
+ clocks = <&clock CLK_SCLK_CAM0>, <&clock CLK_SCLK_CAM1>,
+ <&clock CLK_PIXELASYNCM0>, <&clock CLK_PIXELASYNCM1>;
+ clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0", "pxl_async1";
+
+ fimc_0: fimc@11800000 {
+ compatible = "samsung,exynos4212-fimc";
+ samsung,pix-limits = <4224 8192 1920 4224>;
+ samsung,mainscaler-ext;
+ samsung,isp-wb;
+ samsung,cam-if;
+ };
+
+ fimc_1: fimc@11810000 {
+ compatible = "samsung,exynos4212-fimc";
+ samsung,pix-limits = <4224 8192 1920 4224>;
+ samsung,mainscaler-ext;
+ samsung,isp-wb;
+ samsung,cam-if;
+ };
+
+ fimc_2: fimc@11820000 {
+ compatible = "samsung,exynos4212-fimc";
+ samsung,pix-limits = <4224 8192 1920 4224>;
+ samsung,mainscaler-ext;
+ samsung,isp-wb;
+ samsung,lcd-wb;
+ samsung,cam-if;
+ };
+
+ fimc_3: fimc@11830000 {
+ compatible = "samsung,exynos4212-fimc";
+ samsung,pix-limits = <1920 8192 1366 1920>;
+ samsung,rotators = <0>;
+ samsung,mainscaler-ext;
+ samsung,isp-wb;
+ samsung,lcd-wb;
+ };
+
+ fimc_lite_0: fimc-lite@12390000 {
+ compatible = "samsung,exynos4212-fimc-lite";
+ reg = <0x12390000 0x1000>;
+ interrupts = <0 105 0>;
+ power-domains = <&pd_isp>;
+ clocks = <&clock CLK_FIMC_LITE0>;
+ clock-names = "flite";
+ status = "disabled";
+ };
+
+ fimc_lite_1: fimc-lite@123A0000 {
+ compatible = "samsung,exynos4212-fimc-lite";
+ reg = <0x123A0000 0x1000>;
+ interrupts = <0 106 0>;
+ power-domains = <&pd_isp>;
+ clocks = <&clock CLK_FIMC_LITE1>;
+ clock-names = "flite";
+ status = "disabled";
+ };
+
+ fimc_is: fimc-is@12000000 {
+ compatible = "samsung,exynos4212-fimc-is", "simple-bus";
+ reg = <0x12000000 0x260000>;
+ interrupts = <0 90 0>, <0 95 0>;
+ power-domains = <&pd_isp>;
+ clocks = <&clock CLK_FIMC_LITE0>,
+ <&clock CLK_FIMC_LITE1>, <&clock CLK_PPMUISPX>,
+ <&clock CLK_PPMUISPMX>,
+ <&clock CLK_MOUT_MPLL_USER_T>,
+ <&clock CLK_FIMC_ISP>, <&clock CLK_FIMC_DRC>,
+ <&clock CLK_FIMC_FD>, <&clock CLK_MCUISP>,
+ <&clock CLK_DIV_ISP0>,<&clock CLK_DIV_ISP1>,
+ <&clock CLK_DIV_MCUISP0>,
+ <&clock CLK_DIV_MCUISP1>,
+ <&clock CLK_UART_ISP_SCLK>,
+ <&clock CLK_ACLK200>, <&clock CLK_DIV_ACLK200>,
+ <&clock CLK_ACLK400_MCUISP>,
+ <&clock CLK_DIV_ACLK400_MCUISP>;
+ clock-names = "lite0", "lite1", "ppmuispx",
+ "ppmuispmx", "mpll", "isp",
+ "drc", "fd", "mcuisp",
+ "ispdiv0", "ispdiv1", "mcuispdiv0",
+ "mcuispdiv1", "uart", "aclk200",
+ "div_aclk200", "aclk400mcuisp",
+ "div_aclk400mcuisp";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ status = "disabled";
+
+ pmu {
+ reg = <0x10020000 0x3000>;
+ };
+
+ i2c1_isp: i2c-isp@12140000 {
+ compatible = "samsung,exynos4212-i2c-isp";
+ reg = <0x12140000 0x100>;
+ clocks = <&clock CLK_I2C1_ISP>;
+ clock-names = "i2c_isp";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+
+ mshc_0: mmc@12550000 {
+ compatible = "samsung,exynos4412-dw-mshc";
+ reg = <0x12550000 0x1000>;
+ interrupts = <0 77 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ fifo-depth = <0x80>;
+ clocks = <&clock CLK_SDMMC4>, <&clock CLK_SCLK_MMC4>;
+ clock-names = "biu", "ciu";
+ status = "disabled";
+ };
+
+ exynos-usbphy@125B0000 {
+ compatible = "samsung,exynos4x12-usb2-phy";
+ samsung,sysreg-phandle = <&sys_reg>;
+ };
+
+ tmu@100C0000 {
+ compatible = "samsung,exynos4412-tmu";
+ interrupt-parent = <&combiner>;
+ interrupts = <2 4>;
+ reg = <0x100C0000 0x100>;
+ clocks = <&clock 383>;
+ clock-names = "tmu_apbif";
+ status = "disabled";
+ };
+
+ hdmi: hdmi@12D00000 {
+ compatible = "samsung,exynos4212-hdmi";
+ };
+
+ mixer: mixer@12C10000 {
+ compatible = "samsung,exynos4212-mixer";
+ clock-names = "mixer", "hdmi", "sclk_hdmi", "vp";
+ clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
+ <&clock CLK_SCLK_HDMI>, <&clock CLK_VP>;
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi
new file mode 100644
index 000000000..a0cc0b6f8
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5.dtsi
@@ -0,0 +1,110 @@
+/*
+ * Samsung's Exynos5 SoC series common device tree source
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung's Exynos5 SoC series device nodes are listed in this file. Particular
+ * SoCs from Exynos5 series can include this file and provide values for SoCs
+ * specfic bindings.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&gic>;
+
+ aliases {
+ serial0 = &serial_0;
+ serial1 = &serial_1;
+ serial2 = &serial_2;
+ serial3 = &serial_3;
+ };
+
+ chipid@10000000 {
+ compatible = "samsung,exynos4210-chipid";
+ reg = <0x10000000 0x100>;
+ };
+
+ combiner: interrupt-controller@10440000 {
+ compatible = "samsung,exynos4210-combiner";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ samsung,combiner-nr = <32>;
+ reg = <0x10440000 0x1000>;
+ interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
+ <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
+ <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
+ <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
+ <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+ <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>,
+ <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
+ <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
+ };
+
+ gic: interrupt-controller@10481000 {
+ compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x10481000 0x1000>,
+ <0x10482000 0x1000>,
+ <0x10484000 0x2000>,
+ <0x10486000 0x2000>;
+ interrupts = <1 9 0xf04>;
+ };
+
+ serial_0: serial@12C00000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x12C00000 0x100>;
+ interrupts = <0 51 0>;
+ };
+
+ serial_1: serial@12C10000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x12C10000 0x100>;
+ interrupts = <0 52 0>;
+ };
+
+ serial_2: serial@12C20000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x12C20000 0x100>;
+ interrupts = <0 53 0>;
+ };
+
+ serial_3: serial@12C30000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x12C30000 0x100>;
+ interrupts = <0 54 0>;
+ };
+
+ rtc@101E0000 {
+ compatible = "samsung,s3c6410-rtc";
+ reg = <0x101E0000 0x100>;
+ interrupts = <0 43 0>, <0 44 0>;
+ status = "disabled";
+ };
+
+ fimd@14400000 {
+ compatible = "samsung,exynos5250-fimd";
+ interrupt-parent = <&combiner>;
+ reg = <0x14400000 0x40000>;
+ interrupt-names = "fifo", "vsync", "lcd_sys";
+ interrupts = <18 4>, <18 5>, <18 6>;
+ samsung,sysreg = <&sysreg_system_controller>;
+ status = "disabled";
+ };
+
+ dp-controller@145B0000 {
+ compatible = "samsung,exynos5-dp";
+ reg = <0x145B0000 0x1000>;
+ interrupts = <10 3>;
+ interrupt-parent = <&combiner>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
new file mode 100644
index 000000000..7e728a1b5
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -0,0 +1,562 @@
+/*
+ * Samsung's Exynos5250 based Arndale board device tree source
+ *
+ * Copyright (c) 2013 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.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/input/input.h>
+#include "exynos5250.dtsi"
+
+/ {
+ model = "Insignal Arndale evaluation board based on EXYNOS5250";
+ compatible = "insignal,arndale", "samsung,exynos5250", "samsung,exynos5";
+
+ memory {
+ reg = <0x40000000 0x80000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttySAC2,115200";
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ menu {
+ label = "SW-TACT2";
+ gpios = <&gpx1 4 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_MENU>;
+ gpio-key,wakeup;
+ };
+
+ home {
+ label = "SW-TACT3";
+ gpios = <&gpx1 5 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOME>;
+ gpio-key,wakeup;
+ };
+
+ up {
+ label = "SW-TACT4";
+ gpios = <&gpx1 6 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_UP>;
+ gpio-key,wakeup;
+ };
+
+ down {
+ label = "SW-TACT5";
+ gpios = <&gpx1 7 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_DOWN>;
+ gpio-key,wakeup;
+ };
+
+ back {
+ label = "SW-TACT6";
+ gpios = <&gpx2 0 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_BACK>;
+ gpio-key,wakeup;
+ };
+
+ wakeup {
+ label = "SW-TACT7";
+ gpios = <&gpx2 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WAKEUP>;
+ gpio-key,wakeup;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ main_dc_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "MAIN_DC";
+ };
+
+ mmc_reg: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "VDD_33ON_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpx1 1 GPIO_ACTIVE_LOW>;
+ enable-active-high;
+ };
+
+ reg_hdmi_en: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "hdmi-en";
+ };
+ };
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ // SMSC USB3503 connected in hardware only mode as a PHY
+ usb_hub: usb-hub {
+ compatible = "smsc,usb3503a";
+
+ reset-gpios = <&gpx3 5 GPIO_ACTIVE_LOW>;
+ connect-gpios = <&gpd1 7 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&dp {
+ status = "okay";
+ samsung,color-space = <0>;
+ samsung,dynamic-range = <0>;
+ samsung,ycbcr-coeff = <0>;
+ samsung,color-depth = <1>;
+ samsung,link-rate = <0x0a>;
+ samsung,lane-count = <4>;
+};
+
+&fimd {
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing0>;
+
+ timing0: timing@0 {
+ /* 2560x1600 DP panel */
+ clock-frequency = <50000>;
+ hactive = <2560>;
+ vactive = <1600>;
+ hfront-porch = <48>;
+ hback-porch = <80>;
+ hsync-len = <32>;
+ vback-porch = <16>;
+ vfront-porch = <8>;
+ vsync-len = <6>;
+ };
+ };
+};
+
+&hdmi {
+ hpd-gpio = <&gpx3 7 GPIO_ACTIVE_LOW>;
+ vdd_osc-supply = <&ldo10_reg>;
+ vdd_pll-supply = <&ldo8_reg>;
+ vdd-supply = <&ldo8_reg>;
+};
+
+&i2c_0 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <20000>;
+ samsung,i2c-slave-addr = <0x66>;
+
+ s5m8767_pmic@66 {
+ compatible = "samsung,s5m8767-pmic";
+ reg = <0x66>;
+ interrupt-parent = <&gpx3>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+
+ vinb1-supply = <&main_dc_reg>;
+ vinb2-supply = <&main_dc_reg>;
+ vinb3-supply = <&main_dc_reg>;
+ vinb4-supply = <&main_dc_reg>;
+ vinb5-supply = <&main_dc_reg>;
+ vinb6-supply = <&main_dc_reg>;
+ vinb7-supply = <&main_dc_reg>;
+ vinb8-supply = <&main_dc_reg>;
+ vinb9-supply = <&main_dc_reg>;
+
+ vinl1-supply = <&buck7_reg>;
+ vinl2-supply = <&buck7_reg>;
+ vinl3-supply = <&buck7_reg>;
+ vinl4-supply = <&main_dc_reg>;
+ vinl5-supply = <&main_dc_reg>;
+ vinl6-supply = <&main_dc_reg>;
+ vinl7-supply = <&main_dc_reg>;
+ vinl8-supply = <&buck8_reg>;
+ vinl9-supply = <&buck8_reg>;
+
+ s5m8767,pmic-buck2-dvs-voltage = <1300000>;
+ s5m8767,pmic-buck3-dvs-voltage = <1100000>;
+ s5m8767,pmic-buck4-dvs-voltage = <1200000>;
+ s5m8767,pmic-buck-dvs-gpios = <&gpd1 0 GPIO_ACTIVE_HIGH>,
+ <&gpd1 1 GPIO_ACTIVE_HIGH>,
+ <&gpd1 2 GPIO_ACTIVE_HIGH>;
+ s5m8767,pmic-buck-ds-gpios = <&gpx2 3 GPIO_ACTIVE_HIGH>,
+ <&gpx2 4 GPIO_ACTIVE_HIGH>,
+ <&gpx2 5 GPIO_ACTIVE_HIGH>;
+
+ regulators {
+ ldo1_reg: LDO1 {
+ regulator-name = "VDD_ALIVE_1.0V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "VDD_28IO_DP_1.35V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "VDD_COMMON1_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "VDD_IOPERI_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>;
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "VDD_EXT_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "VDD_MPLL_1.1V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "VDD_XPLL_1.1V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "VDD_COMMON2_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "VDD_33ON_3.0V";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ op_mode = <1>;
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "VDD_COMMON3_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "VDD_ABB2_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "VDD_USB_3.0V";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "VDDQ_C2C_W_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "VDD18_ABB0_3_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "VDD10_COMMON4_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "VDD18_HSIC_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "VDDQ_MMC2_3_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ ldo18_reg: LDO18 {
+ regulator-name = "VDD_33ON_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ op_mode = <1>;
+ };
+
+ ldo22_reg: LDO22 {
+ regulator-name = "EXT_33_OFF";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ op_mode = <1>;
+ };
+
+ ldo23_reg: LDO23 {
+ regulator-name = "EXT_28_OFF";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ op_mode = <1>;
+ };
+
+ ldo25_reg: LDO25 {
+ regulator-name = "PVDD_LDO25";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ op_mode = <1>;
+ };
+
+ ldo26_reg: LDO26 {
+ regulator-name = "EXT_18_OFF";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ op_mode = <1>;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "vdd_mif";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <912500>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "vdd_int";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "vdd_g3d";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "VDD_MEM_1.35V";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1355000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ buck7_reg: BUCK7 {
+ regulator-name = "PVDD_BUCK7";
+ regulator-always-on;
+ op_mode = <1>;
+ };
+
+ buck8_reg: BUCK8 {
+ regulator-name = "PVDD_BUCK8";
+ regulator-always-on;
+ op_mode = <1>;
+ };
+
+ buck9_reg: BUCK9 {
+ regulator-name = "VDD_33_OFF_EXT1";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3000000>;
+ op_mode = <1>;
+ };
+ };
+ };
+};
+
+&i2c_2 {
+ status = "okay";
+
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+ samsung,i2c-slave-addr = <0x50>;
+
+ hdmiddc@50 {
+ compatible = "samsung,exynos4210-hdmiddc";
+ reg = <0x50>;
+ };
+};
+
+&i2c_3 {
+ status = "okay";
+
+ wm1811a@1a {
+ compatible = "wlf,wm1811";
+ reg = <0x1a>;
+
+ AVDD2-supply = <&main_dc_reg>;
+ CPVDD-supply = <&main_dc_reg>;
+ DBVDD1-supply = <&main_dc_reg>;
+ DBVDD2-supply = <&main_dc_reg>;
+ DBVDD3-supply = <&main_dc_reg>;
+ LDO1VDD-supply = <&main_dc_reg>;
+ SPKVDD1-supply = <&main_dc_reg>;
+ SPKVDD2-supply = <&main_dc_reg>;
+
+ wlf,ldo1ena = <&gpb0 0 GPIO_ACTIVE_HIGH>;
+ wlf,ldo2ena = <&gpb0 1 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&i2c_8 {
+ status = "okay";
+
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+ samsung,i2c-slave-addr = <0x38>;
+
+ hdmiphy@38 {
+ compatible = "samsung,exynos4212-hdmiphy";
+ reg = <0x38>;
+ };
+};
+
+&i2c_9 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <40000>;
+ samsung,i2c-slave-addr = <0x38>;
+
+ sata_phy_i2c:sata-phy@38 {
+ compatible = "samsung,exynos-sataphy-i2c";
+ reg = <0x38>;
+ };
+};
+
+&i2s0 {
+ status = "okay";
+};
+
+&mfc {
+ samsung,mfc-r = <0x43000000 0x800000>;
+ samsung,mfc-l = <0x51000000 0x800000>;
+};
+
+&mmc_0 {
+ status = "okay";
+ num-slots = <1>;
+ broken-cd;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ vmmc-supply = <&mmc_reg>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+};
+
+&mmc_2 {
+ status = "okay";
+ num-slots = <1>;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ vmmc-supply = <&mmc_reg>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+ bus-width = <4>;
+ disable-wp;
+ cap-sd-highspeed;
+};
+
+&rtc {
+ status = "okay";
+};
+
+&sata {
+ status = "okay";
+};
+
+&sata_phy {
+ status = "okay";
+ samsung,exynos-sataphy-i2c-phandle = <&sata_phy_i2c>;
+};
diff --git a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
new file mode 100644
index 000000000..886cfca04
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
@@ -0,0 +1,818 @@
+/*
+ * Samsung's Exynos5250 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung's Exynos5250 SoC pin-mux and pin-config optiosn are listed as device
+ * tree nodes are listed in this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/ {
+ pinctrl@11400000 {
+ gpa0: gpa0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpa1: gpa1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpa2: gpa2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb0: gpb0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb1: gpb1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb2: gpb2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb3: gpb3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc0: gpc0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc1: gpc1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc2: gpc2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc3: gpc3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd0: gpd0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd1: gpd1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpy0: gpy0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy1: gpy1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy2: gpy2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy3: gpy3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy4: gpy4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy5: gpy5 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy6: gpy6 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpc4: gpc4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx0: gpx0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&combiner>;
+ #interrupt-cells = <2>;
+ interrupts = <23 0>, <24 0>, <25 0>, <25 1>,
+ <26 0>, <26 1>, <27 0>, <27 1>;
+ };
+
+ gpx1: gpx1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&combiner>;
+ #interrupt-cells = <2>;
+ interrupts = <28 0>, <28 1>, <29 0>, <29 1>,
+ <30 0>, <30 1>, <31 0>, <31 1>;
+ };
+
+ gpx2: gpx2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx3: gpx3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart0_data: uart0-data {
+ samsung,pins = "gpa0-0", "gpa0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart0_fctl: uart0-fctl {
+ samsung,pins = "gpa0-2", "gpa0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c2_bus: i2c2-bus {
+ samsung,pins = "gpa0-6", "gpa0-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c2_hs_bus: i2c2-hs-bus {
+ samsung,pins = "gpa0-6", "gpa0-7";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart2_data: uart2-data {
+ samsung,pins = "gpa1-0", "gpa1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart2_fctl: uart2-fctl {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c3_bus: i2c3-bus {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c3_hs_bus: i2c3-hs-bus {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart3_data: uart3-data {
+ samsung,pins = "gpa1-4", "gpa1-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi0_bus: spi0-bus {
+ samsung,pins = "gpa2-0", "gpa2-2", "gpa2-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c4_bus: i2c4-bus {
+ samsung,pins = "gpa2-0", "gpa2-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c5_bus: i2c5-bus {
+ samsung,pins = "gpa2-2", "gpa2-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi1_bus: spi1-bus {
+ samsung,pins = "gpa2-4", "gpa2-6", "gpa2-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s1_bus: i2s1-bus {
+ samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
+ "gpb0-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm1_bus: pcm1-bus {
+ samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
+ "gpb0-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ ac97_bus: ac97-bus {
+ samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
+ "gpb0-4";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s2_bus: i2s2-bus {
+ samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3",
+ "gpb1-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm2_bus: pcm2-bus {
+ samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3",
+ "gpb1-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ spdif_bus: spdif-bus {
+ samsung,pins = "gpb1-0", "gpb1-1";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi2_bus: spi2-bus {
+ samsung,pins = "gpb1-1", "gpb1-3", "gpb1-4";
+ samsung,pin-function = <5>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c6_bus: i2c6-bus {
+ samsung,pins = "gpb1-3", "gpb1-4";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm0_out: pwm0-out {
+ samsung,pins = "gpb2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm1_out: pwm1-out {
+ samsung,pins = "gpb2-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm2_out: pwm2-out {
+ samsung,pins = "gpb2-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm3_out: pwm3-out {
+ samsung,pins = "gpb2-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c7_bus: i2c7-bus {
+ samsung,pins = "gpb2-2", "gpb2-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c0_bus: i2c0-bus {
+ samsung,pins = "gpb3-0", "gpb3-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c1_bus: i2c1-bus {
+ samsung,pins = "gpb3-2", "gpb3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c0_hs_bus: i2c0-hs-bus {
+ samsung,pins = "gpb3-0", "gpb3-1";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c1_hs_bus: i2c1-hs-bus {
+ samsung,pins = "gpb3-2", "gpb3-3";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ sd0_clk: sd0-clk {
+ samsung,pins = "gpc0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ samsung,pins = "gpc0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cd: sd0-cd {
+ samsung,pins = "gpc0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ samsung,pins = "gpc0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ samsung,pins = "gpc0-3", "gpc0-4", "gpc0-5", "gpc0-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus8: sd0-bus-width8 {
+ samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_clk: sd1-clk {
+ samsung,pins = "gpc2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ samsung,pins = "gpc2-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cd: sd1-cd {
+ samsung,pins = "gpc2-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ samsung,pins = "gpc2-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ samsung,pins = "gpc2-3", "gpc2-4", "gpc2-5", "gpc2-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_clk: sd2-clk {
+ samsung,pins = "gpc3-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cmd: sd2-cmd {
+ samsung,pins = "gpc3-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cd: sd2-cd {
+ samsung,pins = "gpc3-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus1: sd2-bus-width1 {
+ samsung,pins = "gpc3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus4: sd2-bus-width4 {
+ samsung,pins = "gpc3-3", "gpc3-4", "gpc3-5", "gpc3-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus8: sd2-bus-width8 {
+ samsung,pins = "gpc4-3", "gpc4-4", "gpc4-5", "gpc4-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_clk: sd3-clk {
+ samsung,pins = "gpc4-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_cmd: sd3-cmd {
+ samsung,pins = "gpc4-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_cd: sd3-cd {
+ samsung,pins = "gpc4-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_bus1: sd3-bus-width1 {
+ samsung,pins = "gpc4-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_bus4: sd3-bus-width4 {
+ samsung,pins = "gpc4-3", "gpc4-4", "gpc4-5", "gpc4-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ uart1_data: uart1-data {
+ samsung,pins = "gpd0-0", "gpd0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_fctl: uart1-fctl {
+ samsung,pins = "gpd0-2", "gpd0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ dp_hpd: dp_hpd {
+ samsung,pins = "gpx0-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ pinctrl@13400000 {
+ gpe0: gpe0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpe1: gpe1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf0: gpf0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf1: gpf1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg0: gpg0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg1: gpg1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg2: gpg2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gph0: gph0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gph1: gph1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ cam_gpio_a: cam-gpio-a {
+ samsung,pins = "gpe0-0", "gpe0-1", "gpe0-2", "gpe0-3",
+ "gpe0-4", "gpe0-5", "gpe0-6", "gpe0-7",
+ "gpe1-0", "gpe1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_gpio_b: cam-gpio-b {
+ samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3",
+ "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_i2c2_bus: cam-i2c2-bus {
+ samsung,pins = "gpe0-6", "gpe1-0";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_spi1_bus: cam-spi1-bus {
+ samsung,pins = "gpe0-4", "gpe0-5", "gpf0-2", "gpf0-3";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_i2c1_bus: cam-i2c1-bus {
+ samsung,pins = "gpf0-2", "gpf0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_i2c0_bus: cam-i2c0-bus {
+ samsung,pins = "gpf0-0", "gpf0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_spi0_bus: cam-spi0-bus {
+ samsung,pins = "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_bayrgb_bus: cam-bayrgb-bus {
+ samsung,pins = "gpg0-0", "gpg0-1", "gpg0-2", "gpg0-3",
+ "gpg0-4", "gpg0-5", "gpg0-6", "gpg0-7",
+ "gpg1-0", "gpg1-1", "gpg1-2", "gpg1-3",
+ "gpg1-4", "gpg1-5", "gpg1-6", "gpg1-7",
+ "gpg2-0", "gpg2-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_port_a: cam-port-a {
+ samsung,pins = "gph0-0", "gph0-1", "gph0-2", "gph0-3",
+ "gph1-0", "gph1-1", "gph1-2", "gph1-3",
+ "gph1-4", "gph1-5", "gph1-6", "gph1-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ pinctrl@10d10000 {
+ gpv0: gpv0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpv1: gpv1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpv2: gpv2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpv3: gpv3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpv4: gpv4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ c2c_rxd: c2c-rxd {
+ samsung,pins = "gpv0-0", "gpv0-1", "gpv0-2", "gpv0-3",
+ "gpv0-4", "gpv0-5", "gpv0-6", "gpv0-7",
+ "gpv1-0", "gpv1-1", "gpv1-2", "gpv1-3",
+ "gpv1-4", "gpv1-5", "gpv1-6", "gpv1-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ c2c_txd: c2c-txd {
+ samsung,pins = "gpv2-0", "gpv2-1", "gpv2-2", "gpv2-3",
+ "gpv2-4", "gpv2-5", "gpv2-6", "gpv2-7",
+ "gpv3-0", "gpv3-1", "gpv3-2", "gpv3-3",
+ "gpv3-4", "gpv3-5", "gpv3-6", "gpv3-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ pinctrl@03860000 {
+ gpz: gpz {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ i2s0_bus: i2s0-bus {
+ samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
+ "gpz-4", "gpz-5", "gpz-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
new file mode 100644
index 000000000..bc27cc255
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -0,0 +1,412 @@
+/*
+ * SAMSUNG SMDK5250 board device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "exynos5250.dtsi"
+
+/ {
+ model = "SAMSUNG SMDK5250 board based on EXYNOS5250";
+ compatible = "samsung,smdk5250", "samsung,exynos5250", "samsung,exynos5";
+
+ aliases {
+ };
+
+ memory {
+ reg = <0x40000000 0x80000000>;
+ };
+
+ chosen {
+ bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc";
+ };
+
+ vdd: fixed-regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd-supply";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ dbvdd: fixed-regulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "dbvdd-supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ spkvdd: fixed-regulator@2 {
+ compatible = "regulator-fixed";
+ regulator-name = "spkvdd-supply";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ sound {
+ compatible = "samsung,smdk-wm8994";
+
+ samsung,i2s-controller = <&i2s0>;
+ samsung,audio-codec = <&wm8994>;
+ };
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti";
+ clock-frequency = <24000000>;
+ };
+
+ codec_mclk: codec-mclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <16934000>;
+ };
+ };
+};
+
+&dp {
+ samsung,color-space = <0>;
+ samsung,dynamic-range = <0>;
+ samsung,ycbcr-coeff = <0>;
+ samsung,color-depth = <1>;
+ samsung,link-rate = <0x0a>;
+ samsung,lane-count = <4>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dp_hpd>;
+ status = "okay";
+};
+
+&ehci {
+ samsung,vbus-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
+};
+
+&fimd {
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing0>;
+
+ timing0: timing@0 {
+ /* 1280x800 */
+ clock-frequency = <50000>;
+ hactive = <1280>;
+ vactive = <800>;
+ hfront-porch = <4>;
+ hback-porch = <4>;
+ hsync-len = <4>;
+ vback-porch = <4>;
+ vfront-porch = <4>;
+ vsync-len = <4>;
+ };
+ };
+};
+
+&hdmi {
+ hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
+};
+
+&i2c_0 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <20000>;
+
+ eeprom@50 {
+ compatible = "samsung,s524ad0xd1";
+ reg = <0x50>;
+ };
+
+ max77686@09 {
+ compatible = "maxim,max77686";
+ reg = <0x09>;
+ interrupt-parent = <&gpx3>;
+ interrupts = <2 IRQ_TYPE_NONE>;
+
+ voltage-regulators {
+ ldo1_reg: LDO1 {
+ regulator-name = "P1.0V_LDO_OUT1";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "P1.2V_LDO_OUT2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "P1.8V_LDO_OUT3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "P2.8V_LDO_OUT4";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "P1.8V_LDO_OUT5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "P1.1V_LDO_OUT6";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "P1.1V_LDO_OUT7";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "P1.0V_LDO_OUT8";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "P1.8V_LDO_OUT10";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "P1.8V_LDO_OUT11";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "P3.0V_LDO_OUT12";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "P1.8V_LDO_OUT13";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "P1.8V_LDO_OUT14";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "P1.0V_LDO_OUT15";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "P1.8V_LDO_OUT16";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "vdd_mif";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "vdd_int";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "vdd_g3d";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "P1.8V_BUCK_OUT5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+};
+
+&i2c_1 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <20000>;
+
+ eeprom@51 {
+ compatible = "samsung,s524ad0xd1";
+ reg = <0x51>;
+ };
+
+ wm8994: wm8994@1a {
+ compatible = "wlf,wm8994";
+ reg = <0x1a>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ clocks = <&codec_mclk>;
+ clock-names = "MCLK1";
+
+ AVDD2-supply = <&vdd>;
+ CPVDD-supply = <&vdd>;
+ DBVDD-supply = <&dbvdd>;
+ SPKVDD1-supply = <&spkvdd>;
+ SPKVDD2-supply = <&spkvdd>;
+ };
+};
+
+&i2c_2 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+
+ hdmiddc@50 {
+ compatible = "samsung,exynos4210-hdmiddc";
+ reg = <0x50>;
+ };
+};
+
+&i2c_8 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+
+ hdmiphy@38 {
+ compatible = "samsung,exynos4212-hdmiphy";
+ reg = <0x38>;
+ };
+};
+
+&i2c_9 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <40000>;
+ samsung,i2c-slave-addr = <0x38>;
+
+ sata_phy_i2c: sata-phy@38 {
+ compatible = "samsung,exynos-sataphy-i2c";
+ reg = <0x38>;
+ };
+};
+
+&i2s0 {
+ status = "okay";
+};
+
+&mfc {
+ samsung,mfc-r = <0x43000000 0x800000>;
+ samsung,mfc-l = <0x51000000 0x800000>;
+};
+
+&mmc_0 {
+ status = "okay";
+ num-slots = <1>;
+ broken-cd;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+};
+
+&mmc_2 {
+ status = "okay";
+ num-slots = <1>;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+ bus-width = <4>;
+ disable-wp;
+ cap-sd-highspeed;
+};
+
+&rtc {
+ status = "okay";
+};
+
+&sata {
+ status = "okay";
+};
+
+&sata_phy {
+ status = "okay";
+ samsung,exynos-sataphy-i2c-phandle = <&sata_phy_i2c>;
+};
+
+&spi_1 {
+ status = "okay";
+ cs-gpios = <&gpa2 5 GPIO_ACTIVE_HIGH>;
+
+ w25q80bw@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "w25x80";
+ reg = <0>;
+ spi-max-frequency = <1000000>;
+
+ controller-data {
+ samsung,spi-feedback-delay = <0>;
+ };
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0x0 0x40000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "Kernel";
+ reg = <0x40000 0xc0000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
new file mode 100644
index 000000000..1eca97ee4
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5250-snow.dts
@@ -0,0 +1,703 @@
+/*
+ * Google Snow board device tree source
+ *
+ * Copyright (c) 2012 Google, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/maxim,max77686.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/input/input.h>
+#include "exynos5250.dtsi"
+
+/ {
+ model = "Google Snow";
+ compatible = "google,snow", "samsung,exynos5250", "samsung,exynos5";
+
+ aliases {
+ i2c104 = &i2c_104;
+ };
+
+ memory {
+ reg = <0x40000000 0x80000000>;
+ };
+
+ chosen {
+ bootargs = "console=tty1";
+ stdout-path = "serial3:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&power_key_irq &lid_irq>;
+
+ power {
+ label = "Power";
+ gpios = <&gpx1 3 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ gpio-key,wakeup;
+ };
+
+ lid-switch {
+ label = "Lid";
+ gpios = <&gpx3 5 GPIO_ACTIVE_LOW>;
+ linux,input-type = <5>; /* EV_SW */
+ linux,code = <0>; /* SW_LID */
+ debounce-interval = <1>;
+ gpio-key,wakeup;
+ };
+ };
+
+ vbat: vbat-fixed-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vbat-supply";
+ regulator-boot-on;
+ };
+
+ i2c-arbitrator {
+ compatible = "i2c-arb-gpio-challenge";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c-parent = <&{/i2c@12CA0000}>;
+
+ our-claim-gpio = <&gpf0 3 GPIO_ACTIVE_LOW>;
+ their-claim-gpios = <&gpe0 4 GPIO_ACTIVE_LOW>;
+ slew-delay-us = <10>;
+ wait-retry-us = <3000>;
+ wait-free-us = <50000>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&arb_our_claim &arb_their_claim>;
+
+ /* Use ID 104 as a hint that we're on physical bus 4 */
+ i2c_104: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ battery: sbs-battery@b {
+ compatible = "sbs,sbs-battery";
+ reg = <0xb>;
+ sbs,poll-retry-count = <1>;
+ };
+
+ cros_ec: embedded-controller {
+ compatible = "google,cros-ec-i2c";
+ reg = <0x1e>;
+ interrupts = <6 IRQ_TYPE_NONE>;
+ interrupt-parent = <&gpx1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ec_irq>;
+ wakeup-source;
+ };
+
+ power-regulator {
+ compatible = "ti,tps65090";
+ reg = <0x48>;
+
+ /*
+ * Config irq to disable internal pulls
+ * even though we run in polling mode.
+ */
+ pinctrl-names = "default";
+ pinctrl-0 = <&tps65090_irq>;
+
+ vsys1-supply = <&vbat>;
+ vsys2-supply = <&vbat>;
+ vsys3-supply = <&vbat>;
+ infet1-supply = <&vbat>;
+ infet2-supply = <&vbat>;
+ infet3-supply = <&vbat>;
+ infet4-supply = <&vbat>;
+ infet5-supply = <&vbat>;
+ infet6-supply = <&vbat>;
+ infet7-supply = <&vbat>;
+ vsys-l1-supply = <&vbat>;
+ vsys-l2-supply = <&vbat>;
+
+ regulators {
+ dcdc1 {
+ ti,enable-ext-control;
+ };
+ dcdc2 {
+ ti,enable-ext-control;
+ };
+ dcdc3 {
+ ti,enable-ext-control;
+ };
+ fet1: fet1 {
+ regulator-name = "vcd_led";
+ ti,overcurrent-wait = <3>;
+ };
+ tps65090_fet2: fet2 {
+ regulator-name = "video_mid";
+ regulator-always-on;
+ ti,overcurrent-wait = <3>;
+ };
+ fet3 {
+ regulator-name = "wwan_r";
+ regulator-always-on;
+ ti,overcurrent-wait = <3>;
+ };
+ fet4 {
+ regulator-name = "sdcard";
+ ti,overcurrent-wait = <3>;
+ };
+ fet5 {
+ regulator-name = "camout";
+ regulator-always-on;
+ ti,overcurrent-wait = <3>;
+ };
+ fet6: fet6 {
+ regulator-name = "lcd_vdd";
+ ti,overcurrent-wait = <3>;
+ };
+ tps65090_fet7: fet7 {
+ regulator-name = "video_mid_1a";
+ regulator-always-on;
+ ti,overcurrent-wait = <3>;
+ };
+ ldo1 {
+ };
+ ldo2 {
+ };
+ };
+
+ charger {
+ compatible = "ti,tps65090-charger";
+ };
+ };
+ };
+ };
+
+ i2c@12CD0000 {
+ ptn3460: lvds-bridge@20 {
+ compatible = "nxp,ptn3460";
+ reg = <0x20>;
+ powerdown-gpios = <&gpy2 5 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpx1 5 GPIO_ACTIVE_HIGH>;
+ edid-emulation = <5>;
+
+ ports {
+ port@0 {
+ bridge_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+
+ port@1 {
+ bridge_in: endpoint {
+ remote-endpoint = <&dp_out>;
+ };
+ };
+ };
+ };
+ };
+
+ sound {
+ compatible = "google,snow-audio-max98095";
+
+ samsung,model = "Snow-I2S-MAX98095";
+ samsung,i2s-controller = <&i2s0>;
+ samsung,audio-codec = <&max98095>;
+ };
+
+ usb3_vbus_reg: regulator-usb3 {
+ compatible = "regulator-fixed";
+ regulator-name = "P5.0V_USB3CON";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpx2 7 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb3_vbus_en>;
+ enable-active-high;
+ };
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 0 1000000 0>;
+ brightness-levels = <0 100 500 1000 1500 2000 2500 2800>;
+ default-brightness-level = <7>;
+ enable-gpios = <&gpx3 0 GPIO_ACTIVE_HIGH>;
+ power-supply = <&fet1>;
+ pinctrl-0 = <&pwm0_out>;
+ pinctrl-names = "default";
+ };
+
+ panel: panel {
+ compatible = "auo,b116xw03";
+ power-supply = <&fet6>;
+ backlight = <&backlight>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&bridge_out>;
+ };
+ };
+ };
+
+ mmc3_pwrseq: mmc3_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpx0 2 GPIO_ACTIVE_LOW>, /* WIFI_RSTn */
+ <&gpx0 1 GPIO_ACTIVE_LOW>; /* WIFI_EN */
+ clocks = <&max77686 MAX77686_CLK_PMIC>;
+ clock-names = "ext_clock";
+ };
+};
+
+&dp {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&dp_hpd>;
+ samsung,color-space = <0>;
+ samsung,dynamic-range = <0>;
+ samsung,ycbcr-coeff = <0>;
+ samsung,color-depth = <1>;
+ samsung,link-rate = <0x0a>;
+ samsung,lane-count = <2>;
+ samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
+
+ ports {
+ port@0 {
+ dp_out: endpoint {
+ remote-endpoint = <&bridge_in>;
+ };
+ };
+ };
+};
+
+&ehci {
+ samsung,vbus-gpio = <&gpx1 1 GPIO_ACTIVE_HIGH>;
+};
+
+&fimd {
+ status = "okay";
+ samsung,invert-vclk;
+};
+
+&hdmi {
+ hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_hpd_irq>;
+ phy = <&hdmiphy>;
+ ddc = <&i2c_2>;
+ hdmi-en-supply = <&tps65090_fet7>;
+ vdd-supply = <&ldo8_reg>;
+ vdd_osc-supply = <&ldo10_reg>;
+ vdd_pll-supply = <&ldo8_reg>;
+};
+
+&i2c_0 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <378000>;
+
+ max77686: max77686@09 {
+ compatible = "maxim,max77686";
+ interrupt-parent = <&gpx3>;
+ interrupts = <2 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&max77686_irq>;
+ wakeup-source;
+ reg = <0x09>;
+ #clock-cells = <1>;
+
+ voltage-regulators {
+ ldo1_reg: LDO1 {
+ regulator-name = "P1.0V_LDO_OUT1";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "P1.8V_LDO_OUT2";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "P1.8V_LDO_OUT3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "P1.1V_LDO_OUT7";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "P1.0V_LDO_OUT8";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "P1.8V_LDO_OUT10";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "P3.0V_LDO_OUT12";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "P1.8V_LDO_OUT14";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "P1.0V_LDO_OUT15";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "P1.8V_LDO_OUT16";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "vdd_mif";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "vdd_int";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "vdd_g3d";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "P1.8V_BUCK_OUT5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck6_reg: BUCK6 {
+ regulator-name = "P1.35V_BUCK_OUT6";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+
+ buck7_reg: BUCK7 {
+ regulator-name = "P2.0V_BUCK_OUT7";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-always-on;
+ };
+
+ buck8_reg: BUCK8 {
+ regulator-name = "P2.85V_BUCK_OUT8";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c_1 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <378000>;
+
+ trackpad {
+ reg = <0x67>;
+ compatible = "cypress,cyapa";
+ interrupts = <2 IRQ_TYPE_NONE>;
+ interrupt-parent = <&gpx1>;
+ wakeup-source;
+ };
+};
+
+/*
+ * Disabled pullups since external part has its own pullups and
+ * double-pulling gets us out of spec in some cases.
+ */
+&i2c2_bus {
+ samsung,pin-pud = <0>;
+};
+
+&i2c_2 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+
+ hdmiddc@50 {
+ compatible = "samsung,exynos4210-hdmiddc";
+ reg = <0x50>;
+ };
+};
+
+&i2c_3 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+};
+
+&i2c_4 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+};
+
+&i2c_5 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+};
+
+&i2c_7 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+
+ max98095: codec@11 {
+ compatible = "maxim,max98095";
+ reg = <0x11>;
+ pinctrl-0 = <&max98095_en>;
+ pinctrl-names = "default";
+ };
+};
+
+&i2c_8 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <378000>;
+
+ hdmiphy: hdmiphy@38 {
+ compatible = "samsung,exynos4212-hdmiphy";
+ reg = <0x38>;
+ };
+};
+
+&i2s0 {
+ status = "okay";
+};
+
+&mmc_0 {
+ status = "okay";
+ num-slots = <1>;
+ broken-cd;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus4 &sd0_bus8>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+};
+
+&mmc_2 {
+ status = "okay";
+ num-slots = <1>;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+ bus-width = <4>;
+ wp-gpios = <&gpc2 1 GPIO_ACTIVE_HIGH>;
+ cap-sd-highspeed;
+};
+
+/*
+ * On Snow we've got SIP WiFi and so can keep drive strengths low to
+ * reduce EMI.
+ */
+&mmc_3 {
+ status = "okay";
+ num-slots = <1>;
+ broken-cd;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_bus4 &wifi_en &wifi_rst>;
+ bus-width = <4>;
+ cap-sd-highspeed;
+ mmc-pwrseq = <&mmc3_pwrseq>;
+};
+
+&pinctrl_0 {
+ wifi_en: wifi-en {
+ samsung,pins = "gpx0-1";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ wifi_rst: wifi-rst {
+ samsung,pins = "gpx0-2";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ power_key_irq: power-key-irq {
+ samsung,pins = "gpx1-3";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ ec_irq: ec-irq {
+ samsung,pins = "gpx1-6";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ max98095_en: max98095-en {
+ samsung,pins = "gpx1-7";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ tps65090_irq: tps65090-irq {
+ samsung,pins = "gpx2-6";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ usb3_vbus_en: usb3-vbus-en {
+ samsung,pins = "gpx2-7";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ max77686_irq: max77686-irq {
+ samsung,pins = "gpx3-2";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lid_irq: lid-irq {
+ samsung,pins = "gpx3-5";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ hdmi_hpd_irq: hdmi-hpd-irq {
+ samsung,pins = "gpx3-7";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_1 {
+ arb_their_claim: arb-their-claim {
+ samsung,pins = "gpe0-4";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ arb_our_claim: arb-our-claim {
+ samsung,pins = "gpf0-3";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&rtc {
+ status = "okay";
+ clocks = <&clock CLK_RTC>, <&max77686 MAX77686_CLK_AP>;
+ clock-names = "rtc", "rtc_src";
+};
+
+&sd3_bus4 {
+ samsung,pin-drv = <0>;
+};
+
+&sd3_clk {
+ samsung,pin-drv = <0>;
+};
+
+&sd3_cmd {
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+};
+
+&spi_1 {
+ status = "okay";
+ samsung,spi-src-clk = <0>;
+ num-cs = <1>;
+};
+
+&usbdrd_dwc3 {
+ dr_mode = "host";
+};
+
+&usbdrd_phy {
+ vbus-supply = <&usb3_vbus_reg>;
+};
+
+#include "cros-ec-keyboard.dtsi"
diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
new file mode 100644
index 000000000..d03f9b8d3
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5250-spring.dts
@@ -0,0 +1,559 @@
+/*
+ * Google Spring board device tree source
+ *
+ * Copyright (c) 2013 Google, Inc
+ * Copyright (c) 2014 SUSE LINUX Products 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.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/input/input.h>
+#include "exynos5250.dtsi"
+
+/ {
+ model = "Google Spring";
+ compatible = "google,spring", "samsung,exynos5250", "samsung,exynos5";
+
+ memory {
+ reg = <0x40000000 0x80000000>;
+ };
+
+ chosen {
+ bootargs = "console=tty1";
+ stdout-path = "serial3:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&power_key_irq>, <&lid_irq>;
+
+ power {
+ label = "Power";
+ gpios = <&gpx1 3 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ gpio-key,wakeup;
+ };
+
+ lid-switch {
+ label = "Lid";
+ gpios = <&gpx3 5 GPIO_ACTIVE_LOW>;
+ linux,input-type = <5>; /* EV_SW */
+ linux,code = <0>; /* SW_LID */
+ debounce-interval = <1>;
+ gpio-key,wakeup;
+ };
+ };
+
+ usb-hub {
+ compatible = "smsc,usb3503a";
+ reset-gpios = <&gpe1 0 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsic_reset>;
+ };
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti";
+ clock-frequency = <24000000>;
+ };
+ };
+};
+
+&dp {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&dp_hpd_gpio>;
+ samsung,color-space = <0>;
+ samsung,dynamic-range = <0>;
+ samsung,ycbcr-coeff = <0>;
+ samsung,color-depth = <1>;
+ samsung,link-rate = <0x0a>;
+ samsung,lane-count = <1>;
+ samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
+};
+
+&ehci {
+ samsung,vbus-gpio = <&gpx1 1 GPIO_ACTIVE_HIGH>;
+};
+
+&fimd {
+ status = "okay";
+ samsung,invert-vclk;
+};
+
+&hdmi {
+ hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_hpd_irq>;
+ phy = <&hdmiphy>;
+ ddc = <&i2c_2>;
+ hdmi-en-supply = <&ldo8_reg>;
+ vdd-supply = <&ldo8_reg>;
+ vdd_osc-supply = <&ldo10_reg>;
+ vdd_pll-supply = <&ldo8_reg>;
+};
+
+&i2c_0 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <378000>;
+
+ s5m8767-pmic@66 {
+ compatible = "samsung,s5m8767-pmic";
+ reg = <0x66>;
+ interrupt-parent = <&gpx3>;
+ interrupts = <2 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&s5m8767_irq &s5m8767_dvs &s5m8767_ds>;
+ wakeup-source;
+
+ s5m8767,pmic-buck-dvs-gpios = <&gpd1 0 GPIO_ACTIVE_LOW>, /* DVS1 */
+ <&gpd1 1 GPIO_ACTIVE_LOW>, /* DVS2 */
+ <&gpd1 2 GPIO_ACTIVE_LOW>; /* DVS3 */
+
+ s5m8767,pmic-buck-ds-gpios = <&gpx2 3 GPIO_ACTIVE_LOW>, /* SET1 */
+ <&gpx2 4 GPIO_ACTIVE_LOW>, /* SET2 */
+ <&gpx2 5 GPIO_ACTIVE_LOW>; /* SET3 */
+
+ /*
+ * The following arrays of DVS voltages are not used, since we are
+ * not using GPIOs to control PMIC bucks, but they must be defined
+ * to please the driver.
+ */
+ s5m8767,pmic-buck2-dvs-voltage = <1350000>, <1300000>,
+ <1250000>, <1200000>,
+ <1150000>, <1100000>,
+ <1000000>, <950000>;
+
+ s5m8767,pmic-buck3-dvs-voltage = <1100000>, <1100000>,
+ <1100000>, <1100000>,
+ <1000000>, <1000000>,
+ <1000000>, <1000000>;
+
+ s5m8767,pmic-buck4-dvs-voltage = <1200000>, <1200000>,
+ <1200000>, <1200000>,
+ <1200000>, <1200000>,
+ <1200000>, <1200000>;
+
+ clocks {
+ compatible = "samsung,s5m8767-clk";
+ #clock-cells = <1>;
+ clock-output-names = "en32khz_ap",
+ "en32khz_cp",
+ "en32khz_bt";
+ };
+
+ regulators {
+ ldo4_reg: LDO4 {
+ regulator-name = "P1.0V_LDO_OUT4";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ op_mode = <0>;
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "P1.0V_LDO_OUT5";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ op_mode = <0>;
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "vdd_mydp";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ op_mode = <3>;
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "P1.1V_LDO_OUT7";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ op_mode = <3>;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "P1.0V_LDO_OUT8";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ op_mode = <3>;
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "P1.8V_LDO_OUT10";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <3>;
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "P1.8V_LDO_OUT11";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <0>;
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "P3.0V_LDO_OUT12";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ op_mode = <3>;
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "P1.8V_LDO_OUT13";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <0>;
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "P1.8V_LDO_OUT14";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <3>;
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "P1.0V_LDO_OUT15";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ op_mode = <3>;
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "P1.8V_LDO_OUT16";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <3>;
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "P2.8V_LDO_OUT17";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ op_mode = <0>;
+ };
+
+ ldo25_reg: LDO25 {
+ regulator-name = "vdd_bridge";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ op_mode = <1>;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "vdd_mif";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <3>;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <3>;
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "vdd_int";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <3>;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "vdd_g3d";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ op_mode = <3>;
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "P1.8V_BUCK_OUT5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>;
+ };
+
+ buck6_reg: BUCK6 {
+ regulator-name = "P1.2V_BUCK_OUT6";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <0>;
+ };
+
+ buck9_reg: BUCK9 {
+ regulator-name = "vdd_ummc";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <3>;
+ };
+ };
+ };
+};
+
+&i2c_1 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <378000>;
+
+ trackpad@4b {
+ compatible = "atmel,maxtouch";
+ reg = <0x4b>;
+ interrupt-parent = <&gpx1>;
+ interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&trackpad_irq>;
+ linux,gpio-keymap = <KEY_RESERVED
+ KEY_RESERVED
+ KEY_RESERVED
+ KEY_RESERVED
+ KEY_RESERVED
+ BTN_LEFT>;
+ wakeup-source;
+ };
+};
+
+/*
+ * Disabled pullups since external part has its own pullups and
+ * double-pulling gets us out of spec in some cases.
+ */
+&i2c2_bus {
+ samsung,pin-pud = <0>;
+};
+
+&i2c_2 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+
+ hdmiddc@50 {
+ compatible = "samsung,exynos4210-hdmiddc";
+ reg = <0x50>;
+ };
+};
+
+&i2c_3 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+};
+
+&i2c_4 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+
+ cros_ec: embedded-controller {
+ compatible = "google,cros-ec-i2c";
+ reg = <0x1e>;
+ interrupts = <6 IRQ_TYPE_NONE>;
+ interrupt-parent = <&gpx1>;
+ wakeup-source;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ec_irq>;
+ };
+};
+
+&i2c_5 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+};
+
+&i2c_7 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+
+ temperature-sensor@4c {
+ compatible = "gmt,g781";
+ reg = <0x4c>;
+ };
+};
+
+&i2c_8 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <378000>;
+
+ hdmiphy: hdmiphy@38 {
+ compatible = "samsung,exynos4212-hdmiphy";
+ reg = <0x38>;
+ };
+};
+
+&i2s0 {
+ status = "okay";
+};
+
+&mfc {
+ samsung,mfc-r = <0x43000000 0x800000>;
+ samsung,mfc-l = <0x51000000 0x800000>;
+};
+
+&mmc_0 {
+ status = "okay";
+ num-slots = <1>;
+ broken-cd;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus4 &sd0_bus8>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+};
+
+/*
+ * On Spring we've got SIP WiFi and so can keep drive strengths low to
+ * reduce EMI.
+ */
+&mmc_1 {
+ status = "okay";
+ num-slots = <1>;
+ broken-cd;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_cd &sd1_bus4>;
+ bus-width = <4>;
+ cap-sd-highspeed;
+};
+
+&pinctrl_0 {
+ s5m8767_dvs: s5m8767-dvs {
+ samsung,pins = "gpd1-0", "gpd1-1", "gpd1-2";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+
+ dp_hpd_gpio: dp-hpd-gpio {
+ samsung,pins = "gpc3-0";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ trackpad_irq: trackpad-irq {
+ samsung,pins = "gpx1-2";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ power_key_irq: power-key-irq {
+ samsung,pins = "gpx1-3";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ ec_irq: ec-irq {
+ samsung,pins = "gpx1-6";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ s5m8767_ds: s5m8767-ds {
+ samsung,pins = "gpx2-3", "gpx2-4", "gpx2-5";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+
+ s5m8767_irq: s5m8767-irq {
+ samsung,pins = "gpx3-2";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lid_irq: lid-irq {
+ samsung,pins = "gpx3-5";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ hdmi_hpd_irq: hdmi-hpd-irq {
+ samsung,pins = "gpx3-7";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_1 {
+ hsic_reset: hsic-reset {
+ samsung,pins = "gpe1-0";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&sd1_bus4 {
+ samsung,pin-drv = <0>;
+};
+
+&sd1_cd {
+ samsung,pin-drv = <0>;
+};
+
+&sd1_clk {
+ samsung,pin-drv = <0>;
+};
+
+&sd1_cmd {
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+};
+
+&spi_1 {
+ status = "okay";
+ samsung,spi-src-clk = <0>;
+ num-cs = <1>;
+};
+
+#include "cros-ec-keyboard.dtsi"
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
new file mode 100644
index 000000000..257e2f105
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -0,0 +1,814 @@
+/*
+ * SAMSUNG EXYNOS5250 SoC device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * SAMSUNG EXYNOS5250 SoC device nodes are listed in this file.
+ * EXYNOS5250 based board files can include this file and provide
+ * values for board specfic bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * EXYNOS5250 SoC. As device tree coverage for EXYNOS5250 increases,
+ * additional nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <dt-bindings/clock/exynos5250.h>
+#include "exynos5.dtsi"
+#include "exynos5250-pinctrl.dtsi"
+#include "exynos4-cpu-thermal.dtsi"
+#include <dt-bindings/clock/exynos-audss-clk.h>
+
+/ {
+ compatible = "samsung,exynos5250", "samsung,exynos5";
+
+ aliases {
+ spi0 = &spi_0;
+ spi1 = &spi_1;
+ spi2 = &spi_2;
+ gsc0 = &gsc_0;
+ gsc1 = &gsc_1;
+ gsc2 = &gsc_2;
+ gsc3 = &gsc_3;
+ mshc0 = &mmc_0;
+ mshc1 = &mmc_1;
+ mshc2 = &mmc_2;
+ mshc3 = &mmc_3;
+ i2c0 = &i2c_0;
+ i2c1 = &i2c_1;
+ i2c2 = &i2c_2;
+ i2c3 = &i2c_3;
+ i2c4 = &i2c_4;
+ i2c5 = &i2c_5;
+ i2c6 = &i2c_6;
+ i2c7 = &i2c_7;
+ i2c8 = &i2c_8;
+ i2c9 = &i2c_9;
+ pinctrl0 = &pinctrl_0;
+ pinctrl1 = &pinctrl_1;
+ pinctrl2 = &pinctrl_2;
+ pinctrl3 = &pinctrl_3;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0>;
+ clock-frequency = <1700000000>;
+ cooling-min-level = <15>;
+ cooling-max-level = <9>;
+ #cooling-cells = <2>; /* min followed by max */
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <1>;
+ clock-frequency = <1700000000>;
+ };
+ };
+
+ sysram@02020000 {
+ compatible = "mmio-sram";
+ reg = <0x02020000 0x30000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x02020000 0x30000>;
+
+ smp-sysram@0 {
+ compatible = "samsung,exynos4210-sysram";
+ reg = <0x0 0x1000>;
+ };
+
+ smp-sysram@2f000 {
+ compatible = "samsung,exynos4210-sysram-ns";
+ reg = <0x2f000 0x1000>;
+ };
+ };
+
+ pd_gsc: gsc-power-domain@10044000 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10044000 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_mfc: mfc-power-domain@10044040 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10044040 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_disp1: disp1-power-domain@100440A0 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x100440A0 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ clock: clock-controller@10010000 {
+ compatible = "samsung,exynos5250-clock";
+ reg = <0x10010000 0x30000>;
+ #clock-cells = <1>;
+ };
+
+ clock_audss: audss-clock-controller@3810000 {
+ compatible = "samsung,exynos5250-audss-clock";
+ reg = <0x03810000 0x0C>;
+ #clock-cells = <1>;
+ clocks = <&clock CLK_FIN_PLL>, <&clock CLK_FOUT_EPLL>,
+ <&clock CLK_SCLK_AUDIO0>, <&clock CLK_DIV_PCM0>;
+ clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in";
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <1 13 0xf08>,
+ <1 14 0xf08>,
+ <1 11 0xf08>,
+ <1 10 0xf08>;
+ /* Unfortunately we need this since some versions of U-Boot
+ * on Exynos don't set the CNTFRQ register, so we need the
+ * value from DT.
+ */
+ clock-frequency = <24000000>;
+ };
+
+ mct@101C0000 {
+ compatible = "samsung,exynos4210-mct";
+ reg = <0x101C0000 0x800>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&mct_map>;
+ interrupts = <0 0>, <1 0>, <2 0>, <3 0>,
+ <4 0>, <5 0>;
+ clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MCT>;
+ clock-names = "fin_pll", "mct";
+
+ mct_map: mct-map {
+ #interrupt-cells = <2>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = <0x0 0 &combiner 23 3>,
+ <0x1 0 &combiner 23 4>,
+ <0x2 0 &combiner 25 2>,
+ <0x3 0 &combiner 25 3>,
+ <0x4 0 &gic 0 120 0>,
+ <0x5 0 &gic 0 121 0>;
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a15-pmu";
+ interrupt-parent = <&combiner>;
+ interrupts = <1 2>, <22 4>;
+ };
+
+ pinctrl_0: pinctrl@11400000 {
+ compatible = "samsung,exynos5250-pinctrl";
+ reg = <0x11400000 0x1000>;
+ interrupts = <0 46 0>;
+
+ wakup_eint: wakeup-interrupt-controller {
+ compatible = "samsung,exynos4210-wakeup-eint";
+ interrupt-parent = <&gic>;
+ interrupts = <0 32 0>;
+ };
+ };
+
+ pinctrl_1: pinctrl@13400000 {
+ compatible = "samsung,exynos5250-pinctrl";
+ reg = <0x13400000 0x1000>;
+ interrupts = <0 45 0>;
+ };
+
+ pinctrl_2: pinctrl@10d10000 {
+ compatible = "samsung,exynos5250-pinctrl";
+ reg = <0x10d10000 0x1000>;
+ interrupts = <0 50 0>;
+ };
+
+ pinctrl_3: pinctrl@03860000 {
+ compatible = "samsung,exynos5250-pinctrl";
+ reg = <0x03860000 0x1000>;
+ interrupts = <0 47 0>;
+ };
+
+ pmu_system_controller: system-controller@10040000 {
+ compatible = "samsung,exynos5250-pmu", "syscon";
+ reg = <0x10040000 0x5000>;
+ clock-names = "clkout16";
+ clocks = <&clock CLK_FIN_PLL>;
+ #clock-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ };
+
+ sysreg_system_controller: syscon@10050000 {
+ compatible = "samsung,exynos5-sysreg", "syscon";
+ reg = <0x10050000 0x5000>;
+ };
+
+ watchdog@101D0000 {
+ compatible = "samsung,exynos5250-wdt";
+ reg = <0x101D0000 0x100>;
+ interrupts = <0 42 0>;
+ clocks = <&clock CLK_WDT>;
+ clock-names = "watchdog";
+ samsung,syscon-phandle = <&pmu_system_controller>;
+ };
+
+ g2d@10850000 {
+ compatible = "samsung,exynos5250-g2d";
+ reg = <0x10850000 0x1000>;
+ interrupts = <0 91 0>;
+ clocks = <&clock CLK_G2D>;
+ clock-names = "fimg2d";
+ };
+
+ mfc: codec@11000000 {
+ compatible = "samsung,mfc-v6";
+ reg = <0x11000000 0x10000>;
+ interrupts = <0 96 0>;
+ power-domains = <&pd_mfc>;
+ clocks = <&clock CLK_MFC>;
+ clock-names = "mfc";
+ };
+
+ rtc: rtc@101E0000 {
+ clocks = <&clock CLK_RTC>;
+ clock-names = "rtc";
+ interrupt-parent = <&pmu_system_controller>;
+ status = "disabled";
+ };
+
+ tmu: tmu@10060000 {
+ compatible = "samsung,exynos5250-tmu";
+ reg = <0x10060000 0x100>;
+ interrupts = <0 65 0>;
+ clocks = <&clock CLK_TMU>;
+ clock-names = "tmu_apbif";
+ #include "exynos4412-tmu-sensor-conf.dtsi"
+ };
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tmu 0>;
+
+ cooling-maps {
+ map0 {
+ /* Corresponds to 800MHz at freq_table */
+ cooling-device = <&cpu0 9 9>;
+ };
+ map1 {
+ /* Corresponds to 200MHz at freq_table */
+ cooling-device = <&cpu0 15 15>;
+ };
+ };
+ };
+ };
+
+ serial@12C00000 {
+ clocks = <&clock CLK_UART0>, <&clock CLK_SCLK_UART0>;
+ clock-names = "uart", "clk_uart_baud0";
+ };
+
+ serial@12C10000 {
+ clocks = <&clock CLK_UART1>, <&clock CLK_SCLK_UART1>;
+ clock-names = "uart", "clk_uart_baud0";
+ };
+
+ serial@12C20000 {
+ clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
+ clock-names = "uart", "clk_uart_baud0";
+ };
+
+ serial@12C30000 {
+ clocks = <&clock CLK_UART3>, <&clock CLK_SCLK_UART3>;
+ clock-names = "uart", "clk_uart_baud0";
+ };
+
+ sata: sata@122F0000 {
+ compatible = "snps,dwc-ahci";
+ samsung,sata-freq = <66>;
+ reg = <0x122F0000 0x1ff>;
+ interrupts = <0 115 0>;
+ clocks = <&clock CLK_SATA>, <&clock CLK_SCLK_SATA>;
+ clock-names = "sata", "sclk_sata";
+ phys = <&sata_phy>;
+ phy-names = "sata-phy";
+ status = "disabled";
+ };
+
+ sata_phy: sata-phy@12170000 {
+ compatible = "samsung,exynos5250-sata-phy";
+ reg = <0x12170000 0x1ff>;
+ clocks = <&clock CLK_SATA_PHYCTRL>;
+ clock-names = "sata_phyctrl";
+ #phy-cells = <0>;
+ samsung,syscon-phandle = <&pmu_system_controller>;
+ status = "disabled";
+ };
+
+ i2c_0: i2c@12C60000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x12C60000 0x100>;
+ interrupts = <0 56 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_I2C0>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_bus>;
+ samsung,sysreg-phandle = <&sysreg_system_controller>;
+ status = "disabled";
+ };
+
+ i2c_1: i2c@12C70000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x12C70000 0x100>;
+ interrupts = <0 57 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_I2C1>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_bus>;
+ samsung,sysreg-phandle = <&sysreg_system_controller>;
+ status = "disabled";
+ };
+
+ i2c_2: i2c@12C80000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x12C80000 0x100>;
+ interrupts = <0 58 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_I2C2>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_bus>;
+ samsung,sysreg-phandle = <&sysreg_system_controller>;
+ status = "disabled";
+ };
+
+ i2c_3: i2c@12C90000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x12C90000 0x100>;
+ interrupts = <0 59 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_I2C3>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_bus>;
+ samsung,sysreg-phandle = <&sysreg_system_controller>;
+ status = "disabled";
+ };
+
+ i2c_4: i2c@12CA0000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x12CA0000 0x100>;
+ interrupts = <0 60 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_I2C4>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_bus>;
+ status = "disabled";
+ };
+
+ i2c_5: i2c@12CB0000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x12CB0000 0x100>;
+ interrupts = <0 61 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_I2C5>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5_bus>;
+ status = "disabled";
+ };
+
+ i2c_6: i2c@12CC0000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x12CC0000 0x100>;
+ interrupts = <0 62 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_I2C6>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c6_bus>;
+ status = "disabled";
+ };
+
+ i2c_7: i2c@12CD0000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x12CD0000 0x100>;
+ interrupts = <0 63 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_I2C7>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c7_bus>;
+ status = "disabled";
+ };
+
+ i2c_8: i2c@12CE0000 {
+ compatible = "samsung,s3c2440-hdmiphy-i2c";
+ reg = <0x12CE0000 0x1000>;
+ interrupts = <0 64 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_I2C_HDMI>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+
+ i2c_9: i2c@121D0000 {
+ compatible = "samsung,exynos5-sata-phy-i2c";
+ reg = <0x121D0000 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_SATA_PHYI2C>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+
+ spi_0: spi@12d20000 {
+ compatible = "samsung,exynos4210-spi";
+ status = "disabled";
+ reg = <0x12d20000 0x100>;
+ interrupts = <0 66 0>;
+ dmas = <&pdma0 5
+ &pdma0 4>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_SPI0>, <&clock CLK_SCLK_SPI0>;
+ clock-names = "spi", "spi_busclk0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_bus>;
+ };
+
+ spi_1: spi@12d30000 {
+ compatible = "samsung,exynos4210-spi";
+ status = "disabled";
+ reg = <0x12d30000 0x100>;
+ interrupts = <0 67 0>;
+ dmas = <&pdma1 5
+ &pdma1 4>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_SPI1>, <&clock CLK_SCLK_SPI1>;
+ clock-names = "spi", "spi_busclk0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_bus>;
+ };
+
+ spi_2: spi@12d40000 {
+ compatible = "samsung,exynos4210-spi";
+ status = "disabled";
+ reg = <0x12d40000 0x100>;
+ interrupts = <0 68 0>;
+ dmas = <&pdma0 7
+ &pdma0 6>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_SPI2>, <&clock CLK_SCLK_SPI2>;
+ clock-names = "spi", "spi_busclk0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_bus>;
+ };
+
+ mmc_0: mmc@12200000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ interrupts = <0 75 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x12200000 0x1000>;
+ clocks = <&clock CLK_SDMMC0>, <&clock CLK_SCLK_MMC0>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x80>;
+ status = "disabled";
+ };
+
+ mmc_1: mmc@12210000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ interrupts = <0 76 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x12210000 0x1000>;
+ clocks = <&clock CLK_SDMMC1>, <&clock CLK_SCLK_MMC1>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x80>;
+ status = "disabled";
+ };
+
+ mmc_2: mmc@12220000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ interrupts = <0 77 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x12220000 0x1000>;
+ clocks = <&clock CLK_SDMMC2>, <&clock CLK_SCLK_MMC2>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x80>;
+ status = "disabled";
+ };
+
+ mmc_3: mmc@12230000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ reg = <0x12230000 0x1000>;
+ interrupts = <0 78 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_SDMMC3>, <&clock CLK_SCLK_MMC3>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x80>;
+ status = "disabled";
+ };
+
+ i2s0: i2s@03830000 {
+ compatible = "samsung,s5pv210-i2s";
+ status = "disabled";
+ reg = <0x03830000 0x100>;
+ dmas = <&pdma0 10
+ &pdma0 9
+ &pdma0 8>;
+ dma-names = "tx", "rx", "tx-sec";
+ clocks = <&clock_audss EXYNOS_I2S_BUS>,
+ <&clock_audss EXYNOS_I2S_BUS>,
+ <&clock_audss EXYNOS_SCLK_I2S>;
+ clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
+ samsung,idma-addr = <0x03000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_bus>;
+ };
+
+ i2s1: i2s@12D60000 {
+ compatible = "samsung,s3c6410-i2s";
+ status = "disabled";
+ reg = <0x12D60000 0x100>;
+ dmas = <&pdma1 12
+ &pdma1 11>;
+ dma-names = "tx", "rx";
+ clocks = <&clock CLK_I2S1>, <&clock CLK_DIV_I2S1>;
+ clock-names = "iis", "i2s_opclk0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s1_bus>;
+ };
+
+ i2s2: i2s@12D70000 {
+ compatible = "samsung,s3c6410-i2s";
+ status = "disabled";
+ reg = <0x12D70000 0x100>;
+ dmas = <&pdma0 12
+ &pdma0 11>;
+ dma-names = "tx", "rx";
+ clocks = <&clock CLK_I2S2>, <&clock CLK_DIV_I2S2>;
+ clock-names = "iis", "i2s_opclk0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s2_bus>;
+ };
+
+ usb@12000000 {
+ compatible = "samsung,exynos5250-dwusb3";
+ clocks = <&clock CLK_USB3>;
+ clock-names = "usbdrd30";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ usbdrd_dwc3: dwc3 {
+ compatible = "synopsys,dwc3";
+ reg = <0x12000000 0x10000>;
+ interrupts = <0 72 0>;
+ phys = <&usbdrd_phy 0>, <&usbdrd_phy 1>;
+ phy-names = "usb2-phy", "usb3-phy";
+ };
+ };
+
+ usbdrd_phy: phy@12100000 {
+ compatible = "samsung,exynos5250-usbdrd-phy";
+ reg = <0x12100000 0x100>;
+ clocks = <&clock CLK_USB3>, <&clock CLK_FIN_PLL>;
+ clock-names = "phy", "ref";
+ samsung,pmu-syscon = <&pmu_system_controller>;
+ #phy-cells = <1>;
+ };
+
+ ehci: usb@12110000 {
+ compatible = "samsung,exynos4210-ehci";
+ reg = <0x12110000 0x100>;
+ interrupts = <0 71 0>;
+
+ clocks = <&clock CLK_USB2>;
+ clock-names = "usbhost";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ phys = <&usb2_phy_gen 1>;
+ };
+ };
+
+ ohci: usb@12120000 {
+ compatible = "samsung,exynos4210-ohci";
+ reg = <0x12120000 0x100>;
+ interrupts = <0 71 0>;
+
+ clocks = <&clock CLK_USB2>;
+ clock-names = "usbhost";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ phys = <&usb2_phy_gen 1>;
+ };
+ };
+
+ usb2_phy_gen: phy@12130000 {
+ compatible = "samsung,exynos5250-usb2-phy";
+ reg = <0x12130000 0x100>;
+ clocks = <&clock CLK_USB2>, <&clock CLK_FIN_PLL>;
+ clock-names = "phy", "ref";
+ #phy-cells = <1>;
+ samsung,sysreg-phandle = <&sysreg_system_controller>;
+ samsung,pmureg-phandle = <&pmu_system_controller>;
+ };
+
+ pwm: pwm@12dd0000 {
+ compatible = "samsung,exynos4210-pwm";
+ reg = <0x12dd0000 0x100>;
+ samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+ #pwm-cells = <3>;
+ clocks = <&clock CLK_PWM>;
+ clock-names = "timers";
+ };
+
+ amba {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "arm,amba-bus";
+ interrupt-parent = <&gic>;
+ ranges;
+
+ pdma0: pdma@121A0000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x121A0000 0x1000>;
+ interrupts = <0 34 0>;
+ clocks = <&clock CLK_PDMA0>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+
+ pdma1: pdma@121B0000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x121B0000 0x1000>;
+ interrupts = <0 35 0>;
+ clocks = <&clock CLK_PDMA1>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+
+ mdma0: mdma@10800000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x10800000 0x1000>;
+ interrupts = <0 33 0>;
+ clocks = <&clock CLK_MDMA0>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <1>;
+ };
+
+ mdma1: mdma@11C10000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x11C10000 0x1000>;
+ interrupts = <0 124 0>;
+ clocks = <&clock CLK_MDMA1>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <1>;
+ };
+ };
+
+ gsc_0: gsc@13e00000 {
+ compatible = "samsung,exynos5-gsc";
+ reg = <0x13e00000 0x1000>;
+ interrupts = <0 85 0>;
+ power-domains = <&pd_gsc>;
+ clocks = <&clock CLK_GSCL0>;
+ clock-names = "gscl";
+ };
+
+ gsc_1: gsc@13e10000 {
+ compatible = "samsung,exynos5-gsc";
+ reg = <0x13e10000 0x1000>;
+ interrupts = <0 86 0>;
+ power-domains = <&pd_gsc>;
+ clocks = <&clock CLK_GSCL1>;
+ clock-names = "gscl";
+ };
+
+ gsc_2: gsc@13e20000 {
+ compatible = "samsung,exynos5-gsc";
+ reg = <0x13e20000 0x1000>;
+ interrupts = <0 87 0>;
+ power-domains = <&pd_gsc>;
+ clocks = <&clock CLK_GSCL2>;
+ clock-names = "gscl";
+ };
+
+ gsc_3: gsc@13e30000 {
+ compatible = "samsung,exynos5-gsc";
+ reg = <0x13e30000 0x1000>;
+ interrupts = <0 88 0>;
+ power-domains = <&pd_gsc>;
+ clocks = <&clock CLK_GSCL3>;
+ clock-names = "gscl";
+ };
+
+ hdmi: hdmi {
+ compatible = "samsung,exynos4212-hdmi";
+ reg = <0x14530000 0x70000>;
+ power-domains = <&pd_disp1>;
+ interrupts = <0 95 0>;
+ clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>,
+ <&clock CLK_SCLK_PIXEL>, <&clock CLK_SCLK_HDMIPHY>,
+ <&clock CLK_MOUT_HDMI>;
+ clock-names = "hdmi", "sclk_hdmi", "sclk_pixel",
+ "sclk_hdmiphy", "mout_hdmi";
+ samsung,syscon-phandle = <&pmu_system_controller>;
+ };
+
+ mixer {
+ compatible = "samsung,exynos5250-mixer";
+ reg = <0x14450000 0x10000>;
+ power-domains = <&pd_disp1>;
+ interrupts = <0 94 0>;
+ clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
+ <&clock CLK_SCLK_HDMI>;
+ clock-names = "mixer", "hdmi", "sclk_hdmi";
+ };
+
+ dp_phy: video-phy@10040720 {
+ compatible = "samsung,exynos5250-dp-video-phy";
+ samsung,pmu-syscon = <&pmu_system_controller>;
+ #phy-cells = <0>;
+ };
+
+ dp: dp-controller@145B0000 {
+ power-domains = <&pd_disp1>;
+ clocks = <&clock CLK_DP>;
+ clock-names = "dp";
+ phys = <&dp_phy>;
+ phy-names = "dp";
+ };
+
+ fimd: fimd@14400000 {
+ power-domains = <&pd_disp1>;
+ clocks = <&clock CLK_SCLK_FIMD1>, <&clock CLK_FIMD1>;
+ clock-names = "sclk_fimd", "fimd";
+ };
+
+ adc: adc@12D10000 {
+ compatible = "samsung,exynos-adc-v1";
+ reg = <0x12D10000 0x100>;
+ interrupts = <0 106 0>;
+ clocks = <&clock CLK_ADC>;
+ clock-names = "adc";
+ #io-channel-cells = <1>;
+ io-channel-ranges;
+ samsung,syscon-phandle = <&pmu_system_controller>;
+ status = "disabled";
+ };
+
+ sss@10830000 {
+ compatible = "samsung,exynos4210-secss";
+ reg = <0x10830000 0x10000>;
+ interrupts = <0 112 0>;
+ clocks = <&clock CLK_SSS>;
+ clock-names = "secss";
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5260-pinctrl.dtsi b/arch/arm/boot/dts/exynos5260-pinctrl.dtsi
new file mode 100644
index 000000000..f6ee55ea0
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5260-pinctrl.dtsi
@@ -0,0 +1,574 @@
+/*
+ * Samsung's Exynos5260 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung's Exynos5260 SoC pin-mux and pin-config options are listed as device
+ * tree nodes are listed in this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define PIN_PULL_NONE 0
+#define PIN_PULL_DOWN 1
+#define PIN_PULL_UP 3
+
+&pinctrl_0 {
+ gpa0: gpa0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpa1: gpa1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpa2: gpa2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb0: gpb0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb1: gpb1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb2: gpb2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb3: gpb3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb4: gpb4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb5: gpb5 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd0: gpd0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd1: gpd1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd2: gpd2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpe0: gpe0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpe1: gpe1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf0: gpf0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf1: gpf1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpk0: gpk0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx0: gpx0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx1: gpx1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx2: gpx2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx3: gpx3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart0_data: uart0-data {
+ samsung,pins = "gpa0-0", "gpa0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart0_fctl: uart0-fctl {
+ samsung,pins = "gpa0-2", "gpa0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_data: uart1-data {
+ samsung,pins = "gpa1-0", "gpa1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_fctl: uart1-fctl {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart2_data: uart2-data {
+ samsung,pins = "gpa1-4", "gpa1-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi0_bus: spi0-bus {
+ samsung,pins = "gpa2-0", "gpa2-2", "gpa2-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi1_bus: spi1-bus {
+ samsung,pins = "gpa2-4", "gpa2-6", "gpa2-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ usb3_vbus0_en: usb3-vbus0-en {
+ samsung,pins = "gpa2-4";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s1_bus: i2s1-bus {
+ samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
+ "gpb0-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm1_bus: pcm1-bus {
+ samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
+ "gpb0-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <0>;
+ };
+
+ spdif1_bus: spdif1-bus {
+ samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi2_bus: spi2-bus {
+ samsung,pins = "gpb1-0", "gpb1-2", "gpb1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c0_hs_bus: i2c0-hs-bus {
+ samsung,pins = "gpb3-0", "gpb3-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c1_hs_bus: i2c1-hs-bus {
+ samsung,pins = "gpb3-2", "gpb3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c2_hs_bus: i2c2-hs-bus {
+ samsung,pins = "gpb3-4", "gpb3-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c3_hs_bus: i2c3-hs-bus {
+ samsung,pins = "gpb3-6", "gpb3-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c4_bus: i2c4-bus {
+ samsung,pins = "gpb4-0", "gpb4-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c5_bus: i2c5-bus {
+ samsung,pins = "gpb4-2", "gpb4-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c6_bus: i2c6-bus {
+ samsung,pins = "gpb4-4", "gpb4-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c7_bus: i2c7-bus {
+ samsung,pins = "gpb4-6", "gpb4-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c8_bus: i2c8-bus {
+ samsung,pins = "gpb5-0", "gpb5-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c9_bus: i2c9-bus {
+ samsung,pins = "gpb5-2", "gpb5-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c10_bus: i2c10-bus {
+ samsung,pins = "gpb5-4", "gpb5-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c11_bus: i2c11-bus {
+ samsung,pins = "gpb5-6", "gpb5-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_gpio_a: cam-gpio-a {
+ samsung,pins = "gpe0-0", "gpe0-1", "gpe0-2", "gpe0-3",
+ "gpe0-4", "gpe0-5", "gpe0-6", "gpe0-7",
+ "gpe1-0", "gpe1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_gpio_b: cam-gpio-b {
+ samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3",
+ "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_i2c1_bus: cam-i2c1-bus {
+ samsung,pins = "gpf0-2", "gpf0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_i2c0_bus: cam-i2c0-bus {
+ samsung,pins = "gpf0-0", "gpf0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_spi0_bus: cam-spi0-bus {
+ samsung,pins = "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_spi1_bus: cam-spi1-bus {
+ samsung,pins = "gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_1 {
+ gpc0: gpc0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc1: gpc1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc2: gpc2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc3: gpc3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc4: gpc4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ sd0_clk: sd0-clk {
+ samsung,pins = "gpc0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ samsung,pins = "gpc0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ samsung,pins = "gpc0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ samsung,pins = "gpc0-3", "gpc0-4", "gpc0-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus8: sd0-bus-width8 {
+ samsung,pins = "gpc3-0", "gpc3-1", "gpc3-2", "gpc3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_rdqs: sd0-rdqs {
+ samsung,pins = "gpc0-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_clk: sd1-clk {
+ samsung,pins = "gpc1-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ samsung,pins = "gpc1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ samsung,pins = "gpc1-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ samsung,pins = "gpc1-3", "gpc1-4", "gpc1-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus8: sd1-bus-width8 {
+ samsung,pins = "gpc4-0", "gpc4-1", "gpc4-2", "gpc4-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_clk: sd2-clk {
+ samsung,pins = "gpc2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cmd: sd2-cmd {
+ samsung,pins = "gpc2-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cd: sd2-cd {
+ samsung,pins = "gpc2-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus1: sd2-bus-width1 {
+ samsung,pins = "gpc2-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus4: sd2-bus-width4 {
+ samsung,pins = "gpc2-4", "gpc2-5", "gpc2-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ samsung,pin-drv = <3>;
+ };
+};
+
+&pinctrl_2 {
+ gpz0: gpz0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpz1: gpz1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5260-xyref5260.dts b/arch/arm/boot/dts/exynos5260-xyref5260.dts
new file mode 100644
index 000000000..a803b6050
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5260-xyref5260.dts
@@ -0,0 +1,95 @@
+/*
+ * SAMSUNG XYREF5260 board device tree source
+ *
+ * Copyright (c) 2013 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.
+*/
+
+/dts-v1/;
+#include "exynos5260.dtsi"
+
+/ {
+ model = "SAMSUNG XYREF5260 board based on EXYNOS5260";
+ compatible = "samsung,xyref5260", "samsung,exynos5260", "samsung,exynos5";
+
+ memory {
+ reg = <0x20000000 0x80000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttySAC2,115200";
+ };
+
+ fin_pll: xxti {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "fin_pll";
+ #clock-cells = <0>;
+ };
+
+ xrtcxti: xrtcxti {
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ clock-output-names = "xrtcxti";
+ #clock-cells = <0>;
+ };
+};
+
+&pinctrl_0 {
+ hdmi_hpd_irq: hdmi-hpd-irq {
+ samsung,pins = "gpx3-7";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&mmc_0 {
+ status = "okay";
+ num-slots = <1>;
+ broken-cd;
+ bypass-smu;
+ cap-mmc-highspeed;
+ supports-hs200-mode; /* 200 Mhz */
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_rdqs &sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8>;
+ bus-width = <8>;
+};
+
+&mmc_2 {
+ status = "okay";
+ num-slots = <1>;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus1 &sd2_bus4>;
+ bus-width = <4>;
+ disable-wp;
+};
diff --git a/arch/arm/boot/dts/exynos5260.dtsi b/arch/arm/boot/dts/exynos5260.dtsi
new file mode 100644
index 000000000..36da38e29
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5260.dtsi
@@ -0,0 +1,313 @@
+/*
+ * SAMSUNG EXYNOS5260 SoC device tree source
+ *
+ * Copyright (c) 2013 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 "skeleton.dtsi"
+
+#include <dt-bindings/clock/exynos5260-clk.h>
+
+/ {
+ compatible = "samsung,exynos5260", "samsung,exynos5";
+ interrupt-parent = <&gic>;
+
+ aliases {
+ pinctrl0 = &pinctrl_0;
+ pinctrl1 = &pinctrl_1;
+ pinctrl2 = &pinctrl_2;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x0>;
+ cci-control-port = <&cci_control1>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x1>;
+ cci-control-port = <&cci_control1>;
+ };
+
+ cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x100>;
+ cci-control-port = <&cci_control0>;
+ };
+
+ cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x101>;
+ cci-control-port = <&cci_control0>;
+ };
+
+ cpu@102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x102>;
+ cci-control-port = <&cci_control0>;
+ };
+
+ cpu@103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x103>;
+ cci-control-port = <&cci_control0>;
+ };
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ clock_top: clock-controller@10010000 {
+ compatible = "samsung,exynos5260-clock-top";
+ reg = <0x10010000 0x10000>;
+ #clock-cells = <1>;
+ };
+
+ clock_peri: clock-controller@10200000 {
+ compatible = "samsung,exynos5260-clock-peri";
+ reg = <0x10200000 0x10000>;
+ #clock-cells = <1>;
+ };
+
+ clock_egl: clock-controller@10600000 {
+ compatible = "samsung,exynos5260-clock-egl";
+ reg = <0x10600000 0x10000>;
+ #clock-cells = <1>;
+ };
+
+ clock_kfc: clock-controller@10700000 {
+ compatible = "samsung,exynos5260-clock-kfc";
+ reg = <0x10700000 0x10000>;
+ #clock-cells = <1>;
+ };
+
+ clock_g2d: clock-controller@10A00000 {
+ compatible = "samsung,exynos5260-clock-g2d";
+ reg = <0x10A00000 0x10000>;
+ #clock-cells = <1>;
+ };
+
+ clock_mif: clock-controller@10CE0000 {
+ compatible = "samsung,exynos5260-clock-mif";
+ reg = <0x10CE0000 0x10000>;
+ #clock-cells = <1>;
+ };
+
+ clock_mfc: clock-controller@11090000 {
+ compatible = "samsung,exynos5260-clock-mfc";
+ reg = <0x11090000 0x10000>;
+ #clock-cells = <1>;
+ };
+
+ clock_g3d: clock-controller@11830000 {
+ compatible = "samsung,exynos5260-clock-g3d";
+ reg = <0x11830000 0x10000>;
+ #clock-cells = <1>;
+ };
+
+ clock_fsys: clock-controller@122E0000 {
+ compatible = "samsung,exynos5260-clock-fsys";
+ reg = <0x122E0000 0x10000>;
+ #clock-cells = <1>;
+ };
+
+ clock_aud: clock-controller@128C0000 {
+ compatible = "samsung,exynos5260-clock-aud";
+ reg = <0x128C0000 0x10000>;
+ #clock-cells = <1>;
+ };
+
+ clock_isp: clock-controller@133C0000 {
+ compatible = "samsung,exynos5260-clock-isp";
+ reg = <0x133C0000 0x10000>;
+ #clock-cells = <1>;
+ };
+
+ clock_gscl: clock-controller@13F00000 {
+ compatible = "samsung,exynos5260-clock-gscl";
+ reg = <0x13F00000 0x10000>;
+ #clock-cells = <1>;
+ };
+
+ clock_disp: clock-controller@14550000 {
+ compatible = "samsung,exynos5260-clock-disp";
+ reg = <0x14550000 0x10000>;
+ #clock-cells = <1>;
+ };
+
+ gic: interrupt-controller@10481000 {
+ compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-controller;
+ reg = <0x10481000 0x1000>,
+ <0x10482000 0x1000>,
+ <0x10484000 0x2000>,
+ <0x10486000 0x2000>;
+ interrupts = <1 9 0xf04>;
+ };
+
+ chipid: chipid@10000000 {
+ compatible = "samsung,exynos4210-chipid";
+ reg = <0x10000000 0x100>;
+ };
+
+ mct: mct@100B0000 {
+ compatible = "samsung,exynos4210-mct";
+ reg = <0x100B0000 0x1000>;
+ clocks = <&fin_pll>, <&clock_peri PERI_CLK_MCT>;
+ clock-names = "fin_pll", "mct";
+ interrupts = <0 104 0>, <0 105 0>, <0 106 0>,
+ <0 107 0>, <0 122 0>, <0 123 0>,
+ <0 124 0>, <0 125 0>, <0 126 0>,
+ <0 127 0>, <0 128 0>, <0 129 0>;
+ };
+
+ cci: cci@10F00000 {
+ compatible = "arm,cci-400";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x10F00000 0x1000>;
+ ranges = <0x0 0x10F00000 0x6000>;
+
+ cci_control0: slave-if@4000 {
+ compatible = "arm,cci-400-ctrl-if";
+ interface-type = "ace";
+ reg = <0x4000 0x1000>;
+ };
+
+ cci_control1: slave-if@5000 {
+ compatible = "arm,cci-400-ctrl-if";
+ interface-type = "ace";
+ reg = <0x5000 0x1000>;
+ };
+ };
+
+ pinctrl_0: pinctrl@11600000 {
+ compatible = "samsung,exynos5260-pinctrl";
+ reg = <0x11600000 0x1000>;
+ interrupts = <0 79 0>;
+
+ wakeup-interrupt-controller {
+ compatible = "samsung,exynos4210-wakeup-eint";
+ interrupt-parent = <&gic>;
+ interrupts = <0 32 0>;
+ };
+ };
+
+ pinctrl_1: pinctrl@12290000 {
+ compatible = "samsung,exynos5260-pinctrl";
+ reg = <0x12290000 0x1000>;
+ interrupts = <0 157 0>;
+ };
+
+ pinctrl_2: pinctrl@128B0000 {
+ compatible = "samsung,exynos5260-pinctrl";
+ reg = <0x128B0000 0x1000>;
+ interrupts = <0 243 0>;
+ };
+
+ pmu_system_controller: system-controller@10D50000 {
+ compatible = "samsung,exynos5260-pmu", "syscon";
+ reg = <0x10D50000 0x10000>;
+ };
+
+ uart0: serial@12C00000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x12C00000 0x100>;
+ interrupts = <0 146 0>;
+ clocks = <&clock_peri PERI_CLK_UART0>, <&clock_peri PERI_SCLK_UART0>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ uart1: serial@12C10000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x12C10000 0x100>;
+ interrupts = <0 147 0>;
+ clocks = <&clock_peri PERI_CLK_UART1>, <&clock_peri PERI_SCLK_UART1>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ uart2: serial@12C20000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x12C20000 0x100>;
+ interrupts = <0 148 0>;
+ clocks = <&clock_peri PERI_CLK_UART2>, <&clock_peri PERI_SCLK_UART2>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ uart3: serial@12860000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x12860000 0x100>;
+ interrupts = <0 145 0>;
+ clocks = <&clock_aud AUD_CLK_AUD_UART>, <&clock_aud AUD_SCLK_AUD_UART>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ mmc_0: mmc@12140000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ reg = <0x12140000 0x2000>;
+ interrupts = <0 156 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock_fsys FSYS_CLK_MMC0>, <&clock_top TOP_SCLK_MMC0>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <64>;
+ status = "disabled";
+ };
+
+ mmc_1: mmc@12150000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ reg = <0x12150000 0x2000>;
+ interrupts = <0 158 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock_fsys FSYS_CLK_MMC1>, <&clock_top TOP_SCLK_MMC1>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <64>;
+ status = "disabled";
+ };
+
+ mmc_2: mmc@12160000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ reg = <0x12160000 0x2000>;
+ interrupts = <0 159 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock_fsys FSYS_CLK_MMC2>, <&clock_top TOP_SCLK_MMC2>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <64>;
+ status = "disabled";
+ };
+ };
+};
+
+#include "exynos5260-pinctrl.dtsi"
diff --git a/arch/arm/boot/dts/exynos5410-smdk5410.dts b/arch/arm/boot/dts/exynos5410-smdk5410.dts
new file mode 100644
index 000000000..be3e02530
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5410-smdk5410.dts
@@ -0,0 +1,74 @@
+/*
+ * SAMSUNG SMDK5410 board device tree source
+ *
+ * Copyright (c) 2013 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.
+*/
+
+/dts-v1/;
+#include "exynos5410.dtsi"
+/ {
+ model = "Samsung SMDK5410 board based on EXYNOS5410";
+ compatible = "samsung,smdk5410", "samsung,exynos5410", "samsung,exynos5";
+
+ memory {
+ reg = <0x40000000 0x80000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttySAC2,115200";
+ };
+
+ fin_pll: xxti {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "fin_pll";
+ #clock-cells = <0>;
+ };
+
+ firmware@02037000 {
+ compatible = "samsung,secure-firmware";
+ reg = <0x02037000 0x1000>;
+ };
+
+};
+
+&mmc_0 {
+ status = "okay";
+ num-slots = <1>;
+ cap-mmc-highspeed;
+ broken-cd;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ bus-width = <8>;
+};
+
+&mmc_2 {
+ status = "okay";
+ num-slots = <1>;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ bus-width = <4>;
+ disable-wp;
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/exynos5410.dtsi b/arch/arm/boot/dts/exynos5410.dtsi
new file mode 100644
index 000000000..731eefd23
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5410.dtsi
@@ -0,0 +1,221 @@
+/*
+ * SAMSUNG EXYNOS5410 SoC device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * SAMSUNG EXYNOS5410 SoC device nodes are listed in this file.
+ * EXYNOS5410 based board files can include this file and provide
+ * values for board specfic bindings.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/exynos5410.h>
+
+/ {
+ compatible = "samsung,exynos5410", "samsung,exynos5";
+ interrupt-parent = <&gic>;
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ CPU0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x0>;
+ clock-frequency = <1600000000>;
+ };
+
+ CPU1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x1>;
+ clock-frequency = <1600000000>;
+ };
+
+ CPU2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x2>;
+ clock-frequency = <1600000000>;
+ };
+
+ CPU3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x3>;
+ clock-frequency = <1600000000>;
+ };
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ combiner: interrupt-controller@10440000 {
+ compatible = "samsung,exynos4210-combiner";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ samsung,combiner-nr = <32>;
+ reg = <0x10440000 0x1000>;
+ interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
+ <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
+ <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
+ <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
+ <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+ <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>,
+ <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
+ <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
+ };
+
+ gic: interrupt-controller@10481000 {
+ compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x10481000 0x1000>,
+ <0x10482000 0x1000>,
+ <0x10484000 0x2000>,
+ <0x10486000 0x2000>;
+ interrupts = <1 9 0xf04>;
+ };
+
+ chipid@10000000 {
+ compatible = "samsung,exynos4210-chipid";
+ reg = <0x10000000 0x100>;
+ };
+
+ pmu_system_controller: system-controller@10040000 {
+ compatible = "samsung,exynos5410-pmu", "syscon";
+ reg = <0x10040000 0x5000>;
+ };
+
+ mct: mct@101C0000 {
+ compatible = "samsung,exynos4210-mct";
+ reg = <0x101C0000 0xB00>;
+ interrupt-parent = <&interrupt_map>;
+ interrupts = <0>, <1>, <2>, <3>,
+ <4>, <5>, <6>, <7>,
+ <8>, <9>, <10>, <11>;
+ clocks = <&fin_pll>, <&clock CLK_MCT>;
+ clock-names = "fin_pll", "mct";
+
+ interrupt_map: interrupt-map {
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = <0 &combiner 23 3>,
+ <1 &combiner 23 4>,
+ <2 &combiner 25 2>,
+ <3 &combiner 25 3>,
+ <4 &gic 0 120 0>,
+ <5 &gic 0 121 0>,
+ <6 &gic 0 122 0>,
+ <7 &gic 0 123 0>,
+ <8 &gic 0 128 0>,
+ <9 &gic 0 129 0>,
+ <10 &gic 0 130 0>,
+ <11 &gic 0 131 0>;
+ };
+ };
+
+ sysram@02020000 {
+ compatible = "mmio-sram";
+ reg = <0x02020000 0x54000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x02020000 0x54000>;
+
+ smp-sysram@0 {
+ compatible = "samsung,exynos4210-sysram";
+ reg = <0x0 0x1000>;
+ };
+
+ smp-sysram@53000 {
+ compatible = "samsung,exynos4210-sysram-ns";
+ reg = <0x53000 0x1000>;
+ };
+ };
+
+ clock: clock-controller@10010000 {
+ compatible = "samsung,exynos5410-clock";
+ reg = <0x10010000 0x30000>;
+ #clock-cells = <1>;
+ };
+
+ mmc_0: mmc@12200000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ reg = <0x12200000 0x1000>;
+ interrupts = <0 75 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_MMC0>, <&clock CLK_SCLK_MMC0>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x80>;
+ status = "disabled";
+ };
+
+ mmc_1: mmc@12210000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ reg = <0x12210000 0x1000>;
+ interrupts = <0 76 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_MMC1>, <&clock CLK_SCLK_MMC1>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x80>;
+ status = "disabled";
+ };
+
+ mmc_2: mmc@12220000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ reg = <0x12220000 0x1000>;
+ interrupts = <0 77 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_MMC2>, <&clock CLK_SCLK_MMC2>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x80>;
+ status = "disabled";
+ };
+
+ uart0: serial@12C00000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x12C00000 0x100>;
+ interrupts = <0 51 0>;
+ clocks = <&clock CLK_UART0>, <&clock CLK_SCLK_UART0>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ uart1: serial@12C10000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x12C10000 0x100>;
+ interrupts = <0 52 0>;
+ clocks = <&clock CLK_UART1>, <&clock CLK_SCLK_UART1>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ uart2: serial@12C20000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x12C20000 0x100>;
+ interrupts = <0 53 0>;
+ clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
new file mode 100644
index 000000000..b82b6fa15
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
@@ -0,0 +1,378 @@
+/*
+ * Samsung's Exynos5420 based Arndale Octa board device tree source
+ *
+ * Copyright (c) 2013 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.
+*/
+
+/dts-v1/;
+#include "exynos5420.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "Insignal Arndale Octa evaluation board based on EXYNOS5420";
+ compatible = "insignal,arndale-octa", "samsung,exynos5420", "samsung,exynos5";
+
+ memory {
+ reg = <0x20000000 0x80000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttySAC3,115200";
+ };
+
+ firmware@02073000 {
+ compatible = "samsung,secure-firmware";
+ reg = <0x02073000 0x1000>;
+ };
+
+ fixed-rate-clocks {
+ oscclk {
+ compatible = "samsung,exynos5420-oscclk";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ rtc@101E0000 {
+ status = "okay";
+ };
+
+ codec@11000000 {
+ samsung,mfc-r = <0x43000000 0x800000>;
+ samsung,mfc-l = <0x51000000 0x800000>;
+ };
+
+ mmc@12200000 {
+ status = "okay";
+ broken-cd;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8>;
+ vmmc-supply = <&ldo10_reg>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ };
+
+ mmc@12220000 {
+ status = "okay";
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus1 &sd2_bus4>;
+ vmmc-supply = <&ldo19_reg>;
+ vqmmc-supply = <&ldo13_reg>;
+ bus-width = <4>;
+ cap-sd-highspeed;
+ };
+
+ hsi2c_4: i2c@12CA0000 {
+ status = "okay";
+
+ s2mps11_pmic@66 {
+ compatible = "samsung,s2mps11-pmic";
+ reg = <0x66>;
+ s2mps11,buck2-ramp-delay = <12>;
+ s2mps11,buck34-ramp-delay = <12>;
+ s2mps11,buck16-ramp-delay = <12>;
+ s2mps11,buck6-ramp-enable = <1>;
+ s2mps11,buck2-ramp-enable = <1>;
+ s2mps11,buck3-ramp-enable = <1>;
+ s2mps11,buck4-ramp-enable = <1>;
+
+ interrupt-parent = <&gpx3>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
+
+ s2mps11_osc: clocks {
+ #clock-cells = <1>;
+ clock-output-names = "s2mps11_ap",
+ "s2mps11_cp", "s2mps11_bt";
+ };
+
+ regulators {
+ ldo1_reg: LDO1 {
+ regulator-name = "PVDD_ALIVE_1V0";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "PVDD_APIO_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "PVDD_APIO_MMCON_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "PVDD_ADC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "PVDD_PLL_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "PVDD_ANAIP_1V0";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "PVDD_ANAIP_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "PVDD_ABB_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "PVDD_USB_3V3";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "PVDD_PRE_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "PVDD_USB_1V0";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "PVDD_HSIC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "PVDD_APIO_MMCOFF_2V8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "PVDD_PERI_2V8";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "PVDD_PERI_3V3";
+ regulator-min-microvolt = <2200000>;
+ regulator-max-microvolt = <2200000>;
+ };
+
+ ldo18_reg: LDO18 {
+ regulator-name = "PVDD_EMMC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo19_reg: LDO19 {
+ regulator-name = "PVDD_TFLASH_2V8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo20_reg: LDO20 {
+ regulator-name = "PVDD_BTWIFI_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo21_reg: LDO21 {
+ regulator-name = "PVDD_CAM1IO_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo23_reg: LDO23 {
+ regulator-name = "PVDD_MIFS_1V1";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ ldo24_reg: LDO24 {
+ regulator-name = "PVDD_CAM1_AVDD_2V8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo26_reg: LDO26 {
+ regulator-name = "PVDD_CAM0_AF_2V8";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ ldo27_reg: LDO27 {
+ regulator-name = "PVDD_G3DS_1V0";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo28_reg: LDO28 {
+ regulator-name = "PVDD_TSP_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo29_reg: LDO29 {
+ regulator-name = "PVDD_AUDIO_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo31_reg: LDO31 {
+ regulator-name = "PVDD_PERI_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo32_reg: LDO32 {
+ regulator-name = "PVDD_LCD_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo33_reg: LDO33 {
+ regulator-name = "PVDD_CAM0IO_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo35_reg: LDO35 {
+ regulator-name = "PVDD_CAM0_DVDD_1V2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo38_reg: LDO38 {
+ regulator-name = "PVDD_CAM0_AVDD_2V8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "PVDD_MIF_1V1";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "PVDD_INT_1V0";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "PVDD_G3D_1V0";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "PVDD_LPDDR3_1V2";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ buck6_reg: BUCK6 {
+ regulator-name = "PVDD_KFC_1V0";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ buck7_reg: BUCK7 {
+ regulator-name = "VIN_LLDO_1V4";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ };
+
+ buck8_reg: BUCK8 {
+ regulator-name = "VIN_MLDO_2V0";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-always-on;
+ };
+
+ buck9_reg: BUCK9 {
+ regulator-name = "VIN_HLDO_3V5";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3500000>;
+ regulator-always-on;
+ };
+
+ buck10_reg: BUCK10 {
+ regulator-name = "PVDD_EMMCF_2V8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+ };
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ wakeup {
+ label = "SW-TACT1";
+ gpios = <&gpx2 7 1>;
+ linux,code = <KEY_WAKEUP>;
+ gpio-key,wakeup;
+ };
+ };
+};
+
+&usbdrd_dwc3_1 {
+ dr_mode = "host";
+};
+
+&cci {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
new file mode 100644
index 000000000..146e71118
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -0,0 +1,1060 @@
+/*
+ * Google Peach Pit Rev 6+ board device tree source
+ *
+ * Copyright (c) 2014 Google, 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.
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clock/maxim,max77802.h>
+#include <dt-bindings/regulator/maxim,max77802.h>
+#include "exynos5420.dtsi"
+
+/ {
+ model = "Google Peach Pit Rev 6+";
+
+ compatible = "google,pit-rev16",
+ "google,pit-rev15", "google,pit-rev14",
+ "google,pit-rev13", "google,pit-rev12",
+ "google,pit-rev11", "google,pit-rev10",
+ "google,pit-rev9", "google,pit-rev8",
+ "google,pit-rev7", "google,pit-rev6",
+ "google,pit", "google,peach","samsung,exynos5420",
+ "samsung,exynos5";
+
+ aliases {
+ /* Assign 20 so we don't get confused w/ builtin ones */
+ i2c20 = "/spi@12d40000/cros-ec@0/i2c-tunnel";
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 0 1000000 0>;
+ brightness-levels = <0 100 500 1000 1500 2000 2500 2800>;
+ default-brightness-level = <7>;
+ power-supply = <&tps65090_fet1>;
+ pinctrl-0 = <&pwm0_out>;
+ pinctrl-names = "default";
+ };
+
+ chosen {
+ stdout-path = "serial3:115200n8";
+ };
+
+ fixed-rate-clocks {
+ oscclk {
+ compatible = "samsung,exynos5420-oscclk";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&power_key_irq &lid_irq>;
+
+ power {
+ label = "Power";
+ gpios = <&gpx1 2 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ gpio-key,wakeup;
+ };
+
+ lid-switch {
+ label = "Lid";
+ gpios = <&gpx3 4 GPIO_ACTIVE_LOW>;
+ linux,input-type = <5>; /* EV_SW */
+ linux,code = <0>; /* SW_LID */
+ debounce-interval = <1>;
+ gpio-key,wakeup;
+ };
+ };
+
+ memory {
+ reg = <0x20000000 0x80000000>;
+ };
+
+ sound {
+ compatible = "google,snow-audio-max98090";
+
+ samsung,model = "Peach-Pit-I2S-MAX98090";
+ samsung,i2s-controller = <&i2s0>;
+ samsung,audio-codec = <&max98090>;
+ };
+
+ usb300_vbus_reg: regulator-usb300 {
+ compatible = "regulator-fixed";
+ regulator-name = "P5.0V_USB3CON0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gph0 0 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb300_vbus_en>;
+ enable-active-high;
+ };
+
+ usb301_vbus_reg: regulator-usb301 {
+ compatible = "regulator-fixed";
+ regulator-name = "P5.0V_USB3CON1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gph0 1 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb301_vbus_en>;
+ enable-active-high;
+ };
+
+ vbat: fixed-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vbat-supply";
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ panel: panel {
+ compatible = "auo,b116xw03";
+ power-supply = <&tps65090_fet6>;
+ backlight = <&backlight>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&bridge_out>;
+ };
+ };
+ };
+
+ mmc1_pwrseq: mmc1_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpx0 0 GPIO_ACTIVE_LOW>; /* WIFI_EN */
+ clocks = <&max77802 MAX77802_CLK_32K_CP>;
+ clock-names = "ext_clock";
+ };
+};
+
+&adc {
+ status = "okay";
+ vdd-supply = <&ldo9_reg>;
+};
+
+&dp {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&dp_hpd_gpio>;
+ samsung,color-space = <0>;
+ samsung,dynamic-range = <0>;
+ samsung,ycbcr-coeff = <0>;
+ samsung,color-depth = <1>;
+ samsung,link-rate = <0x06>;
+ samsung,lane-count = <2>;
+ samsung,hpd-gpio = <&gpx2 6 0>;
+
+ ports {
+ port@0 {
+ dp_out: endpoint {
+ remote-endpoint = <&bridge_in>;
+ };
+ };
+ };
+};
+
+&fimd {
+ status = "okay";
+ samsung,invert-vclk;
+};
+
+&hdmi {
+ status = "okay";
+ hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_hpd_irq>;
+ ddc = <&i2c_2>;
+
+ hdmi-en-supply = <&tps65090_fet7>;
+ vdd-supply = <&ldo8_reg>;
+ vdd_osc-supply = <&ldo10_reg>;
+ vdd_pll-supply = <&ldo8_reg>;
+};
+
+&hsi2c_4 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ max77802: max77802-pmic@9 {
+ compatible = "maxim,max77802";
+ interrupt-parent = <&gpx3>;
+ interrupts = <1 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&max77802_irq>, <&pmic_selb>,
+ <&pmic_dvs_1>, <&pmic_dvs_2>, <&pmic_dvs_3>;
+ wakeup-source;
+ reg = <0x9>;
+ #clock-cells = <1>;
+
+ inb1-supply = <&tps65090_dcdc2>;
+ inb2-supply = <&tps65090_dcdc1>;
+ inb3-supply = <&tps65090_dcdc2>;
+ inb4-supply = <&tps65090_dcdc2>;
+ inb5-supply = <&tps65090_dcdc1>;
+ inb6-supply = <&tps65090_dcdc2>;
+ inb7-supply = <&tps65090_dcdc1>;
+ inb8-supply = <&tps65090_dcdc1>;
+ inb9-supply = <&tps65090_dcdc1>;
+ inb10-supply = <&tps65090_dcdc1>;
+
+ inl1-supply = <&buck5_reg>;
+ inl2-supply = <&buck7_reg>;
+ inl3-supply = <&buck9_reg>;
+ inl4-supply = <&buck9_reg>;
+ inl5-supply = <&buck9_reg>;
+ inl6-supply = <&tps65090_dcdc2>;
+ inl7-supply = <&buck9_reg>;
+ inl9-supply = <&tps65090_dcdc2>;
+ inl10-supply = <&buck7_reg>;
+
+ regulators {
+ buck1_reg: BUCK1 {
+ regulator-name = "vdd_mif";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "vdd_int";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "vdd_g3d";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "vdd_1v2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck6_reg: BUCK6 {
+ regulator-name = "vdd_kfc";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck7_reg: BUCK7 {
+ regulator-name = "vdd_1v35";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ buck8_reg: BUCK8 {
+ regulator-name = "vdd_emmc";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck9_reg: BUCK9 {
+ regulator-name = "vdd_2v";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ buck10_reg: BUCK10 {
+ regulator-name = "vdd_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo1_reg: LDO1 {
+ regulator-name = "vdd_1v0";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "vdd_1v2_2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "vdd_1v8_3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
+ };
+
+ vqmmc_sdcard: ldo4_reg: LDO4 {
+ regulator-name = "vdd_sd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "vdd_1v8_5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "vdd_1v8_6";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "vdd_1v8_7";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "vdd_ldo8";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "vdd_ldo9";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "vdd_ldo10";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "vdd_ldo11";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "vdd_ldo12";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "vdd_ldo13";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "vdd_ldo14";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "vdd_ldo15";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "vdd_g3ds";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo18_reg: LDO18 {
+ regulator-name = "ldo_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo19_reg: LDO19 {
+ regulator-name = "ldo_19";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo20_reg: LDO20 {
+ regulator-name = "ldo_20";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo21_reg: LDO21 {
+ regulator-name = "ldo_21";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo23_reg: LDO23 {
+ regulator-name = "ldo_23";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ ldo24_reg: LDO24 {
+ regulator-name = "ldo_24";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo25_reg: LDO25 {
+ regulator-name = "ldo_25";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo26_reg: LDO26 {
+ regulator-name = "ldo_26";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo27_reg: LDO27 {
+ regulator-name = "ldo_27";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo28_reg: LDO28 {
+ regulator-name = "ldo_28";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo29_reg: LDO29 {
+ regulator-name = "ldo_29";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo30_reg: LDO30 {
+ regulator-name = "vdd_mifs";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo32_reg: LDO32 {
+ regulator-name = "ldo_32";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ ldo33_reg: LDO33 {
+ regulator-name = "ldo_33";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo34_reg: LDO34 {
+ regulator-name = "ldo_34";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ ldo35_reg: LDO35 {
+ regulator-name = "ldo_35";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+ };
+ };
+};
+
+&hsi2c_7 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ max98090: codec@10 {
+ compatible = "maxim,max98090";
+ reg = <0x10>;
+ interrupts = <2 0>;
+ interrupt-parent = <&gpx0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&max98090_irq>;
+ clocks = <&pmu_system_controller 0>;
+ clock-names = "mclk";
+ };
+
+ light-sensor@44 {
+ compatible = "isil,isl29018";
+ reg = <0x44>;
+ vcc-supply = <&tps65090_fet5>;
+ };
+
+ ps8625: lvds-bridge@48 {
+ compatible = "parade,ps8625";
+ reg = <0x48>;
+ sleep-gpios = <&gpx3 5 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpy7 7 GPIO_ACTIVE_HIGH>;
+ lane-count = <2>;
+ use-external-pwm;
+
+ ports {
+ port@0 {
+ bridge_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+
+ port@1 {
+ bridge_in: endpoint {
+ remote-endpoint = <&dp_out>;
+ };
+ };
+ };
+
+ };
+};
+
+&hsi2c_8 {
+ status = "okay";
+ clock-frequency = <333000>;
+
+ /* Atmel mXT336S */
+ trackpad@4b {
+ compatible = "atmel,maxtouch";
+ reg = <0x4b>;
+ interrupt-parent = <&gpx1>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+ wakeup-source;
+ pinctrl-names = "default";
+ pinctrl-0 = <&trackpad_irq>;
+ linux,gpio-keymap = <KEY_RESERVED
+ KEY_RESERVED
+ KEY_RESERVED /* GPIO0 */
+ KEY_RESERVED /* GPIO1 */
+ KEY_RESERVED /* GPIO2 */
+ BTN_LEFT>; /* GPIO3 */
+ };
+};
+
+&hsi2c_9 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ tpm@20 {
+ compatible = "infineon,slb9645tt";
+ reg = <0x20>;
+
+ /* Unused irq; but still need to configure the pins */
+ pinctrl-names = "default";
+ pinctrl-0 = <&tpm_irq>;
+ };
+};
+
+&i2c_2 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+ samsung,i2c-slave-addr = <0x50>;
+};
+
+&i2s0 {
+ status = "okay";
+};
+
+&mmc_0 {
+ status = "okay";
+ num-slots = <1>;
+ broken-cd;
+ mmc-hs200-1_8v;
+ cap-mmc-highspeed;
+ non-removable;
+ card-detect-delay = <200>;
+ clock-frequency = <400000000>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ samsung,dw-mshc-hs400-timing = <0 2>;
+ samsung,read-strobe-delay = <90>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8 &sd0_rclk>;
+ bus-width = <8>;
+};
+
+&mmc_1 {
+ status = "okay";
+ num-slots = <1>;
+ broken-cd;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ card-detect-delay = <200>;
+ clock-frequency = <400000000>;
+ samsung,dw-mshc-ciu-div = <1>;
+ samsung,dw-mshc-sdr-timing = <0 1>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_int>, <&sd1_bus1>,
+ <&sd1_bus4>, <&sd1_bus8>, <&wifi_en>;
+ bus-width = <4>;
+ cap-sd-highspeed;
+ mmc-pwrseq = <&mmc1_pwrseq>;
+ vqmmc-supply = <&buck10_reg>;
+};
+
+&mmc_2 {
+ status = "okay";
+ num-slots = <1>;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ clock-frequency = <400000000>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus1 &sd2_bus4>;
+ bus-width = <4>;
+};
+
+
+&pinctrl_0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mask_tpm_reset>;
+
+ wifi_en: wifi-en {
+ samsung,pins = "gpx0-0";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ max98090_irq: max98090-irq {
+ samsung,pins = "gpx0-2";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ /* We need GPX0_6 to be low at sleep time; just keep it low always */
+ mask_tpm_reset: mask-tpm-reset {
+ samsung,pins = "gpx0-6";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ samsung,pin-val = <0>;
+ };
+
+ tpm_irq: tpm-irq {
+ samsung,pins = "gpx1-0";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ trackpad_irq: trackpad-irq {
+ samsung,pins = "gpx1-1";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ power_key_irq: power-key-irq {
+ samsung,pins = "gpx1-2";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ ec_irq: ec-irq {
+ samsung,pins = "gpx1-5";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ tps65090_irq: tps65090-irq {
+ samsung,pins = "gpx2-5";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ dp_hpd_gpio: dp_hpd_gpio {
+ samsung,pins = "gpx2-6";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ max77802_irq: max77802-irq {
+ samsung,pins = "gpx3-1";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lid_irq: lid-irq {
+ samsung,pins = "gpx3-4";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ hdmi_hpd_irq: hdmi-hpd-irq {
+ samsung,pins = "gpx3-7";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+
+ pmic_dvs_1: pmic-dvs-1 {
+ samsung,pins = "gpy7-6";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_1 {
+ /* Adjust WiFi drive strengths lower for EMI */
+ sd1_clk: sd1-clk {
+ samsung,pin-drv = <2>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ samsung,pin-drv = <2>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ samsung,pin-drv = <2>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ samsung,pin-drv = <2>;
+ };
+
+ sd1_bus8: sd1-bus-width8 {
+ samsung,pin-drv = <2>;
+ };
+};
+
+&pinctrl_2 {
+ pmic_dvs_2: pmic-dvs-2 {
+ samsung,pins = "gpj4-2";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pmic_dvs_3: pmic-dvs-3 {
+ samsung,pins = "gpj4-3";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_3 {
+ /* Drive SPI lines at x2 for better integrity */
+ spi2-bus {
+ samsung,pin-drv = <2>;
+ };
+
+ /* Drive SPI chip select at x2 for better integrity */
+ ec_spi_cs: ec-spi-cs {
+ samsung,pins = "gpb1-2";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+
+ usb300_vbus_en: usb300-vbus-en {
+ samsung,pins = "gph0-0";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ usb301_vbus_en: usb301-vbus-en {
+ samsung,pins = "gph0-1";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pmic_selb: pmic-selb {
+ samsung,pins = "gph0-2", "gph0-3", "gph0-4", "gph0-5",
+ "gph0-6";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&rtc {
+ status = "okay";
+ clocks = <&clock CLK_RTC>, <&max77802 MAX77802_CLK_32K_AP>;
+ clock-names = "rtc", "rtc_src";
+};
+
+&spi_2 {
+ status = "okay";
+ num-cs = <1>;
+ samsung,spi-src-clk = <0>;
+ cs-gpios = <&gpb1 2 0>;
+
+ cros_ec: cros-ec@0 {
+ compatible = "google,cros-ec-spi";
+ interrupt-parent = <&gpx1>;
+ interrupts = <5 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ec_spi_cs &ec_irq>;
+ reg = <0>;
+ spi-max-frequency = <3125000>;
+
+ controller-data {
+ samsung,spi-feedback-delay = <1>;
+ };
+
+ i2c-tunnel {
+ compatible = "google,cros-ec-i2c-tunnel";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ google,remote-bus = <0>;
+
+ battery: sbs-battery@b {
+ compatible = "sbs,sbs-battery";
+ reg = <0xb>;
+ sbs,poll-retry-count = <1>;
+ sbs,i2c-retry-count = <2>;
+ };
+
+ power-regulator@48 {
+ compatible = "ti,tps65090";
+ reg = <0x48>;
+
+ /*
+ * Config irq to disable internal pulls
+ * even though we run in polling mode.
+ */
+ pinctrl-names = "default";
+ pinctrl-0 = <&tps65090_irq>;
+
+ vsys1-supply = <&vbat>;
+ vsys2-supply = <&vbat>;
+ vsys3-supply = <&vbat>;
+ infet1-supply = <&vbat>;
+ infet2-supply = <&tps65090_dcdc1>;
+ infet3-supply = <&tps65090_dcdc2>;
+ infet4-supply = <&tps65090_dcdc2>;
+ infet5-supply = <&tps65090_dcdc2>;
+ infet6-supply = <&tps65090_dcdc2>;
+ infet7-supply = <&tps65090_dcdc1>;
+ vsys-l1-supply = <&vbat>;
+ vsys-l2-supply = <&vbat>;
+
+ regulators {
+ tps65090_dcdc1: dcdc1 {
+ ti,enable-ext-control;
+ };
+ tps65090_dcdc2: dcdc2 {
+ ti,enable-ext-control;
+ };
+ tps65090_dcdc3: dcdc3 {
+ ti,enable-ext-control;
+ };
+ tps65090_fet1: fet1 {
+ regulator-name = "vcd_led";
+ };
+ tps65090_fet2: fet2 {
+ regulator-name = "video_mid";
+ regulator-always-on;
+ };
+ tps65090_fet3: fet3 {
+ regulator-name = "wwan_r";
+ regulator-always-on;
+ };
+ tps65090_fet4: fet4 {
+ regulator-name = "sdcard";
+ regulator-always-on;
+ };
+ tps65090_fet5: fet5 {
+ regulator-name = "camout";
+ regulator-always-on;
+ };
+ tps65090_fet6: fet6 {
+ regulator-name = "lcd_vdd";
+ };
+ tps65090_fet7: fet7 {
+ regulator-name = "video_mid_1a";
+ regulator-always-on;
+ };
+ tps65090_ldo1: ldo1 {
+ };
+ tps65090_ldo2: ldo2 {
+ };
+ };
+
+ charger {
+ compatible = "ti,tps65090-charger";
+ };
+ };
+ };
+ };
+};
+
+&uart_3 {
+ status = "okay";
+};
+
+&usbdrd_dwc3_0 {
+ dr_mode = "host";
+};
+
+&usbdrd_dwc3_1 {
+ dr_mode = "host";
+};
+
+&usbdrd_phy0 {
+ vbus-supply = <&usb300_vbus_reg>;
+};
+
+&usbdrd_phy1 {
+ vbus-supply = <&usb301_vbus_reg>;
+};
+
+/*
+ * Use longest HW watchdog in SoC (32 seconds) since the hardware
+ * watchdog provides no debugging information (compared to soft/hard
+ * lockup detectors) and so should be last resort.
+ */
+&watchdog {
+ timeout-sec = <32>;
+};
+
+#include "cros-ec-keyboard.dtsi"
+#include "cros-adc-thermistors.dtsi"
diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
new file mode 100644
index 000000000..8b153166e
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
@@ -0,0 +1,722 @@
+/*
+ * Samsung's Exynos5420 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung's Exynos5420 SoC pin-mux and pin-config options are listed as device
+ * tree nodes are listed in this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/ {
+ pinctrl@13400000 {
+ gpy7: gpy7 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx0: gpx0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&combiner>;
+ #interrupt-cells = <2>;
+ interrupts = <23 0>, <24 0>, <25 0>, <25 1>,
+ <26 0>, <26 1>, <27 0>, <27 1>;
+ };
+
+ gpx1: gpx1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&combiner>;
+ #interrupt-cells = <2>;
+ interrupts = <28 0>, <28 1>, <29 0>, <29 1>,
+ <30 0>, <30 1>, <31 0>, <31 1>;
+ };
+
+ gpx2: gpx2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx3: gpx3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ dp_hpd: dp_hpd {
+ samsung,pins = "gpx0-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ pinctrl@13410000 {
+ gpc0: gpc0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc1: gpc1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc2: gpc2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc3: gpc3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc4: gpc4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd1: gpd1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpy0: gpy0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy1: gpy1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy2: gpy2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy3: gpy3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy4: gpy4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy5: gpy5 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy6: gpy6 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ sd0_clk: sd0-clk {
+ samsung,pins = "gpc0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ samsung,pins = "gpc0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cd: sd0-cd {
+ samsung,pins = "gpc0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ samsung,pins = "gpc0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ samsung,pins = "gpc0-4", "gpc0-5", "gpc0-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus8: sd0-bus-width8 {
+ samsung,pins = "gpc3-0", "gpc3-1", "gpc3-2", "gpc3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_clk: sd1-clk {
+ samsung,pins = "gpc1-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_rclk: sd0-rclk {
+ samsung,pins = "gpc0-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ samsung,pins = "gpc1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cd: sd1-cd {
+ samsung,pins = "gpc1-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_int: sd1-int {
+ samsung,pins = "gpd1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ samsung,pins = "gpc1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ samsung,pins = "gpc1-4", "gpc1-5", "gpc1-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus8: sd1-bus-width8 {
+ samsung,pins = "gpd1-4", "gpd1-5", "gpd1-6", "gpd1-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_clk: sd2-clk {
+ samsung,pins = "gpc2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cmd: sd2-cmd {
+ samsung,pins = "gpc2-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cd: sd2-cd {
+ samsung,pins = "gpc2-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus1: sd2-bus-width1 {
+ samsung,pins = "gpc2-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus4: sd2-bus-width4 {
+ samsung,pins = "gpc2-4", "gpc2-5", "gpc2-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+ };
+
+ pinctrl@14000000 {
+ gpe0: gpe0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpe1: gpe1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf0: gpf0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf1: gpf1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg0: gpg0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg1: gpg1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg2: gpg2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpj4: gpj4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ cam_gpio_a: cam-gpio-a {
+ samsung,pins = "gpe0-0", "gpe0-1", "gpe0-2", "gpe0-3",
+ "gpe0-4", "gpe0-5", "gpe0-6", "gpe0-7",
+ "gpe1-0", "gpe1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_gpio_b: cam-gpio-b {
+ samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3",
+ "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_i2c2_bus: cam-i2c2-bus {
+ samsung,pins = "gpf0-4", "gpf0-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+ cam_spi1_bus: cam-spi1-bus {
+ samsung,pins = "gpe0-4", "gpe0-5", "gpf0-2", "gpf0-3";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_i2c1_bus: cam-i2c1-bus {
+ samsung,pins = "gpf0-2", "gpf0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_i2c0_bus: cam-i2c0-bus {
+ samsung,pins = "gpf0-0", "gpf0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_spi0_bus: cam-spi0-bus {
+ samsung,pins = "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_bayrgb_bus: cam-bayrgb-bus {
+ samsung,pins = "gpg0-0", "gpg0-1", "gpg0-2", "gpg0-3",
+ "gpg0-4", "gpg0-5", "gpg0-6", "gpg0-7",
+ "gpg1-0", "gpg1-1", "gpg1-2", "gpg1-3",
+ "gpg1-4", "gpg1-5", "gpg1-6", "gpg1-7",
+ "gpg2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ pinctrl@14010000 {
+ gpa0: gpa0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpa1: gpa1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpa2: gpa2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb0: gpb0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb1: gpb1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb2: gpb2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb3: gpb3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb4: gpb4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gph0: gph0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart0_data: uart0-data {
+ samsung,pins = "gpa0-0", "gpa0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart0_fctl: uart0-fctl {
+ samsung,pins = "gpa0-2", "gpa0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_data: uart1-data {
+ samsung,pins = "gpa0-4", "gpa0-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_fctl: uart1-fctl {
+ samsung,pins = "gpa0-6", "gpa0-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c2_bus: i2c2-bus {
+ samsung,pins = "gpa0-6", "gpa0-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart2_data: uart2-data {
+ samsung,pins = "gpa1-0", "gpa1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart2_fctl: uart2-fctl {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c3_bus: i2c3-bus {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart3_data: uart3-data {
+ samsung,pins = "gpa1-4", "gpa1-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi0_bus: spi0-bus {
+ samsung,pins = "gpa2-0", "gpa2-1", "gpa2-2", "gpa2-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi1_bus: spi1-bus {
+ samsung,pins = "gpa2-4", "gpa2-6", "gpa2-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c4_hs_bus: i2c4-hs-bus {
+ samsung,pins = "gpa2-0", "gpa2-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c5_hs_bus: i2c5-hs-bus {
+ samsung,pins = "gpa2-2", "gpa2-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s1_bus: i2s1-bus {
+ samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
+ "gpb0-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm1_bus: pcm1-bus {
+ samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
+ "gpb0-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s2_bus: i2s2-bus {
+ samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3",
+ "gpb1-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm2_bus: pcm2-bus {
+ samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3",
+ "gpb1-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ spdif_bus: spdif-bus {
+ samsung,pins = "gpb1-0", "gpb1-1";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi2_bus: spi2-bus {
+ samsung,pins = "gpb1-1", "gpb1-3", "gpb1-4";
+ samsung,pin-function = <5>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c6_hs_bus: i2c6-hs-bus {
+ samsung,pins = "gpb1-3", "gpb1-4";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm0_out: pwm0-out {
+ samsung,pins = "gpb2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm1_out: pwm1-out {
+ samsung,pins = "gpb2-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm2_out: pwm2-out {
+ samsung,pins = "gpb2-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm3_out: pwm3-out {
+ samsung,pins = "gpb2-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c7_hs_bus: i2c7-hs-bus {
+ samsung,pins = "gpb2-2", "gpb2-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c0_bus: i2c0-bus {
+ samsung,pins = "gpb3-0", "gpb3-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c1_bus: i2c1-bus {
+ samsung,pins = "gpb3-2", "gpb3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c8_hs_bus: i2c8-hs-bus {
+ samsung,pins = "gpb3-4", "gpb3-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c9_hs_bus: i2c9-hs-bus {
+ samsung,pins = "gpb3-6", "gpb3-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c10_hs_bus: i2c10-hs-bus {
+ samsung,pins = "gpb4-0", "gpb4-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ pinctrl@03860000 {
+ gpz: gpz {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ i2s0_bus: i2s0-bus {
+ samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
+ "gpz-4", "gpz-5", "gpz-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
new file mode 100644
index 000000000..9103f2381
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
@@ -0,0 +1,422 @@
+/*
+ * SAMSUNG SMDK5420 board device tree source
+ *
+ * Copyright (c) 2013 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.
+*/
+
+/dts-v1/;
+#include "exynos5420.dtsi"
+
+/ {
+ model = "Samsung SMDK5420 board based on EXYNOS5420";
+ compatible = "samsung,smdk5420", "samsung,exynos5420", "samsung,exynos5";
+
+ memory {
+ reg = <0x20000000 0x80000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttySAC2,115200 init=/linuxrc";
+ };
+
+ fixed-rate-clocks {
+ oscclk {
+ compatible = "samsung,exynos5420-oscclk";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdd: fixed-regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vdd-supply";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ dbvdd: fixed-regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "dbvdd-supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ spkvdd: fixed-regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "spkvdd-supply";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+ };
+
+ rtc@101E0000 {
+ status = "okay";
+ };
+
+ codec@11000000 {
+ samsung,mfc-r = <0x43000000 0x800000>;
+ samsung,mfc-l = <0x51000000 0x800000>;
+ };
+
+ mmc@12200000 {
+ status = "okay";
+ broken-cd;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ samsung,dw-mshc-hs400-timing = <0 2>;
+ samsung,read-strobe-delay = <90>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8
+ &sd0_rclk>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ };
+
+ mmc@12220000 {
+ status = "okay";
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus1 &sd2_bus4>;
+ bus-width = <4>;
+ cap-sd-highspeed;
+ };
+
+ dp-controller@145B0000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&dp_hpd>;
+ samsung,color-space = <0>;
+ samsung,dynamic-range = <0>;
+ samsung,ycbcr-coeff = <0>;
+ samsung,color-depth = <1>;
+ samsung,link-rate = <0x0a>;
+ samsung,lane-count = <4>;
+ status = "okay";
+ };
+
+ fimd@14400000 {
+ status = "okay";
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing@0 {
+ clock-frequency = <50000>;
+ hactive = <2560>;
+ vactive = <1600>;
+ hfront-porch = <48>;
+ hback-porch = <80>;
+ hsync-len = <32>;
+ vback-porch = <16>;
+ vfront-porch = <8>;
+ vsync-len = <6>;
+ };
+ };
+ };
+
+ pinctrl@13400000 {
+ hdmi_hpd_irq: hdmi-hpd-irq {
+ samsung,pins = "gpx3-7";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ pinctrl@14000000 {
+ usb300_vbus_en: usb300-vbus-en {
+ samsung,pins = "gpg0-5";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ usb301_vbus_en: usb301-vbus-en {
+ samsung,pins = "gpg1-4";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ hdmi@14530000 {
+ status = "okay";
+ hpd-gpio = <&gpx3 7 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_hpd_irq>;
+ };
+
+ usb300_vbus_reg: regulator-usb300 {
+ compatible = "regulator-fixed";
+ regulator-name = "VBUS0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpg0 5 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb300_vbus_en>;
+ enable-active-high;
+ };
+
+ usb301_vbus_reg: regulator-usb301 {
+ compatible = "regulator-fixed";
+ regulator-name = "VBUS1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpg1 4 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb301_vbus_en>;
+ enable-active-high;
+ };
+
+ phy@12100000 {
+ vbus-supply = <&usb300_vbus_reg>;
+ };
+
+ phy@12500000 {
+ vbus-supply = <&usb301_vbus_reg>;
+ };
+
+ i2c_2: i2c@12C80000 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+ status = "okay";
+
+ hdmiddc@50 {
+ compatible = "samsung,exynos4210-hdmiddc";
+ reg = <0x50>;
+ };
+ };
+
+ hsi2c_4: i2c@12CA0000 {
+ status = "okay";
+
+ s2mps11_pmic@66 {
+ compatible = "samsung,s2mps11-pmic";
+ reg = <0x66>;
+ s2mps11,buck2-ramp-delay = <12>;
+ s2mps11,buck34-ramp-delay = <12>;
+ s2mps11,buck16-ramp-delay = <12>;
+ s2mps11,buck6-ramp-enable = <1>;
+ s2mps11,buck2-ramp-enable = <1>;
+ s2mps11,buck3-ramp-enable = <1>;
+ s2mps11,buck4-ramp-enable = <1>;
+
+ s2mps11_osc: clocks {
+ #clock-cells = <1>;
+ clock-output-names = "s2mps11_ap",
+ "s2mps11_cp", "s2mps11_bt";
+ };
+
+ regulators {
+ ldo1_reg: LDO1 {
+ regulator-name = "vdd_ldo1";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "vdd_ldo3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "vdd_ldo5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "vdd_ldo6";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "vdd_ldo7";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "vdd_ldo8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "vdd_ldo9";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "vdd_ldo10";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "vdd_ldo11";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "vdd_ldo12";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "vdd_ldo13";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "vdd_ldo15";
+ regulator-min-microvolt = <3100000>;
+ regulator-max-microvolt = <3100000>;
+ regulator-always-on;
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "vdd_ldo16";
+ regulator-min-microvolt = <2200000>;
+ regulator-max-microvolt = <2200000>;
+ regulator-always-on;
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "tsp_avdd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo19_reg: LDO19 {
+ regulator-name = "vdd_sd";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo24_reg: LDO24 {
+ regulator-name = "tsp_io";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "vdd_mif";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "vdd_int";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "vdd_g3d";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "vdd_mem";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck6_reg: BUCK6 {
+ regulator-name = "vdd_kfc";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck7_reg: BUCK7 {
+ regulator-name = "vdd_1.0v_ldo";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck8_reg: BUCK8 {
+ regulator-name = "vdd_1.8v_ldo";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck9_reg: BUCK9 {
+ regulator-name = "vdd_2.8v_ldo";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3750000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck10_reg: BUCK10 {
+ regulator-name = "vdd_vmem";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5420-trip-points.dtsi b/arch/arm/boot/dts/exynos5420-trip-points.dtsi
new file mode 100644
index 000000000..2180a0152
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-trip-points.dtsi
@@ -0,0 +1,35 @@
+/*
+ * Device tree sources for default Exynos5420 thermal zone definition
+ *
+ * Copyright (c) 2014 Lukasz Majewski <l.majewski@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.
+ *
+ */
+
+polling-delay-passive = <0>;
+polling-delay = <0>;
+trips {
+ cpu-alert-0 {
+ temperature = <85000>; /* millicelsius */
+ hysteresis = <10000>; /* millicelsius */
+ type = "active";
+ };
+ cpu-alert-1 {
+ temperature = <103000>; /* millicelsius */
+ hysteresis = <10000>; /* millicelsius */
+ type = "active";
+ };
+ cpu-alert-2 {
+ temperature = <110000>; /* millicelsius */
+ hysteresis = <10000>; /* millicelsius */
+ type = "active";
+ };
+ cpu-crit-0 {
+ temperature = <120000>; /* millicelsius */
+ hysteresis = <0>; /* millicelsius */
+ type = "critical";
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
new file mode 100644
index 000000000..45317538b
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -0,0 +1,965 @@
+/*
+ * SAMSUNG EXYNOS5420 SoC device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * SAMSUNG EXYNOS54200 SoC device nodes are listed in this file.
+ * EXYNOS5420 based board files can include this file and provide
+ * values for board specfic bindings.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <dt-bindings/clock/exynos5420.h>
+#include "exynos5.dtsi"
+#include "exynos5420-pinctrl.dtsi"
+
+#include <dt-bindings/clock/exynos-audss-clk.h>
+
+/ {
+ compatible = "samsung,exynos5420", "samsung,exynos5";
+
+ aliases {
+ mshc0 = &mmc_0;
+ mshc1 = &mmc_1;
+ mshc2 = &mmc_2;
+ pinctrl0 = &pinctrl_0;
+ pinctrl1 = &pinctrl_1;
+ pinctrl2 = &pinctrl_2;
+ pinctrl3 = &pinctrl_3;
+ pinctrl4 = &pinctrl_4;
+ i2c0 = &i2c_0;
+ i2c1 = &i2c_1;
+ i2c2 = &i2c_2;
+ i2c3 = &i2c_3;
+ i2c4 = &hsi2c_4;
+ i2c5 = &hsi2c_5;
+ i2c6 = &hsi2c_6;
+ i2c7 = &hsi2c_7;
+ i2c8 = &hsi2c_8;
+ i2c9 = &hsi2c_9;
+ i2c10 = &hsi2c_10;
+ gsc0 = &gsc_0;
+ gsc1 = &gsc_1;
+ spi0 = &spi_0;
+ spi1 = &spi_1;
+ spi2 = &spi_2;
+ usbdrdphy0 = &usbdrd_phy0;
+ usbdrdphy1 = &usbdrd_phy1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x0>;
+ clock-frequency = <1800000000>;
+ cci-control-port = <&cci_control1>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x1>;
+ clock-frequency = <1800000000>;
+ cci-control-port = <&cci_control1>;
+ };
+
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x2>;
+ clock-frequency = <1800000000>;
+ cci-control-port = <&cci_control1>;
+ };
+
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x3>;
+ clock-frequency = <1800000000>;
+ cci-control-port = <&cci_control1>;
+ };
+
+ cpu4: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x100>;
+ clock-frequency = <1000000000>;
+ cci-control-port = <&cci_control0>;
+ };
+
+ cpu5: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x101>;
+ clock-frequency = <1000000000>;
+ cci-control-port = <&cci_control0>;
+ };
+
+ cpu6: cpu@102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x102>;
+ clock-frequency = <1000000000>;
+ cci-control-port = <&cci_control0>;
+ };
+
+ cpu7: cpu@103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x103>;
+ clock-frequency = <1000000000>;
+ cci-control-port = <&cci_control0>;
+ };
+ };
+
+ cci: cci@10d20000 {
+ compatible = "arm,cci-400";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x10d20000 0x1000>;
+ ranges = <0x0 0x10d20000 0x6000>;
+
+ cci_control0: slave-if@4000 {
+ compatible = "arm,cci-400-ctrl-if";
+ interface-type = "ace";
+ reg = <0x4000 0x1000>;
+ };
+ cci_control1: slave-if@5000 {
+ compatible = "arm,cci-400-ctrl-if";
+ interface-type = "ace";
+ reg = <0x5000 0x1000>;
+ };
+ };
+
+ sysram@02020000 {
+ compatible = "mmio-sram";
+ reg = <0x02020000 0x54000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x02020000 0x54000>;
+
+ smp-sysram@0 {
+ compatible = "samsung,exynos4210-sysram";
+ reg = <0x0 0x1000>;
+ };
+
+ smp-sysram@53000 {
+ compatible = "samsung,exynos4210-sysram-ns";
+ reg = <0x53000 0x1000>;
+ };
+ };
+
+ clock: clock-controller@10010000 {
+ compatible = "samsung,exynos5420-clock";
+ reg = <0x10010000 0x30000>;
+ #clock-cells = <1>;
+ };
+
+ clock_audss: audss-clock-controller@3810000 {
+ compatible = "samsung,exynos5420-audss-clock";
+ reg = <0x03810000 0x0C>;
+ #clock-cells = <1>;
+ clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MAU_EPLL>,
+ <&clock CLK_SCLK_MAUDIO0>, <&clock CLK_SCLK_MAUPCM0>;
+ clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in";
+ };
+
+ mfc: codec@11000000 {
+ compatible = "samsung,mfc-v7";
+ reg = <0x11000000 0x10000>;
+ interrupts = <0 96 0>;
+ clocks = <&clock CLK_MFC>;
+ clock-names = "mfc";
+ power-domains = <&mfc_pd>;
+ };
+
+ mmc_0: mmc@12200000 {
+ compatible = "samsung,exynos5420-dw-mshc-smu";
+ interrupts = <0 75 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x12200000 0x2000>;
+ clocks = <&clock CLK_MMC0>, <&clock CLK_SCLK_MMC0>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x40>;
+ status = "disabled";
+ };
+
+ mmc_1: mmc@12210000 {
+ compatible = "samsung,exynos5420-dw-mshc-smu";
+ interrupts = <0 76 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x12210000 0x2000>;
+ clocks = <&clock CLK_MMC1>, <&clock CLK_SCLK_MMC1>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x40>;
+ status = "disabled";
+ };
+
+ mmc_2: mmc@12220000 {
+ compatible = "samsung,exynos5420-dw-mshc";
+ interrupts = <0 77 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x12220000 0x1000>;
+ clocks = <&clock CLK_MMC2>, <&clock CLK_SCLK_MMC2>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x40>;
+ status = "disabled";
+ };
+
+ mct: mct@101C0000 {
+ compatible = "samsung,exynos4210-mct";
+ reg = <0x101C0000 0x800>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&mct_map>;
+ interrupts = <0>, <1>, <2>, <3>, <4>, <5>, <6>, <7>,
+ <8>, <9>, <10>, <11>;
+ clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MCT>;
+ clock-names = "fin_pll", "mct";
+
+ mct_map: mct-map {
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = <0 &combiner 23 3>,
+ <1 &combiner 23 4>,
+ <2 &combiner 25 2>,
+ <3 &combiner 25 3>,
+ <4 &gic 0 120 0>,
+ <5 &gic 0 121 0>,
+ <6 &gic 0 122 0>,
+ <7 &gic 0 123 0>,
+ <8 &gic 0 128 0>,
+ <9 &gic 0 129 0>,
+ <10 &gic 0 130 0>,
+ <11 &gic 0 131 0>;
+ };
+ };
+
+ gsc_pd: power-domain@10044000 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10044000 0x20>;
+ #power-domain-cells = <0>;
+ clocks = <&clock CLK_GSCL0>, <&clock CLK_GSCL1>;
+ clock-names = "asb0", "asb1";
+ };
+
+ isp_pd: power-domain@10044020 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10044020 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ mfc_pd: power-domain@10044060 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10044060 0x20>;
+ clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_SW_ACLK333>,
+ <&clock CLK_MOUT_USER_ACLK333>;
+ clock-names = "oscclk", "pclk0", "clk0";
+ #power-domain-cells = <0>;
+ };
+
+ msc_pd: power-domain@10044120 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x10044120 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ disp_pd: power-domain@100440C0 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x100440C0 0x20>;
+ #power-domain-cells = <0>;
+ clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_SW_ACLK200>,
+ <&clock CLK_MOUT_USER_ACLK200_DISP1>,
+ <&clock CLK_MOUT_SW_ACLK300>,
+ <&clock CLK_MOUT_USER_ACLK300_DISP1>,
+ <&clock CLK_MOUT_SW_ACLK400>,
+ <&clock CLK_MOUT_USER_ACLK400_DISP1>,
+ <&clock CLK_FIMD1>, <&clock CLK_MIXER>;
+ clock-names = "oscclk", "pclk0", "clk0",
+ "pclk1", "clk1", "pclk2", "clk2",
+ "asb0", "asb1";
+ };
+
+ pinctrl_0: pinctrl@13400000 {
+ compatible = "samsung,exynos5420-pinctrl";
+ reg = <0x13400000 0x1000>;
+ interrupts = <0 45 0>;
+
+ wakeup-interrupt-controller {
+ compatible = "samsung,exynos4210-wakeup-eint";
+ interrupt-parent = <&gic>;
+ interrupts = <0 32 0>;
+ };
+ };
+
+ pinctrl_1: pinctrl@13410000 {
+ compatible = "samsung,exynos5420-pinctrl";
+ reg = <0x13410000 0x1000>;
+ interrupts = <0 78 0>;
+ };
+
+ pinctrl_2: pinctrl@14000000 {
+ compatible = "samsung,exynos5420-pinctrl";
+ reg = <0x14000000 0x1000>;
+ interrupts = <0 46 0>;
+ };
+
+ pinctrl_3: pinctrl@14010000 {
+ compatible = "samsung,exynos5420-pinctrl";
+ reg = <0x14010000 0x1000>;
+ interrupts = <0 50 0>;
+ };
+
+ pinctrl_4: pinctrl@03860000 {
+ compatible = "samsung,exynos5420-pinctrl";
+ reg = <0x03860000 0x1000>;
+ interrupts = <0 47 0>;
+ };
+
+ rtc: rtc@101E0000 {
+ clocks = <&clock CLK_RTC>;
+ clock-names = "rtc";
+ interrupt-parent = <&pmu_system_controller>;
+ status = "disabled";
+ };
+
+ amba {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "arm,amba-bus";
+ interrupt-parent = <&gic>;
+ ranges;
+
+ adma: adma@03880000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x03880000 0x1000>;
+ interrupts = <0 110 0>;
+ clocks = <&clock_audss EXYNOS_ADMA>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <6>;
+ #dma-requests = <16>;
+ };
+
+ pdma0: pdma@121A0000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x121A0000 0x1000>;
+ interrupts = <0 34 0>;
+ clocks = <&clock CLK_PDMA0>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+
+ pdma1: pdma@121B0000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x121B0000 0x1000>;
+ interrupts = <0 35 0>;
+ clocks = <&clock CLK_PDMA1>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+
+ mdma0: mdma@10800000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x10800000 0x1000>;
+ interrupts = <0 33 0>;
+ clocks = <&clock CLK_MDMA0>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <1>;
+ };
+
+ mdma1: mdma@11C10000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x11C10000 0x1000>;
+ interrupts = <0 124 0>;
+ clocks = <&clock CLK_MDMA1>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <1>;
+ /*
+ * MDMA1 can support both secure and non-secure
+ * AXI transactions. When this is enabled in the kernel
+ * for boards that run in secure mode, we are getting
+ * imprecise external aborts causing the kernel to oops.
+ */
+ status = "disabled";
+ };
+ };
+
+ i2s0: i2s@03830000 {
+ compatible = "samsung,exynos5420-i2s";
+ reg = <0x03830000 0x100>;
+ dmas = <&adma 0
+ &adma 2
+ &adma 1>;
+ dma-names = "tx", "rx", "tx-sec";
+ clocks = <&clock_audss EXYNOS_I2S_BUS>,
+ <&clock_audss EXYNOS_I2S_BUS>,
+ <&clock_audss EXYNOS_SCLK_I2S>;
+ clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
+ samsung,idma-addr = <0x03000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_bus>;
+ status = "disabled";
+ };
+
+ i2s1: i2s@12D60000 {
+ compatible = "samsung,exynos5420-i2s";
+ reg = <0x12D60000 0x100>;
+ dmas = <&pdma1 12
+ &pdma1 11>;
+ dma-names = "tx", "rx";
+ clocks = <&clock CLK_I2S1>, <&clock CLK_SCLK_I2S1>;
+ clock-names = "iis", "i2s_opclk0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s1_bus>;
+ status = "disabled";
+ };
+
+ i2s2: i2s@12D70000 {
+ compatible = "samsung,exynos5420-i2s";
+ reg = <0x12D70000 0x100>;
+ dmas = <&pdma0 12
+ &pdma0 11>;
+ dma-names = "tx", "rx";
+ clocks = <&clock CLK_I2S2>, <&clock CLK_SCLK_I2S2>;
+ clock-names = "iis", "i2s_opclk0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s2_bus>;
+ status = "disabled";
+ };
+
+ spi_0: spi@12d20000 {
+ compatible = "samsung,exynos4210-spi";
+ reg = <0x12d20000 0x100>;
+ interrupts = <0 68 0>;
+ dmas = <&pdma0 5
+ &pdma0 4>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_bus>;
+ clocks = <&clock CLK_SPI0>, <&clock CLK_SCLK_SPI0>;
+ clock-names = "spi", "spi_busclk0";
+ status = "disabled";
+ };
+
+ spi_1: spi@12d30000 {
+ compatible = "samsung,exynos4210-spi";
+ reg = <0x12d30000 0x100>;
+ interrupts = <0 69 0>;
+ dmas = <&pdma1 5
+ &pdma1 4>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_bus>;
+ clocks = <&clock CLK_SPI1>, <&clock CLK_SCLK_SPI1>;
+ clock-names = "spi", "spi_busclk0";
+ status = "disabled";
+ };
+
+ spi_2: spi@12d40000 {
+ compatible = "samsung,exynos4210-spi";
+ reg = <0x12d40000 0x100>;
+ interrupts = <0 70 0>;
+ dmas = <&pdma0 7
+ &pdma0 6>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_bus>;
+ clocks = <&clock CLK_SPI2>, <&clock CLK_SCLK_SPI2>;
+ clock-names = "spi", "spi_busclk0";
+ status = "disabled";
+ };
+
+ uart_0: serial@12C00000 {
+ clocks = <&clock CLK_UART0>, <&clock CLK_SCLK_UART0>;
+ clock-names = "uart", "clk_uart_baud0";
+ };
+
+ uart_1: serial@12C10000 {
+ clocks = <&clock CLK_UART1>, <&clock CLK_SCLK_UART1>;
+ clock-names = "uart", "clk_uart_baud0";
+ };
+
+ uart_2: serial@12C20000 {
+ clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
+ clock-names = "uart", "clk_uart_baud0";
+ };
+
+ uart_3: serial@12C30000 {
+ clocks = <&clock CLK_UART3>, <&clock CLK_SCLK_UART3>;
+ clock-names = "uart", "clk_uart_baud0";
+ };
+
+ pwm: pwm@12dd0000 {
+ compatible = "samsung,exynos4210-pwm";
+ reg = <0x12dd0000 0x100>;
+ samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+ #pwm-cells = <3>;
+ clocks = <&clock CLK_PWM>;
+ clock-names = "timers";
+ };
+
+ dp_phy: video-phy@10040728 {
+ compatible = "samsung,exynos5420-dp-video-phy";
+ samsung,pmu-syscon = <&pmu_system_controller>;
+ #phy-cells = <0>;
+ };
+
+ dp: dp-controller@145B0000 {
+ clocks = <&clock CLK_DP1>;
+ clock-names = "dp";
+ phys = <&dp_phy>;
+ phy-names = "dp";
+ power-domains = <&disp_pd>;
+ };
+
+ mipi_phy: video-phy@10040714 {
+ compatible = "samsung,s5pv210-mipi-video-phy";
+ reg = <0x10040714 12>;
+ #phy-cells = <1>;
+ };
+
+ dsi@14500000 {
+ compatible = "samsung,exynos5410-mipi-dsi";
+ reg = <0x14500000 0x10000>;
+ interrupts = <0 82 0>;
+ phys = <&mipi_phy 1>;
+ phy-names = "dsim";
+ clocks = <&clock CLK_DSIM1>, <&clock CLK_SCLK_MIPI1>;
+ clock-names = "bus_clk", "pll_clk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ fimd: fimd@14400000 {
+ clocks = <&clock CLK_SCLK_FIMD1>, <&clock CLK_FIMD1>;
+ clock-names = "sclk_fimd", "fimd";
+ power-domains = <&disp_pd>;
+ };
+
+ adc: adc@12D10000 {
+ compatible = "samsung,exynos-adc-v2";
+ reg = <0x12D10000 0x100>;
+ interrupts = <0 106 0>;
+ clocks = <&clock CLK_TSADC>;
+ clock-names = "adc";
+ #io-channel-cells = <1>;
+ io-channel-ranges;
+ samsung,syscon-phandle = <&pmu_system_controller>;
+ status = "disabled";
+ };
+
+ i2c_0: i2c@12C60000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x12C60000 0x100>;
+ interrupts = <0 56 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_I2C0>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_bus>;
+ samsung,sysreg-phandle = <&sysreg_system_controller>;
+ status = "disabled";
+ };
+
+ i2c_1: i2c@12C70000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x12C70000 0x100>;
+ interrupts = <0 57 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_I2C1>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_bus>;
+ samsung,sysreg-phandle = <&sysreg_system_controller>;
+ status = "disabled";
+ };
+
+ i2c_2: i2c@12C80000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x12C80000 0x100>;
+ interrupts = <0 58 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_I2C2>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_bus>;
+ samsung,sysreg-phandle = <&sysreg_system_controller>;
+ status = "disabled";
+ };
+
+ i2c_3: i2c@12C90000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x12C90000 0x100>;
+ interrupts = <0 59 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_I2C3>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_bus>;
+ samsung,sysreg-phandle = <&sysreg_system_controller>;
+ status = "disabled";
+ };
+
+ hsi2c_4: i2c@12CA0000 {
+ compatible = "samsung,exynos5-hsi2c";
+ reg = <0x12CA0000 0x1000>;
+ interrupts = <0 60 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_hs_bus>;
+ clocks = <&clock CLK_USI0>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_5: i2c@12CB0000 {
+ compatible = "samsung,exynos5-hsi2c";
+ reg = <0x12CB0000 0x1000>;
+ interrupts = <0 61 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5_hs_bus>;
+ clocks = <&clock CLK_USI1>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_6: i2c@12CC0000 {
+ compatible = "samsung,exynos5-hsi2c";
+ reg = <0x12CC0000 0x1000>;
+ interrupts = <0 62 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c6_hs_bus>;
+ clocks = <&clock CLK_USI2>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_7: i2c@12CD0000 {
+ compatible = "samsung,exynos5-hsi2c";
+ reg = <0x12CD0000 0x1000>;
+ interrupts = <0 63 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c7_hs_bus>;
+ clocks = <&clock CLK_USI3>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_8: i2c@12E00000 {
+ compatible = "samsung,exynos5-hsi2c";
+ reg = <0x12E00000 0x1000>;
+ interrupts = <0 87 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c8_hs_bus>;
+ clocks = <&clock CLK_USI4>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_9: i2c@12E10000 {
+ compatible = "samsung,exynos5-hsi2c";
+ reg = <0x12E10000 0x1000>;
+ interrupts = <0 88 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c9_hs_bus>;
+ clocks = <&clock CLK_USI5>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_10: i2c@12E20000 {
+ compatible = "samsung,exynos5-hsi2c";
+ reg = <0x12E20000 0x1000>;
+ interrupts = <0 203 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c10_hs_bus>;
+ clocks = <&clock CLK_USI6>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hdmi: hdmi@14530000 {
+ compatible = "samsung,exynos5420-hdmi";
+ reg = <0x14530000 0x70000>;
+ interrupts = <0 95 0>;
+ clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>,
+ <&clock CLK_DOUT_PIXEL>, <&clock CLK_SCLK_HDMIPHY>,
+ <&clock CLK_MOUT_HDMI>;
+ clock-names = "hdmi", "sclk_hdmi", "sclk_pixel",
+ "sclk_hdmiphy", "mout_hdmi";
+ phy = <&hdmiphy>;
+ samsung,syscon-phandle = <&pmu_system_controller>;
+ status = "disabled";
+ power-domains = <&disp_pd>;
+ };
+
+ hdmiphy: hdmiphy@145D0000 {
+ reg = <0x145D0000 0x20>;
+ };
+
+ mixer: mixer@14450000 {
+ compatible = "samsung,exynos5420-mixer";
+ reg = <0x14450000 0x10000>;
+ interrupts = <0 94 0>;
+ clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
+ <&clock CLK_SCLK_HDMI>;
+ clock-names = "mixer", "hdmi", "sclk_hdmi";
+ power-domains = <&disp_pd>;
+ };
+
+ gsc_0: video-scaler@13e00000 {
+ compatible = "samsung,exynos5-gsc";
+ reg = <0x13e00000 0x1000>;
+ interrupts = <0 85 0>;
+ clocks = <&clock CLK_GSCL0>;
+ clock-names = "gscl";
+ power-domains = <&gsc_pd>;
+ };
+
+ gsc_1: video-scaler@13e10000 {
+ compatible = "samsung,exynos5-gsc";
+ reg = <0x13e10000 0x1000>;
+ interrupts = <0 86 0>;
+ clocks = <&clock CLK_GSCL1>;
+ clock-names = "gscl";
+ power-domains = <&gsc_pd>;
+ };
+
+ pmu_system_controller: system-controller@10040000 {
+ compatible = "samsung,exynos5420-pmu", "syscon";
+ reg = <0x10040000 0x5000>;
+ clock-names = "clkout16";
+ clocks = <&clock CLK_FIN_PLL>;
+ #clock-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ };
+
+ sysreg_system_controller: syscon@10050000 {
+ compatible = "samsung,exynos5-sysreg", "syscon";
+ reg = <0x10050000 0x5000>;
+ };
+
+ tmu_cpu0: tmu@10060000 {
+ compatible = "samsung,exynos5420-tmu";
+ reg = <0x10060000 0x100>;
+ interrupts = <0 65 0>;
+ clocks = <&clock CLK_TMU>;
+ clock-names = "tmu_apbif";
+ #include "exynos4412-tmu-sensor-conf.dtsi"
+ };
+
+ tmu_cpu1: tmu@10064000 {
+ compatible = "samsung,exynos5420-tmu";
+ reg = <0x10064000 0x100>;
+ interrupts = <0 183 0>;
+ clocks = <&clock CLK_TMU>;
+ clock-names = "tmu_apbif";
+ #include "exynos4412-tmu-sensor-conf.dtsi"
+ };
+
+ tmu_cpu2: tmu@10068000 {
+ compatible = "samsung,exynos5420-tmu-ext-triminfo";
+ reg = <0x10068000 0x100>, <0x1006c000 0x4>;
+ interrupts = <0 184 0>;
+ clocks = <&clock CLK_TMU>, <&clock CLK_TMU>;
+ clock-names = "tmu_apbif", "tmu_triminfo_apbif";
+ #include "exynos4412-tmu-sensor-conf.dtsi"
+ };
+
+ tmu_cpu3: tmu@1006c000 {
+ compatible = "samsung,exynos5420-tmu-ext-triminfo";
+ reg = <0x1006c000 0x100>, <0x100a0000 0x4>;
+ interrupts = <0 185 0>;
+ clocks = <&clock CLK_TMU>, <&clock CLK_TMU_GPU>;
+ clock-names = "tmu_apbif", "tmu_triminfo_apbif";
+ #include "exynos4412-tmu-sensor-conf.dtsi"
+ };
+
+ tmu_gpu: tmu@100a0000 {
+ compatible = "samsung,exynos5420-tmu-ext-triminfo";
+ reg = <0x100a0000 0x100>, <0x10068000 0x4>;
+ interrupts = <0 215 0>;
+ clocks = <&clock CLK_TMU_GPU>, <&clock CLK_TMU>;
+ clock-names = "tmu_apbif", "tmu_triminfo_apbif";
+ #include "exynos4412-tmu-sensor-conf.dtsi"
+ };
+
+ thermal-zones {
+ cpu0_thermal: cpu0-thermal {
+ thermal-sensors = <&tmu_cpu0>;
+ #include "exynos5420-trip-points.dtsi"
+ };
+ cpu1_thermal: cpu1-thermal {
+ thermal-sensors = <&tmu_cpu1>;
+ #include "exynos5420-trip-points.dtsi"
+ };
+ cpu2_thermal: cpu2-thermal {
+ thermal-sensors = <&tmu_cpu2>;
+ #include "exynos5420-trip-points.dtsi"
+ };
+ cpu3_thermal: cpu3-thermal {
+ thermal-sensors = <&tmu_cpu3>;
+ #include "exynos5420-trip-points.dtsi"
+ };
+ gpu_thermal: gpu-thermal {
+ thermal-sensors = <&tmu_gpu>;
+ #include "exynos5420-trip-points.dtsi"
+ };
+ };
+
+ watchdog: watchdog@101D0000 {
+ compatible = "samsung,exynos5420-wdt";
+ reg = <0x101D0000 0x100>;
+ interrupts = <0 42 0>;
+ clocks = <&clock CLK_WDT>;
+ clock-names = "watchdog";
+ samsung,syscon-phandle = <&pmu_system_controller>;
+ };
+
+ sss: sss@10830000 {
+ compatible = "samsung,exynos4210-secss";
+ reg = <0x10830000 0x10000>;
+ interrupts = <0 112 0>;
+ clocks = <&clock CLK_SSS>;
+ clock-names = "secss";
+ };
+
+ usbdrd3_0: usb@12000000 {
+ compatible = "samsung,exynos5250-dwusb3";
+ clocks = <&clock CLK_USBD300>;
+ clock-names = "usbdrd30";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ usbdrd_dwc3_0: dwc3 {
+ compatible = "snps,dwc3";
+ reg = <0x12000000 0x10000>;
+ interrupts = <0 72 0>;
+ phys = <&usbdrd_phy0 0>, <&usbdrd_phy0 1>;
+ phy-names = "usb2-phy", "usb3-phy";
+ };
+ };
+
+ usbdrd_phy0: phy@12100000 {
+ compatible = "samsung,exynos5420-usbdrd-phy";
+ reg = <0x12100000 0x100>;
+ clocks = <&clock CLK_USBD300>, <&clock CLK_SCLK_USBPHY300>;
+ clock-names = "phy", "ref";
+ samsung,pmu-syscon = <&pmu_system_controller>;
+ #phy-cells = <1>;
+ };
+
+ usbdrd3_1: usb@12400000 {
+ compatible = "samsung,exynos5250-dwusb3";
+ clocks = <&clock CLK_USBD301>;
+ clock-names = "usbdrd30";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ usbdrd_dwc3_1: dwc3 {
+ compatible = "snps,dwc3";
+ reg = <0x12400000 0x10000>;
+ interrupts = <0 73 0>;
+ phys = <&usbdrd_phy1 0>, <&usbdrd_phy1 1>;
+ phy-names = "usb2-phy", "usb3-phy";
+ };
+ };
+
+ usbdrd_phy1: phy@12500000 {
+ compatible = "samsung,exynos5420-usbdrd-phy";
+ reg = <0x12500000 0x100>;
+ clocks = <&clock CLK_USBD301>, <&clock CLK_SCLK_USBPHY301>;
+ clock-names = "phy", "ref";
+ samsung,pmu-syscon = <&pmu_system_controller>;
+ #phy-cells = <1>;
+ };
+
+ usbhost2: usb@12110000 {
+ compatible = "samsung,exynos4210-ehci";
+ reg = <0x12110000 0x100>;
+ interrupts = <0 71 0>;
+
+ clocks = <&clock CLK_USBH20>;
+ clock-names = "usbhost";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ phys = <&usb2_phy 1>;
+ };
+ };
+
+ usbhost1: usb@12120000 {
+ compatible = "samsung,exynos4210-ohci";
+ reg = <0x12120000 0x100>;
+ interrupts = <0 71 0>;
+
+ clocks = <&clock CLK_USBH20>;
+ clock-names = "usbhost";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ phys = <&usb2_phy 1>;
+ };
+ };
+
+ usb2_phy: phy@12130000 {
+ compatible = "samsung,exynos5250-usb2-phy";
+ reg = <0x12130000 0x100>;
+ clocks = <&clock CLK_USBH20>, <&clock CLK_SCLK_USBPHY300>;
+ clock-names = "phy", "ref";
+ #phy-cells = <1>;
+ samsung,sysreg-phandle = <&sysreg_system_controller>;
+ samsung,pmureg-phandle = <&pmu_system_controller>;
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3.dts b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
new file mode 100644
index 000000000..edc25cf1d
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
@@ -0,0 +1,388 @@
+/*
+ * Hardkernel Odroid XU3 board device tree source
+ *
+ * Copyright (c) 2014 Collabora Ltd.
+ * Copyright (c) 2013 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.
+*/
+
+/dts-v1/;
+#include "exynos5800.dtsi"
+
+/ {
+ model = "Hardkernel Odroid XU3";
+ compatible = "hardkernel,odroid-xu3", "samsung,exynos5800", "samsung,exynos5";
+
+ memory {
+ reg = <0x40000000 0x7EA00000>;
+ };
+
+ chosen {
+ linux,stdout-path = &serial_2;
+ };
+
+ fimd@14400000 {
+ status = "okay";
+ };
+
+ firmware@02073000 {
+ compatible = "samsung,secure-firmware";
+ reg = <0x02073000 0x1000>;
+ };
+
+ fixed-rate-clocks {
+ oscclk {
+ compatible = "samsung,exynos5420-oscclk";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ hsi2c_4: i2c@12CA0000 {
+ status = "okay";
+
+ s2mps11_pmic@66 {
+ compatible = "samsung,s2mps11-pmic";
+ reg = <0x66>;
+ s2mps11,buck2-ramp-delay = <12>;
+ s2mps11,buck34-ramp-delay = <12>;
+ s2mps11,buck16-ramp-delay = <12>;
+ s2mps11,buck6-ramp-enable = <1>;
+ s2mps11,buck2-ramp-enable = <1>;
+ s2mps11,buck3-ramp-enable = <1>;
+ s2mps11,buck4-ramp-enable = <1>;
+
+ s2mps11_osc: clocks {
+ #clock-cells = <1>;
+ clock-output-names = "s2mps11_ap",
+ "s2mps11_cp", "s2mps11_bt";
+ };
+
+ regulators {
+ ldo1_reg: LDO1 {
+ regulator-name = "vdd_ldo1";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "vdd_ldo3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "vdd_ldo5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "vdd_ldo6";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "vdd_ldo7";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "vdd_ldo8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "vdd_ldo9";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "vdd_ldo10";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "vdd_ldo11";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "vdd_ldo12";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "vdd_ldo13";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "vdd_ldo15";
+ regulator-min-microvolt = <3100000>;
+ regulator-max-microvolt = <3100000>;
+ regulator-always-on;
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "vdd_ldo16";
+ regulator-min-microvolt = <2200000>;
+ regulator-max-microvolt = <2200000>;
+ regulator-always-on;
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "tsp_avdd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo19_reg: LDO19 {
+ regulator-name = "vdd_sd";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo24_reg: LDO24 {
+ regulator-name = "tsp_io";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo26_reg: LDO26 {
+ regulator-name = "vdd_ldo26";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "vdd_mif";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "vdd_int";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "vdd_g3d";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "vdd_mem";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck6_reg: BUCK6 {
+ regulator-name = "vdd_kfc";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck7_reg: BUCK7 {
+ regulator-name = "vdd_1.0v_ldo";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck8_reg: BUCK8 {
+ regulator-name = "vdd_1.8v_ldo";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck9_reg: BUCK9 {
+ regulator-name = "vdd_2.8v_ldo";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3750000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck10_reg: BUCK10 {
+ regulator-name = "vdd_vmem";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+ };
+
+ emmc_pwrseq: pwrseq {
+ pinctrl-0 = <&emmc_nrst_pin>;
+ pinctrl-names = "default";
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpd1 0 1>;
+ };
+
+ i2c_2: i2c@12C80000 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+ status = "okay";
+
+ hdmiddc@50 {
+ compatible = "samsung,exynos4210-hdmiddc";
+ reg = <0x50>;
+ };
+ };
+
+ rtc@101E0000 {
+ status = "okay";
+ };
+};
+
+&hdmi {
+ status = "okay";
+ hpd-gpio = <&gpx3 7 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_hpd_irq>;
+
+ vdd_osc-supply = <&ldo7_reg>;
+ vdd_pll-supply = <&ldo6_reg>;
+ vdd-supply = <&ldo6_reg>;
+};
+
+&mfc {
+ samsung,mfc-r = <0x43000000 0x800000>;
+ samsung,mfc-l = <0x51000000 0x800000>;
+};
+
+&mmc_0 {
+ status = "okay";
+ mmc-pwrseq = <&emmc_pwrseq>;
+ broken-cd;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+};
+
+&mmc_2 {
+ status = "okay";
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus1 &sd2_bus4>;
+ bus-width = <4>;
+ cap-sd-highspeed;
+};
+
+&pinctrl_0 {
+ hdmi_hpd_irq: hdmi-hpd-irq {
+ samsung,pins = "gpx3-7";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_1 {
+ emmc_nrst_pin: emmc-nrst {
+ samsung,pins = "gpd1-0";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&usbdrd_dwc3_0 {
+ dr_mode = "host";
+};
+
+&usbdrd_dwc3_1 {
+ dr_mode = "otg";
+};
+
+&i2c_0 {
+ status = "okay";
+
+ /* A15 cluster: VDD_ARM */
+ ina231@40 {
+ compatible = "ti,ina231";
+ reg = <0x40>;
+ shunt-resistor = <10000>;
+ };
+
+ /* memory: VDD_MEM */
+ ina231@41 {
+ compatible = "ti,ina231";
+ reg = <0x41>;
+ shunt-resistor = <10000>;
+ };
+
+ /* GPU: VDD_G3D */
+ ina231@44 {
+ compatible = "ti,ina231";
+ reg = <0x44>;
+ shunt-resistor = <10000>;
+ };
+
+ /* A7 cluster: VDD_KFC */
+ ina231@45 {
+ compatible = "ti,ina231";
+ reg = <0x45>;
+ shunt-resistor = <10000>;
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5440-sd5v1.dts b/arch/arm/boot/dts/exynos5440-sd5v1.dts
new file mode 100644
index 000000000..268609a42
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5440-sd5v1.dts
@@ -0,0 +1,39 @@
+/*
+ * SAMSUNG SD5v1 board device tree source
+ *
+ * Copyright (c) 2013 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.
+*/
+
+/dts-v1/;
+#include "exynos5440.dtsi"
+
+/ {
+ model = "SAMSUNG SD5v1 board based on EXYNOS5440";
+ compatible = "samsung,sd5v1", "samsung,exynos5440", "samsung,exynos5";
+
+ chosen {
+ bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel earlyprintk no_console_suspend mem=2048M@0x80000000 mem=6144M@0x100000000 console=ttySAC0,115200";
+ };
+
+ fixed-rate-clocks {
+ xtal {
+ compatible = "samsung,clock-xtal";
+ clock-frequency = <50000000>;
+ };
+ };
+
+ gmac: ethernet@00230000 {
+ fixed_phy;
+ phy_addr = <1>;
+ };
+
+ spi {
+ status = "disabled";
+ };
+
+};
diff --git a/arch/arm/boot/dts/exynos5440-ssdk5440.dts b/arch/arm/boot/dts/exynos5440-ssdk5440.dts
new file mode 100644
index 000000000..ff55dac6e
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5440-ssdk5440.dts
@@ -0,0 +1,78 @@
+/*
+ * SAMSUNG SSDK5440 board device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+#include "exynos5440.dtsi"
+
+/ {
+ model = "SAMSUNG SSDK5440 board based on EXYNOS5440";
+ compatible = "samsung,ssdk5440", "samsung,exynos5440", "samsung,exynos5";
+
+ chosen {
+ bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel earlyprintk no_console_suspend mem=2048M@0x80000000 mem=6144M@0x100000000 console=ttySAC0,115200";
+ };
+
+ spi_0: spi@D0000 {
+
+ flash: w25q128@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "winbond,w25q128";
+ spi-max-frequency = <15625000>;
+ reg = <0>;
+ controller-data {
+ samsung,spi-feedback-delay = <0>;
+ };
+
+ partition@00000 {
+ label = "BootLoader";
+ reg = <0x60000 0x80000>;
+ read-only;
+ };
+
+ partition@e0000 {
+ label = "Recovery-Kernel";
+ reg = <0xe0000 0x300000>;
+ read-only;
+ };
+
+ partition@3e0000 {
+ label = "CRAM-FS";
+ reg = <0x3e0000 0x700000>;
+ read-only;
+ };
+
+ partition@ae0000 {
+ label = "User-Data";
+ reg = <0xae0000 0x520000>;
+ };
+
+ };
+
+ };
+
+ fixed-rate-clocks {
+ xtal {
+ compatible = "samsung,clock-xtal";
+ clock-frequency = <50000000>;
+ };
+ };
+
+ pcie@290000 {
+ reset-gpio = <&pin_ctrl 5 0>;
+ status = "okay";
+ };
+
+ pcie@2a0000 {
+ reset-gpio = <&pin_ctrl 22 0>;
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi b/arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi
new file mode 100644
index 000000000..7b2fba0ae
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi
@@ -0,0 +1,24 @@
+/*
+ * Device tree sources for Exynos5440 TMU sensor configuration
+ *
+ * Copyright (c) 2014 Lukasz Majewski <l.majewski@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 <dt-bindings/thermal/thermal_exynos.h>
+
+#thermal-sensor-cells = <0>;
+samsung,tmu_gain = <5>;
+samsung,tmu_reference_voltage = <16>;
+samsung,tmu_noise_cancel_mode = <4>;
+samsung,tmu_efuse_value = <0x5d2d>;
+samsung,tmu_min_efuse_value = <16>;
+samsung,tmu_max_efuse_value = <76>;
+samsung,tmu_first_point_trim = <25>;
+samsung,tmu_second_point_trim = <70>;
+samsung,tmu_default_temp_offset = <25>;
+samsung,tmu_cal_type = <TYPE_ONE_POINT_TRIMMING>;
diff --git a/arch/arm/boot/dts/exynos5440-trip-points.dtsi b/arch/arm/boot/dts/exynos5440-trip-points.dtsi
new file mode 100644
index 000000000..356e963ed
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5440-trip-points.dtsi
@@ -0,0 +1,25 @@
+/*
+ * Device tree sources for default Exynos5440 thermal zone definition
+ *
+ * Copyright (c) 2014 Lukasz Majewski <l.majewski@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.
+ *
+ */
+
+polling-delay-passive = <0>;
+polling-delay = <0>;
+trips {
+ cpu-alert-0 {
+ temperature = <100000>; /* millicelsius */
+ hysteresis = <0>; /* millicelsius */
+ type = "active";
+ };
+ cpu-crit-0 {
+ temperature = <105000>; /* millicelsius */
+ hysteresis = <0>; /* millicelsius */
+ type = "critical";
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5440.dtsi b/arch/arm/boot/dts/exynos5440.dtsi
new file mode 100644
index 000000000..59d9416b3
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5440.dtsi
@@ -0,0 +1,323 @@
+/*
+ * SAMSUNG EXYNOS5440 SoC device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <dt-bindings/clock/exynos5440.h>
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "samsung,exynos5440", "samsung,exynos5";
+
+ interrupt-parent = <&gic>;
+
+ aliases {
+ serial0 = &serial_0;
+ serial1 = &serial_1;
+ spi0 = &spi_0;
+ tmuctrl0 = &tmuctrl_0;
+ tmuctrl1 = &tmuctrl_1;
+ tmuctrl2 = &tmuctrl_2;
+ };
+
+ clock: clock-controller@160000 {
+ compatible = "samsung,exynos5440-clock";
+ reg = <0x160000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ gic: interrupt-controller@2E0000 {
+ compatible = "arm,cortex-a15-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x2E1000 0x1000>,
+ <0x2E2000 0x1000>,
+ <0x2E4000 0x2000>,
+ <0x2E6000 0x2000>;
+ interrupts = <1 9 0xf04>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <1>;
+ };
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <2>;
+ };
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <3>;
+ };
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a15-pmu", "arm,cortex-a9-pmu";
+ interrupts = <0 52 4>,
+ <0 53 4>,
+ <0 54 4>,
+ <0 55 4>;
+ };
+
+ timer {
+ compatible = "arm,cortex-a15-timer",
+ "arm,armv7-timer";
+ interrupts = <1 13 0xf08>,
+ <1 14 0xf08>,
+ <1 11 0xf08>,
+ <1 10 0xf08>;
+ clock-frequency = <50000000>;
+ };
+
+ cpufreq@160000 {
+ compatible = "samsung,exynos5440-cpufreq";
+ reg = <0x160000 0x1000>;
+ interrupts = <0 57 0>;
+ operating-points = <
+ /* KHz uV */
+ 1500000 1100000
+ 1400000 1075000
+ 1300000 1050000
+ 1200000 1025000
+ 1100000 1000000
+ 1000000 975000
+ 900000 950000
+ 800000 925000
+ >;
+ };
+
+ serial_0: serial@B0000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0xB0000 0x1000>;
+ interrupts = <0 2 0>;
+ clocks = <&clock CLK_B_125>, <&clock CLK_B_125>;
+ clock-names = "uart", "clk_uart_baud0";
+ };
+
+ serial_1: serial@C0000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0xC0000 0x1000>;
+ interrupts = <0 3 0>;
+ clocks = <&clock CLK_B_125>, <&clock CLK_B_125>;
+ clock-names = "uart", "clk_uart_baud0";
+ };
+
+ spi_0: spi@D0000 {
+ compatible = "samsung,exynos5440-spi";
+ reg = <0xD0000 0x100>;
+ interrupts = <0 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ samsung,spi-src-clk = <0>;
+ num-cs = <1>;
+ clocks = <&clock CLK_B_125>, <&clock CLK_SPI_BAUD>;
+ clock-names = "spi", "spi_busclk0";
+ };
+
+ pin_ctrl: pinctrl {
+ compatible = "samsung,exynos5440-pinctrl";
+ reg = <0xE0000 0x1000>;
+ interrupts = <0 37 0>, <0 38 0>, <0 39 0>, <0 40 0>,
+ <0 41 0>, <0 42 0>, <0 43 0>, <0 44 0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ #gpio-cells = <2>;
+
+ fan: fan {
+ samsung,exynos5440-pin-function = <1>;
+ };
+
+ hdd_led0: hdd_led0 {
+ samsung,exynos5440-pin-function = <2>;
+ };
+
+ hdd_led1: hdd_led1 {
+ samsung,exynos5440-pin-function = <3>;
+ };
+
+ uart1: uart1 {
+ samsung,exynos5440-pin-function = <4>;
+ };
+ };
+
+ i2c@F0000 {
+ compatible = "samsung,exynos5440-i2c";
+ reg = <0xF0000 0x1000>;
+ interrupts = <0 5 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_B_125>;
+ clock-names = "i2c";
+ };
+
+ i2c@100000 {
+ compatible = "samsung,exynos5440-i2c";
+ reg = <0x100000 0x1000>;
+ interrupts = <0 6 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock CLK_B_125>;
+ clock-names = "i2c";
+ };
+
+ watchdog@110000 {
+ compatible = "samsung,s3c2410-wdt";
+ reg = <0x110000 0x1000>;
+ interrupts = <0 1 0>;
+ clocks = <&clock CLK_B_125>;
+ clock-names = "watchdog";
+ };
+
+ gmac: ethernet@00230000 {
+ compatible = "snps,dwmac-3.70a";
+ reg = <0x00230000 0x8000>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 31 4>;
+ interrupt-names = "macirq";
+ phy-mode = "sgmii";
+ clocks = <&clock CLK_GMAC0>;
+ clock-names = "stmmaceth";
+ };
+
+ amba {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "arm,amba-bus";
+ interrupt-parent = <&gic>;
+ ranges;
+ };
+
+ rtc {
+ compatible = "samsung,s3c6410-rtc";
+ reg = <0x130000 0x1000>;
+ interrupts = <0 17 0>, <0 16 0>;
+ clocks = <&clock CLK_B_125>;
+ clock-names = "rtc";
+ };
+
+ tmuctrl_0: tmuctrl@160118 {
+ compatible = "samsung,exynos5440-tmu";
+ reg = <0x160118 0x230>, <0x160368 0x10>;
+ interrupts = <0 58 0>;
+ clocks = <&clock CLK_B_125>;
+ clock-names = "tmu_apbif";
+ #include "exynos5440-tmu-sensor-conf.dtsi"
+ };
+
+ tmuctrl_1: tmuctrl@16011C {
+ compatible = "samsung,exynos5440-tmu";
+ reg = <0x16011C 0x230>, <0x160368 0x10>;
+ interrupts = <0 58 0>;
+ clocks = <&clock CLK_B_125>;
+ clock-names = "tmu_apbif";
+ #include "exynos5440-tmu-sensor-conf.dtsi"
+ };
+
+ tmuctrl_2: tmuctrl@160120 {
+ compatible = "samsung,exynos5440-tmu";
+ reg = <0x160120 0x230>, <0x160368 0x10>;
+ interrupts = <0 58 0>;
+ clocks = <&clock CLK_B_125>;
+ clock-names = "tmu_apbif";
+ #include "exynos5440-tmu-sensor-conf.dtsi"
+ };
+
+ thermal-zones {
+ cpu0_thermal: cpu0-thermal {
+ thermal-sensors = <&tmuctrl_0>;
+ #include "exynos5440-trip-points.dtsi"
+ };
+ cpu1_thermal: cpu1-thermal {
+ thermal-sensors = <&tmuctrl_1>;
+ #include "exynos5440-trip-points.dtsi"
+ };
+ cpu2_thermal: cpu2-thermal {
+ thermal-sensors = <&tmuctrl_2>;
+ #include "exynos5440-trip-points.dtsi"
+ };
+ };
+
+ sata@210000 {
+ compatible = "snps,exynos5440-ahci";
+ reg = <0x210000 0x10000>;
+ interrupts = <0 30 0>;
+ clocks = <&clock CLK_SATA>;
+ clock-names = "sata";
+ };
+
+ ohci@220000 {
+ compatible = "samsung,exynos5440-ohci";
+ reg = <0x220000 0x1000>;
+ interrupts = <0 29 0>;
+ clocks = <&clock CLK_USB>;
+ clock-names = "usbhost";
+ };
+
+ ehci@221000 {
+ compatible = "samsung,exynos5440-ehci";
+ reg = <0x221000 0x1000>;
+ interrupts = <0 29 0>;
+ clocks = <&clock CLK_USB>;
+ clock-names = "usbhost";
+ };
+
+ pcie@290000 {
+ compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
+ reg = <0x290000 0x1000
+ 0x270000 0x1000
+ 0x271000 0x40>;
+ interrupts = <0 20 0>, <0 21 0>, <0 22 0>;
+ clocks = <&clock CLK_PR0_250_O>, <&clock CLK_PB0_250_O>;
+ clock-names = "pcie", "pcie_bus";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x00000800 0 0x40000000 0x40000000 0 0x00001000 /* configuration space */
+ 0x81000000 0 0 0x40001000 0 0x00010000 /* downstream I/O */
+ 0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0x0 0 &gic 53>;
+ num-lanes = <4>;
+ status = "disabled";
+ };
+
+ pcie@2a0000 {
+ compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
+ reg = <0x2a0000 0x1000
+ 0x272000 0x1000
+ 0x271040 0x40>;
+ interrupts = <0 23 0>, <0 24 0>, <0 25 0>;
+ clocks = <&clock CLK_PR1_250_O>, <&clock CLK_PB0_250_O>;
+ clock-names = "pcie", "pcie_bus";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x00000800 0 0x60000000 0x60000000 0 0x00001000 /* configuration space */
+ 0x81000000 0 0 0x60001000 0 0x00010000 /* downstream I/O */
+ 0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0x0 0 &gic 56>;
+ num-lanes = <4>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
new file mode 100644
index 000000000..02eb8b153
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -0,0 +1,1023 @@
+/*
+ * Google Peach Pi Rev 10+ board device tree source
+ *
+ * Copyright (c) 2014 Google, 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.
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clock/maxim,max77802.h>
+#include <dt-bindings/regulator/maxim,max77802.h>
+#include "exynos5800.dtsi"
+
+/ {
+ model = "Google Peach Pi Rev 10+";
+
+ compatible = "google,pi-rev16",
+ "google,pi-rev15", "google,pi-rev14",
+ "google,pi-rev13", "google,pi-rev12",
+ "google,pi-rev11", "google,pi-rev10",
+ "google,pi", "google,peach", "samsung,exynos5800",
+ "samsung,exynos5";
+
+ aliases {
+ /* Assign 20 so we don't get confused w/ builtin ones */
+ i2c20 = "/spi@12d40000/cros-ec@0/i2c-tunnel";
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 0 1000000 0>;
+ brightness-levels = <0 100 500 1000 1500 2000 2500 2800>;
+ default-brightness-level = <7>;
+ enable-gpios = <&gpx2 2 GPIO_ACTIVE_HIGH>;
+ power-supply = <&tps65090_fet1>;
+ pinctrl-0 = <&pwm0_out>;
+ pinctrl-names = "default";
+ };
+
+ chosen {
+ stdout-path = "serial3:115200n8";
+ };
+
+ fixed-rate-clocks {
+ oscclk {
+ compatible = "samsung,exynos5420-oscclk";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&power_key_irq &lid_irq>;
+
+ power {
+ label = "Power";
+ gpios = <&gpx1 2 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ gpio-key,wakeup;
+ };
+
+ lid-switch {
+ label = "Lid";
+ gpios = <&gpx3 4 GPIO_ACTIVE_LOW>;
+ linux,input-type = <5>; /* EV_SW */
+ linux,code = <0>; /* SW_LID */
+ debounce-interval = <1>;
+ gpio-key,wakeup;
+ };
+
+ };
+
+ memory {
+ reg = <0x20000000 0x80000000>;
+ };
+
+ sound {
+ compatible = "google,snow-audio-max98091";
+
+ samsung,model = "Peach-Pi-I2S-MAX98091";
+ samsung,i2s-controller = <&i2s0>;
+ samsung,audio-codec = <&max98091>;
+ };
+
+ usb300_vbus_reg: regulator-usb300 {
+ compatible = "regulator-fixed";
+ regulator-name = "P5.0V_USB3CON0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gph0 0 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb300_vbus_en>;
+ enable-active-high;
+ };
+
+ usb301_vbus_reg: regulator-usb301 {
+ compatible = "regulator-fixed";
+ regulator-name = "P5.0V_USB3CON1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gph0 1 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb301_vbus_en>;
+ enable-active-high;
+ };
+
+ vbat: fixed-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vbat-supply";
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ panel: panel {
+ compatible = "auo,b133htn01";
+ power-supply = <&tps65090_fet6>;
+ backlight = <&backlight>;
+ };
+
+ mmc1_pwrseq: mmc1_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpx0 0 GPIO_ACTIVE_LOW>; /* WIFI_EN */
+ clocks = <&max77802 MAX77802_CLK_32K_CP>;
+ clock-names = "ext_clock";
+ };
+};
+
+&adc {
+ status = "okay";
+ vdd-supply = <&ldo9_reg>;
+};
+
+&dp {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&dp_hpd_gpio>;
+ samsung,color-space = <0>;
+ samsung,dynamic-range = <0>;
+ samsung,ycbcr-coeff = <0>;
+ samsung,color-depth = <1>;
+ samsung,link-rate = <0x0a>;
+ samsung,lane-count = <2>;
+ samsung,hpd-gpio = <&gpx2 6 0>;
+ panel = <&panel>;
+};
+
+&fimd {
+ status = "okay";
+ samsung,invert-vclk;
+};
+
+&hdmi {
+ status = "okay";
+ hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_hpd_irq>;
+ ddc = <&i2c_2>;
+
+ hdmi-en-supply = <&tps65090_fet7>;
+ vdd-supply = <&ldo8_reg>;
+ vdd_osc-supply = <&ldo10_reg>;
+ vdd_pll-supply = <&ldo8_reg>;
+};
+
+&hsi2c_4 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ max77802: max77802-pmic@9 {
+ compatible = "maxim,max77802";
+ interrupt-parent = <&gpx3>;
+ interrupts = <1 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&max77802_irq>, <&pmic_selb>,
+ <&pmic_dvs_1>, <&pmic_dvs_2>, <&pmic_dvs_3>;
+ wakeup-source;
+ reg = <0x9>;
+ #clock-cells = <1>;
+
+ inb1-supply = <&tps65090_dcdc2>;
+ inb2-supply = <&tps65090_dcdc1>;
+ inb3-supply = <&tps65090_dcdc2>;
+ inb4-supply = <&tps65090_dcdc2>;
+ inb5-supply = <&tps65090_dcdc1>;
+ inb6-supply = <&tps65090_dcdc2>;
+ inb7-supply = <&tps65090_dcdc1>;
+ inb8-supply = <&tps65090_dcdc1>;
+ inb9-supply = <&tps65090_dcdc1>;
+ inb10-supply = <&tps65090_dcdc1>;
+
+ inl1-supply = <&buck5_reg>;
+ inl2-supply = <&buck7_reg>;
+ inl3-supply = <&buck9_reg>;
+ inl4-supply = <&buck9_reg>;
+ inl5-supply = <&buck9_reg>;
+ inl6-supply = <&tps65090_dcdc2>;
+ inl7-supply = <&buck9_reg>;
+ inl9-supply = <&tps65090_dcdc2>;
+ inl10-supply = <&buck7_reg>;
+
+ regulators {
+ buck1_reg: BUCK1 {
+ regulator-name = "vdd_mif";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "vdd_int";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "vdd_g3d";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "vdd_1v2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck6_reg: BUCK6 {
+ regulator-name = "vdd_kfc";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck7_reg: BUCK7 {
+ regulator-name = "vdd_1v35";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ buck8_reg: BUCK8 {
+ regulator-name = "vdd_emmc";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck9_reg: BUCK9 {
+ regulator-name = "vdd_2v";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ buck10_reg: BUCK10 {
+ regulator-name = "vdd_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo1_reg: LDO1 {
+ regulator-name = "vdd_1v0";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "vdd_1v2_2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "vdd_1v8_3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
+ };
+
+ vqmmc_sdcard: ldo4_reg: LDO4 {
+ regulator-name = "vdd_sd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "vdd_1v8_5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "vdd_1v8_6";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "vdd_1v8_7";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "vdd_ldo8";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "vdd_ldo9";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "vdd_ldo10";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "vdd_ldo11";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "vdd_ldo12";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "vdd_ldo13";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "vdd_ldo14";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "vdd_ldo15";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "vdd_g3ds";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo18_reg: LDO18 {
+ regulator-name = "ldo_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo19_reg: LDO19 {
+ regulator-name = "ldo_19";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo20_reg: LDO20 {
+ regulator-name = "ldo_20";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo21_reg: LDO21 {
+ regulator-name = "ldo_21";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo23_reg: LDO23 {
+ regulator-name = "ldo_23";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ ldo24_reg: LDO24 {
+ regulator-name = "ldo_24";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo25_reg: LDO25 {
+ regulator-name = "ldo_25";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo26_reg: LDO26 {
+ regulator-name = "ldo_26";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo27_reg: LDO27 {
+ regulator-name = "ldo_27";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo28_reg: LDO28 {
+ regulator-name = "ldo_28";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo29_reg: LDO29 {
+ regulator-name = "ldo_29";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo30_reg: LDO30 {
+ regulator-name = "vdd_mifs";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo32_reg: LDO32 {
+ regulator-name = "ldo_32";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ ldo33_reg: LDO33 {
+ regulator-name = "ldo_33";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo34_reg: LDO34 {
+ regulator-name = "ldo_34";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ ldo35_reg: LDO35 {
+ regulator-name = "ldo_35";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+ };
+ };
+};
+
+&hsi2c_7 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ max98091: codec@10 {
+ compatible = "maxim,max98091";
+ reg = <0x10>;
+ interrupts = <2 0>;
+ interrupt-parent = <&gpx0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&max98091_irq>;
+ clocks = <&pmu_system_controller 0>;
+ clock-names = "mclk";
+ };
+
+ light-sensor@44 {
+ compatible = "isil,isl29018";
+ reg = <0x44>;
+ vcc-supply = <&tps65090_fet5>;
+ };
+};
+
+&hsi2c_8 {
+ status = "okay";
+ clock-frequency = <333000>;
+ /* Atmel mXT540S */
+ trackpad@4b {
+ compatible = "atmel,maxtouch";
+ reg = <0x4b>;
+ interrupt-parent = <&gpx1>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+ wakeup-source;
+ pinctrl-names = "default";
+ pinctrl-0 = <&trackpad_irq>;
+ linux,gpio-keymap = <KEY_RESERVED
+ KEY_RESERVED
+ KEY_RESERVED /* GPIO 0 */
+ KEY_RESERVED /* GPIO 1 */
+ BTN_LEFT /* GPIO 2 */
+ KEY_RESERVED>; /* GPIO 3 */
+ };
+};
+
+&hsi2c_9 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ tpm@20 {
+ compatible = "infineon,slb9645tt";
+ reg = <0x20>;
+
+ /* Unused irq; but still need to configure the pins */
+ pinctrl-names = "default";
+ pinctrl-0 = <&tpm_irq>;
+ };
+};
+
+&i2c_2 {
+ status = "okay";
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+ samsung,i2c-slave-addr = <0x50>;
+};
+
+&i2s0 {
+ status = "okay";
+};
+
+&mmc_0 {
+ status = "okay";
+ num-slots = <1>;
+ broken-cd;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ cap-mmc-highspeed;
+ non-removable;
+ card-detect-delay = <200>;
+ clock-frequency = <800000000>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ samsung,dw-mshc-hs400-timing = <0 2>;
+ samsung,read-strobe-delay = <90>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8 &sd0_rclk>;
+ bus-width = <8>;
+};
+
+&mmc_1 {
+ status = "okay";
+ num-slots = <1>;
+ broken-cd;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ card-detect-delay = <200>;
+ clock-frequency = <400000000>;
+ samsung,dw-mshc-ciu-div = <1>;
+ samsung,dw-mshc-sdr-timing = <0 1>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_int>, <&sd1_bus1>,
+ <&sd1_bus4>, <&sd1_bus8>, <&wifi_en>;
+ bus-width = <4>;
+ cap-sd-highspeed;
+ mmc-pwrseq = <&mmc1_pwrseq>;
+ vqmmc-supply = <&buck10_reg>;
+};
+
+&mmc_2 {
+ status = "okay";
+ num-slots = <1>;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ clock-frequency = <400000000>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus1 &sd2_bus4>;
+ bus-width = <4>;
+};
+
+
+&pinctrl_0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mask_tpm_reset>;
+
+ wifi_en: wifi-en {
+ samsung,pins = "gpx0-0";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ max98091_irq: max98091-irq {
+ samsung,pins = "gpx0-2";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ /* We need GPX0_6 to be low at sleep time; just keep it low always */
+ mask_tpm_reset: mask-tpm-reset {
+ samsung,pins = "gpx0-6";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ samsung,pin-val = <0>;
+ };
+
+ tpm_irq: tpm-irq {
+ samsung,pins = "gpx1-0";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ trackpad_irq: trackpad-irq {
+ samsung,pins = "gpx1-1";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ power_key_irq: power-key-irq {
+ samsung,pins = "gpx1-2";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ ec_irq: ec-irq {
+ samsung,pins = "gpx1-5";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ tps65090_irq: tps65090-irq {
+ samsung,pins = "gpx2-5";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ dp_hpd_gpio: dp_hpd_gpio {
+ samsung,pins = "gpx2-6";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ max77802_irq: max77802-irq {
+ samsung,pins = "gpx3-1";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lid_irq: lid-irq {
+ samsung,pins = "gpx3-4";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ hdmi_hpd_irq: hdmi-hpd-irq {
+ samsung,pins = "gpx3-7";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+
+ pmic_dvs_1: pmic-dvs-1 {
+ samsung,pins = "gpy7-6";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_1 {
+ /* Adjust WiFi drive strengths lower for EMI */
+ sd1_clk: sd1-clk {
+ samsung,pin-drv = <2>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ samsung,pin-drv = <2>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ samsung,pin-drv = <2>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ samsung,pin-drv = <2>;
+ };
+
+ sd1_bus8: sd1-bus-width8 {
+ samsung,pin-drv = <2>;
+ };
+};
+
+&pinctrl_2 {
+ pmic_dvs_2: pmic-dvs-2 {
+ samsung,pins = "gpj4-2";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pmic_dvs_3: pmic-dvs-3 {
+ samsung,pins = "gpj4-3";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_3 {
+ /* Drive SPI lines at x2 for better integrity */
+ spi2-bus {
+ samsung,pin-drv = <2>;
+ };
+
+ /* Drive SPI chip select at x2 for better integrity */
+ ec_spi_cs: ec-spi-cs {
+ samsung,pins = "gpb1-2";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+
+ usb300_vbus_en: usb300-vbus-en {
+ samsung,pins = "gph0-0";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ usb301_vbus_en: usb301-vbus-en {
+ samsung,pins = "gph0-1";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pmic_selb: pmic-selb {
+ samsung,pins = "gph0-2", "gph0-3", "gph0-4", "gph0-5",
+ "gph0-6";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&rtc {
+ status = "okay";
+ clocks = <&clock CLK_RTC>, <&max77802 MAX77802_CLK_32K_AP>;
+ clock-names = "rtc", "rtc_src";
+};
+
+&spi_2 {
+ status = "okay";
+ num-cs = <1>;
+ samsung,spi-src-clk = <0>;
+ cs-gpios = <&gpb1 2 0>;
+
+ cros_ec: cros-ec@0 {
+ compatible = "google,cros-ec-spi";
+ interrupt-parent = <&gpx1>;
+ interrupts = <5 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ec_spi_cs &ec_irq>;
+ reg = <0>;
+ spi-max-frequency = <3125000>;
+
+ controller-data {
+ samsung,spi-feedback-delay = <1>;
+ };
+
+ i2c-tunnel {
+ compatible = "google,cros-ec-i2c-tunnel";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ google,remote-bus = <0>;
+
+ battery: sbs-battery@b {
+ compatible = "sbs,sbs-battery";
+ reg = <0xb>;
+ sbs,poll-retry-count = <1>;
+ sbs,i2c-retry-count = <2>;
+ };
+
+ power-regulator@48 {
+ compatible = "ti,tps65090";
+ reg = <0x48>;
+
+ /*
+ * Config irq to disable internal pulls
+ * even though we run in polling mode.
+ */
+ pinctrl-names = "default";
+ pinctrl-0 = <&tps65090_irq>;
+
+ vsys1-supply = <&vbat>;
+ vsys2-supply = <&vbat>;
+ vsys3-supply = <&vbat>;
+ infet1-supply = <&vbat>;
+ infet2-supply = <&tps65090_dcdc1>;
+ infet3-supply = <&tps65090_dcdc2>;
+ infet4-supply = <&tps65090_dcdc2>;
+ infet5-supply = <&tps65090_dcdc2>;
+ infet6-supply = <&tps65090_dcdc2>;
+ infet7-supply = <&tps65090_dcdc1>;
+ vsys-l1-supply = <&vbat>;
+ vsys-l2-supply = <&vbat>;
+
+ regulators {
+ tps65090_dcdc1: dcdc1 {
+ ti,enable-ext-control;
+ };
+ tps65090_dcdc2: dcdc2 {
+ ti,enable-ext-control;
+ };
+ tps65090_dcdc3: dcdc3 {
+ ti,enable-ext-control;
+ };
+ tps65090_fet1: fet1 {
+ regulator-name = "vcd_led";
+ };
+ tps65090_fet2: fet2 {
+ regulator-name = "video_mid";
+ regulator-always-on;
+ };
+ tps65090_fet3: fet3 {
+ regulator-name = "wwan_r";
+ regulator-always-on;
+ };
+ tps65090_fet4: fet4 {
+ regulator-name = "sdcard";
+ regulator-always-on;
+ };
+ tps65090_fet5: fet5 {
+ regulator-name = "camout";
+ regulator-always-on;
+ };
+ tps65090_fet6: fet6 {
+ regulator-name = "lcd_vdd";
+ };
+ tps65090_fet7: fet7 {
+ regulator-name = "video_mid_1a";
+ regulator-always-on;
+ };
+ tps65090_ldo1: ldo1 {
+ };
+ tps65090_ldo2: ldo2 {
+ };
+ };
+
+ charger {
+ compatible = "ti,tps65090-charger";
+ };
+ };
+ };
+ };
+};
+
+&uart_3 {
+ status = "okay";
+};
+
+&usbdrd_dwc3_0 {
+ dr_mode = "host";
+};
+
+&usbdrd_dwc3_1 {
+ dr_mode = "host";
+};
+
+&usbdrd_phy0 {
+ vbus-supply = <&usb300_vbus_reg>;
+};
+
+&usbdrd_phy1 {
+ vbus-supply = <&usb301_vbus_reg>;
+};
+
+/*
+ * Use longest HW watchdog in SoC (32 seconds) since the hardware
+ * watchdog provides no debugging information (compared to soft/hard
+ * lockup detectors) and so should be last resort.
+ */
+&watchdog {
+ timeout-sec = <32>;
+};
+
+#include "cros-ec-keyboard.dtsi"
+#include "cros-adc-thermistors.dtsi"
diff --git a/arch/arm/boot/dts/exynos5800.dtsi b/arch/arm/boot/dts/exynos5800.dtsi
new file mode 100644
index 000000000..c0bb3563c
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5800.dtsi
@@ -0,0 +1,28 @@
+/*
+ * SAMSUNG EXYNOS5800 SoC device tree source
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * SAMSUNG EXYNOS5800 SoC device nodes are listed in this file.
+ * EXYNOS5800 based board files can include this file and provide
+ * values for board specfic bindings.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "exynos5420.dtsi"
+
+/ {
+ compatible = "samsung,exynos5800", "samsung,exynos5";
+};
+
+&clock {
+ compatible = "samsung,exynos5800-clock";
+};
+
+&mfc {
+ compatible = "samsung,mfc-v8";
+};
diff --git a/arch/arm/boot/dts/ge863-pro3.dtsi b/arch/arm/boot/dts/ge863-pro3.dtsi
new file mode 100644
index 000000000..0d0e62489
--- /dev/null
+++ b/arch/arm/boot/dts/ge863-pro3.dtsi
@@ -0,0 +1,56 @@
+/*
+ * ge863_pro3.dtsi - Device Tree file for Telit GE863-PRO3
+ *
+ * Copyright (C) 2012 Telit,
+ * 2012 Fabio Porcedda <fabio.porcedda@gmail.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include "at91sam9260.dtsi"
+
+/ {
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <6000000>;
+ };
+
+ main_xtal {
+ clock-frequency = <6000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ status = "okay";
+
+ boot@0 {
+ label = "boot";
+ reg = <0x0 0x7c0000>;
+ };
+
+ root@07c0000 {
+ label = "root";
+ reg = <0x7c0000 0x7840000>;
+ };
+ };
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=ubi0:rootfs ubi.mtd=1 rootfstype=ubifs";
+ };
+};
diff --git a/arch/arm/boot/dts/hi3620-hi4511.dts b/arch/arm/boot/dts/hi3620-hi4511.dts
new file mode 100644
index 000000000..fe623928f
--- /dev/null
+++ b/arch/arm/boot/dts/hi3620-hi4511.dts
@@ -0,0 +1,649 @@
+/*
+ * Copyright (C) 2012-2013 Linaro Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@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
+ * publishhed by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+#include "hi3620.dtsi"
+
+/ {
+ model = "Hisilicon Hi4511 Development Board";
+ compatible = "hisilicon,hi3620-hi4511";
+
+ chosen {
+ bootargs = "console=ttyAMA0,115200 root=/dev/ram0 earlyprintk";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x40000000 0x20000000>;
+ };
+
+ amba {
+ dual_timer0: dual_timer@800000 {
+ status = "ok";
+ };
+
+ uart0: uart@b00000 { /* console */
+ pinctrl-names = "default", "idle";
+ pinctrl-0 = <&uart0_pmx_func &uart0_cfg_func>;
+ pinctrl-1 = <&uart0_pmx_idle &uart0_cfg_idle>;
+ status = "ok";
+ };
+
+ uart1: uart@b01000 { /* modem */
+ pinctrl-names = "default", "idle";
+ pinctrl-0 = <&uart1_pmx_func &uart1_cfg_func>;
+ pinctrl-1 = <&uart1_pmx_idle &uart1_cfg_idle>;
+ status = "ok";
+ };
+
+ uart2: uart@b02000 { /* audience */
+ pinctrl-names = "default", "idle";
+ pinctrl-0 = <&uart2_pmx_func &uart2_cfg_func>;
+ pinctrl-1 = <&uart2_pmx_idle &uart2_cfg_idle>;
+ status = "ok";
+ };
+
+ uart3: uart@b03000 {
+ pinctrl-names = "default", "idle";
+ pinctrl-0 = <&uart3_pmx_func &uart3_cfg_func>;
+ pinctrl-1 = <&uart3_pmx_idle &uart3_cfg_idle>;
+ status = "ok";
+ };
+
+ uart4: uart@b04000 {
+ pinctrl-names = "default", "idle";
+ pinctrl-0 = <&uart4_pmx_func &uart4_cfg_func>;
+ pinctrl-1 = <&uart4_pmx_idle &uart4_cfg_func>;
+ status = "ok";
+ };
+
+ pmx0: pinmux@803000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&board_pmx_pins>;
+
+ board_pmx_pins: board_pmx_pins {
+ pinctrl-single,pins = <
+ 0x008 0x0 /* GPIO -- eFUSE_DOUT */
+ 0x100 0x0 /* USIM_CLK & USIM_DATA (IOMG63) */
+ >;
+ };
+ uart0_pmx_func: uart0_pmx_func {
+ pinctrl-single,pins = <
+ 0x0f0 0x0
+ 0x0f4 0x0 /* UART0_RX & UART0_TX */
+ >;
+ };
+ uart0_pmx_idle: uart0_pmx_idle {
+ pinctrl-single,pins = <
+ /*0x0f0 0x1*/ /* UART0_CTS & UART0_RTS */
+ 0x0f4 0x1 /* UART0_RX & UART0_TX */
+ >;
+ };
+ uart1_pmx_func: uart1_pmx_func {
+ pinctrl-single,pins = <
+ 0x0f8 0x0 /* UART1_CTS & UART1_RTS (IOMG61) */
+ 0x0fc 0x0 /* UART1_RX & UART1_TX (IOMG62) */
+ >;
+ };
+ uart1_pmx_idle: uart1_pmx_idle {
+ pinctrl-single,pins = <
+ 0x0f8 0x1 /* GPIO (IOMG61) */
+ 0x0fc 0x1 /* GPIO (IOMG62) */
+ >;
+ };
+ uart2_pmx_func: uart2_pmx_func {
+ pinctrl-single,pins = <
+ 0x104 0x2 /* UART2_RXD (IOMG96) */
+ 0x108 0x2 /* UART2_TXD (IOMG64) */
+ >;
+ };
+ uart2_pmx_idle: uart2_pmx_idle {
+ pinctrl-single,pins = <
+ 0x104 0x1 /* GPIO (IOMG96) */
+ 0x108 0x1 /* GPIO (IOMG64) */
+ >;
+ };
+ uart3_pmx_func: uart3_pmx_func {
+ pinctrl-single,pins = <
+ 0x160 0x2 /* UART3_CTS & UART3_RTS (IOMG85) */
+ 0x164 0x2 /* UART3_RXD & UART3_TXD (IOMG86) */
+ >;
+ };
+ uart3_pmx_idle: uart3_pmx_idle {
+ pinctrl-single,pins = <
+ 0x160 0x1 /* GPIO (IOMG85) */
+ 0x164 0x1 /* GPIO (IOMG86) */
+ >;
+ };
+ uart4_pmx_func: uart4_pmx_func {
+ pinctrl-single,pins = <
+ 0x168 0x0 /* UART4_CTS & UART4_RTS (IOMG87) */
+ 0x16c 0x0 /* UART4_RXD (IOMG88) */
+ 0x170 0x0 /* UART4_TXD (IOMG93) */
+ >;
+ };
+ uart4_pmx_idle: uart4_pmx_idle {
+ pinctrl-single,pins = <
+ 0x168 0x1 /* GPIO (IOMG87) */
+ 0x16c 0x1 /* GPIO (IOMG88) */
+ 0x170 0x1 /* GPIO (IOMG93) */
+ >;
+ };
+ i2c0_pmx_func: i2c0_pmx_func {
+ pinctrl-single,pins = <
+ 0x0b4 0x0 /* I2C0_SCL & I2C0_SDA (IOMG45) */
+ >;
+ };
+ i2c0_pmx_idle: i2c0_pmx_idle {
+ pinctrl-single,pins = <
+ 0x0b4 0x1 /* GPIO (IOMG45) */
+ >;
+ };
+ i2c1_pmx_func: i2c1_pmx_func {
+ pinctrl-single,pins = <
+ 0x0b8 0x0 /* I2C1_SCL & I2C1_SDA (IOMG46) */
+ >;
+ };
+ i2c1_pmx_idle: i2c1_pmx_idle {
+ pinctrl-single,pins = <
+ 0x0b8 0x1 /* GPIO (IOMG46) */
+ >;
+ };
+ i2c2_pmx_func: i2c2_pmx_func {
+ pinctrl-single,pins = <
+ 0x068 0x0 /* I2C2_SCL (IOMG26) */
+ 0x06c 0x0 /* I2C2_SDA (IOMG27) */
+ >;
+ };
+ i2c2_pmx_idle: i2c2_pmx_idle {
+ pinctrl-single,pins = <
+ 0x068 0x1 /* GPIO (IOMG26) */
+ 0x06c 0x1 /* GPIO (IOMG27) */
+ >;
+ };
+ i2c3_pmx_func: i2c3_pmx_func {
+ pinctrl-single,pins = <
+ 0x050 0x2 /* I2C3_SCL (IOMG20) */
+ 0x054 0x2 /* I2C3_SDA (IOMG21) */
+ >;
+ };
+ i2c3_pmx_idle: i2c3_pmx_idle {
+ pinctrl-single,pins = <
+ 0x050 0x1 /* GPIO (IOMG20) */
+ 0x054 0x1 /* GPIO (IOMG21) */
+ >;
+ };
+ spi0_pmx_func: spi0_pmx_func {
+ pinctrl-single,pins = <
+ 0x0d4 0x0 /* SPI0_CLK/SPI0_DI/SPI0_DO (IOMG53) */
+ 0x0d8 0x0 /* SPI0_CS0 (IOMG54) */
+ 0x0dc 0x0 /* SPI0_CS1 (IOMG55) */
+ 0x0e0 0x0 /* SPI0_CS2 (IOMG56) */
+ 0x0e4 0x0 /* SPI0_CS3 (IOMG57) */
+ >;
+ };
+ spi0_pmx_idle: spi0_pmx_idle {
+ pinctrl-single,pins = <
+ 0x0d4 0x1 /* GPIO (IOMG53) */
+ 0x0d8 0x1 /* GPIO (IOMG54) */
+ 0x0dc 0x1 /* GPIO (IOMG55) */
+ 0x0e0 0x1 /* GPIO (IOMG56) */
+ 0x0e4 0x1 /* GPIO (IOMG57) */
+ >;
+ };
+ spi1_pmx_func: spi1_pmx_func {
+ pinctrl-single,pins = <
+ 0x184 0x0 /* SPI1_CLK/SPI1_DI (IOMG98) */
+ 0x0e8 0x0 /* SPI1_DO (IOMG58) */
+ 0x0ec 0x0 /* SPI1_CS (IOMG95) */
+ >;
+ };
+ spi1_pmx_idle: spi1_pmx_idle {
+ pinctrl-single,pins = <
+ 0x184 0x1 /* GPIO (IOMG98) */
+ 0x0e8 0x1 /* GPIO (IOMG58) */
+ 0x0ec 0x1 /* GPIO (IOMG95) */
+ >;
+ };
+ kpc_pmx_func: kpc_pmx_func {
+ pinctrl-single,pins = <
+ 0x12c 0x0 /* KEY_IN0 (IOMG73) */
+ 0x130 0x0 /* KEY_IN1 (IOMG74) */
+ 0x134 0x0 /* KEY_IN2 (IOMG75) */
+ 0x10c 0x0 /* KEY_OUT0 (IOMG65) */
+ 0x110 0x0 /* KEY_OUT1 (IOMG66) */
+ 0x114 0x0 /* KEY_OUT2 (IOMG67) */
+ >;
+ };
+ kpc_pmx_idle: kpc_pmx_idle {
+ pinctrl-single,pins = <
+ 0x12c 0x1 /* GPIO (IOMG73) */
+ 0x130 0x1 /* GPIO (IOMG74) */
+ 0x134 0x1 /* GPIO (IOMG75) */
+ 0x10c 0x1 /* GPIO (IOMG65) */
+ 0x110 0x1 /* GPIO (IOMG66) */
+ 0x114 0x1 /* GPIO (IOMG67) */
+ >;
+ };
+ gpio_key_func: gpio_key_func {
+ pinctrl-single,pins = <
+ 0x10c 0x1 /* KEY_OUT0/GPIO (IOMG65) */
+ 0x130 0x1 /* KEY_IN1/GPIO (IOMG74) */
+ >;
+ };
+ emmc_pmx_func: emmc_pmx_func {
+ pinctrl-single,pins = <
+ 0x030 0x2 /* eMMC_CMD/eMMC_CLK (IOMG12) */
+ 0x018 0x0 /* NAND_CS3_N (IOMG6) */
+ 0x024 0x0 /* NAND_BUSY2_N (IOMG8) */
+ 0x028 0x0 /* NAND_BUSY3_N (IOMG9) */
+ 0x02c 0x2 /* eMMC_DATA[0:7] (IOMG10) */
+ >;
+ };
+ emmc_pmx_idle: emmc_pmx_idle {
+ pinctrl-single,pins = <
+ 0x030 0x0 /* GPIO (IOMG12) */
+ 0x018 0x1 /* GPIO (IOMG6) */
+ 0x024 0x1 /* GPIO (IOMG8) */
+ 0x028 0x1 /* GPIO (IOMG9) */
+ 0x02c 0x1 /* GPIO (IOMG10) */
+ >;
+ };
+ sd_pmx_func: sd_pmx_func {
+ pinctrl-single,pins = <
+ 0x0bc 0x0 /* SD_CLK/SD_CMD/SD_DATA0/SD_DATA1/SD_DATA2 (IOMG47) */
+ 0x0c0 0x0 /* SD_DATA3 (IOMG48) */
+ >;
+ };
+ sd_pmx_idle: sd_pmx_idle {
+ pinctrl-single,pins = <
+ 0x0bc 0x1 /* GPIO (IOMG47) */
+ 0x0c0 0x1 /* GPIO (IOMG48) */
+ >;
+ };
+ nand_pmx_func: nand_pmx_func {
+ pinctrl-single,pins = <
+ 0x00c 0x0 /* NAND_ALE/NAND_CLE/.../NAND_DATA[0:7] (IOMG3) */
+ 0x010 0x0 /* NAND_CS1_N (IOMG4) */
+ 0x014 0x0 /* NAND_CS2_N (IOMG5) */
+ 0x018 0x0 /* NAND_CS3_N (IOMG6) */
+ 0x01c 0x0 /* NAND_BUSY0_N (IOMG94) */
+ 0x020 0x0 /* NAND_BUSY1_N (IOMG7) */
+ 0x024 0x0 /* NAND_BUSY2_N (IOMG8) */
+ 0x028 0x0 /* NAND_BUSY3_N (IOMG9) */
+ 0x02c 0x0 /* NAND_DATA[8:15] (IOMG10) */
+ >;
+ };
+ nand_pmx_idle: nand_pmx_idle {
+ pinctrl-single,pins = <
+ 0x00c 0x1 /* GPIO (IOMG3) */
+ 0x010 0x1 /* GPIO (IOMG4) */
+ 0x014 0x1 /* GPIO (IOMG5) */
+ 0x018 0x1 /* GPIO (IOMG6) */
+ 0x01c 0x1 /* GPIO (IOMG94) */
+ 0x020 0x1 /* GPIO (IOMG7) */
+ 0x024 0x1 /* GPIO (IOMG8) */
+ 0x028 0x1 /* GPIO (IOMG9) */
+ 0x02c 0x1 /* GPIO (IOMG10) */
+ >;
+ };
+ sdio_pmx_func: sdio_pmx_func {
+ pinctrl-single,pins = <
+ 0x0c4 0x0 /* SDIO_CLK/SDIO_CMD/SDIO_DATA[0:3] (IOMG49) */
+ >;
+ };
+ sdio_pmx_idle: sdio_pmx_idle {
+ pinctrl-single,pins = <
+ 0x0c4 0x1 /* GPIO (IOMG49) */
+ >;
+ };
+ audio_out_pmx_func: audio_out_pmx_func {
+ pinctrl-single,pins = <
+ 0x0f0 0x1 /* GPIO (IOMG59), audio spk & earphone */
+ >;
+ };
+ };
+
+ pmx1: pinmux@803800 {
+ pinctrl-names = "default";
+ pinctrl-0 = < &board_pu_pins &board_pd_pins &board_pd_ps_pins
+ &board_np_pins &board_ps_pins &kpc_cfg_func
+ &audio_out_cfg_func>;
+ board_pu_pins: board_pu_pins {
+ pinctrl-single,pins = <
+ 0x014 0 /* GPIO_158 (IOCFG2) */
+ 0x018 0 /* GPIO_159 (IOCFG3) */
+ 0x01c 0 /* BOOT_MODE0 (IOCFG4) */
+ 0x020 0 /* BOOT_MODE1 (IOCFG5) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 0 2>;
+ pinctrl-single,bias-pullup = <1 1 0 1>;
+ };
+ board_pd_pins: board_pd_pins {
+ pinctrl-single,pins = <
+ 0x038 0 /* eFUSE_DOUT (IOCFG11) */
+ 0x150 0 /* ISP_GPIO8 (IOCFG93) */
+ 0x154 0 /* ISP_GPIO9 (IOCFG94) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ };
+ board_pd_ps_pins: board_pd_ps_pins {
+ pinctrl-single,pins = <
+ 0x2d8 0 /* CLK_OUT0 (IOCFG190) */
+ 0x004 0 /* PMU_SPI_DATA (IOCFG192) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ board_np_pins: board_np_pins {
+ pinctrl-single,pins = <
+ 0x24c 0 /* KEYPAD_OUT7 (IOCFG155) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ };
+ board_ps_pins: board_ps_pins {
+ pinctrl-single,pins = <
+ 0x000 0 /* PMU_SPI_CLK (IOCFG191) */
+ 0x008 0 /* PMU_SPI_CS_N (IOCFG193) */
+ >;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ uart0_cfg_func: uart0_cfg_func {
+ pinctrl-single,pins = <
+ 0x208 0 /* UART0_RXD (IOCFG138) */
+ 0x20c 0 /* UART0_TXD (IOCFG139) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ };
+ uart0_cfg_idle: uart0_cfg_idle {
+ pinctrl-single,pins = <
+ 0x208 0 /* UART0_RXD (IOCFG138) */
+ 0x20c 0 /* UART0_TXD (IOCFG139) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ };
+ uart1_cfg_func: uart1_cfg_func {
+ pinctrl-single,pins = <
+ 0x210 0 /* UART1_CTS (IOCFG140) */
+ 0x214 0 /* UART1_RTS (IOCFG141) */
+ 0x218 0 /* UART1_RXD (IOCFG142) */
+ 0x21c 0 /* UART1_TXD (IOCFG143) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ };
+ uart1_cfg_idle: uart1_cfg_idle {
+ pinctrl-single,pins = <
+ 0x210 0 /* UART1_CTS (IOCFG140) */
+ 0x214 0 /* UART1_RTS (IOCFG141) */
+ 0x218 0 /* UART1_RXD (IOCFG142) */
+ 0x21c 0 /* UART1_TXD (IOCFG143) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ };
+ uart2_cfg_func: uart2_cfg_func {
+ pinctrl-single,pins = <
+ 0x220 0 /* UART2_CTS (IOCFG144) */
+ 0x224 0 /* UART2_RTS (IOCFG145) */
+ 0x228 0 /* UART2_RXD (IOCFG146) */
+ 0x22c 0 /* UART2_TXD (IOCFG147) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ };
+ uart2_cfg_idle: uart2_cfg_idle {
+ pinctrl-single,pins = <
+ 0x220 0 /* GPIO (IOCFG144) */
+ 0x224 0 /* GPIO (IOCFG145) */
+ 0x228 0 /* GPIO (IOCFG146) */
+ 0x22c 0 /* GPIO (IOCFG147) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ };
+ uart3_cfg_func: uart3_cfg_func {
+ pinctrl-single,pins = <
+ 0x294 0 /* UART3_CTS (IOCFG173) */
+ 0x298 0 /* UART3_RTS (IOCFG174) */
+ 0x29c 0 /* UART3_RXD (IOCFG175) */
+ 0x2a0 0 /* UART3_TXD (IOCFG176) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ };
+ uart3_cfg_idle: uart3_cfg_idle {
+ pinctrl-single,pins = <
+ 0x294 0 /* UART3_CTS (IOCFG173) */
+ 0x298 0 /* UART3_RTS (IOCFG174) */
+ 0x29c 0 /* UART3_RXD (IOCFG175) */
+ 0x2a0 0 /* UART3_TXD (IOCFG176) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ };
+ uart4_cfg_func: uart4_cfg_func {
+ pinctrl-single,pins = <
+ 0x2a4 0 /* UART4_CTS (IOCFG177) */
+ 0x2a8 0 /* UART4_RTS (IOCFG178) */
+ 0x2ac 0 /* UART4_RXD (IOCFG179) */
+ 0x2b0 0 /* UART4_TXD (IOCFG180) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ };
+ i2c0_cfg_func: i2c0_cfg_func {
+ pinctrl-single,pins = <
+ 0x17c 0 /* I2C0_SCL (IOCFG103) */
+ 0x180 0 /* I2C0_SDA (IOCFG104) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ i2c1_cfg_func: i2c1_cfg_func {
+ pinctrl-single,pins = <
+ 0x184 0 /* I2C1_SCL (IOCFG105) */
+ 0x188 0 /* I2C1_SDA (IOCFG106) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ i2c2_cfg_func: i2c2_cfg_func {
+ pinctrl-single,pins = <
+ 0x118 0 /* I2C2_SCL (IOCFG79) */
+ 0x11c 0 /* I2C2_SDA (IOCFG80) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ i2c3_cfg_func: i2c3_cfg_func {
+ pinctrl-single,pins = <
+ 0x100 0 /* I2C3_SCL (IOCFG73) */
+ 0x104 0 /* I2C3_SDA (IOCFG74) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ spi0_cfg_func1: spi0_cfg_func1 {
+ pinctrl-single,pins = <
+ 0x1d4 0 /* SPI0_CLK (IOCFG125) */
+ 0x1d8 0 /* SPI0_DI (IOCFG126) */
+ 0x1dc 0 /* SPI0_DO (IOCFG127) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ spi0_cfg_func2: spi0_cfg_func2 {
+ pinctrl-single,pins = <
+ 0x1e0 0 /* SPI0_CS0 (IOCFG128) */
+ 0x1e4 0 /* SPI0_CS1 (IOCFG129) */
+ 0x1e8 0 /* SPI0_CS2 (IOCFG130 */
+ 0x1ec 0 /* SPI0_CS3 (IOCFG131) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 0 2>;
+ pinctrl-single,bias-pullup = <1 1 0 1>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ spi1_cfg_func1: spi1_cfg_func1 {
+ pinctrl-single,pins = <
+ 0x1f0 0 /* SPI1_CLK (IOCFG132) */
+ 0x1f4 0 /* SPI1_DI (IOCFG133) */
+ 0x1f8 0 /* SPI1_DO (IOCFG134) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ spi1_cfg_func2: spi1_cfg_func2 {
+ pinctrl-single,pins = <
+ 0x1fc 0 /* SPI1_CS (IOCFG135) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 0 2>;
+ pinctrl-single,bias-pullup = <1 1 0 1>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ kpc_cfg_func: kpc_cfg_func {
+ pinctrl-single,pins = <
+ 0x250 0 /* KEY_IN0 (IOCFG156) */
+ 0x254 0 /* KEY_IN1 (IOCFG157) */
+ 0x258 0 /* KEY_IN2 (IOCFG158) */
+ 0x230 0 /* KEY_OUT0 (IOCFG148) */
+ 0x234 0 /* KEY_OUT1 (IOCFG149) */
+ 0x238 0 /* KEY_OUT2 (IOCFG150) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ };
+ emmc_cfg_func: emmc_cfg_func {
+ pinctrl-single,pins = <
+ 0x0ac 0 /* eMMC_CMD (IOCFG40) */
+ 0x0b0 0 /* eMMC_CLK (IOCFG41) */
+ 0x058 0 /* NAND_CS3_N (IOCFG19) */
+ 0x064 0 /* NAND_BUSY2_N (IOCFG22) */
+ 0x068 0 /* NAND_BUSY3_N (IOCFG23) */
+ 0x08c 0 /* NAND_DATA8 (IOCFG32) */
+ 0x090 0 /* NAND_DATA9 (IOCFG33) */
+ 0x094 0 /* NAND_DATA10 (IOCFG34) */
+ 0x098 0 /* NAND_DATA11 (IOCFG35) */
+ 0x09c 0 /* NAND_DATA12 (IOCFG36) */
+ 0x0a0 0 /* NAND_DATA13 (IOCFG37) */
+ 0x0a4 0 /* NAND_DATA14 (IOCFG38) */
+ 0x0a8 0 /* NAND_DATA15 (IOCFG39) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 0 2>;
+ pinctrl-single,bias-pullup = <1 1 0 1>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ sd_cfg_func1: sd_cfg_func1 {
+ pinctrl-single,pins = <
+ 0x18c 0 /* SD_CLK (IOCFG107) */
+ 0x190 0 /* SD_CMD (IOCFG108) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ sd_cfg_func2: sd_cfg_func2 {
+ pinctrl-single,pins = <
+ 0x194 0 /* SD_DATA0 (IOCFG109) */
+ 0x198 0 /* SD_DATA1 (IOCFG110) */
+ 0x19c 0 /* SD_DATA2 (IOCFG111) */
+ 0x1a0 0 /* SD_DATA3 (IOCFG112) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ pinctrl-single,drive-strength = <0x70 0xf0>;
+ };
+ nand_cfg_func1: nand_cfg_func1 {
+ pinctrl-single,pins = <
+ 0x03c 0 /* NAND_ALE (IOCFG12) */
+ 0x040 0 /* NAND_CLE (IOCFG13) */
+ 0x06c 0 /* NAND_DATA0 (IOCFG24) */
+ 0x070 0 /* NAND_DATA1 (IOCFG25) */
+ 0x074 0 /* NAND_DATA2 (IOCFG26) */
+ 0x078 0 /* NAND_DATA3 (IOCFG27) */
+ 0x07c 0 /* NAND_DATA4 (IOCFG28) */
+ 0x080 0 /* NAND_DATA5 (IOCFG29) */
+ 0x084 0 /* NAND_DATA6 (IOCFG30) */
+ 0x088 0 /* NAND_DATA7 (IOCFG31) */
+ 0x08c 0 /* NAND_DATA8 (IOCFG32) */
+ 0x090 0 /* NAND_DATA9 (IOCFG33) */
+ 0x094 0 /* NAND_DATA10 (IOCFG34) */
+ 0x098 0 /* NAND_DATA11 (IOCFG35) */
+ 0x09c 0 /* NAND_DATA12 (IOCFG36) */
+ 0x0a0 0 /* NAND_DATA13 (IOCFG37) */
+ 0x0a4 0 /* NAND_DATA14 (IOCFG38) */
+ 0x0a8 0 /* NAND_DATA15 (IOCFG39) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ nand_cfg_func2: nand_cfg_func2 {
+ pinctrl-single,pins = <
+ 0x044 0 /* NAND_RE_N (IOCFG14) */
+ 0x048 0 /* NAND_WE_N (IOCFG15) */
+ 0x04c 0 /* NAND_CS0_N (IOCFG16) */
+ 0x050 0 /* NAND_CS1_N (IOCFG17) */
+ 0x054 0 /* NAND_CS2_N (IOCFG18) */
+ 0x058 0 /* NAND_CS3_N (IOCFG19) */
+ 0x05c 0 /* NAND_BUSY0_N (IOCFG20) */
+ 0x060 0 /* NAND_BUSY1_N (IOCFG21) */
+ 0x064 0 /* NAND_BUSY2_N (IOCFG22) */
+ 0x068 0 /* NAND_BUSY3_N (IOCFG23) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 0 2>;
+ pinctrl-single,bias-pullup = <1 1 0 1>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ sdio_cfg_func: sdio_cfg_func {
+ pinctrl-single,pins = <
+ 0x1a4 0 /* SDIO0_CLK (IOCG113) */
+ 0x1a8 0 /* SDIO0_CMD (IOCG114) */
+ 0x1ac 0 /* SDIO0_DATA0 (IOCG115) */
+ 0x1b0 0 /* SDIO0_DATA1 (IOCG116) */
+ 0x1b4 0 /* SDIO0_DATA2 (IOCG117) */
+ 0x1b8 0 /* SDIO0_DATA3 (IOCG118) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ audio_out_cfg_func: audio_out_cfg_func {
+ pinctrl-single,pins = <
+ 0x200 0 /* GPIO (IOCFG136) */
+ 0x204 0 /* GPIO (IOCFG137) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 0 2>;
+ pinctrl-single,bias-pullup = <0 1 0 1>;
+ };
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ call {
+ label = "call";
+ gpios = <&gpio17 2 0>;
+ linux,code = <169>; /* KEY_PHONE */
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi
new file mode 100644
index 000000000..6cbb62e5c
--- /dev/null
+++ b/arch/arm/boot/dts/hi3620.dtsi
@@ -0,0 +1,566 @@
+/*
+ * Hisilicon Ltd. Hi3620 SoC
+ *
+ * Copyright (C) 2012-2013 Hisilicon Ltd.
+ * Copyright (C) 2012-2013 Linaro Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@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
+ * publishhed by the Free Software Foundation.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/hi3620-clock.h>
+
+/ {
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ };
+
+ pclk: clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+ clock-output-names = "apb_pclk";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "hisilicon,hi3620-smp";
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0x0>;
+ next-level-cache = <&L2>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ };
+
+ cpu@2 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <2>;
+ next-level-cache = <&L2>;
+ };
+
+ cpu@3 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <3>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ amba {
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "arm,amba-bus";
+ interrupt-parent = <&gic>;
+ ranges = <0 0xfc000000 0x2000000>;
+
+ L2: l2-cache {
+ compatible = "arm,pl310-cache";
+ reg = <0x100000 0x100000>;
+ interrupts = <0 15 4>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ gic: interrupt-controller@1000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ /* gic dist base, gic cpu base */
+ reg = <0x1000 0x1000>, <0x100 0x100>;
+ };
+
+ sysctrl: system-controller@802000 {
+ compatible = "hisilicon,sysctrl";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x802000 0x1000>;
+ reg = <0x802000 0x1000>;
+
+ smp-offset = <0x31c>;
+ resume-offset = <0x308>;
+ reboot-offset = <0x4>;
+
+ clock: clock@0 {
+ compatible = "hisilicon,hi3620-clock";
+ reg = <0 0x10000>;
+ #clock-cells = <1>;
+ };
+ };
+
+ dual_timer0: dual_timer@800000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x800000 0x1000>;
+ /* timer00 & timer01 */
+ interrupts = <0 0 4>, <0 1 4>;
+ clocks = <&clock HI3620_TIMER0_MUX>, <&clock HI3620_TIMER1_MUX>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ dual_timer1: dual_timer@801000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x801000 0x1000>;
+ /* timer10 & timer11 */
+ interrupts = <0 2 4>, <0 3 4>;
+ clocks = <&clock HI3620_TIMER2_MUX>, <&clock HI3620_TIMER3_MUX>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ dual_timer2: dual_timer@a01000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0xa01000 0x1000>;
+ /* timer20 & timer21 */
+ interrupts = <0 4 4>, <0 5 4>;
+ clocks = <&clock HI3620_TIMER4_MUX>, <&clock HI3620_TIMER5_MUX>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ dual_timer3: dual_timer@a02000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0xa02000 0x1000>;
+ /* timer30 & timer31 */
+ interrupts = <0 6 4>, <0 7 4>;
+ clocks = <&clock HI3620_TIMER6_MUX>, <&clock HI3620_TIMER7_MUX>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ dual_timer4: dual_timer@a03000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0xa03000 0x1000>;
+ /* timer40 & timer41 */
+ interrupts = <0 96 4>, <0 97 4>;
+ clocks = <&clock HI3620_TIMER8_MUX>, <&clock HI3620_TIMER9_MUX>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ timer5: timer@600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x600 0x20>;
+ interrupts = <1 13 0xf01>;
+ };
+
+ uart0: uart@b00000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xb00000 0x1000>;
+ interrupts = <0 20 4>;
+ clocks = <&clock HI3620_UARTCLK0>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ uart1: uart@b01000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xb01000 0x1000>;
+ interrupts = <0 21 4>;
+ clocks = <&clock HI3620_UARTCLK1>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ uart2: uart@b02000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xb02000 0x1000>;
+ interrupts = <0 22 4>;
+ clocks = <&clock HI3620_UARTCLK2>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ uart3: uart@b03000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xb03000 0x1000>;
+ interrupts = <0 23 4>;
+ clocks = <&clock HI3620_UARTCLK3>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ uart4: uart@b04000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xb04000 0x1000>;
+ interrupts = <0 24 4>;
+ clocks = <&clock HI3620_UARTCLK4>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ gpio0: gpio@806000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x806000 0x1000>;
+ interrupts = <0 64 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 2 0 1 &pmx0 3 0 1 &pmx0 4 0 1
+ &pmx0 5 0 1 &pmx0 6 1 1 &pmx0 7 2 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK0>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio1: gpio@807000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x807000 0x1000>;
+ interrupts = <0 65 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 3 1 &pmx0 1 3 1 &pmx0 2 3 1
+ &pmx0 3 3 1 &pmx0 4 3 1 &pmx0 5 4 1
+ &pmx0 6 5 1 &pmx0 7 6 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK1>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio2: gpio@808000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x808000 0x1000>;
+ interrupts = <0 66 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 7 1 &pmx0 1 8 1 &pmx0 2 9 1
+ &pmx0 3 10 1 &pmx0 4 3 1 &pmx0 5 3 1
+ &pmx0 6 3 1 &pmx0 7 3 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK2>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio3: gpio@809000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x809000 0x1000>;
+ interrupts = <0 67 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 3 1 &pmx0 1 3 1 &pmx0 2 3 1
+ &pmx0 3 3 1 &pmx0 4 11 1 &pmx0 5 11 1
+ &pmx0 6 11 1 &pmx0 7 11 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK3>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio4: gpio@80a000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x80a000 0x1000>;
+ interrupts = <0 68 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 11 1 &pmx0 1 11 1 &pmx0 2 11 1
+ &pmx0 3 11 1 &pmx0 4 12 1 &pmx0 5 12 1
+ &pmx0 6 13 1 &pmx0 7 13 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK4>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio5: gpio@80b000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x80b000 0x1000>;
+ interrupts = <0 69 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 14 1 &pmx0 1 15 1 &pmx0 2 16 1
+ &pmx0 3 16 1 &pmx0 4 16 1 &pmx0 5 16 1
+ &pmx0 6 16 1 &pmx0 7 16 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK5>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio6: gpio@80c000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x80c000 0x1000>;
+ interrupts = <0 70 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 16 1 &pmx0 1 16 1 &pmx0 2 17 1
+ &pmx0 3 17 1 &pmx0 4 18 1 &pmx0 5 18 1
+ &pmx0 6 18 1 &pmx0 7 19 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK6>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio7: gpio@80d000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x80d000 0x1000>;
+ interrupts = <0 71 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 19 1 &pmx0 1 20 1 &pmx0 2 21 1
+ &pmx0 3 22 1 &pmx0 4 23 1 &pmx0 5 24 1
+ &pmx0 6 25 1 &pmx0 7 26 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK7>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio8: gpio@80e000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x80e000 0x1000>;
+ interrupts = <0 72 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 27 1 &pmx0 1 28 1 &pmx0 2 29 1
+ &pmx0 3 30 1 &pmx0 4 31 1 &pmx0 5 32 1
+ &pmx0 6 33 1 &pmx0 7 34 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK8>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio9: gpio@80f000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x80f000 0x1000>;
+ interrupts = <0 73 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 35 1 &pmx0 1 36 1 &pmx0 2 37 1
+ &pmx0 3 38 1 &pmx0 4 39 1 &pmx0 5 40 1
+ &pmx0 6 41 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK9>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio10: gpio@810000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x810000 0x1000>;
+ interrupts = <0 74 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 2 43 1 &pmx0 3 44 1 &pmx0 4 45 1
+ &pmx0 5 45 1 &pmx0 6 46 1 &pmx0 7 46 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK10>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio11: gpio@811000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x811000 0x1000>;
+ interrupts = <0 75 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 47 1 &pmx0 1 47 1 &pmx0 2 47 1
+ &pmx0 3 47 1 &pmx0 4 47 1 &pmx0 5 48 1
+ &pmx0 6 49 1 &pmx0 7 49 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK11>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio12: gpio@812000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x812000 0x1000>;
+ interrupts = <0 76 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 49 1 &pmx0 1 50 1 &pmx0 2 49 1
+ &pmx0 3 49 1 &pmx0 4 51 1 &pmx0 5 51 1
+ &pmx0 6 51 1 &pmx0 7 52 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK12>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio13: gpio@813000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x813000 0x1000>;
+ interrupts = <0 77 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 51 1 &pmx0 1 51 1 &pmx0 2 53 1
+ &pmx0 3 53 1 &pmx0 4 53 1 &pmx0 5 54 1
+ &pmx0 6 55 1 &pmx0 7 56 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK13>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio14: gpio@814000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x814000 0x1000>;
+ interrupts = <0 78 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 57 1 &pmx0 1 97 1 &pmx0 2 97 1
+ &pmx0 3 58 1 &pmx0 4 59 1 &pmx0 5 60 1
+ &pmx0 6 60 1 &pmx0 7 61 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK14>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio15: gpio@815000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x815000 0x1000>;
+ interrupts = <0 79 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 61 1 &pmx0 1 62 1 &pmx0 2 62 1
+ &pmx0 3 63 1 &pmx0 4 63 1 &pmx0 5 64 1
+ &pmx0 6 64 1 &pmx0 7 65 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK15>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio16: gpio@816000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x816000 0x1000>;
+ interrupts = <0 80 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 66 1 &pmx0 1 67 1 &pmx0 2 68 1
+ &pmx0 3 69 1 &pmx0 4 70 1 &pmx0 5 71 1
+ &pmx0 6 72 1 &pmx0 7 73 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK16>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio17: gpio@817000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x817000 0x1000>;
+ interrupts = <0 81 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 74 1 &pmx0 1 75 1 &pmx0 2 76 1
+ &pmx0 3 77 1 &pmx0 4 78 1 &pmx0 5 79 1
+ &pmx0 6 80 1 &pmx0 7 81 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK17>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio18: gpio@818000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x818000 0x1000>;
+ interrupts = <0 82 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 82 1 &pmx0 1 83 1 &pmx0 2 83 1
+ &pmx0 3 84 1 &pmx0 4 84 1 &pmx0 5 85 1
+ &pmx0 6 86 1 &pmx0 7 87 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK18>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio19: gpio@819000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x819000 0x1000>;
+ interrupts = <0 83 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 87 1 &pmx0 1 87 1 &pmx0 2 88 1
+ &pmx0 3 88 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK19>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio20: gpio@81a000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x81a000 0x1000>;
+ interrupts = <0 84 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 89 1 &pmx0 1 89 1 &pmx0 2 90 1
+ &pmx0 3 90 1 &pmx0 4 91 1 &pmx0 5 92 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK20>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio21: gpio@81b000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x81b000 0x1000>;
+ interrupts = <0 85 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 3 94 1 &pmx0 7 96 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&clock HI3620_GPIOCLK21>;
+ clock-names = "apb_pclk";
+ };
+
+ pmx0: pinmux@803000 {
+ compatible = "pinctrl-single";
+ reg = <0x803000 0x188>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #gpio-range-cells = <3>;
+ ranges;
+
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <7>;
+ /* pin base, nr pins & gpio function */
+ pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1
+ &range 12 1 0 &range 13 29 1
+ &range 43 1 0 &range 44 49 1
+ &range 94 1 1 &range 96 2 1>;
+
+ range: gpio-range {
+ #pinctrl-single,gpio-range-cells = <3>;
+ };
+ };
+
+ pmx1: pinmux@803800 {
+ compatible = "pinconf-single";
+ reg = <0x803800 0x2dc>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pinctrl-single,register-width = <32>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts
new file mode 100644
index 000000000..ed14aeac0
--- /dev/null
+++ b/arch/arm/boot/dts/highbank.dts
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2011-2012 Calxeda, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/dts-v1/;
+
+/* First 4KB has pen for secondary cores. */
+/memreserve/ 0x00000000 0x0001000;
+
+/ {
+ model = "Calxeda Highbank";
+ compatible = "calxeda,highbank";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clock-ranges;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@900 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0x900>;
+ next-level-cache = <&L2>;
+ clocks = <&a9pll>;
+ clock-names = "cpu";
+ operating-points = <
+ /* kHz ignored */
+ 1300000 1000000
+ 1200000 1000000
+ 1100000 1000000
+ 800000 1000000
+ 400000 1000000
+ 200000 1000000
+ >;
+ clock-latency = <100000>;
+ };
+
+ cpu@901 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0x901>;
+ next-level-cache = <&L2>;
+ clocks = <&a9pll>;
+ clock-names = "cpu";
+ };
+
+ cpu@902 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0x902>;
+ next-level-cache = <&L2>;
+ clocks = <&a9pll>;
+ clock-names = "cpu";
+ };
+
+ cpu@903 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0x903>;
+ next-level-cache = <&L2>;
+ clocks = <&a9pll>;
+ clock-names = "cpu";
+ };
+ };
+
+ memory {
+ name = "memory";
+ device_type = "memory";
+ reg = <0x00000000 0xff900000>;
+ };
+
+ soc {
+ ranges = <0x00000000 0x00000000 0xffffffff>;
+
+ memory-controller@fff00000 {
+ compatible = "calxeda,hb-ddr-ctrl";
+ reg = <0xfff00000 0x1000>;
+ interrupts = <0 91 4>;
+ };
+
+ timer@fff10600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xfff10600 0x20>;
+ interrupts = <1 13 0xf01>;
+ clocks = <&a9periphclk>;
+ };
+
+ watchdog@fff10620 {
+ compatible = "arm,cortex-a9-twd-wdt";
+ reg = <0xfff10620 0x20>;
+ interrupts = <1 14 0xf01>;
+ clocks = <&a9periphclk>;
+ };
+
+ intc: interrupt-controller@fff11000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #size-cells = <0>;
+ #address-cells = <1>;
+ interrupt-controller;
+ reg = <0xfff11000 0x1000>,
+ <0xfff10100 0x100>;
+ };
+
+ L2: l2-cache {
+ compatible = "arm,pl310-cache";
+ reg = <0xfff12000 0x1000>;
+ interrupts = <0 70 4>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 76 4 0 75 4 0 74 4 0 73 4>;
+ };
+
+
+ sregs@fff3c200 {
+ compatible = "calxeda,hb-sregs-l2-ecc";
+ reg = <0xfff3c200 0x100>;
+ interrupts = <0 71 4 0 72 4>;
+ };
+
+ };
+};
+
+/include/ "ecx-common.dtsi"
diff --git a/arch/arm/boot/dts/hip01-ca9x2.dts b/arch/arm/boot/dts/hip01-ca9x2.dts
new file mode 100644
index 000000000..eca5e4277
--- /dev/null
+++ b/arch/arm/boot/dts/hip01-ca9x2.dts
@@ -0,0 +1,51 @@
+/*
+ * Hisilicon Ltd. HiP01 SoC
+ *
+ * Copyright (C) 2014 Hisilicon Ltd.
+ * Copyright (C) 2014 Huawei Ltd.
+ *
+ * Author: Wang Long <long.wanglong@huawei.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.
+ */
+
+/dts-v1/;
+
+/* First 8KB reserved for secondary core boot */
+/memreserve/ 0x80000000 0x00002000;
+
+#include "hip01.dtsi"
+
+/ {
+ model = "Hisilicon HIP01 Development Board";
+ compatible = "hisilicon,hip01-ca9x2", "hisilicon,hip01";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "hisilicon,hip01-smp";
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x80000000>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/hip01.dtsi b/arch/arm/boot/dts/hip01.dtsi
new file mode 100644
index 000000000..33130f846
--- /dev/null
+++ b/arch/arm/boot/dts/hip01.dtsi
@@ -0,0 +1,110 @@
+/*
+ * Hisilicon Ltd. HiP01 SoC
+ *
+ * Copyright (c) 2014 Hisilicon Ltd.
+ * Copyright (c) 2014 Huawei Ltd.
+ *
+ * Author: Wang Long <long.wanglong@huawei.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 "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ gic: interrupt-controller@1e001000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x1a001000 0x1000>, <0x1a000100 0x1000>;
+ };
+
+ hisi_refclk144mhz: refclk144mkhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <144000000>;
+ clock-output-names = "hisi:refclk144khz";
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+ ranges = <0 0x10000000 0x20000000>;
+
+ amba {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "arm,amba-bus";
+ ranges;
+
+ uart0: uart@10001000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x10001000 0x1000>;
+ clocks = <&hisi_refclk144mhz>;
+ clock-names = "apb_pclk";
+ reg-shift = <2>;
+ interrupts = <0 32 4>;
+ status = "disabled";
+ };
+
+ uart1: uart@10002000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x10002000 0x1000>;
+ clocks = <&hisi_refclk144mhz>;
+ clock-names = "apb_pclk";
+ reg-shift = <2>;
+ interrupts = <0 33 4>;
+ status = "disabled";
+ };
+
+ uart2: uart@10003000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x10003000 0x1000>;
+ clocks = <&hisi_refclk144mhz>;
+ clock-names = "apb_pclk";
+ reg-shift = <2>;
+ interrupts = <0 34 4>;
+ status = "disabled";
+ };
+
+ uart3: uart@10006000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x10006000 0x1000>;
+ clocks = <&hisi_refclk144mhz>;
+ clock-names = "apb_pclk";
+ reg-shift = <2>;
+ interrupts = <0 4 4>;
+ status = "disabled";
+ };
+ };
+
+ system-controller@10000000 {
+ compatible = "hisilicon,hip01-sysctrl", "hisilicon,sysctrl";
+ reg = <0x10000000 0x1000>;
+ reboot-offset = <0x4>;
+ };
+
+ global_timer@0a000200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x0a000200 0x100>;
+ interrupts = <1 11 0xf04>;
+ clocks = <&hisi_refclk144mhz>;
+ };
+
+ local_timer@0a000600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x0a000600 0x100>;
+ interrupts = <1 13 0xf04>;
+ clocks = <&hisi_refclk144mhz>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/hip04-d01.dts b/arch/arm/boot/dts/hip04-d01.dts
new file mode 100644
index 000000000..40a9e33c2
--- /dev/null
+++ b/arch/arm/boot/dts/hip04-d01.dts
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013-2014 Linaro Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@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
+ * publishhed by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+#include "hip04.dtsi"
+
+/ {
+ /* memory bus is 64-bit */
+ #address-cells = <2>;
+ #size-cells = <2>;
+ model = "Hisilicon D01 Development Board";
+ compatible = "hisilicon,hip04-d01";
+
+ memory@00000000,10000000 {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000 0x00000000 0xc0000000>,
+ <0x00000004 0xc0000000 0x00000003 0x40000000>;
+ };
+
+ soc {
+ uart0: uart@4007000 {
+ status = "ok";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/hip04.dtsi b/arch/arm/boot/dts/hip04.dtsi
new file mode 100644
index 000000000..44044f275
--- /dev/null
+++ b/arch/arm/boot/dts/hip04.dtsi
@@ -0,0 +1,983 @@
+/*
+ * Hisilicon Ltd. HiP04 SoC
+ *
+ * Copyright (C) 2013-2014 Hisilicon Ltd.
+ * Copyright (C) 2013-2014 Linaro Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@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.
+ */
+
+/ {
+ /* memory bus is 64-bit */
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ bootwrapper {
+ compatible = "hisilicon,hip04-bootwrapper";
+ boot-method = <0x10c00000 0x10000>, <0xe0000100 0x1000>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&CPU0>;
+ };
+ core1 {
+ cpu = <&CPU1>;
+ };
+ core2 {
+ cpu = <&CPU2>;
+ };
+ core3 {
+ cpu = <&CPU3>;
+ };
+ };
+ cluster1 {
+ core0 {
+ cpu = <&CPU4>;
+ };
+ core1 {
+ cpu = <&CPU5>;
+ };
+ core2 {
+ cpu = <&CPU6>;
+ };
+ core3 {
+ cpu = <&CPU7>;
+ };
+ };
+ cluster2 {
+ core0 {
+ cpu = <&CPU8>;
+ };
+ core1 {
+ cpu = <&CPU9>;
+ };
+ core2 {
+ cpu = <&CPU10>;
+ };
+ core3 {
+ cpu = <&CPU11>;
+ };
+ };
+ cluster3 {
+ core0 {
+ cpu = <&CPU12>;
+ };
+ core1 {
+ cpu = <&CPU13>;
+ };
+ core2 {
+ cpu = <&CPU14>;
+ };
+ core3 {
+ cpu = <&CPU15>;
+ };
+ };
+ };
+ CPU0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0>;
+ };
+ CPU1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <1>;
+ };
+ CPU2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <2>;
+ };
+ CPU3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <3>;
+ };
+ CPU4: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x100>;
+ };
+ CPU5: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x101>;
+ };
+ CPU6: cpu@102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x102>;
+ };
+ CPU7: cpu@103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x103>;
+ };
+ CPU8: cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x200>;
+ };
+ CPU9: cpu@201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x201>;
+ };
+ CPU10: cpu@202 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x202>;
+ };
+ CPU11: cpu@203 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x203>;
+ };
+ CPU12: cpu@300 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x300>;
+ };
+ CPU13: cpu@301 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x301>;
+ };
+ CPU14: cpu@302 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x302>;
+ };
+ CPU15: cpu@303 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x303>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupt-parent = <&gic>;
+ interrupts = <1 13 0xf08>,
+ <1 14 0xf08>,
+ <1 11 0xf08>,
+ <1 10 0xf08>;
+ };
+
+ clk_50m: clk_50m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <50000000>;
+ };
+
+ clk_168m: clk_168m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <168000000>;
+ };
+
+ clk_375m: clk_375m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <375000000>;
+ };
+
+ soc {
+ /* It's a 32-bit SoC. */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+ ranges = <0 0 0xe0000000 0x10000000>;
+
+ gic: interrupt-controller@c01000 {
+ compatible = "hisilicon,hip04-intc";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ interrupts = <1 9 0xf04>;
+
+ reg = <0xc01000 0x1000>, <0xc02000 0x1000>,
+ <0xc04000 0x2000>, <0xc06000 0x2000>;
+ };
+
+ sysctrl: sysctrl {
+ compatible = "hisilicon,sysctrl";
+ reg = <0x3e00000 0x00100000>;
+ };
+
+ fabric: fabric {
+ compatible = "hisilicon,hip04-fabric";
+ reg = <0x302a000 0x1000>;
+ };
+
+ dual_timer0: dual_timer@3000000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x3000000 0x1000>;
+ interrupts = <0 224 4>;
+ clocks = <&clk_50m>, <&clk_50m>;
+ clock-names = "apb_pclk";
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a15-pmu";
+ interrupts = <0 64 4>,
+ <0 65 4>,
+ <0 66 4>,
+ <0 67 4>,
+ <0 68 4>,
+ <0 69 4>,
+ <0 70 4>,
+ <0 71 4>,
+ <0 72 4>,
+ <0 73 4>,
+ <0 74 4>,
+ <0 75 4>,
+ <0 76 4>,
+ <0 77 4>,
+ <0 78 4>,
+ <0 79 4>;
+ };
+
+ uart0: uart@4007000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x4007000 0x1000>;
+ interrupts = <0 381 4>;
+ clocks = <&clk_168m>;
+ clock-names = "uartclk";
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ sata0: sata@a000000 {
+ compatible = "hisilicon,hisi-ahci";
+ reg = <0xa000000 0x1000000>;
+ interrupts = <0 372 4>;
+ };
+
+ };
+
+ etb@0,e3c42000 {
+ compatible = "arm,coresight-etb10", "arm,primecell";
+ reg = <0 0xe3c42000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ port {
+ etb0_in_port: endpoint@0 {
+ slave-mode;
+ remote-endpoint = <&replicator0_out_port0>;
+ };
+ };
+ };
+
+ etb@0,e3c82000 {
+ compatible = "arm,coresight-etb10", "arm,primecell";
+ reg = <0 0xe3c82000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ port {
+ etb1_in_port: endpoint@0 {
+ slave-mode;
+ remote-endpoint = <&replicator1_out_port0>;
+ };
+ };
+ };
+
+ etb@0,e3cc2000 {
+ compatible = "arm,coresight-etb10", "arm,primecell";
+ reg = <0 0xe3cc2000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ port {
+ etb2_in_port: endpoint@0 {
+ slave-mode;
+ remote-endpoint = <&replicator2_out_port0>;
+ };
+ };
+ };
+
+ etb@0,e3d02000 {
+ compatible = "arm,coresight-etb10", "arm,primecell";
+ reg = <0 0xe3d02000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ port {
+ etb3_in_port: endpoint@0 {
+ slave-mode;
+ remote-endpoint = <&replicator3_out_port0>;
+ };
+ };
+ };
+
+ tpiu@0,e3c05000 {
+ compatible = "arm,coresight-tpiu", "arm,primecell";
+ reg = <0 0xe3c05000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ port {
+ tpiu_in_port: endpoint@0 {
+ slave-mode;
+ remote-endpoint = <&funnel4_out_port0>;
+ };
+ };
+ };
+
+ replicator0 {
+ /* non-configurable replicators don't show up on the
+ * AMBA bus. As such no need to add "arm,primecell".
+ */
+ compatible = "arm,coresight-replicator";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* replicator output ports */
+ port@0 {
+ reg = <0>;
+ replicator0_out_port0: endpoint {
+ remote-endpoint = <&etb0_in_port>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ replicator0_out_port1: endpoint {
+ remote-endpoint = <&funnel4_in_port0>;
+ };
+ };
+
+ /* replicator input port */
+ port@2 {
+ reg = <0>;
+ replicator0_in_port0: endpoint {
+ slave-mode;
+ remote-endpoint = <&funnel0_out_port0>;
+ };
+ };
+ };
+ };
+
+ replicator1 {
+ /* non-configurable replicators don't show up on the
+ * AMBA bus. As such no need to add "arm,primecell".
+ */
+ compatible = "arm,coresight-replicator";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* replicator output ports */
+ port@0 {
+ reg = <0>;
+ replicator1_out_port0: endpoint {
+ remote-endpoint = <&etb1_in_port>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ replicator1_out_port1: endpoint {
+ remote-endpoint = <&funnel4_in_port1>;
+ };
+ };
+
+ /* replicator input port */
+ port@2 {
+ reg = <0>;
+ replicator1_in_port0: endpoint {
+ slave-mode;
+ remote-endpoint = <&funnel1_out_port0>;
+ };
+ };
+ };
+ };
+
+ replicator2 {
+ /* non-configurable replicators don't show up on the
+ * AMBA bus. As such no need to add "arm,primecell".
+ */
+ compatible = "arm,coresight-replicator";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* replicator output ports */
+ port@0 {
+ reg = <0>;
+ replicator2_out_port0: endpoint {
+ remote-endpoint = <&etb2_in_port>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ replicator2_out_port1: endpoint {
+ remote-endpoint = <&funnel4_in_port2>;
+ };
+ };
+
+ /* replicator input port */
+ port@2 {
+ reg = <0>;
+ replicator2_in_port0: endpoint {
+ slave-mode;
+ remote-endpoint = <&funnel2_out_port0>;
+ };
+ };
+ };
+ };
+
+ replicator3 {
+ /* non-configurable replicators don't show up on the
+ * AMBA bus. As such no need to add "arm,primecell".
+ */
+ compatible = "arm,coresight-replicator";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* replicator output ports */
+ port@0 {
+ reg = <0>;
+ replicator3_out_port0: endpoint {
+ remote-endpoint = <&etb3_in_port>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ replicator3_out_port1: endpoint {
+ remote-endpoint = <&funnel4_in_port3>;
+ };
+ };
+
+ /* replicator input port */
+ port@2 {
+ reg = <0>;
+ replicator3_in_port0: endpoint {
+ slave-mode;
+ remote-endpoint = <&funnel3_out_port0>;
+ };
+ };
+ };
+ };
+
+ funnel@0,e3c41000 {
+ compatible = "arm,coresight-funnel", "arm,primecell";
+ reg = <0 0xe3c41000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* funnel output port */
+ port@0 {
+ reg = <0>;
+ funnel0_out_port0: endpoint {
+ remote-endpoint =
+ <&replicator0_in_port0>;
+ };
+ };
+
+ /* funnel input ports */
+ port@1 {
+ reg = <0>;
+ funnel0_in_port0: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm0_out_port>;
+ };
+ };
+
+ port@2 {
+ reg = <1>;
+ funnel0_in_port1: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm1_out_port>;
+ };
+ };
+
+ port@3 {
+ reg = <2>;
+ funnel0_in_port2: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm2_out_port>;
+ };
+ };
+
+ port@4 {
+ reg = <3>;
+ funnel0_in_port3: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm3_out_port>;
+ };
+ };
+ };
+ };
+
+ funnel@0,e3c81000 {
+ compatible = "arm,coresight-funnel", "arm,primecell";
+ reg = <0 0xe3c81000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* funnel output port */
+ port@0 {
+ reg = <0>;
+ funnel1_out_port0: endpoint {
+ remote-endpoint =
+ <&replicator1_in_port0>;
+ };
+ };
+
+ /* funnel input ports */
+ port@1 {
+ reg = <0>;
+ funnel1_in_port0: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm4_out_port>;
+ };
+ };
+
+ port@2 {
+ reg = <1>;
+ funnel1_in_port1: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm5_out_port>;
+ };
+ };
+
+ port@3 {
+ reg = <2>;
+ funnel1_in_port2: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm6_out_port>;
+ };
+ };
+
+ port@4 {
+ reg = <3>;
+ funnel1_in_port3: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm7_out_port>;
+ };
+ };
+ };
+ };
+
+ funnel@0,e3cc1000 {
+ compatible = "arm,coresight-funnel", "arm,primecell";
+ reg = <0 0xe3cc1000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* funnel output port */
+ port@0 {
+ reg = <0>;
+ funnel2_out_port0: endpoint {
+ remote-endpoint =
+ <&replicator2_in_port0>;
+ };
+ };
+
+ /* funnel input ports */
+ port@1 {
+ reg = <0>;
+ funnel2_in_port0: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm8_out_port>;
+ };
+ };
+
+ port@2 {
+ reg = <1>;
+ funnel2_in_port1: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm9_out_port>;
+ };
+ };
+
+ port@3 {
+ reg = <2>;
+ funnel2_in_port2: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm10_out_port>;
+ };
+ };
+
+ port@4 {
+ reg = <3>;
+ funnel2_in_port3: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm11_out_port>;
+ };
+ };
+ };
+ };
+
+ funnel@0,e3d01000 {
+ compatible = "arm,coresight-funnel", "arm,primecell";
+ reg = <0 0xe3d01000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* funnel output port */
+ port@0 {
+ reg = <0>;
+ funnel3_out_port0: endpoint {
+ remote-endpoint =
+ <&replicator3_in_port0>;
+ };
+ };
+
+ /* funnel input ports */
+ port@1 {
+ reg = <0>;
+ funnel3_in_port0: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm12_out_port>;
+ };
+ };
+
+ port@2 {
+ reg = <1>;
+ funnel3_in_port1: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm13_out_port>;
+ };
+ };
+
+ port@3 {
+ reg = <2>;
+ funnel3_in_port2: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm14_out_port>;
+ };
+ };
+
+ port@4 {
+ reg = <3>;
+ funnel3_in_port3: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm15_out_port>;
+ };
+ };
+ };
+ };
+
+ funnel@0,e3c04000 {
+ compatible = "arm,coresight-funnel", "arm,primecell";
+ reg = <0 0xe3c04000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* funnel output port */
+ port@0 {
+ reg = <0>;
+ funnel4_out_port0: endpoint {
+ remote-endpoint = <&tpiu_in_port>;
+ };
+ };
+
+ /* funnel input ports */
+ port@1 {
+ reg = <0>;
+ funnel4_in_port0: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&replicator0_out_port1>;
+ };
+ };
+
+ port@2 {
+ reg = <1>;
+ funnel4_in_port1: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&replicator1_out_port1>;
+ };
+ };
+
+ port@3 {
+ reg = <2>;
+ funnel4_in_port2: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&replicator2_out_port1>;
+ };
+ };
+
+ port@4 {
+ reg = <3>;
+ funnel4_in_port3: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&replicator3_out_port1>;
+ };
+ };
+ };
+ };
+
+ ptm@0,e3c7c000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0xe3c7c000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ cpu = <&CPU0>;
+ port {
+ ptm0_out_port: endpoint {
+ remote-endpoint = <&funnel0_in_port0>;
+ };
+ };
+ };
+
+ ptm@0,e3c7d000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0xe3c7d000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ cpu = <&CPU1>;
+ port {
+ ptm1_out_port: endpoint {
+ remote-endpoint = <&funnel0_in_port1>;
+ };
+ };
+ };
+
+ ptm@0,e3c7e000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0xe3c7e000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ cpu = <&CPU2>;
+ port {
+ ptm2_out_port: endpoint {
+ remote-endpoint = <&funnel0_in_port2>;
+ };
+ };
+ };
+
+ ptm@0,e3c7f000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0xe3c7f000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ cpu = <&CPU3>;
+ port {
+ ptm3_out_port: endpoint {
+ remote-endpoint = <&funnel0_in_port3>;
+ };
+ };
+ };
+
+ ptm@0,e3cbc000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0xe3cbc000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ cpu = <&CPU4>;
+ port {
+ ptm4_out_port: endpoint {
+ remote-endpoint = <&funnel1_in_port0>;
+ };
+ };
+ };
+
+ ptm@0,e3cbd000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0xe3cbd000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ cpu = <&CPU5>;
+ port {
+ ptm5_out_port: endpoint {
+ remote-endpoint = <&funnel1_in_port1>;
+ };
+ };
+ };
+
+ ptm@0,e3cbe000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0xe3cbe000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ cpu = <&CPU6>;
+ port {
+ ptm6_out_port: endpoint {
+ remote-endpoint = <&funnel1_in_port2>;
+ };
+ };
+ };
+
+ ptm@0,e3cbf000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0xe3cbf000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ cpu = <&CPU7>;
+ port {
+ ptm7_out_port: endpoint {
+ remote-endpoint = <&funnel1_in_port3>;
+ };
+ };
+ };
+
+ ptm@0,e3cfc000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0xe3cfc000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ cpu = <&CPU8>;
+ port {
+ ptm8_out_port: endpoint {
+ remote-endpoint = <&funnel2_in_port0>;
+ };
+ };
+ };
+
+ ptm@0,e3cfd000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0xe3cfd000 0 0x1000>;
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ cpu = <&CPU9>;
+ port {
+ ptm9_out_port: endpoint {
+ remote-endpoint = <&funnel2_in_port1>;
+ };
+ };
+ };
+
+ ptm@0,e3cfe000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0xe3cfe000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ cpu = <&CPU10>;
+ port {
+ ptm10_out_port: endpoint {
+ remote-endpoint = <&funnel2_in_port2>;
+ };
+ };
+ };
+
+ ptm@0,e3cff000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0xe3cff000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ cpu = <&CPU11>;
+ port {
+ ptm11_out_port: endpoint {
+ remote-endpoint = <&funnel2_in_port3>;
+ };
+ };
+ };
+
+ ptm@0,e3d3c000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0xe3d3c000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ cpu = <&CPU12>;
+ port {
+ ptm12_out_port: endpoint {
+ remote-endpoint = <&funnel3_in_port0>;
+ };
+ };
+ };
+
+ ptm@0,e3d3d000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0xe3d3d000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ cpu = <&CPU13>;
+ port {
+ ptm13_out_port: endpoint {
+ remote-endpoint = <&funnel3_in_port1>;
+ };
+ };
+ };
+
+ ptm@0,e3d3e000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0xe3d3e000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ cpu = <&CPU14>;
+ port {
+ ptm14_out_port: endpoint {
+ remote-endpoint = <&funnel3_in_port2>;
+ };
+ };
+ };
+
+ ptm@0,e3d3f000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0xe3d3f000 0 0x1000>;
+
+ clocks = <&clk_375m>;
+ clock-names = "apb_pclk";
+ cpu = <&CPU15>;
+ port {
+ ptm15_out_port: endpoint {
+ remote-endpoint = <&funnel3_in_port3>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/hisi-x5hd2-dkb.dts b/arch/arm/boot/dts/hisi-x5hd2-dkb.dts
new file mode 100644
index 000000000..721b09238
--- /dev/null
+++ b/arch/arm/boot/dts/hisi-x5hd2-dkb.dts
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2013-2014 Linaro Ltd.
+ * Copyright (c) 2013-2014 Hisilicon 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
+ * publishhed by the Free Software Foundation.
+ */
+
+/dts-v1/;
+#include "hisi-x5hd2.dtsi"
+
+/ {
+ model = "Hisilicon HIX5HD2 Development Board";
+ compatible = "hisilicon,hix5hd2";
+
+ chosen {
+ bootargs = "console=ttyAMA0,115200 earlyprintk";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "hisilicon,hix5hd2-smp";
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&l2>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&l2>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000>;
+ };
+};
+
+&timer0 {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&gmac0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy-handle = <&phy2>;
+ phy-mode = "mii";
+ /* Placeholder, overwritten by bootloader */
+ mac-address = [00 00 00 00 00 00];
+ status = "okay";
+
+ phy2: ethernet-phy@2 {
+ reg = <2>;
+ };
+};
+
+&gmac1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy-handle = <&phy1>;
+ phy-mode = "rgmii";
+ /* Placeholder, overwritten by bootloader */
+ mac-address = [00 00 00 00 00 00];
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&ahci {
+ phys = <&sata_phy>;
+ phy-names = "sata-phy";
+};
diff --git a/arch/arm/boot/dts/hisi-x5hd2.dtsi b/arch/arm/boot/dts/hisi-x5hd2.dtsi
new file mode 100644
index 000000000..c52722b14
--- /dev/null
+++ b/arch/arm/boot/dts/hisi-x5hd2.dtsi
@@ -0,0 +1,556 @@
+/*
+ * Copyright (c) 2013-2014 Linaro Ltd.
+ * Copyright (c) 2013-2014 Hisilicon 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
+ * publishhed by the Free Software Foundation.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/hix5hd2-clock.h>
+
+/ {
+ aliases {
+ serial0 = &uart0;
+ };
+
+ gic: interrupt-controller@f8a01000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ /* gic dist base, gic cpu base */
+ reg = <0xf8a01000 0x1000>, <0xf8a00100 0x100>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+ ranges = <0 0xf8000000 0x8000000>;
+
+ amba {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "arm,amba-bus";
+ ranges;
+
+ timer0: timer@00002000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x00002000 0x1000>;
+ /* timer00 & timer01 */
+ interrupts = <0 24 4>;
+ clocks = <&clock HIX5HD2_FIXED_24M>;
+ status = "disabled";
+ };
+
+ timer1: timer@00a29000 {
+ /*
+ * Only used in NORMAL state, not available ins
+ * SLOW or DOZE state.
+ * The rate is fixed in 24MHz.
+ */
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x00a29000 0x1000>;
+ /* timer10 & timer11 */
+ interrupts = <0 25 4>;
+ clocks = <&clock HIX5HD2_FIXED_24M>;
+ status = "disabled";
+ };
+
+ timer2: timer@00a2a000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x00a2a000 0x1000>;
+ /* timer20 & timer21 */
+ interrupts = <0 26 4>;
+ clocks = <&clock HIX5HD2_FIXED_24M>;
+ status = "disabled";
+ };
+
+ timer3: timer@00a2b000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x00a2b000 0x1000>;
+ /* timer30 & timer31 */
+ interrupts = <0 27 4>;
+ clocks = <&clock HIX5HD2_FIXED_24M>;
+ status = "disabled";
+ };
+
+ timer4: timer@00a81000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x00a81000 0x1000>;
+ /* timer30 & timer31 */
+ interrupts = <0 28 4>;
+ clocks = <&clock HIX5HD2_FIXED_24M>;
+ status = "disabled";
+ };
+
+ uart0: uart@00b00000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x00b00000 0x1000>;
+ interrupts = <0 49 4>;
+ clocks = <&clock HIX5HD2_FIXED_83M>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ uart1: uart@00006000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x00006000 0x1000>;
+ interrupts = <0 50 4>;
+ clocks = <&clock HIX5HD2_FIXED_83M>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ uart2: uart@00b02000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x00b02000 0x1000>;
+ interrupts = <0 51 4>;
+ clocks = <&clock HIX5HD2_FIXED_83M>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ uart3: uart@00b03000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x00b03000 0x1000>;
+ interrupts = <0 52 4>;
+ clocks = <&clock HIX5HD2_FIXED_83M>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ uart4: uart@00b04000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xb04000 0x1000>;
+ interrupts = <0 53 4>;
+ clocks = <&clock HIX5HD2_FIXED_83M>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ gpio0: gpio@b20000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb20000 0x1000>;
+ interrupts = <0 108 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio1: gpio@b21000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb21000 0x1000>;
+ interrupts = <0 109 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio2: gpio@b22000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb22000 0x1000>;
+ interrupts = <0 110 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio3: gpio@b23000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb23000 0x1000>;
+ interrupts = <0 111 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio4: gpio@b24000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb24000 0x1000>;
+ interrupts = <0 112 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio5: gpio@004000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x004000 0x1000>;
+ interrupts = <0 113 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio6: gpio@b26000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb26000 0x1000>;
+ interrupts = <0 114 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio7: gpio@b27000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb27000 0x1000>;
+ interrupts = <0 115 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio8: gpio@b28000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb28000 0x1000>;
+ interrupts = <0 116 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio9: gpio@b29000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb29000 0x1000>;
+ interrupts = <0 117 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio10: gpio@b2a000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb2a000 0x1000>;
+ interrupts = <0 118 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio11: gpio@b2b000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb2b000 0x1000>;
+ interrupts = <0 119 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio12: gpio@b2c000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb2c000 0x1000>;
+ interrupts = <0 120 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio13: gpio@b2d000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb2d000 0x1000>;
+ interrupts = <0 121 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio14: gpio@b2e000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb2e000 0x1000>;
+ interrupts = <0 122 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio15: gpio@b2f000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb2f000 0x1000>;
+ interrupts = <0 123 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio16: gpio@b30000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb30000 0x1000>;
+ interrupts = <0 124 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio17: gpio@b31000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xb31000 0x1000>;
+ interrupts = <0 125 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock HIX5HD2_FIXED_100M>;
+ clock-names = "apb_pclk";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ wdt0: watchdog@a2c000 {
+ compatible = "arm,sp805", "arm,primecell";
+ arm,primecell-periphid = <0x00141805>;
+ reg = <0xa2c000 0x1000>;
+ interrupts = <0 29 4>;
+ clocks = <&clock HIX5HD2_WDG0_RST>;
+ clock-names = "apb_pclk";
+ };
+ };
+
+ local_timer@00a00600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x00a00600 0x20>;
+ interrupts = <1 13 0xf01>;
+ };
+
+ l2: l2-cache {
+ compatible = "arm,pl310-cache";
+ reg = <0x00a10000 0x100000>;
+ interrupts = <0 15 4>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ sysctrl: system-controller@00000000 {
+ compatible = "hisilicon,sysctrl", "syscon";
+ reg = <0x00000000 0x1000>;
+ };
+
+ reboot {
+ compatible = "syscon-reboot";
+ regmap = <&sysctrl>;
+ offset = <0x4>;
+ mask = <0xdeadbeef>;
+ };
+
+ cpuctrl@00a22000 {
+ compatible = "hisilicon,cpuctrl";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x00a22000 0x2000>;
+ ranges = <0 0x00a22000 0x2000>;
+
+ clock: clock@0 {
+ compatible = "hisilicon,hix5hd2-clock";
+ reg = <0 0x2000>;
+ #clock-cells = <1>;
+ };
+ };
+
+ /* unremovable emmc as mmcblk0 */
+ mmc: mmc@1830000 {
+ compatible = "snps,dw-mshc";
+ reg = <0x1830000 0x1000>;
+ interrupts = <0 35 4>;
+ clocks = <&clock HIX5HD2_MMC_CIU_RST>,
+ <&clock HIX5HD2_MMC_BIU_CLK>;
+ clock-names = "ciu", "biu";
+ };
+
+ sd: mmc@1820000 {
+ compatible = "snps,dw-mshc";
+ reg = <0x1820000 0x1000>;
+ interrupts = <0 34 4>;
+ clocks = <&clock HIX5HD2_SD_CIU_RST>,
+ <&clock HIX5HD2_SD_BIU_CLK>;
+ clock-names = "ciu","biu";
+ };
+
+ gmac0: ethernet@1840000 {
+ compatible = "hisilicon,hix5hd2-gmac";
+ reg = <0x1840000 0x1000>,<0x184300c 0x4>;
+ interrupts = <0 71 4>;
+ clocks = <&clock HIX5HD2_MAC0_CLK>;
+ status = "disabled";
+ };
+
+ gmac1: ethernet@1841000 {
+ compatible = "hisilicon,hix5hd2-gmac";
+ reg = <0x1841000 0x1000>,<0x1843010 0x4>;
+ interrupts = <0 72 4>;
+ clocks = <&clock HIX5HD2_MAC1_CLK>;
+ status = "disabled";
+ };
+
+ usb0: ehci@1890000 {
+ compatible = "generic-ehci";
+ reg = <0x1890000 0x1000>;
+ interrupts = <0 66 4>;
+ clocks = <&clock HIX5HD2_USB_CLK>;
+ };
+
+ usb1: ohci@1880000 {
+ compatible = "generic-ohci";
+ reg = <0x1880000 0x1000>;
+ interrupts = <0 67 4>;
+ clocks = <&clock HIX5HD2_USB_CLK>;
+ };
+
+ peripheral_ctrl: syscon@a20000 {
+ compatible = "syscon";
+ reg = <0xa20000 0x1000>;
+ };
+
+ sata_phy: phy@1900000 {
+ compatible = "hisilicon,hix5hd2-sata-phy";
+ reg = <0x1900000 0x10000>;
+ #phy-cells = <0>;
+ hisilicon,peripheral-syscon = <&peripheral_ctrl>;
+ hisilicon,power-reg = <0x8 10>;
+ };
+
+ ahci: sata@1900000 {
+ compatible = "hisilicon,hisi-ahci";
+ reg = <0x1900000 0x10000>;
+ interrupts = <0 70 4>;
+ clocks = <&clock HIX5HD2_SATA_CLK>;
+ };
+
+ ir: ir@001000 {
+ compatible = "hisilicon,hix5hd2-ir";
+ reg = <0x001000 0x1000>;
+ interrupts = <0 47 4>;
+ clocks = <&clock HIX5HD2_FIXED_24M>;
+ hisilicon,power-syscon = <&sysctrl>;
+ };
+
+ i2c0: i2c@b10000 {
+ compatible = "hisilicon,hix5hd2-i2c";
+ reg = <0xb10000 0x1000>;
+ interrupts = <0 38 4>;
+ clocks = <&clock HIX5HD2_I2C0_RST>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@b11000 {
+ compatible = "hisilicon,hix5hd2-i2c";
+ reg = <0xb11000 0x1000>;
+ interrupts = <0 39 4>;
+ clocks = <&clock HIX5HD2_I2C1_RST>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@b12000 {
+ compatible = "hisilicon,hix5hd2-i2c";
+ reg = <0xb12000 0x1000>;
+ interrupts = <0 40 4>;
+ clocks = <&clock HIX5HD2_I2C2_RST>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@b13000 {
+ compatible = "hisilicon,hix5hd2-i2c";
+ reg = <0xb13000 0x1000>;
+ interrupts = <0 41 4>;
+ clocks = <&clock HIX5HD2_I2C3_RST>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@b16000 {
+ compatible = "hisilicon,hix5hd2-i2c";
+ reg = <0xb16000 0x1000>;
+ interrupts = <0 43 4>;
+ clocks = <&clock HIX5HD2_I2C4_RST>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c5: i2c@b17000 {
+ compatible = "hisilicon,hix5hd2-i2c";
+ reg = <0xb17000 0x1000>;
+ interrupts = <0 44 4>;
+ clocks = <&clock HIX5HD2_I2C5_RST>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx1-ads.dts b/arch/arm/boot/dts/imx1-ads.dts
new file mode 100644
index 000000000..af4eee579
--- /dev/null
+++ b/arch/arm/boot/dts/imx1-ads.dts
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx1.dtsi"
+
+/ {
+ model = "Freescale MX1 ADS";
+ compatible = "fsl,imx1ads", "fsl,imx1";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory {
+ reg = <0x08000000 0x04000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32 {
+ compatible = "fsl,imx-clk32", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32000>;
+ };
+ };
+};
+
+&cspi1 {
+ pinctrl-0 = <&pinctrl_cspi1>;
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio3 15 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&i2c {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c>;
+ status = "okay";
+
+ extgpio0: pcf8575@22 {
+ compatible = "nxp,pcf8575";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ extgpio1: pcf8575@24 {
+ compatible = "nxp,pcf8575";
+ reg = <0x24>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&weim {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_weim>;
+ status = "okay";
+
+ nor: nor@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0x00000000 0x02000000>;
+ bank-width = <4>;
+ fsl,weim-cs-timing = <0x00003e00 0x00000801>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+};
+
+&iomuxc {
+ imx1-ads {
+ pinctrl_cspi1: cspi1grp {
+ fsl,pins = <
+ MX1_PAD_SPI1_MISO__SPI1_MISO 0x0
+ MX1_PAD_SPI1_MOSI__SPI1_MOSI 0x0
+ MX1_PAD_SPI1_RDY__SPI1_RDY 0x0
+ MX1_PAD_SPI1_SCLK__SPI1_SCLK 0x0
+ MX1_PAD_SPI1_SS__GPIO3_15 0x0
+ >;
+ };
+
+ pinctrl_i2c: i2cgrp {
+ fsl,pins = <
+ MX1_PAD_I2C_SCL__I2C_SCL 0x0
+ MX1_PAD_I2C_SDA__I2C_SDA 0x0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX1_PAD_UART1_TXD__UART1_TXD 0x0
+ MX1_PAD_UART1_RXD__UART1_RXD 0x0
+ MX1_PAD_UART1_CTS__UART1_CTS 0x0
+ MX1_PAD_UART1_RTS__UART1_RTS 0x0
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX1_PAD_UART2_TXD__UART2_TXD 0x0
+ MX1_PAD_UART2_RXD__UART2_RXD 0x0
+ MX1_PAD_UART2_CTS__UART2_CTS 0x0
+ MX1_PAD_UART2_RTS__UART2_RTS 0x0
+ >;
+ };
+
+ pinctrl_weim: weimgrp {
+ fsl,pins = <
+ MX1_PAD_A0__A0 0x0
+ MX1_PAD_A16__A16 0x0
+ MX1_PAD_A17__A17 0x0
+ MX1_PAD_A18__A18 0x0
+ MX1_PAD_A19__A19 0x0
+ MX1_PAD_A20__A20 0x0
+ MX1_PAD_A21__A21 0x0
+ MX1_PAD_A22__A22 0x0
+ MX1_PAD_A23__A23 0x0
+ MX1_PAD_A24__A24 0x0
+ MX1_PAD_BCLK__BCLK 0x0
+ MX1_PAD_CS4__CS4 0x0
+ MX1_PAD_DTACK__DTACK 0x0
+ MX1_PAD_ECB__ECB 0x0
+ MX1_PAD_LBA__LBA 0x0
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx1-apf9328.dts b/arch/arm/boot/dts/imx1-apf9328.dts
new file mode 100644
index 000000000..07d92fb40
--- /dev/null
+++ b/arch/arm/boot/dts/imx1-apf9328.dts
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx1.dtsi"
+
+/ {
+ model = "Armadeus APF9328";
+ compatible = "armadeus,imx1-apf9328", "fsl,imx1";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory {
+ reg = <0x08000000 0x00800000>;
+ };
+};
+
+&i2c {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&weim {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_weim>;
+ status = "okay";
+
+ nor: nor@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0x00000000 0x02000000>;
+ bank-width = <2>;
+ fsl,weim-cs-timing = <0x00330e04 0x00000d01>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ eth: eth@4,c00000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_eth>;
+ compatible = "davicom,dm9000";
+ reg = <
+ 4 0x00c00000 0x2
+ 4 0x00c00002 0x2
+ >;
+ interrupt-parent = <&gpio2>;
+ interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
+ fsl,weim-cs-timing = <0x0000c700 0x19190d01>;
+ };
+};
+
+&iomuxc {
+ imx1-apf9328 {
+ pinctrl_eth: ethgrp {
+ fsl,pins = <
+ MX1_PAD_SIM_SVEN__GPIO2_14 0x0
+ >;
+ };
+
+ pinctrl_i2c: i2cgrp {
+ fsl,pins = <
+ MX1_PAD_I2C_SCL__I2C_SCL 0x0
+ MX1_PAD_I2C_SDA__I2C_SDA 0x0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX1_PAD_UART1_TXD__UART1_TXD 0x0
+ MX1_PAD_UART1_RXD__UART1_RXD 0x0
+ MX1_PAD_UART1_CTS__UART1_CTS 0x0
+ MX1_PAD_UART1_RTS__UART1_RTS 0x0
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX1_PAD_UART2_TXD__UART2_TXD 0x0
+ MX1_PAD_UART2_RXD__UART2_RXD 0x0
+ MX1_PAD_UART2_CTS__UART2_CTS 0x0
+ MX1_PAD_UART2_RTS__UART2_RTS 0x0
+ >;
+ };
+
+ pinctrl_weim: weimgrp {
+ fsl,pins = <
+ MX1_PAD_A0__A0 0x0
+ MX1_PAD_A16__A16 0x0
+ MX1_PAD_A17__A17 0x0
+ MX1_PAD_A18__A18 0x0
+ MX1_PAD_A19__A19 0x0
+ MX1_PAD_A20__A20 0x0
+ MX1_PAD_A21__A21 0x0
+ MX1_PAD_A22__A22 0x0
+ MX1_PAD_A23__A23 0x0
+ MX1_PAD_A24__A24 0x0
+ MX1_PAD_BCLK__BCLK 0x0
+ MX1_PAD_CS4__CS4 0x0
+ MX1_PAD_DTACK__DTACK 0x0
+ MX1_PAD_ECB__ECB 0x0
+ MX1_PAD_LBA__LBA 0x0
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx1-pinfunc.h b/arch/arm/boot/dts/imx1-pinfunc.h
new file mode 100644
index 000000000..22bec8b87
--- /dev/null
+++ b/arch/arm/boot/dts/imx1-pinfunc.h
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * 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 __DTS_IMX1_PINFUNC_H
+#define __DTS_IMX1_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <pin mux_id>
+ * mux_id consists of
+ * function + (direction << 2) + (gpio_oconf << 4) + (gpio_iconfa << 8) + (gpio_iconfb << 10)
+ *
+ * function: 0 - Primary function
+ * 1 - Alternate function
+ * 2 - GPIO
+ * direction: 0 - Input
+ * 1 - Output
+ * gpio_oconf: 0 - A_IN
+ * 1 - B_IN
+ * 2 - A_OUT
+ * 3 - Data Register
+ * gpio_iconfa/b: 0 - GPIO_IN
+ * 1 - Interrupt Status Register
+ * 2 - 0
+ * 3 - 1
+ *
+ * 'pin' is an integer between 0 and 0xbf. i.MX1 has 4 ports with 32 configurable
+ * configurable pins each. 'pin' is PORT * 32 + PORT_PIN, PORT_PIN is the pin
+ * number on the specific port (between 0 and 31).
+ */
+
+#define MX1_PAD_A24__A24 0x00 0x004
+#define MX1_PAD_A24__GPIO1_0 0x00 0x032
+#define MX1_PAD_A24__SPI2_CLK 0x00 0x006
+#define MX1_PAD_TIN__TIN 0x01 0x000
+#define MX1_PAD_TIN__GPIO1_1 0x01 0x032
+#define MX1_PAD_TIN__SPI2_RXD 0x01 0x022
+#define MX1_PAD_PWMO__PWMO 0x02 0x004
+#define MX1_PAD_PWMO__GPIO1_2 0x02 0x032
+#define MX1_PAD_CSI_MCLK__CSI_MCLK 0x03 0x004
+#define MX1_PAD_CSI_MCLK__GPIO1_3 0x03 0x032
+#define MX1_PAD_CSI_D0__CSI_D0 0x04 0x000
+#define MX1_PAD_CSI_D0__GPIO1_4 0x04 0x032
+#define MX1_PAD_CSI_D1__CSI_D1 0x05 0x000
+#define MX1_PAD_CSI_D1__GPIO1_5 0x05 0x032
+#define MX1_PAD_CSI_D2__CSI_D2 0x06 0x000
+#define MX1_PAD_CSI_D2__GPIO1_6 0x06 0x032
+#define MX1_PAD_CSI_D3__CSI_D3 0x07 0x000
+#define MX1_PAD_CSI_D3__GPIO1_7 0x07 0x032
+#define MX1_PAD_CSI_D4__CSI_D4 0x08 0x000
+#define MX1_PAD_CSI_D4__GPIO1_8 0x08 0x032
+#define MX1_PAD_CSI_D5__CSI_D5 0x09 0x000
+#define MX1_PAD_CSI_D5__GPIO1_9 0x09 0x032
+#define MX1_PAD_CSI_D6__CSI_D6 0x0a 0x000
+#define MX1_PAD_CSI_D6__GPIO1_10 0x0a 0x032
+#define MX1_PAD_CSI_D7__CSI_D7 0x0b 0x000
+#define MX1_PAD_CSI_D7__GPIO1_11 0x0b 0x032
+#define MX1_PAD_CSI_VSYNC__CSI_VSYNC 0x0c 0x000
+#define MX1_PAD_CSI_VSYNC__GPIO1_12 0x0c 0x032
+#define MX1_PAD_CSI_HSYNC__CSI_HSYNC 0x0d 0x000
+#define MX1_PAD_CSI_HSYNC__GPIO1_13 0x0d 0x032
+#define MX1_PAD_CSI_PIXCLK__CSI_PIXCLK 0x0e 0x000
+#define MX1_PAD_CSI_PIXCLK__GPIO1_14 0x0e 0x032
+#define MX1_PAD_I2C_SDA__I2C_SDA 0x0f 0x000
+#define MX1_PAD_I2C_SDA__GPIO1_15 0x0f 0x032
+#define MX1_PAD_I2C_SCL__I2C_SCL 0x10 0x004
+#define MX1_PAD_I2C_SCL__GPIO1_16 0x10 0x032
+#define MX1_PAD_DTACK__DTACK 0x11 0x000
+#define MX1_PAD_DTACK__GPIO1_17 0x11 0x032
+#define MX1_PAD_DTACK__SPI2_SS 0x11 0x002
+#define MX1_PAD_DTACK__A25 0x11 0x016
+#define MX1_PAD_BCLK__BCLK 0x12 0x004
+#define MX1_PAD_BCLK__GPIO1_18 0x12 0x032
+#define MX1_PAD_LBA__LBA 0x13 0x004
+#define MX1_PAD_LBA__GPIO1_19 0x13 0x032
+#define MX1_PAD_ECB__ECB 0x14 0x000
+#define MX1_PAD_ECB__GPIO1_20 0x14 0x032
+#define MX1_PAD_A0__A0 0x15 0x004
+#define MX1_PAD_A0__GPIO1_21 0x15 0x032
+#define MX1_PAD_CS4__CS4 0x16 0x004
+#define MX1_PAD_CS4__GPIO1_22 0x16 0x032
+#define MX1_PAD_CS5__CS5 0x17 0x004
+#define MX1_PAD_CS5__GPIO1_23 0x17 0x032
+#define MX1_PAD_A16__A16 0x18 0x004
+#define MX1_PAD_A16__GPIO1_24 0x18 0x032
+#define MX1_PAD_A17__A17 0x19 0x004
+#define MX1_PAD_A17__GPIO1_25 0x19 0x032
+#define MX1_PAD_A18__A18 0x1a 0x004
+#define MX1_PAD_A18__GPIO1_26 0x1a 0x032
+#define MX1_PAD_A19__A19 0x1b 0x004
+#define MX1_PAD_A19__GPIO1_27 0x1b 0x032
+#define MX1_PAD_A20__A20 0x1c 0x004
+#define MX1_PAD_A20__GPIO1_28 0x1c 0x032
+#define MX1_PAD_A21__A21 0x1d 0x004
+#define MX1_PAD_A21__GPIO1_29 0x1d 0x032
+#define MX1_PAD_A22__A22 0x1e 0x004
+#define MX1_PAD_A22__GPIO1_30 0x1e 0x032
+#define MX1_PAD_A23__A23 0x1f 0x004
+#define MX1_PAD_A23__GPIO1_31 0x1f 0x032
+#define MX1_PAD_SD_DAT0__SD_DAT0 0x28 0x000
+#define MX1_PAD_SD_DAT0__MS_PI0 0x28 0x001
+#define MX1_PAD_SD_DAT0__GPIO2_8 0x28 0x032
+#define MX1_PAD_SD_DAT1__SD_DAT1 0x29 0x000
+#define MX1_PAD_SD_DAT1__MS_PI1 0x29 0x001
+#define MX1_PAD_SD_DAT1__GPIO2_9 0x29 0x032
+#define MX1_PAD_SD_DAT2__SD_DAT2 0x2a 0x000
+#define MX1_PAD_SD_DAT2__MS_SCLKI 0x2a 0x001
+#define MX1_PAD_SD_DAT2__GPIO2_10 0x2a 0x032
+#define MX1_PAD_SD_DAT3__SD_DAT3 0x2b 0x000
+#define MX1_PAD_SD_DAT3__MS_SDIO 0x2b 0x001
+#define MX1_PAD_SD_DAT3__GPIO2_11 0x2b 0x032
+#define MX1_PAD_SD_SCLK__SD_SCLK 0x2c 0x004
+#define MX1_PAD_SD_SCLK__MS_SCLKO 0x2c 0x005
+#define MX1_PAD_SD_SCLK__GPIO2_12 0x2c 0x032
+#define MX1_PAD_SD_CMD__SD_CMD 0x2d 0x000
+#define MX1_PAD_SD_CMD__MS_BS 0x2d 0x005
+#define MX1_PAD_SD_CMD__GPIO2_13 0x2d 0x032
+#define MX1_PAD_SIM_SVEN__SIM_SVEN 0x2e 0x004
+#define MX1_PAD_SIM_SVEN__SSI_RXFS 0x2e 0x001
+#define MX1_PAD_SIM_SVEN__GPIO2_14 0x2e 0x032
+#define MX1_PAD_SIM_PD__SIM_PD 0x2f 0x000
+#define MX1_PAD_SIM_PD__SSI_RXCLK 0x2f 0x001
+#define MX1_PAD_SIM_PD__GPIO2_15 0x2f 0x032
+#define MX1_PAD_SIM_TX__SIM_TX 0x30 0x000
+#define MX1_PAD_SIM_TX__SSI_RXDAT 0x30 0x001
+#define MX1_PAD_SIM_TX__GPIO2_16 0x30 0x032
+#define MX1_PAD_SIM_RX__SIM_RX 0x31 0x000
+#define MX1_PAD_SIM_RX__SSI_TXDAT 0x31 0x005
+#define MX1_PAD_SIM_RX__GPIO2_17 0x31 0x032
+#define MX1_PAD_SIM_RST__SIM_RST 0x32 0x004
+#define MX1_PAD_SIM_RST__SSI_TXFS 0x32 0x001
+#define MX1_PAD_SIM_RST__GPIO2_18 0x32 0x032
+#define MX1_PAD_SIM_CLK__SIM_CLK 0x33 0x004
+#define MX1_PAD_SIM_CLK__SSI_TXCLK 0x33 0x001
+#define MX1_PAD_SIM_CLK__GPIO2_19 0x33 0x032
+#define MX1_PAD_USBD_AFE__USBD_AFE 0x34 0x004
+#define MX1_PAD_USBD_AFE__GPIO2_20 0x34 0x032
+#define MX1_PAD_USBD_OE__USBD_OE 0x35 0x004
+#define MX1_PAD_USBD_OE__GPIO2_21 0x35 0x032
+#define MX1_PAD_USBD_RCV__USBD_RCV 0x36 0x000
+#define MX1_PAD_USBD_RCV__GPIO2_22 0x36 0x032
+#define MX1_PAD_USBD_SUSPND__USBD_SUSPND 0x37 0x004
+#define MX1_PAD_USBD_SUSPND__GPIO2_23 0x37 0x032
+#define MX1_PAD_USBD_VP__USBD_VP 0x38 0x000
+#define MX1_PAD_USBD_VP__GPIO2_24 0x38 0x032
+#define MX1_PAD_USBD_VM__USBD_VM 0x39 0x000
+#define MX1_PAD_USBD_VM__GPIO2_25 0x39 0x032
+#define MX1_PAD_USBD_VPO__USBD_VPO 0x3a 0x004
+#define MX1_PAD_USBD_VPO__GPIO2_26 0x3a 0x032
+#define MX1_PAD_USBD_VMO__USBD_VMO 0x3b 0x004
+#define MX1_PAD_USBD_VMO__GPIO2_27 0x3b 0x032
+#define MX1_PAD_UART2_CTS__UART2_CTS 0x3c 0x004
+#define MX1_PAD_UART2_CTS__GPIO2_28 0x3c 0x032
+#define MX1_PAD_UART2_RTS__UART2_RTS 0x3d 0x000
+#define MX1_PAD_UART2_RTS__GPIO2_29 0x3d 0x032
+#define MX1_PAD_UART2_TXD__UART2_TXD 0x3e 0x004
+#define MX1_PAD_UART2_TXD__GPIO2_30 0x3e 0x032
+#define MX1_PAD_UART2_RXD__UART2_RXD 0x3f 0x000
+#define MX1_PAD_UART2_RXD__GPIO2_31 0x3f 0x032
+#define MX1_PAD_SSI_RXFS__SSI_RXFS 0x43 0x000
+#define MX1_PAD_SSI_RXFS__GPIO3_3 0x43 0x032
+#define MX1_PAD_SSI_RXCLK__SSI_RXCLK 0x44 0x000
+#define MX1_PAD_SSI_RXCLK__GPIO3_4 0x44 0x032
+#define MX1_PAD_SSI_RXDAT__SSI_RXDAT 0x45 0x000
+#define MX1_PAD_SSI_RXDAT__GPIO3_5 0x45 0x032
+#define MX1_PAD_SSI_TXDAT__SSI_TXDAT 0x46 0x004
+#define MX1_PAD_SSI_TXDAT__GPIO3_6 0x46 0x032
+#define MX1_PAD_SSI_TXFS__SSI_TXFS 0x47 0x000
+#define MX1_PAD_SSI_TXFS__GPIO3_7 0x47 0x032
+#define MX1_PAD_SSI_TXCLK__SSI_TXCLK 0x48 0x000
+#define MX1_PAD_SSI_TXCLK__GPIO3_8 0x48 0x032
+#define MX1_PAD_UART1_CTS__UART1_CTS 0x49 0x004
+#define MX1_PAD_UART1_CTS__GPIO3_9 0x49 0x032
+#define MX1_PAD_UART1_RTS__UART1_RTS 0x4a 0x000
+#define MX1_PAD_UART1_RTS__GPIO3_10 0x4a 0x032
+#define MX1_PAD_UART1_TXD__UART1_TXD 0x4b 0x004
+#define MX1_PAD_UART1_TXD__GPIO3_11 0x4b 0x032
+#define MX1_PAD_UART1_RXD__UART1_RXD 0x4c 0x000
+#define MX1_PAD_UART1_RXD__GPIO3_12 0x4c 0x032
+#define MX1_PAD_SPI1_RDY__SPI1_RDY 0x4d 0x000
+#define MX1_PAD_SPI1_RDY__GPIO3_13 0x4d 0x032
+#define MX1_PAD_SPI1_SCLK__SPI1_SCLK 0x4e 0x004
+#define MX1_PAD_SPI1_SCLK__GPIO3_14 0x4e 0x032
+#define MX1_PAD_SPI1_SS__SPI1_SS 0x4f 0x000
+#define MX1_PAD_SPI1_SS__GPIO3_15 0x4f 0x032
+#define MX1_PAD_SPI1_MISO__SPI1_MISO 0x50 0x000
+#define MX1_PAD_SPI1_MISO__GPIO3_16 0x50 0x032
+#define MX1_PAD_SPI1_MOSI__SPI1_MOSI 0x51 0x004
+#define MX1_PAD_SPI1_MOSI__GPIO3_17 0x51 0x032
+#define MX1_PAD_BT13__BT13 0x53 0x004
+#define MX1_PAD_BT13__SSI2_RXCLK 0x53 0x001
+#define MX1_PAD_BT13__GPIO3_19 0x53 0x032
+#define MX1_PAD_BT12__BT12 0x54 0x004
+#define MX1_PAD_BT12__SSI2_TXFS 0x54 0x001
+#define MX1_PAD_BT12__GPIO3_20 0x54 0x032
+#define MX1_PAD_BT11__BT11 0x55 0x004
+#define MX1_PAD_BT11__SSI2_TXCLK 0x55 0x001
+#define MX1_PAD_BT11__GPIO3_21 0x55 0x032
+#define MX1_PAD_BT10__BT10 0x56 0x004
+#define MX1_PAD_BT10__SSI2_TX 0x56 0x001
+#define MX1_PAD_BT10__GPIO3_22 0x56 0x032
+#define MX1_PAD_BT9__BT9 0x57 0x004
+#define MX1_PAD_BT9__SSI2_RX 0x57 0x001
+#define MX1_PAD_BT9__GPIO3_23 0x57 0x032
+#define MX1_PAD_BT8__BT8 0x58 0x004
+#define MX1_PAD_BT8__SSI2_RXFS 0x58 0x001
+#define MX1_PAD_BT8__GPIO3_24 0x58 0x032
+#define MX1_PAD_BT8__UART3_RI 0x58 0x016
+#define MX1_PAD_BT7__BT7 0x59 0x004
+#define MX1_PAD_BT7__GPIO3_25 0x59 0x032
+#define MX1_PAD_BT7__UART3_DSR 0x59 0x016
+#define MX1_PAD_BT6__BT6 0x5a 0x004
+#define MX1_PAD_BT6__GPIO3_26 0x5a 0x032
+#define MX1_PAD_BT6__SPI2_SS3 0x5a 0x016
+#define MX1_PAD_BT6__UART3_DTR 0x5a 0x022
+#define MX1_PAD_BT5__BT5 0x5b 0x000
+#define MX1_PAD_BT5__GPIO3_27 0x5b 0x032
+#define MX1_PAD_BT5__UART3_DCD 0x5b 0x016
+#define MX1_PAD_BT4__BT4 0x5c 0x000
+#define MX1_PAD_BT4__GPIO3_28 0x5c 0x032
+#define MX1_PAD_BT4__UART3_CTS 0x5c 0x016
+#define MX1_PAD_BT3__BT3 0x5d 0x000
+#define MX1_PAD_BT3__GPIO3_29 0x5d 0x032
+#define MX1_PAD_BT3__UART3_RTS 0x5d 0x022
+#define MX1_PAD_BT2__BT2 0x5e 0x004
+#define MX1_PAD_BT2__GPIO3_30 0x5e 0x032
+#define MX1_PAD_BT2__UART3_TX 0x5e 0x016
+#define MX1_PAD_BT1__BT1 0x5f 0x000
+#define MX1_PAD_BT1__GPIO3_31 0x5f 0x032
+#define MX1_PAD_BT1__UART3_RX 0x5f 0x022
+#define MX1_PAD_LSCLK__LSCLK 0x66 0x004
+#define MX1_PAD_LSCLK__GPIO4_6 0x66 0x032
+#define MX1_PAD_REV__REV 0x67 0x004
+#define MX1_PAD_REV__UART2_DTR 0x67 0x001
+#define MX1_PAD_REV__GPIO4_7 0x67 0x032
+#define MX1_PAD_REV__SPI2_CLK 0x67 0x006
+#define MX1_PAD_CLS__CLS 0x68 0x004
+#define MX1_PAD_CLS__UART2_DCD 0x68 0x005
+#define MX1_PAD_CLS__GPIO4_8 0x68 0x032
+#define MX1_PAD_CLS__SPI2_SS 0x68 0x002
+#define MX1_PAD_PS__PS 0x69 0x004
+#define MX1_PAD_PS__UART2_RI 0x69 0x005
+#define MX1_PAD_PS__GPIO4_9 0x69 0x032
+#define MX1_PAD_PS__SPI2_RXD 0x69 0x022
+#define MX1_PAD_SPL_SPR__SPL_SPR 0x6a 0x004
+#define MX1_PAD_SPL_SPR__UART2_DSR 0x6a 0x005
+#define MX1_PAD_SPL_SPR__GPIO4_10 0x6a 0x032
+#define MX1_PAD_SPL_SPR__SPI2_TXD 0x6a 0x006
+#define MX1_PAD_CONTRAST__CONTRAST 0x6b 0x004
+#define MX1_PAD_CONTRAST__GPIO4_11 0x6b 0x032
+#define MX1_PAD_CONTRAST__SPI2_SS2 0x6b 0x012
+#define MX1_PAD_ACD_OE__ACD_OE 0x6c 0x004
+#define MX1_PAD_ACD_OE__GPIO4_12 0x6c 0x032
+#define MX1_PAD_LP_HSYNC__LP_HSYNC 0x6d 0x004
+#define MX1_PAD_LP_HSYNC__GPIO4_13 0x6d 0x032
+#define MX1_PAD_FLM_VSYNC__FLM_VSYNC 0x6e 0x004
+#define MX1_PAD_FLM_VSYNC__GPIO4_14 0x6e 0x032
+#define MX1_PAD_LD0__LD0 0x6f 0x004
+#define MX1_PAD_LD0__GPIO4_15 0x6f 0x032
+#define MX1_PAD_LD1__LD1 0x70 0x004
+#define MX1_PAD_LD1__GPIO4_16 0x70 0x032
+#define MX1_PAD_LD2__LD2 0x71 0x004
+#define MX1_PAD_LD2__GPIO4_17 0x71 0x032
+#define MX1_PAD_LD3__LD3 0x72 0x004
+#define MX1_PAD_LD3__GPIO4_18 0x72 0x032
+#define MX1_PAD_LD4__LD4 0x73 0x004
+#define MX1_PAD_LD4__GPIO4_19 0x73 0x032
+#define MX1_PAD_LD5__LD5 0x74 0x004
+#define MX1_PAD_LD5__GPIO4_20 0x74 0x032
+#define MX1_PAD_LD6__LD6 0x75 0x004
+#define MX1_PAD_LD6__GPIO4_21 0x75 0x032
+#define MX1_PAD_LD7__LD7 0x76 0x004
+#define MX1_PAD_LD7__GPIO4_22 0x76 0x032
+#define MX1_PAD_LD8__LD8 0x77 0x004
+#define MX1_PAD_LD8__GPIO4_23 0x77 0x032
+#define MX1_PAD_LD9__LD9 0x78 0x004
+#define MX1_PAD_LD9__GPIO4_24 0x78 0x032
+#define MX1_PAD_LD10__LD10 0x79 0x004
+#define MX1_PAD_LD10__GPIO4_25 0x79 0x032
+#define MX1_PAD_LD11__LD11 0x7a 0x004
+#define MX1_PAD_LD11__GPIO4_26 0x7a 0x032
+#define MX1_PAD_LD12__LD12 0x7b 0x004
+#define MX1_PAD_LD12__GPIO4_27 0x7b 0x032
+#define MX1_PAD_LD13__LD13 0x7c 0x004
+#define MX1_PAD_LD13__GPIO4_28 0x7c 0x032
+#define MX1_PAD_LD14__LD14 0x7d 0x004
+#define MX1_PAD_LD14__GPIO4_29 0x7d 0x032
+#define MX1_PAD_LD15__LD15 0x7e 0x004
+#define MX1_PAD_LD15__GPIO4_30 0x7e 0x032
+#define MX1_PAD_TMR2OUT__TMR2OUT 0x7f 0x000
+#define MX1_PAD_TMR2OUT__GPIO4_31 0x7f 0x032
+#define MX1_PAD_TMR2OUT__SPI2_TXD 0x7f 0x006
+
+#endif
diff --git a/arch/arm/boot/dts/imx1.dtsi b/arch/arm/boot/dts/imx1.dtsi
new file mode 100644
index 000000000..22f5d1db5
--- /dev/null
+++ b/arch/arm/boot/dts/imx1.dtsi
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * 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 "skeleton.dtsi"
+#include "imx1-pinfunc.h"
+
+#include <dt-bindings/clock/imx1-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ aliases {
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ i2c0 = &i2c;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ spi0 = &cspi1;
+ spi1 = &cspi2;
+ };
+
+ aitc: aitc-interrupt-controller@00223000 {
+ compatible = "fsl,imx1-aitc", "fsl,avic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x00223000 0x1000>;
+ };
+
+ cpus {
+ #size-cells = <0>;
+ #address-cells = <1>;
+
+ cpu: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,arm920t";
+ operating-points = <200000 1900000>;
+ clock-latency = <62500>;
+ clocks = <&clks IMX1_CLK_MCU>;
+ voltage-tolerance = <5>;
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&aitc>;
+ ranges;
+
+ aipi@00200000 {
+ compatible = "fsl,aipi-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x00200000 0x10000>;
+ ranges;
+
+ gpt1: timer@00202000 {
+ compatible = "fsl,imx1-gpt";
+ reg = <0x00202000 0x1000>;
+ interrupts = <59>;
+ clocks = <&clks IMX1_CLK_HCLK>,
+ <&clks IMX1_CLK_PER1>;
+ clock-names = "ipg", "per";
+ };
+
+ gpt2: timer@00203000 {
+ compatible = "fsl,imx1-gpt";
+ reg = <0x00203000 0x1000>;
+ interrupts = <58>;
+ clocks = <&clks IMX1_CLK_HCLK>,
+ <&clks IMX1_CLK_PER1>;
+ clock-names = "ipg", "per";
+ };
+
+ fb: fb@00205000 {
+ compatible = "fsl,imx1-fb";
+ reg = <0x00205000 0x1000>;
+ interrupts = <14>;
+ clocks = <&clks IMX1_CLK_DUMMY>,
+ <&clks IMX1_CLK_DUMMY>,
+ <&clks IMX1_CLK_PER2>;
+ clock-names = "ipg", "ahb", "per";
+ status = "disabled";
+ };
+
+ uart1: serial@00206000 {
+ compatible = "fsl,imx1-uart";
+ reg = <0x00206000 0x1000>;
+ interrupts = <30 29 26>;
+ clocks = <&clks IMX1_CLK_HCLK>,
+ <&clks IMX1_CLK_PER1>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart2: serial@00207000 {
+ compatible = "fsl,imx1-uart";
+ reg = <0x00207000 0x1000>;
+ interrupts = <24 23 20>;
+ clocks = <&clks IMX1_CLK_HCLK>,
+ <&clks IMX1_CLK_PER1>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ pwm: pwm@00208000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx1-pwm";
+ reg = <0x00208000 0x1000>;
+ interrupts = <34>;
+ clocks = <&clks IMX1_CLK_DUMMY>,
+ <&clks IMX1_CLK_PER1>;
+ clock-names = "ipg", "per";
+ };
+
+ dma: dma@00209000 {
+ compatible = "fsl,imx1-dma";
+ reg = <0x00209000 0x1000>;
+ interrupts = <61 60>;
+ clocks = <&clks IMX1_CLK_HCLK>,
+ <&clks IMX1_CLK_DMA_GATE>;
+ clock-names = "ipg", "ahb";
+ #dma-cells = <1>;
+ };
+
+ uart3: serial@0020a000 {
+ compatible = "fsl,imx1-uart";
+ reg = <0x0020a000 0x1000>;
+ interrupts = <54 4 1>;
+ clocks = <&clks IMX1_CLK_UART3_GATE>,
+ <&clks IMX1_CLK_PER1>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+ };
+
+ aipi@00210000 {
+ compatible = "fsl,aipi-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x00210000 0x10000>;
+ ranges;
+
+ cspi1: cspi@00213000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx1-cspi";
+ reg = <0x00213000 0x1000>;
+ interrupts = <41>;
+ clocks = <&clks IMX1_CLK_DUMMY>,
+ <&clks IMX1_CLK_PER1>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ i2c: i2c@00217000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx1-i2c";
+ reg = <0x00217000 0x1000>;
+ interrupts = <39>;
+ clocks = <&clks IMX1_CLK_HCLK>;
+ status = "disabled";
+ };
+
+ cspi2: cspi@00219000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx1-cspi";
+ reg = <0x00219000 0x1000>;
+ interrupts = <40>;
+ clocks = <&clks IMX1_CLK_DUMMY>,
+ <&clks IMX1_CLK_PER1>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ clks: ccm@0021b000 {
+ compatible = "fsl,imx1-ccm";
+ reg = <0x0021b000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ iomuxc: iomuxc@0021c000 {
+ compatible = "fsl,imx1-iomuxc";
+ reg = <0x0021c000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio1: gpio@0021c000 {
+ compatible = "fsl,imx1-gpio";
+ reg = <0x0021c000 0x100>;
+ interrupts = <11>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@0021c100 {
+ compatible = "fsl,imx1-gpio";
+ reg = <0x0021c100 0x100>;
+ interrupts = <12>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@0021c200 {
+ compatible = "fsl,imx1-gpio";
+ reg = <0x0021c200 0x100>;
+ interrupts = <13>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@0021c300 {
+ compatible = "fsl,imx1-gpio";
+ reg = <0x0021c300 0x100>;
+ interrupts = <62>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+ };
+
+ weim: weim@00220000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,imx1-weim";
+ reg = <0x00220000 0x1000>;
+ clocks = <&clks IMX1_CLK_DUMMY>;
+ ranges = <
+ 0 0 0x10000000 0x02000000
+ 1 0 0x12000000 0x01000000
+ 2 0 0x13000000 0x01000000
+ 3 0 0x14000000 0x01000000
+ 4 0 0x15000000 0x01000000
+ 5 0 0x16000000 0x01000000
+ >;
+ status = "disabled";
+ };
+
+ esram: esram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x20000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx23-evk.dts b/arch/arm/boot/dts/imx23-evk.dts
new file mode 100644
index 000000000..57e29977b
--- /dev/null
+++ b/arch/arm/boot/dts/imx23-evk.dts
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2012 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
+ */
+
+/dts-v1/;
+#include "imx23.dtsi"
+
+/ {
+ model = "Freescale i.MX23 Evaluation Kit";
+ compatible = "fsl,imx23-evk", "fsl,imx23";
+
+ memory {
+ reg = <0x40000000 0x08000000>;
+ };
+
+ apb@80000000 {
+ apbh@80000000 {
+ gpmi-nand@8000c000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpmi_pins_a &gpmi_pins_fixup>;
+ status = "okay";
+ };
+
+ ssp0: ssp@80010000 {
+ compatible = "fsl,imx23-mmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_pins_fixup>;
+ bus-width = <4>;
+ wp-gpios = <&gpio1 30 0>;
+ vmmc-supply = <&reg_vddio_sd0>;
+ status = "okay";
+ };
+
+ pinctrl@80018000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hog_pins_a>;
+
+ hog_pins_a: hog@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX23_PAD_LCD_RESET__GPIO_1_18
+ MX23_PAD_PWM3__GPIO_1_29
+ MX23_PAD_PWM4__GPIO_1_30
+ MX23_PAD_SSP1_DETECT__SSP1_DETECT
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+ };
+
+ lcdif@80030000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcdif_24bit_pins_a>;
+ lcd-supply = <&reg_lcd_3v3>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display0 {
+ bits-per-pixel = <32>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <9200000>;
+ hactive = <480>;
+ vactive = <272>;
+ hback-porch = <15>;
+ hfront-porch = <8>;
+ vback-porch = <12>;
+ vfront-porch = <4>;
+ hsync-len = <1>;
+ vsync-len = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+ };
+ };
+
+ apbx@80040000 {
+ lradc@80050000 {
+ status = "okay";
+ fsl,lradc-touchscreen-wires = <4>;
+ };
+
+ pwm: pwm@80064000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm2_pins_a>;
+ status = "okay";
+ };
+
+ auart0: serial@8006c000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart0_pins_a>;
+ status = "okay";
+ };
+
+ duart: serial@80070000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&duart_pins_a>;
+ status = "okay";
+ };
+
+ usbphy0: usbphy@8007c000 {
+ status = "okay";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ usb0: usb@80080000 {
+ status = "okay";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_vddio_sd0: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vddio-sd0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 29 0>;
+ };
+
+ reg_lcd_3v3: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "lcd-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 18 0>;
+ enable-active-high;
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 2 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx23-olinuxino.dts b/arch/arm/boot/dts/imx23-olinuxino.dts
new file mode 100644
index 000000000..82045398b
--- /dev/null
+++ b/arch/arm/boot/dts/imx23-olinuxino.dts
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * Author: Fabio Estevam <fabio.estevam@freescale.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
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include "imx23.dtsi"
+
+/ {
+ model = "i.MX23 Olinuxino Low Cost Board";
+ compatible = "olimex,imx23-olinuxino", "fsl,imx23";
+
+ memory {
+ reg = <0x40000000 0x04000000>;
+ };
+
+ apb@80000000 {
+ apbh@80000000 {
+ ssp0: ssp@80010000 {
+ compatible = "fsl,imx23-mmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_pins_fixup>;
+ bus-width = <4>;
+ broken-cd;
+ status = "okay";
+ };
+
+ pinctrl@80018000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hog_pins_a>;
+
+ hog_pins_a: hog@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX23_PAD_GPMI_ALE__GPIO_0_17
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ led_pin_gpio2_1: led_gpio2_1@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX23_PAD_SSP1_DETECT__GPIO_2_1
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+ };
+
+ ssp1: ssp@80034000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx23-spi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_pins_a>;
+ status = "okay";
+ };
+ };
+
+ apbx@80040000 {
+ lradc@80050000 {
+ status = "okay";
+ };
+
+ duart: serial@80070000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&duart_pins_a>;
+ status = "okay";
+ };
+
+ auart0: serial@8006c000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart0_2pins_a>;
+ status = "okay";
+ };
+
+ usbphy0: usbphy@8007c000 {
+ status = "okay";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ usb0: usb@80080000 {
+ dr_mode = "host";
+ vbus-supply = <&reg_usb0_vbus>;
+ status = "okay";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb0_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb0_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ startup-delay-us = <300>; /* LAN9215 requires a POR of 200us minimum */
+ gpio = <&gpio0 17 0>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pin_gpio2_1>;
+
+ user {
+ label = "green";
+ gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx23-pinfunc.h b/arch/arm/boot/dts/imx23-pinfunc.h
new file mode 100644
index 000000000..5c0f32ca3
--- /dev/null
+++ b/arch/arm/boot/dts/imx23-pinfunc.h
@@ -0,0 +1,333 @@
+/*
+ * Header providing constants for i.MX23 pinctrl bindings.
+ *
+ * Copyright (C) 2013 Lothar WaĂŸmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DT_BINDINGS_MX23_PINCTRL_H__
+#define __DT_BINDINGS_MX23_PINCTRL_H__
+
+#include "mxs-pinfunc.h"
+
+#define MX23_PAD_GPMI_D00__GPMI_D00 0x0000
+#define MX23_PAD_GPMI_D01__GPMI_D01 0x0010
+#define MX23_PAD_GPMI_D02__GPMI_D02 0x0020
+#define MX23_PAD_GPMI_D03__GPMI_D03 0x0030
+#define MX23_PAD_GPMI_D04__GPMI_D04 0x0040
+#define MX23_PAD_GPMI_D05__GPMI_D05 0x0050
+#define MX23_PAD_GPMI_D06__GPMI_D06 0x0060
+#define MX23_PAD_GPMI_D07__GPMI_D07 0x0070
+#define MX23_PAD_GPMI_D08__GPMI_D08 0x0080
+#define MX23_PAD_GPMI_D09__GPMI_D09 0x0090
+#define MX23_PAD_GPMI_D10__GPMI_D10 0x00a0
+#define MX23_PAD_GPMI_D11__GPMI_D11 0x00b0
+#define MX23_PAD_GPMI_D12__GPMI_D12 0x00c0
+#define MX23_PAD_GPMI_D13__GPMI_D13 0x00d0
+#define MX23_PAD_GPMI_D14__GPMI_D14 0x00e0
+#define MX23_PAD_GPMI_D15__GPMI_D15 0x00f0
+#define MX23_PAD_GPMI_CLE__GPMI_CLE 0x0100
+#define MX23_PAD_GPMI_ALE__GPMI_ALE 0x0110
+#define MX23_PAD_GPMI_CE2N__GPMI_CE2N 0x0120
+#define MX23_PAD_GPMI_RDY0__GPMI_RDY0 0x0130
+#define MX23_PAD_GPMI_RDY1__GPMI_RDY1 0x0140
+#define MX23_PAD_GPMI_RDY2__GPMI_RDY2 0x0150
+#define MX23_PAD_GPMI_RDY3__GPMI_RDY3 0x0160
+#define MX23_PAD_GPMI_WPN__GPMI_WPN 0x0170
+#define MX23_PAD_GPMI_WRN__GPMI_WRN 0x0180
+#define MX23_PAD_GPMI_RDN__GPMI_RDN 0x0190
+#define MX23_PAD_AUART1_CTS__AUART1_CTS 0x01a0
+#define MX23_PAD_AUART1_RTS__AUART1_RTS 0x01b0
+#define MX23_PAD_AUART1_RX__AUART1_RX 0x01c0
+#define MX23_PAD_AUART1_TX__AUART1_TX 0x01d0
+#define MX23_PAD_I2C_SCL__I2C_SCL 0x01e0
+#define MX23_PAD_I2C_SDA__I2C_SDA 0x01f0
+#define MX23_PAD_LCD_D00__LCD_D00 0x1000
+#define MX23_PAD_LCD_D01__LCD_D01 0x1010
+#define MX23_PAD_LCD_D02__LCD_D02 0x1020
+#define MX23_PAD_LCD_D03__LCD_D03 0x1030
+#define MX23_PAD_LCD_D04__LCD_D04 0x1040
+#define MX23_PAD_LCD_D05__LCD_D05 0x1050
+#define MX23_PAD_LCD_D06__LCD_D06 0x1060
+#define MX23_PAD_LCD_D07__LCD_D07 0x1070
+#define MX23_PAD_LCD_D08__LCD_D08 0x1080
+#define MX23_PAD_LCD_D09__LCD_D09 0x1090
+#define MX23_PAD_LCD_D10__LCD_D10 0x10a0
+#define MX23_PAD_LCD_D11__LCD_D11 0x10b0
+#define MX23_PAD_LCD_D12__LCD_D12 0x10c0
+#define MX23_PAD_LCD_D13__LCD_D13 0x10d0
+#define MX23_PAD_LCD_D14__LCD_D14 0x10e0
+#define MX23_PAD_LCD_D15__LCD_D15 0x10f0
+#define MX23_PAD_LCD_D16__LCD_D16 0x1100
+#define MX23_PAD_LCD_D17__LCD_D17 0x1110
+#define MX23_PAD_LCD_RESET__LCD_RESET 0x1120
+#define MX23_PAD_LCD_RS__LCD_RS 0x1130
+#define MX23_PAD_LCD_WR__LCD_WR 0x1140
+#define MX23_PAD_LCD_CS__LCD_CS 0x1150
+#define MX23_PAD_LCD_DOTCK__LCD_DOTCK 0x1160
+#define MX23_PAD_LCD_ENABLE__LCD_ENABLE 0x1170
+#define MX23_PAD_LCD_HSYNC__LCD_HSYNC 0x1180
+#define MX23_PAD_LCD_VSYNC__LCD_VSYNC 0x1190
+#define MX23_PAD_PWM0__PWM0 0x11a0
+#define MX23_PAD_PWM1__PWM1 0x11b0
+#define MX23_PAD_PWM2__PWM2 0x11c0
+#define MX23_PAD_PWM3__PWM3 0x11d0
+#define MX23_PAD_PWM4__PWM4 0x11e0
+#define MX23_PAD_SSP1_CMD__SSP1_CMD 0x2000
+#define MX23_PAD_SSP1_DETECT__SSP1_DETECT 0x2010
+#define MX23_PAD_SSP1_DATA0__SSP1_DATA0 0x2020
+#define MX23_PAD_SSP1_DATA1__SSP1_DATA1 0x2030
+#define MX23_PAD_SSP1_DATA2__SSP1_DATA2 0x2040
+#define MX23_PAD_SSP1_DATA3__SSP1_DATA3 0x2050
+#define MX23_PAD_SSP1_SCK__SSP1_SCK 0x2060
+#define MX23_PAD_ROTARYA__ROTARYA 0x2070
+#define MX23_PAD_ROTARYB__ROTARYB 0x2080
+#define MX23_PAD_EMI_A00__EMI_A00 0x2090
+#define MX23_PAD_EMI_A01__EMI_A01 0x20a0
+#define MX23_PAD_EMI_A02__EMI_A02 0x20b0
+#define MX23_PAD_EMI_A03__EMI_A03 0x20c0
+#define MX23_PAD_EMI_A04__EMI_A04 0x20d0
+#define MX23_PAD_EMI_A05__EMI_A05 0x20e0
+#define MX23_PAD_EMI_A06__EMI_A06 0x20f0
+#define MX23_PAD_EMI_A07__EMI_A07 0x2100
+#define MX23_PAD_EMI_A08__EMI_A08 0x2110
+#define MX23_PAD_EMI_A09__EMI_A09 0x2120
+#define MX23_PAD_EMI_A10__EMI_A10 0x2130
+#define MX23_PAD_EMI_A11__EMI_A11 0x2140
+#define MX23_PAD_EMI_A12__EMI_A12 0x2150
+#define MX23_PAD_EMI_BA0__EMI_BA0 0x2160
+#define MX23_PAD_EMI_BA1__EMI_BA1 0x2170
+#define MX23_PAD_EMI_CASN__EMI_CASN 0x2180
+#define MX23_PAD_EMI_CE0N__EMI_CE0N 0x2190
+#define MX23_PAD_EMI_CE1N__EMI_CE1N 0x21a0
+#define MX23_PAD_GPMI_CE1N__GPMI_CE1N 0x21b0
+#define MX23_PAD_GPMI_CE0N__GPMI_CE0N 0x21c0
+#define MX23_PAD_EMI_CKE__EMI_CKE 0x21d0
+#define MX23_PAD_EMI_RASN__EMI_RASN 0x21e0
+#define MX23_PAD_EMI_WEN__EMI_WEN 0x21f0
+#define MX23_PAD_EMI_D00__EMI_D00 0x3000
+#define MX23_PAD_EMI_D01__EMI_D01 0x3010
+#define MX23_PAD_EMI_D02__EMI_D02 0x3020
+#define MX23_PAD_EMI_D03__EMI_D03 0x3030
+#define MX23_PAD_EMI_D04__EMI_D04 0x3040
+#define MX23_PAD_EMI_D05__EMI_D05 0x3050
+#define MX23_PAD_EMI_D06__EMI_D06 0x3060
+#define MX23_PAD_EMI_D07__EMI_D07 0x3070
+#define MX23_PAD_EMI_D08__EMI_D08 0x3080
+#define MX23_PAD_EMI_D09__EMI_D09 0x3090
+#define MX23_PAD_EMI_D10__EMI_D10 0x30a0
+#define MX23_PAD_EMI_D11__EMI_D11 0x30b0
+#define MX23_PAD_EMI_D12__EMI_D12 0x30c0
+#define MX23_PAD_EMI_D13__EMI_D13 0x30d0
+#define MX23_PAD_EMI_D14__EMI_D14 0x30e0
+#define MX23_PAD_EMI_D15__EMI_D15 0x30f0
+#define MX23_PAD_EMI_DQM0__EMI_DQM0 0x3100
+#define MX23_PAD_EMI_DQM1__EMI_DQM1 0x3110
+#define MX23_PAD_EMI_DQS0__EMI_DQS0 0x3120
+#define MX23_PAD_EMI_DQS1__EMI_DQS1 0x3130
+#define MX23_PAD_EMI_CLK__EMI_CLK 0x3140
+#define MX23_PAD_EMI_CLKN__EMI_CLKN 0x3150
+#define MX23_PAD_GPMI_D00__LCD_D8 0x0001
+#define MX23_PAD_GPMI_D01__LCD_D9 0x0011
+#define MX23_PAD_GPMI_D02__LCD_D10 0x0021
+#define MX23_PAD_GPMI_D03__LCD_D11 0x0031
+#define MX23_PAD_GPMI_D04__LCD_D12 0x0041
+#define MX23_PAD_GPMI_D05__LCD_D13 0x0051
+#define MX23_PAD_GPMI_D06__LCD_D14 0x0061
+#define MX23_PAD_GPMI_D07__LCD_D15 0x0071
+#define MX23_PAD_GPMI_D08__LCD_D18 0x0081
+#define MX23_PAD_GPMI_D09__LCD_D19 0x0091
+#define MX23_PAD_GPMI_D10__LCD_D20 0x00a1
+#define MX23_PAD_GPMI_D11__LCD_D21 0x00b1
+#define MX23_PAD_GPMI_D12__LCD_D22 0x00c1
+#define MX23_PAD_GPMI_D13__LCD_D23 0x00d1
+#define MX23_PAD_GPMI_D14__AUART2_RX 0x00e1
+#define MX23_PAD_GPMI_D15__AUART2_TX 0x00f1
+#define MX23_PAD_GPMI_CLE__LCD_D16 0x0101
+#define MX23_PAD_GPMI_ALE__LCD_D17 0x0111
+#define MX23_PAD_GPMI_CE2N__ATA_A2 0x0121
+#define MX23_PAD_AUART1_RTS__IR_CLK 0x01b1
+#define MX23_PAD_AUART1_RX__IR_RX 0x01c1
+#define MX23_PAD_AUART1_TX__IR_TX 0x01d1
+#define MX23_PAD_I2C_SCL__GPMI_RDY2 0x01e1
+#define MX23_PAD_I2C_SDA__GPMI_CE2N 0x01f1
+#define MX23_PAD_LCD_D00__ETM_DA8 0x1001
+#define MX23_PAD_LCD_D01__ETM_DA9 0x1011
+#define MX23_PAD_LCD_D02__ETM_DA10 0x1021
+#define MX23_PAD_LCD_D03__ETM_DA11 0x1031
+#define MX23_PAD_LCD_D04__ETM_DA12 0x1041
+#define MX23_PAD_LCD_D05__ETM_DA13 0x1051
+#define MX23_PAD_LCD_D06__ETM_DA14 0x1061
+#define MX23_PAD_LCD_D07__ETM_DA15 0x1071
+#define MX23_PAD_LCD_D08__ETM_DA0 0x1081
+#define MX23_PAD_LCD_D09__ETM_DA1 0x1091
+#define MX23_PAD_LCD_D10__ETM_DA2 0x10a1
+#define MX23_PAD_LCD_D11__ETM_DA3 0x10b1
+#define MX23_PAD_LCD_D12__ETM_DA4 0x10c1
+#define MX23_PAD_LCD_D13__ETM_DA5 0x10d1
+#define MX23_PAD_LCD_D14__ETM_DA6 0x10e1
+#define MX23_PAD_LCD_D15__ETM_DA7 0x10f1
+#define MX23_PAD_LCD_RESET__ETM_TCTL 0x1121
+#define MX23_PAD_LCD_RS__ETM_TCLK 0x1131
+#define MX23_PAD_LCD_DOTCK__GPMI_RDY3 0x1161
+#define MX23_PAD_LCD_ENABLE__I2C_SCL 0x1171
+#define MX23_PAD_LCD_HSYNC__I2C_SDA 0x1181
+#define MX23_PAD_LCD_VSYNC__LCD_BUSY 0x1191
+#define MX23_PAD_PWM0__ROTARYA 0x11a1
+#define MX23_PAD_PWM1__ROTARYB 0x11b1
+#define MX23_PAD_PWM2__GPMI_RDY3 0x11c1
+#define MX23_PAD_PWM3__ETM_TCTL 0x11d1
+#define MX23_PAD_PWM4__ETM_TCLK 0x11e1
+#define MX23_PAD_SSP1_DETECT__GPMI_CE3N 0x2011
+#define MX23_PAD_SSP1_DATA1__I2C_SCL 0x2031
+#define MX23_PAD_SSP1_DATA2__I2C_SDA 0x2041
+#define MX23_PAD_ROTARYA__AUART2_RTS 0x2071
+#define MX23_PAD_ROTARYB__AUART2_CTS 0x2081
+#define MX23_PAD_GPMI_D00__SSP2_DATA0 0x0002
+#define MX23_PAD_GPMI_D01__SSP2_DATA1 0x0012
+#define MX23_PAD_GPMI_D02__SSP2_DATA2 0x0022
+#define MX23_PAD_GPMI_D03__SSP2_DATA3 0x0032
+#define MX23_PAD_GPMI_D04__SSP2_DATA4 0x0042
+#define MX23_PAD_GPMI_D05__SSP2_DATA5 0x0052
+#define MX23_PAD_GPMI_D06__SSP2_DATA6 0x0062
+#define MX23_PAD_GPMI_D07__SSP2_DATA7 0x0072
+#define MX23_PAD_GPMI_D08__SSP1_DATA4 0x0082
+#define MX23_PAD_GPMI_D09__SSP1_DATA5 0x0092
+#define MX23_PAD_GPMI_D10__SSP1_DATA6 0x00a2
+#define MX23_PAD_GPMI_D11__SSP1_DATA7 0x00b2
+#define MX23_PAD_GPMI_D15__GPMI_CE3N 0x00f2
+#define MX23_PAD_GPMI_RDY0__SSP2_DETECT 0x0132
+#define MX23_PAD_GPMI_RDY1__SSP2_CMD 0x0142
+#define MX23_PAD_GPMI_WRN__SSP2_SCK 0x0182
+#define MX23_PAD_AUART1_CTS__SSP1_DATA4 0x01a2
+#define MX23_PAD_AUART1_RTS__SSP1_DATA5 0x01b2
+#define MX23_PAD_AUART1_RX__SSP1_DATA6 0x01c2
+#define MX23_PAD_AUART1_TX__SSP1_DATA7 0x01d2
+#define MX23_PAD_I2C_SCL__AUART1_TX 0x01e2
+#define MX23_PAD_I2C_SDA__AUART1_RX 0x01f2
+#define MX23_PAD_LCD_D08__SAIF2_SDATA0 0x1082
+#define MX23_PAD_LCD_D09__SAIF1_SDATA0 0x1092
+#define MX23_PAD_LCD_D10__SAIF_MCLK_BITCLK 0x10a2
+#define MX23_PAD_LCD_D11__SAIF_LRCLK 0x10b2
+#define MX23_PAD_LCD_D12__SAIF2_SDATA1 0x10c2
+#define MX23_PAD_LCD_D13__SAIF2_SDATA2 0x10d2
+#define MX23_PAD_LCD_D14__SAIF1_SDATA2 0x10e2
+#define MX23_PAD_LCD_D15__SAIF1_SDATA1 0x10f2
+#define MX23_PAD_LCD_D16__SAIF_ALT_BITCLK 0x1102
+#define MX23_PAD_LCD_RESET__GPMI_CE3N 0x1122
+#define MX23_PAD_PWM0__DUART_RX 0x11a2
+#define MX23_PAD_PWM1__DUART_TX 0x11b2
+#define MX23_PAD_PWM3__AUART1_CTS 0x11d2
+#define MX23_PAD_PWM4__AUART1_RTS 0x11e2
+#define MX23_PAD_SSP1_CMD__JTAG_TDO 0x2002
+#define MX23_PAD_SSP1_DETECT__USB_OTG_ID 0x2012
+#define MX23_PAD_SSP1_DATA0__JTAG_TDI 0x2022
+#define MX23_PAD_SSP1_DATA1__JTAG_TCLK 0x2032
+#define MX23_PAD_SSP1_DATA2__JTAG_RTCK 0x2042
+#define MX23_PAD_SSP1_DATA3__JTAG_TMS 0x2052
+#define MX23_PAD_SSP1_SCK__JTAG_TRST 0x2062
+#define MX23_PAD_ROTARYA__SPDIF 0x2072
+#define MX23_PAD_ROTARYB__GPMI_CE3N 0x2082
+#define MX23_PAD_GPMI_D00__GPIO_0_0 0x0003
+#define MX23_PAD_GPMI_D01__GPIO_0_1 0x0013
+#define MX23_PAD_GPMI_D02__GPIO_0_2 0x0023
+#define MX23_PAD_GPMI_D03__GPIO_0_3 0x0033
+#define MX23_PAD_GPMI_D04__GPIO_0_4 0x0043
+#define MX23_PAD_GPMI_D05__GPIO_0_5 0x0053
+#define MX23_PAD_GPMI_D06__GPIO_0_6 0x0063
+#define MX23_PAD_GPMI_D07__GPIO_0_7 0x0073
+#define MX23_PAD_GPMI_D08__GPIO_0_8 0x0083
+#define MX23_PAD_GPMI_D09__GPIO_0_9 0x0093
+#define MX23_PAD_GPMI_D10__GPIO_0_10 0x00a3
+#define MX23_PAD_GPMI_D11__GPIO_0_11 0x00b3
+#define MX23_PAD_GPMI_D12__GPIO_0_12 0x00c3
+#define MX23_PAD_GPMI_D13__GPIO_0_13 0x00d3
+#define MX23_PAD_GPMI_D14__GPIO_0_14 0x00e3
+#define MX23_PAD_GPMI_D15__GPIO_0_15 0x00f3
+#define MX23_PAD_GPMI_CLE__GPIO_0_16 0x0103
+#define MX23_PAD_GPMI_ALE__GPIO_0_17 0x0113
+#define MX23_PAD_GPMI_CE2N__GPIO_0_18 0x0123
+#define MX23_PAD_GPMI_RDY0__GPIO_0_19 0x0133
+#define MX23_PAD_GPMI_RDY1__GPIO_0_20 0x0143
+#define MX23_PAD_GPMI_RDY2__GPIO_0_21 0x0153
+#define MX23_PAD_GPMI_RDY3__GPIO_0_22 0x0163
+#define MX23_PAD_GPMI_WPN__GPIO_0_23 0x0173
+#define MX23_PAD_GPMI_WRN__GPIO_0_24 0x0183
+#define MX23_PAD_GPMI_RDN__GPIO_0_25 0x0193
+#define MX23_PAD_AUART1_CTS__GPIO_0_26 0x01a3
+#define MX23_PAD_AUART1_RTS__GPIO_0_27 0x01b3
+#define MX23_PAD_AUART1_RX__GPIO_0_28 0x01c3
+#define MX23_PAD_AUART1_TX__GPIO_0_29 0x01d3
+#define MX23_PAD_I2C_SCL__GPIO_0_30 0x01e3
+#define MX23_PAD_I2C_SDA__GPIO_0_31 0x01f3
+#define MX23_PAD_LCD_D00__GPIO_1_0 0x1003
+#define MX23_PAD_LCD_D01__GPIO_1_1 0x1013
+#define MX23_PAD_LCD_D02__GPIO_1_2 0x1023
+#define MX23_PAD_LCD_D03__GPIO_1_3 0x1033
+#define MX23_PAD_LCD_D04__GPIO_1_4 0x1043
+#define MX23_PAD_LCD_D05__GPIO_1_5 0x1053
+#define MX23_PAD_LCD_D06__GPIO_1_6 0x1063
+#define MX23_PAD_LCD_D07__GPIO_1_7 0x1073
+#define MX23_PAD_LCD_D08__GPIO_1_8 0x1083
+#define MX23_PAD_LCD_D09__GPIO_1_9 0x1093
+#define MX23_PAD_LCD_D10__GPIO_1_10 0x10a3
+#define MX23_PAD_LCD_D11__GPIO_1_11 0x10b3
+#define MX23_PAD_LCD_D12__GPIO_1_12 0x10c3
+#define MX23_PAD_LCD_D13__GPIO_1_13 0x10d3
+#define MX23_PAD_LCD_D14__GPIO_1_14 0x10e3
+#define MX23_PAD_LCD_D15__GPIO_1_15 0x10f3
+#define MX23_PAD_LCD_D16__GPIO_1_16 0x1103
+#define MX23_PAD_LCD_D17__GPIO_1_17 0x1113
+#define MX23_PAD_LCD_RESET__GPIO_1_18 0x1123
+#define MX23_PAD_LCD_RS__GPIO_1_19 0x1133
+#define MX23_PAD_LCD_WR__GPIO_1_20 0x1143
+#define MX23_PAD_LCD_CS__GPIO_1_21 0x1153
+#define MX23_PAD_LCD_DOTCK__GPIO_1_22 0x1163
+#define MX23_PAD_LCD_ENABLE__GPIO_1_23 0x1173
+#define MX23_PAD_LCD_HSYNC__GPIO_1_24 0x1183
+#define MX23_PAD_LCD_VSYNC__GPIO_1_25 0x1193
+#define MX23_PAD_PWM0__GPIO_1_26 0x11a3
+#define MX23_PAD_PWM1__GPIO_1_27 0x11b3
+#define MX23_PAD_PWM2__GPIO_1_28 0x11c3
+#define MX23_PAD_PWM3__GPIO_1_29 0x11d3
+#define MX23_PAD_PWM4__GPIO_1_30 0x11e3
+#define MX23_PAD_SSP1_CMD__GPIO_2_0 0x2003
+#define MX23_PAD_SSP1_DETECT__GPIO_2_1 0x2013
+#define MX23_PAD_SSP1_DATA0__GPIO_2_2 0x2023
+#define MX23_PAD_SSP1_DATA1__GPIO_2_3 0x2033
+#define MX23_PAD_SSP1_DATA2__GPIO_2_4 0x2043
+#define MX23_PAD_SSP1_DATA3__GPIO_2_5 0x2053
+#define MX23_PAD_SSP1_SCK__GPIO_2_6 0x2063
+#define MX23_PAD_ROTARYA__GPIO_2_7 0x2073
+#define MX23_PAD_ROTARYB__GPIO_2_8 0x2083
+#define MX23_PAD_EMI_A00__GPIO_2_9 0x2093
+#define MX23_PAD_EMI_A01__GPIO_2_10 0x20a3
+#define MX23_PAD_EMI_A02__GPIO_2_11 0x20b3
+#define MX23_PAD_EMI_A03__GPIO_2_12 0x20c3
+#define MX23_PAD_EMI_A04__GPIO_2_13 0x20d3
+#define MX23_PAD_EMI_A05__GPIO_2_14 0x20e3
+#define MX23_PAD_EMI_A06__GPIO_2_15 0x20f3
+#define MX23_PAD_EMI_A07__GPIO_2_16 0x2103
+#define MX23_PAD_EMI_A08__GPIO_2_17 0x2113
+#define MX23_PAD_EMI_A09__GPIO_2_18 0x2123
+#define MX23_PAD_EMI_A10__GPIO_2_19 0x2133
+#define MX23_PAD_EMI_A11__GPIO_2_20 0x2143
+#define MX23_PAD_EMI_A12__GPIO_2_21 0x2153
+#define MX23_PAD_EMI_BA0__GPIO_2_22 0x2163
+#define MX23_PAD_EMI_BA1__GPIO_2_23 0x2173
+#define MX23_PAD_EMI_CASN__GPIO_2_24 0x2183
+#define MX23_PAD_EMI_CE0N__GPIO_2_25 0x2193
+#define MX23_PAD_EMI_CE1N__GPIO_2_26 0x21a3
+#define MX23_PAD_GPMI_CE1N__GPIO_2_27 0x21b3
+#define MX23_PAD_GPMI_CE0N__GPIO_2_28 0x21c3
+#define MX23_PAD_EMI_CKE__GPIO_2_29 0x21d3
+#define MX23_PAD_EMI_RASN__GPIO_2_30 0x21e3
+#define MX23_PAD_EMI_WEN__GPIO_2_31 0x21f3
+
+#endif /* __DT_BINDINGS_MX23_PINCTRL_H__ */
diff --git a/arch/arm/boot/dts/imx23-stmp378x_devb.dts b/arch/arm/boot/dts/imx23-stmp378x_devb.dts
new file mode 100644
index 000000000..455169e99
--- /dev/null
+++ b/arch/arm/boot/dts/imx23-stmp378x_devb.dts
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2012 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
+ */
+
+/dts-v1/;
+#include "imx23.dtsi"
+
+/ {
+ model = "Freescale STMP378x Development Board";
+ compatible = "fsl,stmp378x-devb", "fsl,imx23";
+
+ memory {
+ reg = <0x40000000 0x04000000>;
+ };
+
+ apb@80000000 {
+ apbh@80000000 {
+ ssp0: ssp@80010000 {
+ compatible = "fsl,imx23-mmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_pins_fixup>;
+ bus-width = <4>;
+ wp-gpios = <&gpio1 30 0>;
+ vmmc-supply = <&reg_vddio_sd0>;
+ status = "okay";
+ };
+
+ pinctrl@80018000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hog_pins_a>;
+
+ hog_pins_a: hog@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX23_PAD_PWM3__GPIO_1_29
+ MX23_PAD_PWM4__GPIO_1_30
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+ };
+ };
+
+ apbx@80040000 {
+ auart0: serial@8006c000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart0_pins_a>;
+ status = "okay";
+ };
+
+ duart: serial@80070000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&duart_pins_a>;
+ status = "okay";
+ };
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_vddio_sd0: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vddio-sd0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 29 0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
new file mode 100644
index 000000000..0cb8b0b11
--- /dev/null
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -0,0 +1,536 @@
+/*
+ * Copyright 2012 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 "skeleton.dtsi"
+#include "imx23-pinfunc.h"
+
+/ {
+ interrupt-parent = <&icoll>;
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ serial0 = &auart0;
+ serial1 = &auart1;
+ spi0 = &ssp0;
+ spi1 = &ssp1;
+ usbphy0 = &usbphy0;
+ };
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm926ej-s";
+ device_type = "cpu";
+ };
+ };
+
+ apb@80000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80000000 0x80000>;
+ ranges;
+
+ apbh@80000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80000000 0x40000>;
+ ranges;
+
+ icoll: interrupt-controller@80000000 {
+ compatible = "fsl,imx23-icoll", "fsl,icoll";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x80000000 0x2000>;
+ };
+
+ dma_apbh: dma-apbh@80004000 {
+ compatible = "fsl,imx23-dma-apbh";
+ reg = <0x80004000 0x2000>;
+ interrupts = <0 14 20 0
+ 13 13 13 13>;
+ interrupt-names = "empty", "ssp0", "ssp1", "empty",
+ "gpmi0", "gpmi1", "gpmi2", "gpmi3";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ clocks = <&clks 15>;
+ };
+
+ ecc@80008000 {
+ reg = <0x80008000 0x2000>;
+ status = "disabled";
+ };
+
+ gpmi-nand@8000c000 {
+ compatible = "fsl,imx23-gpmi-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x8000c000 0x2000>, <0x8000a000 0x2000>;
+ reg-names = "gpmi-nand", "bch";
+ interrupts = <56>;
+ interrupt-names = "bch";
+ clocks = <&clks 34>;
+ clock-names = "gpmi_io";
+ dmas = <&dma_apbh 4>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ ssp0: ssp@80010000 {
+ reg = <0x80010000 0x2000>;
+ interrupts = <15>;
+ clocks = <&clks 33>;
+ dmas = <&dma_apbh 1>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ etm@80014000 {
+ reg = <0x80014000 0x2000>;
+ status = "disabled";
+ };
+
+ pinctrl@80018000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx23-pinctrl", "simple-bus";
+ reg = <0x80018000 0x2000>;
+
+ gpio0: gpio@0 {
+ compatible = "fsl,imx23-gpio", "fsl,mxs-gpio";
+ interrupts = <16>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio@1 {
+ compatible = "fsl,imx23-gpio", "fsl,mxs-gpio";
+ interrupts = <17>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@2 {
+ compatible = "fsl,imx23-gpio", "fsl,mxs-gpio";
+ interrupts = <18>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ duart_pins_a: duart@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX23_PAD_PWM0__DUART_RX
+ MX23_PAD_PWM1__DUART_TX
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ auart0_pins_a: auart0@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX23_PAD_AUART1_RX__AUART1_RX
+ MX23_PAD_AUART1_TX__AUART1_TX
+ MX23_PAD_AUART1_CTS__AUART1_CTS
+ MX23_PAD_AUART1_RTS__AUART1_RTS
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ auart0_2pins_a: auart0-2pins@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX23_PAD_I2C_SCL__AUART1_TX
+ MX23_PAD_I2C_SDA__AUART1_RX
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ gpmi_pins_a: gpmi-nand@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX23_PAD_GPMI_D00__GPMI_D00
+ MX23_PAD_GPMI_D01__GPMI_D01
+ MX23_PAD_GPMI_D02__GPMI_D02
+ MX23_PAD_GPMI_D03__GPMI_D03
+ MX23_PAD_GPMI_D04__GPMI_D04
+ MX23_PAD_GPMI_D05__GPMI_D05
+ MX23_PAD_GPMI_D06__GPMI_D06
+ MX23_PAD_GPMI_D07__GPMI_D07
+ MX23_PAD_GPMI_CLE__GPMI_CLE
+ MX23_PAD_GPMI_ALE__GPMI_ALE
+ MX23_PAD_GPMI_RDY0__GPMI_RDY0
+ MX23_PAD_GPMI_RDY1__GPMI_RDY1
+ MX23_PAD_GPMI_WPN__GPMI_WPN
+ MX23_PAD_GPMI_WRN__GPMI_WRN
+ MX23_PAD_GPMI_RDN__GPMI_RDN
+ MX23_PAD_GPMI_CE1N__GPMI_CE1N
+ MX23_PAD_GPMI_CE0N__GPMI_CE0N
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ gpmi_pins_fixup: gpmi-pins-fixup {
+ fsl,pinmux-ids = <
+ MX23_PAD_GPMI_WPN__GPMI_WPN
+ MX23_PAD_GPMI_WRN__GPMI_WRN
+ MX23_PAD_GPMI_RDN__GPMI_RDN
+ >;
+ fsl,drive-strength = <MXS_DRIVE_12mA>;
+ };
+
+ mmc0_4bit_pins_a: mmc0-4bit@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX23_PAD_SSP1_DATA0__SSP1_DATA0
+ MX23_PAD_SSP1_DATA1__SSP1_DATA1
+ MX23_PAD_SSP1_DATA2__SSP1_DATA2
+ MX23_PAD_SSP1_DATA3__SSP1_DATA3
+ MX23_PAD_SSP1_CMD__SSP1_CMD
+ MX23_PAD_SSP1_SCK__SSP1_SCK
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ mmc0_8bit_pins_a: mmc0-8bit@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX23_PAD_SSP1_DATA0__SSP1_DATA0
+ MX23_PAD_SSP1_DATA1__SSP1_DATA1
+ MX23_PAD_SSP1_DATA2__SSP1_DATA2
+ MX23_PAD_SSP1_DATA3__SSP1_DATA3
+ MX23_PAD_GPMI_D08__SSP1_DATA4
+ MX23_PAD_GPMI_D09__SSP1_DATA5
+ MX23_PAD_GPMI_D10__SSP1_DATA6
+ MX23_PAD_GPMI_D11__SSP1_DATA7
+ MX23_PAD_SSP1_CMD__SSP1_CMD
+ MX23_PAD_SSP1_DETECT__SSP1_DETECT
+ MX23_PAD_SSP1_SCK__SSP1_SCK
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ mmc0_pins_fixup: mmc0-pins-fixup {
+ fsl,pinmux-ids = <
+ MX23_PAD_SSP1_DETECT__SSP1_DETECT
+ MX23_PAD_SSP1_SCK__SSP1_SCK
+ >;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ pwm2_pins_a: pwm2@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX23_PAD_PWM2__PWM2
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_24bit_pins_a: lcdif-24bit@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX23_PAD_LCD_D00__LCD_D00
+ MX23_PAD_LCD_D01__LCD_D01
+ MX23_PAD_LCD_D02__LCD_D02
+ MX23_PAD_LCD_D03__LCD_D03
+ MX23_PAD_LCD_D04__LCD_D04
+ MX23_PAD_LCD_D05__LCD_D05
+ MX23_PAD_LCD_D06__LCD_D06
+ MX23_PAD_LCD_D07__LCD_D07
+ MX23_PAD_LCD_D08__LCD_D08
+ MX23_PAD_LCD_D09__LCD_D09
+ MX23_PAD_LCD_D10__LCD_D10
+ MX23_PAD_LCD_D11__LCD_D11
+ MX23_PAD_LCD_D12__LCD_D12
+ MX23_PAD_LCD_D13__LCD_D13
+ MX23_PAD_LCD_D14__LCD_D14
+ MX23_PAD_LCD_D15__LCD_D15
+ MX23_PAD_LCD_D16__LCD_D16
+ MX23_PAD_LCD_D17__LCD_D17
+ MX23_PAD_GPMI_D08__LCD_D18
+ MX23_PAD_GPMI_D09__LCD_D19
+ MX23_PAD_GPMI_D10__LCD_D20
+ MX23_PAD_GPMI_D11__LCD_D21
+ MX23_PAD_GPMI_D12__LCD_D22
+ MX23_PAD_GPMI_D13__LCD_D23
+ MX23_PAD_LCD_DOTCK__LCD_DOTCK
+ MX23_PAD_LCD_ENABLE__LCD_ENABLE
+ MX23_PAD_LCD_HSYNC__LCD_HSYNC
+ MX23_PAD_LCD_VSYNC__LCD_VSYNC
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ spi2_pins_a: spi2@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX23_PAD_GPMI_WRN__SSP2_SCK
+ MX23_PAD_GPMI_RDY1__SSP2_CMD
+ MX23_PAD_GPMI_D00__SSP2_DATA0
+ MX23_PAD_GPMI_D03__SSP2_DATA3
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+ };
+
+ digctl@8001c000 {
+ compatible = "fsl,imx23-digctl";
+ reg = <0x8001c000 2000>;
+ status = "disabled";
+ };
+
+ emi@80020000 {
+ reg = <0x80020000 0x2000>;
+ status = "disabled";
+ };
+
+ dma_apbx: dma-apbx@80024000 {
+ compatible = "fsl,imx23-dma-apbx";
+ reg = <0x80024000 0x2000>;
+ interrupts = <7 5 9 26
+ 19 0 25 23
+ 60 58 9 0
+ 0 0 0 0>;
+ interrupt-names = "audio-adc", "audio-dac", "spdif-tx", "i2c",
+ "saif0", "empty", "auart0-rx", "auart0-tx",
+ "auart1-rx", "auart1-tx", "saif1", "empty",
+ "empty", "empty", "empty", "empty";
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ clocks = <&clks 16>;
+ };
+
+ dcp@80028000 {
+ compatible = "fsl,imx23-dcp";
+ reg = <0x80028000 0x2000>;
+ interrupts = <53 54>;
+ status = "okay";
+ };
+
+ pxp@8002a000 {
+ reg = <0x8002a000 0x2000>;
+ status = "disabled";
+ };
+
+ ocotp@8002c000 {
+ compatible = "fsl,ocotp";
+ reg = <0x8002c000 0x2000>;
+ status = "disabled";
+ };
+
+ axi-ahb@8002e000 {
+ reg = <0x8002e000 0x2000>;
+ status = "disabled";
+ };
+
+ lcdif@80030000 {
+ compatible = "fsl,imx23-lcdif";
+ reg = <0x80030000 2000>;
+ interrupts = <46 45>;
+ clocks = <&clks 38>;
+ status = "disabled";
+ };
+
+ ssp1: ssp@80034000 {
+ reg = <0x80034000 0x2000>;
+ interrupts = <2>;
+ clocks = <&clks 33>;
+ dmas = <&dma_apbh 2>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ tvenc@80038000 {
+ reg = <0x80038000 0x2000>;
+ status = "disabled";
+ };
+ };
+
+ apbx@80040000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80040000 0x40000>;
+ ranges;
+
+ clks: clkctrl@80040000 {
+ compatible = "fsl,imx23-clkctrl", "fsl,clkctrl";
+ reg = <0x80040000 0x2000>;
+ #clock-cells = <1>;
+ };
+
+ saif0: saif@80042000 {
+ reg = <0x80042000 0x2000>;
+ dmas = <&dma_apbx 4>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ power@80044000 {
+ reg = <0x80044000 0x2000>;
+ status = "disabled";
+ };
+
+ saif1: saif@80046000 {
+ reg = <0x80046000 0x2000>;
+ dmas = <&dma_apbx 10>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ audio-out@80048000 {
+ reg = <0x80048000 0x2000>;
+ dmas = <&dma_apbx 1>;
+ dma-names = "tx";
+ status = "disabled";
+ };
+
+ audio-in@8004c000 {
+ reg = <0x8004c000 0x2000>;
+ dmas = <&dma_apbx 0>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
+ lradc: lradc@80050000 {
+ compatible = "fsl,imx23-lradc";
+ reg = <0x80050000 0x2000>;
+ interrupts = <36 37 38 39 40 41 42 43 44>;
+ status = "disabled";
+ clocks = <&clks 26>;
+ #io-channel-cells = <1>;
+ };
+
+ spdif@80054000 {
+ reg = <0x80054000 2000>;
+ dmas = <&dma_apbx 2>;
+ dma-names = "tx";
+ status = "disabled";
+ };
+
+ i2c@80058000 {
+ reg = <0x80058000 0x2000>;
+ dmas = <&dma_apbx 3>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ rtc@8005c000 {
+ compatible = "fsl,imx23-rtc", "fsl,stmp3xxx-rtc";
+ reg = <0x8005c000 0x2000>;
+ interrupts = <22>;
+ };
+
+ pwm: pwm@80064000 {
+ compatible = "fsl,imx23-pwm";
+ reg = <0x80064000 0x2000>;
+ clocks = <&clks 30>;
+ #pwm-cells = <2>;
+ fsl,pwm-number = <5>;
+ status = "disabled";
+ };
+
+ timrot@80068000 {
+ compatible = "fsl,imx23-timrot", "fsl,timrot";
+ reg = <0x80068000 0x2000>;
+ interrupts = <28 29 30 31>;
+ clocks = <&clks 28>;
+ };
+
+ auart0: serial@8006c000 {
+ compatible = "fsl,imx23-auart";
+ reg = <0x8006c000 0x2000>;
+ interrupts = <24>;
+ clocks = <&clks 32>;
+ dmas = <&dma_apbx 6>, <&dma_apbx 7>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ auart1: serial@8006e000 {
+ compatible = "fsl,imx23-auart";
+ reg = <0x8006e000 0x2000>;
+ interrupts = <59>;
+ clocks = <&clks 32>;
+ dmas = <&dma_apbx 8>, <&dma_apbx 9>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ duart: serial@80070000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x80070000 0x2000>;
+ interrupts = <0>;
+ clocks = <&clks 32>, <&clks 16>;
+ clock-names = "uart", "apb_pclk";
+ status = "disabled";
+ };
+
+ usbphy0: usbphy@8007c000 {
+ compatible = "fsl,imx23-usbphy";
+ reg = <0x8007c000 0x2000>;
+ clocks = <&clks 41>;
+ status = "disabled";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80080000 0x80000>;
+ ranges;
+
+ usb0: usb@80080000 {
+ compatible = "fsl,imx23-usb", "fsl,imx27-usb";
+ reg = <0x80080000 0x40000>;
+ interrupts = <11>;
+ fsl,usbphy = <&usbphy0>;
+ clocks = <&clks 40>;
+ status = "disabled";
+ };
+ };
+
+ iio_hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&lradc 8>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx25-eukrea-cpuimx25.dtsi b/arch/arm/boot/dts/imx25-eukrea-cpuimx25.dtsi
new file mode 100644
index 000000000..d6f27641c
--- /dev/null
+++ b/arch/arm/boot/dts/imx25-eukrea-cpuimx25.dtsi
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@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.
+ */
+
+#include "imx25.dtsi"
+
+/ {
+ model = "Eukrea CPUIMX25";
+ compatible = "eukrea,cpuimx25", "fsl,imx25";
+
+ memory {
+ reg = <0x80000000 0x4000000>; /* 64M */
+ };
+};
+
+&fec {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pcf8563@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+};
+
+&iomuxc {
+ imx25-eukrea-cpuimx25 {
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX25_PAD_FEC_MDC__FEC_MDC 0x80000000
+ MX25_PAD_FEC_MDIO__FEC_MDIO 0x400001e0
+ MX25_PAD_FEC_TDATA0__FEC_TDATA0 0x80000000
+ MX25_PAD_FEC_TDATA1__FEC_TDATA1 0x80000000
+ MX25_PAD_FEC_TX_EN__FEC_TX_EN 0x80000000
+ MX25_PAD_FEC_RDATA0__FEC_RDATA0 0x80000000
+ MX25_PAD_FEC_RDATA1__FEC_RDATA1 0x80000000
+ MX25_PAD_FEC_RX_DV__FEC_RX_DV 0x80000000
+ MX25_PAD_FEC_TX_CLK__FEC_TX_CLK 0x1c0
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX25_PAD_I2C1_CLK__I2C1_CLK 0x80000000
+ MX25_PAD_I2C1_DAT__I2C1_DAT 0x80000000
+ >;
+ };
+ };
+};
+
+&nfc {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ nand-on-flash-bbt;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-cmo-qvga.dts b/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-cmo-qvga.dts
new file mode 100644
index 000000000..68d0834a2
--- /dev/null
+++ b/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-cmo-qvga.dts
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@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.
+ */
+
+#include "imx25-eukrea-mbimxsd25-baseboard.dts"
+
+/ {
+ model = "Eukrea MBIMXSD25 with the CMO-QVGA Display";
+ compatible = "eukrea,mbimxsd25-baseboard-cmo-qvga", "eukrea,mbimxsd25-baseboard", "eukrea,cpuimx25", "fsl,imx25";
+
+ cmo_qvga: display {
+ model = "CMO-QVGA";
+ bits-per-pixel = <16>;
+ fsl,pcr = <0xcad08b80>;
+ bus-width = <18>;
+ native-mode = <&qvga_timings>;
+ display-timings {
+ qvga_timings: 320x240 {
+ clock-frequency = <6500000>;
+ hactive = <320>;
+ vactive = <240>;
+ hback-porch = <30>;
+ hfront-porch = <38>;
+ vback-porch = <20>;
+ vfront-porch = <3>;
+ hsync-len = <15>;
+ vsync-len = <4>;
+ };
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_lcd_3v3: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_lcd_3v3>;
+ regulator-name = "lcd-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+};
+
+&iomuxc {
+ imx25-eukrea-mbimxsd25-baseboard-cmo-qvga {
+ pinctrl_reg_lcd_3v3: reg_lcd_3v3 {
+ fsl,pins = <MX25_PAD_PWM__GPIO_1_26 0x80000000>;
+ };
+ };
+};
+
+&lcdc {
+ display = <&cmo_qvga>;
+ fsl,lpccr = <0x00a903ff>;
+ lcd-supply = <&reg_lcd_3v3>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-dvi-svga.dts b/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-dvi-svga.dts
new file mode 100644
index 000000000..8eee2f65f
--- /dev/null
+++ b/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-dvi-svga.dts
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@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.
+ */
+
+#include "imx25-eukrea-mbimxsd25-baseboard.dts"
+
+/ {
+ model = "Eukrea MBIMXSD25 with the DVI-SVGA Display";
+ compatible = "eukrea,mbimxsd25-baseboard-dvi-svga", "eukrea,mbimxsd25-baseboard", "eukrea,cpuimx25", "fsl,imx25";
+
+ dvi_svga: display {
+ model = "DVI-SVGA";
+ bits-per-pixel = <16>;
+ fsl,pcr = <0xfa208b80>;
+ bus-width = <18>;
+ native-mode = <&dvi_svga_timings>;
+ display-timings {
+ dvi_svga_timings: 800x600 {
+ clock-frequency = <40000000>;
+ hactive = <800>;
+ vactive = <600>;
+ hback-porch = <75>;
+ hfront-porch = <75>;
+ vback-porch = <7>;
+ vfront-porch = <75>;
+ hsync-len = <7>;
+ vsync-len = <7>;
+ };
+ };
+ };
+};
+
+&lcdc {
+ display = <&dvi_svga>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dts b/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dts
new file mode 100644
index 000000000..447da6263
--- /dev/null
+++ b/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dts
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@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.
+ */
+
+#include "imx25-eukrea-mbimxsd25-baseboard.dts"
+
+/ {
+ model = "Eukrea MBIMXSD25 with the DVI-VGA Display";
+ compatible = "eukrea,mbimxsd25-baseboard-dvi-vga", "eukrea,mbimxsd25-baseboard", "eukrea,cpuimx25", "fsl,imx25";
+
+ dvi_vga: display {
+ model = "DVI-VGA";
+ bits-per-pixel = <16>;
+ fsl,pcr = <0xfa208b80>;
+ bus-width = <18>;
+ native-mode = <&dvi_vga_timings>;
+ display-timings {
+ dvi_vga_timings: 640x480 {
+ clock-frequency = <31250000>;
+ hactive = <640>;
+ vactive = <480>;
+ hback-porch = <100>;
+ hfront-porch = <100>;
+ vback-porch = <7>;
+ vfront-porch = <100>;
+ hsync-len = <7>;
+ vsync-len = <7>;
+ };
+ };
+ };
+};
+
+&lcdc {
+ display = <&dvi_vga>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts b/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts
new file mode 100644
index 000000000..ed1d0b457
--- /dev/null
+++ b/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "imx25-eukrea-cpuimx25.dtsi"
+
+/ {
+ model = "Eukrea MBIMXSD25";
+ compatible = "eukrea,mbimxsd25-baseboard", "eukrea,cpuimx25", "fsl,imx25";
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpiokeys>;
+
+ bp1 {
+ label = "BP1";
+ gpios = <&gpio3 18 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_MISC>;
+ gpio-key,wakeup;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpioled>;
+
+ led1 {
+ label = "led1";
+ gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ sound {
+ compatible = "eukrea,asoc-tlv320";
+ eukrea,model = "imx25-eukrea-tlv320aic23";
+ ssi-controller = <&ssi1>;
+ fsl,mux-int-port = <1>;
+ fsl,mux-ext-port = <5>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ cd-gpios = <&gpio1 20>;
+ status = "okay";
+};
+
+&i2c1 {
+ tlv320aic23: codec@1a {
+ compatible = "ti,tlv320aic23";
+ reg = <0x1a>;
+ };
+};
+
+&iomuxc {
+ imx25-eukrea-mbimxsd25-baseboard {
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX25_PAD_KPP_COL3__AUD5_TXFS 0xe0
+ MX25_PAD_KPP_COL2__AUD5_TXC 0xe0
+ MX25_PAD_KPP_COL1__AUD5_RXD 0xe0
+ MX25_PAD_KPP_COL0__AUD5_TXD 0xe0
+ >;
+ };
+
+ pinctrl_esdhc1: esdhc1grp {
+ fsl,pins = <
+ MX25_PAD_SD1_CMD__SD1_CMD 0x400000c0
+ MX25_PAD_SD1_CLK__SD1_CLK 0x400000c0
+ MX25_PAD_SD1_DATA0__SD1_DATA0 0x400000c0
+ MX25_PAD_SD1_DATA1__SD1_DATA1 0x400000c0
+ MX25_PAD_SD1_DATA2__SD1_DATA2 0x400000c0
+ MX25_PAD_SD1_DATA3__SD1_DATA3 0x400000c0
+ >;
+ };
+
+ pinctrl_gpiokeys: gpiokeysgrp {
+ fsl,pins = <MX25_PAD_VSTBY_ACK__GPIO_3_18 0x80000000>;
+ };
+
+ pinctrl_gpioled: gpioledgrp {
+ fsl,pins = <MX25_PAD_POWER_FAIL__GPIO_3_19 0x80000000>;
+ };
+
+ pinctrl_lcdc: lcdcgrp {
+ fsl,pins = <
+ MX25_PAD_LD0__LD0 0x1
+ MX25_PAD_LD1__LD1 0x1
+ MX25_PAD_LD2__LD2 0x1
+ MX25_PAD_LD3__LD3 0x1
+ MX25_PAD_LD4__LD4 0x1
+ MX25_PAD_LD5__LD5 0x1
+ MX25_PAD_LD6__LD6 0x1
+ MX25_PAD_LD7__LD7 0x1
+ MX25_PAD_LD8__LD8 0x1
+ MX25_PAD_LD9__LD9 0x1
+ MX25_PAD_LD10__LD10 0x1
+ MX25_PAD_LD11__LD11 0x1
+ MX25_PAD_LD12__LD12 0x1
+ MX25_PAD_LD13__LD13 0x1
+ MX25_PAD_LD14__LD14 0x1
+ MX25_PAD_LD15__LD15 0x1
+ MX25_PAD_GPIO_E__LD16 0x1
+ MX25_PAD_GPIO_F__LD17 0x1
+ MX25_PAD_HSYNC__HSYNC 0x80000000
+ MX25_PAD_VSYNC__VSYNC 0x80000000
+ MX25_PAD_LSCLK__LSCLK 0x80000000
+ MX25_PAD_OE_ACD__OE_ACD 0x80000000
+ MX25_PAD_CONTRAST__CONTRAST 0x80000000
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX25_PAD_UART1_RTS__UART1_RTS 0xe0
+ MX25_PAD_UART1_CTS__UART1_CTS 0xe0
+ MX25_PAD_UART1_TXD__UART1_TXD 0x80000000
+ MX25_PAD_UART1_RXD__UART1_RXD 0xc0
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX25_PAD_UART2_RXD__UART2_RXD 0x80000000
+ MX25_PAD_UART2_TXD__UART2_TXD 0x80000000
+ MX25_PAD_UART2_RTS__UART2_RTS 0x80000000
+ MX25_PAD_UART2_CTS__UART2_CTS 0x80000000
+ >;
+ };
+ };
+};
+
+&ssi1 {
+ codec-handle = <&tlv320aic23>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&usbhost1 {
+ phy_type = "serial";
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbotg {
+ phy_type = "utmi";
+ dr_mode = "otg";
+ external-vbus-divider;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx25-karo-tx25.dts b/arch/arm/boot/dts/imx25-karo-tx25.dts
new file mode 100644
index 000000000..9b31faa96
--- /dev/null
+++ b/arch/arm/boot/dts/imx25-karo-tx25.dts
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2012 Sascha Hauer, Pengutronix
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx25.dtsi"
+
+/ {
+ model = "Ka-Ro TX25";
+ compatible = "karo,imx25-tx25", "fsl,imx25";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_fec_phy: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "fec-phy";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio4 9 0>;
+ enable-active-high;
+ };
+ };
+
+ memory {
+ reg = <0x80000000 0x02000000 0x90000000 0x02000000>;
+ };
+};
+
+&iomuxc {
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX25_PAD_UART1_TXD__UART1_TXD 0x80000000
+ MX25_PAD_UART1_RXD__UART1_RXD 0x80000000
+ MX25_PAD_UART1_CTS__UART1_CTS 0x80000000
+ MX25_PAD_UART1_RTS__UART1_RTS 0x80000000
+ >;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX25_PAD_D11__GPIO_4_9 0x80000000 /* FEC PHY power on pin */
+ MX25_PAD_D13__GPIO_4_7 0x80000000 /* FEC reset */
+ MX25_PAD_FEC_MDC__FEC_MDC 0x80000000
+ MX25_PAD_FEC_MDIO__FEC_MDIO 0x80000000
+ MX25_PAD_FEC_TDATA0__FEC_TDATA0 0x80000000
+ MX25_PAD_FEC_TDATA1__FEC_TDATA1 0x80000000
+ MX25_PAD_FEC_TX_EN__FEC_TX_EN 0x80000000
+ MX25_PAD_FEC_RDATA0__FEC_RDATA0 0x80000000
+ MX25_PAD_FEC_RDATA1__FEC_RDATA1 0x80000000
+ MX25_PAD_FEC_RX_DV__FEC_RX_DV 0x80000000
+ MX25_PAD_FEC_TX_CLK__FEC_TX_CLK 0x80000000
+ >;
+ };
+
+ pinctrl_nfc: nfcgrp {
+ fsl,pins = <
+ MX25_PAD_NF_CE0__NF_CE0 0x80000000
+ MX25_PAD_NFWE_B__NFWE_B 0x80000000
+ MX25_PAD_NFRE_B__NFRE_B 0x80000000
+ MX25_PAD_NFALE__NFALE 0x80000000
+ MX25_PAD_NFCLE__NFCLE 0x80000000
+ MX25_PAD_NFWP_B__NFWP_B 0x80000000
+ MX25_PAD_NFRB__NFRB 0x80000000
+ MX25_PAD_D7__D7 0x80000000
+ MX25_PAD_D6__D6 0x80000000
+ MX25_PAD_D5__D5 0x80000000
+ MX25_PAD_D4__D4 0x80000000
+ MX25_PAD_D3__D3 0x80000000
+ MX25_PAD_D2__D2 0x80000000
+ MX25_PAD_D1__D1 0x80000000
+ MX25_PAD_D0__D0 0x80000000
+ >;
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ phy-reset-gpios = <&gpio3 7 0>;
+ phy-mode = "rmii";
+ phy-supply = <&reg_fec_phy>;
+ status = "okay";
+};
+
+&nfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nfc>;
+ nand-on-flash-bbt;
+ nand-ecc-mode = "hw";
+ nand-bus-width = <8>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx25-pdk.dts b/arch/arm/boot/dts/imx25-pdk.dts
new file mode 100644
index 000000000..dd45e6971
--- /dev/null
+++ b/arch/arm/boot/dts/imx25-pdk.dts
@@ -0,0 +1,315 @@
+/*
+ * Copyright 2013 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
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include "imx25.dtsi"
+
+/ {
+ model = "Freescale i.MX25 Product Development Kit";
+ compatible = "fsl,imx25-pdk", "fsl,imx25";
+
+ memory {
+ reg = <0x80000000 0x4000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_fec_3v3: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "fec-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 3 0>;
+ enable-active-high;
+ };
+
+ reg_2p5v: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "2P5V";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ };
+
+ reg_3p3v: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_can_3v3: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "can-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio4 6 0>;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx25-pdk-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx25-pdk-sgtl5000";
+ ssi-controller = <&ssi1>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <1>;
+ mux-ext-port = <4>;
+ };
+
+ wvga: display {
+ model = "CLAA057VC01CW";
+ bits-per-pixel = <16>;
+ fsl,pcr = <0xfa208b80>;
+ bus-width = <18>;
+ native-mode = <&wvga_timings>;
+ display-timings {
+ wvga_timings: 640x480 {
+ hactive = <640>;
+ vactive = <480>;
+ hback-porch = <45>;
+ hfront-porch = <114>;
+ hsync-len = <1>;
+ vback-porch = <33>;
+ vfront-porch = <11>;
+ vsync-len = <1>;
+ clock-frequency = <25200000>;
+ };
+ };
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can1>;
+ xceiver-supply = <&reg_can_3v3>;
+ status = "okay";
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ cd-gpios = <&gpio2 1 0>;
+ wp-gpios = <&gpio2 0 0>;
+ status = "okay";
+};
+
+&fec {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ phy-supply = <&reg_fec_3v3>;
+ phy-reset-gpios = <&gpio4 8 0>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&clks 129>;
+ VDDA-supply = <&reg_2p5v>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+};
+
+&iomuxc {
+ imx25-pdk {
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX25_PAD_RW__AUD4_TXFS 0xe0
+ MX25_PAD_OE__AUD4_TXC 0xe0
+ MX25_PAD_EB0__AUD4_TXD 0xe0
+ MX25_PAD_EB1__AUD4_RXD 0xe0
+ >;
+ };
+
+ pinctrl_can1: can1grp {
+ fsl,pins = <
+ MX25_PAD_GPIO_A__CAN1_TX 0x0
+ MX25_PAD_GPIO_B__CAN1_RX 0x0
+ MX25_PAD_D14__GPIO_4_6 0x80000000
+ >;
+ };
+
+ pinctrl_esdhc1: esdhc1grp {
+ fsl,pins = <
+ MX25_PAD_SD1_CMD__SD1_CMD 0x80000000
+ MX25_PAD_SD1_CLK__SD1_CLK 0x80000000
+ MX25_PAD_SD1_DATA0__SD1_DATA0 0x80000000
+ MX25_PAD_SD1_DATA1__SD1_DATA1 0x80000000
+ MX25_PAD_SD1_DATA2__SD1_DATA2 0x80000000
+ MX25_PAD_SD1_DATA3__SD1_DATA3 0x80000000
+ MX25_PAD_A14__GPIO_2_0 0x80000000
+ MX25_PAD_A15__GPIO_2_1 0x80000000
+ >;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX25_PAD_FEC_MDC__FEC_MDC 0x80000000
+ MX25_PAD_FEC_MDIO__FEC_MDIO 0x400001e0
+ MX25_PAD_FEC_TDATA0__FEC_TDATA0 0x80000000
+ MX25_PAD_FEC_TDATA1__FEC_TDATA1 0x80000000
+ MX25_PAD_FEC_TX_EN__FEC_TX_EN 0x80000000
+ MX25_PAD_FEC_RDATA0__FEC_RDATA0 0x80000000
+ MX25_PAD_FEC_RDATA1__FEC_RDATA1 0x80000000
+ MX25_PAD_FEC_RX_DV__FEC_RX_DV 0x80000000
+ MX25_PAD_FEC_TX_CLK__FEC_TX_CLK 0x1c0
+ MX25_PAD_A17__GPIO_2_3 0x80000000
+ MX25_PAD_D12__GPIO_4_8 0x80000000
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX25_PAD_I2C1_CLK__I2C1_CLK 0x80000000
+ MX25_PAD_I2C1_DAT__I2C1_DAT 0x80000000
+ >;
+ };
+
+ pinctrl_kpp: kppgrp {
+ fsl,pins = <
+ MX25_PAD_KPP_ROW0__KPP_ROW0 0x80000000
+ MX25_PAD_KPP_ROW1__KPP_ROW1 0x80000000
+ MX25_PAD_KPP_ROW2__KPP_ROW2 0x80000000
+ MX25_PAD_KPP_ROW3__KPP_ROW3 0x80000000
+ MX25_PAD_KPP_COL0__KPP_COL0 0x80000000
+ MX25_PAD_KPP_COL1__KPP_COL1 0x80000000
+ MX25_PAD_KPP_COL2__KPP_COL2 0x80000000
+ MX25_PAD_KPP_COL3__KPP_COL3 0x80000000
+ >;
+ };
+
+ pinctrl_lcd: lcdgrp {
+ fsl,pins = <
+ MX25_PAD_LD0__LD0 0xe0
+ MX25_PAD_LD1__LD1 0xe0
+ MX25_PAD_LD2__LD2 0xe0
+ MX25_PAD_LD3__LD3 0xe0
+ MX25_PAD_LD4__LD4 0xe0
+ MX25_PAD_LD5__LD5 0xe0
+ MX25_PAD_LD6__LD6 0xe0
+ MX25_PAD_LD7__LD7 0xe0
+ MX25_PAD_LD8__LD8 0xe0
+ MX25_PAD_LD9__LD9 0xe0
+ MX25_PAD_LD10__LD10 0xe0
+ MX25_PAD_LD11__LD11 0xe0
+ MX25_PAD_LD12__LD12 0xe0
+ MX25_PAD_LD13__LD13 0xe0
+ MX25_PAD_LD14__LD14 0xe0
+ MX25_PAD_LD15__LD15 0xe0
+ MX25_PAD_GPIO_E__LD16 0xe0
+ MX25_PAD_GPIO_F__LD17 0xe0
+ MX25_PAD_HSYNC__HSYNC 0xe0
+ MX25_PAD_VSYNC__VSYNC 0xe0
+ MX25_PAD_LSCLK__LSCLK 0xe0
+ MX25_PAD_OE_ACD__OE_ACD 0xe0
+ MX25_PAD_CONTRAST__CONTRAST 0xe0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX25_PAD_UART1_RTS__UART1_RTS 0xe0
+ MX25_PAD_UART1_CTS__UART1_CTS 0xe0
+ MX25_PAD_UART1_TXD__UART1_TXD 0x80000000
+ MX25_PAD_UART1_RXD__UART1_RXD 0xc0
+ >;
+ };
+ };
+};
+
+&lcdc {
+ display = <&wvga>;
+ fsl,lpccr = <0x00a903ff>;
+ fsl,lscr1 = <0x00120300>;
+ fsl,dmacr = <0x00020010>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcd>;
+ status = "okay";
+};
+
+&nfc {
+ nand-on-flash-bbt;
+ status = "okay";
+};
+
+&kpp {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_kpp>;
+ linux,keymap = <
+ MATRIX_KEY(0x0, 0x0, KEY_UP)
+ MATRIX_KEY(0x0, 0x1, KEY_DOWN)
+ MATRIX_KEY(0x0, 0x2, KEY_VOLUMEDOWN)
+ MATRIX_KEY(0x0, 0x3, KEY_HOME)
+ MATRIX_KEY(0x1, 0x0, KEY_RIGHT)
+ MATRIX_KEY(0x1, 0x1, KEY_LEFT)
+ MATRIX_KEY(0x1, 0x2, KEY_ENTER)
+ MATRIX_KEY(0x1, 0x3, KEY_VOLUMEUP)
+ MATRIX_KEY(0x2, 0x0, KEY_F6)
+ MATRIX_KEY(0x2, 0x1, KEY_F8)
+ MATRIX_KEY(0x2, 0x2, KEY_F9)
+ MATRIX_KEY(0x2, 0x3, KEY_F10)
+ MATRIX_KEY(0x3, 0x0, KEY_F1)
+ MATRIX_KEY(0x3, 0x1, KEY_F2)
+ MATRIX_KEY(0x3, 0x2, KEY_F3)
+ MATRIX_KEY(0x3, 0x2, KEY_POWER)
+ >;
+ status = "okay";
+};
+
+&ssi1 {
+ codec-handle = <&codec>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&usbhost1 {
+ phy_type = "serial";
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbotg {
+ phy_type = "utmi";
+ dr_mode = "otg";
+ external-vbus-divider;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx25-pinfunc.h b/arch/arm/boot/dts/imx25-pinfunc.h
new file mode 100644
index 000000000..7c4b9f2f9
--- /dev/null
+++ b/arch/arm/boot/dts/imx25-pinfunc.h
@@ -0,0 +1,577 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.com>
+ * Based on imx35-pinfunc.h in the same directory Which is:
+ * Copyright 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX25_PINFUNC_H
+#define __DTS_IMX25_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+
+#define MX25_PAD_TDO__TDO 0x000 0x3e8 0x000 0x00 0x000
+
+#define MX25_PAD_A10__A10 0x008 0x000 0x000 0x00 0x000
+#define MX25_PAD_A10__GPIO_4_0 0x008 0x000 0x000 0x05 0x000
+
+#define MX25_PAD_A13__A13 0x00c 0x22C 0x000 0x00 0x000
+#define MX25_PAD_A13__GPIO_4_1 0x00c 0x22C 0x000 0x05 0x000
+#define MX25_PAD_A13__LCDC_CLS 0x00c 0x22C 0x000 0x07 0x000
+
+#define MX25_PAD_A14__A14 0x010 0x230 0x000 0x10 0x000
+#define MX25_PAD_A14__GPIO_2_0 0x010 0x230 0x000 0x15 0x000
+#define MX25_PAD_A14__SIM1_CLK1 0x010 0x230 0x000 0x16 0x000
+#define MX25_PAD_A14__LCDC_SPL 0x010 0x230 0x000 0x17 0x000
+
+#define MX25_PAD_A15__A15 0x014 0x234 0x000 0x10 0x000
+#define MX25_PAD_A15__GPIO_2_1 0x014 0x234 0x000 0x15 0x000
+#define MX25_PAD_A15__SIM1_RST1 0x014 0x234 0x000 0x16 0x000
+#define MX25_PAD_A15__LCDC_PS 0x014 0x234 0x000 0x17 0x000
+
+#define MX25_PAD_A16__A16 0x018 0x000 0x000 0x10 0x000
+#define MX25_PAD_A16__GPIO_2_2 0x018 0x000 0x000 0x15 0x000
+#define MX25_PAD_A16__SIM1_VEN1 0x018 0x000 0x000 0x16 0x000
+#define MX25_PAD_A16__LCDC_REV 0x018 0x000 0x000 0x17 0x000
+
+#define MX25_PAD_A17__A17 0x01c 0x238 0x000 0x10 0x000
+#define MX25_PAD_A17__GPIO_2_3 0x01c 0x238 0x000 0x15 0x000
+#define MX25_PAD_A17__SIM1_TX 0x01c 0x238 0x554 0x16 0x000
+#define MX25_PAD_A17__FEC_TX_ERR 0x01c 0x238 0x000 0x17 0x000
+
+#define MX25_PAD_A18__A18 0x020 0x23c 0x000 0x10 0x000
+#define MX25_PAD_A18__GPIO_2_4 0x020 0x23c 0x000 0x15 0x000
+#define MX25_PAD_A18__SIM1_PD1 0x020 0x23c 0x550 0x16 0x000
+#define MX25_PAD_A18__FEC_COL 0x020 0x23c 0x504 0x17 0x000
+
+#define MX25_PAD_A19__A19 0x024 0x240 0x000 0x10 0x000
+#define MX25_PAD_A19__GPIO_2_5 0x024 0x240 0x000 0x15 0x000
+#define MX25_PAD_A19__SIM1_RX1 0x024 0x240 0x54c 0x16 0x000
+#define MX25_PAD_A19__FEC_RX_ERR 0x024 0x240 0x518 0x17 0x000
+
+#define MX25_PAD_A20__A20 0x028 0x244 0x000 0x10 0x000
+#define MX25_PAD_A20__GPIO_2_6 0x028 0x244 0x000 0x15 0x000
+#define MX25_PAD_A20__SIM2_CLK1 0x028 0x244 0x000 0x16 0x000
+#define MX25_PAD_A20__FEC_RDATA2 0x028 0x244 0x50c 0x17 0x000
+
+#define MX25_PAD_A21__A21 0x02c 0x248 0x000 0x10 0x000
+#define MX25_PAD_A21__GPIO_2_7 0x02c 0x248 0x000 0x15 0x000
+#define MX25_PAD_A21__SIM2_RST1 0x02c 0x248 0x000 0x16 0x000
+#define MX25_PAD_A21__FEC_RDATA3 0x02c 0x248 0x510 0x17 0x000
+
+#define MX25_PAD_A22__A22 0x030 0x000 0x000 0x10 0x000
+#define MX25_PAD_A22__GPIO_2_8 0x030 0x000 0x000 0x15 0x000
+#define MX25_PAD_A22__FEC_TDATA2 0x030 0x000 0x000 0x17 0x000
+#define MX25_PAD_A22__SIM2_VEN1 0x030 0x000 0x000 0x16 0x000
+#define MX25_PAD_A22__FEC_TDATA2 0x030 0x000 0x000 0x17 0x000
+
+#define MX25_PAD_A23__A23 0x034 0x24c 0x000 0x10 0x000
+#define MX25_PAD_A23__GPIO_2_9 0x034 0x24c 0x000 0x15 0x000
+#define MX25_PAD_A23__SIM2_TX1 0x034 0x24c 0x560 0x16 0x000
+#define MX25_PAD_A23__FEC_TDATA3 0x034 0x24c 0x000 0x17 0x000
+
+#define MX25_PAD_A24__A24 0x038 0x250 0x000 0x10 0x000
+#define MX25_PAD_A24__GPIO_2_10 0x038 0x250 0x000 0x15 0x000
+#define MX25_PAD_A24__SIM2_PD1 0x038 0x250 0x55c 0x16 0x000
+#define MX25_PAD_A24__FEC_RX_CLK 0x038 0x250 0x514 0x17 0x000
+
+#define MX25_PAD_A25__A25 0x03c 0x254 0x000 0x10 0x000
+#define MX25_PAD_A25__GPIO_2_11 0x03c 0x254 0x000 0x15 0x000
+#define MX25_PAD_A25__FEC_CRS 0x03c 0x254 0x508 0x17 0x000
+
+#define MX25_PAD_EB0__EB0 0x040 0x258 0x000 0x10 0x000
+#define MX25_PAD_EB0__AUD4_TXD 0x040 0x258 0x464 0x14 0x000
+#define MX25_PAD_EB0__GPIO_2_12 0x040 0x258 0x000 0x15 0x000
+
+#define MX25_PAD_EB1__EB1 0x044 0x25c 0x000 0x10 0x000
+#define MX25_PAD_EB1__AUD4_RXD 0x044 0x25c 0x460 0x14 0x000
+#define MX25_PAD_EB1__GPIO_2_13 0x044 0x25c 0x000 0x15 0x000
+
+#define MX25_PAD_OE__OE 0x048 0x260 0x000 0x10 0x000
+#define MX25_PAD_OE__AUD4_TXC 0x048 0x260 0x000 0x14 0x000
+#define MX25_PAD_OE__GPIO_2_14 0x048 0x260 0x000 0x15 0x000
+
+#define MX25_PAD_CS0__CS0 0x04c 0x000 0x000 0x00 0x000
+#define MX25_PAD_CS0__GPIO_4_2 0x04c 0x000 0x000 0x05 0x000
+
+#define MX25_PAD_CS1__CS1 0x050 0x000 0x000 0x00 0x000
+#define MX25_PAD_CS1__NF_CE3 0x050 0x000 0x000 0x01 0x000
+#define MX25_PAD_CS1__GPIO_4_3 0x050 0x000 0x000 0x05 0x000
+
+#define MX25_PAD_CS4__CS4 0x054 0x264 0x000 0x10 0x000
+#define MX25_PAD_CS4__NF_CE1 0x054 0x264 0x000 0x01 0x000
+#define MX25_PAD_CS4__UART5_CTS 0x054 0x264 0x000 0x13 0x000
+#define MX25_PAD_CS4__GPIO_3_20 0x054 0x264 0x000 0x15 0x000
+
+#define MX25_PAD_CS5__CS5 0x058 0x268 0x000 0x10 0x000
+#define MX25_PAD_CS5__NF_CE2 0x058 0x268 0x000 0x01 0x000
+#define MX25_PAD_CS5__UART5_RTS 0x058 0x268 0x574 0x13 0x000
+#define MX25_PAD_CS5__GPIO_3_21 0x058 0x268 0x000 0x15 0x000
+
+#define MX25_PAD_NF_CE0__NF_CE0 0x05c 0x26c 0x000 0x10 0x000
+#define MX25_PAD_NF_CE0__GPIO_3_22 0x05c 0x26c 0x000 0x15 0x000
+
+#define MX25_PAD_ECB__ECB 0x060 0x270 0x000 0x10 0x000
+#define MX25_PAD_ECB__UART5_TXD_MUX 0x060 0x270 0x000 0x13 0x000
+#define MX25_PAD_ECB__GPIO_3_23 0x060 0x270 0x000 0x15 0x000
+
+#define MX25_PAD_LBA__LBA 0x064 0x274 0x000 0x10 0x000
+#define MX25_PAD_LBA__UART5_RXD_MUX 0x064 0x274 0x578 0x13 0x000
+#define MX25_PAD_LBA__GPIO_3_24 0x064 0x274 0x000 0x15 0x000
+
+#define MX25_PAD_BCLK__BCLK 0x068 0x000 0x000 0x00 0x000
+#define MX25_PAD_BCLK__GPIO_4_4 0x068 0x000 0x000 0x05 0x000
+
+#define MX25_PAD_RW__RW 0x06c 0x278 0x000 0x10 0x000
+#define MX25_PAD_RW__AUD4_TXFS 0x06c 0x278 0x474 0x14 0x000
+#define MX25_PAD_RW__GPIO_3_25 0x06c 0x278 0x000 0x15 0x000
+
+#define MX25_PAD_NFWE_B__NFWE_B 0x070 0x000 0x000 0x10 0x000
+#define MX25_PAD_NFWE_B__GPIO_3_26 0x070 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_NFRE_B__NFRE_B 0x074 0x000 0x000 0x10 0x000
+#define MX25_PAD_NFRE_B__GPIO_3_27 0x074 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_NFALE__NFALE 0x078 0x000 0x000 0x10 0x000
+#define MX25_PAD_NFALE__GPIO_3_28 0x078 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_NFCLE__NFCLE 0x07c 0x000 0x000 0x10 0x000
+#define MX25_PAD_NFCLE__GPIO_3_29 0x07c 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_NFWP_B__NFWP_B 0x080 0x000 0x000 0x10 0x000
+#define MX25_PAD_NFWP_B__GPIO_3_30 0x080 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_NFRB__NFRB 0x084 0x27c 0x000 0x10 0x000
+#define MX25_PAD_NFRB__GPIO_3_31 0x084 0x27c 0x000 0x15 0x000
+
+#define MX25_PAD_D15__D15 0x088 0x280 0x000 0x00 0x000
+#define MX25_PAD_D15__LD16 0x088 0x280 0x000 0x01 0x000
+#define MX25_PAD_D15__GPIO_4_5 0x088 0x280 0x000 0x05 0x000
+#define MX25_PAD_D15__SDHC1_DAT7 0x088 0x280 0x4d8 0x06 0x000
+
+#define MX25_PAD_D14__D14 0x08c 0x284 0x000 0x00 0x000
+#define MX25_PAD_D14__LD17 0x08c 0x284 0x000 0x01 0x000
+#define MX25_PAD_D14__GPIO_4_6 0x08c 0x284 0x000 0x05 0x000
+#define MX25_PAD_D14__SDHC1_DAT6 0x08c 0x284 0x4d4 0x06 0x000
+
+#define MX25_PAD_D13__D13 0x090 0x288 0x000 0x00 0x000
+#define MX25_PAD_D13__LD18 0x090 0x288 0x000 0x01 0x000
+#define MX25_PAD_D13__GPIO_4_7 0x090 0x288 0x000 0x05 0x000
+#define MX25_PAD_D13__SDHC1_DAT5 0x090 0x288 0x4d0 0x06 0x000
+
+#define MX25_PAD_D12__D12 0x094 0x28c 0x000 0x00 0x000
+#define MX25_PAD_D12__GPIO_4_8 0x094 0x28c 0x000 0x05 0x000
+#define MX25_PAD_D12__SDHC1_DAT4 0x094 0x28c 0x4cc 0x06 0x000
+
+#define MX25_PAD_D11__D11 0x098 0x290 0x000 0x00 0x000
+#define MX25_PAD_D11__GPIO_4_9 0x098 0x290 0x000 0x05 0x000
+#define MX25_PAD_D11__USBOTG_PWR 0x098 0x290 0x000 0x06 0x000
+
+#define MX25_PAD_D10__D10 0x09c 0x294 0x000 0x00 0x000
+#define MX25_PAD_D10__GPIO_4_10 0x09c 0x294 0x000 0x05 0x000
+#define MX25_PAD_D10__USBOTG_OC 0x09c 0x294 0x57c 0x06 0x000
+
+#define MX25_PAD_D9__D9 0x0a0 0x298 0x000 0x00 0x000
+#define MX25_PAD_D9__GPIO_4_11 0x0a0 0x298 0x000 0x05 0x000
+#define MX25_PAD_D9__USBH2_PWR 0x0a0 0x298 0x000 0x06 0x000
+
+#define MX25_PAD_D8__D8 0x0a4 0x29c 0x000 0x00 0x000
+#define MX25_PAD_D8__GPIO_4_12 0x0a4 0x29c 0x000 0x05 0x000
+#define MX25_PAD_D8__USBH2_OC 0x0a4 0x29c 0x580 0x06 0x000
+
+#define MX25_PAD_D7__D7 0x0a8 0x2a0 0x000 0x00 0x000
+#define MX25_PAD_D7__GPIO_4_13 0x0a8 0x2a0 0x000 0x05 0x000
+
+#define MX25_PAD_D6__D6 0x0ac 0x2a4 0x000 0x00 0x000
+#define MX25_PAD_D6__GPIO_4_14 0x0ac 0x2a4 0x000 0x05 0x000
+
+#define MX25_PAD_D5__D5 0x0b0 0x2a8 0x000 0x00 0x000
+#define MX25_PAD_D5__GPIO_4_15 0x0b0 0x2a8 0x000 0x05 0x000
+
+#define MX25_PAD_D4__D4 0x0b4 0x2ac 0x000 0x00 0x000
+#define MX25_PAD_D4__GPIO_4_16 0x0b4 0x2ac 0x000 0x05 0x000
+
+#define MX25_PAD_D3__D3 0x0b8 0x2b0 0x000 0x00 0x000
+#define MX25_PAD_D3__GPIO_4_17 0x0b8 0x2b0 0x000 0x05 0x000
+
+#define MX25_PAD_D2__D2 0x0bc 0x2b4 0x000 0x00 0x000
+#define MX25_PAD_D2__GPIO_4_18 0x0bc 0x2b4 0x000 0x05 0x000
+
+#define MX25_PAD_D1__D1 0x0c0 0x2b8 0x000 0x00 0x000
+#define MX25_PAD_D1__GPIO_4_19 0x0c0 0x2b8 0x000 0x05 0x000
+
+#define MX25_PAD_D0__D0 0x0c4 0x2bc 0x000 0x00 0x000
+#define MX25_PAD_D0__GPIO_4_20 0x0c4 0x2bc 0x000 0x05 0x000
+
+#define MX25_PAD_LD0__LD0 0x0c8 0x2c0 0x000 0x10 0x000
+#define MX25_PAD_LD0__CSI_D0 0x0c8 0x2c0 0x488 0x12 0x000
+#define MX25_PAD_LD0__GPIO_2_15 0x0c8 0x2c0 0x000 0x15 0x000
+
+#define MX25_PAD_LD1__LD1 0x0cc 0x2c4 0x000 0x10 0x000
+#define MX25_PAD_LD1__CSI_D1 0x0cc 0x2c4 0x48c 0x12 0x000
+#define MX25_PAD_LD1__GPIO_2_16 0x0cc 0x2c4 0x000 0x15 0x000
+
+#define MX25_PAD_LD2__LD2 0x0d0 0x2c8 0x000 0x10 0x000
+#define MX25_PAD_LD2__GPIO_2_17 0x0d0 0x2c8 0x000 0x15 0x000
+
+#define MX25_PAD_LD3__LD3 0x0d4 0x2cc 0x000 0x10 0x000
+#define MX25_PAD_LD3__GPIO_2_18 0x0d4 0x2cc 0x000 0x15 0x000
+
+#define MX25_PAD_LD4__LD4 0x0d8 0x2d0 0x000 0x10 0x000
+#define MX25_PAD_LD4__GPIO_2_19 0x0d8 0x2d0 0x000 0x15 0x000
+
+#define MX25_PAD_LD5__LD5 0x0dc 0x2d4 0x000 0x10 0x000
+#define MX25_PAD_LD5__GPIO_1_19 0x0dc 0x2d4 0x000 0x15 0x000
+
+#define MX25_PAD_LD6__LD6 0x0e0 0x2d8 0x000 0x10 0x000
+#define MX25_PAD_LD6__GPIO_1_20 0x0e0 0x2d8 0x000 0x15 0x000
+
+#define MX25_PAD_LD7__LD7 0x0e4 0x2dc 0x000 0x10 0x000
+#define MX25_PAD_LD7__GPIO_1_21 0x0e4 0x2dc 0x000 0x15 0x000
+
+#define MX25_PAD_LD8__LD8 0x0e8 0x2e0 0x000 0x10 0x000
+#define MX25_PAD_LD8__FEC_TX_ERR 0x0e8 0x2e0 0x000 0x15 0x000
+#define MX25_PAD_LD8__SDHC2_CMD 0x0e8 0x2e0 0x4e0 0x06 0x000
+
+#define MX25_PAD_LD9__LD9 0x0ec 0x2e4 0x000 0x10 0x000
+#define MX25_PAD_LD9__FEC_COL 0x0ec 0x2e4 0x504 0x15 0x001
+#define MX25_PAD_LD9__SDHC2_CLK 0x0ec 0x2e4 0x4dc 0x06 0x000
+
+#define MX25_PAD_LD10__LD10 0x0f0 0x2e8 0x000 0x10 0x000
+#define MX25_PAD_LD10__FEC_RX_ERR 0x0f0 0x2e8 0x518 0x15 0x001
+
+#define MX25_PAD_LD11__LD11 0x0f4 0x2ec 0x000 0x10 0x000
+#define MX25_PAD_LD11__FEC_RDATA2 0x0f4 0x2ec 0x50c 0x15 0x001
+#define MX25_PAD_LD11__SDHC2_DAT1 0x0f4 0x2ec 0x4e8 0x06 0x000
+
+#define MX25_PAD_LD12__LD12 0x0f8 0x2f0 0x000 0x10 0x000
+#define MX25_PAD_LD12__CSPI2_MOSI 0x0f8 0x2f0 0x4a0 0x02 0x000
+#define MX25_PAD_LD12__FEC_RDATA3 0x0f8 0x2f0 0x510 0x15 0x001
+
+#define MX25_PAD_LD13__LD13 0x0fc 0x2f4 0x000 0x10 0x000
+#define MX25_PAD_LD13__CSPI2_MISO 0x0fc 0x2f4 0x49c 0x02 0x000
+#define MX25_PAD_LD13__FEC_TDATA2 0x0fc 0x2f4 0x000 0x15 0x000
+
+#define MX25_PAD_LD14__LD14 0x100 0x2f8 0x000 0x10 0x000
+#define MX25_PAD_LD14__CSPI2_SCLK 0x100 0x2f8 0x494 0x02 0x000
+#define MX25_PAD_LD14__FEC_TDATA3 0x100 0x2f8 0x000 0x15 0x000
+
+#define MX25_PAD_LD15__LD15 0x104 0x2fc 0x000 0x10 0x000
+#define MX25_PAD_LD15__CSPI2_RDY 0x104 0x2fc 0x498 0x02 0x000
+#define MX25_PAD_LD15__FEC_RX_CLK 0x104 0x2fc 0x514 0x15 0x001
+
+#define MX25_PAD_HSYNC__HSYNC 0x108 0x300 0x000 0x10 0x000
+#define MX25_PAD_HSYNC__GPIO_1_22 0x108 0x300 0x000 0x15 0x000
+
+#define MX25_PAD_VSYNC__VSYNC 0x10c 0x304 0x000 0x10 0x000
+#define MX25_PAD_VSYNC__GPIO_1_23 0x10c 0x304 0x000 0x15 0x000
+
+#define MX25_PAD_LSCLK__LSCLK 0x110 0x308 0x000 0x10 0x000
+#define MX25_PAD_LSCLK__GPIO_1_24 0x110 0x308 0x000 0x15 0x000
+
+#define MX25_PAD_OE_ACD__OE_ACD 0x114 0x30c 0x000 0x10 0x000
+#define MX25_PAD_OE_ACD__CSPI2_SS0 0x114 0x30c 0x4a4 0x02 0x000
+#define MX25_PAD_OE_ACD__GPIO_1_25 0x114 0x30c 0x000 0x15 0x000
+
+#define MX25_PAD_CONTRAST__CONTRAST 0x118 0x310 0x000 0x10 0x000
+#define MX25_PAD_CONTRAST__CC4 0x118 0x310 0x000 0x11 0x000
+#define MX25_PAD_CONTRAST__PWM4_PWMO 0x118 0x310 0x000 0x14 0x000
+#define MX25_PAD_CONTRAST__FEC_CRS 0x118 0x310 0x508 0x15 0x001
+
+#define MX25_PAD_PWM__PWM 0x11c 0x314 0x000 0x10 0x000
+#define MX25_PAD_PWM__GPIO_1_26 0x11c 0x314 0x000 0x15 0x000
+#define MX25_PAD_PWM__USBH2_OC 0x11c 0x314 0x580 0x16 0x001
+
+#define MX25_PAD_CSI_D2__CSI_D2 0x120 0x318 0x000 0x10 0x000
+#define MX25_PAD_CSI_D2__UART5_RXD_MUX 0x120 0x318 0x578 0x11 0x001
+#define MX25_PAD_CSI_D2__SIM1_CLK0 0x120 0x318 0x000 0x04 0x000
+#define MX25_PAD_CSI_D2__GPIO_1_27 0x120 0x318 0x000 0x15 0x000
+#define MX25_PAD_CSI_D2__CSPI3_MOSI 0x120 0x318 0x000 0x17 0x000
+
+#define MX25_PAD_CSI_D3__CSI_D3 0x124 0x31c 0x000 0x10 0x000
+#define MX25_PAD_CSI_D3__UART5_TXD_MUX 0x124 0x31c 0x000 0x11 0x000
+#define MX25_PAD_CSI_D3__SIM1_RST0 0x124 0x31c 0x000 0x04 0x000
+#define MX25_PAD_CSI_D3__GPIO_1_28 0x124 0x31c 0x000 0x15 0x000
+#define MX25_PAD_CSI_D3__CSPI3_MISO 0x124 0x31c 0x4b4 0x17 0x001
+
+#define MX25_PAD_CSI_D4__CSI_D4 0x128 0x320 0x000 0x10 0x000
+#define MX25_PAD_CSI_D4__UART5_RTS 0x128 0x320 0x574 0x11 0x001
+#define MX25_PAD_CSI_D4__SIM1_VEN0 0x128 0x320 0x000 0x04 0x000
+#define MX25_PAD_CSI_D4__GPIO_1_29 0x128 0x320 0x000 0x15 0x000
+#define MX25_PAD_CSI_D4__CSPI3_SCLK 0x128 0x320 0x000 0x17 0x000
+
+#define MX25_PAD_CSI_D5__CSI_D5 0x12c 0x324 0x000 0x10 0x000
+#define MX25_PAD_CSI_D5__UART5_CTS 0x12c 0x324 0x000 0x11 0x000
+#define MX25_PAD_CSI_D5__SIM1_TX0 0x12c 0x324 0x000 0x04 0x000
+#define MX25_PAD_CSI_D5__GPIO_1_30 0x12c 0x324 0x000 0x15 0x000
+#define MX25_PAD_CSI_D5__CSPI3_RDY 0x12c 0x324 0x000 0x17 0x000
+
+#define MX25_PAD_CSI_D6__CSI_D6 0x130 0x328 0x000 0x10 0x000
+#define MX25_PAD_CSI_D6__SDHC2_CMD 0x130 0x328 0x4e0 0x12 0x001
+#define MX25_PAD_CSI_D6__SIM1_PD0 0x130 0x328 0x000 0x04 0x000
+#define MX25_PAD_CSI_D6__GPIO_1_31 0x130 0x328 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_D7__CSI_D7 0x134 0x32c 0x000 0x10 0x000
+#define MX25_PAD_CSI_D7__SDHC2_DAT_CLK 0x134 0x32C 0x4dc 0x12 0x001
+#define MX25_PAD_CSI_D7__GPIO_1_6 0x134 0x32c 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_D8__CSI_D8 0x138 0x330 0x000 0x10 0x000
+#define MX25_PAD_CSI_D8__AUD6_RXC 0x138 0x330 0x000 0x12 0x000
+#define MX25_PAD_CSI_D8__GPIO_1_7 0x138 0x330 0x000 0x15 0x000
+#define MX25_PAD_CSI_D8__CSPI3_SS2 0x138 0x330 0x4c4 0x17 0x000
+
+#define MX25_PAD_CSI_D9__CSI_D9 0x13c 0x334 0x000 0x10 0x000
+#define MX25_PAD_CSI_D9__AUD6_RXFS 0x13c 0x334 0x000 0x12 0x000
+#define MX25_PAD_CSI_D9__GPIO_4_21 0x13c 0x334 0x000 0x15 0x000
+#define MX25_PAD_CSI_D9__CSPI3_SS3 0x13c 0x334 0x4c8 0x17 0x000
+
+#define MX25_PAD_CSI_MCLK__CSI_MCLK 0x140 0x338 0x000 0x10 0x000
+#define MX25_PAD_CSI_MCLK__AUD6_TXD 0x140 0x338 0x000 0x11 0x000
+#define MX25_PAD_CSI_MCLK__SDHC2_DAT0 0x140 0x338 0x4e4 0x12 0x001
+#define MX25_PAD_CSI_MCLK__GPIO_1_8 0x140 0x338 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_VSYNC__CSI_VSYNC 0x144 0x33c 0x000 0x10 0x000
+#define MX25_PAD_CSI_VSYNC__AUD6_RXD 0x144 0x33c 0x000 0x11 0x000
+#define MX25_PAD_CSI_VSYNC__SDHC2_DAT1 0x144 0x33c 0x4e8 0x12 0x001
+#define MX25_PAD_CSI_VSYNC__GPIO_1_9 0x144 0x33c 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_HSYNC__CSI_HSYNC 0x148 0x340 0x000 0x10 0x000
+#define MX25_PAD_CSI_HSYNC__AUD6_TXC 0x148 0x340 0x000 0x11 0x000
+#define MX25_PAD_CSI_HSYNC__SDHC2_DAT2 0x148 0x340 0x4ec 0x12 0x001
+#define MX25_PAD_CSI_HSYNC__GPIO_1_10 0x148 0x340 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_PIXCLK__CSI_PIXCLK 0x14c 0x344 0x000 0x10 0x000
+#define MX25_PAD_CSI_PIXCLK__AUD6_TXFS 0x14c 0x344 0x000 0x11 0x000
+#define MX25_PAD_CSI_PIXCLK__SDHC2_DAT3 0x14c 0x344 0x4f0 0x12 0x001
+#define MX25_PAD_CSI_PIXCLK__GPIO_1_11 0x14c 0x344 0x000 0x15 0x000
+
+#define MX25_PAD_I2C1_CLK__I2C1_CLK 0x150 0x348 0x000 0x10 0x000
+#define MX25_PAD_I2C1_CLK__GPIO_1_12 0x150 0x348 0x000 0x15 0x000
+
+#define MX25_PAD_I2C1_DAT__I2C1_DAT 0x154 0x34c 0x000 0x10 0x000
+#define MX25_PAD_I2C1_DAT__GPIO_1_13 0x154 0x34c 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_MOSI__CSPI1_MOSI 0x158 0x350 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_MOSI__UART3_RXD 0x158 0x350 0x000 0x12 0x000
+#define MX25_PAD_CSPI1_MOSI__GPIO_1_14 0x158 0x350 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_MISO__CSPI1_MISO 0x15c 0x354 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_MISO__UART3_TXD 0x15c 0x354 0x000 0x12 0x000
+#define MX25_PAD_CSPI1_MISO__GPIO_1_15 0x15c 0x354 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_SS0__CSPI1_SS0 0x160 0x358 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_SS0__PWM2_PWMO 0x160 0x358 0x000 0x12 0x000
+#define MX25_PAD_CSPI1_SS0__GPIO_1_16 0x160 0x358 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_SS1__CSPI1_SS1 0x164 0x35c 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_SS1__I2C3_DAT 0x164 0x35C 0x528 0x11 0x001
+#define MX25_PAD_CSPI1_SS1__UART3_RTS 0x164 0x35c 0x000 0x12 0x000
+#define MX25_PAD_CSPI1_SS1__GPIO_1_17 0x164 0x35c 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_SCLK__CSPI1_SCLK 0x168 0x360 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_SCLK__UART3_CTS 0x168 0x360 0x000 0x12 0x000
+#define MX25_PAD_CSPI1_SCLK__GPIO_1_18 0x168 0x360 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_RDY__CSPI1_RDY 0x16c 0x364 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_RDY__GPIO_2_22 0x16c 0x364 0x000 0x15 0x000
+
+#define MX25_PAD_UART1_RXD__UART1_RXD 0x170 0x368 0x000 0x10 0x000
+#define MX25_PAD_UART1_RXD__GPIO_4_22 0x170 0x368 0x000 0x15 0x000
+
+#define MX25_PAD_UART1_TXD__UART1_TXD 0x174 0x36c 0x000 0x10 0x000
+#define MX25_PAD_UART1_TXD__GPIO_4_23 0x174 0x36c 0x000 0x15 0x000
+
+#define MX25_PAD_UART1_RTS__UART1_RTS 0x178 0x370 0x000 0x10 0x000
+#define MX25_PAD_UART1_RTS__CSI_D0 0x178 0x370 0x488 0x11 0x001
+#define MX25_PAD_UART1_RTS__CC3 0x178 0x370 0x000 0x12 0x000
+#define MX25_PAD_UART1_RTS__GPIO_4_24 0x178 0x370 0x000 0x15 0x000
+
+#define MX25_PAD_UART1_CTS__UART1_CTS 0x17c 0x374 0x000 0x10 0x000
+#define MX25_PAD_UART1_CTS__CSI_D1 0x17c 0x374 0x48c 0x11 0x001
+#define MX25_PAD_UART1_CTS__GPIO_4_25 0x17c 0x374 0x000 0x15 0x000
+
+#define MX25_PAD_UART2_RXD__UART2_RXD 0x180 0x378 0x000 0x10 0x000
+#define MX25_PAD_UART2_RXD__GPIO_4_26 0x180 0x378 0x000 0x15 0x000
+
+#define MX25_PAD_UART2_TXD__UART2_TXD 0x184 0x37c 0x000 0x10 0x000
+#define MX25_PAD_UART2_TXD__GPIO_4_27 0x184 0x37c 0x000 0x15 0x000
+
+#define MX25_PAD_UART2_RTS__UART2_RTS 0x188 0x380 0x000 0x10 0x000
+#define MX25_PAD_UART2_RTS__FEC_COL 0x188 0x380 0x504 0x12 0x002
+#define MX25_PAD_UART2_RTS__CC1 0x188 0x380 0x000 0x13 0x000
+#define MX25_PAD_UART2_RTS__GPIO_4_28 0x188 0x380 0x000 0x15 0x000
+
+#define MX25_PAD_UART2_CTS__UART2_CTS 0x18c 0x384 0x000 0x10 0x000
+#define MX25_PAD_UART2_CTS__FEC_RX_ERR 0x18c 0x384 0x518 0x12 0x002
+#define MX25_PAD_UART2_CTS__GPIO_4_29 0x18c 0x384 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_CMD__SD1_CMD 0x190 0x388 0x000 0x10 0x000
+#define MX25_PAD_SD1_CMD__CSPI2_MOSI 0x190 0x388 0x4a0 0x11 0x001
+#define MX25_PAD_SD1_CMD__FEC_RDATA2 0x190 0x388 0x50c 0x12 0x002
+#define MX25_PAD_SD1_CMD__GPIO_2_23 0x190 0x388 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_CLK__SD1_CLK 0x194 0x38c 0x000 0x10 0x000
+#define MX25_PAD_SD1_CLK__CSPI2_MISO 0x194 0x38c 0x49c 0x11 0x001
+#define MX25_PAD_SD1_CLK__FEC_RDATA3 0x194 0x38c 0x510 0x12 0x002
+#define MX25_PAD_SD1_CLK__GPIO_2_24 0x194 0x38c 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_DATA0__SD1_DATA0 0x198 0x390 0x000 0x10 0x000
+#define MX25_PAD_SD1_DATA0__CSPI2_SCLK 0x198 0x390 0x494 0x11 0x001
+#define MX25_PAD_SD1_DATA0__GPIO_2_25 0x198 0x390 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_DATA1__SD1_DATA1 0x19c 0x394 0x000 0x10 0x000
+#define MX25_PAD_SD1_DATA1__AUD7_RXD 0x19c 0x394 0x478 0x13 0x000
+#define MX25_PAD_SD1_DATA1__GPIO_2_26 0x19c 0x394 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_DATA2__SD1_DATA2 0x1a0 0x398 0x000 0x10 0x000
+#define MX25_PAD_SD1_DATA2__FEC_RX_CLK 0x1a0 0x398 0x514 0x12 0x002
+#define MX25_PAD_SD1_DATA2__GPIO_2_27 0x1a0 0x398 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_DATA3__SD1_DATA3 0x1a4 0x39c 0x000 0x10 0x000
+#define MX25_PAD_SD1_DATA3__FEC_CRS 0x1a4 0x39c 0x508 0x12 0x002
+#define MX25_PAD_SD1_DATA3__GPIO_2_28 0x1a4 0x39c 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_ROW0__KPP_ROW0 0x1a8 0x3a0 0x000 0x10 0x000
+#define MX25_PAD_KPP_ROW0__GPIO_2_29 0x1a8 0x3a0 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_ROW1__KPP_ROW1 0x1ac 0x3a4 0x000 0x10 0x000
+#define MX25_PAD_KPP_ROW1__GPIO_2_30 0x1ac 0x3a4 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_ROW2__KPP_ROW2 0x1b0 0x3a8 0x000 0x10 0x000
+#define MX25_PAD_KPP_ROW2__CSI_D0 0x1b0 0x3a8 0x488 0x13 0x002
+#define MX25_PAD_KPP_ROW2__GPIO_2_31 0x1b0 0x3a8 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_ROW3__KPP_ROW3 0x1b4 0x3ac 0x000 0x10 0x000
+#define MX25_PAD_KPP_ROW3__CSI_D1 0x1b4 0x3ac 0x48c 0x13 0x002
+#define MX25_PAD_KPP_ROW3__GPIO_3_0 0x1b4 0x3ac 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_COL0__KPP_COL0 0x1b8 0x3b0 0x000 0x10 0x000
+#define MX25_PAD_KPP_COL0__UART4_RXD_MUX 0x1b8 0x3b0 0x570 0x11 0x001
+#define MX25_PAD_KPP_COL0__AUD5_TXD 0x1b8 0x3b0 0x000 0x12 0x000
+#define MX25_PAD_KPP_COL0__GPIO_3_1 0x1b8 0x3b0 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_COL1__KPP_COL1 0x1bc 0x3b4 0x000 0x10 0x000
+#define MX25_PAD_KPP_COL1__UART4_TXD_MUX 0x1bc 0x3b4 0x000 0x11 0x000
+#define MX25_PAD_KPP_COL1__AUD5_RXD 0x1bc 0x3b4 0x000 0x12 0x000
+#define MX25_PAD_KPP_COL1__GPIO_3_2 0x1bc 0x3b4 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_COL2__KPP_COL2 0x1c0 0x3b8 0x000 0x10 0x000
+#define MX25_PAD_KPP_COL2__UART4_RTS 0x1c0 0x3b8 0x000 0x11 0x000
+#define MX25_PAD_KPP_COL2__AUD5_TXC 0x1c0 0x3b8 0x000 0x12 0x000
+#define MX25_PAD_KPP_COL2__GPIO_3_3 0x1c0 0x3b8 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_COL3__KPP_COL3 0x1c4 0x3bc 0x000 0x10 0x000
+#define MX25_PAD_KPP_COL3__UART4_CTS 0x1c4 0x3bc 0x000 0x11 0x000
+#define MX25_PAD_KPP_COL3__AUD5_TXFS 0x1c4 0x3bc 0x000 0x12 0x000
+#define MX25_PAD_KPP_COL3__GPIO_3_4 0x1c4 0x3bc 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_MDC__FEC_MDC 0x1c8 0x3c0 0x000 0x10 0x000
+#define MX25_PAD_FEC_MDC__AUD4_TXD 0x1c8 0x3c0 0x464 0x12 0x001
+#define MX25_PAD_FEC_MDC__GPIO_3_5 0x1c8 0x3c0 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_MDIO__FEC_MDIO 0x1cc 0x3c4 0x000 0x10 0x000
+#define MX25_PAD_FEC_MDIO__AUD4_RXD 0x1cc 0x3c4 0x460 0x12 0x001
+#define MX25_PAD_FEC_MDIO__GPIO_3_6 0x1cc 0x3c4 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_TDATA0__FEC_TDATA0 0x1d0 0x3c8 0x000 0x10 0x000
+#define MX25_PAD_FEC_TDATA0__GPIO_3_7 0x1d0 0x3c8 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_TDATA1__FEC_TDATA1 0x1d4 0x3cc 0x000 0x10 0x000
+#define MX25_PAD_FEC_TDATA1__AUD4_TXFS 0x1d4 0x3cc 0x474 0x12 0x001
+#define MX25_PAD_FEC_TDATA1__GPIO_3_8 0x1d4 0x3cc 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_TX_EN__FEC_TX_EN 0x1d8 0x3d0 0x000 0x10 0x000
+#define MX25_PAD_FEC_TX_EN__GPIO_3_9 0x1d8 0x3d0 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_RDATA0__FEC_RDATA0 0x1dc 0x3d4 0x000 0x10 0x000
+#define MX25_PAD_FEC_RDATA0__GPIO_3_10 0x1dc 0x3d4 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_RDATA1__FEC_RDATA1 0x1e0 0x3d8 0x000 0x10 0x000
+/*
+ * According to the i.MX25 Reference manual (IMX25RM, Rev. 2,
+ * 01/2011) this is CAN1_TX but that's wrong.
+ */
+#define MX25_PAD_FEC_RDATA1__CAN2_TX 0x1e0 0x3d8 0x000 0x14 0x000
+#define MX25_PAD_FEC_RDATA1__GPIO_3_11 0x1e0 0x3d8 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_RX_DV__FEC_RX_DV 0x1e4 0x3dc 0x000 0x10 0x000
+/*
+ * According to the i.MX25 Reference manual (IMX25RM, Rev. 2,
+ * 01/2011) this is CAN1_RX but that's wrong.
+ */
+#define MX25_PAD_FEC_RX_DV__CAN2_RX 0x1e4 0x3dc 0x484 0x14 0x000
+#define MX25_PAD_FEC_RX_DV__GPIO_3_12 0x1e4 0x3dc 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_TX_CLK__FEC_TX_CLK 0x1e8 0x3e0 0x000 0x10 0x000
+#define MX25_PAD_FEC_TX_CLK__GPIO_3_13 0x1e8 0x3e0 0x000 0x15 0x000
+
+#define MX25_PAD_RTCK__RTCK 0x1ec 0x3e4 0x000 0x10 0x000
+#define MX25_PAD_RTCK__OWIRE 0x1ec 0x3e4 0x000 0x11 0x000
+#define MX25_PAD_RTCK__GPIO_3_14 0x1ec 0x3e4 0x000 0x15 0x000
+
+#define MX25_PAD_DE_B__DE_B 0x1f0 0x3ec 0x000 0x10 0x000
+#define MX25_PAD_DE_B__GPIO_2_20 0x1f0 0x3ec 0x000 0x15 0x000
+
+#define MX25_PAD_GPIO_A__GPIO_A 0x1f4 0x3f0 0x000 0x10 0x000
+#define MX25_PAD_GPIO_A__CAN1_TX 0x1f4 0x3f0 0x000 0x16 0x000
+#define MX25_PAD_GPIO_A__USBOTG_PWR 0x1f4 0x3f0 0x000 0x12 0x000
+
+#define MX25_PAD_GPIO_B__GPIO_B 0x1f8 0x3f4 0x000 0x10 0x000
+#define MX25_PAD_GPIO_B__USBOTG_OC 0x1f8 0x3f4 0x57c 0x12 0x001
+#define MX25_PAD_GPIO_B__CAN1_RX 0x1f8 0x3f4 0x480 0x16 0x001
+
+#define MX25_PAD_GPIO_C__GPIO_C 0x1fc 0x3f8 0x000 0x10 0x000
+#define MX25_PAD_GPIO_C__PWM4_PWMO 0x1fc 0x3f8 0x000 0x11 0x000
+#define MX25_PAD_GPIO_C__I2C2_SCL 0x1fc 0x3f8 0x51c 0x12 0x001
+#define MX25_PAD_GPIO_C__KPP_COL4 0x1fc 0x3f8 0x52c 0x13 0x001
+#define MX25_PAD_GPIO_C__CAN2_TX 0x1fc 0x3f8 0x000 0x16 0x000
+
+#define MX25_PAD_GPIO_D__GPIO_D 0x200 0x3fc 0x000 0x10 0x000
+#define MX25_PAD_GPIO_D__I2C2_SDA 0x200 0x3fc 0x520 0x12 0x001
+#define MX25_PAD_GPIO_D__CAN2_RX 0x200 0x3fc 0x484 0x16 0x001
+
+#define MX25_PAD_GPIO_E__GPIO_E 0x204 0x400 0x000 0x10 0x000
+#define MX25_PAD_GPIO_E__I2C3_CLK 0x204 0x400 0x524 0x11 0x002
+#define MX25_PAD_GPIO_E__LD16 0x204 0x400 0x000 0x12 0x000
+#define MX25_PAD_GPIO_E__AUD7_TXD 0x204 0x400 0x000 0x14 0x000
+#define MX25_PAD_GPIO_E__UART4_RXD 0x204 0x400 0x570 0x16 0x002
+
+#define MX25_PAD_GPIO_F__GPIO_F 0x208 0x404 0x000 0x10 0x000
+#define MX25_PAD_GPIO_F__LD17 0x208 0x404 0x000 0x12 0x000
+#define MX25_PAD_GPIO_F__AUD7_TXC 0x208 0x404 0x000 0x14 0x000
+#define MX25_PAD_GPIO_F__UART4_TXD 0x208 0x404 0x000 0x16 0x000
+
+#define MX25_PAD_EXT_ARMCLK__EXT_ARMCLK 0x20c 0x000 0x000 0x10 0x000
+#define MX25_PAD_EXT_ARMCLK__GPIO_3_15 0x20c 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_UPLL_BYPCLK__UPLL_BYPCLK 0x210 0x000 0x000 0x10 0x000
+#define MX25_PAD_UPLL_BYPCLK__GPIO_3_16 0x210 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_VSTBY_REQ__VSTBY_REQ 0x214 0x408 0x000 0x10 0x000
+#define MX25_PAD_VSTBY_REQ__AUD7_TXFS 0x214 0x408 0x000 0x14 0x000
+#define MX25_PAD_VSTBY_REQ__GPIO_3_17 0x214 0x408 0x000 0x15 0x000
+
+#define MX25_PAD_VSTBY_ACK__VSTBY_ACK 0x218 0x40c 0x000 0x10 0x000
+#define MX25_PAD_VSTBY_ACK__GPIO_3_18 0x218 0x40c 0x000 0x15 0x000
+
+#define MX25_PAD_POWER_FAIL__POWER_FAIL 0x21c 0x410 0x000 0x10 0x000
+#define MX25_PAD_POWER_FAIL__AUD7_RXD 0x21c 0x410 0x478 0x14 0x001
+#define MX25_PAD_POWER_FAIL__GPIO_3_19 0x21c 0x410 0x000 0x15 0x000
+
+#define MX25_PAD_CLKO__CLKO 0x220 0x414 0x000 0x10 0x000
+#define MX25_PAD_CLKO__GPIO_2_21 0x220 0x414 0x000 0x15 0x000
+
+#define MX25_PAD_BOOT_MODE0__BOOT_MODE0 0x224 0x000 0x000 0x00 0x000
+#define MX25_PAD_BOOT_MODE0__GPIO_4_30 0x224 0x000 0x000 0x05 0x000
+
+#define MX25_PAD_BOOT_MODE1__BOOT_MODE1 0x228 0x000 0x000 0x00 0x000
+#define MX25_PAD_BOOT_MODE1__GPIO_4_31 0x228 0x000 0x000 0x05 0x000
+
+#endif /* __DTS_IMX25_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi
new file mode 100644
index 000000000..0097c43f7
--- /dev/null
+++ b/arch/arm/boot/dts/imx25.dtsi
@@ -0,0 +1,570 @@
+/*
+ * Copyright 2012 Sascha Hauer, Pengutronix <s.hauer@pengutronix.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
+ */
+
+#include "skeleton.dtsi"
+#include "imx25-pinfunc.h"
+
+/ {
+ aliases {
+ ethernet0 = &fec;
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ i2c2 = &i2c3;
+ mmc0 = &esdhc1;
+ mmc1 = &esdhc2;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ spi0 = &spi1;
+ spi1 = &spi2;
+ spi2 = &spi3;
+ usb0 = &usbotg;
+ usb1 = &usbhost1;
+ };
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm926ej-s";
+ device_type = "cpu";
+ };
+ };
+
+ asic: asic-interrupt-controller@68000000 {
+ compatible = "fsl,imx25-asic", "fsl,avic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x68000000 0x8000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ osc {
+ compatible = "fsl,imx-osc", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&asic>;
+ ranges;
+
+ aips@43f00000 { /* AIPS1 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x43f00000 0x100000>;
+ ranges;
+
+ i2c1: i2c@43f80000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx25-i2c", "fsl,imx21-i2c";
+ reg = <0x43f80000 0x4000>;
+ clocks = <&clks 48>;
+ clock-names = "";
+ interrupts = <3>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@43f84000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx25-i2c", "fsl,imx21-i2c";
+ reg = <0x43f84000 0x4000>;
+ clocks = <&clks 48>;
+ clock-names = "";
+ interrupts = <10>;
+ status = "disabled";
+ };
+
+ can1: can@43f88000 {
+ compatible = "fsl,imx25-flexcan", "fsl,p1010-flexcan";
+ reg = <0x43f88000 0x4000>;
+ interrupts = <43>;
+ clocks = <&clks 75>, <&clks 75>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ can2: can@43f8c000 {
+ compatible = "fsl,imx25-flexcan", "fsl,p1010-flexcan";
+ reg = <0x43f8c000 0x4000>;
+ interrupts = <44>;
+ clocks = <&clks 76>, <&clks 76>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart1: serial@43f90000 {
+ compatible = "fsl,imx25-uart", "fsl,imx21-uart";
+ reg = <0x43f90000 0x4000>;
+ interrupts = <45>;
+ clocks = <&clks 120>, <&clks 57>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart2: serial@43f94000 {
+ compatible = "fsl,imx25-uart", "fsl,imx21-uart";
+ reg = <0x43f94000 0x4000>;
+ interrupts = <32>;
+ clocks = <&clks 121>, <&clks 57>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ i2c2: i2c@43f98000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx25-i2c", "fsl,imx21-i2c";
+ reg = <0x43f98000 0x4000>;
+ clocks = <&clks 48>;
+ clock-names = "";
+ interrupts = <4>;
+ status = "disabled";
+ };
+
+ owire@43f9c000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x43f9c000 0x4000>;
+ clocks = <&clks 51>;
+ clock-names = "";
+ interrupts = <2>;
+ status = "disabled";
+ };
+
+ spi1: cspi@43fa4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
+ reg = <0x43fa4000 0x4000>;
+ clocks = <&clks 78>, <&clks 78>;
+ clock-names = "ipg", "per";
+ interrupts = <14>;
+ status = "disabled";
+ };
+
+ kpp: kpp@43fa8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx25-kpp", "fsl,imx21-kpp";
+ reg = <0x43fa8000 0x4000>;
+ clocks = <&clks 102>;
+ clock-names = "";
+ interrupts = <24>;
+ status = "disabled";
+ };
+
+ iomuxc: iomuxc@43fac000 {
+ compatible = "fsl,imx25-iomuxc";
+ reg = <0x43fac000 0x4000>;
+ };
+
+ audmux: audmux@43fb0000 {
+ compatible = "fsl,imx25-audmux", "fsl,imx31-audmux";
+ reg = <0x43fb0000 0x4000>;
+ status = "disabled";
+ };
+ };
+
+ spba@50000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x50000000 0x40000>;
+ ranges;
+
+ spi3: cspi@50004000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
+ reg = <0x50004000 0x4000>;
+ interrupts = <0>;
+ clocks = <&clks 80>, <&clks 80>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart4: serial@50008000 {
+ compatible = "fsl,imx25-uart", "fsl,imx21-uart";
+ reg = <0x50008000 0x4000>;
+ interrupts = <5>;
+ clocks = <&clks 123>, <&clks 57>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart3: serial@5000c000 {
+ compatible = "fsl,imx25-uart", "fsl,imx21-uart";
+ reg = <0x5000c000 0x4000>;
+ interrupts = <18>;
+ clocks = <&clks 122>, <&clks 57>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ spi2: cspi@50010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
+ reg = <0x50010000 0x4000>;
+ clocks = <&clks 79>, <&clks 79>;
+ clock-names = "ipg", "per";
+ interrupts = <13>;
+ status = "disabled";
+ };
+
+ ssi2: ssi@50014000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx25-ssi", "fsl,imx21-ssi";
+ reg = <0x50014000 0x4000>;
+ interrupts = <11>;
+ clocks = <&clks 118>;
+ clock-names = "ipg";
+ dmas = <&sdma 24 1 0>,
+ <&sdma 25 1 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ esai@50018000 {
+ reg = <0x50018000 0x4000>;
+ interrupts = <7>;
+ };
+
+ uart5: serial@5002c000 {
+ compatible = "fsl,imx25-uart", "fsl,imx21-uart";
+ reg = <0x5002c000 0x4000>;
+ interrupts = <40>;
+ clocks = <&clks 124>, <&clks 57>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ tsc: tsc@50030000 {
+ compatible = "fsl,imx25-adc", "fsl,imx21-tsc";
+ reg = <0x50030000 0x4000>;
+ interrupts = <46>;
+ clocks = <&clks 119>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ ssi1: ssi@50034000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx25-ssi", "fsl,imx21-ssi";
+ reg = <0x50034000 0x4000>;
+ interrupts = <12>;
+ clocks = <&clks 117>;
+ clock-names = "ipg";
+ dmas = <&sdma 28 1 0>,
+ <&sdma 29 1 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ fec: ethernet@50038000 {
+ compatible = "fsl,imx25-fec";
+ reg = <0x50038000 0x4000>;
+ interrupts = <57>;
+ clocks = <&clks 88>, <&clks 65>;
+ clock-names = "ipg", "ahb";
+ status = "disabled";
+ };
+ };
+
+ aips@53f00000 { /* AIPS2 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x53f00000 0x100000>;
+ ranges;
+
+ clks: ccm@53f80000 {
+ compatible = "fsl,imx25-ccm";
+ reg = <0x53f80000 0x4000>;
+ interrupts = <31>;
+ #clock-cells = <1>;
+ };
+
+ gpt4: timer@53f84000 {
+ compatible = "fsl,imx25-gpt", "fsl,imx31-gpt";
+ reg = <0x53f84000 0x4000>;
+ clocks = <&clks 95>, <&clks 47>;
+ clock-names = "ipg", "per";
+ interrupts = <1>;
+ };
+
+ gpt3: timer@53f88000 {
+ compatible = "fsl,imx25-gpt", "fsl,imx31-gpt";
+ reg = <0x53f88000 0x4000>;
+ clocks = <&clks 94>, <&clks 47>;
+ clock-names = "ipg", "per";
+ interrupts = <29>;
+ };
+
+ gpt2: timer@53f8c000 {
+ compatible = "fsl,imx25-gpt", "fsl,imx31-gpt";
+ reg = <0x53f8c000 0x4000>;
+ clocks = <&clks 93>, <&clks 47>;
+ clock-names = "ipg", "per";
+ interrupts = <53>;
+ };
+
+ gpt1: timer@53f90000 {
+ compatible = "fsl,imx25-gpt", "fsl,imx31-gpt";
+ reg = <0x53f90000 0x4000>;
+ clocks = <&clks 92>, <&clks 47>;
+ clock-names = "ipg", "per";
+ interrupts = <54>;
+ };
+
+ epit1: timer@53f94000 {
+ compatible = "fsl,imx25-epit";
+ reg = <0x53f94000 0x4000>;
+ interrupts = <28>;
+ };
+
+ epit2: timer@53f98000 {
+ compatible = "fsl,imx25-epit";
+ reg = <0x53f98000 0x4000>;
+ interrupts = <27>;
+ };
+
+ gpio4: gpio@53f9c000 {
+ compatible = "fsl,imx25-gpio", "fsl,imx35-gpio";
+ reg = <0x53f9c000 0x4000>;
+ interrupts = <23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pwm2: pwm@53fa0000 {
+ compatible = "fsl,imx25-pwm", "fsl,imx27-pwm";
+ #pwm-cells = <2>;
+ reg = <0x53fa0000 0x4000>;
+ clocks = <&clks 106>, <&clks 52>;
+ clock-names = "ipg", "per";
+ interrupts = <36>;
+ };
+
+ gpio3: gpio@53fa4000 {
+ compatible = "fsl,imx25-gpio", "fsl,imx35-gpio";
+ reg = <0x53fa4000 0x4000>;
+ interrupts = <16>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pwm3: pwm@53fa8000 {
+ compatible = "fsl,imx25-pwm", "fsl,imx27-pwm";
+ #pwm-cells = <2>;
+ reg = <0x53fa8000 0x4000>;
+ clocks = <&clks 107>, <&clks 52>;
+ clock-names = "ipg", "per";
+ interrupts = <41>;
+ };
+
+ esdhc1: esdhc@53fb4000 {
+ compatible = "fsl,imx25-esdhc";
+ reg = <0x53fb4000 0x4000>;
+ interrupts = <9>;
+ clocks = <&clks 86>, <&clks 63>, <&clks 45>;
+ clock-names = "ipg", "ahb", "per";
+ status = "disabled";
+ };
+
+ esdhc2: esdhc@53fb8000 {
+ compatible = "fsl,imx25-esdhc";
+ reg = <0x53fb8000 0x4000>;
+ interrupts = <8>;
+ clocks = <&clks 87>, <&clks 64>, <&clks 46>;
+ clock-names = "ipg", "ahb", "per";
+ status = "disabled";
+ };
+
+ lcdc: lcdc@53fbc000 {
+ compatible = "fsl,imx25-fb", "fsl,imx21-fb";
+ reg = <0x53fbc000 0x4000>;
+ interrupts = <39>;
+ clocks = <&clks 103>, <&clks 66>, <&clks 49>;
+ clock-names = "ipg", "ahb", "per";
+ status = "disabled";
+ };
+
+ slcdc@53fc0000 {
+ reg = <0x53fc0000 0x4000>;
+ interrupts = <38>;
+ status = "disabled";
+ };
+
+ pwm4: pwm@53fc8000 {
+ compatible = "fsl,imx25-pwm", "fsl,imx27-pwm";
+ #pwm-cells = <2>;
+ reg = <0x53fc8000 0x4000>;
+ clocks = <&clks 108>, <&clks 52>;
+ clock-names = "ipg", "per";
+ interrupts = <42>;
+ };
+
+ gpio1: gpio@53fcc000 {
+ compatible = "fsl,imx25-gpio", "fsl,imx35-gpio";
+ reg = <0x53fcc000 0x4000>;
+ interrupts = <52>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@53fd0000 {
+ compatible = "fsl,imx25-gpio", "fsl,imx35-gpio";
+ reg = <0x53fd0000 0x4000>;
+ interrupts = <51>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ sdma: sdma@53fd4000 {
+ compatible = "fsl,imx25-sdma";
+ reg = <0x53fd4000 0x4000>;
+ clocks = <&clks 112>, <&clks 68>;
+ clock-names = "ipg", "ahb";
+ #dma-cells = <3>;
+ interrupts = <34>;
+ fsl,sdma-ram-script-name = "/*(DEBLOBBED)*/";
+ };
+
+ wdog@53fdc000 {
+ compatible = "fsl,imx25-wdt", "fsl,imx21-wdt";
+ reg = <0x53fdc000 0x4000>;
+ clocks = <&clks 126>;
+ clock-names = "";
+ interrupts = <55>;
+ };
+
+ pwm1: pwm@53fe0000 {
+ compatible = "fsl,imx25-pwm", "fsl,imx27-pwm";
+ #pwm-cells = <2>;
+ reg = <0x53fe0000 0x4000>;
+ clocks = <&clks 105>, <&clks 52>;
+ clock-names = "ipg", "per";
+ interrupts = <26>;
+ };
+
+ iim: iim@53ff0000 {
+ compatible = "fsl,imx25-iim", "fsl,imx27-iim";
+ reg = <0x53ff0000 0x4000>;
+ interrupts = <19>;
+ clocks = <&clks 99>;
+ };
+
+ usbotg: usb@53ff4000 {
+ compatible = "fsl,imx25-usb", "fsl,imx27-usb";
+ reg = <0x53ff4000 0x0200>;
+ interrupts = <37>;
+ clocks = <&clks 70>;
+ fsl,usbmisc = <&usbmisc 0>;
+ fsl,usbphy = <&usbphy0>;
+ status = "disabled";
+ };
+
+ usbhost1: usb@53ff4400 {
+ compatible = "fsl,imx25-usb", "fsl,imx27-usb";
+ reg = <0x53ff4400 0x0200>;
+ interrupts = <35>;
+ clocks = <&clks 70>;
+ fsl,usbmisc = <&usbmisc 1>;
+ fsl,usbphy = <&usbphy1>;
+ status = "disabled";
+ };
+
+ usbmisc: usbmisc@53ff4600 {
+ #index-cells = <1>;
+ compatible = "fsl,imx25-usbmisc";
+ clocks = <&clks 9>, <&clks 70>, <&clks 8>;
+ clock-names = "ipg", "ahb", "per";
+ reg = <0x53ff4600 0x00f>;
+ };
+
+ dryice@53ffc000 {
+ compatible = "fsl,imx25-dryice", "fsl,imx25-rtc";
+ reg = <0x53ffc000 0x4000>;
+ clocks = <&clks 81>;
+ clock-names = "ipg";
+ interrupts = <25>;
+ };
+ };
+
+ iram: sram@78000000 {
+ compatible = "mmio-sram";
+ reg = <0x78000000 0x20000>;
+ };
+
+ emi@80000000 {
+ compatible = "fsl,emi-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80000000 0x3b002000>;
+ ranges;
+
+ nfc: nand@bb000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ compatible = "fsl,imx25-nand";
+ reg = <0xbb000000 0x2000>;
+ clocks = <&clks 50>;
+ clock-names = "";
+ interrupts = <33>;
+ status = "disabled";
+ };
+ };
+ };
+
+ usbphy {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usbphy0: usb-phy@0 {
+ reg = <0>;
+ compatible = "usb-nop-xceiv";
+ };
+
+ usbphy1: usb-phy@1 {
+ reg = <1>;
+ compatible = "usb-nop-xceiv";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx27-apf27.dts b/arch/arm/boot/dts/imx27-apf27.dts
new file mode 100644
index 000000000..73aae4f5e
--- /dev/null
+++ b/arch/arm/boot/dts/imx27-apf27.dts
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2012 Philippe Reynes <tremyfr@yahoo.fr>
+ * Copyright 2012 Armadeus Systems <support@armadeus.com>
+ *
+ * Based on code which is: Copyright 2012 Sascha Hauer, Pengutronix
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx27.dtsi"
+
+/ {
+ model = "Armadeus Systems APF27 module";
+ compatible = "armadeus,imx27-apf27", "fsl,imx27";
+
+ memory {
+ reg = <0xa0000000 0x04000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ osc26m {
+ compatible = "fsl,imx-osc26m", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+ };
+};
+
+&iomuxc {
+ imx27-apf27 {
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ MX27_PAD_SD3_CMD__FEC_TXD0 0x0
+ MX27_PAD_SD3_CLK__FEC_TXD1 0x0
+ MX27_PAD_ATA_DATA0__FEC_TXD2 0x0
+ MX27_PAD_ATA_DATA1__FEC_TXD3 0x0
+ MX27_PAD_ATA_DATA2__FEC_RX_ER 0x0
+ MX27_PAD_ATA_DATA3__FEC_RXD1 0x0
+ MX27_PAD_ATA_DATA4__FEC_RXD2 0x0
+ MX27_PAD_ATA_DATA5__FEC_RXD3 0x0
+ MX27_PAD_ATA_DATA6__FEC_MDIO 0x0
+ MX27_PAD_ATA_DATA7__FEC_MDC 0x0
+ MX27_PAD_ATA_DATA8__FEC_CRS 0x0
+ MX27_PAD_ATA_DATA9__FEC_TX_CLK 0x0
+ MX27_PAD_ATA_DATA10__FEC_RXD0 0x0
+ MX27_PAD_ATA_DATA11__FEC_RX_DV 0x0
+ MX27_PAD_ATA_DATA12__FEC_RX_CLK 0x0
+ MX27_PAD_ATA_DATA13__FEC_COL 0x0
+ MX27_PAD_ATA_DATA14__FEC_TX_ER 0x0
+ MX27_PAD_ATA_DATA15__FEC_TX_EN 0x0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX27_PAD_UART1_TXD__UART1_TXD 0x0
+ MX27_PAD_UART1_RXD__UART1_RXD 0x0
+ >;
+ };
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ status = "okay";
+};
+
+&nfc {
+ status = "okay";
+ nand-bus-width = <16>;
+ nand-ecc-mode = "hw";
+ nand-on-flash-bbt;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x100000>;
+ };
+
+ partition@100000 {
+ label = "env";
+ reg = <0x100000 0x80000>;
+ };
+
+ partition@180000 {
+ label = "env2";
+ reg = <0x180000 0x80000>;
+ };
+
+ partition@200000 {
+ label = "firmware";
+ reg = <0x200000 0x80000>;
+ };
+
+ partition@280000 {
+ label = "dtb";
+ reg = <0x280000 0x80000>;
+ };
+
+ partition@300000 {
+ label = "kernel";
+ reg = <0x300000 0x500000>;
+ };
+
+ partition@800000 {
+ label = "rootfs";
+ reg = <0x800000 0xf800000>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx27-apf27dev.dts b/arch/arm/boot/dts/imx27-apf27dev.dts
new file mode 100644
index 000000000..bba3f41b8
--- /dev/null
+++ b/arch/arm/boot/dts/imx27-apf27dev.dts
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2013 Armadeus Systems - <support@armadeus.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
+ */
+
+/* APF27Dev is a docking board for the APF27 SOM */
+#include "imx27-apf27.dts"
+
+/ {
+ model = "Armadeus Systems APF27Dev docking/development board";
+ compatible = "armadeus,imx27-apf27dev", "armadeus,imx27-apf27", "fsl,imx27";
+
+ display: display {
+ model = "Chimei-LW700AT9003";
+ native-mode = <&timing0>;
+ bits-per-pixel = <16>; /* non-standard but required */
+ fsl,pcr = <0xfae80083>; /* non-standard but required */
+ display-timings {
+ timing0: 800x480 {
+ clock-frequency = <33000033>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <96>;
+ hfront-porch = <96>;
+ vback-porch = <20>;
+ vfront-porch = <21>;
+ hsync-len = <64>;
+ vsync-len = <4>;
+ };
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ user-key {
+ label = "user";
+ gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>;
+ linux,code = <276>; /* BTN_EXTRA */
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ user {
+ label = "Heartbeat";
+ gpios = <&gpio6 14 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_max5821: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "max5821-reg";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+ };
+};
+
+&cspi1 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cspi1 &pinctrl_cspi1_cs>;
+ status = "okay";
+
+ adc@0 {
+ compatible = "maxim,max1027";
+ reg = <0>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_max1027>;
+ spi-max-frequency = <10000000>;
+ };
+};
+
+&cspi2 {
+ fsl,spi-num-chipselects = <3>;
+ cs-gpios = <&gpio4 21 GPIO_ACTIVE_LOW>,
+ <&gpio4 27 GPIO_ACTIVE_LOW>,
+ <&gpio2 17 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cspi2 &pinctrl_cspi2_cs>;
+ status = "okay";
+};
+
+&fb {
+ display = <&display>;
+ fsl,dmacr = <0x00020010>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_imxfb1>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <0x68>;
+ };
+
+ max5821@38 {
+ compatible = "maxim,max5821";
+ reg = <0x38>;
+ vref-supply = <&reg_max5821>;
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&iomuxc {
+ imx27-apf27dev {
+ pinctrl_cspi1: cspi1grp {
+ fsl,pins = <
+ MX27_PAD_CSPI1_MISO__CSPI1_MISO 0x0
+ MX27_PAD_CSPI1_MOSI__CSPI1_MOSI 0x0
+ MX27_PAD_CSPI1_SCLK__CSPI1_SCLK 0x0
+ >;
+ };
+
+ pinctrl_cspi1_cs: cspi1csgrp {
+ fsl,pins = <MX27_PAD_CSPI1_SS0__GPIO4_28 0x0>;
+ };
+
+ pinctrl_cspi2: cspi2grp {
+ fsl,pins = <
+ MX27_PAD_CSPI2_MISO__CSPI2_MISO 0x0
+ MX27_PAD_CSPI2_MOSI__CSPI2_MOSI 0x0
+ MX27_PAD_CSPI2_SCLK__CSPI2_SCLK 0x0
+ >;
+ };
+
+ pinctrl_cspi2_cs: cspi2csgrp {
+ fsl,pins = <
+ MX27_PAD_CSI_D5__GPIO2_17 0x0
+ MX27_PAD_CSPI2_SS0__GPIO4_21 0x0
+ MX27_PAD_CSPI1_SS1__GPIO4_27 0x0
+ >;
+ };
+
+ pinctrl_gpio_leds: gpioledsgrp {
+ fsl,pins = <MX27_PAD_PC_VS1__GPIO6_14 0x0>;
+ };
+
+ pinctrl_gpio_keys: gpiokeysgrp {
+ fsl,pins = <MX27_PAD_PC_VS2__GPIO6_13 0x0>;
+ };
+
+ pinctrl_imxfb1: imxfbgrp {
+ fsl,pins = <
+ MX27_PAD_CLS__CLS 0x0
+ MX27_PAD_CONTRAST__CONTRAST 0x0
+ MX27_PAD_LD0__LD0 0x0
+ MX27_PAD_LD1__LD1 0x0
+ MX27_PAD_LD2__LD2 0x0
+ MX27_PAD_LD3__LD3 0x0
+ MX27_PAD_LD4__LD4 0x0
+ MX27_PAD_LD5__LD5 0x0
+ MX27_PAD_LD6__LD6 0x0
+ MX27_PAD_LD7__LD7 0x0
+ MX27_PAD_LD8__LD8 0x0
+ MX27_PAD_LD9__LD9 0x0
+ MX27_PAD_LD10__LD10 0x0
+ MX27_PAD_LD11__LD11 0x0
+ MX27_PAD_LD12__LD12 0x0
+ MX27_PAD_LD13__LD13 0x0
+ MX27_PAD_LD14__LD14 0x0
+ MX27_PAD_LD15__LD15 0x0
+ MX27_PAD_LD16__LD16 0x0
+ MX27_PAD_LD17__LD17 0x0
+ MX27_PAD_LSCLK__LSCLK 0x0
+ MX27_PAD_OE_ACD__OE_ACD 0x0
+ MX27_PAD_PS__PS 0x0
+ MX27_PAD_REV__REV 0x0
+ MX27_PAD_SPL_SPR__SPL_SPR 0x0
+ MX27_PAD_HSYNC__HSYNC 0x0
+ MX27_PAD_VSYNC__VSYNC 0x0
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX27_PAD_I2C_DATA__I2C_DATA 0x0
+ MX27_PAD_I2C_CLK__I2C_CLK 0x0
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX27_PAD_I2C2_SDA__I2C2_SDA 0x0
+ MX27_PAD_I2C2_SCL__I2C2_SCL 0x0
+ >;
+ };
+
+ pinctrl_max1027: max1027 {
+ fsl,pins = <
+ MX27_PAD_UART1_CTS__GPIO5_14 0x0 /* CNVST */
+ MX27_PAD_UART1_RTS__GPIO5_15 0x0 /* EOC */
+ >;
+ };
+
+ pinctrl_pwm: pwmgrp {
+ fsl,pins = <
+ MX27_PAD_PWMO__PWMO 0x0
+ >;
+ };
+
+ pinctrl_sdhc2: sdhc2grp {
+ fsl,pins = <
+ MX27_PAD_SD2_CLK__SD2_CLK 0x0
+ MX27_PAD_SD2_CMD__SD2_CMD 0x0
+ MX27_PAD_SD2_D0__SD2_D0 0x0
+ MX27_PAD_SD2_D1__SD2_D1 0x0
+ MX27_PAD_SD2_D2__SD2_D2 0x0
+ MX27_PAD_SD2_D3__SD2_D3 0x0
+ >;
+ };
+
+ pinctrl_sdhc2_cd: sdhc2cdgrp {
+ fsl,pins = <MX27_PAD_TOUT__GPIO3_14 0x0>;
+ };
+ };
+};
+
+&sdhci2 {
+ bus-width = <4>;
+ cd-gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdhc2 &pinctrl_sdhc2_cd>;
+ status = "okay";
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm>;
+};
diff --git a/arch/arm/boot/dts/imx27-eukrea-cpuimx27.dtsi b/arch/arm/boot/dts/imx27-eukrea-cpuimx27.dtsi
new file mode 100644
index 000000000..e2242638e
--- /dev/null
+++ b/arch/arm/boot/dts/imx27-eukrea-cpuimx27.dtsi
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx27.dtsi"
+
+/ {
+ model = "Eukrea CPUIMX27";
+ compatible = "eukrea,cpuimx27", "fsl,imx27";
+
+ memory {
+ reg = <0xa0000000 0x04000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "simple-bus";
+
+ clk14745600: clock@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <14745600>;
+ reg = <0>;
+ };
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pcf8563@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+};
+
+&nfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nfc>;
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ nand-on-flash-bbt;
+ status = "okay";
+};
+
+&owire {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_owire>;
+ status = "okay";
+};
+
+&sdhci2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdhc2>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&usbh2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh2>;
+ dr_mode = "host";
+ phy_type = "ulpi";
+ disable-over-current;
+ status = "okay";
+};
+
+&usbotg {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ dr_mode = "otg";
+ phy_type = "ulpi";
+ disable-over-current;
+ status = "okay";
+};
+
+&weim {
+ status = "okay";
+
+ nor: nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0 0x00000000 0x04000000>;
+ bank-width = <2>;
+ linux,mtd-name = "physmap-flash.0";
+ fsl,weim-cs-timing = <0x00008f03 0xa0330d01 0x002208c0>;
+ };
+
+ uart8250@3,200000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart8250_1>;
+ compatible = "ns8250";
+ clocks = <&clk14745600>;
+ fsl,weim-cs-timing = <0x0000d603 0x0d1d0d01 0x00d20000>;
+ interrupts = <&gpio2 23 IRQ_TYPE_LEVEL_LOW>;
+ reg = <3 0x200000 0x1000>;
+ reg-shift = <1>;
+ reg-io-width = <1>;
+ no-loopback-test;
+ };
+
+ uart8250@3,400000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart8250_2>;
+ compatible = "ns8250";
+ clocks = <&clk14745600>;
+ fsl,weim-cs-timing = <0x0000d603 0x0d1d0d01 0x00d20000>;
+ interrupts = <&gpio2 22 IRQ_TYPE_LEVEL_LOW>;
+ reg = <3 0x400000 0x1000>;
+ reg-shift = <1>;
+ reg-io-width = <1>;
+ no-loopback-test;
+ };
+
+ uart8250@3,800000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart8250_3>;
+ compatible = "ns8250";
+ clocks = <&clk14745600>;
+ fsl,weim-cs-timing = <0x0000d603 0x0d1d0d01 0x00d20000>;
+ interrupts = <&gpio2 27 IRQ_TYPE_LEVEL_LOW>;
+ reg = <3 0x800000 0x1000>;
+ reg-shift = <1>;
+ reg-io-width = <1>;
+ no-loopback-test;
+ };
+
+ uart8250@3,1000000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart8250_4>;
+ compatible = "ns8250";
+ clocks = <&clk14745600>;
+ fsl,weim-cs-timing = <0x0000d603 0x0d1d0d01 0x00d20000>;
+ interrupts = <&gpio2 30 IRQ_TYPE_LEVEL_LOW>;
+ reg = <3 0x1000000 0x1000>;
+ reg-shift = <1>;
+ reg-io-width = <1>;
+ no-loopback-test;
+ };
+};
+
+&iomuxc {
+ imx27-eukrea-cpuimx27 {
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX27_PAD_SD3_CMD__FEC_TXD0 0x0
+ MX27_PAD_SD3_CLK__FEC_TXD1 0x0
+ MX27_PAD_ATA_DATA0__FEC_TXD2 0x0
+ MX27_PAD_ATA_DATA1__FEC_TXD3 0x0
+ MX27_PAD_ATA_DATA2__FEC_RX_ER 0x0
+ MX27_PAD_ATA_DATA3__FEC_RXD1 0x0
+ MX27_PAD_ATA_DATA4__FEC_RXD2 0x0
+ MX27_PAD_ATA_DATA5__FEC_RXD3 0x0
+ MX27_PAD_ATA_DATA6__FEC_MDIO 0x0
+ MX27_PAD_ATA_DATA7__FEC_MDC 0x0
+ MX27_PAD_ATA_DATA8__FEC_CRS 0x0
+ MX27_PAD_ATA_DATA9__FEC_TX_CLK 0x0
+ MX27_PAD_ATA_DATA10__FEC_RXD0 0x0
+ MX27_PAD_ATA_DATA11__FEC_RX_DV 0x0
+ MX27_PAD_ATA_DATA12__FEC_RX_CLK 0x0
+ MX27_PAD_ATA_DATA13__FEC_COL 0x0
+ MX27_PAD_ATA_DATA14__FEC_TX_ER 0x0
+ MX27_PAD_ATA_DATA15__FEC_TX_EN 0x0
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX27_PAD_I2C_DATA__I2C_DATA 0x0
+ MX27_PAD_I2C_CLK__I2C_CLK 0x0
+ >;
+ };
+
+ pinctrl_nfc: nfcgrp {
+ fsl,pins = <
+ MX27_PAD_NFRB__NFRB 0x0
+ MX27_PAD_NFCLE__NFCLE 0x0
+ MX27_PAD_NFWP_B__NFWP_B 0x0
+ MX27_PAD_NFCE_B__NFCE_B 0x0
+ MX27_PAD_NFALE__NFALE 0x0
+ MX27_PAD_NFRE_B__NFRE_B 0x0
+ MX27_PAD_NFWE_B__NFWE_B 0x0
+ >;
+ };
+
+ pinctrl_owire: owiregrp {
+ fsl,pins = <
+ MX27_PAD_RTCK__OWIRE 0x0
+ >;
+ };
+
+ pinctrl_sdhc2: sdhc2grp {
+ fsl,pins = <
+ MX27_PAD_SD2_CLK__SD2_CLK 0x0
+ MX27_PAD_SD2_CMD__SD2_CMD 0x0
+ MX27_PAD_SD2_D0__SD2_D0 0x0
+ MX27_PAD_SD2_D1__SD2_D1 0x0
+ MX27_PAD_SD2_D2__SD2_D2 0x0
+ MX27_PAD_SD2_D3__SD2_D3 0x0
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX27_PAD_USBH1_TXDM__UART4_TXD 0x0
+ MX27_PAD_USBH1_RXDP__UART4_RXD 0x0
+ MX27_PAD_USBH1_TXDP__UART4_CTS 0x0
+ MX27_PAD_USBH1_FS__UART4_RTS 0x0
+ >;
+ };
+
+ pinctrl_uart8250_1: uart82501grp {
+ fsl,pins = <
+ MX27_PAD_USB_PWR__GPIO2_23 0x0
+ >;
+ };
+
+ pinctrl_uart8250_2: uart82502grp {
+ fsl,pins = <
+ MX27_PAD_USBH1_SUSP__GPIO2_22 0x0
+ >;
+ };
+
+ pinctrl_uart8250_3: uart82503grp {
+ fsl,pins = <
+ MX27_PAD_USBH1_OE_B__GPIO2_27 0x0
+ >;
+ };
+
+ pinctrl_uart8250_4: uart82504grp {
+ fsl,pins = <
+ MX27_PAD_USBH1_RXDM__GPIO2_30 0x0
+ >;
+ };
+
+ pinctrl_usbh2: usbh2grp {
+ fsl,pins = <
+ MX27_PAD_USBH2_CLK__USBH2_CLK 0x0
+ MX27_PAD_USBH2_DIR__USBH2_DIR 0x0
+ MX27_PAD_USBH2_NXT__USBH2_NXT 0x0
+ MX27_PAD_USBH2_STP__USBH2_STP 0x0
+ MX27_PAD_CSPI2_SCLK__USBH2_DATA0 0x0
+ MX27_PAD_CSPI2_MOSI__USBH2_DATA1 0x0
+ MX27_PAD_CSPI2_MISO__USBH2_DATA2 0x0
+ MX27_PAD_CSPI2_SS1__USBH2_DATA3 0x0
+ MX27_PAD_CSPI2_SS2__USBH2_DATA4 0x0
+ MX27_PAD_CSPI1_SS2__USBH2_DATA5 0x0
+ MX27_PAD_CSPI2_SS0__USBH2_DATA6 0x0
+ MX27_PAD_USBH2_DATA7__USBH2_DATA7 0x0
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX27_PAD_USBOTG_CLK__USBOTG_CLK 0x0
+ MX27_PAD_USBOTG_DIR__USBOTG_DIR 0x0
+ MX27_PAD_USBOTG_NXT__USBOTG_NXT 0x0
+ MX27_PAD_USBOTG_STP__USBOTG_STP 0x0
+ MX27_PAD_USBOTG_DATA0__USBOTG_DATA0 0x0
+ MX27_PAD_USBOTG_DATA1__USBOTG_DATA1 0x0
+ MX27_PAD_USBOTG_DATA2__USBOTG_DATA2 0x0
+ MX27_PAD_USBOTG_DATA3__USBOTG_DATA3 0x0
+ MX27_PAD_USBOTG_DATA4__USBOTG_DATA4 0x0
+ MX27_PAD_USBOTG_DATA5__USBOTG_DATA5 0x0
+ MX27_PAD_USBOTG_DATA6__USBOTG_DATA6 0x0
+ MX27_PAD_USBOTG_DATA7__USBOTG_DATA7 0x0
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx27-eukrea-mbimxsd27-baseboard.dts b/arch/arm/boot/dts/imx27-eukrea-mbimxsd27-baseboard.dts
new file mode 100644
index 000000000..2ab65fc4c
--- /dev/null
+++ b/arch/arm/boot/dts/imx27-eukrea-mbimxsd27-baseboard.dts
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * 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 "imx27-eukrea-cpuimx27.dtsi"
+
+/ {
+ model = "Eukrea MBIMXSD27";
+ compatible = "eukrea,mbimxsd27-baseboard", "eukrea,cpuimx27", "fsl,imx27";
+
+ display0: CMO-QVGA {
+ model = "CMO-QVGA";
+ native-mode = <&timing0>;
+ bits-per-pixel = <16>;
+ fsl,pcr = <0xfad08b80>;
+
+ display-timings {
+ timing0: 320x240 {
+ clock-frequency = <6500000>;
+ hactive = <320>;
+ vactive = <240>;
+ hback-porch = <20>;
+ hsync-len = <30>;
+ hfront-porch = <38>;
+ vback-porch = <4>;
+ vsync-len = <3>;
+ vfront-porch = <15>;
+ };
+ };
+ };
+
+ backlight {
+ compatible = "gpio-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_backlight>;
+ gpios = <&gpio5 5 GPIO_ACTIVE_HIGH>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpioleds>;
+
+ led1 {
+ label = "system::live";
+ gpios = <&gpio6 16 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ led2 {
+ label = "system::user";
+ gpios = <&gpio6 19 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "simple-bus";
+
+ reg_lcd: regulator@0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdreg>;
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "LCD";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 25 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+};
+
+&cspi1 {
+ pinctrl-0 = <&pinctrl_cspi1>;
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ ads7846 {
+ compatible = "ti,ads7846";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_touch>;
+ reg = <0>;
+ interrupts = <&gpio4 25 IRQ_TYPE_LEVEL_LOW>;
+ spi-cpol;
+ spi-max-frequency = <1500000>;
+ ti,keep-vref-on;
+ };
+};
+
+&fb {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_imxfb>;
+ display = <&display0>;
+ lcd-supply = <&reg_lcd>;
+ fsl,dmacr = <0x00040060>;
+ fsl,lscr1 = <0x00120300>;
+ fsl,lpccr = <0x00a903ff>;
+ status = "okay";
+};
+
+&i2c1 {
+ codec: codec@1a {
+ compatible = "ti,tlv320aic23";
+ reg = <0x1a>;
+ };
+};
+
+&kpp {
+ linux,keymap = <
+ MATRIX_KEY(0, 0, KEY_UP)
+ MATRIX_KEY(0, 1, KEY_DOWN)
+ MATRIX_KEY(1, 0, KEY_RIGHT)
+ MATRIX_KEY(1, 1, KEY_LEFT)
+ >;
+ status = "okay";
+};
+
+&sdhci1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdhc1>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&ssi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssi1>;
+ codec-handle = <&codec>;
+ status = "okay";
+};
+
+&uart1 {
+ fsl,uart-has-rtscts;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ fsl,uart-has-rtscts;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart3 {
+ fsl,uart-has-rtscts;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
+
+&iomuxc {
+ imx27-eukrea-cpuimx27-baseboard {
+ pinctrl_cspi1: cspi1grp {
+ fsl,pins = <
+ MX27_PAD_CSPI1_MISO__CSPI1_MISO 0x0
+ MX27_PAD_CSPI1_MOSI__CSPI1_MOSI 0x0
+ MX27_PAD_CSPI1_SCLK__CSPI1_SCLK 0x0
+ MX27_PAD_CSPI1_SS0__GPIO4_28 0x0 /* CS0 */
+ >;
+ };
+
+ pinctrl_backlight: backlightgrp {
+ fsl,pins = <
+ MX27_PAD_PWMO__GPIO5_5 0x0
+ >;
+ };
+
+ pinctrl_gpioleds: gpioledsgrp {
+ fsl,pins = <
+ MX27_PAD_PC_PWRON__GPIO6_16 0x0
+ MX27_PAD_PC_CD2_B__GPIO6_19 0x0
+ >;
+ };
+
+ pinctrl_imxfb: imxfbgrp {
+ fsl,pins = <
+ MX27_PAD_LD0__LD0 0x0
+ MX27_PAD_LD1__LD1 0x0
+ MX27_PAD_LD2__LD2 0x0
+ MX27_PAD_LD3__LD3 0x0
+ MX27_PAD_LD4__LD4 0x0
+ MX27_PAD_LD5__LD5 0x0
+ MX27_PAD_LD6__LD6 0x0
+ MX27_PAD_LD7__LD7 0x0
+ MX27_PAD_LD8__LD8 0x0
+ MX27_PAD_LD9__LD9 0x0
+ MX27_PAD_LD10__LD10 0x0
+ MX27_PAD_LD11__LD11 0x0
+ MX27_PAD_LD12__LD12 0x0
+ MX27_PAD_LD13__LD13 0x0
+ MX27_PAD_LD14__LD14 0x0
+ MX27_PAD_LD15__LD15 0x0
+ MX27_PAD_LD16__LD16 0x0
+ MX27_PAD_LD17__LD17 0x0
+ MX27_PAD_CONTRAST__CONTRAST 0x0
+ MX27_PAD_OE_ACD__OE_ACD 0x0
+ MX27_PAD_HSYNC__HSYNC 0x0
+ MX27_PAD_VSYNC__VSYNC 0x0
+ >;
+ };
+
+ pinctrl_lcdreg: lcdreggrp {
+ fsl,pins = <
+ MX27_PAD_CLS__GPIO1_25 0x0
+ >;
+ };
+
+ pinctrl_sdhc1: sdhc1grp {
+ fsl,pins = <
+ MX27_PAD_SD1_CLK__SD1_CLK 0x0
+ MX27_PAD_SD1_CMD__SD1_CMD 0x0
+ MX27_PAD_SD1_D0__SD1_D0 0x0
+ MX27_PAD_SD1_D1__SD1_D1 0x0
+ MX27_PAD_SD1_D2__SD1_D2 0x0
+ MX27_PAD_SD1_D3__SD1_D3 0x0
+ >;
+ };
+
+ pinctrl_ssi1: ssi1grp {
+ fsl,pins = <
+ MX27_PAD_SSI4_CLK__SSI4_CLK 0x0
+ MX27_PAD_SSI4_FS__SSI4_FS 0x0
+ MX27_PAD_SSI4_RXDAT__SSI4_RXDAT 0x1
+ MX27_PAD_SSI4_TXDAT__SSI4_TXDAT 0x1
+ >;
+ };
+
+ pinctrl_touch: touchgrp {
+ fsl,pins = <
+ MX27_PAD_CSPI1_RDY__GPIO4_25 0x0 /* IRQ */
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX27_PAD_UART1_TXD__UART1_TXD 0x0
+ MX27_PAD_UART1_RXD__UART1_RXD 0x0
+ MX27_PAD_UART1_CTS__UART1_CTS 0x0
+ MX27_PAD_UART1_RTS__UART1_RTS 0x0
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX27_PAD_UART2_TXD__UART2_TXD 0x0
+ MX27_PAD_UART2_RXD__UART2_RXD 0x0
+ MX27_PAD_UART2_CTS__UART2_CTS 0x0
+ MX27_PAD_UART2_RTS__UART2_RTS 0x0
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX27_PAD_UART3_TXD__UART3_TXD 0x0
+ MX27_PAD_UART3_RXD__UART3_RXD 0x0
+ MX27_PAD_UART3_CTS__UART3_CTS 0x0
+ MX27_PAD_UART3_RTS__UART3_RTS 0x0
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx27-pdk.dts b/arch/arm/boot/dts/imx27-pdk.dts
new file mode 100644
index 000000000..49450dbbc
--- /dev/null
+++ b/arch/arm/boot/dts/imx27-pdk.dts
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2012 Sascha Hauer, Pengutronix
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx27.dtsi"
+
+/ {
+ model = "Freescale i.MX27 Product Development Kit";
+ compatible = "fsl,imx27-pdk", "fsl,imx27";
+
+ memory {
+ reg = <0xa0000000 0x08000000>;
+ };
+
+ usbphy {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usbphy0: usbphy@0 {
+ compatible = "usb-nop-xceiv";
+ reg = <0>;
+ clocks = <&clks IMX27_CLK_DUMMY>;
+ clock-names = "main_clk";
+ };
+ };
+};
+
+&cspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cspi2>;
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 21 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+
+ pmic: mc13783@0 {
+ compatible = "fsl,mc13783";
+ reg = <0>;
+ spi-cs-high;
+ spi-max-frequency = <1000000>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <14 IRQ_TYPE_LEVEL_HIGH>;
+
+ regulators {
+ vgen_reg: vgen {
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vmmc1_reg: vmmc1 {
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ gpo1_reg: gpo1 {
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ gpo3_reg: gpo3 {
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+};
+
+&fec {
+ phy-mode = "mii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ status = "okay";
+};
+
+&kpp {
+ linux,keymap = <
+ MATRIX_KEY(0, 0, KEY_UP)
+ MATRIX_KEY(0, 1, KEY_DOWN)
+ MATRIX_KEY(1, 0, KEY_RIGHT)
+ MATRIX_KEY(1, 1, KEY_LEFT)
+ MATRIX_KEY(1, 2, KEY_ENTER)
+ MATRIX_KEY(2, 0, KEY_F6)
+ MATRIX_KEY(2, 1, KEY_F8)
+ MATRIX_KEY(2, 2, KEY_F9)
+ MATRIX_KEY(2, 3, KEY_F10)
+ >;
+ status = "okay";
+};
+
+&nfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
+ nand-ecc-mode = "hw";
+ nand-on-flash-bbt;
+ status = "okay";
+};
+
+&uart1 {
+ fsl,uart-has-rtscts;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&usbotg {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ dr_mode = "otg";
+ fsl,usbphy = <&usbphy0>;
+ phy_type = "ulpi";
+ status = "okay";
+};
+
+&iomuxc {
+ imx27-pdk {
+ pinctrl_cspi2: cspi2grp {
+ fsl,pins = <
+ MX27_PAD_CSPI2_MISO__CSPI2_MISO 0x0
+ MX27_PAD_CSPI2_MOSI__CSPI2_MOSI 0x0
+ MX27_PAD_CSPI2_SCLK__CSPI2_SCLK 0x0
+ MX27_PAD_CSPI2_SS0__GPIO4_21 0x0 /* SPI2 CS0 */
+ MX27_PAD_TOUT__GPIO3_14 0x0 /* PMIC IRQ */
+ >;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX27_PAD_SD3_CMD__FEC_TXD0 0x0
+ MX27_PAD_SD3_CLK__FEC_TXD1 0x0
+ MX27_PAD_ATA_DATA0__FEC_TXD2 0x0
+ MX27_PAD_ATA_DATA1__FEC_TXD3 0x0
+ MX27_PAD_ATA_DATA2__FEC_RX_ER 0x0
+ MX27_PAD_ATA_DATA3__FEC_RXD1 0x0
+ MX27_PAD_ATA_DATA4__FEC_RXD2 0x0
+ MX27_PAD_ATA_DATA5__FEC_RXD3 0x0
+ MX27_PAD_ATA_DATA6__FEC_MDIO 0x0
+ MX27_PAD_ATA_DATA7__FEC_MDC 0x0
+ MX27_PAD_ATA_DATA8__FEC_CRS 0x0
+ MX27_PAD_ATA_DATA9__FEC_TX_CLK 0x0
+ MX27_PAD_ATA_DATA10__FEC_RXD0 0x0
+ MX27_PAD_ATA_DATA11__FEC_RX_DV 0x0
+ MX27_PAD_ATA_DATA12__FEC_RX_CLK 0x0
+ MX27_PAD_ATA_DATA13__FEC_COL 0x0
+ MX27_PAD_ATA_DATA14__FEC_TX_ER 0x0
+ MX27_PAD_ATA_DATA15__FEC_TX_EN 0x0
+ >;
+ };
+
+ pinctrl_nand: nandgrp {
+ fsl,pins = <
+ MX27_PAD_NFRB__NFRB 0x0
+ MX27_PAD_NFCLE__NFCLE 0x0
+ MX27_PAD_NFWP_B__NFWP_B 0x0
+ MX27_PAD_NFCE_B__NFCE_B 0x0
+ MX27_PAD_NFALE__NFALE 0x0
+ MX27_PAD_NFRE_B__NFRE_B 0x0
+ MX27_PAD_NFWE_B__NFWE_B 0x0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX27_PAD_UART1_TXD__UART1_TXD 0x0
+ MX27_PAD_UART1_RXD__UART1_RXD 0x0
+ MX27_PAD_UART1_CTS__UART1_CTS 0x0
+ MX27_PAD_UART1_RTS__UART1_RTS 0x0
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX27_PAD_USBOTG_NXT__USBOTG_NXT 0x0
+ MX27_PAD_USBOTG_STP__USBOTG_STP 0x0
+ MX27_PAD_USBOTG_DIR__USBOTG_DIR 0x0
+ MX27_PAD_USBOTG_CLK__USBOTG_CLK 0x0
+ MX27_PAD_USBOTG_DATA0__USBOTG_DATA0 0x0
+ MX27_PAD_USBOTG_DATA1__USBOTG_DATA1 0x0
+ MX27_PAD_USBOTG_DATA2__USBOTG_DATA2 0x0
+ MX27_PAD_USBOTG_DATA3__USBOTG_DATA3 0x0
+ MX27_PAD_USBOTG_DATA4__USBOTG_DATA4 0x0
+ MX27_PAD_USBOTG_DATA5__USBOTG_DATA5 0x0
+ MX27_PAD_USBOTG_DATA6__USBOTG_DATA6 0x0
+ MX27_PAD_USBOTG_DATA7__USBOTG_DATA7 0x0
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts b/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts
new file mode 100644
index 000000000..7c869fe3c
--- /dev/null
+++ b/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2012 Markus Pargmann, Pengutronix
+ *
+ * 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 "imx27-phytec-phycard-s-som.dtsi"
+
+/ {
+ model = "Phytec pca100 rapid development kit";
+ compatible = "phytec,imx27-pca100-rdk", "phytec,imx27-pca100", "fsl,imx27";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ display: display {
+ model = "Primeview-PD050VL1";
+ native-mode = <&timing0>;
+ bits-per-pixel = <16>; /* non-standard but required */
+ fsl,pcr = <0xf0c88080>; /* non-standard but required */
+ display-timings {
+ timing0: 640x480 {
+ hactive = <640>;
+ vactive = <480>;
+ hback-porch = <112>;
+ hfront-porch = <36>;
+ hsync-len = <32>;
+ vback-porch = <33>;
+ vfront-porch = <33>;
+ vsync-len = <2>;
+ clock-frequency = <25000000>;
+ };
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3v3: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+};
+
+&fb {
+ display = <&display>;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+
+ adc@64 {
+ compatible = "maxim,max1037";
+ vcc-supply = <&reg_3v3>;
+ reg = <0x64>;
+ };
+};
+
+&iomuxc {
+ imx27-phycard-s-rdk {
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX27_PAD_I2C2_SDA__I2C2_SDA 0x0
+ MX27_PAD_I2C2_SCL__I2C2_SCL 0x0
+ >;
+ };
+
+ pinctrl_owire1: owire1grp {
+ fsl,pins = <
+ MX27_PAD_RTCK__OWIRE 0x0
+ >;
+ };
+
+ pinctrl_sdhc2: sdhc2grp {
+ fsl,pins = <
+ MX27_PAD_SD2_CLK__SD2_CLK 0x0
+ MX27_PAD_SD2_CMD__SD2_CMD 0x0
+ MX27_PAD_SD2_D0__SD2_D0 0x0
+ MX27_PAD_SD2_D1__SD2_D1 0x0
+ MX27_PAD_SD2_D2__SD2_D2 0x0
+ MX27_PAD_SD2_D3__SD2_D3 0x0
+ MX27_PAD_SSI3_RXDAT__GPIO3_29 0x0 /* CD */
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX27_PAD_UART1_TXD__UART1_TXD 0x0
+ MX27_PAD_UART1_RXD__UART1_RXD 0x0
+ MX27_PAD_UART1_CTS__UART1_CTS 0x0
+ MX27_PAD_UART1_RTS__UART1_RTS 0x0
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX27_PAD_UART2_TXD__UART2_TXD 0x0
+ MX27_PAD_UART2_RXD__UART2_RXD 0x0
+ MX27_PAD_UART2_CTS__UART2_CTS 0x0
+ MX27_PAD_UART2_RTS__UART2_RTS 0x0
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX27_PAD_UART3_TXD__UART3_TXD 0x0
+ MX27_PAD_UART3_RXD__UART3_RXD 0x0
+ MX27_PAD_UART3_CTS__UART3_CTS 0x0
+ MX27_PAD_UART3_RTS__UART3_RTS 0x0
+ >;
+ };
+ };
+};
+
+&owire {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_owire1>;
+ status = "okay";
+};
+
+&sdhci2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdhc2>;
+ cd-gpios = <&gpio3 29 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&uart1 {
+ fsl,uart-has-rtscts;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ fsl,uart-has-rtscts;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart3 {
+ fsl,uart-has-rtscts;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi b/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi
new file mode 100644
index 000000000..1b6248079
--- /dev/null
+++ b/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2012 Sascha Hauer, Uwe Kleine-König, Steffen Trumtrar
+ * and Markus Pargmann, Pengutronix
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx27.dtsi"
+
+/ {
+ model = "Phytec pca100";
+ compatible = "phytec,imx27-pca100", "fsl,imx27";
+
+ memory {
+ reg = <0xa0000000 0x08000000>; /* 128MB */
+ };
+};
+
+&cspi1 {
+ fsl,spi-num-chipselects = <2>;
+ cs-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>,
+ <&gpio4 27 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ at24@52 {
+ compatible = "at,24c32";
+ pagesize = <32>;
+ reg = <0x52>;
+ };
+};
+
+&iomuxc {
+ imx27-phycard-s-som {
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ MX27_PAD_SD3_CMD__FEC_TXD0 0x0
+ MX27_PAD_SD3_CLK__FEC_TXD1 0x0
+ MX27_PAD_ATA_DATA0__FEC_TXD2 0x0
+ MX27_PAD_ATA_DATA1__FEC_TXD3 0x0
+ MX27_PAD_ATA_DATA2__FEC_RX_ER 0x0
+ MX27_PAD_ATA_DATA3__FEC_RXD1 0x0
+ MX27_PAD_ATA_DATA4__FEC_RXD2 0x0
+ MX27_PAD_ATA_DATA5__FEC_RXD3 0x0
+ MX27_PAD_ATA_DATA6__FEC_MDIO 0x0
+ MX27_PAD_ATA_DATA7__FEC_MDC 0x0
+ MX27_PAD_ATA_DATA8__FEC_CRS 0x0
+ MX27_PAD_ATA_DATA9__FEC_TX_CLK 0x0
+ MX27_PAD_ATA_DATA10__FEC_RXD0 0x0
+ MX27_PAD_ATA_DATA11__FEC_RX_DV 0x0
+ MX27_PAD_ATA_DATA12__FEC_RX_CLK 0x0
+ MX27_PAD_ATA_DATA13__FEC_COL 0x0
+ MX27_PAD_ATA_DATA14__FEC_TX_ER 0x0
+ MX27_PAD_ATA_DATA15__FEC_TX_EN 0x0
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX27_PAD_I2C2_SDA__I2C2_SDA 0x0
+ MX27_PAD_I2C2_SCL__I2C2_SCL 0x0
+ >;
+ };
+
+ pinctrl_nfc: nfcgrp {
+ fsl,pins = <
+ MX27_PAD_NFRB__NFRB 0x0
+ MX27_PAD_NFCLE__NFCLE 0x0
+ MX27_PAD_NFWP_B__NFWP_B 0x0
+ MX27_PAD_NFCE_B__NFCE_B 0x0
+ MX27_PAD_NFALE__NFALE 0x0
+ MX27_PAD_NFRE_B__NFRE_B 0x0
+ MX27_PAD_NFWE_B__NFWE_B 0x0
+ >;
+ };
+ };
+};
+
+&nfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nfc>;
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ nand-on-flash-bbt;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts b/arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts
new file mode 100644
index 000000000..538568b0d
--- /dev/null
+++ b/arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts
@@ -0,0 +1,324 @@
+/*
+ * 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 "imx27-phytec-phycore-som.dtsi"
+
+/ {
+ model = "Phytec pcm970";
+ compatible = "phytec,imx27-pcm970", "phytec,imx27-pcm038", "fsl,imx27";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ display0: LQ035Q7 {
+ model = "Sharp-LQ035Q7";
+ native-mode = <&timing0>;
+ bits-per-pixel = <16>;
+ fsl,pcr = <0xf00080c0>;
+
+ display-timings {
+ timing0: 240x320 {
+ clock-frequency = <5500000>;
+ hactive = <240>;
+ vactive = <320>;
+ hback-porch = <5>;
+ hsync-len = <7>;
+ hfront-porch = <16>;
+ vback-porch = <7>;
+ vsync-len = <1>;
+ vfront-porch = <9>;
+ pixelclk-active = <1>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ de-active = <0>;
+ };
+ };
+ };
+
+ regulators {
+ regulator@2 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csien>;
+ reg = <2>;
+ regulator-name = "CSI_EN";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 24 GPIO_ACTIVE_LOW>;
+ regulator-always-on;
+ };
+ };
+
+ usbphy {
+ usbphy2: usbphy@2 {
+ compatible = "usb-nop-xceiv";
+ reg = <2>;
+ vcc-supply = <&reg_5v0>;
+ clocks = <&clks IMX27_CLK_DUMMY>;
+ clock-names = "main_clk";
+ };
+ };
+};
+
+&cspi1 {
+ pinctrl-0 = <&pinctrl_cspi1>, <&pinctrl_cspi1cs1>;
+ fsl,spi-num-chipselects = <2>;
+ cs-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>,
+ <&gpio4 27 GPIO_ACTIVE_LOW>;
+};
+
+&fb {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_imxfb1>;
+ display = <&display0>;
+ lcd-supply = <&reg_5v0>;
+ fsl,dmacr = <0x00020010>;
+ fsl,lscr1 = <0x00120300>;
+ fsl,lpccr = <0x00a903ff>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ camgpio: pca9536@41 {
+ compatible = "nxp,pca9536";
+ reg = <0x41>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&iomuxc {
+ imx27_phycore_rdk {
+ pinctrl_csien: csiengrp {
+ fsl,pins = <
+ MX27_PAD_USB_OC_B__GPIO2_24 0x0
+ >;
+ };
+
+ pinctrl_cspi1cs1: cspi1cs1grp {
+ fsl,pins = <
+ MX27_PAD_CSPI1_SS1__GPIO4_27 0x0
+ >;
+ };
+
+ pinctrl_imxfb1: imxfbgrp {
+ fsl,pins = <
+ MX27_PAD_LD0__LD0 0x0
+ MX27_PAD_LD1__LD1 0x0
+ MX27_PAD_LD2__LD2 0x0
+ MX27_PAD_LD3__LD3 0x0
+ MX27_PAD_LD4__LD4 0x0
+ MX27_PAD_LD5__LD5 0x0
+ MX27_PAD_LD6__LD6 0x0
+ MX27_PAD_LD7__LD7 0x0
+ MX27_PAD_LD8__LD8 0x0
+ MX27_PAD_LD9__LD9 0x0
+ MX27_PAD_LD10__LD10 0x0
+ MX27_PAD_LD11__LD11 0x0
+ MX27_PAD_LD12__LD12 0x0
+ MX27_PAD_LD13__LD13 0x0
+ MX27_PAD_LD14__LD14 0x0
+ MX27_PAD_LD15__LD15 0x0
+ MX27_PAD_LD16__LD16 0x0
+ MX27_PAD_LD17__LD17 0x0
+ MX27_PAD_CLS__CLS 0x0
+ MX27_PAD_CONTRAST__CONTRAST 0x0
+ MX27_PAD_LSCLK__LSCLK 0x0
+ MX27_PAD_OE_ACD__OE_ACD 0x0
+ MX27_PAD_PS__PS 0x0
+ MX27_PAD_REV__REV 0x0
+ MX27_PAD_SPL_SPR__SPL_SPR 0x0
+ MX27_PAD_HSYNC__HSYNC 0x0
+ MX27_PAD_VSYNC__VSYNC 0x0
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ /* Add pullup to DATA line */
+ fsl,pins = <
+ MX27_PAD_I2C_DATA__I2C_DATA 0x1
+ MX27_PAD_I2C_CLK__I2C_CLK 0x0
+ >;
+ };
+
+ pinctrl_owire1: owire1grp {
+ fsl,pins = <
+ MX27_PAD_RTCK__OWIRE 0x0
+ >;
+ };
+
+ pinctrl_sdhc2: sdhc2grp {
+ fsl,pins = <
+ MX27_PAD_SD2_CLK__SD2_CLK 0x0
+ MX27_PAD_SD2_CMD__SD2_CMD 0x0
+ MX27_PAD_SD2_D0__SD2_D0 0x0
+ MX27_PAD_SD2_D1__SD2_D1 0x0
+ MX27_PAD_SD2_D2__SD2_D2 0x0
+ MX27_PAD_SD2_D3__SD2_D3 0x0
+ MX27_PAD_SSI3_FS__GPIO3_28 0x0 /* WP */
+ MX27_PAD_SSI3_RXDAT__GPIO3_29 0x0 /* CD */
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX27_PAD_UART1_TXD__UART1_TXD 0x0
+ MX27_PAD_UART1_RXD__UART1_RXD 0x0
+ MX27_PAD_UART1_CTS__UART1_CTS 0x0
+ MX27_PAD_UART1_RTS__UART1_RTS 0x0
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX27_PAD_UART2_TXD__UART2_TXD 0x0
+ MX27_PAD_UART2_RXD__UART2_RXD 0x0
+ MX27_PAD_UART2_CTS__UART2_CTS 0x0
+ MX27_PAD_UART2_RTS__UART2_RTS 0x0
+ >;
+ };
+
+ pinctrl_usbh2: usbh2grp {
+ fsl,pins = <
+ MX27_PAD_USBH2_CLK__USBH2_CLK 0x0
+ MX27_PAD_USBH2_DIR__USBH2_DIR 0x0
+ MX27_PAD_USBH2_NXT__USBH2_NXT 0x0
+ MX27_PAD_USBH2_STP__USBH2_STP 0x0
+ MX27_PAD_CSPI2_SCLK__USBH2_DATA0 0x0
+ MX27_PAD_CSPI2_MOSI__USBH2_DATA1 0x0
+ MX27_PAD_CSPI2_MISO__USBH2_DATA2 0x0
+ MX27_PAD_CSPI2_SS1__USBH2_DATA3 0x0
+ MX27_PAD_CSPI2_SS2__USBH2_DATA4 0x0
+ MX27_PAD_CSPI1_SS2__USBH2_DATA5 0x0
+ MX27_PAD_CSPI2_SS0__USBH2_DATA6 0x0
+ MX27_PAD_USBH2_DATA7__USBH2_DATA7 0x0
+ >;
+ };
+
+ pinctrl_weim: weimgrp {
+ fsl,pins = <
+ MX27_PAD_CS4_B__CS4_B 0x0 /* CS4 */
+ MX27_PAD_SD1_D1__GPIO5_19 0x0 /* CAN IRQ */
+ >;
+ };
+ };
+};
+
+&owire {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_owire1>;
+ status = "okay";
+};
+
+&pmicleds {
+ ledr1: led@3 {
+ reg = <3>;
+ label = "system:red1:user";
+ };
+
+ ledg1: led@4 {
+ reg = <4>;
+ label = "system:green1:user";
+ };
+
+ ledb1: led@5 {
+ reg = <5>;
+ label = "system:blue1:user";
+ };
+
+ ledr2: led@6 {
+ reg = <6>;
+ label = "system:red2:user";
+ };
+
+ ledg2: led@7 {
+ reg = <7>;
+ label = "system:green2:user";
+ };
+
+ ledb2: led@8 {
+ reg = <8>;
+ label = "system:blue2:user";
+ };
+
+ ledr3: led@9 {
+ reg = <9>;
+ label = "system:red3:nand";
+ linux,default-trigger = "nand-disk";
+ };
+
+ ledg3: led@10 {
+ reg = <10>;
+ label = "system:green3:live";
+ linux,default-trigger = "heartbeat";
+ };
+
+ ledb3: led@11 {
+ reg = <11>;
+ label = "system:blue3:cpu";
+ linux,default-trigger = "cpu0";
+ };
+};
+
+&sdhci2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdhc2>;
+ bus-width = <4>;
+ cd-gpios = <&gpio3 29 GPIO_ACTIVE_HIGH>;
+ wp-gpios = <&gpio3 28 GPIO_ACTIVE_HIGH>;
+ vmmc-supply = <&vmmc1_reg>;
+ status = "okay";
+};
+
+&uart1 {
+ fsl,uart-has-rtscts;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ fsl,uart-has-rtscts;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&usbh2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh2>;
+ dr_mode = "host";
+ phy_type = "ulpi";
+ vbus-supply = <&reg_5v0>;
+ fsl,usbphy = <&usbphy2>;
+ disable-over-current;
+ status = "okay";
+};
+
+&weim {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_weim>;
+
+ can@4,0 {
+ compatible = "nxp,sja1000";
+ reg = <4 0x00000000 0x00000100>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
+ nxp,external-clock-frequency = <16000000>;
+ nxp,tx-output-config = <0x16>;
+ nxp,no-comparator-bypass;
+ fsl,weim-cs-timing = <0x0000dcf6 0x444a0301 0x44443302>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi b/arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi
new file mode 100644
index 000000000..b4e955e3b
--- /dev/null
+++ b/arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2012 Sascha Hauer, Pengutronix
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx27.dtsi"
+
+/ {
+ model = "Phytec pcm038";
+ compatible = "phytec,imx27-pcm038", "fsl,imx27";
+
+ memory {
+ reg = <0xa0000000 0x08000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3v3: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_5v0: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "5V0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+ };
+
+ usbphy {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usbphy0: usbphy@0 {
+ compatible = "usb-nop-xceiv";
+ reg = <0>;
+ vcc-supply = <&sw3_reg>;
+ clocks = <&clks IMX27_CLK_DUMMY>;
+ clock-names = "main_clk";
+ };
+ };
+};
+
+&audmux {
+ status = "okay";
+
+ /* SSI0 <=> PINS_4 (MC13783 Audio) */
+ ssi0 {
+ fsl,audmux-port = <0>;
+ fsl,port-config = <0xcb205000>;
+ };
+
+ pins4 {
+ fsl,audmux-port = <2>;
+ fsl,port-config = <0x00001000>;
+ };
+};
+
+&cspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cspi1>;
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+
+ pmic: mc13783@0 {
+ compatible = "fsl,mc13783";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pmic>;
+ reg = <0>;
+ spi-cs-high;
+ spi-max-frequency = <20000000>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <23 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,mc13xxx-uses-adc;
+ fsl,mc13xxx-uses-rtc;
+
+ pmicleds: leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ led-control = <0x001 0x000 0x000 0x000 0x000 0x000>;
+ };
+
+ regulators {
+ /* SW1A and SW1B joined operation */
+ sw1_reg: sw1a {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1520000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ /* SW2A and SW2B joined operation */
+ sw2_reg: sw2a {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ sw3_reg: sw3 {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vaudio_reg: vaudio {
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ violo_reg: violo {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ viohi_reg: viohi {
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vgen_reg: vgen {
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcam_reg: vcam {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ vrf1_reg: vrf1 {
+ regulator-min-microvolt = <2775000>;
+ regulator-max-microvolt = <2775000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vrf2_reg: vrf2 {
+ regulator-min-microvolt = <2775000>;
+ regulator-max-microvolt = <2775000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vmmc1_reg: vmmc1 {
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ gpo1_reg: gpo1 { };
+
+ pwgt1spi_reg: pwgt1spi {
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&fec {
+ phy-mode = "mii";
+ phy-reset-gpios = <&gpio3 30 GPIO_ACTIVE_LOW>;
+ phy-supply = <&reg_3v3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ at24@52 {
+ compatible = "at,24c32";
+ pagesize = <32>;
+ reg = <0x52>;
+ };
+
+ pcf8563@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+
+ lm75@4a {
+ compatible = "national,lm75";
+ reg = <0x4a>;
+ };
+};
+
+&iomuxc {
+ imx27_phycore_som {
+ pinctrl_cspi1: cspi1grp {
+ fsl,pins = <
+ MX27_PAD_CSPI1_MISO__CSPI1_MISO 0x0
+ MX27_PAD_CSPI1_MOSI__CSPI1_MOSI 0x0
+ MX27_PAD_CSPI1_SCLK__CSPI1_SCLK 0x0
+ MX27_PAD_CSPI1_SS0__GPIO4_28 0x0 /* SPI1 CS0 */
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ MX27_PAD_SD3_CMD__FEC_TXD0 0x0
+ MX27_PAD_SD3_CLK__FEC_TXD1 0x0
+ MX27_PAD_ATA_DATA0__FEC_TXD2 0x0
+ MX27_PAD_ATA_DATA1__FEC_TXD3 0x0
+ MX27_PAD_ATA_DATA2__FEC_RX_ER 0x0
+ MX27_PAD_ATA_DATA3__FEC_RXD1 0x0
+ MX27_PAD_ATA_DATA4__FEC_RXD2 0x0
+ MX27_PAD_ATA_DATA5__FEC_RXD3 0x0
+ MX27_PAD_ATA_DATA6__FEC_MDIO 0x0
+ MX27_PAD_ATA_DATA7__FEC_MDC 0x0
+ MX27_PAD_ATA_DATA8__FEC_CRS 0x0
+ MX27_PAD_ATA_DATA9__FEC_TX_CLK 0x0
+ MX27_PAD_ATA_DATA10__FEC_RXD0 0x0
+ MX27_PAD_ATA_DATA11__FEC_RX_DV 0x0
+ MX27_PAD_ATA_DATA12__FEC_RX_CLK 0x0
+ MX27_PAD_ATA_DATA13__FEC_COL 0x0
+ MX27_PAD_ATA_DATA14__FEC_TX_ER 0x0
+ MX27_PAD_ATA_DATA15__FEC_TX_EN 0x0
+ MX27_PAD_SSI3_TXDAT__GPIO3_30 0x0 /* FEC RST */
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX27_PAD_I2C2_SDA__I2C2_SDA 0x0
+ MX27_PAD_I2C2_SCL__I2C2_SCL 0x0
+ >;
+ };
+
+ pinctrl_nfc: nfcgrp {
+ fsl,pins = <
+ MX27_PAD_NFRB__NFRB 0x0
+ MX27_PAD_NFCLE__NFCLE 0x0
+ MX27_PAD_NFWP_B__NFWP_B 0x0
+ MX27_PAD_NFCE_B__NFCE_B 0x0
+ MX27_PAD_NFALE__NFALE 0x0
+ MX27_PAD_NFRE_B__NFRE_B 0x0
+ MX27_PAD_NFWE_B__NFWE_B 0x0
+ >;
+ };
+
+ pinctrl_pmic: pmicgrp {
+ fsl,pins = <
+ MX27_PAD_USB_PWR__GPIO2_23 0x0 /* PMIC IRQ */
+ >;
+ };
+
+ pinctrl_ssi1: ssi1grp {
+ fsl,pins = <
+ MX27_PAD_SSI1_FS__SSI1_FS 0x0
+ MX27_PAD_SSI1_RXDAT__SSI1_RXDAT 0x0
+ MX27_PAD_SSI1_TXDAT__SSI1_TXDAT 0x0
+ MX27_PAD_SSI1_CLK__SSI1_CLK 0x0
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX27_PAD_USBOTG_CLK__USBOTG_CLK 0x0
+ MX27_PAD_USBOTG_DIR__USBOTG_DIR 0x0
+ MX27_PAD_USBOTG_NXT__USBOTG_NXT 0x0
+ MX27_PAD_USBOTG_STP__USBOTG_STP 0x0
+ MX27_PAD_USBOTG_DATA0__USBOTG_DATA0 0x0
+ MX27_PAD_USBOTG_DATA1__USBOTG_DATA1 0x0
+ MX27_PAD_USBOTG_DATA2__USBOTG_DATA2 0x0
+ MX27_PAD_USBOTG_DATA3__USBOTG_DATA3 0x0
+ MX27_PAD_USBOTG_DATA4__USBOTG_DATA4 0x0
+ MX27_PAD_USBOTG_DATA5__USBOTG_DATA5 0x0
+ MX27_PAD_USBOTG_DATA6__USBOTG_DATA6 0x0
+ MX27_PAD_USBOTG_DATA7__USBOTG_DATA7 0x0
+ >;
+ };
+ };
+};
+
+&nfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nfc>;
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ nand-on-flash-bbt;
+ status = "okay";
+};
+
+&ssi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssi1>;
+ status = "okay";
+};
+
+&usbotg {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ dr_mode = "otg";
+ phy_type = "ulpi";
+ fsl,usbphy = <&usbphy0>;
+ vbus-supply = <&sw3_reg>;
+ disable-over-current;
+ status = "okay";
+};
+
+&weim {
+ status = "okay";
+
+ nor: nor@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0x00000000 0x02000000>;
+ bank-width = <2>;
+ linux,mtd-name = "physmap-flash.0";
+ fsl,weim-cs-timing = <0x22c2cf00 0x75000d01 0x00000900>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ sram: sram@1,0 {
+ compatible = "mtd-ram";
+ reg = <1 0x00000000 0x00800000>;
+ bank-width = <2>;
+ linux,mtd-name = "mtd-ram.0";
+ fsl,weim-cs-timing = <0x0000d843 0x22252521 0x22220a00>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx27-pinfunc.h b/arch/arm/boot/dts/imx27-pinfunc.h
new file mode 100644
index 000000000..597bb5f74
--- /dev/null
+++ b/arch/arm/boot/dts/imx27-pinfunc.h
@@ -0,0 +1,480 @@
+/*
+ * Copyright 2013 Markus Pargmann <mpa@pengutronix.de>, Pengutronix
+ *
+ * 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 __DTS_IMX27_PINFUNC_H
+#define __DTS_IMX27_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <pin mux_id>
+ * mux_id consists of
+ * function + (direction << 2) + (gpio_oconf << 4) + (gpio_iconfa << 8) + (gpio_iconfb << 10)
+ *
+ * function: 0 - Primary function
+ * 1 - Alternate function
+ * 2 - GPIO
+ * direction: 0 - Input
+ * 1 - Output
+ * gpio_oconf: 0 - A_IN
+ * 1 - B_IN
+ * 2 - C_IN
+ * 3 - Data Register
+ * gpio_iconfa/b: 0 - GPIO_IN
+ * 1 - Interrupt Status Register
+ * 2 - 0
+ * 3 - 1
+ *
+ * 'pin' is an integer between 0 and 0xbf. imx27 has 6 ports with 32 configurable
+ * configurable pins each. 'pin' is PORT * 32 + PORT_PIN, PORT_PIN is the pin
+ * number on the specific port (between 0 and 31).
+ */
+
+#define MX27_PAD_USBH2_CLK__USBH2_CLK 0x00 0x000
+#define MX27_PAD_USBH2_CLK__GPIO1_0 0x00 0x032
+#define MX27_PAD_USBH2_DIR__USBH2_DIR 0x01 0x000
+#define MX27_PAD_USBH2_DIR__GPIO1_1 0x01 0x032
+#define MX27_PAD_USBH2_DATA7__USBH2_DATA7 0x02 0x004
+#define MX27_PAD_USBH2_DATA7__GPIO1_2 0x02 0x032
+#define MX27_PAD_USBH2_NXT__USBH2_NXT 0x03 0x000
+#define MX27_PAD_USBH2_NXT__GPIO1_3 0x03 0x032
+#define MX27_PAD_USBH2_STP__USBH2_STP 0x04 0x004
+#define MX27_PAD_USBH2_STP__GPIO1_4 0x04 0x032
+#define MX27_PAD_LSCLK__LSCLK 0x05 0x004
+#define MX27_PAD_LSCLK__GPIO1_5 0x05 0x032
+#define MX27_PAD_LD0__LD0 0x06 0x004
+#define MX27_PAD_LD0__GPIO1_6 0x06 0x032
+#define MX27_PAD_LD1__LD1 0x07 0x004
+#define MX27_PAD_LD1__GPIO1_7 0x07 0x032
+#define MX27_PAD_LD2__LD2 0x08 0x004
+#define MX27_PAD_LD2__GPIO1_8 0x08 0x032
+#define MX27_PAD_LD3__LD3 0x09 0x004
+#define MX27_PAD_LD3__GPIO1_9 0x09 0x032
+#define MX27_PAD_LD4__LD4 0x0a 0x004
+#define MX27_PAD_LD4__GPIO1_10 0x0a 0x032
+#define MX27_PAD_LD5__LD5 0x0b 0x004
+#define MX27_PAD_LD5__GPIO1_11 0x0b 0x032
+#define MX27_PAD_LD6__LD6 0x0c 0x004
+#define MX27_PAD_LD6__GPIO1_12 0x0c 0x032
+#define MX27_PAD_LD7__LD7 0x0d 0x004
+#define MX27_PAD_LD7__GPIO1_13 0x0d 0x032
+#define MX27_PAD_LD8__LD8 0x0e 0x004
+#define MX27_PAD_LD8__GPIO1_14 0x0e 0x032
+#define MX27_PAD_LD9__LD9 0x0f 0x004
+#define MX27_PAD_LD9__GPIO1_15 0x0f 0x032
+#define MX27_PAD_LD10__LD10 0x10 0x004
+#define MX27_PAD_LD10__GPIO1_16 0x10 0x032
+#define MX27_PAD_LD11__LD11 0x11 0x004
+#define MX27_PAD_LD11__GPIO1_17 0x11 0x032
+#define MX27_PAD_LD12__LD12 0x12 0x004
+#define MX27_PAD_LD12__GPIO1_18 0x12 0x032
+#define MX27_PAD_LD13__LD13 0x13 0x004
+#define MX27_PAD_LD13__GPIO1_19 0x13 0x032
+#define MX27_PAD_LD14__LD14 0x14 0x004
+#define MX27_PAD_LD14__GPIO1_20 0x14 0x032
+#define MX27_PAD_LD15__LD15 0x15 0x004
+#define MX27_PAD_LD15__GPIO1_21 0x15 0x032
+#define MX27_PAD_LD16__LD16 0x16 0x004
+#define MX27_PAD_LD16__GPIO1_22 0x16 0x032
+#define MX27_PAD_LD17__LD17 0x17 0x004
+#define MX27_PAD_LD17__GPIO1_23 0x17 0x032
+#define MX27_PAD_REV__REV 0x18 0x004
+#define MX27_PAD_REV__GPIO1_24 0x18 0x032
+#define MX27_PAD_CLS__CLS 0x19 0x004
+#define MX27_PAD_CLS__GPIO1_25 0x19 0x032
+#define MX27_PAD_PS__PS 0x1a 0x004
+#define MX27_PAD_PS__GPIO1_26 0x1a 0x032
+#define MX27_PAD_SPL_SPR__SPL_SPR 0x1b 0x004
+#define MX27_PAD_SPL_SPR__GPIO1_27 0x1b 0x032
+#define MX27_PAD_HSYNC__HSYNC 0x1c 0x004
+#define MX27_PAD_HSYNC__GPIO1_28 0x1c 0x032
+#define MX27_PAD_VSYNC__VSYNC 0x1d 0x004
+#define MX27_PAD_VSYNC__GPIO1_29 0x1d 0x032
+#define MX27_PAD_CONTRAST__CONTRAST 0x1e 0x004
+#define MX27_PAD_CONTRAST__GPIO1_30 0x1e 0x032
+#define MX27_PAD_OE_ACD__OE_ACD 0x1f 0x004
+#define MX27_PAD_OE_ACD__GPIO1_31 0x1f 0x032
+#define MX27_PAD_SD2_D0__SD2_D0 0x24 0x004
+#define MX27_PAD_SD2_D0__MSHC_DATA0 0x24 0x005
+#define MX27_PAD_SD2_D0__GPIO2_4 0x24 0x032
+#define MX27_PAD_SD2_D1__SD2_D1 0x25 0x004
+#define MX27_PAD_SD2_D1__MSHC_DATA1 0x25 0x005
+#define MX27_PAD_SD2_D1__GPIO2_5 0x25 0x032
+#define MX27_PAD_SD2_D2__SD2_D2 0x26 0x004
+#define MX27_PAD_SD2_D2__MSHC_DATA2 0x26 0x005
+#define MX27_PAD_SD2_D2__GPIO2_6 0x26 0x032
+#define MX27_PAD_SD2_D3__SD2_D3 0x27 0x004
+#define MX27_PAD_SD2_D3__MSHC_DATA3 0x27 0x005
+#define MX27_PAD_SD2_D3__GPIO2_7 0x27 0x032
+#define MX27_PAD_SD2_CMD__SD2_CMD 0x28 0x004
+#define MX27_PAD_SD2_CMD__MSHC_BS 0x28 0x005
+#define MX27_PAD_SD2_CMD__GPIO2_8 0x28 0x032
+#define MX27_PAD_SD2_CLK__SD2_CLK 0x29 0x004
+#define MX27_PAD_SD2_CLK__MSHC_SCLK 0x29 0x005
+#define MX27_PAD_SD2_CLK__GPIO2_9 0x29 0x032
+#define MX27_PAD_CSI_D0__CSI_D0 0x2a 0x000
+#define MX27_PAD_CSI_D0__UART6_TXD 0x2a 0x005
+#define MX27_PAD_CSI_D0__GPIO2_10 0x2a 0x032
+#define MX27_PAD_CSI_D1__CSI_D1 0x2b 0x000
+#define MX27_PAD_CSI_D1__UART6_RXD 0x2b 0x001
+#define MX27_PAD_CSI_D1__GPIO2_11 0x2b 0x032
+#define MX27_PAD_CSI_D2__CSI_D2 0x2c 0x000
+#define MX27_PAD_CSI_D2__UART6_CTS 0x2c 0x005
+#define MX27_PAD_CSI_D2__GPIO2_12 0x2c 0x032
+#define MX27_PAD_CSI_D3__CSI_D3 0x2d 0x000
+#define MX27_PAD_CSI_D3__UART6_RTS 0x2d 0x001
+#define MX27_PAD_CSI_D3__GPIO2_13 0x2d 0x032
+#define MX27_PAD_CSI_D4__CSI_D4 0x2e 0x000
+#define MX27_PAD_CSI_D4__GPIO2_14 0x2e 0x032
+#define MX27_PAD_CSI_MCLK__CSI_MCLK 0x2f 0x004
+#define MX27_PAD_CSI_MCLK__GPIO2_15 0x2f 0x032
+#define MX27_PAD_CSI_PIXCLK__CSI_PIXCLK 0x30 0x000
+#define MX27_PAD_CSI_PIXCLK__GPIO2_16 0x30 0x032
+#define MX27_PAD_CSI_D5__CSI_D5 0x31 0x000
+#define MX27_PAD_CSI_D5__GPIO2_17 0x31 0x032
+#define MX27_PAD_CSI_D6__CSI_D6 0x32 0x000
+#define MX27_PAD_CSI_D6__UART5_TXD 0x32 0x005
+#define MX27_PAD_CSI_D6__GPIO2_18 0x32 0x032
+#define MX27_PAD_CSI_D7__CSI_D7 0x33 0x000
+#define MX27_PAD_CSI_D7__UART5_RXD 0x33 0x001
+#define MX27_PAD_CSI_D7__GPIO2_19 0x33 0x032
+#define MX27_PAD_CSI_VSYNC__CSI_VSYNC 0x34 0x000
+#define MX27_PAD_CSI_VSYNC__UART5_CTS 0x34 0x005
+#define MX27_PAD_CSI_VSYNC__GPIO2_20 0x34 0x032
+#define MX27_PAD_CSI_HSYNC__CSI_HSYNC 0x35 0x000
+#define MX27_PAD_CSI_HSYNC__UART5_RTS 0x35 0x001
+#define MX27_PAD_CSI_HSYNC__GPIO2_21 0x35 0x032
+#define MX27_PAD_USBH1_SUSP__USBH1_SUSP 0x36 0x004
+#define MX27_PAD_USBH1_SUSP__GPIO2_22 0x36 0x032
+#define MX27_PAD_USB_PWR__USB_PWR 0x37 0x004
+#define MX27_PAD_USB_PWR__GPIO2_23 0x37 0x032
+#define MX27_PAD_USB_OC_B__USB_OC_B 0x38 0x000
+#define MX27_PAD_USB_OC_B__GPIO2_24 0x38 0x032
+#define MX27_PAD_USBH1_RCV__USBH1_RCV 0x39 0x004
+#define MX27_PAD_USBH1_RCV__GPIO2_25 0x39 0x032
+#define MX27_PAD_USBH1_FS__USBH1_FS 0x3a 0x004
+#define MX27_PAD_USBH1_FS__UART4_RTS 0x3a 0x001
+#define MX27_PAD_USBH1_FS__GPIO2_26 0x3a 0x032
+#define MX27_PAD_USBH1_OE_B__USBH1_OE_B 0x3b 0x004
+#define MX27_PAD_USBH1_OE_B__GPIO2_27 0x3b 0x032
+#define MX27_PAD_USBH1_TXDM__USBH1_TXDM 0x3c 0x004
+#define MX27_PAD_USBH1_TXDM__UART4_TXD 0x3c 0x005
+#define MX27_PAD_USBH1_TXDM__GPIO2_28 0x3c 0x032
+#define MX27_PAD_USBH1_TXDP__USBH1_TXDP 0x3d 0x004
+#define MX27_PAD_USBH1_TXDP__UART4_CTS 0x3d 0x005
+#define MX27_PAD_USBH1_TXDP__GPIO2_29 0x3d 0x032
+#define MX27_PAD_USBH1_RXDM__USBH1_RXDM 0x3e 0x004
+#define MX27_PAD_USBH1_RXDM__GPIO2_30 0x3e 0x032
+#define MX27_PAD_USBH1_RXDP__USBH1_RXDP 0x3f 0x004
+#define MX27_PAD_USBH1_RXDP__UART4_RXD 0x3f 0x001
+#define MX27_PAD_USBH1_RXDP__GPIO2_31 0x3f 0x032
+#define MX27_PAD_I2C2_SDA__I2C2_SDA 0x45 0x004
+#define MX27_PAD_I2C2_SDA__GPIO3_5 0x45 0x032
+#define MX27_PAD_I2C2_SCL__I2C2_SCL 0x46 0x004
+#define MX27_PAD_I2C2_SCL__GPIO3_6 0x46 0x032
+#define MX27_PAD_USBOTG_DATA5__USBOTG_DATA5 0x47 0x004
+#define MX27_PAD_USBOTG_DATA5__GPIO3_7 0x47 0x032
+#define MX27_PAD_USBOTG_DATA6__USBOTG_DATA6 0x48 0x004
+#define MX27_PAD_USBOTG_DATA6__GPIO3_8 0x48 0x032
+#define MX27_PAD_USBOTG_DATA0__USBOTG_DATA0 0x49 0x004
+#define MX27_PAD_USBOTG_DATA0__GPIO3_9 0x49 0x032
+#define MX27_PAD_USBOTG_DATA2__USBOTG_DATA2 0x4a 0x004
+#define MX27_PAD_USBOTG_DATA2__GPIO3_10 0x4a 0x032
+#define MX27_PAD_USBOTG_DATA1__USBOTG_DATA1 0x4b 0x004
+#define MX27_PAD_USBOTG_DATA1__GPIO3_11 0x4b 0x032
+#define MX27_PAD_USBOTG_DATA4__USBOTG_DATA4 0x4c 0x004
+#define MX27_PAD_USBOTG_DATA4__GPIO3_12 0x4c 0x032
+#define MX27_PAD_USBOTG_DATA3__USBOTG_DATA3 0x4d 0x004
+#define MX27_PAD_USBOTG_DATA3__GPIO3_13 0x4d 0x032
+#define MX27_PAD_TOUT__TOUT 0x4e 0x004
+#define MX27_PAD_TOUT__GPIO3_14 0x4e 0x032
+#define MX27_PAD_TIN__TIN 0x4f 0x000
+#define MX27_PAD_TIN__GPIO3_15 0x4f 0x032
+#define MX27_PAD_SSI4_FS__SSI4_FS 0x50 0x004
+#define MX27_PAD_SSI4_FS__GPIO3_16 0x50 0x032
+#define MX27_PAD_SSI4_RXDAT__SSI4_RXDAT 0x51 0x004
+#define MX27_PAD_SSI4_RXDAT__GPIO3_17 0x51 0x032
+#define MX27_PAD_SSI4_TXDAT__SSI4_TXDAT 0x52 0x004
+#define MX27_PAD_SSI4_TXDAT__GPIO3_18 0x52 0x032
+#define MX27_PAD_SSI4_CLK__SSI4_CLK 0x53 0x004
+#define MX27_PAD_SSI4_CLK__GPIO3_19 0x53 0x032
+#define MX27_PAD_SSI1_FS__SSI1_FS 0x54 0x004
+#define MX27_PAD_SSI1_FS__GPIO3_20 0x54 0x032
+#define MX27_PAD_SSI1_RXDAT__SSI1_RXDAT 0x55 0x004
+#define MX27_PAD_SSI1_RXDAT__GPIO3_21 0x55 0x032
+#define MX27_PAD_SSI1_TXDAT__SSI1_TXDAT 0x56 0x004
+#define MX27_PAD_SSI1_TXDAT__GPIO3_22 0x56 0x032
+#define MX27_PAD_SSI1_CLK__SSI1_CLK 0x57 0x004
+#define MX27_PAD_SSI1_CLK__GPIO3_23 0x57 0x032
+#define MX27_PAD_SSI2_FS__SSI2_FS 0x58 0x004
+#define MX27_PAD_SSI2_FS__GPT5_TOUT 0x58 0x005
+#define MX27_PAD_SSI2_FS__GPIO3_24 0x58 0x032
+#define MX27_PAD_SSI2_RXDAT__SSI2_RXDAT 0x59 0x004
+#define MX27_PAD_SSI2_RXDAT__GPTS_TIN 0x59 0x001
+#define MX27_PAD_SSI2_RXDAT__GPIO3_25 0x59 0x032
+#define MX27_PAD_SSI2_TXDAT__SSI2_TXDAT 0x5a 0x004
+#define MX27_PAD_SSI2_TXDAT__GPT4_TOUT 0x5a 0x005
+#define MX27_PAD_SSI2_TXDAT__GPIO3_26 0x5a 0x032
+#define MX27_PAD_SSI2_CLK__SSI2_CLK 0x5b 0x004
+#define MX27_PAD_SSI2_CLK__GPT4_TIN 0x5b 0x001
+#define MX27_PAD_SSI2_CLK__GPIO3_27 0x5b 0x032
+#define MX27_PAD_SSI3_FS__SSI3_FS 0x5c 0x004
+#define MX27_PAD_SSI3_FS__SLCDC2_D0 0x5c 0x001
+#define MX27_PAD_SSI3_FS__GPIO3_28 0x5c 0x032
+#define MX27_PAD_SSI3_RXDAT__SSI3_RXDAT 0x5d 0x004
+#define MX27_PAD_SSI3_RXDAT__SLCDC2_RS 0x5d 0x001
+#define MX27_PAD_SSI3_RXDAT__GPIO3_29 0x5d 0x032
+#define MX27_PAD_SSI3_TXDAT__SSI3_TXDAT 0x5e 0x004
+#define MX27_PAD_SSI3_TXDAT__SLCDC2_CS 0x5e 0x001
+#define MX27_PAD_SSI3_TXDAT__GPIO3_30 0x5e 0x032
+#define MX27_PAD_SSI3_CLK__SSI3_CLK 0x5f 0x004
+#define MX27_PAD_SSI3_CLK__SLCDC2_CLK 0x5f 0x001
+#define MX27_PAD_SSI3_CLK__GPIO3_31 0x5f 0x032
+#define MX27_PAD_SD3_CMD__SD3_CMD 0x60 0x004
+#define MX27_PAD_SD3_CMD__FEC_TXD0 0x60 0x006
+#define MX27_PAD_SD3_CMD__GPIO4_0 0x60 0x032
+#define MX27_PAD_SD3_CLK__SD3_CLK 0x61 0x004
+#define MX27_PAD_SD3_CLK__ETMTRACEPKT15 0x61 0x005
+#define MX27_PAD_SD3_CLK__FEC_TXD1 0x61 0x006
+#define MX27_PAD_SD3_CLK__GPIO4_1 0x61 0x032
+#define MX27_PAD_ATA_DATA0__ATA_DATA0 0x62 0x004
+#define MX27_PAD_ATA_DATA0__SD3_D0 0x62 0x005
+#define MX27_PAD_ATA_DATA0__FEC_TXD2 0x62 0x006
+#define MX27_PAD_ATA_DATA0__GPIO4_2 0x62 0x032
+#define MX27_PAD_ATA_DATA1__ATA_DATA1 0x63 0x004
+#define MX27_PAD_ATA_DATA1__SD3_D1 0x63 0x005
+#define MX27_PAD_ATA_DATA1__FEC_TXD3 0x63 0x006
+#define MX27_PAD_ATA_DATA1__GPIO4_3 0x63 0x032
+#define MX27_PAD_ATA_DATA2__ATA_DATA2 0x64 0x004
+#define MX27_PAD_ATA_DATA2__SD3_D2 0x64 0x005
+#define MX27_PAD_ATA_DATA2__FEC_RX_ER 0x64 0x002
+#define MX27_PAD_ATA_DATA2__GPIO4_4 0x64 0x032
+#define MX27_PAD_ATA_DATA3__ATA_DATA3 0x65 0x004
+#define MX27_PAD_ATA_DATA3__SD3_D3 0x65 0x005
+#define MX27_PAD_ATA_DATA3__FEC_RXD1 0x65 0x002
+#define MX27_PAD_ATA_DATA3__GPIO4_5 0x65 0x032
+#define MX27_PAD_ATA_DATA4__ATA_DATA4 0x66 0x004
+#define MX27_PAD_ATA_DATA4__ETMTRACEPKT14 0x66 0x005
+#define MX27_PAD_ATA_DATA4__FEC_RXD2 0x66 0x002
+#define MX27_PAD_ATA_DATA4__GPIO4_6 0x66 0x032
+#define MX27_PAD_ATA_DATA5__ATA_DATA5 0x67 0x004
+#define MX27_PAD_ATA_DATA5__ETMTRACEPKT13 0x67 0x005
+#define MX27_PAD_ATA_DATA5__FEC_RXD3 0x67 0x002
+#define MX27_PAD_ATA_DATA5__GPIO4_7 0x67 0x032
+#define MX27_PAD_ATA_DATA6__ATA_DATA6 0x68 0x004
+#define MX27_PAD_ATA_DATA6__FEC_MDIO 0x68 0x005
+#define MX27_PAD_ATA_DATA6__GPIO4_8 0x68 0x032
+#define MX27_PAD_ATA_DATA7__ATA_DATA7 0x69 0x004
+#define MX27_PAD_ATA_DATA7__ETMTRACEPKT12 0x69 0x005
+#define MX27_PAD_ATA_DATA7__FEC_MDC 0x69 0x006
+#define MX27_PAD_ATA_DATA7__GPIO4_9 0x69 0x032
+#define MX27_PAD_ATA_DATA8__ATA_DATA8 0x6a 0x004
+#define MX27_PAD_ATA_DATA8__ETMTRACEPKT11 0x6a 0x005
+#define MX27_PAD_ATA_DATA8__FEC_CRS 0x6a 0x002
+#define MX27_PAD_ATA_DATA8__GPIO4_10 0x6a 0x032
+#define MX27_PAD_ATA_DATA9__ATA_DATA9 0x6b 0x004
+#define MX27_PAD_ATA_DATA9__ETMTRACEPKT10 0x6b 0x005
+#define MX27_PAD_ATA_DATA9__FEC_TX_CLK 0x6b 0x002
+#define MX27_PAD_ATA_DATA9__GPIO4_11 0x6b 0x032
+#define MX27_PAD_ATA_DATA10__ATA_DATA10 0x6c 0x004
+#define MX27_PAD_ATA_DATA10__ETMTRACEPKT9 0x6c 0x005
+#define MX27_PAD_ATA_DATA10__FEC_RXD0 0x6c 0x002
+#define MX27_PAD_ATA_DATA10__GPIO4_12 0x6c 0x032
+#define MX27_PAD_ATA_DATA11__ATA_DATA11 0x6d 0x004
+#define MX27_PAD_ATA_DATA11__ETMTRACEPKT8 0x6d 0x005
+#define MX27_PAD_ATA_DATA11__FEC_RX_DV 0x6d 0x002
+#define MX27_PAD_ATA_DATA11__GPIO4_13 0x6d 0x032
+#define MX27_PAD_ATA_DATA12__ATA_DATA12 0x6e 0x004
+#define MX27_PAD_ATA_DATA12__ETMTRACEPKT7 0x6e 0x005
+#define MX27_PAD_ATA_DATA12__FEC_RX_CLK 0x6e 0x002
+#define MX27_PAD_ATA_DATA12__GPIO4_14 0x6e 0x032
+#define MX27_PAD_ATA_DATA13__ATA_DATA13 0x6f 0x004
+#define MX27_PAD_ATA_DATA13__ETMTRACEPKT6 0x6f 0x005
+#define MX27_PAD_ATA_DATA13__FEC_COL 0x6f 0x002
+#define MX27_PAD_ATA_DATA13__GPIO4_15 0x6f 0x032
+#define MX27_PAD_ATA_DATA14__ATA_DATA14 0x70 0x004
+#define MX27_PAD_ATA_DATA14__ETMTRACEPKT5 0x70 0x005
+#define MX27_PAD_ATA_DATA14__FEC_TX_ER 0x70 0x006
+#define MX27_PAD_ATA_DATA14__GPIO4_16 0x70 0x032
+#define MX27_PAD_I2C_DATA__I2C_DATA 0x71 0x004
+#define MX27_PAD_I2C_DATA__GPIO4_17 0x71 0x032
+#define MX27_PAD_I2C_CLK__I2C_CLK 0x72 0x004
+#define MX27_PAD_I2C_CLK__GPIO4_18 0x72 0x032
+#define MX27_PAD_CSPI2_SS2__CSPI2_SS2 0x73 0x004
+#define MX27_PAD_CSPI2_SS2__USBH2_DATA4 0x73 0x005
+#define MX27_PAD_CSPI2_SS2__GPIO4_19 0x73 0x032
+#define MX27_PAD_CSPI2_SS1__CSPI2_SS1 0x74 0x004
+#define MX27_PAD_CSPI2_SS1__USBH2_DATA3 0x74 0x005
+#define MX27_PAD_CSPI2_SS1__GPIO4_20 0x74 0x032
+#define MX27_PAD_CSPI2_SS0__CSPI2_SS0 0x75 0x004
+#define MX27_PAD_CSPI2_SS0__USBH2_DATA6 0x75 0x005
+#define MX27_PAD_CSPI2_SS0__GPIO4_21 0x75 0x032
+#define MX27_PAD_CSPI2_SCLK__CSPI2_SCLK 0x76 0x004
+#define MX27_PAD_CSPI2_SCLK__USBH2_DATA0 0x76 0x005
+#define MX27_PAD_CSPI2_SCLK__GPIO4_22 0x76 0x032
+#define MX27_PAD_CSPI2_MISO__CSPI2_MISO 0x77 0x004
+#define MX27_PAD_CSPI2_MISO__USBH2_DATA2 0x77 0x005
+#define MX27_PAD_CSPI2_MISO__GPIO4_23 0x77 0x032
+#define MX27_PAD_CSPI2_MOSI__CSPI2_MOSI 0x78 0x004
+#define MX27_PAD_CSPI2_MOSI__USBH2_DATA1 0x78 0x005
+#define MX27_PAD_CSPI2_MOSI__GPIO4_24 0x78 0x032
+#define MX27_PAD_CSPI1_RDY__CSPI1_RDY 0x79 0x000
+#define MX27_PAD_CSPI1_RDY__GPIO4_25 0x79 0x032
+#define MX27_PAD_CSPI1_SS2__CSPI1_SS2 0x7a 0x004
+#define MX27_PAD_CSPI1_SS2__USBH2_DATA5 0x7a 0x005
+#define MX27_PAD_CSPI1_SS2__GPIO4_26 0x7a 0x032
+#define MX27_PAD_CSPI1_SS1__CSPI1_SS1 0x7b 0x004
+#define MX27_PAD_CSPI1_SS1__GPIO4_27 0x7b 0x032
+#define MX27_PAD_CSPI1_SS0__CSPI1_SS0 0x7c 0x004
+#define MX27_PAD_CSPI1_SS0__GPIO4_28 0x7c 0x032
+#define MX27_PAD_CSPI1_SCLK__CSPI1_SCLK 0x7d 0x004
+#define MX27_PAD_CSPI1_SCLK__GPIO4_29 0x7d 0x032
+#define MX27_PAD_CSPI1_MISO__CSPI1_MISO 0x7e 0x004
+#define MX27_PAD_CSPI1_MISO__GPIO4_30 0x7e 0x032
+#define MX27_PAD_CSPI1_MOSI__CSPI1_MOSI 0x7f 0x004
+#define MX27_PAD_CSPI1_MOSI__GPIO4_31 0x7f 0x032
+#define MX27_PAD_USBOTG_NXT__USBOTG_NXT 0x80 0x000
+#define MX27_PAD_USBOTG_NXT__KP_COL6A 0x80 0x005
+#define MX27_PAD_USBOTG_NXT__GPIO5_0 0x80 0x032
+#define MX27_PAD_USBOTG_STP__USBOTG_STP 0x81 0x004
+#define MX27_PAD_USBOTG_STP__KP_ROW6A 0x81 0x005
+#define MX27_PAD_USBOTG_STP__GPIO5_1 0x81 0x032
+#define MX27_PAD_USBOTG_DIR__USBOTG_DIR 0x82 0x000
+#define MX27_PAD_USBOTG_DIR__KP_ROW7A 0x82 0x005
+#define MX27_PAD_USBOTG_DIR__GPIO5_2 0x82 0x032
+#define MX27_PAD_UART2_CTS__UART2_CTS 0x83 0x004
+#define MX27_PAD_UART2_CTS__KP_COL7 0x83 0x005
+#define MX27_PAD_UART2_CTS__GPIO5_3 0x83 0x032
+#define MX27_PAD_UART2_RTS__UART2_RTS 0x84 0x000
+#define MX27_PAD_UART2_RTS__KP_ROW7 0x84 0x005
+#define MX27_PAD_UART2_RTS__GPIO5_4 0x84 0x032
+#define MX27_PAD_PWMO__PWMO 0x85 0x004
+#define MX27_PAD_PWMO__GPIO5_5 0x85 0x032
+#define MX27_PAD_UART2_TXD__UART2_TXD 0x86 0x004
+#define MX27_PAD_UART2_TXD__KP_COL6 0x86 0x005
+#define MX27_PAD_UART2_TXD__GPIO5_6 0x86 0x032
+#define MX27_PAD_UART2_RXD__UART2_RXD 0x87 0x000
+#define MX27_PAD_UART2_RXD__KP_ROW6 0x87 0x005
+#define MX27_PAD_UART2_RXD__GPIO5_7 0x87 0x032
+#define MX27_PAD_UART3_TXD__UART3_TXD 0x88 0x004
+#define MX27_PAD_UART3_TXD__GPIO5_8 0x88 0x032
+#define MX27_PAD_UART3_RXD__UART3_RXD 0x89 0x000
+#define MX27_PAD_UART3_RXD__GPIO5_9 0x89 0x032
+#define MX27_PAD_UART3_CTS__UART3_CTS 0x8a 0x004
+#define MX27_PAD_UART3_CTS__GPIO5_10 0x8a 0x032
+#define MX27_PAD_UART3_RTS__UART3_RTS 0x8b 0x000
+#define MX27_PAD_UART3_RTS__GPIO5_11 0x8b 0x032
+#define MX27_PAD_UART1_TXD__UART1_TXD 0x8c 0x004
+#define MX27_PAD_UART1_TXD__GPIO5_12 0x8c 0x032
+#define MX27_PAD_UART1_RXD__UART1_RXD 0x8d 0x000
+#define MX27_PAD_UART1_RXD__GPIO5_13 0x8d 0x032
+#define MX27_PAD_UART1_CTS__UART1_CTS 0x8e 0x004
+#define MX27_PAD_UART1_CTS__GPIO5_14 0x8e 0x032
+#define MX27_PAD_UART1_RTS__UART1_RTS 0x8f 0x000
+#define MX27_PAD_UART1_RTS__GPIO5_15 0x8f 0x032
+#define MX27_PAD_RTCK__RTCK 0x90 0x004
+#define MX27_PAD_RTCK__OWIRE 0x90 0x005
+#define MX27_PAD_RTCK__GPIO5_16 0x90 0x032
+#define MX27_PAD_RESET_OUT_B__RESET_OUT_B 0x91 0x004
+#define MX27_PAD_RESET_OUT_B__GPIO5_17 0x91 0x032
+#define MX27_PAD_SD1_D0__SD1_D0 0x92 0x004
+#define MX27_PAD_SD1_D0__CSPI3_MISO 0x92 0x001
+#define MX27_PAD_SD1_D0__GPIO5_18 0x92 0x032
+#define MX27_PAD_SD1_D1__SD1_D1 0x93 0x004
+#define MX27_PAD_SD1_D1__GPIO5_19 0x93 0x032
+#define MX27_PAD_SD1_D2__SD1_D2 0x94 0x004
+#define MX27_PAD_SD1_D2__GPIO5_20 0x94 0x032
+#define MX27_PAD_SD1_D3__SD1_D3 0x95 0x004
+#define MX27_PAD_SD1_D3__CSPI3_SS 0x95 0x005
+#define MX27_PAD_SD1_D3__GPIO5_21 0x95 0x032
+#define MX27_PAD_SD1_CMD__SD1_CMD 0x96 0x004
+#define MX27_PAD_SD1_CMD__CSPI3_MOSI 0x96 0x005
+#define MX27_PAD_SD1_CMD__GPIO5_22 0x96 0x032
+#define MX27_PAD_SD1_CLK__SD1_CLK 0x97 0x004
+#define MX27_PAD_SD1_CLK__CSPI3_SCLK 0x97 0x005
+#define MX27_PAD_SD1_CLK__GPIO5_23 0x97 0x032
+#define MX27_PAD_USBOTG_CLK__USBOTG_CLK 0x98 0x000
+#define MX27_PAD_USBOTG_CLK__GPIO5_24 0x98 0x032
+#define MX27_PAD_USBOTG_DATA7__USBOTG_DATA7 0x99 0x004
+#define MX27_PAD_USBOTG_DATA7__GPIO5_25 0x99 0x032
+#define MX27_PAD_NFRB__NFRB 0xa0 0x000
+#define MX27_PAD_NFRB__ETMTRACEPKT3 0xa0 0x005
+#define MX27_PAD_NFRB__GPIO6_0 0xa0 0x032
+#define MX27_PAD_NFCLE__NFCLE 0xa1 0x004
+#define MX27_PAD_NFCLE__ETMTRACEPKT0 0xa1 0x005
+#define MX27_PAD_NFCLE__GPIO6_1 0xa1 0x032
+#define MX27_PAD_NFWP_B__NFWP_B 0xa2 0x004
+#define MX27_PAD_NFWP_B__ETMTRACEPKT1 0xa2 0x005
+#define MX27_PAD_NFWP_B__GPIO6_2 0xa2 0x032
+#define MX27_PAD_NFCE_B__NFCE_B 0xa3 0x004
+#define MX27_PAD_NFCE_B__ETMTRACEPKT2 0xa3 0x005
+#define MX27_PAD_NFCE_B__GPIO6_3 0xa3 0x032
+#define MX27_PAD_NFALE__NFALE 0xa4 0x004
+#define MX27_PAD_NFALE__ETMPIPESTAT0 0xa4 0x005
+#define MX27_PAD_NFALE__GPIO6_4 0xa4 0x032
+#define MX27_PAD_NFRE_B__NFRE_B 0xa5 0x004
+#define MX27_PAD_NFRE_B__ETMPIPESTAT1 0xa5 0x005
+#define MX27_PAD_NFRE_B__GPIO6_5 0xa5 0x032
+#define MX27_PAD_NFWE_B__NFWE_B 0xa6 0x004
+#define MX27_PAD_NFWE_B__ETMPIPESTAT2 0xa6 0x005
+#define MX27_PAD_NFWE_B__GPIO6_6 0xa6 0x032
+#define MX27_PAD_PC_POE__PC_POE 0xa7 0x004
+#define MX27_PAD_PC_POE__ATA_BUFFER_EN 0xa7 0x005
+#define MX27_PAD_PC_POE__GPIO6_7 0xa7 0x032
+#define MX27_PAD_PC_RW_B__PC_RW_B 0xa8 0x004
+#define MX27_PAD_PC_RW_B__ATA_IORDY 0xa8 0x001
+#define MX27_PAD_PC_RW_B__GPIO6_8 0xa8 0x032
+#define MX27_PAD_IOIS16__IOIS16 0xa9 0x000
+#define MX27_PAD_IOIS16__ATA_INTRQ 0xa9 0x001
+#define MX27_PAD_IOIS16__GPIO6_9 0xa9 0x032
+#define MX27_PAD_PC_RST__PC_RST 0xaa 0x004
+#define MX27_PAD_PC_RST__ATA_RESET_B 0xaa 0x005
+#define MX27_PAD_PC_RST__GPIO6_10 0xaa 0x032
+#define MX27_PAD_PC_BVD2__PC_BVD2 0xab 0x000
+#define MX27_PAD_PC_BVD2__ATA_DMACK 0xab 0x005
+#define MX27_PAD_PC_BVD2__GPIO6_11 0xab 0x032
+#define MX27_PAD_PC_BVD1__PC_BVD1 0xac 0x000
+#define MX27_PAD_PC_BVD1__ATA_DMARQ 0xac 0x001
+#define MX27_PAD_PC_BVD1__GPIO6_12 0xac 0x032
+#define MX27_PAD_PC_VS2__PC_VS2 0xad 0x000
+#define MX27_PAD_PC_VS2__ATA_DA0 0xad 0x005
+#define MX27_PAD_PC_VS2__GPIO6_13 0xad 0x032
+#define MX27_PAD_PC_VS1__PC_VS1 0xae 0x000
+#define MX27_PAD_PC_VS1__ATA_DA1 0xae 0x005
+#define MX27_PAD_PC_VS1__GPIO6_14 0xae 0x032
+#define MX27_PAD_CLKO__CLKO 0xaf 0x004
+#define MX27_PAD_CLKO__GPIO6_15 0xaf 0x032
+#define MX27_PAD_PC_PWRON__PC_PWRON 0xb0 0x000
+#define MX27_PAD_PC_PWRON__ATA_DA2 0xb0 0x005
+#define MX27_PAD_PC_PWRON__GPIO6_16 0xb0 0x032
+#define MX27_PAD_PC_READY__PC_READY 0xb1 0x000
+#define MX27_PAD_PC_READY__ATA_CS0 0xb1 0x005
+#define MX27_PAD_PC_READY__GPIO6_17 0xb1 0x032
+#define MX27_PAD_PC_WAIT_B__PC_WAIT_B 0xb2 0x000
+#define MX27_PAD_PC_WAIT_B__ATA_CS1 0xb2 0x005
+#define MX27_PAD_PC_WAIT_B__GPIO6_18 0xb2 0x032
+#define MX27_PAD_PC_CD2_B__PC_CD2_B 0xb3 0x000
+#define MX27_PAD_PC_CD2_B__ATA_DIOW 0xb3 0x005
+#define MX27_PAD_PC_CD2_B__GPIO6_19 0xb3 0x032
+#define MX27_PAD_PC_CD1_B__PC_CD1_B 0xb4 0x000
+#define MX27_PAD_PC_CD1_B__ATA_DIOR 0xb4 0x005
+#define MX27_PAD_PC_CD1_B__GPIO6_20 0xb4 0x032
+#define MX27_PAD_CS4_B__CS4_B 0xb5 0x004
+#define MX27_PAD_CS4_B__ETMTRACESYNC 0xb5 0x005
+#define MX27_PAD_CS4_B__GPIO6_21 0xb5 0x032
+#define MX27_PAD_CS5_B__CS5_B 0xb6 0x004
+#define MX27_PAD_CS5_B__ETMTRACECLK 0xb6 0x005
+#define MX27_PAD_CS5_B__GPIO6_22 0xb6 0x032
+#define MX27_PAD_ATA_DATA15__ATA_DATA15 0xb7 0x004
+#define MX27_PAD_ATA_DATA15__ETMTRACEPKT4 0xb7 0x005
+#define MX27_PAD_ATA_DATA15__FEC_TX_EN 0xb7 0x006
+#define MX27_PAD_ATA_DATA15__GPIO6_23 0xb7 0x032
+
+#endif /* __DTS_IMX27_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi
new file mode 100644
index 000000000..bc215e4b7
--- /dev/null
+++ b/arch/arm/boot/dts/imx27.dtsi
@@ -0,0 +1,577 @@
+/*
+ * Copyright 2012 Sascha Hauer, Pengutronix
+ *
+ * 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 "skeleton.dtsi"
+#include "imx27-pinfunc.h"
+
+#include <dt-bindings/clock/imx27-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ aliases {
+ ethernet0 = &fec;
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ gpio4 = &gpio5;
+ gpio5 = &gpio6;
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ serial5 = &uart6;
+ spi0 = &cspi1;
+ spi1 = &cspi2;
+ spi2 = &cspi3;
+ };
+
+ aitc: aitc-interrupt-controller@e0000000 {
+ compatible = "fsl,imx27-aitc", "fsl,avic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x10040000 0x1000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ osc26m {
+ compatible = "fsl,imx-osc26m", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+ };
+ };
+
+ cpus {
+ #size-cells = <0>;
+ #address-cells = <1>;
+
+ cpu: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,arm926ej-s";
+ operating-points = <
+ /* kHz uV */
+ 266000 1300000
+ 399000 1450000
+ >;
+ clock-latency = <62500>;
+ clocks = <&clks IMX27_CLK_CPU_DIV>;
+ voltage-tolerance = <5>;
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&aitc>;
+ ranges;
+
+ aipi@10000000 { /* AIPI1 */
+ compatible = "fsl,aipi-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x10000000 0x20000>;
+ ranges;
+
+ dma: dma@10001000 {
+ compatible = "fsl,imx27-dma";
+ reg = <0x10001000 0x1000>;
+ interrupts = <32>;
+ clocks = <&clks IMX27_CLK_DMA_IPG_GATE>,
+ <&clks IMX27_CLK_DMA_AHB_GATE>;
+ clock-names = "ipg", "ahb";
+ #dma-cells = <1>;
+ #dma-channels = <16>;
+ };
+
+ wdog: wdog@10002000 {
+ compatible = "fsl,imx27-wdt", "fsl,imx21-wdt";
+ reg = <0x10002000 0x1000>;
+ interrupts = <27>;
+ clocks = <&clks IMX27_CLK_WDOG_IPG_GATE>;
+ };
+
+ gpt1: timer@10003000 {
+ compatible = "fsl,imx27-gpt", "fsl,imx1-gpt";
+ reg = <0x10003000 0x1000>;
+ interrupts = <26>;
+ clocks = <&clks IMX27_CLK_GPT1_IPG_GATE>,
+ <&clks IMX27_CLK_PER1_GATE>;
+ clock-names = "ipg", "per";
+ };
+
+ gpt2: timer@10004000 {
+ compatible = "fsl,imx27-gpt", "fsl,imx1-gpt";
+ reg = <0x10004000 0x1000>;
+ interrupts = <25>;
+ clocks = <&clks IMX27_CLK_GPT2_IPG_GATE>,
+ <&clks IMX27_CLK_PER1_GATE>;
+ clock-names = "ipg", "per";
+ };
+
+ gpt3: timer@10005000 {
+ compatible = "fsl,imx27-gpt", "fsl,imx1-gpt";
+ reg = <0x10005000 0x1000>;
+ interrupts = <24>;
+ clocks = <&clks IMX27_CLK_GPT3_IPG_GATE>,
+ <&clks IMX27_CLK_PER1_GATE>;
+ clock-names = "ipg", "per";
+ };
+
+ pwm: pwm@10006000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx27-pwm";
+ reg = <0x10006000 0x1000>;
+ interrupts = <23>;
+ clocks = <&clks IMX27_CLK_PWM_IPG_GATE>,
+ <&clks IMX27_CLK_PER1_GATE>;
+ clock-names = "ipg", "per";
+ };
+
+ kpp: kpp@10008000 {
+ compatible = "fsl,imx27-kpp", "fsl,imx21-kpp";
+ reg = <0x10008000 0x1000>;
+ interrupts = <21>;
+ clocks = <&clks IMX27_CLK_KPP_IPG_GATE>;
+ status = "disabled";
+ };
+
+ owire: owire@10009000 {
+ compatible = "fsl,imx27-owire", "fsl,imx21-owire";
+ reg = <0x10009000 0x1000>;
+ clocks = <&clks IMX27_CLK_OWIRE_IPG_GATE>;
+ status = "disabled";
+ };
+
+ uart1: serial@1000a000 {
+ compatible = "fsl,imx27-uart", "fsl,imx21-uart";
+ reg = <0x1000a000 0x1000>;
+ interrupts = <20>;
+ clocks = <&clks IMX27_CLK_UART1_IPG_GATE>,
+ <&clks IMX27_CLK_PER1_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart2: serial@1000b000 {
+ compatible = "fsl,imx27-uart", "fsl,imx21-uart";
+ reg = <0x1000b000 0x1000>;
+ interrupts = <19>;
+ clocks = <&clks IMX27_CLK_UART2_IPG_GATE>,
+ <&clks IMX27_CLK_PER1_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart3: serial@1000c000 {
+ compatible = "fsl,imx27-uart", "fsl,imx21-uart";
+ reg = <0x1000c000 0x1000>;
+ interrupts = <18>;
+ clocks = <&clks IMX27_CLK_UART3_IPG_GATE>,
+ <&clks IMX27_CLK_PER1_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart4: serial@1000d000 {
+ compatible = "fsl,imx27-uart", "fsl,imx21-uart";
+ reg = <0x1000d000 0x1000>;
+ interrupts = <17>;
+ clocks = <&clks IMX27_CLK_UART4_IPG_GATE>,
+ <&clks IMX27_CLK_PER1_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ cspi1: cspi@1000e000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx27-cspi";
+ reg = <0x1000e000 0x1000>;
+ interrupts = <16>;
+ clocks = <&clks IMX27_CLK_CSPI1_IPG_GATE>,
+ <&clks IMX27_CLK_PER2_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ cspi2: cspi@1000f000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx27-cspi";
+ reg = <0x1000f000 0x1000>;
+ interrupts = <15>;
+ clocks = <&clks IMX27_CLK_CSPI2_IPG_GATE>,
+ <&clks IMX27_CLK_PER2_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ssi1: ssi@10010000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx27-ssi", "fsl,imx21-ssi";
+ reg = <0x10010000 0x1000>;
+ interrupts = <14>;
+ clocks = <&clks IMX27_CLK_SSI1_IPG_GATE>;
+ dmas = <&dma 12>, <&dma 13>, <&dma 14>, <&dma 15>;
+ dma-names = "rx0", "tx0", "rx1", "tx1";
+ fsl,fifo-depth = <8>;
+ status = "disabled";
+ };
+
+ ssi2: ssi@10011000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx27-ssi", "fsl,imx21-ssi";
+ reg = <0x10011000 0x1000>;
+ interrupts = <13>;
+ clocks = <&clks IMX27_CLK_SSI2_IPG_GATE>;
+ dmas = <&dma 8>, <&dma 9>, <&dma 10>, <&dma 11>;
+ dma-names = "rx0", "tx0", "rx1", "tx1";
+ fsl,fifo-depth = <8>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@10012000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx27-i2c", "fsl,imx21-i2c";
+ reg = <0x10012000 0x1000>;
+ interrupts = <12>;
+ clocks = <&clks IMX27_CLK_I2C1_IPG_GATE>;
+ status = "disabled";
+ };
+
+ sdhci1: sdhci@10013000 {
+ compatible = "fsl,imx27-mmc", "fsl,imx21-mmc";
+ reg = <0x10013000 0x1000>;
+ interrupts = <11>;
+ clocks = <&clks IMX27_CLK_SDHC1_IPG_GATE>,
+ <&clks IMX27_CLK_PER2_GATE>;
+ clock-names = "ipg", "per";
+ dmas = <&dma 7>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ sdhci2: sdhci@10014000 {
+ compatible = "fsl,imx27-mmc", "fsl,imx21-mmc";
+ reg = <0x10014000 0x1000>;
+ interrupts = <10>;
+ clocks = <&clks IMX27_CLK_SDHC2_IPG_GATE>,
+ <&clks IMX27_CLK_PER2_GATE>;
+ clock-names = "ipg", "per";
+ dmas = <&dma 6>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ iomuxc: iomuxc@10015000 {
+ compatible = "fsl,imx27-iomuxc";
+ reg = <0x10015000 0x600>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio1: gpio@10015000 {
+ compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+ reg = <0x10015000 0x100>;
+ clocks = <&clks IMX27_CLK_GPIO_IPG_GATE>;
+ interrupts = <8>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@10015100 {
+ compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+ reg = <0x10015100 0x100>;
+ clocks = <&clks IMX27_CLK_GPIO_IPG_GATE>;
+ interrupts = <8>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@10015200 {
+ compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+ reg = <0x10015200 0x100>;
+ clocks = <&clks IMX27_CLK_GPIO_IPG_GATE>;
+ interrupts = <8>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@10015300 {
+ compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+ reg = <0x10015300 0x100>;
+ clocks = <&clks IMX27_CLK_GPIO_IPG_GATE>;
+ interrupts = <8>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio5: gpio@10015400 {
+ compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+ reg = <0x10015400 0x100>;
+ clocks = <&clks IMX27_CLK_GPIO_IPG_GATE>;
+ interrupts = <8>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio6: gpio@10015500 {
+ compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+ reg = <0x10015500 0x100>;
+ clocks = <&clks IMX27_CLK_GPIO_IPG_GATE>;
+ interrupts = <8>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ audmux: audmux@10016000 {
+ compatible = "fsl,imx27-audmux", "fsl,imx21-audmux";
+ reg = <0x10016000 0x1000>;
+ clocks = <&clks IMX27_CLK_DUMMY>;
+ clock-names = "audmux";
+ status = "disabled";
+ };
+
+ cspi3: cspi@10017000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx27-cspi";
+ reg = <0x10017000 0x1000>;
+ interrupts = <6>;
+ clocks = <&clks IMX27_CLK_CSPI3_IPG_GATE>,
+ <&clks IMX27_CLK_PER2_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ gpt4: timer@10019000 {
+ compatible = "fsl,imx27-gpt", "fsl,imx1-gpt";
+ reg = <0x10019000 0x1000>;
+ interrupts = <4>;
+ clocks = <&clks IMX27_CLK_GPT4_IPG_GATE>,
+ <&clks IMX27_CLK_PER1_GATE>;
+ clock-names = "ipg", "per";
+ };
+
+ gpt5: timer@1001a000 {
+ compatible = "fsl,imx27-gpt", "fsl,imx1-gpt";
+ reg = <0x1001a000 0x1000>;
+ interrupts = <3>;
+ clocks = <&clks IMX27_CLK_GPT5_IPG_GATE>,
+ <&clks IMX27_CLK_PER1_GATE>;
+ clock-names = "ipg", "per";
+ };
+
+ uart5: serial@1001b000 {
+ compatible = "fsl,imx27-uart", "fsl,imx21-uart";
+ reg = <0x1001b000 0x1000>;
+ interrupts = <49>;
+ clocks = <&clks IMX27_CLK_UART5_IPG_GATE>,
+ <&clks IMX27_CLK_PER1_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart6: serial@1001c000 {
+ compatible = "fsl,imx27-uart", "fsl,imx21-uart";
+ reg = <0x1001c000 0x1000>;
+ interrupts = <48>;
+ clocks = <&clks IMX27_CLK_UART6_IPG_GATE>,
+ <&clks IMX27_CLK_PER1_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ i2c2: i2c@1001d000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx27-i2c", "fsl,imx21-i2c";
+ reg = <0x1001d000 0x1000>;
+ interrupts = <1>;
+ clocks = <&clks IMX27_CLK_I2C2_IPG_GATE>;
+ status = "disabled";
+ };
+
+ sdhci3: sdhci@1001e000 {
+ compatible = "fsl,imx27-mmc", "fsl,imx21-mmc";
+ reg = <0x1001e000 0x1000>;
+ interrupts = <9>;
+ clocks = <&clks IMX27_CLK_SDHC3_IPG_GATE>,
+ <&clks IMX27_CLK_PER2_GATE>;
+ clock-names = "ipg", "per";
+ dmas = <&dma 36>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ gpt6: timer@1001f000 {
+ compatible = "fsl,imx27-gpt", "fsl,imx1-gpt";
+ reg = <0x1001f000 0x1000>;
+ interrupts = <2>;
+ clocks = <&clks IMX27_CLK_GPT6_IPG_GATE>,
+ <&clks IMX27_CLK_PER1_GATE>;
+ clock-names = "ipg", "per";
+ };
+ };
+
+ aipi@10020000 { /* AIPI2 */
+ compatible = "fsl,aipi-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x10020000 0x20000>;
+ ranges;
+
+ fb: fb@10021000 {
+ compatible = "fsl,imx27-fb", "fsl,imx21-fb";
+ interrupts = <61>;
+ reg = <0x10021000 0x1000>;
+ clocks = <&clks IMX27_CLK_LCDC_IPG_GATE>,
+ <&clks IMX27_CLK_LCDC_AHB_GATE>,
+ <&clks IMX27_CLK_PER3_GATE>;
+ clock-names = "ipg", "ahb", "per";
+ status = "disabled";
+ };
+
+ coda: coda@10023000 {
+ compatible = "fsl,imx27-vpu", "cnm,codadx6";
+ reg = <0x10023000 0x0200>;
+ interrupts = <53>;
+ clocks = <&clks IMX27_CLK_VPU_BAUD_GATE>,
+ <&clks IMX27_CLK_VPU_AHB_GATE>;
+ clock-names = "per", "ahb";
+ iram = <&iram>;
+ };
+
+ usbotg: usb@10024000 {
+ compatible = "fsl,imx27-usb";
+ reg = <0x10024000 0x200>;
+ interrupts = <56>;
+ clocks = <&clks IMX27_CLK_USB_IPG_GATE>;
+ fsl,usbmisc = <&usbmisc 0>;
+ status = "disabled";
+ };
+
+ usbh1: usb@10024200 {
+ compatible = "fsl,imx27-usb";
+ reg = <0x10024200 0x200>;
+ interrupts = <54>;
+ clocks = <&clks IMX27_CLK_USB_IPG_GATE>;
+ fsl,usbmisc = <&usbmisc 1>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbh2: usb@10024400 {
+ compatible = "fsl,imx27-usb";
+ reg = <0x10024400 0x200>;
+ interrupts = <55>;
+ clocks = <&clks IMX27_CLK_USB_IPG_GATE>;
+ fsl,usbmisc = <&usbmisc 2>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbmisc: usbmisc@10024600 {
+ #index-cells = <1>;
+ compatible = "fsl,imx27-usbmisc";
+ reg = <0x10024600 0x200>;
+ clocks = <&clks IMX27_CLK_USB_AHB_GATE>;
+ };
+
+ sahara2: sahara@10025000 {
+ compatible = "fsl,imx27-sahara";
+ reg = <0x10025000 0x1000>;
+ interrupts = <59>;
+ clocks = <&clks IMX27_CLK_SAHARA_IPG_GATE>,
+ <&clks IMX27_CLK_SAHARA_AHB_GATE>;
+ clock-names = "ipg", "ahb";
+ };
+
+ clks: ccm@10027000{
+ compatible = "fsl,imx27-ccm";
+ reg = <0x10027000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ iim: iim@10028000 {
+ compatible = "fsl,imx27-iim";
+ reg = <0x10028000 0x1000>;
+ interrupts = <62>;
+ clocks = <&clks IMX27_CLK_IIM_IPG_GATE>;
+ };
+
+ fec: ethernet@1002b000 {
+ compatible = "fsl,imx27-fec";
+ reg = <0x1002b000 0x1000>;
+ interrupts = <50>;
+ clocks = <&clks IMX27_CLK_FEC_IPG_GATE>,
+ <&clks IMX27_CLK_FEC_AHB_GATE>;
+ clock-names = "ipg", "ahb";
+ status = "disabled";
+ };
+ };
+
+ nfc: nand@d8000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,imx27-nand";
+ reg = <0xd8000000 0x1000>;
+ interrupts = <29>;
+ clocks = <&clks IMX27_CLK_NFC_BAUD_GATE>;
+ status = "disabled";
+ };
+
+ weim: weim@d8002000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,imx27-weim";
+ reg = <0xd8002000 0x1000>;
+ clocks = <&clks IMX27_CLK_EMI_AHB_GATE>;
+ ranges = <
+ 0 0 0xc0000000 0x08000000
+ 1 0 0xc8000000 0x08000000
+ 2 0 0xd0000000 0x02000000
+ 3 0 0xd2000000 0x02000000
+ 4 0 0xd4000000 0x02000000
+ 5 0 0xd6000000 0x02000000
+ >;
+ status = "disabled";
+ };
+
+ iram: iram@ffff4c00 {
+ compatible = "mmio-sram";
+ reg = <0xffff4c00 0xb400>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-apf28.dts b/arch/arm/boot/dts/imx28-apf28.dts
new file mode 100644
index 000000000..070e59cbd
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-apf28.dts
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2012 Armadeus Systems - <support@armadeus.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
+ */
+
+/dts-v1/;
+#include "imx28.dtsi"
+
+/ {
+ model = "Armadeus Systems APF28 module";
+ compatible = "armadeus,imx28-apf28", "fsl,imx28";
+
+ memory {
+ reg = <0x40000000 0x08000000>;
+ };
+
+ apb@80000000 {
+ apbh@80000000 {
+ gpmi-nand@8000c000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpmi_pins_a &gpmi_status_cfg>;
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x300000>;
+ };
+
+ partition@300000 {
+ label = "env";
+ reg = <0x300000 0x80000>;
+ };
+
+ partition@380000 {
+ label = "env2";
+ reg = <0x380000 0x80000>;
+ };
+
+ partition@400000 {
+ label = "dtb";
+ reg = <0x400000 0x80000>;
+ };
+
+ partition@480000 {
+ label = "splash";
+ reg = <0x480000 0x80000>;
+ };
+
+ partition@500000 {
+ label = "kernel";
+ reg = <0x500000 0x800000>;
+ };
+
+ partition@d00000 {
+ label = "rootfs";
+ reg = <0xd00000 0xf300000>;
+ };
+ };
+ };
+
+ apbx@80040000 {
+ duart: serial@80074000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&duart_pins_a>;
+ status = "okay";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ mac0: ethernet@800f0000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac0_pins_a>;
+ phy-reset-gpios = <&gpio4 13 GPIO_ACTIVE_LOW>;
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-apf28dev.dts b/arch/arm/boot/dts/imx28-apf28dev.dts
new file mode 100644
index 000000000..7ac4f1af1
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-apf28dev.dts
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2012 Armadeus Systems - <support@armadeus.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
+ */
+
+/* APF28Dev is a docking board for the APF28 SOM */
+#include "imx28-apf28.dts"
+
+/ {
+ model = "Armadeus Systems APF28Dev docking/development board";
+ compatible = "armadeus,imx28-apf28dev", "armadeus,imx28-apf28", "fsl,imx28";
+
+ apb@80000000 {
+ apbh@80000000 {
+ ssp0: ssp@80010000 {
+ compatible = "fsl,imx28-mmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_4bit_pins_a
+ &mmc0_cd_cfg &mmc0_sck_cfg>;
+ bus-width = <4>;
+ status = "okay";
+ };
+
+ ssp2: ssp@80014000 {
+ compatible = "fsl,imx28-spi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_pins_a>;
+ status = "okay";
+ };
+
+ pinctrl@80018000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hog_pins_apf28dev>;
+
+ hog_pins_apf28dev: hog@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D16__GPIO_1_16
+ MX28_PAD_LCD_D17__GPIO_1_17
+ MX28_PAD_LCD_D18__GPIO_1_18
+ MX28_PAD_LCD_D19__GPIO_1_19
+ MX28_PAD_LCD_D20__GPIO_1_20
+ MX28_PAD_LCD_D21__GPIO_1_21
+ MX28_PAD_LCD_D22__GPIO_1_22
+ MX28_PAD_GPMI_CE1N__GPIO_0_17
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_pins_apf28dev: lcdif-apf28dev@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_RD_E__LCD_VSYNC
+ MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+ MX28_PAD_LCD_RS__LCD_DOTCLK
+ MX28_PAD_LCD_CS__LCD_ENABLE
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ usb0_otg_apf28dev: otg-apf28dev@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D23__GPIO_1_23
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+ };
+
+ lcdif@80030000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcdif_16bit_pins_a
+ &lcdif_pins_apf28dev>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display0 {
+ bits-per-pixel = <16>;
+ bus-width = <16>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <33000033>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <96>;
+ hfront-porch = <96>;
+ vback-porch = <20>;
+ vfront-porch = <21>;
+ hsync-len = <64>;
+ vsync-len = <4>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+ };
+
+ can0: can@80032000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&can0_pins_a>;
+ xceiver-supply = <&reg_can0_vcc>;
+ status = "okay";
+ };
+ };
+
+ apbx@80040000 {
+ lradc@80050000 {
+ fsl,lradc-touchscreen-wires = <4>;
+ status = "okay";
+ };
+
+ i2c0: i2c@80058000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+ };
+
+ pwm: pwm@80064000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_pins_a &pwm4_pins_a>;
+ status = "okay";
+ };
+
+ auart0: serial@8006a000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart0_pins_a>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+ };
+
+ usbphy0: usbphy@8007c000 {
+ status = "okay";
+ };
+
+ usbphy1: usbphy@8007e000 {
+ status = "okay";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ usb0: usb@80080000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_otg_apf28dev
+ &usb0_id_pins_b>;
+ vbus-supply = <&reg_usb0_vbus>;
+ status = "okay";
+ };
+
+ usb1: usb@80090000 {
+ status = "okay";
+ };
+
+ mac1: ethernet@800f4000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac1_pins_a>;
+ phy-reset-gpios = <&gpio1 29 GPIO_ACTIVE_LOW>;
+ status = "okay";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb0_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb0_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 23 1>;
+ enable-active-high;
+ };
+
+ reg_can0_vcc: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "can0_vcc";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ user {
+ label = "Heartbeat";
+ gpios = <&gpio0 21 0>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+
+ pwms = <&pwm 3 191000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ user-button {
+ label = "User button";
+ gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+ linux,code = <0x100>;
+ gpio-key,wakeup;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-apx4devkit.dts b/arch/arm/boot/dts/imx28-apx4devkit.dts
new file mode 100644
index 000000000..1092b761d
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-apx4devkit.dts
@@ -0,0 +1,226 @@
+/dts-v1/;
+#include "imx28.dtsi"
+
+/ {
+ model = "Bluegiga APX4 Development Kit";
+ compatible = "bluegiga,apx4devkit", "fsl,imx28";
+
+ memory {
+ reg = <0x40000000 0x04000000>;
+ };
+
+ apb@80000000 {
+ apbh@80000000 {
+ gpmi-nand@8000c000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpmi_pins_a &gpmi_status_cfg>;
+ status = "okay";
+ };
+
+ ssp0: ssp@80010000 {
+ compatible = "fsl,imx28-mmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_sck_cfg>;
+ bus-width = <4>;
+ status = "okay";
+ };
+
+ ssp2: ssp@80014000 {
+ compatible = "fsl,imx28-mmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_4bit_pins_apx4 &mmc2_sck_cfg_apx4>;
+ bus-width = <4>;
+ status = "okay";
+ };
+
+ pinctrl@80018000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hog_pins_a>;
+
+ hog_pins_a: hog@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_CE1N__GPIO_0_17
+ MX28_PAD_GPMI_RDY1__GPIO_0_21
+ MX28_PAD_SSP2_MISO__GPIO_2_18
+ MX28_PAD_SSP2_SS0__AUART3_TX /* was: 0x2131 - MX28_PAD_SSP2_SS0__GPIO_2_19 */
+ MX28_PAD_PWM3__GPIO_3_28
+ MX28_PAD_LCD_RESET__GPIO_3_30
+ MX28_PAD_JTAG_RTCK__GPIO_4_20
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_pins_apx4: lcdif-apx4@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_RD_E__LCD_VSYNC
+ MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+ MX28_PAD_LCD_RS__LCD_DOTCLK
+ MX28_PAD_LCD_CS__LCD_ENABLE
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ mmc2_4bit_pins_apx4: mmc2-4bit-apx4@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP0_DATA4__SSP2_D0
+ MX28_PAD_SSP0_DATA5__SSP2_D3
+ MX28_PAD_SSP0_DATA6__SSP2_CMD
+ MX28_PAD_SSP0_DATA7__SSP2_SCK
+ MX28_PAD_SSP2_SS1__SSP2_D1
+ MX28_PAD_SSP2_SS2__SSP2_D2
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ mmc2_sck_cfg_apx4: mmc2-sck-cfg-apx4 {
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP0_DATA7__SSP2_SCK
+ >;
+ fsl,drive-strength = <MXS_DRIVE_12mA>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+ };
+
+ lcdif@80030000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcdif_24bit_pins_a
+ &lcdif_pins_apx4>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display0 {
+ bits-per-pixel = <32>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <30000000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <88>;
+ hfront-porch = <40>;
+ vback-porch = <32>;
+ vfront-porch = <13>;
+ hsync-len = <48>;
+ vsync-len = <3>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+ };
+ };
+
+ apbx@80040000 {
+ saif0: saif@80042000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&saif0_pins_a>;
+ status = "okay";
+ };
+
+ saif1: saif@80046000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&saif1_pins_a>;
+ fsl,saif-master = <&saif0>;
+ status = "okay";
+ };
+
+ i2c0: i2c@80058000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ sgtl5000: codec@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ VDDA-supply = <&reg_3p3v>;
+ VDDIO-supply = <&reg_3p3v>;
+ clocks = <&saif0>;
+ };
+
+ pcf8563: rtc@51 {
+ compatible = "phg,pcf8563";
+ reg = <0x51>;
+ };
+ };
+
+ duart: serial@80074000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&duart_pins_a>;
+ status = "okay";
+ };
+
+ auart0: serial@8006a000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart0_pins_a>;
+ status = "okay";
+ };
+
+ auart1: serial@8006c000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart1_2pins_a>;
+ status = "okay";
+ };
+
+ auart2: serial@8006e000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart2_2pins_a>;
+ status = "okay";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ mac0: ethernet@800f0000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac0_pins_a>;
+ status = "okay";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+
+ sound {
+ compatible = "bluegiga,apx4devkit-sgtl5000",
+ "fsl,mxs-audio-sgtl5000";
+ model = "apx4devkit-sgtl5000";
+ saif-controllers = <&saif0 &saif1>;
+ audio-codec = <&sgtl5000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ user {
+ label = "Heartbeat";
+ gpios = <&gpio3 28 0>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-cfa10036.dts b/arch/arm/boot/dts/imx28-cfa10036.dts
new file mode 100644
index 000000000..b04b6b885
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-cfa10036.dts
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2012 Free Electrons
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx28.dtsi"
+
+/ {
+ model = "Crystalfontz CFA-10036 Board";
+ compatible = "crystalfontz,cfa10036", "fsl,imx28";
+
+ memory {
+ reg = <0x40000000 0x08000000>;
+ };
+
+ apb@80000000 {
+ apbh@80000000 {
+ pinctrl@80018000 {
+ ssd1306_cfa10036: ssd1306-10036@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP0_DATA7__GPIO_2_7
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ led_pins_cfa10036: leds-10036@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART1_RX__GPIO_3_4
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ usb0_otg_cfa10036: otg-10036@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_RDY0__USB0_ID
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ mmc_pwr_cfa10036: mmc_pwr_cfa10036@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ 0x31c3 /*
+ MX28_PAD_PWM3__GPIO_3_28 */
+ >;
+ fsl,drive-strength = <0>;
+ fsl,voltage = <1>;
+ fsl,pull-up = <0>;
+ };
+
+ };
+
+ ssp0: ssp@80010000 {
+ compatible = "fsl,imx28-mmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_4bit_pins_a
+ &mmc0_cd_cfg &mmc0_sck_cfg>;
+ vmmc-supply = <&reg_vddio_sd0>;
+ bus-width = <4>;
+ status = "okay";
+ };
+ };
+
+ apbx@80040000 {
+ duart: serial@80074000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&duart_pins_b>;
+ status = "okay";
+ };
+
+ i2c0: i2c@80058000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_b>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ ssd1306: oled@3c {
+ compatible = "solomon,ssd1306fb-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ssd1306_cfa10036>;
+ reg = <0x3c>;
+ reset-gpios = <&gpio2 7 0>;
+ solomon,height = <32>;
+ solomon,width = <128>;
+ solomon,page-offset = <0>;
+ };
+ };
+
+ usbphy0: usbphy@8007c000 {
+ status = "okay";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ usb0: usb@80080000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_otg_cfa10036>;
+ dr_mode = "peripheral";
+ phy_type = "utmi";
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_cfa10036>;
+
+ power {
+ gpios = <&gpio3 4 1>;
+ default-state = "on";
+ };
+ };
+
+ reg_vddio_sd0: vddio-sd0 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc_pwr_cfa10036>;
+ regulator-name = "vddio-sd0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 28 0>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-cfa10037.dts b/arch/arm/boot/dts/imx28-cfa10037.dts
new file mode 100644
index 000000000..e5beaa58b
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-cfa10037.dts
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2012 Free Electrons
+ *
+ * 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 CFA-10049 is an expansion board for the CFA-10036 module, thus we
+ * need to include the CFA-10036 DTS.
+ */
+#include "imx28-cfa10036.dts"
+
+/ {
+ model = "Crystalfontz CFA-10037 Board";
+ compatible = "crystalfontz,cfa10037", "crystalfontz,cfa10036", "fsl,imx28";
+
+ apb@80000000 {
+ apbh@80000000 {
+ pinctrl@80018000 {
+ usb_pins_cfa10037: usb-10037@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_D07__GPIO_0_7
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ mac0_pins_cfa10037: mac0-10037@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP2_SS2__GPIO_2_21
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+ };
+ };
+
+ apbx@80040000 {
+ usbphy1: usbphy@8007e000 {
+ status = "okay";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ usb1: usb@80090000 {
+ vbus-supply = <&reg_usb1_vbus>;
+ pinctrl-0 = <&usb1_pins_a>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ mac0: ethernet@800f0000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac0_pins_a
+ &mac0_pins_cfa10037>;
+ phy-reset-gpios = <&gpio2 21 0>;
+ phy-reset-duration = <100>;
+ status = "okay";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb1_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_pins_cfa10037>;
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio0 7 1>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-cfa10049.dts b/arch/arm/boot/dts/imx28-cfa10049.dts
new file mode 100644
index 000000000..ef944b6d4
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-cfa10049.dts
@@ -0,0 +1,436 @@
+/*
+ * Copyright 2012 Free Electrons
+ *
+ * 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 CFA-10049 is an expansion board for the CFA-10036 module, thus we
+ * need to include the CFA-10036 DTS.
+ */
+#include "imx28-cfa10036.dts"
+
+/ {
+ model = "Crystalfontz CFA-10049 Board";
+ compatible = "crystalfontz,cfa10049", "crystalfontz,cfa10036", "fsl,imx28";
+
+ apb@80000000 {
+ apbh@80000000 {
+ pinctrl@80018000 {
+ usb_pins_cfa10049: usb-10049@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_D07__GPIO_0_7
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ i2cmux_pins_cfa10049: i2cmux-10049@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D22__GPIO_1_22
+ MX28_PAD_LCD_D23__GPIO_1_23
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ mac0_pins_cfa10049: mac0-10049@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP2_SS2__GPIO_2_21
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ pca_pins_cfa10049: pca-10049@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP2_SS0__GPIO_2_19
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ rotary_pins_cfa10049: rotary-10049@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_I2C0_SCL__GPIO_3_24
+ MX28_PAD_I2C0_SDA__GPIO_3_25
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ rotary_btn_pins_cfa10049: rotary-btn-10049@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SAIF1_SDATA0__GPIO_3_26
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ spi2_pins_cfa10049: spi2-cfa10049@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP2_SCK__GPIO_2_16
+ MX28_PAD_SSP2_MOSI__GPIO_2_17
+ MX28_PAD_SSP2_MISO__GPIO_2_18
+ MX28_PAD_AUART1_TX__GPIO_3_5
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ spi3_pins_cfa10049: spi3-cfa10049@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_RDN__GPIO_0_24
+ MX28_PAD_GPMI_RESETN__GPIO_0_28
+ MX28_PAD_GPMI_CE1N__GPIO_0_17
+ MX28_PAD_GPMI_ALE__GPIO_0_26
+ MX28_PAD_GPMI_CLE__GPIO_0_27
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ lcdif_18bit_pins_cfa10049: lcdif-18bit@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D00__LCD_D0
+ MX28_PAD_LCD_D01__LCD_D1
+ MX28_PAD_LCD_D02__LCD_D2
+ MX28_PAD_LCD_D03__LCD_D3
+ MX28_PAD_LCD_D04__LCD_D4
+ MX28_PAD_LCD_D05__LCD_D5
+ MX28_PAD_LCD_D06__LCD_D6
+ MX28_PAD_LCD_D07__LCD_D7
+ MX28_PAD_LCD_D08__LCD_D8
+ MX28_PAD_LCD_D09__LCD_D9
+ MX28_PAD_LCD_D10__LCD_D10
+ MX28_PAD_LCD_D11__LCD_D11
+ MX28_PAD_LCD_D12__LCD_D12
+ MX28_PAD_LCD_D13__LCD_D13
+ MX28_PAD_LCD_D14__LCD_D14
+ MX28_PAD_LCD_D15__LCD_D15
+ MX28_PAD_LCD_D16__LCD_D16
+ MX28_PAD_LCD_D17__LCD_D17
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_pins_cfa10049: lcdif-evk@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_RD_E__LCD_VSYNC
+ MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+ MX28_PAD_LCD_RS__LCD_DOTCLK
+ MX28_PAD_LCD_CS__LCD_ENABLE
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_pins_cfa10049_pullup: lcdif-10049-pullup@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_RESET__GPIO_3_30
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ w1_gpio_pins: w1-gpio@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D21__GPIO_1_21
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>; /* 0 will enable the keeper */
+ };
+ };
+
+ lcdif@80030000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcdif_18bit_pins_cfa10049
+ &lcdif_pins_cfa10049
+ &lcdif_pins_cfa10049_pullup>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display0 {
+ bits-per-pixel = <32>;
+ bus-width = <18>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <9216000>;
+ hactive = <320>;
+ vactive = <480>;
+ hback-porch = <2>;
+ hfront-porch = <2>;
+ vback-porch = <2>;
+ vfront-porch = <2>;
+ hsync-len = <15>;
+ vsync-len = <15>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+ };
+ };
+
+ apbx@80040000 {
+ pwm: pwm@80064000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_pins_b>;
+ status = "okay";
+ };
+
+ i2c1: i2c@8005a000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
+
+ i2cmux {
+ compatible = "i2c-mux-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2cmux_pins_cfa10049>;
+ mux-gpios = <&gpio1 22 0 &gpio1 23 0>;
+ i2c-parent = <&i2c1>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ adc0: nau7802@2a {
+ compatible = "nuvoton,nau7802";
+ reg = <0x2a>;
+ nuvoton,vldo = <3000>;
+ };
+ };
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ adc1: nau7802@2a {
+ compatible = "nuvoton,nau7802";
+ reg = <0x2a>;
+ nuvoton,vldo = <3000>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ adc2: nau7802@2a {
+ compatible = "nuvoton,nau7802";
+ reg = <0x2a>;
+ nuvoton,vldo = <3000>;
+ };
+ };
+
+ i2c@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pca9555: pca9555@20 {
+ compatible = "nxp,pca9555";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pca_pins_cfa10049>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <19 0x2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x20>;
+ };
+ };
+ };
+
+ usbphy1: usbphy@8007e000 {
+ status = "okay";
+ };
+
+ lradc@80050000 {
+ status = "okay";
+ fsl,lradc-touchscreen-wires = <4>;
+ };
+ };
+ };
+
+ ahb@80080000 {
+ usb1: usb@80090000 {
+ vbus-supply = <&reg_usb1_vbus>;
+ pinctrl-0 = <&usb1_pins_a>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb1_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_pins_cfa10049>;
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio0 7 1>;
+ };
+ };
+
+ ahb@80080000 {
+ mac0: ethernet@800f0000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac0_pins_a
+ &mac0_pins_cfa10049>;
+ phy-reset-gpios = <&gpio2 21 0>;
+ phy-reset-duration = <100>;
+ status = "okay";
+ };
+ };
+
+ spi2 {
+ compatible = "spi-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_pins_cfa10049>;
+ status = "okay";
+ gpio-sck = <&gpio2 16 0>;
+ gpio-mosi = <&gpio2 17 0>;
+ gpio-miso = <&gpio2 18 0>;
+ cs-gpios = <&gpio3 5 0>;
+ num-chipselects = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hx8357: hx8357@0 {
+ compatible = "himax,hx8357b", "himax,hx8357";
+ reg = <0>;
+ spi-max-frequency = <100000>;
+ spi-cpol;
+ spi-cpha;
+ gpios-reset = <&gpio3 30 0>;
+ im-gpios = <&gpio5 4 0 &gpio5 5 0 &gpio5 6 0>;
+ };
+ };
+
+ spi3 {
+ compatible = "spi-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi3_pins_cfa10049>;
+ status = "okay";
+ gpio-sck = <&gpio0 24 0>;
+ gpio-mosi = <&gpio0 28 0>;
+ cs-gpios = <&gpio0 17 0 &gpio0 26 0 &gpio0 27 0>;
+ num-chipselects = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio5: gpio5@0 {
+ compatible = "fairchild,74hc595";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0>;
+ registers-number = <2>;
+ spi-max-frequency = <100000>;
+ };
+
+ gpio6: gpio6@1 {
+ compatible = "fairchild,74hc595";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <1>;
+ registers-number = <4>;
+ spi-max-frequency = <100000>;
+ };
+
+ dac0: dh2228@2 {
+ compatible = "rohm,dh2228fv";
+ reg = <2>;
+ spi-max-frequency = <100000>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&rotary_btn_pins_cfa10049>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rotary_button {
+ label = "rotary_button";
+ gpios = <&gpio3 26 1>;
+ debounce-interval = <10>;
+ linux,code = <28>;
+ };
+ };
+
+ rotary {
+ compatible = "rotary-encoder";
+ pinctrl-names = "default";
+ pinctrl-0 = <&rotary_pins_cfa10049>;
+ gpios = <&gpio3 24 1>, <&gpio3 25 1>;
+ linux,axis = <1>; /* REL_Y */
+ rotary-encoder,relative-axis;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 3 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+
+ };
+
+ onewire@0 {
+ compatible = "w1-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&w1_gpio_pins>;
+ status = "okay";
+ gpios = <&gpio1 21 0>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-cfa10055.dts b/arch/arm/boot/dts/imx28-cfa10055.dts
new file mode 100644
index 000000000..6a34114be
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-cfa10055.dts
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2013 Crystalfontz America, Inc.
+ * Free Electrons
+ *
+ * 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 CFA-10055 is an expansion board for the CFA-10036 module and
+ * CFA-10037, thus we need to include the CFA-10037 DTS.
+ */
+#include "imx28-cfa10037.dts"
+
+/ {
+ model = "Crystalfontz CFA-10055 Board";
+ compatible = "crystalfontz,cfa10055", "crystalfontz,cfa10037", "crystalfontz,cfa10036", "fsl,imx28";
+
+ apb@80000000 {
+ apbh@80000000 {
+ pinctrl@80018000 {
+ spi2_pins_cfa10055: spi2-cfa10055@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP2_SCK__GPIO_2_16
+ MX28_PAD_SSP2_MOSI__GPIO_2_17
+ MX28_PAD_SSP2_MISO__GPIO_2_18
+ MX28_PAD_AUART1_TX__GPIO_3_5
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ lcdif_18bit_pins_cfa10055: lcdif-18bit@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D00__LCD_D0
+ MX28_PAD_LCD_D01__LCD_D1
+ MX28_PAD_LCD_D02__LCD_D2
+ MX28_PAD_LCD_D03__LCD_D3
+ MX28_PAD_LCD_D04__LCD_D4
+ MX28_PAD_LCD_D05__LCD_D5
+ MX28_PAD_LCD_D06__LCD_D6
+ MX28_PAD_LCD_D07__LCD_D7
+ MX28_PAD_LCD_D08__LCD_D8
+ MX28_PAD_LCD_D09__LCD_D9
+ MX28_PAD_LCD_D10__LCD_D10
+ MX28_PAD_LCD_D11__LCD_D11
+ MX28_PAD_LCD_D12__LCD_D12
+ MX28_PAD_LCD_D13__LCD_D13
+ MX28_PAD_LCD_D14__LCD_D14
+ MX28_PAD_LCD_D15__LCD_D15
+ MX28_PAD_LCD_D16__LCD_D16
+ MX28_PAD_LCD_D17__LCD_D17
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_pins_cfa10055: lcdif-evk@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_RD_E__LCD_VSYNC
+ MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+ MX28_PAD_LCD_RS__LCD_DOTCLK
+ MX28_PAD_LCD_CS__LCD_ENABLE
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_pins_cfa10055_pullup: lcdif-10055-pullup@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_RESET__GPIO_3_30
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+ };
+
+ lcdif@80030000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcdif_18bit_pins_cfa10055
+ &lcdif_pins_cfa10055
+ &lcdif_pins_cfa10055_pullup>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display0 {
+ bits-per-pixel = <32>;
+ bus-width = <18>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <9216000>;
+ hactive = <320>;
+ vactive = <480>;
+ hback-porch = <2>;
+ hfront-porch = <2>;
+ vback-porch = <2>;
+ vfront-porch = <2>;
+ hsync-len = <15>;
+ vsync-len = <15>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+ };
+ };
+
+ apbx@80040000 {
+ lradc@80050000 {
+ fsl,lradc-touchscreen-wires = <4>;
+ status = "okay";
+ };
+
+ pwm: pwm@80064000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_pins_b>;
+ status = "okay";
+ };
+ };
+ };
+
+ spi2 {
+ compatible = "spi-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_pins_cfa10055>;
+ status = "okay";
+ gpio-sck = <&gpio2 16 0>;
+ gpio-mosi = <&gpio2 17 0>;
+ gpio-miso = <&gpio2 18 0>;
+ cs-gpios = <&gpio3 5 0>;
+ num-chipselects = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hx8357: hx8357@0 {
+ compatible = "himax,hx8357b", "himax,hx8357";
+ reg = <0>;
+ spi-max-frequency = <100000>;
+ spi-cpol;
+ spi-cpha;
+ gpios-reset = <&gpio3 30 0>;
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 3 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-cfa10056.dts b/arch/arm/boot/dts/imx28-cfa10056.dts
new file mode 100644
index 000000000..ba6495ca4
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-cfa10056.dts
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2013 Free Electrons
+ *
+ * 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 CFA-10055 is an expansion board for the CFA-10036 module and
+ * CFA-10037, thus we need to include the CFA-10037 DTS.
+ */
+#include "imx28-cfa10037.dts"
+
+/ {
+ model = "Crystalfontz CFA-10056 Board";
+ compatible = "crystalfontz,cfa10056", "crystalfontz,cfa10037", "crystalfontz,cfa10036", "fsl,imx28";
+
+ apb@80000000 {
+ apbh@80000000 {
+ pinctrl@80018000 {
+ spi2_pins_cfa10056: spi2-cfa10056@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP2_SCK__GPIO_2_16
+ MX28_PAD_SSP2_MOSI__GPIO_2_17
+ MX28_PAD_SSP2_MISO__GPIO_2_18
+ MX28_PAD_AUART1_TX__GPIO_3_5
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ lcdif_pins_cfa10056: lcdif-10056@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_RD_E__LCD_VSYNC
+ MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+ MX28_PAD_LCD_RS__LCD_DOTCLK
+ MX28_PAD_LCD_CS__LCD_ENABLE
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_pins_cfa10056_pullup: lcdif-10056-pullup@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_RESET__GPIO_3_30
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+ };
+
+ lcdif@80030000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcdif_24bit_pins_a
+ &lcdif_pins_cfa10056
+ &lcdif_pins_cfa10056_pullup >;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display0 {
+ bits-per-pixel = <32>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <32000000>;
+ hactive = <480>;
+ vactive = <800>;
+ hback-porch = <2>;
+ hfront-porch = <2>;
+ vback-porch = <2>;
+ vfront-porch = <2>;
+ hsync-len = <5>;
+ vsync-len = <5>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+ };
+ };
+ };
+
+ spi2 {
+ compatible = "spi-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_pins_cfa10056>;
+ status = "okay";
+ gpio-sck = <&gpio2 16 0>;
+ gpio-mosi = <&gpio2 17 0>;
+ gpio-miso = <&gpio2 18 0>;
+ cs-gpios = <&gpio3 5 0>;
+ num-chipselects = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hx8369: hx8369@0 {
+ compatible = "himax,hx8369a", "himax,hx8369";
+ reg = <0>;
+ spi-max-frequency = <100000>;
+ spi-cpol;
+ spi-cpha;
+ gpios-reset = <&gpio3 30 0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-cfa10057.dts b/arch/arm/boot/dts/imx28-cfa10057.dts
new file mode 100644
index 000000000..5df0b24ea
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-cfa10057.dts
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2013 Crystalfontz America, Inc.
+ * Copyright 2012 Free Electrons
+ *
+ * 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 CFA-10057 is an expansion board for the CFA-10036 module, thus we
+ * need to include the CFA-10036 DTS.
+ */
+#include "imx28-cfa10036.dts"
+
+/ {
+ model = "Crystalfontz CFA-10057 Board";
+ compatible = "crystalfontz,cfa10057", "crystalfontz,cfa10036", "fsl,imx28";
+
+ apb@80000000 {
+ apbh@80000000 {
+ pinctrl@80018000 {
+ usb_pins_cfa10057: usb-10057@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_D07__GPIO_0_7
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_18bit_pins_cfa10057: lcdif-18bit@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D00__LCD_D0
+ MX28_PAD_LCD_D01__LCD_D1
+ MX28_PAD_LCD_D02__LCD_D2
+ MX28_PAD_LCD_D03__LCD_D3
+ MX28_PAD_LCD_D04__LCD_D4
+ MX28_PAD_LCD_D05__LCD_D5
+ MX28_PAD_LCD_D06__LCD_D6
+ MX28_PAD_LCD_D07__LCD_D7
+ MX28_PAD_LCD_D08__LCD_D8
+ MX28_PAD_LCD_D09__LCD_D9
+ MX28_PAD_LCD_D10__LCD_D10
+ MX28_PAD_LCD_D11__LCD_D11
+ MX28_PAD_LCD_D12__LCD_D12
+ MX28_PAD_LCD_D13__LCD_D13
+ MX28_PAD_LCD_D14__LCD_D14
+ MX28_PAD_LCD_D15__LCD_D15
+ MX28_PAD_LCD_D16__LCD_D16
+ MX28_PAD_LCD_D17__LCD_D17
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_pins_cfa10057: lcdif-evk@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_RD_E__LCD_VSYNC
+ MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+ MX28_PAD_LCD_RS__LCD_DOTCLK
+ MX28_PAD_LCD_CS__LCD_ENABLE
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+ };
+
+ lcdif@80030000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcdif_18bit_pins_cfa10057
+ &lcdif_pins_cfa10057>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display0 {
+ bits-per-pixel = <32>;
+ bus-width = <18>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <30000000>;
+ hactive = <480>;
+ vactive = <800>;
+ hfront-porch = <12>;
+ hback-porch = <2>;
+ vfront-porch = <5>;
+ vback-porch = <3>;
+ hsync-len = <2>;
+ vsync-len = <2>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+ };
+ };
+
+ apbx@80040000 {
+ lradc@80050000 {
+ fsl,lradc-touchscreen-wires = <4>;
+ status = "okay";
+ };
+
+ pwm: pwm@80064000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_pins_b>;
+ status = "okay";
+ };
+
+ i2c1: i2c@8005a000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
+
+ usbphy1: usbphy@8007e000 {
+ status = "okay";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ usb1: usb@80090000 {
+ vbus-supply = <&reg_usb1_vbus>;
+ pinctrl-0 = <&usb1_pins_a>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb1_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_pins_cfa10057>;
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio0 7 1>;
+ };
+ };
+
+ ahb@80080000 {
+ mac0: ethernet@800f0000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac0_pins_a>;
+ phy-reset-gpios = <&gpio2 21 0>;
+ phy-reset-duration = <100>;
+ status = "okay";
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 3 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-cfa10058.dts b/arch/arm/boot/dts/imx28-cfa10058.dts
new file mode 100644
index 000000000..f5c6dce34
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-cfa10058.dts
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2013 Crystalfontz America, Inc.
+ * Copyright 2013 Free Electrons
+ *
+ * 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 CFA-10058 is an expansion board for the CFA-10036 module, thus we
+ * need to include the CFA-10036 DTS.
+ */
+#include "imx28-cfa10036.dts"
+
+/ {
+ model = "Crystalfontz CFA-10058 Board";
+ compatible = "crystalfontz,cfa10058", "crystalfontz,cfa10036", "fsl,imx28";
+
+ apb@80000000 {
+ apbh@80000000 {
+ pinctrl@80018000 {
+ usb_pins_cfa10058: usb-10058@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_D07__GPIO_0_7
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_pins_cfa10058: lcdif-10058@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_RD_E__LCD_VSYNC
+ MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+ MX28_PAD_LCD_RS__LCD_DOTCLK
+ MX28_PAD_LCD_CS__LCD_ENABLE
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+ };
+
+ lcdif@80030000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcdif_24bit_pins_a
+ &lcdif_pins_cfa10058>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display0 {
+ bits-per-pixel = <32>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <30000000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <40>;
+ hfront-porch = <40>;
+ vback-porch = <13>;
+ vfront-porch = <29>;
+ hsync-len = <8>;
+ vsync-len = <8>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+ };
+ };
+
+ apbx@80040000 {
+ lradc@80050000 {
+ fsl,lradc-touchscreen-wires = <4>;
+ status = "okay";
+ };
+
+ pwm: pwm@80064000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_pins_b>;
+ status = "okay";
+ };
+
+ usbphy1: usbphy@8007e000 {
+ status = "okay";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ usb1: usb@80090000 {
+ vbus-supply = <&reg_usb1_vbus>;
+ pinctrl-0 = <&usb1_pins_a>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb1_vbus: regulator@0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_pins_cfa10058>;
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio0 7 1>;
+ };
+ };
+
+ ahb@80080000 {
+ mac0: ethernet@800f0000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac0_pins_a>;
+ phy-reset-gpios = <&gpio2 21 0>;
+ phy-reset-duration = <100>;
+ status = "okay";
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 3 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-duckbill.dts b/arch/arm/boot/dts/imx28-duckbill.dts
new file mode 100644
index 000000000..ce1a7effb
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-duckbill.dts
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2013 Michael Heimpold <mhei@heimpold.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
+ */
+
+/dts-v1/;
+#include "imx28.dtsi"
+
+/ {
+ model = "I2SE Duckbill";
+ compatible = "i2se,duckbill", "fsl,imx28";
+
+ memory {
+ reg = <0x40000000 0x08000000>;
+ };
+
+ apb@80000000 {
+ apbh@80000000 {
+ ssp0: ssp@80010000 {
+ compatible = "fsl,imx28-mmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_4bit_pins_a
+ &mmc0_cd_cfg &mmc0_sck_cfg>;
+ bus-width = <4>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+ };
+
+ pinctrl@80018000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hog_pins_a>;
+
+ hog_pins_a: hog@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP0_DATA7__GPIO_2_7 /* PHY Reset */
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ led_pins_a: led_gpio@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART1_RX__GPIO_3_4
+ MX28_PAD_AUART1_TX__GPIO_3_5
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+ };
+ };
+
+ apbx@80040000 {
+ duart: serial@80074000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&duart_pins_a>;
+ status = "okay";
+ };
+
+ usbphy0: usbphy@8007c000 {
+ status = "okay";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ usb0: usb@80080000 {
+ status = "okay";
+ };
+
+ mac0: ethernet@800f0000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac0_pins_a>;
+ phy-supply = <&reg_3p3v>;
+ phy-reset-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>;
+ phy-reset-duration = <100>;
+ status = "okay";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_a>;
+
+ status {
+ label = "duckbill:green:status";
+ gpios = <&gpio3 5 GPIO_ACTIVE_HIGH>;
+ };
+
+ failure {
+ label = "duckbill:red:status";
+ gpios = <&gpio3 4 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-eukrea-mbmx283lc.dts b/arch/arm/boot/dts/imx28-eukrea-mbmx283lc.dts
new file mode 100644
index 000000000..7c1572c5a
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-eukrea-mbmx283lc.dts
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <eric@eukrea.com>
+ * Copyright 2013 Eukréa Electromatique <denis@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.
+ */
+
+/*
+ * Module contains : i.MX282 + 64MB DDR2 + NAND + Ethernet PHY + RTC
+ */
+
+/dts-v1/;
+#include "imx28-eukrea-mbmx28lc.dtsi"
+
+/ {
+ model = "Eukrea Electromatique MBMX283LC";
+ compatible = "eukrea,mbmx283lc", "eukrea,mbmx28lc", "fsl,imx28";
+
+ memory {
+ reg = <0x40000000 0x04000000>;
+ };
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpmi_pins_a>;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ pcf8563: rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+};
+
+
+&mac0 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac0_pins_a>;
+ phy-reset-gpios = <&gpio4 13 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&pinctrl{
+ pinctrl-names = "default";
+ pinctrl-0 = <&hog_pins_cpuimx283>;
+
+ hog_pins_cpuimx283: hog-cpuimx283@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_ENET0_RX_CLK__GPIO_4_13
+ MX28_PAD_ENET0_TX_CLK__GPIO_4_5
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-eukrea-mbmx287lc.dts b/arch/arm/boot/dts/imx28-eukrea-mbmx287lc.dts
new file mode 100644
index 000000000..e773144e1
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-eukrea-mbmx287lc.dts
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <eric@eukrea.com>
+ * Copyright 2013 Eukréa Electromatique <denis@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.
+ */
+
+/*
+ * Module contains : i.MX287 + 128MB DDR2 + NAND + 2 x Ethernet PHY + RTC
+ */
+
+#include "imx28-eukrea-mbmx283lc.dts"
+
+/ {
+ model = "Eukrea Electromatique MBMX287LC";
+ compatible = "eukrea,mbmx287lc", "eukrea,mbmx283lc", "eukrea,mbmx28lc", "fsl,imx28";
+
+ memory {
+ reg = <0x40000000 0x08000000>;
+ };
+};
+
+&mac1 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac1_pins_a>;
+ phy-reset-gpios = <&gpio3 27 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&pinctrl {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hog_pins_cpuimx283 &hog_pins_cpuimx287>;
+ hog_pins_cpuimx287: hog-cpuimx287@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SPDIF__GPIO_3_27
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi b/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi
new file mode 100644
index 000000000..927b391d2
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi
@@ -0,0 +1,326 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <eric@eukrea.com>
+ * Copyright 2013 Eukréa Electromatique <denis@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.
+ */
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "imx28.dtsi"
+
+/ {
+ model = "Eukrea Electromatique MBMX28LC";
+ compatible = "eukrea,mbmx28lc", "fsl,imx28";
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 4 1000000>;
+ brightness-levels = <0 25 50 75 100 125 150 175 200 225 255>;
+ default-brightness-level = <10>;
+ };
+
+ button-sw3 {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_button_sw3_pins_mbmx28lc>;
+
+ sw3 {
+ label = "SW3";
+ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_MISC>;
+ gpio-key,wakeup;
+ };
+ };
+
+ button-sw4 {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_button_sw4_pins_mbmx28lc>;
+
+ sw4 {
+ label = "SW4";
+ gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_MISC>;
+ gpio-key,wakeup;
+ };
+ };
+
+ led-d6 {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_d6_pins_mbmx28lc>;
+
+ led1 {
+ label = "d6";
+ gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ led-d7 {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_d7_pins_mbmx28lc>;
+
+ led1 {
+ label = "d7";
+ gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_lcd_3v3: regulator@1 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&reg_lcd_3v3_pins_mbmx28lc>;
+ regulator-name = "lcd-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb0_vbus: regulator@2 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&reg_usb0_vbus_pins_mbmx28lc>;
+ regulator-name = "usb0_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 18 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb1_vbus: regulator@3 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&reg_usb1_vbus_pins_mbmx28lc>;
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 19 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx28-mbmx28lc-sgtl5000",
+ "fsl,mxs-audio-sgtl5000";
+ model = "imx28-mbmx28lc-sgtl5000";
+ saif-controllers = <&saif0 &saif1>;
+ audio-codec = <&sgtl5000>;
+ };
+};
+
+&duart {
+ pinctrl-names = "default";
+ pinctrl-0 = <&duart_4pins_a>;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ sgtl5000: codec@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ VDDA-supply = <&reg_3p3v>;
+ VDDIO-supply = <&reg_3p3v>;
+ clocks = <&saif0>;
+ };
+};
+
+&lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcdif_18bit_pins_a &lcdif_pins_mbmx28lc>;
+ lcd-supply = <&reg_lcd_3v3>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display0 {
+ model = "43WVF1G-0";
+ bits-per-pixel = <16>;
+ bus-width = <18>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <9072000>;
+ hactive = <480>;
+ vactive = <272>;
+ hback-porch = <10>;
+ hfront-porch = <5>;
+ vback-porch = <8>;
+ vfront-porch = <8>;
+ hsync-len = <40>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+};
+
+&lradc {
+ fsl,lradc-touchscreen-wires = <4>;
+ status = "okay";
+};
+
+&pinctrl {
+ gpio_button_sw3_pins_mbmx28lc: gpio-button-sw3-mbmx28lc@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D21__GPIO_1_21
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ gpio_button_sw4_pins_mbmx28lc: gpio-button-sw4-mbmx28lc@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D20__GPIO_1_20
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_pins_mbmx28lc: lcdif-mbmx28lc@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_VSYNC__LCD_VSYNC
+ MX28_PAD_LCD_HSYNC__LCD_HSYNC
+ MX28_PAD_LCD_DOTCLK__LCD_DOTCLK
+ MX28_PAD_LCD_ENABLE__LCD_ENABLE
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ led_d6_pins_mbmx28lc: led-d6-mbmx28lc@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D23__GPIO_1_23
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ led_d7_pins_mbmx28lc: led-d7-mbmx28lc@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D22__GPIO_1_22
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ reg_lcd_3v3_pins_mbmx28lc: lcd-3v3-mbmx28lc@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_RESET__GPIO_3_30
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ reg_usb0_vbus_pins_mbmx28lc: reg-usb0-vbus-mbmx28lc@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D18__GPIO_1_18
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ reg_usb1_vbus_pins_mbmx28lc: reg-usb1-vbus-mbmx28lc@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D19__GPIO_1_19
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm4_pins_a>;
+ status = "okay";
+};
+
+&saif0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&saif0_pins_a>;
+ status = "okay";
+};
+
+&saif1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&saif1_pins_a>;
+ fsl,saif-master = <&saif0>;
+ status = "okay";
+};
+
+&ssp0 {
+ compatible = "fsl,imx28-mmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_cd_cfg &mmc0_sck_cfg>;
+ bus-width = <4>;
+ cd-inverted;
+ status = "okay";
+};
+
+&usb0 {
+ disable-over-current;
+ vbus-supply = <&reg_usb0_vbus>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_pins_b>;
+};
+
+&usb1 {
+ vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+};
+
+&usbphy0 {
+ status = "okay";
+};
+
+&usbphy1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx28-evk.dts b/arch/arm/boot/dts/imx28-evk.dts
new file mode 100644
index 000000000..279249b8c
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-evk.dts
@@ -0,0 +1,378 @@
+/*
+ * Copyright 2012 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
+ */
+
+/dts-v1/;
+#include "imx28.dtsi"
+
+/ {
+ model = "Freescale i.MX28 Evaluation Kit";
+ compatible = "fsl,imx28-evk", "fsl,imx28";
+
+ memory {
+ reg = <0x40000000 0x08000000>;
+ };
+
+ apb@80000000 {
+ apbh@80000000 {
+ gpmi-nand@8000c000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpmi_pins_a &gpmi_status_cfg
+ &gpmi_pins_evk>;
+ status = "okay";
+ };
+
+ ssp0: ssp@80010000 {
+ compatible = "fsl,imx28-mmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_8bit_pins_a
+ &mmc0_cd_cfg &mmc0_sck_cfg>;
+ bus-width = <8>;
+ wp-gpios = <&gpio2 12 0>;
+ vmmc-supply = <&reg_vddio_sd0>;
+ status = "okay";
+ };
+
+ ssp1: ssp@80012000 {
+ compatible = "fsl,imx28-mmc";
+ bus-width = <8>;
+ wp-gpios = <&gpio0 28 0>;
+ };
+
+ ssp2: ssp@80014000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx28-spi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_pins_a>;
+ status = "okay";
+
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "sst,sst25vf016b";
+ spi-max-frequency = <40000000>;
+ reg = <0>;
+ };
+ };
+
+ pinctrl@80018000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hog_pins_a>;
+
+ hog_pins_a: hog@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP1_CMD__GPIO_2_13
+ MX28_PAD_SSP1_DATA3__GPIO_2_15
+ MX28_PAD_ENET0_RX_CLK__GPIO_4_13
+ MX28_PAD_SSP1_SCK__GPIO_2_12
+ MX28_PAD_PWM3__GPIO_3_28
+ MX28_PAD_LCD_RESET__GPIO_3_30
+ MX28_PAD_AUART2_RX__GPIO_3_8
+ MX28_PAD_AUART2_TX__GPIO_3_9
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ led_pin_gpio3_5: led_gpio3_5@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART1_TX__GPIO_3_5
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ gpmi_pins_evk: gpmi-nand-evk@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_CE1N__GPMI_CE1N
+ MX28_PAD_GPMI_RDY1__GPMI_READY1
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_pins_evk: lcdif-evk@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_RD_E__LCD_VSYNC
+ MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+ MX28_PAD_LCD_RS__LCD_DOTCLK
+ MX28_PAD_LCD_CS__LCD_ENABLE
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+ };
+
+ lcdif@80030000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcdif_24bit_pins_a
+ &lcdif_pins_evk>;
+ lcd-supply = <&reg_lcd_3v3>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display0 {
+ bits-per-pixel = <32>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <33500000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <89>;
+ hfront-porch = <164>;
+ vback-porch = <23>;
+ vfront-porch = <10>;
+ hsync-len = <10>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+ };
+
+ can0: can@80032000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&can0_pins_a>;
+ xceiver-supply = <&reg_can_3v3>;
+ status = "okay";
+ };
+
+ can1: can@80034000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&can1_pins_a>;
+ xceiver-supply = <&reg_can_3v3>;
+ status = "okay";
+ };
+ };
+
+ apbx@80040000 {
+ saif0: saif@80042000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&saif0_pins_a>;
+ status = "okay";
+ };
+
+ saif1: saif@80046000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&saif1_pins_a>;
+ fsl,saif-master = <&saif0>;
+ status = "okay";
+ };
+
+ lradc@80050000 {
+ status = "okay";
+ fsl,lradc-touchscreen-wires = <4>;
+ fsl,ave-ctrl = <4>;
+ fsl,ave-delay = <2>;
+ fsl,settling = <10>;
+ };
+
+ i2c0: i2c@80058000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ sgtl5000: codec@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ VDDA-supply = <&reg_3p3v>;
+ VDDIO-supply = <&reg_3p3v>;
+ clocks = <&saif0>;
+ };
+
+ at24@51 {
+ compatible = "at24,24c32";
+ pagesize = <32>;
+ reg = <0x51>;
+ };
+ };
+
+ pwm: pwm@80064000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm2_pins_a>;
+ status = "okay";
+ };
+
+ duart: serial@80074000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&duart_pins_a>;
+ status = "okay";
+ };
+
+ auart0: serial@8006a000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart0_pins_a>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+ };
+
+ auart3: serial@80070000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart3_pins_a>;
+ status = "okay";
+ };
+
+ usbphy0: usbphy@8007c000 {
+ status = "okay";
+ };
+
+ usbphy1: usbphy@8007e000 {
+ status = "okay";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ usb0: usb@80080000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_pins_a>;
+ vbus-supply = <&reg_usb0_vbus>;
+ status = "okay";
+ };
+
+ usb1: usb@80090000 {
+ vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+ };
+
+ mac0: ethernet@800f0000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac0_pins_a>;
+ phy-supply = <&reg_fec_3v3>;
+ phy-reset-gpios = <&gpio4 13 0>;
+ phy-reset-duration = <100>;
+ status = "okay";
+ };
+
+ mac1: ethernet@800f4000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac1_pins_a>;
+ status = "okay";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_vddio_sd0: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "vddio-sd0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 28 0>;
+ };
+
+ reg_fec_3v3: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "fec-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 15 0>;
+ };
+
+ reg_usb0_vbus: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "usb0_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 9 0>;
+ enable-active-high;
+ };
+
+ reg_usb1_vbus: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 8 0>;
+ enable-active-high;
+ };
+
+ reg_lcd_3v3: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "lcd-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 30 0>;
+ enable-active-high;
+ };
+
+ reg_can_3v3: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ regulator-name = "can-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 13 0>;
+ enable-active-high;
+ };
+
+ };
+
+ sound {
+ compatible = "fsl,imx28-evk-sgtl5000",
+ "fsl,mxs-audio-sgtl5000";
+ model = "imx28-evk-sgtl5000";
+ saif-controllers = <&saif0 &saif1>;
+ audio-codec = <&sgtl5000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pin_gpio3_5>;
+
+ user {
+ label = "Heartbeat";
+ gpios = <&gpio3 5 0>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 2 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-m28.dtsi b/arch/arm/boot/dts/imx28-m28.dtsi
new file mode 100644
index 000000000..759cc5625
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-m28.dtsi
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2014 Marek Vasut <marex@denx.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
+ */
+
+#include "imx28.dtsi"
+
+/ {
+ model = "DENX M28";
+ compatible = "denx,m28", "fsl,imx28";
+
+ memory {
+ reg = <0x40000000 0x08000000>;
+ };
+
+ apb@80000000 {
+ apbh@80000000 {
+ gpmi-nand@8000c000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpmi_pins_a &gpmi_status_cfg>;
+ status = "okay";
+
+ partition@0 {
+ label = "bootloader";
+ reg = <0x00000000 0x00300000>;
+ read-only;
+ };
+
+ partition@1 {
+ label = "environment";
+ reg = <0x00300000 0x00080000>;
+ };
+
+ partition@2 {
+ label = "redundant-environment";
+ reg = <0x00380000 0x00080000>;
+ };
+
+ partition@3 {
+ label = "kernel";
+ reg = <0x00400000 0x00400000>;
+ };
+
+ partition@4 {
+ label = "filesystem";
+ reg = <0x00800000 0x0f800000>;
+ };
+ };
+ };
+
+ apbx@80040000 {
+ i2c0: i2c@80058000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ rtc: rtc@68 {
+ compatible = "stm,m41t62";
+ reg = <0x68>;
+ };
+ };
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-m28cu3.dts b/arch/arm/boot/dts/imx28-m28cu3.dts
new file mode 100644
index 000000000..2df63bee6
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-m28cu3.dts
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2013 Marek Vasut <marex@denx.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
+ */
+
+/dts-v1/;
+#include "imx28.dtsi"
+
+/ {
+ model = "MSR M28CU3";
+ compatible = "msr,m28cu3", "fsl,imx28";
+
+ memory {
+ reg = <0x40000000 0x08000000>;
+ };
+
+ apb@80000000 {
+ apbh@80000000 {
+ gpmi-nand@8000c000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpmi_pins_a &gpmi_status_cfg>;
+ status = "okay";
+
+ partition@0 {
+ label = "gpmi-nfc-0-boot";
+ reg = <0x00000000 0x01400000>;
+ read-only;
+ };
+
+ partition@1 {
+ label = "gpmi-nfc-general-use";
+ reg = <0x01400000 0x0ec00000>;
+ };
+ };
+
+ ssp0: ssp@80010000 {
+ compatible = "fsl,imx28-mmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_4bit_pins_a
+ &mmc0_cd_cfg
+ &mmc0_sck_cfg>;
+ bus-width = <4>;
+ vmmc-supply = <&reg_vddio_sd0>;
+ status = "okay";
+ };
+
+ ssp2: ssp@80014000 {
+ compatible = "fsl,imx28-mmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_4bit_pins_a
+ &mmc2_cd_cfg
+ &mmc2_sck_cfg>;
+ bus-width = <4>;
+ vmmc-supply = <&reg_vddio_sd1>;
+ status = "okay";
+ };
+
+ pinctrl@80018000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hog_pins_a>;
+
+ hog_pins_a: hog@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP2_SS0__GPIO_2_19
+ MX28_PAD_PWM4__GPIO_3_29
+ MX28_PAD_AUART2_RX__GPIO_3_8
+ MX28_PAD_ENET0_RX_CLK__GPIO_4_13
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_pins_m28: lcdif-m28@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_VSYNC__LCD_VSYNC
+ MX28_PAD_LCD_HSYNC__LCD_HSYNC
+ MX28_PAD_LCD_DOTCLK__LCD_DOTCLK
+ MX28_PAD_LCD_RESET__LCD_RESET
+ MX28_PAD_LCD_CS__LCD_ENABLE
+ MX28_PAD_AUART1_TX__GPIO_3_5
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ led_pins_gpio: leds-m28@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP3_MISO__GPIO_2_26
+ MX28_PAD_SSP3_SCK__GPIO_2_24
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+ };
+
+ ocotp@8002c000 {
+ status = "okay";
+ };
+
+ lcdif@80030000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcdif_24bit_pins_a
+ &lcdif_pins_m28>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display0 {
+ bits-per-pixel = <32>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <6410256>;
+ hactive = <320>;
+ vactive = <240>;
+ hback-porch = <38>;
+ hfront-porch = <20>;
+ vback-porch = <15>;
+ vfront-porch = <5>;
+ hsync-len = <30>;
+ vsync-len = <3>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+ };
+ };
+
+ apbx@80040000 {
+ duart: serial@80074000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&duart_pins_b>;
+ status = "okay";
+ };
+
+ usbphy1: usbphy@8007e000 {
+ status = "okay";
+ };
+
+ auart0: serial@8006a000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart0_2pins_a>;
+ status = "okay";
+ };
+
+ auart3: serial@80070000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart3_2pins_b>;
+ status = "okay";
+ };
+
+ pwm: pwm@80064000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_pins_a>;
+ status = "okay";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ usb1: usb@80090000 {
+ vbus-supply = <&reg_usb1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_pins_a>;
+ disable-over-current;
+ status = "okay";
+ };
+
+ mac0: ethernet@800f0000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac0_pins_a>;
+ phy-reset-gpios = <&gpio4 13 0>;
+ phy-reset-duration = <100>;
+ status = "okay";
+ };
+
+ mac1: ethernet@800f4000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac1_pins_a>;
+ status = "okay";
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 3 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_gpio>;
+
+ user1 {
+ label = "sd0-led";
+ gpios = <&gpio2 26 0>;
+ linux,default-trigger = "mmc0";
+ };
+
+ user2 {
+ label = "sd1-led";
+ gpios = <&gpio2 24 0>;
+ linux,default-trigger = "mmc2";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_vddio_sd0: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "vddio-sd0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 29 0>;
+ };
+
+ reg_vddio_sd1: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "vddio-sd1";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 19 0>;
+ };
+
+ reg_usb1_vbus: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 8 0>;
+ enable-active-high;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-m28evk.dts b/arch/arm/boot/dts/imx28-m28evk.dts
new file mode 100644
index 000000000..e35cc6ba3
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-m28evk.dts
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2012 Marek Vasut <marex@denx.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
+ */
+
+/dts-v1/;
+#include "imx28-m28.dtsi"
+
+/ {
+ model = "DENX M28EVK";
+ compatible = "denx,m28evk", "fsl,imx28";
+
+ apb@80000000 {
+ apbh@80000000 {
+ ssp0: ssp@80010000 {
+ compatible = "fsl,imx28-mmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_8bit_pins_a
+ &mmc0_cd_cfg
+ &mmc0_sck_cfg>;
+ bus-width = <8>;
+ wp-gpios = <&gpio3 10 0>;
+ vmmc-supply = <&reg_vddio_sd0>;
+ status = "okay";
+ };
+
+ ssp2: ssp@80014000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx28-spi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_pins_a>;
+ status = "okay";
+
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p80";
+ spi-max-frequency = <40000000>;
+ reg = <0>;
+ };
+ };
+
+ pinctrl@80018000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hog_pins_a>;
+
+ hog_pins_a: hog@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_PWM3__GPIO_3_28
+ MX28_PAD_AUART2_CTS__GPIO_3_10
+ MX28_PAD_AUART2_RTS__GPIO_3_11
+ MX28_PAD_AUART3_RX__GPIO_3_12
+ MX28_PAD_AUART3_TX__GPIO_3_13
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_pins_m28: lcdif-m28@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_DOTCLK__LCD_DOTCLK
+ MX28_PAD_LCD_ENABLE__LCD_ENABLE
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+ };
+
+ lcdif@80030000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcdif_24bit_pins_a
+ &lcdif_pins_m28>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display0 {
+ bits-per-pixel = <16>;
+ bus-width = <18>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <33260000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <0>;
+ hfront-porch = <256>;
+ vback-porch = <0>;
+ vfront-porch = <45>;
+ hsync-len = <1>;
+ vsync-len = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+ };
+
+ can0: can@80032000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&can0_pins_a>;
+ status = "okay";
+ };
+
+ can1: can@80034000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&can1_pins_a>;
+ status = "okay";
+ };
+ };
+
+ apbx@80040000 {
+ saif0: saif@80042000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&saif0_pins_a>;
+ status = "okay";
+ };
+
+ saif1: saif@80046000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&saif1_pins_a>;
+ fsl,saif-master = <&saif0>;
+ status = "okay";
+ };
+
+ i2c0: i2c@80058000 {
+ sgtl5000: codec@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ VDDA-supply = <&reg_3p3v>;
+ VDDIO-supply = <&reg_3p3v>;
+ clocks = <&saif0>;
+ };
+
+ eeprom: eeprom@51 {
+ compatible = "atmel,24c128";
+ reg = <0x51>;
+ pagesize = <32>;
+ };
+ };
+
+ lradc@80050000 {
+ status = "okay";
+ fsl,lradc-touchscreen-wires = <4>;
+ };
+
+ duart: serial@80074000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&duart_pins_a>;
+ status = "okay";
+ };
+
+ usbphy0: usbphy@8007c000 {
+ status = "okay";
+ };
+
+ usbphy1: usbphy@8007e000 {
+ status = "okay";
+ };
+
+ auart0: serial@8006a000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart0_pins_a>;
+ status = "okay";
+ };
+
+ auart1: serial@8006c000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart1_pins_a>;
+ status = "okay";
+ };
+
+ auart2: serial@8006e000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart2_2pins_b>;
+ status = "okay";
+ };
+
+ pwm: pwm@80064000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm4_pins_a>;
+ status = "okay";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ usb0: usb@80080000 {
+ vbus-supply = <&reg_usb0_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_pins_a>;
+ status = "okay";
+ };
+
+ usb1: usb@80090000 {
+ vbus-supply = <&reg_usb1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_pins_a>;
+ status = "okay";
+ };
+
+ mac0: ethernet@800f0000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac0_pins_a>;
+ clocks = <&clks 57>, <&clks 57>;
+ clock-names = "ipg", "ahb";
+ status = "okay";
+ };
+
+ mac1: ethernet@800f4000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac1_pins_a>;
+ status = "okay";
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 4 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
+ regulators {
+ reg_vddio_sd0: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "vddio-sd0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 28 0>;
+ };
+
+ reg_usb0_vbus: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "usb0_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 12 0>;
+ };
+
+ reg_usb1_vbus: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 13 0>;
+ };
+ };
+
+ sound {
+ compatible = "denx,m28evk-sgtl5000",
+ "fsl,mxs-audio-sgtl5000";
+ model = "m28evk-sgtl5000";
+ saif-controllers = <&saif0 &saif1>;
+ audio-codec = <&sgtl5000>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-pinfunc.h b/arch/arm/boot/dts/imx28-pinfunc.h
new file mode 100644
index 000000000..e11f69ba0
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-pinfunc.h
@@ -0,0 +1,506 @@
+/*
+ * Header providing constants for i.MX28 pinctrl bindings.
+ *
+ * Copyright (C) 2013 Lothar WaĂŸmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DT_BINDINGS_MX28_PINCTRL_H__
+#define __DT_BINDINGS_MX28_PINCTRL_H__
+
+#include "mxs-pinfunc.h"
+
+#define MX28_PAD_GPMI_D00__GPMI_D0 0x0000
+#define MX28_PAD_GPMI_D01__GPMI_D1 0x0010
+#define MX28_PAD_GPMI_D02__GPMI_D2 0x0020
+#define MX28_PAD_GPMI_D03__GPMI_D3 0x0030
+#define MX28_PAD_GPMI_D04__GPMI_D4 0x0040
+#define MX28_PAD_GPMI_D05__GPMI_D5 0x0050
+#define MX28_PAD_GPMI_D06__GPMI_D6 0x0060
+#define MX28_PAD_GPMI_D07__GPMI_D7 0x0070
+#define MX28_PAD_GPMI_CE0N__GPMI_CE0N 0x0100
+#define MX28_PAD_GPMI_CE1N__GPMI_CE1N 0x0110
+#define MX28_PAD_GPMI_CE2N__GPMI_CE2N 0x0120
+#define MX28_PAD_GPMI_CE3N__GPMI_CE3N 0x0130
+#define MX28_PAD_GPMI_RDY0__GPMI_READY0 0x0140
+#define MX28_PAD_GPMI_RDY1__GPMI_READY1 0x0150
+#define MX28_PAD_GPMI_RDY2__GPMI_READY2 0x0160
+#define MX28_PAD_GPMI_RDY3__GPMI_READY3 0x0170
+#define MX28_PAD_GPMI_RDN__GPMI_RDN 0x0180
+#define MX28_PAD_GPMI_WRN__GPMI_WRN 0x0190
+#define MX28_PAD_GPMI_ALE__GPMI_ALE 0x01a0
+#define MX28_PAD_GPMI_CLE__GPMI_CLE 0x01b0
+#define MX28_PAD_GPMI_RESETN__GPMI_RESETN 0x01c0
+#define MX28_PAD_LCD_D00__LCD_D0 0x1000
+#define MX28_PAD_LCD_D01__LCD_D1 0x1010
+#define MX28_PAD_LCD_D02__LCD_D2 0x1020
+#define MX28_PAD_LCD_D03__LCD_D3 0x1030
+#define MX28_PAD_LCD_D04__LCD_D4 0x1040
+#define MX28_PAD_LCD_D05__LCD_D5 0x1050
+#define MX28_PAD_LCD_D06__LCD_D6 0x1060
+#define MX28_PAD_LCD_D07__LCD_D7 0x1070
+#define MX28_PAD_LCD_D08__LCD_D8 0x1080
+#define MX28_PAD_LCD_D09__LCD_D9 0x1090
+#define MX28_PAD_LCD_D10__LCD_D10 0x10a0
+#define MX28_PAD_LCD_D11__LCD_D11 0x10b0
+#define MX28_PAD_LCD_D12__LCD_D12 0x10c0
+#define MX28_PAD_LCD_D13__LCD_D13 0x10d0
+#define MX28_PAD_LCD_D14__LCD_D14 0x10e0
+#define MX28_PAD_LCD_D15__LCD_D15 0x10f0
+#define MX28_PAD_LCD_D16__LCD_D16 0x1100
+#define MX28_PAD_LCD_D17__LCD_D17 0x1110
+#define MX28_PAD_LCD_D18__LCD_D18 0x1120
+#define MX28_PAD_LCD_D19__LCD_D19 0x1130
+#define MX28_PAD_LCD_D20__LCD_D20 0x1140
+#define MX28_PAD_LCD_D21__LCD_D21 0x1150
+#define MX28_PAD_LCD_D22__LCD_D22 0x1160
+#define MX28_PAD_LCD_D23__LCD_D23 0x1170
+#define MX28_PAD_LCD_RD_E__LCD_RD_E 0x1180
+#define MX28_PAD_LCD_WR_RWN__LCD_WR_RWN 0x1190
+#define MX28_PAD_LCD_RS__LCD_RS 0x11a0
+#define MX28_PAD_LCD_CS__LCD_CS 0x11b0
+#define MX28_PAD_LCD_VSYNC__LCD_VSYNC 0x11c0
+#define MX28_PAD_LCD_HSYNC__LCD_HSYNC 0x11d0
+#define MX28_PAD_LCD_DOTCLK__LCD_DOTCLK 0x11e0
+#define MX28_PAD_LCD_ENABLE__LCD_ENABLE 0x11f0
+#define MX28_PAD_SSP0_DATA0__SSP0_D0 0x2000
+#define MX28_PAD_SSP0_DATA1__SSP0_D1 0x2010
+#define MX28_PAD_SSP0_DATA2__SSP0_D2 0x2020
+#define MX28_PAD_SSP0_DATA3__SSP0_D3 0x2030
+#define MX28_PAD_SSP0_DATA4__SSP0_D4 0x2040
+#define MX28_PAD_SSP0_DATA5__SSP0_D5 0x2050
+#define MX28_PAD_SSP0_DATA6__SSP0_D6 0x2060
+#define MX28_PAD_SSP0_DATA7__SSP0_D7 0x2070
+#define MX28_PAD_SSP0_CMD__SSP0_CMD 0x2080
+#define MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT 0x2090
+#define MX28_PAD_SSP0_SCK__SSP0_SCK 0x20a0
+#define MX28_PAD_SSP1_SCK__SSP1_SCK 0x20c0
+#define MX28_PAD_SSP1_CMD__SSP1_CMD 0x20d0
+#define MX28_PAD_SSP1_DATA0__SSP1_D0 0x20e0
+#define MX28_PAD_SSP1_DATA3__SSP1_D3 0x20f0
+#define MX28_PAD_SSP2_SCK__SSP2_SCK 0x2100
+#define MX28_PAD_SSP2_MOSI__SSP2_CMD 0x2110
+#define MX28_PAD_SSP2_MISO__SSP2_D0 0x2120
+#define MX28_PAD_SSP2_SS0__SSP2_D3 0x2130
+#define MX28_PAD_SSP2_SS1__SSP2_D4 0x2140
+#define MX28_PAD_SSP2_SS2__SSP2_D5 0x2150
+#define MX28_PAD_SSP3_SCK__SSP3_SCK 0x2180
+#define MX28_PAD_SSP3_MOSI__SSP3_CMD 0x2190
+#define MX28_PAD_SSP3_MISO__SSP3_D0 0x21a0
+#define MX28_PAD_SSP3_SS0__SSP3_D3 0x21b0
+#define MX28_PAD_AUART0_RX__AUART0_RX 0x3000
+#define MX28_PAD_AUART0_TX__AUART0_TX 0x3010
+#define MX28_PAD_AUART0_CTS__AUART0_CTS 0x3020
+#define MX28_PAD_AUART0_RTS__AUART0_RTS 0x3030
+#define MX28_PAD_AUART1_RX__AUART1_RX 0x3040
+#define MX28_PAD_AUART1_TX__AUART1_TX 0x3050
+#define MX28_PAD_AUART1_CTS__AUART1_CTS 0x3060
+#define MX28_PAD_AUART1_RTS__AUART1_RTS 0x3070
+#define MX28_PAD_AUART2_RX__AUART2_RX 0x3080
+#define MX28_PAD_AUART2_TX__AUART2_TX 0x3090
+#define MX28_PAD_AUART2_CTS__AUART2_CTS 0x30a0
+#define MX28_PAD_AUART2_RTS__AUART2_RTS 0x30b0
+#define MX28_PAD_AUART3_RX__AUART3_RX 0x30c0
+#define MX28_PAD_AUART3_TX__AUART3_TX 0x30d0
+#define MX28_PAD_AUART3_CTS__AUART3_CTS 0x30e0
+#define MX28_PAD_AUART3_RTS__AUART3_RTS 0x30f0
+#define MX28_PAD_PWM0__PWM_0 0x3100
+#define MX28_PAD_PWM1__PWM_1 0x3110
+#define MX28_PAD_PWM2__PWM_2 0x3120
+#define MX28_PAD_SAIF0_MCLK__SAIF0_MCLK 0x3140
+#define MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK 0x3150
+#define MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK 0x3160
+#define MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0 0x3170
+#define MX28_PAD_I2C0_SCL__I2C0_SCL 0x3180
+#define MX28_PAD_I2C0_SDA__I2C0_SDA 0x3190
+#define MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0 0x31a0
+#define MX28_PAD_SPDIF__SPDIF_TX 0x31b0
+#define MX28_PAD_PWM3__PWM_3 0x31c0
+#define MX28_PAD_PWM4__PWM_4 0x31d0
+#define MX28_PAD_LCD_RESET__LCD_RESET 0x31e0
+#define MX28_PAD_ENET0_MDC__ENET0_MDC 0x4000
+#define MX28_PAD_ENET0_MDIO__ENET0_MDIO 0x4010
+#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN 0x4020
+#define MX28_PAD_ENET0_RXD0__ENET0_RXD0 0x4030
+#define MX28_PAD_ENET0_RXD1__ENET0_RXD1 0x4040
+#define MX28_PAD_ENET0_TX_CLK__ENET0_TX_CLK 0x4050
+#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN 0x4060
+#define MX28_PAD_ENET0_TXD0__ENET0_TXD0 0x4070
+#define MX28_PAD_ENET0_TXD1__ENET0_TXD1 0x4080
+#define MX28_PAD_ENET0_RXD2__ENET0_RXD2 0x4090
+#define MX28_PAD_ENET0_RXD3__ENET0_RXD3 0x40a0
+#define MX28_PAD_ENET0_TXD2__ENET0_TXD2 0x40b0
+#define MX28_PAD_ENET0_TXD3__ENET0_TXD3 0x40c0
+#define MX28_PAD_ENET0_RX_CLK__ENET0_RX_CLK 0x40d0
+#define MX28_PAD_ENET0_COL__ENET0_COL 0x40e0
+#define MX28_PAD_ENET0_CRS__ENET0_CRS 0x40f0
+#define MX28_PAD_ENET_CLK__CLKCTRL_ENET 0x4100
+#define MX28_PAD_JTAG_RTCK__JTAG_RTCK 0x4140
+#define MX28_PAD_EMI_D00__EMI_DATA0 0x5000
+#define MX28_PAD_EMI_D01__EMI_DATA1 0x5010
+#define MX28_PAD_EMI_D02__EMI_DATA2 0x5020
+#define MX28_PAD_EMI_D03__EMI_DATA3 0x5030
+#define MX28_PAD_EMI_D04__EMI_DATA4 0x5040
+#define MX28_PAD_EMI_D05__EMI_DATA5 0x5050
+#define MX28_PAD_EMI_D06__EMI_DATA6 0x5060
+#define MX28_PAD_EMI_D07__EMI_DATA7 0x5070
+#define MX28_PAD_EMI_D08__EMI_DATA8 0x5080
+#define MX28_PAD_EMI_D09__EMI_DATA9 0x5090
+#define MX28_PAD_EMI_D10__EMI_DATA10 0x50a0
+#define MX28_PAD_EMI_D11__EMI_DATA11 0x50b0
+#define MX28_PAD_EMI_D12__EMI_DATA12 0x50c0
+#define MX28_PAD_EMI_D13__EMI_DATA13 0x50d0
+#define MX28_PAD_EMI_D14__EMI_DATA14 0x50e0
+#define MX28_PAD_EMI_D15__EMI_DATA15 0x50f0
+#define MX28_PAD_EMI_ODT0__EMI_ODT0 0x5100
+#define MX28_PAD_EMI_DQM0__EMI_DQM0 0x5110
+#define MX28_PAD_EMI_ODT1__EMI_ODT1 0x5120
+#define MX28_PAD_EMI_DQM1__EMI_DQM1 0x5130
+#define MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK 0x5140
+#define MX28_PAD_EMI_CLK__EMI_CLK 0x5150
+#define MX28_PAD_EMI_DQS0__EMI_DQS0 0x5160
+#define MX28_PAD_EMI_DQS1__EMI_DQS1 0x5170
+#define MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN 0x51a0
+#define MX28_PAD_EMI_A00__EMI_ADDR0 0x6000
+#define MX28_PAD_EMI_A01__EMI_ADDR1 0x6010
+#define MX28_PAD_EMI_A02__EMI_ADDR2 0x6020
+#define MX28_PAD_EMI_A03__EMI_ADDR3 0x6030
+#define MX28_PAD_EMI_A04__EMI_ADDR4 0x6040
+#define MX28_PAD_EMI_A05__EMI_ADDR5 0x6050
+#define MX28_PAD_EMI_A06__EMI_ADDR6 0x6060
+#define MX28_PAD_EMI_A07__EMI_ADDR7 0x6070
+#define MX28_PAD_EMI_A08__EMI_ADDR8 0x6080
+#define MX28_PAD_EMI_A09__EMI_ADDR9 0x6090
+#define MX28_PAD_EMI_A10__EMI_ADDR10 0x60a0
+#define MX28_PAD_EMI_A11__EMI_ADDR11 0x60b0
+#define MX28_PAD_EMI_A12__EMI_ADDR12 0x60c0
+#define MX28_PAD_EMI_A13__EMI_ADDR13 0x60d0
+#define MX28_PAD_EMI_A14__EMI_ADDR14 0x60e0
+#define MX28_PAD_EMI_BA0__EMI_BA0 0x6100
+#define MX28_PAD_EMI_BA1__EMI_BA1 0x6110
+#define MX28_PAD_EMI_BA2__EMI_BA2 0x6120
+#define MX28_PAD_EMI_CASN__EMI_CASN 0x6130
+#define MX28_PAD_EMI_RASN__EMI_RASN 0x6140
+#define MX28_PAD_EMI_WEN__EMI_WEN 0x6150
+#define MX28_PAD_EMI_CE0N__EMI_CE0N 0x6160
+#define MX28_PAD_EMI_CE1N__EMI_CE1N 0x6170
+#define MX28_PAD_EMI_CKE__EMI_CKE 0x6180
+#define MX28_PAD_GPMI_D00__SSP1_D0 0x0001
+#define MX28_PAD_GPMI_D01__SSP1_D1 0x0011
+#define MX28_PAD_GPMI_D02__SSP1_D2 0x0021
+#define MX28_PAD_GPMI_D03__SSP1_D3 0x0031
+#define MX28_PAD_GPMI_D04__SSP1_D4 0x0041
+#define MX28_PAD_GPMI_D05__SSP1_D5 0x0051
+#define MX28_PAD_GPMI_D06__SSP1_D6 0x0061
+#define MX28_PAD_GPMI_D07__SSP1_D7 0x0071
+#define MX28_PAD_GPMI_CE0N__SSP3_D0 0x0101
+#define MX28_PAD_GPMI_CE1N__SSP3_D3 0x0111
+#define MX28_PAD_GPMI_CE2N__CAN1_TX 0x0121
+#define MX28_PAD_GPMI_CE3N__CAN1_RX 0x0131
+#define MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT 0x0141
+#define MX28_PAD_GPMI_RDY1__SSP1_CMD 0x0151
+#define MX28_PAD_GPMI_RDY2__CAN0_TX 0x0161
+#define MX28_PAD_GPMI_RDY3__CAN0_RX 0x0171
+#define MX28_PAD_GPMI_RDN__SSP3_SCK 0x0181
+#define MX28_PAD_GPMI_WRN__SSP1_SCK 0x0191
+#define MX28_PAD_GPMI_ALE__SSP3_D1 0x01a1
+#define MX28_PAD_GPMI_CLE__SSP3_D2 0x01b1
+#define MX28_PAD_GPMI_RESETN__SSP3_CMD 0x01c1
+#define MX28_PAD_LCD_D03__ETM_DA8 0x1031
+#define MX28_PAD_LCD_D04__ETM_DA9 0x1041
+#define MX28_PAD_LCD_D08__ETM_DA3 0x1081
+#define MX28_PAD_LCD_D09__ETM_DA4 0x1091
+#define MX28_PAD_LCD_D20__ENET1_1588_EVENT2_OUT 0x1141
+#define MX28_PAD_LCD_D21__ENET1_1588_EVENT2_IN 0x1151
+#define MX28_PAD_LCD_D22__ENET1_1588_EVENT3_OUT 0x1161
+#define MX28_PAD_LCD_D23__ENET1_1588_EVENT3_IN 0x1171
+#define MX28_PAD_LCD_RD_E__LCD_VSYNC 0x1181
+#define MX28_PAD_LCD_WR_RWN__LCD_HSYNC 0x1191
+#define MX28_PAD_LCD_RS__LCD_DOTCLK 0x11a1
+#define MX28_PAD_LCD_CS__LCD_ENABLE 0x11b1
+#define MX28_PAD_LCD_VSYNC__SAIF1_SDATA0 0x11c1
+#define MX28_PAD_LCD_HSYNC__SAIF1_SDATA1 0x11d1
+#define MX28_PAD_LCD_DOTCLK__SAIF1_MCLK 0x11e1
+#define MX28_PAD_SSP0_DATA4__SSP2_D0 0x2041
+#define MX28_PAD_SSP0_DATA5__SSP2_D3 0x2051
+#define MX28_PAD_SSP0_DATA6__SSP2_CMD 0x2061
+#define MX28_PAD_SSP0_DATA7__SSP2_SCK 0x2071
+#define MX28_PAD_SSP1_SCK__SSP2_D1 0x20c1
+#define MX28_PAD_SSP1_CMD__SSP2_D2 0x20d1
+#define MX28_PAD_SSP1_DATA0__SSP2_D6 0x20e1
+#define MX28_PAD_SSP1_DATA3__SSP2_D7 0x20f1
+#define MX28_PAD_SSP2_SCK__AUART2_RX 0x2101
+#define MX28_PAD_SSP2_MOSI__AUART2_TX 0x2111
+#define MX28_PAD_SSP2_MISO__AUART3_RX 0x2121
+#define MX28_PAD_SSP2_SS0__AUART3_TX 0x2131
+#define MX28_PAD_SSP2_SS1__SSP2_D1 0x2141
+#define MX28_PAD_SSP2_SS2__SSP2_D2 0x2151
+#define MX28_PAD_SSP3_SCK__AUART4_TX 0x2181
+#define MX28_PAD_SSP3_MOSI__AUART4_RX 0x2191
+#define MX28_PAD_SSP3_MISO__AUART4_RTS 0x21a1
+#define MX28_PAD_SSP3_SS0__AUART4_CTS 0x21b1
+#define MX28_PAD_AUART0_RX__I2C0_SCL 0x3001
+#define MX28_PAD_AUART0_TX__I2C0_SDA 0x3011
+#define MX28_PAD_AUART0_CTS__AUART4_RX 0x3021
+#define MX28_PAD_AUART0_RTS__AUART4_TX 0x3031
+#define MX28_PAD_AUART1_RX__SSP2_CARD_DETECT 0x3041
+#define MX28_PAD_AUART1_TX__SSP3_CARD_DETECT 0x3051
+#define MX28_PAD_AUART1_CTS__USB0_OVERCURRENT 0x3061
+#define MX28_PAD_AUART1_RTS__USB0_ID 0x3071
+#define MX28_PAD_AUART2_RX__SSP3_D1 0x3081
+#define MX28_PAD_AUART2_TX__SSP3_D2 0x3091
+#define MX28_PAD_AUART2_CTS__I2C1_SCL 0x30a1
+#define MX28_PAD_AUART2_RTS__I2C1_SDA 0x30b1
+#define MX28_PAD_AUART3_RX__CAN0_TX 0x30c1
+#define MX28_PAD_AUART3_TX__CAN0_RX 0x30d1
+#define MX28_PAD_AUART3_CTS__CAN1_TX 0x30e1
+#define MX28_PAD_AUART3_RTS__CAN1_RX 0x30f1
+#define MX28_PAD_PWM0__I2C1_SCL 0x3101
+#define MX28_PAD_PWM1__I2C1_SDA 0x3111
+#define MX28_PAD_PWM2__USB0_ID 0x3121
+#define MX28_PAD_SAIF0_MCLK__PWM_3 0x3141
+#define MX28_PAD_SAIF0_LRCLK__PWM_4 0x3151
+#define MX28_PAD_SAIF0_BITCLK__PWM_5 0x3161
+#define MX28_PAD_SAIF0_SDATA0__PWM_6 0x3171
+#define MX28_PAD_I2C0_SCL__TIMROT_ROTARYA 0x3181
+#define MX28_PAD_I2C0_SDA__TIMROT_ROTARYB 0x3191
+#define MX28_PAD_SAIF1_SDATA0__PWM_7 0x31a1
+#define MX28_PAD_LCD_RESET__LCD_VSYNC 0x31e1
+#define MX28_PAD_ENET0_MDC__GPMI_CE4N 0x4001
+#define MX28_PAD_ENET0_MDIO__GPMI_CE5N 0x4011
+#define MX28_PAD_ENET0_RX_EN__GPMI_CE6N 0x4021
+#define MX28_PAD_ENET0_RXD0__GPMI_CE7N 0x4031
+#define MX28_PAD_ENET0_RXD1__GPMI_READY4 0x4041
+#define MX28_PAD_ENET0_TX_CLK__HSADC_TRIGGER 0x4051
+#define MX28_PAD_ENET0_TX_EN__GPMI_READY5 0x4061
+#define MX28_PAD_ENET0_TXD0__GPMI_READY6 0x4071
+#define MX28_PAD_ENET0_TXD1__GPMI_READY7 0x4081
+#define MX28_PAD_ENET0_RXD2__ENET1_RXD0 0x4091
+#define MX28_PAD_ENET0_RXD3__ENET1_RXD1 0x40a1
+#define MX28_PAD_ENET0_TXD2__ENET1_TXD0 0x40b1
+#define MX28_PAD_ENET0_TXD3__ENET1_TXD1 0x40c1
+#define MX28_PAD_ENET0_RX_CLK__ENET0_RX_ER 0x40d1
+#define MX28_PAD_ENET0_COL__ENET1_TX_EN 0x40e1
+#define MX28_PAD_ENET0_CRS__ENET1_RX_EN 0x40f1
+#define MX28_PAD_GPMI_CE2N__ENET0_RX_ER 0x0122
+#define MX28_PAD_GPMI_CE3N__SAIF1_MCLK 0x0132
+#define MX28_PAD_GPMI_RDY0__USB0_ID 0x0142
+#define MX28_PAD_GPMI_RDY2__ENET0_TX_ER 0x0162
+#define MX28_PAD_GPMI_RDY3__HSADC_TRIGGER 0x0172
+#define MX28_PAD_GPMI_ALE__SSP3_D4 0x01a2
+#define MX28_PAD_GPMI_CLE__SSP3_D5 0x01b2
+#define MX28_PAD_LCD_D00__ETM_DA0 0x1002
+#define MX28_PAD_LCD_D01__ETM_DA1 0x1012
+#define MX28_PAD_LCD_D02__ETM_DA2 0x1022
+#define MX28_PAD_LCD_D03__ETM_DA3 0x1032
+#define MX28_PAD_LCD_D04__ETM_DA4 0x1042
+#define MX28_PAD_LCD_D05__ETM_DA5 0x1052
+#define MX28_PAD_LCD_D06__ETM_DA6 0x1062
+#define MX28_PAD_LCD_D07__ETM_DA7 0x1072
+#define MX28_PAD_LCD_D08__ETM_DA8 0x1082
+#define MX28_PAD_LCD_D09__ETM_DA9 0x1092
+#define MX28_PAD_LCD_D10__ETM_DA10 0x10a2
+#define MX28_PAD_LCD_D11__ETM_DA11 0x10b2
+#define MX28_PAD_LCD_D12__ETM_DA12 0x10c2
+#define MX28_PAD_LCD_D13__ETM_DA13 0x10d2
+#define MX28_PAD_LCD_D14__ETM_DA14 0x10e2
+#define MX28_PAD_LCD_D15__ETM_DA15 0x10f2
+#define MX28_PAD_LCD_D16__ETM_DA7 0x1102
+#define MX28_PAD_LCD_D17__ETM_DA6 0x1112
+#define MX28_PAD_LCD_D18__ETM_DA5 0x1122
+#define MX28_PAD_LCD_D19__ETM_DA4 0x1132
+#define MX28_PAD_LCD_D20__ETM_DA3 0x1142
+#define MX28_PAD_LCD_D21__ETM_DA2 0x1152
+#define MX28_PAD_LCD_D22__ETM_DA1 0x1162
+#define MX28_PAD_LCD_D23__ETM_DA0 0x1172
+#define MX28_PAD_LCD_RD_E__ETM_TCTL 0x1182
+#define MX28_PAD_LCD_WR_RWN__ETM_TCLK 0x1192
+#define MX28_PAD_LCD_HSYNC__ETM_TCTL 0x11d2
+#define MX28_PAD_LCD_DOTCLK__ETM_TCLK 0x11e2
+#define MX28_PAD_SSP1_SCK__ENET0_1588_EVENT2_OUT 0x20c2
+#define MX28_PAD_SSP1_CMD__ENET0_1588_EVENT2_IN 0x20d2
+#define MX28_PAD_SSP1_DATA0__ENET0_1588_EVENT3_OUT 0x20e2
+#define MX28_PAD_SSP1_DATA3__ENET0_1588_EVENT3_IN 0x20f2
+#define MX28_PAD_SSP2_SCK__SAIF0_SDATA1 0x2102
+#define MX28_PAD_SSP2_MOSI__SAIF0_SDATA2 0x2112
+#define MX28_PAD_SSP2_MISO__SAIF1_SDATA1 0x2122
+#define MX28_PAD_SSP2_SS0__SAIF1_SDATA2 0x2132
+#define MX28_PAD_SSP2_SS1__USB1_OVERCURRENT 0x2142
+#define MX28_PAD_SSP2_SS2__USB0_OVERCURRENT 0x2152
+#define MX28_PAD_SSP3_SCK__ENET1_1588_EVENT0_OUT 0x2182
+#define MX28_PAD_SSP3_MOSI__ENET1_1588_EVENT0_IN 0x2192
+#define MX28_PAD_SSP3_MISO__ENET1_1588_EVENT1_OUT 0x21a2
+#define MX28_PAD_SSP3_SS0__ENET1_1588_EVENT1_IN 0x21b2
+#define MX28_PAD_AUART0_RX__DUART_CTS 0x3002
+#define MX28_PAD_AUART0_TX__DUART_RTS 0x3012
+#define MX28_PAD_AUART0_CTS__DUART_RX 0x3022
+#define MX28_PAD_AUART0_RTS__DUART_TX 0x3032
+#define MX28_PAD_AUART1_RX__PWM_0 0x3042
+#define MX28_PAD_AUART1_TX__PWM_1 0x3052
+#define MX28_PAD_AUART1_CTS__TIMROT_ROTARYA 0x3062
+#define MX28_PAD_AUART1_RTS__TIMROT_ROTARYB 0x3072
+#define MX28_PAD_AUART2_RX__SSP3_D4 0x3082
+#define MX28_PAD_AUART2_TX__SSP3_D5 0x3092
+#define MX28_PAD_AUART2_CTS__SAIF1_BITCLK 0x30a2
+#define MX28_PAD_AUART2_RTS__SAIF1_LRCLK 0x30b2
+#define MX28_PAD_AUART3_RX__ENET0_1588_EVENT0_OUT 0x30c2
+#define MX28_PAD_AUART3_TX__ENET0_1588_EVENT0_IN 0x30d2
+#define MX28_PAD_AUART3_CTS__ENET0_1588_EVENT1_OUT 0x30e2
+#define MX28_PAD_AUART3_RTS__ENET0_1588_EVENT1_IN 0x30f2
+#define MX28_PAD_PWM0__DUART_RX 0x3102
+#define MX28_PAD_PWM1__DUART_TX 0x3112
+#define MX28_PAD_PWM2__USB1_OVERCURRENT 0x3122
+#define MX28_PAD_SAIF0_MCLK__AUART4_CTS 0x3142
+#define MX28_PAD_SAIF0_LRCLK__AUART4_RTS 0x3152
+#define MX28_PAD_SAIF0_BITCLK__AUART4_RX 0x3162
+#define MX28_PAD_SAIF0_SDATA0__AUART4_TX 0x3172
+#define MX28_PAD_I2C0_SCL__DUART_RX 0x3182
+#define MX28_PAD_I2C0_SDA__DUART_TX 0x3192
+#define MX28_PAD_SAIF1_SDATA0__SAIF0_SDATA1 0x31a2
+#define MX28_PAD_SPDIF__ENET1_RX_ER 0x31b2
+#define MX28_PAD_ENET0_MDC__SAIF0_SDATA1 0x4002
+#define MX28_PAD_ENET0_MDIO__SAIF0_SDATA2 0x4012
+#define MX28_PAD_ENET0_RX_EN__SAIF1_SDATA1 0x4022
+#define MX28_PAD_ENET0_RXD0__SAIF1_SDATA2 0x4032
+#define MX28_PAD_ENET0_TX_CLK__ENET0_1588_EVENT2_OUT 0x4052
+#define MX28_PAD_ENET0_RXD2__ENET0_1588_EVENT0_OUT 0x4092
+#define MX28_PAD_ENET0_RXD3__ENET0_1588_EVENT0_IN 0x40a2
+#define MX28_PAD_ENET0_TXD2__ENET0_1588_EVENT1_OUT 0x40b2
+#define MX28_PAD_ENET0_TXD3__ENET0_1588_EVENT1_IN 0x40c2
+#define MX28_PAD_ENET0_RX_CLK__ENET0_1588_EVENT2_IN 0x40d2
+#define MX28_PAD_ENET0_COL__ENET0_1588_EVENT3_OUT 0x40e2
+#define MX28_PAD_ENET0_CRS__ENET0_1588_EVENT3_IN 0x40f2
+#define MX28_PAD_GPMI_D00__GPIO_0_0 0x0003
+#define MX28_PAD_GPMI_D01__GPIO_0_1 0x0013
+#define MX28_PAD_GPMI_D02__GPIO_0_2 0x0023
+#define MX28_PAD_GPMI_D03__GPIO_0_3 0x0033
+#define MX28_PAD_GPMI_D04__GPIO_0_4 0x0043
+#define MX28_PAD_GPMI_D05__GPIO_0_5 0x0053
+#define MX28_PAD_GPMI_D06__GPIO_0_6 0x0063
+#define MX28_PAD_GPMI_D07__GPIO_0_7 0x0073
+#define MX28_PAD_GPMI_CE0N__GPIO_0_16 0x0103
+#define MX28_PAD_GPMI_CE1N__GPIO_0_17 0x0113
+#define MX28_PAD_GPMI_CE2N__GPIO_0_18 0x0123
+#define MX28_PAD_GPMI_CE3N__GPIO_0_19 0x0133
+#define MX28_PAD_GPMI_RDY0__GPIO_0_20 0x0143
+#define MX28_PAD_GPMI_RDY1__GPIO_0_21 0x0153
+#define MX28_PAD_GPMI_RDY2__GPIO_0_22 0x0163
+#define MX28_PAD_GPMI_RDY3__GPIO_0_23 0x0173
+#define MX28_PAD_GPMI_RDN__GPIO_0_24 0x0183
+#define MX28_PAD_GPMI_WRN__GPIO_0_25 0x0193
+#define MX28_PAD_GPMI_ALE__GPIO_0_26 0x01a3
+#define MX28_PAD_GPMI_CLE__GPIO_0_27 0x01b3
+#define MX28_PAD_GPMI_RESETN__GPIO_0_28 0x01c3
+#define MX28_PAD_LCD_D00__GPIO_1_0 0x1003
+#define MX28_PAD_LCD_D01__GPIO_1_1 0x1013
+#define MX28_PAD_LCD_D02__GPIO_1_2 0x1023
+#define MX28_PAD_LCD_D03__GPIO_1_3 0x1033
+#define MX28_PAD_LCD_D04__GPIO_1_4 0x1043
+#define MX28_PAD_LCD_D05__GPIO_1_5 0x1053
+#define MX28_PAD_LCD_D06__GPIO_1_6 0x1063
+#define MX28_PAD_LCD_D07__GPIO_1_7 0x1073
+#define MX28_PAD_LCD_D08__GPIO_1_8 0x1083
+#define MX28_PAD_LCD_D09__GPIO_1_9 0x1093
+#define MX28_PAD_LCD_D10__GPIO_1_10 0x10a3
+#define MX28_PAD_LCD_D11__GPIO_1_11 0x10b3
+#define MX28_PAD_LCD_D12__GPIO_1_12 0x10c3
+#define MX28_PAD_LCD_D13__GPIO_1_13 0x10d3
+#define MX28_PAD_LCD_D14__GPIO_1_14 0x10e3
+#define MX28_PAD_LCD_D15__GPIO_1_15 0x10f3
+#define MX28_PAD_LCD_D16__GPIO_1_16 0x1103
+#define MX28_PAD_LCD_D17__GPIO_1_17 0x1113
+#define MX28_PAD_LCD_D18__GPIO_1_18 0x1123
+#define MX28_PAD_LCD_D19__GPIO_1_19 0x1133
+#define MX28_PAD_LCD_D20__GPIO_1_20 0x1143
+#define MX28_PAD_LCD_D21__GPIO_1_21 0x1153
+#define MX28_PAD_LCD_D22__GPIO_1_22 0x1163
+#define MX28_PAD_LCD_D23__GPIO_1_23 0x1173
+#define MX28_PAD_LCD_RD_E__GPIO_1_24 0x1183
+#define MX28_PAD_LCD_WR_RWN__GPIO_1_25 0x1193
+#define MX28_PAD_LCD_RS__GPIO_1_26 0x11a3
+#define MX28_PAD_LCD_CS__GPIO_1_27 0x11b3
+#define MX28_PAD_LCD_VSYNC__GPIO_1_28 0x11c3
+#define MX28_PAD_LCD_HSYNC__GPIO_1_29 0x11d3
+#define MX28_PAD_LCD_DOTCLK__GPIO_1_30 0x11e3
+#define MX28_PAD_LCD_ENABLE__GPIO_1_31 0x11f3
+#define MX28_PAD_SSP0_DATA0__GPIO_2_0 0x2003
+#define MX28_PAD_SSP0_DATA1__GPIO_2_1 0x2013
+#define MX28_PAD_SSP0_DATA2__GPIO_2_2 0x2023
+#define MX28_PAD_SSP0_DATA3__GPIO_2_3 0x2033
+#define MX28_PAD_SSP0_DATA4__GPIO_2_4 0x2043
+#define MX28_PAD_SSP0_DATA5__GPIO_2_5 0x2053
+#define MX28_PAD_SSP0_DATA6__GPIO_2_6 0x2063
+#define MX28_PAD_SSP0_DATA7__GPIO_2_7 0x2073
+#define MX28_PAD_SSP0_CMD__GPIO_2_8 0x2083
+#define MX28_PAD_SSP0_DETECT__GPIO_2_9 0x2093
+#define MX28_PAD_SSP0_SCK__GPIO_2_10 0x20a3
+#define MX28_PAD_SSP1_SCK__GPIO_2_12 0x20c3
+#define MX28_PAD_SSP1_CMD__GPIO_2_13 0x20d3
+#define MX28_PAD_SSP1_DATA0__GPIO_2_14 0x20e3
+#define MX28_PAD_SSP1_DATA3__GPIO_2_15 0x20f3
+#define MX28_PAD_SSP2_SCK__GPIO_2_16 0x2103
+#define MX28_PAD_SSP2_MOSI__GPIO_2_17 0x2113
+#define MX28_PAD_SSP2_MISO__GPIO_2_18 0x2123
+#define MX28_PAD_SSP2_SS0__GPIO_2_19 0x2133
+#define MX28_PAD_SSP2_SS1__GPIO_2_20 0x2143
+#define MX28_PAD_SSP2_SS2__GPIO_2_21 0x2153
+#define MX28_PAD_SSP3_SCK__GPIO_2_24 0x2183
+#define MX28_PAD_SSP3_MOSI__GPIO_2_25 0x2193
+#define MX28_PAD_SSP3_MISO__GPIO_2_26 0x21a3
+#define MX28_PAD_SSP3_SS0__GPIO_2_27 0x21b3
+#define MX28_PAD_AUART0_RX__GPIO_3_0 0x3003
+#define MX28_PAD_AUART0_TX__GPIO_3_1 0x3013
+#define MX28_PAD_AUART0_CTS__GPIO_3_2 0x3023
+#define MX28_PAD_AUART0_RTS__GPIO_3_3 0x3033
+#define MX28_PAD_AUART1_RX__GPIO_3_4 0x3043
+#define MX28_PAD_AUART1_TX__GPIO_3_5 0x3053
+#define MX28_PAD_AUART1_CTS__GPIO_3_6 0x3063
+#define MX28_PAD_AUART1_RTS__GPIO_3_7 0x3073
+#define MX28_PAD_AUART2_RX__GPIO_3_8 0x3083
+#define MX28_PAD_AUART2_TX__GPIO_3_9 0x3093
+#define MX28_PAD_AUART2_CTS__GPIO_3_10 0x30a3
+#define MX28_PAD_AUART2_RTS__GPIO_3_11 0x30b3
+#define MX28_PAD_AUART3_RX__GPIO_3_12 0x30c3
+#define MX28_PAD_AUART3_TX__GPIO_3_13 0x30d3
+#define MX28_PAD_AUART3_CTS__GPIO_3_14 0x30e3
+#define MX28_PAD_AUART3_RTS__GPIO_3_15 0x30f3
+#define MX28_PAD_PWM0__GPIO_3_16 0x3103
+#define MX28_PAD_PWM1__GPIO_3_17 0x3113
+#define MX28_PAD_PWM2__GPIO_3_18 0x3123
+#define MX28_PAD_SAIF0_MCLK__GPIO_3_20 0x3143
+#define MX28_PAD_SAIF0_LRCLK__GPIO_3_21 0x3153
+#define MX28_PAD_SAIF0_BITCLK__GPIO_3_22 0x3163
+#define MX28_PAD_SAIF0_SDATA0__GPIO_3_23 0x3173
+#define MX28_PAD_I2C0_SCL__GPIO_3_24 0x3183
+#define MX28_PAD_I2C0_SDA__GPIO_3_25 0x3193
+#define MX28_PAD_SAIF1_SDATA0__GPIO_3_26 0x31a3
+#define MX28_PAD_SPDIF__GPIO_3_27 0x31b3
+#define MX28_PAD_PWM3__GPIO_3_28 0x31c3
+#define MX28_PAD_PWM4__GPIO_3_29 0x31d3
+#define MX28_PAD_LCD_RESET__GPIO_3_30 0x31e3
+#define MX28_PAD_ENET0_MDC__GPIO_4_0 0x4003
+#define MX28_PAD_ENET0_MDIO__GPIO_4_1 0x4013
+#define MX28_PAD_ENET0_RX_EN__GPIO_4_2 0x4023
+#define MX28_PAD_ENET0_RXD0__GPIO_4_3 0x4033
+#define MX28_PAD_ENET0_RXD1__GPIO_4_4 0x4043
+#define MX28_PAD_ENET0_TX_CLK__GPIO_4_5 0x4053
+#define MX28_PAD_ENET0_TX_EN__GPIO_4_6 0x4063
+#define MX28_PAD_ENET0_TXD0__GPIO_4_7 0x4073
+#define MX28_PAD_ENET0_TXD1__GPIO_4_8 0x4083
+#define MX28_PAD_ENET0_RXD2__GPIO_4_9 0x4093
+#define MX28_PAD_ENET0_RXD3__GPIO_4_10 0x40a3
+#define MX28_PAD_ENET0_TXD2__GPIO_4_11 0x40b3
+#define MX28_PAD_ENET0_TXD3__GPIO_4_12 0x40c3
+#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13 0x40d3
+#define MX28_PAD_ENET0_COL__GPIO_4_14 0x40e3
+#define MX28_PAD_ENET0_CRS__GPIO_4_15 0x40f3
+#define MX28_PAD_ENET_CLK__GPIO_4_16 0x4103
+#define MX28_PAD_JTAG_RTCK__GPIO_4_20 0x4143
+
+#endif /* __DT_BINDINGS_MX28_PINCTRL_H__ */
diff --git a/arch/arm/boot/dts/imx28-sps1.dts b/arch/arm/boot/dts/imx28-sps1.dts
new file mode 100644
index 000000000..0ce3cb8e7
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-sps1.dts
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2012 Marek Vasut <marex@denx.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
+ */
+
+/dts-v1/;
+#include "imx28.dtsi"
+
+/ {
+ model = "SchulerControl GmbH, SC SPS 1";
+ compatible = "schulercontrol,imx28-sps1", "fsl,imx28";
+
+ memory {
+ reg = <0x40000000 0x08000000>;
+ };
+
+ apb@80000000 {
+ apbh@80000000 {
+ pinctrl@80018000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hog_pins_a>;
+
+ hog_pins_a: hog-gpios@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_D00__GPIO_0_0
+ MX28_PAD_GPMI_D03__GPIO_0_3
+ MX28_PAD_GPMI_D06__GPIO_0_6
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ };
+
+ ssp0: ssp@80010000 {
+ compatible = "fsl,imx28-mmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_4bit_pins_a>;
+ bus-width = <4>;
+ status = "okay";
+ };
+
+ ssp2: ssp@80014000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx28-spi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_pins_a>;
+ status = "okay";
+
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "everspin,mr25h256", "mr25h256";
+ spi-max-frequency = <40000000>;
+ reg = <0>;
+ };
+ };
+ };
+
+ apbx@80040000 {
+ i2c0: i2c@80058000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ rtc: rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+
+ eeprom: eeprom@52 {
+ compatible = "atmel,24c64";
+ reg = <0x52>;
+ pagesize = <32>;
+ };
+ };
+
+ duart: serial@80074000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&duart_pins_a>;
+ status = "okay";
+ };
+
+ usbphy0: usbphy@8007c000 {
+ status = "okay";
+ };
+
+ auart0: serial@8006a000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart0_pins_a>;
+ status = "okay";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ usb0: usb@80080000 {
+ vbus-supply = <&reg_usb0_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_pins_b>;
+ status = "okay";
+ };
+
+ mac0: ethernet@800f0000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac0_pins_a>;
+ status = "okay";
+ };
+
+ mac1: ethernet@800f4000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac1_pins_a>;
+ status = "okay";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb0_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb0_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 9 0>;
+ };
+ };
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "gpio-leds";
+ status = "okay";
+
+ led@1 {
+ label = "sps1-1:yellow:user";
+ gpios = <&gpio0 6 0>;
+ linux,default-trigger = "heartbeat";
+ reg = <0>;
+ };
+
+ led@2 {
+ label = "sps1-2:red:user";
+ gpios = <&gpio0 3 0>;
+ linux,default-trigger = "heartbeat";
+ reg = <1>;
+ };
+
+ led@3 {
+ label = "sps1-3:red:user";
+ gpios = <&gpio0 0 0>;
+ default-trigger = "heartbeat";
+ reg = <2>;
+ };
+
+ };
+};
diff --git a/arch/arm/boot/dts/imx28-tx28.dts b/arch/arm/boot/dts/imx28-tx28.dts
new file mode 100644
index 000000000..a5b27c85a
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-tx28.dts
@@ -0,0 +1,722 @@
+/*
+ * Copyright 2012 Shawn Guo <shawn.guo@linaro.org>
+ * Copyright 2013 Lothar WaĂŸmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx28.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Ka-Ro electronics TX28 module";
+ compatible = "karo,tx28", "fsl,imx28";
+
+ aliases {
+ can0 = &can0;
+ can1 = &can1;
+ display = &display0;
+ ds1339 = &ds1339;
+ gpio5 = &gpio5;
+ lcdif = &lcdif;
+ lcdif_23bit_pins = &tx28_lcdif_23bit_pins;
+ lcdif_24bit_pins = &lcdif_24bit_pins_a;
+ reg_can_xcvr = &reg_can_xcvr;
+ spi_gpio = &spi_gpio;
+ spi_mxs = &ssp3;
+ stk5led = &user_led;
+ usbotg = &usb0;
+ };
+
+ memory {
+ reg = <0 0>; /* will be filled in by U-Boot */
+ };
+
+ onewire {
+ compatible = "w1-gpio";
+ gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb0_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb0_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb1_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 27 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_2p5v: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "2P5V";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_can_xcvr: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "CAN XCVR";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 0 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&tx28_flexcan_xcvr_pins>;
+ };
+
+ reg_lcd: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "LCD POWER";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 31 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_lcd_reset: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ regulator-name = "LCD RESET";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <300000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ mclk: clock@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ #clock-cells = <0>;
+ clock-frequency = <27000000>;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx28-tx28-sgtl5000",
+ "fsl,mxs-audio-sgtl5000";
+ model = "imx28-tx28-sgtl5000";
+ saif-controllers = <&saif0 &saif1>;
+ audio-codec = <&sgtl5000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ user_led: user {
+ label = "Heartbeat";
+ gpios = <&gpio4 10 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 0 500000>;
+ /*
+ * a silly way to create a 1:1 relationship between the
+ * PWM value and the actual duty cycle
+ */
+ brightness-levels = < 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 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <50>;
+ };
+
+ matrix_keypad: matrix-keypad@0 {
+ compatible = "gpio-matrix-keypad";
+ col-gpios = <
+ &gpio5 0 GPIO_ACTIVE_HIGH
+ &gpio5 1 GPIO_ACTIVE_HIGH
+ &gpio5 2 GPIO_ACTIVE_HIGH
+ &gpio5 3 GPIO_ACTIVE_HIGH
+ >;
+ row-gpios = <
+ &gpio5 4 GPIO_ACTIVE_HIGH
+ &gpio5 5 GPIO_ACTIVE_HIGH
+ &gpio5 6 GPIO_ACTIVE_HIGH
+ &gpio5 7 GPIO_ACTIVE_HIGH
+ >;
+ /* sample keymap */
+ linux,keymap = <
+ 0x00000074 /* row 0, col 0, KEY_POWER */
+ 0x00010052 /* row 0, col 1, KEY_KP0 */
+ 0x0002004f /* row 0, col 2, KEY_KP1 */
+ 0x00030050 /* row 0, col 3, KEY_KP2 */
+ 0x01000051 /* row 1, col 0, KEY_KP3 */
+ 0x0101004b /* row 1, col 1, KEY_KP4 */
+ 0x0102004c /* row 1, col 2, KEY_KP5 */
+ 0x0103004d /* row 1, col 3, KEY_KP6 */
+ 0x02000047 /* row 2, col 0, KEY_KP7 */
+ 0x02010048 /* row 2, col 1, KEY_KP8 */
+ 0x02020049 /* row 2, col 2, KEY_KP9 */
+ >;
+ gpio-activelow;
+ linux,wakeup;
+ debounce-delay-ms = <100>;
+ col-scan-delay-us = <5000>;
+ linux,no-autorepeat;
+ };
+
+ spi_gpio: spi-gpio {
+ compatible = "spi-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&tx28_spi_gpio_pins>;
+
+ gpio-sck = <&gpio2 24 GPIO_ACTIVE_HIGH>;
+ gpio-mosi = <&gpio2 25 GPIO_ACTIVE_HIGH>;
+ gpio-miso = <&gpio2 26 GPIO_ACTIVE_HIGH>;
+ num-chipselects = <3>;
+ cs-gpios = <
+ &gpio2 27 GPIO_ACTIVE_LOW
+ &gpio3 8 GPIO_ACTIVE_LOW
+ &gpio3 9 GPIO_ACTIVE_LOW
+ >;
+ /* enable this and disable ssp3 below, if you need full duplex SPI transfer */
+ status = "disabled";
+
+ spi@0 {
+ compatible = "spidev";
+ reg = <0>;
+ spi-max-frequency = <57600000>;
+ };
+
+ spi@1 {
+ compatible = "spidev";
+ reg = <1>;
+ spi-max-frequency = <57600000>;
+ };
+
+ spi@2 {
+ compatible = "spidev";
+ reg = <2>;
+ spi-max-frequency = <57600000>;
+ };
+ };
+};
+
+/* 2nd TX-Std UART - (A)UART1 */
+&auart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart1_pins_a>;
+ status = "okay";
+};
+
+/* 3rd TX-Std UART - (A)UART3 */
+&auart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&auart3_pins_a>;
+ status = "okay";
+};
+
+&can0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&can0_pins_a>;
+ xceiver-supply = <&reg_can_xcvr>;
+ status = "okay";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&can1_pins_a>;
+ xceiver-supply = <&reg_can_xcvr>;
+ status = "okay";
+};
+
+&digctl {
+ status = "okay";
+};
+
+/* 1st TX-Std UART - (D)UART */
+&duart {
+ pinctrl-names = "default";
+ pinctrl-0 = <&duart_4pins_a>;
+ status = "okay";
+};
+
+&gpmi {
+ pinctrl-0 = <&gpmi_pins_a &gpmi_status_cfg>;
+ nand-on-flash-bbt;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ sgtl5000: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ VDDA-supply = <&reg_2p5v>;
+ VDDIO-supply = <&reg_3p3v>;
+ clocks = <&mclk>;
+ };
+
+ gpio5: pca953x@20 {
+ compatible = "nxp,pca9554";
+ reg = <0x20>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&tx28_pca9554_pins>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <28 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ polytouch: edt-ft5x06@38 {
+ compatible = "edt,edt-ft5x06";
+ reg = <0x38>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&tx28_edt_ft5x06_pins>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <5 0>;
+ reset-gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&gpio4 9 GPIO_ACTIVE_HIGH>;
+ };
+
+ touchscreen: tsc2007@48 {
+ compatible = "ti,tsc2007";
+ reg = <0x48>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&tx28_tsc2007_pins>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <20 0>;
+ pendown-gpio = <&gpio3 20 GPIO_ACTIVE_LOW>;
+ ti,x-plate-ohms = /bits/ 16 <660>;
+ };
+
+ ds1339: rtc@68 {
+ compatible = "mxim,ds1339";
+ reg = <0x68>;
+ };
+};
+
+&lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcdif_24bit_pins_a &lcdif_sync_pins_a &tx28_lcdif_ctrl_pins>;
+ lcd-supply = <&reg_lcd>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display0 {
+ bits-per-pixel = <32>;
+ bus-width = <24>;
+ display-timings {
+ native-mode = <&timing5>;
+ timing0: timing0 {
+ panel-name = "VGA";
+ clock-frequency = <25175000>;
+ hactive = <640>;
+ vactive = <480>;
+ hback-porch = <48>;
+ hsync-len = <96>;
+ hfront-porch = <16>;
+ vback-porch = <33>;
+ vsync-len = <2>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+
+ timing1: timing1 {
+ panel-name = "ETV570";
+ clock-frequency = <25175000>;
+ hactive = <640>;
+ vactive = <480>;
+ hback-porch = <114>;
+ hsync-len = <30>;
+ hfront-porch = <16>;
+ vback-porch = <32>;
+ vsync-len = <3>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+
+ timing2: timing2 {
+ panel-name = "ET0350";
+ clock-frequency = <6500000>;
+ hactive = <320>;
+ vactive = <240>;
+ hback-porch = <34>;
+ hsync-len = <34>;
+ hfront-porch = <20>;
+ vback-porch = <15>;
+ vsync-len = <3>;
+ vfront-porch = <4>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+
+ timing3: timing3 {
+ panel-name = "ET0430";
+ clock-frequency = <9000000>;
+ hactive = <480>;
+ vactive = <272>;
+ hback-porch = <2>;
+ hsync-len = <41>;
+ hfront-porch = <2>;
+ vback-porch = <2>;
+ vsync-len = <10>;
+ vfront-porch = <2>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+
+ timing4: timing4 {
+ panel-name = "ET0500", "ET0700";
+ clock-frequency = <33260000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <88>;
+ hsync-len = <128>;
+ hfront-porch = <40>;
+ vback-porch = <33>;
+ vsync-len = <2>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+
+ timing5: timing5 {
+ panel-name = "ETQ570";
+ clock-frequency = <6400000>;
+ hactive = <320>;
+ vactive = <240>;
+ hback-porch = <38>;
+ hsync-len = <30>;
+ hfront-porch = <30>;
+ vback-porch = <16>;
+ vsync-len = <3>;
+ vfront-porch = <4>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+};
+
+&lradc {
+ fsl,lradc-touchscreen-wires = <4>;
+ status = "okay";
+};
+
+&mac0 {
+ phy-mode = "rmii";
+ pinctrl-names = "default", "gpio_mode";
+ pinctrl-0 = <&mac0_pins_a>;
+ pinctrl-1 = <&tx28_mac0_pins_gpio>;
+ status = "okay";
+};
+
+&mac1 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac1_pins_a>;
+ /* not enabled by default */
+};
+
+&mxs_rtc {
+ status = "okay";
+};
+
+&ocotp {
+ status = "okay";
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pins_a>;
+ status = "okay";
+};
+
+&pinctrl {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hog_pins_a>;
+
+ hog_pins_a: hog@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_ENET0_RXD3__GPIO_4_10 /* module LED */
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ tx28_edt_ft5x06_pins: tx28-edt-ft5x06-pins {
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP0_DATA6__GPIO_2_6 /* RESET */
+ MX28_PAD_SSP0_DATA5__GPIO_2_5 /* IRQ */
+ MX28_PAD_ENET0_RXD2__GPIO_4_9 /* WAKE */
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ tx28_flexcan_xcvr_pins: tx28-flexcan-xcvr-pins {
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D00__GPIO_1_0
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ tx28_lcdif_23bit_pins: tx28-lcdif-23bit {
+ fsl,pinmux-ids = <
+ /* LCD_D00 may be used as Flexcan Transceiver Enable on STK5-V5 */
+ MX28_PAD_LCD_D01__LCD_D1
+ MX28_PAD_LCD_D02__LCD_D2
+ MX28_PAD_LCD_D03__LCD_D3
+ MX28_PAD_LCD_D04__LCD_D4
+ MX28_PAD_LCD_D05__LCD_D5
+ MX28_PAD_LCD_D06__LCD_D6
+ MX28_PAD_LCD_D07__LCD_D7
+ MX28_PAD_LCD_D08__LCD_D8
+ MX28_PAD_LCD_D09__LCD_D9
+ MX28_PAD_LCD_D10__LCD_D10
+ MX28_PAD_LCD_D11__LCD_D11
+ MX28_PAD_LCD_D12__LCD_D12
+ MX28_PAD_LCD_D13__LCD_D13
+ MX28_PAD_LCD_D14__LCD_D14
+ MX28_PAD_LCD_D15__LCD_D15
+ MX28_PAD_LCD_D16__LCD_D16
+ MX28_PAD_LCD_D17__LCD_D17
+ MX28_PAD_LCD_D18__LCD_D18
+ MX28_PAD_LCD_D19__LCD_D19
+ MX28_PAD_LCD_D20__LCD_D20
+ MX28_PAD_LCD_D21__LCD_D21
+ MX28_PAD_LCD_D22__LCD_D22
+ MX28_PAD_LCD_D23__LCD_D23
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ tx28_lcdif_ctrl_pins: tx28-lcdif-ctrl {
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_ENABLE__GPIO_1_31 /* Enable */
+ MX28_PAD_LCD_RESET__GPIO_3_30 /* Reset */
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ tx28_mac0_pins_gpio: tx28-mac0-gpio-pins {
+ fsl,pinmux-ids = <
+ MX28_PAD_ENET0_MDC__GPIO_4_0
+ MX28_PAD_ENET0_MDIO__GPIO_4_1
+ MX28_PAD_ENET0_RX_EN__GPIO_4_2
+ MX28_PAD_ENET0_RXD0__GPIO_4_3
+ MX28_PAD_ENET0_RXD1__GPIO_4_4
+ 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
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ tx28_pca9554_pins: tx28-pca9554-pins {
+ fsl,pinmux-ids = <
+ MX28_PAD_PWM3__GPIO_3_28
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ tx28_spi_gpio_pins: spi-gpiogrp {
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART2_RX__GPIO_3_8
+ MX28_PAD_AUART2_TX__GPIO_3_9
+ MX28_PAD_SSP3_SCK__GPIO_2_24
+ MX28_PAD_SSP3_MOSI__GPIO_2_25
+ MX28_PAD_SSP3_MISO__GPIO_2_26
+ MX28_PAD_SSP3_SS0__GPIO_2_27
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ tx28_tsc2007_pins: tx28-tsc2007-pins {
+ fsl,pinmux-ids = <
+ MX28_PAD_SAIF0_MCLK__GPIO_3_20 /* TSC2007 IRQ */
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+
+ tx28_usbphy0_pins: tx28-usbphy0-pins {
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_CE2N__GPIO_0_18 /* USBOTG_VBUSEN */
+ MX28_PAD_GPMI_CE3N__GPIO_0_19 /* USBOTH_OC */
+ >;
+ fsl,drive-strength = <MXS_DRIVE_12mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ tx28_usbphy1_pins: tx28-usbphy1-pins {
+ fsl,pinmux-ids = <
+ MX28_PAD_SPDIF__GPIO_3_27 /* USBH_VBUSEN */
+ MX28_PAD_JTAG_RTCK__GPIO_4_20 /* USBH_OC */
+ >;
+ fsl,drive-strength = <MXS_DRIVE_12mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+};
+
+&saif0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&saif0_pins_b>;
+ fsl,saif-master;
+ status = "okay";
+};
+
+&saif1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&saif1_pins_a>;
+ status = "okay";
+};
+
+&ssp0 {
+ compatible = "fsl,imx28-mmc";
+ pinctrl-names = "default", "special";
+ pinctrl-0 = <&mmc0_4bit_pins_a
+ &mmc0_cd_cfg
+ &mmc0_sck_cfg>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&ssp3 {
+ compatible = "fsl,imx28-spi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi3_pins_a>;
+ clock-frequency = <57600000>;
+ status = "okay";
+
+ spi@0 {
+ compatible = "spidev";
+ reg = <0>;
+ spi-max-frequency = <57600000>;
+ };
+
+ spi@1 {
+ compatible = "spidev";
+ reg = <1>;
+ spi-max-frequency = <57600000>;
+ };
+
+ spi@2 {
+ compatible = "spidev";
+ reg = <2>;
+ spi-max-frequency = <57600000>;
+ };
+};
+
+&usb0 {
+ vbus-supply = <&reg_usb0_vbus>;
+ disable-over-current;
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usb1 {
+ vbus-supply = <&reg_usb1_vbus>;
+ disable-over-current;
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbphy0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&tx28_usbphy0_pins>;
+ phy_type = "utmi";
+ status = "okay";
+};
+
+&usbphy1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&tx28_usbphy1_pins>;
+ phy_type = "utmi";
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
new file mode 100644
index 000000000..4e073e854
--- /dev/null
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -0,0 +1,1250 @@
+/*
+ * Copyright 2012 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 <dt-bindings/gpio/gpio.h>
+#include "skeleton.dtsi"
+#include "imx28-pinfunc.h"
+
+/ {
+ interrupt-parent = <&icoll>;
+
+ aliases {
+ ethernet0 = &mac0;
+ ethernet1 = &mac1;
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ gpio3 = &gpio3;
+ gpio4 = &gpio4;
+ saif0 = &saif0;
+ saif1 = &saif1;
+ serial0 = &auart0;
+ serial1 = &auart1;
+ serial2 = &auart2;
+ serial3 = &auart3;
+ serial4 = &auart4;
+ spi0 = &ssp1;
+ spi1 = &ssp2;
+ usbphy0 = &usbphy0;
+ usbphy1 = &usbphy1;
+ };
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm926ej-s";
+ device_type = "cpu";
+ };
+ };
+
+ apb@80000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80000000 0x80000>;
+ ranges;
+
+ apbh@80000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80000000 0x3c900>;
+ ranges;
+
+ icoll: interrupt-controller@80000000 {
+ compatible = "fsl,imx28-icoll", "fsl,icoll";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x80000000 0x2000>;
+ };
+
+ hsadc: hsadc@80002000 {
+ reg = <0x80002000 0x2000>;
+ interrupts = <13>;
+ dmas = <&dma_apbh 12>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
+ dma_apbh: dma-apbh@80004000 {
+ compatible = "fsl,imx28-dma-apbh";
+ reg = <0x80004000 0x2000>;
+ interrupts = <82 83 84 85
+ 88 88 88 88
+ 88 88 88 88
+ 87 86 0 0>;
+ interrupt-names = "ssp0", "ssp1", "ssp2", "ssp3",
+ "gpmi0", "gmpi1", "gpmi2", "gmpi3",
+ "gpmi4", "gmpi5", "gpmi6", "gmpi7",
+ "hsadc", "lcdif", "empty", "empty";
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ clocks = <&clks 25>;
+ };
+
+ perfmon: perfmon@80006000 {
+ reg = <0x80006000 0x800>;
+ interrupts = <27>;
+ status = "disabled";
+ };
+
+ gpmi: gpmi-nand@8000c000 {
+ compatible = "fsl,imx28-gpmi-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x8000c000 0x2000>, <0x8000a000 0x2000>;
+ reg-names = "gpmi-nand", "bch";
+ interrupts = <41>;
+ interrupt-names = "bch";
+ clocks = <&clks 50>;
+ clock-names = "gpmi_io";
+ dmas = <&dma_apbh 4>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ ssp0: ssp@80010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x80010000 0x2000>;
+ interrupts = <96>;
+ clocks = <&clks 46>;
+ dmas = <&dma_apbh 0>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ ssp1: ssp@80012000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x80012000 0x2000>;
+ interrupts = <97>;
+ clocks = <&clks 47>;
+ dmas = <&dma_apbh 1>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ ssp2: ssp@80014000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x80014000 0x2000>;
+ interrupts = <98>;
+ clocks = <&clks 48>;
+ dmas = <&dma_apbh 2>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ ssp3: ssp@80016000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x80016000 0x2000>;
+ interrupts = <99>;
+ clocks = <&clks 49>;
+ dmas = <&dma_apbh 3>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ pinctrl: pinctrl@80018000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx28-pinctrl", "simple-bus";
+ reg = <0x80018000 0x2000>;
+
+ gpio0: gpio@0 {
+ compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+ interrupts = <127>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio@1 {
+ compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+ interrupts = <126>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@2 {
+ compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+ interrupts = <125>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@3 {
+ compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+ interrupts = <124>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@4 {
+ compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+ interrupts = <123>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ duart_pins_a: duart@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_PWM0__DUART_RX
+ MX28_PAD_PWM1__DUART_TX
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ duart_pins_b: duart@1 {
+ reg = <1>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART0_CTS__DUART_RX
+ MX28_PAD_AUART0_RTS__DUART_TX
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ duart_4pins_a: duart-4pins@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART0_CTS__DUART_RX
+ MX28_PAD_AUART0_RTS__DUART_TX
+ MX28_PAD_AUART0_RX__DUART_CTS
+ MX28_PAD_AUART0_TX__DUART_RTS
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ gpmi_pins_a: gpmi-nand@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_D00__GPMI_D0
+ MX28_PAD_GPMI_D01__GPMI_D1
+ MX28_PAD_GPMI_D02__GPMI_D2
+ MX28_PAD_GPMI_D03__GPMI_D3
+ MX28_PAD_GPMI_D04__GPMI_D4
+ MX28_PAD_GPMI_D05__GPMI_D5
+ MX28_PAD_GPMI_D06__GPMI_D6
+ MX28_PAD_GPMI_D07__GPMI_D7
+ MX28_PAD_GPMI_CE0N__GPMI_CE0N
+ MX28_PAD_GPMI_RDY0__GPMI_READY0
+ MX28_PAD_GPMI_RDN__GPMI_RDN
+ MX28_PAD_GPMI_WRN__GPMI_WRN
+ MX28_PAD_GPMI_ALE__GPMI_ALE
+ MX28_PAD_GPMI_CLE__GPMI_CLE
+ MX28_PAD_GPMI_RESETN__GPMI_RESETN
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ gpmi_status_cfg: gpmi-status-cfg {
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_RDN__GPMI_RDN
+ MX28_PAD_GPMI_WRN__GPMI_WRN
+ MX28_PAD_GPMI_RESETN__GPMI_RESETN
+ >;
+ fsl,drive-strength = <MXS_DRIVE_12mA>;
+ };
+
+ auart0_pins_a: auart0@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART0_RX__AUART0_RX
+ MX28_PAD_AUART0_TX__AUART0_TX
+ MX28_PAD_AUART0_CTS__AUART0_CTS
+ MX28_PAD_AUART0_RTS__AUART0_RTS
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ auart0_2pins_a: auart0-2pins@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART0_RX__AUART0_RX
+ MX28_PAD_AUART0_TX__AUART0_TX
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ auart1_pins_a: auart1@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART1_RX__AUART1_RX
+ MX28_PAD_AUART1_TX__AUART1_TX
+ MX28_PAD_AUART1_CTS__AUART1_CTS
+ MX28_PAD_AUART1_RTS__AUART1_RTS
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ auart1_2pins_a: auart1-2pins@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART1_RX__AUART1_RX
+ MX28_PAD_AUART1_TX__AUART1_TX
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ auart2_2pins_a: auart2-2pins@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP2_SCK__AUART2_RX
+ MX28_PAD_SSP2_MOSI__AUART2_TX
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ auart2_2pins_b: auart2-2pins@1 {
+ reg = <1>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART2_RX__AUART2_RX
+ MX28_PAD_AUART2_TX__AUART2_TX
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ auart2_pins_a: auart2-pins@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART2_RX__AUART2_RX
+ MX28_PAD_AUART2_TX__AUART2_TX
+ MX28_PAD_AUART2_CTS__AUART2_CTS
+ MX28_PAD_AUART2_RTS__AUART2_RTS
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ auart3_pins_a: auart3@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART3_RX__AUART3_RX
+ MX28_PAD_AUART3_TX__AUART3_TX
+ MX28_PAD_AUART3_CTS__AUART3_CTS
+ MX28_PAD_AUART3_RTS__AUART3_RTS
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ auart3_2pins_a: auart3-2pins@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP2_MISO__AUART3_RX
+ MX28_PAD_SSP2_SS0__AUART3_TX
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ auart3_2pins_b: auart3-2pins@1 {
+ reg = <1>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART3_RX__AUART3_RX
+ MX28_PAD_AUART3_TX__AUART3_TX
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ auart4_2pins_a: auart4@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP3_SCK__AUART4_TX
+ MX28_PAD_SSP3_MOSI__AUART4_RX
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ mac0_pins_a: mac0@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_ENET0_MDC__ENET0_MDC
+ MX28_PAD_ENET0_MDIO__ENET0_MDIO
+ MX28_PAD_ENET0_RX_EN__ENET0_RX_EN
+ MX28_PAD_ENET0_RXD0__ENET0_RXD0
+ MX28_PAD_ENET0_RXD1__ENET0_RXD1
+ MX28_PAD_ENET0_TX_EN__ENET0_TX_EN
+ MX28_PAD_ENET0_TXD0__ENET0_TXD0
+ MX28_PAD_ENET0_TXD1__ENET0_TXD1
+ MX28_PAD_ENET_CLK__CLKCTRL_ENET
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ mac1_pins_a: mac1@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_ENET0_CRS__ENET1_RX_EN
+ MX28_PAD_ENET0_RXD2__ENET1_RXD0
+ MX28_PAD_ENET0_RXD3__ENET1_RXD1
+ MX28_PAD_ENET0_COL__ENET1_TX_EN
+ MX28_PAD_ENET0_TXD2__ENET1_TXD0
+ MX28_PAD_ENET0_TXD3__ENET1_TXD1
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ mmc0_8bit_pins_a: mmc0-8bit@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP0_DATA0__SSP0_D0
+ MX28_PAD_SSP0_DATA1__SSP0_D1
+ MX28_PAD_SSP0_DATA2__SSP0_D2
+ MX28_PAD_SSP0_DATA3__SSP0_D3
+ MX28_PAD_SSP0_DATA4__SSP0_D4
+ MX28_PAD_SSP0_DATA5__SSP0_D5
+ MX28_PAD_SSP0_DATA6__SSP0_D6
+ MX28_PAD_SSP0_DATA7__SSP0_D7
+ MX28_PAD_SSP0_CMD__SSP0_CMD
+ MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT
+ MX28_PAD_SSP0_SCK__SSP0_SCK
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ mmc0_4bit_pins_a: mmc0-4bit@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP0_DATA0__SSP0_D0
+ MX28_PAD_SSP0_DATA1__SSP0_D1
+ MX28_PAD_SSP0_DATA2__SSP0_D2
+ MX28_PAD_SSP0_DATA3__SSP0_D3
+ MX28_PAD_SSP0_CMD__SSP0_CMD
+ MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT
+ MX28_PAD_SSP0_SCK__SSP0_SCK
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ mmc0_cd_cfg: mmc0-cd-cfg {
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT
+ >;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ mmc0_sck_cfg: mmc0-sck-cfg {
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP0_SCK__SSP0_SCK
+ >;
+ fsl,drive-strength = <MXS_DRIVE_12mA>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ mmc1_4bit_pins_a: mmc1-4bit@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_D00__SSP1_D0
+ MX28_PAD_GPMI_D01__SSP1_D1
+ MX28_PAD_GPMI_D02__SSP1_D2
+ MX28_PAD_GPMI_D03__SSP1_D3
+ MX28_PAD_GPMI_RDY1__SSP1_CMD
+ MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT
+ MX28_PAD_GPMI_WRN__SSP1_SCK
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ mmc1_cd_cfg: mmc1-cd-cfg {
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT
+ >;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ mmc1_sck_cfg: mmc1-sck-cfg {
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_WRN__SSP1_SCK
+ >;
+ fsl,drive-strength = <MXS_DRIVE_12mA>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+
+ mmc2_4bit_pins_a: mmc2-4bit@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP0_DATA4__SSP2_D0
+ MX28_PAD_SSP1_SCK__SSP2_D1
+ MX28_PAD_SSP1_CMD__SSP2_D2
+ MX28_PAD_SSP0_DATA5__SSP2_D3
+ MX28_PAD_SSP0_DATA6__SSP2_CMD
+ MX28_PAD_AUART1_RX__SSP2_CARD_DETECT
+ MX28_PAD_SSP0_DATA7__SSP2_SCK
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ mmc2_cd_cfg: mmc2-cd-cfg {
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART1_RX__SSP2_CARD_DETECT
+ >;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ mmc2_sck_cfg: mmc2-sck-cfg {
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP0_DATA7__SSP2_SCK
+ >;
+ fsl,drive-strength = <MXS_DRIVE_12mA>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ i2c0_pins_a: i2c0@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_I2C0_SCL__I2C0_SCL
+ MX28_PAD_I2C0_SDA__I2C0_SDA
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ i2c0_pins_b: i2c0@1 {
+ reg = <1>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART0_RX__I2C0_SCL
+ MX28_PAD_AUART0_TX__I2C0_SDA
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ i2c1_pins_a: i2c1@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_PWM0__I2C1_SCL
+ MX28_PAD_PWM1__I2C1_SDA
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ i2c1_pins_b: i2c1@1 {
+ reg = <1>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART2_CTS__I2C1_SCL
+ MX28_PAD_AUART2_RTS__I2C1_SDA
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ saif0_pins_a: saif0@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SAIF0_MCLK__SAIF0_MCLK
+ MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK
+ MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK
+ MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0
+ >;
+ fsl,drive-strength = <MXS_DRIVE_12mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ saif0_pins_b: saif0@1 {
+ reg = <1>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK
+ MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK
+ MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0
+ >;
+ fsl,drive-strength = <MXS_DRIVE_12mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ saif1_pins_a: saif1@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0
+ >;
+ fsl,drive-strength = <MXS_DRIVE_12mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ pwm0_pins_a: pwm0@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_PWM0__PWM_0
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ pwm2_pins_a: pwm2@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_PWM2__PWM_2
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ pwm3_pins_a: pwm3@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_PWM3__PWM_3
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ pwm3_pins_b: pwm3@1 {
+ reg = <1>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SAIF0_MCLK__PWM_3
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ pwm4_pins_a: pwm4@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_PWM4__PWM_4
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_24bit_pins_a: lcdif-24bit@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D00__LCD_D0
+ MX28_PAD_LCD_D01__LCD_D1
+ MX28_PAD_LCD_D02__LCD_D2
+ MX28_PAD_LCD_D03__LCD_D3
+ MX28_PAD_LCD_D04__LCD_D4
+ MX28_PAD_LCD_D05__LCD_D5
+ MX28_PAD_LCD_D06__LCD_D6
+ MX28_PAD_LCD_D07__LCD_D7
+ MX28_PAD_LCD_D08__LCD_D8
+ MX28_PAD_LCD_D09__LCD_D9
+ MX28_PAD_LCD_D10__LCD_D10
+ MX28_PAD_LCD_D11__LCD_D11
+ MX28_PAD_LCD_D12__LCD_D12
+ MX28_PAD_LCD_D13__LCD_D13
+ MX28_PAD_LCD_D14__LCD_D14
+ MX28_PAD_LCD_D15__LCD_D15
+ MX28_PAD_LCD_D16__LCD_D16
+ MX28_PAD_LCD_D17__LCD_D17
+ MX28_PAD_LCD_D18__LCD_D18
+ MX28_PAD_LCD_D19__LCD_D19
+ MX28_PAD_LCD_D20__LCD_D20
+ MX28_PAD_LCD_D21__LCD_D21
+ MX28_PAD_LCD_D22__LCD_D22
+ MX28_PAD_LCD_D23__LCD_D23
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_18bit_pins_a: lcdif-18bit@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D00__LCD_D0
+ MX28_PAD_LCD_D01__LCD_D1
+ MX28_PAD_LCD_D02__LCD_D2
+ MX28_PAD_LCD_D03__LCD_D3
+ MX28_PAD_LCD_D04__LCD_D4
+ MX28_PAD_LCD_D05__LCD_D5
+ MX28_PAD_LCD_D06__LCD_D6
+ MX28_PAD_LCD_D07__LCD_D7
+ MX28_PAD_LCD_D08__LCD_D8
+ MX28_PAD_LCD_D09__LCD_D9
+ MX28_PAD_LCD_D10__LCD_D10
+ MX28_PAD_LCD_D11__LCD_D11
+ MX28_PAD_LCD_D12__LCD_D12
+ MX28_PAD_LCD_D13__LCD_D13
+ MX28_PAD_LCD_D14__LCD_D14
+ MX28_PAD_LCD_D15__LCD_D15
+ MX28_PAD_LCD_D16__LCD_D16
+ MX28_PAD_LCD_D17__LCD_D17
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_16bit_pins_a: lcdif-16bit@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_D00__LCD_D0
+ MX28_PAD_LCD_D01__LCD_D1
+ MX28_PAD_LCD_D02__LCD_D2
+ MX28_PAD_LCD_D03__LCD_D3
+ MX28_PAD_LCD_D04__LCD_D4
+ MX28_PAD_LCD_D05__LCD_D5
+ MX28_PAD_LCD_D06__LCD_D6
+ MX28_PAD_LCD_D07__LCD_D7
+ MX28_PAD_LCD_D08__LCD_D8
+ MX28_PAD_LCD_D09__LCD_D9
+ MX28_PAD_LCD_D10__LCD_D10
+ MX28_PAD_LCD_D11__LCD_D11
+ MX28_PAD_LCD_D12__LCD_D12
+ MX28_PAD_LCD_D13__LCD_D13
+ MX28_PAD_LCD_D14__LCD_D14
+ MX28_PAD_LCD_D15__LCD_D15
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ lcdif_sync_pins_a: lcdif-sync@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_LCD_RS__LCD_DOTCLK
+ MX28_PAD_LCD_CS__LCD_ENABLE
+ MX28_PAD_LCD_RD_E__LCD_VSYNC
+ MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ can0_pins_a: can0@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_RDY2__CAN0_TX
+ MX28_PAD_GPMI_RDY3__CAN0_RX
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ can1_pins_a: can1@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_GPMI_CE2N__CAN1_TX
+ MX28_PAD_GPMI_CE3N__CAN1_RX
+ >;
+ fsl,drive-strength = <MXS_DRIVE_4mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ spi2_pins_a: spi2@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP2_SCK__SSP2_SCK
+ MX28_PAD_SSP2_MOSI__SSP2_CMD
+ MX28_PAD_SSP2_MISO__SSP2_D0
+ MX28_PAD_SSP2_SS0__SSP2_D3
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ spi3_pins_a: spi3@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART2_RX__SSP3_D4
+ MX28_PAD_AUART2_TX__SSP3_D5
+ MX28_PAD_SSP3_SCK__SSP3_SCK
+ MX28_PAD_SSP3_MOSI__SSP3_CMD
+ MX28_PAD_SSP3_MISO__SSP3_D0
+ MX28_PAD_SSP3_SS0__SSP3_D3
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ spi3_pins_b: spi3@1 {
+ reg = <1>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP3_SCK__SSP3_SCK
+ MX28_PAD_SSP3_MOSI__SSP3_CMD
+ MX28_PAD_SSP3_MISO__SSP3_D0
+ MX28_PAD_SSP3_SS0__SSP3_D3
+ >;
+ fsl,drive-strength = <MXS_DRIVE_8mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ usb0_pins_a: usb0@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP2_SS2__USB0_OVERCURRENT
+ >;
+ fsl,drive-strength = <MXS_DRIVE_12mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ usb0_pins_b: usb0@1 {
+ reg = <1>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART1_CTS__USB0_OVERCURRENT
+ >;
+ fsl,drive-strength = <MXS_DRIVE_12mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ usb1_pins_a: usb1@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_SSP2_SS1__USB1_OVERCURRENT
+ >;
+ fsl,drive-strength = <MXS_DRIVE_12mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_DISABLE>;
+ };
+
+ usb0_id_pins_a: usb0id@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART1_RTS__USB0_ID
+ >;
+ fsl,drive-strength = <MXS_DRIVE_12mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ usb0_id_pins_b: usb0id1@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ MX28_PAD_PWM2__USB0_ID
+ >;
+ fsl,drive-strength = <MXS_DRIVE_12mA>;
+ fsl,voltage = <MXS_VOLTAGE_HIGH>;
+ fsl,pull-up = <MXS_PULL_ENABLE>;
+ };
+
+ };
+
+ digctl: digctl@8001c000 {
+ compatible = "fsl,imx28-digctl", "fsl,imx23-digctl";
+ reg = <0x8001c000 0x2000>;
+ interrupts = <89>;
+ status = "disabled";
+ };
+
+ etm: etm@80022000 {
+ reg = <0x80022000 0x2000>;
+ status = "disabled";
+ };
+
+ dma_apbx: dma-apbx@80024000 {
+ compatible = "fsl,imx28-dma-apbx";
+ reg = <0x80024000 0x2000>;
+ interrupts = <78 79 66 0
+ 80 81 68 69
+ 70 71 72 73
+ 74 75 76 77>;
+ interrupt-names = "auart4-rx", "auart4-tx", "spdif-tx", "empty",
+ "saif0", "saif1", "i2c0", "i2c1",
+ "auart0-rx", "auart0-tx", "auart1-rx", "auart1-tx",
+ "auart2-rx", "auart2-tx", "auart3-rx", "auart3-tx";
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ clocks = <&clks 26>;
+ };
+
+ dcp: dcp@80028000 {
+ compatible = "fsl,imx28-dcp", "fsl,imx23-dcp";
+ reg = <0x80028000 0x2000>;
+ interrupts = <52 53 54>;
+ status = "okay";
+ };
+
+ pxp: pxp@8002a000 {
+ reg = <0x8002a000 0x2000>;
+ interrupts = <39>;
+ status = "disabled";
+ };
+
+ ocotp: ocotp@8002c000 {
+ compatible = "fsl,ocotp";
+ reg = <0x8002c000 0x2000>;
+ status = "disabled";
+ };
+
+ axi-ahb@8002e000 {
+ reg = <0x8002e000 0x2000>;
+ status = "disabled";
+ };
+
+ lcdif: lcdif@80030000 {
+ compatible = "fsl,imx28-lcdif";
+ reg = <0x80030000 0x2000>;
+ interrupts = <38>;
+ clocks = <&clks 55>;
+ dmas = <&dma_apbh 13>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
+ can0: can@80032000 {
+ compatible = "fsl,imx28-flexcan", "fsl,p1010-flexcan";
+ reg = <0x80032000 0x2000>;
+ interrupts = <8>;
+ clocks = <&clks 58>, <&clks 58>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ can1: can@80034000 {
+ compatible = "fsl,imx28-flexcan", "fsl,p1010-flexcan";
+ reg = <0x80034000 0x2000>;
+ interrupts = <9>;
+ clocks = <&clks 59>, <&clks 59>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ simdbg: simdbg@8003c000 {
+ reg = <0x8003c000 0x200>;
+ status = "disabled";
+ };
+
+ simgpmisel: simgpmisel@8003c200 {
+ reg = <0x8003c200 0x100>;
+ status = "disabled";
+ };
+
+ simsspsel: simsspsel@8003c300 {
+ reg = <0x8003c300 0x100>;
+ status = "disabled";
+ };
+
+ simmemsel: simmemsel@8003c400 {
+ reg = <0x8003c400 0x100>;
+ status = "disabled";
+ };
+
+ gpiomon: gpiomon@8003c500 {
+ reg = <0x8003c500 0x100>;
+ status = "disabled";
+ };
+
+ simenet: simenet@8003c700 {
+ reg = <0x8003c700 0x100>;
+ status = "disabled";
+ };
+
+ armjtag: armjtag@8003c800 {
+ reg = <0x8003c800 0x100>;
+ status = "disabled";
+ };
+ };
+
+ apbx@80040000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80040000 0x40000>;
+ ranges;
+
+ clks: clkctrl@80040000 {
+ compatible = "fsl,imx28-clkctrl", "fsl,clkctrl";
+ reg = <0x80040000 0x2000>;
+ #clock-cells = <1>;
+ };
+
+ saif0: saif@80042000 {
+ compatible = "fsl,imx28-saif";
+ reg = <0x80042000 0x2000>;
+ interrupts = <59>;
+ #clock-cells = <0>;
+ clocks = <&clks 53>;
+ dmas = <&dma_apbx 4>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ power: power@80044000 {
+ reg = <0x80044000 0x2000>;
+ status = "disabled";
+ };
+
+ saif1: saif@80046000 {
+ compatible = "fsl,imx28-saif";
+ reg = <0x80046000 0x2000>;
+ interrupts = <58>;
+ clocks = <&clks 54>;
+ dmas = <&dma_apbx 5>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ lradc: lradc@80050000 {
+ compatible = "fsl,imx28-lradc";
+ reg = <0x80050000 0x2000>;
+ interrupts = <10 14 15 16 17 18 19
+ 20 21 22 23 24 25>;
+ status = "disabled";
+ clocks = <&clks 41>;
+ #io-channel-cells = <1>;
+ };
+
+ spdif: spdif@80054000 {
+ reg = <0x80054000 0x2000>;
+ interrupts = <45>;
+ dmas = <&dma_apbx 2>;
+ dma-names = "tx";
+ status = "disabled";
+ };
+
+ mxs_rtc: rtc@80056000 {
+ compatible = "fsl,imx28-rtc", "fsl,stmp3xxx-rtc";
+ reg = <0x80056000 0x2000>;
+ interrupts = <29>;
+ };
+
+ i2c0: i2c@80058000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx28-i2c";
+ reg = <0x80058000 0x2000>;
+ interrupts = <111>;
+ clock-frequency = <100000>;
+ dmas = <&dma_apbx 6>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ i2c1: i2c@8005a000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx28-i2c";
+ reg = <0x8005a000 0x2000>;
+ interrupts = <110>;
+ clock-frequency = <100000>;
+ dmas = <&dma_apbx 7>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ pwm: pwm@80064000 {
+ compatible = "fsl,imx28-pwm", "fsl,imx23-pwm";
+ reg = <0x80064000 0x2000>;
+ clocks = <&clks 44>;
+ #pwm-cells = <2>;
+ fsl,pwm-number = <8>;
+ status = "disabled";
+ };
+
+ timer: timrot@80068000 {
+ compatible = "fsl,imx28-timrot", "fsl,timrot";
+ reg = <0x80068000 0x2000>;
+ interrupts = <48 49 50 51>;
+ clocks = <&clks 26>;
+ };
+
+ auart0: serial@8006a000 {
+ compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+ reg = <0x8006a000 0x2000>;
+ interrupts = <112>;
+ dmas = <&dma_apbx 8>, <&dma_apbx 9>;
+ dma-names = "rx", "tx";
+ clocks = <&clks 45>;
+ status = "disabled";
+ };
+
+ auart1: serial@8006c000 {
+ compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+ reg = <0x8006c000 0x2000>;
+ interrupts = <113>;
+ dmas = <&dma_apbx 10>, <&dma_apbx 11>;
+ dma-names = "rx", "tx";
+ clocks = <&clks 45>;
+ status = "disabled";
+ };
+
+ auart2: serial@8006e000 {
+ compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+ reg = <0x8006e000 0x2000>;
+ interrupts = <114>;
+ dmas = <&dma_apbx 12>, <&dma_apbx 13>;
+ dma-names = "rx", "tx";
+ clocks = <&clks 45>;
+ status = "disabled";
+ };
+
+ auart3: serial@80070000 {
+ compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+ reg = <0x80070000 0x2000>;
+ interrupts = <115>;
+ dmas = <&dma_apbx 14>, <&dma_apbx 15>;
+ dma-names = "rx", "tx";
+ clocks = <&clks 45>;
+ status = "disabled";
+ };
+
+ auart4: serial@80072000 {
+ compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+ reg = <0x80072000 0x2000>;
+ interrupts = <116>;
+ dmas = <&dma_apbx 0>, <&dma_apbx 1>;
+ dma-names = "rx", "tx";
+ clocks = <&clks 45>;
+ status = "disabled";
+ };
+
+ duart: serial@80074000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x80074000 0x1000>;
+ interrupts = <47>;
+ clocks = <&clks 45>, <&clks 26>;
+ clock-names = "uart", "apb_pclk";
+ status = "disabled";
+ };
+
+ usbphy0: usbphy@8007c000 {
+ compatible = "fsl,imx28-usbphy", "fsl,imx23-usbphy";
+ reg = <0x8007c000 0x2000>;
+ clocks = <&clks 62>;
+ status = "disabled";
+ };
+
+ usbphy1: usbphy@8007e000 {
+ compatible = "fsl,imx28-usbphy", "fsl,imx23-usbphy";
+ reg = <0x8007e000 0x2000>;
+ clocks = <&clks 63>;
+ status = "disabled";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80080000 0x80000>;
+ ranges;
+
+ usb0: usb@80080000 {
+ compatible = "fsl,imx28-usb", "fsl,imx27-usb";
+ reg = <0x80080000 0x10000>;
+ interrupts = <93>;
+ clocks = <&clks 60>;
+ fsl,usbphy = <&usbphy0>;
+ status = "disabled";
+ };
+
+ usb1: usb@80090000 {
+ compatible = "fsl,imx28-usb", "fsl,imx27-usb";
+ reg = <0x80090000 0x10000>;
+ interrupts = <92>;
+ clocks = <&clks 61>;
+ fsl,usbphy = <&usbphy1>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ dflpt: dflpt@800c0000 {
+ reg = <0x800c0000 0x10000>;
+ status = "disabled";
+ };
+
+ mac0: ethernet@800f0000 {
+ compatible = "fsl,imx28-fec";
+ reg = <0x800f0000 0x4000>;
+ interrupts = <101>;
+ clocks = <&clks 57>, <&clks 57>, <&clks 64>;
+ clock-names = "ipg", "ahb", "enet_out";
+ status = "disabled";
+ };
+
+ mac1: ethernet@800f4000 {
+ compatible = "fsl,imx28-fec";
+ reg = <0x800f4000 0x4000>;
+ interrupts = <102>;
+ clocks = <&clks 57>, <&clks 57>;
+ clock-names = "ipg", "ahb";
+ status = "disabled";
+ };
+
+ etn_switch: switch@800f8000 {
+ reg = <0x800f8000 0x8000>;
+ status = "disabled";
+ };
+ };
+
+ iio_hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&lradc 8>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx31-bug.dts b/arch/arm/boot/dts/imx31-bug.dts
new file mode 100644
index 000000000..2424abfc9
--- /dev/null
+++ b/arch/arm/boot/dts/imx31-bug.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2012 Denis 'GNUtoo' Carikli <GNUtoo@no-log.org>
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx31.dtsi"
+
+/ {
+ model = "Buglabs i.MX31 Bug 1.x";
+ compatible = "buglabs,imx31-bug", "fsl,imx31";
+
+ memory {
+ reg = <0x80000000 0x8000000>; /* 128M */
+ };
+};
+
+&uart5 {
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx31.dtsi b/arch/arm/boot/dts/imx31.dtsi
new file mode 100644
index 000000000..c34f82581
--- /dev/null
+++ b/arch/arm/boot/dts/imx31.dtsi
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2012 Denis 'GNUtoo' Carikli <GNUtoo@no-log.org>
+ *
+ * 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 "skeleton.dtsi"
+
+/ {
+ aliases {
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ };
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm1136";
+ device_type = "cpu";
+ };
+ };
+
+ avic: avic-interrupt-controller@60000000 {
+ compatible = "fsl,imx31-avic", "fsl,avic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x60000000 0x100000>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&avic>;
+ ranges;
+
+ aips@43f00000 { /* AIPS1 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x43f00000 0x100000>;
+ ranges;
+
+ uart1: serial@43f90000 {
+ compatible = "fsl,imx31-uart", "fsl,imx21-uart";
+ reg = <0x43f90000 0x4000>;
+ interrupts = <45>;
+ clocks = <&clks 10>, <&clks 30>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart2: serial@43f94000 {
+ compatible = "fsl,imx31-uart", "fsl,imx21-uart";
+ reg = <0x43f94000 0x4000>;
+ interrupts = <32>;
+ clocks = <&clks 10>, <&clks 31>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart4: serial@43fb0000 {
+ compatible = "fsl,imx31-uart", "fsl,imx21-uart";
+ reg = <0x43fb0000 0x4000>;
+ clocks = <&clks 10>, <&clks 49>;
+ clock-names = "ipg", "per";
+ interrupts = <46>;
+ status = "disabled";
+ };
+
+ uart5: serial@43fb4000 {
+ compatible = "fsl,imx31-uart", "fsl,imx21-uart";
+ reg = <0x43fb4000 0x4000>;
+ interrupts = <47>;
+ clocks = <&clks 10>, <&clks 50>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+ };
+
+ spba@50000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x50000000 0x100000>;
+ ranges;
+
+ uart3: serial@5000c000 {
+ compatible = "fsl,imx31-uart", "fsl,imx21-uart";
+ reg = <0x5000c000 0x4000>;
+ interrupts = <18>;
+ clocks = <&clks 10>, <&clks 48>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ iim: iim@5001c000 {
+ compatible = "fsl,imx31-iim", "fsl,imx27-iim";
+ reg = <0x5001c000 0x1000>;
+ interrupts = <19>;
+ clocks = <&clks 25>;
+ };
+
+ clks: ccm@53f80000{
+ compatible = "fsl,imx31-ccm";
+ reg = <0x53f80000 0x4000>;
+ interrupts = <0 31 0x04 0 53 0x04>;
+ #clock-cells = <1>;
+ };
+ };
+
+ aips@53f00000 { /* AIPS2 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x53f00000 0x100000>;
+ ranges;
+
+ gpt: timer@53f90000 {
+ compatible = "fsl,imx31-gpt";
+ reg = <0x53f90000 0x4000>;
+ interrupts = <29>;
+ clocks = <&clks 10>, <&clks 22>;
+ clock-names = "ipg", "per";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx35-eukrea-cpuimx35.dtsi b/arch/arm/boot/dts/imx35-eukrea-cpuimx35.dtsi
new file mode 100644
index 000000000..9c2b715ab
--- /dev/null
+++ b/arch/arm/boot/dts/imx35-eukrea-cpuimx35.dtsi
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@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.
+ */
+
+#include "imx35.dtsi"
+
+/ {
+ model = "Eukrea CPUIMX35";
+ compatible = "eukrea,cpuimx35", "fsl,imx35";
+
+ memory {
+ reg = <0x80000000 0x8000000>; /* 128M */
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pcf8563@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+
+ tsc2007: tsc2007@48 {
+ compatible = "ti,tsc2007";
+ gpios = <&gpio3 2 0>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <0x2 0x8>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tsc2007_1>;
+ reg = <0x48>;
+ ti,x-plate-ohms = <180>;
+ };
+};
+
+&iomuxc {
+ imx35-eukrea {
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX35_PAD_FEC_TX_CLK__FEC_TX_CLK 0x80000000
+ MX35_PAD_FEC_RX_CLK__FEC_RX_CLK 0x80000000
+ MX35_PAD_FEC_RX_DV__FEC_RX_DV 0x80000000
+ MX35_PAD_FEC_COL__FEC_COL 0x80000000
+ MX35_PAD_FEC_RDATA0__FEC_RDATA_0 0x80000000
+ MX35_PAD_FEC_TDATA0__FEC_TDATA_0 0x80000000
+ MX35_PAD_FEC_TX_EN__FEC_TX_EN 0x80000000
+ MX35_PAD_FEC_MDC__FEC_MDC 0x80000000
+ MX35_PAD_FEC_MDIO__FEC_MDIO 0x80000000
+ MX35_PAD_FEC_TX_ERR__FEC_TX_ERR 0x80000000
+ MX35_PAD_FEC_RX_ERR__FEC_RX_ERR 0x80000000
+ MX35_PAD_FEC_CRS__FEC_CRS 0x80000000
+ MX35_PAD_FEC_RDATA1__FEC_RDATA_1 0x80000000
+ MX35_PAD_FEC_TDATA1__FEC_TDATA_1 0x80000000
+ MX35_PAD_FEC_RDATA2__FEC_RDATA_2 0x80000000
+ MX35_PAD_FEC_TDATA2__FEC_TDATA_2 0x80000000
+ MX35_PAD_FEC_RDATA3__FEC_RDATA_3 0x80000000
+ MX35_PAD_FEC_TDATA3__FEC_TDATA_3 0x80000000
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX35_PAD_I2C1_CLK__I2C1_SCL 0x80000000
+ MX35_PAD_I2C1_DAT__I2C1_SDA 0x80000000
+ >;
+ };
+
+ pinctrl_tsc2007_1: tsc2007grp-1 {
+ fsl,pins = <MX35_PAD_ATA_DA2__GPIO3_2 0x80000000>;
+ };
+ };
+};
+
+&nfc {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ nand-on-flash-bbt;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx35-eukrea-mbimxsd35-baseboard.dts b/arch/arm/boot/dts/imx35-eukrea-mbimxsd35-baseboard.dts
new file mode 100644
index 000000000..75b036700
--- /dev/null
+++ b/arch/arm/boot/dts/imx35-eukrea-mbimxsd35-baseboard.dts
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "imx35-eukrea-cpuimx35.dtsi"
+
+/ {
+ model = "Eukrea CPUIMX35";
+ compatible = "eukrea,mbimxsd35-baseboard", "eukrea,cpuimx35", "fsl,imx35";
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_bp1>;
+
+ bp1 {
+ label = "BP1";
+ gpios = <&gpio3 25 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_MISC>;
+ gpio-key,wakeup;
+ linux,input-type = <1>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_led1>;
+
+ led1 {
+ label = "led1";
+ gpios = <&gpio3 29 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ sound {
+ compatible = "eukrea,asoc-tlv320";
+ eukrea,model = "imx35-eukrea-tlv320aic23";
+ ssi-controller = <&ssi1>;
+ fsl,mux-int-port = <1>;
+ fsl,mux-ext-port = <4>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ cd-gpios = <&gpio3 24>;
+ status = "okay";
+};
+
+&i2c1 {
+ tlv320aic23: codec@1a {
+ compatible = "ti,tlv320aic23";
+ reg = <0x1a>;
+ };
+};
+
+&iomuxc {
+ imx35-eukrea {
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS 0x80000000
+ MX35_PAD_STXD4__AUDMUX_AUD4_TXD 0x80000000
+ MX35_PAD_SRXD4__AUDMUX_AUD4_RXD 0x80000000
+ MX35_PAD_SCK4__AUDMUX_AUD4_TXC 0x80000000
+ >;
+ };
+
+ pinctrl_bp1: bp1grp {
+ fsl,pins = <MX35_PAD_LD19__GPIO3_25 0x80000000>;
+ };
+
+ pinctrl_esdhc1: esdhc1grp {
+ fsl,pins = <
+ MX35_PAD_SD1_CMD__ESDHC1_CMD 0x80000000
+ MX35_PAD_SD1_CLK__ESDHC1_CLK 0x80000000
+ MX35_PAD_SD1_DATA0__ESDHC1_DAT0 0x80000000
+ MX35_PAD_SD1_DATA1__ESDHC1_DAT1 0x80000000
+ MX35_PAD_SD1_DATA2__ESDHC1_DAT2 0x80000000
+ MX35_PAD_SD1_DATA3__ESDHC1_DAT3 0x80000000
+ MX35_PAD_LD18__GPIO3_24 0x80000000 /* CD */
+ >;
+ };
+
+ pinctrl_led1: led1grp {
+ fsl,pins = <MX35_PAD_LD23__GPIO3_29 0x80000000>;
+ };
+
+ pinctrl_reg_lcd_3v3: reg-lcd-3v3 {
+ fsl,pins = <MX35_PAD_D3_CLS__GPIO1_4 0x80000000>;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX35_PAD_TXD1__UART1_TXD_MUX 0x1c5
+ MX35_PAD_RXD1__UART1_RXD_MUX 0x1c5
+ MX35_PAD_CTS1__UART1_CTS 0x1c5
+ MX35_PAD_RTS1__UART1_RTS 0x1c5
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX35_PAD_RXD2__UART2_RXD_MUX 0x1c5
+ MX35_PAD_TXD2__UART2_TXD_MUX 0x1c5
+ MX35_PAD_RTS2__UART2_RTS 0x1c5
+ MX35_PAD_CTS2__UART2_CTS 0x1c5
+ >;
+ };
+ };
+};
+
+&ssi1 {
+ codec-handle = <&tlv320aic23>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&usbhost1 {
+ phy_type = "serial";
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbotg {
+ phy_type = "utmi";
+ dr_mode = "otg";
+ external-vbus-divider;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx35-pdk.dts b/arch/arm/boot/dts/imx35-pdk.dts
new file mode 100644
index 000000000..8d7155237
--- /dev/null
+++ b/arch/arm/boot/dts/imx35-pdk.dts
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.com>
+ * Copyright 2014 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
+ */
+
+/dts-v1/;
+#include "imx35.dtsi"
+
+/ {
+ model = "Freescale i.MX35 Product Development Kit";
+ compatible = "fsl,imx35-pdk", "fsl,imx35";
+
+ memory {
+ reg = <0x80000000 0x8000000>,
+ <0x90000000 0x8000000>;
+ };
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ status = "okay";
+};
+
+&iomuxc {
+ imx35-pdk {
+ pinctrl_esdhc1: esdhc1grp {
+ fsl,pins = <
+ MX35_PAD_SD1_CMD__ESDHC1_CMD 0x80000000
+ MX35_PAD_SD1_CLK__ESDHC1_CLK 0x80000000
+ MX35_PAD_SD1_DATA0__ESDHC1_DAT0 0x80000000
+ MX35_PAD_SD1_DATA1__ESDHC1_DAT1 0x80000000
+ MX35_PAD_SD1_DATA2__ESDHC1_DAT2 0x80000000
+ MX35_PAD_SD1_DATA3__ESDHC1_DAT3 0x80000000
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX35_PAD_TXD1__UART1_TXD_MUX 0x1c5
+ MX35_PAD_RXD1__UART1_RXD_MUX 0x1c5
+ MX35_PAD_CTS1__UART1_CTS 0x1c5
+ MX35_PAD_RTS1__UART1_RTS 0x1c5
+ >;
+ };
+ };
+};
+
+&nfc {
+ nand-bus-width = <16>;
+ nand-ecc-mode = "hw";
+ nand-on-flash-bbt;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx35-pinfunc.h b/arch/arm/boot/dts/imx35-pinfunc.h
new file mode 100644
index 000000000..4911f2c40
--- /dev/null
+++ b/arch/arm/boot/dts/imx35-pinfunc.h
@@ -0,0 +1,970 @@
+/*
+ * Copyright 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX35_PINFUNC_H
+#define __DTS_IMX35_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX35_PAD_CAPTURE__GPT_CAPIN1 0x004 0x328 0x000 0x0 0x0
+#define MX35_PAD_CAPTURE__GPT_CMPOUT2 0x004 0x328 0x000 0x1 0x0
+#define MX35_PAD_CAPTURE__CSPI2_SS1 0x004 0x328 0x7f4 0x2 0x0
+#define MX35_PAD_CAPTURE__EPIT1_EPITO 0x004 0x328 0x000 0x3 0x0
+#define MX35_PAD_CAPTURE__CCM_CLK32K 0x004 0x328 0x7d0 0x4 0x0
+#define MX35_PAD_CAPTURE__GPIO1_4 0x004 0x328 0x850 0x5 0x0
+#define MX35_PAD_COMPARE__GPT_CMPOUT1 0x008 0x32c 0x000 0x0 0x0
+#define MX35_PAD_COMPARE__GPT_CAPIN2 0x008 0x32c 0x000 0x1 0x0
+#define MX35_PAD_COMPARE__GPT_CMPOUT3 0x008 0x32c 0x000 0x2 0x0
+#define MX35_PAD_COMPARE__EPIT2_EPITO 0x008 0x32c 0x000 0x3 0x0
+#define MX35_PAD_COMPARE__GPIO1_5 0x008 0x32c 0x854 0x5 0x0
+#define MX35_PAD_COMPARE__SDMA_EXTDMA_2 0x008 0x32c 0x000 0x7 0x0
+#define MX35_PAD_WDOG_RST__WDOG_WDOG_B 0x00c 0x330 0x000 0x0 0x0
+#define MX35_PAD_WDOG_RST__IPU_FLASH_STROBE 0x00c 0x330 0x000 0x3 0x0
+#define MX35_PAD_WDOG_RST__GPIO1_6 0x00c 0x330 0x858 0x5 0x0
+#define MX35_PAD_GPIO1_0__GPIO1_0 0x010 0x334 0x82c 0x0 0x0
+#define MX35_PAD_GPIO1_0__CCM_PMIC_RDY 0x010 0x334 0x7d4 0x1 0x0
+#define MX35_PAD_GPIO1_0__OWIRE_LINE 0x010 0x334 0x990 0x2 0x0
+#define MX35_PAD_GPIO1_0__SDMA_EXTDMA_0 0x010 0x334 0x000 0x7 0x0
+#define MX35_PAD_GPIO1_1__GPIO1_1 0x014 0x338 0x838 0x0 0x0
+#define MX35_PAD_GPIO1_1__PWM_PWMO 0x014 0x338 0x000 0x2 0x0
+#define MX35_PAD_GPIO1_1__CSPI1_SS2 0x014 0x338 0x7d8 0x3 0x0
+#define MX35_PAD_GPIO1_1__SCC_TAMPER_DETECT 0x014 0x338 0x000 0x6 0x0
+#define MX35_PAD_GPIO1_1__SDMA_EXTDMA_1 0x014 0x338 0x000 0x7 0x0
+#define MX35_PAD_GPIO2_0__GPIO2_0 0x018 0x33c 0x868 0x0 0x0
+#define MX35_PAD_GPIO2_0__USB_TOP_USBOTG_CLK 0x018 0x33c 0x000 0x1 0x0
+#define MX35_PAD_GPIO3_0__GPIO3_0 0x01c 0x340 0x8e8 0x0 0x0
+#define MX35_PAD_GPIO3_0__USB_TOP_USBH2_CLK 0x01c 0x340 0x000 0x1 0x0
+#define MX35_PAD_RESET_IN_B__CCM_RESET_IN_B 0x000 0x344 0x000 0x0 0x0
+#define MX35_PAD_POR_B__CCM_POR_B 0x000 0x348 0x000 0x0 0x0
+#define MX35_PAD_CLKO__CCM_CLKO 0x020 0x34c 0x000 0x0 0x0
+#define MX35_PAD_CLKO__GPIO1_8 0x020 0x34c 0x860 0x5 0x0
+#define MX35_PAD_BOOT_MODE0__CCM_BOOT_MODE_0 0x000 0x350 0x000 0x0 0x0
+#define MX35_PAD_BOOT_MODE1__CCM_BOOT_MODE_1 0x000 0x354 0x000 0x0 0x0
+#define MX35_PAD_CLK_MODE0__CCM_CLK_MODE_0 0x000 0x358 0x000 0x0 0x0
+#define MX35_PAD_CLK_MODE1__CCM_CLK_MODE_1 0x000 0x35c 0x000 0x0 0x0
+#define MX35_PAD_POWER_FAIL__CCM_DSM_WAKEUP_INT_26 0x000 0x360 0x000 0x0 0x0
+#define MX35_PAD_VSTBY__CCM_VSTBY 0x024 0x364 0x000 0x0 0x0
+#define MX35_PAD_VSTBY__GPIO1_7 0x024 0x364 0x85c 0x5 0x0
+#define MX35_PAD_A0__EMI_EIM_DA_L_0 0x028 0x368 0x000 0x0 0x0
+#define MX35_PAD_A1__EMI_EIM_DA_L_1 0x02c 0x36c 0x000 0x0 0x0
+#define MX35_PAD_A2__EMI_EIM_DA_L_2 0x030 0x370 0x000 0x0 0x0
+#define MX35_PAD_A3__EMI_EIM_DA_L_3 0x034 0x374 0x000 0x0 0x0
+#define MX35_PAD_A4__EMI_EIM_DA_L_4 0x038 0x378 0x000 0x0 0x0
+#define MX35_PAD_A5__EMI_EIM_DA_L_5 0x03c 0x37c 0x000 0x0 0x0
+#define MX35_PAD_A6__EMI_EIM_DA_L_6 0x040 0x380 0x000 0x0 0x0
+#define MX35_PAD_A7__EMI_EIM_DA_L_7 0x044 0x384 0x000 0x0 0x0
+#define MX35_PAD_A8__EMI_EIM_DA_H_8 0x048 0x388 0x000 0x0 0x0
+#define MX35_PAD_A9__EMI_EIM_DA_H_9 0x04c 0x38c 0x000 0x0 0x0
+#define MX35_PAD_A10__EMI_EIM_DA_H_10 0x050 0x390 0x000 0x0 0x0
+#define MX35_PAD_MA10__EMI_MA10 0x054 0x394 0x000 0x0 0x0
+#define MX35_PAD_A11__EMI_EIM_DA_H_11 0x058 0x398 0x000 0x0 0x0
+#define MX35_PAD_A12__EMI_EIM_DA_H_12 0x05c 0x39c 0x000 0x0 0x0
+#define MX35_PAD_A13__EMI_EIM_DA_H_13 0x060 0x3a0 0x000 0x0 0x0
+#define MX35_PAD_A14__EMI_EIM_DA_H2_14 0x064 0x3a4 0x000 0x0 0x0
+#define MX35_PAD_A15__EMI_EIM_DA_H2_15 0x068 0x3a8 0x000 0x0 0x0
+#define MX35_PAD_A16__EMI_EIM_A_16 0x06c 0x3ac 0x000 0x0 0x0
+#define MX35_PAD_A17__EMI_EIM_A_17 0x070 0x3b0 0x000 0x0 0x0
+#define MX35_PAD_A18__EMI_EIM_A_18 0x074 0x3b4 0x000 0x0 0x0
+#define MX35_PAD_A19__EMI_EIM_A_19 0x078 0x3b8 0x000 0x0 0x0
+#define MX35_PAD_A20__EMI_EIM_A_20 0x07c 0x3bc 0x000 0x0 0x0
+#define MX35_PAD_A21__EMI_EIM_A_21 0x080 0x3c0 0x000 0x0 0x0
+#define MX35_PAD_A22__EMI_EIM_A_22 0x084 0x3c4 0x000 0x0 0x0
+#define MX35_PAD_A23__EMI_EIM_A_23 0x088 0x3c8 0x000 0x0 0x0
+#define MX35_PAD_A24__EMI_EIM_A_24 0x08c 0x3cc 0x000 0x0 0x0
+#define MX35_PAD_A25__EMI_EIM_A_25 0x090 0x3d0 0x000 0x0 0x0
+#define MX35_PAD_SDBA1__EMI_EIM_SDBA1 0x000 0x3d4 0x000 0x0 0x0
+#define MX35_PAD_SDBA0__EMI_EIM_SDBA0 0x000 0x3d8 0x000 0x0 0x0
+#define MX35_PAD_SD0__EMI_DRAM_D_0 0x000 0x3dc 0x000 0x0 0x0
+#define MX35_PAD_SD1__EMI_DRAM_D_1 0x000 0x3e0 0x000 0x0 0x0
+#define MX35_PAD_SD2__EMI_DRAM_D_2 0x000 0x3e4 0x000 0x0 0x0
+#define MX35_PAD_SD3__EMI_DRAM_D_3 0x000 0x3e8 0x000 0x0 0x0
+#define MX35_PAD_SD4__EMI_DRAM_D_4 0x000 0x3ec 0x000 0x0 0x0
+#define MX35_PAD_SD5__EMI_DRAM_D_5 0x000 0x3f0 0x000 0x0 0x0
+#define MX35_PAD_SD6__EMI_DRAM_D_6 0x000 0x3f4 0x000 0x0 0x0
+#define MX35_PAD_SD7__EMI_DRAM_D_7 0x000 0x3f8 0x000 0x0 0x0
+#define MX35_PAD_SD8__EMI_DRAM_D_8 0x000 0x3fc 0x000 0x0 0x0
+#define MX35_PAD_SD9__EMI_DRAM_D_9 0x000 0x400 0x000 0x0 0x0
+#define MX35_PAD_SD10__EMI_DRAM_D_10 0x000 0x404 0x000 0x0 0x0
+#define MX35_PAD_SD11__EMI_DRAM_D_11 0x000 0x408 0x000 0x0 0x0
+#define MX35_PAD_SD12__EMI_DRAM_D_12 0x000 0x40c 0x000 0x0 0x0
+#define MX35_PAD_SD13__EMI_DRAM_D_13 0x000 0x410 0x000 0x0 0x0
+#define MX35_PAD_SD14__EMI_DRAM_D_14 0x000 0x414 0x000 0x0 0x0
+#define MX35_PAD_SD15__EMI_DRAM_D_15 0x000 0x418 0x000 0x0 0x0
+#define MX35_PAD_SD16__EMI_DRAM_D_16 0x000 0x41c 0x000 0x0 0x0
+#define MX35_PAD_SD17__EMI_DRAM_D_17 0x000 0x420 0x000 0x0 0x0
+#define MX35_PAD_SD18__EMI_DRAM_D_18 0x000 0x424 0x000 0x0 0x0
+#define MX35_PAD_SD19__EMI_DRAM_D_19 0x000 0x428 0x000 0x0 0x0
+#define MX35_PAD_SD20__EMI_DRAM_D_20 0x000 0x42c 0x000 0x0 0x0
+#define MX35_PAD_SD21__EMI_DRAM_D_21 0x000 0x430 0x000 0x0 0x0
+#define MX35_PAD_SD22__EMI_DRAM_D_22 0x000 0x434 0x000 0x0 0x0
+#define MX35_PAD_SD23__EMI_DRAM_D_23 0x000 0x438 0x000 0x0 0x0
+#define MX35_PAD_SD24__EMI_DRAM_D_24 0x000 0x43c 0x000 0x0 0x0
+#define MX35_PAD_SD25__EMI_DRAM_D_25 0x000 0x440 0x000 0x0 0x0
+#define MX35_PAD_SD26__EMI_DRAM_D_26 0x000 0x444 0x000 0x0 0x0
+#define MX35_PAD_SD27__EMI_DRAM_D_27 0x000 0x448 0x000 0x0 0x0
+#define MX35_PAD_SD28__EMI_DRAM_D_28 0x000 0x44c 0x000 0x0 0x0
+#define MX35_PAD_SD29__EMI_DRAM_D_29 0x000 0x450 0x000 0x0 0x0
+#define MX35_PAD_SD30__EMI_DRAM_D_30 0x000 0x454 0x000 0x0 0x0
+#define MX35_PAD_SD31__EMI_DRAM_D_31 0x000 0x458 0x000 0x0 0x0
+#define MX35_PAD_DQM0__EMI_DRAM_DQM_0 0x000 0x45c 0x000 0x0 0x0
+#define MX35_PAD_DQM1__EMI_DRAM_DQM_1 0x000 0x460 0x000 0x0 0x0
+#define MX35_PAD_DQM2__EMI_DRAM_DQM_2 0x000 0x464 0x000 0x0 0x0
+#define MX35_PAD_DQM3__EMI_DRAM_DQM_3 0x000 0x468 0x000 0x0 0x0
+#define MX35_PAD_EB0__EMI_EIM_EB0_B 0x094 0x46c 0x000 0x0 0x0
+#define MX35_PAD_EB1__EMI_EIM_EB1_B 0x098 0x470 0x000 0x0 0x0
+#define MX35_PAD_OE__EMI_EIM_OE 0x09c 0x474 0x000 0x0 0x0
+#define MX35_PAD_CS0__EMI_EIM_CS0 0x0a0 0x478 0x000 0x0 0x0
+#define MX35_PAD_CS1__EMI_EIM_CS1 0x0a4 0x47c 0x000 0x0 0x0
+#define MX35_PAD_CS1__EMI_NANDF_CE3 0x0a4 0x47c 0x000 0x3 0x0
+#define MX35_PAD_CS2__EMI_EIM_CS2 0x0a8 0x480 0x000 0x0 0x0
+#define MX35_PAD_CS3__EMI_EIM_CS3 0x0ac 0x484 0x000 0x0 0x0
+#define MX35_PAD_CS4__EMI_EIM_CS4 0x0b0 0x488 0x000 0x0 0x0
+#define MX35_PAD_CS4__EMI_DTACK_B 0x0b0 0x488 0x800 0x1 0x0
+#define MX35_PAD_CS4__EMI_NANDF_CE1 0x0b0 0x488 0x000 0x3 0x0
+#define MX35_PAD_CS4__GPIO1_20 0x0b0 0x488 0x83c 0x5 0x0
+#define MX35_PAD_CS5__EMI_EIM_CS5 0x0b4 0x48c 0x000 0x0 0x0
+#define MX35_PAD_CS5__CSPI2_SS2 0x0b4 0x48c 0x7f8 0x1 0x0
+#define MX35_PAD_CS5__CSPI1_SS2 0x0b4 0x48c 0x7d8 0x2 0x1
+#define MX35_PAD_CS5__EMI_NANDF_CE2 0x0b4 0x48c 0x000 0x3 0x0
+#define MX35_PAD_CS5__GPIO1_21 0x0b4 0x48c 0x840 0x5 0x0
+#define MX35_PAD_NF_CE0__EMI_NANDF_CE0 0x0b8 0x490 0x000 0x0 0x0
+#define MX35_PAD_NF_CE0__GPIO1_22 0x0b8 0x490 0x844 0x5 0x0
+#define MX35_PAD_ECB__EMI_EIM_ECB 0x000 0x494 0x000 0x0 0x0
+#define MX35_PAD_LBA__EMI_EIM_LBA 0x0bc 0x498 0x000 0x0 0x0
+#define MX35_PAD_BCLK__EMI_EIM_BCLK 0x0c0 0x49c 0x000 0x0 0x0
+#define MX35_PAD_RW__EMI_EIM_RW 0x0c4 0x4a0 0x000 0x0 0x0
+#define MX35_PAD_RAS__EMI_DRAM_RAS 0x000 0x4a4 0x000 0x0 0x0
+#define MX35_PAD_CAS__EMI_DRAM_CAS 0x000 0x4a8 0x000 0x0 0x0
+#define MX35_PAD_SDWE__EMI_DRAM_SDWE 0x000 0x4ac 0x000 0x0 0x0
+#define MX35_PAD_SDCKE0__EMI_DRAM_SDCKE_0 0x000 0x4b0 0x000 0x0 0x0
+#define MX35_PAD_SDCKE1__EMI_DRAM_SDCKE_1 0x000 0x4b4 0x000 0x0 0x0
+#define MX35_PAD_SDCLK__EMI_DRAM_SDCLK 0x000 0x4b8 0x000 0x0 0x0
+#define MX35_PAD_SDQS0__EMI_DRAM_SDQS_0 0x000 0x4bc 0x000 0x0 0x0
+#define MX35_PAD_SDQS1__EMI_DRAM_SDQS_1 0x000 0x4c0 0x000 0x0 0x0
+#define MX35_PAD_SDQS2__EMI_DRAM_SDQS_2 0x000 0x4c4 0x000 0x0 0x0
+#define MX35_PAD_SDQS3__EMI_DRAM_SDQS_3 0x000 0x4c8 0x000 0x0 0x0
+#define MX35_PAD_NFWE_B__EMI_NANDF_WE_B 0x0c8 0x4cc 0x000 0x0 0x0
+#define MX35_PAD_NFWE_B__USB_TOP_USBH2_DATA_3 0x0c8 0x4cc 0x9d8 0x1 0x0
+#define MX35_PAD_NFWE_B__IPU_DISPB_D0_VSYNC 0x0c8 0x4cc 0x924 0x2 0x0
+#define MX35_PAD_NFWE_B__GPIO2_18 0x0c8 0x4cc 0x88c 0x5 0x0
+#define MX35_PAD_NFWE_B__ARM11P_TOP_TRACE_0 0x0c8 0x4cc 0x000 0x7 0x0
+#define MX35_PAD_NFRE_B__EMI_NANDF_RE_B 0x0cc 0x4d0 0x000 0x0 0x0
+#define MX35_PAD_NFRE_B__USB_TOP_USBH2_DIR 0x0cc 0x4d0 0x9ec 0x1 0x0
+#define MX35_PAD_NFRE_B__IPU_DISPB_BCLK 0x0cc 0x4d0 0x000 0x2 0x0
+#define MX35_PAD_NFRE_B__GPIO2_19 0x0cc 0x4d0 0x890 0x5 0x0
+#define MX35_PAD_NFRE_B__ARM11P_TOP_TRACE_1 0x0cc 0x4d0 0x000 0x7 0x0
+#define MX35_PAD_NFALE__EMI_NANDF_ALE 0x0d0 0x4d4 0x000 0x0 0x0
+#define MX35_PAD_NFALE__USB_TOP_USBH2_STP 0x0d0 0x4d4 0x000 0x1 0x0
+#define MX35_PAD_NFALE__IPU_DISPB_CS0 0x0d0 0x4d4 0x000 0x2 0x0
+#define MX35_PAD_NFALE__GPIO2_20 0x0d0 0x4d4 0x898 0x5 0x0
+#define MX35_PAD_NFALE__ARM11P_TOP_TRACE_2 0x0d0 0x4d4 0x000 0x7 0x0
+#define MX35_PAD_NFCLE__EMI_NANDF_CLE 0x0d4 0x4d8 0x000 0x0 0x0
+#define MX35_PAD_NFCLE__USB_TOP_USBH2_NXT 0x0d4 0x4d8 0x9f0 0x1 0x0
+#define MX35_PAD_NFCLE__IPU_DISPB_PAR_RS 0x0d4 0x4d8 0x000 0x2 0x0
+#define MX35_PAD_NFCLE__GPIO2_21 0x0d4 0x4d8 0x89c 0x5 0x0
+#define MX35_PAD_NFCLE__ARM11P_TOP_TRACE_3 0x0d4 0x4d8 0x000 0x7 0x0
+#define MX35_PAD_NFWP_B__EMI_NANDF_WP_B 0x0d8 0x4dc 0x000 0x0 0x0
+#define MX35_PAD_NFWP_B__USB_TOP_USBH2_DATA_7 0x0d8 0x4dc 0x9e8 0x1 0x0
+#define MX35_PAD_NFWP_B__IPU_DISPB_WR 0x0d8 0x4dc 0x000 0x2 0x0
+#define MX35_PAD_NFWP_B__GPIO2_22 0x0d8 0x4dc 0x8a0 0x5 0x0
+#define MX35_PAD_NFWP_B__ARM11P_TOP_TRCTL 0x0d8 0x4dc 0x000 0x7 0x0
+#define MX35_PAD_NFRB__EMI_NANDF_RB 0x0dc 0x4e0 0x000 0x0 0x0
+#define MX35_PAD_NFRB__IPU_DISPB_RD 0x0dc 0x4e0 0x000 0x2 0x0
+#define MX35_PAD_NFRB__GPIO2_23 0x0dc 0x4e0 0x8a4 0x5 0x0
+#define MX35_PAD_NFRB__ARM11P_TOP_TRCLK 0x0dc 0x4e0 0x000 0x7 0x0
+#define MX35_PAD_D15__EMI_EIM_D_15 0x000 0x4e4 0x000 0x0 0x0
+#define MX35_PAD_D14__EMI_EIM_D_14 0x000 0x4e8 0x000 0x0 0x0
+#define MX35_PAD_D13__EMI_EIM_D_13 0x000 0x4ec 0x000 0x0 0x0
+#define MX35_PAD_D12__EMI_EIM_D_12 0x000 0x4f0 0x000 0x0 0x0
+#define MX35_PAD_D11__EMI_EIM_D_11 0x000 0x4f4 0x000 0x0 0x0
+#define MX35_PAD_D10__EMI_EIM_D_10 0x000 0x4f8 0x000 0x0 0x0
+#define MX35_PAD_D9__EMI_EIM_D_9 0x000 0x4fc 0x000 0x0 0x0
+#define MX35_PAD_D8__EMI_EIM_D_8 0x000 0x500 0x000 0x0 0x0
+#define MX35_PAD_D7__EMI_EIM_D_7 0x000 0x504 0x000 0x0 0x0
+#define MX35_PAD_D6__EMI_EIM_D_6 0x000 0x508 0x000 0x0 0x0
+#define MX35_PAD_D5__EMI_EIM_D_5 0x000 0x50c 0x000 0x0 0x0
+#define MX35_PAD_D4__EMI_EIM_D_4 0x000 0x510 0x000 0x0 0x0
+#define MX35_PAD_D3__EMI_EIM_D_3 0x000 0x514 0x000 0x0 0x0
+#define MX35_PAD_D2__EMI_EIM_D_2 0x000 0x518 0x000 0x0 0x0
+#define MX35_PAD_D1__EMI_EIM_D_1 0x000 0x51c 0x000 0x0 0x0
+#define MX35_PAD_D0__EMI_EIM_D_0 0x000 0x520 0x000 0x0 0x0
+#define MX35_PAD_CSI_D8__IPU_CSI_D_8 0x0e0 0x524 0x000 0x0 0x0
+#define MX35_PAD_CSI_D8__KPP_COL_0 0x0e0 0x524 0x950 0x1 0x0
+#define MX35_PAD_CSI_D8__GPIO1_20 0x0e0 0x524 0x83c 0x5 0x1
+#define MX35_PAD_CSI_D8__ARM11P_TOP_EVNTBUS_13 0x0e0 0x524 0x000 0x7 0x0
+#define MX35_PAD_CSI_D9__IPU_CSI_D_9 0x0e4 0x528 0x000 0x0 0x0
+#define MX35_PAD_CSI_D9__KPP_COL_1 0x0e4 0x528 0x954 0x1 0x0
+#define MX35_PAD_CSI_D9__GPIO1_21 0x0e4 0x528 0x840 0x5 0x1
+#define MX35_PAD_CSI_D9__ARM11P_TOP_EVNTBUS_14 0x0e4 0x528 0x000 0x7 0x0
+#define MX35_PAD_CSI_D10__IPU_CSI_D_10 0x0e8 0x52c 0x000 0x0 0x0
+#define MX35_PAD_CSI_D10__KPP_COL_2 0x0e8 0x52c 0x958 0x1 0x0
+#define MX35_PAD_CSI_D10__GPIO1_22 0x0e8 0x52c 0x844 0x5 0x1
+#define MX35_PAD_CSI_D10__ARM11P_TOP_EVNTBUS_15 0x0e8 0x52c 0x000 0x7 0x0
+#define MX35_PAD_CSI_D11__IPU_CSI_D_11 0x0ec 0x530 0x000 0x0 0x0
+#define MX35_PAD_CSI_D11__KPP_COL_3 0x0ec 0x530 0x95c 0x1 0x0
+#define MX35_PAD_CSI_D11__GPIO1_23 0x0ec 0x530 0x000 0x5 0x0
+#define MX35_PAD_CSI_D12__IPU_CSI_D_12 0x0f0 0x534 0x000 0x0 0x0
+#define MX35_PAD_CSI_D12__KPP_ROW_0 0x0f0 0x534 0x970 0x1 0x0
+#define MX35_PAD_CSI_D12__GPIO1_24 0x0f0 0x534 0x000 0x5 0x0
+#define MX35_PAD_CSI_D13__IPU_CSI_D_13 0x0f4 0x538 0x000 0x0 0x0
+#define MX35_PAD_CSI_D13__KPP_ROW_1 0x0f4 0x538 0x974 0x1 0x0
+#define MX35_PAD_CSI_D13__GPIO1_25 0x0f4 0x538 0x000 0x5 0x0
+#define MX35_PAD_CSI_D14__IPU_CSI_D_14 0x0f8 0x53c 0x000 0x0 0x0
+#define MX35_PAD_CSI_D14__KPP_ROW_2 0x0f8 0x53c 0x978 0x1 0x0
+#define MX35_PAD_CSI_D14__GPIO1_26 0x0f8 0x53c 0x000 0x5 0x0
+#define MX35_PAD_CSI_D15__IPU_CSI_D_15 0x0fc 0x540 0x97c 0x0 0x0
+#define MX35_PAD_CSI_D15__KPP_ROW_3 0x0fc 0x540 0x000 0x1 0x0
+#define MX35_PAD_CSI_D15__GPIO1_27 0x0fc 0x540 0x000 0x5 0x0
+#define MX35_PAD_CSI_MCLK__IPU_CSI_MCLK 0x100 0x544 0x000 0x0 0x0
+#define MX35_PAD_CSI_MCLK__GPIO1_28 0x100 0x544 0x000 0x5 0x0
+#define MX35_PAD_CSI_VSYNC__IPU_CSI_VSYNC 0x104 0x548 0x000 0x0 0x0
+#define MX35_PAD_CSI_VSYNC__GPIO1_29 0x104 0x548 0x000 0x5 0x0
+#define MX35_PAD_CSI_HSYNC__IPU_CSI_HSYNC 0x108 0x54c 0x000 0x0 0x0
+#define MX35_PAD_CSI_HSYNC__GPIO1_30 0x108 0x54c 0x000 0x5 0x0
+#define MX35_PAD_CSI_PIXCLK__IPU_CSI_PIXCLK 0x10c 0x550 0x000 0x0 0x0
+#define MX35_PAD_CSI_PIXCLK__GPIO1_31 0x10c 0x550 0x000 0x5 0x0
+#define MX35_PAD_I2C1_CLK__I2C1_SCL 0x110 0x554 0x000 0x0 0x0
+#define MX35_PAD_I2C1_CLK__GPIO2_24 0x110 0x554 0x8a8 0x5 0x0
+#define MX35_PAD_I2C1_CLK__CCM_USB_BYP_CLK 0x110 0x554 0x000 0x6 0x0
+#define MX35_PAD_I2C1_DAT__I2C1_SDA 0x114 0x558 0x000 0x0 0x0
+#define MX35_PAD_I2C1_DAT__GPIO2_25 0x114 0x558 0x8ac 0x5 0x0
+#define MX35_PAD_I2C2_CLK__I2C2_SCL 0x118 0x55c 0x000 0x0 0x0
+#define MX35_PAD_I2C2_CLK__CAN1_TXCAN 0x118 0x55c 0x000 0x1 0x0
+#define MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR 0x118 0x55c 0x000 0x2 0x0
+#define MX35_PAD_I2C2_CLK__GPIO2_26 0x118 0x55c 0x8b0 0x5 0x0
+#define MX35_PAD_I2C2_CLK__SDMA_DEBUG_BUS_DEVICE_2 0x118 0x55c 0x000 0x6 0x0
+#define MX35_PAD_I2C2_DAT__I2C2_SDA 0x11c 0x560 0x000 0x0 0x0
+#define MX35_PAD_I2C2_DAT__CAN1_RXCAN 0x11c 0x560 0x7c8 0x1 0x0
+#define MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC 0x11c 0x560 0x9f4 0x2 0x0
+#define MX35_PAD_I2C2_DAT__GPIO2_27 0x11c 0x560 0x8b4 0x5 0x0
+#define MX35_PAD_I2C2_DAT__SDMA_DEBUG_BUS_DEVICE_3 0x11c 0x560 0x000 0x6 0x0
+#define MX35_PAD_STXD4__AUDMUX_AUD4_TXD 0x120 0x564 0x000 0x0 0x0
+#define MX35_PAD_STXD4__GPIO2_28 0x120 0x564 0x8b8 0x5 0x0
+#define MX35_PAD_STXD4__ARM11P_TOP_ARM_COREASID0 0x120 0x564 0x000 0x7 0x0
+#define MX35_PAD_SRXD4__AUDMUX_AUD4_RXD 0x124 0x568 0x000 0x0 0x0
+#define MX35_PAD_SRXD4__GPIO2_29 0x124 0x568 0x8bc 0x5 0x0
+#define MX35_PAD_SRXD4__ARM11P_TOP_ARM_COREASID1 0x124 0x568 0x000 0x7 0x0
+#define MX35_PAD_SCK4__AUDMUX_AUD4_TXC 0x128 0x56c 0x000 0x0 0x0
+#define MX35_PAD_SCK4__GPIO2_30 0x128 0x56c 0x8c4 0x5 0x0
+#define MX35_PAD_SCK4__ARM11P_TOP_ARM_COREASID2 0x128 0x56c 0x000 0x7 0x0
+#define MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS 0x12c 0x570 0x000 0x0 0x0
+#define MX35_PAD_STXFS4__GPIO2_31 0x12c 0x570 0x8c8 0x5 0x0
+#define MX35_PAD_STXFS4__ARM11P_TOP_ARM_COREASID3 0x12c 0x570 0x000 0x7 0x0
+#define MX35_PAD_STXD5__AUDMUX_AUD5_TXD 0x130 0x574 0x000 0x0 0x0
+#define MX35_PAD_STXD5__SPDIF_SPDIF_OUT1 0x130 0x574 0x000 0x1 0x0
+#define MX35_PAD_STXD5__CSPI2_MOSI 0x130 0x574 0x7ec 0x2 0x0
+#define MX35_PAD_STXD5__GPIO1_0 0x130 0x574 0x82c 0x5 0x1
+#define MX35_PAD_STXD5__ARM11P_TOP_ARM_COREASID4 0x130 0x574 0x000 0x7 0x0
+#define MX35_PAD_SRXD5__AUDMUX_AUD5_RXD 0x134 0x578 0x000 0x0 0x0
+#define MX35_PAD_SRXD5__SPDIF_SPDIF_IN1 0x134 0x578 0x998 0x1 0x0
+#define MX35_PAD_SRXD5__CSPI2_MISO 0x134 0x578 0x7e8 0x2 0x0
+#define MX35_PAD_SRXD5__GPIO1_1 0x134 0x578 0x838 0x5 0x1
+#define MX35_PAD_SRXD5__ARM11P_TOP_ARM_COREASID5 0x134 0x578 0x000 0x7 0x0
+#define MX35_PAD_SCK5__AUDMUX_AUD5_TXC 0x138 0x57c 0x000 0x0 0x0
+#define MX35_PAD_SCK5__SPDIF_SPDIF_EXTCLK 0x138 0x57c 0x994 0x1 0x0
+#define MX35_PAD_SCK5__CSPI2_SCLK 0x138 0x57c 0x7e0 0x2 0x0
+#define MX35_PAD_SCK5__GPIO1_2 0x138 0x57c 0x848 0x5 0x0
+#define MX35_PAD_SCK5__ARM11P_TOP_ARM_COREASID6 0x138 0x57c 0x000 0x7 0x0
+#define MX35_PAD_STXFS5__AUDMUX_AUD5_TXFS 0x13c 0x580 0x000 0x0 0x0
+#define MX35_PAD_STXFS5__CSPI2_RDY 0x13c 0x580 0x7e4 0x2 0x0
+#define MX35_PAD_STXFS5__GPIO1_3 0x13c 0x580 0x84c 0x5 0x0
+#define MX35_PAD_STXFS5__ARM11P_TOP_ARM_COREASID7 0x13c 0x580 0x000 0x7 0x0
+#define MX35_PAD_SCKR__ESAI_SCKR 0x140 0x584 0x000 0x0 0x0
+#define MX35_PAD_SCKR__GPIO1_4 0x140 0x584 0x850 0x5 0x1
+#define MX35_PAD_SCKR__ARM11P_TOP_EVNTBUS_10 0x140 0x584 0x000 0x7 0x0
+#define MX35_PAD_FSR__ESAI_FSR 0x144 0x588 0x000 0x0 0x0
+#define MX35_PAD_FSR__GPIO1_5 0x144 0x588 0x854 0x5 0x1
+#define MX35_PAD_FSR__ARM11P_TOP_EVNTBUS_11 0x144 0x588 0x000 0x7 0x0
+#define MX35_PAD_HCKR__ESAI_HCKR 0x148 0x58c 0x000 0x0 0x0
+#define MX35_PAD_HCKR__AUDMUX_AUD5_RXFS 0x148 0x58c 0x000 0x1 0x0
+#define MX35_PAD_HCKR__CSPI2_SS0 0x148 0x58c 0x7f0 0x2 0x0
+#define MX35_PAD_HCKR__IPU_FLASH_STROBE 0x148 0x58c 0x000 0x3 0x0
+#define MX35_PAD_HCKR__GPIO1_6 0x148 0x58c 0x858 0x5 0x1
+#define MX35_PAD_HCKR__ARM11P_TOP_EVNTBUS_12 0x148 0x58c 0x000 0x7 0x0
+#define MX35_PAD_SCKT__ESAI_SCKT 0x14c 0x590 0x000 0x0 0x0
+#define MX35_PAD_SCKT__GPIO1_7 0x14c 0x590 0x85c 0x5 0x1
+#define MX35_PAD_SCKT__IPU_CSI_D_0 0x14c 0x590 0x930 0x6 0x0
+#define MX35_PAD_SCKT__KPP_ROW_2 0x14c 0x590 0x978 0x7 0x1
+#define MX35_PAD_FST__ESAI_FST 0x150 0x594 0x000 0x0 0x0
+#define MX35_PAD_FST__GPIO1_8 0x150 0x594 0x860 0x5 0x1
+#define MX35_PAD_FST__IPU_CSI_D_1 0x150 0x594 0x934 0x6 0x0
+#define MX35_PAD_FST__KPP_ROW_3 0x150 0x594 0x97c 0x7 0x1
+#define MX35_PAD_HCKT__ESAI_HCKT 0x154 0x598 0x000 0x0 0x0
+#define MX35_PAD_HCKT__AUDMUX_AUD5_RXC 0x154 0x598 0x7a8 0x1 0x0
+#define MX35_PAD_HCKT__GPIO1_9 0x154 0x598 0x864 0x5 0x0
+#define MX35_PAD_HCKT__IPU_CSI_D_2 0x154 0x598 0x938 0x6 0x0
+#define MX35_PAD_HCKT__KPP_COL_3 0x154 0x598 0x95c 0x7 0x1
+#define MX35_PAD_TX5_RX0__ESAI_TX5_RX0 0x158 0x59c 0x000 0x0 0x0
+#define MX35_PAD_TX5_RX0__AUDMUX_AUD4_RXC 0x158 0x59c 0x000 0x1 0x0
+#define MX35_PAD_TX5_RX0__CSPI2_SS2 0x158 0x59c 0x7f8 0x2 0x1
+#define MX35_PAD_TX5_RX0__CAN2_TXCAN 0x158 0x59c 0x000 0x3 0x0
+#define MX35_PAD_TX5_RX0__UART2_DTR 0x158 0x59c 0x000 0x4 0x0
+#define MX35_PAD_TX5_RX0__GPIO1_10 0x158 0x59c 0x830 0x5 0x0
+#define MX35_PAD_TX5_RX0__EMI_M3IF_CHOSEN_MASTER_0 0x158 0x59c 0x000 0x7 0x0
+#define MX35_PAD_TX4_RX1__ESAI_TX4_RX1 0x15c 0x5a0 0x000 0x0 0x0
+#define MX35_PAD_TX4_RX1__AUDMUX_AUD4_RXFS 0x15c 0x5a0 0x000 0x1 0x0
+#define MX35_PAD_TX4_RX1__CSPI2_SS3 0x15c 0x5a0 0x7fc 0x2 0x0
+#define MX35_PAD_TX4_RX1__CAN2_RXCAN 0x15c 0x5a0 0x7cc 0x3 0x0
+#define MX35_PAD_TX4_RX1__UART2_DSR 0x15c 0x5a0 0x000 0x4 0x0
+#define MX35_PAD_TX4_RX1__GPIO1_11 0x15c 0x5a0 0x834 0x5 0x0
+#define MX35_PAD_TX4_RX1__IPU_CSI_D_3 0x15c 0x5a0 0x93c 0x6 0x0
+#define MX35_PAD_TX4_RX1__KPP_ROW_0 0x15c 0x5a0 0x970 0x7 0x1
+#define MX35_PAD_TX3_RX2__ESAI_TX3_RX2 0x160 0x5a4 0x000 0x0 0x0
+#define MX35_PAD_TX3_RX2__I2C3_SCL 0x160 0x5a4 0x91c 0x1 0x0
+#define MX35_PAD_TX3_RX2__EMI_NANDF_CE1 0x160 0x5a4 0x000 0x3 0x0
+#define MX35_PAD_TX3_RX2__GPIO1_12 0x160 0x5a4 0x000 0x5 0x0
+#define MX35_PAD_TX3_RX2__IPU_CSI_D_4 0x160 0x5a4 0x940 0x6 0x0
+#define MX35_PAD_TX3_RX2__KPP_ROW_1 0x160 0x5a4 0x974 0x7 0x1
+#define MX35_PAD_TX2_RX3__ESAI_TX2_RX3 0x164 0x5a8 0x000 0x0 0x0
+#define MX35_PAD_TX2_RX3__I2C3_SDA 0x164 0x5a8 0x920 0x1 0x0
+#define MX35_PAD_TX2_RX3__EMI_NANDF_CE2 0x164 0x5a8 0x000 0x3 0x0
+#define MX35_PAD_TX2_RX3__GPIO1_13 0x164 0x5a8 0x000 0x5 0x0
+#define MX35_PAD_TX2_RX3__IPU_CSI_D_5 0x164 0x5a8 0x944 0x6 0x0
+#define MX35_PAD_TX2_RX3__KPP_COL_0 0x164 0x5a8 0x950 0x7 0x1
+#define MX35_PAD_TX1__ESAI_TX1 0x168 0x5ac 0x000 0x0 0x0
+#define MX35_PAD_TX1__CCM_PMIC_RDY 0x168 0x5ac 0x7d4 0x1 0x1
+#define MX35_PAD_TX1__CSPI1_SS2 0x168 0x5ac 0x7d8 0x2 0x2
+#define MX35_PAD_TX1__EMI_NANDF_CE3 0x168 0x5ac 0x000 0x3 0x0
+#define MX35_PAD_TX1__UART2_RI 0x168 0x5ac 0x000 0x4 0x0
+#define MX35_PAD_TX1__GPIO1_14 0x168 0x5ac 0x000 0x5 0x0
+#define MX35_PAD_TX1__IPU_CSI_D_6 0x168 0x5ac 0x948 0x6 0x0
+#define MX35_PAD_TX1__KPP_COL_1 0x168 0x5ac 0x954 0x7 0x1
+#define MX35_PAD_TX0__ESAI_TX0 0x16c 0x5b0 0x000 0x0 0x0
+#define MX35_PAD_TX0__SPDIF_SPDIF_EXTCLK 0x16c 0x5b0 0x994 0x1 0x1
+#define MX35_PAD_TX0__CSPI1_SS3 0x16c 0x5b0 0x7dc 0x2 0x0
+#define MX35_PAD_TX0__EMI_DTACK_B 0x16c 0x5b0 0x800 0x3 0x1
+#define MX35_PAD_TX0__UART2_DCD 0x16c 0x5b0 0x000 0x4 0x0
+#define MX35_PAD_TX0__GPIO1_15 0x16c 0x5b0 0x000 0x5 0x0
+#define MX35_PAD_TX0__IPU_CSI_D_7 0x16c 0x5b0 0x94c 0x6 0x0
+#define MX35_PAD_TX0__KPP_COL_2 0x16c 0x5b0 0x958 0x7 0x1
+#define MX35_PAD_CSPI1_MOSI__CSPI1_MOSI 0x170 0x5b4 0x000 0x0 0x0
+#define MX35_PAD_CSPI1_MOSI__GPIO1_16 0x170 0x5b4 0x000 0x5 0x0
+#define MX35_PAD_CSPI1_MOSI__ECT_CTI_TRIG_OUT1_2 0x170 0x5b4 0x000 0x7 0x0
+#define MX35_PAD_CSPI1_MISO__CSPI1_MISO 0x174 0x5b8 0x000 0x0 0x0
+#define MX35_PAD_CSPI1_MISO__GPIO1_17 0x174 0x5b8 0x000 0x5 0x0
+#define MX35_PAD_CSPI1_MISO__ECT_CTI_TRIG_OUT1_3 0x174 0x5b8 0x000 0x7 0x0
+#define MX35_PAD_CSPI1_SS0__CSPI1_SS0 0x178 0x5bc 0x000 0x0 0x0
+#define MX35_PAD_CSPI1_SS0__OWIRE_LINE 0x178 0x5bc 0x990 0x1 0x1
+#define MX35_PAD_CSPI1_SS0__CSPI2_SS3 0x178 0x5bc 0x7fc 0x2 0x1
+#define MX35_PAD_CSPI1_SS0__GPIO1_18 0x178 0x5bc 0x000 0x5 0x0
+#define MX35_PAD_CSPI1_SS0__ECT_CTI_TRIG_OUT1_4 0x178 0x5bc 0x000 0x7 0x0
+#define MX35_PAD_CSPI1_SS1__CSPI1_SS1 0x17c 0x5c0 0x000 0x0 0x0
+#define MX35_PAD_CSPI1_SS1__PWM_PWMO 0x17c 0x5c0 0x000 0x1 0x0
+#define MX35_PAD_CSPI1_SS1__CCM_CLK32K 0x17c 0x5c0 0x7d0 0x2 0x1
+#define MX35_PAD_CSPI1_SS1__GPIO1_19 0x17c 0x5c0 0x000 0x5 0x0
+#define MX35_PAD_CSPI1_SS1__IPU_DIAGB_29 0x17c 0x5c0 0x000 0x6 0x0
+#define MX35_PAD_CSPI1_SS1__ECT_CTI_TRIG_OUT1_5 0x17c 0x5c0 0x000 0x7 0x0
+#define MX35_PAD_CSPI1_SCLK__CSPI1_SCLK 0x180 0x5c4 0x000 0x0 0x0
+#define MX35_PAD_CSPI1_SCLK__GPIO3_4 0x180 0x5c4 0x904 0x5 0x0
+#define MX35_PAD_CSPI1_SCLK__IPU_DIAGB_30 0x180 0x5c4 0x000 0x6 0x0
+#define MX35_PAD_CSPI1_SCLK__EMI_M3IF_CHOSEN_MASTER_1 0x180 0x5c4 0x000 0x7 0x0
+#define MX35_PAD_CSPI1_SPI_RDY__CSPI1_RDY 0x184 0x5c8 0x000 0x0 0x0
+#define MX35_PAD_CSPI1_SPI_RDY__GPIO3_5 0x184 0x5c8 0x908 0x5 0x0
+#define MX35_PAD_CSPI1_SPI_RDY__IPU_DIAGB_31 0x184 0x5c8 0x000 0x6 0x0
+#define MX35_PAD_CSPI1_SPI_RDY__EMI_M3IF_CHOSEN_MASTER_2 0x184 0x5c8 0x000 0x7 0x0
+#define MX35_PAD_RXD1__UART1_RXD_MUX 0x188 0x5cc 0x000 0x0 0x0
+#define MX35_PAD_RXD1__CSPI2_MOSI 0x188 0x5cc 0x7ec 0x1 0x1
+#define MX35_PAD_RXD1__KPP_COL_4 0x188 0x5cc 0x960 0x4 0x0
+#define MX35_PAD_RXD1__GPIO3_6 0x188 0x5cc 0x90c 0x5 0x0
+#define MX35_PAD_RXD1__ARM11P_TOP_EVNTBUS_16 0x188 0x5cc 0x000 0x7 0x0
+#define MX35_PAD_TXD1__UART1_TXD_MUX 0x18c 0x5d0 0x000 0x0 0x0
+#define MX35_PAD_TXD1__CSPI2_MISO 0x18c 0x5d0 0x7e8 0x1 0x1
+#define MX35_PAD_TXD1__KPP_COL_5 0x18c 0x5d0 0x964 0x4 0x0
+#define MX35_PAD_TXD1__GPIO3_7 0x18c 0x5d0 0x910 0x5 0x0
+#define MX35_PAD_TXD1__ARM11P_TOP_EVNTBUS_17 0x18c 0x5d0 0x000 0x7 0x0
+#define MX35_PAD_RTS1__UART1_RTS 0x190 0x5d4 0x000 0x0 0x0
+#define MX35_PAD_RTS1__CSPI2_SCLK 0x190 0x5d4 0x7e0 0x1 0x1
+#define MX35_PAD_RTS1__I2C3_SCL 0x190 0x5d4 0x91c 0x2 0x1
+#define MX35_PAD_RTS1__IPU_CSI_D_0 0x190 0x5d4 0x930 0x3 0x1
+#define MX35_PAD_RTS1__KPP_COL_6 0x190 0x5d4 0x968 0x4 0x0
+#define MX35_PAD_RTS1__GPIO3_8 0x190 0x5d4 0x914 0x5 0x0
+#define MX35_PAD_RTS1__EMI_NANDF_CE1 0x190 0x5d4 0x000 0x6 0x0
+#define MX35_PAD_RTS1__ARM11P_TOP_EVNTBUS_18 0x190 0x5d4 0x000 0x7 0x0
+#define MX35_PAD_CTS1__UART1_CTS 0x194 0x5d8 0x000 0x0 0x0
+#define MX35_PAD_CTS1__CSPI2_RDY 0x194 0x5d8 0x7e4 0x1 0x1
+#define MX35_PAD_CTS1__I2C3_SDA 0x194 0x5d8 0x920 0x2 0x1
+#define MX35_PAD_CTS1__IPU_CSI_D_1 0x194 0x5d8 0x934 0x3 0x1
+#define MX35_PAD_CTS1__KPP_COL_7 0x194 0x5d8 0x96c 0x4 0x0
+#define MX35_PAD_CTS1__GPIO3_9 0x194 0x5d8 0x918 0x5 0x0
+#define MX35_PAD_CTS1__EMI_NANDF_CE2 0x194 0x5d8 0x000 0x6 0x0
+#define MX35_PAD_CTS1__ARM11P_TOP_EVNTBUS_19 0x194 0x5d8 0x000 0x7 0x0
+#define MX35_PAD_RXD2__UART2_RXD_MUX 0x198 0x5dc 0x000 0x0 0x0
+#define MX35_PAD_RXD2__KPP_ROW_4 0x198 0x5dc 0x980 0x4 0x0
+#define MX35_PAD_RXD2__GPIO3_10 0x198 0x5dc 0x8ec 0x5 0x0
+#define MX35_PAD_TXD2__UART2_TXD_MUX 0x19c 0x5e0 0x000 0x0 0x0
+#define MX35_PAD_TXD2__SPDIF_SPDIF_EXTCLK 0x19c 0x5e0 0x994 0x1 0x2
+#define MX35_PAD_TXD2__KPP_ROW_5 0x19c 0x5e0 0x984 0x4 0x0
+#define MX35_PAD_TXD2__GPIO3_11 0x19c 0x5e0 0x8f0 0x5 0x0
+#define MX35_PAD_RTS2__UART2_RTS 0x1a0 0x5e4 0x000 0x0 0x0
+#define MX35_PAD_RTS2__SPDIF_SPDIF_IN1 0x1a0 0x5e4 0x998 0x1 0x1
+#define MX35_PAD_RTS2__CAN2_RXCAN 0x1a0 0x5e4 0x7cc 0x2 0x1
+#define MX35_PAD_RTS2__IPU_CSI_D_2 0x1a0 0x5e4 0x938 0x3 0x1
+#define MX35_PAD_RTS2__KPP_ROW_6 0x1a0 0x5e4 0x988 0x4 0x0
+#define MX35_PAD_RTS2__GPIO3_12 0x1a0 0x5e4 0x8f4 0x5 0x0
+#define MX35_PAD_RTS2__AUDMUX_AUD5_RXC 0x1a0 0x5e4 0x000 0x6 0x0
+#define MX35_PAD_RTS2__UART3_RXD_MUX 0x1a0 0x5e4 0x9a0 0x7 0x0
+#define MX35_PAD_CTS2__UART2_CTS 0x1a4 0x5e8 0x000 0x0 0x0
+#define MX35_PAD_CTS2__SPDIF_SPDIF_OUT1 0x1a4 0x5e8 0x000 0x1 0x0
+#define MX35_PAD_CTS2__CAN2_TXCAN 0x1a4 0x5e8 0x000 0x2 0x0
+#define MX35_PAD_CTS2__IPU_CSI_D_3 0x1a4 0x5e8 0x93c 0x3 0x1
+#define MX35_PAD_CTS2__KPP_ROW_7 0x1a4 0x5e8 0x98c 0x4 0x0
+#define MX35_PAD_CTS2__GPIO3_13 0x1a4 0x5e8 0x8f8 0x5 0x0
+#define MX35_PAD_CTS2__AUDMUX_AUD5_RXFS 0x1a4 0x5e8 0x000 0x6 0x0
+#define MX35_PAD_CTS2__UART3_TXD_MUX 0x1a4 0x5e8 0x000 0x7 0x0
+#define MX35_PAD_RTCK__ARM11P_TOP_RTCK 0x000 0x5ec 0x000 0x0 0x0
+#define MX35_PAD_TCK__SJC_TCK 0x000 0x5f0 0x000 0x0 0x0
+#define MX35_PAD_TMS__SJC_TMS 0x000 0x5f4 0x000 0x0 0x0
+#define MX35_PAD_TDI__SJC_TDI 0x000 0x5f8 0x000 0x0 0x0
+#define MX35_PAD_TDO__SJC_TDO 0x000 0x5fc 0x000 0x0 0x0
+#define MX35_PAD_TRSTB__SJC_TRSTB 0x000 0x600 0x000 0x0 0x0
+#define MX35_PAD_DE_B__SJC_DE_B 0x000 0x604 0x000 0x0 0x0
+#define MX35_PAD_SJC_MOD__SJC_MOD 0x000 0x608 0x000 0x0 0x0
+#define MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR 0x1a8 0x60c 0x000 0x0 0x0
+#define MX35_PAD_USBOTG_PWR__USB_TOP_USBH2_PWR 0x1a8 0x60c 0x000 0x1 0x0
+#define MX35_PAD_USBOTG_PWR__GPIO3_14 0x1a8 0x60c 0x8fc 0x5 0x0
+#define MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC 0x1ac 0x610 0x000 0x0 0x0
+#define MX35_PAD_USBOTG_OC__USB_TOP_USBH2_OC 0x1ac 0x610 0x9f4 0x1 0x1
+#define MX35_PAD_USBOTG_OC__GPIO3_15 0x1ac 0x610 0x900 0x5 0x0
+#define MX35_PAD_LD0__IPU_DISPB_DAT_0 0x1b0 0x614 0x000 0x0 0x0
+#define MX35_PAD_LD0__GPIO2_0 0x1b0 0x614 0x868 0x5 0x1
+#define MX35_PAD_LD0__SDMA_SDMA_DEBUG_PC_0 0x1b0 0x614 0x000 0x6 0x0
+#define MX35_PAD_LD1__IPU_DISPB_DAT_1 0x1b4 0x618 0x000 0x0 0x0
+#define MX35_PAD_LD1__GPIO2_1 0x1b4 0x618 0x894 0x5 0x0
+#define MX35_PAD_LD1__SDMA_SDMA_DEBUG_PC_1 0x1b4 0x618 0x000 0x6 0x0
+#define MX35_PAD_LD2__IPU_DISPB_DAT_2 0x1b8 0x61c 0x000 0x0 0x0
+#define MX35_PAD_LD2__GPIO2_2 0x1b8 0x61c 0x8c0 0x5 0x0
+#define MX35_PAD_LD2__SDMA_SDMA_DEBUG_PC_2 0x1b8 0x61c 0x000 0x6 0x0
+#define MX35_PAD_LD3__IPU_DISPB_DAT_3 0x1bc 0x620 0x000 0x0 0x0
+#define MX35_PAD_LD3__GPIO2_3 0x1bc 0x620 0x8cc 0x5 0x0
+#define MX35_PAD_LD3__SDMA_SDMA_DEBUG_PC_3 0x1bc 0x620 0x000 0x6 0x0
+#define MX35_PAD_LD4__IPU_DISPB_DAT_4 0x1c0 0x624 0x000 0x0 0x0
+#define MX35_PAD_LD4__GPIO2_4 0x1c0 0x624 0x8d0 0x5 0x0
+#define MX35_PAD_LD4__SDMA_SDMA_DEBUG_PC_4 0x1c0 0x624 0x000 0x6 0x0
+#define MX35_PAD_LD5__IPU_DISPB_DAT_5 0x1c4 0x628 0x000 0x0 0x0
+#define MX35_PAD_LD5__GPIO2_5 0x1c4 0x628 0x8d4 0x5 0x0
+#define MX35_PAD_LD5__SDMA_SDMA_DEBUG_PC_5 0x1c4 0x628 0x000 0x6 0x0
+#define MX35_PAD_LD6__IPU_DISPB_DAT_6 0x1c8 0x62c 0x000 0x0 0x0
+#define MX35_PAD_LD6__GPIO2_6 0x1c8 0x62c 0x8d8 0x5 0x0
+#define MX35_PAD_LD6__SDMA_SDMA_DEBUG_PC_6 0x1c8 0x62c 0x000 0x6 0x0
+#define MX35_PAD_LD7__IPU_DISPB_DAT_7 0x1cc 0x630 0x000 0x0 0x0
+#define MX35_PAD_LD7__GPIO2_7 0x1cc 0x630 0x8dc 0x5 0x0
+#define MX35_PAD_LD7__SDMA_SDMA_DEBUG_PC_7 0x1cc 0x630 0x000 0x6 0x0
+#define MX35_PAD_LD8__IPU_DISPB_DAT_8 0x1d0 0x634 0x000 0x0 0x0
+#define MX35_PAD_LD8__GPIO2_8 0x1d0 0x634 0x8e0 0x5 0x0
+#define MX35_PAD_LD8__SDMA_SDMA_DEBUG_PC_8 0x1d0 0x634 0x000 0x6 0x0
+#define MX35_PAD_LD9__IPU_DISPB_DAT_9 0x1d4 0x638 0x000 0x0 0x0
+#define MX35_PAD_LD9__GPIO2_9 0x1d4 0x638 0x8e4 0x5 0x0
+#define MX35_PAD_LD9__SDMA_SDMA_DEBUG_PC_9 0x1d4 0x638 0x000 0x6 0x0
+#define MX35_PAD_LD10__IPU_DISPB_DAT_10 0x1d8 0x63c 0x000 0x0 0x0
+#define MX35_PAD_LD10__GPIO2_10 0x1d8 0x63c 0x86c 0x5 0x0
+#define MX35_PAD_LD10__SDMA_SDMA_DEBUG_PC_10 0x1d8 0x63c 0x000 0x6 0x0
+#define MX35_PAD_LD11__IPU_DISPB_DAT_11 0x1dc 0x640 0x000 0x0 0x0
+#define MX35_PAD_LD11__GPIO2_11 0x1dc 0x640 0x870 0x5 0x0
+#define MX35_PAD_LD11__SDMA_SDMA_DEBUG_PC_11 0x1dc 0x640 0x000 0x6 0x0
+#define MX35_PAD_LD11__ARM11P_TOP_TRACE_4 0x1dc 0x640 0x000 0x7 0x0
+#define MX35_PAD_LD12__IPU_DISPB_DAT_12 0x1e0 0x644 0x000 0x0 0x0
+#define MX35_PAD_LD12__GPIO2_12 0x1e0 0x644 0x874 0x5 0x0
+#define MX35_PAD_LD12__SDMA_SDMA_DEBUG_PC_12 0x1e0 0x644 0x000 0x6 0x0
+#define MX35_PAD_LD12__ARM11P_TOP_TRACE_5 0x1e0 0x644 0x000 0x7 0x0
+#define MX35_PAD_LD13__IPU_DISPB_DAT_13 0x1e4 0x648 0x000 0x0 0x0
+#define MX35_PAD_LD13__GPIO2_13 0x1e4 0x648 0x878 0x5 0x0
+#define MX35_PAD_LD13__SDMA_SDMA_DEBUG_PC_13 0x1e4 0x648 0x000 0x6 0x0
+#define MX35_PAD_LD13__ARM11P_TOP_TRACE_6 0x1e4 0x648 0x000 0x7 0x0
+#define MX35_PAD_LD14__IPU_DISPB_DAT_14 0x1e8 0x64c 0x000 0x0 0x0
+#define MX35_PAD_LD14__GPIO2_14 0x1e8 0x64c 0x87c 0x5 0x0
+#define MX35_PAD_LD14__SDMA_SDMA_DEBUG_EVENT_CHANNEL_0 0x1e8 0x64c 0x000 0x6 0x0
+#define MX35_PAD_LD14__ARM11P_TOP_TRACE_7 0x1e8 0x64c 0x000 0x7 0x0
+#define MX35_PAD_LD15__IPU_DISPB_DAT_15 0x1ec 0x650 0x000 0x0 0x0
+#define MX35_PAD_LD15__GPIO2_15 0x1ec 0x650 0x880 0x5 0x0
+#define MX35_PAD_LD15__SDMA_SDMA_DEBUG_EVENT_CHANNEL_1 0x1ec 0x650 0x000 0x6 0x0
+#define MX35_PAD_LD15__ARM11P_TOP_TRACE_8 0x1ec 0x650 0x000 0x7 0x0
+#define MX35_PAD_LD16__IPU_DISPB_DAT_16 0x1f0 0x654 0x000 0x0 0x0
+#define MX35_PAD_LD16__IPU_DISPB_D12_VSYNC 0x1f0 0x654 0x928 0x2 0x0
+#define MX35_PAD_LD16__GPIO2_16 0x1f0 0x654 0x884 0x5 0x0
+#define MX35_PAD_LD16__SDMA_SDMA_DEBUG_EVENT_CHANNEL_2 0x1f0 0x654 0x000 0x6 0x0
+#define MX35_PAD_LD16__ARM11P_TOP_TRACE_9 0x1f0 0x654 0x000 0x7 0x0
+#define MX35_PAD_LD17__IPU_DISPB_DAT_17 0x1f4 0x658 0x000 0x0 0x0
+#define MX35_PAD_LD17__IPU_DISPB_CS2 0x1f4 0x658 0x000 0x2 0x0
+#define MX35_PAD_LD17__GPIO2_17 0x1f4 0x658 0x888 0x5 0x0
+#define MX35_PAD_LD17__SDMA_SDMA_DEBUG_EVENT_CHANNEL_3 0x1f4 0x658 0x000 0x6 0x0
+#define MX35_PAD_LD17__ARM11P_TOP_TRACE_10 0x1f4 0x658 0x000 0x7 0x0
+#define MX35_PAD_LD18__IPU_DISPB_DAT_18 0x1f8 0x65c 0x000 0x0 0x0
+#define MX35_PAD_LD18__IPU_DISPB_D0_VSYNC 0x1f8 0x65c 0x924 0x1 0x1
+#define MX35_PAD_LD18__IPU_DISPB_D12_VSYNC 0x1f8 0x65c 0x928 0x2 0x1
+#define MX35_PAD_LD18__ESDHC3_CMD 0x1f8 0x65c 0x818 0x3 0x0
+#define MX35_PAD_LD18__USB_TOP_USBOTG_DATA_3 0x1f8 0x65c 0x9b0 0x4 0x0
+#define MX35_PAD_LD18__GPIO3_24 0x1f8 0x65c 0x000 0x5 0x0
+#define MX35_PAD_LD18__SDMA_SDMA_DEBUG_EVENT_CHANNEL_4 0x1f8 0x65c 0x000 0x6 0x0
+#define MX35_PAD_LD18__ARM11P_TOP_TRACE_11 0x1f8 0x65c 0x000 0x7 0x0
+#define MX35_PAD_LD19__IPU_DISPB_DAT_19 0x1fc 0x660 0x000 0x0 0x0
+#define MX35_PAD_LD19__IPU_DISPB_BCLK 0x1fc 0x660 0x000 0x1 0x0
+#define MX35_PAD_LD19__IPU_DISPB_CS1 0x1fc 0x660 0x000 0x2 0x0
+#define MX35_PAD_LD19__ESDHC3_CLK 0x1fc 0x660 0x814 0x3 0x0
+#define MX35_PAD_LD19__USB_TOP_USBOTG_DIR 0x1fc 0x660 0x9c4 0x4 0x0
+#define MX35_PAD_LD19__GPIO3_25 0x1fc 0x660 0x000 0x5 0x0
+#define MX35_PAD_LD19__SDMA_SDMA_DEBUG_EVENT_CHANNEL_5 0x1fc 0x660 0x000 0x6 0x0
+#define MX35_PAD_LD19__ARM11P_TOP_TRACE_12 0x1fc 0x660 0x000 0x7 0x0
+#define MX35_PAD_LD20__IPU_DISPB_DAT_20 0x200 0x664 0x000 0x0 0x0
+#define MX35_PAD_LD20__IPU_DISPB_CS0 0x200 0x664 0x000 0x1 0x0
+#define MX35_PAD_LD20__IPU_DISPB_SD_CLK 0x200 0x664 0x000 0x2 0x0
+#define MX35_PAD_LD20__ESDHC3_DAT0 0x200 0x664 0x81c 0x3 0x0
+#define MX35_PAD_LD20__GPIO3_26 0x200 0x664 0x000 0x5 0x0
+#define MX35_PAD_LD20__SDMA_SDMA_DEBUG_CORE_STATUS_3 0x200 0x664 0x000 0x6 0x0
+#define MX35_PAD_LD20__ARM11P_TOP_TRACE_13 0x200 0x664 0x000 0x7 0x0
+#define MX35_PAD_LD21__IPU_DISPB_DAT_21 0x204 0x668 0x000 0x0 0x0
+#define MX35_PAD_LD21__IPU_DISPB_PAR_RS 0x204 0x668 0x000 0x1 0x0
+#define MX35_PAD_LD21__IPU_DISPB_SER_RS 0x204 0x668 0x000 0x2 0x0
+#define MX35_PAD_LD21__ESDHC3_DAT1 0x204 0x668 0x820 0x3 0x0
+#define MX35_PAD_LD21__USB_TOP_USBOTG_STP 0x204 0x668 0x000 0x4 0x0
+#define MX35_PAD_LD21__GPIO3_27 0x204 0x668 0x000 0x5 0x0
+#define MX35_PAD_LD21__SDMA_DEBUG_EVENT_CHANNEL_SEL 0x204 0x668 0x000 0x6 0x0
+#define MX35_PAD_LD21__ARM11P_TOP_TRACE_14 0x204 0x668 0x000 0x7 0x0
+#define MX35_PAD_LD22__IPU_DISPB_DAT_22 0x208 0x66c 0x000 0x0 0x0
+#define MX35_PAD_LD22__IPU_DISPB_WR 0x208 0x66c 0x000 0x1 0x0
+#define MX35_PAD_LD22__IPU_DISPB_SD_D_I 0x208 0x66c 0x92c 0x2 0x0
+#define MX35_PAD_LD22__ESDHC3_DAT2 0x208 0x66c 0x824 0x3 0x0
+#define MX35_PAD_LD22__USB_TOP_USBOTG_NXT 0x208 0x66c 0x9c8 0x4 0x0
+#define MX35_PAD_LD22__GPIO3_28 0x208 0x66c 0x000 0x5 0x0
+#define MX35_PAD_LD22__SDMA_DEBUG_BUS_ERROR 0x208 0x66c 0x000 0x6 0x0
+#define MX35_PAD_LD22__ARM11P_TOP_TRCTL 0x208 0x66c 0x000 0x7 0x0
+#define MX35_PAD_LD23__IPU_DISPB_DAT_23 0x20c 0x670 0x000 0x0 0x0
+#define MX35_PAD_LD23__IPU_DISPB_RD 0x20c 0x670 0x000 0x1 0x0
+#define MX35_PAD_LD23__IPU_DISPB_SD_D_IO 0x20c 0x670 0x92c 0x2 0x1
+#define MX35_PAD_LD23__ESDHC3_DAT3 0x20c 0x670 0x828 0x3 0x0
+#define MX35_PAD_LD23__USB_TOP_USBOTG_DATA_7 0x20c 0x670 0x9c0 0x4 0x0
+#define MX35_PAD_LD23__GPIO3_29 0x20c 0x670 0x000 0x5 0x0
+#define MX35_PAD_LD23__SDMA_DEBUG_MATCHED_DMBUS 0x20c 0x670 0x000 0x6 0x0
+#define MX35_PAD_LD23__ARM11P_TOP_TRCLK 0x20c 0x670 0x000 0x7 0x0
+#define MX35_PAD_D3_HSYNC__IPU_DISPB_D3_HSYNC 0x210 0x674 0x000 0x0 0x0
+#define MX35_PAD_D3_HSYNC__IPU_DISPB_SD_D_IO 0x210 0x674 0x92c 0x2 0x2
+#define MX35_PAD_D3_HSYNC__GPIO3_30 0x210 0x674 0x000 0x5 0x0
+#define MX35_PAD_D3_HSYNC__SDMA_DEBUG_RTBUFFER_WRITE 0x210 0x674 0x000 0x6 0x0
+#define MX35_PAD_D3_HSYNC__ARM11P_TOP_TRACE_15 0x210 0x674 0x000 0x7 0x0
+#define MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK 0x214 0x678 0x000 0x0 0x0
+#define MX35_PAD_D3_FPSHIFT__IPU_DISPB_SD_CLK 0x214 0x678 0x000 0x2 0x0
+#define MX35_PAD_D3_FPSHIFT__GPIO3_31 0x214 0x678 0x000 0x5 0x0
+#define MX35_PAD_D3_FPSHIFT__SDMA_SDMA_DEBUG_CORE_STATUS_0 0x214 0x678 0x000 0x6 0x0
+#define MX35_PAD_D3_FPSHIFT__ARM11P_TOP_TRACE_16 0x214 0x678 0x000 0x7 0x0
+#define MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY 0x218 0x67c 0x000 0x0 0x0
+#define MX35_PAD_D3_DRDY__IPU_DISPB_SD_D_O 0x218 0x67c 0x000 0x2 0x0
+#define MX35_PAD_D3_DRDY__GPIO1_0 0x218 0x67c 0x82c 0x5 0x2
+#define MX35_PAD_D3_DRDY__SDMA_SDMA_DEBUG_CORE_STATUS_1 0x218 0x67c 0x000 0x6 0x0
+#define MX35_PAD_D3_DRDY__ARM11P_TOP_TRACE_17 0x218 0x67c 0x000 0x7 0x0
+#define MX35_PAD_CONTRAST__IPU_DISPB_CONTR 0x21c 0x680 0x000 0x0 0x0
+#define MX35_PAD_CONTRAST__GPIO1_1 0x21c 0x680 0x838 0x5 0x2
+#define MX35_PAD_CONTRAST__SDMA_SDMA_DEBUG_CORE_STATUS_2 0x21c 0x680 0x000 0x6 0x0
+#define MX35_PAD_CONTRAST__ARM11P_TOP_TRACE_18 0x21c 0x680 0x000 0x7 0x0
+#define MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC 0x220 0x684 0x000 0x0 0x0
+#define MX35_PAD_D3_VSYNC__IPU_DISPB_CS1 0x220 0x684 0x000 0x2 0x0
+#define MX35_PAD_D3_VSYNC__GPIO1_2 0x220 0x684 0x848 0x5 0x1
+#define MX35_PAD_D3_VSYNC__SDMA_DEBUG_YIELD 0x220 0x684 0x000 0x6 0x0
+#define MX35_PAD_D3_VSYNC__ARM11P_TOP_TRACE_19 0x220 0x684 0x000 0x7 0x0
+#define MX35_PAD_D3_REV__IPU_DISPB_D3_REV 0x224 0x688 0x000 0x0 0x0
+#define MX35_PAD_D3_REV__IPU_DISPB_SER_RS 0x224 0x688 0x000 0x2 0x0
+#define MX35_PAD_D3_REV__GPIO1_3 0x224 0x688 0x84c 0x5 0x1
+#define MX35_PAD_D3_REV__SDMA_DEBUG_BUS_RWB 0x224 0x688 0x000 0x6 0x0
+#define MX35_PAD_D3_REV__ARM11P_TOP_TRACE_20 0x224 0x688 0x000 0x7 0x0
+#define MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS 0x228 0x68c 0x000 0x0 0x0
+#define MX35_PAD_D3_CLS__IPU_DISPB_CS2 0x228 0x68c 0x000 0x2 0x0
+#define MX35_PAD_D3_CLS__GPIO1_4 0x228 0x68c 0x850 0x5 0x2
+#define MX35_PAD_D3_CLS__SDMA_DEBUG_BUS_DEVICE_0 0x228 0x68c 0x000 0x6 0x0
+#define MX35_PAD_D3_CLS__ARM11P_TOP_TRACE_21 0x228 0x68c 0x000 0x7 0x0
+#define MX35_PAD_D3_SPL__IPU_DISPB_D3_SPL 0x22c 0x690 0x000 0x0 0x0
+#define MX35_PAD_D3_SPL__IPU_DISPB_D12_VSYNC 0x22c 0x690 0x928 0x2 0x2
+#define MX35_PAD_D3_SPL__GPIO1_5 0x22c 0x690 0x854 0x5 0x2
+#define MX35_PAD_D3_SPL__SDMA_DEBUG_BUS_DEVICE_1 0x22c 0x690 0x000 0x6 0x0
+#define MX35_PAD_D3_SPL__ARM11P_TOP_TRACE_22 0x22c 0x690 0x000 0x7 0x0
+#define MX35_PAD_SD1_CMD__ESDHC1_CMD 0x230 0x694 0x000 0x0 0x0
+#define MX35_PAD_SD1_CMD__MSHC_SCLK 0x230 0x694 0x000 0x1 0x0
+#define MX35_PAD_SD1_CMD__IPU_DISPB_D0_VSYNC 0x230 0x694 0x924 0x3 0x2
+#define MX35_PAD_SD1_CMD__USB_TOP_USBOTG_DATA_4 0x230 0x694 0x9b4 0x4 0x0
+#define MX35_PAD_SD1_CMD__GPIO1_6 0x230 0x694 0x858 0x5 0x2
+#define MX35_PAD_SD1_CMD__ARM11P_TOP_TRCTL 0x230 0x694 0x000 0x7 0x0
+#define MX35_PAD_SD1_CLK__ESDHC1_CLK 0x234 0x698 0x000 0x0 0x0
+#define MX35_PAD_SD1_CLK__MSHC_BS 0x234 0x698 0x000 0x1 0x0
+#define MX35_PAD_SD1_CLK__IPU_DISPB_BCLK 0x234 0x698 0x000 0x3 0x0
+#define MX35_PAD_SD1_CLK__USB_TOP_USBOTG_DATA_5 0x234 0x698 0x9b8 0x4 0x0
+#define MX35_PAD_SD1_CLK__GPIO1_7 0x234 0x698 0x85c 0x5 0x2
+#define MX35_PAD_SD1_CLK__ARM11P_TOP_TRCLK 0x234 0x698 0x000 0x7 0x0
+#define MX35_PAD_SD1_DATA0__ESDHC1_DAT0 0x238 0x69c 0x000 0x0 0x0
+#define MX35_PAD_SD1_DATA0__MSHC_DATA_0 0x238 0x69c 0x000 0x1 0x0
+#define MX35_PAD_SD1_DATA0__IPU_DISPB_CS0 0x238 0x69c 0x000 0x3 0x0
+#define MX35_PAD_SD1_DATA0__USB_TOP_USBOTG_DATA_6 0x238 0x69c 0x9bc 0x4 0x0
+#define MX35_PAD_SD1_DATA0__GPIO1_8 0x238 0x69c 0x860 0x5 0x2
+#define MX35_PAD_SD1_DATA0__ARM11P_TOP_TRACE_23 0x238 0x69c 0x000 0x7 0x0
+#define MX35_PAD_SD1_DATA1__ESDHC1_DAT1 0x23c 0x6a0 0x000 0x0 0x0
+#define MX35_PAD_SD1_DATA1__MSHC_DATA_1 0x23c 0x6a0 0x000 0x1 0x0
+#define MX35_PAD_SD1_DATA1__IPU_DISPB_PAR_RS 0x23c 0x6a0 0x000 0x3 0x0
+#define MX35_PAD_SD1_DATA1__USB_TOP_USBOTG_DATA_0 0x23c 0x6a0 0x9a4 0x4 0x0
+#define MX35_PAD_SD1_DATA1__GPIO1_9 0x23c 0x6a0 0x864 0x5 0x1
+#define MX35_PAD_SD1_DATA1__ARM11P_TOP_TRACE_24 0x23c 0x6a0 0x000 0x7 0x0
+#define MX35_PAD_SD1_DATA2__ESDHC1_DAT2 0x240 0x6a4 0x000 0x0 0x0
+#define MX35_PAD_SD1_DATA2__MSHC_DATA_2 0x240 0x6a4 0x000 0x1 0x0
+#define MX35_PAD_SD1_DATA2__IPU_DISPB_WR 0x240 0x6a4 0x000 0x3 0x0
+#define MX35_PAD_SD1_DATA2__USB_TOP_USBOTG_DATA_1 0x240 0x6a4 0x9a8 0x4 0x0
+#define MX35_PAD_SD1_DATA2__GPIO1_10 0x240 0x6a4 0x830 0x5 0x1
+#define MX35_PAD_SD1_DATA2__ARM11P_TOP_TRACE_25 0x240 0x6a4 0x000 0x7 0x0
+#define MX35_PAD_SD1_DATA3__ESDHC1_DAT3 0x244 0x6a8 0x000 0x0 0x0
+#define MX35_PAD_SD1_DATA3__MSHC_DATA_3 0x244 0x6a8 0x000 0x1 0x0
+#define MX35_PAD_SD1_DATA3__IPU_DISPB_RD 0x244 0x6a8 0x000 0x3 0x0
+#define MX35_PAD_SD1_DATA3__USB_TOP_USBOTG_DATA_2 0x244 0x6a8 0x9ac 0x4 0x0
+#define MX35_PAD_SD1_DATA3__GPIO1_11 0x244 0x6a8 0x834 0x5 0x1
+#define MX35_PAD_SD1_DATA3__ARM11P_TOP_TRACE_26 0x244 0x6a8 0x000 0x7 0x0
+#define MX35_PAD_SD2_CMD__ESDHC2_CMD 0x248 0x6ac 0x000 0x0 0x0
+#define MX35_PAD_SD2_CMD__I2C3_SCL 0x248 0x6ac 0x91c 0x1 0x2
+#define MX35_PAD_SD2_CMD__ESDHC1_DAT4 0x248 0x6ac 0x804 0x2 0x0
+#define MX35_PAD_SD2_CMD__IPU_CSI_D_2 0x248 0x6ac 0x938 0x3 0x2
+#define MX35_PAD_SD2_CMD__USB_TOP_USBH2_DATA_4 0x248 0x6ac 0x9dc 0x4 0x0
+#define MX35_PAD_SD2_CMD__GPIO2_0 0x248 0x6ac 0x868 0x5 0x2
+#define MX35_PAD_SD2_CMD__SPDIF_SPDIF_OUT1 0x248 0x6ac 0x000 0x6 0x0
+#define MX35_PAD_SD2_CMD__IPU_DISPB_D12_VSYNC 0x248 0x6ac 0x928 0x7 0x3
+#define MX35_PAD_SD2_CLK__ESDHC2_CLK 0x24c 0x6b0 0x000 0x0 0x0
+#define MX35_PAD_SD2_CLK__I2C3_SDA 0x24c 0x6b0 0x920 0x1 0x2
+#define MX35_PAD_SD2_CLK__ESDHC1_DAT5 0x24c 0x6b0 0x808 0x2 0x0
+#define MX35_PAD_SD2_CLK__IPU_CSI_D_3 0x24c 0x6b0 0x93c 0x3 0x2
+#define MX35_PAD_SD2_CLK__USB_TOP_USBH2_DATA_5 0x24c 0x6b0 0x9e0 0x4 0x0
+#define MX35_PAD_SD2_CLK__GPIO2_1 0x24c 0x6b0 0x894 0x5 0x1
+#define MX35_PAD_SD2_CLK__SPDIF_SPDIF_IN1 0x24c 0x6b0 0x998 0x6 0x2
+#define MX35_PAD_SD2_CLK__IPU_DISPB_CS2 0x24c 0x6b0 0x000 0x7 0x0
+#define MX35_PAD_SD2_DATA0__ESDHC2_DAT0 0x250 0x6b4 0x000 0x0 0x0
+#define MX35_PAD_SD2_DATA0__UART3_RXD_MUX 0x250 0x6b4 0x9a0 0x1 0x1
+#define MX35_PAD_SD2_DATA0__ESDHC1_DAT6 0x250 0x6b4 0x80c 0x2 0x0
+#define MX35_PAD_SD2_DATA0__IPU_CSI_D_4 0x250 0x6b4 0x940 0x3 0x1
+#define MX35_PAD_SD2_DATA0__USB_TOP_USBH2_DATA_6 0x250 0x6b4 0x9e4 0x4 0x0
+#define MX35_PAD_SD2_DATA0__GPIO2_2 0x250 0x6b4 0x8c0 0x5 0x1
+#define MX35_PAD_SD2_DATA0__SPDIF_SPDIF_EXTCLK 0x250 0x6b4 0x994 0x6 0x3
+#define MX35_PAD_SD2_DATA1__ESDHC2_DAT1 0x254 0x6b8 0x000 0x0 0x0
+#define MX35_PAD_SD2_DATA1__UART3_TXD_MUX 0x254 0x6b8 0x000 0x1 0x0
+#define MX35_PAD_SD2_DATA1__ESDHC1_DAT7 0x254 0x6b8 0x810 0x2 0x0
+#define MX35_PAD_SD2_DATA1__IPU_CSI_D_5 0x254 0x6b8 0x944 0x3 0x1
+#define MX35_PAD_SD2_DATA1__USB_TOP_USBH2_DATA_0 0x254 0x6b8 0x9cc 0x4 0x0
+#define MX35_PAD_SD2_DATA1__GPIO2_3 0x254 0x6b8 0x8cc 0x5 0x1
+#define MX35_PAD_SD2_DATA2__ESDHC2_DAT2 0x258 0x6bc 0x000 0x0 0x0
+#define MX35_PAD_SD2_DATA2__UART3_RTS 0x258 0x6bc 0x99c 0x1 0x0
+#define MX35_PAD_SD2_DATA2__CAN1_RXCAN 0x258 0x6bc 0x7c8 0x2 0x1
+#define MX35_PAD_SD2_DATA2__IPU_CSI_D_6 0x258 0x6bc 0x948 0x3 0x1
+#define MX35_PAD_SD2_DATA2__USB_TOP_USBH2_DATA_1 0x258 0x6bc 0x9d0 0x4 0x0
+#define MX35_PAD_SD2_DATA2__GPIO2_4 0x258 0x6bc 0x8d0 0x5 0x1
+#define MX35_PAD_SD2_DATA3__ESDHC2_DAT3 0x25c 0x6c0 0x000 0x0 0x0
+#define MX35_PAD_SD2_DATA3__UART3_CTS 0x25c 0x6c0 0x000 0x1 0x0
+#define MX35_PAD_SD2_DATA3__CAN1_TXCAN 0x25c 0x6c0 0x000 0x2 0x0
+#define MX35_PAD_SD2_DATA3__IPU_CSI_D_7 0x25c 0x6c0 0x94c 0x3 0x1
+#define MX35_PAD_SD2_DATA3__USB_TOP_USBH2_DATA_2 0x25c 0x6c0 0x9d4 0x4 0x0
+#define MX35_PAD_SD2_DATA3__GPIO2_5 0x25c 0x6c0 0x8d4 0x5 0x1
+#define MX35_PAD_ATA_CS0__ATA_CS0 0x260 0x6c4 0x000 0x0 0x0
+#define MX35_PAD_ATA_CS0__CSPI1_SS3 0x260 0x6c4 0x7dc 0x1 0x1
+#define MX35_PAD_ATA_CS0__IPU_DISPB_CS1 0x260 0x6c4 0x000 0x3 0x0
+#define MX35_PAD_ATA_CS0__GPIO2_6 0x260 0x6c4 0x8d8 0x5 0x1
+#define MX35_PAD_ATA_CS0__IPU_DIAGB_0 0x260 0x6c4 0x000 0x6 0x0
+#define MX35_PAD_ATA_CS0__ARM11P_TOP_MAX1_HMASTER_0 0x260 0x6c4 0x000 0x7 0x0
+#define MX35_PAD_ATA_CS1__ATA_CS1 0x264 0x6c8 0x000 0x0 0x0
+#define MX35_PAD_ATA_CS1__IPU_DISPB_CS2 0x264 0x6c8 0x000 0x3 0x0
+#define MX35_PAD_ATA_CS1__CSPI2_SS0 0x264 0x6c8 0x7f0 0x4 0x1
+#define MX35_PAD_ATA_CS1__GPIO2_7 0x264 0x6c8 0x8dc 0x5 0x1
+#define MX35_PAD_ATA_CS1__IPU_DIAGB_1 0x264 0x6c8 0x000 0x6 0x0
+#define MX35_PAD_ATA_CS1__ARM11P_TOP_MAX1_HMASTER_1 0x264 0x6c8 0x000 0x7 0x0
+#define MX35_PAD_ATA_DIOR__ATA_DIOR 0x268 0x6cc 0x000 0x0 0x0
+#define MX35_PAD_ATA_DIOR__ESDHC3_DAT0 0x268 0x6cc 0x81c 0x1 0x1
+#define MX35_PAD_ATA_DIOR__USB_TOP_USBOTG_DIR 0x268 0x6cc 0x9c4 0x2 0x1
+#define MX35_PAD_ATA_DIOR__IPU_DISPB_BE0 0x268 0x6cc 0x000 0x3 0x0
+#define MX35_PAD_ATA_DIOR__CSPI2_SS1 0x268 0x6cc 0x7f4 0x4 0x1
+#define MX35_PAD_ATA_DIOR__GPIO2_8 0x268 0x6cc 0x8e0 0x5 0x1
+#define MX35_PAD_ATA_DIOR__IPU_DIAGB_2 0x268 0x6cc 0x000 0x6 0x0
+#define MX35_PAD_ATA_DIOR__ARM11P_TOP_MAX1_HMASTER_2 0x268 0x6cc 0x000 0x7 0x0
+#define MX35_PAD_ATA_DIOW__ATA_DIOW 0x26c 0x6d0 0x000 0x0 0x0
+#define MX35_PAD_ATA_DIOW__ESDHC3_DAT1 0x26c 0x6d0 0x820 0x1 0x1
+#define MX35_PAD_ATA_DIOW__USB_TOP_USBOTG_STP 0x26c 0x6d0 0x000 0x2 0x0
+#define MX35_PAD_ATA_DIOW__IPU_DISPB_BE1 0x26c 0x6d0 0x000 0x3 0x0
+#define MX35_PAD_ATA_DIOW__CSPI2_MOSI 0x26c 0x6d0 0x7ec 0x4 0x2
+#define MX35_PAD_ATA_DIOW__GPIO2_9 0x26c 0x6d0 0x8e4 0x5 0x1
+#define MX35_PAD_ATA_DIOW__IPU_DIAGB_3 0x26c 0x6d0 0x000 0x6 0x0
+#define MX35_PAD_ATA_DIOW__ARM11P_TOP_MAX1_HMASTER_3 0x26c 0x6d0 0x000 0x7 0x0
+#define MX35_PAD_ATA_DMACK__ATA_DMACK 0x270 0x6d4 0x000 0x0 0x0
+#define MX35_PAD_ATA_DMACK__ESDHC3_DAT2 0x270 0x6d4 0x824 0x1 0x1
+#define MX35_PAD_ATA_DMACK__USB_TOP_USBOTG_NXT 0x270 0x6d4 0x9c8 0x2 0x1
+#define MX35_PAD_ATA_DMACK__CSPI2_MISO 0x270 0x6d4 0x7e8 0x4 0x2
+#define MX35_PAD_ATA_DMACK__GPIO2_10 0x270 0x6d4 0x86c 0x5 0x1
+#define MX35_PAD_ATA_DMACK__IPU_DIAGB_4 0x270 0x6d4 0x000 0x6 0x0
+#define MX35_PAD_ATA_DMACK__ARM11P_TOP_MAX0_HMASTER_0 0x270 0x6d4 0x000 0x7 0x0
+#define MX35_PAD_ATA_RESET_B__ATA_RESET_B 0x274 0x6d8 0x000 0x0 0x0
+#define MX35_PAD_ATA_RESET_B__ESDHC3_DAT3 0x274 0x6d8 0x828 0x1 0x1
+#define MX35_PAD_ATA_RESET_B__USB_TOP_USBOTG_DATA_0 0x274 0x6d8 0x9a4 0x2 0x1
+#define MX35_PAD_ATA_RESET_B__IPU_DISPB_SD_D_O 0x274 0x6d8 0x000 0x3 0x0
+#define MX35_PAD_ATA_RESET_B__CSPI2_RDY 0x274 0x6d8 0x7e4 0x4 0x2
+#define MX35_PAD_ATA_RESET_B__GPIO2_11 0x274 0x6d8 0x870 0x5 0x1
+#define MX35_PAD_ATA_RESET_B__IPU_DIAGB_5 0x274 0x6d8 0x000 0x6 0x0
+#define MX35_PAD_ATA_RESET_B__ARM11P_TOP_MAX0_HMASTER_1 0x274 0x6d8 0x000 0x7 0x0
+#define MX35_PAD_ATA_IORDY__ATA_IORDY 0x278 0x6dc 0x000 0x0 0x0
+#define MX35_PAD_ATA_IORDY__ESDHC3_DAT4 0x278 0x6dc 0x000 0x1 0x0
+#define MX35_PAD_ATA_IORDY__USB_TOP_USBOTG_DATA_1 0x278 0x6dc 0x9a8 0x2 0x1
+#define MX35_PAD_ATA_IORDY__IPU_DISPB_SD_D_IO 0x278 0x6dc 0x92c 0x3 0x3
+#define MX35_PAD_ATA_IORDY__ESDHC2_DAT4 0x278 0x6dc 0x000 0x4 0x0
+#define MX35_PAD_ATA_IORDY__GPIO2_12 0x278 0x6dc 0x874 0x5 0x1
+#define MX35_PAD_ATA_IORDY__IPU_DIAGB_6 0x278 0x6dc 0x000 0x6 0x0
+#define MX35_PAD_ATA_IORDY__ARM11P_TOP_MAX0_HMASTER_2 0x278 0x6dc 0x000 0x7 0x0
+#define MX35_PAD_ATA_DATA0__ATA_DATA_0 0x27c 0x6e0 0x000 0x0 0x0
+#define MX35_PAD_ATA_DATA0__ESDHC3_DAT5 0x27c 0x6e0 0x000 0x1 0x0
+#define MX35_PAD_ATA_DATA0__USB_TOP_USBOTG_DATA_2 0x27c 0x6e0 0x9ac 0x2 0x1
+#define MX35_PAD_ATA_DATA0__IPU_DISPB_D12_VSYNC 0x27c 0x6e0 0x928 0x3 0x4
+#define MX35_PAD_ATA_DATA0__ESDHC2_DAT5 0x27c 0x6e0 0x000 0x4 0x0
+#define MX35_PAD_ATA_DATA0__GPIO2_13 0x27c 0x6e0 0x878 0x5 0x1
+#define MX35_PAD_ATA_DATA0__IPU_DIAGB_7 0x27c 0x6e0 0x000 0x6 0x0
+#define MX35_PAD_ATA_DATA0__ARM11P_TOP_MAX0_HMASTER_3 0x27c 0x6e0 0x000 0x7 0x0
+#define MX35_PAD_ATA_DATA1__ATA_DATA_1 0x280 0x6e4 0x000 0x0 0x0
+#define MX35_PAD_ATA_DATA1__ESDHC3_DAT6 0x280 0x6e4 0x000 0x1 0x0
+#define MX35_PAD_ATA_DATA1__USB_TOP_USBOTG_DATA_3 0x280 0x6e4 0x9b0 0x2 0x1
+#define MX35_PAD_ATA_DATA1__IPU_DISPB_SD_CLK 0x280 0x6e4 0x000 0x3 0x0
+#define MX35_PAD_ATA_DATA1__ESDHC2_DAT6 0x280 0x6e4 0x000 0x4 0x0
+#define MX35_PAD_ATA_DATA1__GPIO2_14 0x280 0x6e4 0x87c 0x5 0x1
+#define MX35_PAD_ATA_DATA1__IPU_DIAGB_8 0x280 0x6e4 0x000 0x6 0x0
+#define MX35_PAD_ATA_DATA1__ARM11P_TOP_TRACE_27 0x280 0x6e4 0x000 0x7 0x0
+#define MX35_PAD_ATA_DATA2__ATA_DATA_2 0x284 0x6e8 0x000 0x0 0x0
+#define MX35_PAD_ATA_DATA2__ESDHC3_DAT7 0x284 0x6e8 0x000 0x1 0x0
+#define MX35_PAD_ATA_DATA2__USB_TOP_USBOTG_DATA_4 0x284 0x6e8 0x9b4 0x2 0x1
+#define MX35_PAD_ATA_DATA2__IPU_DISPB_SER_RS 0x284 0x6e8 0x000 0x3 0x0
+#define MX35_PAD_ATA_DATA2__ESDHC2_DAT7 0x284 0x6e8 0x000 0x4 0x0
+#define MX35_PAD_ATA_DATA2__GPIO2_15 0x284 0x6e8 0x880 0x5 0x1
+#define MX35_PAD_ATA_DATA2__IPU_DIAGB_9 0x284 0x6e8 0x000 0x6 0x0
+#define MX35_PAD_ATA_DATA2__ARM11P_TOP_TRACE_28 0x284 0x6e8 0x000 0x7 0x0
+#define MX35_PAD_ATA_DATA3__ATA_DATA_3 0x288 0x6ec 0x000 0x0 0x0
+#define MX35_PAD_ATA_DATA3__ESDHC3_CLK 0x288 0x6ec 0x814 0x1 0x1
+#define MX35_PAD_ATA_DATA3__USB_TOP_USBOTG_DATA_5 0x288 0x6ec 0x9b8 0x2 0x1
+#define MX35_PAD_ATA_DATA3__CSPI2_SCLK 0x288 0x6ec 0x7e0 0x4 0x2
+#define MX35_PAD_ATA_DATA3__GPIO2_16 0x288 0x6ec 0x884 0x5 0x1
+#define MX35_PAD_ATA_DATA3__IPU_DIAGB_10 0x288 0x6ec 0x000 0x6 0x0
+#define MX35_PAD_ATA_DATA3__ARM11P_TOP_TRACE_29 0x288 0x6ec 0x000 0x7 0x0
+#define MX35_PAD_ATA_DATA4__ATA_DATA_4 0x28c 0x6f0 0x000 0x0 0x0
+#define MX35_PAD_ATA_DATA4__ESDHC3_CMD 0x28c 0x6f0 0x818 0x1 0x1
+#define MX35_PAD_ATA_DATA4__USB_TOP_USBOTG_DATA_6 0x28c 0x6f0 0x9bc 0x2 0x1
+#define MX35_PAD_ATA_DATA4__GPIO2_17 0x28c 0x6f0 0x888 0x5 0x1
+#define MX35_PAD_ATA_DATA4__IPU_DIAGB_11 0x28c 0x6f0 0x000 0x6 0x0
+#define MX35_PAD_ATA_DATA4__ARM11P_TOP_TRACE_30 0x28c 0x6f0 0x000 0x7 0x0
+#define MX35_PAD_ATA_DATA5__ATA_DATA_5 0x290 0x6f4 0x000 0x0 0x0
+#define MX35_PAD_ATA_DATA5__USB_TOP_USBOTG_DATA_7 0x290 0x6f4 0x9c0 0x2 0x1
+#define MX35_PAD_ATA_DATA5__GPIO2_18 0x290 0x6f4 0x88c 0x5 0x1
+#define MX35_PAD_ATA_DATA5__IPU_DIAGB_12 0x290 0x6f4 0x000 0x6 0x0
+#define MX35_PAD_ATA_DATA5__ARM11P_TOP_TRACE_31 0x290 0x6f4 0x000 0x7 0x0
+#define MX35_PAD_ATA_DATA6__ATA_DATA_6 0x294 0x6f8 0x000 0x0 0x0
+#define MX35_PAD_ATA_DATA6__CAN1_TXCAN 0x294 0x6f8 0x000 0x1 0x0
+#define MX35_PAD_ATA_DATA6__UART1_DTR 0x294 0x6f8 0x000 0x2 0x0
+#define MX35_PAD_ATA_DATA6__AUDMUX_AUD6_TXD 0x294 0x6f8 0x7b4 0x3 0x0
+#define MX35_PAD_ATA_DATA6__GPIO2_19 0x294 0x6f8 0x890 0x5 0x1
+#define MX35_PAD_ATA_DATA6__IPU_DIAGB_13 0x294 0x6f8 0x000 0x6 0x0
+#define MX35_PAD_ATA_DATA7__ATA_DATA_7 0x298 0x6fc 0x000 0x0 0x0
+#define MX35_PAD_ATA_DATA7__CAN1_RXCAN 0x298 0x6fc 0x7c8 0x1 0x2
+#define MX35_PAD_ATA_DATA7__UART1_DSR 0x298 0x6fc 0x000 0x2 0x0
+#define MX35_PAD_ATA_DATA7__AUDMUX_AUD6_RXD 0x298 0x6fc 0x7b0 0x3 0x0
+#define MX35_PAD_ATA_DATA7__GPIO2_20 0x298 0x6fc 0x898 0x5 0x1
+#define MX35_PAD_ATA_DATA7__IPU_DIAGB_14 0x298 0x6fc 0x000 0x6 0x0
+#define MX35_PAD_ATA_DATA8__ATA_DATA_8 0x29c 0x700 0x000 0x0 0x0
+#define MX35_PAD_ATA_DATA8__UART3_RTS 0x29c 0x700 0x99c 0x1 0x1
+#define MX35_PAD_ATA_DATA8__UART1_RI 0x29c 0x700 0x000 0x2 0x0
+#define MX35_PAD_ATA_DATA8__AUDMUX_AUD6_TXC 0x29c 0x700 0x7c0 0x3 0x0
+#define MX35_PAD_ATA_DATA8__GPIO2_21 0x29c 0x700 0x89c 0x5 0x1
+#define MX35_PAD_ATA_DATA8__IPU_DIAGB_15 0x29c 0x700 0x000 0x6 0x0
+#define MX35_PAD_ATA_DATA9__ATA_DATA_9 0x2a0 0x704 0x000 0x0 0x0
+#define MX35_PAD_ATA_DATA9__UART3_CTS 0x2a0 0x704 0x000 0x1 0x0
+#define MX35_PAD_ATA_DATA9__UART1_DCD 0x2a0 0x704 0x000 0x2 0x0
+#define MX35_PAD_ATA_DATA9__AUDMUX_AUD6_TXFS 0x2a0 0x704 0x7c4 0x3 0x0
+#define MX35_PAD_ATA_DATA9__GPIO2_22 0x2a0 0x704 0x8a0 0x5 0x1
+#define MX35_PAD_ATA_DATA9__IPU_DIAGB_16 0x2a0 0x704 0x000 0x6 0x0
+#define MX35_PAD_ATA_DATA10__ATA_DATA_10 0x2a4 0x708 0x000 0x0 0x0
+#define MX35_PAD_ATA_DATA10__UART3_RXD_MUX 0x2a4 0x708 0x9a0 0x1 0x2
+#define MX35_PAD_ATA_DATA10__AUDMUX_AUD6_RXC 0x2a4 0x708 0x7b8 0x3 0x0
+#define MX35_PAD_ATA_DATA10__GPIO2_23 0x2a4 0x708 0x8a4 0x5 0x1
+#define MX35_PAD_ATA_DATA10__IPU_DIAGB_17 0x2a4 0x708 0x000 0x6 0x0
+#define MX35_PAD_ATA_DATA11__ATA_DATA_11 0x2a8 0x70c 0x000 0x0 0x0
+#define MX35_PAD_ATA_DATA11__UART3_TXD_MUX 0x2a8 0x70c 0x000 0x1 0x0
+#define MX35_PAD_ATA_DATA11__AUDMUX_AUD6_RXFS 0x2a8 0x70c 0x7bc 0x3 0x0
+#define MX35_PAD_ATA_DATA11__GPIO2_24 0x2a8 0x70c 0x8a8 0x5 0x1
+#define MX35_PAD_ATA_DATA11__IPU_DIAGB_18 0x2a8 0x70c 0x000 0x6 0x0
+#define MX35_PAD_ATA_DATA12__ATA_DATA_12 0x2ac 0x710 0x000 0x0 0x0
+#define MX35_PAD_ATA_DATA12__I2C3_SCL 0x2ac 0x710 0x91c 0x1 0x3
+#define MX35_PAD_ATA_DATA12__GPIO2_25 0x2ac 0x710 0x8ac 0x5 0x1
+#define MX35_PAD_ATA_DATA12__IPU_DIAGB_19 0x2ac 0x710 0x000 0x6 0x0
+#define MX35_PAD_ATA_DATA13__ATA_DATA_13 0x2b0 0x714 0x000 0x0 0x0
+#define MX35_PAD_ATA_DATA13__I2C3_SDA 0x2b0 0x714 0x920 0x1 0x3
+#define MX35_PAD_ATA_DATA13__GPIO2_26 0x2b0 0x714 0x8b0 0x5 0x1
+#define MX35_PAD_ATA_DATA13__IPU_DIAGB_20 0x2b0 0x714 0x000 0x6 0x0
+#define MX35_PAD_ATA_DATA14__ATA_DATA_14 0x2b4 0x718 0x000 0x0 0x0
+#define MX35_PAD_ATA_DATA14__IPU_CSI_D_0 0x2b4 0x718 0x930 0x1 0x2
+#define MX35_PAD_ATA_DATA14__KPP_ROW_0 0x2b4 0x718 0x970 0x3 0x2
+#define MX35_PAD_ATA_DATA14__GPIO2_27 0x2b4 0x718 0x8b4 0x5 0x1
+#define MX35_PAD_ATA_DATA14__IPU_DIAGB_21 0x2b4 0x718 0x000 0x6 0x0
+#define MX35_PAD_ATA_DATA15__ATA_DATA_15 0x2b8 0x71c 0x000 0x0 0x0
+#define MX35_PAD_ATA_DATA15__IPU_CSI_D_1 0x2b8 0x71c 0x934 0x1 0x2
+#define MX35_PAD_ATA_DATA15__KPP_ROW_1 0x2b8 0x71c 0x974 0x3 0x2
+#define MX35_PAD_ATA_DATA15__GPIO2_28 0x2b8 0x71c 0x8b8 0x5 0x1
+#define MX35_PAD_ATA_DATA15__IPU_DIAGB_22 0x2b8 0x71c 0x000 0x6 0x0
+#define MX35_PAD_ATA_INTRQ__ATA_INTRQ 0x2bc 0x720 0x000 0x0 0x0
+#define MX35_PAD_ATA_INTRQ__IPU_CSI_D_2 0x2bc 0x720 0x938 0x1 0x3
+#define MX35_PAD_ATA_INTRQ__KPP_ROW_2 0x2bc 0x720 0x978 0x3 0x2
+#define MX35_PAD_ATA_INTRQ__GPIO2_29 0x2bc 0x720 0x8bc 0x5 0x1
+#define MX35_PAD_ATA_INTRQ__IPU_DIAGB_23 0x2bc 0x720 0x000 0x6 0x0
+#define MX35_PAD_ATA_BUFF_EN__ATA_BUFFER_EN 0x2c0 0x724 0x000 0x0 0x0
+#define MX35_PAD_ATA_BUFF_EN__IPU_CSI_D_3 0x2c0 0x724 0x93c 0x1 0x3
+#define MX35_PAD_ATA_BUFF_EN__KPP_ROW_3 0x2c0 0x724 0x97c 0x3 0x2
+#define MX35_PAD_ATA_BUFF_EN__GPIO2_30 0x2c0 0x724 0x8c4 0x5 0x1
+#define MX35_PAD_ATA_BUFF_EN__IPU_DIAGB_24 0x2c0 0x724 0x000 0x6 0x0
+#define MX35_PAD_ATA_DMARQ__ATA_DMARQ 0x2c4 0x728 0x000 0x0 0x0
+#define MX35_PAD_ATA_DMARQ__IPU_CSI_D_4 0x2c4 0x728 0x940 0x1 0x2
+#define MX35_PAD_ATA_DMARQ__KPP_COL_0 0x2c4 0x728 0x950 0x3 0x2
+#define MX35_PAD_ATA_DMARQ__GPIO2_31 0x2c4 0x728 0x8c8 0x5 0x1
+#define MX35_PAD_ATA_DMARQ__IPU_DIAGB_25 0x2c4 0x728 0x000 0x6 0x0
+#define MX35_PAD_ATA_DMARQ__ECT_CTI_TRIG_IN1_4 0x2c4 0x728 0x000 0x7 0x0
+#define MX35_PAD_ATA_DA0__ATA_DA_0 0x2c8 0x72c 0x000 0x0 0x0
+#define MX35_PAD_ATA_DA0__IPU_CSI_D_5 0x2c8 0x72c 0x944 0x1 0x2
+#define MX35_PAD_ATA_DA0__KPP_COL_1 0x2c8 0x72c 0x954 0x3 0x2
+#define MX35_PAD_ATA_DA0__GPIO3_0 0x2c8 0x72c 0x8e8 0x5 0x1
+#define MX35_PAD_ATA_DA0__IPU_DIAGB_26 0x2c8 0x72c 0x000 0x6 0x0
+#define MX35_PAD_ATA_DA0__ECT_CTI_TRIG_IN1_5 0x2c8 0x72c 0x000 0x7 0x0
+#define MX35_PAD_ATA_DA1__ATA_DA_1 0x2cc 0x730 0x000 0x0 0x0
+#define MX35_PAD_ATA_DA1__IPU_CSI_D_6 0x2cc 0x730 0x948 0x1 0x2
+#define MX35_PAD_ATA_DA1__KPP_COL_2 0x2cc 0x730 0x958 0x3 0x2
+#define MX35_PAD_ATA_DA1__GPIO3_1 0x2cc 0x730 0x000 0x5 0x0
+#define MX35_PAD_ATA_DA1__IPU_DIAGB_27 0x2cc 0x730 0x000 0x6 0x0
+#define MX35_PAD_ATA_DA1__ECT_CTI_TRIG_IN1_6 0x2cc 0x730 0x000 0x7 0x0
+#define MX35_PAD_ATA_DA2__ATA_DA_2 0x2d0 0x734 0x000 0x0 0x0
+#define MX35_PAD_ATA_DA2__IPU_CSI_D_7 0x2d0 0x734 0x94c 0x1 0x2
+#define MX35_PAD_ATA_DA2__KPP_COL_3 0x2d0 0x734 0x95c 0x3 0x2
+#define MX35_PAD_ATA_DA2__GPIO3_2 0x2d0 0x734 0x000 0x5 0x0
+#define MX35_PAD_ATA_DA2__IPU_DIAGB_28 0x2d0 0x734 0x000 0x6 0x0
+#define MX35_PAD_ATA_DA2__ECT_CTI_TRIG_IN1_7 0x2d0 0x734 0x000 0x7 0x0
+#define MX35_PAD_MLB_CLK__MLB_MLBCLK 0x2d4 0x738 0x000 0x0 0x0
+#define MX35_PAD_MLB_CLK__GPIO3_3 0x2d4 0x738 0x000 0x5 0x0
+#define MX35_PAD_MLB_DAT__MLB_MLBDAT 0x2d8 0x73c 0x000 0x0 0x0
+#define MX35_PAD_MLB_DAT__GPIO3_4 0x2d8 0x73c 0x904 0x5 0x1
+#define MX35_PAD_MLB_SIG__MLB_MLBSIG 0x2dc 0x740 0x000 0x0 0x0
+#define MX35_PAD_MLB_SIG__GPIO3_5 0x2dc 0x740 0x908 0x5 0x1
+#define MX35_PAD_FEC_TX_CLK__FEC_TX_CLK 0x2e0 0x744 0x000 0x0 0x0
+#define MX35_PAD_FEC_TX_CLK__ESDHC1_DAT4 0x2e0 0x744 0x804 0x1 0x1
+#define MX35_PAD_FEC_TX_CLK__UART3_RXD_MUX 0x2e0 0x744 0x9a0 0x2 0x3
+#define MX35_PAD_FEC_TX_CLK__USB_TOP_USBH2_DIR 0x2e0 0x744 0x9ec 0x3 0x1
+#define MX35_PAD_FEC_TX_CLK__CSPI2_MOSI 0x2e0 0x744 0x7ec 0x4 0x3
+#define MX35_PAD_FEC_TX_CLK__GPIO3_6 0x2e0 0x744 0x90c 0x5 0x1
+#define MX35_PAD_FEC_TX_CLK__IPU_DISPB_D12_VSYNC 0x2e0 0x744 0x928 0x6 0x5
+#define MX35_PAD_FEC_TX_CLK__ARM11P_TOP_EVNTBUS_0 0x2e0 0x744 0x000 0x7 0x0
+#define MX35_PAD_FEC_RX_CLK__FEC_RX_CLK 0x2e4 0x748 0x000 0x0 0x0
+#define MX35_PAD_FEC_RX_CLK__ESDHC1_DAT5 0x2e4 0x748 0x808 0x1 0x1
+#define MX35_PAD_FEC_RX_CLK__UART3_TXD_MUX 0x2e4 0x748 0x000 0x2 0x0
+#define MX35_PAD_FEC_RX_CLK__USB_TOP_USBH2_STP 0x2e4 0x748 0x000 0x3 0x0
+#define MX35_PAD_FEC_RX_CLK__CSPI2_MISO 0x2e4 0x748 0x7e8 0x4 0x3
+#define MX35_PAD_FEC_RX_CLK__GPIO3_7 0x2e4 0x748 0x910 0x5 0x1
+#define MX35_PAD_FEC_RX_CLK__IPU_DISPB_SD_D_I 0x2e4 0x748 0x92c 0x6 0x4
+#define MX35_PAD_FEC_RX_CLK__ARM11P_TOP_EVNTBUS_1 0x2e4 0x748 0x000 0x7 0x0
+#define MX35_PAD_FEC_RX_DV__FEC_RX_DV 0x2e8 0x74c 0x000 0x0 0x0
+#define MX35_PAD_FEC_RX_DV__ESDHC1_DAT6 0x2e8 0x74c 0x80c 0x1 0x1
+#define MX35_PAD_FEC_RX_DV__UART3_RTS 0x2e8 0x74c 0x99c 0x2 0x2
+#define MX35_PAD_FEC_RX_DV__USB_TOP_USBH2_NXT 0x2e8 0x74c 0x9f0 0x3 0x1
+#define MX35_PAD_FEC_RX_DV__CSPI2_SCLK 0x2e8 0x74c 0x7e0 0x4 0x3
+#define MX35_PAD_FEC_RX_DV__GPIO3_8 0x2e8 0x74c 0x914 0x5 0x1
+#define MX35_PAD_FEC_RX_DV__IPU_DISPB_SD_CLK 0x2e8 0x74c 0x000 0x6 0x0
+#define MX35_PAD_FEC_RX_DV__ARM11P_TOP_EVNTBUS_2 0x2e8 0x74c 0x000 0x7 0x0
+#define MX35_PAD_FEC_COL__FEC_COL 0x2ec 0x750 0x000 0x0 0x0
+#define MX35_PAD_FEC_COL__ESDHC1_DAT7 0x2ec 0x750 0x810 0x1 0x1
+#define MX35_PAD_FEC_COL__UART3_CTS 0x2ec 0x750 0x000 0x2 0x0
+#define MX35_PAD_FEC_COL__USB_TOP_USBH2_DATA_0 0x2ec 0x750 0x9cc 0x3 0x1
+#define MX35_PAD_FEC_COL__CSPI2_RDY 0x2ec 0x750 0x7e4 0x4 0x3
+#define MX35_PAD_FEC_COL__GPIO3_9 0x2ec 0x750 0x918 0x5 0x1
+#define MX35_PAD_FEC_COL__IPU_DISPB_SER_RS 0x2ec 0x750 0x000 0x6 0x0
+#define MX35_PAD_FEC_COL__ARM11P_TOP_EVNTBUS_3 0x2ec 0x750 0x000 0x7 0x0
+#define MX35_PAD_FEC_RDATA0__FEC_RDATA_0 0x2f0 0x754 0x000 0x0 0x0
+#define MX35_PAD_FEC_RDATA0__PWM_PWMO 0x2f0 0x754 0x000 0x1 0x0
+#define MX35_PAD_FEC_RDATA0__UART3_DTR 0x2f0 0x754 0x000 0x2 0x0
+#define MX35_PAD_FEC_RDATA0__USB_TOP_USBH2_DATA_1 0x2f0 0x754 0x9d0 0x3 0x1
+#define MX35_PAD_FEC_RDATA0__CSPI2_SS0 0x2f0 0x754 0x7f0 0x4 0x2
+#define MX35_PAD_FEC_RDATA0__GPIO3_10 0x2f0 0x754 0x8ec 0x5 0x1
+#define MX35_PAD_FEC_RDATA0__IPU_DISPB_CS1 0x2f0 0x754 0x000 0x6 0x0
+#define MX35_PAD_FEC_RDATA0__ARM11P_TOP_EVNTBUS_4 0x2f0 0x754 0x000 0x7 0x0
+#define MX35_PAD_FEC_TDATA0__FEC_TDATA_0 0x2f4 0x758 0x000 0x0 0x0
+#define MX35_PAD_FEC_TDATA0__SPDIF_SPDIF_OUT1 0x2f4 0x758 0x000 0x1 0x0
+#define MX35_PAD_FEC_TDATA0__UART3_DSR 0x2f4 0x758 0x000 0x2 0x0
+#define MX35_PAD_FEC_TDATA0__USB_TOP_USBH2_DATA_2 0x2f4 0x758 0x9d4 0x3 0x1
+#define MX35_PAD_FEC_TDATA0__CSPI2_SS1 0x2f4 0x758 0x7f4 0x4 0x2
+#define MX35_PAD_FEC_TDATA0__GPIO3_11 0x2f4 0x758 0x8f0 0x5 0x1
+#define MX35_PAD_FEC_TDATA0__IPU_DISPB_CS0 0x2f4 0x758 0x000 0x6 0x0
+#define MX35_PAD_FEC_TDATA0__ARM11P_TOP_EVNTBUS_5 0x2f4 0x758 0x000 0x7 0x0
+#define MX35_PAD_FEC_TX_EN__FEC_TX_EN 0x2f8 0x75c 0x000 0x0 0x0
+#define MX35_PAD_FEC_TX_EN__SPDIF_SPDIF_IN1 0x2f8 0x75c 0x998 0x1 0x3
+#define MX35_PAD_FEC_TX_EN__UART3_RI 0x2f8 0x75c 0x000 0x2 0x0
+#define MX35_PAD_FEC_TX_EN__USB_TOP_USBH2_DATA_3 0x2f8 0x75c 0x9d8 0x3 0x1
+#define MX35_PAD_FEC_TX_EN__GPIO3_12 0x2f8 0x75c 0x8f4 0x5 0x1
+#define MX35_PAD_FEC_TX_EN__IPU_DISPB_PAR_RS 0x2f8 0x75c 0x000 0x6 0x0
+#define MX35_PAD_FEC_TX_EN__ARM11P_TOP_EVNTBUS_6 0x2f8 0x75c 0x000 0x7 0x0
+#define MX35_PAD_FEC_MDC__FEC_MDC 0x2fc 0x760 0x000 0x0 0x0
+#define MX35_PAD_FEC_MDC__CAN2_TXCAN 0x2fc 0x760 0x000 0x1 0x0
+#define MX35_PAD_FEC_MDC__UART3_DCD 0x2fc 0x760 0x000 0x2 0x0
+#define MX35_PAD_FEC_MDC__USB_TOP_USBH2_DATA_4 0x2fc 0x760 0x9dc 0x3 0x1
+#define MX35_PAD_FEC_MDC__GPIO3_13 0x2fc 0x760 0x8f8 0x5 0x1
+#define MX35_PAD_FEC_MDC__IPU_DISPB_WR 0x2fc 0x760 0x000 0x6 0x0
+#define MX35_PAD_FEC_MDC__ARM11P_TOP_EVNTBUS_7 0x2fc 0x760 0x000 0x7 0x0
+#define MX35_PAD_FEC_MDIO__FEC_MDIO 0x300 0x764 0x000 0x0 0x0
+#define MX35_PAD_FEC_MDIO__CAN2_RXCAN 0x300 0x764 0x7cc 0x1 0x2
+#define MX35_PAD_FEC_MDIO__USB_TOP_USBH2_DATA_5 0x300 0x764 0x9e0 0x3 0x1
+#define MX35_PAD_FEC_MDIO__GPIO3_14 0x300 0x764 0x8fc 0x5 0x1
+#define MX35_PAD_FEC_MDIO__IPU_DISPB_RD 0x300 0x764 0x000 0x6 0x0
+#define MX35_PAD_FEC_MDIO__ARM11P_TOP_EVNTBUS_8 0x300 0x764 0x000 0x7 0x0
+#define MX35_PAD_FEC_TX_ERR__FEC_TX_ERR 0x304 0x768 0x000 0x0 0x0
+#define MX35_PAD_FEC_TX_ERR__OWIRE_LINE 0x304 0x768 0x990 0x1 0x2
+#define MX35_PAD_FEC_TX_ERR__SPDIF_SPDIF_EXTCLK 0x304 0x768 0x994 0x2 0x4
+#define MX35_PAD_FEC_TX_ERR__USB_TOP_USBH2_DATA_6 0x304 0x768 0x9e4 0x3 0x1
+#define MX35_PAD_FEC_TX_ERR__GPIO3_15 0x304 0x768 0x900 0x5 0x1
+#define MX35_PAD_FEC_TX_ERR__IPU_DISPB_D0_VSYNC 0x304 0x768 0x924 0x6 0x3
+#define MX35_PAD_FEC_TX_ERR__ARM11P_TOP_EVNTBUS_9 0x304 0x768 0x000 0x7 0x0
+#define MX35_PAD_FEC_RX_ERR__FEC_RX_ERR 0x308 0x76c 0x000 0x0 0x0
+#define MX35_PAD_FEC_RX_ERR__IPU_CSI_D_0 0x308 0x76c 0x930 0x1 0x3
+#define MX35_PAD_FEC_RX_ERR__USB_TOP_USBH2_DATA_7 0x308 0x76c 0x9e8 0x3 0x1
+#define MX35_PAD_FEC_RX_ERR__KPP_COL_4 0x308 0x76c 0x960 0x4 0x1
+#define MX35_PAD_FEC_RX_ERR__GPIO3_16 0x308 0x76c 0x000 0x5 0x0
+#define MX35_PAD_FEC_RX_ERR__IPU_DISPB_SD_D_IO 0x308 0x76c 0x92c 0x6 0x5
+#define MX35_PAD_FEC_CRS__FEC_CRS 0x30c 0x770 0x000 0x0 0x0
+#define MX35_PAD_FEC_CRS__IPU_CSI_D_1 0x30c 0x770 0x934 0x1 0x3
+#define MX35_PAD_FEC_CRS__USB_TOP_USBH2_PWR 0x30c 0x770 0x000 0x3 0x0
+#define MX35_PAD_FEC_CRS__KPP_COL_5 0x30c 0x770 0x964 0x4 0x1
+#define MX35_PAD_FEC_CRS__GPIO3_17 0x30c 0x770 0x000 0x5 0x0
+#define MX35_PAD_FEC_CRS__IPU_FLASH_STROBE 0x30c 0x770 0x000 0x6 0x0
+#define MX35_PAD_FEC_RDATA1__FEC_RDATA_1 0x310 0x774 0x000 0x0 0x0
+#define MX35_PAD_FEC_RDATA1__IPU_CSI_D_2 0x310 0x774 0x938 0x1 0x4
+#define MX35_PAD_FEC_RDATA1__AUDMUX_AUD6_RXC 0x310 0x774 0x000 0x2 0x0
+#define MX35_PAD_FEC_RDATA1__USB_TOP_USBH2_OC 0x310 0x774 0x9f4 0x3 0x2
+#define MX35_PAD_FEC_RDATA1__KPP_COL_6 0x310 0x774 0x968 0x4 0x1
+#define MX35_PAD_FEC_RDATA1__GPIO3_18 0x310 0x774 0x000 0x5 0x0
+#define MX35_PAD_FEC_RDATA1__IPU_DISPB_BE0 0x310 0x774 0x000 0x6 0x0
+#define MX35_PAD_FEC_TDATA1__FEC_TDATA_1 0x314 0x778 0x000 0x0 0x0
+#define MX35_PAD_FEC_TDATA1__IPU_CSI_D_3 0x314 0x778 0x93c 0x1 0x4
+#define MX35_PAD_FEC_TDATA1__AUDMUX_AUD6_RXFS 0x314 0x778 0x7bc 0x2 0x1
+#define MX35_PAD_FEC_TDATA1__KPP_COL_7 0x314 0x778 0x96c 0x4 0x1
+#define MX35_PAD_FEC_TDATA1__GPIO3_19 0x314 0x778 0x000 0x5 0x0
+#define MX35_PAD_FEC_TDATA1__IPU_DISPB_BE1 0x314 0x778 0x000 0x6 0x0
+#define MX35_PAD_FEC_RDATA2__FEC_RDATA_2 0x318 0x77c 0x000 0x0 0x0
+#define MX35_PAD_FEC_RDATA2__IPU_CSI_D_4 0x318 0x77c 0x940 0x1 0x3
+#define MX35_PAD_FEC_RDATA2__AUDMUX_AUD6_TXD 0x318 0x77c 0x7b4 0x2 0x1
+#define MX35_PAD_FEC_RDATA2__KPP_ROW_4 0x318 0x77c 0x980 0x4 0x1
+#define MX35_PAD_FEC_RDATA2__GPIO3_20 0x318 0x77c 0x000 0x5 0x0
+#define MX35_PAD_FEC_TDATA2__FEC_TDATA_2 0x31c 0x780 0x000 0x0 0x0
+#define MX35_PAD_FEC_TDATA2__IPU_CSI_D_5 0x31c 0x780 0x944 0x1 0x3
+#define MX35_PAD_FEC_TDATA2__AUDMUX_AUD6_RXD 0x31c 0x780 0x7b0 0x2 0x1
+#define MX35_PAD_FEC_TDATA2__KPP_ROW_5 0x31c 0x780 0x984 0x4 0x1
+#define MX35_PAD_FEC_TDATA2__GPIO3_21 0x31c 0x780 0x000 0x5 0x0
+#define MX35_PAD_FEC_RDATA3__FEC_RDATA_3 0x320 0x784 0x000 0x0 0x0
+#define MX35_PAD_FEC_RDATA3__IPU_CSI_D_6 0x320 0x784 0x948 0x1 0x3
+#define MX35_PAD_FEC_RDATA3__AUDMUX_AUD6_TXC 0x320 0x784 0x7c0 0x2 0x1
+#define MX35_PAD_FEC_RDATA3__KPP_ROW_6 0x320 0x784 0x988 0x4 0x1
+#define MX35_PAD_FEC_RDATA3__GPIO3_22 0x320 0x784 0x000 0x6 0x0
+#define MX35_PAD_FEC_TDATA3__FEC_TDATA_3 0x324 0x788 0x000 0x0 0x0
+#define MX35_PAD_FEC_TDATA3__IPU_CSI_D_7 0x324 0x788 0x94c 0x1 0x3
+#define MX35_PAD_FEC_TDATA3__AUDMUX_AUD6_TXFS 0x324 0x788 0x7c4 0x2 0x1
+#define MX35_PAD_FEC_TDATA3__KPP_ROW_7 0x324 0x788 0x98c 0x4 0x1
+#define MX35_PAD_FEC_TDATA3__GPIO3_23 0x324 0x788 0x000 0x5 0x0
+#define MX35_PAD_EXT_ARMCLK__CCM_EXT_ARMCLK 0x000 0x78c 0x000 0x0 0x0
+#define MX35_PAD_TEST_MODE__TCU_TEST_MODE 0x000 0x790 0x000 0x0 0x0
+
+#endif /* __DTS_IMX35_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx35.dtsi b/arch/arm/boot/dts/imx35.dtsi
new file mode 100644
index 000000000..466bcb704
--- /dev/null
+++ b/arch/arm/boot/dts/imx35.dtsi
@@ -0,0 +1,386 @@
+/*
+ * Copyright 2012 Steffen Trumtrar, Pengutronix
+ *
+ * based on imx27.dtsi
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#include "skeleton.dtsi"
+#include "imx35-pinfunc.h"
+
+/ {
+ aliases {
+ ethernet0 = &fec;
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ spi0 = &spi1;
+ spi1 = &spi2;
+ };
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm1136";
+ device_type = "cpu";
+ };
+ };
+
+ avic: avic-interrupt-controller@68000000 {
+ compatible = "fsl,imx35-avic", "fsl,avic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x68000000 0x10000000>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&avic>;
+ ranges;
+
+ L2: l2-cache@30000000 {
+ compatible = "arm,l210-cache";
+ reg = <0x30000000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ aips1: aips@43f00000 {
+ compatible = "fsl,aips", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x43f00000 0x100000>;
+ ranges;
+
+ i2c1: i2c@43f80000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx35-i2c", "fsl,imx1-i2c";
+ reg = <0x43f80000 0x4000>;
+ clocks = <&clks 51>;
+ clock-names = "ipg_per";
+ interrupts = <10>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@43f84000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx35-i2c", "fsl,imx1-i2c";
+ reg = <0x43f84000 0x4000>;
+ clocks = <&clks 53>;
+ clock-names = "ipg_per";
+ interrupts = <3>;
+ status = "disabled";
+ };
+
+ uart1: serial@43f90000 {
+ compatible = "fsl,imx35-uart", "fsl,imx21-uart";
+ reg = <0x43f90000 0x4000>;
+ clocks = <&clks 9>, <&clks 70>;
+ clock-names = "ipg", "per";
+ interrupts = <45>;
+ status = "disabled";
+ };
+
+ uart2: serial@43f94000 {
+ compatible = "fsl,imx35-uart", "fsl,imx21-uart";
+ reg = <0x43f94000 0x4000>;
+ clocks = <&clks 9>, <&clks 71>;
+ clock-names = "ipg", "per";
+ interrupts = <32>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@43f98000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx35-i2c", "fsl,imx1-i2c";
+ reg = <0x43f98000 0x4000>;
+ clocks = <&clks 52>;
+ clock-names = "ipg_per";
+ interrupts = <4>;
+ status = "disabled";
+ };
+
+ ssi1: ssi@43fa0000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx35-ssi", "fsl,imx21-ssi";
+ reg = <0x43fa0000 0x4000>;
+ interrupts = <11>;
+ clocks = <&clks 68>;
+ dmas = <&sdma 28 0 0>,
+ <&sdma 29 0 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ spi1: cspi@43fa4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx35-cspi";
+ reg = <0x43fa4000 0x4000>;
+ clocks = <&clks 35 &clks 35>;
+ clock-names = "ipg", "per";
+ interrupts = <14>;
+ status = "disabled";
+ };
+
+ iomuxc: iomuxc@43fac000 {
+ compatible = "fsl,imx35-iomuxc";
+ reg = <0x43fac000 0x4000>;
+ };
+ };
+
+ spba: spba-bus@50000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x50000000 0x100000>;
+ ranges;
+
+ uart3: serial@5000c000 {
+ compatible = "fsl,imx35-uart", "fsl,imx21-uart";
+ reg = <0x5000c000 0x4000>;
+ clocks = <&clks 9>, <&clks 72>;
+ clock-names = "ipg", "per";
+ interrupts = <18>;
+ status = "disabled";
+ };
+
+ spi2: cspi@50010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx35-cspi";
+ reg = <0x50010000 0x4000>;
+ interrupts = <13>;
+ clocks = <&clks 36 &clks 36>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ fec: fec@50038000 {
+ compatible = "fsl,imx35-fec", "fsl,imx27-fec";
+ reg = <0x50038000 0x4000>;
+ clocks = <&clks 46>, <&clks 8>;
+ clock-names = "ipg", "ahb";
+ interrupts = <57>;
+ status = "disabled";
+ };
+ };
+
+ aips2: aips@53f00000 {
+ compatible = "fsl,aips", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x53f00000 0x100000>;
+ ranges;
+
+ clks: ccm@53f80000 {
+ compatible = "fsl,imx35-ccm";
+ reg = <0x53f80000 0x4000>;
+ interrupts = <31>;
+ #clock-cells = <1>;
+ };
+
+ gpt: timer@53f90000 {
+ compatible = "fsl,imx35-gpt", "fsl,imx31-gpt";
+ reg = <0x53f90000 0x4000>;
+ interrupts = <29>;
+ clocks = <&clks 9>, <&clks 50>;
+ clock-names = "ipg", "per";
+ };
+
+ gpio3: gpio@53fa4000 {
+ compatible = "fsl,imx35-gpio", "fsl,imx31-gpio";
+ reg = <0x53fa4000 0x4000>;
+ interrupts = <56>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ esdhc1: esdhc@53fb4000 {
+ compatible = "fsl,imx35-esdhc";
+ reg = <0x53fb4000 0x4000>;
+ interrupts = <7>;
+ clocks = <&clks 9>, <&clks 8>, <&clks 43>;
+ clock-names = "ipg", "ahb", "per";
+ status = "disabled";
+ };
+
+ esdhc2: esdhc@53fb8000 {
+ compatible = "fsl,imx35-esdhc";
+ reg = <0x53fb8000 0x4000>;
+ interrupts = <8>;
+ clocks = <&clks 9>, <&clks 8>, <&clks 44>;
+ clock-names = "ipg", "ahb", "per";
+ status = "disabled";
+ };
+
+ esdhc3: esdhc@53fbc000 {
+ compatible = "fsl,imx35-esdhc";
+ reg = <0x53fbc000 0x4000>;
+ interrupts = <9>;
+ clocks = <&clks 9>, <&clks 8>, <&clks 45>;
+ clock-names = "ipg", "ahb", "per";
+ status = "disabled";
+ };
+
+ audmux: audmux@53fc4000 {
+ compatible = "fsl,imx35-audmux", "fsl,imx31-audmux";
+ reg = <0x53fc4000 0x4000>;
+ status = "disabled";
+ };
+
+ gpio1: gpio@53fcc000 {
+ compatible = "fsl,imx35-gpio", "fsl,imx31-gpio";
+ reg = <0x53fcc000 0x4000>;
+ interrupts = <52>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@53fd0000 {
+ compatible = "fsl,imx35-gpio", "fsl,imx31-gpio";
+ reg = <0x53fd0000 0x4000>;
+ interrupts = <51>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ sdma: sdma@53fd4000 {
+ compatible = "fsl,imx35-sdma";
+ reg = <0x53fd4000 0x4000>;
+ clocks = <&clks 9>, <&clks 65>;
+ clock-names = "ipg", "ahb";
+ #dma-cells = <3>;
+ interrupts = <34>;
+ fsl,sdma-ram-script-name = "/*(DEBLOBBED)*/";
+ };
+
+ wdog: wdog@53fdc000 {
+ compatible = "fsl,imx35-wdt", "fsl,imx21-wdt";
+ reg = <0x53fdc000 0x4000>;
+ clocks = <&clks 74>;
+ clock-names = "";
+ interrupts = <55>;
+ };
+
+ can1: can@53fe4000 {
+ compatible = "fsl,imx35-flexcan", "fsl,p1010-flexcan";
+ reg = <0x53fe4000 0x1000>;
+ clocks = <&clks 33>;
+ clock-names = "ipg";
+ interrupts = <43>;
+ status = "disabled";
+ };
+
+ can2: can@53fe8000 {
+ compatible = "fsl,imx35-flexcan", "fsl,p1010-flexcan";
+ reg = <0x53fe8000 0x1000>;
+ clocks = <&clks 34>;
+ clock-names = "ipg";
+ interrupts = <44>;
+ status = "disabled";
+ };
+
+ usbotg: usb@53ff4000 {
+ compatible = "fsl,imx35-usb", "fsl,imx27-usb";
+ reg = <0x53ff4000 0x0200>;
+ interrupts = <37>;
+ clocks = <&clks 73>;
+ fsl,usbmisc = <&usbmisc 0>;
+ fsl,usbphy = <&usbphy0>;
+ status = "disabled";
+ };
+
+ usbhost1: usb@53ff4400 {
+ compatible = "fsl,imx35-usb", "fsl,imx27-usb";
+ reg = <0x53ff4400 0x0200>;
+ interrupts = <35>;
+ clocks = <&clks 73>;
+ fsl,usbmisc = <&usbmisc 1>;
+ fsl,usbphy = <&usbphy1>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbmisc: usbmisc@53ff4600 {
+ #index-cells = <1>;
+ compatible = "fsl,imx35-usbmisc";
+ clocks = <&clks 9>, <&clks 73>, <&clks 28>;
+ clock-names = "ipg", "ahb", "per";
+ reg = <0x53ff4600 0x00f>;
+ };
+ };
+
+ emi@80000000 { /* External Memory Interface */
+ compatible = "fsl,emi", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80000000 0x40000000>;
+ ranges;
+
+ nfc: nand@bb000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,imx35-nand", "fsl,imx25-nand";
+ reg = <0xbb000000 0x2000>;
+ clocks = <&clks 29>;
+ clock-names = "";
+ interrupts = <33>;
+ status = "disabled";
+ };
+
+ weim: weim@b8002000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clocks = <&clks 0>;
+ compatible = "fsl,imx35-weim", "fsl,imx27-weim";
+ reg = <0xb8002000 0x1000>;
+ ranges = <
+ 0 0 0xa0000000 0x8000000
+ 1 0 0xa8000000 0x8000000
+ 2 0 0xb0000000 0x2000000
+ 3 0 0xb2000000 0x2000000
+ 4 0 0xb4000000 0x2000000
+ 5 0 0xb6000000 0x2000000
+ >;
+ status = "disabled";
+ };
+ };
+ };
+
+ usbphy {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usbphy0: usb-phy@0 {
+ reg = <0>;
+ compatible = "usb-nop-xceiv";
+ };
+
+ usbphy1: usb-phy@1 {
+ reg = <1>;
+ compatible = "usb-nop-xceiv";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx50-evk.dts b/arch/arm/boot/dts/imx50-evk.dts
new file mode 100644
index 000000000..1b22512c9
--- /dev/null
+++ b/arch/arm/boot/dts/imx50-evk.dts
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2013 Greg Ungerer <gerg@uclinux.org>
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx50.dtsi"
+
+/ {
+ model = "Freescale i.MX50 Evaluation Kit";
+ compatible = "fsl,imx50-evk", "fsl,imx50";
+
+ memory {
+ reg = <0x70000000 0x80000000>;
+ };
+};
+
+&cspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cspi>;
+ fsl,spi-num-chipselects = <2>;
+ cs-gpios = <&gpio4 11 0>, <&gpio4 13 0>;
+ status = "okay";
+
+ flash: m25p32@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p32", "m25p80";
+ spi-max-frequency = <25000000>;
+ reg = <1>;
+
+ partition@0 {
+ label = "bootloader";
+ reg = <0x0 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "kernel";
+ reg = <0x100000 0x300000>;
+ };
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ phy-mode = "rmii";
+ phy-reset-gpios = <&gpio4 12 0>;
+ status = "okay";
+};
+
+&iomuxc {
+ imx50-evk {
+ pinctrl_cspi: cspigrp {
+ fsl,pins = <
+ MX50_PAD_CSPI_SCLK__CSPI_SCLK 0x00
+ MX50_PAD_CSPI_MISO__CSPI_MISO 0x00
+ MX50_PAD_CSPI_MOSI__CSPI_MOSI 0x00
+ MX50_PAD_CSPI_SS0__GPIO4_11 0xc4
+ MX50_PAD_ECSPI1_MOSI__CSPI_SS1 0xf4
+ >;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX50_PAD_SSI_RXFS__FEC_MDC 0x80
+ MX50_PAD_SSI_RXC__FEC_MDIO 0x80
+ MX50_PAD_DISP_D0__FEC_TX_CLK 0x80
+ MX50_PAD_DISP_D1__FEC_RX_ERR 0x80
+ MX50_PAD_DISP_D2__FEC_RX_DV 0x80
+ MX50_PAD_DISP_D3__FEC_RDATA_1 0x80
+ MX50_PAD_DISP_D4__FEC_RDATA_0 0x80
+ MX50_PAD_DISP_D5__FEC_TX_EN 0x80
+ MX50_PAD_DISP_D6__FEC_TDATA_1 0x80
+ MX50_PAD_DISP_D7__FEC_TDATA_0 0x80
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX50_PAD_UART1_TXD__UART1_TXD_MUX 0x1e4
+ MX50_PAD_UART1_RXD__UART1_RXD_MUX 0x1e4
+ MX50_PAD_UART1_RTS__UART1_RTS 0x1e4
+ MX50_PAD_UART1_CTS__UART1_CTS 0x1e4
+ >;
+ };
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&usbh1 {
+ status = "okay";
+};
+
+&usbh2 {
+ status = "okay";
+};
+
+&usbh3 {
+ status = "okay";
+};
+
+&usbotg {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx50-pinfunc.h b/arch/arm/boot/dts/imx50-pinfunc.h
new file mode 100644
index 000000000..97e6e7f4e
--- /dev/null
+++ b/arch/arm/boot/dts/imx50-pinfunc.h
@@ -0,0 +1,923 @@
+/*
+ * Copyright 2013 Greg Ungerer <gerg@uclinux.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 __DTS_IMX50_PINFUNC_H
+#define __DTS_IMX50_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX50_PAD_KEY_COL0__KPP_COL_0 0x020 0x2cc 0x000 0x0 0x0
+#define MX50_PAD_KEY_COL0__GPIO4_0 0x020 0x2cc 0x000 0x1 0x0
+#define MX50_PAD_KEY_COL0__EIM_NANDF_CLE 0x020 0x2cc 0x000 0x2 0x0
+#define MX50_PAD_KEY_COL0__CTI_TRIGIN7 0x020 0x2cc 0x000 0x6 0x0
+#define MX50_PAD_KEY_COL0__USBPHY1_TXREADY 0x020 0x2cc 0x000 0x7 0x0
+#define MX50_PAD_KEY_ROW0__KPP_ROW_0 0x024 0x2d0 0x000 0x0 0x0
+#define MX50_PAD_KEY_ROW0__GPIO4_1 0x024 0x2d0 0x000 0x1 0x0
+#define MX50_PAD_KEY_ROW0__EIM_NANDF_ALE 0x024 0x2d0 0x000 0x2 0x0
+#define MX50_PAD_KEY_ROW0__CTI_TRIGIN_ACK7 0x024 0x2d0 0x000 0x6 0x0
+#define MX50_PAD_KEY_ROW0__USBPHY1_RXVALID 0x024 0x2d0 0x000 0x7 0x0
+#define MX50_PAD_KEY_COL1__KPP_COL_1 0x028 0x2d4 0x000 0x0 0x0
+#define MX50_PAD_KEY_COL1__GPIO4_2 0x028 0x2d4 0x000 0x1 0x0
+#define MX50_PAD_KEY_COL1__EIM_NANDF_CEN_0 0x028 0x2d4 0x000 0x2 0x0
+#define MX50_PAD_KEY_COL1__CTI_TRIGOUT_ACK6 0x028 0x2d4 0x000 0x6 0x0
+#define MX50_PAD_KEY_COL1__USBPHY1_RXACTIVE 0x028 0x2d4 0x000 0x7 0x0
+#define MX50_PAD_KEY_ROW1__KPP_ROW_1 0x02c 0x2d8 0x000 0x0 0x0
+#define MX50_PAD_KEY_ROW1__GPIO4_3 0x02c 0x2d8 0x000 0x1 0x0
+#define MX50_PAD_KEY_ROW1__EIM_NANDF_CEN_1 0x02c 0x2d8 0x000 0x2 0x0
+#define MX50_PAD_KEY_ROW1__CTI_TRIGOUT_ACK7 0x02c 0x2d8 0x000 0x6 0x0
+#define MX50_PAD_KEY_ROW1__USBPHY1_RXERROR 0x02c 0x2d8 0x000 0x7 0x0
+#define MX50_PAD_KEY_COL2__KPP_COL_1 0x030 0x2dc 0x000 0x0 0x0
+#define MX50_PAD_KEY_COL2__GPIO4_4 0x030 0x2dc 0x000 0x1 0x0
+#define MX50_PAD_KEY_COL2__EIM_NANDF_CEN_2 0x030 0x2dc 0x000 0x2 0x0
+#define MX50_PAD_KEY_COL2__CTI_TRIGOUT6 0x030 0x2dc 0x000 0x6 0x0
+#define MX50_PAD_KEY_COL2__USBPHY1_SIECLOCK 0x030 0x2dc 0x000 0x7 0x0
+#define MX50_PAD_KEY_ROW2__KPP_ROW_2 0x034 0x2e0 0x000 0x0 0x0
+#define MX50_PAD_KEY_ROW2__GPIO4_5 0x034 0x2e0 0x000 0x1 0x0
+#define MX50_PAD_KEY_ROW2__EIM_NANDF_CEN_3 0x034 0x2e0 0x000 0x2 0x0
+#define MX50_PAD_KEY_ROW2__CTI_TRIGOUT7 0x034 0x2e0 0x000 0x6 0x0
+#define MX50_PAD_KEY_ROW2__USBPHY1_LINESTATE_0 0x034 0x2e0 0x000 0x7 0x0
+#define MX50_PAD_KEY_COL3__KPP_COL_2 0x038 0x2e4 0x000 0x0 0x0
+#define MX50_PAD_KEY_COL3__GPIO4_6 0x038 0x2e4 0x000 0x1 0x0
+#define MX50_PAD_KEY_COL3__EIM_NANDF_READY0 0x038 0x2e4 0x7b4 0x2 0x0
+#define MX50_PAD_KEY_COL3__SDMA_EXT_EVENT_0 0x038 0x2e4 0x7b8 0x6 0x0
+#define MX50_PAD_KEY_COL3__USBPHY1_LINESTATE_1 0x038 0x2e4 0x000 0x7 0x0
+#define MX50_PAD_KEY_ROW3__KPP_ROW_3 0x03c 0x2e8 0x000 0x0 0x0
+#define MX50_PAD_KEY_ROW3__GPIO4_7 0x03c 0x2e8 0x000 0x1 0x0
+#define MX50_PAD_KEY_ROW3__EIM_NANDF_DQS 0x03c 0x2e8 0x7b0 0x2 0x0
+#define MX50_PAD_KEY_ROW3__SDMA_EXT_EVENT_1 0x03c 0x2e8 0x7bc 0x6 0x0
+#define MX50_PAD_KEY_ROW3__USBPHY1_VBUSVALID 0x03c 0x2e8 0x000 0x7 0x0
+#define MX50_PAD_I2C1_SCL__I2C1_SCL 0x040 0x2ec 0x000 0x0 0x0
+#define MX50_PAD_I2C1_SCL__GPIO6_18 0x040 0x2ec 0x000 0x1 0x0
+#define MX50_PAD_I2C1_SCL__UART2_TXD_MUX 0x040 0x2ec 0x7cc 0x2 0x0
+#define MX50_PAD_I2C1_SDA__I2C1_SDA 0x044 0x2f0 0x000 0x0 0x0
+#define MX50_PAD_I2C1_SDA__GPIO6_19 0x044 0x2f0 0x000 0x1 0x0
+#define MX50_PAD_I2C1_SDA__UART2_RXD_MUX 0x044 0x2f0 0x7cc 0x2 0x1
+#define MX50_PAD_I2C2_SCL__I2C2_SCL 0x048 0x2f4 0x000 0x0 0x0
+#define MX50_PAD_I2C2_SCL__GPIO6_20 0x048 0x2f4 0x000 0x1 0x0
+#define MX50_PAD_I2C2_SCL__UART2_CTS 0x048 0x2f4 0x000 0x2 0x0
+#define MX50_PAD_I2C2_SDA__I2C2_SDA 0x04c 0x2f8 0x000 0x0 0x0
+#define MX50_PAD_I2C2_SDA__GPIO6_21 0x04c 0x2f8 0x000 0x1 0x0
+#define MX50_PAD_I2C2_SDA__UART2_RTS 0x04c 0x2f8 0x7c8 0x2 0x1
+#define MX50_PAD_I2C3_SCL__I2C3_SCL 0x050 0x2fc 0x000 0x0 0x0
+#define MX50_PAD_I2C3_SCL__GPIO6_22 0x050 0x2fc 0x000 0x1 0x0
+#define MX50_PAD_I2C3_SCL__FEC_MDC 0x050 0x2fc 0x000 0x2 0x0
+#define MX50_PAD_I2C3_SCL__GPC_PMIC_RDY 0x050 0x2fc 0x000 0x3 0x0
+#define MX50_PAD_I2C3_SCL__GPT_CAPIN1 0x050 0x2fc 0x000 0x5 0x0
+#define MX50_PAD_I2C3_SCL__OBSERVE_MUX_OBSRV_INT_OUT0 0x050 0x2fc 0x000 0x6 0x0
+#define MX50_PAD_I2C3_SCL__USBOH1_USBOTG_OC 0x050 0x2fc 0x7e8 0x7 0x0
+#define MX50_PAD_I2C3_SDA__I2C3_SDA 0x054 0x300 0x000 0x0 0x0
+#define MX50_PAD_I2C3_SDA__GPIO6_23 0x054 0x300 0x000 0x1 0x0
+#define MX50_PAD_I2C3_SDA__FEC_MDIO 0x054 0x300 0x774 0x2 0x0
+#define MX50_PAD_I2C3_SDA__TZIC_PWRFAIL_INT 0x054 0x300 0x000 0x3 0x0
+#define MX50_PAD_I2C3_SDA__SRTC_ALARM_DEB 0x054 0x300 0x000 0x4 0x0
+#define MX50_PAD_I2C3_SDA__GPT_CAPIN2 0x054 0x300 0x000 0x5 0x0
+#define MX50_PAD_I2C3_SDA__OBSERVE_MUX_OBSRV_INT_OUT1 0x054 0x300 0x000 0x6 0x0
+#define MX50_PAD_I2C3_SDA__USBOH1_USBOTG_PWR 0x054 0x300 0x000 0x7 0x0
+#define MX50_PAD_PWM1__PWM1_PWMO 0x058 0x304 0x000 0x0 0x0
+#define MX50_PAD_PWM1__GPIO6_24 0x058 0x304 0x000 0x1 0x0
+#define MX50_PAD_PWM1__USBOH1_USBOTG_OC 0x058 0x304 0x7e8 0x2 0x1
+#define MX50_PAD_PWM1__GPT_CMPOUT1 0x058 0x304 0x000 0x5 0x0
+#define MX50_PAD_PWM1__OBSERVE_MUX_OBSRV_INT_OUT2 0x058 0x304 0x000 0x6 0x0
+#define MX50_PAD_PWM1__SJC_FAIL 0x058 0x304 0x000 0x7 0x0
+#define MX50_PAD_PWM2__PWM2_PWMO 0x05c 0x308 0x000 0x0 0x0
+#define MX50_PAD_PWM2__GPIO6_25 0x05c 0x308 0x000 0x1 0x0
+#define MX50_PAD_PWM2__USBOH1_USBOTG_PWR 0x05c 0x308 0x000 0x2 0x0
+#define MX50_PAD_PWM2__GPT_CMPOUT2 0x05c 0x308 0x000 0x5 0x0
+#define MX50_PAD_PWM2__OBSERVE_MUX_OBSRV_INT_OUT3 0x05c 0x308 0x000 0x6 0x0
+#define MX50_PAD_PWM2__SRC_ANY_PU_RST 0x05c 0x308 0x000 0x7 0x0
+#define MX50_PAD_OWIRE__OWIRE_LINE 0x060 0x30c 0x000 0x0 0x0
+#define MX50_PAD_OWIRE__GPIO6_26 0x060 0x30c 0x000 0x1 0x0
+#define MX50_PAD_OWIRE__USBOH1_USBH1_OC 0x060 0x30c 0x000 0x2 0x0
+#define MX50_PAD_OWIRE__CCM_SSI_EXT1_CLK 0x060 0x30c 0x000 0x3 0x0
+#define MX50_PAD_OWIRE__EPDC_PWRIRQ 0x060 0x30c 0x000 0x4 0x0
+#define MX50_PAD_OWIRE__GPT_CMPOUT3 0x060 0x30c 0x000 0x5 0x0
+#define MX50_PAD_OWIRE__OBSERVE_MUX_OBSRV_INT_OUT4 0x060 0x30c 0x000 0x6 0x0
+#define MX50_PAD_OWIRE__SJC_JTAG_ACT 0x060 0x30c 0x000 0x7 0x0
+#define MX50_PAD_EPITO__EPIT1_EPITO 0x064 0x310 0x000 0x0 0x0
+#define MX50_PAD_EPITO__GPIO6_27 0x064 0x310 0x000 0x1 0x0
+#define MX50_PAD_EPITO__USBOH1_USBH1_PWR 0x064 0x310 0x000 0x2 0x0
+#define MX50_PAD_EPITO__CCM_SSI_EXT2_CLK 0x064 0x310 0x000 0x3 0x0
+#define MX50_PAD_EPITO__DPLLIP1_TOG_EN 0x064 0x310 0x000 0x4 0x0
+#define MX50_PAD_EPITO__GPT_CLK_IN 0x064 0x310 0x000 0x5 0x0
+#define MX50_PAD_EPITO__PMU_IRQ_B 0x064 0x310 0x000 0x6 0x0
+#define MX50_PAD_EPITO__SJC_DE_B 0x064 0x310 0x000 0x7 0x0
+#define MX50_PAD_WDOG__WDOG1_WDOG_B 0x068 0x314 0x000 0x0 0x0
+#define MX50_PAD_WDOG__GPIO6_28 0x068 0x314 0x000 0x1 0x0
+#define MX50_PAD_WDOG__WDOG1_WDOG_RST_B_DEB 0x068 0x314 0x000 0x2 0x0
+#define MX50_PAD_WDOG__CCM_XTAL32K 0x068 0x314 0x000 0x6 0x0
+#define MX50_PAD_WDOG__SJC_DONE 0x068 0x314 0x000 0x7 0x0
+#define MX50_PAD_SSI_TXFS__AUDMUX_AUD3_TXFS 0x06c 0x318 0x000 0x0 0x0
+#define MX50_PAD_SSI_TXFS__GPIO6_0 0x06c 0x318 0x000 0x1 0x0
+#define MX50_PAD_SSI_TXFS__SRC_BT_FUSE_RSV_1 0x06c 0x318 0x000 0x6 0x0
+#define MX50_PAD_SSI_TXFS__USBPHY1_DATAOUT_8 0x06c 0x318 0x000 0x7 0x0
+#define MX50_PAD_SSI_TXC__AUDMUX_AUD3_TXC 0x070 0x31c 0x000 0x0 0x0
+#define MX50_PAD_SSI_TXC__GPIO6_1 0x070 0x31c 0x000 0x1 0x0
+#define MX50_PAD_SSI_TXC__SRC_BT_FUSE_RSV_0 0x070 0x31c 0x000 0x6 0x0
+#define MX50_PAD_SSI_TXC__USBPHY1_DATAOUT_9 0x070 0x31c 0x000 0x7 0x0
+#define MX50_PAD_SSI_TXD__AUDMUX_AUD3_TXD 0x074 0x320 0x000 0x0 0x0
+#define MX50_PAD_SSI_TXD__GPIO6_2 0x074 0x320 0x000 0x1 0x0
+#define MX50_PAD_SSI_TXD__CSPI_RDY 0x074 0x320 0x6e8 0x4 0x0
+#define MX50_PAD_SSI_TXD__USBPHY1_DATAOUT_10 0x074 0x320 0x000 0x7 0x0
+#define MX50_PAD_SSI_RXD__AUDMUX_AUD3_RXD 0x078 0x324 0x000 0x0 0x0
+#define MX50_PAD_SSI_RXD__GPIO6_3 0x078 0x324 0x000 0x1 0x0
+#define MX50_PAD_SSI_RXD__CSPI_SS3 0x078 0x324 0x6f4 0x4 0x0
+#define MX50_PAD_SSI_RXD__USBPHY1_DATAOUT_11 0x078 0x324 0x000 0x7 0x0
+#define MX50_PAD_SSI_RXFS__AUDMUX_AUD3_RXFS 0x07c 0x328 0x000 0x0 0x0
+#define MX50_PAD_SSI_RXFS__GPIO6_4 0x07c 0x328 0x000 0x1 0x0
+#define MX50_PAD_SSI_RXFS__UART5_TXD_MUX 0x07c 0x328 0x7e4 0x2 0x0
+#define MX50_PAD_SSI_RXFS__EIM_WEIM_D_6 0x07c 0x328 0x804 0x3 0x0
+#define MX50_PAD_SSI_RXFS__CSPI_SS2 0x07c 0x328 0x6f0 0x4 0x0
+#define MX50_PAD_SSI_RXFS__FEC_COL 0x07c 0x328 0x770 0x5 0x0
+#define MX50_PAD_SSI_RXFS__FEC_MDC 0x07c 0x328 0x000 0x6 0x0
+#define MX50_PAD_SSI_RXFS__USBPHY1_DATAOUT_12 0x07c 0x328 0x000 0x7 0x0
+#define MX50_PAD_SSI_RXC__AUDMUX_AUD3_RXC 0x080 0x32c 0x000 0x0 0x0
+#define MX50_PAD_SSI_RXC__GPIO6_5 0x080 0x32c 0x000 0x1 0x0
+#define MX50_PAD_SSI_RXC__UART5_RXD_MUX 0x080 0x32c 0x7e4 0x2 0x1
+#define MX50_PAD_SSI_RXC__EIM_WEIM_D_7 0x080 0x32c 0x808 0x3 0x0
+#define MX50_PAD_SSI_RXC__CSPI_SS1 0x080 0x32c 0x6ec 0x4 0x0
+#define MX50_PAD_SSI_RXC__FEC_RX_CLK 0x080 0x32c 0x780 0x5 0x0
+#define MX50_PAD_SSI_RXC__FEC_MDIO 0x080 0x32c 0x774 0x6 0x1
+#define MX50_PAD_SSI_RXC__USBPHY1_DATAOUT_13 0x080 0x32c 0x000 0x7 0x0
+#define MX50_PAD_UART1_TXD__UART1_TXD_MUX 0x084 0x330 0x7c4 0x0 0x0
+#define MX50_PAD_UART1_TXD__GPIO6_6 0x084 0x330 0x000 0x1 0x0
+#define MX50_PAD_UART1_TXD__USBPHY1_DATAOUT_14 0x084 0x330 0x000 0x7 0x0
+#define MX50_PAD_UART1_RXD__UART1_RXD_MUX 0x088 0x334 0x7c4 0x0 0x1
+#define MX50_PAD_UART1_RXD__GPIO6_7 0x088 0x334 0x000 0x1 0x0
+#define MX50_PAD_UART1_RXD__USBPHY1_DATAOUT_15 0x088 0x334 0x000 0x7 0x0
+#define MX50_PAD_UART1_CTS__UART1_CTS 0x08c 0x338 0x000 0x0 0x0
+#define MX50_PAD_UART1_CTS__GPIO6_8 0x08c 0x338 0x000 0x1 0x0
+#define MX50_PAD_UART1_CTS__UART5_TXD_MUX 0x08c 0x338 0x7e4 0x2 0x2
+#define MX50_PAD_UART1_CTS__ESDHC4_DAT4 0x08c 0x338 0x760 0x4 0x0
+#define MX50_PAD_UART1_CTS__ESDHC4_CMD 0x08c 0x338 0x74c 0x5 0x0
+#define MX50_PAD_UART1_CTS__USBPHY2_DATAOUT_8 0x08c 0x338 0x000 0x7 0x0
+#define MX50_PAD_UART1_RTS__UART1_RTS 0x090 0x33c 0x7c0 0x0 0x3
+#define MX50_PAD_UART1_RTS__GPIO6_9 0x090 0x33c 0x000 0x1 0x0
+#define MX50_PAD_UART1_RTS__UART5_RXD_MUX 0x090 0x33c 0x7e4 0x2 0x3
+#define MX50_PAD_UART1_RTS__ESDHC4_DAT5 0x090 0x33c 0x764 0x4 0x0
+#define MX50_PAD_UART1_RTS__ESDHC4_CLK 0x090 0x33c 0x748 0x5 0x0
+#define MX50_PAD_UART1_RTS__USBPHY2_DATAOUT_9 0x090 0x33c 0x000 0x7 0x0
+#define MX50_PAD_UART2_TXD__UART2_TXD_MUX 0x094 0x340 0x7cc 0x0 0x2
+#define MX50_PAD_UART2_TXD__GPIO6_10 0x094 0x340 0x000 0x1 0x0
+#define MX50_PAD_UART2_TXD__ESDHC4_DAT6 0x094 0x340 0x768 0x4 0x0
+#define MX50_PAD_UART2_TXD__ESDHC4_DAT4 0x094 0x340 0x760 0x5 0x1
+#define MX50_PAD_UART2_TXD__USBPHY2_DATAOUT_10 0x094 0x340 0x000 0x7 0x0
+#define MX50_PAD_UART2_RXD__UART2_RXD_MUX 0x098 0x344 0x7cc 0x0 0x3
+#define MX50_PAD_UART2_RXD__GPIO6_11 0x098 0x344 0x000 0x1 0x0
+#define MX50_PAD_UART2_RXD__ESDHC4_DAT7 0x098 0x344 0x76c 0x4 0x0
+#define MX50_PAD_UART2_RXD__ESDHC4_DAT5 0x098 0x344 0x764 0x5 0x1
+#define MX50_PAD_UART2_RXD__USBPHY2_DATAOUT_11 0x098 0x344 0x000 0x7 0x0
+#define MX50_PAD_UART2_CTS__UART2_CTS 0x09c 0x348 0x000 0x0 0x0
+#define MX50_PAD_UART2_CTS__GPIO6_12 0x09c 0x348 0x000 0x1 0x0
+#define MX50_PAD_UART2_CTS__ESDHC4_CMD 0x09c 0x348 0x74c 0x4 0x1
+#define MX50_PAD_UART2_CTS__ESDHC4_DAT6 0x09c 0x348 0x768 0x5 0x1
+#define MX50_PAD_UART2_CTS__USBPHY2_DATAOUT_12 0x09c 0x348 0x000 0x7 0x0
+#define MX50_PAD_UART2_RTS__UART2_RTS 0x0a0 0x34c 0x7c8 0x0 0x2
+#define MX50_PAD_UART2_RTS__GPIO6_13 0x0a0 0x34c 0x000 0x1 0x0
+#define MX50_PAD_UART2_RTS__ESDHC4_CLK 0x0a0 0x34c 0x748 0x4 0x1
+#define MX50_PAD_UART2_RTS__ESDHC4_DAT7 0x0a0 0x34c 0x76c 0x5 0x1
+#define MX50_PAD_UART2_RTS__USBPHY2_DATAOUT_13 0x0a0 0x34c 0x000 0x7 0x0
+#define MX50_PAD_UART3_TXD__UART3_TXD_MUX 0x0a4 0x350 0x7d4 0x0 0x0
+#define MX50_PAD_UART3_TXD__GPIO6_14 0x0a4 0x350 0x000 0x1 0x0
+#define MX50_PAD_UART3_TXD__ESDHC1_DAT4 0x0a4 0x350 0x000 0x3 0x0
+#define MX50_PAD_UART3_TXD__ESDHC4_DAT0 0x0a4 0x350 0x000 0x4 0x0
+#define MX50_PAD_UART3_TXD__ESDHC2_WP 0x0a4 0x350 0x744 0x5 0x0
+#define MX50_PAD_UART3_TXD__EIM_WEIM_D_12 0x0a4 0x350 0x81c 0x6 0x0
+#define MX50_PAD_UART3_TXD__USBPHY2_DATAOUT_14 0x0a4 0x350 0x000 0x7 0x0
+#define MX50_PAD_UART3_RXD__UART3_RXD_MUX 0x0a8 0x354 0x7d4 0x0 0x1
+#define MX50_PAD_UART3_RXD__GPIO6_15 0x0a8 0x354 0x000 0x1 0x0
+#define MX50_PAD_UART3_RXD__ESDHC1_DAT5 0x0a8 0x354 0x000 0x3 0x0
+#define MX50_PAD_UART3_RXD__ESDHC4_DAT1 0x0a8 0x354 0x754 0x4 0x0
+#define MX50_PAD_UART3_RXD__ESDHC2_CD 0x0a8 0x354 0x740 0x5 0x0
+#define MX50_PAD_UART3_RXD__EIM_WEIM_D_13 0x0a8 0x354 0x820 0x6 0x0
+#define MX50_PAD_UART3_RXD__USBPHY2_DATAOUT_15 0x0a8 0x354 0x000 0x7 0x0
+#define MX50_PAD_UART4_TXD__UART4_TXD_MUX 0x0ac 0x358 0x7dc 0x0 0x0
+#define MX50_PAD_UART4_TXD__GPIO6_16 0x0ac 0x358 0x000 0x1 0x0
+#define MX50_PAD_UART4_TXD__UART3_CTS 0x0ac 0x358 0x7d0 0x2 0x0
+#define MX50_PAD_UART4_TXD__ESDHC1_DAT6 0x0ac 0x358 0x000 0x3 0x0
+#define MX50_PAD_UART4_TXD__ESDHC4_DAT2 0x0ac 0x358 0x758 0x4 0x0
+#define MX50_PAD_UART4_TXD__ESDHC2_LCTL 0x0ac 0x358 0x000 0x5 0x0
+#define MX50_PAD_UART4_TXD__EIM_WEIM_D_14 0x0ac 0x358 0x824 0x6 0x0
+#define MX50_PAD_UART4_RXD__UART4_RXD_MUX 0x0b0 0x35c 0x7dc 0x0 0x1
+#define MX50_PAD_UART4_RXD__GPIO6_17 0x0b0 0x35c 0x000 0x1 0x0
+#define MX50_PAD_UART4_RXD__UART3_RTS 0x0b0 0x35c 0x7d0 0x2 0x1
+#define MX50_PAD_UART4_RXD__ESDHC1_DAT7 0x0b0 0x35c 0x000 0x3 0x0
+#define MX50_PAD_UART4_RXD__ESDHC4_DAT3 0x0b0 0x35c 0x75c 0x4 0x0
+#define MX50_PAD_UART4_RXD__ESDHC1_LCTL 0x0b0 0x35c 0x000 0x5 0x0
+#define MX50_PAD_UART4_RXD__EIM_WEIM_D_15 0x0b0 0x35c 0x828 0x6 0x0
+#define MX50_PAD_CSPI_SCLK__CSPI_SCLK 0x0b4 0x360 0x000 0x0 0x0
+#define MX50_PAD_CSPI_SCLK__GPIO4_8 0x0b4 0x360 0x000 0x1 0x0
+#define MX50_PAD_CSPI_MOSI__CSPI_MOSI 0x0b8 0x364 0x000 0x0 0x0
+#define MX50_PAD_CSPI_MOSI__GPIO4_9 0x0b8 0x364 0x000 0x1 0x0
+#define MX50_PAD_CSPI_MISO__CSPI_MISO 0x0bc 0x368 0x000 0x0 0x0
+#define MX50_PAD_CSPI_MISO__GPIO4_10 0x0bc 0x368 0x000 0x1 0x0
+#define MX50_PAD_CSPI_SS0__CSPI_SS0 0x0c0 0x36c 0x000 0x0 0x0
+#define MX50_PAD_CSPI_SS0__GPIO4_11 0x0c0 0x36c 0x000 0x1 0x0
+#define MX50_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x0c4 0x370 0x000 0x0 0x0
+#define MX50_PAD_ECSPI1_SCLK__GPIO4_12 0x0c4 0x370 0x000 0x1 0x0
+#define MX50_PAD_ECSPI1_SCLK__CSPI_RDY 0x0c4 0x370 0x6e8 0x2 0x1
+#define MX50_PAD_ECSPI1_SCLK__ECSPI2_RDY 0x0c4 0x370 0x000 0x3 0x0
+#define MX50_PAD_ECSPI1_SCLK__UART3_RTS 0x0c4 0x370 0x7d0 0x4 0x2
+#define MX50_PAD_ECSPI1_SCLK__EPDC_SDCE_6 0x0c4 0x370 0x000 0x5 0x0
+#define MX50_PAD_ECSPI1_SCLK__EIM_WEIM_D_8 0x0c4 0x370 0x80c 0x7 0x0
+#define MX50_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x0c8 0x374 0x000 0x0 0x0
+#define MX50_PAD_ECSPI1_MOSI__GPIO4_13 0x0c8 0x374 0x000 0x1 0x0
+#define MX50_PAD_ECSPI1_MOSI__CSPI_SS1 0x0c8 0x374 0x6ec 0x2 0x1
+#define MX50_PAD_ECSPI1_MOSI__ECSPI2_SS1 0x0c8 0x374 0x000 0x3 0x0
+#define MX50_PAD_ECSPI1_MOSI__UART3_CTS 0x0c8 0x374 0x000 0x4 0x0
+#define MX50_PAD_ECSPI1_MOSI__EPDC_SDCE_7 0x0c8 0x374 0x000 0x5 0x0
+#define MX50_PAD_ECSPI1_MOSI__EIM_WEIM_D_9 0x0c8 0x374 0x810 0x7 0x0
+#define MX50_PAD_ECSPI1_MISO__ECSPI1_MISO 0x0cc 0x378 0x000 0x0 0x0
+#define MX50_PAD_ECSPI1_MISO__GPIO4_14 0x0cc 0x378 0x000 0x1 0x0
+#define MX50_PAD_ECSPI1_MISO__CSPI_SS2 0x0cc 0x378 0x6f0 0x2 0x1
+#define MX50_PAD_ECSPI1_MISO__ECSPI2_SS2 0x0cc 0x378 0x000 0x3 0x0
+#define MX50_PAD_ECSPI1_MISO__UART4_RTS 0x0cc 0x378 0x7d8 0x4 0x0
+#define MX50_PAD_ECSPI1_MISO__EPDC_SDCE_8 0x0cc 0x378 0x000 0x5 0x0
+#define MX50_PAD_ECSPI1_MISO__EIM_WEIM_D_10 0x0cc 0x378 0x814 0x7 0x0
+#define MX50_PAD_ECSPI1_SS0__ECSPI1_SS0 0x0d0 0x37c 0x000 0x0 0x0
+#define MX50_PAD_ECSPI1_SS0__GPIO4_15 0x0d0 0x37c 0x000 0x1 0x0
+#define MX50_PAD_ECSPI1_SS0__CSPI_SS3 0x0d0 0x37c 0x6f4 0x2 0x1
+#define MX50_PAD_ECSPI1_SS0__ECSPI2_SS3 0x0d0 0x37c 0x000 0x3 0x0
+#define MX50_PAD_ECSPI1_SS0__UART4_CTS 0x0d0 0x37c 0x000 0x4 0x0
+#define MX50_PAD_ECSPI1_SS0__EPDC_SDCE_9 0x0d0 0x37c 0x000 0x5 0x0
+#define MX50_PAD_ECSPI1_SS0__EIM_WEIM_D_11 0x0d0 0x37c 0x818 0x7 0x0
+#define MX50_PAD_ECSPI2_SCLK__ECSPI2_SCLK 0x0d4 0x380 0x000 0x0 0x0
+#define MX50_PAD_ECSPI2_SCLK__GPIO4_16 0x0d4 0x380 0x000 0x1 0x0
+#define MX50_PAD_ECSPI2_SCLK__ELCDIF_WR_RWN 0x0d4 0x380 0x000 0x2 0x0
+#define MX50_PAD_ECSPI2_SCLK__ECSPI1_RDY 0x0d4 0x380 0x000 0x3 0x0
+#define MX50_PAD_ECSPI2_SCLK__UART5_RTS 0x0d4 0x380 0x7e0 0x4 0x0
+#define MX50_PAD_ECSPI2_SCLK__ELCDIF_DOTCLK 0x0d4 0x380 0x000 0x5 0x0
+#define MX50_PAD_ECSPI2_SCLK__EIM_NANDF_CEN_4 0x0d4 0x380 0x000 0x6 0x0
+#define MX50_PAD_ECSPI2_SCLK__EIM_WEIM_D_8 0x0d4 0x380 0x80c 0x7 0x1
+#define MX50_PAD_ECSPI2_MOSI__ECSPI2_MOSI 0x0d8 0x384 0x000 0x0 0x0
+#define MX50_PAD_ECSPI2_MOSI__GPIO4_17 0x0d8 0x384 0x000 0x1 0x0
+#define MX50_PAD_ECSPI2_MOSI__ELCDIF_RE_E 0x0d8 0x384 0x000 0x2 0x0
+#define MX50_PAD_ECSPI2_MOSI__ECSPI1_SS1 0x0d8 0x384 0x000 0x3 0x0
+#define MX50_PAD_ECSPI2_MOSI__UART5_CTS 0x0d8 0x384 0x7e0 0x4 0x1
+#define MX50_PAD_ECSPI2_MOSI__ELCDIF_ENABLE 0x0d8 0x384 0x000 0x5 0x0
+#define MX50_PAD_ECSPI2_MOSI__EIM_NANDF_CEN_5 0x0d8 0x384 0x000 0x6 0x0
+#define MX50_PAD_ECSPI2_MOSI__EIM_WEIM_D_9 0x0d8 0x384 0x810 0x7 0x1
+#define MX50_PAD_ECSPI2_MISO__ECSPI2_MISO 0x0dc 0x388 0x000 0x0 0x0
+#define MX50_PAD_ECSPI2_MISO__GPIO4_18 0x0dc 0x388 0x000 0x1 0x0
+#define MX50_PAD_ECSPI2_MISO__ELCDIF_RS 0x0dc 0x388 0x000 0x2 0x0
+#define MX50_PAD_ECSPI2_MISO__ECSPI1_SS2 0x0dc 0x388 0x000 0x3 0x0
+#define MX50_PAD_ECSPI2_MISO__UART5_TXD_MUX 0x0dc 0x388 0x7e4 0x4 0x4
+#define MX50_PAD_ECSPI2_MISO__ELCDIF_VSYNC 0x0dc 0x388 0x73c 0x5 0x0
+#define MX50_PAD_ECSPI2_MISO__EIM_NANDF_CEN_6 0x0dc 0x388 0x000 0x6 0x0
+#define MX50_PAD_ECSPI2_MISO__EIM_WEIM_D_10 0x0dc 0x388 0x814 0x7 0x1
+#define MX50_PAD_ECSPI2_SS0__ECSPI2_SS0 0x0e0 0x38c 0x000 0x0 0x0
+#define MX50_PAD_ECSPI2_SS0__GPIO4_19 0x0e0 0x38c 0x000 0x1 0x0
+#define MX50_PAD_ECSPI2_SS0__ELCDIF_CS 0x0e0 0x38c 0x000 0x2 0x0
+#define MX50_PAD_ECSPI2_SS0__ECSPI2_SS3 0x0e0 0x38c 0x000 0x3 0x0
+#define MX50_PAD_ECSPI2_SS0__UART5_RXD_MUX 0x0e0 0x38c 0x7e4 0x4 0x5
+#define MX50_PAD_ECSPI2_SS0__ELCDIF_HSYNC 0x0e0 0x38c 0x6f8 0x5 0x0
+#define MX50_PAD_ECSPI2_SS0__EIM_NANDF_CEN_7 0x0e0 0x38c 0x000 0x6 0x0
+#define MX50_PAD_ECSPI2_SS0__EIM_WEIM_D_11 0x0e0 0x38c 0x818 0x7 0x1
+#define MX50_PAD_SD1_CLK__ESDHC1_CLK 0x0e4 0x390 0x000 0x0 0x0
+#define MX50_PAD_SD1_CLK__GPIO5_0 0x0e4 0x390 0x000 0x1 0x0
+#define MX50_PAD_SD1_CLK__CCM_CLKO 0x0e4 0x390 0x000 0x7 0x0
+#define MX50_PAD_SD1_CMD__ESDHC1_CMD 0x0e8 0x394 0x000 0x0 0x0
+#define MX50_PAD_SD1_CMD__GPIO5_1 0x0e8 0x394 0x000 0x1 0x0
+#define MX50_PAD_SD1_CMD__CCM_CLKO2 0x0e8 0x394 0x000 0x7 0x0
+#define MX50_PAD_SD1_D0__ESDHC1_DAT0 0x0ec 0x398 0x000 0x0 0x0
+#define MX50_PAD_SD1_D0__GPIO5_2 0x0ec 0x398 0x000 0x1 0x0
+#define MX50_PAD_SD1_D0__CCM_PLL1_BYP 0x0ec 0x398 0x6dc 0x7 0x0
+#define MX50_PAD_SD1_D1__ESDHC1_DAT1 0x0f0 0x39c 0x000 0x0 0x0
+#define MX50_PAD_SD1_D1__GPIO5_3 0x0f0 0x39c 0x000 0x1 0x0
+#define MX50_PAD_SD1_D1__CCM_PLL2_BYP 0x0f0 0x39c 0x000 0x7 0x0
+#define MX50_PAD_SD1_D2__ESDHC1_DAT2 0x0f4 0x3a0 0x000 0x0 0x0
+#define MX50_PAD_SD1_D2__GPIO5_4 0x0f4 0x3a0 0x000 0x1 0x0
+#define MX50_PAD_SD1_D2__CCM_PLL3_BYP 0x0f4 0x3a0 0x6e4 0x7 0x0
+#define MX50_PAD_SD1_D3__ESDHC1_DAT3 0x0f8 0x3a4 0x000 0x0 0x0
+#define MX50_PAD_SD1_D3__GPIO5_5 0x0f8 0x3a4 0x000 0x1 0x0
+#define MX50_PAD_SD2_CLK__ESDHC2_CLK 0x0fc 0x3a8 0x000 0x0 0x0
+#define MX50_PAD_SD2_CLK__GPIO5_6 0x0fc 0x3a8 0x000 0x1 0x0
+#define MX50_PAD_SD2_CLK__MSHC_SCLK 0x0fc 0x3a8 0x000 0x2 0x0
+#define MX50_PAD_SD2_CMD__ESDHC2_CMD 0x100 0x3ac 0x000 0x0 0x0
+#define MX50_PAD_SD2_CMD__GPIO5_7 0x100 0x3ac 0x000 0x1 0x0
+#define MX50_PAD_SD2_CMD__MSHC_BS 0x100 0x3ac 0x000 0x2 0x0
+#define MX50_PAD_SD2_D0__ESDHC2_DAT0 0x104 0x3b0 0x000 0x0 0x0
+#define MX50_PAD_SD2_D0__GPIO5_8 0x104 0x3b0 0x000 0x1 0x0
+#define MX50_PAD_SD2_D0__MSHC_DATA_0 0x104 0x3b0 0x000 0x2 0x0
+#define MX50_PAD_SD2_D0__KPP_COL_4 0x104 0x3b0 0x790 0x3 0x0
+#define MX50_PAD_SD2_D1__ESDHC2_DAT1 0x108 0x3b4 0x000 0x0 0x0
+#define MX50_PAD_SD2_D1__GPIO5_9 0x108 0x3b4 0x000 0x1 0x0
+#define MX50_PAD_SD2_D1__MSHC_DATA_1 0x108 0x3b4 0x000 0x2 0x0
+#define MX50_PAD_SD2_D1__KPP_ROW_4 0x108 0x3b4 0x7a0 0x3 0x0
+#define MX50_PAD_SD2_D2__ESDHC2_DAT2 0x10c 0x3b8 0x000 0x0 0x0
+#define MX50_PAD_SD2_D2__GPIO5_10 0x10c 0x3b8 0x000 0x1 0x0
+#define MX50_PAD_SD2_D2__MSHC_DATA_2 0x10c 0x3b8 0x000 0x2 0x0
+#define MX50_PAD_SD2_D2__KPP_COL_5 0x10c 0x3b8 0x794 0x3 0x0
+#define MX50_PAD_SD2_D3__ESDHC2_DAT3 0x110 0x3bc 0x000 0x0 0x0
+#define MX50_PAD_SD2_D3__GPIO5_11 0x110 0x3bc 0x000 0x1 0x0
+#define MX50_PAD_SD2_D3__MSHC_DATA_3 0x110 0x3bc 0x000 0x2 0x0
+#define MX50_PAD_SD2_D3__KPP_ROW_5 0x110 0x3bc 0x7a4 0x3 0x0
+#define MX50_PAD_SD2_D4__ESDHC2_DAT4 0x114 0x3c0 0x000 0x0 0x0
+#define MX50_PAD_SD2_D4__GPIO5_12 0x114 0x3c0 0x000 0x1 0x0
+#define MX50_PAD_SD2_D4__AUDMUX_AUD4_RXFS 0x114 0x3c0 0x6d0 0x2 0x0
+#define MX50_PAD_SD2_D4__KPP_COL_6 0x114 0x3c0 0x798 0x3 0x0
+#define MX50_PAD_SD2_D4__EIM_WEIM_D_0 0x114 0x3c0 0x7ec 0x4 0x0
+#define MX50_PAD_SD2_D4__CCM_CCM_OUT_0 0x114 0x3c0 0x000 0x7 0x0
+#define MX50_PAD_SD2_D5__ESDHC2_DAT5 0x118 0x3c4 0x000 0x0 0x0
+#define MX50_PAD_SD2_D5__GPIO5_13 0x118 0x3c4 0x000 0x1 0x0
+#define MX50_PAD_SD2_D5__AUDMUX_AUD4_RXC 0x118 0x3c4 0x6cc 0x2 0x0
+#define MX50_PAD_SD2_D5__KPP_ROW_6 0x118 0x3c4 0x7a8 0x3 0x0
+#define MX50_PAD_SD2_D5__EIM_WEIM_D_1 0x118 0x3c4 0x7f0 0x4 0x0
+#define MX50_PAD_SD2_D5__CCM_CCM_OUT_1 0x118 0x3c4 0x000 0x7 0x0
+#define MX50_PAD_SD2_D6__ESDHC2_DAT6 0x11c 0x3c8 0x000 0x0 0x0
+#define MX50_PAD_SD2_D6__GPIO5_14 0x11c 0x3c8 0x000 0x1 0x0
+#define MX50_PAD_SD2_D6__AUDMUX_AUD4_RXD 0x11c 0x3c8 0x6c4 0x2 0x0
+#define MX50_PAD_SD2_D6__KPP_COL_7 0x11c 0x3c8 0x79c 0x3 0x0
+#define MX50_PAD_SD2_D6__EIM_WEIM_D_2 0x11c 0x3c8 0x7f4 0x4 0x0
+#define MX50_PAD_SD2_D6__CCM_CCM_OUT_2 0x11c 0x3c8 0x000 0x7 0x0
+#define MX50_PAD_SD2_D7__ESDHC2_DAT7 0x120 0x3cc 0x000 0x0 0x0
+#define MX50_PAD_SD2_D7__GPIO5_15 0x120 0x3cc 0x000 0x1 0x0
+#define MX50_PAD_SD2_D7__AUDMUX_AUD4_TXFS 0x120 0x3cc 0x6d8 0x2 0x0
+#define MX50_PAD_SD2_D7__KPP_ROW_7 0x120 0x3cc 0x7ac 0x3 0x0
+#define MX50_PAD_SD2_D7__EIM_WEIM_D_3 0x120 0x3cc 0x7f8 0x4 0x0
+#define MX50_PAD_SD2_D7__CCM_STOP 0x120 0x3cc 0x000 0x7 0x0
+#define MX50_PAD_SD2_WP__ESDHC2_WP 0x124 0x3d0 0x744 0x0 0x1
+#define MX50_PAD_SD2_WP__GPIO5_16 0x124 0x3d0 0x000 0x1 0x0
+#define MX50_PAD_SD2_WP__AUDMUX_AUD4_TXD 0x124 0x3d0 0x6c8 0x2 0x0
+#define MX50_PAD_SD2_WP__EIM_WEIM_D_4 0x124 0x3d0 0x7fc 0x4 0x0
+#define MX50_PAD_SD2_WP__CCM_WAIT 0x124 0x3d0 0x000 0x7 0x0
+#define MX50_PAD_SD2_CD__ESDHC2_CD 0x128 0x3d4 0x740 0x0 0x1
+#define MX50_PAD_SD2_CD__GPIO5_17 0x128 0x3d4 0x000 0x1 0x0
+#define MX50_PAD_SD2_CD__AUDMUX_AUD4_TXC 0x128 0x3d4 0x6d4 0x2 0x0
+#define MX50_PAD_SD2_CD__EIM_WEIM_D_5 0x128 0x3d4 0x800 0x4 0x0
+#define MX50_PAD_SD2_CD__CCM_REF_EN_B 0x128 0x3d4 0x000 0x7 0x0
+#define MX50_PAD_DISP_D0__ELCDIF_DAT_0 0x12c 0x40c 0x6fc 0x0 0x0
+#define MX50_PAD_DISP_D0__GPIO2_0 0x12c 0x40c 0x000 0x1 0x0
+#define MX50_PAD_DISP_D0__FEC_TX_CLK 0x12c 0x40c 0x78c 0x2 0x0
+#define MX50_PAD_DISP_D0__EIM_WEIM_A_16 0x12c 0x40c 0x000 0x3 0x0
+#define MX50_PAD_DISP_D0__SDMA_DEBUG_PC_0 0x12c 0x40c 0x000 0x6 0x0
+#define MX50_PAD_DISP_D0__USBPHY1_VSTATUS_0 0x12c 0x40c 0x000 0x7 0x0
+#define MX50_PAD_DISP_D1__ELCDIF_DAT_1 0x130 0x410 0x700 0x0 0x0
+#define MX50_PAD_DISP_D1__GPIO2_1 0x130 0x410 0x000 0x1 0x0
+#define MX50_PAD_DISP_D1__FEC_RX_ERR 0x130 0x410 0x788 0x2 0x0
+#define MX50_PAD_DISP_D1__EIM_WEIM_A_17 0x130 0x410 0x000 0x3 0x0
+#define MX50_PAD_DISP_D1__SDMA_DEBUG_PC_1 0x130 0x410 0x000 0x6 0x0
+#define MX50_PAD_DISP_D1__USBPHY1_VSTATUS_1 0x130 0x410 0x000 0x7 0x0
+#define MX50_PAD_DISP_D2__ELCDIF_DAT_2 0x134 0x414 0x704 0x0 0x0
+#define MX50_PAD_DISP_D2__GPIO2_2 0x134 0x414 0x000 0x1 0x0
+#define MX50_PAD_DISP_D2__FEC_RX_DV 0x134 0x414 0x784 0x2 0x0
+#define MX50_PAD_DISP_D2__EIM_WEIM_A_18 0x134 0x414 0x000 0x3 0x0
+#define MX50_PAD_DISP_D2__SDMA_DEBUG_PC_2 0x134 0x414 0x000 0x6 0x0
+#define MX50_PAD_DISP_D2__USBPHY1_VSTATUS_2 0x134 0x414 0x000 0x7 0x0
+#define MX50_PAD_DISP_D3__ELCDIF_DAT_3 0x138 0x418 0x708 0x0 0x0
+#define MX50_PAD_DISP_D3__GPIO2_3 0x138 0x418 0x000 0x1 0x0
+#define MX50_PAD_DISP_D3__FEC_RDATA_1 0x138 0x418 0x77c 0x2 0x0
+#define MX50_PAD_DISP_D3__EIM_WEIM_A_19 0x138 0x418 0x000 0x3 0x0
+#define MX50_PAD_DISP_D3__FEC_COL 0x138 0x418 0x770 0x4 0x1
+#define MX50_PAD_DISP_D3__SDMA_DEBUG_PC_3 0x138 0x418 0x000 0x6 0x0
+#define MX50_PAD_DISP_D3__USBPHY1_VSTATUS_3 0x138 0x418 0x000 0x7 0x0
+#define MX50_PAD_DISP_D4__ELCDIF_DAT_4 0x13c 0x41c 0x70c 0x0 0x0
+#define MX50_PAD_DISP_D4__GPIO2_4 0x13c 0x41c 0x000 0x1 0x0
+#define MX50_PAD_DISP_D4__FEC_RDATA_0 0x13c 0x41c 0x778 0x2 0x0
+#define MX50_PAD_DISP_D4__EIM_WEIM_A_20 0x13c 0x41c 0x000 0x3 0x0
+#define MX50_PAD_DISP_D4__SDMA_DEBUG_PC_4 0x13c 0x41c 0x000 0x6 0x0
+#define MX50_PAD_DISP_D4__USBPHY1_VSTATUS_4 0x13c 0x41c 0x000 0x7 0x0
+#define MX50_PAD_DISP_D5__ELCDIF_DAT_5 0x140 0x420 0x710 0x0 0x0
+#define MX50_PAD_DISP_D5__GPIO2_5 0x140 0x420 0x000 0x1 0x0
+#define MX50_PAD_DISP_D5__FEC_TX_EN 0x140 0x420 0x000 0x2 0x0
+#define MX50_PAD_DISP_D5__EIM_WEIM_A_21 0x140 0x420 0x000 0x3 0x0
+#define MX50_PAD_DISP_D5__SDMA_DEBUG_PC_5 0x140 0x420 0x000 0x6 0x0
+#define MX50_PAD_DISP_D5__USBPHY1_VSTATUS_5 0x140 0x420 0x000 0x7 0x0
+#define MX50_PAD_DISP_D6__ELCDIF_DAT_6 0x144 0x424 0x714 0x0 0x0
+#define MX50_PAD_DISP_D6__GPIO2_6 0x144 0x424 0x000 0x1 0x0
+#define MX50_PAD_DISP_D6__FEC_TDATA_1 0x144 0x424 0x000 0x2 0x0
+#define MX50_PAD_DISP_D6__EIM_WEIM_A_22 0x144 0x424 0x000 0x3 0x0
+#define MX50_PAD_DISP_D6__FEC_RX_CLK 0x144 0x424 0x780 0x4 0x1
+#define MX50_PAD_DISP_D6__SDMA_DEBUG_PC_6 0x144 0x424 0x000 0x6 0x0
+#define MX50_PAD_DISP_D6__USBPHY1_VSTATUS_6 0x144 0x424 0x000 0x7 0x0
+#define MX50_PAD_DISP_D7__ELCDIF_DAT_7 0x148 0x428 0x718 0x0 0x0
+#define MX50_PAD_DISP_D7__GPIO2_7 0x148 0x428 0x000 0x1 0x0
+#define MX50_PAD_DISP_D7__FEC_TDATA_0 0x148 0x428 0x000 0x2 0x0
+#define MX50_PAD_DISP_D7__EIM_WEIM_A_23 0x148 0x428 0x000 0x3 0x0
+#define MX50_PAD_DISP_D7__SDMA_DEBUG_PC_7 0x148 0x428 0x000 0x6 0x0
+#define MX50_PAD_DISP_D7__USBPHY1_VSTATUS_7 0x148 0x428 0x000 0x7 0x0
+#define MX50_PAD_DISP_WR__ELCDIF_WR_RWN 0x14c 0x42c 0x000 0x0 0x0
+#define MX50_PAD_DISP_WR__GPIO2_16 0x14c 0x42c 0x000 0x1 0x0
+#define MX50_PAD_DISP_WR__ELCDIF_DOTCLK 0x14c 0x42c 0x000 0x2 0x0
+#define MX50_PAD_DISP_WR__EIM_WEIM_A_24 0x14c 0x42c 0x000 0x3 0x0
+#define MX50_PAD_DISP_WR__SDMA_DEBUG_PC_8 0x14c 0x42c 0x000 0x6 0x0
+#define MX50_PAD_DISP_WR__USBPHY1_AVALID 0x14c 0x42c 0x000 0x7 0x0
+#define MX50_PAD_DISP_RD__ELCDIF_RD_E 0x150 0x430 0x000 0x0 0x0
+#define MX50_PAD_DISP_RD__GPIO2_19 0x150 0x430 0x000 0x1 0x0
+#define MX50_PAD_DISP_RD__ELCDIF_ENABLE 0x150 0x430 0x000 0x2 0x0
+#define MX50_PAD_DISP_RD__EIM_WEIM_A_25 0x150 0x430 0x000 0x3 0x0
+#define MX50_PAD_DISP_RD__SDMA_DEBUG_PC_9 0x150 0x430 0x000 0x6 0x0
+#define MX50_PAD_DISP_RD__USBPHY1_BVALID 0x150 0x430 0x000 0x7 0x0
+#define MX50_PAD_DISP_RS__ELCDIF_RS 0x154 0x434 0x000 0x0 0x0
+#define MX50_PAD_DISP_RS__GPIO2_17 0x154 0x434 0x000 0x1 0x0
+#define MX50_PAD_DISP_RS__ELCDIF_VSYNC 0x154 0x434 0x73c 0x2 0x1
+#define MX50_PAD_DISP_RS__EIM_WEIM_A_26 0x154 0x434 0x000 0x3 0x0
+#define MX50_PAD_DISP_RS__SDMA_DEBUG_PC_10 0x154 0x434 0x000 0x6 0x0
+#define MX50_PAD_DISP_RS__USBPHY1_ENDSESSION 0x154 0x434 0x000 0x7 0x0
+#define MX50_PAD_DISP_CS__ELCDIF_CS 0x158 0x438 0x000 0x0 0x0
+#define MX50_PAD_DISP_CS__GPIO2_21 0x158 0x438 0x000 0x1 0x0
+#define MX50_PAD_DISP_CS__ELCDIF_HSYNC 0x158 0x438 0x6f8 0x2 0x1
+#define MX50_PAD_DISP_CS__EIM_WEIM_A_27 0x158 0x438 0x000 0x3 0x0
+#define MX50_PAD_DISP_CS__EIM_WEIM_CS_3 0x158 0x438 0x000 0x4 0x0
+#define MX50_PAD_DISP_CS__SDMA_DEBUG_PC_11 0x158 0x438 0x000 0x6 0x0
+#define MX50_PAD_DISP_CS__USBPHY1_IDDIG 0x158 0x438 0x000 0x7 0x0
+#define MX50_PAD_DISP_BUSY__ELCDIF_BUSY 0x15c 0x43c 0x6f8 0x0 0x2
+#define MX50_PAD_DISP_BUSY__GPIO2_18 0x15c 0x43c 0x000 0x1 0x0
+#define MX50_PAD_DISP_BUSY__EIM_WEIM_CS_3 0x15c 0x43c 0x000 0x4 0x0
+#define MX50_PAD_DISP_BUSY__SDMA_DEBUG_PC_12 0x15c 0x43c 0x000 0x6 0x0
+#define MX50_PAD_DISP_BUSY__USBPHY2_HOSTDISCONNECT 0x15c 0x43c 0x000 0x7 0x0
+#define MX50_PAD_DISP_RESET__ELCDIF_RESET 0x160 0x440 0x000 0x0 0x0
+#define MX50_PAD_DISP_RESET__GPIO2_20 0x160 0x440 0x000 0x1 0x0
+#define MX50_PAD_DISP_RESET__EIM_WEIM_CS_3 0x160 0x440 0x000 0x4 0x0
+#define MX50_PAD_DISP_RESET__SDMA_DEBUG_PC_13 0x160 0x440 0x000 0x6 0x0
+#define MX50_PAD_DISP_RESET__USBPHY2_BISTOK 0x160 0x440 0x000 0x7 0x0
+#define MX50_PAD_SD3_CMD__ESDHC3_CMD 0x164 0x444 0x000 0x0 0x0
+#define MX50_PAD_SD3_CMD__GPIO5_18 0x164 0x444 0x000 0x1 0x0
+#define MX50_PAD_SD3_CMD__EIM_NANDF_WRN 0x164 0x444 0x000 0x2 0x0
+#define MX50_PAD_SD3_CMD__SSP_CMD 0x164 0x444 0x000 0x3 0x0
+#define MX50_PAD_SD3_CLK__ESDHC3_CLK 0x168 0x448 0x000 0x0 0x0
+#define MX50_PAD_SD3_CLK__GPIO5_19 0x168 0x448 0x000 0x1 0x0
+#define MX50_PAD_SD3_CLK__EIM_NANDF_RDN 0x168 0x448 0x000 0x2 0x0
+#define MX50_PAD_SD3_CLK__SSP_CLK 0x168 0x448 0x000 0x3 0x0
+#define MX50_PAD_SD3_D0__ESDHC3_DAT0 0x16c 0x44c 0x000 0x0 0x0
+#define MX50_PAD_SD3_D0__GPIO5_20 0x16c 0x44c 0x000 0x1 0x0
+#define MX50_PAD_SD3_D0__EIM_NANDF_D_4 0x16c 0x44c 0x000 0x2 0x0
+#define MX50_PAD_SD3_D0__SSP_D0 0x16c 0x44c 0x000 0x3 0x0
+#define MX50_PAD_SD3_D0__CCM_PLL1_BYP 0x16c 0x44c 0x6dc 0x7 0x1
+#define MX50_PAD_SD3_D1__ESDHC3_DAT1 0x170 0x450 0x000 0x0 0x0
+#define MX50_PAD_SD3_D1__GPIO5_21 0x170 0x450 0x000 0x1 0x0
+#define MX50_PAD_SD3_D1__EIM_NANDF_D_5 0x170 0x450 0x000 0x2 0x0
+#define MX50_PAD_SD3_D1__SSP_D1 0x170 0x450 0x000 0x3 0x0
+#define MX50_PAD_SD3_D1__CCM_PLL2_BYP 0x170 0x450 0x000 0x7 0x0
+#define MX50_PAD_SD3_D2__ESDHC3_DAT2 0x174 0x454 0x000 0x0 0x0
+#define MX50_PAD_SD3_D2__GPIO5_22 0x174 0x454 0x000 0x1 0x0
+#define MX50_PAD_SD3_D2__EIM_NANDF_D_6 0x174 0x454 0x000 0x2 0x0
+#define MX50_PAD_SD3_D2__SSP_D2 0x174 0x454 0x000 0x3 0x0
+#define MX50_PAD_SD3_D2__CCM_PLL3_BYP 0x174 0x454 0x6e4 0x7 0x1
+#define MX50_PAD_SD3_D3__ESDHC3_DAT3 0x178 0x458 0x000 0x0 0x0
+#define MX50_PAD_SD3_D3__GPIO5_23 0x178 0x458 0x000 0x1 0x0
+#define MX50_PAD_SD3_D3__EIM_NANDF_D_7 0x178 0x458 0x000 0x2 0x0
+#define MX50_PAD_SD3_D3__SSP_D3 0x178 0x458 0x000 0x3 0x0
+#define MX50_PAD_SD3_D4__ESDHC3_DAT4 0x17c 0x45c 0x000 0x0 0x0
+#define MX50_PAD_SD3_D4__GPIO5_24 0x17c 0x45c 0x000 0x1 0x0
+#define MX50_PAD_SD3_D4__EIM_NANDF_D_0 0x17c 0x45c 0x000 0x2 0x0
+#define MX50_PAD_SD3_D4__SSP_D4 0x17c 0x45c 0x000 0x3 0x0
+#define MX50_PAD_SD3_D5__ESDHC3_DAT5 0x180 0x460 0x000 0x0 0x0
+#define MX50_PAD_SD3_D5__GPIO5_25 0x180 0x460 0x000 0x1 0x0
+#define MX50_PAD_SD3_D5__EIM_NANDF_D_1 0x180 0x460 0x000 0x2 0x0
+#define MX50_PAD_SD3_D5__SSP_D5 0x180 0x460 0x000 0x3 0x0
+#define MX50_PAD_SD3_D6__ESDHC3_DAT6 0x184 0x464 0x000 0x0 0x0
+#define MX50_PAD_SD3_D6__GPIO5_26 0x184 0x464 0x000 0x1 0x0
+#define MX50_PAD_SD3_D6__EIM_NANDF_D_2 0x184 0x464 0x000 0x2 0x0
+#define MX50_PAD_SD3_D6__SSP_D6 0x184 0x464 0x000 0x3 0x0
+#define MX50_PAD_SD3_D7__ESDHC3_DAT7 0x188 0x468 0x000 0x0 0x0
+#define MX50_PAD_SD3_D7__GPIO5_27 0x188 0x468 0x000 0x1 0x0
+#define MX50_PAD_SD3_D7__EIM_NANDF_D_3 0x188 0x468 0x000 0x2 0x0
+#define MX50_PAD_SD3_D7__SSP_D7 0x188 0x468 0x000 0x3 0x0
+#define MX50_PAD_SD3_WP__ESDHC3_WP 0x18c 0x46C 0x000 0x0 0x0
+#define MX50_PAD_SD3_WP__GPIO5_28 0x18c 0x46C 0x000 0x1 0x0
+#define MX50_PAD_SD3_WP__EIM_NANDF_RESETN 0x18c 0x46C 0x000 0x2 0x0
+#define MX50_PAD_SD3_WP__SSP_CD 0x18c 0x46C 0x000 0x3 0x0
+#define MX50_PAD_SD3_WP__ESDHC4_LCTL 0x18c 0x46C 0x000 0x4 0x0
+#define MX50_PAD_SD3_WP__EIM_WEIM_CS_3 0x18c 0x46C 0x000 0x5 0x0
+#define MX50_PAD_DISP_D8__ELCDIF_DAT_8 0x190 0x470 0x71c 0x0 0x0
+#define MX50_PAD_DISP_D8__GPIO2_8 0x190 0x470 0x000 0x1 0x0
+#define MX50_PAD_DISP_D8__EIM_NANDF_CLE 0x190 0x470 0x000 0x2 0x0
+#define MX50_PAD_DISP_D8__ESDHC1_LCTL 0x190 0x470 0x000 0x3 0x0
+#define MX50_PAD_DISP_D8__ESDHC4_CMD 0x190 0x470 0x74c 0x4 0x2
+#define MX50_PAD_DISP_D8__KPP_COL_4 0x190 0x470 0x790 0x5 0x1
+#define MX50_PAD_DISP_D8__FEC_TX_CLK 0x190 0x470 0x78c 0x6 0x1
+#define MX50_PAD_DISP_D8__USBPHY1_DATAOUT_0 0x190 0x470 0x000 0x7 0x0
+#define MX50_PAD_DISP_D9__ELCDIF_DAT_9 0x194 0x474 0x720 0x0 0x0
+#define MX50_PAD_DISP_D9__GPIO2_9 0x194 0x474 0x000 0x1 0x0
+#define MX50_PAD_DISP_D9__EIM_NANDF_ALE 0x194 0x474 0x000 0x2 0x0
+#define MX50_PAD_DISP_D9__ESDHC2_LCTL 0x194 0x474 0x000 0x3 0x0
+#define MX50_PAD_DISP_D9__ESDHC4_CLK 0x194 0x474 0x748 0x4 0x2
+#define MX50_PAD_DISP_D9__KPP_ROW_4 0x194 0x474 0x7a0 0x5 0x1
+#define MX50_PAD_DISP_D9__FEC_RX_ER 0x194 0x474 0x788 0x6 0x1
+#define MX50_PAD_DISP_D9__USBPHY1_DATAOUT_1 0x194 0x474 0x000 0x7 0x0
+#define MX50_PAD_DISP_D10__ELCDIF_DAT_10 0x198 0x478 0x724 0x0 0x0
+#define MX50_PAD_DISP_D10__GPIO2_10 0x198 0x478 0x000 0x1 0x0
+#define MX50_PAD_DISP_D10__EIM_NANDF_CEN_0 0x198 0x478 0x000 0x2 0x0
+#define MX50_PAD_DISP_D10__ESDHC3_LCTL 0x198 0x478 0x000 0x3 0x0
+#define MX50_PAD_DISP_D10__ESDHC4_DAT0 0x198 0x478 0x000 0x4 0x0
+#define MX50_PAD_DISP_D10__KPP_COL_5 0x198 0x478 0x794 0x5 0x1
+#define MX50_PAD_DISP_D10__FEC_RX_DV 0x198 0x478 0x784 0x6 0x1
+#define MX50_PAD_DISP_D10__USBPHY1_DATAOUT_2 0x198 0x478 0x000 0x7 0x0
+#define MX50_PAD_DISP_D11__ELCDIF_DAT_11 0x19c 0x47c 0x728 0x0 0x0
+#define MX50_PAD_DISP_D11__GPIO2_11 0x19c 0x47c 0x000 0x1 0x0
+#define MX50_PAD_DISP_D11__EIM_NANDF_CEN_1 0x19c 0x47c 0x000 0x2 0x0
+#define MX50_PAD_DISP_D11__ESDHC4_DAT1 0x19c 0x47c 0x754 0x4 0x1
+#define MX50_PAD_DISP_D11__KPP_ROW_5 0x19c 0x47c 0x7a4 0x5 0x1
+#define MX50_PAD_DISP_D11__FEC_RDATA_1 0x19c 0x47c 0x77c 0x6 0x1
+#define MX50_PAD_DISP_D11__USBPHY1_DATAOUT_3 0x19c 0x47c 0x000 0x7 0x0
+#define MX50_PAD_DISP_D12__ELCDIF_DAT_12 0x1a0 0x480 0x72c 0x0 0x0
+#define MX50_PAD_DISP_D12__GPIO2_12 0x1a0 0x480 0x000 0x1 0x0
+#define MX50_PAD_DISP_D12__EIM_NANDF_CEN_2 0x1a0 0x480 0x000 0x2 0x0
+#define MX50_PAD_DISP_D12__ESDHC1_CD 0x1a0 0x480 0x000 0x3 0x0
+#define MX50_PAD_DISP_D12__ESDHC4_DAT2 0x1a0 0x480 0x758 0x4 0x1
+#define MX50_PAD_DISP_D12__KPP_COL_6 0x1a0 0x480 0x798 0x5 0x1
+#define MX50_PAD_DISP_D12__FEC_RDATA_0 0x1a0 0x480 0x778 0x6 0x1
+#define MX50_PAD_DISP_D12__USBPHY1_DATAOUT_4 0x1a0 0x480 0x000 0x7 0x0
+#define MX50_PAD_DISP_D13__ELCDIF_DAT_13 0x1a4 0x484 0x730 0x0 0x0
+#define MX50_PAD_DISP_D13__GPIO2_13 0x1a4 0x484 0x000 0x1 0x0
+#define MX50_PAD_DISP_D13__EIM_NANDF_CEN_3 0x1a4 0x484 0x000 0x2 0x0
+#define MX50_PAD_DISP_D13__ESDHC3_CD 0x1a4 0x484 0x000 0x3 0x0
+#define MX50_PAD_DISP_D13__ESDHC4_DAT3 0x1a4 0x484 0x75c 0x4 0x1
+#define MX50_PAD_DISP_D13__KPP_ROW_6 0x1a4 0x484 0x7a8 0x5 0x1
+#define MX50_PAD_DISP_D13__FEC_TX_EN 0x1a4 0x484 0x000 0x6 0x0
+#define MX50_PAD_DISP_D13__USBPHY1_DATAOUT_5 0x1a4 0x484 0x000 0x7 0x0
+#define MX50_PAD_DISP_D14__ELCDIF_DAT_14 0x1a8 0x488 0x734 0x0 0x0
+#define MX50_PAD_DISP_D14__GPIO2_14 0x1a8 0x488 0x000 0x1 0x0
+#define MX50_PAD_DISP_D14__EIM_NANDF_READY0 0x1a8 0x488 0x7b4 0x2 0x1
+#define MX50_PAD_DISP_D14__ESDHC1_WP 0x1a8 0x488 0x000 0x3 0x0
+#define MX50_PAD_DISP_D14__ESDHC4_WP 0x1a8 0x488 0x000 0x4 0x0
+#define MX50_PAD_DISP_D14__KPP_COL_7 0x1a8 0x488 0x79c 0x5 0x1
+#define MX50_PAD_DISP_D14__FEC_TDATA_1 0x1a8 0x488 0x000 0x6 0x0
+#define MX50_PAD_DISP_D14__USBPHY1_DATAOUT_6 0x1a8 0x488 0x000 0x7 0x0
+#define MX50_PAD_DISP_D15__ELCDIF_DAT_15 0x1ac 0x48c 0x738 0x0 0x0
+#define MX50_PAD_DISP_D15__GPIO2_15 0x1ac 0x48c 0x000 0x1 0x0
+#define MX50_PAD_DISP_D15__EIM_NANDF_DQS 0x1ac 0x48c 0x7b0 0x2 0x1
+#define MX50_PAD_DISP_D15__ESDHC3_RST 0x1ac 0x48c 0x000 0x3 0x0
+#define MX50_PAD_DISP_D15__ESDHC4_CD 0x1ac 0x48c 0x000 0x4 0x0
+#define MX50_PAD_DISP_D15__KPP_ROW_7 0x1ac 0x48c 0x7ac 0x5 0x1
+#define MX50_PAD_DISP_D15__FEC_TDATA_0 0x1ac 0x48c 0x000 0x6 0x0
+#define MX50_PAD_DISP_D15__USBPHY1_DATAOUT_7 0x1ac 0x48c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D0__EPDC_SDDO_0 0x1b0 0x54c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D0__GPIO3_0 0x1b0 0x54c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D0__EIM_WEIM_D_0 0x1b0 0x54c 0x7ec 0x2 0x1
+#define MX50_PAD_EPDC_D0__ELCDIF_RS 0x1b0 0x54c 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D0__ELCDIF_DOTCLK 0x1b0 0x54c 0x000 0x4 0x0
+#define MX50_PAD_EPDC_D0__SDMA_DEBUG_EVT_CHN_LINES_0 0x1b0 0x54c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D0__USBPHY2_DATAOUT_0 0x1b0 0x54c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D1__EPDC_SDDO_1 0x1b4 0x550 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D1__GPIO3_1 0x1b4 0x550 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D1__EIM_WEIM_D_1 0x1b4 0x550 0x7f0 0x2 0x1
+#define MX50_PAD_EPDC_D1__ELCDIF_CS 0x1b4 0x550 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D1__ELCDIF_ENABLE 0x1b4 0x550 0x000 0x4 0x0
+#define MX50_PAD_EPDC_D1__SDMA_DEBUG_EVT_CHN_LINES_1 0x1b4 0x550 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D1__USBPHY2_DATAOUT_1 0x1b4 0x550 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D2__EPDC_SDDO_2 0x1b8 0x554 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D2__GPIO3_2 0x1b8 0x554 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D2__EIM_WEIM_D_2 0x1b8 0x554 0x7f4 0x2 0x1
+#define MX50_PAD_EPDC_D2__ELCDIF_WR_RWN 0x1b8 0x554 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D2__ELCDIF_VSYNC 0x1b8 0x554 0x73c 0x4 0x2
+#define MX50_PAD_EPDC_D2__SDMA_DEBUG_EVT_CHN_LINES_2 0x1b8 0x554 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D2__USBPHY2_DATAOUT_2 0x1b8 0x554 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D3__EPDC_SDDO_3 0x1bc 0x558 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D3__GPIO3_3 0x1bc 0x558 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D3__EIM_WEIM_D_3 0x1bc 0x558 0x7f8 0x2 0x1
+#define MX50_PAD_EPDC_D3__ELCDIF_RD_E 0x1bc 0x558 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D3__ELCDIF_HSYNC 0x1bc 0x558 0x6f8 0x4 0x3
+#define MX50_PAD_EPDC_D3__SDMA_DEBUG_EVT_CHN_LINES_3 0x1bc 0x558 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D3__USBPHY2_DATAOUT_3 0x1bc 0x558 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D4__EPDC_SDDO_4 0x1c0 0x55c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D4__GPIO3_4 0x1c0 0x55c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D4__EIM_WEIM_D_4 0x1c0 0x55c 0x7fc 0x2 0x1
+#define MX50_PAD_EPDC_D4__SDMA_DEBUG_EVT_CHN_LINES_4 0x1c0 0x55c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D4__USBPHY2_DATAOUT_4 0x1c0 0x55c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D5__EPDC_SDDO_5 0x1c4 0x560 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D5__GPIO3_5 0x1c4 0x560 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D5__EIM_WEIM_D_5 0x1c4 0x560 0x800 0x2 0x1
+#define MX50_PAD_EPDC_D5__SDMA_DEBUG_EVT_CHN_LINES_5 0x1c4 0x560 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D5__USBPHY2_DATAOUT_5 0x1c4 0x560 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D6__EPDC_SDDO_6 0x1c8 0x564 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D6__GPIO3_6 0x1c8 0x564 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D6__EIM_WEIM_D_6 0x1c8 0x564 0x804 0x2 0x1
+#define MX50_PAD_EPDC_D6__SDMA_DEBUG_EVT_CHN_LINES_6 0x1c8 0x564 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D6__USBPHY2_DATAOUT_6 0x1c8 0x564 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D7__EPDC_SDDO_7 0x1cc 0x568 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D7__GPIO3_7 0x1cc 0x568 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D7__EIM_WEIM_D_7 0x1cc 0x568 0x808 0x2 0x1
+#define MX50_PAD_EPDC_D7__SDMA_DEBUG_EVT_CHN_LINES_7 0x1cc 0x568 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D7__USBPHY2_DATAOUT_7 0x1cc 0x568 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D8__EPDC_SDDO_8 0x1d0 0x56c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D8__GPIO3_8 0x1d0 0x56c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D8__EIM_WEIM_D_8 0x1d0 0x56c 0x80c 0x2 0x2
+#define MX50_PAD_EPDC_D8__ELCDIF_DAT_24 0x1d0 0x56c 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D8__SDMA_DEBUG_MATCHED_DMBUS 0x1d0 0x56c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D8__USBPHY2_VSTATUS_0 0x1d0 0x56c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D9__EPDC_SDDO_9 0x1d4 0x570 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D9__GPIO3_9 0x1d4 0x570 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D9__EIM_WEIM_D_9 0x1d4 0x570 0x810 0x2 0x2
+#define MX50_PAD_EPDC_D9__ELCDIF_DAT_25 0x1d4 0x570 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D9__SDMA_DEBUG_EVENT_CHANNEL_SEL 0x1d4 0x570 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D9__USBPHY2_VSTATUS_1 0x1d4 0x570 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D10__EPDC_SDDO_10 0x1d8 0x574 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D10__GPIO3_10 0x1d8 0x574 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D10__EIM_WEIM_D_10 0x1d8 0x574 0x814 0x2 0x2
+#define MX50_PAD_EPDC_D10__ELCDIF_DAT_26 0x1d8 0x574 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D10__SDMA_DEBUG_EVENT_CHANNEL_0 0x1d8 0x574 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D10__USBPHY2_VSTATUS_2 0x1d8 0x574 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D11__EPDC_SDDO_11 0x1dc 0x578 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D11__GPIO3_11 0x1dc 0x578 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D11__EIM_WEIM_D_11 0x1dc 0x578 0x818 0x2 0x2
+#define MX50_PAD_EPDC_D11__ELCDIF_DAT_27 0x1dc 0x578 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D11__SDMA_DEBUG_EVENT_CHANNEL_1 0x1dc 0x578 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D11__USBPHY2_VSTATUS_3 0x1dc 0x578 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D12__EPDC_SDDO_12 0x1e0 0x57c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D12__GPIO3_12 0x1e0 0x57c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D12__EIM_WEIM_D_12 0x1e0 0x57c 0x81c 0x2 0x1
+#define MX50_PAD_EPDC_D12__ELCDIF_DAT_28 0x1e0 0x57c 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D12__SDMA_DEBUG_EVENT_CHANNEL_2 0x1e0 0x57c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D12__USBPHY2_VSTATUS_4 0x1e0 0x57c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D13__EPDC_SDDO_13 0x1e4 0x580 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D13__GPIO3_13 0x1e4 0x580 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D13__EIM_WEIM_D_13 0x1e4 0x580 0x820 0x2 0x1
+#define MX50_PAD_EPDC_D13__ELCDIF_DAT_29 0x1e4 0x580 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D13__SDMA_DEBUG_EVENT_CHANNEL_3 0x1e4 0x580 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D13__USBPHY2_VSTATUS_5 0x1e4 0x580 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D14__EPDC_SDDO_14 0x1e8 0x584 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D14__GPIO3_14 0x1e8 0x584 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D14__EIM_WEIM_D_14 0x1e8 0x584 0x824 0x2 0x1
+#define MX50_PAD_EPDC_D14__ELCDIF_DAT_30 0x1e8 0x584 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D14__AUDMUX_AUD6_TXD 0x1e8 0x584 0x000 0x4 0x0
+#define MX50_PAD_EPDC_D14__SDMA_DEBUG_EVENT_CHANNEL_4 0x1e8 0x584 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D14__USBPHY2_VSTATUS_6 0x1e8 0x584 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D15__EPDC_SDDO_15 0x1ec 0x588 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D15__GPIO3_15 0x1ec 0x588 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D15__EIM_WEIM_D_15 0x1ec 0x588 0x828 0x2 0x1
+#define MX50_PAD_EPDC_D15__ELCDIF_DAT_31 0x1ec 0x588 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D15__AUDMUX_AUD6_TXC 0x1ec 0x588 0x000 0x4 0x0
+#define MX50_PAD_EPDC_D15__SDMA_DEBUG_EVENT_CHANNEL_5 0x1ec 0x588 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D15__USBPHY2_VSTATUS_7 0x1ec 0x588 0x000 0x7 0x0
+#define MX50_PAD_EPDC_GDCLK__EPDC_GDCLK 0x1f0 0x58c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_GDCLK__GPIO3_16 0x1f0 0x58c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_GDCLK__EIM_WEIM_D_16 0x1f0 0x58c 0x000 0x2 0x0
+#define MX50_PAD_EPDC_GDCLK__ELCDIF_DAT_16 0x1f0 0x58c 0x000 0x3 0x0
+#define MX50_PAD_EPDC_GDCLK__AUDMUX_AUD6_TXFS 0x1f0 0x58c 0x000 0x4 0x0
+#define MX50_PAD_EPDC_GDCLK__SDMA_DEBUG_CORE_STATE_0 0x1f0 0x58c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_GDCLK__USBPHY2_BISTOK 0x1f0 0x58c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_GDSP__EPCD_GDSP 0x1f4 0x590 0x000 0x0 0x0
+#define MX50_PAD_EPDC_GDSP__GPIO3_17 0x1f4 0x590 0x000 0x1 0x0
+#define MX50_PAD_EPDC_GDSP__EIM_WEIM_D_17 0x1f4 0x590 0x000 0x2 0x0
+#define MX50_PAD_EPDC_GDSP__ELCDIF_DAT_17 0x1f4 0x590 0x000 0x3 0x0
+#define MX50_PAD_EPDC_GDSP__AUDMUX_AUD6_RXD 0x1f4 0x590 0x000 0x4 0x0
+#define MX50_PAD_EPDC_GDSP__SDMA_DEBUG_CORE_STATE_1 0x1f4 0x590 0x000 0x6 0x0
+#define MX50_PAD_EPDC_GDSP__USBPHY2_BVALID 0x1f4 0x590 0x000 0x7 0x0
+#define MX50_PAD_EPDC_GDOE__EPCD_GDOE 0x1f8 0x594 0x000 0x0 0x0
+#define MX50_PAD_EPDC_GDOE__GPIO3_18 0x1f8 0x594 0x000 0x1 0x0
+#define MX50_PAD_EPDC_GDOE__EIM_WEIM_D_18 0x1f8 0x594 0x000 0x2 0x0
+#define MX50_PAD_EPDC_GDOE__ELCDIF_DAT_18 0x1f8 0x594 0x000 0x3 0x0
+#define MX50_PAD_EPDC_GDOE__AUDMUX_AUD6_RXC 0x1f8 0x594 0x000 0x4 0x0
+#define MX50_PAD_EPDC_GDOE__SDMA_DEBUG_CORE_STATE_2 0x1f8 0x594 0x000 0x6 0x0
+#define MX50_PAD_EPDC_GDOE__USBPHY2_ENDSESSION 0x1f8 0x594 0x000 0x7 0x0
+#define MX50_PAD_EPDC_GDRL__EPCD_GDRL 0x1fc 0x598 0x000 0x0 0x0
+#define MX50_PAD_EPDC_GDRL__GPIO3_19 0x1fc 0x598 0x000 0x1 0x0
+#define MX50_PAD_EPDC_GDRL__EIM_WEIM_D_19 0x1f8 0x598 0x000 0x2 0x0
+#define MX50_PAD_EPDC_GDRL__ELCDIF_DAT_19 0x1fc 0x598 0x000 0x3 0x0
+#define MX50_PAD_EPDC_GDRL__AUDMUX_AUD6_RXFS 0x1fc 0x598 0x000 0x4 0x0
+#define MX50_PAD_EPDC_GDRL__SDMA_DEBUG_CORE_STATE_3 0x1fc 0x598 0x000 0x6 0x0
+#define MX50_PAD_EPDC_GDRL__USBPHY2_IDDIG 0x1fc 0x598 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDCLK__EPCD_SDCLK 0x200 0x59c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCLK__GPIO3_20 0x200 0x59c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCLK__EIM_WEIM_D_20 0x200 0x59c 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDCLK__ELCDIF_DAT_20 0x200 0x59c 0x000 0x3 0x0
+#define MX50_PAD_EPDC_SDCLK__AUDMUX_AUD5_TXD 0x200 0x59c 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDCLK__SDMA_DEBUG_BUS_DEVICE_0 0x200 0x59c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDCLK__USBPHY2_HOSTDISCONNECT 0x200 0x59c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDOEZ__EPCD_SDOEZ 0x204 0x5a0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDOEZ__GPIO3_21 0x204 0x5a0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDOEZ__EIM_WEIM_D_21 0x204 0x5a0 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDOEZ__ELCDIF_DAT_21 0x204 0x5a0 0x000 0x3 0x0
+#define MX50_PAD_EPDC_SDOEZ__AUDMUX_AUD5_TXC 0x204 0x5a0 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDOEZ__SDMA_DEBUG_BUS_DEVICE_1 0x204 0x5a0 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDOEZ__USBPHY2_TXREADY 0x204 0x5a0 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDOED__EPCD_SDOED 0x208 0x5a4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDOED__GPIO3_22 0x208 0x5a4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDOED__EIM_WEIM_D_22 0x208 0x5a4 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDOED__ELCDIF_DAT_22 0x208 0x5a4 0x000 0x3 0x0
+#define MX50_PAD_EPDC_SDOED__AUDMUX_AUD5_TXFS 0x208 0x5a4 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDOED__SDMA_DEBUG_BUS_DEVICE_2 0x208 0x5a4 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDOED__USBPHY2_RXVALID 0x208 0x5a4 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDOE__EPCD_SDOE 0x20c 0x5a8 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDOE__GPIO3_23 0x20c 0x5a8 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDOE__EIM_WEIM_D_23 0x20c 0x5a8 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDOE__ELCDIF_DAT_23 0x20c 0x5a8 0x000 0x3 0x0
+#define MX50_PAD_EPDC_SDOE__AUDMUX_AUD5_RXD 0x20c 0x5a8 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDOE__SDMA_DEBUG_BUS_DEVICE_3 0x20c 0x5a8 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDOE__USBPHY2_RXACTIVE 0x20c 0x5a8 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDLE__EPCD_SDLE 0x210 0x5ac 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDLE__GPIO3_24 0x210 0x5ac 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDLE__EIM_WEIM_D_24 0x210 0x5ac 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDLE__ELCDIF_DAT_8 0x210 0x5ac 0x71c 0x3 0x1
+#define MX50_PAD_EPDC_SDLE__AUDMUX_AUD5_RXC 0x210 0x5ac 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDLE__SDMA_DEBUG_BUS_DEVICE_4 0x210 0x5ac 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDLE__USBPHY2_RXERROR 0x210 0x5ac 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDCLKN__EPCD_SDCLKN 0x214 0x5b0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCLKN__GPIO3_25 0x214 0x5b0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCLKN__EIM_WEIM_D_25 0x214 0x5b0 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDCLKN__ELCDIF_DAT_9 0x214 0x5b0 0x720 0x3 0x1
+#define MX50_PAD_EPDC_SDCLKN__AUDMUX_AUD5_RXFS 0x214 0x5b0 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDCLKN__SDMA_DEBUG_BUS_ERROR 0x214 0x5b0 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDCLKN__USBPHY2_SIECLOCK 0x214 0x5b0 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDSHR__EPCD_SDSHR 0x218 0x5b4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDSHR__GPIO3_26 0x218 0x5b4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDSHR__EIM_WEIM_D_26 0x218 0x5b4 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDSHR__ELCDIF_DAT_10 0x218 0x5b4 0x724 0x3 0x1
+#define MX50_PAD_EPDC_SDSHR__AUDMUX_AUD4_TXD 0x218 0x5b4 0x6c8 0x4 0x1
+#define MX50_PAD_EPDC_SDSHR__SDMA_DEBUG_BUS_RWB 0x218 0x5b4 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDSHR__USBPHY2_LINESTATE_0 0x218 0x5b4 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRCOM__EPCD_PWRCOM 0x21c 0x5b8 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRCOM__GPIO3_27 0x21c 0x5b8 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRCOM__EIM_WEIM_D_27 0x21c 0x5b8 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRCOM__ELCDIF_DAT_11 0x21c 0x5b8 0x728 0x3 0x1
+#define MX50_PAD_EPDC_PWRCOM__AUDMUX_AUD4_TXC 0x21c 0x5b8 0x6d4 0x4 0x1
+#define MX50_PAD_EPDC_PWRCOM__SDMA_DEBUG_CORE_RUN 0x21c 0x5b8 0x000 0x6 0x0
+#define MX50_PAD_EPDC_PWRCOM__USBPHY2_LINESTATE_1 0x21c 0x5b8 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRSTAT__EPCD_PWRSTAT 0x220 0x5bc 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRSTAT__GPIO3_28 0x220 0x5bc 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRSTAT__EIM_WEIM_D_28 0x220 0x5bc 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRSTAT__ELCDIF_DAT_12 0x220 0x5bc 0x72c 0x3 0x1
+#define MX50_PAD_EPDC_PWRSTAT__AUDMUX_AUD4_TXFS 0x220 0x5bc 0x6d8 0x4 0x1
+#define MX50_PAD_EPDC_PWRSTAT__SDMA_DEBUG_MODE 0x220 0x5bc 0x000 0x6 0x0
+#define MX50_PAD_EPDC_PWRSTAT__USBPHY2_VBUSVALID 0x220 0x5bc 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRCTRL0__EPCD_PWRCTRL0 0x224 0x5c0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRCTRL0__GPIO3_29 0x224 0x5c0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRCTRL0__EIM_WEIM_D_29 0x224 0x5c0 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRCTRL0__ELCDIF_DAT_13 0x224 0x5c0 0x730 0x3 0x1
+#define MX50_PAD_EPDC_PWRCTRL0__AUDMUX_AUD4_RXD 0x224 0x5c0 0x6c4 0x4 0x1
+#define MX50_PAD_EPDC_PWRCTRL0__SDMA_DEBUG_RTBUFFER_WRITE 0x224 0x5c0 0x000 0x6 0x0
+#define MX50_PAD_EPDC_PWRCTRL0__USBPHY2_AVALID 0x224 0x5c0 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRCTRL1__EPCD_PWRCTRL1 0x228 0x5c4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRCTRL1__GPIO3_30 0x228 0x5c4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRCTRL1__EIM_WEIM_D_30 0x228 0x5c4 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRCTRL1__ELCDIF_DAT_14 0x228 0x5c4 0x734 0x3 0x1
+#define MX50_PAD_EPDC_PWRCTRL1__AUDMUX_AUD4_RXC 0x228 0x5c4 0x6cc 0x4 0x1
+#define MX50_PAD_EPDC_PWRCTRL1__SDMA_DEBUG_YIELD 0x228 0x5c4 0x000 0x6 0x0
+#define MX50_PAD_EPDC_PWRCTRL1__USBPHY1_ONBIST 0x228 0x5c4 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRCTRL2__EPCD_PWRCTRL2 0x22c 0x5c8 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRCTRL2__GPIO3_31 0x22c 0x5c8 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRCTRL2__EIM_WEIM_D_31 0x22c 0x5c8 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRCTRL2__ELCDIF_DAT_15 0x22c 0x5c8 0x738 0x3 0x1
+#define MX50_PAD_EPDC_PWRCTRL2__AUDMUX_AUD4_RXFS 0x22c 0x5c8 0x6d0 0x4 0x1
+#define MX50_PAD_EPDC_PWRCTRL2__SDMA_EXT_EVENT_0 0x22c 0x5c8 0x7b8 0x6 0x1
+#define MX50_PAD_EPDC_PWRCTRL2__USBPHY2_ONBIST 0x22c 0x5c8 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRCTRL3__EPCD_PWRCTRL3 0x230 0x5cc 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRCTRL3__GPIO4_20 0x230 0x5cc 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRCTRL3__EIM_WEIM_EB_2 0x230 0x5cc 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRCTRL3__SDMA_EXT_EVENT_1 0x230 0x5cc 0x7bc 0x6 0x1
+#define MX50_PAD_EPDC_PWRCTRL3__USBPHY1_BISTOK 0x230 0x5cc 0x000 0x7 0x0
+#define MX50_PAD_EPDC_VCOM0__EPCD_VCOM_0 0x234 0x5d0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_VCOM0__GPIO4_21 0x234 0x5d0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_VCOM0__EIM_WEIM_EB_3 0x234 0x5d0 0x000 0x2 0x0
+#define MX50_PAD_EPDC_VCOM0__USBPHY2_BISTOK 0x234 0x5d0 0x000 0x7 0x0
+#define MX50_PAD_EPDC_VCOM1__EPCD_VCOM_1 0x238 0x5d4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_VCOM1__GPIO4_22 0x238 0x5d4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_VCOM1__EIM_WEIM_CS_3 0x238 0x5d4 0x000 0x2 0x0
+#define MX50_PAD_EPDC_BDR0__EPCD_BDR_0 0x23c 0x5d8 0x000 0x0 0x0
+#define MX50_PAD_EPDC_BDR0__GPIO4_23 0x23c 0x5d8 0x000 0x1 0x0
+#define MX50_PAD_EPDC_BDR0__ELCDIF_DAT_7 0x23c 0x5d8 0x718 0x3 0x1
+#define MX50_PAD_EPDC_BDR1__EPCD_BDR_1 0x240 0x5dc 0x000 0x0 0x0
+#define MX50_PAD_EPDC_BDR1__GPIO4_24 0x240 0x5dc 0x000 0x1 0x0
+#define MX50_PAD_EPDC_BDR1__ELCDIF_DAT_6 0x240 0x5dc 0x714 0x3 0x1
+#define MX50_PAD_EPDC_SDCE0__EPCD_SDCE_0 0x244 0x5e0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE0__GPIO4_25 0x244 0x5e0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE0__ELCDIF_DAT_5 0x244 0x5e0 0x710 0x3 0x1
+#define MX50_PAD_EPDC_SDCE1__EPCD_SDCE_1 0x248 0x5e4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE1__GPIO4_26 0x248 0x5e4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE1__ELCDIF_DAT_4 0x248 0x5e4 0x70c 0x3 0x0
+#define MX50_PAD_EPDC_SDCE2__EPCD_SDCE_2 0x24c 0x5e8 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE2__GPIO4_27 0x24c 0x5e8 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE2__ELCDIF_DAT_3 0x24c 0x5e8 0x708 0x3 0x1
+#define MX50_PAD_EPDC_SDCE3__EPCD_SDCE_3 0x250 0x5ec 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE3__GPIO4_28 0x250 0x5ec 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE3__ELCDIF_DAT_2 0x250 0x5ec 0x704 0x3 0x1
+#define MX50_PAD_EPDC_SDCE4__EPCD_SDCE_4 0x254 0x5f0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE4__GPIO4_29 0x254 0x5f0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE4__ELCDIF_DAT_1 0x254 0x5f0 0x700 0x3 0x1
+#define MX50_PAD_EPDC_SDCE5__EPCD_SDCE_5 0x258 0x5f4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE5__GPIO4_30 0x258 0x5f4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE5__ELCDIF_DAT_0 0x258 0x5f4 0x6fc 0x3 0x1
+#define MX50_PAD_EIM_DA0__EIM_WEIM_A_0 0x25c 0x5f8 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA0__GPIO1_0 0x25c 0x5f8 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA0__KPP_COL_4 0x25c 0x5f8 0x790 0x3 0x2
+#define MX50_PAD_EIM_DA0__TPIU_TRACE_0 0x25c 0x5f8 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA0__SRC_BT_CFG1_0 0x25c 0x5f8 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA1__EIM_WEIM_A_1 0x260 0x5fc 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA1__GPIO1_1 0x260 0x5fc 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA1__KPP_ROW_4 0x260 0x5fc 0x7a0 0x3 0x2
+#define MX50_PAD_EIM_DA1__TPIU_TRACE_1 0x260 0x5fc 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA1__SRC_BT_CFG1_1 0x260 0x5fc 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA2__EIM_WEIM_A_2 0x264 0x600 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA2__GPIO1_2 0x264 0x600 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA2__KPP_COL_5 0x264 0x600 0x794 0x3 0x2
+#define MX50_PAD_EIM_DA2__TPIU_TRACE_2 0x264 0x600 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA2__SRC_BT_CFG1_2 0x264 0x600 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA3__EIM_WEIM_A_3 0x268 0x604 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA3__GPIO1_3 0x268 0x604 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA3__KPP_ROW_5 0x268 0x604 0x7a4 0x3 0x2
+#define MX50_PAD_EIM_DA3__TPIU_TRACE_3 0x268 0x604 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA3__SRC_BT_CFG1_3 0x268 0x604 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA4__EIM_WEIM_A_4 0x26c 0x608 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA4__GPIO1_4 0x26c 0x608 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA4__KPP_COL_6 0x26c 0x608 0x798 0x3 0x2
+#define MX50_PAD_EIM_DA4__TPIU_TRACE_4 0x26c 0x608 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA4__SRC_BT_CFG1_4 0x26c 0x608 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA5__EIM_WEIM_A_5 0x270 0x60c 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA5__GPIO1_5 0x270 0x60c 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA5__KPP_ROW_6 0x270 0x60c 0x7a8 0x3 0x2
+#define MX50_PAD_EIM_DA5__TPIU_TRACE_5 0x270 0x60c 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA5__SRC_BT_CFG1_5 0x270 0x60c 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA6__EIM_WEIM_A_6 0x274 0x610 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA6__GPIO1_6 0x274 0x610 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA6__KPP_COL_7 0x274 0x610 0x79c 0x3 0x2
+#define MX50_PAD_EIM_DA6__TPIU_TRACE_6 0x274 0x610 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA6__SRC_BT_CFG1_6 0x274 0x610 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA7__EIM_WEIM_A_7 0x278 0x614 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA7__GPIO1_7 0x278 0x614 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA7__KPP_ROW_7 0x278 0x614 0x7ac 0x3 0x2
+#define MX50_PAD_EIM_DA7__TPIU_TRACE_7 0x278 0x614 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA7__SRC_BT_CFG1_7 0x278 0x614 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA8__EIM_WEIM_A_8 0x27c 0x618 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA8__GPIO1_8 0x27c 0x618 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA8__EIM_NANDF_CLE 0x27c 0x618 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA8__TPIU_TRACE_8 0x27c 0x618 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA8__SRC_BT_CFG2_0 0x27c 0x618 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA9__EIM_WEIM_A_9 0x280 0x61c 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA9__GPIO1_9 0x280 0x61c 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA9__EIM_NANDF_ALE 0x280 0x61c 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA9__TPIU_TRACE_9 0x280 0x61c 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA9__SRC_BT_CFG2_1 0x280 0x61c 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA10__EIM_WEIM_A_10 0x284 0x620 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA10__GPIO1_10 0x284 0x620 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA10__EIM_NANDF_CEN_0 0x284 0x620 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA10__TPIU_TRACE_10 0x284 0x620 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA10__SRC_BT_CFG2_2 0x284 0x620 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA11__EIM_WEIM_A_11 0x288 0x624 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA11__GPIO1_11 0x288 0x624 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA11__EIM_NANDF_CEN_1 0x288 0x624 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA11__TPIU_TRACE_11 0x288 0x624 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA11__SRC_BT_CFG2_3 0x288 0x624 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA12__EIM_WEIM_A_12 0x28c 0x628 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA12__GPIO1_12 0x28c 0x628 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA12__EIM_NANDF_CEN_2 0x28c 0x628 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA12__EPDC_SDCE_6 0x28c 0x628 0x000 0x3 0x0
+#define MX50_PAD_EIM_DA12__TPIU_TRACE_12 0x28c 0x628 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA12__SRC_BT_CFG2_4 0x28c 0x628 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA13__EIM_WEIM_A_13 0x290 0x62c 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA13__GPIO1_13 0x290 0x62c 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA13__EIM_NANDF_CEN_3 0x290 0x62c 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA13__EPDC_SDCE_7 0x290 0x62c 0x000 0x3 0x0
+#define MX50_PAD_EIM_DA13__TPIU_TRACE_13 0x290 0x62c 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA13__SRC_BT_CFG2_5 0x290 0x62c 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA14__EIM_WEIM_A_14 0x294 0x630 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA14__GPIO1_14 0x294 0x630 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA14__EIM_NANDF_READY0 0x294 0x630 0x7b4 0x2 0x2
+#define MX50_PAD_EIM_DA14__EPDC_SDCE_8 0x294 0x630 0x000 0x3 0x0
+#define MX50_PAD_EIM_DA14__TPIU_TRACE_14 0x294 0x630 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA14__SRC_BT_CFG2_6 0x294 0x630 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA15__EIM_WEIM_A_15 0x298 0x634 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA15__GPIO1_15 0x298 0x634 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA15__EIM_NANDF_DQS 0x298 0x634 0x7b0 0x2 0x2
+#define MX50_PAD_EIM_DA15__EPDC_SDCE_9 0x298 0x634 0x000 0x3 0x0
+#define MX50_PAD_EIM_DA15__TPIU_TRACE_15 0x298 0x634 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA15__SRC_BT_CFG2_7 0x298 0x634 0x000 0x7 0x0
+#define MX50_PAD_EIM_CS2__EIM_WEIM_CS_2 0x29c 0x638 0x000 0x0 0x0
+#define MX50_PAD_EIM_CS2__GPIO1_16 0x29c 0x638 0x000 0x1 0x0
+#define MX50_PAD_EIM_CS2__EIM_WEIM_A_27 0x29c 0x638 0x000 0x2 0x0
+#define MX50_PAD_EIM_CS2__TPIU_TRCLK 0x29c 0x638 0x000 0x6 0x0
+#define MX50_PAD_EIM_CS2__SRC_BT_CFG3_0 0x29c 0x638 0x000 0x7 0x0
+#define MX50_PAD_EIM_CS1__EIM_WEIM_CS_1 0x2a0 0x63c 0x000 0x0 0x0
+#define MX50_PAD_EIM_CS1__GPIO1_17 0x2a0 0x63c 0x000 0x1 0x0
+#define MX50_PAD_EIM_CS1__TPIU_TRCTL 0x2a0 0x63c 0x000 0x6 0x0
+#define MX50_PAD_EIM_CS1__SRC_BT_CFG3_1 0x2a0 0x63c 0x000 0x7 0x0
+#define MX50_PAD_EIM_CS0__EIM_WEIM_CS_0 0x2a4 0x640 0x000 0x0 0x0
+#define MX50_PAD_EIM_CS0__GPIO1_18 0x2a4 0x640 0x000 0x1 0x0
+#define MX50_PAD_EIM_CS0__SRC_BT_CFG3_2 0x2a4 0x640 0x000 0x7 0x0
+#define MX50_PAD_EIM_EB0__EIM_WEIM_EB_0 0x2a8 0x644 0x000 0x0 0x0
+#define MX50_PAD_EIM_EB0__GPIO1_19 0x2a8 0x644 0x000 0x1 0x0
+#define MX50_PAD_EIM_EB0__SRC_BT_CFG3_3 0x2a8 0x644 0x000 0x7 0x0
+#define MX50_PAD_EIM_EB1__EIM_WEIM_EB_1 0x2ac 0x648 0x000 0x0 0x0
+#define MX50_PAD_EIM_EB1__GPIO1_20 0x2ac 0x648 0x000 0x1 0x0
+#define MX50_PAD_EIM_EB1__SRC_BT_CFG3_4 0x2ac 0x648 0x000 0x7 0x0
+#define MX50_PAD_EIM_WAIT__EIM_WEIM_WAIT 0x2b0 0x64c 0x000 0x0 0x0
+#define MX50_PAD_EIM_WAIT__GPIO1_21 0x2b0 0x64c 0x000 0x1 0x0
+#define MX50_PAD_EIM_WAIT__EIM_WEIM_DTACK_B 0x2b0 0x64c 0x000 0x2 0x0
+#define MX50_PAD_EIM_WAIT__SRC_BT_CFG3_5 0x2b0 0x64c 0x000 0x7 0x0
+#define MX50_PAD_EIM_BCLK__EIM_WEIM_BCLK 0x2b4 0x650 0x000 0x0 0x0
+#define MX50_PAD_EIM_BCLK__GPIO1_22 0x2b4 0x650 0x000 0x1 0x0
+#define MX50_PAD_EIM_BCLK__SRC_BT_CFG3_6 0x2b4 0x650 0x000 0x7 0x0
+#define MX50_PAD_EIM_RDY__EIM_WEIM_RDY 0x2b8 0x654 0x000 0x0 0x0
+#define MX50_PAD_EIM_RDY__GPIO1_23 0x2b8 0x654 0x000 0x1 0x0
+#define MX50_PAD_EIM_RDY__SRC_BT_CFG3_7 0x2b8 0x654 0x000 0x7 0x0
+#define MX50_PAD_EIM_OE__EIM_WEIM_OE 0x2bc 0x658 0x000 0x0 0x0
+#define MX50_PAD_EIM_OE__GPIO1_24 0x2bc 0x658 0x000 0x1 0x0
+#define MX50_PAD_EIM_OE__INT_BOOT 0x2bc 0x658 0x000 0x7 0x0
+#define MX50_PAD_EIM_RW__EIM_WEIM_RW 0x2c0 0x65c 0x000 0x0 0x0
+#define MX50_PAD_EIM_RW__GPIO1_25 0x2c0 0x65c 0x000 0x1 0x0
+#define MX50_PAD_EIM_RW__SYSTEM_RST 0x2c0 0x65c 0x000 0x7 0x0
+#define MX50_PAD_EIM_LBA__EIM_WEIM_LBA 0x2c4 0x660 0x000 0x0 0x0
+#define MX50_PAD_EIM_LBA__GPIO1_26 0x2c4 0x660 0x000 0x1 0x0
+#define MX50_PAD_EIM_LBA__TESTER_ACK 0x2c4 0x660 0x000 0x7 0x0
+#define MX50_PAD_EIM_CRE__EIM_WEIM_CRE 0x2c8 0x664 0x000 0x0 0x0
+#define MX50_PAD_EIM_CRE__GPIO1_27 0x2c8 0x664 0x000 0x1 0x0
+
+#endif /* __DTS_IMX50_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx50.dtsi b/arch/arm/boot/dts/imx50.dtsi
new file mode 100644
index 000000000..527f01c4f
--- /dev/null
+++ b/arch/arm/boot/dts/imx50.dtsi
@@ -0,0 +1,492 @@
+/*
+ * Copyright 2013 Greg Ungerer <gerg@uclinux.org>
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 "skeleton.dtsi"
+#include "imx50-pinfunc.h"
+#include <dt-bindings/clock/imx5-clock.h>
+
+/ {
+ aliases {
+ ethernet0 = &fec;
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ gpio4 = &gpio5;
+ gpio5 = &gpio6;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a8";
+ reg = <0x0>;
+ };
+ };
+
+ tzic: tz-interrupt-controller@0fffc000 {
+ compatible = "fsl,imx50-tzic", "fsl,imx53-tzic", "fsl,tzic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x0fffc000 0x4000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ckil {
+ compatible = "fsl,imx-ckil", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+
+ ckih1 {
+ compatible = "fsl,imx-ckih1", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <22579200>;
+ };
+
+ ckih2 {
+ compatible = "fsl,imx-ckih2", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ osc {
+ compatible = "fsl,imx-osc", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&tzic>;
+ ranges;
+
+ aips@50000000 { /* AIPS1 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x50000000 0x10000000>;
+ ranges;
+
+ spba@50000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x50000000 0x40000>;
+ ranges;
+
+ esdhc1: esdhc@50004000 {
+ compatible = "fsl,imx50-esdhc";
+ reg = <0x50004000 0x4000>;
+ interrupts = <1>;
+ clocks = <&clks IMX5_CLK_ESDHC1_IPG_GATE>,
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC1_PER_GATE>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ esdhc2: esdhc@50008000 {
+ compatible = "fsl,imx50-esdhc";
+ reg = <0x50008000 0x4000>;
+ interrupts = <2>;
+ clocks = <&clks IMX5_CLK_ESDHC2_IPG_GATE>,
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC2_PER_GATE>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ uart3: serial@5000c000 {
+ compatible = "fsl,imx50-uart", "fsl,imx21-uart";
+ reg = <0x5000c000 0x4000>;
+ interrupts = <33>;
+ clocks = <&clks IMX5_CLK_UART3_IPG_GATE>,
+ <&clks IMX5_CLK_UART3_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi1: ecspi@50010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx50-ecspi", "fsl,imx51-ecspi";
+ reg = <0x50010000 0x4000>;
+ interrupts = <36>;
+ clocks = <&clks IMX5_CLK_ECSPI1_IPG_GATE>,
+ <&clks IMX5_CLK_ECSPI1_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ssi2: ssi@50014000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx50-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
+ reg = <0x50014000 0x4000>;
+ interrupts = <30>;
+ clocks = <&clks IMX5_CLK_SSI2_IPG_GATE>;
+ dmas = <&sdma 24 1 0>,
+ <&sdma 25 1 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ esdhc3: esdhc@50020000 {
+ compatible = "fsl,imx50-esdhc";
+ reg = <0x50020000 0x4000>;
+ interrupts = <3>;
+ clocks = <&clks IMX5_CLK_ESDHC3_IPG_GATE>,
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC3_PER_GATE>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ esdhc4: esdhc@50024000 {
+ compatible = "fsl,imx50-esdhc";
+ reg = <0x50024000 0x4000>;
+ interrupts = <4>;
+ clocks = <&clks IMX5_CLK_ESDHC4_IPG_GATE>,
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC4_PER_GATE>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+ };
+
+ usbotg: usb@53f80000 {
+ compatible = "fsl,imx50-usb", "fsl,imx27-usb";
+ reg = <0x53f80000 0x0200>;
+ interrupts = <18>;
+ clocks = <&clks IMX5_CLK_USB_PHY1_GATE>;
+ status = "disabled";
+ };
+
+ usbh1: usb@53f80200 {
+ compatible = "fsl,imx50-usb", "fsl,imx27-usb";
+ reg = <0x53f80200 0x0200>;
+ interrupts = <14>;
+ clocks = <&clks IMX5_CLK_USB_PHY2_GATE>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbh2: usb@53f80400 {
+ compatible = "fsl,imx50-usb", "fsl,imx27-usb";
+ reg = <0x53f80400 0x0200>;
+ interrupts = <16>;
+ clocks = <&clks IMX5_CLK_USBOH3_GATE>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbh3: usb@53f80600 {
+ compatible = "fsl,imx50-usb", "fsl,imx27-usb";
+ reg = <0x53f80600 0x0200>;
+ interrupts = <17>;
+ clocks = <&clks IMX5_CLK_USBOH3_GATE>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ gpio1: gpio@53f84000 {
+ compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+ reg = <0x53f84000 0x4000>;
+ interrupts = <50 51>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@53f88000 {
+ compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+ reg = <0x53f88000 0x4000>;
+ interrupts = <52 53>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@53f8c000 {
+ compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+ reg = <0x53f8c000 0x4000>;
+ interrupts = <54 55>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@53f90000 {
+ compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+ reg = <0x53f90000 0x4000>;
+ interrupts = <56 57>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ wdog1: wdog@53f98000 {
+ compatible = "fsl,imx50-wdt", "fsl,imx21-wdt";
+ reg = <0x53f98000 0x4000>;
+ interrupts = <58>;
+ clocks = <&clks IMX5_CLK_DUMMY>;
+ };
+
+ gpt: timer@53fa0000 {
+ compatible = "fsl,imx50-gpt", "fsl,imx31-gpt";
+ reg = <0x53fa0000 0x4000>;
+ interrupts = <39>;
+ clocks = <&clks IMX5_CLK_GPT_IPG_GATE>,
+ <&clks IMX5_CLK_GPT_HF_GATE>;
+ clock-names = "ipg", "per";
+ };
+
+ iomuxc: iomuxc@53fa8000 {
+ compatible = "fsl,imx50-iomuxc", "fsl,imx53-iomuxc";
+ reg = <0x53fa8000 0x4000>;
+ };
+
+ gpr: iomuxc-gpr@53fa8000 {
+ compatible = "fsl,imx50-iomuxc-gpr", "syscon";
+ reg = <0x53fa8000 0xc>;
+ };
+
+ pwm1: pwm@53fb4000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx50-pwm", "fsl,imx27-pwm";
+ reg = <0x53fb4000 0x4000>;
+ clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
+ <&clks IMX5_CLK_PWM1_HF_GATE>;
+ clock-names = "ipg", "per";
+ interrupts = <61>;
+ };
+
+ pwm2: pwm@53fb8000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx50-pwm", "fsl,imx27-pwm";
+ reg = <0x53fb8000 0x4000>;
+ clocks = <&clks IMX5_CLK_PWM2_IPG_GATE>,
+ <&clks IMX5_CLK_PWM2_HF_GATE>;
+ clock-names = "ipg", "per";
+ interrupts = <94>;
+ };
+
+ uart1: serial@53fbc000 {
+ compatible = "fsl,imx50-uart", "fsl,imx21-uart";
+ reg = <0x53fbc000 0x4000>;
+ interrupts = <31>;
+ clocks = <&clks IMX5_CLK_UART1_IPG_GATE>,
+ <&clks IMX5_CLK_UART1_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart2: serial@53fc0000 {
+ compatible = "fsl,imx50-uart", "fsl,imx21-uart";
+ reg = <0x53fc0000 0x4000>;
+ interrupts = <32>;
+ clocks = <&clks IMX5_CLK_UART2_IPG_GATE>,
+ <&clks IMX5_CLK_UART2_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ src: src@53fd0000 {
+ compatible = "fsl,imx50-src", "fsl,imx51-src";
+ reg = <0x53fd0000 0x4000>;
+ #reset-cells = <1>;
+ };
+
+ clks: ccm@53fd4000{
+ compatible = "fsl,imx50-ccm";
+ reg = <0x53fd4000 0x4000>;
+ interrupts = <0 71 0x04 0 72 0x04>;
+ #clock-cells = <1>;
+ };
+
+ gpio5: gpio@53fdc000 {
+ compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+ reg = <0x53fdc000 0x4000>;
+ interrupts = <103 104>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio6: gpio@53fe0000 {
+ compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+ reg = <0x53fe0000 0x4000>;
+ interrupts = <105 106>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ i2c3: i2c@53fec000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx50-i2c", "fsl,imx21-i2c";
+ reg = <0x53fec000 0x4000>;
+ interrupts = <64>;
+ clocks = <&clks IMX5_CLK_I2C3_GATE>;
+ status = "disabled";
+ };
+
+ uart4: serial@53ff0000 {
+ compatible = "fsl,imx50-uart", "fsl,imx21-uart";
+ reg = <0x53ff0000 0x4000>;
+ interrupts = <13>;
+ clocks = <&clks IMX5_CLK_UART4_IPG_GATE>,
+ <&clks IMX5_CLK_UART4_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+ };
+
+ aips@60000000 { /* AIPS2 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x60000000 0x10000000>;
+ ranges;
+
+ uart5: serial@63f90000 {
+ compatible = "fsl,imx50-uart", "fsl,imx21-uart";
+ reg = <0x63f90000 0x4000>;
+ interrupts = <86>;
+ clocks = <&clks IMX5_CLK_UART5_IPG_GATE>,
+ <&clks IMX5_CLK_UART5_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ owire: owire@63fa4000 {
+ compatible = "fsl,imx50-owire", "fsl,imx21-owire";
+ reg = <0x63fa4000 0x4000>;
+ clocks = <&clks IMX5_CLK_OWIRE_GATE>;
+ status = "disabled";
+ };
+
+ ecspi2: ecspi@63fac000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx50-ecspi", "fsl,imx51-ecspi";
+ reg = <0x63fac000 0x4000>;
+ interrupts = <37>;
+ clocks = <&clks IMX5_CLK_ECSPI2_IPG_GATE>,
+ <&clks IMX5_CLK_ECSPI2_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ sdma: sdma@63fb0000 {
+ compatible = "fsl,imx50-sdma", "fsl,imx35-sdma";
+ reg = <0x63fb0000 0x4000>;
+ interrupts = <6>;
+ clocks = <&clks IMX5_CLK_SDMA_GATE>,
+ <&clks IMX5_CLK_SDMA_GATE>;
+ clock-names = "ipg", "ahb";
+ fsl,sdma-ram-script-name = "/*(DEBLOBBED)*/";
+ };
+
+ cspi: cspi@63fc0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx50-cspi", "fsl,imx35-cspi";
+ reg = <0x63fc0000 0x4000>;
+ interrupts = <38>;
+ clocks = <&clks IMX5_CLK_CSPI_IPG_GATE>,
+ <&clks IMX5_CLK_CSPI_IPG_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ i2c2: i2c@63fc4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx50-i2c", "fsl,imx21-i2c";
+ reg = <0x63fc4000 0x4000>;
+ interrupts = <63>;
+ clocks = <&clks IMX5_CLK_I2C2_GATE>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@63fc8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx50-i2c", "fsl,imx21-i2c";
+ reg = <0x63fc8000 0x4000>;
+ interrupts = <62>;
+ clocks = <&clks IMX5_CLK_I2C1_GATE>;
+ status = "disabled";
+ };
+
+ ssi1: ssi@63fcc000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx50-ssi", "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
+ reg = <0x63fcc000 0x4000>;
+ interrupts = <29>;
+ clocks = <&clks IMX5_CLK_SSI1_IPG_GATE>;
+ dmas = <&sdma 28 0 0>,
+ <&sdma 29 0 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ audmux: audmux@63fd0000 {
+ compatible = "fsl,imx50-audmux", "fsl,imx31-audmux";
+ reg = <0x63fd0000 0x4000>;
+ status = "disabled";
+ };
+
+ fec: ethernet@63fec000 {
+ compatible = "fsl,imx53-fec", "fsl,imx25-fec";
+ reg = <0x63fec000 0x4000>;
+ interrupts = <87>;
+ clocks = <&clks IMX5_CLK_FEC_GATE>,
+ <&clks IMX5_CLK_FEC_GATE>,
+ <&clks IMX5_CLK_FEC_GATE>;
+ clock-names = "ipg", "ahb", "ptp";
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx51-apf51.dts b/arch/arm/boot/dts/imx51-apf51.dts
new file mode 100644
index 000000000..e88b2a6be
--- /dev/null
+++ b/arch/arm/boot/dts/imx51-apf51.dts
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2012 Armadeus Systems - <support@armadeus.com>
+ * Copyright 2012 Laurent Cans <laurent.cans@gmail.com>
+ *
+ * Based on mx51-babbage.dts
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx51.dtsi"
+
+/ {
+ model = "Armadeus Systems APF51 module";
+ compatible = "armadeus,imx51-apf51", "fsl,imx51";
+
+ memory {
+ reg = <0x90000000 0x20000000>;
+ };
+
+ clocks {
+ osc {
+ clock-frequency = <33554432>;
+ };
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ phy-mode = "mii";
+ phy-reset-gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>;
+ phy-reset-duration = <1>;
+ status = "okay";
+};
+
+&iomuxc {
+ imx51-apf51 {
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX51_PAD_DI_GP3__FEC_TX_ER 0x80000000
+ MX51_PAD_DI2_PIN4__FEC_CRS 0x80000000
+ MX51_PAD_DI2_PIN2__FEC_MDC 0x80000000
+ MX51_PAD_DI2_PIN3__FEC_MDIO 0x80000000
+ MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 0x80000000
+ MX51_PAD_DI_GP4__FEC_RDATA2 0x80000000
+ MX51_PAD_DISP2_DAT0__FEC_RDATA3 0x80000000
+ MX51_PAD_DISP2_DAT1__FEC_RX_ER 0x80000000
+ MX51_PAD_DISP2_DAT6__FEC_TDATA1 0x80000000
+ MX51_PAD_DISP2_DAT7__FEC_TDATA2 0x80000000
+ MX51_PAD_DISP2_DAT8__FEC_TDATA3 0x80000000
+ MX51_PAD_DISP2_DAT9__FEC_TX_EN 0x80000000
+ MX51_PAD_DISP2_DAT10__FEC_COL 0x80000000
+ MX51_PAD_DISP2_DAT11__FEC_RX_CLK 0x80000000
+ MX51_PAD_DISP2_DAT12__FEC_RX_DV 0x80000000
+ MX51_PAD_DISP2_DAT13__FEC_TX_CLK 0x80000000
+ MX51_PAD_DISP2_DAT14__FEC_RDATA0 0x80000000
+ MX51_PAD_DISP2_DAT15__FEC_TDATA0 0x80000000
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX51_PAD_UART3_RXD__UART3_RXD 0x1c5
+ MX51_PAD_UART3_TXD__UART3_TXD 0x1c5
+ >;
+ };
+ };
+};
+
+&nfc {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ nand-on-flash-bbt;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx51-apf51dev.dts b/arch/arm/boot/dts/imx51-apf51dev.dts
new file mode 100644
index 000000000..93d3ea123
--- /dev/null
+++ b/arch/arm/boot/dts/imx51-apf51dev.dts
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2013 Armadeus Systems - <support@armadeus.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
+ */
+
+/* APF51Dev is a docking board for the APF51 SOM */
+#include "imx51-apf51.dts"
+
+/ {
+ model = "Armadeus Systems APF51Dev docking/development board";
+ compatible = "armadeus,imx51-apf51dev", "armadeus,imx51-apf51", "fsl,imx51";
+
+ backlight@bl1{
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_backlight>;
+ compatible = "gpio-backlight";
+ gpios = <&gpio3 4 GPIO_ACTIVE_HIGH>;
+ default-on;
+ };
+
+ display@di1 {
+ compatible = "fsl,imx-parallel-display";
+ interface-pix-fmt = "bgr666";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu_disp1>;
+
+ display-timings {
+ lw700 {
+ native-mode;
+ clock-frequency = <33000033>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <96>;
+ hfront-porch = <96>;
+ vback-porch = <20>;
+ vfront-porch = <21>;
+ hsync-len = <64>;
+ vsync-len = <4>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+
+ port {
+ display_in: endpoint {
+ remote-endpoint = <&ipu_di0_disp0>;
+ };
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ user-key {
+ label = "user";
+ gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+ linux,code = <256>; /* BTN_0 */
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ user {
+ label = "Heartbeat";
+ gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
+
+&ecspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ fsl,spi-num-chipselects = <2>;
+ cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>,
+ <&gpio4 25 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&ecspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi2>;
+ fsl,spi-num-chipselects = <2>;
+ cs-gpios = <&gpio3 28 GPIO_ACTIVE_LOW>,
+ <&gpio3 27 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ cd-gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&esdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc2>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx51-apf51dev {
+ pinctrl_backlight: bl1grp {
+ fsl,pins = <
+ MX51_PAD_DI1_D1_CS__GPIO3_4 0x1F5
+ >;
+ };
+
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX51_PAD_EIM_EB2__GPIO2_22 0x0C5
+ MX51_PAD_EIM_EB3__GPIO2_23 0x0C5
+ MX51_PAD_EIM_CS4__GPIO2_29 0x100
+ MX51_PAD_NANDF_D13__GPIO3_27 0x0C5
+ MX51_PAD_NANDF_D12__GPIO3_28 0x0C5
+ MX51_PAD_CSPI1_SS0__GPIO4_24 0x0C5
+ MX51_PAD_CSPI1_SS1__GPIO4_25 0x0C5
+ MX51_PAD_GPIO1_2__GPIO1_2 0x0C5
+ MX51_PAD_GPIO1_3__GPIO1_3 0x0C5
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX51_PAD_CSPI1_MISO__ECSPI1_MISO 0x185
+ MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI 0x185
+ MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK 0x185
+ >;
+ };
+
+ pinctrl_ecspi2: ecspi2grp {
+ fsl,pins = <
+ MX51_PAD_NANDF_RB3__ECSPI2_MISO 0x185
+ MX51_PAD_NANDF_D15__ECSPI2_MOSI 0x185
+ MX51_PAD_NANDF_RB2__ECSPI2_SCLK 0x185
+ >;
+ };
+
+ pinctrl_esdhc1: esdhc1grp {
+ fsl,pins = <
+ MX51_PAD_SD1_CMD__SD1_CMD 0x400020d5
+ MX51_PAD_SD1_CLK__SD1_CLK 0x20d5
+ MX51_PAD_SD1_DATA0__SD1_DATA0 0x20d5
+ MX51_PAD_SD1_DATA1__SD1_DATA1 0x20d5
+ MX51_PAD_SD1_DATA2__SD1_DATA2 0x20d5
+ MX51_PAD_SD1_DATA3__SD1_DATA3 0x20d5
+ >;
+ };
+
+ pinctrl_esdhc2: esdhc2grp {
+ fsl,pins = <
+ MX51_PAD_SD2_CMD__SD2_CMD 0x400020d5
+ MX51_PAD_SD2_CLK__SD2_CLK 0x20d5
+ MX51_PAD_SD2_DATA0__SD2_DATA0 0x20d5
+ MX51_PAD_SD2_DATA1__SD2_DATA1 0x20d5
+ MX51_PAD_SD2_DATA2__SD2_DATA2 0x20d5
+ MX51_PAD_SD2_DATA3__SD2_DATA3 0x20d5
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX51_PAD_EIM_D27__I2C2_SCL 0x400001ed
+ MX51_PAD_EIM_D24__I2C2_SDA 0x400001ed
+ >;
+ };
+
+ pinctrl_ipu_disp1: ipudisp1grp {
+ fsl,pins = <
+ MX51_PAD_DISP1_DAT0__DISP1_DAT0 0x5
+ MX51_PAD_DISP1_DAT1__DISP1_DAT1 0x5
+ MX51_PAD_DISP1_DAT2__DISP1_DAT2 0x5
+ MX51_PAD_DISP1_DAT3__DISP1_DAT3 0x5
+ MX51_PAD_DISP1_DAT4__DISP1_DAT4 0x5
+ MX51_PAD_DISP1_DAT5__DISP1_DAT5 0x5
+ MX51_PAD_DISP1_DAT6__DISP1_DAT6 0x5
+ MX51_PAD_DISP1_DAT7__DISP1_DAT7 0x5
+ MX51_PAD_DISP1_DAT8__DISP1_DAT8 0x5
+ MX51_PAD_DISP1_DAT9__DISP1_DAT9 0x5
+ MX51_PAD_DISP1_DAT10__DISP1_DAT10 0x5
+ MX51_PAD_DISP1_DAT11__DISP1_DAT11 0x5
+ MX51_PAD_DISP1_DAT12__DISP1_DAT12 0x5
+ MX51_PAD_DISP1_DAT13__DISP1_DAT13 0x5
+ MX51_PAD_DISP1_DAT14__DISP1_DAT14 0x5
+ MX51_PAD_DISP1_DAT15__DISP1_DAT15 0x5
+ MX51_PAD_DISP1_DAT16__DISP1_DAT16 0x5
+ MX51_PAD_DISP1_DAT17__DISP1_DAT17 0x5
+ MX51_PAD_DISP1_DAT18__DISP1_DAT18 0x5
+ MX51_PAD_DISP1_DAT19__DISP1_DAT19 0x5
+ MX51_PAD_DISP1_DAT20__DISP1_DAT20 0x5
+ MX51_PAD_DISP1_DAT21__DISP1_DAT21 0x5
+ MX51_PAD_DISP1_DAT22__DISP1_DAT22 0x5
+ MX51_PAD_DISP1_DAT23__DISP1_DAT23 0x5
+ MX51_PAD_DI1_PIN2__DI1_PIN2 0x5
+ MX51_PAD_DI1_PIN3__DI1_PIN3 0x5
+ >;
+ };
+ };
+};
+
+&ipu_di0_disp0 {
+ remote-endpoint = <&display_in>;
+};
diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts
new file mode 100644
index 000000000..649befeb2
--- /dev/null
+++ b/arch/arm/boot/dts/imx51-babbage.dts
@@ -0,0 +1,655 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx51.dtsi"
+
+/ {
+ model = "Freescale i.MX51 Babbage Board";
+ compatible = "fsl,imx51-babbage", "fsl,imx51";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory {
+ reg = <0x90000000 0x20000000>;
+ };
+
+ clocks {
+ ckih1 {
+ clock-frequency = <22579200>;
+ };
+
+ clk_26M: codec_clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+ gpios = <&gpio4 26 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ display0: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ interface-pix-fmt = "rgb24";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu_disp1>;
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: dvi {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ };
+ };
+
+ port {
+ display0_in: endpoint {
+ remote-endpoint = <&ipu_di0_disp0>;
+ };
+ };
+ };
+
+ display1: display@di1 {
+ compatible = "fsl,imx-parallel-display";
+ interface-pix-fmt = "rgb565";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu_disp2>;
+ status = "disabled";
+ display-timings {
+ native-mode = <&timing1>;
+ timing1: claawvga {
+ clock-frequency = <27000000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <40>;
+ hfront-porch = <60>;
+ vback-porch = <10>;
+ vfront-porch = <10>;
+ hsync-len = <20>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+
+ port {
+ display1_in: endpoint {
+ remote-endpoint = <&ipu_di1_disp1>;
+ };
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ power {
+ label = "Power Button";
+ gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
+ linux,code = <KEY_POWER>;
+ gpio-key,wakeup;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ led-diagnostic {
+ label = "diagnostic";
+ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_hub_reset: regulator@0 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotgreg>;
+ reg = <0>;
+ regulator-name = "hub_reset";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx51-babbage-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx51-babbage-sgtl5000";
+ ssi-controller = <&ssi2>;
+ audio-codec = <&sgtl5000>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <2>;
+ mux-ext-port = <3>;
+ };
+
+ usbphy {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "simple-bus";
+
+ usbh1phy: usbh1phy@0 {
+ compatible = "usb-nop-xceiv";
+ reg = <0>;
+ clocks = <&clks IMX5_CLK_DUMMY>;
+ clock-names = "main_clk";
+ reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&ecspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ fsl,spi-num-chipselects = <2>;
+ cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>,
+ <&gpio4 25 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ pmic: mc13892@0 {
+ compatible = "fsl,mc13892";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pmic>;
+ spi-max-frequency = <6000000>;
+ spi-cs-high;
+ reg = <0>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,mc13xxx-uses-rtc;
+
+ regulators {
+ sw1_reg: sw1 {
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1375000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1850000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3_reg: sw3 {
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1850000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1850000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vpll_reg: vpll {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdig_reg: vdig {
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <1650000>;
+ regulator-boot-on;
+ };
+
+ vsd_reg: vsd {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3150000>;
+ };
+
+ vusb2_reg: vusb2 {
+ regulator-min-microvolt = <2400000>;
+ regulator-max-microvolt = <2775000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vvideo_reg: vvideo {
+ regulator-min-microvolt = <2775000>;
+ regulator-max-microvolt = <2775000>;
+ };
+
+ vaudio_reg: vaudio {
+ regulator-min-microvolt = <2300000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ vcam_reg: vcam {
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3150000>;
+ regulator-always-on;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ flash: at45db321d@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at45db321d", "atmel,at45", "atmel,dataflash";
+ spi-max-frequency = <25000000>;
+ reg = <1>;
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0x0 0x40000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "Kernel";
+ reg = <0x40000 0x3c0000>;
+ };
+ };
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ cd-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&esdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc2>;
+ cd-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ phy-mode = "mii";
+ phy-reset-gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+ phy-reset-duration = <1>;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ sgtl5000: codec@0a {
+ compatible = "fsl,sgtl5000";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_clkcodec>;
+ reg = <0x0a>;
+ clocks = <&clk_26M>;
+ VDDA-supply = <&vdig_reg>;
+ VDDIO-supply = <&vvideo_reg>;
+ };
+};
+
+&ipu_di0_disp0 {
+ remote-endpoint = <&display0_in>;
+};
+
+&ipu_di1_disp1 {
+ remote-endpoint = <&display1_in>;
+};
+
+&kpp {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_kpp>;
+ linux,keymap = <
+ MATRIX_KEY(0, 0, KEY_UP)
+ MATRIX_KEY(0, 1, KEY_DOWN)
+ MATRIX_KEY(0, 2, KEY_VOLUMEDOWN)
+ MATRIX_KEY(0, 3, KEY_HOME)
+ MATRIX_KEY(1, 0, KEY_RIGHT)
+ MATRIX_KEY(1, 1, KEY_LEFT)
+ MATRIX_KEY(1, 2, KEY_ENTER)
+ MATRIX_KEY(1, 3, KEY_VOLUMEUP)
+ MATRIX_KEY(2, 0, KEY_F6)
+ MATRIX_KEY(2, 1, KEY_F8)
+ MATRIX_KEY(2, 2, KEY_F9)
+ MATRIX_KEY(2, 3, KEY_F10)
+ MATRIX_KEY(3, 0, KEY_F1)
+ MATRIX_KEY(3, 1, KEY_F2)
+ MATRIX_KEY(3, 2, KEY_F3)
+ MATRIX_KEY(3, 3, KEY_POWER)
+ >;
+ status = "okay";
+};
+
+&ssi2 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&usbh1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1>;
+ vbus-supply = <&reg_hub_reset>;
+ fsl,usbphy = <&usbh1phy>;
+ phy_type = "ulpi";
+ status = "okay";
+};
+
+&usbotg {
+ dr_mode = "otg";
+ disable-over-current;
+ phy_type = "utmi_wide";
+ status = "okay";
+};
+
+&iomuxc {
+ imx51-babbage {
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX51_PAD_AUD3_BB_TXD__AUD3_TXD 0x80000000
+ MX51_PAD_AUD3_BB_RXD__AUD3_RXD 0x80000000
+ MX51_PAD_AUD3_BB_CK__AUD3_TXC 0x80000000
+ MX51_PAD_AUD3_BB_FS__AUD3_TXFS 0x80000000
+ >;
+ };
+
+ pinctrl_clkcodec: clkcodecgrp {
+ fsl,pins = <
+ MX51_PAD_CSPI1_RDY__GPIO4_26 0x80000000
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX51_PAD_CSPI1_MISO__ECSPI1_MISO 0x185
+ MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI 0x185
+ MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK 0x185
+ MX51_PAD_CSPI1_SS0__GPIO4_24 0x85 /* CS0 */
+ MX51_PAD_CSPI1_SS1__GPIO4_25 0x85 /* CS1 */
+ >;
+ };
+
+ pinctrl_esdhc1: esdhc1grp {
+ fsl,pins = <
+ MX51_PAD_SD1_CMD__SD1_CMD 0x400020d5
+ MX51_PAD_SD1_CLK__SD1_CLK 0x20d5
+ MX51_PAD_SD1_DATA0__SD1_DATA0 0x20d5
+ MX51_PAD_SD1_DATA1__SD1_DATA1 0x20d5
+ MX51_PAD_SD1_DATA2__SD1_DATA2 0x20d5
+ MX51_PAD_SD1_DATA3__SD1_DATA3 0x20d5
+ MX51_PAD_GPIO1_0__GPIO1_0 0x100
+ MX51_PAD_GPIO1_1__GPIO1_1 0x100
+ >;
+ };
+
+ pinctrl_esdhc2: esdhc2grp {
+ fsl,pins = <
+ MX51_PAD_SD2_CMD__SD2_CMD 0x400020d5
+ MX51_PAD_SD2_CLK__SD2_CLK 0x20d5
+ MX51_PAD_SD2_DATA0__SD2_DATA0 0x20d5
+ MX51_PAD_SD2_DATA1__SD2_DATA1 0x20d5
+ MX51_PAD_SD2_DATA2__SD2_DATA2 0x20d5
+ MX51_PAD_SD2_DATA3__SD2_DATA3 0x20d5
+ MX51_PAD_GPIO1_5__GPIO1_5 0x100 /* WP */
+ MX51_PAD_GPIO1_6__GPIO1_6 0x100 /* CD */
+ >;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX51_PAD_EIM_EB2__FEC_MDIO 0x000001f5
+ MX51_PAD_EIM_EB3__FEC_RDATA1 0x00000085
+ MX51_PAD_EIM_CS2__FEC_RDATA2 0x00000085
+ MX51_PAD_EIM_CS3__FEC_RDATA3 0x00000085
+ MX51_PAD_EIM_CS4__FEC_RX_ER 0x00000180
+ MX51_PAD_EIM_CS5__FEC_CRS 0x00000180
+ MX51_PAD_NANDF_RB2__FEC_COL 0x00000180
+ MX51_PAD_NANDF_RB3__FEC_RX_CLK 0x00000180
+ MX51_PAD_NANDF_D9__FEC_RDATA0 0x00002180
+ MX51_PAD_NANDF_D8__FEC_TDATA0 0x00002004
+ MX51_PAD_NANDF_CS2__FEC_TX_ER 0x00002004
+ MX51_PAD_NANDF_CS3__FEC_MDC 0x00002004
+ MX51_PAD_NANDF_CS4__FEC_TDATA1 0x00002004
+ MX51_PAD_NANDF_CS5__FEC_TDATA2 0x00002004
+ MX51_PAD_NANDF_CS6__FEC_TDATA3 0x00002004
+ MX51_PAD_NANDF_CS7__FEC_TX_EN 0x00002004
+ MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK 0x00002180
+ MX51_PAD_NANDF_D11__FEC_RX_DV 0x000020a4
+ MX51_PAD_EIM_A20__GPIO2_14 0x00000085 /* Phy Reset */
+ >;
+ };
+
+ pinctrl_gpio_keys: gpiokeysgrp {
+ fsl,pins = <
+ MX51_PAD_EIM_A27__GPIO2_21 0x5
+ >;
+ };
+
+ pinctrl_gpio_leds: gpioledsgrp {
+ fsl,pins = <
+ MX51_PAD_EIM_D22__GPIO2_6 0x80000000
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX51_PAD_EIM_D19__I2C1_SCL 0x400001ed
+ MX51_PAD_EIM_D16__I2C1_SDA 0x400001ed
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX51_PAD_KEY_COL4__I2C2_SCL 0x400001ed
+ MX51_PAD_KEY_COL5__I2C2_SDA 0x400001ed
+ >;
+ };
+
+ pinctrl_ipu_disp1: ipudisp1grp {
+ fsl,pins = <
+ MX51_PAD_DISP1_DAT0__DISP1_DAT0 0x5
+ MX51_PAD_DISP1_DAT1__DISP1_DAT1 0x5
+ MX51_PAD_DISP1_DAT2__DISP1_DAT2 0x5
+ MX51_PAD_DISP1_DAT3__DISP1_DAT3 0x5
+ MX51_PAD_DISP1_DAT4__DISP1_DAT4 0x5
+ MX51_PAD_DISP1_DAT5__DISP1_DAT5 0x5
+ MX51_PAD_DISP1_DAT6__DISP1_DAT6 0x5
+ MX51_PAD_DISP1_DAT7__DISP1_DAT7 0x5
+ MX51_PAD_DISP1_DAT8__DISP1_DAT8 0x5
+ MX51_PAD_DISP1_DAT9__DISP1_DAT9 0x5
+ MX51_PAD_DISP1_DAT10__DISP1_DAT10 0x5
+ MX51_PAD_DISP1_DAT11__DISP1_DAT11 0x5
+ MX51_PAD_DISP1_DAT12__DISP1_DAT12 0x5
+ MX51_PAD_DISP1_DAT13__DISP1_DAT13 0x5
+ MX51_PAD_DISP1_DAT14__DISP1_DAT14 0x5
+ MX51_PAD_DISP1_DAT15__DISP1_DAT15 0x5
+ MX51_PAD_DISP1_DAT16__DISP1_DAT16 0x5
+ MX51_PAD_DISP1_DAT17__DISP1_DAT17 0x5
+ MX51_PAD_DISP1_DAT18__DISP1_DAT18 0x5
+ MX51_PAD_DISP1_DAT19__DISP1_DAT19 0x5
+ MX51_PAD_DISP1_DAT20__DISP1_DAT20 0x5
+ MX51_PAD_DISP1_DAT21__DISP1_DAT21 0x5
+ MX51_PAD_DISP1_DAT22__DISP1_DAT22 0x5
+ MX51_PAD_DISP1_DAT23__DISP1_DAT23 0x5
+ MX51_PAD_DI1_PIN2__DI1_PIN2 0x5
+ MX51_PAD_DI1_PIN3__DI1_PIN3 0x5
+ >;
+ };
+
+ pinctrl_ipu_disp2: ipudisp2grp {
+ fsl,pins = <
+ MX51_PAD_DISP2_DAT0__DISP2_DAT0 0x5
+ MX51_PAD_DISP2_DAT1__DISP2_DAT1 0x5
+ MX51_PAD_DISP2_DAT2__DISP2_DAT2 0x5
+ MX51_PAD_DISP2_DAT3__DISP2_DAT3 0x5
+ MX51_PAD_DISP2_DAT4__DISP2_DAT4 0x5
+ MX51_PAD_DISP2_DAT5__DISP2_DAT5 0x5
+ MX51_PAD_DISP2_DAT6__DISP2_DAT6 0x5
+ MX51_PAD_DISP2_DAT7__DISP2_DAT7 0x5
+ MX51_PAD_DISP2_DAT8__DISP2_DAT8 0x5
+ MX51_PAD_DISP2_DAT9__DISP2_DAT9 0x5
+ MX51_PAD_DISP2_DAT10__DISP2_DAT10 0x5
+ MX51_PAD_DISP2_DAT11__DISP2_DAT11 0x5
+ MX51_PAD_DISP2_DAT12__DISP2_DAT12 0x5
+ MX51_PAD_DISP2_DAT13__DISP2_DAT13 0x5
+ MX51_PAD_DISP2_DAT14__DISP2_DAT14 0x5
+ MX51_PAD_DISP2_DAT15__DISP2_DAT15 0x5
+ MX51_PAD_DI2_PIN2__DI2_PIN2 0x5
+ MX51_PAD_DI2_PIN3__DI2_PIN3 0x5
+ MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK 0x5
+ MX51_PAD_DI_GP4__DI2_PIN15 0x5
+ >;
+ };
+
+ pinctrl_kpp: kppgrp {
+ fsl,pins = <
+ MX51_PAD_KEY_ROW0__KEY_ROW0 0xe0
+ MX51_PAD_KEY_ROW1__KEY_ROW1 0xe0
+ MX51_PAD_KEY_ROW2__KEY_ROW2 0xe0
+ MX51_PAD_KEY_ROW3__KEY_ROW3 0xe0
+ MX51_PAD_KEY_COL0__KEY_COL0 0xe8
+ MX51_PAD_KEY_COL1__KEY_COL1 0xe8
+ MX51_PAD_KEY_COL2__KEY_COL2 0xe8
+ MX51_PAD_KEY_COL3__KEY_COL3 0xe8
+ >;
+ };
+
+ pinctrl_pmic: pmicgrp {
+ fsl,pins = <
+ MX51_PAD_GPIO1_8__GPIO1_8 0xe5 /* IRQ */
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX51_PAD_UART1_RXD__UART1_RXD 0x1c5
+ MX51_PAD_UART1_TXD__UART1_TXD 0x1c5
+ MX51_PAD_UART1_RTS__UART1_RTS 0x1c5
+ MX51_PAD_UART1_CTS__UART1_CTS 0x1c5
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX51_PAD_UART2_RXD__UART2_RXD 0x1c5
+ MX51_PAD_UART2_TXD__UART2_TXD 0x1c5
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX51_PAD_EIM_D25__UART3_RXD 0x1c5
+ MX51_PAD_EIM_D26__UART3_TXD 0x1c5
+ MX51_PAD_EIM_D27__UART3_RTS 0x1c5
+ MX51_PAD_EIM_D24__UART3_CTS 0x1c5
+ >;
+ };
+
+ pinctrl_usbh1: usbh1grp {
+ fsl,pins = <
+ MX51_PAD_USBH1_CLK__USBH1_CLK 0x80000000
+ MX51_PAD_USBH1_DIR__USBH1_DIR 0x80000000
+ MX51_PAD_USBH1_NXT__USBH1_NXT 0x80000000
+ MX51_PAD_USBH1_DATA0__USBH1_DATA0 0x80000000
+ MX51_PAD_USBH1_DATA1__USBH1_DATA1 0x80000000
+ MX51_PAD_USBH1_DATA2__USBH1_DATA2 0x80000000
+ MX51_PAD_USBH1_DATA3__USBH1_DATA3 0x80000000
+ MX51_PAD_USBH1_DATA4__USBH1_DATA4 0x80000000
+ MX51_PAD_USBH1_DATA5__USBH1_DATA5 0x80000000
+ MX51_PAD_USBH1_DATA6__USBH1_DATA6 0x80000000
+ MX51_PAD_USBH1_DATA7__USBH1_DATA7 0x80000000
+ >;
+ };
+
+ pinctrl_usbh1reg: usbh1reggrp {
+ fsl,pins = <
+ MX51_PAD_EIM_D21__GPIO2_5 0x85
+ >;
+ };
+
+ pinctrl_usbotgreg: usbotgreggrp {
+ fsl,pins = <
+ MX51_PAD_GPIO1_7__GPIO1_7 0x85
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx51-digi-connectcore-jsk.dts b/arch/arm/boot/dts/imx51-digi-connectcore-jsk.dts
new file mode 100644
index 000000000..1db517d3d
--- /dev/null
+++ b/arch/arm/boot/dts/imx51-digi-connectcore-jsk.dts
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * 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 "imx51-digi-connectcore-som.dtsi"
+
+/ {
+ model = "Digi ConnectCore CC(W)-MX51 JSK";
+ compatible = "digi,connectcore-ccxmx51-jsk",
+ "digi,connectcore-ccxmx51-som", "fsl,imx51";
+
+ chosen {
+ linux,stdout-path = &uart1;
+ };
+};
+
+&owire {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_owire>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
+
+&usbotg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usbh1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1>;
+ dr_mode = "host";
+ phy_type = "ulpi";
+ disable-over-current;
+ status = "okay";
+};
+
+&iomuxc {
+ imx51-digi-connectcore-jsk {
+ pinctrl_owire: owiregrp {
+ fsl,pins = <
+ MX51_PAD_OWIRE_LINE__OWIRE_LINE 0x40000000
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX51_PAD_UART1_RXD__UART1_RXD 0x1c5
+ MX51_PAD_UART1_TXD__UART1_TXD 0x1c5
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX51_PAD_UART2_RXD__UART2_RXD 0x1c5
+ MX51_PAD_UART2_TXD__UART2_TXD 0x1c5
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX51_PAD_UART3_RXD__UART3_RXD 0x1c5
+ MX51_PAD_UART3_TXD__UART3_TXD 0x1c5
+ >;
+ };
+
+ pinctrl_usbh1: usbh1grp {
+ fsl,pins = <
+ MX51_PAD_USBH1_DATA0__USBH1_DATA0 0x1e5
+ MX51_PAD_USBH1_DATA1__USBH1_DATA1 0x1e5
+ MX51_PAD_USBH1_DATA2__USBH1_DATA2 0x1e5
+ MX51_PAD_USBH1_DATA3__USBH1_DATA3 0x1e5
+ MX51_PAD_USBH1_DATA4__USBH1_DATA4 0x1e5
+ MX51_PAD_USBH1_DATA5__USBH1_DATA5 0x1e5
+ MX51_PAD_USBH1_DATA6__USBH1_DATA6 0x1e5
+ MX51_PAD_USBH1_DATA7__USBH1_DATA7 0x1e5
+ MX51_PAD_USBH1_CLK__USBH1_CLK 0x1e5
+ MX51_PAD_USBH1_DIR__USBH1_DIR 0x1e5
+ MX51_PAD_USBH1_NXT__USBH1_NXT 0x1e5
+ MX51_PAD_USBH1_STP__USBH1_STP 0x1e5
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx51-digi-connectcore-som.dtsi b/arch/arm/boot/dts/imx51-digi-connectcore-som.dtsi
new file mode 100644
index 000000000..321662f53
--- /dev/null
+++ b/arch/arm/boot/dts/imx51-digi-connectcore-som.dtsi
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx51.dtsi"
+
+/ {
+ model = "Digi ConnectCore CC(W)-MX51";
+ compatible = "digi,connectcore-ccxmx51-som", "fsl,imx51";
+
+ memory {
+ reg = <0x90000000 0x08000000>;
+ };
+};
+
+&ecspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+
+ pmic: mc13892@0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mc13892>;
+ compatible = "fsl,mc13892";
+ spi-max-frequency = <16000000>;
+ spi-cs-high;
+ reg = <0>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,mc13xxx-uses-rtc;
+
+ regulators {
+ sw1_reg: sw1 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3_reg: sw3 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst { };
+
+ viohi_reg: viohi {
+ regulator-always-on;
+ };
+
+ vpll_reg: vpll {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vdig_reg: vdig {
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-always-on;
+ };
+
+ vsd_reg: vsd {
+ regulator-min-microvolt = <3150000>;
+ regulator-max-microvolt = <3150000>;
+ regulator-always-on;
+ };
+
+ vusb2_reg: vusb2 {
+ regulator-min-microvolt = <2600000>;
+ regulator-max-microvolt = <2600000>;
+ regulator-always-on;
+ };
+
+ vvideo_reg: vvideo {
+ regulator-min-microvolt = <2775000>;
+ regulator-max-microvolt = <2775000>;
+ regulator-always-on;
+ };
+
+ vaudio_reg: vaudio {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ vcam_reg: vcam {
+ regulator-min-microvolt = <2750000>;
+ regulator-max-microvolt = <2750000>;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <3150000>;
+ regulator-max-microvolt = <3150000>;
+ regulator-always-on;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vusb_reg: vusb {
+ regulator-always-on;
+ };
+
+ gpo1_reg: gpo1 { };
+
+ gpo2_reg: gpo2 { };
+
+ gpo3_reg: gpo3 { };
+
+ gpo4_reg: gpo4 { };
+
+ pwgt2spi_reg: pwgt2spi {
+ regulator-always-on;
+ };
+
+ vcoincell_reg: vcoincell {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&esdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc2>;
+ cap-sdio-irq;
+ enable-sdio-wakeup;
+ keep-power-in-suspend;
+ max-frequency = <50000000>;
+ no-1-8-v;
+ non-removable;
+ vmmc-supply = <&gpo4_reg>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ phy-mode = "mii";
+ phy-supply = <&gpo3_reg>;
+ /* Pins shared with LCD2, keep status disabled */
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ mma7455l@1d {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mma7455l>;
+ compatible = "fsl,mma7455l";
+ reg = <0x1d>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH>, <6 IRQ_TYPE_LEVEL_HIGH>;
+ };
+};
+
+&nfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nfc>;
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ nand-on-flash-bbt;
+ status = "okay";
+};
+
+&usbotg {
+ phy_type = "utmi_wide";
+ disable-over-current;
+ /* Device role is not known, keep status disabled */
+};
+
+&weim {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_weim>;
+ status = "okay";
+
+ lan9221: lan9221@5,0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lan9221>;
+ compatible = "smsc,lan9221", "smsc,lan9115";
+ reg = <5 0x00000000 0x1000>;
+ fsl,weim-cs-timing = <
+ 0x00420081 0x00000000
+ 0x32260000 0x00000000
+ 0x72080f00 0x00000000
+ >;
+ clocks = <&clks IMX5_CLK_DUMMY>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+ phy-mode = "mii";
+ reg-io-width = <2>;
+ smsc,irq-push-pull;
+ vdd33a-supply = <&gpo2_reg>;
+ vddvario-supply = <&gpo2_reg>;
+ };
+};
+
+&iomuxc {
+ imx51-digi-connectcore-som {
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX51_PAD_CSPI1_MISO__ECSPI1_MISO 0x185
+ MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI 0x185
+ MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK 0x185
+ MX51_PAD_CSPI1_SS0__GPIO4_24 0x85 /* CS0 */
+ >;
+ };
+
+ pinctrl_esdhc2: esdhc2grp {
+ fsl,pins = <
+ MX51_PAD_SD2_CMD__SD2_CMD 0x400020d5
+ MX51_PAD_SD2_CLK__SD2_CLK 0x20d5
+ MX51_PAD_SD2_DATA0__SD2_DATA0 0x20d5
+ MX51_PAD_SD2_DATA1__SD2_DATA1 0x20d5
+ MX51_PAD_SD2_DATA2__SD2_DATA2 0x20d5
+ MX51_PAD_SD2_DATA3__SD2_DATA3 0x20d5
+ >;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX51_PAD_DI_GP3__FEC_TX_ER 0x80000000
+ MX51_PAD_DI2_PIN4__FEC_CRS 0x80000000
+ MX51_PAD_DI2_PIN2__FEC_MDC 0x80000000
+ MX51_PAD_DI2_PIN3__FEC_MDIO 0x80000000
+ MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 0x80000000
+ MX51_PAD_DI_GP4__FEC_RDATA2 0x80000000
+ MX51_PAD_DISP2_DAT0__FEC_RDATA3 0x80000000
+ MX51_PAD_DISP2_DAT1__FEC_RX_ER 0x80000000
+ MX51_PAD_DISP2_DAT6__FEC_TDATA1 0x80000000
+ MX51_PAD_DISP2_DAT7__FEC_TDATA2 0x80000000
+ MX51_PAD_DISP2_DAT8__FEC_TDATA3 0x80000000
+ MX51_PAD_DISP2_DAT9__FEC_TX_EN 0x80000000
+ MX51_PAD_DISP2_DAT10__FEC_COL 0x80000000
+ MX51_PAD_DISP2_DAT11__FEC_RX_CLK 0x80000000
+ MX51_PAD_DISP2_DAT12__FEC_RX_DV 0x80000000
+ MX51_PAD_DISP2_DAT13__FEC_TX_CLK 0x80000000
+ MX51_PAD_DISP2_DAT14__FEC_RDATA0 0x80000000
+ MX51_PAD_DISP2_DAT15__FEC_TDATA0 0x80000000
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX51_PAD_GPIO1_2__I2C2_SCL 0x400001ed
+ MX51_PAD_GPIO1_3__I2C2_SDA 0x400001ed
+ >;
+ };
+
+ pinctrl_nfc: nfcgrp {
+ fsl,pins = <
+ MX51_PAD_NANDF_D0__NANDF_D0 0x80000000
+ MX51_PAD_NANDF_D1__NANDF_D1 0x80000000
+ MX51_PAD_NANDF_D2__NANDF_D2 0x80000000
+ MX51_PAD_NANDF_D3__NANDF_D3 0x80000000
+ MX51_PAD_NANDF_D4__NANDF_D4 0x80000000
+ MX51_PAD_NANDF_D5__NANDF_D5 0x80000000
+ MX51_PAD_NANDF_D6__NANDF_D6 0x80000000
+ MX51_PAD_NANDF_D7__NANDF_D7 0x80000000
+ MX51_PAD_NANDF_ALE__NANDF_ALE 0x80000000
+ MX51_PAD_NANDF_CLE__NANDF_CLE 0x80000000
+ MX51_PAD_NANDF_RE_B__NANDF_RE_B 0x80000000
+ MX51_PAD_NANDF_WE_B__NANDF_WE_B 0x80000000
+ MX51_PAD_NANDF_WP_B__NANDF_WP_B 0x80000000
+ MX51_PAD_NANDF_CS0__NANDF_CS0 0x80000000
+ MX51_PAD_NANDF_RB0__NANDF_RB0 0x80000000
+ >;
+ };
+
+ pinctrl_lan9221: lan9221grp {
+ fsl,pins = <
+ MX51_PAD_GPIO1_9__GPIO1_9 0xe5 /* IRQ */
+ >;
+ };
+
+ pinctrl_mc13892: mc13892grp {
+ fsl,pins = <
+ MX51_PAD_GPIO1_5__GPIO1_5 0xe5 /* IRQ */
+ >;
+ };
+
+ pinctrl_mma7455l: mma7455lgrp {
+ fsl,pins = <
+ MX51_PAD_GPIO1_7__GPIO1_7 0xe5 /* IRQ1 */
+ MX51_PAD_GPIO1_6__GPIO1_6 0xe5 /* IRQ2 */
+ >;
+ };
+
+ pinctrl_weim: weimgrp {
+ fsl,pins = <
+ MX51_PAD_EIM_DA0__EIM_DA0 0x80000000
+ MX51_PAD_EIM_DA1__EIM_DA1 0x80000000
+ MX51_PAD_EIM_DA2__EIM_DA2 0x80000000
+ MX51_PAD_EIM_DA3__EIM_DA3 0x80000000
+ MX51_PAD_EIM_DA4__EIM_DA4 0x80000000
+ MX51_PAD_EIM_DA5__EIM_DA5 0x80000000
+ MX51_PAD_EIM_DA6__EIM_DA6 0x80000000
+ MX51_PAD_EIM_DA7__EIM_DA7 0x80000000
+ MX51_PAD_EIM_DA8__EIM_DA8 0x80000000
+ MX51_PAD_EIM_DA9__EIM_DA9 0x80000000
+ MX51_PAD_EIM_DA10__EIM_DA10 0x80000000
+ MX51_PAD_EIM_DA11__EIM_DA11 0x80000000
+ MX51_PAD_EIM_DA12__EIM_DA12 0x80000000
+ MX51_PAD_EIM_DA13__EIM_DA13 0x80000000
+ MX51_PAD_EIM_DA14__EIM_DA14 0x80000000
+ MX51_PAD_EIM_DA15__EIM_DA15 0x80000000
+ MX51_PAD_EIM_A16__EIM_A16 0x80000000
+ MX51_PAD_EIM_A17__EIM_A17 0x80000000
+ MX51_PAD_EIM_A18__EIM_A18 0x80000000
+ MX51_PAD_EIM_A19__EIM_A19 0x80000000
+ MX51_PAD_EIM_A20__EIM_A20 0x80000000
+ MX51_PAD_EIM_A21__EIM_A21 0x80000000
+ MX51_PAD_EIM_A22__EIM_A22 0x80000000
+ MX51_PAD_EIM_A23__EIM_A23 0x80000000
+ MX51_PAD_EIM_A24__EIM_A24 0x80000000
+ MX51_PAD_EIM_A25__EIM_A25 0x80000000
+ MX51_PAD_EIM_A26__EIM_A26 0x80000000
+ MX51_PAD_EIM_A27__EIM_A27 0x80000000
+ MX51_PAD_EIM_D16__EIM_D16 0x80000000
+ MX51_PAD_EIM_D17__EIM_D17 0x80000000
+ MX51_PAD_EIM_D18__EIM_D18 0x80000000
+ MX51_PAD_EIM_D19__EIM_D19 0x80000000
+ MX51_PAD_EIM_D20__EIM_D20 0x80000000
+ MX51_PAD_EIM_D21__EIM_D21 0x80000000
+ MX51_PAD_EIM_D22__EIM_D22 0x80000000
+ MX51_PAD_EIM_D23__EIM_D23 0x80000000
+ MX51_PAD_EIM_D24__EIM_D24 0x80000000
+ MX51_PAD_EIM_D25__EIM_D25 0x80000000
+ MX51_PAD_EIM_D26__EIM_D26 0x80000000
+ MX51_PAD_EIM_D27__EIM_D27 0x80000000
+ MX51_PAD_EIM_D28__EIM_D28 0x80000000
+ MX51_PAD_EIM_D29__EIM_D29 0x80000000
+ MX51_PAD_EIM_D30__EIM_D30 0x80000000
+ MX51_PAD_EIM_D31__EIM_D31 0x80000000
+ MX51_PAD_EIM_OE__EIM_OE 0x80000000
+ MX51_PAD_EIM_DTACK__EIM_DTACK 0x80000000
+ MX51_PAD_EIM_LBA__EIM_LBA 0x80000000
+ MX51_PAD_EIM_CS5__EIM_CS5 0x80000000 /* CS5 */
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi b/arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi
new file mode 100644
index 000000000..63164266a
--- /dev/null
+++ b/arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@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 "imx51.dtsi"
+
+/ {
+ model = "Eukrea CPUIMX51";
+ compatible = "eukrea,cpuimx51", "fsl,imx51";
+
+ memory {
+ reg = <0x90000000 0x10000000>; /* 256M */
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pcf8563@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+
+ tsc2007: tsc2007@49 {
+ compatible = "ti,tsc2007";
+ gpios = <&gpio4 0 1>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <0x0 0x8>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tsc2007_1>;
+ reg = <0x49>;
+ ti,x-plate-ohms = <180>;
+ };
+};
+
+&iomuxc {
+ imx51-eukrea {
+ pinctrl_tsc2007_1: tsc2007grp-1 {
+ fsl,pins = <
+ MX51_PAD_GPIO_NAND__GPIO_NAND 0x1f5
+ MX51_PAD_NANDF_D8__GPIO4_0 0x1f5
+ >;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX51_PAD_DI_GP3__FEC_TX_ER 0x80000000
+ MX51_PAD_DI2_PIN4__FEC_CRS 0x80000000
+ MX51_PAD_DI2_PIN2__FEC_MDC 0x80000000
+ MX51_PAD_DI2_PIN3__FEC_MDIO 0x80000000
+ MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 0x80000000
+ MX51_PAD_DI_GP4__FEC_RDATA2 0x80000000
+ MX51_PAD_DISP2_DAT0__FEC_RDATA3 0x80000000
+ MX51_PAD_DISP2_DAT1__FEC_RX_ER 0x80000000
+ MX51_PAD_DISP2_DAT6__FEC_TDATA1 0x80000000
+ MX51_PAD_DISP2_DAT7__FEC_TDATA2 0x80000000
+ MX51_PAD_DISP2_DAT8__FEC_TDATA3 0x80000000
+ MX51_PAD_DISP2_DAT9__FEC_TX_EN 0x80000000
+ MX51_PAD_DISP2_DAT10__FEC_COL 0x80000000
+ MX51_PAD_DISP2_DAT11__FEC_RX_CLK 0x80000000
+ MX51_PAD_DISP2_DAT12__FEC_RX_DV 0x80000000
+ MX51_PAD_DISP2_DAT13__FEC_TX_CLK 0x80000000
+ MX51_PAD_DISP2_DAT14__FEC_RDATA0 0x80000000
+ MX51_PAD_DISP2_DAT15__FEC_TDATA0 0x80000000
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX51_PAD_SD2_CMD__I2C1_SCL 0x400001ed
+ MX51_PAD_SD2_CLK__I2C1_SDA 0x400001ed
+ >;
+ };
+ };
+};
+
+&nfc {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ nand-on-flash-bbt;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts b/arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts
new file mode 100644
index 000000000..34599c547
--- /dev/null
+++ b/arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@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.
+ */
+
+/dts-v1/;
+#include "imx51-eukrea-cpuimx51.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Eukrea CPUIMX51";
+ compatible = "eukrea,mbimxsd51","eukrea,cpuimx51", "fsl,imx51";
+
+ clocks {
+ clk24M: can_clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpiokeys_1>;
+
+ button-1 {
+ label = "BP1";
+ gpios = <&gpio3 31 GPIO_ACTIVE_LOW>;
+ linux,code = <256>;
+ gpio-key,wakeup;
+ linux,input-type = <1>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpioled>;
+
+ led1 {
+ label = "led1";
+ gpios = <&gpio3 30 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_can: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "CAN_RST";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio4 15 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <20000>;
+ enable-active-high;
+ };
+ };
+
+ sound {
+ compatible = "eukrea,asoc-tlv320";
+ eukrea,model = "imx51-eukrea-tlv320aic23";
+ ssi-controller = <&ssi2>;
+ fsl,mux-int-port = <2>;
+ fsl,mux-ext-port = <3>;
+ };
+
+ usbphy {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "simple-bus";
+
+ usbh1phy: usbh1phy@0 {
+ compatible = "usb-nop-xceiv";
+ reg = <0>;
+ clocks = <&clks IMX5_CLK_USB_PHY_GATE>;
+ clock-names = "main_clk";
+ clock-frequency = <19200000>;
+ };
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1 &pinctrl_esdhc1_cd>;
+ cd-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&ecspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 24 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ can0: can@0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can>;
+ compatible = "microchip,mcp2515";
+ reg = <0>;
+ clocks = <&clk24M>;
+ spi-max-frequency = <10000000>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+ vdd-supply = <&reg_can>;
+ };
+};
+
+&i2c1 {
+ tlv320aic23: codec@1a {
+ compatible = "ti,tlv320aic23";
+ reg = <0x1a>;
+ };
+};
+
+&iomuxc {
+ imx51-eukrea {
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX51_PAD_AUD3_BB_TXD__AUD3_TXD 0x80000000
+ MX51_PAD_AUD3_BB_RXD__AUD3_RXD 0x80000000
+ MX51_PAD_AUD3_BB_CK__AUD3_TXC 0x80000000
+ MX51_PAD_AUD3_BB_FS__AUD3_TXFS 0x80000000
+ >;
+ };
+
+
+ pinctrl_can: cangrp {
+ fsl,pins = <
+ MX51_PAD_CSI2_PIXCLK__GPIO4_15 0x80000000 /* nReset */
+ MX51_PAD_GPIO1_1__GPIO1_1 0x80000000 /* IRQ */
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX51_PAD_CSPI1_MISO__ECSPI1_MISO 0x185
+ MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI 0x185
+ MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK 0x185
+ MX51_PAD_CSPI1_SS0__GPIO4_24 0x80000000 /* CS0 */
+ >;
+ };
+
+ pinctrl_esdhc1: esdhc1grp {
+ fsl,pins = <
+ MX51_PAD_SD1_CMD__SD1_CMD 0x400020d5
+ MX51_PAD_SD1_CLK__SD1_CLK 0x20d5
+ MX51_PAD_SD1_DATA0__SD1_DATA0 0x20d5
+ MX51_PAD_SD1_DATA1__SD1_DATA1 0x20d5
+ MX51_PAD_SD1_DATA2__SD1_DATA2 0x20d5
+ MX51_PAD_SD1_DATA3__SD1_DATA3 0x20d5
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX51_PAD_UART1_RXD__UART1_RXD 0x1c5
+ MX51_PAD_UART1_TXD__UART1_TXD 0x1c5
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX51_PAD_UART3_RXD__UART3_RXD 0x1c5
+ MX51_PAD_UART3_TXD__UART3_TXD 0x1c5
+ >;
+ };
+
+ pinctrl_uart3_rtscts: uart3rtsctsgrp {
+ fsl,pins = <
+ MX51_PAD_KEY_COL4__UART3_RTS 0x1c5
+ MX51_PAD_KEY_COL5__UART3_CTS 0x1c5
+ >;
+ };
+
+ pinctrl_backlight_1: backlightgrp-1 {
+ fsl,pins = <
+ MX51_PAD_DI1_D1_CS__GPIO3_4 0x1f5
+ >;
+ };
+
+ pinctrl_esdhc1_cd: esdhc1_cd {
+ fsl,pins = <
+ MX51_PAD_GPIO1_0__GPIO1_0 0xd5
+ >;
+ };
+
+ pinctrl_gpiokeys_1: gpiokeysgrp-1 {
+ fsl,pins = <
+ MX51_PAD_NANDF_D9__GPIO3_31 0x1f5
+ >;
+ };
+
+ pinctrl_gpioled: gpioledgrp-1 {
+ fsl,pins = <
+ MX51_PAD_NANDF_D10__GPIO3_30 0x80000000
+ >;
+ };
+
+ pinctrl_reg_lcd_3v3: reg_lcd_3v3 {
+ fsl,pins = <
+ MX51_PAD_CSI1_D9__GPIO3_13 0x1f5
+ >;
+ };
+
+ pinctrl_usbh1: usbh1grp {
+ fsl,pins = <
+ MX51_PAD_USBH1_CLK__USBH1_CLK 0x1e5
+ MX51_PAD_USBH1_DIR__USBH1_DIR 0x1e5
+ MX51_PAD_USBH1_NXT__USBH1_NXT 0x1e5
+ MX51_PAD_USBH1_DATA0__USBH1_DATA0 0x1e5
+ MX51_PAD_USBH1_DATA1__USBH1_DATA1 0x1e5
+ MX51_PAD_USBH1_DATA2__USBH1_DATA2 0x1e5
+ MX51_PAD_USBH1_DATA3__USBH1_DATA3 0x1e5
+ MX51_PAD_USBH1_DATA4__USBH1_DATA4 0x1e5
+ MX51_PAD_USBH1_DATA5__USBH1_DATA5 0x1e5
+ MX51_PAD_USBH1_DATA6__USBH1_DATA6 0x1e5
+ MX51_PAD_USBH1_DATA7__USBH1_DATA7 0x1e5
+ MX51_PAD_USBH1_STP__USBH1_STP 0x1e5
+ >;
+ };
+
+ pinctrl_usbh1_vbus: usbh1-vbusgrp {
+ fsl,pins = <
+ MX51_PAD_EIM_CS3__GPIO2_28 0x1f5
+ >;
+ };
+ };
+};
+
+&ssi2 {
+ codec-handle = <&tlv320aic23>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3 &pinctrl_uart3_rtscts>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&usbh1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1>;
+ fsl,usbphy = <&usbh1phy>;
+ dr_mode = "host";
+ phy_type = "ulpi";
+ status = "okay";
+};
+
+&usbotg {
+ dr_mode = "otg";
+ phy_type = "utmi_wide";
+ status = "okay";
+};
+
+&usbphy0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1_vbus>;
+ reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm/boot/dts/imx51-pinfunc.h b/arch/arm/boot/dts/imx51-pinfunc.h
new file mode 100644
index 000000000..9eb92abae
--- /dev/null
+++ b/arch/arm/boot/dts/imx51-pinfunc.h
@@ -0,0 +1,773 @@
+/*
+ * Copyright 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX51_PINFUNC_H
+#define __DTS_IMX51_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX51_PAD_EIM_D16__AUD4_RXFS 0x05c 0x3f0 0x000 0x5 0x0
+#define MX51_PAD_EIM_D16__AUD5_TXD 0x05c 0x3f0 0x8d8 0x7 0x0
+#define MX51_PAD_EIM_D16__EIM_D16 0x05c 0x3f0 0x000 0x0 0x0
+#define MX51_PAD_EIM_D16__GPIO2_0 0x05c 0x3f0 0x000 0x1 0x0
+#define MX51_PAD_EIM_D16__I2C1_SDA 0x05c 0x3f0 0x9b4 0x4 0x0
+#define MX51_PAD_EIM_D16__UART2_CTS 0x05c 0x3f0 0x000 0x3 0x0
+#define MX51_PAD_EIM_D16__USBH2_DATA0 0x05c 0x3f0 0x000 0x2 0x0
+#define MX51_PAD_EIM_D17__AUD5_RXD 0x060 0x3f4 0x8d4 0x7 0x0
+#define MX51_PAD_EIM_D17__EIM_D17 0x060 0x3f4 0x000 0x0 0x0
+#define MX51_PAD_EIM_D17__GPIO2_1 0x060 0x3f4 0x000 0x1 0x0
+#define MX51_PAD_EIM_D17__UART2_RXD 0x060 0x3f4 0x9ec 0x3 0x0
+#define MX51_PAD_EIM_D17__UART3_CTS 0x060 0x3f4 0x000 0x4 0x0
+#define MX51_PAD_EIM_D17__USBH2_DATA1 0x060 0x3f4 0x000 0x2 0x0
+#define MX51_PAD_EIM_D18__AUD5_TXC 0x064 0x3f8 0x8e4 0x7 0x0
+#define MX51_PAD_EIM_D18__EIM_D18 0x064 0x3f8 0x000 0x0 0x0
+#define MX51_PAD_EIM_D18__GPIO2_2 0x064 0x3f8 0x000 0x1 0x0
+#define MX51_PAD_EIM_D18__UART2_TXD 0x064 0x3f8 0x000 0x3 0x0
+#define MX51_PAD_EIM_D18__UART3_RTS 0x064 0x3f8 0x9f0 0x4 0x1
+#define MX51_PAD_EIM_D18__USBH2_DATA2 0x064 0x3f8 0x000 0x2 0x0
+#define MX51_PAD_EIM_D19__AUD4_RXC 0x068 0x3fc 0x000 0x5 0x0
+#define MX51_PAD_EIM_D19__AUD5_TXFS 0x068 0x3fc 0x8e8 0x7 0x0
+#define MX51_PAD_EIM_D19__EIM_D19 0x068 0x3fc 0x000 0x0 0x0
+#define MX51_PAD_EIM_D19__GPIO2_3 0x068 0x3fc 0x000 0x1 0x0
+#define MX51_PAD_EIM_D19__I2C1_SCL 0x068 0x3fc 0x9b0 0x4 0x0
+#define MX51_PAD_EIM_D19__UART2_RTS 0x068 0x3fc 0x9e8 0x3 0x1
+#define MX51_PAD_EIM_D19__USBH2_DATA3 0x068 0x3fc 0x000 0x2 0x0
+#define MX51_PAD_EIM_D20__AUD4_TXD 0x06c 0x400 0x8c8 0x5 0x0
+#define MX51_PAD_EIM_D20__EIM_D20 0x06c 0x400 0x000 0x0 0x0
+#define MX51_PAD_EIM_D20__GPIO2_4 0x06c 0x400 0x000 0x1 0x0
+#define MX51_PAD_EIM_D20__SRTC_ALARM_DEB 0x06c 0x400 0x000 0x4 0x0
+#define MX51_PAD_EIM_D20__USBH2_DATA4 0x06c 0x400 0x000 0x2 0x0
+#define MX51_PAD_EIM_D21__AUD4_RXD 0x070 0x404 0x8c4 0x5 0x0
+#define MX51_PAD_EIM_D21__EIM_D21 0x070 0x404 0x000 0x0 0x0
+#define MX51_PAD_EIM_D21__GPIO2_5 0x070 0x404 0x000 0x1 0x0
+#define MX51_PAD_EIM_D21__SRTC_ALARM_DEB 0x070 0x404 0x000 0x3 0x0
+#define MX51_PAD_EIM_D21__USBH2_DATA5 0x070 0x404 0x000 0x2 0x0
+#define MX51_PAD_EIM_D22__AUD4_TXC 0x074 0x408 0x8cc 0x5 0x0
+#define MX51_PAD_EIM_D22__EIM_D22 0x074 0x408 0x000 0x0 0x0
+#define MX51_PAD_EIM_D22__GPIO2_6 0x074 0x408 0x000 0x1 0x0
+#define MX51_PAD_EIM_D22__USBH2_DATA6 0x074 0x408 0x000 0x2 0x0
+#define MX51_PAD_EIM_D23__AUD4_TXFS 0x078 0x40c 0x8d0 0x5 0x0
+#define MX51_PAD_EIM_D23__EIM_D23 0x078 0x40c 0x000 0x0 0x0
+#define MX51_PAD_EIM_D23__GPIO2_7 0x078 0x40c 0x000 0x1 0x0
+#define MX51_PAD_EIM_D23__SPDIF_OUT1 0x078 0x40c 0x000 0x4 0x0
+#define MX51_PAD_EIM_D23__USBH2_DATA7 0x078 0x40c 0x000 0x2 0x0
+#define MX51_PAD_EIM_D24__AUD6_RXFS 0x07c 0x410 0x8f8 0x5 0x0
+#define MX51_PAD_EIM_D24__EIM_D24 0x07c 0x410 0x000 0x0 0x0
+#define MX51_PAD_EIM_D24__GPIO2_8 0x07c 0x410 0x000 0x1 0x0
+#define MX51_PAD_EIM_D24__I2C2_SDA 0x07c 0x410 0x9bc 0x4 0x0
+#define MX51_PAD_EIM_D24__UART3_CTS 0x07c 0x410 0x000 0x3 0x0
+#define MX51_PAD_EIM_D24__USBOTG_DATA0 0x07c 0x410 0x000 0x2 0x0
+#define MX51_PAD_EIM_D25__EIM_D25 0x080 0x414 0x000 0x0 0x0
+#define MX51_PAD_EIM_D25__KEY_COL6 0x080 0x414 0x9c8 0x1 0x0
+#define MX51_PAD_EIM_D25__UART2_CTS 0x080 0x414 0x000 0x4 0x0
+#define MX51_PAD_EIM_D25__UART3_RXD 0x080 0x414 0x9f4 0x3 0x0
+#define MX51_PAD_EIM_D25__USBOTG_DATA1 0x080 0x414 0x000 0x2 0x0
+#define MX51_PAD_EIM_D26__EIM_D26 0x084 0x418 0x000 0x0 0x0
+#define MX51_PAD_EIM_D26__KEY_COL7 0x084 0x418 0x9cc 0x1 0x0
+#define MX51_PAD_EIM_D26__UART2_RTS 0x084 0x418 0x9e8 0x4 0x3
+#define MX51_PAD_EIM_D26__UART3_TXD 0x084 0x418 0x000 0x3 0x0
+#define MX51_PAD_EIM_D26__USBOTG_DATA2 0x084 0x418 0x000 0x2 0x0
+#define MX51_PAD_EIM_D27__AUD6_RXC 0x088 0x41c 0x8f4 0x5 0x0
+#define MX51_PAD_EIM_D27__EIM_D27 0x088 0x41c 0x000 0x0 0x0
+#define MX51_PAD_EIM_D27__GPIO2_9 0x088 0x41c 0x000 0x1 0x0
+#define MX51_PAD_EIM_D27__I2C2_SCL 0x088 0x41c 0x9b8 0x4 0x0
+#define MX51_PAD_EIM_D27__UART3_RTS 0x088 0x41c 0x9f0 0x3 0x3
+#define MX51_PAD_EIM_D27__USBOTG_DATA3 0x088 0x41c 0x000 0x2 0x0
+#define MX51_PAD_EIM_D28__AUD6_TXD 0x08c 0x420 0x8f0 0x5 0x0
+#define MX51_PAD_EIM_D28__EIM_D28 0x08c 0x420 0x000 0x0 0x0
+#define MX51_PAD_EIM_D28__KEY_ROW4 0x08c 0x420 0x9d0 0x1 0x0
+#define MX51_PAD_EIM_D28__USBOTG_DATA4 0x08c 0x420 0x000 0x2 0x0
+#define MX51_PAD_EIM_D29__AUD6_RXD 0x090 0x424 0x8ec 0x5 0x0
+#define MX51_PAD_EIM_D29__EIM_D29 0x090 0x424 0x000 0x0 0x0
+#define MX51_PAD_EIM_D29__KEY_ROW5 0x090 0x424 0x9d4 0x1 0x0
+#define MX51_PAD_EIM_D29__USBOTG_DATA5 0x090 0x424 0x000 0x2 0x0
+#define MX51_PAD_EIM_D30__AUD6_TXC 0x094 0x428 0x8fc 0x5 0x0
+#define MX51_PAD_EIM_D30__EIM_D30 0x094 0x428 0x000 0x0 0x0
+#define MX51_PAD_EIM_D30__KEY_ROW6 0x094 0x428 0x9d8 0x1 0x0
+#define MX51_PAD_EIM_D30__USBOTG_DATA6 0x094 0x428 0x000 0x2 0x0
+#define MX51_PAD_EIM_D31__AUD6_TXFS 0x098 0x42c 0x900 0x5 0x0
+#define MX51_PAD_EIM_D31__EIM_D31 0x098 0x42c 0x000 0x0 0x0
+#define MX51_PAD_EIM_D31__KEY_ROW7 0x098 0x42c 0x9dc 0x1 0x0
+#define MX51_PAD_EIM_D31__USBOTG_DATA7 0x098 0x42c 0x000 0x2 0x0
+#define MX51_PAD_EIM_A16__EIM_A16 0x09c 0x430 0x000 0x0 0x0
+#define MX51_PAD_EIM_A16__GPIO2_10 0x09c 0x430 0x000 0x1 0x0
+#define MX51_PAD_EIM_A16__OSC_FREQ_SEL0 0x09c 0x430 0x000 0x7 0x0
+#define MX51_PAD_EIM_A17__EIM_A17 0x0a0 0x434 0x000 0x0 0x0
+#define MX51_PAD_EIM_A17__GPIO2_11 0x0a0 0x434 0x000 0x1 0x0
+#define MX51_PAD_EIM_A17__OSC_FREQ_SEL1 0x0a0 0x434 0x000 0x7 0x0
+#define MX51_PAD_EIM_A18__BOOT_LPB0 0x0a4 0x438 0x000 0x7 0x0
+#define MX51_PAD_EIM_A18__EIM_A18 0x0a4 0x438 0x000 0x0 0x0
+#define MX51_PAD_EIM_A18__GPIO2_12 0x0a4 0x438 0x000 0x1 0x0
+#define MX51_PAD_EIM_A19__BOOT_LPB1 0x0a8 0x43c 0x000 0x7 0x0
+#define MX51_PAD_EIM_A19__EIM_A19 0x0a8 0x43c 0x000 0x0 0x0
+#define MX51_PAD_EIM_A19__GPIO2_13 0x0a8 0x43c 0x000 0x1 0x0
+#define MX51_PAD_EIM_A20__BOOT_UART_SRC0 0x0ac 0x440 0x000 0x7 0x0
+#define MX51_PAD_EIM_A20__EIM_A20 0x0ac 0x440 0x000 0x0 0x0
+#define MX51_PAD_EIM_A20__GPIO2_14 0x0ac 0x440 0x000 0x1 0x0
+#define MX51_PAD_EIM_A21__BOOT_UART_SRC1 0x0b0 0x444 0x000 0x7 0x0
+#define MX51_PAD_EIM_A21__EIM_A21 0x0b0 0x444 0x000 0x0 0x0
+#define MX51_PAD_EIM_A21__GPIO2_15 0x0b0 0x444 0x000 0x1 0x0
+#define MX51_PAD_EIM_A22__EIM_A22 0x0b4 0x448 0x000 0x0 0x0
+#define MX51_PAD_EIM_A22__GPIO2_16 0x0b4 0x448 0x000 0x1 0x0
+#define MX51_PAD_EIM_A23__BOOT_HPN_EN 0x0b8 0x44c 0x000 0x7 0x0
+#define MX51_PAD_EIM_A23__EIM_A23 0x0b8 0x44c 0x000 0x0 0x0
+#define MX51_PAD_EIM_A23__GPIO2_17 0x0b8 0x44c 0x000 0x1 0x0
+#define MX51_PAD_EIM_A24__EIM_A24 0x0bc 0x450 0x000 0x0 0x0
+#define MX51_PAD_EIM_A24__GPIO2_18 0x0bc 0x450 0x000 0x1 0x0
+#define MX51_PAD_EIM_A24__USBH2_CLK 0x0bc 0x450 0x000 0x2 0x0
+#define MX51_PAD_EIM_A25__DISP1_PIN4 0x0c0 0x454 0x000 0x6 0x0
+#define MX51_PAD_EIM_A25__EIM_A25 0x0c0 0x454 0x000 0x0 0x0
+#define MX51_PAD_EIM_A25__GPIO2_19 0x0c0 0x454 0x000 0x1 0x0
+#define MX51_PAD_EIM_A25__USBH2_DIR 0x0c0 0x454 0x000 0x2 0x0
+#define MX51_PAD_EIM_A26__CSI1_DATA_EN 0x0c4 0x458 0x9a0 0x5 0x0
+#define MX51_PAD_EIM_A26__DISP2_EXT_CLK 0x0c4 0x458 0x908 0x6 0x0
+#define MX51_PAD_EIM_A26__EIM_A26 0x0c4 0x458 0x000 0x0 0x0
+#define MX51_PAD_EIM_A26__GPIO2_20 0x0c4 0x458 0x000 0x1 0x0
+#define MX51_PAD_EIM_A26__USBH2_STP 0x0c4 0x458 0x000 0x2 0x0
+#define MX51_PAD_EIM_A27__CSI2_DATA_EN 0x0c8 0x45c 0x99c 0x5 0x0
+#define MX51_PAD_EIM_A27__DISP1_PIN1 0x0c8 0x45c 0x9a4 0x6 0x0
+#define MX51_PAD_EIM_A27__EIM_A27 0x0c8 0x45c 0x000 0x0 0x0
+#define MX51_PAD_EIM_A27__GPIO2_21 0x0c8 0x45c 0x000 0x1 0x0
+#define MX51_PAD_EIM_A27__USBH2_NXT 0x0c8 0x45c 0x000 0x2 0x0
+#define MX51_PAD_EIM_EB0__EIM_EB0 0x0cc 0x460 0x000 0x0 0x0
+#define MX51_PAD_EIM_EB1__EIM_EB1 0x0d0 0x464 0x000 0x0 0x0
+#define MX51_PAD_EIM_EB2__AUD5_RXFS 0x0d4 0x468 0x8e0 0x6 0x0
+#define MX51_PAD_EIM_EB2__CSI1_D2 0x0d4 0x468 0x000 0x5 0x0
+#define MX51_PAD_EIM_EB2__EIM_EB2 0x0d4 0x468 0x000 0x0 0x0
+#define MX51_PAD_EIM_EB2__FEC_MDIO 0x0d4 0x468 0x954 0x3 0x0
+#define MX51_PAD_EIM_EB2__GPIO2_22 0x0d4 0x468 0x000 0x1 0x0
+#define MX51_PAD_EIM_EB2__GPT_CMPOUT1 0x0d4 0x468 0x000 0x7 0x0
+#define MX51_PAD_EIM_EB3__AUD5_RXC 0x0d8 0x46c 0x8dc 0x6 0x0
+#define MX51_PAD_EIM_EB3__CSI1_D3 0x0d8 0x46c 0x000 0x5 0x0
+#define MX51_PAD_EIM_EB3__EIM_EB3 0x0d8 0x46c 0x000 0x0 0x0
+#define MX51_PAD_EIM_EB3__FEC_RDATA1 0x0d8 0x46c 0x95c 0x3 0x0
+#define MX51_PAD_EIM_EB3__GPIO2_23 0x0d8 0x46c 0x000 0x1 0x0
+#define MX51_PAD_EIM_EB3__GPT_CMPOUT2 0x0d8 0x46c 0x000 0x7 0x0
+#define MX51_PAD_EIM_OE__EIM_OE 0x0dc 0x470 0x000 0x0 0x0
+#define MX51_PAD_EIM_OE__GPIO2_24 0x0dc 0x470 0x000 0x1 0x0
+#define MX51_PAD_EIM_CS0__EIM_CS0 0x0e0 0x474 0x000 0x0 0x0
+#define MX51_PAD_EIM_CS0__GPIO2_25 0x0e0 0x474 0x000 0x1 0x0
+#define MX51_PAD_EIM_CS1__EIM_CS1 0x0e4 0x478 0x000 0x0 0x0
+#define MX51_PAD_EIM_CS1__GPIO2_26 0x0e4 0x478 0x000 0x1 0x0
+#define MX51_PAD_EIM_CS2__AUD5_TXD 0x0e8 0x47c 0x8d8 0x6 0x1
+#define MX51_PAD_EIM_CS2__CSI1_D4 0x0e8 0x47c 0x000 0x5 0x0
+#define MX51_PAD_EIM_CS2__EIM_CS2 0x0e8 0x47c 0x000 0x0 0x0
+#define MX51_PAD_EIM_CS2__FEC_RDATA2 0x0e8 0x47c 0x960 0x3 0x0
+#define MX51_PAD_EIM_CS2__GPIO2_27 0x0e8 0x47c 0x000 0x1 0x0
+#define MX51_PAD_EIM_CS2__USBOTG_STP 0x0e8 0x47c 0x000 0x2 0x0
+#define MX51_PAD_EIM_CS3__AUD5_RXD 0x0ec 0x480 0x8d4 0x6 0x1
+#define MX51_PAD_EIM_CS3__CSI1_D5 0x0ec 0x480 0x000 0x5 0x0
+#define MX51_PAD_EIM_CS3__EIM_CS3 0x0ec 0x480 0x000 0x0 0x0
+#define MX51_PAD_EIM_CS3__FEC_RDATA3 0x0ec 0x480 0x964 0x3 0x0
+#define MX51_PAD_EIM_CS3__GPIO2_28 0x0ec 0x480 0x000 0x1 0x0
+#define MX51_PAD_EIM_CS3__USBOTG_NXT 0x0ec 0x480 0x000 0x2 0x0
+#define MX51_PAD_EIM_CS4__AUD5_TXC 0x0f0 0x484 0x8e4 0x6 0x1
+#define MX51_PAD_EIM_CS4__CSI1_D6 0x0f0 0x484 0x000 0x5 0x0
+#define MX51_PAD_EIM_CS4__EIM_CS4 0x0f0 0x484 0x000 0x0 0x0
+#define MX51_PAD_EIM_CS4__FEC_RX_ER 0x0f0 0x484 0x970 0x3 0x0
+#define MX51_PAD_EIM_CS4__GPIO2_29 0x0f0 0x484 0x000 0x1 0x0
+#define MX51_PAD_EIM_CS4__USBOTG_CLK 0x0f0 0x484 0x000 0x2 0x0
+#define MX51_PAD_EIM_CS5__AUD5_TXFS 0x0f4 0x488 0x8e8 0x6 0x1
+#define MX51_PAD_EIM_CS5__CSI1_D7 0x0f4 0x488 0x000 0x5 0x0
+#define MX51_PAD_EIM_CS5__DISP1_EXT_CLK 0x0f4 0x488 0x904 0x4 0x0
+#define MX51_PAD_EIM_CS5__EIM_CS5 0x0f4 0x488 0x000 0x0 0x0
+#define MX51_PAD_EIM_CS5__FEC_CRS 0x0f4 0x488 0x950 0x3 0x0
+#define MX51_PAD_EIM_CS5__GPIO2_30 0x0f4 0x488 0x000 0x1 0x0
+#define MX51_PAD_EIM_CS5__USBOTG_DIR 0x0f4 0x488 0x000 0x2 0x0
+#define MX51_PAD_EIM_DTACK__EIM_DTACK 0x0f8 0x48c 0x000 0x0 0x0
+#define MX51_PAD_EIM_DTACK__GPIO2_31 0x0f8 0x48c 0x000 0x1 0x0
+#define MX51_PAD_EIM_LBA__EIM_LBA 0x0fc 0x494 0x000 0x0 0x0
+#define MX51_PAD_EIM_LBA__GPIO3_1 0x0fc 0x494 0x978 0x1 0x0
+#define MX51_PAD_EIM_CRE__EIM_CRE 0x100 0x4a0 0x000 0x0 0x0
+#define MX51_PAD_EIM_CRE__GPIO3_2 0x100 0x4a0 0x97c 0x1 0x0
+#define MX51_PAD_DRAM_CS1__DRAM_CS1 0x104 0x4d0 0x000 0x0 0x0
+#define MX51_PAD_NANDF_WE_B__GPIO3_3 0x108 0x4e4 0x980 0x3 0x0
+#define MX51_PAD_NANDF_WE_B__NANDF_WE_B 0x108 0x4e4 0x000 0x0 0x0
+#define MX51_PAD_NANDF_WE_B__PATA_DIOW 0x108 0x4e4 0x000 0x1 0x0
+#define MX51_PAD_NANDF_WE_B__SD3_DATA0 0x108 0x4e4 0x93c 0x2 0x0
+#define MX51_PAD_NANDF_RE_B__GPIO3_4 0x10c 0x4e8 0x984 0x3 0x0
+#define MX51_PAD_NANDF_RE_B__NANDF_RE_B 0x10c 0x4e8 0x000 0x0 0x0
+#define MX51_PAD_NANDF_RE_B__PATA_DIOR 0x10c 0x4e8 0x000 0x1 0x0
+#define MX51_PAD_NANDF_RE_B__SD3_DATA1 0x10c 0x4e8 0x940 0x2 0x0
+#define MX51_PAD_NANDF_ALE__GPIO3_5 0x110 0x4ec 0x988 0x3 0x0
+#define MX51_PAD_NANDF_ALE__NANDF_ALE 0x110 0x4ec 0x000 0x0 0x0
+#define MX51_PAD_NANDF_ALE__PATA_BUFFER_EN 0x110 0x4ec 0x000 0x1 0x0
+#define MX51_PAD_NANDF_CLE__GPIO3_6 0x114 0x4f0 0x98c 0x3 0x0
+#define MX51_PAD_NANDF_CLE__NANDF_CLE 0x114 0x4f0 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CLE__PATA_RESET_B 0x114 0x4f0 0x000 0x1 0x0
+#define MX51_PAD_NANDF_WP_B__GPIO3_7 0x118 0x4f4 0x990 0x3 0x0
+#define MX51_PAD_NANDF_WP_B__NANDF_WP_B 0x118 0x4f4 0x000 0x0 0x0
+#define MX51_PAD_NANDF_WP_B__PATA_DMACK 0x118 0x4f4 0x000 0x1 0x0
+#define MX51_PAD_NANDF_WP_B__SD3_DATA2 0x118 0x4f4 0x944 0x2 0x0
+#define MX51_PAD_NANDF_RB0__ECSPI2_SS1 0x11c 0x4f8 0x930 0x5 0x0
+#define MX51_PAD_NANDF_RB0__GPIO3_8 0x11c 0x4f8 0x994 0x3 0x0
+#define MX51_PAD_NANDF_RB0__NANDF_RB0 0x11c 0x4f8 0x000 0x0 0x0
+#define MX51_PAD_NANDF_RB0__PATA_DMARQ 0x11c 0x4f8 0x000 0x1 0x0
+#define MX51_PAD_NANDF_RB0__SD3_DATA3 0x11c 0x4f8 0x948 0x2 0x0
+#define MX51_PAD_NANDF_RB1__CSPI_MOSI 0x120 0x4fc 0x91c 0x6 0x0
+#define MX51_PAD_NANDF_RB1__ECSPI2_RDY 0x120 0x4fc 0x000 0x2 0x0
+#define MX51_PAD_NANDF_RB1__GPIO3_9 0x120 0x4fc 0x000 0x3 0x0
+#define MX51_PAD_NANDF_RB1__NANDF_RB1 0x120 0x4fc 0x000 0x0 0x0
+#define MX51_PAD_NANDF_RB1__PATA_IORDY 0x120 0x4fc 0x000 0x1 0x0
+#define MX51_PAD_NANDF_RB1__SD4_CMD 0x120 0x4fc 0x000 0x5 0x0
+#define MX51_PAD_NANDF_RB2__DISP2_WAIT 0x124 0x500 0x9a8 0x5 0x0
+#define MX51_PAD_NANDF_RB2__ECSPI2_SCLK 0x124 0x500 0x000 0x2 0x0
+#define MX51_PAD_NANDF_RB2__FEC_COL 0x124 0x500 0x94c 0x1 0x0
+#define MX51_PAD_NANDF_RB2__GPIO3_10 0x124 0x500 0x000 0x3 0x0
+#define MX51_PAD_NANDF_RB2__NANDF_RB2 0x124 0x500 0x000 0x0 0x0
+#define MX51_PAD_NANDF_RB2__USBH3_H3_DP 0x124 0x500 0x000 0x7 0x0
+#define MX51_PAD_NANDF_RB2__USBH3_NXT 0x124 0x500 0xa20 0x6 0x0
+#define MX51_PAD_NANDF_RB3__DISP1_WAIT 0x128 0x504 0x000 0x5 0x0
+#define MX51_PAD_NANDF_RB3__ECSPI2_MISO 0x128 0x504 0x000 0x2 0x0
+#define MX51_PAD_NANDF_RB3__FEC_RX_CLK 0x128 0x504 0x968 0x1 0x0
+#define MX51_PAD_NANDF_RB3__GPIO3_11 0x128 0x504 0x000 0x3 0x0
+#define MX51_PAD_NANDF_RB3__NANDF_RB3 0x128 0x504 0x000 0x0 0x0
+#define MX51_PAD_NANDF_RB3__USBH3_CLK 0x128 0x504 0x9f8 0x6 0x0
+#define MX51_PAD_NANDF_RB3__USBH3_H3_DM 0x128 0x504 0x000 0x7 0x0
+#define MX51_PAD_GPIO_NAND__GPIO_NAND 0x12c 0x514 0x998 0x0 0x0
+#define MX51_PAD_GPIO_NAND__PATA_INTRQ 0x12c 0x514 0x000 0x1 0x0
+#define MX51_PAD_NANDF_CS0__GPIO3_16 0x130 0x518 0x000 0x3 0x0
+#define MX51_PAD_NANDF_CS0__NANDF_CS0 0x130 0x518 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CS1__GPIO3_17 0x134 0x51c 0x000 0x3 0x0
+#define MX51_PAD_NANDF_CS1__NANDF_CS1 0x134 0x51c 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CS2__CSPI_SCLK 0x138 0x520 0x914 0x6 0x0
+#define MX51_PAD_NANDF_CS2__FEC_TX_ER 0x138 0x520 0x000 0x2 0x0
+#define MX51_PAD_NANDF_CS2__GPIO3_18 0x138 0x520 0x000 0x3 0x0
+#define MX51_PAD_NANDF_CS2__NANDF_CS2 0x138 0x520 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CS2__PATA_CS_0 0x138 0x520 0x000 0x1 0x0
+#define MX51_PAD_NANDF_CS2__SD4_CLK 0x138 0x520 0x000 0x5 0x0
+#define MX51_PAD_NANDF_CS2__USBH3_H1_DP 0x138 0x520 0x000 0x7 0x0
+#define MX51_PAD_NANDF_CS3__FEC_MDC 0x13c 0x524 0x000 0x2 0x0
+#define MX51_PAD_NANDF_CS3__GPIO3_19 0x13c 0x524 0x000 0x3 0x0
+#define MX51_PAD_NANDF_CS3__NANDF_CS3 0x13c 0x524 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CS3__PATA_CS_1 0x13c 0x524 0x000 0x1 0x0
+#define MX51_PAD_NANDF_CS3__SD4_DAT0 0x13c 0x524 0x000 0x5 0x0
+#define MX51_PAD_NANDF_CS3__USBH3_H1_DM 0x13c 0x524 0x000 0x7 0x0
+#define MX51_PAD_NANDF_CS4__FEC_TDATA1 0x140 0x528 0x000 0x2 0x0
+#define MX51_PAD_NANDF_CS4__GPIO3_20 0x140 0x528 0x000 0x3 0x0
+#define MX51_PAD_NANDF_CS4__NANDF_CS4 0x140 0x528 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CS4__PATA_DA_0 0x140 0x528 0x000 0x1 0x0
+#define MX51_PAD_NANDF_CS4__SD4_DAT1 0x140 0x528 0x000 0x5 0x0
+#define MX51_PAD_NANDF_CS4__USBH3_STP 0x140 0x528 0xa24 0x7 0x0
+#define MX51_PAD_NANDF_CS5__FEC_TDATA2 0x144 0x52c 0x000 0x2 0x0
+#define MX51_PAD_NANDF_CS5__GPIO3_21 0x144 0x52c 0x000 0x3 0x0
+#define MX51_PAD_NANDF_CS5__NANDF_CS5 0x144 0x52c 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CS5__PATA_DA_1 0x144 0x52c 0x000 0x1 0x0
+#define MX51_PAD_NANDF_CS5__SD4_DAT2 0x144 0x52c 0x000 0x5 0x0
+#define MX51_PAD_NANDF_CS5__USBH3_DIR 0x144 0x52c 0xa1c 0x7 0x0
+#define MX51_PAD_NANDF_CS6__CSPI_SS3 0x148 0x530 0x928 0x7 0x0
+#define MX51_PAD_NANDF_CS6__FEC_TDATA3 0x148 0x530 0x000 0x2 0x0
+#define MX51_PAD_NANDF_CS6__GPIO3_22 0x148 0x530 0x000 0x3 0x0
+#define MX51_PAD_NANDF_CS6__NANDF_CS6 0x148 0x530 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CS6__PATA_DA_2 0x148 0x530 0x000 0x1 0x0
+#define MX51_PAD_NANDF_CS6__SD4_DAT3 0x148 0x530 0x000 0x5 0x0
+#define MX51_PAD_NANDF_CS7__FEC_TX_EN 0x14c 0x534 0x000 0x1 0x0
+#define MX51_PAD_NANDF_CS7__GPIO3_23 0x14c 0x534 0x000 0x3 0x0
+#define MX51_PAD_NANDF_CS7__NANDF_CS7 0x14c 0x534 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CS7__SD3_CLK 0x14c 0x534 0x000 0x5 0x0
+#define MX51_PAD_NANDF_RDY_INT__ECSPI2_SS0 0x150 0x538 0x000 0x2 0x0
+#define MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK 0x150 0x538 0x974 0x1 0x0
+#define MX51_PAD_NANDF_RDY_INT__GPIO3_24 0x150 0x538 0x000 0x3 0x0
+#define MX51_PAD_NANDF_RDY_INT__NANDF_RDY_INT 0x150 0x538 0x938 0x0 0x0
+#define MX51_PAD_NANDF_RDY_INT__SD3_CMD 0x150 0x538 0x000 0x5 0x0
+#define MX51_PAD_NANDF_D15__ECSPI2_MOSI 0x154 0x53c 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D15__GPIO3_25 0x154 0x53c 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D15__NANDF_D15 0x154 0x53c 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D15__PATA_DATA15 0x154 0x53c 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D15__SD3_DAT7 0x154 0x53c 0x000 0x5 0x0
+#define MX51_PAD_NANDF_D14__ECSPI2_SS3 0x158 0x540 0x934 0x2 0x0
+#define MX51_PAD_NANDF_D14__GPIO3_26 0x158 0x540 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D14__NANDF_D14 0x158 0x540 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D14__PATA_DATA14 0x158 0x540 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D14__SD3_DAT6 0x158 0x540 0x000 0x5 0x0
+#define MX51_PAD_NANDF_D13__ECSPI2_SS2 0x15c 0x544 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D13__GPIO3_27 0x15c 0x544 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D13__NANDF_D13 0x15c 0x544 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D13__PATA_DATA13 0x15c 0x544 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D13__SD3_DAT5 0x15c 0x544 0x000 0x5 0x0
+#define MX51_PAD_NANDF_D12__ECSPI2_SS1 0x160 0x548 0x930 0x2 0x1
+#define MX51_PAD_NANDF_D12__GPIO3_28 0x160 0x548 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D12__NANDF_D12 0x160 0x548 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D12__PATA_DATA12 0x160 0x548 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D12__SD3_DAT4 0x160 0x548 0x000 0x5 0x0
+#define MX51_PAD_NANDF_D11__FEC_RX_DV 0x164 0x54c 0x96c 0x2 0x0
+#define MX51_PAD_NANDF_D11__GPIO3_29 0x164 0x54c 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D11__NANDF_D11 0x164 0x54c 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D11__PATA_DATA11 0x164 0x54c 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D11__SD3_DATA3 0x164 0x54c 0x948 0x5 0x1
+#define MX51_PAD_NANDF_D10__GPIO3_30 0x168 0x550 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D10__NANDF_D10 0x168 0x550 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D10__PATA_DATA10 0x168 0x550 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D10__SD3_DATA2 0x168 0x550 0x944 0x5 0x1
+#define MX51_PAD_NANDF_D9__FEC_RDATA0 0x16c 0x554 0x958 0x2 0x0
+#define MX51_PAD_NANDF_D9__GPIO3_31 0x16c 0x554 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D9__NANDF_D9 0x16c 0x554 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D9__PATA_DATA9 0x16c 0x554 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D9__SD3_DATA1 0x16c 0x554 0x940 0x5 0x1
+#define MX51_PAD_NANDF_D8__FEC_TDATA0 0x170 0x558 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D8__GPIO4_0 0x170 0x558 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D8__NANDF_D8 0x170 0x558 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D8__PATA_DATA8 0x170 0x558 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D8__SD3_DATA0 0x170 0x558 0x93c 0x5 0x1
+#define MX51_PAD_NANDF_D7__GPIO4_1 0x174 0x55c 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D7__NANDF_D7 0x174 0x55c 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D7__PATA_DATA7 0x174 0x55c 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D7__USBH3_DATA0 0x174 0x55c 0x9fc 0x5 0x0
+#define MX51_PAD_NANDF_D6__GPIO4_2 0x178 0x560 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D6__NANDF_D6 0x178 0x560 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D6__PATA_DATA6 0x178 0x560 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D6__SD4_LCTL 0x178 0x560 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D6__USBH3_DATA1 0x178 0x560 0xa00 0x5 0x0
+#define MX51_PAD_NANDF_D5__GPIO4_3 0x17c 0x564 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D5__NANDF_D5 0x17c 0x564 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D5__PATA_DATA5 0x17c 0x564 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D5__SD4_WP 0x17c 0x564 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D5__USBH3_DATA2 0x17c 0x564 0xa04 0x5 0x0
+#define MX51_PAD_NANDF_D4__GPIO4_4 0x180 0x568 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D4__NANDF_D4 0x180 0x568 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D4__PATA_DATA4 0x180 0x568 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D4__SD4_CD 0x180 0x568 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D4__USBH3_DATA3 0x180 0x568 0xa08 0x5 0x0
+#define MX51_PAD_NANDF_D3__GPIO4_5 0x184 0x56c 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D3__NANDF_D3 0x184 0x56c 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D3__PATA_DATA3 0x184 0x56c 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D3__SD4_DAT4 0x184 0x56c 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D3__USBH3_DATA4 0x184 0x56c 0xa0c 0x5 0x0
+#define MX51_PAD_NANDF_D2__GPIO4_6 0x188 0x570 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D2__NANDF_D2 0x188 0x570 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D2__PATA_DATA2 0x188 0x570 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D2__SD4_DAT5 0x188 0x570 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D2__USBH3_DATA5 0x188 0x570 0xa10 0x5 0x0
+#define MX51_PAD_NANDF_D1__GPIO4_7 0x18c 0x574 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D1__NANDF_D1 0x18c 0x574 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D1__PATA_DATA1 0x18c 0x574 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D1__SD4_DAT6 0x18c 0x574 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D1__USBH3_DATA6 0x18c 0x574 0xa14 0x5 0x0
+#define MX51_PAD_NANDF_D0__GPIO4_8 0x190 0x578 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D0__NANDF_D0 0x190 0x578 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D0__PATA_DATA0 0x190 0x578 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D0__SD4_DAT7 0x190 0x578 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D0__USBH3_DATA7 0x190 0x578 0xa18 0x5 0x0
+#define MX51_PAD_CSI1_D8__CSI1_D8 0x194 0x57c 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D8__GPIO3_12 0x194 0x57c 0x998 0x3 0x1
+#define MX51_PAD_CSI1_D9__CSI1_D9 0x198 0x580 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D9__GPIO3_13 0x198 0x580 0x000 0x3 0x0
+#define MX51_PAD_CSI1_D10__CSI1_D10 0x19c 0x584 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D11__CSI1_D11 0x1a0 0x588 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D12__CSI1_D12 0x1a4 0x58c 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D13__CSI1_D13 0x1a8 0x590 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D14__CSI1_D14 0x1ac 0x594 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D15__CSI1_D15 0x1b0 0x598 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D16__CSI1_D16 0x1b4 0x59c 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D17__CSI1_D17 0x1b8 0x5a0 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D18__CSI1_D18 0x1bc 0x5a4 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D19__CSI1_D19 0x1c0 0x5a8 0x000 0x0 0x0
+#define MX51_PAD_CSI1_VSYNC__CSI1_VSYNC 0x1c4 0x5ac 0x000 0x0 0x0
+#define MX51_PAD_CSI1_VSYNC__GPIO3_14 0x1c4 0x5ac 0x000 0x3 0x0
+#define MX51_PAD_CSI1_HSYNC__CSI1_HSYNC 0x1c8 0x5b0 0x000 0x0 0x0
+#define MX51_PAD_CSI1_HSYNC__GPIO3_15 0x1c8 0x5b0 0x000 0x3 0x0
+#define MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK 0x000 0x5b4 0x000 0x0 0x0
+#define MX51_PAD_CSI1_MCLK__CSI1_MCLK 0x000 0x5b8 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D12__CSI2_D12 0x1cc 0x5bc 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D12__GPIO4_9 0x1cc 0x5bc 0x000 0x3 0x0
+#define MX51_PAD_CSI2_D13__CSI2_D13 0x1d0 0x5c0 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D13__GPIO4_10 0x1d0 0x5c0 0x000 0x3 0x0
+#define MX51_PAD_CSI2_D14__CSI2_D14 0x1d4 0x5c4 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D15__CSI2_D15 0x1d8 0x5c8 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D16__CSI2_D16 0x1dc 0x5cc 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D17__CSI2_D17 0x1e0 0x5d0 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D18__CSI2_D18 0x1e4 0x5d4 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D18__GPIO4_11 0x1e4 0x5d4 0x000 0x3 0x0
+#define MX51_PAD_CSI2_D19__CSI2_D19 0x1e8 0x5d8 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D19__GPIO4_12 0x1e8 0x5d8 0x000 0x3 0x0
+#define MX51_PAD_CSI2_VSYNC__CSI2_VSYNC 0x1ec 0x5dc 0x000 0x0 0x0
+#define MX51_PAD_CSI2_VSYNC__GPIO4_13 0x1ec 0x5dc 0x000 0x3 0x0
+#define MX51_PAD_CSI2_HSYNC__CSI2_HSYNC 0x1f0 0x5e0 0x000 0x0 0x0
+#define MX51_PAD_CSI2_HSYNC__GPIO4_14 0x1f0 0x5e0 0x000 0x3 0x0
+#define MX51_PAD_CSI2_PIXCLK__CSI2_PIXCLK 0x1f4 0x5e4 0x000 0x0 0x0
+#define MX51_PAD_CSI2_PIXCLK__GPIO4_15 0x1f4 0x5e4 0x000 0x3 0x0
+#define MX51_PAD_I2C1_CLK__GPIO4_16 0x1f8 0x5e8 0x000 0x3 0x0
+#define MX51_PAD_I2C1_CLK__I2C1_CLK 0x1f8 0x5e8 0x000 0x0 0x0
+#define MX51_PAD_I2C1_DAT__GPIO4_17 0x1fc 0x5ec 0x000 0x3 0x0
+#define MX51_PAD_I2C1_DAT__I2C1_DAT 0x1fc 0x5ec 0x000 0x0 0x0
+#define MX51_PAD_AUD3_BB_TXD__AUD3_TXD 0x200 0x5f0 0x000 0x0 0x0
+#define MX51_PAD_AUD3_BB_TXD__GPIO4_18 0x200 0x5f0 0x000 0x3 0x0
+#define MX51_PAD_AUD3_BB_RXD__AUD3_RXD 0x204 0x5f4 0x000 0x0 0x0
+#define MX51_PAD_AUD3_BB_RXD__GPIO4_19 0x204 0x5f4 0x000 0x3 0x0
+#define MX51_PAD_AUD3_BB_RXD__UART3_RXD 0x204 0x5f4 0x9f4 0x1 0x2
+#define MX51_PAD_AUD3_BB_CK__AUD3_TXC 0x208 0x5f8 0x000 0x0 0x0
+#define MX51_PAD_AUD3_BB_CK__GPIO4_20 0x208 0x5f8 0x000 0x3 0x0
+#define MX51_PAD_AUD3_BB_FS__AUD3_TXFS 0x20c 0x5fc 0x000 0x0 0x0
+#define MX51_PAD_AUD3_BB_FS__GPIO4_21 0x20c 0x5fc 0x000 0x3 0x0
+#define MX51_PAD_AUD3_BB_FS__UART3_TXD 0x20c 0x5fc 0x000 0x1 0x0
+#define MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI 0x210 0x600 0x000 0x0 0x0
+#define MX51_PAD_CSPI1_MOSI__GPIO4_22 0x210 0x600 0x000 0x3 0x0
+#define MX51_PAD_CSPI1_MOSI__I2C1_SDA 0x210 0x600 0x9b4 0x1 0x1
+#define MX51_PAD_CSPI1_MISO__AUD4_RXD 0x214 0x604 0x8c4 0x1 0x1
+#define MX51_PAD_CSPI1_MISO__ECSPI1_MISO 0x214 0x604 0x000 0x0 0x0
+#define MX51_PAD_CSPI1_MISO__GPIO4_23 0x214 0x604 0x000 0x3 0x0
+#define MX51_PAD_CSPI1_SS0__AUD4_TXC 0x218 0x608 0x8cc 0x1 0x1
+#define MX51_PAD_CSPI1_SS0__ECSPI1_SS0 0x218 0x608 0x000 0x0 0x0
+#define MX51_PAD_CSPI1_SS0__GPIO4_24 0x218 0x608 0x000 0x3 0x0
+#define MX51_PAD_CSPI1_SS1__AUD4_TXD 0x21c 0x60c 0x8c8 0x1 0x1
+#define MX51_PAD_CSPI1_SS1__ECSPI1_SS1 0x21c 0x60c 0x000 0x0 0x0
+#define MX51_PAD_CSPI1_SS1__GPIO4_25 0x21c 0x60c 0x000 0x3 0x0
+#define MX51_PAD_CSPI1_RDY__AUD4_TXFS 0x220 0x610 0x8d0 0x1 0x1
+#define MX51_PAD_CSPI1_RDY__ECSPI1_RDY 0x220 0x610 0x000 0x0 0x0
+#define MX51_PAD_CSPI1_RDY__GPIO4_26 0x220 0x610 0x000 0x3 0x0
+#define MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK 0x224 0x614 0x000 0x0 0x0
+#define MX51_PAD_CSPI1_SCLK__GPIO4_27 0x224 0x614 0x000 0x3 0x0
+#define MX51_PAD_CSPI1_SCLK__I2C1_SCL 0x224 0x614 0x9b0 0x1 0x1
+#define MX51_PAD_UART1_RXD__GPIO4_28 0x228 0x618 0x000 0x3 0x0
+#define MX51_PAD_UART1_RXD__UART1_RXD 0x228 0x618 0x9e4 0x0 0x0
+#define MX51_PAD_UART1_TXD__GPIO4_29 0x22c 0x61c 0x000 0x3 0x0
+#define MX51_PAD_UART1_TXD__PWM2_PWMO 0x22c 0x61c 0x000 0x1 0x0
+#define MX51_PAD_UART1_TXD__UART1_TXD 0x22c 0x61c 0x000 0x0 0x0
+#define MX51_PAD_UART1_RTS__GPIO4_30 0x230 0x620 0x000 0x3 0x0
+#define MX51_PAD_UART1_RTS__UART1_RTS 0x230 0x620 0x9e0 0x0 0x0
+#define MX51_PAD_UART1_CTS__GPIO4_31 0x234 0x624 0x000 0x3 0x0
+#define MX51_PAD_UART1_CTS__UART1_CTS 0x234 0x624 0x000 0x0 0x0
+#define MX51_PAD_UART2_RXD__FIRI_TXD 0x238 0x628 0x000 0x1 0x0
+#define MX51_PAD_UART2_RXD__GPIO1_20 0x238 0x628 0x000 0x3 0x0
+#define MX51_PAD_UART2_RXD__UART2_RXD 0x238 0x628 0x9ec 0x0 0x2
+#define MX51_PAD_UART2_TXD__FIRI_RXD 0x23c 0x62c 0x000 0x1 0x0
+#define MX51_PAD_UART2_TXD__GPIO1_21 0x23c 0x62c 0x000 0x3 0x0
+#define MX51_PAD_UART2_TXD__UART2_TXD 0x23c 0x62c 0x000 0x0 0x0
+#define MX51_PAD_UART3_RXD__CSI1_D0 0x240 0x630 0x000 0x2 0x0
+#define MX51_PAD_UART3_RXD__GPIO1_22 0x240 0x630 0x000 0x3 0x0
+#define MX51_PAD_UART3_RXD__UART1_DTR 0x240 0x630 0x000 0x0 0x0
+#define MX51_PAD_UART3_RXD__UART3_RXD 0x240 0x630 0x9f4 0x1 0x4
+#define MX51_PAD_UART3_TXD__CSI1_D1 0x244 0x634 0x000 0x2 0x0
+#define MX51_PAD_UART3_TXD__GPIO1_23 0x244 0x634 0x000 0x3 0x0
+#define MX51_PAD_UART3_TXD__UART1_DSR 0x244 0x634 0x000 0x0 0x0
+#define MX51_PAD_UART3_TXD__UART3_TXD 0x244 0x634 0x000 0x1 0x0
+#define MX51_PAD_OWIRE_LINE__GPIO1_24 0x248 0x638 0x000 0x3 0x0
+#define MX51_PAD_OWIRE_LINE__OWIRE_LINE 0x248 0x638 0x000 0x0 0x0
+#define MX51_PAD_OWIRE_LINE__SPDIF_OUT 0x248 0x638 0x000 0x6 0x0
+#define MX51_PAD_KEY_ROW0__KEY_ROW0 0x24c 0x63c 0x000 0x0 0x0
+#define MX51_PAD_KEY_ROW1__KEY_ROW1 0x250 0x640 0x000 0x0 0x0
+#define MX51_PAD_KEY_ROW2__KEY_ROW2 0x254 0x644 0x000 0x0 0x0
+#define MX51_PAD_KEY_ROW3__KEY_ROW3 0x258 0x648 0x000 0x0 0x0
+#define MX51_PAD_KEY_COL0__KEY_COL0 0x25c 0x64c 0x000 0x0 0x0
+#define MX51_PAD_KEY_COL0__PLL1_BYP 0x25c 0x64c 0x90c 0x7 0x0
+#define MX51_PAD_KEY_COL1__KEY_COL1 0x260 0x650 0x000 0x0 0x0
+#define MX51_PAD_KEY_COL1__PLL2_BYP 0x260 0x650 0x910 0x7 0x0
+#define MX51_PAD_KEY_COL2__KEY_COL2 0x264 0x654 0x000 0x0 0x0
+#define MX51_PAD_KEY_COL2__PLL3_BYP 0x264 0x654 0x000 0x7 0x0
+#define MX51_PAD_KEY_COL3__KEY_COL3 0x268 0x658 0x000 0x0 0x0
+#define MX51_PAD_KEY_COL4__I2C2_SCL 0x26c 0x65c 0x9b8 0x3 0x1
+#define MX51_PAD_KEY_COL4__KEY_COL4 0x26c 0x65c 0x000 0x0 0x0
+#define MX51_PAD_KEY_COL4__SPDIF_OUT1 0x26c 0x65c 0x000 0x6 0x0
+#define MX51_PAD_KEY_COL4__UART1_RI 0x26c 0x65c 0x000 0x1 0x0
+#define MX51_PAD_KEY_COL4__UART3_RTS 0x26c 0x65c 0x9f0 0x2 0x4
+#define MX51_PAD_KEY_COL5__I2C2_SDA 0x270 0x660 0x9bc 0x3 0x1
+#define MX51_PAD_KEY_COL5__KEY_COL5 0x270 0x660 0x000 0x0 0x0
+#define MX51_PAD_KEY_COL5__UART1_DCD 0x270 0x660 0x000 0x1 0x0
+#define MX51_PAD_KEY_COL5__UART3_CTS 0x270 0x660 0x000 0x2 0x0
+#define MX51_PAD_USBH1_CLK__CSPI_SCLK 0x278 0x678 0x914 0x1 0x1
+#define MX51_PAD_USBH1_CLK__GPIO1_25 0x278 0x678 0x000 0x2 0x0
+#define MX51_PAD_USBH1_CLK__I2C2_SCL 0x278 0x678 0x9b8 0x5 0x2
+#define MX51_PAD_USBH1_CLK__USBH1_CLK 0x278 0x678 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DIR__CSPI_MOSI 0x27c 0x67c 0x91c 0x1 0x1
+#define MX51_PAD_USBH1_DIR__GPIO1_26 0x27c 0x67c 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DIR__I2C2_SDA 0x27c 0x67c 0x9bc 0x5 0x2
+#define MX51_PAD_USBH1_DIR__USBH1_DIR 0x27c 0x67c 0x000 0x0 0x0
+#define MX51_PAD_USBH1_STP__CSPI_RDY 0x280 0x680 0x000 0x1 0x0
+#define MX51_PAD_USBH1_STP__GPIO1_27 0x280 0x680 0x000 0x2 0x0
+#define MX51_PAD_USBH1_STP__UART3_RXD 0x280 0x680 0x9f4 0x5 0x6
+#define MX51_PAD_USBH1_STP__USBH1_STP 0x280 0x680 0x000 0x0 0x0
+#define MX51_PAD_USBH1_NXT__CSPI_MISO 0x284 0x684 0x918 0x1 0x0
+#define MX51_PAD_USBH1_NXT__GPIO1_28 0x284 0x684 0x000 0x2 0x0
+#define MX51_PAD_USBH1_NXT__UART3_TXD 0x284 0x684 0x000 0x5 0x0
+#define MX51_PAD_USBH1_NXT__USBH1_NXT 0x284 0x684 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DATA0__GPIO1_11 0x288 0x688 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DATA0__UART2_CTS 0x288 0x688 0x000 0x1 0x0
+#define MX51_PAD_USBH1_DATA0__USBH1_DATA0 0x288 0x688 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DATA1__GPIO1_12 0x28c 0x68c 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DATA1__UART2_RXD 0x28c 0x68c 0x9ec 0x1 0x4
+#define MX51_PAD_USBH1_DATA1__USBH1_DATA1 0x28c 0x68c 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DATA2__GPIO1_13 0x290 0x690 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DATA2__UART2_TXD 0x290 0x690 0x000 0x1 0x0
+#define MX51_PAD_USBH1_DATA2__USBH1_DATA2 0x290 0x690 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DATA3__GPIO1_14 0x294 0x694 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DATA3__UART2_RTS 0x294 0x694 0x9e8 0x1 0x5
+#define MX51_PAD_USBH1_DATA3__USBH1_DATA3 0x294 0x694 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DATA4__CSPI_SS0 0x298 0x698 0x000 0x1 0x0
+#define MX51_PAD_USBH1_DATA4__GPIO1_15 0x298 0x698 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DATA4__USBH1_DATA4 0x298 0x698 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DATA5__CSPI_SS1 0x29c 0x69c 0x920 0x1 0x0
+#define MX51_PAD_USBH1_DATA5__GPIO1_16 0x29c 0x69c 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DATA5__USBH1_DATA5 0x29c 0x69c 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DATA6__CSPI_SS3 0x2a0 0x6a0 0x928 0x1 0x1
+#define MX51_PAD_USBH1_DATA6__GPIO1_17 0x2a0 0x6a0 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DATA6__USBH1_DATA6 0x2a0 0x6a0 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DATA7__ECSPI1_SS3 0x2a4 0x6a4 0x000 0x1 0x0
+#define MX51_PAD_USBH1_DATA7__ECSPI2_SS3 0x2a4 0x6a4 0x934 0x5 0x1
+#define MX51_PAD_USBH1_DATA7__GPIO1_18 0x2a4 0x6a4 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DATA7__USBH1_DATA7 0x2a4 0x6a4 0x000 0x0 0x0
+#define MX51_PAD_DI1_PIN11__DI1_PIN11 0x2a8 0x6a8 0x000 0x0 0x0
+#define MX51_PAD_DI1_PIN11__ECSPI1_SS2 0x2a8 0x6a8 0x000 0x7 0x0
+#define MX51_PAD_DI1_PIN11__GPIO3_0 0x2a8 0x6a8 0x000 0x4 0x0
+#define MX51_PAD_DI1_PIN12__DI1_PIN12 0x2ac 0x6ac 0x000 0x0 0x0
+#define MX51_PAD_DI1_PIN12__GPIO3_1 0x2ac 0x6ac 0x978 0x4 0x1
+#define MX51_PAD_DI1_PIN13__DI1_PIN13 0x2b0 0x6b0 0x000 0x0 0x0
+#define MX51_PAD_DI1_PIN13__GPIO3_2 0x2b0 0x6b0 0x97c 0x4 0x1
+#define MX51_PAD_DI1_D0_CS__DI1_D0_CS 0x2b4 0x6b4 0x000 0x0 0x0
+#define MX51_PAD_DI1_D0_CS__GPIO3_3 0x2b4 0x6b4 0x980 0x4 0x1
+#define MX51_PAD_DI1_D1_CS__DI1_D1_CS 0x2b8 0x6b8 0x000 0x0 0x0
+#define MX51_PAD_DI1_D1_CS__DISP1_PIN14 0x2b8 0x6b8 0x000 0x2 0x0
+#define MX51_PAD_DI1_D1_CS__DISP1_PIN5 0x2b8 0x6b8 0x000 0x3 0x0
+#define MX51_PAD_DI1_D1_CS__GPIO3_4 0x2b8 0x6b8 0x984 0x4 0x1
+#define MX51_PAD_DISPB2_SER_DIN__DISP1_PIN1 0x2bc 0x6bc 0x9a4 0x2 0x1
+#define MX51_PAD_DISPB2_SER_DIN__DISPB2_SER_DIN 0x2bc 0x6bc 0x9c4 0x0 0x0
+#define MX51_PAD_DISPB2_SER_DIN__GPIO3_5 0x2bc 0x6bc 0x988 0x4 0x1
+#define MX51_PAD_DISPB2_SER_DIO__DISP1_PIN6 0x2c0 0x6c0 0x000 0x3 0x0
+#define MX51_PAD_DISPB2_SER_DIO__DISPB2_SER_DIO 0x2c0 0x6c0 0x9c4 0x0 0x1
+#define MX51_PAD_DISPB2_SER_DIO__GPIO3_6 0x2c0 0x6c0 0x98c 0x4 0x1
+#define MX51_PAD_DISPB2_SER_CLK__DISP1_PIN17 0x2c4 0x6c4 0x000 0x2 0x0
+#define MX51_PAD_DISPB2_SER_CLK__DISP1_PIN7 0x2c4 0x6c4 0x000 0x3 0x0
+#define MX51_PAD_DISPB2_SER_CLK__DISPB2_SER_CLK 0x2c4 0x6c4 0x000 0x0 0x0
+#define MX51_PAD_DISPB2_SER_CLK__GPIO3_7 0x2c4 0x6c4 0x990 0x4 0x1
+#define MX51_PAD_DISPB2_SER_RS__DISP1_EXT_CLK 0x2c8 0x6c8 0x000 0x2 0x0
+#define MX51_PAD_DISPB2_SER_RS__DISP1_PIN16 0x2c8 0x6c8 0x000 0x2 0x0
+#define MX51_PAD_DISPB2_SER_RS__DISP1_PIN8 0x2c8 0x6c8 0x000 0x3 0x0
+#define MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS 0x2c8 0x6c8 0x000 0x0 0x0
+#define MX51_PAD_DISPB2_SER_RS__GPIO3_8 0x2c8 0x6c8 0x994 0x4 0x1
+#define MX51_PAD_DISP1_DAT0__DISP1_DAT0 0x2cc 0x6cc 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT1__DISP1_DAT1 0x2d0 0x6d0 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT2__DISP1_DAT2 0x2d4 0x6d4 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT3__DISP1_DAT3 0x2d8 0x6d8 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT4__DISP1_DAT4 0x2dc 0x6dc 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT5__DISP1_DAT5 0x2e0 0x6e0 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT6__BOOT_USB_SRC 0x2e4 0x6e4 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT6__DISP1_DAT6 0x2e4 0x6e4 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT7__BOOT_EEPROM_CFG 0x2e8 0x6e8 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT7__DISP1_DAT7 0x2e8 0x6e8 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT8__BOOT_SRC0 0x2ec 0x6ec 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT8__DISP1_DAT8 0x2ec 0x6ec 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT9__BOOT_SRC1 0x2f0 0x6f0 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT9__DISP1_DAT9 0x2f0 0x6f0 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT10__BOOT_SPARE_SIZE 0x2f4 0x6f4 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT10__DISP1_DAT10 0x2f4 0x6f4 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT11__BOOT_LPB_FREQ2 0x2f8 0x6f8 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT11__DISP1_DAT11 0x2f8 0x6f8 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT12__BOOT_MLC_SEL 0x2fc 0x6fc 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT12__DISP1_DAT12 0x2fc 0x6fc 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT13__BOOT_MEM_CTL0 0x300 0x700 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT13__DISP1_DAT13 0x300 0x700 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT14__BOOT_MEM_CTL1 0x304 0x704 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT14__DISP1_DAT14 0x304 0x704 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT15__BOOT_BUS_WIDTH 0x308 0x708 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT15__DISP1_DAT15 0x308 0x708 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT16__BOOT_PAGE_SIZE0 0x30c 0x70c 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT16__DISP1_DAT16 0x30c 0x70c 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT17__BOOT_PAGE_SIZE1 0x310 0x710 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT17__DISP1_DAT17 0x310 0x710 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT18__BOOT_WEIM_MUXED0 0x314 0x714 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT18__DISP1_DAT18 0x314 0x714 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT18__DISP2_PIN11 0x314 0x714 0x000 0x5 0x0
+#define MX51_PAD_DISP1_DAT18__DISP2_PIN5 0x314 0x714 0x000 0x4 0x0
+#define MX51_PAD_DISP1_DAT19__BOOT_WEIM_MUXED1 0x318 0x718 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT19__DISP1_DAT19 0x318 0x718 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT19__DISP2_PIN12 0x318 0x718 0x000 0x5 0x0
+#define MX51_PAD_DISP1_DAT19__DISP2_PIN6 0x318 0x718 0x000 0x4 0x0
+#define MX51_PAD_DISP1_DAT20__BOOT_MEM_TYPE0 0x31c 0x71c 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT20__DISP1_DAT20 0x31c 0x71c 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT20__DISP2_PIN13 0x31c 0x71c 0x000 0x5 0x0
+#define MX51_PAD_DISP1_DAT20__DISP2_PIN7 0x31c 0x71c 0x000 0x4 0x0
+#define MX51_PAD_DISP1_DAT21__BOOT_MEM_TYPE1 0x320 0x720 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT21__DISP1_DAT21 0x320 0x720 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT21__DISP2_PIN14 0x320 0x720 0x000 0x5 0x0
+#define MX51_PAD_DISP1_DAT21__DISP2_PIN8 0x320 0x720 0x000 0x4 0x0
+#define MX51_PAD_DISP1_DAT22__BOOT_LPB_FREQ0 0x324 0x724 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT22__DISP1_DAT22 0x324 0x724 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT22__DISP2_D0_CS 0x324 0x724 0x000 0x6 0x0
+#define MX51_PAD_DISP1_DAT22__DISP2_DAT16 0x324 0x724 0x000 0x5 0x0
+#define MX51_PAD_DISP1_DAT23__BOOT_LPB_FREQ1 0x328 0x728 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT23__DISP1_DAT23 0x328 0x728 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT23__DISP2_D1_CS 0x328 0x728 0x000 0x6 0x0
+#define MX51_PAD_DISP1_DAT23__DISP2_DAT17 0x328 0x728 0x000 0x5 0x0
+#define MX51_PAD_DISP1_DAT23__DISP2_SER_CS 0x328 0x728 0x000 0x4 0x0
+#define MX51_PAD_DI1_PIN3__DI1_PIN3 0x32c 0x72c 0x000 0x0 0x0
+#define MX51_PAD_DI1_PIN2__DI1_PIN2 0x330 0x734 0x000 0x0 0x0
+#define MX51_PAD_DI_GP2__DISP1_SER_CLK 0x338 0x740 0x000 0x0 0x0
+#define MX51_PAD_DI_GP2__DISP2_WAIT 0x338 0x740 0x9a8 0x2 0x1
+#define MX51_PAD_DI_GP3__CSI1_DATA_EN 0x33c 0x744 0x9a0 0x3 0x1
+#define MX51_PAD_DI_GP3__DISP1_SER_DIO 0x33c 0x744 0x9c0 0x0 0x0
+#define MX51_PAD_DI_GP3__FEC_TX_ER 0x33c 0x744 0x000 0x2 0x0
+#define MX51_PAD_DI2_PIN4__CSI2_DATA_EN 0x340 0x748 0x99c 0x3 0x1
+#define MX51_PAD_DI2_PIN4__DI2_PIN4 0x340 0x748 0x000 0x0 0x0
+#define MX51_PAD_DI2_PIN4__FEC_CRS 0x340 0x748 0x950 0x2 0x1
+#define MX51_PAD_DI2_PIN2__DI2_PIN2 0x344 0x74c 0x000 0x0 0x0
+#define MX51_PAD_DI2_PIN2__FEC_MDC 0x344 0x74c 0x000 0x2 0x0
+#define MX51_PAD_DI2_PIN3__DI2_PIN3 0x348 0x750 0x000 0x0 0x0
+#define MX51_PAD_DI2_PIN3__FEC_MDIO 0x348 0x750 0x954 0x2 0x1
+#define MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK 0x34c 0x754 0x000 0x0 0x0
+#define MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 0x34c 0x754 0x95c 0x2 0x1
+#define MX51_PAD_DI_GP4__DI2_PIN15 0x350 0x758 0x000 0x4 0x0
+#define MX51_PAD_DI_GP4__DISP1_SER_DIN 0x350 0x758 0x9c0 0x0 0x1
+#define MX51_PAD_DI_GP4__DISP2_PIN1 0x350 0x758 0x000 0x3 0x0
+#define MX51_PAD_DI_GP4__FEC_RDATA2 0x350 0x758 0x960 0x2 0x1
+#define MX51_PAD_DISP2_DAT0__DISP2_DAT0 0x354 0x75c 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT0__FEC_RDATA3 0x354 0x75c 0x964 0x2 0x1
+#define MX51_PAD_DISP2_DAT0__KEY_COL6 0x354 0x75c 0x9c8 0x4 0x1
+#define MX51_PAD_DISP2_DAT0__UART3_RXD 0x354 0x75c 0x9f4 0x5 0x8
+#define MX51_PAD_DISP2_DAT0__USBH3_CLK 0x354 0x75c 0x9f8 0x3 0x1
+#define MX51_PAD_DISP2_DAT1__DISP2_DAT1 0x358 0x760 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT1__FEC_RX_ER 0x358 0x760 0x970 0x2 0x1
+#define MX51_PAD_DISP2_DAT1__KEY_COL7 0x358 0x760 0x9cc 0x4 0x1
+#define MX51_PAD_DISP2_DAT1__UART3_TXD 0x358 0x760 0x000 0x5 0x0
+#define MX51_PAD_DISP2_DAT1__USBH3_DIR 0x358 0x760 0xa1c 0x3 0x1
+#define MX51_PAD_DISP2_DAT2__DISP2_DAT2 0x35c 0x764 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT3__DISP2_DAT3 0x360 0x768 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT4__DISP2_DAT4 0x364 0x76c 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT5__DISP2_DAT5 0x368 0x770 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT6__DISP2_DAT6 0x36c 0x774 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT6__FEC_TDATA1 0x36c 0x774 0x000 0x2 0x0
+#define MX51_PAD_DISP2_DAT6__GPIO1_19 0x36c 0x774 0x000 0x5 0x0
+#define MX51_PAD_DISP2_DAT6__KEY_ROW4 0x36c 0x774 0x9d0 0x4 0x1
+#define MX51_PAD_DISP2_DAT6__USBH3_STP 0x36c 0x774 0xa24 0x3 0x1
+#define MX51_PAD_DISP2_DAT7__DISP2_DAT7 0x370 0x778 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT7__FEC_TDATA2 0x370 0x778 0x000 0x2 0x0
+#define MX51_PAD_DISP2_DAT7__GPIO1_29 0x370 0x778 0x000 0x5 0x0
+#define MX51_PAD_DISP2_DAT7__KEY_ROW5 0x370 0x778 0x9d4 0x4 0x1
+#define MX51_PAD_DISP2_DAT7__USBH3_NXT 0x370 0x778 0xa20 0x3 0x1
+#define MX51_PAD_DISP2_DAT8__DISP2_DAT8 0x374 0x77c 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT8__FEC_TDATA3 0x374 0x77c 0x000 0x2 0x0
+#define MX51_PAD_DISP2_DAT8__GPIO1_30 0x374 0x77c 0x000 0x5 0x0
+#define MX51_PAD_DISP2_DAT8__KEY_ROW6 0x374 0x77c 0x9d8 0x4 0x1
+#define MX51_PAD_DISP2_DAT8__USBH3_DATA0 0x374 0x77c 0x9fc 0x3 0x1
+#define MX51_PAD_DISP2_DAT9__AUD6_RXC 0x378 0x780 0x8f4 0x4 0x1
+#define MX51_PAD_DISP2_DAT9__DISP2_DAT9 0x378 0x780 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT9__FEC_TX_EN 0x378 0x780 0x000 0x2 0x0
+#define MX51_PAD_DISP2_DAT9__GPIO1_31 0x378 0x780 0x000 0x5 0x0
+#define MX51_PAD_DISP2_DAT9__USBH3_DATA1 0x378 0x780 0xa00 0x3 0x1
+#define MX51_PAD_DISP2_DAT10__DISP2_DAT10 0x37c 0x784 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT10__DISP2_SER_CS 0x37c 0x784 0x000 0x5 0x0
+#define MX51_PAD_DISP2_DAT10__FEC_COL 0x37c 0x784 0x94c 0x2 0x1
+#define MX51_PAD_DISP2_DAT10__KEY_ROW7 0x37c 0x784 0x9dc 0x4 0x1
+#define MX51_PAD_DISP2_DAT10__USBH3_DATA2 0x37c 0x784 0xa04 0x3 0x1
+#define MX51_PAD_DISP2_DAT11__AUD6_TXD 0x380 0x788 0x8f0 0x4 0x1
+#define MX51_PAD_DISP2_DAT11__DISP2_DAT11 0x380 0x788 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT11__FEC_RX_CLK 0x380 0x788 0x968 0x2 0x1
+#define MX51_PAD_DISP2_DAT11__GPIO1_10 0x380 0x788 0x000 0x7 0x0
+#define MX51_PAD_DISP2_DAT11__USBH3_DATA3 0x380 0x788 0xa08 0x3 0x1
+#define MX51_PAD_DISP2_DAT12__AUD6_RXD 0x384 0x78c 0x8ec 0x4 0x1
+#define MX51_PAD_DISP2_DAT12__DISP2_DAT12 0x384 0x78c 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT12__FEC_RX_DV 0x384 0x78c 0x96c 0x2 0x1
+#define MX51_PAD_DISP2_DAT12__USBH3_DATA4 0x384 0x78c 0xa0c 0x3 0x1
+#define MX51_PAD_DISP2_DAT13__AUD6_TXC 0x388 0x790 0x8fc 0x4 0x1
+#define MX51_PAD_DISP2_DAT13__DISP2_DAT13 0x388 0x790 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT13__FEC_TX_CLK 0x388 0x790 0x974 0x2 0x1
+#define MX51_PAD_DISP2_DAT13__USBH3_DATA5 0x388 0x790 0xa10 0x3 0x1
+#define MX51_PAD_DISP2_DAT14__AUD6_TXFS 0x38c 0x794 0x900 0x4 0x1
+#define MX51_PAD_DISP2_DAT14__DISP2_DAT14 0x38c 0x794 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT14__FEC_RDATA0 0x38c 0x794 0x958 0x2 0x1
+#define MX51_PAD_DISP2_DAT14__USBH3_DATA6 0x38c 0x794 0xa14 0x3 0x1
+#define MX51_PAD_DISP2_DAT15__AUD6_RXFS 0x390 0x798 0x8f8 0x4 0x1
+#define MX51_PAD_DISP2_DAT15__DISP1_SER_CS 0x390 0x798 0x000 0x5 0x0
+#define MX51_PAD_DISP2_DAT15__DISP2_DAT15 0x390 0x798 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT15__FEC_TDATA0 0x390 0x798 0x000 0x2 0x0
+#define MX51_PAD_DISP2_DAT15__USBH3_DATA7 0x390 0x798 0xa18 0x3 0x1
+#define MX51_PAD_SD1_CMD__AUD5_RXFS 0x394 0x79c 0x8e0 0x1 0x1
+#define MX51_PAD_SD1_CMD__CSPI_MOSI 0x394 0x79c 0x91c 0x2 0x2
+#define MX51_PAD_SD1_CMD__SD1_CMD 0x394 0x79c 0x000 0x0 0x0
+#define MX51_PAD_SD1_CLK__AUD5_RXC 0x398 0x7a0 0x8dc 0x1 0x1
+#define MX51_PAD_SD1_CLK__CSPI_SCLK 0x398 0x7a0 0x914 0x2 0x2
+#define MX51_PAD_SD1_CLK__SD1_CLK 0x398 0x7a0 0x000 0x0 0x0
+#define MX51_PAD_SD1_DATA0__AUD5_TXD 0x39c 0x7a4 0x8d8 0x1 0x2
+#define MX51_PAD_SD1_DATA0__CSPI_MISO 0x39c 0x7a4 0x918 0x2 0x1
+#define MX51_PAD_SD1_DATA0__SD1_DATA0 0x39c 0x7a4 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA0__EIM_DA0 0x01c 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA1__EIM_DA1 0x020 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA2__EIM_DA2 0x024 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA3__EIM_DA3 0x028 0x000 0x000 0x0 0x0
+#define MX51_PAD_SD1_DATA1__AUD5_RXD 0x3a0 0x7a8 0x8d4 0x1 0x2
+#define MX51_PAD_SD1_DATA1__SD1_DATA1 0x3a0 0x7a8 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA4__EIM_DA4 0x02c 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA5__EIM_DA5 0x030 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA6__EIM_DA6 0x034 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA7__EIM_DA7 0x038 0x000 0x000 0x0 0x0
+#define MX51_PAD_SD1_DATA2__AUD5_TXC 0x3a4 0x7ac 0x8e4 0x1 0x2
+#define MX51_PAD_SD1_DATA2__SD1_DATA2 0x3a4 0x7ac 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA10__EIM_DA10 0x044 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA11__EIM_DA11 0x048 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA8__EIM_DA8 0x03c 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA9__EIM_DA9 0x040 0x000 0x000 0x0 0x0
+#define MX51_PAD_SD1_DATA3__AUD5_TXFS 0x3a8 0x7b0 0x8e8 0x1 0x2
+#define MX51_PAD_SD1_DATA3__CSPI_SS1 0x3a8 0x7b0 0x920 0x2 0x1
+#define MX51_PAD_SD1_DATA3__SD1_DATA3 0x3a8 0x7b0 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_0__CSPI_SS2 0x3ac 0x7b4 0x924 0x2 0x0
+#define MX51_PAD_GPIO1_0__GPIO1_0 0x3ac 0x7b4 0x000 0x1 0x0
+#define MX51_PAD_GPIO1_0__SD1_CD 0x3ac 0x7b4 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_1__CSPI_MISO 0x3b0 0x7b8 0x918 0x2 0x2
+#define MX51_PAD_GPIO1_1__GPIO1_1 0x3b0 0x7b8 0x000 0x1 0x0
+#define MX51_PAD_GPIO1_1__SD1_WP 0x3b0 0x7b8 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA12__EIM_DA12 0x04c 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA13__EIM_DA13 0x050 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA14__EIM_DA14 0x054 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA15__EIM_DA15 0x058 0x000 0x000 0x0 0x0
+#define MX51_PAD_SD2_CMD__CSPI_MOSI 0x3b4 0x7bc 0x91c 0x2 0x3
+#define MX51_PAD_SD2_CMD__I2C1_SCL 0x3b4 0x7bc 0x9b0 0x1 0x2
+#define MX51_PAD_SD2_CMD__SD2_CMD 0x3b4 0x7bc 0x000 0x0 0x0
+#define MX51_PAD_SD2_CLK__CSPI_SCLK 0x3b8 0x7c0 0x914 0x2 0x3
+#define MX51_PAD_SD2_CLK__I2C1_SDA 0x3b8 0x7c0 0x9b4 0x1 0x2
+#define MX51_PAD_SD2_CLK__SD2_CLK 0x3b8 0x7c0 0x000 0x0 0x0
+#define MX51_PAD_SD2_DATA0__CSPI_MISO 0x3bc 0x7c4 0x918 0x2 0x3
+#define MX51_PAD_SD2_DATA0__SD1_DAT4 0x3bc 0x7c4 0x000 0x1 0x0
+#define MX51_PAD_SD2_DATA0__SD2_DATA0 0x3bc 0x7c4 0x000 0x0 0x0
+#define MX51_PAD_SD2_DATA1__SD1_DAT5 0x3c0 0x7c8 0x000 0x1 0x0
+#define MX51_PAD_SD2_DATA1__SD2_DATA1 0x3c0 0x7c8 0x000 0x0 0x0
+#define MX51_PAD_SD2_DATA1__USBH3_H2_DP 0x3c0 0x7c8 0x000 0x2 0x0
+#define MX51_PAD_SD2_DATA2__SD1_DAT6 0x3c4 0x7cc 0x000 0x1 0x0
+#define MX51_PAD_SD2_DATA2__SD2_DATA2 0x3c4 0x7cc 0x000 0x0 0x0
+#define MX51_PAD_SD2_DATA2__USBH3_H2_DM 0x3c4 0x7cc 0x000 0x2 0x0
+#define MX51_PAD_SD2_DATA3__CSPI_SS2 0x3c8 0x7d0 0x924 0x2 0x1
+#define MX51_PAD_SD2_DATA3__SD1_DAT7 0x3c8 0x7d0 0x000 0x1 0x0
+#define MX51_PAD_SD2_DATA3__SD2_DATA3 0x3c8 0x7d0 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_2__CCM_OUT_2 0x3cc 0x7d4 0x000 0x5 0x0
+#define MX51_PAD_GPIO1_2__GPIO1_2 0x3cc 0x7d4 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_2__I2C2_SCL 0x3cc 0x7d4 0x9b8 0x2 0x3
+#define MX51_PAD_GPIO1_2__PLL1_BYP 0x3cc 0x7d4 0x90c 0x7 0x1
+#define MX51_PAD_GPIO1_2__PWM1_PWMO 0x3cc 0x7d4 0x000 0x1 0x0
+#define MX51_PAD_GPIO1_3__GPIO1_3 0x3d0 0x7d8 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_3__I2C2_SDA 0x3d0 0x7d8 0x9bc 0x2 0x3
+#define MX51_PAD_GPIO1_3__PLL2_BYP 0x3d0 0x7d8 0x910 0x7 0x1
+#define MX51_PAD_GPIO1_3__PWM2_PWMO 0x3d0 0x7d8 0x000 0x1 0x0
+#define MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ 0x3d4 0x7fc 0x000 0x0 0x0
+#define MX51_PAD_PMIC_INT_REQ__PMIC_PMU_IRQ_B 0x3d4 0x7fc 0x000 0x1 0x0
+#define MX51_PAD_GPIO1_4__DISP2_EXT_CLK 0x3d8 0x804 0x908 0x4 0x1
+#define MX51_PAD_GPIO1_4__EIM_RDY 0x3d8 0x804 0x938 0x3 0x1
+#define MX51_PAD_GPIO1_4__GPIO1_4 0x3d8 0x804 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_4__WDOG1_WDOG_B 0x3d8 0x804 0x000 0x2 0x0
+#define MX51_PAD_GPIO1_5__CSI2_MCLK 0x3dc 0x808 0x000 0x6 0x0
+#define MX51_PAD_GPIO1_5__DISP2_PIN16 0x3dc 0x808 0x000 0x3 0x0
+#define MX51_PAD_GPIO1_5__GPIO1_5 0x3dc 0x808 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_5__WDOG2_WDOG_B 0x3dc 0x808 0x000 0x2 0x0
+#define MX51_PAD_GPIO1_6__DISP2_PIN17 0x3e0 0x80c 0x000 0x4 0x0
+#define MX51_PAD_GPIO1_6__GPIO1_6 0x3e0 0x80c 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_6__REF_EN_B 0x3e0 0x80c 0x000 0x3 0x0
+#define MX51_PAD_GPIO1_7__CCM_OUT_0 0x3e4 0x810 0x000 0x3 0x0
+#define MX51_PAD_GPIO1_7__GPIO1_7 0x3e4 0x810 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_7__SD2_WP 0x3e4 0x810 0x000 0x6 0x0
+#define MX51_PAD_GPIO1_7__SPDIF_OUT1 0x3e4 0x810 0x000 0x2 0x0
+#define MX51_PAD_GPIO1_8__CSI2_DATA_EN 0x3e8 0x814 0x99c 0x2 0x2
+#define MX51_PAD_GPIO1_8__GPIO1_8 0x3e8 0x814 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_8__SD2_CD 0x3e8 0x814 0x000 0x6 0x0
+#define MX51_PAD_GPIO1_8__USBH3_PWR 0x3e8 0x814 0x000 0x1 0x0
+#define MX51_PAD_GPIO1_9__CCM_OUT_1 0x3ec 0x818 0x000 0x3 0x0
+#define MX51_PAD_GPIO1_9__DISP2_D1_CS 0x3ec 0x818 0x000 0x2 0x0
+#define MX51_PAD_GPIO1_9__DISP2_SER_CS 0x3ec 0x818 0x000 0x7 0x0
+#define MX51_PAD_GPIO1_9__GPIO1_9 0x3ec 0x818 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_9__SD2_LCTL 0x3ec 0x818 0x000 0x6 0x0
+#define MX51_PAD_GPIO1_9__USBH3_OC 0x3ec 0x818 0x000 0x1 0x0
+
+#endif /* __DTS_IMX51_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
new file mode 100644
index 000000000..ec933b489
--- /dev/null
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -0,0 +1,592 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 "skeleton.dtsi"
+#include "imx51-pinfunc.h"
+#include <dt-bindings/clock/imx5-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ aliases {
+ ethernet0 = &fec;
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ mmc0 = &esdhc1;
+ mmc1 = &esdhc2;
+ mmc2 = &esdhc3;
+ mmc3 = &esdhc4;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ spi0 = &ecspi1;
+ spi1 = &ecspi2;
+ spi2 = &cspi;
+ };
+
+ tzic: tz-interrupt-controller@e0000000 {
+ compatible = "fsl,imx51-tzic", "fsl,tzic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xe0000000 0x4000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ckil {
+ compatible = "fsl,imx-ckil", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+
+ ckih1 {
+ compatible = "fsl,imx-ckih1", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ ckih2 {
+ compatible = "fsl,imx-ckih2", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ osc {
+ compatible = "fsl,imx-osc", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a8";
+ reg = <0>;
+ clock-latency = <62500>;
+ clocks = <&clks IMX5_CLK_CPU_PODF>;
+ clock-names = "cpu";
+ operating-points = <
+ 166000 1000000
+ 600000 1050000
+ 800000 1100000
+ >;
+ voltage-tolerance = <5>;
+ };
+ };
+
+ usbphy {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "simple-bus";
+
+ usbphy0: usbphy@0 {
+ compatible = "usb-nop-xceiv";
+ reg = <0>;
+ clocks = <&clks IMX5_CLK_USB_PHY_GATE>;
+ clock-names = "main_clk";
+ };
+ };
+
+ display-subsystem {
+ compatible = "fsl,imx-display-subsystem";
+ ports = <&ipu_di0>, <&ipu_di1>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&tzic>;
+ ranges;
+
+ iram: iram@1ffe0000 {
+ compatible = "mmio-sram";
+ reg = <0x1ffe0000 0x20000>;
+ };
+
+ ipu: ipu@40000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-ipu";
+ reg = <0x40000000 0x20000000>;
+ interrupts = <11 10>;
+ clocks = <&clks IMX5_CLK_IPU_GATE>,
+ <&clks IMX5_CLK_IPU_DI0_GATE>,
+ <&clks IMX5_CLK_IPU_DI1_GATE>;
+ clock-names = "bus", "di0", "di1";
+ resets = <&src 2>;
+
+ ipu_di0: port@2 {
+ reg = <2>;
+
+ ipu_di0_disp0: endpoint {
+ };
+ };
+
+ ipu_di1: port@3 {
+ reg = <3>;
+
+ ipu_di1_disp1: endpoint {
+ };
+ };
+ };
+
+ aips@70000000 { /* AIPS1 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x70000000 0x10000000>;
+ ranges;
+
+ spba@70000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x70000000 0x40000>;
+ ranges;
+
+ esdhc1: esdhc@70004000 {
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70004000 0x4000>;
+ interrupts = <1>;
+ clocks = <&clks IMX5_CLK_ESDHC1_IPG_GATE>,
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC1_PER_GATE>;
+ clock-names = "ipg", "ahb", "per";
+ status = "disabled";
+ };
+
+ esdhc2: esdhc@70008000 {
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70008000 0x4000>;
+ interrupts = <2>;
+ clocks = <&clks IMX5_CLK_ESDHC2_IPG_GATE>,
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC2_PER_GATE>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ uart3: serial@7000c000 {
+ compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+ reg = <0x7000c000 0x4000>;
+ interrupts = <33>;
+ clocks = <&clks IMX5_CLK_UART3_IPG_GATE>,
+ <&clks IMX5_CLK_UART3_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi1: ecspi@70010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-ecspi";
+ reg = <0x70010000 0x4000>;
+ interrupts = <36>;
+ clocks = <&clks IMX5_CLK_ECSPI1_IPG_GATE>,
+ <&clks IMX5_CLK_ECSPI1_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ssi2: ssi@70014000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
+ reg = <0x70014000 0x4000>;
+ interrupts = <30>;
+ clocks = <&clks IMX5_CLK_SSI2_IPG_GATE>,
+ <&clks IMX5_CLK_SSI2_ROOT_GATE>;
+ clock-names = "ipg", "baud";
+ dmas = <&sdma 24 1 0>,
+ <&sdma 25 1 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ esdhc3: esdhc@70020000 {
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70020000 0x4000>;
+ interrupts = <3>;
+ clocks = <&clks IMX5_CLK_ESDHC3_IPG_GATE>,
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC3_PER_GATE>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ esdhc4: esdhc@70024000 {
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70024000 0x4000>;
+ interrupts = <4>;
+ clocks = <&clks IMX5_CLK_ESDHC4_IPG_GATE>,
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC4_PER_GATE>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+ };
+
+ usbotg: usb@73f80000 {
+ compatible = "fsl,imx51-usb", "fsl,imx27-usb";
+ reg = <0x73f80000 0x0200>;
+ interrupts = <18>;
+ clocks = <&clks IMX5_CLK_USBOH3_GATE>;
+ fsl,usbmisc = <&usbmisc 0>;
+ fsl,usbphy = <&usbphy0>;
+ status = "disabled";
+ };
+
+ usbh1: usb@73f80200 {
+ compatible = "fsl,imx51-usb", "fsl,imx27-usb";
+ reg = <0x73f80200 0x0200>;
+ interrupts = <14>;
+ clocks = <&clks IMX5_CLK_USBOH3_GATE>;
+ fsl,usbmisc = <&usbmisc 1>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbh2: usb@73f80400 {
+ compatible = "fsl,imx51-usb", "fsl,imx27-usb";
+ reg = <0x73f80400 0x0200>;
+ interrupts = <16>;
+ clocks = <&clks IMX5_CLK_USBOH3_GATE>;
+ fsl,usbmisc = <&usbmisc 2>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbh3: usb@73f80600 {
+ compatible = "fsl,imx51-usb", "fsl,imx27-usb";
+ reg = <0x73f80600 0x0200>;
+ interrupts = <17>;
+ clocks = <&clks IMX5_CLK_USBOH3_GATE>;
+ fsl,usbmisc = <&usbmisc 3>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbmisc: usbmisc@73f80800 {
+ #index-cells = <1>;
+ compatible = "fsl,imx51-usbmisc";
+ reg = <0x73f80800 0x200>;
+ clocks = <&clks IMX5_CLK_USBOH3_GATE>;
+ };
+
+ gpio1: gpio@73f84000 {
+ compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
+ reg = <0x73f84000 0x4000>;
+ interrupts = <50 51>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@73f88000 {
+ compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
+ reg = <0x73f88000 0x4000>;
+ interrupts = <52 53>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@73f8c000 {
+ compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
+ reg = <0x73f8c000 0x4000>;
+ interrupts = <54 55>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@73f90000 {
+ compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
+ reg = <0x73f90000 0x4000>;
+ interrupts = <56 57>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ kpp: kpp@73f94000 {
+ compatible = "fsl,imx51-kpp", "fsl,imx21-kpp";
+ reg = <0x73f94000 0x4000>;
+ interrupts = <60>;
+ clocks = <&clks IMX5_CLK_DUMMY>;
+ status = "disabled";
+ };
+
+ wdog1: wdog@73f98000 {
+ compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
+ reg = <0x73f98000 0x4000>;
+ interrupts = <58>;
+ clocks = <&clks IMX5_CLK_DUMMY>;
+ };
+
+ wdog2: wdog@73f9c000 {
+ compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
+ reg = <0x73f9c000 0x4000>;
+ interrupts = <59>;
+ clocks = <&clks IMX5_CLK_DUMMY>;
+ status = "disabled";
+ };
+
+ gpt: timer@73fa0000 {
+ compatible = "fsl,imx51-gpt", "fsl,imx31-gpt";
+ reg = <0x73fa0000 0x4000>;
+ interrupts = <39>;
+ clocks = <&clks IMX5_CLK_GPT_IPG_GATE>,
+ <&clks IMX5_CLK_GPT_HF_GATE>;
+ clock-names = "ipg", "per";
+ };
+
+ iomuxc: iomuxc@73fa8000 {
+ compatible = "fsl,imx51-iomuxc";
+ reg = <0x73fa8000 0x4000>;
+ };
+
+ pwm1: pwm@73fb4000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx51-pwm", "fsl,imx27-pwm";
+ reg = <0x73fb4000 0x4000>;
+ clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
+ <&clks IMX5_CLK_PWM1_HF_GATE>;
+ clock-names = "ipg", "per";
+ interrupts = <61>;
+ };
+
+ pwm2: pwm@73fb8000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx51-pwm", "fsl,imx27-pwm";
+ reg = <0x73fb8000 0x4000>;
+ clocks = <&clks IMX5_CLK_PWM2_IPG_GATE>,
+ <&clks IMX5_CLK_PWM2_HF_GATE>;
+ clock-names = "ipg", "per";
+ interrupts = <94>;
+ };
+
+ uart1: serial@73fbc000 {
+ compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+ reg = <0x73fbc000 0x4000>;
+ interrupts = <31>;
+ clocks = <&clks IMX5_CLK_UART1_IPG_GATE>,
+ <&clks IMX5_CLK_UART1_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart2: serial@73fc0000 {
+ compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+ reg = <0x73fc0000 0x4000>;
+ interrupts = <32>;
+ clocks = <&clks IMX5_CLK_UART2_IPG_GATE>,
+ <&clks IMX5_CLK_UART2_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ src: src@73fd0000 {
+ compatible = "fsl,imx51-src";
+ reg = <0x73fd0000 0x4000>;
+ #reset-cells = <1>;
+ };
+
+ clks: ccm@73fd4000{
+ compatible = "fsl,imx51-ccm";
+ reg = <0x73fd4000 0x4000>;
+ interrupts = <0 71 0x04 0 72 0x04>;
+ #clock-cells = <1>;
+ };
+ };
+
+ aips@80000000 { /* AIPS2 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80000000 0x10000000>;
+ ranges;
+
+ iim: iim@83f98000 {
+ compatible = "fsl,imx51-iim", "fsl,imx27-iim";
+ reg = <0x83f98000 0x4000>;
+ interrupts = <69>;
+ clocks = <&clks IMX5_CLK_IIM_GATE>;
+ };
+
+ owire: owire@83fa4000 {
+ compatible = "fsl,imx51-owire", "fsl,imx21-owire";
+ reg = <0x83fa4000 0x4000>;
+ interrupts = <88>;
+ clocks = <&clks IMX5_CLK_OWIRE_GATE>;
+ status = "disabled";
+ };
+
+ ecspi2: ecspi@83fac000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-ecspi";
+ reg = <0x83fac000 0x4000>;
+ interrupts = <37>;
+ clocks = <&clks IMX5_CLK_ECSPI2_IPG_GATE>,
+ <&clks IMX5_CLK_ECSPI2_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ sdma: sdma@83fb0000 {
+ compatible = "fsl,imx51-sdma", "fsl,imx35-sdma";
+ reg = <0x83fb0000 0x4000>;
+ interrupts = <6>;
+ clocks = <&clks IMX5_CLK_SDMA_GATE>,
+ <&clks IMX5_CLK_SDMA_GATE>;
+ clock-names = "ipg", "ahb";
+ #dma-cells = <3>;
+ fsl,sdma-ram-script-name = "/*(DEBLOBBED)*/";
+ };
+
+ cspi: cspi@83fc0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-cspi", "fsl,imx35-cspi";
+ reg = <0x83fc0000 0x4000>;
+ interrupts = <38>;
+ clocks = <&clks IMX5_CLK_CSPI_IPG_GATE>,
+ <&clks IMX5_CLK_CSPI_IPG_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ i2c2: i2c@83fc4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-i2c", "fsl,imx21-i2c";
+ reg = <0x83fc4000 0x4000>;
+ interrupts = <63>;
+ clocks = <&clks IMX5_CLK_I2C2_GATE>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@83fc8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-i2c", "fsl,imx21-i2c";
+ reg = <0x83fc8000 0x4000>;
+ interrupts = <62>;
+ clocks = <&clks IMX5_CLK_I2C1_GATE>;
+ status = "disabled";
+ };
+
+ ssi1: ssi@83fcc000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
+ reg = <0x83fcc000 0x4000>;
+ interrupts = <29>;
+ clocks = <&clks IMX5_CLK_SSI1_IPG_GATE>,
+ <&clks IMX5_CLK_SSI1_ROOT_GATE>;
+ clock-names = "ipg", "baud";
+ dmas = <&sdma 28 0 0>,
+ <&sdma 29 0 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ audmux: audmux@83fd0000 {
+ compatible = "fsl,imx51-audmux", "fsl,imx31-audmux";
+ reg = <0x83fd0000 0x4000>;
+ clocks = <&clks IMX5_CLK_DUMMY>;
+ clock-names = "audmux";
+ status = "disabled";
+ };
+
+ weim: weim@83fda000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,imx51-weim";
+ reg = <0x83fda000 0x1000>;
+ clocks = <&clks IMX5_CLK_EMI_SLOW_GATE>;
+ ranges = <
+ 0 0 0xb0000000 0x08000000
+ 1 0 0xb8000000 0x08000000
+ 2 0 0xc0000000 0x08000000
+ 3 0 0xc8000000 0x04000000
+ 4 0 0xcc000000 0x02000000
+ 5 0 0xce000000 0x02000000
+ >;
+ status = "disabled";
+ };
+
+ nfc: nand@83fdb000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,imx51-nand";
+ reg = <0x83fdb000 0x1000 0xcfff0000 0x10000>;
+ interrupts = <8>;
+ clocks = <&clks IMX5_CLK_NFC_GATE>;
+ status = "disabled";
+ };
+
+ pata: pata@83fe0000 {
+ compatible = "fsl,imx51-pata", "fsl,imx27-pata";
+ reg = <0x83fe0000 0x4000>;
+ interrupts = <70>;
+ clocks = <&clks IMX5_CLK_PATA_GATE>;
+ status = "disabled";
+ };
+
+ ssi3: ssi@83fe8000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
+ reg = <0x83fe8000 0x4000>;
+ interrupts = <96>;
+ clocks = <&clks IMX5_CLK_SSI3_IPG_GATE>,
+ <&clks IMX5_CLK_SSI3_ROOT_GATE>;
+ clock-names = "ipg", "baud";
+ dmas = <&sdma 46 0 0>,
+ <&sdma 47 0 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ fec: ethernet@83fec000 {
+ compatible = "fsl,imx51-fec", "fsl,imx27-fec";
+ reg = <0x83fec000 0x4000>;
+ interrupts = <87>;
+ clocks = <&clks IMX5_CLK_FEC_GATE>,
+ <&clks IMX5_CLK_FEC_GATE>,
+ <&clks IMX5_CLK_FEC_GATE>;
+ clock-names = "ipg", "ahb", "ptp";
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx53-ard.dts b/arch/arm/boot/dts/imx53-ard.dts
new file mode 100644
index 000000000..e9337ad52
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-ard.dts
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx53.dtsi"
+
+/ {
+ model = "Freescale i.MX53 Automotive Reference Design Board";
+ compatible = "fsl,imx53-ard", "fsl,imx53";
+
+ memory {
+ reg = <0x70000000 0x40000000>;
+ };
+
+ eim-cs1@f4000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,eim-bus", "simple-bus";
+ reg = <0xf4000000 0x3ff0000>;
+ ranges;
+
+ lan9220@f4000000 {
+ compatible = "smsc,lan9220", "smsc,lan9115";
+ reg = <0xf4000000 0x2000000>;
+ phy-mode = "mii";
+ interrupt-parent = <&gpio2>;
+ interrupts = <31 0x8>;
+ reg-io-width = <4>;
+ /*
+ * VDD33A and VDDVARIO of LAN9220 are supplied by
+ * SW4_3V3 of LTC3589. Before the regulator driver
+ * for this PMIC is available, we use a fixed dummy
+ * 3V3 regulator to get LAN9220 driver probing work.
+ */
+ vdd33a-supply = <&reg_3p3v>;
+ vddvario-supply = <&reg_3p3v>;
+ smsc,irq-push-pull;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ home {
+ label = "Home";
+ gpios = <&gpio5 10 0>;
+ linux,code = <102>; /* KEY_HOME */
+ gpio-key,wakeup;
+ };
+
+ back {
+ label = "Back";
+ gpios = <&gpio5 11 0>;
+ linux,code = <158>; /* KEY_BACK */
+ gpio-key,wakeup;
+ };
+
+ program {
+ label = "Program";
+ gpios = <&gpio5 12 0>;
+ linux,code = <362>; /* KEY_PROGRAM */
+ gpio-key,wakeup;
+ };
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio5 13 0>;
+ linux,code = <115>; /* KEY_VOLUMEUP */
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio4 0 0>;
+ linux,code = <114>; /* KEY_VOLUMEDOWN */
+ };
+ };
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ cd-gpios = <&gpio1 1 0>;
+ wp-gpios = <&gpio1 9 0>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx53-ard {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX53_PAD_GPIO_1__GPIO1_1 0x80000000
+ MX53_PAD_GPIO_9__GPIO1_9 0x80000000
+ MX53_PAD_EIM_EB3__GPIO2_31 0x80000000
+ MX53_PAD_GPIO_10__GPIO4_0 0x80000000
+ MX53_PAD_DISP0_DAT16__GPIO5_10 0x80000000
+ MX53_PAD_DISP0_DAT17__GPIO5_11 0x80000000
+ MX53_PAD_DISP0_DAT18__GPIO5_12 0x80000000
+ MX53_PAD_DISP0_DAT19__GPIO5_13 0x80000000
+ MX53_PAD_EIM_D16__EMI_WEIM_D_16 0x80000000
+ MX53_PAD_EIM_D17__EMI_WEIM_D_17 0x80000000
+ MX53_PAD_EIM_D18__EMI_WEIM_D_18 0x80000000
+ MX53_PAD_EIM_D19__EMI_WEIM_D_19 0x80000000
+ MX53_PAD_EIM_D20__EMI_WEIM_D_20 0x80000000
+ MX53_PAD_EIM_D21__EMI_WEIM_D_21 0x80000000
+ MX53_PAD_EIM_D22__EMI_WEIM_D_22 0x80000000
+ MX53_PAD_EIM_D23__EMI_WEIM_D_23 0x80000000
+ MX53_PAD_EIM_D24__EMI_WEIM_D_24 0x80000000
+ MX53_PAD_EIM_D25__EMI_WEIM_D_25 0x80000000
+ MX53_PAD_EIM_D26__EMI_WEIM_D_26 0x80000000
+ MX53_PAD_EIM_D27__EMI_WEIM_D_27 0x80000000
+ MX53_PAD_EIM_D28__EMI_WEIM_D_28 0x80000000
+ MX53_PAD_EIM_D29__EMI_WEIM_D_29 0x80000000
+ MX53_PAD_EIM_D30__EMI_WEIM_D_30 0x80000000
+ MX53_PAD_EIM_D31__EMI_WEIM_D_31 0x80000000
+ MX53_PAD_EIM_DA0__EMI_NAND_WEIM_DA_0 0x80000000
+ MX53_PAD_EIM_DA1__EMI_NAND_WEIM_DA_1 0x80000000
+ MX53_PAD_EIM_DA2__EMI_NAND_WEIM_DA_2 0x80000000
+ MX53_PAD_EIM_DA3__EMI_NAND_WEIM_DA_3 0x80000000
+ MX53_PAD_EIM_DA4__EMI_NAND_WEIM_DA_4 0x80000000
+ MX53_PAD_EIM_DA5__EMI_NAND_WEIM_DA_5 0x80000000
+ MX53_PAD_EIM_DA6__EMI_NAND_WEIM_DA_6 0x80000000
+ MX53_PAD_EIM_OE__EMI_WEIM_OE 0x80000000
+ MX53_PAD_EIM_RW__EMI_WEIM_RW 0x80000000
+ MX53_PAD_EIM_CS1__EMI_WEIM_CS_1 0x80000000
+ >;
+ };
+
+ pinctrl_esdhc1: esdhc1grp {
+ fsl,pins = <
+ MX53_PAD_SD1_DATA0__ESDHC1_DAT0 0x1d5
+ MX53_PAD_SD1_DATA1__ESDHC1_DAT1 0x1d5
+ MX53_PAD_SD1_DATA2__ESDHC1_DAT2 0x1d5
+ MX53_PAD_SD1_DATA3__ESDHC1_DAT3 0x1d5
+ MX53_PAD_PATA_DATA8__ESDHC1_DAT4 0x1d5
+ MX53_PAD_PATA_DATA9__ESDHC1_DAT5 0x1d5
+ MX53_PAD_PATA_DATA10__ESDHC1_DAT6 0x1d5
+ MX53_PAD_PATA_DATA11__ESDHC1_DAT7 0x1d5
+ MX53_PAD_SD1_CMD__ESDHC1_CMD 0x1d5
+ MX53_PAD_SD1_CLK__ESDHC1_CLK 0x1d5
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX53_PAD_PATA_DIOW__UART1_TXD_MUX 0x1e4
+ MX53_PAD_PATA_DMACK__UART1_RXD_MUX 0x1e4
+ >;
+ };
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx53-m53.dtsi b/arch/arm/boot/dts/imx53-m53.dtsi
new file mode 100644
index 000000000..87a7fc709
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-m53.dtsi
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2014 Marek Vasut <marex@denx.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
+ */
+
+#include "imx53.dtsi"
+
+/ {
+ model = "DENX M53";
+ compatible = "denx,imx53-m53", "fsl,imx53";
+
+ memory {
+ reg = <0x70000000 0x20000000>,
+ <0xb0000000 0x20000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p2v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P2V";
+ regulator-min-microvolt = <3200000>;
+ regulator-max-microvolt = <3200000>;
+ regulator-always-on;
+ };
+
+ reg_backlight: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "lcd-supply";
+ regulator-min-microvolt = <3200000>;
+ regulator-max-microvolt = <3200000>;
+ regulator-always-on;
+ };
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ stmpe610@41 {
+ compatible = "st,stmpe610";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x41>;
+ id = <0>;
+ blocks = <0x5>;
+ interrupts = <6 0x0>;
+ interrupt-parent = <&gpio7>;
+ irq-trigger = <0x1>;
+
+ stmpe_touchscreen {
+ compatible = "st,stmpe-ts";
+ reg = <0>;
+ st,sample-time = <4>;
+ st,mod-12b = <1>;
+ st,ref-sel = <0>;
+ st,adc-freq = <1>;
+ st,ave-ctrl = <3>;
+ st,touch-det-delay = <3>;
+ st,settling = <4>;
+ st,fraction-z = <7>;
+ st,i-drive = <1>;
+ };
+ };
+
+ eeprom: eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ pagesize = <32>;
+ };
+
+ rtc: rtc@68 {
+ compatible = "stm,m41t62";
+ reg = <0x68>;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx53-m53evk {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK 0x80000000
+ MX53_PAD_EIM_EB3__GPIO2_31 0x80000000
+ MX53_PAD_PATA_DA_0__GPIO7_6 0x80000000
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX53_PAD_EIM_D16__I2C2_SDA 0xc0000000
+ MX53_PAD_EIM_EB2__I2C2_SCL 0xc0000000
+ >;
+ };
+
+ pinctrl_nand: nandgrp {
+ fsl,pins = <
+ MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B 0x4
+ MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B 0x4
+ MX53_PAD_NANDF_CLE__EMI_NANDF_CLE 0x4
+ MX53_PAD_NANDF_ALE__EMI_NANDF_ALE 0x4
+ MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B 0xe0
+ MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0 0xe0
+ MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0 0x4
+ MX53_PAD_PATA_DATA0__EMI_NANDF_D_0 0xa4
+ MX53_PAD_PATA_DATA1__EMI_NANDF_D_1 0xa4
+ MX53_PAD_PATA_DATA2__EMI_NANDF_D_2 0xa4
+ MX53_PAD_PATA_DATA3__EMI_NANDF_D_3 0xa4
+ MX53_PAD_PATA_DATA4__EMI_NANDF_D_4 0xa4
+ MX53_PAD_PATA_DATA5__EMI_NANDF_D_5 0xa4
+ MX53_PAD_PATA_DATA6__EMI_NANDF_D_6 0xa4
+ MX53_PAD_PATA_DATA7__EMI_NANDF_D_7 0xa4
+ >;
+ };
+ };
+};
+
+&nfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx53-m53evk.dts b/arch/arm/boot/dts/imx53-m53evk.dts
new file mode 100644
index 000000000..d0e0f57eb
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-m53evk.dts
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2013 Marek Vasut <marex@denx.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
+ */
+
+/dts-v1/;
+#include "imx53-m53.dtsi"
+
+/ {
+ model = "DENX M53EVK";
+ compatible = "denx,imx53-m53evk", "fsl,imx53";
+
+ display1: display@di1 {
+ compatible = "fsl,imx-parallel-display";
+ interface-pix-fmt = "bgr666";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu_disp1>;
+
+ display-timings {
+ 800x480p60 {
+ native-mode;
+ clock-frequency = <31500000>;
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <40>;
+ hback-porch = <88>;
+ hsync-len = <128>;
+ vback-porch = <33>;
+ vfront-porch = <9>;
+ vsync-len = <3>;
+ vsync-active = <1>;
+ };
+ };
+
+ port {
+ display1_in: endpoint {
+ remote-endpoint = <&ipu_di1_disp1>;
+ };
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 3000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ power-supply = <&reg_backlight>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pin_gpio>;
+
+ user1 {
+ label = "user1";
+ gpios = <&gpio2 8 0>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ user2 {
+ label = "user2";
+ gpios = <&gpio2 9 0>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usbh1_vbus: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 2 0>;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx53-m53evk-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx53-m53evk-sgtl5000";
+ ssi-controller = <&ssi2>;
+ audio-codec = <&sgtl5000>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "LINE_IN", "Line In Jack",
+ "Headphone Jack", "HP_OUT",
+ "Ext Spk", "LINE_OUT";
+ mux-int-port = <2>;
+ mux-ext-port = <4>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can1>;
+ status = "okay";
+};
+
+&can2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can2>;
+ status = "okay";
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ cd-gpios = <&gpio1 1 0>;
+ wp-gpios = <&gpio1 9 0>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ phy-mode = "rmii";
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ sgtl5000: codec@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ VDDA-supply = <&reg_3p2v>;
+ VDDIO-supply = <&reg_3p2v>;
+ clocks = <&clks IMX5_CLK_SSI_EXT1_GATE>;
+ };
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx53-m53evk {
+ pinctrl_usb: usbgrp {
+ fsl,pins = <
+ MX53_PAD_GPIO_2__GPIO1_2 0x80000000
+ MX53_PAD_GPIO_3__USBOH3_USBH1_OC 0x80000000
+ >;
+ };
+
+ led_pin_gpio: led_gpio@0 {
+ fsl,pins = <
+ MX53_PAD_PATA_DATA8__GPIO2_8 0x80000000
+ MX53_PAD_PATA_DATA9__GPIO2_9 0x80000000
+ >;
+ };
+
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX53_PAD_SD2_DATA3__AUDMUX_AUD4_TXC 0x80000000
+ MX53_PAD_SD2_DATA2__AUDMUX_AUD4_TXD 0x80000000
+ MX53_PAD_SD2_DATA1__AUDMUX_AUD4_TXFS 0x80000000
+ MX53_PAD_SD2_DATA0__AUDMUX_AUD4_RXD 0x80000000
+ >;
+ };
+
+ pinctrl_can1: can1grp {
+ fsl,pins = <
+ MX53_PAD_GPIO_7__CAN1_TXCAN 0x80000000
+ MX53_PAD_GPIO_8__CAN1_RXCAN 0x80000000
+ >;
+ };
+
+ pinctrl_can2: can2grp {
+ fsl,pins = <
+ MX53_PAD_KEY_COL4__CAN2_TXCAN 0x80000000
+ MX53_PAD_KEY_ROW4__CAN2_RXCAN 0x80000000
+ >;
+ };
+
+ pinctrl_esdhc1: esdhc1grp {
+ fsl,pins = <
+ MX53_PAD_SD1_DATA0__ESDHC1_DAT0 0x1d5
+ MX53_PAD_SD1_DATA1__ESDHC1_DAT1 0x1d5
+ MX53_PAD_SD1_DATA2__ESDHC1_DAT2 0x1d5
+ MX53_PAD_SD1_DATA3__ESDHC1_DAT3 0x1d5
+ MX53_PAD_SD1_CMD__ESDHC1_CMD 0x1d5
+ MX53_PAD_SD1_CLK__ESDHC1_CLK 0x1d5
+ >;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX53_PAD_FEC_MDC__FEC_MDC 0x80000000
+ MX53_PAD_FEC_MDIO__FEC_MDIO 0x80000000
+ MX53_PAD_FEC_REF_CLK__FEC_TX_CLK 0x80000000
+ MX53_PAD_FEC_RX_ER__FEC_RX_ER 0x80000000
+ MX53_PAD_FEC_CRS_DV__FEC_RX_DV 0x80000000
+ MX53_PAD_FEC_RXD1__FEC_RDATA_1 0x80000000
+ MX53_PAD_FEC_RXD0__FEC_RDATA_0 0x80000000
+ MX53_PAD_FEC_TX_EN__FEC_TX_EN 0x80000000
+ MX53_PAD_FEC_TXD1__FEC_TDATA_1 0x80000000
+ MX53_PAD_FEC_TXD0__FEC_TDATA_0 0x80000000
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX53_PAD_EIM_D21__I2C1_SCL 0xc0000000
+ MX53_PAD_EIM_D28__I2C1_SDA 0xc0000000
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX53_PAD_GPIO_6__I2C3_SDA 0xc0000000
+ MX53_PAD_GPIO_5__I2C3_SCL 0xc0000000
+ >;
+ };
+
+ pinctrl_ipu_disp1: ipudisp1grp {
+ fsl,pins = <
+ MX53_PAD_EIM_DA9__IPU_DISP1_DAT_0 0x5
+ MX53_PAD_EIM_DA8__IPU_DISP1_DAT_1 0x5
+ MX53_PAD_EIM_DA7__IPU_DISP1_DAT_2 0x5
+ MX53_PAD_EIM_DA6__IPU_DISP1_DAT_3 0x5
+ MX53_PAD_EIM_DA5__IPU_DISP1_DAT_4 0x5
+ MX53_PAD_EIM_DA4__IPU_DISP1_DAT_5 0x5
+ MX53_PAD_EIM_DA3__IPU_DISP1_DAT_6 0x5
+ MX53_PAD_EIM_DA2__IPU_DISP1_DAT_7 0x5
+ MX53_PAD_EIM_DA1__IPU_DISP1_DAT_8 0x5
+ MX53_PAD_EIM_DA0__IPU_DISP1_DAT_9 0x5
+ MX53_PAD_EIM_EB1__IPU_DISP1_DAT_10 0x5
+ MX53_PAD_EIM_EB0__IPU_DISP1_DAT_11 0x5
+ MX53_PAD_EIM_A17__IPU_DISP1_DAT_12 0x5
+ MX53_PAD_EIM_A18__IPU_DISP1_DAT_13 0x5
+ MX53_PAD_EIM_A19__IPU_DISP1_DAT_14 0x5
+ MX53_PAD_EIM_A20__IPU_DISP1_DAT_15 0x5
+ MX53_PAD_EIM_A21__IPU_DISP1_DAT_16 0x5
+ MX53_PAD_EIM_A22__IPU_DISP1_DAT_17 0x5
+ MX53_PAD_EIM_A23__IPU_DISP1_DAT_18 0x5
+ MX53_PAD_EIM_A24__IPU_DISP1_DAT_19 0x5
+ MX53_PAD_EIM_D31__IPU_DISP1_DAT_20 0x5
+ MX53_PAD_EIM_D30__IPU_DISP1_DAT_21 0x5
+ MX53_PAD_EIM_D26__IPU_DISP1_DAT_22 0x5
+ MX53_PAD_EIM_D27__IPU_DISP1_DAT_23 0x5
+ MX53_PAD_EIM_A16__IPU_DI1_DISP_CLK 0x5
+ MX53_PAD_EIM_DA13__IPU_DI1_D0_CS 0x5
+ MX53_PAD_EIM_DA14__IPU_DI1_D1_CS 0x5
+ MX53_PAD_EIM_DA15__IPU_DI1_PIN1 0x5
+ MX53_PAD_EIM_DA11__IPU_DI1_PIN2 0x5
+ MX53_PAD_EIM_DA12__IPU_DI1_PIN3 0x5
+ MX53_PAD_EIM_A25__IPU_DI1_PIN12 0x5
+ MX53_PAD_EIM_DA10__IPU_DI1_PIN15 0x5
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX53_PAD_DISP0_DAT8__PWM1_PWMO 0x5
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX53_PAD_PATA_DIOW__UART1_TXD_MUX 0x1e4
+ MX53_PAD_PATA_DMACK__UART1_RXD_MUX 0x1e4
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX 0x1e4
+ MX53_PAD_PATA_DMARQ__UART2_TXD_MUX 0x1e4
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX53_PAD_PATA_CS_0__UART3_TXD_MUX 0x1e4
+ MX53_PAD_PATA_CS_1__UART3_RXD_MUX 0x1e4
+ MX53_PAD_PATA_DA_1__UART3_CTS 0x1e4
+ MX53_PAD_PATA_DA_2__UART3_RTS 0x1e4
+ >;
+ };
+ };
+};
+
+&ipu_di1_disp1 {
+ remote-endpoint = <&display1_in>;
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&sata {
+ status = "okay";
+};
+
+&ssi2 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
+
+&usbh1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb>;
+ vbus-supply = <&reg_usbh1_vbus>;
+ phy_type = "utmi";
+ status = "okay";
+};
+
+&usbotg {
+ dr_mode = "peripheral";
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx53-mba53.dts b/arch/arm/boot/dts/imx53-mba53.dts
new file mode 100644
index 000000000..2e44d2aba
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-mba53.dts
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx53-tqma53.dtsi"
+
+/ {
+ model = "TQ MBa53 starter kit";
+ compatible = "tq,mba53", "tq,tqma53", "fsl,imx53";
+
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm2 0 50000>;
+ brightness-levels = <0 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100>;
+ default-brightness-level = <10>;
+ enable-gpios = <&gpio7 7 0>;
+ power-supply = <&reg_backlight>;
+ };
+
+ disp1: display@disp1 {
+ compatible = "fsl,imx-parallel-display";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_disp1_1>;
+ interface-pix-fmt = "rgb24";
+ status = "disabled";
+
+ port {
+ display1_in: endpoint {
+ remote-endpoint = <&ipu_di1_disp1>;
+ };
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_backlight: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "lcd-supply";
+ gpio = <&gpio2 5 0>;
+ startup-delay-us = <5000>;
+ };
+
+ reg_3p2v: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "3P2V";
+ regulator-min-microvolt = <3200000>;
+ regulator-max-microvolt = <3200000>;
+ regulator-always-on;
+ };
+ };
+
+ sound {
+ compatible = "tq,imx53-mba53-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx53-mba53-sgtl5000";
+ ssi-controller = <&ssi2>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <2>;
+ mux-ext-port = <5>;
+ };
+};
+
+&ldb {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds1_1>;
+ status = "disabled";
+};
+
+&iomuxc {
+ lvds1 {
+ pinctrl_lvds1_1: lvds1-grp1 {
+ fsl,pins = <
+ MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 0x80000000
+ MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK 0x80000000
+ MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 0x80000000
+ MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 0x80000000
+ MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 0x80000000
+ >;
+ };
+
+ pinctrl_lvds1_2: lvds1-grp2 {
+ fsl,pins = <
+ MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 0x80000000
+ MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 0x80000000
+ MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK 0x80000000
+ MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 0x80000000
+ MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 0x80000000
+ >;
+ };
+ };
+
+ disp1 {
+ pinctrl_disp1_1: disp1-grp1 {
+ fsl,pins = <
+ MX53_PAD_EIM_A16__IPU_DI1_DISP_CLK 0x80000000 /* DISP1_CLK */
+ MX53_PAD_EIM_DA10__IPU_DI1_PIN15 0x80000000 /* DISP1_DRDY */
+ MX53_PAD_EIM_D23__IPU_DI1_PIN2 0x80000000 /* DISP1_HSYNC */
+ MX53_PAD_EIM_EB3__IPU_DI1_PIN3 0x80000000 /* DISP1_VSYNC */
+ MX53_PAD_EIM_D26__IPU_DISP1_DAT_22 0x80000000
+ MX53_PAD_EIM_D27__IPU_DISP1_DAT_23 0x80000000
+ MX53_PAD_EIM_D30__IPU_DISP1_DAT_21 0x80000000
+ MX53_PAD_EIM_D31__IPU_DISP1_DAT_20 0x80000000
+ MX53_PAD_EIM_A24__IPU_DISP1_DAT_19 0x80000000
+ MX53_PAD_EIM_A23__IPU_DISP1_DAT_18 0x80000000
+ MX53_PAD_EIM_A22__IPU_DISP1_DAT_17 0x80000000
+ MX53_PAD_EIM_A21__IPU_DISP1_DAT_16 0x80000000
+ MX53_PAD_EIM_A20__IPU_DISP1_DAT_15 0x80000000
+ MX53_PAD_EIM_A19__IPU_DISP1_DAT_14 0x80000000
+ MX53_PAD_EIM_A18__IPU_DISP1_DAT_13 0x80000000
+ MX53_PAD_EIM_A17__IPU_DISP1_DAT_12 0x80000000
+ MX53_PAD_EIM_EB0__IPU_DISP1_DAT_11 0x80000000
+ MX53_PAD_EIM_EB1__IPU_DISP1_DAT_10 0x80000000
+ MX53_PAD_EIM_DA0__IPU_DISP1_DAT_9 0x80000000
+ MX53_PAD_EIM_DA1__IPU_DISP1_DAT_8 0x80000000
+ MX53_PAD_EIM_DA2__IPU_DISP1_DAT_7 0x80000000
+ MX53_PAD_EIM_DA3__IPU_DISP1_DAT_6 0x80000000
+ MX53_PAD_EIM_DA4__IPU_DISP1_DAT_5 0x80000000
+ MX53_PAD_EIM_DA5__IPU_DISP1_DAT_4 0x80000000
+ MX53_PAD_EIM_DA6__IPU_DISP1_DAT_3 0x80000000
+ MX53_PAD_EIM_DA7__IPU_DISP1_DAT_2 0x80000000
+ MX53_PAD_EIM_DA8__IPU_DISP1_DAT_1 0x80000000
+ MX53_PAD_EIM_DA9__IPU_DISP1_DAT_0 0x80000000
+ >;
+ };
+ };
+
+ tve {
+ pinctrl_vga_sync_1: vgasync-grp1 {
+ fsl,pins = <
+ /* VGA_VSYNC, HSYNC with max drive strength */
+ MX53_PAD_EIM_CS1__IPU_DI1_PIN6 0xe6
+ MX53_PAD_EIM_DA15__IPU_DI1_PIN4 0xe6
+ >;
+ };
+ };
+};
+
+&ipu_di1_disp1 {
+ remote-endpoint = <&display1_in>;
+};
+
+&cspi {
+ status = "okay";
+};
+
+&audmux {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+};
+
+&i2c2 {
+ codec: sgtl5000@a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&clks IMX5_CLK_SSI_EXT1_GATE>;
+ VDDA-supply = <&reg_3p2v>;
+ VDDIO-supply = <&reg_3p2v>;
+ };
+
+ expander: pca9554@20 {
+ compatible = "pca9554";
+ reg = <0x20>;
+ interrupts = <109>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ };
+
+ sensor2: lm75@49 {
+ compatible = "lm75";
+ reg = <0x49>;
+ };
+};
+
+&fec {
+ phy-reset-gpios = <&gpio7 6 0>;
+ status = "okay";
+};
+
+&esdhc2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&ecspi1 {
+ status = "okay";
+};
+
+&usbotg {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbh1 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&ssi2 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&can1 {
+ status = "okay";
+};
+
+&can2 {
+ status = "okay";
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+&tve {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_vga_sync_1>;
+ ddc-i2c-bus = <&i2c3>;
+ fsl,tve-mode = "vga";
+ fsl,hsync-pin = <4>;
+ fsl,vsync-pin = <6>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx53-pinfunc.h b/arch/arm/boot/dts/imx53-pinfunc.h
new file mode 100644
index 000000000..aec406bc6
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-pinfunc.h
@@ -0,0 +1,1189 @@
+/*
+ * Copyright 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX53_PINFUNC_H
+#define __DTS_IMX53_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX53_PAD_GPIO_19__KPP_COL_5 0x020 0x348 0x840 0x0 0x0
+#define MX53_PAD_GPIO_19__GPIO4_5 0x020 0x348 0x000 0x1 0x0
+#define MX53_PAD_GPIO_19__CCM_CLKO 0x020 0x348 0x000 0x2 0x0
+#define MX53_PAD_GPIO_19__SPDIF_OUT1 0x020 0x348 0x000 0x3 0x0
+#define MX53_PAD_GPIO_19__RTC_CE_RTC_EXT_TRIG2 0x020 0x348 0x000 0x4 0x0
+#define MX53_PAD_GPIO_19__ECSPI1_RDY 0x020 0x348 0x000 0x5 0x0
+#define MX53_PAD_GPIO_19__FEC_TDATA_3 0x020 0x348 0x000 0x6 0x0
+#define MX53_PAD_GPIO_19__SRC_INT_BOOT 0x020 0x348 0x000 0x7 0x0
+#define MX53_PAD_KEY_COL0__KPP_COL_0 0x024 0x34c 0x000 0x0 0x0
+#define MX53_PAD_KEY_COL0__GPIO4_6 0x024 0x34c 0x000 0x1 0x0
+#define MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC 0x024 0x34c 0x758 0x2 0x0
+#define MX53_PAD_KEY_COL0__UART4_TXD_MUX 0x024 0x34c 0x000 0x4 0x0
+#define MX53_PAD_KEY_COL0__ECSPI1_SCLK 0x024 0x34c 0x79c 0x5 0x0
+#define MX53_PAD_KEY_COL0__FEC_RDATA_3 0x024 0x34c 0x000 0x6 0x0
+#define MX53_PAD_KEY_COL0__SRC_ANY_PU_RST 0x024 0x34c 0x000 0x7 0x0
+#define MX53_PAD_KEY_ROW0__KPP_ROW_0 0x028 0x350 0x000 0x0 0x0
+#define MX53_PAD_KEY_ROW0__GPIO4_7 0x028 0x350 0x000 0x1 0x0
+#define MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD 0x028 0x350 0x74c 0x2 0x0
+#define MX53_PAD_KEY_ROW0__UART4_RXD_MUX 0x028 0x350 0x890 0x4 0x1
+#define MX53_PAD_KEY_ROW0__ECSPI1_MOSI 0x028 0x350 0x7a4 0x5 0x0
+#define MX53_PAD_KEY_ROW0__FEC_TX_ER 0x028 0x350 0x000 0x6 0x0
+#define MX53_PAD_KEY_COL1__KPP_COL_1 0x02c 0x354 0x000 0x0 0x0
+#define MX53_PAD_KEY_COL1__GPIO4_8 0x02c 0x354 0x000 0x1 0x0
+#define MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS 0x02c 0x354 0x75c 0x2 0x0
+#define MX53_PAD_KEY_COL1__UART5_TXD_MUX 0x02c 0x354 0x000 0x4 0x0
+#define MX53_PAD_KEY_COL1__ECSPI1_MISO 0x02c 0x354 0x7a0 0x5 0x0
+#define MX53_PAD_KEY_COL1__FEC_RX_CLK 0x02c 0x354 0x808 0x6 0x0
+#define MX53_PAD_KEY_COL1__USBPHY1_TXREADY 0x02c 0x354 0x000 0x7 0x0
+#define MX53_PAD_KEY_ROW1__KPP_ROW_1 0x030 0x358 0x000 0x0 0x0
+#define MX53_PAD_KEY_ROW1__GPIO4_9 0x030 0x358 0x000 0x1 0x0
+#define MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD 0x030 0x358 0x748 0x2 0x0
+#define MX53_PAD_KEY_ROW1__UART5_RXD_MUX 0x030 0x358 0x898 0x4 0x1
+#define MX53_PAD_KEY_ROW1__ECSPI1_SS0 0x030 0x358 0x7a8 0x5 0x0
+#define MX53_PAD_KEY_ROW1__FEC_COL 0x030 0x358 0x800 0x6 0x0
+#define MX53_PAD_KEY_ROW1__USBPHY1_RXVALID 0x030 0x358 0x000 0x7 0x0
+#define MX53_PAD_KEY_COL2__KPP_COL_2 0x034 0x35c 0x000 0x0 0x0
+#define MX53_PAD_KEY_COL2__GPIO4_10 0x034 0x35c 0x000 0x1 0x0
+#define MX53_PAD_KEY_COL2__CAN1_TXCAN 0x034 0x35c 0x000 0x2 0x0
+#define MX53_PAD_KEY_COL2__FEC_MDIO 0x034 0x35c 0x804 0x4 0x0
+#define MX53_PAD_KEY_COL2__ECSPI1_SS1 0x034 0x35c 0x7ac 0x5 0x0
+#define MX53_PAD_KEY_COL2__FEC_RDATA_2 0x034 0x35c 0x000 0x6 0x0
+#define MX53_PAD_KEY_COL2__USBPHY1_RXACTIVE 0x034 0x35c 0x000 0x7 0x0
+#define MX53_PAD_KEY_ROW2__KPP_ROW_2 0x038 0x360 0x000 0x0 0x0
+#define MX53_PAD_KEY_ROW2__GPIO4_11 0x038 0x360 0x000 0x1 0x0
+#define MX53_PAD_KEY_ROW2__CAN1_RXCAN 0x038 0x360 0x760 0x2 0x0
+#define MX53_PAD_KEY_ROW2__FEC_MDC 0x038 0x360 0x000 0x4 0x0
+#define MX53_PAD_KEY_ROW2__ECSPI1_SS2 0x038 0x360 0x7b0 0x5 0x0
+#define MX53_PAD_KEY_ROW2__FEC_TDATA_2 0x038 0x360 0x000 0x6 0x0
+#define MX53_PAD_KEY_ROW2__USBPHY1_RXERROR 0x038 0x360 0x000 0x7 0x0
+#define MX53_PAD_KEY_COL3__KPP_COL_3 0x03c 0x364 0x000 0x0 0x0
+#define MX53_PAD_KEY_COL3__GPIO4_12 0x03c 0x364 0x000 0x1 0x0
+#define MX53_PAD_KEY_COL3__USBOH3_H2_DP 0x03c 0x364 0x000 0x2 0x0
+#define MX53_PAD_KEY_COL3__SPDIF_IN1 0x03c 0x364 0x870 0x3 0x0
+#define MX53_PAD_KEY_COL3__I2C2_SCL 0x03c 0x364 0x81c 0x4 0x0
+#define MX53_PAD_KEY_COL3__ECSPI1_SS3 0x03c 0x364 0x7b4 0x5 0x0
+#define MX53_PAD_KEY_COL3__FEC_CRS 0x03c 0x364 0x000 0x6 0x0
+#define MX53_PAD_KEY_COL3__USBPHY1_SIECLOCK 0x03c 0x364 0x000 0x7 0x0
+#define MX53_PAD_KEY_ROW3__KPP_ROW_3 0x040 0x368 0x000 0x0 0x0
+#define MX53_PAD_KEY_ROW3__GPIO4_13 0x040 0x368 0x000 0x1 0x0
+#define MX53_PAD_KEY_ROW3__USBOH3_H2_DM 0x040 0x368 0x000 0x2 0x0
+#define MX53_PAD_KEY_ROW3__CCM_ASRC_EXT_CLK 0x040 0x368 0x768 0x3 0x0
+#define MX53_PAD_KEY_ROW3__I2C2_SDA 0x040 0x368 0x820 0x4 0x0
+#define MX53_PAD_KEY_ROW3__OSC32K_32K_OUT 0x040 0x368 0x000 0x5 0x0
+#define MX53_PAD_KEY_ROW3__CCM_PLL4_BYP 0x040 0x368 0x77c 0x6 0x0
+#define MX53_PAD_KEY_ROW3__USBPHY1_LINESTATE_0 0x040 0x368 0x000 0x7 0x0
+#define MX53_PAD_KEY_COL4__KPP_COL_4 0x044 0x36c 0x000 0x0 0x0
+#define MX53_PAD_KEY_COL4__GPIO4_14 0x044 0x36c 0x000 0x1 0x0
+#define MX53_PAD_KEY_COL4__CAN2_TXCAN 0x044 0x36c 0x000 0x2 0x0
+#define MX53_PAD_KEY_COL4__IPU_SISG_4 0x044 0x36c 0x000 0x3 0x0
+#define MX53_PAD_KEY_COL4__UART5_RTS 0x044 0x36c 0x894 0x4 0x0
+#define MX53_PAD_KEY_COL4__USBOH3_USBOTG_OC 0x044 0x36c 0x89c 0x5 0x0
+#define MX53_PAD_KEY_COL4__USBPHY1_LINESTATE_1 0x044 0x36c 0x000 0x7 0x0
+#define MX53_PAD_KEY_ROW4__KPP_ROW_4 0x048 0x370 0x000 0x0 0x0
+#define MX53_PAD_KEY_ROW4__GPIO4_15 0x048 0x370 0x000 0x1 0x0
+#define MX53_PAD_KEY_ROW4__CAN2_RXCAN 0x048 0x370 0x764 0x2 0x0
+#define MX53_PAD_KEY_ROW4__IPU_SISG_5 0x048 0x370 0x000 0x3 0x0
+#define MX53_PAD_KEY_ROW4__UART5_CTS 0x048 0x370 0x000 0x4 0x0
+#define MX53_PAD_KEY_ROW4__USBOH3_USBOTG_PWR 0x048 0x370 0x000 0x5 0x0
+#define MX53_PAD_KEY_ROW4__USBPHY1_VBUSVALID 0x048 0x370 0x000 0x7 0x0
+#define MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK 0x04c 0x378 0x000 0x0 0x0
+#define MX53_PAD_DI0_DISP_CLK__GPIO4_16 0x04c 0x378 0x000 0x1 0x0
+#define MX53_PAD_DI0_DISP_CLK__USBOH3_USBH2_DIR 0x04c 0x378 0x000 0x2 0x0
+#define MX53_PAD_DI0_DISP_CLK__SDMA_DEBUG_CORE_STATE_0 0x04c 0x378 0x000 0x5 0x0
+#define MX53_PAD_DI0_DISP_CLK__EMI_EMI_DEBUG_0 0x04c 0x378 0x000 0x6 0x0
+#define MX53_PAD_DI0_DISP_CLK__USBPHY1_AVALID 0x04c 0x378 0x000 0x7 0x0
+#define MX53_PAD_DI0_PIN15__IPU_DI0_PIN15 0x050 0x37c 0x000 0x0 0x0
+#define MX53_PAD_DI0_PIN15__GPIO4_17 0x050 0x37c 0x000 0x1 0x0
+#define MX53_PAD_DI0_PIN15__AUDMUX_AUD6_TXC 0x050 0x37c 0x000 0x2 0x0
+#define MX53_PAD_DI0_PIN15__SDMA_DEBUG_CORE_STATE_1 0x050 0x37c 0x000 0x5 0x0
+#define MX53_PAD_DI0_PIN15__EMI_EMI_DEBUG_1 0x050 0x37c 0x000 0x6 0x0
+#define MX53_PAD_DI0_PIN15__USBPHY1_BVALID 0x050 0x37c 0x000 0x7 0x0
+#define MX53_PAD_DI0_PIN2__IPU_DI0_PIN2 0x054 0x380 0x000 0x0 0x0
+#define MX53_PAD_DI0_PIN2__GPIO4_18 0x054 0x380 0x000 0x1 0x0
+#define MX53_PAD_DI0_PIN2__AUDMUX_AUD6_TXD 0x054 0x380 0x000 0x2 0x0
+#define MX53_PAD_DI0_PIN2__SDMA_DEBUG_CORE_STATE_2 0x054 0x380 0x000 0x5 0x0
+#define MX53_PAD_DI0_PIN2__EMI_EMI_DEBUG_2 0x054 0x380 0x000 0x6 0x0
+#define MX53_PAD_DI0_PIN2__USBPHY1_ENDSESSION 0x054 0x380 0x000 0x7 0x0
+#define MX53_PAD_DI0_PIN3__IPU_DI0_PIN3 0x058 0x384 0x000 0x0 0x0
+#define MX53_PAD_DI0_PIN3__GPIO4_19 0x058 0x384 0x000 0x1 0x0
+#define MX53_PAD_DI0_PIN3__AUDMUX_AUD6_TXFS 0x058 0x384 0x000 0x2 0x0
+#define MX53_PAD_DI0_PIN3__SDMA_DEBUG_CORE_STATE_3 0x058 0x384 0x000 0x5 0x0
+#define MX53_PAD_DI0_PIN3__EMI_EMI_DEBUG_3 0x058 0x384 0x000 0x6 0x0
+#define MX53_PAD_DI0_PIN3__USBPHY1_IDDIG 0x058 0x384 0x000 0x7 0x0
+#define MX53_PAD_DI0_PIN4__IPU_DI0_PIN4 0x05c 0x388 0x000 0x0 0x0
+#define MX53_PAD_DI0_PIN4__GPIO4_20 0x05c 0x388 0x000 0x1 0x0
+#define MX53_PAD_DI0_PIN4__AUDMUX_AUD6_RXD 0x05c 0x388 0x000 0x2 0x0
+#define MX53_PAD_DI0_PIN4__ESDHC1_WP 0x05c 0x388 0x7fc 0x3 0x0
+#define MX53_PAD_DI0_PIN4__SDMA_DEBUG_YIELD 0x05c 0x388 0x000 0x5 0x0
+#define MX53_PAD_DI0_PIN4__EMI_EMI_DEBUG_4 0x05c 0x388 0x000 0x6 0x0
+#define MX53_PAD_DI0_PIN4__USBPHY1_HOSTDISCONNECT 0x05c 0x388 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0 0x060 0x38c 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT0__GPIO4_21 0x060 0x38c 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT0__CSPI_SCLK 0x060 0x38c 0x780 0x2 0x0
+#define MX53_PAD_DISP0_DAT0__USBOH3_USBH2_DATA_0 0x060 0x38c 0x000 0x3 0x0
+#define MX53_PAD_DISP0_DAT0__SDMA_DEBUG_CORE_RUN 0x060 0x38c 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT0__EMI_EMI_DEBUG_5 0x060 0x38c 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT0__USBPHY2_TXREADY 0x060 0x38c 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1 0x064 0x390 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT1__GPIO4_22 0x064 0x390 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT1__CSPI_MOSI 0x064 0x390 0x788 0x2 0x0
+#define MX53_PAD_DISP0_DAT1__USBOH3_USBH2_DATA_1 0x064 0x390 0x000 0x3 0x0
+#define MX53_PAD_DISP0_DAT1__SDMA_DEBUG_EVENT_CHANNEL_SEL 0x064 0x390 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT1__EMI_EMI_DEBUG_6 0x064 0x390 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT1__USBPHY2_RXVALID 0x064 0x390 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2 0x068 0x394 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT2__GPIO4_23 0x068 0x394 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT2__CSPI_MISO 0x068 0x394 0x784 0x2 0x0
+#define MX53_PAD_DISP0_DAT2__USBOH3_USBH2_DATA_2 0x068 0x394 0x000 0x3 0x0
+#define MX53_PAD_DISP0_DAT2__SDMA_DEBUG_MODE 0x068 0x394 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT2__EMI_EMI_DEBUG_7 0x068 0x394 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT2__USBPHY2_RXACTIVE 0x068 0x394 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3 0x06c 0x398 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT3__GPIO4_24 0x06c 0x398 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT3__CSPI_SS0 0x06c 0x398 0x78c 0x2 0x0
+#define MX53_PAD_DISP0_DAT3__USBOH3_USBH2_DATA_3 0x06c 0x398 0x000 0x3 0x0
+#define MX53_PAD_DISP0_DAT3__SDMA_DEBUG_BUS_ERROR 0x06c 0x398 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT3__EMI_EMI_DEBUG_8 0x06c 0x398 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT3__USBPHY2_RXERROR 0x06c 0x398 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4 0x070 0x39c 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT4__GPIO4_25 0x070 0x39c 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT4__CSPI_SS1 0x070 0x39c 0x790 0x2 0x0
+#define MX53_PAD_DISP0_DAT4__USBOH3_USBH2_DATA_4 0x070 0x39c 0x000 0x3 0x0
+#define MX53_PAD_DISP0_DAT4__SDMA_DEBUG_BUS_RWB 0x070 0x39c 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT4__EMI_EMI_DEBUG_9 0x070 0x39c 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT4__USBPHY2_SIECLOCK 0x070 0x39c 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5 0x074 0x3a0 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT5__GPIO4_26 0x074 0x3a0 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT5__CSPI_SS2 0x074 0x3a0 0x794 0x2 0x0
+#define MX53_PAD_DISP0_DAT5__USBOH3_USBH2_DATA_5 0x074 0x3a0 0x000 0x3 0x0
+#define MX53_PAD_DISP0_DAT5__SDMA_DEBUG_MATCHED_DMBUS 0x074 0x3a0 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT5__EMI_EMI_DEBUG_10 0x074 0x3a0 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT5__USBPHY2_LINESTATE_0 0x074 0x3a0 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6 0x078 0x3a4 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT6__GPIO4_27 0x078 0x3a4 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT6__CSPI_SS3 0x078 0x3a4 0x798 0x2 0x0
+#define MX53_PAD_DISP0_DAT6__USBOH3_USBH2_DATA_6 0x078 0x3a4 0x000 0x3 0x0
+#define MX53_PAD_DISP0_DAT6__SDMA_DEBUG_RTBUFFER_WRITE 0x078 0x3a4 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT6__EMI_EMI_DEBUG_11 0x078 0x3a4 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT6__USBPHY2_LINESTATE_1 0x078 0x3a4 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7 0x07c 0x3a8 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT7__GPIO4_28 0x07c 0x3a8 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT7__CSPI_RDY 0x07c 0x3a8 0x000 0x2 0x0
+#define MX53_PAD_DISP0_DAT7__USBOH3_USBH2_DATA_7 0x07c 0x3a8 0x000 0x3 0x0
+#define MX53_PAD_DISP0_DAT7__SDMA_DEBUG_EVENT_CHANNEL_0 0x07c 0x3a8 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT7__EMI_EMI_DEBUG_12 0x07c 0x3a8 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT7__USBPHY2_VBUSVALID 0x07c 0x3a8 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8 0x080 0x3ac 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT8__GPIO4_29 0x080 0x3ac 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT8__PWM1_PWMO 0x080 0x3ac 0x000 0x2 0x0
+#define MX53_PAD_DISP0_DAT8__WDOG1_WDOG_B 0x080 0x3ac 0x000 0x3 0x0
+#define MX53_PAD_DISP0_DAT8__SDMA_DEBUG_EVENT_CHANNEL_1 0x080 0x3ac 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT8__EMI_EMI_DEBUG_13 0x080 0x3ac 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT8__USBPHY2_AVALID 0x080 0x3ac 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9 0x084 0x3b0 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT9__GPIO4_30 0x084 0x3b0 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT9__PWM2_PWMO 0x084 0x3b0 0x000 0x2 0x0
+#define MX53_PAD_DISP0_DAT9__WDOG2_WDOG_B 0x084 0x3b0 0x000 0x3 0x0
+#define MX53_PAD_DISP0_DAT9__SDMA_DEBUG_EVENT_CHANNEL_2 0x084 0x3b0 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT9__EMI_EMI_DEBUG_14 0x084 0x3b0 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT9__USBPHY2_VSTATUS_0 0x084 0x3b0 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10 0x088 0x3b4 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT10__GPIO4_31 0x088 0x3b4 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT10__USBOH3_USBH2_STP 0x088 0x3b4 0x000 0x2 0x0
+#define MX53_PAD_DISP0_DAT10__SDMA_DEBUG_EVENT_CHANNEL_3 0x088 0x3b4 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT10__EMI_EMI_DEBUG_15 0x088 0x3b4 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT10__USBPHY2_VSTATUS_1 0x088 0x3b4 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11 0x08c 0x3b8 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT11__GPIO5_5 0x08c 0x3b8 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT11__USBOH3_USBH2_NXT 0x08c 0x3b8 0x000 0x2 0x0
+#define MX53_PAD_DISP0_DAT11__SDMA_DEBUG_EVENT_CHANNEL_4 0x08c 0x3b8 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT11__EMI_EMI_DEBUG_16 0x08c 0x3b8 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT11__USBPHY2_VSTATUS_2 0x08c 0x3b8 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12 0x090 0x3bc 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT12__GPIO5_6 0x090 0x3bc 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT12__USBOH3_USBH2_CLK 0x090 0x3bc 0x000 0x2 0x0
+#define MX53_PAD_DISP0_DAT12__SDMA_DEBUG_EVENT_CHANNEL_5 0x090 0x3bc 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT12__EMI_EMI_DEBUG_17 0x090 0x3bc 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT12__USBPHY2_VSTATUS_3 0x090 0x3bc 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13 0x094 0x3c0 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT13__GPIO5_7 0x094 0x3c0 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT13__AUDMUX_AUD5_RXFS 0x094 0x3c0 0x754 0x3 0x0
+#define MX53_PAD_DISP0_DAT13__SDMA_DEBUG_EVT_CHN_LINES_0 0x094 0x3c0 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT13__EMI_EMI_DEBUG_18 0x094 0x3c0 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT13__USBPHY2_VSTATUS_4 0x094 0x3c0 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14 0x098 0x3c4 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT14__GPIO5_8 0x098 0x3c4 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT14__AUDMUX_AUD5_RXC 0x098 0x3c4 0x750 0x3 0x0
+#define MX53_PAD_DISP0_DAT14__SDMA_DEBUG_EVT_CHN_LINES_1 0x098 0x3c4 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT14__EMI_EMI_DEBUG_19 0x098 0x3c4 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT14__USBPHY2_VSTATUS_5 0x098 0x3c4 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15 0x09c 0x3c8 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT15__GPIO5_9 0x09c 0x3c8 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT15__ECSPI1_SS1 0x09c 0x3c8 0x7ac 0x2 0x1
+#define MX53_PAD_DISP0_DAT15__ECSPI2_SS1 0x09c 0x3c8 0x7c8 0x3 0x0
+#define MX53_PAD_DISP0_DAT15__SDMA_DEBUG_EVT_CHN_LINES_2 0x09c 0x3c8 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT15__EMI_EMI_DEBUG_20 0x09c 0x3c8 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT15__USBPHY2_VSTATUS_6 0x09c 0x3c8 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16 0x0a0 0x3cc 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT16__GPIO5_10 0x0a0 0x3cc 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT16__ECSPI2_MOSI 0x0a0 0x3cc 0x7c0 0x2 0x0
+#define MX53_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC 0x0a0 0x3cc 0x758 0x3 0x1
+#define MX53_PAD_DISP0_DAT16__SDMA_EXT_EVENT_0 0x0a0 0x3cc 0x868 0x4 0x0
+#define MX53_PAD_DISP0_DAT16__SDMA_DEBUG_EVT_CHN_LINES_3 0x0a0 0x3cc 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT16__EMI_EMI_DEBUG_21 0x0a0 0x3cc 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT16__USBPHY2_VSTATUS_7 0x0a0 0x3cc 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17 0x0a4 0x3d0 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT17__GPIO5_11 0x0a4 0x3d0 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT17__ECSPI2_MISO 0x0a4 0x3d0 0x7bc 0x2 0x0
+#define MX53_PAD_DISP0_DAT17__AUDMUX_AUD5_TXD 0x0a4 0x3d0 0x74c 0x3 0x1
+#define MX53_PAD_DISP0_DAT17__SDMA_EXT_EVENT_1 0x0a4 0x3d0 0x86c 0x4 0x0
+#define MX53_PAD_DISP0_DAT17__SDMA_DEBUG_EVT_CHN_LINES_4 0x0a4 0x3d0 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT17__EMI_EMI_DEBUG_22 0x0a4 0x3d0 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18 0x0a8 0x3d4 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT18__GPIO5_12 0x0a8 0x3d4 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT18__ECSPI2_SS0 0x0a8 0x3d4 0x7c4 0x2 0x0
+#define MX53_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS 0x0a8 0x3d4 0x75c 0x3 0x1
+#define MX53_PAD_DISP0_DAT18__AUDMUX_AUD4_RXFS 0x0a8 0x3d4 0x73c 0x4 0x0
+#define MX53_PAD_DISP0_DAT18__SDMA_DEBUG_EVT_CHN_LINES_5 0x0a8 0x3d4 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT18__EMI_EMI_DEBUG_23 0x0a8 0x3d4 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT18__EMI_WEIM_CS_2 0x0a8 0x3d4 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19 0x0ac 0x3d8 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT19__GPIO5_13 0x0ac 0x3d8 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT19__ECSPI2_SCLK 0x0ac 0x3d8 0x7b8 0x2 0x0
+#define MX53_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD 0x0ac 0x3d8 0x748 0x3 0x1
+#define MX53_PAD_DISP0_DAT19__AUDMUX_AUD4_RXC 0x0ac 0x3d8 0x738 0x4 0x0
+#define MX53_PAD_DISP0_DAT19__SDMA_DEBUG_EVT_CHN_LINES_6 0x0ac 0x3d8 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT19__EMI_EMI_DEBUG_24 0x0ac 0x3d8 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT19__EMI_WEIM_CS_3 0x0ac 0x3d8 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20 0x0b0 0x3dc 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT20__GPIO5_14 0x0b0 0x3dc 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT20__ECSPI1_SCLK 0x0b0 0x3dc 0x79c 0x2 0x1
+#define MX53_PAD_DISP0_DAT20__AUDMUX_AUD4_TXC 0x0b0 0x3dc 0x740 0x3 0x0
+#define MX53_PAD_DISP0_DAT20__SDMA_DEBUG_EVT_CHN_LINES_7 0x0b0 0x3dc 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT20__EMI_EMI_DEBUG_25 0x0b0 0x3dc 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT20__SATA_PHY_TDI 0x0b0 0x3dc 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21 0x0b4 0x3e0 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT21__GPIO5_15 0x0b4 0x3e0 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT21__ECSPI1_MOSI 0x0b4 0x3e0 0x7a4 0x2 0x1
+#define MX53_PAD_DISP0_DAT21__AUDMUX_AUD4_TXD 0x0b4 0x3e0 0x734 0x3 0x0
+#define MX53_PAD_DISP0_DAT21__SDMA_DEBUG_BUS_DEVICE_0 0x0b4 0x3e0 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT21__EMI_EMI_DEBUG_26 0x0b4 0x3e0 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT21__SATA_PHY_TDO 0x0b4 0x3e0 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22 0x0b8 0x3e4 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT22__GPIO5_16 0x0b8 0x3e4 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT22__ECSPI1_MISO 0x0b8 0x3e4 0x7a0 0x2 0x1
+#define MX53_PAD_DISP0_DAT22__AUDMUX_AUD4_TXFS 0x0b8 0x3e4 0x744 0x3 0x0
+#define MX53_PAD_DISP0_DAT22__SDMA_DEBUG_BUS_DEVICE_1 0x0b8 0x3e4 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT22__EMI_EMI_DEBUG_27 0x0b8 0x3e4 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT22__SATA_PHY_TCK 0x0b8 0x3e4 0x000 0x7 0x0
+#define MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23 0x0bc 0x3e8 0x000 0x0 0x0
+#define MX53_PAD_DISP0_DAT23__GPIO5_17 0x0bc 0x3e8 0x000 0x1 0x0
+#define MX53_PAD_DISP0_DAT23__ECSPI1_SS0 0x0bc 0x3e8 0x7a8 0x2 0x1
+#define MX53_PAD_DISP0_DAT23__AUDMUX_AUD4_RXD 0x0bc 0x3e8 0x730 0x3 0x0
+#define MX53_PAD_DISP0_DAT23__SDMA_DEBUG_BUS_DEVICE_2 0x0bc 0x3e8 0x000 0x5 0x0
+#define MX53_PAD_DISP0_DAT23__EMI_EMI_DEBUG_28 0x0bc 0x3e8 0x000 0x6 0x0
+#define MX53_PAD_DISP0_DAT23__SATA_PHY_TMS 0x0bc 0x3e8 0x000 0x7 0x0
+#define MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK 0x0c0 0x3ec 0x000 0x0 0x0
+#define MX53_PAD_CSI0_PIXCLK__GPIO5_18 0x0c0 0x3ec 0x000 0x1 0x0
+#define MX53_PAD_CSI0_PIXCLK__SDMA_DEBUG_PC_0 0x0c0 0x3ec 0x000 0x5 0x0
+#define MX53_PAD_CSI0_PIXCLK__EMI_EMI_DEBUG_29 0x0c0 0x3ec 0x000 0x6 0x0
+#define MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC 0x0c4 0x3f0 0x000 0x0 0x0
+#define MX53_PAD_CSI0_MCLK__GPIO5_19 0x0c4 0x3f0 0x000 0x1 0x0
+#define MX53_PAD_CSI0_MCLK__CCM_CSI0_MCLK 0x0c4 0x3f0 0x000 0x2 0x0
+#define MX53_PAD_CSI0_MCLK__SDMA_DEBUG_PC_1 0x0c4 0x3f0 0x000 0x5 0x0
+#define MX53_PAD_CSI0_MCLK__EMI_EMI_DEBUG_30 0x0c4 0x3f0 0x000 0x6 0x0
+#define MX53_PAD_CSI0_MCLK__TPIU_TRCTL 0x0c4 0x3f0 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DATA_EN__IPU_CSI0_DATA_EN 0x0c8 0x3f4 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DATA_EN__GPIO5_20 0x0c8 0x3f4 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DATA_EN__SDMA_DEBUG_PC_2 0x0c8 0x3f4 0x000 0x5 0x0
+#define MX53_PAD_CSI0_DATA_EN__EMI_EMI_DEBUG_31 0x0c8 0x3f4 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DATA_EN__TPIU_TRCLK 0x0c8 0x3f4 0x000 0x7 0x0
+#define MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC 0x0cc 0x3f8 0x000 0x0 0x0
+#define MX53_PAD_CSI0_VSYNC__GPIO5_21 0x0cc 0x3f8 0x000 0x1 0x0
+#define MX53_PAD_CSI0_VSYNC__SDMA_DEBUG_PC_3 0x0cc 0x3f8 0x000 0x5 0x0
+#define MX53_PAD_CSI0_VSYNC__EMI_EMI_DEBUG_32 0x0cc 0x3f8 0x000 0x6 0x0
+#define MX53_PAD_CSI0_VSYNC__TPIU_TRACE_0 0x0cc 0x3f8 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DAT4__IPU_CSI0_D_4 0x0d0 0x3fc 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DAT4__GPIO5_22 0x0d0 0x3fc 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DAT4__KPP_COL_5 0x0d0 0x3fc 0x840 0x2 0x1
+#define MX53_PAD_CSI0_DAT4__ECSPI1_SCLK 0x0d0 0x3fc 0x79c 0x3 0x2
+#define MX53_PAD_CSI0_DAT4__USBOH3_USBH3_STP 0x0d0 0x3fc 0x000 0x4 0x0
+#define MX53_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC 0x0d0 0x3fc 0x000 0x5 0x0
+#define MX53_PAD_CSI0_DAT4__EMI_EMI_DEBUG_33 0x0d0 0x3fc 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DAT4__TPIU_TRACE_1 0x0d0 0x3fc 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DAT5__IPU_CSI0_D_5 0x0d4 0x400 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DAT5__GPIO5_23 0x0d4 0x400 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DAT5__KPP_ROW_5 0x0d4 0x400 0x84c 0x2 0x0
+#define MX53_PAD_CSI0_DAT5__ECSPI1_MOSI 0x0d4 0x400 0x7a4 0x3 0x2
+#define MX53_PAD_CSI0_DAT5__USBOH3_USBH3_NXT 0x0d4 0x400 0x000 0x4 0x0
+#define MX53_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD 0x0d4 0x400 0x000 0x5 0x0
+#define MX53_PAD_CSI0_DAT5__EMI_EMI_DEBUG_34 0x0d4 0x400 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DAT5__TPIU_TRACE_2 0x0d4 0x400 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DAT6__IPU_CSI0_D_6 0x0d8 0x404 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DAT6__GPIO5_24 0x0d8 0x404 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DAT6__KPP_COL_6 0x0d8 0x404 0x844 0x2 0x0
+#define MX53_PAD_CSI0_DAT6__ECSPI1_MISO 0x0d8 0x404 0x7a0 0x3 0x2
+#define MX53_PAD_CSI0_DAT6__USBOH3_USBH3_CLK 0x0d8 0x404 0x000 0x4 0x0
+#define MX53_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS 0x0d8 0x404 0x000 0x5 0x0
+#define MX53_PAD_CSI0_DAT6__EMI_EMI_DEBUG_35 0x0d8 0x404 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DAT6__TPIU_TRACE_3 0x0d8 0x404 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DAT7__IPU_CSI0_D_7 0x0dc 0x408 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DAT7__GPIO5_25 0x0dc 0x408 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DAT7__KPP_ROW_6 0x0dc 0x408 0x850 0x2 0x0
+#define MX53_PAD_CSI0_DAT7__ECSPI1_SS0 0x0dc 0x408 0x7a8 0x3 0x2
+#define MX53_PAD_CSI0_DAT7__USBOH3_USBH3_DIR 0x0dc 0x408 0x000 0x4 0x0
+#define MX53_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD 0x0dc 0x408 0x000 0x5 0x0
+#define MX53_PAD_CSI0_DAT7__EMI_EMI_DEBUG_36 0x0dc 0x408 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DAT7__TPIU_TRACE_4 0x0dc 0x408 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DAT8__IPU_CSI0_D_8 0x0e0 0x40c 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DAT8__GPIO5_26 0x0e0 0x40c 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DAT8__KPP_COL_7 0x0e0 0x40c 0x848 0x2 0x0
+#define MX53_PAD_CSI0_DAT8__ECSPI2_SCLK 0x0e0 0x40c 0x7b8 0x3 0x1
+#define MX53_PAD_CSI0_DAT8__USBOH3_USBH3_OC 0x0e0 0x40c 0x000 0x4 0x0
+#define MX53_PAD_CSI0_DAT8__I2C1_SDA 0x0e0 0x40c 0x818 0x5 0x0
+#define MX53_PAD_CSI0_DAT8__EMI_EMI_DEBUG_37 0x0e0 0x40c 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DAT8__TPIU_TRACE_5 0x0e0 0x40c 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DAT9__IPU_CSI0_D_9 0x0e4 0x410 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DAT9__GPIO5_27 0x0e4 0x410 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DAT9__KPP_ROW_7 0x0e4 0x410 0x854 0x2 0x0
+#define MX53_PAD_CSI0_DAT9__ECSPI2_MOSI 0x0e4 0x410 0x7c0 0x3 0x1
+#define MX53_PAD_CSI0_DAT9__USBOH3_USBH3_PWR 0x0e4 0x410 0x000 0x4 0x0
+#define MX53_PAD_CSI0_DAT9__I2C1_SCL 0x0e4 0x410 0x814 0x5 0x0
+#define MX53_PAD_CSI0_DAT9__EMI_EMI_DEBUG_38 0x0e4 0x410 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DAT9__TPIU_TRACE_6 0x0e4 0x410 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DAT10__IPU_CSI0_D_10 0x0e8 0x414 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DAT10__GPIO5_28 0x0e8 0x414 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DAT10__UART1_TXD_MUX 0x0e8 0x414 0x000 0x2 0x0
+#define MX53_PAD_CSI0_DAT10__ECSPI2_MISO 0x0e8 0x414 0x7bc 0x3 0x1
+#define MX53_PAD_CSI0_DAT10__AUDMUX_AUD3_RXC 0x0e8 0x414 0x000 0x4 0x0
+#define MX53_PAD_CSI0_DAT10__SDMA_DEBUG_PC_4 0x0e8 0x414 0x000 0x5 0x0
+#define MX53_PAD_CSI0_DAT10__EMI_EMI_DEBUG_39 0x0e8 0x414 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DAT10__TPIU_TRACE_7 0x0e8 0x414 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DAT11__IPU_CSI0_D_11 0x0ec 0x418 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DAT11__GPIO5_29 0x0ec 0x418 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DAT11__UART1_RXD_MUX 0x0ec 0x418 0x878 0x2 0x1
+#define MX53_PAD_CSI0_DAT11__ECSPI2_SS0 0x0ec 0x418 0x7c4 0x3 0x1
+#define MX53_PAD_CSI0_DAT11__AUDMUX_AUD3_RXFS 0x0ec 0x418 0x000 0x4 0x0
+#define MX53_PAD_CSI0_DAT11__SDMA_DEBUG_PC_5 0x0ec 0x418 0x000 0x5 0x0
+#define MX53_PAD_CSI0_DAT11__EMI_EMI_DEBUG_40 0x0ec 0x418 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DAT11__TPIU_TRACE_8 0x0ec 0x418 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12 0x0f0 0x41c 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DAT12__GPIO5_30 0x0f0 0x41c 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DAT12__UART4_TXD_MUX 0x0f0 0x41c 0x000 0x2 0x0
+#define MX53_PAD_CSI0_DAT12__USBOH3_USBH3_DATA_0 0x0f0 0x41c 0x000 0x4 0x0
+#define MX53_PAD_CSI0_DAT12__SDMA_DEBUG_PC_6 0x0f0 0x41c 0x000 0x5 0x0
+#define MX53_PAD_CSI0_DAT12__EMI_EMI_DEBUG_41 0x0f0 0x41c 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DAT12__TPIU_TRACE_9 0x0f0 0x41c 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13 0x0f4 0x420 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DAT13__GPIO5_31 0x0f4 0x420 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DAT13__UART4_RXD_MUX 0x0f4 0x420 0x890 0x2 0x3
+#define MX53_PAD_CSI0_DAT13__USBOH3_USBH3_DATA_1 0x0f4 0x420 0x000 0x4 0x0
+#define MX53_PAD_CSI0_DAT13__SDMA_DEBUG_PC_7 0x0f4 0x420 0x000 0x5 0x0
+#define MX53_PAD_CSI0_DAT13__EMI_EMI_DEBUG_42 0x0f4 0x420 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DAT13__TPIU_TRACE_10 0x0f4 0x420 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14 0x0f8 0x424 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DAT14__GPIO6_0 0x0f8 0x424 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DAT14__UART5_TXD_MUX 0x0f8 0x424 0x000 0x2 0x0
+#define MX53_PAD_CSI0_DAT14__USBOH3_USBH3_DATA_2 0x0f8 0x424 0x000 0x4 0x0
+#define MX53_PAD_CSI0_DAT14__SDMA_DEBUG_PC_8 0x0f8 0x424 0x000 0x5 0x0
+#define MX53_PAD_CSI0_DAT14__EMI_EMI_DEBUG_43 0x0f8 0x424 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DAT14__TPIU_TRACE_11 0x0f8 0x424 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15 0x0fc 0x428 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DAT15__GPIO6_1 0x0fc 0x428 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DAT15__UART5_RXD_MUX 0x0fc 0x428 0x898 0x2 0x3
+#define MX53_PAD_CSI0_DAT15__USBOH3_USBH3_DATA_3 0x0fc 0x428 0x000 0x4 0x0
+#define MX53_PAD_CSI0_DAT15__SDMA_DEBUG_PC_9 0x0fc 0x428 0x000 0x5 0x0
+#define MX53_PAD_CSI0_DAT15__EMI_EMI_DEBUG_44 0x0fc 0x428 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DAT15__TPIU_TRACE_12 0x0fc 0x428 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16 0x100 0x42c 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DAT16__GPIO6_2 0x100 0x42c 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DAT16__UART4_RTS 0x100 0x42c 0x88c 0x2 0x0
+#define MX53_PAD_CSI0_DAT16__USBOH3_USBH3_DATA_4 0x100 0x42c 0x000 0x4 0x0
+#define MX53_PAD_CSI0_DAT16__SDMA_DEBUG_PC_10 0x100 0x42c 0x000 0x5 0x0
+#define MX53_PAD_CSI0_DAT16__EMI_EMI_DEBUG_45 0x100 0x42c 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DAT16__TPIU_TRACE_13 0x100 0x42c 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17 0x104 0x430 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DAT17__GPIO6_3 0x104 0x430 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DAT17__UART4_CTS 0x104 0x430 0x000 0x2 0x0
+#define MX53_PAD_CSI0_DAT17__USBOH3_USBH3_DATA_5 0x104 0x430 0x000 0x4 0x0
+#define MX53_PAD_CSI0_DAT17__SDMA_DEBUG_PC_11 0x104 0x430 0x000 0x5 0x0
+#define MX53_PAD_CSI0_DAT17__EMI_EMI_DEBUG_46 0x104 0x430 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DAT17__TPIU_TRACE_14 0x104 0x430 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18 0x108 0x434 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DAT18__GPIO6_4 0x108 0x434 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DAT18__UART5_RTS 0x108 0x434 0x894 0x2 0x2
+#define MX53_PAD_CSI0_DAT18__USBOH3_USBH3_DATA_6 0x108 0x434 0x000 0x4 0x0
+#define MX53_PAD_CSI0_DAT18__SDMA_DEBUG_PC_12 0x108 0x434 0x000 0x5 0x0
+#define MX53_PAD_CSI0_DAT18__EMI_EMI_DEBUG_47 0x108 0x434 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DAT18__TPIU_TRACE_15 0x108 0x434 0x000 0x7 0x0
+#define MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19 0x10c 0x438 0x000 0x0 0x0
+#define MX53_PAD_CSI0_DAT19__GPIO6_5 0x10c 0x438 0x000 0x1 0x0
+#define MX53_PAD_CSI0_DAT19__UART5_CTS 0x10c 0x438 0x000 0x2 0x0
+#define MX53_PAD_CSI0_DAT19__USBOH3_USBH3_DATA_7 0x10c 0x438 0x000 0x4 0x0
+#define MX53_PAD_CSI0_DAT19__SDMA_DEBUG_PC_13 0x10c 0x438 0x000 0x5 0x0
+#define MX53_PAD_CSI0_DAT19__EMI_EMI_DEBUG_48 0x10c 0x438 0x000 0x6 0x0
+#define MX53_PAD_CSI0_DAT19__USBPHY2_BISTOK 0x10c 0x438 0x000 0x7 0x0
+#define MX53_PAD_EIM_A25__EMI_WEIM_A_25 0x110 0x458 0x000 0x0 0x0
+#define MX53_PAD_EIM_A25__GPIO5_2 0x110 0x458 0x000 0x1 0x0
+#define MX53_PAD_EIM_A25__ECSPI2_RDY 0x110 0x458 0x000 0x2 0x0
+#define MX53_PAD_EIM_A25__IPU_DI1_PIN12 0x110 0x458 0x000 0x3 0x0
+#define MX53_PAD_EIM_A25__CSPI_SS1 0x110 0x458 0x790 0x4 0x1
+#define MX53_PAD_EIM_A25__IPU_DI0_D1_CS 0x110 0x458 0x000 0x6 0x0
+#define MX53_PAD_EIM_A25__USBPHY1_BISTOK 0x110 0x458 0x000 0x7 0x0
+#define MX53_PAD_EIM_EB2__EMI_WEIM_EB_2 0x114 0x45c 0x000 0x0 0x0
+#define MX53_PAD_EIM_EB2__GPIO2_30 0x114 0x45c 0x000 0x1 0x0
+#define MX53_PAD_EIM_EB2__CCM_DI1_EXT_CLK 0x114 0x45c 0x76c 0x2 0x0
+#define MX53_PAD_EIM_EB2__IPU_SER_DISP1_CS 0x114 0x45c 0x000 0x3 0x0
+#define MX53_PAD_EIM_EB2__ECSPI1_SS0 0x114 0x45c 0x7a8 0x4 0x3
+#define MX53_PAD_EIM_EB2__I2C2_SCL 0x114 0x45c 0x81c 0x5 0x1
+#define MX53_PAD_EIM_D16__EMI_WEIM_D_16 0x118 0x460 0x000 0x0 0x0
+#define MX53_PAD_EIM_D16__GPIO3_16 0x118 0x460 0x000 0x1 0x0
+#define MX53_PAD_EIM_D16__IPU_DI0_PIN5 0x118 0x460 0x000 0x2 0x0
+#define MX53_PAD_EIM_D16__IPU_DISPB1_SER_CLK 0x118 0x460 0x000 0x3 0x0
+#define MX53_PAD_EIM_D16__ECSPI1_SCLK 0x118 0x460 0x79c 0x4 0x3
+#define MX53_PAD_EIM_D16__I2C2_SDA 0x118 0x460 0x820 0x5 0x1
+#define MX53_PAD_EIM_D17__EMI_WEIM_D_17 0x11c 0x464 0x000 0x0 0x0
+#define MX53_PAD_EIM_D17__GPIO3_17 0x11c 0x464 0x000 0x1 0x0
+#define MX53_PAD_EIM_D17__IPU_DI0_PIN6 0x11c 0x464 0x000 0x2 0x0
+#define MX53_PAD_EIM_D17__IPU_DISPB1_SER_DIN 0x11c 0x464 0x830 0x3 0x0
+#define MX53_PAD_EIM_D17__ECSPI1_MISO 0x11c 0x464 0x7a0 0x4 0x3
+#define MX53_PAD_EIM_D17__I2C3_SCL 0x11c 0x464 0x824 0x5 0x0
+#define MX53_PAD_EIM_D18__EMI_WEIM_D_18 0x120 0x468 0x000 0x0 0x0
+#define MX53_PAD_EIM_D18__GPIO3_18 0x120 0x468 0x000 0x1 0x0
+#define MX53_PAD_EIM_D18__IPU_DI0_PIN7 0x120 0x468 0x000 0x2 0x0
+#define MX53_PAD_EIM_D18__IPU_DISPB1_SER_DIO 0x120 0x468 0x830 0x3 0x1
+#define MX53_PAD_EIM_D18__ECSPI1_MOSI 0x120 0x468 0x7a4 0x4 0x3
+#define MX53_PAD_EIM_D18__I2C3_SDA 0x120 0x468 0x828 0x5 0x0
+#define MX53_PAD_EIM_D18__IPU_DI1_D0_CS 0x120 0x468 0x000 0x6 0x0
+#define MX53_PAD_EIM_D19__EMI_WEIM_D_19 0x124 0x46c 0x000 0x0 0x0
+#define MX53_PAD_EIM_D19__GPIO3_19 0x124 0x46c 0x000 0x1 0x0
+#define MX53_PAD_EIM_D19__IPU_DI0_PIN8 0x124 0x46c 0x000 0x2 0x0
+#define MX53_PAD_EIM_D19__IPU_DISPB1_SER_RS 0x124 0x46c 0x000 0x3 0x0
+#define MX53_PAD_EIM_D19__ECSPI1_SS1 0x124 0x46c 0x7ac 0x4 0x2
+#define MX53_PAD_EIM_D19__EPIT1_EPITO 0x124 0x46c 0x000 0x5 0x0
+#define MX53_PAD_EIM_D19__UART1_CTS 0x124 0x46c 0x000 0x6 0x0
+#define MX53_PAD_EIM_D19__USBOH3_USBH2_OC 0x124 0x46c 0x8a4 0x7 0x0
+#define MX53_PAD_EIM_D20__EMI_WEIM_D_20 0x128 0x470 0x000 0x0 0x0
+#define MX53_PAD_EIM_D20__GPIO3_20 0x128 0x470 0x000 0x1 0x0
+#define MX53_PAD_EIM_D20__IPU_DI0_PIN16 0x128 0x470 0x000 0x2 0x0
+#define MX53_PAD_EIM_D20__IPU_SER_DISP0_CS 0x128 0x470 0x000 0x3 0x0
+#define MX53_PAD_EIM_D20__CSPI_SS0 0x128 0x470 0x78c 0x4 0x1
+#define MX53_PAD_EIM_D20__EPIT2_EPITO 0x128 0x470 0x000 0x5 0x0
+#define MX53_PAD_EIM_D20__UART1_RTS 0x128 0x470 0x874 0x6 0x1
+#define MX53_PAD_EIM_D20__USBOH3_USBH2_PWR 0x128 0x470 0x000 0x7 0x0
+#define MX53_PAD_EIM_D21__EMI_WEIM_D_21 0x12c 0x474 0x000 0x0 0x0
+#define MX53_PAD_EIM_D21__GPIO3_21 0x12c 0x474 0x000 0x1 0x0
+#define MX53_PAD_EIM_D21__IPU_DI0_PIN17 0x12c 0x474 0x000 0x2 0x0
+#define MX53_PAD_EIM_D21__IPU_DISPB0_SER_CLK 0x12c 0x474 0x000 0x3 0x0
+#define MX53_PAD_EIM_D21__CSPI_SCLK 0x12c 0x474 0x780 0x4 0x1
+#define MX53_PAD_EIM_D21__I2C1_SCL 0x12c 0x474 0x814 0x5 0x1
+#define MX53_PAD_EIM_D21__USBOH3_USBOTG_OC 0x12c 0x474 0x89c 0x6 0x1
+#define MX53_PAD_EIM_D22__EMI_WEIM_D_22 0x130 0x478 0x000 0x0 0x0
+#define MX53_PAD_EIM_D22__GPIO3_22 0x130 0x478 0x000 0x1 0x0
+#define MX53_PAD_EIM_D22__IPU_DI0_PIN1 0x130 0x478 0x000 0x2 0x0
+#define MX53_PAD_EIM_D22__IPU_DISPB0_SER_DIN 0x130 0x478 0x82c 0x3 0x0
+#define MX53_PAD_EIM_D22__CSPI_MISO 0x130 0x478 0x784 0x4 0x1
+#define MX53_PAD_EIM_D22__USBOH3_USBOTG_PWR 0x130 0x478 0x000 0x6 0x0
+#define MX53_PAD_EIM_D23__EMI_WEIM_D_23 0x134 0x47c 0x000 0x0 0x0
+#define MX53_PAD_EIM_D23__GPIO3_23 0x134 0x47c 0x000 0x1 0x0
+#define MX53_PAD_EIM_D23__UART3_CTS 0x134 0x47c 0x000 0x2 0x0
+#define MX53_PAD_EIM_D23__UART1_DCD 0x134 0x47c 0x000 0x3 0x0
+#define MX53_PAD_EIM_D23__IPU_DI0_D0_CS 0x134 0x47c 0x000 0x4 0x0
+#define MX53_PAD_EIM_D23__IPU_DI1_PIN2 0x134 0x47c 0x000 0x5 0x0
+#define MX53_PAD_EIM_D23__IPU_CSI1_DATA_EN 0x134 0x47c 0x834 0x6 0x0
+#define MX53_PAD_EIM_D23__IPU_DI1_PIN14 0x134 0x47c 0x000 0x7 0x0
+#define MX53_PAD_EIM_EB3__EMI_WEIM_EB_3 0x138 0x480 0x000 0x0 0x0
+#define MX53_PAD_EIM_EB3__GPIO2_31 0x138 0x480 0x000 0x1 0x0
+#define MX53_PAD_EIM_EB3__UART3_RTS 0x138 0x480 0x884 0x2 0x1
+#define MX53_PAD_EIM_EB3__UART1_RI 0x138 0x480 0x000 0x3 0x0
+#define MX53_PAD_EIM_EB3__IPU_DI1_PIN3 0x138 0x480 0x000 0x5 0x0
+#define MX53_PAD_EIM_EB3__IPU_CSI1_HSYNC 0x138 0x480 0x838 0x6 0x0
+#define MX53_PAD_EIM_EB3__IPU_DI1_PIN16 0x138 0x480 0x000 0x7 0x0
+#define MX53_PAD_EIM_D24__EMI_WEIM_D_24 0x13c 0x484 0x000 0x0 0x0
+#define MX53_PAD_EIM_D24__GPIO3_24 0x13c 0x484 0x000 0x1 0x0
+#define MX53_PAD_EIM_D24__UART3_TXD_MUX 0x13c 0x484 0x000 0x2 0x0
+#define MX53_PAD_EIM_D24__ECSPI1_SS2 0x13c 0x484 0x7b0 0x3 0x1
+#define MX53_PAD_EIM_D24__CSPI_SS2 0x13c 0x484 0x794 0x4 0x1
+#define MX53_PAD_EIM_D24__AUDMUX_AUD5_RXFS 0x13c 0x484 0x754 0x5 0x1
+#define MX53_PAD_EIM_D24__ECSPI2_SS2 0x13c 0x484 0x000 0x6 0x0
+#define MX53_PAD_EIM_D24__UART1_DTR 0x13c 0x484 0x000 0x7 0x0
+#define MX53_PAD_EIM_D25__EMI_WEIM_D_25 0x140 0x488 0x000 0x0 0x0
+#define MX53_PAD_EIM_D25__GPIO3_25 0x140 0x488 0x000 0x1 0x0
+#define MX53_PAD_EIM_D25__UART3_RXD_MUX 0x140 0x488 0x888 0x2 0x1
+#define MX53_PAD_EIM_D25__ECSPI1_SS3 0x140 0x488 0x7b4 0x3 0x1
+#define MX53_PAD_EIM_D25__CSPI_SS3 0x140 0x488 0x798 0x4 0x1
+#define MX53_PAD_EIM_D25__AUDMUX_AUD5_RXC 0x140 0x488 0x750 0x5 0x1
+#define MX53_PAD_EIM_D25__ECSPI2_SS3 0x140 0x488 0x000 0x6 0x0
+#define MX53_PAD_EIM_D25__UART1_DSR 0x140 0x488 0x000 0x7 0x0
+#define MX53_PAD_EIM_D26__EMI_WEIM_D_26 0x144 0x48c 0x000 0x0 0x0
+#define MX53_PAD_EIM_D26__GPIO3_26 0x144 0x48c 0x000 0x1 0x0
+#define MX53_PAD_EIM_D26__UART2_TXD_MUX 0x144 0x48c 0x000 0x2 0x0
+#define MX53_PAD_EIM_D26__FIRI_RXD 0x144 0x48c 0x80c 0x3 0x0
+#define MX53_PAD_EIM_D26__IPU_CSI0_D_1 0x144 0x48c 0x000 0x4 0x0
+#define MX53_PAD_EIM_D26__IPU_DI1_PIN11 0x144 0x48c 0x000 0x5 0x0
+#define MX53_PAD_EIM_D26__IPU_SISG_2 0x144 0x48c 0x000 0x6 0x0
+#define MX53_PAD_EIM_D26__IPU_DISP1_DAT_22 0x144 0x48c 0x000 0x7 0x0
+#define MX53_PAD_EIM_D27__EMI_WEIM_D_27 0x148 0x490 0x000 0x0 0x0
+#define MX53_PAD_EIM_D27__GPIO3_27 0x148 0x490 0x000 0x1 0x0
+#define MX53_PAD_EIM_D27__UART2_RXD_MUX 0x148 0x490 0x880 0x2 0x1
+#define MX53_PAD_EIM_D27__FIRI_TXD 0x148 0x490 0x000 0x3 0x0
+#define MX53_PAD_EIM_D27__IPU_CSI0_D_0 0x148 0x490 0x000 0x4 0x0
+#define MX53_PAD_EIM_D27__IPU_DI1_PIN13 0x148 0x490 0x000 0x5 0x0
+#define MX53_PAD_EIM_D27__IPU_SISG_3 0x148 0x490 0x000 0x6 0x0
+#define MX53_PAD_EIM_D27__IPU_DISP1_DAT_23 0x148 0x490 0x000 0x7 0x0
+#define MX53_PAD_EIM_D28__EMI_WEIM_D_28 0x14c 0x494 0x000 0x0 0x0
+#define MX53_PAD_EIM_D28__GPIO3_28 0x14c 0x494 0x000 0x1 0x0
+#define MX53_PAD_EIM_D28__UART2_CTS 0x14c 0x494 0x000 0x2 0x0
+#define MX53_PAD_EIM_D28__IPU_DISPB0_SER_DIO 0x14c 0x494 0x82c 0x3 0x1
+#define MX53_PAD_EIM_D28__CSPI_MOSI 0x14c 0x494 0x788 0x4 0x1
+#define MX53_PAD_EIM_D28__I2C1_SDA 0x14c 0x494 0x818 0x5 0x1
+#define MX53_PAD_EIM_D28__IPU_EXT_TRIG 0x14c 0x494 0x000 0x6 0x0
+#define MX53_PAD_EIM_D28__IPU_DI0_PIN13 0x14c 0x494 0x000 0x7 0x0
+#define MX53_PAD_EIM_D29__EMI_WEIM_D_29 0x150 0x498 0x000 0x0 0x0
+#define MX53_PAD_EIM_D29__GPIO3_29 0x150 0x498 0x000 0x1 0x0
+#define MX53_PAD_EIM_D29__UART2_RTS 0x150 0x498 0x87c 0x2 0x1
+#define MX53_PAD_EIM_D29__IPU_DISPB0_SER_RS 0x150 0x498 0x000 0x3 0x0
+#define MX53_PAD_EIM_D29__CSPI_SS0 0x150 0x498 0x78c 0x4 0x2
+#define MX53_PAD_EIM_D29__IPU_DI1_PIN15 0x150 0x498 0x000 0x5 0x0
+#define MX53_PAD_EIM_D29__IPU_CSI1_VSYNC 0x150 0x498 0x83c 0x6 0x0
+#define MX53_PAD_EIM_D29__IPU_DI0_PIN14 0x150 0x498 0x000 0x7 0x0
+#define MX53_PAD_EIM_D30__EMI_WEIM_D_30 0x154 0x49c 0x000 0x0 0x0
+#define MX53_PAD_EIM_D30__GPIO3_30 0x154 0x49c 0x000 0x1 0x0
+#define MX53_PAD_EIM_D30__UART3_CTS 0x154 0x49c 0x000 0x2 0x0
+#define MX53_PAD_EIM_D30__IPU_CSI0_D_3 0x154 0x49c 0x000 0x3 0x0
+#define MX53_PAD_EIM_D30__IPU_DI0_PIN11 0x154 0x49c 0x000 0x4 0x0
+#define MX53_PAD_EIM_D30__IPU_DISP1_DAT_21 0x154 0x49c 0x000 0x5 0x0
+#define MX53_PAD_EIM_D30__USBOH3_USBH1_OC 0x154 0x49c 0x8a0 0x6 0x0
+#define MX53_PAD_EIM_D30__USBOH3_USBH2_OC 0x154 0x49c 0x8a4 0x7 0x1
+#define MX53_PAD_EIM_D31__EMI_WEIM_D_31 0x158 0x4a0 0x000 0x0 0x0
+#define MX53_PAD_EIM_D31__GPIO3_31 0x158 0x4a0 0x000 0x1 0x0
+#define MX53_PAD_EIM_D31__UART3_RTS 0x158 0x4a0 0x884 0x2 0x3
+#define MX53_PAD_EIM_D31__IPU_CSI0_D_2 0x158 0x4a0 0x000 0x3 0x0
+#define MX53_PAD_EIM_D31__IPU_DI0_PIN12 0x158 0x4a0 0x000 0x4 0x0
+#define MX53_PAD_EIM_D31__IPU_DISP1_DAT_20 0x158 0x4a0 0x000 0x5 0x0
+#define MX53_PAD_EIM_D31__USBOH3_USBH1_PWR 0x158 0x4a0 0x000 0x6 0x0
+#define MX53_PAD_EIM_D31__USBOH3_USBH2_PWR 0x158 0x4a0 0x000 0x7 0x0
+#define MX53_PAD_EIM_A24__EMI_WEIM_A_24 0x15c 0x4a8 0x000 0x0 0x0
+#define MX53_PAD_EIM_A24__GPIO5_4 0x15c 0x4a8 0x000 0x1 0x0
+#define MX53_PAD_EIM_A24__IPU_DISP1_DAT_19 0x15c 0x4a8 0x000 0x2 0x0
+#define MX53_PAD_EIM_A24__IPU_CSI1_D_19 0x15c 0x4a8 0x000 0x3 0x0
+#define MX53_PAD_EIM_A24__IPU_SISG_2 0x15c 0x4a8 0x000 0x6 0x0
+#define MX53_PAD_EIM_A24__USBPHY2_BVALID 0x15c 0x4a8 0x000 0x7 0x0
+#define MX53_PAD_EIM_A23__EMI_WEIM_A_23 0x160 0x4ac 0x000 0x0 0x0
+#define MX53_PAD_EIM_A23__GPIO6_6 0x160 0x4ac 0x000 0x1 0x0
+#define MX53_PAD_EIM_A23__IPU_DISP1_DAT_18 0x160 0x4ac 0x000 0x2 0x0
+#define MX53_PAD_EIM_A23__IPU_CSI1_D_18 0x160 0x4ac 0x000 0x3 0x0
+#define MX53_PAD_EIM_A23__IPU_SISG_3 0x160 0x4ac 0x000 0x6 0x0
+#define MX53_PAD_EIM_A23__USBPHY2_ENDSESSION 0x160 0x4ac 0x000 0x7 0x0
+#define MX53_PAD_EIM_A22__EMI_WEIM_A_22 0x164 0x4b0 0x000 0x0 0x0
+#define MX53_PAD_EIM_A22__GPIO2_16 0x164 0x4b0 0x000 0x1 0x0
+#define MX53_PAD_EIM_A22__IPU_DISP1_DAT_17 0x164 0x4b0 0x000 0x2 0x0
+#define MX53_PAD_EIM_A22__IPU_CSI1_D_17 0x164 0x4b0 0x000 0x3 0x0
+#define MX53_PAD_EIM_A22__SRC_BT_CFG1_7 0x164 0x4b0 0x000 0x7 0x0
+#define MX53_PAD_EIM_A21__EMI_WEIM_A_21 0x168 0x4b4 0x000 0x0 0x0
+#define MX53_PAD_EIM_A21__GPIO2_17 0x168 0x4b4 0x000 0x1 0x0
+#define MX53_PAD_EIM_A21__IPU_DISP1_DAT_16 0x168 0x4b4 0x000 0x2 0x0
+#define MX53_PAD_EIM_A21__IPU_CSI1_D_16 0x168 0x4b4 0x000 0x3 0x0
+#define MX53_PAD_EIM_A21__SRC_BT_CFG1_6 0x168 0x4b4 0x000 0x7 0x0
+#define MX53_PAD_EIM_A20__EMI_WEIM_A_20 0x16c 0x4b8 0x000 0x0 0x0
+#define MX53_PAD_EIM_A20__GPIO2_18 0x16c 0x4b8 0x000 0x1 0x0
+#define MX53_PAD_EIM_A20__IPU_DISP1_DAT_15 0x16c 0x4b8 0x000 0x2 0x0
+#define MX53_PAD_EIM_A20__IPU_CSI1_D_15 0x16c 0x4b8 0x000 0x3 0x0
+#define MX53_PAD_EIM_A20__SRC_BT_CFG1_5 0x16c 0x4b8 0x000 0x7 0x0
+#define MX53_PAD_EIM_A19__EMI_WEIM_A_19 0x170 0x4bc 0x000 0x0 0x0
+#define MX53_PAD_EIM_A19__GPIO2_19 0x170 0x4bc 0x000 0x1 0x0
+#define MX53_PAD_EIM_A19__IPU_DISP1_DAT_14 0x170 0x4bc 0x000 0x2 0x0
+#define MX53_PAD_EIM_A19__IPU_CSI1_D_14 0x170 0x4bc 0x000 0x3 0x0
+#define MX53_PAD_EIM_A19__SRC_BT_CFG1_4 0x170 0x4bc 0x000 0x7 0x0
+#define MX53_PAD_EIM_A18__EMI_WEIM_A_18 0x174 0x4c0 0x000 0x0 0x0
+#define MX53_PAD_EIM_A18__GPIO2_20 0x174 0x4c0 0x000 0x1 0x0
+#define MX53_PAD_EIM_A18__IPU_DISP1_DAT_13 0x174 0x4c0 0x000 0x2 0x0
+#define MX53_PAD_EIM_A18__IPU_CSI1_D_13 0x174 0x4c0 0x000 0x3 0x0
+#define MX53_PAD_EIM_A18__SRC_BT_CFG1_3 0x174 0x4c0 0x000 0x7 0x0
+#define MX53_PAD_EIM_A17__EMI_WEIM_A_17 0x178 0x4c4 0x000 0x0 0x0
+#define MX53_PAD_EIM_A17__GPIO2_21 0x178 0x4c4 0x000 0x1 0x0
+#define MX53_PAD_EIM_A17__IPU_DISP1_DAT_12 0x178 0x4c4 0x000 0x2 0x0
+#define MX53_PAD_EIM_A17__IPU_CSI1_D_12 0x178 0x4c4 0x000 0x3 0x0
+#define MX53_PAD_EIM_A17__SRC_BT_CFG1_2 0x178 0x4c4 0x000 0x7 0x0
+#define MX53_PAD_EIM_A16__EMI_WEIM_A_16 0x17c 0x4c8 0x000 0x0 0x0
+#define MX53_PAD_EIM_A16__GPIO2_22 0x17c 0x4c8 0x000 0x1 0x0
+#define MX53_PAD_EIM_A16__IPU_DI1_DISP_CLK 0x17c 0x4c8 0x000 0x2 0x0
+#define MX53_PAD_EIM_A16__IPU_CSI1_PIXCLK 0x17c 0x4c8 0x000 0x3 0x0
+#define MX53_PAD_EIM_A16__SRC_BT_CFG1_1 0x17c 0x4c8 0x000 0x7 0x0
+#define MX53_PAD_EIM_CS0__EMI_WEIM_CS_0 0x180 0x4cc 0x000 0x0 0x0
+#define MX53_PAD_EIM_CS0__GPIO2_23 0x180 0x4cc 0x000 0x1 0x0
+#define MX53_PAD_EIM_CS0__ECSPI2_SCLK 0x180 0x4cc 0x7b8 0x2 0x2
+#define MX53_PAD_EIM_CS0__IPU_DI1_PIN5 0x180 0x4cc 0x000 0x3 0x0
+#define MX53_PAD_EIM_CS1__EMI_WEIM_CS_1 0x184 0x4d0 0x000 0x0 0x0
+#define MX53_PAD_EIM_CS1__GPIO2_24 0x184 0x4d0 0x000 0x1 0x0
+#define MX53_PAD_EIM_CS1__ECSPI2_MOSI 0x184 0x4d0 0x7c0 0x2 0x2
+#define MX53_PAD_EIM_CS1__IPU_DI1_PIN6 0x184 0x4d0 0x000 0x3 0x0
+#define MX53_PAD_EIM_OE__EMI_WEIM_OE 0x188 0x4d4 0x000 0x0 0x0
+#define MX53_PAD_EIM_OE__GPIO2_25 0x188 0x4d4 0x000 0x1 0x0
+#define MX53_PAD_EIM_OE__ECSPI2_MISO 0x188 0x4d4 0x7bc 0x2 0x2
+#define MX53_PAD_EIM_OE__IPU_DI1_PIN7 0x188 0x4d4 0x000 0x3 0x0
+#define MX53_PAD_EIM_OE__USBPHY2_IDDIG 0x188 0x4d4 0x000 0x7 0x0
+#define MX53_PAD_EIM_RW__EMI_WEIM_RW 0x18c 0x4d8 0x000 0x0 0x0
+#define MX53_PAD_EIM_RW__GPIO2_26 0x18c 0x4d8 0x000 0x1 0x0
+#define MX53_PAD_EIM_RW__ECSPI2_SS0 0x18c 0x4d8 0x7c4 0x2 0x2
+#define MX53_PAD_EIM_RW__IPU_DI1_PIN8 0x18c 0x4d8 0x000 0x3 0x0
+#define MX53_PAD_EIM_RW__USBPHY2_HOSTDISCONNECT 0x18c 0x4d8 0x000 0x7 0x0
+#define MX53_PAD_EIM_LBA__EMI_WEIM_LBA 0x190 0x4dc 0x000 0x0 0x0
+#define MX53_PAD_EIM_LBA__GPIO2_27 0x190 0x4dc 0x000 0x1 0x0
+#define MX53_PAD_EIM_LBA__ECSPI2_SS1 0x190 0x4dc 0x7c8 0x2 0x1
+#define MX53_PAD_EIM_LBA__IPU_DI1_PIN17 0x190 0x4dc 0x000 0x3 0x0
+#define MX53_PAD_EIM_LBA__SRC_BT_CFG1_0 0x190 0x4dc 0x000 0x7 0x0
+#define MX53_PAD_EIM_EB0__EMI_WEIM_EB_0 0x194 0x4e4 0x000 0x0 0x0
+#define MX53_PAD_EIM_EB0__GPIO2_28 0x194 0x4e4 0x000 0x1 0x0
+#define MX53_PAD_EIM_EB0__IPU_DISP1_DAT_11 0x194 0x4e4 0x000 0x3 0x0
+#define MX53_PAD_EIM_EB0__IPU_CSI1_D_11 0x194 0x4e4 0x000 0x4 0x0
+#define MX53_PAD_EIM_EB0__GPC_PMIC_RDY 0x194 0x4e4 0x810 0x5 0x0
+#define MX53_PAD_EIM_EB0__SRC_BT_CFG2_7 0x194 0x4e4 0x000 0x7 0x0
+#define MX53_PAD_EIM_EB1__EMI_WEIM_EB_1 0x198 0x4e8 0x000 0x0 0x0
+#define MX53_PAD_EIM_EB1__GPIO2_29 0x198 0x4e8 0x000 0x1 0x0
+#define MX53_PAD_EIM_EB1__IPU_DISP1_DAT_10 0x198 0x4e8 0x000 0x3 0x0
+#define MX53_PAD_EIM_EB1__IPU_CSI1_D_10 0x198 0x4e8 0x000 0x4 0x0
+#define MX53_PAD_EIM_EB1__SRC_BT_CFG2_6 0x198 0x4e8 0x000 0x7 0x0
+#define MX53_PAD_EIM_DA0__EMI_NAND_WEIM_DA_0 0x19c 0x4ec 0x000 0x0 0x0
+#define MX53_PAD_EIM_DA0__GPIO3_0 0x19c 0x4ec 0x000 0x1 0x0
+#define MX53_PAD_EIM_DA0__IPU_DISP1_DAT_9 0x19c 0x4ec 0x000 0x3 0x0
+#define MX53_PAD_EIM_DA0__IPU_CSI1_D_9 0x19c 0x4ec 0x000 0x4 0x0
+#define MX53_PAD_EIM_DA0__SRC_BT_CFG2_5 0x19c 0x4ec 0x000 0x7 0x0
+#define MX53_PAD_EIM_DA1__EMI_NAND_WEIM_DA_1 0x1a0 0x4f0 0x000 0x0 0x0
+#define MX53_PAD_EIM_DA1__GPIO3_1 0x1a0 0x4f0 0x000 0x1 0x0
+#define MX53_PAD_EIM_DA1__IPU_DISP1_DAT_8 0x1a0 0x4f0 0x000 0x3 0x0
+#define MX53_PAD_EIM_DA1__IPU_CSI1_D_8 0x1a0 0x4f0 0x000 0x4 0x0
+#define MX53_PAD_EIM_DA1__SRC_BT_CFG2_4 0x1a0 0x4f0 0x000 0x7 0x0
+#define MX53_PAD_EIM_DA2__EMI_NAND_WEIM_DA_2 0x1a4 0x4f4 0x000 0x0 0x0
+#define MX53_PAD_EIM_DA2__GPIO3_2 0x1a4 0x4f4 0x000 0x1 0x0
+#define MX53_PAD_EIM_DA2__IPU_DISP1_DAT_7 0x1a4 0x4f4 0x000 0x3 0x0
+#define MX53_PAD_EIM_DA2__IPU_CSI1_D_7 0x1a4 0x4f4 0x000 0x4 0x0
+#define MX53_PAD_EIM_DA2__SRC_BT_CFG2_3 0x1a4 0x4f4 0x000 0x7 0x0
+#define MX53_PAD_EIM_DA3__EMI_NAND_WEIM_DA_3 0x1a8 0x4f8 0x000 0x0 0x0
+#define MX53_PAD_EIM_DA3__GPIO3_3 0x1a8 0x4f8 0x000 0x1 0x0
+#define MX53_PAD_EIM_DA3__IPU_DISP1_DAT_6 0x1a8 0x4f8 0x000 0x3 0x0
+#define MX53_PAD_EIM_DA3__IPU_CSI1_D_6 0x1a8 0x4f8 0x000 0x4 0x0
+#define MX53_PAD_EIM_DA3__SRC_BT_CFG2_2 0x1a8 0x4f8 0x000 0x7 0x0
+#define MX53_PAD_EIM_DA4__EMI_NAND_WEIM_DA_4 0x1ac 0x4fc 0x000 0x0 0x0
+#define MX53_PAD_EIM_DA4__GPIO3_4 0x1ac 0x4fc 0x000 0x1 0x0
+#define MX53_PAD_EIM_DA4__IPU_DISP1_DAT_5 0x1ac 0x4fc 0x000 0x3 0x0
+#define MX53_PAD_EIM_DA4__IPU_CSI1_D_5 0x1ac 0x4fc 0x000 0x4 0x0
+#define MX53_PAD_EIM_DA4__SRC_BT_CFG3_7 0x1ac 0x4fc 0x000 0x7 0x0
+#define MX53_PAD_EIM_DA5__EMI_NAND_WEIM_DA_5 0x1b0 0x500 0x000 0x0 0x0
+#define MX53_PAD_EIM_DA5__GPIO3_5 0x1b0 0x500 0x000 0x1 0x0
+#define MX53_PAD_EIM_DA5__IPU_DISP1_DAT_4 0x1b0 0x500 0x000 0x3 0x0
+#define MX53_PAD_EIM_DA5__IPU_CSI1_D_4 0x1b0 0x500 0x000 0x4 0x0
+#define MX53_PAD_EIM_DA5__SRC_BT_CFG3_6 0x1b0 0x500 0x000 0x7 0x0
+#define MX53_PAD_EIM_DA6__EMI_NAND_WEIM_DA_6 0x1b4 0x504 0x000 0x0 0x0
+#define MX53_PAD_EIM_DA6__GPIO3_6 0x1b4 0x504 0x000 0x1 0x0
+#define MX53_PAD_EIM_DA6__IPU_DISP1_DAT_3 0x1b4 0x504 0x000 0x3 0x0
+#define MX53_PAD_EIM_DA6__IPU_CSI1_D_3 0x1b4 0x504 0x000 0x4 0x0
+#define MX53_PAD_EIM_DA6__SRC_BT_CFG3_5 0x1b4 0x504 0x000 0x7 0x0
+#define MX53_PAD_EIM_DA7__EMI_NAND_WEIM_DA_7 0x1b8 0x508 0x000 0x0 0x0
+#define MX53_PAD_EIM_DA7__GPIO3_7 0x1b8 0x508 0x000 0x1 0x0
+#define MX53_PAD_EIM_DA7__IPU_DISP1_DAT_2 0x1b8 0x508 0x000 0x3 0x0
+#define MX53_PAD_EIM_DA7__IPU_CSI1_D_2 0x1b8 0x508 0x000 0x4 0x0
+#define MX53_PAD_EIM_DA7__SRC_BT_CFG3_4 0x1b8 0x508 0x000 0x7 0x0
+#define MX53_PAD_EIM_DA8__EMI_NAND_WEIM_DA_8 0x1bc 0x50c 0x000 0x0 0x0
+#define MX53_PAD_EIM_DA8__GPIO3_8 0x1bc 0x50c 0x000 0x1 0x0
+#define MX53_PAD_EIM_DA8__IPU_DISP1_DAT_1 0x1bc 0x50c 0x000 0x3 0x0
+#define MX53_PAD_EIM_DA8__IPU_CSI1_D_1 0x1bc 0x50c 0x000 0x4 0x0
+#define MX53_PAD_EIM_DA8__SRC_BT_CFG3_3 0x1bc 0x50c 0x000 0x7 0x0
+#define MX53_PAD_EIM_DA9__EMI_NAND_WEIM_DA_9 0x1c0 0x510 0x000 0x0 0x0
+#define MX53_PAD_EIM_DA9__GPIO3_9 0x1c0 0x510 0x000 0x1 0x0
+#define MX53_PAD_EIM_DA9__IPU_DISP1_DAT_0 0x1c0 0x510 0x000 0x3 0x0
+#define MX53_PAD_EIM_DA9__IPU_CSI1_D_0 0x1c0 0x510 0x000 0x4 0x0
+#define MX53_PAD_EIM_DA9__SRC_BT_CFG3_2 0x1c0 0x510 0x000 0x7 0x0
+#define MX53_PAD_EIM_DA10__EMI_NAND_WEIM_DA_10 0x1c4 0x514 0x000 0x0 0x0
+#define MX53_PAD_EIM_DA10__GPIO3_10 0x1c4 0x514 0x000 0x1 0x0
+#define MX53_PAD_EIM_DA10__IPU_DI1_PIN15 0x1c4 0x514 0x000 0x3 0x0
+#define MX53_PAD_EIM_DA10__IPU_CSI1_DATA_EN 0x1c4 0x514 0x834 0x4 0x1
+#define MX53_PAD_EIM_DA10__SRC_BT_CFG3_1 0x1c4 0x514 0x000 0x7 0x0
+#define MX53_PAD_EIM_DA11__EMI_NAND_WEIM_DA_11 0x1c8 0x518 0x000 0x0 0x0
+#define MX53_PAD_EIM_DA11__GPIO3_11 0x1c8 0x518 0x000 0x1 0x0
+#define MX53_PAD_EIM_DA11__IPU_DI1_PIN2 0x1c8 0x518 0x000 0x3 0x0
+#define MX53_PAD_EIM_DA11__IPU_CSI1_HSYNC 0x1c8 0x518 0x838 0x4 0x1
+#define MX53_PAD_EIM_DA12__EMI_NAND_WEIM_DA_12 0x1cc 0x51c 0x000 0x0 0x0
+#define MX53_PAD_EIM_DA12__GPIO3_12 0x1cc 0x51c 0x000 0x1 0x0
+#define MX53_PAD_EIM_DA12__IPU_DI1_PIN3 0x1cc 0x51c 0x000 0x3 0x0
+#define MX53_PAD_EIM_DA12__IPU_CSI1_VSYNC 0x1cc 0x51c 0x83c 0x4 0x1
+#define MX53_PAD_EIM_DA13__EMI_NAND_WEIM_DA_13 0x1d0 0x520 0x000 0x0 0x0
+#define MX53_PAD_EIM_DA13__GPIO3_13 0x1d0 0x520 0x000 0x1 0x0
+#define MX53_PAD_EIM_DA13__IPU_DI1_D0_CS 0x1d0 0x520 0x000 0x3 0x0
+#define MX53_PAD_EIM_DA13__CCM_DI1_EXT_CLK 0x1d0 0x520 0x76c 0x4 0x1
+#define MX53_PAD_EIM_DA14__EMI_NAND_WEIM_DA_14 0x1d4 0x524 0x000 0x0 0x0
+#define MX53_PAD_EIM_DA14__GPIO3_14 0x1d4 0x524 0x000 0x1 0x0
+#define MX53_PAD_EIM_DA14__IPU_DI1_D1_CS 0x1d4 0x524 0x000 0x3 0x0
+#define MX53_PAD_EIM_DA14__CCM_DI0_EXT_CLK 0x1d4 0x524 0x000 0x4 0x0
+#define MX53_PAD_EIM_DA15__EMI_NAND_WEIM_DA_15 0x1d8 0x528 0x000 0x0 0x0
+#define MX53_PAD_EIM_DA15__GPIO3_15 0x1d8 0x528 0x000 0x1 0x0
+#define MX53_PAD_EIM_DA15__IPU_DI1_PIN1 0x1d8 0x528 0x000 0x3 0x0
+#define MX53_PAD_EIM_DA15__IPU_DI1_PIN4 0x1d8 0x528 0x000 0x4 0x0
+#define MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B 0x1dc 0x52c 0x000 0x0 0x0
+#define MX53_PAD_NANDF_WE_B__GPIO6_12 0x1dc 0x52c 0x000 0x1 0x0
+#define MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B 0x1e0 0x530 0x000 0x0 0x0
+#define MX53_PAD_NANDF_RE_B__GPIO6_13 0x1e0 0x530 0x000 0x1 0x0
+#define MX53_PAD_EIM_WAIT__EMI_WEIM_WAIT 0x1e4 0x534 0x000 0x0 0x0
+#define MX53_PAD_EIM_WAIT__GPIO5_0 0x1e4 0x534 0x000 0x1 0x0
+#define MX53_PAD_EIM_WAIT__EMI_WEIM_DTACK_B 0x1e4 0x534 0x000 0x2 0x0
+#define MX53_PAD_LVDS1_TX3_P__GPIO6_22 0x1ec 0x000 0x000 0x0 0x0
+#define MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 0x1ec 0x000 0x000 0x1 0x0
+#define MX53_PAD_LVDS1_TX2_P__GPIO6_24 0x1f0 0x000 0x000 0x0 0x0
+#define MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 0x1f0 0x000 0x000 0x1 0x0
+#define MX53_PAD_LVDS1_CLK_P__GPIO6_26 0x1f4 0x000 0x000 0x0 0x0
+#define MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK 0x1f4 0x000 0x000 0x1 0x0
+#define MX53_PAD_LVDS1_TX1_P__GPIO6_28 0x1f8 0x000 0x000 0x0 0x0
+#define MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 0x1f8 0x000 0x000 0x1 0x0
+#define MX53_PAD_LVDS1_TX0_P__GPIO6_30 0x1fc 0x000 0x000 0x0 0x0
+#define MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 0x1fc 0x000 0x000 0x1 0x0
+#define MX53_PAD_LVDS0_TX3_P__GPIO7_22 0x200 0x000 0x000 0x0 0x0
+#define MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 0x200 0x000 0x000 0x1 0x0
+#define MX53_PAD_LVDS0_CLK_P__GPIO7_24 0x204 0x000 0x000 0x0 0x0
+#define MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK 0x204 0x000 0x000 0x1 0x0
+#define MX53_PAD_LVDS0_TX2_P__GPIO7_26 0x208 0x000 0x000 0x0 0x0
+#define MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 0x208 0x000 0x000 0x1 0x0
+#define MX53_PAD_LVDS0_TX1_P__GPIO7_28 0x20c 0x000 0x000 0x0 0x0
+#define MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 0x20c 0x000 0x000 0x1 0x0
+#define MX53_PAD_LVDS0_TX0_P__GPIO7_30 0x210 0x000 0x000 0x0 0x0
+#define MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 0x210 0x000 0x000 0x1 0x0
+#define MX53_PAD_GPIO_10__GPIO4_0 0x214 0x540 0x000 0x0 0x0
+#define MX53_PAD_GPIO_10__OSC32k_32K_OUT 0x214 0x540 0x000 0x1 0x0
+#define MX53_PAD_GPIO_11__GPIO4_1 0x218 0x544 0x000 0x0 0x0
+#define MX53_PAD_GPIO_12__GPIO4_2 0x21c 0x548 0x000 0x0 0x0
+#define MX53_PAD_GPIO_13__GPIO4_3 0x220 0x54c 0x000 0x0 0x0
+#define MX53_PAD_GPIO_14__GPIO4_4 0x224 0x550 0x000 0x0 0x0
+#define MX53_PAD_NANDF_CLE__EMI_NANDF_CLE 0x228 0x5a0 0x000 0x0 0x0
+#define MX53_PAD_NANDF_CLE__GPIO6_7 0x228 0x5a0 0x000 0x1 0x0
+#define MX53_PAD_NANDF_CLE__USBPHY1_VSTATUS_0 0x228 0x5a0 0x000 0x7 0x0
+#define MX53_PAD_NANDF_ALE__EMI_NANDF_ALE 0x22c 0x5a4 0x000 0x0 0x0
+#define MX53_PAD_NANDF_ALE__GPIO6_8 0x22c 0x5a4 0x000 0x1 0x0
+#define MX53_PAD_NANDF_ALE__USBPHY1_VSTATUS_1 0x22c 0x5a4 0x000 0x7 0x0
+#define MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B 0x230 0x5a8 0x000 0x0 0x0
+#define MX53_PAD_NANDF_WP_B__GPIO6_9 0x230 0x5a8 0x000 0x1 0x0
+#define MX53_PAD_NANDF_WP_B__USBPHY1_VSTATUS_2 0x230 0x5a8 0x000 0x7 0x0
+#define MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0 0x234 0x5ac 0x000 0x0 0x0
+#define MX53_PAD_NANDF_RB0__GPIO6_10 0x234 0x5ac 0x000 0x1 0x0
+#define MX53_PAD_NANDF_RB0__USBPHY1_VSTATUS_3 0x234 0x5ac 0x000 0x7 0x0
+#define MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0 0x238 0x5b0 0x000 0x0 0x0
+#define MX53_PAD_NANDF_CS0__GPIO6_11 0x238 0x5b0 0x000 0x1 0x0
+#define MX53_PAD_NANDF_CS0__USBPHY1_VSTATUS_4 0x238 0x5b0 0x000 0x7 0x0
+#define MX53_PAD_NANDF_CS1__EMI_NANDF_CS_1 0x23c 0x5b4 0x000 0x0 0x0
+#define MX53_PAD_NANDF_CS1__GPIO6_14 0x23c 0x5b4 0x000 0x1 0x0
+#define MX53_PAD_NANDF_CS1__MLB_MLBCLK 0x23c 0x5b4 0x858 0x6 0x0
+#define MX53_PAD_NANDF_CS1__USBPHY1_VSTATUS_5 0x23c 0x5b4 0x000 0x7 0x0
+#define MX53_PAD_NANDF_CS2__EMI_NANDF_CS_2 0x240 0x5b8 0x000 0x0 0x0
+#define MX53_PAD_NANDF_CS2__GPIO6_15 0x240 0x5b8 0x000 0x1 0x0
+#define MX53_PAD_NANDF_CS2__IPU_SISG_0 0x240 0x5b8 0x000 0x2 0x0
+#define MX53_PAD_NANDF_CS2__ESAI1_TX0 0x240 0x5b8 0x7e4 0x3 0x0
+#define MX53_PAD_NANDF_CS2__EMI_WEIM_CRE 0x240 0x5b8 0x000 0x4 0x0
+#define MX53_PAD_NANDF_CS2__CCM_CSI0_MCLK 0x240 0x5b8 0x000 0x5 0x0
+#define MX53_PAD_NANDF_CS2__MLB_MLBSIG 0x240 0x5b8 0x860 0x6 0x0
+#define MX53_PAD_NANDF_CS2__USBPHY1_VSTATUS_6 0x240 0x5b8 0x000 0x7 0x0
+#define MX53_PAD_NANDF_CS3__EMI_NANDF_CS_3 0x244 0x5bc 0x000 0x0 0x0
+#define MX53_PAD_NANDF_CS3__GPIO6_16 0x244 0x5bc 0x000 0x1 0x0
+#define MX53_PAD_NANDF_CS3__IPU_SISG_1 0x244 0x5bc 0x000 0x2 0x0
+#define MX53_PAD_NANDF_CS3__ESAI1_TX1 0x244 0x5bc 0x7e8 0x3 0x0
+#define MX53_PAD_NANDF_CS3__EMI_WEIM_A_26 0x244 0x5bc 0x000 0x4 0x0
+#define MX53_PAD_NANDF_CS3__MLB_MLBDAT 0x244 0x5bc 0x85c 0x6 0x0
+#define MX53_PAD_NANDF_CS3__USBPHY1_VSTATUS_7 0x244 0x5bc 0x000 0x7 0x0
+#define MX53_PAD_FEC_MDIO__FEC_MDIO 0x248 0x5c4 0x804 0x0 0x1
+#define MX53_PAD_FEC_MDIO__GPIO1_22 0x248 0x5c4 0x000 0x1 0x0
+#define MX53_PAD_FEC_MDIO__ESAI1_SCKR 0x248 0x5c4 0x7dc 0x2 0x0
+#define MX53_PAD_FEC_MDIO__FEC_COL 0x248 0x5c4 0x800 0x3 0x1
+#define MX53_PAD_FEC_MDIO__RTC_CE_RTC_PS2 0x248 0x5c4 0x000 0x4 0x0
+#define MX53_PAD_FEC_MDIO__SDMA_DEBUG_BUS_DEVICE_3 0x248 0x5c4 0x000 0x5 0x0
+#define MX53_PAD_FEC_MDIO__EMI_EMI_DEBUG_49 0x248 0x5c4 0x000 0x6 0x0
+#define MX53_PAD_FEC_REF_CLK__FEC_TX_CLK 0x24c 0x5c8 0x000 0x0 0x0
+#define MX53_PAD_FEC_REF_CLK__GPIO1_23 0x24c 0x5c8 0x000 0x1 0x0
+#define MX53_PAD_FEC_REF_CLK__ESAI1_FSR 0x24c 0x5c8 0x7cc 0x2 0x0
+#define MX53_PAD_FEC_REF_CLK__SDMA_DEBUG_BUS_DEVICE_4 0x24c 0x5c8 0x000 0x5 0x0
+#define MX53_PAD_FEC_REF_CLK__EMI_EMI_DEBUG_50 0x24c 0x5c8 0x000 0x6 0x0
+#define MX53_PAD_FEC_RX_ER__FEC_RX_ER 0x250 0x5cc 0x000 0x0 0x0
+#define MX53_PAD_FEC_RX_ER__GPIO1_24 0x250 0x5cc 0x000 0x1 0x0
+#define MX53_PAD_FEC_RX_ER__ESAI1_HCKR 0x250 0x5cc 0x7d4 0x2 0x0
+#define MX53_PAD_FEC_RX_ER__FEC_RX_CLK 0x250 0x5cc 0x808 0x3 0x1
+#define MX53_PAD_FEC_RX_ER__RTC_CE_RTC_PS3 0x250 0x5cc 0x000 0x4 0x0
+#define MX53_PAD_FEC_CRS_DV__FEC_RX_DV 0x254 0x5d0 0x000 0x0 0x0
+#define MX53_PAD_FEC_CRS_DV__GPIO1_25 0x254 0x5d0 0x000 0x1 0x0
+#define MX53_PAD_FEC_CRS_DV__ESAI1_SCKT 0x254 0x5d0 0x7e0 0x2 0x0
+#define MX53_PAD_FEC_RXD1__FEC_RDATA_1 0x258 0x5d4 0x000 0x0 0x0
+#define MX53_PAD_FEC_RXD1__GPIO1_26 0x258 0x5d4 0x000 0x1 0x0
+#define MX53_PAD_FEC_RXD1__ESAI1_FST 0x258 0x5d4 0x7d0 0x2 0x0
+#define MX53_PAD_FEC_RXD1__MLB_MLBSIG 0x258 0x5d4 0x860 0x3 0x1
+#define MX53_PAD_FEC_RXD1__RTC_CE_RTC_PS1 0x258 0x5d4 0x000 0x4 0x0
+#define MX53_PAD_FEC_RXD0__FEC_RDATA_0 0x25c 0x5d8 0x000 0x0 0x0
+#define MX53_PAD_FEC_RXD0__GPIO1_27 0x25c 0x5d8 0x000 0x1 0x0
+#define MX53_PAD_FEC_RXD0__ESAI1_HCKT 0x25c 0x5d8 0x7d8 0x2 0x0
+#define MX53_PAD_FEC_RXD0__OSC32k_32K_OUT 0x25c 0x5d8 0x000 0x3 0x0
+#define MX53_PAD_FEC_TX_EN__FEC_TX_EN 0x260 0x5dc 0x000 0x0 0x0
+#define MX53_PAD_FEC_TX_EN__GPIO1_28 0x260 0x5dc 0x000 0x1 0x0
+#define MX53_PAD_FEC_TX_EN__ESAI1_TX3_RX2 0x260 0x5dc 0x7f0 0x2 0x0
+#define MX53_PAD_FEC_TXD1__FEC_TDATA_1 0x264 0x5e0 0x000 0x0 0x0
+#define MX53_PAD_FEC_TXD1__GPIO1_29 0x264 0x5e0 0x000 0x1 0x0
+#define MX53_PAD_FEC_TXD1__ESAI1_TX2_RX3 0x264 0x5e0 0x7ec 0x2 0x0
+#define MX53_PAD_FEC_TXD1__MLB_MLBCLK 0x264 0x5e0 0x858 0x3 0x1
+#define MX53_PAD_FEC_TXD1__RTC_CE_RTC_PRSC_CLK 0x264 0x5e0 0x000 0x4 0x0
+#define MX53_PAD_FEC_TXD0__FEC_TDATA_0 0x268 0x5e4 0x000 0x0 0x0
+#define MX53_PAD_FEC_TXD0__GPIO1_30 0x268 0x5e4 0x000 0x1 0x0
+#define MX53_PAD_FEC_TXD0__ESAI1_TX4_RX1 0x268 0x5e4 0x7f4 0x2 0x0
+#define MX53_PAD_FEC_TXD0__USBPHY2_DATAOUT_0 0x268 0x5e4 0x000 0x7 0x0
+#define MX53_PAD_FEC_MDC__FEC_MDC 0x26c 0x5e8 0x000 0x0 0x0
+#define MX53_PAD_FEC_MDC__GPIO1_31 0x26c 0x5e8 0x000 0x1 0x0
+#define MX53_PAD_FEC_MDC__ESAI1_TX5_RX0 0x26c 0x5e8 0x7f8 0x2 0x0
+#define MX53_PAD_FEC_MDC__MLB_MLBDAT 0x26c 0x5e8 0x85c 0x3 0x1
+#define MX53_PAD_FEC_MDC__RTC_CE_RTC_ALARM1_TRIG 0x26c 0x5e8 0x000 0x4 0x0
+#define MX53_PAD_FEC_MDC__USBPHY2_DATAOUT_1 0x26c 0x5e8 0x000 0x7 0x0
+#define MX53_PAD_PATA_DIOW__PATA_DIOW 0x270 0x5f0 0x000 0x0 0x0
+#define MX53_PAD_PATA_DIOW__GPIO6_17 0x270 0x5f0 0x000 0x1 0x0
+#define MX53_PAD_PATA_DIOW__UART1_TXD_MUX 0x270 0x5f0 0x000 0x3 0x0
+#define MX53_PAD_PATA_DIOW__USBPHY2_DATAOUT_2 0x270 0x5f0 0x000 0x7 0x0
+#define MX53_PAD_PATA_DMACK__PATA_DMACK 0x274 0x5f4 0x000 0x0 0x0
+#define MX53_PAD_PATA_DMACK__GPIO6_18 0x274 0x5f4 0x000 0x1 0x0
+#define MX53_PAD_PATA_DMACK__UART1_RXD_MUX 0x274 0x5f4 0x878 0x3 0x3
+#define MX53_PAD_PATA_DMACK__USBPHY2_DATAOUT_3 0x274 0x5f4 0x000 0x7 0x0
+#define MX53_PAD_PATA_DMARQ__PATA_DMARQ 0x278 0x5f8 0x000 0x0 0x0
+#define MX53_PAD_PATA_DMARQ__GPIO7_0 0x278 0x5f8 0x000 0x1 0x0
+#define MX53_PAD_PATA_DMARQ__UART2_TXD_MUX 0x278 0x5f8 0x000 0x3 0x0
+#define MX53_PAD_PATA_DMARQ__CCM_CCM_OUT_0 0x278 0x5f8 0x000 0x5 0x0
+#define MX53_PAD_PATA_DMARQ__USBPHY2_DATAOUT_4 0x278 0x5f8 0x000 0x7 0x0
+#define MX53_PAD_PATA_BUFFER_EN__PATA_BUFFER_EN 0x27c 0x5fc 0x000 0x0 0x0
+#define MX53_PAD_PATA_BUFFER_EN__GPIO7_1 0x27c 0x5fc 0x000 0x1 0x0
+#define MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX 0x27c 0x5fc 0x880 0x3 0x3
+#define MX53_PAD_PATA_BUFFER_EN__CCM_CCM_OUT_1 0x27c 0x5fc 0x000 0x5 0x0
+#define MX53_PAD_PATA_BUFFER_EN__USBPHY2_DATAOUT_5 0x27c 0x5fc 0x000 0x7 0x0
+#define MX53_PAD_PATA_INTRQ__PATA_INTRQ 0x280 0x600 0x000 0x0 0x0
+#define MX53_PAD_PATA_INTRQ__GPIO7_2 0x280 0x600 0x000 0x1 0x0
+#define MX53_PAD_PATA_INTRQ__UART2_CTS 0x280 0x600 0x000 0x3 0x0
+#define MX53_PAD_PATA_INTRQ__CAN1_TXCAN 0x280 0x600 0x000 0x4 0x0
+#define MX53_PAD_PATA_INTRQ__CCM_CCM_OUT_2 0x280 0x600 0x000 0x5 0x0
+#define MX53_PAD_PATA_INTRQ__USBPHY2_DATAOUT_6 0x280 0x600 0x000 0x7 0x0
+#define MX53_PAD_PATA_DIOR__PATA_DIOR 0x284 0x604 0x000 0x0 0x0
+#define MX53_PAD_PATA_DIOR__GPIO7_3 0x284 0x604 0x000 0x1 0x0
+#define MX53_PAD_PATA_DIOR__UART2_RTS 0x284 0x604 0x87c 0x3 0x3
+#define MX53_PAD_PATA_DIOR__CAN1_RXCAN 0x284 0x604 0x760 0x4 0x1
+#define MX53_PAD_PATA_DIOR__USBPHY2_DATAOUT_7 0x284 0x604 0x000 0x7 0x0
+#define MX53_PAD_PATA_RESET_B__PATA_PATA_RESET_B 0x288 0x608 0x000 0x0 0x0
+#define MX53_PAD_PATA_RESET_B__GPIO7_4 0x288 0x608 0x000 0x1 0x0
+#define MX53_PAD_PATA_RESET_B__ESDHC3_CMD 0x288 0x608 0x000 0x2 0x0
+#define MX53_PAD_PATA_RESET_B__UART1_CTS 0x288 0x608 0x000 0x3 0x0
+#define MX53_PAD_PATA_RESET_B__CAN2_TXCAN 0x288 0x608 0x000 0x4 0x0
+#define MX53_PAD_PATA_RESET_B__USBPHY1_DATAOUT_0 0x288 0x608 0x000 0x7 0x0
+#define MX53_PAD_PATA_IORDY__PATA_IORDY 0x28c 0x60c 0x000 0x0 0x0
+#define MX53_PAD_PATA_IORDY__GPIO7_5 0x28c 0x60c 0x000 0x1 0x0
+#define MX53_PAD_PATA_IORDY__ESDHC3_CLK 0x28c 0x60c 0x000 0x2 0x0
+#define MX53_PAD_PATA_IORDY__UART1_RTS 0x28c 0x60c 0x874 0x3 0x3
+#define MX53_PAD_PATA_IORDY__CAN2_RXCAN 0x28c 0x60c 0x764 0x4 0x1
+#define MX53_PAD_PATA_IORDY__USBPHY1_DATAOUT_1 0x28c 0x60c 0x000 0x7 0x0
+#define MX53_PAD_PATA_DA_0__PATA_DA_0 0x290 0x610 0x000 0x0 0x0
+#define MX53_PAD_PATA_DA_0__GPIO7_6 0x290 0x610 0x000 0x1 0x0
+#define MX53_PAD_PATA_DA_0__ESDHC3_RST 0x290 0x610 0x000 0x2 0x0
+#define MX53_PAD_PATA_DA_0__OWIRE_LINE 0x290 0x610 0x864 0x4 0x0
+#define MX53_PAD_PATA_DA_0__USBPHY1_DATAOUT_2 0x290 0x610 0x000 0x7 0x0
+#define MX53_PAD_PATA_DA_1__PATA_DA_1 0x294 0x614 0x000 0x0 0x0
+#define MX53_PAD_PATA_DA_1__GPIO7_7 0x294 0x614 0x000 0x1 0x0
+#define MX53_PAD_PATA_DA_1__ESDHC4_CMD 0x294 0x614 0x000 0x2 0x0
+#define MX53_PAD_PATA_DA_1__UART3_CTS 0x294 0x614 0x000 0x4 0x0
+#define MX53_PAD_PATA_DA_1__USBPHY1_DATAOUT_3 0x294 0x614 0x000 0x7 0x0
+#define MX53_PAD_PATA_DA_2__PATA_DA_2 0x298 0x618 0x000 0x0 0x0
+#define MX53_PAD_PATA_DA_2__GPIO7_8 0x298 0x618 0x000 0x1 0x0
+#define MX53_PAD_PATA_DA_2__ESDHC4_CLK 0x298 0x618 0x000 0x2 0x0
+#define MX53_PAD_PATA_DA_2__UART3_RTS 0x298 0x618 0x884 0x4 0x5
+#define MX53_PAD_PATA_DA_2__USBPHY1_DATAOUT_4 0x298 0x618 0x000 0x7 0x0
+#define MX53_PAD_PATA_CS_0__PATA_CS_0 0x29c 0x61c 0x000 0x0 0x0
+#define MX53_PAD_PATA_CS_0__GPIO7_9 0x29c 0x61c 0x000 0x1 0x0
+#define MX53_PAD_PATA_CS_0__UART3_TXD_MUX 0x29c 0x61c 0x000 0x4 0x0
+#define MX53_PAD_PATA_CS_0__USBPHY1_DATAOUT_5 0x29c 0x61c 0x000 0x7 0x0
+#define MX53_PAD_PATA_CS_1__PATA_CS_1 0x2a0 0x620 0x000 0x0 0x0
+#define MX53_PAD_PATA_CS_1__GPIO7_10 0x2a0 0x620 0x000 0x1 0x0
+#define MX53_PAD_PATA_CS_1__UART3_RXD_MUX 0x2a0 0x620 0x888 0x4 0x3
+#define MX53_PAD_PATA_CS_1__USBPHY1_DATAOUT_6 0x2a0 0x620 0x000 0x7 0x0
+#define MX53_PAD_PATA_DATA0__PATA_DATA_0 0x2a4 0x628 0x000 0x0 0x0
+#define MX53_PAD_PATA_DATA0__GPIO2_0 0x2a4 0x628 0x000 0x1 0x0
+#define MX53_PAD_PATA_DATA0__EMI_NANDF_D_0 0x2a4 0x628 0x000 0x3 0x0
+#define MX53_PAD_PATA_DATA0__ESDHC3_DAT4 0x2a4 0x628 0x000 0x4 0x0
+#define MX53_PAD_PATA_DATA0__GPU3d_GPU_DEBUG_OUT_0 0x2a4 0x628 0x000 0x5 0x0
+#define MX53_PAD_PATA_DATA0__IPU_DIAG_BUS_0 0x2a4 0x628 0x000 0x6 0x0
+#define MX53_PAD_PATA_DATA0__USBPHY1_DATAOUT_7 0x2a4 0x628 0x000 0x7 0x0
+#define MX53_PAD_PATA_DATA1__PATA_DATA_1 0x2a8 0x62c 0x000 0x0 0x0
+#define MX53_PAD_PATA_DATA1__GPIO2_1 0x2a8 0x62c 0x000 0x1 0x0
+#define MX53_PAD_PATA_DATA1__EMI_NANDF_D_1 0x2a8 0x62c 0x000 0x3 0x0
+#define MX53_PAD_PATA_DATA1__ESDHC3_DAT5 0x2a8 0x62c 0x000 0x4 0x0
+#define MX53_PAD_PATA_DATA1__GPU3d_GPU_DEBUG_OUT_1 0x2a8 0x62c 0x000 0x5 0x0
+#define MX53_PAD_PATA_DATA1__IPU_DIAG_BUS_1 0x2a8 0x62c 0x000 0x6 0x0
+#define MX53_PAD_PATA_DATA2__PATA_DATA_2 0x2ac 0x630 0x000 0x0 0x0
+#define MX53_PAD_PATA_DATA2__GPIO2_2 0x2ac 0x630 0x000 0x1 0x0
+#define MX53_PAD_PATA_DATA2__EMI_NANDF_D_2 0x2ac 0x630 0x000 0x3 0x0
+#define MX53_PAD_PATA_DATA2__ESDHC3_DAT6 0x2ac 0x630 0x000 0x4 0x0
+#define MX53_PAD_PATA_DATA2__GPU3d_GPU_DEBUG_OUT_2 0x2ac 0x630 0x000 0x5 0x0
+#define MX53_PAD_PATA_DATA2__IPU_DIAG_BUS_2 0x2ac 0x630 0x000 0x6 0x0
+#define MX53_PAD_PATA_DATA3__PATA_DATA_3 0x2b0 0x634 0x000 0x0 0x0
+#define MX53_PAD_PATA_DATA3__GPIO2_3 0x2b0 0x634 0x000 0x1 0x0
+#define MX53_PAD_PATA_DATA3__EMI_NANDF_D_3 0x2b0 0x634 0x000 0x3 0x0
+#define MX53_PAD_PATA_DATA3__ESDHC3_DAT7 0x2b0 0x634 0x000 0x4 0x0
+#define MX53_PAD_PATA_DATA3__GPU3d_GPU_DEBUG_OUT_3 0x2b0 0x634 0x000 0x5 0x0
+#define MX53_PAD_PATA_DATA3__IPU_DIAG_BUS_3 0x2b0 0x634 0x000 0x6 0x0
+#define MX53_PAD_PATA_DATA4__PATA_DATA_4 0x2b4 0x638 0x000 0x0 0x0
+#define MX53_PAD_PATA_DATA4__GPIO2_4 0x2b4 0x638 0x000 0x1 0x0
+#define MX53_PAD_PATA_DATA4__EMI_NANDF_D_4 0x2b4 0x638 0x000 0x3 0x0
+#define MX53_PAD_PATA_DATA4__ESDHC4_DAT4 0x2b4 0x638 0x000 0x4 0x0
+#define MX53_PAD_PATA_DATA4__GPU3d_GPU_DEBUG_OUT_4 0x2b4 0x638 0x000 0x5 0x0
+#define MX53_PAD_PATA_DATA4__IPU_DIAG_BUS_4 0x2b4 0x638 0x000 0x6 0x0
+#define MX53_PAD_PATA_DATA5__PATA_DATA_5 0x2b8 0x63c 0x000 0x0 0x0
+#define MX53_PAD_PATA_DATA5__GPIO2_5 0x2b8 0x63c 0x000 0x1 0x0
+#define MX53_PAD_PATA_DATA5__EMI_NANDF_D_5 0x2b8 0x63c 0x000 0x3 0x0
+#define MX53_PAD_PATA_DATA5__ESDHC4_DAT5 0x2b8 0x63c 0x000 0x4 0x0
+#define MX53_PAD_PATA_DATA5__GPU3d_GPU_DEBUG_OUT_5 0x2b8 0x63c 0x000 0x5 0x0
+#define MX53_PAD_PATA_DATA5__IPU_DIAG_BUS_5 0x2b8 0x63c 0x000 0x6 0x0
+#define MX53_PAD_PATA_DATA6__PATA_DATA_6 0x2bc 0x640 0x000 0x0 0x0
+#define MX53_PAD_PATA_DATA6__GPIO2_6 0x2bc 0x640 0x000 0x1 0x0
+#define MX53_PAD_PATA_DATA6__EMI_NANDF_D_6 0x2bc 0x640 0x000 0x3 0x0
+#define MX53_PAD_PATA_DATA6__ESDHC4_DAT6 0x2bc 0x640 0x000 0x4 0x0
+#define MX53_PAD_PATA_DATA6__GPU3d_GPU_DEBUG_OUT_6 0x2bc 0x640 0x000 0x5 0x0
+#define MX53_PAD_PATA_DATA6__IPU_DIAG_BUS_6 0x2bc 0x640 0x000 0x6 0x0
+#define MX53_PAD_PATA_DATA7__PATA_DATA_7 0x2c0 0x644 0x000 0x0 0x0
+#define MX53_PAD_PATA_DATA7__GPIO2_7 0x2c0 0x644 0x000 0x1 0x0
+#define MX53_PAD_PATA_DATA7__EMI_NANDF_D_7 0x2c0 0x644 0x000 0x3 0x0
+#define MX53_PAD_PATA_DATA7__ESDHC4_DAT7 0x2c0 0x644 0x000 0x4 0x0
+#define MX53_PAD_PATA_DATA7__GPU3d_GPU_DEBUG_OUT_7 0x2c0 0x644 0x000 0x5 0x0
+#define MX53_PAD_PATA_DATA7__IPU_DIAG_BUS_7 0x2c0 0x644 0x000 0x6 0x0
+#define MX53_PAD_PATA_DATA8__PATA_DATA_8 0x2c4 0x648 0x000 0x0 0x0
+#define MX53_PAD_PATA_DATA8__GPIO2_8 0x2c4 0x648 0x000 0x1 0x0
+#define MX53_PAD_PATA_DATA8__ESDHC1_DAT4 0x2c4 0x648 0x000 0x2 0x0
+#define MX53_PAD_PATA_DATA8__EMI_NANDF_D_8 0x2c4 0x648 0x000 0x3 0x0
+#define MX53_PAD_PATA_DATA8__ESDHC3_DAT0 0x2c4 0x648 0x000 0x4 0x0
+#define MX53_PAD_PATA_DATA8__GPU3d_GPU_DEBUG_OUT_8 0x2c4 0x648 0x000 0x5 0x0
+#define MX53_PAD_PATA_DATA8__IPU_DIAG_BUS_8 0x2c4 0x648 0x000 0x6 0x0
+#define MX53_PAD_PATA_DATA9__PATA_DATA_9 0x2c8 0x64c 0x000 0x0 0x0
+#define MX53_PAD_PATA_DATA9__GPIO2_9 0x2c8 0x64c 0x000 0x1 0x0
+#define MX53_PAD_PATA_DATA9__ESDHC1_DAT5 0x2c8 0x64c 0x000 0x2 0x0
+#define MX53_PAD_PATA_DATA9__EMI_NANDF_D_9 0x2c8 0x64c 0x000 0x3 0x0
+#define MX53_PAD_PATA_DATA9__ESDHC3_DAT1 0x2c8 0x64c 0x000 0x4 0x0
+#define MX53_PAD_PATA_DATA9__GPU3d_GPU_DEBUG_OUT_9 0x2c8 0x64c 0x000 0x5 0x0
+#define MX53_PAD_PATA_DATA9__IPU_DIAG_BUS_9 0x2c8 0x64c 0x000 0x6 0x0
+#define MX53_PAD_PATA_DATA10__PATA_DATA_10 0x2cc 0x650 0x000 0x0 0x0
+#define MX53_PAD_PATA_DATA10__GPIO2_10 0x2cc 0x650 0x000 0x1 0x0
+#define MX53_PAD_PATA_DATA10__ESDHC1_DAT6 0x2cc 0x650 0x000 0x2 0x0
+#define MX53_PAD_PATA_DATA10__EMI_NANDF_D_10 0x2cc 0x650 0x000 0x3 0x0
+#define MX53_PAD_PATA_DATA10__ESDHC3_DAT2 0x2cc 0x650 0x000 0x4 0x0
+#define MX53_PAD_PATA_DATA10__GPU3d_GPU_DEBUG_OUT_10 0x2cc 0x650 0x000 0x5 0x0
+#define MX53_PAD_PATA_DATA10__IPU_DIAG_BUS_10 0x2cc 0x650 0x000 0x6 0x0
+#define MX53_PAD_PATA_DATA11__PATA_DATA_11 0x2d0 0x654 0x000 0x0 0x0
+#define MX53_PAD_PATA_DATA11__GPIO2_11 0x2d0 0x654 0x000 0x1 0x0
+#define MX53_PAD_PATA_DATA11__ESDHC1_DAT7 0x2d0 0x654 0x000 0x2 0x0
+#define MX53_PAD_PATA_DATA11__EMI_NANDF_D_11 0x2d0 0x654 0x000 0x3 0x0
+#define MX53_PAD_PATA_DATA11__ESDHC3_DAT3 0x2d0 0x654 0x000 0x4 0x0
+#define MX53_PAD_PATA_DATA11__GPU3d_GPU_DEBUG_OUT_11 0x2d0 0x654 0x000 0x5 0x0
+#define MX53_PAD_PATA_DATA11__IPU_DIAG_BUS_11 0x2d0 0x654 0x000 0x6 0x0
+#define MX53_PAD_PATA_DATA12__PATA_DATA_12 0x2d4 0x658 0x000 0x0 0x0
+#define MX53_PAD_PATA_DATA12__GPIO2_12 0x2d4 0x658 0x000 0x1 0x0
+#define MX53_PAD_PATA_DATA12__ESDHC2_DAT4 0x2d4 0x658 0x000 0x2 0x0
+#define MX53_PAD_PATA_DATA12__EMI_NANDF_D_12 0x2d4 0x658 0x000 0x3 0x0
+#define MX53_PAD_PATA_DATA12__ESDHC4_DAT0 0x2d4 0x658 0x000 0x4 0x0
+#define MX53_PAD_PATA_DATA12__GPU3d_GPU_DEBUG_OUT_12 0x2d4 0x658 0x000 0x5 0x0
+#define MX53_PAD_PATA_DATA12__IPU_DIAG_BUS_12 0x2d4 0x658 0x000 0x6 0x0
+#define MX53_PAD_PATA_DATA13__PATA_DATA_13 0x2d8 0x65c 0x000 0x0 0x0
+#define MX53_PAD_PATA_DATA13__GPIO2_13 0x2d8 0x65c 0x000 0x1 0x0
+#define MX53_PAD_PATA_DATA13__ESDHC2_DAT5 0x2d8 0x65c 0x000 0x2 0x0
+#define MX53_PAD_PATA_DATA13__EMI_NANDF_D_13 0x2d8 0x65c 0x000 0x3 0x0
+#define MX53_PAD_PATA_DATA13__ESDHC4_DAT1 0x2d8 0x65c 0x000 0x4 0x0
+#define MX53_PAD_PATA_DATA13__GPU3d_GPU_DEBUG_OUT_13 0x2d8 0x65c 0x000 0x5 0x0
+#define MX53_PAD_PATA_DATA13__IPU_DIAG_BUS_13 0x2d8 0x65c 0x000 0x6 0x0
+#define MX53_PAD_PATA_DATA14__PATA_DATA_14 0x2dc 0x660 0x000 0x0 0x0
+#define MX53_PAD_PATA_DATA14__GPIO2_14 0x2dc 0x660 0x000 0x1 0x0
+#define MX53_PAD_PATA_DATA14__ESDHC2_DAT6 0x2dc 0x660 0x000 0x2 0x0
+#define MX53_PAD_PATA_DATA14__EMI_NANDF_D_14 0x2dc 0x660 0x000 0x3 0x0
+#define MX53_PAD_PATA_DATA14__ESDHC4_DAT2 0x2dc 0x660 0x000 0x4 0x0
+#define MX53_PAD_PATA_DATA14__GPU3d_GPU_DEBUG_OUT_14 0x2dc 0x660 0x000 0x5 0x0
+#define MX53_PAD_PATA_DATA14__IPU_DIAG_BUS_14 0x2dc 0x660 0x000 0x6 0x0
+#define MX53_PAD_PATA_DATA15__PATA_DATA_15 0x2e0 0x664 0x000 0x0 0x0
+#define MX53_PAD_PATA_DATA15__GPIO2_15 0x2e0 0x664 0x000 0x1 0x0
+#define MX53_PAD_PATA_DATA15__ESDHC2_DAT7 0x2e0 0x664 0x000 0x2 0x0
+#define MX53_PAD_PATA_DATA15__EMI_NANDF_D_15 0x2e0 0x664 0x000 0x3 0x0
+#define MX53_PAD_PATA_DATA15__ESDHC4_DAT3 0x2e0 0x664 0x000 0x4 0x0
+#define MX53_PAD_PATA_DATA15__GPU3d_GPU_DEBUG_OUT_15 0x2e0 0x664 0x000 0x5 0x0
+#define MX53_PAD_PATA_DATA15__IPU_DIAG_BUS_15 0x2e0 0x664 0x000 0x6 0x0
+#define MX53_PAD_SD1_DATA0__ESDHC1_DAT0 0x2e4 0x66c 0x000 0x0 0x0
+#define MX53_PAD_SD1_DATA0__GPIO1_16 0x2e4 0x66c 0x000 0x1 0x0
+#define MX53_PAD_SD1_DATA0__GPT_CAPIN1 0x2e4 0x66c 0x000 0x3 0x0
+#define MX53_PAD_SD1_DATA0__CSPI_MISO 0x2e4 0x66c 0x784 0x5 0x2
+#define MX53_PAD_SD1_DATA0__CCM_PLL3_BYP 0x2e4 0x66c 0x778 0x7 0x0
+#define MX53_PAD_SD1_DATA1__ESDHC1_DAT1 0x2e8 0x670 0x000 0x0 0x0
+#define MX53_PAD_SD1_DATA1__GPIO1_17 0x2e8 0x670 0x000 0x1 0x0
+#define MX53_PAD_SD1_DATA1__GPT_CAPIN2 0x2e8 0x670 0x000 0x3 0x0
+#define MX53_PAD_SD1_DATA1__CSPI_SS0 0x2e8 0x670 0x78c 0x5 0x3
+#define MX53_PAD_SD1_DATA1__CCM_PLL4_BYP 0x2e8 0x670 0x77c 0x7 0x1
+#define MX53_PAD_SD1_CMD__ESDHC1_CMD 0x2ec 0x674 0x000 0x0 0x0
+#define MX53_PAD_SD1_CMD__GPIO1_18 0x2ec 0x674 0x000 0x1 0x0
+#define MX53_PAD_SD1_CMD__GPT_CMPOUT1 0x2ec 0x674 0x000 0x3 0x0
+#define MX53_PAD_SD1_CMD__CSPI_MOSI 0x2ec 0x674 0x788 0x5 0x2
+#define MX53_PAD_SD1_CMD__CCM_PLL1_BYP 0x2ec 0x674 0x770 0x7 0x0
+#define MX53_PAD_SD1_DATA2__ESDHC1_DAT2 0x2f0 0x678 0x000 0x0 0x0
+#define MX53_PAD_SD1_DATA2__GPIO1_19 0x2f0 0x678 0x000 0x1 0x0
+#define MX53_PAD_SD1_DATA2__GPT_CMPOUT2 0x2f0 0x678 0x000 0x2 0x0
+#define MX53_PAD_SD1_DATA2__PWM2_PWMO 0x2f0 0x678 0x000 0x3 0x0
+#define MX53_PAD_SD1_DATA2__WDOG1_WDOG_B 0x2f0 0x678 0x000 0x4 0x0
+#define MX53_PAD_SD1_DATA2__CSPI_SS1 0x2f0 0x678 0x790 0x5 0x2
+#define MX53_PAD_SD1_DATA2__WDOG1_WDOG_RST_B_DEB 0x2f0 0x678 0x000 0x6 0x0
+#define MX53_PAD_SD1_DATA2__CCM_PLL2_BYP 0x2f0 0x678 0x774 0x7 0x0
+#define MX53_PAD_SD1_CLK__ESDHC1_CLK 0x2f4 0x67c 0x000 0x0 0x0
+#define MX53_PAD_SD1_CLK__GPIO1_20 0x2f4 0x67c 0x000 0x1 0x0
+#define MX53_PAD_SD1_CLK__OSC32k_32K_OUT 0x2f4 0x67c 0x000 0x2 0x0
+#define MX53_PAD_SD1_CLK__GPT_CLKIN 0x2f4 0x67c 0x000 0x3 0x0
+#define MX53_PAD_SD1_CLK__CSPI_SCLK 0x2f4 0x67c 0x780 0x5 0x2
+#define MX53_PAD_SD1_CLK__SATA_PHY_DTB_0 0x2f4 0x67c 0x000 0x7 0x0
+#define MX53_PAD_SD1_DATA3__ESDHC1_DAT3 0x2f8 0x680 0x000 0x0 0x0
+#define MX53_PAD_SD1_DATA3__GPIO1_21 0x2f8 0x680 0x000 0x1 0x0
+#define MX53_PAD_SD1_DATA3__GPT_CMPOUT3 0x2f8 0x680 0x000 0x2 0x0
+#define MX53_PAD_SD1_DATA3__PWM1_PWMO 0x2f8 0x680 0x000 0x3 0x0
+#define MX53_PAD_SD1_DATA3__WDOG2_WDOG_B 0x2f8 0x680 0x000 0x4 0x0
+#define MX53_PAD_SD1_DATA3__CSPI_SS2 0x2f8 0x680 0x794 0x5 0x2
+#define MX53_PAD_SD1_DATA3__WDOG2_WDOG_RST_B_DEB 0x2f8 0x680 0x000 0x6 0x0
+#define MX53_PAD_SD1_DATA3__SATA_PHY_DTB_1 0x2f8 0x680 0x000 0x7 0x0
+#define MX53_PAD_SD2_CLK__ESDHC2_CLK 0x2fc 0x688 0x000 0x0 0x0
+#define MX53_PAD_SD2_CLK__GPIO1_10 0x2fc 0x688 0x000 0x1 0x0
+#define MX53_PAD_SD2_CLK__KPP_COL_5 0x2fc 0x688 0x840 0x2 0x2
+#define MX53_PAD_SD2_CLK__AUDMUX_AUD4_RXFS 0x2fc 0x688 0x73c 0x3 0x1
+#define MX53_PAD_SD2_CLK__CSPI_SCLK 0x2fc 0x688 0x780 0x5 0x3
+#define MX53_PAD_SD2_CLK__SCC_RANDOM_V 0x2fc 0x688 0x000 0x7 0x0
+#define MX53_PAD_SD2_CMD__ESDHC2_CMD 0x300 0x68c 0x000 0x0 0x0
+#define MX53_PAD_SD2_CMD__GPIO1_11 0x300 0x68c 0x000 0x1 0x0
+#define MX53_PAD_SD2_CMD__KPP_ROW_5 0x300 0x68c 0x84c 0x2 0x1
+#define MX53_PAD_SD2_CMD__AUDMUX_AUD4_RXC 0x300 0x68c 0x738 0x3 0x1
+#define MX53_PAD_SD2_CMD__CSPI_MOSI 0x300 0x68c 0x788 0x5 0x3
+#define MX53_PAD_SD2_CMD__SCC_RANDOM 0x300 0x68c 0x000 0x7 0x0
+#define MX53_PAD_SD2_DATA3__ESDHC2_DAT3 0x304 0x690 0x000 0x0 0x0
+#define MX53_PAD_SD2_DATA3__GPIO1_12 0x304 0x690 0x000 0x1 0x0
+#define MX53_PAD_SD2_DATA3__KPP_COL_6 0x304 0x690 0x844 0x2 0x1
+#define MX53_PAD_SD2_DATA3__AUDMUX_AUD4_TXC 0x304 0x690 0x740 0x3 0x1
+#define MX53_PAD_SD2_DATA3__CSPI_SS2 0x304 0x690 0x794 0x5 0x3
+#define MX53_PAD_SD2_DATA3__SJC_DONE 0x304 0x690 0x000 0x7 0x0
+#define MX53_PAD_SD2_DATA2__ESDHC2_DAT2 0x308 0x694 0x000 0x0 0x0
+#define MX53_PAD_SD2_DATA2__GPIO1_13 0x308 0x694 0x000 0x1 0x0
+#define MX53_PAD_SD2_DATA2__KPP_ROW_6 0x308 0x694 0x850 0x2 0x1
+#define MX53_PAD_SD2_DATA2__AUDMUX_AUD4_TXD 0x308 0x694 0x734 0x3 0x1
+#define MX53_PAD_SD2_DATA2__CSPI_SS1 0x308 0x694 0x790 0x5 0x3
+#define MX53_PAD_SD2_DATA2__SJC_FAIL 0x308 0x694 0x000 0x7 0x0
+#define MX53_PAD_SD2_DATA1__ESDHC2_DAT1 0x30c 0x698 0x000 0x0 0x0
+#define MX53_PAD_SD2_DATA1__GPIO1_14 0x30c 0x698 0x000 0x1 0x0
+#define MX53_PAD_SD2_DATA1__KPP_COL_7 0x30c 0x698 0x848 0x2 0x1
+#define MX53_PAD_SD2_DATA1__AUDMUX_AUD4_TXFS 0x30c 0x698 0x744 0x3 0x1
+#define MX53_PAD_SD2_DATA1__CSPI_SS0 0x30c 0x698 0x78c 0x5 0x4
+#define MX53_PAD_SD2_DATA1__RTIC_SEC_VIO 0x30c 0x698 0x000 0x7 0x0
+#define MX53_PAD_SD2_DATA0__ESDHC2_DAT0 0x310 0x69c 0x000 0x0 0x0
+#define MX53_PAD_SD2_DATA0__GPIO1_15 0x310 0x69c 0x000 0x1 0x0
+#define MX53_PAD_SD2_DATA0__KPP_ROW_7 0x310 0x69c 0x854 0x2 0x1
+#define MX53_PAD_SD2_DATA0__AUDMUX_AUD4_RXD 0x310 0x69c 0x730 0x3 0x1
+#define MX53_PAD_SD2_DATA0__CSPI_MISO 0x310 0x69c 0x784 0x5 0x3
+#define MX53_PAD_SD2_DATA0__RTIC_DONE_INT 0x310 0x69c 0x000 0x7 0x0
+#define MX53_PAD_GPIO_0__CCM_CLKO 0x314 0x6a4 0x000 0x0 0x0
+#define MX53_PAD_GPIO_0__GPIO1_0 0x314 0x6a4 0x000 0x1 0x0
+#define MX53_PAD_GPIO_0__KPP_COL_5 0x314 0x6a4 0x840 0x2 0x3
+#define MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK 0x314 0x6a4 0x000 0x3 0x0
+#define MX53_PAD_GPIO_0__EPIT1_EPITO 0x314 0x6a4 0x000 0x4 0x0
+#define MX53_PAD_GPIO_0__SRTC_ALARM_DEB 0x314 0x6a4 0x000 0x5 0x0
+#define MX53_PAD_GPIO_0__USBOH3_USBH1_PWR 0x314 0x6a4 0x000 0x6 0x0
+#define MX53_PAD_GPIO_0__CSU_TD 0x314 0x6a4 0x000 0x7 0x0
+#define MX53_PAD_GPIO_1__ESAI1_SCKR 0x318 0x6a8 0x7dc 0x0 0x1
+#define MX53_PAD_GPIO_1__GPIO1_1 0x318 0x6a8 0x000 0x1 0x0
+#define MX53_PAD_GPIO_1__KPP_ROW_5 0x318 0x6a8 0x84c 0x2 0x2
+#define MX53_PAD_GPIO_1__CCM_SSI_EXT2_CLK 0x318 0x6a8 0x000 0x3 0x0
+#define MX53_PAD_GPIO_1__PWM2_PWMO 0x318 0x6a8 0x000 0x4 0x0
+#define MX53_PAD_GPIO_1__WDOG2_WDOG_B 0x318 0x6a8 0x000 0x5 0x0
+#define MX53_PAD_GPIO_1__ESDHC1_CD 0x318 0x6a8 0x000 0x6 0x0
+#define MX53_PAD_GPIO_1__SRC_TESTER_ACK 0x318 0x6a8 0x000 0x7 0x0
+#define MX53_PAD_GPIO_9__ESAI1_FSR 0x31c 0x6ac 0x7cc 0x0 0x1
+#define MX53_PAD_GPIO_9__GPIO1_9 0x31c 0x6ac 0x000 0x1 0x0
+#define MX53_PAD_GPIO_9__KPP_COL_6 0x31c 0x6ac 0x844 0x2 0x2
+#define MX53_PAD_GPIO_9__CCM_REF_EN_B 0x31c 0x6ac 0x000 0x3 0x0
+#define MX53_PAD_GPIO_9__PWM1_PWMO 0x31c 0x6ac 0x000 0x4 0x0
+#define MX53_PAD_GPIO_9__WDOG1_WDOG_B 0x31c 0x6ac 0x000 0x5 0x0
+#define MX53_PAD_GPIO_9__ESDHC1_WP 0x31c 0x6ac 0x7fc 0x6 0x1
+#define MX53_PAD_GPIO_9__SCC_FAIL_STATE 0x31c 0x6ac 0x000 0x7 0x0
+#define MX53_PAD_GPIO_3__ESAI1_HCKR 0x320 0x6b0 0x7d4 0x0 0x1
+#define MX53_PAD_GPIO_3__GPIO1_3 0x320 0x6b0 0x000 0x1 0x0
+#define MX53_PAD_GPIO_3__I2C3_SCL 0x320 0x6b0 0x824 0x2 0x1
+#define MX53_PAD_GPIO_3__DPLLIP1_TOG_EN 0x320 0x6b0 0x000 0x3 0x0
+#define MX53_PAD_GPIO_3__CCM_CLKO2 0x320 0x6b0 0x000 0x4 0x0
+#define MX53_PAD_GPIO_3__OBSERVE_MUX_OBSRV_INT_OUT0 0x320 0x6b0 0x000 0x5 0x0
+#define MX53_PAD_GPIO_3__USBOH3_USBH1_OC 0x320 0x6b0 0x8a0 0x6 0x1
+#define MX53_PAD_GPIO_3__MLB_MLBCLK 0x320 0x6b0 0x858 0x7 0x2
+#define MX53_PAD_GPIO_6__ESAI1_SCKT 0x324 0x6b4 0x7e0 0x0 0x1
+#define MX53_PAD_GPIO_6__GPIO1_6 0x324 0x6b4 0x000 0x1 0x0
+#define MX53_PAD_GPIO_6__I2C3_SDA 0x324 0x6b4 0x828 0x2 0x1
+#define MX53_PAD_GPIO_6__CCM_CCM_OUT_0 0x324 0x6b4 0x000 0x3 0x0
+#define MX53_PAD_GPIO_6__CSU_CSU_INT_DEB 0x324 0x6b4 0x000 0x4 0x0
+#define MX53_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 0x324 0x6b4 0x000 0x5 0x0
+#define MX53_PAD_GPIO_6__ESDHC2_LCTL 0x324 0x6b4 0x000 0x6 0x0
+#define MX53_PAD_GPIO_6__MLB_MLBSIG 0x324 0x6b4 0x860 0x7 0x2
+#define MX53_PAD_GPIO_2__ESAI1_FST 0x328 0x6b8 0x7d0 0x0 0x1
+#define MX53_PAD_GPIO_2__GPIO1_2 0x328 0x6b8 0x000 0x1 0x0
+#define MX53_PAD_GPIO_2__KPP_ROW_6 0x328 0x6b8 0x850 0x2 0x2
+#define MX53_PAD_GPIO_2__CCM_CCM_OUT_1 0x328 0x6b8 0x000 0x3 0x0
+#define MX53_PAD_GPIO_2__CSU_CSU_ALARM_AUT_0 0x328 0x6b8 0x000 0x4 0x0
+#define MX53_PAD_GPIO_2__OBSERVE_MUX_OBSRV_INT_OUT2 0x328 0x6b8 0x000 0x5 0x0
+#define MX53_PAD_GPIO_2__ESDHC2_WP 0x328 0x6b8 0x000 0x6 0x0
+#define MX53_PAD_GPIO_2__MLB_MLBDAT 0x328 0x6b8 0x85c 0x7 0x2
+#define MX53_PAD_GPIO_4__ESAI1_HCKT 0x32c 0x6bc 0x7d8 0x0 0x1
+#define MX53_PAD_GPIO_4__GPIO1_4 0x32c 0x6bc 0x000 0x1 0x0
+#define MX53_PAD_GPIO_4__KPP_COL_7 0x32c 0x6bc 0x848 0x2 0x2
+#define MX53_PAD_GPIO_4__CCM_CCM_OUT_2 0x32c 0x6bc 0x000 0x3 0x0
+#define MX53_PAD_GPIO_4__CSU_CSU_ALARM_AUT_1 0x32c 0x6bc 0x000 0x4 0x0
+#define MX53_PAD_GPIO_4__OBSERVE_MUX_OBSRV_INT_OUT3 0x32c 0x6bc 0x000 0x5 0x0
+#define MX53_PAD_GPIO_4__ESDHC2_CD 0x32c 0x6bc 0x000 0x6 0x0
+#define MX53_PAD_GPIO_4__SCC_SEC_STATE 0x32c 0x6bc 0x000 0x7 0x0
+#define MX53_PAD_GPIO_5__ESAI1_TX2_RX3 0x330 0x6c0 0x7ec 0x0 0x1
+#define MX53_PAD_GPIO_5__GPIO1_5 0x330 0x6c0 0x000 0x1 0x0
+#define MX53_PAD_GPIO_5__KPP_ROW_7 0x330 0x6c0 0x854 0x2 0x2
+#define MX53_PAD_GPIO_5__CCM_CLKO 0x330 0x6c0 0x000 0x3 0x0
+#define MX53_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 0x330 0x6c0 0x000 0x4 0x0
+#define MX53_PAD_GPIO_5__OBSERVE_MUX_OBSRV_INT_OUT4 0x330 0x6c0 0x000 0x5 0x0
+#define MX53_PAD_GPIO_5__I2C3_SCL 0x330 0x6c0 0x824 0x6 0x2
+#define MX53_PAD_GPIO_5__CCM_PLL1_BYP 0x330 0x6c0 0x770 0x7 0x1
+#define MX53_PAD_GPIO_7__ESAI1_TX4_RX1 0x334 0x6c4 0x7f4 0x0 0x1
+#define MX53_PAD_GPIO_7__GPIO1_7 0x334 0x6c4 0x000 0x1 0x0
+#define MX53_PAD_GPIO_7__EPIT1_EPITO 0x334 0x6c4 0x000 0x2 0x0
+#define MX53_PAD_GPIO_7__CAN1_TXCAN 0x334 0x6c4 0x000 0x3 0x0
+#define MX53_PAD_GPIO_7__UART2_TXD_MUX 0x334 0x6c4 0x000 0x4 0x0
+#define MX53_PAD_GPIO_7__FIRI_RXD 0x334 0x6c4 0x80c 0x5 0x1
+#define MX53_PAD_GPIO_7__SPDIF_PLOCK 0x334 0x6c4 0x000 0x6 0x0
+#define MX53_PAD_GPIO_7__CCM_PLL2_BYP 0x334 0x6c4 0x774 0x7 0x1
+#define MX53_PAD_GPIO_8__ESAI1_TX5_RX0 0x338 0x6c8 0x7f8 0x0 0x1
+#define MX53_PAD_GPIO_8__GPIO1_8 0x338 0x6c8 0x000 0x1 0x0
+#define MX53_PAD_GPIO_8__EPIT2_EPITO 0x338 0x6c8 0x000 0x2 0x0
+#define MX53_PAD_GPIO_8__CAN1_RXCAN 0x338 0x6c8 0x760 0x3 0x2
+#define MX53_PAD_GPIO_8__UART2_RXD_MUX 0x338 0x6c8 0x880 0x4 0x5
+#define MX53_PAD_GPIO_8__FIRI_TXD 0x338 0x6c8 0x000 0x5 0x0
+#define MX53_PAD_GPIO_8__SPDIF_SRCLK 0x338 0x6c8 0x000 0x6 0x0
+#define MX53_PAD_GPIO_8__CCM_PLL3_BYP 0x338 0x6c8 0x778 0x7 0x1
+#define MX53_PAD_GPIO_16__ESAI1_TX3_RX2 0x33c 0x6cc 0x7f0 0x0 0x1
+#define MX53_PAD_GPIO_16__GPIO7_11 0x33c 0x6cc 0x000 0x1 0x0
+#define MX53_PAD_GPIO_16__TZIC_PWRFAIL_INT 0x33c 0x6cc 0x000 0x2 0x0
+#define MX53_PAD_GPIO_16__RTC_CE_RTC_EXT_TRIG1 0x33c 0x6cc 0x000 0x4 0x0
+#define MX53_PAD_GPIO_16__SPDIF_IN1 0x33c 0x6cc 0x870 0x5 0x1
+#define MX53_PAD_GPIO_16__I2C3_SDA 0x33c 0x6cc 0x828 0x6 0x2
+#define MX53_PAD_GPIO_16__SJC_DE_B 0x33c 0x6cc 0x000 0x7 0x0
+#define MX53_PAD_GPIO_17__ESAI1_TX0 0x340 0x6d0 0x7e4 0x0 0x1
+#define MX53_PAD_GPIO_17__GPIO7_12 0x340 0x6d0 0x000 0x1 0x0
+#define MX53_PAD_GPIO_17__SDMA_EXT_EVENT_0 0x340 0x6d0 0x868 0x2 0x1
+#define MX53_PAD_GPIO_17__GPC_PMIC_RDY 0x340 0x6d0 0x810 0x3 0x1
+#define MX53_PAD_GPIO_17__RTC_CE_RTC_FSV_TRIG 0x340 0x6d0 0x000 0x4 0x0
+#define MX53_PAD_GPIO_17__SPDIF_OUT1 0x340 0x6d0 0x000 0x5 0x0
+#define MX53_PAD_GPIO_17__IPU_SNOOP2 0x340 0x6d0 0x000 0x6 0x0
+#define MX53_PAD_GPIO_17__SJC_JTAG_ACT 0x340 0x6d0 0x000 0x7 0x0
+#define MX53_PAD_GPIO_18__ESAI1_TX1 0x344 0x6d4 0x7e8 0x0 0x1
+#define MX53_PAD_GPIO_18__GPIO7_13 0x344 0x6d4 0x000 0x1 0x0
+#define MX53_PAD_GPIO_18__SDMA_EXT_EVENT_1 0x344 0x6d4 0x86c 0x2 0x1
+#define MX53_PAD_GPIO_18__OWIRE_LINE 0x344 0x6d4 0x864 0x3 0x1
+#define MX53_PAD_GPIO_18__RTC_CE_RTC_ALARM2_TRIG 0x344 0x6d4 0x000 0x4 0x0
+#define MX53_PAD_GPIO_18__CCM_ASRC_EXT_CLK 0x344 0x6d4 0x768 0x5 0x1
+#define MX53_PAD_GPIO_18__ESDHC1_LCTL 0x344 0x6d4 0x000 0x6 0x0
+#define MX53_PAD_GPIO_18__SRC_SYSTEM_RST 0x344 0x6d4 0x000 0x7 0x0
+
+#endif /* __DTS_IMX53_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx53-qsb-common.dtsi b/arch/arm/boot/dts/imx53-qsb-common.dtsi
new file mode 100644
index 000000000..181ae5ebf
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-qsb-common.dtsi
@@ -0,0 +1,366 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 "imx53.dtsi"
+
+/ {
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory {
+ reg = <0x70000000 0x20000000>,
+ <0xb0000000 0x20000000>;
+ };
+
+ display0: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ interface-pix-fmt = "rgb565";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu_disp0>;
+ status = "disabled";
+ display-timings {
+ claawvga {
+ native-mode;
+ clock-frequency = <27000000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <40>;
+ hfront-porch = <60>;
+ vback-porch = <10>;
+ vfront-porch = <10>;
+ hsync-len = <20>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+
+ port {
+ display0_in: endpoint {
+ remote-endpoint = <&ipu_di0_disp0>;
+ };
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power Button";
+ gpios = <&gpio1 8 0>;
+ linux,code = <116>; /* KEY_POWER */
+ };
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio2 14 0>;
+ linux,code = <115>; /* KEY_VOLUMEUP */
+ gpio-key,wakeup;
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio2 15 0>;
+ linux,code = <114>; /* KEY_VOLUMEDOWN */
+ gpio-key,wakeup;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pin_gpio7_7>;
+
+ user {
+ label = "Heartbeat";
+ gpios = <&gpio7 7 0>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p2v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P2V";
+ regulator-min-microvolt = <3200000>;
+ regulator-max-microvolt = <3200000>;
+ regulator-always-on;
+ };
+
+ reg_usb_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio7 8 0>;
+ enable-active-high;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx53-qsb-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx53-qsb-sgtl5000";
+ ssi-controller = <&ssi2>;
+ audio-codec = <&sgtl5000>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <2>;
+ mux-ext-port = <5>;
+ };
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ status = "okay";
+};
+
+&ipu_di0_disp0 {
+ remote-endpoint = <&display0_in>;
+};
+
+&ssi2 {
+ status = "okay";
+};
+
+&esdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc3>;
+ cd-gpios = <&gpio3 11 0>;
+ wp-gpios = <&gpio3 12 0>;
+ bus-width = <8>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx53-qsb {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK 0x80000000
+ MX53_PAD_GPIO_8__GPIO1_8 0x80000000
+ MX53_PAD_PATA_DATA14__GPIO2_14 0x80000000
+ MX53_PAD_PATA_DATA15__GPIO2_15 0x80000000
+ MX53_PAD_EIM_DA11__GPIO3_11 0x80000000
+ MX53_PAD_EIM_DA12__GPIO3_12 0x80000000
+ MX53_PAD_PATA_DA_0__GPIO7_6 0x80000000
+ MX53_PAD_PATA_DA_2__GPIO7_8 0x80000000
+ MX53_PAD_GPIO_16__GPIO7_11 0x80000000
+ >;
+ };
+
+ led_pin_gpio7_7: led_gpio7_7@0 {
+ fsl,pins = <
+ MX53_PAD_PATA_DA_1__GPIO7_7 0x80000000
+ >;
+ };
+
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC 0x80000000
+ MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD 0x80000000
+ MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS 0x80000000
+ MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD 0x80000000
+ >;
+ };
+
+ pinctrl_esdhc1: esdhc1grp {
+ fsl,pins = <
+ MX53_PAD_SD1_DATA0__ESDHC1_DAT0 0x1d5
+ MX53_PAD_SD1_DATA1__ESDHC1_DAT1 0x1d5
+ MX53_PAD_SD1_DATA2__ESDHC1_DAT2 0x1d5
+ MX53_PAD_SD1_DATA3__ESDHC1_DAT3 0x1d5
+ MX53_PAD_SD1_CMD__ESDHC1_CMD 0x1d5
+ MX53_PAD_SD1_CLK__ESDHC1_CLK 0x1d5
+ >;
+ };
+
+ pinctrl_esdhc3: esdhc3grp {
+ fsl,pins = <
+ MX53_PAD_PATA_DATA8__ESDHC3_DAT0 0x1d5
+ MX53_PAD_PATA_DATA9__ESDHC3_DAT1 0x1d5
+ MX53_PAD_PATA_DATA10__ESDHC3_DAT2 0x1d5
+ MX53_PAD_PATA_DATA11__ESDHC3_DAT3 0x1d5
+ MX53_PAD_PATA_DATA0__ESDHC3_DAT4 0x1d5
+ MX53_PAD_PATA_DATA1__ESDHC3_DAT5 0x1d5
+ MX53_PAD_PATA_DATA2__ESDHC3_DAT6 0x1d5
+ MX53_PAD_PATA_DATA3__ESDHC3_DAT7 0x1d5
+ MX53_PAD_PATA_RESET_B__ESDHC3_CMD 0x1d5
+ MX53_PAD_PATA_IORDY__ESDHC3_CLK 0x1d5
+ >;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX53_PAD_FEC_MDC__FEC_MDC 0x80000000
+ MX53_PAD_FEC_MDIO__FEC_MDIO 0x80000000
+ MX53_PAD_FEC_REF_CLK__FEC_TX_CLK 0x80000000
+ MX53_PAD_FEC_RX_ER__FEC_RX_ER 0x80000000
+ MX53_PAD_FEC_CRS_DV__FEC_RX_DV 0x80000000
+ MX53_PAD_FEC_RXD1__FEC_RDATA_1 0x80000000
+ MX53_PAD_FEC_RXD0__FEC_RDATA_0 0x80000000
+ MX53_PAD_FEC_TX_EN__FEC_TX_EN 0x80000000
+ MX53_PAD_FEC_TXD1__FEC_TDATA_1 0x80000000
+ MX53_PAD_FEC_TXD0__FEC_TDATA_0 0x80000000
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX53_PAD_CSI0_DAT8__I2C1_SDA 0xc0000000
+ MX53_PAD_CSI0_DAT9__I2C1_SCL 0xc0000000
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX53_PAD_KEY_ROW3__I2C2_SDA 0xc0000000
+ MX53_PAD_KEY_COL3__I2C2_SCL 0xc0000000
+ >;
+ };
+
+ pinctrl_ipu_disp0: ipudisp0grp {
+ fsl,pins = <
+ MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK 0x5
+ MX53_PAD_DI0_PIN15__IPU_DI0_PIN15 0x5
+ MX53_PAD_DI0_PIN2__IPU_DI0_PIN2 0x5
+ MX53_PAD_DI0_PIN3__IPU_DI0_PIN3 0x5
+ MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0 0x5
+ MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1 0x5
+ MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2 0x5
+ MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3 0x5
+ MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4 0x5
+ MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5 0x5
+ MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6 0x5
+ MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7 0x5
+ MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8 0x5
+ MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9 0x5
+ MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10 0x5
+ MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11 0x5
+ MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12 0x5
+ MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13 0x5
+ MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14 0x5
+ MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15 0x5
+ MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16 0x5
+ MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17 0x5
+ MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18 0x5
+ MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19 0x5
+ MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20 0x5
+ MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21 0x5
+ MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22 0x5
+ MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23 0x5
+ >;
+ };
+
+ pinctrl_vga_sync: vgasync-grp {
+ fsl,pins = <
+ /* VGA_HSYNC, VSYNC with max drive strength */
+ MX53_PAD_EIM_OE__IPU_DI1_PIN7 0xe6
+ MX53_PAD_EIM_RW__IPU_DI1_PIN8 0xe6
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX53_PAD_CSI0_DAT10__UART1_TXD_MUX 0x1e4
+ MX53_PAD_CSI0_DAT11__UART1_RXD_MUX 0x1e4
+ >;
+ };
+ };
+};
+
+&tve {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_vga_sync>;
+ fsl,tve-mode = "vga";
+ fsl,hsync-pin = <4>;
+ fsl,vsync-pin = <6>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ sgtl5000: codec@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ VDDA-supply = <&reg_3p2v>;
+ VDDIO-supply = <&reg_3p2v>;
+ clocks = <&clks IMX5_CLK_SSI_EXT1_GATE>;
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ accelerometer: mma8450@1c {
+ compatible = "fsl,mma8450";
+ reg = <0x1c>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ phy-mode = "rmii";
+ phy-reset-gpios = <&gpio7 6 0>;
+ status = "okay";
+};
+
+&sata {
+ status = "okay";
+};
+
+&vpu {
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_vbus>;
+ phy_type = "utmi";
+ status = "okay";
+};
+
+&usbotg {
+ dr_mode = "peripheral";
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx53-qsb.dts b/arch/arm/boot/dts/imx53-qsb.dts
new file mode 100644
index 000000000..dec4b073c
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-qsb.dts
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx53-qsb-common.dtsi"
+
+/ {
+ model = "Freescale i.MX53 Quick Start Board";
+ compatible = "fsl,imx53-qsb", "fsl,imx53";
+};
+
+&i2c1 {
+ pmic: dialog@48 {
+ compatible = "dlg,da9053-aa", "dlg,da9052";
+ reg = <0x48>;
+ interrupt-parent = <&gpio7>;
+ interrupts = <11 0x8>; /* low-level active IRQ at GPIO7_11 */
+
+ regulators {
+ buck1_reg: buck1 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <2075000>;
+ regulator-always-on;
+ };
+
+ buck2_reg: buck2 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <2075000>;
+ regulator-always-on;
+ };
+
+ buck3_reg: buck3 {
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ buck4_reg: buck4 {
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ ldo1_reg: ldo1 {
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo2_reg: ldo2 {
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo3_reg: ldo3 {
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo4_reg: ldo4 {
+ regulator-min-microvolt = <1725000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo5_reg: ldo5 {
+ regulator-min-microvolt = <1725000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo6_reg: ldo6 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3600000>;
+ regulator-always-on;
+ };
+
+ ldo7_reg: ldo7 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3600000>;
+ regulator-always-on;
+ };
+
+ ldo8_reg: ldo8 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3600000>;
+ regulator-always-on;
+ };
+
+ ldo9_reg: ldo9 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3600000>;
+ regulator-always-on;
+ };
+
+ ldo10_reg: ldo10 {
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <3650000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx53-qsrb.dts b/arch/arm/boot/dts/imx53-qsrb.dts
new file mode 100644
index 000000000..82d623d05
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-qsrb.dts
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/dts-v1/;
+
+#include "imx53-qsb-common.dtsi"
+
+/ {
+ model = "Freescale i.MX53 Quick Start-R Board";
+ compatible = "fsl,imx53-qsrb", "fsl,imx53";
+};
+
+&iomuxc {
+ i2c1 {
+ /* open drain */
+ pinctrl_i2c1_qsrb: i2c1grp-1 {
+ fsl,pins = <
+ MX53_PAD_CSI0_DAT8__I2C1_SDA 0x400001ec
+ MX53_PAD_CSI0_DAT9__I2C1_SCL 0x400001ec
+ >;
+ };
+
+ pinctrl_pmic: pmicgrp {
+ fsl,pins = <
+ MX53_PAD_CSI0_DAT5__GPIO5_23 0x1e4 /* IRQ */
+ >;
+ };
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1_qsrb>;
+ status = "okay";
+
+ pmic: mc34708@8 {
+ compatible = "fsl,mc34708";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pmic>;
+ reg = <0x08>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <23 0x8>;
+ regulators {
+ sw1_reg: sw1a {
+ regulator-name = "SW1";
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <1437500>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw1b_reg: sw1b {
+ regulator-name = "SW1B";
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <1437500>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw2_reg: sw2 {
+ regulator-name = "SW2";
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <1437500>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3_reg: sw3 {
+ regulator-name = "SW3";
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <1425000>;
+ regulator-boot-on;
+ };
+
+ sw4a_reg: sw4a {
+ regulator-name = "SW4A";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4b_reg: sw4b {
+ regulator-name = "SW4B";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw5_reg: sw5 {
+ regulator-name = "SW5";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-name = "SWBST";
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vpll_reg: vpll {
+ regulator-name = "VPLL";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ };
+
+ vrefddr_reg: vrefddr {
+ regulator-name = "VREFDDR";
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vusb_reg: vusb {
+ regulator-name = "VUSB";
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vusb2_reg: vusb2 {
+ regulator-name = "VUSB2";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdac_reg: vdac {
+ regulator-name = "VDAC";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2775000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-name = "VGEN1";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-name = "VGEN2";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx53-smd.dts b/arch/arm/boot/dts/imx53-smd.dts
new file mode 100644
index 000000000..1d325576b
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-smd.dts
@@ -0,0 +1,279 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx53.dtsi"
+
+/ {
+ model = "Freescale i.MX53 Smart Mobile Reference Design Board";
+ compatible = "fsl,imx53-smd", "fsl,imx53";
+
+ memory {
+ reg = <0x70000000 0x40000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio2 14 0>;
+ linux,code = <115>; /* KEY_VOLUMEUP */
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio2 15 0>;
+ linux,code = <114>; /* KEY_VOLUMEDOWN */
+ };
+ };
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ cd-gpios = <&gpio3 13 0>;
+ wp-gpios = <&gpio4 11 0>;
+ status = "okay";
+};
+
+&esdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc2>;
+ non-removable;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&ecspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ fsl,spi-num-chipselects = <2>;
+ cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>;
+ status = "okay";
+
+ zigbee: mc1323@0 {
+ compatible = "fsl,mc1323";
+ spi-max-frequency = <8000000>;
+ reg = <0>;
+ };
+
+ flash: m25p32@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p32", "st,m25p";
+ spi-max-frequency = <20000000>;
+ reg = <1>;
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0x0 0x40000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "Kernel";
+ reg = <0x40000 0x3c0000>;
+ };
+ };
+};
+
+&esdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc3>;
+ non-removable;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx53-smd {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX53_PAD_PATA_DATA14__GPIO2_14 0x80000000
+ MX53_PAD_PATA_DATA15__GPIO2_15 0x80000000
+ MX53_PAD_EIM_EB2__GPIO2_30 0x80000000
+ MX53_PAD_EIM_DA13__GPIO3_13 0x80000000
+ MX53_PAD_EIM_D19__GPIO3_19 0x80000000
+ MX53_PAD_KEY_ROW2__GPIO4_11 0x80000000
+ MX53_PAD_PATA_DA_0__GPIO7_6 0x80000000
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX53_PAD_EIM_D16__ECSPI1_SCLK 0x80000000
+ MX53_PAD_EIM_D17__ECSPI1_MISO 0x80000000
+ MX53_PAD_EIM_D18__ECSPI1_MOSI 0x80000000
+ >;
+ };
+
+ pinctrl_esdhc1: esdhc1grp {
+ fsl,pins = <
+ MX53_PAD_SD1_DATA0__ESDHC1_DAT0 0x1d5
+ MX53_PAD_SD1_DATA1__ESDHC1_DAT1 0x1d5
+ MX53_PAD_SD1_DATA2__ESDHC1_DAT2 0x1d5
+ MX53_PAD_SD1_DATA3__ESDHC1_DAT3 0x1d5
+ MX53_PAD_SD1_CMD__ESDHC1_CMD 0x1d5
+ MX53_PAD_SD1_CLK__ESDHC1_CLK 0x1d5
+ >;
+ };
+
+ pinctrl_esdhc2: esdhc2grp {
+ fsl,pins = <
+ MX53_PAD_SD2_CMD__ESDHC2_CMD 0x1d5
+ MX53_PAD_SD2_CLK__ESDHC2_CLK 0x1d5
+ MX53_PAD_SD2_DATA0__ESDHC2_DAT0 0x1d5
+ MX53_PAD_SD2_DATA1__ESDHC2_DAT1 0x1d5
+ MX53_PAD_SD2_DATA2__ESDHC2_DAT2 0x1d5
+ MX53_PAD_SD2_DATA3__ESDHC2_DAT3 0x1d5
+ >;
+ };
+
+ pinctrl_esdhc3: esdhc3grp {
+ fsl,pins = <
+ MX53_PAD_PATA_DATA8__ESDHC3_DAT0 0x1d5
+ MX53_PAD_PATA_DATA9__ESDHC3_DAT1 0x1d5
+ MX53_PAD_PATA_DATA10__ESDHC3_DAT2 0x1d5
+ MX53_PAD_PATA_DATA11__ESDHC3_DAT3 0x1d5
+ MX53_PAD_PATA_DATA0__ESDHC3_DAT4 0x1d5
+ MX53_PAD_PATA_DATA1__ESDHC3_DAT5 0x1d5
+ MX53_PAD_PATA_DATA2__ESDHC3_DAT6 0x1d5
+ MX53_PAD_PATA_DATA3__ESDHC3_DAT7 0x1d5
+ MX53_PAD_PATA_RESET_B__ESDHC3_CMD 0x1d5
+ MX53_PAD_PATA_IORDY__ESDHC3_CLK 0x1d5
+ >;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX53_PAD_FEC_MDC__FEC_MDC 0x80000000
+ MX53_PAD_FEC_MDIO__FEC_MDIO 0x80000000
+ MX53_PAD_FEC_REF_CLK__FEC_TX_CLK 0x80000000
+ MX53_PAD_FEC_RX_ER__FEC_RX_ER 0x80000000
+ MX53_PAD_FEC_CRS_DV__FEC_RX_DV 0x80000000
+ MX53_PAD_FEC_RXD1__FEC_RDATA_1 0x80000000
+ MX53_PAD_FEC_RXD0__FEC_RDATA_0 0x80000000
+ MX53_PAD_FEC_TX_EN__FEC_TX_EN 0x80000000
+ MX53_PAD_FEC_TXD1__FEC_TDATA_1 0x80000000
+ MX53_PAD_FEC_TXD0__FEC_TDATA_0 0x80000000
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX53_PAD_CSI0_DAT8__I2C1_SDA 0xc0000000
+ MX53_PAD_CSI0_DAT9__I2C1_SCL 0xc0000000
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX53_PAD_KEY_ROW3__I2C2_SDA 0xc0000000
+ MX53_PAD_KEY_COL3__I2C2_SCL 0xc0000000
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX53_PAD_CSI0_DAT10__UART1_TXD_MUX 0x1e4
+ MX53_PAD_CSI0_DAT11__UART1_RXD_MUX 0x1e4
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX 0x1e4
+ MX53_PAD_PATA_DMARQ__UART2_TXD_MUX 0x1e4
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX53_PAD_PATA_CS_0__UART3_TXD_MUX 0x1e4
+ MX53_PAD_PATA_CS_1__UART3_RXD_MUX 0x1e4
+ MX53_PAD_PATA_DA_1__UART3_CTS 0x1e4
+ MX53_PAD_PATA_DA_2__UART3_RTS 0x1e4
+ >;
+ };
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ };
+
+ magnetometer: mag3110@0e {
+ compatible = "fsl,mag3110";
+ reg = <0x0e>;
+ };
+
+ touchkey: mpr121@5a {
+ compatible = "fsl,mpr121";
+ reg = <0x5a>;
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ accelerometer: mma8450@1c {
+ compatible = "fsl,mma8450";
+ reg = <0x1c>;
+ };
+
+ camera: ov5642@3c {
+ compatible = "ovti,ov5642";
+ reg = <0x3c>;
+ };
+
+ pmic: dialog@48 {
+ compatible = "dlg,da9053", "dlg,da9052";
+ reg = <0x48>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ phy-mode = "rmii";
+ phy-reset-gpios = <&gpio7 6 0>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx53-tqma53.dtsi b/arch/arm/boot/dts/imx53-tqma53.dtsi
new file mode 100644
index 000000000..4f1f0e286
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-tqma53.dtsi
@@ -0,0 +1,288 @@
+/*
+ * Copyright 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * 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 "imx53.dtsi"
+
+/ {
+ model = "TQ TQMa53";
+ compatible = "tq,tqma53", "fsl,imx53";
+
+ memory {
+ reg = <0x70000000 0x40000000>; /* Up to 1GiB */
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+};
+
+&esdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc2>,
+ <&pinctrl_esdhc2_cdwp>;
+ vmmc-supply = <&reg_3p3v>;
+ wp-gpios = <&gpio1 2 0>;
+ cd-gpios = <&gpio1 4 0>;
+ status = "disabled";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "disabled";
+};
+
+&ecspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ fsl,spi-num-chipselects = <4>;
+ cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>,
+ <&gpio3 24 0>, <&gpio3 25 0>;
+ status = "disabled";
+};
+
+&esdhc3 { /* EMMC */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc3>;
+ vmmc-supply = <&reg_3p3v>;
+ non-removable;
+ bus-width = <8>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx53-tqma53 {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK 0x80000000 /* SSI_MCLK */
+ MX53_PAD_PATA_DA_1__GPIO7_7 0x80000000 /* LCD_BLT_EN */
+ MX53_PAD_PATA_DA_2__GPIO7_8 0x80000000 /* LCD_RESET */
+ MX53_PAD_PATA_DATA5__GPIO2_5 0x80000000 /* LCD_POWER */
+ MX53_PAD_PATA_DATA6__GPIO2_6 0x80000000 /* PMIC_INT */
+ MX53_PAD_PATA_DATA14__GPIO2_14 0x80000000 /* CSI_RST */
+ MX53_PAD_PATA_DATA15__GPIO2_15 0x80000000 /* CSI_PWDN */
+ MX53_PAD_GPIO_19__GPIO4_5 0x80000000 /* #SYSTEM_DOWN */
+ MX53_PAD_GPIO_3__GPIO1_3 0x80000000
+ MX53_PAD_PATA_DA_0__GPIO7_6 0x80000000 /* #PHY_RESET */
+ MX53_PAD_GPIO_1__PWM2_PWMO 0x80000000 /* LCD_CONTRAST */
+ >;
+ };
+
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC 0x80000000
+ MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD 0x80000000
+ MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS 0x80000000
+ MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD 0x80000000
+ >;
+ };
+
+ pinctrl_can1: can1grp {
+ fsl,pins = <
+ MX53_PAD_KEY_COL2__CAN1_TXCAN 0x80000000
+ MX53_PAD_KEY_ROW2__CAN1_RXCAN 0x80000000
+ >;
+ };
+
+ pinctrl_can2: can2grp {
+ fsl,pins = <
+ MX53_PAD_KEY_COL4__CAN2_TXCAN 0x80000000
+ MX53_PAD_KEY_ROW4__CAN2_RXCAN 0x80000000
+ >;
+ };
+
+ pinctrl_cspi: cspigrp {
+ fsl,pins = <
+ MX53_PAD_SD1_DATA0__CSPI_MISO 0x1d5
+ MX53_PAD_SD1_CMD__CSPI_MOSI 0x1d5
+ MX53_PAD_SD1_CLK__CSPI_SCLK 0x1d5
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX53_PAD_EIM_D16__ECSPI1_SCLK 0x80000000
+ MX53_PAD_EIM_D17__ECSPI1_MISO 0x80000000
+ MX53_PAD_EIM_D18__ECSPI1_MOSI 0x80000000
+ >;
+ };
+
+ pinctrl_esdhc2: esdhc2grp {
+ fsl,pins = <
+ MX53_PAD_SD2_CMD__ESDHC2_CMD 0x1d5
+ MX53_PAD_SD2_CLK__ESDHC2_CLK 0x1d5
+ MX53_PAD_SD2_DATA0__ESDHC2_DAT0 0x1d5
+ MX53_PAD_SD2_DATA1__ESDHC2_DAT1 0x1d5
+ MX53_PAD_SD2_DATA2__ESDHC2_DAT2 0x1d5
+ MX53_PAD_SD2_DATA3__ESDHC2_DAT3 0x1d5
+ >;
+ };
+
+ pinctrl_esdhc2_cdwp: esdhc2cdwp {
+ fsl,pins = <
+ MX53_PAD_GPIO_4__GPIO1_4 0x80000000 /* SD2_CD */
+ MX53_PAD_GPIO_2__GPIO1_2 0x80000000 /* SD2_WP */
+ >;
+ };
+
+ pinctrl_esdhc3: esdhc3grp {
+ fsl,pins = <
+ MX53_PAD_PATA_DATA8__ESDHC3_DAT0 0x1d5
+ MX53_PAD_PATA_DATA9__ESDHC3_DAT1 0x1d5
+ MX53_PAD_PATA_DATA10__ESDHC3_DAT2 0x1d5
+ MX53_PAD_PATA_DATA11__ESDHC3_DAT3 0x1d5
+ MX53_PAD_PATA_DATA0__ESDHC3_DAT4 0x1d5
+ MX53_PAD_PATA_DATA1__ESDHC3_DAT5 0x1d5
+ MX53_PAD_PATA_DATA2__ESDHC3_DAT6 0x1d5
+ MX53_PAD_PATA_DATA3__ESDHC3_DAT7 0x1d5
+ MX53_PAD_PATA_RESET_B__ESDHC3_CMD 0x1d5
+ MX53_PAD_PATA_IORDY__ESDHC3_CLK 0x1d5
+ >;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX53_PAD_FEC_MDC__FEC_MDC 0x80000000
+ MX53_PAD_FEC_MDIO__FEC_MDIO 0x80000000
+ MX53_PAD_FEC_REF_CLK__FEC_TX_CLK 0x80000000
+ MX53_PAD_FEC_RX_ER__FEC_RX_ER 0x80000000
+ MX53_PAD_FEC_CRS_DV__FEC_RX_DV 0x80000000
+ MX53_PAD_FEC_RXD1__FEC_RDATA_1 0x80000000
+ MX53_PAD_FEC_RXD0__FEC_RDATA_0 0x80000000
+ MX53_PAD_FEC_TX_EN__FEC_TX_EN 0x80000000
+ MX53_PAD_FEC_TXD1__FEC_TDATA_1 0x80000000
+ MX53_PAD_FEC_TXD0__FEC_TDATA_0 0x80000000
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX53_PAD_KEY_ROW3__I2C2_SDA 0xc0000000
+ MX53_PAD_KEY_COL3__I2C2_SCL 0xc0000000
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX53_PAD_GPIO_6__I2C3_SDA 0xc0000000
+ MX53_PAD_GPIO_5__I2C3_SCL 0xc0000000
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX53_PAD_PATA_DIOW__UART1_TXD_MUX 0x1e4
+ MX53_PAD_PATA_DMACK__UART1_RXD_MUX 0x1e4
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX 0x1e4
+ MX53_PAD_PATA_DMARQ__UART2_TXD_MUX 0x1e4
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX53_PAD_PATA_CS_0__UART3_TXD_MUX 0x1e4
+ MX53_PAD_PATA_CS_1__UART3_RXD_MUX 0x1e4
+ >;
+ };
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ fsl,uart-has-rtscts;
+ status = "disabled";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "disabled";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can1>;
+ status = "disabled";
+};
+
+&can2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can2>;
+ status = "disabled";
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "disabled";
+};
+
+&cspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cspi>;
+ fsl,spi-num-chipselects = <3>;
+ cs-gpios = <&gpio1 18 0>, <&gpio1 19 0>,
+ <&gpio1 21 0>;
+ status = "disabled";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ pmic: mc34708@8 {
+ compatible = "fsl,mc34708";
+ reg = <0x8>;
+ fsl,mc13xxx-uses-rtc;
+ interrupt-parent = <&gpio2>;
+ interrupts = <6 4>; /* PATA_DATA6, active high */
+ };
+
+ sensor1: lm75@48 {
+ compatible = "lm75";
+ reg = <0x48>;
+ };
+
+ eeprom: 24c64@50 {
+ compatible = "at,24c64";
+ pagesize = <32>;
+ reg = <0x50>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ phy-mode = "rmii";
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx53-tx53-x03x.dts b/arch/arm/boot/dts/imx53-tx53-x03x.dts
new file mode 100644
index 000000000..3b73e81dc
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-tx53-x03x.dts
@@ -0,0 +1,324 @@
+/*
+ * Copyright 2013 Lothar WaĂŸmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx53-tx53.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ model = "Ka-Ro electronics TX53 module (LCD)";
+ compatible = "karo,tx53", "fsl,imx53";
+
+ aliases {
+ display = &display;
+ };
+
+ soc {
+ display: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ interface-pix-fmt = "rgb24";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rgb24_vga1>;
+ status = "okay";
+
+ port {
+ display0_in: endpoint {
+ remote-endpoint = <&ipu_di0_disp0>;
+ };
+ };
+
+ display-timings {
+ VGA {
+ clock-frequency = <25200000>;
+ hactive = <640>;
+ vactive = <480>;
+ hback-porch = <48>;
+ hsync-len = <96>;
+ hfront-porch = <16>;
+ vback-porch = <31>;
+ vsync-len = <2>;
+ vfront-porch = <12>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ETV570 {
+ clock-frequency = <25200000>;
+ hactive = <640>;
+ vactive = <480>;
+ hback-porch = <114>;
+ hsync-len = <30>;
+ hfront-porch = <16>;
+ vback-porch = <32>;
+ vsync-len = <3>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ET0350 {
+ clock-frequency = <6413760>;
+ hactive = <320>;
+ vactive = <240>;
+ hback-porch = <34>;
+ hsync-len = <34>;
+ hfront-porch = <20>;
+ vback-porch = <15>;
+ vsync-len = <3>;
+ vfront-porch = <4>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ET0430 {
+ clock-frequency = <9009000>;
+ hactive = <480>;
+ vactive = <272>;
+ hback-porch = <2>;
+ hsync-len = <41>;
+ hfront-porch = <2>;
+ vback-porch = <2>;
+ vsync-len = <10>;
+ vfront-porch = <2>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+
+ ET0500 {
+ clock-frequency = <33264000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <88>;
+ hsync-len = <128>;
+ hfront-porch = <40>;
+ vback-porch = <33>;
+ vsync-len = <2>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ET0700 { /* same as ET0500 */
+ clock-frequency = <33264000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <88>;
+ hsync-len = <128>;
+ hfront-porch = <40>;
+ vback-porch = <33>;
+ vsync-len = <2>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ETQ570 {
+ clock-frequency = <6596040>;
+ hactive = <320>;
+ vactive = <240>;
+ hback-porch = <38>;
+ hsync-len = <30>;
+ hfront-porch = <30>;
+ vback-porch = <16>;
+ vsync-len = <3>;
+ vfront-porch = <4>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm2 0 500000 PWM_POLARITY_INVERTED>;
+ power-supply = <&reg_3v3>;
+ brightness-levels = <
+ 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 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100
+ >;
+ default-brightness-level = <50>;
+ };
+
+ regulators {
+ reg_lcd_pwr: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "LCD POWER";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 31 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-boot-on;
+ };
+
+ reg_lcd_reset: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ regulator-name = "LCD RESET";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 29 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-boot-on;
+ };
+ };
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ sgtl5000: codec@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ VDDA-supply = <&reg_2v5>;
+ VDDIO-supply = <&reg_3v3>;
+ clocks = <&mclk>;
+ };
+
+ polytouch: edt-ft5x06@38 {
+ compatible = "edt,edt-ft5x06";
+ reg = <0x38>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_edt_ft5x06_1>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <15 0>;
+ reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
+ };
+
+ touchscreen: tsc2007@48 {
+ compatible = "ti,tsc2007";
+ reg = <0x48>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tsc2007>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <26 0>;
+ gpios = <&gpio3 26 GPIO_ACTIVE_LOW>;
+ ti,x-plate-ohms = <660>;
+ linux,wakeup;
+ };
+};
+
+&iomuxc {
+ imx53-tx53-x03x {
+ pinctrl_edt_ft5x06_1: edt-ft5x06grp-1 {
+ fsl,pins = <
+ MX53_PAD_NANDF_CS2__GPIO6_15 0x1f0 /* Interrupt */
+ MX53_PAD_EIM_A16__GPIO2_22 0x04 /* Reset */
+ MX53_PAD_EIM_A17__GPIO2_21 0x04 /* Wake */
+ >;
+ };
+
+ pinctrl_kpp: kppgrp {
+ fsl,pins = <
+ MX53_PAD_GPIO_9__KPP_COL_6 0x1f4
+ MX53_PAD_GPIO_4__KPP_COL_7 0x1f4
+ MX53_PAD_KEY_COL2__KPP_COL_2 0x1f4
+ MX53_PAD_KEY_COL3__KPP_COL_3 0x1f4
+ MX53_PAD_GPIO_2__KPP_ROW_6 0x1f4
+ MX53_PAD_GPIO_5__KPP_ROW_7 0x1f4
+ MX53_PAD_KEY_ROW2__KPP_ROW_2 0x1f4
+ MX53_PAD_KEY_ROW3__KPP_ROW_3 0x1f4
+ >;
+ };
+
+ pinctrl_rgb24_vga1: rgb24-vgagrp1 {
+ fsl,pins = <
+ MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK 0x5
+ MX53_PAD_DI0_PIN15__IPU_DI0_PIN15 0x5
+ MX53_PAD_DI0_PIN2__IPU_DI0_PIN2 0x5
+ MX53_PAD_DI0_PIN3__IPU_DI0_PIN3 0x5
+ MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0 0x5
+ MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1 0x5
+ MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2 0x5
+ MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3 0x5
+ MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4 0x5
+ MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5 0x5
+ MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6 0x5
+ MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7 0x5
+ MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8 0x5
+ MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9 0x5
+ MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10 0x5
+ MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11 0x5
+ MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12 0x5
+ MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13 0x5
+ MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14 0x5
+ MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15 0x5
+ MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16 0x5
+ MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17 0x5
+ MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18 0x5
+ MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19 0x5
+ MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20 0x5
+ MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21 0x5
+ MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22 0x5
+ MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23 0x5
+ >;
+ };
+
+ pinctrl_tsc2007: tsc2007grp {
+ fsl,pins = <
+ MX53_PAD_EIM_D26__GPIO3_26 0x1f0 /* Interrupt */
+ >;
+ };
+ };
+};
+
+&ipu_di0_disp0 {
+ remote-endpoint = <&display0_in>;
+};
+
+&kpp {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_kpp>;
+ /* sample keymap */
+ /* row/col 0,1 are mapped to KPP row/col 6,7 */
+ linux,keymap = <
+ MATRIX_KEY(6, 6, KEY_POWER)
+ MATRIX_KEY(6, 7, KEY_KP0)
+ MATRIX_KEY(6, 2, KEY_KP1)
+ MATRIX_KEY(6, 3, KEY_KP2)
+ MATRIX_KEY(7, 6, KEY_KP3)
+ MATRIX_KEY(7, 7, KEY_KP4)
+ MATRIX_KEY(7, 2, KEY_KP5)
+ MATRIX_KEY(7, 3, KEY_KP6)
+ MATRIX_KEY(2, 6, KEY_KP7)
+ MATRIX_KEY(2, 7, KEY_KP8)
+ MATRIX_KEY(2, 2, KEY_KP9)
+ >;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx53-tx53-x13x.dts b/arch/arm/boot/dts/imx53-tx53-x13x.dts
new file mode 100644
index 000000000..64804719f
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-tx53-x13x.dts
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2013 Lothar WaĂŸmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx53-tx53.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "Ka-Ro electronics TX53 module (LVDS)";
+ compatible = "karo,tx53", "fsl,imx53";
+
+ aliases {
+ display = &lvds0;
+ lvds0 = &lvds0;
+ lvds1 = &lvds1;
+ };
+
+ backlight0: backlight0 {
+ compatible = "pwm-backlight";
+ pwms = <&pwm2 0 500000 0>;
+ power-supply = <&reg_3v3>;
+ brightness-levels = <
+ 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 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100
+ >;
+ default-brightness-level = <50>;
+ };
+
+ backlight1: backlight1 {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 500000 0>;
+ power-supply = <&reg_3v3>;
+ brightness-levels = <
+ 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 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100
+ >;
+ default-brightness-level = <50>;
+ };
+
+ regulators {
+ reg_lcd_pwr0: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "LVDS0 POWER";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 29 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-boot-on;
+ };
+
+ reg_lcd_pwr1: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ regulator-name = "LVDS1 POWER";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 31 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-boot-on;
+ };
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ touchscreen2: eeti@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_eeti2>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <23 0>;
+ wakeup-gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
+ linux,wakeup;
+ };
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ sgtl5000: codec@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ VDDA-supply = <&reg_2v5>;
+ VDDIO-supply = <&reg_3v3>;
+ clocks = <&mclk>;
+ };
+
+ touchscreen1: eeti@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_eeti1>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <22 0>;
+ wakeup-gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+ linux,wakeup;
+ };
+};
+
+&iomuxc {
+ imx53-tx53-x13x {
+ pinctrl_i2c2: i2c2-grp1 {
+ fsl,pins = <
+ MX53_PAD_KEY_ROW3__I2C2_SDA 0xc0000000
+ MX53_PAD_KEY_COL3__I2C2_SCL 0xc0000000
+ >;
+ };
+
+ pinctrl_lvds0: lvds0grp {
+ fsl,pins = <
+ MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 0x80000000
+ MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK 0x80000000
+ MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 0x80000000
+ MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 0x80000000
+ MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 0x80000000
+ >;
+ };
+
+ pinctrl_lvds1: lvds1grp {
+ fsl,pins = <
+ MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 0x80000000
+ MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 0x80000000
+ MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK 0x80000000
+ MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 0x80000000
+ MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 0x80000000
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <MX53_PAD_GPIO_9__PWM1_PWMO 0x04>;
+ };
+
+ pinctrl_eeti1: eeti1grp {
+ fsl,pins = <
+ MX53_PAD_EIM_D22__GPIO3_22 0x1f0 /* Interrupt */
+ >;
+ };
+
+ pinctrl_eeti2: eeti2grp {
+ fsl,pins = <
+ MX53_PAD_EIM_D23__GPIO3_23 0x1f0 /* Interrupt */
+ >;
+ };
+ };
+};
+
+&ldb {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds0 &pinctrl_lvds1>;
+ status = "okay";
+
+ lvds0: lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&lvds_timing0>;
+ lvds_timing0: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hsync-len = <60>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vsync-len = <10>;
+ vfront-porch = <7>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+
+ lvds1: lvds-channel@1 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&lvds_timing1>;
+ lvds_timing1: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hsync-len = <60>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vsync-len = <10>;
+ vfront-porch = <7>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx53-tx53.dtsi b/arch/arm/boot/dts/imx53-tx53.dtsi
new file mode 100644
index 000000000..db4ce991d
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-tx53.dtsi
@@ -0,0 +1,549 @@
+/*
+ * Copyright 2012 <LW@KARO-electronics.de>
+ * based on imx53-qsb.dts
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include "imx53.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Ka-Ro electronics TX53 module";
+ compatible = "karo,tx53", "fsl,imx53";
+
+ aliases {
+ can0 = &can2; /* Make the can interface indices consistent with TX28/TX48 modules */
+ can1 = &can1;
+ ipu = &ipu;
+ reg_can_xcvr = &reg_can_xcvr;
+ usbh1 = &usbh1;
+ usbotg = &usbotg;
+ };
+
+ clocks {
+ ckih1 {
+ clock-frequency = <0>;
+ };
+
+ mclk: clock@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ #clock-cells = <0>;
+ clock-frequency = <27000000>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_key>;
+
+ power {
+ label = "Power Button";
+ gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>;
+ linux,code = <116>; /* KEY_POWER */
+ gpio-key,wakeup;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_stk5led>;
+
+ user {
+ label = "Heartbeat";
+ gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_2v5: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "2V5";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ };
+
+ reg_3v3: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_can_xcvr: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "CAN XCVR";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can_xcvr>;
+ gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_usbh1_vbus: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "usbh1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1_vbus>;
+ gpio = <&gpio3 31 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usbotg_vbus: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "usbotg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg_vbus>;
+ gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ sound {
+ compatible = "karo,tx53-audio-sgtl5000", "fsl,imx-audio-sgtl5000";
+ model = "tx53-audio-sgtl5000";
+ ssi-controller = <&ssi1>;
+ audio-codec = <&sgtl5000>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ /* '1' based port numbers according to datasheet names */
+ mux-int-port = <1>;
+ mux-ext-port = <5>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssi1>;
+ status = "okay";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can1>;
+ xceiver-supply = <&reg_can_xcvr>;
+ status = "okay";
+};
+
+&can2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can2>;
+ xceiver-supply = <&reg_can_xcvr>;
+ status = "okay";
+};
+
+&ecspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ fsl,spi-num-chipselects = <2>;
+ status = "okay";
+
+ cs-gpios = <
+ &gpio2 30 GPIO_ACTIVE_HIGH
+ &gpio3 19 GPIO_ACTIVE_HIGH
+ >;
+
+ spidev0: spi@0 {
+ compatible = "spidev";
+ reg = <0>;
+ spi-max-frequency = <54000000>;
+ };
+
+ spidev1: spi@1 {
+ compatible = "spidev";
+ reg = <1>;
+ spi-max-frequency = <54000000>;
+ };
+};
+
+&esdhc1 {
+ cd-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>;
+ fsl,wp-controller;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ status = "okay";
+};
+
+&esdhc2 {
+ cd-gpios = <&gpio3 25 GPIO_ACTIVE_HIGH>;
+ fsl,wp-controller;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc2>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ phy-mode = "rmii";
+ phy-reset-gpios = <&gpio7 6 GPIO_ACTIVE_HIGH>;
+ phy-handle = <&phy0>;
+ mac-address = [000000000000]; /* placeholder; will be overwritten by bootloader */
+ status = "okay";
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&gpio2>;
+ interrupts = <4>;
+ device_type = "ethernet-phy";
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ rtc1: ds1339@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ds1339>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <20 0>;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx53-tx53 {
+ pinctrl_hog: hoggrp {
+ /* pins not in use by any device on the Starterkit board series */
+ fsl,pins = <
+ /* CMOS Sensor Interface */
+ MX53_PAD_CSI0_DAT12__GPIO5_30 0x1f4
+ MX53_PAD_CSI0_DAT13__GPIO5_31 0x1f4
+ MX53_PAD_CSI0_DAT14__GPIO6_0 0x1f4
+ MX53_PAD_CSI0_DAT15__GPIO6_1 0x1f4
+ MX53_PAD_CSI0_DAT16__GPIO6_2 0x1f4
+ MX53_PAD_CSI0_DAT17__GPIO6_3 0x1f4
+ MX53_PAD_CSI0_DAT18__GPIO6_4 0x1f4
+ MX53_PAD_CSI0_DAT19__GPIO6_5 0x1f4
+ MX53_PAD_CSI0_MCLK__GPIO5_19 0x1f4
+ MX53_PAD_CSI0_VSYNC__GPIO5_21 0x1f4
+ MX53_PAD_CSI0_PIXCLK__GPIO5_18 0x1f4
+ MX53_PAD_GPIO_0__GPIO1_0 0x1f4
+ /* Module Specific Signal */
+ /* MX53_PAD_NANDF_CS2__GPIO6_15 0x1f4 maybe used by EDT-FT5x06 */
+ /* MX53_PAD_EIM_A16__GPIO2_22 0x1f4 maybe used by EDT-FT5x06 */
+ MX53_PAD_EIM_D29__GPIO3_29 0x1f4
+ MX53_PAD_EIM_EB3__GPIO2_31 0x1f4
+ /* MX53_PAD_EIM_A17__GPIO2_21 0x1f4 maybe used by EDT-FT5x06 */
+ /* MX53_PAD_EIM_A18__GPIO2_20 0x1f4 used by LED */
+ MX53_PAD_EIM_A19__GPIO2_19 0x1f4
+ MX53_PAD_EIM_A20__GPIO2_18 0x1f4
+ MX53_PAD_EIM_A21__GPIO2_17 0x1f4
+ MX53_PAD_EIM_A22__GPIO2_16 0x1f4
+ MX53_PAD_EIM_A23__GPIO6_6 0x1f4
+ MX53_PAD_EIM_A24__GPIO5_4 0x1f4
+ MX53_PAD_CSI0_DAT8__GPIO5_26 0x1f4
+ MX53_PAD_CSI0_DAT9__GPIO5_27 0x1f4
+ MX53_PAD_CSI0_DAT10__GPIO5_28 0x1f4
+ MX53_PAD_CSI0_DAT11__GPIO5_29 0x1f4
+ /* MX53_PAD_EIM_D22__GPIO3_22 0x1f4 maybe used by EETI touchpanel driver */
+ /* MX53_PAD_EIM_D23__GPIO3_23 0x1f4 maybe used by EETI touchpanel driver */
+ MX53_PAD_GPIO_13__GPIO4_3 0x1f4
+ MX53_PAD_EIM_CS0__GPIO2_23 0x1f4
+ MX53_PAD_EIM_CS1__GPIO2_24 0x1f4
+ MX53_PAD_CSI0_DATA_EN__GPIO5_20 0x1f4
+ MX53_PAD_EIM_WAIT__GPIO5_0 0x1f4
+ MX53_PAD_EIM_EB0__GPIO2_28 0x1f4
+ MX53_PAD_EIM_EB1__GPIO2_29 0x1f4
+ MX53_PAD_EIM_OE__GPIO2_25 0x1f4
+ MX53_PAD_EIM_LBA__GPIO2_27 0x1f4
+ MX53_PAD_EIM_RW__GPIO2_26 0x1f4
+ MX53_PAD_EIM_DA8__GPIO3_8 0x1f4
+ MX53_PAD_EIM_DA9__GPIO3_9 0x1f4
+ MX53_PAD_EIM_DA10__GPIO3_10 0x1f4
+ MX53_PAD_EIM_DA11__GPIO3_11 0x1f4
+ MX53_PAD_EIM_DA12__GPIO3_12 0x1f4
+ MX53_PAD_EIM_DA13__GPIO3_13 0x1f4
+ MX53_PAD_EIM_DA14__GPIO3_14 0x1f4
+ MX53_PAD_EIM_DA15__GPIO3_15 0x1f4
+ >;
+ };
+
+ pinctrl_can1: can1grp {
+ fsl,pins = <
+ MX53_PAD_GPIO_7__CAN1_TXCAN 0x80000000
+ MX53_PAD_GPIO_8__CAN1_RXCAN 0x80000000
+ >;
+ };
+
+ pinctrl_can2: can2grp {
+ fsl,pins = <
+ MX53_PAD_KEY_COL4__CAN2_TXCAN 0x80000000
+ MX53_PAD_KEY_ROW4__CAN2_RXCAN 0x80000000
+ >;
+ };
+
+ pinctrl_can_xcvr: can-xcvrgrp {
+ fsl,pins = <MX53_PAD_DISP0_DAT0__GPIO4_21 0xe0>; /* Flexcan XCVR enable */
+ };
+
+ pinctrl_ds1339: ds1339grp {
+ fsl,pins = <MX53_PAD_DI0_PIN4__GPIO4_20 0xe0>;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX53_PAD_GPIO_19__ECSPI1_RDY 0x80000000
+ MX53_PAD_EIM_EB2__ECSPI1_SS0 0x80000000
+ MX53_PAD_EIM_D16__ECSPI1_SCLK 0x80000000
+ MX53_PAD_EIM_D17__ECSPI1_MISO 0x80000000
+ MX53_PAD_EIM_D18__ECSPI1_MOSI 0x80000000
+ MX53_PAD_EIM_D19__ECSPI1_SS1 0x80000000
+ >;
+ };
+
+ pinctrl_esdhc1: esdhc1grp {
+ fsl,pins = <
+ MX53_PAD_SD1_DATA0__ESDHC1_DAT0 0x1d5
+ MX53_PAD_SD1_DATA1__ESDHC1_DAT1 0x1d5
+ MX53_PAD_SD1_DATA2__ESDHC1_DAT2 0x1d5
+ MX53_PAD_SD1_DATA3__ESDHC1_DAT3 0x1d5
+ MX53_PAD_SD1_CMD__ESDHC1_CMD 0x1d5
+ MX53_PAD_SD1_CLK__ESDHC1_CLK 0x1d5
+ MX53_PAD_EIM_D24__GPIO3_24 0x1f0
+ >;
+ };
+
+ pinctrl_esdhc2: esdhc2grp {
+ fsl,pins = <
+ MX53_PAD_SD2_CMD__ESDHC2_CMD 0x1d5
+ MX53_PAD_SD2_CLK__ESDHC2_CLK 0x1d5
+ MX53_PAD_SD2_DATA0__ESDHC2_DAT0 0x1d5
+ MX53_PAD_SD2_DATA1__ESDHC2_DAT1 0x1d5
+ MX53_PAD_SD2_DATA2__ESDHC2_DAT2 0x1d5
+ MX53_PAD_SD2_DATA3__ESDHC2_DAT3 0x1d5
+ MX53_PAD_EIM_D25__GPIO3_25 0x1f0
+ >;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX53_PAD_FEC_MDC__FEC_MDC 0x80000000
+ MX53_PAD_FEC_MDIO__FEC_MDIO 0x80000000
+ MX53_PAD_FEC_REF_CLK__FEC_TX_CLK 0x80000000
+ MX53_PAD_FEC_RX_ER__FEC_RX_ER 0x80000000
+ MX53_PAD_FEC_CRS_DV__FEC_RX_DV 0x80000000
+ MX53_PAD_FEC_RXD1__FEC_RDATA_1 0x80000000
+ MX53_PAD_FEC_RXD0__FEC_RDATA_0 0x80000000
+ MX53_PAD_FEC_TX_EN__FEC_TX_EN 0x80000000
+ MX53_PAD_FEC_TXD1__FEC_TDATA_1 0x80000000
+ MX53_PAD_FEC_TXD0__FEC_TDATA_0 0x80000000
+ >;
+ };
+
+ pinctrl_gpio_key: gpio-keygrp {
+ fsl,pins = <MX53_PAD_EIM_A25__GPIO5_2 0x1f4>;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX53_PAD_EIM_D21__I2C1_SCL 0xc0000000
+ MX53_PAD_EIM_D28__I2C1_SDA 0xc0000000
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX53_PAD_GPIO_3__I2C3_SCL 0xc0000000
+ MX53_PAD_GPIO_6__I2C3_SDA 0xc0000000
+ >;
+ };
+
+ pinctrl_nand: nandgrp {
+ fsl,pins = <
+ MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B 0x4
+ MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B 0x4
+ MX53_PAD_NANDF_CLE__EMI_NANDF_CLE 0x4
+ MX53_PAD_NANDF_ALE__EMI_NANDF_ALE 0x4
+ MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B 0xe0
+ MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0 0xe0
+ MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0 0x4
+ MX53_PAD_EIM_DA0__EMI_NAND_WEIM_DA_0 0xa4
+ MX53_PAD_EIM_DA1__EMI_NAND_WEIM_DA_1 0xa4
+ MX53_PAD_EIM_DA2__EMI_NAND_WEIM_DA_2 0xa4
+ MX53_PAD_EIM_DA3__EMI_NAND_WEIM_DA_3 0xa4
+ MX53_PAD_EIM_DA4__EMI_NAND_WEIM_DA_4 0xa4
+ MX53_PAD_EIM_DA5__EMI_NAND_WEIM_DA_5 0xa4
+ MX53_PAD_EIM_DA6__EMI_NAND_WEIM_DA_6 0xa4
+ MX53_PAD_EIM_DA7__EMI_NAND_WEIM_DA_7 0xa4
+ >;
+ };
+
+ pinctrl_pwm2: pwm2grp {
+ fsl,pins = <
+ MX53_PAD_GPIO_1__PWM2_PWMO 0x80000000
+ >;
+ };
+
+ pinctrl_ssi1: ssi1grp {
+ fsl,pins = <
+ MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC 0x80000000
+ MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD 0x80000000
+ MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS 0x80000000
+ MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD 0x80000000
+ >;
+ };
+
+ pinctrl_ssi2: ssi2grp {
+ fsl,pins = <
+ MX53_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC 0x80000000
+ MX53_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD 0x80000000
+ MX53_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS 0x80000000
+ MX53_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD 0x80000000
+ MX53_PAD_EIM_D27__GPIO3_27 0x1f0
+ >;
+ };
+
+ pinctrl_stk5led: stk5ledgrp {
+ fsl,pins = <MX53_PAD_EIM_A18__GPIO2_20 0xc0>;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX53_PAD_PATA_DIOW__UART1_TXD_MUX 0x1e4
+ MX53_PAD_PATA_DMACK__UART1_RXD_MUX 0x1e4
+ MX53_PAD_PATA_RESET_B__UART1_CTS 0x1c5
+ MX53_PAD_PATA_IORDY__UART1_RTS 0x1c5
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX 0x1c5
+ MX53_PAD_PATA_DMARQ__UART2_TXD_MUX 0x1c5
+ MX53_PAD_PATA_DIOR__UART2_RTS 0x1c5
+ MX53_PAD_PATA_INTRQ__UART2_CTS 0x1c5
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX53_PAD_PATA_CS_0__UART3_TXD_MUX 0x1e4
+ MX53_PAD_PATA_CS_1__UART3_RXD_MUX 0x1e4
+ MX53_PAD_PATA_DA_1__UART3_CTS 0x1e4
+ MX53_PAD_PATA_DA_2__UART3_RTS 0x1e4
+ >;
+ };
+
+ pinctrl_usbh1: usbh1grp {
+ fsl,pins = <
+ MX53_PAD_EIM_D30__GPIO3_30 0x100 /* OC */
+ >;
+ };
+
+ pinctrl_usbh1_vbus: usbh1-vbusgrp {
+ fsl,pins = <
+ MX53_PAD_EIM_D31__GPIO3_31 0xe0 /* VBUS ENABLE */
+ >;
+ };
+
+ pinctrl_usbotg_vbus: usbotg-vbusgrp {
+ fsl,pins = <
+ MX53_PAD_GPIO_7__GPIO1_7 0xe0 /* VBUS ENABLE */
+ MX53_PAD_GPIO_8__GPIO1_8 0x100 /* OC */
+ >;
+ };
+ };
+};
+
+&ipu {
+ status = "okay";
+};
+
+&nfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ nand-on-flash-bbt;
+ status = "okay";
+};
+
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm2>;
+ #pwm-cells = <3>;
+};
+
+&sdma {
+ fsl,sdma-ram-script-name = "/*(DEBLOBBED)*/";
+};
+
+&ssi1 {
+ codec-handle = <&sgtl5000>;
+ status = "okay";
+};
+
+&ssi2 {
+ status = "disabled";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&usbh1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1>;
+ phy_type = "utmi";
+ disable-over-current;
+ vbus-supply = <&reg_usbh1_vbus>;
+ status = "okay";
+};
+
+&usbotg {
+ phy_type = "utmi";
+ dr_mode = "peripheral";
+ disable-over-current;
+ vbus-supply = <&reg_usbotg_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx53-voipac-bsb.dts b/arch/arm/boot/dts/imx53-voipac-bsb.dts
new file mode 100644
index 000000000..c17d3ad6d
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-voipac-bsb.dts
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2013 Rostislav Lisovy <lisovy@gmail.com>, PiKRON s.r.o.
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx53-voipac-dmm-668.dtsi"
+
+/ {
+ sound {
+ compatible = "fsl,imx53-voipac-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx53-voipac-sgtl5000";
+ ssi-controller = <&ssi2>;
+ audio-codec = <&sgtl5000>;
+ audio-routing =
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <2>;
+ mux-ext-port = <5>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pin_gpio>;
+
+ led1 {
+ label = "led-red";
+ gpios = <&gpio3 29 0>;
+ default-state = "off";
+ };
+
+ led2 {
+ label = "led-orange";
+ gpios = <&gpio2 31 0>;
+ default-state = "off";
+ };
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx53-voipac {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ /* SD2_CD */
+ MX53_PAD_EIM_D25__GPIO3_25 0x80000000
+ /* SD2_WP */
+ MX53_PAD_EIM_A19__GPIO2_19 0x80000000
+ >;
+ };
+
+ led_pin_gpio: led_gpio {
+ fsl,pins = <
+ MX53_PAD_EIM_D29__GPIO3_29 0x80000000
+ MX53_PAD_EIM_EB3__GPIO2_31 0x80000000
+ >;
+ };
+
+ /* Keyboard controller */
+ pinctrl_kpp_1: kppgrp-1 {
+ fsl,pins = <
+ MX53_PAD_GPIO_9__KPP_COL_6 0xe8
+ MX53_PAD_GPIO_4__KPP_COL_7 0xe8
+ MX53_PAD_KEY_COL2__KPP_COL_2 0xe8
+ MX53_PAD_KEY_COL3__KPP_COL_3 0xe8
+ MX53_PAD_KEY_COL4__KPP_COL_4 0xe8
+ MX53_PAD_GPIO_2__KPP_ROW_6 0xe0
+ MX53_PAD_GPIO_5__KPP_ROW_7 0xe0
+ MX53_PAD_KEY_ROW2__KPP_ROW_2 0xe0
+ MX53_PAD_KEY_ROW3__KPP_ROW_3 0xe0
+ MX53_PAD_KEY_ROW4__KPP_ROW_4 0xe0
+ >;
+ };
+
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC 0x80000000
+ MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD 0x80000000
+ MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS 0x80000000
+ MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD 0x80000000
+ >;
+ };
+
+ pinctrl_esdhc2: esdhc2grp {
+ fsl,pins = <
+ MX53_PAD_SD2_CMD__ESDHC2_CMD 0x1d5
+ MX53_PAD_SD2_CLK__ESDHC2_CLK 0x1d5
+ MX53_PAD_SD2_DATA0__ESDHC2_DAT0 0x1d5
+ MX53_PAD_SD2_DATA1__ESDHC2_DAT1 0x1d5
+ MX53_PAD_SD2_DATA2__ESDHC2_DAT2 0x1d5
+ MX53_PAD_SD2_DATA3__ESDHC2_DAT3 0x1d5
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX53_PAD_GPIO_3__I2C3_SCL 0xc0000000
+ MX53_PAD_GPIO_6__I2C3_SDA 0xc0000000
+ >;
+ };
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>; /* SSI1 */
+ status = "okay";
+};
+
+&esdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc2>;
+ cd-gpios = <&gpio3 25 0>;
+ wp-gpios = <&gpio2 19 0>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ sgtl5000: codec@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ VDDA-supply = <&reg_3p3v>;
+ VDDIO-supply = <&reg_3p3v>;
+ clocks = <&clks 150>;
+ };
+};
+
+&kpp {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_kpp_1>;
+ linux,keymap = <
+ 0x0203003b /* KEY_F1 */
+ 0x0603003c /* KEY_F2 */
+ 0x0207003d /* KEY_F3 */
+ 0x0607003e /* KEY_F4 */
+ >;
+ keypad,num-rows = <8>;
+ keypad,num-columns = <1>;
+ status = "okay";
+};
+
+&ssi2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi b/arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi
new file mode 100644
index 000000000..ba689fbd0
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2013 Rostislav Lisovy <lisovy@gmail.com>, PiKRON s.r.o.
+ *
+ * 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 "imx53.dtsi"
+
+/ {
+ model = "Voipac i.MX53 X53-DMM-668";
+ compatible = "voipac,imx53-dmm-668", "fsl,imx53";
+
+ memory@70000000 {
+ device_type = "memory";
+ reg = <0x70000000 0x20000000>;
+ };
+
+ memory@b0000000 {
+ device_type = "memory";
+ reg = <0xb0000000 0x20000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_usb_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 31 0>; /* PEN */
+ enable-active-high;
+ };
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx53-voipac {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ /* Make DA9053 regulator functional */
+ MX53_PAD_GPIO_16__GPIO7_11 0x80000000
+ /* FEC Power enable */
+ MX53_PAD_GPIO_11__GPIO4_1 0x80000000
+ /* FEC RST */
+ MX53_PAD_GPIO_12__GPIO4_2 0x80000000
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX53_PAD_EIM_D16__ECSPI1_SCLK 0x80000000
+ MX53_PAD_EIM_D17__ECSPI1_MISO 0x80000000
+ MX53_PAD_EIM_D18__ECSPI1_MOSI 0x80000000
+ >;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX53_PAD_FEC_MDC__FEC_MDC 0x80000000
+ MX53_PAD_FEC_MDIO__FEC_MDIO 0x80000000
+ MX53_PAD_FEC_REF_CLK__FEC_TX_CLK 0x80000000
+ MX53_PAD_FEC_RX_ER__FEC_RX_ER 0x80000000
+ MX53_PAD_FEC_CRS_DV__FEC_RX_DV 0x80000000
+ MX53_PAD_FEC_RXD1__FEC_RDATA_1 0x80000000
+ MX53_PAD_FEC_RXD0__FEC_RDATA_0 0x80000000
+ MX53_PAD_FEC_TX_EN__FEC_TX_EN 0x80000000
+ MX53_PAD_FEC_TXD1__FEC_TDATA_1 0x80000000
+ MX53_PAD_FEC_TXD0__FEC_TDATA_0 0x80000000
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX53_PAD_EIM_D21__I2C1_SCL 0xc0000000
+ MX53_PAD_EIM_D28__I2C1_SDA 0xc0000000
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX53_PAD_PATA_DIOW__UART1_TXD_MUX 0x1e4
+ MX53_PAD_PATA_DMACK__UART1_RXD_MUX 0x1e4
+ >;
+ };
+
+ pinctrl_nand: nandgrp {
+ fsl,pins = <
+ MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B 0x4
+ MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B 0x4
+ MX53_PAD_NANDF_CLE__EMI_NANDF_CLE 0x4
+ MX53_PAD_NANDF_ALE__EMI_NANDF_ALE 0x4
+ MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B 0xe0
+ MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0 0xe0
+ MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0 0x4
+ MX53_PAD_PATA_DATA0__EMI_NANDF_D_0 0xa4
+ MX53_PAD_PATA_DATA1__EMI_NANDF_D_1 0xa4
+ MX53_PAD_PATA_DATA2__EMI_NANDF_D_2 0xa4
+ MX53_PAD_PATA_DATA3__EMI_NANDF_D_3 0xa4
+ MX53_PAD_PATA_DATA4__EMI_NANDF_D_4 0xa4
+ MX53_PAD_PATA_DATA5__EMI_NANDF_D_5 0xa4
+ MX53_PAD_PATA_DATA6__EMI_NANDF_D_6 0xa4
+ MX53_PAD_PATA_DATA7__EMI_NANDF_D_7 0xa4
+ >;
+ };
+ };
+};
+
+&ecspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ fsl,spi-num-chipselects = <4>;
+ cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>, <&gpio2 16 0>, <&gpio2 17 0>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ phy-mode = "rmii";
+ phy-reset-gpios = <&gpio4 2 0>;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: dialog@48 {
+ compatible = "dlg,da9053-aa", "dlg,da9052";
+ reg = <0x48>;
+ interrupt-parent = <&gpio7>;
+ interrupts = <11 0x8>; /* low-level active IRQ at GPIO7_11 */
+
+ regulators {
+ buck1_reg: buck1 {
+ regulator-name = "BUCKCORE";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ };
+
+ buck2_reg: buck2 {
+ regulator-name = "BUCKPRO";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+
+ buck3_reg: buck3 {
+ regulator-name = "BUCKMEM";
+ regulator-min-microvolt = <1420000>;
+ regulator-max-microvolt = <1580000>;
+ regulator-always-on;
+ };
+
+ buck4_reg: buck4 {
+ regulator-name = "BUCKPERI";
+ regulator-min-microvolt = <2370000>;
+ regulator-max-microvolt = <2630000>;
+ regulator-always-on;
+ };
+
+ ldo1_reg: ldo1 {
+ regulator-name = "ldo1_1v3";
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo2_reg: ldo2 {
+ regulator-name = "ldo2_1v3";
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+
+ ldo3_reg: ldo3 {
+ regulator-name = "ldo3_3v3";
+ regulator-min-microvolt = <3250000>;
+ regulator-max-microvolt = <3350000>;
+ regulator-always-on;
+ };
+
+ ldo4_reg: ldo4 {
+ regulator-name = "ldo4_2v775";
+ regulator-min-microvolt = <2770000>;
+ regulator-max-microvolt = <2780000>;
+ regulator-always-on;
+ };
+
+ ldo5_reg: ldo5 {
+ regulator-name = "ldo5_3v3";
+ regulator-min-microvolt = <3250000>;
+ regulator-max-microvolt = <3350000>;
+ regulator-always-on;
+ };
+
+ ldo6_reg: ldo6 {
+ regulator-name = "ldo6_1v3";
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+
+ ldo7_reg: ldo7 {
+ regulator-name = "ldo7_2v75";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo8_reg: ldo8 {
+ regulator-name = "ldo8_1v8";
+ regulator-min-microvolt = <1750000>;
+ regulator-max-microvolt = <1850000>;
+ regulator-always-on;
+ };
+
+ ldo9_reg: ldo9 {
+ regulator-name = "ldo9_1v5";
+ regulator-min-microvolt = <1450000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ ldo10_reg: ldo10 {
+ regulator-name = "ldo10_1v3";
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&nfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_vbus>;
+ phy_type = "utmi";
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
new file mode 100644
index 000000000..73a99cb8d
--- /dev/null
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -0,0 +1,793 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 "skeleton.dtsi"
+#include "imx53-pinfunc.h"
+#include <dt-bindings/clock/imx5-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ aliases {
+ ethernet0 = &fec;
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ gpio4 = &gpio5;
+ gpio5 = &gpio6;
+ gpio6 = &gpio7;
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ i2c2 = &i2c3;
+ mmc0 = &esdhc1;
+ mmc1 = &esdhc2;
+ mmc2 = &esdhc3;
+ mmc3 = &esdhc4;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ spi0 = &ecspi1;
+ spi1 = &ecspi2;
+ spi2 = &cspi;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a8";
+ reg = <0x0>;
+ clocks = <&clks IMX5_CLK_ARM>;
+ clock-latency = <61036>;
+ voltage-tolerance = <5>;
+ operating-points = <
+ /* kHz */
+ 166666 850000
+ 400000 900000
+ 800000 1050000
+ 1000000 1200000
+ 1200000 1300000
+ >;
+ };
+ };
+
+ display-subsystem {
+ compatible = "fsl,imx-display-subsystem";
+ ports = <&ipu_di0>, <&ipu_di1>;
+ };
+
+ tzic: tz-interrupt-controller@0fffc000 {
+ compatible = "fsl,imx53-tzic", "fsl,tzic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x0fffc000 0x4000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ckil {
+ compatible = "fsl,imx-ckil", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+
+ ckih1 {
+ compatible = "fsl,imx-ckih1", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <22579200>;
+ };
+
+ ckih2 {
+ compatible = "fsl,imx-ckih2", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ osc {
+ compatible = "fsl,imx-osc", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&tzic>;
+ ranges;
+
+ sata: sata@10000000 {
+ compatible = "fsl,imx53-ahci";
+ reg = <0x10000000 0x1000>;
+ interrupts = <28>;
+ clocks = <&clks IMX5_CLK_SATA_GATE>,
+ <&clks IMX5_CLK_SATA_REF>,
+ <&clks IMX5_CLK_AHB>;
+ clock-names = "sata", "sata_ref", "ahb";
+ status = "disabled";
+ };
+
+ ipu: ipu@18000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-ipu";
+ reg = <0x18000000 0x08000000>;
+ interrupts = <11 10>;
+ clocks = <&clks IMX5_CLK_IPU_GATE>,
+ <&clks IMX5_CLK_IPU_DI0_GATE>,
+ <&clks IMX5_CLK_IPU_DI1_GATE>;
+ clock-names = "bus", "di0", "di1";
+ resets = <&src 2>;
+
+ ipu_di0: port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ ipu_di0_disp0: endpoint@0 {
+ reg = <0>;
+ };
+
+ ipu_di0_lvds0: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&lvds0_in>;
+ };
+ };
+
+ ipu_di1: port@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ ipu_di1_disp1: endpoint@0 {
+ reg = <0>;
+ };
+
+ ipu_di1_lvds1: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&lvds1_in>;
+ };
+
+ ipu_di1_tve: endpoint@2 {
+ reg = <2>;
+ remote-endpoint = <&tve_in>;
+ };
+ };
+ };
+
+ aips@50000000 { /* AIPS1 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x50000000 0x10000000>;
+ ranges;
+
+ spba@50000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x50000000 0x40000>;
+ ranges;
+
+ esdhc1: esdhc@50004000 {
+ compatible = "fsl,imx53-esdhc";
+ reg = <0x50004000 0x4000>;
+ interrupts = <1>;
+ clocks = <&clks IMX5_CLK_ESDHC1_IPG_GATE>,
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC1_PER_GATE>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ esdhc2: esdhc@50008000 {
+ compatible = "fsl,imx53-esdhc";
+ reg = <0x50008000 0x4000>;
+ interrupts = <2>;
+ clocks = <&clks IMX5_CLK_ESDHC2_IPG_GATE>,
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC2_PER_GATE>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ uart3: serial@5000c000 {
+ compatible = "fsl,imx53-uart", "fsl,imx21-uart";
+ reg = <0x5000c000 0x4000>;
+ interrupts = <33>;
+ clocks = <&clks IMX5_CLK_UART3_IPG_GATE>,
+ <&clks IMX5_CLK_UART3_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi1: ecspi@50010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
+ reg = <0x50010000 0x4000>;
+ interrupts = <36>;
+ clocks = <&clks IMX5_CLK_ECSPI1_IPG_GATE>,
+ <&clks IMX5_CLK_ECSPI1_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ssi2: ssi@50014000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx53-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
+ reg = <0x50014000 0x4000>;
+ interrupts = <30>;
+ clocks = <&clks IMX5_CLK_SSI2_IPG_GATE>,
+ <&clks IMX5_CLK_SSI2_ROOT_GATE>;
+ clock-names = "ipg", "baud";
+ dmas = <&sdma 24 1 0>,
+ <&sdma 25 1 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ esdhc3: esdhc@50020000 {
+ compatible = "fsl,imx53-esdhc";
+ reg = <0x50020000 0x4000>;
+ interrupts = <3>;
+ clocks = <&clks IMX5_CLK_ESDHC3_IPG_GATE>,
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC3_PER_GATE>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ esdhc4: esdhc@50024000 {
+ compatible = "fsl,imx53-esdhc";
+ reg = <0x50024000 0x4000>;
+ interrupts = <4>;
+ clocks = <&clks IMX5_CLK_ESDHC4_IPG_GATE>,
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC4_PER_GATE>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+ };
+
+ aipstz1: bridge@53f00000 {
+ compatible = "fsl,imx53-aipstz";
+ reg = <0x53f00000 0x60>;
+ };
+
+ usbphy0: usbphy@0 {
+ compatible = "usb-nop-xceiv";
+ clocks = <&clks IMX5_CLK_USB_PHY1_GATE>;
+ clock-names = "main_clk";
+ status = "okay";
+ };
+
+ usbphy1: usbphy@1 {
+ compatible = "usb-nop-xceiv";
+ clocks = <&clks IMX5_CLK_USB_PHY2_GATE>;
+ clock-names = "main_clk";
+ status = "okay";
+ };
+
+ usbotg: usb@53f80000 {
+ compatible = "fsl,imx53-usb", "fsl,imx27-usb";
+ reg = <0x53f80000 0x0200>;
+ interrupts = <18>;
+ clocks = <&clks IMX5_CLK_USBOH3_GATE>;
+ fsl,usbmisc = <&usbmisc 0>;
+ fsl,usbphy = <&usbphy0>;
+ status = "disabled";
+ };
+
+ usbh1: usb@53f80200 {
+ compatible = "fsl,imx53-usb", "fsl,imx27-usb";
+ reg = <0x53f80200 0x0200>;
+ interrupts = <14>;
+ clocks = <&clks IMX5_CLK_USBOH3_GATE>;
+ fsl,usbmisc = <&usbmisc 1>;
+ fsl,usbphy = <&usbphy1>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbh2: usb@53f80400 {
+ compatible = "fsl,imx53-usb", "fsl,imx27-usb";
+ reg = <0x53f80400 0x0200>;
+ interrupts = <16>;
+ clocks = <&clks IMX5_CLK_USBOH3_GATE>;
+ fsl,usbmisc = <&usbmisc 2>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbh3: usb@53f80600 {
+ compatible = "fsl,imx53-usb", "fsl,imx27-usb";
+ reg = <0x53f80600 0x0200>;
+ interrupts = <17>;
+ clocks = <&clks IMX5_CLK_USBOH3_GATE>;
+ fsl,usbmisc = <&usbmisc 3>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbmisc: usbmisc@53f80800 {
+ #index-cells = <1>;
+ compatible = "fsl,imx53-usbmisc";
+ reg = <0x53f80800 0x200>;
+ clocks = <&clks IMX5_CLK_USBOH3_GATE>;
+ };
+
+ gpio1: gpio@53f84000 {
+ compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
+ reg = <0x53f84000 0x4000>;
+ interrupts = <50 51>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@53f88000 {
+ compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
+ reg = <0x53f88000 0x4000>;
+ interrupts = <52 53>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@53f8c000 {
+ compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
+ reg = <0x53f8c000 0x4000>;
+ interrupts = <54 55>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@53f90000 {
+ compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
+ reg = <0x53f90000 0x4000>;
+ interrupts = <56 57>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ kpp: kpp@53f94000 {
+ compatible = "fsl,imx53-kpp", "fsl,imx21-kpp";
+ reg = <0x53f94000 0x4000>;
+ interrupts = <60>;
+ clocks = <&clks IMX5_CLK_DUMMY>;
+ status = "disabled";
+ };
+
+ wdog1: wdog@53f98000 {
+ compatible = "fsl,imx53-wdt", "fsl,imx21-wdt";
+ reg = <0x53f98000 0x4000>;
+ interrupts = <58>;
+ clocks = <&clks IMX5_CLK_DUMMY>;
+ };
+
+ wdog2: wdog@53f9c000 {
+ compatible = "fsl,imx53-wdt", "fsl,imx21-wdt";
+ reg = <0x53f9c000 0x4000>;
+ interrupts = <59>;
+ clocks = <&clks IMX5_CLK_DUMMY>;
+ status = "disabled";
+ };
+
+ gpt: timer@53fa0000 {
+ compatible = "fsl,imx53-gpt", "fsl,imx31-gpt";
+ reg = <0x53fa0000 0x4000>;
+ interrupts = <39>;
+ clocks = <&clks IMX5_CLK_GPT_IPG_GATE>,
+ <&clks IMX5_CLK_GPT_HF_GATE>;
+ clock-names = "ipg", "per";
+ };
+
+ iomuxc: iomuxc@53fa8000 {
+ compatible = "fsl,imx53-iomuxc";
+ reg = <0x53fa8000 0x4000>;
+ };
+
+ gpr: iomuxc-gpr@53fa8000 {
+ compatible = "fsl,imx53-iomuxc-gpr", "syscon";
+ reg = <0x53fa8000 0xc>;
+ };
+
+ ldb: ldb@53fa8008 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-ldb";
+ reg = <0x53fa8008 0x4>;
+ gpr = <&gpr>;
+ clocks = <&clks IMX5_CLK_LDB_DI0_SEL>,
+ <&clks IMX5_CLK_LDB_DI1_SEL>,
+ <&clks IMX5_CLK_IPU_DI0_SEL>,
+ <&clks IMX5_CLK_IPU_DI1_SEL>,
+ <&clks IMX5_CLK_LDB_DI0_GATE>,
+ <&clks IMX5_CLK_LDB_DI1_GATE>;
+ clock-names = "di0_pll", "di1_pll",
+ "di0_sel", "di1_sel",
+ "di0", "di1";
+ status = "disabled";
+
+ lvds-channel@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ lvds0_in: endpoint {
+ remote-endpoint = <&ipu_di0_lvds0>;
+ };
+ };
+ };
+
+ lvds-channel@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ status = "disabled";
+
+ port@1 {
+ reg = <1>;
+
+ lvds1_in: endpoint {
+ remote-endpoint = <&ipu_di1_lvds1>;
+ };
+ };
+ };
+ };
+
+ pwm1: pwm@53fb4000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
+ reg = <0x53fb4000 0x4000>;
+ clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
+ <&clks IMX5_CLK_PWM1_HF_GATE>;
+ clock-names = "ipg", "per";
+ interrupts = <61>;
+ };
+
+ pwm2: pwm@53fb8000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
+ reg = <0x53fb8000 0x4000>;
+ clocks = <&clks IMX5_CLK_PWM2_IPG_GATE>,
+ <&clks IMX5_CLK_PWM2_HF_GATE>;
+ clock-names = "ipg", "per";
+ interrupts = <94>;
+ };
+
+ uart1: serial@53fbc000 {
+ compatible = "fsl,imx53-uart", "fsl,imx21-uart";
+ reg = <0x53fbc000 0x4000>;
+ interrupts = <31>;
+ clocks = <&clks IMX5_CLK_UART1_IPG_GATE>,
+ <&clks IMX5_CLK_UART1_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart2: serial@53fc0000 {
+ compatible = "fsl,imx53-uart", "fsl,imx21-uart";
+ reg = <0x53fc0000 0x4000>;
+ interrupts = <32>;
+ clocks = <&clks IMX5_CLK_UART2_IPG_GATE>,
+ <&clks IMX5_CLK_UART2_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ can1: can@53fc8000 {
+ compatible = "fsl,imx53-flexcan", "fsl,p1010-flexcan";
+ reg = <0x53fc8000 0x4000>;
+ interrupts = <82>;
+ clocks = <&clks IMX5_CLK_CAN1_IPG_GATE>,
+ <&clks IMX5_CLK_CAN1_SERIAL_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ can2: can@53fcc000 {
+ compatible = "fsl,imx53-flexcan", "fsl,p1010-flexcan";
+ reg = <0x53fcc000 0x4000>;
+ interrupts = <83>;
+ clocks = <&clks IMX5_CLK_CAN2_IPG_GATE>,
+ <&clks IMX5_CLK_CAN2_SERIAL_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ src: src@53fd0000 {
+ compatible = "fsl,imx53-src", "fsl,imx51-src";
+ reg = <0x53fd0000 0x4000>;
+ #reset-cells = <1>;
+ };
+
+ clks: ccm@53fd4000{
+ compatible = "fsl,imx53-ccm";
+ reg = <0x53fd4000 0x4000>;
+ interrupts = <0 71 0x04 0 72 0x04>;
+ #clock-cells = <1>;
+ };
+
+ gpio5: gpio@53fdc000 {
+ compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
+ reg = <0x53fdc000 0x4000>;
+ interrupts = <103 104>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio6: gpio@53fe0000 {
+ compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
+ reg = <0x53fe0000 0x4000>;
+ interrupts = <105 106>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio7: gpio@53fe4000 {
+ compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
+ reg = <0x53fe4000 0x4000>;
+ interrupts = <107 108>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ i2c3: i2c@53fec000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-i2c", "fsl,imx21-i2c";
+ reg = <0x53fec000 0x4000>;
+ interrupts = <64>;
+ clocks = <&clks IMX5_CLK_I2C3_GATE>;
+ status = "disabled";
+ };
+
+ uart4: serial@53ff0000 {
+ compatible = "fsl,imx53-uart", "fsl,imx21-uart";
+ reg = <0x53ff0000 0x4000>;
+ interrupts = <13>;
+ clocks = <&clks IMX5_CLK_UART4_IPG_GATE>,
+ <&clks IMX5_CLK_UART4_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+ };
+
+ aips@60000000 { /* AIPS2 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x60000000 0x10000000>;
+ ranges;
+
+ aipstz2: bridge@63f00000 {
+ compatible = "fsl,imx53-aipstz";
+ reg = <0x63f00000 0x60>;
+ };
+
+ iim: iim@63f98000 {
+ compatible = "fsl,imx53-iim", "fsl,imx27-iim";
+ reg = <0x63f98000 0x4000>;
+ interrupts = <69>;
+ clocks = <&clks IMX5_CLK_IIM_GATE>;
+ };
+
+ uart5: serial@63f90000 {
+ compatible = "fsl,imx53-uart", "fsl,imx21-uart";
+ reg = <0x63f90000 0x4000>;
+ interrupts = <86>;
+ clocks = <&clks IMX5_CLK_UART5_IPG_GATE>,
+ <&clks IMX5_CLK_UART5_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ owire: owire@63fa4000 {
+ compatible = "fsl,imx53-owire", "fsl,imx21-owire";
+ reg = <0x63fa4000 0x4000>;
+ clocks = <&clks IMX5_CLK_OWIRE_GATE>;
+ status = "disabled";
+ };
+
+ ecspi2: ecspi@63fac000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
+ reg = <0x63fac000 0x4000>;
+ interrupts = <37>;
+ clocks = <&clks IMX5_CLK_ECSPI2_IPG_GATE>,
+ <&clks IMX5_CLK_ECSPI2_PER_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ sdma: sdma@63fb0000 {
+ compatible = "fsl,imx53-sdma", "fsl,imx35-sdma";
+ reg = <0x63fb0000 0x4000>;
+ interrupts = <6>;
+ clocks = <&clks IMX5_CLK_SDMA_GATE>,
+ <&clks IMX5_CLK_SDMA_GATE>;
+ clock-names = "ipg", "ahb";
+ #dma-cells = <3>;
+ fsl,sdma-ram-script-name = "/*(DEBLOBBED)*/";
+ };
+
+ cspi: cspi@63fc0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-cspi", "fsl,imx35-cspi";
+ reg = <0x63fc0000 0x4000>;
+ interrupts = <38>;
+ clocks = <&clks IMX5_CLK_CSPI_IPG_GATE>,
+ <&clks IMX5_CLK_CSPI_IPG_GATE>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ i2c2: i2c@63fc4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-i2c", "fsl,imx21-i2c";
+ reg = <0x63fc4000 0x4000>;
+ interrupts = <63>;
+ clocks = <&clks IMX5_CLK_I2C2_GATE>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@63fc8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-i2c", "fsl,imx21-i2c";
+ reg = <0x63fc8000 0x4000>;
+ interrupts = <62>;
+ clocks = <&clks IMX5_CLK_I2C1_GATE>;
+ status = "disabled";
+ };
+
+ ssi1: ssi@63fcc000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx53-ssi", "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
+ reg = <0x63fcc000 0x4000>;
+ interrupts = <29>;
+ clocks = <&clks IMX5_CLK_SSI1_IPG_GATE>,
+ <&clks IMX5_CLK_SSI1_ROOT_GATE>;
+ clock-names = "ipg", "baud";
+ dmas = <&sdma 28 0 0>,
+ <&sdma 29 0 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ audmux: audmux@63fd0000 {
+ compatible = "fsl,imx53-audmux", "fsl,imx31-audmux";
+ reg = <0x63fd0000 0x4000>;
+ status = "disabled";
+ };
+
+ nfc: nand@63fdb000 {
+ compatible = "fsl,imx53-nand";
+ reg = <0x63fdb000 0x1000 0xf7ff0000 0x10000>;
+ interrupts = <8>;
+ clocks = <&clks IMX5_CLK_NFC_GATE>;
+ status = "disabled";
+ };
+
+ ssi3: ssi@63fe8000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx53-ssi", "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
+ reg = <0x63fe8000 0x4000>;
+ interrupts = <96>;
+ clocks = <&clks IMX5_CLK_SSI3_IPG_GATE>,
+ <&clks IMX5_CLK_SSI3_ROOT_GATE>;
+ clock-names = "ipg", "baud";
+ dmas = <&sdma 46 0 0>,
+ <&sdma 47 0 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ fec: ethernet@63fec000 {
+ compatible = "fsl,imx53-fec", "fsl,imx25-fec";
+ reg = <0x63fec000 0x4000>;
+ interrupts = <87>;
+ clocks = <&clks IMX5_CLK_FEC_GATE>,
+ <&clks IMX5_CLK_FEC_GATE>,
+ <&clks IMX5_CLK_FEC_GATE>;
+ clock-names = "ipg", "ahb", "ptp";
+ status = "disabled";
+ };
+
+ tve: tve@63ff0000 {
+ compatible = "fsl,imx53-tve";
+ reg = <0x63ff0000 0x1000>;
+ interrupts = <92>;
+ clocks = <&clks IMX5_CLK_TVE_GATE>,
+ <&clks IMX5_CLK_IPU_DI1_SEL>;
+ clock-names = "tve", "di_sel";
+ status = "disabled";
+
+ port {
+ tve_in: endpoint {
+ remote-endpoint = <&ipu_di1_tve>;
+ };
+ };
+ };
+
+ vpu: vpu@63ff4000 {
+ compatible = "fsl,imx53-vpu", "cnm,coda7541";
+ reg = <0x63ff4000 0x1000>;
+ interrupts = <9>;
+ clocks = <&clks IMX5_CLK_VPU_REFERENCE_GATE>,
+ <&clks IMX5_CLK_VPU_GATE>;
+ clock-names = "per", "ahb";
+ resets = <&src 1>;
+ iram = <&ocram>;
+ };
+
+ sahara: crypto@63ff8000 {
+ compatible = "fsl,imx53-sahara";
+ reg = <0x63ff8000 0x4000>;
+ interrupts = <19 20>;
+ clocks = <&clks IMX5_CLK_SAHARA_IPG_GATE>,
+ <&clks IMX5_CLK_SAHARA_IPG_GATE>;
+ clock-names = "ipg", "ahb";
+ };
+ };
+
+ ocram: sram@f8000000 {
+ compatible = "mmio-sram";
+ reg = <0xf8000000 0x20000>;
+ clocks = <&clks IMX5_CLK_OCRAM>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a8-pmu";
+ interrupts = <77>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6dl-aristainetos_4.dts b/arch/arm/boot/dts/imx6dl-aristainetos_4.dts
new file mode 100644
index 000000000..d4c4a22db
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-aristainetos_4.dts
@@ -0,0 +1,89 @@
+/*
+ * support fot the imx6 based aristainetos board
+ *
+ * Copyright (C) 2014 Heiko Schocher <hs@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.
+ *
+ */
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-aristainetos.dtsi"
+
+/ {
+ model = "aristainetos i.MX6 Dual Lite Board 4";
+ compatible = "fsl,imx6dl";
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ enable-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_backlight>;
+ status = "okay";
+ };
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ soc {
+ display0: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ interface-pix-fmt = "rgb24";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu_disp>;
+ status = "okay";
+
+ display-timings {
+ 480x800p60 {
+ native-mode;
+ clock-frequency = <30000000>;
+ hactive = <480>;
+ vactive = <800>;
+ hfront-porch = <59>;
+ hback-porch = <10>;
+ hsync-len = <10>;
+ vback-porch = <15>;
+ vfront-porch = <15>;
+ vsync-len = <15>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ };
+ };
+
+ port {
+ display0_in: endpoint {
+ remote-endpoint = <&ipu1_di0_disp0>;
+ };
+ };
+ };
+ };
+};
+
+&ecspi2 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi2>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&ipu1_di0_disp0 {
+ remote-endpoint = <&display0_in>;
+};
+
+&pwm1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6dl-aristainetos_7.dts b/arch/arm/boot/dts/imx6dl-aristainetos_7.dts
new file mode 100644
index 000000000..15203f0e9
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-aristainetos_7.dts
@@ -0,0 +1,78 @@
+/*
+ * support fot the imx6 based aristainetos board
+ *
+ * Copyright (C) 2014 Heiko Schocher <hs@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.
+ *
+ */
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-aristainetos.dtsi"
+
+/ {
+ model = "aristainetos i.MX6 Dual Lite Board 7";
+ compatible = "fsl,imx6dl";
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ soc {
+ display0: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ interface-pix-fmt = "rgb24";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu_disp>;
+ status = "okay";
+
+ display-timings {
+ 800x480p60 {
+ native-mode;
+ clock-frequency = <33246000>;
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <88>;
+ hback-porch = <88>;
+ hsync-len = <80>;
+ vback-porch = <10>;
+ vfront-porch = <10>;
+ vsync-len = <25>;
+ vsync-active = <1>;
+ };
+ };
+
+ port {
+ display0_in: endpoint {
+ remote-endpoint = <&ipu1_di0_disp0>;
+ };
+ };
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm3 0 3000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_backlight>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&ipu1_di0_disp0 {
+ remote-endpoint = <&display0_in>;
+};
+
+&pwm3 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6dl-cubox-i.dts b/arch/arm/boot/dts/imx6dl-cubox-i.dts
new file mode 100644
index 000000000..e0b7fe8e1
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-cubox-i.dts
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 Russell King
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-cubox-i.dtsi"
+
+/ {
+ model = "SolidRun Cubox-i Solo/DualLite";
+ compatible = "solidrun,cubox-i/dl", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts b/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts
new file mode 100644
index 000000000..994f96a3f
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Sascha Hauer <s.hauer@pengutronix.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 __DTS_V1__
+#define __DTS_V1__
+/dts-v1/;
+#endif
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-dfi-fs700-m60.dtsi"
+
+/ {
+ model = "DFI FS700-M60-6DL i.MX6dl Q7 Board";
+ compatible = "dfi,fs700-m60-6dl", "dfi,fs700e-m60", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-gw51xx.dts b/arch/arm/boot/dts/imx6dl-gw51xx.dts
new file mode 100644
index 000000000..b2bd022fc
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-gw51xx.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw51xx.dtsi"
+
+/ {
+ model = "Gateworks Ventana i.MX6 DualLite/Solo GW51XX";
+ compatible = "gw,imx6dl-gw51xx", "gw,ventana", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-gw52xx.dts b/arch/arm/boot/dts/imx6dl-gw52xx.dts
new file mode 100644
index 000000000..a2e0b73fd
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-gw52xx.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw52xx.dtsi"
+
+/ {
+ model = "Gateworks Ventana i.MX6 DualLite/Solo GW52XX";
+ compatible = "gw,imx6dl-gw52xx", "gw,ventana", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-gw53xx.dts b/arch/arm/boot/dts/imx6dl-gw53xx.dts
new file mode 100644
index 000000000..6844b708d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-gw53xx.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw53xx.dtsi"
+
+/ {
+ model = "Gateworks Ventana i.MX6 DualLite/Solo GW53XX";
+ compatible = "gw,imx6dl-gw53xx", "gw,ventana", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-gw54xx.dts b/arch/arm/boot/dts/imx6dl-gw54xx.dts
new file mode 100644
index 000000000..be915412f
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-gw54xx.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw54xx.dtsi"
+
+/ {
+ model = "Gateworks Ventana i.MX6 DualLite/Solo GW54XX";
+ compatible = "gw,imx6dl-gw54xx", "gw,ventana", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-gw552x.dts b/arch/arm/boot/dts/imx6dl-gw552x.dts
new file mode 100644
index 000000000..a4b700cef
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-gw552x.dts
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2014 Gateworks Corporation
+ *
+ * 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
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw552x.dtsi"
+
+/ {
+ model = "Gateworks Ventana i.MX6 DualLite/Solo GW552X";
+ compatible = "gw,imx6dl-gw552x", "gw,ventana", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-hummingboard.dts b/arch/arm/boot/dts/imx6dl-hummingboard.dts
new file mode 100644
index 000000000..7369d2d7d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-hummingboard.dts
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014 Rabeeh Khoury (rabeeh@solid-run.com)
+ * Based on dt work by Russell King
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-hummingboard.dtsi"
+
+/ {
+ model = "SolidRun HummingBoard Solo/DualLite";
+ compatible = "solidrun,hummingboard/dl", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-nitrogen6x.dts b/arch/arm/boot/dts/imx6dl-nitrogen6x.dts
new file mode 100644
index 000000000..5f4d33ccc
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-nitrogen6x.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2013 Boundary Devices, Inc.
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-nitrogen6x.dtsi"
+
+/ {
+ model = "Freescale i.MX6 DualLite Nitrogen6x Board";
+ compatible = "fsl,imx6dl-nitrogen6x", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-phytec-pbab01.dts b/arch/arm/boot/dts/imx6dl-phytec-pbab01.dts
new file mode 100644
index 000000000..08e978014
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-phytec-pbab01.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx6dl-phytec-pfla02.dtsi"
+#include "imx6qdl-phytec-pbab01.dtsi"
+
+/ {
+ model = "Phytec phyFLEX-i.MX6 DualLite/Solo Carrier-Board";
+ compatible = "phytec,imx6dl-pbab01", "phytec,imx6dl-pfla02", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi
new file mode 100644
index 000000000..964bc2ad3
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
+ *
+ * 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 "imx6dl.dtsi"
+#include "imx6qdl-phytec-pfla02.dtsi"
+
+/ {
+ model = "Phytec phyFLEX-i.MX6 DualLite/Solo";
+ compatible = "phytec,imx6dl-pfla02", "fsl,imx6dl";
+
+ memory {
+ reg = <0x10000000 0x20000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6dl-pinfunc.h b/arch/arm/boot/dts/imx6dl-pinfunc.h
new file mode 100644
index 000000000..0ead323fd
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-pinfunc.h
@@ -0,0 +1,1091 @@
+/*
+ * Copyright 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX6DL_PINFUNC_H
+#define __DTS_IMX6DL_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX6QDL_PAD_CSI0_DAT10__IPU1_CSI0_DATA10 0x04c 0x360 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT10__AUD3_RXC 0x04c 0x360 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT10__ECSPI2_MISO 0x04c 0x360 0x7f8 0x2 0x0
+#define MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x04c 0x360 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT10__UART1_RX_DATA 0x04c 0x360 0x8fc 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT10__GPIO5_IO28 0x04c 0x360 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT10__ARM_TRACE07 0x04c 0x360 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT11__IPU1_CSI0_DATA11 0x050 0x364 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT11__AUD3_RXFS 0x050 0x364 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT11__ECSPI2_SS0 0x050 0x364 0x800 0x2 0x0
+#define MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x050 0x364 0x8fc 0x3 0x1
+#define MX6QDL_PAD_CSI0_DAT11__UART1_TX_DATA 0x050 0x364 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT11__GPIO5_IO29 0x050 0x364 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT11__ARM_TRACE08 0x050 0x364 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x054 0x368 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT12__EIM_DATA08 0x054 0x368 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x054 0x368 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT12__UART4_RX_DATA 0x054 0x368 0x914 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT12__GPIO5_IO30 0x054 0x368 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT12__ARM_TRACE09 0x054 0x368 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x058 0x36c 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT13__EIM_DATA09 0x058 0x36c 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x058 0x36c 0x914 0x3 0x1
+#define MX6QDL_PAD_CSI0_DAT13__UART4_TX_DATA 0x058 0x36c 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT13__GPIO5_IO31 0x058 0x36c 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT13__ARM_TRACE10 0x058 0x36c 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x05c 0x370 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT14__EIM_DATA10 0x05c 0x370 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT14__UART5_TX_DATA 0x05c 0x370 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT14__UART5_RX_DATA 0x05c 0x370 0x91c 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT14__GPIO6_IO00 0x05c 0x370 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT14__ARM_TRACE11 0x05c 0x370 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x060 0x374 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT15__EIM_DATA11 0x060 0x374 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT15__UART5_RX_DATA 0x060 0x374 0x91c 0x3 0x1
+#define MX6QDL_PAD_CSI0_DAT15__UART5_TX_DATA 0x060 0x374 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT15__GPIO6_IO01 0x060 0x374 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT15__ARM_TRACE12 0x060 0x374 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x064 0x378 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT16__EIM_DATA12 0x064 0x378 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B 0x064 0x378 0x910 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT16__UART4_CTS_B 0x064 0x378 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT16__GPIO6_IO02 0x064 0x378 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT16__ARM_TRACE13 0x064 0x378 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x068 0x37c 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT17__EIM_DATA13 0x068 0x37c 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B 0x068 0x37c 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT17__UART4_RTS_B 0x068 0x37c 0x910 0x3 0x1
+#define MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03 0x068 0x37c 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT17__ARM_TRACE14 0x068 0x37c 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x06c 0x380 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT18__EIM_DATA14 0x06c 0x380 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT18__UART5_RTS_B 0x06c 0x380 0x918 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT18__UART5_CTS_B 0x06c 0x380 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT18__GPIO6_IO04 0x06c 0x380 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT18__ARM_TRACE15 0x06c 0x380 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x070 0x384 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT19__EIM_DATA15 0x070 0x384 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT19__UART5_CTS_B 0x070 0x384 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT19__UART5_RTS_B 0x070 0x384 0x918 0x3 0x1
+#define MX6QDL_PAD_CSI0_DAT19__GPIO6_IO05 0x070 0x384 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT4__IPU1_CSI0_DATA04 0x074 0x388 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT4__EIM_DATA02 0x074 0x388 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT4__ECSPI1_SCLK 0x074 0x388 0x7d8 0x2 0x0
+#define MX6QDL_PAD_CSI0_DAT4__KEY_COL5 0x074 0x388 0x8c0 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x074 0x388 0x000 0x4 0x0
+#define MX6QDL_PAD_CSI0_DAT4__GPIO5_IO22 0x074 0x388 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT4__ARM_TRACE01 0x074 0x388 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT5__IPU1_CSI0_DATA05 0x078 0x38c 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT5__EIM_DATA03 0x078 0x38c 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT5__ECSPI1_MOSI 0x078 0x38c 0x7e0 0x2 0x0
+#define MX6QDL_PAD_CSI0_DAT5__KEY_ROW5 0x078 0x38c 0x8cc 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x078 0x38c 0x000 0x4 0x0
+#define MX6QDL_PAD_CSI0_DAT5__GPIO5_IO23 0x078 0x38c 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT5__ARM_TRACE02 0x078 0x38c 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT6__IPU1_CSI0_DATA06 0x07c 0x390 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT6__EIM_DATA04 0x07c 0x390 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT6__ECSPI1_MISO 0x07c 0x390 0x7dc 0x2 0x0
+#define MX6QDL_PAD_CSI0_DAT6__KEY_COL6 0x07c 0x390 0x8c4 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x07c 0x390 0x000 0x4 0x0
+#define MX6QDL_PAD_CSI0_DAT6__GPIO5_IO24 0x07c 0x390 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT6__ARM_TRACE03 0x07c 0x390 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT7__IPU1_CSI0_DATA07 0x080 0x394 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT7__EIM_DATA05 0x080 0x394 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT7__ECSPI1_SS0 0x080 0x394 0x7e4 0x2 0x0
+#define MX6QDL_PAD_CSI0_DAT7__KEY_ROW6 0x080 0x394 0x8d0 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x080 0x394 0x000 0x4 0x0
+#define MX6QDL_PAD_CSI0_DAT7__GPIO5_IO25 0x080 0x394 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT7__ARM_TRACE04 0x080 0x394 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT8__IPU1_CSI0_DATA08 0x084 0x398 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT8__EIM_DATA06 0x084 0x398 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT8__ECSPI2_SCLK 0x084 0x398 0x7f4 0x2 0x0
+#define MX6QDL_PAD_CSI0_DAT8__KEY_COL7 0x084 0x398 0x8c8 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x084 0x398 0x86c 0x4 0x0
+#define MX6QDL_PAD_CSI0_DAT8__GPIO5_IO26 0x084 0x398 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT8__ARM_TRACE05 0x084 0x398 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT9__IPU1_CSI0_DATA09 0x088 0x39c 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT9__EIM_DATA07 0x088 0x39c 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT9__ECSPI2_MOSI 0x088 0x39c 0x7fc 0x2 0x0
+#define MX6QDL_PAD_CSI0_DAT9__KEY_ROW7 0x088 0x39c 0x8d4 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x088 0x39c 0x868 0x4 0x0
+#define MX6QDL_PAD_CSI0_DAT9__GPIO5_IO27 0x088 0x39c 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT9__ARM_TRACE06 0x088 0x39c 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN 0x08c 0x3a0 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DATA_EN__EIM_DATA00 0x08c 0x3a0 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x08c 0x3a0 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DATA_EN__ARM_TRACE_CLK 0x08c 0x3a0 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x090 0x3a4 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_MCLK__CCM_CLKO1 0x090 0x3a4 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_MCLK__GPIO5_IO19 0x090 0x3a4 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_MCLK__ARM_TRACE_CTL 0x090 0x3a4 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x094 0x3a8 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18 0x094 0x3a8 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_PIXCLK__ARM_EVENTO 0x094 0x3a8 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x098 0x3ac 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_VSYNC__EIM_DATA01 0x098 0x3ac 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21 0x098 0x3ac 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_VSYNC__ARM_TRACE00 0x098 0x3ac 0x000 0x7 0x0
+#define MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x09c 0x3b0 0x000 0x0 0x0
+#define MX6QDL_PAD_DI0_DISP_CLK__LCD_CLK 0x09c 0x3b0 0x000 0x1 0x0
+#define MX6QDL_PAD_DI0_DISP_CLK__GPIO4_IO16 0x09c 0x3b0 0x000 0x5 0x0
+#define MX6QDL_PAD_DI0_DISP_CLK__LCD_WR_RWN 0x09c 0x3b0 0x000 0x8 0x0
+#define MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x0a0 0x3b4 0x000 0x0 0x0
+#define MX6QDL_PAD_DI0_PIN15__LCD_ENABLE 0x0a0 0x3b4 0x000 0x1 0x0
+#define MX6QDL_PAD_DI0_PIN15__AUD6_TXC 0x0a0 0x3b4 0x000 0x2 0x0
+#define MX6QDL_PAD_DI0_PIN15__GPIO4_IO17 0x0a0 0x3b4 0x000 0x5 0x0
+#define MX6QDL_PAD_DI0_PIN15__LCD_RD_E 0x0a0 0x3b4 0x000 0x8 0x0
+#define MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x0a4 0x3b8 0x000 0x0 0x0
+#define MX6QDL_PAD_DI0_PIN2__LCD_HSYNC 0x0a4 0x3b8 0x8d8 0x1 0x0
+#define MX6QDL_PAD_DI0_PIN2__AUD6_TXD 0x0a4 0x3b8 0x000 0x2 0x0
+#define MX6QDL_PAD_DI0_PIN2__GPIO4_IO18 0x0a4 0x3b8 0x000 0x5 0x0
+#define MX6QDL_PAD_DI0_PIN2__LCD_RS 0x0a4 0x3b8 0x000 0x8 0x0
+#define MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x0a8 0x3bc 0x000 0x0 0x0
+#define MX6QDL_PAD_DI0_PIN3__LCD_VSYNC 0x0a8 0x3bc 0x000 0x1 0x0
+#define MX6QDL_PAD_DI0_PIN3__AUD6_TXFS 0x0a8 0x3bc 0x000 0x2 0x0
+#define MX6QDL_PAD_DI0_PIN3__GPIO4_IO19 0x0a8 0x3bc 0x000 0x5 0x0
+#define MX6QDL_PAD_DI0_PIN3__LCD_CS 0x0a8 0x3bc 0x000 0x8 0x0
+#define MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04 0x0ac 0x3c0 0x000 0x0 0x0
+#define MX6QDL_PAD_DI0_PIN4__LCD_BUSY 0x0ac 0x3c0 0x8d8 0x1 0x1
+#define MX6QDL_PAD_DI0_PIN4__AUD6_RXD 0x0ac 0x3c0 0x000 0x2 0x0
+#define MX6QDL_PAD_DI0_PIN4__SD1_WP 0x0ac 0x3c0 0x92c 0x3 0x0
+#define MX6QDL_PAD_DI0_PIN4__GPIO4_IO20 0x0ac 0x3c0 0x000 0x5 0x0
+#define MX6QDL_PAD_DI0_PIN4__LCD_RESET 0x0ac 0x3c0 0x000 0x8 0x0
+#define MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x0b0 0x3c4 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT0__LCD_DATA00 0x0b0 0x3c4 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x0b0 0x3c4 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT0__GPIO4_IO21 0x0b0 0x3c4 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x0b4 0x3c8 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT1__LCD_DATA01 0x0b4 0x3c8 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x0b4 0x3c8 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT1__GPIO4_IO22 0x0b4 0x3c8 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x0b8 0x3cc 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT10__LCD_DATA10 0x0b8 0x3cc 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT10__GPIO4_IO31 0x0b8 0x3cc 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x0bc 0x3d0 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT11__LCD_DATA11 0x0bc 0x3d0 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT11__GPIO5_IO05 0x0bc 0x3d0 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x0c0 0x3d4 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT12__LCD_DATA12 0x0c0 0x3d4 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT12__GPIO5_IO06 0x0c0 0x3d4 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x0c4 0x3d8 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT13__LCD_DATA13 0x0c4 0x3d8 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT13__AUD5_RXFS 0x0c4 0x3d8 0x7bc 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT13__GPIO5_IO07 0x0c4 0x3d8 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x0c8 0x3dc 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT14__LCD_DATA14 0x0c8 0x3dc 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT14__AUD5_RXC 0x0c8 0x3dc 0x7b8 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT14__GPIO5_IO08 0x0c8 0x3dc 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x0cc 0x3e0 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT15__LCD_DATA15 0x0cc 0x3e0 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT15__ECSPI1_SS1 0x0cc 0x3e0 0x7e8 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT15__ECSPI2_SS1 0x0cc 0x3e0 0x804 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09 0x0cc 0x3e0 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x0d0 0x3e4 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT16__LCD_DATA16 0x0d0 0x3e4 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT16__ECSPI2_MOSI 0x0d0 0x3e4 0x7fc 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT16__AUD5_TXC 0x0d0 0x3e4 0x7c0 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT16__SDMA_EXT_EVENT0 0x0d0 0x3e4 0x8e8 0x4 0x0
+#define MX6QDL_PAD_DISP0_DAT16__GPIO5_IO10 0x0d0 0x3e4 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x0d4 0x3e8 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT17__LCD_DATA17 0x0d4 0x3e8 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT17__ECSPI2_MISO 0x0d4 0x3e8 0x7f8 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT17__AUD5_TXD 0x0d4 0x3e8 0x7b4 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT17__SDMA_EXT_EVENT1 0x0d4 0x3e8 0x8ec 0x4 0x0
+#define MX6QDL_PAD_DISP0_DAT17__GPIO5_IO11 0x0d4 0x3e8 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x0d8 0x3ec 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT18__LCD_DATA18 0x0d8 0x3ec 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT18__ECSPI2_SS0 0x0d8 0x3ec 0x800 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS 0x0d8 0x3ec 0x7c4 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT18__AUD4_RXFS 0x0d8 0x3ec 0x7a4 0x4 0x0
+#define MX6QDL_PAD_DISP0_DAT18__GPIO5_IO12 0x0d8 0x3ec 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT18__EIM_CS2_B 0x0d8 0x3ec 0x000 0x7 0x0
+#define MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x0dc 0x3f0 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT19__LCD_DATA19 0x0dc 0x3f0 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT19__ECSPI2_SCLK 0x0dc 0x3f0 0x7f4 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x0dc 0x3f0 0x7b0 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT19__AUD4_RXC 0x0dc 0x3f0 0x7a0 0x4 0x0
+#define MX6QDL_PAD_DISP0_DAT19__GPIO5_IO13 0x0dc 0x3f0 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT19__EIM_CS3_B 0x0dc 0x3f0 0x000 0x7 0x0
+#define MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x0e0 0x3f4 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT2__LCD_DATA02 0x0e0 0x3f4 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x0e0 0x3f4 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT2__GPIO4_IO23 0x0e0 0x3f4 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x0e4 0x3f8 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT20__LCD_DATA20 0x0e4 0x3f8 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT20__ECSPI1_SCLK 0x0e4 0x3f8 0x7d8 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT20__AUD4_TXC 0x0e4 0x3f8 0x7a8 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT20__GPIO5_IO14 0x0e4 0x3f8 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x0e8 0x3fc 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT21__LCD_DATA21 0x0e8 0x3fc 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT21__ECSPI1_MOSI 0x0e8 0x3fc 0x7e0 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT21__AUD4_TXD 0x0e8 0x3fc 0x79c 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15 0x0e8 0x3fc 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x0ec 0x400 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT22__LCD_DATA22 0x0ec 0x400 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT22__ECSPI1_MISO 0x0ec 0x400 0x7dc 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT22__AUD4_TXFS 0x0ec 0x400 0x7ac 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT22__GPIO5_IO16 0x0ec 0x400 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x0f0 0x404 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT23__LCD_DATA23 0x0f0 0x404 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT23__ECSPI1_SS0 0x0f0 0x404 0x7e4 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT23__AUD4_RXD 0x0f0 0x404 0x798 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT23__GPIO5_IO17 0x0f0 0x404 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x0f4 0x408 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT3__LCD_DATA03 0x0f4 0x408 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT3__ECSPI3_SS0 0x0f4 0x408 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x0f4 0x408 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x0f8 0x40c 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT4__LCD_DATA04 0x0f8 0x40c 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT4__ECSPI3_SS1 0x0f8 0x40c 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT4__GPIO4_IO25 0x0f8 0x40c 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x0fc 0x410 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT5__LCD_DATA05 0x0fc 0x410 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT5__ECSPI3_SS2 0x0fc 0x410 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT5__AUD6_RXFS 0x0fc 0x410 0x000 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT5__GPIO4_IO26 0x0fc 0x410 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x100 0x414 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT6__LCD_DATA06 0x100 0x414 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT6__ECSPI3_SS3 0x100 0x414 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT6__AUD6_RXC 0x100 0x414 0x000 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT6__GPIO4_IO27 0x100 0x414 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x104 0x418 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT7__LCD_DATA07 0x104 0x418 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT7__ECSPI3_RDY 0x104 0x418 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT7__GPIO4_IO28 0x104 0x418 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x108 0x41c 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT8__LCD_DATA08 0x108 0x41c 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT8__PWM1_OUT 0x108 0x41c 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT8__WDOG1_B 0x108 0x41c 0x000 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT8__GPIO4_IO29 0x108 0x41c 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x10c 0x420 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT9__LCD_DATA09 0x10c 0x420 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT9__PWM2_OUT 0x10c 0x420 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT9__WDOG2_B 0x10c 0x420 0x000 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT9__GPIO4_IO30 0x10c 0x420 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A16__EIM_ADDR16 0x110 0x4e0 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A16__IPU1_DI1_DISP_CLK 0x110 0x4e0 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A16__IPU1_CSI1_PIXCLK 0x110 0x4e0 0x8b8 0x2 0x0
+#define MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x110 0x4e0 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A16__SRC_BOOT_CFG16 0x110 0x4e0 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A16__EPDC_DATA00 0x110 0x4e0 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_A17__EIM_ADDR17 0x114 0x4e4 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A17__IPU1_DISP1_DATA12 0x114 0x4e4 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A17__IPU1_CSI1_DATA12 0x114 0x4e4 0x890 0x2 0x0
+#define MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x114 0x4e4 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A17__SRC_BOOT_CFG17 0x114 0x4e4 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A17__EPDC_PWR_STAT 0x114 0x4e4 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_A18__EIM_ADDR18 0x118 0x4e8 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A18__IPU1_DISP1_DATA13 0x118 0x4e8 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A18__IPU1_CSI1_DATA13 0x118 0x4e8 0x894 0x2 0x0
+#define MX6QDL_PAD_EIM_A18__GPIO2_IO20 0x118 0x4e8 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A18__SRC_BOOT_CFG18 0x118 0x4e8 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A18__EPDC_PWR_CTRL0 0x118 0x4e8 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_A19__EIM_ADDR19 0x11c 0x4ec 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A19__IPU1_DISP1_DATA14 0x11c 0x4ec 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A19__IPU1_CSI1_DATA14 0x11c 0x4ec 0x898 0x2 0x0
+#define MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x11c 0x4ec 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A19__SRC_BOOT_CFG19 0x11c 0x4ec 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A19__EPDC_PWR_CTRL1 0x11c 0x4ec 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_A20__EIM_ADDR20 0x120 0x4f0 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A20__IPU1_DISP1_DATA15 0x120 0x4f0 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A20__IPU1_CSI1_DATA15 0x120 0x4f0 0x89c 0x2 0x0
+#define MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x120 0x4f0 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A20__SRC_BOOT_CFG20 0x120 0x4f0 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A20__EPDC_PWR_CTRL2 0x120 0x4f0 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_A21__EIM_ADDR21 0x124 0x4f4 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A21__IPU1_DISP1_DATA16 0x124 0x4f4 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A21__IPU1_CSI1_DATA16 0x124 0x4f4 0x8a0 0x2 0x0
+#define MX6QDL_PAD_EIM_A21__GPIO2_IO17 0x124 0x4f4 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A21__SRC_BOOT_CFG21 0x124 0x4f4 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A21__EPDC_GDCLK 0x124 0x4f4 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_A22__EIM_ADDR22 0x128 0x4f8 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A22__IPU1_DISP1_DATA17 0x128 0x4f8 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A22__IPU1_CSI1_DATA17 0x128 0x4f8 0x8a4 0x2 0x0
+#define MX6QDL_PAD_EIM_A22__GPIO2_IO16 0x128 0x4f8 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A22__SRC_BOOT_CFG22 0x128 0x4f8 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A22__EPDC_GDSP 0x128 0x4f8 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_A23__EIM_ADDR23 0x12c 0x4fc 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A23__IPU1_DISP1_DATA18 0x12c 0x4fc 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A23__IPU1_CSI1_DATA18 0x12c 0x4fc 0x8a8 0x2 0x0
+#define MX6QDL_PAD_EIM_A23__IPU1_SISG3 0x12c 0x4fc 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_A23__GPIO6_IO06 0x12c 0x4fc 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A23__SRC_BOOT_CFG23 0x12c 0x4fc 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A23__EPDC_GDOE 0x12c 0x4fc 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_A24__EIM_ADDR24 0x130 0x500 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A24__IPU1_DISP1_DATA19 0x130 0x500 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A24__IPU1_CSI1_DATA19 0x130 0x500 0x8ac 0x2 0x0
+#define MX6QDL_PAD_EIM_A24__IPU1_SISG2 0x130 0x500 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_A24__GPIO5_IO04 0x130 0x500 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A24__SRC_BOOT_CFG24 0x130 0x500 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A24__EPDC_GDRL 0x130 0x500 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_A25__EIM_ADDR25 0x134 0x504 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A25__ECSPI4_SS1 0x134 0x504 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A25__ECSPI2_RDY 0x134 0x504 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_A25__IPU1_DI1_PIN12 0x134 0x504 0x000 0x3 0x0
+#define MX6QDL_PAD_EIM_A25__IPU1_DI0_D1_CS 0x134 0x504 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x134 0x504 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A25__HDMI_TX_CEC_LINE 0x134 0x504 0x85c 0x6 0x0
+#define MX6QDL_PAD_EIM_A25__EPDC_DATA15 0x134 0x504 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_A25__EIM_ACLK_FREERUN 0x134 0x504 0x000 0x9 0x0
+#define MX6QDL_PAD_EIM_BCLK__EIM_BCLK 0x138 0x508 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_BCLK__IPU1_DI1_PIN16 0x138 0x508 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0x138 0x508 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_BCLK__EPDC_SDCE9 0x138 0x508 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_CS0__EIM_CS0_B 0x13c 0x50c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_CS0__IPU1_DI1_PIN05 0x13c 0x50c 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_CS0__ECSPI2_SCLK 0x13c 0x50c 0x7f4 0x2 0x2
+#define MX6QDL_PAD_EIM_CS0__GPIO2_IO23 0x13c 0x50c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_CS0__EPDC_DATA06 0x13c 0x50c 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_CS1__EIM_CS1_B 0x140 0x510 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_CS1__IPU1_DI1_PIN06 0x140 0x510 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_CS1__ECSPI2_MOSI 0x140 0x510 0x7fc 0x2 0x2
+#define MX6QDL_PAD_EIM_CS1__GPIO2_IO24 0x140 0x510 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_CS1__EPDC_DATA08 0x140 0x510 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_D16__EIM_DATA16 0x144 0x514 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x144 0x514 0x7d8 0x1 0x2
+#define MX6QDL_PAD_EIM_D16__IPU1_DI0_PIN05 0x144 0x514 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D16__IPU1_CSI1_DATA18 0x144 0x514 0x8a8 0x3 0x1
+#define MX6QDL_PAD_EIM_D16__HDMI_TX_DDC_SDA 0x144 0x514 0x864 0x4 0x0
+#define MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x144 0x514 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D16__I2C2_SDA 0x144 0x514 0x874 0x6 0x0
+#define MX6QDL_PAD_EIM_D16__EPDC_DATA10 0x144 0x514 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_D17__EIM_DATA17 0x148 0x518 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x148 0x518 0x7dc 0x1 0x2
+#define MX6QDL_PAD_EIM_D17__IPU1_DI0_PIN06 0x148 0x518 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D17__IPU1_CSI1_PIXCLK 0x148 0x518 0x8b8 0x3 0x1
+#define MX6QDL_PAD_EIM_D17__DCIC1_OUT 0x148 0x518 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D17__GPIO3_IO17 0x148 0x518 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D17__I2C3_SCL 0x148 0x518 0x878 0x6 0x0
+#define MX6QDL_PAD_EIM_D17__EPDC_VCOM0 0x148 0x518 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_D18__EIM_DATA18 0x14c 0x51c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x14c 0x51c 0x7e0 0x1 0x2
+#define MX6QDL_PAD_EIM_D18__IPU1_DI0_PIN07 0x14c 0x51c 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D18__IPU1_CSI1_DATA17 0x14c 0x51c 0x8a4 0x3 0x1
+#define MX6QDL_PAD_EIM_D18__IPU1_DI1_D0_CS 0x14c 0x51c 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D18__GPIO3_IO18 0x14c 0x51c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D18__I2C3_SDA 0x14c 0x51c 0x87c 0x6 0x0
+#define MX6QDL_PAD_EIM_D18__EPDC_VCOM1 0x14c 0x51c 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_D19__EIM_DATA19 0x150 0x520 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D19__ECSPI1_SS1 0x150 0x520 0x7e8 0x1 0x1
+#define MX6QDL_PAD_EIM_D19__IPU1_DI0_PIN08 0x150 0x520 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D19__IPU1_CSI1_DATA16 0x150 0x520 0x8a0 0x3 0x1
+#define MX6QDL_PAD_EIM_D19__UART1_CTS_B 0x150 0x520 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D19__UART1_RTS_B 0x150 0x520 0x8f8 0x4 0x0
+#define MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x150 0x520 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D19__EPIT1_OUT 0x150 0x520 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_D19__EPDC_DATA12 0x150 0x520 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_D20__EIM_DATA20 0x154 0x524 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D20__ECSPI4_SS0 0x154 0x524 0x808 0x1 0x0
+#define MX6QDL_PAD_EIM_D20__IPU1_DI0_PIN16 0x154 0x524 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D20__IPU1_CSI1_DATA15 0x154 0x524 0x89c 0x3 0x1
+#define MX6QDL_PAD_EIM_D20__UART1_RTS_B 0x154 0x524 0x8f8 0x4 0x1
+#define MX6QDL_PAD_EIM_D20__UART1_CTS_B 0x154 0x524 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D20__GPIO3_IO20 0x154 0x524 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D20__EPIT2_OUT 0x154 0x524 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_D21__EIM_DATA21 0x158 0x528 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D21__ECSPI4_SCLK 0x158 0x528 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D21__IPU1_DI0_PIN17 0x158 0x528 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D21__IPU1_CSI1_DATA11 0x158 0x528 0x88c 0x3 0x0
+#define MX6QDL_PAD_EIM_D21__USB_OTG_OC 0x158 0x528 0x920 0x4 0x0
+#define MX6QDL_PAD_EIM_D21__GPIO3_IO21 0x158 0x528 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D21__I2C1_SCL 0x158 0x528 0x868 0x6 0x1
+#define MX6QDL_PAD_EIM_D21__SPDIF_IN 0x158 0x528 0x8f0 0x7 0x0
+#define MX6QDL_PAD_EIM_D22__EIM_DATA22 0x15c 0x52c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D22__ECSPI4_MISO 0x15c 0x52c 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D22__IPU1_DI0_PIN01 0x15c 0x52c 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D22__IPU1_CSI1_DATA10 0x15c 0x52c 0x888 0x3 0x0
+#define MX6QDL_PAD_EIM_D22__USB_OTG_PWR 0x15c 0x52c 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x15c 0x52c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D22__SPDIF_OUT 0x15c 0x52c 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_D22__EPDC_SDCE6 0x15c 0x52c 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_D23__EIM_DATA23 0x160 0x530 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D23__IPU1_DI0_D0_CS 0x160 0x530 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x160 0x530 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D23__UART3_RTS_B 0x160 0x530 0x908 0x2 0x0
+#define MX6QDL_PAD_EIM_D23__UART1_DCD_B 0x160 0x530 0x000 0x3 0x0
+#define MX6QDL_PAD_EIM_D23__IPU1_CSI1_DATA_EN 0x160 0x530 0x8b0 0x4 0x0
+#define MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x160 0x530 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D23__IPU1_DI1_PIN02 0x160 0x530 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_D23__IPU1_DI1_PIN14 0x160 0x530 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_D23__EPDC_DATA11 0x160 0x530 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_D24__EIM_DATA24 0x164 0x534 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D24__ECSPI4_SS2 0x164 0x534 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x164 0x534 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D24__UART3_RX_DATA 0x164 0x534 0x90c 0x2 0x0
+#define MX6QDL_PAD_EIM_D24__ECSPI1_SS2 0x164 0x534 0x7ec 0x3 0x0
+#define MX6QDL_PAD_EIM_D24__ECSPI2_SS2 0x164 0x534 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D24__GPIO3_IO24 0x164 0x534 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D24__AUD5_RXFS 0x164 0x534 0x7bc 0x6 0x1
+#define MX6QDL_PAD_EIM_D24__UART1_DTR_B 0x164 0x534 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_D24__EPDC_SDCE7 0x164 0x534 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_D25__EIM_DATA25 0x168 0x538 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D25__ECSPI4_SS3 0x168 0x538 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x168 0x538 0x90c 0x2 0x1
+#define MX6QDL_PAD_EIM_D25__UART3_TX_DATA 0x168 0x538 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D25__ECSPI1_SS3 0x168 0x538 0x7f0 0x3 0x0
+#define MX6QDL_PAD_EIM_D25__ECSPI2_SS3 0x168 0x538 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D25__GPIO3_IO25 0x168 0x538 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D25__AUD5_RXC 0x168 0x538 0x7b8 0x6 0x1
+#define MX6QDL_PAD_EIM_D25__UART1_DSR_B 0x168 0x538 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_D25__EPDC_SDCE8 0x168 0x538 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_D26__EIM_DATA26 0x16c 0x53c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D26__IPU1_DI1_PIN11 0x16c 0x53c 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D26__IPU1_CSI0_DATA01 0x16c 0x53c 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D26__IPU1_CSI1_DATA14 0x16c 0x53c 0x898 0x3 0x1
+#define MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x16c 0x53c 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D26__UART2_RX_DATA 0x16c 0x53c 0x904 0x4 0x0
+#define MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x16c 0x53c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D26__IPU1_SISG2 0x16c 0x53c 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_D26__IPU1_DISP1_DATA22 0x16c 0x53c 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_D26__EPDC_SDOED 0x16c 0x53c 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_D27__EIM_DATA27 0x170 0x540 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D27__IPU1_DI1_PIN13 0x170 0x540 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D27__IPU1_CSI0_DATA00 0x170 0x540 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D27__IPU1_CSI1_DATA13 0x170 0x540 0x894 0x3 0x1
+#define MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x170 0x540 0x904 0x4 0x1
+#define MX6QDL_PAD_EIM_D27__UART2_TX_DATA 0x170 0x540 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D27__GPIO3_IO27 0x170 0x540 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D27__IPU1_SISG3 0x170 0x540 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_D27__IPU1_DISP1_DATA23 0x170 0x540 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_D27__EPDC_SDOE 0x170 0x540 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_D28__EIM_DATA28 0x174 0x544 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D28__I2C1_SDA 0x174 0x544 0x86c 0x1 0x1
+#define MX6QDL_PAD_EIM_D28__ECSPI4_MOSI 0x174 0x544 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D28__IPU1_CSI1_DATA12 0x174 0x544 0x890 0x3 0x1
+#define MX6QDL_PAD_EIM_D28__UART2_CTS_B 0x174 0x544 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D28__UART2_RTS_B 0x174 0x544 0x900 0x4 0x0
+#define MX6QDL_PAD_EIM_D28__UART2_DTE_CTS_B 0x174 0x544 0x900 0x4 0x0
+#define MX6QDL_PAD_EIM_D28__UART2_DTE_RTS_B 0x174 0x544 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D28__GPIO3_IO28 0x174 0x544 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D28__IPU1_EXT_TRIG 0x174 0x544 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_D28__IPU1_DI0_PIN13 0x174 0x544 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_D28__EPDC_PWR_CTRL3 0x174 0x544 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_D29__EIM_DATA29 0x178 0x548 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D29__IPU1_DI1_PIN15 0x178 0x548 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D29__ECSPI4_SS0 0x178 0x548 0x808 0x2 0x1
+#define MX6QDL_PAD_EIM_D29__UART2_RTS_B 0x178 0x548 0x900 0x4 0x1
+#define MX6QDL_PAD_EIM_D29__UART2_CTS_B 0x178 0x548 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D29__UART2_DTE_RTS_B 0x178 0x548 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D29__UART2_DTE_CTS_B 0x178 0x548 0x900 0x4 0x1
+#define MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x178 0x548 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D29__IPU1_CSI1_VSYNC 0x178 0x548 0x8bc 0x6 0x0
+#define MX6QDL_PAD_EIM_D29__IPU1_DI0_PIN14 0x178 0x548 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_D29__EPDC_PWR_WAKE 0x178 0x548 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_D30__EIM_DATA30 0x17c 0x54c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D30__IPU1_DISP1_DATA21 0x17c 0x54c 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D30__IPU1_DI0_PIN11 0x17c 0x54c 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D30__IPU1_CSI0_DATA03 0x17c 0x54c 0x000 0x3 0x0
+#define MX6QDL_PAD_EIM_D30__UART3_CTS_B 0x17c 0x54c 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D30__UART3_RTS_B 0x17c 0x54c 0x908 0x4 0x1
+#define MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x17c 0x54c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D30__USB_H1_OC 0x17c 0x54c 0x924 0x6 0x0
+#define MX6QDL_PAD_EIM_D30__EPDC_SDOEZ 0x17c 0x54c 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_D31__EIM_DATA31 0x180 0x550 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D31__IPU1_DISP1_DATA20 0x180 0x550 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D31__IPU1_DI0_PIN12 0x180 0x550 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D31__IPU1_CSI0_DATA02 0x180 0x550 0x000 0x3 0x0
+#define MX6QDL_PAD_EIM_D31__UART3_RTS_B 0x180 0x550 0x908 0x4 0x2
+#define MX6QDL_PAD_EIM_D31__UART3_CTS_B 0x180 0x550 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x180 0x550 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D31__USB_H1_PWR 0x180 0x550 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_D31__EPDC_SDCLK_P 0x180 0x550 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_D31__EIM_ACLK_FREERUN 0x180 0x550 0x000 0x9 0x0
+#define MX6QDL_PAD_EIM_DA0__EIM_AD00 0x184 0x554 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA0__IPU1_DISP1_DATA09 0x184 0x554 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA0__IPU1_CSI1_DATA09 0x184 0x554 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA0__GPIO3_IO00 0x184 0x554 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA0__SRC_BOOT_CFG00 0x184 0x554 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA0__EPDC_SDCLK_N 0x184 0x554 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_DA1__EIM_AD01 0x188 0x558 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA1__IPU1_DISP1_DATA08 0x188 0x558 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA1__IPU1_CSI1_DATA08 0x188 0x558 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA1__GPIO3_IO01 0x188 0x558 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA1__SRC_BOOT_CFG01 0x188 0x558 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA1__EPDC_SDLE 0x188 0x558 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_DA10__EIM_AD10 0x18c 0x55c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA10__IPU1_DI1_PIN15 0x18c 0x55c 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA10__IPU1_CSI1_DATA_EN 0x18c 0x55c 0x8b0 0x2 0x1
+#define MX6QDL_PAD_EIM_DA10__GPIO3_IO10 0x18c 0x55c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA10__SRC_BOOT_CFG10 0x18c 0x55c 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA10__EPDC_DATA01 0x18c 0x55c 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_DA11__EIM_AD11 0x190 0x560 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA11__IPU1_DI1_PIN02 0x190 0x560 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA11__IPU1_CSI1_HSYNC 0x190 0x560 0x8b4 0x2 0x0
+#define MX6QDL_PAD_EIM_DA11__GPIO3_IO11 0x190 0x560 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA11__SRC_BOOT_CFG11 0x190 0x560 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA11__EPDC_DATA03 0x190 0x560 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_DA12__EIM_AD12 0x194 0x564 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA12__IPU1_DI1_PIN03 0x194 0x564 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA12__IPU1_CSI1_VSYNC 0x194 0x564 0x8bc 0x2 0x1
+#define MX6QDL_PAD_EIM_DA12__GPIO3_IO12 0x194 0x564 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA12__SRC_BOOT_CFG12 0x194 0x564 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA12__EPDC_DATA02 0x194 0x564 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_DA13__EIM_AD13 0x198 0x568 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA13__IPU1_DI1_D0_CS 0x198 0x568 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA13__GPIO3_IO13 0x198 0x568 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA13__SRC_BOOT_CFG13 0x198 0x568 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA13__EPDC_DATA13 0x198 0x568 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_DA14__EIM_AD14 0x19c 0x56c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA14__IPU1_DI1_D1_CS 0x19c 0x56c 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA14__GPIO3_IO14 0x19c 0x56c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA14__SRC_BOOT_CFG14 0x19c 0x56c 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA14__EPDC_DATA14 0x19c 0x56c 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_DA15__EIM_AD15 0x1a0 0x570 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA15__IPU1_DI1_PIN01 0x1a0 0x570 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA15__IPU1_DI1_PIN04 0x1a0 0x570 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA15__GPIO3_IO15 0x1a0 0x570 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA15__SRC_BOOT_CFG15 0x1a0 0x570 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA15__EPDC_DATA09 0x1a0 0x570 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_DA2__EIM_AD02 0x1a4 0x574 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA2__IPU1_DISP1_DATA07 0x1a4 0x574 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA2__IPU1_CSI1_DATA07 0x1a4 0x574 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA2__GPIO3_IO02 0x1a4 0x574 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA2__SRC_BOOT_CFG02 0x1a4 0x574 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA2__EPDC_BDR0 0x1a4 0x574 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_DA3__EIM_AD03 0x1a8 0x578 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA3__IPU1_DISP1_DATA06 0x1a8 0x578 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA3__IPU1_CSI1_DATA06 0x1a8 0x578 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA3__GPIO3_IO03 0x1a8 0x578 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA3__SRC_BOOT_CFG03 0x1a8 0x578 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA3__EPDC_BDR1 0x1a8 0x578 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_DA4__EIM_AD04 0x1ac 0x57c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA4__IPU1_DISP1_DATA05 0x1ac 0x57c 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA4__IPU1_CSI1_DATA05 0x1ac 0x57c 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA4__GPIO3_IO04 0x1ac 0x57c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA4__SRC_BOOT_CFG04 0x1ac 0x57c 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA4__EPDC_SDCE0 0x1ac 0x57c 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_DA5__EIM_AD05 0x1b0 0x580 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA5__IPU1_DISP1_DATA04 0x1b0 0x580 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA5__IPU1_CSI1_DATA04 0x1b0 0x580 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA5__GPIO3_IO05 0x1b0 0x580 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA5__SRC_BOOT_CFG05 0x1b0 0x580 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA5__EPDC_SDCE1 0x1b0 0x580 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_DA6__EIM_AD06 0x1b4 0x584 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA6__IPU1_DISP1_DATA03 0x1b4 0x584 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA6__IPU1_CSI1_DATA03 0x1b4 0x584 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA6__GPIO3_IO06 0x1b4 0x584 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA6__SRC_BOOT_CFG06 0x1b4 0x584 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA6__EPDC_SDCE2 0x1b4 0x584 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_DA7__EIM_AD07 0x1b8 0x588 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA7__IPU1_DISP1_DATA02 0x1b8 0x588 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA7__IPU1_CSI1_DATA02 0x1b8 0x588 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA7__GPIO3_IO07 0x1b8 0x588 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA7__SRC_BOOT_CFG07 0x1b8 0x588 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA7__EPDC_SDCE3 0x1b8 0x588 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_DA8__EIM_AD08 0x1bc 0x58c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA8__IPU1_DISP1_DATA01 0x1bc 0x58c 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA8__IPU1_CSI1_DATA01 0x1bc 0x58c 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA8__GPIO3_IO08 0x1bc 0x58c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA8__SRC_BOOT_CFG08 0x1bc 0x58c 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA8__EPDC_SDCE4 0x1bc 0x58c 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_DA9__EIM_AD09 0x1c0 0x590 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA9__IPU1_DISP1_DATA00 0x1c0 0x590 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA9__IPU1_CSI1_DATA00 0x1c0 0x590 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0x1c0 0x590 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA9__SRC_BOOT_CFG09 0x1c0 0x590 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA9__EPDC_SDCE5 0x1c0 0x590 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_EB0__EIM_EB0_B 0x1c4 0x594 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_EB0__IPU1_DISP1_DATA11 0x1c4 0x594 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_EB0__IPU1_CSI1_DATA11 0x1c4 0x594 0x88c 0x2 0x1
+#define MX6QDL_PAD_EIM_EB0__CCM_PMIC_READY 0x1c4 0x594 0x7d4 0x4 0x0
+#define MX6QDL_PAD_EIM_EB0__GPIO2_IO28 0x1c4 0x594 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_EB0__SRC_BOOT_CFG27 0x1c4 0x594 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_EB0__EPDC_PWR_COM 0x1c4 0x594 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_EB1__EIM_EB1_B 0x1c8 0x598 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_EB1__IPU1_DISP1_DATA10 0x1c8 0x598 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_EB1__IPU1_CSI1_DATA10 0x1c8 0x598 0x888 0x2 0x1
+#define MX6QDL_PAD_EIM_EB1__GPIO2_IO29 0x1c8 0x598 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_EB1__SRC_BOOT_CFG28 0x1c8 0x598 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_EB1__EPDC_SDSHR 0x1c8 0x598 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_EB2__EIM_EB2_B 0x1cc 0x59c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_EB2__ECSPI1_SS0 0x1cc 0x59c 0x7e4 0x1 0x2
+#define MX6QDL_PAD_EIM_EB2__IPU1_CSI1_DATA19 0x1cc 0x59c 0x8ac 0x3 0x1
+#define MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x1cc 0x59c 0x860 0x4 0x0
+#define MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1cc 0x59c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x1cc 0x59c 0x870 0x6 0x0
+#define MX6QDL_PAD_EIM_EB2__SRC_BOOT_CFG30 0x1cc 0x59c 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_EB2__EPDC_DATA05 0x1cc 0x59c 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_EB3__EIM_EB3_B 0x1d0 0x5a0 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_EB3__ECSPI4_RDY 0x1d0 0x5a0 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1d0 0x5a0 0x908 0x2 0x3
+#define MX6QDL_PAD_EIM_EB3__UART3_CTS_B 0x1d0 0x5a0 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_EB3__UART1_RI_B 0x1d0 0x5a0 0x000 0x3 0x0
+#define MX6QDL_PAD_EIM_EB3__IPU1_CSI1_HSYNC 0x1d0 0x5a0 0x8b4 0x4 0x1
+#define MX6QDL_PAD_EIM_EB3__GPIO2_IO31 0x1d0 0x5a0 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_EB3__IPU1_DI1_PIN03 0x1d0 0x5a0 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_EB3__SRC_BOOT_CFG31 0x1d0 0x5a0 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_EB3__EPDC_SDCE0 0x1d0 0x5a0 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_EB3__EIM_ACLK_FREERUN 0x1d0 0x5a0 0x000 0x9 0x0
+#define MX6QDL_PAD_EIM_LBA__EIM_LBA_B 0x1d4 0x5a4 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_LBA__IPU1_DI1_PIN17 0x1d4 0x5a4 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_LBA__ECSPI2_SS1 0x1d4 0x5a4 0x804 0x2 0x1
+#define MX6QDL_PAD_EIM_LBA__GPIO2_IO27 0x1d4 0x5a4 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_LBA__SRC_BOOT_CFG26 0x1d4 0x5a4 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_LBA__EPDC_DATA04 0x1d4 0x5a4 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_OE__EIM_OE_B 0x1d8 0x5a8 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_OE__IPU1_DI1_PIN07 0x1d8 0x5a8 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_OE__ECSPI2_MISO 0x1d8 0x5a8 0x7f8 0x2 0x2
+#define MX6QDL_PAD_EIM_OE__GPIO2_IO25 0x1d8 0x5a8 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_OE__EPDC_PWR_IRQ 0x1d8 0x5a8 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_RW__EIM_RW 0x1dc 0x5ac 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_RW__IPU1_DI1_PIN08 0x1dc 0x5ac 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_RW__ECSPI2_SS0 0x1dc 0x5ac 0x800 0x2 0x2
+#define MX6QDL_PAD_EIM_RW__GPIO2_IO26 0x1dc 0x5ac 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_RW__SRC_BOOT_CFG29 0x1dc 0x5ac 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_RW__EPDC_DATA07 0x1dc 0x5ac 0x000 0x8 0x0
+#define MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B 0x1e0 0x5b0 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_WAIT__EIM_DTACK_B 0x1e0 0x5b0 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_WAIT__GPIO5_IO00 0x1e0 0x5b0 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_WAIT__SRC_BOOT_CFG25 0x1e0 0x5b0 0x000 0x7 0x0
+#define MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN 0x1e4 0x5b4 0x828 0x1 0x0
+#define MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK 0x1e4 0x5b4 0x840 0x2 0x0
+#define MX6QDL_PAD_ENET_CRS_DV__SPDIF_EXT_CLK 0x1e4 0x5b4 0x8f4 0x3 0x0
+#define MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x1e4 0x5b4 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_MDC__MLB_DATA 0x1e8 0x5b8 0x8e0 0x0 0x0
+#define MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1e8 0x5b8 0x000 0x1 0x0
+#define MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0 0x1e8 0x5b8 0x858 0x2 0x0
+#define MX6QDL_PAD_ENET_MDC__ENET_1588_EVENT1_IN 0x1e8 0x5b8 0x000 0x4 0x0
+#define MX6QDL_PAD_ENET_MDC__GPIO1_IO31 0x1e8 0x5b8 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1ec 0x5bc 0x810 0x1 0x0
+#define MX6QDL_PAD_ENET_MDIO__ESAI_RX_CLK 0x1ec 0x5bc 0x83c 0x2 0x0
+#define MX6QDL_PAD_ENET_MDIO__ENET_1588_EVENT1_OUT 0x1ec 0x5bc 0x000 0x4 0x0
+#define MX6QDL_PAD_ENET_MDIO__GPIO1_IO22 0x1ec 0x5bc 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_MDIO__SPDIF_LOCK 0x1ec 0x5bc 0x000 0x6 0x0
+#define MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1f0 0x5c0 0x000 0x1 0x0
+#define MX6QDL_PAD_ENET_REF_CLK__ESAI_RX_FS 0x1f0 0x5c0 0x82c 0x2 0x0
+#define MX6QDL_PAD_ENET_REF_CLK__GPIO1_IO23 0x1f0 0x5c0 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_REF_CLK__SPDIF_SR_CLK 0x1f0 0x5c0 0x000 0x6 0x0
+#define MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x1f4 0x5c4 0x790 0x0 0x0
+#define MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER 0x1f4 0x5c4 0x000 0x1 0x0
+#define MX6QDL_PAD_ENET_RX_ER__ESAI_RX_HF_CLK 0x1f4 0x5c4 0x834 0x2 0x0
+#define MX6QDL_PAD_ENET_RX_ER__SPDIF_IN 0x1f4 0x5c4 0x8f0 0x3 0x1
+#define MX6QDL_PAD_ENET_RX_ER__ENET_1588_EVENT2_OUT 0x1f4 0x5c4 0x000 0x4 0x0
+#define MX6QDL_PAD_ENET_RX_ER__GPIO1_IO24 0x1f4 0x5c4 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0 0x1f8 0x5c8 0x818 0x1 0x0
+#define MX6QDL_PAD_ENET_RXD0__ESAI_TX_HF_CLK 0x1f8 0x5c8 0x838 0x2 0x0
+#define MX6QDL_PAD_ENET_RXD0__SPDIF_OUT 0x1f8 0x5c8 0x000 0x3 0x0
+#define MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x1f8 0x5c8 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_RXD1__MLB_SIG 0x1fc 0x5cc 0x8e4 0x0 0x0
+#define MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1 0x1fc 0x5cc 0x81c 0x1 0x0
+#define MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS 0x1fc 0x5cc 0x830 0x2 0x0
+#define MX6QDL_PAD_ENET_RXD1__ENET_1588_EVENT3_OUT 0x1fc 0x5cc 0x000 0x4 0x0
+#define MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x1fc 0x5cc 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x200 0x5d0 0x000 0x1 0x0
+#define MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2 0x200 0x5d0 0x850 0x2 0x0
+#define MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x200 0x5d0 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_TX_EN__I2C4_SCL 0x200 0x5d0 0x880 0x9 0x0
+#define MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0 0x204 0x5d4 0x000 0x1 0x0
+#define MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1 0x204 0x5d4 0x854 0x2 0x0
+#define MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x204 0x5d4 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_TXD1__MLB_CLK 0x208 0x5d8 0x8dc 0x0 0x0
+#define MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1 0x208 0x5d8 0x000 0x1 0x0
+#define MX6QDL_PAD_ENET_TXD1__ESAI_TX2_RX3 0x208 0x5d8 0x84c 0x2 0x0
+#define MX6QDL_PAD_ENET_TXD1__ENET_1588_EVENT0_IN 0x208 0x5d8 0x000 0x4 0x0
+#define MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x208 0x5d8 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_TXD1__I2C4_SDA 0x208 0x5d8 0x884 0x9 0x0
+#define MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x20c 0x5dc 0x000 0x0 0x0
+#define MX6QDL_PAD_GPIO_0__KEY_COL5 0x20c 0x5dc 0x8c0 0x2 0x1
+#define MX6QDL_PAD_GPIO_0__ASRC_EXT_CLK 0x20c 0x5dc 0x794 0x3 0x0
+#define MX6QDL_PAD_GPIO_0__EPIT1_OUT 0x20c 0x5dc 0x000 0x4 0x0
+#define MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x20c 0x5dc 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_0__USB_H1_PWR 0x20c 0x5dc 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_0__SNVS_VIO_5 0x20c 0x5dc 0x000 0x7 0x0
+#define MX6QDL_PAD_GPIO_1__ESAI_RX_CLK 0x210 0x5e0 0x83c 0x0 0x1
+#define MX6QDL_PAD_GPIO_1__WDOG2_B 0x210 0x5e0 0x000 0x1 0x0
+#define MX6QDL_PAD_GPIO_1__KEY_ROW5 0x210 0x5e0 0x8cc 0x2 0x1
+#define MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x210 0x5e0 0x790 0x3 0x1
+#define MX6QDL_PAD_GPIO_1__PWM2_OUT 0x210 0x5e0 0x000 0x4 0x0
+#define MX6QDL_PAD_GPIO_1__GPIO1_IO01 0x210 0x5e0 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_1__SD1_CD_B 0x210 0x5e0 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_16__ESAI_TX3_RX2 0x214 0x5e4 0x850 0x0 0x1
+#define MX6QDL_PAD_GPIO_16__ENET_1588_EVENT2_IN 0x214 0x5e4 0x000 0x1 0x0
+#define MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x214 0x5e4 0x80c 0x2 0x0
+#define MX6QDL_PAD_GPIO_16__SD1_LCTL 0x214 0x5e4 0x000 0x3 0x0
+#define MX6QDL_PAD_GPIO_16__SPDIF_IN 0x214 0x5e4 0x8f0 0x4 0x2
+#define MX6QDL_PAD_GPIO_16__GPIO7_IO11 0x214 0x5e4 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_16__I2C3_SDA 0x214 0x5e4 0x87c 0x6 0x1
+#define MX6QDL_PAD_GPIO_16__JTAG_DE_B 0x214 0x5e4 0x000 0x7 0x0
+#define MX6QDL_PAD_GPIO_17__ESAI_TX0 0x218 0x5e8 0x844 0x0 0x0
+#define MX6QDL_PAD_GPIO_17__ENET_1588_EVENT3_IN 0x218 0x5e8 0x000 0x1 0x0
+#define MX6QDL_PAD_GPIO_17__CCM_PMIC_READY 0x218 0x5e8 0x7d4 0x2 0x1
+#define MX6QDL_PAD_GPIO_17__SDMA_EXT_EVENT0 0x218 0x5e8 0x8e8 0x3 0x1
+#define MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x218 0x5e8 0x000 0x4 0x0
+#define MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x218 0x5e8 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_18__ESAI_TX1 0x21c 0x5ec 0x848 0x0 0x0
+#define MX6QDL_PAD_GPIO_18__ENET_RX_CLK 0x21c 0x5ec 0x814 0x1 0x0
+#define MX6QDL_PAD_GPIO_18__SD3_VSELECT 0x21c 0x5ec 0x000 0x2 0x0
+#define MX6QDL_PAD_GPIO_18__SDMA_EXT_EVENT1 0x21c 0x5ec 0x8ec 0x3 0x1
+#define MX6QDL_PAD_GPIO_18__ASRC_EXT_CLK 0x21c 0x5ec 0x794 0x4 0x1
+#define MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x21c 0x5ec 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_18__SNVS_VIO_5_CTL 0x21c 0x5ec 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_19__KEY_COL5 0x220 0x5f0 0x8c0 0x0 0x2
+#define MX6QDL_PAD_GPIO_19__ENET_1588_EVENT0_OUT 0x220 0x5f0 0x000 0x1 0x0
+#define MX6QDL_PAD_GPIO_19__SPDIF_OUT 0x220 0x5f0 0x000 0x2 0x0
+#define MX6QDL_PAD_GPIO_19__CCM_CLKO1 0x220 0x5f0 0x000 0x3 0x0
+#define MX6QDL_PAD_GPIO_19__ECSPI1_RDY 0x220 0x5f0 0x000 0x4 0x0
+#define MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x220 0x5f0 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_19__ENET_TX_ER 0x220 0x5f0 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_2__ESAI_TX_FS 0x224 0x5f4 0x830 0x0 0x1
+#define MX6QDL_PAD_GPIO_2__KEY_ROW6 0x224 0x5f4 0x8d0 0x2 0x1
+#define MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x224 0x5f4 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_2__SD2_WP 0x224 0x5f4 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_2__MLB_DATA 0x224 0x5f4 0x8e0 0x7 0x1
+#define MX6QDL_PAD_GPIO_3__ESAI_RX_HF_CLK 0x228 0x5f8 0x834 0x0 0x1
+#define MX6QDL_PAD_GPIO_3__I2C3_SCL 0x228 0x5f8 0x878 0x2 0x1
+#define MX6QDL_PAD_GPIO_3__XTALOSC_REF_CLK_24M 0x228 0x5f8 0x000 0x3 0x0
+#define MX6QDL_PAD_GPIO_3__CCM_CLKO2 0x228 0x5f8 0x000 0x4 0x0
+#define MX6QDL_PAD_GPIO_3__GPIO1_IO03 0x228 0x5f8 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_3__USB_H1_OC 0x228 0x5f8 0x924 0x6 0x1
+#define MX6QDL_PAD_GPIO_3__MLB_CLK 0x228 0x5f8 0x8dc 0x7 0x1
+#define MX6QDL_PAD_GPIO_4__ESAI_TX_HF_CLK 0x22c 0x5fc 0x838 0x0 0x1
+#define MX6QDL_PAD_GPIO_4__KEY_COL7 0x22c 0x5fc 0x8c8 0x2 0x1
+#define MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x22c 0x5fc 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_4__SD2_CD_B 0x22c 0x5fc 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_5__ESAI_TX2_RX3 0x230 0x600 0x84c 0x0 0x1
+#define MX6QDL_PAD_GPIO_5__KEY_ROW7 0x230 0x600 0x8d4 0x2 0x1
+#define MX6QDL_PAD_GPIO_5__CCM_CLKO1 0x230 0x600 0x000 0x3 0x0
+#define MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x230 0x600 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_5__I2C3_SCL 0x230 0x600 0x878 0x6 0x2
+#define MX6QDL_PAD_GPIO_5__ARM_EVENTI 0x230 0x600 0x000 0x7 0x0
+#define MX6QDL_PAD_GPIO_6__ESAI_TX_CLK 0x234 0x604 0x840 0x0 0x1
+#define MX6QDL_PAD_GPIO_6__ENET_IRQ 0x234 0x604 0x03c 0x11 0xff000609
+#define MX6QDL_PAD_GPIO_6__I2C3_SDA 0x234 0x604 0x87c 0x2 0x2
+#define MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x234 0x604 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_6__SD2_LCTL 0x234 0x604 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_6__MLB_SIG 0x234 0x604 0x8e4 0x7 0x1
+#define MX6QDL_PAD_GPIO_7__ESAI_TX4_RX1 0x238 0x608 0x854 0x0 0x1
+#define MX6QDL_PAD_GPIO_7__EPIT1_OUT 0x238 0x608 0x000 0x2 0x0
+#define MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x238 0x608 0x000 0x3 0x0
+#define MX6QDL_PAD_GPIO_7__UART2_TX_DATA 0x238 0x608 0x000 0x4 0x0
+#define MX6QDL_PAD_GPIO_7__UART2_RX_DATA 0x238 0x608 0x904 0x4 0x2
+#define MX6QDL_PAD_GPIO_7__GPIO1_IO07 0x238 0x608 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_7__SPDIF_LOCK 0x238 0x608 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_7__USB_OTG_HOST_MODE 0x238 0x608 0x000 0x7 0x0
+#define MX6QDL_PAD_GPIO_7__I2C4_SCL 0x238 0x608 0x880 0x8 0x1
+#define MX6QDL_PAD_GPIO_8__ESAI_TX5_RX0 0x23c 0x60c 0x858 0x0 0x1
+#define MX6QDL_PAD_GPIO_8__XTALOSC_REF_CLK_32K 0x23c 0x60c 0x000 0x1 0x0
+#define MX6QDL_PAD_GPIO_8__EPIT2_OUT 0x23c 0x60c 0x000 0x2 0x0
+#define MX6QDL_PAD_GPIO_8__FLEXCAN1_RX 0x23c 0x60c 0x7c8 0x3 0x0
+#define MX6QDL_PAD_GPIO_8__UART2_RX_DATA 0x23c 0x60c 0x904 0x4 0x3
+#define MX6QDL_PAD_GPIO_8__UART2_TX_DATA 0x23c 0x60c 0x000 0x4 0x0
+#define MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x23c 0x60c 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_8__SPDIF_SR_CLK 0x23c 0x60c 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_8__USB_OTG_PWR_CTL_WAKE 0x23c 0x60c 0x000 0x7 0x0
+#define MX6QDL_PAD_GPIO_8__I2C4_SDA 0x23c 0x60c 0x884 0x8 0x1
+#define MX6QDL_PAD_GPIO_9__ESAI_RX_FS 0x240 0x610 0x82c 0x0 0x1
+#define MX6QDL_PAD_GPIO_9__WDOG1_B 0x240 0x610 0x000 0x1 0x0
+#define MX6QDL_PAD_GPIO_9__KEY_COL6 0x240 0x610 0x8c4 0x2 0x1
+#define MX6QDL_PAD_GPIO_9__CCM_REF_EN_B 0x240 0x610 0x000 0x3 0x0
+#define MX6QDL_PAD_GPIO_9__PWM1_OUT 0x240 0x610 0x000 0x4 0x0
+#define MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x240 0x610 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_9__SD1_WP 0x240 0x610 0x92c 0x6 0x1
+#define MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK 0x244 0x62c 0x7d8 0x0 0x3
+#define MX6QDL_PAD_KEY_COL0__ENET_RX_DATA3 0x244 0x62c 0x824 0x1 0x0
+#define MX6QDL_PAD_KEY_COL0__AUD5_TXC 0x244 0x62c 0x7c0 0x2 0x1
+#define MX6QDL_PAD_KEY_COL0__KEY_COL0 0x244 0x62c 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x244 0x62c 0x000 0x4 0x0
+#define MX6QDL_PAD_KEY_COL0__UART4_RX_DATA 0x244 0x62c 0x914 0x4 0x2
+#define MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x244 0x62c 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_COL0__DCIC1_OUT 0x244 0x62c 0x000 0x6 0x0
+#define MX6QDL_PAD_KEY_COL1__ECSPI1_MISO 0x248 0x630 0x7dc 0x0 0x3
+#define MX6QDL_PAD_KEY_COL1__ENET_MDIO 0x248 0x630 0x810 0x1 0x1
+#define MX6QDL_PAD_KEY_COL1__AUD5_TXFS 0x248 0x630 0x7c4 0x2 0x1
+#define MX6QDL_PAD_KEY_COL1__KEY_COL1 0x248 0x630 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x248 0x630 0x000 0x4 0x0
+#define MX6QDL_PAD_KEY_COL1__UART5_RX_DATA 0x248 0x630 0x91c 0x4 0x2
+#define MX6QDL_PAD_KEY_COL1__GPIO4_IO08 0x248 0x630 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_COL1__SD1_VSELECT 0x248 0x630 0x000 0x6 0x0
+#define MX6QDL_PAD_KEY_COL2__ECSPI1_SS1 0x24c 0x634 0x7e8 0x0 0x2
+#define MX6QDL_PAD_KEY_COL2__ENET_RX_DATA2 0x24c 0x634 0x820 0x1 0x0
+#define MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x24c 0x634 0x000 0x2 0x0
+#define MX6QDL_PAD_KEY_COL2__KEY_COL2 0x24c 0x634 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_COL2__ENET_MDC 0x24c 0x634 0x000 0x4 0x0
+#define MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x24c 0x634 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_COL2__USB_H1_PWR_CTL_WAKE 0x24c 0x634 0x000 0x6 0x0
+#define MX6QDL_PAD_KEY_COL3__ECSPI1_SS3 0x250 0x638 0x7f0 0x0 0x1
+#define MX6QDL_PAD_KEY_COL3__ENET_CRS 0x250 0x638 0x000 0x1 0x0
+#define MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x250 0x638 0x860 0x2 0x1
+#define MX6QDL_PAD_KEY_COL3__KEY_COL3 0x250 0x638 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x250 0x638 0x870 0x4 0x1
+#define MX6QDL_PAD_KEY_COL3__GPIO4_IO12 0x250 0x638 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_COL3__SPDIF_IN 0x250 0x638 0x8f0 0x6 0x3
+#define MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x254 0x63c 0x000 0x0 0x0
+#define MX6QDL_PAD_KEY_COL4__IPU1_SISG4 0x254 0x63c 0x000 0x1 0x0
+#define MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x254 0x63c 0x920 0x2 0x1
+#define MX6QDL_PAD_KEY_COL4__KEY_COL4 0x254 0x63c 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_COL4__UART5_RTS_B 0x254 0x63c 0x918 0x4 0x2
+#define MX6QDL_PAD_KEY_COL4__UART5_CTS_B 0x254 0x63c 0x000 0x4 0x0
+#define MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x254 0x63c 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI 0x258 0x640 0x7e0 0x0 0x3
+#define MX6QDL_PAD_KEY_ROW0__ENET_TX_DATA3 0x258 0x640 0x000 0x1 0x0
+#define MX6QDL_PAD_KEY_ROW0__AUD5_TXD 0x258 0x640 0x7b4 0x2 0x1
+#define MX6QDL_PAD_KEY_ROW0__KEY_ROW0 0x258 0x640 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x258 0x640 0x914 0x4 0x3
+#define MX6QDL_PAD_KEY_ROW0__UART4_TX_DATA 0x258 0x640 0x000 0x4 0x0
+#define MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x258 0x640 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_ROW0__DCIC2_OUT 0x258 0x640 0x000 0x6 0x0
+#define MX6QDL_PAD_KEY_ROW1__ECSPI1_SS0 0x25c 0x644 0x7e4 0x0 0x3
+#define MX6QDL_PAD_KEY_ROW1__ENET_COL 0x25c 0x644 0x000 0x1 0x0
+#define MX6QDL_PAD_KEY_ROW1__AUD5_RXD 0x25c 0x644 0x7b0 0x2 0x1
+#define MX6QDL_PAD_KEY_ROW1__KEY_ROW1 0x25c 0x644 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x25c 0x644 0x91c 0x4 0x3
+#define MX6QDL_PAD_KEY_ROW1__UART5_TX_DATA 0x25c 0x644 0x000 0x4 0x0
+#define MX6QDL_PAD_KEY_ROW1__GPIO4_IO09 0x25c 0x644 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_ROW1__SD2_VSELECT 0x25c 0x644 0x000 0x6 0x0
+#define MX6QDL_PAD_KEY_ROW2__ECSPI1_SS2 0x260 0x648 0x7ec 0x0 0x1
+#define MX6QDL_PAD_KEY_ROW2__ENET_TX_DATA2 0x260 0x648 0x000 0x1 0x0
+#define MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x260 0x648 0x7c8 0x2 0x1
+#define MX6QDL_PAD_KEY_ROW2__KEY_ROW2 0x260 0x648 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_ROW2__SD2_VSELECT 0x260 0x648 0x000 0x4 0x0
+#define MX6QDL_PAD_KEY_ROW2__GPIO4_IO11 0x260 0x648 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x260 0x648 0x85c 0x6 0x1
+#define MX6QDL_PAD_KEY_ROW3__ASRC_EXT_CLK 0x264 0x64c 0x794 0x1 0x2
+#define MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x264 0x64c 0x864 0x2 0x1
+#define MX6QDL_PAD_KEY_ROW3__KEY_ROW3 0x264 0x64c 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x264 0x64c 0x874 0x4 0x1
+#define MX6QDL_PAD_KEY_ROW3__GPIO4_IO13 0x264 0x64c 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_ROW3__SD1_VSELECT 0x264 0x64c 0x000 0x6 0x0
+#define MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x268 0x650 0x7cc 0x0 0x0
+#define MX6QDL_PAD_KEY_ROW4__IPU1_SISG5 0x268 0x650 0x000 0x1 0x0
+#define MX6QDL_PAD_KEY_ROW4__USB_OTG_PWR 0x268 0x650 0x000 0x2 0x0
+#define MX6QDL_PAD_KEY_ROW4__KEY_ROW4 0x268 0x650 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_ROW4__UART5_CTS_B 0x268 0x650 0x000 0x4 0x0
+#define MX6QDL_PAD_KEY_ROW4__UART5_RTS_B 0x268 0x650 0x918 0x4 0x3
+#define MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x268 0x650 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_ALE__NAND_ALE 0x26c 0x654 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_ALE__SD4_RESET 0x26c 0x654 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_ALE__GPIO6_IO08 0x26c 0x654 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_CLE__NAND_CLE 0x270 0x658 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x270 0x658 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0x274 0x65c 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x274 0x65c 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0x278 0x660 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_CS1__SD4_VSELECT 0x278 0x660 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_CS1__SD3_VSELECT 0x278 0x660 0x000 0x2 0x0
+#define MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x278 0x660 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_CS2__NAND_CE2_B 0x27c 0x664 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_CS2__IPU1_SISG0 0x27c 0x664 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_CS2__ESAI_TX0 0x27c 0x664 0x844 0x2 0x1
+#define MX6QDL_PAD_NANDF_CS2__EIM_CRE 0x27c 0x664 0x000 0x3 0x0
+#define MX6QDL_PAD_NANDF_CS2__CCM_CLKO2 0x27c 0x664 0x000 0x4 0x0
+#define MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x27c 0x664 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_CS3__NAND_CE3_B 0x280 0x668 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_CS3__IPU1_SISG1 0x280 0x668 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_CS3__ESAI_TX1 0x280 0x668 0x848 0x2 0x1
+#define MX6QDL_PAD_NANDF_CS3__EIM_ADDR26 0x280 0x668 0x000 0x3 0x0
+#define MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x280 0x668 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_CS3__I2C4_SDA 0x280 0x668 0x884 0x9 0x2
+#define MX6QDL_PAD_NANDF_D0__NAND_DATA00 0x284 0x66c 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_D0__SD1_DATA4 0x284 0x66c 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x284 0x66c 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_D1__NAND_DATA01 0x288 0x670 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_D1__SD1_DATA5 0x288 0x670 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x288 0x670 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_D2__NAND_DATA02 0x28c 0x674 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_D2__SD1_DATA6 0x28c 0x674 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x28c 0x674 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_D3__NAND_DATA03 0x290 0x678 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_D3__SD1_DATA7 0x290 0x678 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x290 0x678 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_D4__NAND_DATA04 0x294 0x67c 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_D4__SD2_DATA4 0x294 0x67c 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x294 0x67c 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_D5__NAND_DATA05 0x298 0x680 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_D5__SD2_DATA5 0x298 0x680 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x298 0x680 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_D6__NAND_DATA06 0x29c 0x684 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_D6__SD2_DATA6 0x29c 0x684 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x29c 0x684 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_D7__NAND_DATA07 0x2a0 0x688 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_D7__SD2_DATA7 0x2a0 0x688 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_D7__GPIO2_IO07 0x2a0 0x688 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0x2a4 0x68c 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_RB0__GPIO6_IO10 0x2a4 0x68c 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0x2a8 0x690 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_WP_B__GPIO6_IO09 0x2a8 0x690 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_WP_B__I2C4_SCL 0x2a8 0x690 0x880 0x9 0x2
+#define MX6QDL_PAD_RGMII_RD0__HSI_RX_READY 0x2ac 0x694 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x2ac 0x694 0x818 0x1 0x1
+#define MX6QDL_PAD_RGMII_RD0__GPIO6_IO25 0x2ac 0x694 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_RD1__HSI_TX_FLAG 0x2b0 0x698 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x2b0 0x698 0x81c 0x1 0x1
+#define MX6QDL_PAD_RGMII_RD1__GPIO6_IO27 0x2b0 0x698 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_RD2__HSI_TX_DATA 0x2b4 0x69c 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x2b4 0x69c 0x820 0x1 0x1
+#define MX6QDL_PAD_RGMII_RD2__GPIO6_IO28 0x2b4 0x69c 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_RD3__HSI_TX_WAKE 0x2b8 0x6a0 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x2b8 0x6a0 0x824 0x1 0x1
+#define MX6QDL_PAD_RGMII_RD3__GPIO6_IO29 0x2b8 0x6a0 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_RX_CTL__USB_H3_DATA 0x2bc 0x6a4 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x2bc 0x6a4 0x828 0x1 0x1
+#define MX6QDL_PAD_RGMII_RX_CTL__GPIO6_IO24 0x2bc 0x6a4 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_RXC__USB_H3_STROBE 0x2c0 0x6a8 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x2c0 0x6a8 0x814 0x1 0x1
+#define MX6QDL_PAD_RGMII_RXC__GPIO6_IO30 0x2c0 0x6a8 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_TD0__HSI_TX_READY 0x2c4 0x6ac 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x2c4 0x6ac 0x000 0x1 0x0
+#define MX6QDL_PAD_RGMII_TD0__GPIO6_IO20 0x2c4 0x6ac 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_TD1__HSI_RX_FLAG 0x2c8 0x6b0 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x2c8 0x6b0 0x000 0x1 0x0
+#define MX6QDL_PAD_RGMII_TD1__GPIO6_IO21 0x2c8 0x6b0 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_TD2__HSI_RX_DATA 0x2cc 0x6b4 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x2cc 0x6b4 0x000 0x1 0x0
+#define MX6QDL_PAD_RGMII_TD2__GPIO6_IO22 0x2cc 0x6b4 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_TD3__HSI_RX_WAKE 0x2d0 0x6b8 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x2d0 0x6b8 0x000 0x1 0x0
+#define MX6QDL_PAD_RGMII_TD3__GPIO6_IO23 0x2d0 0x6b8 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_TX_CTL__USB_H2_STROBE 0x2d4 0x6bc 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x2d4 0x6bc 0x000 0x1 0x0
+#define MX6QDL_PAD_RGMII_TX_CTL__GPIO6_IO26 0x2d4 0x6bc 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_TX_CTL__ENET_REF_CLK 0x2d4 0x6bc 0x80c 0x7 0x1
+#define MX6QDL_PAD_RGMII_TXC__USB_H2_DATA 0x2d8 0x6c0 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x2d8 0x6c0 0x000 0x1 0x0
+#define MX6QDL_PAD_RGMII_TXC__SPDIF_EXT_CLK 0x2d8 0x6c0 0x8f4 0x2 0x1
+#define MX6QDL_PAD_RGMII_TXC__GPIO6_IO19 0x2d8 0x6c0 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_TXC__XTALOSC_REF_CLK_24M 0x2d8 0x6c0 0x000 0x7 0x0
+#define MX6QDL_PAD_SD1_CLK__SD1_CLK 0x2dc 0x6c4 0x928 0x0 0x1
+#define MX6QDL_PAD_SD1_CLK__OSC32K_32K_OUT 0x2dc 0x6c4 0x000 0x2 0x0
+#define MX6QDL_PAD_SD1_CLK__GPT_CLKIN 0x2dc 0x6c4 0x000 0x3 0x0
+#define MX6QDL_PAD_SD1_CLK__GPIO1_IO20 0x2dc 0x6c4 0x000 0x5 0x0
+#define MX6QDL_PAD_SD1_CMD__SD1_CMD 0x2e0 0x6c8 0x000 0x0 0x0
+#define MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x2e0 0x6c8 0x000 0x2 0x0
+#define MX6QDL_PAD_SD1_CMD__GPT_COMPARE1 0x2e0 0x6c8 0x000 0x3 0x0
+#define MX6QDL_PAD_SD1_CMD__GPIO1_IO18 0x2e0 0x6c8 0x000 0x5 0x0
+#define MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x2e4 0x6cc 0x000 0x0 0x0
+#define MX6QDL_PAD_SD1_DAT0__GPT_CAPTURE1 0x2e4 0x6cc 0x000 0x3 0x0
+#define MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x2e4 0x6cc 0x000 0x5 0x0
+#define MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x2e8 0x6d0 0x000 0x0 0x0
+#define MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x2e8 0x6d0 0x000 0x2 0x0
+#define MX6QDL_PAD_SD1_DAT1__GPT_CAPTURE2 0x2e8 0x6d0 0x000 0x3 0x0
+#define MX6QDL_PAD_SD1_DAT1__GPIO1_IO17 0x2e8 0x6d0 0x000 0x5 0x0
+#define MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x2ec 0x6d4 0x000 0x0 0x0
+#define MX6QDL_PAD_SD1_DAT2__GPT_COMPARE2 0x2ec 0x6d4 0x000 0x2 0x0
+#define MX6QDL_PAD_SD1_DAT2__PWM2_OUT 0x2ec 0x6d4 0x000 0x3 0x0
+#define MX6QDL_PAD_SD1_DAT2__WDOG1_B 0x2ec 0x6d4 0x000 0x4 0x0
+#define MX6QDL_PAD_SD1_DAT2__GPIO1_IO19 0x2ec 0x6d4 0x000 0x5 0x0
+#define MX6QDL_PAD_SD1_DAT2__WDOG1_RESET_B_DEB 0x2ec 0x6d4 0x000 0x6 0x0
+#define MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x2f0 0x6d8 0x000 0x0 0x0
+#define MX6QDL_PAD_SD1_DAT3__GPT_COMPARE3 0x2f0 0x6d8 0x000 0x2 0x0
+#define MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x2f0 0x6d8 0x000 0x3 0x0
+#define MX6QDL_PAD_SD1_DAT3__WDOG2_B 0x2f0 0x6d8 0x000 0x4 0x0
+#define MX6QDL_PAD_SD1_DAT3__GPIO1_IO21 0x2f0 0x6d8 0x000 0x5 0x0
+#define MX6QDL_PAD_SD1_DAT3__WDOG2_RESET_B_DEB 0x2f0 0x6d8 0x000 0x6 0x0
+#define MX6QDL_PAD_SD2_CLK__SD2_CLK 0x2f4 0x6dc 0x930 0x0 0x1
+#define MX6QDL_PAD_SD2_CLK__KEY_COL5 0x2f4 0x6dc 0x8c0 0x2 0x3
+#define MX6QDL_PAD_SD2_CLK__AUD4_RXFS 0x2f4 0x6dc 0x7a4 0x3 0x1
+#define MX6QDL_PAD_SD2_CLK__GPIO1_IO10 0x2f4 0x6dc 0x000 0x5 0x0
+#define MX6QDL_PAD_SD2_CMD__SD2_CMD 0x2f8 0x6e0 0x000 0x0 0x0
+#define MX6QDL_PAD_SD2_CMD__KEY_ROW5 0x2f8 0x6e0 0x8cc 0x2 0x2
+#define MX6QDL_PAD_SD2_CMD__AUD4_RXC 0x2f8 0x6e0 0x7a0 0x3 0x1
+#define MX6QDL_PAD_SD2_CMD__GPIO1_IO11 0x2f8 0x6e0 0x000 0x5 0x0
+#define MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x2fc 0x6e4 0x000 0x0 0x0
+#define MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x2fc 0x6e4 0x798 0x3 0x1
+#define MX6QDL_PAD_SD2_DAT0__KEY_ROW7 0x2fc 0x6e4 0x8d4 0x4 0x2
+#define MX6QDL_PAD_SD2_DAT0__GPIO1_IO15 0x2fc 0x6e4 0x000 0x5 0x0
+#define MX6QDL_PAD_SD2_DAT0__DCIC2_OUT 0x2fc 0x6e4 0x000 0x6 0x0
+#define MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x300 0x6e8 0x000 0x0 0x0
+#define MX6QDL_PAD_SD2_DAT1__EIM_CS2_B 0x300 0x6e8 0x000 0x2 0x0
+#define MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x300 0x6e8 0x7ac 0x3 0x1
+#define MX6QDL_PAD_SD2_DAT1__KEY_COL7 0x300 0x6e8 0x8c8 0x4 0x2
+#define MX6QDL_PAD_SD2_DAT1__GPIO1_IO14 0x300 0x6e8 0x000 0x5 0x0
+#define MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x304 0x6ec 0x000 0x0 0x0
+#define MX6QDL_PAD_SD2_DAT2__EIM_CS3_B 0x304 0x6ec 0x000 0x2 0x0
+#define MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x304 0x6ec 0x79c 0x3 0x1
+#define MX6QDL_PAD_SD2_DAT2__KEY_ROW6 0x304 0x6ec 0x8d0 0x4 0x2
+#define MX6QDL_PAD_SD2_DAT2__GPIO1_IO13 0x304 0x6ec 0x000 0x5 0x0
+#define MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x308 0x6f0 0x000 0x0 0x0
+#define MX6QDL_PAD_SD2_DAT3__KEY_COL6 0x308 0x6f0 0x8c4 0x2 0x2
+#define MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x308 0x6f0 0x7a8 0x3 0x1
+#define MX6QDL_PAD_SD2_DAT3__GPIO1_IO12 0x308 0x6f0 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_CLK__SD3_CLK 0x30c 0x6f4 0x934 0x0 0x1
+#define MX6QDL_PAD_SD3_CLK__UART2_RTS_B 0x30c 0x6f4 0x900 0x1 0x2
+#define MX6QDL_PAD_SD3_CLK__UART2_CTS_B 0x30c 0x6f4 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_CLK__FLEXCAN1_RX 0x30c 0x6f4 0x7c8 0x2 0x2
+#define MX6QDL_PAD_SD3_CLK__GPIO7_IO03 0x30c 0x6f4 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_CMD__SD3_CMD 0x310 0x6f8 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_CMD__UART2_CTS_B 0x310 0x6f8 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_CMD__UART2_RTS_B 0x310 0x6f8 0x900 0x1 0x3
+#define MX6QDL_PAD_SD3_CMD__FLEXCAN1_TX 0x310 0x6f8 0x000 0x2 0x0
+#define MX6QDL_PAD_SD3_CMD__GPIO7_IO02 0x310 0x6f8 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x314 0x6fc 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_DAT0__UART1_CTS_B 0x314 0x6fc 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_DAT0__UART1_RTS_B 0x314 0x6fc 0x8f8 0x1 0x2
+#define MX6QDL_PAD_SD3_DAT0__FLEXCAN2_TX 0x314 0x6fc 0x000 0x2 0x0
+#define MX6QDL_PAD_SD3_DAT0__GPIO7_IO04 0x314 0x6fc 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x318 0x700 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_DAT1__UART1_RTS_B 0x318 0x700 0x8f8 0x1 0x3
+#define MX6QDL_PAD_SD3_DAT1__UART1_CTS_B 0x318 0x700 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_DAT1__FLEXCAN2_RX 0x318 0x700 0x7cc 0x2 0x1
+#define MX6QDL_PAD_SD3_DAT1__GPIO7_IO05 0x318 0x700 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x31c 0x704 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_DAT2__GPIO7_IO06 0x31c 0x704 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x320 0x708 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_DAT3__UART3_CTS_B 0x320 0x708 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_DAT3__UART3_RTS_B 0x320 0x708 0x908 0x1 0x4
+#define MX6QDL_PAD_SD3_DAT3__GPIO7_IO07 0x320 0x708 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x324 0x70c 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_DAT4__UART2_RX_DATA 0x324 0x70c 0x904 0x1 0x4
+#define MX6QDL_PAD_SD3_DAT4__UART2_TX_DATA 0x324 0x70c 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x324 0x70c 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x328 0x710 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_DAT5__UART2_TX_DATA 0x328 0x710 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_DAT5__UART2_RX_DATA 0x328 0x710 0x904 0x1 0x5
+#define MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x328 0x710 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x32c 0x714 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x32c 0x714 0x8fc 0x1 0x2
+#define MX6QDL_PAD_SD3_DAT6__UART1_TX_DATA 0x32c 0x714 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_DAT6__GPIO6_IO18 0x32c 0x714 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x330 0x718 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x330 0x718 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_DAT7__UART1_RX_DATA 0x330 0x718 0x8fc 0x1 0x3
+#define MX6QDL_PAD_SD3_DAT7__GPIO6_IO17 0x330 0x718 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_RST__SD3_RESET 0x334 0x71c 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_RST__UART3_RTS_B 0x334 0x71c 0x908 0x1 0x5
+#define MX6QDL_PAD_SD3_RST__UART3_CTS_B 0x334 0x71c 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x334 0x71c 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_CLK__SD4_CLK 0x338 0x720 0x938 0x0 0x1
+#define MX6QDL_PAD_SD4_CLK__NAND_WE_B 0x338 0x720 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_CLK__UART3_RX_DATA 0x338 0x720 0x90c 0x2 0x2
+#define MX6QDL_PAD_SD4_CLK__UART3_TX_DATA 0x338 0x720 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_CLK__GPIO7_IO10 0x338 0x720 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_CMD__SD4_CMD 0x33c 0x724 0x000 0x0 0x0
+#define MX6QDL_PAD_SD4_CMD__NAND_RE_B 0x33c 0x724 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_CMD__UART3_TX_DATA 0x33c 0x724 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_CMD__UART3_RX_DATA 0x33c 0x724 0x90c 0x2 0x3
+#define MX6QDL_PAD_SD4_CMD__GPIO7_IO09 0x33c 0x724 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x340 0x728 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x340 0x728 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_DAT0__GPIO2_IO08 0x340 0x728 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x344 0x72c 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x344 0x72c 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_DAT1__GPIO2_IO09 0x344 0x72c 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x348 0x730 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_DAT2__PWM4_OUT 0x348 0x730 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_DAT2__GPIO2_IO10 0x348 0x730 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x34c 0x734 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_DAT3__GPIO2_IO11 0x34c 0x734 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x350 0x738 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x350 0x738 0x904 0x2 0x6
+#define MX6QDL_PAD_SD4_DAT4__UART2_TX_DATA 0x350 0x738 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_DAT4__GPIO2_IO12 0x350 0x738 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x354 0x73c 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_DAT5__UART2_RTS_B 0x354 0x73c 0x900 0x2 0x4
+#define MX6QDL_PAD_SD4_DAT5__UART2_CTS_B 0x354 0x73c 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_DAT5__GPIO2_IO13 0x354 0x73c 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x358 0x740 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_DAT6__UART2_CTS_B 0x358 0x740 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_DAT6__UART2_RTS_B 0x358 0x740 0x900 0x2 0x5
+#define MX6QDL_PAD_SD4_DAT6__GPIO2_IO14 0x358 0x740 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x35c 0x744 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x35c 0x744 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_DAT7__UART2_RX_DATA 0x35c 0x744 0x904 0x2 0x7
+#define MX6QDL_PAD_SD4_DAT7__GPIO2_IO15 0x35c 0x744 0x000 0x5 0x0
+
+#endif /* __DTS_IMX6DL_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx6dl-rex-basic.dts b/arch/arm/boot/dts/imx6dl-rex-basic.dts
new file mode 100644
index 000000000..b13845c28
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-rex-basic.dts
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2014 FEDEVEL, Inc.
+ *
+ * Author: Robert Nelson <robertcnelson@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.
+ *
+ */
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-rex.dtsi"
+
+/ {
+ model = "Rex Basic i.MX6 Dual Lite Board";
+ compatible = "rex,imx6dl-rex-basic", "fsl,imx6dl";
+
+ memory {
+ reg = <0x10000000 0x20000000>;
+ };
+};
+
+&ecspi3 {
+ flash: m25p80@0 {
+ compatible = "sst,sst25vf016b";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6dl-riotboard.dts b/arch/arm/boot/dts/imx6dl-riotboard.dts
new file mode 100644
index 000000000..43cb3fd76
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-riotboard.dts
@@ -0,0 +1,538 @@
+/*
+ * Copyright 2014 Iain Paton <ipaton0@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.
+ *
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "RIoTboard i.MX6S";
+ compatible = "riot,imx6s-riotboard", "fsl,imx6dl";
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_2p5v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "2P5V";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ };
+
+ reg_3p3v: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_usb_otg_vbus: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 0>;
+ enable-active-high;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_led>;
+
+ led0: user1 {
+ label = "user1";
+ gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+
+ led1: user2 {
+ label = "user2";
+ gpios = <&gpio3 28 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx-audio-sgtl5000";
+ model = "imx6-riotboard-sgtl5000";
+ ssi-controller = <&ssi1>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <1>;
+ mux-ext-port = <3>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio3 31 0>;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c2>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&clks 201>;
+ VDDA-supply = <&reg_2p5v>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+
+ pmic: pf0100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <16 8>;
+
+ regulators {
+ reg_vddcore: sw1ab { /* VDDARM_IN */
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-always-on;
+ };
+
+ reg_vddsoc: sw1c { /* VDDSOC_IN */
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-always-on;
+ };
+
+ reg_gen_3v3: sw2 { /* VDDHIGH_IN */
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_ddr_1v5a: sw3a { /* NVCC_DRAM, NVCC_RGMII */
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-always-on;
+ };
+
+ reg_ddr_1v5b: sw3b { /* NVCC_DRAM, NVCC_RGMII */
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-always-on;
+ };
+
+ reg_ddr_vtt: sw4 { /* MIPI conn */
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-always-on;
+ };
+
+ reg_5v_600mA: swbst { /* not used */
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ reg_snvs_3v: vsnvs { /* VDD_SNVS_IN */
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr { /* VREF_DDR */
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_vgen1_1v5: vgen1 { /* not used */
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ reg_vgen2_1v2_eth: vgen2 { /* pcie ? */
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ reg_vgen3_2v8: vgen3 { /* not used */
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ reg_vgen4_1v8: vgen4 { /* NVCC_SD3 */
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_vgen5_2v5_sgtl: vgen5 { /* Pwr LED & 5V0_delayed enable */
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_vgen6_3v3: vgen6 { /* #V#_DELAYED enable, MIPI */
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&i2c4 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ clocks = <&clks 116>;
+ status = "okay";
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm2>;
+ status = "okay";
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>;
+ status = "okay";
+};
+
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4>;
+ status = "okay";
+};
+
+&ssi1 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ status = "okay";
+};
+
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5>;
+ status = "okay";
+};
+
+&usbh1 {
+ dr_mode = "host";
+ disable-over-current;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ cd-gpios = <&gpio1 4 0>;
+ wp-gpios = <&gpio1 2 0>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ cd-gpios = <&gpio7 0 0>;
+ wp-gpios = <&gpio7 1 0>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ vmmc-supply = <&reg_3p3v>;
+ non-removable;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+
+ imx6-riotboard {
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
+ MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
+ MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0
+ MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0 /* CAM_MCLK */
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
+ MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
+ MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
+ MX6QDL_PAD_DISP0_DAT23__GPIO5_IO17 0x000b1 /* CS0 */
+ >;
+ };
+
+ pinctrl_ecspi2: ecspi2grp {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09 0x000b1 /* CS1 */
+ MX6QDL_PAD_DISP0_DAT16__ECSPI2_MOSI 0x100b1
+ MX6QDL_PAD_DISP0_DAT17__ECSPI2_MISO 0x100b1
+ MX6QDL_PAD_DISP0_DAT18__GPIO5_IO12 0x000b1 /* CS0 */
+ MX6QDL_PAD_DISP0_DAT19__ECSPI2_SCLK 0x100b1
+ >;
+ };
+
+ pinctrl_ecspi3: ecspi3grp {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
+ MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
+ MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
+ MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x000b1 /* CS0 */
+ MX6QDL_PAD_DISP0_DAT4__GPIO4_IO25 0x000b1 /* CS1 */
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x0a0b1 /* AR8035 CLK_25M --> ENET_REF_CLK (V22) */
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 /* AR8035 pin strapping: IO voltage: pull up */
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x130b0 /* AR8035 pin strapping: PHYADDR#0: pull down */
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x130b0 /* AR8035 pin strapping: PHYADDR#1: pull down */
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 /* AR8035 pin strapping: MODE#1: pull up */
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 /* AR8035 pin strapping: MODE#3: pull up */
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x130b0 /* AR8035 pin strapping: MODE#0: pull down */
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8 /* GPIO16 -> AR8035 25MHz */
+ MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x130b0 /* RGMII_nRST */
+ MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x180b0 /* AR8035 interrupt */
+ MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
+ MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_7__I2C4_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_8__I2C4_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_led: ledgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x1b0b1 /* user led0 */
+ MX6QDL_PAD_EIM_D28__GPIO3_IO28 0x1b0b1 /* user led1 */
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT8__PWM1_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm2: pwm2grp {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT9__PWM2_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm4: pwm4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5: uart5grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x000b0 /* MX6QDL_PAD_EIM_D22__USB_OTG_PWR */
+ MX6QDL_PAD_EIM_D21__USB_OTG_OC 0x1b0b0
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1b0b0 /* SD2 CD */
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1f0b0 /* SD2 WP */
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 /* SD3 CD */
+ MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x1f0b0 /* SD3 WP */
+ >;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
+ MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
+ MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
+ MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
+ MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
+ MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
+ MX6QDL_PAD_NANDF_ALE__GPIO6_IO08 0x17059 /* SD4 RST (eMMC) */
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6dl-sabreauto.dts b/arch/arm/boot/dts/imx6dl-sabreauto.dts
new file mode 100644
index 000000000..a6ce7b487
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-sabreauto.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-sabreauto.dtsi"
+
+/ {
+ model = "Freescale i.MX6 DualLite/Solo SABRE Automotive Board";
+ compatible = "fsl,imx6dl-sabreauto", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-sabrelite.dts b/arch/arm/boot/dts/imx6dl-sabrelite.dts
new file mode 100644
index 000000000..2de04479d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-sabrelite.dts
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-sabrelite.dtsi"
+
+/ {
+ model = "Freescale i.MX6 DualLite SABRE Lite Board";
+ compatible = "fsl,imx6dl-sabrelite", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-sabresd.dts b/arch/arm/boot/dts/imx6dl-sabresd.dts
new file mode 100644
index 000000000..1e45f2f9d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-sabresd.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-sabresd.dtsi"
+
+/ {
+ model = "Freescale i.MX6 DualLite SABRE Smart Device Board";
+ compatible = "fsl,imx6dl-sabresd", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-tx6dl-comtft.dts b/arch/arm/boot/dts/imx6dl-tx6dl-comtft.dts
new file mode 100644
index 000000000..913bb9a04
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-tx6dl-comtft.dts
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2014 Lothar WaĂŸmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+
+/ {
+ model = "Ka-Ro electronics TX6DL Module on CoMpact TFT";
+ compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+
+ aliases {
+ display = &display;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm2 0 500000 0>;
+ power-supply = <&reg_3v3>;
+ /*
+ * a poor man's way to create a 1:1 relationship between
+ * the PWM value and the actual duty cycle
+ */
+ brightness-levels = < 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 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <50>;
+ };
+
+ display: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ interface-pix-fmt = "rgb24";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_disp0_1>;
+ status = "okay";
+
+ port {
+ display0_in: endpoint {
+ remote-endpoint = <&ipu1_di0_disp0>;
+ };
+ };
+
+ display-timings {
+ native-mode = <&ET070001DM6>;
+
+ ET070001DM6: CoMTFT { /* same as ET0700 but with inverted pixel clock */
+ clock-frequency = <33264000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <88>;
+ hsync-len = <128>;
+ hfront-porch = <40>;
+ vback-porch = <33>;
+ vsync-len = <2>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+};
+
+&can1 {
+ status = "disabled";
+};
+
+&can2 {
+ xceiver-supply = <&reg_3v3>;
+};
+
+&ipu1_di0_disp0 {
+ remote-endpoint = <&display0_in>;
+};
+
+&kpp {
+ status = "disabled";
+};
+
+&reg_can_xcvr {
+ status = "disabled";
+};
+
+&touchscreen {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6dl-tx6u-801x.dts b/arch/arm/boot/dts/imx6dl-tx6u-801x.dts
new file mode 100644
index 000000000..5fe465c28
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-tx6u-801x.dts
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2014 Lothar WaĂŸmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+
+/ {
+ model = "Ka-Ro electronics TX6U-801x Module";
+ compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+
+ aliases {
+ display = &display;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm2 0 500000 PWM_POLARITY_INVERTED>;
+ power-supply = <&reg_3v3>;
+ /*
+ * a poor man's way to create a 1:1 relationship between
+ * the PWM value and the actual duty cycle
+ */
+ brightness-levels = < 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 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <50>;
+ };
+
+ display: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ interface-pix-fmt = "rgb24";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_disp0_1>;
+ status = "okay";
+
+ port {
+ display0_in: endpoint {
+ remote-endpoint = <&ipu1_di0_disp0>;
+ };
+ };
+
+ display-timings {
+ VGA {
+ clock-frequency = <25200000>;
+ hactive = <640>;
+ vactive = <480>;
+ hback-porch = <48>;
+ hsync-len = <96>;
+ hfront-porch = <16>;
+ vback-porch = <31>;
+ vsync-len = <2>;
+ vfront-porch = <12>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ETV570 {
+ clock-frequency = <25200000>;
+ hactive = <640>;
+ vactive = <480>;
+ hback-porch = <114>;
+ hsync-len = <30>;
+ hfront-porch = <16>;
+ vback-porch = <32>;
+ vsync-len = <3>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ET0350 {
+ clock-frequency = <6413760>;
+ hactive = <320>;
+ vactive = <240>;
+ hback-porch = <34>;
+ hsync-len = <34>;
+ hfront-porch = <20>;
+ vback-porch = <15>;
+ vsync-len = <3>;
+ vfront-porch = <4>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ET0430 {
+ clock-frequency = <9009000>;
+ hactive = <480>;
+ vactive = <272>;
+ hback-porch = <2>;
+ hsync-len = <41>;
+ hfront-porch = <2>;
+ vback-porch = <2>;
+ vsync-len = <10>;
+ vfront-porch = <2>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+
+ ET0500 {
+ clock-frequency = <33264000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <88>;
+ hsync-len = <128>;
+ hfront-porch = <40>;
+ vback-porch = <33>;
+ vsync-len = <2>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ET0700 { /* same as ET0500 */
+ clock-frequency = <33264000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <88>;
+ hsync-len = <128>;
+ hfront-porch = <40>;
+ vback-porch = <33>;
+ vsync-len = <2>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ETQ570 {
+ clock-frequency = <6596040>;
+ hactive = <320>;
+ vactive = <240>;
+ hback-porch = <38>;
+ hsync-len = <30>;
+ hfront-porch = <30>;
+ vback-porch = <16>;
+ vsync-len = <3>;
+ vfront-porch = <4>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&ipu1_di0_disp0 {
+ remote-endpoint = <&display0_in>;
+};
diff --git a/arch/arm/boot/dts/imx6dl-tx6u-811x.dts b/arch/arm/boot/dts/imx6dl-tx6u-811x.dts
new file mode 100644
index 000000000..c275eecc9
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-tx6u-811x.dts
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2014 Lothar WaĂŸmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+
+/ {
+ model = "Ka-Ro electronics TX6U-811x Module";
+ compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+
+ aliases {
+ display = &lvds0;
+ lvds0 = &lvds0;
+ lvds1 = &lvds1;
+ };
+
+ backlight0: backlight0 {
+ compatible = "pwm-backlight";
+ pwms = <&pwm2 0 500000 0>;
+ power-supply = <&reg_lcd0_pwr>;
+ /*
+ * a poor man's way to create a 1:1 relationship between
+ * the PWM value and the actual duty cycle
+ */
+ brightness-levels = < 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 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <50>;
+ };
+
+ backlight1: backlight1 {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 500000 0>;
+ power-supply = <&reg_lcd1_pwr>;
+ /*
+ * a poor man's way to create a 1:1 relationship between
+ * the PWM value and the actual duty cycle
+ */
+ brightness-levels = < 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 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <50>;
+ };
+};
+
+&i2c3 {
+ polytouch2: eeti@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_eeti>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <22 0>;
+ wakeup-gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+ linux,wakeup;
+ };
+};
+
+&iomuxc {
+ imx6dl-tx6u-811x {
+ pinctrl_eeti: eetigrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b1 /* Interrupt */
+ >;
+ };
+ };
+};
+
+&kpp {
+ status = "disabled"; /* pad conflict with backlight1 PWM */
+};
+
+&ldb {
+ status = "okay";
+
+ lvds0: lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&lvds_timing0>;
+ lvds_timing0: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+
+ lvds1: lvds-channel@1 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "disabled";
+
+ display-timings {
+ native-mode = <&lvds_timing1>;
+ lvds_timing1: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+};
+
+&pwm1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6dl-udoo.dts b/arch/arm/boot/dts/imx6dl-udoo.dts
new file mode 100644
index 000000000..e3713f00e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-udoo.dts
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-udoo.dtsi"
+
+/ {
+ model = "Udoo i.MX6 Dual-lite Board";
+ compatible = "udoo,imx6dl-udoo", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-wandboard-revb1.dts b/arch/arm/boot/dts/imx6dl-wandboard-revb1.dts
new file mode 100644
index 000000000..f607d4f1d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-wandboard-revb1.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-wandboard-revb1.dtsi"
+
+/ {
+ model = "Wandboard i.MX6 Dual Lite Board";
+ compatible = "wand,imx6dl-wandboard", "fsl,imx6dl";
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6dl-wandboard.dts b/arch/arm/boot/dts/imx6dl-wandboard.dts
new file mode 100644
index 000000000..bbb616723
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-wandboard.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-wandboard-revc1.dtsi"
+
+/ {
+ model = "Wandboard i.MX6 Dual Lite Board";
+ compatible = "wand,imx6dl-wandboard", "fsl,imx6dl";
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi
new file mode 100644
index 000000000..f94bf7283
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl.dtsi
@@ -0,0 +1,124 @@
+
+/*
+ * Copyright 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "imx6dl-pinfunc.h"
+#include "imx6qdl.dtsi"
+
+/ {
+ aliases {
+ i2c3 = &i2c4;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ operating-points = <
+ /* kHz uV */
+ 996000 1250000
+ 792000 1175000
+ 396000 1075000
+ >;
+ fsl,soc-operating-points = <
+ /* ARM kHz SOC-PU uV */
+ 996000 1175000
+ 792000 1175000
+ 396000 1175000
+ >;
+ clock-latency = <61036>; /* two CLK32 periods */
+ clocks = <&clks IMX6QDL_CLK_ARM>,
+ <&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
+ <&clks IMX6QDL_CLK_STEP>,
+ <&clks IMX6QDL_CLK_PLL1_SW>,
+ <&clks IMX6QDL_CLK_PLL1_SYS>;
+ clock-names = "arm", "pll2_pfd2_396m", "step",
+ "pll1_sw", "pll1_sys";
+ arm-supply = <&reg_arm>;
+ pu-supply = <&reg_pu>;
+ soc-supply = <&reg_soc>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ soc {
+ ocram: sram@00900000 {
+ compatible = "mmio-sram";
+ reg = <0x00900000 0x20000>;
+ clocks = <&clks IMX6QDL_CLK_OCRAM>;
+ };
+
+ aips1: aips-bus@02000000 {
+ iomuxc: iomuxc@020e0000 {
+ compatible = "fsl,imx6dl-iomuxc";
+ };
+
+ pxp: pxp@020f0000 {
+ reg = <0x020f0000 0x4000>;
+ interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ epdc: epdc@020f4000 {
+ reg = <0x020f4000 0x4000>;
+ interrupts = <0 97 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ lcdif: lcdif@020f8000 {
+ reg = <0x020f8000 0x4000>;
+ interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ aips2: aips-bus@02100000 {
+ i2c4: i2c@021f8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
+ reg = <0x021f8000 0x4000>;
+ interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6DL_CLK_I2C4>;
+ status = "disabled";
+ };
+ };
+ };
+
+ display-subsystem {
+ compatible = "fsl,imx-display-subsystem";
+ ports = <&ipu1_di0>, <&ipu1_di1>;
+ };
+};
+
+&hdmi {
+ compatible = "fsl,imx6dl-hdmi";
+};
+
+&ldb {
+ clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_SEL>,
+ <&clks IMX6QDL_CLK_IPU1_DI0_SEL>, <&clks IMX6QDL_CLK_IPU1_DI1_SEL>,
+ <&clks IMX6QDL_CLK_LDB_DI0>, <&clks IMX6QDL_CLK_LDB_DI1>;
+ clock-names = "di0_pll", "di1_pll",
+ "di0_sel", "di1_sel",
+ "di0", "di1";
+};
+
+&vpu {
+ compatible = "fsl,imx6dl-vpu", "cnm,coda960";
+};
diff --git a/arch/arm/boot/dts/imx6q-arm2.dts b/arch/arm/boot/dts/imx6q-arm2.dts
new file mode 100644
index 000000000..78df05e9d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-arm2.dts
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+
+/ {
+ model = "Freescale i.MX6 Quad Armadillo2 Board";
+ compatible = "fsl,imx6q-arm2", "fsl,imx6q";
+
+ memory {
+ reg = <0x10000000 0x80000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_usb_otg_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 0>;
+ enable-active-high;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ debug-led {
+ label = "Heartbeat";
+ gpios = <&gpio3 25 0>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand>;
+ status = "disabled"; /* gpmi nand conflicts with SD */
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6q-arm2 {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D25__GPIO3_IO25 0x80000000
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL1__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_KEY_COL2__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
+ >;
+ };
+
+ pinctrl_gpmi_nand: gpminandgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
+ MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
+ MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
+ MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
+ MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
+ MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
+ MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
+ MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
+ MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
+ MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
+ MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
+ MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
+ MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
+ MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
+ MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
+ MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
+ MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D26__UART2_RX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D27__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D28__UART2_DTE_CTS_B 0x1b0b1
+ MX6QDL_PAD_EIM_D29__UART2_DTE_RTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
+ MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
+ MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
+ MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3_cdwp: usdhc3cdwp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x80000000
+ MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x80000000
+ >;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
+ MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
+ MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
+ MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
+ MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
+ MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
+ MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
+ MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
+ MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
+ MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
+ >;
+ };
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc3 {
+ cd-gpios = <&gpio6 11 0>;
+ wp-gpios = <&gpio6 14 0>;
+ vmmc-supply = <&reg_3p3v>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3
+ &pinctrl_usdhc3_cdwp>;
+ status = "okay";
+};
+
+&usdhc4 {
+ non-removable;
+ vmmc-supply = <&reg_3p3v>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ fsl,dte-mode;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-cm-fx6.dts b/arch/arm/boot/dts/imx6q-cm-fx6.dts
new file mode 100644
index 000000000..99b46f803
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-cm-fx6.dts
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2013 CompuLab Ltd.
+ *
+ * Author: Valentin Raevsky <valentin@compulab.co.il>
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+
+/ {
+ model = "CompuLab CM-FX6";
+ compatible = "compulab,cm-fx6", "fsl,imx6q";
+
+ memory {
+ reg = <0x10000000 0x80000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ heartbeat-led {
+ label = "Heartbeat";
+ gpios = <&gpio2 31 0>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ status = "okay";
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand>;
+ status = "okay";
+};
+
+&iomuxc {
+ imx6q-cm-fx6 {
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ >;
+ };
+
+ pinctrl_gpmi_nand: gpminandgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
+ MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
+ MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
+ MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
+ MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
+ MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
+ MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
+ MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
+ MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
+ MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
+ MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
+ MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
+ MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
+ MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
+ MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
+ MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
+ MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
+ >;
+ };
+ };
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-cubox-i.dts b/arch/arm/boot/dts/imx6q-cubox-i.dts
new file mode 100644
index 000000000..670bd8c4c
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-cubox-i.dts
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2014 Russell King
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-cubox-i.dtsi"
+
+/ {
+ model = "SolidRun Cubox-i Dual/Quad";
+ compatible = "solidrun,cubox-i/q", "fsl,imx6q";
+};
+
+&sata {
+ status = "okay";
+ fsl,transmit-level-mV = <1104>;
+ fsl,transmit-boost-mdB = <0>;
+ fsl,transmit-atten-16ths = <9>;
+ fsl,no-spread-spectrum;
+};
diff --git a/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts b/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts
new file mode 100644
index 000000000..fd0ad9a88
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Sascha Hauer <s.hauer@pengutronix.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 __DTS_V1__
+#define __DTS_V1__
+/dts-v1/;
+#endif
+
+#include "imx6q.dtsi"
+#include "imx6qdl-dfi-fs700-m60.dtsi"
+
+/ {
+ model = "DFI FS700-M60-6QD i.MX6qd Q7 Board";
+ compatible = "dfi,fs700-m60-6qd", "dfi,fs700e-m60", "fsl,imx6q";
+};
diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
new file mode 100644
index 000000000..4fa254347
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
@@ -0,0 +1,487 @@
+/*
+ * Copyright 2013 Data Modul AG
+ *
+ * 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
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "imx6q.dtsi"
+
+/ {
+ model = "Data Modul eDM-QMX6 Board";
+ compatible = "dmo,imx6q-edmqmx6", "fsl,imx6q";
+
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ aliases {
+ gpio7 = &stmpe_gpio1;
+ gpio8 = &stmpe_gpio2;
+ stmpe-i2c0 = &stmpe1;
+ stmpe-i2c1 = &stmpe2;
+ };
+
+ memory {
+ reg = <0x10000000 0x80000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_usb_otg_switch: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb_otg_switch";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio7 12 0>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_usb_host1: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "usb_host1_en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 31 0>;
+ enable-active-high;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ led-blue {
+ label = "blue";
+ gpios = <&stmpe_gpio1 8 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ led-green {
+ label = "green";
+ gpios = <&stmpe_gpio1 9 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-pink {
+ label = "pink";
+ gpios = <&stmpe_gpio1 10 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-red {
+ label = "red";
+ gpios = <&stmpe_gpio1 11 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can1>;
+ status = "okay";
+};
+
+&ecspi5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi5>;
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio1 12 0>;
+ status = "okay";
+
+ flash: m25p80@0 {
+ compatible = "m25p80";
+ spi-max-frequency = <40000000>;
+ reg = <0>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio1 25 0>;
+ phy-supply = <&vgen2_1v2_eth>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2
+ &pinctrl_stmpe1
+ &pinctrl_stmpe2
+ &pinctrl_pfuze>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <20 8>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ regulator-always-on;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen2_1v2_eth: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vdd_high_in: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ stmpe1: stmpe1601@40 {
+ compatible = "st,stmpe1601";
+ reg = <0x40>;
+ interrupts = <30 0>;
+ interrupt-parent = <&gpio3>;
+ vcc-supply = <&sw2_reg>;
+ vio-supply = <&sw2_reg>;
+
+ stmpe_gpio1: stmpe_gpio {
+ #gpio-cells = <2>;
+ compatible = "st,stmpe-gpio";
+ };
+ };
+
+ stmpe2: stmpe1601@44 {
+ compatible = "st,stmpe1601";
+ reg = <0x44>;
+ interrupts = <2 0>;
+ interrupt-parent = <&gpio5>;
+ vcc-supply = <&sw2_reg>;
+ vio-supply = <&sw2_reg>;
+
+ stmpe_gpio2: stmpe_gpio {
+ #gpio-cells = <2>;
+ compatible = "st,stmpe-gpio";
+ };
+ };
+
+ temp1: ad7414@4c {
+ compatible = "ad,ad7414";
+ reg = <0x4c>;
+ };
+
+ temp2: ad7414@4d {
+ compatible = "ad,ad7414";
+ reg = <0x4d>;
+ };
+
+ rtc: m41t62@68 {
+ compatible = "stm,m41t62";
+ reg = <0x68>;
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6q-dmo-edmqmx6 {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x80000000
+ MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x80000000
+ >;
+ };
+
+ pinctrl_can1: can1grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x1b0b0
+ MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x1b0b0
+ >;
+ };
+
+ pinctrl_ecspi5: ecspi5rp-1 {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT0__ECSPI5_MISO 0x80000000
+ MX6QDL_PAD_SD1_CMD__ECSPI5_MOSI 0x80000000
+ MX6QDL_PAD_SD1_CLK__ECSPI5_SCLK 0x80000000
+ MX6QDL_PAD_SD2_DAT3__GPIO1_IO12 0x80000000
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL1__GPIO4_IO08 0x100b1
+ >;
+ };
+
+ pinctrl_pfuze: pfuze100grp1 {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D20__GPIO3_IO20 0x80000000
+ >;
+ };
+
+ pinctrl_stmpe1: stmpe1grp {
+ fsl,pins = <MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x80000000>;
+ };
+
+ pinctrl_stmpe2: stmpe2grp {
+ fsl,pins = <MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x80000000>;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
+ MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
+ MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
+ MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
+ MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
+ MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
+ MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
+ MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
+ MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
+ MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
+ >;
+ };
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpio = <&gpio4 8 0>;
+ status = "okay";
+};
+
+&sata {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_host1>;
+ disable-over-current;
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbotg {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ vmmc-supply = <&reg_3p3v>;
+ non-removable;
+ bus-width = <8>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-gk802.dts b/arch/arm/boot/dts/imx6q-gk802.dts
new file mode 100644
index 000000000..703539cf3
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-gk802.dts
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2013 Philipp Zabel
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+
+/ {
+ model = "Zealz GK802";
+ compatible = "zealz,imx6q-gk802", "fsl,imx6q";
+
+ chosen {
+ stdout-path = &uart4;
+ };
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ recovery-button {
+ label = "recovery";
+ gpios = <&gpio3 16 1>;
+ linux,code = <0x198>; /* KEY_RESTART */
+ gpio-key,wakeup;
+ };
+ };
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c3>;
+ status = "okay";
+};
+
+/* Internal I2C */
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ /* SDMC DM2016 1024 bit EEPROM + 128 bit OTP */
+ eeprom: dm2016@51 {
+ compatible = "sdmc,dm2016";
+ reg = <0x51>;
+ };
+};
+
+/* External I2C via HDMI */
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ clock-frequency = <100000>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6q-gk802 {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ /* Recovery button, active-low */
+ MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x100b1
+ /* RTL8192CU enable GPIO, active-low */
+ MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x1b0b0
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
+ MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
+ MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
+ MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
+ MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
+ MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
+ >;
+ };
+ };
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ status = "okay";
+};
+
+/* External USB-A port (USBOTG) */
+&usbotg {
+ disable-over-current;
+ status = "okay";
+};
+
+/* Internal USB port (USBH1), connected to RTL8192CU */
+&usbh1 {
+ disable-over-current;
+ status = "okay";
+};
+
+/* External microSD */
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ bus-width = <4>;
+ cd-gpios = <&gpio6 11 0>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+/* Internal microSD */
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ bus-width = <4>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw51xx.dts b/arch/arm/boot/dts/imx6q-gw51xx.dts
new file mode 100644
index 000000000..8e8bcd8fe
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-gw51xx.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-gw51xx.dtsi"
+
+/ {
+ model = "Gateworks Ventana i.MX6 Dual/Quad GW51XX";
+ compatible = "gw,imx6q-gw51xx", "gw,ventana", "fsl,imx6q";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw52xx.dts b/arch/arm/boot/dts/imx6q-gw52xx.dts
new file mode 100644
index 000000000..a12c47e5e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-gw52xx.dts
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-gw52xx.dtsi"
+
+/ {
+ model = "Gateworks Ventana i.MX6 Dual/Quad GW52XX";
+ compatible = "gw,imx6q-gw52xx", "gw,ventana", "fsl,imx6q";
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw53xx.dts b/arch/arm/boot/dts/imx6q-gw53xx.dts
new file mode 100644
index 000000000..d76aaa83d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-gw53xx.dts
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-gw53xx.dtsi"
+
+/ {
+ model = "Gateworks Ventana i.MX6 Dual/Quad GW53XX";
+ compatible = "gw,imx6q-gw53xx", "gw,ventana", "fsl,imx6q";
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw5400-a.dts b/arch/arm/boot/dts/imx6q-gw5400-a.dts
new file mode 100644
index 000000000..822ffb231
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-gw5400-a.dts
@@ -0,0 +1,524 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include "imx6q.dtsi"
+
+/ {
+ model = "Gateworks Ventana GW5400-A";
+ compatible = "gw,imx6q-gw5400-a", "gw,ventana", "fsl,imx6q";
+
+ /* these are used by bootloader for disabling nodes */
+ aliases {
+ ethernet1 = &eth1;
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ i2c2 = &i2c3;
+ led0 = &led0;
+ led1 = &led1;
+ led2 = &led2;
+ ssi0 = &ssi1;
+ spi0 = &ecspi1;
+ usb0 = &usbh1;
+ usb1 = &usbotg;
+ };
+
+ chosen {
+ bootargs = "console=ttymxc1,115200";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ led0: user1 {
+ label = "user1";
+ gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* 102 -> MX6_PANLEDG */
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+
+ led1: user2 {
+ label = "user2";
+ gpios = <&gpio4 10 GPIO_ACTIVE_HIGH>; /* 106 -> MX6_PANLEDR */
+ default-state = "off";
+ };
+
+ led2: user3 {
+ label = "user3";
+ gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* 111 -> MX6_LOCLED# */
+ default-state = "off";
+ };
+ };
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ pps {
+ compatible = "pps-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+ gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_1p0v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "1P0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_usb_h1_vbus: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ reg_usb_otg_vbus: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6q-ventana-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "sgtl5000-audio";
+ ssi-controller = <&ssi1>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <1>;
+ mux-ext-port = <4>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&ecspi1 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ status = "okay";
+
+ flash: m25p80@0 {
+ compatible = "sst,w25q256";
+ spi-max-frequency = <30000000>;
+ reg = <0>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c3>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ eeprom1: eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+
+ eeprom2: eeprom@51 {
+ compatible = "atmel,24c02";
+ reg = <0x51>;
+ pagesize = <16>;
+ };
+
+ eeprom3: eeprom@52 {
+ compatible = "atmel,24c02";
+ reg = <0x52>;
+ pagesize = <16>;
+ };
+
+ eeprom4: eeprom@53 {
+ compatible = "atmel,24c02";
+ reg = <0x53>;
+ pagesize = <16>;
+ };
+
+ gpio: pca9555@23 {
+ compatible = "nxp,pca9555";
+ reg = <0x23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ rtc: ds1672@68 {
+ compatible = "dallas,ds1672";
+ reg = <0x68>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3950000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ accelerometer: mma8450@1c {
+ compatible = "fsl,mma8450";
+ reg = <0x1c>;
+ };
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&clks 201>;
+ VDDA-supply = <&sw4_reg>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+
+ touchscreen: egalax_ts@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ interrupt-parent = <&gpio7>;
+ interrupts = <12 2>;
+ wakeup-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&ldb {
+ status = "okay";
+};
+
+&pcie {
+ reset-gpio = <&gpio1 29 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ eth1: sky2@8 { /* MAC/PHY on bus 8 */
+ compatible = "marvell,sky2";
+ };
+};
+
+&ssi1 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5>;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_h1_vbus>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&iomuxc {
+ imx6q-gw5400-a {
+
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
+ MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
+ MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
+ MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0 /* AUD4_MCK */
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
+ MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
+ MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
+ MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x1b0b0 /* SPINOR_CS0# */
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ >;
+ };
+
+ pinctrl_gpio_leds: gpioledsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x1b0b0 /* user1 led */
+ MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x1b0b0 /* user2 led */
+ MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x1b0b0 /* user3 led */
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x1b0b0 /* PCIE IRQ */
+ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x1b0b0 /* PCIE RST */
+ >;
+ };
+
+ pinctrl_pps: ppsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x1b0b0 /* GPS_PPS */
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5: uart5grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0 /* OTG_PWR_EN */
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6q-gw54xx.dts b/arch/arm/boot/dts/imx6q-gw54xx.dts
new file mode 100644
index 000000000..6e8f53e92
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-gw54xx.dts
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-gw54xx.dtsi"
+
+/ {
+ model = "Gateworks Ventana i.MX6 Dual/Quad GW54XX";
+ compatible = "gw,imx6q-gw54xx", "gw,ventana", "fsl,imx6q";
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw552x.dts b/arch/arm/boot/dts/imx6q-gw552x.dts
new file mode 100644
index 000000000..f87a8fa6e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-gw552x.dts
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2014 Gateworks Corporation
+ *
+ * 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
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-gw552x.dtsi"
+
+/ {
+ model = "Gateworks Ventana i.MX6 Dual/Quad GW552X";
+ compatible = "gw,imx6q-gw552x", "gw,ventana", "fsl,imx6q";
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-hummingboard.dts b/arch/arm/boot/dts/imx6q-hummingboard.dts
new file mode 100644
index 000000000..0f6044553
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-hummingboard.dts
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 Rabeeh Khoury (rabeeh@solid-run.com)
+ * Based on dt work by Russell King
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-hummingboard.dtsi"
+
+/ {
+ model = "SolidRun HummingBoard Dual/Quad";
+ compatible = "solidrun,hummingboard/q", "fsl,imx6q";
+};
+
+&sata {
+ status = "okay";
+ fsl,transmit-level-mV = <1025>;
+ fsl,transmit-boost-mdB = <3330>;
+ fsl,transmit-atten-16ths = <9>;
+ fsl,receive-eq-mdB = <3000>;
+};
diff --git a/arch/arm/boot/dts/imx6q-nitrogen6x.dts b/arch/arm/boot/dts/imx6q-nitrogen6x.dts
new file mode 100644
index 000000000..a57866b2e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-nitrogen6x.dts
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2013 Boundary Devices, Inc.
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-nitrogen6x.dtsi"
+
+/ {
+ model = "Freescale i.MX6 Quad Nitrogen6x Board";
+ compatible = "fsl,imx6q-nitrogen6x", "fsl,imx6q";
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-phytec-pbab01.dts b/arch/arm/boot/dts/imx6q-phytec-pbab01.dts
new file mode 100644
index 000000000..c139ac0eb
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-phytec-pbab01.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx6q-phytec-pfla02.dtsi"
+#include "imx6qdl-phytec-pbab01.dtsi"
+
+/ {
+ model = "Phytec phyFLEX-i.MX6 Quad Carrier-Board";
+ compatible = "phytec,imx6q-pbab01", "phytec,imx6q-pfla02", "fsl,imx6q";
+
+ chosen {
+ stdout-path = &uart4;
+ };
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi
new file mode 100644
index 000000000..cd20d0a94
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
+ *
+ * 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 "imx6q.dtsi"
+#include "imx6qdl-phytec-pfla02.dtsi"
+
+/ {
+ model = "Phytec phyFLEX-i.MX6 Quad";
+ compatible = "phytec,imx6q-pfla02", "fsl,imx6q";
+
+ memory {
+ reg = <0x10000000 0x80000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6q-pinfunc.h b/arch/arm/boot/dts/imx6q-pinfunc.h
new file mode 100644
index 000000000..9fc6120a1
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-pinfunc.h
@@ -0,0 +1,1047 @@
+/*
+ * Copyright 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX6Q_PINFUNC_H
+#define __DTS_IMX6Q_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x04c 0x360 0x000 0x0 0x0
+#define MX6QDL_PAD_SD2_DAT1__ECSPI5_SS0 0x04c 0x360 0x834 0x1 0x0
+#define MX6QDL_PAD_SD2_DAT1__EIM_CS2_B 0x04c 0x360 0x000 0x2 0x0
+#define MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x04c 0x360 0x7c8 0x3 0x0
+#define MX6QDL_PAD_SD2_DAT1__KEY_COL7 0x04c 0x360 0x8f0 0x4 0x0
+#define MX6QDL_PAD_SD2_DAT1__GPIO1_IO14 0x04c 0x360 0x000 0x5 0x0
+#define MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x050 0x364 0x000 0x0 0x0
+#define MX6QDL_PAD_SD2_DAT2__ECSPI5_SS1 0x050 0x364 0x838 0x1 0x0
+#define MX6QDL_PAD_SD2_DAT2__EIM_CS3_B 0x050 0x364 0x000 0x2 0x0
+#define MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x050 0x364 0x7b8 0x3 0x0
+#define MX6QDL_PAD_SD2_DAT2__KEY_ROW6 0x050 0x364 0x8f8 0x4 0x0
+#define MX6QDL_PAD_SD2_DAT2__GPIO1_IO13 0x050 0x364 0x000 0x5 0x0
+#define MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x054 0x368 0x000 0x0 0x0
+#define MX6QDL_PAD_SD2_DAT0__ECSPI5_MISO 0x054 0x368 0x82c 0x1 0x0
+#define MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x054 0x368 0x7b4 0x3 0x0
+#define MX6QDL_PAD_SD2_DAT0__KEY_ROW7 0x054 0x368 0x8fc 0x4 0x0
+#define MX6QDL_PAD_SD2_DAT0__GPIO1_IO15 0x054 0x368 0x000 0x5 0x0
+#define MX6QDL_PAD_SD2_DAT0__DCIC2_OUT 0x054 0x368 0x000 0x6 0x0
+#define MX6QDL_PAD_RGMII_TXC__USB_H2_DATA 0x058 0x36c 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x058 0x36c 0x000 0x1 0x0
+#define MX6QDL_PAD_RGMII_TXC__SPDIF_EXT_CLK 0x058 0x36c 0x918 0x2 0x0
+#define MX6QDL_PAD_RGMII_TXC__GPIO6_IO19 0x058 0x36c 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_TXC__XTALOSC_REF_CLK_24M 0x058 0x36c 0x000 0x7 0x0
+#define MX6QDL_PAD_RGMII_TD0__HSI_TX_READY 0x05c 0x370 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x05c 0x370 0x000 0x1 0x0
+#define MX6QDL_PAD_RGMII_TD0__GPIO6_IO20 0x05c 0x370 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_TD1__HSI_RX_FLAG 0x060 0x374 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x060 0x374 0x000 0x1 0x0
+#define MX6QDL_PAD_RGMII_TD1__GPIO6_IO21 0x060 0x374 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_TD2__HSI_RX_DATA 0x064 0x378 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x064 0x378 0x000 0x1 0x0
+#define MX6QDL_PAD_RGMII_TD2__GPIO6_IO22 0x064 0x378 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_TD3__HSI_RX_WAKE 0x068 0x37c 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x068 0x37c 0x000 0x1 0x0
+#define MX6QDL_PAD_RGMII_TD3__GPIO6_IO23 0x068 0x37c 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_RX_CTL__USB_H3_DATA 0x06c 0x380 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x06c 0x380 0x858 0x1 0x0
+#define MX6QDL_PAD_RGMII_RX_CTL__GPIO6_IO24 0x06c 0x380 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_RD0__HSI_RX_READY 0x070 0x384 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x070 0x384 0x848 0x1 0x0
+#define MX6QDL_PAD_RGMII_RD0__GPIO6_IO25 0x070 0x384 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_TX_CTL__USB_H2_STROBE 0x074 0x388 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x074 0x388 0x000 0x1 0x0
+#define MX6QDL_PAD_RGMII_TX_CTL__GPIO6_IO26 0x074 0x388 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_TX_CTL__ENET_REF_CLK 0x074 0x388 0x83c 0x7 0x0
+#define MX6QDL_PAD_RGMII_RD1__HSI_TX_FLAG 0x078 0x38c 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x078 0x38c 0x84c 0x1 0x0
+#define MX6QDL_PAD_RGMII_RD1__GPIO6_IO27 0x078 0x38c 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_RD2__HSI_TX_DATA 0x07c 0x390 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x07c 0x390 0x850 0x1 0x0
+#define MX6QDL_PAD_RGMII_RD2__GPIO6_IO28 0x07c 0x390 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_RD3__HSI_TX_WAKE 0x080 0x394 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x080 0x394 0x854 0x1 0x0
+#define MX6QDL_PAD_RGMII_RD3__GPIO6_IO29 0x080 0x394 0x000 0x5 0x0
+#define MX6QDL_PAD_RGMII_RXC__USB_H3_STROBE 0x084 0x398 0x000 0x0 0x0
+#define MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x084 0x398 0x844 0x1 0x0
+#define MX6QDL_PAD_RGMII_RXC__GPIO6_IO30 0x084 0x398 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A25__EIM_ADDR25 0x088 0x39c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A25__ECSPI4_SS1 0x088 0x39c 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A25__ECSPI2_RDY 0x088 0x39c 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_A25__IPU1_DI1_PIN12 0x088 0x39c 0x000 0x3 0x0
+#define MX6QDL_PAD_EIM_A25__IPU1_DI0_D1_CS 0x088 0x39c 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x088 0x39c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A25__HDMI_TX_CEC_LINE 0x088 0x39c 0x88c 0x6 0x0
+#define MX6QDL_PAD_EIM_EB2__EIM_EB2_B 0x08c 0x3a0 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_EB2__ECSPI1_SS0 0x08c 0x3a0 0x800 0x1 0x0
+#define MX6QDL_PAD_EIM_EB2__IPU2_CSI1_DATA19 0x08c 0x3a0 0x8d4 0x3 0x0
+#define MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x08c 0x3a0 0x890 0x4 0x0
+#define MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x08c 0x3a0 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x08c 0x3a0 0x8a0 0x6 0x0
+#define MX6QDL_PAD_EIM_EB2__SRC_BOOT_CFG30 0x08c 0x3a0 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_D16__EIM_DATA16 0x090 0x3a4 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x090 0x3a4 0x7f4 0x1 0x0
+#define MX6QDL_PAD_EIM_D16__IPU1_DI0_PIN05 0x090 0x3a4 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D16__IPU2_CSI1_DATA18 0x090 0x3a4 0x8d0 0x3 0x0
+#define MX6QDL_PAD_EIM_D16__HDMI_TX_DDC_SDA 0x090 0x3a4 0x894 0x4 0x0
+#define MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x090 0x3a4 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D16__I2C2_SDA 0x090 0x3a4 0x8a4 0x6 0x0
+#define MX6QDL_PAD_EIM_D17__EIM_DATA17 0x094 0x3a8 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x094 0x3a8 0x7f8 0x1 0x0
+#define MX6QDL_PAD_EIM_D17__IPU1_DI0_PIN06 0x094 0x3a8 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D17__IPU2_CSI1_PIXCLK 0x094 0x3a8 0x8e0 0x3 0x0
+#define MX6QDL_PAD_EIM_D17__DCIC1_OUT 0x094 0x3a8 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D17__GPIO3_IO17 0x094 0x3a8 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D17__I2C3_SCL 0x094 0x3a8 0x8a8 0x6 0x0
+#define MX6QDL_PAD_EIM_D18__EIM_DATA18 0x098 0x3ac 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x098 0x3ac 0x7fc 0x1 0x0
+#define MX6QDL_PAD_EIM_D18__IPU1_DI0_PIN07 0x098 0x3ac 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D18__IPU2_CSI1_DATA17 0x098 0x3ac 0x8cc 0x3 0x0
+#define MX6QDL_PAD_EIM_D18__IPU1_DI1_D0_CS 0x098 0x3ac 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D18__GPIO3_IO18 0x098 0x3ac 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D18__I2C3_SDA 0x098 0x3ac 0x8ac 0x6 0x0
+#define MX6QDL_PAD_EIM_D19__EIM_DATA19 0x09c 0x3b0 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D19__ECSPI1_SS1 0x09c 0x3b0 0x804 0x1 0x0
+#define MX6QDL_PAD_EIM_D19__IPU1_DI0_PIN08 0x09c 0x3b0 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D19__IPU2_CSI1_DATA16 0x09c 0x3b0 0x8c8 0x3 0x0
+#define MX6QDL_PAD_EIM_D19__UART1_CTS_B 0x09c 0x3b0 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D19__UART1_RTS_B 0x09c 0x3b0 0x91c 0x4 0x0
+#define MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x09c 0x3b0 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D19__EPIT1_OUT 0x09c 0x3b0 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_D20__EIM_DATA20 0x0a0 0x3b4 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D20__ECSPI4_SS0 0x0a0 0x3b4 0x824 0x1 0x0
+#define MX6QDL_PAD_EIM_D20__IPU1_DI0_PIN16 0x0a0 0x3b4 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D20__IPU2_CSI1_DATA15 0x0a0 0x3b4 0x8c4 0x3 0x0
+#define MX6QDL_PAD_EIM_D20__UART1_RTS_B 0x0a0 0x3b4 0x91c 0x4 0x1
+#define MX6QDL_PAD_EIM_D20__UART1_CTS_B 0x0a0 0x3b4 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D20__GPIO3_IO20 0x0a0 0x3b4 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D20__EPIT2_OUT 0x0a0 0x3b4 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_D21__EIM_DATA21 0x0a4 0x3b8 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D21__ECSPI4_SCLK 0x0a4 0x3b8 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D21__IPU1_DI0_PIN17 0x0a4 0x3b8 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D21__IPU2_CSI1_DATA11 0x0a4 0x3b8 0x8b4 0x3 0x0
+#define MX6QDL_PAD_EIM_D21__USB_OTG_OC 0x0a4 0x3b8 0x944 0x4 0x0
+#define MX6QDL_PAD_EIM_D21__GPIO3_IO21 0x0a4 0x3b8 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D21__I2C1_SCL 0x0a4 0x3b8 0x898 0x6 0x0
+#define MX6QDL_PAD_EIM_D21__SPDIF_IN 0x0a4 0x3b8 0x914 0x7 0x0
+#define MX6QDL_PAD_EIM_D22__EIM_DATA22 0x0a8 0x3bc 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D22__ECSPI4_MISO 0x0a8 0x3bc 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D22__IPU1_DI0_PIN01 0x0a8 0x3bc 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D22__IPU2_CSI1_DATA10 0x0a8 0x3bc 0x8b0 0x3 0x0
+#define MX6QDL_PAD_EIM_D22__USB_OTG_PWR 0x0a8 0x3bc 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x0a8 0x3bc 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D22__SPDIF_OUT 0x0a8 0x3bc 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_D23__EIM_DATA23 0x0ac 0x3c0 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D23__IPU1_DI0_D0_CS 0x0ac 0x3c0 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x0ac 0x3c0 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D23__UART3_RTS_B 0x0ac 0x3c0 0x92c 0x2 0x0
+#define MX6QDL_PAD_EIM_D23__UART1_DCD_B 0x0ac 0x3c0 0x000 0x3 0x0
+#define MX6QDL_PAD_EIM_D23__IPU2_CSI1_DATA_EN 0x0ac 0x3c0 0x8d8 0x4 0x0
+#define MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x0ac 0x3c0 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D23__IPU1_DI1_PIN02 0x0ac 0x3c0 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_D23__IPU1_DI1_PIN14 0x0ac 0x3c0 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_EB3__EIM_EB3_B 0x0b0 0x3c4 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_EB3__ECSPI4_RDY 0x0b0 0x3c4 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x0b0 0x3c4 0x92c 0x2 0x1
+#define MX6QDL_PAD_EIM_EB3__UART3_CTS_B 0x0b0 0x3c4 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_EB3__UART1_RI_B 0x0b0 0x3c4 0x000 0x3 0x0
+#define MX6QDL_PAD_EIM_EB3__IPU2_CSI1_HSYNC 0x0b0 0x3c4 0x8dc 0x4 0x0
+#define MX6QDL_PAD_EIM_EB3__GPIO2_IO31 0x0b0 0x3c4 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_EB3__IPU1_DI1_PIN03 0x0b0 0x3c4 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_EB3__SRC_BOOT_CFG31 0x0b0 0x3c4 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_D24__EIM_DATA24 0x0b4 0x3c8 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D24__ECSPI4_SS2 0x0b4 0x3c8 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x0b4 0x3c8 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D24__UART3_RX_DATA 0x0b4 0x3c8 0x930 0x2 0x0
+#define MX6QDL_PAD_EIM_D24__ECSPI1_SS2 0x0b4 0x3c8 0x808 0x3 0x0
+#define MX6QDL_PAD_EIM_D24__ECSPI2_SS2 0x0b4 0x3c8 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D24__GPIO3_IO24 0x0b4 0x3c8 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D24__AUD5_RXFS 0x0b4 0x3c8 0x7d8 0x6 0x0
+#define MX6QDL_PAD_EIM_D24__UART1_DTR_B 0x0b4 0x3c8 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_D25__EIM_DATA25 0x0b8 0x3cc 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D25__ECSPI4_SS3 0x0b8 0x3cc 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x0b8 0x3cc 0x930 0x2 0x1
+#define MX6QDL_PAD_EIM_D25__UART3_TX_DATA 0x0b8 0x3cc 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D25__ECSPI1_SS3 0x0b8 0x3cc 0x80c 0x3 0x0
+#define MX6QDL_PAD_EIM_D25__ECSPI2_SS3 0x0b8 0x3cc 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D25__GPIO3_IO25 0x0b8 0x3cc 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D25__AUD5_RXC 0x0b8 0x3cc 0x7d4 0x6 0x0
+#define MX6QDL_PAD_EIM_D25__UART1_DSR_B 0x0b8 0x3cc 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_D26__EIM_DATA26 0x0bc 0x3d0 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D26__IPU1_DI1_PIN11 0x0bc 0x3d0 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D26__IPU1_CSI0_DATA01 0x0bc 0x3d0 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D26__IPU2_CSI1_DATA14 0x0bc 0x3d0 0x8c0 0x3 0x0
+#define MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x0bc 0x3d0 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D26__UART2_RX_DATA 0x0bc 0x3d0 0x928 0x4 0x0
+#define MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x0bc 0x3d0 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D26__IPU1_SISG2 0x0bc 0x3d0 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_D26__IPU1_DISP1_DATA22 0x0bc 0x3d0 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_D27__EIM_DATA27 0x0c0 0x3d4 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D27__IPU1_DI1_PIN13 0x0c0 0x3d4 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D27__IPU1_CSI0_DATA00 0x0c0 0x3d4 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D27__IPU2_CSI1_DATA13 0x0c0 0x3d4 0x8bc 0x3 0x0
+#define MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x0c0 0x3d4 0x928 0x4 0x1
+#define MX6QDL_PAD_EIM_D27__UART2_TX_DATA 0x0c0 0x3d4 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D27__GPIO3_IO27 0x0c0 0x3d4 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D27__IPU1_SISG3 0x0c0 0x3d4 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_D27__IPU1_DISP1_DATA23 0x0c0 0x3d4 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_D28__EIM_DATA28 0x0c4 0x3d8 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D28__I2C1_SDA 0x0c4 0x3d8 0x89c 0x1 0x0
+#define MX6QDL_PAD_EIM_D28__ECSPI4_MOSI 0x0c4 0x3d8 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D28__IPU2_CSI1_DATA12 0x0c4 0x3d8 0x8b8 0x3 0x0
+#define MX6QDL_PAD_EIM_D28__UART2_CTS_B 0x0c4 0x3d8 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D28__UART2_RTS_B 0x0c4 0x3d8 0x924 0x4 0x0
+#define MX6QDL_PAD_EIM_D28__UART2_DTE_CTS_B 0x0c4 0x3d8 0x924 0x4 0x0
+#define MX6QDL_PAD_EIM_D28__UART2_DTE_RTS_B 0x0c4 0x3d8 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D28__GPIO3_IO28 0x0c4 0x3d8 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D28__IPU1_EXT_TRIG 0x0c4 0x3d8 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_D28__IPU1_DI0_PIN13 0x0c4 0x3d8 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_D29__EIM_DATA29 0x0c8 0x3dc 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D29__IPU1_DI1_PIN15 0x0c8 0x3dc 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D29__ECSPI4_SS0 0x0c8 0x3dc 0x824 0x2 0x1
+#define MX6QDL_PAD_EIM_D29__UART2_RTS_B 0x0c8 0x3dc 0x924 0x4 0x1
+#define MX6QDL_PAD_EIM_D29__UART2_CTS_B 0x0c8 0x3dc 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D29__UART2_DTE_RTS_B 0x0c8 0x3dc 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D29__UART2_DTE_CTS_B 0x0c8 0x3dc 0x924 0x4 0x1
+#define MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x0c8 0x3dc 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D29__IPU2_CSI1_VSYNC 0x0c8 0x3dc 0x8e4 0x6 0x0
+#define MX6QDL_PAD_EIM_D29__IPU1_DI0_PIN14 0x0c8 0x3dc 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_D30__EIM_DATA30 0x0cc 0x3e0 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D30__IPU1_DISP1_DATA21 0x0cc 0x3e0 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D30__IPU1_DI0_PIN11 0x0cc 0x3e0 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D30__IPU1_CSI0_DATA03 0x0cc 0x3e0 0x000 0x3 0x0
+#define MX6QDL_PAD_EIM_D30__UART3_CTS_B 0x0cc 0x3e0 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D30__UART3_RTS_B 0x0cc 0x3e0 0x92c 0x4 0x2
+#define MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x0cc 0x3e0 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D30__USB_H1_OC 0x0cc 0x3e0 0x948 0x6 0x0
+#define MX6QDL_PAD_EIM_D31__EIM_DATA31 0x0d0 0x3e4 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_D31__IPU1_DISP1_DATA20 0x0d0 0x3e4 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_D31__IPU1_DI0_PIN12 0x0d0 0x3e4 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_D31__IPU1_CSI0_DATA02 0x0d0 0x3e4 0x000 0x3 0x0
+#define MX6QDL_PAD_EIM_D31__UART3_RTS_B 0x0d0 0x3e4 0x92c 0x4 0x3
+#define MX6QDL_PAD_EIM_D31__UART3_CTS_B 0x0d0 0x3e4 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x0d0 0x3e4 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_D31__USB_H1_PWR 0x0d0 0x3e4 0x000 0x6 0x0
+#define MX6QDL_PAD_EIM_A24__EIM_ADDR24 0x0d4 0x3e8 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A24__IPU1_DISP1_DATA19 0x0d4 0x3e8 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A24__IPU2_CSI1_DATA19 0x0d4 0x3e8 0x8d4 0x2 0x1
+#define MX6QDL_PAD_EIM_A24__IPU2_SISG2 0x0d4 0x3e8 0x000 0x3 0x0
+#define MX6QDL_PAD_EIM_A24__IPU1_SISG2 0x0d4 0x3e8 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_A24__GPIO5_IO04 0x0d4 0x3e8 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A24__SRC_BOOT_CFG24 0x0d4 0x3e8 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A23__EIM_ADDR23 0x0d8 0x3ec 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A23__IPU1_DISP1_DATA18 0x0d8 0x3ec 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A23__IPU2_CSI1_DATA18 0x0d8 0x3ec 0x8d0 0x2 0x1
+#define MX6QDL_PAD_EIM_A23__IPU2_SISG3 0x0d8 0x3ec 0x000 0x3 0x0
+#define MX6QDL_PAD_EIM_A23__IPU1_SISG3 0x0d8 0x3ec 0x000 0x4 0x0
+#define MX6QDL_PAD_EIM_A23__GPIO6_IO06 0x0d8 0x3ec 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A23__SRC_BOOT_CFG23 0x0d8 0x3ec 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A22__EIM_ADDR22 0x0dc 0x3f0 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A22__IPU1_DISP1_DATA17 0x0dc 0x3f0 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A22__IPU2_CSI1_DATA17 0x0dc 0x3f0 0x8cc 0x2 0x1
+#define MX6QDL_PAD_EIM_A22__GPIO2_IO16 0x0dc 0x3f0 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A22__SRC_BOOT_CFG22 0x0dc 0x3f0 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A21__EIM_ADDR21 0x0e0 0x3f4 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A21__IPU1_DISP1_DATA16 0x0e0 0x3f4 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A21__IPU2_CSI1_DATA16 0x0e0 0x3f4 0x8c8 0x2 0x1
+#define MX6QDL_PAD_EIM_A21__GPIO2_IO17 0x0e0 0x3f4 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A21__SRC_BOOT_CFG21 0x0e0 0x3f4 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A20__EIM_ADDR20 0x0e4 0x3f8 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A20__IPU1_DISP1_DATA15 0x0e4 0x3f8 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A20__IPU2_CSI1_DATA15 0x0e4 0x3f8 0x8c4 0x2 0x1
+#define MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x0e4 0x3f8 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A20__SRC_BOOT_CFG20 0x0e4 0x3f8 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A19__EIM_ADDR19 0x0e8 0x3fc 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A19__IPU1_DISP1_DATA14 0x0e8 0x3fc 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A19__IPU2_CSI1_DATA14 0x0e8 0x3fc 0x8c0 0x2 0x1
+#define MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x0e8 0x3fc 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A19__SRC_BOOT_CFG19 0x0e8 0x3fc 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A18__EIM_ADDR18 0x0ec 0x400 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A18__IPU1_DISP1_DATA13 0x0ec 0x400 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A18__IPU2_CSI1_DATA13 0x0ec 0x400 0x8bc 0x2 0x1
+#define MX6QDL_PAD_EIM_A18__GPIO2_IO20 0x0ec 0x400 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A18__SRC_BOOT_CFG18 0x0ec 0x400 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A17__EIM_ADDR17 0x0f0 0x404 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A17__IPU1_DISP1_DATA12 0x0f0 0x404 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A17__IPU2_CSI1_DATA12 0x0f0 0x404 0x8b8 0x2 0x1
+#define MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x0f0 0x404 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A17__SRC_BOOT_CFG17 0x0f0 0x404 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_A16__EIM_ADDR16 0x0f4 0x408 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_A16__IPU1_DI1_DISP_CLK 0x0f4 0x408 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_A16__IPU2_CSI1_PIXCLK 0x0f4 0x408 0x8e0 0x2 0x1
+#define MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x0f4 0x408 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_A16__SRC_BOOT_CFG16 0x0f4 0x408 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_CS0__EIM_CS0_B 0x0f8 0x40c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_CS0__IPU1_DI1_PIN05 0x0f8 0x40c 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_CS0__ECSPI2_SCLK 0x0f8 0x40c 0x810 0x2 0x0
+#define MX6QDL_PAD_EIM_CS0__GPIO2_IO23 0x0f8 0x40c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_CS1__EIM_CS1_B 0x0fc 0x410 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_CS1__IPU1_DI1_PIN06 0x0fc 0x410 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_CS1__ECSPI2_MOSI 0x0fc 0x410 0x818 0x2 0x0
+#define MX6QDL_PAD_EIM_CS1__GPIO2_IO24 0x0fc 0x410 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_OE__EIM_OE_B 0x100 0x414 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_OE__IPU1_DI1_PIN07 0x100 0x414 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_OE__ECSPI2_MISO 0x100 0x414 0x814 0x2 0x0
+#define MX6QDL_PAD_EIM_OE__GPIO2_IO25 0x100 0x414 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_RW__EIM_RW 0x104 0x418 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_RW__IPU1_DI1_PIN08 0x104 0x418 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_RW__ECSPI2_SS0 0x104 0x418 0x81c 0x2 0x0
+#define MX6QDL_PAD_EIM_RW__GPIO2_IO26 0x104 0x418 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_RW__SRC_BOOT_CFG29 0x104 0x418 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_LBA__EIM_LBA_B 0x108 0x41c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_LBA__IPU1_DI1_PIN17 0x108 0x41c 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_LBA__ECSPI2_SS1 0x108 0x41c 0x820 0x2 0x0
+#define MX6QDL_PAD_EIM_LBA__GPIO2_IO27 0x108 0x41c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_LBA__SRC_BOOT_CFG26 0x108 0x41c 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_EB0__EIM_EB0_B 0x10c 0x420 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_EB0__IPU1_DISP1_DATA11 0x10c 0x420 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_EB0__IPU2_CSI1_DATA11 0x10c 0x420 0x8b4 0x2 0x1
+#define MX6QDL_PAD_EIM_EB0__CCM_PMIC_READY 0x10c 0x420 0x7f0 0x4 0x0
+#define MX6QDL_PAD_EIM_EB0__GPIO2_IO28 0x10c 0x420 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_EB0__SRC_BOOT_CFG27 0x10c 0x420 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_EB1__EIM_EB1_B 0x110 0x424 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_EB1__IPU1_DISP1_DATA10 0x110 0x424 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_EB1__IPU2_CSI1_DATA10 0x110 0x424 0x8b0 0x2 0x1
+#define MX6QDL_PAD_EIM_EB1__GPIO2_IO29 0x110 0x424 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_EB1__SRC_BOOT_CFG28 0x110 0x424 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA0__EIM_AD00 0x114 0x428 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA0__IPU1_DISP1_DATA09 0x114 0x428 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA0__IPU2_CSI1_DATA09 0x114 0x428 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA0__GPIO3_IO00 0x114 0x428 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA0__SRC_BOOT_CFG00 0x114 0x428 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA1__EIM_AD01 0x118 0x42c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA1__IPU1_DISP1_DATA08 0x118 0x42c 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA1__IPU2_CSI1_DATA08 0x118 0x42c 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA1__GPIO3_IO01 0x118 0x42c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA1__SRC_BOOT_CFG01 0x118 0x42c 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA2__EIM_AD02 0x11c 0x430 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA2__IPU1_DISP1_DATA07 0x11c 0x430 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA2__IPU2_CSI1_DATA07 0x11c 0x430 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA2__GPIO3_IO02 0x11c 0x430 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA2__SRC_BOOT_CFG02 0x11c 0x430 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA3__EIM_AD03 0x120 0x434 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA3__IPU1_DISP1_DATA06 0x120 0x434 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA3__IPU2_CSI1_DATA06 0x120 0x434 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA3__GPIO3_IO03 0x120 0x434 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA3__SRC_BOOT_CFG03 0x120 0x434 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA4__EIM_AD04 0x124 0x438 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA4__IPU1_DISP1_DATA05 0x124 0x438 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA4__IPU2_CSI1_DATA05 0x124 0x438 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA4__GPIO3_IO04 0x124 0x438 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA4__SRC_BOOT_CFG04 0x124 0x438 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA5__EIM_AD05 0x128 0x43c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA5__IPU1_DISP1_DATA04 0x128 0x43c 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA5__IPU2_CSI1_DATA04 0x128 0x43c 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA5__GPIO3_IO05 0x128 0x43c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA5__SRC_BOOT_CFG05 0x128 0x43c 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA6__EIM_AD06 0x12c 0x440 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA6__IPU1_DISP1_DATA03 0x12c 0x440 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA6__IPU2_CSI1_DATA03 0x12c 0x440 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA6__GPIO3_IO06 0x12c 0x440 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA6__SRC_BOOT_CFG06 0x12c 0x440 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA7__EIM_AD07 0x130 0x444 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA7__IPU1_DISP1_DATA02 0x130 0x444 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA7__IPU2_CSI1_DATA02 0x130 0x444 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA7__GPIO3_IO07 0x130 0x444 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA7__SRC_BOOT_CFG07 0x130 0x444 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA8__EIM_AD08 0x134 0x448 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA8__IPU1_DISP1_DATA01 0x134 0x448 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA8__IPU2_CSI1_DATA01 0x134 0x448 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA8__GPIO3_IO08 0x134 0x448 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA8__SRC_BOOT_CFG08 0x134 0x448 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA9__EIM_AD09 0x138 0x44c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA9__IPU1_DISP1_DATA00 0x138 0x44c 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA9__IPU2_CSI1_DATA00 0x138 0x44c 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0x138 0x44c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA9__SRC_BOOT_CFG09 0x138 0x44c 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA10__EIM_AD10 0x13c 0x450 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA10__IPU1_DI1_PIN15 0x13c 0x450 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA10__IPU2_CSI1_DATA_EN 0x13c 0x450 0x8d8 0x2 0x1
+#define MX6QDL_PAD_EIM_DA10__GPIO3_IO10 0x13c 0x450 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA10__SRC_BOOT_CFG10 0x13c 0x450 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA11__EIM_AD11 0x140 0x454 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA11__IPU1_DI1_PIN02 0x140 0x454 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA11__IPU2_CSI1_HSYNC 0x140 0x454 0x8dc 0x2 0x1
+#define MX6QDL_PAD_EIM_DA11__GPIO3_IO11 0x140 0x454 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA11__SRC_BOOT_CFG11 0x140 0x454 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA12__EIM_AD12 0x144 0x458 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA12__IPU1_DI1_PIN03 0x144 0x458 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA12__IPU2_CSI1_VSYNC 0x144 0x458 0x8e4 0x2 0x1
+#define MX6QDL_PAD_EIM_DA12__GPIO3_IO12 0x144 0x458 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA12__SRC_BOOT_CFG12 0x144 0x458 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA13__EIM_AD13 0x148 0x45c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA13__IPU1_DI1_D0_CS 0x148 0x45c 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA13__GPIO3_IO13 0x148 0x45c 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA13__SRC_BOOT_CFG13 0x148 0x45c 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA14__EIM_AD14 0x14c 0x460 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA14__IPU1_DI1_D1_CS 0x14c 0x460 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA14__GPIO3_IO14 0x14c 0x460 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA14__SRC_BOOT_CFG14 0x14c 0x460 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_DA15__EIM_AD15 0x150 0x464 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_DA15__IPU1_DI1_PIN01 0x150 0x464 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_DA15__IPU1_DI1_PIN04 0x150 0x464 0x000 0x2 0x0
+#define MX6QDL_PAD_EIM_DA15__GPIO3_IO15 0x150 0x464 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_DA15__SRC_BOOT_CFG15 0x150 0x464 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B 0x154 0x468 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_WAIT__EIM_DTACK_B 0x154 0x468 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_WAIT__GPIO5_IO00 0x154 0x468 0x000 0x5 0x0
+#define MX6QDL_PAD_EIM_WAIT__SRC_BOOT_CFG25 0x154 0x468 0x000 0x7 0x0
+#define MX6QDL_PAD_EIM_BCLK__EIM_BCLK 0x158 0x46c 0x000 0x0 0x0
+#define MX6QDL_PAD_EIM_BCLK__IPU1_DI1_PIN16 0x158 0x46c 0x000 0x1 0x0
+#define MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0x158 0x46c 0x000 0x5 0x0
+#define MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x15c 0x470 0x000 0x0 0x0
+#define MX6QDL_PAD_DI0_DISP_CLK__IPU2_DI0_DISP_CLK 0x15c 0x470 0x000 0x1 0x0
+#define MX6QDL_PAD_DI0_DISP_CLK__GPIO4_IO16 0x15c 0x470 0x000 0x5 0x0
+#define MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x160 0x474 0x000 0x0 0x0
+#define MX6QDL_PAD_DI0_PIN15__IPU2_DI0_PIN15 0x160 0x474 0x000 0x1 0x0
+#define MX6QDL_PAD_DI0_PIN15__AUD6_TXC 0x160 0x474 0x000 0x2 0x0
+#define MX6QDL_PAD_DI0_PIN15__GPIO4_IO17 0x160 0x474 0x000 0x5 0x0
+#define MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x164 0x478 0x000 0x0 0x0
+#define MX6QDL_PAD_DI0_PIN2__IPU2_DI0_PIN02 0x164 0x478 0x000 0x1 0x0
+#define MX6QDL_PAD_DI0_PIN2__AUD6_TXD 0x164 0x478 0x000 0x2 0x0
+#define MX6QDL_PAD_DI0_PIN2__GPIO4_IO18 0x164 0x478 0x000 0x5 0x0
+#define MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x168 0x47c 0x000 0x0 0x0
+#define MX6QDL_PAD_DI0_PIN3__IPU2_DI0_PIN03 0x168 0x47c 0x000 0x1 0x0
+#define MX6QDL_PAD_DI0_PIN3__AUD6_TXFS 0x168 0x47c 0x000 0x2 0x0
+#define MX6QDL_PAD_DI0_PIN3__GPIO4_IO19 0x168 0x47c 0x000 0x5 0x0
+#define MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04 0x16c 0x480 0x000 0x0 0x0
+#define MX6QDL_PAD_DI0_PIN4__IPU2_DI0_PIN04 0x16c 0x480 0x000 0x1 0x0
+#define MX6QDL_PAD_DI0_PIN4__AUD6_RXD 0x16c 0x480 0x000 0x2 0x0
+#define MX6QDL_PAD_DI0_PIN4__SD1_WP 0x16c 0x480 0x94c 0x3 0x0
+#define MX6QDL_PAD_DI0_PIN4__GPIO4_IO20 0x16c 0x480 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x170 0x484 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT0__IPU2_DISP0_DATA00 0x170 0x484 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x170 0x484 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT0__GPIO4_IO21 0x170 0x484 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x174 0x488 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT1__IPU2_DISP0_DATA01 0x174 0x488 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x174 0x488 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT1__GPIO4_IO22 0x174 0x488 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x178 0x48c 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT2__IPU2_DISP0_DATA02 0x178 0x48c 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x178 0x48c 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT2__GPIO4_IO23 0x178 0x48c 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x17c 0x490 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT3__IPU2_DISP0_DATA03 0x17c 0x490 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT3__ECSPI3_SS0 0x17c 0x490 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x17c 0x490 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x180 0x494 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT4__IPU2_DISP0_DATA04 0x180 0x494 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT4__ECSPI3_SS1 0x180 0x494 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT4__GPIO4_IO25 0x180 0x494 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x184 0x498 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT5__IPU2_DISP0_DATA05 0x184 0x498 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT5__ECSPI3_SS2 0x184 0x498 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT5__AUD6_RXFS 0x184 0x498 0x000 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT5__GPIO4_IO26 0x184 0x498 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x188 0x49c 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT6__IPU2_DISP0_DATA06 0x188 0x49c 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT6__ECSPI3_SS3 0x188 0x49c 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT6__AUD6_RXC 0x188 0x49c 0x000 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT6__GPIO4_IO27 0x188 0x49c 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x18c 0x4a0 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT7__IPU2_DISP0_DATA07 0x18c 0x4a0 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT7__ECSPI3_RDY 0x18c 0x4a0 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT7__GPIO4_IO28 0x18c 0x4a0 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x190 0x4a4 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT8__IPU2_DISP0_DATA08 0x190 0x4a4 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT8__PWM1_OUT 0x190 0x4a4 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT8__WDOG1_B 0x190 0x4a4 0x000 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT8__GPIO4_IO29 0x190 0x4a4 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x194 0x4a8 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT9__IPU2_DISP0_DATA09 0x194 0x4a8 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT9__PWM2_OUT 0x194 0x4a8 0x000 0x2 0x0
+#define MX6QDL_PAD_DISP0_DAT9__WDOG2_B 0x194 0x4a8 0x000 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT9__GPIO4_IO30 0x194 0x4a8 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x198 0x4ac 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT10__IPU2_DISP0_DATA10 0x198 0x4ac 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT10__GPIO4_IO31 0x198 0x4ac 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x19c 0x4b0 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT11__IPU2_DISP0_DATA11 0x19c 0x4b0 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT11__GPIO5_IO05 0x19c 0x4b0 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x1a0 0x4b4 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT12__IPU2_DISP0_DATA12 0x1a0 0x4b4 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT12__GPIO5_IO06 0x1a0 0x4b4 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x1a4 0x4b8 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT13__IPU2_DISP0_DATA13 0x1a4 0x4b8 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT13__AUD5_RXFS 0x1a4 0x4b8 0x7d8 0x3 0x1
+#define MX6QDL_PAD_DISP0_DAT13__GPIO5_IO07 0x1a4 0x4b8 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x1a8 0x4bc 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT14__IPU2_DISP0_DATA14 0x1a8 0x4bc 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT14__AUD5_RXC 0x1a8 0x4bc 0x7d4 0x3 0x1
+#define MX6QDL_PAD_DISP0_DAT14__GPIO5_IO08 0x1a8 0x4bc 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x1ac 0x4c0 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT15__IPU2_DISP0_DATA15 0x1ac 0x4c0 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT15__ECSPI1_SS1 0x1ac 0x4c0 0x804 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT15__ECSPI2_SS1 0x1ac 0x4c0 0x820 0x3 0x1
+#define MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09 0x1ac 0x4c0 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x1b0 0x4c4 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT16__IPU2_DISP0_DATA16 0x1b0 0x4c4 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT16__ECSPI2_MOSI 0x1b0 0x4c4 0x818 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT16__AUD5_TXC 0x1b0 0x4c4 0x7dc 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT16__SDMA_EXT_EVENT0 0x1b0 0x4c4 0x90c 0x4 0x0
+#define MX6QDL_PAD_DISP0_DAT16__GPIO5_IO10 0x1b0 0x4c4 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x1b4 0x4c8 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT17__IPU2_DISP0_DATA17 0x1b4 0x4c8 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT17__ECSPI2_MISO 0x1b4 0x4c8 0x814 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT17__AUD5_TXD 0x1b4 0x4c8 0x7d0 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT17__SDMA_EXT_EVENT1 0x1b4 0x4c8 0x910 0x4 0x0
+#define MX6QDL_PAD_DISP0_DAT17__GPIO5_IO11 0x1b4 0x4c8 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x1b8 0x4cc 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT18__IPU2_DISP0_DATA18 0x1b8 0x4cc 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT18__ECSPI2_SS0 0x1b8 0x4cc 0x81c 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS 0x1b8 0x4cc 0x7e0 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT18__AUD4_RXFS 0x1b8 0x4cc 0x7c0 0x4 0x0
+#define MX6QDL_PAD_DISP0_DAT18__GPIO5_IO12 0x1b8 0x4cc 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT18__EIM_CS2_B 0x1b8 0x4cc 0x000 0x7 0x0
+#define MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x1bc 0x4d0 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT19__IPU2_DISP0_DATA19 0x1bc 0x4d0 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT19__ECSPI2_SCLK 0x1bc 0x4d0 0x810 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x1bc 0x4d0 0x7cc 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT19__AUD4_RXC 0x1bc 0x4d0 0x7bc 0x4 0x0
+#define MX6QDL_PAD_DISP0_DAT19__GPIO5_IO13 0x1bc 0x4d0 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT19__EIM_CS3_B 0x1bc 0x4d0 0x000 0x7 0x0
+#define MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x1c0 0x4d4 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT20__IPU2_DISP0_DATA20 0x1c0 0x4d4 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT20__ECSPI1_SCLK 0x1c0 0x4d4 0x7f4 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT20__AUD4_TXC 0x1c0 0x4d4 0x7c4 0x3 0x0
+#define MX6QDL_PAD_DISP0_DAT20__GPIO5_IO14 0x1c0 0x4d4 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x1c4 0x4d8 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT21__IPU2_DISP0_DATA21 0x1c4 0x4d8 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT21__ECSPI1_MOSI 0x1c4 0x4d8 0x7fc 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT21__AUD4_TXD 0x1c4 0x4d8 0x7b8 0x3 0x1
+#define MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15 0x1c4 0x4d8 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x1c8 0x4dc 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT22__IPU2_DISP0_DATA22 0x1c8 0x4dc 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT22__ECSPI1_MISO 0x1c8 0x4dc 0x7f8 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT22__AUD4_TXFS 0x1c8 0x4dc 0x7c8 0x3 0x1
+#define MX6QDL_PAD_DISP0_DAT22__GPIO5_IO16 0x1c8 0x4dc 0x000 0x5 0x0
+#define MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x1cc 0x4e0 0x000 0x0 0x0
+#define MX6QDL_PAD_DISP0_DAT23__IPU2_DISP0_DATA23 0x1cc 0x4e0 0x000 0x1 0x0
+#define MX6QDL_PAD_DISP0_DAT23__ECSPI1_SS0 0x1cc 0x4e0 0x800 0x2 0x1
+#define MX6QDL_PAD_DISP0_DAT23__AUD4_RXD 0x1cc 0x4e0 0x7b4 0x3 0x1
+#define MX6QDL_PAD_DISP0_DAT23__GPIO5_IO17 0x1cc 0x4e0 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1d0 0x4e4 0x840 0x1 0x0
+#define MX6QDL_PAD_ENET_MDIO__ESAI_RX_CLK 0x1d0 0x4e4 0x86c 0x2 0x0
+#define MX6QDL_PAD_ENET_MDIO__ENET_1588_EVENT1_OUT 0x1d0 0x4e4 0x000 0x4 0x0
+#define MX6QDL_PAD_ENET_MDIO__GPIO1_IO22 0x1d0 0x4e4 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_MDIO__SPDIF_LOCK 0x1d0 0x4e4 0x000 0x6 0x0
+#define MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1d4 0x4e8 0x000 0x1 0x0
+#define MX6QDL_PAD_ENET_REF_CLK__ESAI_RX_FS 0x1d4 0x4e8 0x85c 0x2 0x0
+#define MX6QDL_PAD_ENET_REF_CLK__GPIO1_IO23 0x1d4 0x4e8 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_REF_CLK__SPDIF_SR_CLK 0x1d4 0x4e8 0x000 0x6 0x0
+#define MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x1d8 0x4ec 0x004 0x0 0xff0d0100
+#define MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER 0x1d8 0x4ec 0x000 0x1 0x0
+#define MX6QDL_PAD_ENET_RX_ER__ESAI_RX_HF_CLK 0x1d8 0x4ec 0x864 0x2 0x0
+#define MX6QDL_PAD_ENET_RX_ER__SPDIF_IN 0x1d8 0x4ec 0x914 0x3 0x1
+#define MX6QDL_PAD_ENET_RX_ER__ENET_1588_EVENT2_OUT 0x1d8 0x4ec 0x000 0x4 0x0
+#define MX6QDL_PAD_ENET_RX_ER__GPIO1_IO24 0x1d8 0x4ec 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN 0x1dc 0x4f0 0x858 0x1 0x1
+#define MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK 0x1dc 0x4f0 0x870 0x2 0x0
+#define MX6QDL_PAD_ENET_CRS_DV__SPDIF_EXT_CLK 0x1dc 0x4f0 0x918 0x3 0x1
+#define MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x1dc 0x4f0 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_RXD1__MLB_SIG 0x1e0 0x4f4 0x908 0x0 0x0
+#define MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1 0x1e0 0x4f4 0x84c 0x1 0x1
+#define MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS 0x1e0 0x4f4 0x860 0x2 0x0
+#define MX6QDL_PAD_ENET_RXD1__ENET_1588_EVENT3_OUT 0x1e0 0x4f4 0x000 0x4 0x0
+#define MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x1e0 0x4f4 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0 0x1e4 0x4f8 0x848 0x1 0x1
+#define MX6QDL_PAD_ENET_RXD0__ESAI_TX_HF_CLK 0x1e4 0x4f8 0x868 0x2 0x0
+#define MX6QDL_PAD_ENET_RXD0__SPDIF_OUT 0x1e4 0x4f8 0x000 0x3 0x0
+#define MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x1e4 0x4f8 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1e8 0x4fc 0x000 0x1 0x0
+#define MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2 0x1e8 0x4fc 0x880 0x2 0x0
+#define MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x1e8 0x4fc 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_TXD1__MLB_CLK 0x1ec 0x500 0x900 0x0 0x0
+#define MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1 0x1ec 0x500 0x000 0x1 0x0
+#define MX6QDL_PAD_ENET_TXD1__ESAI_TX2_RX3 0x1ec 0x500 0x87c 0x2 0x0
+#define MX6QDL_PAD_ENET_TXD1__ENET_1588_EVENT0_IN 0x1ec 0x500 0x000 0x4 0x0
+#define MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x1ec 0x500 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0 0x1f0 0x504 0x000 0x1 0x0
+#define MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1 0x1f0 0x504 0x884 0x2 0x0
+#define MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x1f0 0x504 0x000 0x5 0x0
+#define MX6QDL_PAD_ENET_MDC__MLB_DATA 0x1f4 0x508 0x904 0x0 0x0
+#define MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1f4 0x508 0x000 0x1 0x0
+#define MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0 0x1f4 0x508 0x888 0x2 0x0
+#define MX6QDL_PAD_ENET_MDC__ENET_1588_EVENT1_IN 0x1f4 0x508 0x000 0x4 0x0
+#define MX6QDL_PAD_ENET_MDC__GPIO1_IO31 0x1f4 0x508 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK 0x1f8 0x5c8 0x7f4 0x0 0x2
+#define MX6QDL_PAD_KEY_COL0__ENET_RX_DATA3 0x1f8 0x5c8 0x854 0x1 0x1
+#define MX6QDL_PAD_KEY_COL0__AUD5_TXC 0x1f8 0x5c8 0x7dc 0x2 0x1
+#define MX6QDL_PAD_KEY_COL0__KEY_COL0 0x1f8 0x5c8 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1f8 0x5c8 0x000 0x4 0x0
+#define MX6QDL_PAD_KEY_COL0__UART4_RX_DATA 0x1f8 0x5c8 0x938 0x4 0x0
+#define MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x1f8 0x5c8 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_COL0__DCIC1_OUT 0x1f8 0x5c8 0x000 0x6 0x0
+#define MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI 0x1fc 0x5cc 0x7fc 0x0 0x2
+#define MX6QDL_PAD_KEY_ROW0__ENET_TX_DATA3 0x1fc 0x5cc 0x000 0x1 0x0
+#define MX6QDL_PAD_KEY_ROW0__AUD5_TXD 0x1fc 0x5cc 0x7d0 0x2 0x1
+#define MX6QDL_PAD_KEY_ROW0__KEY_ROW0 0x1fc 0x5cc 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1fc 0x5cc 0x938 0x4 0x1
+#define MX6QDL_PAD_KEY_ROW0__UART4_TX_DATA 0x1fc 0x5cc 0x000 0x4 0x0
+#define MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x1fc 0x5cc 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_ROW0__DCIC2_OUT 0x1fc 0x5cc 0x000 0x6 0x0
+#define MX6QDL_PAD_KEY_COL1__ECSPI1_MISO 0x200 0x5d0 0x7f8 0x0 0x2
+#define MX6QDL_PAD_KEY_COL1__ENET_MDIO 0x200 0x5d0 0x840 0x1 0x1
+#define MX6QDL_PAD_KEY_COL1__AUD5_TXFS 0x200 0x5d0 0x7e0 0x2 0x1
+#define MX6QDL_PAD_KEY_COL1__KEY_COL1 0x200 0x5d0 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x200 0x5d0 0x000 0x4 0x0
+#define MX6QDL_PAD_KEY_COL1__UART5_RX_DATA 0x200 0x5d0 0x940 0x4 0x0
+#define MX6QDL_PAD_KEY_COL1__GPIO4_IO08 0x200 0x5d0 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_COL1__SD1_VSELECT 0x200 0x5d0 0x000 0x6 0x0
+#define MX6QDL_PAD_KEY_ROW1__ECSPI1_SS0 0x204 0x5d4 0x800 0x0 0x2
+#define MX6QDL_PAD_KEY_ROW1__ENET_COL 0x204 0x5d4 0x000 0x1 0x0
+#define MX6QDL_PAD_KEY_ROW1__AUD5_RXD 0x204 0x5d4 0x7cc 0x2 0x1
+#define MX6QDL_PAD_KEY_ROW1__KEY_ROW1 0x204 0x5d4 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x204 0x5d4 0x940 0x4 0x1
+#define MX6QDL_PAD_KEY_ROW1__UART5_TX_DATA 0x204 0x5d4 0x000 0x4 0x0
+#define MX6QDL_PAD_KEY_ROW1__GPIO4_IO09 0x204 0x5d4 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_ROW1__SD2_VSELECT 0x204 0x5d4 0x000 0x6 0x0
+#define MX6QDL_PAD_KEY_COL2__ECSPI1_SS1 0x208 0x5d8 0x804 0x0 0x2
+#define MX6QDL_PAD_KEY_COL2__ENET_RX_DATA2 0x208 0x5d8 0x850 0x1 0x1
+#define MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x208 0x5d8 0x000 0x2 0x0
+#define MX6QDL_PAD_KEY_COL2__KEY_COL2 0x208 0x5d8 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_COL2__ENET_MDC 0x208 0x5d8 0x000 0x4 0x0
+#define MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x208 0x5d8 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_COL2__USB_H1_PWR_CTL_WAKE 0x208 0x5d8 0x000 0x6 0x0
+#define MX6QDL_PAD_KEY_ROW2__ECSPI1_SS2 0x20c 0x5dc 0x808 0x0 0x1
+#define MX6QDL_PAD_KEY_ROW2__ENET_TX_DATA2 0x20c 0x5dc 0x000 0x1 0x0
+#define MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x20c 0x5dc 0x7e4 0x2 0x0
+#define MX6QDL_PAD_KEY_ROW2__KEY_ROW2 0x20c 0x5dc 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_ROW2__SD2_VSELECT 0x20c 0x5dc 0x000 0x4 0x0
+#define MX6QDL_PAD_KEY_ROW2__GPIO4_IO11 0x20c 0x5dc 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x20c 0x5dc 0x88c 0x6 0x1
+#define MX6QDL_PAD_KEY_COL3__ECSPI1_SS3 0x210 0x5e0 0x80c 0x0 0x1
+#define MX6QDL_PAD_KEY_COL3__ENET_CRS 0x210 0x5e0 0x000 0x1 0x0
+#define MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x210 0x5e0 0x890 0x2 0x1
+#define MX6QDL_PAD_KEY_COL3__KEY_COL3 0x210 0x5e0 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x210 0x5e0 0x8a0 0x4 0x1
+#define MX6QDL_PAD_KEY_COL3__GPIO4_IO12 0x210 0x5e0 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_COL3__SPDIF_IN 0x210 0x5e0 0x914 0x6 0x2
+#define MX6QDL_PAD_KEY_ROW3__ASRC_EXT_CLK 0x214 0x5e4 0x7b0 0x1 0x0
+#define MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x214 0x5e4 0x894 0x2 0x1
+#define MX6QDL_PAD_KEY_ROW3__KEY_ROW3 0x214 0x5e4 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x214 0x5e4 0x8a4 0x4 0x1
+#define MX6QDL_PAD_KEY_ROW3__GPIO4_IO13 0x214 0x5e4 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_ROW3__SD1_VSELECT 0x214 0x5e4 0x000 0x6 0x0
+#define MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x218 0x5e8 0x000 0x0 0x0
+#define MX6QDL_PAD_KEY_COL4__IPU1_SISG4 0x218 0x5e8 0x000 0x1 0x0
+#define MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x218 0x5e8 0x944 0x2 0x1
+#define MX6QDL_PAD_KEY_COL4__KEY_COL4 0x218 0x5e8 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_COL4__UART5_RTS_B 0x218 0x5e8 0x93c 0x4 0x0
+#define MX6QDL_PAD_KEY_COL4__UART5_CTS_B 0x218 0x5e8 0x000 0x4 0x0
+#define MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x218 0x5e8 0x000 0x5 0x0
+#define MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x21c 0x5ec 0x7e8 0x0 0x0
+#define MX6QDL_PAD_KEY_ROW4__IPU1_SISG5 0x21c 0x5ec 0x000 0x1 0x0
+#define MX6QDL_PAD_KEY_ROW4__USB_OTG_PWR 0x21c 0x5ec 0x000 0x2 0x0
+#define MX6QDL_PAD_KEY_ROW4__KEY_ROW4 0x21c 0x5ec 0x000 0x3 0x0
+#define MX6QDL_PAD_KEY_ROW4__UART5_CTS_B 0x21c 0x5ec 0x000 0x4 0x0
+#define MX6QDL_PAD_KEY_ROW4__UART5_RTS_B 0x21c 0x5ec 0x93c 0x4 0x1
+#define MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x21c 0x5ec 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x220 0x5f0 0x000 0x0 0x0
+#define MX6QDL_PAD_GPIO_0__KEY_COL5 0x220 0x5f0 0x8e8 0x2 0x0
+#define MX6QDL_PAD_GPIO_0__ASRC_EXT_CLK 0x220 0x5f0 0x7b0 0x3 0x1
+#define MX6QDL_PAD_GPIO_0__EPIT1_OUT 0x220 0x5f0 0x000 0x4 0x0
+#define MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x220 0x5f0 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_0__USB_H1_PWR 0x220 0x5f0 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_0__SNVS_VIO_5 0x220 0x5f0 0x000 0x7 0x0
+#define MX6QDL_PAD_GPIO_1__ESAI_RX_CLK 0x224 0x5f4 0x86c 0x0 0x1
+#define MX6QDL_PAD_GPIO_1__WDOG2_B 0x224 0x5f4 0x000 0x1 0x0
+#define MX6QDL_PAD_GPIO_1__KEY_ROW5 0x224 0x5f4 0x8f4 0x2 0x0
+#define MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x224 0x5f4 0x004 0x3 0xff0d0101
+#define MX6QDL_PAD_GPIO_1__PWM2_OUT 0x224 0x5f4 0x000 0x4 0x0
+#define MX6QDL_PAD_GPIO_1__GPIO1_IO01 0x224 0x5f4 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_1__SD1_CD_B 0x224 0x5f4 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_9__ESAI_RX_FS 0x228 0x5f8 0x85c 0x0 0x1
+#define MX6QDL_PAD_GPIO_9__WDOG1_B 0x228 0x5f8 0x000 0x1 0x0
+#define MX6QDL_PAD_GPIO_9__KEY_COL6 0x228 0x5f8 0x8ec 0x2 0x0
+#define MX6QDL_PAD_GPIO_9__CCM_REF_EN_B 0x228 0x5f8 0x000 0x3 0x0
+#define MX6QDL_PAD_GPIO_9__PWM1_OUT 0x228 0x5f8 0x000 0x4 0x0
+#define MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x228 0x5f8 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_9__SD1_WP 0x228 0x5f8 0x94c 0x6 0x1
+#define MX6QDL_PAD_GPIO_3__ESAI_RX_HF_CLK 0x22c 0x5fc 0x864 0x0 0x1
+#define MX6QDL_PAD_GPIO_3__I2C3_SCL 0x22c 0x5fc 0x8a8 0x2 0x1
+#define MX6QDL_PAD_GPIO_3__XTALOSC_REF_CLK_24M 0x22c 0x5fc 0x000 0x3 0x0
+#define MX6QDL_PAD_GPIO_3__CCM_CLKO2 0x22c 0x5fc 0x000 0x4 0x0
+#define MX6QDL_PAD_GPIO_3__GPIO1_IO03 0x22c 0x5fc 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_3__USB_H1_OC 0x22c 0x5fc 0x948 0x6 0x1
+#define MX6QDL_PAD_GPIO_3__MLB_CLK 0x22c 0x5fc 0x900 0x7 0x1
+#define MX6QDL_PAD_GPIO_6__ESAI_TX_CLK 0x230 0x600 0x870 0x0 0x1
+#define MX6QDL_PAD_GPIO_6__ENET_IRQ 0x230 0x600 0x03c 0x11 0xff000609
+#define MX6QDL_PAD_GPIO_6__I2C3_SDA 0x230 0x600 0x8ac 0x2 0x1
+#define MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x230 0x600 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_6__SD2_LCTL 0x230 0x600 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_6__MLB_SIG 0x230 0x600 0x908 0x7 0x1
+#define MX6QDL_PAD_GPIO_2__ESAI_TX_FS 0x234 0x604 0x860 0x0 0x1
+#define MX6QDL_PAD_GPIO_2__KEY_ROW6 0x234 0x604 0x8f8 0x2 0x1
+#define MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x234 0x604 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_2__SD2_WP 0x234 0x604 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_2__MLB_DATA 0x234 0x604 0x904 0x7 0x1
+#define MX6QDL_PAD_GPIO_4__ESAI_TX_HF_CLK 0x238 0x608 0x868 0x0 0x1
+#define MX6QDL_PAD_GPIO_4__KEY_COL7 0x238 0x608 0x8f0 0x2 0x1
+#define MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x238 0x608 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_4__SD2_CD_B 0x238 0x608 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_5__ESAI_TX2_RX3 0x23c 0x60c 0x87c 0x0 0x1
+#define MX6QDL_PAD_GPIO_5__KEY_ROW7 0x23c 0x60c 0x8fc 0x2 0x1
+#define MX6QDL_PAD_GPIO_5__CCM_CLKO1 0x23c 0x60c 0x000 0x3 0x0
+#define MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x23c 0x60c 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_5__I2C3_SCL 0x23c 0x60c 0x8a8 0x6 0x2
+#define MX6QDL_PAD_GPIO_5__ARM_EVENTI 0x23c 0x60c 0x000 0x7 0x0
+#define MX6QDL_PAD_GPIO_7__ESAI_TX4_RX1 0x240 0x610 0x884 0x0 0x1
+#define MX6QDL_PAD_GPIO_7__ECSPI5_RDY 0x240 0x610 0x000 0x1 0x0
+#define MX6QDL_PAD_GPIO_7__EPIT1_OUT 0x240 0x610 0x000 0x2 0x0
+#define MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x240 0x610 0x000 0x3 0x0
+#define MX6QDL_PAD_GPIO_7__UART2_TX_DATA 0x240 0x610 0x000 0x4 0x0
+#define MX6QDL_PAD_GPIO_7__UART2_RX_DATA 0x240 0x610 0x928 0x4 0x2
+#define MX6QDL_PAD_GPIO_7__GPIO1_IO07 0x240 0x610 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_7__SPDIF_LOCK 0x240 0x610 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_7__USB_OTG_HOST_MODE 0x240 0x610 0x000 0x7 0x0
+#define MX6QDL_PAD_GPIO_8__ESAI_TX5_RX0 0x244 0x614 0x888 0x0 0x1
+#define MX6QDL_PAD_GPIO_8__XTALOSC_REF_CLK_32K 0x244 0x614 0x000 0x1 0x0
+#define MX6QDL_PAD_GPIO_8__EPIT2_OUT 0x244 0x614 0x000 0x2 0x0
+#define MX6QDL_PAD_GPIO_8__FLEXCAN1_RX 0x244 0x614 0x7e4 0x3 0x1
+#define MX6QDL_PAD_GPIO_8__UART2_RX_DATA 0x244 0x614 0x928 0x4 0x3
+#define MX6QDL_PAD_GPIO_8__UART2_TX_DATA 0x244 0x614 0x000 0x4 0x0
+#define MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x244 0x614 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_8__SPDIF_SR_CLK 0x244 0x614 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_8__USB_OTG_PWR_CTL_WAKE 0x244 0x614 0x000 0x7 0x0
+#define MX6QDL_PAD_GPIO_16__ESAI_TX3_RX2 0x248 0x618 0x880 0x0 0x1
+#define MX6QDL_PAD_GPIO_16__ENET_1588_EVENT2_IN 0x248 0x618 0x000 0x1 0x0
+#define MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x248 0x618 0x83c 0x2 0x1
+#define MX6QDL_PAD_GPIO_16__SD1_LCTL 0x248 0x618 0x000 0x3 0x0
+#define MX6QDL_PAD_GPIO_16__SPDIF_IN 0x248 0x618 0x914 0x4 0x3
+#define MX6QDL_PAD_GPIO_16__GPIO7_IO11 0x248 0x618 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_16__I2C3_SDA 0x248 0x618 0x8ac 0x6 0x2
+#define MX6QDL_PAD_GPIO_16__JTAG_DE_B 0x248 0x618 0x000 0x7 0x0
+#define MX6QDL_PAD_GPIO_17__ESAI_TX0 0x24c 0x61c 0x874 0x0 0x0
+#define MX6QDL_PAD_GPIO_17__ENET_1588_EVENT3_IN 0x24c 0x61c 0x000 0x1 0x0
+#define MX6QDL_PAD_GPIO_17__CCM_PMIC_READY 0x24c 0x61c 0x7f0 0x2 0x1
+#define MX6QDL_PAD_GPIO_17__SDMA_EXT_EVENT0 0x24c 0x61c 0x90c 0x3 0x1
+#define MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x24c 0x61c 0x000 0x4 0x0
+#define MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x24c 0x61c 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_18__ESAI_TX1 0x250 0x620 0x878 0x0 0x0
+#define MX6QDL_PAD_GPIO_18__ENET_RX_CLK 0x250 0x620 0x844 0x1 0x1
+#define MX6QDL_PAD_GPIO_18__SD3_VSELECT 0x250 0x620 0x000 0x2 0x0
+#define MX6QDL_PAD_GPIO_18__SDMA_EXT_EVENT1 0x250 0x620 0x910 0x3 0x1
+#define MX6QDL_PAD_GPIO_18__ASRC_EXT_CLK 0x250 0x620 0x7b0 0x4 0x2
+#define MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x250 0x620 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_18__SNVS_VIO_5_CTL 0x250 0x620 0x000 0x6 0x0
+#define MX6QDL_PAD_GPIO_19__KEY_COL5 0x254 0x624 0x8e8 0x0 0x1
+#define MX6QDL_PAD_GPIO_19__ENET_1588_EVENT0_OUT 0x254 0x624 0x000 0x1 0x0
+#define MX6QDL_PAD_GPIO_19__SPDIF_OUT 0x254 0x624 0x000 0x2 0x0
+#define MX6QDL_PAD_GPIO_19__CCM_CLKO1 0x254 0x624 0x000 0x3 0x0
+#define MX6QDL_PAD_GPIO_19__ECSPI1_RDY 0x254 0x624 0x000 0x4 0x0
+#define MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x254 0x624 0x000 0x5 0x0
+#define MX6QDL_PAD_GPIO_19__ENET_TX_ER 0x254 0x624 0x000 0x6 0x0
+#define MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x258 0x628 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18 0x258 0x628 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_PIXCLK__ARM_EVENTO 0x258 0x628 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x25c 0x62c 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_MCLK__CCM_CLKO1 0x25c 0x62c 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_MCLK__GPIO5_IO19 0x25c 0x62c 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_MCLK__ARM_TRACE_CTL 0x25c 0x62c 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN 0x260 0x630 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DATA_EN__EIM_DATA00 0x260 0x630 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x260 0x630 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DATA_EN__ARM_TRACE_CLK 0x260 0x630 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x264 0x634 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_VSYNC__EIM_DATA01 0x264 0x634 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21 0x264 0x634 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_VSYNC__ARM_TRACE00 0x264 0x634 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT4__IPU1_CSI0_DATA04 0x268 0x638 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT4__EIM_DATA02 0x268 0x638 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT4__ECSPI1_SCLK 0x268 0x638 0x7f4 0x2 0x3
+#define MX6QDL_PAD_CSI0_DAT4__KEY_COL5 0x268 0x638 0x8e8 0x3 0x2
+#define MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x268 0x638 0x000 0x4 0x0
+#define MX6QDL_PAD_CSI0_DAT4__GPIO5_IO22 0x268 0x638 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT4__ARM_TRACE01 0x268 0x638 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT5__IPU1_CSI0_DATA05 0x26c 0x63c 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT5__EIM_DATA03 0x26c 0x63c 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT5__ECSPI1_MOSI 0x26c 0x63c 0x7fc 0x2 0x3
+#define MX6QDL_PAD_CSI0_DAT5__KEY_ROW5 0x26c 0x63c 0x8f4 0x3 0x1
+#define MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x26c 0x63c 0x000 0x4 0x0
+#define MX6QDL_PAD_CSI0_DAT5__GPIO5_IO23 0x26c 0x63c 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT5__ARM_TRACE02 0x26c 0x63c 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT6__IPU1_CSI0_DATA06 0x270 0x640 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT6__EIM_DATA04 0x270 0x640 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT6__ECSPI1_MISO 0x270 0x640 0x7f8 0x2 0x3
+#define MX6QDL_PAD_CSI0_DAT6__KEY_COL6 0x270 0x640 0x8ec 0x3 0x1
+#define MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x270 0x640 0x000 0x4 0x0
+#define MX6QDL_PAD_CSI0_DAT6__GPIO5_IO24 0x270 0x640 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT6__ARM_TRACE03 0x270 0x640 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT7__IPU1_CSI0_DATA07 0x274 0x644 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT7__EIM_DATA05 0x274 0x644 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT7__ECSPI1_SS0 0x274 0x644 0x800 0x2 0x3
+#define MX6QDL_PAD_CSI0_DAT7__KEY_ROW6 0x274 0x644 0x8f8 0x3 0x2
+#define MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x274 0x644 0x000 0x4 0x0
+#define MX6QDL_PAD_CSI0_DAT7__GPIO5_IO25 0x274 0x644 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT7__ARM_TRACE04 0x274 0x644 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT8__IPU1_CSI0_DATA08 0x278 0x648 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT8__EIM_DATA06 0x278 0x648 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT8__ECSPI2_SCLK 0x278 0x648 0x810 0x2 0x2
+#define MX6QDL_PAD_CSI0_DAT8__KEY_COL7 0x278 0x648 0x8f0 0x3 0x2
+#define MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x278 0x648 0x89c 0x4 0x1
+#define MX6QDL_PAD_CSI0_DAT8__GPIO5_IO26 0x278 0x648 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT8__ARM_TRACE05 0x278 0x648 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT9__IPU1_CSI0_DATA09 0x27c 0x64c 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT9__EIM_DATA07 0x27c 0x64c 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT9__ECSPI2_MOSI 0x27c 0x64c 0x818 0x2 0x2
+#define MX6QDL_PAD_CSI0_DAT9__KEY_ROW7 0x27c 0x64c 0x8fc 0x3 0x2
+#define MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x27c 0x64c 0x898 0x4 0x1
+#define MX6QDL_PAD_CSI0_DAT9__GPIO5_IO27 0x27c 0x64c 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT9__ARM_TRACE06 0x27c 0x64c 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT10__IPU1_CSI0_DATA10 0x280 0x650 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT10__AUD3_RXC 0x280 0x650 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT10__ECSPI2_MISO 0x280 0x650 0x814 0x2 0x2
+#define MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x280 0x650 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT10__UART1_RX_DATA 0x280 0x650 0x920 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT10__GPIO5_IO28 0x280 0x650 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT10__ARM_TRACE07 0x280 0x650 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT11__IPU1_CSI0_DATA11 0x284 0x654 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT11__AUD3_RXFS 0x284 0x654 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT11__ECSPI2_SS0 0x284 0x654 0x81c 0x2 0x2
+#define MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x284 0x654 0x920 0x3 0x1
+#define MX6QDL_PAD_CSI0_DAT11__UART1_TX_DATA 0x284 0x654 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT11__GPIO5_IO29 0x284 0x654 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT11__ARM_TRACE08 0x284 0x654 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x288 0x658 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT12__EIM_DATA08 0x288 0x658 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x288 0x658 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT12__UART4_RX_DATA 0x288 0x658 0x938 0x3 0x2
+#define MX6QDL_PAD_CSI0_DAT12__GPIO5_IO30 0x288 0x658 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT12__ARM_TRACE09 0x288 0x658 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x28c 0x65c 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT13__EIM_DATA09 0x28c 0x65c 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x28c 0x65c 0x938 0x3 0x3
+#define MX6QDL_PAD_CSI0_DAT13__UART4_TX_DATA 0x28c 0x65c 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT13__GPIO5_IO31 0x28c 0x65c 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT13__ARM_TRACE10 0x28c 0x65c 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x290 0x660 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT14__EIM_DATA10 0x290 0x660 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT14__UART5_TX_DATA 0x290 0x660 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT14__UART5_RX_DATA 0x290 0x660 0x940 0x3 0x2
+#define MX6QDL_PAD_CSI0_DAT14__GPIO6_IO00 0x290 0x660 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT14__ARM_TRACE11 0x290 0x660 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x294 0x664 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT15__EIM_DATA11 0x294 0x664 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT15__UART5_RX_DATA 0x294 0x664 0x940 0x3 0x3
+#define MX6QDL_PAD_CSI0_DAT15__UART5_TX_DATA 0x294 0x664 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT15__GPIO6_IO01 0x294 0x664 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT15__ARM_TRACE12 0x294 0x664 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x298 0x668 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT16__EIM_DATA12 0x298 0x668 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B 0x298 0x668 0x934 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT16__UART4_CTS_B 0x298 0x668 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT16__GPIO6_IO02 0x298 0x668 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT16__ARM_TRACE13 0x298 0x668 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x29c 0x66c 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT17__EIM_DATA13 0x29c 0x66c 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B 0x29c 0x66c 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT17__UART4_RTS_B 0x29c 0x66c 0x934 0x3 0x1
+#define MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03 0x29c 0x66c 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT17__ARM_TRACE14 0x29c 0x66c 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x2a0 0x670 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT18__EIM_DATA14 0x2a0 0x670 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT18__UART5_RTS_B 0x2a0 0x670 0x93c 0x3 0x2
+#define MX6QDL_PAD_CSI0_DAT18__UART5_CTS_B 0x2a0 0x670 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT18__GPIO6_IO04 0x2a0 0x670 0x000 0x5 0x0
+#define MX6QDL_PAD_CSI0_DAT18__ARM_TRACE15 0x2a0 0x670 0x000 0x7 0x0
+#define MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x2a4 0x674 0x000 0x0 0x0
+#define MX6QDL_PAD_CSI0_DAT19__EIM_DATA15 0x2a4 0x674 0x000 0x1 0x0
+#define MX6QDL_PAD_CSI0_DAT19__UART5_CTS_B 0x2a4 0x674 0x000 0x3 0x0
+#define MX6QDL_PAD_CSI0_DAT19__UART5_RTS_B 0x2a4 0x674 0x93c 0x3 0x3
+#define MX6QDL_PAD_CSI0_DAT19__GPIO6_IO05 0x2a4 0x674 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x2a8 0x690 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x2a8 0x690 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_DAT7__UART1_RX_DATA 0x2a8 0x690 0x920 0x1 0x2
+#define MX6QDL_PAD_SD3_DAT7__GPIO6_IO17 0x2a8 0x690 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x2ac 0x694 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x2ac 0x694 0x920 0x1 0x3
+#define MX6QDL_PAD_SD3_DAT6__UART1_TX_DATA 0x2ac 0x694 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_DAT6__GPIO6_IO18 0x2ac 0x694 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x2b0 0x698 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_DAT5__UART2_TX_DATA 0x2b0 0x698 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_DAT5__UART2_RX_DATA 0x2b0 0x698 0x928 0x1 0x4
+#define MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x2b0 0x698 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x2b4 0x69c 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_DAT4__UART2_RX_DATA 0x2b4 0x69c 0x928 0x1 0x5
+#define MX6QDL_PAD_SD3_DAT4__UART2_TX_DATA 0x2b4 0x69c 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x2b4 0x69c 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_CMD__SD3_CMD 0x2b8 0x6a0 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_CMD__UART2_CTS_B 0x2b8 0x6a0 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_CMD__UART2_RTS_B 0x2b8 0x6a0 0x924 0x1 0x2
+#define MX6QDL_PAD_SD3_CMD__FLEXCAN1_TX 0x2b8 0x6a0 0x000 0x2 0x0
+#define MX6QDL_PAD_SD3_CMD__GPIO7_IO02 0x2b8 0x6a0 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_CLK__SD3_CLK 0x2bc 0x6a4 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_CLK__UART2_RTS_B 0x2bc 0x6a4 0x924 0x1 0x3
+#define MX6QDL_PAD_SD3_CLK__UART2_CTS_B 0x2bc 0x6a4 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_CLK__FLEXCAN1_RX 0x2bc 0x6a4 0x7e4 0x2 0x2
+#define MX6QDL_PAD_SD3_CLK__GPIO7_IO03 0x2bc 0x6a4 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x2c0 0x6a8 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_DAT0__UART1_CTS_B 0x2c0 0x6a8 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_DAT0__UART1_RTS_B 0x2c0 0x6a8 0x91c 0x1 0x2
+#define MX6QDL_PAD_SD3_DAT0__FLEXCAN2_TX 0x2c0 0x6a8 0x000 0x2 0x0
+#define MX6QDL_PAD_SD3_DAT0__GPIO7_IO04 0x2c0 0x6a8 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x2c4 0x6ac 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_DAT1__UART1_RTS_B 0x2c4 0x6ac 0x91c 0x1 0x3
+#define MX6QDL_PAD_SD3_DAT1__UART1_CTS_B 0x2c4 0x6ac 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_DAT1__FLEXCAN2_RX 0x2c4 0x6ac 0x7e8 0x2 0x1
+#define MX6QDL_PAD_SD3_DAT1__GPIO7_IO05 0x2c4 0x6ac 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x2c8 0x6b0 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_DAT2__GPIO7_IO06 0x2c8 0x6b0 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x2cc 0x6b4 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_DAT3__UART3_CTS_B 0x2cc 0x6b4 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_DAT3__UART3_RTS_B 0x2cc 0x6b4 0x92c 0x1 0x4
+#define MX6QDL_PAD_SD3_DAT3__GPIO7_IO07 0x2cc 0x6b4 0x000 0x5 0x0
+#define MX6QDL_PAD_SD3_RST__SD3_RESET 0x2d0 0x6b8 0x000 0x0 0x0
+#define MX6QDL_PAD_SD3_RST__UART3_RTS_B 0x2d0 0x6b8 0x92c 0x1 0x5
+#define MX6QDL_PAD_SD3_RST__UART3_CTS_B 0x2d0 0x6b8 0x000 0x1 0x0
+#define MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x2d0 0x6b8 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_CLE__NAND_CLE 0x2d4 0x6bc 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_CLE__IPU2_SISG4 0x2d4 0x6bc 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x2d4 0x6bc 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_ALE__NAND_ALE 0x2d8 0x6c0 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_ALE__SD4_RESET 0x2d8 0x6c0 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_ALE__GPIO6_IO08 0x2d8 0x6c0 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0x2dc 0x6c4 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_WP_B__IPU2_SISG5 0x2dc 0x6c4 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_WP_B__GPIO6_IO09 0x2dc 0x6c4 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0x2e0 0x6c8 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_RB0__IPU2_DI0_PIN01 0x2e0 0x6c8 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_RB0__GPIO6_IO10 0x2e0 0x6c8 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0x2e4 0x6cc 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x2e4 0x6cc 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0x2e8 0x6d0 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_CS1__SD4_VSELECT 0x2e8 0x6d0 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_CS1__SD3_VSELECT 0x2e8 0x6d0 0x000 0x2 0x0
+#define MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x2e8 0x6d0 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_CS2__NAND_CE2_B 0x2ec 0x6d4 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_CS2__IPU1_SISG0 0x2ec 0x6d4 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_CS2__ESAI_TX0 0x2ec 0x6d4 0x874 0x2 0x1
+#define MX6QDL_PAD_NANDF_CS2__EIM_CRE 0x2ec 0x6d4 0x000 0x3 0x0
+#define MX6QDL_PAD_NANDF_CS2__CCM_CLKO2 0x2ec 0x6d4 0x000 0x4 0x0
+#define MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x2ec 0x6d4 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_CS2__IPU2_SISG0 0x2ec 0x6d4 0x000 0x6 0x0
+#define MX6QDL_PAD_NANDF_CS3__NAND_CE3_B 0x2f0 0x6d8 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_CS3__IPU1_SISG1 0x2f0 0x6d8 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_CS3__ESAI_TX1 0x2f0 0x6d8 0x878 0x2 0x1
+#define MX6QDL_PAD_NANDF_CS3__EIM_ADDR26 0x2f0 0x6d8 0x000 0x3 0x0
+#define MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x2f0 0x6d8 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_CS3__IPU2_SISG1 0x2f0 0x6d8 0x000 0x6 0x0
+#define MX6QDL_PAD_SD4_CMD__SD4_CMD 0x2f4 0x6dc 0x000 0x0 0x0
+#define MX6QDL_PAD_SD4_CMD__NAND_RE_B 0x2f4 0x6dc 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_CMD__UART3_TX_DATA 0x2f4 0x6dc 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_CMD__UART3_RX_DATA 0x2f4 0x6dc 0x930 0x2 0x2
+#define MX6QDL_PAD_SD4_CMD__GPIO7_IO09 0x2f4 0x6dc 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_CLK__SD4_CLK 0x2f8 0x6e0 0x000 0x0 0x0
+#define MX6QDL_PAD_SD4_CLK__NAND_WE_B 0x2f8 0x6e0 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_CLK__UART3_RX_DATA 0x2f8 0x6e0 0x930 0x2 0x3
+#define MX6QDL_PAD_SD4_CLK__UART3_TX_DATA 0x2f8 0x6e0 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_CLK__GPIO7_IO10 0x2f8 0x6e0 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_D0__NAND_DATA00 0x2fc 0x6e4 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_D0__SD1_DATA4 0x2fc 0x6e4 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x2fc 0x6e4 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_D1__NAND_DATA01 0x300 0x6e8 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_D1__SD1_DATA5 0x300 0x6e8 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x300 0x6e8 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_D2__NAND_DATA02 0x304 0x6ec 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_D2__SD1_DATA6 0x304 0x6ec 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x304 0x6ec 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_D3__NAND_DATA03 0x308 0x6f0 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_D3__SD1_DATA7 0x308 0x6f0 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x308 0x6f0 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_D4__NAND_DATA04 0x30c 0x6f4 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_D4__SD2_DATA4 0x30c 0x6f4 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x30c 0x6f4 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_D5__NAND_DATA05 0x310 0x6f8 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_D5__SD2_DATA5 0x310 0x6f8 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x310 0x6f8 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_D6__NAND_DATA06 0x314 0x6fc 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_D6__SD2_DATA6 0x314 0x6fc 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x314 0x6fc 0x000 0x5 0x0
+#define MX6QDL_PAD_NANDF_D7__NAND_DATA07 0x318 0x700 0x000 0x0 0x0
+#define MX6QDL_PAD_NANDF_D7__SD2_DATA7 0x318 0x700 0x000 0x1 0x0
+#define MX6QDL_PAD_NANDF_D7__GPIO2_IO07 0x318 0x700 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x31c 0x704 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x31c 0x704 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_DAT0__GPIO2_IO08 0x31c 0x704 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x320 0x708 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x320 0x708 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_DAT1__GPIO2_IO09 0x320 0x708 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x324 0x70c 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_DAT2__PWM4_OUT 0x324 0x70c 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_DAT2__GPIO2_IO10 0x324 0x70c 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x328 0x710 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_DAT3__GPIO2_IO11 0x328 0x710 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x32c 0x714 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x32c 0x714 0x928 0x2 0x6
+#define MX6QDL_PAD_SD4_DAT4__UART2_TX_DATA 0x32c 0x714 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_DAT4__GPIO2_IO12 0x32c 0x714 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x330 0x718 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_DAT5__UART2_RTS_B 0x330 0x718 0x924 0x2 0x4
+#define MX6QDL_PAD_SD4_DAT5__UART2_CTS_B 0x330 0x718 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_DAT5__GPIO2_IO13 0x330 0x718 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x334 0x71c 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_DAT6__UART2_CTS_B 0x334 0x71c 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_DAT6__UART2_RTS_B 0x334 0x71c 0x924 0x2 0x5
+#define MX6QDL_PAD_SD4_DAT6__GPIO2_IO14 0x334 0x71c 0x000 0x5 0x0
+#define MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x338 0x720 0x000 0x1 0x0
+#define MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x338 0x720 0x000 0x2 0x0
+#define MX6QDL_PAD_SD4_DAT7__UART2_RX_DATA 0x338 0x720 0x928 0x2 0x7
+#define MX6QDL_PAD_SD4_DAT7__GPIO2_IO15 0x338 0x720 0x000 0x5 0x0
+#define MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x33c 0x724 0x000 0x0 0x0
+#define MX6QDL_PAD_SD1_DAT1__ECSPI5_SS0 0x33c 0x724 0x834 0x1 0x1
+#define MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x33c 0x724 0x000 0x2 0x0
+#define MX6QDL_PAD_SD1_DAT1__GPT_CAPTURE2 0x33c 0x724 0x000 0x3 0x0
+#define MX6QDL_PAD_SD1_DAT1__GPIO1_IO17 0x33c 0x724 0x000 0x5 0x0
+#define MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x340 0x728 0x000 0x0 0x0
+#define MX6QDL_PAD_SD1_DAT0__ECSPI5_MISO 0x340 0x728 0x82c 0x1 0x1
+#define MX6QDL_PAD_SD1_DAT0__GPT_CAPTURE1 0x340 0x728 0x000 0x3 0x0
+#define MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x340 0x728 0x000 0x5 0x0
+#define MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x344 0x72c 0x000 0x0 0x0
+#define MX6QDL_PAD_SD1_DAT3__ECSPI5_SS2 0x344 0x72c 0x000 0x1 0x0
+#define MX6QDL_PAD_SD1_DAT3__GPT_COMPARE3 0x344 0x72c 0x000 0x2 0x0
+#define MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x344 0x72c 0x000 0x3 0x0
+#define MX6QDL_PAD_SD1_DAT3__WDOG2_B 0x344 0x72c 0x000 0x4 0x0
+#define MX6QDL_PAD_SD1_DAT3__GPIO1_IO21 0x344 0x72c 0x000 0x5 0x0
+#define MX6QDL_PAD_SD1_DAT3__WDOG2_RESET_B_DEB 0x344 0x72c 0x000 0x6 0x0
+#define MX6QDL_PAD_SD1_CMD__SD1_CMD 0x348 0x730 0x000 0x0 0x0
+#define MX6QDL_PAD_SD1_CMD__ECSPI5_MOSI 0x348 0x730 0x830 0x1 0x0
+#define MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x348 0x730 0x000 0x2 0x0
+#define MX6QDL_PAD_SD1_CMD__GPT_COMPARE1 0x348 0x730 0x000 0x3 0x0
+#define MX6QDL_PAD_SD1_CMD__GPIO1_IO18 0x348 0x730 0x000 0x5 0x0
+#define MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x34c 0x734 0x000 0x0 0x0
+#define MX6QDL_PAD_SD1_DAT2__ECSPI5_SS1 0x34c 0x734 0x838 0x1 0x1
+#define MX6QDL_PAD_SD1_DAT2__GPT_COMPARE2 0x34c 0x734 0x000 0x2 0x0
+#define MX6QDL_PAD_SD1_DAT2__PWM2_OUT 0x34c 0x734 0x000 0x3 0x0
+#define MX6QDL_PAD_SD1_DAT2__WDOG1_B 0x34c 0x734 0x000 0x4 0x0
+#define MX6QDL_PAD_SD1_DAT2__GPIO1_IO19 0x34c 0x734 0x000 0x5 0x0
+#define MX6QDL_PAD_SD1_DAT2__WDOG1_RESET_B_DEB 0x34c 0x734 0x000 0x6 0x0
+#define MX6QDL_PAD_SD1_CLK__SD1_CLK 0x350 0x738 0x000 0x0 0x0
+#define MX6QDL_PAD_SD1_CLK__ECSPI5_SCLK 0x350 0x738 0x828 0x1 0x0
+#define MX6QDL_PAD_SD1_CLK__OSC32K_32K_OUT 0x350 0x738 0x000 0x2 0x0
+#define MX6QDL_PAD_SD1_CLK__GPT_CLKIN 0x350 0x738 0x000 0x3 0x0
+#define MX6QDL_PAD_SD1_CLK__GPIO1_IO20 0x350 0x738 0x000 0x5 0x0
+#define MX6QDL_PAD_SD2_CLK__SD2_CLK 0x354 0x73c 0x000 0x0 0x0
+#define MX6QDL_PAD_SD2_CLK__ECSPI5_SCLK 0x354 0x73c 0x828 0x1 0x1
+#define MX6QDL_PAD_SD2_CLK__KEY_COL5 0x354 0x73c 0x8e8 0x2 0x3
+#define MX6QDL_PAD_SD2_CLK__AUD4_RXFS 0x354 0x73c 0x7c0 0x3 0x1
+#define MX6QDL_PAD_SD2_CLK__GPIO1_IO10 0x354 0x73c 0x000 0x5 0x0
+#define MX6QDL_PAD_SD2_CMD__SD2_CMD 0x358 0x740 0x000 0x0 0x0
+#define MX6QDL_PAD_SD2_CMD__ECSPI5_MOSI 0x358 0x740 0x830 0x1 0x1
+#define MX6QDL_PAD_SD2_CMD__KEY_ROW5 0x358 0x740 0x8f4 0x2 0x2
+#define MX6QDL_PAD_SD2_CMD__AUD4_RXC 0x358 0x740 0x7bc 0x3 0x1
+#define MX6QDL_PAD_SD2_CMD__GPIO1_IO11 0x358 0x740 0x000 0x5 0x0
+#define MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x35c 0x744 0x000 0x0 0x0
+#define MX6QDL_PAD_SD2_DAT3__ECSPI5_SS3 0x35c 0x744 0x000 0x1 0x0
+#define MX6QDL_PAD_SD2_DAT3__KEY_COL6 0x35c 0x744 0x8ec 0x2 0x2
+#define MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x35c 0x744 0x7c4 0x3 0x1
+#define MX6QDL_PAD_SD2_DAT3__GPIO1_IO12 0x35c 0x744 0x000 0x5 0x0
+
+#endif /* __DTS_IMX6Q_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx6q-rex-pro.dts b/arch/arm/boot/dts/imx6q-rex-pro.dts
new file mode 100644
index 000000000..3c2852b16
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-rex-pro.dts
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2014 FEDEVEL, Inc.
+ *
+ * Author: Robert Nelson <robertcnelson@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.
+ *
+ */
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-rex.dtsi"
+
+/ {
+ model = "Rex Pro i.MX6 Quad Board";
+ compatible = "rex,imx6q-rex-pro", "fsl,imx6q";
+
+ memory {
+ reg = <0x10000000 0x80000000>;
+ };
+};
+
+&ecspi3 {
+ flash: m25p80@0 {
+ compatible = "sst,sst25vf032b";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-sabreauto.dts b/arch/arm/boot/dts/imx6q-sabreauto.dts
new file mode 100644
index 000000000..334b9247e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabreauto.dts
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-sabreauto.dtsi"
+
+/ {
+ model = "Freescale i.MX6 Quad SABRE Automotive Board";
+ compatible = "fsl,imx6q-sabreauto", "fsl,imx6q";
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-sabrelite.dts b/arch/arm/boot/dts/imx6q-sabrelite.dts
new file mode 100644
index 000000000..96e4688be
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabrelite.dts
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-sabrelite.dtsi"
+
+/ {
+ model = "Freescale i.MX6 Quad SABRE Lite Board";
+ compatible = "fsl,imx6q-sabrelite", "fsl,imx6q";
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-sabresd.dts b/arch/arm/boot/dts/imx6q-sabresd.dts
new file mode 100644
index 000000000..9cbdfe7a0
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabresd.dts
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-sabresd.dtsi"
+
+/ {
+ model = "Freescale i.MX6 Quad SABRE Smart Device Board";
+ compatible = "fsl,imx6q-sabresd", "fsl,imx6q";
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-sbc6x.dts b/arch/arm/boot/dts/imx6q-sbc6x.dts
new file mode 100644
index 000000000..86cf09364
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sbc6x.dts
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2013 Pavel Machek <pavel@denx.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License V2.
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+
+/ {
+ model = "MicroSys sbc6x board";
+ compatible = "microsys,sbc6x", "fsl,imx6q";
+
+ memory {
+ reg = <0x10000000 0x80000000>;
+ };
+};
+
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ status = "okay";
+};
+
+&iomuxc {
+ imx6q-sbc6x {
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ >;
+ };
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&usbotg {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-tbs2910.dts b/arch/arm/boot/dts/imx6q-tbs2910.dts
new file mode 100644
index 000000000..a43abfa21
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-tbs2910.dts
@@ -0,0 +1,432 @@
+/*
+ * Copyright 2014 Soeren Moch <smoch@web.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "TBS2910 Matrix ARM mini PC";
+ compatible = "tbs,imx6q-tbs2910", "fsl,imx6q";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory {
+ reg = <0x10000000 0x80000000>;
+ };
+
+ fan {
+ compatible = "gpio-fan";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_fan>;
+ gpios = <&gpio3 28 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = <0 0
+ 3000 1>;
+ };
+
+ ir_recv {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio3 18 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ir>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ blue {
+ label = "blue_status_led";
+ gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+ default-state = "keep";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_2p5v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "2P5V";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ };
+
+ reg_3p3v: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_5p0v: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "5P0V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+ };
+
+ sound-sgtl5000 {
+ audio-codec = <&sgtl5000>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ compatible = "fsl,imx-audio-sgtl5000";
+ model = "On-board Codec";
+ mux-ext-port = <3>;
+ mux-int-port = <1>;
+ ssi-controller = <&ssi1>;
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "On-board SPDIF";
+ spdif-controller = <&spdif>;
+ spdif-out;
+ };
+};
+
+&audmux {
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&hdmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi>;
+ ddc-i2c-bus = <&i2c2>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ sgtl5000: sgtl5000@0a {
+ clocks = <&clks 201>;
+ compatible = "fsl,sgtl5000";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sgtl5000>;
+ reg = <0x0a>;
+ VDDA-supply = <&reg_2p5v>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ rtc: ds1307@68 {
+ compatible = "dallas,ds1307";
+ reg = <0x68>;
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&sata {
+ status = "okay";
+};
+
+&snvs_poweroff {
+ status = "okay";
+};
+
+&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif>;
+ status = "okay";
+};
+
+&ssi1 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_5p0v>;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_5p0v>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ bus-width = <4>;
+ cd-gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ bus-width = <4>;
+ cd-gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>;
+ wp-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ bus-width = <8>;
+ non-removable;
+ no-1-8-v;
+ status = "okay";
+};
+
+&iomuxc {
+ imx6q-tbs2910 {
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x1b059
+ >;
+ };
+
+ pinctrl_hdmi: hdmigrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_ir: irgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D18__GPIO3_IO18 0x17059
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x17059
+ >;
+ };
+
+ pinctrl_sgtl5000: sgtl5000grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
+ MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
+ MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0
+ MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0
+ >;
+ };
+
+ pinctrl_spdif: spdifgrp {
+ fsl,pins = <MX6QDL_PAD_GPIO_19__SPDIF_OUT 0x13091
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
+ MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x17059
+ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x17059
+ >;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
+ MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
+ MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
+ MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
+ MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
+ MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
+ MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
+ MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
+ MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
+ MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
+ >;
+ };
+ };
+
+ gpio_fan {
+ pinctrl_gpio_fan: gpiofangrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D28__GPIO3_IO28 0x130b1
+ >;
+ };
+ };
+
+ gpio_leds {
+ pinctrl_gpio_leds: gpioledsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x130b1
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6q-tx6q-1010-comtft.dts b/arch/arm/boot/dts/imx6q-tx6q-1010-comtft.dts
new file mode 100644
index 000000000..b18fae10b
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-tx6q-1010-comtft.dts
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2014 Lothar WaĂŸmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-tx6.dtsi"
+
+/ {
+ model = "Ka-Ro electronics TX6Q-1010 Module on CoMpact TFT";
+ compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+
+ aliases {
+ display = &display;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm2 0 500000 0>;
+ power-supply = <&reg_3v3>;
+ /*
+ * a poor man's way to create a 1:1 relationship between
+ * the PWM value and the actual duty cycle
+ */
+ brightness-levels = < 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 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <50>;
+ };
+
+ display: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ interface-pix-fmt = "rgb24";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_disp0_1>;
+ status = "okay";
+
+ port {
+ display0_in: endpoint {
+ remote-endpoint = <&ipu1_di0_disp0>;
+ };
+ };
+
+ display-timings {
+ native-mode = <&ET070001DM6>;
+
+ ET070001DM6: CoMTFT { /* same as ET0700 but with inverted pixel clock */
+ clock-frequency = <33264000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <88>;
+ hsync-len = <128>;
+ hfront-porch = <40>;
+ vback-porch = <33>;
+ vsync-len = <2>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+};
+
+&can1 {
+ status = "disabled";
+};
+
+&can2 {
+ xceiver-supply = <&reg_3v3>;
+};
+
+&ipu1_di0_disp0 {
+ remote-endpoint = <&display0_in>;
+};
+
+&kpp {
+ status = "disabled";
+};
+
+&reg_can_xcvr {
+ status = "disabled";
+};
+
+&touchscreen {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6q-tx6q-1010.dts b/arch/arm/boot/dts/imx6q-tx6q-1010.dts
new file mode 100644
index 000000000..b58ec9c96
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-tx6q-1010.dts
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2014 Lothar WaĂŸmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-tx6.dtsi"
+
+/ {
+ model = "Ka-Ro electronics TX6Q-1010 Module";
+ compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+
+ aliases {
+ display = &display;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm2 0 500000 PWM_POLARITY_INVERTED>;
+ power-supply = <&reg_3v3>;
+ /*
+ * a poor man's way to create a 1:1 relationship between
+ * the PWM value and the actual duty cycle
+ */
+ brightness-levels = < 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 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <50>;
+ };
+
+ display: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ interface-pix-fmt = "rgb24";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_disp0_1>;
+ status = "okay";
+
+ port {
+ display0_in: endpoint {
+ remote-endpoint = <&ipu1_di0_disp0>;
+ };
+ };
+
+ display-timings {
+ VGA {
+ clock-frequency = <25200000>;
+ hactive = <640>;
+ vactive = <480>;
+ hback-porch = <48>;
+ hsync-len = <96>;
+ hfront-porch = <16>;
+ vback-porch = <31>;
+ vsync-len = <2>;
+ vfront-porch = <12>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ETV570 {
+ clock-frequency = <25200000>;
+ hactive = <640>;
+ vactive = <480>;
+ hback-porch = <114>;
+ hsync-len = <30>;
+ hfront-porch = <16>;
+ vback-porch = <32>;
+ vsync-len = <3>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ET0350 {
+ clock-frequency = <6413760>;
+ hactive = <320>;
+ vactive = <240>;
+ hback-porch = <34>;
+ hsync-len = <34>;
+ hfront-porch = <20>;
+ vback-porch = <15>;
+ vsync-len = <3>;
+ vfront-porch = <4>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ET0430 {
+ clock-frequency = <9009000>;
+ hactive = <480>;
+ vactive = <272>;
+ hback-porch = <2>;
+ hsync-len = <41>;
+ hfront-porch = <2>;
+ vback-porch = <2>;
+ vsync-len = <10>;
+ vfront-porch = <2>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+
+ ET0500 {
+ clock-frequency = <33264000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <88>;
+ hsync-len = <128>;
+ hfront-porch = <40>;
+ vback-porch = <33>;
+ vsync-len = <2>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ET0700 { /* same as ET0500 */
+ clock-frequency = <33264000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <88>;
+ hsync-len = <128>;
+ hfront-porch = <40>;
+ vback-porch = <33>;
+ vsync-len = <2>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ETQ570 {
+ clock-frequency = <6596040>;
+ hactive = <320>;
+ vactive = <240>;
+ hback-porch = <38>;
+ hsync-len = <30>;
+ hfront-porch = <30>;
+ vback-porch = <16>;
+ vsync-len = <3>;
+ vfront-porch = <4>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&ipu1_di0_disp0 {
+ remote-endpoint = <&display0_in>;
+};
diff --git a/arch/arm/boot/dts/imx6q-tx6q-1020-comtft.dts b/arch/arm/boot/dts/imx6q-tx6q-1020-comtft.dts
new file mode 100644
index 000000000..0bb9a9de6
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-tx6q-1020-comtft.dts
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2014 Lothar WaĂŸmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-tx6.dtsi"
+
+/ {
+ model = "Ka-Ro electronics TX6Q-1020 Module on CoMpact TFT";
+ compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+
+ aliases {
+ display = &display;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm2 0 500000 0>;
+ power-supply = <&reg_3v3>;
+ /*
+ * a poor man's way to create a 1:1 relationship between
+ * the PWM value and the actual duty cycle
+ */
+ brightness-levels = < 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 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <50>;
+ };
+
+ display: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ interface-pix-fmt = "rgb24";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_disp0_1>;
+ status = "okay";
+
+ port {
+ display0_in: endpoint {
+ remote-endpoint = <&ipu1_di0_disp0>;
+ };
+ };
+
+ display-timings {
+ native-mode = <&ET070001DM6>;
+
+ ET070001DM6: CoMTFT { /* same as ET0700 but with inverted pixel clock */
+ clock-frequency = <33264000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <88>;
+ hsync-len = <128>;
+ hfront-porch = <40>;
+ vback-porch = <33>;
+ vsync-len = <2>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+};
+
+&can1 {
+ status = "disabled";
+};
+
+&can2 {
+ xceiver-supply = <&reg_3v3>;
+};
+
+&ds1339 {
+ status = "disabled";
+};
+
+&gpmi {
+ status = "disabled";
+};
+
+&iomuxc {
+ imx6qdl-tx6 {
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CMD__SD4_CMD 0x070b1
+ MX6QDL_PAD_SD4_CLK__SD4_CLK 0x070b1
+ MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x070b1
+ MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x070b1
+ MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x070b1
+ MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x070b1
+ MX6QDL_PAD_NANDF_ALE__SD4_RESET 0x0b0b1
+ >;
+ };
+ };
+};
+
+&ipu1_di0_disp0 {
+ remote-endpoint = <&display0_in>;
+};
+
+&kpp {
+ status = "disabled";
+};
+
+&reg_can_xcvr {
+ status = "disabled";
+};
+
+&touchscreen {
+ status = "disabled";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ bus-width = <4>;
+ no-1-8-v;
+ fsl,wp-controller;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-tx6q-1020.dts b/arch/arm/boot/dts/imx6q-tx6q-1020.dts
new file mode 100644
index 000000000..b96d80a35
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-tx6q-1020.dts
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2014 Lothar WaĂŸmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-tx6.dtsi"
+
+/ {
+ model = "Ka-Ro electronics TX6Q-1020 Module";
+ compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+
+ aliases {
+ display = &display;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm2 0 500000 PWM_POLARITY_INVERTED>;
+ power-supply = <&reg_3v3>;
+ /*
+ * a poor man's way to create a 1:1 relationship between
+ * the PWM value and the actual duty cycle
+ */
+ brightness-levels = < 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 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <50>;
+ };
+
+ display: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ interface-pix-fmt = "rgb24";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_disp0_1>;
+ status = "okay";
+
+ port {
+ display0_in: endpoint {
+ remote-endpoint = <&ipu1_di0_disp0>;
+ };
+ };
+
+ display-timings {
+ VGA {
+ clock-frequency = <25200000>;
+ hactive = <640>;
+ vactive = <480>;
+ hback-porch = <48>;
+ hsync-len = <96>;
+ hfront-porch = <16>;
+ vback-porch = <31>;
+ vsync-len = <2>;
+ vfront-porch = <12>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ETV570 {
+ clock-frequency = <25200000>;
+ hactive = <640>;
+ vactive = <480>;
+ hback-porch = <114>;
+ hsync-len = <30>;
+ hfront-porch = <16>;
+ vback-porch = <32>;
+ vsync-len = <3>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ET0350 {
+ clock-frequency = <6413760>;
+ hactive = <320>;
+ vactive = <240>;
+ hback-porch = <34>;
+ hsync-len = <34>;
+ hfront-porch = <20>;
+ vback-porch = <15>;
+ vsync-len = <3>;
+ vfront-porch = <4>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ET0430 {
+ clock-frequency = <9009000>;
+ hactive = <480>;
+ vactive = <272>;
+ hback-porch = <2>;
+ hsync-len = <41>;
+ hfront-porch = <2>;
+ vback-porch = <2>;
+ vsync-len = <10>;
+ vfront-porch = <2>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+
+ ET0500 {
+ clock-frequency = <33264000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <88>;
+ hsync-len = <128>;
+ hfront-porch = <40>;
+ vback-porch = <33>;
+ vsync-len = <2>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ET0700 { /* same as ET0500 */
+ clock-frequency = <33264000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <88>;
+ hsync-len = <128>;
+ hfront-porch = <40>;
+ vback-porch = <33>;
+ vsync-len = <2>;
+ vfront-porch = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ ETQ570 {
+ clock-frequency = <6596040>;
+ hactive = <320>;
+ vactive = <240>;
+ hback-porch = <38>;
+ hsync-len = <30>;
+ hfront-porch = <30>;
+ vback-porch = <16>;
+ vsync-len = <3>;
+ vfront-porch = <4>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&ds1339 {
+ status = "disabled";
+};
+
+&gpmi {
+ status = "disabled";
+};
+
+&iomuxc {
+ imx6qdl-tx6 {
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CMD__SD4_CMD 0x070b1
+ MX6QDL_PAD_SD4_CLK__SD4_CLK 0x070b1
+ MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x070b1
+ MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x070b1
+ MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x070b1
+ MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x070b1
+ MX6QDL_PAD_NANDF_ALE__SD4_RESET 0x0b0b1
+ >;
+ };
+ };
+};
+
+&ipu1_di0_disp0 {
+ remote-endpoint = <&display0_in>;
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ bus-width = <4>;
+ no-1-8-v;
+ fsl,wp-controller;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-tx6q-1110.dts b/arch/arm/boot/dts/imx6q-tx6q-1110.dts
new file mode 100644
index 000000000..88aa1e4c7
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-tx6q-1110.dts
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2014 Lothar WaĂŸmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-tx6.dtsi"
+
+/ {
+ model = "Ka-Ro electronics TX6Q-1110 Module";
+ compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+
+ aliases {
+ display = &lvds0;
+ lvds0 = &lvds0;
+ lvds1 = &lvds1;
+ };
+
+ backlight0: backlight0 {
+ compatible = "pwm-backlight";
+ pwms = <&pwm2 0 500000 0>;
+ power-supply = <&reg_lcd0_pwr>;
+ /*
+ * a poor man's way to create a 1:1 relationship between
+ * the PWM value and the actual duty cycle
+ */
+ brightness-levels = < 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 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <50>;
+ };
+
+ backlight1: backlight1 {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 500000 0>;
+ power-supply = <&reg_lcd1_pwr>;
+ /*
+ * a poor man's way to create a 1:1 relationship between
+ * the PWM value and the actual duty cycle
+ */
+ brightness-levels = < 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 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <50>;
+ };
+};
+
+&i2c3 {
+ polytouch1: eeti@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_eeti>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <22 0>;
+ wakeup-gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+ linux,wakeup;
+ };
+};
+
+&iomuxc {
+ imx6q-tx6q-1110 {
+ pinctrl_eeti: eetigrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b1 /* Interrupt */
+ >;
+ };
+ };
+};
+
+&kpp {
+ status = "disabled"; /* pad conflict with backlight1 PWM */
+};
+
+&ldb {
+ status = "okay";
+
+ lvds0: lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&lvds_timing0>;
+ lvds_timing0: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+
+ lvds1: lvds-channel@1 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "disabled";
+
+ display-timings {
+ native-mode = <&lvds_timing1>;
+ lvds_timing1: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-udoo.dts b/arch/arm/boot/dts/imx6q-udoo.dts
new file mode 100644
index 000000000..c3e64ff3d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-udoo.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-udoo.dtsi"
+
+/ {
+ model = "Udoo i.MX6 Quad Board";
+ compatible = "udoo,imx6q-udoo", "fsl,imx6q";
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-wandboard-revb1.dts b/arch/arm/boot/dts/imx6q-wandboard-revb1.dts
new file mode 100644
index 000000000..20bf3c282
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-wandboard-revb1.dts
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-wandboard-revb1.dtsi"
+
+/ {
+ model = "Wandboard i.MX6 Quad Board";
+ compatible = "wand,imx6q-wandboard", "fsl,imx6q";
+
+ memory {
+ reg = <0x10000000 0x80000000>;
+ };
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-wandboard.dts b/arch/arm/boot/dts/imx6q-wandboard.dts
new file mode 100644
index 000000000..4a8a6ee13
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-wandboard.dts
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-wandboard-revc1.dtsi"
+
+/ {
+ model = "Wandboard i.MX6 Quad Board";
+ compatible = "wand,imx6q-wandboard", "fsl,imx6q";
+
+ memory {
+ reg = <0x10000000 0x80000000>;
+ };
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
new file mode 100644
index 000000000..399103b8e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -0,0 +1,318 @@
+
+/*
+ * Copyright 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "imx6q-pinfunc.h"
+#include "imx6qdl.dtsi"
+
+/ {
+ aliases {
+ spi4 = &ecspi5;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ operating-points = <
+ /* kHz uV */
+ 1200000 1275000
+ 996000 1250000
+ 852000 1250000
+ 792000 1175000
+ 396000 975000
+ >;
+ fsl,soc-operating-points = <
+ /* ARM kHz SOC-PU uV */
+ 1200000 1275000
+ 996000 1250000
+ 852000 1250000
+ 792000 1175000
+ 396000 1175000
+ >;
+ clock-latency = <61036>; /* two CLK32 periods */
+ clocks = <&clks IMX6QDL_CLK_ARM>,
+ <&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
+ <&clks IMX6QDL_CLK_STEP>,
+ <&clks IMX6QDL_CLK_PLL1_SW>,
+ <&clks IMX6QDL_CLK_PLL1_SYS>;
+ clock-names = "arm", "pll2_pfd2_396m", "step",
+ "pll1_sw", "pll1_sys";
+ arm-supply = <&reg_arm>;
+ pu-supply = <&reg_pu>;
+ soc-supply = <&reg_soc>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ };
+
+ cpu@2 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <2>;
+ next-level-cache = <&L2>;
+ };
+
+ cpu@3 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <3>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ soc {
+ ocram: sram@00900000 {
+ compatible = "mmio-sram";
+ reg = <0x00900000 0x40000>;
+ clocks = <&clks IMX6QDL_CLK_OCRAM>;
+ };
+
+ aips-bus@02000000 { /* AIPS1 */
+ spba-bus@02000000 {
+ ecspi5: ecspi@02018000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02018000 0x4000>;
+ interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6Q_CLK_ECSPI5>,
+ <&clks IMX6Q_CLK_ECSPI5>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 11 7 1>, <&sdma 12 7 2>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ };
+
+ iomuxc: iomuxc@020e0000 {
+ compatible = "fsl,imx6q-iomuxc";
+
+ ipu2 {
+ pinctrl_ipu2_1: ipu2grp-1 {
+ fsl,pins = <
+ MX6QDL_PAD_DI0_DISP_CLK__IPU2_DI0_DISP_CLK 0x10
+ MX6QDL_PAD_DI0_PIN15__IPU2_DI0_PIN15 0x10
+ MX6QDL_PAD_DI0_PIN2__IPU2_DI0_PIN02 0x10
+ MX6QDL_PAD_DI0_PIN3__IPU2_DI0_PIN03 0x10
+ MX6QDL_PAD_DI0_PIN4__IPU2_DI0_PIN04 0x80000000
+ MX6QDL_PAD_DISP0_DAT0__IPU2_DISP0_DATA00 0x10
+ MX6QDL_PAD_DISP0_DAT1__IPU2_DISP0_DATA01 0x10
+ MX6QDL_PAD_DISP0_DAT2__IPU2_DISP0_DATA02 0x10
+ MX6QDL_PAD_DISP0_DAT3__IPU2_DISP0_DATA03 0x10
+ MX6QDL_PAD_DISP0_DAT4__IPU2_DISP0_DATA04 0x10
+ MX6QDL_PAD_DISP0_DAT5__IPU2_DISP0_DATA05 0x10
+ MX6QDL_PAD_DISP0_DAT6__IPU2_DISP0_DATA06 0x10
+ MX6QDL_PAD_DISP0_DAT7__IPU2_DISP0_DATA07 0x10
+ MX6QDL_PAD_DISP0_DAT8__IPU2_DISP0_DATA08 0x10
+ MX6QDL_PAD_DISP0_DAT9__IPU2_DISP0_DATA09 0x10
+ MX6QDL_PAD_DISP0_DAT10__IPU2_DISP0_DATA10 0x10
+ MX6QDL_PAD_DISP0_DAT11__IPU2_DISP0_DATA11 0x10
+ MX6QDL_PAD_DISP0_DAT12__IPU2_DISP0_DATA12 0x10
+ MX6QDL_PAD_DISP0_DAT13__IPU2_DISP0_DATA13 0x10
+ MX6QDL_PAD_DISP0_DAT14__IPU2_DISP0_DATA14 0x10
+ MX6QDL_PAD_DISP0_DAT15__IPU2_DISP0_DATA15 0x10
+ MX6QDL_PAD_DISP0_DAT16__IPU2_DISP0_DATA16 0x10
+ MX6QDL_PAD_DISP0_DAT17__IPU2_DISP0_DATA17 0x10
+ MX6QDL_PAD_DISP0_DAT18__IPU2_DISP0_DATA18 0x10
+ MX6QDL_PAD_DISP0_DAT19__IPU2_DISP0_DATA19 0x10
+ MX6QDL_PAD_DISP0_DAT20__IPU2_DISP0_DATA20 0x10
+ MX6QDL_PAD_DISP0_DAT21__IPU2_DISP0_DATA21 0x10
+ MX6QDL_PAD_DISP0_DAT22__IPU2_DISP0_DATA22 0x10
+ MX6QDL_PAD_DISP0_DAT23__IPU2_DISP0_DATA23 0x10
+ >;
+ };
+ };
+ };
+ };
+
+ sata: sata@02200000 {
+ compatible = "fsl,imx6q-ahci";
+ reg = <0x02200000 0x4000>;
+ interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_SATA>,
+ <&clks IMX6QDL_CLK_SATA_REF_100M>,
+ <&clks IMX6QDL_CLK_AHB>;
+ clock-names = "sata", "sata_ref", "ahb";
+ status = "disabled";
+ };
+
+ ipu2: ipu@02800000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-ipu";
+ reg = <0x02800000 0x400000>;
+ interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>,
+ <0 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_IPU2>,
+ <&clks IMX6QDL_CLK_IPU2_DI0>,
+ <&clks IMX6QDL_CLK_IPU2_DI1>;
+ clock-names = "bus", "di0", "di1";
+ resets = <&src 4>;
+
+ ipu2_csi0: port@0 {
+ reg = <0>;
+ };
+
+ ipu2_csi1: port@1 {
+ reg = <1>;
+ };
+
+ ipu2_di0: port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ ipu2_di0_disp0: endpoint@0 {
+ };
+
+ ipu2_di0_hdmi: endpoint@1 {
+ remote-endpoint = <&hdmi_mux_2>;
+ };
+
+ ipu2_di0_mipi: endpoint@2 {
+ };
+
+ ipu2_di0_lvds0: endpoint@3 {
+ remote-endpoint = <&lvds0_mux_2>;
+ };
+
+ ipu2_di0_lvds1: endpoint@4 {
+ remote-endpoint = <&lvds1_mux_2>;
+ };
+ };
+
+ ipu2_di1: port@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ ipu2_di1_hdmi: endpoint@1 {
+ remote-endpoint = <&hdmi_mux_3>;
+ };
+
+ ipu2_di1_mipi: endpoint@2 {
+ };
+
+ ipu2_di1_lvds0: endpoint@3 {
+ remote-endpoint = <&lvds0_mux_3>;
+ };
+
+ ipu2_di1_lvds1: endpoint@4 {
+ remote-endpoint = <&lvds1_mux_3>;
+ };
+ };
+ };
+ };
+
+ display-subsystem {
+ compatible = "fsl,imx-display-subsystem";
+ ports = <&ipu1_di0>, <&ipu1_di1>, <&ipu2_di0>, <&ipu2_di1>;
+ };
+};
+
+&hdmi {
+ compatible = "fsl,imx6q-hdmi";
+
+ port@2 {
+ reg = <2>;
+
+ hdmi_mux_2: endpoint {
+ remote-endpoint = <&ipu2_di0_hdmi>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+
+ hdmi_mux_3: endpoint {
+ remote-endpoint = <&ipu2_di1_hdmi>;
+ };
+ };
+};
+
+&ldb {
+ clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_SEL>,
+ <&clks IMX6QDL_CLK_IPU1_DI0_SEL>, <&clks IMX6QDL_CLK_IPU1_DI1_SEL>,
+ <&clks IMX6QDL_CLK_IPU2_DI0_SEL>, <&clks IMX6QDL_CLK_IPU2_DI1_SEL>,
+ <&clks IMX6QDL_CLK_LDB_DI0>, <&clks IMX6QDL_CLK_LDB_DI1>;
+ clock-names = "di0_pll", "di1_pll",
+ "di0_sel", "di1_sel", "di2_sel", "di3_sel",
+ "di0", "di1";
+
+ lvds-channel@0 {
+ port@2 {
+ reg = <2>;
+
+ lvds0_mux_2: endpoint {
+ remote-endpoint = <&ipu2_di0_lvds0>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+
+ lvds0_mux_3: endpoint {
+ remote-endpoint = <&ipu2_di1_lvds0>;
+ };
+ };
+ };
+
+ lvds-channel@1 {
+ port@2 {
+ reg = <2>;
+
+ lvds1_mux_2: endpoint {
+ remote-endpoint = <&ipu2_di0_lvds1>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+
+ lvds1_mux_3: endpoint {
+ remote-endpoint = <&ipu2_di1_lvds1>;
+ };
+ };
+ };
+};
+
+&mipi_dsi {
+ ports {
+ port@2 {
+ reg = <2>;
+
+ mipi_mux_2: endpoint {
+ remote-endpoint = <&ipu2_di0_mipi>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+
+ mipi_mux_3: endpoint {
+ remote-endpoint = <&ipu2_di1_mipi>;
+ };
+ };
+ };
+};
+
+&vpu {
+ compatible = "fsl,imx6q-vpu", "cnm,coda960";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi b/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi
new file mode 100644
index 000000000..e6d9195a1
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi
@@ -0,0 +1,418 @@
+/*
+ * support fot the imx6 based aristainetos board
+ *
+ * Copyright (C) 2014 Heiko Schocher <hs@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 <dt-bindings/gpio/gpio.h>
+
+/ {
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_2p5v: regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "2P5V";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_usbh1_vbus: regulator@2 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 31 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_aristainetos_usbh1_vbus>;
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_usbotg_vbus: regulator@3 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 15 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_aristainetos_usbotg_vbus>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ status = "okay";
+};
+
+&can2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ tmp103: tmp103@71 {
+ compatible = "ti,tmp103";
+ reg = <0x71>;
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ rtc@68 {
+ compatible = "dallas,m41t00";
+ reg = <0x68>;
+ };
+};
+
+&ecspi4 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio3 20 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi4>;
+ status = "okay";
+
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q128a11";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rmii";
+ phy-reset-gpios = <&gpio3 29 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand>;
+ status = "okay";
+};
+
+&pcie {
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usbh1_vbus>;
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usbotg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ vmmc-supply = <&reg_3p3v>;
+ cd-gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ vmmc-supply = <&reg_3p3v>;
+ cd-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog &pinctrl_gpio>;
+
+ imx6qdl-aristainetos {
+ pinctrl_aristainetos_usbh1_vbus: aristainetos-usbh1-vbus {
+ fsl,pins = <MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x130b0>;
+ };
+
+ pinctrl_aristainetos_usbotg_vbus: aristainetos-usbotg-vbus {
+ fsl,pins = <MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x130b0>;
+ };
+
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x1b0b0
+ >;
+ };
+
+ pinctrl_backlight: backlightgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_9__PWM1_OUT 0x1b0b0
+ MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b0
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0
+ >;
+ };
+
+ pinctrl_ecspi2: ecspi2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_OE__ECSPI2_MISO 0x100b1
+ MX6QDL_PAD_EIM_CS0__ECSPI2_SCLK 0x100b1
+ MX6QDL_PAD_EIM_CS1__ECSPI2_MOSI 0x100b1
+ MX6QDL_PAD_EIM_D24__GPIO3_IO24 0x100b1
+ >;
+ };
+
+ pinctrl_ecspi4: ecspi4grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__ECSPI4_SCLK 0x100b1
+ MX6QDL_PAD_EIM_D22__ECSPI4_MISO 0x100b1
+ MX6QDL_PAD_EIM_D28__ECSPI4_MOSI 0x100b1
+ MX6QDL_PAD_EIM_D20__GPIO3_IO20 0x100b1
+ MX6QDL_PAD_SD4_DAT7__GPIO2_IO15 0x1b0b0 /* WP pin */
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0 0x1b0b0
+ MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1 0x1b0b0
+ MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
+ MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER 0x1b0b0
+ MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0 0x1b0b0
+ MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1 0x1b0b0
+ MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN 0x1b0b0
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x1b0b0
+ MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x1b0b0
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_DAT0__FLEXCAN2_TX 0x1b0b0
+ MX6QDL_PAD_SD3_DAT1__FLEXCAN2_RX 0x1b0b0
+ >;
+ };
+
+ pinctrl_gpio: gpiogrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT2__GPIO2_IO10 0x1b0b0
+ MX6QDL_PAD_SD4_DAT3__GPIO2_IO11 0x1b0b0
+ MX6QDL_PAD_SD4_DAT4__GPIO2_IO12 0x1b0b0
+ MX6QDL_PAD_SD4_DAT5__GPIO2_IO13 0x1b0b0
+ MX6QDL_PAD_GPIO_3__GPIO1_IO03 0x1b0b0
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1b0b0
+ MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x1b0b0
+ MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x1b0b0
+ MX6QDL_PAD_GPIO_7__GPIO1_IO07 0x1b0b0
+ MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x1b0b0
+ MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x1b0b0
+ >;
+ };
+
+ pinctrl_gpmi_nand: gpminandgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
+ MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
+ MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
+ MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
+ MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
+ MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
+ MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
+ MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
+ MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
+ MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
+ MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
+ MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
+ MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
+ MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
+ MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
+ MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
+ MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
+ >;
+ };
+
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x10
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
+ MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_ipu_disp: ipudisp1grp {
+ fsl,pins = <
+ MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
+ MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x10
+ MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x10
+ MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x10
+ MX6QDL_PAD_DI0_PIN4__GPIO4_IO20 0x20000
+ MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x10
+ MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x10
+ MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x10
+ MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x10
+ MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x10
+ MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x10
+ MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x10
+ MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x10
+ MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x10
+ MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x10
+ MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x10
+ MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x10
+ MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x10
+ MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x10
+ MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x10
+ MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x10
+ MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x10
+ MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x10
+ MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x10
+ MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x10
+ MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x10
+ MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x10
+ MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x10
+ MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x10
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5: uart5grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT14__UART5_TX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT15__UART5_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059
+ MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059
+ MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
+ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
+ MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
+ MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
+ MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x1b0b0
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
+ MX6QDL_PAD_KEY_COL1__GPIO4_IO08 0x1b0b0
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
new file mode 100644
index 000000000..d033bb182
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2014 Russell King
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "imx6qdl-microsom.dtsi"
+#include "imx6qdl-microsom-ar8035.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ ir_recv: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio3 9 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cubox_i_ir>;
+ };
+
+ pwmleds {
+ compatible = "pwm-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cubox_i_pwm1>;
+
+ front {
+ active-low;
+ label = "imx6:red:front";
+ max-brightness = <248>;
+ pwms = <&pwm1 0 50000>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+
+ reg_3p3v: 3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_usbh1_vbus: usb-h1-vbus {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio1 0 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cubox_i_usbh1_vbus>;
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_usbotg_vbus: usb-otg-vbus {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 22 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cubox_i_usbotg_vbus>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "Integrated SPDIF";
+ /* IMX6 doesn't implement this yet */
+ spdif-controller = <&spdif>;
+ spdif-out;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&pinctrl_gpio_key>;
+ pinctrl-names = "default";
+
+ button_0 {
+ label = "Button 0";
+ gpios = <&gpio3 8 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_0>;
+ };
+ };
+};
+
+&hdmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cubox_i_hdmi>;
+ ddc-i2c-bus = <&i2c2>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cubox_i_i2c2>;
+ status = "okay";
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cubox_i_i2c3>;
+
+ status = "okay";
+
+ rtc: pcf8523@68 {
+ compatible = "nxp,pcf8523";
+ reg = <0x68>;
+ };
+};
+
+&iomuxc {
+ cubox_i {
+ pinctrl_cubox_i_hdmi: cubox-i-hdmi {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
+ >;
+ };
+
+ pinctrl_cubox_i_i2c2: cubox-i-i2c2 {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_cubox_i_i2c3: cubox-i-i2c3 {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_cubox_i_ir: cubox-i-ir {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0x80000000
+ >;
+ };
+
+ pinctrl_cubox_i_pwm1: cubox-i-pwm1-front-led {
+ fsl,pins = <MX6QDL_PAD_DISP0_DAT8__PWM1_OUT 0x1b0b0>;
+ };
+
+ pinctrl_cubox_i_spdif: cubox-i-spdif {
+ fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x13091>;
+ };
+
+ pinctrl_cubox_i_usbh1: cubox-i-usbh1 {
+ fsl,pins = <MX6QDL_PAD_GPIO_3__USB_H1_OC 0x1b0b0>;
+ };
+
+ pinctrl_cubox_i_usbh1_vbus: cubox-i-usbh1-vbus {
+ fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x4001b0b0>;
+ };
+
+ pinctrl_cubox_i_usbotg: cubox-i-usbotg {
+ /*
+ * The Cubox-i pulls ID low, but as it's pointless
+ * leaving it as a pull-up, even if it is just 10uA.
+ */
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059
+ MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
+ >;
+ };
+
+ pinctrl_cubox_i_usbotg_vbus: cubox-i-usbotg-vbus {
+ fsl,pins = <MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x4001b0b0>;
+ };
+
+ pinctrl_cubox_i_usdhc2_aux: cubox-i-usdhc2-aux {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1f071
+ MX6QDL_PAD_KEY_ROW1__SD2_VSELECT 0x1b071
+ >;
+ };
+
+ pinctrl_cubox_i_usdhc2: cubox-i-usdhc2 {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x13059
+ >;
+ };
+
+ pinctrl_gpio_key: gpio-key {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_DA8__GPIO3_IO08 0x17059
+ >;
+ };
+ };
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cubox_i_spdif>;
+ status = "okay";
+};
+
+&usbh1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cubox_i_usbh1>;
+ vbus-supply = <&reg_usbh1_vbus>;
+ status = "okay";
+};
+
+&usbotg {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cubox_i_usbotg>;
+ vbus-supply = <&reg_usbotg_vbus>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cubox_i_usdhc2_aux &pinctrl_cubox_i_usdhc2>;
+ vmmc-supply = <&reg_3p3v>;
+ cd-gpios = <&gpio1 4 0>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
new file mode 100644
index 000000000..2c253d6d2
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
@@ -0,0 +1,199 @@
+/ {
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dummy_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "dummy-supply";
+ };
+
+ reg_usb_otg_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 0>;
+ enable-active-high;
+ };
+ };
+
+ chosen {
+ stdout-path = &uart1;
+ };
+};
+
+&ecspi3 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 24 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi3>;
+ status = "okay";
+
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "sst,sst25vf040b", "m25p80";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ status = "okay";
+ phy-mode = "rgmii";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6qdl-dfi-fs700-m60 {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000
+ MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x80000000 /* PMIC irq */
+ MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x80000000 /* MAX11801 irq */
+ MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x000030b0 /* Backlight enable */
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
+ MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x80000000 /* card detect */
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
+ MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
+ MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
+ MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
+ MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
+ MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
+ MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
+ MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
+ MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
+ MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_ecspi3: ecspi3grp {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
+ MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
+ MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
+ MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x80000000 /* SPI NOR chipselect */
+ >;
+ };
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&usbh1 {
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usdhc2 { /* module slot */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ cd-gpios = <&gpio2 2 0>;
+ status = "okay";
+};
+
+&usdhc3 { /* baseboard slot */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+};
+
+&usdhc4 { /* eMMC */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
new file mode 100644
index 000000000..f2867c4b3
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
@@ -0,0 +1,333 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+
+/ {
+ /* these are used by bootloader for disabling nodes */
+ aliases {
+ led0 = &led0;
+ led1 = &led1;
+ nand = &gpmi;
+ usb0 = &usbh1;
+ usb1 = &usbotg;
+ };
+
+ chosen {
+ bootargs = "console=ttymxc1,115200";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ led0: user1 {
+ label = "user1";
+ gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+
+ led1: user2 {
+ label = "user2";
+ gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */
+ default-state = "off";
+ };
+ };
+
+ memory {
+ reg = <0x10000000 0x20000000>;
+ };
+
+ pps {
+ compatible = "pps-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pps>;
+ gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_5p0v: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "5P0V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ reg_usb_otg_vbus: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c3>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ eeprom1: eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+
+ eeprom2: eeprom@51 {
+ compatible = "atmel,24c02";
+ reg = <0x51>;
+ pagesize = <16>;
+ };
+
+ eeprom3: eeprom@52 {
+ compatible = "atmel,24c02";
+ reg = <0x52>;
+ pagesize = <16>;
+ };
+
+ eeprom4: eeprom@53 {
+ compatible = "atmel,24c02";
+ reg = <0x53>;
+ pagesize = <16>;
+ };
+
+ gpio: pca9555@23 {
+ compatible = "nxp,pca9555";
+ reg = <0x23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ rtc: ds1672@68 {
+ compatible = "dallas,ds1672";
+ reg = <0x68>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpio = <&gpio1 0 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
+
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5>;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usbh1 {
+ status = "okay";
+};
+
+&iomuxc {
+ imx6qdl-gw51xx {
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x1b0b0 /* PHY Reset */
+ >;
+ };
+
+ pinctrl_gpio_leds: gpioledsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x1b0b0
+ MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x1b0b0
+ >;
+ };
+
+ pinctrl_gpmi_nand: gpminandgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
+ MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
+ MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
+ MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
+ MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
+ MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
+ MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
+ MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
+ MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
+ MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
+ MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
+ MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
+ MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
+ MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
+ MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
+ MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0
+ >;
+ };
+
+ pinctrl_pps: ppsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5: uart5grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0 /* OTG_PWR_EN */
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
new file mode 100644
index 000000000..b5756c21e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
@@ -0,0 +1,476 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+
+/ {
+ /* these are used by bootloader for disabling nodes */
+ aliases {
+ led0 = &led0;
+ led1 = &led1;
+ led2 = &led2;
+ nand = &gpmi;
+ ssi0 = &ssi1;
+ usb0 = &usbh1;
+ usb1 = &usbotg;
+ };
+
+ chosen {
+ bootargs = "console=ttymxc1,115200";
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm4 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ led0: user1 {
+ label = "user1";
+ gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+
+ led1: user2 {
+ label = "user2";
+ gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */
+ default-state = "off";
+ };
+
+ led2: user3 {
+ label = "user3";
+ gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */
+ default-state = "off";
+ };
+ };
+
+ memory {
+ reg = <0x10000000 0x20000000>;
+ };
+
+ pps {
+ compatible = "pps-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pps>;
+ gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_1p0v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "1P0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ /* remove this fixed regulator once ltc3676__sw2 driver available */
+ reg_1p8v: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "1P8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_5p0v: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "5P0V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ reg_usb_otg_vbus: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6q-ventana-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "sgtl5000-audio";
+ ssi-controller = <&ssi1>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <1>;
+ mux-ext-port = <4>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c3>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ eeprom1: eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+
+ eeprom2: eeprom@51 {
+ compatible = "atmel,24c02";
+ reg = <0x51>;
+ pagesize = <16>;
+ };
+
+ eeprom3: eeprom@52 {
+ compatible = "atmel,24c02";
+ reg = <0x52>;
+ pagesize = <16>;
+ };
+
+ eeprom4: eeprom@53 {
+ compatible = "atmel,24c02";
+ reg = <0x53>;
+ pagesize = <16>;
+ };
+
+ gpio: pca9555@23 {
+ compatible = "nxp,pca9555";
+ reg = <0x23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ rtc: ds1672@68 {
+ compatible = "dallas,ds1672";
+ reg = <0x68>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&clks 201>;
+ VDDA-supply = <&reg_1p8v>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+
+ touchscreen: egalax_ts@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ interrupt-parent = <&gpio7>;
+ interrupts = <12 2>;
+ wakeup-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ };
+ };
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpio = <&gpio1 29 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4>;
+ status = "okay";
+};
+
+&ssi1 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5>;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usbh1 {
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ cd-gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&iomuxc {
+ imx6qdl-gw52xx {
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
+ MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
+ MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
+ MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0 /* AUD4_MCK */
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x1b0b0 /* PHY Reset */
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x1b0b1
+ MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x1b0b1
+ MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x4001b0b0 /* CAN_STBY */
+ >;
+ };
+
+ pinctrl_gpio_leds: gpioledsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x1b0b0
+ MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x1b0b0
+ MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x1b0b0
+ >;
+ };
+
+ pinctrl_gpmi_nand: gpminandgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
+ MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
+ MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
+ MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
+ MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
+ MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
+ MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
+ MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
+ MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
+ MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
+ MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
+ MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
+ MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
+ MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
+ MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
+ MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x1b0b0 /* PCIE_RST# */
+ >;
+ };
+
+ pinctrl_pps: ppsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm4: pwm4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5: uart5grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0 /* OTG_PWR_EN */
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 /* CD */
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
new file mode 100644
index 000000000..86f03c1b1
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
@@ -0,0 +1,483 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+
+/ {
+ /* these are used by bootloader for disabling nodes */
+ aliases {
+ ethernet1 = &eth1;
+ led0 = &led0;
+ led1 = &led1;
+ led2 = &led2;
+ nand = &gpmi;
+ ssi0 = &ssi1;
+ usb0 = &usbh1;
+ usb1 = &usbotg;
+ };
+
+ chosen {
+ bootargs = "console=ttymxc1,115200";
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm4 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ led0: user1 {
+ label = "user1";
+ gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+
+ led1: user2 {
+ label = "user2";
+ gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */
+ default-state = "off";
+ };
+
+ led2: user3 {
+ label = "user3";
+ gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */
+ default-state = "off";
+ };
+ };
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ pps {
+ compatible = "pps-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pps>;
+ gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_1p0v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "1P0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ /* remove when pmic 1p8 regulator available */
+ reg_1p8v: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "1P8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_usb_h1_vbus: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ reg_usb_otg_vbus: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6q-ventana-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "sgtl5000-audio";
+ ssi-controller = <&ssi1>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <1>;
+ mux-ext-port = <4>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c3>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ eeprom1: eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+
+ eeprom2: eeprom@51 {
+ compatible = "atmel,24c02";
+ reg = <0x51>;
+ pagesize = <16>;
+ };
+
+ eeprom3: eeprom@52 {
+ compatible = "atmel,24c02";
+ reg = <0x52>;
+ pagesize = <16>;
+ };
+
+ eeprom4: eeprom@53 {
+ compatible = "atmel,24c02";
+ reg = <0x53>;
+ pagesize = <16>;
+ };
+
+ gpio: pca9555@23 {
+ compatible = "nxp,pca9555";
+ reg = <0x23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ rtc: ds1672@68 {
+ compatible = "dallas,ds1672";
+ reg = <0x68>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&clks 201>;
+ VDDA-supply = <&reg_1p8v>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+
+ touchscreen: egalax_ts@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <11 2>;
+ wakeup-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@1 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ };
+ };
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpio = <&gpio1 29 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ eth1: sky2@8 { /* MAC/PHY on bus 8 */
+ compatible = "marvell,sky2";
+ };
+};
+
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4>;
+ status = "okay";
+};
+
+&ssi1 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5>;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_h1_vbus>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ cd-gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&iomuxc {
+ imx6qdl-gw53xx {
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
+ MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
+ MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
+ MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0 /* AUD4_MCK */
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x1b0b1
+ MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x1b0b1
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x4001b0b0 /* CAN_STBY */
+ >;
+ };
+
+ pinctrl_gpio_leds: gpioledsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x1b0b0
+ MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x1b0b0
+ MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x1b0b0
+ >;
+ };
+
+ pinctrl_gpmi_nand: gpminandgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
+ MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
+ MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
+ MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
+ MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
+ MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
+ MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
+ MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
+ MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
+ MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
+ MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
+ MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
+ MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
+ MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
+ MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
+ MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x1b0b0 /* PCIE IRQ */
+ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x1b0b0 /* PCIE RST */
+ >;
+ };
+
+ pinctrl_pps: ppsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm4: pwm4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5: uart5grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0 /* PWR_EN */
+ MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x1b0b0 /* OC */
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 /* CD */
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
new file mode 100644
index 000000000..4a8d97f47
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
@@ -0,0 +1,574 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+
+/ {
+ /* these are used by bootloader for disabling nodes */
+ aliases {
+ ethernet1 = &eth1;
+ led0 = &led0;
+ led1 = &led1;
+ led2 = &led2;
+ nand = &gpmi;
+ ssi0 = &ssi1;
+ usb0 = &usbh1;
+ usb1 = &usbotg;
+ };
+
+ chosen {
+ bootargs = "console=ttymxc1,115200";
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm4 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ led0: user1 {
+ label = "user1";
+ gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+
+ led1: user2 {
+ label = "user2";
+ gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */
+ default-state = "off";
+ };
+
+ led2: user3 {
+ label = "user3";
+ gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */
+ default-state = "off";
+ };
+ };
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ pps {
+ compatible = "pps-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pps>;
+ gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_1p0v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "1P0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_usb_h1_vbus: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ reg_usb_otg_vbus: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6q-ventana-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "sgtl5000-audio";
+ ssi-controller = <&ssi1>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <1>;
+ mux-ext-port = <4>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>; /* AUD4<->sgtl5000 */
+ status = "okay";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c3>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ eeprom1: eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+
+ eeprom2: eeprom@51 {
+ compatible = "atmel,24c02";
+ reg = <0x51>;
+ pagesize = <16>;
+ };
+
+ eeprom3: eeprom@52 {
+ compatible = "atmel,24c02";
+ reg = <0x52>;
+ pagesize = <16>;
+ };
+
+ eeprom4: eeprom@53 {
+ compatible = "atmel,24c02";
+ reg = <0x53>;
+ pagesize = <16>;
+ };
+
+ gpio: pca9555@23 {
+ compatible = "nxp,pca9555";
+ reg = <0x23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ rtc: ds1672@68 {
+ compatible = "dallas,ds1672";
+ reg = <0x68>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3950000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&clks 201>;
+ VDDA-supply = <&sw4_reg>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+
+ touchscreen: egalax_ts@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ interrupt-parent = <&gpio7>;
+ interrupts = <12 2>;
+ wakeup-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@1 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ };
+ };
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpio = <&gpio1 29 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ eth1: sky2@8 { /* MAC/PHY on bus 8 */
+ compatible = "marvell,sky2";
+ };
+};
+
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4>;
+ status = "okay";
+};
+
+&ssi1 {
+ status = "okay";
+};
+
+&ssi2 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5>;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_h1_vbus>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ cd-gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&iomuxc {
+ imx6qdl-gw54xx {
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
+ MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
+ MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
+ MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0 /* AUD4_MCK */
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x1b0b1
+ MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x1b0b1
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x4001b0b0 /* CAN_STBY */
+ >;
+ };
+
+ pinctrl_gpio_leds: gpioledsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x1b0b0
+ MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x1b0b0
+ MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x1b0b0
+ >;
+ };
+
+ pinctrl_gpmi_nand: gpminandgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
+ MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
+ MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
+ MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
+ MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
+ MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
+ MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
+ MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
+ MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
+ MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
+ MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
+ MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
+ MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
+ MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
+ MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
+ MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x1b0b0 /* PCIE IRQ */
+ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x1b0b0 /* PCIE RST */
+ >;
+ };
+
+ pinctrl_pps: ppsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm4: pwm4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5: uart5grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0 /* PWR_EN */
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi
new file mode 100644
index 000000000..5c6587f6c
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2014 Gateworks Corporation
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+
+/ {
+ /* these are used by bootloader for disabling nodes */
+ aliases {
+ led0 = &led0;
+ led1 = &led1;
+ led2 = &led2;
+ nand = &gpmi;
+ usb0 = &usbh1;
+ usb1 = &usbotg;
+ };
+
+ chosen {
+ bootargs = "console=ttymxc1,115200";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ led0: user1 {
+ label = "user1";
+ gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+
+ led1: user2 {
+ label = "user2";
+ gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */
+ default-state = "off";
+ };
+
+ led2: user3 {
+ label = "user3";
+ gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */
+ default-state = "off";
+ };
+ };
+
+ memory {
+ reg = <0x10000000 0x20000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_1p0v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "1P0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_5p0v: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "5P0V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+ };
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c3>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ eeprom1: eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+
+ eeprom2: eeprom@51 {
+ compatible = "atmel,24c02";
+ reg = <0x51>;
+ pagesize = <16>;
+ };
+
+ eeprom3: eeprom@52 {
+ compatible = "atmel,24c02";
+ reg = <0x52>;
+ pagesize = <16>;
+ };
+
+ eeprom4: eeprom@53 {
+ compatible = "atmel,24c02";
+ reg = <0x53>;
+ pagesize = <16>;
+ };
+
+ gpio: pca9555@23 {
+ compatible = "nxp,pca9555";
+ reg = <0x23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ rtc: ds1672@68 {
+ compatible = "dallas,ds1672";
+ reg = <0x68>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpio = <&gpio1 29 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
+
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5>;
+ status = "okay"; };
+
+&usbh1 {
+ status = "okay";
+};
+
+&iomuxc {
+ imx6qdl-gw552x {
+ pinctrl_gpio_leds: gpioledsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x1b0b0
+ MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x1b0b0
+ MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x1b0b0
+ >;
+ };
+
+ pinctrl_gpmi_nand: gpminandgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
+ MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
+ MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
+ MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
+ MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
+ MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
+ MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
+ MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
+ MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
+ MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
+ MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
+ MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
+ MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
+ MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
+ MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
+ MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x1b0b0
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5: uart5grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi b/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi
new file mode 100644
index 000000000..151a3db2a
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2013,2014 Russell King
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "imx6qdl-microsom.dtsi"
+#include "imx6qdl-microsom-ar8035.dtsi"
+
+/ {
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ ir_recv: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio3 5 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard_gpio3_5>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+
+ reg_3p3v: 3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_usbh1_vbus: usb-h1-vbus {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio1 0 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard_usbh1_vbus>;
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_usbotg_vbus: usb-otg-vbus {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 22 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard_usbotg_vbus>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+ };
+
+ sound-sgtl5000 {
+ audio-codec = <&sgtl5000>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ compatible = "fsl,imx-audio-sgtl5000";
+ model = "On-board Codec";
+ mux-ext-port = <5>;
+ mux-int-port = <1>;
+ ssi-controller = <&ssi1>;
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "On-board SPDIF";
+ /* IMX6 doesn't implement this yet */
+ spdif-controller = <&spdif>;
+ spdif-out;
+ };
+};
+
+&audmux {
+ status = "okay";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard_flexcan1>;
+ status = "okay";
+};
+
+&hdmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard_hdmi>;
+ ddc-i2c-bus = <&i2c2>;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard_i2c1>;
+ status = "okay";
+
+ /* Pro baseboard model */
+ rtc: pcf8523@68 {
+ compatible = "nxp,pcf8523";
+ reg = <0x68>;
+ };
+
+ /* Pro baseboard model */
+ sgtl5000: sgtl5000@0a {
+ clocks = <&clks IMX6QDL_CLK_CKO>;
+ compatible = "fsl,sgtl5000";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard_sgtl5000>;
+ reg = <0x0a>;
+ VDDA-supply = <&reg_3p3v>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard_i2c2>;
+ status = "okay";
+};
+
+&iomuxc {
+ hummingboard {
+ pinctrl_hummingboard_flexcan1: hummingboard-flexcan1 {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CLK__FLEXCAN1_RX 0x80000000
+ MX6QDL_PAD_SD3_CMD__FLEXCAN1_TX 0x80000000
+ >;
+ };
+
+ pinctrl_hummingboard_gpio3_5: hummingboard-gpio3_5 {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_DA5__GPIO3_IO05 0x1b0b1
+ >;
+ };
+
+ pinctrl_hummingboard_hdmi: hummingboard-hdmi {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
+ >;
+ };
+
+ pinctrl_hummingboard_i2c1: hummingboard-i2c1 {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_hummingboard_i2c2: hummingboard-i2c2 {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_hummingboard_pwm1: pwm1grp {
+ fsl,pins = <MX6QDL_PAD_DISP0_DAT8__PWM1_OUT 0x1b0b1>;
+ };
+
+ pinctrl_hummingboard_sgtl5000: hummingboard-sgtl5000 {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x130b0
+ MX6QDL_PAD_KEY_COL0__AUD5_TXC 0x130b0
+ MX6QDL_PAD_KEY_ROW0__AUD5_TXD 0x110b0
+ MX6QDL_PAD_KEY_COL1__AUD5_TXFS 0x130b0
+ MX6QDL_PAD_GPIO_5__CCM_CLKO1 0x130b0
+ >;
+ };
+
+ pinctrl_hummingboard_spdif: hummingboard-spdif {
+ fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x13091>;
+ };
+
+ pinctrl_hummingboard_usbh1_vbus: hummingboard-usbh1-vbus {
+ fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0>;
+ };
+
+ pinctrl_hummingboard_usbotg_id: hummingboard-usbotg-id {
+ /*
+ * Similar to pinctrl_usbotg_2, but we want it
+ * pulled down for a fixed host connection.
+ */
+ fsl,pins = <MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059>;
+ };
+
+ pinctrl_hummingboard_usbotg_vbus: hummingboard-usbotg-vbus {
+ fsl,pins = <MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0>;
+ };
+
+ pinctrl_hummingboard_usdhc2_aux: hummingboard-usdhc2-aux {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1f071
+ >;
+ };
+
+ pinctrl_hummingboard_usdhc2: hummingboard-usdhc2 {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x13059
+ >;
+ };
+ };
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard_pwm1>;
+ status = "okay";
+};
+
+&pwm2 {
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard_spdif>;
+ status = "okay";
+};
+
+&ssi1 {
+ fsl,mode = "i2s-slave";
+ status = "okay";
+};
+
+&usbh1 {
+ disable-over-current;
+ vbus-supply = <&reg_usbh1_vbus>;
+ status = "okay";
+};
+
+&usbotg {
+ disable-over-current;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard_usbotg_id>;
+ vbus-supply = <&reg_usbotg_vbus>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &pinctrl_hummingboard_usdhc2_aux
+ &pinctrl_hummingboard_usdhc2
+ >;
+ vmmc-supply = <&reg_3p3v>;
+ cd-gpios = <&gpio1 4 0>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi b/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi
new file mode 100644
index 000000000..4a1820309
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2013,2014 Russell King
+ *
+ * This describes the hookup for an AR8035 to the iMX6 on the SolidRun
+ * MicroSOM.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_microsom_enet_ar8035>;
+ phy-mode = "rgmii";
+ phy-reset-duration = <2>;
+ phy-reset-gpios = <&gpio4 15 0>;
+ status = "okay";
+};
+
+&iomuxc {
+ enet {
+ pinctrl_microsom_enet_ar8035: microsom-enet-ar8035 {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b8b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ /* AR8035 reset */
+ MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x130b0
+ /* AR8035 interrupt */
+ MX6QDL_PAD_DI0_PIN2__GPIO4_IO18 0x80000000
+ /* GPIO16 -> AR8035 25MHz */
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0xc0000000
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x80000000
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b030
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b030
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b030
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b030
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b030
+ /* AR8035 CLK_25M --> ENET_REF_CLK (V22) */
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x0a0b1
+ /* AR8035 pin strapping: IO voltage: pull up */
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b030
+ /* AR8035 pin strapping: PHYADDR#0: pull down */
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x13030
+ /* AR8035 pin strapping: PHYADDR#1: pull down */
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x13030
+ /* AR8035 pin strapping: MODE#1: pull up */
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b030
+ /* AR8035 pin strapping: MODE#3: pull up */
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b030
+ /* AR8035 pin strapping: MODE#0: pull down */
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x13030
+
+ /*
+ * As the RMII pins are also connected to RGMII
+ * so that an AR8030 can be placed, set these
+ * to high-z with the same pulls as above.
+ * Use the GPIO settings to avoid changing the
+ * input select registers.
+ */
+ MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x03000
+ MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x03000
+ MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x03000
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6qdl-microsom.dtsi b/arch/arm/boot/dts/imx6qdl-microsom.dtsi
new file mode 100644
index 000000000..349f82be8
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-microsom.dtsi
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013,2014 Russell King
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License.
+ *
+ * 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.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+&iomuxc {
+ microsom {
+ pinctrl_microsom_uart1: microsom-uart1 {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_microsom_uart1>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
new file mode 100644
index 000000000..08218120e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
@@ -0,0 +1,463 @@
+/*
+ * Copyright 2013 Boundary Devices, Inc.
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_2p5v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "2P5V";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_usb_otg_vbus: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 0>;
+ enable-active-high;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ power {
+ label = "Power Button";
+ gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ gpio-key,wakeup;
+ };
+
+ menu {
+ label = "Menu";
+ gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_MENU>;
+ };
+
+ home {
+ label = "Home";
+ gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOME>;
+ };
+
+ back {
+ label = "Back";
+ gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_BACK>;
+ };
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio7 13 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6q-nitrogen6x-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx6q-nitrogen6x-sgtl5000";
+ ssi-controller = <&ssi1>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <1>;
+ mux-ext-port = <3>;
+ };
+
+ backlight_lcd {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ power-supply = <&reg_3p3v>;
+ status = "okay";
+ };
+
+ backlight_lvds {
+ compatible = "pwm-backlight";
+ pwms = <&pwm4 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ power-supply = <&reg_3p3v>;
+ status = "okay";
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&ecspi1 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio3 19 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ status = "okay";
+
+ flash: m25p80@0 {
+ compatible = "sst,sst25vf016b";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio1 27 0>;
+ txen-skew-ps = <0>;
+ txc-skew-ps = <3000>;
+ rxdv-skew-ps = <0>;
+ rxc-skew-ps = <3000>;
+ rxd0-skew-ps = <0>;
+ rxd1-skew-ps = <0>;
+ rxd2-skew-ps = <0>;
+ rxd3-skew-ps = <0>;
+ txd0-skew-ps = <0>;
+ txd1-skew-ps = <0>;
+ txd2-skew-ps = <0>;
+ txd3-skew-ps = <0>;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c2>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&clks 201>;
+ VDDA-supply = <&reg_2p5v>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+
+ rtc: rtc@6f {
+ compatible = "isil,isl1208";
+ reg = <0x6f>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6q-nitrogen6x {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ /* SGTL5000 sys_mclk */
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x030b0
+ >;
+ };
+
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
+ MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
+ MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0
+ MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
+ MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
+ MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
+ MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x000b1 /* CS */
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x100b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x100b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x100b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x100b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x100b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x100b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x100b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x100b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x100b0
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ /* Phy reset */
+ MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x000b0
+ MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
+ >;
+ };
+
+ pinctrl_gpio_keys: gpio_keysgrp {
+ fsl,pins = <
+ /* Power Button */
+ MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
+ /* Menu Button */
+ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0
+ /* Home Button */
+ MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x1b0b0
+ /* Back Button */
+ MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
+ /* Volume Up Button */
+ MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x1b0b0
+ /* Volume Down Button */
+ MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x1b0b0
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm4: pwm4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
+ /* power enable, high active */
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x000b0
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 /* CD */
+ >;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
+ MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
+ MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
+ MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
+ MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
+ MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
+ MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x1b0b0 /* CD */
+ >;
+ };
+ };
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ };
+ };
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>;
+ status = "okay";
+};
+
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4>;
+ status = "okay";
+};
+
+&ssi1 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&usbh1 {
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ cd-gpios = <&gpio7 0 0>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ cd-gpios = <&gpio2 6 0>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi
new file mode 100644
index 000000000..585b4f698
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
+ *
+ * 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 <dt-bindings/sound/fsl-imx-audmux.h>
+
+/ {
+ chosen {
+ linux,stdout-path = &uart4;
+ };
+
+ regulators {
+ sound_1v8: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "i2s-audio-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ sound_3v3: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "i2s-audio-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+
+ tlv320_mclk: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <19200000>;
+ clock-output-names = "tlv320-mclk";
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "OnboardTLV320AIC3007";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,bitclock-master = <&dailink_master>;
+ simple-audio-card,frame-master = <&dailink_master>;
+ simple-audio-card,widgets =
+ "Microphone", "Mic Jack",
+ "Line", "Line In",
+ "Line", "Line Out",
+ "Speaker", "Speaker",
+ "Headphone", "Headphone Jack";
+ simple-audio-card,routing =
+ "Line Out", "LLOUT",
+ "Line Out", "RLOUT",
+ "Speaker", "SPOP",
+ "Speaker", "SPOM",
+ "Headphone Jack", "HPLOUT",
+ "Headphone Jack", "HPROUT",
+ "MIC3L", "Mic Jack",
+ "MIC3R", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "LINE1L", "Line In",
+ "LINE1R", "Line In";
+
+ simple-audio-card,cpu {
+ sound-dai = <&ssi2>;
+ };
+
+ dailink_master: simple-audio-card,codec {
+ sound-dai = <&codec>;
+ clocks = <&tlv320_mclk>;
+ };
+ };
+
+};
+
+&audmux {
+ status = "okay";
+
+ ssi2 {
+ fsl,audmux-port = <1>;
+ fsl,port-config = <
+ (IMX_AUDMUX_V2_PTCR_TFSDIR |
+ IMX_AUDMUX_V2_PTCR_TFSEL(4) |
+ IMX_AUDMUX_V2_PTCR_TCLKDIR |
+ IMX_AUDMUX_V2_PTCR_TCSEL(4))
+ IMX_AUDMUX_V2_PDCR_RXDSEL(4)
+ >;
+ };
+
+ pins5 {
+ fsl,audmux-port = <4>;
+ fsl,port-config = <
+ 0x00000000
+ IMX_AUDMUX_V2_PDCR_RXDSEL(1)
+ >;
+ };
+};
+
+&can1 {
+ status = "okay";
+};
+
+&fec {
+ status = "okay";
+};
+
+&hdmi {
+ status = "okay";
+};
+
+&i2c2 {
+ status = "okay";
+
+ codec: tlv320@18 {
+ compatible = "ti,tlv320aic3007";
+ #sound-dai-cells = <0>;
+ reg = <0x18>;
+ ai3x-micbias-vg = <2>;
+
+ AVDD-supply = <&sound_3v3>;
+ IOVDD-supply = <&sound_3v3>;
+ DRVDD-supply = <&sound_3v3>;
+ DVDD-supply = <&sound_1v8>;
+ };
+
+ stmpe@41 {
+ compatible = "st,stmpe811";
+ reg = <0x41>;
+ };
+
+ rtc@51 {
+ compatible = "nxp,rtc8564";
+ reg = <0x51>;
+ };
+
+ adc@64 {
+ compatible = "maxim,max1037";
+ reg = <0x64>;
+ };
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+&pcie {
+ status = "okay";
+};
+
+&ssi2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&uart4 {
+ status = "okay";
+};
+
+&usbh1 {
+ status = "okay";
+};
+
+&usbotg {
+ status = "okay";
+};
+
+&usdhc2 {
+ status = "okay";
+};
+
+&usdhc3 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
new file mode 100644
index 000000000..1ce6133b6
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
@@ -0,0 +1,424 @@
+/*
+ * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Phytec phyFLEX-i.MX6 Ouad";
+ compatible = "phytec,imx6q-pfla02", "fsl,imx6q";
+
+ memory {
+ reg = <0x10000000 0x80000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb_otg_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 15 0>;
+ enable-active-high;
+ };
+
+ reg_usb_h1_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 0 0>;
+ enable-active-high;
+ };
+ };
+
+ gpio_leds: leds {
+ compatible = "gpio-leds";
+
+ green {
+ label = "phyflex:green";
+ gpios = <&gpio1 30 0>;
+ };
+
+ red {
+ label = "phyflex:red";
+ gpios = <&gpio2 31 0>;
+ };
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "disabled";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ status = "disabled";
+};
+
+&ecspi3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi3>;
+ status = "okay";
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 24 0>;
+
+ flash@0 {
+ compatible = "m25p80";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
+ phy-supply = <&vdd_eth_io_reg>;
+ status = "disabled";
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand>;
+ nand-on-flash-bbt;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "atmel,24c32";
+ reg = <0x50>;
+ };
+
+ pmic@58 {
+ compatible = "dlg,da9063";
+ reg = <0x58>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <9 0x8>; /* active-low GPIO2_9 */
+
+ regulators {
+ vddcore_reg: bcore1 {
+ regulator-min-microvolt = <730000>;
+ regulator-max-microvolt = <1380000>;
+ regulator-always-on;
+ };
+
+ vddsoc_reg: bcore2 {
+ regulator-min-microvolt = <730000>;
+ regulator-max-microvolt = <1380000>;
+ regulator-always-on;
+ };
+
+ vdd_ddr3_reg: bpro {
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ };
+
+ vdd_3v3_reg: bperi {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_buckmem_reg: bmem {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_eth_reg: bio {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ vdd_eth_io_reg: ldo4 {
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ vdd_mx6_snvs_reg: ldo5 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ vdd_3v3_pmic_io_reg: ldo6 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_sd0_reg: ldo9 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vdd_sd1_reg: ldo10 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vdd_mx6_high_reg: ldo11 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ clock-frequency = <100000>;
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ clock-frequency = <100000>;
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6q-phytec-pfla02 {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
+ MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x80000000 /* SPI NOR chipselect */
+ MX6QDL_PAD_SD4_DAT1__GPIO2_IO09 0x80000000 /* PMIC interrupt */
+ MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* Green LED */
+ MX6QDL_PAD_EIM_EB3__GPIO2_IO31 0x80000000 /* Red LED */
+ >;
+ };
+
+ pinctrl_ecspi3: ecspi3grp {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
+ MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
+ MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x1b0b0
+ MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x1b0b0
+ >;
+ };
+
+ pinctrl_gpmi_nand: gpminandgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
+ MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
+ MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
+ MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
+ MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
+ MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
+ MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
+ MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
+ MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
+ MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
+ MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
+ MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
+ MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
+ MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
+ MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
+ MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
+ MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <MX6QDL_PAD_DI0_PIN15__GPIO4_IO17 0x80000000>;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D30__UART3_RTS_B 0x1b0b1
+ MX6QDL_PAD_EIM_D31__UART3_CTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbh1: usbh1grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_0__USB_H1_PWR 0x80000000
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
+ MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3_cdwp: usdhc3cdwp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000
+ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
+ >;
+ };
+
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT16__AUD5_TXC 0x130b0
+ MX6QDL_PAD_DISP0_DAT17__AUD5_TXD 0x110b0
+ MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS 0x130b0
+ MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x130b0
+ >;
+ };
+ };
+};
+
+&pcie {
+ pinctrl-name = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpio = <&gpio4 17 0>;
+ status = "disabled";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "disabled";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ status = "disabled";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_h1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1>;
+ status = "disabled";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ status = "disabled";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ cd-gpios = <&gpio1 4 0>;
+ wp-gpios = <&gpio1 2 0>;
+ status = "disabled";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3
+ &pinctrl_usdhc3_cdwp>;
+ cd-gpios = <&gpio1 27 0>;
+ wp-gpios = <&gpio1 29 0>;
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-rex.dtsi b/arch/arm/boot/dts/imx6qdl-rex.dtsi
new file mode 100644
index 000000000..488a64079
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-rex.dtsi
@@ -0,0 +1,356 @@
+/*
+ * Copyright 2014 FEDEVEL, Inc.
+ *
+ * Author: Robert Nelson <robertcnelson@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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_usbh1_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1>;
+ regulator-name = "usbh1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 31 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb_otg_vbus: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_led>;
+
+ led0: usr {
+ label = "usr";
+ gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6-rex-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx6-rex-sgtl5000";
+ ssi-controller = <&ssi1>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <1>;
+ mux-ext-port = <3>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&ecspi2 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio5 12 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi2>;
+ status = "okay";
+};
+
+&ecspi3 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 26 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi3>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c2>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&clks 201>;
+ VDDA-supply = <&reg_3p3v>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ eeprom@57 {
+ compatible = "at,24c02";
+ reg = <0x57>;
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6qdl-rex {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ /* SGTL5000 sys_mclk */
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x030b0
+ >;
+ };
+
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
+ MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
+ MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0
+ MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
+ >;
+ };
+
+ pinctrl_ecspi2: ecspi2grp {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
+ MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
+ MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
+ /* CS */
+ MX6QDL_PAD_DISP0_DAT5__GPIO4_IO26 0x000b1
+ >;
+ };
+
+ pinctrl_ecspi3: ecspi3grp {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT17__ECSPI2_MISO 0x100b1
+ MX6QDL_PAD_DISP0_DAT16__ECSPI2_MOSI 0x100b1
+ MX6QDL_PAD_DISP0_DAT19__ECSPI2_SCLK 0x100b1
+ /* CS */
+ MX6QDL_PAD_DISP0_DAT18__GPIO5_IO12 0x000b1
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ /* Phy reset */
+ MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x000b0
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
+ MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_led: ledgrp {
+ fsl,pins = <
+ /* user led */
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbh1: usbh1grp {
+ fsl,pins = <
+ /* power enable, high active */
+ MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x10b0
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ MX6QDL_PAD_EIM_D21__USB_OTG_OC 0x1b0b0
+ /* power enable, high active */
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x10b0
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
+ /* CD */
+ MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
+ /* WP */
+ MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1f0b0
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ /* CD */
+ MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x1b0b0
+ /* WP */
+ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1f0b0
+ >;
+ };
+ };
+};
+
+&ssi1 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usbh1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1>;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ bus-width = <4>;
+ cd-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ bus-width = <4>;
+ cd-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
new file mode 100644
index 000000000..3b24b1265
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
@@ -0,0 +1,492 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+
+/ {
+ memory {
+ reg = <0x10000000 0x80000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ user {
+ label = "debug";
+ gpios = <&gpio5 15 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif",
+ "fsl,imx-sabreauto-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif>;
+ spdif-in;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm3 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ status = "okay";
+ };
+};
+
+&ecspi1 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio3 19 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
+ status = "disabled"; /* pin conflict with WEIM NOR */
+
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p32";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ status = "okay";
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ max7310_a: gpio@30 {
+ compatible = "maxim,max7310";
+ reg = <0x30>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ max7310_b: gpio@32 {
+ compatible = "maxim,max7310";
+ reg = <0x32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ max7310_c: gpio@34 {
+ compatible = "maxim,max7310";
+ reg = <0x34>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6qdl-sabreauto {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x80000000
+ MX6QDL_PAD_SD2_DAT2__GPIO1_IO13 0x80000000
+ MX6QDL_PAD_GPIO_18__SD3_VSELECT 0x17059
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
+ MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
+ MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
+ >;
+ };
+
+ pinctrl_ecspi1_cs: ecspi1cs {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x80000000
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL1__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_KEY_COL2__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
+ >;
+ };
+
+ pinctrl_gpio_leds: gpioledsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15 0x80000000
+ >;
+ };
+
+ pinctrl_gpmi_nand: gpminandgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
+ MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
+ MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
+ MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
+ MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
+ MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
+ MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
+ MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
+ MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
+ MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
+ MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
+ MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
+ MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
+ MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
+ MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
+ MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
+ MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pwm3: pwm1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_spdif: spdifgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__SPDIF_IN 0x1b0b0
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
+ MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
+ MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
+ MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170b9
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100b9
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
+ MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170b9
+ MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170b9
+ MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170b9
+ MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
+ MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9
+ MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9
+ MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9
+ MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9
+ >;
+ };
+
+ pinctrl_weim_cs0: weimcs0grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_CS0__EIM_CS0_B 0xb0b1
+ >;
+ };
+
+ pinctrl_weim_nor: weimnorgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_OE__EIM_OE_B 0xb0b1
+ MX6QDL_PAD_EIM_RW__EIM_RW 0xb0b1
+ MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B 0xb060
+ MX6QDL_PAD_EIM_D16__EIM_DATA16 0x1b0b0
+ MX6QDL_PAD_EIM_D17__EIM_DATA17 0x1b0b0
+ MX6QDL_PAD_EIM_D18__EIM_DATA18 0x1b0b0
+ MX6QDL_PAD_EIM_D19__EIM_DATA19 0x1b0b0
+ MX6QDL_PAD_EIM_D20__EIM_DATA20 0x1b0b0
+ MX6QDL_PAD_EIM_D21__EIM_DATA21 0x1b0b0
+ MX6QDL_PAD_EIM_D22__EIM_DATA22 0x1b0b0
+ MX6QDL_PAD_EIM_D23__EIM_DATA23 0x1b0b0
+ MX6QDL_PAD_EIM_D24__EIM_DATA24 0x1b0b0
+ MX6QDL_PAD_EIM_D25__EIM_DATA25 0x1b0b0
+ MX6QDL_PAD_EIM_D26__EIM_DATA26 0x1b0b0
+ MX6QDL_PAD_EIM_D27__EIM_DATA27 0x1b0b0
+ MX6QDL_PAD_EIM_D28__EIM_DATA28 0x1b0b0
+ MX6QDL_PAD_EIM_D29__EIM_DATA29 0x1b0b0
+ MX6QDL_PAD_EIM_D30__EIM_DATA30 0x1b0b0
+ MX6QDL_PAD_EIM_D31__EIM_DATA31 0x1b0b0
+ MX6QDL_PAD_EIM_A23__EIM_ADDR23 0xb0b1
+ MX6QDL_PAD_EIM_A22__EIM_ADDR22 0xb0b1
+ MX6QDL_PAD_EIM_A21__EIM_ADDR21 0xb0b1
+ MX6QDL_PAD_EIM_A20__EIM_ADDR20 0xb0b1
+ MX6QDL_PAD_EIM_A19__EIM_ADDR19 0xb0b1
+ MX6QDL_PAD_EIM_A18__EIM_ADDR18 0xb0b1
+ MX6QDL_PAD_EIM_A17__EIM_ADDR17 0xb0b1
+ MX6QDL_PAD_EIM_A16__EIM_ADDR16 0xb0b1
+ MX6QDL_PAD_EIM_DA15__EIM_AD15 0xb0b1
+ MX6QDL_PAD_EIM_DA14__EIM_AD14 0xb0b1
+ MX6QDL_PAD_EIM_DA13__EIM_AD13 0xb0b1
+ MX6QDL_PAD_EIM_DA12__EIM_AD12 0xb0b1
+ MX6QDL_PAD_EIM_DA11__EIM_AD11 0xb0b1
+ MX6QDL_PAD_EIM_DA10__EIM_AD10 0xb0b1
+ MX6QDL_PAD_EIM_DA9__EIM_AD09 0xb0b1
+ MX6QDL_PAD_EIM_DA8__EIM_AD08 0xb0b1
+ MX6QDL_PAD_EIM_DA7__EIM_AD07 0xb0b1
+ MX6QDL_PAD_EIM_DA6__EIM_AD06 0xb0b1
+ MX6QDL_PAD_EIM_DA5__EIM_AD05 0xb0b1
+ MX6QDL_PAD_EIM_DA4__EIM_AD04 0xb0b1
+ MX6QDL_PAD_EIM_DA3__EIM_AD03 0xb0b1
+ MX6QDL_PAD_EIM_DA2__EIM_AD02 0xb0b1
+ MX6QDL_PAD_EIM_DA1__EIM_AD01 0xb0b1
+ MX6QDL_PAD_EIM_DA0__EIM_AD00 0xb0b1
+ >;
+ };
+ };
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ };
+ };
+ };
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>;
+ status = "okay";
+};
+
+&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ cd-gpios = <&gpio6 15 0>;
+ wp-gpios = <&gpio1 13 0>;
+ status = "okay";
+};
+
+&weim {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_weim_nor &pinctrl_weim_cs0>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0x08000000 0x08000000>;
+ status = "disabled"; /* pin conflict with SPI NOR */
+
+ nor@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x02000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ bank-width = <2>;
+ fsl,weim-cs-timing = <0x00620081 0x00000001 0x1c022000
+ 0x0000c000 0x1404a38e 0x00000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
new file mode 100644
index 000000000..0b28a9d52
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
@@ -0,0 +1,459 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_2p5v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "2P5V";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_usb_otg_vbus: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 0>;
+ enable-active-high;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ power {
+ label = "Power Button";
+ gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ gpio-key,wakeup;
+ };
+
+ menu {
+ label = "Menu";
+ gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_MENU>;
+ };
+
+ home {
+ label = "Home";
+ gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOME>;
+ };
+
+ back {
+ label = "Back";
+ gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_BACK>;
+ };
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio7 13 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6q-sabrelite-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx6q-sabrelite-sgtl5000";
+ ssi-controller = <&ssi1>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <1>;
+ mux-ext-port = <4>;
+ };
+
+ backlight_lcd {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ power-supply = <&reg_3p3v>;
+ status = "okay";
+ };
+
+ backlight_lvds {
+ compatible = "pwm-backlight";
+ pwms = <&pwm4 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ power-supply = <&reg_3p3v>;
+ status = "okay";
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&ecspi1 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio3 19 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ status = "okay";
+
+ flash: m25p80@0 {
+ compatible = "sst,sst25vf016b";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
+ txen-skew-ps = <0>;
+ txc-skew-ps = <3000>;
+ rxdv-skew-ps = <0>;
+ rxc-skew-ps = <3000>;
+ rxd0-skew-ps = <0>;
+ rxd1-skew-ps = <0>;
+ rxd2-skew-ps = <0>;
+ rxd3-skew-ps = <0>;
+ txd0-skew-ps = <0>;
+ txd1-skew-ps = <0>;
+ txd2-skew-ps = <0>;
+ txd3-skew-ps = <0>;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c2>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&clks 201>;
+ VDDA-supply = <&reg_2p5v>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6q-sabrelite {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ /* SGTL5000 sys_mclk */
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x030b0
+ >;
+ };
+
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
+ MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
+ MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
+ MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
+ MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
+ MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
+ MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x000b1 /* CS */
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x100b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x100b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x100b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x100b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x100b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x100b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x100b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x100b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x100b0
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ /* Phy reset */
+ MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x000b0
+ MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
+ >;
+ };
+
+ pinctrl_gpio_keys: gpio_keysgrp {
+ fsl,pins = <
+ /* Power Button */
+ MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
+ /* Menu Button */
+ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0
+ /* Home Button */
+ MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x1b0b0
+ /* Back Button */
+ MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
+ /* Volume Up Button */
+ MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x1b0b0
+ /* Volume Down Button */
+ MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x1b0b0
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm4: pwm4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
+ /* power enable, high active */
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x000b0
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 /* CD */
+ MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x1f0b0 /* WP */
+ >;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
+ MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
+ MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
+ MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
+ MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
+ MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
+ MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x1b0b0 /* CD */
+ >;
+ };
+ };
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ };
+ };
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>;
+ status = "okay";
+};
+
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4>;
+ status = "okay";
+};
+
+&ssi1 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&usbh1 {
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ cd-gpios = <&gpio7 0 0>;
+ wp-gpios = <&gpio7 1 0>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ cd-gpios = <&gpio2 6 0>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
new file mode 100644
index 000000000..a626e6dd8
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
@@ -0,0 +1,586 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb_otg_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 0>;
+ enable-active-high;
+ vin-supply = <&swbst_reg>;
+ };
+
+ reg_usb_h1_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 29 0>;
+ enable-active-high;
+ vin-supply = <&swbst_reg>;
+ };
+
+ reg_audio: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "wm8962-supply";
+ gpio = <&gpio4 10 0>;
+ enable-active-high;
+ };
+
+ reg_pcie: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie_reg>;
+ regulator-name = "MPCIE_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 19 0>;
+ regulator-always-on;
+ enable-active-high;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ power {
+ label = "Power Button";
+ gpios = <&gpio3 29 GPIO_ACTIVE_LOW>;
+ gpio-key,wakeup;
+ linux,code = <KEY_POWER>;
+ };
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+ gpio-key,wakeup;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+ gpio-key,wakeup;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6q-sabresd-wm8962",
+ "fsl,imx-audio-wm8962";
+ model = "wm8962-audio";
+ ssi-controller = <&ssi2>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "Ext Spk", "SPKOUTL",
+ "Ext Spk", "SPKOUTR",
+ "AMIC", "MICBIAS",
+ "IN3R", "AMIC";
+ mux-int-port = <2>;
+ mux-ext-port = <3>;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ status = "okay";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ red {
+ gpios = <&gpio1 2 0>;
+ default-state = "on";
+ };
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&ecspi1 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 9 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ status = "okay";
+
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p32";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio1 25 0>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c2>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ codec: wm8962@1a {
+ compatible = "wlf,wm8962";
+ reg = <0x1a>;
+ clocks = <&clks IMX6QDL_CLK_CKO>;
+ DCVDD-supply = <&reg_audio>;
+ DBVDD-supply = <&reg_audio>;
+ AVDD-supply = <&reg_audio>;
+ CPVDD-supply = <&reg_audio>;
+ MICVDD-supply = <&reg_audio>;
+ PLLVDD-supply = <&reg_audio>;
+ SPKVDD1-supply = <&reg_audio>;
+ SPKVDD2-supply = <&reg_audio>;
+ gpio-cfg = <
+ 0x0000 /* 0:Default */
+ 0x0000 /* 1:Default */
+ 0x0013 /* 2:FN_DMICCLK */
+ 0x0000 /* 3:Default */
+ 0x8014 /* 4:FN_DMICCDAT */
+ 0x0000 /* 5:Default */
+ >;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ egalax_ts@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <7 2>;
+ wakeup-gpios = <&gpio6 7 0>;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6qdl-sabresd {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x1b0b0
+ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0
+ MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
+ MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0
+ MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x1b0b0
+ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x1b0b0
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0
+ MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x1b0b0
+ >;
+ };
+
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
+ MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
+ MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0
+ MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL1__ECSPI1_MISO 0x100b1
+ MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI 0x100b1
+ MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK 0x100b1
+ MX6QDL_PAD_KEY_ROW1__GPIO4_IO09 0x1b0b0
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ >;
+ };
+
+ pinctrl_gpio_keys: gpio_keysgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b0
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1b0b0
+ MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x1b0b0
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
+ MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0
+ >;
+ };
+
+ pinctrl_pcie_reg: pciereggrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x1b0b0
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
+ MX6QDL_PAD_NANDF_D4__SD2_DATA4 0x17059
+ MX6QDL_PAD_NANDF_D5__SD2_DATA5 0x17059
+ MX6QDL_PAD_NANDF_D6__SD2_DATA6 0x17059
+ MX6QDL_PAD_NANDF_D7__SD2_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
+ MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
+ MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
+ MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
+ MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
+ MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
+ MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
+ MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
+ MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
+ MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
+ MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
+ MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
+ MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
+ >;
+ };
+ };
+
+ gpio_leds {
+ pinctrl_gpio_leds: gpioledsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0
+ >;
+ };
+ };
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@1 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: hsd100pxn1 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <220>;
+ hfront-porch = <40>;
+ vback-porch = <21>;
+ vfront-porch = <7>;
+ hsync-len = <60>;
+ vsync-len = <10>;
+ };
+ };
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpio = <&gpio7 12 0>;
+ status = "okay";
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&snvs_poweroff {
+ status = "okay";
+};
+
+&ssi2 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_h1_vbus>;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ bus-width = <8>;
+ cd-gpios = <&gpio2 2 0>;
+ wp-gpios = <&gpio2 3 0>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ bus-width = <8>;
+ cd-gpios = <&gpio2 0 0>;
+ wp-gpios = <&gpio2 1 0>;
+ status = "okay";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ bus-width = <8>;
+ non-removable;
+ no-1-8-v;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-tx6.dtsi b/arch/arm/boot/dts/imx6qdl-tx6.dtsi
new file mode 100644
index 000000000..f02b80b41
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-tx6.dtsi
@@ -0,0 +1,696 @@
+/*
+ * Copyright 2014 Lothar WaĂŸmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ aliases {
+ can0 = &can2;
+ can1 = &can1;
+ ethernet0 = &fec;
+ lcdif_23bit_pins_a = &pinctrl_disp0_1;
+ lcdif_24bit_pins_a = &pinctrl_disp0_2;
+ pwm0 = &pwm1;
+ pwm1 = &pwm2;
+ reg_can_xcvr = &reg_can_xcvr;
+ stk5led = &user_led;
+ usbotg = &usbotg;
+ sdhc0 = &usdhc1;
+ sdhc1 = &usdhc2;
+ };
+
+ memory {
+ reg = <0 0>; /* will be filled by U-Boot */
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ mclk: clock@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ #clock-cells = <0>;
+ clock-frequency = <27000000>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power Button";
+ gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>;
+ linux,code = <KEY_POWER>;
+ gpio-key,wakeup;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ user_led: user {
+ label = "Heartbeat";
+ gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3v3_etn: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3V3_ETN";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_etnphy_power>;
+ gpio = <&gpio3 20 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_2v5: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "2V5";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ reg_3v3: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_can_xcvr: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "CAN XCVR";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan_xcvr>;
+ gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>;
+ enable-active-low;
+ };
+
+ reg_lcd0_pwr: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "LCD0 POWER";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcd0_pwr>;
+ gpio = <&gpio3 29 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_lcd1_pwr: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "LCD1 POWER";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcd1_pwr>;
+ gpio = <&gpio2 31 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_usbh1_vbus: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ regulator-name = "usbh1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1_vbus>;
+ gpio = <&gpio3 31 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usbotg_vbus: regulator@7 {
+ compatible = "regulator-fixed";
+ reg = <7>;
+ regulator-name = "usbotg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg_vbus>;
+ gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ sound {
+ compatible = "karo,imx6qdl-tx6qdl-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "sgtl5000-audio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ ssi-controller = <&ssi1>;
+ audio-codec = <&sgtl5000>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <1>;
+ mux-ext-port = <5>;
+ };
+};
+
+&audmux {
+ status = "okay";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can_xcvr>;
+ status = "okay";
+};
+
+&can2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can_xcvr>;
+ status = "okay";
+};
+
+&ecspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ fsl,spi-num-chipselects = <2>;
+ cs-gpios = <
+ &gpio2 30 GPIO_ACTIVE_HIGH
+ &gpio3 19 GPIO_ACTIVE_HIGH
+ >;
+ status = "okay";
+
+ spidev0: spi@0 {
+ compatible = "spidev";
+ reg = <0>;
+ spi-max-frequency = <54000000>;
+ };
+
+ spidev1: spi@1 {
+ compatible = "spidev";
+ reg = <1>;
+ spi-max-frequency = <54000000>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rmii";
+ phy-reset-gpios = <&gpio7 6 GPIO_ACTIVE_HIGH>;
+ phy-supply = <&reg_3v3_etn>;
+ status = "okay";
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand>;
+ nand-on-flash-bbt;
+ fsl,no-blockmark-swap;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ ds1339: rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ };
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ sgtl5000: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ VDDA-supply = <&reg_2v5>;
+ VDDIO-supply = <&reg_3v3>;
+ clocks = <&mclk>;
+ };
+
+ polytouch: edt-ft5x06@38 {
+ compatible = "edt,edt-ft5x06";
+ reg = <0x38>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_edt_ft5x06>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <15 0>;
+ reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
+ linux,wakeup;
+ };
+
+ touchscreen: tsc2007@48 {
+ compatible = "ti,tsc2007";
+ reg = <0x48>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tsc2007>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <26 0>;
+ gpios = <&gpio3 26 GPIO_ACTIVE_LOW>;
+ ti,x-plate-ohms = <660>;
+ linux,wakeup;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6qdl-tx6 {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_A18__GPIO2_IO20 0x1b0b1 /* LED */
+ MX6QDL_PAD_SD3_DAT2__GPIO7_IO06 0x1b0b1 /* ETN PHY RESET */
+ MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x1b0b1 /* ETN PHY INT */
+ MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x1b0b1 /* PWR BTN */
+ >;
+ };
+
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW1__AUD5_RXD 0x130b0 /* SSI1_RXD */
+ MX6QDL_PAD_KEY_ROW0__AUD5_TXD 0x110b0 /* SSI1_TXD */
+ MX6QDL_PAD_KEY_COL0__AUD5_TXC 0x130b0 /* SSI1_CLK */
+ MX6QDL_PAD_KEY_COL1__AUD5_TXFS 0x130b0 /* SSI1_FS */
+ >;
+ };
+
+ pinctrl_disp0_1: disp0grp-1 {
+ fsl,pins = <
+ MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
+ MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x10
+ MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x10
+ MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x10
+ /* PAD DISP0_DAT0 is used for the Flexcan transceiver control */
+ MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x10
+ MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x10
+ MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x10
+ MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x10
+ MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x10
+ MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x10
+ MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x10
+ MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x10
+ MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x10
+ MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x10
+ MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x10
+ MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x10
+ MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x10
+ MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x10
+ MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x10
+ MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x10
+ MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x10
+ MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x10
+ MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x10
+ MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x10
+ MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x10
+ MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x10
+ MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x10
+ >;
+ };
+
+ pinctrl_disp0_2: disp0grp-2 {
+ fsl,pins = <
+ MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
+ MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x10
+ MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x10
+ MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x10
+ MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x10
+ MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x10
+ MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x10
+ MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x10
+ MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x10
+ MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x10
+ MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x10
+ MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x10
+ MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x10
+ MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x10
+ MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x10
+ MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x10
+ MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x10
+ MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x10
+ MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x10
+ MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x10
+ MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x10
+ MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x10
+ MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x10
+ MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x10
+ MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x10
+ MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x10
+ MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x10
+ MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x10
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x0b0b0
+ MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x0b0b0
+ MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x0b0b0
+ MX6QDL_PAD_GPIO_19__ECSPI1_RDY 0x0b0b0
+ MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x0b0b0 /* SPI CS0 */
+ MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x0b0b0 /* SPI CS1 */
+ >;
+ };
+
+ pinctrl_edt_ft5x06: edt-ft5x06grp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x1b0b0 /* Interrupt */
+ MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x1b0b0 /* Reset */
+ MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x1b0b0 /* Wake */
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0 0x1b0b0
+ MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1 0x1b0b0
+ MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER 0x1b0b0
+ MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
+ MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0 0x1b0b0
+ MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1 0x1b0b0
+ MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN 0x1b0b0
+ >;
+ };
+
+ pinctrl_etnphy_power: etnphy-pwrgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D20__GPIO3_IO20 0x1b0b1 /* ETN PHY POWER */
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x1b0b0
+ MX6QDL_PAD_GPIO_8__FLEXCAN1_RX 0x1b0b0
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x1b0b0
+ MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x1b0b0
+ >;
+ };
+
+ pinctrl_flexcan_xcvr: flexcan-xcvrgrp {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT0__GPIO4_IO21 0x1b0b0 /* Flexcan XCVR enable */
+ >;
+ };
+
+ pinctrl_gpmi_nand: gpminandgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__NAND_CLE 0x0b0b1
+ MX6QDL_PAD_NANDF_ALE__NAND_ALE 0x0b0b1
+ MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0x0b0b1
+ MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0x0b000
+ MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0x0b0b1
+ MX6QDL_PAD_SD4_CMD__NAND_RE_B 0x0b0b1
+ MX6QDL_PAD_SD4_CLK__NAND_WE_B 0x0b0b1
+ MX6QDL_PAD_NANDF_D0__NAND_DATA00 0x0b0b1
+ MX6QDL_PAD_NANDF_D1__NAND_DATA01 0x0b0b1
+ MX6QDL_PAD_NANDF_D2__NAND_DATA02 0x0b0b1
+ MX6QDL_PAD_NANDF_D3__NAND_DATA03 0x0b0b1
+ MX6QDL_PAD_NANDF_D4__NAND_DATA04 0x0b0b1
+ MX6QDL_PAD_NANDF_D5__NAND_DATA05 0x0b0b1
+ MX6QDL_PAD_NANDF_D6__NAND_DATA06 0x0b0b1
+ MX6QDL_PAD_NANDF_D7__NAND_DATA07 0x0b0b1
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_kpp: kppgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_9__KEY_COL6 0x1b0b1
+ MX6QDL_PAD_GPIO_4__KEY_COL7 0x1b0b1
+ MX6QDL_PAD_KEY_COL2__KEY_COL2 0x1b0b1
+ MX6QDL_PAD_KEY_COL3__KEY_COL3 0x1b0b1
+ MX6QDL_PAD_GPIO_2__KEY_ROW6 0x1b0b1
+ MX6QDL_PAD_GPIO_5__KEY_ROW7 0x1b0b1
+ MX6QDL_PAD_KEY_ROW2__KEY_ROW2 0x1b0b1
+ MX6QDL_PAD_KEY_ROW3__KEY_ROW3 0x1b0b1
+ >;
+ };
+
+ pinctrl_lcd0_pwr: lcd0-pwrgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b1 /* LCD Reset */
+ >;
+ };
+
+ pinctrl_lcd1_pwr: lcd1-pwrgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_EB3__GPIO2_IO31 0x1b0b1 /* LCD Power Enable */
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_9__PWM1_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm2: pwm2grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__PWM2_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_tsc2007: tsc2007grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x1b0b0 /* Interrupt */
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart1_rtscts: uart1_rtsctsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_DAT1__UART1_RTS_B 0x1b0b1
+ MX6QDL_PAD_SD3_DAT0__UART1_CTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2_rtscts: uart2_rtsctsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT5__UART2_RTS_B 0x1b0b1
+ MX6QDL_PAD_SD4_DAT6__UART2_CTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart3_rtscts: uart3_rtsctsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_DAT3__UART3_CTS_B 0x1b0b1
+ MX6QDL_PAD_SD3_RST__UART3_RTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbh1_vbus: usbh1-vbusgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x1b0b0 /* USBH1_VBUSEN */
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x17059
+ >;
+ };
+
+ pinctrl_usbotg_vbus: usbotg-vbusgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_7__GPIO1_IO07 0x1b0b0 /* USBOTG_VBUSEN */
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__SD1_CMD 0x070b1
+ MX6QDL_PAD_SD1_CLK__SD1_CLK 0x070b1
+ MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x070b1
+ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x070b1
+ MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x070b1
+ MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x070b1
+ MX6QDL_PAD_SD3_CMD__GPIO7_IO02 0x170b0 /* SD1 CD */
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x070b1
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x070b1
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x070b1
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x070b1
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x070b1
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x070b1
+ MX6QDL_PAD_SD3_CLK__GPIO7_IO03 0x170b0 /* SD2 CD */
+ >;
+ };
+ };
+};
+
+&kpp {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_kpp>;
+ /* sample keymap */
+ /* row/col 0,1 are mapped to KPP row/col 6,7 */
+ linux,keymap = <
+ MATRIX_KEY(6, 6, KEY_POWER) /* 0x06060074 */
+ MATRIX_KEY(6, 7, KEY_KP0) /* 0x06070052 */
+ MATRIX_KEY(6, 2, KEY_KP1) /* 0x0602004f */
+ MATRIX_KEY(6, 3, KEY_KP2) /* 0x06030050 */
+ MATRIX_KEY(7, 6, KEY_KP3) /* 0x07060051 */
+ MATRIX_KEY(7, 7, KEY_KP4) /* 0x0707004b */
+ MATRIX_KEY(7, 2, KEY_KP5) /* 0x0702004c */
+ MATRIX_KEY(7, 3, KEY_KP6) /* 0x0703004d */
+ MATRIX_KEY(2, 6, KEY_KP7) /* 0x02060047 */
+ MATRIX_KEY(2, 7, KEY_KP8) /* 0x02070048 */
+ MATRIX_KEY(2, 2, KEY_KP9) /* 0x02020049 */
+ >;
+ status = "okay";
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ #pwm-cells = <3>;
+ status = "disabled";
+};
+
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm2>;
+ #pwm-cells = <3>;
+ status = "okay";
+};
+
+&ssi1 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2 &pinctrl_uart2_rtscts>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3 &pinctrl_uart3_rtscts>;
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usbh1_vbus>;
+ dr_mode = "host";
+ disable-over-current;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usbotg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ dr_mode = "peripheral";
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ bus-width = <4>;
+ no-1-8-v;
+ cd-gpios = <&gpio7 2 0>;
+ fsl,wp-controller;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ bus-width = <4>;
+ no-1-8-v;
+ cd-gpios = <&gpio7 3 0>;
+ fsl,wp-controller;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-udoo.dtsi b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
new file mode 100644
index 000000000..1211da894
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/ {
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb_h1_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ startup-delay-us = <2>; /* USB2415 requires a POR of 1 us minimum */
+ gpio = <&gpio7 12 0>;
+ };
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c2>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&iomuxc {
+ imx6q-udoo {
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbh: usbhgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000
+ MX6QDL_PAD_NANDF_CS2__CCM_CLKO2 0x130b0
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ >;
+ };
+ };
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&usbh1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh>;
+ vbus-supply = <&reg_usb_h1_vbus>;
+ clocks = <&clks 201>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-wandboard-revb1.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard-revb1.dtsi
new file mode 100644
index 000000000..ef7fa62b9
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-wandboard-revb1.dtsi
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include "imx6qdl-wandboard.dtsi"
+
+&iomuxc {
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6qdl-wandboard {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0 /* GPIO_0_CLKO */
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000 /* uSDHC1 CD */
+ MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0x80000000 /* uSDHC3 CD */
+ MX6QDL_PAD_EIM_EB1__GPIO2_IO29 0x0f0b0 /* WL_REF_ON */
+ MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x0f0b0 /* WL_RST_N */
+ MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x000b0 /* WL_REG_ON */
+ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* WL_HOST_WAKE */
+ MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* WL_WAKE */
+ MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x80000000 /* RGMII_nRST */
+ MX6QDL_PAD_EIM_DA13__GPIO3_IO13 0x80000000 /* BT_ON */
+ MX6QDL_PAD_EIM_DA14__GPIO3_IO14 0x80000000 /* BT_WAKE */
+ MX6QDL_PAD_EIM_DA15__GPIO3_IO15 0x80000000 /* BT_HOST_WAKE */
+ >;
+ };
+ };
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-wandboard-revc1.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard-revc1.dtsi
new file mode 100644
index 000000000..8d893a78c
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-wandboard-revc1.dtsi
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include "imx6qdl-wandboard.dtsi"
+
+&iomuxc {
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6qdl-wandboard {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0 /* GPIO_0_CLKO */
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000 /* uSDHC1 CD */
+ MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0x80000000 /* uSDHC3 CD */
+ MX6QDL_PAD_CSI0_DAT14__GPIO6_IO00 0x0f0b0 /* WIFI_ON (reset, active low) */
+ MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x000b0 /* WL_REG_ON (unused) */
+ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* WL_HOST_WAKE, input */
+ MX6QDL_PAD_CSI0_DAT13__GPIO5_IO31 0x0f0b0 /* GPIO5_IO31 (Wifi Power Enable) */
+ MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* WL_WAKE (unused) */
+ MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21 0x80000000 /* BT_ON */
+ MX6QDL_PAD_CSI0_DAT12__GPIO5_IO30 0x80000000 /* BT_WAKE */
+ MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x80000000 /* BT_HOST_WAKE */
+ MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x80000000 /* RGMII_nRST */
+ >;
+ };
+ };
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
new file mode 100644
index 000000000..5fb091675
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/ {
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_2p5v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "2P5V";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6-wandboard-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx6-wandboard-sgtl5000";
+ ssi-controller = <&ssi1>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <1>;
+ mux-ext-port = <3>;
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif>;
+ spdif-out;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c1>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&clks 201>;
+ VDDA-supply = <&reg_2p5v>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+
+ imx6qdl-wandboard {
+
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
+ MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
+ MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0
+ MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_spdif: spdifgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_RXD0__SPDIF_OUT 0x1b0b0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x1b0b1
+ MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059
+ MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059
+ MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
+ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
+ MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
+ MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ >;
+ };
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio3 29 0>;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ status = "okay";
+};
+
+&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif>;
+ status = "okay";
+};
+
+&ssi1 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&usbh1 {
+ status = "okay";
+};
+
+&usbotg {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ cd-gpios = <&gpio1 2 0>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ cd-gpios = <&gpio3 9 0>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
new file mode 100644
index 000000000..2d89a7be7
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -0,0 +1,1193 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 <dt-bindings/clock/imx6qdl-clock.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ aliases {
+ ethernet0 = &fec;
+ can0 = &can1;
+ can1 = &can2;
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ gpio4 = &gpio5;
+ gpio5 = &gpio6;
+ gpio6 = &gpio7;
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ i2c2 = &i2c3;
+ mmc0 = &usdhc1;
+ mmc1 = &usdhc2;
+ mmc2 = &usdhc3;
+ mmc3 = &usdhc4;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ spi0 = &ecspi1;
+ spi1 = &ecspi2;
+ spi2 = &ecspi3;
+ spi3 = &ecspi4;
+ usbphy0 = &usbphy1;
+ usbphy1 = &usbphy2;
+ };
+
+ intc: interrupt-controller@00a01000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x00a01000 0x1000>,
+ <0x00a00100 0x100>;
+ interrupt-parent = <&intc>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ckil {
+ compatible = "fsl,imx-ckil", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+
+ ckih1 {
+ compatible = "fsl,imx-ckih1", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ osc {
+ compatible = "fsl,imx-osc", "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&gpc>;
+ ranges;
+
+ dma_apbh: dma-apbh@00110000 {
+ compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
+ reg = <0x00110000 0x2000>;
+ interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>,
+ <0 13 IRQ_TYPE_LEVEL_HIGH>,
+ <0 13 IRQ_TYPE_LEVEL_HIGH>,
+ <0 13 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
+ #dma-cells = <1>;
+ dma-channels = <4>;
+ clocks = <&clks IMX6QDL_CLK_APBH_DMA>;
+ };
+
+ gpmi: gpmi-nand@00112000 {
+ compatible = "fsl,imx6q-gpmi-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x00112000 0x2000>, <0x00114000 0x2000>;
+ reg-names = "gpmi-nand", "bch";
+ interrupts = <0 15 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "bch";
+ clocks = <&clks IMX6QDL_CLK_GPMI_IO>,
+ <&clks IMX6QDL_CLK_GPMI_APB>,
+ <&clks IMX6QDL_CLK_GPMI_BCH>,
+ <&clks IMX6QDL_CLK_GPMI_BCH_APB>,
+ <&clks IMX6QDL_CLK_PER1_BCH>;
+ clock-names = "gpmi_io", "gpmi_apb", "gpmi_bch",
+ "gpmi_bch_apb", "per1_bch";
+ dmas = <&dma_apbh 0>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ timer@00a00600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x00a00600 0x20>;
+ interrupts = <1 13 0xf01>;
+ interrupt-parent = <&intc>;
+ clocks = <&clks IMX6QDL_CLK_TWD>;
+ };
+
+ L2: l2-cache@00a02000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x00a02000 0x1000>;
+ interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
+ cache-unified;
+ cache-level = <2>;
+ arm,tag-latency = <4 2 3>;
+ arm,data-latency = <4 2 3>;
+ };
+
+ pcie: pcie@0x01000000 {
+ compatible = "fsl,imx6q-pcie", "snps,dw-pcie";
+ reg = <0x01ffc000 0x04000>,
+ <0x01f00000 0x80000>;
+ reg-names = "dbi", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x00000800 0 0x01f00000 0x01f00000 0 0x00080000 /* configuration space */
+ 0x81000000 0 0 0x01f80000 0 0x00010000 /* downstream I/O */
+ 0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
+ num-lanes = <1>;
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_PCIE_AXI>,
+ <&clks IMX6QDL_CLK_LVDS1_GATE>,
+ <&clks IMX6QDL_CLK_PCIE_REF_125M>;
+ clock-names = "pcie", "pcie_bus", "pcie_phy";
+ status = "disabled";
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ aips-bus@02000000 { /* AIPS1 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02000000 0x100000>;
+ ranges;
+
+ spba-bus@02000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02000000 0x40000>;
+ ranges;
+
+ spdif: spdif@02004000 {
+ compatible = "fsl,imx35-spdif";
+ reg = <0x02004000 0x4000>;
+ interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 14 18 0>,
+ <&sdma 15 18 0>;
+ dma-names = "rx", "tx";
+ clocks = <&clks IMX6QDL_CLK_SPDIF>, <&clks IMX6QDL_CLK_OSC>,
+ <&clks IMX6QDL_CLK_SPDIF>, <&clks IMX6QDL_CLK_DUMMY>,
+ <&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_DUMMY>,
+ <&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_DUMMY>,
+ <&clks IMX6QDL_CLK_DUMMY>;
+ clock-names = "core", "rxtx0",
+ "rxtx1", "rxtx2",
+ "rxtx3", "rxtx4",
+ "rxtx5", "rxtx6",
+ "rxtx7";
+ status = "disabled";
+ };
+
+ ecspi1: ecspi@02008000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02008000 0x4000>;
+ interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_ECSPI1>,
+ <&clks IMX6QDL_CLK_ECSPI1>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ ecspi2: ecspi@0200c000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+ reg = <0x0200c000 0x4000>;
+ interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_ECSPI2>,
+ <&clks IMX6QDL_CLK_ECSPI2>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 5 7 1>, <&sdma 6 7 2>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ ecspi3: ecspi@02010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02010000 0x4000>;
+ interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_ECSPI3>,
+ <&clks IMX6QDL_CLK_ECSPI3>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 7 7 1>, <&sdma 8 7 2>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ ecspi4: ecspi@02014000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02014000 0x4000>;
+ interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_ECSPI4>,
+ <&clks IMX6QDL_CLK_ECSPI4>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart1: serial@02020000 {
+ compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02020000 0x4000>;
+ interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_UART_IPG>,
+ <&clks IMX6QDL_CLK_UART_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 25 4 0>, <&sdma 26 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ esai: esai@02024000 {
+ reg = <0x02024000 0x4000>;
+ interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ ssi1: ssi@02028000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx6q-ssi",
+ "fsl,imx51-ssi";
+ reg = <0x02028000 0x4000>;
+ interrupts = <0 46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_SSI1_IPG>,
+ <&clks IMX6QDL_CLK_SSI1>;
+ clock-names = "ipg", "baud";
+ dmas = <&sdma 37 1 0>,
+ <&sdma 38 1 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ ssi2: ssi@0202c000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx6q-ssi",
+ "fsl,imx51-ssi";
+ reg = <0x0202c000 0x4000>;
+ interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_SSI2_IPG>,
+ <&clks IMX6QDL_CLK_SSI2>;
+ clock-names = "ipg", "baud";
+ dmas = <&sdma 41 1 0>,
+ <&sdma 42 1 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ ssi3: ssi@02030000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx6q-ssi",
+ "fsl,imx51-ssi";
+ reg = <0x02030000 0x4000>;
+ interrupts = <0 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_SSI3_IPG>,
+ <&clks IMX6QDL_CLK_SSI3>;
+ clock-names = "ipg", "baud";
+ dmas = <&sdma 45 1 0>,
+ <&sdma 46 1 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ asrc: asrc@02034000 {
+ reg = <0x02034000 0x4000>;
+ interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ spba@0203c000 {
+ reg = <0x0203c000 0x4000>;
+ };
+ };
+
+ vpu: vpu@02040000 {
+ compatible = "cnm,coda960";
+ reg = <0x02040000 0x3c000>;
+ interrupts = <0 12 IRQ_TYPE_LEVEL_HIGH>,
+ <0 3 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "bit", "jpeg";
+ clocks = <&clks IMX6QDL_CLK_VPU_AXI>,
+ <&clks IMX6QDL_CLK_MMDC_CH0_AXI>;
+ clock-names = "per", "ahb";
+ resets = <&src 1>;
+ iram = <&ocram>;
+ };
+
+ aipstz@0207c000 { /* AIPSTZ1 */
+ reg = <0x0207c000 0x4000>;
+ };
+
+ pwm1: pwm@02080000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
+ reg = <0x02080000 0x4000>;
+ interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_IPG>,
+ <&clks IMX6QDL_CLK_PWM1>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ pwm2: pwm@02084000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
+ reg = <0x02084000 0x4000>;
+ interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_IPG>,
+ <&clks IMX6QDL_CLK_PWM2>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ pwm3: pwm@02088000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
+ reg = <0x02088000 0x4000>;
+ interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_IPG>,
+ <&clks IMX6QDL_CLK_PWM3>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ pwm4: pwm@0208c000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
+ reg = <0x0208c000 0x4000>;
+ interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_IPG>,
+ <&clks IMX6QDL_CLK_PWM4>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ can1: flexcan@02090000 {
+ compatible = "fsl,imx6q-flexcan";
+ reg = <0x02090000 0x4000>;
+ interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_CAN1_IPG>,
+ <&clks IMX6QDL_CLK_CAN1_SERIAL>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ can2: flexcan@02094000 {
+ compatible = "fsl,imx6q-flexcan";
+ reg = <0x02094000 0x4000>;
+ interrupts = <0 111 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_CAN2_IPG>,
+ <&clks IMX6QDL_CLK_CAN2_SERIAL>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ gpt: gpt@02098000 {
+ compatible = "fsl,imx6q-gpt", "fsl,imx31-gpt";
+ reg = <0x02098000 0x4000>;
+ interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_GPT_IPG>,
+ <&clks IMX6QDL_CLK_GPT_IPG_PER>,
+ <&clks IMX6QDL_CLK_GPT_3M>;
+ clock-names = "ipg", "per", "osc_per";
+ };
+
+ gpio1: gpio@0209c000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x0209c000 0x4000>;
+ interrupts = <0 66 IRQ_TYPE_LEVEL_HIGH>,
+ <0 67 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@020a0000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020a0000 0x4000>;
+ interrupts = <0 68 IRQ_TYPE_LEVEL_HIGH>,
+ <0 69 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@020a4000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020a4000 0x4000>;
+ interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>,
+ <0 71 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@020a8000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020a8000 0x4000>;
+ interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>,
+ <0 73 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio5: gpio@020ac000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020ac000 0x4000>;
+ interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>,
+ <0 75 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio6: gpio@020b0000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020b0000 0x4000>;
+ interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>,
+ <0 77 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio7: gpio@020b4000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020b4000 0x4000>;
+ interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>,
+ <0 79 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ kpp: kpp@020b8000 {
+ compatible = "fsl,imx6q-kpp", "fsl,imx21-kpp";
+ reg = <0x020b8000 0x4000>;
+ interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_IPG>;
+ status = "disabled";
+ };
+
+ wdog1: wdog@020bc000 {
+ compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
+ reg = <0x020bc000 0x4000>;
+ interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_DUMMY>;
+ };
+
+ wdog2: wdog@020c0000 {
+ compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
+ reg = <0x020c0000 0x4000>;
+ interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_DUMMY>;
+ status = "disabled";
+ };
+
+ clks: ccm@020c4000 {
+ compatible = "fsl,imx6q-ccm";
+ reg = <0x020c4000 0x4000>;
+ interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>,
+ <0 88 IRQ_TYPE_LEVEL_HIGH>;
+ #clock-cells = <1>;
+ };
+
+ anatop: anatop@020c8000 {
+ compatible = "fsl,imx6q-anatop", "syscon", "simple-bus";
+ reg = <0x020c8000 0x1000>;
+ interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
+ <0 54 IRQ_TYPE_LEVEL_HIGH>,
+ <0 127 IRQ_TYPE_LEVEL_HIGH>;
+
+ regulator-1p1@110 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd1p1";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1375000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x110>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <4>;
+ anatop-min-voltage = <800000>;
+ anatop-max-voltage = <1375000>;
+ };
+
+ regulator-3p0@120 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd3p0";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3150000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x120>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <0>;
+ anatop-min-voltage = <2625000>;
+ anatop-max-voltage = <3400000>;
+ };
+
+ regulator-2p5@130 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd2p5";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2750000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x130>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <0>;
+ anatop-min-voltage = <2000000>;
+ anatop-max-voltage = <2750000>;
+ };
+
+ reg_arm: regulator-vddcore@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vddarm";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <0>;
+ anatop-vol-bit-width = <5>;
+ anatop-delay-reg-offset = <0x170>;
+ anatop-delay-bit-shift = <24>;
+ anatop-delay-bit-width = <2>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
+
+ reg_pu: regulator-vddpu@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vddpu";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-enable-ramp-delay = <150>;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <9>;
+ anatop-vol-bit-width = <5>;
+ anatop-delay-reg-offset = <0x170>;
+ anatop-delay-bit-shift = <26>;
+ anatop-delay-bit-width = <2>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
+
+ reg_soc: regulator-vddsoc@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vddsoc";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <18>;
+ anatop-vol-bit-width = <5>;
+ anatop-delay-reg-offset = <0x170>;
+ anatop-delay-bit-shift = <28>;
+ anatop-delay-bit-width = <2>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
+ };
+
+ tempmon: tempmon {
+ compatible = "fsl,imx6q-tempmon";
+ interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,tempmon = <&anatop>;
+ fsl,tempmon-data = <&ocotp>;
+ clocks = <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
+ };
+
+ usbphy1: usbphy@020c9000 {
+ compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
+ reg = <0x020c9000 0x1000>;
+ interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_USBPHY1>;
+ fsl,anatop = <&anatop>;
+ };
+
+ usbphy2: usbphy@020ca000 {
+ compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
+ reg = <0x020ca000 0x1000>;
+ interrupts = <0 45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_USBPHY2>;
+ fsl,anatop = <&anatop>;
+ };
+
+ snvs@020cc000 {
+ compatible = "fsl,sec-v4.0-mon", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x020cc000 0x4000>;
+
+ snvs_rtc: snvs-rtc-lp@34 {
+ compatible = "fsl,sec-v4.0-mon-rtc-lp";
+ reg = <0x34 0x58>;
+ interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>,
+ <0 20 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ snvs_poweroff: snvs-poweroff@38 {
+ compatible = "fsl,sec-v4.0-poweroff";
+ reg = <0x38 0x4>;
+ status = "disabled";
+ };
+ };
+
+ epit1: epit@020d0000 { /* EPIT1 */
+ reg = <0x020d0000 0x4000>;
+ interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ epit2: epit@020d4000 { /* EPIT2 */
+ reg = <0x020d4000 0x4000>;
+ interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ src: src@020d8000 {
+ compatible = "fsl,imx6q-src", "fsl,imx51-src";
+ reg = <0x020d8000 0x4000>;
+ interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>,
+ <0 96 IRQ_TYPE_LEVEL_HIGH>;
+ #reset-cells = <1>;
+ };
+
+ gpc: gpc@020dc000 {
+ compatible = "fsl,imx6q-gpc";
+ reg = <0x020dc000 0x4000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>,
+ <0 90 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&intc>;
+ pu-supply = <&reg_pu>;
+ clocks = <&clks IMX6QDL_CLK_GPU3D_CORE>,
+ <&clks IMX6QDL_CLK_GPU3D_SHADER>,
+ <&clks IMX6QDL_CLK_GPU2D_CORE>,
+ <&clks IMX6QDL_CLK_GPU2D_AXI>,
+ <&clks IMX6QDL_CLK_OPENVG_AXI>,
+ <&clks IMX6QDL_CLK_VPU_AXI>;
+ #power-domain-cells = <1>;
+ };
+
+ gpr: iomuxc-gpr@020e0000 {
+ compatible = "fsl,imx6q-iomuxc-gpr", "syscon";
+ reg = <0x020e0000 0x38>;
+ };
+
+ iomuxc: iomuxc@020e0000 {
+ compatible = "fsl,imx6dl-iomuxc", "fsl,imx6q-iomuxc";
+ reg = <0x020e0000 0x4000>;
+ };
+
+ ldb: ldb@020e0008 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-ldb", "fsl,imx53-ldb";
+ gpr = <&gpr>;
+ status = "disabled";
+
+ lvds-channel@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ lvds0_mux_0: endpoint {
+ remote-endpoint = <&ipu1_di0_lvds0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ lvds0_mux_1: endpoint {
+ remote-endpoint = <&ipu1_di1_lvds0>;
+ };
+ };
+ };
+
+ lvds-channel@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ lvds1_mux_0: endpoint {
+ remote-endpoint = <&ipu1_di0_lvds1>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ lvds1_mux_1: endpoint {
+ remote-endpoint = <&ipu1_di1_lvds1>;
+ };
+ };
+ };
+ };
+
+ hdmi: hdmi@0120000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x00120000 0x9000>;
+ interrupts = <0 115 0x04>;
+ gpr = <&gpr>;
+ clocks = <&clks IMX6QDL_CLK_HDMI_IAHB>,
+ <&clks IMX6QDL_CLK_HDMI_ISFR>;
+ clock-names = "iahb", "isfr";
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ hdmi_mux_0: endpoint {
+ remote-endpoint = <&ipu1_di0_hdmi>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ hdmi_mux_1: endpoint {
+ remote-endpoint = <&ipu1_di1_hdmi>;
+ };
+ };
+ };
+
+ dcic1: dcic@020e4000 {
+ reg = <0x020e4000 0x4000>;
+ interrupts = <0 124 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dcic2: dcic@020e8000 {
+ reg = <0x020e8000 0x4000>;
+ interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sdma: sdma@020ec000 {
+ compatible = "fsl,imx6q-sdma", "fsl,imx35-sdma";
+ reg = <0x020ec000 0x4000>;
+ interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_SDMA>,
+ <&clks IMX6QDL_CLK_SDMA>;
+ clock-names = "ipg", "ahb";
+ #dma-cells = <3>;
+ fsl,sdma-ram-script-name = "/*(DEBLOBBED)*/";
+ };
+ };
+
+ aips-bus@02100000 { /* AIPS2 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02100000 0x100000>;
+ ranges;
+
+ caam@02100000 {
+ reg = <0x02100000 0x40000>;
+ interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>,
+ <0 106 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ aipstz@0217c000 { /* AIPSTZ2 */
+ reg = <0x0217c000 0x4000>;
+ };
+
+ usbotg: usb@02184000 {
+ compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+ reg = <0x02184000 0x200>;
+ interrupts = <0 43 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_USBOH3>;
+ fsl,usbphy = <&usbphy1>;
+ fsl,usbmisc = <&usbmisc 0>;
+ status = "disabled";
+ };
+
+ usbh1: usb@02184200 {
+ compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+ reg = <0x02184200 0x200>;
+ interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_USBOH3>;
+ fsl,usbphy = <&usbphy2>;
+ fsl,usbmisc = <&usbmisc 1>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbh2: usb@02184400 {
+ compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+ reg = <0x02184400 0x200>;
+ interrupts = <0 41 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_USBOH3>;
+ fsl,usbmisc = <&usbmisc 2>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbh3: usb@02184600 {
+ compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+ reg = <0x02184600 0x200>;
+ interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_USBOH3>;
+ fsl,usbmisc = <&usbmisc 3>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbmisc: usbmisc@02184800 {
+ #index-cells = <1>;
+ compatible = "fsl,imx6q-usbmisc";
+ reg = <0x02184800 0x200>;
+ clocks = <&clks IMX6QDL_CLK_USBOH3>;
+ };
+
+ fec: ethernet@02188000 {
+ compatible = "fsl,imx6q-fec";
+ reg = <0x02188000 0x4000>;
+ interrupts-extended =
+ <&intc 0 118 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_ENET>,
+ <&clks IMX6QDL_CLK_ENET>,
+ <&clks IMX6QDL_CLK_ENET_REF>;
+ clock-names = "ipg", "ahb", "ptp";
+ status = "disabled";
+ };
+
+ mlb@0218c000 {
+ reg = <0x0218c000 0x4000>;
+ interrupts = <0 53 IRQ_TYPE_LEVEL_HIGH>,
+ <0 117 IRQ_TYPE_LEVEL_HIGH>,
+ <0 126 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ usdhc1: usdhc@02190000 {
+ compatible = "fsl,imx6q-usdhc";
+ reg = <0x02190000 0x4000>;
+ interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_USDHC1>,
+ <&clks IMX6QDL_CLK_USDHC1>,
+ <&clks IMX6QDL_CLK_USDHC1>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ usdhc2: usdhc@02194000 {
+ compatible = "fsl,imx6q-usdhc";
+ reg = <0x02194000 0x4000>;
+ interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_USDHC2>,
+ <&clks IMX6QDL_CLK_USDHC2>,
+ <&clks IMX6QDL_CLK_USDHC2>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ usdhc3: usdhc@02198000 {
+ compatible = "fsl,imx6q-usdhc";
+ reg = <0x02198000 0x4000>;
+ interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_USDHC3>,
+ <&clks IMX6QDL_CLK_USDHC3>,
+ <&clks IMX6QDL_CLK_USDHC3>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ usdhc4: usdhc@0219c000 {
+ compatible = "fsl,imx6q-usdhc";
+ reg = <0x0219c000 0x4000>;
+ interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_USDHC4>,
+ <&clks IMX6QDL_CLK_USDHC4>,
+ <&clks IMX6QDL_CLK_USDHC4>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@021a0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
+ reg = <0x021a0000 0x4000>;
+ interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_I2C1>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@021a4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
+ reg = <0x021a4000 0x4000>;
+ interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_I2C2>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@021a8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
+ reg = <0x021a8000 0x4000>;
+ interrupts = <0 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_I2C3>;
+ status = "disabled";
+ };
+
+ romcp@021ac000 {
+ reg = <0x021ac000 0x4000>;
+ };
+
+ mmdc0: mmdc@021b0000 { /* MMDC0 */
+ compatible = "fsl,imx6q-mmdc";
+ reg = <0x021b0000 0x4000>;
+ };
+
+ mmdc1: mmdc@021b4000 { /* MMDC1 */
+ reg = <0x021b4000 0x4000>;
+ };
+
+ weim: weim@021b8000 {
+ compatible = "fsl,imx6q-weim";
+ reg = <0x021b8000 0x4000>;
+ interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_EIM_SLOW>;
+ };
+
+ ocotp: ocotp@021bc000 {
+ compatible = "fsl,imx6q-ocotp", "syscon";
+ reg = <0x021bc000 0x4000>;
+ };
+
+ tzasc@021d0000 { /* TZASC1 */
+ reg = <0x021d0000 0x4000>;
+ interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ tzasc@021d4000 { /* TZASC2 */
+ reg = <0x021d4000 0x4000>;
+ interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ audmux: audmux@021d8000 {
+ compatible = "fsl,imx6q-audmux", "fsl,imx31-audmux";
+ reg = <0x021d8000 0x4000>;
+ status = "disabled";
+ };
+
+ mipi_csi: mipi@021dc000 {
+ reg = <0x021dc000 0x4000>;
+ };
+
+ mipi_dsi: mipi@021e0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x021e0000 0x4000>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ mipi_mux_0: endpoint {
+ remote-endpoint = <&ipu1_di0_mipi>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ mipi_mux_1: endpoint {
+ remote-endpoint = <&ipu1_di1_mipi>;
+ };
+ };
+ };
+ };
+
+ vdoa@021e4000 {
+ reg = <0x021e4000 0x4000>;
+ interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ uart2: serial@021e8000 {
+ compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x021e8000 0x4000>;
+ interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_UART_IPG>,
+ <&clks IMX6QDL_CLK_UART_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 27 4 0>, <&sdma 28 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart3: serial@021ec000 {
+ compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x021ec000 0x4000>;
+ interrupts = <0 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_UART_IPG>,
+ <&clks IMX6QDL_CLK_UART_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 29 4 0>, <&sdma 30 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart4: serial@021f0000 {
+ compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x021f0000 0x4000>;
+ interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_UART_IPG>,
+ <&clks IMX6QDL_CLK_UART_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 31 4 0>, <&sdma 32 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart5: serial@021f4000 {
+ compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x021f4000 0x4000>;
+ interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_UART_IPG>,
+ <&clks IMX6QDL_CLK_UART_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 33 4 0>, <&sdma 34 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ };
+
+ ipu1: ipu@02400000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-ipu";
+ reg = <0x02400000 0x400000>;
+ interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>,
+ <0 5 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_IPU1>,
+ <&clks IMX6QDL_CLK_IPU1_DI0>,
+ <&clks IMX6QDL_CLK_IPU1_DI1>;
+ clock-names = "bus", "di0", "di1";
+ resets = <&src 2>;
+
+ ipu1_csi0: port@0 {
+ reg = <0>;
+ };
+
+ ipu1_csi1: port@1 {
+ reg = <1>;
+ };
+
+ ipu1_di0: port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ ipu1_di0_disp0: endpoint@0 {
+ };
+
+ ipu1_di0_hdmi: endpoint@1 {
+ remote-endpoint = <&hdmi_mux_0>;
+ };
+
+ ipu1_di0_mipi: endpoint@2 {
+ remote-endpoint = <&mipi_mux_0>;
+ };
+
+ ipu1_di0_lvds0: endpoint@3 {
+ remote-endpoint = <&lvds0_mux_0>;
+ };
+
+ ipu1_di0_lvds1: endpoint@4 {
+ remote-endpoint = <&lvds1_mux_0>;
+ };
+ };
+
+ ipu1_di1: port@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ ipu1_di0_disp1: endpoint@0 {
+ };
+
+ ipu1_di1_hdmi: endpoint@1 {
+ remote-endpoint = <&hdmi_mux_1>;
+ };
+
+ ipu1_di1_mipi: endpoint@2 {
+ remote-endpoint = <&mipi_mux_1>;
+ };
+
+ ipu1_di1_lvds0: endpoint@3 {
+ remote-endpoint = <&lvds0_mux_1>;
+ };
+
+ ipu1_di1_lvds1: endpoint@4 {
+ remote-endpoint = <&lvds1_mux_1>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sl-evk.dts b/arch/arm/boot/dts/imx6sl-evk.dts
new file mode 100644
index 000000000..945887d3f
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sl-evk.dts
@@ -0,0 +1,642 @@
+/*
+ * Copyright (C) 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "imx6sl.dtsi"
+
+/ {
+ model = "Freescale i.MX6 SoloLite EVK Board";
+ compatible = "fsl,imx6sl-evk", "fsl,imx6sl";
+
+ memory {
+ reg = <0x80000000 0x40000000>;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_led>;
+
+ user {
+ label = "debug";
+ gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb_otg1_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 0 0>;
+ enable-active-high;
+ vin-supply = <&swbst_reg>;
+ };
+
+ reg_usb_otg2_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb_otg2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 2 0>;
+ enable-active-high;
+ vin-supply = <&swbst_reg>;
+ };
+
+ reg_aud3v: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "wm8962-supply-3v15";
+ regulator-min-microvolt = <3150000>;
+ regulator-max-microvolt = <3150000>;
+ regulator-boot-on;
+ };
+
+ reg_aud4v: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "wm8962-supply-4v2";
+ regulator-min-microvolt = <4325000>;
+ regulator-max-microvolt = <4325000>;
+ regulator-boot-on;
+ };
+
+ reg_lcd_3v3: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "lcd-3v3";
+ gpio = <&gpio4 3 0>;
+ enable-active-high;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6sl-evk-wm8962", "fsl,imx-audio-wm8962";
+ model = "wm8962-audio";
+ ssi-controller = <&ssi2>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "Ext Spk", "SPKOUTL",
+ "Ext Spk", "SPKOUTR",
+ "AMIC", "MICBIAS",
+ "IN3R", "AMIC";
+ mux-int-port = <2>;
+ mux-ext-port = <3>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux3>;
+ status = "okay";
+};
+
+&ecspi1 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 11 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ status = "okay";
+
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p32";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_fec>;
+ pinctrl-1 = <&pinctrl_fec_sleep>;
+ phy-mode = "rmii";
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ codec: wm8962@1a {
+ compatible = "wlf,wm8962";
+ reg = <0x1a>;
+ clocks = <&clks IMX6SL_CLK_EXTERN_AUDIO>;
+ DCVDD-supply = <&vgen3_reg>;
+ DBVDD-supply = <&reg_aud3v>;
+ AVDD-supply = <&vgen3_reg>;
+ CPVDD-supply = <&vgen3_reg>;
+ MICVDD-supply = <&reg_aud3v>;
+ PLLVDD-supply = <&vgen3_reg>;
+ SPKVDD1-supply = <&reg_aud4v>;
+ SPKVDD2-supply = <&reg_aud4v>;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6sl-evk {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6SL_PAD_KEY_ROW7__GPIO4_IO07 0x17059
+ MX6SL_PAD_KEY_COL7__GPIO4_IO06 0x17059
+ MX6SL_PAD_SD2_DAT7__GPIO5_IO00 0x17059
+ MX6SL_PAD_SD2_DAT6__GPIO4_IO29 0x17059
+ MX6SL_PAD_REF_CLK_32K__GPIO3_IO22 0x17059
+ MX6SL_PAD_KEY_COL4__GPIO4_IO00 0x80000000
+ MX6SL_PAD_KEY_COL5__GPIO4_IO02 0x80000000
+ MX6SL_PAD_AUD_MCLK__AUDIO_CLK_OUT 0x4130b0
+ >;
+ };
+
+ pinctrl_audmux3: audmux3grp {
+ fsl,pins = <
+ MX6SL_PAD_AUD_RXD__AUD3_RXD 0x4130b0
+ MX6SL_PAD_AUD_TXC__AUD3_TXC 0x4130b0
+ MX6SL_PAD_AUD_TXD__AUD3_TXD 0x4110b0
+ MX6SL_PAD_AUD_TXFS__AUD3_TXFS 0x4130b0
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x100b1
+ MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1
+ MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1
+ MX6SL_PAD_ECSPI1_SS0__GPIO4_IO11 0x80000000
+ >;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX6SL_PAD_FEC_MDC__FEC_MDC 0x1b0b0
+ MX6SL_PAD_FEC_MDIO__FEC_MDIO 0x1b0b0
+ MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV 0x1b0b0
+ MX6SL_PAD_FEC_RXD0__FEC_RX_DATA0 0x1b0b0
+ MX6SL_PAD_FEC_RXD1__FEC_RX_DATA1 0x1b0b0
+ MX6SL_PAD_FEC_TX_EN__FEC_TX_EN 0x1b0b0
+ MX6SL_PAD_FEC_TXD0__FEC_TX_DATA0 0x1b0b0
+ MX6SL_PAD_FEC_TXD1__FEC_TX_DATA1 0x1b0b0
+ MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT 0x4001b0a8
+ >;
+ };
+
+ pinctrl_fec_sleep: fecgrp-sleep {
+ fsl,pins = <
+ MX6SL_PAD_FEC_MDC__GPIO4_IO23 0x3080
+ MX6SL_PAD_FEC_CRS_DV__GPIO4_IO25 0x3080
+ MX6SL_PAD_FEC_RXD0__GPIO4_IO17 0x3080
+ MX6SL_PAD_FEC_RXD1__GPIO4_IO18 0x3080
+ MX6SL_PAD_FEC_TX_EN__GPIO4_IO22 0x3080
+ MX6SL_PAD_FEC_TXD0__GPIO4_IO24 0x3080
+ MX6SL_PAD_FEC_TXD1__GPIO4_IO16 0x3080
+ MX6SL_PAD_FEC_REF_CLK__GPIO4_IO26 0x3080
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6SL_PAD_I2C1_SCL__I2C1_SCL 0x4001b8b1
+ MX6SL_PAD_I2C1_SDA__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6SL_PAD_I2C2_SCL__I2C2_SCL 0x4001b8b1
+ MX6SL_PAD_I2C2_SDA__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_kpp: kppgrp {
+ fsl,pins = <
+ MX6SL_PAD_KEY_ROW0__KEY_ROW0 0x1b010
+ MX6SL_PAD_KEY_ROW1__KEY_ROW1 0x1b010
+ MX6SL_PAD_KEY_ROW2__KEY_ROW2 0x1b0b0
+ MX6SL_PAD_KEY_COL0__KEY_COL0 0x110b0
+ MX6SL_PAD_KEY_COL1__KEY_COL1 0x110b0
+ MX6SL_PAD_KEY_COL2__KEY_COL2 0x110b0
+ >;
+ };
+
+ pinctrl_lcd: lcdgrp {
+ fsl,pins = <
+ MX6SL_PAD_LCD_DAT0__LCD_DATA00 0x1b0b0
+ MX6SL_PAD_LCD_DAT1__LCD_DATA01 0x1b0b0
+ MX6SL_PAD_LCD_DAT2__LCD_DATA02 0x1b0b0
+ MX6SL_PAD_LCD_DAT3__LCD_DATA03 0x1b0b0
+ MX6SL_PAD_LCD_DAT4__LCD_DATA04 0x1b0b0
+ MX6SL_PAD_LCD_DAT5__LCD_DATA05 0x1b0b0
+ MX6SL_PAD_LCD_DAT6__LCD_DATA06 0x1b0b0
+ MX6SL_PAD_LCD_DAT7__LCD_DATA07 0x1b0b0
+ MX6SL_PAD_LCD_DAT8__LCD_DATA08 0x1b0b0
+ MX6SL_PAD_LCD_DAT9__LCD_DATA09 0x1b0b0
+ MX6SL_PAD_LCD_DAT10__LCD_DATA10 0x1b0b0
+ MX6SL_PAD_LCD_DAT11__LCD_DATA11 0x1b0b0
+ MX6SL_PAD_LCD_DAT12__LCD_DATA12 0x1b0b0
+ MX6SL_PAD_LCD_DAT13__LCD_DATA13 0x1b0b0
+ MX6SL_PAD_LCD_DAT14__LCD_DATA14 0x1b0b0
+ MX6SL_PAD_LCD_DAT15__LCD_DATA15 0x1b0b0
+ MX6SL_PAD_LCD_DAT16__LCD_DATA16 0x1b0b0
+ MX6SL_PAD_LCD_DAT17__LCD_DATA17 0x1b0b0
+ MX6SL_PAD_LCD_DAT18__LCD_DATA18 0x1b0b0
+ MX6SL_PAD_LCD_DAT19__LCD_DATA19 0x1b0b0
+ MX6SL_PAD_LCD_DAT20__LCD_DATA20 0x1b0b0
+ MX6SL_PAD_LCD_DAT21__LCD_DATA21 0x1b0b0
+ MX6SL_PAD_LCD_DAT22__LCD_DATA22 0x1b0b0
+ MX6SL_PAD_LCD_DAT23__LCD_DATA23 0x1b0b0
+ MX6SL_PAD_LCD_CLK__LCD_CLK 0x1b0b0
+ MX6SL_PAD_LCD_ENABLE__LCD_ENABLE 0x1b0b0
+ MX6SL_PAD_LCD_HSYNC__LCD_HSYNC 0x1b0b0
+ MX6SL_PAD_LCD_VSYNC__LCD_VSYNC 0x1b0b0
+ >;
+ };
+
+ pinctrl_led: ledgrp {
+ fsl,pins = <
+ MX6SL_PAD_HSIC_STROBE__GPIO3_IO20 0x17059
+ >;
+ };
+
+ pinctrl_pwm1: pwmgrp {
+ fsl,pins = <
+ MX6SL_PAD_PWM1__PWM1_OUT 0x110b0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6SL_PAD_UART1_RXD__UART1_RX_DATA 0x1b0b1
+ MX6SL_PAD_UART1_TXD__UART1_TX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg1: usbotg1grp {
+ fsl,pins = <
+ MX6SL_PAD_EPDC_PWRCOM__USB_OTG1_ID 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6SL_PAD_SD1_CMD__SD1_CMD 0x17059
+ MX6SL_PAD_SD1_CLK__SD1_CLK 0x10059
+ MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x17059
+ MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x17059
+ MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x17059
+ MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x17059
+ MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x17059
+ MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x17059
+ MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x17059
+ MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ MX6SL_PAD_SD1_CMD__SD1_CMD 0x170b9
+ MX6SL_PAD_SD1_CLK__SD1_CLK 0x100b9
+ MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170b9
+ MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170b9
+ MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170b9
+ MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170b9
+ MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170b9
+ MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170b9
+ MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170b9
+ MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ MX6SL_PAD_SD1_CMD__SD1_CMD 0x170f9
+ MX6SL_PAD_SD1_CLK__SD1_CLK 0x100f9
+ MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170f9
+ MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170f9
+ MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170f9
+ MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170f9
+ MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170f9
+ MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170f9
+ MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170f9
+ MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6SL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6SL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ MX6SL_PAD_SD2_CMD__SD2_CMD 0x170b9
+ MX6SL_PAD_SD2_CLK__SD2_CLK 0x100b9
+ MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170b9
+ MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170b9
+ MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170b9
+ MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ MX6SL_PAD_SD2_CMD__SD2_CMD 0x170f9
+ MX6SL_PAD_SD2_CLK__SD2_CLK 0x100f9
+ MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170f9
+ MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170f9
+ MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170f9
+ MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6SL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6SL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+ fsl,pins = <
+ MX6SL_PAD_SD3_CMD__SD3_CMD 0x170b9
+ MX6SL_PAD_SD3_CLK__SD3_CLK 0x100b9
+ MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
+ MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
+ MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
+ MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+ fsl,pins = <
+ MX6SL_PAD_SD3_CMD__SD3_CMD 0x170f9
+ MX6SL_PAD_SD3_CLK__SD3_CLK 0x100f9
+ MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
+ MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
+ MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
+ MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
+ >;
+ };
+ };
+};
+
+&kpp {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_kpp>;
+ linux,keymap = <
+ MATRIX_KEY(0x0, 0x0, KEY_UP) /* ROW0, COL0 */
+ MATRIX_KEY(0x0, 0x1, KEY_DOWN) /* ROW0, COL1 */
+ MATRIX_KEY(0x0, 0x2, KEY_ENTER) /* ROW0, COL2 */
+ MATRIX_KEY(0x1, 0x0, KEY_HOME) /* ROW1, COL0 */
+ MATRIX_KEY(0x1, 0x1, KEY_RIGHT) /* ROW1, COL1 */
+ MATRIX_KEY(0x1, 0x2, KEY_LEFT) /* ROW1, COL2 */
+ MATRIX_KEY(0x2, 0x0, KEY_VOLUMEDOWN) /* ROW2, COL0 */
+ MATRIX_KEY(0x2, 0x1, KEY_VOLUMEUP) /* ROW2, COL1 */
+ >;
+ status = "okay";
+};
+
+&lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcd>;
+ lcd-supply = <&reg_lcd_3v3>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display0 {
+ bits-per-pixel = <32>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <33500000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <89>;
+ hfront-porch = <164>;
+ vback-porch = <23>;
+ vfront-porch = <10>;
+ hsync-len = <10>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&snvs_poweroff {
+ status = "okay";
+};
+
+&ssi2 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usb_otg2_vbus>;
+ dr_mode = "host";
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ cd-gpios = <&gpio4 7 0>;
+ wp-gpios = <&gpio4 6 0>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
+ cd-gpios = <&gpio5 0 0>;
+ wp-gpios = <&gpio4 29 0>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ cd-gpios = <&gpio3 22 0>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6sl-pinfunc.h b/arch/arm/boot/dts/imx6sl-pinfunc.h
new file mode 100644
index 000000000..77b17bcc7
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sl-pinfunc.h
@@ -0,0 +1,1077 @@
+/*
+ * Copyright 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX6SL_PINFUNC_H
+#define __DTS_IMX6SL_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX6SL_PAD_AUD_MCLK__AUDIO_CLK_OUT 0x04c 0x2a4 0x000 0x0 0x0
+#define MX6SL_PAD_AUD_MCLK__PWM4_OUT 0x04c 0x2a4 0x000 0x1 0x0
+#define MX6SL_PAD_AUD_MCLK__ECSPI3_RDY 0x04c 0x2a4 0x6b4 0x2 0x0
+#define MX6SL_PAD_AUD_MCLK__FEC_MDC 0x04c 0x2a4 0x000 0x3 0x0
+#define MX6SL_PAD_AUD_MCLK__WDOG2_RESET_B_DEB 0x04c 0x2a4 0x000 0x4 0x0
+#define MX6SL_PAD_AUD_MCLK__GPIO1_IO06 0x04c 0x2a4 0x000 0x5 0x0
+#define MX6SL_PAD_AUD_MCLK__SPDIF_EXT_CLK 0x04c 0x2a4 0x7f4 0x6 0x0
+#define MX6SL_PAD_AUD_RXC__AUD3_RXC 0x050 0x2a8 0x000 0x0 0x0
+#define MX6SL_PAD_AUD_RXC__I2C1_SDA 0x050 0x2a8 0x720 0x1 0x0
+#define MX6SL_PAD_AUD_RXC__UART3_TX_DATA 0x050 0x2a8 0x000 0x2 0x0
+#define MX6SL_PAD_AUD_RXC__UART3_RX_DATA 0x050 0x2a8 0x80c 0x2 0x0
+#define MX6SL_PAD_AUD_RXC__FEC_TX_CLK 0x050 0x2a8 0x70c 0x3 0x0
+#define MX6SL_PAD_AUD_RXC__I2C3_SDA 0x050 0x2a8 0x730 0x4 0x0
+#define MX6SL_PAD_AUD_RXC__GPIO1_IO01 0x050 0x2a8 0x000 0x5 0x0
+#define MX6SL_PAD_AUD_RXC__ECSPI3_SS1 0x050 0x2a8 0x6c4 0x6 0x0
+#define MX6SL_PAD_AUD_RXD__AUD3_RXD 0x054 0x2ac 0x000 0x0 0x0
+#define MX6SL_PAD_AUD_RXD__ECSPI3_MOSI 0x054 0x2ac 0x6bc 0x1 0x0
+#define MX6SL_PAD_AUD_RXD__UART4_RX_DATA 0x054 0x2ac 0x814 0x2 0x0
+#define MX6SL_PAD_AUD_RXD__UART4_TX_DATA 0x054 0x2ac 0x000 0x2 0x0
+#define MX6SL_PAD_AUD_RXD__FEC_RX_ER 0x054 0x2ac 0x708 0x3 0x0
+#define MX6SL_PAD_AUD_RXD__SD1_LCTL 0x054 0x2ac 0x000 0x4 0x0
+#define MX6SL_PAD_AUD_RXD__GPIO1_IO02 0x054 0x2ac 0x000 0x5 0x0
+#define MX6SL_PAD_AUD_RXFS__AUD3_RXFS 0x058 0x2b0 0x000 0x0 0x0
+#define MX6SL_PAD_AUD_RXFS__I2C1_SCL 0x058 0x2b0 0x71c 0x1 0x0
+#define MX6SL_PAD_AUD_RXFS__UART3_RX_DATA 0x058 0x2b0 0x80c 0x2 0x1
+#define MX6SL_PAD_AUD_RXFS__UART3_TX_DATA 0x058 0x2b0 0x000 0x2 0x0
+#define MX6SL_PAD_AUD_RXFS__FEC_MDIO 0x058 0x2b0 0x6f4 0x3 0x0
+#define MX6SL_PAD_AUD_RXFS__I2C3_SCL 0x058 0x2b0 0x72c 0x4 0x0
+#define MX6SL_PAD_AUD_RXFS__GPIO1_IO00 0x058 0x2b0 0x000 0x5 0x0
+#define MX6SL_PAD_AUD_RXFS__ECSPI3_SS0 0x058 0x2b0 0x6c0 0x6 0x0
+#define MX6SL_PAD_AUD_TXC__AUD3_TXC 0x05c 0x2b4 0x000 0x0 0x0
+#define MX6SL_PAD_AUD_TXC__ECSPI3_MISO 0x05c 0x2b4 0x6b8 0x1 0x0
+#define MX6SL_PAD_AUD_TXC__UART4_TX_DATA 0x05c 0x2b4 0x000 0x2 0x0
+#define MX6SL_PAD_AUD_TXC__UART4_RX_DATA 0x05c 0x2b4 0x814 0x2 0x1
+#define MX6SL_PAD_AUD_TXC__FEC_RX_DV 0x05c 0x2b4 0x704 0x3 0x0
+#define MX6SL_PAD_AUD_TXC__SD2_LCTL 0x05c 0x2b4 0x000 0x4 0x0
+#define MX6SL_PAD_AUD_TXC__GPIO1_IO03 0x05c 0x2b4 0x000 0x5 0x0
+#define MX6SL_PAD_AUD_TXD__AUD3_TXD 0x060 0x2b8 0x000 0x0 0x0
+#define MX6SL_PAD_AUD_TXD__ECSPI3_SCLK 0x060 0x2b8 0x6b0 0x1 0x0
+#define MX6SL_PAD_AUD_TXD__UART4_CTS_B 0x060 0x2b8 0x000 0x2 0x0
+#define MX6SL_PAD_AUD_TXD__UART4_RTS_B 0x060 0x2b8 0x810 0x2 0x0
+#define MX6SL_PAD_AUD_TXD__FEC_TX_DATA0 0x060 0x2b8 0x000 0x3 0x0
+#define MX6SL_PAD_AUD_TXD__SD4_LCTL 0x060 0x2b8 0x000 0x4 0x0
+#define MX6SL_PAD_AUD_TXD__GPIO1_IO05 0x060 0x2b8 0x000 0x5 0x0
+#define MX6SL_PAD_AUD_TXFS__AUD3_TXFS 0x064 0x2bc 0x000 0x0 0x0
+#define MX6SL_PAD_AUD_TXFS__PWM3_OUT 0x064 0x2bc 0x000 0x1 0x0
+#define MX6SL_PAD_AUD_TXFS__UART4_RTS_B 0x064 0x2bc 0x810 0x2 0x1
+#define MX6SL_PAD_AUD_TXFS__UART4_CTS_B 0x064 0x2bc 0x000 0x2 0x0
+#define MX6SL_PAD_AUD_TXFS__FEC_RX_DATA1 0x064 0x2bc 0x6fc 0x3 0x0
+#define MX6SL_PAD_AUD_TXFS__SD3_LCTL 0x064 0x2bc 0x000 0x4 0x0
+#define MX6SL_PAD_AUD_TXFS__GPIO1_IO04 0x064 0x2bc 0x000 0x5 0x0
+#define MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x068 0x358 0x684 0x0 0x0
+#define MX6SL_PAD_ECSPI1_MISO__AUD4_TXFS 0x068 0x358 0x5f8 0x1 0x0
+#define MX6SL_PAD_ECSPI1_MISO__UART5_RTS_B 0x068 0x358 0x818 0x2 0x0
+#define MX6SL_PAD_ECSPI1_MISO__UART5_CTS_B 0x068 0x358 0x000 0x2 0x0
+#define MX6SL_PAD_ECSPI1_MISO__EPDC_BDR0 0x068 0x358 0x000 0x3 0x0
+#define MX6SL_PAD_ECSPI1_MISO__SD2_WP 0x068 0x358 0x834 0x4 0x0
+#define MX6SL_PAD_ECSPI1_MISO__GPIO4_IO10 0x068 0x358 0x000 0x5 0x0
+#define MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x06c 0x35c 0x688 0x0 0x0
+#define MX6SL_PAD_ECSPI1_MOSI__AUD4_TXC 0x06c 0x35c 0x5f4 0x1 0x0
+#define MX6SL_PAD_ECSPI1_MOSI__UART5_TX_DATA 0x06c 0x35c 0x000 0x2 0x0
+#define MX6SL_PAD_ECSPI1_MOSI__UART5_RX_DATA 0x06c 0x35c 0x81c 0x2 0x0
+#define MX6SL_PAD_ECSPI1_MOSI__EPDC_VCOM1 0x06c 0x35c 0x000 0x3 0x0
+#define MX6SL_PAD_ECSPI1_MOSI__SD2_VSELECT 0x06c 0x35c 0x000 0x4 0x0
+#define MX6SL_PAD_ECSPI1_MOSI__GPIO4_IO09 0x06c 0x35c 0x000 0x5 0x0
+#define MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x070 0x360 0x67c 0x0 0x0
+#define MX6SL_PAD_ECSPI1_SCLK__AUD4_TXD 0x070 0x360 0x5e8 0x1 0x0
+#define MX6SL_PAD_ECSPI1_SCLK__UART5_RX_DATA 0x070 0x360 0x81c 0x2 0x1
+#define MX6SL_PAD_ECSPI1_SCLK__UART5_TX_DATA 0x070 0x360 0x000 0x2 0x0
+#define MX6SL_PAD_ECSPI1_SCLK__EPDC_VCOM0 0x070 0x360 0x000 0x3 0x0
+#define MX6SL_PAD_ECSPI1_SCLK__SD2_RESET 0x070 0x360 0x000 0x4 0x0
+#define MX6SL_PAD_ECSPI1_SCLK__GPIO4_IO08 0x070 0x360 0x000 0x5 0x0
+#define MX6SL_PAD_ECSPI1_SCLK__USB_OTG2_OC 0x070 0x360 0x820 0x6 0x0
+#define MX6SL_PAD_ECSPI1_SS0__ECSPI1_SS0 0x074 0x364 0x68c 0x0 0x0
+#define MX6SL_PAD_ECSPI1_SS0__AUD4_RXD 0x074 0x364 0x5e4 0x1 0x0
+#define MX6SL_PAD_ECSPI1_SS0__UART5_CTS_B 0x074 0x364 0x000 0x2 0x0
+#define MX6SL_PAD_ECSPI1_SS0__UART5_RTS_B 0x074 0x364 0x818 0x2 0x1
+#define MX6SL_PAD_ECSPI1_SS0__EPDC_BDR1 0x074 0x364 0x000 0x3 0x0
+#define MX6SL_PAD_ECSPI1_SS0__SD2_CD_B 0x074 0x364 0x830 0x4 0x0
+#define MX6SL_PAD_ECSPI1_SS0__GPIO4_IO11 0x074 0x364 0x000 0x5 0x0
+#define MX6SL_PAD_ECSPI1_SS0__USB_OTG2_PWR 0x074 0x364 0x000 0x6 0x0
+#define MX6SL_PAD_ECSPI2_MISO__ECSPI2_MISO 0x078 0x368 0x6a0 0x0 0x0
+#define MX6SL_PAD_ECSPI2_MISO__SDMA_EXT_EVENT0 0x078 0x368 0x000 0x1 0x0
+#define MX6SL_PAD_ECSPI2_MISO__UART3_RTS_B 0x078 0x368 0x808 0x2 0x0
+#define MX6SL_PAD_ECSPI2_MISO__UART3_CTS_B 0x078 0x368 0x000 0x2 0x0
+#define MX6SL_PAD_ECSPI2_MISO__CSI_MCLK 0x078 0x368 0x000 0x3 0x0
+#define MX6SL_PAD_ECSPI2_MISO__SD1_WP 0x078 0x368 0x82c 0x4 0x0
+#define MX6SL_PAD_ECSPI2_MISO__GPIO4_IO14 0x078 0x368 0x000 0x5 0x0
+#define MX6SL_PAD_ECSPI2_MISO__USB_OTG1_OC 0x078 0x368 0x824 0x6 0x0
+#define MX6SL_PAD_ECSPI2_MOSI__ECSPI2_MOSI 0x07c 0x36c 0x6a4 0x0 0x0
+#define MX6SL_PAD_ECSPI2_MOSI__SDMA_EXT_EVENT1 0x07c 0x36c 0x000 0x1 0x0
+#define MX6SL_PAD_ECSPI2_MOSI__UART3_TX_DATA 0x07c 0x36c 0x000 0x2 0x0
+#define MX6SL_PAD_ECSPI2_MOSI__UART3_RX_DATA 0x07c 0x36c 0x80c 0x2 0x2
+#define MX6SL_PAD_ECSPI2_MOSI__CSI_HSYNC 0x07c 0x36c 0x670 0x3 0x0
+#define MX6SL_PAD_ECSPI2_MOSI__SD1_VSELECT 0x07c 0x36c 0x000 0x4 0x0
+#define MX6SL_PAD_ECSPI2_MOSI__GPIO4_IO13 0x07c 0x36c 0x000 0x5 0x0
+#define MX6SL_PAD_ECSPI2_SCLK__ECSPI2_SCLK 0x080 0x370 0x69c 0x0 0x0
+#define MX6SL_PAD_ECSPI2_SCLK__SPDIF_EXT_CLK 0x080 0x370 0x7f4 0x1 0x1
+#define MX6SL_PAD_ECSPI2_SCLK__UART3_RX_DATA 0x080 0x370 0x80c 0x2 0x3
+#define MX6SL_PAD_ECSPI2_SCLK__UART3_TX_DATA 0x080 0x370 0x000 0x2 0x0
+#define MX6SL_PAD_ECSPI2_SCLK__CSI_PIXCLK 0x080 0x370 0x674 0x3 0x0
+#define MX6SL_PAD_ECSPI2_SCLK__SD1_RESET 0x080 0x370 0x000 0x4 0x0
+#define MX6SL_PAD_ECSPI2_SCLK__GPIO4_IO12 0x080 0x370 0x000 0x5 0x0
+#define MX6SL_PAD_ECSPI2_SCLK__USB_OTG2_OC 0x080 0x370 0x820 0x6 0x1
+#define MX6SL_PAD_ECSPI2_SS0__ECSPI2_SS0 0x084 0x374 0x6a8 0x0 0x0
+#define MX6SL_PAD_ECSPI2_SS0__ECSPI1_SS3 0x084 0x374 0x698 0x1 0x0
+#define MX6SL_PAD_ECSPI2_SS0__UART3_CTS_B 0x084 0x374 0x000 0x2 0x0
+#define MX6SL_PAD_ECSPI2_SS0__UART3_RTS_B 0x084 0x374 0x808 0x2 0x1
+#define MX6SL_PAD_ECSPI2_SS0__CSI_VSYNC 0x084 0x374 0x678 0x3 0x0
+#define MX6SL_PAD_ECSPI2_SS0__SD1_CD_B 0x084 0x374 0x828 0x4 0x0
+#define MX6SL_PAD_ECSPI2_SS0__GPIO4_IO15 0x084 0x374 0x000 0x5 0x0
+#define MX6SL_PAD_ECSPI2_SS0__USB_OTG1_PWR 0x084 0x374 0x000 0x6 0x0
+#define MX6SL_PAD_EPDC_BDR0__EPDC_BDR0 0x088 0x378 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_BDR0__SD4_CLK 0x088 0x378 0x850 0x1 0x0
+#define MX6SL_PAD_EPDC_BDR0__UART3_RTS_B 0x088 0x378 0x808 0x2 0x2
+#define MX6SL_PAD_EPDC_BDR0__UART3_CTS_B 0x088 0x378 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_BDR0__EIM_ADDR26 0x088 0x378 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_BDR0__SPDC_RL 0x088 0x378 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_BDR0__GPIO2_IO05 0x088 0x378 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_BDR0__EPDC_SDCE7 0x088 0x378 0x000 0x6 0x0
+#define MX6SL_PAD_EPDC_BDR1__EPDC_BDR1 0x08c 0x37c 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_BDR1__SD4_CMD 0x08c 0x37c 0x858 0x1 0x0
+#define MX6SL_PAD_EPDC_BDR1__UART3_CTS_B 0x08c 0x37c 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_BDR1__UART3_RTS_B 0x08c 0x37c 0x808 0x2 0x3
+#define MX6SL_PAD_EPDC_BDR1__EIM_CRE 0x08c 0x37c 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_BDR1__SPDC_UD 0x08c 0x37c 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_BDR1__GPIO2_IO06 0x08c 0x37c 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_BDR1__EPDC_SDCE8 0x08c 0x37c 0x000 0x6 0x0
+#define MX6SL_PAD_EPDC_D0__EPDC_DATA00 0x090 0x380 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_D0__ECSPI4_MOSI 0x090 0x380 0x6d8 0x1 0x0
+#define MX6SL_PAD_EPDC_D0__LCD_DATA24 0x090 0x380 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_D0__CSI_DATA00 0x090 0x380 0x630 0x3 0x0
+#define MX6SL_PAD_EPDC_D0__SPDC_DATA00 0x090 0x380 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_D0__GPIO1_IO07 0x090 0x380 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_D1__EPDC_DATA01 0x094 0x384 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_D1__ECSPI4_MISO 0x094 0x384 0x6d4 0x1 0x0
+#define MX6SL_PAD_EPDC_D1__LCD_DATA25 0x094 0x384 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_D1__CSI_DATA01 0x094 0x384 0x634 0x3 0x0
+#define MX6SL_PAD_EPDC_D1__SPDC_DATA01 0x094 0x384 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_D1__GPIO1_IO08 0x094 0x384 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_D10__EPDC_DATA10 0x098 0x388 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_D10__ECSPI3_SS0 0x098 0x388 0x6c0 0x1 0x1
+#define MX6SL_PAD_EPDC_D10__EPDC_PWR_CTRL2 0x098 0x388 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_D10__EIM_ADDR18 0x098 0x388 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_D10__SPDC_DATA10 0x098 0x388 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_D10__GPIO1_IO17 0x098 0x388 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_D10__SD4_WP 0x098 0x388 0x87c 0x6 0x0
+#define MX6SL_PAD_EPDC_D11__EPDC_DATA11 0x09c 0x38c 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_D11__ECSPI3_SCLK 0x09c 0x38c 0x6b0 0x1 0x1
+#define MX6SL_PAD_EPDC_D11__EPDC_PWR_CTRL3 0x09c 0x38c 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_D11__EIM_ADDR19 0x09c 0x38c 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_D11__SPDC_DATA11 0x09c 0x38c 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_D11__GPIO1_IO18 0x09c 0x38c 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_D11__SD4_CD_B 0x09c 0x38c 0x854 0x6 0x0
+#define MX6SL_PAD_EPDC_D12__EPDC_DATA12 0x0a0 0x390 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_D12__UART2_RX_DATA 0x0a0 0x390 0x804 0x1 0x0
+#define MX6SL_PAD_EPDC_D12__UART2_TX_DATA 0x0a0 0x390 0x000 0x1 0x0
+#define MX6SL_PAD_EPDC_D12__EPDC_PWR_COM 0x0a0 0x390 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_D12__EIM_ADDR20 0x0a0 0x390 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_D12__SPDC_DATA12 0x0a0 0x390 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_D12__GPIO1_IO19 0x0a0 0x390 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_D12__ECSPI3_SS1 0x0a0 0x390 0x6c4 0x6 0x1
+#define MX6SL_PAD_EPDC_D13__EPDC_DATA13 0x0a4 0x394 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_D13__UART2_TX_DATA 0x0a4 0x394 0x000 0x1 0x0
+#define MX6SL_PAD_EPDC_D13__UART2_RX_DATA 0x0a4 0x394 0x804 0x1 0x1
+#define MX6SL_PAD_EPDC_D13__EPDC_PWR_IRQ 0x0a4 0x394 0x6e8 0x2 0x0
+#define MX6SL_PAD_EPDC_D13__EIM_ADDR21 0x0a4 0x394 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_D13__SPDC_DATA13 0x0a4 0x394 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_D13__GPIO1_IO20 0x0a4 0x394 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_D13__ECSPI3_SS2 0x0a4 0x394 0x6c8 0x6 0x0
+#define MX6SL_PAD_EPDC_D14__EPDC_DATA14 0x0a8 0x398 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_D14__UART2_RTS_B 0x0a8 0x398 0x800 0x1 0x0
+#define MX6SL_PAD_EPDC_D14__UART2_CTS_B 0x0a8 0x398 0x000 0x1 0x0
+#define MX6SL_PAD_EPDC_D14__EPDC_PWR_STAT 0x0a8 0x398 0x6ec 0x2 0x0
+#define MX6SL_PAD_EPDC_D14__EIM_ADDR22 0x0a8 0x398 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_D14__SPDC_DATA14 0x0a8 0x398 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_D14__GPIO1_IO21 0x0a8 0x398 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_D14__ECSPI3_SS3 0x0a8 0x398 0x6cc 0x6 0x0
+#define MX6SL_PAD_EPDC_D15__EPDC_DATA15 0x0ac 0x39c 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_D15__UART2_CTS_B 0x0ac 0x39c 0x000 0x1 0x0
+#define MX6SL_PAD_EPDC_D15__UART2_RTS_B 0x0ac 0x39c 0x800 0x1 0x1
+#define MX6SL_PAD_EPDC_D15__EPDC_PWR_WAKE 0x0ac 0x39c 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_D15__EIM_ADDR23 0x0ac 0x39c 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_D15__SPDC_DATA15 0x0ac 0x39c 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_D15__GPIO1_IO22 0x0ac 0x39c 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_D15__ECSPI3_RDY 0x0ac 0x39c 0x6b4 0x6 0x1
+#define MX6SL_PAD_EPDC_D2__EPDC_DATA02 0x0b0 0x3a0 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_D2__ECSPI4_SS0 0x0b0 0x3a0 0x6dc 0x1 0x0
+#define MX6SL_PAD_EPDC_D2__LCD_DATA26 0x0b0 0x3a0 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_D2__CSI_DATA02 0x0b0 0x3a0 0x638 0x3 0x0
+#define MX6SL_PAD_EPDC_D2__SPDC_DATA02 0x0b0 0x3a0 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_D2__GPIO1_IO09 0x0b0 0x3a0 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_D3__EPDC_DATA03 0x0b4 0x3a4 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_D3__ECSPI4_SCLK 0x0b4 0x3a4 0x6d0 0x1 0x0
+#define MX6SL_PAD_EPDC_D3__LCD_DATA27 0x0b4 0x3a4 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_D3__CSI_DATA03 0x0b4 0x3a4 0x63c 0x3 0x0
+#define MX6SL_PAD_EPDC_D3__SPDC_DATA03 0x0b4 0x3a4 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_D3__GPIO1_IO10 0x0b4 0x3a4 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_D4__EPDC_DATA04 0x0b8 0x3a8 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_D4__ECSPI4_SS1 0x0b8 0x3a8 0x6e0 0x1 0x0
+#define MX6SL_PAD_EPDC_D4__LCD_DATA28 0x0b8 0x3a8 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_D4__CSI_DATA04 0x0b8 0x3a8 0x640 0x3 0x0
+#define MX6SL_PAD_EPDC_D4__SPDC_DATA04 0x0b8 0x3a8 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_D4__GPIO1_IO11 0x0b8 0x3a8 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_D5__EPDC_DATA05 0x0bc 0x3ac 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_D5__ECSPI4_SS2 0x0bc 0x3ac 0x6e4 0x1 0x0
+#define MX6SL_PAD_EPDC_D5__LCD_DATA29 0x0bc 0x3ac 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_D5__CSI_DATA05 0x0bc 0x3ac 0x644 0x3 0x0
+#define MX6SL_PAD_EPDC_D5__SPDC_DATA05 0x0bc 0x3ac 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_D5__GPIO1_IO12 0x0bc 0x3ac 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_D6__EPDC_DATA06 0x0c0 0x3b0 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_D6__ECSPI4_SS3 0x0c0 0x3b0 0x000 0x1 0x0
+#define MX6SL_PAD_EPDC_D6__LCD_DATA30 0x0c0 0x3b0 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_D6__CSI_DATA06 0x0c0 0x3b0 0x648 0x3 0x0
+#define MX6SL_PAD_EPDC_D6__SPDC_DATA06 0x0c0 0x3b0 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_D6__GPIO1_IO13 0x0c0 0x3b0 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_D7__EPDC_DATA07 0x0c4 0x3b4 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_D7__ECSPI4_RDY 0x0c4 0x3b4 0x000 0x1 0x0
+#define MX6SL_PAD_EPDC_D7__LCD_DATA31 0x0c4 0x3b4 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_D7__CSI_DATA07 0x0c4 0x3b4 0x64c 0x3 0x0
+#define MX6SL_PAD_EPDC_D7__SPDC_DATA07 0x0c4 0x3b4 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_D7__GPIO1_IO14 0x0c4 0x3b4 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_D8__EPDC_DATA08 0x0c8 0x3b8 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_D8__ECSPI3_MOSI 0x0c8 0x3b8 0x6bc 0x1 0x1
+#define MX6SL_PAD_EPDC_D8__EPDC_PWR_CTRL0 0x0c8 0x3b8 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_D8__EIM_ADDR16 0x0c8 0x3b8 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_D8__SPDC_DATA08 0x0c8 0x3b8 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_D8__GPIO1_IO15 0x0c8 0x3b8 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_D8__SD4_RESET 0x0c8 0x3b8 0x000 0x6 0x0
+#define MX6SL_PAD_EPDC_D9__EPDC_DATA09 0x0cc 0x3bc 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_D9__ECSPI3_MISO 0x0cc 0x3bc 0x6b8 0x1 0x1
+#define MX6SL_PAD_EPDC_D9__EPDC_PWR_CTRL1 0x0cc 0x3bc 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_D9__EIM_ADDR17 0x0cc 0x3bc 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_D9__SPDC_DATA09 0x0cc 0x3bc 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_D9__GPIO1_IO16 0x0cc 0x3bc 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_D9__SD4_VSELECT 0x0cc 0x3bc 0x000 0x6 0x0
+#define MX6SL_PAD_EPDC_GDCLK__EPDC_GDCLK 0x0d0 0x3c0 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_GDCLK__ECSPI2_SS2 0x0d0 0x3c0 0x000 0x1 0x0
+#define MX6SL_PAD_EPDC_GDCLK__SPDC_YCKR 0x0d0 0x3c0 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_GDCLK__CSI_PIXCLK 0x0d0 0x3c0 0x674 0x3 0x1
+#define MX6SL_PAD_EPDC_GDCLK__SPDC_YCKL 0x0d0 0x3c0 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_GDCLK__GPIO1_IO31 0x0d0 0x3c0 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_GDCLK__SD2_RESET 0x0d0 0x3c0 0x000 0x6 0x0
+#define MX6SL_PAD_EPDC_GDOE__EPDC_GDOE 0x0d4 0x3c4 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_GDOE__ECSPI2_SS3 0x0d4 0x3c4 0x000 0x1 0x0
+#define MX6SL_PAD_EPDC_GDOE__SPDC_YOER 0x0d4 0x3c4 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_GDOE__CSI_HSYNC 0x0d4 0x3c4 0x670 0x3 0x1
+#define MX6SL_PAD_EPDC_GDOE__SPDC_YOEL 0x0d4 0x3c4 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_GDOE__GPIO2_IO00 0x0d4 0x3c4 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_GDOE__SD2_VSELECT 0x0d4 0x3c4 0x000 0x6 0x0
+#define MX6SL_PAD_EPDC_GDRL__EPDC_GDRL 0x0d8 0x3c8 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_GDRL__ECSPI2_RDY 0x0d8 0x3c8 0x000 0x1 0x0
+#define MX6SL_PAD_EPDC_GDRL__SPDC_YDIOUR 0x0d8 0x3c8 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_GDRL__CSI_MCLK 0x0d8 0x3c8 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_GDRL__SPDC_YDIOUL 0x0d8 0x3c8 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_GDRL__GPIO2_IO01 0x0d8 0x3c8 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_GDRL__SD2_WP 0x0d8 0x3c8 0x834 0x6 0x1
+#define MX6SL_PAD_EPDC_GDSP__EPDC_GDSP 0x0dc 0x3cc 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_GDSP__PWM4_OUT 0x0dc 0x3cc 0x000 0x1 0x0
+#define MX6SL_PAD_EPDC_GDSP__SPDC_YDIODR 0x0dc 0x3cc 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_GDSP__CSI_VSYNC 0x0dc 0x3cc 0x678 0x3 0x1
+#define MX6SL_PAD_EPDC_GDSP__SPDC_YDIODL 0x0dc 0x3cc 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_GDSP__GPIO2_IO02 0x0dc 0x3cc 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_GDSP__SD2_CD_B 0x0dc 0x3cc 0x830 0x6 0x1
+#define MX6SL_PAD_EPDC_PWRCOM__EPDC_PWR_COM 0x0e0 0x3d0 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_PWRCOM__SD4_DATA0 0x0e0 0x3d0 0x85c 0x1 0x0
+#define MX6SL_PAD_EPDC_PWRCOM__LCD_DATA20 0x0e0 0x3d0 0x7c8 0x2 0x0
+#define MX6SL_PAD_EPDC_PWRCOM__EIM_BCLK 0x0e0 0x3d0 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_PWRCOM__USB_OTG1_ID 0x0e0 0x3d0 0x5dc 0x4 0x0
+#define MX6SL_PAD_EPDC_PWRCOM__GPIO2_IO11 0x0e0 0x3d0 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_PWRCOM__SD3_RESET 0x0e0 0x3d0 0x000 0x6 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL0__EPDC_PWR_CTRL0 0x0e4 0x3d4 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL0__AUD5_RXC 0x0e4 0x3d4 0x604 0x1 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL0__LCD_DATA16 0x0e4 0x3d4 0x7b8 0x2 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL0__EIM_RW 0x0e4 0x3d4 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL0__SPDC_YCKL 0x0e4 0x3d4 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL0__GPIO2_IO07 0x0e4 0x3d4 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL0__SD4_RESET 0x0e4 0x3d4 0x000 0x6 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL1__EPDC_PWR_CTRL1 0x0e8 0x3d8 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL1__AUD5_TXFS 0x0e8 0x3d8 0x610 0x1 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL1__LCD_DATA17 0x0e8 0x3d8 0x7bc 0x2 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL1__EIM_OE_B 0x0e8 0x3d8 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL1__SPDC_YOEL 0x0e8 0x3d8 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL1__GPIO2_IO08 0x0e8 0x3d8 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL1__SD4_VSELECT 0x0e8 0x3d8 0x000 0x6 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL2__EPDC_PWR_CTRL2 0x0ec 0x3dc 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL2__AUD5_TXD 0x0ec 0x3dc 0x600 0x1 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL2__LCD_DATA18 0x0ec 0x3dc 0x7c0 0x2 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL2__EIM_CS0_B 0x0ec 0x3dc 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL2__SPDC_YDIOUL 0x0ec 0x3dc 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL2__GPIO2_IO09 0x0ec 0x3dc 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL2__SD4_WP 0x0ec 0x3dc 0x87c 0x6 0x1
+#define MX6SL_PAD_EPDC_PWRCTRL3__EPDC_PWR_CTRL3 0x0f0 0x3e0 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL3__AUD5_TXC 0x0f0 0x3e0 0x60c 0x1 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL3__LCD_DATA19 0x0f0 0x3e0 0x7c4 0x2 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL3__EIM_CS1_B 0x0f0 0x3e0 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL3__SPDC_YDIODL 0x0f0 0x3e0 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL3__GPIO2_IO10 0x0f0 0x3e0 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_PWRCTRL3__SD4_CD_B 0x0f0 0x3e0 0x854 0x6 0x1
+#define MX6SL_PAD_EPDC_PWRINT__EPDC_PWR_IRQ 0x0f4 0x3e4 0x6e8 0x0 0x1
+#define MX6SL_PAD_EPDC_PWRINT__SD4_DATA1 0x0f4 0x3e4 0x860 0x1 0x0
+#define MX6SL_PAD_EPDC_PWRINT__LCD_DATA21 0x0f4 0x3e4 0x7cc 0x2 0x0
+#define MX6SL_PAD_EPDC_PWRINT__EIM_ACLK_FREERUN 0x0f4 0x3e4 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_PWRINT__USB_OTG2_ID 0x0f4 0x3e4 0x5e0 0x4 0x0
+#define MX6SL_PAD_EPDC_PWRINT__GPIO2_IO12 0x0f4 0x3e4 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_PWRINT__SD3_VSELECT 0x0f4 0x3e4 0x000 0x6 0x0
+#define MX6SL_PAD_EPDC_PWRSTAT__EPDC_PWR_STAT 0x0f8 0x3e8 0x6ec 0x0 0x1
+#define MX6SL_PAD_EPDC_PWRSTAT__SD4_DATA2 0x0f8 0x3e8 0x864 0x1 0x0
+#define MX6SL_PAD_EPDC_PWRSTAT__LCD_DATA22 0x0f8 0x3e8 0x7d0 0x2 0x0
+#define MX6SL_PAD_EPDC_PWRSTAT__EIM_WAIT_B 0x0f8 0x3e8 0x884 0x3 0x0
+#define MX6SL_PAD_EPDC_PWRSTAT__ARM_EVENTI 0x0f8 0x3e8 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_PWRSTAT__GPIO2_IO13 0x0f8 0x3e8 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_PWRSTAT__SD3_WP 0x0f8 0x3e8 0x84c 0x6 0x0
+#define MX6SL_PAD_EPDC_PWRWAKEUP__EPDC_PWR_WAKE 0x0fc 0x3ec 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_PWRWAKEUP__SD4_DATA3 0x0fc 0x3ec 0x868 0x1 0x0
+#define MX6SL_PAD_EPDC_PWRWAKEUP__LCD_DATA23 0x0fc 0x3ec 0x7d4 0x2 0x0
+#define MX6SL_PAD_EPDC_PWRWAKEUP__EIM_DTACK_B 0x0fc 0x3ec 0x880 0x3 0x0
+#define MX6SL_PAD_EPDC_PWRWAKEUP__ARM_EVENTO 0x0fc 0x3ec 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_PWRWAKEUP__GPIO2_IO14 0x0fc 0x3ec 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_PWRWAKEUP__SD3_CD_B 0x0fc 0x3ec 0x838 0x6 0x0
+#define MX6SL_PAD_EPDC_SDCE0__EPDC_SDCE0 0x100 0x3f0 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_SDCE0__ECSPI2_SS1 0x100 0x3f0 0x6ac 0x1 0x0
+#define MX6SL_PAD_EPDC_SDCE0__PWM3_OUT 0x100 0x3f0 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_SDCE0__EIM_CS2_B 0x100 0x3f0 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_SDCE0__SPDC_YCKR 0x100 0x3f0 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_SDCE0__GPIO1_IO27 0x100 0x3f0 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_SDCE1__EPDC_SDCE1 0x104 0x3f4 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_SDCE1__WDOG2_B 0x104 0x3f4 0x000 0x1 0x0
+#define MX6SL_PAD_EPDC_SDCE1__PWM4_OUT 0x104 0x3f4 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_SDCE1__EIM_LBA_B 0x104 0x3f4 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_SDCE1__SPDC_YOER 0x104 0x3f4 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_SDCE1__GPIO1_IO28 0x104 0x3f4 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_SDCE2__EPDC_SDCE2 0x108 0x3f8 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_SDCE2__I2C3_SCL 0x108 0x3f8 0x72c 0x1 0x1
+#define MX6SL_PAD_EPDC_SDCE2__PWM1_OUT 0x108 0x3f8 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_SDCE2__EIM_EB0_B 0x108 0x3f8 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_SDCE2__SPDC_YDIOUR 0x108 0x3f8 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_SDCE2__GPIO1_IO29 0x108 0x3f8 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_SDCE3__EPDC_SDCE3 0x10c 0x3fc 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_SDCE3__I2C3_SDA 0x10c 0x3fc 0x730 0x1 0x1
+#define MX6SL_PAD_EPDC_SDCE3__PWM2_OUT 0x10c 0x3fc 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_SDCE3__EIM_EB1_B 0x10c 0x3fc 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_SDCE3__SPDC_YDIODR 0x10c 0x3fc 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_SDCE3__GPIO1_IO30 0x10c 0x3fc 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_SDCLK__EPDC_SDCLK_P 0x110 0x400 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_SDCLK__ECSPI2_MOSI 0x110 0x400 0x6a4 0x1 0x1
+#define MX6SL_PAD_EPDC_SDCLK__I2C2_SCL 0x110 0x400 0x724 0x2 0x0
+#define MX6SL_PAD_EPDC_SDCLK__CSI_DATA08 0x110 0x400 0x650 0x3 0x0
+#define MX6SL_PAD_EPDC_SDCLK__SPDC_CL 0x110 0x400 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_SDCLK__GPIO1_IO23 0x110 0x400 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_SDLE__EPDC_SDLE 0x114 0x404 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_SDLE__ECSPI2_MISO 0x114 0x404 0x6a0 0x1 0x1
+#define MX6SL_PAD_EPDC_SDLE__I2C2_SDA 0x114 0x404 0x728 0x2 0x0
+#define MX6SL_PAD_EPDC_SDLE__CSI_DATA09 0x114 0x404 0x654 0x3 0x0
+#define MX6SL_PAD_EPDC_SDLE__SPDC_LD 0x114 0x404 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_SDLE__GPIO1_IO24 0x114 0x404 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_SDOE__EPDC_SDOE 0x118 0x408 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_SDOE__ECSPI2_SS0 0x118 0x408 0x6a8 0x1 0x1
+#define MX6SL_PAD_EPDC_SDOE__SPDC_XDIOR 0x118 0x408 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_SDOE__CSI_DATA10 0x118 0x408 0x658 0x3 0x0
+#define MX6SL_PAD_EPDC_SDOE__SPDC_XDIOL 0x118 0x408 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_SDOE__GPIO1_IO25 0x118 0x408 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_SDSHR__EPDC_SDSHR 0x11c 0x40c 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_SDSHR__ECSPI2_SCLK 0x11c 0x40c 0x69c 0x1 0x1
+#define MX6SL_PAD_EPDC_SDSHR__EPDC_SDCE4 0x11c 0x40c 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_SDSHR__CSI_DATA11 0x11c 0x40c 0x65c 0x3 0x0
+#define MX6SL_PAD_EPDC_SDSHR__SPDC_XDIOR 0x11c 0x40c 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_SDSHR__GPIO1_IO26 0x11c 0x40c 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_VCOM0__EPDC_VCOM0 0x120 0x410 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_VCOM0__AUD5_RXFS 0x120 0x410 0x608 0x1 0x0
+#define MX6SL_PAD_EPDC_VCOM0__UART3_RX_DATA 0x120 0x410 0x80c 0x2 0x4
+#define MX6SL_PAD_EPDC_VCOM0__UART3_TX_DATA 0x120 0x410 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_VCOM0__EIM_ADDR24 0x120 0x410 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_VCOM0__SPDC_VCOM0 0x120 0x410 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_VCOM0__GPIO2_IO03 0x120 0x410 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_VCOM0__EPDC_SDCE5 0x120 0x410 0x000 0x6 0x0
+#define MX6SL_PAD_EPDC_VCOM1__EPDC_VCOM1 0x124 0x414 0x000 0x0 0x0
+#define MX6SL_PAD_EPDC_VCOM1__AUD5_RXD 0x124 0x414 0x5fc 0x1 0x0
+#define MX6SL_PAD_EPDC_VCOM1__UART3_TX_DATA 0x124 0x414 0x000 0x2 0x0
+#define MX6SL_PAD_EPDC_VCOM1__UART3_RX_DATA 0x124 0x414 0x80c 0x2 0x5
+#define MX6SL_PAD_EPDC_VCOM1__EIM_ADDR25 0x124 0x414 0x000 0x3 0x0
+#define MX6SL_PAD_EPDC_VCOM1__SPDC_VCOM1 0x124 0x414 0x000 0x4 0x0
+#define MX6SL_PAD_EPDC_VCOM1__GPIO2_IO04 0x124 0x414 0x000 0x5 0x0
+#define MX6SL_PAD_EPDC_VCOM1__EPDC_SDCE6 0x124 0x414 0x000 0x6 0x0
+#define MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV 0x128 0x418 0x704 0x0 0x1
+#define MX6SL_PAD_FEC_CRS_DV__SD4_DATA1 0x128 0x418 0x860 0x1 0x1
+#define MX6SL_PAD_FEC_CRS_DV__AUD6_TXC 0x128 0x418 0x624 0x2 0x0
+#define MX6SL_PAD_FEC_CRS_DV__ECSPI4_MISO 0x128 0x418 0x6d4 0x3 0x1
+#define MX6SL_PAD_FEC_CRS_DV__GPT_COMPARE2 0x128 0x418 0x000 0x4 0x0
+#define MX6SL_PAD_FEC_CRS_DV__GPIO4_IO25 0x128 0x418 0x000 0x5 0x0
+#define MX6SL_PAD_FEC_CRS_DV__ARM_TRACE31 0x128 0x418 0x000 0x6 0x0
+#define MX6SL_PAD_FEC_MDC__FEC_MDC 0x12c 0x41c 0x000 0x0 0x0
+#define MX6SL_PAD_FEC_MDC__SD4_DATA4 0x12c 0x41c 0x86c 0x1 0x0
+#define MX6SL_PAD_FEC_MDC__AUDIO_CLK_OUT 0x12c 0x41c 0x000 0x2 0x0
+#define MX6SL_PAD_FEC_MDC__SD1_RESET 0x12c 0x41c 0x000 0x3 0x0
+#define MX6SL_PAD_FEC_MDC__SD3_RESET 0x12c 0x41c 0x000 0x4 0x0
+#define MX6SL_PAD_FEC_MDC__GPIO4_IO23 0x12c 0x41c 0x000 0x5 0x0
+#define MX6SL_PAD_FEC_MDC__ARM_TRACE29 0x12c 0x41c 0x000 0x6 0x0
+#define MX6SL_PAD_FEC_MDIO__FEC_MDIO 0x130 0x420 0x6f4 0x0 0x1
+#define MX6SL_PAD_FEC_MDIO__SD4_CLK 0x130 0x420 0x850 0x1 0x1
+#define MX6SL_PAD_FEC_MDIO__AUD6_RXFS 0x130 0x420 0x620 0x2 0x0
+#define MX6SL_PAD_FEC_MDIO__ECSPI4_SS0 0x130 0x420 0x6dc 0x3 0x1
+#define MX6SL_PAD_FEC_MDIO__GPT_CAPTURE1 0x130 0x420 0x710 0x4 0x0
+#define MX6SL_PAD_FEC_MDIO__GPIO4_IO20 0x130 0x420 0x000 0x5 0x0
+#define MX6SL_PAD_FEC_MDIO__ARM_TRACE26 0x130 0x420 0x000 0x6 0x0
+#define MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT 0x134 0x424 0x000 0x0 0x0
+#define MX6SL_PAD_FEC_REF_CLK__SD4_RESET 0x134 0x424 0x000 0x1 0x0
+#define MX6SL_PAD_FEC_REF_CLK__WDOG1_B 0x134 0x424 0x000 0x2 0x0
+#define MX6SL_PAD_FEC_REF_CLK__PWM4_OUT 0x134 0x424 0x000 0x3 0x0
+#define MX6SL_PAD_FEC_REF_CLK__CCM_PMIC_READY 0x134 0x424 0x62c 0x4 0x0
+#define MX6SL_PAD_FEC_REF_CLK__GPIO4_IO26 0x134 0x424 0x000 0x5 0x0
+#define MX6SL_PAD_FEC_REF_CLK__SPDIF_EXT_CLK 0x134 0x424 0x7f4 0x6 0x2
+#define MX6SL_PAD_FEC_RX_ER__FEC_RX_ER 0x138 0x428 0x708 0x0 0x1
+#define MX6SL_PAD_FEC_RX_ER__SD4_DATA0 0x138 0x428 0x85c 0x1 0x1
+#define MX6SL_PAD_FEC_RX_ER__AUD6_RXD 0x138 0x428 0x614 0x2 0x0
+#define MX6SL_PAD_FEC_RX_ER__ECSPI4_MOSI 0x138 0x428 0x6d8 0x3 0x1
+#define MX6SL_PAD_FEC_RX_ER__GPT_COMPARE1 0x138 0x428 0x000 0x4 0x0
+#define MX6SL_PAD_FEC_RX_ER__GPIO4_IO19 0x138 0x428 0x000 0x5 0x0
+#define MX6SL_PAD_FEC_RX_ER__ARM_TRACE25 0x138 0x428 0x000 0x6 0x0
+#define MX6SL_PAD_FEC_RXD0__FEC_RX_DATA0 0x13c 0x42c 0x6f8 0x0 0x0
+#define MX6SL_PAD_FEC_RXD0__SD4_DATA5 0x13c 0x42c 0x870 0x1 0x0
+#define MX6SL_PAD_FEC_RXD0__USB_OTG1_ID 0x13c 0x42c 0x5dc 0x2 0x1
+#define MX6SL_PAD_FEC_RXD0__SD1_VSELECT 0x13c 0x42c 0x000 0x3 0x0
+#define MX6SL_PAD_FEC_RXD0__SD3_VSELECT 0x13c 0x42c 0x000 0x4 0x0
+#define MX6SL_PAD_FEC_RXD0__GPIO4_IO17 0x13c 0x42c 0x000 0x5 0x0
+#define MX6SL_PAD_FEC_RXD0__ARM_TRACE24 0x13c 0x42c 0x000 0x6 0x0
+#define MX6SL_PAD_FEC_RXD1__FEC_RX_DATA1 0x140 0x430 0x6fc 0x0 0x1
+#define MX6SL_PAD_FEC_RXD1__SD4_DATA2 0x140 0x430 0x864 0x1 0x1
+#define MX6SL_PAD_FEC_RXD1__AUD6_TXFS 0x140 0x430 0x628 0x2 0x0
+#define MX6SL_PAD_FEC_RXD1__ECSPI4_SS1 0x140 0x430 0x6e0 0x3 0x1
+#define MX6SL_PAD_FEC_RXD1__GPT_COMPARE3 0x140 0x430 0x000 0x4 0x0
+#define MX6SL_PAD_FEC_RXD1__GPIO4_IO18 0x140 0x430 0x000 0x5 0x0
+#define MX6SL_PAD_FEC_RXD1__FEC_COL 0x140 0x430 0x6f0 0x6 0x0
+#define MX6SL_PAD_FEC_TX_CLK__FEC_TX_CLK 0x144 0x434 0x70c 0x0 0x1
+#define MX6SL_PAD_FEC_TX_CLK__SD4_CMD 0x144 0x434 0x858 0x1 0x1
+#define MX6SL_PAD_FEC_TX_CLK__AUD6_RXC 0x144 0x434 0x61c 0x2 0x0
+#define MX6SL_PAD_FEC_TX_CLK__ECSPI4_SCLK 0x144 0x434 0x6d0 0x3 0x1
+#define MX6SL_PAD_FEC_TX_CLK__GPT_CAPTURE2 0x144 0x434 0x714 0x4 0x0
+#define MX6SL_PAD_FEC_TX_CLK__GPIO4_IO21 0x144 0x434 0x000 0x5 0x0
+#define MX6SL_PAD_FEC_TX_CLK__ARM_TRACE27 0x144 0x434 0x000 0x6 0x0
+#define MX6SL_PAD_FEC_TX_EN__FEC_TX_EN 0x148 0x438 0x000 0x0 0x0
+#define MX6SL_PAD_FEC_TX_EN__SD4_DATA6 0x148 0x438 0x874 0x1 0x0
+#define MX6SL_PAD_FEC_TX_EN__SPDIF_IN 0x148 0x438 0x7f0 0x2 0x0
+#define MX6SL_PAD_FEC_TX_EN__SD1_WP 0x148 0x438 0x82c 0x3 0x1
+#define MX6SL_PAD_FEC_TX_EN__SD3_WP 0x148 0x438 0x84c 0x4 0x1
+#define MX6SL_PAD_FEC_TX_EN__GPIO4_IO22 0x148 0x438 0x000 0x5 0x0
+#define MX6SL_PAD_FEC_TX_EN__ARM_TRACE28 0x148 0x438 0x000 0x6 0x0
+#define MX6SL_PAD_FEC_TXD0__FEC_TX_DATA0 0x14c 0x43c 0x000 0x0 0x0
+#define MX6SL_PAD_FEC_TXD0__SD4_DATA3 0x14c 0x43c 0x868 0x1 0x1
+#define MX6SL_PAD_FEC_TXD0__AUD6_TXD 0x14c 0x43c 0x618 0x2 0x0
+#define MX6SL_PAD_FEC_TXD0__ECSPI4_SS2 0x14c 0x43c 0x6e4 0x3 0x1
+#define MX6SL_PAD_FEC_TXD0__GPT_CLKIN 0x14c 0x43c 0x718 0x4 0x0
+#define MX6SL_PAD_FEC_TXD0__GPIO4_IO24 0x14c 0x43c 0x000 0x5 0x0
+#define MX6SL_PAD_FEC_TXD0__ARM_TRACE30 0x14c 0x43c 0x000 0x6 0x0
+#define MX6SL_PAD_FEC_TXD1__FEC_TX_DATA1 0x150 0x440 0x000 0x0 0x0
+#define MX6SL_PAD_FEC_TXD1__SD4_DATA7 0x150 0x440 0x878 0x1 0x0
+#define MX6SL_PAD_FEC_TXD1__SPDIF_OUT 0x150 0x440 0x000 0x2 0x0
+#define MX6SL_PAD_FEC_TXD1__SD1_CD_B 0x150 0x440 0x828 0x3 0x1
+#define MX6SL_PAD_FEC_TXD1__SD3_CD_B 0x150 0x440 0x838 0x4 0x1
+#define MX6SL_PAD_FEC_TXD1__GPIO4_IO16 0x150 0x440 0x000 0x5 0x0
+#define MX6SL_PAD_FEC_TXD1__FEC_RX_CLK 0x150 0x440 0x700 0x6 0x0
+#define MX6SL_PAD_HSIC_DAT__USB_H_DATA 0x154 0x444 0x000 0x0 0x0
+#define MX6SL_PAD_HSIC_DAT__I2C1_SCL 0x154 0x444 0x71c 0x1 0x1
+#define MX6SL_PAD_HSIC_DAT__PWM1_OUT 0x154 0x444 0x000 0x2 0x0
+#define MX6SL_PAD_HSIC_DAT__XTALOSC_REF_CLK_24M 0x154 0x444 0x000 0x3 0x0
+#define MX6SL_PAD_HSIC_DAT__GPIO3_IO19 0x154 0x444 0x000 0x5 0x0
+#define MX6SL_PAD_HSIC_STROBE__USB_H_STROBE 0x158 0x448 0x000 0x0 0x0
+#define MX6SL_PAD_HSIC_STROBE__I2C1_SDA 0x158 0x448 0x720 0x1 0x1
+#define MX6SL_PAD_HSIC_STROBE__PWM2_OUT 0x158 0x448 0x000 0x2 0x0
+#define MX6SL_PAD_HSIC_STROBE__XTALOSC_REF_CLK_32K 0x158 0x448 0x000 0x3 0x0
+#define MX6SL_PAD_HSIC_STROBE__GPIO3_IO20 0x158 0x448 0x000 0x5 0x0
+#define MX6SL_PAD_I2C1_SCL__I2C1_SCL 0x15c 0x44c 0x71c 0x0 0x2
+#define MX6SL_PAD_I2C1_SCL__UART1_RTS_B 0x15c 0x44c 0x7f8 0x1 0x0
+#define MX6SL_PAD_I2C1_SCL__UART1_CTS_B 0x15c 0x44c 0x000 0x1 0x0
+#define MX6SL_PAD_I2C1_SCL__ECSPI3_SS2 0x15c 0x44c 0x6c8 0x2 0x1
+#define MX6SL_PAD_I2C1_SCL__FEC_RX_DATA0 0x15c 0x44c 0x6f8 0x3 0x1
+#define MX6SL_PAD_I2C1_SCL__SD3_RESET 0x15c 0x44c 0x000 0x4 0x0
+#define MX6SL_PAD_I2C1_SCL__GPIO3_IO12 0x15c 0x44c 0x000 0x5 0x0
+#define MX6SL_PAD_I2C1_SCL__ECSPI1_SS1 0x15c 0x44c 0x690 0x6 0x0
+#define MX6SL_PAD_I2C1_SDA__I2C1_SDA 0x160 0x450 0x720 0x0 0x2
+#define MX6SL_PAD_I2C1_SDA__UART1_CTS_B 0x160 0x450 0x000 0x1 0x0
+#define MX6SL_PAD_I2C1_SDA__UART1_RTS_B 0x160 0x450 0x7f8 0x1 0x1
+#define MX6SL_PAD_I2C1_SDA__ECSPI3_SS3 0x160 0x450 0x6cc 0x2 0x1
+#define MX6SL_PAD_I2C1_SDA__FEC_TX_EN 0x160 0x450 0x000 0x3 0x0
+#define MX6SL_PAD_I2C1_SDA__SD3_VSELECT 0x160 0x450 0x000 0x4 0x0
+#define MX6SL_PAD_I2C1_SDA__GPIO3_IO13 0x160 0x450 0x000 0x5 0x0
+#define MX6SL_PAD_I2C1_SDA__ECSPI1_SS2 0x160 0x450 0x694 0x6 0x0
+#define MX6SL_PAD_I2C2_SCL__I2C2_SCL 0x164 0x454 0x724 0x0 0x1
+#define MX6SL_PAD_I2C2_SCL__AUD4_RXFS 0x164 0x454 0x5f0 0x1 0x0
+#define MX6SL_PAD_I2C2_SCL__SPDIF_IN 0x164 0x454 0x7f0 0x2 0x1
+#define MX6SL_PAD_I2C2_SCL__FEC_TX_DATA1 0x164 0x454 0x000 0x3 0x0
+#define MX6SL_PAD_I2C2_SCL__SD3_WP 0x164 0x454 0x84c 0x4 0x2
+#define MX6SL_PAD_I2C2_SCL__GPIO3_IO14 0x164 0x454 0x000 0x5 0x0
+#define MX6SL_PAD_I2C2_SCL__ECSPI1_RDY 0x164 0x454 0x680 0x6 0x0
+#define MX6SL_PAD_I2C2_SDA__I2C2_SDA 0x168 0x458 0x728 0x0 0x1
+#define MX6SL_PAD_I2C2_SDA__AUD4_RXC 0x168 0x458 0x5ec 0x1 0x0
+#define MX6SL_PAD_I2C2_SDA__SPDIF_OUT 0x168 0x458 0x000 0x2 0x0
+#define MX6SL_PAD_I2C2_SDA__FEC_REF_OUT 0x168 0x458 0x000 0x3 0x0
+#define MX6SL_PAD_I2C2_SDA__SD3_CD_B 0x168 0x458 0x838 0x4 0x2
+#define MX6SL_PAD_I2C2_SDA__GPIO3_IO15 0x168 0x458 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_COL0__KEY_COL0 0x16c 0x474 0x734 0x0 0x0
+#define MX6SL_PAD_KEY_COL0__I2C2_SCL 0x16c 0x474 0x724 0x1 0x2
+#define MX6SL_PAD_KEY_COL0__LCD_DATA00 0x16c 0x474 0x778 0x2 0x0
+#define MX6SL_PAD_KEY_COL0__EIM_AD00 0x16c 0x474 0x000 0x3 0x0
+#define MX6SL_PAD_KEY_COL0__SD1_CD_B 0x16c 0x474 0x828 0x4 0x2
+#define MX6SL_PAD_KEY_COL0__GPIO3_IO24 0x16c 0x474 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_COL1__KEY_COL1 0x170 0x478 0x738 0x0 0x0
+#define MX6SL_PAD_KEY_COL1__ECSPI4_MOSI 0x170 0x478 0x6d8 0x1 0x2
+#define MX6SL_PAD_KEY_COL1__LCD_DATA02 0x170 0x478 0x780 0x2 0x0
+#define MX6SL_PAD_KEY_COL1__EIM_AD02 0x170 0x478 0x000 0x3 0x0
+#define MX6SL_PAD_KEY_COL1__SD3_DATA4 0x170 0x478 0x83c 0x4 0x0
+#define MX6SL_PAD_KEY_COL1__GPIO3_IO26 0x170 0x478 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_COL2__KEY_COL2 0x174 0x47c 0x73c 0x0 0x0
+#define MX6SL_PAD_KEY_COL2__ECSPI4_SS0 0x174 0x47c 0x6dc 0x1 0x2
+#define MX6SL_PAD_KEY_COL2__LCD_DATA04 0x174 0x47c 0x788 0x2 0x0
+#define MX6SL_PAD_KEY_COL2__EIM_AD04 0x174 0x47c 0x000 0x3 0x0
+#define MX6SL_PAD_KEY_COL2__SD3_DATA6 0x174 0x47c 0x844 0x4 0x0
+#define MX6SL_PAD_KEY_COL2__GPIO3_IO28 0x174 0x47c 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_COL3__KEY_COL3 0x178 0x480 0x740 0x0 0x0
+#define MX6SL_PAD_KEY_COL3__AUD6_RXFS 0x178 0x480 0x620 0x1 0x1
+#define MX6SL_PAD_KEY_COL3__LCD_DATA06 0x178 0x480 0x790 0x2 0x0
+#define MX6SL_PAD_KEY_COL3__EIM_AD06 0x178 0x480 0x000 0x3 0x0
+#define MX6SL_PAD_KEY_COL3__SD4_DATA6 0x178 0x480 0x874 0x4 0x1
+#define MX6SL_PAD_KEY_COL3__GPIO3_IO30 0x178 0x480 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_COL3__SD1_RESET 0x178 0x480 0x000 0x6 0x0
+#define MX6SL_PAD_KEY_COL4__KEY_COL4 0x17c 0x484 0x744 0x0 0x0
+#define MX6SL_PAD_KEY_COL4__AUD6_RXD 0x17c 0x484 0x614 0x1 0x1
+#define MX6SL_PAD_KEY_COL4__LCD_DATA08 0x17c 0x484 0x798 0x2 0x0
+#define MX6SL_PAD_KEY_COL4__EIM_AD08 0x17c 0x484 0x000 0x3 0x0
+#define MX6SL_PAD_KEY_COL4__SD4_CLK 0x17c 0x484 0x850 0x4 0x2
+#define MX6SL_PAD_KEY_COL4__GPIO4_IO00 0x17c 0x484 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_COL4__USB_OTG1_PWR 0x17c 0x484 0x000 0x6 0x0
+#define MX6SL_PAD_KEY_COL5__KEY_COL5 0x180 0x488 0x748 0x0 0x0
+#define MX6SL_PAD_KEY_COL5__AUD6_TXFS 0x180 0x488 0x628 0x1 0x1
+#define MX6SL_PAD_KEY_COL5__LCD_DATA10 0x180 0x488 0x7a0 0x2 0x0
+#define MX6SL_PAD_KEY_COL5__EIM_AD10 0x180 0x488 0x000 0x3 0x0
+#define MX6SL_PAD_KEY_COL5__SD4_DATA0 0x180 0x488 0x85c 0x4 0x2
+#define MX6SL_PAD_KEY_COL5__GPIO4_IO02 0x180 0x488 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_COL5__USB_OTG2_PWR 0x180 0x488 0x000 0x6 0x0
+#define MX6SL_PAD_KEY_COL6__KEY_COL6 0x184 0x48c 0x74c 0x0 0x0
+#define MX6SL_PAD_KEY_COL6__UART4_RX_DATA 0x184 0x48c 0x814 0x1 0x2
+#define MX6SL_PAD_KEY_COL6__UART4_TX_DATA 0x184 0x48c 0x000 0x1 0x0
+#define MX6SL_PAD_KEY_COL6__LCD_DATA12 0x184 0x48c 0x7a8 0x2 0x0
+#define MX6SL_PAD_KEY_COL6__EIM_AD12 0x184 0x48c 0x000 0x3 0x0
+#define MX6SL_PAD_KEY_COL6__SD4_DATA2 0x184 0x48c 0x864 0x4 0x2
+#define MX6SL_PAD_KEY_COL6__GPIO4_IO04 0x184 0x48c 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_COL6__SD3_RESET 0x184 0x48c 0x000 0x6 0x0
+#define MX6SL_PAD_KEY_COL7__KEY_COL7 0x188 0x490 0x750 0x0 0x0
+#define MX6SL_PAD_KEY_COL7__UART4_RTS_B 0x188 0x490 0x810 0x1 0x2
+#define MX6SL_PAD_KEY_COL7__UART4_CTS_B 0x188 0x490 0x000 0x1 0x0
+#define MX6SL_PAD_KEY_COL7__LCD_DATA14 0x188 0x490 0x7b0 0x2 0x0
+#define MX6SL_PAD_KEY_COL7__EIM_AD14 0x188 0x490 0x000 0x3 0x0
+#define MX6SL_PAD_KEY_COL7__SD4_DATA4 0x188 0x490 0x86c 0x4 0x1
+#define MX6SL_PAD_KEY_COL7__GPIO4_IO06 0x188 0x490 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_COL7__SD1_WP 0x188 0x490 0x82c 0x6 0x2
+#define MX6SL_PAD_KEY_ROW0__KEY_ROW0 0x18c 0x494 0x754 0x0 0x0
+#define MX6SL_PAD_KEY_ROW0__I2C2_SDA 0x18c 0x494 0x728 0x1 0x2
+#define MX6SL_PAD_KEY_ROW0__LCD_DATA01 0x18c 0x494 0x77c 0x2 0x0
+#define MX6SL_PAD_KEY_ROW0__EIM_AD01 0x18c 0x494 0x000 0x3 0x0
+#define MX6SL_PAD_KEY_ROW0__SD1_WP 0x18c 0x494 0x82c 0x4 0x3
+#define MX6SL_PAD_KEY_ROW0__GPIO3_IO25 0x18c 0x494 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_ROW1__KEY_ROW1 0x190 0x498 0x758 0x0 0x0
+#define MX6SL_PAD_KEY_ROW1__ECSPI4_MISO 0x190 0x498 0x6d4 0x1 0x2
+#define MX6SL_PAD_KEY_ROW1__LCD_DATA03 0x190 0x498 0x784 0x2 0x0
+#define MX6SL_PAD_KEY_ROW1__EIM_AD03 0x190 0x498 0x000 0x3 0x0
+#define MX6SL_PAD_KEY_ROW1__SD3_DATA5 0x190 0x498 0x840 0x4 0x0
+#define MX6SL_PAD_KEY_ROW1__GPIO3_IO27 0x190 0x498 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_ROW2__KEY_ROW2 0x194 0x49c 0x75c 0x0 0x0
+#define MX6SL_PAD_KEY_ROW2__ECSPI4_SCLK 0x194 0x49c 0x6d0 0x1 0x2
+#define MX6SL_PAD_KEY_ROW2__LCD_DATA05 0x194 0x49c 0x78c 0x2 0x0
+#define MX6SL_PAD_KEY_ROW2__EIM_AD05 0x194 0x49c 0x000 0x3 0x0
+#define MX6SL_PAD_KEY_ROW2__SD3_DATA7 0x194 0x49c 0x848 0x4 0x0
+#define MX6SL_PAD_KEY_ROW2__GPIO3_IO29 0x194 0x49c 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_ROW3__KEY_ROW3 0x198 0x4a0 0x760 0x0 0x0
+#define MX6SL_PAD_KEY_ROW3__AUD6_RXC 0x198 0x4a0 0x61c 0x1 0x1
+#define MX6SL_PAD_KEY_ROW3__LCD_DATA07 0x198 0x4a0 0x794 0x2 0x0
+#define MX6SL_PAD_KEY_ROW3__EIM_AD07 0x198 0x4a0 0x000 0x3 0x0
+#define MX6SL_PAD_KEY_ROW3__SD4_DATA7 0x198 0x4a0 0x878 0x4 0x1
+#define MX6SL_PAD_KEY_ROW3__GPIO3_IO31 0x198 0x4a0 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_ROW3__SD1_VSELECT 0x198 0x4a0 0x000 0x6 0x0
+#define MX6SL_PAD_KEY_ROW4__KEY_ROW4 0x19c 0x4a4 0x764 0x0 0x0
+#define MX6SL_PAD_KEY_ROW4__AUD6_TXC 0x19c 0x4a4 0x624 0x1 0x1
+#define MX6SL_PAD_KEY_ROW4__LCD_DATA09 0x19c 0x4a4 0x79c 0x2 0x0
+#define MX6SL_PAD_KEY_ROW4__EIM_AD09 0x19c 0x4a4 0x000 0x3 0x0
+#define MX6SL_PAD_KEY_ROW4__SD4_CMD 0x19c 0x4a4 0x858 0x4 0x2
+#define MX6SL_PAD_KEY_ROW4__GPIO4_IO01 0x19c 0x4a4 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_ROW4__USB_OTG1_OC 0x19c 0x4a4 0x824 0x6 0x1
+#define MX6SL_PAD_KEY_ROW5__KEY_ROW5 0x1a0 0x4a8 0x768 0x0 0x0
+#define MX6SL_PAD_KEY_ROW5__AUD6_TXD 0x1a0 0x4a8 0x618 0x1 0x1
+#define MX6SL_PAD_KEY_ROW5__LCD_DATA11 0x1a0 0x4a8 0x7a4 0x2 0x0
+#define MX6SL_PAD_KEY_ROW5__EIM_AD11 0x1a0 0x4a8 0x000 0x3 0x0
+#define MX6SL_PAD_KEY_ROW5__SD4_DATA1 0x1a0 0x4a8 0x860 0x4 0x2
+#define MX6SL_PAD_KEY_ROW5__GPIO4_IO03 0x1a0 0x4a8 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_ROW5__USB_OTG2_OC 0x1a0 0x4a8 0x820 0x6 0x2
+#define MX6SL_PAD_KEY_ROW6__KEY_ROW6 0x1a4 0x4ac 0x76c 0x0 0x0
+#define MX6SL_PAD_KEY_ROW6__UART4_TX_DATA 0x1a4 0x4ac 0x000 0x1 0x0
+#define MX6SL_PAD_KEY_ROW6__UART4_RX_DATA 0x1a4 0x4ac 0x814 0x1 0x3
+#define MX6SL_PAD_KEY_ROW6__LCD_DATA13 0x1a4 0x4ac 0x7ac 0x2 0x0
+#define MX6SL_PAD_KEY_ROW6__EIM_AD13 0x1a4 0x4ac 0x000 0x3 0x0
+#define MX6SL_PAD_KEY_ROW6__SD4_DATA3 0x1a4 0x4ac 0x868 0x4 0x2
+#define MX6SL_PAD_KEY_ROW6__GPIO4_IO05 0x1a4 0x4ac 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_ROW6__SD3_VSELECT 0x1a4 0x4ac 0x000 0x6 0x0
+#define MX6SL_PAD_KEY_ROW7__KEY_ROW7 0x1a8 0x4b0 0x770 0x0 0x0
+#define MX6SL_PAD_KEY_ROW7__UART4_CTS_B 0x1a8 0x4b0 0x000 0x1 0x0
+#define MX6SL_PAD_KEY_ROW7__UART4_RTS_B 0x1a8 0x4b0 0x810 0x1 0x3
+#define MX6SL_PAD_KEY_ROW7__LCD_DATA15 0x1a8 0x4b0 0x7b4 0x2 0x0
+#define MX6SL_PAD_KEY_ROW7__EIM_AD15 0x1a8 0x4b0 0x000 0x3 0x0
+#define MX6SL_PAD_KEY_ROW7__SD4_DATA5 0x1a8 0x4b0 0x870 0x4 0x1
+#define MX6SL_PAD_KEY_ROW7__GPIO4_IO07 0x1a8 0x4b0 0x000 0x5 0x0
+#define MX6SL_PAD_KEY_ROW7__SD1_CD_B 0x1a8 0x4b0 0x828 0x6 0x3
+#define MX6SL_PAD_LCD_CLK__LCD_CLK 0x1ac 0x4b4 0x000 0x0 0x0
+#define MX6SL_PAD_LCD_CLK__SD4_DATA4 0x1ac 0x4b4 0x86c 0x1 0x2
+#define MX6SL_PAD_LCD_CLK__LCD_WR_RWN 0x1ac 0x4b4 0x000 0x2 0x0
+#define MX6SL_PAD_LCD_CLK__EIM_RW 0x1ac 0x4b4 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_CLK__PWM4_OUT 0x1ac 0x4b4 0x000 0x4 0x0
+#define MX6SL_PAD_LCD_CLK__GPIO2_IO15 0x1ac 0x4b4 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT0__LCD_DATA00 0x1b0 0x4b8 0x778 0x0 0x1
+#define MX6SL_PAD_LCD_DAT0__ECSPI1_MOSI 0x1b0 0x4b8 0x688 0x1 0x1
+#define MX6SL_PAD_LCD_DAT0__USB_OTG2_ID 0x1b0 0x4b8 0x5e0 0x2 0x1
+#define MX6SL_PAD_LCD_DAT0__PWM1_OUT 0x1b0 0x4b8 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT0__UART5_DTR_B 0x1b0 0x4b8 0x000 0x4 0x0
+#define MX6SL_PAD_LCD_DAT0__GPIO2_IO20 0x1b0 0x4b8 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT0__ARM_TRACE00 0x1b0 0x4b8 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT0__SRC_BOOT_CFG00 0x1b0 0x4b8 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT1__LCD_DATA01 0x1b4 0x4bc 0x77c 0x0 0x1
+#define MX6SL_PAD_LCD_DAT1__ECSPI1_MISO 0x1b4 0x4bc 0x684 0x1 0x1
+#define MX6SL_PAD_LCD_DAT1__USB_OTG1_ID 0x1b4 0x4bc 0x5dc 0x2 0x2
+#define MX6SL_PAD_LCD_DAT1__PWM2_OUT 0x1b4 0x4bc 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT1__AUD4_RXFS 0x1b4 0x4bc 0x5f0 0x4 0x1
+#define MX6SL_PAD_LCD_DAT1__GPIO2_IO21 0x1b4 0x4bc 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT1__ARM_TRACE01 0x1b4 0x4bc 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT1__SRC_BOOT_CFG01 0x1b4 0x4bc 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT10__LCD_DATA10 0x1b8 0x4c0 0x7a0 0x0 0x1
+#define MX6SL_PAD_LCD_DAT10__KEY_COL1 0x1b8 0x4c0 0x738 0x1 0x1
+#define MX6SL_PAD_LCD_DAT10__CSI_DATA07 0x1b8 0x4c0 0x64c 0x2 0x1
+#define MX6SL_PAD_LCD_DAT10__EIM_DATA04 0x1b8 0x4c0 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT10__ECSPI2_MISO 0x1b8 0x4c0 0x6a0 0x4 0x2
+#define MX6SL_PAD_LCD_DAT10__GPIO2_IO30 0x1b8 0x4c0 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT10__ARM_TRACE10 0x1b8 0x4c0 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT10__SRC_BOOT_CFG10 0x1b8 0x4c0 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT11__LCD_DATA11 0x1bc 0x4c4 0x7a4 0x0 0x1
+#define MX6SL_PAD_LCD_DAT11__KEY_ROW1 0x1bc 0x4c4 0x758 0x1 0x1
+#define MX6SL_PAD_LCD_DAT11__CSI_DATA06 0x1bc 0x4c4 0x648 0x2 0x1
+#define MX6SL_PAD_LCD_DAT11__EIM_DATA05 0x1bc 0x4c4 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT11__ECSPI2_SS1 0x1bc 0x4c4 0x6ac 0x4 0x1
+#define MX6SL_PAD_LCD_DAT11__GPIO2_IO31 0x1bc 0x4c4 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT11__ARM_TRACE11 0x1bc 0x4c4 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT11__SRC_BOOT_CFG11 0x1bc 0x4c4 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT12__LCD_DATA12 0x1c0 0x4c8 0x7a8 0x0 0x1
+#define MX6SL_PAD_LCD_DAT12__KEY_COL2 0x1c0 0x4c8 0x73c 0x1 0x1
+#define MX6SL_PAD_LCD_DAT12__CSI_DATA05 0x1c0 0x4c8 0x644 0x2 0x1
+#define MX6SL_PAD_LCD_DAT12__EIM_DATA06 0x1c0 0x4c8 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT12__UART5_RTS_B 0x1c0 0x4c8 0x818 0x4 0x2
+#define MX6SL_PAD_LCD_DAT12__UART5_CTS_B 0x1c0 0x4c8 0x000 0x4 0x0
+#define MX6SL_PAD_LCD_DAT12__GPIO3_IO00 0x1c0 0x4c8 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT12__ARM_TRACE12 0x1c0 0x4c8 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT12__SRC_BOOT_CFG12 0x1c0 0x4c8 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT13__LCD_DATA13 0x1c4 0x4cc 0x7ac 0x0 0x1
+#define MX6SL_PAD_LCD_DAT13__KEY_ROW2 0x1c4 0x4cc 0x75c 0x1 0x1
+#define MX6SL_PAD_LCD_DAT13__CSI_DATA04 0x1c4 0x4cc 0x640 0x2 0x1
+#define MX6SL_PAD_LCD_DAT13__EIM_DATA07 0x1c4 0x4cc 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT13__UART5_CTS_B 0x1c4 0x4cc 0x000 0x4 0x0
+#define MX6SL_PAD_LCD_DAT13__UART5_RTS_B 0x1c4 0x4cc 0x818 0x4 0x3
+#define MX6SL_PAD_LCD_DAT13__GPIO3_IO01 0x1c4 0x4cc 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT13__ARM_TRACE13 0x1c4 0x4cc 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT13__SRC_BOOT_CFG13 0x1c4 0x4cc 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT14__LCD_DATA14 0x1c8 0x4d0 0x7b0 0x0 0x1
+#define MX6SL_PAD_LCD_DAT14__KEY_COL3 0x1c8 0x4d0 0x740 0x1 0x1
+#define MX6SL_PAD_LCD_DAT14__CSI_DATA03 0x1c8 0x4d0 0x63c 0x2 0x1
+#define MX6SL_PAD_LCD_DAT14__EIM_DATA08 0x1c8 0x4d0 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT14__UART5_RX_DATA 0x1c8 0x4d0 0x81c 0x4 0x2
+#define MX6SL_PAD_LCD_DAT14__UART5_TX_DATA 0x1c8 0x4d0 0x000 0x4 0x0
+#define MX6SL_PAD_LCD_DAT14__GPIO3_IO02 0x1c8 0x4d0 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT14__ARM_TRACE14 0x1c8 0x4d0 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT14__SRC_BOOT_CFG14 0x1c8 0x4d0 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT15__LCD_DATA15 0x1cc 0x4d4 0x7b4 0x0 0x1
+#define MX6SL_PAD_LCD_DAT15__KEY_ROW3 0x1cc 0x4d4 0x760 0x1 0x1
+#define MX6SL_PAD_LCD_DAT15__CSI_DATA02 0x1cc 0x4d4 0x638 0x2 0x1
+#define MX6SL_PAD_LCD_DAT15__EIM_DATA09 0x1cc 0x4d4 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT15__UART5_TX_DATA 0x1cc 0x4d4 0x000 0x4 0x0
+#define MX6SL_PAD_LCD_DAT15__UART5_RX_DATA 0x1cc 0x4d4 0x81c 0x4 0x3
+#define MX6SL_PAD_LCD_DAT15__GPIO3_IO03 0x1cc 0x4d4 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT15__ARM_TRACE15 0x1cc 0x4d4 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT15__SRC_BOOT_CFG15 0x1cc 0x4d4 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT16__LCD_DATA16 0x1d0 0x4d8 0x7b8 0x0 0x1
+#define MX6SL_PAD_LCD_DAT16__KEY_COL4 0x1d0 0x4d8 0x744 0x1 0x1
+#define MX6SL_PAD_LCD_DAT16__CSI_DATA01 0x1d0 0x4d8 0x634 0x2 0x1
+#define MX6SL_PAD_LCD_DAT16__EIM_DATA10 0x1d0 0x4d8 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT16__I2C2_SCL 0x1d0 0x4d8 0x724 0x4 0x3
+#define MX6SL_PAD_LCD_DAT16__GPIO3_IO04 0x1d0 0x4d8 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT16__ARM_TRACE16 0x1d0 0x4d8 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT16__SRC_BOOT_CFG24 0x1d0 0x4d8 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT17__LCD_DATA17 0x1d4 0x4dc 0x7bc 0x0 0x1
+#define MX6SL_PAD_LCD_DAT17__KEY_ROW4 0x1d4 0x4dc 0x764 0x1 0x1
+#define MX6SL_PAD_LCD_DAT17__CSI_DATA00 0x1d4 0x4dc 0x630 0x2 0x1
+#define MX6SL_PAD_LCD_DAT17__EIM_DATA11 0x1d4 0x4dc 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT17__I2C2_SDA 0x1d4 0x4dc 0x728 0x4 0x3
+#define MX6SL_PAD_LCD_DAT17__GPIO3_IO05 0x1d4 0x4dc 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT17__ARM_TRACE17 0x1d4 0x4dc 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT17__SRC_BOOT_CFG25 0x1d4 0x4dc 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT18__LCD_DATA18 0x1d8 0x4e0 0x7c0 0x0 0x1
+#define MX6SL_PAD_LCD_DAT18__KEY_COL5 0x1d8 0x4e0 0x748 0x1 0x1
+#define MX6SL_PAD_LCD_DAT18__CSI_DATA15 0x1d8 0x4e0 0x66c 0x2 0x0
+#define MX6SL_PAD_LCD_DAT18__EIM_DATA12 0x1d8 0x4e0 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT18__GPT_CAPTURE1 0x1d8 0x4e0 0x710 0x4 0x1
+#define MX6SL_PAD_LCD_DAT18__GPIO3_IO06 0x1d8 0x4e0 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT18__ARM_TRACE18 0x1d8 0x4e0 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT18__SRC_BOOT_CFG26 0x1d8 0x4e0 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT19__LCD_DATA19 0x1dc 0x4e4 0x7c4 0x0 0x1
+#define MX6SL_PAD_LCD_DAT19__KEY_ROW5 0x1dc 0x4e4 0x768 0x1 0x1
+#define MX6SL_PAD_LCD_DAT19__CSI_DATA14 0x1dc 0x4e4 0x668 0x2 0x0
+#define MX6SL_PAD_LCD_DAT19__EIM_DATA13 0x1dc 0x4e4 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT19__GPT_CAPTURE2 0x1dc 0x4e4 0x714 0x4 0x1
+#define MX6SL_PAD_LCD_DAT19__GPIO3_IO07 0x1dc 0x4e4 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT19__ARM_TRACE19 0x1dc 0x4e4 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT19__SRC_BOOT_CFG27 0x1dc 0x4e4 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT2__LCD_DATA02 0x1e0 0x4e8 0x780 0x0 0x1
+#define MX6SL_PAD_LCD_DAT2__ECSPI1_SS0 0x1e0 0x4e8 0x68c 0x1 0x1
+#define MX6SL_PAD_LCD_DAT2__EPIT2_OUT 0x1e0 0x4e8 0x000 0x2 0x0
+#define MX6SL_PAD_LCD_DAT2__PWM3_OUT 0x1e0 0x4e8 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT2__AUD4_RXC 0x1e0 0x4e8 0x5ec 0x4 0x1
+#define MX6SL_PAD_LCD_DAT2__GPIO2_IO22 0x1e0 0x4e8 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT2__ARM_TRACE02 0x1e0 0x4e8 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT2__SRC_BOOT_CFG02 0x1e0 0x4e8 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT20__LCD_DATA20 0x1e4 0x4ec 0x7c8 0x0 0x1
+#define MX6SL_PAD_LCD_DAT20__KEY_COL6 0x1e4 0x4ec 0x74c 0x1 0x1
+#define MX6SL_PAD_LCD_DAT20__CSI_DATA13 0x1e4 0x4ec 0x664 0x2 0x0
+#define MX6SL_PAD_LCD_DAT20__EIM_DATA14 0x1e4 0x4ec 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT20__GPT_COMPARE1 0x1e4 0x4ec 0x000 0x4 0x0
+#define MX6SL_PAD_LCD_DAT20__GPIO3_IO08 0x1e4 0x4ec 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT20__ARM_TRACE20 0x1e4 0x4ec 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT20__SRC_BOOT_CFG28 0x1e4 0x4ec 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT21__LCD_DATA21 0x1e8 0x4f0 0x7cc 0x0 0x1
+#define MX6SL_PAD_LCD_DAT21__KEY_ROW6 0x1e8 0x4f0 0x76c 0x1 0x1
+#define MX6SL_PAD_LCD_DAT21__CSI_DATA12 0x1e8 0x4f0 0x660 0x2 0x0
+#define MX6SL_PAD_LCD_DAT21__EIM_DATA15 0x1e8 0x4f0 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT21__GPT_COMPARE2 0x1e8 0x4f0 0x000 0x4 0x0
+#define MX6SL_PAD_LCD_DAT21__GPIO3_IO09 0x1e8 0x4f0 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT21__ARM_TRACE21 0x1e8 0x4f0 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT21__SRC_BOOT_CFG29 0x1e8 0x4f0 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT22__LCD_DATA22 0x1ec 0x4f4 0x7d0 0x0 0x1
+#define MX6SL_PAD_LCD_DAT22__KEY_COL7 0x1ec 0x4f4 0x750 0x1 0x1
+#define MX6SL_PAD_LCD_DAT22__CSI_DATA11 0x1ec 0x4f4 0x65c 0x2 0x1
+#define MX6SL_PAD_LCD_DAT22__EIM_EB3_B 0x1ec 0x4f4 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT22__GPT_COMPARE3 0x1ec 0x4f4 0x000 0x4 0x0
+#define MX6SL_PAD_LCD_DAT22__GPIO3_IO10 0x1ec 0x4f4 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT22__ARM_TRACE22 0x1ec 0x4f4 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT22__SRC_BOOT_CFG30 0x1ec 0x4f4 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT23__LCD_DATA23 0x1f0 0x4f8 0x7d4 0x0 0x1
+#define MX6SL_PAD_LCD_DAT23__KEY_ROW7 0x1f0 0x4f8 0x770 0x1 0x1
+#define MX6SL_PAD_LCD_DAT23__CSI_DATA10 0x1f0 0x4f8 0x658 0x2 0x1
+#define MX6SL_PAD_LCD_DAT23__EIM_EB2_B 0x1f0 0x4f8 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT23__GPT_CLKIN 0x1f0 0x4f8 0x718 0x4 0x1
+#define MX6SL_PAD_LCD_DAT23__GPIO3_IO11 0x1f0 0x4f8 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT23__ARM_TRACE23 0x1f0 0x4f8 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT23__SRC_BOOT_CFG31 0x1f0 0x4f8 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT3__LCD_DATA03 0x1f4 0x4fc 0x784 0x0 0x1
+#define MX6SL_PAD_LCD_DAT3__ECSPI1_SCLK 0x1f4 0x4fc 0x67c 0x1 0x1
+#define MX6SL_PAD_LCD_DAT3__UART5_DSR_B 0x1f4 0x4fc 0x000 0x2 0x0
+#define MX6SL_PAD_LCD_DAT3__PWM4_OUT 0x1f4 0x4fc 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT3__AUD4_RXD 0x1f4 0x4fc 0x5e4 0x4 0x1
+#define MX6SL_PAD_LCD_DAT3__GPIO2_IO23 0x1f4 0x4fc 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT3__ARM_TRACE03 0x1f4 0x4fc 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT3__SRC_BOOT_CFG03 0x1f4 0x4fc 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT4__LCD_DATA04 0x1f8 0x500 0x788 0x0 0x1
+#define MX6SL_PAD_LCD_DAT4__ECSPI1_SS1 0x1f8 0x500 0x690 0x1 0x1
+#define MX6SL_PAD_LCD_DAT4__CSI_VSYNC 0x1f8 0x500 0x678 0x2 0x2
+#define MX6SL_PAD_LCD_DAT4__WDOG2_RESET_B_DEB 0x1f8 0x500 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT4__AUD4_TXC 0x1f8 0x500 0x5f4 0x4 0x1
+#define MX6SL_PAD_LCD_DAT4__GPIO2_IO24 0x1f8 0x500 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT4__ARM_TRACE04 0x1f8 0x500 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT4__SRC_BOOT_CFG04 0x1f8 0x500 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT5__LCD_DATA05 0x1fc 0x504 0x78c 0x0 0x1
+#define MX6SL_PAD_LCD_DAT5__ECSPI1_SS2 0x1fc 0x504 0x694 0x1 0x1
+#define MX6SL_PAD_LCD_DAT5__CSI_HSYNC 0x1fc 0x504 0x670 0x2 0x2
+#define MX6SL_PAD_LCD_DAT5__EIM_CS3_B 0x1fc 0x504 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT5__AUD4_TXFS 0x1fc 0x504 0x5f8 0x4 0x1
+#define MX6SL_PAD_LCD_DAT5__GPIO2_IO25 0x1fc 0x504 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT5__ARM_TRACE05 0x1fc 0x504 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT5__SRC_BOOT_CFG05 0x1fc 0x504 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT6__LCD_DATA06 0x200 0x508 0x790 0x0 0x1
+#define MX6SL_PAD_LCD_DAT6__ECSPI1_SS3 0x200 0x508 0x698 0x1 0x1
+#define MX6SL_PAD_LCD_DAT6__CSI_PIXCLK 0x200 0x508 0x674 0x2 0x2
+#define MX6SL_PAD_LCD_DAT6__EIM_DATA00 0x200 0x508 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT6__AUD4_TXD 0x200 0x508 0x5e8 0x4 0x1
+#define MX6SL_PAD_LCD_DAT6__GPIO2_IO26 0x200 0x508 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT6__ARM_TRACE06 0x200 0x508 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT6__SRC_BOOT_CFG06 0x200 0x508 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT7__LCD_DATA07 0x204 0x50c 0x794 0x0 0x1
+#define MX6SL_PAD_LCD_DAT7__ECSPI1_RDY 0x204 0x50c 0x680 0x1 0x1
+#define MX6SL_PAD_LCD_DAT7__CSI_MCLK 0x204 0x50c 0x000 0x2 0x0
+#define MX6SL_PAD_LCD_DAT7__EIM_DATA01 0x204 0x50c 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT7__AUDIO_CLK_OUT 0x204 0x50c 0x000 0x4 0x0
+#define MX6SL_PAD_LCD_DAT7__GPIO2_IO27 0x204 0x50c 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT7__ARM_TRACE07 0x204 0x50c 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT7__SRC_BOOT_CFG07 0x204 0x50c 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT8__LCD_DATA08 0x208 0x510 0x798 0x0 0x1
+#define MX6SL_PAD_LCD_DAT8__KEY_COL0 0x208 0x510 0x734 0x1 0x1
+#define MX6SL_PAD_LCD_DAT8__CSI_DATA09 0x208 0x510 0x654 0x2 0x1
+#define MX6SL_PAD_LCD_DAT8__EIM_DATA02 0x208 0x510 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT8__ECSPI2_SCLK 0x208 0x510 0x69c 0x4 0x2
+#define MX6SL_PAD_LCD_DAT8__GPIO2_IO28 0x208 0x510 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT8__ARM_TRACE08 0x208 0x510 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT8__SRC_BOOT_CFG08 0x208 0x510 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_DAT9__LCD_DATA09 0x20c 0x514 0x79c 0x0 0x1
+#define MX6SL_PAD_LCD_DAT9__KEY_ROW0 0x20c 0x514 0x754 0x1 0x1
+#define MX6SL_PAD_LCD_DAT9__CSI_DATA08 0x20c 0x514 0x650 0x2 0x1
+#define MX6SL_PAD_LCD_DAT9__EIM_DATA03 0x20c 0x514 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_DAT9__ECSPI2_MOSI 0x20c 0x514 0x6a4 0x4 0x2
+#define MX6SL_PAD_LCD_DAT9__GPIO2_IO29 0x20c 0x514 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_DAT9__ARM_TRACE09 0x20c 0x514 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_DAT9__SRC_BOOT_CFG09 0x20c 0x514 0x000 0x7 0x0
+#define MX6SL_PAD_LCD_ENABLE__LCD_ENABLE 0x210 0x518 0x000 0x0 0x0
+#define MX6SL_PAD_LCD_ENABLE__SD4_DATA5 0x210 0x518 0x870 0x1 0x2
+#define MX6SL_PAD_LCD_ENABLE__LCD_RD_E 0x210 0x518 0x000 0x2 0x0
+#define MX6SL_PAD_LCD_ENABLE__EIM_OE_B 0x210 0x518 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_ENABLE__UART2_RX_DATA 0x210 0x518 0x804 0x4 0x2
+#define MX6SL_PAD_LCD_ENABLE__UART2_TX_DATA 0x210 0x518 0x000 0x4 0x0
+#define MX6SL_PAD_LCD_ENABLE__GPIO2_IO16 0x210 0x518 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_HSYNC__LCD_HSYNC 0x214 0x51c 0x774 0x0 0x0
+#define MX6SL_PAD_LCD_HSYNC__SD4_DATA6 0x214 0x51c 0x874 0x1 0x2
+#define MX6SL_PAD_LCD_HSYNC__LCD_CS 0x214 0x51c 0x000 0x2 0x0
+#define MX6SL_PAD_LCD_HSYNC__EIM_CS0_B 0x214 0x51c 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_HSYNC__UART2_TX_DATA 0x214 0x51c 0x000 0x4 0x0
+#define MX6SL_PAD_LCD_HSYNC__UART2_RX_DATA 0x214 0x51c 0x804 0x4 0x3
+#define MX6SL_PAD_LCD_HSYNC__GPIO2_IO17 0x214 0x51c 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_HSYNC__ARM_TRACE_CLK 0x214 0x51c 0x000 0x6 0x0
+#define MX6SL_PAD_LCD_RESET__LCD_RESET 0x218 0x520 0x000 0x0 0x0
+#define MX6SL_PAD_LCD_RESET__EIM_DTACK_B 0x218 0x520 0x880 0x1 0x1
+#define MX6SL_PAD_LCD_RESET__LCD_BUSY 0x218 0x520 0x774 0x2 0x1
+#define MX6SL_PAD_LCD_RESET__EIM_WAIT_B 0x218 0x520 0x884 0x3 0x1
+#define MX6SL_PAD_LCD_RESET__UART2_CTS_B 0x218 0x520 0x000 0x4 0x0
+#define MX6SL_PAD_LCD_RESET__UART2_RTS_B 0x218 0x520 0x800 0x4 0x2
+#define MX6SL_PAD_LCD_RESET__GPIO2_IO19 0x218 0x520 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_RESET__CCM_PMIC_READY 0x218 0x520 0x62c 0x6 0x1
+#define MX6SL_PAD_LCD_VSYNC__LCD_VSYNC 0x21c 0x524 0x000 0x0 0x0
+#define MX6SL_PAD_LCD_VSYNC__SD4_DATA7 0x21c 0x524 0x878 0x1 0x2
+#define MX6SL_PAD_LCD_VSYNC__LCD_RS 0x21c 0x524 0x000 0x2 0x0
+#define MX6SL_PAD_LCD_VSYNC__EIM_CS1_B 0x21c 0x524 0x000 0x3 0x0
+#define MX6SL_PAD_LCD_VSYNC__UART2_RTS_B 0x21c 0x524 0x800 0x4 0x3
+#define MX6SL_PAD_LCD_VSYNC__UART2_CTS_B 0x21c 0x524 0x000 0x4 0x0
+#define MX6SL_PAD_LCD_VSYNC__GPIO2_IO18 0x21c 0x524 0x000 0x5 0x0
+#define MX6SL_PAD_LCD_VSYNC__ARM_TRACE_CTL 0x21c 0x524 0x000 0x6 0x0
+#define MX6SL_PAD_PWM1__PWM1_OUT 0x220 0x528 0x000 0x0 0x0
+#define MX6SL_PAD_PWM1__CCM_CLKO 0x220 0x528 0x000 0x1 0x0
+#define MX6SL_PAD_PWM1__AUDIO_CLK_OUT 0x220 0x528 0x000 0x2 0x0
+#define MX6SL_PAD_PWM1__FEC_REF_OUT 0x220 0x528 0x000 0x3 0x0
+#define MX6SL_PAD_PWM1__CSI_MCLK 0x220 0x528 0x000 0x4 0x0
+#define MX6SL_PAD_PWM1__GPIO3_IO23 0x220 0x528 0x000 0x5 0x0
+#define MX6SL_PAD_PWM1__EPIT1_OUT 0x220 0x528 0x000 0x6 0x0
+#define MX6SL_PAD_REF_CLK_24M__XTALOSC_REF_CLK_24M 0x224 0x52c 0x000 0x0 0x0
+#define MX6SL_PAD_REF_CLK_24M__I2C3_SCL 0x224 0x52c 0x72c 0x1 0x2
+#define MX6SL_PAD_REF_CLK_24M__PWM3_OUT 0x224 0x52c 0x000 0x2 0x0
+#define MX6SL_PAD_REF_CLK_24M__USB_OTG2_ID 0x224 0x52c 0x5e0 0x3 0x2
+#define MX6SL_PAD_REF_CLK_24M__CCM_PMIC_READY 0x224 0x52c 0x62c 0x4 0x2
+#define MX6SL_PAD_REF_CLK_24M__GPIO3_IO21 0x224 0x52c 0x000 0x5 0x0
+#define MX6SL_PAD_REF_CLK_24M__SD3_WP 0x224 0x52c 0x84c 0x6 0x3
+#define MX6SL_PAD_REF_CLK_32K__XTALOSC_REF_CLK_32K 0x228 0x530 0x000 0x0 0x0
+#define MX6SL_PAD_REF_CLK_32K__I2C3_SDA 0x228 0x530 0x730 0x1 0x2
+#define MX6SL_PAD_REF_CLK_32K__PWM4_OUT 0x228 0x530 0x000 0x2 0x0
+#define MX6SL_PAD_REF_CLK_32K__USB_OTG1_ID 0x228 0x530 0x5dc 0x3 0x3
+#define MX6SL_PAD_REF_CLK_32K__SD1_LCTL 0x228 0x530 0x000 0x4 0x0
+#define MX6SL_PAD_REF_CLK_32K__GPIO3_IO22 0x228 0x530 0x000 0x5 0x0
+#define MX6SL_PAD_REF_CLK_32K__SD3_CD_B 0x228 0x530 0x838 0x6 0x3
+#define MX6SL_PAD_SD1_CLK__SD1_CLK 0x22c 0x534 0x000 0x0 0x0
+#define MX6SL_PAD_SD1_CLK__FEC_MDIO 0x22c 0x534 0x6f4 0x1 0x2
+#define MX6SL_PAD_SD1_CLK__KEY_COL0 0x22c 0x534 0x734 0x2 0x2
+#define MX6SL_PAD_SD1_CLK__EPDC_SDCE4 0x22c 0x534 0x000 0x3 0x0
+#define MX6SL_PAD_SD1_CLK__GPIO5_IO15 0x22c 0x534 0x000 0x5 0x0
+#define MX6SL_PAD_SD1_CMD__SD1_CMD 0x230 0x538 0x000 0x0 0x0
+#define MX6SL_PAD_SD1_CMD__FEC_TX_CLK 0x230 0x538 0x70c 0x1 0x2
+#define MX6SL_PAD_SD1_CMD__KEY_ROW0 0x230 0x538 0x754 0x2 0x2
+#define MX6SL_PAD_SD1_CMD__EPDC_SDCE5 0x230 0x538 0x000 0x3 0x0
+#define MX6SL_PAD_SD1_CMD__GPIO5_IO14 0x230 0x538 0x000 0x5 0x0
+#define MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x234 0x53c 0x000 0x0 0x0
+#define MX6SL_PAD_SD1_DAT0__FEC_RX_ER 0x234 0x53c 0x708 0x1 0x2
+#define MX6SL_PAD_SD1_DAT0__KEY_COL1 0x234 0x53c 0x738 0x2 0x2
+#define MX6SL_PAD_SD1_DAT0__EPDC_SDCE6 0x234 0x53c 0x000 0x3 0x0
+#define MX6SL_PAD_SD1_DAT0__GPIO5_IO11 0x234 0x53c 0x000 0x5 0x0
+#define MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x238 0x540 0x000 0x0 0x0
+#define MX6SL_PAD_SD1_DAT1__FEC_RX_DV 0x238 0x540 0x704 0x1 0x2
+#define MX6SL_PAD_SD1_DAT1__KEY_ROW1 0x238 0x540 0x758 0x2 0x2
+#define MX6SL_PAD_SD1_DAT1__EPDC_SDCE7 0x238 0x540 0x000 0x3 0x0
+#define MX6SL_PAD_SD1_DAT1__GPIO5_IO08 0x238 0x540 0x000 0x5 0x0
+#define MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x23c 0x544 0x000 0x0 0x0
+#define MX6SL_PAD_SD1_DAT2__FEC_RX_DATA1 0x23c 0x544 0x6fc 0x1 0x2
+#define MX6SL_PAD_SD1_DAT2__KEY_COL2 0x23c 0x544 0x73c 0x2 0x2
+#define MX6SL_PAD_SD1_DAT2__EPDC_SDCE8 0x23c 0x544 0x000 0x3 0x0
+#define MX6SL_PAD_SD1_DAT2__GPIO5_IO13 0x23c 0x544 0x000 0x5 0x0
+#define MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x240 0x548 0x000 0x0 0x0
+#define MX6SL_PAD_SD1_DAT3__FEC_TX_DATA0 0x240 0x548 0x000 0x1 0x0
+#define MX6SL_PAD_SD1_DAT3__KEY_ROW2 0x240 0x548 0x75c 0x2 0x2
+#define MX6SL_PAD_SD1_DAT3__EPDC_SDCE9 0x240 0x548 0x000 0x3 0x0
+#define MX6SL_PAD_SD1_DAT3__GPIO5_IO06 0x240 0x548 0x000 0x5 0x0
+#define MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x244 0x54c 0x000 0x0 0x0
+#define MX6SL_PAD_SD1_DAT4__FEC_MDC 0x244 0x54c 0x000 0x1 0x0
+#define MX6SL_PAD_SD1_DAT4__KEY_COL3 0x244 0x54c 0x740 0x2 0x2
+#define MX6SL_PAD_SD1_DAT4__EPDC_SDCLK_N 0x244 0x54c 0x000 0x3 0x0
+#define MX6SL_PAD_SD1_DAT4__UART4_RX_DATA 0x244 0x54c 0x814 0x4 0x4
+#define MX6SL_PAD_SD1_DAT4__UART4_TX_DATA 0x244 0x54c 0x000 0x4 0x0
+#define MX6SL_PAD_SD1_DAT4__GPIO5_IO12 0x244 0x54c 0x000 0x5 0x0
+#define MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x248 0x550 0x000 0x0 0x0
+#define MX6SL_PAD_SD1_DAT5__FEC_RX_DATA0 0x248 0x550 0x6f8 0x1 0x2
+#define MX6SL_PAD_SD1_DAT5__KEY_ROW3 0x248 0x550 0x760 0x2 0x2
+#define MX6SL_PAD_SD1_DAT5__EPDC_SDOED 0x248 0x550 0x000 0x3 0x0
+#define MX6SL_PAD_SD1_DAT5__UART4_TX_DATA 0x248 0x550 0x000 0x4 0x0
+#define MX6SL_PAD_SD1_DAT5__UART4_RX_DATA 0x248 0x550 0x814 0x4 0x5
+#define MX6SL_PAD_SD1_DAT5__GPIO5_IO09 0x248 0x550 0x000 0x5 0x0
+#define MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x24c 0x554 0x000 0x0 0x0
+#define MX6SL_PAD_SD1_DAT6__FEC_TX_EN 0x24c 0x554 0x000 0x1 0x0
+#define MX6SL_PAD_SD1_DAT6__KEY_COL4 0x24c 0x554 0x744 0x2 0x2
+#define MX6SL_PAD_SD1_DAT6__EPDC_SDOEZ 0x24c 0x554 0x000 0x3 0x0
+#define MX6SL_PAD_SD1_DAT6__UART4_RTS_B 0x24c 0x554 0x810 0x4 0x4
+#define MX6SL_PAD_SD1_DAT6__UART4_CTS_B 0x24c 0x554 0x000 0x4 0x0
+#define MX6SL_PAD_SD1_DAT6__GPIO5_IO07 0x24c 0x554 0x000 0x5 0x0
+#define MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x250 0x558 0x000 0x0 0x0
+#define MX6SL_PAD_SD1_DAT7__FEC_TX_DATA1 0x250 0x558 0x000 0x1 0x0
+#define MX6SL_PAD_SD1_DAT7__KEY_ROW4 0x250 0x558 0x764 0x2 0x2
+#define MX6SL_PAD_SD1_DAT7__CCM_PMIC_READY 0x250 0x558 0x62c 0x3 0x3
+#define MX6SL_PAD_SD1_DAT7__UART4_CTS_B 0x250 0x558 0x000 0x4 0x0
+#define MX6SL_PAD_SD1_DAT7__UART4_RTS_B 0x250 0x558 0x810 0x4 0x5
+#define MX6SL_PAD_SD1_DAT7__GPIO5_IO10 0x250 0x558 0x000 0x5 0x0
+#define MX6SL_PAD_SD2_CLK__SD2_CLK 0x254 0x55c 0x000 0x0 0x0
+#define MX6SL_PAD_SD2_CLK__AUD4_RXFS 0x254 0x55c 0x5f0 0x1 0x2
+#define MX6SL_PAD_SD2_CLK__ECSPI3_SCLK 0x254 0x55c 0x6b0 0x2 0x2
+#define MX6SL_PAD_SD2_CLK__CSI_DATA00 0x254 0x55c 0x630 0x3 0x2
+#define MX6SL_PAD_SD2_CLK__GPIO5_IO05 0x254 0x55c 0x000 0x5 0x0
+#define MX6SL_PAD_SD2_CMD__SD2_CMD 0x258 0x560 0x000 0x0 0x0
+#define MX6SL_PAD_SD2_CMD__AUD4_RXC 0x258 0x560 0x5ec 0x1 0x2
+#define MX6SL_PAD_SD2_CMD__ECSPI3_SS0 0x258 0x560 0x6c0 0x2 0x2
+#define MX6SL_PAD_SD2_CMD__CSI_DATA01 0x258 0x560 0x634 0x3 0x2
+#define MX6SL_PAD_SD2_CMD__EPIT1_OUT 0x258 0x560 0x000 0x4 0x0
+#define MX6SL_PAD_SD2_CMD__GPIO5_IO04 0x258 0x560 0x000 0x5 0x0
+#define MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x25c 0x564 0x000 0x0 0x0
+#define MX6SL_PAD_SD2_DAT0__AUD4_RXD 0x25c 0x564 0x5e4 0x1 0x2
+#define MX6SL_PAD_SD2_DAT0__ECSPI3_MOSI 0x25c 0x564 0x6bc 0x2 0x2
+#define MX6SL_PAD_SD2_DAT0__CSI_DATA02 0x25c 0x564 0x638 0x3 0x2
+#define MX6SL_PAD_SD2_DAT0__UART5_RTS_B 0x25c 0x564 0x818 0x4 0x4
+#define MX6SL_PAD_SD2_DAT0__UART5_CTS_B 0x25c 0x564 0x000 0x4 0x0
+#define MX6SL_PAD_SD2_DAT0__GPIO5_IO01 0x25c 0x564 0x000 0x5 0x0
+#define MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x260 0x568 0x000 0x0 0x0
+#define MX6SL_PAD_SD2_DAT1__AUD4_TXC 0x260 0x568 0x5f4 0x1 0x2
+#define MX6SL_PAD_SD2_DAT1__ECSPI3_MISO 0x260 0x568 0x6b8 0x2 0x2
+#define MX6SL_PAD_SD2_DAT1__CSI_DATA03 0x260 0x568 0x63c 0x3 0x2
+#define MX6SL_PAD_SD2_DAT1__UART5_CTS_B 0x260 0x568 0x000 0x4 0x0
+#define MX6SL_PAD_SD2_DAT1__UART5_RTS_B 0x260 0x568 0x818 0x4 0x5
+#define MX6SL_PAD_SD2_DAT1__GPIO4_IO30 0x260 0x568 0x000 0x5 0x0
+#define MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x264 0x56c 0x000 0x0 0x0
+#define MX6SL_PAD_SD2_DAT2__AUD4_TXFS 0x264 0x56c 0x5f8 0x1 0x2
+#define MX6SL_PAD_SD2_DAT2__FEC_COL 0x264 0x56c 0x6f0 0x2 0x1
+#define MX6SL_PAD_SD2_DAT2__CSI_DATA04 0x264 0x56c 0x640 0x3 0x2
+#define MX6SL_PAD_SD2_DAT2__UART5_RX_DATA 0x264 0x56c 0x81c 0x4 0x4
+#define MX6SL_PAD_SD2_DAT2__UART5_TX_DATA 0x264 0x56c 0x000 0x4 0x0
+#define MX6SL_PAD_SD2_DAT2__GPIO5_IO03 0x264 0x56c 0x000 0x5 0x0
+#define MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x268 0x570 0x000 0x0 0x0
+#define MX6SL_PAD_SD2_DAT3__AUD4_TXD 0x268 0x570 0x5e8 0x1 0x2
+#define MX6SL_PAD_SD2_DAT3__FEC_RX_CLK 0x268 0x570 0x700 0x2 0x1
+#define MX6SL_PAD_SD2_DAT3__CSI_DATA05 0x268 0x570 0x644 0x3 0x2
+#define MX6SL_PAD_SD2_DAT3__UART5_TX_DATA 0x268 0x570 0x000 0x4 0x0
+#define MX6SL_PAD_SD2_DAT3__UART5_RX_DATA 0x268 0x570 0x81c 0x4 0x5
+#define MX6SL_PAD_SD2_DAT3__GPIO4_IO28 0x268 0x570 0x000 0x5 0x0
+#define MX6SL_PAD_SD2_DAT4__SD2_DATA4 0x26c 0x574 0x000 0x0 0x0
+#define MX6SL_PAD_SD2_DAT4__SD3_DATA4 0x26c 0x574 0x83c 0x1 0x1
+#define MX6SL_PAD_SD2_DAT4__UART2_RX_DATA 0x26c 0x574 0x804 0x2 0x4
+#define MX6SL_PAD_SD2_DAT4__UART2_TX_DATA 0x26c 0x574 0x000 0x2 0x0
+#define MX6SL_PAD_SD2_DAT4__CSI_DATA06 0x26c 0x574 0x648 0x3 0x2
+#define MX6SL_PAD_SD2_DAT4__SPDIF_OUT 0x26c 0x574 0x000 0x4 0x0
+#define MX6SL_PAD_SD2_DAT4__GPIO5_IO02 0x26c 0x574 0x000 0x5 0x0
+#define MX6SL_PAD_SD2_DAT5__SD2_DATA5 0x270 0x578 0x000 0x0 0x0
+#define MX6SL_PAD_SD2_DAT5__SD3_DATA5 0x270 0x578 0x840 0x1 0x1
+#define MX6SL_PAD_SD2_DAT5__UART2_TX_DATA 0x270 0x578 0x000 0x2 0x0
+#define MX6SL_PAD_SD2_DAT5__UART2_RX_DATA 0x270 0x578 0x804 0x2 0x5
+#define MX6SL_PAD_SD2_DAT5__CSI_DATA07 0x270 0x578 0x64c 0x3 0x2
+#define MX6SL_PAD_SD2_DAT5__SPDIF_IN 0x270 0x578 0x7f0 0x4 0x2
+#define MX6SL_PAD_SD2_DAT5__GPIO4_IO31 0x270 0x578 0x000 0x5 0x0
+#define MX6SL_PAD_SD2_DAT6__SD2_DATA6 0x274 0x57c 0x000 0x0 0x0
+#define MX6SL_PAD_SD2_DAT6__SD3_DATA6 0x274 0x57c 0x844 0x1 0x1
+#define MX6SL_PAD_SD2_DAT6__UART2_RTS_B 0x274 0x57c 0x800 0x2 0x4
+#define MX6SL_PAD_SD2_DAT6__UART2_CTS_B 0x274 0x57c 0x000 0x2 0x0
+#define MX6SL_PAD_SD2_DAT6__CSI_DATA08 0x274 0x57c 0x650 0x3 0x2
+#define MX6SL_PAD_SD2_DAT6__SD2_WP 0x274 0x57c 0x834 0x4 0x2
+#define MX6SL_PAD_SD2_DAT6__GPIO4_IO29 0x274 0x57c 0x000 0x5 0x0
+#define MX6SL_PAD_SD2_DAT7__SD2_DATA7 0x278 0x580 0x000 0x0 0x0
+#define MX6SL_PAD_SD2_DAT7__SD3_DATA7 0x278 0x580 0x848 0x1 0x1
+#define MX6SL_PAD_SD2_DAT7__UART2_CTS_B 0x278 0x580 0x000 0x2 0x0
+#define MX6SL_PAD_SD2_DAT7__UART2_RTS_B 0x278 0x580 0x800 0x2 0x5
+#define MX6SL_PAD_SD2_DAT7__CSI_DATA09 0x278 0x580 0x654 0x3 0x2
+#define MX6SL_PAD_SD2_DAT7__SD2_CD_B 0x278 0x580 0x830 0x4 0x2
+#define MX6SL_PAD_SD2_DAT7__GPIO5_IO00 0x278 0x580 0x000 0x5 0x0
+#define MX6SL_PAD_SD2_RST__SD2_RESET 0x27c 0x584 0x000 0x0 0x0
+#define MX6SL_PAD_SD2_RST__FEC_REF_OUT 0x27c 0x584 0x000 0x1 0x0
+#define MX6SL_PAD_SD2_RST__WDOG2_B 0x27c 0x584 0x000 0x2 0x0
+#define MX6SL_PAD_SD2_RST__SPDIF_OUT 0x27c 0x584 0x000 0x3 0x0
+#define MX6SL_PAD_SD2_RST__CSI_MCLK 0x27c 0x584 0x000 0x4 0x0
+#define MX6SL_PAD_SD2_RST__GPIO4_IO27 0x27c 0x584 0x000 0x5 0x0
+#define MX6SL_PAD_SD3_CLK__SD3_CLK 0x280 0x588 0x000 0x0 0x0
+#define MX6SL_PAD_SD3_CLK__AUD5_RXFS 0x280 0x588 0x608 0x1 0x1
+#define MX6SL_PAD_SD3_CLK__KEY_COL5 0x280 0x588 0x748 0x2 0x2
+#define MX6SL_PAD_SD3_CLK__CSI_DATA10 0x280 0x588 0x658 0x3 0x2
+#define MX6SL_PAD_SD3_CLK__WDOG1_RESET_B_DEB 0x280 0x588 0x000 0x4 0x0
+#define MX6SL_PAD_SD3_CLK__GPIO5_IO18 0x280 0x588 0x000 0x5 0x0
+#define MX6SL_PAD_SD3_CLK__USB_OTG1_PWR 0x280 0x588 0x000 0x6 0x0
+#define MX6SL_PAD_SD3_CMD__SD3_CMD 0x284 0x58c 0x000 0x0 0x0
+#define MX6SL_PAD_SD3_CMD__AUD5_RXC 0x284 0x58c 0x604 0x1 0x1
+#define MX6SL_PAD_SD3_CMD__KEY_ROW5 0x284 0x58c 0x768 0x2 0x2
+#define MX6SL_PAD_SD3_CMD__CSI_DATA11 0x284 0x58c 0x65c 0x3 0x2
+#define MX6SL_PAD_SD3_CMD__USB_OTG2_ID 0x284 0x58c 0x5e0 0x4 0x3
+#define MX6SL_PAD_SD3_CMD__GPIO5_IO21 0x284 0x58c 0x000 0x5 0x0
+#define MX6SL_PAD_SD3_CMD__USB_OTG2_PWR 0x284 0x58c 0x000 0x6 0x0
+#define MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x288 0x590 0x000 0x0 0x0
+#define MX6SL_PAD_SD3_DAT0__AUD5_RXD 0x288 0x590 0x5fc 0x1 0x1
+#define MX6SL_PAD_SD3_DAT0__KEY_COL6 0x288 0x590 0x74c 0x2 0x2
+#define MX6SL_PAD_SD3_DAT0__CSI_DATA12 0x288 0x590 0x660 0x3 0x1
+#define MX6SL_PAD_SD3_DAT0__USB_OTG1_ID 0x288 0x590 0x5dc 0x4 0x4
+#define MX6SL_PAD_SD3_DAT0__GPIO5_IO19 0x288 0x590 0x000 0x5 0x0
+#define MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x28c 0x594 0x000 0x0 0x0
+#define MX6SL_PAD_SD3_DAT1__AUD5_TXC 0x28c 0x594 0x60c 0x1 0x1
+#define MX6SL_PAD_SD3_DAT1__KEY_ROW6 0x28c 0x594 0x76c 0x2 0x2
+#define MX6SL_PAD_SD3_DAT1__CSI_DATA13 0x28c 0x594 0x664 0x3 0x1
+#define MX6SL_PAD_SD3_DAT1__SD1_VSELECT 0x28c 0x594 0x000 0x4 0x0
+#define MX6SL_PAD_SD3_DAT1__GPIO5_IO20 0x28c 0x594 0x000 0x5 0x0
+#define MX6SL_PAD_SD3_DAT1__JTAG_DE_B 0x28c 0x594 0x000 0x6 0x0
+#define MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x290 0x598 0x000 0x0 0x0
+#define MX6SL_PAD_SD3_DAT2__AUD5_TXFS 0x290 0x598 0x610 0x1 0x1
+#define MX6SL_PAD_SD3_DAT2__KEY_COL7 0x290 0x598 0x750 0x2 0x2
+#define MX6SL_PAD_SD3_DAT2__CSI_DATA14 0x290 0x598 0x668 0x3 0x1
+#define MX6SL_PAD_SD3_DAT2__EPIT1_OUT 0x290 0x598 0x000 0x4 0x0
+#define MX6SL_PAD_SD3_DAT2__GPIO5_IO16 0x290 0x598 0x000 0x5 0x0
+#define MX6SL_PAD_SD3_DAT2__USB_OTG2_OC 0x290 0x598 0x820 0x6 0x3
+#define MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x294 0x59c 0x000 0x0 0x0
+#define MX6SL_PAD_SD3_DAT3__AUD5_TXD 0x294 0x59c 0x600 0x1 0x1
+#define MX6SL_PAD_SD3_DAT3__KEY_ROW7 0x294 0x59c 0x770 0x2 0x2
+#define MX6SL_PAD_SD3_DAT3__CSI_DATA15 0x294 0x59c 0x66c 0x3 0x1
+#define MX6SL_PAD_SD3_DAT3__EPIT2_OUT 0x294 0x59c 0x000 0x4 0x0
+#define MX6SL_PAD_SD3_DAT3__GPIO5_IO17 0x294 0x59c 0x000 0x5 0x0
+#define MX6SL_PAD_SD3_DAT3__USB_OTG1_OC 0x294 0x59c 0x824 0x6 0x2
+#define MX6SL_PAD_UART1_RXD__UART1_RX_DATA 0x298 0x5a0 0x7fc 0x0 0x0
+#define MX6SL_PAD_UART1_RXD__UART1_TX_DATA 0x298 0x5a0 0x000 0x0 0x0
+#define MX6SL_PAD_UART1_RXD__PWM1_OUT 0x298 0x5a0 0x000 0x1 0x0
+#define MX6SL_PAD_UART1_RXD__UART4_RX_DATA 0x298 0x5a0 0x814 0x2 0x6
+#define MX6SL_PAD_UART1_RXD__UART4_TX_DATA 0x298 0x5a0 0x000 0x2 0x0
+#define MX6SL_PAD_UART1_RXD__FEC_COL 0x298 0x5a0 0x6f0 0x3 0x2
+#define MX6SL_PAD_UART1_RXD__UART5_RX_DATA 0x298 0x5a0 0x81c 0x4 0x6
+#define MX6SL_PAD_UART1_RXD__UART5_TX_DATA 0x298 0x5a0 0x000 0x4 0x0
+#define MX6SL_PAD_UART1_RXD__GPIO3_IO16 0x298 0x5a0 0x000 0x5 0x0
+#define MX6SL_PAD_UART1_TXD__UART1_TX_DATA 0x29c 0x5a4 0x000 0x0 0x0
+#define MX6SL_PAD_UART1_TXD__UART1_RX_DATA 0x29c 0x5a4 0x7fc 0x0 0x1
+#define MX6SL_PAD_UART1_TXD__PWM2_OUT 0x29c 0x5a4 0x000 0x1 0x0
+#define MX6SL_PAD_UART1_TXD__UART4_TX_DATA 0x29c 0x5a4 0x000 0x2 0x0
+#define MX6SL_PAD_UART1_TXD__UART4_RX_DATA 0x29c 0x5a4 0x814 0x2 0x7
+#define MX6SL_PAD_UART1_TXD__FEC_RX_CLK 0x29c 0x5a4 0x700 0x3 0x2
+#define MX6SL_PAD_UART1_TXD__UART5_TX_DATA 0x29c 0x5a4 0x000 0x4 0x0
+#define MX6SL_PAD_UART1_TXD__UART5_RX_DATA 0x29c 0x5a4 0x81c 0x4 0x7
+#define MX6SL_PAD_UART1_TXD__GPIO3_IO17 0x29c 0x5a4 0x000 0x5 0x0
+#define MX6SL_PAD_UART1_TXD__UART5_DCD_B 0x29c 0x5a4 0x000 0x7 0x0
+#define MX6SL_PAD_WDOG_B__WDOG1_B 0x2a0 0x5a8 0x000 0x0 0x0
+#define MX6SL_PAD_WDOG_B__WDOG1_RESET_B_DEB 0x2a0 0x5a8 0x000 0x1 0x0
+#define MX6SL_PAD_WDOG_B__UART5_RI_B 0x2a0 0x5a8 0x000 0x2 0x0
+#define MX6SL_PAD_WDOG_B__GPIO3_IO18 0x2a0 0x5a8 0x000 0x5 0x0
+
+#endif /* __DTS_IMX6SL_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx6sl-warp.dts b/arch/arm/boot/dts/imx6sl-warp.dts
new file mode 100644
index 000000000..64f7decf1
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sl-warp.dts
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2014, 2015 O.S. Systems Software LTDA.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "imx6sl.dtsi"
+
+/ {
+ model = "WaRP Board";
+ compatible = "warp,imx6sl-warp", "fsl,imx6sl";
+
+ memory {
+ reg = <0x80000000 0x20000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb_otg1_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 0 0>;
+ enable-active-high;
+ };
+
+ reg_usb_otg2_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb_otg2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 2 0>;
+ enable-active-high;
+ };
+
+ reg_1p8v: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "1P8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+
+ usdhc3_pwrseq: usdhc3_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio4 5 GPIO_ACTIVE_LOW>, /* WL_REG_ON */
+ <&gpio3 25 GPIO_ACTIVE_LOW>, /* BT_REG_ON */
+ <&gpio4 4 GPIO_ACTIVE_LOW>, /* BT_WAKE */
+ <&gpio4 6 GPIO_ACTIVE_LOW>; /* BT_RST_N */
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ dr_mode = "host";
+ disable-over-current;
+ status = "okay";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usb_otg2_vbus>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ bus-width = <4>;
+ non-removable;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ mmc-pwrseq = <&usdhc3_pwrseq>;
+ status = "okay";
+};
+
+&iomuxc {
+ imx6sl-warp {
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6SL_PAD_UART1_RXD__UART1_RX_DATA 0x41b0b1
+ MX6SL_PAD_UART1_TXD__UART1_TX_DATA 0x41b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6SL_PAD_EPDC_D12__UART2_RX_DATA 0x41b0b1
+ MX6SL_PAD_EPDC_D13__UART2_TX_DATA 0x41b0b1
+ MX6SL_PAD_EPDC_D14__UART2_RTS_B 0x4130B1
+ MX6SL_PAD_EPDC_D15__UART2_CTS_B 0x4130B1
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX6SL_PAD_AUD_RXC__UART3_RX_DATA 0x41b0b1
+ MX6SL_PAD_AUD_RXC__UART3_TX_DATA 0x41b0b1
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6SL_PAD_SD2_CMD__SD2_CMD 0x417059
+ MX6SL_PAD_SD2_CLK__SD2_CLK 0x410059
+ MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x417059
+ MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x417059
+ MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x417059
+ MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x417059
+ MX6SL_PAD_SD2_DAT4__SD2_DATA4 0x417059
+ MX6SL_PAD_SD2_DAT5__SD2_DATA5 0x417059
+ MX6SL_PAD_SD2_DAT6__SD2_DATA6 0x417059
+ MX6SL_PAD_SD2_DAT7__SD2_DATA7 0x417059
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ MX6SL_PAD_SD2_CMD__SD2_CMD 0x4170b9
+ MX6SL_PAD_SD2_CLK__SD2_CLK 0x4100b9
+ MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x4170b9
+ MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x4170b9
+ MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x4170b9
+ MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x4170b9
+ MX6SL_PAD_SD2_DAT4__SD2_DATA4 0x4170b9
+ MX6SL_PAD_SD2_DAT5__SD2_DATA5 0x4170b9
+ MX6SL_PAD_SD2_DAT6__SD2_DATA6 0x4170b9
+ MX6SL_PAD_SD2_DAT7__SD2_DATA7 0x4170b9
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ MX6SL_PAD_SD2_CMD__SD2_CMD 0x4170f9
+ MX6SL_PAD_SD2_CLK__SD2_CLK 0x4100f9
+ MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x4170f9
+ MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x4170f9
+ MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x4170f9
+ MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x4170f9
+ MX6SL_PAD_SD2_DAT4__SD2_DATA4 0x4170f9
+ MX6SL_PAD_SD2_DAT5__SD2_DATA5 0x4170f9
+ MX6SL_PAD_SD2_DAT6__SD2_DATA6 0x4170f9
+ MX6SL_PAD_SD2_DAT7__SD2_DATA7 0x4170f9
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6SL_PAD_SD3_CMD__SD3_CMD 0x417059
+ MX6SL_PAD_SD3_CLK__SD3_CLK 0x410059
+ MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x417059
+ MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x417059
+ MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x417059
+ MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x417059
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+ fsl,pins = <
+ MX6SL_PAD_SD3_CMD__SD3_CMD 0x4170b9
+ MX6SL_PAD_SD3_CLK__SD3_CLK 0x4100b9
+ MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x4170b9
+ MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x4170b9
+ MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x4170b9
+ MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x4170b9
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+ fsl,pins = <
+ MX6SL_PAD_SD3_CMD__SD3_CMD 0x4170f9
+ MX6SL_PAD_SD3_CLK__SD3_CLK 0x4100f9
+ MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x4170f9
+ MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x4170f9
+ MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x4170f9
+ MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x4170f9
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
new file mode 100644
index 000000000..1157f2d58
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -0,0 +1,836 @@
+/*
+ * Copyright 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "skeleton.dtsi"
+#include "imx6sl-pinfunc.h"
+#include <dt-bindings/clock/imx6sl-clock.h>
+
+/ {
+ aliases {
+ ethernet0 = &fec;
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ gpio4 = &gpio5;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ spi0 = &ecspi1;
+ spi1 = &ecspi2;
+ spi2 = &ecspi3;
+ spi3 = &ecspi4;
+ usbphy0 = &usbphy1;
+ usbphy1 = &usbphy2;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0x0>;
+ next-level-cache = <&L2>;
+ operating-points = <
+ /* kHz uV */
+ 996000 1275000
+ 792000 1175000
+ 396000 975000
+ >;
+ fsl,soc-operating-points = <
+ /* ARM kHz SOC-PU uV */
+ 996000 1225000
+ 792000 1175000
+ 396000 1175000
+ >;
+ clock-latency = <61036>; /* two CLK32 periods */
+ clocks = <&clks IMX6SL_CLK_ARM>, <&clks IMX6SL_CLK_PLL2_PFD2>,
+ <&clks IMX6SL_CLK_STEP>, <&clks IMX6SL_CLK_PLL1_SW>,
+ <&clks IMX6SL_CLK_PLL1_SYS>;
+ clock-names = "arm", "pll2_pfd2_396m", "step",
+ "pll1_sw", "pll1_sys";
+ arm-supply = <&reg_arm>;
+ pu-supply = <&reg_pu>;
+ soc-supply = <&reg_soc>;
+ };
+ };
+
+ intc: interrupt-controller@00a01000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x00a01000 0x1000>,
+ <0x00a00100 0x100>;
+ interrupt-parent = <&intc>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ckil {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+
+ osc {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&gpc>;
+ ranges;
+
+ ocram: sram@00900000 {
+ compatible = "mmio-sram";
+ reg = <0x00900000 0x20000>;
+ clocks = <&clks IMX6SL_CLK_OCRAM>;
+ };
+
+ L2: l2-cache@00a02000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x00a02000 0x1000>;
+ interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
+ cache-unified;
+ cache-level = <2>;
+ arm,tag-latency = <4 2 3>;
+ arm,data-latency = <4 2 3>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ aips1: aips-bus@02000000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02000000 0x100000>;
+ ranges;
+
+ spba: spba-bus@02000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02000000 0x40000>;
+ ranges;
+
+ spdif: spdif@02004000 {
+ reg = <0x02004000 0x4000>;
+ interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ ecspi1: ecspi@02008000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02008000 0x4000>;
+ interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_ECSPI1>,
+ <&clks IMX6SL_CLK_ECSPI1>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi2: ecspi@0200c000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
+ reg = <0x0200c000 0x4000>;
+ interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_ECSPI2>,
+ <&clks IMX6SL_CLK_ECSPI2>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi3: ecspi@02010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02010000 0x4000>;
+ interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_ECSPI3>,
+ <&clks IMX6SL_CLK_ECSPI3>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi4: ecspi@02014000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02014000 0x4000>;
+ interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_ECSPI4>,
+ <&clks IMX6SL_CLK_ECSPI4>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart5: serial@02018000 {
+ compatible = "fsl,imx6sl-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02018000 0x4000>;
+ interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_UART>,
+ <&clks IMX6SL_CLK_UART_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 33 4 0>, <&sdma 34 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart1: serial@02020000 {
+ compatible = "fsl,imx6sl-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02020000 0x4000>;
+ interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_UART>,
+ <&clks IMX6SL_CLK_UART_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 25 4 0>, <&sdma 26 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart2: serial@02024000 {
+ compatible = "fsl,imx6sl-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02024000 0x4000>;
+ interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_UART>,
+ <&clks IMX6SL_CLK_UART_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 27 4 0>, <&sdma 28 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ ssi1: ssi@02028000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx6sl-ssi",
+ "fsl,imx51-ssi";
+ reg = <0x02028000 0x4000>;
+ interrupts = <0 46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_SSI1_IPG>,
+ <&clks IMX6SL_CLK_SSI1>;
+ clock-names = "ipg", "baud";
+ dmas = <&sdma 37 1 0>,
+ <&sdma 38 1 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ ssi2: ssi@0202c000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx6sl-ssi",
+ "fsl,imx51-ssi";
+ reg = <0x0202c000 0x4000>;
+ interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_SSI2_IPG>,
+ <&clks IMX6SL_CLK_SSI2>;
+ clock-names = "ipg", "baud";
+ dmas = <&sdma 41 1 0>,
+ <&sdma 42 1 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ ssi3: ssi@02030000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx6sl-ssi",
+ "fsl,imx51-ssi";
+ reg = <0x02030000 0x4000>;
+ interrupts = <0 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_SSI3_IPG>,
+ <&clks IMX6SL_CLK_SSI3>;
+ clock-names = "ipg", "baud";
+ dmas = <&sdma 45 1 0>,
+ <&sdma 46 1 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ uart3: serial@02034000 {
+ compatible = "fsl,imx6sl-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02034000 0x4000>;
+ interrupts = <0 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_UART>,
+ <&clks IMX6SL_CLK_UART_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 29 4 0>, <&sdma 30 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart4: serial@02038000 {
+ compatible = "fsl,imx6sl-uart",
+ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02038000 0x4000>;
+ interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_UART>,
+ <&clks IMX6SL_CLK_UART_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 31 4 0>, <&sdma 32 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ };
+
+ pwm1: pwm@02080000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
+ reg = <0x02080000 0x4000>;
+ interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_PWM1>,
+ <&clks IMX6SL_CLK_PWM1>;
+ clock-names = "ipg", "per";
+ };
+
+ pwm2: pwm@02084000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
+ reg = <0x02084000 0x4000>;
+ interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_PWM2>,
+ <&clks IMX6SL_CLK_PWM2>;
+ clock-names = "ipg", "per";
+ };
+
+ pwm3: pwm@02088000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
+ reg = <0x02088000 0x4000>;
+ interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_PWM3>,
+ <&clks IMX6SL_CLK_PWM3>;
+ clock-names = "ipg", "per";
+ };
+
+ pwm4: pwm@0208c000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
+ reg = <0x0208c000 0x4000>;
+ interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_PWM4>,
+ <&clks IMX6SL_CLK_PWM4>;
+ clock-names = "ipg", "per";
+ };
+
+ gpt: gpt@02098000 {
+ compatible = "fsl,imx6sl-gpt";
+ reg = <0x02098000 0x4000>;
+ interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_GPT>,
+ <&clks IMX6SL_CLK_GPT_SERIAL>;
+ clock-names = "ipg", "per";
+ };
+
+ gpio1: gpio@0209c000 {
+ compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
+ reg = <0x0209c000 0x4000>;
+ interrupts = <0 66 IRQ_TYPE_LEVEL_HIGH>,
+ <0 67 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@020a0000 {
+ compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
+ reg = <0x020a0000 0x4000>;
+ interrupts = <0 68 IRQ_TYPE_LEVEL_HIGH>,
+ <0 69 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@020a4000 {
+ compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
+ reg = <0x020a4000 0x4000>;
+ interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>,
+ <0 71 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@020a8000 {
+ compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
+ reg = <0x020a8000 0x4000>;
+ interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>,
+ <0 73 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio5: gpio@020ac000 {
+ compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
+ reg = <0x020ac000 0x4000>;
+ interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>,
+ <0 75 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ kpp: kpp@020b8000 {
+ compatible = "fsl,imx6sl-kpp", "fsl,imx21-kpp";
+ reg = <0x020b8000 0x4000>;
+ interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_DUMMY>;
+ status = "disabled";
+ };
+
+ wdog1: wdog@020bc000 {
+ compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt";
+ reg = <0x020bc000 0x4000>;
+ interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_DUMMY>;
+ };
+
+ wdog2: wdog@020c0000 {
+ compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt";
+ reg = <0x020c0000 0x4000>;
+ interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_DUMMY>;
+ status = "disabled";
+ };
+
+ clks: ccm@020c4000 {
+ compatible = "fsl,imx6sl-ccm";
+ reg = <0x020c4000 0x4000>;
+ interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>,
+ <0 88 IRQ_TYPE_LEVEL_HIGH>;
+ #clock-cells = <1>;
+ };
+
+ anatop: anatop@020c8000 {
+ compatible = "fsl,imx6sl-anatop",
+ "fsl,imx6q-anatop",
+ "syscon", "simple-bus";
+ reg = <0x020c8000 0x1000>;
+ interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
+ <0 54 IRQ_TYPE_LEVEL_HIGH>,
+ <0 127 IRQ_TYPE_LEVEL_HIGH>;
+
+ regulator-1p1@110 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd1p1";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1375000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x110>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <4>;
+ anatop-min-voltage = <800000>;
+ anatop-max-voltage = <1375000>;
+ };
+
+ regulator-3p0@120 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd3p0";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3150000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x120>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <0>;
+ anatop-min-voltage = <2625000>;
+ anatop-max-voltage = <3400000>;
+ };
+
+ regulator-2p5@130 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd2p5";
+ regulator-min-microvolt = <2100000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x130>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <0>;
+ anatop-min-voltage = <2100000>;
+ anatop-max-voltage = <2850000>;
+ };
+
+ reg_arm: regulator-vddcore@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vddarm";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <0>;
+ anatop-vol-bit-width = <5>;
+ anatop-delay-reg-offset = <0x170>;
+ anatop-delay-bit-shift = <24>;
+ anatop-delay-bit-width = <2>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
+
+ reg_pu: regulator-vddpu@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vddpu";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <9>;
+ anatop-vol-bit-width = <5>;
+ anatop-delay-reg-offset = <0x170>;
+ anatop-delay-bit-shift = <26>;
+ anatop-delay-bit-width = <2>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
+
+ reg_soc: regulator-vddsoc@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vddsoc";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <18>;
+ anatop-vol-bit-width = <5>;
+ anatop-delay-reg-offset = <0x170>;
+ anatop-delay-bit-shift = <28>;
+ anatop-delay-bit-width = <2>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
+ };
+
+ tempmon: tempmon {
+ compatible = "fsl,imx6q-tempmon";
+ interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,tempmon = <&anatop>;
+ fsl,tempmon-data = <&ocotp>;
+ clocks = <&clks IMX6SL_CLK_PLL3_USB_OTG>;
+ };
+
+ usbphy1: usbphy@020c9000 {
+ compatible = "fsl,imx6sl-usbphy", "fsl,imx23-usbphy";
+ reg = <0x020c9000 0x1000>;
+ interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_USBPHY1>;
+ fsl,anatop = <&anatop>;
+ };
+
+ usbphy2: usbphy@020ca000 {
+ compatible = "fsl,imx6sl-usbphy", "fsl,imx23-usbphy";
+ reg = <0x020ca000 0x1000>;
+ interrupts = <0 45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_USBPHY2>;
+ fsl,anatop = <&anatop>;
+ };
+
+ snvs@020cc000 {
+ compatible = "fsl,sec-v4.0-mon", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x020cc000 0x4000>;
+
+ snvs_rtc: snvs-rtc-lp@34 {
+ compatible = "fsl,sec-v4.0-mon-rtc-lp";
+ reg = <0x34 0x58>;
+ interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>,
+ <0 20 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ snvs_poweroff: snvs-poweroff@38 {
+ compatible = "fsl,sec-v4.0-poweroff";
+ reg = <0x38 0x4>;
+ status = "disabled";
+ };
+ };
+
+ epit1: epit@020d0000 {
+ reg = <0x020d0000 0x4000>;
+ interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ epit2: epit@020d4000 {
+ reg = <0x020d4000 0x4000>;
+ interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ src: src@020d8000 {
+ compatible = "fsl,imx6sl-src", "fsl,imx51-src";
+ reg = <0x020d8000 0x4000>;
+ interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>,
+ <0 96 IRQ_TYPE_LEVEL_HIGH>;
+ #reset-cells = <1>;
+ };
+
+ gpc: gpc@020dc000 {
+ compatible = "fsl,imx6sl-gpc", "fsl,imx6q-gpc";
+ reg = <0x020dc000 0x4000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&intc>;
+ pu-supply = <&reg_pu>;
+ clocks = <&clks IMX6SL_CLK_GPU2D_OVG>,
+ <&clks IMX6SL_CLK_GPU2D_PODF>;
+ #power-domain-cells = <1>;
+ };
+
+ gpr: iomuxc-gpr@020e0000 {
+ compatible = "fsl,imx6sl-iomuxc-gpr",
+ "fsl,imx6q-iomuxc-gpr", "syscon";
+ reg = <0x020e0000 0x38>;
+ };
+
+ iomuxc: iomuxc@020e0000 {
+ compatible = "fsl,imx6sl-iomuxc";
+ reg = <0x020e0000 0x4000>;
+ };
+
+ csi: csi@020e4000 {
+ reg = <0x020e4000 0x4000>;
+ interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ spdc: spdc@020e8000 {
+ reg = <0x020e8000 0x4000>;
+ interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sdma: sdma@020ec000 {
+ compatible = "fsl,imx6sl-sdma", "fsl,imx6q-sdma";
+ reg = <0x020ec000 0x4000>;
+ interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_SDMA>,
+ <&clks IMX6SL_CLK_SDMA>;
+ clock-names = "ipg", "ahb";
+ #dma-cells = <3>;
+ /* imx6sl reuses imx6q sdma firmware */
+ fsl,sdma-ram-script-name = "/*(DEBLOBBED)*/";
+ };
+
+ pxp: pxp@020f0000 {
+ reg = <0x020f0000 0x4000>;
+ interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ epdc: epdc@020f4000 {
+ reg = <0x020f4000 0x4000>;
+ interrupts = <0 97 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ lcdif: lcdif@020f8000 {
+ compatible = "fsl,imx6sl-lcdif", "fsl,imx28-lcdif";
+ reg = <0x020f8000 0x4000>;
+ interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_LCDIF_PIX>,
+ <&clks IMX6SL_CLK_LCDIF_AXI>,
+ <&clks IMX6SL_CLK_DUMMY>;
+ clock-names = "pix", "axi", "disp_axi";
+ status = "disabled";
+ };
+
+ dcp: dcp@020fc000 {
+ reg = <0x020fc000 0x4000>;
+ interrupts = <0 99 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ aips2: aips-bus@02100000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02100000 0x100000>;
+ ranges;
+
+ usbotg1: usb@02184000 {
+ compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
+ reg = <0x02184000 0x200>;
+ interrupts = <0 43 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_USBOH3>;
+ fsl,usbphy = <&usbphy1>;
+ fsl,usbmisc = <&usbmisc 0>;
+ status = "disabled";
+ };
+
+ usbotg2: usb@02184200 {
+ compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
+ reg = <0x02184200 0x200>;
+ interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_USBOH3>;
+ fsl,usbphy = <&usbphy2>;
+ fsl,usbmisc = <&usbmisc 1>;
+ status = "disabled";
+ };
+
+ usbh: usb@02184400 {
+ compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
+ reg = <0x02184400 0x200>;
+ interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_USBOH3>;
+ fsl,usbmisc = <&usbmisc 2>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbmisc: usbmisc@02184800 {
+ #index-cells = <1>;
+ compatible = "fsl,imx6sl-usbmisc", "fsl,imx6q-usbmisc";
+ reg = <0x02184800 0x200>;
+ clocks = <&clks IMX6SL_CLK_USBOH3>;
+ };
+
+ fec: ethernet@02188000 {
+ compatible = "fsl,imx6sl-fec", "fsl,imx25-fec";
+ reg = <0x02188000 0x4000>;
+ interrupts = <0 114 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_ENET>,
+ <&clks IMX6SL_CLK_ENET_REF>;
+ clock-names = "ipg", "ahb";
+ status = "disabled";
+ };
+
+ usdhc1: usdhc@02190000 {
+ compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
+ reg = <0x02190000 0x4000>;
+ interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_USDHC1>,
+ <&clks IMX6SL_CLK_USDHC1>,
+ <&clks IMX6SL_CLK_USDHC1>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ usdhc2: usdhc@02194000 {
+ compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
+ reg = <0x02194000 0x4000>;
+ interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_USDHC2>,
+ <&clks IMX6SL_CLK_USDHC2>,
+ <&clks IMX6SL_CLK_USDHC2>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ usdhc3: usdhc@02198000 {
+ compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
+ reg = <0x02198000 0x4000>;
+ interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_USDHC3>,
+ <&clks IMX6SL_CLK_USDHC3>,
+ <&clks IMX6SL_CLK_USDHC3>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ usdhc4: usdhc@0219c000 {
+ compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
+ reg = <0x0219c000 0x4000>;
+ interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_USDHC4>,
+ <&clks IMX6SL_CLK_USDHC4>,
+ <&clks IMX6SL_CLK_USDHC4>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@021a0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
+ reg = <0x021a0000 0x4000>;
+ interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_I2C1>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@021a4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
+ reg = <0x021a4000 0x4000>;
+ interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_I2C2>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@021a8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
+ reg = <0x021a8000 0x4000>;
+ interrupts = <0 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_I2C3>;
+ status = "disabled";
+ };
+
+ mmdc: mmdc@021b0000 {
+ compatible = "fsl,imx6sl-mmdc", "fsl,imx6q-mmdc";
+ reg = <0x021b0000 0x4000>;
+ };
+
+ rngb: rngb@021b4000 {
+ reg = <0x021b4000 0x4000>;
+ interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ weim: weim@021b8000 {
+ reg = <0x021b8000 0x4000>;
+ interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ ocotp: ocotp@021bc000 {
+ compatible = "fsl,imx6sl-ocotp", "syscon";
+ reg = <0x021bc000 0x4000>;
+ };
+
+ audmux: audmux@021d8000 {
+ compatible = "fsl,imx6sl-audmux", "fsl,imx31-audmux";
+ reg = <0x021d8000 0x4000>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sx-pinfunc.h b/arch/arm/boot/dts/imx6sx-pinfunc.h
new file mode 100644
index 000000000..bb9c6b78c
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-pinfunc.h
@@ -0,0 +1,1544 @@
+/*
+ * Copyright 2014 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 __DTS_IMX6SX_PINFUNC_H
+#define __DTS_IMX6SX_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX6SX_PAD_GPIO1_IO00__I2C1_SCL 0x0014 0x035C 0x07A8 0x0 0x1
+#define MX6SX_PAD_GPIO1_IO00__USDHC1_VSELECT 0x0014 0x035C 0x0000 0x1 0x0
+#define MX6SX_PAD_GPIO1_IO00__SPDIF_LOCK 0x0014 0x035C 0x0000 0x2 0x0
+#define MX6SX_PAD_GPIO1_IO00__CCM_WAIT 0x0014 0x035C 0x0000 0x3 0x0
+#define MX6SX_PAD_GPIO1_IO00__WDOG1_WDOG_ANY 0x0014 0x035C 0x0000 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO00__GPIO1_IO_0 0x0014 0x035C 0x0000 0x5 0x0
+#define MX6SX_PAD_GPIO1_IO00__SNVS_HP_WRAPPER_VIO_5 0x0014 0x035C 0x0000 0x6 0x0
+#define MX6SX_PAD_GPIO1_IO00__PHY_DTB_1 0x0014 0x035C 0x0000 0x7 0x0
+#define MX6SX_PAD_GPIO1_IO01__I2C1_SDA 0x0018 0x0360 0x07AC 0x0 0x1
+#define MX6SX_PAD_GPIO1_IO01__USDHC1_RESET_B 0x0018 0x0360 0x0000 0x1 0x0
+#define MX6SX_PAD_GPIO1_IO01__SPDIF_SR_CLK 0x0018 0x0360 0x0000 0x2 0x0
+#define MX6SX_PAD_GPIO1_IO01__CCM_STOP 0x0018 0x0360 0x0000 0x3 0x0
+#define MX6SX_PAD_GPIO1_IO01__WDOG3_WDOG_B 0x0018 0x0360 0x0000 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO01__GPIO1_IO_1 0x0018 0x0360 0x0000 0x5 0x0
+#define MX6SX_PAD_GPIO1_IO01__SNVS_HP_WRAPPER_VIO_5_CTL 0x0018 0x0360 0x0000 0x6 0x0
+#define MX6SX_PAD_GPIO1_IO01__PHY_DTB_0 0x0018 0x0360 0x0000 0x7 0x0
+#define MX6SX_PAD_GPIO1_IO02__I2C2_SCL 0x001C 0x0364 0x07B0 0x0 0x1
+#define MX6SX_PAD_GPIO1_IO02__USDHC1_CD_B 0x001C 0x0364 0x0864 0x1 0x1
+#define MX6SX_PAD_GPIO1_IO02__CSI2_MCLK 0x001C 0x0364 0x0000 0x2 0x0
+#define MX6SX_PAD_GPIO1_IO02__CCM_DI0_EXT_CLK 0x001C 0x0364 0x0000 0x3 0x0
+#define MX6SX_PAD_GPIO1_IO02__WDOG1_WDOG_B 0x001C 0x0364 0x0000 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO02__GPIO1_IO_2 0x001C 0x0364 0x0000 0x5 0x0
+#define MX6SX_PAD_GPIO1_IO02__CCM_REF_EN_B 0x001C 0x0364 0x0000 0x6 0x0
+#define MX6SX_PAD_GPIO1_IO02__PHY_TDI 0x001C 0x0364 0x0000 0x7 0x0
+#define MX6SX_PAD_GPIO1_IO03__I2C2_SDA 0x0020 0x0368 0x07B4 0x0 0x1
+#define MX6SX_PAD_GPIO1_IO03__USDHC1_WP 0x0020 0x0368 0x0868 0x1 0x1
+#define MX6SX_PAD_GPIO1_IO03__ENET1_REF_CLK_25M 0x0020 0x0368 0x0000 0x2 0x0
+#define MX6SX_PAD_GPIO1_IO03__CCM_DI1_EXT_CLK 0x0020 0x0368 0x0000 0x3 0x0
+#define MX6SX_PAD_GPIO1_IO03__WDOG2_WDOG_B 0x0020 0x0368 0x0000 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO03__GPIO1_IO_3 0x0020 0x0368 0x0000 0x5 0x0
+#define MX6SX_PAD_GPIO1_IO03__CCM_PLL3_BYP 0x0020 0x0368 0x0000 0x6 0x0
+#define MX6SX_PAD_GPIO1_IO03__PHY_TCK 0x0020 0x0368 0x0000 0x7 0x0
+#define MX6SX_PAD_GPIO1_IO04__UART1_RX 0x0024 0x036C 0x0830 0x0 0x0
+#define MX6SX_PAD_GPIO1_IO04__UART1_TX 0x0024 0x036C 0x0000 0x0 0x0
+#define MX6SX_PAD_GPIO1_IO04__USDHC2_RESET_B 0x0024 0x036C 0x0000 0x1 0x0
+#define MX6SX_PAD_GPIO1_IO04__ENET1_MDC 0x0024 0x036C 0x0000 0x2 0x0
+#define MX6SX_PAD_GPIO1_IO04__OSC32K_32K_OUT 0x0024 0x036C 0x0000 0x3 0x0
+#define MX6SX_PAD_GPIO1_IO04__ENET2_REF_CLK2 0x0024 0x036C 0x076C 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO04__GPIO1_IO_4 0x0024 0x036C 0x0000 0x5 0x0
+#define MX6SX_PAD_GPIO1_IO04__CCM_PLL2_BYP 0x0024 0x036C 0x0000 0x6 0x0
+#define MX6SX_PAD_GPIO1_IO04__PHY_TMS 0x0024 0x036C 0x0000 0x7 0x0
+#define MX6SX_PAD_GPIO1_IO05__UART1_RX 0x0028 0x0370 0x0830 0x0 0x1
+#define MX6SX_PAD_GPIO1_IO05__UART1_TX 0x0028 0x0370 0x0000 0x0 0x0
+#define MX6SX_PAD_GPIO1_IO05__USDHC2_VSELECT 0x0028 0x0370 0x0000 0x1 0x0
+#define MX6SX_PAD_GPIO1_IO05__ENET1_MDIO 0x0028 0x0370 0x0764 0x2 0x0
+#define MX6SX_PAD_GPIO1_IO05__ASRC_ASRC_EXT_CLK 0x0028 0x0370 0x0000 0x3 0x0
+#define MX6SX_PAD_GPIO1_IO05__ENET1_REF_CLK1 0x0028 0x0370 0x0760 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO05__GPIO1_IO_5 0x0028 0x0370 0x0000 0x5 0x0
+#define MX6SX_PAD_GPIO1_IO05__SRC_TESTER_ACK 0x0028 0x0370 0x0000 0x6 0x0
+#define MX6SX_PAD_GPIO1_IO05__PHY_TDO 0x0028 0x0370 0x0000 0x7 0x0
+#define MX6SX_PAD_GPIO1_IO06__UART2_RX 0x002C 0x0374 0x0838 0x0 0x0
+#define MX6SX_PAD_GPIO1_IO06__UART2_TX 0x002C 0x0374 0x0000 0x0 0x0
+#define MX6SX_PAD_GPIO1_IO06__USDHC2_CD_B 0x002C 0x0374 0x086C 0x1 0x1
+#define MX6SX_PAD_GPIO1_IO06__ENET2_MDC 0x002C 0x0374 0x0000 0x2 0x0
+#define MX6SX_PAD_GPIO1_IO06__CSI1_MCLK 0x002C 0x0374 0x0000 0x3 0x0
+#define MX6SX_PAD_GPIO1_IO06__UART1_RTS_B 0x002C 0x0374 0x082C 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO06__GPIO1_IO_6 0x002C 0x0374 0x0000 0x5 0x0
+#define MX6SX_PAD_GPIO1_IO06__SRC_ANY_PU_RESET 0x002C 0x0374 0x0000 0x6 0x0
+#define MX6SX_PAD_GPIO1_IO06__OCOTP_CTRL_WRAPPER_FUSE_LATCHED 0x002C 0x0374 0x0000 0x7 0x0
+#define MX6SX_PAD_GPIO1_IO07__UART2_RX 0x0030 0x0378 0x0838 0x0 0x1
+#define MX6SX_PAD_GPIO1_IO07__UART2_TX 0x0030 0x0378 0x0000 0x0 0x0
+#define MX6SX_PAD_GPIO1_IO07__USDHC2_WP 0x0030 0x0378 0x0870 0x1 0x1
+#define MX6SX_PAD_GPIO1_IO07__ENET2_MDIO 0x0030 0x0378 0x0770 0x2 0x0
+#define MX6SX_PAD_GPIO1_IO07__AUDMUX_MCLK 0x0030 0x0378 0x0000 0x3 0x0
+#define MX6SX_PAD_GPIO1_IO07__UART1_CTS_B 0x0030 0x0378 0x0000 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO07__GPIO1_IO_7 0x0030 0x0378 0x0000 0x5 0x0
+#define MX6SX_PAD_GPIO1_IO07__SRC_EARLY_RESET 0x0030 0x0378 0x0000 0x6 0x0
+#define MX6SX_PAD_GPIO1_IO07__DCIC2_OUT 0x0030 0x0378 0x0000 0x7 0x0
+#define MX6SX_PAD_GPIO1_IO07__VDEC_DEBUG_44 0x0030 0x0378 0x0000 0x8 0x0
+#define MX6SX_PAD_GPIO1_IO08__USB_OTG1_OC 0x0034 0x037C 0x0860 0x0 0x0
+#define MX6SX_PAD_GPIO1_IO08__WDOG1_WDOG_B 0x0034 0x037C 0x0000 0x1 0x0
+#define MX6SX_PAD_GPIO1_IO08__SDMA_EXT_EVENT_0 0x0034 0x037C 0x081C 0x2 0x0
+#define MX6SX_PAD_GPIO1_IO08__CCM_PMIC_RDY 0x0034 0x037C 0x069C 0x3 0x1
+#define MX6SX_PAD_GPIO1_IO08__UART2_RTS_B 0x0034 0x037C 0x0834 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO08__GPIO1_IO_8 0x0034 0x037C 0x0000 0x5 0x0
+#define MX6SX_PAD_GPIO1_IO08__SRC_SYSTEM_RESET 0x0034 0x037C 0x0000 0x6 0x0
+#define MX6SX_PAD_GPIO1_IO08__DCIC1_OUT 0x0034 0x037C 0x0000 0x7 0x0
+#define MX6SX_PAD_GPIO1_IO08__VDEC_DEBUG_43 0x0034 0x037C 0x0000 0x8 0x0
+#define MX6SX_PAD_GPIO1_IO09__USB_OTG1_PWR 0x0038 0x0380 0x0000 0x0 0x0
+#define MX6SX_PAD_GPIO1_IO09__WDOG2_WDOG_B 0x0038 0x0380 0x0000 0x1 0x0
+#define MX6SX_PAD_GPIO1_IO09__SDMA_EXT_EVENT_1 0x0038 0x0380 0x0820 0x2 0x0
+#define MX6SX_PAD_GPIO1_IO09__CCM_OUT0 0x0038 0x0380 0x0000 0x3 0x0
+#define MX6SX_PAD_GPIO1_IO09__UART2_CTS_B 0x0038 0x0380 0x0000 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO09__GPIO1_IO_9 0x0038 0x0380 0x0000 0x5 0x0
+#define MX6SX_PAD_GPIO1_IO09__SRC_INT_BOOT 0x0038 0x0380 0x0000 0x6 0x0
+#define MX6SX_PAD_GPIO1_IO09__OBSERVE_MUX_OUT_4 0x0038 0x0380 0x0000 0x7 0x0
+#define MX6SX_PAD_GPIO1_IO09__VDEC_DEBUG_42 0x0038 0x0380 0x0000 0x8 0x0
+#define MX6SX_PAD_GPIO1_IO10__ANATOP_OTG1_ID 0x003C 0x0384 0x0624 0x0 0x0
+#define MX6SX_PAD_GPIO1_IO10__SPDIF_EXT_CLK 0x003C 0x0384 0x0828 0x1 0x0
+#define MX6SX_PAD_GPIO1_IO10__PWM1_OUT 0x003C 0x0384 0x0000 0x2 0x0
+#define MX6SX_PAD_GPIO1_IO10__CCM_OUT1 0x003C 0x0384 0x0000 0x3 0x0
+#define MX6SX_PAD_GPIO1_IO10__CSI1_FIELD 0x003C 0x0384 0x070C 0x4 0x1
+#define MX6SX_PAD_GPIO1_IO10__GPIO1_IO_10 0x003C 0x0384 0x0000 0x5 0x0
+#define MX6SX_PAD_GPIO1_IO10__CSU_CSU_INT_DEB 0x003C 0x0384 0x0000 0x6 0x0
+#define MX6SX_PAD_GPIO1_IO10__OBSERVE_MUX_OUT_3 0x003C 0x0384 0x0000 0x7 0x0
+#define MX6SX_PAD_GPIO1_IO10__VDEC_DEBUG_41 0x003C 0x0384 0x0000 0x8 0x0
+#define MX6SX_PAD_GPIO1_IO11__USB_OTG2_OC 0x0040 0x0388 0x085C 0x0 0x0
+#define MX6SX_PAD_GPIO1_IO11__SPDIF_IN 0x0040 0x0388 0x0824 0x1 0x2
+#define MX6SX_PAD_GPIO1_IO11__PWM2_OUT 0x0040 0x0388 0x0000 0x2 0x0
+#define MX6SX_PAD_GPIO1_IO11__CCM_CLKO1 0x0040 0x0388 0x0000 0x3 0x0
+#define MX6SX_PAD_GPIO1_IO11__MLB_DATA 0x0040 0x0388 0x07EC 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO11__GPIO1_IO_11 0x0040 0x0388 0x0000 0x5 0x0
+#define MX6SX_PAD_GPIO1_IO11__CSU_CSU_ALARM_AUT_0 0x0040 0x0388 0x0000 0x6 0x0
+#define MX6SX_PAD_GPIO1_IO11__OBSERVE_MUX_OUT_2 0x0040 0x0388 0x0000 0x7 0x0
+#define MX6SX_PAD_GPIO1_IO11__VDEC_DEBUG_40 0x0040 0x0388 0x0000 0x8 0x0
+#define MX6SX_PAD_GPIO1_IO12__USB_OTG2_PWR 0x0044 0x038C 0x0000 0x0 0x0
+#define MX6SX_PAD_GPIO1_IO12__SPDIF_OUT 0x0044 0x038C 0x0000 0x1 0x0
+#define MX6SX_PAD_GPIO1_IO12__PWM3_OUT 0x0044 0x038C 0x0000 0x2 0x0
+#define MX6SX_PAD_GPIO1_IO12__CCM_CLKO2 0x0044 0x038C 0x0000 0x3 0x0
+#define MX6SX_PAD_GPIO1_IO12__MLB_CLK 0x0044 0x038C 0x07E8 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO12__GPIO1_IO_12 0x0044 0x038C 0x0000 0x5 0x0
+#define MX6SX_PAD_GPIO1_IO12__CSU_CSU_ALARM_AUT_1 0x0044 0x038C 0x0000 0x6 0x0
+#define MX6SX_PAD_GPIO1_IO12__OBSERVE_MUX_OUT_1 0x0044 0x038C 0x0000 0x7 0x0
+#define MX6SX_PAD_GPIO1_IO12__VDEC_DEBUG_39 0x0044 0x038C 0x0000 0x8 0x0
+#define MX6SX_PAD_GPIO1_IO13__WDOG1_WDOG_ANY 0x0048 0x0390 0x0000 0x0 0x0
+#define MX6SX_PAD_GPIO1_IO13__ANATOP_OTG2_ID 0x0048 0x0390 0x0628 0x1 0x0
+#define MX6SX_PAD_GPIO1_IO13__PWM4_OUT 0x0048 0x0390 0x0000 0x2 0x0
+#define MX6SX_PAD_GPIO1_IO13__CCM_OUT2 0x0048 0x0390 0x0000 0x3 0x0
+#define MX6SX_PAD_GPIO1_IO13__MLB_SIG 0x0048 0x0390 0x07F0 0x4 0x0
+#define MX6SX_PAD_GPIO1_IO13__GPIO1_IO_13 0x0048 0x0390 0x0000 0x5 0x0
+#define MX6SX_PAD_GPIO1_IO13__CSU_CSU_ALARM_AUT_2 0x0048 0x0390 0x0000 0x6 0x0
+#define MX6SX_PAD_GPIO1_IO13__OBSERVE_MUX_OUT_0 0x0048 0x0390 0x0000 0x7 0x0
+#define MX6SX_PAD_GPIO1_IO13__VDEC_DEBUG_38 0x0048 0x0390 0x0000 0x8 0x0
+#define MX6SX_PAD_CSI_DATA00__CSI1_DATA_2 0x004C 0x0394 0x06A8 0x0 0x0
+#define MX6SX_PAD_CSI_DATA00__ESAI_TX_CLK 0x004C 0x0394 0x078C 0x1 0x1
+#define MX6SX_PAD_CSI_DATA00__AUDMUX_AUD6_TXC 0x004C 0x0394 0x0684 0x2 0x1
+#define MX6SX_PAD_CSI_DATA00__I2C1_SCL 0x004C 0x0394 0x07A8 0x3 0x0
+#define MX6SX_PAD_CSI_DATA00__UART6_RI_B 0x004C 0x0394 0x0000 0x4 0x0
+#define MX6SX_PAD_CSI_DATA00__GPIO1_IO_14 0x004C 0x0394 0x0000 0x5 0x0
+#define MX6SX_PAD_CSI_DATA00__WEIM_DATA_23 0x004C 0x0394 0x0000 0x6 0x0
+#define MX6SX_PAD_CSI_DATA00__SAI1_TX_BCLK 0x004C 0x0394 0x0800 0x7 0x0
+#define MX6SX_PAD_CSI_DATA00__VADC_DATA_4 0x004C 0x0394 0x0000 0x8 0x0
+#define MX6SX_PAD_CSI_DATA00__MMDC_DEBUG_37 0x004C 0x0394 0x0000 0x9 0x0
+#define MX6SX_PAD_CSI_DATA01__CSI1_DATA_3 0x0050 0x0398 0x06AC 0x0 0x0
+#define MX6SX_PAD_CSI_DATA01__ESAI_TX_FS 0x0050 0x0398 0x077C 0x1 0x1
+#define MX6SX_PAD_CSI_DATA01__AUDMUX_AUD6_TXFS 0x0050 0x0398 0x0688 0x2 0x1
+#define MX6SX_PAD_CSI_DATA01__I2C1_SDA 0x0050 0x0398 0x07AC 0x3 0x0
+#define MX6SX_PAD_CSI_DATA01__UART6_DSR_B 0x0050 0x0398 0x0000 0x4 0x0
+#define MX6SX_PAD_CSI_DATA01__GPIO1_IO_15 0x0050 0x0398 0x0000 0x5 0x0
+#define MX6SX_PAD_CSI_DATA01__WEIM_DATA_22 0x0050 0x0398 0x0000 0x6 0x0
+#define MX6SX_PAD_CSI_DATA01__SAI1_TX_SYNC 0x0050 0x0398 0x0804 0x7 0x0
+#define MX6SX_PAD_CSI_DATA01__VADC_DATA_5 0x0050 0x0398 0x0000 0x8 0x0
+#define MX6SX_PAD_CSI_DATA01__MMDC_DEBUG_38 0x0050 0x0398 0x0000 0x9 0x0
+#define MX6SX_PAD_CSI_DATA02__CSI1_DATA_4 0x0054 0x039C 0x06B0 0x0 0x0
+#define MX6SX_PAD_CSI_DATA02__ESAI_RX_CLK 0x0054 0x039C 0x0788 0x1 0x1
+#define MX6SX_PAD_CSI_DATA02__AUDMUX_AUD6_RXC 0x0054 0x039C 0x067C 0x2 0x1
+#define MX6SX_PAD_CSI_DATA02__KPP_COL_5 0x0054 0x039C 0x07C8 0x3 0x0
+#define MX6SX_PAD_CSI_DATA02__UART6_DTR_B 0x0054 0x039C 0x0000 0x4 0x0
+#define MX6SX_PAD_CSI_DATA02__GPIO1_IO_16 0x0054 0x039C 0x0000 0x5 0x0
+#define MX6SX_PAD_CSI_DATA02__WEIM_DATA_21 0x0054 0x039C 0x0000 0x6 0x0
+#define MX6SX_PAD_CSI_DATA02__SAI1_RX_BCLK 0x0054 0x039C 0x07F4 0x7 0x0
+#define MX6SX_PAD_CSI_DATA02__VADC_DATA_6 0x0054 0x039C 0x0000 0x8 0x0
+#define MX6SX_PAD_CSI_DATA02__MMDC_DEBUG_39 0x0054 0x039C 0x0000 0x9 0x0
+#define MX6SX_PAD_CSI_DATA03__CSI1_DATA_5 0x0058 0x03A0 0x06B4 0x0 0x0
+#define MX6SX_PAD_CSI_DATA03__ESAI_RX_FS 0x0058 0x03A0 0x0778 0x1 0x1
+#define MX6SX_PAD_CSI_DATA03__AUDMUX_AUD6_RXFS 0x0058 0x03A0 0x0680 0x2 0x1
+#define MX6SX_PAD_CSI_DATA03__KPP_ROW_5 0x0058 0x03A0 0x07D4 0x3 0x0
+#define MX6SX_PAD_CSI_DATA03__UART6_DCD_B 0x0058 0x03A0 0x0000 0x4 0x0
+#define MX6SX_PAD_CSI_DATA03__GPIO1_IO_17 0x0058 0x03A0 0x0000 0x5 0x0
+#define MX6SX_PAD_CSI_DATA03__WEIM_DATA_20 0x0058 0x03A0 0x0000 0x6 0x0
+#define MX6SX_PAD_CSI_DATA03__SAI1_RX_SYNC 0x0058 0x03A0 0x07FC 0x7 0x0
+#define MX6SX_PAD_CSI_DATA03__VADC_DATA_7 0x0058 0x03A0 0x0000 0x8 0x0
+#define MX6SX_PAD_CSI_DATA03__MMDC_DEBUG_40 0x0058 0x03A0 0x0000 0x9 0x0
+#define MX6SX_PAD_CSI_DATA04__CSI1_DATA_6 0x005C 0x03A4 0x06B8 0x0 0x0
+#define MX6SX_PAD_CSI_DATA04__ESAI_TX1 0x005C 0x03A4 0x0794 0x1 0x1
+#define MX6SX_PAD_CSI_DATA04__SPDIF_OUT 0x005C 0x03A4 0x0000 0x2 0x0
+#define MX6SX_PAD_CSI_DATA04__KPP_COL_6 0x005C 0x03A4 0x07CC 0x3 0x0
+#define MX6SX_PAD_CSI_DATA04__UART6_RX 0x005C 0x03A4 0x0858 0x4 0x0
+#define MX6SX_PAD_CSI_DATA04__UART6_TX 0x005C 0x03A4 0x0000 0x4 0x0
+#define MX6SX_PAD_CSI_DATA04__GPIO1_IO_18 0x005C 0x03A4 0x0000 0x5 0x0
+#define MX6SX_PAD_CSI_DATA04__WEIM_DATA_19 0x005C 0x03A4 0x0000 0x6 0x0
+#define MX6SX_PAD_CSI_DATA04__PWM5_OUT 0x005C 0x03A4 0x0000 0x7 0x0
+#define MX6SX_PAD_CSI_DATA04__VADC_DATA_8 0x005C 0x03A4 0x0000 0x8 0x0
+#define MX6SX_PAD_CSI_DATA04__MMDC_DEBUG_41 0x005C 0x03A4 0x0000 0x9 0x0
+#define MX6SX_PAD_CSI_DATA05__CSI1_DATA_7 0x0060 0x03A8 0x06BC 0x0 0x0
+#define MX6SX_PAD_CSI_DATA05__ESAI_TX4_RX1 0x0060 0x03A8 0x07A0 0x1 0x1
+#define MX6SX_PAD_CSI_DATA05__SPDIF_IN 0x0060 0x03A8 0x0824 0x2 0x1
+#define MX6SX_PAD_CSI_DATA05__KPP_ROW_6 0x0060 0x03A8 0x07D8 0x3 0x0
+#define MX6SX_PAD_CSI_DATA05__UART6_RX 0x0060 0x03A8 0x0858 0x4 0x1
+#define MX6SX_PAD_CSI_DATA05__UART6_TX 0x0060 0x03A8 0x0000 0x4 0x0
+#define MX6SX_PAD_CSI_DATA05__GPIO1_IO_19 0x0060 0x03A8 0x0000 0x5 0x0
+#define MX6SX_PAD_CSI_DATA05__WEIM_DATA_18 0x0060 0x03A8 0x0000 0x6 0x0
+#define MX6SX_PAD_CSI_DATA05__PWM6_OUT 0x0060 0x03A8 0x0000 0x7 0x0
+#define MX6SX_PAD_CSI_DATA05__VADC_DATA_9 0x0060 0x03A8 0x0000 0x8 0x0
+#define MX6SX_PAD_CSI_DATA05__MMDC_DEBUG_42 0x0060 0x03A8 0x0000 0x9 0x0
+#define MX6SX_PAD_CSI_DATA06__CSI1_DATA_8 0x0064 0x03AC 0x06C0 0x0 0x0
+#define MX6SX_PAD_CSI_DATA06__ESAI_TX2_RX3 0x0064 0x03AC 0x0798 0x1 0x1
+#define MX6SX_PAD_CSI_DATA06__I2C4_SCL 0x0064 0x03AC 0x07C0 0x2 0x2
+#define MX6SX_PAD_CSI_DATA06__KPP_COL_7 0x0064 0x03AC 0x07D0 0x3 0x0
+#define MX6SX_PAD_CSI_DATA06__UART6_RTS_B 0x0064 0x03AC 0x0854 0x4 0x0
+#define MX6SX_PAD_CSI_DATA06__GPIO1_IO_20 0x0064 0x03AC 0x0000 0x5 0x0
+#define MX6SX_PAD_CSI_DATA06__WEIM_DATA_17 0x0064 0x03AC 0x0000 0x6 0x0
+#define MX6SX_PAD_CSI_DATA06__DCIC2_OUT 0x0064 0x03AC 0x0000 0x7 0x0
+#define MX6SX_PAD_CSI_DATA06__VADC_DATA_10 0x0064 0x03AC 0x0000 0x8 0x0
+#define MX6SX_PAD_CSI_DATA06__MMDC_DEBUG_43 0x0064 0x03AC 0x0000 0x9 0x0
+#define MX6SX_PAD_CSI_DATA07__CSI1_DATA_9 0x0068 0x03B0 0x06C4 0x0 0x0
+#define MX6SX_PAD_CSI_DATA07__ESAI_TX3_RX2 0x0068 0x03B0 0x079C 0x1 0x1
+#define MX6SX_PAD_CSI_DATA07__I2C4_SDA 0x0068 0x03B0 0x07C4 0x2 0x2
+#define MX6SX_PAD_CSI_DATA07__KPP_ROW_7 0x0068 0x03B0 0x07DC 0x3 0x0
+#define MX6SX_PAD_CSI_DATA07__UART6_CTS_B 0x0068 0x03B0 0x0000 0x4 0x0
+#define MX6SX_PAD_CSI_DATA07__GPIO1_IO_21 0x0068 0x03B0 0x0000 0x5 0x0
+#define MX6SX_PAD_CSI_DATA07__WEIM_DATA_16 0x0068 0x03B0 0x0000 0x6 0x0
+#define MX6SX_PAD_CSI_DATA07__DCIC1_OUT 0x0068 0x03B0 0x0000 0x7 0x0
+#define MX6SX_PAD_CSI_DATA07__VADC_DATA_11 0x0068 0x03B0 0x0000 0x8 0x0
+#define MX6SX_PAD_CSI_DATA07__MMDC_DEBUG_44 0x0068 0x03B0 0x0000 0x9 0x0
+#define MX6SX_PAD_CSI_HSYNC__CSI1_HSYNC 0x006C 0x03B4 0x0700 0x0 0x0
+#define MX6SX_PAD_CSI_HSYNC__ESAI_TX0 0x006C 0x03B4 0x0790 0x1 0x1
+#define MX6SX_PAD_CSI_HSYNC__AUDMUX_AUD6_TXD 0x006C 0x03B4 0x0678 0x2 0x1
+#define MX6SX_PAD_CSI_HSYNC__UART4_RTS_B 0x006C 0x03B4 0x0844 0x3 0x2
+#define MX6SX_PAD_CSI_HSYNC__MQS_LEFT 0x006C 0x03B4 0x0000 0x4 0x0
+#define MX6SX_PAD_CSI_HSYNC__GPIO1_IO_22 0x006C 0x03B4 0x0000 0x5 0x0
+#define MX6SX_PAD_CSI_HSYNC__WEIM_DATA_25 0x006C 0x03B4 0x0000 0x6 0x0
+#define MX6SX_PAD_CSI_HSYNC__SAI1_TX_DATA_0 0x006C 0x03B4 0x0000 0x7 0x0
+#define MX6SX_PAD_CSI_HSYNC__VADC_DATA_2 0x006C 0x03B4 0x0000 0x8 0x0
+#define MX6SX_PAD_CSI_HSYNC__MMDC_DEBUG_35 0x006C 0x03B4 0x0000 0x9 0x0
+#define MX6SX_PAD_CSI_MCLK__CSI1_MCLK 0x0070 0x03B8 0x0000 0x0 0x0
+#define MX6SX_PAD_CSI_MCLK__ESAI_TX_HF_CLK 0x0070 0x03B8 0x0784 0x1 0x1
+#define MX6SX_PAD_CSI_MCLK__OSC32K_32K_OUT 0x0070 0x03B8 0x0000 0x2 0x0
+#define MX6SX_PAD_CSI_MCLK__UART4_RX 0x0070 0x03B8 0x0848 0x3 0x2
+#define MX6SX_PAD_CSI_MCLK__UART4_TX 0x0070 0x03B8 0x0000 0x3 0x0
+#define MX6SX_PAD_CSI_MCLK__ANATOP_32K_OUT 0x0070 0x03B8 0x0000 0x4 0x0
+#define MX6SX_PAD_CSI_MCLK__GPIO1_IO_23 0x0070 0x03B8 0x0000 0x5 0x0
+#define MX6SX_PAD_CSI_MCLK__WEIM_DATA_26 0x0070 0x03B8 0x0000 0x6 0x0
+#define MX6SX_PAD_CSI_MCLK__CSI1_FIELD 0x0070 0x03B8 0x070C 0x7 0x0
+#define MX6SX_PAD_CSI_MCLK__VADC_DATA_1 0x0070 0x03B8 0x0000 0x8 0x0
+#define MX6SX_PAD_CSI_MCLK__MMDC_DEBUG_34 0x0070 0x03B8 0x0000 0x9 0x0
+#define MX6SX_PAD_CSI_PIXCLK__CSI1_PIXCLK 0x0074 0x03BC 0x0704 0x0 0x0
+#define MX6SX_PAD_CSI_PIXCLK__ESAI_RX_HF_CLK 0x0074 0x03BC 0x0780 0x1 0x1
+#define MX6SX_PAD_CSI_PIXCLK__AUDMUX_MCLK 0x0074 0x03BC 0x0000 0x2 0x0
+#define MX6SX_PAD_CSI_PIXCLK__UART4_RX 0x0074 0x03BC 0x0848 0x3 0x3
+#define MX6SX_PAD_CSI_PIXCLK__UART4_TX 0x0074 0x03BC 0x0000 0x3 0x0
+#define MX6SX_PAD_CSI_PIXCLK__ANATOP_24M_OUT 0x0074 0x03BC 0x0000 0x4 0x0
+#define MX6SX_PAD_CSI_PIXCLK__GPIO1_IO_24 0x0074 0x03BC 0x0000 0x5 0x0
+#define MX6SX_PAD_CSI_PIXCLK__WEIM_DATA_27 0x0074 0x03BC 0x0000 0x6 0x0
+#define MX6SX_PAD_CSI_PIXCLK__ESAI_TX_HF_CLK 0x0074 0x03BC 0x0784 0x7 0x2
+#define MX6SX_PAD_CSI_PIXCLK__VADC_CLK 0x0074 0x03BC 0x0000 0x8 0x0
+#define MX6SX_PAD_CSI_PIXCLK__MMDC_DEBUG_33 0x0074 0x03BC 0x0000 0x9 0x0
+#define MX6SX_PAD_CSI_VSYNC__CSI1_VSYNC 0x0078 0x03C0 0x0708 0x0 0x0
+#define MX6SX_PAD_CSI_VSYNC__ESAI_TX5_RX0 0x0078 0x03C0 0x07A4 0x1 0x1
+#define MX6SX_PAD_CSI_VSYNC__AUDMUX_AUD6_RXD 0x0078 0x03C0 0x0674 0x2 0x1
+#define MX6SX_PAD_CSI_VSYNC__UART4_CTS_B 0x0078 0x03C0 0x0000 0x3 0x0
+#define MX6SX_PAD_CSI_VSYNC__MQS_RIGHT 0x0078 0x03C0 0x0000 0x4 0x0
+#define MX6SX_PAD_CSI_VSYNC__GPIO1_IO_25 0x0078 0x03C0 0x0000 0x5 0x0
+#define MX6SX_PAD_CSI_VSYNC__WEIM_DATA_24 0x0078 0x03C0 0x0000 0x6 0x0
+#define MX6SX_PAD_CSI_VSYNC__SAI1_RX_DATA_0 0x0078 0x03C0 0x07F8 0x7 0x0
+#define MX6SX_PAD_CSI_VSYNC__VADC_DATA_3 0x0078 0x03C0 0x0000 0x8 0x0
+#define MX6SX_PAD_CSI_VSYNC__MMDC_DEBUG_36 0x0078 0x03C0 0x0000 0x9 0x0
+#define MX6SX_PAD_ENET1_COL__ENET1_COL 0x007C 0x03C4 0x0000 0x0 0x0
+#define MX6SX_PAD_ENET1_COL__ENET2_MDC 0x007C 0x03C4 0x0000 0x1 0x0
+#define MX6SX_PAD_ENET1_COL__AUDMUX_AUD4_TXC 0x007C 0x03C4 0x0654 0x2 0x1
+#define MX6SX_PAD_ENET1_COL__UART1_RI_B 0x007C 0x03C4 0x0000 0x3 0x0
+#define MX6SX_PAD_ENET1_COL__SPDIF_EXT_CLK 0x007C 0x03C4 0x0828 0x4 0x1
+#define MX6SX_PAD_ENET1_COL__GPIO2_IO_0 0x007C 0x03C4 0x0000 0x5 0x0
+#define MX6SX_PAD_ENET1_COL__CSI2_DATA_23 0x007C 0x03C4 0x0000 0x6 0x0
+#define MX6SX_PAD_ENET1_COL__LCDIF2_DATA_16 0x007C 0x03C4 0x0000 0x7 0x0
+#define MX6SX_PAD_ENET1_COL__VDEC_DEBUG_37 0x007C 0x03C4 0x0000 0x8 0x0
+#define MX6SX_PAD_ENET1_COL__PCIE_CTRL_DEBUG_31 0x007C 0x03C4 0x0000 0x9 0x0
+#define MX6SX_PAD_ENET1_CRS__ENET1_CRS 0x0080 0x03C8 0x0000 0x0 0x0
+#define MX6SX_PAD_ENET1_CRS__ENET2_MDIO 0x0080 0x03C8 0x0770 0x1 0x1
+#define MX6SX_PAD_ENET1_CRS__AUDMUX_AUD4_TXD 0x0080 0x03C8 0x0648 0x2 0x1
+#define MX6SX_PAD_ENET1_CRS__UART1_DCD_B 0x0080 0x03C8 0x0000 0x3 0x0
+#define MX6SX_PAD_ENET1_CRS__SPDIF_LOCK 0x0080 0x03C8 0x0000 0x4 0x0
+#define MX6SX_PAD_ENET1_CRS__GPIO2_IO_1 0x0080 0x03C8 0x0000 0x5 0x0
+#define MX6SX_PAD_ENET1_CRS__CSI2_DATA_22 0x0080 0x03C8 0x0000 0x6 0x0
+#define MX6SX_PAD_ENET1_CRS__LCDIF2_DATA_17 0x0080 0x03C8 0x0000 0x7 0x0
+#define MX6SX_PAD_ENET1_CRS__VDEC_DEBUG_36 0x0080 0x03C8 0x0000 0x8 0x0
+#define MX6SX_PAD_ENET1_CRS__PCIE_CTRL_DEBUG_30 0x0080 0x03C8 0x0000 0x9 0x0
+#define MX6SX_PAD_ENET1_MDC__ENET1_MDC 0x0084 0x03CC 0x0000 0x0 0x0
+#define MX6SX_PAD_ENET1_MDC__ENET2_MDC 0x0084 0x03CC 0x0000 0x1 0x0
+#define MX6SX_PAD_ENET1_MDC__AUDMUX_AUD3_RXFS 0x0084 0x03CC 0x0638 0x2 0x1
+#define MX6SX_PAD_ENET1_MDC__ANATOP_24M_OUT 0x0084 0x03CC 0x0000 0x3 0x0
+#define MX6SX_PAD_ENET1_MDC__EPIT2_OUT 0x0084 0x03CC 0x0000 0x4 0x0
+#define MX6SX_PAD_ENET1_MDC__GPIO2_IO_2 0x0084 0x03CC 0x0000 0x5 0x0
+#define MX6SX_PAD_ENET1_MDC__USB_OTG1_PWR 0x0084 0x03CC 0x0000 0x6 0x0
+#define MX6SX_PAD_ENET1_MDC__PWM7_OUT 0x0084 0x03CC 0x0000 0x7 0x0
+#define MX6SX_PAD_ENET1_MDIO__ENET1_MDIO 0x0088 0x03D0 0x0764 0x0 0x1
+#define MX6SX_PAD_ENET1_MDIO__ENET2_MDIO 0x0088 0x03D0 0x0770 0x1 0x2
+#define MX6SX_PAD_ENET1_MDIO__AUDMUX_MCLK 0x0088 0x03D0 0x0000 0x2 0x0
+#define MX6SX_PAD_ENET1_MDIO__OSC32K_32K_OUT 0x0088 0x03D0 0x0000 0x3 0x0
+#define MX6SX_PAD_ENET1_MDIO__EPIT1_OUT 0x0088 0x03D0 0x0000 0x4 0x0
+#define MX6SX_PAD_ENET1_MDIO__GPIO2_IO_3 0x0088 0x03D0 0x0000 0x5 0x0
+#define MX6SX_PAD_ENET1_MDIO__USB_OTG1_OC 0x0088 0x03D0 0x0860 0x6 0x1
+#define MX6SX_PAD_ENET1_MDIO__PWM8_OUT 0x0088 0x03D0 0x0000 0x7 0x0
+#define MX6SX_PAD_ENET1_RX_CLK__ENET1_RX_CLK 0x008C 0x03D4 0x0768 0x0 0x0
+#define MX6SX_PAD_ENET1_RX_CLK__ENET1_REF_CLK_25M 0x008C 0x03D4 0x0000 0x1 0x0
+#define MX6SX_PAD_ENET1_RX_CLK__AUDMUX_AUD4_TXFS 0x008C 0x03D4 0x0658 0x2 0x1
+#define MX6SX_PAD_ENET1_RX_CLK__UART1_DSR_B 0x008C 0x03D4 0x0000 0x3 0x0
+#define MX6SX_PAD_ENET1_RX_CLK__SPDIF_OUT 0x008C 0x03D4 0x0000 0x4 0x0
+#define MX6SX_PAD_ENET1_RX_CLK__GPIO2_IO_4 0x008C 0x03D4 0x0000 0x5 0x0
+#define MX6SX_PAD_ENET1_RX_CLK__CSI2_DATA_21 0x008C 0x03D4 0x0000 0x6 0x0
+#define MX6SX_PAD_ENET1_RX_CLK__LCDIF2_DATA_18 0x008C 0x03D4 0x0000 0x7 0x0
+#define MX6SX_PAD_ENET1_RX_CLK__VDEC_DEBUG_35 0x008C 0x03D4 0x0000 0x8 0x0
+#define MX6SX_PAD_ENET1_RX_CLK__PCIE_CTRL_DEBUG_29 0x008C 0x03D4 0x0000 0x9 0x0
+#define MX6SX_PAD_ENET1_TX_CLK__ENET1_TX_CLK 0x0090 0x03D8 0x0000 0x0 0x0
+#define MX6SX_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x0090 0x03D8 0x0760 0x1 0x1
+#define MX6SX_PAD_ENET1_TX_CLK__AUDMUX_AUD4_RXD 0x0090 0x03D8 0x0644 0x2 0x1
+#define MX6SX_PAD_ENET1_TX_CLK__UART1_DTR_B 0x0090 0x03D8 0x0000 0x3 0x0
+#define MX6SX_PAD_ENET1_TX_CLK__SPDIF_SR_CLK 0x0090 0x03D8 0x0000 0x4 0x0
+#define MX6SX_PAD_ENET1_TX_CLK__GPIO2_IO_5 0x0090 0x03D8 0x0000 0x5 0x0
+#define MX6SX_PAD_ENET1_TX_CLK__CSI2_DATA_20 0x0090 0x03D8 0x0000 0x6 0x0
+#define MX6SX_PAD_ENET1_TX_CLK__LCDIF2_DATA_19 0x0090 0x03D8 0x0000 0x7 0x0
+#define MX6SX_PAD_ENET1_TX_CLK__VDEC_DEBUG_34 0x0090 0x03D8 0x0000 0x8 0x0
+#define MX6SX_PAD_ENET1_TX_CLK__PCIE_CTRL_DEBUG_28 0x0090 0x03D8 0x0000 0x9 0x0
+#define MX6SX_PAD_ENET2_COL__ENET2_COL 0x0094 0x03DC 0x0000 0x0 0x0
+#define MX6SX_PAD_ENET2_COL__ENET1_MDC 0x0094 0x03DC 0x0000 0x1 0x0
+#define MX6SX_PAD_ENET2_COL__AUDMUX_AUD4_RXC 0x0094 0x03DC 0x064C 0x2 0x1
+#define MX6SX_PAD_ENET2_COL__UART1_RX 0x0094 0x03DC 0x0830 0x3 0x2
+#define MX6SX_PAD_ENET2_COL__UART1_TX 0x0094 0x03DC 0x0000 0x3 0x0
+#define MX6SX_PAD_ENET2_COL__SPDIF_IN 0x0094 0x03DC 0x0824 0x4 0x3
+#define MX6SX_PAD_ENET2_COL__GPIO2_IO_6 0x0094 0x03DC 0x0000 0x5 0x0
+#define MX6SX_PAD_ENET2_COL__ANATOP_OTG1_ID 0x0094 0x03DC 0x0624 0x6 0x1
+#define MX6SX_PAD_ENET2_COL__LCDIF2_DATA_20 0x0094 0x03DC 0x0000 0x7 0x0
+#define MX6SX_PAD_ENET2_COL__VDEC_DEBUG_33 0x0094 0x03DC 0x0000 0x8 0x0
+#define MX6SX_PAD_ENET2_COL__PCIE_CTRL_DEBUG_27 0x0094 0x03DC 0x0000 0x9 0x0
+#define MX6SX_PAD_ENET2_CRS__ENET2_CRS 0x0098 0x03E0 0x0000 0x0 0x0
+#define MX6SX_PAD_ENET2_CRS__ENET1_MDIO 0x0098 0x03E0 0x0764 0x1 0x2
+#define MX6SX_PAD_ENET2_CRS__AUDMUX_AUD4_RXFS 0x0098 0x03E0 0x0650 0x2 0x1
+#define MX6SX_PAD_ENET2_CRS__UART1_RX 0x0098 0x03E0 0x0830 0x3 0x3
+#define MX6SX_PAD_ENET2_CRS__UART1_TX 0x0098 0x03E0 0x0000 0x3 0x0
+#define MX6SX_PAD_ENET2_CRS__MLB_SIG 0x0098 0x03E0 0x07F0 0x4 0x1
+#define MX6SX_PAD_ENET2_CRS__GPIO2_IO_7 0x0098 0x03E0 0x0000 0x5 0x0
+#define MX6SX_PAD_ENET2_CRS__ANATOP_OTG2_ID 0x0098 0x03E0 0x0628 0x6 0x1
+#define MX6SX_PAD_ENET2_CRS__LCDIF2_DATA_21 0x0098 0x03E0 0x0000 0x7 0x0
+#define MX6SX_PAD_ENET2_CRS__VDEC_DEBUG_32 0x0098 0x03E0 0x0000 0x8 0x0
+#define MX6SX_PAD_ENET2_CRS__PCIE_CTRL_DEBUG_26 0x0098 0x03E0 0x0000 0x9 0x0
+#define MX6SX_PAD_ENET2_RX_CLK__ENET2_RX_CLK 0x009C 0x03E4 0x0774 0x0 0x0
+#define MX6SX_PAD_ENET2_RX_CLK__ENET2_REF_CLK_25M 0x009C 0x03E4 0x0000 0x1 0x0
+#define MX6SX_PAD_ENET2_RX_CLK__I2C3_SCL 0x009C 0x03E4 0x07B8 0x2 0x1
+#define MX6SX_PAD_ENET2_RX_CLK__UART1_RTS_B 0x009C 0x03E4 0x082C 0x3 0x2
+#define MX6SX_PAD_ENET2_RX_CLK__MLB_DATA 0x009C 0x03E4 0x07EC 0x4 0x1
+#define MX6SX_PAD_ENET2_RX_CLK__GPIO2_IO_8 0x009C 0x03E4 0x0000 0x5 0x0
+#define MX6SX_PAD_ENET2_RX_CLK__USB_OTG2_OC 0x009C 0x03E4 0x085C 0x6 0x1
+#define MX6SX_PAD_ENET2_RX_CLK__LCDIF2_DATA_22 0x009C 0x03E4 0x0000 0x7 0x0
+#define MX6SX_PAD_ENET2_RX_CLK__VDEC_DEBUG_31 0x009C 0x03E4 0x0000 0x8 0x0
+#define MX6SX_PAD_ENET2_RX_CLK__PCIE_CTRL_DEBUG_25 0x009C 0x03E4 0x0000 0x9 0x0
+#define MX6SX_PAD_ENET2_TX_CLK__ENET2_TX_CLK 0x00A0 0x03E8 0x0000 0x0 0x0
+#define MX6SX_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x00A0 0x03E8 0x076C 0x1 0x1
+#define MX6SX_PAD_ENET2_TX_CLK__I2C3_SDA 0x00A0 0x03E8 0x07BC 0x2 0x1
+#define MX6SX_PAD_ENET2_TX_CLK__UART1_CTS_B 0x00A0 0x03E8 0x0000 0x3 0x0
+#define MX6SX_PAD_ENET2_TX_CLK__MLB_CLK 0x00A0 0x03E8 0x07E8 0x4 0x1
+#define MX6SX_PAD_ENET2_TX_CLK__GPIO2_IO_9 0x00A0 0x03E8 0x0000 0x5 0x0
+#define MX6SX_PAD_ENET2_TX_CLK__USB_OTG2_PWR 0x00A0 0x03E8 0x0000 0x6 0x0
+#define MX6SX_PAD_ENET2_TX_CLK__LCDIF2_DATA_23 0x00A0 0x03E8 0x0000 0x7 0x0
+#define MX6SX_PAD_ENET2_TX_CLK__VDEC_DEBUG_30 0x00A0 0x03E8 0x0000 0x8 0x0
+#define MX6SX_PAD_ENET2_TX_CLK__PCIE_CTRL_DEBUG_24 0x00A0 0x03E8 0x0000 0x9 0x0
+#define MX6SX_PAD_KEY_COL0__KPP_COL_0 0x00A4 0x03EC 0x0000 0x0 0x0
+#define MX6SX_PAD_KEY_COL0__USDHC3_CD_B 0x00A4 0x03EC 0x0000 0x1 0x0
+#define MX6SX_PAD_KEY_COL0__UART6_RTS_B 0x00A4 0x03EC 0x0854 0x2 0x2
+#define MX6SX_PAD_KEY_COL0__ECSPI1_SCLK 0x00A4 0x03EC 0x0710 0x3 0x0
+#define MX6SX_PAD_KEY_COL0__AUDMUX_AUD5_TXC 0x00A4 0x03EC 0x066C 0x4 0x0
+#define MX6SX_PAD_KEY_COL0__GPIO2_IO_10 0x00A4 0x03EC 0x0000 0x5 0x0
+#define MX6SX_PAD_KEY_COL0__SDMA_EXT_EVENT_1 0x00A4 0x03EC 0x0820 0x6 0x1
+#define MX6SX_PAD_KEY_COL0__SAI2_TX_BCLK 0x00A4 0x03EC 0x0814 0x7 0x0
+#define MX6SX_PAD_KEY_COL0__VADC_DATA_0 0x00A4 0x03EC 0x0000 0x8 0x0
+#define MX6SX_PAD_KEY_COL1__KPP_COL_1 0x00A8 0x03F0 0x0000 0x0 0x0
+#define MX6SX_PAD_KEY_COL1__USDHC3_RESET_B 0x00A8 0x03F0 0x0000 0x1 0x0
+#define MX6SX_PAD_KEY_COL1__UART6_RX 0x00A8 0x03F0 0x0858 0x2 0x2
+#define MX6SX_PAD_KEY_COL1__UART6_TX 0x00A8 0x03F0 0x0000 0x2 0x0
+#define MX6SX_PAD_KEY_COL1__ECSPI1_MISO 0x00A8 0x03F0 0x0714 0x3 0x0
+#define MX6SX_PAD_KEY_COL1__AUDMUX_AUD5_TXFS 0x00A8 0x03F0 0x0670 0x4 0x0
+#define MX6SX_PAD_KEY_COL1__GPIO2_IO_11 0x00A8 0x03F0 0x0000 0x5 0x0
+#define MX6SX_PAD_KEY_COL1__USDHC3_RESET 0x00A8 0x03F0 0x0000 0x6 0x0
+#define MX6SX_PAD_KEY_COL1__SAI2_TX_SYNC 0x00A8 0x03F0 0x0818 0x7 0x0
+#define MX6SX_PAD_KEY_COL2__KPP_COL_2 0x00AC 0x03F4 0x0000 0x0 0x0
+#define MX6SX_PAD_KEY_COL2__USDHC4_CD_B 0x00AC 0x03F4 0x0874 0x1 0x1
+#define MX6SX_PAD_KEY_COL2__UART5_RTS_B 0x00AC 0x03F4 0x084C 0x2 0x2
+#define MX6SX_PAD_KEY_COL2__CAN1_TX 0x00AC 0x03F4 0x0000 0x3 0x0
+#define MX6SX_PAD_KEY_COL2__CANFD_TX1 0x00AC 0x03F4 0x0000 0x4 0x0
+#define MX6SX_PAD_KEY_COL2__GPIO2_IO_12 0x00AC 0x03F4 0x0000 0x5 0x0
+#define MX6SX_PAD_KEY_COL2__WEIM_DATA_30 0x00AC 0x03F4 0x0000 0x6 0x0
+#define MX6SX_PAD_KEY_COL2__ECSPI1_RDY 0x00AC 0x03F4 0x0000 0x7 0x0
+#define MX6SX_PAD_KEY_COL3__KPP_COL_3 0x00B0 0x03F8 0x0000 0x0 0x0
+#define MX6SX_PAD_KEY_COL3__USDHC4_LCTL 0x00B0 0x03F8 0x0000 0x1 0x0
+#define MX6SX_PAD_KEY_COL3__UART5_RX 0x00B0 0x03F8 0x0850 0x2 0x2
+#define MX6SX_PAD_KEY_COL3__UART5_TX 0x00B0 0x03F8 0x0000 0x2 0x0
+#define MX6SX_PAD_KEY_COL3__CAN2_TX 0x00B0 0x03F8 0x0000 0x3 0x0
+#define MX6SX_PAD_KEY_COL3__CANFD_TX2 0x00B0 0x03F8 0x0000 0x4 0x0
+#define MX6SX_PAD_KEY_COL3__GPIO2_IO_13 0x00B0 0x03F8 0x0000 0x5 0x0
+#define MX6SX_PAD_KEY_COL3__WEIM_DATA_28 0x00B0 0x03F8 0x0000 0x6 0x0
+#define MX6SX_PAD_KEY_COL3__ECSPI1_SS2 0x00B0 0x03F8 0x0000 0x7 0x0
+#define MX6SX_PAD_KEY_COL4__KPP_COL_4 0x00B4 0x03FC 0x0000 0x0 0x0
+#define MX6SX_PAD_KEY_COL4__ENET2_MDC 0x00B4 0x03FC 0x0000 0x1 0x0
+#define MX6SX_PAD_KEY_COL4__I2C3_SCL 0x00B4 0x03FC 0x07B8 0x2 0x2
+#define MX6SX_PAD_KEY_COL4__USDHC2_LCTL 0x00B4 0x03FC 0x0000 0x3 0x0
+#define MX6SX_PAD_KEY_COL4__AUDMUX_AUD5_RXC 0x00B4 0x03FC 0x0664 0x4 0x0
+#define MX6SX_PAD_KEY_COL4__GPIO2_IO_14 0x00B4 0x03FC 0x0000 0x5 0x0
+#define MX6SX_PAD_KEY_COL4__WEIM_CRE 0x00B4 0x03FC 0x0000 0x6 0x0
+#define MX6SX_PAD_KEY_COL4__SAI2_RX_BCLK 0x00B4 0x03FC 0x0808 0x7 0x0
+#define MX6SX_PAD_KEY_ROW0__KPP_ROW_0 0x00B8 0x0400 0x0000 0x0 0x0
+#define MX6SX_PAD_KEY_ROW0__USDHC3_WP 0x00B8 0x0400 0x0000 0x1 0x0
+#define MX6SX_PAD_KEY_ROW0__UART6_CTS_B 0x00B8 0x0400 0x0000 0x2 0x0
+#define MX6SX_PAD_KEY_ROW0__ECSPI1_MOSI 0x00B8 0x0400 0x0718 0x3 0x0
+#define MX6SX_PAD_KEY_ROW0__AUDMUX_AUD5_TXD 0x00B8 0x0400 0x0660 0x4 0x0
+#define MX6SX_PAD_KEY_ROW0__GPIO2_IO_15 0x00B8 0x0400 0x0000 0x5 0x0
+#define MX6SX_PAD_KEY_ROW0__SDMA_EXT_EVENT_0 0x00B8 0x0400 0x081C 0x6 0x1
+#define MX6SX_PAD_KEY_ROW0__SAI2_TX_DATA_0 0x00B8 0x0400 0x0000 0x7 0x0
+#define MX6SX_PAD_KEY_ROW0__GPU_IDLE 0x00B8 0x0400 0x0000 0x8 0x0
+#define MX6SX_PAD_KEY_ROW1__KPP_ROW_1 0x00BC 0x0404 0x0000 0x0 0x0
+#define MX6SX_PAD_KEY_ROW1__USDHC4_VSELECT 0x00BC 0x0404 0x0000 0x1 0x0
+#define MX6SX_PAD_KEY_ROW1__UART6_RX 0x00BC 0x0404 0x0858 0x2 0x3
+#define MX6SX_PAD_KEY_ROW1__UART6_TX 0x00BC 0x0404 0x0000 0x2 0x0
+#define MX6SX_PAD_KEY_ROW1__ECSPI1_SS0 0x00BC 0x0404 0x071C 0x3 0x0
+#define MX6SX_PAD_KEY_ROW1__AUDMUX_AUD5_RXD 0x00BC 0x0404 0x065C 0x4 0x0
+#define MX6SX_PAD_KEY_ROW1__GPIO2_IO_16 0x00BC 0x0404 0x0000 0x5 0x0
+#define MX6SX_PAD_KEY_ROW1__WEIM_DATA_31 0x00BC 0x0404 0x0000 0x6 0x0
+#define MX6SX_PAD_KEY_ROW1__SAI2_RX_DATA_0 0x00BC 0x0404 0x080C 0x7 0x0
+#define MX6SX_PAD_KEY_ROW1__M4_NMI 0x00BC 0x0404 0x0000 0x8 0x0
+#define MX6SX_PAD_KEY_ROW2__KPP_ROW_2 0x00C0 0x0408 0x0000 0x0 0x0
+#define MX6SX_PAD_KEY_ROW2__USDHC4_WP 0x00C0 0x0408 0x0878 0x1 0x1
+#define MX6SX_PAD_KEY_ROW2__UART5_CTS_B 0x00C0 0x0408 0x0000 0x2 0x0
+#define MX6SX_PAD_KEY_ROW2__CAN1_RX 0x00C0 0x0408 0x068C 0x3 0x1
+#define MX6SX_PAD_KEY_ROW2__CANFD_RX1 0x00C0 0x0408 0x0694 0x4 0x1
+#define MX6SX_PAD_KEY_ROW2__GPIO2_IO_17 0x00C0 0x0408 0x0000 0x5 0x0
+#define MX6SX_PAD_KEY_ROW2__WEIM_DATA_29 0x00C0 0x0408 0x0000 0x6 0x0
+#define MX6SX_PAD_KEY_ROW2__ECSPI1_SS3 0x00C0 0x0408 0x0000 0x7 0x0
+#define MX6SX_PAD_KEY_ROW3__KPP_ROW_3 0x00C4 0x040C 0x0000 0x0 0x0
+#define MX6SX_PAD_KEY_ROW3__USDHC3_LCTL 0x00C4 0x040C 0x0000 0x1 0x0
+#define MX6SX_PAD_KEY_ROW3__UART5_RX 0x00C4 0x040C 0x0850 0x2 0x3
+#define MX6SX_PAD_KEY_ROW3__UART5_TX 0x00C4 0x040C 0x0000 0x2 0x0
+#define MX6SX_PAD_KEY_ROW3__CAN2_RX 0x00C4 0x040C 0x0690 0x3 0x1
+#define MX6SX_PAD_KEY_ROW3__CANFD_RX2 0x00C4 0x040C 0x0698 0x4 0x1
+#define MX6SX_PAD_KEY_ROW3__GPIO2_IO_18 0x00C4 0x040C 0x0000 0x5 0x0
+#define MX6SX_PAD_KEY_ROW3__WEIM_DTACK_B 0x00C4 0x040C 0x0000 0x6 0x0
+#define MX6SX_PAD_KEY_ROW3__ECSPI1_SS1 0x00C4 0x040C 0x0000 0x7 0x0
+#define MX6SX_PAD_KEY_ROW4__KPP_ROW_4 0x00C8 0x0410 0x0000 0x0 0x0
+#define MX6SX_PAD_KEY_ROW4__ENET2_MDIO 0x00C8 0x0410 0x0770 0x1 0x3
+#define MX6SX_PAD_KEY_ROW4__I2C3_SDA 0x00C8 0x0410 0x07BC 0x2 0x2
+#define MX6SX_PAD_KEY_ROW4__USDHC1_LCTL 0x00C8 0x0410 0x0000 0x3 0x0
+#define MX6SX_PAD_KEY_ROW4__AUDMUX_AUD5_RXFS 0x00C8 0x0410 0x0668 0x4 0x0
+#define MX6SX_PAD_KEY_ROW4__GPIO2_IO_19 0x00C8 0x0410 0x0000 0x5 0x0
+#define MX6SX_PAD_KEY_ROW4__WEIM_ACLK_FREERUN 0x00C8 0x0410 0x0000 0x6 0x0
+#define MX6SX_PAD_KEY_ROW4__SAI2_RX_SYNC 0x00C8 0x0410 0x0810 0x7 0x0
+#define MX6SX_PAD_LCD1_CLK__LCDIF1_CLK 0x00CC 0x0414 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_CLK__LCDIF1_WR_RWN 0x00CC 0x0414 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_CLK__AUDMUX_AUD3_RXC 0x00CC 0x0414 0x0634 0x2 0x1
+#define MX6SX_PAD_LCD1_CLK__ENET1_1588_EVENT2_IN 0x00CC 0x0414 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_CLK__CSI1_DATA_16 0x00CC 0x0414 0x06DC 0x4 0x0
+#define MX6SX_PAD_LCD1_CLK__GPIO3_IO_0 0x00CC 0x0414 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_CLK__USDHC1_WP 0x00CC 0x0414 0x0868 0x6 0x0
+#define MX6SX_PAD_LCD1_CLK__SIM_M_HADDR_16 0x00CC 0x0414 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_CLK__VADC_TEST_0 0x00CC 0x0414 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_CLK__MMDC_DEBUG_0 0x00CC 0x0414 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA00__LCDIF1_DATA_0 0x00D0 0x0418 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA00__WEIM_CS1_B 0x00D0 0x0418 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA00__M4_TRACE_0 0x00D0 0x0418 0x0000 0x2 0x0
+#define MX6SX_PAD_LCD1_DATA00__KITTEN_TRACE_0 0x00D0 0x0418 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA00__CSI1_DATA_20 0x00D0 0x0418 0x06EC 0x4 0x0
+#define MX6SX_PAD_LCD1_DATA00__GPIO3_IO_1 0x00D0 0x0418 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA00__SRC_BT_CFG_0 0x00D0 0x0418 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA00__SIM_M_HADDR_21 0x00D0 0x0418 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA00__VADC_TEST_5 0x00D0 0x0418 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA00__MMDC_DEBUG_5 0x00D0 0x0418 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA01__LCDIF1_DATA_1 0x00D4 0x041C 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA01__WEIM_CS2_B 0x00D4 0x041C 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA01__M4_TRACE_1 0x00D4 0x041C 0x0000 0x2 0x0
+#define MX6SX_PAD_LCD1_DATA01__KITTEN_TRACE_1 0x00D4 0x041C 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA01__CSI1_DATA_21 0x00D4 0x041C 0x06F0 0x4 0x0
+#define MX6SX_PAD_LCD1_DATA01__GPIO3_IO_2 0x00D4 0x041C 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA01__SRC_BT_CFG_1 0x00D4 0x041C 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA01__SIM_M_HADDR_22 0x00D4 0x041C 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA01__VADC_TEST_6 0x00D4 0x041C 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA01__MMDC_DEBUG_6 0x00D4 0x041C 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA02__LCDIF1_DATA_2 0x00D8 0x0420 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA02__WEIM_CS3_B 0x00D8 0x0420 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA02__M4_TRACE_2 0x00D8 0x0420 0x0000 0x2 0x0
+#define MX6SX_PAD_LCD1_DATA02__KITTEN_TRACE_2 0x00D8 0x0420 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA02__CSI1_DATA_22 0x00D8 0x0420 0x06F4 0x4 0x0
+#define MX6SX_PAD_LCD1_DATA02__GPIO3_IO_3 0x00D8 0x0420 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA02__SRC_BT_CFG_2 0x00D8 0x0420 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA02__SIM_M_HADDR_23 0x00D8 0x0420 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA02__VADC_TEST_7 0x00D8 0x0420 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA02__MMDC_DEBUG_7 0x00D8 0x0420 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA03__LCDIF1_DATA_3 0x00DC 0x0424 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA03__WEIM_ADDR_24 0x00DC 0x0424 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA03__M4_TRACE_3 0x00DC 0x0424 0x0000 0x2 0x0
+#define MX6SX_PAD_LCD1_DATA03__KITTEN_TRACE_3 0x00DC 0x0424 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA03__CSI1_DATA_23 0x00DC 0x0424 0x06F8 0x4 0x0
+#define MX6SX_PAD_LCD1_DATA03__GPIO3_IO_4 0x00DC 0x0424 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA03__SRC_BT_CFG_3 0x00DC 0x0424 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA03__SIM_M_HADDR_24 0x00DC 0x0424 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA03__VADC_TEST_8 0x00DC 0x0424 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA03__MMDC_DEBUG_8 0x00DC 0x0424 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA04__LCDIF1_DATA_4 0x00E0 0x0428 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA04__WEIM_ADDR_25 0x00E0 0x0428 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA04__KITTEN_TRACE_4 0x00E0 0x0428 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA04__CSI1_VSYNC 0x00E0 0x0428 0x0708 0x4 0x1
+#define MX6SX_PAD_LCD1_DATA04__GPIO3_IO_5 0x00E0 0x0428 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA04__SRC_BT_CFG_4 0x00E0 0x0428 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA04__SIM_M_HADDR_25 0x00E0 0x0428 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA04__VADC_TEST_9 0x00E0 0x0428 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA04__MMDC_DEBUG_9 0x00E0 0x0428 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA05__LCDIF1_DATA_5 0x00E4 0x042C 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA05__WEIM_ADDR_26 0x00E4 0x042C 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA05__KITTEN_TRACE_5 0x00E4 0x042C 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA05__CSI1_HSYNC 0x00E4 0x042C 0x0700 0x4 0x1
+#define MX6SX_PAD_LCD1_DATA05__GPIO3_IO_6 0x00E4 0x042C 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA05__SRC_BT_CFG_5 0x00E4 0x042C 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA05__SIM_M_HADDR_26 0x00E4 0x042C 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA05__VADC_TEST_10 0x00E4 0x042C 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA05__MMDC_DEBUG_10 0x00E4 0x042C 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA06__LCDIF1_DATA_6 0x00E8 0x0430 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA06__WEIM_EB_B_2 0x00E8 0x0430 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA06__KITTEN_TRACE_6 0x00E8 0x0430 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA06__CSI1_PIXCLK 0x00E8 0x0430 0x0704 0x4 0x1
+#define MX6SX_PAD_LCD1_DATA06__GPIO3_IO_7 0x00E8 0x0430 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA06__SRC_BT_CFG_6 0x00E8 0x0430 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA06__SIM_M_HADDR_27 0x00E8 0x0430 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA06__VADC_TEST_11 0x00E8 0x0430 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA06__MMDC_DEBUG_11 0x00E8 0x0430 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA07__LCDIF1_DATA_7 0x00EC 0x0434 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA07__WEIM_EB_B_3 0x00EC 0x0434 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA07__KITTEN_TRACE_7 0x00EC 0x0434 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA07__CSI1_MCLK 0x00EC 0x0434 0x0000 0x4 0x0
+#define MX6SX_PAD_LCD1_DATA07__GPIO3_IO_8 0x00EC 0x0434 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA07__SRC_BT_CFG_7 0x00EC 0x0434 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA07__SIM_M_HADDR_28 0x00EC 0x0434 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA07__VADC_TEST_12 0x00EC 0x0434 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA07__MMDC_DEBUG_12 0x00EC 0x0434 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA08__LCDIF1_DATA_8 0x00F0 0x0438 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA08__WEIM_AD_8 0x00F0 0x0438 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA08__KITTEN_TRACE_8 0x00F0 0x0438 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA08__CSI1_DATA_9 0x00F0 0x0438 0x06C4 0x4 0x1
+#define MX6SX_PAD_LCD1_DATA08__GPIO3_IO_9 0x00F0 0x0438 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA08__SRC_BT_CFG_8 0x00F0 0x0438 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA08__SIM_M_HADDR_29 0x00F0 0x0438 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA08__VADC_TEST_13 0x00F0 0x0438 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA08__MMDC_DEBUG_13 0x00F0 0x0438 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA09__LCDIF1_DATA_9 0x00F4 0x043C 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA09__WEIM_AD_9 0x00F4 0x043C 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA09__KITTEN_TRACE_9 0x00F4 0x043C 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA09__CSI1_DATA_8 0x00F4 0x043C 0x06C0 0x4 0x1
+#define MX6SX_PAD_LCD1_DATA09__GPIO3_IO_10 0x00F4 0x043C 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA09__SRC_BT_CFG_9 0x00F4 0x043C 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA09__SIM_M_HADDR_30 0x00F4 0x043C 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA09__VADC_TEST_14 0x00F4 0x043C 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA09__MMDC_DEBUG_14 0x00F4 0x043C 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA10__LCDIF1_DATA_10 0x00F8 0x0440 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA10__WEIM_AD_10 0x00F8 0x0440 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA10__KITTEN_TRACE_10 0x00F8 0x0440 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA10__CSI1_DATA_7 0x00F8 0x0440 0x06BC 0x4 0x1
+#define MX6SX_PAD_LCD1_DATA10__GPIO3_IO_11 0x00F8 0x0440 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA10__SRC_BT_CFG_10 0x00F8 0x0440 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA10__SIM_M_HADDR_31 0x00F8 0x0440 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA10__VADC_TEST_15 0x00F8 0x0440 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA10__MMDC_DEBUG_15 0x00F8 0x0440 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA11__LCDIF1_DATA_11 0x00FC 0x0444 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA11__WEIM_AD_11 0x00FC 0x0444 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA11__KITTEN_TRACE_11 0x00FC 0x0444 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA11__CSI1_DATA_6 0x00FC 0x0444 0x06B8 0x4 0x1
+#define MX6SX_PAD_LCD1_DATA11__GPIO3_IO_12 0x00FC 0x0444 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA11__SRC_BT_CFG_11 0x00FC 0x0444 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA11__SIM_M_HBURST_0 0x00FC 0x0444 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA11__VADC_TEST_16 0x00FC 0x0444 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA11__MMDC_DEBUG_16 0x00FC 0x0444 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA12__LCDIF1_DATA_12 0x0100 0x0448 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA12__WEIM_AD_12 0x0100 0x0448 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA12__KITTEN_TRACE_12 0x0100 0x0448 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA12__CSI1_DATA_5 0x0100 0x0448 0x06B4 0x4 0x1
+#define MX6SX_PAD_LCD1_DATA12__GPIO3_IO_13 0x0100 0x0448 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA12__SRC_BT_CFG_12 0x0100 0x0448 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA12__SIM_M_HBURST_1 0x0100 0x0448 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA12__VADC_TEST_17 0x0100 0x0448 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA12__MMDC_DEBUG_17 0x0100 0x0448 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA13__LCDIF1_DATA_13 0x0104 0x044C 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA13__WEIM_AD_13 0x0104 0x044C 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA13__KITTEN_TRACE_13 0x0104 0x044C 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA13__CSI1_DATA_4 0x0104 0x044C 0x06B0 0x4 0x1
+#define MX6SX_PAD_LCD1_DATA13__GPIO3_IO_14 0x0104 0x044C 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA13__SRC_BT_CFG_13 0x0104 0x044C 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA13__SIM_M_HBURST_2 0x0104 0x044C 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA13__VADC_TEST_18 0x0104 0x044C 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA13__MMDC_DEBUG_18 0x0104 0x044C 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA14__LCDIF1_DATA_14 0x0108 0x0450 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA14__WEIM_AD_14 0x0108 0x0450 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA14__KITTEN_TRACE_14 0x0108 0x0450 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA14__CSI1_DATA_3 0x0108 0x0450 0x06AC 0x4 0x1
+#define MX6SX_PAD_LCD1_DATA14__GPIO3_IO_15 0x0108 0x0450 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA14__SRC_BT_CFG_14 0x0108 0x0450 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA14__SIM_M_HMASTLOCK 0x0108 0x0450 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA14__VADC_TEST_19 0x0108 0x0450 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA14__MMDC_DEBUG_19 0x0108 0x0450 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA15__LCDIF1_DATA_15 0x010C 0x0454 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA15__WEIM_AD_15 0x010C 0x0454 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA15__KITTEN_TRACE_15 0x010C 0x0454 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA15__CSI1_DATA_2 0x010C 0x0454 0x06A8 0x4 0x1
+#define MX6SX_PAD_LCD1_DATA15__GPIO3_IO_16 0x010C 0x0454 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA15__SRC_BT_CFG_15 0x010C 0x0454 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA15__SIM_M_HPROT_0 0x010C 0x0454 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA15__VDEC_DEBUG_0 0x010C 0x0454 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA15__MMDC_DEBUG_20 0x010C 0x0454 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA16__LCDIF1_DATA_16 0x0110 0x0458 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA16__WEIM_ADDR_16 0x0110 0x0458 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA16__M4_TRACE_CLK 0x0110 0x0458 0x0000 0x2 0x0
+#define MX6SX_PAD_LCD1_DATA16__KITTEN_TRACE_CLK 0x0110 0x0458 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA16__CSI1_DATA_1 0x0110 0x0458 0x06A4 0x4 0x0
+#define MX6SX_PAD_LCD1_DATA16__GPIO3_IO_17 0x0110 0x0458 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA16__SRC_BT_CFG_24 0x0110 0x0458 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA16__SIM_M_HPROT_1 0x0110 0x0458 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA16__VDEC_DEBUG_1 0x0110 0x0458 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA16__MMDC_DEBUG_21 0x0110 0x0458 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA17__LCDIF1_DATA_17 0x0114 0x045C 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA17__WEIM_ADDR_17 0x0114 0x045C 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA17__KITTEN_TRACE_CTL 0x0114 0x045C 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA17__CSI1_DATA_0 0x0114 0x045C 0x06A0 0x4 0x0
+#define MX6SX_PAD_LCD1_DATA17__GPIO3_IO_18 0x0114 0x045C 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA17__SRC_BT_CFG_25 0x0114 0x045C 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA17__SIM_M_HPROT_2 0x0114 0x045C 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA17__VDEC_DEBUG_2 0x0114 0x045C 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA17__MMDC_DEBUG_22 0x0114 0x045C 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA18__LCDIF1_DATA_18 0x0118 0x0460 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA18__WEIM_ADDR_18 0x0118 0x0460 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA18__M4_EVENTO 0x0118 0x0460 0x0000 0x2 0x0
+#define MX6SX_PAD_LCD1_DATA18__KITTEN_EVENTO 0x0118 0x0460 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA18__CSI1_DATA_15 0x0118 0x0460 0x06D8 0x4 0x0
+#define MX6SX_PAD_LCD1_DATA18__GPIO3_IO_19 0x0118 0x0460 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA18__SRC_BT_CFG_26 0x0118 0x0460 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA18__SIM_M_HPROT_3 0x0118 0x0460 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA18__VDEC_DEBUG_3 0x0118 0x0460 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA18__MMDC_DEBUG_23 0x0118 0x0460 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA19__LCDIF1_DATA_19 0x011C 0x0464 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA19__WEIM_ADDR_19 0x011C 0x0464 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA19__M4_TRACE_SWO 0x011C 0x0464 0x0000 0x2 0x0
+#define MX6SX_PAD_LCD1_DATA19__CSI1_DATA_14 0x011C 0x0464 0x06D4 0x4 0x0
+#define MX6SX_PAD_LCD1_DATA19__GPIO3_IO_20 0x011C 0x0464 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA19__SRC_BT_CFG_27 0x011C 0x0464 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA19__SIM_M_HREADYOUT 0x011C 0x0464 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA19__VDEC_DEBUG_4 0x011C 0x0464 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA19__MMDC_DEBUG_24 0x011C 0x0464 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA20__LCDIF1_DATA_20 0x0120 0x0468 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA20__WEIM_ADDR_20 0x0120 0x0468 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA20__PWM8_OUT 0x0120 0x0468 0x0000 0x2 0x0
+#define MX6SX_PAD_LCD1_DATA20__ENET1_1588_EVENT2_OUT 0x0120 0x0468 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA20__CSI1_DATA_13 0x0120 0x0468 0x06D0 0x4 0x0
+#define MX6SX_PAD_LCD1_DATA20__GPIO3_IO_21 0x0120 0x0468 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA20__SRC_BT_CFG_28 0x0120 0x0468 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA20__SIM_M_HRESP 0x0120 0x0468 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA20__VDEC_DEBUG_5 0x0120 0x0468 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA20__MMDC_DEBUG_25 0x0120 0x0468 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA21__LCDIF1_DATA_21 0x0124 0x046C 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA21__WEIM_ADDR_21 0x0124 0x046C 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA21__PWM7_OUT 0x0124 0x046C 0x0000 0x2 0x0
+#define MX6SX_PAD_LCD1_DATA21__ENET1_1588_EVENT3_OUT 0x0124 0x046C 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA21__CSI1_DATA_12 0x0124 0x046C 0x06CC 0x4 0x0
+#define MX6SX_PAD_LCD1_DATA21__GPIO3_IO_22 0x0124 0x046C 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA21__SRC_BT_CFG_29 0x0124 0x046C 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA21__SIM_M_HSIZE_0 0x0124 0x046C 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA21__VDEC_DEBUG_6 0x0124 0x046C 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA21__MMDC_DEBUG_26 0x0124 0x046C 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA22__LCDIF1_DATA_22 0x0128 0x0470 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA22__WEIM_ADDR_22 0x0128 0x0470 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA22__PWM6_OUT 0x0128 0x0470 0x0000 0x2 0x0
+#define MX6SX_PAD_LCD1_DATA22__ENET2_1588_EVENT2_OUT 0x0128 0x0470 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA22__CSI1_DATA_11 0x0128 0x0470 0x06C8 0x4 0x0
+#define MX6SX_PAD_LCD1_DATA22__GPIO3_IO_23 0x0128 0x0470 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA22__SRC_BT_CFG_30 0x0128 0x0470 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA22__SIM_M_HSIZE_1 0x0128 0x0470 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA22__VDEC_DEBUG_7 0x0128 0x0470 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA22__MMDC_DEBUG_27 0x0128 0x0470 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_DATA23__LCDIF1_DATA_23 0x012C 0x0474 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_DATA23__WEIM_ADDR_23 0x012C 0x0474 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_DATA23__PWM5_OUT 0x012C 0x0474 0x0000 0x2 0x0
+#define MX6SX_PAD_LCD1_DATA23__ENET2_1588_EVENT3_OUT 0x012C 0x0474 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_DATA23__CSI1_DATA_10 0x012C 0x0474 0x06FC 0x4 0x0
+#define MX6SX_PAD_LCD1_DATA23__GPIO3_IO_24 0x012C 0x0474 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_DATA23__SRC_BT_CFG_31 0x012C 0x0474 0x0000 0x6 0x0
+#define MX6SX_PAD_LCD1_DATA23__SIM_M_HSIZE_2 0x012C 0x0474 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_DATA23__VDEC_DEBUG_8 0x012C 0x0474 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_DATA23__MMDC_DEBUG_28 0x012C 0x0474 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_ENABLE__LCDIF1_ENABLE 0x0130 0x0478 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_ENABLE__LCDIF1_RD_E 0x0130 0x0478 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_ENABLE__AUDMUX_AUD3_TXC 0x0130 0x0478 0x063C 0x2 0x1
+#define MX6SX_PAD_LCD1_ENABLE__ENET1_1588_EVENT3_IN 0x0130 0x0478 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_ENABLE__CSI1_DATA_17 0x0130 0x0478 0x06E0 0x4 0x0
+#define MX6SX_PAD_LCD1_ENABLE__GPIO3_IO_25 0x0130 0x0478 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_ENABLE__USDHC1_CD_B 0x0130 0x0478 0x0864 0x6 0x0
+#define MX6SX_PAD_LCD1_ENABLE__SIM_M_HADDR_17 0x0130 0x0478 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_ENABLE__VADC_TEST_1 0x0130 0x0478 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_ENABLE__MMDC_DEBUG_1 0x0130 0x0478 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_HSYNC__LCDIF1_HSYNC 0x0134 0x047C 0x07E0 0x0 0x0
+#define MX6SX_PAD_LCD1_HSYNC__LCDIF1_RS 0x0134 0x047C 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_HSYNC__AUDMUX_AUD3_TXD 0x0134 0x047C 0x0630 0x2 0x1
+#define MX6SX_PAD_LCD1_HSYNC__ENET2_1588_EVENT2_IN 0x0134 0x047C 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_HSYNC__CSI1_DATA_18 0x0134 0x047C 0x06E4 0x4 0x0
+#define MX6SX_PAD_LCD1_HSYNC__GPIO3_IO_26 0x0134 0x047C 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_HSYNC__USDHC2_WP 0x0134 0x047C 0x0870 0x6 0x0
+#define MX6SX_PAD_LCD1_HSYNC__SIM_M_HADDR_18 0x0134 0x047C 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_HSYNC__VADC_TEST_2 0x0134 0x047C 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_HSYNC__MMDC_DEBUG_2 0x0134 0x047C 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_RESET__LCDIF1_RESET 0x0138 0x0480 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_RESET__LCDIF1_CS 0x0138 0x0480 0x0000 0x1 0x0
+#define MX6SX_PAD_LCD1_RESET__AUDMUX_AUD3_RXD 0x0138 0x0480 0x062C 0x2 0x1
+#define MX6SX_PAD_LCD1_RESET__KITTEN_EVENTI 0x0138 0x0480 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_RESET__M4_EVENTI 0x0138 0x0480 0x0000 0x4 0x0
+#define MX6SX_PAD_LCD1_RESET__GPIO3_IO_27 0x0138 0x0480 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_RESET__CCM_PMIC_RDY 0x0138 0x0480 0x069C 0x6 0x0
+#define MX6SX_PAD_LCD1_RESET__SIM_M_HADDR_20 0x0138 0x0480 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_RESET__VADC_TEST_4 0x0138 0x0480 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_RESET__MMDC_DEBUG_4 0x0138 0x0480 0x0000 0x9 0x0
+#define MX6SX_PAD_LCD1_VSYNC__LCDIF1_VSYNC 0x013C 0x0484 0x0000 0x0 0x0
+#define MX6SX_PAD_LCD1_VSYNC__LCDIF1_BUSY 0x013C 0x0484 0x07E0 0x1 0x1
+#define MX6SX_PAD_LCD1_VSYNC__AUDMUX_AUD3_TXFS 0x013C 0x0484 0x0640 0x2 0x1
+#define MX6SX_PAD_LCD1_VSYNC__ENET2_1588_EVENT3_IN 0x013C 0x0484 0x0000 0x3 0x0
+#define MX6SX_PAD_LCD1_VSYNC__CSI1_DATA_19 0x013C 0x0484 0x06E8 0x4 0x0
+#define MX6SX_PAD_LCD1_VSYNC__GPIO3_IO_28 0x013C 0x0484 0x0000 0x5 0x0
+#define MX6SX_PAD_LCD1_VSYNC__USDHC2_CD_B 0x013C 0x0484 0x086C 0x6 0x0
+#define MX6SX_PAD_LCD1_VSYNC__SIM_M_HADDR_19 0x013C 0x0484 0x0000 0x7 0x0
+#define MX6SX_PAD_LCD1_VSYNC__VADC_TEST_3 0x013C 0x0484 0x0000 0x8 0x0
+#define MX6SX_PAD_LCD1_VSYNC__MMDC_DEBUG_3 0x013C 0x0484 0x0000 0x9 0x0
+#define MX6SX_PAD_NAND_ALE__RAWNAND_ALE 0x0140 0x0488 0x0000 0x0 0x0
+#define MX6SX_PAD_NAND_ALE__I2C3_SDA 0x0140 0x0488 0x07BC 0x1 0x0
+#define MX6SX_PAD_NAND_ALE__QSPI2_A_SS0_B 0x0140 0x0488 0x0000 0x2 0x0
+#define MX6SX_PAD_NAND_ALE__ECSPI2_SS0 0x0140 0x0488 0x072C 0x3 0x0
+#define MX6SX_PAD_NAND_ALE__ESAI_TX3_RX2 0x0140 0x0488 0x079C 0x4 0x0
+#define MX6SX_PAD_NAND_ALE__GPIO4_IO_0 0x0140 0x0488 0x0000 0x5 0x0
+#define MX6SX_PAD_NAND_ALE__WEIM_CS0_B 0x0140 0x0488 0x0000 0x6 0x0
+#define MX6SX_PAD_NAND_ALE__TPSMP_HDATA_0 0x0140 0x0488 0x0000 0x7 0x0
+#define MX6SX_PAD_NAND_ALE__ANATOP_USBPHY1_TSTI_TX_EN 0x0140 0x0488 0x0000 0x8 0x0
+#define MX6SX_PAD_NAND_ALE__SDMA_DEBUG_PC_12 0x0140 0x0488 0x0000 0x9 0x0
+#define MX6SX_PAD_NAND_CE0_B__RAWNAND_CE0_B 0x0144 0x048C 0x0000 0x0 0x0
+#define MX6SX_PAD_NAND_CE0_B__USDHC2_VSELECT 0x0144 0x048C 0x0000 0x1 0x0
+#define MX6SX_PAD_NAND_CE0_B__QSPI2_A_DATA_2 0x0144 0x048C 0x0000 0x2 0x0
+#define MX6SX_PAD_NAND_CE0_B__AUDMUX_AUD4_TXC 0x0144 0x048C 0x0654 0x3 0x0
+#define MX6SX_PAD_NAND_CE0_B__ESAI_TX_CLK 0x0144 0x048C 0x078C 0x4 0x0
+#define MX6SX_PAD_NAND_CE0_B__GPIO4_IO_1 0x0144 0x048C 0x0000 0x5 0x0
+#define MX6SX_PAD_NAND_CE0_B__WEIM_LBA_B 0x0144 0x048C 0x0000 0x6 0x0
+#define MX6SX_PAD_NAND_CE0_B__TPSMP_HDATA_3 0x0144 0x048C 0x0000 0x7 0x0
+#define MX6SX_PAD_NAND_CE0_B__ANATOP_USBPHY1_TSTI_TX_HIZ 0x0144 0x048C 0x0000 0x8 0x0
+#define MX6SX_PAD_NAND_CE0_B__SDMA_DEBUG_PC_9 0x0144 0x048C 0x0000 0x9 0x0
+#define MX6SX_PAD_NAND_CE1_B__RAWNAND_CE1_B 0x0148 0x0490 0x0000 0x0 0x0
+#define MX6SX_PAD_NAND_CE1_B__USDHC3_RESET_B 0x0148 0x0490 0x0000 0x1 0x0
+#define MX6SX_PAD_NAND_CE1_B__QSPI2_A_DATA_3 0x0148 0x0490 0x0000 0x2 0x0
+#define MX6SX_PAD_NAND_CE1_B__AUDMUX_AUD4_TXD 0x0148 0x0490 0x0648 0x3 0x0
+#define MX6SX_PAD_NAND_CE1_B__ESAI_TX0 0x0148 0x0490 0x0790 0x4 0x0
+#define MX6SX_PAD_NAND_CE1_B__GPIO4_IO_2 0x0148 0x0490 0x0000 0x5 0x0
+#define MX6SX_PAD_NAND_CE1_B__WEIM_OE 0x0148 0x0490 0x0000 0x6 0x0
+#define MX6SX_PAD_NAND_CE1_B__TPSMP_HDATA_4 0x0148 0x0490 0x0000 0x7 0x0
+#define MX6SX_PAD_NAND_CE1_B__ANATOP_USBPHY1_TSTI_TX_LS_MODE 0x0148 0x0490 0x0000 0x8 0x0
+#define MX6SX_PAD_NAND_CE1_B__SDMA_DEBUG_PC_8 0x0148 0x0490 0x0000 0x9 0x0
+#define MX6SX_PAD_NAND_CLE__RAWNAND_CLE 0x014C 0x0494 0x0000 0x0 0x0
+#define MX6SX_PAD_NAND_CLE__I2C3_SCL 0x014C 0x0494 0x07B8 0x1 0x0
+#define MX6SX_PAD_NAND_CLE__QSPI2_A_SCLK 0x014C 0x0494 0x0000 0x2 0x0
+#define MX6SX_PAD_NAND_CLE__ECSPI2_SCLK 0x014C 0x0494 0x0720 0x3 0x0
+#define MX6SX_PAD_NAND_CLE__ESAI_TX2_RX3 0x014C 0x0494 0x0798 0x4 0x0
+#define MX6SX_PAD_NAND_CLE__GPIO4_IO_3 0x014C 0x0494 0x0000 0x5 0x0
+#define MX6SX_PAD_NAND_CLE__WEIM_BCLK 0x014C 0x0494 0x0000 0x6 0x0
+#define MX6SX_PAD_NAND_CLE__TPSMP_CLK 0x014C 0x0494 0x0000 0x7 0x0
+#define MX6SX_PAD_NAND_CLE__ANATOP_USBPHY1_TSTI_TX_DP 0x014C 0x0494 0x0000 0x8 0x0
+#define MX6SX_PAD_NAND_CLE__SDMA_DEBUG_PC_13 0x014C 0x0494 0x0000 0x9 0x0
+#define MX6SX_PAD_NAND_DATA00__RAWNAND_DATA00 0x0150 0x0498 0x0000 0x0 0x0
+#define MX6SX_PAD_NAND_DATA00__USDHC1_DATA4 0x0150 0x0498 0x0000 0x1 0x0
+#define MX6SX_PAD_NAND_DATA00__QSPI2_B_DATA_1 0x0150 0x0498 0x0000 0x2 0x0
+#define MX6SX_PAD_NAND_DATA00__ECSPI5_MISO 0x0150 0x0498 0x0754 0x3 0x0
+#define MX6SX_PAD_NAND_DATA00__ESAI_RX_CLK 0x0150 0x0498 0x0788 0x4 0x0
+#define MX6SX_PAD_NAND_DATA00__GPIO4_IO_4 0x0150 0x0498 0x0000 0x5 0x0
+#define MX6SX_PAD_NAND_DATA00__WEIM_AD_0 0x0150 0x0498 0x0000 0x6 0x0
+#define MX6SX_PAD_NAND_DATA00__TPSMP_HDATA_7 0x0150 0x0498 0x0000 0x7 0x0
+#define MX6SX_PAD_NAND_DATA00__ANATOP_USBPHY1_TSTO_RX_DISCON_DET 0x0150 0x0498 0x0000 0x8 0x0
+#define MX6SX_PAD_NAND_DATA00__SDMA_DEBUG_EVT_CHN_LINES_5 0x0150 0x0498 0x0000 0x9 0x0
+#define MX6SX_PAD_NAND_DATA01__RAWNAND_DATA01 0x0154 0x049C 0x0000 0x0 0x0
+#define MX6SX_PAD_NAND_DATA01__USDHC1_DATA5 0x0154 0x049C 0x0000 0x1 0x0
+#define MX6SX_PAD_NAND_DATA01__QSPI2_B_DATA_0 0x0154 0x049C 0x0000 0x2 0x0
+#define MX6SX_PAD_NAND_DATA01__ECSPI5_MOSI 0x0154 0x049C 0x0758 0x3 0x0
+#define MX6SX_PAD_NAND_DATA01__ESAI_RX_FS 0x0154 0x049C 0x0778 0x4 0x0
+#define MX6SX_PAD_NAND_DATA01__GPIO4_IO_5 0x0154 0x049C 0x0000 0x5 0x0
+#define MX6SX_PAD_NAND_DATA01__WEIM_AD_1 0x0154 0x049C 0x0000 0x6 0x0
+#define MX6SX_PAD_NAND_DATA01__TPSMP_HDATA_8 0x0154 0x049C 0x0000 0x7 0x0
+#define MX6SX_PAD_NAND_DATA01__ANATOP_USBPHY1_TSTO_RX_HS_RXD 0x0154 0x049C 0x0000 0x8 0x0
+#define MX6SX_PAD_NAND_DATA01__SDMA_DEBUG_EVT_CHN_LINES_4 0x0154 0x049C 0x0000 0x9 0x0
+#define MX6SX_PAD_NAND_DATA02__RAWNAND_DATA02 0x0158 0x04A0 0x0000 0x0 0x0
+#define MX6SX_PAD_NAND_DATA02__USDHC1_DATA6 0x0158 0x04A0 0x0000 0x1 0x0
+#define MX6SX_PAD_NAND_DATA02__QSPI2_B_SCLK 0x0158 0x04A0 0x0000 0x2 0x0
+#define MX6SX_PAD_NAND_DATA02__ECSPI5_SCLK 0x0158 0x04A0 0x0750 0x3 0x0
+#define MX6SX_PAD_NAND_DATA02__ESAI_TX_HF_CLK 0x0158 0x04A0 0x0784 0x4 0x0
+#define MX6SX_PAD_NAND_DATA02__GPIO4_IO_6 0x0158 0x04A0 0x0000 0x5 0x0
+#define MX6SX_PAD_NAND_DATA02__WEIM_AD_2 0x0158 0x04A0 0x0000 0x6 0x0
+#define MX6SX_PAD_NAND_DATA02__TPSMP_HDATA_9 0x0158 0x04A0 0x0000 0x7 0x0
+#define MX6SX_PAD_NAND_DATA02__ANATOP_USBPHY2_TSTO_PLL_CLK20DIV 0x0158 0x04A0 0x0000 0x8 0x0
+#define MX6SX_PAD_NAND_DATA02__SDMA_DEBUG_EVT_CHN_LINES_3 0x0158 0x04A0 0x0000 0x9 0x0
+#define MX6SX_PAD_NAND_DATA03__RAWNAND_DATA03 0x015C 0x04A4 0x0000 0x0 0x0
+#define MX6SX_PAD_NAND_DATA03__USDHC1_DATA7 0x015C 0x04A4 0x0000 0x1 0x0
+#define MX6SX_PAD_NAND_DATA03__QSPI2_B_SS0_B 0x015C 0x04A4 0x0000 0x2 0x0
+#define MX6SX_PAD_NAND_DATA03__ECSPI5_SS0 0x015C 0x04A4 0x075C 0x3 0x0
+#define MX6SX_PAD_NAND_DATA03__ESAI_RX_HF_CLK 0x015C 0x04A4 0x0780 0x4 0x0
+#define MX6SX_PAD_NAND_DATA03__GPIO4_IO_7 0x015C 0x04A4 0x0000 0x5 0x0
+#define MX6SX_PAD_NAND_DATA03__WEIM_AD_3 0x015C 0x04A4 0x0000 0x6 0x0
+#define MX6SX_PAD_NAND_DATA03__TPSMP_HDATA_10 0x015C 0x04A4 0x0000 0x7 0x0
+#define MX6SX_PAD_NAND_DATA03__ANATOP_USBPHY1_TSTO_RX_SQUELCH 0x015C 0x04A4 0x0000 0x8 0x0
+#define MX6SX_PAD_NAND_DATA03__SDMA_DEBUG_EVT_CHN_LINES_6 0x015C 0x04A4 0x0000 0x9 0x0
+#define MX6SX_PAD_NAND_DATA04__RAWNAND_DATA04 0x0160 0x04A8 0x0000 0x0 0x0
+#define MX6SX_PAD_NAND_DATA04__USDHC2_DATA4 0x0160 0x04A8 0x0000 0x1 0x0
+#define MX6SX_PAD_NAND_DATA04__QSPI2_B_SS1_B 0x0160 0x04A8 0x0000 0x2 0x0
+#define MX6SX_PAD_NAND_DATA04__UART3_RTS_B 0x0160 0x04A8 0x083C 0x3 0x0
+#define MX6SX_PAD_NAND_DATA04__AUDMUX_AUD4_RXFS 0x0160 0x04A8 0x0650 0x4 0x0
+#define MX6SX_PAD_NAND_DATA04__GPIO4_IO_8 0x0160 0x04A8 0x0000 0x5 0x0
+#define MX6SX_PAD_NAND_DATA04__WEIM_AD_4 0x0160 0x04A8 0x0000 0x6 0x0
+#define MX6SX_PAD_NAND_DATA04__TPSMP_HDATA_11 0x0160 0x04A8 0x0000 0x7 0x0
+#define MX6SX_PAD_NAND_DATA04__ANATOP_USBPHY2_TSTO_RX_SQUELCH 0x0160 0x04A8 0x0000 0x8 0x0
+#define MX6SX_PAD_NAND_DATA04__SDMA_DEBUG_CORE_STATE_0 0x0160 0x04A8 0x0000 0x9 0x0
+#define MX6SX_PAD_NAND_DATA05__RAWNAND_DATA05 0x0164 0x04AC 0x0000 0x0 0x0
+#define MX6SX_PAD_NAND_DATA05__USDHC2_DATA5 0x0164 0x04AC 0x0000 0x1 0x0
+#define MX6SX_PAD_NAND_DATA05__QSPI2_B_DQS 0x0164 0x04AC 0x0000 0x2 0x0
+#define MX6SX_PAD_NAND_DATA05__UART3_CTS_B 0x0164 0x04AC 0x0000 0x3 0x0
+#define MX6SX_PAD_NAND_DATA05__AUDMUX_AUD4_RXC 0x0164 0x04AC 0x064C 0x4 0x0
+#define MX6SX_PAD_NAND_DATA05__GPIO4_IO_9 0x0164 0x04AC 0x0000 0x5 0x0
+#define MX6SX_PAD_NAND_DATA05__WEIM_AD_5 0x0164 0x04AC 0x0000 0x6 0x0
+#define MX6SX_PAD_NAND_DATA05__TPSMP_HDATA_12 0x0164 0x04AC 0x0000 0x7 0x0
+#define MX6SX_PAD_NAND_DATA05__ANATOP_USBPHY2_TSTO_RX_DISCON_DET 0x0164 0x04AC 0x0000 0x8 0x0
+#define MX6SX_PAD_NAND_DATA05__SDMA_DEBUG_CORE_STATE_1 0x0164 0x04AC 0x0000 0x9 0x0
+#define MX6SX_PAD_NAND_DATA06__RAWNAND_DATA06 0x0168 0x04B0 0x0000 0x0 0x0
+#define MX6SX_PAD_NAND_DATA06__USDHC2_DATA6 0x0168 0x04B0 0x0000 0x1 0x0
+#define MX6SX_PAD_NAND_DATA06__QSPI2_A_SS1_B 0x0168 0x04B0 0x0000 0x2 0x0
+#define MX6SX_PAD_NAND_DATA06__UART3_RX 0x0168 0x04B0 0x0840 0x3 0x0
+#define MX6SX_PAD_NAND_DATA06__UART3_TX 0x0168 0x04B0 0x0000 0x3 0x0
+#define MX6SX_PAD_NAND_DATA06__PWM3_OUT 0x0168 0x04B0 0x0000 0x4 0x0
+#define MX6SX_PAD_NAND_DATA06__GPIO4_IO_10 0x0168 0x04B0 0x0000 0x5 0x0
+#define MX6SX_PAD_NAND_DATA06__WEIM_AD_6 0x0168 0x04B0 0x0000 0x6 0x0
+#define MX6SX_PAD_NAND_DATA06__TPSMP_HDATA_13 0x0168 0x04B0 0x0000 0x7 0x0
+#define MX6SX_PAD_NAND_DATA06__ANATOP_USBPHY2_TSTO_RX_FS_RXD 0x0168 0x04B0 0x0000 0x8 0x0
+#define MX6SX_PAD_NAND_DATA06__SDMA_DEBUG_CORE_STATE_2 0x0168 0x04B0 0x0000 0x9 0x0
+#define MX6SX_PAD_NAND_DATA07__RAWNAND_DATA07 0x016C 0x04B4 0x0000 0x0 0x0
+#define MX6SX_PAD_NAND_DATA07__USDHC2_DATA7 0x016C 0x04B4 0x0000 0x1 0x0
+#define MX6SX_PAD_NAND_DATA07__QSPI2_A_DQS 0x016C 0x04B4 0x0000 0x2 0x0
+#define MX6SX_PAD_NAND_DATA07__UART3_RX 0x016C 0x04B4 0x0840 0x3 0x1
+#define MX6SX_PAD_NAND_DATA07__UART3_TX 0x016C 0x04B4 0x0000 0x3 0x0
+#define MX6SX_PAD_NAND_DATA07__PWM4_OUT 0x016C 0x04B4 0x0000 0x4 0x0
+#define MX6SX_PAD_NAND_DATA07__GPIO4_IO_11 0x016C 0x04B4 0x0000 0x5 0x0
+#define MX6SX_PAD_NAND_DATA07__WEIM_AD_7 0x016C 0x04B4 0x0000 0x6 0x0
+#define MX6SX_PAD_NAND_DATA07__TPSMP_HDATA_14 0x016C 0x04B4 0x0000 0x7 0x0
+#define MX6SX_PAD_NAND_DATA07__ANATOP_USBPHY1_TSTO_RX_FS_RXD 0x016C 0x04B4 0x0000 0x8 0x0
+#define MX6SX_PAD_NAND_DATA07__SDMA_DEBUG_CORE_STATE_3 0x016C 0x04B4 0x0000 0x9 0x0
+#define MX6SX_PAD_NAND_RE_B__RAWNAND_RE_B 0x0170 0x04B8 0x0000 0x0 0x0
+#define MX6SX_PAD_NAND_RE_B__USDHC2_RESET_B 0x0170 0x04B8 0x0000 0x1 0x0
+#define MX6SX_PAD_NAND_RE_B__QSPI2_B_DATA_3 0x0170 0x04B8 0x0000 0x2 0x0
+#define MX6SX_PAD_NAND_RE_B__AUDMUX_AUD4_TXFS 0x0170 0x04B8 0x0658 0x3 0x0
+#define MX6SX_PAD_NAND_RE_B__ESAI_TX_FS 0x0170 0x04B8 0x077C 0x4 0x0
+#define MX6SX_PAD_NAND_RE_B__GPIO4_IO_12 0x0170 0x04B8 0x0000 0x5 0x0
+#define MX6SX_PAD_NAND_RE_B__WEIM_RW 0x0170 0x04B8 0x0000 0x6 0x0
+#define MX6SX_PAD_NAND_RE_B__TPSMP_HDATA_5 0x0170 0x04B8 0x0000 0x7 0x0
+#define MX6SX_PAD_NAND_RE_B__ANATOP_USBPHY2_TSTO_RX_HS_RXD 0x0170 0x04B8 0x0000 0x8 0x0
+#define MX6SX_PAD_NAND_RE_B__SDMA_DEBUG_PC_7 0x0170 0x04B8 0x0000 0x9 0x0
+#define MX6SX_PAD_NAND_READY_B__RAWNAND_READY_B 0x0174 0x04BC 0x0000 0x0 0x0
+#define MX6SX_PAD_NAND_READY_B__USDHC1_VSELECT 0x0174 0x04BC 0x0000 0x1 0x0
+#define MX6SX_PAD_NAND_READY_B__QSPI2_A_DATA_1 0x0174 0x04BC 0x0000 0x2 0x0
+#define MX6SX_PAD_NAND_READY_B__ECSPI2_MISO 0x0174 0x04BC 0x0724 0x3 0x0
+#define MX6SX_PAD_NAND_READY_B__ESAI_TX1 0x0174 0x04BC 0x0794 0x4 0x0
+#define MX6SX_PAD_NAND_READY_B__GPIO4_IO_13 0x0174 0x04BC 0x0000 0x5 0x0
+#define MX6SX_PAD_NAND_READY_B__WEIM_EB_B_1 0x0174 0x04BC 0x0000 0x6 0x0
+#define MX6SX_PAD_NAND_READY_B__TPSMP_HDATA_2 0x0174 0x04BC 0x0000 0x7 0x0
+#define MX6SX_PAD_NAND_READY_B__ANATOP_USBPHY1_TSTI_TX_DN 0x0174 0x04BC 0x0000 0x8 0x0
+#define MX6SX_PAD_NAND_READY_B__SDMA_DEBUG_PC_10 0x0174 0x04BC 0x0000 0x9 0x0
+#define MX6SX_PAD_NAND_WE_B__RAWNAND_WE_B 0x0178 0x04C0 0x0000 0x0 0x0
+#define MX6SX_PAD_NAND_WE_B__USDHC4_VSELECT 0x0178 0x04C0 0x0000 0x1 0x0
+#define MX6SX_PAD_NAND_WE_B__QSPI2_B_DATA_2 0x0178 0x04C0 0x0000 0x2 0x0
+#define MX6SX_PAD_NAND_WE_B__AUDMUX_AUD4_RXD 0x0178 0x04C0 0x0644 0x3 0x0
+#define MX6SX_PAD_NAND_WE_B__ESAI_TX5_RX0 0x0178 0x04C0 0x07A4 0x4 0x0
+#define MX6SX_PAD_NAND_WE_B__GPIO4_IO_14 0x0178 0x04C0 0x0000 0x5 0x0
+#define MX6SX_PAD_NAND_WE_B__WEIM_WAIT 0x0178 0x04C0 0x0000 0x6 0x0
+#define MX6SX_PAD_NAND_WE_B__TPSMP_HDATA_6 0x0178 0x04C0 0x0000 0x7 0x0
+#define MX6SX_PAD_NAND_WE_B__ANATOP_USBPHY1_TSTO_PLL_CLK20DIV 0x0178 0x04C0 0x0000 0x8 0x0
+#define MX6SX_PAD_NAND_WE_B__SDMA_DEBUG_PC_6 0x0178 0x04C0 0x0000 0x9 0x0
+#define MX6SX_PAD_NAND_WP_B__RAWNAND_WP_B 0x017C 0x04C4 0x0000 0x0 0x0
+#define MX6SX_PAD_NAND_WP_B__USDHC1_RESET_B 0x017C 0x04C4 0x0000 0x1 0x0
+#define MX6SX_PAD_NAND_WP_B__QSPI2_A_DATA_0 0x017C 0x04C4 0x0000 0x2 0x0
+#define MX6SX_PAD_NAND_WP_B__ECSPI2_MOSI 0x017C 0x04C4 0x0728 0x3 0x0
+#define MX6SX_PAD_NAND_WP_B__ESAI_TX4_RX1 0x017C 0x04C4 0x07A0 0x4 0x0
+#define MX6SX_PAD_NAND_WP_B__GPIO4_IO_15 0x017C 0x04C4 0x0000 0x5 0x0
+#define MX6SX_PAD_NAND_WP_B__WEIM_EB_B_0 0x017C 0x04C4 0x0000 0x6 0x0
+#define MX6SX_PAD_NAND_WP_B__TPSMP_HDATA_1 0x017C 0x04C4 0x0000 0x7 0x0
+#define MX6SX_PAD_NAND_WP_B__ANATOP_USBPHY1_TSTI_TX_HS_MODE 0x017C 0x04C4 0x0000 0x8 0x0
+#define MX6SX_PAD_NAND_WP_B__SDMA_DEBUG_PC_11 0x017C 0x04C4 0x0000 0x9 0x0
+#define MX6SX_PAD_QSPI1A_DATA0__QSPI1_A_DATA_0 0x0180 0x04C8 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1A_DATA0__USB_OTG2_OC 0x0180 0x04C8 0x085C 0x1 0x2
+#define MX6SX_PAD_QSPI1A_DATA0__ECSPI1_MOSI 0x0180 0x04C8 0x0718 0x2 0x1
+#define MX6SX_PAD_QSPI1A_DATA0__ESAI_TX4_RX1 0x0180 0x04C8 0x07A0 0x3 0x2
+#define MX6SX_PAD_QSPI1A_DATA0__CSI1_DATA_14 0x0180 0x04C8 0x06D4 0x4 0x1
+#define MX6SX_PAD_QSPI1A_DATA0__GPIO4_IO_16 0x0180 0x04C8 0x0000 0x5 0x0
+#define MX6SX_PAD_QSPI1A_DATA0__WEIM_DATA_6 0x0180 0x04C8 0x0000 0x6 0x0
+#define MX6SX_PAD_QSPI1A_DATA0__SIM_M_HADDR_3 0x0180 0x04C8 0x0000 0x7 0x0
+#define MX6SX_PAD_QSPI1A_DATA0__SDMA_DEBUG_BUS_DEVICE_3 0x0180 0x04C8 0x0000 0x9 0x0
+#define MX6SX_PAD_QSPI1A_DATA1__QSPI1_A_DATA_1 0x0184 0x04CC 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1A_DATA1__ANATOP_OTG1_ID 0x0184 0x04CC 0x0624 0x1 0x2
+#define MX6SX_PAD_QSPI1A_DATA1__ECSPI1_MISO 0x0184 0x04CC 0x0714 0x2 0x1
+#define MX6SX_PAD_QSPI1A_DATA1__ESAI_TX1 0x0184 0x04CC 0x0794 0x3 0x2
+#define MX6SX_PAD_QSPI1A_DATA1__CSI1_DATA_13 0x0184 0x04CC 0x06D0 0x4 0x1
+#define MX6SX_PAD_QSPI1A_DATA1__GPIO4_IO_17 0x0184 0x04CC 0x0000 0x5 0x0
+#define MX6SX_PAD_QSPI1A_DATA1__WEIM_DATA_5 0x0184 0x04CC 0x0000 0x6 0x0
+#define MX6SX_PAD_QSPI1A_DATA1__SIM_M_HADDR_4 0x0184 0x04CC 0x0000 0x7 0x0
+#define MX6SX_PAD_QSPI1A_DATA1__SDMA_DEBUG_PC_0 0x0184 0x04CC 0x0000 0x9 0x0
+#define MX6SX_PAD_QSPI1A_DATA2__QSPI1_A_DATA_2 0x0188 0x04D0 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1A_DATA2__USB_OTG1_PWR 0x0188 0x04D0 0x0000 0x1 0x0
+#define MX6SX_PAD_QSPI1A_DATA2__ECSPI5_SS1 0x0188 0x04D0 0x0000 0x2 0x0
+#define MX6SX_PAD_QSPI1A_DATA2__ESAI_TX_CLK 0x0188 0x04D0 0x078C 0x3 0x2
+#define MX6SX_PAD_QSPI1A_DATA2__CSI1_DATA_12 0x0188 0x04D0 0x06CC 0x4 0x1
+#define MX6SX_PAD_QSPI1A_DATA2__GPIO4_IO_18 0x0188 0x04D0 0x0000 0x5 0x0
+#define MX6SX_PAD_QSPI1A_DATA2__WEIM_DATA_4 0x0188 0x04D0 0x0000 0x6 0x0
+#define MX6SX_PAD_QSPI1A_DATA2__SIM_M_HADDR_6 0x0188 0x04D0 0x0000 0x7 0x0
+#define MX6SX_PAD_QSPI1A_DATA2__SDMA_DEBUG_PC_1 0x0188 0x04D0 0x0000 0x9 0x0
+#define MX6SX_PAD_QSPI1A_DATA3__QSPI1_A_DATA_3 0x018C 0x04D4 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1A_DATA3__USB_OTG1_OC 0x018C 0x04D4 0x0860 0x1 0x2
+#define MX6SX_PAD_QSPI1A_DATA3__ECSPI5_SS2 0x018C 0x04D4 0x0000 0x2 0x0
+#define MX6SX_PAD_QSPI1A_DATA3__ESAI_TX0 0x018C 0x04D4 0x0790 0x3 0x2
+#define MX6SX_PAD_QSPI1A_DATA3__CSI1_DATA_11 0x018C 0x04D4 0x06C8 0x4 0x1
+#define MX6SX_PAD_QSPI1A_DATA3__GPIO4_IO_19 0x018C 0x04D4 0x0000 0x5 0x0
+#define MX6SX_PAD_QSPI1A_DATA3__WEIM_DATA_3 0x018C 0x04D4 0x0000 0x6 0x0
+#define MX6SX_PAD_QSPI1A_DATA3__SIM_M_HADDR_7 0x018C 0x04D4 0x0000 0x7 0x0
+#define MX6SX_PAD_QSPI1A_DATA3__SDMA_DEBUG_PC_2 0x018C 0x04D4 0x0000 0x9 0x0
+#define MX6SX_PAD_QSPI1A_DQS__QSPI1_A_DQS 0x0190 0x04D8 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1A_DQS__CAN2_TX 0x0190 0x04D8 0x0000 0x1 0x0
+#define MX6SX_PAD_QSPI1A_DQS__CANFD_TX2 0x0190 0x04D8 0x0000 0x2 0x0
+#define MX6SX_PAD_QSPI1A_DQS__ECSPI5_MOSI 0x0190 0x04D8 0x0758 0x3 0x1
+#define MX6SX_PAD_QSPI1A_DQS__CSI1_DATA_15 0x0190 0x04D8 0x06D8 0x4 0x1
+#define MX6SX_PAD_QSPI1A_DQS__GPIO4_IO_20 0x0190 0x04D8 0x0000 0x5 0x0
+#define MX6SX_PAD_QSPI1A_DQS__WEIM_DATA_7 0x0190 0x04D8 0x0000 0x6 0x0
+#define MX6SX_PAD_QSPI1A_DQS__SIM_M_HADDR_13 0x0190 0x04D8 0x0000 0x7 0x0
+#define MX6SX_PAD_QSPI1A_DQS__SDMA_DEBUG_BUS_DEVICE_4 0x0190 0x04D8 0x0000 0x9 0x0
+#define MX6SX_PAD_QSPI1A_SCLK__QSPI1_A_SCLK 0x0194 0x04DC 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1A_SCLK__ANATOP_OTG2_ID 0x0194 0x04DC 0x0628 0x1 0x2
+#define MX6SX_PAD_QSPI1A_SCLK__ECSPI1_SCLK 0x0194 0x04DC 0x0710 0x2 0x1
+#define MX6SX_PAD_QSPI1A_SCLK__ESAI_TX2_RX3 0x0194 0x04DC 0x0798 0x3 0x2
+#define MX6SX_PAD_QSPI1A_SCLK__CSI1_DATA_1 0x0194 0x04DC 0x06A4 0x4 0x1
+#define MX6SX_PAD_QSPI1A_SCLK__GPIO4_IO_21 0x0194 0x04DC 0x0000 0x5 0x0
+#define MX6SX_PAD_QSPI1A_SCLK__WEIM_DATA_0 0x0194 0x04DC 0x0000 0x6 0x0
+#define MX6SX_PAD_QSPI1A_SCLK__SIM_M_HADDR_0 0x0194 0x04DC 0x0000 0x7 0x0
+#define MX6SX_PAD_QSPI1A_SCLK__SDMA_DEBUG_PC_5 0x0194 0x04DC 0x0000 0x9 0x0
+#define MX6SX_PAD_QSPI1A_SS0_B__QSPI1_A_SS0_B 0x0198 0x04E0 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1A_SS0_B__USB_OTG2_PWR 0x0198 0x04E0 0x0000 0x1 0x0
+#define MX6SX_PAD_QSPI1A_SS0_B__ECSPI1_SS0 0x0198 0x04E0 0x071C 0x2 0x1
+#define MX6SX_PAD_QSPI1A_SS0_B__ESAI_TX3_RX2 0x0198 0x04E0 0x079C 0x3 0x2
+#define MX6SX_PAD_QSPI1A_SS0_B__CSI1_DATA_0 0x0198 0x04E0 0x06A0 0x4 0x1
+#define MX6SX_PAD_QSPI1A_SS0_B__GPIO4_IO_22 0x0198 0x04E0 0x0000 0x5 0x0
+#define MX6SX_PAD_QSPI1A_SS0_B__WEIM_DATA_1 0x0198 0x04E0 0x0000 0x6 0x0
+#define MX6SX_PAD_QSPI1A_SS0_B__SIM_M_HADDR_1 0x0198 0x04E0 0x0000 0x7 0x0
+#define MX6SX_PAD_QSPI1A_SS0_B__SDMA_DEBUG_PC_4 0x0198 0x04E0 0x0000 0x9 0x0
+#define MX6SX_PAD_QSPI1A_SS1_B__QSPI1_A_SS1_B 0x019C 0x04E4 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1A_SS1_B__CAN1_RX 0x019C 0x04E4 0x068C 0x1 0x2
+#define MX6SX_PAD_QSPI1A_SS1_B__CANFD_RX1 0x019C 0x04E4 0x0694 0x2 0x2
+#define MX6SX_PAD_QSPI1A_SS1_B__ECSPI5_MISO 0x019C 0x04E4 0x0754 0x3 0x1
+#define MX6SX_PAD_QSPI1A_SS1_B__CSI1_DATA_10 0x019C 0x04E4 0x06FC 0x4 0x1
+#define MX6SX_PAD_QSPI1A_SS1_B__GPIO4_IO_23 0x019C 0x04E4 0x0000 0x5 0x0
+#define MX6SX_PAD_QSPI1A_SS1_B__WEIM_DATA_2 0x019C 0x04E4 0x0000 0x6 0x0
+#define MX6SX_PAD_QSPI1A_SS1_B__SIM_M_HADDR_12 0x019C 0x04E4 0x0000 0x7 0x0
+#define MX6SX_PAD_QSPI1A_SS1_B__SDMA_DEBUG_PC_3 0x019C 0x04E4 0x0000 0x9 0x0
+#define MX6SX_PAD_QSPI1B_DATA0__QSPI1_B_DATA_0 0x01A0 0x04E8 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1B_DATA0__UART3_CTS_B 0x01A0 0x04E8 0x0000 0x1 0x0
+#define MX6SX_PAD_QSPI1B_DATA0__ECSPI3_MOSI 0x01A0 0x04E8 0x0738 0x2 0x1
+#define MX6SX_PAD_QSPI1B_DATA0__ESAI_RX_FS 0x01A0 0x04E8 0x0778 0x3 0x2
+#define MX6SX_PAD_QSPI1B_DATA0__CSI1_DATA_22 0x01A0 0x04E8 0x06F4 0x4 0x1
+#define MX6SX_PAD_QSPI1B_DATA0__GPIO4_IO_24 0x01A0 0x04E8 0x0000 0x5 0x0
+#define MX6SX_PAD_QSPI1B_DATA0__WEIM_DATA_14 0x01A0 0x04E8 0x0000 0x6 0x0
+#define MX6SX_PAD_QSPI1B_DATA0__SIM_M_HADDR_9 0x01A0 0x04E8 0x0000 0x7 0x0
+#define MX6SX_PAD_QSPI1B_DATA1__QSPI1_B_DATA_1 0x01A4 0x04EC 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1B_DATA1__UART3_RTS_B 0x01A4 0x04EC 0x083C 0x1 0x5
+#define MX6SX_PAD_QSPI1B_DATA1__ECSPI3_MISO 0x01A4 0x04EC 0x0734 0x2 0x1
+#define MX6SX_PAD_QSPI1B_DATA1__ESAI_RX_CLK 0x01A4 0x04EC 0x0788 0x3 0x2
+#define MX6SX_PAD_QSPI1B_DATA1__CSI1_DATA_21 0x01A4 0x04EC 0x06F0 0x4 0x1
+#define MX6SX_PAD_QSPI1B_DATA1__GPIO4_IO_25 0x01A4 0x04EC 0x0000 0x5 0x0
+#define MX6SX_PAD_QSPI1B_DATA1__WEIM_DATA_13 0x01A4 0x04EC 0x0000 0x6 0x0
+#define MX6SX_PAD_QSPI1B_DATA1__SIM_M_HADDR_8 0x01A4 0x04EC 0x0000 0x7 0x0
+#define MX6SX_PAD_QSPI1B_DATA2__QSPI1_B_DATA_2 0x01A8 0x04F0 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1B_DATA2__I2C2_SDA 0x01A8 0x04F0 0x07B4 0x1 0x2
+#define MX6SX_PAD_QSPI1B_DATA2__ECSPI5_RDY 0x01A8 0x04F0 0x0000 0x2 0x0
+#define MX6SX_PAD_QSPI1B_DATA2__ESAI_TX5_RX0 0x01A8 0x04F0 0x07A4 0x3 0x2
+#define MX6SX_PAD_QSPI1B_DATA2__CSI1_DATA_20 0x01A8 0x04F0 0x06EC 0x4 0x1
+#define MX6SX_PAD_QSPI1B_DATA2__GPIO4_IO_26 0x01A8 0x04F0 0x0000 0x5 0x0
+#define MX6SX_PAD_QSPI1B_DATA2__WEIM_DATA_12 0x01A8 0x04F0 0x0000 0x6 0x0
+#define MX6SX_PAD_QSPI1B_DATA2__SIM_M_HADDR_5 0x01A8 0x04F0 0x0000 0x7 0x0
+#define MX6SX_PAD_QSPI1B_DATA3__QSPI1_B_DATA_3 0x01AC 0x04F4 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1B_DATA3__I2C2_SCL 0x01AC 0x04F4 0x07B0 0x1 0x2
+#define MX6SX_PAD_QSPI1B_DATA3__ECSPI5_SS3 0x01AC 0x04F4 0x0000 0x2 0x0
+#define MX6SX_PAD_QSPI1B_DATA3__ESAI_TX_FS 0x01AC 0x04F4 0x077C 0x3 0x2
+#define MX6SX_PAD_QSPI1B_DATA3__CSI1_DATA_19 0x01AC 0x04F4 0x06E8 0x4 0x1
+#define MX6SX_PAD_QSPI1B_DATA3__GPIO4_IO_27 0x01AC 0x04F4 0x0000 0x5 0x0
+#define MX6SX_PAD_QSPI1B_DATA3__WEIM_DATA_11 0x01AC 0x04F4 0x0000 0x6 0x0
+#define MX6SX_PAD_QSPI1B_DATA3__SIM_M_HADDR_2 0x01AC 0x04F4 0x0000 0x7 0x0
+#define MX6SX_PAD_QSPI1B_DQS__QSPI1_B_DQS 0x01B0 0x04F8 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1B_DQS__CAN1_TX 0x01B0 0x04F8 0x0000 0x1 0x0
+#define MX6SX_PAD_QSPI1B_DQS__CANFD_TX1 0x01B0 0x04F8 0x0000 0x2 0x0
+#define MX6SX_PAD_QSPI1B_DQS__ECSPI5_SS0 0x01B0 0x04F8 0x075C 0x3 0x1
+#define MX6SX_PAD_QSPI1B_DQS__CSI1_DATA_23 0x01B0 0x04F8 0x06F8 0x4 0x1
+#define MX6SX_PAD_QSPI1B_DQS__GPIO4_IO_28 0x01B0 0x04F8 0x0000 0x5 0x0
+#define MX6SX_PAD_QSPI1B_DQS__WEIM_DATA_15 0x01B0 0x04F8 0x0000 0x6 0x0
+#define MX6SX_PAD_QSPI1B_DQS__SIM_M_HADDR_15 0x01B0 0x04F8 0x0000 0x7 0x0
+#define MX6SX_PAD_QSPI1B_SCLK__QSPI1_B_SCLK 0x01B4 0x04FC 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1B_SCLK__UART3_RX 0x01B4 0x04FC 0x0840 0x1 0x4
+#define MX6SX_PAD_QSPI1B_SCLK__UART3_TX 0x01B4 0x04FC 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1B_SCLK__ECSPI3_SCLK 0x01B4 0x04FC 0x0730 0x2 0x1
+#define MX6SX_PAD_QSPI1B_SCLK__ESAI_RX_HF_CLK 0x01B4 0x04FC 0x0780 0x3 0x2
+#define MX6SX_PAD_QSPI1B_SCLK__CSI1_DATA_16 0x01B4 0x04FC 0x06DC 0x4 0x1
+#define MX6SX_PAD_QSPI1B_SCLK__GPIO4_IO_29 0x01B4 0x04FC 0x0000 0x5 0x0
+#define MX6SX_PAD_QSPI1B_SCLK__WEIM_DATA_8 0x01B4 0x04FC 0x0000 0x6 0x0
+#define MX6SX_PAD_QSPI1B_SCLK__SIM_M_HADDR_11 0x01B4 0x04FC 0x0000 0x7 0x0
+#define MX6SX_PAD_QSPI1B_SS0_B__QSPI1_B_SS0_B 0x01B8 0x0500 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1B_SS0_B__UART3_RX 0x01B8 0x0500 0x0840 0x1 0x5
+#define MX6SX_PAD_QSPI1B_SS0_B__UART3_TX 0x01B8 0x0500 0x0000 0x1 0x0
+#define MX6SX_PAD_QSPI1B_SS0_B__ECSPI3_SS0 0x01B8 0x0500 0x073C 0x2 0x1
+#define MX6SX_PAD_QSPI1B_SS0_B__ESAI_TX_HF_CLK 0x01B8 0x0500 0x0784 0x3 0x3
+#define MX6SX_PAD_QSPI1B_SS0_B__CSI1_DATA_17 0x01B8 0x0500 0x06E0 0x4 0x1
+#define MX6SX_PAD_QSPI1B_SS0_B__GPIO4_IO_30 0x01B8 0x0500 0x0000 0x5 0x0
+#define MX6SX_PAD_QSPI1B_SS0_B__WEIM_DATA_9 0x01B8 0x0500 0x0000 0x6 0x0
+#define MX6SX_PAD_QSPI1B_SS0_B__SIM_M_HADDR_10 0x01B8 0x0500 0x0000 0x7 0x0
+#define MX6SX_PAD_QSPI1B_SS1_B__QSPI1_B_SS1_B 0x01BC 0x0504 0x0000 0x0 0x0
+#define MX6SX_PAD_QSPI1B_SS1_B__CAN2_RX 0x01BC 0x0504 0x0690 0x1 0x2
+#define MX6SX_PAD_QSPI1B_SS1_B__CANFD_RX2 0x01BC 0x0504 0x0698 0x2 0x2
+#define MX6SX_PAD_QSPI1B_SS1_B__ECSPI5_SCLK 0x01BC 0x0504 0x0750 0x3 0x1
+#define MX6SX_PAD_QSPI1B_SS1_B__CSI1_DATA_18 0x01BC 0x0504 0x06E4 0x4 0x1
+#define MX6SX_PAD_QSPI1B_SS1_B__GPIO4_IO_31 0x01BC 0x0504 0x0000 0x5 0x0
+#define MX6SX_PAD_QSPI1B_SS1_B__WEIM_DATA_10 0x01BC 0x0504 0x0000 0x6 0x0
+#define MX6SX_PAD_QSPI1B_SS1_B__SIM_M_HADDR_14 0x01BC 0x0504 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII1_RD0__ENET1_RX_DATA_0 0x01C0 0x0508 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII1_RD0__GPIO5_IO_0 0x01C0 0x0508 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII1_RD0__CSI2_DATA_10 0x01C0 0x0508 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII1_RD0__ANATOP_TESTI_0 0x01C0 0x0508 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII1_RD0__RAWNAND_TESTER_TRIGGER 0x01C0 0x0508 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII1_RD0__PCIE_CTRL_DEBUG_0 0x01C0 0x0508 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII1_RD1__ENET1_RX_DATA_1 0x01C4 0x050C 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII1_RD1__GPIO5_IO_1 0x01C4 0x050C 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII1_RD1__CSI2_DATA_11 0x01C4 0x050C 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII1_RD1__ANATOP_TESTI_1 0x01C4 0x050C 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII1_RD1__USDHC1_TESTER_TRIGGER 0x01C4 0x050C 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII1_RD1__PCIE_CTRL_DEBUG_1 0x01C4 0x050C 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII1_RD2__ENET1_RX_DATA_2 0x01C8 0x0510 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII1_RD2__GPIO5_IO_2 0x01C8 0x0510 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII1_RD2__CSI2_DATA_12 0x01C8 0x0510 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII1_RD2__ANATOP_TESTI_2 0x01C8 0x0510 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII1_RD2__USDHC2_TESTER_TRIGGER 0x01C8 0x0510 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII1_RD2__PCIE_CTRL_DEBUG_2 0x01C8 0x0510 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII1_RD3__ENET1_RX_DATA_3 0x01CC 0x0514 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII1_RD3__GPIO5_IO_3 0x01CC 0x0514 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII1_RD3__CSI2_DATA_13 0x01CC 0x0514 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII1_RD3__ANATOP_TESTI_3 0x01CC 0x0514 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII1_RD3__USDHC3_TESTER_TRIGGER 0x01CC 0x0514 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII1_RD3__PCIE_CTRL_DEBUG_3 0x01CC 0x0514 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII1_RX_CTL__ENET1_RX_EN 0x01D0 0x0518 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII1_RX_CTL__GPIO5_IO_4 0x01D0 0x0518 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII1_RX_CTL__CSI2_DATA_14 0x01D0 0x0518 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII1_RX_CTL__ANATOP_TESTO_0 0x01D0 0x0518 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII1_RX_CTL__USDHC4_TESTER_TRIGGER 0x01D0 0x0518 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII1_RX_CTL__PCIE_CTRL_DEBUG_4 0x01D0 0x0518 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII1_RXC__ENET1_RX_CLK 0x01D4 0x051C 0x0768 0x0 0x1
+#define MX6SX_PAD_RGMII1_RXC__ENET1_RX_ER 0x01D4 0x051C 0x0000 0x1 0x0
+#define MX6SX_PAD_RGMII1_RXC__GPIO5_IO_5 0x01D4 0x051C 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII1_RXC__CSI2_DATA_15 0x01D4 0x051C 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII1_RXC__ANATOP_TESTO_1 0x01D4 0x051C 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII1_RXC__ECSPI1_TESTER_TRIGGER 0x01D4 0x051C 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII1_RXC__PCIE_CTRL_DEBUG_5 0x01D4 0x051C 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII1_TD0__ENET1_TX_DATA_0 0x01D8 0x0520 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII1_TD0__SAI2_RX_SYNC 0x01D8 0x0520 0x0810 0x2 0x1
+#define MX6SX_PAD_RGMII1_TD0__GPIO5_IO_6 0x01D8 0x0520 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII1_TD0__CSI2_DATA_16 0x01D8 0x0520 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII1_TD0__ANATOP_TESTO_2 0x01D8 0x0520 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII1_TD0__ECSPI2_TESTER_TRIGGER 0x01D8 0x0520 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII1_TD0__PCIE_CTRL_DEBUG_6 0x01D8 0x0520 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII1_TD1__ENET1_TX_DATA_1 0x01DC 0x0524 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII1_TD1__SAI2_RX_BCLK 0x01DC 0x0524 0x0808 0x2 0x1
+#define MX6SX_PAD_RGMII1_TD1__GPIO5_IO_7 0x01DC 0x0524 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII1_TD1__CSI2_DATA_17 0x01DC 0x0524 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII1_TD1__ANATOP_TESTO_3 0x01DC 0x0524 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII1_TD1__ECSPI3_TESTER_TRIGGER 0x01DC 0x0524 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII1_TD1__PCIE_CTRL_DEBUG_7 0x01DC 0x0524 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII1_TD2__ENET1_TX_DATA_2 0x01E0 0x0528 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII1_TD2__SAI2_TX_SYNC 0x01E0 0x0528 0x0818 0x2 0x1
+#define MX6SX_PAD_RGMII1_TD2__GPIO5_IO_8 0x01E0 0x0528 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII1_TD2__CSI2_DATA_18 0x01E0 0x0528 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII1_TD2__ANATOP_TESTO_4 0x01E0 0x0528 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII1_TD2__ECSPI4_TESTER_TRIGGER 0x01E0 0x0528 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII1_TD2__PCIE_CTRL_DEBUG_8 0x01E0 0x0528 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII1_TD3__ENET1_TX_DATA_3 0x01E4 0x052C 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII1_TD3__SAI2_TX_BCLK 0x01E4 0x052C 0x0814 0x2 0x1
+#define MX6SX_PAD_RGMII1_TD3__GPIO5_IO_9 0x01E4 0x052C 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII1_TD3__CSI2_DATA_19 0x01E4 0x052C 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII1_TD3__ANATOP_TESTO_5 0x01E4 0x052C 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII1_TD3__ECSPI5_TESTER_TRIGGER 0x01E4 0x052C 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII1_TD3__PCIE_CTRL_DEBUG_9 0x01E4 0x052C 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII1_TX_CTL__ENET1_TX_EN 0x01E8 0x0530 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII1_TX_CTL__SAI2_RX_DATA_0 0x01E8 0x0530 0x080C 0x2 0x1
+#define MX6SX_PAD_RGMII1_TX_CTL__GPIO5_IO_10 0x01E8 0x0530 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII1_TX_CTL__CSI2_DATA_0 0x01E8 0x0530 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII1_TX_CTL__ANATOP_TESTO_6 0x01E8 0x0530 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII1_TX_CTL__QSPI1_TESTER_TRIGGER 0x01E8 0x0530 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII1_TX_CTL__PCIE_CTRL_DEBUG_10 0x01E8 0x0530 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII1_TXC__ENET1_RGMII_TXC 0x01EC 0x0534 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII1_TXC__ENET1_TX_ER 0x01EC 0x0534 0x0000 0x1 0x0
+#define MX6SX_PAD_RGMII1_TXC__SAI2_TX_DATA_0 0x01EC 0x0534 0x0000 0x2 0x0
+#define MX6SX_PAD_RGMII1_TXC__GPIO5_IO_11 0x01EC 0x0534 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII1_TXC__CSI2_DATA_1 0x01EC 0x0534 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII1_TXC__ANATOP_TESTO_7 0x01EC 0x0534 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII1_TXC__QSPI2_TESTER_TRIGGER 0x01EC 0x0534 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII1_TXC__PCIE_CTRL_DEBUG_11 0x01EC 0x0534 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII2_RD0__ENET2_RX_DATA_0 0x01F0 0x0538 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII2_RD0__PWM4_OUT 0x01F0 0x0538 0x0000 0x2 0x0
+#define MX6SX_PAD_RGMII2_RD0__GPIO5_IO_12 0x01F0 0x0538 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII2_RD0__CSI2_DATA_2 0x01F0 0x0538 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII2_RD0__ANATOP_TESTO_8 0x01F0 0x0538 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII2_RD0__VDEC_DEBUG_18 0x01F0 0x0538 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII2_RD0__PCIE_CTRL_DEBUG_12 0x01F0 0x0538 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII2_RD1__ENET2_RX_DATA_1 0x01F4 0x053C 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII2_RD1__PWM3_OUT 0x01F4 0x053C 0x0000 0x2 0x0
+#define MX6SX_PAD_RGMII2_RD1__GPIO5_IO_13 0x01F4 0x053C 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII2_RD1__CSI2_DATA_3 0x01F4 0x053C 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII2_RD1__ANATOP_TESTO_9 0x01F4 0x053C 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII2_RD1__VDEC_DEBUG_19 0x01F4 0x053C 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII2_RD1__PCIE_CTRL_DEBUG_13 0x01F4 0x053C 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII2_RD2__ENET2_RX_DATA_2 0x01F8 0x0540 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII2_RD2__PWM2_OUT 0x01F8 0x0540 0x0000 0x2 0x0
+#define MX6SX_PAD_RGMII2_RD2__GPIO5_IO_14 0x01F8 0x0540 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII2_RD2__CSI2_DATA_4 0x01F8 0x0540 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII2_RD2__ANATOP_TESTO_10 0x01F8 0x0540 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII2_RD2__VDEC_DEBUG_20 0x01F8 0x0540 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII2_RD2__PCIE_CTRL_DEBUG_14 0x01F8 0x0540 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII2_RD3__ENET2_RX_DATA_3 0x01FC 0x0544 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII2_RD3__PWM1_OUT 0x01FC 0x0544 0x0000 0x2 0x0
+#define MX6SX_PAD_RGMII2_RD3__GPIO5_IO_15 0x01FC 0x0544 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII2_RD3__CSI2_DATA_5 0x01FC 0x0544 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII2_RD3__ANATOP_TESTO_11 0x01FC 0x0544 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII2_RD3__VDEC_DEBUG_21 0x01FC 0x0544 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII2_RD3__PCIE_CTRL_DEBUG_15 0x01FC 0x0544 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII2_RX_CTL__ENET2_RX_EN 0x0200 0x0548 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII2_RX_CTL__GPIO5_IO_16 0x0200 0x0548 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII2_RX_CTL__CSI2_DATA_6 0x0200 0x0548 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII2_RX_CTL__ANATOP_TESTO_12 0x0200 0x0548 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII2_RX_CTL__VDEC_DEBUG_22 0x0200 0x0548 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII2_RX_CTL__PCIE_CTRL_DEBUG_16 0x0200 0x0548 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII2_RXC__ENET2_RX_CLK 0x0204 0x054C 0x0774 0x0 0x1
+#define MX6SX_PAD_RGMII2_RXC__ENET2_RX_ER 0x0204 0x054C 0x0000 0x1 0x0
+#define MX6SX_PAD_RGMII2_RXC__GPIO5_IO_17 0x0204 0x054C 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII2_RXC__CSI2_DATA_7 0x0204 0x054C 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII2_RXC__ANATOP_TESTO_13 0x0204 0x054C 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII2_RXC__VDEC_DEBUG_23 0x0204 0x054C 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII2_RXC__PCIE_CTRL_DEBUG_17 0x0204 0x054C 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII2_TD0__ENET2_TX_DATA_0 0x0208 0x0550 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII2_TD0__SAI1_RX_SYNC 0x0208 0x0550 0x07FC 0x2 0x1
+#define MX6SX_PAD_RGMII2_TD0__PWM8_OUT 0x0208 0x0550 0x0000 0x3 0x0
+#define MX6SX_PAD_RGMII2_TD0__GPIO5_IO_18 0x0208 0x0550 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII2_TD0__CSI2_DATA_8 0x0208 0x0550 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII2_TD0__ANATOP_TESTO_14 0x0208 0x0550 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII2_TD0__VDEC_DEBUG_24 0x0208 0x0550 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII2_TD0__PCIE_CTRL_DEBUG_18 0x0208 0x0550 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII2_TD1__ENET2_TX_DATA_1 0x020C 0x0554 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII2_TD1__SAI1_RX_BCLK 0x020C 0x0554 0x07F4 0x2 0x1
+#define MX6SX_PAD_RGMII2_TD1__PWM7_OUT 0x020C 0x0554 0x0000 0x3 0x0
+#define MX6SX_PAD_RGMII2_TD1__GPIO5_IO_19 0x020C 0x0554 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII2_TD1__CSI2_DATA_9 0x020C 0x0554 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII2_TD1__ANATOP_TESTO_15 0x020C 0x0554 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII2_TD1__VDEC_DEBUG_25 0x020C 0x0554 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII2_TD1__PCIE_CTRL_DEBUG_19 0x020C 0x0554 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII2_TD2__ENET2_TX_DATA_2 0x0210 0x0558 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII2_TD2__SAI1_TX_SYNC 0x0210 0x0558 0x0804 0x2 0x1
+#define MX6SX_PAD_RGMII2_TD2__PWM6_OUT 0x0210 0x0558 0x0000 0x3 0x0
+#define MX6SX_PAD_RGMII2_TD2__GPIO5_IO_20 0x0210 0x0558 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII2_TD2__CSI2_VSYNC 0x0210 0x0558 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII2_TD2__SJC_FAIL 0x0210 0x0558 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII2_TD2__VDEC_DEBUG_26 0x0210 0x0558 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII2_TD2__PCIE_CTRL_DEBUG_20 0x0210 0x0558 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII2_TD3__ENET2_TX_DATA_3 0x0214 0x055C 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII2_TD3__SAI1_TX_BCLK 0x0214 0x055C 0x0800 0x2 0x1
+#define MX6SX_PAD_RGMII2_TD3__PWM5_OUT 0x0214 0x055C 0x0000 0x3 0x0
+#define MX6SX_PAD_RGMII2_TD3__GPIO5_IO_21 0x0214 0x055C 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII2_TD3__CSI2_HSYNC 0x0214 0x055C 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII2_TD3__SJC_JTAG_ACT 0x0214 0x055C 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII2_TD3__VDEC_DEBUG_27 0x0214 0x055C 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII2_TD3__PCIE_CTRL_DEBUG_21 0x0214 0x055C 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII2_TX_CTL__ENET2_TX_EN 0x0218 0x0560 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII2_TX_CTL__SAI1_RX_DATA_0 0x0218 0x0560 0x07F8 0x2 0x1
+#define MX6SX_PAD_RGMII2_TX_CTL__GPIO5_IO_22 0x0218 0x0560 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII2_TX_CTL__CSI2_FIELD 0x0218 0x0560 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII2_TX_CTL__SJC_DE_B 0x0218 0x0560 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII2_TX_CTL__VDEC_DEBUG_28 0x0218 0x0560 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII2_TX_CTL__PCIE_CTRL_DEBUG_22 0x0218 0x0560 0x0000 0x9 0x0
+#define MX6SX_PAD_RGMII2_TXC__ENET2_RGMII_TXC 0x021C 0x0564 0x0000 0x0 0x0
+#define MX6SX_PAD_RGMII2_TXC__ENET2_TX_ER 0x021C 0x0564 0x0000 0x1 0x0
+#define MX6SX_PAD_RGMII2_TXC__SAI1_TX_DATA_0 0x021C 0x0564 0x0000 0x2 0x0
+#define MX6SX_PAD_RGMII2_TXC__GPIO5_IO_23 0x021C 0x0564 0x0000 0x5 0x0
+#define MX6SX_PAD_RGMII2_TXC__CSI2_PIXCLK 0x021C 0x0564 0x0000 0x6 0x0
+#define MX6SX_PAD_RGMII2_TXC__SJC_DONE 0x021C 0x0564 0x0000 0x7 0x0
+#define MX6SX_PAD_RGMII2_TXC__VDEC_DEBUG_29 0x021C 0x0564 0x0000 0x8 0x0
+#define MX6SX_PAD_RGMII2_TXC__PCIE_CTRL_DEBUG_23 0x021C 0x0564 0x0000 0x9 0x0
+#define MX6SX_PAD_SD1_CLK__USDHC1_CLK 0x0220 0x0568 0x0000 0x0 0x0
+#define MX6SX_PAD_SD1_CLK__AUDMUX_AUD5_RXFS 0x0220 0x0568 0x0668 0x1 0x1
+#define MX6SX_PAD_SD1_CLK__WDOG2_WDOG_B 0x0220 0x0568 0x0000 0x2 0x0
+#define MX6SX_PAD_SD1_CLK__GPT_CLK 0x0220 0x0568 0x0000 0x3 0x0
+#define MX6SX_PAD_SD1_CLK__WDOG2_WDOG_RST_B_DEB 0x0220 0x0568 0x0000 0x4 0x0
+#define MX6SX_PAD_SD1_CLK__GPIO6_IO_0 0x0220 0x0568 0x0000 0x5 0x0
+#define MX6SX_PAD_SD1_CLK__ENET2_1588_EVENT1_OUT 0x0220 0x0568 0x0000 0x6 0x0
+#define MX6SX_PAD_SD1_CLK__CCM_OUT1 0x0220 0x0568 0x0000 0x7 0x0
+#define MX6SX_PAD_SD1_CLK__VADC_ADC_PROC_CLK 0x0220 0x0568 0x0000 0x8 0x0
+#define MX6SX_PAD_SD1_CLK__MMDC_DEBUG_45 0x0220 0x0568 0x0000 0x9 0x0
+#define MX6SX_PAD_SD1_CMD__USDHC1_CMD 0x0224 0x056C 0x0000 0x0 0x0
+#define MX6SX_PAD_SD1_CMD__AUDMUX_AUD5_RXC 0x0224 0x056C 0x0664 0x1 0x1
+#define MX6SX_PAD_SD1_CMD__WDOG1_WDOG_B 0x0224 0x056C 0x0000 0x2 0x0
+#define MX6SX_PAD_SD1_CMD__GPT_COMPARE1 0x0224 0x056C 0x0000 0x3 0x0
+#define MX6SX_PAD_SD1_CMD__WDOG1_WDOG_RST_B_DEB 0x0224 0x056C 0x0000 0x4 0x0
+#define MX6SX_PAD_SD1_CMD__GPIO6_IO_1 0x0224 0x056C 0x0000 0x5 0x0
+#define MX6SX_PAD_SD1_CMD__ENET2_1588_EVENT1_IN 0x0224 0x056C 0x0000 0x6 0x0
+#define MX6SX_PAD_SD1_CMD__CCM_CLKO1 0x0224 0x056C 0x0000 0x7 0x0
+#define MX6SX_PAD_SD1_CMD__VADC_EXT_SYSCLK 0x0224 0x056C 0x0000 0x8 0x0
+#define MX6SX_PAD_SD1_CMD__MMDC_DEBUG_46 0x0224 0x056C 0x0000 0x9 0x0
+#define MX6SX_PAD_SD1_DATA0__USDHC1_DATA0 0x0228 0x0570 0x0000 0x0 0x0
+#define MX6SX_PAD_SD1_DATA0__AUDMUX_AUD5_RXD 0x0228 0x0570 0x065C 0x1 0x1
+#define MX6SX_PAD_SD1_DATA0__CAAM_WRAPPER_RNG_OSC_OBS 0x0228 0x0570 0x0000 0x2 0x0
+#define MX6SX_PAD_SD1_DATA0__GPT_CAPTURE1 0x0228 0x0570 0x0000 0x3 0x0
+#define MX6SX_PAD_SD1_DATA0__UART2_RX 0x0228 0x0570 0x0838 0x4 0x2
+#define MX6SX_PAD_SD1_DATA0__UART2_TX 0x0228 0x0570 0x0000 0x4 0x0
+#define MX6SX_PAD_SD1_DATA0__GPIO6_IO_2 0x0228 0x0570 0x0000 0x5 0x0
+#define MX6SX_PAD_SD1_DATA0__ENET1_1588_EVENT1_IN 0x0228 0x0570 0x0000 0x6 0x0
+#define MX6SX_PAD_SD1_DATA0__CCM_OUT2 0x0228 0x0570 0x0000 0x7 0x0
+#define MX6SX_PAD_SD1_DATA0__VADC_CLAMP_UP 0x0228 0x0570 0x0000 0x8 0x0
+#define MX6SX_PAD_SD1_DATA0__MMDC_DEBUG_48 0x0228 0x0570 0x0000 0x9 0x0
+#define MX6SX_PAD_SD1_DATA1__USDHC1_DATA1 0x022C 0x0574 0x0000 0x0 0x0
+#define MX6SX_PAD_SD1_DATA1__AUDMUX_AUD5_TXC 0x022C 0x0574 0x066C 0x1 0x1
+#define MX6SX_PAD_SD1_DATA1__PWM4_OUT 0x022C 0x0574 0x0000 0x2 0x0
+#define MX6SX_PAD_SD1_DATA1__GPT_CAPTURE2 0x022C 0x0574 0x0000 0x3 0x0
+#define MX6SX_PAD_SD1_DATA1__UART2_RX 0x022C 0x0574 0x0838 0x4 0x3
+#define MX6SX_PAD_SD1_DATA1__UART2_TX 0x022C 0x0574 0x0000 0x4 0x0
+#define MX6SX_PAD_SD1_DATA1__GPIO6_IO_3 0x022C 0x0574 0x0000 0x5 0x0
+#define MX6SX_PAD_SD1_DATA1__ENET1_1588_EVENT1_OUT 0x022C 0x0574 0x0000 0x6 0x0
+#define MX6SX_PAD_SD1_DATA1__CCM_CLKO2 0x022C 0x0574 0x0000 0x7 0x0
+#define MX6SX_PAD_SD1_DATA1__VADC_CLAMP_DOWN 0x022C 0x0574 0x0000 0x8 0x0
+#define MX6SX_PAD_SD1_DATA1__MMDC_DEBUG_47 0x022C 0x0574 0x0000 0x9 0x0
+#define MX6SX_PAD_SD1_DATA2__USDHC1_DATA2 0x0230 0x0578 0x0000 0x0 0x0
+#define MX6SX_PAD_SD1_DATA2__AUDMUX_AUD5_TXFS 0x0230 0x0578 0x0670 0x1 0x1
+#define MX6SX_PAD_SD1_DATA2__PWM3_OUT 0x0230 0x0578 0x0000 0x2 0x0
+#define MX6SX_PAD_SD1_DATA2__GPT_COMPARE2 0x0230 0x0578 0x0000 0x3 0x0
+#define MX6SX_PAD_SD1_DATA2__UART2_CTS_B 0x0230 0x0578 0x0000 0x4 0x0
+#define MX6SX_PAD_SD1_DATA2__GPIO6_IO_4 0x0230 0x0578 0x0000 0x5 0x0
+#define MX6SX_PAD_SD1_DATA2__ECSPI4_RDY 0x0230 0x0578 0x0000 0x6 0x0
+#define MX6SX_PAD_SD1_DATA2__CCM_OUT0 0x0230 0x0578 0x0000 0x7 0x0
+#define MX6SX_PAD_SD1_DATA2__VADC_EXT_PD_N 0x0230 0x0578 0x0000 0x8 0x0
+#define MX6SX_PAD_SD1_DATA3__USDHC1_DATA3 0x0234 0x057C 0x0000 0x0 0x0
+#define MX6SX_PAD_SD1_DATA3__AUDMUX_AUD5_TXD 0x0234 0x057C 0x0660 0x1 0x1
+#define MX6SX_PAD_SD1_DATA3__AUDMUX_AUD5_RXD 0x0234 0x057C 0x065C 0x2 0x2
+#define MX6SX_PAD_SD1_DATA3__GPT_COMPARE3 0x0234 0x057C 0x0000 0x3 0x0
+#define MX6SX_PAD_SD1_DATA3__UART2_RTS_B 0x0234 0x057C 0x0834 0x4 0x3
+#define MX6SX_PAD_SD1_DATA3__GPIO6_IO_5 0x0234 0x057C 0x0000 0x5 0x0
+#define MX6SX_PAD_SD1_DATA3__ECSPI4_SS1 0x0234 0x057C 0x0000 0x6 0x0
+#define MX6SX_PAD_SD1_DATA3__CCM_PMIC_RDY 0x0234 0x057C 0x069C 0x7 0x2
+#define MX6SX_PAD_SD1_DATA3__VADC_RST_N 0x0234 0x057C 0x0000 0x8 0x0
+#define MX6SX_PAD_SD2_CLK__USDHC2_CLK 0x0238 0x0580 0x0000 0x0 0x0
+#define MX6SX_PAD_SD2_CLK__AUDMUX_AUD6_RXFS 0x0238 0x0580 0x0680 0x1 0x2
+#define MX6SX_PAD_SD2_CLK__KPP_COL_5 0x0238 0x0580 0x07C8 0x2 0x1
+#define MX6SX_PAD_SD2_CLK__ECSPI4_SCLK 0x0238 0x0580 0x0740 0x3 0x1
+#define MX6SX_PAD_SD2_CLK__MLB_SIG 0x0238 0x0580 0x07F0 0x4 0x2
+#define MX6SX_PAD_SD2_CLK__GPIO6_IO_6 0x0238 0x0580 0x0000 0x5 0x0
+#define MX6SX_PAD_SD2_CLK__MQS_RIGHT 0x0238 0x0580 0x0000 0x6 0x0
+#define MX6SX_PAD_SD2_CLK__WDOG1_WDOG_ANY 0x0238 0x0580 0x0000 0x7 0x0
+#define MX6SX_PAD_SD2_CLK__VADC_CLAMP_CURRENT_5 0x0238 0x0580 0x0000 0x8 0x0
+#define MX6SX_PAD_SD2_CLK__MMDC_DEBUG_29 0x0238 0x0580 0x0000 0x9 0x0
+#define MX6SX_PAD_SD2_CMD__USDHC2_CMD 0x023C 0x0584 0x0000 0x0 0x0
+#define MX6SX_PAD_SD2_CMD__AUDMUX_AUD6_RXC 0x023C 0x0584 0x067C 0x1 0x2
+#define MX6SX_PAD_SD2_CMD__KPP_ROW_5 0x023C 0x0584 0x07D4 0x2 0x1
+#define MX6SX_PAD_SD2_CMD__ECSPI4_MOSI 0x023C 0x0584 0x0748 0x3 0x1
+#define MX6SX_PAD_SD2_CMD__MLB_CLK 0x023C 0x0584 0x07E8 0x4 0x2
+#define MX6SX_PAD_SD2_CMD__GPIO6_IO_7 0x023C 0x0584 0x0000 0x5 0x0
+#define MX6SX_PAD_SD2_CMD__MQS_LEFT 0x023C 0x0584 0x0000 0x6 0x0
+#define MX6SX_PAD_SD2_CMD__WDOG3_WDOG_B 0x023C 0x0584 0x0000 0x7 0x0
+#define MX6SX_PAD_SD2_CMD__VADC_CLAMP_CURRENT_4 0x023C 0x0584 0x0000 0x8 0x0
+#define MX6SX_PAD_SD2_CMD__MMDC_DEBUG_30 0x023C 0x0584 0x0000 0x9 0x0
+#define MX6SX_PAD_SD2_DATA0__USDHC2_DATA0 0x0240 0x0588 0x0000 0x0 0x0
+#define MX6SX_PAD_SD2_DATA0__AUDMUX_AUD6_RXD 0x0240 0x0588 0x0674 0x1 0x2
+#define MX6SX_PAD_SD2_DATA0__KPP_ROW_7 0x0240 0x0588 0x07DC 0x2 0x1
+#define MX6SX_PAD_SD2_DATA0__PWM1_OUT 0x0240 0x0588 0x0000 0x3 0x0
+#define MX6SX_PAD_SD2_DATA0__I2C4_SDA 0x0240 0x0588 0x07C4 0x4 0x3
+#define MX6SX_PAD_SD2_DATA0__GPIO6_IO_8 0x0240 0x0588 0x0000 0x5 0x0
+#define MX6SX_PAD_SD2_DATA0__ECSPI4_SS3 0x0240 0x0588 0x0000 0x6 0x0
+#define MX6SX_PAD_SD2_DATA0__UART4_RX 0x0240 0x0588 0x0848 0x7 0x4
+#define MX6SX_PAD_SD2_DATA0__UART4_TX 0x0240 0x0588 0x0000 0x7 0x0
+#define MX6SX_PAD_SD2_DATA0__VADC_CLAMP_CURRENT_0 0x0240 0x0588 0x0000 0x8 0x0
+#define MX6SX_PAD_SD2_DATA0__MMDC_DEBUG_50 0x0240 0x0588 0x0000 0x9 0x0
+#define MX6SX_PAD_SD2_DATA1__USDHC2_DATA1 0x0244 0x058C 0x0000 0x0 0x0
+#define MX6SX_PAD_SD2_DATA1__AUDMUX_AUD6_TXC 0x0244 0x058C 0x0684 0x1 0x2
+#define MX6SX_PAD_SD2_DATA1__KPP_COL_7 0x0244 0x058C 0x07D0 0x2 0x1
+#define MX6SX_PAD_SD2_DATA1__PWM2_OUT 0x0244 0x058C 0x0000 0x3 0x0
+#define MX6SX_PAD_SD2_DATA1__I2C4_SCL 0x0244 0x058C 0x07C0 0x4 0x3
+#define MX6SX_PAD_SD2_DATA1__GPIO6_IO_9 0x0244 0x058C 0x0000 0x5 0x0
+#define MX6SX_PAD_SD2_DATA1__ECSPI4_SS2 0x0244 0x058C 0x0000 0x6 0x0
+#define MX6SX_PAD_SD2_DATA1__UART4_RX 0x0244 0x058C 0x0848 0x7 0x5
+#define MX6SX_PAD_SD2_DATA1__UART4_TX 0x0244 0x058C 0x0000 0x7 0x0
+#define MX6SX_PAD_SD2_DATA1__VADC_CLAMP_CURRENT_1 0x0244 0x058C 0x0000 0x8 0x0
+#define MX6SX_PAD_SD2_DATA1__MMDC_DEBUG_49 0x0244 0x058C 0x0000 0x9 0x0
+#define MX6SX_PAD_SD2_DATA2__USDHC2_DATA2 0x0248 0x0590 0x0000 0x0 0x0
+#define MX6SX_PAD_SD2_DATA2__AUDMUX_AUD6_TXFS 0x0248 0x0590 0x0688 0x1 0x2
+#define MX6SX_PAD_SD2_DATA2__KPP_ROW_6 0x0248 0x0590 0x07D8 0x2 0x1
+#define MX6SX_PAD_SD2_DATA2__ECSPI4_SS0 0x0248 0x0590 0x074C 0x3 0x1
+#define MX6SX_PAD_SD2_DATA2__SDMA_EXT_EVENT_0 0x0248 0x0590 0x081C 0x4 0x2
+#define MX6SX_PAD_SD2_DATA2__GPIO6_IO_10 0x0248 0x0590 0x0000 0x5 0x0
+#define MX6SX_PAD_SD2_DATA2__SPDIF_OUT 0x0248 0x0590 0x0000 0x6 0x0
+#define MX6SX_PAD_SD2_DATA2__UART6_RX 0x0248 0x0590 0x0858 0x7 0x4
+#define MX6SX_PAD_SD2_DATA2__UART6_TX 0x0248 0x0590 0x0000 0x7 0x0
+#define MX6SX_PAD_SD2_DATA2__VADC_CLAMP_CURRENT_2 0x0248 0x0590 0x0000 0x8 0x0
+#define MX6SX_PAD_SD2_DATA2__MMDC_DEBUG_32 0x0248 0x0590 0x0000 0x9 0x0
+#define MX6SX_PAD_SD2_DATA3__USDHC2_DATA3 0x024C 0x0594 0x0000 0x0 0x0
+#define MX6SX_PAD_SD2_DATA3__AUDMUX_AUD6_TXD 0x024C 0x0594 0x0678 0x1 0x2
+#define MX6SX_PAD_SD2_DATA3__KPP_COL_6 0x024C 0x0594 0x07CC 0x2 0x1
+#define MX6SX_PAD_SD2_DATA3__ECSPI4_MISO 0x024C 0x0594 0x0744 0x3 0x1
+#define MX6SX_PAD_SD2_DATA3__MLB_DATA 0x024C 0x0594 0x07EC 0x4 0x2
+#define MX6SX_PAD_SD2_DATA3__GPIO6_IO_11 0x024C 0x0594 0x0000 0x5 0x0
+#define MX6SX_PAD_SD2_DATA3__SPDIF_IN 0x024C 0x0594 0x0824 0x6 0x4
+#define MX6SX_PAD_SD2_DATA3__UART6_RX 0x024C 0x0594 0x0858 0x7 0x5
+#define MX6SX_PAD_SD2_DATA3__UART6_TX 0x024C 0x0594 0x0000 0x7 0x0
+#define MX6SX_PAD_SD2_DATA3__VADC_CLAMP_CURRENT_3 0x024C 0x0594 0x0000 0x8 0x0
+#define MX6SX_PAD_SD2_DATA3__MMDC_DEBUG_31 0x024C 0x0594 0x0000 0x9 0x0
+#define MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x0250 0x0598 0x0000 0x0 0x0
+#define MX6SX_PAD_SD3_CLK__UART4_CTS_B 0x0250 0x0598 0x0000 0x1 0x0
+#define MX6SX_PAD_SD3_CLK__ECSPI4_SCLK 0x0250 0x0598 0x0740 0x2 0x0
+#define MX6SX_PAD_SD3_CLK__AUDMUX_AUD6_RXFS 0x0250 0x0598 0x0680 0x3 0x0
+#define MX6SX_PAD_SD3_CLK__LCDIF2_VSYNC 0x0250 0x0598 0x0000 0x4 0x0
+#define MX6SX_PAD_SD3_CLK__GPIO7_IO_0 0x0250 0x0598 0x0000 0x5 0x0
+#define MX6SX_PAD_SD3_CLK__LCDIF2_BUSY 0x0250 0x0598 0x07E4 0x6 0x0
+#define MX6SX_PAD_SD3_CLK__TPSMP_HDATA_29 0x0250 0x0598 0x0000 0x7 0x0
+#define MX6SX_PAD_SD3_CLK__SDMA_DEBUG_EVENT_CHANNEL_5 0x0250 0x0598 0x0000 0x9 0x0
+#define MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x0254 0x059C 0x0000 0x0 0x0
+#define MX6SX_PAD_SD3_CMD__UART4_RX 0x0254 0x059C 0x0848 0x1 0x0
+#define MX6SX_PAD_SD3_CMD__UART4_TX 0x0254 0x059C 0x0000 0x1 0x0
+#define MX6SX_PAD_SD3_CMD__ECSPI4_MOSI 0x0254 0x059C 0x0748 0x2 0x0
+#define MX6SX_PAD_SD3_CMD__AUDMUX_AUD6_RXC 0x0254 0x059C 0x067C 0x3 0x0
+#define MX6SX_PAD_SD3_CMD__LCDIF2_HSYNC 0x0254 0x059C 0x07E4 0x4 0x1
+#define MX6SX_PAD_SD3_CMD__GPIO7_IO_1 0x0254 0x059C 0x0000 0x5 0x0
+#define MX6SX_PAD_SD3_CMD__LCDIF2_RS 0x0254 0x059C 0x0000 0x6 0x0
+#define MX6SX_PAD_SD3_CMD__TPSMP_HDATA_28 0x0254 0x059C 0x0000 0x7 0x0
+#define MX6SX_PAD_SD3_CMD__SDMA_DEBUG_EVENT_CHANNEL_4 0x0254 0x059C 0x0000 0x9 0x0
+#define MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x0258 0x05A0 0x0000 0x0 0x0
+#define MX6SX_PAD_SD3_DATA0__I2C4_SCL 0x0258 0x05A0 0x07C0 0x1 0x0
+#define MX6SX_PAD_SD3_DATA0__ECSPI2_SS1 0x0258 0x05A0 0x0000 0x2 0x0
+#define MX6SX_PAD_SD3_DATA0__AUDMUX_AUD6_RXD 0x0258 0x05A0 0x0674 0x3 0x0
+#define MX6SX_PAD_SD3_DATA0__LCDIF2_DATA_1 0x0258 0x05A0 0x0000 0x4 0x0
+#define MX6SX_PAD_SD3_DATA0__GPIO7_IO_2 0x0258 0x05A0 0x0000 0x5 0x0
+#define MX6SX_PAD_SD3_DATA0__DCIC1_OUT 0x0258 0x05A0 0x0000 0x6 0x0
+#define MX6SX_PAD_SD3_DATA0__TPSMP_HDATA_30 0x0258 0x05A0 0x0000 0x7 0x0
+#define MX6SX_PAD_SD3_DATA0__GPU_DEBUG_0 0x0258 0x05A0 0x0000 0x8 0x0
+#define MX6SX_PAD_SD3_DATA0__SDMA_DEBUG_EVT_CHN_LINES_0 0x0258 0x05A0 0x0000 0x9 0x0
+#define MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x025C 0x05A4 0x0000 0x0 0x0
+#define MX6SX_PAD_SD3_DATA1__I2C4_SDA 0x025C 0x05A4 0x07C4 0x1 0x0
+#define MX6SX_PAD_SD3_DATA1__ECSPI2_SS2 0x025C 0x05A4 0x0000 0x2 0x0
+#define MX6SX_PAD_SD3_DATA1__AUDMUX_AUD6_TXC 0x025C 0x05A4 0x0684 0x3 0x0
+#define MX6SX_PAD_SD3_DATA1__LCDIF2_DATA_0 0x025C 0x05A4 0x0000 0x4 0x0
+#define MX6SX_PAD_SD3_DATA1__GPIO7_IO_3 0x025C 0x05A4 0x0000 0x5 0x0
+#define MX6SX_PAD_SD3_DATA1__DCIC2_OUT 0x025C 0x05A4 0x0000 0x6 0x0
+#define MX6SX_PAD_SD3_DATA1__TPSMP_HDATA_31 0x025C 0x05A4 0x0000 0x7 0x0
+#define MX6SX_PAD_SD3_DATA1__GPU_DEBUG_1 0x025C 0x05A4 0x0000 0x8 0x0
+#define MX6SX_PAD_SD3_DATA1__SDMA_DEBUG_EVT_CHN_LINES_1 0x025C 0x05A4 0x0000 0x9 0x0
+#define MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x0260 0x05A8 0x0000 0x0 0x0
+#define MX6SX_PAD_SD3_DATA2__UART4_RTS_B 0x0260 0x05A8 0x0844 0x1 0x1
+#define MX6SX_PAD_SD3_DATA2__ECSPI4_SS0 0x0260 0x05A8 0x074C 0x2 0x0
+#define MX6SX_PAD_SD3_DATA2__AUDMUX_AUD6_TXFS 0x0260 0x05A8 0x0688 0x3 0x0
+#define MX6SX_PAD_SD3_DATA2__LCDIF2_CLK 0x0260 0x05A8 0x0000 0x4 0x0
+#define MX6SX_PAD_SD3_DATA2__GPIO7_IO_4 0x0260 0x05A8 0x0000 0x5 0x0
+#define MX6SX_PAD_SD3_DATA2__LCDIF2_WR_RWN 0x0260 0x05A8 0x0000 0x6 0x0
+#define MX6SX_PAD_SD3_DATA2__TPSMP_HDATA_26 0x0260 0x05A8 0x0000 0x7 0x0
+#define MX6SX_PAD_SD3_DATA2__GPU_DEBUG_2 0x0260 0x05A8 0x0000 0x8 0x0
+#define MX6SX_PAD_SD3_DATA2__SDMA_DEBUG_EVENT_CHANNEL_2 0x0260 0x05A8 0x0000 0x9 0x0
+#define MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x0264 0x05AC 0x0000 0x0 0x0
+#define MX6SX_PAD_SD3_DATA3__UART4_RX 0x0264 0x05AC 0x0848 0x1 0x1
+#define MX6SX_PAD_SD3_DATA3__UART4_TX 0x0264 0x05AC 0x0000 0x1 0x0
+#define MX6SX_PAD_SD3_DATA3__ECSPI4_MISO 0x0264 0x05AC 0x0744 0x2 0x0
+#define MX6SX_PAD_SD3_DATA3__AUDMUX_AUD6_TXD 0x0264 0x05AC 0x0678 0x3 0x0
+#define MX6SX_PAD_SD3_DATA3__LCDIF2_ENABLE 0x0264 0x05AC 0x0000 0x4 0x0
+#define MX6SX_PAD_SD3_DATA3__GPIO7_IO_5 0x0264 0x05AC 0x0000 0x5 0x0
+#define MX6SX_PAD_SD3_DATA3__LCDIF2_RD_E 0x0264 0x05AC 0x0000 0x6 0x0
+#define MX6SX_PAD_SD3_DATA3__TPSMP_HDATA_27 0x0264 0x05AC 0x0000 0x7 0x0
+#define MX6SX_PAD_SD3_DATA3__GPU_DEBUG_3 0x0264 0x05AC 0x0000 0x8 0x0
+#define MX6SX_PAD_SD3_DATA3__SDMA_DEBUG_EVENT_CHANNEL_3 0x0264 0x05AC 0x0000 0x9 0x0
+#define MX6SX_PAD_SD3_DATA4__USDHC3_DATA4 0x0268 0x05B0 0x0000 0x0 0x0
+#define MX6SX_PAD_SD3_DATA4__CAN2_RX 0x0268 0x05B0 0x0690 0x1 0x0
+#define MX6SX_PAD_SD3_DATA4__CANFD_RX2 0x0268 0x05B0 0x0698 0x2 0x0
+#define MX6SX_PAD_SD3_DATA4__UART3_RX 0x0268 0x05B0 0x0840 0x3 0x2
+#define MX6SX_PAD_SD3_DATA4__UART3_TX 0x0268 0x05B0 0x0000 0x3 0x0
+#define MX6SX_PAD_SD3_DATA4__LCDIF2_DATA_3 0x0268 0x05B0 0x0000 0x4 0x0
+#define MX6SX_PAD_SD3_DATA4__GPIO7_IO_6 0x0268 0x05B0 0x0000 0x5 0x0
+#define MX6SX_PAD_SD3_DATA4__ENET2_1588_EVENT0_IN 0x0268 0x05B0 0x0000 0x6 0x0
+#define MX6SX_PAD_SD3_DATA4__TPSMP_HTRANS_1 0x0268 0x05B0 0x0000 0x7 0x0
+#define MX6SX_PAD_SD3_DATA4__GPU_DEBUG_4 0x0268 0x05B0 0x0000 0x8 0x0
+#define MX6SX_PAD_SD3_DATA4__SDMA_DEBUG_BUS_DEVICE_0 0x0268 0x05B0 0x0000 0x9 0x0
+#define MX6SX_PAD_SD3_DATA5__USDHC3_DATA5 0x026C 0x05B4 0x0000 0x0 0x0
+#define MX6SX_PAD_SD3_DATA5__CAN1_TX 0x026C 0x05B4 0x0000 0x1 0x0
+#define MX6SX_PAD_SD3_DATA5__CANFD_TX1 0x026C 0x05B4 0x0000 0x2 0x0
+#define MX6SX_PAD_SD3_DATA5__UART3_RX 0x026C 0x05B4 0x0840 0x3 0x3
+#define MX6SX_PAD_SD3_DATA5__UART3_TX 0x026C 0x05B4 0x0000 0x3 0x0
+#define MX6SX_PAD_SD3_DATA5__LCDIF2_DATA_2 0x026C 0x05B4 0x0000 0x4 0x0
+#define MX6SX_PAD_SD3_DATA5__GPIO7_IO_7 0x026C 0x05B4 0x0000 0x5 0x0
+#define MX6SX_PAD_SD3_DATA5__ENET2_1588_EVENT0_OUT 0x026C 0x05B4 0x0000 0x6 0x0
+#define MX6SX_PAD_SD3_DATA5__SIM_M_HWRITE 0x026C 0x05B4 0x0000 0x7 0x0
+#define MX6SX_PAD_SD3_DATA5__GPU_DEBUG_5 0x026C 0x05B4 0x0000 0x8 0x0
+#define MX6SX_PAD_SD3_DATA5__SDMA_DEBUG_BUS_DEVICE_1 0x026C 0x05B4 0x0000 0x9 0x0
+#define MX6SX_PAD_SD3_DATA6__USDHC3_DATA6 0x0270 0x05B8 0x0000 0x0 0x0
+#define MX6SX_PAD_SD3_DATA6__CAN2_TX 0x0270 0x05B8 0x0000 0x1 0x0
+#define MX6SX_PAD_SD3_DATA6__CANFD_TX2 0x0270 0x05B8 0x0000 0x2 0x0
+#define MX6SX_PAD_SD3_DATA6__UART3_RTS_B 0x0270 0x05B8 0x083C 0x3 0x2
+#define MX6SX_PAD_SD3_DATA6__LCDIF2_DATA_4 0x0270 0x05B8 0x0000 0x4 0x0
+#define MX6SX_PAD_SD3_DATA6__GPIO7_IO_8 0x0270 0x05B8 0x0000 0x5 0x0
+#define MX6SX_PAD_SD3_DATA6__ENET1_1588_EVENT0_OUT 0x0270 0x05B8 0x0000 0x6 0x0
+#define MX6SX_PAD_SD3_DATA6__TPSMP_HTRANS_0 0x0270 0x05B8 0x0000 0x7 0x0
+#define MX6SX_PAD_SD3_DATA6__GPU_DEBUG_7 0x0270 0x05B8 0x0000 0x8 0x0
+#define MX6SX_PAD_SD3_DATA6__SDMA_DEBUG_EVT_CHN_LINES_7 0x0270 0x05B8 0x0000 0x9 0x0
+#define MX6SX_PAD_SD3_DATA7__USDHC3_DATA7 0x0274 0x05BC 0x0000 0x0 0x0
+#define MX6SX_PAD_SD3_DATA7__CAN1_RX 0x0274 0x05BC 0x068C 0x1 0x0
+#define MX6SX_PAD_SD3_DATA7__CANFD_RX1 0x0274 0x05BC 0x0694 0x2 0x0
+#define MX6SX_PAD_SD3_DATA7__UART3_CTS_B 0x0274 0x05BC 0x0000 0x3 0x0
+#define MX6SX_PAD_SD3_DATA7__LCDIF2_DATA_5 0x0274 0x05BC 0x0000 0x4 0x0
+#define MX6SX_PAD_SD3_DATA7__GPIO7_IO_9 0x0274 0x05BC 0x0000 0x5 0x0
+#define MX6SX_PAD_SD3_DATA7__ENET1_1588_EVENT0_IN 0x0274 0x05BC 0x0000 0x6 0x0
+#define MX6SX_PAD_SD3_DATA7__TPSMP_HDATA_DIR 0x0274 0x05BC 0x0000 0x7 0x0
+#define MX6SX_PAD_SD3_DATA7__GPU_DEBUG_6 0x0274 0x05BC 0x0000 0x8 0x0
+#define MX6SX_PAD_SD3_DATA7__SDMA_DEBUG_EVT_CHN_LINES_2 0x0274 0x05BC 0x0000 0x9 0x0
+#define MX6SX_PAD_SD4_CLK__USDHC4_CLK 0x0278 0x05C0 0x0000 0x0 0x0
+#define MX6SX_PAD_SD4_CLK__RAWNAND_DATA15 0x0278 0x05C0 0x0000 0x1 0x0
+#define MX6SX_PAD_SD4_CLK__ECSPI2_MISO 0x0278 0x05C0 0x0724 0x2 0x1
+#define MX6SX_PAD_SD4_CLK__AUDMUX_AUD3_RXFS 0x0278 0x05C0 0x0638 0x3 0x0
+#define MX6SX_PAD_SD4_CLK__LCDIF2_DATA_13 0x0278 0x05C0 0x0000 0x4 0x0
+#define MX6SX_PAD_SD4_CLK__GPIO6_IO_12 0x0278 0x05C0 0x0000 0x5 0x0
+#define MX6SX_PAD_SD4_CLK__ECSPI3_SS2 0x0278 0x05C0 0x0000 0x6 0x0
+#define MX6SX_PAD_SD4_CLK__TPSMP_HDATA_20 0x0278 0x05C0 0x0000 0x7 0x0
+#define MX6SX_PAD_SD4_CLK__VDEC_DEBUG_12 0x0278 0x05C0 0x0000 0x8 0x0
+#define MX6SX_PAD_SD4_CLK__SDMA_DEBUG_EVENT_CHANNEL_SEL 0x0278 0x05C0 0x0000 0x9 0x0
+#define MX6SX_PAD_SD4_CMD__USDHC4_CMD 0x027C 0x05C4 0x0000 0x0 0x0
+#define MX6SX_PAD_SD4_CMD__RAWNAND_DATA14 0x027C 0x05C4 0x0000 0x1 0x0
+#define MX6SX_PAD_SD4_CMD__ECSPI2_MOSI 0x027C 0x05C4 0x0728 0x2 0x1
+#define MX6SX_PAD_SD4_CMD__AUDMUX_AUD3_RXC 0x027C 0x05C4 0x0634 0x3 0x0
+#define MX6SX_PAD_SD4_CMD__LCDIF2_DATA_14 0x027C 0x05C4 0x0000 0x4 0x0
+#define MX6SX_PAD_SD4_CMD__GPIO6_IO_13 0x027C 0x05C4 0x0000 0x5 0x0
+#define MX6SX_PAD_SD4_CMD__ECSPI3_SS1 0x027C 0x05C4 0x0000 0x6 0x0
+#define MX6SX_PAD_SD4_CMD__TPSMP_HDATA_19 0x027C 0x05C4 0x0000 0x7 0x0
+#define MX6SX_PAD_SD4_CMD__VDEC_DEBUG_11 0x027C 0x05C4 0x0000 0x8 0x0
+#define MX6SX_PAD_SD4_CMD__SDMA_DEBUG_CORE_RUN 0x027C 0x05C4 0x0000 0x9 0x0
+#define MX6SX_PAD_SD4_DATA0__USDHC4_DATA0 0x0280 0x05C8 0x0000 0x0 0x0
+#define MX6SX_PAD_SD4_DATA0__RAWNAND_DATA10 0x0280 0x05C8 0x0000 0x1 0x0
+#define MX6SX_PAD_SD4_DATA0__ECSPI2_SS0 0x0280 0x05C8 0x072C 0x2 0x1
+#define MX6SX_PAD_SD4_DATA0__AUDMUX_AUD3_RXD 0x0280 0x05C8 0x062C 0x3 0x0
+#define MX6SX_PAD_SD4_DATA0__LCDIF2_DATA_12 0x0280 0x05C8 0x0000 0x4 0x0
+#define MX6SX_PAD_SD4_DATA0__GPIO6_IO_14 0x0280 0x05C8 0x0000 0x5 0x0
+#define MX6SX_PAD_SD4_DATA0__ECSPI3_SS3 0x0280 0x05C8 0x0000 0x6 0x0
+#define MX6SX_PAD_SD4_DATA0__TPSMP_HDATA_21 0x0280 0x05C8 0x0000 0x7 0x0
+#define MX6SX_PAD_SD4_DATA0__VDEC_DEBUG_13 0x0280 0x05C8 0x0000 0x8 0x0
+#define MX6SX_PAD_SD4_DATA0__SDMA_DEBUG_MODE 0x0280 0x05C8 0x0000 0x9 0x0
+#define MX6SX_PAD_SD4_DATA1__USDHC4_DATA1 0x0284 0x05CC 0x0000 0x0 0x0
+#define MX6SX_PAD_SD4_DATA1__RAWNAND_DATA11 0x0284 0x05CC 0x0000 0x1 0x0
+#define MX6SX_PAD_SD4_DATA1__ECSPI2_SCLK 0x0284 0x05CC 0x0720 0x2 0x1
+#define MX6SX_PAD_SD4_DATA1__AUDMUX_AUD3_TXC 0x0284 0x05CC 0x063C 0x3 0x0
+#define MX6SX_PAD_SD4_DATA1__LCDIF2_DATA_11 0x0284 0x05CC 0x0000 0x4 0x0
+#define MX6SX_PAD_SD4_DATA1__GPIO6_IO_15 0x0284 0x05CC 0x0000 0x5 0x0
+#define MX6SX_PAD_SD4_DATA1__ECSPI3_RDY 0x0284 0x05CC 0x0000 0x6 0x0
+#define MX6SX_PAD_SD4_DATA1__TPSMP_HDATA_22 0x0284 0x05CC 0x0000 0x7 0x0
+#define MX6SX_PAD_SD4_DATA1__VDEC_DEBUG_14 0x0284 0x05CC 0x0000 0x8 0x0
+#define MX6SX_PAD_SD4_DATA1__SDMA_DEBUG_BUS_ERROR 0x0284 0x05CC 0x0000 0x9 0x0
+#define MX6SX_PAD_SD4_DATA2__USDHC4_DATA2 0x0288 0x05D0 0x0000 0x0 0x0
+#define MX6SX_PAD_SD4_DATA2__RAWNAND_DATA12 0x0288 0x05D0 0x0000 0x1 0x0
+#define MX6SX_PAD_SD4_DATA2__I2C2_SDA 0x0288 0x05D0 0x07B4 0x2 0x0
+#define MX6SX_PAD_SD4_DATA2__AUDMUX_AUD3_TXFS 0x0288 0x05D0 0x0640 0x3 0x0
+#define MX6SX_PAD_SD4_DATA2__LCDIF2_DATA_10 0x0288 0x05D0 0x0000 0x4 0x0
+#define MX6SX_PAD_SD4_DATA2__GPIO6_IO_16 0x0288 0x05D0 0x0000 0x5 0x0
+#define MX6SX_PAD_SD4_DATA2__ECSPI2_SS3 0x0288 0x05D0 0x0000 0x6 0x0
+#define MX6SX_PAD_SD4_DATA2__TPSMP_HDATA_23 0x0288 0x05D0 0x0000 0x7 0x0
+#define MX6SX_PAD_SD4_DATA2__VDEC_DEBUG_15 0x0288 0x05D0 0x0000 0x8 0x0
+#define MX6SX_PAD_SD4_DATA2__SDMA_DEBUG_BUS_RWB 0x0288 0x05D0 0x0000 0x9 0x0
+#define MX6SX_PAD_SD4_DATA3__USDHC4_DATA3 0x028C 0x05D4 0x0000 0x0 0x0
+#define MX6SX_PAD_SD4_DATA3__RAWNAND_DATA13 0x028C 0x05D4 0x0000 0x1 0x0
+#define MX6SX_PAD_SD4_DATA3__I2C2_SCL 0x028C 0x05D4 0x07B0 0x2 0x0
+#define MX6SX_PAD_SD4_DATA3__AUDMUX_AUD3_TXD 0x028C 0x05D4 0x0630 0x3 0x0
+#define MX6SX_PAD_SD4_DATA3__LCDIF2_DATA_9 0x028C 0x05D4 0x0000 0x4 0x0
+#define MX6SX_PAD_SD4_DATA3__GPIO6_IO_17 0x028C 0x05D4 0x0000 0x5 0x0
+#define MX6SX_PAD_SD4_DATA3__ECSPI2_RDY 0x028C 0x05D4 0x0000 0x6 0x0
+#define MX6SX_PAD_SD4_DATA3__TPSMP_HDATA_24 0x028C 0x05D4 0x0000 0x7 0x0
+#define MX6SX_PAD_SD4_DATA3__VDEC_DEBUG_16 0x028C 0x05D4 0x0000 0x8 0x0
+#define MX6SX_PAD_SD4_DATA3__SDMA_DEBUG_MATCHED_DMBUS 0x028C 0x05D4 0x0000 0x9 0x0
+#define MX6SX_PAD_SD4_DATA4__USDHC4_DATA4 0x0290 0x05D8 0x0000 0x0 0x0
+#define MX6SX_PAD_SD4_DATA4__RAWNAND_DATA09 0x0290 0x05D8 0x0000 0x1 0x0
+#define MX6SX_PAD_SD4_DATA4__UART5_RX 0x0290 0x05D8 0x0850 0x2 0x0
+#define MX6SX_PAD_SD4_DATA4__UART5_TX 0x0290 0x05D8 0x0000 0x2 0x0
+#define MX6SX_PAD_SD4_DATA4__ECSPI3_SCLK 0x0290 0x05D8 0x0730 0x3 0x0
+#define MX6SX_PAD_SD4_DATA4__LCDIF2_DATA_8 0x0290 0x05D8 0x0000 0x4 0x0
+#define MX6SX_PAD_SD4_DATA4__GPIO6_IO_18 0x0290 0x05D8 0x0000 0x5 0x0
+#define MX6SX_PAD_SD4_DATA4__SPDIF_OUT 0x0290 0x05D8 0x0000 0x6 0x0
+#define MX6SX_PAD_SD4_DATA4__TPSMP_HDATA_16 0x0290 0x05D8 0x0000 0x7 0x0
+#define MX6SX_PAD_SD4_DATA4__USB_OTG_HOST_MODE 0x0290 0x05D8 0x0000 0x8 0x0
+#define MX6SX_PAD_SD4_DATA4__SDMA_DEBUG_RTBUFFER_WRITE 0x0290 0x05D8 0x0000 0x9 0x0
+#define MX6SX_PAD_SD4_DATA5__USDHC4_DATA5 0x0294 0x05DC 0x0000 0x0 0x0
+#define MX6SX_PAD_SD4_DATA5__RAWNAND_CE2_B 0x0294 0x05DC 0x0000 0x1 0x0
+#define MX6SX_PAD_SD4_DATA5__UART5_RX 0x0294 0x05DC 0x0850 0x2 0x1
+#define MX6SX_PAD_SD4_DATA5__UART5_TX 0x0294 0x05DC 0x0000 0x2 0x0
+#define MX6SX_PAD_SD4_DATA5__ECSPI3_MOSI 0x0294 0x05DC 0x0738 0x3 0x0
+#define MX6SX_PAD_SD4_DATA5__LCDIF2_DATA_7 0x0294 0x05DC 0x0000 0x4 0x0
+#define MX6SX_PAD_SD4_DATA5__GPIO6_IO_19 0x0294 0x05DC 0x0000 0x5 0x0
+#define MX6SX_PAD_SD4_DATA5__SPDIF_IN 0x0294 0x05DC 0x0824 0x6 0x0
+#define MX6SX_PAD_SD4_DATA5__TPSMP_HDATA_17 0x0294 0x05DC 0x0000 0x7 0x0
+#define MX6SX_PAD_SD4_DATA5__VDEC_DEBUG_9 0x0294 0x05DC 0x0000 0x8 0x0
+#define MX6SX_PAD_SD4_DATA5__SDMA_DEBUG_EVENT_CHANNEL_0 0x0294 0x05DC 0x0000 0x9 0x0
+#define MX6SX_PAD_SD4_DATA6__USDHC4_DATA6 0x0298 0x05E0 0x0000 0x0 0x0
+#define MX6SX_PAD_SD4_DATA6__RAWNAND_CE3_B 0x0298 0x05E0 0x0000 0x1 0x0
+#define MX6SX_PAD_SD4_DATA6__UART5_RTS_B 0x0298 0x05E0 0x084C 0x2 0x0
+#define MX6SX_PAD_SD4_DATA6__ECSPI3_MISO 0x0298 0x05E0 0x0734 0x3 0x0
+#define MX6SX_PAD_SD4_DATA6__LCDIF2_DATA_6 0x0298 0x05E0 0x0000 0x4 0x0
+#define MX6SX_PAD_SD4_DATA6__GPIO6_IO_20 0x0298 0x05E0 0x0000 0x5 0x0
+#define MX6SX_PAD_SD4_DATA6__USDHC4_WP 0x0298 0x05E0 0x0878 0x6 0x0
+#define MX6SX_PAD_SD4_DATA6__TPSMP_HDATA_18 0x0298 0x05E0 0x0000 0x7 0x0
+#define MX6SX_PAD_SD4_DATA6__VDEC_DEBUG_10 0x0298 0x05E0 0x0000 0x8 0x0
+#define MX6SX_PAD_SD4_DATA6__SDMA_DEBUG_EVENT_CHANNEL_1 0x0298 0x05E0 0x0000 0x9 0x0
+#define MX6SX_PAD_SD4_DATA7__USDHC4_DATA7 0x029C 0x05E4 0x0000 0x0 0x0
+#define MX6SX_PAD_SD4_DATA7__RAWNAND_DATA08 0x029C 0x05E4 0x0000 0x1 0x0
+#define MX6SX_PAD_SD4_DATA7__UART5_CTS_B 0x029C 0x05E4 0x0000 0x2 0x0
+#define MX6SX_PAD_SD4_DATA7__ECSPI3_SS0 0x029C 0x05E4 0x073C 0x3 0x0
+#define MX6SX_PAD_SD4_DATA7__LCDIF2_DATA_15 0x029C 0x05E4 0x0000 0x4 0x0
+#define MX6SX_PAD_SD4_DATA7__GPIO6_IO_21 0x029C 0x05E4 0x0000 0x5 0x0
+#define MX6SX_PAD_SD4_DATA7__USDHC4_CD_B 0x029C 0x05E4 0x0874 0x6 0x0
+#define MX6SX_PAD_SD4_DATA7__TPSMP_HDATA_15 0x029C 0x05E4 0x0000 0x7 0x0
+#define MX6SX_PAD_SD4_DATA7__USB_OTG_PWR_WAKE 0x029C 0x05E4 0x0000 0x8 0x0
+#define MX6SX_PAD_SD4_DATA7__SDMA_DEBUG_YIELD 0x029C 0x05E4 0x0000 0x9 0x0
+#define MX6SX_PAD_SD4_RESET_B__USDHC4_RESET_B 0x02A0 0x05E8 0x0000 0x0 0x0
+#define MX6SX_PAD_SD4_RESET_B__RAWNAND_DQS 0x02A0 0x05E8 0x0000 0x1 0x0
+#define MX6SX_PAD_SD4_RESET_B__USDHC4_RESET 0x02A0 0x05E8 0x0000 0x2 0x0
+#define MX6SX_PAD_SD4_RESET_B__AUDMUX_MCLK 0x02A0 0x05E8 0x0000 0x3 0x0
+#define MX6SX_PAD_SD4_RESET_B__LCDIF2_RESET 0x02A0 0x05E8 0x0000 0x4 0x0
+#define MX6SX_PAD_SD4_RESET_B__GPIO6_IO_22 0x02A0 0x05E8 0x0000 0x5 0x0
+#define MX6SX_PAD_SD4_RESET_B__LCDIF2_CS 0x02A0 0x05E8 0x0000 0x6 0x0
+#define MX6SX_PAD_SD4_RESET_B__TPSMP_HDATA_25 0x02A0 0x05E8 0x0000 0x7 0x0
+#define MX6SX_PAD_SD4_RESET_B__VDEC_DEBUG_17 0x02A0 0x05E8 0x0000 0x8 0x0
+#define MX6SX_PAD_SD4_RESET_B__SDMA_DEBUG_BUS_DEVICE_2 0x02A0 0x05E8 0x0000 0x9 0x0
+#define MX6SX_PAD_USB_H_DATA__USB_H_DATA 0x02A4 0x05EC 0x0000 0x0 0x0
+#define MX6SX_PAD_USB_H_DATA__PWM2_OUT 0x02A4 0x05EC 0x0000 0x1 0x0
+#define MX6SX_PAD_USB_H_DATA__ANATOP_24M_OUT 0x02A4 0x05EC 0x0000 0x2 0x0
+#define MX6SX_PAD_USB_H_DATA__I2C4_SDA 0x02A4 0x05EC 0x07C4 0x3 0x1
+#define MX6SX_PAD_USB_H_DATA__WDOG3_WDOG_B 0x02A4 0x05EC 0x0000 0x4 0x0
+#define MX6SX_PAD_USB_H_DATA__GPIO7_IO_10 0x02A4 0x05EC 0x0000 0x5 0x0
+#define MX6SX_PAD_USB_H_STROBE__USB_H_STROBE 0x02A8 0x05F0 0x0000 0x0 0x0
+#define MX6SX_PAD_USB_H_STROBE__PWM1_OUT 0x02A8 0x05F0 0x0000 0x1 0x0
+#define MX6SX_PAD_USB_H_STROBE__ANATOP_32K_OUT 0x02A8 0x05F0 0x0000 0x2 0x0
+#define MX6SX_PAD_USB_H_STROBE__I2C4_SCL 0x02A8 0x05F0 0x07C0 0x3 0x1
+#define MX6SX_PAD_USB_H_STROBE__WDOG3_WDOG_RST_B_DEB 0x02A8 0x05F0 0x0000 0x4 0x0
+#define MX6SX_PAD_USB_H_STROBE__GPIO7_IO_11 0x02A8 0x05F0 0x0000 0x5 0x0
+
+#endif /* __DTS_IMX6SX_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx6sx-sabreauto.dts b/arch/arm/boot/dts/imx6sx-sabreauto.dts
new file mode 100644
index 000000000..e3c0b63c2
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-sabreauto.dts
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/dts-v1/;
+
+#include "imx6sx.dtsi"
+
+/ {
+ model = "Freescale i.MX6 SoloX Sabre Auto Board";
+ compatible = "fsl,imx6sx-sabreauto", "fsl,imx6sx";
+
+ memory {
+ reg = <0x80000000 0x80000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vcc_sd3: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_vcc_sd3>;
+ regulator-name = "VCC_SD3";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio2 11 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ bus-width = <8>;
+ cd-gpios = <&gpio7 10 GPIO_ACTIVE_HIGH>;
+ wp-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&vcc_sd3>;
+ status = "okay";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ bus-width = <8>;
+ cd-gpios = <&gpio7 11 GPIO_ACTIVE_HIGH>;
+ no-1-8-v;
+ keep-power-in-suspend;
+ enable-sdio-wakup;
+ status = "okay";
+};
+
+&iomuxc {
+ imx6x-sabreauto {
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO04__UART1_TX 0x1b0b1
+ MX6SX_PAD_GPIO1_IO05__UART1_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x17059
+ MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x10059
+ MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x17059
+ MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x17059
+ MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x17059
+ MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x17059
+ MX6SX_PAD_SD3_DATA4__USDHC3_DATA4 0x17059
+ MX6SX_PAD_SD3_DATA5__USDHC3_DATA5 0x17059
+ MX6SX_PAD_SD3_DATA6__USDHC3_DATA6 0x17059
+ MX6SX_PAD_SD3_DATA7__USDHC3_DATA7 0x17059
+ MX6SX_PAD_KEY_COL0__GPIO2_IO_10 0x17059 /* CD */
+ MX6SX_PAD_KEY_ROW0__GPIO2_IO_15 0x17059 /* WP */
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp-100mhz {
+ fsl,pins = <
+ MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x170b9
+ MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x100b9
+ MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x170b9
+ MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x170b9
+ MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x170b9
+ MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x170b9
+ MX6SX_PAD_SD3_DATA4__USDHC3_DATA4 0x170b9
+ MX6SX_PAD_SD3_DATA5__USDHC3_DATA5 0x170b9
+ MX6SX_PAD_SD3_DATA6__USDHC3_DATA6 0x170b9
+ MX6SX_PAD_SD3_DATA7__USDHC3_DATA7 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp-200mhz {
+ fsl,pins = <
+ MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x170f9
+ MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x100f9
+ MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x170f9
+ MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x170f9
+ MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x170f9
+ MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x170f9
+ MX6SX_PAD_SD3_DATA4__USDHC3_DATA4 0x170f9
+ MX6SX_PAD_SD3_DATA5__USDHC3_DATA5 0x170f9
+ MX6SX_PAD_SD3_DATA6__USDHC3_DATA6 0x170f9
+ MX6SX_PAD_SD3_DATA7__USDHC3_DATA7 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6SX_PAD_SD4_CMD__USDHC4_CMD 0x17059
+ MX6SX_PAD_SD4_CLK__USDHC4_CLK 0x10059
+ MX6SX_PAD_SD4_DATA0__USDHC4_DATA0 0x17059
+ MX6SX_PAD_SD4_DATA1__USDHC4_DATA1 0x17059
+ MX6SX_PAD_SD4_DATA2__USDHC4_DATA2 0x17059
+ MX6SX_PAD_SD4_DATA3__USDHC4_DATA3 0x17059
+ MX6SX_PAD_SD4_DATA7__GPIO6_IO_21 0x17059 /* CD */
+ MX6SX_PAD_SD4_DATA6__GPIO6_IO_20 0x17059 /* WP */
+ >;
+ };
+
+ pinctrl_vcc_sd3: vccsd3grp {
+ fsl,pins = <
+ MX6SX_PAD_KEY_COL1__GPIO2_IO_11 0x17059
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sx-sdb-reva.dts b/arch/arm/boot/dts/imx6sx-sdb-reva.dts
new file mode 100644
index 000000000..c76b87cba
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-sdb-reva.dts
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2015 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 "imx6sx-sdb.dtsi"
+
+/ {
+ model = "Freescale i.MX6 SoloX SDB RevA Board";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&qspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi2>;
+ status = "okay";
+
+ flash0: s25fl128s@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25fl128s";
+ spi-max-frequency = <66000000>;
+ };
+
+ flash1: s25fl128s@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25fl128s";
+ spi-max-frequency = <66000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sx-sdb.dts b/arch/arm/boot/dts/imx6sx-sdb.dts
new file mode 100644
index 000000000..0bfc4e786
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-sdb.dts
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2015 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 "imx6sx-sdb.dtsi"
+
+/ {
+ model = "Freescale i.MX6 SoloX SDB RevB Board";
+};
+
+&cpu0 {
+ operating-points = <
+ /* kHz uV */
+ 996000 1250000
+ 792000 1175000
+ 396000 1175000
+ >;
+ fsl,soc-operating-points = <
+ /* ARM kHz SOC uV */
+ 996000 1250000
+ 792000 1175000
+ 396000 1175000
+ >;
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze200";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&qspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi2>;
+ status = "okay";
+
+ flash0: n25q256a@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ reg = <0>;
+ };
+
+ flash1: n25q256a@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q256a";
+ spi-max-frequency = <29000000>;
+ reg = <1>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sx-sdb.dtsi b/arch/arm/boot/dts/imx6sx-sdb.dtsi
new file mode 100644
index 000000000..cef04cef3
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-sdb.dtsi
@@ -0,0 +1,562 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "imx6sx.dtsi"
+
+/ {
+ model = "Freescale i.MX6 SoloX SDB Board";
+ compatible = "fsl,imx6sx-sdb", "fsl,imx6sx";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory {
+ reg = <0x80000000 0x40000000>;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm3 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vcc_sd3: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_vcc_sd3>;
+ regulator-name = "VCC_SD3";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio2 11 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb_otg1_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb_otg2_vbus: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg2>;
+ regulator-name = "usb_otg2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_psu_5v: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "PSU-5V0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_lcd_3v3: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "lcd-3v3";
+ gpio = <&gpio3 27 0>;
+ enable-active-high;
+ };
+
+ reg_peri_3v3: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_peri_3v3>;
+ regulator-name = "peri_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ reg_enet_3v3: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet_3v3>;
+ regulator-name = "enet_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6sx-sdb-wm8962", "fsl,imx-audio-wm8962";
+ model = "wm8962-audio";
+ ssi-controller = <&ssi2>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "Ext Spk", "SPKOUTL",
+ "Ext Spk", "SPKOUTR",
+ "AMIC", "MICBIAS",
+ "IN3R", "AMIC";
+ mux-int-port = <2>;
+ mux-ext-port = <6>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1>;
+ phy-supply = <&reg_enet_3v3>;
+ phy-mode = "rgmii";
+ phy-handle = <&ethphy1>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ ethphy2: ethernet-phy@2 {
+ reg = <2>;
+ };
+ };
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet2>;
+ phy-mode = "rgmii";
+ phy-handle = <&ethphy2>;
+ status = "okay";
+};
+
+&i2c4 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ status = "okay";
+
+ codec: wm8962@1a {
+ compatible = "wlf,wm8962";
+ reg = <0x1a>;
+ clocks = <&clks IMX6SX_CLK_AUDIO>;
+ DCVDD-supply = <&vgen4_reg>;
+ DBVDD-supply = <&vgen4_reg>;
+ AVDD-supply = <&vgen4_reg>;
+ CPVDD-supply = <&vgen4_reg>;
+ MICVDD-supply = <&vgen3_reg>;
+ PLLVDD-supply = <&vgen4_reg>;
+ SPKVDD1-supply = <&reg_psu_5v>;
+ SPKVDD2-supply = <&reg_psu_5v>;
+ };
+};
+
+&lcdif1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcd>;
+ lcd-supply = <&reg_lcd_3v3>;
+ display = <&display0>;
+ status = "okay";
+
+ display0: display0 {
+ bits-per-pixel = <16>;
+ bus-width = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <33500000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <89>;
+ hfront-porch = <164>;
+ vback-porch = <23>;
+ vfront-porch = <10>;
+ hsync-len = <10>;
+ vsync-len = <10>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>;
+ status = "okay";
+};
+
+&snvs_poweroff {
+ status = "okay";
+};
+
+&ssi2 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart5 { /* for bluetooth */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1_id>;
+ status = "okay";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usb_otg2_vbus>;
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ non-removable;
+ no-1-8-v;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ bus-width = <8>;
+ cd-gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>;
+ wp-gpios = <&gpio2 15 GPIO_ACTIVE_HIGH>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&vcc_sd3>;
+ status = "okay";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ cd-gpios = <&gpio6 21 GPIO_ACTIVE_HIGH>;
+ wp-gpios = <&gpio6 20 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&iomuxc {
+ imx6x-sdb {
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA00__AUDMUX_AUD6_TXC 0x130b0
+ MX6SX_PAD_CSI_DATA01__AUDMUX_AUD6_TXFS 0x130b0
+ MX6SX_PAD_CSI_HSYNC__AUDMUX_AUD6_TXD 0x120b0
+ MX6SX_PAD_CSI_VSYNC__AUDMUX_AUD6_RXD 0x130b0
+ MX6SX_PAD_CSI_PIXCLK__AUDMUX_MCLK 0x130b0
+ >;
+ };
+
+ pinctrl_enet1: enet1grp {
+ fsl,pins = <
+ MX6SX_PAD_ENET1_MDIO__ENET1_MDIO 0xa0b1
+ MX6SX_PAD_ENET1_MDC__ENET1_MDC 0xa0b1
+ MX6SX_PAD_RGMII1_TXC__ENET1_RGMII_TXC 0xa0b1
+ MX6SX_PAD_RGMII1_TD0__ENET1_TX_DATA_0 0xa0b1
+ MX6SX_PAD_RGMII1_TD1__ENET1_TX_DATA_1 0xa0b1
+ MX6SX_PAD_RGMII1_TD2__ENET1_TX_DATA_2 0xa0b1
+ MX6SX_PAD_RGMII1_TD3__ENET1_TX_DATA_3 0xa0b1
+ MX6SX_PAD_RGMII1_TX_CTL__ENET1_TX_EN 0xa0b1
+ MX6SX_PAD_RGMII1_RXC__ENET1_RX_CLK 0x3081
+ MX6SX_PAD_RGMII1_RD0__ENET1_RX_DATA_0 0x3081
+ MX6SX_PAD_RGMII1_RD1__ENET1_RX_DATA_1 0x3081
+ MX6SX_PAD_RGMII1_RD2__ENET1_RX_DATA_2 0x3081
+ MX6SX_PAD_RGMII1_RD3__ENET1_RX_DATA_3 0x3081
+ MX6SX_PAD_RGMII1_RX_CTL__ENET1_RX_EN 0x3081
+ MX6SX_PAD_ENET2_RX_CLK__ENET2_REF_CLK_25M 0x91
+ >;
+ };
+
+ pinctrl_enet_3v3: enet3v3grp {
+ fsl,pins = <
+ MX6SX_PAD_ENET2_COL__GPIO2_IO_6 0x80000000
+ >;
+ };
+
+ pinctrl_enet2: enet2grp {
+ fsl,pins = <
+ MX6SX_PAD_RGMII2_TXC__ENET2_RGMII_TXC 0xa0b9
+ MX6SX_PAD_RGMII2_TD0__ENET2_TX_DATA_0 0xa0b1
+ MX6SX_PAD_RGMII2_TD1__ENET2_TX_DATA_1 0xa0b1
+ MX6SX_PAD_RGMII2_TD2__ENET2_TX_DATA_2 0xa0b1
+ MX6SX_PAD_RGMII2_TD3__ENET2_TX_DATA_3 0xa0b1
+ MX6SX_PAD_RGMII2_TX_CTL__ENET2_TX_EN 0xa0b1
+ MX6SX_PAD_RGMII2_RXC__ENET2_RX_CLK 0x3081
+ MX6SX_PAD_RGMII2_RD0__ENET2_RX_DATA_0 0x3081
+ MX6SX_PAD_RGMII2_RD1__ENET2_RX_DATA_1 0x3081
+ MX6SX_PAD_RGMII2_RD2__ENET2_RX_DATA_2 0x3081
+ MX6SX_PAD_RGMII2_RD3__ENET2_RX_DATA_3 0x3081
+ MX6SX_PAD_RGMII2_RX_CTL__ENET2_RX_EN 0x3081
+ >;
+ };
+
+ pinctrl_gpio_keys: gpio_keysgrp {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA04__GPIO1_IO_18 0x17059
+ MX6SX_PAD_CSI_DATA05__GPIO1_IO_19 0x17059
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO01__I2C1_SDA 0x4001b8b1
+ MX6SX_PAD_GPIO1_IO00__I2C1_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+ MX6SX_PAD_CSI_DATA07__I2C4_SDA 0x4001b8b1
+ MX6SX_PAD_CSI_DATA06__I2C4_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_lcd: lcdgrp {
+ fsl,pins = <
+ MX6SX_PAD_LCD1_DATA00__LCDIF1_DATA_0 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA01__LCDIF1_DATA_1 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA02__LCDIF1_DATA_2 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA03__LCDIF1_DATA_3 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA04__LCDIF1_DATA_4 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA05__LCDIF1_DATA_5 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA06__LCDIF1_DATA_6 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA07__LCDIF1_DATA_7 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA08__LCDIF1_DATA_8 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA09__LCDIF1_DATA_9 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA10__LCDIF1_DATA_10 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA11__LCDIF1_DATA_11 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA12__LCDIF1_DATA_12 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA13__LCDIF1_DATA_13 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA14__LCDIF1_DATA_14 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA15__LCDIF1_DATA_15 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA16__LCDIF1_DATA_16 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA17__LCDIF1_DATA_17 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA18__LCDIF1_DATA_18 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA19__LCDIF1_DATA_19 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA20__LCDIF1_DATA_20 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA21__LCDIF1_DATA_21 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA22__LCDIF1_DATA_22 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA23__LCDIF1_DATA_23 0x4001b0b0
+ MX6SX_PAD_LCD1_CLK__LCDIF1_CLK 0x4001b0b0
+ MX6SX_PAD_LCD1_ENABLE__LCDIF1_ENABLE 0x4001b0b0
+ MX6SX_PAD_LCD1_VSYNC__LCDIF1_VSYNC 0x4001b0b0
+ MX6SX_PAD_LCD1_HSYNC__LCDIF1_HSYNC 0x4001b0b0
+ MX6SX_PAD_LCD1_RESET__GPIO3_IO_27 0x4001b0b0
+ >;
+ };
+
+ pinctrl_peri_3v3: peri3v3grp {
+ fsl,pins = <
+ MX6SX_PAD_QSPI1A_DATA0__GPIO4_IO_16 0x80000000
+ >;
+ };
+
+ pinctrl_pwm3: pwm3grp-1 {
+ fsl,pins = <
+ MX6SX_PAD_SD1_DATA2__PWM3_OUT 0x110b0
+ >;
+ };
+
+ pinctrl_qspi2: qspi2grp {
+ fsl,pins = <
+ MX6SX_PAD_NAND_WP_B__QSPI2_A_DATA_0 0x70f1
+ MX6SX_PAD_NAND_READY_B__QSPI2_A_DATA_1 0x70f1
+ MX6SX_PAD_NAND_CE0_B__QSPI2_A_DATA_2 0x70f1
+ MX6SX_PAD_NAND_CE1_B__QSPI2_A_DATA_3 0x70f1
+ MX6SX_PAD_NAND_CLE__QSPI2_A_SCLK 0x70f1
+ MX6SX_PAD_NAND_ALE__QSPI2_A_SS0_B 0x70f1
+ MX6SX_PAD_NAND_DATA01__QSPI2_B_DATA_0 0x70f1
+ MX6SX_PAD_NAND_DATA00__QSPI2_B_DATA_1 0x70f1
+ MX6SX_PAD_NAND_WE_B__QSPI2_B_DATA_2 0x70f1
+ MX6SX_PAD_NAND_RE_B__QSPI2_B_DATA_3 0x70f1
+ MX6SX_PAD_NAND_DATA02__QSPI2_B_SCLK 0x70f1
+ MX6SX_PAD_NAND_DATA03__QSPI2_B_SS0_B 0x70f1
+ >;
+ };
+
+ pinctrl_vcc_sd3: vccsd3grp {
+ fsl,pins = <
+ MX6SX_PAD_KEY_COL1__GPIO2_IO_11 0x17059
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO04__UART1_TX 0x1b0b1
+ MX6SX_PAD_GPIO1_IO05__UART1_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart5: uart5grp {
+ fsl,pins = <
+ MX6SX_PAD_KEY_ROW3__UART5_RX 0x1b0b1
+ MX6SX_PAD_KEY_COL3__UART5_TX 0x1b0b1
+ MX6SX_PAD_KEY_ROW2__UART5_CTS_B 0x1b0b1
+ MX6SX_PAD_KEY_COL2__UART5_RTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_usb_otg1: usbotg1grp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO09__GPIO1_IO_9 0x10b0
+ >;
+ };
+
+ pinctrl_usb_otg1_id: usbotg1idgrp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO10__ANATOP_OTG1_ID 0x17059
+ >;
+ };
+
+ pinctrl_usb_otg2: usbot2ggrp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO12__GPIO1_IO_12 0x10b0
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6SX_PAD_SD2_CMD__USDHC2_CMD 0x17059
+ MX6SX_PAD_SD2_CLK__USDHC2_CLK 0x10059
+ MX6SX_PAD_SD2_DATA0__USDHC2_DATA0 0x17059
+ MX6SX_PAD_SD2_DATA1__USDHC2_DATA1 0x17059
+ MX6SX_PAD_SD2_DATA2__USDHC2_DATA2 0x17059
+ MX6SX_PAD_SD2_DATA3__USDHC2_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x17059
+ MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x10059
+ MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x17059
+ MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x17059
+ MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x17059
+ MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x17059
+ MX6SX_PAD_SD3_DATA4__USDHC3_DATA4 0x17059
+ MX6SX_PAD_SD3_DATA5__USDHC3_DATA5 0x17059
+ MX6SX_PAD_SD3_DATA6__USDHC3_DATA6 0x17059
+ MX6SX_PAD_SD3_DATA7__USDHC3_DATA7 0x17059
+ MX6SX_PAD_KEY_COL0__GPIO2_IO_10 0x17059 /* CD */
+ MX6SX_PAD_KEY_ROW0__GPIO2_IO_15 0x17059 /* WP */
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp-100mhz {
+ fsl,pins = <
+ MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x170b9
+ MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x100b9
+ MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x170b9
+ MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x170b9
+ MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x170b9
+ MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x170b9
+ MX6SX_PAD_SD3_DATA4__USDHC3_DATA4 0x170b9
+ MX6SX_PAD_SD3_DATA5__USDHC3_DATA5 0x170b9
+ MX6SX_PAD_SD3_DATA6__USDHC3_DATA6 0x170b9
+ MX6SX_PAD_SD3_DATA7__USDHC3_DATA7 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp-200mhz {
+ fsl,pins = <
+ MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x170f9
+ MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x100f9
+ MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x170f9
+ MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x170f9
+ MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x170f9
+ MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x170f9
+ MX6SX_PAD_SD3_DATA4__USDHC3_DATA4 0x170f9
+ MX6SX_PAD_SD3_DATA5__USDHC3_DATA5 0x170f9
+ MX6SX_PAD_SD3_DATA6__USDHC3_DATA6 0x170f9
+ MX6SX_PAD_SD3_DATA7__USDHC3_DATA7 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6SX_PAD_SD4_CMD__USDHC4_CMD 0x17059
+ MX6SX_PAD_SD4_CLK__USDHC4_CLK 0x10059
+ MX6SX_PAD_SD4_DATA0__USDHC4_DATA0 0x17059
+ MX6SX_PAD_SD4_DATA1__USDHC4_DATA1 0x17059
+ MX6SX_PAD_SD4_DATA2__USDHC4_DATA2 0x17059
+ MX6SX_PAD_SD4_DATA3__USDHC4_DATA3 0x17059
+ MX6SX_PAD_SD4_DATA7__GPIO6_IO_21 0x17059 /* CD */
+ MX6SX_PAD_SD4_DATA6__GPIO6_IO_20 0x17059 /* WP */
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
new file mode 100644
index 000000000..83c61ae78
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -0,0 +1,1226 @@
+/*
+ * Copyright 2014 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 <dt-bindings/clock/imx6sx-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "imx6sx-pinfunc.h"
+#include "skeleton.dtsi"
+
+/ {
+ aliases {
+ can0 = &flexcan1;
+ can1 = &flexcan2;
+ ethernet0 = &fec1;
+ ethernet1 = &fec2;
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ gpio4 = &gpio5;
+ gpio5 = &gpio6;
+ gpio6 = &gpio7;
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ i2c2 = &i2c3;
+ i2c3 = &i2c4;
+ mmc0 = &usdhc1;
+ mmc1 = &usdhc2;
+ mmc2 = &usdhc3;
+ mmc3 = &usdhc4;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ serial5 = &uart6;
+ spi0 = &ecspi1;
+ spi1 = &ecspi2;
+ spi2 = &ecspi3;
+ spi3 = &ecspi4;
+ spi4 = &ecspi5;
+ usbphy0 = &usbphy1;
+ usbphy1 = &usbphy2;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ operating-points = <
+ /* kHz uV */
+ 996000 1250000
+ 792000 1175000
+ 396000 1075000
+ >;
+ fsl,soc-operating-points = <
+ /* ARM kHz SOC uV */
+ 996000 1175000
+ 792000 1175000
+ 396000 1175000
+ >;
+ clock-latency = <61036>; /* two CLK32 periods */
+ clocks = <&clks IMX6SX_CLK_ARM>,
+ <&clks IMX6SX_CLK_PLL2_PFD2>,
+ <&clks IMX6SX_CLK_STEP>,
+ <&clks IMX6SX_CLK_PLL1_SW>,
+ <&clks IMX6SX_CLK_PLL1_SYS>;
+ clock-names = "arm", "pll2_pfd2_396m", "step",
+ "pll1_sw", "pll1_sys";
+ arm-supply = <&reg_arm>;
+ soc-supply = <&reg_soc>;
+ };
+ };
+
+ intc: interrupt-controller@00a01000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x00a01000 0x1000>,
+ <0x00a00100 0x100>;
+ interrupt-parent = <&intc>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ckil: clock@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "ckil";
+ };
+
+ osc: clock@1 {
+ compatible = "fixed-clock";
+ reg = <1>;
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "osc";
+ };
+
+ ipp_di0: clock@2 {
+ compatible = "fixed-clock";
+ reg = <2>;
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "ipp_di0";
+ };
+
+ ipp_di1: clock@3 {
+ compatible = "fixed-clock";
+ reg = <3>;
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "ipp_di1";
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&gpc>;
+ ranges;
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ ocram: sram@00900000 {
+ compatible = "mmio-sram";
+ reg = <0x00900000 0x20000>;
+ clocks = <&clks IMX6SX_CLK_OCRAM>;
+ };
+
+ L2: l2-cache@00a02000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x00a02000 0x1000>;
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+ cache-unified;
+ cache-level = <2>;
+ arm,tag-latency = <4 2 3>;
+ arm,data-latency = <4 2 3>;
+ };
+
+ dma_apbh: dma-apbh@01804000 {
+ compatible = "fsl,imx6sx-dma-apbh", "fsl,imx28-dma-apbh";
+ reg = <0x01804000 0x2000>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
+ #dma-cells = <1>;
+ dma-channels = <4>;
+ clocks = <&clks IMX6SX_CLK_APBH_DMA>;
+ };
+
+ gpmi: gpmi-nand@01806000{
+ compatible = "fsl,imx6sx-gpmi-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x01806000 0x2000>, <0x01808000 0x4000>;
+ reg-names = "gpmi-nand", "bch";
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "bch";
+ clocks = <&clks IMX6SX_CLK_GPMI_IO>,
+ <&clks IMX6SX_CLK_GPMI_APB>,
+ <&clks IMX6SX_CLK_GPMI_BCH>,
+ <&clks IMX6SX_CLK_GPMI_BCH_APB>,
+ <&clks IMX6SX_CLK_PER1_BCH>;
+ clock-names = "gpmi_io", "gpmi_apb", "gpmi_bch",
+ "gpmi_bch_apb", "per1_bch";
+ dmas = <&dma_apbh 0>;
+ dma-names = "rx-tx";
+ status = "disabled";
+ };
+
+ aips1: aips-bus@02000000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02000000 0x100000>;
+ ranges;
+
+ spba-bus@02000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02000000 0x40000>;
+ ranges;
+
+ spdif: spdif@02004000 {
+ compatible = "fsl,imx6sx-spdif", "fsl,imx35-spdif";
+ reg = <0x02004000 0x4000>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 14 18 0>,
+ <&sdma 15 18 0>;
+ dma-names = "rx", "tx";
+ clocks = <&clks IMX6SX_CLK_SPDIF>,
+ <&clks IMX6SX_CLK_OSC>,
+ <&clks IMX6SX_CLK_SPDIF>,
+ <&clks 0>, <&clks 0>, <&clks 0>,
+ <&clks IMX6SX_CLK_IPG>,
+ <&clks 0>, <&clks 0>,
+ <&clks IMX6SX_CLK_SPBA>;
+ clock-names = "core", "rxtx0",
+ "rxtx1", "rxtx2",
+ "rxtx3", "rxtx4",
+ "rxtx5", "rxtx6",
+ "rxtx7", "dma";
+ status = "disabled";
+ };
+
+ ecspi1: ecspi@02008000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sx-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02008000 0x4000>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_ECSPI1>,
+ <&clks IMX6SX_CLK_ECSPI1>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi2: ecspi@0200c000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sx-ecspi", "fsl,imx51-ecspi";
+ reg = <0x0200c000 0x4000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_ECSPI2>,
+ <&clks IMX6SX_CLK_ECSPI2>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi3: ecspi@02010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sx-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02010000 0x4000>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_ECSPI3>,
+ <&clks IMX6SX_CLK_ECSPI3>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi4: ecspi@02014000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sx-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02014000 0x4000>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_ECSPI4>,
+ <&clks IMX6SX_CLK_ECSPI4>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart1: serial@02020000 {
+ compatible = "fsl,imx6sx-uart", "fsl,imx21-uart";
+ reg = <0x02020000 0x4000>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_UART_IPG>,
+ <&clks IMX6SX_CLK_UART_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 25 4 0>, <&sdma 26 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ esai: esai@02024000 {
+ reg = <0x02024000 0x4000>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_ESAI_IPG>,
+ <&clks IMX6SX_CLK_ESAI_MEM>,
+ <&clks IMX6SX_CLK_ESAI_EXTAL>,
+ <&clks IMX6SX_CLK_ESAI_IPG>,
+ <&clks IMX6SX_CLK_SPBA>;
+ clock-names = "core", "mem", "extal",
+ "fsys", "dma";
+ status = "disabled";
+ };
+
+ ssi1: ssi@02028000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx6sx-ssi", "fsl,imx51-ssi";
+ reg = <0x02028000 0x4000>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_SSI1_IPG>,
+ <&clks IMX6SX_CLK_SSI1>;
+ clock-names = "ipg", "baud";
+ dmas = <&sdma 37 1 0>, <&sdma 38 1 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ ssi2: ssi@0202c000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx6sx-ssi", "fsl,imx51-ssi";
+ reg = <0x0202c000 0x4000>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_SSI2_IPG>,
+ <&clks IMX6SX_CLK_SSI2>;
+ clock-names = "ipg", "baud";
+ dmas = <&sdma 41 1 0>, <&sdma 42 1 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ ssi3: ssi@02030000 {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,imx6sx-ssi", "fsl,imx51-ssi";
+ reg = <0x02030000 0x4000>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_SSI3_IPG>,
+ <&clks IMX6SX_CLK_SSI3>;
+ clock-names = "ipg", "baud";
+ dmas = <&sdma 45 1 0>, <&sdma 46 1 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+ status = "disabled";
+ };
+
+ asrc: asrc@02034000 {
+ reg = <0x02034000 0x4000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_ASRC_MEM>,
+ <&clks IMX6SX_CLK_ASRC_IPG>,
+ <&clks IMX6SX_CLK_SPDIF>,
+ <&clks IMX6SX_CLK_SPBA>;
+ clock-names = "mem", "ipg", "asrck", "dma";
+ dmas = <&sdma 17 20 1>, <&sdma 18 20 1>,
+ <&sdma 19 20 1>, <&sdma 20 20 1>,
+ <&sdma 21 20 1>, <&sdma 22 20 1>;
+ dma-names = "rxa", "rxb", "rxc",
+ "txa", "txb", "txc";
+ status = "okay";
+ };
+ };
+
+ pwm1: pwm@02080000 {
+ compatible = "fsl,imx6sx-pwm", "fsl,imx27-pwm";
+ reg = <0x02080000 0x4000>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_PWM1>,
+ <&clks IMX6SX_CLK_PWM1>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ pwm2: pwm@02084000 {
+ compatible = "fsl,imx6sx-pwm", "fsl,imx27-pwm";
+ reg = <0x02084000 0x4000>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_PWM2>,
+ <&clks IMX6SX_CLK_PWM2>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ pwm3: pwm@02088000 {
+ compatible = "fsl,imx6sx-pwm", "fsl,imx27-pwm";
+ reg = <0x02088000 0x4000>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_PWM3>,
+ <&clks IMX6SX_CLK_PWM3>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ pwm4: pwm@0208c000 {
+ compatible = "fsl,imx6sx-pwm", "fsl,imx27-pwm";
+ reg = <0x0208c000 0x4000>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_PWM4>,
+ <&clks IMX6SX_CLK_PWM4>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ flexcan1: can@02090000 {
+ compatible = "fsl,imx6sx-flexcan", "fsl,imx6q-flexcan";
+ reg = <0x02090000 0x4000>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_CAN1_IPG>,
+ <&clks IMX6SX_CLK_CAN1_SERIAL>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ flexcan2: can@02094000 {
+ compatible = "fsl,imx6sx-flexcan", "fsl,imx6q-flexcan";
+ reg = <0x02094000 0x4000>;
+ interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_CAN2_IPG>,
+ <&clks IMX6SX_CLK_CAN2_SERIAL>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ gpt: gpt@02098000 {
+ compatible = "fsl,imx6sx-gpt", "fsl,imx31-gpt";
+ reg = <0x02098000 0x4000>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_GPT_BUS>,
+ <&clks IMX6SX_CLK_GPT_3M>;
+ clock-names = "ipg", "per";
+ };
+
+ gpio1: gpio@0209c000 {
+ compatible = "fsl,imx6sx-gpio", "fsl,imx35-gpio";
+ reg = <0x0209c000 0x4000>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@020a0000 {
+ compatible = "fsl,imx6sx-gpio", "fsl,imx35-gpio";
+ reg = <0x020a0000 0x4000>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@020a4000 {
+ compatible = "fsl,imx6sx-gpio", "fsl,imx35-gpio";
+ reg = <0x020a4000 0x4000>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@020a8000 {
+ compatible = "fsl,imx6sx-gpio", "fsl,imx35-gpio";
+ reg = <0x020a8000 0x4000>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio5: gpio@020ac000 {
+ compatible = "fsl,imx6sx-gpio", "fsl,imx35-gpio";
+ reg = <0x020ac000 0x4000>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio6: gpio@020b0000 {
+ compatible = "fsl,imx6sx-gpio", "fsl,imx35-gpio";
+ reg = <0x020b0000 0x4000>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio7: gpio@020b4000 {
+ compatible = "fsl,imx6sx-gpio", "fsl,imx35-gpio";
+ reg = <0x020b4000 0x4000>;
+ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ kpp: kpp@020b8000 {
+ compatible = "fsl,imx6sx-kpp", "fsl,imx21-kpp";
+ reg = <0x020b8000 0x4000>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_DUMMY>;
+ status = "disabled";
+ };
+
+ wdog1: wdog@020bc000 {
+ compatible = "fsl,imx6sx-wdt", "fsl,imx21-wdt";
+ reg = <0x020bc000 0x4000>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_DUMMY>;
+ };
+
+ wdog2: wdog@020c0000 {
+ compatible = "fsl,imx6sx-wdt", "fsl,imx21-wdt";
+ reg = <0x020c0000 0x4000>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_DUMMY>;
+ status = "disabled";
+ };
+
+ clks: ccm@020c4000 {
+ compatible = "fsl,imx6sx-ccm";
+ reg = <0x020c4000 0x4000>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+ #clock-cells = <1>;
+ clocks = <&ckil>, <&osc>, <&ipp_di0>, <&ipp_di1>;
+ clock-names = "ckil", "osc", "ipp_di0", "ipp_di1";
+ };
+
+ anatop: anatop@020c8000 {
+ compatible = "fsl,imx6sx-anatop", "fsl,imx6q-anatop",
+ "syscon", "simple-bus";
+ reg = <0x020c8000 0x1000>;
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+
+ regulator-1p1@110 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd1p1";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1375000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x110>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <4>;
+ anatop-min-voltage = <800000>;
+ anatop-max-voltage = <1375000>;
+ };
+
+ regulator-3p0@120 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd3p0";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3150000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x120>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <0>;
+ anatop-min-voltage = <2625000>;
+ anatop-max-voltage = <3400000>;
+ };
+
+ regulator-2p5@130 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd2p5";
+ regulator-min-microvolt = <2100000>;
+ regulator-max-microvolt = <2875000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x130>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <0>;
+ anatop-min-voltage = <2100000>;
+ anatop-max-voltage = <2875000>;
+ };
+
+ reg_arm: regulator-vddcore@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vddarm";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <0>;
+ anatop-vol-bit-width = <5>;
+ anatop-delay-reg-offset = <0x170>;
+ anatop-delay-bit-shift = <24>;
+ anatop-delay-bit-width = <2>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
+
+ reg_pcie: regulator-vddpcie@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vddpcie";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <9>;
+ anatop-vol-bit-width = <5>;
+ anatop-delay-reg-offset = <0x170>;
+ anatop-delay-bit-shift = <26>;
+ anatop-delay-bit-width = <2>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
+
+ reg_soc: regulator-vddsoc@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vddsoc";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <18>;
+ anatop-vol-bit-width = <5>;
+ anatop-delay-reg-offset = <0x170>;
+ anatop-delay-bit-shift = <28>;
+ anatop-delay-bit-width = <2>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
+ };
+
+ tempmon: tempmon {
+ compatible = "fsl,imx6sx-tempmon", "fsl,imx6q-tempmon";
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,tempmon = <&anatop>;
+ fsl,tempmon-data = <&ocotp>;
+ clocks = <&clks IMX6SX_CLK_PLL3_USB_OTG>;
+ };
+
+ usbphy1: usbphy@020c9000 {
+ compatible = "fsl,imx6sx-usbphy", "fsl,imx23-usbphy";
+ reg = <0x020c9000 0x1000>;
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_USBPHY1>;
+ fsl,anatop = <&anatop>;
+ };
+
+ usbphy2: usbphy@020ca000 {
+ compatible = "fsl,imx6sx-usbphy", "fsl,imx23-usbphy";
+ reg = <0x020ca000 0x1000>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_USBPHY2>;
+ fsl,anatop = <&anatop>;
+ };
+
+ snvs: snvs@020cc000 {
+ compatible = "fsl,sec-v4.0-mon", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x020cc000 0x4000>;
+
+ snvs_rtc: snvs-rtc-lp@34 {
+ compatible = "fsl,sec-v4.0-mon-rtc-lp";
+ reg = <0x34 0x58>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ snvs_poweroff: snvs-poweroff@38 {
+ compatible = "fsl,sec-v4.0-poweroff";
+ reg = <0x38 0x4>;
+ status = "disabled";
+ };
+ };
+
+ epit1: epit@020d0000 {
+ reg = <0x020d0000 0x4000>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ epit2: epit@020d4000 {
+ reg = <0x020d4000 0x4000>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ src: src@020d8000 {
+ compatible = "fsl,imx6sx-src", "fsl,imx51-src";
+ reg = <0x020d8000 0x4000>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ #reset-cells = <1>;
+ };
+
+ gpc: gpc@020dc000 {
+ compatible = "fsl,imx6sx-gpc", "fsl,imx6q-gpc";
+ reg = <0x020dc000 0x4000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&intc>;
+ };
+
+ iomuxc: iomuxc@020e0000 {
+ compatible = "fsl,imx6sx-iomuxc";
+ reg = <0x020e0000 0x4000>;
+ };
+
+ gpr: iomuxc-gpr@020e4000 {
+ compatible = "fsl,imx6sx-iomuxc-gpr",
+ "fsl,imx6q-iomuxc-gpr", "syscon";
+ reg = <0x020e4000 0x4000>;
+ };
+
+ sdma: sdma@020ec000 {
+ compatible = "fsl,imx6sx-sdma", "fsl,imx6q-sdma";
+ reg = <0x020ec000 0x4000>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_SDMA>,
+ <&clks IMX6SX_CLK_SDMA>;
+ clock-names = "ipg", "ahb";
+ #dma-cells = <3>;
+ /* imx6sx reuses imx6q sdma firmware */
+ fsl,sdma-ram-script-name = "/*(DEBLOBBED)*/";
+ };
+ };
+
+ aips2: aips-bus@02100000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02100000 0x100000>;
+ ranges;
+
+ usbotg1: usb@02184000 {
+ compatible = "fsl,imx6sx-usb", "fsl,imx27-usb";
+ reg = <0x02184000 0x200>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_USBOH3>;
+ fsl,usbphy = <&usbphy1>;
+ fsl,usbmisc = <&usbmisc 0>;
+ fsl,anatop = <&anatop>;
+ status = "disabled";
+ };
+
+ usbotg2: usb@02184200 {
+ compatible = "fsl,imx6sx-usb", "fsl,imx27-usb";
+ reg = <0x02184200 0x200>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_USBOH3>;
+ fsl,usbphy = <&usbphy2>;
+ fsl,usbmisc = <&usbmisc 1>;
+ status = "disabled";
+ };
+
+ usbh: usb@02184400 {
+ compatible = "fsl,imx6sx-usb", "fsl,imx27-usb";
+ reg = <0x02184400 0x200>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_USBOH3>;
+ fsl,usbmisc = <&usbmisc 2>;
+ phy_type = "hsic";
+ fsl,anatop = <&anatop>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbmisc: usbmisc@02184800 {
+ #index-cells = <1>;
+ compatible = "fsl,imx6sx-usbmisc", "fsl,imx6q-usbmisc";
+ reg = <0x02184800 0x200>;
+ clocks = <&clks IMX6SX_CLK_USBOH3>;
+ };
+
+ fec1: ethernet@02188000 {
+ compatible = "fsl,imx6sx-fec", "fsl,imx6q-fec";
+ reg = <0x02188000 0x4000>;
+ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_ENET>,
+ <&clks IMX6SX_CLK_ENET_AHB>,
+ <&clks IMX6SX_CLK_ENET_PTP>,
+ <&clks IMX6SX_CLK_ENET_REF>,
+ <&clks IMX6SX_CLK_ENET_PTP>;
+ clock-names = "ipg", "ahb", "ptp",
+ "enet_clk_ref", "enet_out";
+ fsl,num-tx-queues=<3>;
+ fsl,num-rx-queues=<3>;
+ status = "disabled";
+ };
+
+ mlb: mlb@0218c000 {
+ reg = <0x0218c000 0x4000>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_MLB>;
+ status = "disabled";
+ };
+
+ usdhc1: usdhc@02190000 {
+ compatible = "fsl,imx6sx-usdhc", "fsl,imx6sl-usdhc";
+ reg = <0x02190000 0x4000>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_USDHC1>,
+ <&clks IMX6SX_CLK_USDHC1>,
+ <&clks IMX6SX_CLK_USDHC1>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ usdhc2: usdhc@02194000 {
+ compatible = "fsl,imx6sx-usdhc", "fsl,imx6sl-usdhc";
+ reg = <0x02194000 0x4000>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_USDHC2>,
+ <&clks IMX6SX_CLK_USDHC2>,
+ <&clks IMX6SX_CLK_USDHC2>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ usdhc3: usdhc@02198000 {
+ compatible = "fsl,imx6sx-usdhc", "fsl,imx6sl-usdhc";
+ reg = <0x02198000 0x4000>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_USDHC3>,
+ <&clks IMX6SX_CLK_USDHC3>,
+ <&clks IMX6SX_CLK_USDHC3>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ usdhc4: usdhc@0219c000 {
+ compatible = "fsl,imx6sx-usdhc", "fsl,imx6sl-usdhc";
+ reg = <0x0219c000 0x4000>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_USDHC4>,
+ <&clks IMX6SX_CLK_USDHC4>,
+ <&clks IMX6SX_CLK_USDHC4>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@021a0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sx-i2c", "fsl,imx21-i2c";
+ reg = <0x021a0000 0x4000>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_I2C1>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@021a4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sx-i2c", "fsl,imx21-i2c";
+ reg = <0x021a4000 0x4000>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_I2C2>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@021a8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sx-i2c", "fsl,imx21-i2c";
+ reg = <0x021a8000 0x4000>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_I2C3>;
+ status = "disabled";
+ };
+
+ mmdc: mmdc@021b0000 {
+ compatible = "fsl,imx6sx-mmdc", "fsl,imx6q-mmdc";
+ reg = <0x021b0000 0x4000>;
+ };
+
+ fec2: ethernet@021b4000 {
+ compatible = "fsl,imx6sx-fec", "fsl,imx6q-fec";
+ reg = <0x021b4000 0x4000>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_ENET>,
+ <&clks IMX6SX_CLK_ENET_AHB>,
+ <&clks IMX6SX_CLK_ENET_PTP>,
+ <&clks IMX6SX_CLK_ENET2_REF_125M>,
+ <&clks IMX6SX_CLK_ENET_PTP>;
+ clock-names = "ipg", "ahb", "ptp",
+ "enet_clk_ref", "enet_out";
+ status = "disabled";
+ };
+
+ weim: weim@021b8000 {
+ compatible = "fsl,imx6sx-weim", "fsl,imx6q-weim";
+ reg = <0x021b8000 0x4000>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_EIM_SLOW>;
+ };
+
+ ocotp: ocotp@021bc000 {
+ compatible = "fsl,imx6sx-ocotp", "syscon";
+ reg = <0x021bc000 0x4000>;
+ clocks = <&clks IMX6SX_CLK_OCOTP>;
+ };
+
+ sai1: sai@021d4000 {
+ compatible = "fsl,imx6sx-sai";
+ reg = <0x021d4000 0x4000>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_SAI1_IPG>,
+ <&clks IMX6SX_CLK_SAI1>,
+ <&clks 0>, <&clks 0>;
+ clock-names = "bus", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx", "tx";
+ dmas = <&sdma 31 23 0>, <&sdma 32 23 0>;
+ dma-source = <&gpr 0 15 0 16>;
+ status = "disabled";
+ };
+
+ audmux: audmux@021d8000 {
+ compatible = "fsl,imx6sx-audmux", "fsl,imx31-audmux";
+ reg = <0x021d8000 0x4000>;
+ status = "disabled";
+ };
+
+ sai2: sai@021dc000 {
+ compatible = "fsl,imx6sx-sai";
+ reg = <0x021dc000 0x4000>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_SAI2_IPG>,
+ <&clks IMX6SX_CLK_SAI2>,
+ <&clks 0>, <&clks 0>;
+ clock-names = "bus", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx", "tx";
+ dmas = <&sdma 33 23 0>, <&sdma 34 23 0>;
+ dma-source = <&gpr 0 17 0 18>;
+ status = "disabled";
+ };
+
+ qspi1: qspi@021e0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sx-qspi";
+ reg = <0x021e0000 0x4000>, <0x60000000 0x10000000>;
+ reg-names = "QuadSPI", "QuadSPI-memory";
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_QSPI1>,
+ <&clks IMX6SX_CLK_QSPI1>;
+ clock-names = "qspi_en", "qspi";
+ status = "disabled";
+ };
+
+ qspi2: qspi@021e4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sx-qspi";
+ reg = <0x021e4000 0x4000>, <0x70000000 0x10000000>;
+ reg-names = "QuadSPI", "QuadSPI-memory";
+ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_QSPI2>,
+ <&clks IMX6SX_CLK_QSPI2>;
+ clock-names = "qspi_en", "qspi";
+ status = "disabled";
+ };
+
+ uart2: serial@021e8000 {
+ compatible = "fsl,imx6sx-uart", "fsl,imx21-uart";
+ reg = <0x021e8000 0x4000>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_UART_IPG>,
+ <&clks IMX6SX_CLK_UART_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 27 4 0>, <&sdma 28 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart3: serial@021ec000 {
+ compatible = "fsl,imx6sx-uart", "fsl,imx21-uart";
+ reg = <0x021ec000 0x4000>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_UART_IPG>,
+ <&clks IMX6SX_CLK_UART_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 29 4 0>, <&sdma 30 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart4: serial@021f0000 {
+ compatible = "fsl,imx6sx-uart", "fsl,imx21-uart";
+ reg = <0x021f0000 0x4000>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_UART_IPG>,
+ <&clks IMX6SX_CLK_UART_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 31 4 0>, <&sdma 32 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart5: serial@021f4000 {
+ compatible = "fsl,imx6sx-uart", "fsl,imx21-uart";
+ reg = <0x021f4000 0x4000>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_UART_IPG>,
+ <&clks IMX6SX_CLK_UART_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 33 4 0>, <&sdma 34 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c4: i2c@021f8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sx-i2c", "fsl,imx21-i2c";
+ reg = <0x021f8000 0x4000>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_I2C4>;
+ status = "disabled";
+ };
+ };
+
+ aips3: aips-bus@02200000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02200000 0x100000>;
+ ranges;
+
+ spba-bus@02200000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02240000 0x40000>;
+ ranges;
+
+ csi1: csi@02214000 {
+ reg = <0x02214000 0x4000>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_DISPLAY_AXI>,
+ <&clks IMX6SX_CLK_CSI>,
+ <&clks IMX6SX_CLK_DCIC1>;
+ clock-names = "disp-axi", "csi_mclk", "dcic";
+ status = "disabled";
+ };
+
+ pxp: pxp@02218000 {
+ reg = <0x02218000 0x4000>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_PXP_AXI>,
+ <&clks IMX6SX_CLK_DISPLAY_AXI>;
+ clock-names = "pxp-axi", "disp-axi";
+ status = "disabled";
+ };
+
+ csi2: csi@0221c000 {
+ reg = <0x0221c000 0x4000>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_DISPLAY_AXI>,
+ <&clks IMX6SX_CLK_CSI>,
+ <&clks IMX6SX_CLK_DCIC2>;
+ clock-names = "disp-axi", "csi_mclk", "dcic";
+ status = "disabled";
+ };
+
+ lcdif1: lcdif@02220000 {
+ compatible = "fsl,imx6sx-lcdif", "fsl,imx28-lcdif";
+ reg = <0x02220000 0x4000>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_LCDIF1_PIX>,
+ <&clks IMX6SX_CLK_LCDIF_APB>,
+ <&clks IMX6SX_CLK_DISPLAY_AXI>;
+ clock-names = "pix", "axi", "disp_axi";
+ status = "disabled";
+ };
+
+ lcdif2: lcdif@02224000 {
+ compatible = "fsl,imx6sx-lcdif", "fsl,imx28-lcdif";
+ reg = <0x02224000 0x4000>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_LCDIF2_PIX>,
+ <&clks IMX6SX_CLK_LCDIF_APB>,
+ <&clks IMX6SX_CLK_DISPLAY_AXI>;
+ clock-names = "pix", "axi", "disp_axi";
+ status = "disabled";
+ };
+
+ vadc: vadc@02228000 {
+ reg = <0x02228000 0x4000>, <0x0222c000 0x4000>;
+ reg-names = "vadc-vafe", "vadc-vdec";
+ clocks = <&clks IMX6SX_CLK_VADC>,
+ <&clks IMX6SX_CLK_CSI>;
+ clock-names = "vadc", "csi";
+ status = "disabled";
+ };
+ };
+
+ adc1: adc@02280000 {
+ compatible = "fsl,imx6sx-adc", "fsl,vf610-adc";
+ reg = <0x02280000 0x4000>;
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_IPG>;
+ clock-names = "adc";
+ status = "disabled";
+ };
+
+ adc2: adc@02284000 {
+ compatible = "fsl,imx6sx-adc", "fsl,vf610-adc";
+ reg = <0x02284000 0x4000>;
+ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_IPG>;
+ clock-names = "adc";
+ status = "disabled";
+ };
+
+ wdog3: wdog@02288000 {
+ compatible = "fsl,imx6sx-wdt", "fsl,imx21-wdt";
+ reg = <0x02288000 0x4000>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_DUMMY>;
+ status = "disabled";
+ };
+
+ ecspi5: ecspi@0228c000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6sx-ecspi", "fsl,imx51-ecspi";
+ reg = <0x0228c000 0x4000>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_ECSPI5>,
+ <&clks IMX6SX_CLK_ECSPI5>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart6: serial@022a0000 {
+ compatible = "fsl,imx6sx-uart", "fsl,imx21-uart";
+ reg = <0x022a0000 0x4000>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_UART_IPG>,
+ <&clks IMX6SX_CLK_UART_SERIAL>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma 0 4 0>, <&sdma 47 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ pwm5: pwm@022a4000 {
+ compatible = "fsl,imx6sx-pwm", "fsl,imx27-pwm";
+ reg = <0x022a4000 0x4000>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_PWM5>,
+ <&clks IMX6SX_CLK_PWM5>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ pwm6: pwm@022a8000 {
+ compatible = "fsl,imx6sx-pwm", "fsl,imx27-pwm";
+ reg = <0x022a8000 0x4000>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_PWM6>,
+ <&clks IMX6SX_CLK_PWM6>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ pwm7: pwm@022ac000 {
+ compatible = "fsl,imx6sx-pwm", "fsl,imx27-pwm";
+ reg = <0x022ac000 0x4000>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_PWM7>,
+ <&clks IMX6SX_CLK_PWM7>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+
+ pwm8: pwm@0022b0000 {
+ compatible = "fsl,imx6sx-pwm", "fsl,imx27-pwm";
+ reg = <0x0022b0000 0x4000>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_PWM8>,
+ <&clks IMX6SX_CLK_PWM8>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ };
+ };
+
+ pcie: pcie@0x08000000 {
+ compatible = "fsl,imx6sx-pcie", "snps,dw-pcie";
+ reg = <0x08ffc000 0x4000>; /* DBI */
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ /* configuration space */
+ ranges = <0x00000800 0 0x08f00000 0x08f00000 0 0x00080000
+ /* downstream I/O */
+ 0x81000000 0 0 0x08f80000 0 0x00010000
+ /* non-prefetchable memory */
+ 0x82000000 0 0x08000000 0x08000000 0 0x00f00000>;
+ num-lanes = <1>;
+ interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SX_CLK_PCIE_REF_125M>,
+ <&clks IMX6SX_CLK_PCIE_AXI>,
+ <&clks IMX6SX_CLK_LVDS1_OUT>,
+ <&clks IMX6SX_CLK_DISPLAY_AXI>;
+ clock-names = "pcie_ref_125m", "pcie_axi",
+ "lvds_gate", "display_axi";
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/include/dt-bindings b/arch/arm/boot/dts/include/dt-bindings
new file mode 120000
index 000000000..08c00e497
--- /dev/null
+++ b/arch/arm/boot/dts/include/dt-bindings
@@ -0,0 +1 @@
+../../../../../include/dt-bindings \ No newline at end of file
diff --git a/arch/arm/boot/dts/integrator.dtsi b/arch/arm/boot/dts/integrator.dtsi
new file mode 100644
index 000000000..28e38f8c6
--- /dev/null
+++ b/arch/arm/boot/dts/integrator.dtsi
@@ -0,0 +1,132 @@
+/*
+ * SoC core Device Tree for the ARM Integrator platforms
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ core-module@10000000 {
+ compatible = "arm,core-module-integrator", "syscon";
+ reg = <0x10000000 0x200>;
+
+ /* Use core module LED to indicate CPU load */
+ led@0c.0 {
+ compatible = "register-bit-led";
+ offset = <0x0c>;
+ mask = <0x01>;
+ label = "integrator:core_module";
+ linux,default-trigger = "cpu0";
+ default-state = "on";
+ };
+ };
+
+ ebi@12000000 {
+ compatible = "arm,external-bus-interface";
+ reg = <0x12000000 0x100>;
+ };
+
+ timer@13000000 {
+ reg = <0x13000000 0x100>;
+ interrupt-parent = <&pic>;
+ interrupts = <5>;
+ };
+
+ timer@13000100 {
+ reg = <0x13000100 0x100>;
+ interrupt-parent = <&pic>;
+ interrupts = <6>;
+ };
+
+ timer@13000200 {
+ reg = <0x13000200 0x100>;
+ interrupt-parent = <&pic>;
+ interrupts = <7>;
+ };
+
+ pic@14000000 {
+ compatible = "arm,versatile-fpga-irq";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ reg = <0x14000000 0x100>;
+ clear-mask = <0xffffffff>;
+ };
+
+ flash@24000000 {
+ compatible = "cfi-flash";
+ reg = <0x24000000 0x02000000>;
+ };
+
+ fpga {
+ compatible = "arm,amba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ interrupt-parent = <&pic>;
+
+ /*
+ * These PrimeCells are in the same locations and using the
+ * same interrupts in all Integrators, however the silicon
+ * version deployed is different.
+ */
+ rtc@15000000 {
+ reg = <0x15000000 0x1000>;
+ interrupts = <8>;
+ };
+
+ uart@16000000 {
+ reg = <0x16000000 0x1000>;
+ interrupts = <1>;
+ };
+
+ uart@17000000 {
+ reg = <0x17000000 0x1000>;
+ interrupts = <2>;
+ };
+
+ kmi@18000000 {
+ reg = <0x18000000 0x1000>;
+ interrupts = <3>;
+ };
+
+ kmi@19000000 {
+ reg = <0x19000000 0x1000>;
+ interrupts = <4>;
+ };
+
+ syscon {
+ /* Debug registers mapped as syscon */
+ compatible = "syscon";
+ reg = <0x1a000000 0x10>;
+
+ led@04.0 {
+ compatible = "register-bit-led";
+ offset = <0x04>;
+ mask = <0x01>;
+ label = "integrator:green0";
+ linux,default-trigger = "heartbeat";
+ default-state = "on";
+ };
+ led@04.1 {
+ compatible = "register-bit-led";
+ offset = <0x04>;
+ mask = <0x02>;
+ label = "integrator:yellow";
+ default-state = "off";
+ };
+ led@04.2 {
+ compatible = "register-bit-led";
+ offset = <0x04>;
+ mask = <0x04>;
+ label = "integrator:red";
+ default-state = "off";
+ };
+ led@04.3 {
+ compatible = "register-bit-led";
+ offset = <0x04>;
+ mask = <0x08>;
+ label = "integrator:green1";
+ default-state = "off";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts
new file mode 100644
index 000000000..cf06e32ee
--- /dev/null
+++ b/arch/arm/boot/dts/integratorap.dts
@@ -0,0 +1,153 @@
+/*
+ * Device Tree for the ARM Integrator/AP platform
+ */
+
+/dts-v1/;
+/include/ "integrator.dtsi"
+
+/ {
+ model = "ARM Integrator/AP";
+ compatible = "arm,integrator-ap";
+ dma-ranges = <0x80000000 0x0 0x80000000>;
+
+ aliases {
+ arm,timer-primary = &timer2;
+ arm,timer-secondary = &timer1;
+ };
+
+ chosen {
+ bootargs = "root=/dev/ram0 console=ttyAM0,38400n8 earlyprintk";
+ };
+
+ /* 24 MHz chrystal on the core module */
+ xtal24mhz: xtal24mhz@24M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ pclk: pclk@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <1>;
+ clock-mult = <1>;
+ clocks = <&xtal24mhz>;
+ };
+
+ /* The UART clock is 14.74 MHz divided by an ICS525 */
+ uartclk: uartclk@14.74M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <14745600>;
+ };
+
+ syscon {
+ compatible = "arm,integrator-ap-syscon";
+ reg = <0x11000000 0x100>;
+ interrupt-parent = <&pic>;
+ /* These are the logical module IRQs */
+ interrupts = <9>, <10>, <11>, <12>;
+ };
+
+ timer0: timer@13000000 {
+ compatible = "arm,integrator-timer";
+ clocks = <&xtal24mhz>;
+ };
+
+ timer1: timer@13000100 {
+ compatible = "arm,integrator-timer";
+ clocks = <&xtal24mhz>;
+ };
+
+ timer2: timer@13000200 {
+ compatible = "arm,integrator-timer";
+ clocks = <&xtal24mhz>;
+ };
+
+ pic: pic@14000000 {
+ valid-mask = <0x003fffff>;
+ };
+
+ pci: pciv3@62000000 {
+ compatible = "v3,v360epc-pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0x62000000 0x10000>;
+ interrupt-parent = <&pic>;
+ interrupts = <17>; /* Bus error IRQ */
+ ranges = <0x00000000 0 0x61000000 /* config space */
+ 0x61000000 0 0x00100000 /* 16 MiB @ 61000000 */
+ 0x01000000 0 0x0 /* I/O space */
+ 0x60000000 0 0x00100000 /* 16 MiB @ 60000000 */
+ 0x02000000 0 0x00000000 /* non-prefectable memory */
+ 0x40000000 0 0x10000000 /* 256 MiB @ 40000000 */
+ 0x42000000 0 0x10000000 /* prefetchable memory */
+ 0x50000000 0 0x10000000>; /* 256 MiB @ 50000000 */
+ interrupt-map-mask = <0xf800 0 0 0x7>;
+ interrupt-map = <
+ /* IDSEL 9 */
+ 0x4800 0 0 1 &pic 13 /* INT A on slot 9 is irq 13 */
+ 0x4800 0 0 2 &pic 14 /* INT B on slot 9 is irq 14 */
+ 0x4800 0 0 3 &pic 15 /* INT C on slot 9 is irq 15 */
+ 0x4800 0 0 4 &pic 16 /* INT D on slot 9 is irq 16 */
+ /* IDSEL 10 */
+ 0x5000 0 0 1 &pic 14 /* INT A on slot 10 is irq 14 */
+ 0x5000 0 0 2 &pic 15 /* INT B on slot 10 is irq 15 */
+ 0x5000 0 0 3 &pic 16 /* INT C on slot 10 is irq 16 */
+ 0x5000 0 0 4 &pic 13 /* INT D on slot 10 is irq 13 */
+ /* IDSEL 11 */
+ 0x5800 0 0 1 &pic 15 /* INT A on slot 11 is irq 15 */
+ 0x5800 0 0 2 &pic 16 /* INT B on slot 11 is irq 16 */
+ 0x5800 0 0 3 &pic 13 /* INT C on slot 11 is irq 13 */
+ 0x5800 0 0 4 &pic 14 /* INT D on slot 11 is irq 14 */
+ /* IDSEL 12 */
+ 0x6000 0 0 1 &pic 16 /* INT A on slot 12 is irq 16 */
+ 0x6000 0 0 2 &pic 13 /* INT B on slot 12 is irq 13 */
+ 0x6000 0 0 3 &pic 14 /* INT C on slot 12 is irq 14 */
+ 0x6000 0 0 4 &pic 15 /* INT D on slot 12 is irq 15 */
+ >;
+ };
+
+ fpga {
+ /*
+ * The Integator/AP predates the idea to have magic numbers
+ * identifying the PrimeCell in hardware, thus we have to
+ * supply these from the device tree.
+ */
+ rtc: rtc@15000000 {
+ compatible = "arm,pl030", "arm,primecell";
+ arm,primecell-periphid = <0x00041030>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ uart0: uart@16000000 {
+ compatible = "arm,pl010", "arm,primecell";
+ arm,primecell-periphid = <0x00041010>;
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ uart1: uart@17000000 {
+ compatible = "arm,pl010", "arm,primecell";
+ arm,primecell-periphid = <0x00041010>;
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ kmi0: kmi@18000000 {
+ compatible = "arm,pl050", "arm,primecell";
+ arm,primecell-periphid = <0x00041050>;
+ clocks = <&xtal24mhz>, <&pclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+
+ kmi1: kmi@19000000 {
+ compatible = "arm,pl050", "arm,primecell";
+ arm,primecell-periphid = <0x00041050>;
+ clocks = <&xtal24mhz>, <&pclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts
new file mode 100644
index 000000000..d43f15b4f
--- /dev/null
+++ b/arch/arm/boot/dts/integratorcp.dts
@@ -0,0 +1,215 @@
+/*
+ * Device Tree for the ARM Integrator/CP platform
+ */
+
+/dts-v1/;
+/include/ "integrator.dtsi"
+
+/ {
+ model = "ARM Integrator/CP";
+ compatible = "arm,integrator-cp";
+
+ chosen {
+ bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk";
+ };
+
+ /*
+ * The Integrator/CP overall clocking architecture can be found in
+ * ARM DUI 0184B page 7-28 "Integrator/CP922T system clocks" which
+ * appear to illustrate the layout used in most configurations.
+ */
+
+ /* The codec chrystal operates at 24.576 MHz */
+ xtal_codec: xtal24.576@24.576M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24576000>;
+ };
+
+ /* The chrystal is divided by 2 by the codec for the AACI bit clock */
+ aaci_bitclk: aaci_bitclk@12.288M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <2>;
+ clock-mult = <1>;
+ clocks = <&xtal_codec>;
+ };
+
+ /* This is a 25MHz chrystal on the base board */
+ xtal25mhz: xtal25mhz@25M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <25000000>;
+ };
+
+ /* The UART clock is 14.74 MHz divided from 25MHz by an ICS525 */
+ uartclk: uartclk@14.74M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <14745600>;
+ };
+
+ /* Actually sysclk I think */
+ pclk: pclk@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ core-module@10000000 {
+ /* 24 MHz chrystal on the core module */
+ xtal24mhz: xtal24mhz@24M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ /*
+ * External oscillator on the core module, usually used
+ * to drive video circuitry. Driven from the 24MHz clock.
+ */
+ auxosc: cm_aux_osc@25M {
+ #clock-cells = <0>;
+ compatible = "arm,integrator-cm-auxosc";
+ clocks = <&xtal24mhz>;
+ };
+
+ /* The KMI clock is the 24 MHz oscillator divided to 8MHz */
+ kmiclk: kmiclk@1M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <3>;
+ clock-mult = <1>;
+ clocks = <&xtal24mhz>;
+ };
+
+ /* The timer clock is the 24 MHz oscillator divided to 1MHz */
+ timclk: timclk@1M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <24>;
+ clock-mult = <1>;
+ clocks = <&xtal24mhz>;
+ };
+ };
+
+ syscon {
+ compatible = "arm,integrator-cp-syscon";
+ reg = <0xcb000000 0x100>;
+ };
+
+ timer0: timer@13000000 {
+ /* TIMER0 runs directly on the 25MHz chrystal */
+ compatible = "arm,integrator-cp-timer";
+ clocks = <&xtal25mhz>;
+ };
+
+ timer1: timer@13000100 {
+ /* TIMER1 runs @ 1MHz */
+ compatible = "arm,integrator-cp-timer";
+ clocks = <&timclk>;
+ };
+
+ timer2: timer@13000200 {
+ /* TIMER2 runs @ 1MHz */
+ compatible = "arm,integrator-cp-timer";
+ clocks = <&timclk>;
+ };
+
+ pic: pic@14000000 {
+ valid-mask = <0x1fc003ff>;
+ };
+
+ cic: cic@10000040 {
+ compatible = "arm,versatile-fpga-irq";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ reg = <0x10000040 0x100>;
+ clear-mask = <0xffffffff>;
+ valid-mask = <0x00000007>;
+ };
+
+ /* The SIC is cascaded off IRQ 26 on the PIC */
+ sic: sic@ca000000 {
+ compatible = "arm,versatile-fpga-irq";
+ interrupt-parent = <&pic>;
+ interrupts = <26>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ reg = <0xca000000 0x100>;
+ clear-mask = <0x00000fff>;
+ valid-mask = <0x00000fff>;
+ };
+
+ ethernet@c8000000 {
+ compatible = "smsc,lan91c111";
+ reg = <0xc8000000 0x10>;
+ interrupt-parent = <&pic>;
+ interrupts = <27>;
+ };
+
+ fpga {
+ /*
+ * These PrimeCells are at the same location and using
+ * the same interrupts in all Integrators, but in the CP
+ * slightly newer versions are deployed.
+ */
+ rtc@15000000 {
+ compatible = "arm,pl031", "arm,primecell";
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ uart@16000000 {
+ compatible = "arm,pl011", "arm,primecell";
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ uart@17000000 {
+ compatible = "arm,pl011", "arm,primecell";
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ kmi@18000000 {
+ compatible = "arm,pl050", "arm,primecell";
+ clocks = <&kmiclk>, <&pclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+
+ kmi@19000000 {
+ compatible = "arm,pl050", "arm,primecell";
+ clocks = <&kmiclk>, <&pclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+
+ /*
+ * These PrimeCells are only available on the Integrator/CP
+ */
+ mmc@1c000000 {
+ compatible = "arm,pl180", "arm,primecell";
+ reg = <0x1c000000 0x1000>;
+ interrupts = <23 24>;
+ max-frequency = <515633>;
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "mclk", "apb_pclk";
+ };
+
+ aaci@1d000000 {
+ compatible = "arm,pl041", "arm,primecell";
+ reg = <0x1d000000 0x1000>;
+ interrupts = <25>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ clcd@c0000000 {
+ compatible = "arm,pl110", "arm,primecell";
+ reg = <0xC0000000 0x1000>;
+ interrupts = <22>;
+ clocks = <&auxosc>, <&pclk>;
+ clock-names = "clcd", "apb_pclk";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/k2e-clocks.dtsi b/arch/arm/boot/dts/k2e-clocks.dtsi
new file mode 100644
index 000000000..4773d6af6
--- /dev/null
+++ b/arch/arm/boot/dts/k2e-clocks.dtsi
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Edison SoC specific device tree
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+clocks {
+ mainpllclk: mainpllclk@2310110 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,main-pll-clock";
+ clocks = <&refclksys>;
+ reg = <0x02620350 4>, <0x02310110 4>;
+ reg-names = "control", "multiplier";
+ fixed-postdiv = <2>;
+ };
+
+ papllclk: papllclk@2620358 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclkpass>;
+ clock-output-names = "papllclk";
+ reg = <0x02620358 4>;
+ reg-names = "control";
+ };
+
+ ddr3apllclk: ddr3apllclk@2620360 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclkddr3a>;
+ clock-output-names = "ddr-3a-pll-clk";
+ reg = <0x02620360 4>;
+ reg-names = "control";
+ };
+
+ clkusb1: clkusb1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk16>;
+ clock-output-names = "usb1";
+ reg = <0x02350004 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clkhyperlink0: clkhyperlink0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk12>;
+ clock-output-names = "hyperlink-0";
+ reg = <0x02350030 0xb00>, <0x02350014 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <5>;
+ };
+
+ clkpcie1: clkpcie1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk12>;
+ clock-output-names = "pcie1";
+ reg = <0x0235006c 0xb00>, <0x02350048 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <18>;
+ };
+
+ clkxge: clkxge {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "xge";
+ reg = <0x023500c8 0xb00>, <0x02350074 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <29>;
+ };
+};
diff --git a/arch/arm/boot/dts/k2e-evm.dts b/arch/arm/boot/dts/k2e-evm.dts
new file mode 100644
index 000000000..560d62150
--- /dev/null
+++ b/arch/arm/boot/dts/k2e-evm.dts
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2013-2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Edison EVM device tree
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "keystone.dtsi"
+#include "k2e.dtsi"
+
+/ {
+ compatible = "ti,k2e-evm","ti,keystone";
+ model = "Texas Instruments Keystone 2 Edison EVM";
+
+ soc {
+
+ clocks {
+ refclksys: refclksys {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <100000000>;
+ clock-output-names = "refclk-sys";
+ };
+
+ refclkpass: refclkpass {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <100000000>;
+ clock-output-names = "refclk-pass";
+ };
+
+ refclkddr3a: refclkddr3a {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <100000000>;
+ clock-output-names = "refclk-ddr3a";
+ };
+ };
+ };
+};
+
+&usb_phy {
+ status = "okay";
+};
+
+&usb {
+ status = "okay";
+};
+
+&usb1_phy {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+};
+
+&i2c0 {
+ dtt@50 {
+ compatible = "at,24c1024";
+ reg = <0x50>;
+ };
+};
+
+&aemif {
+ cs0 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clock-ranges;
+ ranges;
+
+ ti,cs-chipselect = <0>;
+ /* all timings in nanoseconds */
+ ti,cs-min-turnaround-ns = <12>;
+ ti,cs-read-hold-ns = <6>;
+ ti,cs-read-strobe-ns = <23>;
+ ti,cs-read-setup-ns = <9>;
+ ti,cs-write-hold-ns = <8>;
+ ti,cs-write-strobe-ns = <23>;
+ ti,cs-write-setup-ns = <8>;
+
+ nand@0,0 {
+ compatible = "ti,keystone-nand","ti,davinci-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0 0x4000000
+ 1 0 0x0000100>;
+
+ ti,davinci-chipselect = <0>;
+ ti,davinci-mask-ale = <0x2000>;
+ ti,davinci-mask-cle = <0x4000>;
+ ti,davinci-mask-chipsel = <0>;
+ nand-ecc-mode = "hw";
+ ti,davinci-ecc-bits = <4>;
+ nand-on-flash-bbt;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "params";
+ reg = <0x100000 0x80000>;
+ read-only;
+ };
+
+ partition@180000 {
+ label = "ubifs";
+ reg = <0x180000 0x1FE80000>;
+ };
+ };
+ };
+};
+
+&spi0 {
+ nor_flash: n25q128a11@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "Micron,n25q128a11";
+ spi-max-frequency = <54000000>;
+ m25p,fast-read;
+ reg = <0>;
+
+ partition@0 {
+ label = "u-boot-spl";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@1 {
+ label = "misc";
+ reg = <0x80000 0xf80000>;
+ };
+ };
+};
+
+&mdio {
+ ethphy0: ethernet-phy@0 {
+ compatible = "marvell,88E1514", "marvell,88E1510", "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "marvell,88E1514", "marvell,88E1510", "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+};
diff --git a/arch/arm/boot/dts/k2e.dtsi b/arch/arm/boot/dts/k2e.dtsi
new file mode 100644
index 000000000..5fc14683d
--- /dev/null
+++ b/arch/arm/boot/dts/k2e.dtsi
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2013-2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Edison soc device tree
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ interrupt-parent = <&gic>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <1>;
+ };
+
+ cpu@2 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <2>;
+ };
+
+ cpu@3 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <3>;
+ };
+ };
+
+ soc {
+ /include/ "k2e-clocks.dtsi"
+
+ usb: usb@2680000 {
+ interrupts = <GIC_SPI 152 IRQ_TYPE_EDGE_RISING>;
+ dwc3@2690000 {
+ interrupts = <GIC_SPI 152 IRQ_TYPE_EDGE_RISING>;
+ };
+ };
+
+ usb1_phy: usb_phy@2620750 {
+ compatible = "ti,keystone-usbphy";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x2620750 24>;
+ status = "disabled";
+ };
+
+ usb1: usb@25000000 {
+ compatible = "ti,keystone-dwc3";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x25000000 0x10000>;
+ clocks = <&clkusb1>;
+ clock-names = "usb";
+ interrupts = <GIC_SPI 414 IRQ_TYPE_EDGE_RISING>;
+ ranges;
+ dma-coherent;
+ dma-ranges;
+ status = "disabled";
+
+ dwc3@25010000 {
+ compatible = "synopsys,dwc3";
+ reg = <0x25010000 0x70000>;
+ interrupts = <GIC_SPI 414 IRQ_TYPE_EDGE_RISING>;
+ usb-phy = <&usb1_phy>, <&usb1_phy>;
+ };
+ };
+
+ dspgpio0: keystone_dsp_gpio@02620240 {
+ compatible = "ti,keystone-dsp-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio,syscon-dev = <&devctrl 0x240>;
+ };
+
+ pcie@21020000 {
+ compatible = "ti,keystone-pcie","snps,dw-pcie";
+ clocks = <&clkpcie1>;
+ clock-names = "pcie";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ reg = <0x21021000 0x2000>, <0x21020000 0x1000>, <0x02620128 4>;
+ ranges = <0x81000000 0 0 0x23260000 0x4000 0x4000
+ 0x82000000 0 0x60000000 0x60000000 0 0x10000000>;
+
+ device_type = "pci";
+ num-lanes = <2>;
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie_intc1 0>, /* INT A */
+ <0 0 0 2 &pcie_intc1 1>, /* INT B */
+ <0 0 0 3 &pcie_intc1 2>, /* INT C */
+ <0 0 0 4 &pcie_intc1 3>; /* INT D */
+
+ pcie_msi_intc1: msi-interrupt-controller {
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 377 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 378 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 379 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 380 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 381 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 382 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 383 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 384 IRQ_TYPE_EDGE_RISING>;
+ };
+
+ pcie_intc1: legacy-interrupt-controller {
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 373 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 374 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 375 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 376 IRQ_TYPE_EDGE_RISING>;
+ };
+ };
+ };
+};
+
+&mdio {
+ reg = <0x24200f00 0x100>;
+};
diff --git a/arch/arm/boot/dts/k2hk-clocks.dtsi b/arch/arm/boot/dts/k2hk-clocks.dtsi
new file mode 100644
index 000000000..d5adee3c0
--- /dev/null
+++ b/arch/arm/boot/dts/k2hk-clocks.dtsi
@@ -0,0 +1,426 @@
+/*
+ * Copyright 2013-2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Kepler/Hawking SoC clock nodes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+clocks {
+ armpllclk: armpllclk@2620370 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclkarm>;
+ clock-output-names = "arm-pll-clk";
+ reg = <0x02620370 4>;
+ reg-names = "control";
+ };
+
+ mainpllclk: mainpllclk@2310110 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,main-pll-clock";
+ clocks = <&refclksys>;
+ reg = <0x02620350 4>, <0x02310110 4>;
+ reg-names = "control", "multiplier";
+ fixed-postdiv = <2>;
+ };
+
+ papllclk: papllclk@2620358 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclkpass>;
+ clock-output-names = "papllclk";
+ reg = <0x02620358 4>;
+ reg-names = "control";
+ };
+
+ ddr3apllclk: ddr3apllclk@2620360 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclkddr3a>;
+ clock-output-names = "ddr-3a-pll-clk";
+ reg = <0x02620360 4>;
+ reg-names = "control";
+ };
+
+ ddr3bpllclk: ddr3bpllclk@2620368 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclkddr3b>;
+ clock-output-names = "ddr-3b-pll-clk";
+ reg = <0x02620368 4>;
+ reg-names = "control";
+ };
+
+ clktsip: clktsip {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk16>;
+ clock-output-names = "tsip";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clksrio: clksrio {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1rstiso13>;
+ clock-output-names = "srio";
+ reg = <0x0235002c 0xb00>, <0x02350010 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <4>;
+ };
+
+ clkhyperlink0: clkhyperlink0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk12>;
+ clock-output-names = "hyperlink-0";
+ reg = <0x02350030 0xb00>, <0x02350014 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <5>;
+ };
+
+ clkgem1: clkgem1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem1";
+ reg = <0x02350040 0xb00>, <0x02350024 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <9>;
+ };
+
+ clkgem2: clkgem2 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem2";
+ reg = <0x02350044 0xb00>, <0x02350028 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <10>;
+ };
+
+ clkgem3: clkgem3 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem3";
+ reg = <0x02350048 0xb00>, <0x0235002c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <11>;
+ };
+
+ clkgem4: clkgem4 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem4";
+ reg = <0x0235004c 0xb00>, <0x02350030 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <12>;
+ };
+
+ clkgem5: clkgem5 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem5";
+ reg = <0x02350050 0xb00>, <0x02350034 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <13>;
+ };
+
+ clkgem6: clkgem6 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem6";
+ reg = <0x02350054 0xb00>, <0x02350038 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <14>;
+ };
+
+ clkgem7: clkgem7 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem7";
+ reg = <0x02350058 0xb00>, <0x0235003c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <15>;
+ };
+
+ clkddr31: clkddr31 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "ddr3-1";
+ reg = <0x02350060 0xb00>, <0x02350040 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <16>;
+ };
+
+ clktac: clktac {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tac";
+ reg = <0x02350064 0xb00>, <0x02350044 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <17>;
+ };
+
+ clkrac01: clkrac01 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "rac-01";
+ reg = <0x02350068 0xb00>, <0x02350044 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <17>;
+ };
+
+ clkrac23: clkrac23 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "rac-23";
+ reg = <0x0235006c 0xb00>, <0x02350048 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <18>;
+ };
+
+ clkfftc0: clkfftc0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "fftc-0";
+ reg = <0x02350070 0xb00>, <0x0235004c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <19>;
+ };
+
+ clkfftc1: clkfftc1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "fftc-1";
+ reg = <0x02350074 0xb00>, <0x0235004c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <19>;
+ };
+
+ clkfftc2: clkfftc2 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "fftc-2";
+ reg = <0x02350078 0xb00>, <0x02350050 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <20>;
+ };
+
+ clkfftc3: clkfftc3 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "fftc-3";
+ reg = <0x0235007c 0xb00>, <0x02350050 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <20>;
+ };
+
+ clkfftc4: clkfftc4 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "fftc-4";
+ reg = <0x02350080 0xb00>, <0x02350050 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <20>;
+ };
+
+ clkfftc5: clkfftc5 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "fftc-5";
+ reg = <0x02350084 0xb00>, <0x02350050 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <20>;
+ };
+
+ clkaif: clkaif {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "aif";
+ reg = <0x02350088 0xb00>, <0x02350054 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <21>;
+ };
+
+ clktcp3d0: clktcp3d0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tcp3d-0";
+ reg = <0x0235008c 0xb00>, <0x02350058 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <22>;
+ };
+
+ clktcp3d1: clktcp3d1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tcp3d-1";
+ reg = <0x02350090 0xb00>, <0x02350058 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <22>;
+ };
+
+ clktcp3d2: clktcp3d2 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tcp3d-2";
+ reg = <0x02350094 0xb00>, <0x0235005c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <23>;
+ };
+
+ clktcp3d3: clktcp3d3 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tcp3d-3";
+ reg = <0x02350098 0xb00>, <0x0235005c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <23>;
+ };
+
+ clkvcp0: clkvcp0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-0";
+ reg = <0x0235009c 0xb00>, <0x02350060 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <24>;
+ };
+
+ clkvcp1: clkvcp1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-1";
+ reg = <0x023500a0 0xb00>, <0x02350060 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <24>;
+ };
+
+ clkvcp2: clkvcp2 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-2";
+ reg = <0x023500a4 0xb00>, <0x02350060 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <24>;
+ };
+
+ clkvcp3: clkvcp3 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-3";
+ reg = <0x023500a8 0xb00>, <0x02350060 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <24>;
+ };
+
+ clkvcp4: clkvcp4 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-4";
+ reg = <0x023500ac 0xb00>, <0x02350064 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <25>;
+ };
+
+ clkvcp5: clkvcp5 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-5";
+ reg = <0x023500b0 0xb00>, <0x02350064 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <25>;
+ };
+
+ clkvcp6: clkvcp6 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-6";
+ reg = <0x023500b4 0xb00>, <0x02350064 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <25>;
+ };
+
+ clkvcp7: clkvcp7 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-7";
+ reg = <0x023500b8 0xb00>, <0x02350064 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <25>;
+ };
+
+ clkbcp: clkbcp {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "bcp";
+ reg = <0x023500bc 0xb00>, <0x02350068 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <26>;
+ };
+
+ clkdxb: clkdxb {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "dxb";
+ reg = <0x023500c0 0xb00>, <0x0235006c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <27>;
+ };
+
+ clkhyperlink1: clkhyperlink1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk12>;
+ clock-output-names = "hyperlink-1";
+ reg = <0x023500c4 0xb00>, <0x02350070 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <28>;
+ };
+
+ clkxge: clkxge {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "xge";
+ reg = <0x023500c8 0xb00>, <0x02350074 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <29>;
+ };
+};
diff --git a/arch/arm/boot/dts/k2hk-evm.dts b/arch/arm/boot/dts/k2hk-evm.dts
new file mode 100644
index 000000000..3223cc152
--- /dev/null
+++ b/arch/arm/boot/dts/k2hk-evm.dts
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2013-2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Kepler/Hawking EVM device tree
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "keystone.dtsi"
+#include "k2hk.dtsi"
+
+/ {
+ compatible = "ti,k2hk-evm","ti,keystone";
+ model = "Texas Instruments Keystone 2 Kepler/Hawking EVM";
+
+ soc {
+ clocks {
+ refclksys: refclksys {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <122880000>;
+ clock-output-names = "refclk-sys";
+ };
+
+ refclkpass: refclkpass {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <122880000>;
+ clock-output-names = "refclk-pass";
+ };
+
+ refclkarm: refclkarm {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <125000000>;
+ clock-output-names = "refclk-arm";
+ };
+
+ refclkddr3a: refclkddr3a {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <100000000>;
+ clock-output-names = "refclk-ddr3a";
+ };
+
+ refclkddr3b: refclkddr3b {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <100000000>;
+ clock-output-names = "refclk-ddr3b";
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ debug1_1 {
+ label = "keystone:green:debug1";
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; /* 12 */
+ };
+
+ debug1_2 {
+ label = "keystone:red:debug1";
+ gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; /* 13 */
+ };
+
+ debug2 {
+ label = "keystone:blue:debug2";
+ gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>; /* 14 */
+ };
+
+ debug3 {
+ label = "keystone:blue:debug3";
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; /* 15 */
+ };
+ };
+};
+
+&usb_phy {
+ status = "okay";
+};
+
+&usb {
+ status = "okay";
+};
+
+&aemif {
+ cs0 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clock-ranges;
+ ranges;
+
+ ti,cs-chipselect = <0>;
+ /* all timings in nanoseconds */
+ ti,cs-min-turnaround-ns = <12>;
+ ti,cs-read-hold-ns = <6>;
+ ti,cs-read-strobe-ns = <23>;
+ ti,cs-read-setup-ns = <9>;
+ ti,cs-write-hold-ns = <8>;
+ ti,cs-write-strobe-ns = <23>;
+ ti,cs-write-setup-ns = <8>;
+
+ nand@0,0 {
+ compatible = "ti,keystone-nand","ti,davinci-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0 0x4000000
+ 1 0 0x0000100>;
+
+ ti,davinci-chipselect = <0>;
+ ti,davinci-mask-ale = <0x2000>;
+ ti,davinci-mask-cle = <0x4000>;
+ ti,davinci-mask-chipsel = <0>;
+ nand-ecc-mode = "hw";
+ ti,davinci-ecc-bits = <4>;
+ nand-on-flash-bbt;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "params";
+ reg = <0x100000 0x80000>;
+ read-only;
+ };
+
+ partition@180000 {
+ label = "ubifs";
+ reg = <0x180000 0x1fe80000>;
+ };
+ };
+ };
+};
+
+&i2c0 {
+ dtt@50 {
+ compatible = "at,24c1024";
+ reg = <0x50>;
+ };
+};
+
+&spi0 {
+ nor_flash: n25q128a11@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "Micron,n25q128a11";
+ spi-max-frequency = <54000000>;
+ m25p,fast-read;
+ reg = <0>;
+
+ partition@0 {
+ label = "u-boot-spl";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@1 {
+ label = "misc";
+ reg = <0x80000 0xf80000>;
+ };
+ };
+};
+
+&mdio {
+ ethphy0: ethernet-phy@0 {
+ compatible = "marvell,88E1111", "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "marvell,88E1111", "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+};
diff --git a/arch/arm/boot/dts/k2hk.dtsi b/arch/arm/boot/dts/k2hk.dtsi
new file mode 100644
index 000000000..d721f4b73
--- /dev/null
+++ b/arch/arm/boot/dts/k2hk.dtsi
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2013-2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Kepler/Hawking soc specific device tree
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ interrupt-parent = <&gic>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <1>;
+ };
+
+ cpu@2 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <2>;
+ };
+
+ cpu@3 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <3>;
+ };
+ };
+
+ soc {
+ /include/ "k2hk-clocks.dtsi"
+
+ dspgpio0: keystone_dsp_gpio@02620240 {
+ compatible = "ti,keystone-dsp-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio,syscon-dev = <&devctrl 0x240>;
+ };
+
+ dspgpio1: keystone_dsp_gpio@2620244 {
+ compatible = "ti,keystone-dsp-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio,syscon-dev = <&devctrl 0x244>;
+ };
+
+ dspgpio2: keystone_dsp_gpio@2620248 {
+ compatible = "ti,keystone-dsp-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio,syscon-dev = <&devctrl 0x248>;
+ };
+
+ dspgpio3: keystone_dsp_gpio@262024c {
+ compatible = "ti,keystone-dsp-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio,syscon-dev = <&devctrl 0x24c>;
+ };
+
+ dspgpio4: keystone_dsp_gpio@2620250 {
+ compatible = "ti,keystone-dsp-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio,syscon-dev = <&devctrl 0x250>;
+ };
+
+ dspgpio5: keystone_dsp_gpio@2620254 {
+ compatible = "ti,keystone-dsp-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio,syscon-dev = <&devctrl 0x254>;
+ };
+
+ dspgpio6: keystone_dsp_gpio@2620258 {
+ compatible = "ti,keystone-dsp-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio,syscon-dev = <&devctrl 0x258>;
+ };
+
+ dspgpio7: keystone_dsp_gpio@262025c {
+ compatible = "ti,keystone-dsp-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio,syscon-dev = <&devctrl 0x25c>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/k2l-clocks.dtsi b/arch/arm/boot/dts/k2l-clocks.dtsi
new file mode 100644
index 000000000..eb1e3e29f
--- /dev/null
+++ b/arch/arm/boot/dts/k2l-clocks.dtsi
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2013-2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 lamarr SoC clock nodes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+clocks {
+ armpllclk: armpllclk@2620370 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclksys>;
+ clock-output-names = "arm-pll-clk";
+ reg = <0x02620370 4>;
+ reg-names = "control";
+ };
+
+ mainpllclk: mainpllclk@2310110 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,main-pll-clock";
+ clocks = <&refclksys>;
+ reg = <0x02620350 4>, <0x02310110 4>;
+ reg-names = "control", "multiplier";
+ fixed-postdiv = <2>;
+ };
+
+ papllclk: papllclk@2620358 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclksys>;
+ clock-output-names = "papllclk";
+ reg = <0x02620358 4>;
+ reg-names = "control";
+ };
+
+ ddr3apllclk: ddr3apllclk@2620360 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclksys>;
+ clock-output-names = "ddr-3a-pll-clk";
+ reg = <0x02620360 4>;
+ reg-names = "control";
+ };
+
+ clkdfeiqnsys: clkdfeiqnsys {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk12>;
+ clock-output-names = "dfe";
+ reg-names = "control", "domain";
+ reg = <0x02350004 0xb00>, <0x02350000 0x400>;
+ domain-id = <0>;
+ };
+
+ clkpcie1: clkpcie1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk12>;
+ clock-output-names = "pcie";
+ reg = <0x0235002c 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <4>;
+ };
+
+ clkgem1: clkgem1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem1";
+ reg = <0x02350040 0xb00>, <0x02350024 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <9>;
+ };
+
+ clkgem2: clkgem2 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem2";
+ reg = <0x02350044 0xb00>, <0x02350028 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <10>;
+ };
+
+ clkgem3: clkgem3 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem3";
+ reg = <0x02350048 0xb00>, <0x0235002c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <11>;
+ };
+
+ clktac: clktac {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tac";
+ reg = <0x02350064 0xb00>, <0x02350044 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <17>;
+ };
+
+ clkrac: clkrac {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "rac";
+ reg = <0x02350068 0xb00>, <0x02350044 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <17>;
+ };
+
+ clkdfepd0: clkdfepd0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "dfe-pd0";
+ reg = <0x0235006c 0xb00>, <0x02350044 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <18>;
+ };
+
+ clkfftc0: clkfftc0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "fftc-0";
+ reg = <0x02350070 0xb00>, <0x0235004c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <19>;
+ };
+
+ clkosr: clkosr {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "osr";
+ reg = <0x02350088 0xb00>, <0x0235004c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <21>;
+ };
+
+ clktcp3d0: clktcp3d0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tcp3d-0";
+ reg = <0x0235008c 0xb00>, <0x02350058 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <22>;
+ };
+
+ clktcp3d1: clktcp3d1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tcp3d-1";
+ reg = <0x02350094 0xb00>, <0x02350058 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <23>;
+ };
+
+ clkvcp0: clkvcp0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-0";
+ reg = <0x0235009c 0xb00>, <0x02350060 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <24>;
+ };
+
+ clkvcp1: clkvcp1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-1";
+ reg = <0x023500a0 0xb00>, <0x02350060 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <24>;
+ };
+
+ clkvcp2: clkvcp2 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-2";
+ reg = <0x023500a4 0xb00>, <0x02350060 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <24>;
+ };
+
+ clkvcp3: clkvcp3 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-3";
+ reg = <0x023500a8 0xb00>, <0x02350060 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <24>;
+ };
+
+ clkbcp: clkbcp {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "bcp";
+ reg = <0x023500bc 0xb00>, <0x02350068 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <26>;
+ };
+
+ clkdfepd1: clkdfepd1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "dfe-pd1";
+ reg = <0x023500c0 0xb00>, <0x02350044 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <27>;
+ };
+
+ clkfftc1: clkfftc1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "fftc-1";
+ reg = <0x023500c4 0xb00>, <0x023504c0 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <28>;
+ };
+
+ clkiqnail: clkiqnail {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "iqn-ail";
+ reg = <0x023500c8 0xb00>, <0x0235004c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <29>;
+ };
+
+ clkuart2: clkuart2 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkmodrst0>;
+ clock-output-names = "uart2";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clkuart3: clkuart3 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkmodrst0>;
+ clock-output-names = "uart3";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/k2l-evm.dts b/arch/arm/boot/dts/k2l-evm.dts
new file mode 100644
index 000000000..85cc7f287
--- /dev/null
+++ b/arch/arm/boot/dts/k2l-evm.dts
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Lamarr EVM device tree
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "keystone.dtsi"
+#include "k2l.dtsi"
+
+/ {
+ compatible = "ti,k2l-evm","ti,keystone";
+ model = "Texas Instruments Keystone 2 Lamarr EVM";
+
+ soc {
+ clocks {
+ refclksys: refclksys {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <122880000>;
+ clock-output-names = "refclk-sys";
+ };
+ };
+ };
+};
+
+&usb_phy {
+ status = "okay";
+};
+
+&usb {
+ status = "okay";
+};
+
+&i2c0 {
+ dtt@50 {
+ compatible = "at,24c1024";
+ reg = <0x50>;
+ };
+};
+
+&aemif {
+ cs0 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clock-ranges;
+ ranges;
+
+ ti,cs-chipselect = <0>;
+ /* all timings in nanoseconds */
+ ti,cs-min-turnaround-ns = <12>;
+ ti,cs-read-hold-ns = <6>;
+ ti,cs-read-strobe-ns = <23>;
+ ti,cs-read-setup-ns = <9>;
+ ti,cs-write-hold-ns = <8>;
+ ti,cs-write-strobe-ns = <23>;
+ ti,cs-write-setup-ns = <8>;
+
+ nand@0,0 {
+ compatible = "ti,keystone-nand","ti,davinci-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0 0x4000000
+ 1 0 0x0000100>;
+
+ ti,davinci-chipselect = <0>;
+ ti,davinci-mask-ale = <0x2000>;
+ ti,davinci-mask-cle = <0x4000>;
+ ti,davinci-mask-chipsel = <0>;
+ nand-ecc-mode = "hw";
+ ti,davinci-ecc-bits = <4>;
+ nand-on-flash-bbt;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "params";
+ reg = <0x100000 0x80000>;
+ read-only;
+ };
+
+ partition@180000 {
+ label = "ubifs";
+ reg = <0x180000 0x7FE80000>;
+ };
+ };
+ };
+};
+
+&spi0 {
+ nor_flash: n25q128a11@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "Micron,n25q128a11";
+ spi-max-frequency = <54000000>;
+ m25p,fast-read;
+ reg = <0>;
+
+ partition@0 {
+ label = "u-boot-spl";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@1 {
+ label = "misc";
+ reg = <0x80000 0xf80000>;
+ };
+ };
+};
+
+&mdio {
+ ethphy0: ethernet-phy@0 {
+ compatible = "marvell,88E1514", "marvell,88E1510", "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "marvell,88E1514", "marvell,88E1510", "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+};
diff --git a/arch/arm/boot/dts/k2l.dtsi b/arch/arm/boot/dts/k2l.dtsi
new file mode 100644
index 000000000..e32c3baa7
--- /dev/null
+++ b/arch/arm/boot/dts/k2l.dtsi
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Lamarr SoC specific device tree
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ interrupt-parent = <&gic>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <1>;
+ };
+ };
+
+ soc {
+
+ /include/ "k2l-clocks.dtsi"
+
+ uart2: serial@02348400 {
+ compatible = "ns16550a";
+ current-speed = <115200>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ reg = <0x02348400 0x100>;
+ clocks = <&clkuart2>;
+ interrupts = <GIC_SPI 432 IRQ_TYPE_EDGE_RISING>;
+ };
+
+ uart3: serial@02348800 {
+ compatible = "ns16550a";
+ current-speed = <115200>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ reg = <0x02348800 0x100>;
+ clocks = <&clkuart3>;
+ interrupts = <GIC_SPI 435 IRQ_TYPE_EDGE_RISING>;
+ };
+
+ dspgpio0: keystone_dsp_gpio@02620240 {
+ compatible = "ti,keystone-dsp-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio,syscon-dev = <&devctrl 0x240>;
+ };
+
+ dspgpio1: keystone_dsp_gpio@2620244 {
+ compatible = "ti,keystone-dsp-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio,syscon-dev = <&devctrl 0x244>;
+ };
+
+ dspgpio2: keystone_dsp_gpio@2620248 {
+ compatible = "ti,keystone-dsp-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio,syscon-dev = <&devctrl 0x248>;
+ };
+
+ dspgpio3: keystone_dsp_gpio@262024c {
+ compatible = "ti,keystone-dsp-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio,syscon-dev = <&devctrl 0x24c>;
+ };
+ };
+};
+
+&spi0 {
+ ti,davinci-spi-num-cs = <5>;
+};
+
+&spi1 {
+ ti,davinci-spi-num-cs = <3>;
+};
+
+&spi2 {
+ ti,davinci-spi-num-cs = <5>;
+ /* Pin muxed. Enabled and configured by Bootloader */
+ status = "disabled";
+};
+
+&mdio {
+ reg = <0x26200f00 0x100>;
+};
diff --git a/arch/arm/boot/dts/keystone-clocks.dtsi b/arch/arm/boot/dts/keystone-clocks.dtsi
new file mode 100644
index 000000000..0c334b257
--- /dev/null
+++ b/arch/arm/boot/dts/keystone-clocks.dtsi
@@ -0,0 +1,414 @@
+/*
+ * Device Tree Source for Keystone 2 clock tree
+ *
+ * Copyright (C) 2013 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.
+ */
+
+clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ mainmuxclk: mainmuxclk@2310108 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-mux-clock";
+ clocks = <&mainpllclk>, <&refclksys>;
+ reg = <0x02310108 4>;
+ bit-shift = <23>;
+ bit-mask = <1>;
+ clock-output-names = "mainmuxclk";
+ };
+
+ chipclk1: chipclk1 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&mainmuxclk>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ clock-output-names = "chipclk1";
+ };
+
+ chipclk1rstiso: chipclk1rstiso {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&mainmuxclk>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ clock-output-names = "chipclk1rstiso";
+ };
+
+ gemtraceclk: gemtraceclk@2310120 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-divider-clock";
+ clocks = <&mainmuxclk>;
+ reg = <0x02310120 4>;
+ bit-shift = <0>;
+ bit-mask = <8>;
+ clock-output-names = "gemtraceclk";
+ };
+
+ chipstmxptclk: chipstmxptclk {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-divider-clock";
+ clocks = <&mainmuxclk>;
+ reg = <0x02310164 4>;
+ bit-shift = <0>;
+ bit-mask = <8>;
+ clock-output-names = "chipstmxptclk";
+ };
+
+ chipclk12: chipclk12 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&chipclk1>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "chipclk12";
+ };
+
+ chipclk13: chipclk13 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&chipclk1>;
+ clock-div = <3>;
+ clock-mult = <1>;
+ clock-output-names = "chipclk13";
+ };
+
+ paclk13: paclk13 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&papllclk>;
+ clock-div = <3>;
+ clock-mult = <1>;
+ clock-output-names = "paclk13";
+ };
+
+ chipclk14: chipclk14 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&chipclk1>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clock-output-names = "chipclk14";
+ };
+
+ chipclk16: chipclk16 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&chipclk1>;
+ clock-div = <6>;
+ clock-mult = <1>;
+ clock-output-names = "chipclk16";
+ };
+
+ chipclk112: chipclk112 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&chipclk1>;
+ clock-div = <12>;
+ clock-mult = <1>;
+ clock-output-names = "chipclk112";
+ };
+
+ chipclk124: chipclk124 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&chipclk1>;
+ clock-div = <24>;
+ clock-mult = <1>;
+ clock-output-names = "chipclk114";
+ };
+
+ chipclk1rstiso13: chipclk1rstiso13 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&chipclk1rstiso>;
+ clock-div = <3>;
+ clock-mult = <1>;
+ clock-output-names = "chipclk1rstiso13";
+ };
+
+ chipclk1rstiso14: chipclk1rstiso14 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&chipclk1rstiso>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clock-output-names = "chipclk1rstiso14";
+ };
+
+ chipclk1rstiso16: chipclk1rstiso16 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&chipclk1rstiso>;
+ clock-div = <6>;
+ clock-mult = <1>;
+ clock-output-names = "chipclk1rstiso16";
+ };
+
+ chipclk1rstiso112: chipclk1rstiso112 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&chipclk1rstiso>;
+ clock-div = <12>;
+ clock-mult = <1>;
+ clock-output-names = "chipclk1rstiso112";
+ };
+
+ clkmodrst0: clkmodrst0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk16>;
+ clock-output-names = "modrst0";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+
+ clkusb: clkusb {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk16>;
+ clock-output-names = "usb";
+ reg = <0x02350008 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clkaemifspi: clkaemifspi {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk16>;
+ clock-output-names = "aemif-spi";
+ reg = <0x0235000c 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+
+ clkdebugsstrc: clkdebugsstrc {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "debugss-trc";
+ reg = <0x02350014 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <1>;
+ };
+
+ clktetbtrc: clktetbtrc {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tetb-trc";
+ reg = <0x02350018 0xb00>, <0x02350004 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <1>;
+ };
+
+ clkpa: clkpa {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&paclk13>;
+ clock-output-names = "pa";
+ reg = <0x0235001c 0xb00>, <0x02350008 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <2>;
+ };
+
+ clkcpgmac: clkcpgmac {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkpa>;
+ clock-output-names = "cpgmac";
+ reg = <0x02350020 0xb00>, <0x02350008 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <2>;
+ };
+
+ clksa: clksa {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkpa>;
+ clock-output-names = "sa";
+ reg = <0x02350024 0xb00>, <0x02350008 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <2>;
+ };
+
+ clkpcie: clkpcie {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk12>;
+ clock-output-names = "pcie";
+ reg = <0x02350028 0xb00>, <0x0235000c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <3>;
+ };
+
+ clksr: clksr {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1rstiso112>;
+ clock-output-names = "sr";
+ reg = <0x02350034 0xb00>, <0x02350018 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <6>;
+ };
+
+ clkgem0: clkgem0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem0";
+ reg = <0x0235003c 0xb00>, <0x02350020 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <8>;
+ };
+
+ clkddr30: clkddr30 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk12>;
+ clock-output-names = "ddr3-0";
+ reg = <0x0235005c 0xb00>, <0x02350040 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <16>;
+ };
+
+ clkwdtimer0: clkwdtimer0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkmodrst0>;
+ clock-output-names = "timer0";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clkwdtimer1: clkwdtimer1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkmodrst0>;
+ clock-output-names = "timer1";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clkwdtimer2: clkwdtimer2 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkmodrst0>;
+ clock-output-names = "timer2";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clkwdtimer3: clkwdtimer3 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkmodrst0>;
+ clock-output-names = "timer3";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clktimer15: clktimer15 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkmodrst0>;
+ clock-output-names = "timer15";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clkuart0: clkuart0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkmodrst0>;
+ clock-output-names = "uart0";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clkuart1: clkuart1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkmodrst0>;
+ clock-output-names = "uart1";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clkaemif: clkaemif {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkaemifspi>;
+ clock-output-names = "aemif";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clkusim: clkusim {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkmodrst0>;
+ clock-output-names = "usim";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clki2c: clki2c {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkmodrst0>;
+ clock-output-names = "i2c";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clkspi: clkspi {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkaemifspi>;
+ clock-output-names = "spi";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clkgpio: clkgpio {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkmodrst0>;
+ clock-output-names = "gpio";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clkkeymgr: clkkeymgr {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkmodrst0>;
+ clock-output-names = "keymgr";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/keystone.dtsi b/arch/arm/boot/dts/keystone.dtsi
new file mode 100644
index 000000000..c06542b2c
--- /dev/null
+++ b/arch/arm/boot/dts/keystone.dtsi
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2013 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 <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/gpio/gpio.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ model = "Texas Instruments Keystone 2 SoC";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&gic>;
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ memory {
+ reg = <0x00000000 0x80000000 0x00000000 0x40000000>;
+ };
+
+ gic: interrupt-controller {
+ compatible = "arm,cortex-a15-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x0 0x02561000 0x0 0x1000>,
+ <0x0 0x02562000 0x0 0x2000>,
+ <0x0 0x02564000 0x0 0x1000>,
+ <0x0 0x02566000 0x0 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
+ IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts =
+ <GIC_PPI 13
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a15-pmu";
+ interrupts = <GIC_SPI 20 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 22 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 23 IRQ_TYPE_EDGE_RISING>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ti,keystone","simple-bus";
+ interrupt-parent = <&gic>;
+ ranges = <0x0 0x0 0x0 0xc0000000>;
+ dma-ranges = <0x80000000 0x8 0x00000000 0x80000000>;
+
+ pllctrl: pll-controller@02310000 {
+ compatible = "ti,keystone-pllctrl", "syscon";
+ reg = <0x02310000 0x200>;
+ };
+
+ devctrl: device-state-control@02620000 {
+ compatible = "ti,keystone-devctrl", "syscon";
+ reg = <0x02620000 0x1000>;
+ };
+
+ rstctrl: reset-controller {
+ compatible = "ti,keystone-reset";
+ ti,syscon-pll = <&pllctrl 0xe4>;
+ ti,syscon-dev = <&devctrl 0x328>;
+ ti,wdt-list = <0>;
+ };
+
+ /include/ "keystone-clocks.dtsi"
+
+ uart0: serial@02530c00 {
+ compatible = "ns16550a";
+ current-speed = <115200>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ reg = <0x02530c00 0x100>;
+ clocks = <&clkuart0>;
+ interrupts = <GIC_SPI 277 IRQ_TYPE_EDGE_RISING>;
+ };
+
+ uart1: serial@02531000 {
+ compatible = "ns16550a";
+ current-speed = <115200>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ reg = <0x02531000 0x100>;
+ clocks = <&clkuart1>;
+ interrupts = <GIC_SPI 280 IRQ_TYPE_EDGE_RISING>;
+ };
+
+ i2c0: i2c@2530000 {
+ compatible = "ti,davinci-i2c";
+ reg = <0x02530000 0x400>;
+ clock-frequency = <100000>;
+ clocks = <&clki2c>;
+ interrupts = <GIC_SPI 283 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c1: i2c@2530400 {
+ compatible = "ti,davinci-i2c";
+ reg = <0x02530400 0x400>;
+ clock-frequency = <100000>;
+ clocks = <&clki2c>;
+ interrupts = <GIC_SPI 286 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c2: i2c@2530800 {
+ compatible = "ti,davinci-i2c";
+ reg = <0x02530800 0x400>;
+ clock-frequency = <100000>;
+ clocks = <&clki2c>;
+ interrupts = <GIC_SPI 289 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ spi0: spi@21000400 {
+ compatible = "ti,dm6441-spi";
+ reg = <0x21000400 0x200>;
+ num-cs = <4>;
+ ti,davinci-spi-intr-line = <0>;
+ interrupts = <GIC_SPI 292 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkspi>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ spi1: spi@21000600 {
+ compatible = "ti,dm6441-spi";
+ reg = <0x21000600 0x200>;
+ num-cs = <4>;
+ ti,davinci-spi-intr-line = <0>;
+ interrupts = <GIC_SPI 296 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkspi>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ spi2: spi@21000800 {
+ compatible = "ti,dm6441-spi";
+ reg = <0x21000800 0x200>;
+ num-cs = <4>;
+ ti,davinci-spi-intr-line = <0>;
+ interrupts = <GIC_SPI 300 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkspi>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ usb_phy: usb_phy@2620738 {
+ compatible = "ti,keystone-usbphy";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x2620738 24>;
+ status = "disabled";
+ };
+
+ usb: usb@2680000 {
+ compatible = "ti,keystone-dwc3";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x2680000 0x10000>;
+ clocks = <&clkusb>;
+ clock-names = "usb";
+ interrupts = <GIC_SPI 393 IRQ_TYPE_EDGE_RISING>;
+ ranges;
+ dma-coherent;
+ dma-ranges;
+ status = "disabled";
+
+ dwc3@2690000 {
+ compatible = "synopsys,dwc3";
+ reg = <0x2690000 0x70000>;
+ interrupts = <GIC_SPI 393 IRQ_TYPE_EDGE_RISING>;
+ usb-phy = <&usb_phy>, <&usb_phy>;
+ };
+ };
+
+ wdt: wdt@022f0080 {
+ compatible = "ti,keystone-wdt","ti,davinci-wdt";
+ reg = <0x022f0080 0x80>;
+ clocks = <&clkwdtimer0>;
+ };
+
+ clock_event: timer@22f0000 {
+ compatible = "ti,keystone-timer";
+ reg = <0x022f0000 0x80>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clktimer15>;
+ };
+
+ gpio0: gpio@260bf00 {
+ compatible = "ti,keystone-gpio";
+ reg = <0x0260bf00 0x100>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ /* HW Interrupts mapped to GPIO pins */
+ interrupts = <GIC_SPI 120 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 121 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 123 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 124 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 125 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 126 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 127 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 128 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 129 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 130 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 131 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 132 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 133 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 134 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 135 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 136 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 137 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 138 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 139 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 140 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 141 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 142 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 143 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 144 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 145 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 146 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 147 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 148 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 149 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 150 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkgpio>;
+ clock-names = "gpio";
+ ti,ngpio = <32>;
+ ti,davinci-gpio-unbanked = <32>;
+ };
+
+ aemif: aemif@21000A00 {
+ compatible = "ti,keystone-aemif", "ti,davinci-aemif";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clocks = <&clkaemif>;
+ clock-names = "aemif";
+ clock-ranges;
+
+ reg = <0x21000A00 0x00000100>;
+ ranges = <0 0 0x30000000 0x10000000
+ 1 0 0x21000A00 0x00000100>;
+ };
+
+ mdio: mdio@02090300 {
+ compatible = "ti,keystone_mdio", "ti,davinci_mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x02090300 0x100>;
+ status = "disabled";
+ clocks = <&clkpa>;
+ clock-names = "fck";
+ bus_freq = <2500000>;
+ };
+
+ kirq0: keystone_irq@26202a0 {
+ compatible = "ti,keystone-irq";
+ interrupts = <GIC_SPI 4 IRQ_TYPE_EDGE_RISING>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ ti,syscon-dev = <&devctrl 0x2a0>;
+ };
+
+ pcie@21800000 {
+ compatible = "ti,keystone-pcie", "snps,dw-pcie";
+ clocks = <&clkpcie>;
+ clock-names = "pcie";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ reg = <0x21801000 0x2000>, <0x21800000 0x1000>, <0x02620128 4>;
+ ranges = <0x81000000 0 0 0x23250000 0 0x4000
+ 0x82000000 0 0x50000000 0x50000000 0 0x10000000>;
+
+ device_type = "pci";
+ num-lanes = <2>;
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie_intc0 0>, /* INT A */
+ <0 0 0 2 &pcie_intc0 1>, /* INT B */
+ <0 0 0 3 &pcie_intc0 2>, /* INT C */
+ <0 0 0 4 &pcie_intc0 3>; /* INT D */
+
+ pcie_msi_intc0: msi-interrupt-controller {
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 31 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 32 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 33 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 35 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 36 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 37 IRQ_TYPE_EDGE_RISING>;
+ };
+
+ pcie_intc0: legacy-interrupt-controller {
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 27 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 28 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 29 IRQ_TYPE_EDGE_RISING>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-6192.dtsi b/arch/arm/boot/dts/kirkwood-6192.dtsi
new file mode 100644
index 000000000..9e6e9e269
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-6192.dtsi
@@ -0,0 +1,86 @@
+/ {
+ mbus {
+ pciec: pcie-controller {
+ compatible = "marvell,kirkwood-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
+ 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
+ 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */>;
+
+ pcie0: pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x00040000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &intc 9>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gate_clk 2>;
+ status = "disabled";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ compatible = "marvell,88f6192-pinctrl";
+
+ pmx_sata0: pmx-sata0 {
+ marvell,pins = "mpp5", "mpp21", "mpp23";
+ marvell,function = "sata0";
+ };
+ pmx_sata1: pmx-sata1 {
+ marvell,pins = "mpp4", "mpp20", "mpp22";
+ marvell,function = "sata1";
+ };
+ pmx_sdio: pmx-sdio {
+ marvell,pins = "mpp12", "mpp13", "mpp14",
+ "mpp15", "mpp16", "mpp17";
+ marvell,function = "sdio";
+ };
+ };
+
+ rtc: rtc@10300 {
+ compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc";
+ reg = <0x10300 0x20>;
+ interrupts = <53>;
+ clocks = <&gate_clk 7>;
+ };
+
+ sata: sata@80000 {
+ compatible = "marvell,orion-sata";
+ reg = <0x80000 0x5000>;
+ interrupts = <21>;
+ clocks = <&gate_clk 14>, <&gate_clk 15>;
+ clock-names = "0", "1";
+ phys = <&sata_phy0>, <&sata_phy1>;
+ phy-names = "port0", "port1";
+ status = "disabled";
+ };
+
+ sdio: mvsdio@90000 {
+ compatible = "marvell,orion-sdio";
+ reg = <0x90000 0x200>;
+ interrupts = <28>;
+ clocks = <&gate_clk 4>;
+ bus-width = <4>;
+ cap-sdio-irq;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-6281.dtsi b/arch/arm/boot/dts/kirkwood-6281.dtsi
new file mode 100644
index 000000000..7dc7d6782
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-6281.dtsi
@@ -0,0 +1,88 @@
+/ {
+ mbus {
+ pciec: pcie-controller {
+ compatible = "marvell,kirkwood-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
+ 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
+ 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */>;
+
+ pcie0: pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x00040000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &intc 9>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gate_clk 2>;
+ status = "disabled";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ compatible = "marvell,88f6281-pinctrl";
+
+ pmx_sata0: pmx-sata0 {
+ marvell,pins = "mpp5", "mpp21", "mpp23";
+ marvell,function = "sata0";
+ };
+ pmx_sata1: pmx-sata1 {
+ marvell,pins = "mpp4", "mpp20", "mpp22";
+ marvell,function = "sata1";
+ };
+ pmx_sdio: pmx-sdio {
+ marvell,pins = "mpp12", "mpp13", "mpp14",
+ "mpp15", "mpp16", "mpp17";
+ marvell,function = "sdio";
+ };
+ };
+
+ rtc: rtc@10300 {
+ compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc";
+ reg = <0x10300 0x20>;
+ interrupts = <53>;
+ clocks = <&gate_clk 7>;
+ };
+
+ sata: sata@80000 {
+ compatible = "marvell,orion-sata";
+ reg = <0x80000 0x5000>;
+ interrupts = <21>;
+ clocks = <&gate_clk 14>, <&gate_clk 15>;
+ clock-names = "0", "1";
+ phys = <&sata_phy0>, <&sata_phy1>;
+ phy-names = "port0", "port1";
+ status = "disabled";
+ };
+
+ sdio: mvsdio@90000 {
+ compatible = "marvell,orion-sdio";
+ reg = <0x90000 0x200>;
+ interrupts = <28>;
+ clocks = <&gate_clk 4>;
+ pinctrl-0 = <&pmx_sdio>;
+ pinctrl-names = "default";
+ bus-width = <4>;
+ cap-sdio-irq;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-6282.dtsi b/arch/arm/boot/dts/kirkwood-6282.dtsi
new file mode 100644
index 000000000..4680eec99
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-6282.dtsi
@@ -0,0 +1,138 @@
+/ {
+ mbus {
+ pciec: pcie-controller {
+ compatible = "marvell,kirkwood-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
+ 0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000
+ 0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000
+ 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
+ 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */
+ 0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 1.0 MEM */
+ 0x81000000 0x2 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 1.0 IO */>;
+
+ pcie0: pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x00040000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &intc 9>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gate_clk 2>;
+ status = "disabled";
+ };
+
+ pcie1: pcie@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82001000 0 0x00044000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+ 0x81000000 0 0 0x81000000 0x2 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &intc 10>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gate_clk 18>;
+ status = "disabled";
+ };
+ };
+ };
+ ocp@f1000000 {
+
+ pinctrl: pin-controller@10000 {
+ compatible = "marvell,88f6282-pinctrl";
+
+ pmx_sata0: pmx-sata0 {
+ marvell,pins = "mpp5", "mpp21", "mpp23";
+ marvell,function = "sata0";
+ };
+ pmx_sata1: pmx-sata1 {
+ marvell,pins = "mpp4", "mpp20", "mpp22";
+ marvell,function = "sata1";
+ };
+
+ /*
+ * Default I2C1 pinctrl setting on mpp36/mpp37,
+ * overwrite marvell,pins on board level if required.
+ */
+ pmx_twsi1: pmx-twsi1 {
+ marvell,pins = "mpp36", "mpp37";
+ marvell,function = "twsi1";
+ };
+
+ pmx_sdio: pmx-sdio {
+ marvell,pins = "mpp12", "mpp13", "mpp14",
+ "mpp15", "mpp16", "mpp17";
+ marvell,function = "sdio";
+ };
+ };
+
+ thermal: thermal@10078 {
+ compatible = "marvell,kirkwood-thermal";
+ reg = <0x10078 0x4>;
+ status = "okay";
+ };
+
+ rtc: rtc@10300 {
+ compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc";
+ reg = <0x10300 0x20>;
+ interrupts = <53>;
+ clocks = <&gate_clk 7>;
+ };
+
+ i2c1: i2c@11100 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11100 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <32>;
+ clock-frequency = <100000>;
+ clocks = <&gate_clk 7>;
+ pinctrl-0 = <&pmx_twsi1>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ sata: sata@80000 {
+ compatible = "marvell,orion-sata";
+ reg = <0x80000 0x5000>;
+ interrupts = <21>;
+ clocks = <&gate_clk 14>, <&gate_clk 15>;
+ clock-names = "0", "1";
+ phys = <&sata_phy0>, <&sata_phy1>;
+ phy-names = "port0", "port1";
+ status = "disabled";
+ };
+
+ sdio: mvsdio@90000 {
+ compatible = "marvell,orion-sdio";
+ reg = <0x90000 0x200>;
+ interrupts = <28>;
+ clocks = <&gate_clk 4>;
+ pinctrl-0 = <&pmx_sdio>;
+ pinctrl-names = "default";
+ bus-width = <4>;
+ cap-sdio-irq;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-98dx4122.dtsi b/arch/arm/boot/dts/kirkwood-98dx4122.dtsi
new file mode 100644
index 000000000..9e1f741d7
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-98dx4122.dtsi
@@ -0,0 +1,51 @@
+/ {
+ mbus {
+ pciec: pcie-controller {
+ compatible = "marvell,kirkwood-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
+ 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
+ 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */>;
+
+ pcie0: pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x00040000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &intc 9>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gate_clk 2>;
+ status = "disabled";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ compatible = "marvell,98dx4122-pinctrl";
+
+ };
+ };
+};
+
+&sata_phy0 {
+ status = "disabled";
+};
+
+&sata_phy1 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/kirkwood-b3.dts b/arch/arm/boot/dts/kirkwood-b3.dts
new file mode 100644
index 000000000..c9247f867
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-b3.dts
@@ -0,0 +1,201 @@
+/*
+ * Device Tree file for Excito Bubba B3
+ *
+ * Copyright (C) 2013, Andrew Lunn <andrew@lunn.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.
+ *
+ * Note: This requires a new'ish version of u-boot, which disables the
+ * L2 cache. If your B3 silently fails to boot, u-boot is probably too
+ * old. Either upgrade, or consider the following email:
+ *
+ * http://lists.debian.org/debian-arm/2012/08/msg00128.html
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "Excito B3";
+ compatible = "excito,b3", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+ memory { /* 512 MB */
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ /* Wifi model has Atheros chipset on pcie port */
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pmx_button_power: pmx-button-power {
+ marvell,pins = "mpp39";
+ marvell,function = "gpio";
+ };
+ pmx_led_green: pmx-led-green {
+ marvell,pins = "mpp38";
+ marvell,function = "gpio";
+ };
+ pmx_led_red: pmx-led-red {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+ pmx_led_blue: pmx-led-blue {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+ pmx_beeper: pmx-beeper {
+ marvell,pins = "mpp40";
+ marvell,function = "gpio";
+ };
+ };
+
+ spi@10600 {
+ status = "okay";
+
+ m25p16@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p16";
+ reg = <0>;
+ spi-max-frequency = <40000000>;
+ mode = <0>;
+
+ partition@0 {
+ reg = <0x0 0xc0000>;
+ label = "u-boot";
+ };
+
+ partition@c0000 {
+ reg = <0xc0000 0x20000>;
+ label = "u-boot env";
+ };
+
+ partition@e0000 {
+ reg = <0xe0000 0x120000>;
+ label = "data";
+ };
+ };
+ };
+
+ i2c@11000 {
+ status = "okay";
+ /*
+ * There is something on the bus at address 0x64.
+ * Not yet identified what it is, maybe the eeprom
+ * for the Atheros WiFi chip?
+ */
+ };
+
+
+ serial@12000 {
+ /* Internal on test pins, 3.3v TTL
+ * UART0_RX = Testpoint 65
+ * UART0_TX = Testpoint 66
+ * See the Excito Wiki for more details.
+ */
+ status = "okay";
+ };
+
+ sata@80000 {
+ /* One internal, the second as eSATA */
+ status = "okay";
+ nr-ports = <2>;
+ };
+ };
+
+ gpio-leds {
+ /*
+ * There is one LED "port" on the front and the colours
+ * mix together giving some interesting combinations.
+ */
+ compatible = "gpio-leds";
+ pinctrl-0 = < &pmx_led_green &pmx_led_red
+ &pmx_led_blue >;
+ pinctrl-names = "default";
+
+ programming_led {
+ label = "bubba3:green:programming";
+ gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ error_led {
+ label = "bubba3:red:error";
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ };
+
+ active_led {
+ label = "bubba3:blue:active";
+ gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&pmx_button_power>;
+ pinctrl-names = "default";
+
+ power-button {
+ /* On the back */
+ label = "Power Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ beeper: beeper {
+ /* 4KHz Piezoelectric buzzer */
+ compatible = "gpio-beeper";
+ pinctrl-0 = <&pmx_beeper>;
+ pinctrl-names = "default";
+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@8 {
+ device_type = "ethernet-phy";
+ reg = <8>;
+ };
+
+ ethphy1: ethernet-phy@24 {
+ device_type = "ethernet-phy";
+ reg = <24>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
+
+&eth1 {
+ status = "okay";
+ ethernet1-port@0 {
+ phy-handle = <&ethphy1>;
+ };
+};
+
diff --git a/arch/arm/boot/dts/kirkwood-blackarmor-nas220.dts b/arch/arm/boot/dts/kirkwood-blackarmor-nas220.dts
new file mode 100644
index 000000000..fa02a9aff
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-blackarmor-nas220.dts
@@ -0,0 +1,173 @@
+/*
+ * Device Tree file for Seagate Blackarmor NAS220
+ *
+ * Copyright (C) 2014 Evgeni Dobrev <evgeni@studio-punkt.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "kirkwood.dtsi"
+#include "kirkwood-6192.dtsi"
+
+/ {
+ model = "Seagate Blackarmor NAS220";
+ compatible = "seagate,blackarmor-nas220","marvell,kirkwood-88f6192",
+ "marvell,kirkwood";
+
+ memory { /* 128 MB */
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio_poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ button@1{
+ label = "Reset";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+ };
+
+ button@2{
+ label = "Power";
+ linux,code = <KEY_SLEEP>;
+ gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ blue-power {
+ label = "nas220:blue:power";
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_power_sata0 &pmx_power_sata1>;
+ pinctrl-names = "default";
+
+ sata0_power: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "SATA0 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 24 GPIO_ACTIVE_LOW>;
+ };
+
+ sata1_power: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "SATA1 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 28 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+/*
+ * Serial port routed to connector CN5
+ *
+ * pin 1 - TX (CPU's TX)
+ * pin 4 - RX (CPU's RX)
+ * pin 6 - GND
+ */
+&uart0 {
+ status = "okay";
+};
+
+&pinctrl {
+ pinctrl-0 = <&pmx_button_reset &pmx_button_power>;
+ pinctrl-names = "default";
+
+ pmx_act_sata0: pmx-act-sata0 {
+ marvell,pins = "mpp15";
+ marvell,function = "sata0";
+ };
+
+ pmx_act_sata1: pmx-act-sata1 {
+ marvell,pins = "mpp16";
+ marvell,function = "sata1";
+ };
+
+ pmx_power_sata0: pmx-power-sata0 {
+ marvell,pins = "mpp24";
+ marvell,function = "gpio";
+ };
+
+ pmx_power_sata1: pmx-power-sata1 {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+
+ pmx_button_reset: pmx-button-reset {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+
+ pmx_button_power: pmx-button-power {
+ marvell,pins = "mpp26";
+ marvell,function = "gpio";
+ };
+};
+
+&sata {
+ status = "okay";
+ nr-ports = <2>;
+};
+
+&i2c0 {
+ status = "okay";
+
+ adt7476: thermal@2e {
+ compatible = "adi,adt7476";
+ reg = <0x2e>;
+ };
+};
+
+&nand {
+ status = "okay";
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@8 {
+ reg = <8>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-cloudbox.dts b/arch/arm/boot/dts/kirkwood-cloudbox.dts
new file mode 100644
index 000000000..ab6ab4933
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-cloudbox.dts
@@ -0,0 +1,102 @@
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "LaCie CloudBox";
+ compatible = "lacie,cloudbox", "marvell,kirkwood-88f6702", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pmx_cloudbox_sata0: pmx-cloudbox-sata0 {
+ marvell,pins = "mpp15";
+ marvell,function = "sata0";
+ };
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ sata@80000 {
+ pinctrl-0 = <&pmx_cloudbox_sata0>;
+ pinctrl-names = "default";
+ status = "okay";
+ nr-ports = <1>;
+ };
+
+ spi@10600 {
+ status = "okay";
+
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mxicy,mx25l4005a";
+ reg = <0>;
+ spi-max-frequency = <20000000>;
+ mode = <0>;
+
+ partition@0 {
+ reg = <0x0 0x80000>;
+ label = "u-boot";
+ };
+ };
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@1 {
+ label = "Power push button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ red-fail {
+ label = "cloudbox:red:fail";
+ gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+ };
+ blue-sata {
+ label = "cloudbox:blue:sata";
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio_poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-d2net.dts b/arch/arm/boot/dts/kirkwood-d2net.dts
new file mode 100644
index 000000000..6b7856025
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-d2net.dts
@@ -0,0 +1,42 @@
+/*
+ * Device Tree file for d2 Network v2
+ *
+ * Copyright (C) 2014 Simon Guinot <simon.guinot@sequanux.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.
+*/
+
+/dts-v1/;
+
+#include "kirkwood-netxbig.dtsi"
+
+/ {
+ model = "LaCie d2 Network v2";
+ compatible = "lacie,d2net_v2", "lacie,netxbig", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ ns2-leds {
+ compatible = "lacie,ns2-leds";
+
+ blue-sata {
+ label = "d2net_v2:blue:sata";
+ slow-gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+ cmd-gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ red-fail {
+ label = "d2net_v2:red:fail";
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-db-88f6281.dts b/arch/arm/boot/dts/kirkwood-db-88f6281.dts
new file mode 100644
index 000000000..c39dd766c
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-db-88f6281.dts
@@ -0,0 +1,30 @@
+/*
+ * Marvell DB-88F6281-BP Development Board Setup
+ *
+ * Saeed Bishara <saeed@marvell.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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.
+ */
+
+/dts-v1/;
+
+#include "kirkwood-db.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "Marvell DB-88F6281-BP Development Board";
+ compatible = "marvell,db-88f6281-bp", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-db-88f6282.dts b/arch/arm/boot/dts/kirkwood-db-88f6282.dts
new file mode 100644
index 000000000..701c6b6cd
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-db-88f6282.dts
@@ -0,0 +1,34 @@
+/*
+ * Marvell DB-88F6282-BP Development Board Setup
+ *
+ * Saeed Bishara <saeed@marvell.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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.
+ */
+
+/dts-v1/;
+
+#include "kirkwood-db.dtsi"
+#include "kirkwood-6282.dtsi"
+
+/ {
+ model = "Marvell DB-88F6282-BP Development Board";
+ compatible = "marvell,db-88f6282-bp", "marvell,kirkwood-88f6282", "marvell,kirkwood";
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+
+ pcie@2,0 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-db.dtsi b/arch/arm/boot/dts/kirkwood-db.dtsi
new file mode 100644
index 000000000..812df691a
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-db.dtsi
@@ -0,0 +1,92 @@
+/*
+ * Marvell DB-{88F6281,88F6282}-BP Development Board Setup
+ *
+ * Saeed Bishara <saeed@marvell.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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.
+ *
+ * This file contains the definitions that are common between the 6281
+ * and 6282 variants of the Marvell Kirkwood Development Board.
+ */
+
+#include "kirkwood.dtsi"
+
+/ {
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>; /* 512 MB */
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ ocp@f1000000 {
+ pin-controller@10000 {
+ pmx_sdio_gpios: pmx-sdio-gpios {
+ marvell,pins = "mpp37", "mpp38";
+ marvell,function = "gpio";
+ };
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ sata@80000 {
+ nr-ports = <2>;
+ status = "okay";
+ };
+
+ ehci@50000 {
+ status = "okay";
+ };
+
+ mvsdio@90000 {
+ pinctrl-0 = <&pmx_sdio_gpios>;
+ pinctrl-names = "default";
+ wp-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+ cd-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+ };
+};
+
+&nand {
+ chip-delay = <25>;
+ status = "okay";
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x0 0x100000>;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x100000 0x400000>;
+ };
+
+ partition@500000 {
+ label = "root";
+ reg = <0x500000 0x1fb00000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@8 {
+ reg = <8>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-dir665.dts b/arch/arm/boot/dts/kirkwood-dir665.dts
new file mode 100644
index 000000000..786959ee9
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-dir665.dts
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2014 Claudio Leite <leitec@staticky.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.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "D-Link DIR-665";
+ compatible = "dlink,dir-665", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>; /* 128 MB */
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pinctrl-0 =< &pmx_led_usb
+ &pmx_led_internet_blue
+ &pmx_led_internet_amber
+ &pmx_led_5g &pmx_led_status_blue
+ &pmx_led_wps &pmx_led_status_amber
+ &pmx_led_24g
+ &pmx_btn_restart &pmx_btn_wps>;
+ pinctrl-names = "default";
+
+ pmx_led_usb: pmx-led-usb {
+ marvell,pins = "mpp12";
+ marvell,function = "gpio";
+ };
+ pmx_led_internet_blue: pmx-led-internet-blue {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+ pmx_led_internet_amber: pmx-led-internet-amber {
+ marvell,pins = "mpp43";
+ marvell,function = "gpio";
+ };
+ pmx_led_5g: pmx-led-5g {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+ pmx_led_status_blue: pmx-led-status-blue {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+ pmx_led_wps: pmx-led-wps {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+ pmx_led_status_amber: pmx-led-status-amber {
+ marvell,pins = "mpp48";
+ marvell,function = "gpio";
+ };
+ pmx_led_24g: pmx-led-24g {
+ marvell,pins = "mpp49";
+ marvell,function = "gpio";
+ };
+ pmx_btn_restart: pmx-btn-restart {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+ pmx_btn_wps: pmx-btn-wps {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
+ };
+ };
+
+ spi@10600 {
+ status = "okay";
+ m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mxicy,mx25l12805d";
+ spi-max-frequency = <50000000>;
+ reg = <0>;
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x0 0x30000>;
+ read-only;
+ };
+
+ partition@30000 {
+ label = "nvram";
+ reg = <0x30000 0x10000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "kernel";
+ reg = <0x40000 0x180000>;
+ };
+
+ partition@1c0000 {
+ label = "rootfs";
+ reg = <0x1c0000 0xe00000>;
+ };
+
+ cal_data: partition@fc0000 {
+ label = "cal_data";
+ reg = <0xfc0000 0x10000>;
+ read-only;
+ };
+
+ partition@fd0000 {
+ label = "lang_pack";
+ reg = <0xfd0000 0x30000>;
+ read-only;
+ };
+ };
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ i2c@11000 {
+ status = "okay";
+ };
+
+ ehci@50000 {
+ status = "okay";
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ blue-usb {
+ label = "dir665:blue:usb";
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ };
+ blue-internet {
+ /* Can only be turned on if the Internet
+ * Ethernet port has Link
+ */
+ label = "dir665:blue:internet";
+ gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+ };
+ amber-internet {
+ label = "dir665:amber:internet";
+ gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
+ };
+ blue-wifi5g {
+ label = "dir665:blue:5g";
+ gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+ };
+ blue-status {
+ label = "dir665:blue:status";
+ gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ };
+ blue-wps {
+ label = "dir665:blue:wps";
+ gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
+ };
+ amber-status {
+ label = "dir665:amber:status";
+ gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
+ };
+ blue-24g {
+ label = "dir665:blue:24g";
+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reset {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
+ };
+ wps {
+ label = "wps";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ dsa@0 {
+ compatible = "marvell,dsa";
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ dsa,ethernet = <&eth0port>;
+ dsa,mii-bus = <&mdio>;
+
+ switch@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0 0>; /* MDIO address 0, switch 0 in tree */
+
+ port@0 {
+ reg = <0>;
+ label = "lan4";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan3";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan2";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan1";
+ };
+
+ port@4 {
+ reg = <4>;
+ label = "wan";
+ };
+
+ port@6 {
+ reg = <6>;
+ label = "cpu";
+ };
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+};
+
+/* eth0 is connected to a Marvell 88E6171 switch, without a PHY. So set
+ * fixed speed and duplex. */
+&eth0 {
+ status = "okay";
+
+ ethernet0-port@0 {
+ speed = <1000>;
+ duplex = <1>;
+ };
+};
+
+/* eth1 is connected to the switch as well. However DSA only supports a
+ * single CPU port. So leave this port disabled to avoid confusion. */
+
+&eth1 {
+ status = "disabled";
+};
+
+/* There is no battery on the boards, so the RTC does not keep time
+ * when there is no power, making it useless. */
+&rtc {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/kirkwood-dns320.dts b/arch/arm/boot/dts/kirkwood-dns320.dts
new file mode 100644
index 000000000..d85ef0a91
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-dns320.dts
@@ -0,0 +1,58 @@
+/dts-v1/;
+
+#include "kirkwood-dnskw.dtsi"
+
+/ {
+ model = "D-Link DNS-320 NAS (Rev A1)";
+ compatible = "dlink,dns-320-a1", "dlink,dns-320", "dlink,dns-kirkwood", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_led_power &pmx_led_red_usb_320
+ &pmx_led_red_left_hdd &pmx_led_red_right_hdd
+ &pmx_led_white_usb>;
+ pinctrl-names = "default";
+
+ blue-power {
+ label = "dns320:blue:power";
+ gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+ blue-usb {
+ label = "dns320:blue:usb";
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+ };
+ orange-l_hdd {
+ label = "dns320:orange:l_hdd";
+ gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
+ };
+ orange-r_hdd {
+ label = "dns320:orange:r_hdd";
+ gpios = <&gpio0 27 GPIO_ACTIVE_LOW>;
+ };
+ orange-usb {
+ label = "dns320:orange:usb";
+ gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; /* GPIO 35 */
+ };
+ };
+
+ ocp@f1000000 {
+ serial@12000 {
+ status = "okay";
+ };
+
+ serial@12100 {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-dns325.dts b/arch/arm/boot/dts/kirkwood-dns325.dts
new file mode 100644
index 000000000..5e586ed04
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-dns325.dts
@@ -0,0 +1,62 @@
+/dts-v1/;
+
+#include "kirkwood-dnskw.dtsi"
+
+/ {
+ model = "D-Link DNS-325 NAS (Rev A1)";
+ compatible = "dlink,dns-325-a1", "dlink,dns-325", "dlink,dns-kirkwood", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_led_power &pmx_led_red_usb_325
+ &pmx_led_red_left_hdd &pmx_led_red_right_hdd
+ &pmx_led_white_usb>;
+ pinctrl-names = "default";
+
+ white-power {
+ label = "dns325:white:power";
+ gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+ white-usb {
+ label = "dns325:white:usb";
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; /* GPIO 43 */
+ };
+ red-l_hdd {
+ label = "dns325:red:l_hdd";
+ gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
+ };
+ red-r_hdd {
+ label = "dns325:red:r_hdd";
+ gpios = <&gpio0 27 GPIO_ACTIVE_LOW>;
+ };
+ red-usb {
+ label = "dns325:red:usb";
+ gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ ocp@f1000000 {
+ i2c@11000 {
+ status = "okay";
+
+ lm75: lm75@48 {
+ compatible = "national,lm75";
+ reg = <0x48>;
+ };
+ };
+ serial@12000 {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-dnskw.dtsi b/arch/arm/boot/dts/kirkwood-dnskw.dtsi
new file mode 100644
index 000000000..113dcf056
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-dnskw.dtsi
@@ -0,0 +1,234 @@
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "D-Link DNS NASes (kirkwood-based)";
+ compatible = "dlink,dns-kirkwood", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_button_power &pmx_button_unmount
+ &pmx_button_reset>;
+ pinctrl-names = "default";
+
+ button@1 {
+ label = "Power button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ };
+ button@2 {
+ label = "USB unmount button";
+ linux,code = <KEY_EJECTCD>;
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ };
+ button@3 {
+ label = "Reset button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio_fan {
+ /* Fan: ADDA AD045HB-G73 40mm 6000rpm@5v */
+ compatible = "gpio-fan";
+ pinctrl-0 = <&pmx_fan_high_speed &pmx_fan_low_speed>;
+ pinctrl-names = "default";
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW
+ &gpio1 13 GPIO_ACTIVE_LOW>;
+ gpio-fan,speed-map = <0 0
+ 3000 1
+ 6000 2>;
+ };
+
+ gpio_poweroff {
+ compatible = "gpio-poweroff";
+ pinctrl-0 = <&pmx_power_off>;
+ pinctrl-names = "default";
+ gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+
+ pinctrl-0 = <&pmx_power_back_on &pmx_present_sata0
+ &pmx_present_sata1 &pmx_fan_tacho
+ &pmx_temp_alarm>;
+ pinctrl-names = "default";
+
+ pmx_sata0: pmx-sata0 {
+ marvell,pins = "mpp20";
+ marvell,function = "sata1";
+ };
+ pmx_sata1: pmx-sata1 {
+ marvell,pins = "mpp21";
+ marvell,function = "sata0";
+ };
+ pmx_led_power: pmx-led-power {
+ marvell,pins = "mpp26";
+ marvell,function = "gpio";
+ };
+ pmx_led_red_right_hdd: pmx-led-red-right-hdd {
+ marvell,pins = "mpp27";
+ marvell,function = "gpio";
+ };
+ pmx_led_red_left_hdd: pmx-led-red-left-hdd {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+ pmx_led_red_usb_325: pmx-led-red-usb-325 {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+ pmx_button_power: pmx-button-power {
+ marvell,pins = "mpp34";
+ marvell,function = "gpio";
+ };
+ pmx_led_red_usb_320: pmx-led-red-usb-320 {
+ marvell,pins = "mpp35";
+ marvell,function = "gpio";
+ };
+ pmx_power_off: pmx-power-off {
+ marvell,pins = "mpp36";
+ marvell,function = "gpio";
+ };
+ pmx_power_back_on: pmx-power-back-on {
+ marvell,pins = "mpp37";
+ marvell,function = "gpio";
+ };
+ pmx_power_sata0: pmx-power-sata0 {
+ marvell,pins = "mpp39";
+ marvell,function = "gpio";
+ };
+ pmx_power_sata1: pmx-power-sata1 {
+ marvell,pins = "mpp40";
+ marvell,function = "gpio";
+ };
+ pmx_present_sata0: pmx-present-sata0 {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+ pmx_present_sata1: pmx-present-sata1 {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+ pmx_led_white_usb: pmx-led-white-usb {
+ marvell,pins = "mpp43";
+ marvell,function = "gpio";
+ };
+ pmx_fan_tacho: pmx-fan-tacho {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+ pmx_fan_high_speed: pmx-fan-high-speed {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+ pmx_fan_low_speed: pmx-fan-low-speed {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
+ };
+ pmx_button_unmount: pmx-button-unmount {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+ pmx_button_reset: pmx-button-reset {
+ marvell,pins = "mpp48";
+ marvell,function = "gpio";
+ };
+ pmx_temp_alarm: pmx-temp-alarm {
+ marvell,pins = "mpp49";
+ marvell,function = "gpio";
+ };
+ };
+ sata@80000 {
+ pinctrl-0 = <&pmx_sata0 &pmx_sata1>;
+ pinctrl-names = "default";
+ status = "okay";
+ nr-ports = <2>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_power_sata0 &pmx_power_sata1>;
+ pinctrl-names = "default";
+
+ sata0_power: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "SATA0 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 7 0>;
+ };
+ sata1_power: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "SATA1 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 8 0>;
+ };
+ };
+};
+
+&nand {
+ status = "okay";
+ chip-delay = <35>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x0100000 0x500000>;
+ };
+
+ partition@600000 {
+ label = "ramdisk";
+ reg = <0x0600000 0x500000>;
+ };
+
+ partition@b00000 {
+ label = "image";
+ reg = <0x0b00000 0x6600000>;
+ };
+
+ partition@7100000 {
+ label = "mini firmware";
+ reg = <0x7100000 0xa00000>;
+ };
+
+ partition@7b00000 {
+ label = "config";
+ reg = <0x7b00000 0x500000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@8 {
+ reg = <8>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-dockstar.dts b/arch/arm/boot/dts/kirkwood-dockstar.dts
new file mode 100644
index 000000000..849736349
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-dockstar.dts
@@ -0,0 +1,109 @@
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "Seagate FreeAgent Dockstar";
+ compatible = "seagate,dockstar", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk root=/dev/sda1 rootdelay=10";
+ stdout-path = &uart0;
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pmx_usb_power_enable: pmx-usb-power-enable {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+ pmx_led_green: pmx-led-green {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
+ };
+ pmx_led_orange: pmx-led-orange {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+ };
+ serial@12000 {
+ status = "ok";
+ };
+ };
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_led_green &pmx_led_orange>;
+ pinctrl-names = "default";
+
+ health {
+ label = "status:green:health";
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+ fault {
+ label = "status:orange:fault";
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ };
+ };
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_usb_power_enable>;
+ pinctrl-names = "default";
+
+ usb_power: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "USB Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 29 0>;
+ };
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x0100000 0x400000>;
+ };
+
+ partition@500000 {
+ label = "data";
+ reg = <0x0500000 0xfb00000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "marvell,88e1116";
+ reg = <0>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-dreamplug.dts b/arch/arm/boot/dts/kirkwood-dreamplug.dts
new file mode 100644
index 000000000..6467c7924
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts
@@ -0,0 +1,126 @@
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "Globalscale Technologies Dreamplug";
+ compatible = "globalscale,dreamplug-003-ds2001", "globalscale,dreamplug", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pmx_led_bluetooth: pmx-led-bluetooth {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+ pmx_led_wifi: pmx-led-wifi {
+ marvell,pins = "mpp48";
+ marvell,function = "gpio";
+ };
+ pmx_led_wifi_ap: pmx-led-wifi-ap {
+ marvell,pins = "mpp49";
+ marvell,function = "gpio";
+ };
+ };
+ serial@12000 {
+ status = "ok";
+ };
+
+ spi@10600 {
+ status = "okay";
+
+ m25p40@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mxicy,mx25l1606e";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+ mode = <0>;
+
+ partition@0 {
+ reg = <0x0 0x80000>;
+ label = "u-boot";
+ };
+
+ partition@100000 {
+ reg = <0x100000 0x10000>;
+ label = "u-boot env";
+ };
+
+ partition@180000 {
+ reg = <0x180000 0x10000>;
+ label = "dtb";
+ };
+ };
+ };
+
+ sata@80000 {
+ status = "okay";
+ nr-ports = <1>;
+ };
+
+ mvsdio@90000 {
+ pinctrl-0 = <&pmx_sdio>;
+ pinctrl-names = "default";
+ status = "okay";
+ /* No CD or WP GPIOs */
+ broken-cd;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_led_bluetooth &pmx_led_wifi
+ &pmx_led_wifi_ap >;
+ pinctrl-names = "default";
+
+ bluetooth {
+ label = "dreamplug:blue:bluetooth";
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ };
+ wifi {
+ label = "dreamplug:green:wifi";
+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
+ };
+ wifi-ap {
+ label = "dreamplug:green:wifi_ap";
+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
+
+&eth1 {
+ status = "okay";
+ ethernet1-port@0 {
+ phy-handle = <&ethphy1>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds109.dts b/arch/arm/boot/dts/kirkwood-ds109.dts
new file mode 100644
index 000000000..d4bcc1c7f
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ds109.dts
@@ -0,0 +1,42 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+ model = "Synology DS109, DS110, DS110jv20";
+ compatible = "synology,ds109", "synology,ds110jv20",
+ "synology,ds110", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-fan-150-32-35 {
+ status = "okay";
+ };
+
+ gpio-leds-hdd-21-1 {
+ status = "okay";
+ };
+};
+
+&rs5c372 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds110jv10.dts b/arch/arm/boot/dts/kirkwood-ds110jv10.dts
new file mode 100644
index 000000000..95bf83b91
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ds110jv10.dts
@@ -0,0 +1,42 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+ model = "Synology DS110j v10 and v30";
+ compatible = "synology,ds110jv10", "synology,ds110jv30",
+ "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-fan-150-32-35 {
+ status = "okay";
+ };
+
+ gpio-leds-hdd-21-1 {
+ status = "okay";
+ };
+};
+
+&s35390a {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds111.dts b/arch/arm/boot/dts/kirkwood-ds111.dts
new file mode 100644
index 000000000..61f47fbe4
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ds111.dts
@@ -0,0 +1,45 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+ model = "Synology DS111";
+ compatible = "synology,ds111", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-fan-100-15-35-1 {
+ status = "okay";
+ };
+
+ gpio-leds-hdd-21-1 {
+ status = "okay";
+ };
+};
+
+&s35390a {
+ status = "okay";
+};
+
+&pcie2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds112.dts b/arch/arm/boot/dts/kirkwood-ds112.dts
new file mode 100644
index 000000000..bf4143c6c
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ds112.dts
@@ -0,0 +1,49 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+ model = "Synology DS111";
+ compatible = "synology,ds111", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-fan-100-15-35-1 {
+ status = "okay";
+ };
+
+ gpio-leds-21-2 {
+ status = "okay";
+ };
+
+ regulators-hdd-30 {
+ status = "okay";
+ };
+};
+
+&s35390a {
+ status = "okay";
+};
+
+&pcie2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds209.dts b/arch/arm/boot/dts/kirkwood-ds209.dts
new file mode 100644
index 000000000..6d25093a9
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ds209.dts
@@ -0,0 +1,45 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+ model = "Synology DS209";
+ compatible = "synology,ds209", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-fan-150-32-35 {
+ status = "okay";
+ };
+
+ gpio-leds-hdd-21-2 {
+ status = "okay";
+ };
+
+ regulators-hdd-31 {
+ status = "okay";
+ };
+};
+
+&rs5c372 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds210.dts b/arch/arm/boot/dts/kirkwood-ds210.dts
new file mode 100644
index 000000000..2f1933efc
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ds210.dts
@@ -0,0 +1,47 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+ model = "Synology DS210 v10, v20, v30, DS211j";
+ compatible = "synology,ds210jv10", "synology,ds210jv20",
+ "synology,ds210jv30", "synology,ds211j",
+ "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-fan-150-32-35 {
+ status = "okay";
+ };
+
+ gpio-leds-hdd-21-2 {
+ status = "okay";
+ };
+
+ regulators-hdd-31 {
+ status = "okay";
+ };
+};
+
+&s35390a {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds212.dts b/arch/arm/boot/dts/kirkwood-ds212.dts
new file mode 100644
index 000000000..99afd462f
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ds212.dts
@@ -0,0 +1,48 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+ model = "Synology DS212, DS212p v10, v20, DS213air v10, DS213 v10";
+ compatible = "synology,ds212", "synology,ds212pv10",
+ "synology,ds212pv10", "synology,ds212pv20",
+ "synology,ds213airv10", "synology,ds213v10",
+ "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-fan-100-15-35-1 {
+ status = "okay";
+ };
+
+ gpio-leds-hdd-21-2 {
+ status = "okay";
+ };
+};
+
+&s35390a {
+ status = "okay";
+};
+
+&pcie2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds212j.dts b/arch/arm/boot/dts/kirkwood-ds212j.dts
new file mode 100644
index 000000000..f5c4213fc
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ds212j.dts
@@ -0,0 +1,42 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+ model = "Synology DS212j v10, v20";
+ compatible = "synology,ds212jv10", "synology,ds212jv20",
+ "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-fan-100-32-35 {
+ status = "okay";
+ };
+
+ gpio-leds-hdd-21-2 {
+ status = "okay";
+ };
+};
+
+&s35390a {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds409.dts b/arch/arm/boot/dts/kirkwood-ds409.dts
new file mode 100644
index 000000000..e80a962eb
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ds409.dts
@@ -0,0 +1,49 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+ model = "Synology DS409, DS410j";
+ compatible = "synology,ds409", "synology,ds410j", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-fan-150-15-18 {
+ status = "okay";
+ };
+
+ gpio-leds-hdd-36 {
+ status = "okay";
+ };
+
+ gpio-leds-alarm-12 {
+ status = "okay";
+ };
+};
+
+&eth1 {
+ status = "okay";
+};
+
+&rs5c372 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds409slim.dts b/arch/arm/boot/dts/kirkwood-ds409slim.dts
new file mode 100644
index 000000000..cae5af4b8
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ds409slim.dts
@@ -0,0 +1,41 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+ model = "Synology 409slim";
+ compatible = "synology,ds409slim", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-fan-150-32-35 {
+ status = "okay";
+ };
+
+ gpio-leds-hdd-20 {
+ status = "okay";
+ };
+};
+
+&rs5c372 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds411.dts b/arch/arm/boot/dts/kirkwood-ds411.dts
new file mode 100644
index 000000000..623cd4a37
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ds411.dts
@@ -0,0 +1,53 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+ model = "Synology DS411, DS413jv10";
+ compatible = "synology,ds411", "synology,ds413jv10", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-fan-100-15-35-1 {
+ status = "okay";
+ };
+
+ gpio-leds-hdd-36 {
+ status = "okay";
+ };
+
+ regulators-hdd-34 {
+ status = "okay";
+ };
+};
+
+&eth1 {
+ status = "okay";
+};
+
+&s35390a {
+ status = "okay";
+};
+
+&pcie2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds411j.dts b/arch/arm/boot/dts/kirkwood-ds411j.dts
new file mode 100644
index 000000000..3348e330f
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ds411j.dts
@@ -0,0 +1,49 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+ model = "Synology DS411j";
+ compatible = "synology,ds411j", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-fan-150-15-18 {
+ status = "okay";
+ };
+
+ gpio-leds-hdd-36 {
+ status = "okay";
+ };
+
+ gpio-leds-alarm-12 {
+ status = "okay";
+ };
+};
+
+&eth1 {
+ status = "okay";
+};
+
+&s35390a {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds411slim.dts b/arch/arm/boot/dts/kirkwood-ds411slim.dts
new file mode 100644
index 000000000..a0a1fad8b
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ds411slim.dts
@@ -0,0 +1,49 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+ model = "Synology DS411slim";
+ compatible = "synology,ds411slim", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-fan-100-15-35-1 {
+ status = "okay";
+ };
+
+ gpio-leds-hdd-36 {
+ status = "okay";
+ };
+};
+
+&eth1 {
+ status = "okay";
+};
+
+&s35390a {
+ status = "okay";
+};
+
+&pcie2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-goflexnet.dts b/arch/arm/boot/dts/kirkwood-goflexnet.dts
new file mode 100644
index 000000000..aa60a0b04
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-goflexnet.dts
@@ -0,0 +1,189 @@
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "Seagate GoFlex Net";
+ compatible = "seagate,goflexnet", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk root=/dev/sda1 rootdelay=10";
+ stdout-path = &uart0;
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pmx_usb_power_enable: pmx-usb-power-enable {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+ pmx_led_right_cap_0: pmx-led_right_cap_0 {
+ marvell,pins = "mpp38";
+ marvell,function = "gpio";
+ };
+ pmx_led_right_cap_1: pmx-led_right_cap_1 {
+ marvell,pins = "mpp39";
+ marvell,function = "gpio";
+ };
+ pmx_led_right_cap_2: pmx-led_right_cap_2 {
+ marvell,pins = "mpp40";
+ marvell,function = "gpio";
+ };
+ pmx_led_right_cap_3: pmx-led_right_cap_3 {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+ pmx_led_left_cap_0: pmx-led_left_cap_0 {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+ pmx_led_left_cap_1: pmx-led_left_cap_1 {
+ marvell,pins = "mpp43";
+ marvell,function = "gpio";
+ };
+ pmx_led_left_cap_2: pmx-led_left_cap_2 {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+ pmx_led_left_cap_3: pmx-led_left_cap_3 {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+ pmx_led_green: pmx-led_green {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
+ };
+ pmx_led_orange: pmx-led_orange {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+ };
+ serial@12000 {
+ status = "ok";
+ };
+
+ sata@80000 {
+ status = "okay";
+ nr-ports = <2>;
+ };
+
+ };
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = < &pmx_led_orange
+ &pmx_led_left_cap_0 &pmx_led_left_cap_1
+ &pmx_led_left_cap_2 &pmx_led_left_cap_3
+ &pmx_led_right_cap_0 &pmx_led_right_cap_1
+ &pmx_led_right_cap_2 &pmx_led_right_cap_3
+ >;
+ pinctrl-names = "default";
+
+ health {
+ label = "status:green:health";
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+ fault {
+ label = "status:orange:fault";
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ };
+ left0 {
+ label = "status:white:left0";
+ gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+ };
+ left1 {
+ label = "status:white:left1";
+ gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
+ };
+ left2 {
+ label = "status:white:left2";
+ gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ };
+ left3 {
+ label = "status:white:left3";
+ gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ };
+ right0 {
+ label = "status:white:right0";
+ gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+ };
+ right1 {
+ label = "status:white:right1";
+ gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ };
+ right2 {
+ label = "status:white:right2";
+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+ };
+ right3 {
+ label = "status:white:right3";
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ };
+ };
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_usb_power_enable>;
+ pinctrl-names = "default";
+
+ usb_power: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "USB Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&nand {
+ chip-delay = <40>;
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x0100000 0x400000>;
+ };
+
+ partition@500000 {
+ label = "pogoplug";
+ reg = <0x0500000 0x2000000>;
+ };
+
+ partition@2500000 {
+ label = "root";
+ reg = <0x02500000 0xd800000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts b/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts
new file mode 100644
index 000000000..b2d9834bf
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts
@@ -0,0 +1,132 @@
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "Globalscale Technologies Guruplug Server Plus";
+ compatible = "globalscale,guruplug-server-plus", "globalscale,guruplug", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pmx_led_health_r: pmx-led-health-r {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
+ };
+ pmx_led_health_g: pmx-led-health-g {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+ pmx_led_wmode_r: pmx-led-wmode-r {
+ marvell,pins = "mpp48";
+ marvell,function = "gpio";
+ };
+ pmx_led_wmode_g: pmx-led-wmode-g {
+ marvell,pins = "mpp49";
+ marvell,function = "gpio";
+ };
+ };
+ serial@12000 {
+ status = "ok";
+ };
+
+ sata@80000 {
+ status = "okay";
+ nr-ports = <1>;
+ };
+
+ /* AzureWave AW-GH381 WiFi/BT */
+ mvsdio@90000 {
+ status = "okay";
+ non-removable;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = < &pmx_led_health_r &pmx_led_health_g
+ &pmx_led_wmode_r &pmx_led_wmode_g >;
+ pinctrl-names = "default";
+
+ health-r {
+ label = "guruplug:red:health";
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ };
+ health-g {
+ label = "guruplug:green:health";
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ };
+ wmode-r {
+ label = "guruplug:red:wmode";
+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
+ };
+ wmode-g {
+ label = "guruplug:green:wmode";
+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x00100000 0x00400000>;
+ };
+
+ partition@500000 {
+ label = "data";
+ reg = <0x00500000 0x1fb00000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ /* Marvell 88E1121R */
+ compatible = "ethernet-phy-id0141.0cb0",
+ "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ /* Marvell 88E1121R */
+ compatible = "ethernet-phy-id0141.0cb0",
+ "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ phy-connection-type = "rgmii-id";
+ };
+};
+
+&eth1 {
+ status = "okay";
+ ethernet1-port@0 {
+ phy-handle = <&ethphy1>;
+ phy-connection-type = "rgmii-id";
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-ib62x0.dts b/arch/arm/boot/dts/kirkwood-ib62x0.dts
new file mode 100644
index 000000000..bfa5edde1
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ib62x0.dts
@@ -0,0 +1,145 @@
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "RaidSonic ICY BOX IB-NAS62x0 (Rev B)";
+ compatible = "raidsonic,ib-nas6210-b", "raidsonic,ib-nas6220-b", "raidsonic,ib-nas6210", "raidsonic,ib-nas6220", "raidsonic,ib-nas62x0", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pmx_led_os_red: pmx-led-os-red {
+ marvell,pins = "mpp22";
+ marvell,function = "gpio";
+ };
+ pmx_power_off: pmx-power-off {
+ marvell,pins = "mpp24";
+ marvell,function = "gpio";
+ };
+ pmx_led_os_green: pmx-led-os-green {
+ marvell,pins = "mpp25";
+ marvell,function = "gpio";
+ };
+ pmx_led_usb_transfer: pmx-led-usb-transfer {
+ marvell,pins = "mpp27";
+ marvell,function = "gpio";
+ };
+ pmx_button_reset: pmx-button-reset {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+ pmx_button_usb_copy: pmx-button-usb-copy {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ sata@80000 {
+ status = "okay";
+ nr-ports = <2>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_button_reset &pmx_button_usb_copy>;
+ pinctrl-names = "default";
+
+ button@1 {
+ label = "USB Copy";
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
+ };
+ button@2 {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_led_os_red &pmx_led_os_green
+ &pmx_led_usb_transfer>;
+ pinctrl-names = "default";
+
+ green-os {
+ label = "ib62x0:green:os";
+ gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
+ default-state = "keep";
+ };
+ red-os {
+ label = "ib62x0:red:os";
+ gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
+ };
+ usb-copy {
+ label = "ib62x0:red:usb_copy";
+ gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio_poweroff {
+ compatible = "gpio-poweroff";
+ pinctrl-0 = <&pmx_power_off>;
+ pinctrl-names = "default";
+ gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0xe0000>;
+ };
+
+ partition@e0000 {
+ label = "u-boot environment";
+ reg = <0xe0000 0x100000>;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x0100000 0x600000>;
+ };
+
+ partition@700000 {
+ label = "root";
+ reg = <0x0700000 0xf900000>;
+ };
+
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@8 {
+ reg = <8>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts
new file mode 100644
index 000000000..38e31d15a
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-iconnect.dts
@@ -0,0 +1,196 @@
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "Iomega Iconnect";
+ compatible = "iom,iconnect-1.1", "iom,iconnect", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ linux,initrd-start = <0x4500040>;
+ linux,initrd-end = <0x4800000>;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pmx_button_reset: pmx-button-reset {
+ marvell,pins = "mpp12";
+ marvell,function = "gpio";
+ };
+ pmx_button_otb: pmx-button-otb {
+ marvell,pins = "mpp35";
+ marvell,function = "gpio";
+ };
+ pmx_led_level: pmx-led-level {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+ pmx_led_power_blue: pmx-led-power-blue {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+ pmx_led_power_red: pmx-power-red {
+ marvell,pins = "mpp43";
+ marvell,function = "gpio";
+ };
+ pmx_led_usb1: pmx-led-usb1 {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+ pmx_led_usb2: pmx-led-usb2 {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+ pmx_led_usb3: pmx-led-usb3 {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
+ };
+ pmx_led_usb4: pmx-led-usb4 {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+ pmx_led_otb: pmx-led-otb {
+ marvell,pins = "mpp48";
+ marvell,function = "gpio";
+ };
+ };
+ i2c@11000 {
+ status = "okay";
+
+ lm63: lm63@4c {
+ compatible = "national,lm63";
+ reg = <0x4c>;
+ };
+ };
+ serial@12000 {
+ status = "ok";
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = < &pmx_led_level &pmx_led_power_blue
+ &pmx_led_power_red &pmx_led_usb1
+ &pmx_led_usb2 &pmx_led_usb3
+ &pmx_led_usb4 &pmx_led_otb >;
+ pinctrl-names = "default";
+
+ led-level {
+ label = "led_level";
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ power-blue {
+ label = "power:blue";
+ gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+ default-state = "keep";
+ };
+ power-red {
+ label = "power:red";
+ gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
+ };
+ usb1 {
+ label = "usb1:blue";
+ gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ };
+ usb2 {
+ label = "usb2:blue";
+ gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ };
+ usb3 {
+ label = "usb3:blue";
+ gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+ };
+ usb4 {
+ label = "usb4:blue";
+ gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
+ };
+ otb {
+ label = "otb:blue";
+ gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = < &pmx_button_reset &pmx_button_otb >;
+ pinctrl-names = "default";
+
+ button@1 {
+ label = "OTB Button";
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ debounce-interval = <100>;
+ };
+ button@2 {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+ debounce-interval = <100>;
+ };
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x0000000 0xc0000>;
+ };
+
+ partition@a0000 {
+ label = "env";
+ reg = <0xa0000 0x20000>;
+ };
+
+ partition@100000 {
+ label = "zImage";
+ reg = <0x100000 0x300000>;
+ };
+
+ partition@540000 {
+ label = "initrd";
+ reg = <0x540000 0x300000>;
+ };
+
+ partition@980000 {
+ label = "boot";
+ reg = <0x980000 0x1f400000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@11 {
+ reg = <11>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
new file mode 100644
index 000000000..8474bffec
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
@@ -0,0 +1,225 @@
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "Iomega StorCenter ix2-200";
+ compatible = "iom,ix2-200", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pinctrl-0 = < &pmx_led_sata_brt_ctrl_1
+ &pmx_led_sata_brt_ctrl_2
+ &pmx_led_backup_brt_ctrl_1
+ &pmx_led_backup_brt_ctrl_2
+ &pmx_led_power_brt_ctrl_1
+ &pmx_led_power_brt_ctrl_2
+ &pmx_led_health_brt_ctrl_1
+ &pmx_led_health_brt_ctrl_2
+ &pmx_led_rebuild_brt_ctrl_1
+ &pmx_led_rebuild_brt_ctrl_2 >;
+ pinctrl-names = "default";
+
+ pmx_button_reset: pmx-button-reset {
+ marvell,pins = "mpp12";
+ marvell,function = "gpio";
+ };
+ pmx_button_power: pmx-button-power {
+ marvell,pins = "mpp14";
+ marvell,function = "gpio";
+ };
+ pmx_led_backup: pmx-led-backup {
+ marvell,pins = "mpp15";
+ marvell,function = "gpio";
+ };
+ pmx_led_power: pmx-led-power {
+ marvell,pins = "mpp16";
+ marvell,function = "gpio";
+ };
+ pmx_button_otb: pmx-button-otb {
+ marvell,pins = "mpp35";
+ marvell,function = "gpio";
+ };
+ pmx_led_rebuild: pmx-led-rebuild {
+ marvell,pins = "mpp36";
+ marvell,function = "gpio";
+ };
+ pmx_led_health: pmx-led_health {
+ marvell,pins = "mpp37";
+ marvell,function = "gpio";
+ };
+ pmx_led_sata_brt_ctrl_1: pmx-led-sata-brt-ctrl-1 {
+ marvell,pins = "mpp38";
+ marvell,function = "gpio";
+ };
+ pmx_led_sata_brt_ctrl_2: pmx-led-sata-brt-ctrl-2 {
+ marvell,pins = "mpp39";
+ marvell,function = "gpio";
+ };
+ pmx_led_backup_brt_ctrl_1: pmx-led-backup-brt-ctrl-1 {
+ marvell,pins = "mpp40";
+ marvell,function = "gpio";
+ };
+ pmx_led_backup_brt_ctrl_2: pmx-led-backup-brt-ctrl-2 {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+ pmx_led_power_brt_ctrl_1: pmx-led-power-brt-ctrl-1 {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+ pmx_led_power_brt_ctrl_2: pmx-led-power-brt-ctrl-2 {
+ marvell,pins = "mpp43";
+ marvell,function = "gpio";
+ };
+ pmx_led_health_brt_ctrl_1: pmx-led-health-brt-ctrl-1 {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+ pmx_led_health_brt_ctrl_2: pmx-led-health-brt-ctrl-2 {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+ pmx_led_rebuild_brt_ctrl_1: pmx-led-rebuild-brt-ctrl-1 {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
+ };
+ pmx_led_rebuild_brt_ctrl_2: pmx-led-rebuild-brt-ctrl-2 {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+
+ };
+ i2c@11000 {
+ status = "okay";
+
+ lm63: lm63@4c {
+ compatible = "national,lm63";
+ reg = <0x4c>;
+ };
+ };
+
+ serial@12000 {
+ status = "ok";
+ };
+
+ sata@80000 {
+ status = "okay";
+ nr-ports = <2>;
+ };
+
+ };
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = < &pmx_led_backup &pmx_led_power
+ &pmx_led_rebuild &pmx_led_health >;
+ pinctrl-names = "default";
+
+ power_led {
+ label = "status:white:power_led";
+ gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
+ default-state = "keep";
+ };
+ rebuild_led {
+ label = "status:white:rebuild_led";
+ gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+ };
+ health_led {
+ label = "status:red:health_led";
+ gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+ };
+ backup_led {
+ label = "status:blue:backup_led";
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
+ };
+ };
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_button_reset &pmx_button_power
+ &pmx_button_otb>;
+ pinctrl-names = "default";
+
+
+ Power {
+ label = "Power Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+ };
+ Reset {
+ label = "Reset Button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+ };
+ OTB {
+ label = "OTB Button";
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ };
+ };
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x100000>;
+ read-only;
+ };
+
+ partition@a0000 {
+ label = "env";
+ reg = <0xa0000 0x20000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x100000 0x300000>;
+ };
+
+ partition@400000 {
+ label = "rootfs";
+ reg = <0x400000 0x1C00000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy1: ethernet-phy@11 {
+ reg = <11>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ speed = <1000>;
+ duplex = <1>;
+ };
+};
+
+&eth1 {
+ status = "okay";
+ ethernet1-port@0 {
+ phy-handle = <&ethphy1>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-is2.dts b/arch/arm/boot/dts/kirkwood-is2.dts
new file mode 100644
index 000000000..da674bbd4
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-is2.dts
@@ -0,0 +1,34 @@
+/dts-v1/;
+
+#include "kirkwood-ns2-common.dtsi"
+
+/ {
+ model = "LaCie Internet Space v2";
+ compatible = "lacie,inetspace_v2", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ ocp@f1000000 {
+ sata@80000 {
+ pinctrl-0 = <&pmx_ns2_sata0>;
+ pinctrl-names = "default";
+ status = "okay";
+ nr-ports = <1>;
+ };
+ };
+
+ ns2-leds {
+ compatible = "lacie,ns2-leds";
+
+ blue-sata {
+ label = "ns2:blue:sata";
+ slow-gpio = <&gpio0 29 0>;
+ cmd-gpio = <&gpio0 30 0>;
+ };
+ };
+};
+
+&ethphy0 { reg = <8>; };
diff --git a/arch/arm/boot/dts/kirkwood-km_common.dtsi b/arch/arm/boot/dts/kirkwood-km_common.dtsi
new file mode 100644
index 000000000..8367c772c
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-km_common.dtsi
@@ -0,0 +1,48 @@
+/ {
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pinctrl-0 = < &pmx_i2c_gpio_sda &pmx_i2c_gpio_scl >;
+ pinctrl-names = "default";
+
+ pmx_i2c_gpio_sda: pmx-gpio-sda {
+ marvell,pins = "mpp8";
+ marvell,function = "gpio";
+ };
+ pmx_i2c_gpio_scl: pmx-gpio-scl {
+ marvell,pins = "mpp9";
+ marvell,function = "gpio";
+ };
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+ };
+
+ i2c@0 {
+ compatible = "i2c-gpio";
+ gpios = < &gpio0 8 GPIO_ACTIVE_HIGH /* sda */
+ &gpio0 9 GPIO_ACTIVE_HIGH>; /* scl */
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ };
+};
+
+&nand {
+ status = "okay";
+ chip-delay = <25>;
+};
diff --git a/arch/arm/boot/dts/kirkwood-km_fixedeth.dts b/arch/arm/boot/dts/kirkwood-km_fixedeth.dts
new file mode 100644
index 000000000..9895f2b10
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-km_fixedeth.dts
@@ -0,0 +1,23 @@
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-98dx4122.dtsi"
+#include "kirkwood-km_common.dtsi"
+
+/ {
+ model = "Keymile Kirkwood Fixed Eth";
+ compatible = "keymile,km_fixedeth", "marvell,kirkwood-98DX4122", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ speed = <1000>; /* <SPEED_1000> */
+ duplex = <1>; /* <DUPLEX_FULL> */
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-km_kirkwood.dts b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts
new file mode 100644
index 000000000..235bf382f
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts
@@ -0,0 +1,30 @@
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-98dx4122.dtsi"
+#include "kirkwood-km_common.dtsi"
+
+/ {
+ model = "Keymile Kirkwood Reference Design";
+ compatible = "keymile,km_kirkwood", "marvell,kirkwood-98DX4122", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x08000000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-laplug.dts b/arch/arm/boot/dts/kirkwood-laplug.dts
new file mode 100644
index 000000000..24425660e
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-laplug.dts
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2013 Maxime Hadjinlian <maxime.hadjinlian@gmail.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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "kirkwood.dtsi"
+#include "kirkwood-6192.dtsi"
+
+/ {
+ model = "LaCie LaPlug";
+ compatible = "lacie,laplug", "marvell,kirkwood-88f6192", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>; /* 128 MB */
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ serial@12000 {
+ status = "okay";
+ };
+
+ i2c@11000 {
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "atmel,24c04";
+ pagesize = <16>;
+ reg = <0x50>;
+ };
+ };
+
+ pinctrl: pin-controller@10000 {
+ pmx_usb_power_enable: pmx-usb-power-enable {
+ marvell,pins = "mpp14";
+ marvell,function = "gpio";
+ };
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ button@1{
+ label = "Power push button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ red-fail {
+ label = "laplug_v2:red:power";
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ };
+ blue-power {
+ label = "laplug_v2:blue:power";
+ gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+ };
+
+ gpio_poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_usb_power_enable>;
+ pinctrl-names = "default";
+
+ usb_power_back1: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "USB Power Back 1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 15 GPIO_ACTIVE_HIGH>;
+ };
+
+ usb_power_back2: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "USB Power Back 2";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+ };
+
+ usb_power_front: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "USB Power Front";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&nand {
+ /* Total size : 512MB */
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x100000>; /* 1MB */
+ read-only;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x100000 0x1000000>; /* 16MB */
+ };
+
+ partition@1100000 {
+ label = "rootfs";
+ reg = <0x1100000 0x1EF00000>; /* 495MB */
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ device_type = "ethernet-phy";
+ reg = <0>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-lschlv2.dts b/arch/arm/boot/dts/kirkwood-lschlv2.dts
new file mode 100644
index 000000000..e2fa368ae
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-lschlv2.dts
@@ -0,0 +1,19 @@
+/dts-v1/;
+
+#include "kirkwood-lsxl.dtsi"
+
+/ {
+ model = "Buffalo Linkstation LS-CHLv2";
+ compatible = "buffalo,lschlv2", "buffalo,lsxl", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x4000000>;
+ };
+
+ ocp@f1000000 {
+ serial@12000 {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-lsxhl.dts b/arch/arm/boot/dts/kirkwood-lsxhl.dts
new file mode 100644
index 000000000..8d89cdf8d
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-lsxhl.dts
@@ -0,0 +1,19 @@
+/dts-v1/;
+
+#include "kirkwood-lsxl.dtsi"
+
+/ {
+ model = "Buffalo Linkstation LS-XHL";
+ compatible = "buffalo,lsxhl", "buffalo,lsxl", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ ocp@f1000000 {
+ serial@12000 {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-lsxl.dtsi b/arch/arm/boot/dts/kirkwood-lsxl.dtsi
new file mode 100644
index 000000000..53484474d
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-lsxl.dtsi
@@ -0,0 +1,236 @@
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pmx_power_hdd: pmx-power-hdd {
+ marvell,pins = "mpp10";
+ marvell,function = "gpo";
+ };
+ pmx_usb_vbus: pmx-usb-vbus {
+ marvell,pins = "mpp11";
+ marvell,function = "gpio";
+ };
+ pmx_fan_high: pmx-fan-high {
+ marvell,pins = "mpp18";
+ marvell,function = "gpo";
+ };
+ pmx_fan_low: pmx-fan-low {
+ marvell,pins = "mpp19";
+ marvell,function = "gpo";
+ };
+ pmx_led_function_blue: pmx-led-function-blue {
+ marvell,pins = "mpp36";
+ marvell,function = "gpio";
+ };
+ pmx_led_alarm: pmx-led-alarm {
+ marvell,pins = "mpp37";
+ marvell,function = "gpio";
+ };
+ pmx_led_info: pmx-led-info {
+ marvell,pins = "mpp38";
+ marvell,function = "gpio";
+ };
+ pmx_led_power: pmx-led-power {
+ marvell,pins = "mpp39";
+ marvell,function = "gpio";
+ };
+ pmx_fan_lock: pmx-fan-lock {
+ marvell,pins = "mpp40";
+ marvell,function = "gpio";
+ };
+ pmx_button_function: pmx-button-function {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+ pmx_power_switch: pmx-power-switch {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+ pmx_power_auto_switch: pmx-power-auto-switch {
+ marvell,pins = "mpp43";
+ marvell,function = "gpio";
+ };
+ pmx_led_function_red: pmx-led-function_red {
+ marvell,pins = "mpp48";
+ marvell,function = "gpio";
+ };
+
+ };
+ sata@80000 {
+ status = "okay";
+ nr-ports = <1>;
+ };
+
+ spi@10600 {
+ status = "okay";
+
+ m25p40@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p40";
+ reg = <0>;
+ spi-max-frequency = <25000000>;
+ mode = <0>;
+
+ partition@0 {
+ reg = <0x0 0x60000>;
+ label = "uboot";
+ read-only;
+ };
+
+ partition@60000 {
+ reg = <0x60000 0x10000>;
+ label = "dtb";
+ read-only;
+ };
+
+ partition@70000 {
+ reg = <0x70000 0x10000>;
+ label = "uboot_env";
+ };
+ };
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_button_function &pmx_power_switch
+ &pmx_power_auto_switch>;
+ pinctrl-names = "default";
+
+ button@1 {
+ label = "Function Button";
+ linux,code = <KEY_OPTION>;
+ gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ };
+ button@2 {
+ label = "Power-on Switch";
+ linux,code = <KEY_RESERVED>;
+ linux,input-type = <5>;
+ gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+ };
+ button@3 {
+ label = "Power-auto Switch";
+ linux,code = <KEY_ESC>;
+ linux,input-type = <5>;
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio_leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm
+ &pmx_led_info &pmx_led_power
+ &pmx_led_function_blue>;
+ pinctrl-names = "default";
+
+ led@1 {
+ label = "lsxl:blue:func";
+ gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+ };
+
+ led@2 {
+ label = "lsxl:red:alarm";
+ gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+ };
+
+ led@3 {
+ label = "lsxl:amber:info";
+ gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+ };
+
+ led@4 {
+ label = "lsxl:blue:power";
+ gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+
+ led@5 {
+ label = "lsxl:red:func";
+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio_fan {
+ compatible = "gpio-fan";
+ pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>;
+ pinctrl-names = "default";
+ gpios = <&gpio0 19 GPIO_ACTIVE_LOW
+ &gpio0 18 GPIO_ACTIVE_LOW>;
+ gpio-fan,speed-map = <0 3
+ 1500 2
+ 3250 1
+ 5000 0>;
+ alarm-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+ };
+
+ restart_poweroff {
+ compatible = "restart-poweroff";
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_power_hdd &pmx_usb_vbus>;
+ pinctrl-names = "default";
+
+ usb_power: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "USB Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 11 0>;
+ };
+ hdd_power: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "HDD Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 10 0>;
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ ethphy1: ethernet-phy@8 {
+ reg = <8>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
+
+&eth1 {
+ status = "okay";
+ ethernet1-port@0 {
+ phy-handle = <&ethphy1>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-mplcec4.dts b/arch/arm/boot/dts/kirkwood-mplcec4.dts
new file mode 100644
index 000000000..f3a991837
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-mplcec4.dts
@@ -0,0 +1,217 @@
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "MPL CEC4";
+ compatible = "mpl,cec4-10", "mpl,cec4", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pmx_led_health: pmx-led-health {
+ marvell,pins = "mpp7";
+ marvell,function = "gpo";
+ };
+
+ pmx_sata1: pmx-sata1 {
+ marvell,pins = "mpp34";
+ marvell,function = "sata1";
+ };
+
+ pmx_sata0: pmx-sata0 {
+ marvell,pins = "mpp35";
+ marvell,function = "sata0";
+ };
+
+ pmx_led_user1o: pmx-led-user1o {
+ marvell,pins = "mpp40";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_user1g: pmx-led-user1g {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_user0o: pmx-led-user0o {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_user0g: pmx-led-user0g {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_misc: pmx-led-misc {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
+ };
+
+ pmx_sdio_cd: pmx-sdio-cd {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+ };
+
+ i2c@11000 {
+ status = "okay";
+
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+
+ eeprom@57 {
+ compatible = "atmel,24c02";
+ reg = <0x57>;
+ };
+
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ rtc@10300 {
+ status = "disabled";
+ };
+
+ sata@80000 {
+ pinctrl-0 = <&pmx_sata0 &pmx_sata1>;
+ pinctrl-names = "default";
+ nr-ports = <2>;
+ status = "okay";
+ };
+
+ mvsdio@90000 {
+ pinctrl-0 = <&pmx_sdio &pmx_sdio_cd>;
+ pinctrl-names = "default";
+ status = "okay";
+ cd-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ /* No WP GPIO */
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = < &pmx_led_health
+ &pmx_led_user1o
+ &pmx_led_user1g &pmx_led_user0o
+ &pmx_led_user0g &pmx_led_misc
+ >;
+ pinctrl-names = "default";
+
+ health {
+ label = "status:green:health";
+ gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+ };
+
+ user1o {
+ label = "user1:orange";
+ gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
+ default-state = "on";
+ };
+
+ user1g {
+ label = "user1:green";
+ gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ default-state = "on";
+ };
+
+ user0o {
+ label = "user0:orange";
+ gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+ default-state = "on";
+ };
+
+ user0g {
+ label = "user0:green";
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+ default-state = "on";
+ };
+
+ misc {
+ label = "status:orange:misc";
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ default-state = "on";
+ };
+
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x0000000 0x100000>;
+ };
+
+ partition@100000 {
+ label = "env";
+ reg = <0x100000 0x80000>;
+ };
+
+ partition@180000 {
+ label = "fdt";
+ reg = <0x180000 0x80000>;
+ };
+
+ partition@200000 {
+ label = "kernel";
+ reg = <0x200000 0x400000>;
+ };
+
+ partition@600000 {
+ label = "rootfs";
+ reg = <0x600000 0x1fa00000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ ethphy1: ethernet-phy@2 {
+ reg = <2>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
+
+&eth1 {
+ status = "okay";
+ ethernet1-port@0 {
+ phy-handle = <&ethphy1>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts b/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts
new file mode 100644
index 000000000..f82827d6f
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts
@@ -0,0 +1,181 @@
+/*
+ * Marvell 88F6281 GTW GE Board
+ *
+ * Lennert Buytenhek <buytenh@marvell.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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.
+ *
+ * This file contains the definitions that are common between the 6281
+ * and 6282 variants of the Marvell Kirkwood Development Board.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "Marvell 88F6281 GTW GE Board";
+ compatible = "marvell,mv88f6281gtw-ge", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>; /* 512 MB */
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pin-controller@10000 {
+ pmx_usb_led: pmx-usb-led {
+ marvell,pins = "mpp12";
+ marvell,function = "gpo";
+ };
+
+ pmx_leds: pmx-leds {
+ marvell,pins = "mpp20", "mpp21";
+ marvell,function = "gpio";
+ };
+
+ pmx_keys: pmx-keys {
+ marvell,pins = "mpp46", "mpp47";
+ marvell,function = "gpio";
+ };
+ };
+
+ spi@10600 {
+ status = "okay";
+
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mxicy,mx25l12805d";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+ mode = <0>;
+ };
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ ehci@50000 {
+ status = "okay";
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_leds &pmx_usb_led>;
+ pinctrl-names = "default";
+
+ green-status {
+ label = "gtw:green:Status";
+ gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
+ };
+
+ red-status {
+ label = "gtw:red:Status";
+ gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>;
+ };
+
+ green-usb {
+ label = "gtw:green:USB";
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_keys>;
+ pinctrl-names = "default";
+
+ button@1 {
+ label = "SWR Button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ };
+ button@2 {
+ label = "WPS Button";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ dsa@0 {
+ compatible = "marvell,dsa";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dsa,ethernet = <&eth0port>;
+ dsa,mii-bus = <&mdio>;
+
+ switch@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0 0>; /* MDIO address 0, switch 0 in tree */
+
+ port@0 {
+ reg = <0>;
+ label = "lan1";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan2";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan3";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan4";
+ };
+
+ port@4 {
+ reg = <4>;
+ label = "wan";
+ };
+
+ port@5 {
+ reg = <5>;
+ label = "cpu";
+ };
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+};
+
+&eth0 {
+ status = "okay";
+
+ ethernet0-port@0 {
+ speed = <1000>;
+ duplex = <1>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-nas2big.dts b/arch/arm/boot/dts/kirkwood-nas2big.dts
new file mode 100644
index 000000000..7427ec50b
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-nas2big.dts
@@ -0,0 +1,143 @@
+/*
+ * Device Tree file for LaCie 2Big NAS
+ *
+ * Copyright (C) 2015 Seagate
+ *
+ * Author: Simon Guinot <simon.guinot@sequanux.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.
+*/
+
+/dts-v1/;
+
+#include "kirkwood-netxbig.dtsi"
+
+/ {
+ model = "LaCie 2Big NAS";
+ compatible = "lacie,nas2big", "lacie,netxbig", "marvell,kirkwood-88f6282", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ rtc@10300 {
+ /* The on-chip RTC is not powered (no supercap). */
+ status = "disabled";
+ };
+ spi@10600 {
+ /*
+ * A NAND flash is used instead of an SPI flash for
+ * the other netxbig-compatible boards.
+ */
+ status = "disabled";
+ };
+ };
+
+ fan {
+ /*
+ * An I2C fan controller (GMT G762) is used but alarm is
+ * wired to a separate GPIO.
+ */
+ compatible = "gpio-fan";
+ alarm-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
+ };
+
+ regulators: regulators {
+ status = "okay";
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+
+ regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "hdd1power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+ };
+ clocks {
+ g762_clk: g762-oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+
+ /*
+ * An external I2C RTC (Dallas DS1337S+) is used. This allows
+ * to power-up the board on an RTC alarm. The external RTC can
+ * be kept powered, even when the SoC is off.
+ */
+ rtc@68 {
+ compatible = "dallas,ds1307";
+ reg = <0x68>;
+ interrupts = <43>;
+ };
+ g762@3e {
+ compatible = "gmt,g762";
+ reg = <0x3e>;
+ clocks = <&g762_clk>;
+ };
+};
+
+&nand {
+ chip-delay = <50>;
+ status = "okay";
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0x0 0x100000>;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x100000 0x1000000>;
+ };
+
+ partition@1100000 {
+ label = "root";
+ reg = <0x1100000 0x8000000>;
+ };
+
+ partition@9100000 {
+ label = "unused";
+ reg = <0x9100000 0x6f00000>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-net2big.dts b/arch/arm/boot/dts/kirkwood-net2big.dts
new file mode 100644
index 000000000..13a44773b
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-net2big.dts
@@ -0,0 +1,65 @@
+/*
+ * Device Tree file for LaCie 2Big Network v2
+ *
+ * Copyright (C) 2014
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * Based on netxbig_v2-setup.c,
+ * Copyright (C) 2010 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.
+*/
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-netxbig.dtsi"
+
+/ {
+ model = "LaCie 2Big Network v2";
+ compatible = "lacie,net2big_v2", "lacie,netxbig", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ fan {
+ compatible = "gpio-fan";
+ alarm-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&regulators {
+ regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "hdd1power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+ };
+
+ clocks {
+ g762_clk: g762-oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+};
+
+&i2c0 {
+ g762@3e {
+ compatible = "gmt,g762";
+ reg = <0x3e>;
+ clocks = <&g762_clk>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-net5big.dts b/arch/arm/boot/dts/kirkwood-net5big.dts
new file mode 100644
index 000000000..36155b749
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-net5big.dts
@@ -0,0 +1,111 @@
+/*
+ * Device Tree file for LaCie 5Big Network v2
+ *
+ * Copyright (C) 2014
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * Based on netxbig_v2-setup.c,
+ * Copyright (C) 2010 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.
+*/
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-netxbig.dtsi"
+
+/ {
+ model = "LaCie 5Big Network v2";
+ compatible = "lacie,net5big_v2", "lacie,netxbig", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+
+};
+
+&regulators {
+ regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "hdd1power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "hdd2power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "hdd3power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "hdd4power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 11 GPIO_ACTIVE_HIGH>;
+ };
+
+ clocks {
+ g762_clk: g762-oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+};
+
+&mdio {
+ ethphy1: ethernet-phy@1 {
+ reg = <0>;
+ };
+};
+
+&eth1 {
+ status = "okay";
+ ethernet1-port@0 {
+ phy-handle = <&ethphy1>;
+ };
+};
+
+
+&i2c0 {
+ g762@3e {
+ compatible = "gmt,g762";
+ reg = <0x3e>;
+ clocks = <&g762_clk>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts b/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
new file mode 100644
index 000000000..fd733c63b
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
@@ -0,0 +1,253 @@
+/*
+ * Device Tree file for NETGEAR ReadyNAS Duo v2
+ *
+ * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.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.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+
+/ {
+ model = "NETGEAR ReadyNAS Duo v2";
+ compatible = "netgear,readynas-duo-v2", "netgear,readynas", "marvell,kirkwood-88f6282", "marvell,kirkwood";
+
+ memory { /* 256 MB */
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pmx_button_power: pmx-button-power {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+
+ pmx_button_backup: pmx-button-backup {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+
+ pmx_button_reset: pmx-button-reset {
+ marvell,pins = "mpp13";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_power: pmx-led-blue-power {
+ marvell,pins = "mpp31";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_activity: pmx-led-blue-activity {
+ marvell,pins = "mpp38";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_disk1: pmx-led-blue-disk1 {
+ marvell,pins = "mpp23";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_disk2: pmx-led-blue-disk2 {
+ marvell,pins = "mpp22";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_backup: pmx-led-blue-backup {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+
+ pmx_poweroff: pmx-poweroff {
+ marvell,pins = "mpp30";
+ marvell,function = "gpio";
+ };
+ };
+
+ clocks {
+ g762_clk: g762-oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <8192>;
+ };
+ };
+
+ i2c@11000 {
+ status = "okay";
+
+ rs5c372a: rs5c372a@32 {
+ compatible = "ricoh,rs5c372a";
+ reg = <0x32>;
+ };
+
+ g762: g762@3e {
+ compatible = "gmt,g762";
+ reg = <0x3e>;
+ clocks = <&g762_clk>; /* input clock */
+ fan_gear_mode = <0>;
+ fan_startv = <1>;
+ pwm_polarity = <0>;
+ };
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ sata@80000 {
+ status = "okay";
+ nr-ports = <2>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = < &pmx_led_blue_power &pmx_led_blue_activity
+ &pmx_led_blue_disk1 &pmx_led_blue_disk2
+ &pmx_led_blue_backup >;
+ pinctrl-names = "default";
+
+ power_led {
+ label = "status:blue:power_led";
+ gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+
+ activity_led {
+ label = "status:blue:activity_led";
+ gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+ };
+
+ disk1_led {
+ label = "status:blue:disk1_led";
+ gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+ };
+
+ disk2_led {
+ label = "status:blue:disk2_led";
+ gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
+ };
+
+ backup_led {
+ label = "status:blue:backup_led";
+ gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&pmx_button_power &pmx_button_backup
+ &pmx_button_reset>;
+ pinctrl-names = "default";
+
+ power-button {
+ label = "Power Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ };
+
+ reset-button {
+ label = "Reset Button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+ };
+
+ backup-button {
+ label = "Backup Button";
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ pinctrl-0 = <&pmx_poweroff>;
+ pinctrl-names = "default";
+ gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb3_regulator: usb3-regulator {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "USB 3.0 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x180000>;
+ read-only;
+ };
+
+ partition@180000 {
+ label = "u-boot-env";
+ reg = <0x180000 0x20000>;
+ };
+
+ partition@200000 {
+ label = "uImage";
+ reg = <0x0200000 0x600000>;
+ };
+
+ partition@800000 {
+ label = "minirootfs";
+ reg = <0x0800000 0x1000000>;
+ };
+
+ partition@1800000 {
+ label = "jffs2";
+ reg = <0x1800000 0x6800000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 { /* Marvell 88E1318 */
+ reg = <0>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-netgear_readynas_nv+_v2.dts b/arch/arm/boot/dts/kirkwood-netgear_readynas_nv+_v2.dts
new file mode 100644
index 000000000..b514d643f
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-netgear_readynas_nv+_v2.dts
@@ -0,0 +1,267 @@
+/*
+ * Device Tree file for NETGEAR ReadyNAS NV+ v2
+ *
+ * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.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.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+
+/ {
+ model = "NETGEAR ReadyNAS NV+ v2";
+ compatible = "netgear,readynas-nv+-v2", "netgear,readynas", "marvell,kirkwood-88f6282", "marvell,kirkwood";
+
+ memory { /* 256 MB */
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ /* Connected to NEC uPD720200 USB 3.0 controller */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pmx_button_power: pmx-button-power {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+
+ pmx_button_backup: pmx-button-backup {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+
+ pmx_button_reset: pmx-button-reset {
+ marvell,pins = "mpp13";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_power: pmx-led-blue-power {
+ marvell,pins = "mpp31";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_backup: pmx-led-blue-backup {
+ marvell,pins = "mpp22";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_disk1: pmx-led-blue-disk1 {
+ marvell,pins = "mpp20";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_disk2: pmx-led-blue-disk2 {
+ marvell,pins = "mpp23";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_disk3: pmx-led-blue-disk3 {
+ marvell,pins = "mpp24";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_disk4: pmx-led-blue-disk4 {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+
+ pmx_poweroff: pmx-poweroff {
+ marvell,pins = "mpp30";
+ marvell,function = "gpio";
+ };
+ };
+
+ clocks {
+ g762_clk: g762-oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <8192>;
+ };
+ };
+
+ i2c@11000 {
+ status = "okay";
+
+ rs5c372a: rs5c372a@32 {
+ compatible = "ricoh,rs5c372a";
+ reg = <0x32>;
+ };
+
+ g762: g762@3e {
+ compatible = "gmt,g762";
+ reg = <0x3e>;
+ clocks = <&g762_clk>; /* input clock */
+ fan_gear_mode = <0>;
+ fan_startv = <1>;
+ pwm_polarity = <0>;
+ };
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ sata@80000 { /* Connected to Marvell 88SM4140 SATA port multiplier */
+ status = "okay";
+ nr-ports = <1>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = < &pmx_led_blue_power &pmx_led_blue_backup
+ &pmx_led_blue_disk1 &pmx_led_blue_disk2
+ &pmx_led_blue_disk3 &pmx_led_blue_disk3 >;
+ pinctrl-names = "default";
+
+ power_led {
+ label = "status:blue:power_led";
+ gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+
+ backup_led {
+ label = "status:blue:backup_led";
+ gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
+ };
+
+ disk1_led {
+ label = "status:blue:disk1_led";
+ gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+ };
+
+ disk2_led {
+ label = "status:blue:disk2_led";
+ gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+ };
+
+ disk3_led {
+ label = "status:blue:disk3_led";
+ gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
+ };
+
+ disk4_led {
+ label = "status:blue:disk4_led";
+ gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&pmx_button_power &pmx_button_backup
+ &pmx_button_reset>;
+ pinctrl-names = "default";
+
+ power-button {
+ label = "Power Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ };
+
+ reset-button {
+ label = "Reset Button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+ };
+
+ backup-button {
+ label = "Backup Button";
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ pinctrl-0 = <&pmx_poweroff>;
+ pinctrl-names = "default";
+ gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb3_regulator: usb3-regulator {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "USB 3.0 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x180000>;
+ read-only;
+ };
+
+ partition@180000 {
+ label = "u-boot-env";
+ reg = <0x180000 0x20000>;
+ };
+
+ partition@200000 {
+ label = "uImage";
+ reg = <0x0200000 0x600000>;
+ };
+
+ partition@800000 {
+ label = "minirootfs";
+ reg = <0x0800000 0x1000000>;
+ };
+
+ partition@1800000 {
+ label = "jffs2";
+ reg = <0x1800000 0x6800000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 { /* Marvell 88E1318 */
+ device_type = "ethernet-phy";
+ reg = <0>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-netxbig.dtsi b/arch/arm/boot/dts/kirkwood-netxbig.dtsi
new file mode 100644
index 000000000..b0cfb7cd3
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-netxbig.dtsi
@@ -0,0 +1,154 @@
+/*
+ * Device Tree common file for LaCie 2Big and 5Big Network v2
+ *
+ * Copyright (C) 2014
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * Based on netxbig_v2-setup.c,
+ * Copyright (C) 2010 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 "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ ocp@f1000000 {
+ serial@12000 {
+ status = "okay";
+ };
+
+ spi@10600 {
+ status = "okay";
+
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mxicy,mx25l4005a";
+ reg = <0>;
+ spi-max-frequency = <20000000>;
+ mode = <0>;
+
+ partition@0 {
+ reg = <0x0 0x80000>;
+ label = "u-boot";
+ };
+ };
+ };
+
+ sata@80000 {
+ status = "okay";
+ nr-ports = <2>;
+ };
+
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /*
+ * button@1 and button@2 represent a three position rocker
+ * switch. Thus the conventional KEY_POWER does not fit
+ */
+ button@1 {
+ label = "Back power switch (on|auto)";
+ linux,code = <KEY_ESC>;
+ linux,input-type = <5>;
+ gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+ };
+ button@2 {
+ label = "Back power switch (auto|off)";
+ linux,code = <KEY_1>;
+ linux,input-type = <5>;
+ gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
+ };
+ button@3 {
+ label = "Function button";
+ linux,code = <KEY_OPTION>;
+ gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ };
+
+ };
+
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulators: regulators {
+ status = "okay";
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+
+ regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "hdd0power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 16 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <8>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ reg = <0>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
+
+&pinctrl {
+ pinctrl-names = "default";
+
+ pmx_button_function: pmx-button-function {
+ marvell,pins = "mpp34";
+ marvell,function = "gpio";
+ };
+ pmx_button_power_off: pmx-button-power-off {
+ marvell,pins = "mpp15";
+ marvell,function = "gpio";
+ };
+ pmx_button_power_on: pmx-button-power-on {
+ marvell,pins = "mpp13";
+ marvell,function = "gpio";
+ };
+};
+
+&i2c0 {
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "atmel,24c04";
+ pagesize = <16>;
+ reg = <0x50>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi
new file mode 100644
index 000000000..fe6c0246d
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi
@@ -0,0 +1,96 @@
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pmx_ns2_sata0: pmx-ns2-sata0 {
+ marvell,pins = "mpp21";
+ marvell,function = "sata0";
+ };
+ pmx_ns2_sata1: pmx-ns2-sata1 {
+ marvell,pins = "mpp20";
+ marvell,function = "sata1";
+ };
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ spi@10600 {
+ status = "okay";
+
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mxicy,mx25l4005a";
+ reg = <0>;
+ spi-max-frequency = <20000000>;
+ mode = <0>;
+
+ partition@0 {
+ reg = <0x0 0x80000>;
+ label = "u-boot";
+ };
+ };
+ };
+
+ i2c@11000 {
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "atmel,24c04";
+ pagesize = <16>;
+ reg = <0x50>;
+ };
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@1 {
+ label = "Power push button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ red-fail {
+ label = "ns2:red:fail";
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio_poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
+ };
+
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy {
+ /* overwrite reg property in board file */
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-ns2.dts b/arch/arm/boot/dts/kirkwood-ns2.dts
new file mode 100644
index 000000000..53368d102
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ns2.dts
@@ -0,0 +1,34 @@
+/dts-v1/;
+
+#include "kirkwood-ns2-common.dtsi"
+
+/ {
+ model = "LaCie Network Space v2";
+ compatible = "lacie,netspace_v2", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ ocp@f1000000 {
+ sata@80000 {
+ pinctrl-0 = <&pmx_ns2_sata0>;
+ pinctrl-names = "default";
+ status = "okay";
+ nr-ports = <1>;
+ };
+ };
+
+ ns2-leds {
+ compatible = "lacie,ns2-leds";
+
+ blue-sata {
+ label = "ns2:blue:sata";
+ slow-gpio = <&gpio0 29 0>;
+ cmd-gpio = <&gpio0 30 0>;
+ };
+ };
+};
+
+&ethphy0 { reg = <8>; };
diff --git a/arch/arm/boot/dts/kirkwood-ns2lite.dts b/arch/arm/boot/dts/kirkwood-ns2lite.dts
new file mode 100644
index 000000000..1f2ca60d8
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ns2lite.dts
@@ -0,0 +1,34 @@
+/dts-v1/;
+
+#include "kirkwood-ns2-common.dtsi"
+
+/ {
+ model = "LaCie Network Space Lite v2";
+ compatible = "lacie,netspace_lite_v2", "marvell,kirkwood-88f6192", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ ocp@f1000000 {
+ sata@80000 {
+ pinctrl-0 = <&pmx_ns2_sata0>;
+ pinctrl-names = "default";
+ status = "okay";
+ nr-ports = <1>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ blue-sata {
+ label = "ns2:blue:sata";
+ gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "ide-disk";
+ };
+ };
+};
+
+&ethphy0 { reg = <0>; };
diff --git a/arch/arm/boot/dts/kirkwood-ns2max.dts b/arch/arm/boot/dts/kirkwood-ns2max.dts
new file mode 100644
index 000000000..72c78d0b1
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ns2max.dts
@@ -0,0 +1,53 @@
+/dts-v1/;
+
+#include "kirkwood-ns2-common.dtsi"
+
+/ {
+ model = "LaCie Network Space Max v2";
+ compatible = "lacie,netspace_max_v2", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ ocp@f1000000 {
+ sata@80000 {
+ pinctrl-0 = <&pmx_ns2_sata0 &pmx_ns2_sata1>;
+ pinctrl-names = "default";
+ status = "okay";
+ nr-ports = <2>;
+ };
+ };
+
+ gpio_fan {
+ compatible = "gpio-fan";
+ gpios = <&gpio0 22 GPIO_ACTIVE_LOW
+ &gpio0 7 GPIO_ACTIVE_LOW
+ &gpio1 1 GPIO_ACTIVE_LOW
+ &gpio0 23 GPIO_ACTIVE_LOW>;
+ gpio-fan,speed-map =
+ < 0 0
+ 1500 15
+ 1700 14
+ 1800 13
+ 2100 12
+ 3100 11
+ 3300 10
+ 4300 9
+ 5500 8>;
+ alarm-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
+ };
+
+ ns2-leds {
+ compatible = "lacie,ns2-leds";
+
+ blue-sata {
+ label = "ns2:blue:sata";
+ slow-gpio = <&gpio0 29 0>;
+ cmd-gpio = <&gpio0 30 0>;
+ };
+ };
+};
+
+&ethphy0 { reg = <8>; };
diff --git a/arch/arm/boot/dts/kirkwood-ns2mini.dts b/arch/arm/boot/dts/kirkwood-ns2mini.dts
new file mode 100644
index 000000000..c441bf62c
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ns2mini.dts
@@ -0,0 +1,54 @@
+/dts-v1/;
+
+#include "kirkwood-ns2-common.dtsi"
+
+/ {
+ /* This machine is embedded in the first LaCie CloudBox product. */
+ model = "LaCie Network Space Mini v2";
+ compatible = "lacie,netspace_mini_v2", "marvell,kirkwood-88f6192", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ ocp@f1000000 {
+ sata@80000 {
+ pinctrl-0 = <&pmx_ns2_sata0>;
+ pinctrl-names = "default";
+ status = "okay";
+ nr-ports = <1>;
+ };
+ };
+
+ gpio_fan {
+ compatible = "gpio-fan";
+ gpios = <&gpio0 22 GPIO_ACTIVE_LOW
+ &gpio0 7 GPIO_ACTIVE_LOW
+ &gpio1 1 GPIO_ACTIVE_LOW
+ &gpio0 23 GPIO_ACTIVE_LOW>;
+ gpio-fan,speed-map =
+ < 0 0
+ 3000 15
+ 3180 14
+ 4140 13
+ 4570 12
+ 6760 11
+ 7140 10
+ 7980 9
+ 9200 8>;
+ alarm-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
+ };
+
+ ns2-leds {
+ compatible = "lacie,ns2-leds";
+
+ blue-sata {
+ label = "ns2:blue:sata";
+ slow-gpio = <&gpio0 29 0>;
+ cmd-gpio = <&gpio0 30 0>;
+ };
+ };
+};
+
+&ethphy0 { reg = <0>; };
diff --git a/arch/arm/boot/dts/kirkwood-nsa310.dts b/arch/arm/boot/dts/kirkwood-nsa310.dts
new file mode 100644
index 000000000..6139df0f3
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-nsa310.dts
@@ -0,0 +1,140 @@
+/dts-v1/;
+
+#include "kirkwood-nsa3x0-common.dtsi"
+
+/ {
+ compatible = "zyxel,nsa310", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ stdout-path = &uart0;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pinctrl-0 = <&pmx_unknown>;
+ pinctrl-names = "default";
+
+ pmx_led_esata_green: pmx-led-esata-green {
+ marvell,pins = "mpp12";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_esata_red: pmx-led-esata-red {
+ marvell,pins = "mpp13";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_usb_green: pmx-led-usb-green {
+ marvell,pins = "mpp15";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_usb_red: pmx-led-usb-red {
+ marvell,pins = "mpp16";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_sys_green: pmx-led-sys-green {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_sys_red: pmx-led-sys-red {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_hdd_green: pmx-led-hdd-green {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_hdd_red: pmx-led-hdd-red {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+
+ pmx_unknown: pmx-unknown {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+
+ };
+
+ i2c@11000 {
+ status = "okay";
+
+ adt7476: adt7476a@2e {
+ compatible = "adi,adt7476";
+ reg = <0x2e>;
+ };
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_led_esata_green &pmx_led_esata_red
+ &pmx_led_usb_green &pmx_led_usb_red
+ &pmx_led_sys_green &pmx_led_sys_red
+ &pmx_led_copy_green &pmx_led_copy_red
+ &pmx_led_hdd_green &pmx_led_hdd_red>;
+ pinctrl-names = "default";
+
+ green-sys {
+ label = "nsa310:green:sys";
+ gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+ };
+ red-sys {
+ label = "nsa310:red:sys";
+ gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+ };
+ green-hdd {
+ label = "nsa310:green:hdd";
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ };
+ red-hdd {
+ label = "nsa310:red:hdd";
+ gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+ };
+ green-esata {
+ label = "nsa310:green:esata";
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ };
+ red-esata {
+ label = "nsa310:red:esata";
+ gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+ };
+ green-usb {
+ label = "nsa310:green:usb";
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
+ };
+ red-usb {
+ label = "nsa310:red:usb";
+ gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
+ };
+ green-copy {
+ label = "nsa310:green:copy";
+ gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ };
+ red-copy {
+ label = "nsa310:red:copy";
+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-nsa310a.dts b/arch/arm/boot/dts/kirkwood-nsa310a.dts
new file mode 100644
index 000000000..3d2b3d494
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-nsa310a.dts
@@ -0,0 +1,114 @@
+/dts-v1/;
+
+#include "kirkwood-nsa3x0-common.dtsi"
+
+/*
+ * There are at least two different NSA310 designs. This variant does
+ * not have the red USB Led.
+ */
+
+/ {
+ compatible = "zyxel,nsa310a", "zyxel,nsa310", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ stdout-path = &uart0;
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pinctrl-names = "default";
+
+ pmx_led_esata_green: pmx-led-esata-green {
+ marvell,pins = "mpp12";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_esata_red: pmx-led-esata-red {
+ marvell,pins = "mpp13";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_usb_green: pmx-led-usb-green {
+ marvell,pins = "mpp15";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_sys_green: pmx-led-sys-green {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_sys_red: pmx-led-sys-red {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_hdd_green: pmx-led-hdd-green {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_hdd_red: pmx-led-hdd-red {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+
+ };
+
+ i2c@11000 {
+ status = "okay";
+
+ lm85: lm85@2e {
+ compatible = "national,lm85";
+ reg = <0x2e>;
+ };
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ green-sys {
+ label = "nsa310:green:sys";
+ gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+ };
+ red-sys {
+ label = "nsa310:red:sys";
+ gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+ };
+ green-hdd {
+ label = "nsa310:green:hdd";
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ };
+ red-hdd {
+ label = "nsa310:red:hdd";
+ gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+ };
+ green-esata {
+ label = "nsa310:green:esata";
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ };
+ red-esata {
+ label = "nsa310:red:esata";
+ gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+ };
+ green-usb {
+ label = "nsa310:green:usb";
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
+ };
+ green-copy {
+ label = "nsa310:green:copy";
+ gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ };
+ red-copy {
+ label = "nsa310:red:copy";
+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-nsa320.dts b/arch/arm/boot/dts/kirkwood-nsa320.dts
new file mode 100644
index 000000000..24f686d10
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-nsa320.dts
@@ -0,0 +1,215 @@
+/* Device tree file for the Zyxel NSA 320 NAS box.
+ *
+ * Copyright (c) 2014, Adam Baker <linux@baker-net.org.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.
+ *
+ * Based upon the board setup file created by Peter Schildmann */
+
+/dts-v1/;
+
+#include "kirkwood-nsa3x0-common.dtsi"
+
+/ {
+ model = "Zyxel NSA320";
+ compatible = "zyxel,nsa320", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ stdout-path = &uart0;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pinctrl-names = "default";
+
+ /* SATA Activity and Present pins are not connected */
+ pmx_sata0: pmx-sata0 {
+ marvell,pins ;
+ marvell,function = "sata0";
+ };
+
+ pmx_sata1: pmx-sata1 {
+ marvell,pins ;
+ marvell,function = "sata1";
+ };
+
+ pmx_led_hdd2_green: pmx-led-hdd2-green {
+ marvell,pins = "mpp12";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_hdd2_red: pmx-led-hdd2-red {
+ marvell,pins = "mpp13";
+ marvell,function = "gpio";
+ };
+
+ pmx_mcu_data: pmx-mcu-data {
+ marvell,pins = "mpp14";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_usb_green: pmx-led-usb-green {
+ marvell,pins = "mpp15";
+ marvell,function = "gpio";
+ };
+
+ pmx_mcu_clk: pmx-mcu-clk {
+ marvell,pins = "mpp16";
+ marvell,function = "gpio";
+ };
+
+ pmx_mcu_act: pmx-mcu-act {
+ marvell,pins = "mpp17";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_sys_green: pmx-led-sys-green {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_sys_orange: pmx-led-sys-orange {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_hdd1_green: pmx-led-hdd1-green {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_hdd1_red: pmx-led-hdd1-red {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+
+ pmx_htp: pmx-htp {
+ marvell,pins = "mpp43";
+ marvell,function = "gpio";
+ };
+
+ /* Buzzer needs to be switched at around 1kHz so is
+ not compatible with the gpio-beeper driver. */
+ pmx_buzzer: pmx-buzzer {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+
+ pmx_vid_b1: pmx-vid-b1 {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+
+ pmx_power_resume_data: pmx-power-resume-data {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+
+ pmx_power_resume_clk: pmx-power-resume-clk {
+ marvell,pins = "mpp49";
+ marvell,function = "gpio";
+ };
+ };
+
+ i2c@11000 {
+ status = "okay";
+
+ pcf8563: pcf8563@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+ };
+ };
+
+ regulators {
+ usb0_power: regulator@1 {
+ enable-active-high;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_led_hdd2_green &pmx_led_hdd2_red
+ &pmx_led_usb_green
+ &pmx_led_sys_green &pmx_led_sys_orange
+ &pmx_led_copy_green &pmx_led_copy_red
+ &pmx_led_hdd1_green &pmx_led_hdd1_red>;
+ pinctrl-names = "default";
+
+ green-sys {
+ label = "nsa320:green:sys";
+ gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+ };
+ orange-sys {
+ label = "nsa320:orange:sys";
+ gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+ };
+ green-hdd1 {
+ label = "nsa320:green:hdd1";
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ };
+ red-hdd1 {
+ label = "nsa320:red:hdd1";
+ gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+ };
+ green-hdd2 {
+ label = "nsa320:green:hdd2";
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ };
+ red-hdd2 {
+ label = "nsa320:red:hdd2";
+ gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+ };
+ green-usb {
+ label = "nsa320:green:usb";
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
+ };
+ green-copy {
+ label = "nsa320:green:copy";
+ gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ };
+ red-copy {
+ label = "nsa320:red:copy";
+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ /* The following pins are currently not assigned to a driver,
+ some of them should be configured as inputs.
+ pinctrl-0 = <&pmx_mcu_data &pmx_mcu_clk &pmx_mcu_act
+ &pmx_htp &pmx_vid_b1
+ &pmx_power_resume_data &pmx_power_resume_clk>; */
+};
+
+&mdio {
+ status = "okay";
+ ethphy0: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-nsa3x0-common.dtsi b/arch/arm/boot/dts/kirkwood-nsa3x0-common.dtsi
new file mode 100644
index 000000000..2075a2e82
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-nsa3x0-common.dtsi
@@ -0,0 +1,159 @@
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "ZyXEL NSA310";
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+
+ pmx_usb_power: pmx-usb-power {
+ marvell,pins = "mpp21";
+ marvell,function = "gpio";
+ };
+
+ pmx_pwr_off: pmx-pwr-off {
+ marvell,pins = "mpp48";
+ marvell,function = "gpio";
+ };
+
+ pmx_btn_reset: pmx-btn-reset {
+ marvell,pins = "mpp36";
+ marvell,function = "gpio";
+ };
+
+ pmx_btn_copy: pmx-btn-copy {
+ marvell,pins = "mpp37";
+ marvell,function = "gpio";
+ };
+
+ pmx_btn_power: pmx-btn-power {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_copy_green: pmx-led-copy-green {
+ marvell,pins = "mpp39";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_copy_red: pmx-led-copy-red {
+ marvell,pins = "mpp40";
+ marvell,function = "gpio";
+ };
+ };
+
+ serial@12000 {
+ status = "ok";
+ };
+
+ sata@80000 {
+ status = "okay";
+ nr-ports = <2>;
+ };
+ };
+
+ gpio_poweroff {
+ compatible = "gpio-poweroff";
+ pinctrl-0 = <&pmx_pwr_off>;
+ pinctrl-names = "default";
+ gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_btn_reset &pmx_btn_copy &pmx_btn_power>;
+ pinctrl-names = "default";
+
+ button@1 {
+ label = "Power Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+ };
+ button@2 {
+ label = "Copy Button";
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+ };
+ button@3 {
+ label = "Reset Button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_usb_power>;
+ pinctrl-names = "default";
+
+ usb0_power: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "USB Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 21 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&nand {
+ status = "okay";
+ chip-delay = <35>;
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x0000000 0x0100000>;
+ read-only;
+ };
+ partition@100000 {
+ label = "uboot_env";
+ reg = <0x0100000 0x0080000>;
+ };
+ partition@180000 {
+ label = "key_store";
+ reg = <0x0180000 0x0080000>;
+ };
+ partition@200000 {
+ label = "info";
+ reg = <0x0200000 0x0080000>;
+ };
+ partition@280000 {
+ label = "etc";
+ reg = <0x0280000 0x0a00000>;
+ };
+ partition@c80000 {
+ label = "kernel_1";
+ reg = <0x0c80000 0x0a00000>;
+ };
+ partition@1680000 {
+ label = "rootfs1";
+ reg = <0x1680000 0x2fc0000>;
+ };
+ partition@4640000 {
+ label = "kernel_2";
+ reg = <0x4640000 0x0a00000>;
+ };
+ partition@5040000 {
+ label = "rootfs2";
+ reg = <0x5040000 0x2fc0000>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts
new file mode 100644
index 000000000..fb9dc2272
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts
@@ -0,0 +1,176 @@
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+
+/ {
+ model = "Plat'Home OpenBlocksA6";
+ compatible = "plathome,openblocks-a6", "marvell,kirkwood-88f6283", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ ocp@f1000000 {
+ serial@12000 {
+ status = "okay";
+ };
+
+ serial@12100 {
+ status = "okay";
+ };
+
+ sata@80000 {
+ nr-ports = <1>;
+ status = "okay";
+ };
+
+ i2c@11100 {
+ status = "okay";
+
+ s35390a: s35390a@30 {
+ compatible = "sii,s35390a";
+ reg = <0x30>;
+ };
+ };
+
+ pinctrl: pin-controller@10000 {
+ pinctrl-0 = <&pmx_dip_switches &pmx_gpio_header>;
+ pinctrl-names = "default";
+
+ pmx_uart0: pmx-uart0 {
+ marvell,pins = "mpp10", "mpp11", "mpp15",
+ "mpp16";
+ marvell,function = "uart0";
+ };
+
+ pmx_uart1: pmx-uart1 {
+ marvell,pins = "mpp13", "mpp14", "mpp8",
+ "mpp9";
+ marvell,function = "uart1";
+ };
+
+ pmx_sysrst: pmx-sysrst {
+ marvell,pins = "mpp6";
+ marvell,function = "sysrst";
+ };
+
+ pmx_dip_switches: pmx-dip-switches {
+ marvell,pins = "mpp20", "mpp21", "mpp22", "mpp23";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_header: pmx-gpio-header {
+ marvell,pins = "mpp24", "mpp25", "mpp26", "mpp27",
+ "mpp28", "mpp29", "mpp30", "mpp31";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_init: pmx-init {
+ marvell,pins = "mpp38";
+ marvell,function = "gpio";
+ };
+
+ pmx_usb_oc: pmx-usb-oc {
+ marvell,pins = "mpp39";
+ marvell,function = "gpio";
+ };
+
+ pmx_leds: pmx-leds {
+ marvell,pins = "mpp41", "mpp42", "mpp43";
+ marvell,function = "gpio";
+ };
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_leds>;
+ pinctrl-names = "default";
+
+ led-red {
+ label = "obsa6:red:stat";
+ gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ };
+
+ led-green {
+ label = "obsa6:green:stat";
+ gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+ };
+
+ led-yellow {
+ label = "obsa6:yellow:stat";
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&pmx_gpio_init>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@1 {
+ label = "Init Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&nand {
+ chip-delay = <25>;
+ status = "okay";
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x0 0x90000>;
+ };
+
+ partition@90000 {
+ label = "env";
+ reg = <0x90000 0x44000>;
+ };
+
+ partition@d4000 {
+ label = "test";
+ reg = <0xd4000 0x24000>;
+ };
+
+ partition@f4000 {
+ label = "conf";
+ reg = <0xf4000 0x400000>;
+ };
+
+ partition@4f4000 {
+ label = "linux";
+ reg = <0x4f4000 0x1d20000>;
+ };
+
+ partition@2214000 {
+ label = "user";
+ reg = <0x2214000 0x1dec000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-openblocks_a7.dts b/arch/arm/boot/dts/kirkwood-openblocks_a7.dts
new file mode 100644
index 000000000..d5e3bc518
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-openblocks_a7.dts
@@ -0,0 +1,205 @@
+/*
+ * Device Tree file for OpenBlocks A7 board
+ *
+ * Copyright (C) 2013 Free Electrons
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+
+/ {
+ model = "Plat'Home OpenBlocksA7";
+ compatible = "plathome,openblocks-a7", "marvell,kirkwood-88f6283", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>; /* 1 GB */
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ ocp@f1000000 {
+ serial@12000 {
+ status = "okay";
+ };
+
+ serial@12100 {
+ status = "okay";
+ };
+
+ sata@80000 {
+ nr-ports = <1>;
+ status = "okay";
+ };
+
+ i2c@11100 {
+ status = "okay";
+
+ s24c02: s24c02@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ };
+ };
+
+ pinctrl: pin-controller@10000 {
+ pinctrl-0 = <&pmx_dip_switches &pmx_gpio_header>;
+ pinctrl-names = "default";
+
+ pmx_uart0: pmx-uart0 {
+ marvell,pins = "mpp10", "mpp11", "mpp15",
+ "mpp16";
+ marvell,function = "uart0";
+ };
+
+ pmx_uart1: pmx-uart1 {
+ marvell,pins = "mpp13", "mpp14", "mpp8",
+ "mpp9";
+ marvell,function = "uart1";
+ };
+
+ pmx_sysrst: pmx-sysrst {
+ marvell,pins = "mpp6";
+ marvell,function = "sysrst";
+ };
+
+ pmx_dip_switches: pmx-dip-switches {
+ marvell,pins = "mpp44", "mpp45", "mpp46", "mpp47";
+ marvell,function = "gpio";
+ };
+
+ /*
+ * Accessible on connector J202. The MPP
+ * listed below are pin 1-7, pin 8 is unused,
+ * pin 9 is external reset input and pin 10 is
+ * ground.
+ */
+ pmx_gpio_header: pmx-gpio-header {
+ marvell,pins = "mpp17", "mpp7", "mpp29", "mpp28",
+ "mpp35", "mpp34", "mpp40";
+ marvell,function = "gpio";
+ };
+
+ pmx_gpio_init: pmx-init {
+ marvell,pins = "mpp38";
+ marvell,function = "gpio";
+ };
+
+ pmx_usb_oc: pmx-usb-oc {
+ marvell,pins = "mpp39";
+ marvell,function = "gpio";
+ };
+
+ pmx_leds: pmx-leds {
+ marvell,pins = "mpp41", "mpp42", "mpp43";
+ marvell,function = "gpio";
+ };
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_leds>;
+ pinctrl-names = "default";
+
+ led-red {
+ label = "obsa7:red:stat";
+ gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ };
+
+ led-green {
+ label = "obsa7:green:stat";
+ gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+ };
+
+ led-yellow {
+ label = "obsa7:yellow:stat";
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&pmx_gpio_init>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@1 {
+ label = "Init Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&nand {
+ chip-delay = <25>;
+ status = "okay";
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x0 0x1c0000>;
+ };
+
+ partition@1c0000 {
+ label = "env";
+ reg = <0x1c0000 0x2c0000>;
+ };
+
+ partition@480000 {
+ label = "test";
+ reg = <0x480000 0x160000>;
+ };
+
+ partition@5e0000 {
+ label = "conf";
+ reg = <0x5e0000 0x540000>;
+ };
+
+ partition@b20000 {
+ label = "linux";
+ reg = <0xb20000 0x3d40000>;
+ };
+
+ partition@4860000 {
+ label = "user";
+ reg = <0x4860000 0xb7a0000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
+
+&eth1 {
+ status = "okay";
+ ethernet1-port@0 {
+ phy-handle = <&ethphy1>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-openrd-base.dts b/arch/arm/boot/dts/kirkwood-openrd-base.dts
new file mode 100644
index 000000000..8af589996
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-openrd-base.dts
@@ -0,0 +1,42 @@
+/*
+ * Marvell OpenRD Base Board Description
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms 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 file contains the definitions that are specific to OpenRD
+ * base variant of the Marvell Kirkwood Development Board.
+ */
+
+/dts-v1/;
+
+#include "kirkwood-openrd.dtsi"
+
+/ {
+ model = "OpenRD Base";
+ compatible = "marvell,openrd-base", "marvell,openrd", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ ocp@f1000000 {
+ serial@12100 {
+ status = "okay";
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@8 {
+ reg = <8>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-openrd-client.dts b/arch/arm/boot/dts/kirkwood-openrd-client.dts
new file mode 100644
index 000000000..887b9c1fe
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-openrd-client.dts
@@ -0,0 +1,73 @@
+/*
+ * Marvell OpenRD Client Board Description
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms 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 file contains the definitions that are specific to OpenRD
+ * client variant of the Marvell Kirkwood Development Board.
+ */
+
+/dts-v1/;
+
+#include "kirkwood-openrd.dtsi"
+
+/ {
+ model = "OpenRD Client";
+ compatible = "marvell,openrd-client", "marvell,openrd", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ ocp@f1000000 {
+ i2c@11000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ cs42l51: cs42l51@4a {
+ compatible = "cirrus,cs42l51";
+ reg = <0x4a>;
+ };
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,mclk-fs = <256>;
+
+ simple-audio-card,cpu {
+ sound-dai = <&audio0>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&cs42l51>;
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@8 {
+ reg = <8>;
+ };
+ ethphy1: ethernet-phy@24 {
+ reg = <24>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
+
+&eth1 {
+ status = "okay";
+ ethernet1-port@0 {
+ phy-handle = <&ethphy1>;
+ };
+};
+
diff --git a/arch/arm/boot/dts/kirkwood-openrd-ultimate.dts b/arch/arm/boot/dts/kirkwood-openrd-ultimate.dts
new file mode 100644
index 000000000..9f12f8b53
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-openrd-ultimate.dts
@@ -0,0 +1,58 @@
+/*
+ * Marvell OpenRD Ultimate Board Description
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms 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 file contains the definitions that are specific to OpenRD
+ * ultimate variant of the Marvell Kirkwood Development Board.
+ */
+
+/dts-v1/;
+
+#include "kirkwood-openrd.dtsi"
+
+/ {
+ model = "OpenRD Ultimate";
+ compatible = "marvell,openrd-ultimate", "marvell,openrd", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ ocp@f1000000 {
+ i2c@11000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ cs42l51: cs42l51@4a {
+ compatible = "cirrus,cs42l51";
+ reg = <0x4a>;
+ };
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ ethphy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
+
+&eth1 {
+ status = "okay";
+ ethernet1-port@0 {
+ phy-handle = <&ethphy1>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-openrd.dtsi b/arch/arm/boot/dts/kirkwood-openrd.dtsi
new file mode 100644
index 000000000..d3330dadf
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-openrd.dtsi
@@ -0,0 +1,90 @@
+/*
+ * Marvell OpenRD (Base|Client|Ultimate) Board Description
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms 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 file contains the definitions that are common between the three
+ * variants of the Marvell Kirkwood Development Board.
+ */
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pinctrl-0 = <&pmx_select28 &pmx_sdio_cd &pmx_select34>;
+ pinctrl-names = "default";
+
+ pmx_select28: pmx-select-uart-sd {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+ pmx_sdio_cd: pmx-sdio-cd {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+ pmx_select34: pmx-select-rs232-rs484 {
+ marvell,pins = "mpp34";
+ marvell,function = "gpio";
+ };
+ };
+ serial@12000 {
+ status = "okay";
+
+ };
+ sata@80000 {
+ status = "okay";
+ nr-ports = <2>;
+ };
+ mvsdio@90000 {
+ status = "okay";
+ cd-gpios = <&gpio0 29 9>;
+ };
+ };
+};
+
+&nand {
+ status = "okay";
+ pinctrl-0 = <&pmx_nand>;
+ pinctrl-names = "default";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x100000>;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x0100000 0x400000>;
+ };
+
+ partition@600000 {
+ label = "root";
+ reg = <0x0600000 0x1FA00000>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-pogo_e02.dts b/arch/arm/boot/dts/kirkwood-pogo_e02.dts
new file mode 100644
index 000000000..a190080c9
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-pogo_e02.dts
@@ -0,0 +1,134 @@
+/*
+ * kirkwood-pogo_e02.dts - Device tree file for Pogoplug E02
+ *
+ * Copyright (C) 2015 Christoph Junghans <ottxor@gentoo.org>
+ *
+ * based on information of dts files from
+ * Arch Linux ARM by Oleg Rakhmanov <moonman.ca@gmail.com>
+ * OpenWrt by Felix Kaechele <heffer@fedoraproject.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.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "Cloud Engines Pogoplug E02";
+ compatible = "cloudengines,pogoe02", "marvell,kirkwood-88f6281",
+ "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ health {
+ label = "pogo_e02:green:health";
+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+ fault {
+ label = "pogo_e02:orange:fault";
+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_usb_power_enable>;
+ pinctrl-names = "default";
+
+ usb_power: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "USB Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&pinctrl {
+ pinctrl-0 = < &pmx_usb_power_enable &pmx_led_orange
+ &pmx_led_green >;
+ pinctrl-names = "default";
+
+ pmx_usb_power_enable: pmx-usb-power-enable {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_green: pmx-led-green {
+ marvell,pins = "mpp48";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_orange: pmx-led-orange {
+ marvell,pins = "mpp49";
+ marvell,function = "gpio";
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&nand {
+ chip-delay = <40>;
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x0100000 0x400000>;
+ };
+
+ partition@500000 {
+ label = "pogoplug";
+ reg = <0x0500000 0x2000000>;
+ };
+
+ partition@2500000 {
+ label = "root";
+ reg = <0x02500000 0x5b00000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-rd88f6192.dts b/arch/arm/boot/dts/kirkwood-rd88f6192.dts
new file mode 100644
index 000000000..35a29dee8
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-rd88f6192.dts
@@ -0,0 +1,111 @@
+/*
+ * Marvell RD88F6192 Board descrition
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms 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 file contains the definitions that are common between the three
+ * variants of the Marvell Kirkwood Development Board.
+ */
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6192.dtsi"
+
+/ {
+ model = "Marvell RD88F6192 reference design";
+ compatible = "marvell,rd88f6192", "marvell,kirkwood-88f6192", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pinctrl-0 = <&pmx_usb_power>;
+ pinctrl-names = "default";
+
+ pmx_usb_power: pmx-usb-power {
+ marvell,pins = "mpp10";
+ marvell,function = "gpo";
+ };
+ };
+
+ serial@12000 {
+ status = "okay";
+
+ };
+
+ spi@10600 {
+ status = "okay";
+
+ m25p128@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p128";
+ reg = <0>;
+ spi-max-frequency = <20000000>;
+ mode = <0>;
+ };
+ };
+
+ sata@80000 {
+ status = "okay";
+ nr-ports = <2>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_usb_power>;
+ pinctrl-names = "default";
+
+ usb_power: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "USB VBUS";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 10 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@8 {
+ reg = <8>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+}; \ No newline at end of file
diff --git a/arch/arm/boot/dts/kirkwood-rd88f6281-a.dts b/arch/arm/boot/dts/kirkwood-rd88f6281-a.dts
new file mode 100644
index 000000000..f2e08b3b3
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-rd88f6281-a.dts
@@ -0,0 +1,43 @@
+/*
+ * Marvell RD88F6181 A Board descrition
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms 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 file contains the definitions for the board with the A0 or
+ * higher stepping of the SoC. The ethernet switch does not have a
+ * "wan" port.
+ */
+
+/dts-v1/;
+#include "kirkwood-rd88f6281.dtsi"
+
+/ {
+ model = "Marvell RD88f6281 Reference design, with A0 or higher SoC";
+ compatible = "marvell,rd88f6281-a", "marvell,rd88f6281","marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ dsa@0 {
+ switch@0 {
+ reg = <10 0>; /* MDIO address 10, switch 0 in tree */
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy1: ethernet-phy@11 {
+ reg = <11>;
+ };
+};
+
+&eth1 {
+ status = "okay";
+
+ ethernet1-port@0 {
+ phy-handle = <&ethphy1>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-rd88f6281-z0.dts b/arch/arm/boot/dts/kirkwood-rd88f6281-z0.dts
new file mode 100644
index 000000000..f4272b64e
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-rd88f6281-z0.dts
@@ -0,0 +1,35 @@
+/*
+ * Marvell RD88F6181 Z0 stepping descrition
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms 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 file contains the definitions for the board using the Z0
+ * stepping of the SoC. The ethernet switch has a "wan" port.
+*/
+
+/dts-v1/;
+
+#include "kirkwood-rd88f6281.dtsi"
+
+/ {
+ model = "Marvell RD88f6281 Reference design, with Z0 SoC";
+ compatible = "marvell,rd88f6281-z0", "marvell,rd88f6281","marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ dsa@0 {
+ switch@0 {
+ reg = <0 0>; /* MDIO address 0, switch 0 in tree */
+ port@4 {
+ reg = <4>;
+ label = "wan";
+ };
+ };
+ };
+};
+
+&eth1 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi b/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi
new file mode 100644
index 000000000..d195e884b
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi
@@ -0,0 +1,136 @@
+/*
+ * Marvell RD88F6181 Common Board descrition
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms 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 file contains the definitions that are common between the two
+ * variants of the Marvell Kirkwood Development Board.
+ */
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pinctrl-names = "default";
+
+ pmx_sdio_cd: pmx-sdio-cd {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+ };
+
+ serial@12000 {
+ status = "okay";
+
+ };
+
+ sata@80000 {
+ status = "okay";
+ nr-ports = <2>;
+ };
+ mvsdio@90000 {
+ pinctrl-0 = <&pmx_sdio &pmx_sdio_cd>;
+ pinctrl-names = "default";
+ status = "okay";
+ cd-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+ /* No WP GPIO */
+ };
+ };
+
+ dsa@0 {
+ compatible = "marvell,dsa";
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ dsa,ethernet = <&eth0port>;
+ dsa,mii-bus = <&mdio>;
+
+ switch@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ label = "lan1";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan2";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan3";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan4";
+ };
+
+ port@5 {
+ reg = <5>;
+ label = "cpu";
+ };
+ };
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x0100000 0x200000>;
+ };
+
+ partition@300000 {
+ label = "rootfs";
+ reg = <0x0300000 0x500000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ speed = <1000>;
+ duplex = <1>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-rs212.dts b/arch/arm/boot/dts/kirkwood-rs212.dts
new file mode 100644
index 000000000..3b19f1fd4
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-rs212.dts
@@ -0,0 +1,49 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+ model = "Synology RS212";
+ compatible = "synology,rs212", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-fan-100-15-35-3 {
+ status = "okay";
+ };
+
+ gpio-leds-hdd-38 {
+ status = "okay";
+ };
+
+ regulators-hdd-30-2 {
+ status = "okay";
+ };
+};
+
+&s35390a {
+ status = "okay";
+};
+
+&pcie2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-rs409.dts b/arch/arm/boot/dts/kirkwood-rs409.dts
new file mode 100644
index 000000000..921ca49e8
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-rs409.dts
@@ -0,0 +1,45 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+ model = "Synology RS409";
+ compatible = "synology,rs409", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-fan-150-15-18 {
+ status = "okay";
+ };
+
+ gpio-leds-hdd-36 {
+ status = "okay";
+ };
+};
+
+&eth1 {
+ status = "okay";
+};
+
+&rs5c372 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-rs411.dts b/arch/arm/boot/dts/kirkwood-rs411.dts
new file mode 100644
index 000000000..02852b0c8
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-rs411.dts
@@ -0,0 +1,45 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+ model = "Synology RS411 RS812";
+ compatible = "synology,rs411", "synology,rs812", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-fan-100-15-35-3 {
+ status = "okay";
+ };
+
+ gpio-leds-hdd-36 {
+ status = "okay";
+ };
+};
+
+&eth1 {
+ status = "okay";
+};
+
+&s35390a {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi b/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi
new file mode 100644
index 000000000..7196c7f3e
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi
@@ -0,0 +1,105 @@
+/*
+ * kirkwood-sheevaplug-common.dtsi - Common parts for Sheevaplugs
+ *
+ * Copyright (C) 2013 Simon Baatz <gmbnomis@gmail.com>
+ *
+ * Licensed under GPLv2
+ */
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+
+ pmx_usb_power_enable: pmx-usb-power-enable {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+ pmx_led_red: pmx-led-red {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
+ };
+ pmx_led_blue: pmx-led-blue {
+ marvell,pins = "mpp49";
+ marvell,function = "gpio";
+ };
+ pmx_sdio_cd: pmx-sdio-cd {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+ pmx_sdio_wp: pmx-sdio-wp {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+ };
+ serial@12000 {
+ status = "okay";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_usb_power_enable>;
+ pinctrl-names = "default";
+
+ usb_power: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "USB Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 29 0>;
+ };
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x100000>;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x0100000 0x400000>;
+ };
+
+ partition@500000 {
+ label = "root";
+ reg = <0x0500000 0x1fb00000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts b/arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts
new file mode 100644
index 000000000..e2b4ea4f9
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts
@@ -0,0 +1,43 @@
+/*
+ * kirkwood-sheevaplug-esata.dts - Device tree file for eSATA Sheevaplug
+ *
+ * Copyright (C) 2013 Simon Baatz <gmbnomis@gmail.com>
+ *
+ * Licensed under GPLv2
+ */
+
+/dts-v1/;
+
+#include "kirkwood-sheevaplug-common.dtsi"
+
+/ {
+ model = "Globalscale Technologies eSATA SheevaPlug";
+ compatible = "globalscale,sheevaplug-esata-rev13", "globalscale,sheevaplug-esata", "globalscale,sheevaplug", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ ocp@f1000000 {
+ sata@80000 {
+ status = "okay";
+ nr-ports = <2>;
+ };
+
+ mvsdio@90000 {
+ pinctrl-0 = <&pmx_sdio &pmx_sdio_cd &pmx_sdio_wp>;
+ pinctrl-names = "default";
+ status = "okay";
+ cd-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_led_blue>;
+ pinctrl-names = "default";
+
+ health {
+ label = "sheevaplug:blue:health";
+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-sheevaplug.dts b/arch/arm/boot/dts/kirkwood-sheevaplug.dts
new file mode 100644
index 000000000..82f6abf12
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-sheevaplug.dts
@@ -0,0 +1,43 @@
+/*
+ * kirkwood-sheevaplug.dts - Device tree file for Sheevaplug
+ *
+ * Copyright (C) 2013 Simon Baatz <gmbnomis@gmail.com>
+ *
+ * Licensed under GPLv2
+ */
+
+/dts-v1/;
+
+#include "kirkwood-sheevaplug-common.dtsi"
+
+/ {
+ model = "Globalscale Technologies SheevaPlug";
+ compatible = "globalscale,sheevaplug", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ ocp@f1000000 {
+ mvsdio@90000 {
+ pinctrl-0 = <&pmx_sdio>;
+ pinctrl-names = "default";
+ status = "okay";
+ /* No CD or WP GPIOs */
+ broken-cd;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_led_blue &pmx_led_red>;
+ pinctrl-names = "default";
+
+ health {
+ label = "sheevaplug:blue:health";
+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+
+ misc {
+ label = "sheevaplug:red:misc";
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-synology.dtsi b/arch/arm/boot/dts/kirkwood-synology.dtsi
new file mode 100644
index 000000000..8be5b2e46
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-synology.dtsi
@@ -0,0 +1,863 @@
+/*
+ * Nodes for Marvell 628x Synology devices
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/ {
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+
+ pcie2: pcie@2,0 {
+ status = "disabled";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pmx_alarmled_12: pmx-alarmled-12 {
+ marvell,pins = "mpp12";
+ marvell,function = "gpio";
+ };
+
+ pmx_fanctrl_15: pmx-fanctrl-15 {
+ marvell,pins = "mpp15";
+ marvell,function = "gpio";
+ };
+
+ pmx_fanctrl_16: pmx-fanctrl-16 {
+ marvell,pins = "mpp16";
+ marvell,function = "gpio";
+ };
+
+ pmx_fanctrl_17: pmx-fanctrl-17 {
+ marvell,pins = "mpp17";
+ marvell,function = "gpio";
+ };
+
+ pmx_fanalarm_18: pmx-fanalarm-18 {
+ marvell,pins = "mpp18";
+ marvell,function = "gpo";
+ };
+
+ pmx_hddled_20: pmx-hddled-20 {
+ marvell,pins = "mpp20";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_21: pmx-hddled-21 {
+ marvell,pins = "mpp21";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_22: pmx-hddled-22 {
+ marvell,pins = "mpp22";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_23: pmx-hddled-23 {
+ marvell,pins = "mpp23";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_24: pmx-hddled-24 {
+ marvell,pins = "mpp24";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_25: pmx-hddled-25 {
+ marvell,pins = "mpp25";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_26: pmx-hddled-26 {
+ marvell,pins = "mpp26";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_27: pmx-hddled-27 {
+ marvell,pins = "mpp27";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_28: pmx-hddled-28 {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+
+ pmx_hdd1_pwr_29: pmx-hdd1-pwr-29 {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+
+ pmx_hdd1_pwr_30: pmx-hdd-pwr-30 {
+ marvell,pins = "mpp30";
+ marvell,function = "gpio";
+ };
+
+ pmx_hdd2_pwr_31: pmx-hdd2-pwr-31 {
+ marvell,pins = "mpp31";
+ marvell,function = "gpio";
+ };
+
+ pmx_fanctrl_32: pmx-fanctrl-32 {
+ marvell,pins = "mpp32";
+ marvell,function = "gpio";
+ };
+
+ pmx_fanctrl_33: pmx-fanctrl-33 {
+ marvell,pins = "mpp33";
+ marvell,function = "gpo";
+ };
+
+ pmx_fanctrl_34: pmx-fanctrl-34 {
+ marvell,pins = "mpp34";
+ marvell,function = "gpio";
+ };
+
+ pmx_hdd2_pwr_34: pmx-hdd2-pwr-34 {
+ marvell,pins = "mpp34";
+ marvell,function = "gpio";
+ };
+
+ pmx_fanalarm_35: pmx-fanalarm-35 {
+ marvell,pins = "mpp35";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_36: pmx-hddled-36 {
+ marvell,pins = "mpp36";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_37: pmx-hddled-37 {
+ marvell,pins = "mpp37";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_38: pmx-hddled-38 {
+ marvell,pins = "mpp38";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_39: pmx-hddled-39 {
+ marvell,pins = "mpp39";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_40: pmx-hddled-40 {
+ marvell,pins = "mpp40";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_41: pmx-hddled-41 {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_42: pmx-hddled-42 {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_43: pmx-hddled-43 {
+ marvell,pins = "mpp43";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_44: pmx-hddled-44 {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+
+ pmx_hddled_45: pmx-hddled-45 {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+
+ pmx_hdd3_pwr_44: pmx-hdd3-pwr-44 {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+
+ pmx_hdd4_pwr_45: pmx-hdd4-pwr-45 {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+
+ pmx_fanalarm_44: pmx-fanalarm-44 {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+
+ pmx_fanalarm_45: pmx-fanalarm-45 {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+ };
+
+ rtc@10300 {
+ status = "disabled";
+ };
+
+ spi@10600 {
+ status = "okay";
+
+ m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p80";
+ reg = <0>;
+ spi-max-frequency = <20000000>;
+ mode = <0>;
+
+ partition@00000000 {
+ reg = <0x00000000 0x00080000>;
+ label = "RedBoot";
+ };
+
+ partition@00080000 {
+ reg = <0x00080000 0x00200000>;
+ label = "zImage";
+ };
+
+ partition@00280000 {
+ reg = <0x00280000 0x00140000>;
+ label = "rd.gz";
+ };
+
+ partition@003c0000 {
+ reg = <0x003c0000 0x00010000>;
+ label = "vendor";
+ };
+
+ partition@003d0000 {
+ reg = <0x003d0000 0x00020000>;
+ label = "RedBoot config";
+ };
+
+ partition@003f0000 {
+ reg = <0x003f0000 0x00010000>;
+ label = "FIS directory";
+ };
+ };
+ };
+
+ i2c@11000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ rs5c372: rs5c372@32 {
+ status = "disabled";
+ compatible = "ricoh,rs5c372";
+ reg = <0x32>;
+ };
+
+ s35390a: s35390a@30 {
+ status = "disabled";
+ compatible = "sii,s35390a";
+ reg = <0x30>;
+ };
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ serial@12100 {
+ status = "okay";
+ };
+
+ poweroff@12100 {
+ compatible = "synology,power-off";
+ reg = <0x12100 0x100>;
+ clocks = <&gate_clk 7>;
+ };
+
+ sata@80000 {
+ pinctrl-0 = <&pmx_sata0 &pmx_sata1>;
+ pinctrl-names = "default";
+ status = "okay";
+ nr-ports = <2>;
+ };
+ };
+
+ gpio-fan-150-32-35 {
+ status = "disabled";
+ compatible = "gpio-fan";
+ pinctrl-0 = <&pmx_fanctrl_32 &pmx_fanctrl_33 &pmx_fanctrl_34
+ &pmx_fanalarm_35>;
+ pinctrl-names = "default";
+ gpios = <&gpio1 0 GPIO_ACTIVE_HIGH
+ &gpio1 1 GPIO_ACTIVE_HIGH
+ &gpio1 2 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = < 0 0
+ 2200 1
+ 2500 2
+ 3000 4
+ 3300 3
+ 3700 5
+ 3800 6
+ 4200 7 >;
+ };
+
+ gpio-fan-150-15-18 {
+ status = "disabled";
+ compatible = "gpio-fan";
+ pinctrl-0 = <&pmx_fanctrl_15 &pmx_fanctrl_16 &pmx_fanctrl_17
+ &pmx_fanalarm_18>;
+ pinctrl-names = "default";
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH
+ &gpio0 16 GPIO_ACTIVE_HIGH
+ &gpio0 17 GPIO_ACTIVE_HIGH>;
+ alarm-gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = < 0 0
+ 2200 1
+ 2500 2
+ 3000 4
+ 3300 3
+ 3700 5
+ 3800 6
+ 4200 7 >;
+ };
+
+ gpio-fan-100-32-35 {
+ status = "disabled";
+ compatible = "gpio-fan";
+ pinctrl-0 = <&pmx_fanctrl_32 &pmx_fanctrl_33 &pmx_fanctrl_34
+ &pmx_fanalarm_35>;
+ pinctrl-names = "default";
+ gpios = <&gpio1 0 GPIO_ACTIVE_HIGH
+ &gpio1 1 GPIO_ACTIVE_HIGH
+ &gpio1 2 GPIO_ACTIVE_HIGH>;
+ alarm-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = < 0 0
+ 2500 1
+ 3100 2
+ 3800 3
+ 4600 4
+ 4800 5
+ 4900 6
+ 5000 7 >;
+ };
+
+ gpio-fan-100-15-18 {
+ status = "disabled";
+ compatible = "gpio-fan";
+ pinctrl-0 = <&pmx_fanctrl_15 &pmx_fanctrl_16 &pmx_fanctrl_17
+ &pmx_fanalarm_18>;
+ pinctrl-names = "default";
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH
+ &gpio0 16 GPIO_ACTIVE_HIGH
+ &gpio0 17 GPIO_ACTIVE_HIGH>;
+ alarm-gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = < 0 0
+ 2500 1
+ 3100 2
+ 3800 3
+ 4600 4
+ 4800 5
+ 4900 6
+ 5000 7 >;
+ };
+
+ gpio-fan-100-15-35-1 {
+ status = "disabled";
+ compatible = "gpio-fan";
+ pinctrl-0 = <&pmx_fanctrl_15 &pmx_fanctrl_16 &pmx_fanctrl_17
+ &pmx_fanalarm_35>;
+ pinctrl-names = "default";
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH
+ &gpio0 16 GPIO_ACTIVE_HIGH
+ &gpio0 17 GPIO_ACTIVE_HIGH>;
+ alarm-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = < 0 0
+ 2500 1
+ 3100 2
+ 3800 3
+ 4600 4
+ 4800 5
+ 4900 6
+ 5000 7 >;
+ };
+
+ gpio-fan-100-15-35-3 {
+ status = "disabled";
+ compatible = "gpio-fan";
+ pinctrl-0 = <&pmx_fanctrl_15 &pmx_fanctrl_16 &pmx_fanctrl_17
+ &pmx_fanalarm_35 &pmx_fanalarm_44 &pmx_fanalarm_45>;
+ pinctrl-names = "default";
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH
+ &gpio0 16 GPIO_ACTIVE_HIGH
+ &gpio0 17 GPIO_ACTIVE_HIGH>;
+ alarm-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH
+ &gpio1 12 GPIO_ACTIVE_HIGH
+ &gpio1 13 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = < 0 0
+ 2500 1
+ 3100 2
+ 3800 3
+ 4600 4
+ 4800 5
+ 4900 6
+ 5000 7 >;
+ };
+
+ gpio-leds-alarm-12 {
+ status = "disabled";
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_alarmled_12>;
+ pinctrl-names = "default";
+
+ hdd1-green {
+ label = "synology:alarm";
+ gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-leds-hdd-20 {
+ status = "disabled";
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_hddled_20 &pmx_hddled_21 &pmx_hddled_22
+ &pmx_hddled_23 &pmx_hddled_24 &pmx_hddled_25
+ &pmx_hddled_26 &pmx_hddled_27>;
+ pinctrl-names = "default";
+
+ hdd1-green {
+ label = "synology:green:hdd1";
+ gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd1-amber {
+ label = "synology:amber:hdd1";
+ gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd2-green {
+ label = "synology:green:hdd2";
+ gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd2-amber {
+ label = "synology:amber:hdd2";
+ gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd3-green {
+ label = "synology:green:hdd3";
+ gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd3-amber {
+ label = "synology:amber:hdd3";
+ gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd4-green {
+ label = "synology:green:hdd4";
+ gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd4-amber {
+ label = "synology:amber:hdd4";
+ gpios = <&gpio0 27 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-leds-hdd-21-1 {
+ status = "disabled";
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_hddled_21 &pmx_hddled_23>;
+ pinctrl-names = "default";
+
+ hdd1-green {
+ label = "synology:green:hdd1";
+ gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd1-amber {
+ label = "synology:amber:hdd1";
+ gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-leds-hdd-21-2 {
+ status = "disabled";
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_hddled_21 &pmx_hddled_23 &pmx_hddled_20 &pmx_hddled_22>;
+ pinctrl-names = "default";
+
+ hdd1-green {
+ label = "synology:green:hdd1";
+ gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd1-amber {
+ label = "synology:amber:hdd1";
+ gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd2-green {
+ label = "synology:green:hdd2";
+ gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd2-amber {
+ label = "synology:amber:hdd2";
+ gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-leds-hdd-36 {
+ status = "disabled";
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_hddled_36 &pmx_hddled_37 &pmx_hddled_38
+ &pmx_hddled_39 &pmx_hddled_40 &pmx_hddled_41
+ &pmx_hddled_42 &pmx_hddled_43 &pmx_hddled_44
+ &pmx_hddled_45>;
+ pinctrl-names = "default";
+
+ hdd1-green {
+ label = "synology:green:hdd1";
+ gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd1-amber {
+ label = "synology:amber:hdd1";
+ gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd2-green {
+ label = "synology:green:hdd2";
+ gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd2-amber {
+ label = "synology:amber:hdd2";
+ gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd3-green {
+ label = "synology:green:hdd3";
+ gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd3-amber {
+ label = "synology:amber:hdd3";
+ gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd4-green {
+ label = "synology:green:hdd4";
+ gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd4-amber {
+ label = "synology:amber:hdd4";
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd5-green {
+ label = "synology:green:hdd5";
+ gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd5-amber {
+ label = "synology:amber:hdd5";
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-leds-hdd-38 {
+ status = "disabled";
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_hddled_38 &pmx_hddled_39 &pmx_hddled_36 &pmx_hddled_37>;
+ pinctrl-names = "default";
+
+ hdd1-green {
+ label = "synology:green:hdd1";
+ gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd1-amber {
+ label = "synology:amber:hdd1";
+ gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd2-green {
+ label = "synology:green:hdd2";
+ gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+ };
+
+ hdd2-amber {
+ label = "synology:amber:hdd2";
+ gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ regulators-hdd-29 {
+ status = "disabled";
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_hdd1_pwr_29 &pmx_hdd2_pwr_31>;
+ pinctrl-names = "default";
+
+ regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "hdd1power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ startup-delay-us = <5000000>;
+ gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "hdd2power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ startup-delay-us = <5000000>;
+ gpio = <&gpio0 31 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ regulators-hdd-30-1 {
+ status = "disabled";
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_hdd1_pwr_30>;
+ pinctrl-names = "default";
+
+ regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "hdd1power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ startup-delay-us = <5000000>;
+ gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ regulators-hdd-30-2 {
+ status = "disabled";
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_hdd1_pwr_30 &pmx_hdd2_pwr_34>;
+ pinctrl-names = "default";
+
+ regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "hdd1power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ startup-delay-us = <5000000>;
+ gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "hdd2power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ startup-delay-us = <5000000>;
+ gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ regulators-hdd-30-4 {
+ status = "disabled";
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_hdd1_pwr_30 &pmx_hdd2_pwr_34
+ &pmx_hdd3_pwr_44 &pmx_hdd4_pwr_45>;
+ pinctrl-names = "default";
+
+ regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "hdd1power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ startup-delay-us = <5000000>;
+ gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "hdd2power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ startup-delay-us = <5000000>;
+ gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "hdd3power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ startup-delay-us = <5000000>;
+ gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "hdd4power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ startup-delay-us = <5000000>;
+ gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ regulators-hdd-31 {
+ status = "disabled";
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_hdd2_pwr_31>;
+ pinctrl-names = "default";
+
+ regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "hdd2power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ startup-delay-us = <5000000>;
+ gpio = <&gpio0 31 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ regulators-hdd-34 {
+ status = "disabled";
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_hdd2_pwr_34 &pmx_hdd3_pwr_44
+ &pmx_hdd4_pwr_45>;
+ pinctrl-names = "default";
+
+ regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "hdd2power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ startup-delay-us = <5000000>;
+ gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "hdd3power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ startup-delay-us = <5000000>;
+ gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "hdd4power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ startup-delay-us = <5000000>;
+ gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ device_type = "ethernet-phy";
+ reg = <8>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ device_type = "ethernet-phy";
+ reg = <9>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
+
+&eth1 {
+ status = "disabled";
+
+ ethernet1-port@0 {
+ phy-handle = <&ethphy1>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-t5325.dts b/arch/arm/boot/dts/kirkwood-t5325.dts
new file mode 100644
index 000000000..610ec0f95
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-t5325.dts
@@ -0,0 +1,231 @@
+/*
+ * Device Tree file for HP t5325 Thin Client"
+ *
+ * Copyright (C) 2014
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+*/
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "HP t5325 Thin Client";
+ compatible = "hp,t5325", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pinctrl-0 = <&pmx_i2s &pmx_sysrst>;
+ pinctrl-names = "default";
+
+ pmx_button_power: pmx-button_power {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+
+ pmx_power_off: pmx-power-off {
+ marvell,pins = "mpp48";
+ marvell,function = "gpio";
+ };
+
+ pmx_led: pmx-led {
+ marvell,pins = "mpp21";
+ marvell,function = "gpio";
+ };
+
+ pmx_usb_sata_power_enable: pmx-usb-sata-power-enable {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+
+ pmx_spi: pmx-spi {
+ marvell,pins = "mpp1", "mpp2", "mpp3", "mpp7";
+ marvell,function = "spi";
+ };
+
+ pmx_sysrst: pmx-sysrst {
+ marvell,pins = "mpp6";
+ marvell,function = "sysrst";
+ };
+
+ pmx_i2s: pmx-i2s {
+ marvell,pins = "mpp39", "mpp40", "mpp41", "mpp42",
+ "mpp43";
+ marvell,function = "audio";
+ };
+ };
+
+ spi@10600 {
+ status = "okay";
+
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p80";
+ spi-max-frequency = <86000000>;
+ reg = <0>;
+ mode = <0>;
+
+ partition@0 {
+ reg = <0x0 0x80000>;
+ label = "u-boot";
+ };
+
+ partition@1 {
+ reg = <0x80000 0x40000>;
+ label = "SSD firmware";
+ };
+
+ partition@2 {
+ reg = <0xc0000 0x10000>;
+ label = "u-boot env";
+ };
+
+ partition@3 {
+ reg = <0xd0000 0x10000>;
+ label = "permanent u-boot env";
+ };
+
+ partition@4 {
+ reg = <0xd0000 0x10000>;
+ label = "permanent u-boot env";
+ };
+ };
+ };
+
+ i2c@11000 {
+ status = "okay";
+
+ alc5621: alc5621@1a {
+ compatible = "realtek,alc5621";
+ reg = <0x1a>;
+ #sound-dai-cells = <0>;
+ add-ctrl = <0x3700>;
+ jack-det-ctrl = <0x4810>;
+ };
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ sata@80000 {
+ status = "okay";
+ nr-ports = <2>;
+ };
+
+ audio: audio-controller@a0000 {
+ status = "okay";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_usb_sata_power_enable>;
+ pinctrl-names = "default";
+
+ usb_power: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "USB-SATA Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_button_power>;
+ pinctrl-names = "default";
+
+ button@1 {
+ label = "Power Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio_poweroff {
+ compatible = "gpio-poweroff";
+ pinctrl-0 = <&pmx_power_off>;
+ pinctrl-names = "default";
+ gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,routing =
+ "Headphone Jack", "HPL",
+ "Headphone Jack", "HPR",
+ "Speaker", "SPKOUT",
+ "Speaker", "SPKOUTN",
+ "MIC1", "Mic Jack",
+ "MIC2", "Mic Jack";
+ simple-audio-card,widgets =
+ "Headphone", "Headphone Jack",
+ "Speaker", "Speaker",
+ "Microphone", "Mic Jack";
+
+ simple-audio-card,mclk-fs = <256>;
+
+ simple-audio-card,cpu {
+ sound-dai = <&audio>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&alc5621>;
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy {
+ device_type = "ethernet-phy";
+ reg = <8>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-topkick.dts b/arch/arm/boot/dts/kirkwood-topkick.dts
new file mode 100644
index 000000000..f5c8c0dd4
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-topkick.dts
@@ -0,0 +1,215 @@
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+
+/ {
+ model = "Univeral Scientific Industrial Co. Topkick-1281P2";
+ compatible = "usi,topkick-1281P2", "usi,topkick", "marvell,kirkwood-88f6282", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ /*
+ * Switch positions
+ *
+ * /-SW_LEFT(2)
+ * |
+ * | /-SW_IDLE
+ * | |
+ * | | /-SW_RIGHT
+ * | | |
+ * PS [L] [I] [R] LEDS
+ */
+ pinctrl-0 = <&pmx_sw_left &pmx_sw_right
+ &pmx_sw_idle &pmx_sw_left2>;
+ pinctrl-names = "default";
+
+ pmx_led_disk_yellow: pmx-led-disk-yellow {
+ marvell,pins = "mpp21";
+ marvell,function = "gpio";
+ };
+
+ pmx_sata0_pwr_enable: pmx-sata0-pwr-enable {
+ marvell,pins = "mpp36";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_sys_red: pmx-led-sys-red {
+ marvell,pins = "mpp37";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_sys_blue: pmx-led-sys-blue {
+ marvell,pins = "mpp38";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_wifi_green: pmx-led-wifi-green {
+ marvell,pins = "mpp39";
+ marvell,function = "gpio";
+ };
+
+ pmx_sw_left: pmx-sw-left {
+ marvell,pins = "mpp43";
+ marvell,function = "gpio";
+ };
+
+ pmx_sw_right: pmx-sw-right {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+
+ pmx_sw_idle: pmx-sw-idle {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+
+ pmx_sw_left2: pmx-sw-left2 {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_wifi_yellow: pmx-led-wifi-yellow {
+ marvell,pins = "mpp48";
+ marvell,function = "gpio";
+ };
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ sata@80000 {
+ status = "okay";
+ nr-ports = <1>;
+ };
+
+ i2c@11000 {
+ status = "okay";
+ };
+
+ mvsdio@90000 {
+ pinctrl-0 = <&pmx_sdio>;
+ pinctrl-names = "default";
+ status = "okay";
+ /* No CD or WP GPIOs */
+ broken-cd;
+ };
+ };
+
+ gpio-leds {
+ /*
+ * GPIO LED layout
+ *
+ * /-SYS_LED(2)
+ * |
+ * | /-DISK_LED
+ * | |
+ * | | /-WLAN_LED(2)
+ * | | |
+ * [SW] [*] [*] [*]
+ */
+
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_led_disk_yellow &pmx_led_sys_red
+ &pmx_led_sys_blue &pmx_led_wifi_green
+ &pmx_led_wifi_yellow>;
+ pinctrl-names = "default";
+
+ disk {
+ label = "topkick:yellow:disk";
+ gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "ide-disk";
+ };
+ system2 {
+ label = "topkick:red:system";
+ gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+ };
+ system {
+ label = "topkick:blue:system";
+ gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+ default-state = "on";
+ };
+ wifi {
+ label = "topkick:green:wifi";
+ gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+ };
+ wifi2 {
+ label = "topkick:yellow:wifi";
+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
+ };
+ };
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_sata0_pwr_enable>;
+ pinctrl-names = "default";
+
+ sata0_power: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "SATA0 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 4 0>;
+ };
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x180000>;
+ };
+
+ partition@180000 {
+ label = "u-boot env";
+ reg = <0x0180000 0x20000>;
+ };
+
+ partition@200000 {
+ label = "uImage";
+ reg = <0x0200000 0x600000>;
+ };
+
+ partition@800000 {
+ label = "uInitrd";
+ reg = <0x0800000 0x1000000>;
+ };
+
+ partition@1800000 {
+ label = "rootfs";
+ reg = <0x1800000 0xe800000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-ts219-6281.dts b/arch/arm/boot/dts/kirkwood-ts219-6281.dts
new file mode 100644
index 000000000..9767d73f3
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ts219-6281.dts
@@ -0,0 +1,55 @@
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-ts219.dtsi"
+
+/ {
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+
+ pinctrl-0 = <&pmx_ram_size &pmx_board_id>;
+ pinctrl-names = "default";
+
+ pmx_ram_size: pmx-ram-size {
+ /* RAM: 0: 256 MB, 1: 512 MB */
+ marvell,pins = "mpp36";
+ marvell,function = "gpio";
+ };
+ pmx_USB_copy_button: pmx-USB-copy-button {
+ marvell,pins = "mpp15";
+ marvell,function = "gpio";
+ };
+ pmx_reset_button: pmx-reset-button {
+ marvell,pins = "mpp16";
+ marvell,function = "gpio";
+ };
+ pmx_board_id: pmx-board-id {
+ /* 0: TS-11x, 1: TS-21x */
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_reset_button &pmx_USB_copy_button>;
+ pinctrl-names = "default";
+
+ button@1 {
+ label = "USB Copy";
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
+ };
+ button@2 {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&ethphy0 { reg = <8>; };
diff --git a/arch/arm/boot/dts/kirkwood-ts219-6282.dts b/arch/arm/boot/dts/kirkwood-ts219-6282.dts
new file mode 100644
index 000000000..bfc1a32d4
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ts219-6282.dts
@@ -0,0 +1,65 @@
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-ts219.dtsi"
+
+/ {
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@2,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+
+ pinctrl-0 = <&pmx_ram_size &pmx_board_id>;
+ pinctrl-names = "default";
+
+ pmx_ram_size: pmx-ram-size {
+ /* RAM: 0: 256 MB, 1: 512 MB */
+ marvell,pins = "mpp36";
+ marvell,function = "gpio";
+ };
+ pmx_reset_button: pmx-reset-button {
+ marvell,pins = "mpp37";
+ marvell,function = "gpio";
+ };
+ pmx_USB_copy_button: pmx-USB-copy-button {
+ marvell,pins = "mpp43";
+ marvell,function = "gpio";
+ };
+ pmx_board_id: pmx-board-id {
+ /* 0: TS-11x, 1: TS-21x */
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_reset_button &pmx_USB_copy_button>;
+ pinctrl-names = "default";
+
+ button@1 {
+ label = "USB Copy";
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+ };
+ button@2 {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&ethphy0 { reg = <0>; };
diff --git a/arch/arm/boot/dts/kirkwood-ts219.dtsi b/arch/arm/boot/dts/kirkwood-ts219.dtsi
new file mode 100644
index 000000000..df7f15276
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ts219.dtsi
@@ -0,0 +1,107 @@
+/ {
+ model = "QNAP TS219 family";
+ compatible = "qnap,ts219", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ i2c@11000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ s35390a: s35390a@30 {
+ compatible = "s35390a";
+ reg = <0x30>;
+ };
+ };
+ serial@12000 {
+ status = "okay";
+ };
+ serial@12100 {
+ status = "okay";
+ };
+ poweroff@12100 {
+ compatible = "qnap,power-off";
+ reg = <0x12000 0x100>;
+ clocks = <&gate_clk 7>;
+ };
+ spi@10600 {
+ status = "okay";
+
+ m25p128@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p128";
+ reg = <0>;
+ spi-max-frequency = <20000000>;
+ mode = <0>;
+
+ partition@0000000 {
+ reg = <0x00000000 0x00080000>;
+ label = "U-Boot";
+ };
+
+ partition@00200000 {
+ reg = <0x00200000 0x00200000>;
+ label = "Kernel";
+ };
+
+ partition@00400000 {
+ reg = <0x00400000 0x00900000>;
+ label = "RootFS1";
+ };
+ partition@00d00000 {
+ reg = <0x00d00000 0x00300000>;
+ label = "RootFS2";
+ };
+ partition@00040000 {
+ reg = <0x00080000 0x00040000>;
+ label = "U-Boot Config";
+ };
+ partition@000c0000 {
+ reg = <0x000c0000 0x00140000>;
+ label = "NAS Config";
+ };
+ };
+ };
+ sata@80000 {
+ pinctrl-0 = <&pmx_sata0 &pmx_sata1>;
+ pinctrl-names = "default";
+ status = "okay";
+ nr-ports = <2>;
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy {
+ /* overwrite reg property in board file */
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-ts419-6281.dts b/arch/arm/boot/dts/kirkwood-ts419-6281.dts
new file mode 100644
index 000000000..aa22aa862
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ts419-6281.dts
@@ -0,0 +1,20 @@
+/*
+ * Device Tree file for QNAP TS41X with 6281 SoC
+ *
+ * Copyright (C) 2013, Andrew Lunn <andrew@lunn.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.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-ts219.dtsi"
+#include "kirkwood-ts419.dtsi"
+
+&ethphy0 { reg = <8>; };
+&ethphy1 { reg = <0>; };
diff --git a/arch/arm/boot/dts/kirkwood-ts419-6282.dts b/arch/arm/boot/dts/kirkwood-ts419-6282.dts
new file mode 100644
index 000000000..d7512d4cd
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ts419-6282.dts
@@ -0,0 +1,32 @@
+/*
+ * Device Tree file for QNAP TS41X with 6282 SoC
+ *
+ * Copyright (C) 2013, Andrew Lunn <andrew@lunn.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.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-ts219.dtsi"
+#include "kirkwood-ts419.dtsi"
+
+/ {
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@2,0 {
+ status = "okay";
+ };
+ };
+ };
+};
+
+&ethphy0 { reg = <0>; };
+&ethphy1 { reg = <1>; };
diff --git a/arch/arm/boot/dts/kirkwood-ts419.dtsi b/arch/arm/boot/dts/kirkwood-ts419.dtsi
new file mode 100644
index 000000000..30ab93bfb
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-ts419.dtsi
@@ -0,0 +1,75 @@
+/*
+ * Device Tree include file for QNAP TS41X
+ *
+ * Copyright (C) 2013, Andrew Lunn <andrew@lunn.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.
+ */
+
+/ {
+ model = "QNAP TS419 family";
+ compatible = "qnap,ts419", "marvell,kirkwood";
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
+ pinctrl-names = "default";
+
+ pmx_USB_copy_button: pmx-USB-copy-button {
+ marvell,pins = "mpp43";
+ marvell,function = "gpio";
+ };
+ pmx_reset_button: pmx-reset-button {
+ marvell,pins = "mpp37";
+ marvell,function = "gpio";
+ };
+ /*
+ * JP1 indicates if an LCD module is installed
+ * on the serial port (0), or if the port is used
+ * as a console (1).
+ */
+ pmx_jumper_jp1: pmx-jumper_jp1 {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_reset_button &pmx_USB_copy_button>;
+ pinctrl-names = "default";
+
+ button@1 {
+ label = "USB Copy";
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+ };
+ button@2 {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy1: ethernet-phy@1 {
+ device_type = "ethernet-phy";
+ /* overwrite reg property in board file */
+ };
+};
+
+&eth1 {
+ status = "okay";
+ ethernet1-port@0 {
+ phy-handle = <&ethphy1>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
new file mode 100644
index 000000000..464f09a1a
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -0,0 +1,383 @@
+/include/ "skeleton.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
+
+/ {
+ compatible = "marvell,kirkwood";
+ interrupt-parent = <&intc>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "marvell,feroceon";
+ reg = <0>;
+ clocks = <&core_clk 1>, <&core_clk 3>, <&gate_clk 11>;
+ clock-names = "cpu_clk", "ddrclk", "powersave";
+ };
+ };
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ i2c0 = &i2c0;
+ };
+
+ mbus {
+ compatible = "marvell,kirkwood-mbus", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ /* If a board file needs to change this ranges it must replace it completely */
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000 /* internal-regs */
+ MBUS_ID(0x01, 0x2f) 0 0xf4000000 0x10000 /* nand flash */
+ MBUS_ID(0x03, 0x01) 0 0xf5000000 0x10000 /* crypto sram */
+ >;
+ controller = <&mbusc>;
+ pcie-mem-aperture = <0xe0000000 0x10000000>; /* 256 MiB memory space */
+ pcie-io-aperture = <0xf2000000 0x100000>; /* 1 MiB I/O space */
+
+ cesa: crypto@0301 {
+ compatible = "marvell,orion-crypto";
+ reg = <MBUS_ID(0xf0, 0x01) 0x30000 0x10000>,
+ <MBUS_ID(0x03, 0x01) 0 0x800>;
+ reg-names = "regs", "sram";
+ interrupts = <22>;
+ clocks = <&gate_clk 17>;
+ status = "okay";
+ };
+
+ nand: nand@012f {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cle = <0>;
+ ale = <1>;
+ bank-width = <1>;
+ compatible = "marvell,orion-nand";
+ reg = <MBUS_ID(0x01, 0x2f) 0 0x400>;
+ chip-delay = <25>;
+ /* set partition map and/or chip-delay in board dts */
+ clocks = <&gate_clk 7>;
+ pinctrl-0 = <&pmx_nand>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+ };
+
+ ocp@f1000000 {
+ compatible = "simple-bus";
+ ranges = <0x00000000 0xf1000000 0x0100000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ pinctrl: pin-controller@10000 {
+ /* set compatible property in SoC file */
+ reg = <0x10000 0x20>;
+
+ pmx_ge1: pmx-ge1 {
+ marvell,pins = "mpp20", "mpp21", "mpp22", "mpp23",
+ "mpp24", "mpp25", "mpp26", "mpp27",
+ "mpp30", "mpp31", "mpp32", "mpp33";
+ marvell,function = "ge1";
+ };
+
+ pmx_nand: pmx-nand {
+ marvell,pins = "mpp0", "mpp1", "mpp2", "mpp3",
+ "mpp4", "mpp5", "mpp18", "mpp19";
+ marvell,function = "nand";
+ };
+
+ /*
+ * Default SPI0 pinctrl setting with CSn on mpp0,
+ * overwrite marvell,pins on board level if required.
+ */
+ pmx_spi: pmx-spi {
+ marvell,pins = "mpp0", "mpp1", "mpp2", "mpp3";
+ marvell,function = "spi";
+ };
+
+ pmx_twsi0: pmx-twsi0 {
+ marvell,pins = "mpp8", "mpp9";
+ marvell,function = "twsi0";
+ };
+
+ /*
+ * Default UART pinctrl setting without RTS/CTS,
+ * overwrite marvell,pins on board level if required.
+ */
+ pmx_uart0: pmx-uart0 {
+ marvell,pins = "mpp10", "mpp11";
+ marvell,function = "uart0";
+ };
+
+ pmx_uart1: pmx-uart1 {
+ marvell,pins = "mpp13", "mpp14";
+ marvell,function = "uart1";
+ };
+ };
+
+ core_clk: core-clocks@10030 {
+ compatible = "marvell,kirkwood-core-clock";
+ reg = <0x10030 0x4>;
+ #clock-cells = <1>;
+ };
+
+ spi0: spi@10600 {
+ compatible = "marvell,orion-spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ interrupts = <23>;
+ reg = <0x10600 0x28>;
+ clocks = <&gate_clk 7>;
+ pinctrl-0 = <&pmx_spi>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ gpio0: gpio@10100 {
+ compatible = "marvell,orion-gpio";
+ #gpio-cells = <2>;
+ gpio-controller;
+ reg = <0x10100 0x40>;
+ ngpios = <32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <35>, <36>, <37>, <38>;
+ clocks = <&gate_clk 7>;
+ };
+
+ gpio1: gpio@10140 {
+ compatible = "marvell,orion-gpio";
+ #gpio-cells = <2>;
+ gpio-controller;
+ reg = <0x10140 0x40>;
+ ngpios = <18>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <39>, <40>, <41>;
+ clocks = <&gate_clk 7>;
+ };
+
+ i2c0: i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <29>;
+ clock-frequency = <100000>;
+ clocks = <&gate_clk 7>;
+ pinctrl-0 = <&pmx_twsi0>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ uart0: serial@12000 {
+ compatible = "ns16550a";
+ reg = <0x12000 0x100>;
+ reg-shift = <2>;
+ interrupts = <33>;
+ clocks = <&gate_clk 7>;
+ pinctrl-0 = <&pmx_uart0>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ uart1: serial@12100 {
+ compatible = "ns16550a";
+ reg = <0x12100 0x100>;
+ reg-shift = <2>;
+ interrupts = <34>;
+ clocks = <&gate_clk 7>;
+ pinctrl-0 = <&pmx_uart1>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ mbusc: mbus-controller@20000 {
+ compatible = "marvell,mbus-controller";
+ reg = <0x20000 0x80>, <0x1500 0x20>;
+ };
+
+ sysc: system-controller@20000 {
+ compatible = "marvell,orion-system-controller";
+ reg = <0x20000 0x120>;
+ };
+
+ bridge_intc: bridge-interrupt-ctrl@20110 {
+ compatible = "marvell,orion-bridge-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x20110 0x8>;
+ interrupts = <1>;
+ marvell,#interrupts = <6>;
+ };
+
+ gate_clk: clock-gating-control@2011c {
+ compatible = "marvell,kirkwood-gating-clock";
+ reg = <0x2011c 0x4>;
+ clocks = <&core_clk 0>;
+ #clock-cells = <1>;
+ };
+
+ l2: l2-cache@20128 {
+ compatible = "marvell,kirkwood-cache";
+ reg = <0x20128 0x4>;
+ };
+
+ intc: main-interrupt-ctrl@20200 {
+ compatible = "marvell,orion-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x20200 0x10>, <0x20210 0x10>;
+ };
+
+ timer: timer@20300 {
+ compatible = "marvell,orion-timer";
+ reg = <0x20300 0x20>;
+ interrupt-parent = <&bridge_intc>;
+ interrupts = <1>, <2>;
+ clocks = <&core_clk 0>;
+ };
+
+ wdt: watchdog-timer@20300 {
+ compatible = "marvell,orion-wdt";
+ reg = <0x20300 0x28>, <0x20108 0x4>;
+ interrupt-parent = <&bridge_intc>;
+ interrupts = <3>;
+ clocks = <&gate_clk 7>;
+ status = "okay";
+ };
+
+ usb0: ehci@50000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <19>;
+ clocks = <&gate_clk 3>;
+ status = "okay";
+ };
+
+ dma0: xor@60800 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60800 0x100
+ 0x60A00 0x100>;
+ status = "okay";
+ clocks = <&gate_clk 8>;
+
+ xor00 {
+ interrupts = <5>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor01 {
+ interrupts = <6>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+
+ dma1: xor@60900 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60900 0x100
+ 0x60B00 0x100>;
+ status = "okay";
+ clocks = <&gate_clk 16>;
+
+ xor00 {
+ interrupts = <7>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor01 {
+ interrupts = <8>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+
+ eth0: ethernet-controller@72000 {
+ compatible = "marvell,kirkwood-eth";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x72000 0x4000>;
+ clocks = <&gate_clk 0>;
+ marvell,tx-checksum-limit = <1600>;
+ status = "disabled";
+
+ eth0port: ethernet0-port@0 {
+ compatible = "marvell,kirkwood-eth-port";
+ reg = <0>;
+ interrupts = <11>;
+ /* overwrite MAC address in bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ /* set phy-handle property in board file */
+ };
+ };
+
+ mdio: mdio-bus@72004 {
+ compatible = "marvell,orion-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x72004 0x84>;
+ interrupts = <46>;
+ clocks = <&gate_clk 0>;
+ status = "disabled";
+
+ /* add phy nodes in board file */
+ };
+
+ eth1: ethernet-controller@76000 {
+ compatible = "marvell,kirkwood-eth";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x76000 0x4000>;
+ clocks = <&gate_clk 19>;
+ marvell,tx-checksum-limit = <1600>;
+ pinctrl-0 = <&pmx_ge1>;
+ pinctrl-names = "default";
+ status = "disabled";
+
+ eth1port: ethernet1-port@0 {
+ compatible = "marvell,kirkwood-eth-port";
+ reg = <0>;
+ interrupts = <15>;
+ /* overwrite MAC address in bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ /* set phy-handle property in board file */
+ };
+ };
+
+ sata_phy0: sata-phy@82000 {
+ compatible = "marvell,mvebu-sata-phy";
+ reg = <0x82000 0x0334>;
+ clocks = <&gate_clk 14>;
+ clock-names = "sata";
+ #phy-cells = <0>;
+ status = "ok";
+ };
+
+ sata_phy1: sata-phy@84000 {
+ compatible = "marvell,mvebu-sata-phy";
+ reg = <0x84000 0x0334>;
+ clocks = <&gate_clk 15>;
+ clock-names = "sata";
+ #phy-cells = <0>;
+ status = "ok";
+ };
+
+ audio0: audio-controller@a0000 {
+ compatible = "marvell,kirkwood-audio";
+ #sound-dai-cells = <0>;
+ reg = <0xa0000 0x2210>;
+ interrupts = <24>;
+ clocks = <&gate_clk 9>;
+ clock-names = "internal";
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kizbox.dts b/arch/arm/boot/dts/kizbox.dts
new file mode 100644
index 000000000..e83e4f931
--- /dev/null
+++ b/arch/arm/boot/dts/kizbox.dts
@@ -0,0 +1,150 @@
+/*
+ * kizbox.dts - Device Tree file for Overkiz Kizbox board
+ *
+ * Copyright (C) 2012 Boris BREZILLON <linux-arm@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+/dts-v1/;
+#include "at91sam9g20.dtsi"
+
+/ {
+
+ model = "Overkiz kizbox";
+ compatible = "overkiz,kizbox", "atmel,at91sam9g20", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "panic=5 ubi.mtd=1 rootfstype=ubifs root=ubi0:root";
+ };
+
+ memory {
+ reg = <0x20000000 0x2000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <18432000>;
+ };
+
+ main_xtal {
+ clock-frequency = <18432000>;
+ };
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ usart0: serial@fffb0000 {
+ status = "okay";
+ };
+
+ usart1: serial@fffb4000 {
+ status = "okay";
+ };
+
+ macb0: ethernet@fffc4000 {
+ phy-mode = "mii";
+ pinctrl-0 = <&pinctrl_macb_rmii
+ &pinctrl_macb_rmii_mii_alt>;
+ status = "okay";
+ };
+
+ watchdog@fffffd40 {
+ timeout-sec = <15>;
+ atmel,max-heartbeat-sec = <16>;
+ atmel,min-heartbeat-sec = <0>;
+ status = "okay";
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ status = "okay";
+
+ bootloaderkernel@0 {
+ label = "bootloader-kernel";
+ reg = <0x0 0xc0000>;
+ };
+
+ ubi@c0000 {
+ label = "ubi";
+ reg = <0xc0000 0x7f40000>;
+ };
+
+ };
+
+ usb0: ohci@00500000 {
+ num-ports = <1>;
+ status = "okay";
+ };
+ };
+
+ i2c@0 {
+ status = "okay";
+
+ pcf8563@51 {
+ /* nxp pcf8563 rtc */
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led1g {
+ label = "led1:green";
+ gpios = <&pioB 0 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "none";
+ };
+
+ led1r {
+ label = "led1:red";
+ gpios = <&pioB 1 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "none";
+ };
+
+ led2g {
+ label = "led2:green";
+ gpios = <&pioB 2 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "none";
+ default-state = "on";
+ };
+
+ led2r {
+ label = "led2:red";
+ gpios = <&pioB 3 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "none";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reset {
+ label = "reset";
+ gpios = <&pioB 30 GPIO_ACTIVE_LOW>;
+ linux,code = <0x100>;
+ gpio-key,wakeup;
+ };
+
+ mode {
+ label = "mode";
+ gpios = <&pioB 31 GPIO_ACTIVE_LOW>;
+ linux,code = <0x101>;
+ gpio-key,wakeup;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
new file mode 100644
index 000000000..3abebb75f
--- /dev/null
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -0,0 +1,299 @@
+/*
+ * NXP LPC32xx SoC
+ *
+ * Copyright 2012 Roland Stigge <stigge@antcom.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
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "nxp,lpc3220";
+ interrupt-parent = <&mic>;
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm926ej-s";
+ device_type = "cpu";
+ };
+ };
+
+ ahb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x20000000 0x20000000 0x30000000>;
+
+ /*
+ * Enable either SLC or MLC
+ */
+ slc: flash@20020000 {
+ compatible = "nxp,lpc3220-slc";
+ reg = <0x20020000 0x1000>;
+ status = "disabled";
+ };
+
+ mlc: flash@200a8000 {
+ compatible = "nxp,lpc3220-mlc";
+ reg = <0x200a8000 0x11000>;
+ interrupts = <11 0>;
+ status = "disabled";
+ };
+
+ dma@31000000 {
+ compatible = "arm,pl080", "arm,primecell";
+ reg = <0x31000000 0x1000>;
+ interrupts = <0x1c 0>;
+ };
+
+ /*
+ * Enable either ohci or usbd (gadget)!
+ */
+ ohci@31020000 {
+ compatible = "nxp,ohci-nxp", "usb-ohci";
+ reg = <0x31020000 0x300>;
+ interrupts = <0x3b 0>;
+ status = "disabled";
+ };
+
+ usbd@31020000 {
+ compatible = "nxp,lpc3220-udc";
+ reg = <0x31020000 0x300>;
+ interrupts = <0x3d 0>, <0x3e 0>, <0x3c 0>, <0x3a 0>;
+ status = "disabled";
+ };
+
+ clcd@31040000 {
+ compatible = "arm,pl110", "arm,primecell";
+ reg = <0x31040000 0x1000>;
+ interrupts = <0x0e 0>;
+ status = "disabled";
+ };
+
+ mac: ethernet@31060000 {
+ compatible = "nxp,lpc-eth";
+ reg = <0x31060000 0x1000>;
+ interrupts = <0x1d 0>;
+ };
+
+ apb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x20000000 0x20000000 0x30000000>;
+
+ ssp0: ssp@20084000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x20084000 0x1000>;
+ interrupts = <0x14 0>;
+ };
+
+ spi1: spi@20088000 {
+ compatible = "nxp,lpc3220-spi";
+ reg = <0x20088000 0x1000>;
+ };
+
+ ssp1: ssp@2008c000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x2008c000 0x1000>;
+ interrupts = <0x15 0>;
+ };
+
+ spi2: spi@20090000 {
+ compatible = "nxp,lpc3220-spi";
+ reg = <0x20090000 0x1000>;
+ };
+
+ i2s0: i2s@20094000 {
+ compatible = "nxp,lpc3220-i2s";
+ reg = <0x20094000 0x1000>;
+ };
+
+ sd@20098000 {
+ compatible = "arm,pl18x", "arm,primecell";
+ reg = <0x20098000 0x1000>;
+ interrupts = <0x0f 0>, <0x0d 0>;
+ status = "disabled";
+ };
+
+ i2s1: i2s@2009C000 {
+ compatible = "nxp,lpc3220-i2s";
+ reg = <0x2009C000 0x1000>;
+ };
+
+ /* UART5 first since it is the default console, ttyS0 */
+ uart5: serial@40090000 {
+ /* actually, ns16550a w/ 64 byte fifos! */
+ compatible = "nxp,lpc3220-uart";
+ reg = <0x40090000 0x1000>;
+ interrupts = <9 0>;
+ clock-frequency = <13000000>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart3: serial@40080000 {
+ compatible = "nxp,lpc3220-uart";
+ reg = <0x40080000 0x1000>;
+ interrupts = <7 0>;
+ clock-frequency = <13000000>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart4: serial@40088000 {
+ compatible = "nxp,lpc3220-uart";
+ reg = <0x40088000 0x1000>;
+ interrupts = <8 0>;
+ clock-frequency = <13000000>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart6: serial@40098000 {
+ compatible = "nxp,lpc3220-uart";
+ reg = <0x40098000 0x1000>;
+ interrupts = <10 0>;
+ clock-frequency = <13000000>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@400A0000 {
+ compatible = "nxp,pnx-i2c";
+ reg = <0x400A0000 0x100>;
+ interrupts = <0x33 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pnx,timeout = <0x64>;
+ };
+
+ i2c2: i2c@400A8000 {
+ compatible = "nxp,pnx-i2c";
+ reg = <0x400A8000 0x100>;
+ interrupts = <0x32 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pnx,timeout = <0x64>;
+ };
+
+ mpwm: mpwm@400E8000 {
+ compatible = "nxp,lpc3220-motor-pwm";
+ reg = <0x400E8000 0x78>;
+ status = "disabled";
+ #pwm-cells = <2>;
+ };
+
+ i2cusb: i2c@31020300 {
+ compatible = "nxp,pnx-i2c";
+ reg = <0x31020300 0x100>;
+ interrupts = <0x3f 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pnx,timeout = <0x64>;
+ };
+ };
+
+ fab {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x20000000 0x20000000 0x30000000>;
+
+ /*
+ * MIC Interrupt controller includes:
+ * MIC @40008000
+ * SIC1 @4000C000
+ * SIC2 @40010000
+ */
+ mic: interrupt-controller@40008000 {
+ compatible = "nxp,lpc3220-mic";
+ interrupt-controller;
+ reg = <0x40008000 0xC000>;
+ #interrupt-cells = <2>;
+ };
+
+ uart1: serial@40014000 {
+ compatible = "nxp,lpc3220-hsuart";
+ reg = <0x40014000 0x1000>;
+ interrupts = <26 0>;
+ status = "disabled";
+ };
+
+ uart2: serial@40018000 {
+ compatible = "nxp,lpc3220-hsuart";
+ reg = <0x40018000 0x1000>;
+ interrupts = <25 0>;
+ status = "disabled";
+ };
+
+ uart7: serial@4001c000 {
+ compatible = "nxp,lpc3220-hsuart";
+ reg = <0x4001c000 0x1000>;
+ interrupts = <24 0>;
+ status = "disabled";
+ };
+
+ rtc@40024000 {
+ compatible = "nxp,lpc3220-rtc";
+ reg = <0x40024000 0x1000>;
+ interrupts = <0x34 0>;
+ };
+
+ gpio: gpio@40028000 {
+ compatible = "nxp,lpc3220-gpio";
+ reg = <0x40028000 0x1000>;
+ gpio-controller;
+ #gpio-cells = <3>; /* bank, pin, flags */
+ };
+
+ watchdog@4003C000 {
+ compatible = "nxp,pnx4008-wdt";
+ reg = <0x4003C000 0x1000>;
+ };
+
+ /*
+ * TSC vs. ADC: Since those two share the same
+ * hardware, you need to choose from one of the
+ * following two and do 'status = "okay";' for one of
+ * them
+ */
+
+ adc@40048000 {
+ compatible = "nxp,lpc3220-adc";
+ reg = <0x40048000 0x1000>;
+ interrupts = <0x27 0>;
+ status = "disabled";
+ };
+
+ tsc@40048000 {
+ compatible = "nxp,lpc3220-tsc";
+ reg = <0x40048000 0x1000>;
+ interrupts = <0x27 0>;
+ status = "disabled";
+ };
+
+ key@40050000 {
+ compatible = "nxp,lpc3220-key";
+ reg = <0x40050000 0x1000>;
+ interrupts = <54 0>;
+ status = "disabled";
+ };
+
+ pwm: pwm@4005C000 {
+ compatible = "nxp,lpc3220-pwm";
+ reg = <0x4005C000 0x8>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ls1021a-qds.dts b/arch/arm/boot/dts/ls1021a-qds.dts
new file mode 100644
index 000000000..9c5e16ba8
--- /dev/null
+++ b/arch/arm/boot/dts/ls1021a-qds.dts
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2013-2014 Freescale Semiconductor, Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "ls1021a.dtsi"
+
+/ {
+ model = "LS1021A QDS Board";
+
+ aliases {
+ enet0_rgmii_phy = &rgmii_phy1;
+ enet1_rgmii_phy = &rgmii_phy2;
+ enet2_rgmii_phy = &rgmii_phy3;
+ enet0_sgmii_phy = &sgmii_phy1c;
+ enet1_sgmii_phy = &sgmii_phy1d;
+ };
+};
+
+&dspi0 {
+ bus-num = <0>;
+ status = "okay";
+
+ dspiflash: at45db021d@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at45db021d", "atmel,at45", "atmel,dataflash";
+ spi-max-frequency = <16000000>;
+ spi-cpol;
+ spi-cpha;
+ reg = <0>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+
+ pca9547: mux@77 {
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0>;
+
+ ds3232: rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2>;
+
+ ina220@40 {
+ compatible = "ti,ina220";
+ reg = <0x40>;
+ shunt-resistor = <1000>;
+ };
+
+ ina220@41 {
+ compatible = "ti,ina220";
+ reg = <0x41>;
+ shunt-resistor = <1000>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3>;
+
+ eeprom@56 {
+ compatible = "atmel,24c512";
+ reg = <0x56>;
+ };
+
+ eeprom@57 {
+ compatible = "atmel,24c512";
+ reg = <0x57>;
+ };
+
+ adt7461a@4c {
+ compatible = "adi,adt7461a";
+ reg = <0x4c>;
+ };
+ };
+ };
+};
+
+&ifc {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ /* NOR, NAND Flashes and FPGA on board */
+ ranges = <0x0 0x0 0x0 0x60000000 0x08000000
+ 0x2 0x0 0x0 0x7e800000 0x00010000
+ 0x3 0x0 0x0 0x7fb00000 0x00000100>;
+ status = "okay";
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ fpga: board-control@3,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ reg = <0x3 0x0 0x0000100>;
+ bank-width = <1>;
+ device-width = <1>;
+ ranges = <0 3 0 0x100>;
+
+ mdio-mux-emi1 {
+ compatible = "mdio-mux-mmioreg";
+ mdio-parent-bus = <&mdio0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x54 1>; /* BRDCFG4 */
+ mux-mask = <0xe0>; /* EMI1[2:0] */
+
+ /* Onboard PHYs */
+ ls1021amdio0: mdio@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ rgmii_phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ };
+
+ ls1021amdio1: mdio@20 {
+ reg = <0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ rgmii_phy2: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+ };
+
+ ls1021amdio2: mdio@40 {
+ reg = <0x40>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ rgmii_phy3: ethernet-phy@3 {
+ reg = <0x3>;
+ };
+ };
+
+ ls1021amdio3: mdio@60 {
+ reg = <0x60>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ sgmii_phy1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+ };
+
+ ls1021amdio4: mdio@80 {
+ reg = <0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ sgmii_phy1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+ };
+ };
+ };
+};
+
+&lpuart0 {
+ status = "okay";
+};
+
+&mdio0 {
+ tbi0: tbi-phy@8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/ls1021a-twr.dts b/arch/arm/boot/dts/ls1021a-twr.dts
new file mode 100644
index 000000000..a2c591e2d
--- /dev/null
+++ b/arch/arm/boot/dts/ls1021a-twr.dts
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2013-2014 Freescale Semiconductor, Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "ls1021a.dtsi"
+
+/ {
+ model = "LS1021A TWR Board";
+
+ aliases {
+ enet2_rgmii_phy = &rgmii_phy1;
+ enet0_sgmii_phy = &sgmii_phy2;
+ enet1_sgmii_phy = &sgmii_phy0;
+ };
+};
+
+&dspi1 {
+ bus-num = <0>;
+ status = "okay";
+
+ dspiflash: s25fl064k@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25fl064k";
+ spi-max-frequency = <16000000>;
+ spi-cpol;
+ spi-cpha;
+ reg = <0>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+&i2c1 {
+ status = "okay";
+};
+
+&ifc {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ /* NOR Flash on board */
+ ranges = <0x0 0x0 0x0 0x60000000 0x08000000>;
+ status = "okay";
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+};
+
+&lpuart0 {
+ status = "okay";
+};
+
+&mdio0 {
+ sgmii_phy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ rgmii_phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ sgmii_phy2: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+ tbi1: tbi-phy@1f {
+ reg = <0x1f>;
+ device_type = "tbi-phy";
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
new file mode 100644
index 000000000..c70bb27ac
--- /dev/null
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -0,0 +1,409 @@
+/*
+ * Copyright 2013-2014 Freescale Semiconductor, Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "skeleton64.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "fsl,ls1021a";
+ interrupt-parent = <&gic>;
+
+ aliases {
+ serial0 = &lpuart0;
+ serial1 = &lpuart1;
+ serial2 = &lpuart2;
+ serial3 = &lpuart3;
+ serial4 = &lpuart4;
+ serial5 = &lpuart5;
+ sysclk = &sysclk;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@f00 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0xf00>;
+ clocks = <&cluster1_clk>;
+ };
+
+ cpu@f01 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0xf01>;
+ clocks = <&cluster1_clk>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ device_type = "soc";
+ interrupt-parent = <&gic>;
+ ranges;
+
+ gic: interrupt-controller@1400000 {
+ compatible = "arm,cortex-a7-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x0 0x1401000 0x0 0x1000>,
+ <0x0 0x1402000 0x0 0x1000>,
+ <0x0 0x1404000 0x0 0x2000>,
+ <0x0 0x1406000 0x0 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+
+ };
+
+ ifc: ifc@1530000 {
+ compatible = "fsl,ifc", "simple-bus";
+ reg = <0x0 0x1530000 0x0 0x10000>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dcfg: dcfg@1ee0000 {
+ compatible = "fsl,ls1021a-dcfg", "syscon";
+ reg = <0x0 0x1ee0000 0x0 0x10000>;
+ big-endian;
+ };
+
+ esdhc: esdhc@1560000 {
+ compatible = "fsl,esdhc";
+ reg = <0x0 0x1560000 0x0 0x10000>;
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <0>;
+ voltage-ranges = <1800 1800 3300 3300>;
+ sdhci,auto-cmd12;
+ big-endian;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ scfg: scfg@1570000 {
+ compatible = "fsl,ls1021a-scfg", "syscon";
+ reg = <0x0 0x1570000 0x0 0x10000>;
+ big-endian;
+ };
+
+ clockgen: clocking@1ee1000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x0 0x1ee1000 0x10000>;
+
+ sysclk: sysclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-output-names = "sysclk";
+ };
+
+ cga_pll1: pll@800 {
+ compatible = "fsl,qoriq-core-pll-2.0";
+ #clock-cells = <1>;
+ reg = <0x800 0x10>;
+ clocks = <&sysclk>;
+ clock-output-names = "cga-pll1", "cga-pll1-div2",
+ "cga-pll1-div4";
+ };
+
+ platform_clk: pll@c00 {
+ compatible = "fsl,qoriq-core-pll-2.0";
+ #clock-cells = <1>;
+ reg = <0xc00 0x10>;
+ clocks = <&sysclk>;
+ clock-output-names = "platform-clk", "platform-clk-div2";
+ };
+
+ cluster1_clk: clk0c0@0 {
+ compatible = "fsl,qoriq-core-mux-2.0";
+ #clock-cells = <0>;
+ reg = <0x0 0x10>;
+ clock-names = "pll1cga", "pll1cga-div2", "pll1cga-div4";
+ clocks = <&cga_pll1 0>, <&cga_pll1 1>, <&cga_pll1 2>;
+ clock-output-names = "cluster1-clk";
+ };
+ };
+
+ dspi0: dspi@2100000 {
+ compatible = "fsl,vf610-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x2100000 0x0 0x10000>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "dspi";
+ clocks = <&platform_clk 1>;
+ spi-num-chipselects = <5>;
+ big-endian;
+ status = "disabled";
+ };
+
+ dspi1: dspi@2110000 {
+ compatible = "fsl,vf610-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x2110000 0x0 0x10000>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "dspi";
+ clocks = <&platform_clk 1>;
+ spi-num-chipselects = <5>;
+ big-endian;
+ status = "disabled";
+ };
+
+ i2c0: i2c@2180000 {
+ compatible = "fsl,vf610-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x2180000 0x0 0x10000>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "i2c";
+ clocks = <&platform_clk 1>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@2190000 {
+ compatible = "fsl,vf610-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x2190000 0x0 0x10000>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "i2c";
+ clocks = <&platform_clk 1>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@21a0000 {
+ compatible = "fsl,vf610-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x21a0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "i2c";
+ clocks = <&platform_clk 1>;
+ status = "disabled";
+ };
+
+ uart0: serial@21c0500 {
+ compatible = "fsl,16550-FIFO64", "ns16550a";
+ reg = <0x0 0x21c0500 0x0 0x100>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <0>;
+ fifo-size = <15>;
+ status = "disabled";
+ };
+
+ uart1: serial@21c0600 {
+ compatible = "fsl,16550-FIFO64", "ns16550a";
+ reg = <0x0 0x21c0600 0x0 0x100>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <0>;
+ fifo-size = <15>;
+ status = "disabled";
+ };
+
+ uart2: serial@21d0500 {
+ compatible = "fsl,16550-FIFO64", "ns16550a";
+ reg = <0x0 0x21d0500 0x0 0x100>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <0>;
+ fifo-size = <15>;
+ status = "disabled";
+ };
+
+ uart3: serial@21d0600 {
+ compatible = "fsl,16550-FIFO64", "ns16550a";
+ reg = <0x0 0x21d0600 0x0 0x100>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <0>;
+ fifo-size = <15>;
+ status = "disabled";
+ };
+
+ lpuart0: serial@2950000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x2950000 0x0 0x1000>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sysclk>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart1: serial@2960000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x2960000 0x0 0x1000>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart2: serial@2970000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x2970000 0x0 0x1000>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart3: serial@2980000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x2980000 0x0 0x1000>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart4: serial@2990000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x2990000 0x0 0x1000>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart5: serial@29a0000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x29a0000 0x0 0x1000>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ wdog0: watchdog@2ad0000 {
+ compatible = "fsl,imx21-wdt";
+ reg = <0x0 0x2ad0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ clock-names = "wdog-en";
+ big-endian;
+ };
+
+ sai1: sai@2b50000 {
+ compatible = "fsl,vf610-sai";
+ reg = <0x0 0x2b50000 0x0 0x10000>;
+ interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ clock-names = "sai";
+ dma-names = "tx", "rx";
+ dmas = <&edma0 1 47>,
+ <&edma0 1 46>;
+ big-endian;
+ status = "disabled";
+ };
+
+ sai2: sai@2b60000 {
+ compatible = "fsl,vf610-sai";
+ reg = <0x0 0x2b60000 0x0 0x10000>;
+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ clock-names = "sai";
+ dma-names = "tx", "rx";
+ dmas = <&edma0 1 45>,
+ <&edma0 1 44>;
+ big-endian;
+ status = "disabled";
+ };
+
+ edma0: edma@2c00000 {
+ #dma-cells = <2>;
+ compatible = "fsl,vf610-edma";
+ reg = <0x0 0x2c00000 0x0 0x10000>,
+ <0x0 0x2c10000 0x0 0x10000>,
+ <0x0 0x2c20000 0x0 0x10000>;
+ interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma-tx", "edma-err";
+ dma-channels = <32>;
+ big-endian;
+ clock-names = "dmamux0", "dmamux1";
+ clocks = <&platform_clk 1>,
+ <&platform_clk 1>;
+ };
+
+ mdio0: mdio@2d24000 {
+ compatible = "gianfar";
+ device_type = "mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x2d24000 0x0 0x4000>;
+ };
+
+ usb@8600000 {
+ compatible = "fsl-usb2-dr-v2.5", "fsl-usb2-dr";
+ reg = <0x0 0x8600000 0x0 0x1000>;
+ interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+ dr_mode = "host";
+ phy_type = "ulpi";
+ };
+
+ usb3@3100000 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0x3100000 0x0 0x10000>;
+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+ dr_mode = "host";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/meson.dtsi b/arch/arm/boot/dts/meson.dtsi
new file mode 100644
index 000000000..548441384
--- /dev/null
+++ b/arch/arm/boot/dts/meson.dtsi
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2014 Carlo Caione <carlo@caione.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&gic>;
+
+ L2: l2-cache-controller@c4200000 {
+ compatible = "arm,pl310-cache";
+ reg = <0xc4200000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ gic: interrupt-controller@c4301000 {
+ compatible = "arm,cortex-a9-gic";
+ reg = <0xc4301000 0x1000>,
+ <0xc4300100 0x0100>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
+
+ timer@c1109940 {
+ compatible = "amlogic,meson6-timer";
+ reg = <0xc1109940 0x14>;
+ interrupts = <0 10 1>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ wdt: watchdog@c1109900 {
+ compatible = "amlogic,meson6-wdt";
+ reg = <0xc1109900 0x8>;
+ };
+
+ uart_AO: serial@c81004c0 {
+ compatible = "amlogic,meson-uart";
+ reg = <0xc81004c0 0x14>;
+ interrupts = <0 90 1>;
+ clocks = <&clk81>;
+ status = "disabled";
+ };
+
+ uart_A: serial@c81084c0 {
+ compatible = "amlogic,meson-uart";
+ reg = <0xc81084c0 0x14>;
+ interrupts = <0 90 1>;
+ clocks = <&clk81>;
+ status = "disabled";
+ };
+
+ uart_B: serial@c81084dc {
+ compatible = "amlogic,meson-uart";
+ reg = <0xc81084dc 0x14>;
+ interrupts = <0 90 1>;
+ clocks = <&clk81>;
+ status = "disabled";
+ };
+
+ uart_C: serial@c8108700 {
+ compatible = "amlogic,meson-uart";
+ reg = <0xc8108700 0x14>;
+ interrupts = <0 90 1>;
+ clocks = <&clk81>;
+ status = "disabled";
+ };
+
+ i2c_AO: i2c@c8100500 {
+ compatible = "amlogic,meson6-i2c";
+ reg = <0xc8100500 0x20>;
+ interrupts = <0 92 1>;
+ clocks = <&clk81>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c_A: i2c@c1108500 {
+ compatible = "amlogic,meson6-i2c";
+ reg = <0xc1108500 0x20>;
+ interrupts = <0 21 1>;
+ clocks = <&clk81>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c_B: i2c@c11087c0 {
+ compatible = "amlogic,meson6-i2c";
+ reg = <0xc11087c0 0x20>;
+ interrupts = <0 128 1>;
+ clocks = <&clk81>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ ir_receiver: ir-receiver@c8100480 {
+ compatible= "amlogic,meson6-ir";
+ reg = <0xc8100480 0x20>;
+ interrupts = <0 15 1>;
+ status = "disabled";
+ };
+
+ spifc: spi@c1108c80 {
+ compatible = "amlogic,meson6-spifc";
+ reg = <0xc1108c80 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clk81>;
+ status = "disabled";
+ };
+
+ ethmac: ethernet@c9410000 {
+ compatible = "amlogic,meson6-dwmac", "snps,dwmac";
+ reg = <0xc9410000 0x10000
+ 0xc1108108 0x4>;
+ interrupts = <0 8 1>;
+ interrupt-names = "macirq";
+ clocks = <&clk81>;
+ clock-names = "stmmaceth";
+ status = "disabled";
+ };
+ };
+}; /* end of / */
diff --git a/arch/arm/boot/dts/meson6-atv1200.dts b/arch/arm/boot/dts/meson6-atv1200.dts
new file mode 100644
index 000000000..1237faa63
--- /dev/null
+++ b/arch/arm/boot/dts/meson6-atv1200.dts
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2014 Carlo Caione <carlo@caione.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+/include/ "meson6.dtsi"
+
+/ {
+ model = "Geniatech ATV1200";
+ compatible = "geniatech,atv1200", "amlogic,meson6";
+
+ aliases {
+ serial0 = &uart_AO;
+ };
+
+ memory {
+ reg = <0x40000000 0x80000000>;
+ };
+};
+
+&uart_AO {
+ status = "okay";
+};
+
+&ethmac {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/meson6.dtsi b/arch/arm/boot/dts/meson6.dtsi
new file mode 100644
index 000000000..8b33be15a
--- /dev/null
+++ b/arch/arm/boot/dts/meson6.dtsi
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2014 Carlo Caione <carlo@caione.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/include/ "meson.dtsi"
+
+/ {
+ model = "Amlogic Meson6 SoC";
+ compatible = "amlogic,meson6";
+
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x200>;
+ };
+
+ cpu@201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x201>;
+ };
+ };
+
+ clk81: clk@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <200000000>;
+ };
+}; /* end of / */
diff --git a/arch/arm/boot/dts/meson8-minix-neo-x8.dts b/arch/arm/boot/dts/meson8-minix-neo-x8.dts
new file mode 100644
index 000000000..4f536bb1f
--- /dev/null
+++ b/arch/arm/boot/dts/meson8-minix-neo-x8.dts
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2014 Beniamino Galvani <b.galvani@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include "meson8.dtsi"
+
+/ {
+ model = "MINIX NEO-X8";
+ compatible = "minix,neo-x8", "amlogic,meson8";
+
+ aliases {
+ serial0 = &uart_AO;
+ };
+
+ memory {
+ reg = <0x40000000 0x80000000>;
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ blue {
+ label = "x8:blue:power";
+ gpios = <&gpio_ao GPIO_TEST_N GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+ pinctrl-names = "default";
+};
+
+&i2c_AO {
+ status = "okay";
+ pinctrl-0 = <&i2c_ao_pins>;
+ pinctrl-names = "default";
+
+ pmic@32 {
+ compatible = "ricoh,rn5t618";
+ reg = <0x32>;
+
+ regulators {
+ };
+ };
+
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+};
+
+&spifc {
+ status = "okay";
+ pinctrl-0 = <&spi_nor_pins>;
+ pinctrl-names = "default";
+
+ spi-flash@0 {
+ compatible = "mxicy,mx25l1606e";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0>;
+ spi-max-frequency = <30000000>;
+
+ partition@0 {
+ label = "boot";
+ reg = <0x0 0x100000>;
+ };
+
+ partition@100000 {
+ label = "env";
+ reg = <0x100000 0x10000>;
+ };
+ };
+};
+
+&ir_receiver {
+ status = "okay";
+ pinctrl-0 = <&ir_recv_pins>;
+ pinctrl-names = "default";
+};
+
+&ethmac {
+ status = "okay";
+ pinctrl-0 = <&eth_pins>;
+ pnictrl-names = "default";
+};
diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi
new file mode 100644
index 000000000..a2ddcb8c5
--- /dev/null
+++ b/arch/arm/boot/dts/meson8.dtsi
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2014 Carlo Caione <carlo@caione.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/gpio/meson8-gpio.h>
+/include/ "meson.dtsi"
+
+/ {
+ model = "Amlogic Meson8 SoC";
+ compatible = "amlogic,meson8";
+
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x200>;
+ };
+
+ cpu@201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x201>;
+ };
+
+ cpu@202 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x202>;
+ };
+
+ cpu@203 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x203>;
+ };
+ };
+
+ clk81: clk@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <141666666>;
+ };
+
+ pinctrl: pinctrl@c1109880 {
+ compatible = "amlogic,meson8-pinctrl";
+ reg = <0xc1109880 0x10>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio: banks@c11080b0 {
+ reg = <0xc11080b0 0x28>,
+ <0xc11080e8 0x18>,
+ <0xc1108120 0x18>,
+ <0xc1108030 0x30>;
+ reg-names = "mux", "pull", "pull-enable", "gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio_ao: ao-bank@c1108030 {
+ reg = <0xc8100014 0x4>,
+ <0xc810002c 0x4>,
+ <0xc8100024 0x8>;
+ reg-names = "mux", "pull", "gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ uart_ao_a_pins: uart_ao_a {
+ mux {
+ groups = "uart_tx_ao_a", "uart_rx_ao_a";
+ function = "uart_ao";
+ };
+ };
+
+ i2c_ao_pins: i2c_mst_ao {
+ mux {
+ groups = "i2c_mst_sck_ao", "i2c_mst_sda_ao";
+ function = "i2c_mst_ao";
+ };
+ };
+
+ spi_nor_pins: nor {
+ mux {
+ groups = "nor_d", "nor_q", "nor_c", "nor_cs";
+ function = "nor";
+ };
+ };
+
+ ir_recv_pins: remote {
+ mux {
+ groups = "remote_input";
+ function = "remote";
+ };
+ };
+
+ eth_pins: ethernet {
+ mux {
+ groups = "eth_tx_clk_50m", "eth_tx_en",
+ "eth_txd1", "eth_txd0",
+ "eth_rx_clk_in", "eth_rx_dv",
+ "eth_rxd1", "eth_rxd0", "eth_mdio",
+ "eth_mdc";
+ function = "ethernet";
+ };
+ };
+ };
+
+}; /* end of / */
diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts b/arch/arm/boot/dts/mmp2-brownstone.dts
new file mode 100644
index 000000000..350208c5e
--- /dev/null
+++ b/arch/arm/boot/dts/mmp2-brownstone.dts
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@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.
+ */
+
+/dts-v1/;
+#include "mmp2.dtsi"
+
+/ {
+ model = "Marvell MMP2 Brownstone Development Board";
+ compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2";
+
+ chosen {
+ bootargs = "console=ttyS2,38400 root=/dev/nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ soc {
+ apb@d4000000 {
+ uart3: uart@d4018000 {
+ status = "okay";
+ };
+ twsi1: i2c@d4011000 {
+ status = "okay";
+ pmic: max8925@3c {
+ compatible = "maxium,max8925";
+ reg = <0x3c>;
+ interrupts = <1>;
+ interrupt-parent = <&intcmux4>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ maxim,tsc-irq = <0>;
+
+ regulators {
+ SDV1 {
+ regulator-min-microvolt = <637500>;
+ regulator-max-microvolt = <1425000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ SDV2 {
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <2225000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ SDV3 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO1 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO2 {
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <2250000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO3 {
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <2250000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO4 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO5 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO6 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO7 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO8 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO9 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO10 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ };
+ LDO11 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO12 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO13 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO14 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO15 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO16 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO17 {
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <2250000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO18 {
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <2250000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO19 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO20 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ backlight {
+ maxim,max8925-dual-string = <0>;
+ };
+ charger {
+ batt-detect = <0>;
+ topoff-threshold = <1>;
+ fast-charge = <7>;
+ no-temp-support = <0>;
+ no-insert-detect = <0>;
+ };
+ };
+ };
+ rtc: rtc@d4010000 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
new file mode 100644
index 000000000..766bbb849
--- /dev/null
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@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 "skeleton.dtsi"
+#include <dt-bindings/clock/marvell,mmp2.h>
+
+/ {
+ aliases {
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ i2c0 = &twsi1;
+ i2c1 = &twsi2;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&intc>;
+ ranges;
+
+ L2: l2-cache {
+ compatible = "marvell,tauros2-cache";
+ marvell,tauros2-cache-features = <0x3>;
+ };
+
+ axi@d4200000 { /* AXI */
+ compatible = "mrvl,axi-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd4200000 0x00200000>;
+ ranges;
+
+ intc: interrupt-controller@d4282000 {
+ compatible = "mrvl,mmp2-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xd4282000 0x1000>;
+ mrvl,intc-nr-irqs = <64>;
+ };
+
+ intcmux4: interrupt-controller@d4282150 {
+ compatible = "mrvl,mmp2-mux-intc";
+ interrupts = <4>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x150 0x4>, <0x168 0x4>;
+ reg-names = "mux status", "mux mask";
+ mrvl,intc-nr-irqs = <2>;
+ };
+
+ intcmux5: interrupt-controller@d4282154 {
+ compatible = "mrvl,mmp2-mux-intc";
+ interrupts = <5>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x154 0x4>, <0x16c 0x4>;
+ reg-names = "mux status", "mux mask";
+ mrvl,intc-nr-irqs = <2>;
+ mrvl,clr-mfp-irq = <1>;
+ };
+
+ intcmux9: interrupt-controller@d4282180 {
+ compatible = "mrvl,mmp2-mux-intc";
+ interrupts = <9>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x180 0x4>, <0x17c 0x4>;
+ reg-names = "mux status", "mux mask";
+ mrvl,intc-nr-irqs = <3>;
+ };
+
+ intcmux17: interrupt-controller@d4282158 {
+ compatible = "mrvl,mmp2-mux-intc";
+ interrupts = <17>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x158 0x4>, <0x170 0x4>;
+ reg-names = "mux status", "mux mask";
+ mrvl,intc-nr-irqs = <5>;
+ };
+
+ intcmux35: interrupt-controller@d428215c {
+ compatible = "mrvl,mmp2-mux-intc";
+ interrupts = <35>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x15c 0x4>, <0x174 0x4>;
+ reg-names = "mux status", "mux mask";
+ mrvl,intc-nr-irqs = <15>;
+ };
+
+ intcmux51: interrupt-controller@d4282160 {
+ compatible = "mrvl,mmp2-mux-intc";
+ interrupts = <51>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x160 0x4>, <0x178 0x4>;
+ reg-names = "mux status", "mux mask";
+ mrvl,intc-nr-irqs = <2>;
+ };
+
+ intcmux55: interrupt-controller@d4282188 {
+ compatible = "mrvl,mmp2-mux-intc";
+ interrupts = <55>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x188 0x4>, <0x184 0x4>;
+ reg-names = "mux status", "mux mask";
+ mrvl,intc-nr-irqs = <2>;
+ };
+ };
+
+ apb@d4000000 { /* APB */
+ compatible = "mrvl,apb-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd4000000 0x00200000>;
+ ranges;
+
+ timer0: timer@d4014000 {
+ compatible = "mrvl,mmp-timer";
+ reg = <0xd4014000 0x100>;
+ interrupts = <13>;
+ };
+
+ uart1: uart@d4030000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4030000 0x1000>;
+ interrupts = <27>;
+ clocks = <&soc_clocks MMP2_CLK_UART0>;
+ resets = <&soc_clocks MMP2_CLK_UART0>;
+ status = "disabled";
+ };
+
+ uart2: uart@d4017000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4017000 0x1000>;
+ interrupts = <28>;
+ clocks = <&soc_clocks MMP2_CLK_UART1>;
+ resets = <&soc_clocks MMP2_CLK_UART1>;
+ status = "disabled";
+ };
+
+ uart3: uart@d4018000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4018000 0x1000>;
+ interrupts = <24>;
+ clocks = <&soc_clocks MMP2_CLK_UART2>;
+ resets = <&soc_clocks MMP2_CLK_UART2>;
+ status = "disabled";
+ };
+
+ uart4: uart@d4016000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4016000 0x1000>;
+ interrupts = <46>;
+ clocks = <&soc_clocks MMP2_CLK_UART3>;
+ resets = <&soc_clocks MMP2_CLK_UART3>;
+ status = "disabled";
+ };
+
+ gpio@d4019000 {
+ compatible = "marvell,mmp2-gpio";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd4019000 0x1000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <49>;
+ interrupt-names = "gpio_mux";
+ clocks = <&soc_clocks MMP2_CLK_GPIO>;
+ resets = <&soc_clocks MMP2_CLK_GPIO>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ ranges;
+
+ gcb0: gpio@d4019000 {
+ reg = <0xd4019000 0x4>;
+ };
+
+ gcb1: gpio@d4019004 {
+ reg = <0xd4019004 0x4>;
+ };
+
+ gcb2: gpio@d4019008 {
+ reg = <0xd4019008 0x4>;
+ };
+
+ gcb3: gpio@d4019100 {
+ reg = <0xd4019100 0x4>;
+ };
+
+ gcb4: gpio@d4019104 {
+ reg = <0xd4019104 0x4>;
+ };
+
+ gcb5: gpio@d4019108 {
+ reg = <0xd4019108 0x4>;
+ };
+ };
+
+ twsi1: i2c@d4011000 {
+ compatible = "mrvl,mmp-twsi";
+ reg = <0xd4011000 0x1000>;
+ interrupts = <7>;
+ clocks = <&soc_clocks MMP2_CLK_TWSI0>;
+ resets = <&soc_clocks MMP2_CLK_TWSI0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ mrvl,i2c-fast-mode;
+ status = "disabled";
+ };
+
+ twsi2: i2c@d4025000 {
+ compatible = "mrvl,mmp-twsi";
+ reg = <0xd4025000 0x1000>;
+ interrupts = <58>;
+ clocks = <&soc_clocks MMP2_CLK_TWSI1>;
+ resets = <&soc_clocks MMP2_CLK_TWSI1>;
+ status = "disabled";
+ };
+
+ rtc: rtc@d4010000 {
+ compatible = "mrvl,mmp-rtc";
+ reg = <0xd4010000 0x1000>;
+ interrupts = <1 0>;
+ interrupt-names = "rtc 1Hz", "rtc alarm";
+ interrupt-parent = <&intcmux5>;
+ clocks = <&soc_clocks MMP2_CLK_RTC>;
+ resets = <&soc_clocks MMP2_CLK_RTC>;
+ status = "disabled";
+ };
+ };
+
+ soc_clocks: clocks{
+ compatible = "marvell,mmp2-clock";
+ reg = <0xd4050000 0x1000>,
+ <0xd4282800 0x400>,
+ <0xd4015000 0x1000>;
+ reg-names = "mpmu", "apmu", "apbc";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/moxart-uc7112lx.dts b/arch/arm/boot/dts/moxart-uc7112lx.dts
new file mode 100644
index 000000000..10d088df0
--- /dev/null
+++ b/arch/arm/boot/dts/moxart-uc7112lx.dts
@@ -0,0 +1,117 @@
+/* moxart-uc7112lx.dts - Device Tree file for MOXA UC-7112-LX
+ *
+ * Copyright (C) 2013 Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/dts-v1/;
+/include/ "moxart.dtsi"
+
+/ {
+ model = "MOXA UC-7112-LX";
+ compatible = "moxa,moxart-uc-7112-lx", "moxa,moxart";
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x2000000>;
+ };
+
+ clocks {
+ ref12: ref12M {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <12000000>;
+ };
+ };
+
+ flash@80000000,0 {
+ compatible = "numonyx,js28f128", "cfi-flash";
+ reg = <0x80000000 0x1000000>;
+ bank-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "bootloader";
+ reg = <0x0 0x40000>;
+ };
+ partition@40000 {
+ label = "linux kernel";
+ reg = <0x40000 0x1C0000>;
+ };
+ partition@200000 {
+ label = "root filesystem";
+ reg = <0x200000 0x800000>;
+ };
+ partition@a00000 {
+ label = "user filesystem";
+ reg = <0xa00000 0x600000>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ user-led {
+ label = "ready-led";
+ gpios = <&gpio 27 0x1>;
+ default-state = "on";
+ linux,default-trigger = "default-on";
+ };
+ };
+
+ gpio_keys_polled {
+ compatible = "gpio-keys-polled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ poll-interval = <500>;
+ button@25 {
+ label = "GPIO Reset";
+ linux,code = <116>;
+ gpios = <&gpio 25 1>;
+ };
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk root=/dev/mmcblk0p1 rw rootwait";
+ };
+};
+
+&clk_pll {
+ clocks = <&ref12>;
+};
+
+&sdhci {
+ status = "okay";
+};
+
+&mdio0 {
+ status = "okay";
+
+ ethphy0: ethernet-phy@1 {
+ device_type = "ethernet-phy";
+ compatible = "moxa,moxart-rtl8201cp", "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+};
+
+&mdio1 {
+ status = "okay";
+
+ ethphy1: ethernet-phy@1 {
+ device_type = "ethernet-phy";
+ compatible = "moxa,moxart-rtl8201cp", "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+};
+
+&mac0 {
+ status = "okay";
+};
+
+&mac1 {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/moxart.dtsi b/arch/arm/boot/dts/moxart.dtsi
new file mode 100644
index 000000000..1fd27ed65
--- /dev/null
+++ b/arch/arm/boot/dts/moxart.dtsi
@@ -0,0 +1,148 @@
+/* moxart.dtsi - Device Tree Include file for MOXA ART family SoC
+ *
+ * Copyright (C) 2013 Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "moxa,moxart";
+ model = "MOXART";
+ interrupt-parent = <&intc>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "faraday,fa526";
+ reg = <0>;
+ };
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x90000000 0x10000000>;
+ ranges;
+
+ intc: interrupt-controller@98800000 {
+ compatible = "moxa,moxart-ic";
+ reg = <0x98800000 0x38>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-mask = <0x00080000>;
+ };
+
+ clk_pll: clk_pll@98100000 {
+ compatible = "moxa,moxart-pll-clock";
+ #clock-cells = <0>;
+ reg = <0x98100000 0x34>;
+ };
+
+ clk_apb: clk_apb@98100000 {
+ compatible = "moxa,moxart-apb-clock";
+ #clock-cells = <0>;
+ reg = <0x98100000 0x34>;
+ clocks = <&clk_pll>;
+ };
+
+ timer: timer@98400000 {
+ compatible = "moxa,moxart-timer";
+ reg = <0x98400000 0x42>;
+ interrupts = <19 1>;
+ clocks = <&clk_apb>;
+ };
+
+ gpio: gpio@98700000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ compatible = "moxa,moxart-gpio";
+ reg = <0x98700000 0xC>;
+ };
+
+ rtc: rtc {
+ compatible = "moxa,moxart-rtc";
+ gpio-rtc-sclk = <&gpio 5 0>;
+ gpio-rtc-data = <&gpio 6 0>;
+ gpio-rtc-reset = <&gpio 7 0>;
+ };
+
+ dma: dma@90500000 {
+ compatible = "moxa,moxart-dma";
+ reg = <0x90500080 0x40>;
+ interrupts = <24 0>;
+ #dma-cells = <1>;
+ };
+
+ watchdog: watchdog@98500000 {
+ compatible = "moxa,moxart-watchdog";
+ reg = <0x98500000 0x10>;
+ clocks = <&clk_apb>;
+ };
+
+ sdhci: sdhci@98e00000 {
+ compatible = "moxa,moxart-sdhci";
+ reg = <0x98e00000 0x5C>;
+ interrupts = <5 0>;
+ clocks = <&clk_apb>;
+ dmas = <&dma 5>,
+ <&dma 5>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mdio0: mdio@90900090 {
+ compatible = "moxa,moxart-mdio";
+ reg = <0x90900090 0x8>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ mdio1: mdio@92000090 {
+ compatible = "moxa,moxart-mdio";
+ reg = <0x92000090 0x8>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ mac0: mac@90900000 {
+ compatible = "moxa,moxart-mac";
+ reg = <0x90900000 0x90>;
+ interrupts = <25 0>;
+ phy-handle = <&ethphy0>;
+ phy-mode = "mii";
+ status = "disabled";
+ };
+
+ mac1: mac@92000000 {
+ compatible = "moxa,moxart-mac";
+ reg = <0x92000000 0x90>;
+ interrupts = <27 0>;
+ phy-handle = <&ethphy1>;
+ phy-mode = "mii";
+ status = "disabled";
+ };
+
+ uart0: uart@98200000 {
+ compatible = "ns16550a";
+ reg = <0x98200000 0x20>;
+ interrupts = <31 8>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <14745600>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/mpa1600.dts b/arch/arm/boot/dts/mpa1600.dts
new file mode 100644
index 000000000..f0f5e1098
--- /dev/null
+++ b/arch/arm/boot/dts/mpa1600.dts
@@ -0,0 +1,77 @@
+/*
+ * mpa1600.dts - Device Tree file for Phontech MPA 1600
+ *
+ * Copyright (C) 2013 Joachim Eastwood <manabian@gmail.com>
+ *
+ * Licensed under GPLv2 only
+ */
+/dts-v1/;
+#include "at91rm9200.dtsi"
+
+/ {
+ model = "Phontech MPA 1600";
+ compatible = "phontech,mpa1600", "atmel,at91rm9200";
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <18432000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <18432000>;
+ };
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ macb0: ethernet@fffbc000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ ssc0: ssc@fffd0000 {
+ status = "okay";
+ };
+
+ ssc1: ssc@fffd4000 {
+ status = "okay";
+ };
+ };
+
+ usb0: ohci@00300000 {
+ num-ports = <1>;
+ status = "okay";
+ };
+ };
+
+ i2c@0 {
+ status = "okay";
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ monitor_mute {
+ label = "Monitor mute";
+ gpios = <&pioC 1 GPIO_ACTIVE_LOW>;
+ linux,code = <113>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/mt6589-aquaris5.dts b/arch/arm/boot/dts/mt6589-aquaris5.dts
new file mode 100644
index 000000000..594a6f3be
--- /dev/null
+++ b/arch/arm/boot/dts/mt6589-aquaris5.dts
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Matthias Brugger <matthias.bgg@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.
+ */
+
+/dts-v1/;
+#include "mt6589.dtsi"
+
+/ {
+ model = "bq Aquaris5";
+ compatible = "mundoreader,bq-aquaris5", "mediatek,mt6589";
+
+ chosen {
+ bootargs = "console=ttyS0,921600n8 earlyprintk";
+ stdout-path = &uart0;
+ };
+
+ memory {
+ reg = <0x80000000 0x40000000>;
+ };
+
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/mt6589.dtsi b/arch/arm/boot/dts/mt6589.dtsi
new file mode 100644
index 000000000..88b3cb128
--- /dev/null
+++ b/arch/arm/boot/dts/mt6589.dtsi
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Matthias Brugger <matthias.bgg@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.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "mediatek,mt6589";
+ interrupt-parent = <&sysirq>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x0>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x1>;
+ };
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x2>;
+ };
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x3>;
+ };
+
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+
+ system_clk: dummy13m {
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ #clock-cells = <0>;
+ };
+
+ rtc_clk: dummy32k {
+ compatible = "fixed-clock";
+ clock-frequency = <32000>;
+ #clock-cells = <0>;
+ };
+
+ uart_clk: dummy26m {
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ #clock-cells = <0>;
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+
+ timer: timer@10008000 {
+ compatible = "mediatek,mt6577-timer";
+ reg = <0x10008000 0x80>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&system_clk>, <&rtc_clk>;
+ clock-names = "system-clk", "rtc-clk";
+ };
+
+ sysirq: interrupt-controller@10200100 {
+ compatible = "mediatek,mt6589-sysirq",
+ "mediatek,mt6577-sysirq";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0x10200100 0x1c>;
+ };
+
+ gic: interrupt-controller@10211000 {
+ compatible = "arm,cortex-a7-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0x10211000 0x1000>,
+ <0x10212000 0x1000>,
+ <0x10214000 0x2000>,
+ <0x10216000 0x2000>;
+ };
+
+ uart0: serial@11006000 {
+ compatible = "mediatek,mt6577-uart";
+ reg = <0x11006000 0x400>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart1: serial@11007000 {
+ compatible = "mediatek,mt6577-uart";
+ reg = <0x11007000 0x400>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart2: serial@11008000 {
+ compatible = "mediatek,mt6577-uart";
+ reg = <0x11008000 0x400>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart3: serial@11009000 {
+ compatible = "mediatek,mt6577-uart";
+ reg = <0x11009000 0x400>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ wdt: watchdog@010000000 {
+ compatible = "mediatek,mt6589-wdt";
+ reg = <0x10000000 0x44>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/mt6592-evb.dts b/arch/arm/boot/dts/mt6592-evb.dts
new file mode 100644
index 000000000..b57237e63
--- /dev/null
+++ b/arch/arm/boot/dts/mt6592-evb.dts
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Howard Chen <ibanezchen@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.
+ */
+
+/dts-v1/;
+#include "mt6592.dtsi"
+
+/ {
+ model = "mt6592 evb";
+ compatible = "mediatek,mt6592-evb", "mediatek,mt6592";
+
+ memory {
+ reg = <0x80000000 0x40000000>;
+ };
+};
+
diff --git a/arch/arm/boot/dts/mt6592.dtsi b/arch/arm/boot/dts/mt6592.dtsi
new file mode 100644
index 000000000..c69201fff
--- /dev/null
+++ b/arch/arm/boot/dts/mt6592.dtsi
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Howard Chen <ibanezchen@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.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "mediatek,mt6592";
+ interrupt-parent = <&sysirq>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x0>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x1>;
+ };
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x2>;
+ };
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x3>;
+ };
+ cpu@4 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x4>;
+ };
+ cpu@5 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x5>;
+ };
+ cpu@6 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x6>;
+ };
+ cpu@7 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x7>;
+ };
+ };
+
+ system_clk: dummy13m {
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ #clock-cells = <0>;
+ };
+
+ rtc_clk: dummy32k {
+ compatible = "fixed-clock";
+ clock-frequency = <32000>;
+ #clock-cells = <0>;
+ };
+
+ uart_clk: dummy26m {
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ #clock-cells = <0>;
+ };
+
+ timer: timer@10008000 {
+ compatible = "mediatek,mt6577-timer";
+ reg = <0x10008000 0x80>;
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&system_clk>, <&rtc_clk>;
+ clock-names = "system-clk", "rtc-clk";
+ };
+
+ sysirq: interrupt-controller@10200220 {
+ compatible = "mediatek,mt6592-sysirq", "mediatek,mt6577-sysirq";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0x10200220 0x1c>;
+ };
+
+ gic: interrupt-controller@10211000 {
+ compatible = "arm,cortex-a7-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0x10211000 0x1000>,
+ <0x10212000 0x1000>;
+ };
+
+ uart0: serial@11002000 {
+ compatible = "mediatek,mt6577-uart";
+ reg = <0x11002000 0x400>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart1: serial@11003000 {
+ compatible = "mediatek,mt6577-uart";
+ reg = <0x11003000 0x400>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart2: serial@11004000 {
+ compatible = "mediatek,mt6577-uart";
+ reg = <0x11004000 0x400>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart3: serial@11005000 {
+ compatible = "mediatek,mt6577-uart";
+ reg = <0x11005000 0x400>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/mt8127-moose.dts b/arch/arm/boot/dts/mt8127-moose.dts
new file mode 100644
index 000000000..073e295a1
--- /dev/null
+++ b/arch/arm/boot/dts/mt8127-moose.dts
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Joe.C <yingjoe.chen@mediatek.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.
+ */
+
+/dts-v1/;
+#include "mt8127.dtsi"
+
+/ {
+ model = "MediaTek MT8127 Moose Board";
+ compatible = "mediatek,mt8127-moose", "mediatek,mt8127";
+
+ memory {
+ reg = <0 0x80000000 0 0x40000000>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/mt8127.dtsi b/arch/arm/boot/dts/mt8127.dtsi
new file mode 100644
index 000000000..aaa786233
--- /dev/null
+++ b/arch/arm/boot/dts/mt8127.dtsi
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Joe.C <yingjoe.chen@mediatek.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 <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "skeleton64.dtsi"
+
+/ {
+ compatible = "mediatek,mt8127";
+ interrupt-parent = <&sysirq>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x0>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x1>;
+ };
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x2>;
+ };
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x3>;
+ };
+
+ };
+
+ clocks {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "simple-bus";
+ ranges;
+
+ system_clk: dummy13m {
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ #clock-cells = <0>;
+ };
+
+ rtc_clk: dummy32k {
+ compatible = "fixed-clock";
+ clock-frequency = <32000>;
+ #clock-cells = <0>;
+ };
+
+ uart_clk: dummy26m {
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ #clock-cells = <0>;
+ };
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "simple-bus";
+ ranges;
+
+ timer: timer@10008000 {
+ compatible = "mediatek,mt8127-timer",
+ "mediatek,mt6577-timer";
+ reg = <0 0x10008000 0 0x80>;
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&system_clk>, <&rtc_clk>;
+ clock-names = "system-clk", "rtc-clk";
+ };
+
+ sysirq: interrupt-controller@10200100 {
+ compatible = "mediatek,mt8127-sysirq",
+ "mediatek,mt6577-sysirq";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0 0x10200100 0 0x1c>;
+ };
+
+ gic: interrupt-controller@10211000 {
+ compatible = "arm,cortex-a7-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0 0x10211000 0 0x1000>,
+ <0 0x10212000 0 0x1000>,
+ <0 0x10214000 0 0x2000>,
+ <0 0x10216000 0 0x2000>;
+ };
+
+ uart0: serial@11006000 {
+ compatible = "mediatek,mt8127-uart","mediatek,mt6577-uart";
+ reg = <0 0x11002000 0 0x400>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart1: serial@11007000 {
+ compatible = "mediatek,mt8127-uart","mediatek,mt6577-uart";
+ reg = <0 0x11003000 0 0x400>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart2: serial@11008000 {
+ compatible = "mediatek,mt8127-uart","mediatek,mt6577-uart";
+ reg = <0 0x11004000 0 0x400>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart3: serial@11009000 {
+ compatible = "mediatek,mt8127-uart","mediatek,mt6577-uart";
+ reg = <0 0x11005000 0 0x400>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/mt8135-evbp1.dts b/arch/arm/boot/dts/mt8135-evbp1.dts
new file mode 100644
index 000000000..36677382b
--- /dev/null
+++ b/arch/arm/boot/dts/mt8135-evbp1.dts
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Joe.C <yingjoe.chen@mediatek.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.
+ */
+
+/dts-v1/;
+#include "mt8135.dtsi"
+
+/ {
+ model = "MediaTek MT8135 evaluation board";
+ compatible = "mediatek,mt8135-evbp1", "mediatek,mt8135";
+
+ memory {
+ reg = <0 0x80000000 0 0x40000000>;
+ };
+};
+
+&uart3 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/mt8135.dtsi b/arch/arm/boot/dts/mt8135.dtsi
new file mode 100644
index 000000000..a161e99ff
--- /dev/null
+++ b/arch/arm/boot/dts/mt8135.dtsi
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Joe.C <yingjoe.chen@mediatek.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 <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "skeleton64.dtsi"
+
+/ {
+ compatible = "mediatek,mt8135";
+ interrupt-parent = <&sysirq>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+ core1 {
+ cpu = <&cpu1>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&cpu2>;
+ };
+ core1 {
+ cpu = <&cpu3>;
+ };
+ };
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x000>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x001>;
+ };
+
+ cpu2: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x100>;
+ };
+
+ cpu3: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x101>;
+ };
+ };
+
+ clocks {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "simple-bus";
+ ranges;
+
+ system_clk: dummy13m {
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ #clock-cells = <0>;
+ };
+
+ rtc_clk: dummy32k {
+ compatible = "fixed-clock";
+ clock-frequency = <32000>;
+ #clock-cells = <0>;
+ };
+
+ uart_clk: dummy26m {
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ #clock-cells = <0>;
+ };
+
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "simple-bus";
+ ranges;
+
+ timer: timer@10008000 {
+ compatible = "mediatek,mt8135-timer",
+ "mediatek,mt6577-timer";
+ reg = <0 0x10008000 0 0x80>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&system_clk>, <&rtc_clk>;
+ clock-names = "system-clk", "rtc-clk";
+ };
+
+ sysirq: interrupt-controller@10200030 {
+ compatible = "mediatek,mt8135-sysirq",
+ "mediatek,mt6577-sysirq";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0 0x10200030 0 0x1c>;
+ };
+
+ gic: interrupt-controller@10211000 {
+ compatible = "arm,cortex-a15-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0 0x10211000 0 0x1000>,
+ <0 0x10212000 0 0x1000>,
+ <0 0x10214000 0 0x2000>,
+ <0 0x10216000 0 0x2000>;
+ };
+
+ uart0: serial@11006000 {
+ compatible = "mediatek,mt8135-uart","mediatek,mt6577-uart";
+ reg = <0 0x11006000 0 0x400>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart1: serial@11007000 {
+ compatible = "mediatek,mt8135-uart","mediatek,mt6577-uart";
+ reg = <0 0x11007000 0 0x400>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart2: serial@11008000 {
+ compatible = "mediatek,mt8135-uart","mediatek,mt6577-uart";
+ reg = <0 0x11008000 0 0x400>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart3: serial@11009000 {
+ compatible = "mediatek,mt8135-uart","mediatek,mt6577-uart";
+ reg = <0 0x11009000 0 0x400>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ };
+};
diff --git a/arch/arm/boot/dts/mxs-pinfunc.h b/arch/arm/boot/dts/mxs-pinfunc.h
new file mode 100644
index 000000000..c6da987b2
--- /dev/null
+++ b/arch/arm/boot/dts/mxs-pinfunc.h
@@ -0,0 +1,31 @@
+/*
+ * Header providing constants for i.MX28 pinctrl bindings.
+ *
+ * Copyright (C) 2013 Lothar WaĂŸmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DT_BINDINGS_MXS_PINCTRL_H__
+#define __DT_BINDINGS_MXS_PINCTRL_H__
+
+/* fsl,drive-strength property */
+#define MXS_DRIVE_4mA 0
+#define MXS_DRIVE_8mA 1
+#define MXS_DRIVE_12mA 2
+#define MXS_DRIVE_16mA 3
+
+/* fsl,voltage property */
+#define MXS_VOLTAGE_LOW 0
+#define MXS_VOLTAGE_HIGH 1
+
+/* fsl,pull-up property */
+#define MXS_PULL_DISABLE 0
+#define MXS_PULL_ENABLE 1
+
+#endif /* __DT_BINDINGS_MXS_PINCTRL_H__ */
diff --git a/arch/arm/boot/dts/nspire-classic.dtsi b/arch/arm/boot/dts/nspire-classic.dtsi
new file mode 100644
index 000000000..4907c5085
--- /dev/null
+++ b/arch/arm/boot/dts/nspire-classic.dtsi
@@ -0,0 +1,79 @@
+/*
+ * linux/arch/arm/boot/nspire-classic.dts
+ *
+ * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/include/ "nspire.dtsi"
+
+&lcd {
+ lcd-type = "classic";
+};
+
+&fast_timer {
+ /* compatible = "lsi,zevio-timer"; */
+ reg = <0x90010000 0x1000>, <0x900A0010 0x8>;
+};
+
+&uart {
+ compatible = "ns16550";
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb_pclk>;
+ no-loopback-test;
+};
+
+&timer0 {
+ /* compatible = "lsi,zevio-timer"; */
+ reg = <0x900C0000 0x1000>, <0x900A0018 0x8>;
+};
+
+&timer1 {
+ compatible = "lsi,zevio-timer";
+ reg = <0x900D0000 0x1000>, <0x900A0020 0x8>;
+};
+
+&keypad {
+ active-low;
+
+};
+
+&base_clk {
+ compatible = "lsi,nspire-classic-clock";
+};
+
+&ahb_clk {
+ compatible = "lsi,nspire-classic-ahb-divider";
+};
+
+
+&vbus_reg {
+ gpio = <&gpio 5 0>;
+};
+
+/ {
+ memory {
+ device_type = "memory";
+ reg = <0x10000000 0x2000000>; /* 32 MB */
+ };
+
+ ahb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ intc: interrupt-controller@DC000000 {
+ compatible = "lsi,zevio-intc";
+ interrupt-controller;
+ reg = <0xDC000000 0x1000>;
+ #interrupt-cells = <1>;
+ };
+ };
+ chosen {
+ bootargs = "debug earlyprintk console=tty0 console=ttyS0,115200n8 root=/dev/ram0";
+ };
+};
diff --git a/arch/arm/boot/dts/nspire-clp.dts b/arch/arm/boot/dts/nspire-clp.dts
new file mode 100644
index 000000000..fa5a04465
--- /dev/null
+++ b/arch/arm/boot/dts/nspire-clp.dts
@@ -0,0 +1,45 @@
+/*
+ * linux/arch/arm/boot/nspire-clp.dts
+ *
+ * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+/dts-v1/;
+
+/include/ "nspire-classic.dtsi"
+
+&keypad {
+ linux,keymap = <
+ 0x0000001c 0x0001001c 0x00020039
+ 0x0004002c 0x00050034 0x00060015
+ 0x0007000b 0x0008002d 0x01000033
+ 0x0101004e 0x01020011 0x01030004
+ 0x0104002f 0x01050003 0x01060016
+ 0x01070002 0x01080014 0x02000062
+ 0x0201000c 0x0202001f 0x02030007
+ 0x02040013 0x02050006 0x02060010
+ 0x02070005 0x02080019 0x03000027
+ 0x03010037 0x03020018 0x0303000a
+ 0x03040031 0x03050009 0x03060032
+ 0x03070008 0x03080026 0x04000028
+ 0x04010035 0x04020025 0x04040024
+ 0x04060017 0x04080023 0x05000028
+ 0x05020022 0x0503001b 0x05040021
+ 0x0505001a 0x05060012 0x0507006f
+ 0x05080020 0x0509002a 0x0601001c
+ 0x0602002e 0x06030068 0x06040030
+ 0x0605006d 0x0606001e 0x06070001
+ 0x0608002b 0x0609000f 0x07000067
+ 0x0702006a 0x0704006c 0x07060069
+ 0x0707000e 0x0708001d 0x070a000d
+ >;
+};
+
+/ {
+ model = "TI-NSPIRE Clickpad";
+ compatible = "ti,nspire-clp";
+};
diff --git a/arch/arm/boot/dts/nspire-cx.dts b/arch/arm/boot/dts/nspire-cx.dts
new file mode 100644
index 000000000..08e0b81b3
--- /dev/null
+++ b/arch/arm/boot/dts/nspire-cx.dts
@@ -0,0 +1,116 @@
+/*
+ * linux/arch/arm/boot/nspire-cx.dts
+ *
+ * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+/dts-v1/;
+
+/include/ "nspire.dtsi"
+
+&lcd {
+ lcd-type = "cx";
+};
+
+&fast_timer {
+ /* compatible = "arm,sp804", "arm,primecell"; */
+};
+
+&uart {
+ compatible = "arm,pl011", "arm,primecell";
+
+ clocks = <&uart_clk>, <&apb_pclk>;
+ clock-names = "uart_clk", "apb_pclk";
+};
+
+&timer0 {
+ compatible = "arm,sp804", "arm,primecell";
+};
+
+&timer1 {
+ compatible = "arm,sp804", "arm,primecell";
+};
+
+&base_clk {
+ compatible = "lsi,nspire-cx-clock";
+};
+
+&ahb_clk {
+ compatible = "lsi,nspire-cx-ahb-divider";
+};
+
+&keypad {
+ linux,keymap = <
+ 0x0000001c 0x0001001c 0x00040039
+ 0x0005002c 0x00060015 0x0007000b
+ 0x0008000f 0x0100002d 0x01010011
+ 0x0102002f 0x01030004 0x01040016
+ 0x01050014 0x0106001f 0x01070002
+ 0x010a006a 0x02000013 0x02010010
+ 0x02020019 0x02030007 0x02040018
+ 0x02050031 0x02060032 0x02070005
+ 0x02080028 0x0209006c 0x03000026
+ 0x03010025 0x03020024 0x0303000a
+ 0x03040017 0x03050023 0x03060022
+ 0x03070008 0x03080035 0x03090069
+ 0x04000021 0x04010012 0x04020020
+ 0x0404002e 0x04050030 0x0406001e
+ 0x0407000d 0x04080037 0x04090067
+ 0x05010038 0x0502000c 0x0503001b
+ 0x05040034 0x0505001a 0x05060006
+ 0x05080027 0x0509000e 0x050a006f
+ 0x0600002b 0x0602004e 0x06030068
+ 0x06040003 0x0605006d 0x06060009
+ 0x06070001 0x0609000f 0x0708002a
+ 0x0709001d 0x070a0033 >;
+};
+
+&vbus_reg {
+ gpio = <&gpio 2 0>;
+};
+
+/ {
+ model = "TI-NSPIRE CX";
+ compatible = "ti,nspire-cx";
+
+ memory {
+ device_type = "memory";
+ reg = <0x10000000 0x4000000>; /* 64 MB */
+ };
+
+ uart_clk: uart_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ ahb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ intc: interrupt-controller@DC000000 {
+ compatible = "arm,pl190-vic";
+ interrupt-controller;
+ reg = <0xDC000000 0x1000>;
+ #interrupt-cells = <1>;
+ };
+
+ apb@90000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ i2c@90050000 {
+ compatible = "snps,designware-i2c";
+ reg = <0x90050000 0x1000>;
+ interrupts = <20>;
+ };
+ };
+ };
+ chosen {
+ bootargs = "debug earlyprintk console=tty0 console=ttyAMA0,115200n8 root=/dev/ram0";
+ };
+};
diff --git a/arch/arm/boot/dts/nspire-tp.dts b/arch/arm/boot/dts/nspire-tp.dts
new file mode 100644
index 000000000..621391ce6
--- /dev/null
+++ b/arch/arm/boot/dts/nspire-tp.dts
@@ -0,0 +1,44 @@
+/*
+ * linux/arch/arm/boot/nspire-tp.dts
+ *
+ * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+/dts-v1/;
+
+/include/ "nspire-classic.dtsi"
+
+&keypad {
+ linux,keymap = <
+ 0x0000001c 0x0001001c 0x00040039
+ 0x0005002c 0x00060015 0x0007000b
+ 0x0008000f 0x0100002d 0x01010011
+ 0x0102002f 0x01030004 0x01040016
+ 0x01050014 0x0106001f 0x01070002
+ 0x010a006a 0x02000013 0x02010010
+ 0x02020019 0x02030007 0x02040018
+ 0x02050031 0x02060032 0x02070005
+ 0x02080028 0x0209006c 0x03000026
+ 0x03010025 0x03020024 0x0303000a
+ 0x03040017 0x03050023 0x03060022
+ 0x03070008 0x03080035 0x03090069
+ 0x04000021 0x04010012 0x04020020
+ 0x0404002e 0x04050030 0x0406001e
+ 0x0407000d 0x04080037 0x04090067
+ 0x05010038 0x0502000c 0x0503001b
+ 0x05040034 0x0505001a 0x05060006
+ 0x05080027 0x0509000e 0x050a006f
+ 0x0600002b 0x0602004e 0x06030068
+ 0x06040003 0x0605006d 0x06060009
+ 0x06070001 0x0609000f 0x0708002a
+ 0x0709001d 0x070a0033 >;
+};
+
+/ {
+ model = "TI-NSPIRE Touchpad";
+ compatible = "ti,nspire-tp";
+};
diff --git a/arch/arm/boot/dts/nspire.dtsi b/arch/arm/boot/dts/nspire.dtsi
new file mode 100644
index 000000000..390c91aea
--- /dev/null
+++ b/arch/arm/boot/dts/nspire.dtsi
@@ -0,0 +1,196 @@
+/*
+ * linux/arch/arm/boot/nspire.dtsi
+ *
+ * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&intc>;
+
+ cpus {
+ cpu@0 {
+ compatible = "arm,arm926ejs";
+ };
+ };
+
+ bootrom: bootrom@00000000 {
+ reg = <0x00000000 0x80000>;
+ };
+
+ sram: sram@A4000000 {
+ device = "memory";
+ reg = <0xA4000000 0x20000>;
+ };
+
+ timer_clk: timer_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ base_clk: base_clk {
+ #clock-cells = <0>;
+ reg = <0x900B0024 0x4>;
+ };
+
+ ahb_clk: ahb_clk {
+ #clock-cells = <0>;
+ reg = <0x900B0024 0x4>;
+ clocks = <&base_clk>;
+ };
+
+ apb_pclk: apb_pclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <2>;
+ clock-mult = <1>;
+ clocks = <&ahb_clk>;
+ };
+
+ usb_phy: usb_phy {
+ compatible = "usb-nop-xceiv";
+ };
+
+ vbus_reg: vbus_reg {
+ compatible = "regulator-fixed";
+
+ regulator-name = "USB VBUS output";
+ regulator-type = "voltage";
+
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ spi: spi@A9000000 {
+ reg = <0xA9000000 0x1000>;
+ };
+
+ usb0: usb@B0000000 {
+ compatible = "lsi,zevio-usb";
+ reg = <0xB0000000 0x1000>;
+ interrupts = <8>;
+
+ usb-phy = <&usb_phy>;
+ vbus-supply = <&vbus_reg>;
+ };
+
+ usb1: usb@B4000000 {
+ reg = <0xB4000000 0x1000>;
+ interrupts = <9>;
+ status = "disabled";
+ };
+
+ lcd: lcd@C0000000 {
+ compatible = "arm,pl111", "arm,primecell";
+ reg = <0xC0000000 0x1000>;
+ interrupts = <21>;
+
+ clocks = <&apb_pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ adc: adc@C4000000 {
+ reg = <0xC4000000 0x1000>;
+ interrupts = <11>;
+ };
+
+ tdes: crypto@C8010000 {
+ reg = <0xC8010000 0x1000>;
+ };
+
+ sha256: crypto@CC000000 {
+ reg = <0xCC000000 0x1000>;
+ };
+
+ apb@90000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clock-ranges;
+ ranges;
+
+ gpio: gpio@90000000 {
+ compatible = "lsi,zevio-gpio";
+ reg = <0x90000000 0x1000>;
+ interrupts = <7>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ fast_timer: timer@90010000 {
+ reg = <0x90010000 0x1000>;
+ interrupts = <17>;
+ };
+
+ uart: serial@90020000 {
+ reg = <0x90020000 0x1000>;
+ interrupts = <1>;
+ };
+
+ timer0: timer@900C0000 {
+ reg = <0x900C0000 0x1000>;
+
+ clocks = <&timer_clk>;
+ };
+
+ timer1: timer@900D0000 {
+ reg = <0x900D0000 0x1000>;
+ interrupts = <19>;
+
+ clocks = <&timer_clk>;
+ };
+
+ watchdog: watchdog@90060000 {
+ compatible = "arm,amba-primecell";
+ reg = <0x90060000 0x1000>;
+ interrupts = <3>;
+ };
+
+ rtc: rtc@90090000 {
+ reg = <0x90090000 0x1000>;
+ interrupts = <4>;
+ };
+
+ misc: misc@900A0000 {
+ reg = <0x900A0000 0x1000>;
+ };
+
+ pwr: pwr@900B0000 {
+ reg = <0x900B0000 0x1000>;
+ interrupts = <15>;
+ };
+
+ keypad: input@900E0000 {
+ compatible = "ti,nspire-keypad";
+ reg = <0x900E0000 0x1000>;
+ interrupts = <16>;
+
+ scan-interval = <1000>;
+ row-delay = <200>;
+
+ clocks = <&apb_pclk>;
+ };
+
+ contrast: contrast@900F0000 {
+ reg = <0x900F0000 0x1000>;
+ };
+
+ led: led@90110000 {
+ reg = <0x90110000 0x1000>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
new file mode 100644
index 000000000..445fafc73
--- /dev/null
+++ b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
@@ -0,0 +1,54 @@
+/*
+ * Common file for GPMC connected smsc911x on omaps
+ *
+ * Note that the board specifc DTS file needs to specify
+ * ranges, pinctrl, reg, interrupt parent and interrupts.
+ */
+
+/ {
+ vddvario: regulator-vddvario {
+ compatible = "regulator-fixed";
+ regulator-name = "vddvario";
+ regulator-always-on;
+ };
+
+ vdd33a: regulator-vdd33a {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd33a";
+ regulator-always-on;
+ };
+};
+
+&gpmc {
+ ethernet@gpmc {
+ compatible = "smsc,lan9221", "smsc,lan9115";
+ bank-width = <2>;
+ gpmc,device-width = <1>;
+ gpmc,cycle2cycle-samecsen = <1>;
+ gpmc,cycle2cycle-diffcsen = <1>;
+ gpmc,cs-on-ns = <5>;
+ gpmc,cs-rd-off-ns = <150>;
+ gpmc,cs-wr-off-ns = <150>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <15>;
+ gpmc,adv-wr-off-ns = <40>;
+ gpmc,oe-on-ns = <45>;
+ gpmc,oe-off-ns = <140>;
+ gpmc,we-on-ns = <45>;
+ gpmc,we-off-ns = <140>;
+ gpmc,rd-cycle-ns = <155>;
+ gpmc,wr-cycle-ns = <155>;
+ gpmc,access-ns = <120>;
+ gpmc,page-burst-access-ns = <20>;
+ gpmc,bus-turnaround-ns = <75>;
+ gpmc,cycle2cycle-delay-ns = <75>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+ gpmc,wr-access-ns = <0>;
+ vddvario-supply = <&vddvario>;
+ vdd33a-supply = <&vdd33a>;
+ reg-io-width = <4>;
+ smsc,save-mac-address;
+ };
+};
diff --git a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
new file mode 100644
index 000000000..73e272fad
--- /dev/null
+++ b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
@@ -0,0 +1,58 @@
+/*
+ * Common file for GPMC connected smsc9221 on omaps
+ *
+ * Compared to smsc911x, smsc9221 (and others like smsc9217
+ * or smsc 9218) has faster timings, leading to higher
+ * bandwidth.
+ *
+ * Note that the board specifc DTS file needs to specify
+ * ranges, pinctrl, reg, interrupt parent and interrupts.
+ */
+
+/ {
+ vddvario: regulator-vddvario {
+ compatible = "regulator-fixed";
+ regulator-name = "vddvario";
+ regulator-always-on;
+ };
+
+ vdd33a: regulator-vdd33a {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd33a";
+ regulator-always-on;
+ };
+};
+
+&gpmc {
+ ethernet@gpmc {
+ compatible = "smsc,lan9221","smsc,lan9115";
+ bank-width = <2>;
+
+ gpmc,mux-add-data;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <42>;
+ gpmc,cs-wr-off-ns = <36>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <12>;
+ gpmc,adv-wr-off-ns = <12>;
+ gpmc,oe-on-ns = <0>;
+ gpmc,oe-off-ns = <42>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <36>;
+ gpmc,rd-cycle-ns = <60>;
+ gpmc,wr-cycle-ns = <54>;
+ gpmc,access-ns = <36>;
+ gpmc,page-burst-access-ns = <0>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,wr-data-mux-bus-ns = <18>;
+ gpmc,wr-access-ns = <42>;
+ gpmc,cycle2cycle-samecsen;
+ gpmc,cycle2cycle-diffcsen;
+
+ vddvario-supply = <&vddvario>;
+ vdd33a-supply = <&vdd33a>;
+ reg-io-width = <4>;
+ smsc,save-mac-address;
+ };
+};
diff --git a/arch/arm/boot/dts/omap-zoom-common.dtsi b/arch/arm/boot/dts/omap-zoom-common.dtsi
new file mode 100644
index 000000000..46ef3e443
--- /dev/null
+++ b/arch/arm/boot/dts/omap-zoom-common.dtsi
@@ -0,0 +1,91 @@
+/*
+ * Common features on the Zoom debug board
+ */
+
+#include "omap-gpmc-smsc911x.dtsi"
+
+&gpmc {
+ ranges = <3 0 0x10000000 0x1000000>, /* CS3: 16MB for UART */
+ <7 0 0x2c000000 0x01000000>;
+
+ /*
+ * Four port TL16CP754C serial port on GPMC,
+ * they probably share the same GPIO IRQ
+ * REVISIT: Add timing support from slls644g.pdf
+ */
+ uart@3,0 {
+ compatible = "ns16550a";
+ reg = <3 0 8>; /* CS3, offset 0, IO size 8 */
+ bank-width = <2>;
+ reg-shift = <1>;
+ reg-io-width = <1>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <6 IRQ_TYPE_EDGE_RISING>; /* gpio102 */
+ clock-frequency = <1843200>;
+ current-speed = <115200>;
+ gpmc,mux-add-data = <0>;
+ gpmc,device-width = <1>;
+ gpmc,wait-pin = <1>;
+ gpmc,cycle2cycle-samecsen = <1>;
+ gpmc,cycle2cycle-diffcsen = <1>;
+ gpmc,cs-on-ns = <5>;
+ gpmc,cs-rd-off-ns = <155>;
+ gpmc,cs-wr-off-ns = <155>;
+ gpmc,adv-on-ns = <15>;
+ gpmc,adv-rd-off-ns = <40>;
+ gpmc,adv-wr-off-ns = <40>;
+ gpmc,oe-on-ns = <45>;
+ gpmc,oe-off-ns = <145>;
+ gpmc,we-on-ns = <45>;
+ gpmc,we-off-ns = <145>;
+ gpmc,rd-cycle-ns = <155>;
+ gpmc,wr-cycle-ns = <155>;
+ gpmc,access-ns = <145>;
+ gpmc,page-burst-access-ns = <20>;
+ gpmc,bus-turnaround-ns = <20>;
+ gpmc,cycle2cycle-delay-ns = <20>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wr-data-mux-bus-ns = <45>;
+ gpmc,wr-access-ns = <145>;
+ };
+ uart@3,1 {
+ compatible = "ns16550a";
+ reg = <3 0x100 8>; /* CS3, offset 0x100, IO size 8 */
+ bank-width = <2>;
+ reg-shift = <1>;
+ reg-io-width = <1>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <6 IRQ_TYPE_EDGE_RISING>; /* gpio102 */
+ clock-frequency = <1843200>;
+ current-speed = <115200>;
+ };
+ uart@3,2 {
+ compatible = "ns16550a";
+ reg = <3 0x200 8>; /* CS3, offset 0x200, IO size 8 */
+ bank-width = <2>;
+ reg-shift = <1>;
+ reg-io-width = <1>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <6 IRQ_TYPE_EDGE_RISING>; /* gpio102 */
+ clock-frequency = <1843200>;
+ current-speed = <115200>;
+ };
+ uart@3,3 {
+ compatible = "ns16550a";
+ reg = <3 0x300 8>; /* CS3, offset 0x300, IO size 8 */
+ bank-width = <2>;
+ reg-shift = <1>;
+ reg-io-width = <1>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <6 IRQ_TYPE_EDGE_RISING>; /* gpio102 */
+ clock-frequency = <1843200>;
+ current-speed = <115200>;
+ };
+
+ ethernet@gpmc {
+ reg = <7 0 0xff>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <30 IRQ_TYPE_LEVEL_LOW>; /* gpio158 */
+ };
+};
diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi
new file mode 100644
index 000000000..578fa2a54
--- /dev/null
+++ b/arch/arm/boot/dts/omap2.dtsi
@@ -0,0 +1,298 @@
+/*
+ * Device Tree Source for OMAP2 SoC
+ *
+ * Copyright (C) 2011 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/omap.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "ti,omap2430", "ti,omap2420", "ti,omap2";
+ interrupt-parent = <&intc>;
+
+ aliases {
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ };
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm1136jf-s";
+ device_type = "cpu";
+ };
+ };
+
+ pmu {
+ compatible = "arm,arm1136-pmu";
+ interrupts = <3>;
+ };
+
+ soc {
+ compatible = "ti,omap-infra";
+ mpu {
+ compatible = "ti,omap2-mpu";
+ ti,hwmods = "mpu";
+ };
+ };
+
+ ocp {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "l3_main";
+
+ aes: aes@480a6000 {
+ compatible = "ti,omap2-aes";
+ ti,hwmods = "aes";
+ reg = <0x480a6000 0x50>;
+ dmas = <&sdma 9 &sdma 10>;
+ dma-names = "tx", "rx";
+ };
+
+ hdq1w: 1w@480b2000 {
+ compatible = "ti,omap2420-1w";
+ ti,hwmods = "hdq1w";
+ reg = <0x480b2000 0x1000>;
+ interrupts = <58>;
+ };
+
+ intc: interrupt-controller@1 {
+ compatible = "ti,omap2-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x480FE000 0x1000>;
+ };
+
+ sdma: dma-controller@48056000 {
+ compatible = "ti,omap2430-sdma", "ti,omap2420-sdma";
+ ti,hwmods = "dma";
+ reg = <0x48056000 0x1000>;
+ interrupts = <12>,
+ <13>,
+ <14>,
+ <15>;
+ #dma-cells = <1>;
+ dma-channels = <32>;
+ dma-requests = <64>;
+ };
+
+ i2c1: i2c@48070000 {
+ compatible = "ti,omap2-i2c";
+ ti,hwmods = "i2c1";
+ reg = <0x48070000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <56>;
+ dmas = <&sdma 27 &sdma 28>;
+ dma-names = "tx", "rx";
+ };
+
+ i2c2: i2c@48072000 {
+ compatible = "ti,omap2-i2c";
+ ti,hwmods = "i2c2";
+ reg = <0x48072000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <57>;
+ dmas = <&sdma 29 &sdma 30>;
+ dma-names = "tx", "rx";
+ };
+
+ mcspi1: mcspi@48098000 {
+ compatible = "ti,omap2-mcspi";
+ ti,hwmods = "mcspi1";
+ reg = <0x48098000 0x100>;
+ interrupts = <65>;
+ dmas = <&sdma 35 &sdma 36 &sdma 37 &sdma 38
+ &sdma 39 &sdma 40 &sdma 41 &sdma 42>;
+ dma-names = "tx0", "rx0", "tx1", "rx1",
+ "tx2", "rx2", "tx3", "rx3";
+ };
+
+ mcspi2: mcspi@4809a000 {
+ compatible = "ti,omap2-mcspi";
+ ti,hwmods = "mcspi2";
+ reg = <0x4809a000 0x100>;
+ interrupts = <66>;
+ dmas = <&sdma 43 &sdma 44 &sdma 45 &sdma 46>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
+ };
+
+ rng: rng@480a0000 {
+ compatible = "ti,omap2-rng";
+ ti,hwmods = "rng";
+ reg = <0x480a0000 0x50>;
+ interrupts = <52>;
+ };
+
+ sham: sham@480a4000 {
+ compatible = "ti,omap2-sham";
+ ti,hwmods = "sham";
+ reg = <0x480a4000 0x64>;
+ interrupts = <51>;
+ dmas = <&sdma 13>;
+ dma-names = "rx";
+ };
+
+ uart1: serial@4806a000 {
+ compatible = "ti,omap2-uart";
+ ti,hwmods = "uart1";
+ reg = <0x4806a000 0x2000>;
+ interrupts = <72>;
+ dmas = <&sdma 49 &sdma 50>;
+ dma-names = "tx", "rx";
+ clock-frequency = <48000000>;
+ };
+
+ uart2: serial@4806c000 {
+ compatible = "ti,omap2-uart";
+ ti,hwmods = "uart2";
+ reg = <0x4806c000 0x400>;
+ interrupts = <73>;
+ dmas = <&sdma 51 &sdma 52>;
+ dma-names = "tx", "rx";
+ clock-frequency = <48000000>;
+ };
+
+ uart3: serial@4806e000 {
+ compatible = "ti,omap2-uart";
+ ti,hwmods = "uart3";
+ reg = <0x4806e000 0x400>;
+ interrupts = <74>;
+ dmas = <&sdma 53 &sdma 54>;
+ dma-names = "tx", "rx";
+ clock-frequency = <48000000>;
+ };
+
+ timer2: timer@4802a000 {
+ compatible = "ti,omap2420-timer";
+ reg = <0x4802a000 0x400>;
+ interrupts = <38>;
+ ti,hwmods = "timer2";
+ };
+
+ timer3: timer@48078000 {
+ compatible = "ti,omap2420-timer";
+ reg = <0x48078000 0x400>;
+ interrupts = <39>;
+ ti,hwmods = "timer3";
+ };
+
+ timer4: timer@4807a000 {
+ compatible = "ti,omap2420-timer";
+ reg = <0x4807a000 0x400>;
+ interrupts = <40>;
+ ti,hwmods = "timer4";
+ };
+
+ timer5: timer@4807c000 {
+ compatible = "ti,omap2420-timer";
+ reg = <0x4807c000 0x400>;
+ interrupts = <41>;
+ ti,hwmods = "timer5";
+ ti,timer-dsp;
+ };
+
+ timer6: timer@4807e000 {
+ compatible = "ti,omap2420-timer";
+ reg = <0x4807e000 0x400>;
+ interrupts = <42>;
+ ti,hwmods = "timer6";
+ ti,timer-dsp;
+ };
+
+ timer7: timer@48080000 {
+ compatible = "ti,omap2420-timer";
+ reg = <0x48080000 0x400>;
+ interrupts = <43>;
+ ti,hwmods = "timer7";
+ ti,timer-dsp;
+ };
+
+ timer8: timer@48082000 {
+ compatible = "ti,omap2420-timer";
+ reg = <0x48082000 0x400>;
+ interrupts = <44>;
+ ti,hwmods = "timer8";
+ ti,timer-dsp;
+ };
+
+ timer9: timer@48084000 {
+ compatible = "ti,omap2420-timer";
+ reg = <0x48084000 0x400>;
+ interrupts = <45>;
+ ti,hwmods = "timer9";
+ ti,timer-pwm;
+ };
+
+ timer10: timer@48086000 {
+ compatible = "ti,omap2420-timer";
+ reg = <0x48086000 0x400>;
+ interrupts = <46>;
+ ti,hwmods = "timer10";
+ ti,timer-pwm;
+ };
+
+ timer11: timer@48088000 {
+ compatible = "ti,omap2420-timer";
+ reg = <0x48088000 0x400>;
+ interrupts = <47>;
+ ti,hwmods = "timer11";
+ ti,timer-pwm;
+ };
+
+ timer12: timer@4808a000 {
+ compatible = "ti,omap2420-timer";
+ reg = <0x4808a000 0x400>;
+ interrupts = <48>;
+ ti,hwmods = "timer12";
+ ti,timer-pwm;
+ };
+
+ dss: dss@48050000 {
+ compatible = "ti,omap2-dss";
+ reg = <0x48050000 0x400>;
+ status = "disabled";
+ ti,hwmods = "dss_core";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dispc@48050400 {
+ compatible = "ti,omap2-dispc";
+ reg = <0x48050400 0x400>;
+ interrupts = <25>;
+ ti,hwmods = "dss_dispc";
+ };
+
+ rfbi: encoder@48050800 {
+ compatible = "ti,omap2-rfbi";
+ reg = <0x48050800 0x400>;
+ status = "disabled";
+ ti,hwmods = "dss_rfbi";
+ };
+
+ venc: encoder@48050c00 {
+ compatible = "ti,omap2-venc";
+ reg = <0x48050c00 0x400>;
+ status = "disabled";
+ ti,hwmods = "dss_venc";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap2420-clocks.dtsi b/arch/arm/boot/dts/omap2420-clocks.dtsi
new file mode 100644
index 000000000..ce8c742d7
--- /dev/null
+++ b/arch/arm/boot/dts/omap2420-clocks.dtsi
@@ -0,0 +1,270 @@
+/*
+ * Device Tree Source for OMAP2420 clock data
+ *
+ * Copyright (C) 2014 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.
+ */
+
+&prcm_clocks {
+ sys_clkout2_src_gate: sys_clkout2_src_gate {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&core_ck>;
+ ti,bit-shift = <15>;
+ reg = <0x0070>;
+ };
+
+ sys_clkout2_src_mux: sys_clkout2_src_mux {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&core_ck>, <&sys_ck>, <&func_96m_ck>, <&func_54m_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0070>;
+ };
+
+ sys_clkout2_src: sys_clkout2_src {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&sys_clkout2_src_gate>, <&sys_clkout2_src_mux>;
+ };
+
+ sys_clkout2: sys_clkout2 {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&sys_clkout2_src>;
+ ti,bit-shift = <11>;
+ ti,max-div = <64>;
+ reg = <0x0070>;
+ ti,index-power-of-two;
+ };
+
+ dsp_gate_ick: dsp_gate_ick {
+ #clock-cells = <0>;
+ compatible = "ti,composite-interface-clock";
+ clocks = <&dsp_fck>;
+ ti,bit-shift = <1>;
+ reg = <0x0810>;
+ };
+
+ dsp_div_ick: dsp_div_ick {
+ #clock-cells = <0>;
+ compatible = "ti,composite-divider-clock";
+ clocks = <&dsp_fck>;
+ ti,bit-shift = <5>;
+ ti,max-div = <3>;
+ reg = <0x0840>;
+ ti,index-starts-at-one;
+ };
+
+ dsp_ick: dsp_ick {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&dsp_gate_ick>, <&dsp_div_ick>;
+ };
+
+ iva1_gate_ifck: iva1_gate_ifck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&core_ck>;
+ ti,bit-shift = <10>;
+ reg = <0x0800>;
+ };
+
+ iva1_div_ifck: iva1_div_ifck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-divider-clock";
+ clocks = <&core_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0840>;
+ ti,dividers = <0>, <1>, <2>, <3>, <4>, <0>, <6>, <0>, <8>, <0>, <0>, <0>, <12>;
+ };
+
+ iva1_ifck: iva1_ifck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&iva1_gate_ifck>, <&iva1_div_ifck>;
+ };
+
+ iva1_ifck_div: iva1_ifck_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&iva1_ifck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ iva1_mpu_int_ifck: iva1_mpu_int_ifck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&iva1_ifck_div>;
+ ti,bit-shift = <8>;
+ reg = <0x0800>;
+ };
+
+ wdt3_ick: wdt3_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <28>;
+ reg = <0x0210>;
+ };
+
+ wdt3_fck: wdt3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <28>;
+ reg = <0x0200>;
+ };
+
+ mmc_ick: mmc_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <26>;
+ reg = <0x0210>;
+ };
+
+ mmc_fck: mmc_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_96m_ck>;
+ ti,bit-shift = <26>;
+ reg = <0x0200>;
+ };
+
+ eac_ick: eac_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x0210>;
+ };
+
+ eac_fck: eac_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_96m_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x0200>;
+ };
+
+ i2c1_fck: i2c1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_12m_ck>;
+ ti,bit-shift = <19>;
+ reg = <0x0200>;
+ };
+
+ i2c2_fck: i2c2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_12m_ck>;
+ ti,bit-shift = <20>;
+ reg = <0x0200>;
+ };
+
+ vlynq_ick: vlynq_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l3_ck>;
+ ti,bit-shift = <3>;
+ reg = <0x0210>;
+ };
+
+ vlynq_gate_fck: vlynq_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&core_ck>;
+ ti,bit-shift = <3>;
+ reg = <0x0200>;
+ };
+
+ core_d18_ck: core_d18_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&core_ck>;
+ clock-mult = <1>;
+ clock-div = <18>;
+ };
+
+ vlynq_mux_fck: vlynq_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_96m_ck>, <&core_ck>, <&core_d2_ck>, <&core_d3_ck>, <&core_d4_ck>, <&dummy_ck>, <&core_d6_ck>, <&dummy_ck>, <&core_d8_ck>, <&core_d9_ck>, <&dummy_ck>, <&dummy_ck>, <&core_d12_ck>, <&dummy_ck>, <&dummy_ck>, <&dummy_ck>, <&core_d16_ck>, <&dummy_ck>, <&core_d18_ck>;
+ ti,bit-shift = <15>;
+ reg = <0x0240>;
+ };
+
+ vlynq_fck: vlynq_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&vlynq_gate_fck>, <&vlynq_mux_fck>;
+ };
+};
+
+&prcm_clockdomains {
+ gfx_clkdm: gfx_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&gfx_ick>;
+ };
+
+ core_l3_clkdm: core_l3_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&cam_fck>, <&vlynq_ick>, <&usb_fck>;
+ };
+
+ wkup_clkdm: wkup_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&dpll_ck>, <&emul_ck>, <&gpt1_ick>, <&gpios_ick>,
+ <&gpios_fck>, <&mpu_wdt_ick>, <&mpu_wdt_fck>,
+ <&sync_32k_ick>, <&wdt1_ick>, <&omapctrl_ick>;
+ };
+
+ iva1_clkdm: iva1_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&iva1_mpu_int_ifck>;
+ };
+
+ dss_clkdm: dss_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&dss_ick>, <&dss_54m_fck>;
+ };
+
+ core_l4_clkdm: core_l4_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&ssi_l4_ick>, <&gpt2_ick>, <&gpt3_ick>, <&gpt4_ick>,
+ <&gpt5_ick>, <&gpt6_ick>, <&gpt7_ick>, <&gpt8_ick>,
+ <&gpt9_ick>, <&gpt10_ick>, <&gpt11_ick>, <&gpt12_ick>,
+ <&mcbsp1_ick>, <&mcbsp2_ick>, <&mcspi1_ick>,
+ <&mcspi1_fck>, <&mcspi2_ick>, <&mcspi2_fck>,
+ <&uart1_ick>, <&uart1_fck>, <&uart2_ick>, <&uart2_fck>,
+ <&uart3_ick>, <&uart3_fck>, <&cam_ick>,
+ <&mailboxes_ick>, <&wdt4_ick>, <&wdt4_fck>,
+ <&wdt3_ick>, <&wdt3_fck>, <&mspro_ick>, <&mspro_fck>,
+ <&mmc_ick>, <&mmc_fck>, <&fac_ick>, <&fac_fck>,
+ <&eac_ick>, <&eac_fck>, <&hdq_ick>, <&hdq_fck>,
+ <&i2c1_ick>, <&i2c1_fck>, <&i2c2_ick>, <&i2c2_fck>,
+ <&des_ick>, <&sha_ick>, <&rng_ick>, <&aes_ick>,
+ <&pka_ick>;
+ };
+};
+
+&func_96m_ck {
+ compatible = "fixed-factor-clock";
+ clocks = <&apll96_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+};
+
+&dsp_div_fck {
+ ti,dividers = <0>, <1>, <2>, <3>, <4>, <0>, <6>, <0>, <8>, <0>, <0>, <0>, <12>;
+};
+
+&ssi_ssr_sst_div_fck {
+ ti,dividers = <0>, <1>, <2>, <3>, <4>, <0>, <6>, <0>, <8>;
+};
diff --git a/arch/arm/boot/dts/omap2420-h4.dts b/arch/arm/boot/dts/omap2420-h4.dts
new file mode 100644
index 000000000..34cdecb4f
--- /dev/null
+++ b/arch/arm/boot/dts/omap2420-h4.dts
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+/dts-v1/;
+
+#include "omap2420.dtsi"
+
+/ {
+ model = "TI OMAP2420 H4 board";
+ compatible = "ti,omap2420-h4", "ti,omap2420", "ti,omap2";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x4000000>; /* 64 MB */
+ };
+};
+
+&gpmc {
+ ranges = <0 0 0x08000000 0x04000000>;
+
+ nor@0,0 {
+ compatible = "cfi-flash";
+ linux,mtd-name= "intel,ge28f256l18b85";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0 0x04000000>;
+ bank-width = <2>;
+
+ gpmc,mux-add-data = <2>;
+ gpmc,cs-on-ns = <10>;
+ gpmc,cs-rd-off-ns = <160>;
+ gpmc,cs-wr-off-ns = <160>;
+ gpmc,adv-on-ns = <20>;
+ gpmc,adv-rd-off-ns = <50>;
+ gpmc,adv-wr-off-ns = <50>;
+ gpmc,oe-on-ns = <60>;
+ gpmc,oe-off-ns = <120>;
+ gpmc,we-on-ns = <60>;
+ gpmc,we-off-ns = <120>;
+ gpmc,rd-cycle-ns = <170>;
+ gpmc,wr-cycle-ns = <170>;
+ gpmc,access-ns = <150>;
+ gpmc,page-burst-access-ns = <10>;
+
+ partition@0 {
+ label = "bootloader";
+ reg = <0 0x20000>;
+ };
+ partition@20000 {
+ label = "params";
+ reg = <0x20000 0x20000>;
+ };
+ partition@40000 {
+ label = "kernel";
+ reg = <0x40000 0x200000>;
+ };
+ partition@240000 {
+ label = "file-system";
+ reg = <0x240000 0x3dc0000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap2420-n800.dts b/arch/arm/boot/dts/omap2420-n800.dts
new file mode 100644
index 000000000..d8c1b4236
--- /dev/null
+++ b/arch/arm/boot/dts/omap2420-n800.dts
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+#include "omap2420-n8x0-common.dtsi"
+
+/ {
+ model = "Nokia N800";
+ compatible = "nokia,n800", "nokia,n8x0", "ti,omap2420", "ti,omap2";
+};
diff --git a/arch/arm/boot/dts/omap2420-n810-wimax.dts b/arch/arm/boot/dts/omap2420-n810-wimax.dts
new file mode 100644
index 000000000..6b25b0359
--- /dev/null
+++ b/arch/arm/boot/dts/omap2420-n810-wimax.dts
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+#include "omap2420-n8x0-common.dtsi"
+
+/ {
+ model = "Nokia N810 WiMax";
+ compatible = "nokia,n810-wimax", "nokia,n8x0", "ti,omap2420", "ti,omap2";
+};
diff --git a/arch/arm/boot/dts/omap2420-n810.dts b/arch/arm/boot/dts/omap2420-n810.dts
new file mode 100644
index 000000000..b604d26bd
--- /dev/null
+++ b/arch/arm/boot/dts/omap2420-n810.dts
@@ -0,0 +1,15 @@
+/dts-v1/;
+
+#include "omap2420-n8x0-common.dtsi"
+
+/ {
+ model = "Nokia N810";
+ compatible = "nokia,n810", "nokia,n8x0", "ti,omap2420", "ti,omap2";
+};
+
+&i2c2 {
+ aic3x@18 {
+ compatible = "tlv320aic3x";
+ reg = <0x18>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
new file mode 100644
index 000000000..c9f1e93a9
--- /dev/null
+++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
@@ -0,0 +1,105 @@
+#include "omap2420.dtsi"
+
+/ {
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x8000000>; /* 128 MB */
+ };
+
+ ocp {
+ i2c@0 {
+ compatible = "i2c-cbus-gpio";
+ gpios = <&gpio3 2 0 /* gpio66 clk */
+ &gpio3 1 0 /* gpio65 dat */
+ &gpio3 0 0 /* gpio64 sel */
+ >;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ retu_mfd: retu@1 {
+ compatible = "retu-mfd";
+ interrupt-parent = <&gpio4>;
+ interrupts = <12 IRQ_TYPE_EDGE_RISING>;
+ reg = <0x1>;
+ };
+ };
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+
+ pmic@72 {
+ compatible = "menelaus";
+ reg = <0x72>;
+ interrupts = <7 IRQ_TYPE_EDGE_RISING>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+};
+
+&gpmc {
+ ranges = <0 0 0x04000000 0x1000000>; /* CS0: 16MB for OneNAND */
+
+ /* gpio-irq for dma: 26 */
+
+ onenand@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0 0x20000>; /* CS0, offset 0, IO size 128K */
+
+ gpmc,sync-read;
+ gpmc,burst-length = <16>;
+ gpmc,burst-read;
+ gpmc,burst-wrap;
+ gpmc,device-width = <2>;
+ gpmc,mux-add-data = <2>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <127>;
+ gpmc,cs-wr-off-ns = <109>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <18>;
+ gpmc,adv-wr-off-ns = <18>;
+ gpmc,oe-on-ns = <27>;
+ gpmc,oe-off-ns = <127>;
+ gpmc,we-on-ns = <27>;
+ gpmc,we-off-ns = <72>;
+ gpmc,rd-cycle-ns = <145>;
+ gpmc,wr-cycle-ns = <136>;
+ gpmc,access-ns = <118>;
+ gpmc,page-burst-access-ns = <27>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,clk-activation-ns = <9>;
+ gpmc,sync-clk-ps = <27000>;
+
+ /* MTD partition table corresponding to old board-n8x0 file. */
+ partition@0 {
+ label = "bootloader";
+ reg = <0x00000000 0x00020000>;
+ read-only;
+ };
+ partition@1 {
+ label = "config";
+ reg = <0x00020000 0x00060000>;
+ };
+ partition@2 {
+ label = "kernel";
+ reg = <0x00080000 0x00200000>;
+ };
+ partition@3 {
+ label = "initfs";
+ reg = <0x00280000 0x00400000>;
+ };
+ partition@4 {
+ label = "rootfs";
+ reg = <0x00680000 0x0f980000>;
+ };
+ partition@5 {
+ label = "omap2-onenand";
+ reg = <0x00000000 0x10000000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap2420.dtsi b/arch/arm/boot/dts/omap2420.dtsi
new file mode 100644
index 000000000..5b9a376cc
--- /dev/null
+++ b/arch/arm/boot/dts/omap2420.dtsi
@@ -0,0 +1,216 @@
+/*
+ * Device Tree Source for OMAP2420 SoC
+ *
+ * Copyright (C) 2012 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 "omap2.dtsi"
+
+/ {
+ compatible = "ti,omap2420", "ti,omap2";
+
+ ocp {
+ l4: l4@48000000 {
+ compatible = "ti,omap2-l4", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x48000000 0x100000>;
+
+ prcm: prcm@8000 {
+ compatible = "ti,omap2-prcm";
+ reg = <0x8000 0x1000>;
+
+ prcm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ prcm_clockdomains: clockdomains {
+ };
+ };
+
+ scm: scm@0 {
+ compatible = "ti,omap2-scm", "simple-bus";
+ reg = <0x0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x0 0x1000>;
+
+ omap2420_pmx: pinmux@30 {
+ compatible = "ti,omap2420-padconf",
+ "pinctrl-single";
+ reg = <0x30 0x0113>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-single,register-width = <8>;
+ pinctrl-single,function-mask = <0x3f>;
+ };
+
+ scm_conf: scm_conf@270 {
+ compatible = "syscon";
+ reg = <0x270 0x100>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ scm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ scm_clockdomains: clockdomains {
+ };
+ };
+
+ counter32k: counter@4000 {
+ compatible = "ti,omap-counter32k";
+ reg = <0x4000 0x20>;
+ ti,hwmods = "counter_32k";
+ };
+ };
+
+ gpio1: gpio@48018000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x48018000 0x200>;
+ interrupts = <29>;
+ ti,hwmods = "gpio1";
+ ti,gpio-always-on;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio2: gpio@4801a000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x4801a000 0x200>;
+ interrupts = <30>;
+ ti,hwmods = "gpio2";
+ ti,gpio-always-on;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio3: gpio@4801c000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x4801c000 0x200>;
+ interrupts = <31>;
+ ti,hwmods = "gpio3";
+ ti,gpio-always-on;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio4: gpio@4801e000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x4801e000 0x200>;
+ interrupts = <32>;
+ ti,hwmods = "gpio4";
+ ti,gpio-always-on;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpmc: gpmc@6800a000 {
+ compatible = "ti,omap2420-gpmc";
+ reg = <0x6800a000 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ interrupts = <20>;
+ gpmc,num-cs = <8>;
+ gpmc,num-waitpins = <4>;
+ ti,hwmods = "gpmc";
+ };
+
+ mcbsp1: mcbsp@48074000 {
+ compatible = "ti,omap2420-mcbsp";
+ reg = <0x48074000 0xff>;
+ reg-names = "mpu";
+ interrupts = <59>, /* TX interrupt */
+ <60>; /* RX interrupt */
+ interrupt-names = "tx", "rx";
+ ti,hwmods = "mcbsp1";
+ dmas = <&sdma 31>,
+ <&sdma 32>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mcbsp2: mcbsp@48076000 {
+ compatible = "ti,omap2420-mcbsp";
+ reg = <0x48076000 0xff>;
+ reg-names = "mpu";
+ interrupts = <62>, /* TX interrupt */
+ <63>; /* RX interrupt */
+ interrupt-names = "tx", "rx";
+ ti,hwmods = "mcbsp2";
+ dmas = <&sdma 33>,
+ <&sdma 34>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ msdi1: mmc@4809c000 {
+ compatible = "ti,omap2420-mmc";
+ ti,hwmods = "msdi1";
+ reg = <0x4809c000 0x80>;
+ interrupts = <83>;
+ dmas = <&sdma 61 &sdma 62>;
+ dma-names = "tx", "rx";
+ };
+
+ mailbox: mailbox@48094000 {
+ compatible = "ti,omap2-mailbox";
+ reg = <0x48094000 0x200>;
+ interrupts = <26>, <34>;
+ interrupt-names = "dsp", "iva";
+ ti,hwmods = "mailbox";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <6>;
+ mbox_dsp: dsp {
+ ti,mbox-tx = <0 0 0>;
+ ti,mbox-rx = <1 0 0>;
+ };
+ mbox_iva: iva {
+ ti,mbox-tx = <2 1 3>;
+ ti,mbox-rx = <3 1 3>;
+ };
+ };
+
+ timer1: timer@48028000 {
+ compatible = "ti,omap2420-timer";
+ reg = <0x48028000 0x400>;
+ interrupts = <37>;
+ ti,hwmods = "timer1";
+ ti,timer-alwon;
+ };
+
+ wd_timer2: wdt@48022000 {
+ compatible = "ti,omap2-wdt";
+ ti,hwmods = "wd_timer2";
+ reg = <0x48022000 0x80>;
+ };
+ };
+};
+
+&i2c1 {
+ compatible = "ti,omap2420-i2c";
+};
+
+&i2c2 {
+ compatible = "ti,omap2420-i2c";
+};
+
+/include/ "omap24xx-clocks.dtsi"
+/include/ "omap2420-clocks.dtsi"
diff --git a/arch/arm/boot/dts/omap2430-clocks.dtsi b/arch/arm/boot/dts/omap2430-clocks.dtsi
new file mode 100644
index 000000000..93fed6883
--- /dev/null
+++ b/arch/arm/boot/dts/omap2430-clocks.dtsi
@@ -0,0 +1,344 @@
+/*
+ * Device Tree Source for OMAP2430 clock data
+ *
+ * Copyright (C) 2014 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.
+ */
+
+&scm_clocks {
+ mcbsp3_mux_fck: mcbsp3_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_96m_ck>, <&mcbsp_clks>;
+ reg = <0x78>;
+ };
+
+ mcbsp3_fck: mcbsp3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&mcbsp3_gate_fck>, <&mcbsp3_mux_fck>;
+ };
+
+ mcbsp4_mux_fck: mcbsp4_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_96m_ck>, <&mcbsp_clks>;
+ ti,bit-shift = <2>;
+ reg = <0x78>;
+ };
+
+ mcbsp4_fck: mcbsp4_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&mcbsp4_gate_fck>, <&mcbsp4_mux_fck>;
+ };
+
+ mcbsp5_mux_fck: mcbsp5_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_96m_ck>, <&mcbsp_clks>;
+ ti,bit-shift = <4>;
+ reg = <0x78>;
+ };
+
+ mcbsp5_fck: mcbsp5_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&mcbsp5_gate_fck>, <&mcbsp5_mux_fck>;
+ };
+};
+
+&prcm_clocks {
+ iva2_1_gate_ick: iva2_1_gate_ick {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&dsp_fck>;
+ ti,bit-shift = <0>;
+ reg = <0x0800>;
+ };
+
+ iva2_1_div_ick: iva2_1_div_ick {
+ #clock-cells = <0>;
+ compatible = "ti,composite-divider-clock";
+ clocks = <&dsp_fck>;
+ ti,bit-shift = <5>;
+ ti,max-div = <3>;
+ reg = <0x0840>;
+ ti,index-starts-at-one;
+ };
+
+ iva2_1_ick: iva2_1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&iva2_1_gate_ick>, <&iva2_1_div_ick>;
+ };
+
+ mdm_gate_ick: mdm_gate_ick {
+ #clock-cells = <0>;
+ compatible = "ti,composite-interface-clock";
+ clocks = <&core_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x0c10>;
+ };
+
+ mdm_div_ick: mdm_div_ick {
+ #clock-cells = <0>;
+ compatible = "ti,composite-divider-clock";
+ clocks = <&core_ck>;
+ reg = <0x0c40>;
+ ti,dividers = <0>, <1>, <0>, <0>, <4>, <0>, <6>, <0>, <0>, <9>;
+ };
+
+ mdm_ick: mdm_ick {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&mdm_gate_ick>, <&mdm_div_ick>;
+ };
+
+ mdm_osc_ck: mdm_osc_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&osc_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0c00>;
+ };
+
+ mcbsp3_ick: mcbsp3_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <3>;
+ reg = <0x0214>;
+ };
+
+ mcbsp3_gate_fck: mcbsp3_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&mcbsp_clks>;
+ ti,bit-shift = <3>;
+ reg = <0x0204>;
+ };
+
+ mcbsp4_ick: mcbsp4_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <4>;
+ reg = <0x0214>;
+ };
+
+ mcbsp4_gate_fck: mcbsp4_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&mcbsp_clks>;
+ ti,bit-shift = <4>;
+ reg = <0x0204>;
+ };
+
+ mcbsp5_ick: mcbsp5_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <5>;
+ reg = <0x0214>;
+ };
+
+ mcbsp5_gate_fck: mcbsp5_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&mcbsp_clks>;
+ ti,bit-shift = <5>;
+ reg = <0x0204>;
+ };
+
+ mcspi3_ick: mcspi3_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <9>;
+ reg = <0x0214>;
+ };
+
+ mcspi3_fck: mcspi3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_48m_ck>;
+ ti,bit-shift = <9>;
+ reg = <0x0204>;
+ };
+
+ icr_ick: icr_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <6>;
+ reg = <0x0410>;
+ };
+
+ i2chs1_fck: i2chs1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,omap2430-interface-clock";
+ clocks = <&func_96m_ck>;
+ ti,bit-shift = <19>;
+ reg = <0x0204>;
+ };
+
+ i2chs2_fck: i2chs2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,omap2430-interface-clock";
+ clocks = <&func_96m_ck>;
+ ti,bit-shift = <20>;
+ reg = <0x0204>;
+ };
+
+ usbhs_ick: usbhs_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l3_ck>;
+ ti,bit-shift = <6>;
+ reg = <0x0214>;
+ };
+
+ mmchs1_ick: mmchs1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <7>;
+ reg = <0x0214>;
+ };
+
+ mmchs1_fck: mmchs1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_96m_ck>;
+ ti,bit-shift = <7>;
+ reg = <0x0204>;
+ };
+
+ mmchs2_ick: mmchs2_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0214>;
+ };
+
+ mmchs2_fck: mmchs2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_96m_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0204>;
+ };
+
+ gpio5_ick: gpio5_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <10>;
+ reg = <0x0214>;
+ };
+
+ gpio5_fck: gpio5_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <10>;
+ reg = <0x0204>;
+ };
+
+ mdm_intc_ick: mdm_intc_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <11>;
+ reg = <0x0214>;
+ };
+
+ mmchsdb1_fck: mmchsdb1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <16>;
+ reg = <0x0204>;
+ };
+
+ mmchsdb2_fck: mmchsdb2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <17>;
+ reg = <0x0204>;
+ };
+};
+
+&prcm_clockdomains {
+ gfx_clkdm: gfx_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&gfx_ick>;
+ };
+
+ core_l3_clkdm: core_l3_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&cam_fck>, <&usb_fck>, <&usbhs_ick>;
+ };
+
+ wkup_clkdm: wkup_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&dpll_ck>, <&emul_ck>, <&gpt1_ick>, <&gpios_ick>,
+ <&gpios_fck>, <&mpu_wdt_ick>, <&mpu_wdt_fck>,
+ <&sync_32k_ick>, <&wdt1_ick>, <&omapctrl_ick>,
+ <&icr_ick>;
+ };
+
+ dss_clkdm: dss_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&dss_ick>, <&dss_54m_fck>;
+ };
+
+ core_l4_clkdm: core_l4_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&ssi_l4_ick>, <&gpt2_ick>, <&gpt3_ick>, <&gpt4_ick>,
+ <&gpt5_ick>, <&gpt6_ick>, <&gpt7_ick>, <&gpt8_ick>,
+ <&gpt9_ick>, <&gpt10_ick>, <&gpt11_ick>, <&gpt12_ick>,
+ <&mcbsp1_ick>, <&mcbsp2_ick>, <&mcbsp3_ick>,
+ <&mcbsp4_ick>, <&mcbsp5_ick>, <&mcspi1_ick>,
+ <&mcspi1_fck>, <&mcspi2_ick>, <&mcspi2_fck>,
+ <&mcspi3_ick>, <&mcspi3_fck>, <&uart1_ick>,
+ <&uart1_fck>, <&uart2_ick>, <&uart2_fck>, <&uart3_ick>,
+ <&uart3_fck>, <&cam_ick>, <&mailboxes_ick>,
+ <&wdt4_ick>, <&wdt4_fck>, <&mspro_ick>, <&mspro_fck>,
+ <&fac_ick>, <&fac_fck>, <&hdq_ick>, <&hdq_fck>,
+ <&i2c1_ick>, <&i2chs1_fck>, <&i2c2_ick>, <&i2chs2_fck>,
+ <&des_ick>, <&sha_ick>, <&rng_ick>, <&aes_ick>,
+ <&pka_ick>, <&mmchs1_ick>, <&mmchs1_fck>,
+ <&mmchs2_ick>, <&mmchs2_fck>, <&gpio5_ick>,
+ <&gpio5_fck>, <&mdm_intc_ick>, <&mmchsdb1_fck>,
+ <&mmchsdb2_fck>;
+ };
+
+ mdm_clkdm: mdm_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&mdm_osc_ck>;
+ };
+};
+
+&func_96m_ck {
+ compatible = "ti,mux-clock";
+ clocks = <&apll96_ck>, <&alt_ck>;
+ ti,bit-shift = <4>;
+ reg = <0x0540>;
+};
+
+&dsp_div_fck {
+ ti,max-div = <4>;
+ ti,index-starts-at-one;
+};
+
+&ssi_ssr_sst_div_fck {
+ ti,max-div = <5>;
+ ti,index-starts-at-one;
+};
diff --git a/arch/arm/boot/dts/omap2430-sdp.dts b/arch/arm/boot/dts/omap2430-sdp.dts
new file mode 100644
index 000000000..6b36ede58
--- /dev/null
+++ b/arch/arm/boot/dts/omap2430-sdp.dts
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+/dts-v1/;
+
+#include "omap2430.dtsi"
+
+/ {
+ model = "TI OMAP2430 SDP";
+ compatible = "ti,omap2430-sdp", "ti,omap2430", "ti,omap2";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x8000000>; /* 128 MB */
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ };
+};
+
+#include "twl4030.dtsi"
+
+&mmc1 {
+ vmmc-supply = <&vmmc1>;
+ bus-width = <4>;
+};
+
+&gpmc {
+ ranges = <5 0 0x08000000 0x01000000>;
+ ethernet@gpmc {
+ compatible = "smsc,lan91c94";
+ interrupt-parent = <&gpio5>;
+ interrupts = <21 IRQ_TYPE_LEVEL_LOW>; /* gpio149 */
+ reg = <5 0x300 0xf>;
+ bank-width = <2>;
+ gpmc,sync-clk-ps = <0>;
+ gpmc,mux-add-data = <2>;
+ gpmc,device-width = <1>;
+ gpmc,cycle2cycle-samecsen = <1>;
+ gpmc,cycle2cycle-diffcsen = <1>;
+ gpmc,cs-on-ns = <6>;
+ gpmc,cs-rd-off-ns = <187>;
+ gpmc,cs-wr-off-ns = <187>;
+ gpmc,adv-on-ns = <18>;
+ gpmc,adv-rd-off-ns = <48>;
+ gpmc,adv-wr-off-ns = <48>;
+ gpmc,oe-on-ns = <60>;
+ gpmc,oe-off-ns = <169>;
+ gpmc,we-on-ns = <66>;
+ gpmc,we-off-ns = <169>;
+ gpmc,rd-cycle-ns = <187>;
+ gpmc,wr-cycle-ns = <187>;
+ gpmc,access-ns = <187>;
+ gpmc,page-burst-access-ns = <24>;
+ gpmc,bus-turnaround-ns = <24>;
+ gpmc,cycle2cycle-delay-ns = <24>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+ gpmc,wr-access-ns = <0>;
+ };
+};
+
diff --git a/arch/arm/boot/dts/omap2430.dtsi b/arch/arm/boot/dts/omap2430.dtsi
new file mode 100644
index 000000000..11a7963be
--- /dev/null
+++ b/arch/arm/boot/dts/omap2430.dtsi
@@ -0,0 +1,313 @@
+/*
+ * Device Tree Source for OMAP243x SoC
+ *
+ * Copyright (C) 2012 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 "omap2.dtsi"
+
+/ {
+ compatible = "ti,omap2430", "ti,omap2";
+
+ ocp {
+ l4_wkup: l4_wkup@49000000 {
+ compatible = "ti,omap2-l4-wkup", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x49000000 0x31000>;
+
+ prcm: prcm@6000 {
+ compatible = "ti,omap2-prcm";
+ reg = <0x6000 0x1000>;
+
+ prcm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ prcm_clockdomains: clockdomains {
+ };
+ };
+
+ scm: scm@2000 {
+ compatible = "ti,omap2-scm", "simple-bus";
+ reg = <0x2000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x2000 0x1000>;
+
+ omap2430_pmx: pinmux@30 {
+ compatible = "ti,omap2430-padconf",
+ "pinctrl-single";
+ reg = <0x30 0x0154>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-single,register-width = <8>;
+ pinctrl-single,function-mask = <0x3f>;
+ };
+
+ scm_conf: scm_conf@270 {
+ compatible = "syscon";
+ reg = <0x270 0x240>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ scm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ pbias_regulator: pbias_regulator {
+ compatible = "ti,pbias-omap";
+ reg = <0x230 0x4>;
+ syscon = <&scm_conf>;
+ pbias_mmc_reg: pbias_mmc_omap2430 {
+ regulator-name = "pbias_mmc_omap2430";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ };
+ };
+ };
+
+ scm_clockdomains: clockdomains {
+ };
+ };
+
+ counter32k: counter@20000 {
+ compatible = "ti,omap-counter32k";
+ reg = <0x20000 0x20>;
+ ti,hwmods = "counter_32k";
+ };
+ };
+
+ gpio1: gpio@4900c000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x4900c000 0x200>;
+ interrupts = <29>;
+ ti,hwmods = "gpio1";
+ ti,gpio-always-on;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio2: gpio@4900e000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x4900e000 0x200>;
+ interrupts = <30>;
+ ti,hwmods = "gpio2";
+ ti,gpio-always-on;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio3: gpio@49010000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x49010000 0x200>;
+ interrupts = <31>;
+ ti,hwmods = "gpio3";
+ ti,gpio-always-on;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio4: gpio@49012000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x49012000 0x200>;
+ interrupts = <32>;
+ ti,hwmods = "gpio4";
+ ti,gpio-always-on;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio5: gpio@480b6000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x480b6000 0x200>;
+ interrupts = <33>;
+ ti,hwmods = "gpio5";
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpmc: gpmc@6e000000 {
+ compatible = "ti,omap2430-gpmc";
+ reg = <0x6e000000 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ interrupts = <20>;
+ gpmc,num-cs = <8>;
+ gpmc,num-waitpins = <4>;
+ ti,hwmods = "gpmc";
+ };
+
+ mcbsp1: mcbsp@48074000 {
+ compatible = "ti,omap2430-mcbsp";
+ reg = <0x48074000 0xff>;
+ reg-names = "mpu";
+ interrupts = <64>, /* OCP compliant interrupt */
+ <59>, /* TX interrupt */
+ <60>, /* RX interrupt */
+ <61>; /* RX overflow interrupt */
+ interrupt-names = "common", "tx", "rx", "rx_overflow";
+ ti,buffer-size = <128>;
+ ti,hwmods = "mcbsp1";
+ dmas = <&sdma 31>,
+ <&sdma 32>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mcbsp2: mcbsp@48076000 {
+ compatible = "ti,omap2430-mcbsp";
+ reg = <0x48076000 0xff>;
+ reg-names = "mpu";
+ interrupts = <16>, /* OCP compliant interrupt */
+ <62>, /* TX interrupt */
+ <63>; /* RX interrupt */
+ interrupt-names = "common", "tx", "rx";
+ ti,buffer-size = <128>;
+ ti,hwmods = "mcbsp2";
+ dmas = <&sdma 33>,
+ <&sdma 34>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mcbsp3: mcbsp@4808c000 {
+ compatible = "ti,omap2430-mcbsp";
+ reg = <0x4808c000 0xff>;
+ reg-names = "mpu";
+ interrupts = <17>, /* OCP compliant interrupt */
+ <89>, /* TX interrupt */
+ <90>; /* RX interrupt */
+ interrupt-names = "common", "tx", "rx";
+ ti,buffer-size = <128>;
+ ti,hwmods = "mcbsp3";
+ dmas = <&sdma 17>,
+ <&sdma 18>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mcbsp4: mcbsp@4808e000 {
+ compatible = "ti,omap2430-mcbsp";
+ reg = <0x4808e000 0xff>;
+ reg-names = "mpu";
+ interrupts = <18>, /* OCP compliant interrupt */
+ <54>, /* TX interrupt */
+ <55>; /* RX interrupt */
+ interrupt-names = "common", "tx", "rx";
+ ti,buffer-size = <128>;
+ ti,hwmods = "mcbsp4";
+ dmas = <&sdma 19>,
+ <&sdma 20>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mcbsp5: mcbsp@48096000 {
+ compatible = "ti,omap2430-mcbsp";
+ reg = <0x48096000 0xff>;
+ reg-names = "mpu";
+ interrupts = <19>, /* OCP compliant interrupt */
+ <81>, /* TX interrupt */
+ <82>; /* RX interrupt */
+ interrupt-names = "common", "tx", "rx";
+ ti,buffer-size = <128>;
+ ti,hwmods = "mcbsp5";
+ dmas = <&sdma 21>,
+ <&sdma 22>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mmc1: mmc@4809c000 {
+ compatible = "ti,omap2-hsmmc";
+ reg = <0x4809c000 0x200>;
+ interrupts = <83>;
+ ti,hwmods = "mmc1";
+ ti,dual-volt;
+ dmas = <&sdma 61>, <&sdma 62>;
+ dma-names = "tx", "rx";
+ pbias-supply = <&pbias_mmc_reg>;
+ };
+
+ mmc2: mmc@480b4000 {
+ compatible = "ti,omap2-hsmmc";
+ reg = <0x480b4000 0x200>;
+ interrupts = <86>;
+ ti,hwmods = "mmc2";
+ dmas = <&sdma 47>, <&sdma 48>;
+ dma-names = "tx", "rx";
+ };
+
+ mailbox: mailbox@48094000 {
+ compatible = "ti,omap2-mailbox";
+ reg = <0x48094000 0x200>;
+ interrupts = <26>;
+ ti,hwmods = "mailbox";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <6>;
+ mbox_dsp: dsp {
+ ti,mbox-tx = <0 0 0>;
+ ti,mbox-rx = <1 0 0>;
+ };
+ };
+
+ timer1: timer@49018000 {
+ compatible = "ti,omap2420-timer";
+ reg = <0x49018000 0x400>;
+ interrupts = <37>;
+ ti,hwmods = "timer1";
+ ti,timer-alwon;
+ };
+
+ mcspi3: mcspi@480b8000 {
+ compatible = "ti,omap2-mcspi";
+ ti,hwmods = "mcspi3";
+ reg = <0x480b8000 0x100>;
+ interrupts = <91>;
+ dmas = <&sdma 15 &sdma 16 &sdma 23 &sdma 24>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
+ };
+
+ usb_otg_hs: usb_otg_hs@480ac000 {
+ compatible = "ti,omap2-musb";
+ ti,hwmods = "usb_otg_hs";
+ reg = <0x480ac000 0x1000>;
+ interrupts = <93>;
+ };
+
+ wd_timer2: wdt@49016000 {
+ compatible = "ti,omap2-wdt";
+ ti,hwmods = "wd_timer2";
+ reg = <0x49016000 0x80>;
+ };
+ };
+};
+
+&i2c1 {
+ compatible = "ti,omap2430-i2c";
+};
+
+&i2c2 {
+ compatible = "ti,omap2430-i2c";
+};
+
+/include/ "omap24xx-clocks.dtsi"
+/include/ "omap2430-clocks.dtsi"
diff --git a/arch/arm/boot/dts/omap24xx-clocks.dtsi b/arch/arm/boot/dts/omap24xx-clocks.dtsi
new file mode 100644
index 000000000..63965b876
--- /dev/null
+++ b/arch/arm/boot/dts/omap24xx-clocks.dtsi
@@ -0,0 +1,1244 @@
+/*
+ * Device Tree Source for OMAP24xx clock data
+ *
+ * Copyright (C) 2014 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.
+ */
+&scm_clocks {
+ mcbsp1_mux_fck: mcbsp1_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_96m_ck>, <&mcbsp_clks>;
+ ti,bit-shift = <2>;
+ reg = <0x4>;
+ };
+
+ mcbsp1_fck: mcbsp1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&mcbsp1_gate_fck>, <&mcbsp1_mux_fck>;
+ };
+
+ mcbsp2_mux_fck: mcbsp2_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_96m_ck>, <&mcbsp_clks>;
+ ti,bit-shift = <6>;
+ reg = <0x4>;
+ };
+
+ mcbsp2_fck: mcbsp2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&mcbsp2_gate_fck>, <&mcbsp2_mux_fck>;
+ };
+};
+
+&prcm_clocks {
+ func_32k_ck: func_32k_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ secure_32k_ck: secure_32k_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ virt_12m_ck: virt_12m_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ virt_13m_ck: virt_13m_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ };
+
+ virt_19200000_ck: virt_19200000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <19200000>;
+ };
+
+ virt_26m_ck: virt_26m_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ };
+
+ aplls_clkin_ck: aplls_clkin_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&virt_19200000_ck>, <&virt_26m_ck>, <&virt_13m_ck>, <&virt_12m_ck>;
+ ti,bit-shift = <23>;
+ reg = <0x0540>;
+ };
+
+ aplls_clkin_x2_ck: aplls_clkin_x2_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&aplls_clkin_ck>;
+ clock-mult = <2>;
+ clock-div = <1>;
+ };
+
+ osc_ck: osc_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&aplls_clkin_ck>, <&aplls_clkin_x2_ck>;
+ ti,bit-shift = <6>;
+ reg = <0x0060>;
+ ti,index-starts-at-one;
+ };
+
+ sys_ck: sys_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&osc_ck>;
+ ti,bit-shift = <6>;
+ ti,max-div = <3>;
+ reg = <0x0060>;
+ ti,index-starts-at-one;
+ };
+
+ alt_ck: alt_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <54000000>;
+ };
+
+ mcbsp_clks: mcbsp_clks {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0x0>;
+ };
+
+ dpll_ck: dpll_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap2-dpll-core-clock";
+ clocks = <&sys_ck>, <&sys_ck>;
+ reg = <0x0500>, <0x0540>;
+ };
+
+ apll96_ck: apll96_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap2-apll-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <2>;
+ ti,idlest-shift = <8>;
+ ti,clock-frequency = <96000000>;
+ reg = <0x0500>, <0x0530>, <0x0520>;
+ };
+
+ apll54_ck: apll54_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap2-apll-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <6>;
+ ti,idlest-shift = <9>;
+ ti,clock-frequency = <54000000>;
+ reg = <0x0500>, <0x0530>, <0x0520>;
+ };
+
+ func_54m_ck: func_54m_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&apll54_ck>, <&alt_ck>;
+ ti,bit-shift = <5>;
+ reg = <0x0540>;
+ };
+
+ core_ck: core_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ func_96m_ck: func_96m_ck {
+ #clock-cells = <0>;
+ };
+
+ apll96_d2_ck: apll96_d2_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&apll96_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ func_48m_ck: func_48m_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&apll96_d2_ck>, <&alt_ck>;
+ ti,bit-shift = <3>;
+ reg = <0x0540>;
+ };
+
+ func_12m_ck: func_12m_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&func_48m_ck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ sys_clkout_src_gate: sys_clkout_src_gate {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&core_ck>;
+ ti,bit-shift = <7>;
+ reg = <0x0070>;
+ };
+
+ sys_clkout_src_mux: sys_clkout_src_mux {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&core_ck>, <&sys_ck>, <&func_96m_ck>, <&func_54m_ck>;
+ reg = <0x0070>;
+ };
+
+ sys_clkout_src: sys_clkout_src {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&sys_clkout_src_gate>, <&sys_clkout_src_mux>;
+ };
+
+ sys_clkout: sys_clkout {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&sys_clkout_src>;
+ ti,bit-shift = <3>;
+ ti,max-div = <64>;
+ reg = <0x0070>;
+ ti,index-power-of-two;
+ };
+
+ emul_ck: emul_ck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&func_54m_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x0078>;
+ };
+
+ mpu_ck: mpu_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&core_ck>;
+ ti,max-div = <31>;
+ reg = <0x0140>;
+ ti,index-starts-at-one;
+ };
+
+ dsp_gate_fck: dsp_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&core_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x0800>;
+ };
+
+ dsp_div_fck: dsp_div_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-divider-clock";
+ clocks = <&core_ck>;
+ reg = <0x0840>;
+ };
+
+ dsp_fck: dsp_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&dsp_gate_fck>, <&dsp_div_fck>;
+ };
+
+ core_l3_ck: core_l3_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&core_ck>;
+ ti,max-div = <31>;
+ reg = <0x0240>;
+ ti,index-starts-at-one;
+ };
+
+ gfx_3d_gate_fck: gfx_3d_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&core_l3_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x0300>;
+ };
+
+ gfx_3d_div_fck: gfx_3d_div_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-divider-clock";
+ clocks = <&core_l3_ck>;
+ ti,max-div = <4>;
+ reg = <0x0340>;
+ ti,index-starts-at-one;
+ };
+
+ gfx_3d_fck: gfx_3d_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gfx_3d_gate_fck>, <&gfx_3d_div_fck>;
+ };
+
+ gfx_2d_gate_fck: gfx_2d_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&core_l3_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0300>;
+ };
+
+ gfx_2d_div_fck: gfx_2d_div_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-divider-clock";
+ clocks = <&core_l3_ck>;
+ ti,max-div = <4>;
+ reg = <0x0340>;
+ ti,index-starts-at-one;
+ };
+
+ gfx_2d_fck: gfx_2d_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gfx_2d_gate_fck>, <&gfx_2d_div_fck>;
+ };
+
+ gfx_ick: gfx_ick {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_l3_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x0310>;
+ };
+
+ l4_ck: l4_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&core_l3_ck>;
+ ti,bit-shift = <5>;
+ ti,max-div = <3>;
+ reg = <0x0240>;
+ ti,index-starts-at-one;
+ };
+
+ dss_ick: dss_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-no-wait-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x0210>;
+ };
+
+ dss1_gate_fck: dss1_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&core_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x0200>;
+ };
+
+ core_d2_ck: core_d2_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&core_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ core_d3_ck: core_d3_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&core_ck>;
+ clock-mult = <1>;
+ clock-div = <3>;
+ };
+
+ core_d4_ck: core_d4_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&core_ck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ core_d5_ck: core_d5_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&core_ck>;
+ clock-mult = <1>;
+ clock-div = <5>;
+ };
+
+ core_d6_ck: core_d6_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&core_ck>;
+ clock-mult = <1>;
+ clock-div = <6>;
+ };
+
+ dummy_ck: dummy_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ core_d8_ck: core_d8_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&core_ck>;
+ clock-mult = <1>;
+ clock-div = <8>;
+ };
+
+ core_d9_ck: core_d9_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&core_ck>;
+ clock-mult = <1>;
+ clock-div = <9>;
+ };
+
+ core_d12_ck: core_d12_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&core_ck>;
+ clock-mult = <1>;
+ clock-div = <12>;
+ };
+
+ core_d16_ck: core_d16_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&core_ck>;
+ clock-mult = <1>;
+ clock-div = <16>;
+ };
+
+ dss1_mux_fck: dss1_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&sys_ck>, <&core_ck>, <&core_d2_ck>, <&core_d3_ck>, <&core_d4_ck>, <&core_d5_ck>, <&core_d6_ck>, <&core_d8_ck>, <&core_d9_ck>, <&core_d12_ck>, <&core_d16_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0240>;
+ };
+
+ dss1_fck: dss1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&dss1_gate_fck>, <&dss1_mux_fck>;
+ };
+
+ dss2_gate_fck: dss2_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&func_48m_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0200>;
+ };
+
+ dss2_mux_fck: dss2_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&sys_ck>, <&func_48m_ck>;
+ ti,bit-shift = <13>;
+ reg = <0x0240>;
+ };
+
+ dss2_fck: dss2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&dss2_gate_fck>, <&dss2_mux_fck>;
+ };
+
+ dss_54m_fck: dss_54m_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_54m_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x0200>;
+ };
+
+ ssi_ssr_sst_gate_fck: ssi_ssr_sst_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&core_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0204>;
+ };
+
+ ssi_ssr_sst_div_fck: ssi_ssr_sst_div_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-divider-clock";
+ clocks = <&core_ck>;
+ ti,bit-shift = <20>;
+ reg = <0x0240>;
+ };
+
+ ssi_ssr_sst_fck: ssi_ssr_sst_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&ssi_ssr_sst_gate_fck>, <&ssi_ssr_sst_div_fck>;
+ };
+
+ usb_l4_gate_ick: usb_l4_gate_ick {
+ #clock-cells = <0>;
+ compatible = "ti,composite-interface-clock";
+ clocks = <&core_l3_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x0214>;
+ };
+
+ usb_l4_div_ick: usb_l4_div_ick {
+ #clock-cells = <0>;
+ compatible = "ti,composite-divider-clock";
+ clocks = <&core_l3_ck>;
+ ti,bit-shift = <25>;
+ reg = <0x0240>;
+ ti,dividers = <0>, <1>, <2>, <0>, <4>;
+ };
+
+ usb_l4_ick: usb_l4_ick {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&usb_l4_gate_ick>, <&usb_l4_div_ick>;
+ };
+
+ ssi_l4_ick: ssi_l4_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0214>;
+ };
+
+ gpt1_ick: gpt1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x0410>;
+ };
+
+ gpt1_gate_fck: gpt1_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x0400>;
+ };
+
+ gpt1_mux_fck: gpt1_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_32k_ck>, <&sys_ck>, <&alt_ck>;
+ reg = <0x0440>;
+ };
+
+ gpt1_fck: gpt1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt1_gate_fck>, <&gpt1_mux_fck>;
+ };
+
+ gpt2_ick: gpt2_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <4>;
+ reg = <0x0210>;
+ };
+
+ gpt2_gate_fck: gpt2_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <4>;
+ reg = <0x0200>;
+ };
+
+ gpt2_mux_fck: gpt2_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_32k_ck>, <&sys_ck>, <&alt_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x0244>;
+ };
+
+ gpt2_fck: gpt2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt2_gate_fck>, <&gpt2_mux_fck>;
+ };
+
+ gpt3_ick: gpt3_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <5>;
+ reg = <0x0210>;
+ };
+
+ gpt3_gate_fck: gpt3_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <5>;
+ reg = <0x0200>;
+ };
+
+ gpt3_mux_fck: gpt3_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_32k_ck>, <&sys_ck>, <&alt_ck>;
+ ti,bit-shift = <4>;
+ reg = <0x0244>;
+ };
+
+ gpt3_fck: gpt3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt3_gate_fck>, <&gpt3_mux_fck>;
+ };
+
+ gpt4_ick: gpt4_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <6>;
+ reg = <0x0210>;
+ };
+
+ gpt4_gate_fck: gpt4_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <6>;
+ reg = <0x0200>;
+ };
+
+ gpt4_mux_fck: gpt4_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_32k_ck>, <&sys_ck>, <&alt_ck>;
+ ti,bit-shift = <6>;
+ reg = <0x0244>;
+ };
+
+ gpt4_fck: gpt4_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt4_gate_fck>, <&gpt4_mux_fck>;
+ };
+
+ gpt5_ick: gpt5_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <7>;
+ reg = <0x0210>;
+ };
+
+ gpt5_gate_fck: gpt5_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <7>;
+ reg = <0x0200>;
+ };
+
+ gpt5_mux_fck: gpt5_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_32k_ck>, <&sys_ck>, <&alt_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0244>;
+ };
+
+ gpt5_fck: gpt5_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt5_gate_fck>, <&gpt5_mux_fck>;
+ };
+
+ gpt6_ick: gpt6_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0210>;
+ };
+
+ gpt6_gate_fck: gpt6_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0200>;
+ };
+
+ gpt6_mux_fck: gpt6_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_32k_ck>, <&sys_ck>, <&alt_ck>;
+ ti,bit-shift = <10>;
+ reg = <0x0244>;
+ };
+
+ gpt6_fck: gpt6_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt6_gate_fck>, <&gpt6_mux_fck>;
+ };
+
+ gpt7_ick: gpt7_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <9>;
+ reg = <0x0210>;
+ };
+
+ gpt7_gate_fck: gpt7_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <9>;
+ reg = <0x0200>;
+ };
+
+ gpt7_mux_fck: gpt7_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_32k_ck>, <&sys_ck>, <&alt_ck>;
+ ti,bit-shift = <12>;
+ reg = <0x0244>;
+ };
+
+ gpt7_fck: gpt7_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt7_gate_fck>, <&gpt7_mux_fck>;
+ };
+
+ gpt8_ick: gpt8_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <10>;
+ reg = <0x0210>;
+ };
+
+ gpt8_gate_fck: gpt8_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <10>;
+ reg = <0x0200>;
+ };
+
+ gpt8_mux_fck: gpt8_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_32k_ck>, <&sys_ck>, <&alt_ck>;
+ ti,bit-shift = <14>;
+ reg = <0x0244>;
+ };
+
+ gpt8_fck: gpt8_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt8_gate_fck>, <&gpt8_mux_fck>;
+ };
+
+ gpt9_ick: gpt9_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <11>;
+ reg = <0x0210>;
+ };
+
+ gpt9_gate_fck: gpt9_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <11>;
+ reg = <0x0200>;
+ };
+
+ gpt9_mux_fck: gpt9_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_32k_ck>, <&sys_ck>, <&alt_ck>;
+ ti,bit-shift = <16>;
+ reg = <0x0244>;
+ };
+
+ gpt9_fck: gpt9_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt9_gate_fck>, <&gpt9_mux_fck>;
+ };
+
+ gpt10_ick: gpt10_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <12>;
+ reg = <0x0210>;
+ };
+
+ gpt10_gate_fck: gpt10_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <12>;
+ reg = <0x0200>;
+ };
+
+ gpt10_mux_fck: gpt10_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_32k_ck>, <&sys_ck>, <&alt_ck>;
+ ti,bit-shift = <18>;
+ reg = <0x0244>;
+ };
+
+ gpt10_fck: gpt10_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt10_gate_fck>, <&gpt10_mux_fck>;
+ };
+
+ gpt11_ick: gpt11_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <13>;
+ reg = <0x0210>;
+ };
+
+ gpt11_gate_fck: gpt11_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <13>;
+ reg = <0x0200>;
+ };
+
+ gpt11_mux_fck: gpt11_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_32k_ck>, <&sys_ck>, <&alt_ck>;
+ ti,bit-shift = <20>;
+ reg = <0x0244>;
+ };
+
+ gpt11_fck: gpt11_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt11_gate_fck>, <&gpt11_mux_fck>;
+ };
+
+ gpt12_ick: gpt12_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <14>;
+ reg = <0x0210>;
+ };
+
+ gpt12_gate_fck: gpt12_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <14>;
+ reg = <0x0200>;
+ };
+
+ gpt12_mux_fck: gpt12_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&func_32k_ck>, <&sys_ck>, <&alt_ck>;
+ ti,bit-shift = <22>;
+ reg = <0x0244>;
+ };
+
+ gpt12_fck: gpt12_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt12_gate_fck>, <&gpt12_mux_fck>;
+ };
+
+ mcbsp1_ick: mcbsp1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <15>;
+ reg = <0x0210>;
+ };
+
+ mcbsp1_gate_fck: mcbsp1_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&mcbsp_clks>;
+ ti,bit-shift = <15>;
+ reg = <0x0200>;
+ };
+
+ mcbsp2_ick: mcbsp2_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <16>;
+ reg = <0x0210>;
+ };
+
+ mcbsp2_gate_fck: mcbsp2_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&mcbsp_clks>;
+ ti,bit-shift = <16>;
+ reg = <0x0200>;
+ };
+
+ mcspi1_ick: mcspi1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <17>;
+ reg = <0x0210>;
+ };
+
+ mcspi1_fck: mcspi1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_48m_ck>;
+ ti,bit-shift = <17>;
+ reg = <0x0200>;
+ };
+
+ mcspi2_ick: mcspi2_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <18>;
+ reg = <0x0210>;
+ };
+
+ mcspi2_fck: mcspi2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_48m_ck>;
+ ti,bit-shift = <18>;
+ reg = <0x0200>;
+ };
+
+ uart1_ick: uart1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <21>;
+ reg = <0x0210>;
+ };
+
+ uart1_fck: uart1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_48m_ck>;
+ ti,bit-shift = <21>;
+ reg = <0x0200>;
+ };
+
+ uart2_ick: uart2_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <22>;
+ reg = <0x0210>;
+ };
+
+ uart2_fck: uart2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_48m_ck>;
+ ti,bit-shift = <22>;
+ reg = <0x0200>;
+ };
+
+ uart3_ick: uart3_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x0214>;
+ };
+
+ uart3_fck: uart3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_48m_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x0204>;
+ };
+
+ gpios_ick: gpios_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x0410>;
+ };
+
+ gpios_fck: gpios_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x0400>;
+ };
+
+ mpu_wdt_ick: mpu_wdt_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <3>;
+ reg = <0x0410>;
+ };
+
+ mpu_wdt_fck: mpu_wdt_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <3>;
+ reg = <0x0400>;
+ };
+
+ sync_32k_ick: sync_32k_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0410>;
+ };
+
+ wdt1_ick: wdt1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <4>;
+ reg = <0x0410>;
+ };
+
+ omapctrl_ick: omapctrl_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <5>;
+ reg = <0x0410>;
+ };
+
+ cam_fck: cam_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&func_96m_ck>;
+ ti,bit-shift = <31>;
+ reg = <0x0200>;
+ };
+
+ cam_ick: cam_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-no-wait-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <31>;
+ reg = <0x0210>;
+ };
+
+ mailboxes_ick: mailboxes_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <30>;
+ reg = <0x0210>;
+ };
+
+ wdt4_ick: wdt4_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <29>;
+ reg = <0x0210>;
+ };
+
+ wdt4_fck: wdt4_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_32k_ck>;
+ ti,bit-shift = <29>;
+ reg = <0x0200>;
+ };
+
+ mspro_ick: mspro_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <27>;
+ reg = <0x0210>;
+ };
+
+ mspro_fck: mspro_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_96m_ck>;
+ ti,bit-shift = <27>;
+ reg = <0x0200>;
+ };
+
+ fac_ick: fac_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <25>;
+ reg = <0x0210>;
+ };
+
+ fac_fck: fac_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_12m_ck>;
+ ti,bit-shift = <25>;
+ reg = <0x0200>;
+ };
+
+ hdq_ick: hdq_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <23>;
+ reg = <0x0210>;
+ };
+
+ hdq_fck: hdq_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_12m_ck>;
+ ti,bit-shift = <23>;
+ reg = <0x0200>;
+ };
+
+ i2c1_ick: i2c1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <19>;
+ reg = <0x0210>;
+ };
+
+ i2c2_ick: i2c2_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <20>;
+ reg = <0x0210>;
+ };
+
+ gpmc_fck: gpmc_fck {
+ #clock-cells = <0>;
+ compatible = "ti,fixed-factor-clock";
+ clocks = <&core_l3_ck>;
+ ti,clock-div = <1>;
+ ti,autoidle-shift = <1>;
+ reg = <0x0238>;
+ ti,clock-mult = <1>;
+ };
+
+ sdma_fck: sdma_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&core_l3_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ sdma_ick: sdma_ick {
+ #clock-cells = <0>;
+ compatible = "ti,fixed-factor-clock";
+ clocks = <&core_l3_ck>;
+ ti,clock-div = <1>;
+ ti,autoidle-shift = <0>;
+ reg = <0x0238>;
+ ti,clock-mult = <1>;
+ };
+
+ sdrc_ick: sdrc_ick {
+ #clock-cells = <0>;
+ compatible = "ti,fixed-factor-clock";
+ clocks = <&core_l3_ck>;
+ ti,clock-div = <1>;
+ ti,autoidle-shift = <2>;
+ reg = <0x0238>;
+ ti,clock-mult = <1>;
+ };
+
+ des_ick: des_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x021c>;
+ };
+
+ sha_ick: sha_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x021c>;
+ };
+
+ rng_ick: rng_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x021c>;
+ };
+
+ aes_ick: aes_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <3>;
+ reg = <0x021c>;
+ };
+
+ pka_ick: pka_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l4_ck>;
+ ti,bit-shift = <4>;
+ reg = <0x021c>;
+ };
+
+ usb_fck: usb_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&func_48m_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x0204>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-beagle-xm-ab.dts b/arch/arm/boot/dts/omap3-beagle-xm-ab.dts
new file mode 100644
index 000000000..7ac3bcf59
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-beagle-xm-ab.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2011 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 "omap3-beagle-xm.dts"
+
+/ {
+ /* HS USB Port 2 Power enable was inverted with the xM C */
+ hsusb2_power: hsusb2_power_reg {
+ enable-active-high;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts b/arch/arm/boot/dts/omap3-beagle-xm.dts
new file mode 100644
index 000000000..7c4dca122
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-beagle-xm.dts
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+/dts-v1/;
+
+#include "omap36xx.dtsi"
+
+/ {
+ model = "TI OMAP3 BeagleBoard xM";
+ compatible = "ti,omap3-beagle-xm", "ti,omap36xx", "ti,omap3";
+
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vcc>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>; /* 512 MB */
+ };
+
+ aliases {
+ display0 = &dvi0;
+ display1 = &tv0;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ heartbeat {
+ label = "beagleboard::usr0";
+ gpios = <&gpio5 22 GPIO_ACTIVE_HIGH>; /* 150 -> D6 LED */
+ linux,default-trigger = "heartbeat";
+ };
+
+ mmc {
+ label = "beagleboard::usr1";
+ gpios = <&gpio5 21 GPIO_ACTIVE_HIGH>; /* 149 -> D7 LED */
+ linux,default-trigger = "mmc0";
+ };
+ };
+
+ pwmleds {
+ compatible = "pwm-leds";
+
+ pmu_stat {
+ label = "beagleboard::pmu_stat";
+ pwms = <&twl_pwmled 1 7812500>;
+ max-brightness = <127>;
+ };
+ };
+
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "omap3beagle";
+
+ ti,mcbsp = <&mcbsp2>;
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ user {
+ label = "user";
+ gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+ linux,code = <0x114>;
+ gpio-key,wakeup;
+ };
+
+ };
+
+ /* HS USB Port 2 Power */
+ hsusb2_power: hsusb2_power_reg {
+ compatible = "regulator-fixed";
+ regulator-name = "hsusb2_vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&twl_gpio 18 0>; /* GPIO LEDA */
+ startup-delay-us = <70000>;
+ };
+
+ /* HS USB Host PHY on PORT 2 */
+ hsusb2_phy: hsusb2_phy {
+ compatible = "usb-nop-xceiv";
+ reset-gpios = <&gpio5 19 GPIO_ACTIVE_LOW>; /* gpio_147 */
+ vcc-supply = <&hsusb2_power>;
+ };
+
+ tfp410: encoder@0 {
+ compatible = "ti,tfp410";
+ powerdown-gpios = <&twl_gpio 2 GPIO_ACTIVE_LOW>;
+
+ /* XXX pinctrl from twl */
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ tfp410_in: endpoint@0 {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ tfp410_out: endpoint@0 {
+ remote-endpoint = <&dvi_connector_in>;
+ };
+ };
+ };
+ };
+
+ dvi0: connector@0 {
+ compatible = "dvi-connector";
+ label = "dvi";
+
+ digital;
+
+ ddc-i2c-bus = <&i2c3>;
+
+ port {
+ dvi_connector_in: endpoint {
+ remote-endpoint = <&tfp410_out>;
+ };
+ };
+ };
+
+ tv0: connector@1 {
+ compatible = "svideo-connector";
+ label = "tv";
+
+ port {
+ tv_connector_in: endpoint {
+ remote-endpoint = <&venc_out>;
+ };
+ };
+ };
+
+ etb@5401b000 {
+ compatible = "arm,coresight-etb10", "arm,primecell";
+ reg = <0x5401b000 0x1000>;
+
+ clocks = <&emu_src_ck>;
+ clock-names = "apb_pclk";
+ port {
+ etb_in: endpoint {
+ slave-mode;
+ remote-endpoint = <&etm_out>;
+ };
+ };
+ };
+
+ etm@54010000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0x54010000 0x1000>;
+
+ clocks = <&emu_src_ck>;
+ clock-names = "apb_pclk";
+ port {
+ etm_out: endpoint {
+ remote-endpoint = <&etb_in>;
+ };
+ };
+ };
+};
+
+&omap3_pmx_wkup {
+ gpio1_pins: pinmux_gpio1_pins {
+ pinctrl-single,pins = <
+ 0x0e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE4) /* sys_boot2.gpio_4 */
+ >;
+ };
+
+ dss_dpi_pins2: pinmux_dss_dpi_pins1 {
+ pinctrl-single,pins = <
+ 0x0a (PIN_OUTPUT | MUX_MODE3) /* sys_boot0.dss_data18 */
+ 0x0c (PIN_OUTPUT | MUX_MODE3) /* sys_boot1.dss_data19 */
+ 0x10 (PIN_OUTPUT | MUX_MODE3) /* sys_boot3.dss_data20 */
+ 0x12 (PIN_OUTPUT | MUX_MODE3) /* sys_boot4.dss_data21 */
+ 0x14 (PIN_OUTPUT | MUX_MODE3) /* sys_boot5.dss_data22 */
+ 0x16 (PIN_OUTPUT | MUX_MODE3) /* sys_boot6.dss_data23 */
+ >;
+ };
+};
+
+&omap3_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusb2_pins
+ >;
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ 0x16e (PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+ 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx OUTPUT | MODE0 */
+ >;
+ };
+
+ hsusb2_pins: pinmux_hsusb2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21d4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */
+ OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */
+ OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */
+ OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */
+ OMAP3_CORE1_IOPAD(0x21dc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */
+ OMAP3_CORE1_IOPAD(0x21de, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */
+ >;
+ };
+
+ dss_dpi_pins1: pinmux_dss_dpi_pins2 {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */
+ OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */
+ OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */
+ OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */
+
+ OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */
+ OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */
+ OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */
+ OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */
+ OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */
+ OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */
+ OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */
+ OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */
+ OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */
+ OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */
+ OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */
+ OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */
+
+ OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE3) /* dss_data18.dss_data0 */
+ OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE3) /* dss_data19.dss_data1 */
+ OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE3) /* dss_data20.dss_data2 */
+ OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE3) /* dss_data21.dss_data3 */
+ OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE3) /* dss_data22.dss_data4 */
+ OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE3) /* dss_data23.dss_data5 */
+ >;
+ };
+};
+
+&omap3_pmx_core2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusb2_2_pins
+ >;
+
+ hsusb2_2_pins: pinmux_hsusb2_2_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */
+ OMAP3630_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */
+ OMAP3630_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */
+ OMAP3630_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */
+ OMAP3630_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */
+ OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */
+ >;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ codec {
+ };
+ };
+
+ twl_power: power {
+ compatible = "ti,twl4030-power-beagleboard-xm", "ti,twl4030-power-idle-osc-off";
+ ti,use_poweroff;
+ };
+ };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&i2c2 {
+ clock-frequency = <400000>;
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+};
+
+&mmc1 {
+ vmmc-supply = <&vmmc1>;
+ vmmc_aux-supply = <&vsim>;
+ bus-width = <8>;
+};
+
+&mmc2 {
+ status = "disabled";
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&twl_gpio {
+ ti,use-leds;
+ /* pullups: BIT(1) */
+ ti,pullups = <0x000002>;
+ /*
+ * pulldowns:
+ * BIT(2), BIT(6), BIT(7), BIT(8), BIT(13)
+ * BIT(15), BIT(16), BIT(17)
+ */
+ ti,pulldowns = <0x03a1c4>;
+};
+
+&usb_otg_hs {
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ phys = <&usb2_phy>;
+ phy-names = "usb2-phy";
+ mode = <3>;
+ power = <50>;
+};
+
+&uart3 {
+ interrupts-extended = <&intc 74 &omap3_pmx_core OMAP3_UART3_RX>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+};
+
+&gpio1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio1_pins>;
+};
+
+&usbhshost {
+ port2-mode = "ehci-phy";
+};
+
+&usbhsehci {
+ phys = <0 &hsusb2_phy>;
+};
+
+&vaux2 {
+ regulator-name = "usb_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+};
+
+&mcbsp2 {
+ status = "okay";
+};
+
+&dss {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &dss_dpi_pins1
+ &dss_dpi_pins2
+ >;
+
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&tfp410_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+&venc {
+ status = "ok";
+
+ vdda-supply = <&vdac>;
+
+ port {
+ venc_out: endpoint {
+ remote-endpoint = <&tv_connector_in>;
+ ti,channels = <2>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts
new file mode 100644
index 000000000..a5474113c
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-beagle.dts
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+/dts-v1/;
+
+#include "omap34xx.dtsi"
+
+/ {
+ model = "TI OMAP3 BeagleBoard";
+ compatible = "ti,omap3-beagle", "ti,omap3";
+
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vcc>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ aliases {
+ display0 = &dvi0;
+ display1 = &tv0;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pmu_stat {
+ label = "beagleboard::pmu_stat";
+ gpios = <&twl_gpio 19 GPIO_ACTIVE_HIGH>; /* LEDB */
+ };
+
+ heartbeat {
+ label = "beagleboard::usr0";
+ gpios = <&gpio5 22 GPIO_ACTIVE_HIGH>; /* 150 -> D6 LED */
+ linux,default-trigger = "heartbeat";
+ };
+
+ mmc {
+ label = "beagleboard::usr1";
+ gpios = <&gpio5 21 GPIO_ACTIVE_HIGH>; /* 149 -> D7 LED */
+ linux,default-trigger = "mmc0";
+ };
+ };
+
+ /* HS USB Port 2 Power */
+ hsusb2_power: hsusb2_power_reg {
+ compatible = "regulator-fixed";
+ regulator-name = "hsusb2_vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&twl_gpio 18 0>; /* GPIO LEDA */
+ startup-delay-us = <70000>;
+ };
+
+ /* HS USB Host PHY on PORT 2 */
+ hsusb2_phy: hsusb2_phy {
+ compatible = "usb-nop-xceiv";
+ reset-gpios = <&gpio5 19 GPIO_ACTIVE_LOW>; /* gpio_147 */
+ vcc-supply = <&hsusb2_power>;
+ };
+
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "omap3beagle";
+
+ ti,mcbsp = <&mcbsp2>;
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ user {
+ label = "user";
+ gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ linux,code = <0x114>;
+ gpio-key,wakeup;
+ };
+
+ };
+
+ tfp410: encoder@0 {
+ compatible = "ti,tfp410";
+ powerdown-gpios = <&gpio6 10 GPIO_ACTIVE_LOW>; /* gpio_170 */
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&tfp410_pins>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ tfp410_in: endpoint@0 {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ tfp410_out: endpoint@0 {
+ remote-endpoint = <&dvi_connector_in>;
+ };
+ };
+ };
+ };
+
+ dvi0: connector@0 {
+ compatible = "dvi-connector";
+ label = "dvi";
+
+ digital;
+
+ ddc-i2c-bus = <&i2c3>;
+
+ port {
+ dvi_connector_in: endpoint {
+ remote-endpoint = <&tfp410_out>;
+ };
+ };
+ };
+
+ tv0: connector@1 {
+ compatible = "svideo-connector";
+ label = "tv";
+
+ port {
+ tv_connector_in: endpoint {
+ remote-endpoint = <&venc_out>;
+ };
+ };
+ };
+
+ etb@540000000 {
+ compatible = "arm,coresight-etb10", "arm,primecell";
+ reg = <0x5401b000 0x1000>;
+
+ clocks = <&emu_src_ck>;
+ clock-names = "apb_pclk";
+ port {
+ etb_in: endpoint {
+ slave-mode;
+ remote-endpoint = <&etm_out>;
+ };
+ };
+ };
+
+ etm@54010000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0x54010000 0x1000>;
+
+ clocks = <&emu_src_ck>;
+ clock-names = "apb_pclk";
+ port {
+ etm_out: endpoint {
+ remote-endpoint = <&etb_in>;
+ };
+ };
+ };
+};
+
+&omap3_pmx_wkup {
+ gpio1_pins: pinmux_gpio1_pins {
+ pinctrl-single,pins = <
+ 0x14 (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE4) /* sys_boot5.gpio_7 */
+ >;
+ };
+};
+
+&omap3_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusb2_pins
+ >;
+
+ hsusb2_pins: pinmux_hsusb2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21d4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */
+ OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */
+ OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */
+ OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */
+ OMAP3_CORE1_IOPAD(0x21dc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */
+ OMAP3_CORE1_IOPAD(0x21de, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ 0x16e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+ 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */
+ >;
+ };
+
+ tfp410_pins: pinmux_tfp410_pins {
+ pinctrl-single,pins = <
+ 0x194 (PIN_OUTPUT | MUX_MODE4) /* hdq_sio.gpio_170 */
+ >;
+ };
+
+ dss_dpi_pins: pinmux_dss_dpi_pins {
+ pinctrl-single,pins = <
+ 0x0a4 (PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */
+ 0x0a6 (PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */
+ 0x0a8 (PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */
+ 0x0aa (PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */
+ 0x0ac (PIN_OUTPUT | MUX_MODE0) /* dss_data0.dss_data0 */
+ 0x0ae (PIN_OUTPUT | MUX_MODE0) /* dss_data1.dss_data1 */
+ 0x0b0 (PIN_OUTPUT | MUX_MODE0) /* dss_data2.dss_data2 */
+ 0x0b2 (PIN_OUTPUT | MUX_MODE0) /* dss_data3.dss_data3 */
+ 0x0b4 (PIN_OUTPUT | MUX_MODE0) /* dss_data4.dss_data4 */
+ 0x0b6 (PIN_OUTPUT | MUX_MODE0) /* dss_data5.dss_data5 */
+ 0x0b8 (PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */
+ 0x0ba (PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */
+ 0x0bc (PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */
+ 0x0be (PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */
+ 0x0c0 (PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */
+ 0x0c2 (PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */
+ 0x0c4 (PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */
+ 0x0c6 (PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */
+ 0x0c8 (PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */
+ 0x0ca (PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */
+ 0x0cc (PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */
+ 0x0ce (PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */
+ 0x0d0 (PIN_OUTPUT | MUX_MODE0) /* dss_data18.dss_data18 */
+ 0x0d2 (PIN_OUTPUT | MUX_MODE0) /* dss_data19.dss_data19 */
+ 0x0d4 (PIN_OUTPUT | MUX_MODE0) /* dss_data20.dss_data20 */
+ 0x0d6 (PIN_OUTPUT | MUX_MODE0) /* dss_data21.dss_data21 */
+ 0x0d8 (PIN_OUTPUT | MUX_MODE0) /* dss_data22.dss_data22 */
+ 0x0da (PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */
+ >;
+ };
+};
+
+&omap3_pmx_core2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusb2_2_pins
+ >;
+
+ hsusb2_2_pins: pinmux_hsusb2_2_pins {
+ pinctrl-single,pins = <
+ OMAP3430_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */
+ OMAP3430_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */
+ OMAP3430_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */
+ OMAP3430_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */
+ OMAP3430_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */
+ OMAP3430_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */
+ >;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ codec {
+ };
+ };
+ };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&i2c3 {
+ clock-frequency = <100000>;
+};
+
+&mmc1 {
+ vmmc-supply = <&vmmc1>;
+ vmmc_aux-supply = <&vsim>;
+ bus-width = <8>;
+};
+
+&mmc2 {
+ status = "disabled";
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&usbhshost {
+ port2-mode = "ehci-phy";
+};
+
+&usbhsehci {
+ phys = <0 &hsusb2_phy>;
+};
+
+&twl_gpio {
+ ti,use-leds;
+ /* pullups: BIT(1) */
+ ti,pullups = <0x000002>;
+ /*
+ * pulldowns:
+ * BIT(2), BIT(6), BIT(7), BIT(8), BIT(13)
+ * BIT(15), BIT(16), BIT(17)
+ */
+ ti,pulldowns = <0x03a1c4>;
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+ interrupts-extended = <&intc 74 &omap3_pmx_core OMAP3_UART3_RX>;
+};
+
+&gpio1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio1_pins>;
+};
+
+&usb_otg_hs {
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ phys = <&usb2_phy>;
+ phy-names = "usb2-phy";
+ mode = <3>;
+ power = <50>;
+};
+
+&vaux2 {
+ regulator-name = "vdd_ehci";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+};
+
+&mcbsp2 {
+ status = "okay";
+};
+
+/* Needed to power the DPI pins */
+&vpll2 {
+ regulator-always-on;
+};
+
+&dss {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_dpi_pins>;
+
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&tfp410_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+&venc {
+ status = "ok";
+
+ vdda-supply = <&vdac>;
+
+ port {
+ venc_out: endpoint {
+ remote-endpoint = <&tv_connector_in>;
+ ti,channels = <2>;
+ };
+ };
+};
+
+&gpmc {
+ status = "ok";
+ ranges = <0 0 0x30000000 0x1000000>; /* CS0 space, 16MB */
+
+ /* Chip select 0 */
+ nand@0,0 {
+ reg = <0 0 4>; /* NAND I/O window, 4 bytes */
+ interrupts = <20>;
+ ti,nand-ecc-opt = "ham1";
+ nand-bus-width = <16>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ gpmc,device-width = <2>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <36>;
+ gpmc,cs-wr-off-ns = <36>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <24>;
+ gpmc,adv-wr-off-ns = <36>;
+ gpmc,oe-on-ns = <6>;
+ gpmc,oe-off-ns = <48>;
+ gpmc,we-on-ns = <6>;
+ gpmc,we-off-ns = <30>;
+ gpmc,rd-cycle-ns = <72>;
+ gpmc,wr-cycle-ns = <72>;
+ gpmc,access-ns = <54>;
+ gpmc,wr-access-ns = <30>;
+
+ partition@0 {
+ label = "X-Loader";
+ reg = <0 0x80000>;
+ };
+ partition@80000 {
+ label = "U-Boot";
+ reg = <0x80000 0x1e0000>;
+ };
+ partition@1c0000 {
+ label = "U-Boot Env";
+ reg = <0x260000 0x20000>;
+ };
+ partition@280000 {
+ label = "Kernel";
+ reg = <0x280000 0x400000>;
+ };
+ partition@780000 {
+ label = "Filesystem";
+ reg = <0x680000 0xf980000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-cm-t3517.dts b/arch/arm/boot/dts/omap3-cm-t3517.dts
new file mode 100644
index 000000000..f5b5a1d96
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-cm-t3517.dts
@@ -0,0 +1,157 @@
+/*
+ * Support for CompuLab CM-T3517
+ */
+/dts-v1/;
+
+#include "am3517.dtsi"
+#include "omap3-cm-t3x.dtsi"
+
+/ {
+ model = "CompuLab CM-T3517";
+ compatible = "compulab,omap3-cm-t3517", "ti,am3517", "ti,omap3";
+
+ vmmc: regulator-vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ wl12xx_vmmc2: wl12xx_vmmc2 {
+ compatible = "regulator-fixed";
+ regulator-name = "vw1271";
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &wl12xx_wkup_pins
+ &wl12xx_core_pins
+ >;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio1 6 GPIO_ACTIVE_HIGH >; /* gpio6 */
+ startup-delay-us = <20000>;
+ enable-active-high;
+ };
+
+ wl12xx_vaux2: wl12xx_vaux2 {
+ compatible = "regulator-fixed";
+ regulator-name = "vwl1271_vaux2";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+};
+
+&omap3_pmx_wkup {
+
+ wl12xx_wkup_pins: pinmux_wl12xx_wkup_pins {
+ pinctrl-single,pins = <
+ OMAP3_WKUP_IOPAD(0x2a0e, PIN_OUTPUT | MUX_MODE4) /* sys_boot2.gpio_4 */
+ OMAP3_WKUP_IOPAD(0x2a12, PIN_OUTPUT | MUX_MODE4) /* sys_boot4.gpio_6 */
+ >;
+ };
+};
+
+&omap3_pmx_core {
+
+ phy1_reset_pins: pinmux_hsusb1_phy_reset_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE4) /* uart2_tx.gpio_146 */
+ >;
+ };
+
+ phy2_reset_pins: pinmux_hsusb2_phy_reset_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x217a, PIN_OUTPUT | MUX_MODE4) /* uart2_rx.gpio_147 */
+ >;
+ };
+
+ otg_drv_vbus: pinmux_otg_drv_vbus {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2210, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii_50Mhz_clk.usb0_drvvbus */
+ >;
+ };
+
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
+ OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
+ OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
+ OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+ OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
+ OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
+ >;
+ };
+
+ wl12xx_core_pins: pinmux_wl12xx_core_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20b8, PIN_OUTPUT | MUX_MODE4) /* gpmc_ncs5.gpio_56 */
+ OMAP3_CORE1_IOPAD(0x2176, PIN_INPUT_PULLUP | MUX_MODE4) /* uart2_rts.gpio_145 */
+ >;
+ };
+
+ usb_hub_pins: pinmux_usb_hub_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2184, PIN_OUTPUT | MUX_MODE4) /* mcbsp4_clkx.gpio_152 - USB HUB RST */
+ >;
+ };
+};
+
+&hsusb1_phy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&phy1_reset_pins>;
+ reset-gpios = <&gpio5 18 GPIO_ACTIVE_LOW>;
+};
+
+&hsusb2_phy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&phy2_reset_pins>;
+ reset-gpios = <&gpio5 19 GPIO_ACTIVE_LOW>;
+};
+
+&davinci_emac {
+ status = "okay";
+};
+
+&davinci_mdio {
+ status = "okay";
+};
+
+&am35x_otg_hs {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&otg_drv_vbus>;
+};
+
+&mmc1 {
+ vmmc-supply = <&vmmc>;
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+ vmmc-supply = <&wl12xx_vmmc2>;
+ vmmc_aux-supply = <&wl12xx_vaux2>;
+ non-removable;
+ bus-width = <4>;
+ cap-power-off-card;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1271";
+ reg = <2>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH>; /* gpio 145 */
+ ref-clock-frequency = <38400000>;
+ };
+};
+
+&dss {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &dss_dpi_pins_common
+ &dss_dpi_pins_cm_t35x
+ >;
+};
+
diff --git a/arch/arm/boot/dts/omap3-cm-t3530.dts b/arch/arm/boot/dts/omap3-cm-t3530.dts
new file mode 100644
index 000000000..8dd14fcf6
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-cm-t3530.dts
@@ -0,0 +1,59 @@
+/*
+ * Support for CompuLab CM-T3530
+ */
+/dts-v1/;
+
+#include "omap34xx.dtsi"
+#include "omap3-cm-t3x30.dtsi"
+
+/ {
+ model = "CompuLab CM-T3530";
+ compatible = "compulab,omap3-cm-t3530", "ti,omap34xx", "ti,omap3";
+
+ /* Regulator to trigger the reset signal of the Wifi module */
+ mmc2_sdio_reset: regulator-mmc2-sdio-reset {
+ compatible = "regulator-fixed";
+ regulator-name = "regulator-mmc2-sdio-reset";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&twl_gpio 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+};
+
+&omap3_pmx_core {
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
+ OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
+ OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
+ OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+ OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
+ OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
+ OMAP3_CORE1_IOPAD(0x2164, PIN_OUTPUT | MUX_MODE1) /* sdmmc2_dat4.sdmmc2_dir_dat0 */
+ OMAP3_CORE1_IOPAD(0x2166, PIN_OUTPUT | MUX_MODE1) /* sdmmc2_dat5.sdmmc2_dir_dat1 */
+ OMAP3_CORE1_IOPAD(0x2168, PIN_OUTPUT | MUX_MODE1) /* sdmmc2_dat6.sdmmc2_dir_cmd */
+ OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT | MUX_MODE1) /* sdmmc2_dat7.sdmmc2_clkin */
+ >;
+ };
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+ vmmc-supply = <&mmc2_sdio_reset>;
+ non-removable;
+ bus-width = <4>;
+ cap-power-off-card;
+};
+
+&dss {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &dss_dpi_pins_common
+ &dss_dpi_pins_cm_t35x
+ >;
+};
+
diff --git a/arch/arm/boot/dts/omap3-cm-t3730.dts b/arch/arm/boot/dts/omap3-cm-t3730.dts
new file mode 100644
index 000000000..2294f5b0a
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-cm-t3730.dts
@@ -0,0 +1,97 @@
+/*
+ * Support for CompuLab CM-T3730
+ */
+/dts-v1/;
+
+#include "omap36xx.dtsi"
+#include "omap3-cm-t3x30.dtsi"
+
+/ {
+ model = "CompuLab CM-T3730";
+ compatible = "compulab,omap3-cm-t3730", "ti,omap36xx", "ti,omap3";
+
+ wl12xx_vmmc2: wl12xx_vmmc2 {
+ compatible = "regulator-fixed";
+ regulator-name = "vw1271";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wl12xx_gpio>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio3 9 GPIO_ACTIVE_HIGH>; /* gpio73 */
+ startup-delay-us = <20000>;
+ enable-active-high;
+ };
+
+ wl12xx_vaux2: wl12xx_vaux2 {
+ compatible = "regulator-fixed";
+ regulator-name = "vwl1271_vaux2";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vaux2>;
+ };
+};
+
+&omap3_pmx_wkup {
+ dss_dpi_pins_cm_t3730: pinmux_dss_dpi_pins_cm_t3730 {
+ pinctrl-single,pins = <
+ OMAP3_WKUP_IOPAD(0x2a08, PIN_OUTPUT | MUX_MODE3) /* sys_boot0.dss_data18 */
+ OMAP3_WKUP_IOPAD(0x2a0c, PIN_OUTPUT | MUX_MODE3) /* sys_boot1.dss_data19 */
+ OMAP3_WKUP_IOPAD(0x2a10, PIN_OUTPUT | MUX_MODE3) /* sys_boot3.dss_data20 */
+ OMAP3_WKUP_IOPAD(0x2a12, PIN_OUTPUT | MUX_MODE3) /* sys_boot4.dss_data21 */
+ OMAP3_WKUP_IOPAD(0x2a14, PIN_OUTPUT | MUX_MODE3) /* sys_boot5.dss_data22 */
+ OMAP3_WKUP_IOPAD(0x2a16, PIN_OUTPUT | MUX_MODE3) /* sys_boot6.dss_data23 */
+ >;
+ };
+};
+
+&omap3_pmx_core {
+
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
+ OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
+ OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
+ OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+ OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
+ OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
+ >;
+ };
+
+ wl12xx_gpio: pinmux_wl12xx_gpio {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE4) /* dss_data3.gpio_73 */
+ OMAP3_CORE1_IOPAD(0x2164, PIN_INPUT | MUX_MODE4) /* sdmmc2_dat4.gpio_136 */
+ >;
+ };
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+ vmmc-supply = <&wl12xx_vmmc2>;
+ vmmc_aux-supply = <&wl12xx_vaux2>;
+ non-removable;
+ bus-width = <4>;
+ cap-power-off-card;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1271";
+ reg = <2>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; /* gpio 136 */
+ ref-clock-frequency = <38400000>;
+ };
+};
+
+&dss {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &dss_dpi_pins_common
+ &dss_dpi_pins_cm_t3730
+ >;
+};
+
diff --git a/arch/arm/boot/dts/omap3-cm-t3x.dtsi b/arch/arm/boot/dts/omap3-cm-t3x.dtsi
new file mode 100644
index 000000000..4d091ca43
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-cm-t3x.dtsi
@@ -0,0 +1,319 @@
+/*
+ * Common support for CompuLab CM-T3x CoMs
+ */
+
+/ {
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&green_led_pins>;
+ ledb {
+ label = "cm-t3x:green";
+ gpios = <&gpio6 26 GPIO_ACTIVE_HIGH>; /* gpio186 */
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ /* HS USB Port 1 Power */
+ hsusb1_power: hsusb1_power_reg {
+ compatible = "regulator-fixed";
+ regulator-name = "hsusb1_vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <70000>;
+ };
+
+ /* HS USB Port 2 Power */
+ hsusb2_power: hsusb2_power_reg {
+ compatible = "regulator-fixed";
+ regulator-name = "hsusb2_vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <70000>;
+ };
+
+ /* HS USB Host PHY on PORT 1 */
+ hsusb1_phy: hsusb1_phy {
+ compatible = "usb-nop-xceiv";
+ vcc-supply = <&hsusb1_power>;
+ };
+
+ /* HS USB Host PHY on PORT 2 */
+ hsusb2_phy: hsusb2_phy {
+ compatible = "usb-nop-xceiv";
+ vcc-supply = <&hsusb2_power>;
+ };
+
+ ads7846reg: ads7846-reg {
+ compatible = "regulator-fixed";
+ regulator-name = "ads7846-reg";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ tv0: connector@1 {
+ compatible = "svideo-connector";
+ label = "tv";
+
+ port {
+ tv_connector_in: endpoint {
+ remote-endpoint = <&venc_out>;
+ };
+ };
+ };
+};
+
+&omap3_pmx_core {
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+ OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */
+ OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */
+ OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */
+ OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */
+ OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */
+ OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
+ >;
+ };
+
+ green_led_pins: pinmux_green_led_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21e2, PIN_OUTPUT | MUX_MODE4) /* sys_clkout2.gpio_186 */
+ >;
+ };
+
+ dss_dpi_pins_common: pinmux_dss_dpi_pins_common {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */
+ OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */
+ OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */
+ OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */
+
+ OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */
+ OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */
+ OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */
+ OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */
+ OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */
+ OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */
+ OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */
+ OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */
+ OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */
+ OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */
+ OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */
+ OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */
+ OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE0) /* dss_data18.dss_data18 */
+ OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE0) /* dss_data19.dss_data19 */
+ OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE0) /* dss_data20.dss_data20 */
+ OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE0) /* dss_data21.dss_data21 */
+ OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE0) /* dss_data22.dss_data22 */
+ OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */
+ >;
+ };
+
+ dss_dpi_pins_cm_t35x: pinmux_dss_dpi_pins_cm_t35x {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE0) /* dss_data0.dss_data0 */
+ OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT | MUX_MODE0) /* dss_data1.dss_data1 */
+ OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT | MUX_MODE0) /* dss_data2.dss_data2 */
+ OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE0) /* dss_data3.dss_data3 */
+ OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE0) /* dss_data4.dss_data4 */
+ OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE0) /* dss_data5.dss_data5 */
+ >;
+ };
+
+ ads7846_pins: pinmux_ads7846_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20ba, PIN_INPUT_PULLUP | MUX_MODE4) /* gpmc_ncs6.gpio_57 */
+ >;
+ };
+
+ mcspi1_pins: pinmux_mcspi1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21c8, PIN_INPUT | MUX_MODE0) /* mcspi1_clk */
+ OMAP3_CORE1_IOPAD(0x21ca, PIN_INPUT | MUX_MODE0) /* mcspi1_simo */
+ OMAP3_CORE1_IOPAD(0x21cc, PIN_INPUT | MUX_MODE0) /* mcspi1_somi */
+ OMAP3_CORE1_IOPAD(0x21ce, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcspi1_cs0 */
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */
+ OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */
+ >;
+ };
+
+ mcbsp2_pins: pinmux_mcbsp2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x213c, PIN_INPUT | MUX_MODE0) /* mcbsp2_fsx */
+ OMAP3_CORE1_IOPAD(0x213e, PIN_INPUT | MUX_MODE0) /* mcbsp2_clkx */
+ OMAP3_CORE1_IOPAD(0x2140, PIN_INPUT | MUX_MODE0) /* mcbsp2_dr */
+ OMAP3_CORE1_IOPAD(0x2142, PIN_OUTPUT | MUX_MODE0) /* mcbsp2_dx */
+ >;
+ };
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ bus-width = <4>;
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+
+ clock-frequency = <400000>;
+
+ at24@50 {
+ compatible = "at24,24c02";
+ pagesize = <16>;
+ reg = <0x50>;
+ };
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+};
+
+&usbhshost {
+ port1-mode = "ehci-phy";
+ port2-mode = "ehci-phy";
+};
+
+&usbhsehci {
+ phys = <&hsusb1_phy &hsusb2_phy>;
+};
+
+&mcspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi1_pins>;
+
+ /* touch controller */
+ ads7846@0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ads7846_pins>;
+
+ compatible = "ti,ads7846";
+ vcc-supply = <&ads7846reg>;
+
+ reg = <0>; /* CS0 */
+ spi-max-frequency = <1500000>;
+
+ interrupt-parent = <&gpio2>;
+ interrupts = <25 0>; /* gpio_57 */
+ pendown-gpio = <&gpio2 25 0>;
+
+ ti,x-min = /bits/ 16 <0x0>;
+ ti,x-max = /bits/ 16 <0x0fff>;
+ ti,y-min = /bits/ 16 <0x0>;
+ ti,y-max = /bits/ 16 <0x0fff>;
+
+ ti,x-plate-ohms = /bits/ 16 <180>;
+ ti,pressure-max = /bits/ 16 <255>;
+
+ ti,debounce-max = /bits/ 16 <30>;
+ ti,debounce-tol = /bits/ 16 <10>;
+ ti,debounce-rep = /bits/ 16 <1>;
+
+ linux,wakeup;
+ };
+};
+
+&venc {
+ status = "ok";
+
+ port {
+ venc_out: endpoint {
+ remote-endpoint = <&tv_connector_in>;
+ ti,channels = <2>;
+ };
+ };
+};
+
+&mcbsp2 {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcbsp2_pins>;
+};
+
+&gpmc {
+ ranges = <0 0 0x00000000 0x01000000>;
+
+ nand@0,0 {
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ nand-bus-width = <8>;
+ gpmc,device-width = <1>;
+ ti,nand-ecc-opt = "sw";
+
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <120>;
+ gpmc,cs-wr-off-ns = <120>;
+
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <120>;
+ gpmc,adv-wr-off-ns = <120>;
+
+ gpmc,we-on-ns = <6>;
+ gpmc,we-off-ns = <90>;
+
+ gpmc,oe-on-ns = <6>;
+ gpmc,oe-off-ns = <90>;
+
+ gpmc,page-burst-access-ns = <6>;
+ gpmc,access-ns = <72>;
+ gpmc,cycle2cycle-delay-ns = <60>;
+
+ gpmc,rd-cycle-ns = <120>;
+ gpmc,wr-cycle-ns = <120>;
+ gpmc,wr-access-ns = <186>;
+ gpmc,wr-data-mux-bus-ns = <90>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "xloader";
+ reg = <0 0x80000>;
+ };
+ partition@0x80000 {
+ label = "uboot";
+ reg = <0x80000 0x1e0000>;
+ };
+ partition@0x260000 {
+ label = "uboot environment";
+ reg = <0x260000 0x40000>;
+ };
+ partition@0x2a0000 {
+ label = "linux";
+ reg = <0x2a0000 0x400000>;
+ };
+ partition@0x6a0000 {
+ label = "rootfs";
+ reg = <0x6a0000 0x1f880000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
new file mode 100644
index 000000000..046cd7733
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
@@ -0,0 +1,130 @@
+/*
+ * Common support for CompuLab CM-T3x30 CoMs
+ */
+
+#include "omap3-cm-t3x.dtsi"
+
+/ {
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vcc>;
+ };
+ };
+
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "cm-t35";
+
+ ti,mcbsp = <&mcbsp2>;
+ };
+};
+
+&omap3_pmx_core {
+
+ smsc1_pins: pinmux_smsc1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20b8, PIN_OUTPUT | MUX_MODE0) /* gpmc_ncs5.gpmc_ncs5 */
+ OMAP3_CORE1_IOPAD(0x219a, PIN_INPUT_PULLUP | MUX_MODE4) /* uart3_cts_rctx.gpio_163 */
+ >;
+ };
+
+ hsusb0_pins: pinmux_hsusb0_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21a2, PIN_OUTPUT | MUX_MODE0) /* hsusb0_clk.hsusb0_clk */
+ OMAP3_CORE1_IOPAD(0x21a4, PIN_OUTPUT | MUX_MODE0) /* hsusb0_stp.hsusb0_stp */
+ OMAP3_CORE1_IOPAD(0x21a6, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_dir.hsusb0_dir */
+ OMAP3_CORE1_IOPAD(0x21a8, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_nxt.hsusb0_nxt */
+ OMAP3_CORE1_IOPAD(0x21aa, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data0.hsusb2_data0 */
+ OMAP3_CORE1_IOPAD(0x21ac, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data1.hsusb0_data1 */
+ OMAP3_CORE1_IOPAD(0x21ae, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data2.hsusb0_data2 */
+ OMAP3_CORE1_IOPAD(0x21b0, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data7.hsusb0_data3 */
+ OMAP3_CORE1_IOPAD(0x21b2, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data7.hsusb0_data4 */
+ OMAP3_CORE1_IOPAD(0x21b4, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data7.hsusb0_data5 */
+ OMAP3_CORE1_IOPAD(0x21b6, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data7.hsusb0_data6 */
+ OMAP3_CORE1_IOPAD(0x21b8, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data7.hsusb0_data7 */
+ >;
+ };
+};
+
+#include "omap-gpmc-smsc911x.dtsi"
+
+&gpmc {
+ ranges = <5 0 0x2c000000 0x01000000>, /* CM-T3x30 SMSC9x Eth */
+ <0 0 0x00000000 0x01000000>; /* CM-T3x NAND */
+
+ smsc1: ethernet@gpmc {
+ compatible = "smsc,lan9221", "smsc,lan9115";
+ pinctrl-names = "default";
+ pinctrl-0 = <&smsc1_pins>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+ reg = <5 0 0xff>;
+ };
+};
+
+&i2c1 {
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ codec {
+ };
+ };
+ };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+#include <dt-bindings/input/input.h>
+
+&venc {
+ vdda-supply = <&vdac>;
+};
+
+&mmc1 {
+ vmmc-supply = <&vmmc1>;
+};
+
+&twl_gpio {
+ ti,use-leds;
+ /* pullups: BIT(0) */
+ ti,pullups = <0x000001>;
+};
+
+&twl_keypad {
+ linux,keymap = <
+ MATRIX_KEY(0x00, 0x01, KEY_A)
+ MATRIX_KEY(0x00, 0x02, KEY_B)
+ MATRIX_KEY(0x00, 0x03, KEY_LEFT)
+
+ MATRIX_KEY(0x01, 0x01, KEY_UP)
+ MATRIX_KEY(0x01, 0x02, KEY_ENTER)
+ MATRIX_KEY(0x01, 0x03, KEY_DOWN)
+
+ MATRIX_KEY(0x02, 0x01, KEY_RIGHT)
+ MATRIX_KEY(0x02, 0x02, KEY_C)
+ MATRIX_KEY(0x02, 0x03, KEY_D)
+ >;
+};
+
+&hsusb1_phy {
+ reset-gpios = <&twl_gpio 6 GPIO_ACTIVE_LOW>;
+};
+
+&hsusb2_phy {
+ reset-gpios = <&twl_gpio 7 GPIO_ACTIVE_LOW>;
+};
+
+&usb_otg_hs {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsusb0_pins>;
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ phys = <&usb2_phy>;
+ phy-names = "usb2-phy";
+ mode = <3>;
+ power = <50>;
+};
diff --git a/arch/arm/boot/dts/omap3-devkit8000.dts b/arch/arm/boot/dts/omap3-devkit8000.dts
new file mode 100644
index 000000000..921de6605
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-devkit8000.dts
@@ -0,0 +1,159 @@
+/*
+ * Author: Anil Kumar <anilk4.v@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.
+ */
+/dts-v1/;
+
+#include "omap34xx.dtsi"
+/ {
+ model = "TimLL OMAP3 Devkit8000";
+ compatible = "timll,omap3-devkit8000", "ti,omap3";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ heartbeat {
+ label = "devkit8000::led1";
+ gpios = <&gpio6 26 GPIO_ACTIVE_HIGH>; /* 186 -> LED1 */
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+
+ mmc {
+ label = "devkit8000::led2";
+ gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>; /* 163 -> LED2 */
+ default-state = "on";
+ linux,default-trigger = "none";
+ };
+
+ usr {
+ label = "devkit8000::led3";
+ gpios = <&gpio6 4 GPIO_ACTIVE_HIGH>; /* 164 -> LED3 */
+ default-state = "on";
+ linux,default-trigger = "usr";
+ };
+
+ };
+
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "devkit8000";
+
+ ti,mcbsp = <&mcbsp2>;
+ ti,audio-routing =
+ "Ext Spk", "PREDRIVEL",
+ "Ext Spk", "PREDRIVER",
+ "MAINMIC", "Main Mic",
+ "Main Mic", "Mic Bias 1";
+ };
+};
+
+&i2c1 {
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ codec {
+ };
+ };
+ };
+};
+
+&i2c2 {
+ status = "disabled";
+};
+
+&i2c3 {
+ status = "disabled";
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&mmc1 {
+ vmmc-supply = <&vmmc1>;
+ vmmc_aux-supply = <&vsim>;
+ bus-width = <8>;
+};
+
+&mmc2 {
+ status = "disabled";
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&wdt2 {
+ status = "disabled";
+};
+
+&mcbsp2 {
+ status = "okay";
+};
+
+&gpmc {
+ ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */
+
+ nand@0,0 {
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ nand-bus-width = <16>;
+ gpmc,device-width = <2>;
+ ti,nand-ecc-opt = "sw";
+
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <44>;
+ gpmc,cs-wr-off-ns = <44>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <34>;
+ gpmc,adv-wr-off-ns = <44>;
+ gpmc,we-off-ns = <40>;
+ gpmc,oe-off-ns = <54>;
+ gpmc,access-ns = <64>;
+ gpmc,rd-cycle-ns = <82>;
+ gpmc,wr-cycle-ns = <82>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ x-loader@0 {
+ label = "X-Loader";
+ reg = <0 0x80000>;
+ };
+
+ bootloaders@80000 {
+ label = "U-Boot";
+ reg = <0x80000 0x1e0000>;
+ };
+
+ bootloaders_env@260000 {
+ label = "U-Boot Env";
+ reg = <0x260000 0x20000>;
+ };
+
+ kernel@280000 {
+ label = "Kernel";
+ reg = <0x280000 0x400000>;
+ };
+
+ filesystem@680000 {
+ label = "File System";
+ reg = <0x680000 0xf980000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-evm-37xx.dts b/arch/arm/boot/dts/omap3-evm-37xx.dts
new file mode 100644
index 000000000..16e8ce350
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-evm-37xx.dts
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+/dts-v1/;
+
+#include "omap36xx.dtsi"
+#include "omap3-evm-common.dtsi"
+
+
+/ {
+ model = "TI OMAP37XX EVM (TMDSEVM3730)";
+ compatible = "ti,omap3-evm-37xx", "ti,omap36xx";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ wl12xx_vmmc: wl12xx_vmmc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wl12xx_gpio>;
+ };
+};
+
+&dss {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &dss_dpi_pins1
+ &dss_dpi_pins2
+ >;
+};
+
+&omap3_pmx_core {
+ dss_dpi_pins1: pinmux_dss_dpi_pins2 {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */
+ OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */
+ OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */
+ OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */
+
+ OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */
+ OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */
+ OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */
+ OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */
+ OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */
+ OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */
+ OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */
+ OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */
+ OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */
+ OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */
+ OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */
+ OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */
+
+ OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE3) /* dss_data18.dss_data0 */
+ OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE3) /* dss_data19.dss_data1 */
+ OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE3) /* dss_data20.dss_data2 */
+ OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE3) /* dss_data21.dss_data3 */
+ OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE3) /* dss_data22.dss_data4 */
+ OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE3) /* dss_data23.dss_data5 */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ 0x114 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */
+ 0x116 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */
+ 0x118 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */
+ 0x11a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */
+ 0x11c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */
+ 0x11e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
+ 0x120 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat4.sdmmc1_dat4 */
+ 0x122 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat5.sdmmc1_dat5 */
+ 0x124 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat6.sdmmc1_dat6 */
+ 0x126 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat7.sdmmc1_dat7 */
+ >;
+ };
+
+ /* NOTE: Clocked externally, needs INPUT also for sdmmc2_clk.sdmmc2_clk */
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ 0x128 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
+ 0x12a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
+ 0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
+ 0x12e (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+ 0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
+ 0x132 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ 0x16e (WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+ 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */
+ >;
+ };
+
+ wl12xx_gpio: pinmux_wl12xx_gpio {
+ pinctrl-single,pins = <
+ 0x150 (PIN_OUTPUT | MUX_MODE4) /* uart1_cts.gpio_150 */
+ 0x14e (PIN_INPUT | MUX_MODE4) /* uart1_rts.gpio_149 */
+ >;
+ };
+
+ smsc911x_pins: pinmux_smsc911x_pins {
+ pinctrl-single,pins = <
+ 0x1a2 (PIN_INPUT | MUX_MODE4) /* mcspi1_cs2.gpio_176 */
+ >;
+ };
+};
+
+&omap3_pmx_wkup {
+ dss_dpi_pins2: pinmux_dss_dpi_pins1 {
+ pinctrl-single,pins = <
+ 0x0a (PIN_OUTPUT | MUX_MODE3) /* sys_boot0.dss_data18 */
+ 0x0c (PIN_OUTPUT | MUX_MODE3) /* sys_boot1.dss_data19 */
+ 0x10 (PIN_OUTPUT | MUX_MODE3) /* sys_boot3.dss_data20 */
+ 0x12 (PIN_OUTPUT | MUX_MODE3) /* sys_boot4.dss_data21 */
+ 0x14 (PIN_OUTPUT | MUX_MODE3) /* sys_boot5.dss_data22 */
+ 0x16 (PIN_OUTPUT | MUX_MODE3) /* sys_boot6.dss_data23 */
+ >;
+ };
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&uart1 {
+ interrupts-extended = <&intc 72 &omap3_pmx_core OMAP3_UART1_RX>;
+};
+
+&uart2 {
+ interrupts-extended = <&intc 73 &omap3_pmx_core OMAP3_UART2_RX>;
+};
+
+&uart3 {
+ interrupts-extended = <&intc 74 &omap3_pmx_core OMAP3_UART3_RX>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+};
+
+&gpmc {
+ ranges = <0 0 0x00000000 0x1000000>, /* CS0: 16MB for NAND */
+ <5 0 0x2c000000 0x01000000>;
+
+ nand@0,0 {
+ linux,mtd-name= "hynix,h8kds0un0mer-4em";
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ nand-bus-width = <16>;
+ gpmc,device-width = <2>;
+ ti,nand-ecc-opt = "bch8";
+
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <44>;
+ gpmc,cs-wr-off-ns = <44>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <34>;
+ gpmc,adv-wr-off-ns = <44>;
+ gpmc,we-off-ns = <40>;
+ gpmc,oe-off-ns = <54>;
+ gpmc,access-ns = <64>;
+ gpmc,rd-cycle-ns = <82>;
+ gpmc,wr-cycle-ns = <82>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "X-Loader";
+ reg = <0 0x80000>;
+ };
+ partition@0x80000 {
+ label = "U-Boot";
+ reg = <0x80000 0x1c0000>;
+ };
+ partition@0x1c0000 {
+ label = "Environment";
+ reg = <0x240000 0x40000>;
+ };
+ partition@0x280000 {
+ label = "Kernel";
+ reg = <0x280000 0x500000>;
+ };
+ partition@0x780000 {
+ label = "Filesystem";
+ reg = <0x780000 0x1f880000>;
+ };
+ };
+
+ ethernet@gpmc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&smsc911x_pins>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-evm-common.dtsi b/arch/arm/boot/dts/omap3-evm-common.dtsi
new file mode 100644
index 000000000..346552b94
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-evm-common.dtsi
@@ -0,0 +1,160 @@
+/*
+ * Common support for omap3 EVM boards
+ */
+
+#include <dt-bindings/input/input.h>
+#include "omap-gpmc-smsc911x.dtsi"
+
+/ {
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vcc>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ ledb {
+ label = "omap3evm::ledb";
+ gpios = <&twl_gpio 19 GPIO_ACTIVE_HIGH>; /* LEDB */
+ linux,default-trigger = "default-on";
+ };
+ };
+
+ wl12xx_vmmc: wl12xx_vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "vwl1271";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio5 22 0>; /* gpio150 */
+ startup-delay-us = <70000>;
+ enable-active-high;
+ vin-supply = <&vmmc2>;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+ };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+#include "omap3-panel-sharp-ls037v7dw01.dtsi"
+
+&backlight0 {
+ gpios = <&twl_gpio 18 GPIO_ACTIVE_LOW>;
+};
+
+&twl {
+ twl_power: power {
+ compatible = "ti,twl4030-power-omap3-evm", "ti,twl4030-power-idle";
+ ti,use_poweroff;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+
+ /*
+ * TVP5146 Video decoder-in for analog input support.
+ */
+ tvp5146@5c {
+ compatible = "ti,tvp5146m2";
+ reg = <0x5c>;
+ };
+};
+
+&lcd_3v3 {
+ gpio = <&gpio5 25 GPIO_ACTIVE_LOW>; /* gpio153 */
+ enable-active-low;
+};
+
+&lcd0 {
+ enable-gpios = <&gpio5 24 GPIO_ACTIVE_HIGH>; /* gpio152, lcd INI */
+ reset-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>; /* gpio155, lcd RESB */
+ mode-gpios = <&gpio5 26 GPIO_ACTIVE_HIGH /* gpio154, lcd MO */
+ &gpio1 2 GPIO_ACTIVE_HIGH /* gpio2, lcd LR */
+ &gpio1 3 GPIO_ACTIVE_HIGH>; /* gpio3, lcd UD */
+};
+
+&mcspi1 {
+ tsc2046@0 {
+ interrupt-parent = <&gpio6>;
+ interrupts = <15 0>; /* gpio175 */
+ pendown-gpio = <&gpio6 15 0>;
+ };
+};
+
+&mmc1 {
+ vmmc-supply = <&vmmc1>;
+ vmmc_aux-supply = <&vsim>;
+ bus-width = <8>;
+};
+
+&mmc2 {
+ vmmc-supply = <&wl12xx_vmmc>;
+ non-removable;
+ bus-width = <4>;
+ cap-power-off-card;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1271";
+ reg = <2>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <21 IRQ_TYPE_LEVEL_HIGH>; /* gpio 149 */
+ ref-clock-frequency = <38400000>;
+ };
+};
+
+&twl_gpio {
+ ti,use-leds;
+};
+
+&twl_keypad {
+ linux,keymap = <
+ MATRIX_KEY(2, 2, KEY_1)
+ MATRIX_KEY(1, 1, KEY_2)
+ MATRIX_KEY(0, 0, KEY_3)
+ MATRIX_KEY(3, 2, KEY_4)
+ MATRIX_KEY(2, 1, KEY_5)
+ MATRIX_KEY(1, 0, KEY_6)
+ MATRIX_KEY(1, 3, KEY_7)
+ MATRIX_KEY(3, 1, KEY_8)
+ MATRIX_KEY(2, 0, KEY_9)
+ MATRIX_KEY(2, 3, KEY_KPASTERISK)
+ MATRIX_KEY(0, 2, KEY_0)
+ MATRIX_KEY(3, 0, KEY_KPDOT)
+ /* s4 not wired */
+ MATRIX_KEY(1, 2, KEY_BACKSPACE)
+ MATRIX_KEY(0, 1, KEY_ENTER)
+ >;
+};
+
+&usb_otg_hs {
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ phys = <&usb2_phy>;
+ phy-names = "usb2-phy";
+ mode = <3>;
+ power = <50>;
+};
+
+&gpmc {
+ ethernet@gpmc {
+ interrupt-parent = <&gpio6>;
+ interrupts = <16 8>;
+ reg = <5 0 0xff>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-evm.dts b/arch/arm/boot/dts/omap3-evm.dts
new file mode 100644
index 000000000..e10dcd0fa
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-evm.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+/dts-v1/;
+
+#include "omap34xx.dtsi"
+#include "omap3-evm-common.dtsi"
+
+/ {
+ model = "TI OMAP35XX EVM (TMDSEVM3530)";
+ compatible = "ti,omap3-evm", "ti,omap3";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi
new file mode 100644
index 000000000..b9f68817b
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-gta04.dtsi
@@ -0,0 +1,519 @@
+/*
+ * Copyright (C) 2013 Marek Belisko <marek@goldelico.com>
+ *
+ * Based on omap3-beagle-xm.dts
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "omap36xx.dtsi"
+
+/ {
+ model = "OMAP3 GTA04";
+ compatible = "ti,omap3-gta04", "ti,omap36xx", "ti,omap3";
+
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vcc>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>; /* 512 MB */
+ };
+
+ aliases {
+ display0 = &lcd;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ aux-button {
+ label = "aux";
+ linux,code = <169>;
+ gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ gpio-key,wakeup;
+ };
+ };
+
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "gta04";
+
+ ti,mcbsp = <&mcbsp2>;
+ };
+
+ spi_lcd {
+ compatible = "spi-gpio";
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_gpio_pins>;
+
+ gpio-sck = <&gpio1 12 0>;
+ gpio-miso = <&gpio1 18 0>;
+ gpio-mosi = <&gpio1 20 0>;
+ cs-gpios = <&gpio1 19 0>;
+ num-chipselects = <1>;
+
+ /* lcd panel */
+ lcd: td028ttec1@0 {
+ compatible = "toppoly,td028ttec1";
+ reg = <0>;
+ spi-max-frequency = <100000>;
+ spi-cpol;
+ spi-cpha;
+
+ label = "lcd";
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+ };
+ };
+
+ hsusb2_phy: hsusb2_phy {
+ compatible = "usb-nop-xceiv";
+ reset-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>;
+ };
+
+ tv0: connector@1 {
+ compatible = "svideo-connector";
+ label = "tv";
+
+ port {
+ tv_connector_in: endpoint {
+ remote-endpoint = <&opa_out>;
+ };
+ };
+ };
+
+ tv_amp: opa362 {
+ compatible = "ti,opa362";
+ enable-gpios = <&gpio1 23 0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ opa_in: endpoint@0 {
+ remote-endpoint = <&venc_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ opa_out: endpoint@0 {
+ remote-endpoint = <&tv_connector_in>;
+ };
+ };
+ };
+ };
+};
+
+&omap3_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusb2_pins
+ >;
+
+ hsusb2_pins: pinmux_hsusb2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21d4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */
+ OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */
+ OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */
+ OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */
+ OMAP3_CORE1_IOPAD(0x21dc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */
+ OMAP3_CORE1_IOPAD(0x21de, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */
+ >;
+ };
+
+ uart1_pins: pinmux_uart1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2182, PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */
+ OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE0) /* uart1_tx.uart1_tx */
+ >;
+ };
+
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */
+ OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0) /* uart3_rx.uart3_rx */
+ OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0) /* uart3_tx.uart3_tx */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */
+ OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */
+ OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */
+ OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */
+ OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */
+ OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
+ >;
+ };
+
+ dss_dpi_pins: pinmux_dss_dpi_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */
+ OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */
+ OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */
+ OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */
+ OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE0) /* dss_data0.dss_data0 */
+ OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT | MUX_MODE0) /* dss_data1.dss_data1 */
+ OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT | MUX_MODE0) /* dss_data2.dss_data2 */
+ OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE0) /* dss_data3.dss_data3 */
+ OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE0) /* dss_data4.dss_data4 */
+ OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE0) /* dss_data5.dss_data5 */
+ OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */
+ OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */
+ OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */
+ OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */
+ OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */
+ OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */
+ OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */
+ OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */
+ OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */
+ OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */
+ OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */
+ OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */
+ OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE0) /* dss_data18.dss_data18 */
+ OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE0) /* dss_data19.dss_data19 */
+ OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE0) /* dss_data20.dss_data20 */
+ OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE0) /* dss_data21.dss_data21 */
+ OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE0) /* dss_data22.dss_data22 */
+ OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */
+ >;
+ };
+};
+
+&omap3_pmx_core2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusb2_2_pins
+ >;
+
+ hsusb2_2_pins: pinmux_hsusb2_2_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */
+ OMAP3630_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */
+ OMAP3630_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */
+ OMAP3630_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */
+ OMAP3630_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */
+ OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */
+ >;
+ };
+
+ spi_gpio_pins: spi_gpio_pinmux {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25d8, PIN_OUTPUT | MUX_MODE4) /* clk */
+ OMAP3630_CORE2_IOPAD(0x25e6, PIN_OUTPUT | MUX_MODE4) /* cs */
+ OMAP3630_CORE2_IOPAD(0x25e8, PIN_OUTPUT | MUX_MODE4) /* tx */
+ OMAP3630_CORE2_IOPAD(0x25e4, PIN_INPUT | MUX_MODE4) /* rx */
+ >;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ ti,enable-vibra = <1>;
+ codec {
+ ti,ramp_delay_value = <3>;
+ };
+ };
+
+ twl_power: power {
+ compatible = "ti,twl4030-power";
+ ti,use_poweroff;
+ };
+ };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&i2c2 {
+ clock-frequency = <400000>;
+
+ /* pressure sensor */
+ bmp085@77 {
+ compatible = "bosch,bmp085";
+ reg = <0x77>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <17 IRQ_TYPE_EDGE_RISING>; /* GPIO_113 */
+ };
+
+ /* accelerometer */
+ bma180@41 {
+ compatible = "bosch,bma180";
+ reg = <0x41>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <19 IRQ_TYPE_LEVEL_HIGH>; /* GPIO_115 */
+ };
+
+ /* gyroscope */
+ itg3200@68 {
+ compatible = "invensense,itg3200";
+ reg = <0x68>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <24 0>; /* GPIO_56 */
+ };
+
+ /* leds */
+ tca6507@45 {
+ compatible = "ti,tca6507";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x45>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gta04_led0: red_aux@0 {
+ label = "gta04:red:aux";
+ reg = <0x0>;
+ };
+
+ gta04_led1: green_aux@1 {
+ label = "gta04:green:aux";
+ reg = <0x1>;
+ };
+
+ gta04_led3: red_power@3 {
+ label = "gta04:red:power";
+ reg = <0x3>;
+ linux,default-trigger = "default-on";
+ };
+
+ gta04_led4: green_power@4 {
+ label = "gta04:green:power";
+ reg = <0x4>;
+ };
+
+ wifi_reset: wifi_reset@6 {
+ reg = <0x6>;
+ compatible = "gpio";
+ };
+ };
+
+ /* compass aka magnetometer */
+ hmc5843@1e {
+ compatible = "honeywell,hmc5883l";
+ reg = <0x1e>;
+ };
+
+ /* touchscreen */
+ tsc2007@48 {
+ compatible = "ti,tsc2007";
+ reg = <0x48>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <0 IRQ_TYPE_EDGE_FALLING>; /* GPIO_160 */
+ gpios = <&gpio6 0 GPIO_ACTIVE_LOW>;
+ ti,x-plate-ohms = <600>;
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+};
+
+&usb_otg_hs {
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ phys = <&usb2_phy>;
+ phy-names = "usb2-phy";
+ mode = <3>;
+ power = <50>;
+};
+
+&usbhshost {
+ port2-mode = "ehci-phy";
+};
+
+&usbhsehci {
+ phys = <0 &hsusb2_phy>;
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&vmmc1>;
+ bus-width = <4>;
+ ti,non-removable;
+};
+
+&mmc2 {
+ vmmc-supply = <&vaux4>;
+ bus-width = <4>;
+ ti,non-removable;
+ cap-power-off-card;
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&twl_keypad {
+ status = "disabled";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+};
+
+&charger {
+ ti,bb-uvolt = <3200000>;
+ ti,bb-uamp = <150>;
+};
+
+/* spare */
+&vaux1 {
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3000000>;
+};
+
+/* sensors */
+&vaux2 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+};
+
+/* camera */
+&vaux3 {
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+};
+
+/* WLAN/BT */
+&vaux4 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3150000>;
+};
+
+/* GPS LNA */
+&vsim {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3150000>;
+};
+
+&dss {
+ pinctrl-names = "default";
+ pinctrl-0 = < &dss_dpi_pins >;
+
+ status = "okay";
+ vdds_dsi-supply = <&vpll2>;
+
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+&venc {
+ status = "okay";
+
+ vdda-supply = <&vdac>;
+
+ port {
+ venc_out: endpoint {
+ remote-endpoint = <&opa_in>;
+ ti,channels = <2>;
+ ti,invert-polarity;
+ };
+ };
+};
+
+&gpmc {
+ ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */
+
+ nand@0,0 {
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ nand-bus-width = <16>;
+ ti,nand-ecc-opt = "bch8";
+
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <44>;
+ gpmc,cs-wr-off-ns = <44>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <34>;
+ gpmc,adv-wr-off-ns = <44>;
+ gpmc,we-off-ns = <40>;
+ gpmc,oe-off-ns = <54>;
+ gpmc,access-ns = <64>;
+ gpmc,rd-cycle-ns = <82>;
+ gpmc,wr-cycle-ns = <82>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+ gpmc,device-width = <2>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ x-loader@0 {
+ label = "X-Loader";
+ reg = <0 0x80000>;
+ };
+
+ bootloaders@80000 {
+ label = "U-Boot";
+ reg = <0x80000 0x1e0000>;
+ };
+
+ bootloaders_env@260000 {
+ label = "U-Boot Env";
+ reg = <0x260000 0x20000>;
+ };
+
+ kernel@280000 {
+ label = "Kernel";
+ reg = <0x280000 0x400000>;
+ };
+
+ filesystem@680000 {
+ label = "File System";
+ reg = <0x680000 0xf980000>;
+ };
+ };
+};
+
+&mcbsp2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/omap3-gta04a3.dts b/arch/arm/boot/dts/omap3-gta04a3.dts
new file mode 100644
index 000000000..3099a892c
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-gta04a3.dts
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014 H. Nikolaus Schaller <hns@goldelico.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 "omap3-gta04.dtsi"
+
+/ {
+ model = "Goldelico GTA04A3";
+};
+
+&i2c2 {
+
+ /* alternate accelerometer that might be installed on some GTA04A3 boards */
+ lis302@1d {
+ compatible = "st,lis331dlh", "st,lis3lv02d";
+ reg = <0x1d>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <18 (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)>;
+ Vdd-supply = <&vaux2>;
+ Vdd_IO-supply = <&vaux2>;
+
+ st,click-single-x;
+ st,click-single-y;
+ st,click-single-z;
+ st,click-thresh-x = <8>;
+ st,click-thresh-y = <8>;
+ st,click-thresh-z = <10>;
+ st,click-click-time-limit = <9>;
+ st,click-latency = <50>;
+ st,irq1-click;
+ st,wakeup-x-lo;
+ st,wakeup-x-hi;
+ st,wakeup-y-lo;
+ st,wakeup-y-hi;
+ st,wakeup-z-lo;
+ st,wakeup-z-hi;
+ st,min-limit-x = <32>;
+ st,min-limit-y = <3>;
+ st,min-limit-z = <3>;
+ st,max-limit-x = <3>;
+ st,max-limit-y = <32>;
+ st,max-limit-z = <32>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-gta04a4.dts b/arch/arm/boot/dts/omap3-gta04a4.dts
new file mode 100644
index 000000000..c918bb1f0
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-gta04a4.dts
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2014 Marek Belisko <marek@goldelico.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 "omap3-gta04.dtsi"
+
+/ {
+ model = "Goldelico GTA04A4";
+};
diff --git a/arch/arm/boot/dts/omap3-gta04a5.dts b/arch/arm/boot/dts/omap3-gta04a5.dts
new file mode 100644
index 000000000..52b386f68
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-gta04a5.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2014 H. Nikolaus Schaller <hns@goldelico.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 "omap3-gta04.dtsi"
+
+/ {
+ model = "Goldelico GTA04A5";
+
+ sound {
+ ti,jack-det-gpio = <&twl_gpio 2 0>; /* GTA04A5 only */
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-ha-common.dtsi b/arch/arm/boot/dts/omap3-ha-common.dtsi
new file mode 100644
index 000000000..bd66545ef
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-ha-common.dtsi
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2014 Stefan Roese <sr@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 "omap3-tao3530.dtsi"
+
+/ {
+ gpio_poweroff {
+ pinctrl-names = "default";
+ pinctrl-0 = <&poweroff_pins>;
+
+ compatible = "gpio-poweroff";
+ gpios = <&gpio6 8 GPIO_ACTIVE_LOW>; /* GPIO 168 */
+ };
+};
+
+&omap3_pmx_core {
+ sound2_pins: pinmux_sound2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x209e, PIN_OUTPUT | MUX_MODE4) /* gpmc_d8 gpio_44 */
+ >;
+ };
+
+ led_blue_pins: pinmux_led_blue_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2110, PIN_OUTPUT | MUX_MODE4) /* cam_xclka gpio_96, LED blue */
+ >;
+ };
+
+ led_green_pins: pinmux_led_green_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2126, PIN_OUTPUT | MUX_MODE4) /* cam_d8 gpio_107, LED green */
+ >;
+ };
+
+ led_red_pins: pinmux_led_red_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x212e, PIN_OUTPUT_PULLUP | MUX_MODE4) /* cam_xclkb gpio_111, LED red */
+ >;
+ };
+
+ poweroff_pins: pinmux_poweroff_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21be, PIN_OUTPUT_PULLUP | MUX_MODE4) /* i2c2_scl gpio_168 */
+ >;
+ };
+
+ powerdown_input_pins: pinmux_powerdown_input_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21c0, PIN_INPUT_PULLUP | MUX_MODE4) /* i2c2_sda gpio_183 */
+ >;
+ };
+
+ fpga_boot0_pins: fpga_boot0_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x211a, PIN_INPUT | MUX_MODE4) /* cam_d2 gpio_101 */
+ OMAP3_CORE1_IOPAD(0x211c, PIN_OUTPUT | MUX_MODE4) /* cam_d3 gpio_102 */
+ OMAP3_CORE1_IOPAD(0x211e, PIN_OUTPUT | MUX_MODE4) /* cam_d4 gpio_103 */
+ OMAP3_CORE1_IOPAD(0x2120, PIN_INPUT_PULLUP | MUX_MODE4) /* cam_d5 gpio_104 */
+ >;
+ };
+
+ fpga_boot1_pins: fpga_boot1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20a2, PIN_INPUT | MUX_MODE4) /* gpmc_d10 gpio_46 */
+ OMAP3_CORE1_IOPAD(0x20a4, PIN_OUTPUT | MUX_MODE4) /* gpmc_d11 gpio_47 */
+ OMAP3_CORE1_IOPAD(0x20a6, PIN_OUTPUT | MUX_MODE4) /* gpmc_d12 gpio_48 */
+ OMAP3_CORE1_IOPAD(0x20a8, PIN_INPUT_PULLUP | MUX_MODE4) /* gpmc_d13 gpio_49 */
+ >;
+ };
+};
+
+/* I2C2: mux'ed with GPIO168 which is connected to nKILL_POWER */
+&i2c2 {
+ status = "disabled";
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+};
diff --git a/arch/arm/boot/dts/omap3-ha-lcd.dts b/arch/arm/boot/dts/omap3-ha-lcd.dts
new file mode 100644
index 000000000..11aa28d73
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-ha-lcd.dts
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2014 Stefan Roese <sr@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 "omap3-ha-common.dtsi"
+
+/ {
+ model = "TI OMAP3 HEAD acoustics LCD-baseboard with TAO3530 SOM";
+ compatible = "headacoustics,omap3-ha-lcd", "technexion,omap3-tao3530", "ti,omap34xx", "ti,omap3";
+};
+
+&omap3_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusbb2_pins
+ &powerdown_input_pins
+ &fpga_boot0_pins
+ &fpga_boot1_pins
+ &led_blue_pins
+ &led_green_pins
+ &led_red_pins
+ &touchscreen_wake_pins
+ >;
+
+ touchscreen_irq_pins: pinmux_touchscreen_irq_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2164, PIN_INPUT_PULLUP | MUX_MODE4) /* gpio_136, Touchscreen IRQ */
+ >;
+ };
+
+ touchscreen_wake_pins: pinmux_touchscreen_wake_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x212c, PIN_OUTPUT_PULLUP | MUX_MODE4) /* gpio_110, Touchscreen Wake */
+ >;
+ };
+
+ dss_dpi_pins: pinmux_dss_dpi_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */
+ OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */
+ OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */
+ OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */
+ OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE0) /* dss_data0.dss_data0 */
+ OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT | MUX_MODE0) /* dss_data1.dss_data1 */
+ OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT | MUX_MODE0) /* dss_data2.dss_data2 */
+ OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE0) /* dss_data3.dss_data3 */
+ OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE0) /* dss_data4.dss_data4 */
+ OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE0) /* dss_data5.dss_data5 */
+ OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */
+ OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */
+ OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */
+ OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */
+ OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */
+ OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */
+ OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */
+ OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */
+ OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */
+ OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */
+ OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */
+ OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */
+ OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE0) /* dss_data18.dss_data18 */
+ OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE0) /* dss_data19.dss_data19 */
+ OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE0) /* dss_data20.dss_data20 */
+ OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE0) /* dss_data21.dss_data21 */
+ OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE0) /* dss_data22.dss_data22 */
+ OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */
+ >;
+ };
+
+ lte430_pins: pinmux_lte430_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2168, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat6.gpio_138 */
+ >;
+ };
+
+ backlight_pins: pinmux_backlight_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x216a, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat7.gpio_139 */
+ >;
+ };
+};
+
+/* I2C2: mux'ed with GPIO168 which is connected to nKILL_POWER */
+&i2c2 {
+ status = "disabled";
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+};
+
+/* Needed to power the DPI pins */
+&vpll2 {
+ regulator-always-on;
+};
+
+&dss {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_dpi_pins>;
+
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+/ {
+ aliases {
+ display0 = &lcd0;
+ };
+
+ lcd0: display@0 {
+ compatible = "panel-dpi";
+ label = "lcd";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&lte430_pins>;
+ enable-gpios = <&gpio5 10 GPIO_ACTIVE_LOW>; /* gpio_138 */
+
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+
+ panel-timing {
+ clock-frequency = <31250000>;
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <40>;
+ hback-porch = <86>;
+ hsync-len = <1>;
+ vback-porch = <30>;
+ vfront-porch = <13>;
+ vsync-len = <3>;
+
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+
+ backlight {
+ compatible = "gpio-backlight";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&backlight_pins>;
+ gpios = <&gpio5 11 GPIO_ACTIVE_HIGH>; /* gpio_139 */
+
+ default-on;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-ha.dts b/arch/arm/boot/dts/omap3-ha.dts
new file mode 100644
index 000000000..fde325688
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-ha.dts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2014 Stefan Roese <sr@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 "omap3-ha-common.dtsi"
+
+/ {
+ model = "TI OMAP3 HEAD acoustics baseboard with TAO3530 SOM";
+ compatible = "headacoustics,omap3-ha", "technexion,omap3-tao3530", "ti,omap34xx", "ti,omap3";
+};
+
+&omap3_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusbb2_pins
+ &powerdown_input_pins
+ &fpga_boot0_pins
+ &fpga_boot1_pins
+ &led_blue_pins
+ &led_green_pins
+ &led_red_pins
+ >;
+};
diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi
new file mode 100644
index 000000000..d5e5cd449
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-igep.dtsi
@@ -0,0 +1,216 @@
+/*
+ * Common device tree for IGEP boards based on AM/DM37x
+ *
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@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.
+ */
+/dts-v1/;
+
+#include "omap36xx.dtsi"
+
+/ {
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>; /* 512 MB */
+ };
+
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "igep2";
+ ti,mcbsp = <&mcbsp2>;
+ };
+
+ vdd33: regulator-vdd33 {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd33";
+ regulator-always-on;
+ };
+
+};
+
+&omap3_pmx_core {
+ uart1_pins: pinmux_uart1_pins {
+ pinctrl-single,pins = <
+ 0x152 (PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */
+ 0x14c (PIN_OUTPUT |MUX_MODE0) /* uart1_tx.uart1_tx */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ 0x16e (PIN_INPUT | MUX_MODE0) /* uart3_rx.uart3_rx */
+ 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx.uart3_tx */
+ >;
+ };
+
+ mcbsp2_pins: pinmux_mcbsp2_pins {
+ pinctrl-single,pins = <
+ 0x10c (PIN_INPUT | MUX_MODE0) /* mcbsp2_fsx.mcbsp2_fsx */
+ 0x10e (PIN_INPUT | MUX_MODE0) /* mcbsp2_clkx.mcbsp2_clkx */
+ 0x110 (PIN_INPUT | MUX_MODE0) /* mcbsp2_dr.mcbsp2.dr */
+ 0x112 (PIN_OUTPUT | MUX_MODE0) /* mcbsp2_dx.mcbsp2_dx */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ 0x114 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */
+ 0x116 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */
+ 0x118 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */
+ 0x11a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */
+ 0x11c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */
+ 0x11e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
+ >;
+ };
+
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ 0x128 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
+ 0x12a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
+ 0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
+ 0x12e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+ 0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
+ 0x132 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
+ >;
+ };
+
+ smsc9221_pins: pinmux_smsc9221_pins {
+ pinctrl-single,pins = <
+ 0x1a2 (PIN_INPUT | MUX_MODE4) /* mcspi1_cs2.gpio_176 */
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ 0x18a (PIN_INPUT | MUX_MODE0) /* i2c1_scl.i2c1_scl */
+ 0x18c (PIN_INPUT | MUX_MODE0) /* i2c1_sda.i2c1_sda */
+ >;
+ };
+
+ i2c3_pins: pinmux_i2c3_pins {
+ pinctrl-single,pins = <
+ 0x192 (PIN_INPUT | MUX_MODE0) /* i2c3_scl.i2c3_scl */
+ 0x194 (PIN_INPUT | MUX_MODE0) /* i2c3_sda.i2c3_sda */
+ >;
+ };
+};
+
+&gpmc {
+ nand@0,0 {
+ linux,mtd-name= "micron,mt29c4g96maz";
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ nand-bus-width = <16>;
+ gpmc,device-width = <2>;
+ ti,nand-ecc-opt = "bch8";
+
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <44>;
+ gpmc,cs-wr-off-ns = <44>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <34>;
+ gpmc,adv-wr-off-ns = <44>;
+ gpmc,we-off-ns = <40>;
+ gpmc,oe-off-ns = <54>;
+ gpmc,access-ns = <64>;
+ gpmc,rd-cycle-ns = <82>;
+ gpmc,wr-cycle-ns = <82>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "SPL";
+ reg = <0 0x100000>;
+ };
+ partition@80000 {
+ label = "U-Boot";
+ reg = <0x100000 0x180000>;
+ };
+ partition@1c0000 {
+ label = "Environment";
+ reg = <0x280000 0x100000>;
+ };
+ partition@280000 {
+ label = "Kernel";
+ reg = <0x380000 0x300000>;
+ };
+ partition@780000 {
+ label = "Filesystem";
+ reg = <0x680000 0x1f980000>;
+ };
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ codec {
+ };
+ };
+ };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+};
+
+&mcbsp2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcbsp2_pins>;
+ status = "okay";
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&vmmc1>;
+ vmmc_aux-supply = <&vsim>;
+ bus-width = <4>;
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+};
+
+&twl_gpio {
+ ti,use-leds;
+};
+
+&usb_otg_hs {
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ phys = <&usb2_phy>;
+ phy-names = "usb2-phy";
+ mode = <3>;
+ power = <50>;
+};
diff --git a/arch/arm/boot/dts/omap3-igep0020-common.dtsi b/arch/arm/boot/dts/omap3-igep0020-common.dtsi
new file mode 100644
index 000000000..e458c2185
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-igep0020-common.dtsi
@@ -0,0 +1,246 @@
+/*
+ * Common Device Tree Source for IGEPv2
+ *
+ * Copyright (C) 2014 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2014 Enric Balletbo i Serra <eballetbo@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 "omap3-igep.dtsi"
+#include "omap-gpmc-smsc9221.dtsi"
+
+/ {
+
+ leds {
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_pins>;
+ compatible = "gpio-leds";
+
+ boot {
+ label = "omap3:green:boot";
+ gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+
+ user0 {
+ label = "omap3:red:user0";
+ gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ user1 {
+ label = "omap3:red:user1";
+ gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ user2 {
+ label = "omap3:green:user1";
+ gpios = <&twl_gpio 19 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ /* HS USB Port 1 Power */
+ hsusb1_power: hsusb1_power_reg {
+ compatible = "regulator-fixed";
+ regulator-name = "hsusb1_vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&twl_gpio 18 GPIO_ACTIVE_LOW>; /* GPIO LEDA */
+ startup-delay-us = <70000>;
+ };
+
+ /* HS USB Host PHY on PORT 1 */
+ hsusb1_phy: hsusb1_phy {
+ compatible = "usb-nop-xceiv";
+ reset-gpios = <&gpio1 24 GPIO_ACTIVE_LOW>; /* gpio_24 */
+ vcc-supply = <&hsusb1_power>;
+ };
+
+ tfp410: encoder@0 {
+ compatible = "ti,tfp410";
+ powerdown-gpios = <&gpio6 10 GPIO_ACTIVE_LOW>; /* gpio_170 */
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ tfp410_in: endpoint@0 {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ tfp410_out: endpoint@0 {
+ remote-endpoint = <&dvi_connector_in>;
+ };
+ };
+ };
+ };
+
+ dvi0: connector@0 {
+ compatible = "dvi-connector";
+ label = "dvi";
+
+ digital;
+
+ ddc-i2c-bus = <&i2c3>;
+
+ port {
+ dvi_connector_in: endpoint {
+ remote-endpoint = <&tfp410_out>;
+ };
+ };
+ };
+};
+
+&omap3_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &tfp410_pins
+ &dss_dpi_pins
+ >;
+
+ tfp410_pins: pinmux_tfp410_pins {
+ pinctrl-single,pins = <
+ 0x196 (PIN_OUTPUT | MUX_MODE4) /* hdq_sio.gpio_170 */
+ >;
+ };
+
+ dss_dpi_pins: pinmux_dss_dpi_pins {
+ pinctrl-single,pins = <
+ 0x0a4 (PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */
+ 0x0a6 (PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */
+ 0x0a8 (PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */
+ 0x0aa (PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */
+ 0x0ac (PIN_OUTPUT | MUX_MODE0) /* dss_data0.dss_data0 */
+ 0x0ae (PIN_OUTPUT | MUX_MODE0) /* dss_data1.dss_data1 */
+ 0x0b0 (PIN_OUTPUT | MUX_MODE0) /* dss_data2.dss_data2 */
+ 0x0b2 (PIN_OUTPUT | MUX_MODE0) /* dss_data3.dss_data3 */
+ 0x0b4 (PIN_OUTPUT | MUX_MODE0) /* dss_data4.dss_data4 */
+ 0x0b6 (PIN_OUTPUT | MUX_MODE0) /* dss_data5.dss_data5 */
+ 0x0b8 (PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */
+ 0x0ba (PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */
+ 0x0bc (PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */
+ 0x0be (PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */
+ 0x0c0 (PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */
+ 0x0c2 (PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */
+ 0x0c4 (PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */
+ 0x0c6 (PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */
+ 0x0c8 (PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */
+ 0x0ca (PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */
+ 0x0cc (PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */
+ 0x0ce (PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */
+ 0x0d0 (PIN_OUTPUT | MUX_MODE0) /* dss_data18.dss_data18 */
+ 0x0d2 (PIN_OUTPUT | MUX_MODE0) /* dss_data19.dss_data19 */
+ 0x0d4 (PIN_OUTPUT | MUX_MODE0) /* dss_data20.dss_data20 */
+ 0x0d6 (PIN_OUTPUT | MUX_MODE0) /* dss_data21.dss_data21 */
+ 0x0d8 (PIN_OUTPUT | MUX_MODE0) /* dss_data22.dss_data22 */
+ 0x0da (PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */
+ >;
+ };
+
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT | MUX_MODE0) /* uart2_cts.uart2_cts */
+ OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0) /* uart2_rts .uart2_rts*/
+ OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */
+ OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */
+ >;
+ };
+};
+
+&omap3_pmx_core2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusbb1_pins
+ >;
+
+ hsusbb1_pins: pinmux_hsusbb1_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25da, PIN_OUTPUT | MUX_MODE3) /* etk_ctl.hsusb1_clk */
+ OMAP3630_CORE2_IOPAD(0x25d8, PIN_OUTPUT | MUX_MODE3) /* etk_clk.hsusb1_stp */
+ OMAP3630_CORE2_IOPAD(0x25ec, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d8.hsusb1_dir */
+ OMAP3630_CORE2_IOPAD(0x25ee, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d9.hsusb1_nxt */
+ OMAP3630_CORE2_IOPAD(0x25dc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d0.hsusb1_data0 */
+ OMAP3630_CORE2_IOPAD(0x25de, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d1.hsusb1_data1 */
+ OMAP3630_CORE2_IOPAD(0x25e0, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d2.hsusb1_data2 */
+ OMAP3630_CORE2_IOPAD(0x25e2, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d3.hsusb1_data7 */
+ OMAP3630_CORE2_IOPAD(0x25e4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d4.hsusb1_data4 */
+ OMAP3630_CORE2_IOPAD(0x25e6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d5.hsusb1_data5 */
+ OMAP3630_CORE2_IOPAD(0x25e8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d6.hsusb1_data6 */
+ OMAP3630_CORE2_IOPAD(0x25ea, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d7.hsusb1_data3 */
+ >;
+ };
+
+ leds_pins: pinmux_leds_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25f4, PIN_OUTPUT | MUX_MODE4) /* etk_d12.gpio_26 */
+ OMAP3630_CORE2_IOPAD(0x25f6, PIN_OUTPUT | MUX_MODE4) /* etk_d13.gpio_27 */
+ OMAP3630_CORE2_IOPAD(0x25f8, PIN_OUTPUT | MUX_MODE4) /* etk_d14.gpio_28 */
+ >;
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+
+ /*
+ * Display monitor features are burnt in the EEPROM
+ * as EDID data.
+ */
+ eeprom@50 {
+ compatible = "ti,eeprom";
+ reg = <0x50>;
+ };
+};
+
+&gpmc {
+ ranges = <0 0 0x00000000 0x20000000>,
+ <5 0 0x2c000000 0x01000000>;
+
+ ethernet@gpmc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&smsc9221_pins>;
+ reg = <5 0 0xff>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+};
+
+&usbhshost {
+ port1-mode = "ehci-phy";
+};
+
+&usbhsehci {
+ phys = <&hsusb1_phy>;
+};
+
+&vpll2 {
+ /* Needed for DSS */
+ regulator-name = "vdds_dsi";
+};
+
+&dss {
+ status = "ok";
+
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&tfp410_in>;
+ data-lines = <24>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-igep0020-rev-f.dts b/arch/arm/boot/dts/omap3-igep0020-rev-f.dts
new file mode 100644
index 000000000..72f7cdc09
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-igep0020-rev-f.dts
@@ -0,0 +1,54 @@
+/*
+ * Device Tree Source for IGEPv2 Rev. F (TI OMAP AM/DM37x)
+ *
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@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 "omap3-igep0020-common.dtsi"
+
+/ {
+ model = "IGEPv2 Rev. F (TI OMAP AM/DM37x)";
+ compatible = "isee,omap3-igep0020-rev-f", "ti,omap36xx", "ti,omap3";
+
+ /* Regulator to trigger the WL_EN signal of the Wifi module */
+ lbep5clwmc_wlen: regulator-lbep5clwmc-wlen {
+ compatible = "regulator-fixed";
+ regulator-name = "regulator-lbep5clwmc-wlen";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio5 11 GPIO_ACTIVE_HIGH>; /* gpio_139 - WL_EN */
+ enable-active-high;
+ };
+};
+
+&omap3_pmx_core {
+ lbep5clwmc_pins: pinmux_lbep5clwmc_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21d4, PIN_INPUT | MUX_MODE4) /* mcspi1_cs3.gpio_177 - W_IRQ */
+ OMAP3_CORE1_IOPAD(0x2166, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat5.gpio_137 - BT_EN */
+ OMAP3_CORE1_IOPAD(0x216a, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat7.gpio_139 - WL_EN */
+ >;
+ };
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins &lbep5clwmc_pins>;
+ vmmc-supply = <&lbep5clwmc_wlen>;
+ bus-width = <4>;
+ non-removable;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1835";
+ reg = <2>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH>; /* gpio 177 */
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-igep0020.dts b/arch/arm/boot/dts/omap3-igep0020.dts
new file mode 100644
index 000000000..fea7f7edb
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-igep0020.dts
@@ -0,0 +1,67 @@
+/*
+ * Device Tree Source for IGEPv2 Rev. C (TI OMAP AM/DM37x)
+ *
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@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 "omap3-igep0020-common.dtsi"
+
+/ {
+ model = "IGEPv2 Rev. C (TI OMAP AM/DM37x)";
+ compatible = "isee,omap3-igep0020", "ti,omap36xx", "ti,omap3";
+
+ /* Regulator to trigger the WIFI_PDN signal of the Wifi module */
+ lbee1usjyc_pdn: lbee1usjyc_pdn {
+ compatible = "regulator-fixed";
+ regulator-name = "regulator-lbee1usjyc-pdn";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio5 10 GPIO_ACTIVE_HIGH>; /* gpio_138 - WIFI_PDN */
+ startup-delay-us = <10000>;
+ enable-active-high;
+ };
+
+ /* Regulator to trigger the RESET_N_W signal of the Wifi module */
+ lbee1usjyc_reset_n_w: lbee1usjyc_reset_n_w {
+ compatible = "regulator-fixed";
+ regulator-name = "regulator-lbee1usjyc-reset-n-w";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio5 11 GPIO_ACTIVE_HIGH>; /* gpio_139 - RESET_N_W */
+ enable-active-high;
+ };
+};
+
+&omap3_pmx_core {
+ lbee1usjyc_pins: pinmux_lbee1usjyc_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2166, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat5.gpio_137 - RESET_N_W */
+ OMAP3_CORE1_IOPAD(0x2168, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat6.gpio_138 - WIFI_PDN */
+ OMAP3_CORE1_IOPAD(0x216a, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat7.gpio_139 - RST_N_B */
+ >;
+ };
+
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT | MUX_MODE0) /* uart2_cts.uart2_cts */
+ OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0) /* uart2_rts .uart2_rts*/
+ OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */
+ OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */
+ >;
+ };
+};
+
+/* On board Wifi module */
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins &lbee1usjyc_pins>;
+ vmmc-supply = <&lbee1usjyc_pdn>;
+ vmmc_aux-supply = <&lbee1usjyc_reset_n_w>;
+ bus-width = <4>;
+ non-removable;
+};
diff --git a/arch/arm/boot/dts/omap3-igep0030-common.dtsi b/arch/arm/boot/dts/omap3-igep0030-common.dtsi
new file mode 100644
index 000000000..0cb1527c3
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-igep0030-common.dtsi
@@ -0,0 +1,60 @@
+/*
+ * Common Device Tree Source for IGEP COM MODULE
+ *
+ * Copyright (C) 2014 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2014 Enric Balletbo i Serra <eballetbo@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 "omap3-igep.dtsi"
+
+/ {
+ leds: gpio_leds {
+ compatible = "gpio-leds";
+
+ user0 {
+ label = "omap3:red:user0";
+ gpios = <&twl_gpio 18 GPIO_ACTIVE_LOW>; /* LEDA */
+ default-state = "off";
+ };
+
+ user1 {
+ label = "omap3:green:user1";
+ gpios = <&twl_gpio 19 GPIO_ACTIVE_LOW>; /* LEDB */
+ default-state = "off";
+ };
+
+ user2 {
+ label = "omap3:red:user1";
+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; /* gpio_16 */
+ default-state = "off";
+ };
+ };
+};
+
+&omap3_pmx_core {
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x216c, PIN_INPUT | MUX_MODE1) /* mcbsp3_dx.uart2_cts */
+ OMAP3_CORE1_IOPAD(0x216e, PIN_OUTPUT | MUX_MODE1) /* mcbsp3_dr.uart2_rts */
+ OMAP3_CORE1_IOPAD(0x2170, PIN_OUTPUT | MUX_MODE1) /* mcbsp3_clk.uart2_tx */
+ OMAP3_CORE1_IOPAD(0x2172, PIN_INPUT | MUX_MODE1) /* mcbsp3_fsx.uart2_rx */
+ >;
+ };
+};
+
+&omap3_pmx_core2 {
+ leds_core2_pins: pinmux_leds_core2_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25e0, PIN_OUTPUT | MUX_MODE4) /* etk_d2.gpio_16 */
+ >;
+ };
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+};
diff --git a/arch/arm/boot/dts/omap3-igep0030-rev-g.dts b/arch/arm/boot/dts/omap3-igep0030-rev-g.dts
new file mode 100644
index 000000000..b899e3418
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-igep0030-rev-g.dts
@@ -0,0 +1,76 @@
+/*
+ * Device Tree Source for IGEP COM MODULE Rev. G (TI OMAP AM/DM37x)
+ *
+ * Copyright (C) 2014 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2014 Enric Balletbo i Serra <eballetbo@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 "omap3-igep0030-common.dtsi"
+
+/ {
+ model = "IGEP COM MODULE Rev. G (TI OMAP AM/DM37x)";
+ compatible = "isee,omap3-igep0030-rev-g", "ti,omap36xx", "ti,omap3";
+
+ /* Regulator to trigger the WL_EN signal of the Wifi module */
+ lbep5clwmc_wlen: regulator-lbep5clwmc-wlen {
+ compatible = "regulator-fixed";
+ regulator-name = "regulator-lbep5clwmc-wlen";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio5 11 GPIO_ACTIVE_HIGH>; /* gpio_139 - WL_EN */
+ enable-active-high;
+ };
+};
+
+&omap3_pmx_core {
+ lbep5clwmc_pins: pinmux_lbep5clwmc_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2164, PIN_INPUT | MUX_MODE4) /* sdmmc2_dat4.gpio_136 - W_IRQ */
+ OMAP3_CORE1_IOPAD(0x2166, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat5.gpio_137 - BT_EN */
+ OMAP3_CORE1_IOPAD(0x216a, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat7.gpio_139 - WL_EN */
+ >;
+ };
+
+ leds_pins: pinmux_leds_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21be, PIN_OUTPUT | MUX_MODE4) /* i2c2_scl.gpio_168 */
+ >;
+ };
+
+};
+
+&i2c2 {
+ status = "disabled";
+};
+
+&leds {
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_pins &leds_core2_pins>;
+
+ boot {
+ label = "omap3:green:boot";
+ gpios = <&gpio6 8 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins &lbep5clwmc_pins>;
+ vmmc-supply = <&lbep5clwmc_wlen>;
+ bus-width = <4>;
+ non-removable;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1835";
+ reg = <2>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; /* gpio 136 */
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-igep0030.dts b/arch/arm/boot/dts/omap3-igep0030.dts
new file mode 100644
index 000000000..8150f47cc
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-igep0030.dts
@@ -0,0 +1,70 @@
+/*
+ * Device Tree Source for IGEP COM MODULE Rev. E (TI OMAP AM/DM37x)
+ *
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@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 "omap3-igep0030-common.dtsi"
+
+/ {
+ model = "IGEP COM MODULE Rev. E (TI OMAP AM/DM37x)";
+ compatible = "isee,omap3-igep0030", "ti,omap36xx", "ti,omap3";
+
+ /* Regulator to trigger the WIFI_PDN signal of the Wifi module */
+ lbee1usjyc_pdn: lbee1usjyc_pdn {
+ compatible = "regulator-fixed";
+ regulator-name = "regulator-lbee1usjyc-pdn";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio5 10 GPIO_ACTIVE_HIGH>; /* gpio_138 - WIFI_PDN */
+ startup-delay-us = <10000>;
+ enable-active-high;
+ };
+
+ /* Regulator to trigger the RESET_N_W signal of the Wifi module */
+ lbee1usjyc_reset_n_w: lbee1usjyc_reset_n_w {
+ compatible = "regulator-fixed";
+ regulator-name = "regulator-lbee1usjyc-reset-n-w";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio5 11 GPIO_ACTIVE_HIGH>; /* gpio_139 - RESET_N_W */
+ enable-active-high;
+ };
+};
+
+&omap3_pmx_core {
+ lbee1usjyc_pins: pinmux_lbee1usjyc_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2166, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat5.gpio_137 - RESET_N_W */
+ OMAP3_CORE1_IOPAD(0x2168, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat6.gpio_138 - WIFI_PDN */
+ OMAP3_CORE1_IOPAD(0x216a, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat7.gpio_139 - RST_N_B */
+ >;
+ };
+};
+
+&leds {
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_core2_pins>;
+
+ boot {
+ label = "omap3:green:boot";
+ gpios = <&twl_gpio 13 GPIO_ACTIVE_LOW>; /* LEDSYNC */
+ default-state = "on";
+ };
+};
+
+/* On board Wifi module */
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins &lbee1usjyc_pins>;
+ vmmc-supply = <&lbee1usjyc_pdn>;
+ vmmc_aux-supply = <&lbee1usjyc_reset_n_w>;
+ bus-width = <4>;
+ non-removable;
+};
+
diff --git a/arch/arm/boot/dts/omap3-ldp.dts b/arch/arm/boot/dts/omap3-ldp.dts
new file mode 100644
index 000000000..b699bc48f
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-ldp.dts
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "omap34xx.dtsi"
+#include "omap-gpmc-smsc911x.dtsi"
+
+/ {
+ model = "TI OMAP3430 LDP (Zoom1 Labrador)";
+ compatible = "ti,omap3-ldp", "ti,omap3";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x8000000>; /* 128 MB */
+ };
+
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vcc>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_key_pins>;
+
+ key_enter {
+ label = "enter";
+ gpios = <&gpio4 5 GPIO_ACTIVE_LOW>; /* gpio101 */
+ linux,code = <0x0107001c>; /* KEY_ENTER */
+ gpio-key,wakeup;
+ };
+
+ key_f1 {
+ label = "f1";
+ gpios = <&gpio4 6 GPIO_ACTIVE_LOW>; /* gpio102 */
+ linux,code = <0x0303003b>; /* KEY_F1 */
+ gpio-key,wakeup;
+ };
+
+ key_f2 {
+ label = "f2";
+ gpios = <&gpio4 7 GPIO_ACTIVE_LOW>; /* gpio103 */
+ linux,code = <0x0403003c>; /* KEY_F2 */
+ gpio-key,wakeup;
+ };
+
+ key_f3 {
+ label = "f3";
+ gpios = <&gpio4 8 GPIO_ACTIVE_LOW>; /* gpio104 */
+ linux,code = <0x0503003d>; /* KEY_F3 */
+ gpio-key,wakeup;
+ };
+
+ key_f4 {
+ label = "f4";
+ gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; /* gpio105 */
+ linux,code = <0x0704003e>; /* KEY_F4 */
+ gpio-key,wakeup;
+ };
+
+ key_left {
+ label = "left";
+ gpios = <&gpio4 10 GPIO_ACTIVE_LOW>; /* gpio106 */
+ linux,code = <0x04070069>; /* KEY_LEFT */
+ gpio-key,wakeup;
+ };
+
+ key_right {
+ label = "right";
+ gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; /* gpio107 */
+ linux,code = <0x0507006a>; /* KEY_RIGHT */
+ gpio-key,wakeup;
+ };
+
+ key_up {
+ label = "up";
+ gpios = <&gpio4 12 GPIO_ACTIVE_LOW>; /* gpio108 */
+ linux,code = <0x06070067>; /* KEY_UP */
+ gpio-key,wakeup;
+ };
+
+ key_down {
+ label = "down";
+ gpios = <&gpio4 13 GPIO_ACTIVE_LOW>; /* gpio109 */
+ linux,code = <0x0707006c>; /* KEY_DOWN */
+ gpio-key,wakeup;
+ };
+ };
+};
+
+&gpmc {
+ ranges = <0 0 0x00000000 0x01000000>,
+ <1 0 0x08000000 0x01000000>;
+
+ nand@0,0 {
+ linux,mtd-name= "micron,nand";
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ nand-bus-width = <16>;
+ gpmc,device-width = <2>;
+ ti,nand-ecc-opt = "bch8";
+
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <44>;
+ gpmc,cs-wr-off-ns = <44>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <34>;
+ gpmc,adv-wr-off-ns = <44>;
+ gpmc,we-off-ns = <40>;
+ gpmc,oe-off-ns = <54>;
+ gpmc,access-ns = <64>;
+ gpmc,rd-cycle-ns = <82>;
+ gpmc,wr-cycle-ns = <82>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "X-Loader";
+ reg = <0 0x80000>;
+ };
+ partition@80000 {
+ label = "U-Boot";
+ reg = <0x80000 0x140000>;
+ };
+ partition@1c0000 {
+ label = "Environment";
+ reg = <0x1c0000 0x40000>;
+ };
+ partition@200000 {
+ label = "Kernel";
+ reg = <0x200000 0x1e00000>;
+ };
+ partition@2000000 {
+ label = "Filesystem";
+ reg = <0x2000000 0x6000000>;
+ };
+ };
+
+ ethernet@gpmc {
+ interrupt-parent = <&gpio5>;
+ interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
+ reg = <1 0 0xff>;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+
+ twl_power: power {
+ compatible = "ti,twl4030-power-idle";
+ ti,use_poweroff;
+ };
+ };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+#include "omap3-panel-sharp-ls037v7dw01.dtsi"
+
+&backlight0 {
+ gpios = <&twl_gpio 7 GPIO_ACTIVE_HIGH>;
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+};
+
+/* tps61130rsa enabled by twl4030 regen */
+&lcd_3v3 {
+ regulator-always-on;
+};
+
+&lcd0 {
+ enable-gpios = <&twl_gpio 15 GPIO_ACTIVE_HIGH>; /* lcd INI */
+ reset-gpios = <&gpio2 23 GPIO_ACTIVE_HIGH>; /* gpio55, lcd RESB */
+ mode-gpios = <&gpio2 24 GPIO_ACTIVE_HIGH>; /* gpio56, lcd MO */
+};
+
+&mcspi1 {
+ tsc2046@0 {
+ interrupt-parent = <&gpio2>;
+ interrupts = <22 0>; /* gpio54 */
+ pendown-gpio = <&gpio2 22 0>;
+ };
+};
+
+&mmc1 {
+ /* See 35xx errata 2.1.1.128 in SPRZ278F */
+ compatible = "ti,omap3-pre-es3-hsmmc";
+ vmmc-supply = <&vmmc1>;
+ bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+};
+
+&mmc2 {
+ status="disabled";
+};
+
+&mmc3 {
+ status="disabled";
+};
+
+&omap3_pmx_core {
+ gpio_key_pins: pinmux_gpio_key_pins {
+ pinctrl-single,pins = <
+ 0xea (PIN_INPUT | MUX_MODE4) /* cam_d2.gpio_101 */
+ 0xec (PIN_INPUT | MUX_MODE4) /* cam_d3.gpio_102 */
+ 0xee (PIN_INPUT | MUX_MODE4) /* cam_d4.gpio_103 */
+ 0xf0 (PIN_INPUT | MUX_MODE4) /* cam_d5.gpio_104 */
+ 0xf2 (PIN_INPUT | MUX_MODE4) /* cam_d6.gpio_105 */
+ 0xf4 (PIN_INPUT | MUX_MODE4) /* cam_d7.gpio_106 */
+ 0xf6 (PIN_INPUT | MUX_MODE4) /* cam_d8.gpio_107 */
+ 0xf8 (PIN_INPUT | MUX_MODE4) /* cam_d9.gpio_108 */
+ 0xfa (PIN_INPUT | MUX_MODE4) /* cam_d10.gpio_109 */
+ >;
+ };
+
+ musb_pins: pinmux_musb_pins {
+ pinctrl-single,pins = <
+ 0x172 (PIN_INPUT | MUX_MODE0) /* hsusb0_clk.hsusb0_clk */
+ 0x17a (PIN_INPUT | MUX_MODE0) /* hsusb0_data0.hsusb0_data0 */
+ 0x17c (PIN_INPUT | MUX_MODE0) /* hsusb0_data1.hsusb0_data1 */
+ 0x17e (PIN_INPUT | MUX_MODE0) /* hsusb0_data2.hsusb0_data2 */
+ 0x180 (PIN_INPUT | MUX_MODE0) /* hsusb0_data3.hsusb0_data3 */
+ 0x182 (PIN_INPUT | MUX_MODE0) /* hsusb0_data4.hsusb0_data4 */
+ 0x184 (PIN_INPUT | MUX_MODE0) /* hsusb0_data5.hsusb0_data5 */
+ 0x186 (PIN_INPUT | MUX_MODE0) /* hsusb0_data6.hsusb0_data6 */
+ 0x188 (PIN_INPUT | MUX_MODE0) /* hsusb0_data7.hsusb0_data7 */
+ 0x176 (PIN_INPUT | MUX_MODE0) /* hsusb0_dir.hsusb0_dir */
+ 0x178 (PIN_INPUT | MUX_MODE0) /* hsusb0_nxt.hsusb0_nxt */
+ 0x174 (PIN_OUTPUT | MUX_MODE0) /* hsusb0_stp.hsusb0_stp */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.mmc1_clk */
+ OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.mmc1_cmd */
+ OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.mmc1_dat0 */
+ OMAP3_CORE1_IOPAD(0x214A, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.mmc1_dat1 */
+ OMAP3_CORE1_IOPAD(0x214C, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.mmc1_dat2 */
+ OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.mmc1_dat3 */
+ >;
+ };
+};
+
+&twl_keypad {
+ linux,keymap = <MATRIX_KEY(0, 0, KEY_1)
+ MATRIX_KEY(0, 1, KEY_2)
+ MATRIX_KEY(0, 2, KEY_3)
+ MATRIX_KEY(1, 0, KEY_4)
+ MATRIX_KEY(1, 1, KEY_5)
+ MATRIX_KEY(1, 2, KEY_6)
+ MATRIX_KEY(1, 3, KEY_F5)
+ MATRIX_KEY(2, 0, KEY_7)
+ MATRIX_KEY(2, 1, KEY_8)
+ MATRIX_KEY(2, 2, KEY_9)
+ MATRIX_KEY(2, 3, KEY_F6)
+ MATRIX_KEY(3, 0, KEY_F7)
+ MATRIX_KEY(3, 1, KEY_0)
+ MATRIX_KEY(3, 2, KEY_F8)
+ MATRIX_KEY(5, 4, KEY_RESERVED)
+ MATRIX_KEY(4, 4, KEY_VOLUMEUP)
+ MATRIX_KEY(5, 5, KEY_VOLUMEDOWN)>;
+};
+
+&uart3 {
+ interrupts-extended = <&intc 74 &omap3_pmx_core OMAP3_UART3_RX>;
+};
+
+&usb_otg_hs {
+ pinctrl-names = "default";
+ pinctrl-0 = <&musb_pins>;
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ mode = <3>;
+ power = <50>;
+};
+
+&vaux1 {
+ /* Needed for ads7846 */
+ regulator-name = "vcc";
+};
diff --git a/arch/arm/boot/dts/omap3-lilly-a83x.dtsi b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
new file mode 100644
index 000000000..e63133304
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
@@ -0,0 +1,458 @@
+/*
+ * Copyright (C) 2014 Christoph Fritz <chf.fritzc@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 "omap36xx.dtsi"
+
+/ {
+ model = "INCOstartec LILLY-A83X module (DM3730)";
+ compatible = "incostartec,omap3-lilly-a83x", "ti,omap36xx", "ti,omap3";
+
+ chosen {
+ bootargs = "console=ttyO0,115200n8 vt.global_cursor_default=0 consoleblank=0";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x8000000>; /* 128 MB */
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led1 {
+ label = "lilly-a83x::led1";
+ gpios = <&gpio1 29 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+
+ };
+
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "lilly-a83x";
+
+ ti,mcbsp = <&mcbsp2>;
+ };
+
+ reg_vcc3: vcc3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ hsusb1_phy: hsusb1_phy {
+ compatible = "usb-nop-xceiv";
+ vcc-supply = <&reg_vcc3>;
+ };
+};
+
+&omap3_pmx_wkup {
+ pinctrl-names = "default";
+
+ lan9221_pins: pinmux_lan9221_pins {
+ pinctrl-single,pins = <
+ OMAP3_WKUP_IOPAD(0x2a5a, PIN_INPUT | MUX_MODE4) /* reserved.gpio_129 */
+ >;
+ };
+
+ tsc2048_pins: pinmux_tsc2048_pins {
+ pinctrl-single,pins = <
+ OMAP3_WKUP_IOPAD(0x2a16, PIN_INPUT_PULLUP | MUX_MODE4) /* sys_boot6.gpio_8 */
+ >;
+ };
+
+ mmc1cd_pins: pinmux_mmc1cd_pins {
+ pinctrl-single,pins = <
+ OMAP3_WKUP_IOPAD(0x2a56, PIN_INPUT | MUX_MODE4) /* reserved.gpio_126 */
+ >;
+ };
+};
+
+&omap3_pmx_core {
+ pinctrl-names = "default";
+
+ uart1_pins: pinmux_uart1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE0) /* uart1_tx.uart1_tx */
+ OMAP3_CORE1_IOPAD(0x217e, PIN_OUTPUT | MUX_MODE0) /* uart1_rts.uart1_rts */
+ OMAP3_CORE1_IOPAD(0x2180, PIN_INPUT | MUX_MODE0) /* uart1_cts.uart1_cts */
+ OMAP3_CORE1_IOPAD(0x2182, PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */
+ >;
+ };
+
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2170, PIN_OUTPUT | MUX_MODE1) /* mcbsp3_clkx.uart2_tx */
+ OMAP3_CORE1_IOPAD(0x2172, PIN_INPUT | MUX_MODE1) /* mcbsp3_fsx.uart2_rx */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+ OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21ba ,PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl.i2c1_scl */
+ OMAP3_CORE1_IOPAD(0x21bc ,PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda.i2c1_sda */
+ >;
+ };
+
+ i2c2_pins: pinmux_i2c2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21be, PIN_INPUT | MUX_MODE0) /* i2c2_scl.i2c2_scl */
+ OMAP3_CORE1_IOPAD(0x21c0, PIN_INPUT | MUX_MODE0) /* i2c2_sda.i2c2_sda */
+ >;
+ };
+
+ i2c3_pins: pinmux_i2c3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT | MUX_MODE0) /* i2c3_scl.i2c3_scl */
+ OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT | MUX_MODE0) /* i2c3_sda.i2c3_sda */
+ >;
+ };
+
+ hsusb1_pins: pinmux_hsusb1_pins {
+ pinctrl-single,pins = <
+
+ /* GPIO 182 controls USB-Hub reset. But USB-Phy its
+ * reset can't be controlled. So we clamp this GPIO to
+ * high (PIN_OFF_OUTPUT_HIGH) to always enable USB-Hub.
+ */
+
+ OMAP3_CORE1_IOPAD(0x21de, PIN_OUTPUT_PULLUP | PIN_OFF_OUTPUT_HIGH | MUX_MODE4) /* mcspi2_cs1.gpio_182 */
+ >;
+ };
+
+ hsusb_otg_pins: pinmux_hsusb_otg_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21a2, PIN_INPUT | MUX_MODE0) /* hsusb0_clk.hsusb0_clk */
+ OMAP3_CORE1_IOPAD(0x21a4, PIN_OUTPUT | MUX_MODE0) /* hsusb0_stp.hsusb0_stp */
+ OMAP3_CORE1_IOPAD(0x21a6, PIN_INPUT | MUX_MODE0) /* hsusb0_dir.hsusb0_dir */
+ OMAP3_CORE1_IOPAD(0x21a8, PIN_INPUT | MUX_MODE0) /* hsusb0_nxt.hsusb0_nxt */
+ OMAP3_CORE1_IOPAD(0x21aa, PIN_INPUT | MUX_MODE0) /* hsusb0_data0.hsusb0_data0 */
+ OMAP3_CORE1_IOPAD(0x21ac, PIN_INPUT | MUX_MODE0) /* hsusb0_data1.hsusb0_data1 */
+ OMAP3_CORE1_IOPAD(0x21ae, PIN_INPUT | MUX_MODE0) /* hsusb0_data2.hsusb0_data2 */
+ OMAP3_CORE1_IOPAD(0x21b0, PIN_INPUT | MUX_MODE0) /* hsusb0_data3.hsusb0_data3 */
+ OMAP3_CORE1_IOPAD(0x21b2, PIN_INPUT | MUX_MODE0) /* hsusb0_data4.hsusb0_data4 */
+ OMAP3_CORE1_IOPAD(0x21b4, PIN_INPUT | MUX_MODE0) /* hsusb0_data5.hsusb0_data5 */
+ OMAP3_CORE1_IOPAD(0x21b6, PIN_INPUT | MUX_MODE0) /* hsusb0_data6.hsusb0_data6 */
+ OMAP3_CORE1_IOPAD(0x21b8, PIN_INPUT | MUX_MODE0) /* hsusb0_data7.hsusb0_data7 */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */
+ OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */
+ OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */
+ OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */
+ OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */
+ OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
+ >;
+ };
+
+ spi2_pins: pinmux_spi2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcspi2_clk.mcspi2_clk */
+ OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcspi2_simo.mcspi2_simo */
+ OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcspi2_somi.mcspi2_somi */
+ OMAP3_CORE1_IOPAD(0x21dc, PIN_OUTPUT | MUX_MODE0) /* mcspi2_cs0.mcspi2_cs0 */
+ >;
+ };
+};
+
+&omap3_pmx_core2 {
+ pinctrl-names = "default";
+
+ hsusb1_2_pins: pinmux_hsusb1_2_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25d8, PIN_OUTPUT | MUX_MODE3) /* etk_clk.hsusb1_stp */
+ OMAP3630_CORE2_IOPAD(0x25da, PIN_INPUT | MUX_MODE3) /* etk_ctl.hsusb1_clk */
+ OMAP3630_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE3) /* etk_d0.hsusb1_data0 */
+ OMAP3630_CORE2_IOPAD(0x25de, PIN_INPUT | MUX_MODE3) /* etk_d1.hsusb1_data1 */
+ OMAP3630_CORE2_IOPAD(0x25e0, PIN_INPUT | MUX_MODE3) /* etk_d2.hsusb1_data2 */
+ OMAP3630_CORE2_IOPAD(0x25e2, PIN_INPUT | MUX_MODE3) /* etk_d3.hsusb1_data7 */
+ OMAP3630_CORE2_IOPAD(0x25e4, PIN_INPUT | MUX_MODE3) /* etk_d4.hsusb1_data4 */
+ OMAP3630_CORE2_IOPAD(0x25e6, PIN_INPUT | MUX_MODE3) /* etk_d5.hsusb1_data5 */
+ OMAP3630_CORE2_IOPAD(0x25e8, PIN_INPUT | MUX_MODE3) /* etk_d6.hsusb1_data6 */
+ OMAP3630_CORE2_IOPAD(0x25ea, PIN_INPUT | MUX_MODE3) /* etk_d7.hsusb1_data3 */
+ OMAP3630_CORE2_IOPAD(0x25ec, PIN_INPUT | MUX_MODE3) /* etk_d8.hsusb1_dir */
+ OMAP3630_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE3) /* etk_d9.hsusb1_nxt */
+ >;
+ };
+
+ gpio1_pins: pinmux_gpio1_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25fa, PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* etk_d15.gpio_29 */
+ >;
+ };
+
+};
+
+&gpio1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio1_pins>;
+};
+
+&gpio6 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsusb1_pins>;
+};
+
+&i2c1 {
+ clock-frequency = <2600000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ codec {
+ };
+ };
+ };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&twl {
+ vmmc1: regulator-vmmc1 {
+ regulator-always-on;
+ };
+
+ vdd1: regulator-vdd1 {
+ regulator-always-on;
+ };
+
+ vdd2: regulator-vdd2 {
+ regulator-always-on;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <2600000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+};
+
+&i2c3 {
+ clock-frequency = <2600000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+ gpiom1: gpio@20 {
+ compatible = "mcp,mcp23017";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x20>;
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+};
+
+&uart4 {
+ status = "disabled";
+};
+
+&mmc1 {
+ cd-gpios = <&gpio4 30 IRQ_TYPE_LEVEL_LOW>;
+ cd-inverted;
+ vmmc-supply = <&vmmc1>;
+ bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins &mmc1cd_pins>;
+ cap-sdio-irq;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+};
+
+&mmc2 {
+ status = "disabled";
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&mcspi2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_pins>;
+
+ tsc2046@0 {
+ reg = <0>; /* CS0 */
+ compatible = "ti,tsc2046";
+ interrupt-parent = <&gpio1>;
+ interrupts = <8 0>; /* boot6 / gpio_8 */
+ spi-max-frequency = <1000000>;
+ pendown-gpio = <&gpio1 8 0>;
+ vcc-supply = <&reg_vcc3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&tsc2048_pins>;
+
+ ti,x-min = <300>;
+ ti,x-max = <3000>;
+ ti,y-min = <600>;
+ ti,y-max = <3600>;
+ ti,x-plate-ohms = <80>;
+ ti,pressure-max = <255>;
+ ti,swap-xy;
+
+ linux,wakeup;
+ };
+};
+
+&usbhsehci {
+ phys = <&hsusb1_phy>;
+};
+
+&usbhshost {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsusb1_2_pins>;
+ num-ports = <2>;
+ port1-mode = "ehci-phy";
+};
+
+&usb_otg_hs {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsusb_otg_pins>;
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ phys = <&usb2_phy>;
+ phy-names = "usb2-phy";
+ mode = <3>;
+ power = <50>;
+};
+
+&mcbsp2 {
+ status = "okay";
+};
+
+&gpmc {
+ ranges = <0 0 0x30000000 0x1000000>,
+ <7 0 0x15000000 0x01000000>;
+
+ nand@0,0 {
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ nand-bus-width = <16>;
+ ti,nand-ecc-opt = "bch8";
+ /* no elm on omap3 */
+
+ gpmc,mux-add-data = <0>;
+ gpmc,device-width = <2>;
+ gpmc,wait-pin = <0>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,burst-length= <4>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <100>;
+ gpmc,cs-wr-off-ns = <100>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <100>;
+ gpmc,adv-wr-off-ns = <100>;
+ gpmc,oe-on-ns = <5>;
+ gpmc,oe-off-ns = <75>;
+ gpmc,we-on-ns = <5>;
+ gpmc,we-off-ns = <75>;
+ gpmc,rd-cycle-ns = <100>;
+ gpmc,wr-cycle-ns = <100>;
+ gpmc,access-ns = <60>;
+ gpmc,page-burst-access-ns = <5>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-samecsen;
+ gpmc,cycle2cycle-delay-ns = <50>;
+ gpmc,wr-data-mux-bus-ns = <75>;
+ gpmc,wr-access-ns = <155>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "MLO";
+ reg = <0 0x80000>;
+ };
+
+ partition@0x80000 {
+ label = "u-boot";
+ reg = <0x80000 0x1e0000>;
+ };
+
+ partition@0x260000 {
+ label = "u-boot-environment";
+ reg = <0x260000 0x20000>;
+ };
+
+ partition@0x280000 {
+ label = "kernel";
+ reg = <0x280000 0x500000>;
+ };
+
+ partition@0x780000 {
+ label = "filesystem";
+ reg = <0x780000 0xf880000>;
+ };
+ };
+
+ ethernet@7,0 {
+ compatible = "smsc,lan9221", "smsc,lan9115";
+ bank-width = <2>;
+ gpmc,mux-add-data = <2>;
+ gpmc,cs-on-ns = <10>;
+ gpmc,cs-rd-off-ns = <60>;
+ gpmc,cs-wr-off-ns = <60>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <10>;
+ gpmc,adv-wr-off-ns = <10>;
+ gpmc,oe-on-ns = <10>;
+ gpmc,oe-off-ns = <60>;
+ gpmc,we-on-ns = <10>;
+ gpmc,we-off-ns = <60>;
+ gpmc,rd-cycle-ns = <100>;
+ gpmc,wr-cycle-ns = <100>;
+ gpmc,access-ns = <50>;
+ gpmc,page-burst-access-ns = <5>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <75>;
+ gpmc,wr-data-mux-bus-ns = <15>;
+ gpmc,wr-access-ns = <75>;
+ gpmc,cycle2cycle-samecsen;
+ gpmc,cycle2cycle-diffcsen;
+ vddvario-supply = <&reg_vcc3>;
+ vdd33a-supply = <&reg_vcc3>;
+ reg-io-width = <4>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <1 0x2>;
+ reg = <7 0 0xff>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&lan9221_pins>;
+ phy-mode = "mii";
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-lilly-dbb056.dts b/arch/arm/boot/dts/omap3-lilly-dbb056.dts
new file mode 100644
index 000000000..834f7c65f
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-lilly-dbb056.dts
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2014 Christoph Fritz <chf.fritzc@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.
+ */
+/dts-v1/;
+
+#include "omap3-lilly-a83x.dtsi"
+
+/ {
+ model = "INCOstartec LILLY-DBB056 (DM3730)";
+ compatible = "incostartec,omap3-lilly-dbb056", "incostartec,omap3-lilly-a83x", "ti,omap36xx", "ti,omap3";
+};
+
+&twl {
+ vaux2: regulator-vaux2 {
+ compatible = "ti,twl4030-vaux2";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+};
+
+&omap3_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_pins>;
+
+ lan9117_pins: pinmux_lan9117_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2114, PIN_INPUT | MUX_MODE4) /* cam_fld.gpio_98 */
+ >;
+ };
+
+ gpio4_pins: pinmux_gpio4_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x212e, PIN_INPUT | MUX_MODE4) /* cam_xclkb.gpio_111 -> sja1000 IRQ */
+ >;
+ };
+
+ gpio5_pins: pinmux_gpio5_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x218c, PIN_OUTPUT | PIN_OFF_OUTPUT_HIGH | MUX_MODE4) /* mcbsp1_clk.gpio_156 -> enable DSS */
+ >;
+ };
+
+ lcd_pins: pinmux_lcd_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */
+ OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */
+ OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */
+ OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */
+ OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE0) /* dss_data0.dss_data0 */
+ OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT | MUX_MODE0) /* dss_data1.dss_data1 */
+ OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT | MUX_MODE0) /* dss_data2.dss_data2 */
+ OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE0) /* dss_data3.dss_data3 */
+ OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE0) /* dss_data4.dss_data4 */
+ OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE0) /* dss_data5.dss_data5 */
+ OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */
+ OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */
+ OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */
+ OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */
+ OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */
+ OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */
+ OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */
+ OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */
+ OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */
+ OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */
+ OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */
+ OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */
+ >;
+ };
+
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
+ OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
+ OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
+ OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+ OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
+ OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
+ OMAP3_CORE1_IOPAD(0x2164, PIN_OUTPUT | MUX_MODE1) /* sdmmc2_dat4.sdmmc2_dir_dat0 */
+ OMAP3_CORE1_IOPAD(0x2166, PIN_OUTPUT | MUX_MODE1) /* sdmmc2_dat5.sdmmc2_dir_dat1 */
+ OMAP3_CORE1_IOPAD(0x2168, PIN_OUTPUT | MUX_MODE1) /* sdmmc2_dat6.sdmmc2_dir_cmd */
+ OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT | MUX_MODE1) /* sdmmc2_dat7.sdmmc2_clkin */
+ OMAP3_CORE1_IOPAD(0x219a, PIN_INPUT_PULLUP | MUX_MODE4) /* uart3_cts_rctx.gpio_163 -> wp */
+ OMAP3_CORE1_IOPAD(0x219c, PIN_INPUT_PULLUP | MUX_MODE4) /* uart3_rts_sd.gpio_164 -> cd */
+ >;
+ };
+
+ spi1_pins: pinmux_spi1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21c8, PIN_INPUT | MUX_MODE0) /* mcspi1_clk.mcspi1_clk */
+ OMAP3_CORE1_IOPAD(0x21ca, PIN_INPUT | MUX_MODE0) /* mcspi1_simo.mcspi1_simo */
+ OMAP3_CORE1_IOPAD(0x21cc, PIN_INPUT | MUX_MODE0) /* mcspi1_somi.mcspi1_somi */
+ OMAP3_CORE1_IOPAD(0x21ce, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcspi1_cs0.mcspi1_cs0 */
+ >;
+ };
+};
+
+&gpio4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio4_pins>;
+};
+
+&gpio5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio5_pins>;
+};
+
+&mmc2 {
+ status = "okay";
+ bus-width = <4>;
+ vmmc-supply = <&vmmc1>;
+ cd-gpios = <&gpio6 4 0>; /* gpio_164 */
+ wp-gpios = <&gpio6 3 0>; /* gpio_163 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+ ti,dual-volt;
+};
+
+&mcspi1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins>;
+};
+
+&gpmc {
+ ranges = <0 0 0x30000000 0x1000000>, /* nand assigned by COM a83x */
+ <4 0 0x20000000 0x01000000>,
+ <7 0 0x15000000 0x01000000>; /* eth assigend by COM a83x */
+
+ ethernet@4,0 {
+ compatible = "smsc,lan9117", "smsc,lan9115";
+ bank-width = <2>;
+ gpmc,mux-add-data = <2>;
+ gpmc,cs-on-ns = <10>;
+ gpmc,cs-rd-off-ns = <65>;
+ gpmc,cs-wr-off-ns = <65>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <10>;
+ gpmc,adv-wr-off-ns = <10>;
+ gpmc,oe-on-ns = <10>;
+ gpmc,oe-off-ns = <65>;
+ gpmc,we-on-ns = <10>;
+ gpmc,we-off-ns = <65>;
+ gpmc,rd-cycle-ns = <100>;
+ gpmc,wr-cycle-ns = <100>;
+ gpmc,access-ns = <60>;
+ gpmc,page-burst-access-ns = <5>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <75>;
+ gpmc,wr-data-mux-bus-ns = <15>;
+ gpmc,wr-access-ns = <75>;
+ gpmc,cycle2cycle-samecsen;
+ gpmc,cycle2cycle-diffcsen;
+ vddvario-supply = <&reg_vcc3>;
+ vdd33a-supply = <&reg_vcc3>;
+ reg-io-width = <4>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <2 0x2>;
+ reg = <4 0 0xff>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&lan9117_pins>;
+ phy-mode = "mii";
+ smsc,force-internal-phy;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-n9.dts b/arch/arm/boot/dts/omap3-n9.dts
new file mode 100644
index 000000000..f2e213931
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-n9.dts
@@ -0,0 +1,55 @@
+/*
+ * omap3-n9.dts - Device Tree file for Nokia N9
+ *
+ * Written by: Aaro Koskinen <aaro.koskinen@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+#include "omap3-n950-n9.dtsi"
+
+/ {
+ model = "Nokia N9";
+ compatible = "nokia,omap3-n9", "ti,omap36xx", "ti,omap3";
+};
+
+&i2c2 {
+ smia_1: camera@10 {
+ compatible = "nokia,smia";
+ reg = <0x10>;
+ /* No reset gpio */
+ vana-supply = <&vaux3>;
+ clocks = <&isp 0>;
+ clock-frequency = <9600000>;
+ nokia,nvm-size = <(16 * 64)>;
+ port {
+ smia_1_1: endpoint {
+ link-frequencies = /bits/ 64 <199200000 210000000 499200000>;
+ clock-lanes = <0>;
+ data-lanes = <1 2>;
+ remote-endpoint = <&csi2a_ep>;
+ };
+ };
+ };
+};
+
+&isp {
+ vdd-csiphy1-supply = <&vaux2>;
+ vdd-csiphy2-supply = <&vaux2>;
+ ports {
+ port@2 {
+ reg = <2>;
+ csi2a_ep: endpoint {
+ remote-endpoint = <&smia_1_1>;
+ clock-lanes = <2>;
+ data-lanes = <1 3>;
+ crc = <1>;
+ lane-polarities = <1 1 1>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
new file mode 100644
index 000000000..5f5e0f3d5
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -0,0 +1,990 @@
+/*
+ * Copyright (C) 2013 Pavel Machek <pavel@ucw.cz>
+ * Copyright (C) 2013-2014 Aaro Koskinen <aaro.koskinen@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 (or later) as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+#include "omap34xx.dtsi"
+#include <dt-bindings/input/input.h>
+
+/*
+ * Default secure signed bootloader (Nokia X-Loader) does not enable L3 firewall
+ * for omap AES HW crypto support. When linux kernel try to access memory of AES
+ * blocks then kernel receive "Unhandled fault: external abort on non-linefetch"
+ * and crash. Until somebody fix omap-aes.c and omap_hwmod_3xxx_data.c code (no
+ * crash anymore) omap AES support will be disabled for all Nokia N900 devices.
+ * There is "unofficial" version of bootloader which enables AES in L3 firewall
+ * but it is not widely used and to prevent kernel crash rather AES is disabled.
+ * There is also no runtime detection code if AES is disabled in L3 firewall...
+ */
+&aes {
+ status = "disabled";
+};
+
+/ {
+ model = "Nokia N900";
+ compatible = "nokia,omap3-n900", "ti,omap3430", "ti,omap3";
+
+ aliases {
+ i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ };
+
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vcc>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ heartbeat {
+ label = "debug::sleep";
+ gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>; /* gpio162 */
+ linux,default-trigger = "default-on";
+ pinctrl-names = "default";
+ pinctrl-0 = <&debug_leds>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ camera_lens_cover {
+ label = "Camera Lens Cover";
+ gpios = <&gpio4 14 GPIO_ACTIVE_LOW>; /* 110 */
+ linux,input-type = <5>; /* EV_SW */
+ linux,code = <0x09>; /* SW_CAMERA_LENS_COVER */
+ gpio-key,wakeup;
+ };
+
+ camera_focus {
+ label = "Camera Focus";
+ gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; /* 68 */
+ linux,code = <0x210>; /* KEY_CAMERA_FOCUS */
+ gpio-key,wakeup;
+ };
+
+ camera_capture {
+ label = "Camera Capture";
+ gpios = <&gpio3 5 GPIO_ACTIVE_LOW>; /* 69 */
+ linux,code = <0xd4>; /* KEY_CAMERA */
+ gpio-key,wakeup;
+ };
+
+ lock_button {
+ label = "Lock Button";
+ gpios = <&gpio4 17 GPIO_ACTIVE_LOW>; /* 113 */
+ linux,code = <0x98>; /* KEY_SCREENLOCK */
+ gpio-key,wakeup;
+ };
+
+ keypad_slide {
+ label = "Keypad Slide";
+ gpios = <&gpio3 7 GPIO_ACTIVE_LOW>; /* 71 */
+ linux,input-type = <5>; /* EV_SW */
+ linux,code = <0x0a>; /* SW_KEYPAD_SLIDE */
+ gpio-key,wakeup;
+ };
+
+ proximity_sensor {
+ label = "Proximity Sensor";
+ gpios = <&gpio3 25 GPIO_ACTIVE_HIGH>; /* 89 */
+ linux,input-type = <5>; /* EV_SW */
+ linux,code = <0x0b>; /* SW_FRONT_PROXIMITY */
+ };
+ };
+
+ isp1704: isp1704 {
+ compatible = "nxp,isp1704";
+ nxp,enable-gpio = <&gpio3 3 GPIO_ACTIVE_HIGH>;
+ usb-phy = <&usb2_phy>;
+ };
+
+ tv: connector {
+ compatible = "composite-video-connector";
+ label = "tv";
+
+ port {
+ tv_connector_in: endpoint {
+ remote-endpoint = <&venc_out>;
+ };
+ };
+ };
+
+ sound: n900-audio {
+ compatible = "nokia,n900-audio";
+
+ nokia,cpu-dai = <&mcbsp2>;
+ nokia,audio-codec = <&tlv320aic3x>, <&tlv320aic3x_aux>;
+ nokia,headphone-amplifier = <&tpa6130a2>;
+
+ tvout-selection-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>; /* 40 */
+ jack-detection-gpios = <&gpio6 17 GPIO_ACTIVE_HIGH>; /* 177 */
+ eci-switch-gpios = <&gpio6 22 GPIO_ACTIVE_HIGH>; /* 182 */
+ speaker-amplifier-gpios = <&twl_gpio 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ battery: n900-battery {
+ compatible = "nokia,n900-battery";
+ io-channels = <&twl_madc 0>, <&twl_madc 4>, <&twl_madc 12>;
+ io-channel-names = "temp", "bsi", "vbat";
+ };
+};
+
+&omap3_pmx_core {
+ pinctrl-names = "default";
+
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ 0x14a (PIN_INPUT | MUX_MODE0) /* uart2_rx */
+ 0x148 (PIN_OUTPUT | MUX_MODE0) /* uart2_tx */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ 0x16e (PIN_INPUT | MUX_MODE0) /* uart3_rx */
+ 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx */
+ >;
+ };
+
+ ethernet_pins: pinmux_ethernet_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20b4, PIN_INPUT_PULLDOWN | MUX_MODE4) /* gpmc_ncs3.gpio_54 */
+ OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE4) /* dss_data16.gpio_86 */
+ OMAP3_CORE1_IOPAD(0x219c, PIN_OUTPUT | MUX_MODE4) /* uart3_rts_sd.gpio_164 */
+ >;
+ };
+
+ gpmc_pins: pinmux_gpmc_pins {
+ pinctrl-single,pins = <
+
+ /* address lines */
+ OMAP3_CORE1_IOPAD(0x207a, PIN_OUTPUT | MUX_MODE0) /* gpmc_a1.gpmc_a1 */
+ OMAP3_CORE1_IOPAD(0x207c, PIN_OUTPUT | MUX_MODE0) /* gpmc_a2.gpmc_a2 */
+ OMAP3_CORE1_IOPAD(0x207e, PIN_OUTPUT | MUX_MODE0) /* gpmc_a3.gpmc_a3 */
+
+ /* data lines, gpmc_d0..d7 not muxable according to TRM */
+ OMAP3_CORE1_IOPAD(0x209e, PIN_INPUT | MUX_MODE0) /* gpmc_d8.gpmc_d8 */
+ OMAP3_CORE1_IOPAD(0x20a0, PIN_INPUT | MUX_MODE0) /* gpmc_d9.gpmc_d9 */
+ OMAP3_CORE1_IOPAD(0x20a2, PIN_INPUT | MUX_MODE0) /* gpmc_d10.gpmc_d10 */
+ OMAP3_CORE1_IOPAD(0x20a4, PIN_INPUT | MUX_MODE0) /* gpmc_d11.gpmc_d11 */
+ OMAP3_CORE1_IOPAD(0x20a6, PIN_INPUT | MUX_MODE0) /* gpmc_d12.gpmc_d12 */
+ OMAP3_CORE1_IOPAD(0x20a8, PIN_INPUT | MUX_MODE0) /* gpmc_d13.gpmc_d13 */
+ OMAP3_CORE1_IOPAD(0x20aa, PIN_INPUT | MUX_MODE0) /* gpmc_d14.gpmc_d14 */
+ OMAP3_CORE1_IOPAD(0x20ac, PIN_INPUT | MUX_MODE0) /* gpmc_d15.gpmc_d15 */
+
+ /*
+ * gpmc_ncs0, gpmc_nadv_ale, gpmc_noe, gpmc_nwe, gpmc_wait0 not muxable
+ * according to TRM. OneNAND seems to require PIN_INPUT on clock.
+ */
+ OMAP3_CORE1_IOPAD(0x20b0, PIN_OUTPUT | MUX_MODE0) /* gpmc_ncs1.gpmc_ncs1 */
+ OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0) /* gpmc_clk.gpmc_clk */
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ 0x18a (PIN_INPUT | MUX_MODE0) /* i2c1_scl */
+ 0x18c (PIN_INPUT | MUX_MODE0) /* i2c1_sda */
+ >;
+ };
+
+ i2c2_pins: pinmux_i2c2_pins {
+ pinctrl-single,pins = <
+ 0x18e (PIN_INPUT | MUX_MODE0) /* i2c2_scl */
+ 0x190 (PIN_INPUT | MUX_MODE0) /* i2c2_sda */
+ >;
+ };
+
+ i2c3_pins: pinmux_i2c3_pins {
+ pinctrl-single,pins = <
+ 0x192 (PIN_INPUT | MUX_MODE0) /* i2c3_scl */
+ 0x194 (PIN_INPUT | MUX_MODE0) /* i2c3_sda */
+ >;
+ };
+
+ debug_leds: pinmux_debug_led_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2198, PIN_OUTPUT | MUX_MODE4) /* mcbsp1_clkx.gpio_162 */
+ >;
+ };
+
+ mcspi4_pins: pinmux_mcspi4_pins {
+ pinctrl-single,pins = <
+ 0x15c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mcspi4_clk */
+ 0x162 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mcspi4_somi */
+ 0x160 (PIN_OUTPUT | MUX_MODE1) /* mcspi4_simo */
+ 0x166 (PIN_OUTPUT | MUX_MODE1) /* mcspi4_cs0 */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ 0x114 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk */
+ 0x116 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd */
+ 0x118 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0 */
+ 0x11a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1 */
+ 0x11c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2 */
+ 0x11e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3 */
+ >;
+ };
+
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ 0x128 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk */
+ 0x12a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd */
+ 0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0 */
+ 0x12e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1 */
+ 0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2 */
+ 0x132 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3 */
+ 0x134 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat4 */
+ 0x136 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat5 */
+ 0x138 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat6 */
+ 0x13a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat7 */
+ >;
+ };
+
+ acx565akm_pins: pinmux_acx565akm_pins {
+ pinctrl-single,pins = <
+ 0x0d4 (PIN_OUTPUT | MUX_MODE4) /* RX51_LCD_RESET_GPIO */
+ >;
+ };
+
+ dss_sdi_pins: pinmux_dss_sdi_pins {
+ pinctrl-single,pins = <
+ 0x0c0 (PIN_OUTPUT | MUX_MODE1) /* dss_data10.sdi_dat1n */
+ 0x0c2 (PIN_OUTPUT | MUX_MODE1) /* dss_data11.sdi_dat1p */
+ 0x0c4 (PIN_OUTPUT | MUX_MODE1) /* dss_data12.sdi_dat2n */
+ 0x0c6 (PIN_OUTPUT | MUX_MODE1) /* dss_data13.sdi_dat2p */
+
+ 0x0d8 (PIN_OUTPUT | MUX_MODE1) /* dss_data22.sdi_clkp */
+ 0x0da (PIN_OUTPUT | MUX_MODE1) /* dss_data23.sdi_clkn */
+ >;
+ };
+
+ wl1251_pins: pinmux_wl1251 {
+ pinctrl-single,pins = <
+ 0x0ce (PIN_OUTPUT | MUX_MODE4) /* gpio 87 => wl1251 enable */
+ 0x05a (PIN_INPUT | MUX_MODE4) /* gpio 42 => wl1251 irq */
+ >;
+ };
+
+ ssi_pins: pinmux_ssi {
+ pinctrl-single,pins = <
+ 0x150 (PIN_INPUT_PULLUP | MUX_MODE1) /* ssi1_rdy_tx */
+ 0x14e (PIN_OUTPUT | MUX_MODE1) /* ssi1_flag_tx */
+ 0x152 (PIN_INPUT | WAKEUP_EN | MUX_MODE4) /* ssi1_wake_tx (cawake) */
+ 0x14c (PIN_OUTPUT | MUX_MODE1) /* ssi1_dat_tx */
+ 0x154 (PIN_INPUT | MUX_MODE1) /* ssi1_dat_rx */
+ 0x156 (PIN_INPUT | MUX_MODE1) /* ssi1_flag_rx */
+ 0x158 (PIN_OUTPUT | MUX_MODE1) /* ssi1_rdy_rx */
+ 0x15a (PIN_OUTPUT | MUX_MODE1) /* ssi1_wake */
+ >;
+ };
+
+ modem_pins: pinmux_modem {
+ pinctrl-single,pins = <
+ 0x0ac (PIN_OUTPUT | MUX_MODE4) /* gpio 70 => cmt_apeslpx */
+ 0x0b0 (PIN_INPUT | WAKEUP_EN | MUX_MODE4) /* gpio 72 => ape_rst_rq */
+ 0x0b2 (PIN_OUTPUT | MUX_MODE4) /* gpio 73 => cmt_rst_rq */
+ 0x0b4 (PIN_OUTPUT | MUX_MODE4) /* gpio 74 => cmt_en */
+ 0x0b6 (PIN_OUTPUT | MUX_MODE4) /* gpio 75 => cmt_rst */
+ 0x15e (PIN_OUTPUT | MUX_MODE4) /* gpio 157 => cmt_bsi */
+ >;
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+
+ clock-frequency = <2200000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+ };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&vaux1 {
+ regulator-name = "V28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on; /* due to battery cover sensor */
+};
+
+&vaux2 {
+ regulator-name = "VCSI";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+};
+
+&vaux3 {
+ regulator-name = "VMMC2_30";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3000000>;
+};
+
+&vaux4 {
+ regulator-name = "VCAM_ANA_28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+};
+
+&vmmc1 {
+ regulator-name = "VMMC1";
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <3150000>;
+};
+
+&vmmc2 {
+ regulator-name = "V28_A";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on; /* due VIO leak to AIC34 VDDs */
+};
+
+&vpll1 {
+ regulator-name = "VPLL";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+};
+
+&vpll2 {
+ regulator-name = "VSDI_CSI";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+};
+
+&vsim {
+ regulator-name = "VMMC2_IO_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+};
+
+&vio {
+ regulator-name = "VIO";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+};
+
+&vintana1 {
+ regulator-name = "VINTANA1";
+ /* fixed to 1500000 */
+ regulator-always-on;
+};
+
+&vintana2 {
+ regulator-name = "VINTANA2";
+ regulator-min-microvolt = <2750000>;
+ regulator-max-microvolt = <2750000>;
+ regulator-always-on;
+};
+
+&vintdig {
+ regulator-name = "VINTDIG";
+ /* fixed to 1500000 */
+ regulator-always-on;
+};
+
+&twl {
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ ti,enable-vibra = <1>;
+ };
+
+ twl_power: power {
+ compatible = "ti,twl4030-power-n900", "ti,twl4030-power-idle-osc-off";
+ ti,use_poweroff;
+ };
+};
+
+&twl_keypad {
+ linux,keymap = < MATRIX_KEY(0x00, 0x00, KEY_Q)
+ MATRIX_KEY(0x00, 0x01, KEY_O)
+ MATRIX_KEY(0x00, 0x02, KEY_P)
+ MATRIX_KEY(0x00, 0x03, KEY_COMMA)
+ MATRIX_KEY(0x00, 0x04, KEY_BACKSPACE)
+ MATRIX_KEY(0x00, 0x06, KEY_A)
+ MATRIX_KEY(0x00, 0x07, KEY_S)
+
+ MATRIX_KEY(0x01, 0x00, KEY_W)
+ MATRIX_KEY(0x01, 0x01, KEY_D)
+ MATRIX_KEY(0x01, 0x02, KEY_F)
+ MATRIX_KEY(0x01, 0x03, KEY_G)
+ MATRIX_KEY(0x01, 0x04, KEY_H)
+ MATRIX_KEY(0x01, 0x05, KEY_J)
+ MATRIX_KEY(0x01, 0x06, KEY_K)
+ MATRIX_KEY(0x01, 0x07, KEY_L)
+
+ MATRIX_KEY(0x02, 0x00, KEY_E)
+ MATRIX_KEY(0x02, 0x01, KEY_DOT)
+ MATRIX_KEY(0x02, 0x02, KEY_UP)
+ MATRIX_KEY(0x02, 0x03, KEY_ENTER)
+ MATRIX_KEY(0x02, 0x05, KEY_Z)
+ MATRIX_KEY(0x02, 0x06, KEY_X)
+ MATRIX_KEY(0x02, 0x07, KEY_C)
+ MATRIX_KEY(0x02, 0x08, KEY_F9)
+
+ MATRIX_KEY(0x03, 0x00, KEY_R)
+ MATRIX_KEY(0x03, 0x01, KEY_V)
+ MATRIX_KEY(0x03, 0x02, KEY_B)
+ MATRIX_KEY(0x03, 0x03, KEY_N)
+ MATRIX_KEY(0x03, 0x04, KEY_M)
+ MATRIX_KEY(0x03, 0x05, KEY_SPACE)
+ MATRIX_KEY(0x03, 0x06, KEY_SPACE)
+ MATRIX_KEY(0x03, 0x07, KEY_LEFT)
+
+ MATRIX_KEY(0x04, 0x00, KEY_T)
+ MATRIX_KEY(0x04, 0x01, KEY_DOWN)
+ MATRIX_KEY(0x04, 0x02, KEY_RIGHT)
+ MATRIX_KEY(0x04, 0x04, KEY_LEFTCTRL)
+ MATRIX_KEY(0x04, 0x05, KEY_RIGHTALT)
+ MATRIX_KEY(0x04, 0x06, KEY_LEFTSHIFT)
+ MATRIX_KEY(0x04, 0x08, KEY_F10)
+
+ MATRIX_KEY(0x05, 0x00, KEY_Y)
+ MATRIX_KEY(0x05, 0x08, KEY_F11)
+
+ MATRIX_KEY(0x06, 0x00, KEY_U)
+
+ MATRIX_KEY(0x07, 0x00, KEY_I)
+ MATRIX_KEY(0x07, 0x01, KEY_F7)
+ MATRIX_KEY(0x07, 0x02, KEY_F8)
+ >;
+};
+
+&twl_gpio {
+ ti,pullups = <0x0>;
+ ti,pulldowns = <0x03ff3f>; /* BIT(0..5) | BIT(8..17) */
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+
+ clock-frequency = <100000>;
+
+ tlv320aic3x: tlv320aic3x@18 {
+ compatible = "ti,tlv320aic3x";
+ reg = <0x18>;
+ gpio-reset = <&gpio2 28 GPIO_ACTIVE_HIGH>; /* 60 */
+ ai3x-gpio-func = <
+ 0 /* AIC3X_GPIO1_FUNC_DISABLED */
+ 5 /* AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT */
+ >;
+
+ AVDD-supply = <&vmmc2>;
+ DRVDD-supply = <&vmmc2>;
+ IOVDD-supply = <&vio>;
+ DVDD-supply = <&vio>;
+
+ ai3x-micbias-vg = <1>;
+ };
+
+ tlv320aic3x_aux: tlv320aic3x@19 {
+ compatible = "ti,tlv320aic3x";
+ reg = <0x19>;
+ gpio-reset = <&gpio2 28 GPIO_ACTIVE_HIGH>; /* 60 */
+
+ AVDD-supply = <&vmmc2>;
+ DRVDD-supply = <&vmmc2>;
+ IOVDD-supply = <&vio>;
+ DVDD-supply = <&vio>;
+
+ ai3x-micbias-vg = <2>;
+ };
+
+ tsl2563: tsl2563@29 {
+ compatible = "amstaos,tsl2563";
+ reg = <0x29>;
+
+ amstaos,cover-comp-gain = <16>;
+ };
+
+ lp5523: lp5523@32 {
+ compatible = "national,lp5523";
+ reg = <0x32>;
+ clock-mode = /bits/ 8 <0>; /* LP55XX_CLOCK_AUTO */
+ enable-gpio = <&gpio2 9 GPIO_ACTIVE_HIGH>; /* 41 */
+
+ chan0 {
+ chan-name = "lp5523:kb1";
+ led-cur = /bits/ 8 <50>;
+ max-cur = /bits/ 8 <100>;
+ };
+
+ chan1 {
+ chan-name = "lp5523:kb2";
+ led-cur = /bits/ 8 <50>;
+ max-cur = /bits/ 8 <100>;
+ };
+
+ chan2 {
+ chan-name = "lp5523:kb3";
+ led-cur = /bits/ 8 <50>;
+ max-cur = /bits/ 8 <100>;
+ };
+
+ chan3 {
+ chan-name = "lp5523:kb4";
+ led-cur = /bits/ 8 <50>;
+ max-cur = /bits/ 8 <100>;
+ };
+
+ chan4 {
+ chan-name = "lp5523:b";
+ led-cur = /bits/ 8 <50>;
+ max-cur = /bits/ 8 <100>;
+ };
+
+ chan5 {
+ chan-name = "lp5523:g";
+ led-cur = /bits/ 8 <50>;
+ max-cur = /bits/ 8 <100>;
+ };
+
+ chan6 {
+ chan-name = "lp5523:r";
+ led-cur = /bits/ 8 <50>;
+ max-cur = /bits/ 8 <100>;
+ };
+
+ chan7 {
+ chan-name = "lp5523:kb5";
+ led-cur = /bits/ 8 <50>;
+ max-cur = /bits/ 8 <100>;
+ };
+
+ chan8 {
+ chan-name = "lp5523:kb6";
+ led-cur = /bits/ 8 <50>;
+ max-cur = /bits/ 8 <100>;
+ };
+ };
+
+ bq27200: bq27200@55 {
+ compatible = "ti,bq27200";
+ reg = <0x55>;
+ };
+
+ tpa6130a2: tpa6130a2@60 {
+ compatible = "ti,tpa6130a2";
+ reg = <0x60>;
+
+ Vdd-supply = <&vmmc2>;
+
+ power-gpio = <&gpio4 2 GPIO_ACTIVE_HIGH>; /* 98 */
+ };
+
+ si4713: si4713@63 {
+ compatible = "silabs,si4713";
+ reg = <0x63>;
+
+ interrupts-extended = <&gpio2 21 IRQ_TYPE_EDGE_FALLING>; /* 53 */
+ reset-gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>; /* 163 */
+ vio-supply = <&vio>;
+ vdd-supply = <&vaux1>;
+ };
+
+ bq24150a: bq24150a@6b {
+ compatible = "ti,bq24150a";
+ reg = <0x6b>;
+
+ ti,current-limit = <100>;
+ ti,weak-battery-voltage = <3400>;
+ ti,battery-regulation-voltage = <4200>;
+ ti,charge-current = <650>;
+ ti,termination-current = <100>;
+ ti,resistor-sense = <68>;
+
+ ti,usb-charger-detection = <&isp1704>;
+ };
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+
+ clock-frequency = <400000>;
+
+ lis302dl: lis3lv02d@1d {
+ compatible = "st,lis3lv02d";
+ reg = <0x1d>;
+
+ Vdd-supply = <&vaux1>;
+ Vdd_IO-supply = <&vio>;
+
+ interrupt-parent = <&gpio6>;
+ interrupts = <21 20>; /* 181 and 180 */
+
+ /* click flags */
+ st,click-single-x;
+ st,click-single-y;
+ st,click-single-z;
+
+ /* Limits are 0.5g * value */
+ st,click-threshold-x = <8>;
+ st,click-threshold-y = <8>;
+ st,click-threshold-z = <10>;
+
+ /* Click must be longer than time limit */
+ st,click-time-limit = <9>;
+
+ /* Kind of debounce filter */
+ st,click-latency = <50>;
+
+ /* Interrupt line 2 for click detection */
+ st,irq2-click;
+
+ st,wakeup-x-hi;
+ st,wakeup-y-hi;
+ st,wakeup-threshold = <(800/18)>; /* millig-value / 18 to get HW values */
+
+ st,wakeup2-z-hi;
+ st,wakeup2-threshold = <(900/18)>; /* millig-value / 18 to get HW values */
+
+ st,hipass1-disable;
+ st,hipass2-disable;
+
+ st,axis-x = <1>; /* LIS3_DEV_X */
+ st,axis-y = <(-2)>; /* LIS3_INV_DEV_Y */
+ st,axis-z = <(-3)>; /* LIS3_INV_DEV_Z */
+
+ st,min-limit-x = <(-32)>;
+ st,min-limit-y = <3>;
+ st,min-limit-z = <3>;
+
+ st,max-limit-x = <(-3)>;
+ st,max-limit-y = <32>;
+ st,max-limit-z = <32>;
+ };
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&vmmc1>;
+ bus-width = <4>;
+ cd-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>; /* 160 */
+};
+
+/* most boards use vaux3, only some old versions use vmmc2 instead */
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+ vmmc-supply = <&vaux3>;
+ vmmc_aux-supply = <&vsim>;
+ bus-width = <8>;
+ non-removable;
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&gpmc {
+ ranges = <0 0 0x01000000 0x01000000>, /* 16 MB for OneNAND */
+ <1 0 0x02000000 0x01000000>; /* 16 MB for smc91c96 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpmc_pins>;
+
+ /* sys_ndmareq1 could be used by the driver, not as gpio65 though */
+ onenand@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0 0x20000>; /* CS0, offset 0, IO size 128K */
+
+ gpmc,sync-read;
+ gpmc,sync-write;
+ gpmc,burst-length = <16>;
+ gpmc,burst-read;
+ gpmc,burst-wrap;
+ gpmc,burst-write;
+ gpmc,device-width = <2>; /* GPMC_DEVWIDTH_16BIT */
+ gpmc,mux-add-data = <2>; /* GPMC_MUX_AD */
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <87>;
+ gpmc,cs-wr-off-ns = <87>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <10>;
+ gpmc,adv-wr-off-ns = <10>;
+ gpmc,oe-on-ns = <15>;
+ gpmc,oe-off-ns = <87>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <87>;
+ gpmc,rd-cycle-ns = <112>;
+ gpmc,wr-cycle-ns = <112>;
+ gpmc,access-ns = <81>;
+ gpmc,page-burst-access-ns = <15>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,clk-activation-ns = <5>;
+ gpmc,wr-data-mux-bus-ns = <30>;
+ gpmc,wr-access-ns = <81>;
+ gpmc,sync-clk-ps = <15000>;
+
+ /*
+ * MTD partition table corresponding to Nokia's
+ * Maemo 5 (Fremantle) release.
+ */
+ partition@0 {
+ label = "bootloader";
+ reg = <0x00000000 0x00020000>;
+ read-only;
+ };
+ partition@1 {
+ label = "config";
+ reg = <0x00020000 0x00060000>;
+ };
+ partition@2 {
+ label = "log";
+ reg = <0x00080000 0x00040000>;
+ };
+ partition@3 {
+ label = "kernel";
+ reg = <0x000c0000 0x00200000>;
+ };
+ partition@4 {
+ label = "initfs";
+ reg = <0x002c0000 0x00200000>;
+ };
+ partition@5 {
+ label = "rootfs";
+ reg = <0x004c0000 0x0fb40000>;
+ };
+ };
+
+ /* Ethernet is on some early development boards and qemu */
+ ethernet@gpmc {
+ compatible = "smsc,lan91c94";
+ interrupt-parent = <&gpio2>;
+ interrupts = <22 IRQ_TYPE_LEVEL_HIGH>; /* gpio54 */
+ reg = <1 0 0xf>; /* 16 byte IO range */
+ bank-width = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ethernet_pins>;
+ power-gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>; /* gpio86 */
+ reset-gpios = <&gpio6 4 GPIO_ACTIVE_HIGH>; /* gpio164 */
+ gpmc,device-width = <2>;
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <48>;
+ gpmc,cs-wr-off-ns = <24>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <0>;
+ gpmc,adv-wr-off-ns = <0>;
+ gpmc,we-on-ns = <12>;
+ gpmc,we-off-ns = <18>;
+ gpmc,oe-on-ns = <12>;
+ gpmc,oe-off-ns = <48>;
+ gpmc,page-burst-access-ns = <0>;
+ gpmc,access-ns = <42>;
+ gpmc,rd-cycle-ns = <180>;
+ gpmc,wr-cycle-ns = <180>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wr-access-ns = <0>;
+ gpmc,wr-data-mux-bus-ns = <12>;
+ };
+};
+
+&mcspi1 {
+ /*
+ * For some reason, touchscreen is necessary for screen to work at
+ * all on real hw. It works well without it on emulator.
+ *
+ * Also... order in the device tree actually matters here.
+ */
+ tsc2005@0 {
+ compatible = "ti,tsc2005";
+ spi-max-frequency = <6000000>;
+ reg = <0>;
+
+ vio-supply = <&vio>;
+
+ reset-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* 104 */
+ interrupts-extended = <&gpio4 4 IRQ_TYPE_EDGE_RISING>; /* 100 */
+
+ touchscreen-fuzz-x = <4>;
+ touchscreen-fuzz-y = <7>;
+ touchscreen-fuzz-pressure = <2>;
+ touchscreen-size-x = <4096>;
+ touchscreen-size-y = <4096>;
+ touchscreen-max-pressure = <2048>;
+
+ ti,x-plate-ohms = <280>;
+ ti,esd-recovery-timeout-ms = <8000>;
+ };
+
+ acx565akm@2 {
+ compatible = "sony,acx565akm";
+ spi-max-frequency = <6000000>;
+ reg = <2>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&acx565akm_pins>;
+
+ label = "lcd";
+ reset-gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>; /* 90 */
+
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&sdi_out>;
+ };
+ };
+ };
+};
+
+&mcspi4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi4_pins>;
+
+ wl1251@0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wl1251_pins>;
+
+ vio-supply = <&vio>;
+
+ compatible = "ti,wl1251";
+ reg = <0>;
+ spi-max-frequency = <48000000>;
+
+ spi-cpol;
+ spi-cpha;
+
+ ti,power-gpio = <&gpio3 23 GPIO_ACTIVE_HIGH>; /* 87 */
+
+ interrupt-parent = <&gpio2>;
+ interrupts = <10 IRQ_TYPE_NONE>; /* gpio line 42 */
+ };
+};
+
+&usb_otg_hs {
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ phys = <&usb2_phy>;
+ phy-names = "usb2-phy";
+ mode = <2>;
+ power = <50>;
+};
+
+&uart1 {
+ status = "disabled";
+};
+
+&uart2 {
+ interrupts-extended = <&intc 73 &omap3_pmx_core OMAP3_UART2_RX>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+};
+
+&uart3 {
+ interrupts-extended = <&intc 74 &omap3_pmx_core OMAP3_UART3_RX>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+};
+
+&dss {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_sdi_pins>;
+
+ vdds_sdi-supply = <&vaux1>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+
+ sdi_out: endpoint {
+ remote-endpoint = <&lcd_in>;
+ datapairs = <2>;
+ };
+ };
+ };
+};
+
+&venc {
+ status = "ok";
+
+ vdda-supply = <&vdac>;
+
+ port {
+ venc_out: endpoint {
+ remote-endpoint = <&tv_connector_in>;
+ ti,channels = <1>;
+ };
+ };
+};
+
+&mcbsp2 {
+ status = "ok";
+};
+
+&ssi_port1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ssi_pins>;
+
+ ti,ssi-cawake-gpio = <&gpio5 23 GPIO_ACTIVE_HIGH>; /* 151 */
+
+ modem: hsi-client {
+ compatible = "nokia,n900-modem";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&modem_pins>;
+
+ hsi-channel-ids = <0>, <1>, <2>, <3>;
+ hsi-channel-names = "mcsaab-control",
+ "speech-control",
+ "speech-data",
+ "mcsaab-data";
+ hsi-speed-kbps = <55000>;
+ hsi-mode = "frame";
+ hsi-flow = "synchronized";
+ hsi-arb-mode = "round-robin";
+
+ interrupts-extended = <&gpio3 8 IRQ_TYPE_EDGE_FALLING>; /* 72 */
+
+ gpios = <&gpio3 6 GPIO_ACTIVE_HIGH>, /* 70 */
+ <&gpio3 9 GPIO_ACTIVE_HIGH>, /* 73 */
+ <&gpio3 10 GPIO_ACTIVE_HIGH>, /* 74 */
+ <&gpio3 11 GPIO_ACTIVE_HIGH>, /* 75 */
+ <&gpio5 29 GPIO_ACTIVE_HIGH>; /* 157 */
+ gpio-names = "cmt_apeslpx",
+ "cmt_rst_rq",
+ "cmt_en",
+ "cmt_rst",
+ "cmt_bsi";
+ };
+};
+
+&ssi_port2 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi
new file mode 100644
index 000000000..800b379d3
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi
@@ -0,0 +1,193 @@
+/*
+ * omap3-n950-n9.dtsi - Device Tree file for Nokia N950 & N9 (common stuff)
+ *
+ * Written by: Aaro Koskinen <aaro.koskinen@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "omap36xx.dtsi"
+
+/ {
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vcc>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>; /* 1 GB */
+ };
+
+ vemmc: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "VEMMC";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ gpio = <&gpio5 29 0>; /* gpio line 157 */
+ startup-delay-us = <150>;
+ enable-active-high;
+ };
+};
+
+&omap3_pmx_core {
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ 0x128 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk */
+ 0x12a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd */
+ 0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0 */
+ 0x12e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1 */
+ 0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2 */
+ 0x132 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3 */
+ >;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <2900000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+ };
+};
+
+/include/ "twl4030.dtsi"
+
+&twl {
+ compatible = "ti,twl5031";
+
+ twl_power: power {
+ compatible = "ti,twl4030-power";
+ ti,use_poweroff;
+ };
+};
+
+&twl_gpio {
+ ti,pullups = <0x000001>; /* BIT(0) */
+ ti,pulldowns = <0x008106>; /* BIT(1) | BIT(2) | BIT(8) | BIT(15) */
+};
+
+/* CSI-2 receiver */
+&vaux2 {
+ regulator-name = "vaux2";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+};
+
+/* Cameras */
+&vaux3 {
+ regulator-name = "vaux3";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+};
+
+&mmc1 {
+ status = "disabled";
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+ vmmc-supply = <&vemmc>;
+ bus-width = <4>;
+ ti,non-removable;
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&usb_otg_hs {
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ phys = <&usb2_phy>;
+ phy-names = "usb2-phy";
+ mode = <3>;
+ power = <50>;
+};
+
+&gpmc {
+ ranges = <0 0 0x04000000 0x1000000>; /* CS0: 16MB for OneNAND */
+
+ onenand@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0 0x20000>; /* CS0, offset 0, IO size 128K */
+
+ gpmc,sync-read;
+ gpmc,sync-write;
+ gpmc,burst-length = <16>;
+ gpmc,burst-read;
+ gpmc,burst-wrap;
+ gpmc,burst-write;
+ gpmc,device-width = <2>;
+ gpmc,mux-add-data = <2>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <87>;
+ gpmc,cs-wr-off-ns = <87>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <10>;
+ gpmc,adv-wr-off-ns = <10>;
+ gpmc,oe-on-ns = <15>;
+ gpmc,oe-off-ns = <87>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <87>;
+ gpmc,rd-cycle-ns = <112>;
+ gpmc,wr-cycle-ns = <112>;
+ gpmc,access-ns = <81>;
+ gpmc,page-burst-access-ns = <15>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,clk-activation-ns = <5>;
+ gpmc,wr-data-mux-bus-ns = <30>;
+ gpmc,wr-access-ns = <81>;
+ gpmc,sync-clk-ps = <15000>;
+
+ /*
+ * MTD partition table corresponding to Nokia's MeeGo 1.2
+ * Harmattan release.
+ */
+ partition@0 {
+ label = "bootloader";
+ reg = <0x00000000 0x00100000>;
+ };
+ partition@1 {
+ label = "config";
+ reg = <0x00100000 0x002c0000>;
+ };
+ partition@2 {
+ label = "kernel";
+ reg = <0x003c0000 0x01000000>;
+ };
+ partition@3 {
+ label = "log";
+ reg = <0x013c0000 0x00200000>;
+ };
+ partition@4 {
+ label = "var";
+ reg = <0x015c0000 0x1ca40000>;
+ };
+ partition@5 {
+ label = "moslo";
+ reg = <0x1e000000 0x02000000>;
+ };
+ partition@6 {
+ label = "omap2-onenand";
+ reg = <0x00000000 0x20000000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-n950.dts b/arch/arm/boot/dts/omap3-n950.dts
new file mode 100644
index 000000000..0885b34d5
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-n950.dts
@@ -0,0 +1,55 @@
+/*
+ * omap3-n950.dts - Device Tree file for Nokia N950
+ *
+ * Written by: Aaro Koskinen <aaro.koskinen@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+#include "omap3-n950-n9.dtsi"
+
+/ {
+ model = "Nokia N950";
+ compatible = "nokia,omap3-n950", "ti,omap36xx", "ti,omap3";
+};
+
+&i2c2 {
+ smia_1: camera@10 {
+ compatible = "nokia,smia";
+ reg = <0x10>;
+ /* No reset gpio */
+ vana-supply = <&vaux3>;
+ clocks = <&isp 0>;
+ clock-frequency = <9600000>;
+ nokia,nvm-size = <(16 * 64)>;
+ port {
+ smia_1_1: endpoint {
+ link-frequencies = /bits/ 64 <210000000 333600000 398400000>;
+ clock-lanes = <0>;
+ data-lanes = <1 2>;
+ remote-endpoint = <&csi2a_ep>;
+ };
+ };
+ };
+};
+
+&isp {
+ vdd-csiphy1-supply = <&vaux2>;
+ vdd-csiphy2-supply = <&vaux2>;
+ ports {
+ port@2 {
+ reg = <2>;
+ csi2a_ep: endpoint {
+ remote-endpoint = <&smia_1_1>;
+ clock-lanes = <2>;
+ data-lanes = <3 1>;
+ crc = <1>;
+ lane-polarities = <1 1 1>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-overo-alto35-common.dtsi b/arch/arm/boot/dts/omap3-overo-alto35-common.dtsi
new file mode 100644
index 000000000..7aae8fb82
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-alto35-common.dtsi
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Alto35 expansion board is manufactured by Gumstix Inc.
+ */
+
+#include "omap3-overo-common-peripherals.dtsi"
+#include "omap3-overo-common-lcd35.dtsi"
+
+#include <dt-bindings/input/input.h>
+
+/ {
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+ gpio148 {
+ label = "overo:red:gpio148";
+ gpios = <&gpio5 20 GPIO_ACTIVE_HIGH>; /* gpio 148 */
+ };
+ gpio150 {
+ label = "overo:yellow:gpio150";
+ gpios = <&gpio5 22 GPIO_ACTIVE_HIGH>; /* gpio 150 */
+ };
+ gpio151 {
+ label = "overo:blue:gpio151";
+ gpios = <&gpio5 23 GPIO_ACTIVE_HIGH>; /* gpio 151 */
+ };
+ gpio170 {
+ label = "overo:green:gpio170";
+ gpios = <&gpio6 10 GPIO_ACTIVE_HIGH>; /* gpio 170 */
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&button_pins>;
+ button0@10 {
+ label = "button0";
+ linux,code = <BTN_0>;
+ gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; /* gpio_10 */
+ gpio-key,wakeup;
+ };
+ };
+};
+
+&omap3_pmx_core {
+ led_pins: pinmux_led_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE4) /* uart1_tx.gpio_148 */
+ OMAP3_CORE1_IOPAD(0x2180, PIN_OUTPUT | MUX_MODE4) /* uart1_cts.gpio_150 */
+ OMAP3_CORE1_IOPAD(0x2182, PIN_OUTPUT | MUX_MODE4) /* uart1_rx.gpio_151 */
+ OMAP3_CORE1_IOPAD(0x21c6, PIN_OUTPUT | MUX_MODE4) /* hdq_sio.gpio_170 */
+ >;
+ };
+};
+
+&omap3_pmx_wkup {
+ button_pins: pinmux_button_pins {
+ pinctrl-single,pins = <
+ OMAP3_WKUP_IOPAD(0x2a18, PIN_INPUT | MUX_MODE4) /* sys_clkout1.gpio_10 */
+ >;
+ };
+};
+
+&usbhshost {
+ status = "disabled";
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-alto35.dts b/arch/arm/boot/dts/omap3-overo-alto35.dts
new file mode 100644
index 000000000..a3249eb75
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-alto35.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Alto35 expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo.dtsi"
+#include "omap3-overo-alto35-common.dtsi"
+
+/ {
+ model = "OMAP35xx Gumstix Overo on Alto35";
+ compatible = "gumstix,omap3-overo-alto35", "gumstix,omap3-overo", "ti,omap3430", "ti,omap3";
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-base.dtsi b/arch/arm/boot/dts/omap3-overo-base.dtsi
new file mode 100644
index 000000000..18e164968
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-base.dtsi
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2012 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * The Gumstix Overo must be combined with an expansion board.
+ */
+
+/ {
+ pwmleds {
+ compatible = "pwm-leds";
+
+ overo {
+ label = "overo:blue:COM";
+ pwms = <&twl_pwmled 1 7812500>;
+ max-brightness = <127>;
+ linux,default-trigger = "mmc0";
+ };
+ };
+
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "overo";
+
+ ti,mcbsp = <&mcbsp2>;
+ };
+
+ /* HS USB Port 2 Power */
+ hsusb2_power: hsusb2_power_reg {
+ compatible = "regulator-fixed";
+ regulator-name = "hsusb2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio6 8 0>; /* gpio_168: vbus enable */
+ startup-delay-us = <70000>;
+ enable-active-high;
+ };
+
+ /* HS USB Host PHY on PORT 2 */
+ hsusb2_phy: hsusb2_phy {
+ compatible = "usb-nop-xceiv";
+ reset-gpios = <&gpio6 23 GPIO_ACTIVE_LOW>; /* gpio_183 */
+ vcc-supply = <&hsusb2_power>;
+ };
+
+ /* Regulator to trigger the nPoweron signal of the Wifi module */
+ w3cbw003c_npoweron: regulator-w3cbw003c-npoweron {
+ compatible = "regulator-fixed";
+ regulator-name = "regulator-w3cbw003c-npoweron";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 22 GPIO_ACTIVE_HIGH>; /* gpio_54: nPoweron */
+ enable-active-high;
+ };
+
+ /* Regulator to trigger the nReset signal of the Wifi module */
+ w3cbw003c_wifi_nreset: regulator-w3cbw003c-wifi-nreset {
+ pinctrl-names = "default";
+ pinctrl-0 = <&w3cbw003c_pins &w3cbw003c_2_pins>;
+ compatible = "regulator-fixed";
+ regulator-name = "regulator-w3cbw003c-wifi-nreset";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 16 GPIO_ACTIVE_HIGH>; /* gpio_16: WiFi nReset */
+ startup-delay-us = <10000>;
+ };
+
+ /* Regulator to trigger the nReset signal of the Bluetooth module */
+ w3cbw003c_bt_nreset: regulator-w3cbw003c-bt-nreset {
+ compatible = "regulator-fixed";
+ regulator-name = "regulator-w3cbw003c-bt-nreset";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio6 4 GPIO_ACTIVE_HIGH>; /* gpio_164: BT nReset */
+ startup-delay-us = <10000>;
+ };
+};
+
+&omap3_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusb2_pins
+ >;
+
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x216c, PIN_INPUT | MUX_MODE1) /* mcbsp3_dx.uart2_cts */
+ OMAP3_CORE1_IOPAD(0x216e, PIN_OUTPUT | MUX_MODE1) /* mcbsp3_dr.uart2_rts */
+ OMAP3_CORE1_IOPAD(0x2170, PIN_OUTPUT | MUX_MODE1) /* mcbsp3_clk.uart2_tx */
+ OMAP3_CORE1_IOPAD(0x2172, PIN_INPUT | MUX_MODE1) /* mcbsp3_fsx.uart2_rx */
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT | MUX_MODE0) /* i2c1_scl.i2c1_scl */
+ OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT | MUX_MODE0) /* i2c1_sda.i2c1_sda */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */
+ OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */
+ OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */
+ OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */
+ OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */
+ OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
+ >;
+ };
+
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
+ OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
+ OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
+ OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+ OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
+ OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
+ >;
+ };
+
+ /* WiFi/BT combo */
+ w3cbw003c_pins: pinmux_w3cbw003c_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20b4, PIN_OUTPUT | MUX_MODE4) /* gpmc_ncs3.gpio_54 */
+ OMAP3_CORE1_IOPAD(0x219c, PIN_OUTPUT | MUX_MODE4) /* uart3_rts_sd.gpio_164 */
+ >;
+ };
+
+ hsusb2_pins: pinmux_hsusb2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21d4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */
+ OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */
+ OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */
+ OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */
+ OMAP3_CORE1_IOPAD(0x21dc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */
+ OMAP3_CORE1_IOPAD(0x21de, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */
+ OMAP3_CORE1_IOPAD(0x21be, PIN_OUTPUT | MUX_MODE4) /* i2c2_scl.gpio_168 */
+ OMAP3_CORE1_IOPAD(0x21c0, PIN_OUTPUT | MUX_MODE4) /* i2c2_sda.gpio_183 */
+ >;
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ codec {
+ };
+ };
+ };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+/* i2c2 pins are used for gpio */
+&i2c2 {
+ status = "disabled";
+};
+
+/* on board microSD slot */
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&vmmc1>;
+ bus-width = <4>;
+};
+
+/* optional on board WiFi */
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+ vmmc-supply = <&w3cbw003c_npoweron>;
+ vqmmc-supply = <&w3cbw003c_bt_nreset>;
+ vmmc_aux-supply = <&w3cbw003c_wifi_nreset>;
+ bus-width = <4>;
+ cap-sdio-irq;
+ non-removable;
+};
+
+&twl_gpio {
+ ti,use-leds;
+};
+
+&usb_otg_hs {
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ phys = <&usb2_phy>;
+ phy-names = "usb2-phy";
+ mode = <3>;
+ power = <50>;
+};
+
+&usbhshost {
+ port2-mode = "ehci-phy";
+};
+
+&usbhsehci {
+ phys = <0 &hsusb2_phy>;
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi b/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
new file mode 100644
index 000000000..17b82f826
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Chestnut43 expansion board is manufactured by Gumstix Inc.
+ */
+
+#include "omap3-overo-common-peripherals.dtsi"
+#include "omap3-overo-common-lcd43.dtsi"
+
+#include <dt-bindings/input/input.h>
+
+/ {
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+ heartbeat {
+ label = "overo:red:gpio21";
+ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>; /* gpio_21 */
+ linux,default-trigger = "heartbeat";
+ };
+ gpio22 {
+ label = "overo:blue:gpio22";
+ gpios = <&gpio1 22 GPIO_ACTIVE_LOW>; /* gpio_22 */
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&button_pins>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ button0@23 {
+ label = "button0";
+ linux,code = <BTN_0>;
+ gpios = <&gpio1 23 GPIO_ACTIVE_LOW>; /* gpio_23 */
+ gpio-key,wakeup;
+ };
+ button1@14 {
+ label = "button1";
+ linux,code = <BTN_1>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; /* gpio_14 */
+ gpio-key,wakeup;
+ };
+ };
+};
+
+#include "omap-gpmc-smsc9221.dtsi"
+
+&gpmc {
+ ranges = <5 0 0x2c000000 0x1000000>; /* CS5 */
+
+ ethernet@gpmc {
+ reg = <5 0 0xff>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <16 IRQ_TYPE_LEVEL_LOW>; /* GPIO 176 */
+ };
+};
+
+&lis33de {
+ status = "disabled";
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-chestnut43.dts b/arch/arm/boot/dts/omap3-overo-chestnut43.dts
new file mode 100644
index 000000000..fe0824aca
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-chestnut43.dts
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Chestnut43 expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo.dtsi"
+#include "omap3-overo-chestnut43-common.dtsi"
+
+/ {
+ model = "OMAP35xx Gumstix Overo on Chestnut43";
+ compatible = "gumstix,omap3-overo-chestnut43", "gumstix,omap3-overo", "ti,omap3430", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+ led_pins: pinmux_led_pins {
+ pinctrl-single,pins = <
+ OMAP3430_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4) /* etk_d7.gpio_21 */
+ OMAP3430_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4) /* etk_d8.gpio_22 */
+ >;
+ };
+
+ button_pins: pinmux_button_pins {
+ pinctrl-single,pins = <
+ OMAP3430_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE4) /* etk_d9.gpio_23 */
+ OMAP3430_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE4) /* etk_d0.gpio_14 */
+ >;
+ };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-common-dvi.dtsi b/arch/arm/boot/dts/omap3-overo-common-dvi.dtsi
new file mode 100644
index 000000000..802f704f6
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-common-dvi.dtsi
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * DVI output for some Gumstix Overo boards (Tobi and Summit)
+ */
+
+&omap3_pmx_core {
+ dss_dpi_pins: pinmux_dss_dpi_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */
+ OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */
+ OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */
+ OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */
+ OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE0) /* dss_data0.dss_data0 */
+ OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT | MUX_MODE0) /* dss_data1.dss_data1 */
+ OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT | MUX_MODE0) /* dss_data2.dss_data2 */
+ OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE0) /* dss_data3.dss_data3 */
+ OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE0) /* dss_data4.dss_data4 */
+ OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE0) /* dss_data5.dss_data5 */
+ OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */
+ OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */
+ OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */
+ OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */
+ OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */
+ OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */
+ OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */
+ OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */
+ OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */
+ OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */
+ OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */
+ OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */
+ OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE0) /* dss_data18.dss_data18 */
+ OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE0) /* dss_data19.dss_data19 */
+ OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE0) /* dss_data20.dss_data20 */
+ OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE0) /* dss_data21.dss_data21 */
+ OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE0) /* dss_data22.dss_data22 */
+ OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */
+ >;
+ };
+};
+
+/* Needed to power the DPI pins */
+&vpll2 {
+ regulator-always-on;
+};
+
+&dss {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_dpi_pins>;
+
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&tfp410_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+/ {
+ aliases {
+ display0 = &dvi0;
+ };
+
+ tfp410: encoder@0 {
+ compatible = "ti,tfp410";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ tfp410_in: endpoint@0 {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ tfp410_out: endpoint@0 {
+ remote-endpoint = <&dvi_connector_in>;
+ };
+ };
+ };
+ };
+
+ dvi0: connector@0 {
+ compatible = "dvi-connector";
+ label = "dvi";
+
+ digital;
+ ddc-i2c-bus = <&i2c3>;
+
+ port {
+ dvi_connector_in: endpoint {
+ remote-endpoint = <&tfp410_out>;
+ };
+ };
+ };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi b/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi
new file mode 100644
index 000000000..233c69e50
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * 4.3'' LCD panel output for some Gumstix Overo boards (Gallop43, Chestnut43)
+ */
+
+&omap3_pmx_core {
+ dss_dpi_pins: pinmux_dss_dpi_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */
+ OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */
+ OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */
+ OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */
+ OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE0) /* dss_data0.dss_data0 */
+ OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT | MUX_MODE0) /* dss_data1.dss_data1 */
+ OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT | MUX_MODE0) /* dss_data2.dss_data2 */
+ OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE0) /* dss_data3.dss_data3 */
+ OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE0) /* dss_data4.dss_data4 */
+ OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE0) /* dss_data5.dss_data5 */
+ OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */
+ OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */
+ OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */
+ OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */
+ OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */
+ OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */
+ OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */
+ OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */
+ OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */
+ OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */
+ OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */
+ OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */
+ OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE0) /* dss_data18.dss_data18 */
+ OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE0) /* dss_data19.dss_data19 */
+ OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE0) /* dss_data20.dss_data20 */
+ OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE0) /* dss_data21.dss_data21 */
+ OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE0) /* dss_data22.dss_data22 */
+ OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */
+ >;
+ };
+
+ lb035_pins: pinmux_lb035_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2174, PIN_OUTPUT | MUX_MODE4) /* uart2_cts.gpio_144 */
+ >;
+ };
+
+ backlight_pins: pinmux_backlight_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE4) /* uart2_rts.gpio_145 */
+ >;
+ };
+
+ mcspi1_pins: pinmux_mcspi1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21c8, PIN_INPUT | MUX_MODE0) /* mcspi1_clk.mcspi1_clk */
+ OMAP3_CORE1_IOPAD(0x21ca, PIN_INPUT | MUX_MODE0) /* mcspi1_simo.mcspi1_simo */
+ OMAP3_CORE1_IOPAD(0x21cc, PIN_INPUT | MUX_MODE0) /* mcspi1_somi.mcspi1_somi */
+ OMAP3_CORE1_IOPAD(0x21ce, PIN_INPUT | MUX_MODE0) /* mcspi1_cs0.mcspi1_cs0 */
+ >;
+ };
+
+ ads7846_pins: pinmux_ads7846_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2138, PIN_INPUT_PULLDOWN | MUX_MODE4) /* csi2_dx1.gpio_114 */
+ >;
+ };
+};
+
+/* Needed to power the DPI pins */
+&vpll2 {
+ regulator-always-on;
+};
+
+&dss {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_dpi_pins>;
+
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+/ {
+ aliases {
+ display0 = &lcd0;
+ };
+
+ ads7846reg: ads7846-reg {
+ compatible = "regulator-fixed";
+ regulator-name = "ads7846-reg";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ backlight {
+ compatible = "gpio-backlight";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&backlight_pins>;
+ gpios = <&gpio5 17 GPIO_ACTIVE_HIGH>; /* gpio_145 */
+
+ default-on;
+ };
+};
+
+&mcspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi1_pins>;
+
+ lcd0: display@0 {
+ compatible = "lgphilips,lb035q02";
+ label = "lcd";
+
+ reg = <1>; /* CS1 */
+ spi-max-frequency = <10000000>;
+ spi-cpol;
+ spi-cpha;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&lb035_pins>;
+ enable-gpios = <&gpio5 16 GPIO_ACTIVE_HIGH>; /* gpio_144 */
+
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+ };
+
+ /* touch controller */
+ ads7846@0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ads7846_pins>;
+
+ compatible = "ti,ads7846";
+ vcc-supply = <&ads7846reg>;
+
+ reg = <0>; /* CS0 */
+ spi-max-frequency = <1500000>;
+
+ interrupt-parent = <&gpio4>;
+ interrupts = <18 0>; /* gpio_114 */
+ pendown-gpio = <&gpio4 18 0>;
+
+ ti,x-min = /bits/ 16 <0x0>;
+ ti,x-max = /bits/ 16 <0x0fff>;
+ ti,y-min = /bits/ 16 <0x0>;
+ ti,y-max = /bits/ 16 <0x0fff>;
+ ti,x-plate-ohms = /bits/ 16 <180>;
+ ti,pressure-max = /bits/ 16 <255>;
+
+ linux,wakeup;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi b/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi
new file mode 100644
index 000000000..f5395b7da
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * 4.3'' LCD panel output for some Gumstix Overo boards (Gallop43, Chestnut43)
+ */
+
+&omap3_pmx_core {
+ dss_dpi_pins: pinmux_dss_dpi_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */
+ OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */
+ OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */
+ OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */
+ OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE0) /* dss_data0.dss_data0 */
+ OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT | MUX_MODE0) /* dss_data1.dss_data1 */
+ OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT | MUX_MODE0) /* dss_data2.dss_data2 */
+ OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE0) /* dss_data3.dss_data3 */
+ OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE0) /* dss_data4.dss_data4 */
+ OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE0) /* dss_data5.dss_data5 */
+ OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */
+ OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */
+ OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */
+ OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */
+ OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */
+ OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */
+ OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */
+ OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */
+ OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */
+ OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */
+ OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */
+ OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */
+ OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE0) /* dss_data18.dss_data18 */
+ OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE0) /* dss_data19.dss_data19 */
+ OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE0) /* dss_data20.dss_data20 */
+ OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE0) /* dss_data21.dss_data21 */
+ OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE0) /* dss_data22.dss_data22 */
+ OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */
+ >;
+ };
+
+ lte430_pins: pinmux_lte430_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2174, PIN_OUTPUT | MUX_MODE4) /* uart2_cts.gpio_144 */
+ >;
+ };
+
+ backlight_pins: pinmux_backlight_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE4) /* uart2_rts.gpio_145 */
+ >;
+ };
+
+ mcspi1_pins: pinmux_mcspi1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21c8, PIN_INPUT | MUX_MODE0) /* mcspi1_clk.mcspi1_clk */
+ OMAP3_CORE1_IOPAD(0x21ca, PIN_INPUT | MUX_MODE0) /* mcspi1_simo.mcspi1_simo */
+ OMAP3_CORE1_IOPAD(0x21cc, PIN_INPUT | MUX_MODE0) /* mcspi1_somi.mcspi1_somi */
+ OMAP3_CORE1_IOPAD(0x21ce, PIN_INPUT | MUX_MODE0) /* mcspi1_cs0.mcspi1_cs0 */
+ >;
+ };
+
+ ads7846_pins: pinmux_ads7846_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2138, PIN_INPUT_PULLDOWN | MUX_MODE4) /* csi2_dx1.gpio_114 */
+ >;
+ };
+};
+
+/* Needed to power the DPI pins */
+&vpll2 {
+ regulator-always-on;
+};
+
+&dss {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_dpi_pins>;
+
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+/ {
+ aliases {
+ display0 = &lcd0;
+ };
+
+ lcd0: display@0 {
+ compatible = "samsung,lte430wq-f0c", "panel-dpi";
+ label = "lcd";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&lte430_pins>;
+ enable-gpios = <&gpio5 16 GPIO_ACTIVE_HIGH>; /* gpio_144 */
+
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+
+ panel-timing {
+ clock-frequency = <9200000>;
+ hactive = <480>;
+ vactive = <272>;
+ hfront-porch = <8>;
+ hback-porch = <4>;
+ hsync-len = <41>;
+ vback-porch = <2>;
+ vfront-porch = <4>;
+ vsync-len = <10>;
+
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+
+ ads7846reg: ads7846-reg {
+ compatible = "regulator-fixed";
+ regulator-name = "ads7846-reg";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ backlight {
+ compatible = "gpio-backlight";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&backlight_pins>;
+ gpios = <&gpio5 17 GPIO_ACTIVE_HIGH>; /* gpio_145 */
+
+ default-on;
+ };
+};
+
+&mcspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi1_pins>;
+
+ /* touch controller */
+ ads7846@0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ads7846_pins>;
+
+ compatible = "ti,ads7846";
+ vcc-supply = <&ads7846reg>;
+
+ reg = <0>; /* CS0 */
+ spi-max-frequency = <1500000>;
+
+ interrupt-parent = <&gpio4>;
+ interrupts = <18 0>; /* gpio_114 */
+ pendown-gpio = <&gpio4 18 0>;
+
+ ti,x-min = /bits/ 16 <0x0>;
+ ti,x-max = /bits/ 16 <0x0fff>;
+ ti,y-min = /bits/ 16 <0x0>;
+ ti,y-max = /bits/ 16 <0x0fff>;
+ ti,x-plate-ohms = /bits/ 16 <180>;
+ ti,pressure-max = /bits/ 16 <255>;
+
+ linux,wakeup;
+ };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-common-peripherals.dtsi b/arch/arm/boot/dts/omap3-overo-common-peripherals.dtsi
new file mode 100644
index 000000000..520453d95
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-common-peripherals.dtsi
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Peripherals common to all Gumstix Overo boards (Tobi, Summit, Palo43,...)
+ */
+
+/ {
+ lis33_3v3: lis33-3v3-reg {
+ compatible = "regulator-fixed";
+ regulator-name = "lis33-3v3-reg";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ lis33_1v8: lis33-1v8-reg {
+ compatible = "regulator-fixed";
+ regulator-name = "lis33-1v8-reg";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+};
+
+&omap3_pmx_core {
+ i2c3_pins: pinmux_i2c3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT | MUX_MODE0) /* i2c3_scl.i2c3_scl */
+ OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT | MUX_MODE0) /* i2c3_sda.i2c3_sda */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+ OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */
+ >;
+ };
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+ clock-frequency = <100000>;
+
+ /* optional 1K EEPROM with revision information */
+ eeprom@51 {
+ compatible = "atmel,24c01";
+ reg = <0x51>;
+ pagesize = <8>;
+ };
+
+ lis33de: lis33de@1d {
+ compatible = "st,lis33de", "st,lis3lv02d";
+ reg = <0x1d>;
+ Vdd-supply = <&lis33_1v8>;
+ Vdd_IO-supply = <&lis33_3v3>;
+
+ st,click-single-x;
+ st,click-single-y;
+ st,click-single-z;
+ st,click-thresh-x = <10>;
+ st,click-thresh-y = <10>;
+ st,click-thresh-z = <10>;
+ st,irq1-click;
+ st,irq2-click;
+ st,wakeup-x-lo;
+ st,wakeup-x-hi;
+ st,wakeup-y-lo;
+ st,wakeup-y-hi;
+ st,wakeup-z-lo;
+ st,wakeup-z-hi;
+ st,min-limit-x = <120>;
+ st,min-limit-y = <120>;
+ st,min-limit-z = <140>;
+ st,max-limit-x = <550>;
+ st,max-limit-y = <550>;
+ st,max-limit-z = <750>;
+ };
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&uart3 {
+ interrupts-extended = <&intc 74 &omap3_pmx_core OMAP3_UART3_RX>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-gallop43-common.dtsi b/arch/arm/boot/dts/omap3-overo-gallop43-common.dtsi
new file mode 100644
index 000000000..49d2254a9
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-gallop43-common.dtsi
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Gallop43 expansion board is manufactured by Gumstix Inc.
+ */
+
+#include "omap3-overo-common-peripherals.dtsi"
+#include "omap3-overo-common-lcd43.dtsi"
+
+#include <dt-bindings/input/input.h>
+
+/ {
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+ heartbeat {
+ label = "overo:red:gpio21";
+ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>; /* gpio_21 */
+ linux,default-trigger = "heartbeat";
+ };
+ gpio22 {
+ label = "overo:blue:gpio22";
+ gpios = <&gpio1 22 GPIO_ACTIVE_LOW>; /* gpio_22 */
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&button_pins>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ button0@23 {
+ label = "button0";
+ linux,code = <BTN_0>;
+ gpios = <&gpio1 23 GPIO_ACTIVE_LOW>; /* gpio_23 */
+ gpio-key,wakeup;
+ };
+ button1@14 {
+ label = "button1";
+ linux,code = <BTN_1>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; /* gpio_14 */
+ gpio-key,wakeup;
+ };
+ };
+};
+
+&usbhshost {
+ status = "disabled";
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-gallop43.dts b/arch/arm/boot/dts/omap3-overo-gallop43.dts
new file mode 100644
index 000000000..241f5c191
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-gallop43.dts
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Gallop43 expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo.dtsi"
+#include "omap3-overo-gallop43-common.dtsi"
+
+/ {
+ model = "OMAP35xx Gumstix Overo on Gallop43";
+ compatible = "gumstix,omap3-overo-gallop43", "gumstix,omap3-overo", "ti,omap3430", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+ led_pins: pinmux_led_pins {
+ pinctrl-single,pins = <
+ OMAP3430_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4) /* etk_d7.gpio_21 */
+ OMAP3430_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4) /* etk_d8.gpio_22 */
+ >;
+ };
+
+ button_pins: pinmux_button_pins {
+ pinctrl-single,pins = <
+ OMAP3430_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE4) /* etk_d9.gpio_23 */
+ OMAP3430_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE4) /* etk_d0.gpio_14 */
+ >;
+ };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-palo43-common.dtsi b/arch/arm/boot/dts/omap3-overo-palo43-common.dtsi
new file mode 100644
index 000000000..087aedf5b
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-palo43-common.dtsi
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Palo43 expansion board is manufactured by Gumstix Inc.
+ */
+
+#include "omap3-overo-common-peripherals.dtsi"
+#include "omap3-overo-common-lcd43.dtsi"
+
+#include <dt-bindings/input/input.h>
+
+/ {
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+ heartbeat {
+ label = "overo:red:gpio21";
+ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>; /* gpio_21 */
+ linux,default-trigger = "heartbeat";
+ };
+ gpio22 {
+ label = "overo:blue:gpio22";
+ gpios = <&gpio1 22 GPIO_ACTIVE_LOW>; /* gpio_22 */
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&button_pins>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ button0@23 {
+ label = "button0";
+ linux,code = <BTN_0>;
+ gpios = <&gpio1 23 GPIO_ACTIVE_LOW>; /* gpio_23 */
+ gpio-key,wakeup;
+ };
+ button1@14 {
+ label = "button1";
+ linux,code = <BTN_1>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; /* gpio_14 */
+ gpio-key,wakeup;
+ };
+ };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-palo43.dts b/arch/arm/boot/dts/omap3-overo-palo43.dts
new file mode 100644
index 000000000..cedb103b4
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-palo43.dts
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Palo43 expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo.dtsi"
+#include "omap3-overo-palo43-common.dtsi"
+
+/ {
+ model = "OMAP35xx Gumstix Overo on Palo43";
+ compatible = "gumstix,omap3-overo-palo43", "gumstix,omap3-overo", "ti,omap3430", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+ led_pins: pinmux_led_pins {
+ pinctrl-single,pins = <
+ OMAP3430_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4) /* etk_d7.gpio_21 */
+ OMAP3430_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4) /* etk_d8.gpio_22 */
+ >;
+ };
+
+ button_pins: pinmux_button_pins {
+ pinctrl-single,pins = <
+ OMAP3430_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE4) /* etk_d9.gpio_23 */
+ OMAP3430_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE4) /* etk_d0.gpio_14 */
+ >;
+ };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-storm-alto35.dts b/arch/arm/boot/dts/omap3-overo-storm-alto35.dts
new file mode 100644
index 000000000..e9cae52af
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-storm-alto35.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Alto35 expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo-storm.dtsi"
+#include "omap3-overo-alto35-common.dtsi"
+
+/ {
+ model = "OMAP36xx/AM37xx/DM37xx Gumstix Overo on Alto35";
+ compatible = "gumstix,omap3-overo-alto35", "gumstix,omap3-overo", "ti,omap36xx", "ti,omap3";
+};
diff --git a/arch/arm/boot/dts/omap3-overo-storm-chestnut43.dts b/arch/arm/boot/dts/omap3-overo-storm-chestnut43.dts
new file mode 100644
index 000000000..7d82fdfd9
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-storm-chestnut43.dts
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Chestnut43 expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo-storm.dtsi"
+#include "omap3-overo-chestnut43-common.dtsi"
+
+/ {
+ model = "OMAP36xx/AM37xx/DM37xx Gumstix Overo on Chestnut43";
+ compatible = "gumstix,omap3-overo-chestnut43", "gumstix,omap3-overo", "ti,omap36xx", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+ led_pins: pinmux_led_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4) /* etk_d7.gpio_21 */
+ OMAP3630_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4) /* etk_d8.gpio_22 */
+ >;
+ };
+
+ button_pins: pinmux_button_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE4) /* etk_d9.gpio_23 */
+ OMAP3630_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE4) /* etk_d0.gpio_14 */
+ >;
+ };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-storm-gallop43.dts b/arch/arm/boot/dts/omap3-overo-storm-gallop43.dts
new file mode 100644
index 000000000..a1b57e0cf
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-storm-gallop43.dts
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Gallop43 expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo-storm.dtsi"
+#include "omap3-overo-gallop43-common.dtsi"
+
+/ {
+ model = "OMAP36xx/AM37xx/DM37xx Gumstix Overo on Gallop43";
+ compatible = "gumstix,omap3-overo-gallop43", "gumstix,omap3-overo", "ti,omap36xx", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+ led_pins: pinmux_led_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4) /* etk_d7.gpio_21 */
+ OMAP3630_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4) /* etk_d8.gpio_22 */
+ >;
+ };
+
+ button_pins: pinmux_button_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE4) /* etk_d9.gpio_23 */
+ OMAP3630_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE4) /* etk_d0.gpio_14 */
+ >;
+ };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-storm-palo43.dts b/arch/arm/boot/dts/omap3-overo-storm-palo43.dts
new file mode 100644
index 000000000..b585d8fbc
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-storm-palo43.dts
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Palo43 expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo-storm.dtsi"
+#include "omap3-overo-palo43-common.dtsi"
+
+/ {
+ model = "OMAP36xx/AM37xx/DM37xx Gumstix Overo on Palo43";
+ compatible = "gumstix,omap3-overo-palo43", "gumstix,omap3-overo", "ti,omap36xx", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+ led_pins: pinmux_led_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4) /* etk_d7.gpio_21 */
+ OMAP3630_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4) /* etk_d8.gpio_22 */
+ >;
+ };
+
+ button_pins: pinmux_button_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE4) /* etk_d9.gpio_23 */
+ OMAP3630_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE4) /* etk_d0.gpio_14 */
+ >;
+ };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-storm-summit.dts b/arch/arm/boot/dts/omap3-overo-storm-summit.dts
new file mode 100644
index 000000000..a0d7fd836
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-storm-summit.dts
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Summit expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo-storm.dtsi"
+#include "omap3-overo-summit-common.dtsi"
+
+/ {
+ model = "OMAP36xx/AM37xx/DM37xx Gumstix Overo on Summit";
+ compatible = "gumstix,omap3-overo-summit", "gumstix,omap3-overo", "ti,omap36xx", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+ led_pins: pinmux_led_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4) /* etk_d7.gpio_21 */
+ >;
+ };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-storm-tobi.dts b/arch/arm/boot/dts/omap3-overo-storm-tobi.dts
new file mode 100644
index 000000000..879383aca
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-storm-tobi.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Tobi expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo-storm.dtsi"
+#include "omap3-overo-tobi-common.dtsi"
+
+/ {
+ model = "OMAP36xx/AM37xx/DM37xx Gumstix Overo on Tobi";
+ compatible = "gumstix,omap3-overo-tobi", "gumstix,omap3-overo", "ti,omap36xx", "ti,omap3";
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-storm.dtsi b/arch/arm/boot/dts/omap3-overo-storm.dtsi
new file mode 100644
index 000000000..6cb418b41
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-storm.dtsi
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "omap36xx.dtsi"
+#include "omap3-overo-base.dtsi"
+
+&omap3_pmx_core2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusb2_2_pins
+ >;
+
+ hsusb2_2_pins: pinmux_hsusb2_2_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */
+ OMAP3630_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */
+ OMAP3630_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */
+ OMAP3630_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */
+ OMAP3630_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */
+ OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */
+ >;
+ };
+
+ w3cbw003c_2_pins: pinmux_w3cbw003c_2_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25e0, PIN_OUTPUT | MUX_MODE4) /* etk_d2.gpio_16 */
+ >;
+ };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-summit-common.dtsi b/arch/arm/boot/dts/omap3-overo-summit-common.dtsi
new file mode 100644
index 000000000..0ac97ba98
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-summit-common.dtsi
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Summit expansion board is manufactured by Gumstix Inc.
+ */
+
+#include "omap3-overo-common-peripherals.dtsi"
+#include "omap3-overo-common-dvi.dtsi"
+
+/ {
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+ heartbeat {
+ label = "overo:red:gpio21";
+ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>; /* gpio_21 */
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
+
+&lis33de {
+ status = "disabled";
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-summit.dts b/arch/arm/boot/dts/omap3-overo-summit.dts
new file mode 100644
index 000000000..697656094
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-summit.dts
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Summit expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo.dtsi"
+#include "omap3-overo-summit-common.dtsi"
+
+/ {
+ model = "OMAP35xx Gumstix Overo on Summit";
+ compatible = "gumstix,omap3-overo-summit", "gumstix,omap3-overo", "ti,omap3430", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+ led_pins: pinmux_led_pins {
+ pinctrl-single,pins = <
+ OMAP3430_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4) /* etk_d7.gpio_21 */
+ >;
+ };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi b/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi
new file mode 100644
index 000000000..9e24b6a1d
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Tobi expansion board is manufactured by Gumstix Inc.
+ */
+
+#include "omap3-overo-common-peripherals.dtsi"
+#include "omap3-overo-common-dvi.dtsi"
+
+/ {
+ leds {
+ compatible = "gpio-leds";
+ heartbeat {
+ label = "overo:red:gpio21";
+ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
+
+#include "omap-gpmc-smsc9221.dtsi"
+
+&gpmc {
+ ranges = <5 0 0x2c000000 0x1000000>; /* CS5 */
+
+ ethernet@gpmc {
+ reg = <5 0 0xff>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <16 IRQ_TYPE_LEVEL_LOW>; /* GPIO 176 */
+ };
+};
+
+&lis33de {
+ status = "disabled";
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-tobi.dts b/arch/arm/boot/dts/omap3-overo-tobi.dts
new file mode 100644
index 000000000..fd6400efc
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo-tobi.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Tobi expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo.dtsi"
+#include "omap3-overo-tobi-common.dtsi"
+
+/ {
+ model = "OMAP35xx Gumstix Overo on Tobi";
+ compatible = "gumstix,omap3-overo-tobi", "gumstix,omap3-overo", "ti,omap3430", "ti,omap3";
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo.dtsi b/arch/arm/boot/dts/omap3-overo.dtsi
new file mode 100644
index 000000000..69ca7c45b
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo.dtsi
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "omap34xx.dtsi"
+#include "omap3-overo-base.dtsi"
+
+&omap3_pmx_core2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusb2_2_pins
+ >;
+
+ hsusb2_2_pins: pinmux_hsusb2_2_pins {
+ pinctrl-single,pins = <
+ OMAP3430_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */
+ OMAP3430_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */
+ OMAP3430_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */
+ OMAP3430_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */
+ OMAP3430_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */
+ OMAP3430_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */
+ >;
+ };
+
+ w3cbw003c_2_pins: pinmux_w3cbw003c_2_pins {
+ pinctrl-single,pins = <
+ OMAP3430_CORE2_IOPAD(0x25e0, PIN_OUTPUT | MUX_MODE4) /* etk_d2.gpio_16 */
+ >;
+ };
+};
+
+&mcbsp2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/omap3-pandora-1ghz.dts b/arch/arm/boot/dts/omap3-pandora-1ghz.dts
new file mode 100644
index 000000000..9619a28df
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-pandora-1ghz.dts
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2015
+ * Nikolaus Schaller <hns@goldelico.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.
+ */
+
+/*
+ * device tree for OpenPandora 1GHz with DM3730
+ */
+
+/dts-v1/;
+
+#include "omap36xx.dtsi"
+#include "omap3-pandora-common.dtsi"
+
+/ {
+ model = "Pandora Handheld Console 1GHz";
+
+ compatible = "ti,omap36xx", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusb2_2_pins
+ &control_pins
+ >;
+
+ hsusb2_2_pins: pinmux_hsusb2_2_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */
+ OMAP3630_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */
+ OMAP3630_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */
+ OMAP3630_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */
+ OMAP3630_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */
+ OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */
+ >;
+ };
+
+ mmc3_pins: pinmux_mmc3_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25d8, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_clk.sdmmc3_clk */
+ OMAP3630_CORE2_IOPAD(0x25da, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_ctl.sdmmc3_cmd */
+ OMAP3630_CORE2_IOPAD(0x25e2, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d3.sdmmc3_dat3 */
+ OMAP3630_CORE2_IOPAD(0x25e4, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d4.sdmmc3_dat0 */
+ OMAP3630_CORE2_IOPAD(0x25e6, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d5.sdmmc3_dat1 */
+ OMAP3630_CORE2_IOPAD(0x25e8, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d6.sdmmc3_dat2 */
+ >;
+ };
+
+ control_pins: pinmux_control_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25dc, PIN_INPUT_PULLDOWN | MUX_MODE4) /* etk_d0.gpio_14 = HP_SHUTDOWN */
+ OMAP3630_CORE2_IOPAD(0x25de, PIN_OUTPUT | MUX_MODE4) /* etk_d1.gpio_15 = BT_SHUTDOWN */
+ OMAP3630_CORE2_IOPAD(0x25e0, PIN_OUTPUT | MUX_MODE4) /* etk_d2.gpio_16 = RESET_USB_HOST */
+ OMAP3630_CORE2_IOPAD(0x25ea, PIN_INPUT | MUX_MODE4) /* etk_d7.gpio_21 = WIFI IRQ */
+ OMAP3630_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4) /* etk_d8.gpio_22 = MSECURE */
+ OMAP3630_CORE2_IOPAD(0x25ee, PIN_OUTPUT | MUX_MODE4) /* etk_d9.gpio_23 = WIFI_POWER */
+ OMAP3_WKUP_IOPAD(0x2a54, PIN_INPUT | MUX_MODE4) /* reserved.gpio_127 = MMC2_WP */
+ OMAP3_WKUP_IOPAD(0x2a56, PIN_INPUT | MUX_MODE4) /* reserved.gpio_126 = MMC1_WP */
+ OMAP3_WKUP_IOPAD(0x2a58, PIN_OUTPUT | MUX_MODE4) /* reserved.gpio_128 = LED_MMC1 */
+ OMAP3_WKUP_IOPAD(0x2a5a, PIN_OUTPUT | MUX_MODE4) /* reserved.gpio_129 = LED_MMC2 */
+
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-pandora-600mhz.dts b/arch/arm/boot/dts/omap3-pandora-600mhz.dts
new file mode 100644
index 000000000..fb803a70a
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-pandora-600mhz.dts
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015
+ * Nikolaus Schaller <hns@goldelico.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.
+ */
+
+/*
+ * device tree for OpenPandora with OMAP3530
+ */
+
+/dts-v1/;
+
+#include "omap34xx.dtsi"
+#include "omap3-pandora-common.dtsi"
+
+/ {
+ model = "Pandora Handheld Console";
+
+ compatible = "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusb2_2_pins
+ &control_pins
+ >;
+
+ hsusb2_2_pins: pinmux_hsusb2_2_pins {
+ pinctrl-single,pins = <
+ OMAP3430_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */
+ OMAP3430_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */
+ OMAP3430_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */
+ OMAP3430_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */
+ OMAP3430_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */
+ OMAP3430_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */
+ >;
+ };
+
+ mmc3_pins: pinmux_mmc3_pins {
+ pinctrl-single,pins = <
+ OMAP3430_CORE2_IOPAD(0x25d8, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_clk.sdmmc3_clk */
+ OMAP3430_CORE2_IOPAD(0x25da, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_ctl.sdmmc3_cmd */
+ OMAP3430_CORE2_IOPAD(0x25e2, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d3.sdmmc3_dat3 */
+ OMAP3430_CORE2_IOPAD(0x25e4, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d4.sdmmc3_dat0 */
+ OMAP3430_CORE2_IOPAD(0x25e6, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d5.sdmmc3_dat1 */
+ OMAP3430_CORE2_IOPAD(0x25e8, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d6.sdmmc3_dat2 */
+ >;
+ };
+
+ control_pins: pinmux_control_pins {
+ pinctrl-single,pins = <
+ OMAP3430_CORE2_IOPAD(0x25dc, PIN_INPUT_PULLDOWN | MUX_MODE4) /* etk_d0.gpio_14 = HP_SHUTDOWN */
+ OMAP3430_CORE2_IOPAD(0x25de, PIN_OUTPUT | MUX_MODE4) /* etk_d1.gpio_15 = BT_SHUTDOWN */
+ OMAP3430_CORE2_IOPAD(0x25e0, PIN_OUTPUT | MUX_MODE4) /* etk_d2.gpio_16 = RESET_USB_HOST */
+ OMAP3430_CORE2_IOPAD(0x25ea, PIN_INPUT | MUX_MODE4) /* etk_d7.gpio_21 = WIFI IRQ */
+ OMAP3430_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4) /* etk_d8.gpio_22 = MSECURE */
+ OMAP3430_CORE2_IOPAD(0x25ee, PIN_OUTPUT | MUX_MODE4) /* etk_d9.gpio_23 = WIFI_POWER */
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-pandora-common.dtsi b/arch/arm/boot/dts/omap3-pandora-common.dtsi
new file mode 100644
index 000000000..782ab1ff1
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-pandora-common.dtsi
@@ -0,0 +1,640 @@
+/*
+ * Copyright (C) 2015
+ * Nikolaus Schaller <hns@goldelico.com>
+ *
+ * Common device tree include for OpenPandora 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 <dt-bindings/input/input.h>
+
+/ {
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vcc>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>; /* 512 MB */
+ };
+
+ aliases {
+ display0 = &lcd;
+ };
+
+ tv: connector@1 {
+ compatible = "connector-analog-tv";
+ label = "tv";
+
+ port {
+ tv_connector_in: endpoint {
+ remote-endpoint = <&venc_out>;
+ };
+ };
+ };
+
+ gpio-leds {
+
+ compatible = "gpio-leds";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+
+ led@1 {
+ label = "pandora::sd1";
+ gpios = <&gpio5 0 GPIO_ACTIVE_HIGH>; /* GPIO_128 */
+ linux,default-trigger = "mmc0";
+ default-state = "off";
+ };
+
+ led@2 {
+ label = "pandora::sd2";
+ gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; /* GPIO_129 */
+ linux,default-trigger = "mmc1";
+ default-state = "off";
+ };
+
+ led@3 {
+ label = "pandora::bluetooth";
+ gpios = <&gpio5 30 GPIO_ACTIVE_HIGH>; /* GPIO_158 */
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+
+ led@4 {
+ label = "pandora::wifi";
+ gpios = <&gpio5 31 GPIO_ACTIVE_HIGH>; /* GPIO_159 */
+ linux,default-trigger = "mmc2";
+ default-state = "off";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&button_pins>;
+
+ up-button {
+ label = "up";
+ linux,code = <KEY_UP>;
+ gpios = <&gpio4 14 GPIO_ACTIVE_LOW>; /* GPIO_110 */
+ gpio-key,wakeup;
+ };
+
+ down-button {
+ label = "down";
+ linux,code = <KEY_DOWN>;
+ gpios = <&gpio4 7 GPIO_ACTIVE_LOW>; /* GPIO_103 */
+ gpio-key,wakeup;
+ };
+
+ left-button {
+ label = "left";
+ linux,code = <KEY_LEFT>;
+ gpios = <&gpio4 0 GPIO_ACTIVE_LOW>; /* GPIO_96 */
+ gpio-key,wakeup;
+ };
+
+ right-button {
+ label = "right";
+ linux,code = <KEY_RIGHT>;
+ gpios = <&gpio4 2 GPIO_ACTIVE_LOW>; /* GPIO_98 */
+ gpio-key,wakeup;
+ };
+
+ pageup-button {
+ label = "game 1";
+ linux,code = <KEY_PAGEUP>;
+ gpios = <&gpio4 13 GPIO_ACTIVE_LOW>; /* GPIO_109 */
+ gpio-key,wakeup;
+ };
+
+ pagedown-button {
+ label = "game 3";
+ linux,code = <KEY_PAGEDOWN>;
+ gpios = <&gpio4 10 GPIO_ACTIVE_LOW>; /* GPIO_106 */
+ gpio-key,wakeup;
+ };
+
+ home-button {
+ label = "game 4";
+ linux,code = <KEY_HOME>;
+ gpios = <&gpio4 5 GPIO_ACTIVE_LOW>; /* GPIO_101 */
+ gpio-key,wakeup;
+ };
+
+ end-button {
+ label = "game 2";
+ linux,code = <KEY_END>;
+ gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* GPIO_111 */
+ gpio-key,wakeup;
+ };
+
+ right-shift {
+ label = "l";
+ linux,code = <KEY_RIGHTSHIFT>;
+ gpios = <&gpio4 6 GPIO_ACTIVE_LOW>; /* GPIO_102 */
+ gpio-key,wakeup;
+ };
+
+ kp-plus {
+ label = "l2";
+ linux,code = <KEY_KPPLUS>;
+ gpios = <&gpio4 1 GPIO_ACTIVE_LOW>; /* GPIO_97 */
+ gpio-key,wakeup;
+ };
+
+ right-ctrl {
+ label = "r";
+ linux,code = <KEY_RIGHTCTRL>;
+ gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; /* GPIO_105 */
+ gpio-key,wakeup;
+ };
+
+ kp-minus {
+ label = "r2";
+ linux,code = <KEY_KPMINUS>;
+ gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; /* GPIO_107 */
+ gpio-key,wakeup;
+ };
+
+ left-ctrl {
+ label = "ctrl";
+ linux,code = <KEY_LEFTCTRL>;
+ gpios = <&gpio4 8 GPIO_ACTIVE_LOW>; /* GPIO_104 */
+ gpio-key,wakeup;
+ };
+
+ menu {
+ label = "menu";
+ linux,code = <KEY_MENU>;
+ gpios = <&gpio4 3 GPIO_ACTIVE_LOW>; /* GPIO_99 */
+ gpio-key,wakeup;
+ };
+
+ hold {
+ label = "hold";
+ linux,code = <KEY_COFFEE>;
+ gpios = <&gpio6 16 GPIO_ACTIVE_LOW>; /* GPIO_176 */
+ gpio-key,wakeup;
+ };
+
+ left-alt {
+ label = "alt";
+ linux,code = <KEY_LEFTALT>;
+ gpios = <&gpio4 4 GPIO_ACTIVE_HIGH>; /* GPIO_100 */
+ gpio-key,wakeup;
+ };
+
+ lid {
+ label = "lid";
+ linux,code = <0x00>; /* SW_LID lid shut */
+ linux,input-type = <0x05>; /* EV_SW */
+ gpios = <&gpio4 12 GPIO_ACTIVE_HIGH>; /* GPIO_108 */
+ };
+ };
+};
+
+&omap3_pmx_core {
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */
+ OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */
+ OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */
+ OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */
+ OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */
+ OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
+ >;
+ };
+
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
+ OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
+ OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
+ OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+ OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
+ OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
+ OMAP3_CORE1_IOPAD(0x2164, PIN_OUTPUT_PULLUP | MUX_MODE1) /* sdmmc2_dat4.sdmmc2_dirdat0 */
+ OMAP3_CORE1_IOPAD(0x2166, PIN_OUTPUT_PULLUP | MUX_MODE1) /* sdmmc2_dat5.sdmmc2_dirdat1 */
+ OMAP3_CORE1_IOPAD(0x2168, PIN_OUTPUT_PULLUP | MUX_MODE1) /* sdmmc2_dat6.sdmmc2_dircmd */
+ OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT_PULLUP | MUX_MODE1) /* sdmmc2_dat7.sdmmc2_clkin */
+ >;
+ };
+
+ dss_dpi_pins: pinmux_dss_dpi_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */
+ OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */
+ OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */
+ OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */
+ OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE0) /* dss_data0.dss_data0 */
+ OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT | MUX_MODE0) /* dss_data1.dss_data1 */
+ OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT | MUX_MODE0) /* dss_data2.dss_data2 */
+ OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE0) /* dss_data3.dss_data3 */
+ OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE0) /* dss_data4.dss_data4 */
+ OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE0) /* dss_data5.dss_data5 */
+ OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */
+ OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */
+ OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */
+ OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */
+ OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */
+ OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */
+ OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */
+ OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */
+ OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */
+ OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */
+ OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */
+ OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */
+ OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE0) /* dss_data18.dss_data18 */
+ OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE0) /* dss_data19.dss_data19 */
+ OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE0) /* dss_data20.dss_data20 */
+ OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE0) /* dss_data21.dss_data21 */
+ OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE0) /* dss_data22.dss_data22 */
+ OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */
+ OMAP3_CORE1_IOPAD(0x218e, PIN_OUTPUT | MUX_MODE4) /* GPIO_157 = lcd reset */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+ OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */
+ >;
+ };
+
+ led_pins: pinmux_leds_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2154, PIN_OUTPUT | MUX_MODE4) /* GPIO_128 */
+ OMAP3_CORE1_IOPAD(0x2156, PIN_OUTPUT | MUX_MODE4) /* GPIO_129 */
+ OMAP3_CORE1_IOPAD(0x2190, PIN_OUTPUT | MUX_MODE4) /* GPIO_158 */
+ OMAP3_CORE1_IOPAD(0x2192, PIN_OUTPUT | MUX_MODE4) /* GPIO_159 */
+ >;
+ };
+
+ button_pins: pinmux_button_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2110, PIN_INPUT | MUX_MODE4) /* GPIO_96 */
+ OMAP3_CORE1_IOPAD(0x2112, PIN_INPUT | MUX_MODE4) /* GPIO_97 */
+ OMAP3_CORE1_IOPAD(0x2114, PIN_INPUT | MUX_MODE4) /* GPIO_98 */
+ OMAP3_CORE1_IOPAD(0x2116, PIN_INPUT | MUX_MODE4) /* GPIO_99 */
+ OMAP3_CORE1_IOPAD(0x2118, PIN_INPUT | MUX_MODE4) /* GPIO_100 */
+ OMAP3_CORE1_IOPAD(0x211a, PIN_INPUT | MUX_MODE4) /* GPIO_101 */
+ OMAP3_CORE1_IOPAD(0x211c, PIN_INPUT | MUX_MODE4) /* GPIO_102 */
+ OMAP3_CORE1_IOPAD(0x211e, PIN_INPUT | MUX_MODE4) /* GPIO_103 */
+ OMAP3_CORE1_IOPAD(0x2120, PIN_INPUT | MUX_MODE4) /* GPIO_104 */
+ OMAP3_CORE1_IOPAD(0x2122, PIN_INPUT | MUX_MODE4) /* GPIO_105 */
+ OMAP3_CORE1_IOPAD(0x2124, PIN_INPUT | MUX_MODE4) /* GPIO_106 */
+ OMAP3_CORE1_IOPAD(0x2126, PIN_INPUT | MUX_MODE4) /* GPIO_107 */
+ OMAP3_CORE1_IOPAD(0x2128, PIN_INPUT | MUX_MODE4) /* GPIO_108 */
+ OMAP3_CORE1_IOPAD(0x212a, PIN_INPUT | MUX_MODE4) /* GPIO_109 */
+ OMAP3_CORE1_IOPAD(0x212c, PIN_INPUT | MUX_MODE4) /* GPIO_110 */
+ OMAP3_CORE1_IOPAD(0x212e, PIN_INPUT | MUX_MODE4) /* GPIO_111 */
+ OMAP3_CORE1_IOPAD(0x21d2, PIN_INPUT | MUX_MODE4) /* GPIO_176 */
+ >;
+ };
+
+ penirq_pins: pinmux_penirq_pins {
+ pinctrl-single,pins = <
+ /* here we could enable to wakeup the cpu from suspend by a pen touch */
+ OMAP3_CORE1_IOPAD(0x210c, PIN_INPUT | MUX_MODE4) /* GPIO_94 */
+ >;
+ };
+
+};
+
+&omap3_pmx_core2 {
+ /* define in CPU specific file that includes this one
+ * use either OMAP3430_CORE2_IOPAD() or OMAP3630_CORE2_IOPAD()
+ */
+};
+
+&i2c1 {
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+
+ twl_power: power {
+ compatible = "ti,twl4030-power-reset";
+ ti,use_poweroff;
+ };
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+
+ codec {
+ ti,ramp_delay_value = <3>;
+ };
+ };
+ };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&twl_keypad {
+ keypad,num-rows = <8>;
+ keypad,num-columns = <6>;
+ linux,keymap = <
+ MATRIX_KEY(0, 0, KEY_9)
+ MATRIX_KEY(0, 1, KEY_8)
+ MATRIX_KEY(0, 2, KEY_I)
+ MATRIX_KEY(0, 3, KEY_J)
+ MATRIX_KEY(0, 4, KEY_N)
+ MATRIX_KEY(0, 5, KEY_M)
+ MATRIX_KEY(1, 0, KEY_0)
+ MATRIX_KEY(1, 1, KEY_7)
+ MATRIX_KEY(1, 2, KEY_U)
+ MATRIX_KEY(1, 3, KEY_H)
+ MATRIX_KEY(1, 4, KEY_B)
+ MATRIX_KEY(1, 5, KEY_SPACE)
+ MATRIX_KEY(2, 0, KEY_BACKSPACE)
+ MATRIX_KEY(2, 1, KEY_6)
+ MATRIX_KEY(2, 2, KEY_Y)
+ MATRIX_KEY(2, 3, KEY_G)
+ MATRIX_KEY(2, 4, KEY_V)
+ MATRIX_KEY(2, 5, KEY_FN)
+ MATRIX_KEY(3, 0, KEY_O)
+ MATRIX_KEY(3, 1, KEY_5)
+ MATRIX_KEY(3, 2, KEY_T)
+ MATRIX_KEY(3, 3, KEY_F)
+ MATRIX_KEY(3, 4, KEY_C)
+ MATRIX_KEY(4, 0, KEY_P)
+ MATRIX_KEY(4, 1, KEY_4)
+ MATRIX_KEY(4, 2, KEY_R)
+ MATRIX_KEY(4, 3, KEY_D)
+ MATRIX_KEY(4, 4, KEY_X)
+ MATRIX_KEY(5, 0, KEY_K)
+ MATRIX_KEY(5, 1, KEY_3)
+ MATRIX_KEY(5, 2, KEY_E)
+ MATRIX_KEY(5, 3, KEY_S)
+ MATRIX_KEY(5, 4, KEY_Z)
+ MATRIX_KEY(6, 0, KEY_L)
+ MATRIX_KEY(6, 1, KEY_2)
+ MATRIX_KEY(6, 2, KEY_W)
+ MATRIX_KEY(6, 3, KEY_A)
+ MATRIX_KEY(6, 4, KEY_RIGHTBRACE)
+ MATRIX_KEY(7, 0, KEY_ENTER)
+ MATRIX_KEY(7, 1, KEY_1)
+ MATRIX_KEY(7, 2, KEY_Q)
+ MATRIX_KEY(7, 3, KEY_LEFTSHIFT)
+ MATRIX_KEY(7, 4, KEY_LEFTBRACE )
+ >;
+};
+
+/* backup battery charger */
+&charger {
+ ti,bb-uvolt = <3200000>;
+ ti,bb-uamp = <150>;
+};
+
+/* MMC2 */
+&vmmc2 {
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <3150000>;
+};
+
+/* LCD */
+&vaux1 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+};
+
+/* USB Host PHY */
+&vaux2 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+};
+
+/* available on expansion connector */
+&vaux3 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+};
+
+/* ADS7846 and nubs */
+&vaux4 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+};
+
+/* power audio DAC and LID sensor */
+&vsim {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ /* no clients so we should disable clock */
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+
+ bq27500@55 {
+ compatible = "ti,bq27500";
+ reg = <0x55>;
+ };
+
+};
+
+&usb_otg_hs {
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ phys = <&usb2_phy>;
+ phy-names = "usb2-phy";
+ mode = <3>;
+ power = <50>;
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&vmmc1>;
+ bus-width = <4>;
+ cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio4 30 GPIO_ACTIVE_LOW>; /* GPIO_126 */
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+ vmmc-supply = <&vmmc2>;
+ bus-width = <4>;
+ cd-gpios = <&twl_gpio 1 GPIO_ACTIVE_HIGH>;
+ wp-gpios = <&gpio4 31 GPIO_ACTIVE_LOW>; /* GPIO_127 */
+};
+
+/* bluetooth*/
+&uart1 {
+};
+
+/* spare (expansion connector) */
+&uart2 {
+};
+
+/* console (expansion connector) */
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+ interrupts-extended = <&intc 74 &omap3_pmx_core OMAP3_UART3_RX>;
+};
+
+&usbhshost {
+ port2-mode = "ehci-phy";
+};
+
+&gpmc {
+ ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */
+
+ nand@0,0 {
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ nand-bus-width = <16>;
+ ti,nand-ecc-opt = "sw";
+
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <44>;
+ gpmc,cs-wr-off-ns = <44>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <34>;
+ gpmc,adv-wr-off-ns = <44>;
+ gpmc,we-off-ns = <40>;
+ gpmc,oe-off-ns = <54>;
+ gpmc,access-ns = <64>;
+ gpmc,rd-cycle-ns = <82>;
+ gpmc,wr-cycle-ns = <82>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+ gpmc,device-width = <2>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /* u-boot uses mtdparts=nand:512k(xloader),1920k(uboot),128k(uboot-env),10m(boot),-(rootfs) */
+
+ x-loader@0 {
+ label = "xloader";
+ reg = <0 0x80000>;
+ };
+
+ bootloaders@80000 {
+ label = "uboot";
+ reg = <0x80000 0x1e0000>;
+ };
+
+ bootloaders_env@260000 {
+ label = "uboot-env";
+ reg = <0x260000 0x20000>;
+ };
+
+ kernel@280000 {
+ label = "boot";
+ reg = <0x280000 0xa00000>;
+ };
+
+ filesystem@680000 {
+ label = "rootfs";
+ reg = <0xc80000 0>; /* 0 = MTDPART_SIZ_FULL */
+ };
+ };
+};
+
+&mcspi1 {
+ tsc2046@0 {
+ reg = <0>; /* CS0 */
+ compatible = "ti,tsc2046";
+ spi-max-frequency = <1000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&penirq_pins>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <30 0>; /* GPIO_94 */
+ pendown-gpio = <&gpio3 30 0>;
+ vcc-supply = <&vaux4>;
+
+ ti,x-min = /bits/ 16 <0>;
+ ti,x-max = /bits/ 16 <8000>;
+ ti,y-min = /bits/ 16 <0>;
+ ti,y-max = /bits/ 16 <4800>;
+ ti,x-plate-ohms = /bits/ 16 <40>;
+ ti,pressure-max = /bits/ 16 <255>;
+
+ linux,wakeup;
+ };
+
+ lcd: lcd@1 {
+ reg = <1>; /* CS1 */
+ compatible = "omapdss,tpo,td043mtea1";
+ spi-max-frequency = <100000>;
+ spi-cpol;
+ spi-cpha;
+
+ label = "lcd";
+ reset-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>; /* GPIO_157 */
+ vcc-supply = <&vaux1>;
+
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+ };
+
+
+};
+
+/* n/a - used as GPIOs */
+&mcbsp1 {
+};
+
+/* audio DAC */
+&mcbsp2 {
+};
+
+/* bluetooth */
+&mcbsp3 {
+};
+
+/* to twl4030*/
+&mcbsp4 {
+};
+
+&venc {
+ status = "ok";
+
+ vdda-supply = <&vdac>;
+
+ port {
+ venc_out: endpoint {
+ remote-endpoint = <&tv_connector_in>;
+ ti,channels = <2>;
+ };
+ };
+};
+
+&dss {
+ pinctrl-names = "default";
+ pinctrl-0 = < &dss_dpi_pins >;
+
+ status = "ok";
+ vdds_dsi-supply = <&vpll2>;
+
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <24>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi b/arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi
new file mode 100644
index 000000000..f4b1a6185
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi
@@ -0,0 +1,71 @@
+/*
+ * Common file for omap dpi panels with QVGA and reset pins
+ *
+ * Note that the board specifc DTS file needs to specify
+ * at minimum the GPIO enable-gpios for display, and
+ * gpios for gpio-backlight.
+ */
+
+/ {
+ aliases {
+ display0 = &lcd0;
+ };
+
+ backlight0: backlight {
+ compatible = "gpio-backlight";
+ default-on;
+ };
+
+ /* 3.3V GPIO controlled regulator for LCD_ENVDD */
+ lcd_3v3: regulator-lcd-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "lcd_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <70000>;
+ };
+
+ lcd0: display {
+ compatible = "sharp,ls037v7dw01";
+ label = "lcd";
+ power-supply = <&lcd_3v3>;
+
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+ };
+};
+
+/* Needed to power the DPI pins */
+&vpll2 {
+ regulator-always-on;
+};
+
+&dss {
+ status = "ok";
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <18>;
+ };
+ };
+};
+
+&mcspi1 {
+ tsc2046@0 {
+ reg = <0>; /* CS0 */
+ compatible = "ti,tsc2046";
+ spi-max-frequency = <1000000>;
+ vcc-supply = <&lcd_3v3>;
+ ti,x-min = /bits/ 16 <0>;
+ ti,x-max = /bits/ 16 <8000>;
+ ti,y-min = /bits/ 16 <0>;
+ ti,y-max = /bits/ 16 <4800>;
+ ti,x-plate-ohms = /bits/ 16 <40>;
+ ti,pressure-max = /bits/ 16 <255>;
+ ti,swap-xy;
+ linux,wakeup;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-sb-t35.dtsi b/arch/arm/boot/dts/omap3-sb-t35.dtsi
new file mode 100644
index 000000000..827f61426
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-sb-t35.dtsi
@@ -0,0 +1,138 @@
+/*
+ * Common support for CompuLab SB-T35 used on SBC-T3530, SBC-T3517 and SBC-T3730
+ */
+
+/ {
+ tfp410: encoder@0 {
+ compatible = "ti,tfp410";
+
+ powerdown-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>; /* gpio_54 */
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&tfp410_pins>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ tfp410_in: endpoint@0 {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ tfp410_out: endpoint@0 {
+ remote-endpoint = <&dvi_connector_in>;
+ };
+ };
+ };
+ };
+
+ dvi0: connector@0 {
+ compatible = "dvi-connector";
+ label = "dvi";
+
+ port {
+ dvi_connector_in: endpoint {
+ remote-endpoint = <&tfp410_out>;
+ };
+ };
+ };
+
+ audio_amp: audio_amp {
+ compatible = "regulator-fixed";
+ regulator-name = "audio_amp";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sb_t35_audio_amp>;
+ gpio = <&gpio2 29 GPIO_ACTIVE_LOW>; /* gpio_61 */
+ enable-active-low;
+ regulator-always-on;
+ };
+};
+
+&omap3_pmx_core {
+ smsc2_pins: pinmux_smsc2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20b6, PIN_OUTPUT | MUX_MODE0) /* gpmc_ncs4.gpmc_ncs4 */
+ OMAP3_CORE1_IOPAD(0x20d2, PIN_INPUT_PULLUP | MUX_MODE4) /* gpmc_wait3.gpio_65 */
+ >;
+ };
+
+ tfp410_pins: pinmux_tfp410_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20b4, PIN_OUTPUT | MUX_MODE4) /* gpmc_ncs3.gpio_54 */
+ >;
+ };
+
+ i2c3_pins: pinmux_i2c3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */
+ OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */
+ >;
+ };
+
+ sb_t35_audio_amp: pinmux_sb_t35_audio_amp {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20c8, PIN_OUTPUT | MUX_MODE4) /* gpmc_nbe1.gpio_61 */
+ >;
+ };
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+
+ clock-frequency = <400000>;
+
+ at24@50 {
+ compatible = "at24,24c02";
+ pagesize = <16>;
+ reg = <0x50>;
+ };
+};
+
+&gpmc {
+ ranges = <4 0 0x2d000000 0x01000000>;
+
+ smsc2: ethernet@4,0 {
+ compatible = "smsc,lan9221", "smsc,lan9115";
+ pinctrl-names = "default";
+ pinctrl-0 = <&smsc2_pins>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+ reg = <4 0 0xff>;
+ bank-width = <2>;
+ gpmc,device-width = <1>;
+ gpmc,cycle2cycle-samecsen = <1>;
+ gpmc,cycle2cycle-diffcsen = <1>;
+ gpmc,cs-on-ns = <5>;
+ gpmc,cs-rd-off-ns = <150>;
+ gpmc,cs-wr-off-ns = <150>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <15>;
+ gpmc,adv-wr-off-ns = <40>;
+ gpmc,oe-on-ns = <45>;
+ gpmc,oe-off-ns = <140>;
+ gpmc,we-on-ns = <45>;
+ gpmc,we-off-ns = <140>;
+ gpmc,rd-cycle-ns = <155>;
+ gpmc,wr-cycle-ns = <155>;
+ gpmc,access-ns = <120>;
+ gpmc,page-burst-access-ns = <20>;
+ gpmc,bus-turnaround-ns = <75>;
+ gpmc,cycle2cycle-delay-ns = <75>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+ gpmc,wr-access-ns = <0>;
+ vddvario-supply = <&vddvario>;
+ vdd33a-supply = <&vdd33a>;
+ reg-io-width = <4>;
+ smsc,save-mac-address;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-sbc-t3517.dts b/arch/arm/boot/dts/omap3-sbc-t3517.dts
new file mode 100644
index 000000000..c2d5c28a1
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-sbc-t3517.dts
@@ -0,0 +1,75 @@
+/*
+ * Suppport for CompuLab SBC-T3517 with CM-T3517
+ */
+
+#include "omap3-cm-t3517.dts"
+#include "omap3-sb-t35.dtsi"
+
+/ {
+ model = "CompuLab SBC-T3517 with CM-T3517";
+ compatible = "compulab,omap3-sbc-t3517", "compulab,omap3-cm-t3517", "ti,am3517", "ti,omap3";
+
+ aliases {
+ display0 = &dvi0;
+ display1 = &tv0;
+ };
+
+ /* Only one GPMC smsc9220 on SBC-T3517, CM-T3517 uses am35x Ethernet */
+ vddvario: regulator-vddvario-sb-t35 {
+ compatible = "regulator-fixed";
+ regulator-name = "vddvario";
+ regulator-always-on;
+ };
+
+ vdd33a: regulator-vdd33a-sb-t35 {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd33a";
+ regulator-always-on;
+ };
+};
+
+&omap3_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &sb_t35_usb_hub_pins
+ &usb_hub_pins
+ >;
+
+ mmc1_aux_pins: pinmux_mmc1_aux_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20c0, PIN_INPUT_PULLUP | MUX_MODE4) /* gpmc_clk.gpio_59 */
+ OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT_PULLUP | MUX_MODE4) /* uart2_cts.gpio_144 */
+ >;
+ };
+
+ sb_t35_usb_hub_pins: pinmux_sb_t35_usb_hub_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21ec, PIN_OUTPUT | MUX_MODE4) /* ccdc_wen.gpio_98 - SB-T35 USB HUB RST */
+ >;
+ };
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &mmc1_pins
+ &mmc1_aux_pins
+ >;
+
+ wp-gpios = <&gpio2 27 GPIO_ACTIVE_HIGH>; /* gpio_59 */
+ cd-gpios = <&gpio5 16 GPIO_ACTIVE_HIGH>; /* gpio_144 */
+};
+
+&dss {
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&tfp410_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+&gpmc {
+ ranges = <4 0 0x2d000000 0x01000000>, /* SB-T35 SMSC9x Eth */
+ <0 0 0x00000000 0x01000000>; /* CM-T3x NAND */
+};
diff --git a/arch/arm/boot/dts/omap3-sbc-t3530.dts b/arch/arm/boot/dts/omap3-sbc-t3530.dts
new file mode 100644
index 000000000..834bc786c
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-sbc-t3530.dts
@@ -0,0 +1,47 @@
+/*
+ * Suppport for CompuLab SBC-T3530 with CM-T3530
+ */
+
+#include "omap3-cm-t3530.dts"
+#include "omap3-sb-t35.dtsi"
+
+/ {
+ model = "CompuLab SBC-T3530 with CM-T3530";
+ compatible = "compulab,omap3-sbc-t3530", "compulab,omap3-cm-t3530", "ti,omap34xx", "ti,omap3";
+
+ aliases {
+ display0 = &dvi0;
+ display1 = &tv0;
+ };
+};
+
+&omap3_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sb_t35_usb_hub_pins>;
+
+ sb_t35_usb_hub_pins: pinmux_sb_t35_usb_hub_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2130, PIN_OUTPUT | MUX_MODE4) /* ccdc_wen.gpio_167 - SB-T35 USB HUB RST */
+ >;
+ };
+};
+
+&gpmc {
+ ranges = <5 0 0x2c000000 0x01000000>, /* CM-T3x30 SMSC9x Eth */
+ <4 0 0x2d000000 0x01000000>, /* SB-T35 SMSC9x Eth */
+ <0 0 0x00000000 0x01000000>; /* CM-T3x NAND */
+};
+
+&mmc1 {
+ cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_HIGH>;
+};
+
+&dss {
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&tfp410_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
diff --git a/arch/arm/boot/dts/omap3-sbc-t3730.dts b/arch/arm/boot/dts/omap3-sbc-t3730.dts
new file mode 100644
index 000000000..73c7bf4a4
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-sbc-t3730.dts
@@ -0,0 +1,43 @@
+/*
+ * Suppport for CompuLab SBC-T3730 with CM-T3730
+ */
+
+#include "omap3-cm-t3730.dts"
+#include "omap3-sb-t35.dtsi"
+
+/ {
+ model = "CompuLab SBC-T3730 with CM-T3730";
+ compatible = "compulab,omap3-sbc-t3730", "compulab,omap3-cm-t3730", "ti,omap36xx", "ti,omap3";
+
+ aliases {
+ display0 = &dvi0;
+ display1 = &tv0;
+ };
+};
+
+&omap3_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sb_t35_usb_hub_pins>;
+
+ sb_t35_usb_hub_pins: pinmux_sb_t35_usb_hub_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2130, PIN_OUTPUT | MUX_MODE4) /* ccdc_wen.gpio_167 - SB-T35 USB HUB RST */
+ >;
+ };
+};
+
+&gpmc {
+ ranges = <5 0 0x2c000000 0x01000000>, /* CM-T3x30 SMSC9x Eth */
+ <4 0 0x2d000000 0x01000000>, /* SB-T35 SMSC9x Eth */
+ <0 0 0x00000000 0x01000000>; /* CM-T3x NAND */
+};
+
+&dss {
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&tfp410_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
diff --git a/arch/arm/boot/dts/omap3-tao3530.dtsi b/arch/arm/boot/dts/omap3-tao3530.dtsi
new file mode 100644
index 000000000..7bd8d9a4f
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-tao3530.dtsi
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2014 Stefan Roese <sr@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.
+ */
+/dts-v1/;
+
+#include "omap34xx.dtsi"
+
+/* Secure omaps have some devices inaccessible depending on the firmware */
+&aes {
+ status = "disabled";
+};
+
+&sham {
+ status = "disabled";
+};
+
+/ {
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vcc>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ /* HS USB Port 2 Power */
+ hsusb2_power: hsusb2_power_reg {
+ compatible = "regulator-fixed";
+ regulator-name = "hsusb2_vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&twl_gpio 18 0>; /* GPIO LEDA */
+ startup-delay-us = <70000>;
+ };
+
+ /* HS USB Host PHY on PORT 2 */
+ hsusb2_phy: hsusb2_phy {
+ compatible = "usb-nop-xceiv";
+ reset-gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; /* gpio_162 */
+ vcc-supply = <&hsusb2_power>;
+ };
+
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "omap3beagle";
+
+ /* McBSP2 is used for onboard sound, same as on beagle */
+ ti,mcbsp = <&mcbsp2>;
+ };
+
+ /* Regulator to enable/switch the vcc of the Wifi module */
+ mmc2_sdio_poweron: regulator-mmc2-sdio-poweron {
+ compatible = "regulator-fixed";
+ regulator-name = "regulator-mmc2-sdio-poweron";
+ regulator-min-microvolt = <3150000>;
+ regulator-max-microvolt = <3150000>;
+ gpio = <&gpio5 29 GPIO_ACTIVE_LOW>; /* gpio_157 */
+ enable-active-low;
+ startup-delay-us = <10000>;
+ };
+};
+
+&omap3_pmx_core {
+ hsusbb2_pins: pinmux_hsusbb2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */
+ OMAP3_CORE1_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */
+ OMAP3_CORE1_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */
+ OMAP3_CORE1_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */
+ OMAP3_CORE1_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */
+ OMAP3_CORE1_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */
+ OMAP3_CORE1_IOPAD(0x21d4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */
+ OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */
+ OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */
+ OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */
+ OMAP3_CORE1_IOPAD(0x21dc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */
+ OMAP3_CORE1_IOPAD(0x21de, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */
+ OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */
+ OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */
+ OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */
+ OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */
+ OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
+ OMAP3_CORE1_IOPAD(0x2150, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat4.sdmmc1_dat4 */
+ OMAP3_CORE1_IOPAD(0x2152, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat5.sdmmc1_dat5 */
+ OMAP3_CORE1_IOPAD(0x2154, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat6.sdmmc1_dat6 */
+ OMAP3_CORE1_IOPAD(0x2156, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat7.sdmmc1_dat7 */
+ >;
+ };
+
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
+ OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
+ OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
+ OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+ OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
+ OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
+ >;
+ };
+
+ /* wlan GPIO output for WLAN_EN */
+ wlan_gpio: pinmux_wlan_gpio {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x218e, PIN_OUTPUT | MUX_MODE4) /* mcbsp1_fsr gpio_157 */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+ OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */
+ >;
+ };
+
+ i2c3_pins: pinmux_i2c3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl.i2c3_scl */
+ OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda.i2c3_sda */
+ >;
+ };
+
+ mcspi1_pins: pinmux_mcspi1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21c8, PIN_INPUT | MUX_MODE0) /* mcspi1_clk.mcspi1_clk */
+ OMAP3_CORE1_IOPAD(0x21ca, PIN_OUTPUT | MUX_MODE0) /* mcspi1_simo.mcspi1_simo */
+ OMAP3_CORE1_IOPAD(0x21cc, PIN_INPUT_PULLUP | MUX_MODE0) /* mcspi1_somi.mcspi1_somi */
+ OMAP3_CORE1_IOPAD(0x21ce, PIN_OUTPUT | MUX_MODE0) /* mcspi1_cs0.mcspi1_cs0 */
+ >;
+ };
+
+ mcspi3_pins: pinmux_mcspi3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x25dc, PIN_OUTPUT | MUX_MODE1) /* etk_d0.mcspi3_simo gpio14 INPUT | MODE1 */
+ OMAP3_CORE1_IOPAD(0x25de, PIN_INPUT_PULLUP | MUX_MODE1) /* etk_d1.mcspi3_somi gpio15 INPUT | MODE1 */
+ OMAP3_CORE1_IOPAD(0x25e0, PIN_OUTPUT | MUX_MODE1) /* etk_d2.mcspi3_cs0 gpio16 INPUT | MODE1 */
+ OMAP3_CORE1_IOPAD(0x25e2, PIN_INPUT | MUX_MODE1) /* etk_d3.mcspi3_clk gpio17 INPUT | MODE1 */
+ >;
+ };
+
+ mcbsp3_pins: pinmux_mcbsp3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x216c, PIN_OUTPUT | MUX_MODE0) /* mcbsp3_dx.uart2_cts */
+ OMAP3_CORE1_IOPAD(0x216e, PIN_INPUT | MUX_MODE0) /* mcbsp3_dr.uart2_rts */
+ OMAP3_CORE1_IOPAD(0x2170, PIN_INPUT | MUX_MODE0) /* mcbsp3_clk.uart2_tx */
+ OMAP3_CORE1_IOPAD(0x2172, PIN_INPUT | MUX_MODE0) /* mcbsp3_fsx.uart2_rx */
+ >;
+ };
+};
+
+/* McBSP1: mux'ed with GPIO158 as clock for HA-DSP */
+&mcbsp1 {
+ status = "disabled";
+};
+
+&mcbsp2 {
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ codec {
+ };
+ };
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+};
+
+&mcspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi1_pins>;
+
+ spidev@0 {
+ compatible = "spidev";
+ spi-max-frequency = <48000000>;
+ reg = <0>;
+ spi-cpha;
+ };
+};
+
+&mcspi3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi3_pins>;
+
+ spidev@0 {
+ compatible = "spidev";
+ spi-max-frequency = <48000000>;
+ reg = <0>;
+ spi-cpha;
+ };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&vmmc1>;
+ vmmc_aux-supply = <&vsim>;
+ cd-gpios = <&twl_gpio 0 0>;
+ bus-width = <8>;
+};
+
+// WiFi (Marvell 88W8686) on MMC2/SDIO
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+ vmmc-supply = <&mmc2_sdio_poweron>;
+ non-removable;
+ bus-width = <4>;
+ cap-power-off-card;
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&usbhshost {
+ port2-mode = "ehci-phy";
+};
+
+&usbhsehci {
+ phys = <0 &hsusb2_phy>;
+};
+
+&twl_gpio {
+ ti,use-leds;
+ /* pullups: BIT(1) */
+ ti,pullups = <0x000002>;
+ /*
+ * pulldowns:
+ * BIT(2), BIT(6), BIT(7), BIT(8), BIT(13)
+ * BIT(15), BIT(16), BIT(17)
+ */
+ ti,pulldowns = <0x03a1c4>;
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+};
+
+&mcbsp3 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcbsp3_pins>;
+};
+
+&gpmc {
+ ranges = <0 0 0x00000000 0x01000000>;
+
+ nand@0,0 {
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ nand-bus-width = <16>;
+ gpmc,device-width = <2>; /* GPMC_DEVWIDTH_16BIT */
+ ti,nand-ecc-opt = "sw";
+
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <36>;
+ gpmc,cs-wr-off-ns = <36>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <24>;
+ gpmc,adv-wr-off-ns = <36>;
+ gpmc,oe-on-ns = <6>;
+ gpmc,oe-off-ns = <48>;
+ gpmc,we-on-ns = <6>;
+ gpmc,we-off-ns = <30>;
+ gpmc,rd-cycle-ns = <72>;
+ gpmc,wr-cycle-ns = <72>;
+ gpmc,access-ns = <54>;
+ gpmc,wr-access-ns = <30>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ x-loader@0 {
+ label = "X-Loader";
+ reg = <0 0x80000>;
+ };
+
+ bootloaders@80000 {
+ label = "U-Boot";
+ reg = <0x80000 0x1e0000>;
+ };
+
+ bootloaders_env@260000 {
+ label = "U-Boot Env";
+ reg = <0x260000 0x20000>;
+ };
+
+ kernel@280000 {
+ label = "Kernel";
+ reg = <0x280000 0x400000>;
+ };
+
+ filesystem@680000 {
+ label = "File System";
+ reg = <0x680000 0xf980000>;
+ };
+ };
+};
+
+&usb_otg_hs {
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ phys = <&usb2_phy>;
+ phy-names = "usb2-phy";
+ mode = <3>;
+ power = <50>;
+};
+
+&vaux2 {
+ regulator-name = "vdd_ehci";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+};
diff --git a/arch/arm/boot/dts/omap3-thunder.dts b/arch/arm/boot/dts/omap3-thunder.dts
new file mode 100644
index 000000000..d659515ab
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-thunder.dts
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2014 Stefan Roese <sr@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 "omap3-tao3530.dtsi"
+
+/ {
+ model = "TI OMAP3 Thunder baseboard with TAO3530 SOM";
+ compatible = "technexion,omap3-thunder", "technexion,omap3-tao3530", "ti,omap34xx", "ti,omap3";
+};
+
+&omap3_pmx_core {
+ dss_dpi_pins: pinmux_dss_dpi_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */
+ OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */
+ OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */
+ OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */
+ OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE0) /* dss_data0.dss_data0 */
+ OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT | MUX_MODE0) /* dss_data1.dss_data1 */
+ OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT | MUX_MODE0) /* dss_data2.dss_data2 */
+ OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE0) /* dss_data3.dss_data3 */
+ OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE0) /* dss_data4.dss_data4 */
+ OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE0) /* dss_data5.dss_data5 */
+ OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */
+ OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */
+ OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */
+ OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */
+ OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */
+ OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */
+ OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */
+ OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */
+ OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */
+ OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */
+ OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */
+ OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */
+ OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE0) /* dss_data18.dss_data18 */
+ OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE0) /* dss_data19.dss_data19 */
+ OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE0) /* dss_data20.dss_data20 */
+ OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE0) /* dss_data21.dss_data21 */
+ OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE0) /* dss_data22.dss_data22 */
+ OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */
+ >;
+ };
+
+ lte430_pins: pinmux_lte430_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2168, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat6.gpio_138 */
+ >;
+ };
+
+ backlight_pins: pinmux_backlight_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x216a, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat7.gpio_139 */
+ >;
+ };
+};
+
+/* Needed to power the DPI pins */
+&vpll2 {
+ regulator-always-on;
+};
+
+&dss {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_dpi_pins>;
+
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+/ {
+ aliases {
+ display0 = &lcd0;
+ };
+
+ lcd0: display@0 {
+ compatible = "samsung,lte430wq-f0c", "panel-dpi";
+ label = "lcd";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&lte430_pins>;
+ enable-gpios = <&gpio5 10 GPIO_ACTIVE_LOW>; /* gpio_138 */
+
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+
+ panel-timing {
+ clock-frequency = <9000000>;
+ hactive = <480>;
+ vactive = <272>;
+ hfront-porch = <3>;
+ hback-porch = <2>;
+ hsync-len = <42>;
+ vback-porch = <2>;
+ vfront-porch = <3>;
+ vsync-len = <11>;
+
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+
+ backlight {
+ compatible = "gpio-backlight";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&backlight_pins>;
+ gpios = <&gpio5 11 GPIO_ACTIVE_HIGH>; /* gpio_139 */
+
+ default-on;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-zoom3.dts b/arch/arm/boot/dts/omap3-zoom3.dts
new file mode 100644
index 000000000..131448d86
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-zoom3.dts
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+/dts-v1/;
+
+#include "omap36xx.dtsi"
+#include "omap-zoom-common.dtsi"
+
+/ {
+ model = "TI Zoom3";
+ compatible = "ti,omap3-zoom3", "ti,omap36xx", "ti,omap3";
+
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vcc>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>; /* 512 MB */
+ };
+
+ vddvario: regulator-vddvario {
+ compatible = "regulator-fixed";
+ regulator-name = "vddvario";
+ regulator-always-on;
+ };
+
+ vdd33a: regulator-vdd33a {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd33a";
+ regulator-always-on;
+ };
+
+ wl12xx_vmmc: wl12xx_vmmc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wl12xx_gpio>;
+ compatible = "regulator-fixed";
+ regulator-name = "vwl1271";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio4 5 0>; /* gpio101 */
+ startup-delay-us = <70000>;
+ enable-active-high;
+ };
+};
+
+&omap3_pmx_core {
+ /* REVISIT: twl gpio0 is mmc0_cd */
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ 0x114 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */
+ 0x116 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */
+ 0x118 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */
+ 0x11a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */
+ 0x11c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */
+ 0x11e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
+ >;
+ };
+
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ 0x128 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
+ 0x12a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
+ 0x12c (PIN_INPUT | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
+ 0x12e (PIN_INPUT | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+ 0x130 (PIN_INPUT | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
+ 0x132 (PIN_INPUT | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
+ 0x134 (PIN_INPUT | MUX_MODE0) /* sdmmc2_dat4.sdmmc2_dat4 */
+ 0x136 (PIN_INPUT | MUX_MODE0) /* sdmmc2_dat5.sdmmc2_dat5 */
+ 0x138 (PIN_INPUT | MUX_MODE0) /* sdmmc2_dat6.sdmmc2_dat6 */
+ 0x13a (PIN_INPUT | MUX_MODE0) /* sdmmc2_dat7.sdmmc2_dat7 */
+ >;
+ };
+
+ mmc3_pins: pinmux_mmc3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2198, PIN_INPUT | MUX_MODE4) /* mcbsp1_clkx.gpio_162 WLAN IRQ */
+ OMAP3_CORE1_IOPAD(0x21d0, PIN_INPUT_PULLUP | MUX_MODE3) /* mcspi1_cs1.sdmmc3_cmd */
+ >;
+ };
+
+ uart1_pins: pinmux_uart1_pins {
+ pinctrl-single,pins = <
+ 0x150 (PIN_INPUT | MUX_MODE0) /* uart1_cts.uart1_cts */
+ 0x14e (PIN_OUTPUT | MUX_MODE0) /* uart1_rts.uart1_rts */
+ 0x152 (WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */
+ 0x14c (PIN_OUTPUT | MUX_MODE0) /* uart1_tx.uart1_tx */
+ >;
+ };
+
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ 0x144 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts.uart2_cts */
+ 0x146 (PIN_OUTPUT | MUX_MODE0) /* uart2_rts.uart2_rts */
+ 0x14a (WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */
+ 0x148 (PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ 0x16a (PIN_INPUT_PULLDOWN | MUX_MODE0) /* uart3_cts_rctx.uart3_cts_rctx */
+ 0x16c (PIN_OUTPUT | MUX_MODE0) /* uart3_rts_sd.uart3_rts_sd */
+ 0x16e (WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+ 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */
+ >;
+ };
+
+ /* wl12xx GPIO output for WLAN_EN */
+ wl12xx_gpio: pinmux_wl12xx_gpio {
+ pinctrl-single,pins = <
+ 0xea (PIN_OUTPUT| MUX_MODE4) /* cam_d2.gpio_101 */
+ >;
+ };
+};
+
+&omap3_pmx_core2 {
+ mmc3_2_pins: pinmux_mmc3_2_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25d8, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_clk.sdmmc3_clk */
+ OMAP3630_CORE2_IOPAD(0x25e4, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d4.sdmmc3_dat0 */
+ OMAP3630_CORE2_IOPAD(0x25e6, WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d5.sdmmc3_dat1 */
+ OMAP3630_CORE2_IOPAD(0x25e8, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d6.sdmmc3_dat2 */
+ OMAP3630_CORE2_IOPAD(0x25e2, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d3.sdmmc3_dat3 */
+ >;
+ };
+};
+
+&omap3_pmx_wkup {
+ wlan_host_wkup: pinmux_wlan_host_wkup_pins {
+ pinctrl-single,pins = <
+ 0x1a (PIN_INPUT_PULLUP | MUX_MODE4) /* sys_clkout1.gpio_10 WLAN_HOST_WKUP */
+ >;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+ };
+};
+
+#include "twl4030.dtsi"
+
+&i2c2 {
+ clock-frequency = <400000>;
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+
+ /*
+ * TVP5146 Video decoder-in for analog input support.
+ */
+ tvp5146@5c {
+ compatible = "ti,tvp5146m2";
+ reg = <0x5c>;
+ };
+};
+
+&twl_gpio {
+ ti,use-leds;
+};
+
+&mmc1 {
+ vmmc-supply = <&vmmc1>;
+ vmmc_aux-supply = <&vsim>;
+ bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+};
+/*
+&mmc2 {
+ vmmc-supply = <&vmmc2>;
+ ti,non-removable;
+ bus-width = <8>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+};
+*/
+&mmc3 {
+ vmmc-supply = <&wl12xx_vmmc>;
+ non-removable;
+ bus-width = <4>;
+ cap-power-off-card;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc3_pins &mmc3_2_pins>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1271";
+ reg = <2>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; /* gpio 162 */
+ ref-clock-frequency = <26000000>;
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+};
+
+&uart4 {
+ status = "disabled";
+};
+
+&usb_otg_hs {
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ mode = <3>;
+ power = <50>;
+};
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
new file mode 100644
index 000000000..69a40cfc1
--- /dev/null
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -0,0 +1,835 @@
+/*
+ * Device Tree Source for OMAP3 SoC
+ *
+ * Copyright (C) 2011 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/omap.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "ti,omap3430", "ti,omap3";
+ interrupt-parent = <&intc>;
+
+ aliases {
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ i2c2 = &i2c3;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a8";
+ device_type = "cpu";
+ reg = <0x0>;
+
+ clocks = <&dpll1_ck>;
+ clock-names = "cpu";
+
+ clock-latency = <300000>; /* From omap-cpufreq driver */
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a8-pmu";
+ reg = <0x54000000 0x800000>;
+ interrupts = <3>;
+ ti,hwmods = "debugss";
+ };
+
+ /*
+ * The soc node represents the soc top level view. It is used for IPs
+ * that are not memory mapped in the MPU view or for the MPU itself.
+ */
+ soc {
+ compatible = "ti,omap-infra";
+ mpu {
+ compatible = "ti,omap3-mpu";
+ ti,hwmods = "mpu";
+ };
+
+ iva: iva {
+ compatible = "ti,iva2.2";
+ ti,hwmods = "iva";
+
+ dsp {
+ compatible = "ti,omap3-c64";
+ };
+ };
+ };
+
+ /*
+ * XXX: Use a flat representation of the OMAP3 interconnect.
+ * The real OMAP interconnect network is quite complex.
+ * Since it will not bring real advantage to represent that in DT for
+ * the moment, just use a fake OCP bus entry to represent the whole bus
+ * hierarchy.
+ */
+ ocp {
+ compatible = "ti,omap3-l3-smx", "simple-bus";
+ reg = <0x68000000 0x10000>;
+ interrupts = <9 10>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "l3_main";
+
+ l4_core: l4@48000000 {
+ compatible = "ti,omap3-l4-core", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x48000000 0x1000000>;
+
+ scm: scm@2000 {
+ compatible = "ti,omap3-scm", "simple-bus";
+ reg = <0x2000 0x2000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x2000 0x2000>;
+
+ omap3_pmx_core: pinmux@30 {
+ compatible = "ti,omap3-padconf",
+ "pinctrl-single";
+ reg = <0x30 0x238>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ pinctrl-single,register-width = <16>;
+ pinctrl-single,function-mask = <0xff1f>;
+ };
+
+ scm_conf: scm_conf@270 {
+ compatible = "syscon";
+ reg = <0x270 0x330>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ scm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ scm_clockdomains: clockdomains {
+ };
+
+ omap3_pmx_wkup: pinmux@a00 {
+ compatible = "ti,omap3-padconf",
+ "pinctrl-single";
+ reg = <0xa00 0x5c>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ pinctrl-single,register-width = <16>;
+ pinctrl-single,function-mask = <0xff1f>;
+ };
+ };
+ };
+
+ aes: aes@480c5000 {
+ compatible = "ti,omap3-aes";
+ ti,hwmods = "aes";
+ reg = <0x480c5000 0x50>;
+ interrupts = <0>;
+ dmas = <&sdma 65 &sdma 66>;
+ dma-names = "tx", "rx";
+ };
+
+ prm: prm@48306000 {
+ compatible = "ti,omap3-prm";
+ reg = <0x48306000 0x4000>;
+ interrupts = <11>;
+
+ prm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ prm_clockdomains: clockdomains {
+ };
+ };
+
+ cm: cm@48004000 {
+ compatible = "ti,omap3-cm";
+ reg = <0x48004000 0x4000>;
+
+ cm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cm_clockdomains: clockdomains {
+ };
+ };
+
+ counter32k: counter@48320000 {
+ compatible = "ti,omap-counter32k";
+ reg = <0x48320000 0x20>;
+ ti,hwmods = "counter_32k";
+ };
+
+ intc: interrupt-controller@48200000 {
+ compatible = "ti,omap3-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x48200000 0x1000>;
+ };
+
+ sdma: dma-controller@48056000 {
+ compatible = "ti,omap3630-sdma", "ti,omap3430-sdma";
+ reg = <0x48056000 0x1000>;
+ interrupts = <12>,
+ <13>,
+ <14>,
+ <15>;
+ #dma-cells = <1>;
+ dma-channels = <32>;
+ dma-requests = <96>;
+ };
+
+ pbias_regulator: pbias_regulator {
+ compatible = "ti,pbias-omap";
+ reg = <0x2b0 0x4>;
+ syscon = <&scm_conf>;
+ pbias_mmc_reg: pbias_mmc_omap2430 {
+ regulator-name = "pbias_mmc_omap2430";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ };
+ };
+
+ gpio1: gpio@48310000 {
+ compatible = "ti,omap3-gpio";
+ reg = <0x48310000 0x200>;
+ interrupts = <29>;
+ ti,hwmods = "gpio1";
+ ti,gpio-always-on;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@49050000 {
+ compatible = "ti,omap3-gpio";
+ reg = <0x49050000 0x200>;
+ interrupts = <30>;
+ ti,hwmods = "gpio2";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@49052000 {
+ compatible = "ti,omap3-gpio";
+ reg = <0x49052000 0x200>;
+ interrupts = <31>;
+ ti,hwmods = "gpio3";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@49054000 {
+ compatible = "ti,omap3-gpio";
+ reg = <0x49054000 0x200>;
+ interrupts = <32>;
+ ti,hwmods = "gpio4";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio5: gpio@49056000 {
+ compatible = "ti,omap3-gpio";
+ reg = <0x49056000 0x200>;
+ interrupts = <33>;
+ ti,hwmods = "gpio5";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio6: gpio@49058000 {
+ compatible = "ti,omap3-gpio";
+ reg = <0x49058000 0x200>;
+ interrupts = <34>;
+ ti,hwmods = "gpio6";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart1: serial@4806a000 {
+ compatible = "ti,omap3-uart";
+ reg = <0x4806a000 0x2000>;
+ interrupts-extended = <&intc 72>;
+ dmas = <&sdma 49 &sdma 50>;
+ dma-names = "tx", "rx";
+ ti,hwmods = "uart1";
+ clock-frequency = <48000000>;
+ };
+
+ uart2: serial@4806c000 {
+ compatible = "ti,omap3-uart";
+ reg = <0x4806c000 0x400>;
+ interrupts-extended = <&intc 73>;
+ dmas = <&sdma 51 &sdma 52>;
+ dma-names = "tx", "rx";
+ ti,hwmods = "uart2";
+ clock-frequency = <48000000>;
+ };
+
+ uart3: serial@49020000 {
+ compatible = "ti,omap3-uart";
+ reg = <0x49020000 0x400>;
+ interrupts-extended = <&intc 74>;
+ dmas = <&sdma 53 &sdma 54>;
+ dma-names = "tx", "rx";
+ ti,hwmods = "uart3";
+ clock-frequency = <48000000>;
+ };
+
+ i2c1: i2c@48070000 {
+ compatible = "ti,omap3-i2c";
+ reg = <0x48070000 0x80>;
+ interrupts = <56>;
+ dmas = <&sdma 27 &sdma 28>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c1";
+ };
+
+ i2c2: i2c@48072000 {
+ compatible = "ti,omap3-i2c";
+ reg = <0x48072000 0x80>;
+ interrupts = <57>;
+ dmas = <&sdma 29 &sdma 30>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c2";
+ };
+
+ i2c3: i2c@48060000 {
+ compatible = "ti,omap3-i2c";
+ reg = <0x48060000 0x80>;
+ interrupts = <61>;
+ dmas = <&sdma 25 &sdma 26>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c3";
+ };
+
+ mailbox: mailbox@48094000 {
+ compatible = "ti,omap3-mailbox";
+ ti,hwmods = "mailbox";
+ reg = <0x48094000 0x200>;
+ interrupts = <26>;
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <2>;
+ ti,mbox-num-fifos = <2>;
+ mbox_dsp: dsp {
+ ti,mbox-tx = <0 0 0>;
+ ti,mbox-rx = <1 0 0>;
+ };
+ };
+
+ mcspi1: spi@48098000 {
+ compatible = "ti,omap2-mcspi";
+ reg = <0x48098000 0x100>;
+ interrupts = <65>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi1";
+ ti,spi-num-cs = <4>;
+ dmas = <&sdma 35>,
+ <&sdma 36>,
+ <&sdma 37>,
+ <&sdma 38>,
+ <&sdma 39>,
+ <&sdma 40>,
+ <&sdma 41>,
+ <&sdma 42>;
+ dma-names = "tx0", "rx0", "tx1", "rx1",
+ "tx2", "rx2", "tx3", "rx3";
+ };
+
+ mcspi2: spi@4809a000 {
+ compatible = "ti,omap2-mcspi";
+ reg = <0x4809a000 0x100>;
+ interrupts = <66>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi2";
+ ti,spi-num-cs = <2>;
+ dmas = <&sdma 43>,
+ <&sdma 44>,
+ <&sdma 45>,
+ <&sdma 46>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
+ };
+
+ mcspi3: spi@480b8000 {
+ compatible = "ti,omap2-mcspi";
+ reg = <0x480b8000 0x100>;
+ interrupts = <91>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi3";
+ ti,spi-num-cs = <2>;
+ dmas = <&sdma 15>,
+ <&sdma 16>,
+ <&sdma 23>,
+ <&sdma 24>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
+ };
+
+ mcspi4: spi@480ba000 {
+ compatible = "ti,omap2-mcspi";
+ reg = <0x480ba000 0x100>;
+ interrupts = <48>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi4";
+ ti,spi-num-cs = <1>;
+ dmas = <&sdma 70>, <&sdma 71>;
+ dma-names = "tx0", "rx0";
+ };
+
+ hdqw1w: 1w@480b2000 {
+ compatible = "ti,omap3-1w";
+ reg = <0x480b2000 0x1000>;
+ interrupts = <58>;
+ ti,hwmods = "hdq1w";
+ };
+
+ mmc1: mmc@4809c000 {
+ compatible = "ti,omap3-hsmmc";
+ reg = <0x4809c000 0x200>;
+ interrupts = <83>;
+ ti,hwmods = "mmc1";
+ ti,dual-volt;
+ dmas = <&sdma 61>, <&sdma 62>;
+ dma-names = "tx", "rx";
+ pbias-supply = <&pbias_mmc_reg>;
+ };
+
+ mmc2: mmc@480b4000 {
+ compatible = "ti,omap3-hsmmc";
+ reg = <0x480b4000 0x200>;
+ interrupts = <86>;
+ ti,hwmods = "mmc2";
+ dmas = <&sdma 47>, <&sdma 48>;
+ dma-names = "tx", "rx";
+ };
+
+ mmc3: mmc@480ad000 {
+ compatible = "ti,omap3-hsmmc";
+ reg = <0x480ad000 0x200>;
+ interrupts = <94>;
+ ti,hwmods = "mmc3";
+ dmas = <&sdma 77>, <&sdma 78>;
+ dma-names = "tx", "rx";
+ };
+
+ mmu_isp: mmu@480bd400 {
+ #iommu-cells = <0>;
+ compatible = "ti,omap2-iommu";
+ reg = <0x480bd400 0x80>;
+ interrupts = <24>;
+ ti,hwmods = "mmu_isp";
+ ti,#tlb-entries = <8>;
+ };
+
+ mmu_iva: mmu@5d000000 {
+ #iommu-cells = <0>;
+ compatible = "ti,omap2-iommu";
+ reg = <0x5d000000 0x80>;
+ interrupts = <28>;
+ ti,hwmods = "mmu_iva";
+ status = "disabled";
+ };
+
+ wdt2: wdt@48314000 {
+ compatible = "ti,omap3-wdt";
+ reg = <0x48314000 0x80>;
+ ti,hwmods = "wd_timer2";
+ };
+
+ mcbsp1: mcbsp@48074000 {
+ compatible = "ti,omap3-mcbsp";
+ reg = <0x48074000 0xff>;
+ reg-names = "mpu";
+ interrupts = <16>, /* OCP compliant interrupt */
+ <59>, /* TX interrupt */
+ <60>; /* RX interrupt */
+ interrupt-names = "common", "tx", "rx";
+ ti,buffer-size = <128>;
+ ti,hwmods = "mcbsp1";
+ dmas = <&sdma 31>,
+ <&sdma 32>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mcbsp2: mcbsp@49022000 {
+ compatible = "ti,omap3-mcbsp";
+ reg = <0x49022000 0xff>,
+ <0x49028000 0xff>;
+ reg-names = "mpu", "sidetone";
+ interrupts = <17>, /* OCP compliant interrupt */
+ <62>, /* TX interrupt */
+ <63>, /* RX interrupt */
+ <4>; /* Sidetone */
+ interrupt-names = "common", "tx", "rx", "sidetone";
+ ti,buffer-size = <1280>;
+ ti,hwmods = "mcbsp2", "mcbsp2_sidetone";
+ dmas = <&sdma 33>,
+ <&sdma 34>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mcbsp3: mcbsp@49024000 {
+ compatible = "ti,omap3-mcbsp";
+ reg = <0x49024000 0xff>,
+ <0x4902a000 0xff>;
+ reg-names = "mpu", "sidetone";
+ interrupts = <22>, /* OCP compliant interrupt */
+ <89>, /* TX interrupt */
+ <90>, /* RX interrupt */
+ <5>; /* Sidetone */
+ interrupt-names = "common", "tx", "rx", "sidetone";
+ ti,buffer-size = <128>;
+ ti,hwmods = "mcbsp3", "mcbsp3_sidetone";
+ dmas = <&sdma 17>,
+ <&sdma 18>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mcbsp4: mcbsp@49026000 {
+ compatible = "ti,omap3-mcbsp";
+ reg = <0x49026000 0xff>;
+ reg-names = "mpu";
+ interrupts = <23>, /* OCP compliant interrupt */
+ <54>, /* TX interrupt */
+ <55>; /* RX interrupt */
+ interrupt-names = "common", "tx", "rx";
+ ti,buffer-size = <128>;
+ ti,hwmods = "mcbsp4";
+ dmas = <&sdma 19>,
+ <&sdma 20>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mcbsp5: mcbsp@48096000 {
+ compatible = "ti,omap3-mcbsp";
+ reg = <0x48096000 0xff>;
+ reg-names = "mpu";
+ interrupts = <27>, /* OCP compliant interrupt */
+ <81>, /* TX interrupt */
+ <82>; /* RX interrupt */
+ interrupt-names = "common", "tx", "rx";
+ ti,buffer-size = <128>;
+ ti,hwmods = "mcbsp5";
+ dmas = <&sdma 21>,
+ <&sdma 22>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ sham: sham@480c3000 {
+ compatible = "ti,omap3-sham";
+ ti,hwmods = "sham";
+ reg = <0x480c3000 0x64>;
+ interrupts = <49>;
+ dmas = <&sdma 69>;
+ dma-names = "rx";
+ };
+
+ smartreflex_core: smartreflex@480cb000 {
+ compatible = "ti,omap3-smartreflex-core";
+ ti,hwmods = "smartreflex_core";
+ reg = <0x480cb000 0x400>;
+ interrupts = <19>;
+ };
+
+ smartreflex_mpu_iva: smartreflex@480c9000 {
+ compatible = "ti,omap3-smartreflex-iva";
+ ti,hwmods = "smartreflex_mpu_iva";
+ reg = <0x480c9000 0x400>;
+ interrupts = <18>;
+ };
+
+ timer1: timer@48318000 {
+ compatible = "ti,omap3430-timer";
+ reg = <0x48318000 0x400>;
+ interrupts = <37>;
+ ti,hwmods = "timer1";
+ ti,timer-alwon;
+ };
+
+ timer2: timer@49032000 {
+ compatible = "ti,omap3430-timer";
+ reg = <0x49032000 0x400>;
+ interrupts = <38>;
+ ti,hwmods = "timer2";
+ };
+
+ timer3: timer@49034000 {
+ compatible = "ti,omap3430-timer";
+ reg = <0x49034000 0x400>;
+ interrupts = <39>;
+ ti,hwmods = "timer3";
+ };
+
+ timer4: timer@49036000 {
+ compatible = "ti,omap3430-timer";
+ reg = <0x49036000 0x400>;
+ interrupts = <40>;
+ ti,hwmods = "timer4";
+ };
+
+ timer5: timer@49038000 {
+ compatible = "ti,omap3430-timer";
+ reg = <0x49038000 0x400>;
+ interrupts = <41>;
+ ti,hwmods = "timer5";
+ ti,timer-dsp;
+ };
+
+ timer6: timer@4903a000 {
+ compatible = "ti,omap3430-timer";
+ reg = <0x4903a000 0x400>;
+ interrupts = <42>;
+ ti,hwmods = "timer6";
+ ti,timer-dsp;
+ };
+
+ timer7: timer@4903c000 {
+ compatible = "ti,omap3430-timer";
+ reg = <0x4903c000 0x400>;
+ interrupts = <43>;
+ ti,hwmods = "timer7";
+ ti,timer-dsp;
+ };
+
+ timer8: timer@4903e000 {
+ compatible = "ti,omap3430-timer";
+ reg = <0x4903e000 0x400>;
+ interrupts = <44>;
+ ti,hwmods = "timer8";
+ ti,timer-pwm;
+ ti,timer-dsp;
+ };
+
+ timer9: timer@49040000 {
+ compatible = "ti,omap3430-timer";
+ reg = <0x49040000 0x400>;
+ interrupts = <45>;
+ ti,hwmods = "timer9";
+ ti,timer-pwm;
+ };
+
+ timer10: timer@48086000 {
+ compatible = "ti,omap3430-timer";
+ reg = <0x48086000 0x400>;
+ interrupts = <46>;
+ ti,hwmods = "timer10";
+ ti,timer-pwm;
+ };
+
+ timer11: timer@48088000 {
+ compatible = "ti,omap3430-timer";
+ reg = <0x48088000 0x400>;
+ interrupts = <47>;
+ ti,hwmods = "timer11";
+ ti,timer-pwm;
+ };
+
+ timer12: timer@48304000 {
+ compatible = "ti,omap3430-timer";
+ reg = <0x48304000 0x400>;
+ interrupts = <95>;
+ ti,hwmods = "timer12";
+ ti,timer-alwon;
+ ti,timer-secure;
+ };
+
+ usbhstll: usbhstll@48062000 {
+ compatible = "ti,usbhs-tll";
+ reg = <0x48062000 0x1000>;
+ interrupts = <78>;
+ ti,hwmods = "usb_tll_hs";
+ };
+
+ usbhshost: usbhshost@48064000 {
+ compatible = "ti,usbhs-host";
+ reg = <0x48064000 0x400>;
+ ti,hwmods = "usb_host_hs";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ usbhsohci: ohci@48064400 {
+ compatible = "ti,ohci-omap3";
+ reg = <0x48064400 0x400>;
+ interrupt-parent = <&intc>;
+ interrupts = <76>;
+ };
+
+ usbhsehci: ehci@48064800 {
+ compatible = "ti,ehci-omap";
+ reg = <0x48064800 0x400>;
+ interrupt-parent = <&intc>;
+ interrupts = <77>;
+ };
+ };
+
+ gpmc: gpmc@6e000000 {
+ compatible = "ti,omap3430-gpmc";
+ ti,hwmods = "gpmc";
+ reg = <0x6e000000 0x02d0>;
+ interrupts = <20>;
+ gpmc,num-cs = <8>;
+ gpmc,num-waitpins = <4>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ };
+
+ usb_otg_hs: usb_otg_hs@480ab000 {
+ compatible = "ti,omap3-musb";
+ reg = <0x480ab000 0x1000>;
+ interrupts = <92>, <93>;
+ interrupt-names = "mc", "dma";
+ ti,hwmods = "usb_otg_hs";
+ multipoint = <1>;
+ num-eps = <16>;
+ ram-bits = <12>;
+ };
+
+ dss: dss@48050000 {
+ compatible = "ti,omap3-dss";
+ reg = <0x48050000 0x200>;
+ status = "disabled";
+ ti,hwmods = "dss_core";
+ clocks = <&dss1_alwon_fck>;
+ clock-names = "fck";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dispc@48050400 {
+ compatible = "ti,omap3-dispc";
+ reg = <0x48050400 0x400>;
+ interrupts = <25>;
+ ti,hwmods = "dss_dispc";
+ clocks = <&dss1_alwon_fck>;
+ clock-names = "fck";
+ };
+
+ dsi: encoder@4804fc00 {
+ compatible = "ti,omap3-dsi";
+ reg = <0x4804fc00 0x200>,
+ <0x4804fe00 0x40>,
+ <0x4804ff00 0x20>;
+ reg-names = "proto", "phy", "pll";
+ interrupts = <25>;
+ status = "disabled";
+ ti,hwmods = "dss_dsi1";
+ clocks = <&dss1_alwon_fck>, <&dss2_alwon_fck>;
+ clock-names = "fck", "sys_clk";
+ };
+
+ rfbi: encoder@48050800 {
+ compatible = "ti,omap3-rfbi";
+ reg = <0x48050800 0x100>;
+ status = "disabled";
+ ti,hwmods = "dss_rfbi";
+ clocks = <&dss1_alwon_fck>, <&dss_ick>;
+ clock-names = "fck", "ick";
+ };
+
+ venc: encoder@48050c00 {
+ compatible = "ti,omap3-venc";
+ reg = <0x48050c00 0x100>;
+ status = "disabled";
+ ti,hwmods = "dss_venc";
+ clocks = <&dss_tv_fck>;
+ clock-names = "fck";
+ };
+ };
+
+ ssi: ssi-controller@48058000 {
+ compatible = "ti,omap3-ssi";
+ ti,hwmods = "ssi";
+
+ status = "disabled";
+
+ reg = <0x48058000 0x1000>,
+ <0x48059000 0x1000>;
+ reg-names = "sys",
+ "gdd";
+
+ interrupts = <71>;
+ interrupt-names = "gdd_mpu";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ ssi_port1: ssi-port@4805a000 {
+ compatible = "ti,omap3-ssi-port";
+
+ reg = <0x4805a000 0x800>,
+ <0x4805a800 0x800>;
+ reg-names = "tx",
+ "rx";
+
+ interrupt-parent = <&intc>;
+ interrupts = <67>,
+ <68>;
+ };
+
+ ssi_port2: ssi-port@4805b000 {
+ compatible = "ti,omap3-ssi-port";
+
+ reg = <0x4805b000 0x800>,
+ <0x4805b800 0x800>;
+ reg-names = "tx",
+ "rx";
+
+ interrupt-parent = <&intc>;
+ interrupts = <69>,
+ <70>;
+ };
+ };
+ };
+};
+
+/include/ "omap3xxx-clocks.dtsi"
diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
new file mode 100644
index 000000000..16b0cdfbe
--- /dev/null
+++ b/arch/arm/boot/dts/omap3430-sdp.dts
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+/dts-v1/;
+
+#include "omap34xx.dtsi"
+
+/ {
+ model = "TI OMAP3430 SDP";
+ compatible = "ti,omap3430-sdp", "ti,omap3";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+};
+
+&i2c1 {
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&mmc1 {
+ vmmc-supply = <&vmmc1>;
+ vmmc_aux-supply = <&vsim>;
+ /*
+ * S6-3 must be in ON position for 8 bit mode to function
+ * Else, use 4 bit mode
+ */
+ bus-width = <8>;
+};
+
+&mmc2 {
+ status = "disabled";
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&gpmc {
+ ranges = <0 0 0x10000000 0x08000000>,
+ <1 0 0x28000000 0x1000000>, /* CS1: 16MB for NAND */
+ <2 0 0x20000000 0x1000000>; /* CS2: 16MB for OneNAND */
+
+ nor@0,0 {
+ compatible = "cfi-flash";
+ linux,mtd-name= "intel,pf48f6000m0y1be";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0 0x08000000>;
+ bank-width = <2>;
+
+ gpmc,mux-add-data = <2>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <186>;
+ gpmc,cs-wr-off-ns = <186>;
+ gpmc,adv-on-ns = <12>;
+ gpmc,adv-rd-off-ns = <48>;
+ gpmc,adv-wr-off-ns = <48>;
+ gpmc,oe-on-ns = <54>;
+ gpmc,oe-off-ns = <168>;
+ gpmc,we-on-ns = <54>;
+ gpmc,we-off-ns = <168>;
+ gpmc,rd-cycle-ns = <186>;
+ gpmc,wr-cycle-ns = <186>;
+ gpmc,access-ns = <114>;
+ gpmc,page-burst-access-ns = <6>;
+ gpmc,bus-turnaround-ns = <12>;
+ gpmc,cycle2cycle-delay-ns = <18>;
+ gpmc,wr-data-mux-bus-ns = <90>;
+ gpmc,wr-access-ns = <186>;
+ gpmc,cycle2cycle-samecsen;
+ gpmc,cycle2cycle-diffcsen;
+
+ partition@0 {
+ label = "bootloader-nor";
+ reg = <0 0x40000>;
+ };
+ partition@40000 {
+ label = "params-nor";
+ reg = <0x40000 0x40000>;
+ };
+ partition@80000 {
+ label = "kernel-nor";
+ reg = <0x80000 0x200000>;
+ };
+ partition@280000 {
+ label = "filesystem-nor";
+ reg = <0x240000 0x7d80000>;
+ };
+ };
+
+ nand@1,0 {
+ linux,mtd-name= "micron,mt29f1g08abb";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <1 0 4>; /* CS1, offset 0, IO size 4 */
+ ti,nand-ecc-opt = "sw";
+ nand-bus-width = <8>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <36>;
+ gpmc,cs-wr-off-ns = <36>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <24>;
+ gpmc,adv-wr-off-ns = <36>;
+ gpmc,oe-on-ns = <6>;
+ gpmc,oe-off-ns = <48>;
+ gpmc,we-on-ns = <6>;
+ gpmc,we-off-ns = <30>;
+ gpmc,rd-cycle-ns = <72>;
+ gpmc,wr-cycle-ns = <72>;
+ gpmc,access-ns = <54>;
+ gpmc,wr-access-ns = <30>;
+
+ partition@0 {
+ label = "xloader-nand";
+ reg = <0 0x80000>;
+ };
+ partition@80000 {
+ label = "bootloader-nand";
+ reg = <0x80000 0x140000>;
+ };
+ partition@1c0000 {
+ label = "params-nand";
+ reg = <0x1c0000 0xc0000>;
+ };
+ partition@280000 {
+ label = "kernel-nand";
+ reg = <0x280000 0x500000>;
+ };
+ partition@780000 {
+ label = "filesystem-nand";
+ reg = <0x780000 0x7880000>;
+ };
+ };
+
+ onenand@2,0 {
+ linux,mtd-name= "samsung,kfm2g16q2m-deb8";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <2 0 0x20000>; /* CS2, offset 0, IO size 4 */
+
+ gpmc,device-width = <2>;
+ gpmc,mux-add-data = <2>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <84>;
+ gpmc,cs-wr-off-ns = <72>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <18>;
+ gpmc,adv-wr-off-ns = <18>;
+ gpmc,oe-on-ns = <30>;
+ gpmc,oe-off-ns = <84>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <42>;
+ gpmc,rd-cycle-ns = <108>;
+ gpmc,wr-cycle-ns = <96>;
+ gpmc,access-ns = <78>;
+ gpmc,wr-data-mux-bus-ns = <30>;
+
+ partition@0 {
+ label = "xloader-onenand";
+ reg = <0 0x80000>;
+ };
+ partition@80000 {
+ label = "bootloader-onenand";
+ reg = <0x80000 0x40000>;
+ };
+ partition@c0000 {
+ label = "params-onenand";
+ reg = <0xc0000 0x20000>;
+ };
+ partition@e0000 {
+ label = "kernel-onenand";
+ reg = <0xe0000 0x200000>;
+ };
+ partition@2e0000 {
+ label = "filesystem-onenand";
+ reg = <0x2e0000 0xfd20000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap3430es1-clocks.dtsi b/arch/arm/boot/dts/omap3430es1-clocks.dtsi
new file mode 100644
index 000000000..4c22f3a7f
--- /dev/null
+++ b/arch/arm/boot/dts/omap3430es1-clocks.dtsi
@@ -0,0 +1,208 @@
+/*
+ * Device Tree Source for OMAP3430 ES1 clock data
+ *
+ * Copyright (C) 2013 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.
+ */
+&cm_clocks {
+ gfx_l3_ck: gfx_l3_ck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&l3_ick>;
+ reg = <0x0b10>;
+ ti,bit-shift = <0>;
+ };
+
+ gfx_l3_fck: gfx_l3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&l3_ick>;
+ ti,max-div = <7>;
+ reg = <0x0b40>;
+ ti,index-starts-at-one;
+ };
+
+ gfx_l3_ick: gfx_l3_ick {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&gfx_l3_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ gfx_cg1_ck: gfx_cg1_ck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&gfx_l3_fck>;
+ reg = <0x0b00>;
+ ti,bit-shift = <1>;
+ };
+
+ gfx_cg2_ck: gfx_cg2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&gfx_l3_fck>;
+ reg = <0x0b00>;
+ ti,bit-shift = <2>;
+ };
+
+ d2d_26m_fck: d2d_26m_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&sys_ck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <3>;
+ };
+
+ fshostusb_fck: fshostusb_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_48m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <5>;
+ };
+
+ ssi_ssr_gate_fck_3430es1: ssi_ssr_gate_fck_3430es1 {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&corex2_fck>;
+ ti,bit-shift = <0>;
+ reg = <0x0a00>;
+ };
+
+ ssi_ssr_div_fck_3430es1: ssi_ssr_div_fck_3430es1 {
+ #clock-cells = <0>;
+ compatible = "ti,composite-divider-clock";
+ clocks = <&corex2_fck>;
+ ti,bit-shift = <8>;
+ reg = <0x0a40>;
+ ti,dividers = <0>, <1>, <2>, <3>, <4>, <0>, <6>, <0>, <8>;
+ };
+
+ ssi_ssr_fck: ssi_ssr_fck_3430es1 {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&ssi_ssr_gate_fck_3430es1>, <&ssi_ssr_div_fck_3430es1>;
+ };
+
+ ssi_sst_fck: ssi_sst_fck_3430es1 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&ssi_ssr_fck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ hsotgusb_ick_3430es1: hsotgusb_ick_3430es1 {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-no-wait-interface-clock";
+ clocks = <&core_l3_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <4>;
+ };
+
+ fac_ick: fac_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <8>;
+ };
+
+ ssi_l4_ick: ssi_l4_ick {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&l4_ick>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ ssi_ick: ssi_ick_3430es1 {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-no-wait-interface-clock";
+ clocks = <&ssi_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <0>;
+ };
+
+ usb_l4_gate_ick: usb_l4_gate_ick {
+ #clock-cells = <0>;
+ compatible = "ti,composite-interface-clock";
+ clocks = <&l4_ick>;
+ ti,bit-shift = <5>;
+ reg = <0x0a10>;
+ };
+
+ usb_l4_div_ick: usb_l4_div_ick {
+ #clock-cells = <0>;
+ compatible = "ti,composite-divider-clock";
+ clocks = <&l4_ick>;
+ ti,bit-shift = <4>;
+ ti,max-div = <1>;
+ reg = <0x0a40>;
+ ti,index-starts-at-one;
+ };
+
+ usb_l4_ick: usb_l4_ick {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&usb_l4_gate_ick>, <&usb_l4_div_ick>;
+ };
+
+ dss1_alwon_fck: dss1_alwon_fck_3430es1 {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll4_m4x2_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x0e00>;
+ ti,set-rate-parent;
+ };
+
+ dss_ick: dss_ick_3430es1 {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-no-wait-interface-clock";
+ clocks = <&l4_ick>;
+ reg = <0x0e10>;
+ ti,bit-shift = <0>;
+ };
+};
+
+&cm_clockdomains {
+ core_l3_clkdm: core_l3_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&sdrc_ick>, <&hsotgusb_ick_3430es1>;
+ };
+
+ gfx_3430es1_clkdm: gfx_3430es1_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&gfx_l3_ck>, <&gfx_cg1_ck>, <&gfx_cg2_ck>;
+ };
+
+ dss_clkdm: dss_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&dss_tv_fck>, <&dss_96m_fck>, <&dss2_alwon_fck>,
+ <&dss1_alwon_fck>, <&dss_ick>;
+ };
+
+ d2d_clkdm: d2d_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&d2d_26m_fck>;
+ };
+
+ core_l4_clkdm: core_l4_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&mmchs2_fck>, <&mmchs1_fck>, <&i2c3_fck>, <&i2c2_fck>,
+ <&i2c1_fck>, <&mcspi4_fck>, <&mcspi3_fck>,
+ <&mcspi2_fck>, <&mcspi1_fck>, <&uart2_fck>,
+ <&uart1_fck>, <&hdq_fck>, <&mmchs2_ick>, <&mmchs1_ick>,
+ <&hdq_ick>, <&mcspi4_ick>, <&mcspi3_ick>,
+ <&mcspi2_ick>, <&mcspi1_ick>, <&i2c3_ick>, <&i2c2_ick>,
+ <&i2c1_ick>, <&uart2_ick>, <&uart1_ick>, <&gpt11_ick>,
+ <&gpt10_ick>, <&mcbsp5_ick>, <&mcbsp1_ick>,
+ <&omapctrl_ick>, <&aes2_ick>, <&sha12_ick>,
+ <&fshostusb_fck>, <&fac_ick>, <&ssi_ick>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap34xx-omap36xx-clocks.dtsi b/arch/arm/boot/dts/omap34xx-omap36xx-clocks.dtsi
new file mode 100644
index 000000000..b02017b76
--- /dev/null
+++ b/arch/arm/boot/dts/omap34xx-omap36xx-clocks.dtsi
@@ -0,0 +1,268 @@
+/*
+ * Device Tree Source for OMAP34XX/OMAP36XX clock data
+ *
+ * Copyright (C) 2013 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.
+ */
+&cm_clocks {
+ security_l4_ick2: security_l4_ick2 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&l4_ick>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ aes1_ick: aes1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&security_l4_ick2>;
+ ti,bit-shift = <3>;
+ reg = <0x0a14>;
+ };
+
+ rng_ick: rng_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&security_l4_ick2>;
+ reg = <0x0a14>;
+ ti,bit-shift = <2>;
+ };
+
+ sha11_ick: sha11_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&security_l4_ick2>;
+ reg = <0x0a14>;
+ ti,bit-shift = <1>;
+ };
+
+ des1_ick: des1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&security_l4_ick2>;
+ reg = <0x0a14>;
+ ti,bit-shift = <0>;
+ };
+
+ cam_mclk: cam_mclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll4_m5x2_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x0f00>;
+ ti,set-rate-parent;
+ };
+
+ cam_ick: cam_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-no-wait-interface-clock";
+ clocks = <&l4_ick>;
+ reg = <0x0f10>;
+ ti,bit-shift = <0>;
+ };
+
+ csi2_96m_fck: csi2_96m_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&core_96m_fck>;
+ reg = <0x0f00>;
+ ti,bit-shift = <1>;
+ };
+
+ security_l3_ick: security_l3_ick {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&l3_ick>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ pka_ick: pka_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&security_l3_ick>;
+ reg = <0x0a14>;
+ ti,bit-shift = <4>;
+ };
+
+ icr_ick: icr_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <29>;
+ };
+
+ des2_ick: des2_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <26>;
+ };
+
+ mspro_ick: mspro_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <23>;
+ };
+
+ mailboxes_ick: mailboxes_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <7>;
+ };
+
+ ssi_l4_ick: ssi_l4_ick {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&l4_ick>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ sr1_fck: sr1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&sys_ck>;
+ reg = <0x0c00>;
+ ti,bit-shift = <6>;
+ };
+
+ sr2_fck: sr2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&sys_ck>;
+ reg = <0x0c00>;
+ ti,bit-shift = <7>;
+ };
+
+ sr_l4_ick: sr_l4_ick {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&l4_ick>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll2_fck: dpll2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&core_ck>;
+ ti,bit-shift = <19>;
+ ti,max-div = <7>;
+ reg = <0x0040>;
+ ti,index-starts-at-one;
+ };
+
+ dpll2_ck: dpll2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-dpll-clock";
+ clocks = <&sys_ck>, <&dpll2_fck>;
+ reg = <0x0004>, <0x0024>, <0x0040>, <0x0034>;
+ ti,low-power-stop;
+ ti,lock;
+ ti,low-power-bypass;
+ };
+
+ dpll2_m2_ck: dpll2_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll2_ck>;
+ ti,max-div = <31>;
+ reg = <0x0044>;
+ ti,index-starts-at-one;
+ };
+
+ iva2_ck: iva2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&dpll2_m2_ck>;
+ reg = <0x0000>;
+ ti,bit-shift = <0>;
+ };
+
+ modem_fck: modem_fck {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&sys_ck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <31>;
+ };
+
+ sad2d_ick: sad2d_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l3_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <3>;
+ };
+
+ mad2d_ick: mad2d_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&l3_ick>;
+ reg = <0x0a18>;
+ ti,bit-shift = <3>;
+ };
+
+ mspro_fck: mspro_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_96m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <23>;
+ };
+};
+
+&cm_clockdomains {
+ cam_clkdm: cam_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&cam_ick>, <&csi2_96m_fck>;
+ };
+
+ iva2_clkdm: iva2_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&iva2_ck>;
+ };
+
+ dpll2_clkdm: dpll2_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&dpll2_ck>;
+ };
+
+ wkup_clkdm: wkup_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&gpio1_dbck>, <&wdt2_fck>, <&wdt2_ick>, <&wdt1_ick>,
+ <&gpio1_ick>, <&omap_32ksync_ick>, <&gpt12_ick>,
+ <&gpt1_ick>, <&sr1_fck>, <&sr2_fck>;
+ };
+
+ d2d_clkdm: d2d_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&modem_fck>, <&sad2d_ick>, <&mad2d_ick>;
+ };
+
+ core_l4_clkdm: core_l4_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&mmchs2_fck>, <&mmchs1_fck>, <&i2c3_fck>, <&i2c2_fck>,
+ <&i2c1_fck>, <&mcspi4_fck>, <&mcspi3_fck>,
+ <&mcspi2_fck>, <&mcspi1_fck>, <&uart2_fck>,
+ <&uart1_fck>, <&hdq_fck>, <&mmchs2_ick>, <&mmchs1_ick>,
+ <&hdq_ick>, <&mcspi4_ick>, <&mcspi3_ick>,
+ <&mcspi2_ick>, <&mcspi1_ick>, <&i2c3_ick>, <&i2c2_ick>,
+ <&i2c1_ick>, <&uart2_ick>, <&uart1_ick>, <&gpt11_ick>,
+ <&gpt10_ick>, <&mcbsp5_ick>, <&mcbsp1_ick>,
+ <&omapctrl_ick>, <&aes2_ick>, <&sha12_ick>, <&icr_ick>,
+ <&des2_ick>, <&mspro_ick>, <&mailboxes_ick>,
+ <&mspro_fck>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap34xx.dtsi b/arch/arm/boot/dts/omap34xx.dtsi
new file mode 100644
index 000000000..4f6b2d5b1
--- /dev/null
+++ b/arch/arm/boot/dts/omap34xx.dtsi
@@ -0,0 +1,73 @@
+/*
+ * Device Tree Source for OMAP34xx/OMAP35xx SoC
+ *
+ * Copyright (C) 2013 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 <dt-bindings/media/omap3-isp.h>
+
+#include "omap3.dtsi"
+
+/ {
+ cpus {
+ cpu@0 {
+ /* OMAP343x/OMAP35xx variants OPP1-5 */
+ operating-points = <
+ /* kHz uV */
+ 125000 975000
+ 250000 1075000
+ 500000 1200000
+ 550000 1270000
+ 600000 1350000
+ >;
+ clock-latency = <300000>; /* From legacy driver */
+ };
+ };
+
+ ocp {
+ omap3_pmx_core2: pinmux@480025d8 {
+ compatible = "ti,omap3-padconf", "pinctrl-single";
+ reg = <0x480025d8 0x24>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ pinctrl-single,register-width = <16>;
+ pinctrl-single,function-mask = <0xff1f>;
+ };
+
+ isp: isp@480bc000 {
+ compatible = "ti,omap3-isp";
+ reg = <0x480bc000 0x12fc
+ 0x480bd800 0x017c>;
+ interrupts = <24>;
+ iommus = <&mmu_isp>;
+ syscon = <&scm_conf 0xdc>;
+ ti,phy-type = <OMAP3ISP_PHY_TYPE_COMPLEX_IO>;
+ #clock-cells = <1>;
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+};
+
+&ssi {
+ status = "ok";
+
+ clocks = <&ssi_ssr_fck>,
+ <&ssi_sst_fck>,
+ <&ssi_ick>;
+ clock-names = "ssi_ssr_fck",
+ "ssi_sst_fck",
+ "ssi_ick";
+};
+
+/include/ "omap34xx-omap36xx-clocks.dtsi"
+/include/ "omap36xx-omap3430es2plus-clocks.dtsi"
+/include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi"
diff --git a/arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi b/arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi
new file mode 100644
index 000000000..080fb3f4e
--- /dev/null
+++ b/arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi
@@ -0,0 +1,242 @@
+/*
+ * Device Tree Source for OMAP36xx/AM35xx/OMAP34xx clock data
+ *
+ * Copyright (C) 2013 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.
+ */
+&prm_clocks {
+ corex2_d3_fck: corex2_d3_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&corex2_fck>;
+ clock-mult = <1>;
+ clock-div = <3>;
+ };
+
+ corex2_d5_fck: corex2_d5_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&corex2_fck>;
+ clock-mult = <1>;
+ clock-div = <5>;
+ };
+};
+&cm_clocks {
+ dpll5_ck: dpll5_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-dpll-clock";
+ clocks = <&sys_ck>, <&sys_ck>;
+ reg = <0x0d04>, <0x0d24>, <0x0d4c>, <0x0d34>;
+ ti,low-power-stop;
+ ti,lock;
+ };
+
+ dpll5_m2_ck: dpll5_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll5_ck>;
+ ti,max-div = <31>;
+ reg = <0x0d50>;
+ ti,index-starts-at-one;
+ };
+
+ sgx_gate_fck: sgx_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&core_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0b00>;
+ };
+
+ core_d3_ck: core_d3_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&core_ck>;
+ clock-mult = <1>;
+ clock-div = <3>;
+ };
+
+ core_d4_ck: core_d4_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&core_ck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ core_d6_ck: core_d6_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&core_ck>;
+ clock-mult = <1>;
+ clock-div = <6>;
+ };
+
+ omap_192m_alwon_fck: omap_192m_alwon_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll4_m2x2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ core_d2_ck: core_d2_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&core_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ sgx_mux_fck: sgx_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&core_d3_ck>, <&core_d4_ck>, <&core_d6_ck>, <&cm_96m_fck>, <&omap_192m_alwon_fck>, <&core_d2_ck>, <&corex2_d3_fck>, <&corex2_d5_fck>;
+ reg = <0x0b40>;
+ };
+
+ sgx_fck: sgx_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&sgx_gate_fck>, <&sgx_mux_fck>;
+ };
+
+ sgx_ick: sgx_ick {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&l3_ick>;
+ reg = <0x0b10>;
+ ti,bit-shift = <0>;
+ };
+
+ cpefuse_fck: cpefuse_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_ck>;
+ reg = <0x0a08>;
+ ti,bit-shift = <0>;
+ };
+
+ ts_fck: ts_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&omap_32k_fck>;
+ reg = <0x0a08>;
+ ti,bit-shift = <1>;
+ };
+
+ usbtll_fck: usbtll_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&dpll5_m2_ck>;
+ reg = <0x0a08>;
+ ti,bit-shift = <2>;
+ };
+
+ usbtll_ick: usbtll_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a18>;
+ ti,bit-shift = <2>;
+ };
+
+ mmchs3_ick: mmchs3_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <30>;
+ };
+
+ mmchs3_fck: mmchs3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_96m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <30>;
+ };
+
+ dss1_alwon_fck: dss1_alwon_fck_3430es2 {
+ #clock-cells = <0>;
+ compatible = "ti,dss-gate-clock";
+ clocks = <&dpll4_m4x2_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x0e00>;
+ ti,set-rate-parent;
+ };
+
+ dss_ick: dss_ick_3430es2 {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-dss-interface-clock";
+ clocks = <&l4_ick>;
+ reg = <0x0e10>;
+ ti,bit-shift = <0>;
+ };
+
+ usbhost_120m_fck: usbhost_120m_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll5_m2_ck>;
+ reg = <0x1400>;
+ ti,bit-shift = <1>;
+ };
+
+ usbhost_48m_fck: usbhost_48m_fck {
+ #clock-cells = <0>;
+ compatible = "ti,dss-gate-clock";
+ clocks = <&omap_48m_fck>;
+ reg = <0x1400>;
+ ti,bit-shift = <0>;
+ };
+
+ usbhost_ick: usbhost_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-dss-interface-clock";
+ clocks = <&l4_ick>;
+ reg = <0x1410>;
+ ti,bit-shift = <0>;
+ };
+};
+
+&cm_clockdomains {
+ dpll5_clkdm: dpll5_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&dpll5_ck>;
+ };
+
+ sgx_clkdm: sgx_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&sgx_ick>;
+ };
+
+ dss_clkdm: dss_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&dss_tv_fck>, <&dss_96m_fck>, <&dss2_alwon_fck>,
+ <&dss1_alwon_fck>, <&dss_ick>;
+ };
+
+ core_l4_clkdm: core_l4_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&mmchs2_fck>, <&mmchs1_fck>, <&i2c3_fck>, <&i2c2_fck>,
+ <&i2c1_fck>, <&mcspi4_fck>, <&mcspi3_fck>,
+ <&mcspi2_fck>, <&mcspi1_fck>, <&uart2_fck>,
+ <&uart1_fck>, <&hdq_fck>, <&mmchs2_ick>, <&mmchs1_ick>,
+ <&hdq_ick>, <&mcspi4_ick>, <&mcspi3_ick>,
+ <&mcspi2_ick>, <&mcspi1_ick>, <&i2c3_ick>, <&i2c2_ick>,
+ <&i2c1_ick>, <&uart2_ick>, <&uart1_ick>, <&gpt11_ick>,
+ <&gpt10_ick>, <&mcbsp5_ick>, <&mcbsp1_ick>,
+ <&omapctrl_ick>, <&aes2_ick>, <&sha12_ick>,
+ <&cpefuse_fck>, <&ts_fck>, <&usbtll_fck>,
+ <&usbtll_ick>, <&mmchs3_ick>, <&mmchs3_fck>;
+ };
+
+ usbhost_clkdm: usbhost_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&usbhost_120m_fck>, <&usbhost_48m_fck>,
+ <&usbhost_ick>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap36xx-clocks.dtsi b/arch/arm/boot/dts/omap36xx-clocks.dtsi
new file mode 100644
index 000000000..200ae3a5c
--- /dev/null
+++ b/arch/arm/boot/dts/omap36xx-clocks.dtsi
@@ -0,0 +1,110 @@
+/*
+ * Device Tree Source for OMAP36xx clock data
+ *
+ * Copyright (C) 2013 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.
+ */
+&cm_clocks {
+ dpll4_ck: dpll4_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-dpll-per-j-type-clock";
+ clocks = <&sys_ck>, <&sys_ck>;
+ reg = <0x0d00>, <0x0d20>, <0x0d44>, <0x0d30>;
+ };
+
+ dpll4_m5x2_ck: dpll4_m5x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,hsdiv-gate-clock";
+ clocks = <&dpll4_m5x2_mul_ck>;
+ ti,bit-shift = <0x1e>;
+ reg = <0x0d00>;
+ ti,set-rate-parent;
+ ti,set-bit-to-disable;
+ };
+
+ dpll4_m2x2_ck: dpll4_m2x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,hsdiv-gate-clock";
+ clocks = <&dpll4_m2x2_mul_ck>;
+ ti,bit-shift = <0x1b>;
+ reg = <0x0d00>;
+ ti,set-bit-to-disable;
+ };
+
+ dpll3_m3x2_ck: dpll3_m3x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,hsdiv-gate-clock";
+ clocks = <&dpll3_m3x2_mul_ck>;
+ ti,bit-shift = <0xc>;
+ reg = <0x0d00>;
+ ti,set-bit-to-disable;
+ };
+
+ dpll4_m3x2_ck: dpll4_m3x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,hsdiv-gate-clock";
+ clocks = <&dpll4_m3x2_mul_ck>;
+ ti,bit-shift = <0x1c>;
+ reg = <0x0d00>;
+ ti,set-bit-to-disable;
+ };
+
+ dpll4_m6x2_ck: dpll4_m6x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,hsdiv-gate-clock";
+ clocks = <&dpll4_m6x2_mul_ck>;
+ ti,bit-shift = <0x1f>;
+ reg = <0x0d00>;
+ ti,set-bit-to-disable;
+ };
+
+ uart4_fck: uart4_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&per_48m_fck>;
+ reg = <0x1000>;
+ ti,bit-shift = <18>;
+ };
+};
+
+&dpll4_m2x2_mul_ck {
+ clock-mult = <1>;
+};
+
+&dpll4_m3x2_mul_ck {
+ clock-mult = <1>;
+};
+
+&dpll4_m4x2_mul_ck {
+ ti,clock-mult = <1>;
+};
+
+&dpll4_m5x2_mul_ck {
+ ti,clock-mult = <1>;
+};
+
+&dpll4_m6x2_mul_ck {
+ clock-mult = <1>;
+};
+
+&cm_clockdomains {
+ dpll4_clkdm: dpll4_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&dpll4_ck>;
+ };
+
+ per_clkdm: per_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&uart3_fck>, <&gpio6_dbck>, <&gpio5_dbck>,
+ <&gpio4_dbck>, <&gpio3_dbck>, <&gpio2_dbck>,
+ <&wdt3_fck>, <&gpio6_ick>, <&gpio5_ick>, <&gpio4_ick>,
+ <&gpio3_ick>, <&gpio2_ick>, <&wdt3_ick>, <&uart3_ick>,
+ <&uart4_ick>, <&gpt9_ick>, <&gpt8_ick>, <&gpt7_ick>,
+ <&gpt6_ick>, <&gpt5_ick>, <&gpt4_ick>, <&gpt3_ick>,
+ <&gpt2_ick>, <&mcbsp2_ick>, <&mcbsp3_ick>,
+ <&mcbsp4_ick>, <&uart4_fck>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap36xx-omap3430es2plus-clocks.dtsi b/arch/arm/boot/dts/omap36xx-omap3430es2plus-clocks.dtsi
new file mode 100644
index 000000000..877318c28
--- /dev/null
+++ b/arch/arm/boot/dts/omap36xx-omap3430es2plus-clocks.dtsi
@@ -0,0 +1,198 @@
+/*
+ * Device Tree Source for OMAP34xx/OMAP36xx clock data
+ *
+ * Copyright (C) 2013 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.
+ */
+&cm_clocks {
+ ssi_ssr_gate_fck_3430es2: ssi_ssr_gate_fck_3430es2 {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&corex2_fck>;
+ ti,bit-shift = <0>;
+ reg = <0x0a00>;
+ };
+
+ ssi_ssr_div_fck_3430es2: ssi_ssr_div_fck_3430es2 {
+ #clock-cells = <0>;
+ compatible = "ti,composite-divider-clock";
+ clocks = <&corex2_fck>;
+ ti,bit-shift = <8>;
+ reg = <0x0a40>;
+ ti,dividers = <0>, <1>, <2>, <3>, <4>, <0>, <6>, <0>, <8>;
+ };
+
+ ssi_ssr_fck: ssi_ssr_fck_3430es2 {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&ssi_ssr_gate_fck_3430es2>, <&ssi_ssr_div_fck_3430es2>;
+ };
+
+ ssi_sst_fck: ssi_sst_fck_3430es2 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&ssi_ssr_fck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ hsotgusb_ick_3430es2: hsotgusb_ick_3430es2 {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-hsotgusb-interface-clock";
+ clocks = <&core_l3_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <4>;
+ };
+
+ ssi_l4_ick: ssi_l4_ick {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&l4_ick>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ ssi_ick: ssi_ick_3430es2 {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-ssi-interface-clock";
+ clocks = <&ssi_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <0>;
+ };
+
+ usim_gate_fck: usim_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&omap_96m_fck>;
+ ti,bit-shift = <9>;
+ reg = <0x0c00>;
+ };
+
+ sys_d2_ck: sys_d2_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ omap_96m_d2_fck: omap_96m_d2_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&omap_96m_fck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ omap_96m_d4_fck: omap_96m_d4_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&omap_96m_fck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ omap_96m_d8_fck: omap_96m_d8_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&omap_96m_fck>;
+ clock-mult = <1>;
+ clock-div = <8>;
+ };
+
+ omap_96m_d10_fck: omap_96m_d10_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&omap_96m_fck>;
+ clock-mult = <1>;
+ clock-div = <10>;
+ };
+
+ dpll5_m2_d4_ck: dpll5_m2_d4_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll5_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ dpll5_m2_d8_ck: dpll5_m2_d8_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll5_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <8>;
+ };
+
+ dpll5_m2_d16_ck: dpll5_m2_d16_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll5_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <16>;
+ };
+
+ dpll5_m2_d20_ck: dpll5_m2_d20_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll5_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <20>;
+ };
+
+ usim_mux_fck: usim_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&sys_ck>, <&sys_d2_ck>, <&omap_96m_d2_fck>, <&omap_96m_d4_fck>, <&omap_96m_d8_fck>, <&omap_96m_d10_fck>, <&dpll5_m2_d4_ck>, <&dpll5_m2_d8_ck>, <&dpll5_m2_d16_ck>, <&dpll5_m2_d20_ck>;
+ ti,bit-shift = <3>;
+ reg = <0x0c40>;
+ ti,index-starts-at-one;
+ };
+
+ usim_fck: usim_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&usim_gate_fck>, <&usim_mux_fck>;
+ };
+
+ usim_ick: usim_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&wkup_l4_ick>;
+ reg = <0x0c10>;
+ ti,bit-shift = <9>;
+ };
+};
+
+&cm_clockdomains {
+ core_l3_clkdm: core_l3_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&sdrc_ick>, <&hsotgusb_ick_3430es2>;
+ };
+
+ wkup_clkdm: wkup_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&gpio1_dbck>, <&wdt2_fck>, <&wdt2_ick>, <&wdt1_ick>,
+ <&gpio1_ick>, <&omap_32ksync_ick>, <&gpt12_ick>,
+ <&gpt1_ick>, <&usim_ick>;
+ };
+
+ core_l4_clkdm: core_l4_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&cpefuse_fck>, <&ts_fck>, <&usbtll_fck>,
+ <&usbtll_ick>, <&mmchs3_ick>, <&mmchs3_fck>,
+ <&mmchs2_fck>, <&mmchs1_fck>, <&i2c3_fck>, <&i2c2_fck>,
+ <&i2c1_fck>, <&mcspi4_fck>, <&mcspi3_fck>,
+ <&mcspi2_fck>, <&mcspi1_fck>, <&uart2_fck>,
+ <&uart1_fck>, <&hdq_fck>, <&mmchs2_ick>, <&mmchs1_ick>,
+ <&hdq_ick>, <&mcspi4_ick>, <&mcspi3_ick>,
+ <&mcspi2_ick>, <&mcspi1_ick>, <&i2c3_ick>, <&i2c2_ick>,
+ <&i2c1_ick>, <&uart2_ick>, <&uart1_ick>, <&gpt11_ick>,
+ <&gpt10_ick>, <&mcbsp5_ick>, <&mcbsp1_ick>,
+ <&omapctrl_ick>, <&aes2_ick>, <&sha12_ick>,
+ <&ssi_ick>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap36xx.dtsi b/arch/arm/boot/dts/omap36xx.dtsi
new file mode 100644
index 000000000..86253de5a
--- /dev/null
+++ b/arch/arm/boot/dts/omap36xx.dtsi
@@ -0,0 +1,112 @@
+/*
+ * Device Tree Source for OMAP3 SoC
+ *
+ * Copyright (C) 2012 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 <dt-bindings/media/omap3-isp.h>
+
+#include "omap3.dtsi"
+
+/ {
+ aliases {
+ serial3 = &uart4;
+ };
+
+ cpus {
+ /* OMAP3630/OMAP37xx 'standard device' variants OPP50 to OPP130 */
+ cpu@0 {
+ operating-points = <
+ /* kHz uV */
+ 300000 1012500
+ 600000 1200000
+ 800000 1325000
+ >;
+ clock-latency = <300000>; /* From legacy driver */
+ };
+ };
+
+ ocp {
+ uart4: serial@49042000 {
+ compatible = "ti,omap3-uart";
+ reg = <0x49042000 0x400>;
+ interrupts = <80>;
+ dmas = <&sdma 81 &sdma 82>;
+ dma-names = "tx", "rx";
+ ti,hwmods = "uart4";
+ clock-frequency = <48000000>;
+ };
+
+ abb_mpu_iva: regulator-abb-mpu {
+ compatible = "ti,abb-v1";
+ regulator-name = "abb_mpu_iva";
+ #address-cell = <0>;
+ #size-cells = <0>;
+ reg = <0x483072f0 0x8>, <0x48306818 0x4>;
+ reg-names = "base-address", "int-address";
+ ti,tranxdone-status-mask = <0x4000000>;
+ clocks = <&sys_ck>;
+ ti,settling-time = <30>;
+ ti,clock-cycles = <8>;
+ ti,abb_info = <
+ /*uV ABB efuse rbb_m fbb_m vset_m*/
+ 1012500 0 0 0 0 0
+ 1200000 0 0 0 0 0
+ 1325000 0 0 0 0 0
+ 1375000 1 0 0 0 0
+ >;
+ };
+
+ omap3_pmx_core2: pinmux@480025a0 {
+ compatible = "ti,omap3-padconf", "pinctrl-single";
+ reg = <0x480025a0 0x5c>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ pinctrl-single,register-width = <16>;
+ pinctrl-single,function-mask = <0xff1f>;
+ };
+
+ isp: isp@480bc000 {
+ compatible = "ti,omap3-isp";
+ reg = <0x480bc000 0x12fc
+ 0x480bd800 0x0600>;
+ interrupts = <24>;
+ iommus = <&mmu_isp>;
+ syscon = <&scm_conf 0x2f0>;
+ ti,phy-type = <OMAP3ISP_PHY_TYPE_CSIPHY>;
+ #clock-cells = <1>;
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+};
+
+/* OMAP3630 needs dss_96m_fck for VENC */
+&venc {
+ clocks = <&dss_tv_fck>, <&dss_96m_fck>;
+ clock-names = "fck", "tv_dac_clk";
+};
+
+&ssi {
+ status = "ok";
+
+ clocks = <&ssi_ssr_fck>,
+ <&ssi_sst_fck>,
+ <&ssi_ick>;
+ clock-names = "ssi_ssr_fck",
+ "ssi_sst_fck",
+ "ssi_ick";
+};
+
+/include/ "omap34xx-omap36xx-clocks.dtsi"
+/include/ "omap36xx-omap3430es2plus-clocks.dtsi"
+/include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi"
+/include/ "omap36xx-clocks.dtsi"
diff --git a/arch/arm/boot/dts/omap3xxx-clocks.dtsi b/arch/arm/boot/dts/omap3xxx-clocks.dtsi
new file mode 100644
index 000000000..bbba5bdc4
--- /dev/null
+++ b/arch/arm/boot/dts/omap3xxx-clocks.dtsi
@@ -0,0 +1,1665 @@
+/*
+ * Device Tree Source for OMAP3 clock data
+ *
+ * Copyright (C) 2013 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.
+ */
+&prm_clocks {
+ virt_16_8m_ck: virt_16_8m_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <16800000>;
+ };
+
+ osc_sys_ck: osc_sys_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&virt_12m_ck>, <&virt_13m_ck>, <&virt_19200000_ck>, <&virt_26000000_ck>, <&virt_38_4m_ck>, <&virt_16_8m_ck>;
+ reg = <0x0d40>;
+ };
+
+ sys_ck: sys_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&osc_sys_ck>;
+ ti,bit-shift = <6>;
+ ti,max-div = <3>;
+ reg = <0x1270>;
+ ti,index-starts-at-one;
+ };
+
+ sys_clkout1: sys_clkout1 {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&osc_sys_ck>;
+ reg = <0x0d70>;
+ ti,bit-shift = <7>;
+ };
+
+ dpll3_x2_ck: dpll3_x2_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll3_ck>;
+ clock-mult = <2>;
+ clock-div = <1>;
+ };
+
+ dpll3_m2x2_ck: dpll3_m2x2_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll3_m2_ck>;
+ clock-mult = <2>;
+ clock-div = <1>;
+ };
+
+ dpll4_x2_ck: dpll4_x2_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll4_ck>;
+ clock-mult = <2>;
+ clock-div = <1>;
+ };
+
+ corex2_fck: corex2_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll3_m2x2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ wkup_l4_ick: wkup_l4_ick {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+};
+
+&scm_clocks {
+ mcbsp5_mux_fck: mcbsp5_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&core_96m_fck>, <&mcbsp_clks>;
+ ti,bit-shift = <4>;
+ reg = <0x68>;
+ };
+
+ mcbsp5_fck: mcbsp5_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&mcbsp5_gate_fck>, <&mcbsp5_mux_fck>;
+ };
+
+ mcbsp1_mux_fck: mcbsp1_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&core_96m_fck>, <&mcbsp_clks>;
+ ti,bit-shift = <2>;
+ reg = <0x04>;
+ };
+
+ mcbsp1_fck: mcbsp1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&mcbsp1_gate_fck>, <&mcbsp1_mux_fck>;
+ };
+
+ mcbsp2_mux_fck: mcbsp2_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&per_96m_fck>, <&mcbsp_clks>;
+ ti,bit-shift = <6>;
+ reg = <0x04>;
+ };
+
+ mcbsp2_fck: mcbsp2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&mcbsp2_gate_fck>, <&mcbsp2_mux_fck>;
+ };
+
+ mcbsp3_mux_fck: mcbsp3_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&per_96m_fck>, <&mcbsp_clks>;
+ reg = <0x68>;
+ };
+
+ mcbsp3_fck: mcbsp3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&mcbsp3_gate_fck>, <&mcbsp3_mux_fck>;
+ };
+
+ mcbsp4_mux_fck: mcbsp4_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&per_96m_fck>, <&mcbsp_clks>;
+ ti,bit-shift = <2>;
+ reg = <0x68>;
+ };
+
+ mcbsp4_fck: mcbsp4_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&mcbsp4_gate_fck>, <&mcbsp4_mux_fck>;
+ };
+};
+&cm_clocks {
+ dummy_apb_pclk: dummy_apb_pclk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0x0>;
+ };
+
+ omap_32k_fck: omap_32k_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ virt_12m_ck: virt_12m_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ virt_13m_ck: virt_13m_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ };
+
+ virt_19200000_ck: virt_19200000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <19200000>;
+ };
+
+ virt_26000000_ck: virt_26000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ };
+
+ virt_38_4m_ck: virt_38_4m_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <38400000>;
+ };
+
+ dpll4_ck: dpll4_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-dpll-per-clock";
+ clocks = <&sys_ck>, <&sys_ck>;
+ reg = <0x0d00>, <0x0d20>, <0x0d44>, <0x0d30>;
+ };
+
+ dpll4_m2_ck: dpll4_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll4_ck>;
+ ti,max-div = <63>;
+ reg = <0x0d48>;
+ ti,index-starts-at-one;
+ };
+
+ dpll4_m2x2_mul_ck: dpll4_m2x2_mul_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll4_m2_ck>;
+ clock-mult = <2>;
+ clock-div = <1>;
+ };
+
+ dpll4_m2x2_ck: dpll4_m2x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll4_m2x2_mul_ck>;
+ ti,bit-shift = <0x1b>;
+ reg = <0x0d00>;
+ ti,set-bit-to-disable;
+ };
+
+ omap_96m_alwon_fck: omap_96m_alwon_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll4_m2x2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll3_ck: dpll3_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-dpll-core-clock";
+ clocks = <&sys_ck>, <&sys_ck>;
+ reg = <0x0d00>, <0x0d20>, <0x0d40>, <0x0d30>;
+ };
+
+ dpll3_m3_ck: dpll3_m3_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll3_ck>;
+ ti,bit-shift = <16>;
+ ti,max-div = <31>;
+ reg = <0x1140>;
+ ti,index-starts-at-one;
+ };
+
+ dpll3_m3x2_mul_ck: dpll3_m3x2_mul_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll3_m3_ck>;
+ clock-mult = <2>;
+ clock-div = <1>;
+ };
+
+ dpll3_m3x2_ck: dpll3_m3x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll3_m3x2_mul_ck>;
+ ti,bit-shift = <0xc>;
+ reg = <0x0d00>;
+ ti,set-bit-to-disable;
+ };
+
+ emu_core_alwon_ck: emu_core_alwon_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll3_m3x2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ sys_altclk: sys_altclk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0x0>;
+ };
+
+ mcbsp_clks: mcbsp_clks {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0x0>;
+ };
+
+ dpll3_m2_ck: dpll3_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll3_ck>;
+ ti,bit-shift = <27>;
+ ti,max-div = <31>;
+ reg = <0x0d40>;
+ ti,index-starts-at-one;
+ };
+
+ core_ck: core_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll3_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll1_fck: dpll1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&core_ck>;
+ ti,bit-shift = <19>;
+ ti,max-div = <7>;
+ reg = <0x0940>;
+ ti,index-starts-at-one;
+ };
+
+ dpll1_ck: dpll1_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-dpll-clock";
+ clocks = <&sys_ck>, <&dpll1_fck>;
+ reg = <0x0904>, <0x0924>, <0x0940>, <0x0934>;
+ };
+
+ dpll1_x2_ck: dpll1_x2_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll1_ck>;
+ clock-mult = <2>;
+ clock-div = <1>;
+ };
+
+ dpll1_x2m2_ck: dpll1_x2m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll1_x2_ck>;
+ ti,max-div = <31>;
+ reg = <0x0944>;
+ ti,index-starts-at-one;
+ };
+
+ cm_96m_fck: cm_96m_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&omap_96m_alwon_fck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ omap_96m_fck: omap_96m_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&cm_96m_fck>, <&sys_ck>;
+ ti,bit-shift = <6>;
+ reg = <0x0d40>;
+ };
+
+ dpll4_m3_ck: dpll4_m3_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll4_ck>;
+ ti,bit-shift = <8>;
+ ti,max-div = <32>;
+ reg = <0x0e40>;
+ ti,index-starts-at-one;
+ };
+
+ dpll4_m3x2_mul_ck: dpll4_m3x2_mul_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll4_m3_ck>;
+ clock-mult = <2>;
+ clock-div = <1>;
+ };
+
+ dpll4_m3x2_ck: dpll4_m3x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll4_m3x2_mul_ck>;
+ ti,bit-shift = <0x1c>;
+ reg = <0x0d00>;
+ ti,set-bit-to-disable;
+ };
+
+ omap_54m_fck: omap_54m_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dpll4_m3x2_ck>, <&sys_altclk>;
+ ti,bit-shift = <5>;
+ reg = <0x0d40>;
+ };
+
+ cm_96m_d2_fck: cm_96m_d2_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&cm_96m_fck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ omap_48m_fck: omap_48m_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&cm_96m_d2_fck>, <&sys_altclk>;
+ ti,bit-shift = <3>;
+ reg = <0x0d40>;
+ };
+
+ omap_12m_fck: omap_12m_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&omap_48m_fck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ dpll4_m4_ck: dpll4_m4_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll4_ck>;
+ ti,max-div = <32>;
+ reg = <0x0e40>;
+ ti,index-starts-at-one;
+ };
+
+ dpll4_m4x2_mul_ck: dpll4_m4x2_mul_ck {
+ #clock-cells = <0>;
+ compatible = "ti,fixed-factor-clock";
+ clocks = <&dpll4_m4_ck>;
+ ti,clock-mult = <2>;
+ ti,clock-div = <1>;
+ ti,set-rate-parent;
+ };
+
+ dpll4_m4x2_ck: dpll4_m4x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll4_m4x2_mul_ck>;
+ ti,bit-shift = <0x1d>;
+ reg = <0x0d00>;
+ ti,set-bit-to-disable;
+ ti,set-rate-parent;
+ };
+
+ dpll4_m5_ck: dpll4_m5_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll4_ck>;
+ ti,max-div = <63>;
+ reg = <0x0f40>;
+ ti,index-starts-at-one;
+ };
+
+ dpll4_m5x2_mul_ck: dpll4_m5x2_mul_ck {
+ #clock-cells = <0>;
+ compatible = "ti,fixed-factor-clock";
+ clocks = <&dpll4_m5_ck>;
+ ti,clock-mult = <2>;
+ ti,clock-div = <1>;
+ ti,set-rate-parent;
+ };
+
+ dpll4_m5x2_ck: dpll4_m5x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll4_m5x2_mul_ck>;
+ ti,bit-shift = <0x1e>;
+ reg = <0x0d00>;
+ ti,set-bit-to-disable;
+ ti,set-rate-parent;
+ };
+
+ dpll4_m6_ck: dpll4_m6_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll4_ck>;
+ ti,bit-shift = <24>;
+ ti,max-div = <63>;
+ reg = <0x1140>;
+ ti,index-starts-at-one;
+ };
+
+ dpll4_m6x2_mul_ck: dpll4_m6x2_mul_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll4_m6_ck>;
+ clock-mult = <2>;
+ clock-div = <1>;
+ };
+
+ dpll4_m6x2_ck: dpll4_m6x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll4_m6x2_mul_ck>;
+ ti,bit-shift = <0x1f>;
+ reg = <0x0d00>;
+ ti,set-bit-to-disable;
+ };
+
+ emu_per_alwon_ck: emu_per_alwon_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll4_m6x2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ clkout2_src_gate_ck: clkout2_src_gate_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&core_ck>;
+ ti,bit-shift = <7>;
+ reg = <0x0d70>;
+ };
+
+ clkout2_src_mux_ck: clkout2_src_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&core_ck>, <&sys_ck>, <&cm_96m_fck>, <&omap_54m_fck>;
+ reg = <0x0d70>;
+ };
+
+ clkout2_src_ck: clkout2_src_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&clkout2_src_gate_ck>, <&clkout2_src_mux_ck>;
+ };
+
+ sys_clkout2: sys_clkout2 {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&clkout2_src_ck>;
+ ti,bit-shift = <3>;
+ ti,max-div = <64>;
+ reg = <0x0d70>;
+ ti,index-power-of-two;
+ };
+
+ mpu_ck: mpu_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll1_x2m2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ arm_fck: arm_fck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&mpu_ck>;
+ reg = <0x0924>;
+ ti,max-div = <2>;
+ };
+
+ emu_mpu_alwon_ck: emu_mpu_alwon_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&mpu_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ l3_ick: l3_ick {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&core_ck>;
+ ti,max-div = <3>;
+ reg = <0x0a40>;
+ ti,index-starts-at-one;
+ };
+
+ l4_ick: l4_ick {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&l3_ick>;
+ ti,bit-shift = <2>;
+ ti,max-div = <3>;
+ reg = <0x0a40>;
+ ti,index-starts-at-one;
+ };
+
+ rm_ick: rm_ick {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&l4_ick>;
+ ti,bit-shift = <1>;
+ ti,max-div = <3>;
+ reg = <0x0c40>;
+ ti,index-starts-at-one;
+ };
+
+ gpt10_gate_fck: gpt10_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <11>;
+ reg = <0x0a00>;
+ };
+
+ gpt10_mux_fck: gpt10_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&omap_32k_fck>, <&sys_ck>;
+ ti,bit-shift = <6>;
+ reg = <0x0a40>;
+ };
+
+ gpt10_fck: gpt10_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt10_gate_fck>, <&gpt10_mux_fck>;
+ };
+
+ gpt11_gate_fck: gpt11_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <12>;
+ reg = <0x0a00>;
+ };
+
+ gpt11_mux_fck: gpt11_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&omap_32k_fck>, <&sys_ck>;
+ ti,bit-shift = <7>;
+ reg = <0x0a40>;
+ };
+
+ gpt11_fck: gpt11_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt11_gate_fck>, <&gpt11_mux_fck>;
+ };
+
+ core_96m_fck: core_96m_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&omap_96m_fck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ mmchs2_fck: mmchs2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_96m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <25>;
+ };
+
+ mmchs1_fck: mmchs1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_96m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <24>;
+ };
+
+ i2c3_fck: i2c3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_96m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <17>;
+ };
+
+ i2c2_fck: i2c2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_96m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <16>;
+ };
+
+ i2c1_fck: i2c1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_96m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <15>;
+ };
+
+ mcbsp5_gate_fck: mcbsp5_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&mcbsp_clks>;
+ ti,bit-shift = <10>;
+ reg = <0x0a00>;
+ };
+
+ mcbsp1_gate_fck: mcbsp1_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&mcbsp_clks>;
+ ti,bit-shift = <9>;
+ reg = <0x0a00>;
+ };
+
+ core_48m_fck: core_48m_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&omap_48m_fck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ mcspi4_fck: mcspi4_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_48m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <21>;
+ };
+
+ mcspi3_fck: mcspi3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_48m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <20>;
+ };
+
+ mcspi2_fck: mcspi2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_48m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <19>;
+ };
+
+ mcspi1_fck: mcspi1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_48m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <18>;
+ };
+
+ uart2_fck: uart2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_48m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <14>;
+ };
+
+ uart1_fck: uart1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_48m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <13>;
+ };
+
+ core_12m_fck: core_12m_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&omap_12m_fck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ hdq_fck: hdq_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_12m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <22>;
+ };
+
+ core_l3_ick: core_l3_ick {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&l3_ick>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ sdrc_ick: sdrc_ick {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_l3_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <1>;
+ };
+
+ gpmc_fck: gpmc_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&core_l3_ick>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ core_l4_ick: core_l4_ick {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&l4_ick>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ mmchs2_ick: mmchs2_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <25>;
+ };
+
+ mmchs1_ick: mmchs1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <24>;
+ };
+
+ hdq_ick: hdq_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <22>;
+ };
+
+ mcspi4_ick: mcspi4_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <21>;
+ };
+
+ mcspi3_ick: mcspi3_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <20>;
+ };
+
+ mcspi2_ick: mcspi2_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <19>;
+ };
+
+ mcspi1_ick: mcspi1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <18>;
+ };
+
+ i2c3_ick: i2c3_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <17>;
+ };
+
+ i2c2_ick: i2c2_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <16>;
+ };
+
+ i2c1_ick: i2c1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <15>;
+ };
+
+ uart2_ick: uart2_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <14>;
+ };
+
+ uart1_ick: uart1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <13>;
+ };
+
+ gpt11_ick: gpt11_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <12>;
+ };
+
+ gpt10_ick: gpt10_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <11>;
+ };
+
+ mcbsp5_ick: mcbsp5_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <10>;
+ };
+
+ mcbsp1_ick: mcbsp1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <9>;
+ };
+
+ omapctrl_ick: omapctrl_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <6>;
+ };
+
+ dss_tv_fck: dss_tv_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&omap_54m_fck>;
+ reg = <0x0e00>;
+ ti,bit-shift = <2>;
+ };
+
+ dss_96m_fck: dss_96m_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&omap_96m_fck>;
+ reg = <0x0e00>;
+ ti,bit-shift = <2>;
+ };
+
+ dss2_alwon_fck: dss2_alwon_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_ck>;
+ reg = <0x0e00>;
+ ti,bit-shift = <1>;
+ };
+
+ dummy_ck: dummy_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ gpt1_gate_fck: gpt1_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x0c00>;
+ };
+
+ gpt1_mux_fck: gpt1_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&omap_32k_fck>, <&sys_ck>;
+ reg = <0x0c40>;
+ };
+
+ gpt1_fck: gpt1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt1_gate_fck>, <&gpt1_mux_fck>;
+ };
+
+ aes2_ick: aes2_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ ti,bit-shift = <28>;
+ reg = <0x0a10>;
+ };
+
+ wkup_32k_fck: wkup_32k_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&omap_32k_fck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ gpio1_dbck: gpio1_dbck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&wkup_32k_fck>;
+ reg = <0x0c00>;
+ ti,bit-shift = <3>;
+ };
+
+ sha12_ick: sha12_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <27>;
+ };
+
+ wdt2_fck: wdt2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&wkup_32k_fck>;
+ reg = <0x0c00>;
+ ti,bit-shift = <5>;
+ };
+
+ wdt2_ick: wdt2_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&wkup_l4_ick>;
+ reg = <0x0c10>;
+ ti,bit-shift = <5>;
+ };
+
+ wdt1_ick: wdt1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&wkup_l4_ick>;
+ reg = <0x0c10>;
+ ti,bit-shift = <4>;
+ };
+
+ gpio1_ick: gpio1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&wkup_l4_ick>;
+ reg = <0x0c10>;
+ ti,bit-shift = <3>;
+ };
+
+ omap_32ksync_ick: omap_32ksync_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&wkup_l4_ick>;
+ reg = <0x0c10>;
+ ti,bit-shift = <2>;
+ };
+
+ gpt12_ick: gpt12_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&wkup_l4_ick>;
+ reg = <0x0c10>;
+ ti,bit-shift = <1>;
+ };
+
+ gpt1_ick: gpt1_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&wkup_l4_ick>;
+ reg = <0x0c10>;
+ ti,bit-shift = <0>;
+ };
+
+ per_96m_fck: per_96m_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&omap_96m_alwon_fck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ per_48m_fck: per_48m_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&omap_48m_fck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ uart3_fck: uart3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&per_48m_fck>;
+ reg = <0x1000>;
+ ti,bit-shift = <11>;
+ };
+
+ gpt2_gate_fck: gpt2_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <3>;
+ reg = <0x1000>;
+ };
+
+ gpt2_mux_fck: gpt2_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&omap_32k_fck>, <&sys_ck>;
+ reg = <0x1040>;
+ };
+
+ gpt2_fck: gpt2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt2_gate_fck>, <&gpt2_mux_fck>;
+ };
+
+ gpt3_gate_fck: gpt3_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <4>;
+ reg = <0x1000>;
+ };
+
+ gpt3_mux_fck: gpt3_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&omap_32k_fck>, <&sys_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x1040>;
+ };
+
+ gpt3_fck: gpt3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt3_gate_fck>, <&gpt3_mux_fck>;
+ };
+
+ gpt4_gate_fck: gpt4_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <5>;
+ reg = <0x1000>;
+ };
+
+ gpt4_mux_fck: gpt4_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&omap_32k_fck>, <&sys_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x1040>;
+ };
+
+ gpt4_fck: gpt4_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt4_gate_fck>, <&gpt4_mux_fck>;
+ };
+
+ gpt5_gate_fck: gpt5_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <6>;
+ reg = <0x1000>;
+ };
+
+ gpt5_mux_fck: gpt5_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&omap_32k_fck>, <&sys_ck>;
+ ti,bit-shift = <3>;
+ reg = <0x1040>;
+ };
+
+ gpt5_fck: gpt5_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt5_gate_fck>, <&gpt5_mux_fck>;
+ };
+
+ gpt6_gate_fck: gpt6_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <7>;
+ reg = <0x1000>;
+ };
+
+ gpt6_mux_fck: gpt6_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&omap_32k_fck>, <&sys_ck>;
+ ti,bit-shift = <4>;
+ reg = <0x1040>;
+ };
+
+ gpt6_fck: gpt6_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt6_gate_fck>, <&gpt6_mux_fck>;
+ };
+
+ gpt7_gate_fck: gpt7_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1000>;
+ };
+
+ gpt7_mux_fck: gpt7_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&omap_32k_fck>, <&sys_ck>;
+ ti,bit-shift = <5>;
+ reg = <0x1040>;
+ };
+
+ gpt7_fck: gpt7_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt7_gate_fck>, <&gpt7_mux_fck>;
+ };
+
+ gpt8_gate_fck: gpt8_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <9>;
+ reg = <0x1000>;
+ };
+
+ gpt8_mux_fck: gpt8_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&omap_32k_fck>, <&sys_ck>;
+ ti,bit-shift = <6>;
+ reg = <0x1040>;
+ };
+
+ gpt8_fck: gpt8_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt8_gate_fck>, <&gpt8_mux_fck>;
+ };
+
+ gpt9_gate_fck: gpt9_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&sys_ck>;
+ ti,bit-shift = <10>;
+ reg = <0x1000>;
+ };
+
+ gpt9_mux_fck: gpt9_mux_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&omap_32k_fck>, <&sys_ck>;
+ ti,bit-shift = <7>;
+ reg = <0x1040>;
+ };
+
+ gpt9_fck: gpt9_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&gpt9_gate_fck>, <&gpt9_mux_fck>;
+ };
+
+ per_32k_alwon_fck: per_32k_alwon_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&omap_32k_fck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ gpio6_dbck: gpio6_dbck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&per_32k_alwon_fck>;
+ reg = <0x1000>;
+ ti,bit-shift = <17>;
+ };
+
+ gpio5_dbck: gpio5_dbck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&per_32k_alwon_fck>;
+ reg = <0x1000>;
+ ti,bit-shift = <16>;
+ };
+
+ gpio4_dbck: gpio4_dbck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&per_32k_alwon_fck>;
+ reg = <0x1000>;
+ ti,bit-shift = <15>;
+ };
+
+ gpio3_dbck: gpio3_dbck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&per_32k_alwon_fck>;
+ reg = <0x1000>;
+ ti,bit-shift = <14>;
+ };
+
+ gpio2_dbck: gpio2_dbck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&per_32k_alwon_fck>;
+ reg = <0x1000>;
+ ti,bit-shift = <13>;
+ };
+
+ wdt3_fck: wdt3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&per_32k_alwon_fck>;
+ reg = <0x1000>;
+ ti,bit-shift = <12>;
+ };
+
+ per_l4_ick: per_l4_ick {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&l4_ick>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ gpio6_ick: gpio6_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <17>;
+ };
+
+ gpio5_ick: gpio5_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <16>;
+ };
+
+ gpio4_ick: gpio4_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <15>;
+ };
+
+ gpio3_ick: gpio3_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <14>;
+ };
+
+ gpio2_ick: gpio2_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <13>;
+ };
+
+ wdt3_ick: wdt3_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <12>;
+ };
+
+ uart3_ick: uart3_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <11>;
+ };
+
+ uart4_ick: uart4_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <18>;
+ };
+
+ gpt9_ick: gpt9_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <10>;
+ };
+
+ gpt8_ick: gpt8_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <9>;
+ };
+
+ gpt7_ick: gpt7_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <8>;
+ };
+
+ gpt6_ick: gpt6_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <7>;
+ };
+
+ gpt5_ick: gpt5_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <6>;
+ };
+
+ gpt4_ick: gpt4_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <5>;
+ };
+
+ gpt3_ick: gpt3_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <4>;
+ };
+
+ gpt2_ick: gpt2_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <3>;
+ };
+
+ mcbsp2_ick: mcbsp2_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <0>;
+ };
+
+ mcbsp3_ick: mcbsp3_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <1>;
+ };
+
+ mcbsp4_ick: mcbsp4_ick {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&per_l4_ick>;
+ reg = <0x1010>;
+ ti,bit-shift = <2>;
+ };
+
+ mcbsp2_gate_fck: mcbsp2_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&mcbsp_clks>;
+ ti,bit-shift = <0>;
+ reg = <0x1000>;
+ };
+
+ mcbsp3_gate_fck: mcbsp3_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&mcbsp_clks>;
+ ti,bit-shift = <1>;
+ reg = <0x1000>;
+ };
+
+ mcbsp4_gate_fck: mcbsp4_gate_fck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-gate-clock";
+ clocks = <&mcbsp_clks>;
+ ti,bit-shift = <2>;
+ reg = <0x1000>;
+ };
+
+ emu_src_mux_ck: emu_src_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_ck>, <&emu_core_alwon_ck>, <&emu_per_alwon_ck>, <&emu_mpu_alwon_ck>;
+ reg = <0x1140>;
+ };
+
+ emu_src_ck: emu_src_ck {
+ #clock-cells = <0>;
+ compatible = "ti,clkdm-gate-clock";
+ clocks = <&emu_src_mux_ck>;
+ };
+
+ pclk_fck: pclk_fck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&emu_src_ck>;
+ ti,bit-shift = <8>;
+ ti,max-div = <7>;
+ reg = <0x1140>;
+ ti,index-starts-at-one;
+ };
+
+ pclkx2_fck: pclkx2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&emu_src_ck>;
+ ti,bit-shift = <6>;
+ ti,max-div = <3>;
+ reg = <0x1140>;
+ ti,index-starts-at-one;
+ };
+
+ atclk_fck: atclk_fck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&emu_src_ck>;
+ ti,bit-shift = <4>;
+ ti,max-div = <3>;
+ reg = <0x1140>;
+ ti,index-starts-at-one;
+ };
+
+ traceclk_src_fck: traceclk_src_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_ck>, <&emu_core_alwon_ck>, <&emu_per_alwon_ck>, <&emu_mpu_alwon_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x1140>;
+ };
+
+ traceclk_fck: traceclk_fck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&traceclk_src_fck>;
+ ti,bit-shift = <11>;
+ ti,max-div = <7>;
+ reg = <0x1140>;
+ ti,index-starts-at-one;
+ };
+
+ secure_32k_fck: secure_32k_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ gpt12_fck: gpt12_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&secure_32k_fck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ wdt1_fck: wdt1_fck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&secure_32k_fck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+};
+
+&cm_clockdomains {
+ core_l3_clkdm: core_l3_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&sdrc_ick>;
+ };
+
+ dpll3_clkdm: dpll3_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&dpll3_ck>;
+ };
+
+ dpll1_clkdm: dpll1_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&dpll1_ck>;
+ };
+
+ per_clkdm: per_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&uart3_fck>, <&gpio6_dbck>, <&gpio5_dbck>,
+ <&gpio4_dbck>, <&gpio3_dbck>, <&gpio2_dbck>,
+ <&wdt3_fck>, <&gpio6_ick>, <&gpio5_ick>, <&gpio4_ick>,
+ <&gpio3_ick>, <&gpio2_ick>, <&wdt3_ick>, <&uart3_ick>,
+ <&uart4_ick>, <&gpt9_ick>, <&gpt8_ick>, <&gpt7_ick>,
+ <&gpt6_ick>, <&gpt5_ick>, <&gpt4_ick>, <&gpt3_ick>,
+ <&gpt2_ick>, <&mcbsp2_ick>, <&mcbsp3_ick>,
+ <&mcbsp4_ick>;
+ };
+
+ emu_clkdm: emu_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&emu_src_ck>;
+ };
+
+ dpll4_clkdm: dpll4_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&dpll4_ck>;
+ };
+
+ wkup_clkdm: wkup_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&gpio1_dbck>, <&wdt2_fck>, <&wdt2_ick>, <&wdt1_ick>,
+ <&gpio1_ick>, <&omap_32ksync_ick>, <&gpt12_ick>,
+ <&gpt1_ick>;
+ };
+
+ dss_clkdm: dss_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&dss_tv_fck>, <&dss_96m_fck>, <&dss2_alwon_fck>;
+ };
+
+ core_l4_clkdm: core_l4_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&mmchs2_fck>, <&mmchs1_fck>, <&i2c3_fck>, <&i2c2_fck>,
+ <&i2c1_fck>, <&mcspi4_fck>, <&mcspi3_fck>,
+ <&mcspi2_fck>, <&mcspi1_fck>, <&uart2_fck>,
+ <&uart1_fck>, <&hdq_fck>, <&mmchs2_ick>, <&mmchs1_ick>,
+ <&hdq_ick>, <&mcspi4_ick>, <&mcspi3_ick>,
+ <&mcspi2_ick>, <&mcspi1_ick>, <&i2c3_ick>, <&i2c2_ick>,
+ <&i2c1_ick>, <&uart2_ick>, <&uart1_ick>, <&gpt11_ick>,
+ <&gpt10_ick>, <&mcbsp5_ick>, <&mcbsp1_ick>,
+ <&omapctrl_ick>, <&aes2_ick>, <&sha12_ick>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap4-cpu-thermal.dtsi b/arch/arm/boot/dts/omap4-cpu-thermal.dtsi
new file mode 100644
index 000000000..ab7f87ae9
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-cpu-thermal.dtsi
@@ -0,0 +1,41 @@
+/*
+ * Device Tree Source for OMAP4/5 SoC CPU thermal
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ * Contact: Eduardo Valentin <eduardo.valentin@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 <dt-bindings/thermal/thermal.h>
+
+cpu_thermal: cpu_thermal {
+ polling-delay-passive = <250>; /* milliseconds */
+ polling-delay = <1000>; /* milliseconds */
+
+ /* sensor ID */
+ thermal-sensors = <&bandgap 0>;
+
+ cpu_trips: trips {
+ cpu_alert0: cpu_alert {
+ temperature = <100000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "passive";
+ };
+ cpu_crit: cpu_crit {
+ temperature = <125000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "critical";
+ };
+ };
+
+ cpu_cooling_maps: cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ cooling-device =
+ <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap4-duovero-parlor.dts b/arch/arm/boot/dts/omap4-duovero-parlor.dts
new file mode 100644
index 000000000..1a78f013f
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-duovero-parlor.dts
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "omap4-duovero.dtsi"
+
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "OMAP4430 Gumstix Duovero on Parlor";
+ compatible = "gumstix,omap4-duovero-parlor", "gumstix,omap4-duovero", "ti,omap4430", "ti,omap4";
+
+ aliases {
+ display0 = &hdmi0;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ led0 {
+ label = "duovero:blue:led0";
+ gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>; /* gpio_122 */
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ button0@121 {
+ label = "button0";
+ linux,code = <BTN_0>;
+ gpios = <&gpio4 25 GPIO_ACTIVE_LOW>; /* gpio_121 */
+ gpio-key,wakeup;
+ };
+ };
+
+ hdmi0: connector@0 {
+ compatible = "hdmi-connector";
+ label = "hdmi";
+
+ type = "d";
+
+ hpd-gpios = <&gpio2 31 GPIO_ACTIVE_HIGH>; /* gpio_63 */
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_out>;
+ };
+ };
+ };
+};
+
+&omap4_pmx_core {
+ pinctrl-0 = <
+ &led_pins
+ &button_pins
+ &smsc_pins
+ >;
+
+ led_pins: pinmux_led_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x116, PIN_OUTPUT | MUX_MODE3) /* abe_dmic_din3.gpio_122 */
+ >;
+ };
+
+ button_pins: pinmux_button_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x114, PIN_INPUT_PULLUP | MUX_MODE3) /* abe_dmic_din2.gpio_121 */
+ >;
+ };
+
+ i2c2_pins: pinmux_i2c2_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x126, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_scl */
+ OMAP4_IOPAD(0x128, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_sda */
+ >;
+ };
+
+ i2c3_pins: pinmux_i2c3_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x12a, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */
+ OMAP4_IOPAD(0x12c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */
+ >;
+ };
+
+ smsc_pins: pinmux_smsc_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x068, PIN_INPUT | MUX_MODE3) /* gpmc_a20.gpio_44: IRQ */
+ OMAP4_IOPAD(0x06a, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a21.gpio_45: nReset */
+ OMAP4_IOPAD(0x070, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a24.gpio_48: amdix enabled */
+ >;
+ };
+
+ dss_hdmi_pins: pinmux_dss_hdmi_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x098, PIN_INPUT | MUX_MODE3) /* hdmi_hpd.gpio_63 */
+ OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */
+ OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_ddc_scl.hdmi_ddc_scl */
+ OMAP4_IOPAD(0x09e, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_ddc_sda.hdmi_ddc_sda */
+ >;
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+
+ clock-frequency = <400000>;
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+
+ clock-frequency = <100000>;
+
+ /* optional 1K EEPROM with revision information */
+ eeprom@51 {
+ compatible = "atmel,24c01";
+ reg = <0x51>;
+ pagesize = <8>;
+ };
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+#include "omap-gpmc-smsc911x.dtsi"
+
+&gpmc {
+ ranges = <5 0 0x2c000000 0x1000000>; /* CS5 */
+
+ ethernet@gpmc {
+ reg = <5 0 0xff>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <12 IRQ_TYPE_LEVEL_LOW>; /* gpio_44 */
+
+ phy-mode = "mii";
+
+ gpmc,cs-on-ns = <10>;
+ gpmc,cs-rd-off-ns = <50>;
+ gpmc,cs-wr-off-ns = <50>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <10>;
+ gpmc,adv-wr-off-ns = <10>;
+ gpmc,oe-on-ns = <15>;
+ gpmc,oe-off-ns = <50>;
+ gpmc,we-on-ns = <15>;
+ gpmc,we-off-ns = <50>;
+ gpmc,rd-cycle-ns = <50>;
+ gpmc,wr-cycle-ns = <50>;
+ gpmc,access-ns = <50>;
+ gpmc,page-burst-access-ns = <0>;
+ gpmc,bus-turnaround-ns = <35>;
+ gpmc,cycle2cycle-delay-ns = <35>;
+ gpmc,wr-data-mux-bus-ns = <35>;
+ gpmc,wr-access-ns = <50>;
+
+ gpmc,mux-add-data = <2>;
+ gpmc,sync-read;
+ gpmc,sync-write;
+ gpmc,clk-activation-ns = <5>;
+ gpmc,sync-clk-ps = <20000>;
+ };
+};
+
+&dss {
+ status = "ok";
+};
+
+&hdmi {
+ status = "ok";
+ vdda-supply = <&vdac>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_hdmi_pins>;
+
+ port {
+ hdmi_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+};
+
diff --git a/arch/arm/boot/dts/omap4-duovero.dtsi b/arch/arm/boot/dts/omap4-duovero.dtsi
new file mode 100644
index 000000000..f2a94fa62
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-duovero.dtsi
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "omap443x.dtsi"
+
+/ {
+ model = "Gumstix Duovero";
+ compatible = "gumstix,omap4-duovero", "ti,omap4430", "ti,omap4";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>; /* 1 GB */
+ };
+
+ sound {
+ compatible = "ti,abe-twl6040";
+ ti,model = "DuoVero";
+
+ ti,mclk-freq = <38400000>;
+
+ ti,mcpdm = <&mcpdm>;
+
+ ti,twl6040 = <&twl6040>;
+
+ /* Audio routing */
+ ti,audio-routing =
+ "Headset Stereophone", "HSOL",
+ "Headset Stereophone", "HSOR",
+ "HSMIC", "Headset Mic",
+ "Headset Mic", "Headset Mic Bias";
+ };
+
+ /* HS USB Host PHY on PORT 1 */
+ hsusb1_phy: hsusb1_phy {
+ compatible = "usb-nop-xceiv";
+ reset-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>; /* gpio_62 */
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsusb1phy_pins>;
+
+ clocks = <&auxclk3_ck>;
+ clock-names = "main_clk";
+ clock-frequency = <19200000>;
+ };
+
+ /* regulator for w2cbw0015 on sdio5 */
+ w2cbw0015_vmmc: w2cbw0015_vmmc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&w2cbw0015_pins>;
+ compatible = "regulator-fixed";
+ regulator-name = "w2cbw0015";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio2 11 GPIO_ACTIVE_LOW>; /* gpio_43 */
+ startup-delay-us = <70000>;
+ enable-active-high;
+ regulator-boot-on;
+ };
+};
+
+&omap4_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &twl6040_pins
+ &hsusbb1_pins
+ >;
+
+ twl6040_pins: pinmux_twl6040_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x166, PIN_OUTPUT | MUX_MODE3) /* usbb2_ulpitll_nxt.gpio_160 */
+ OMAP4_IOPAD(0x1a0, PIN_INPUT | MUX_MODE0) /* sys_nirq2.sys_nirq2 */
+ >;
+ };
+
+ mcpdm_pins: pinmux_mcpdm_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x106, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_pdm_ul_data.abe_pdm_ul_data */
+ OMAP4_IOPAD(0x108, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_pdm_dl_data.abe_pdm_dl_data */
+ OMAP4_IOPAD(0x10a, PIN_INPUT_PULLUP | MUX_MODE0) /* abe_pdm_frame.abe_pdm_frame */
+ OMAP4_IOPAD(0x10c, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_pdm_lb_clk.abe_pdm_lb_clk */
+ OMAP4_IOPAD(0x10e, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_clks.abe_clks */
+ >;
+ };
+
+ mcbsp1_pins: pinmux_mcbsp1_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x0fe, PIN_INPUT | MUX_MODE0) /* abe_mcbsp1_clkx.abe_mcbsp1_clkx */
+ OMAP4_IOPAD(0x100, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp1_dr.abe_mcbsp1_dr */
+ OMAP4_IOPAD(0x102, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp1_dx.abe_mcbsp1_dx */
+ OMAP4_IOPAD(0x104, PIN_INPUT | MUX_MODE0) /* abe_mcbsp1_fsx.abe_mcbsp1_fsx */
+ >;
+ };
+
+ hsusbb1_pins: pinmux_hsusbb1_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x0c2, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_clk.usbb1_ulpiphy_clk */
+ OMAP4_IOPAD(0x0c4, PIN_OUTPUT | MUX_MODE4) /* usbb1_ulpitll_stp.usbb1_ulpiphy_stp */
+ OMAP4_IOPAD(0x0c6, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dir.usbb1_ulpiphy_dir */
+ OMAP4_IOPAD(0x0c8, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_nxt.usbb1_ulpiphy_nxt */
+ OMAP4_IOPAD(0x0ca, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat0.usbb1_ulpiphy_dat0 */
+ OMAP4_IOPAD(0x0cc, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat1.usbb1_ulpiphy_dat1 */
+ OMAP4_IOPAD(0x0ce, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat2.usbb1_ulpiphy_dat2 */
+ OMAP4_IOPAD(0x0d0, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat3.usbb1_ulpiphy_dat3 */
+ OMAP4_IOPAD(0x0d2, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat4.usbb1_ulpiphy_dat4 */
+ OMAP4_IOPAD(0x0d4, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat5.usbb1_ulpiphy_dat5 */
+ OMAP4_IOPAD(0x0d6, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat6.usbb1_ulpiphy_dat6 */
+ OMAP4_IOPAD(0x0d8, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat7.usbb1_ulpiphy_dat7 */
+ >;
+ };
+
+ hsusb1phy_pins: pinmux_hsusb1phy_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x08c, PIN_OUTPUT | MUX_MODE3) /* gpmc_wait1.gpio_62 */
+ >;
+ };
+
+ w2cbw0015_pins: pinmux_w2cbw0015_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x066, PIN_OUTPUT | MUX_MODE3) /* gpmc_a19.gpio_43 */
+ OMAP4_IOPAD(0x07a, PIN_INPUT | MUX_MODE3) /* gpmc_ncs3.gpio_53 */
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x122, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */
+ OMAP4_IOPAD(0x124, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */
+ >;
+ };
+
+ i2c4_pins: pinmux_i2c4_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x12e, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */
+ OMAP4_IOPAD(0x130, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x0e2, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk */
+ OMAP4_IOPAD(0x0e4, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmcc1_cmd */
+ OMAP4_IOPAD(0x0e6, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmcc1_dat0 */
+ OMAP4_IOPAD(0x0e8, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1 */
+ OMAP4_IOPAD(0x0ea, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2 */
+ OMAP4_IOPAD(0x0ec, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3 */
+ >;
+ };
+
+ mmc5_pins: pinmux_mmc5_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_clk */
+ OMAP4_IOPAD(0x14a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmcc5_cmd */
+ OMAP4_IOPAD(0x14c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmcc5_dat0 */
+ OMAP4_IOPAD(0x14e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat1 */
+ OMAP4_IOPAD(0x150, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat2 */
+ OMAP4_IOPAD(0x152, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat3 */
+ >;
+ };
+};
+
+/* PMIC */
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+
+ clock-frequency = <400000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */
+ };
+
+ twl6040: twl@4b {
+ compatible = "ti,twl6040";
+ reg = <0x4b>;
+ interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */
+ ti,audpwron-gpio = <&gpio6 0 GPIO_ACTIVE_HIGH>; /* gpio_160 */
+
+ vio-supply = <&v1v8>;
+ v2v1-supply = <&v2v1>;
+ enable-active-high;
+ };
+};
+
+#include "twl6030.dtsi"
+#include "twl6030_omap4.dtsi"
+
+/* on-board bluetooth / WiFi module */
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins>;
+
+ clock-frequency = <400000>;
+};
+
+&mcbsp1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcbsp1_pins>;
+ status = "okay";
+};
+
+&mcpdm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcpdm_pins>;
+ status = "okay";
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+
+ vmmc-supply = <&vmmc>;
+ ti,bus-width = <4>;
+ ti,non-removable; /* FIXME: use PMIC_MMC detect */
+};
+
+&mmc2 {
+ status = "disabled";
+};
+
+/* mmc3 is available to the expansion board */
+
+&mmc4 {
+ status = "disabled";
+};
+
+/* on-board WiFi module */
+&mmc5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc5_pins>;
+
+ vmmc-supply = <&w2cbw0015_vmmc>;
+ ti,bus-width = <4>;
+ ti,non-removable;
+ cap-power-off-card;
+};
+
+&twl_usb_comparator {
+ usb-supply = <&vusb>;
+};
+
+&usb_otg_hs {
+ interface-type = <1>;
+ mode = <3>;
+ power = <50>;
+};
+
+&usbhshost {
+ port1-mode = "ehci-phy";
+};
+
+&usbhsehci {
+ phys = <&hsusb1_phy>;
+};
+
diff --git a/arch/arm/boot/dts/omap4-panda-a4.dts b/arch/arm/boot/dts/omap4-panda-a4.dts
new file mode 100644
index 000000000..133f1b74e
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-panda-a4.dts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+/dts-v1/;
+
+#include "omap443x.dtsi"
+#include "omap4-panda-common.dtsi"
+
+/* Pandaboard Rev A4+ have external pullups on SCL & SDA */
+&dss_hdmi_pins {
+ pinctrl-single,pins = <
+ 0x5a (PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */
+ 0x5c (PIN_INPUT | MUX_MODE0) /* hdmi_scl.hdmi_scl */
+ 0x5e (PIN_INPUT | MUX_MODE0) /* hdmi_sda.hdmi_sda */
+ >;
+};
diff --git a/arch/arm/boot/dts/omap4-panda-common.dtsi b/arch/arm/boot/dts/omap4-panda-common.dtsi
new file mode 100644
index 000000000..f1507bc87
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-panda-common.dtsi
@@ -0,0 +1,543 @@
+/*
+ * Copyright (C) 2011-2013 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 "elpida_ecb240abacn.dtsi"
+
+/ {
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>; /* 1 GB */
+ };
+
+ aliases {
+ display0 = &dvi0;
+ display1 = &hdmi0;
+ };
+
+ leds: leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &led_wkgpio_pins
+ >;
+
+ heartbeat {
+ label = "pandaboard::status1";
+ gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ mmc {
+ label = "pandaboard::status2";
+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "mmc0";
+ };
+ };
+
+ sound: sound {
+ compatible = "ti,abe-twl6040";
+ ti,model = "PandaBoard";
+
+ ti,mclk-freq = <38400000>;
+
+ ti,mcpdm = <&mcpdm>;
+
+ ti,twl6040 = <&twl6040>;
+
+ /* Audio routing */
+ ti,audio-routing =
+ "Headset Stereophone", "HSOL",
+ "Headset Stereophone", "HSOR",
+ "Ext Spk", "HFL",
+ "Ext Spk", "HFR",
+ "Line Out", "AUXL",
+ "Line Out", "AUXR",
+ "HSMIC", "Headset Mic",
+ "Headset Mic", "Headset Mic Bias",
+ "AFML", "Line In",
+ "AFMR", "Line In";
+ };
+
+ /* HS USB Port 1 Power */
+ hsusb1_power: hsusb1_power_reg {
+ compatible = "regulator-fixed";
+ regulator-name = "hsusb1_vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 1 0>; /* gpio_1 */
+ startup-delay-us = <70000>;
+ enable-active-high;
+ /*
+ * boot-on is required along with always-on as the
+ * regulator framework doesn't enable the regulator
+ * if boot-on is not there.
+ */
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ /* HS USB Host PHY on PORT 1 */
+ hsusb1_phy: hsusb1_phy {
+ compatible = "usb-nop-xceiv";
+ reset-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>; /* gpio_62 */
+ vcc-supply = <&hsusb1_power>;
+ clocks = <&auxclk3_ck>;
+ clock-names = "main_clk";
+ clock-frequency = <19200000>;
+ };
+
+ /* regulator for wl12xx on sdio5 */
+ wl12xx_vmmc: wl12xx_vmmc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wl12xx_gpio>;
+ compatible = "regulator-fixed";
+ regulator-name = "vwl1271";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio2 11 0>;
+ startup-delay-us = <70000>;
+ enable-active-high;
+ };
+
+ tfp410: encoder@0 {
+ compatible = "ti,tfp410";
+ powerdown-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>; /* gpio_0 */
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ tfp410_in: endpoint@0 {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ tfp410_out: endpoint@0 {
+ remote-endpoint = <&dvi_connector_in>;
+ };
+ };
+ };
+ };
+
+ dvi0: connector@0 {
+ compatible = "dvi-connector";
+ label = "dvi";
+
+ digital;
+
+ ddc-i2c-bus = <&i2c3>;
+
+ port {
+ dvi_connector_in: endpoint {
+ remote-endpoint = <&tfp410_out>;
+ };
+ };
+ };
+
+ tpd12s015: encoder@1 {
+ compatible = "ti,tpd12s015";
+
+ gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>, /* 60, CT CP HPD */
+ <&gpio2 9 GPIO_ACTIVE_HIGH>, /* 41, LS OE */
+ <&gpio2 31 GPIO_ACTIVE_HIGH>; /* 63, HPD */
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ tpd12s015_in: endpoint@0 {
+ remote-endpoint = <&hdmi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ tpd12s015_out: endpoint@0 {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+ };
+ };
+
+ hdmi0: connector@1 {
+ compatible = "hdmi-connector";
+ label = "hdmi";
+
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&tpd12s015_out>;
+ };
+ };
+ };
+};
+
+&omap4_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &dss_dpi_pins
+ &tfp410_pins
+ &dss_hdmi_pins
+ &tpd12s015_pins
+ &hsusbb1_pins
+ >;
+
+ twl6040_pins: pinmux_twl6040_pins {
+ pinctrl-single,pins = <
+ 0xe0 (PIN_OUTPUT | MUX_MODE3) /* hdq_sio.gpio_127 */
+ 0x160 (PIN_INPUT | MUX_MODE0) /* sys_nirq2.sys_nirq2 */
+ >;
+ };
+
+ mcpdm_pins: pinmux_mcpdm_pins {
+ pinctrl-single,pins = <
+ 0xc6 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_pdm_ul_data.abe_pdm_ul_data */
+ 0xc8 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_pdm_dl_data.abe_pdm_dl_data */
+ 0xca (PIN_INPUT_PULLUP | MUX_MODE0) /* abe_pdm_frame.abe_pdm_frame */
+ 0xcc (PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_pdm_lb_clk.abe_pdm_lb_clk */
+ 0xce (PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_clks.abe_clks */
+ >;
+ };
+
+ mcbsp1_pins: pinmux_mcbsp1_pins {
+ pinctrl-single,pins = <
+ 0xbe (PIN_INPUT | MUX_MODE0) /* abe_mcbsp1_clkx.abe_mcbsp1_clkx */
+ 0xc0 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp1_dr.abe_mcbsp1_dr */
+ 0xc2 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp1_dx.abe_mcbsp1_dx */
+ 0xc4 (PIN_INPUT | MUX_MODE0) /* abe_mcbsp1_fsx.abe_mcbsp1_fsx */
+ >;
+ };
+
+ dss_dpi_pins: pinmux_dss_dpi_pins {
+ pinctrl-single,pins = <
+ 0x122 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data23 */
+ 0x124 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data22 */
+ 0x126 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data21 */
+ 0x128 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data20 */
+ 0x12a (PIN_OUTPUT | MUX_MODE5) /* dispc2_data19 */
+ 0x12c (PIN_OUTPUT | MUX_MODE5) /* dispc2_data18 */
+ 0x12e (PIN_OUTPUT | MUX_MODE5) /* dispc2_data15 */
+ 0x130 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data14 */
+ 0x132 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data13 */
+ 0x134 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data12 */
+ 0x136 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data11 */
+
+ 0x174 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data10 */
+ 0x176 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data9 */
+ 0x178 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data16 */
+ 0x17a (PIN_OUTPUT | MUX_MODE5) /* dispc2_data17 */
+ 0x17c (PIN_OUTPUT | MUX_MODE5) /* dispc2_hsync */
+ 0x17e (PIN_OUTPUT | MUX_MODE5) /* dispc2_pclk */
+ 0x180 (PIN_OUTPUT | MUX_MODE5) /* dispc2_vsync */
+ 0x182 (PIN_OUTPUT | MUX_MODE5) /* dispc2_de */
+ 0x184 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data8 */
+ 0x186 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data7 */
+ 0x188 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data6 */
+ 0x18a (PIN_OUTPUT | MUX_MODE5) /* dispc2_data5 */
+ 0x18c (PIN_OUTPUT | MUX_MODE5) /* dispc2_data4 */
+ 0x18e (PIN_OUTPUT | MUX_MODE5) /* dispc2_data3 */
+
+ 0x190 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data2 */
+ 0x192 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data1 */
+ 0x194 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data0 */
+ >;
+ };
+
+ tfp410_pins: pinmux_tfp410_pins {
+ pinctrl-single,pins = <
+ 0x144 (PIN_OUTPUT | MUX_MODE3) /* gpio_0 */
+ >;
+ };
+
+ dss_hdmi_pins: pinmux_dss_hdmi_pins {
+ pinctrl-single,pins = <
+ 0x5a (PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */
+ 0x5c (PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_scl.hdmi_scl */
+ 0x5e (PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_sda.hdmi_sda */
+ >;
+ };
+
+ tpd12s015_pins: pinmux_tpd12s015_pins {
+ pinctrl-single,pins = <
+ 0x22 (PIN_OUTPUT | MUX_MODE3) /* gpmc_a17.gpio_41 */
+ 0x48 (PIN_OUTPUT | MUX_MODE3) /* gpmc_nbe1.gpio_60 */
+ 0x58 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* hdmi_hpd.gpio_63 */
+ >;
+ };
+
+ hsusbb1_pins: pinmux_hsusbb1_pins {
+ pinctrl-single,pins = <
+ 0x82 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_clk.usbb1_ulpiphy_clk */
+ 0x84 (PIN_OUTPUT | MUX_MODE4) /* usbb1_ulpitll_stp.usbb1_ulpiphy_stp */
+ 0x86 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dir.usbb1_ulpiphy_dir */
+ 0x88 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_nxt.usbb1_ulpiphy_nxt */
+ 0x8a (PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat0.usbb1_ulpiphy_dat0 */
+ 0x8c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat1.usbb1_ulpiphy_dat1 */
+ 0x8e (PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat2.usbb1_ulpiphy_dat2 */
+ 0x90 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat3.usbb1_ulpiphy_dat3 */
+ 0x92 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat4.usbb1_ulpiphy_dat4 */
+ 0x94 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat5.usbb1_ulpiphy_dat5 */
+ 0x96 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat6.usbb1_ulpiphy_dat6 */
+ 0x98 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat7.usbb1_ulpiphy_dat7 */
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ 0xe2 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */
+ 0xe4 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */
+ >;
+ };
+
+ i2c2_pins: pinmux_i2c2_pins {
+ pinctrl-single,pins = <
+ 0xe6 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_scl */
+ 0xe8 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_sda */
+ >;
+ };
+
+ i2c3_pins: pinmux_i2c3_pins {
+ pinctrl-single,pins = <
+ 0xea (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */
+ 0xec (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */
+ >;
+ };
+
+ i2c4_pins: pinmux_i2c4_pins {
+ pinctrl-single,pins = <
+ 0xee (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */
+ 0xf0 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */
+ >;
+ };
+
+ /*
+ * wl12xx GPIO outputs for WLAN_EN, BT_EN, FM_EN, BT_WAKEUP
+ * REVISIT: Are the pull-ups needed for GPIO 48 and 49?
+ */
+ wl12xx_gpio: pinmux_wl12xx_gpio {
+ pinctrl-single,pins = <
+ 0x26 (PIN_OUTPUT | MUX_MODE3) /* gpmc_a19.gpio_43 */
+ 0x2c (PIN_OUTPUT | MUX_MODE3) /* gpmc_a22.gpio_46 */
+ 0x30 (PIN_OUTPUT_PULLUP | MUX_MODE3) /* gpmc_a24.gpio_48 */
+ 0x32 (PIN_OUTPUT_PULLUP | MUX_MODE3) /* gpmc_a25.gpio_49 */
+ >;
+ };
+
+ /* wl12xx GPIO inputs and SDIO pins */
+ wl12xx_pins: pinmux_wl12xx_pins {
+ pinctrl-single,pins = <
+ 0x38 (PIN_INPUT | MUX_MODE3) /* gpmc_ncs2.gpio_52 */
+ 0x3a (PIN_INPUT | MUX_MODE3) /* gpmc_ncs3.gpio_53 */
+ 0x108 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_clk.sdmmc5_clk */
+ 0x10a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_cmd.sdmmc5_cmd */
+ 0x10c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat0.sdmmc5_dat0 */
+ 0x10e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat1.sdmmc5_dat1 */
+ 0x110 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat2.sdmmc5_dat2 */
+ 0x112 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat3.sdmmc5_dat3 */
+ >;
+ };
+};
+
+&omap4_pmx_wkup {
+ led_wkgpio_pins: pinmux_leds_wkpins {
+ pinctrl-single,pins = <
+ 0x1a (PIN_OUTPUT | MUX_MODE3) /* gpio_wk7 */
+ 0x1c (PIN_OUTPUT | MUX_MODE3) /* gpio_wk8 */
+ >;
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+
+ clock-frequency = <400000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ /* IRQ# = 7 */
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */
+ };
+
+ twl6040: twl@4b {
+ compatible = "ti,twl6040";
+ reg = <0x4b>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&twl6040_pins>;
+
+ /* IRQ# = 119 */
+ interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */
+ ti,audpwron-gpio = <&gpio4 31 GPIO_ACTIVE_HIGH>; /* gpio line 127 */
+
+ vio-supply = <&v1v8>;
+ v2v1-supply = <&v2v1>;
+ enable-active-high;
+ };
+};
+
+#include "twl6030.dtsi"
+#include "twl6030_omap4.dtsi"
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+
+ clock-frequency = <400000>;
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+
+ clock-frequency = <100000>;
+
+ /*
+ * Display monitor features are burnt in their EEPROM as EDID data.
+ * The EEPROM is connected as I2C slave device.
+ */
+ eeprom@50 {
+ compatible = "ti,eeprom";
+ reg = <0x50>;
+ };
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins>;
+
+ clock-frequency = <400000>;
+};
+
+&mmc1 {
+ vmmc-supply = <&vmmc>;
+ bus-width = <8>;
+};
+
+&mmc2 {
+ status = "disabled";
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&mmc4 {
+ status = "disabled";
+};
+
+&mmc5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wl12xx_pins>;
+ vmmc-supply = <&wl12xx_vmmc>;
+ non-removable;
+ bus-width = <4>;
+ cap-power-off-card;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1271";
+ reg = <2>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <21 IRQ_TYPE_LEVEL_HIGH>; /* gpio 53 */
+ ref-clock-frequency = <38400000>;
+ };
+};
+
+&emif1 {
+ cs1-used;
+ device-handle = <&elpida_ECB240ABACN>;
+};
+
+&emif2 {
+ cs1-used;
+ device-handle = <&elpida_ECB240ABACN>;
+};
+
+&mcbsp1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcbsp1_pins>;
+ status = "okay";
+};
+
+&mcpdm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcpdm_pins>;
+ status = "okay";
+};
+
+&twl_usb_comparator {
+ usb-supply = <&vusb>;
+};
+
+&uart2 {
+ interrupts-extended = <&wakeupgen GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH
+ &omap4_pmx_core OMAP4_UART2_RX>;
+};
+
+&uart3 {
+ interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH
+ &omap4_pmx_core OMAP4_UART3_RX>;
+};
+
+&uart4 {
+ interrupts-extended = <&wakeupgen GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH
+ &omap4_pmx_core OMAP4_UART4_RX>;
+};
+
+&usb_otg_hs {
+ interface-type = <1>;
+ mode = <3>;
+ power = <50>;
+};
+
+&usbhshost {
+ port1-mode = "ehci-phy";
+};
+
+&usbhsehci {
+ phys = <&hsusb1_phy>;
+};
+
+&dss {
+ status = "ok";
+
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&tfp410_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+&dsi2 {
+ status = "ok";
+ vdd-supply = <&vcxio>;
+};
+
+&hdmi {
+ status = "ok";
+ vdda-supply = <&vdac>;
+
+ port {
+ hdmi_out: endpoint {
+ remote-endpoint = <&tpd12s015_in>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap4-panda-es.dts b/arch/arm/boot/dts/omap4-panda-es.dts
new file mode 100644
index 000000000..2f1dabcc6
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-panda-es.dts
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+/dts-v1/;
+
+#include "omap4460.dtsi"
+#include "omap4-panda-common.dtsi"
+
+/ {
+ model = "TI OMAP4 PandaBoard-ES";
+ compatible = "ti,omap4-panda-es", "ti,omap4-panda", "ti,omap4460", "ti,omap4430", "ti,omap4";
+};
+
+/* Audio routing is differnet between PandaBoard4430 and PandaBoardES */
+&sound {
+ ti,model = "PandaBoardES";
+
+ /* Audio routing */
+ ti,audio-routing =
+ "Headset Stereophone", "HSOL",
+ "Headset Stereophone", "HSOR",
+ "Ext Spk", "HFL",
+ "Ext Spk", "HFR",
+ "Line Out", "AUXL",
+ "Line Out", "AUXR",
+ "AFML", "Line In",
+ "AFMR", "Line In";
+};
+
+/* PandaboardES has external pullups on SCL & SDA */
+&dss_hdmi_pins {
+ pinctrl-single,pins = <
+ 0x5a (PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */
+ 0x5c (PIN_INPUT | MUX_MODE0) /* hdmi_scl.hdmi_scl */
+ 0x5e (PIN_INPUT | MUX_MODE0) /* hdmi_sda.hdmi_sda */
+ >;
+};
+
+&omap4_pmx_core {
+ led_gpio_pins: gpio_led_pmx {
+ pinctrl-single,pins = <
+ 0xb6 (PIN_OUTPUT | MUX_MODE3) /* gpio_110 */
+ >;
+ };
+};
+
+&led_wkgpio_pins {
+ pinctrl-single,pins = <
+ 0x1c (PIN_OUTPUT | MUX_MODE3) /* gpio_wk8 */
+ >;
+};
+
+&leds {
+ pinctrl-0 = <
+ &led_gpio_pins
+ &led_wkgpio_pins
+ >;
+
+ heartbeat {
+ gpios = <&gpio4 14 GPIO_ACTIVE_HIGH>;
+ };
+ mmc {
+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&gpio1 {
+ ti,no-reset-on-init;
+};
diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts
new file mode 100644
index 000000000..a0e28b2e2
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-panda.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+/dts-v1/;
+
+#include "omap443x.dtsi"
+#include "omap4-panda-common.dtsi"
+
+/ {
+ model = "TI OMAP4 PandaBoard";
+ compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4";
+};
diff --git a/arch/arm/boot/dts/omap4-sdp-es23plus.dts b/arch/arm/boot/dts/omap4-sdp-es23plus.dts
new file mode 100644
index 000000000..aad5dda0f
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-sdp-es23plus.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2012 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 "omap4-sdp.dts"
+
+/* SDP boards with 4430 ES2.3+ or 4460 have external pullups on SCL & SDA */
+&dss_hdmi_pins {
+ pinctrl-single,pins = <
+ 0x5a (PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */
+ 0x5c (PIN_INPUT | MUX_MODE0) /* hdmi_scl.hdmi_scl */
+ 0x5e (PIN_INPUT | MUX_MODE0) /* hdmi_sda.hdmi_sda */
+ >;
+};
diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts
new file mode 100644
index 000000000..dac86ed74
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-sdp.dts
@@ -0,0 +1,699 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+/dts-v1/;
+
+#include "omap443x.dtsi"
+#include "elpida_ecb240abacn.dtsi"
+
+/ {
+ model = "TI OMAP4 SDP board";
+ compatible = "ti,omap4-sdp", "ti,omap4430", "ti,omap4";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>; /* 1 GB */
+ };
+
+ aliases {
+ display0 = &lcd0;
+ display1 = &lcd1;
+ display2 = &hdmi0;
+ };
+
+ vdd_eth: fixedregulator-vdd-eth {
+ compatible = "regulator-fixed";
+ regulator-name = "VDD_ETH";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 16 0>; /* gpio line 48 */
+ enable-active-high;
+ regulator-boot-on;
+ };
+
+ vbat: fixedregulator-vbat {
+ compatible = "regulator-fixed";
+ regulator-name = "VBAT";
+ regulator-min-microvolt = <3750000>;
+ regulator-max-microvolt = <3750000>;
+ regulator-boot-on;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ debug0 {
+ label = "omap4:green:debug0";
+ gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>; /* 61 */
+ };
+
+ debug1 {
+ label = "omap4:green:debug1";
+ gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>; /* 30 */
+ };
+
+ debug2 {
+ label = "omap4:green:debug2";
+ gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; /* 7 */
+ };
+
+ debug3 {
+ label = "omap4:green:debug3";
+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; /* 8 */
+ };
+
+ debug4 {
+ label = "omap4:green:debug4";
+ gpios = <&gpio2 18 GPIO_ACTIVE_HIGH>; /* 50 */
+ };
+
+ user1 {
+ label = "omap4:blue:user";
+ gpios = <&gpio6 9 GPIO_ACTIVE_HIGH>; /* 169 */
+ };
+
+ user2 {
+ label = "omap4:red:user";
+ gpios = <&gpio6 10 GPIO_ACTIVE_HIGH>; /* 170 */
+ };
+
+ user3 {
+ label = "omap4:green:user";
+ gpios = <&gpio5 11 GPIO_ACTIVE_HIGH>; /* 139 */
+ };
+ };
+
+ pwmleds {
+ compatible = "pwm-leds";
+ kpad {
+ label = "omap4::keypad";
+ pwms = <&twl_pwm 0 7812500>;
+ max-brightness = <127>;
+ };
+
+ charging {
+ label = "omap4:green:chrg";
+ pwms = <&twl_pwmled 0 7812500>;
+ max-brightness = <255>;
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&twl_pwm 1 7812500>;
+ brightness-levels = <
+ 0 10 20 30 40
+ 50 60 70 80 90
+ 100 110 120 127
+ >;
+ default-brightness-level = <13>;
+ };
+
+ sound {
+ compatible = "ti,abe-twl6040";
+ ti,model = "SDP4430";
+
+ ti,jack-detection = <1>;
+ ti,mclk-freq = <38400000>;
+
+ ti,mcpdm = <&mcpdm>;
+ ti,dmic = <&dmic>;
+
+ ti,twl6040 = <&twl6040>;
+
+ /* Audio routing */
+ ti,audio-routing =
+ "Headset Stereophone", "HSOL",
+ "Headset Stereophone", "HSOR",
+ "Earphone Spk", "EP",
+ "Ext Spk", "HFL",
+ "Ext Spk", "HFR",
+ "Line Out", "AUXL",
+ "Line Out", "AUXR",
+ "Vibrator", "VIBRAL",
+ "Vibrator", "VIBRAR",
+ "HSMIC", "Headset Mic",
+ "Headset Mic", "Headset Mic Bias",
+ "MAINMIC", "Main Handset Mic",
+ "Main Handset Mic", "Main Mic Bias",
+ "SUBMIC", "Sub Handset Mic",
+ "Sub Handset Mic", "Main Mic Bias",
+ "AFML", "Line In",
+ "AFMR", "Line In",
+ "DMic", "Digital Mic",
+ "Digital Mic", "Digital Mic1 Bias";
+ };
+
+ /* regulator for wl12xx on sdio5 */
+ wl12xx_vmmc: wl12xx_vmmc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wl12xx_gpio>;
+ compatible = "regulator-fixed";
+ regulator-name = "vwl1271";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio2 22 0>;
+ startup-delay-us = <70000>;
+ enable-active-high;
+ };
+
+ tpd12s015: encoder@0 {
+ compatible = "ti,tpd12s015";
+
+ gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>, /* 60, CT CP HPD */
+ <&gpio2 9 GPIO_ACTIVE_HIGH>, /* 41, LS OE */
+ <&gpio2 31 GPIO_ACTIVE_HIGH>; /* 63, HPD */
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ tpd12s015_in: endpoint@0 {
+ remote-endpoint = <&hdmi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ tpd12s015_out: endpoint@0 {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+ };
+ };
+
+ hdmi0: connector@0 {
+ compatible = "hdmi-connector";
+ label = "hdmi";
+
+ type = "c";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&tpd12s015_out>;
+ };
+ };
+ };
+};
+
+&omap4_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &dss_hdmi_pins
+ &tpd12s015_pins
+ >;
+
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ 0xd8 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts.uart2_cts */
+ 0xda (PIN_OUTPUT | MUX_MODE0) /* uart2_rts.uart2_rts */
+ 0xdc (PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_rx.uart2_rx */
+ 0xde (PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ 0x100 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart3_cts_rctx.uart3_cts_rctx */
+ 0x102 (PIN_OUTPUT | MUX_MODE0) /* uart3_rts_sd.uart3_rts_sd */
+ 0x104 (PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+ 0x106 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */
+ >;
+ };
+
+ uart4_pins: pinmux_uart4_pins {
+ pinctrl-single,pins = <
+ 0x11c (PIN_INPUT | MUX_MODE0) /* uart4_rx.uart4_rx */
+ 0x11e (PIN_OUTPUT | MUX_MODE0) /* uart4_tx.uart4_tx */
+ >;
+ };
+
+ twl6040_pins: pinmux_twl6040_pins {
+ pinctrl-single,pins = <
+ 0xe0 (PIN_OUTPUT | MUX_MODE3) /* hdq_sio.gpio_127 */
+ 0x160 (PIN_INPUT | MUX_MODE0) /* sys_nirq2.sys_nirq2 */
+ >;
+ };
+
+ mcpdm_pins: pinmux_mcpdm_pins {
+ pinctrl-single,pins = <
+ 0xc6 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_pdm_ul_data.abe_pdm_ul_data */
+ 0xc8 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_pdm_dl_data.abe_pdm_dl_data */
+ 0xca (PIN_INPUT_PULLUP | MUX_MODE0) /* abe_pdm_frame.abe_pdm_frame */
+ 0xcc (PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_pdm_lb_clk.abe_pdm_lb_clk */
+ 0xce (PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_clks.abe_clks */
+ >;
+ };
+
+ dmic_pins: pinmux_dmic_pins {
+ pinctrl-single,pins = <
+ 0xd0 (PIN_OUTPUT | MUX_MODE0) /* abe_dmic_clk1.abe_dmic_clk1 */
+ 0xd2 (PIN_INPUT | MUX_MODE0) /* abe_dmic_din1.abe_dmic_din1 */
+ 0xd4 (PIN_INPUT | MUX_MODE0) /* abe_dmic_din2.abe_dmic_din2 */
+ 0xd6 (PIN_INPUT | MUX_MODE0) /* abe_dmic_din3.abe_dmic_din3 */
+ >;
+ };
+
+ mcbsp1_pins: pinmux_mcbsp1_pins {
+ pinctrl-single,pins = <
+ 0xbe (PIN_INPUT | MUX_MODE0) /* abe_mcbsp1_clkx.abe_mcbsp1_clkx */
+ 0xc0 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp1_dr.abe_mcbsp1_dr */
+ 0xc2 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp1_dx.abe_mcbsp1_dx */
+ 0xc4 (PIN_INPUT | MUX_MODE0) /* abe_mcbsp1_fsx.abe_mcbsp1_fsx */
+ >;
+ };
+
+ mcbsp2_pins: pinmux_mcbsp2_pins {
+ pinctrl-single,pins = <
+ 0xb6 (PIN_INPUT | MUX_MODE0) /* abe_mcbsp2_clkx.abe_mcbsp2_clkx */
+ 0xb8 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp2_dr.abe_mcbsp2_dr */
+ 0xba (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp2_dx.abe_mcbsp2_dx */
+ 0xbc (PIN_INPUT | MUX_MODE0) /* abe_mcbsp2_fsx.abe_mcbsp2_fsx */
+ >;
+ };
+
+ mcspi1_pins: pinmux_mcspi1_pins {
+ pinctrl-single,pins = <
+ 0xf2 (PIN_INPUT | MUX_MODE0) /* mcspi1_clk.mcspi1_clk */
+ 0xf4 (PIN_INPUT | MUX_MODE0) /* mcspi1_somi.mcspi1_somi */
+ 0xf6 (PIN_INPUT | MUX_MODE0) /* mcspi1_simo.mcspi1_simo */
+ 0xf8 (PIN_INPUT | MUX_MODE0) /* mcspi1_cs0.mcspi1_cs0 */
+ >;
+ };
+
+ dss_hdmi_pins: pinmux_dss_hdmi_pins {
+ pinctrl-single,pins = <
+ 0x5a (PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */
+ 0x5c (PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_scl.hdmi_scl */
+ 0x5e (PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_sda.hdmi_sda */
+ >;
+ };
+
+ tpd12s015_pins: pinmux_tpd12s015_pins {
+ pinctrl-single,pins = <
+ 0x22 (PIN_OUTPUT | MUX_MODE3) /* gpmc_a17.gpio_41 */
+ 0x48 (PIN_OUTPUT | MUX_MODE3) /* gpmc_nbe1.gpio_60 */
+ 0x58 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* hdmi_hpd.gpio_63 */
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ 0xe2 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */
+ 0xe4 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */
+ >;
+ };
+
+ i2c2_pins: pinmux_i2c2_pins {
+ pinctrl-single,pins = <
+ 0xe6 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_scl */
+ 0xe8 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_sda */
+ >;
+ };
+
+ i2c3_pins: pinmux_i2c3_pins {
+ pinctrl-single,pins = <
+ 0xea (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */
+ 0xec (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */
+ >;
+ };
+
+ i2c4_pins: pinmux_i2c4_pins {
+ pinctrl-single,pins = <
+ 0xee (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */
+ 0xf0 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */
+ >;
+ };
+
+ /* wl12xx GPIO output for WLAN_EN */
+ wl12xx_gpio: pinmux_wl12xx_gpio {
+ pinctrl-single,pins = <
+ 0x3c (PIN_OUTPUT | MUX_MODE3) /* gpmc_nwp.gpio_54 */
+ >;
+ };
+
+ /* wl12xx GPIO inputs and SDIO pins */
+ wl12xx_pins: pinmux_wl12xx_pins {
+ pinctrl-single,pins = <
+ 0x3a (PIN_INPUT | MUX_MODE3) /* gpmc_ncs3.gpio_53 */
+ 0x108 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_clk.sdmmc5_clk */
+ 0x10a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_cmd.sdmmc5_cmd */
+ 0x10c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat0.sdmmc5_dat0 */
+ 0x10e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat1.sdmmc5_dat1 */
+ 0x110 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat2.sdmmc5_dat2 */
+ 0x112 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat3.sdmmc5_dat3 */
+ >;
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+
+ clock-frequency = <400000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ /* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */
+ };
+
+ twl6040: twl@4b {
+ compatible = "ti,twl6040";
+ reg = <0x4b>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&twl6040_pins>;
+
+ /* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */
+ interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */
+ ti,audpwron-gpio = <&gpio4 31 0>; /* gpio line 127 */
+
+ vio-supply = <&v1v8>;
+ v2v1-supply = <&v2v1>;
+ enable-active-high;
+
+ /* regulators for vibra motor */
+ vddvibl-supply = <&vbat>;
+ vddvibr-supply = <&vbat>;
+
+ vibra {
+ /* Vibra driver, motor resistance parameters */
+ ti,vibldrv-res = <8>;
+ ti,vibrdrv-res = <3>;
+ ti,viblmotor-res = <10>;
+ ti,vibrmotor-res = <10>;
+ };
+ };
+};
+
+#include "twl6030.dtsi"
+#include "twl6030_omap4.dtsi"
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+
+ clock-frequency = <400000>;
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+
+ clock-frequency = <400000>;
+
+ /*
+ * Temperature Sensor
+ * http://www.ti.com/lit/ds/symlink/tmp105.pdf
+ */
+ tmp105@48 {
+ compatible = "ti,tmp105";
+ reg = <0x48>;
+ };
+
+ /*
+ * Ambient Light Sensor
+ * http://www.rohm.com/products/databook/sensor/pdf/bh1780gli-e.pdf
+ */
+ bh1780@29 {
+ compatible = "rohm,bh1780";
+ reg = <0x29>;
+ };
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins>;
+
+ clock-frequency = <400000>;
+
+ /*
+ * 3-Axis Digital Compass
+ * http://www.sparkfun.com/datasheets/Sensors/Magneto/HMC5843.pdf
+ */
+ hmc5843@1e {
+ compatible = "honeywell,hmc5843";
+ reg = <0x1e>;
+ };
+};
+
+&mcspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi1_pins>;
+
+ eth@0 {
+ compatible = "ks8851";
+ spi-max-frequency = <24000000>;
+ reg = <0>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>; /* gpio line 34 */
+ vdd-supply = <&vdd_eth>;
+ };
+};
+
+&mmc1 {
+ vmmc-supply = <&vmmc>;
+ bus-width = <8>;
+};
+
+&mmc2 {
+ vmmc-supply = <&vaux1>;
+ bus-width = <8>;
+ ti,non-removable;
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&mmc4 {
+ status = "disabled";
+};
+
+&mmc5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wl12xx_pins>;
+ vmmc-supply = <&wl12xx_vmmc>;
+ non-removable;
+ bus-width = <4>;
+ cap-power-off-card;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1281";
+ reg = <2>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <21 IRQ_TYPE_LEVEL_HIGH>; /* gpio 53 */
+ ref-clock-frequency = <26000000>;
+ tcxo-clock-frequency = <26000000>;
+ };
+};
+
+&emif1 {
+ cs1-used;
+ device-handle = <&elpida_ECB240ABACN>;
+};
+
+&emif2 {
+ cs1-used;
+ device-handle = <&elpida_ECB240ABACN>;
+};
+
+&keypad {
+ keypad,num-rows = <8>;
+ keypad,num-columns = <8>;
+ linux,keymap = <0x00000012 /* KEY_E */
+ 0x00010013 /* KEY_R */
+ 0x00020014 /* KEY_T */
+ 0x00030066 /* KEY_HOME */
+ 0x0004003f /* KEY_F5 */
+ 0x000500f0 /* KEY_UNKNOWN */
+ 0x00060017 /* KEY_I */
+ 0x0007002a /* KEY_LEFTSHIFT */
+ 0x01000020 /* KEY_D*/
+ 0x01010021 /* KEY_F */
+ 0x01020022 /* KEY_G */
+ 0x010300e7 /* KEY_SEND */
+ 0x01040040 /* KEY_F6 */
+ 0x010500f0 /* KEY_UNKNOWN */
+ 0x01060025 /* KEY_K */
+ 0x0107001c /* KEY_ENTER */
+ 0x0200002d /* KEY_X */
+ 0x0201002e /* KEY_C */
+ 0x0202002f /* KEY_V */
+ 0x0203006b /* KEY_END */
+ 0x02040041 /* KEY_F7 */
+ 0x020500f0 /* KEY_UNKNOWN */
+ 0x02060034 /* KEY_DOT */
+ 0x0207003a /* KEY_CAPSLOCK */
+ 0x0300002c /* KEY_Z */
+ 0x0301004e /* KEY_KPLUS */
+ 0x03020030 /* KEY_B */
+ 0x0303003b /* KEY_F1 */
+ 0x03040042 /* KEY_F8 */
+ 0x030500f0 /* KEY_UNKNOWN */
+ 0x03060018 /* KEY_O */
+ 0x03070039 /* KEY_SPACE */
+ 0x04000011 /* KEY_W */
+ 0x04010015 /* KEY_Y */
+ 0x04020016 /* KEY_U */
+ 0x0403003c /* KEY_F2 */
+ 0x04040073 /* KEY_VOLUMEUP */
+ 0x040500f0 /* KEY_UNKNOWN */
+ 0x04060026 /* KEY_L */
+ 0x04070069 /* KEY_LEFT */
+ 0x0500001f /* KEY_S */
+ 0x05010023 /* KEY_H */
+ 0x05020024 /* KEY_J */
+ 0x0503003d /* KEY_F3 */
+ 0x05040043 /* KEY_F9 */
+ 0x05050072 /* KEY_VOLUMEDOWN */
+ 0x05060032 /* KEY_M */
+ 0x0507006a /* KEY_RIGHT */
+ 0x06000010 /* KEY_Q */
+ 0x0601001e /* KEY_A */
+ 0x06020031 /* KEY_N */
+ 0x0603009e /* KEY_BACK */
+ 0x0604000e /* KEY_BACKSPACE */
+ 0x060500f0 /* KEY_UNKNOWN */
+ 0x06060019 /* KEY_P */
+ 0x06070067 /* KEY_UP */
+ 0x07000094 /* KEY_PROG1 */
+ 0x07010095 /* KEY_PROG2 */
+ 0x070200ca /* KEY_PROG3 */
+ 0x070300cb /* KEY_PROG4 */
+ 0x0704003e /* KEY_F4 */
+ 0x070500f0 /* KEY_UNKNOWN */
+ 0x07060160 /* KEY_OK */
+ 0x0707006c>; /* KEY_DOWN */
+ linux,input-no-autorepeat;
+};
+
+&uart2 {
+ interrupts-extended = <&wakeupgen GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH
+ &omap4_pmx_core OMAP4_UART2_RX>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+};
+
+&uart3 {
+ interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH
+ &omap4_pmx_core OMAP4_UART3_RX>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+};
+
+&uart4 {
+ interrupts-extended = <&wakeupgen GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH
+ &omap4_pmx_core OMAP4_UART4_RX>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins>;
+};
+
+&mcbsp1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcbsp1_pins>;
+ status = "okay";
+};
+
+&mcbsp2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcbsp2_pins>;
+ status = "okay";
+};
+
+&dmic {
+ pinctrl-names = "default";
+ pinctrl-0 = <&dmic_pins>;
+ status = "okay";
+};
+
+&mcpdm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcpdm_pins>;
+ status = "okay";
+};
+
+&twl_usb_comparator {
+ usb-supply = <&vusb>;
+};
+
+&usb_otg_hs {
+ interface-type = <1>;
+ mode = <3>;
+ power = <50>;
+};
+
+&dss {
+ status = "ok";
+};
+
+&dsi1 {
+ status = "ok";
+ vdd-supply = <&vcxio>;
+
+ port {
+ dsi1_out_ep: endpoint {
+ remote-endpoint = <&lcd0_in>;
+ lanes = <0 1 2 3 4 5>;
+ };
+ };
+
+ lcd0: display {
+ compatible = "tpo,taal", "panel-dsi-cm";
+ label = "lcd0";
+
+ reset-gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* 102 */
+
+ port {
+ lcd0_in: endpoint {
+ remote-endpoint = <&dsi1_out_ep>;
+ };
+ };
+ };
+};
+
+&dsi2 {
+ status = "ok";
+ vdd-supply = <&vcxio>;
+
+ port {
+ dsi2_out_ep: endpoint {
+ remote-endpoint = <&lcd1_in>;
+ lanes = <0 1 2 3 4 5>;
+ };
+ };
+
+ lcd1: display {
+ compatible = "tpo,taal", "panel-dsi-cm";
+ label = "lcd1";
+
+ reset-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* 104 */
+
+ port {
+ lcd1_in: endpoint {
+ remote-endpoint = <&dsi2_out_ep>;
+ };
+ };
+ };
+};
+
+&hdmi {
+ status = "ok";
+ vdda-supply = <&vdac>;
+
+ port {
+ hdmi_out: endpoint {
+ remote-endpoint = <&tpd12s015_in>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap4-var-dvk-om44.dts b/arch/arm/boot/dts/omap4-var-dvk-om44.dts
new file mode 100644
index 000000000..458d79fa3
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-var-dvk-om44.dts
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2014 Joachim Eastwood <manabian@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.
+ */
+/dts-v1/;
+
+#include "omap4-var-som-om44.dtsi"
+#include "omap4-var-som-om44-wlan.dtsi"
+#include "omap4-var-om44customboard.dtsi"
+
+/ {
+ model = "Variscite VAR-DVK-OM44";
+ compatible = "variscite,var-dvk-om44", "variscite,var-som-om44", "ti,omap4460", "ti,omap4";
+
+ aliases {
+ display0 = &lcd0;
+ display1 = &hdmi0;
+ };
+
+ lcd0: display {
+ compatible = "innolux,at070tn83", "panel-dpi";
+ label = "lcd";
+ panel-timing {
+ clock-frequency = <33333333>;
+
+ hback-porch = <40>;
+ hactive = <800>;
+ hfront-porch = <40>;
+ hsync-len = <48>;
+
+ vback-porch = <29>;
+ vactive = <480>;
+ vfront-porch = <13>;
+ vsync-len = <3>;
+ };
+
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+ };
+
+ backlight {
+ compatible = "gpio-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&backlight_pins>;
+
+ gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>; /* gpio 122 */
+ };
+};
+
+&dss {
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_dpi_pins>;
+
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+&dsi2 {
+ status = "okay";
+ vdd-supply = <&vcxio>;
+};
diff --git a/arch/arm/boot/dts/omap4-var-om44customboard.dtsi b/arch/arm/boot/dts/omap4-var-om44customboard.dtsi
new file mode 100644
index 000000000..f2d2fdb75
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-var-om44customboard.dtsi
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2014 Joachim Eastwood <manabian@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 <dt-bindings/input/input.h>
+
+/ {
+ aliases {
+ display0 = &hdmi0;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_led_pins>;
+
+ led0 {
+ label = "var:green:led0";
+ gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>; /* gpio 173 */
+ linux,default-trigger = "heartbeat";
+ };
+
+ led1 {
+ label = "var:green:led1";
+ gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>; /* gpio 172 */
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_key_pins>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ user-key@184 {
+ label = "user";
+ gpios = <&gpio6 24 GPIO_ACTIVE_HIGH>; /* gpio 184 */
+ linux,code = <BTN_EXTRA>;
+ gpio-key,wakeup;
+ };
+ };
+
+ hdmi0: connector@0 {
+ compatible = "hdmi-connector";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_hpd_pins>;
+ label = "hdmi";
+ type = "a";
+
+ hpd-gpios = <&gpio2 31 GPIO_ACTIVE_HIGH>; /* gpio_63 */
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_out>;
+ };
+ };
+ };
+};
+
+&omap4_pmx_core {
+ uart1_pins: pinmux_uart1_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x13c, PIN_INPUT_PULLUP | MUX_MODE1) /* mcspi1_cs2.uart1_cts */
+ OMAP4_IOPAD(0x13e, PIN_OUTPUT | MUX_MODE1) /* mcspi1_cs3.uart1_rts */
+ OMAP4_IOPAD(0x126, PIN_INPUT_PULLUP | MUX_MODE1) /* i2c2_scl.uart1_rx */
+ OMAP4_IOPAD(0x128, PIN_OUTPUT | MUX_MODE1) /* i2c2_sda.uart1_tx */
+ >;
+ };
+
+ mcspi1_pins: pinmux_mcspi1_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x132, PIN_INPUT | MUX_MODE0) /* mcspi1_clk.mcspi1_clk */
+ OMAP4_IOPAD(0x134, PIN_INPUT | MUX_MODE0) /* mcspi1_somi.mcspi1_somi */
+ OMAP4_IOPAD(0x136, PIN_INPUT | MUX_MODE0) /* mcspi1_simo.mcspi1_simo */
+ OMAP4_IOPAD(0x138, PIN_INPUT | MUX_MODE0) /* mcspi1_cs0.mcspi1_cs0 */
+ >;
+ };
+
+ mcasp_pins: pinmux_mcsasp_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x0f8, PIN_OUTPUT | MUX_MODE2) /* mcbsp2_dr.abe_mcasp_axr */
+ >;
+ };
+
+ dss_dpi_pins: pinmux_dss_dpi_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x162, PIN_OUTPUT | MUX_MODE5) /* dispc2_data23 */
+ OMAP4_IOPAD(0x164, PIN_OUTPUT | MUX_MODE5) /* dispc2_data22 */
+ OMAP4_IOPAD(0x166, PIN_OUTPUT | MUX_MODE5) /* dispc2_data21 */
+ OMAP4_IOPAD(0x168, PIN_OUTPUT | MUX_MODE5) /* dispc2_data20 */
+ OMAP4_IOPAD(0x16a, PIN_OUTPUT | MUX_MODE5) /* dispc2_data19 */
+ OMAP4_IOPAD(0x16c, PIN_OUTPUT | MUX_MODE5) /* dispc2_data18 */
+ OMAP4_IOPAD(0x16e, PIN_OUTPUT | MUX_MODE5) /* dispc2_data15 */
+ OMAP4_IOPAD(0x170, PIN_OUTPUT | MUX_MODE5) /* dispc2_data14 */
+ OMAP4_IOPAD(0x172, PIN_OUTPUT | MUX_MODE5) /* dispc2_data13 */
+ OMAP4_IOPAD(0x174, PIN_OUTPUT | MUX_MODE5) /* dispc2_data12 */
+ OMAP4_IOPAD(0x176, PIN_OUTPUT | MUX_MODE5) /* dispc2_data11 */
+ OMAP4_IOPAD(0x1b4, PIN_OUTPUT | MUX_MODE5) /* dispc2_data10 */
+ OMAP4_IOPAD(0x1b6, PIN_OUTPUT | MUX_MODE5) /* dispc2_data9 */
+ OMAP4_IOPAD(0x1b8, PIN_OUTPUT | MUX_MODE5) /* dispc2_data16 */
+ OMAP4_IOPAD(0x1ba, PIN_OUTPUT | MUX_MODE5) /* dispc2_data17 */
+ OMAP4_IOPAD(0x1bc, PIN_OUTPUT | MUX_MODE5) /* dispc2_hsync */
+ OMAP4_IOPAD(0x1be, PIN_OUTPUT | MUX_MODE5) /* dispc2_pclk */
+ OMAP4_IOPAD(0x1c0, PIN_OUTPUT | MUX_MODE5) /* dispc2_vsync */
+ OMAP4_IOPAD(0x1c2, PIN_OUTPUT | MUX_MODE5) /* dispc2_de */
+ OMAP4_IOPAD(0x1c4, PIN_OUTPUT | MUX_MODE5) /* dispc2_data8 */
+ OMAP4_IOPAD(0x1c6, PIN_OUTPUT | MUX_MODE5) /* dispc2_data7 */
+ OMAP4_IOPAD(0x1c8, PIN_OUTPUT | MUX_MODE5) /* dispc2_data6 */
+ OMAP4_IOPAD(0x1ca, PIN_OUTPUT | MUX_MODE5) /* dispc2_data5 */
+ OMAP4_IOPAD(0x1cc, PIN_OUTPUT | MUX_MODE5) /* dispc2_data4 */
+ OMAP4_IOPAD(0x1ce, PIN_OUTPUT | MUX_MODE5) /* dispc2_data3 */
+ OMAP4_IOPAD(0x1d0, PIN_OUTPUT | MUX_MODE5) /* dispc2_data2 */
+ OMAP4_IOPAD(0x1d2, PIN_OUTPUT | MUX_MODE5) /* dispc2_data1 */
+ OMAP4_IOPAD(0x1d4, PIN_OUTPUT | MUX_MODE5) /* dispc2_data0 */
+ >;
+ };
+
+ dss_hdmi_pins: pinmux_dss_hdmi_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */
+ OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_scl.hdmi_scl */
+ OMAP4_IOPAD(0x09e, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_sda.hdmi_sda */
+ >;
+ };
+
+ i2c4_pins: pinmux_i2c4_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x12e, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */
+ OMAP4_IOPAD(0x130, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */
+ >;
+ };
+
+ mmc5_pins: pinmux_mmc5_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x0f6, PIN_INPUT | MUX_MODE3) /* abe_mcbsp2_clkx.gpio_110 */
+ OMAP4_IOPAD(0x148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_clk.sdmmc5_clk */
+ OMAP4_IOPAD(0x14a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_cmd.sdmmc5_cmd */
+ OMAP4_IOPAD(0x14c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat0.sdmmc5_dat0 */
+ OMAP4_IOPAD(0x14e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat1.sdmmc5_dat1 */
+ OMAP4_IOPAD(0x150, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat2.sdmmc5_dat2 */
+ OMAP4_IOPAD(0x152, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat3.sdmmc5_dat3 */
+ >;
+ };
+
+ gpio_led_pins: pinmux_gpio_led_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x17e, PIN_OUTPUT | MUX_MODE3) /* kpd_col4.gpio_172 */
+ OMAP4_IOPAD(0x180, PIN_OUTPUT | MUX_MODE3) /* kpd_col5.gpio_173 */
+ >;
+ };
+
+ gpio_key_pins: pinmux_gpio_key_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x1a2, PIN_INPUT | MUX_MODE3) /* sys_boot0.gpio_184 */
+ >;
+ };
+
+ ks8851_irq_pins: pinmux_ks8851_irq_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x17c, PIN_INPUT_PULLUP | MUX_MODE3) /* kpd_col3.gpio_171 */
+ >;
+ };
+
+ hdmi_hpd_pins: pinmux_hdmi_hpd_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x098, PIN_INPUT_PULLDOWN | MUX_MODE3) /* hdmi_hpd.gpio_63 */
+ >;
+ };
+
+ backlight_pins: pinmux_backlight_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x116, PIN_OUTPUT | MUX_MODE3) /* abe_dmic_din3.gpio_122 */
+ >;
+ };
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins>;
+ clock-frequency = <400000>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "okay";
+};
+
+&mcspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi1_pins>;
+ status = "okay";
+
+ eth@0 {
+ compatible = "ks8851";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ks8851_irq_pins>;
+ spi-max-frequency = <24000000>;
+ reg = <0>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; /* gpio 171 */
+ };
+};
+
+&mmc5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc5_pins>;
+ vmmc-supply = <&vbat>;
+ bus-width = <4>;
+ cd-gpios = <&gpio4 14 GPIO_ACTIVE_HIGH>; /* gpio 110 */
+ status = "okay";
+};
+
+&dss {
+ status = "okay";
+};
+
+&hdmi {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_hdmi_pins>;
+ vdda-supply = <&vdac>;
+
+ port {
+ hdmi_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi b/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi
new file mode 100644
index 000000000..9bceeb7e1
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 Joachim Eastwood <manabian@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.
+ */
+
+/ {
+ /* regulator for wl12xx on sdio4 */
+ wl12xx_vmmc: wl12xx_vmmc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wl12xx_ctrl_pins>;
+ compatible = "regulator-fixed";
+ regulator-name = "vwl1271";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio2 11 0>; /* gpio 43 */
+ startup-delay-us = <70000>;
+ enable-active-high;
+ };
+};
+
+&omap4_pmx_core {
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x118, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts.uart2_cts */
+ OMAP4_IOPAD(0x11a, PIN_OUTPUT | MUX_MODE0) /* uart2_rts.uart2_rts */
+ OMAP4_IOPAD(0x11c, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_rx.uart2_rx */
+ OMAP4_IOPAD(0x11e, PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */
+ >;
+ };
+
+ wl12xx_ctrl_pins: pinmux_wl12xx_ctrl_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x062, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a17.gpio_41 (WLAN_IRQ) */
+ OMAP4_IOPAD(0x064, PIN_OUTPUT | MUX_MODE3) /* gpmc_a18.gpio_42 (BT_EN) */
+ OMAP4_IOPAD(0x066, PIN_OUTPUT | MUX_MODE3) /* gpmc_a19.gpio_43 (WLAN_EN) */
+ >;
+ };
+
+ mmc4_pins: pinmux_mmc4_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x154, PIN_INPUT_PULLUP | MUX_MODE1) /* mcspi4_clk.sdmmc4_clk */
+ OMAP4_IOPAD(0x156, PIN_INPUT_PULLUP | MUX_MODE1) /* mcspi4_simo.sdmmc4_cmd */
+ OMAP4_IOPAD(0x158, PIN_INPUT_PULLUP | MUX_MODE1) /* mcspi4_somi.sdmmc4_dat0 */
+ OMAP4_IOPAD(0x15e, PIN_INPUT_PULLUP | MUX_MODE1) /* uart4_tx.sdmmc4_dat1 */
+ OMAP4_IOPAD(0x15c, PIN_INPUT_PULLUP | MUX_MODE1) /* uart4_rx.sdmmc4_dat2 */
+ OMAP4_IOPAD(0x15a, PIN_INPUT_PULLUP | MUX_MODE1) /* mcspi4_cs0.sdmmc4_dat3 */
+ >;
+ };
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+ status = "okay";
+};
+
+&mmc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc4_pins>;
+ vmmc-supply = <&wl12xx_vmmc>;
+ non-removable;
+ bus-width = <4>;
+ cap-power-off-card;
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1271";
+ reg = <2>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH>; /* gpio 41 */
+ ref-clock-frequency = <38400000>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap4-var-som-om44.dtsi b/arch/arm/boot/dts/omap4-var-som-om44.dtsi
new file mode 100644
index 000000000..a4f1ba2e1
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-var-som-om44.dtsi
@@ -0,0 +1,341 @@
+/*
+ * Copyright (C) 2014 Joachim Eastwood <manabian@gmail.com>
+ * Copyright (C) 2012 Variscite Ltd. - http://www.variscite.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 "omap4460.dtsi"
+
+/ {
+ model = "Variscite VAR-SOM-OM44";
+ compatible = "variscite,var-som-om44", "ti,omap4460", "ti,omap4";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>; /* 1 GB */
+ };
+
+ sound: sound@0 {
+ compatible = "ti,abe-twl6040";
+ ti,model = "VAR-SOM-OM44";
+
+ ti,mclk-freq = <38400000>;
+ ti,mcpdm = <&mcpdm>;
+ ti,twl6040 = <&twl6040>;
+
+ /* Audio routing */
+ ti,audio-routing =
+ "Headset Stereophone", "HSOL",
+ "Headset Stereophone", "HSOR",
+ "AFML", "Line In",
+ "AFMR", "Line In";
+ };
+
+ /* HS USB Host PHY on PORT 1 */
+ hsusb1_phy: hsusb1_phy {
+ compatible = "usb-nop-xceiv";
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusbb1_phy_clk_pins
+ &hsusbb1_phy_rst_pins
+ >;
+
+ reset-gpios = <&gpio6 17 GPIO_ACTIVE_LOW>; /* gpio 177 */
+ vcc-supply = <&vbat>;
+
+ clocks = <&auxclk3_ck>;
+ clock-names = "main_clk";
+ clock-frequency = <19200000>;
+ };
+
+ vbat: fixedregulator-vbat {
+ compatible = "regulator-fixed";
+ regulator-name = "VBAT";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&omap4_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusbb1_pins
+ >;
+
+ twl6040_pins: pinmux_twl6040_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x19c, PIN_OUTPUT | MUX_MODE3) /* fref_clk2_out.gpio_182 */
+ OMAP4_IOPAD(0x1a0, PIN_INPUT | MUX_MODE0) /* sys_nirq2.sys_nirq2 */
+ >;
+ };
+
+ mcpdm_pins: pinmux_mcpdm_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x106, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_pdm_ul_data.abe_pdm_ul_data */
+ OMAP4_IOPAD(0x108, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_pdm_dl_data.abe_pdm_dl_data */
+ OMAP4_IOPAD(0x10a, PIN_INPUT_PULLUP | MUX_MODE0) /* abe_pdm_frame.abe_pdm_frame */
+ OMAP4_IOPAD(0x10c, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_pdm_lb_clk.abe_pdm_lb_clk */
+ OMAP4_IOPAD(0x10e, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_clks.abe_clks */
+ >;
+ };
+
+ tsc2004_pins: pinmux_tsc2004_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x090, PIN_INPUT | MUX_MODE3) /* gpmc_ncs4.gpio_101 (irq) */
+ OMAP4_IOPAD(0x092, PIN_OUTPUT | MUX_MODE3) /* gpmc_ncs5.gpio_102 (rst) */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x140, PIN_INPUT_PULLUP | MUX_MODE0) /* uart3_cts_rctx.uart3_cts_rctx */
+ OMAP4_IOPAD(0x142, PIN_OUTPUT | MUX_MODE0) /* uart3_rts_sd.uart3_rts_sd */
+ OMAP4_IOPAD(0x144, PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+ OMAP4_IOPAD(0x146, PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */
+ >;
+ };
+
+ hsusbb1_pins: pinmux_hsusbb1_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x0c2, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_clk.usbb1_ulpiphy_clk */
+ OMAP4_IOPAD(0x0c4, PIN_OUTPUT | MUX_MODE4) /* usbb1_ulpitll_stp.usbb1_ulpiphy_stp */
+ OMAP4_IOPAD(0x0c6, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dir.usbb1_ulpiphy_dir */
+ OMAP4_IOPAD(0x0c8, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_nxt.usbb1_ulpiphy_nxt */
+ OMAP4_IOPAD(0x0ca, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat0.usbb1_ulpiphy_dat0 */
+ OMAP4_IOPAD(0x0cc, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat1.usbb1_ulpiphy_dat1 */
+ OMAP4_IOPAD(0x0ce, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat2.usbb1_ulpiphy_dat2 */
+ OMAP4_IOPAD(0x0d0, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat3.usbb1_ulpiphy_dat3 */
+ OMAP4_IOPAD(0x0d2, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat4.usbb1_ulpiphy_dat4 */
+ OMAP4_IOPAD(0x0d4, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat5.usbb1_ulpiphy_dat5 */
+ OMAP4_IOPAD(0x0d6, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat6.usbb1_ulpiphy_dat6 */
+ OMAP4_IOPAD(0x0d8, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_dat7.usbb1_ulpiphy_dat7 */
+ >;
+ };
+
+ hsusbb1_phy_rst_pins: pinmux_hsusbb1_phy_rst_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x18c, PIN_OUTPUT | MUX_MODE3) /* kpd_row2.gpio_177 */
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x122, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */
+ OMAP4_IOPAD(0x124, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */
+ >;
+ };
+
+ i2c3_pins: pinmux_i2c3_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x12a, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */
+ OMAP4_IOPAD(0x12c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x0e2, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */
+ OMAP4_IOPAD(0x0e4, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */
+ OMAP4_IOPAD(0x0e6, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */
+ OMAP4_IOPAD(0x0e8, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */
+ OMAP4_IOPAD(0x0ea, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */
+ OMAP4_IOPAD(0x0ec, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
+ >;
+ };
+};
+
+&omap4_pmx_wkup {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusbb1_hub_rst_pins
+ &lan7500_rst_pins
+ >;
+
+ hsusbb1_phy_clk_pins: pinmux_hsusbb1_phy_clk_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x058, PIN_OUTPUT | MUX_MODE0) /* fref_clk3_out */
+ >;
+ };
+
+ hsusbb1_hub_rst_pins: pinmux_hsusbb1_hub_rst_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x042, PIN_OUTPUT | MUX_MODE3) /* gpio_wk1 */
+ >;
+ };
+
+ lan7500_rst_pins: pinmux_lan7500_rst_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x040, PIN_OUTPUT | MUX_MODE3) /* gpio_wk0 */
+ >;
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ status = "okay";
+
+ clock-frequency = <400000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ /* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */
+ };
+
+ twl6040: twl@4b {
+ compatible = "ti,twl6040";
+ reg = <0x4b>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&twl6040_pins>;
+
+ /* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */
+ interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */
+ ti,audpwron-gpio = <&gpio6 22 0>; /* gpio 182 */
+
+ vio-supply = <&v1v8>;
+ v2v1-supply = <&v2v1>;
+ enable-active-high;
+ };
+};
+
+#include "twl6030.dtsi"
+#include "twl6030_omap4.dtsi"
+
+&vusim {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+};
+
+&i2c2 {
+ status = "disabled";
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+ status = "okay";
+
+ clock-frequency = <400000>;
+
+ touchscreen: tsc2004@48 {
+ compatible = "ti,tsc2004";
+ reg = <0x48>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&tsc2004_pins>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <5 IRQ_TYPE_LEVEL_LOW>; /* gpio 101 */
+ status = "disabled";
+ };
+
+ tmp105@49 {
+ compatible = "ti,tmp105";
+ reg = <0x49>;
+ };
+
+ eeprom@50 {
+ compatible = "microchip,24c32";
+ reg = <0x50>;
+ };
+};
+
+&i2c4 {
+ status = "disabled";
+};
+
+&mcpdm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcpdm_pins>;
+ status = "okay";
+};
+
+&gpmc {
+ status = "disabled";
+};
+
+&mcspi1 {
+ status = "disabled";
+};
+
+&mcspi2 {
+ status = "disabled";
+};
+
+&mcspi3 {
+ status = "disabled";
+};
+
+&mcspi4 {
+ status = "disabled";
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&vmmc>;
+ bus-width = <4>;
+ ti,non-removable;
+ status = "okay";
+};
+
+&mmc2 {
+ status = "disabled";
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&mmc4 {
+ status = "disabled";
+};
+
+&mmc5 {
+ status = "disabled";
+};
+
+&uart1 {
+ status = "disabled";
+};
+
+&uart2 {
+ status = "disabled";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+ status = "okay";
+};
+
+&uart4 {
+ status = "disabled";
+};
+
+&keypad {
+ status = "disabled";
+};
+
+&twl_usb_comparator {
+ usb-supply = <&vusb>;
+};
+
+&usb_otg_hs {
+ interface-type = <1>;
+ mode = <3>;
+ power = <50>;
+};
+
+&usbhshost {
+ port1-mode = "ehci-phy";
+};
+
+&usbhsehci {
+ phys = <&hsusb1_phy>;
+};
diff --git a/arch/arm/boot/dts/omap4-var-stk-om44.dts b/arch/arm/boot/dts/omap4-var-stk-om44.dts
new file mode 100644
index 000000000..56b64e618
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-var-stk-om44.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2014 Joachim Eastwood <manabian@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.
+ */
+/dts-v1/;
+
+#include "omap4-var-som-om44.dtsi"
+#include "omap4-var-som-om44-wlan.dtsi"
+#include "omap4-var-om44customboard.dtsi"
+
+/ {
+ model = "Variscite VAR-STK-OM44";
+ compatible = "variscite,var-stk-om44", "variscite,var-som-om44", "ti,omap4460", "ti,omap4";
+};
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
new file mode 100644
index 000000000..f884d6adb
--- /dev/null
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -0,0 +1,1009 @@
+/*
+ * Copyright (C) 2011 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/omap.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "ti,omap4430", "ti,omap4";
+ interrupt-parent = <&wakeupgen>;
+
+ aliases {
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ i2c2 = &i2c3;
+ i2c3 = &i2c4;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ next-level-cache = <&L2>;
+ reg = <0x0>;
+
+ clocks = <&dpll_mpu_ck>;
+ clock-names = "cpu";
+
+ clock-latency = <300000>; /* From omap-cpufreq driver */
+ };
+ cpu@1 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ next-level-cache = <&L2>;
+ reg = <0x1>;
+ };
+ };
+
+ gic: interrupt-controller@48241000 {
+ compatible = "arm,cortex-a9-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x48241000 0x1000>,
+ <0x48240100 0x0100>;
+ interrupt-parent = <&gic>;
+ };
+
+ L2: l2-cache-controller@48242000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x48242000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ local-timer@48240600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ clocks = <&mpu_periphclk>;
+ reg = <0x48240600 0x20>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-parent = <&gic>;
+ };
+
+ wakeupgen: interrupt-controller@48281000 {
+ compatible = "ti,omap4-wugen-mpu";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x48281000 0x1000>;
+ interrupt-parent = <&gic>;
+ };
+
+ /*
+ * The soc node represents the soc top level view. It is used for IPs
+ * that are not memory mapped in the MPU view or for the MPU itself.
+ */
+ soc {
+ compatible = "ti,omap-infra";
+ mpu {
+ compatible = "ti,omap4-mpu";
+ ti,hwmods = "mpu";
+ sram = <&ocmcram>;
+ };
+
+ dsp {
+ compatible = "ti,omap3-c64";
+ ti,hwmods = "dsp";
+ };
+
+ iva {
+ compatible = "ti,ivahd";
+ ti,hwmods = "iva";
+ };
+ };
+
+ /*
+ * XXX: Use a flat representation of the OMAP4 interconnect.
+ * The real OMAP interconnect network is quite complex.
+ * Since it will not bring real advantage to represent that in DT for
+ * the moment, just use a fake OCP bus entry to represent the whole bus
+ * hierarchy.
+ */
+ ocp {
+ compatible = "ti,omap4-l3-noc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3";
+ reg = <0x44000000 0x1000>,
+ <0x44800000 0x2000>,
+ <0x45000000 0x1000>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+
+ l4_cfg: l4@4a000000 {
+ compatible = "ti,omap4-l4-cfg", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x4a000000 0x1000000>;
+
+ cm1: cm1@4000 {
+ compatible = "ti,omap4-cm1";
+ reg = <0x4000 0x2000>;
+
+ cm1_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cm1_clockdomains: clockdomains {
+ };
+ };
+
+ cm2: cm2@8000 {
+ compatible = "ti,omap4-cm2";
+ reg = <0x8000 0x3000>;
+
+ cm2_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cm2_clockdomains: clockdomains {
+ };
+ };
+
+ omap4_scm_core: scm@2000 {
+ compatible = "ti,omap4-scm-core", "simple-bus";
+ reg = <0x2000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x2000 0x1000>;
+
+ scm_conf: scm_conf@0 {
+ compatible = "syscon";
+ reg = <0x0 0x800>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
+
+ omap4_padconf_core: scm@100000 {
+ compatible = "ti,omap4-scm-padconf-core",
+ "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x100000 0x1000>;
+
+ omap4_pmx_core: pinmux@40 {
+ compatible = "ti,omap4-padconf",
+ "pinctrl-single";
+ reg = <0x40 0x0196>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ pinctrl-single,register-width = <16>;
+ pinctrl-single,function-mask = <0x7fff>;
+ };
+
+ omap4_padconf_global: omap4_padconf_global@5a0 {
+ compatible = "syscon";
+ reg = <0x5a0 0x170>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ pbias_regulator: pbias_regulator {
+ compatible = "ti,pbias-omap";
+ reg = <0x60 0x4>;
+ syscon = <&omap4_padconf_global>;
+ pbias_mmc_reg: pbias_mmc_omap4 {
+ regulator-name = "pbias_mmc_omap4";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ };
+ };
+ };
+ };
+
+ l4_wkup: l4@300000 {
+ compatible = "ti,omap4-l4-wkup", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x300000 0x40000>;
+
+ counter32k: counter@4000 {
+ compatible = "ti,omap-counter32k";
+ reg = <0x4000 0x20>;
+ ti,hwmods = "counter_32k";
+ };
+
+ prm: prm@6000 {
+ compatible = "ti,omap4-prm";
+ reg = <0x6000 0x3000>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+
+ prm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ prm_clockdomains: clockdomains {
+ };
+ };
+
+ scrm: scrm@a000 {
+ compatible = "ti,omap4-scrm";
+ reg = <0xa000 0x2000>;
+
+ scrm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ scrm_clockdomains: clockdomains {
+ };
+ };
+
+ omap4_pmx_wkup: pinmux@1e040 {
+ compatible = "ti,omap4-padconf",
+ "pinctrl-single";
+ reg = <0x1e040 0x0038>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ pinctrl-single,register-width = <16>;
+ pinctrl-single,function-mask = <0x7fff>;
+ };
+ };
+ };
+
+ ocmcram: ocmcram@40304000 {
+ compatible = "mmio-sram";
+ reg = <0x40304000 0xa000>; /* 40k */
+ };
+
+ sdma: dma-controller@4a056000 {
+ compatible = "ti,omap4430-sdma";
+ reg = <0x4a056000 0x1000>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ dma-channels = <32>;
+ dma-requests = <127>;
+ };
+
+ gpio1: gpio@4a310000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x4a310000 0x200>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio1";
+ ti,gpio-always-on;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@48055000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x48055000 0x200>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio2";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@48057000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x48057000 0x200>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio3";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@48059000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x48059000 0x200>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio4";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio5: gpio@4805b000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x4805b000 0x200>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio5";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio6: gpio@4805d000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x4805d000 0x200>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio6";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpmc: gpmc@50000000 {
+ compatible = "ti,omap4430-gpmc";
+ reg = <0x50000000 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ gpmc,num-cs = <8>;
+ gpmc,num-waitpins = <4>;
+ ti,hwmods = "gpmc";
+ ti,no-idle-on-init;
+ clocks = <&l3_div_ck>;
+ clock-names = "fck";
+ };
+
+ uart1: serial@4806a000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x4806a000 0x100>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart1";
+ clock-frequency = <48000000>;
+ };
+
+ uart2: serial@4806c000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x4806c000 0x100>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart2";
+ clock-frequency = <48000000>;
+ };
+
+ uart3: serial@48020000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x48020000 0x100>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart3";
+ clock-frequency = <48000000>;
+ };
+
+ uart4: serial@4806e000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x4806e000 0x100>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart4";
+ clock-frequency = <48000000>;
+ };
+
+ hwspinlock: spinlock@4a0f6000 {
+ compatible = "ti,omap4-hwspinlock";
+ reg = <0x4a0f6000 0x1000>;
+ ti,hwmods = "spinlock";
+ #hwlock-cells = <1>;
+ };
+
+ i2c1: i2c@48070000 {
+ compatible = "ti,omap4-i2c";
+ reg = <0x48070000 0x100>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c1";
+ };
+
+ i2c2: i2c@48072000 {
+ compatible = "ti,omap4-i2c";
+ reg = <0x48072000 0x100>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c2";
+ };
+
+ i2c3: i2c@48060000 {
+ compatible = "ti,omap4-i2c";
+ reg = <0x48060000 0x100>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c3";
+ };
+
+ i2c4: i2c@48350000 {
+ compatible = "ti,omap4-i2c";
+ reg = <0x48350000 0x100>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c4";
+ };
+
+ mcspi1: spi@48098000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x48098000 0x200>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi1";
+ ti,spi-num-cs = <4>;
+ dmas = <&sdma 35>,
+ <&sdma 36>,
+ <&sdma 37>,
+ <&sdma 38>,
+ <&sdma 39>,
+ <&sdma 40>,
+ <&sdma 41>,
+ <&sdma 42>;
+ dma-names = "tx0", "rx0", "tx1", "rx1",
+ "tx2", "rx2", "tx3", "rx3";
+ };
+
+ mcspi2: spi@4809a000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x4809a000 0x200>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi2";
+ ti,spi-num-cs = <2>;
+ dmas = <&sdma 43>,
+ <&sdma 44>,
+ <&sdma 45>,
+ <&sdma 46>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
+ };
+
+ mcspi3: spi@480b8000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x480b8000 0x200>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi3";
+ ti,spi-num-cs = <2>;
+ dmas = <&sdma 15>, <&sdma 16>;
+ dma-names = "tx0", "rx0";
+ };
+
+ mcspi4: spi@480ba000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x480ba000 0x200>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi4";
+ ti,spi-num-cs = <1>;
+ dmas = <&sdma 70>, <&sdma 71>;
+ dma-names = "tx0", "rx0";
+ };
+
+ mmc1: mmc@4809c000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x4809c000 0x400>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmc1";
+ ti,dual-volt;
+ ti,needs-special-reset;
+ dmas = <&sdma 61>, <&sdma 62>;
+ dma-names = "tx", "rx";
+ pbias-supply = <&pbias_mmc_reg>;
+ };
+
+ mmc2: mmc@480b4000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x480b4000 0x400>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmc2";
+ ti,needs-special-reset;
+ dmas = <&sdma 47>, <&sdma 48>;
+ dma-names = "tx", "rx";
+ };
+
+ mmc3: mmc@480ad000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x480ad000 0x400>;
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmc3";
+ ti,needs-special-reset;
+ dmas = <&sdma 77>, <&sdma 78>;
+ dma-names = "tx", "rx";
+ };
+
+ mmc4: mmc@480d1000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x480d1000 0x400>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmc4";
+ ti,needs-special-reset;
+ dmas = <&sdma 57>, <&sdma 58>;
+ dma-names = "tx", "rx";
+ };
+
+ mmc5: mmc@480d5000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x480d5000 0x400>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmc5";
+ ti,needs-special-reset;
+ dmas = <&sdma 59>, <&sdma 60>;
+ dma-names = "tx", "rx";
+ };
+
+ mmu_dsp: mmu@4a066000 {
+ compatible = "ti,omap4-iommu";
+ reg = <0x4a066000 0x100>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmu_dsp";
+ };
+
+ mmu_ipu: mmu@55082000 {
+ compatible = "ti,omap4-iommu";
+ reg = <0x55082000 0x100>;
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmu_ipu";
+ ti,iommu-bus-err-back;
+ };
+
+ wdt2: wdt@4a314000 {
+ compatible = "ti,omap4-wdt", "ti,omap3-wdt";
+ reg = <0x4a314000 0x80>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "wd_timer2";
+ };
+
+ mcpdm: mcpdm@40132000 {
+ compatible = "ti,omap4-mcpdm";
+ reg = <0x40132000 0x7f>, /* MPU private access */
+ <0x49032000 0x7f>; /* L3 Interconnect */
+ reg-names = "mpu", "dma";
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mcpdm";
+ dmas = <&sdma 65>,
+ <&sdma 66>;
+ dma-names = "up_link", "dn_link";
+ status = "disabled";
+ };
+
+ dmic: dmic@4012e000 {
+ compatible = "ti,omap4-dmic";
+ reg = <0x4012e000 0x7f>, /* MPU private access */
+ <0x4902e000 0x7f>; /* L3 Interconnect */
+ reg-names = "mpu", "dma";
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "dmic";
+ dmas = <&sdma 67>;
+ dma-names = "up_link";
+ status = "disabled";
+ };
+
+ mcbsp1: mcbsp@40122000 {
+ compatible = "ti,omap4-mcbsp";
+ reg = <0x40122000 0xff>, /* MPU private access */
+ <0x49022000 0xff>; /* L3 Interconnect */
+ reg-names = "mpu", "dma";
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "common";
+ ti,buffer-size = <128>;
+ ti,hwmods = "mcbsp1";
+ dmas = <&sdma 33>,
+ <&sdma 34>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mcbsp2: mcbsp@40124000 {
+ compatible = "ti,omap4-mcbsp";
+ reg = <0x40124000 0xff>, /* MPU private access */
+ <0x49024000 0xff>; /* L3 Interconnect */
+ reg-names = "mpu", "dma";
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "common";
+ ti,buffer-size = <128>;
+ ti,hwmods = "mcbsp2";
+ dmas = <&sdma 17>,
+ <&sdma 18>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mcbsp3: mcbsp@40126000 {
+ compatible = "ti,omap4-mcbsp";
+ reg = <0x40126000 0xff>, /* MPU private access */
+ <0x49026000 0xff>; /* L3 Interconnect */
+ reg-names = "mpu", "dma";
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "common";
+ ti,buffer-size = <128>;
+ ti,hwmods = "mcbsp3";
+ dmas = <&sdma 19>,
+ <&sdma 20>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mcbsp4: mcbsp@48096000 {
+ compatible = "ti,omap4-mcbsp";
+ reg = <0x48096000 0xff>; /* L4 Interconnect */
+ reg-names = "mpu";
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "common";
+ ti,buffer-size = <128>;
+ ti,hwmods = "mcbsp4";
+ dmas = <&sdma 31>,
+ <&sdma 32>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ keypad: keypad@4a31c000 {
+ compatible = "ti,omap4-keypad";
+ reg = <0x4a31c000 0x80>;
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ reg-names = "mpu";
+ ti,hwmods = "kbd";
+ };
+
+ dmm@4e000000 {
+ compatible = "ti,omap4-dmm";
+ reg = <0x4e000000 0x800>;
+ interrupts = <0 113 0x4>;
+ ti,hwmods = "dmm";
+ };
+
+ emif1: emif@4c000000 {
+ compatible = "ti,emif-4d";
+ reg = <0x4c000000 0x100>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "emif1";
+ ti,no-idle-on-init;
+ phy-type = <1>;
+ hw-caps-read-idle-ctrl;
+ hw-caps-ll-interface;
+ hw-caps-temp-alert;
+ };
+
+ emif2: emif@4d000000 {
+ compatible = "ti,emif-4d";
+ reg = <0x4d000000 0x100>;
+ interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "emif2";
+ ti,no-idle-on-init;
+ phy-type = <1>;
+ hw-caps-read-idle-ctrl;
+ hw-caps-ll-interface;
+ hw-caps-temp-alert;
+ };
+
+ ocp2scp@4a0ad000 {
+ compatible = "ti,omap-ocp2scp";
+ reg = <0x4a0ad000 0x1f>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "ocp2scp_usb_phy";
+ usb2_phy: usb2phy@4a0ad080 {
+ compatible = "ti,omap-usb2";
+ reg = <0x4a0ad080 0x58>;
+ ctrl-module = <&omap_control_usb2phy>;
+ clocks = <&usb_phy_cm_clk32k>;
+ clock-names = "wkupclk";
+ #phy-cells = <0>;
+ };
+ };
+
+ mailbox: mailbox@4a0f4000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x4a0f4000 0x200>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mailbox";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <3>;
+ ti,mbox-num-fifos = <8>;
+ mbox_ipu: mbox_ipu {
+ ti,mbox-tx = <0 0 0>;
+ ti,mbox-rx = <1 0 0>;
+ };
+ mbox_dsp: mbox_dsp {
+ ti,mbox-tx = <3 0 0>;
+ ti,mbox-rx = <2 0 0>;
+ };
+ };
+
+ timer1: timer@4a318000 {
+ compatible = "ti,omap3430-timer";
+ reg = <0x4a318000 0x80>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer1";
+ ti,timer-alwon;
+ };
+
+ timer2: timer@48032000 {
+ compatible = "ti,omap3430-timer";
+ reg = <0x48032000 0x80>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer2";
+ };
+
+ timer3: timer@48034000 {
+ compatible = "ti,omap4430-timer";
+ reg = <0x48034000 0x80>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer3";
+ };
+
+ timer4: timer@48036000 {
+ compatible = "ti,omap4430-timer";
+ reg = <0x48036000 0x80>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer4";
+ };
+
+ timer5: timer@40138000 {
+ compatible = "ti,omap4430-timer";
+ reg = <0x40138000 0x80>,
+ <0x49038000 0x80>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer5";
+ ti,timer-dsp;
+ };
+
+ timer6: timer@4013a000 {
+ compatible = "ti,omap4430-timer";
+ reg = <0x4013a000 0x80>,
+ <0x4903a000 0x80>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer6";
+ ti,timer-dsp;
+ };
+
+ timer7: timer@4013c000 {
+ compatible = "ti,omap4430-timer";
+ reg = <0x4013c000 0x80>,
+ <0x4903c000 0x80>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer7";
+ ti,timer-dsp;
+ };
+
+ timer8: timer@4013e000 {
+ compatible = "ti,omap4430-timer";
+ reg = <0x4013e000 0x80>,
+ <0x4903e000 0x80>;
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer8";
+ ti,timer-pwm;
+ ti,timer-dsp;
+ };
+
+ timer9: timer@4803e000 {
+ compatible = "ti,omap4430-timer";
+ reg = <0x4803e000 0x80>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer9";
+ ti,timer-pwm;
+ };
+
+ timer10: timer@48086000 {
+ compatible = "ti,omap3430-timer";
+ reg = <0x48086000 0x80>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer10";
+ ti,timer-pwm;
+ };
+
+ timer11: timer@48088000 {
+ compatible = "ti,omap4430-timer";
+ reg = <0x48088000 0x80>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer11";
+ ti,timer-pwm;
+ };
+
+ usbhstll: usbhstll@4a062000 {
+ compatible = "ti,usbhs-tll";
+ reg = <0x4a062000 0x1000>;
+ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "usb_tll_hs";
+ };
+
+ usbhshost: usbhshost@4a064000 {
+ compatible = "ti,usbhs-host";
+ reg = <0x4a064000 0x800>;
+ ti,hwmods = "usb_host_hs";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ clocks = <&init_60m_fclk>,
+ <&xclk60mhsp1_ck>,
+ <&xclk60mhsp2_ck>;
+ clock-names = "refclk_60m_int",
+ "refclk_60m_ext_p1",
+ "refclk_60m_ext_p2";
+
+ usbhsohci: ohci@4a064800 {
+ compatible = "ti,ohci-omap3";
+ reg = <0x4a064800 0x400>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ usbhsehci: ehci@4a064c00 {
+ compatible = "ti,ehci-omap";
+ reg = <0x4a064c00 0x400>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ omap_control_usb2phy: control-phy@4a002300 {
+ compatible = "ti,control-phy-usb2";
+ reg = <0x4a002300 0x4>;
+ reg-names = "power";
+ };
+
+ omap_control_usbotg: control-phy@4a00233c {
+ compatible = "ti,control-phy-otghs";
+ reg = <0x4a00233c 0x4>;
+ reg-names = "otghs_control";
+ };
+
+ usb_otg_hs: usb_otg_hs@4a0ab000 {
+ compatible = "ti,omap4-musb";
+ reg = <0x4a0ab000 0x7ff>;
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "mc", "dma";
+ ti,hwmods = "usb_otg_hs";
+ usb-phy = <&usb2_phy>;
+ phys = <&usb2_phy>;
+ phy-names = "usb2-phy";
+ multipoint = <1>;
+ num-eps = <16>;
+ ram-bits = <12>;
+ ctrl-module = <&omap_control_usbotg>;
+ };
+
+ aes: aes@4b501000 {
+ compatible = "ti,omap4-aes";
+ ti,hwmods = "aes";
+ reg = <0x4b501000 0xa0>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 111>, <&sdma 110>;
+ dma-names = "tx", "rx";
+ };
+
+ des: des@480a5000 {
+ compatible = "ti,omap4-des";
+ ti,hwmods = "des";
+ reg = <0x480a5000 0xa0>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 117>, <&sdma 116>;
+ dma-names = "tx", "rx";
+ };
+
+ abb_mpu: regulator-abb-mpu {
+ compatible = "ti,abb-v2";
+ regulator-name = "abb_mpu";
+ #address-cells = <0>;
+ #size-cells = <0>;
+ ti,tranxdone-status-mask = <0x80>;
+ clocks = <&sys_clkin_ck>;
+ ti,settling-time = <50>;
+ ti,clock-cycles = <16>;
+
+ status = "disabled";
+ };
+
+ abb_iva: regulator-abb-iva {
+ compatible = "ti,abb-v2";
+ regulator-name = "abb_iva";
+ #address-cells = <0>;
+ #size-cells = <0>;
+ ti,tranxdone-status-mask = <0x80000000>;
+ clocks = <&sys_clkin_ck>;
+ ti,settling-time = <50>;
+ ti,clock-cycles = <16>;
+
+ status = "disabled";
+ };
+
+ dss: dss@58000000 {
+ compatible = "ti,omap4-dss";
+ reg = <0x58000000 0x80>;
+ status = "disabled";
+ ti,hwmods = "dss_core";
+ clocks = <&dss_dss_clk>;
+ clock-names = "fck";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dispc@58001000 {
+ compatible = "ti,omap4-dispc";
+ reg = <0x58001000 0x1000>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "dss_dispc";
+ clocks = <&dss_dss_clk>;
+ clock-names = "fck";
+ };
+
+ rfbi: encoder@58002000 {
+ compatible = "ti,omap4-rfbi";
+ reg = <0x58002000 0x1000>;
+ status = "disabled";
+ ti,hwmods = "dss_rfbi";
+ clocks = <&dss_dss_clk>, <&l3_div_ck>;
+ clock-names = "fck", "ick";
+ };
+
+ venc: encoder@58003000 {
+ compatible = "ti,omap4-venc";
+ reg = <0x58003000 0x1000>;
+ status = "disabled";
+ ti,hwmods = "dss_venc";
+ clocks = <&dss_tv_clk>;
+ clock-names = "fck";
+ };
+
+ dsi1: encoder@58004000 {
+ compatible = "ti,omap4-dsi";
+ reg = <0x58004000 0x200>,
+ <0x58004200 0x40>,
+ <0x58004300 0x20>;
+ reg-names = "proto", "phy", "pll";
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ ti,hwmods = "dss_dsi1";
+ clocks = <&dss_dss_clk>, <&dss_sys_clk>;
+ clock-names = "fck", "sys_clk";
+ };
+
+ dsi2: encoder@58005000 {
+ compatible = "ti,omap4-dsi";
+ reg = <0x58005000 0x200>,
+ <0x58005200 0x40>,
+ <0x58005300 0x20>;
+ reg-names = "proto", "phy", "pll";
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ ti,hwmods = "dss_dsi2";
+ clocks = <&dss_dss_clk>, <&dss_sys_clk>;
+ clock-names = "fck", "sys_clk";
+ };
+
+ hdmi: encoder@58006000 {
+ compatible = "ti,omap4-hdmi";
+ reg = <0x58006000 0x200>,
+ <0x58006200 0x100>,
+ <0x58006300 0x100>,
+ <0x58006400 0x1000>;
+ reg-names = "wp", "pll", "phy", "core";
+ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ ti,hwmods = "dss_hdmi";
+ clocks = <&dss_48mhz_clk>, <&dss_sys_clk>;
+ clock-names = "fck", "sys_clk";
+ dmas = <&sdma 76>;
+ dma-names = "audio_tx";
+ };
+ };
+ };
+};
+
+/include/ "omap44xx-clocks.dtsi"
diff --git a/arch/arm/boot/dts/omap443x-clocks.dtsi b/arch/arm/boot/dts/omap443x-clocks.dtsi
new file mode 100644
index 000000000..2bd2166f8
--- /dev/null
+++ b/arch/arm/boot/dts/omap443x-clocks.dtsi
@@ -0,0 +1,18 @@
+/*
+ * Device Tree Source for OMAP4 clock data
+ *
+ * Copyright (C) 2013 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.
+ */
+&prm_clocks {
+ bandgap_fclk: bandgap_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1888>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap443x.dtsi b/arch/arm/boot/dts/omap443x.dtsi
new file mode 100644
index 000000000..0adfa1d1e
--- /dev/null
+++ b/arch/arm/boot/dts/omap443x.dtsi
@@ -0,0 +1,74 @@
+/*
+ * Device Tree Source for OMAP443x SoC
+ *
+ * Copyright (C) 2013 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 "omap4.dtsi"
+
+/ {
+ cpus {
+ cpu0: cpu@0 {
+ /* OMAP443x variants OPP50-OPPNT */
+ operating-points = <
+ /* kHz uV */
+ 300000 1025000
+ 600000 1200000
+ 800000 1313000
+ 1008000 1375000
+ >;
+ clock-latency = <300000>; /* From legacy driver */
+
+ /* cooling options */
+ cooling-min-level = <0>;
+ cooling-max-level = <3>;
+ #cooling-cells = <2>; /* min followed by max */
+ };
+ };
+
+ thermal-zones {
+ #include "omap4-cpu-thermal.dtsi"
+ };
+
+ ocp {
+ bandgap: bandgap {
+ reg = <0x4a002260 0x4
+ 0x4a00232C 0x4>;
+ compatible = "ti,omap4430-bandgap";
+
+ #thermal-sensor-cells = <0>;
+ };
+ };
+
+ ocp {
+ abb_mpu: regulator-abb-mpu {
+ status = "okay";
+
+ reg = <0x4a307bd0 0x8>, <0x4a306014 0x4>;
+ reg-names = "base-address", "int-address";
+
+ ti,abb_info = <
+ /*uV ABB efuse rbb_m fbb_m vset_m*/
+ 1025000 0 0 0 0 0
+ 1200000 0 0 0 0 0
+ 1313000 0 0 0 0 0
+ 1375000 1 0 0 0 0
+ 1389000 1 0 0 0 0
+ >;
+ };
+
+ /* Default unused, just provide register info for record */
+ abb_iva: regulator-abb-iva {
+ reg = <0x4a307bd8 0x8>, <0x4a306010 0x4>;
+ reg-names = "base-address", "int-address";
+ };
+
+ };
+
+};
+
+/include/ "omap443x-clocks.dtsi"
diff --git a/arch/arm/boot/dts/omap4460.dtsi b/arch/arm/boot/dts/omap4460.dtsi
new file mode 100644
index 000000000..194f9ef0a
--- /dev/null
+++ b/arch/arm/boot/dts/omap4460.dtsi
@@ -0,0 +1,93 @@
+/*
+ * Device Tree Source for OMAP4460 SoC
+ *
+ * Copyright (C) 2012 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 "omap4.dtsi"
+
+/ {
+ cpus {
+ /* OMAP446x 'standard device' variants OPP50 to OPPTurbo */
+ cpu0: cpu@0 {
+ operating-points = <
+ /* kHz uV */
+ 350000 1025000
+ 700000 1200000
+ 920000 1313000
+ >;
+ clock-latency = <300000>; /* From legacy driver */
+
+ /* cooling options */
+ cooling-min-level = <0>;
+ cooling-max-level = <2>;
+ #cooling-cells = <2>; /* min followed by max */
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "debugss";
+ };
+
+ thermal-zones {
+ #include "omap4-cpu-thermal.dtsi"
+ };
+
+ ocp {
+ bandgap: bandgap {
+ reg = <0x4a002260 0x4
+ 0x4a00232C 0x4
+ 0x4a002378 0x18>;
+ compatible = "ti,omap4460-bandgap";
+ interrupts = <0 126 IRQ_TYPE_LEVEL_HIGH>; /* talert */
+ gpios = <&gpio3 22 0>; /* tshut */
+
+ #thermal-sensor-cells = <0>;
+ };
+
+ abb_mpu: regulator-abb-mpu {
+ status = "okay";
+
+ reg = <0x4a307bd0 0x8>, <0x4a306014 0x4>,
+ <0x4A002268 0x4>;
+ reg-names = "base-address", "int-address",
+ "efuse-address";
+
+ ti,abb_info = <
+ /*uV ABB efuse rbb_m fbb_m vset_m*/
+ 1025000 0 0 0 0 0
+ 1200000 0 0 0 0 0
+ 1313000 0 0 0x100000 0x40000 0
+ 1375000 1 0 0 0 0
+ 1389000 1 0 0 0 0
+ >;
+ };
+
+ abb_iva: regulator-abb-iva {
+ status = "okay";
+
+ reg = <0x4a307bd8 0x8>, <0x4a306010 0x4>,
+ <0x4A002268 0x4>;
+ reg-names = "base-address", "int-address",
+ "efuse-address";
+
+ ti,abb_info = <
+ /*uV ABB efuse rbb_m fbb_m vset_m*/
+ 950000 0 0 0 0 0
+ 1140000 0 0 0 0 0
+ 1291000 0 0 0x200000 0 0
+ 1375000 1 0 0 0 0
+ 1376000 1 0 0 0 0
+ >;
+ };
+ };
+
+};
+
+/include/ "omap446x-clocks.dtsi"
diff --git a/arch/arm/boot/dts/omap446x-clocks.dtsi b/arch/arm/boot/dts/omap446x-clocks.dtsi
new file mode 100644
index 000000000..be033e980
--- /dev/null
+++ b/arch/arm/boot/dts/omap446x-clocks.dtsi
@@ -0,0 +1,27 @@
+/*
+ * Device Tree Source for OMAP4 clock data
+ *
+ * Copyright (C) 2013 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.
+ */
+&prm_clocks {
+ div_ts_ck: div_ts_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&l4_wkup_clk_mux_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1888>;
+ ti,dividers = <8>, <16>, <32>;
+ };
+
+ bandgap_ts_fclk: bandgap_ts_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&div_ts_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1888>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap44xx-clocks.dtsi b/arch/arm/boot/dts/omap44xx-clocks.dtsi
new file mode 100644
index 000000000..f2c48f098
--- /dev/null
+++ b/arch/arm/boot/dts/omap44xx-clocks.dtsi
@@ -0,0 +1,1643 @@
+/*
+ * Device Tree Source for OMAP4 clock data
+ *
+ * Copyright (C) 2013 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.
+ */
+&cm1_clocks {
+ extalt_clkin_ck: extalt_clkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <59000000>;
+ };
+
+ pad_clks_src_ck: pad_clks_src_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ pad_clks_ck: pad_clks_ck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&pad_clks_src_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0108>;
+ };
+
+ pad_slimbus_core_clks_ck: pad_slimbus_core_clks_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ secure_32k_clk_src_ck: secure_32k_clk_src_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ slimbus_src_clk: slimbus_src_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ slimbus_clk: slimbus_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&slimbus_src_clk>;
+ ti,bit-shift = <10>;
+ reg = <0x0108>;
+ };
+
+ sys_32k_ck: sys_32k_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ virt_12000000_ck: virt_12000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ virt_13000000_ck: virt_13000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ };
+
+ virt_16800000_ck: virt_16800000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <16800000>;
+ };
+
+ virt_19200000_ck: virt_19200000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <19200000>;
+ };
+
+ virt_26000000_ck: virt_26000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ };
+
+ virt_27000000_ck: virt_27000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <27000000>;
+ };
+
+ virt_38400000_ck: virt_38400000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <38400000>;
+ };
+
+ tie_low_clock_ck: tie_low_clock_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ utmi_phy_clkout_ck: utmi_phy_clkout_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <60000000>;
+ };
+
+ xclk60mhsp1_ck: xclk60mhsp1_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <60000000>;
+ };
+
+ xclk60mhsp2_ck: xclk60mhsp2_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <60000000>;
+ };
+
+ xclk60motg_ck: xclk60motg_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <60000000>;
+ };
+
+ dpll_abe_ck: dpll_abe_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-m4xen-clock";
+ clocks = <&abe_dpll_refclk_mux_ck>, <&abe_dpll_bypass_clk_mux_ck>;
+ reg = <0x01e0>, <0x01e4>, <0x01ec>, <0x01e8>;
+ };
+
+ dpll_abe_x2_ck: dpll_abe_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-x2-clock";
+ clocks = <&dpll_abe_ck>;
+ reg = <0x01f0>;
+ };
+
+ dpll_abe_m2x2_ck: dpll_abe_m2x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_abe_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x01f0>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ abe_24m_fclk: abe_24m_fclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_abe_m2x2_ck>;
+ clock-mult = <1>;
+ clock-div = <8>;
+ };
+
+ abe_clk: abe_clk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_abe_m2x2_ck>;
+ ti,max-div = <4>;
+ reg = <0x0108>;
+ ti,index-power-of-two;
+ };
+
+ aess_fclk: aess_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&abe_clk>;
+ ti,bit-shift = <24>;
+ ti,max-div = <2>;
+ reg = <0x0528>;
+ };
+
+ dpll_abe_m3x2_ck: dpll_abe_m3x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_abe_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x01f4>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ core_hsd_byp_clk_mux_ck: core_hsd_byp_clk_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&dpll_abe_m3x2_ck>;
+ ti,bit-shift = <23>;
+ reg = <0x012c>;
+ };
+
+ dpll_core_ck: dpll_core_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-core-clock";
+ clocks = <&sys_clkin_ck>, <&core_hsd_byp_clk_mux_ck>;
+ reg = <0x0120>, <0x0124>, <0x012c>, <0x0128>;
+ };
+
+ dpll_core_x2_ck: dpll_core_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-x2-clock";
+ clocks = <&dpll_core_ck>;
+ };
+
+ dpll_core_m6x2_ck: dpll_core_m6x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0140>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_core_m2_ck: dpll_core_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0130>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ ddrphy_ck: ddrphy_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ dpll_core_m5x2_ck: dpll_core_m5x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x013c>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ div_core_ck: div_core_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_m5x2_ck>;
+ reg = <0x0100>;
+ ti,max-div = <2>;
+ };
+
+ div_iva_hs_clk: div_iva_hs_clk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_m5x2_ck>;
+ ti,max-div = <4>;
+ reg = <0x01dc>;
+ ti,index-power-of-two;
+ };
+
+ div_mpu_hs_clk: div_mpu_hs_clk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_m5x2_ck>;
+ ti,max-div = <4>;
+ reg = <0x019c>;
+ ti,index-power-of-two;
+ };
+
+ dpll_core_m4x2_ck: dpll_core_m4x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0138>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dll_clk_div_ck: dll_clk_div_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_m4x2_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ dpll_abe_m2_ck: dpll_abe_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_abe_ck>;
+ ti,max-div = <31>;
+ reg = <0x01f0>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_core_m3x2_gate_ck: dpll_core_m3x2_gate_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0134>;
+ };
+
+ dpll_core_m3x2_div_ck: dpll_core_m3x2_div_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <31>;
+ reg = <0x0134>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_core_m3x2_ck: dpll_core_m3x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&dpll_core_m3x2_gate_ck>, <&dpll_core_m3x2_div_ck>;
+ };
+
+ dpll_core_m7x2_ck: dpll_core_m7x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0144>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ iva_hsd_byp_clk_mux_ck: iva_hsd_byp_clk_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&div_iva_hs_clk>;
+ ti,bit-shift = <23>;
+ reg = <0x01ac>;
+ };
+
+ dpll_iva_ck: dpll_iva_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-clock";
+ clocks = <&sys_clkin_ck>, <&iva_hsd_byp_clk_mux_ck>;
+ reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>;
+ };
+
+ dpll_iva_x2_ck: dpll_iva_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-x2-clock";
+ clocks = <&dpll_iva_ck>;
+ };
+
+ dpll_iva_m4x2_ck: dpll_iva_m4x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_iva_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x01b8>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_iva_m5x2_ck: dpll_iva_m5x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_iva_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x01bc>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_mpu_ck: dpll_mpu_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-clock";
+ clocks = <&sys_clkin_ck>, <&div_mpu_hs_clk>;
+ reg = <0x0160>, <0x0164>, <0x016c>, <0x0168>;
+ };
+
+ dpll_mpu_m2_ck: dpll_mpu_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_mpu_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0170>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ per_hs_clk_div_ck: per_hs_clk_div_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_abe_m3x2_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ usb_hs_clk_div_ck: usb_hs_clk_div_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_abe_m3x2_ck>;
+ clock-mult = <1>;
+ clock-div = <3>;
+ };
+
+ l3_div_ck: l3_div_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&div_core_ck>;
+ ti,bit-shift = <4>;
+ ti,max-div = <2>;
+ reg = <0x0100>;
+ };
+
+ l4_div_ck: l4_div_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&l3_div_ck>;
+ ti,bit-shift = <8>;
+ ti,max-div = <2>;
+ reg = <0x0100>;
+ };
+
+ lp_clk_div_ck: lp_clk_div_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_abe_m2x2_ck>;
+ clock-mult = <1>;
+ clock-div = <16>;
+ };
+
+ mpu_periphclk: mpu_periphclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_mpu_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ ocp_abe_iclk: ocp_abe_iclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&aess_fclk>;
+ ti,bit-shift = <24>;
+ reg = <0x0528>;
+ ti,dividers = <2>, <1>;
+ };
+
+ per_abe_24m_fclk: per_abe_24m_fclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_abe_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ dmic_sync_mux_ck: dmic_sync_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&syc_clk_div_ck>, <&func_24m_clk>;
+ ti,bit-shift = <25>;
+ reg = <0x0538>;
+ };
+
+ func_dmic_abe_gfclk: func_dmic_abe_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dmic_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x0538>;
+ };
+
+ mcasp_sync_mux_ck: mcasp_sync_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&syc_clk_div_ck>, <&func_24m_clk>;
+ ti,bit-shift = <25>;
+ reg = <0x0540>;
+ };
+
+ func_mcasp_abe_gfclk: func_mcasp_abe_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&mcasp_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x0540>;
+ };
+
+ mcbsp1_sync_mux_ck: mcbsp1_sync_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&syc_clk_div_ck>, <&func_24m_clk>;
+ ti,bit-shift = <25>;
+ reg = <0x0548>;
+ };
+
+ func_mcbsp1_gfclk: func_mcbsp1_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&mcbsp1_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x0548>;
+ };
+
+ mcbsp2_sync_mux_ck: mcbsp2_sync_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&syc_clk_div_ck>, <&func_24m_clk>;
+ ti,bit-shift = <25>;
+ reg = <0x0550>;
+ };
+
+ func_mcbsp2_gfclk: func_mcbsp2_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&mcbsp2_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x0550>;
+ };
+
+ mcbsp3_sync_mux_ck: mcbsp3_sync_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&syc_clk_div_ck>, <&func_24m_clk>;
+ ti,bit-shift = <25>;
+ reg = <0x0558>;
+ };
+
+ func_mcbsp3_gfclk: func_mcbsp3_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&mcbsp3_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x0558>;
+ };
+
+ slimbus1_fclk_1: slimbus1_fclk_1 {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&func_24m_clk>;
+ ti,bit-shift = <9>;
+ reg = <0x0560>;
+ };
+
+ slimbus1_fclk_0: slimbus1_fclk_0 {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&abe_24m_fclk>;
+ ti,bit-shift = <8>;
+ reg = <0x0560>;
+ };
+
+ slimbus1_fclk_2: slimbus1_fclk_2 {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&pad_clks_ck>;
+ ti,bit-shift = <10>;
+ reg = <0x0560>;
+ };
+
+ slimbus1_slimbus_clk: slimbus1_slimbus_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&slimbus_clk>;
+ ti,bit-shift = <11>;
+ reg = <0x0560>;
+ };
+
+ timer5_sync_mux: timer5_sync_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&syc_clk_div_ck>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x0568>;
+ };
+
+ timer6_sync_mux: timer6_sync_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&syc_clk_div_ck>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x0570>;
+ };
+
+ timer7_sync_mux: timer7_sync_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&syc_clk_div_ck>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x0578>;
+ };
+
+ timer8_sync_mux: timer8_sync_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&syc_clk_div_ck>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x0580>;
+ };
+
+ dummy_ck: dummy_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+};
+&prm_clocks {
+ sys_clkin_ck: sys_clkin_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&virt_12000000_ck>, <&virt_13000000_ck>, <&virt_16800000_ck>, <&virt_19200000_ck>, <&virt_26000000_ck>, <&virt_27000000_ck>, <&virt_38400000_ck>;
+ reg = <0x0110>;
+ ti,index-starts-at-one;
+ };
+
+ abe_dpll_bypass_clk_mux_ck: abe_dpll_bypass_clk_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x0108>;
+ };
+
+ abe_dpll_refclk_mux_ck: abe_dpll_refclk_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>;
+ reg = <0x010c>;
+ };
+
+ dbgclk_mux_ck: dbgclk_mux_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ l4_wkup_clk_mux_ck: l4_wkup_clk_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&lp_clk_div_ck>;
+ reg = <0x0108>;
+ };
+
+ syc_clk_div_ck: syc_clk_div_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&sys_clkin_ck>;
+ reg = <0x0100>;
+ ti,max-div = <2>;
+ };
+
+ gpio1_dbclk: gpio1_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1838>;
+ };
+
+ dmt1_clk_mux: dmt1_clk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1840>;
+ };
+
+ usim_ck: usim_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_m4x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1858>;
+ ti,dividers = <14>, <18>;
+ };
+
+ usim_fclk: usim_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&usim_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1858>;
+ };
+
+ pmd_stm_clock_mux_ck: pmd_stm_clock_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&dpll_core_m6x2_ck>, <&tie_low_clock_ck>;
+ ti,bit-shift = <20>;
+ reg = <0x1a20>;
+ };
+
+ pmd_trace_clk_mux_ck: pmd_trace_clk_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&dpll_core_m6x2_ck>, <&tie_low_clock_ck>;
+ ti,bit-shift = <22>;
+ reg = <0x1a20>;
+ };
+
+ stm_clk_div_ck: stm_clk_div_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&pmd_stm_clock_mux_ck>;
+ ti,bit-shift = <27>;
+ ti,max-div = <64>;
+ reg = <0x1a20>;
+ ti,index-power-of-two;
+ };
+
+ trace_clk_div_div_ck: trace_clk_div_div_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&pmd_trace_clk_mux_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1a20>;
+ ti,dividers = <0>, <1>, <2>, <0>, <4>;
+ };
+
+ trace_clk_div_ck: trace_clk_div_ck {
+ #clock-cells = <0>;
+ compatible = "ti,clkdm-gate-clock";
+ clocks = <&trace_clk_div_div_ck>;
+ };
+};
+
+&prm_clockdomains {
+ emu_sys_clkdm: emu_sys_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&trace_clk_div_ck>;
+ };
+};
+
+&cm2_clocks {
+ per_hsd_byp_clk_mux_ck: per_hsd_byp_clk_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&per_hs_clk_div_ck>;
+ ti,bit-shift = <23>;
+ reg = <0x014c>;
+ };
+
+ dpll_per_ck: dpll_per_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-clock";
+ clocks = <&sys_clkin_ck>, <&per_hsd_byp_clk_mux_ck>;
+ reg = <0x0140>, <0x0144>, <0x014c>, <0x0148>;
+ };
+
+ dpll_per_m2_ck: dpll_per_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_ck>;
+ ti,max-div = <31>;
+ reg = <0x0150>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_per_x2_ck: dpll_per_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-x2-clock";
+ clocks = <&dpll_per_ck>;
+ reg = <0x0150>;
+ };
+
+ dpll_per_m2x2_ck: dpll_per_m2x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0150>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_per_m3x2_gate_ck: dpll_per_m3x2_gate_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0154>;
+ };
+
+ dpll_per_m3x2_div_ck: dpll_per_m3x2_div_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-divider-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,max-div = <31>;
+ reg = <0x0154>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_per_m3x2_ck: dpll_per_m3x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&dpll_per_m3x2_gate_ck>, <&dpll_per_m3x2_div_ck>;
+ };
+
+ dpll_per_m4x2_ck: dpll_per_m4x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0158>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_per_m5x2_ck: dpll_per_m5x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x015c>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_per_m6x2_ck: dpll_per_m6x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0160>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_per_m7x2_ck: dpll_per_m7x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,max-div = <31>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0164>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_usb_ck: dpll_usb_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-j-type-clock";
+ clocks = <&sys_clkin_ck>, <&usb_hs_clk_div_ck>;
+ reg = <0x0180>, <0x0184>, <0x018c>, <0x0188>;
+ };
+
+ dpll_usb_clkdcoldo_ck: dpll_usb_clkdcoldo_ck {
+ #clock-cells = <0>;
+ compatible = "ti,fixed-factor-clock";
+ clocks = <&dpll_usb_ck>;
+ ti,clock-div = <1>;
+ ti,autoidle-shift = <8>;
+ reg = <0x01b4>;
+ ti,clock-mult = <1>;
+ ti,invert-autoidle-bit;
+ };
+
+ dpll_usb_m2_ck: dpll_usb_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_usb_ck>;
+ ti,max-div = <127>;
+ ti,autoidle-shift = <8>;
+ reg = <0x0190>;
+ ti,index-starts-at-one;
+ ti,invert-autoidle-bit;
+ };
+
+ ducati_clk_mux_ck: ducati_clk_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&div_core_ck>, <&dpll_per_m6x2_ck>;
+ reg = <0x0100>;
+ };
+
+ func_12m_fclk: func_12m_fclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2x2_ck>;
+ clock-mult = <1>;
+ clock-div = <16>;
+ };
+
+ func_24m_clk: func_24m_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ func_24mc_fclk: func_24mc_fclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2x2_ck>;
+ clock-mult = <1>;
+ clock-div = <8>;
+ };
+
+ func_48m_fclk: func_48m_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_m2x2_ck>;
+ reg = <0x0108>;
+ ti,dividers = <4>, <8>;
+ };
+
+ func_48mc_fclk: func_48mc_fclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2x2_ck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ func_64m_fclk: func_64m_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_m4x2_ck>;
+ reg = <0x0108>;
+ ti,dividers = <2>, <4>;
+ };
+
+ func_96m_fclk: func_96m_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_m2x2_ck>;
+ reg = <0x0108>;
+ ti,dividers = <2>, <4>;
+ };
+
+ init_60m_fclk: init_60m_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_usb_m2_ck>;
+ reg = <0x0104>;
+ ti,dividers = <1>, <8>;
+ };
+
+ per_abe_nc_fclk: per_abe_nc_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_abe_m2_ck>;
+ reg = <0x0108>;
+ ti,max-div = <2>;
+ };
+
+ aes1_fck: aes1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l3_div_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x15a0>;
+ };
+
+ aes2_fck: aes2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l3_div_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x15a8>;
+ };
+
+ dss_sys_clk: dss_sys_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&syc_clk_div_ck>;
+ ti,bit-shift = <10>;
+ reg = <0x1120>;
+ };
+
+ dss_tv_clk: dss_tv_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&extalt_clkin_ck>;
+ ti,bit-shift = <11>;
+ reg = <0x1120>;
+ };
+
+ dss_dss_clk: dss_dss_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_per_m5x2_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1120>;
+ ti,set-rate-parent;
+ };
+
+ dss_48mhz_clk: dss_48mhz_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&func_48mc_fclk>;
+ ti,bit-shift = <9>;
+ reg = <0x1120>;
+ };
+
+ fdif_fck: fdif_fck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_m4x2_ck>;
+ ti,bit-shift = <24>;
+ ti,max-div = <4>;
+ reg = <0x1028>;
+ ti,index-power-of-two;
+ };
+
+ gpio2_dbclk: gpio2_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1460>;
+ };
+
+ gpio3_dbclk: gpio3_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1468>;
+ };
+
+ gpio4_dbclk: gpio4_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1470>;
+ };
+
+ gpio5_dbclk: gpio5_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1478>;
+ };
+
+ gpio6_dbclk: gpio6_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1480>;
+ };
+
+ sgx_clk_mux: sgx_clk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dpll_core_m7x2_ck>, <&dpll_per_m7x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1220>;
+ };
+
+ hsi_fck: hsi_fck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ ti,max-div = <4>;
+ reg = <0x1338>;
+ ti,index-power-of-two;
+ };
+
+ iss_ctrlclk: iss_ctrlclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&func_96m_fclk>;
+ ti,bit-shift = <8>;
+ reg = <0x1020>;
+ };
+
+ mcbsp4_sync_mux_ck: mcbsp4_sync_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_96m_fclk>, <&per_abe_nc_fclk>;
+ ti,bit-shift = <25>;
+ reg = <0x14e0>;
+ };
+
+ per_mcbsp4_gfclk: per_mcbsp4_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&mcbsp4_sync_mux_ck>, <&pad_clks_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x14e0>;
+ };
+
+ hsmmc1_fclk: hsmmc1_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_64m_fclk>, <&func_96m_fclk>;
+ ti,bit-shift = <24>;
+ reg = <0x1328>;
+ };
+
+ hsmmc2_fclk: hsmmc2_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_64m_fclk>, <&func_96m_fclk>;
+ ti,bit-shift = <24>;
+ reg = <0x1330>;
+ };
+
+ ocp2scp_usb_phy_phy_48m: ocp2scp_usb_phy_phy_48m {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&func_48m_fclk>;
+ ti,bit-shift = <8>;
+ reg = <0x13e0>;
+ };
+
+ sha2md5_fck: sha2md5_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l3_div_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x15c8>;
+ };
+
+ slimbus2_fclk_1: slimbus2_fclk_1 {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&per_abe_24m_fclk>;
+ ti,bit-shift = <9>;
+ reg = <0x1538>;
+ };
+
+ slimbus2_fclk_0: slimbus2_fclk_0 {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&func_24mc_fclk>;
+ ti,bit-shift = <8>;
+ reg = <0x1538>;
+ };
+
+ slimbus2_slimbus_clk: slimbus2_slimbus_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&pad_slimbus_core_clks_ck>;
+ ti,bit-shift = <10>;
+ reg = <0x1538>;
+ };
+
+ smartreflex_core_fck: smartreflex_core_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l4_wkup_clk_mux_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0638>;
+ };
+
+ smartreflex_iva_fck: smartreflex_iva_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l4_wkup_clk_mux_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0630>;
+ };
+
+ smartreflex_mpu_fck: smartreflex_mpu_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l4_wkup_clk_mux_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0628>;
+ };
+
+ cm2_dm10_mux: cm2_dm10_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1428>;
+ };
+
+ cm2_dm11_mux: cm2_dm11_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1430>;
+ };
+
+ cm2_dm2_mux: cm2_dm2_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1438>;
+ };
+
+ cm2_dm3_mux: cm2_dm3_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1440>;
+ };
+
+ cm2_dm4_mux: cm2_dm4_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1448>;
+ };
+
+ cm2_dm9_mux: cm2_dm9_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1450>;
+ };
+
+ usb_host_fs_fck: usb_host_fs_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&func_48mc_fclk>;
+ ti,bit-shift = <1>;
+ reg = <0x13d0>;
+ };
+
+ utmi_p1_gfclk: utmi_p1_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&init_60m_fclk>, <&xclk60mhsp1_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1358>;
+ };
+
+ usb_host_hs_utmi_p1_clk: usb_host_hs_utmi_p1_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&utmi_p1_gfclk>;
+ ti,bit-shift = <8>;
+ reg = <0x1358>;
+ };
+
+ utmi_p2_gfclk: utmi_p2_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&init_60m_fclk>, <&xclk60mhsp2_ck>;
+ ti,bit-shift = <25>;
+ reg = <0x1358>;
+ };
+
+ usb_host_hs_utmi_p2_clk: usb_host_hs_utmi_p2_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&utmi_p2_gfclk>;
+ ti,bit-shift = <9>;
+ reg = <0x1358>;
+ };
+
+ usb_host_hs_utmi_p3_clk: usb_host_hs_utmi_p3_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&init_60m_fclk>;
+ ti,bit-shift = <10>;
+ reg = <0x1358>;
+ };
+
+ usb_host_hs_hsic480m_p1_clk: usb_host_hs_hsic480m_p1_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_usb_m2_ck>;
+ ti,bit-shift = <13>;
+ reg = <0x1358>;
+ };
+
+ usb_host_hs_hsic60m_p1_clk: usb_host_hs_hsic60m_p1_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&init_60m_fclk>;
+ ti,bit-shift = <11>;
+ reg = <0x1358>;
+ };
+
+ usb_host_hs_hsic60m_p2_clk: usb_host_hs_hsic60m_p2_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&init_60m_fclk>;
+ ti,bit-shift = <12>;
+ reg = <0x1358>;
+ };
+
+ usb_host_hs_hsic480m_p2_clk: usb_host_hs_hsic480m_p2_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_usb_m2_ck>;
+ ti,bit-shift = <14>;
+ reg = <0x1358>;
+ };
+
+ usb_host_hs_func48mclk: usb_host_hs_func48mclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&func_48mc_fclk>;
+ ti,bit-shift = <15>;
+ reg = <0x1358>;
+ };
+
+ usb_host_hs_fck: usb_host_hs_fck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&init_60m_fclk>;
+ ti,bit-shift = <1>;
+ reg = <0x1358>;
+ };
+
+ otg_60m_gfclk: otg_60m_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&utmi_phy_clkout_ck>, <&xclk60motg_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1360>;
+ };
+
+ usb_otg_hs_xclk: usb_otg_hs_xclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&otg_60m_gfclk>;
+ ti,bit-shift = <8>;
+ reg = <0x1360>;
+ };
+
+ usb_otg_hs_ick: usb_otg_hs_ick {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l3_div_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x1360>;
+ };
+
+ usb_phy_cm_clk32k: usb_phy_cm_clk32k {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0640>;
+ };
+
+ usb_tll_hs_usb_ch2_clk: usb_tll_hs_usb_ch2_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&init_60m_fclk>;
+ ti,bit-shift = <10>;
+ reg = <0x1368>;
+ };
+
+ usb_tll_hs_usb_ch0_clk: usb_tll_hs_usb_ch0_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&init_60m_fclk>;
+ ti,bit-shift = <8>;
+ reg = <0x1368>;
+ };
+
+ usb_tll_hs_usb_ch1_clk: usb_tll_hs_usb_ch1_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&init_60m_fclk>;
+ ti,bit-shift = <9>;
+ reg = <0x1368>;
+ };
+
+ usb_tll_hs_ick: usb_tll_hs_ick {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l4_div_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x1368>;
+ };
+};
+
+&cm2_clockdomains {
+ l3_init_clkdm: l3_init_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&dpll_usb_ck>, <&usb_host_fs_fck>;
+ };
+};
+
+&scrm_clocks {
+ auxclk0_src_gate_ck: auxclk0_src_gate_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&dpll_core_m3x2_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0310>;
+ };
+
+ auxclk0_src_mux_ck: auxclk0_src_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&sys_clkin_ck>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0310>;
+ };
+
+ auxclk0_src_ck: auxclk0_src_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&auxclk0_src_gate_ck>, <&auxclk0_src_mux_ck>;
+ };
+
+ auxclk0_ck: auxclk0_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&auxclk0_src_ck>;
+ ti,bit-shift = <16>;
+ ti,max-div = <16>;
+ reg = <0x0310>;
+ };
+
+ auxclk1_src_gate_ck: auxclk1_src_gate_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&dpll_core_m3x2_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0314>;
+ };
+
+ auxclk1_src_mux_ck: auxclk1_src_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&sys_clkin_ck>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0314>;
+ };
+
+ auxclk1_src_ck: auxclk1_src_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&auxclk1_src_gate_ck>, <&auxclk1_src_mux_ck>;
+ };
+
+ auxclk1_ck: auxclk1_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&auxclk1_src_ck>;
+ ti,bit-shift = <16>;
+ ti,max-div = <16>;
+ reg = <0x0314>;
+ };
+
+ auxclk2_src_gate_ck: auxclk2_src_gate_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&dpll_core_m3x2_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0318>;
+ };
+
+ auxclk2_src_mux_ck: auxclk2_src_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&sys_clkin_ck>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0318>;
+ };
+
+ auxclk2_src_ck: auxclk2_src_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&auxclk2_src_gate_ck>, <&auxclk2_src_mux_ck>;
+ };
+
+ auxclk2_ck: auxclk2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&auxclk2_src_ck>;
+ ti,bit-shift = <16>;
+ ti,max-div = <16>;
+ reg = <0x0318>;
+ };
+
+ auxclk3_src_gate_ck: auxclk3_src_gate_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&dpll_core_m3x2_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x031c>;
+ };
+
+ auxclk3_src_mux_ck: auxclk3_src_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&sys_clkin_ck>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x031c>;
+ };
+
+ auxclk3_src_ck: auxclk3_src_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&auxclk3_src_gate_ck>, <&auxclk3_src_mux_ck>;
+ };
+
+ auxclk3_ck: auxclk3_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&auxclk3_src_ck>;
+ ti,bit-shift = <16>;
+ ti,max-div = <16>;
+ reg = <0x031c>;
+ };
+
+ auxclk4_src_gate_ck: auxclk4_src_gate_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&dpll_core_m3x2_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0320>;
+ };
+
+ auxclk4_src_mux_ck: auxclk4_src_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&sys_clkin_ck>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0320>;
+ };
+
+ auxclk4_src_ck: auxclk4_src_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&auxclk4_src_gate_ck>, <&auxclk4_src_mux_ck>;
+ };
+
+ auxclk4_ck: auxclk4_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&auxclk4_src_ck>;
+ ti,bit-shift = <16>;
+ ti,max-div = <16>;
+ reg = <0x0320>;
+ };
+
+ auxclk5_src_gate_ck: auxclk5_src_gate_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&dpll_core_m3x2_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0324>;
+ };
+
+ auxclk5_src_mux_ck: auxclk5_src_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&sys_clkin_ck>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0324>;
+ };
+
+ auxclk5_src_ck: auxclk5_src_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&auxclk5_src_gate_ck>, <&auxclk5_src_mux_ck>;
+ };
+
+ auxclk5_ck: auxclk5_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&auxclk5_src_ck>;
+ ti,bit-shift = <16>;
+ ti,max-div = <16>;
+ reg = <0x0324>;
+ };
+
+ auxclkreq0_ck: auxclkreq0_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>, <&auxclk5_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x0210>;
+ };
+
+ auxclkreq1_ck: auxclkreq1_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>, <&auxclk5_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x0214>;
+ };
+
+ auxclkreq2_ck: auxclkreq2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>, <&auxclk5_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x0218>;
+ };
+
+ auxclkreq3_ck: auxclkreq3_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>, <&auxclk5_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x021c>;
+ };
+
+ auxclkreq4_ck: auxclkreq4_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>, <&auxclk5_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x0220>;
+ };
+
+ auxclkreq5_ck: auxclkreq5_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>, <&auxclk5_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x0224>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap5-cm-t54.dts b/arch/arm/boot/dts/omap5-cm-t54.dts
new file mode 100644
index 000000000..61ad2ea34
--- /dev/null
+++ b/arch/arm/boot/dts/omap5-cm-t54.dts
@@ -0,0 +1,679 @@
+/*
+ * Support for CompuLab CM-T54
+ */
+/dts-v1/;
+
+#include "omap5.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ model = "CompuLab CM-T54";
+ compatible = "compulab,omap5-cm-t54", "ti,omap5";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x7F000000>; /* 2048 MB */
+ };
+
+ aliases {
+ display0 = &hdmi0;
+ display1 = &dvi0;
+ display2 = &lcd0;
+ };
+
+ vmmcsd_fixed: fixed-regulator-mmcsd {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsd_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vwlan_pdn_fixed: fixed-regulator-vwlan-pdn {
+ compatible = "regulator-fixed";
+ regulator-name = "vwlan_pdn_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&ldo2_reg>;
+ gpio = <&gpio4 13 GPIO_ACTIVE_HIGH>; /* gpio4_109 */
+ startup-delay-us = <1000>;
+ enable-active-high;
+ };
+
+ vwlan_fixed: fixed-regulator-vwlan {
+ compatible = "regulator-fixed";
+ regulator-name = "vwlan_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vwlan_pdn_fixed>;
+ gpio = <&gpio4 14 GPIO_ACTIVE_HIGH>; /* gpio4_110 */
+ startup-delay-us = <1000>;
+ enable-active-high;
+ };
+
+ ads7846reg: ads7846-reg {
+ compatible = "regulator-fixed";
+ regulator-name = "ads7846-reg";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ /* HS USB Host PHY on PORT 2 */
+ hsusb2_phy: hsusb2_phy {
+ compatible = "usb-nop-xceiv";
+ reset-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>; /* gpio3_76 HUB_RESET */
+ };
+
+ /* HS USB Host PHY on PORT 3 */
+ hsusb3_phy: hsusb3_phy {
+ compatible = "usb-nop-xceiv";
+ reset-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; /* gpio3_83 ETH_RESET */
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ led@1 {
+ label = "Heartbeat";
+ gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>; /* gpio3_80 ACT_LED */
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+ };
+
+ lcd0: display {
+ compatible = "startek,startek-kd050c", "panel-dpi";
+ label = "lcd";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_pins>;
+
+ enable-gpios = <&gpio8 3 GPIO_ACTIVE_HIGH>;
+
+ panel-timing {
+ clock-frequency = <33000000>;
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <40>;
+ hback-porch = <40>;
+ hsync-len = <43>;
+ vback-porch = <29>;
+ vfront-porch = <13>;
+ vsync-len = <3>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_lcd_out>;
+ };
+ };
+ };
+
+ hdmi0: connector@0 {
+ compatible = "hdmi-connector";
+ label = "hdmi";
+
+ type = "a";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_conn_pins>;
+
+ hpd-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>; /* GPIO 193, HPD */
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_out>;
+ };
+ };
+ };
+
+ tfp410: encoder@0 {
+ compatible = "ti,tfp410";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ tfp410_in: endpoint@0 {
+ remote-endpoint = <&dpi_dvi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ tfp410_out: endpoint@0 {
+ remote-endpoint = <&dvi_connector_in>;
+ };
+ };
+ };
+ };
+
+ dvi0: connector@1 {
+ compatible = "dvi-connector";
+ label = "dvi";
+
+ digital;
+
+ ddc-i2c-bus = <&i2c2>;
+
+ port {
+ dvi_connector_in: endpoint {
+ remote-endpoint = <&tfp410_out>;
+ };
+ };
+ };
+};
+
+&omap5_pmx_wkup {
+
+ ads7846_pins: pinmux_ads7846_pins {
+ pinctrl-single,pins = <
+ 0x02 (PIN_INPUT_PULLDOWN | MUX_MODE6) /* llib_wakereqin.gpio1_wk15 */
+ >;
+ };
+};
+
+&omap5_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &led_gpio_pins
+ &usbhost_pins
+ >;
+
+ led_gpio_pins: pinmux_led_gpio_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x00b0, PIN_OUTPUT | MUX_MODE6) /* hsi2_caflag.gpio3_80 */
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x01f2, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_pmic_scl */
+ OMAP5_IOPAD(0x01f4, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_pmic_sda */
+ >;
+ };
+
+ i2c2_pins: pinmux_i2c2_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x01b8, PIN_INPUT | MUX_MODE0) /* i2c2_scl */
+ OMAP5_IOPAD(0x01ba, PIN_INPUT | MUX_MODE0) /* i2c2_sda */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x01e2, PIN_INPUT_PULLUP | MUX_MODE0) /* sdcard_clk */
+ OMAP5_IOPAD(0x01e4, PIN_INPUT_PULLUP | MUX_MODE0) /* sdcard_cmd */
+ OMAP5_IOPAD(0x01e6, PIN_INPUT_PULLUP | MUX_MODE0) /* sdcard_data2 */
+ OMAP5_IOPAD(0x01e8, PIN_INPUT_PULLUP | MUX_MODE0) /* sdcard_data3 */
+ OMAP5_IOPAD(0x01ea, PIN_INPUT_PULLUP | MUX_MODE0) /* sdcard_data0 */
+ OMAP5_IOPAD(0x01ec, PIN_INPUT_PULLUP | MUX_MODE0) /* sdcard_data1 */
+ >;
+ };
+
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x0040, PIN_INPUT_PULLUP | MUX_MODE0) /* emmc_clk */
+ OMAP5_IOPAD(0x0042, PIN_INPUT_PULLUP | MUX_MODE0) /* emmc_cmd */
+ OMAP5_IOPAD(0x0044, PIN_INPUT_PULLUP | MUX_MODE0) /* emmc_data0 */
+ OMAP5_IOPAD(0x0046, PIN_INPUT_PULLUP | MUX_MODE0) /* emmc_data1 */
+ OMAP5_IOPAD(0x0048, PIN_INPUT_PULLUP | MUX_MODE0) /* emmc_data2 */
+ OMAP5_IOPAD(0x004a, PIN_INPUT_PULLUP | MUX_MODE0) /* emmc_data3 */
+ OMAP5_IOPAD(0x004c, PIN_INPUT_PULLUP | MUX_MODE0) /* emmc_data4 */
+ OMAP5_IOPAD(0x004e, PIN_INPUT_PULLUP | MUX_MODE0) /* emmc_data5 */
+ OMAP5_IOPAD(0x0050, PIN_INPUT_PULLUP | MUX_MODE0) /* emmc_data6 */
+ OMAP5_IOPAD(0x0052, PIN_INPUT_PULLUP | MUX_MODE0) /* emmc_data7 */
+ >;
+ };
+
+ mmc3_pins: pinmux_mmc3_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x01a4, PIN_INPUT_PULLUP | MUX_MODE0) /* wlsdio_clk */
+ OMAP5_IOPAD(0x01a6, PIN_INPUT_PULLUP | MUX_MODE0) /* wlsdio_cmd */
+ OMAP5_IOPAD(0x01a8, PIN_INPUT_PULLUP | MUX_MODE0) /* wlsdio_data0 */
+ OMAP5_IOPAD(0x01aa, PIN_INPUT_PULLUP | MUX_MODE0) /* wlsdio_data1 */
+ OMAP5_IOPAD(0x01ac, PIN_INPUT_PULLUP | MUX_MODE0) /* wlsdio_data2 */
+ OMAP5_IOPAD(0x01ae, PIN_INPUT_PULLUP | MUX_MODE0) /* wlsdio_data3 */
+ >;
+ };
+
+ wlan_gpios_pins: pinmux_wlan_gpios_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x019c, PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* abemcpdm_ul_data.gpio4_109 */
+ OMAP5_IOPAD(0x019e, PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* abemcpdm_dl_data.gpio4_110 */
+ >;
+ };
+
+ usbhost_pins: pinmux_usbhost_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x00c4, PIN_INPUT | MUX_MODE0) /* usbb2_hsic_strobe */
+ OMAP5_IOPAD(0x00c6, PIN_INPUT | MUX_MODE0) /* usbb2_hsic_data */
+
+ OMAP5_IOPAD(0x01dc, PIN_INPUT | MUX_MODE0) /* usbb3_hsic_strobe */
+ OMAP5_IOPAD(0x01de, PIN_INPUT | MUX_MODE0) /* usbb3_hsic_data */
+
+ OMAP5_IOPAD(0x00a8, PIN_OUTPUT | MUX_MODE6) /* hsi2_caready.gpio3_76 */
+ OMAP5_IOPAD(0x00b6, PIN_OUTPUT | MUX_MODE6) /* hsi2_acdata.gpio3_83 */
+ >;
+ };
+
+ dss_hdmi_pins: pinmux_dss_hdmi_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x013c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec */
+ OMAP5_IOPAD(0x0140, PIN_INPUT | MUX_MODE0) /* hdmi_ddc_scl */
+ OMAP5_IOPAD(0x0142, PIN_INPUT | MUX_MODE0) /* hdmi_ddc_sda */
+ >;
+ };
+
+ lcd_pins: pinmux_lcd_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x0172, PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* timer11_pwm_evt.gpio8_227 */
+ >;
+ };
+
+ hdmi_conn_pins: pinmux_hdmi_conn_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x013e, PIN_INPUT | MUX_MODE6) /* hdmi_hpd.gpio7_193 */
+ >;
+ };
+
+ dss_dpi_pins: pinmux_dss_dpi_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x0104, PIN_OUTPUT | MUX_MODE3) /* rfbi_data15.dispc_data15 */
+ OMAP5_IOPAD(0x0106, PIN_OUTPUT | MUX_MODE3) /* rfbi_data14.dispc_data14 */
+ OMAP5_IOPAD(0x0108, PIN_OUTPUT | MUX_MODE3) /* rfbi_data13.dispc_data13 */
+ OMAP5_IOPAD(0x010a, PIN_OUTPUT | MUX_MODE3) /* rfbi_data12.dispc_data12 */
+ OMAP5_IOPAD(0x010c, PIN_OUTPUT | MUX_MODE3) /* rfbi_data11.dispc_data11 */
+ OMAP5_IOPAD(0x010e, PIN_OUTPUT | MUX_MODE3) /* rfbi_data10.dispc_data10 */
+ OMAP5_IOPAD(0x0110, PIN_OUTPUT | MUX_MODE3) /* rfbi_data9.dispc_data9 */
+ OMAP5_IOPAD(0x0112, PIN_OUTPUT | MUX_MODE3) /* rfbi_data8.dispc_data8 */
+ OMAP5_IOPAD(0x0114, PIN_OUTPUT | MUX_MODE3) /* rfbi_data7.dispc_data7 */
+ OMAP5_IOPAD(0x0116, PIN_OUTPUT | MUX_MODE3) /* rfbi_data6.dispc_data6 */
+ OMAP5_IOPAD(0x0118, PIN_OUTPUT | MUX_MODE3) /* rfbi_data5.dispc_data5 */
+ OMAP5_IOPAD(0x011a, PIN_OUTPUT | MUX_MODE3) /* rfbi_data4.dispc_data4 */
+ OMAP5_IOPAD(0x011c, PIN_OUTPUT | MUX_MODE3) /* rfbi_data3.dispc_data3 */
+ OMAP5_IOPAD(0x011e, PIN_OUTPUT | MUX_MODE3) /* rfbi_data2.dispc_data2 */
+ OMAP5_IOPAD(0x0120, PIN_OUTPUT | MUX_MODE3) /* rfbi_data1.dispc_data1 */
+ OMAP5_IOPAD(0x0122, PIN_OUTPUT | MUX_MODE3) /* rfbi_data0.dispc_data0 */
+ OMAP5_IOPAD(0x0124, PIN_OUTPUT | MUX_MODE3) /* rfbi_we.dispc_vsync */
+ OMAP5_IOPAD(0x0126, PIN_OUTPUT | MUX_MODE3) /* rfbi_cs0.dispc_hsync */
+ OMAP5_IOPAD(0x0128, PIN_OUTPUT | MUX_MODE3) /* rfbi_a0.dispc_de */
+ OMAP5_IOPAD(0x012a, PIN_OUTPUT | MUX_MODE3) /* rfbi_re.dispc_pclk */
+ OMAP5_IOPAD(0x012c, PIN_OUTPUT | MUX_MODE3) /* rfbi_hsync0.dispc_data17 */
+ OMAP5_IOPAD(0x012e, PIN_OUTPUT | MUX_MODE3) /* rfbi_te_vsync0.dispc_data16 */
+ OMAP5_IOPAD(0x0130, PIN_OUTPUT | MUX_MODE3) /* gpio6_182.dispc_data18 */
+ OMAP5_IOPAD(0x0132, PIN_OUTPUT | MUX_MODE3) /* gpio6_183.dispc_data19 */
+ OMAP5_IOPAD(0x0134, PIN_OUTPUT | MUX_MODE3) /* gpio6_184.dispc_data20 */
+ OMAP5_IOPAD(0x0136, PIN_OUTPUT | MUX_MODE3) /* gpio6_185.dispc_data21 */
+ OMAP5_IOPAD(0x0138, PIN_OUTPUT | MUX_MODE3) /* gpio6_186.dispc_data22 */
+ OMAP5_IOPAD(0x013a, PIN_OUTPUT | MUX_MODE3) /* gpio6_187.dispc_data23 */
+ >;
+ };
+
+ mcspi2_pins: pinmux_mcspi1_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x00fc, PIN_INPUT | MUX_MODE0) /* mcspi2_clk */
+ OMAP5_IOPAD(0x00fe, PIN_INPUT | MUX_MODE0) /* mcspi2_simo */
+ OMAP5_IOPAD(0x0100, PIN_INPUT | MUX_MODE0) /* mcspi2_somi */
+ OMAP5_IOPAD(0x0102, PIN_INPUT | MUX_MODE0) /* mcspi2_cs0 */
+ >;
+ };
+};
+
+&mcspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi2_pins>;
+
+ /* touch controller */
+ ads7846@0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ads7846_pins>;
+
+ compatible = "ti,ads7846";
+ vcc-supply = <&ads7846reg>;
+
+ reg = <0>; /* CS0 */
+ spi-max-frequency = <1500000>;
+
+ interrupt-parent = <&gpio1>;
+ interrupts = <15 0>; /* gpio1_wk15 */
+ pendown-gpio = <&gpio1 15 0>;
+
+
+ ti,x-min = /bits/ 16 <0x0>;
+ ti,x-max = /bits/ 16 <0x0fff>;
+ ti,y-min = /bits/ 16 <0x0>;
+ ti,y-max = /bits/ 16 <0x0fff>;
+
+ ti,x-plate-ohms = /bits/ 16 <180>;
+ ti,pressure-max = /bits/ 16 <255>;
+
+ ti,debounce-max = /bits/ 16 <30>;
+ ti,debounce-tol = /bits/ 16 <10>;
+ ti,debounce-rep = /bits/ 16 <1>;
+
+ linux,wakeup;
+ };
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&ldo9_reg>;
+ bus-width = <4>;
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+ vmmc-supply = <&vmmcsd_fixed>;
+ bus-width = <8>;
+ ti,non-removable;
+};
+
+&mmc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &mmc3_pins
+ &wlan_gpios_pins
+ >;
+ vmmc-supply = <&vwlan_fixed>;
+ bus-width = <4>;
+ ti,non-removable;
+};
+
+&mmc4 {
+ status = "disabled";
+};
+
+&mmc5 {
+ status = "disabled";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+
+ clock-frequency = <400000>;
+
+ at24@50 {
+ compatible = "at24,24c02";
+ pagesize = <16>;
+ reg = <0x50>;
+ };
+
+ palmas: palmas@48 {
+ compatible = "ti,palmas";
+ interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */
+ reg = <0x48>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ti,system-power-controller;
+
+ extcon_usb3: palmas_usb {
+ compatible = "ti,palmas-usb-vid";
+ ti,enable-vbus-detection;
+ ti,enable-id-detection;
+ ti,wakeup;
+ };
+
+ rtc {
+ compatible = "ti,palmas-rtc";
+ interrupt-parent = <&palmas>;
+ interrupts = <8 IRQ_TYPE_NONE>;
+ };
+
+ palmas_pmic {
+ compatible = "ti,palmas-pmic";
+ interrupt-parent = <&palmas>;
+ interrupts = <14 IRQ_TYPE_NONE>;
+ interrupt-name = "short-irq";
+
+ ti,ldo6-vibrator;
+
+ regulators {
+ smps123_reg: smps123 {
+ /* VDD_OPP_MPU */
+ regulator-name = "smps123";
+ regulator-min-microvolt = < 600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps45_reg: smps45 {
+ /* VDD_OPP_MM */
+ regulator-name = "smps45";
+ regulator-min-microvolt = < 600000>;
+ regulator-max-microvolt = <1310000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps6_reg: smps6 {
+ /* VDD_DDR3 - over VDD_SMPS6 */
+ regulator-name = "smps6";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps7_reg: smps7 {
+ /* VDDS_1v8_OMAP over VDDS_1v8_MAIN */
+ regulator-name = "smps7";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps8_reg: smps8 {
+ /* VDD_OPP_CORE */
+ regulator-name = "smps8";
+ regulator-min-microvolt = < 600000>;
+ regulator-max-microvolt = <1310000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps9_reg: smps9 {
+ /* VDDA_2v1_AUD over VDD_2v1 */
+ regulator-name = "smps9";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ ti,smps-range = <0x80>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps10_out2_reg: smps10_out2 {
+ /* VBUS_5V_OTG */
+ regulator-name = "smps10_out2";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps10_out1_reg: smps10_out1 {
+ /* VBUS_5V_OTG */
+ regulator-name = "smps10_out1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ ldo1_reg: ldo1 {
+ /* VDDAPHY_CAM: vdda_csiport */
+ regulator-name = "ldo1";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo2_reg: ldo2 {
+ /* VDD_3V3_WLAN */
+ regulator-name = "ldo2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <1000>;
+ };
+
+ ldo3_reg: ldo3 {
+ /* VCC_1V5_AUD */
+ regulator-name = "ldo3";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo4_reg: ldo4 {
+ /* VDDAPHY_DISP: vdda_dsiport/hdmi */
+ regulator-name = "ldo4";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo5_reg: ldo5 {
+ /* VDDA_1V8_PHY: usb/sata/hdmi.. */
+ regulator-name = "ldo5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo6_reg: ldo6 {
+ /* VDDS_1V2_WKUP: hsic/ldo_emu_wkup */
+ regulator-name = "ldo6";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo7_reg: ldo7 {
+ /* VDD_VPP: vpp1 */
+ regulator-name = "ldo7";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ /* Only for efuse reprograming! */
+ status = "disabled";
+ };
+
+ ldo8_reg: ldo8 {
+ /* VDD_3V_GP: act led/serial console */
+ regulator-name = "ldo8";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo9_reg: ldo9 {
+ /* VCC_DV_SDIO: vdds_sdcard */
+ regulator-name = "ldo9";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ };
+
+ ldoln_reg: ldoln {
+ /* VDDA_1v8_REF: vdds_osc/mm_l4per.. */
+ regulator-name = "ldoln";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldousb_reg: ldousb {
+ /* VDDA_3V_USB: VDDA_USBHS33 */
+ regulator-name = "ldousb";
+ regulator-min-microvolt = <3250000>;
+ regulator-max-microvolt = <3250000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ regen3_reg: regen3 {
+ /* REGEN3 controls LDO9 supply to card */
+ regulator-name = "regen3";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+
+ clock-frequency = <100000>;
+};
+
+&usbhshost {
+ port2-mode = "ehci-hsic";
+ port3-mode = "ehci-hsic";
+};
+
+&usbhsehci {
+ phys = <0 &hsusb2_phy &hsusb3_phy>;
+};
+
+&usb3 {
+ extcon = <&extcon_usb3>;
+ vbus-supply = <&smps10_out1_reg>;
+};
+
+&cpu0 {
+ cpu0-supply = <&smps123_reg>;
+};
+
+&dss {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_dpi_pins>;
+
+ port {
+ dpi_dvi_out: endpoint@0 {
+ remote-endpoint = <&tfp410_in>;
+ data-lines = <24>;
+ };
+
+ dpi_lcd_out: endpoint@1 {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+&dsi2 {
+ status = "ok";
+ vdd-supply = <&ldo4_reg>;
+};
+
+&hdmi {
+ status = "ok";
+ vdda-supply = <&ldo4_reg>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_hdmi_pins>;
+
+ port {
+ hdmi_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ lanes = <1 0 3 2 5 4 7 6>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap5-core-thermal.dtsi b/arch/arm/boot/dts/omap5-core-thermal.dtsi
new file mode 100644
index 000000000..de8a3d456
--- /dev/null
+++ b/arch/arm/boot/dts/omap5-core-thermal.dtsi
@@ -0,0 +1,28 @@
+/*
+ * Device Tree Source for OMAP543x SoC CORE thermal
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ * Contact: Eduardo Valentin <eduardo.valentin@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 <dt-bindings/thermal/thermal.h>
+
+core_thermal: core_thermal {
+ polling-delay-passive = <250>; /* milliseconds */
+ polling-delay = <500>; /* milliseconds */
+
+ /* sensor ID */
+ thermal-sensors = <&bandgap 2>;
+
+ trips {
+ core_crit: core_crit {
+ temperature = <125000>; /* milliCelsius */
+ hysteresis = <2000>; /* milliCelsius */
+ type = "critical";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap5-gpu-thermal.dtsi b/arch/arm/boot/dts/omap5-gpu-thermal.dtsi
new file mode 100644
index 000000000..bc3090f2e
--- /dev/null
+++ b/arch/arm/boot/dts/omap5-gpu-thermal.dtsi
@@ -0,0 +1,28 @@
+/*
+ * Device Tree Source for OMAP543x SoC GPU thermal
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ * Contact: Eduardo Valentin <eduardo.valentin@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 <dt-bindings/thermal/thermal.h>
+
+gpu_thermal: gpu_thermal {
+ polling-delay-passive = <250>; /* milliseconds */
+ polling-delay = <500>; /* milliseconds */
+
+ /* sensor ID */
+ thermal-sensors = <&bandgap 1>;
+
+ trips {
+ gpu_crit: gpu_crit {
+ temperature = <125000>; /* milliCelsius */
+ hysteresis = <2000>; /* milliCelsius */
+ type = "critical";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap5-sbc-t54.dts b/arch/arm/boot/dts/omap5-sbc-t54.dts
new file mode 100644
index 000000000..337bbbc01
--- /dev/null
+++ b/arch/arm/boot/dts/omap5-sbc-t54.dts
@@ -0,0 +1,51 @@
+/*
+ * Suppport for CompuLab CM-T54 on SB-T54 baseboard
+ */
+
+#include "omap5-cm-t54.dts"
+
+/ {
+ model = "CompuLab CM-T54 on SB-T54";
+ compatible = "compulab,omap5-sbc-t54", "compulab,omap5-cm-t54", "ti,omap5";
+};
+
+&omap5_pmx_core {
+ i2c4_pins: pinmux_i2c4_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x00f8, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */
+ OMAP5_IOPAD(0x00fa, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */
+ >;
+ };
+
+ mmc1_aux_pins: pinmux_mmc1_aux_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x0174, PIN_INPUT_PULLUP | MUX_MODE6) /* timer5_pwm_evt.gpio8_228 */
+ OMAP5_IOPAD(0x0176, PIN_INPUT_PULLUP | MUX_MODE6) /* timer6_pwm_evt.gpio8_229 */
+ >;
+ };
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &mmc1_pins
+ &mmc1_aux_pins
+ >;
+ cd-inverted;
+ wp-inverted;
+ cd-gpios = <&gpio8 4 GPIO_ACTIVE_LOW>; /* gpio8_228 */
+ wp-gpios = <&gpio8 5 GPIO_ACTIVE_LOW>; /* gpio8_229 */
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins>;
+
+ clock-frequency = <400000>;
+
+ at24@50 {
+ compatible = "at24,24c02";
+ pagesize = <16>;
+ reg = <0x50>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap5-uevm.dts b/arch/arm/boot/dts/omap5-uevm.dts
new file mode 100644
index 000000000..74777a6e2
--- /dev/null
+++ b/arch/arm/boot/dts/omap5-uevm.dts
@@ -0,0 +1,634 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+/dts-v1/;
+
+#include "omap5.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ model = "TI OMAP5 uEVM board";
+ compatible = "ti,omap5-uevm", "ti,omap5";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x7F000000>; /* 2032 MB */
+ };
+
+ aliases {
+ display0 = &hdmi0;
+ };
+
+ vmmcsd_fixed: fixedregulator-mmcsd {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsd_fixed";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ /* HS USB Host PHY on PORT 2 */
+ hsusb2_phy: hsusb2_phy {
+ compatible = "usb-nop-xceiv";
+ reset-gpios = <&gpio3 16 GPIO_ACTIVE_LOW>; /* gpio3_80 HUB_NRESET */
+ clocks = <&auxclk1_ck>;
+ clock-names = "main_clk";
+ clock-frequency = <19200000>;
+ };
+
+ /* HS USB Host PHY on PORT 3 */
+ hsusb3_phy: hsusb3_phy {
+ compatible = "usb-nop-xceiv";
+ reset-gpios = <&gpio3 15 GPIO_ACTIVE_LOW>; /* gpio3_79 ETH_NRESET */
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ led@1 {
+ label = "omap5:blue:usr1";
+ gpios = <&gpio5 25 GPIO_ACTIVE_HIGH>; /* gpio5_153 D1 LED */
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+ };
+
+ tpd12s015: encoder@0 {
+ compatible = "ti,tpd12s015";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&tpd12s015_pins>;
+
+ gpios = <&gpio9 0 GPIO_ACTIVE_HIGH>, /* TCA6424A P01, CT CP HPD */
+ <&gpio9 1 GPIO_ACTIVE_HIGH>, /* TCA6424A P00, LS OE */
+ <&gpio7 1 GPIO_ACTIVE_HIGH>; /* GPIO 193, HPD */
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ tpd12s015_in: endpoint@0 {
+ remote-endpoint = <&hdmi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ tpd12s015_out: endpoint@0 {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+ };
+ };
+
+ hdmi0: connector@0 {
+ compatible = "hdmi-connector";
+ label = "hdmi";
+
+ type = "b";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&tpd12s015_out>;
+ };
+ };
+ };
+
+ sound: sound {
+ compatible = "ti,abe-twl6040";
+ ti,model = "omap5-uevm";
+
+ ti,mclk-freq = <19200000>;
+
+ ti,mcpdm = <&mcpdm>;
+
+ ti,twl6040 = <&twl6040>;
+
+ /* Audio routing */
+ ti,audio-routing =
+ "Headset Stereophone", "HSOL",
+ "Headset Stereophone", "HSOR",
+ "Line Out", "AUXL",
+ "Line Out", "AUXR",
+ "HSMIC", "Headset Mic",
+ "Headset Mic", "Headset Mic Bias",
+ "AFML", "Line In",
+ "AFMR", "Line In";
+ };
+};
+
+&omap5_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &usbhost_pins
+ &led_gpio_pins
+ >;
+
+ twl6040_pins: pinmux_twl6040_pins {
+ pinctrl-single,pins = <
+ 0x17e (PIN_OUTPUT | MUX_MODE6) /* mcspi1_somi.gpio5_141 */
+ >;
+ };
+
+ mcpdm_pins: pinmux_mcpdm_pins {
+ pinctrl-single,pins = <
+ 0x142 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_clks.abe_clks */
+ 0x15c (PIN_INPUT_PULLDOWN | MUX_MODE0) /* abemcpdm_ul_data.abemcpdm_ul_data */
+ 0x15e (PIN_INPUT_PULLDOWN | MUX_MODE0) /* abemcpdm_dl_data.abemcpdm_dl_data */
+ 0x160 (PIN_INPUT_PULLUP | MUX_MODE0) /* abemcpdm_frame.abemcpdm_frame */
+ 0x162 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* abemcpdm_lb_clk.abemcpdm_lb_clk */
+ >;
+ };
+
+ mcbsp1_pins: pinmux_mcbsp1_pins {
+ pinctrl-single,pins = <
+ 0x14c (PIN_INPUT | MUX_MODE1) /* abedmic_clk2.abemcbsp1_fsx */
+ 0x14e (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* abedmic_clk3.abemcbsp1_dx */
+ 0x150 (PIN_INPUT | MUX_MODE1) /* abeslimbus1_clock.abemcbsp1_clkx */
+ 0x152 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* abeslimbus1_data.abemcbsp1_dr */
+ >;
+ };
+
+ mcbsp2_pins: pinmux_mcbsp2_pins {
+ pinctrl-single,pins = <
+ 0x154 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* abemcbsp2_dr.abemcbsp2_dr */
+ 0x156 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* abemcbsp2_dx.abemcbsp2_dx */
+ 0x158 (PIN_INPUT | MUX_MODE0) /* abemcbsp2_fsx.abemcbsp2_fsx */
+ 0x15a (PIN_INPUT | MUX_MODE0) /* abemcbsp2_clkx.abemcbsp2_clkx */
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ 0x1b2 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */
+ 0x1b4 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */
+ >;
+ };
+
+ i2c5_pins: pinmux_i2c5_pins {
+ pinctrl-single,pins = <
+ 0x184 (PIN_INPUT | MUX_MODE0) /* i2c5_scl */
+ 0x186 (PIN_INPUT | MUX_MODE0) /* i2c5_sda */
+ >;
+ };
+
+ mcspi2_pins: pinmux_mcspi2_pins {
+ pinctrl-single,pins = <
+ 0xbc (PIN_INPUT | MUX_MODE0) /* mcspi2_clk */
+ 0xbe (PIN_INPUT | MUX_MODE0) /* mcspi2_simo */
+ 0xc0 (PIN_INPUT_PULLUP | MUX_MODE0) /* mcspi2_somi */
+ 0xc2 (PIN_OUTPUT | MUX_MODE0) /* mcspi2_cs0 */
+ >;
+ };
+
+ mcspi3_pins: pinmux_mcspi3_pins {
+ pinctrl-single,pins = <
+ 0x78 (PIN_INPUT | MUX_MODE1) /* mcspi3_somi */
+ 0x7a (PIN_INPUT | MUX_MODE1) /* mcspi3_cs0 */
+ 0x7c (PIN_INPUT | MUX_MODE1) /* mcspi3_simo */
+ 0x7e (PIN_INPUT | MUX_MODE1) /* mcspi3_clk */
+ >;
+ };
+
+ mcspi4_pins: pinmux_mcspi4_pins {
+ pinctrl-single,pins = <
+ 0x164 (PIN_INPUT | MUX_MODE1) /* mcspi4_clk */
+ 0x168 (PIN_INPUT | MUX_MODE1) /* mcspi4_simo */
+ 0x16a (PIN_INPUT | MUX_MODE1) /* mcspi4_somi */
+ 0x16c (PIN_INPUT | MUX_MODE1) /* mcspi4_cs0 */
+ >;
+ };
+
+ usbhost_pins: pinmux_usbhost_pins {
+ pinctrl-single,pins = <
+ 0x84 (PIN_INPUT | MUX_MODE0) /* usbb2_hsic_strobe */
+ 0x86 (PIN_INPUT | MUX_MODE0) /* usbb2_hsic_data */
+
+ 0x19e (PIN_INPUT | MUX_MODE0) /* usbb3_hsic_strobe */
+ 0x1a0 (PIN_INPUT | MUX_MODE0) /* usbb3_hsic_data */
+
+ 0x70 (PIN_OUTPUT | MUX_MODE6) /* gpio3_80 HUB_NRESET */
+ 0x6e (PIN_OUTPUT | MUX_MODE6) /* gpio3_79 ETH_NRESET */
+ >;
+ };
+
+ led_gpio_pins: pinmux_led_gpio_pins {
+ pinctrl-single,pins = <
+ 0x196 (PIN_OUTPUT | MUX_MODE6) /* uart3_cts_rctx.gpio5_153 */
+ >;
+ };
+
+ uart1_pins: pinmux_uart1_pins {
+ pinctrl-single,pins = <
+ 0x60 (PIN_OUTPUT | MUX_MODE0) /* uart1_tx.uart1_cts */
+ 0x62 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_tx.uart1_cts */
+ 0x64 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rx.uart1_rts */
+ 0x66 (PIN_OUTPUT | MUX_MODE0) /* uart1_rx.uart1_rts */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ 0x19a (PIN_OUTPUT | MUX_MODE0) /* uart3_rts_irsd.uart3_tx_irtx */
+ 0x19c (PIN_INPUT_PULLUP | MUX_MODE0) /* uart3_rx_irrx.uart3_usbb3_hsic */
+ >;
+ };
+
+ uart5_pins: pinmux_uart5_pins {
+ pinctrl-single,pins = <
+ 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart5_rx.uart5_rx */
+ 0x172 (PIN_OUTPUT | MUX_MODE0) /* uart5_tx.uart5_tx */
+ 0x174 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart5_cts.uart5_rts */
+ 0x176 (PIN_OUTPUT | MUX_MODE0) /* uart5_cts.uart5_rts */
+ >;
+ };
+
+ dss_hdmi_pins: pinmux_dss_hdmi_pins {
+ pinctrl-single,pins = <
+ 0x0fc (PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */
+ 0x100 (PIN_INPUT | MUX_MODE0) /* hdmi_ddc_scl.hdmi_ddc_scl */
+ 0x102 (PIN_INPUT | MUX_MODE0) /* hdmi_ddc_sda.hdmi_ddc_sda */
+ >;
+ };
+
+ tpd12s015_pins: pinmux_tpd12s015_pins {
+ pinctrl-single,pins = <
+ 0x0fe (PIN_INPUT_PULLDOWN | MUX_MODE6) /* hdmi_hpd.gpio7_193 */
+ >;
+ };
+};
+
+&omap5_pmx_wkup {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &usbhost_wkup_pins
+ >;
+
+ usbhost_wkup_pins: pinmux_usbhost_wkup_pins {
+ pinctrl-single,pins = <
+ 0x1A (PIN_OUTPUT | MUX_MODE0) /* fref_clk1_out, USB hub clk */
+ >;
+ };
+};
+
+&mmc1 {
+ vmmc-supply = <&ldo9_reg>;
+ bus-width = <4>;
+};
+
+&mmc2 {
+ vmmc-supply = <&vmmcsd_fixed>;
+ bus-width = <8>;
+ ti,non-removable;
+};
+
+&mmc3 {
+ bus-width = <4>;
+ ti,non-removable;
+};
+
+&mmc4 {
+ status = "disabled";
+};
+
+&mmc5 {
+ status = "disabled";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+
+ clock-frequency = <400000>;
+
+ palmas: palmas@48 {
+ compatible = "ti,palmas";
+ interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */
+ reg = <0x48>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ti,system-power-controller;
+
+ extcon_usb3: palmas_usb {
+ compatible = "ti,palmas-usb-vid";
+ ti,enable-vbus-detection;
+ ti,enable-id-detection;
+ ti,wakeup;
+ };
+
+ clk32kgaudio: palmas_clk32k@1 {
+ compatible = "ti,palmas-clk32kgaudio";
+ #clock-cells = <0>;
+ };
+
+ palmas_pmic {
+ compatible = "ti,palmas-pmic";
+ interrupt-parent = <&palmas>;
+ interrupts = <14 IRQ_TYPE_NONE>;
+ interrupt-name = "short-irq";
+
+ ti,ldo6-vibrator;
+
+ regulators {
+ smps123_reg: smps123 {
+ /* VDD_OPP_MPU */
+ regulator-name = "smps123";
+ regulator-min-microvolt = < 600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps45_reg: smps45 {
+ /* VDD_OPP_MM */
+ regulator-name = "smps45";
+ regulator-min-microvolt = < 600000>;
+ regulator-max-microvolt = <1310000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps6_reg: smps6 {
+ /* VDD_DDR3 - over VDD_SMPS6 */
+ regulator-name = "smps6";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps7_reg: smps7 {
+ /* VDDS_1v8_OMAP over VDDS_1v8_MAIN */
+ regulator-name = "smps7";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps8_reg: smps8 {
+ /* VDD_OPP_CORE */
+ regulator-name = "smps8";
+ regulator-min-microvolt = < 600000>;
+ regulator-max-microvolt = <1310000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps9_reg: smps9 {
+ /* VDDA_2v1_AUD over VDD_2v1 */
+ regulator-name = "smps9";
+ regulator-min-microvolt = <2100000>;
+ regulator-max-microvolt = <2100000>;
+ ti,smps-range = <0x80>;
+ };
+
+ smps10_out2_reg: smps10_out2 {
+ /* VBUS_5V_OTG */
+ regulator-name = "smps10_out2";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps10_out1_reg: smps10_out1 {
+ /* VBUS_5V_OTG */
+ regulator-name = "smps10_out1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ ldo1_reg: ldo1 {
+ /* VDDAPHY_CAM: vdda_csiport */
+ regulator-name = "ldo1";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo2_reg: ldo2 {
+ /* VCC_2V8_DISP: Does not go anywhere */
+ regulator-name = "ldo2";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ /* Unused */
+ status = "disabled";
+ };
+
+ ldo3_reg: ldo3 {
+ /* VDDAPHY_MDM: vdda_lli */
+ regulator-name = "ldo3";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ /* Only if Modem is used */
+ status = "disabled";
+ };
+
+ ldo4_reg: ldo4 {
+ /* VDDAPHY_DISP: vdda_dsiport/hdmi */
+ regulator-name = "ldo4";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo5_reg: ldo5 {
+ /* VDDA_1V8_PHY: usb/sata/hdmi.. */
+ regulator-name = "ldo5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo6_reg: ldo6 {
+ /* VDDS_1V2_WKUP: hsic/ldo_emu_wkup */
+ regulator-name = "ldo6";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo7_reg: ldo7 {
+ /* VDD_VPP: vpp1 */
+ regulator-name = "ldo7";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ /* Only for efuse reprograming! */
+ status = "disabled";
+ };
+
+ ldo8_reg: ldo8 {
+ /* VDD_3v0: Does not go anywhere */
+ regulator-name = "ldo8";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ /* Unused */
+ status = "disabled";
+ };
+
+ ldo9_reg: ldo9 {
+ /* VCC_DV_SDIO: vdds_sdcard */
+ regulator-name = "ldo9";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ };
+
+ ldoln_reg: ldoln {
+ /* VDDA_1v8_REF: vdds_osc/mm_l4per.. */
+ regulator-name = "ldoln";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldousb_reg: ldousb {
+ /* VDDA_3V_USB: VDDA_USBHS33 */
+ regulator-name = "ldousb";
+ regulator-min-microvolt = <3250000>;
+ regulator-max-microvolt = <3250000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ regen3_reg: regen3 {
+ /* REGEN3 controls LDO9 supply to card */
+ regulator-name = "regen3";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+ };
+
+ twl6040: twl@4b {
+ compatible = "ti,twl6040";
+ reg = <0x4b>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&twl6040_pins>;
+
+ interrupts = <GIC_SPI 119 IRQ_TYPE_NONE>; /* IRQ_SYS_2N cascaded to gic */
+ ti,audpwron-gpio = <&gpio5 13 0>; /* gpio line 141 */
+
+ vio-supply = <&smps7_reg>;
+ v2v1-supply = <&smps9_reg>;
+ enable-active-high;
+
+ clocks = <&clk32kgaudio>;
+ clock-names = "clk32k";
+ };
+};
+
+&i2c5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5_pins>;
+
+ clock-frequency = <400000>;
+
+ gpio9: gpio@22 {
+ compatible = "ti,tca6424";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&mcpdm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcpdm_pins>;
+ status = "okay";
+};
+
+&mcbsp1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcbsp1_pins>;
+ status = "okay";
+};
+
+&mcbsp2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcbsp2_pins>;
+ status = "okay";
+};
+
+&usbhshost {
+ port2-mode = "ehci-hsic";
+ port3-mode = "ehci-hsic";
+};
+
+&usbhsehci {
+ phys = <0 &hsusb2_phy &hsusb3_phy>;
+};
+
+&usb3 {
+ extcon = <&extcon_usb3>;
+ vbus-supply = <&smps10_out1_reg>;
+};
+
+&mcspi1 {
+
+};
+
+&mcspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi2_pins>;
+};
+
+&mcspi3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi3_pins>;
+};
+
+&mcspi4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi4_pins>;
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+};
+
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart5_pins>;
+};
+
+&cpu0 {
+ cpu0-supply = <&smps123_reg>;
+};
+
+&dss {
+ status = "ok";
+};
+
+&hdmi {
+ status = "ok";
+ vdda-supply = <&ldo4_reg>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_hdmi_pins>;
+
+ port {
+ hdmi_out: endpoint {
+ remote-endpoint = <&tpd12s015_in>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
new file mode 100644
index 000000000..7d24ae030
--- /dev/null
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -0,0 +1,1136 @@
+/*
+ * Copyright (C) 2012 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.
+ * Based on "omap4.dtsi"
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/omap.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ compatible = "ti,omap5";
+ interrupt-parent = <&wakeupgen>;
+
+ aliases {
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ i2c2 = &i2c3;
+ i2c3 = &i2c4;
+ i2c4 = &i2c5;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ serial5 = &uart6;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x0>;
+
+ operating-points = <
+ /* kHz uV */
+ 1000000 1060000
+ 1500000 1250000
+ >;
+
+ clocks = <&dpll_mpu_ck>;
+ clock-names = "cpu";
+
+ clock-latency = <300000>; /* From omap-cpufreq driver */
+
+ /* cooling options */
+ cooling-min-level = <0>;
+ cooling-max-level = <2>;
+ #cooling-cells = <2>; /* min followed by max */
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x1>;
+ };
+ };
+
+ thermal-zones {
+ #include "omap4-cpu-thermal.dtsi"
+ #include "omap5-gpu-thermal.dtsi"
+ #include "omap5-core-thermal.dtsi"
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ /* PPI secure/nonsecure IRQ */
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-parent = <&gic>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a15-pmu";
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gic: interrupt-controller@48211000 {
+ compatible = "arm,cortex-a15-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x48211000 0x1000>,
+ <0x48212000 0x1000>,
+ <0x48214000 0x2000>,
+ <0x48216000 0x2000>;
+ interrupt-parent = <&gic>;
+ };
+
+ wakeupgen: interrupt-controller@48281000 {
+ compatible = "ti,omap5-wugen-mpu", "ti,omap4-wugen-mpu";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x48281000 0x1000>;
+ interrupt-parent = <&gic>;
+ };
+
+ /*
+ * The soc node represents the soc top level view. It is used for IPs
+ * that are not memory mapped in the MPU view or for the MPU itself.
+ */
+ soc {
+ compatible = "ti,omap-infra";
+ mpu {
+ compatible = "ti,omap4-mpu";
+ ti,hwmods = "mpu";
+ sram = <&ocmcram>;
+ };
+ };
+
+ /*
+ * XXX: Use a flat representation of the OMAP3 interconnect.
+ * The real OMAP interconnect network is quite complex.
+ * Since it will not bring real advantage to represent that in DT for
+ * the moment, just use a fake OCP bus entry to represent the whole bus
+ * hierarchy.
+ */
+ ocp {
+ compatible = "ti,omap5-l3-noc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3";
+ reg = <0x44000000 0x2000>,
+ <0x44800000 0x3000>,
+ <0x45000000 0x4000>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+
+ l4_cfg: l4@4a000000 {
+ compatible = "ti,omap5-l4-cfg", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x4a000000 0x22a000>;
+
+ scm_core: scm@2000 {
+ compatible = "ti,omap5-scm-core", "simple-bus";
+ reg = <0x2000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x2000 0x800>;
+
+ scm_conf: scm_conf@0 {
+ compatible = "syscon";
+ reg = <0x0 0x800>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
+
+ scm_padconf_core: scm@2800 {
+ compatible = "ti,omap5-scm-padconf-core",
+ "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x2800 0x800>;
+
+ omap5_pmx_core: pinmux@40 {
+ compatible = "ti,omap5-padconf",
+ "pinctrl-single";
+ reg = <0x40 0x01b6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ pinctrl-single,register-width = <16>;
+ pinctrl-single,function-mask = <0x7fff>;
+ };
+
+ omap5_padconf_global: omap5_padconf_global@5a0 {
+ compatible = "syscon";
+ reg = <0x5a0 0xec>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ pbias_regulator: pbias_regulator {
+ compatible = "ti,pbias-omap";
+ reg = <0x60 0x4>;
+ syscon = <&omap5_padconf_global>;
+ pbias_mmc_reg: pbias_mmc_omap5 {
+ regulator-name = "pbias_mmc_omap5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ };
+ };
+ };
+ };
+
+ cm_core_aon: cm_core_aon@4000 {
+ compatible = "ti,omap5-cm-core-aon";
+ reg = <0x4000 0x2000>;
+
+ cm_core_aon_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cm_core_aon_clockdomains: clockdomains {
+ };
+ };
+
+ cm_core: cm_core@8000 {
+ compatible = "ti,omap5-cm-core";
+ reg = <0x8000 0x3000>;
+
+ cm_core_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cm_core_clockdomains: clockdomains {
+ };
+ };
+ };
+
+ l4_wkup: l4@4ae00000 {
+ compatible = "ti,omap5-l4-wkup", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x4ae00000 0x2b000>;
+
+ counter32k: counter@4000 {
+ compatible = "ti,omap-counter32k";
+ reg = <0x4000 0x40>;
+ ti,hwmods = "counter_32k";
+ };
+
+ prm: prm@6000 {
+ compatible = "ti,omap5-prm";
+ reg = <0x6000 0x3000>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+
+ prm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ prm_clockdomains: clockdomains {
+ };
+ };
+
+ scrm: scrm@a000 {
+ compatible = "ti,omap5-scrm";
+ reg = <0xa000 0x2000>;
+
+ scrm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ scrm_clockdomains: clockdomains {
+ };
+ };
+
+ omap5_pmx_wkup: pinmux@c840 {
+ compatible = "ti,omap5-padconf",
+ "pinctrl-single";
+ reg = <0xc840 0x0038>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ pinctrl-single,register-width = <16>;
+ pinctrl-single,function-mask = <0x7fff>;
+ };
+ };
+
+ ocmcram: ocmcram@40300000 {
+ compatible = "mmio-sram";
+ reg = <0x40300000 0x20000>; /* 128k */
+ };
+
+ sdma: dma-controller@4a056000 {
+ compatible = "ti,omap4430-sdma";
+ reg = <0x4a056000 0x1000>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ dma-channels = <32>;
+ dma-requests = <127>;
+ };
+
+ gpio1: gpio@4ae10000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x4ae10000 0x200>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio1";
+ ti,gpio-always-on;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@48055000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x48055000 0x200>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio2";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@48057000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x48057000 0x200>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio3";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@48059000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x48059000 0x200>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio4";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio5: gpio@4805b000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x4805b000 0x200>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio5";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio6: gpio@4805d000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x4805d000 0x200>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio6";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio7: gpio@48051000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x48051000 0x200>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio7";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio8: gpio@48053000 {
+ compatible = "ti,omap4-gpio";
+ reg = <0x48053000 0x200>;
+ interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "gpio8";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpmc: gpmc@50000000 {
+ compatible = "ti,omap4430-gpmc";
+ reg = <0x50000000 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ gpmc,num-cs = <8>;
+ gpmc,num-waitpins = <4>;
+ ti,hwmods = "gpmc";
+ clocks = <&l3_iclk_div>;
+ clock-names = "fck";
+ };
+
+ i2c1: i2c@48070000 {
+ compatible = "ti,omap4-i2c";
+ reg = <0x48070000 0x100>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c1";
+ };
+
+ i2c2: i2c@48072000 {
+ compatible = "ti,omap4-i2c";
+ reg = <0x48072000 0x100>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c2";
+ };
+
+ i2c3: i2c@48060000 {
+ compatible = "ti,omap4-i2c";
+ reg = <0x48060000 0x100>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c3";
+ };
+
+ i2c4: i2c@4807a000 {
+ compatible = "ti,omap4-i2c";
+ reg = <0x4807a000 0x100>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c4";
+ };
+
+ i2c5: i2c@4807c000 {
+ compatible = "ti,omap4-i2c";
+ reg = <0x4807c000 0x100>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "i2c5";
+ };
+
+ hwspinlock: spinlock@4a0f6000 {
+ compatible = "ti,omap4-hwspinlock";
+ reg = <0x4a0f6000 0x1000>;
+ ti,hwmods = "spinlock";
+ #hwlock-cells = <1>;
+ };
+
+ mcspi1: spi@48098000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x48098000 0x200>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi1";
+ ti,spi-num-cs = <4>;
+ dmas = <&sdma 35>,
+ <&sdma 36>,
+ <&sdma 37>,
+ <&sdma 38>,
+ <&sdma 39>,
+ <&sdma 40>,
+ <&sdma 41>,
+ <&sdma 42>;
+ dma-names = "tx0", "rx0", "tx1", "rx1",
+ "tx2", "rx2", "tx3", "rx3";
+ };
+
+ mcspi2: spi@4809a000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x4809a000 0x200>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi2";
+ ti,spi-num-cs = <2>;
+ dmas = <&sdma 43>,
+ <&sdma 44>,
+ <&sdma 45>,
+ <&sdma 46>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
+ };
+
+ mcspi3: spi@480b8000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x480b8000 0x200>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi3";
+ ti,spi-num-cs = <2>;
+ dmas = <&sdma 15>, <&sdma 16>;
+ dma-names = "tx0", "rx0";
+ };
+
+ mcspi4: spi@480ba000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x480ba000 0x200>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi4";
+ ti,spi-num-cs = <1>;
+ dmas = <&sdma 70>, <&sdma 71>;
+ dma-names = "tx0", "rx0";
+ };
+
+ uart1: serial@4806a000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x4806a000 0x100>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart1";
+ clock-frequency = <48000000>;
+ };
+
+ uart2: serial@4806c000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x4806c000 0x100>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart2";
+ clock-frequency = <48000000>;
+ };
+
+ uart3: serial@48020000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x48020000 0x100>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart3";
+ clock-frequency = <48000000>;
+ };
+
+ uart4: serial@4806e000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x4806e000 0x100>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart4";
+ clock-frequency = <48000000>;
+ };
+
+ uart5: serial@48066000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x48066000 0x100>;
+ interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart5";
+ clock-frequency = <48000000>;
+ };
+
+ uart6: serial@48068000 {
+ compatible = "ti,omap4-uart";
+ reg = <0x48068000 0x100>;
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "uart6";
+ clock-frequency = <48000000>;
+ };
+
+ mmc1: mmc@4809c000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x4809c000 0x400>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmc1";
+ ti,dual-volt;
+ ti,needs-special-reset;
+ dmas = <&sdma 61>, <&sdma 62>;
+ dma-names = "tx", "rx";
+ pbias-supply = <&pbias_mmc_reg>;
+ };
+
+ mmc2: mmc@480b4000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x480b4000 0x400>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmc2";
+ ti,needs-special-reset;
+ dmas = <&sdma 47>, <&sdma 48>;
+ dma-names = "tx", "rx";
+ };
+
+ mmc3: mmc@480ad000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x480ad000 0x400>;
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmc3";
+ ti,needs-special-reset;
+ dmas = <&sdma 77>, <&sdma 78>;
+ dma-names = "tx", "rx";
+ };
+
+ mmc4: mmc@480d1000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x480d1000 0x400>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmc4";
+ ti,needs-special-reset;
+ dmas = <&sdma 57>, <&sdma 58>;
+ dma-names = "tx", "rx";
+ };
+
+ mmc5: mmc@480d5000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x480d5000 0x400>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmc5";
+ ti,needs-special-reset;
+ dmas = <&sdma 59>, <&sdma 60>;
+ dma-names = "tx", "rx";
+ };
+
+ mmu_dsp: mmu@4a066000 {
+ compatible = "ti,omap4-iommu";
+ reg = <0x4a066000 0x100>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmu_dsp";
+ };
+
+ mmu_ipu: mmu@55082000 {
+ compatible = "ti,omap4-iommu";
+ reg = <0x55082000 0x100>;
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmu_ipu";
+ ti,iommu-bus-err-back;
+ };
+
+ keypad: keypad@4ae1c000 {
+ compatible = "ti,omap4-keypad";
+ reg = <0x4ae1c000 0x400>;
+ ti,hwmods = "kbd";
+ };
+
+ mcpdm: mcpdm@40132000 {
+ compatible = "ti,omap4-mcpdm";
+ reg = <0x40132000 0x7f>, /* MPU private access */
+ <0x49032000 0x7f>; /* L3 Interconnect */
+ reg-names = "mpu", "dma";
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mcpdm";
+ dmas = <&sdma 65>,
+ <&sdma 66>;
+ dma-names = "up_link", "dn_link";
+ status = "disabled";
+ };
+
+ dmic: dmic@4012e000 {
+ compatible = "ti,omap4-dmic";
+ reg = <0x4012e000 0x7f>, /* MPU private access */
+ <0x4902e000 0x7f>; /* L3 Interconnect */
+ reg-names = "mpu", "dma";
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "dmic";
+ dmas = <&sdma 67>;
+ dma-names = "up_link";
+ status = "disabled";
+ };
+
+ mcbsp1: mcbsp@40122000 {
+ compatible = "ti,omap4-mcbsp";
+ reg = <0x40122000 0xff>, /* MPU private access */
+ <0x49022000 0xff>; /* L3 Interconnect */
+ reg-names = "mpu", "dma";
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "common";
+ ti,buffer-size = <128>;
+ ti,hwmods = "mcbsp1";
+ dmas = <&sdma 33>,
+ <&sdma 34>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mcbsp2: mcbsp@40124000 {
+ compatible = "ti,omap4-mcbsp";
+ reg = <0x40124000 0xff>, /* MPU private access */
+ <0x49024000 0xff>; /* L3 Interconnect */
+ reg-names = "mpu", "dma";
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "common";
+ ti,buffer-size = <128>;
+ ti,hwmods = "mcbsp2";
+ dmas = <&sdma 17>,
+ <&sdma 18>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mcbsp3: mcbsp@40126000 {
+ compatible = "ti,omap4-mcbsp";
+ reg = <0x40126000 0xff>, /* MPU private access */
+ <0x49026000 0xff>; /* L3 Interconnect */
+ reg-names = "mpu", "dma";
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "common";
+ ti,buffer-size = <128>;
+ ti,hwmods = "mcbsp3";
+ dmas = <&sdma 19>,
+ <&sdma 20>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mailbox: mailbox@4a0f4000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x4a0f4000 0x200>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mailbox";
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <3>;
+ ti,mbox-num-fifos = <8>;
+ mbox_ipu: mbox_ipu {
+ ti,mbox-tx = <0 0 0>;
+ ti,mbox-rx = <1 0 0>;
+ };
+ mbox_dsp: mbox_dsp {
+ ti,mbox-tx = <3 0 0>;
+ ti,mbox-rx = <2 0 0>;
+ };
+ };
+
+ timer1: timer@4ae18000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x4ae18000 0x80>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer1";
+ ti,timer-alwon;
+ };
+
+ timer2: timer@48032000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x48032000 0x80>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer2";
+ };
+
+ timer3: timer@48034000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x48034000 0x80>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer3";
+ };
+
+ timer4: timer@48036000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x48036000 0x80>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer4";
+ };
+
+ timer5: timer@40138000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x40138000 0x80>,
+ <0x49038000 0x80>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer5";
+ ti,timer-dsp;
+ ti,timer-pwm;
+ };
+
+ timer6: timer@4013a000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x4013a000 0x80>,
+ <0x4903a000 0x80>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer6";
+ ti,timer-dsp;
+ ti,timer-pwm;
+ };
+
+ timer7: timer@4013c000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x4013c000 0x80>,
+ <0x4903c000 0x80>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer7";
+ ti,timer-dsp;
+ };
+
+ timer8: timer@4013e000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x4013e000 0x80>,
+ <0x4903e000 0x80>;
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer8";
+ ti,timer-dsp;
+ ti,timer-pwm;
+ };
+
+ timer9: timer@4803e000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x4803e000 0x80>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer9";
+ ti,timer-pwm;
+ };
+
+ timer10: timer@48086000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x48086000 0x80>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer10";
+ ti,timer-pwm;
+ };
+
+ timer11: timer@48088000 {
+ compatible = "ti,omap5430-timer";
+ reg = <0x48088000 0x80>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "timer11";
+ ti,timer-pwm;
+ };
+
+ wdt2: wdt@4ae14000 {
+ compatible = "ti,omap5-wdt", "ti,omap3-wdt";
+ reg = <0x4ae14000 0x80>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "wd_timer2";
+ };
+
+ dmm@4e000000 {
+ compatible = "ti,omap5-dmm";
+ reg = <0x4e000000 0x800>;
+ interrupts = <0 113 0x4>;
+ ti,hwmods = "dmm";
+ };
+
+ emif1: emif@4c000000 {
+ compatible = "ti,emif-4d5";
+ ti,hwmods = "emif1";
+ ti,no-idle-on-init;
+ phy-type = <2>; /* DDR PHY type: Intelli PHY */
+ reg = <0x4c000000 0x400>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+ hw-caps-read-idle-ctrl;
+ hw-caps-ll-interface;
+ hw-caps-temp-alert;
+ };
+
+ emif2: emif@4d000000 {
+ compatible = "ti,emif-4d5";
+ ti,hwmods = "emif2";
+ ti,no-idle-on-init;
+ phy-type = <2>; /* DDR PHY type: Intelli PHY */
+ reg = <0x4d000000 0x400>;
+ interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+ hw-caps-read-idle-ctrl;
+ hw-caps-ll-interface;
+ hw-caps-temp-alert;
+ };
+
+ omap_control_usb2phy: control-phy@4a002300 {
+ compatible = "ti,control-phy-usb2";
+ reg = <0x4a002300 0x4>;
+ reg-names = "power";
+ };
+
+ omap_control_usb3phy: control-phy@4a002370 {
+ compatible = "ti,control-phy-pipe3";
+ reg = <0x4a002370 0x4>;
+ reg-names = "power";
+ };
+
+ usb3: omap_dwc3@4a020000 {
+ compatible = "ti,dwc3";
+ ti,hwmods = "usb_otg_ss";
+ reg = <0x4a020000 0x10000>;
+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ utmi-mode = <2>;
+ ranges;
+ dwc3@4a030000 {
+ compatible = "snps,dwc3";
+ reg = <0x4a030000 0x10000>;
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb2_phy>, <&usb3_phy>;
+ phy-names = "usb2-phy", "usb3-phy";
+ dr_mode = "peripheral";
+ tx-fifo-resize;
+ };
+ };
+
+ ocp2scp@4a080000 {
+ compatible = "ti,omap-ocp2scp";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x4a080000 0x20>;
+ ranges;
+ ti,hwmods = "ocp2scp1";
+ usb2_phy: usb2phy@4a084000 {
+ compatible = "ti,omap-usb2";
+ reg = <0x4a084000 0x7c>;
+ ctrl-module = <&omap_control_usb2phy>;
+ clocks = <&usb_phy_cm_clk32k>, <&usb_otg_ss_refclk960m>;
+ clock-names = "wkupclk", "refclk";
+ #phy-cells = <0>;
+ };
+
+ usb3_phy: usb3phy@4a084400 {
+ compatible = "ti,omap-usb3";
+ reg = <0x4a084400 0x80>,
+ <0x4a084800 0x64>,
+ <0x4a084c00 0x40>;
+ reg-names = "phy_rx", "phy_tx", "pll_ctrl";
+ ctrl-module = <&omap_control_usb3phy>;
+ clocks = <&usb_phy_cm_clk32k>,
+ <&sys_clkin>,
+ <&usb_otg_ss_refclk960m>;
+ clock-names = "wkupclk",
+ "sysclk",
+ "refclk";
+ #phy-cells = <0>;
+ };
+ };
+
+ usbhstll: usbhstll@4a062000 {
+ compatible = "ti,usbhs-tll";
+ reg = <0x4a062000 0x1000>;
+ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "usb_tll_hs";
+ };
+
+ usbhshost: usbhshost@4a064000 {
+ compatible = "ti,usbhs-host";
+ reg = <0x4a064000 0x800>;
+ ti,hwmods = "usb_host_hs";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ clocks = <&l3init_60m_fclk>,
+ <&xclk60mhsp1_ck>,
+ <&xclk60mhsp2_ck>;
+ clock-names = "refclk_60m_int",
+ "refclk_60m_ext_p1",
+ "refclk_60m_ext_p2";
+
+ usbhsohci: ohci@4a064800 {
+ compatible = "ti,ohci-omap3";
+ reg = <0x4a064800 0x400>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ usbhsehci: ehci@4a064c00 {
+ compatible = "ti,ehci-omap";
+ reg = <0x4a064c00 0x400>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ bandgap: bandgap@4a0021e0 {
+ reg = <0x4a0021e0 0xc
+ 0x4a00232c 0xc
+ 0x4a002380 0x2c
+ 0x4a0023C0 0x3c>;
+ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+ compatible = "ti,omap5430-bandgap";
+
+ #thermal-sensor-cells = <1>;
+ };
+
+ omap_control_sata: control-phy@4a002374 {
+ compatible = "ti,control-phy-pipe3";
+ reg = <0x4a002374 0x4>;
+ reg-names = "power";
+ clocks = <&sys_clkin>;
+ clock-names = "sysclk";
+ };
+
+ /* OCP2SCP3 */
+ ocp2scp@4a090000 {
+ compatible = "ti,omap-ocp2scp";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x4a090000 0x20>;
+ ranges;
+ ti,hwmods = "ocp2scp3";
+ sata_phy: phy@4a096000 {
+ compatible = "ti,phy-pipe3-sata";
+ reg = <0x4A096000 0x80>, /* phy_rx */
+ <0x4A096400 0x64>, /* phy_tx */
+ <0x4A096800 0x40>; /* pll_ctrl */
+ reg-names = "phy_rx", "phy_tx", "pll_ctrl";
+ ctrl-module = <&omap_control_sata>;
+ clocks = <&sys_clkin>, <&sata_ref_clk>;
+ clock-names = "sysclk", "refclk";
+ #phy-cells = <0>;
+ };
+ };
+
+ sata: sata@4a141100 {
+ compatible = "snps,dwc-ahci";
+ reg = <0x4a140000 0x1100>, <0x4a141100 0x7>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&sata_phy>;
+ phy-names = "sata-phy";
+ clocks = <&sata_ref_clk>;
+ ti,hwmods = "sata";
+ };
+
+ dss: dss@58000000 {
+ compatible = "ti,omap5-dss";
+ reg = <0x58000000 0x80>;
+ status = "disabled";
+ ti,hwmods = "dss_core";
+ clocks = <&dss_dss_clk>;
+ clock-names = "fck";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dispc@58001000 {
+ compatible = "ti,omap5-dispc";
+ reg = <0x58001000 0x1000>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "dss_dispc";
+ clocks = <&dss_dss_clk>;
+ clock-names = "fck";
+ };
+
+ rfbi: encoder@58002000 {
+ compatible = "ti,omap5-rfbi";
+ reg = <0x58002000 0x100>;
+ status = "disabled";
+ ti,hwmods = "dss_rfbi";
+ clocks = <&dss_dss_clk>, <&l3_iclk_div>;
+ clock-names = "fck", "ick";
+ };
+
+ dsi1: encoder@58004000 {
+ compatible = "ti,omap5-dsi";
+ reg = <0x58004000 0x200>,
+ <0x58004200 0x40>,
+ <0x58004300 0x40>;
+ reg-names = "proto", "phy", "pll";
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ ti,hwmods = "dss_dsi1";
+ clocks = <&dss_dss_clk>, <&dss_sys_clk>;
+ clock-names = "fck", "sys_clk";
+ };
+
+ dsi2: encoder@58005000 {
+ compatible = "ti,omap5-dsi";
+ reg = <0x58009000 0x200>,
+ <0x58009200 0x40>,
+ <0x58009300 0x40>;
+ reg-names = "proto", "phy", "pll";
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ ti,hwmods = "dss_dsi2";
+ clocks = <&dss_dss_clk>, <&dss_sys_clk>;
+ clock-names = "fck", "sys_clk";
+ };
+
+ hdmi: encoder@58060000 {
+ compatible = "ti,omap5-hdmi";
+ reg = <0x58040000 0x200>,
+ <0x58040200 0x80>,
+ <0x58040300 0x80>,
+ <0x58060000 0x19000>;
+ reg-names = "wp", "pll", "phy", "core";
+ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ ti,hwmods = "dss_hdmi";
+ clocks = <&dss_48mhz_clk>, <&dss_sys_clk>;
+ clock-names = "fck", "sys_clk";
+ dmas = <&sdma 76>;
+ dma-names = "audio_tx";
+ };
+ };
+
+ abb_mpu: regulator-abb-mpu {
+ compatible = "ti,abb-v2";
+ regulator-name = "abb_mpu";
+ #address-cells = <0>;
+ #size-cells = <0>;
+ clocks = <&sys_clkin>;
+ ti,settling-time = <50>;
+ ti,clock-cycles = <16>;
+
+ reg = <0x4ae07cdc 0x8>, <0x4ae06014 0x4>,
+ <0x4a0021c4 0x8>, <0x4ae0c318 0x4>;
+ reg-names = "base-address", "int-address",
+ "efuse-address", "ldo-address";
+ ti,tranxdone-status-mask = <0x80>;
+ /* LDOVBBMPU_MUX_CTRL */
+ ti,ldovbb-override-mask = <0x400>;
+ /* LDOVBBMPU_VSET_OUT */
+ ti,ldovbb-vset-mask = <0x1F>;
+
+ /*
+ * NOTE: only FBB mode used but actual vset will
+ * determine final biasing
+ */
+ ti,abb_info = <
+ /*uV ABB efuse rbb_m fbb_m vset_m*/
+ 1060000 0 0x0 0 0x02000000 0x01F00000
+ 1250000 0 0x4 0 0x02000000 0x01F00000
+ >;
+ };
+
+ abb_mm: regulator-abb-mm {
+ compatible = "ti,abb-v2";
+ regulator-name = "abb_mm";
+ #address-cells = <0>;
+ #size-cells = <0>;
+ clocks = <&sys_clkin>;
+ ti,settling-time = <50>;
+ ti,clock-cycles = <16>;
+
+ reg = <0x4ae07ce4 0x8>, <0x4ae06010 0x4>,
+ <0x4a0021a4 0x8>, <0x4ae0c314 0x4>;
+ reg-names = "base-address", "int-address",
+ "efuse-address", "ldo-address";
+ ti,tranxdone-status-mask = <0x80000000>;
+ /* LDOVBBMM_MUX_CTRL */
+ ti,ldovbb-override-mask = <0x400>;
+ /* LDOVBBMM_VSET_OUT */
+ ti,ldovbb-vset-mask = <0x1F>;
+
+ /*
+ * NOTE: only FBB mode used but actual vset will
+ * determine final biasing
+ */
+ ti,abb_info = <
+ /*uV ABB efuse rbb_m fbb_m vset_m*/
+ 1025000 0 0x0 0 0x02000000 0x01F00000
+ 1120000 0 0x4 0 0x02000000 0x01F00000
+ >;
+ };
+ };
+};
+
+&cpu_thermal {
+ polling-delay = <500>; /* milliseconds */
+};
+
+/include/ "omap54xx-clocks.dtsi"
diff --git a/arch/arm/boot/dts/omap54xx-clocks.dtsi b/arch/arm/boot/dts/omap54xx-clocks.dtsi
new file mode 100644
index 000000000..83b425fb3
--- /dev/null
+++ b/arch/arm/boot/dts/omap54xx-clocks.dtsi
@@ -0,0 +1,1390 @@
+/*
+ * Device Tree Source for OMAP5 clock data
+ *
+ * Copyright (C) 2013 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.
+ */
+&cm_core_aon_clocks {
+ pad_clks_src_ck: pad_clks_src_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ pad_clks_ck: pad_clks_ck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&pad_clks_src_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0108>;
+ };
+
+ secure_32k_clk_src_ck: secure_32k_clk_src_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ slimbus_src_clk: slimbus_src_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ slimbus_clk: slimbus_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&slimbus_src_clk>;
+ ti,bit-shift = <10>;
+ reg = <0x0108>;
+ };
+
+ sys_32k_ck: sys_32k_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ virt_12000000_ck: virt_12000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ virt_13000000_ck: virt_13000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ };
+
+ virt_16800000_ck: virt_16800000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <16800000>;
+ };
+
+ virt_19200000_ck: virt_19200000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <19200000>;
+ };
+
+ virt_26000000_ck: virt_26000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ };
+
+ virt_27000000_ck: virt_27000000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <27000000>;
+ };
+
+ virt_38400000_ck: virt_38400000_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <38400000>;
+ };
+
+ xclk60mhsp1_ck: xclk60mhsp1_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <60000000>;
+ };
+
+ xclk60mhsp2_ck: xclk60mhsp2_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <60000000>;
+ };
+
+ dpll_abe_ck: dpll_abe_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-m4xen-clock";
+ clocks = <&abe_dpll_clk_mux>, <&abe_dpll_bypass_clk_mux>;
+ reg = <0x01e0>, <0x01e4>, <0x01ec>, <0x01e8>;
+ };
+
+ dpll_abe_x2_ck: dpll_abe_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-x2-clock";
+ clocks = <&dpll_abe_ck>;
+ };
+
+ dpll_abe_m2x2_ck: dpll_abe_m2x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_abe_x2_ck>;
+ ti,max-div = <31>;
+ reg = <0x01f0>;
+ ti,index-starts-at-one;
+ };
+
+ abe_24m_fclk: abe_24m_fclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_abe_m2x2_ck>;
+ clock-mult = <1>;
+ clock-div = <8>;
+ };
+
+ abe_clk: abe_clk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_abe_m2x2_ck>;
+ ti,max-div = <4>;
+ reg = <0x0108>;
+ ti,index-power-of-two;
+ };
+
+ abe_iclk: abe_iclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&aess_fclk>;
+ ti,bit-shift = <24>;
+ reg = <0x0528>;
+ ti,dividers = <2>, <1>;
+ };
+
+ abe_lp_clk_div: abe_lp_clk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_abe_m2x2_ck>;
+ clock-mult = <1>;
+ clock-div = <16>;
+ };
+
+ dpll_abe_m3x2_ck: dpll_abe_m3x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_abe_x2_ck>;
+ ti,max-div = <31>;
+ reg = <0x01f4>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_core_byp_mux: dpll_core_byp_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin>, <&dpll_abe_m3x2_ck>;
+ ti,bit-shift = <23>;
+ reg = <0x012c>;
+ };
+
+ dpll_core_ck: dpll_core_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-core-clock";
+ clocks = <&sys_clkin>, <&dpll_core_byp_mux>;
+ reg = <0x0120>, <0x0124>, <0x012c>, <0x0128>;
+ };
+
+ dpll_core_x2_ck: dpll_core_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-x2-clock";
+ clocks = <&dpll_core_ck>;
+ };
+
+ dpll_core_h21x2_ck: dpll_core_h21x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <63>;
+ reg = <0x0150>;
+ ti,index-starts-at-one;
+ };
+
+ c2c_fclk: c2c_fclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_h21x2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ c2c_iclk: c2c_iclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&c2c_fclk>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ dpll_core_h11x2_ck: dpll_core_h11x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <63>;
+ reg = <0x0138>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_core_h12x2_ck: dpll_core_h12x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <63>;
+ reg = <0x013c>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_core_h13x2_ck: dpll_core_h13x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <63>;
+ reg = <0x0140>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_core_h14x2_ck: dpll_core_h14x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <63>;
+ reg = <0x0144>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_core_h22x2_ck: dpll_core_h22x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <63>;
+ reg = <0x0154>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_core_h23x2_ck: dpll_core_h23x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <63>;
+ reg = <0x0158>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_core_h24x2_ck: dpll_core_h24x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <63>;
+ reg = <0x015c>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_core_m2_ck: dpll_core_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_ck>;
+ ti,max-div = <31>;
+ reg = <0x0130>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_core_m3x2_ck: dpll_core_m3x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_core_x2_ck>;
+ ti,max-div = <31>;
+ reg = <0x0134>;
+ ti,index-starts-at-one;
+ };
+
+ iva_dpll_hs_clk_div: iva_dpll_hs_clk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_h12x2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll_iva_byp_mux: dpll_iva_byp_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin>, <&iva_dpll_hs_clk_div>;
+ ti,bit-shift = <23>;
+ reg = <0x01ac>;
+ };
+
+ dpll_iva_ck: dpll_iva_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-clock";
+ clocks = <&sys_clkin>, <&dpll_iva_byp_mux>;
+ reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>;
+ };
+
+ dpll_iva_x2_ck: dpll_iva_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-x2-clock";
+ clocks = <&dpll_iva_ck>;
+ };
+
+ dpll_iva_h11x2_ck: dpll_iva_h11x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_iva_x2_ck>;
+ ti,max-div = <63>;
+ reg = <0x01b8>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_iva_h12x2_ck: dpll_iva_h12x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_iva_x2_ck>;
+ ti,max-div = <63>;
+ reg = <0x01bc>;
+ ti,index-starts-at-one;
+ };
+
+ mpu_dpll_hs_clk_div: mpu_dpll_hs_clk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_core_h12x2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll_mpu_ck: dpll_mpu_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap5-mpu-dpll-clock";
+ clocks = <&sys_clkin>, <&mpu_dpll_hs_clk_div>;
+ reg = <0x0160>, <0x0164>, <0x016c>, <0x0168>;
+ };
+
+ dpll_mpu_m2_ck: dpll_mpu_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_mpu_ck>;
+ ti,max-div = <31>;
+ reg = <0x0170>;
+ ti,index-starts-at-one;
+ };
+
+ per_dpll_hs_clk_div: per_dpll_hs_clk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_abe_m3x2_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ usb_dpll_hs_clk_div: usb_dpll_hs_clk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_abe_m3x2_ck>;
+ clock-mult = <1>;
+ clock-div = <3>;
+ };
+
+ l3_iclk_div: l3_iclk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ ti,max-div = <2>;
+ ti,bit-shift = <4>;
+ reg = <0x100>;
+ clocks = <&dpll_core_h12x2_ck>;
+ ti,index-power-of-two;
+ };
+
+ gpu_l3_iclk: gpu_l3_iclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&l3_iclk_div>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ l4_root_clk_div: l4_root_clk_div {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ ti,max-div = <2>;
+ ti,bit-shift = <8>;
+ reg = <0x100>;
+ clocks = <&l3_iclk_div>;
+ ti,index-power-of-two;
+ };
+
+ slimbus1_slimbus_clk: slimbus1_slimbus_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&slimbus_clk>;
+ ti,bit-shift = <11>;
+ reg = <0x0560>;
+ };
+
+ aess_fclk: aess_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&abe_clk>;
+ ti,bit-shift = <24>;
+ ti,max-div = <2>;
+ reg = <0x0528>;
+ };
+
+ dmic_sync_mux_ck: dmic_sync_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&dss_syc_gfclk_div>, <&func_24m_clk>;
+ ti,bit-shift = <26>;
+ reg = <0x0538>;
+ };
+
+ dmic_gfclk: dmic_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dmic_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x0538>;
+ };
+
+ mcasp_sync_mux_ck: mcasp_sync_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&dss_syc_gfclk_div>, <&func_24m_clk>;
+ ti,bit-shift = <26>;
+ reg = <0x0540>;
+ };
+
+ mcasp_gfclk: mcasp_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&mcasp_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x0540>;
+ };
+
+ mcbsp1_sync_mux_ck: mcbsp1_sync_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&dss_syc_gfclk_div>, <&func_24m_clk>;
+ ti,bit-shift = <26>;
+ reg = <0x0548>;
+ };
+
+ mcbsp1_gfclk: mcbsp1_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&mcbsp1_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x0548>;
+ };
+
+ mcbsp2_sync_mux_ck: mcbsp2_sync_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&dss_syc_gfclk_div>, <&func_24m_clk>;
+ ti,bit-shift = <26>;
+ reg = <0x0550>;
+ };
+
+ mcbsp2_gfclk: mcbsp2_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&mcbsp2_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x0550>;
+ };
+
+ mcbsp3_sync_mux_ck: mcbsp3_sync_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&abe_24m_fclk>, <&dss_syc_gfclk_div>, <&func_24m_clk>;
+ ti,bit-shift = <26>;
+ reg = <0x0558>;
+ };
+
+ mcbsp3_gfclk: mcbsp3_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&mcbsp3_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>;
+ ti,bit-shift = <24>;
+ reg = <0x0558>;
+ };
+
+ timer5_gfclk_mux: timer5_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dss_syc_gfclk_div>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x0568>;
+ };
+
+ timer6_gfclk_mux: timer6_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dss_syc_gfclk_div>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x0570>;
+ };
+
+ timer7_gfclk_mux: timer7_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dss_syc_gfclk_div>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x0578>;
+ };
+
+ timer8_gfclk_mux: timer8_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dss_syc_gfclk_div>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x0580>;
+ };
+
+ dummy_ck: dummy_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+};
+&prm_clocks {
+ sys_clkin: sys_clkin {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&virt_12000000_ck>, <&virt_13000000_ck>, <&virt_16800000_ck>, <&virt_19200000_ck>, <&virt_26000000_ck>, <&virt_27000000_ck>, <&virt_38400000_ck>;
+ reg = <0x0110>;
+ ti,index-starts-at-one;
+ };
+
+ abe_dpll_bypass_clk_mux: abe_dpll_bypass_clk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin>, <&sys_32k_ck>;
+ reg = <0x0108>;
+ };
+
+ abe_dpll_clk_mux: abe_dpll_clk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin>, <&sys_32k_ck>;
+ reg = <0x010c>;
+ };
+
+ custefuse_sys_gfclk_div: custefuse_sys_gfclk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ dss_syc_gfclk_div: dss_syc_gfclk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&sys_clkin>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ wkupaon_iclk_mux: wkupaon_iclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin>, <&abe_lp_clk_div>;
+ reg = <0x0108>;
+ };
+
+ l3instr_ts_gclk_div: l3instr_ts_gclk_div {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&wkupaon_iclk_mux>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ gpio1_dbclk: gpio1_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1938>;
+ };
+
+ timer1_gfclk_mux: timer1_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1940>;
+ };
+};
+&cm_core_clocks {
+
+ dpll_per_byp_mux: dpll_per_byp_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin>, <&per_dpll_hs_clk_div>;
+ ti,bit-shift = <23>;
+ reg = <0x014c>;
+ };
+
+ dpll_per_ck: dpll_per_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-clock";
+ clocks = <&sys_clkin>, <&dpll_per_byp_mux>;
+ reg = <0x0140>, <0x0144>, <0x014c>, <0x0148>;
+ };
+
+ dpll_per_x2_ck: dpll_per_x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-x2-clock";
+ clocks = <&dpll_per_ck>;
+ };
+
+ dpll_per_h11x2_ck: dpll_per_h11x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,max-div = <63>;
+ reg = <0x0158>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_per_h12x2_ck: dpll_per_h12x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,max-div = <63>;
+ reg = <0x015c>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_per_h14x2_ck: dpll_per_h14x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,max-div = <63>;
+ reg = <0x0164>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_per_m2_ck: dpll_per_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_ck>;
+ ti,max-div = <31>;
+ reg = <0x0150>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_per_m2x2_ck: dpll_per_m2x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,max-div = <31>;
+ reg = <0x0150>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_per_m3x2_ck: dpll_per_m3x2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_x2_ck>;
+ ti,max-div = <31>;
+ reg = <0x0154>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_unipro1_ck: dpll_unipro1_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-clock";
+ clocks = <&sys_clkin>, <&sys_clkin>;
+ reg = <0x0200>, <0x0204>, <0x020c>, <0x0208>;
+ };
+
+ dpll_unipro1_clkdcoldo: dpll_unipro1_clkdcoldo {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_unipro1_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll_unipro1_m2_ck: dpll_unipro1_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_unipro1_ck>;
+ ti,max-div = <127>;
+ reg = <0x0210>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_unipro2_ck: dpll_unipro2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-clock";
+ clocks = <&sys_clkin>, <&sys_clkin>;
+ reg = <0x01c0>, <0x01c4>, <0x01cc>, <0x01c8>;
+ };
+
+ dpll_unipro2_clkdcoldo: dpll_unipro2_clkdcoldo {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_unipro2_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll_unipro2_m2_ck: dpll_unipro2_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_unipro2_ck>;
+ ti,max-div = <127>;
+ reg = <0x01d0>;
+ ti,index-starts-at-one;
+ };
+
+ dpll_usb_byp_mux: dpll_usb_byp_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin>, <&usb_dpll_hs_clk_div>;
+ ti,bit-shift = <23>;
+ reg = <0x018c>;
+ };
+
+ dpll_usb_ck: dpll_usb_ck {
+ #clock-cells = <0>;
+ compatible = "ti,omap4-dpll-j-type-clock";
+ clocks = <&sys_clkin>, <&dpll_usb_byp_mux>;
+ reg = <0x0180>, <0x0184>, <0x018c>, <0x0188>;
+ };
+
+ dpll_usb_clkdcoldo: dpll_usb_clkdcoldo {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_usb_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ dpll_usb_m2_ck: dpll_usb_m2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_usb_ck>;
+ ti,max-div = <127>;
+ reg = <0x0190>;
+ ti,index-starts-at-one;
+ };
+
+ func_128m_clk: func_128m_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_h11x2_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ func_12m_fclk: func_12m_fclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2x2_ck>;
+ clock-mult = <1>;
+ clock-div = <16>;
+ };
+
+ func_24m_clk: func_24m_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ func_48m_fclk: func_48m_fclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2x2_ck>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ };
+
+ func_96m_fclk: func_96m_fclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_per_m2x2_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ l3init_60m_fclk: l3init_60m_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_usb_m2_ck>;
+ reg = <0x0104>;
+ ti,dividers = <1>, <8>;
+ };
+
+ dss_32khz_clk: dss_32khz_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <11>;
+ reg = <0x1420>;
+ };
+
+ dss_48mhz_clk: dss_48mhz_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&func_48m_fclk>;
+ ti,bit-shift = <9>;
+ reg = <0x1420>;
+ };
+
+ dss_dss_clk: dss_dss_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_per_h12x2_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1420>;
+ ti,set-rate-parent;
+ };
+
+ dss_sys_clk: dss_sys_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dss_syc_gfclk_div>;
+ ti,bit-shift = <10>;
+ reg = <0x1420>;
+ };
+
+ gpio2_dbclk: gpio2_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1060>;
+ };
+
+ gpio3_dbclk: gpio3_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1068>;
+ };
+
+ gpio4_dbclk: gpio4_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1070>;
+ };
+
+ gpio5_dbclk: gpio5_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1078>;
+ };
+
+ gpio6_dbclk: gpio6_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1080>;
+ };
+
+ gpio7_dbclk: gpio7_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1110>;
+ };
+
+ gpio8_dbclk: gpio8_dbclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1118>;
+ };
+
+ iss_ctrlclk: iss_ctrlclk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&func_96m_fclk>;
+ ti,bit-shift = <8>;
+ reg = <0x1320>;
+ };
+
+ lli_txphy_clk: lli_txphy_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_unipro1_clkdcoldo>;
+ ti,bit-shift = <8>;
+ reg = <0x0f20>;
+ };
+
+ lli_txphy_ls_clk: lli_txphy_ls_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_unipro1_m2_ck>;
+ ti,bit-shift = <9>;
+ reg = <0x0f20>;
+ };
+
+ mmc1_32khz_clk: mmc1_32khz_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x1628>;
+ };
+
+ sata_ref_clk: sata_ref_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_clkin>;
+ ti,bit-shift = <8>;
+ reg = <0x1688>;
+ };
+
+ usb_host_hs_hsic480m_p1_clk: usb_host_hs_hsic480m_p1_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_usb_m2_ck>;
+ ti,bit-shift = <13>;
+ reg = <0x1658>;
+ };
+
+ usb_host_hs_hsic480m_p2_clk: usb_host_hs_hsic480m_p2_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_usb_m2_ck>;
+ ti,bit-shift = <14>;
+ reg = <0x1658>;
+ };
+
+ usb_host_hs_hsic480m_p3_clk: usb_host_hs_hsic480m_p3_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_usb_m2_ck>;
+ ti,bit-shift = <7>;
+ reg = <0x1658>;
+ };
+
+ usb_host_hs_hsic60m_p1_clk: usb_host_hs_hsic60m_p1_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l3init_60m_fclk>;
+ ti,bit-shift = <11>;
+ reg = <0x1658>;
+ };
+
+ usb_host_hs_hsic60m_p2_clk: usb_host_hs_hsic60m_p2_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l3init_60m_fclk>;
+ ti,bit-shift = <12>;
+ reg = <0x1658>;
+ };
+
+ usb_host_hs_hsic60m_p3_clk: usb_host_hs_hsic60m_p3_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l3init_60m_fclk>;
+ ti,bit-shift = <6>;
+ reg = <0x1658>;
+ };
+
+ utmi_p1_gfclk: utmi_p1_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&l3init_60m_fclk>, <&xclk60mhsp1_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1658>;
+ };
+
+ usb_host_hs_utmi_p1_clk: usb_host_hs_utmi_p1_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&utmi_p1_gfclk>;
+ ti,bit-shift = <8>;
+ reg = <0x1658>;
+ };
+
+ utmi_p2_gfclk: utmi_p2_gfclk {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&l3init_60m_fclk>, <&xclk60mhsp2_ck>;
+ ti,bit-shift = <25>;
+ reg = <0x1658>;
+ };
+
+ usb_host_hs_utmi_p2_clk: usb_host_hs_utmi_p2_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&utmi_p2_gfclk>;
+ ti,bit-shift = <9>;
+ reg = <0x1658>;
+ };
+
+ usb_host_hs_utmi_p3_clk: usb_host_hs_utmi_p3_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l3init_60m_fclk>;
+ ti,bit-shift = <10>;
+ reg = <0x1658>;
+ };
+
+ usb_otg_ss_refclk960m: usb_otg_ss_refclk960m {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&dpll_usb_clkdcoldo>;
+ ti,bit-shift = <8>;
+ reg = <0x16f0>;
+ };
+
+ usb_phy_cm_clk32k: usb_phy_cm_clk32k {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_32k_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0640>;
+ };
+
+ usb_tll_hs_usb_ch0_clk: usb_tll_hs_usb_ch0_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l3init_60m_fclk>;
+ ti,bit-shift = <8>;
+ reg = <0x1668>;
+ };
+
+ usb_tll_hs_usb_ch1_clk: usb_tll_hs_usb_ch1_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l3init_60m_fclk>;
+ ti,bit-shift = <9>;
+ reg = <0x1668>;
+ };
+
+ usb_tll_hs_usb_ch2_clk: usb_tll_hs_usb_ch2_clk {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&l3init_60m_fclk>;
+ ti,bit-shift = <10>;
+ reg = <0x1668>;
+ };
+
+ fdif_fclk: fdif_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_h11x2_ck>;
+ ti,bit-shift = <24>;
+ ti,max-div = <2>;
+ reg = <0x1328>;
+ };
+
+ gpu_core_gclk_mux: gpu_core_gclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dpll_core_h14x2_ck>, <&dpll_per_h14x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1520>;
+ };
+
+ gpu_hyd_gclk_mux: gpu_hyd_gclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&dpll_core_h14x2_ck>, <&dpll_per_h14x2_ck>;
+ ti,bit-shift = <25>;
+ reg = <0x1520>;
+ };
+
+ hsi_fclk: hsi_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ ti,max-div = <2>;
+ reg = <0x1638>;
+ };
+
+ mmc1_fclk_mux: mmc1_fclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_128m_clk>, <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1628>;
+ };
+
+ mmc1_fclk: mmc1_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&mmc1_fclk_mux>;
+ ti,bit-shift = <25>;
+ ti,max-div = <2>;
+ reg = <0x1628>;
+ };
+
+ mmc2_fclk_mux: mmc2_fclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&func_128m_clk>, <&dpll_per_m2x2_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1630>;
+ };
+
+ mmc2_fclk: mmc2_fclk {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&mmc2_fclk_mux>;
+ ti,bit-shift = <25>;
+ ti,max-div = <2>;
+ reg = <0x1630>;
+ };
+
+ timer10_gfclk_mux: timer10_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1028>;
+ };
+
+ timer11_gfclk_mux: timer11_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1030>;
+ };
+
+ timer2_gfclk_mux: timer2_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1038>;
+ };
+
+ timer3_gfclk_mux: timer3_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1040>;
+ };
+
+ timer4_gfclk_mux: timer4_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1048>;
+ };
+
+ timer9_gfclk_mux: timer9_gfclk_mux {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_clkin>, <&sys_32k_ck>;
+ ti,bit-shift = <24>;
+ reg = <0x1050>;
+ };
+};
+
+&cm_core_clockdomains {
+ l3init_clkdm: l3init_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&dpll_usb_ck>;
+ };
+};
+
+&scrm_clocks {
+ auxclk0_src_gate_ck: auxclk0_src_gate_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&dpll_core_m3x2_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0310>;
+ };
+
+ auxclk0_src_mux_ck: auxclk0_src_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&sys_clkin>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0310>;
+ };
+
+ auxclk0_src_ck: auxclk0_src_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&auxclk0_src_gate_ck>, <&auxclk0_src_mux_ck>;
+ };
+
+ auxclk0_ck: auxclk0_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&auxclk0_src_ck>;
+ ti,bit-shift = <16>;
+ ti,max-div = <16>;
+ reg = <0x0310>;
+ };
+
+ auxclk1_src_gate_ck: auxclk1_src_gate_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&dpll_core_m3x2_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0314>;
+ };
+
+ auxclk1_src_mux_ck: auxclk1_src_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&sys_clkin>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0314>;
+ };
+
+ auxclk1_src_ck: auxclk1_src_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&auxclk1_src_gate_ck>, <&auxclk1_src_mux_ck>;
+ };
+
+ auxclk1_ck: auxclk1_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&auxclk1_src_ck>;
+ ti,bit-shift = <16>;
+ ti,max-div = <16>;
+ reg = <0x0314>;
+ };
+
+ auxclk2_src_gate_ck: auxclk2_src_gate_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&dpll_core_m3x2_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0318>;
+ };
+
+ auxclk2_src_mux_ck: auxclk2_src_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&sys_clkin>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0318>;
+ };
+
+ auxclk2_src_ck: auxclk2_src_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&auxclk2_src_gate_ck>, <&auxclk2_src_mux_ck>;
+ };
+
+ auxclk2_ck: auxclk2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&auxclk2_src_ck>;
+ ti,bit-shift = <16>;
+ ti,max-div = <16>;
+ reg = <0x0318>;
+ };
+
+ auxclk3_src_gate_ck: auxclk3_src_gate_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&dpll_core_m3x2_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x031c>;
+ };
+
+ auxclk3_src_mux_ck: auxclk3_src_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&sys_clkin>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x031c>;
+ };
+
+ auxclk3_src_ck: auxclk3_src_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&auxclk3_src_gate_ck>, <&auxclk3_src_mux_ck>;
+ };
+
+ auxclk3_ck: auxclk3_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&auxclk3_src_ck>;
+ ti,bit-shift = <16>;
+ ti,max-div = <16>;
+ reg = <0x031c>;
+ };
+
+ auxclk4_src_gate_ck: auxclk4_src_gate_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-no-wait-gate-clock";
+ clocks = <&dpll_core_m3x2_ck>;
+ ti,bit-shift = <8>;
+ reg = <0x0320>;
+ };
+
+ auxclk4_src_mux_ck: auxclk4_src_mux_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-mux-clock";
+ clocks = <&sys_clkin>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x0320>;
+ };
+
+ auxclk4_src_ck: auxclk4_src_ck {
+ #clock-cells = <0>;
+ compatible = "ti,composite-clock";
+ clocks = <&auxclk4_src_gate_ck>, <&auxclk4_src_mux_ck>;
+ };
+
+ auxclk4_ck: auxclk4_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&auxclk4_src_ck>;
+ ti,bit-shift = <16>;
+ ti,max-div = <16>;
+ reg = <0x0320>;
+ };
+
+ auxclkreq0_ck: auxclkreq0_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x0210>;
+ };
+
+ auxclkreq1_ck: auxclkreq1_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x0214>;
+ };
+
+ auxclkreq2_ck: auxclkreq2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x0218>;
+ };
+
+ auxclkreq3_ck: auxclkreq3_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>;
+ ti,bit-shift = <2>;
+ reg = <0x021c>;
+ };
+};
diff --git a/arch/arm/boot/dts/orion5x-lacie-d2-network.dts b/arch/arm/boot/dts/orion5x-lacie-d2-network.dts
new file mode 100644
index 000000000..c701e8d16
--- /dev/null
+++ b/arch/arm/boot/dts/orion5x-lacie-d2-network.dts
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2014 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ * 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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "orion5x-mv88f5182.dtsi"
+
+/ {
+ model = "LaCie d2 Network";
+ compatible = "lacie,d2-network", "marvell,orion5x-88f5182", "marvell,orion5x";
+
+ memory {
+ reg = <0x00000000 0x4000000>; /* 64 MB */
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ linux,stdout-path = &uart0;
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>,
+ <MBUS_ID(0x09, 0x00) 0 0xf2200000 0x800>,
+ <MBUS_ID(0x01, 0x0f) 0 0xfff80000 0x80000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&pmx_buttons>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ front_button {
+ label = "Front Push Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+ };
+
+ power_rocker_sw_on {
+ label = "Power rocker switch (on|auto)";
+ linux,input-type = <5>; /* EV_SW */
+ linux,code = <1>; /* D2NET_SWITCH_POWER_ON */
+ gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+ };
+
+ power_rocker_sw_off {
+ label = "Power rocker switch (auto|off)";
+ linux,input-type = <5>; /* EV_SW */
+ linux,code = <2>; /* D2NET_SWITCH_POWER_OFF */
+ gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_sata0_power &pmx_sata1_power>;
+ pinctrl-names = "default";
+
+ sata0_power: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "SATA0 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 3 GPIO_ACTIVE_HIGH>;
+ };
+
+ sata1_power: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "SATA1 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&devbus_bootcs {
+ status = "okay";
+
+ devbus,keep-config;
+
+ /*
+ * 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'.
+ */
+ flash@0 {
+ compatible = "cfi-flash";
+ reg = <0 0x80000>;
+ bank-width = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "Full512Kb";
+ reg = <0 0x80000>;
+ read-only;
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy: ethernet-phy {
+ reg = <8>;
+ };
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&eth {
+ status = "okay";
+
+ ethernet-port@0 {
+ phy-handle = <&ethphy>;
+ };
+};
+
+&i2c {
+ status = "okay";
+ clock-frequency = <100000>;
+ #address-cells = <1>;
+
+ rtc@32 {
+ compatible = "ricoh,rs5c372b";
+ reg = <0x32>;
+ };
+
+ fan@3e {
+ compatible = "gmt,g762";
+ reg = <0x3e>;
+
+ /* Not enough HW info */
+ status = "disabled";
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c08";
+ reg = <0x50>;
+ };
+};
+
+&pinctrl {
+ pinctrl-0 = <&pmx_leds &pmx_board_id &pmx_fan_fail>;
+ pinctrl-names = "default";
+
+ pmx_board_id: pmx-board-id {
+ marvell,pins = "mpp0", "mpp1", "mpp2";
+ marvell,function = "gpio";
+ };
+
+ pmx_buttons: pmx-buttons {
+ marvell,pins = "mpp8", "mpp9", "mpp18";
+ marvell,function = "gpio";
+ };
+
+ pmx_fan_fail: pmx-fan-fail {
+ marvell,pins = "mpp5";
+ marvell,function = "gpio";
+ };
+
+ /*
+ * MPP6: Red front LED
+ * MPP16: Blue front LED blink control
+ */
+ pmx_leds: pmx-leds {
+ marvell,pins = "mpp6", "mpp16";
+ marvell,function = "gpio";
+ };
+
+ pmx_sata0_led_active: pmx-sata0-led-active {
+ marvell,pins = "mpp14";
+ marvell,function = "sata0";
+ };
+
+ pmx_sata0_power: pmx-sata0-power {
+ marvell,pins = "mpp3";
+ marvell,function = "gpio";
+ };
+
+ pmx_sata1_led_active: pmx-sata1-led-active {
+ marvell,pins = "mpp15";
+ marvell,function = "sata1";
+ };
+
+ pmx_sata1_power: pmx-sata1-power {
+ marvell,pins = "mpp12";
+ marvell,function = "gpio";
+ };
+
+ /*
+ * Non MPP GPIOs:
+ * GPIO 22: USB port 1 fuse (0 = Fail, 1 = Ok)
+ * GPIO 23: Blue front LED off
+ * GPIO 24: Inhibit board power off (0 = Disabled, 1 = Enabled)
+ */
+};
+
+&sata {
+ pinctrl-0 = <&pmx_sata0_led_active
+ &pmx_sata1_led_active>;
+ pinctrl-names = "default";
+ status = "okay";
+ nr-ports = <2>;
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts b/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts
new file mode 100644
index 000000000..89ff404a5
--- /dev/null
+++ b/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2012 Thomas Petazzoni <thomas.petazzoni@free-electrons.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.
+ */
+
+/*
+ * 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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "orion5x-mv88f5182.dtsi"
+
+/ {
+ model = "LaCie Ethernet Disk mini V2";
+ compatible = "lacie,ethernet-disk-mini-v2", "marvell,orion5x-88f5182", "marvell,orion5x";
+
+ memory {
+ reg = <0x00000000 0x4000000>; /* 64 MB */
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ linux,stdout-path = &uart0;
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>,
+ <MBUS_ID(0x09, 0x00) 0 0xf2200000 0x800>,
+ <MBUS_ID(0x01, 0x0f) 0 0xfff80000 0x80000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&pmx_power_button>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ button@1 {
+ label = "Power-on Switch";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_power_led>;
+ pinctrl-names = "default";
+
+ led@1 {
+ label = "power:blue";
+ gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&devbus_bootcs {
+ status = "okay";
+
+ /* Read parameters */
+ devbus,bus-width = <8>;
+ devbus,turn-off-ps = <90000>;
+ devbus,badr-skew-ps = <0>;
+ devbus,acc-first-ps = <186000>;
+ devbus,acc-next-ps = <186000>;
+
+ /* Write parameters */
+ devbus,wr-high-ps = <90000>;
+ devbus,wr-low-ps = <90000>;
+ devbus,ale-wr-ps = <90000>;
+
+ /*
+ * 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'.
+ */
+ flash@0 {
+ compatible = "cfi-flash";
+ reg = <0 0x80000>;
+ bank-width = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "Full512Kb";
+ reg = <0 0x80000>;
+ read-only;
+ };
+ };
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&eth {
+ status = "okay";
+
+ ethernet-port@0 {
+ phy-handle = <&ethphy>;
+ };
+};
+
+&i2c {
+ status = "okay";
+ clock-frequency = <100000>;
+ #address-cells = <1>;
+
+ rtc@32 {
+ compatible = "ricoh,rs5c372a";
+ reg = <0x32>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy: ethernet-phy {
+ reg = <8>;
+ };
+};
+
+&pinctrl {
+ pinctrl-0 = <&pmx_rtc &pmx_power_led_ctrl>;
+ pinctrl-names = "default";
+
+ pmx_power_button: pmx-power-button {
+ marvell,pins = "mpp18";
+ marvell,function = "gpio";
+ };
+
+ pmx_power_led: pmx-power-led {
+ marvell,pins = "mpp16";
+ marvell,function = "gpio";
+ };
+
+ pmx_power_led_ctrl: pmx-power-led-ctrl {
+ marvell,pins = "mpp17";
+ marvell,function = "gpio";
+ };
+
+ pmx_rtc: pmx-rtc {
+ marvell,pins = "mpp3";
+ marvell,function = "gpio";
+ };
+};
+
+&sata {
+ pinctrl-0 = <&pmx_sata0 &pmx_sata1>;
+ pinctrl-names = "default";
+ status = "okay";
+ nr-ports = <2>;
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/orion5x-maxtor-shared-storage-2.dts b/arch/arm/boot/dts/orion5x-maxtor-shared-storage-2.dts
new file mode 100644
index 000000000..ff3484904
--- /dev/null
+++ b/arch/arm/boot/dts/orion5x-maxtor-shared-storage-2.dts
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2014 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ * Copyright (C) Sylver Bruneau <sylver.bruneau@googlemail.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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "orion5x-mv88f5182.dtsi"
+
+/ {
+ model = "Maxtor Shared Storage II";
+ compatible = "maxtor,shared-storage-2", "marvell,orion5x-88f5182", "marvell,orion5x";
+
+ memory {
+ reg = <0x00000000 0x4000000>; /* 64 MB */
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ linux,stdout-path = &uart0;
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>,
+ <MBUS_ID(0x09, 0x00) 0 0xf2200000 0x800>,
+ <MBUS_ID(0x01, 0x0f) 0 0xff800000 0x40000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&pmx_buttons>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power {
+ label = "Power";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+ };
+
+ reset {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&devbus_bootcs {
+ status = "okay";
+
+ devbus,keep-config;
+
+ /*
+ * 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'.
+ */
+ flash@0 {
+ compatible = "cfi-flash";
+ reg = <0 0x40000>;
+ bank-width = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy: ethernet-phy {
+ reg = <8>;
+ };
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&eth {
+ status = "okay";
+
+ ethernet-port@0 {
+ phy-handle = <&ethphy>;
+ };
+};
+
+&i2c {
+ status = "okay";
+ clock-frequency = <100000>;
+ #address-cells = <1>;
+
+ rtc@68 {
+ compatible = "st,m41t81";
+ reg = <0x68>;
+ pinctrl-0 = <&pmx_rtc>;
+ pinctrl-names = "default";
+ interrupt-parent = <&gpio0>;
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&pinctrl {
+ pinctrl-0 = <&pmx_leds &pmx_misc>;
+ pinctrl-names = "default";
+
+ pmx_buttons: pmx-buttons {
+ marvell,pins = "mpp11", "mpp12";
+ marvell,function = "gpio";
+ };
+
+ /*
+ * MPP0: Power LED
+ * MPP1: Error LED
+ */
+ pmx_leds: pmx-leds {
+ marvell,pins = "mpp0", "mpp1";
+ marvell,function = "gpio";
+ };
+
+ /*
+ * MPP4: HDD ind. (Single/Dual)
+ * MPP5: HD0 5V control
+ * MPP6: HD0 12V control
+ * MPP7: HD1 5V control
+ * MPP8: HD1 12V control
+ */
+ pmx_misc: pmx-misc {
+ marvell,pins = "mpp4", "mpp5", "mpp6", "mpp7", "mpp8", "mpp10";
+ marvell,function = "gpio";
+ };
+
+ pmx_rtc: pmx-rtc {
+ marvell,pins = "mpp3";
+ marvell,function = "gpio";
+ };
+
+ pmx_sata0_led_active: pmx-sata0-led-active {
+ marvell,pins = "mpp14";
+ marvell,function = "sata0";
+ };
+
+ pmx_sata1_led_active: pmx-sata1-led-active {
+ marvell,pins = "mpp15";
+ marvell,function = "sata1";
+ };
+
+ /*
+ * Non MPP GPIOs:
+ * GPIO 22: USB port 1 fuse (0 = Fail, 1 = Ok)
+ * GPIO 23: Blue front LED off
+ * GPIO 24: Inhibit board power off (0 = Disabled, 1 = Enabled)
+ */
+};
+
+&sata {
+ pinctrl-0 = <&pmx_sata0_led_active
+ &pmx_sata1_led_active>;
+ pinctrl-names = "default";
+ status = "okay";
+ nr-ports = <2>;
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/orion5x-mv88f5182.dtsi b/arch/arm/boot/dts/orion5x-mv88f5182.dtsi
new file mode 100644
index 000000000..d1ed71c60
--- /dev/null
+++ b/arch/arm/boot/dts/orion5x-mv88f5182.dtsi
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2014 Thomas Petazzoni <thomas.petazzoni@free-electrons.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 "orion5x.dtsi"
+
+/ {
+ compatible = "marvell,orion5x-88f5182", "marvell,orion5x";
+
+ soc {
+ compatible = "marvell,orion5x-88f5182-mbus", "simple-bus";
+
+ internal-regs {
+ pinctrl: pinctrl@10000 {
+ compatible = "marvell,88f5182-pinctrl";
+ reg = <0x10000 0x8>, <0x10050 0x4>;
+
+ pmx_sata0: pmx-sata0 {
+ marvell,pins = "mpp12", "mpp14";
+ marvell,function = "sata0";
+ };
+
+ pmx_sata1: pmx-sata1 {
+ marvell,pins = "mpp13", "mpp15";
+ marvell,function = "sata1";
+ };
+ };
+
+ core_clk: core-clocks@10030 {
+ compatible = "marvell,mv88f5182-core-clock";
+ reg = <0x10010 0x4>;
+ #clock-cells = <1>;
+ };
+
+ mbusc: mbus-controller@20000 {
+ compatible = "marvell,mbus-controller";
+ reg = <0x20000 0x100>, <0x1500 0x20>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/orion5x-rd88f5182-nas.dts b/arch/arm/boot/dts/orion5x-rd88f5182-nas.dts
new file mode 100644
index 000000000..6fb052507
--- /dev/null
+++ b/arch/arm/boot/dts/orion5x-rd88f5182-nas.dts
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2014 Thomas Petazzoni <thomas.petazzoni@free-electrons.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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "orion5x-mv88f5182.dtsi"
+
+/ {
+ model = "Marvell Reference Design 88F5182 NAS";
+ compatible = "marvell,rd-88f5182-nas", "marvell,orion5x-88f5182", "marvell,orion5x";
+
+ memory {
+ reg = <0x00000000 0x4000000>; /* 64 MB */
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ linux,stdout-path = &uart0;
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>,
+ <MBUS_ID(0x09, 0x00) 0 0xf2200000 0x800>,
+ <MBUS_ID(0x01, 0x0f) 0 0xf4000000 0x80000>,
+ <MBUS_ID(0x01, 0x1d) 0 0xfc000000 0x1000000>;
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_debug_led>;
+ pinctrl-names = "default";
+
+ led@0 {
+ label = "rd88f5182:cpu";
+ linux,default-trigger = "heartbeat";
+ gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&devbus_bootcs {
+ status = "okay";
+
+ /* Read parameters */
+ devbus,bus-width = <8>;
+ devbus,turn-off-ps = <90000>;
+ devbus,badr-skew-ps = <0>;
+ devbus,acc-first-ps = <186000>;
+ devbus,acc-next-ps = <186000>;
+
+ /* Write parameters */
+ devbus,wr-high-ps = <90000>;
+ devbus,wr-low-ps = <90000>;
+ devbus,ale-wr-ps = <90000>;
+
+ flash@0 {
+ compatible = "cfi-flash";
+ reg = <0 0x80000>;
+ bank-width = <1>;
+ };
+};
+
+&devbus_cs1 {
+ status = "okay";
+
+ /* Read parameters */
+ devbus,bus-width = <8>;
+ devbus,turn-off-ps = <90000>;
+ devbus,badr-skew-ps = <0>;
+ devbus,acc-first-ps = <186000>;
+ devbus,acc-next-ps = <186000>;
+
+ /* Write parameters */
+ devbus,wr-high-ps = <90000>;
+ devbus,wr-low-ps = <90000>;
+ devbus,ale-wr-ps = <90000>;
+
+ flash@0 {
+ compatible = "cfi-flash";
+ reg = <0 0x1000000>;
+ bank-width = <1>;
+ };
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&eth {
+ status = "okay";
+
+ ethernet-port@0 {
+ phy-handle = <&ethphy>;
+ };
+};
+
+&i2c {
+ status = "okay";
+ clock-frequency = <100000>;
+ #address-cells = <1>;
+
+ rtc@68 {
+ pinctrl-0 = <&pmx_rtc>;
+ pinctrl-names = "default";
+ compatible = "dallas,ds1338";
+ reg = <0x68>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy: ethernet-phy {
+ reg = <8>;
+ };
+};
+
+&pinctrl {
+ pinctrl-0 = <&pmx_reset_switch &pmx_misc_gpios
+ &pmx_pci_gpios>;
+ pinctrl-names = "default";
+
+ /*
+ * 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
+ */
+
+ pmx_debug_led: pmx-debug_led {
+ marvell,pins = "mpp0";
+ marvell,function = "gpio";
+ };
+
+ pmx_reset_switch: pmx-reset-switch {
+ marvell,pins = "mpp1";
+ marvell,function = "gpio";
+ };
+
+ pmx_rtc: pmx-rtc {
+ marvell,pins = "mpp3";
+ marvell,function = "gpio";
+ };
+
+ pmx_misc_gpios: pmx-misc-gpios {
+ marvell,pins = "mpp4", "mpp5";
+ marvell,function = "gpio";
+ };
+
+ pmx_pci_gpios: pmx-pci-gpios {
+ marvell,pins = "mpp6", "mpp7";
+ marvell,function = "gpio";
+ };
+};
+
+&sata {
+ pinctrl-0 = <&pmx_sata0 &pmx_sata1>;
+ pinctrl-names = "default";
+ status = "okay";
+ nr-ports = <2>;
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/orion5x.dtsi b/arch/arm/boot/dts/orion5x.dtsi
new file mode 100644
index 000000000..75cd01bd6
--- /dev/null
+++ b/arch/arm/boot/dts/orion5x.dtsi
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2012 Thomas Petazzoni <thomas.petazzoni@free-electrons.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 "skeleton.dtsi"
+
+#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
+
+/ {
+ model = "Marvell Orion5x SoC";
+ compatible = "marvell,orion5x";
+ interrupt-parent = <&intc>;
+
+ aliases {
+ gpio0 = &gpio0;
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ controller = <&mbusc>;
+
+ devbus_bootcs: devbus-bootcs {
+ compatible = "marvell,orion-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x1046C 0x4>;
+ ranges = <0 MBUS_ID(0x01, 0x0f) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&core_clk 0>;
+ status = "disabled";
+ };
+
+ devbus_cs0: devbus-cs0 {
+ compatible = "marvell,orion-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x1045C 0x4>;
+ ranges = <0 MBUS_ID(0x01, 0x1e) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&core_clk 0>;
+ status = "disabled";
+ };
+
+ devbus_cs1: devbus-cs1 {
+ compatible = "marvell,orion-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10460 0x4>;
+ ranges = <0 MBUS_ID(0x01, 0x1d) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&core_clk 0>;
+ status = "disabled";
+ };
+
+ devbus_cs2: devbus-cs2 {
+ compatible = "marvell,orion-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10464 0x4>;
+ ranges = <0 MBUS_ID(0x01, 0x1b) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&core_clk 0>;
+ status = "disabled";
+ };
+
+ internal-regs {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
+
+ gpio0: gpio@10100 {
+ compatible = "marvell,orion-gpio";
+ #gpio-cells = <2>;
+ gpio-controller;
+ reg = <0x10100 0x40>;
+ ngpios = <32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <6>, <7>, <8>, <9>;
+ };
+
+ spi: spi@10600 {
+ compatible = "marvell,orion-spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ reg = <0x10600 0x28>;
+ status = "disabled";
+ };
+
+ i2c: i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <5>;
+ clocks = <&core_clk 0>;
+ status = "disabled";
+ };
+
+ uart0: serial@12000 {
+ compatible = "ns16550a";
+ reg = <0x12000 0x100>;
+ reg-shift = <2>;
+ interrupts = <3>;
+ clocks = <&core_clk 0>;
+ status = "disabled";
+ };
+
+ uart1: serial@12100 {
+ compatible = "ns16550a";
+ reg = <0x12100 0x100>;
+ reg-shift = <2>;
+ interrupts = <4>;
+ clocks = <&core_clk 0>;
+ status = "disabled";
+ };
+
+ bridge_intc: bridge-interrupt-ctrl@20110 {
+ compatible = "marvell,orion-bridge-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x20110 0x8>;
+ interrupts = <0>;
+ marvell,#interrupts = <4>;
+ };
+
+ intc: interrupt-controller@20200 {
+ compatible = "marvell,orion-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x20200 0x08>;
+ };
+
+ timer: timer@20300 {
+ compatible = "marvell,orion-timer";
+ reg = <0x20300 0x20>;
+ interrupt-parent = <&bridge_intc>;
+ interrupts = <1>, <2>;
+ clocks = <&core_clk 0>;
+ };
+
+ wdt: wdt@20300 {
+ compatible = "marvell,orion-wdt";
+ reg = <0x20300 0x28>;
+ interrupt-parent = <&bridge_intc>;
+ interrupts = <3>;
+ status = "okay";
+ };
+
+ ehci0: ehci@50000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <17>;
+ status = "disabled";
+ };
+
+ xor: dma-controller@60900 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60900 0x100
+ 0x60b00 0x100>;
+ status = "okay";
+
+ xor00 {
+ interrupts = <30>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor01 {
+ interrupts = <31>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+
+ eth: ethernet-controller@72000 {
+ compatible = "marvell,orion-eth";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x72000 0x4000>;
+ marvell,tx-checksum-limit = <1600>;
+ status = "disabled";
+
+ ethport: ethernet-port@0 {
+ compatible = "marvell,orion-eth-port";
+ reg = <0>;
+ interrupts = <21>;
+ /* overwrite MAC address in bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ /* set phy-handle property in board file */
+ };
+ };
+
+ mdio: mdio-bus@72004 {
+ compatible = "marvell,orion-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x72004 0x84>;
+ interrupts = <22>;
+ status = "disabled";
+
+ /* add phy nodes in board file */
+ };
+
+ sata: sata@80000 {
+ compatible = "marvell,orion-sata";
+ reg = <0x80000 0x5000>;
+ interrupts = <29>;
+ status = "disabled";
+ };
+
+ ehci1: ehci@a0000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0xa0000 0x1000>;
+ interrupts = <12>;
+ status = "disabled";
+ };
+ };
+
+ cesa: crypto@90000 {
+ compatible = "marvell,orion-crypto";
+ reg = <MBUS_ID(0xf0, 0x01) 0x90000 0x10000>,
+ <MBUS_ID(0x09, 0x00) 0x0 0x800>;
+ reg-names = "regs", "sram";
+ interrupts = <28>;
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/phy3250.dts b/arch/arm/boot/dts/phy3250.dts
new file mode 100644
index 000000000..90fdbd77f
--- /dev/null
+++ b/arch/arm/boot/dts/phy3250.dts
@@ -0,0 +1,202 @@
+/*
+ * PHYTEC phyCORE-LPC3250 board
+ *
+ * Copyright 2012 Roland Stigge <stigge@antcom.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
+ */
+
+/dts-v1/;
+/include/ "lpc32xx.dtsi"
+
+/ {
+ model = "PHYTEC phyCORE-LPC3250 board based on NXP LPC3250";
+ compatible = "phytec,phy3250", "nxp,lpc3250";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x4000000>;
+ };
+
+ ahb {
+ mac: ethernet@31060000 {
+ phy-mode = "rmii";
+ use-iram;
+ };
+
+ /* Here, choose exactly one from: ohci, usbd */
+ ohci@31020000 {
+ transceiver = <&isp1301>;
+ status = "okay";
+ };
+
+/*
+ usbd@31020000 {
+ transceiver = <&isp1301>;
+ status = "okay";
+ };
+*/
+
+ clcd@31040000 {
+ status = "okay";
+ };
+
+ /* 64MB Flash via SLC NAND controller */
+ slc: flash@20020000 {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ nxp,wdr-clks = <14>;
+ nxp,wwidth = <40000000>;
+ nxp,whold = <100000000>;
+ nxp,wsetup = <100000000>;
+ nxp,rdr-clks = <14>;
+ nxp,rwidth = <40000000>;
+ nxp,rhold = <66666666>;
+ nxp,rsetup = <100000000>;
+ nand-on-flash-bbt;
+ gpios = <&gpio 5 19 1>; /* GPO_P3 19, active low */
+
+ mtd0@00000000 {
+ label = "phy3250-boot";
+ reg = <0x00000000 0x00064000>;
+ read-only;
+ };
+
+ mtd1@00064000 {
+ label = "phy3250-uboot";
+ reg = <0x00064000 0x00190000>;
+ read-only;
+ };
+
+ mtd2@001f4000 {
+ label = "phy3250-ubt-prms";
+ reg = <0x001f4000 0x00010000>;
+ };
+
+ mtd3@00204000 {
+ label = "phy3250-kernel";
+ reg = <0x00204000 0x00400000>;
+ };
+
+ mtd4@00604000 {
+ label = "phy3250-rootfs";
+ reg = <0x00604000 0x039fc000>;
+ };
+ };
+
+ apb {
+ uart5: serial@40090000 {
+ status = "okay";
+ };
+
+ uart3: serial@40080000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@400A0000 {
+ clock-frequency = <100000>;
+
+ pcf8563: rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+
+ uda1380: uda1380@18 {
+ compatible = "nxp,uda1380";
+ reg = <0x18>;
+ power-gpio = <&gpio 0x59 0>;
+ reset-gpio = <&gpio 0x51 0>;
+ dac-clk = "wspll";
+ };
+ };
+
+ i2c2: i2c@400A8000 {
+ clock-frequency = <100000>;
+ };
+
+ i2cusb: i2c@31020300 {
+ clock-frequency = <100000>;
+
+ isp1301: usb-transceiver@2c {
+ compatible = "nxp,isp1301";
+ reg = <0x2c>;
+ };
+ };
+
+ ssp0: ssp@20084000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ num-cs = <1>;
+ cs-gpios = <&gpio 3 5 0>;
+
+ eeprom: at25@0 {
+ pl022,interface = <0>;
+ pl022,com-mode = <0>;
+ pl022,rx-level-trig = <1>;
+ pl022,tx-level-trig = <1>;
+ pl022,ctrl-len = <11>;
+ pl022,wait-state = <0>;
+ pl022,duplex = <0>;
+
+ at25,byte-len = <0x8000>;
+ at25,addr-mode = <2>;
+ at25,page-size = <64>;
+
+ compatible = "atmel,at25";
+ reg = <0>;
+ spi-max-frequency = <5000000>;
+ };
+ };
+
+ sd@20098000 {
+ wp-gpios = <&gpio 3 0 0>;
+ cd-gpios = <&gpio 3 1 0>;
+ cd-inverted;
+ bus-width = <4>;
+ status = "okay";
+ };
+ };
+
+ fab {
+ uart2: serial@40018000 {
+ status = "okay";
+ };
+
+ tsc@40048000 {
+ status = "okay";
+ };
+
+ key@40050000 {
+ status = "okay";
+ keypad,num-rows = <1>;
+ keypad,num-columns = <1>;
+ nxp,debounce-delay-ms = <3>;
+ nxp,scan-delay-ms = <34>;
+ linux,keymap = <0x00000002>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led0 { /* red */
+ gpios = <&gpio 5 1 0>; /* GPO_P3 1, GPIO 80, active high */
+ default-state = "off";
+ };
+
+ led1 { /* green */
+ gpios = <&gpio 5 14 0>; /* GPO_P3 14, GPIO 93, active high */
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/picoxcell-pc3x2.dtsi b/arch/arm/boot/dts/picoxcell-pc3x2.dtsi
new file mode 100644
index 000000000..533919e96
--- /dev/null
+++ b/arch/arm/boot/dts/picoxcell-pc3x2.dtsi
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2011 Picochip, Jamie Iles
+ *
+ * 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/ "skeleton.dtsi"
+/ {
+ model = "Picochip picoXcell PC3X2";
+ compatible = "picochip,pc3x2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm1176jz-s";
+ device_type = "cpu";
+ clock-frequency = <400000000>;
+ d-cache-line-size = <32>;
+ d-cache-size = <32768>;
+ i-cache-line-size = <32>;
+ i-cache-size = <32768>;
+ };
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pclk: clock@0 {
+ compatible = "fixed-clock";
+ clock-outputs = "bus", "pclk";
+ clock-frequency = <200000000>;
+ ref-clock = <&ref_clk>, "ref";
+ };
+ };
+
+ paxi {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x80000000 0x400000>;
+
+ emac: gem@30000 {
+ compatible = "cadence,gem";
+ reg = <0x30000 0x10000>;
+ interrupts = <31>;
+ };
+
+ dmac1: dmac@40000 {
+ compatible = "snps,dw-dmac";
+ reg = <0x40000 0x10000>;
+ interrupts = <25>;
+ };
+
+ dmac2: dmac@50000 {
+ compatible = "snps,dw-dmac";
+ reg = <0x50000 0x10000>;
+ interrupts = <26>;
+ };
+
+ vic0: interrupt-controller@60000 {
+ compatible = "arm,pl192-vic";
+ interrupt-controller;
+ reg = <0x60000 0x1000>;
+ #interrupt-cells = <1>;
+ };
+
+ vic1: interrupt-controller@64000 {
+ compatible = "arm,pl192-vic";
+ interrupt-controller;
+ reg = <0x64000 0x1000>;
+ #interrupt-cells = <1>;
+ };
+
+ fuse: picoxcell-fuse@80000 {
+ compatible = "picoxcell,fuse-pc3x2";
+ reg = <0x80000 0x10000>;
+ };
+
+ ssi: picoxcell-spi@90000 {
+ compatible = "picoxcell,spi";
+ reg = <0x90000 0x10000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <10>;
+ };
+
+ ipsec: spacc@100000 {
+ compatible = "picochip,spacc-ipsec";
+ reg = <0x100000 0x10000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <24>;
+ ref-clock = <&pclk>, "ref";
+ };
+
+ srtp: spacc@140000 {
+ compatible = "picochip,spacc-srtp";
+ reg = <0x140000 0x10000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <23>;
+ };
+
+ l2_engine: spacc@180000 {
+ compatible = "picochip,spacc-l2";
+ reg = <0x180000 0x10000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <22>;
+ ref-clock = <&pclk>, "ref";
+ };
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x200000 0x80000>;
+
+ rtc0: rtc@00000 {
+ compatible = "picochip,pc3x2-rtc";
+ clock-freq = <200000000>;
+ reg = <0x00000 0xf>;
+ interrupt-parent = <&vic1>;
+ interrupts = <8>;
+ };
+
+ timer0: timer@10000 {
+ compatible = "picochip,pc3x2-timer";
+ interrupt-parent = <&vic0>;
+ interrupts = <4>;
+ clock-freq = <200000000>;
+ reg = <0x10000 0x14>;
+ };
+
+ timer1: timer@10014 {
+ compatible = "picochip,pc3x2-timer";
+ interrupt-parent = <&vic0>;
+ interrupts = <5>;
+ clock-freq = <200000000>;
+ reg = <0x10014 0x14>;
+ };
+
+ timer2: timer@10028 {
+ compatible = "picochip,pc3x2-timer";
+ interrupt-parent = <&vic0>;
+ interrupts = <6>;
+ clock-freq = <200000000>;
+ reg = <0x10028 0x14>;
+ };
+
+ timer3: timer@1003c {
+ compatible = "picochip,pc3x2-timer";
+ interrupt-parent = <&vic0>;
+ interrupts = <7>;
+ clock-freq = <200000000>;
+ reg = <0x1003c 0x14>;
+ };
+
+ gpio: gpio@20000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x20000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-io-width = <4>;
+
+ banka: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-bank";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-generic,nr-gpio = <8>;
+
+ regoffset-dat = <0x50>;
+ regoffset-set = <0x00>;
+ regoffset-dirout = <0x04>;
+ };
+
+ bankb: gpio-controller@1 {
+ compatible = "snps,dw-apb-gpio-bank";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-generic,nr-gpio = <8>;
+
+ regoffset-dat = <0x54>;
+ regoffset-set = <0x0c>;
+ regoffset-dirout = <0x10>;
+ };
+ };
+
+ uart0: uart@30000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x30000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <10>;
+ clock-frequency = <3686400>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ uart1: uart@40000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x40000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <9>;
+ clock-frequency = <3686400>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ wdog: watchdog@50000 {
+ compatible = "snps,dw-apb-wdg";
+ reg = <0x50000 0x10000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <11>;
+ bus-clock = <&pclk>, "bus";
+ };
+ };
+ };
+
+ rwid-axi {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+
+ ebi@50000000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0x40000000 0x08000000
+ 1 0 0x48000000 0x08000000
+ 2 0 0x50000000 0x08000000
+ 3 0 0x58000000 0x08000000>;
+ };
+
+ axi2pico@c0000000 {
+ compatible = "picochip,axi2pico-pc3x2";
+ reg = <0xc0000000 0x10000>;
+ interrupts = <13 14 15 16 17 18 19 20 21>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/picoxcell-pc3x3.dtsi b/arch/arm/boot/dts/picoxcell-pc3x3.dtsi
new file mode 100644
index 000000000..ab3e80085
--- /dev/null
+++ b/arch/arm/boot/dts/picoxcell-pc3x3.dtsi
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2011 Picochip, Jamie Iles
+ *
+ * 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/ "skeleton.dtsi"
+/ {
+ model = "Picochip picoXcell PC3X3";
+ compatible = "picochip,pc3x3";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm1176jz-s";
+ device_type = "cpu";
+ cpu-clock = <&arm_clk>, "cpu";
+ d-cache-line-size = <32>;
+ d-cache-size = <32768>;
+ i-cache-line-size = <32>;
+ i-cache-size = <32768>;
+ };
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ clkgate: clkgate@800a0048 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x800a0048 4>;
+ compatible = "picochip,pc3x3-clk-gate";
+
+ tzprot_clk: clock@0 {
+ compatible = "picochip,pc3x3-gated-clk";
+ clock-outputs = "bus";
+ picochip,clk-disable-bit = <0>;
+ clock-frequency = <200000000>;
+ ref-clock = <&ref_clk>, "ref";
+ };
+
+ spi_clk: clock@1 {
+ compatible = "picochip,pc3x3-gated-clk";
+ clock-outputs = "bus";
+ picochip,clk-disable-bit = <1>;
+ clock-frequency = <200000000>;
+ ref-clock = <&ref_clk>, "ref";
+ };
+
+ dmac0_clk: clock@2 {
+ compatible = "picochip,pc3x3-gated-clk";
+ clock-outputs = "bus";
+ picochip,clk-disable-bit = <2>;
+ clock-frequency = <200000000>;
+ ref-clock = <&ref_clk>, "ref";
+ };
+
+ dmac1_clk: clock@3 {
+ compatible = "picochip,pc3x3-gated-clk";
+ clock-outputs = "bus";
+ picochip,clk-disable-bit = <3>;
+ clock-frequency = <200000000>;
+ ref-clock = <&ref_clk>, "ref";
+ };
+
+ ebi_clk: clock@4 {
+ compatible = "picochip,pc3x3-gated-clk";
+ clock-outputs = "bus";
+ picochip,clk-disable-bit = <4>;
+ clock-frequency = <200000000>;
+ ref-clock = <&ref_clk>, "ref";
+ };
+
+ ipsec_clk: clock@5 {
+ compatible = "picochip,pc3x3-gated-clk";
+ clock-outputs = "bus";
+ picochip,clk-disable-bit = <5>;
+ clock-frequency = <200000000>;
+ ref-clock = <&ref_clk>, "ref";
+ };
+
+ l2_clk: clock@6 {
+ compatible = "picochip,pc3x3-gated-clk";
+ clock-outputs = "bus";
+ picochip,clk-disable-bit = <6>;
+ clock-frequency = <200000000>;
+ ref-clock = <&ref_clk>, "ref";
+ };
+
+ trng_clk: clock@7 {
+ compatible = "picochip,pc3x3-gated-clk";
+ clock-outputs = "bus";
+ picochip,clk-disable-bit = <7>;
+ clock-frequency = <200000000>;
+ ref-clock = <&ref_clk>, "ref";
+ };
+
+ fuse_clk: clock@8 {
+ compatible = "picochip,pc3x3-gated-clk";
+ clock-outputs = "bus";
+ picochip,clk-disable-bit = <8>;
+ clock-frequency = <200000000>;
+ ref-clock = <&ref_clk>, "ref";
+ };
+
+ otp_clk: clock@9 {
+ compatible = "picochip,pc3x3-gated-clk";
+ clock-outputs = "bus";
+ picochip,clk-disable-bit = <9>;
+ clock-frequency = <200000000>;
+ ref-clock = <&ref_clk>, "ref";
+ };
+ };
+
+ arm_clk: clock@11 {
+ compatible = "picochip,pc3x3-pll";
+ reg = <0x800a0050 0x8>;
+ picochip,min-freq = <140000000>;
+ picochip,max-freq = <700000000>;
+ ref-clock = <&ref_clk>, "ref";
+ clock-outputs = "cpu";
+ };
+
+ pclk: clock@12 {
+ compatible = "fixed-clock";
+ clock-outputs = "bus", "pclk";
+ clock-frequency = <200000000>;
+ ref-clock = <&ref_clk>, "ref";
+ };
+ };
+
+ paxi {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x80000000 0x400000>;
+
+ emac: gem@30000 {
+ compatible = "cadence,gem";
+ reg = <0x30000 0x10000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <31>;
+ };
+
+ dmac1: dmac@40000 {
+ compatible = "snps,dw-dmac";
+ reg = <0x40000 0x10000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <25>;
+ };
+
+ dmac2: dmac@50000 {
+ compatible = "snps,dw-dmac";
+ reg = <0x50000 0x10000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <26>;
+ };
+
+ vic0: interrupt-controller@60000 {
+ compatible = "arm,pl192-vic";
+ interrupt-controller;
+ reg = <0x60000 0x1000>;
+ #interrupt-cells = <1>;
+ };
+
+ vic1: interrupt-controller@64000 {
+ compatible = "arm,pl192-vic";
+ interrupt-controller;
+ reg = <0x64000 0x1000>;
+ #interrupt-cells = <1>;
+ };
+
+ fuse: picoxcell-fuse@80000 {
+ compatible = "picoxcell,fuse-pc3x3";
+ reg = <0x80000 0x10000>;
+ };
+
+ ssi: picoxcell-spi@90000 {
+ compatible = "picoxcell,spi";
+ reg = <0x90000 0x10000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <10>;
+ };
+
+ ipsec: spacc@100000 {
+ compatible = "picochip,spacc-ipsec";
+ reg = <0x100000 0x10000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <24>;
+ ref-clock = <&ipsec_clk>, "ref";
+ };
+
+ srtp: spacc@140000 {
+ compatible = "picochip,spacc-srtp";
+ reg = <0x140000 0x10000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <23>;
+ };
+
+ l2_engine: spacc@180000 {
+ compatible = "picochip,spacc-l2";
+ reg = <0x180000 0x10000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <22>;
+ ref-clock = <&l2_clk>, "ref";
+ };
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x200000 0x80000>;
+
+ rtc0: rtc@00000 {
+ compatible = "picochip,pc3x2-rtc";
+ clock-freq = <200000000>;
+ reg = <0x00000 0xf>;
+ interrupt-parent = <&vic0>;
+ interrupts = <8>;
+ };
+
+ timer0: timer@10000 {
+ compatible = "picochip,pc3x2-timer";
+ interrupt-parent = <&vic0>;
+ interrupts = <4>;
+ clock-freq = <200000000>;
+ reg = <0x10000 0x14>;
+ };
+
+ timer1: timer@10014 {
+ compatible = "picochip,pc3x2-timer";
+ interrupt-parent = <&vic0>;
+ interrupts = <5>;
+ clock-freq = <200000000>;
+ reg = <0x10014 0x14>;
+ };
+
+ gpio: gpio@20000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x20000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-io-width = <4>;
+
+ banka: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-bank";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-generic,nr-gpio = <8>;
+
+ regoffset-dat = <0x50>;
+ regoffset-set = <0x00>;
+ regoffset-dirout = <0x04>;
+ };
+
+ bankb: gpio-controller@1 {
+ compatible = "snps,dw-apb-gpio-bank";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-generic,nr-gpio = <16>;
+
+ regoffset-dat = <0x54>;
+ regoffset-set = <0x0c>;
+ regoffset-dirout = <0x10>;
+ };
+
+ bankd: gpio-controller@2 {
+ compatible = "snps,dw-apb-gpio-bank";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-generic,nr-gpio = <30>;
+
+ regoffset-dat = <0x5c>;
+ regoffset-set = <0x24>;
+ regoffset-dirout = <0x28>;
+ };
+ };
+
+ uart0: uart@30000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x30000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <10>;
+ clock-frequency = <3686400>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ uart1: uart@40000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x40000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <9>;
+ clock-frequency = <3686400>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ wdog: watchdog@50000 {
+ compatible = "snps,dw-apb-wdg";
+ reg = <0x50000 0x10000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <11>;
+ bus-clock = <&pclk>, "bus";
+ };
+
+ timer2: timer@60000 {
+ compatible = "picochip,pc3x2-timer";
+ interrupt-parent = <&vic0>;
+ interrupts = <6>;
+ clock-freq = <200000000>;
+ reg = <0x60000 0x14>;
+ };
+
+ timer3: timer@60014 {
+ compatible = "picochip,pc3x2-timer";
+ interrupt-parent = <&vic0>;
+ interrupts = <7>;
+ clock-freq = <200000000>;
+ reg = <0x60014 0x14>;
+ };
+ };
+ };
+
+ rwid-axi {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+
+ ebi@50000000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0x40000000 0x08000000
+ 1 0 0x48000000 0x08000000
+ 2 0 0x50000000 0x08000000
+ 3 0 0x58000000 0x08000000>;
+ };
+
+ axi2pico@c0000000 {
+ compatible = "picochip,axi2pico-pc3x3";
+ reg = <0xc0000000 0x10000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <13 14 15 16 17 18 19 20 21>;
+ };
+
+ otp@ffff8000 {
+ compatible = "picochip,otp-pc3x3";
+ reg = <0xffff8000 0x8000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/picoxcell-pc7302-pc3x2.dts b/arch/arm/boot/dts/picoxcell-pc7302-pc3x2.dts
new file mode 100644
index 000000000..1297414dd
--- /dev/null
+++ b/arch/arm/boot/dts/picoxcell-pc7302-pc3x2.dts
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2011 Picochip, Jamie Iles
+ *
+ * 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.
+ */
+
+/dts-v1/;
+/include/ "picoxcell-pc3x2.dtsi"
+/ {
+ model = "Picochip PC7302 (PC3X2)";
+ compatible = "picochip,pc7302-pc3x2", "picochip,pc3x2";
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x08000000>;
+ };
+
+ chosen {
+ linux,stdout-path = &uart0;
+ };
+
+ clocks {
+ ref_clk: clock@1 {
+ compatible = "fixed-clock";
+ clock-outputs = "ref";
+ clock-frequency = <20000000>;
+ };
+ };
+
+ rwid-axi {
+ ebi@50000000 {
+ nand: gpio-nand@2,0 {
+ compatible = "gpio-control-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <2 0x0000 0x1000>;
+ bus-clock = <&pclk>, "bus";
+ gpio-control-nand,io-sync-reg =
+ <0x00000000 0x80220000>;
+
+ gpios = <&banka 1 0 /* rdy */
+ &banka 2 0 /* nce */
+ &banka 3 0 /* ale */
+ &banka 4 0 /* cle */
+ 0 /* nwp */>;
+
+ boot@100000 {
+ label = "Boot";
+ reg = <0x100000 0x80000>;
+ };
+
+ redundant-boot@200000 {
+ label = "Redundant Boot";
+ reg = <0x200000 0x80000>;
+ };
+
+ boot-env@300000 {
+ label = "Boot Evironment";
+ reg = <0x300000 0x20000>;
+ };
+
+ redundant-boot-env@320000 {
+ label = "Redundant Boot Environment";
+ reg = <0x300000 0x20000>;
+ };
+
+ kernel@380000 {
+ label = "Kernel";
+ reg = <0x380000 0x800000>;
+ };
+
+ fs@b80000 {
+ label = "File System";
+ reg = <0xb80000 0xf480000>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/picoxcell-pc7302-pc3x3.dts b/arch/arm/boot/dts/picoxcell-pc7302-pc3x3.dts
new file mode 100644
index 000000000..9e317a4f4
--- /dev/null
+++ b/arch/arm/boot/dts/picoxcell-pc7302-pc3x3.dts
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2011 Picochip, Jamie Iles
+ *
+ * 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.
+ */
+
+/dts-v1/;
+/include/ "picoxcell-pc3x3.dtsi"
+/ {
+ model = "Picochip PC7302 (PC3X3)";
+ compatible = "picochip,pc7302-pc3x3", "picochip,pc3x3";
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x08000000>;
+ };
+
+ chosen {
+ linux,stdout-path = &uart0;
+ };
+
+ clocks {
+ ref_clk: clock@10 {
+ compatible = "fixed-clock";
+ clock-outputs = "ref";
+ clock-frequency = <20000000>;
+ };
+
+ clkgate: clkgate@800a0048 {
+ clock@4 {
+ picochip,clk-no-disable;
+ };
+ };
+ };
+
+ rwid-axi {
+ ebi@50000000 {
+ nand: gpio-nand@2,0 {
+ compatible = "gpio-control-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <2 0x0000 0x1000>;
+ bus-clock = <&ebi_clk>, "bus";
+ gpio-control-nand,io-sync-reg =
+ <0x00000000 0x80220000>;
+
+ gpios = <&banka 1 0 /* rdy */
+ &banka 2 0 /* nce */
+ &banka 3 0 /* ale */
+ &banka 4 0 /* cle */
+ 0 /* nwp */>;
+
+ boot@100000 {
+ label = "Boot";
+ reg = <0x100000 0x80000>;
+ };
+
+ redundant-boot@200000 {
+ label = "Redundant Boot";
+ reg = <0x200000 0x80000>;
+ };
+
+ boot-env@300000 {
+ label = "Boot Evironment";
+ reg = <0x300000 0x20000>;
+ };
+
+ redundant-boot-env@320000 {
+ label = "Redundant Boot Environment";
+ reg = <0x300000 0x20000>;
+ };
+
+ kernel@380000 {
+ label = "Kernel";
+ reg = <0x380000 0x800000>;
+ };
+
+ fs@b80000 {
+ label = "File System";
+ reg = <0xb80000 0xf480000>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/pm9g45.dts b/arch/arm/boot/dts/pm9g45.dts
new file mode 100644
index 000000000..66afcff67
--- /dev/null
+++ b/arch/arm/boot/dts/pm9g45.dts
@@ -0,0 +1,173 @@
+/*
+ * pm9g45.dts - Device Tree file for Ronetix pm9g45 board
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+/dts-v1/;
+#include "at91sam9g45.dtsi"
+
+/ {
+ model = "Ronetix pm9g45";
+ compatible = "ronetix,pm9g45", "atmel,at91sam9g45", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x70000000 0x8000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@ffffee00 {
+ status = "okay";
+ };
+
+ pinctrl@fffff200 {
+
+ board {
+ pinctrl_board_nand: nand0-board {
+ atmel,pins =
+ <AT91_PIOD 3 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP /* PD3 gpio RDY pin pull_up*/
+ AT91_PIOC 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>; /* PC14 gpio enable pin pull_up */
+ };
+ };
+
+ mmc {
+ pinctrl_board_mmc: mmc0-board {
+ atmel,pins =
+ <AT91_PIOD 6 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PD6 gpio CD pin pull_up and deglitch */
+ };
+ };
+ };
+
+ mmc0: mmc@fff80000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc
+ &pinctrl_mmc0_slot0_clk_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 6 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ macb0: ethernet@fffbc000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ pinctrl-0 = <&pinctrl_board_nand>;
+
+ gpios = <&pioD 3 GPIO_ACTIVE_HIGH
+ &pioC 14 GPIO_ACTIVE_HIGH
+ 0
+ >;
+
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x20000>;
+ };
+
+ barebox@20000 {
+ label = "barebox";
+ reg = <0x20000 0x40000>;
+ };
+
+ bareboxenv@60000 {
+ label = "bareboxenv";
+ reg = <0x60000 0x1A0000>;
+ };
+
+ kernel@200000 {
+ label = "bareboxenv2";
+ reg = <0x200000 0x300000>;
+ };
+
+ kernel@500000 {
+ label = "root";
+ reg = <0x500000 0x400000>;
+ };
+
+ data@900000 {
+ label = "data";
+ reg = <0x900000 0x8340000>;
+ };
+ };
+
+ usb0: ohci@00700000 {
+ status = "okay";
+ num-ports = <2>;
+ };
+
+ usb1: ehci@00800000 {
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led0 {
+ label = "led0";
+ gpios = <&pioD 0 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "nand-disk";
+ };
+
+ led1 {
+ label = "led1";
+ gpios = <&pioD 31 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ right {
+ label = "SW4";
+ gpios = <&pioE 7 GPIO_ACTIVE_LOW>;
+ linux,code = <106>;
+ };
+
+ up {
+ label = "SW3";
+ gpios = <&pioE 8 GPIO_ACTIVE_LOW>;
+ linux,code = <103>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/prima2-evb.dts b/arch/arm/boot/dts/prima2-evb.dts
new file mode 100644
index 000000000..57286b4e7
--- /dev/null
+++ b/arch/arm/boot/dts/prima2-evb.dts
@@ -0,0 +1,37 @@
+/*
+ * DTS file for CSR SiRFprimaII Evaluation Board
+ *
+ * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/dts-v1/;
+
+/include/ "prima2.dtsi"
+
+/ {
+ model = "CSR SiRFprimaII Evaluation Board";
+ compatible = "sirf,prima2", "sirf,prima2-cb";
+
+ memory {
+ reg = <0x00000000 0x20000000>;
+ };
+
+ axi {
+ peri-iobg {
+ uart@b0060000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_a>;
+ };
+ spi@b00d0000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins_a>;
+ };
+ spi@b0170000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins_a>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/prima2.dtsi b/arch/arm/boot/dts/prima2.dtsi
new file mode 100644
index 000000000..1ca1a9aa9
--- /dev/null
+++ b/arch/arm/boot/dts/prima2.dtsi
@@ -0,0 +1,840 @@
+/*
+ * DTS file for CSR SiRFprimaII SoC
+ *
+ * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/include/ "skeleton.dtsi"
+/ {
+ compatible = "sirf,prima2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&intc>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0x0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <32768>;
+ i-cache-size = <32768>;
+ /* from bootloader */
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ clocks = <&clks 12>;
+ operating-points = <
+ /* kHz uV */
+ 200000 1025000
+ 400000 1025000
+ 664000 1050000
+ 800000 1100000
+ >;
+ clock-latency = <150000>;
+ };
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <29>;
+ };
+
+ axi {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x40000000 0x40000000 0x80000000>;
+
+ l2-cache-controller@80040000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x80040000 0x1000>;
+ interrupts = <59>;
+ arm,tag-latency = <1 1 1>;
+ arm,data-latency = <1 1 1>;
+ arm,filter-ranges = <0 0x40000000>;
+ };
+
+ intc: interrupt-controller@80020000 {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "sirf,prima2-intc";
+ reg = <0x80020000 0x1000>;
+ };
+
+ sys-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x88000000 0x88000000 0x40000>;
+
+ clks: clock-controller@88000000 {
+ compatible = "sirf,prima2-clkc";
+ reg = <0x88000000 0x1000>;
+ interrupts = <3>;
+ #clock-cells = <1>;
+ };
+
+ rstc: reset-controller@88010000 {
+ compatible = "sirf,prima2-rstc";
+ reg = <0x88010000 0x1000>;
+ #reset-cells = <1>;
+ };
+
+ rsc-controller@88020000 {
+ compatible = "sirf,prima2-rsc";
+ reg = <0x88020000 0x1000>;
+ };
+
+ cphifbg@88030000 {
+ compatible = "sirf,prima2-cphifbg";
+ reg = <0x88030000 0x1000>;
+ clocks = <&clks 42>;
+ };
+ };
+
+ mem-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x90000000 0x90000000 0x10000>;
+
+ memory-controller@90000000 {
+ compatible = "sirf,prima2-memc";
+ reg = <0x90000000 0x2000>;
+ interrupts = <27>;
+ clocks = <&clks 5>;
+ };
+
+ memc-monitor {
+ compatible = "sirf,prima2-memcmon";
+ reg = <0x90002000 0x200>;
+ interrupts = <4>;
+ clocks = <&clks 32>;
+ };
+ };
+
+ disp-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x90010000 0x90010000 0x30000>;
+
+ display@90010000 {
+ compatible = "sirf,prima2-lcd";
+ reg = <0x90010000 0x20000>;
+ interrupts = <30>;
+ };
+
+ vpp@90020000 {
+ compatible = "sirf,prima2-vpp";
+ reg = <0x90020000 0x10000>;
+ interrupts = <31>;
+ clocks = <&clks 35>;
+ resets = <&rstc 6>;
+ };
+ };
+
+ graphics-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x98000000 0x98000000 0x8000000>;
+
+ graphics@98000000 {
+ compatible = "powervr,sgx531";
+ reg = <0x98000000 0x8000000>;
+ interrupts = <6>;
+ clocks = <&clks 32>;
+ };
+ };
+
+ multimedia-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0xa0000000 0xa0000000 0x8000000>;
+
+ multimedia@a0000000 {
+ compatible = "sirf,prima2-video-codec";
+ reg = <0xa0000000 0x8000000>;
+ interrupts = <5>;
+ clocks = <&clks 33>;
+ };
+ };
+
+ dsp-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0xa8000000 0xa8000000 0x2000000>;
+
+ dspif@a8000000 {
+ compatible = "sirf,prima2-dspif";
+ reg = <0xa8000000 0x10000>;
+ interrupts = <9>;
+ resets = <&rstc 1>;
+ };
+
+ gps@a8010000 {
+ compatible = "sirf,prima2-gps";
+ reg = <0xa8010000 0x10000>;
+ interrupts = <7>;
+ clocks = <&clks 9>;
+ resets = <&rstc 2>;
+ };
+
+ dsp@a9000000 {
+ compatible = "sirf,prima2-dsp";
+ reg = <0xa9000000 0x1000000>;
+ interrupts = <8>;
+ clocks = <&clks 8>;
+ resets = <&rstc 0>;
+ };
+ };
+
+ peri-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0xb0000000 0xb0000000 0x180000>,
+ <0x56000000 0x56000000 0x1b00000>;
+
+ timer@b0020000 {
+ compatible = "sirf,prima2-tick";
+ reg = <0xb0020000 0x1000>;
+ interrupts = <0>;
+ clocks = <&clks 11>;
+ };
+
+ nand@b0030000 {
+ compatible = "sirf,prima2-nand";
+ reg = <0xb0030000 0x10000>;
+ interrupts = <41>;
+ clocks = <&clks 26>;
+ };
+
+ audio@b0040000 {
+ compatible = "sirf,prima2-audio";
+ reg = <0xb0040000 0x10000>;
+ interrupts = <35>;
+ clocks = <&clks 27>;
+ };
+
+ uart0: uart@b0050000 {
+ cell-index = <0>;
+ compatible = "sirf,prima2-uart";
+ reg = <0xb0050000 0x1000>;
+ interrupts = <17>;
+ fifosize = <128>;
+ clocks = <&clks 13>;
+ dmas = <&dmac1 5>, <&dmac0 2>;
+ dma-names = "rx", "tx";
+ };
+
+ uart1: uart@b0060000 {
+ cell-index = <1>;
+ compatible = "sirf,prima2-uart";
+ reg = <0xb0060000 0x1000>;
+ interrupts = <18>;
+ fifosize = <32>;
+ clocks = <&clks 14>;
+ };
+
+ uart2: uart@b0070000 {
+ cell-index = <2>;
+ compatible = "sirf,prima2-uart";
+ reg = <0xb0070000 0x1000>;
+ interrupts = <19>;
+ fifosize = <128>;
+ clocks = <&clks 15>;
+ dmas = <&dmac0 6>, <&dmac0 7>;
+ dma-names = "rx", "tx";
+ };
+
+ usp0: usp@b0080000 {
+ cell-index = <0>;
+ compatible = "sirf,prima2-usp";
+ reg = <0xb0080000 0x10000>;
+ interrupts = <20>;
+ fifosize = <128>;
+ clocks = <&clks 28>;
+ dmas = <&dmac1 1>, <&dmac1 2>;
+ dma-names = "rx", "tx";
+ };
+
+ usp1: usp@b0090000 {
+ cell-index = <1>;
+ compatible = "sirf,prima2-usp";
+ reg = <0xb0090000 0x10000>;
+ interrupts = <21>;
+ fifosize = <128>;
+ clocks = <&clks 29>;
+ dmas = <&dmac0 14>, <&dmac0 15>;
+ dma-names = "rx", "tx";
+ };
+
+ usp2: usp@b00a0000 {
+ cell-index = <2>;
+ compatible = "sirf,prima2-usp";
+ reg = <0xb00a0000 0x10000>;
+ interrupts = <22>;
+ fifosize = <128>;
+ clocks = <&clks 30>;
+ dmas = <&dmac0 10>, <&dmac0 11>;
+ dma-names = "rx", "tx";
+ };
+
+ dmac0: dma-controller@b00b0000 {
+ cell-index = <0>;
+ compatible = "sirf,prima2-dmac";
+ reg = <0xb00b0000 0x10000>;
+ interrupts = <12>;
+ clocks = <&clks 24>;
+ #dma-cells = <1>;
+ };
+
+ dmac1: dma-controller@b0160000 {
+ cell-index = <1>;
+ compatible = "sirf,prima2-dmac";
+ reg = <0xb0160000 0x10000>;
+ interrupts = <13>;
+ clocks = <&clks 25>;
+ #dma-cells = <1>;
+ };
+
+ vip@b00C0000 {
+ compatible = "sirf,prima2-vip";
+ reg = <0xb00C0000 0x10000>;
+ clocks = <&clks 31>;
+ interrupts = <14>;
+ sirf,vip-dma-rx-channel = <16>;
+ };
+
+ spi0: spi@b00d0000 {
+ cell-index = <0>;
+ compatible = "sirf,prima2-spi";
+ reg = <0xb00d0000 0x10000>;
+ interrupts = <15>;
+ sirf,spi-num-chipselects = <1>;
+ dmas = <&dmac1 9>,
+ <&dmac1 4>;
+ dma-names = "rx", "tx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clks 19>;
+ status = "disabled";
+ };
+
+ spi1: spi@b0170000 {
+ cell-index = <1>;
+ compatible = "sirf,prima2-spi";
+ reg = <0xb0170000 0x10000>;
+ interrupts = <16>;
+ sirf,spi-num-chipselects = <1>;
+ dmas = <&dmac0 12>,
+ <&dmac0 13>;
+ dma-names = "rx", "tx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clks 20>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@b00e0000 {
+ cell-index = <0>;
+ compatible = "sirf,prima2-i2c";
+ reg = <0xb00e0000 0x10000>;
+ interrupts = <24>;
+ clocks = <&clks 17>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c1: i2c@b00f0000 {
+ cell-index = <1>;
+ compatible = "sirf,prima2-i2c";
+ reg = <0xb00f0000 0x10000>;
+ interrupts = <25>;
+ clocks = <&clks 18>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ tsc@b0110000 {
+ compatible = "sirf,prima2-tsc";
+ reg = <0xb0110000 0x10000>;
+ interrupts = <33>;
+ clocks = <&clks 16>;
+ };
+
+ gpio: pinctrl@b0120000 {
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ compatible = "sirf,prima2-pinctrl";
+ reg = <0xb0120000 0x10000>;
+ interrupts = <43 44 45 46 47>;
+ gpio-controller;
+ interrupt-controller;
+
+ lcd_16pins_a: lcd0@0 {
+ lcd {
+ sirf,pins = "lcd_16bitsgrp";
+ sirf,function = "lcd_16bits";
+ };
+ };
+ lcd_18pins_a: lcd0@1 {
+ lcd {
+ sirf,pins = "lcd_18bitsgrp";
+ sirf,function = "lcd_18bits";
+ };
+ };
+ lcd_24pins_a: lcd0@2 {
+ lcd {
+ sirf,pins = "lcd_24bitsgrp";
+ sirf,function = "lcd_24bits";
+ };
+ };
+ lcdrom_pins_a: lcdrom0@0 {
+ lcd {
+ sirf,pins = "lcdromgrp";
+ sirf,function = "lcdrom";
+ };
+ };
+ uart0_pins_a: uart0@0 {
+ uart {
+ sirf,pins = "uart0grp";
+ sirf,function = "uart0";
+ };
+ };
+ uart0_noflow_pins_a: uart0@1 {
+ uart {
+ sirf,pins = "uart0_nostreamctrlgrp";
+ sirf,function = "uart0_nostreamctrl";
+ };
+ };
+ uart1_pins_a: uart1@0 {
+ uart {
+ sirf,pins = "uart1grp";
+ sirf,function = "uart1";
+ };
+ };
+ uart2_pins_a: uart2@0 {
+ uart {
+ sirf,pins = "uart2grp";
+ sirf,function = "uart2";
+ };
+ };
+ uart2_noflow_pins_a: uart2@1 {
+ uart {
+ sirf,pins = "uart2_nostreamctrlgrp";
+ sirf,function = "uart2_nostreamctrl";
+ };
+ };
+ spi0_pins_a: spi0@0 {
+ spi {
+ sirf,pins = "spi0grp";
+ sirf,function = "spi0";
+ };
+ };
+ spi1_pins_a: spi1@0 {
+ spi {
+ sirf,pins = "spi1grp";
+ sirf,function = "spi1";
+ };
+ };
+ i2c0_pins_a: i2c0@0 {
+ i2c {
+ sirf,pins = "i2c0grp";
+ sirf,function = "i2c0";
+ };
+ };
+ i2c1_pins_a: i2c1@0 {
+ i2c {
+ sirf,pins = "i2c1grp";
+ sirf,function = "i2c1";
+ };
+ };
+ pwm0_pins_a: pwm0@0 {
+ pwm {
+ sirf,pins = "pwm0grp";
+ sirf,function = "pwm0";
+ };
+ };
+ pwm1_pins_a: pwm1@0 {
+ pwm {
+ sirf,pins = "pwm1grp";
+ sirf,function = "pwm1";
+ };
+ };
+ pwm2_pins_a: pwm2@0 {
+ pwm {
+ sirf,pins = "pwm2grp";
+ sirf,function = "pwm2";
+ };
+ };
+ pwm3_pins_a: pwm3@0 {
+ pwm {
+ sirf,pins = "pwm3grp";
+ sirf,function = "pwm3";
+ };
+ };
+ gps_pins_a: gps@0 {
+ gps {
+ sirf,pins = "gpsgrp";
+ sirf,function = "gps";
+ };
+ };
+ vip_pins_a: vip@0 {
+ vip {
+ sirf,pins = "vipgrp";
+ sirf,function = "vip";
+ };
+ };
+ sdmmc0_pins_a: sdmmc0@0 {
+ sdmmc0 {
+ sirf,pins = "sdmmc0grp";
+ sirf,function = "sdmmc0";
+ };
+ };
+ sdmmc1_pins_a: sdmmc1@0 {
+ sdmmc1 {
+ sirf,pins = "sdmmc1grp";
+ sirf,function = "sdmmc1";
+ };
+ };
+ sdmmc2_pins_a: sdmmc2@0 {
+ sdmmc2 {
+ sirf,pins = "sdmmc2grp";
+ sirf,function = "sdmmc2";
+ };
+ };
+ sdmmc3_pins_a: sdmmc3@0 {
+ sdmmc3 {
+ sirf,pins = "sdmmc3grp";
+ sirf,function = "sdmmc3";
+ };
+ };
+ sdmmc4_pins_a: sdmmc4@0 {
+ sdmmc4 {
+ sirf,pins = "sdmmc4grp";
+ sirf,function = "sdmmc4";
+ };
+ };
+ sdmmc5_pins_a: sdmmc5@0 {
+ sdmmc5 {
+ sirf,pins = "sdmmc5grp";
+ sirf,function = "sdmmc5";
+ };
+ };
+ i2s_mclk_pins_a: i2s_mclk@0 {
+ i2s_mclk {
+ sirf,pins = "i2smclkgrp";
+ sirf,function = "i2s_mclk";
+ };
+ };
+ i2s_ext_clk_input_pins_a: i2s_ext_clk_input@0 {
+ i2s_ext_clk_input {
+ sirf,pins = "i2s_ext_clk_inputgrp";
+ sirf,function = "i2s_ext_clk_input";
+ };
+ };
+ i2s_pins_a: i2s@0 {
+ i2s {
+ sirf,pins = "i2sgrp";
+ sirf,function = "i2s";
+ };
+ };
+ i2s_no_din_pins_a: i2s_no_din@0 {
+ i2s_no_din {
+ sirf,pins = "i2s_no_dingrp";
+ sirf,function = "i2s_no_din";
+ };
+ };
+ i2s_6chn_pins_a: i2s_6chn@0 {
+ i2s_6chn {
+ sirf,pins = "i2s_6chngrp";
+ sirf,function = "i2s_6chn";
+ };
+ };
+ ac97_pins_a: ac97@0 {
+ ac97 {
+ sirf,pins = "ac97grp";
+ sirf,function = "ac97";
+ };
+ };
+ nand_pins_a: nand@0 {
+ nand {
+ sirf,pins = "nandgrp";
+ sirf,function = "nand";
+ };
+ };
+ usp0_pins_a: usp0@0 {
+ usp0 {
+ sirf,pins = "usp0grp";
+ sirf,function = "usp0";
+ };
+ };
+ usp0_uart_nostreamctrl_pins_a: usp0@1 {
+ usp0 {
+ sirf,pins =
+ "usp0_uart_nostreamctrl_grp";
+ sirf,function =
+ "usp0_uart_nostreamctrl";
+ };
+ };
+ usp0_only_utfs_pins_a: usp0@2 {
+ usp0 {
+ sirf,pins = "usp0_only_utfs_grp";
+ sirf,function = "usp0_only_utfs";
+ };
+ };
+ usp0_only_urfs_pins_a: usp0@3 {
+ usp0 {
+ sirf,pins = "usp0_only_urfs_grp";
+ sirf,function = "usp0_only_urfs";
+ };
+ };
+ usp1_pins_a: usp1@0 {
+ usp1 {
+ sirf,pins = "usp1grp";
+ sirf,function = "usp1";
+ };
+ };
+ usp1_uart_nostreamctrl_pins_a: usp1@1 {
+ usp1 {
+ sirf,pins =
+ "usp1_uart_nostreamctrl_grp";
+ sirf,function =
+ "usp1_uart_nostreamctrl";
+ };
+ };
+ usp2_pins_a: usp2@0 {
+ usp2 {
+ sirf,pins = "usp2grp";
+ sirf,function = "usp2";
+ };
+ };
+ usp2_uart_nostreamctrl_pins_a: usp2@1 {
+ usp2 {
+ sirf,pins =
+ "usp2_uart_nostreamctrl_grp";
+ sirf,function =
+ "usp2_uart_nostreamctrl";
+ };
+ };
+ usb0_utmi_drvbus_pins_a: usb0_utmi_drvbus@0 {
+ usb0_utmi_drvbus {
+ sirf,pins = "usb0_utmi_drvbusgrp";
+ sirf,function = "usb0_utmi_drvbus";
+ };
+ };
+ usb1_utmi_drvbus_pins_a: usb1_utmi_drvbus@0 {
+ usb1_utmi_drvbus {
+ sirf,pins = "usb1_utmi_drvbusgrp";
+ sirf,function = "usb1_utmi_drvbus";
+ };
+ };
+ usb1_dp_dn_pins_a: usb1_dp_dn@0 {
+ usb1_dp_dn {
+ sirf,pins = "usb1_dp_dngrp";
+ sirf,function = "usb1_dp_dn";
+ };
+ };
+ uart1_route_io_usb1_pins_a: uart1_route_io_usb1@0 {
+ uart1_route_io_usb1 {
+ sirf,pins = "uart1_route_io_usb1grp";
+ sirf,function = "uart1_route_io_usb1";
+ };
+ };
+ warm_rst_pins_a: warm_rst@0 {
+ warm_rst {
+ sirf,pins = "warm_rstgrp";
+ sirf,function = "warm_rst";
+ };
+ };
+ pulse_count_pins_a: pulse_count@0 {
+ pulse_count {
+ sirf,pins = "pulse_countgrp";
+ sirf,function = "pulse_count";
+ };
+ };
+ cko0_pins_a: cko0@0 {
+ cko0 {
+ sirf,pins = "cko0grp";
+ sirf,function = "cko0";
+ };
+ };
+ cko1_pins_a: cko1@0 {
+ cko1 {
+ sirf,pins = "cko1grp";
+ sirf,function = "cko1";
+ };
+ };
+ };
+
+ pwm@b0130000 {
+ compatible = "sirf,prima2-pwm";
+ reg = <0xb0130000 0x10000>;
+ clocks = <&clks 21>;
+ };
+
+ efusesys@b0140000 {
+ compatible = "sirf,prima2-efuse";
+ reg = <0xb0140000 0x10000>;
+ clocks = <&clks 22>;
+ };
+
+ pulsec@b0150000 {
+ compatible = "sirf,prima2-pulsec";
+ reg = <0xb0150000 0x10000>;
+ interrupts = <48>;
+ clocks = <&clks 23>;
+ };
+
+ pci-iobg {
+ compatible = "sirf,prima2-pciiobg", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x56000000 0x56000000 0x1b00000>;
+
+ sd0: sdhci@56000000 {
+ cell-index = <0>;
+ compatible = "sirf,prima2-sdhc";
+ reg = <0x56000000 0x100000>;
+ interrupts = <38>;
+ status = "disabled";
+ bus-width = <8>;
+ clocks = <&clks 36>;
+ };
+
+ sd1: sdhci@56100000 {
+ cell-index = <1>;
+ compatible = "sirf,prima2-sdhc";
+ reg = <0x56100000 0x100000>;
+ interrupts = <38>;
+ status = "disabled";
+ bus-width = <4>;
+ clocks = <&clks 36>;
+ };
+
+ sd2: sdhci@56200000 {
+ cell-index = <2>;
+ compatible = "sirf,prima2-sdhc";
+ reg = <0x56200000 0x100000>;
+ interrupts = <23>;
+ status = "disabled";
+ clocks = <&clks 37>;
+ };
+
+ sd3: sdhci@56300000 {
+ cell-index = <3>;
+ compatible = "sirf,prima2-sdhc";
+ reg = <0x56300000 0x100000>;
+ interrupts = <23>;
+ status = "disabled";
+ clocks = <&clks 37>;
+ };
+
+ sd4: sdhci@56400000 {
+ cell-index = <4>;
+ compatible = "sirf,prima2-sdhc";
+ reg = <0x56400000 0x100000>;
+ interrupts = <39>;
+ status = "disabled";
+ clocks = <&clks 38>;
+ };
+
+ sd5: sdhci@56500000 {
+ cell-index = <5>;
+ compatible = "sirf,prima2-sdhc";
+ reg = <0x56500000 0x100000>;
+ interrupts = <39>;
+ clocks = <&clks 38>;
+ };
+
+ pci-copy@57900000 {
+ compatible = "sirf,prima2-pcicp";
+ reg = <0x57900000 0x100000>;
+ interrupts = <40>;
+ };
+
+ rom-interface@57a00000 {
+ compatible = "sirf,prima2-romif";
+ reg = <0x57a00000 0x100000>;
+ };
+ };
+ };
+
+ rtc-iobg {
+ compatible = "sirf,prima2-rtciobg", "sirf-prima2-rtciobg-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80030000 0x10000>;
+
+ gpsrtc@1000 {
+ compatible = "sirf,prima2-gpsrtc";
+ reg = <0x1000 0x1000>;
+ interrupts = <55 56 57>;
+ };
+
+ sysrtc@2000 {
+ compatible = "sirf,prima2-sysrtc";
+ reg = <0x2000 0x1000>;
+ interrupts = <52 53 54>;
+ };
+
+ minigpsrtc@2000 {
+ compatible = "sirf,prima2-minigpsrtc";
+ reg = <0x2000 0x1000>;
+ interrupts = <54>;
+ };
+
+ pwrc@3000 {
+ compatible = "sirf,prima2-pwrc";
+ reg = <0x3000 0x1000>;
+ interrupts = <32>;
+ };
+ };
+
+ uus-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0xb8000000 0xb8000000 0x40000>;
+
+ usb0: usb@b00e0000 {
+ compatible = "chipidea,ci13611a-prima2";
+ reg = <0xb8000000 0x10000>;
+ interrupts = <10>;
+ clocks = <&clks 40>;
+ };
+
+ usb1: usb@b00f0000 {
+ compatible = "chipidea,ci13611a-prima2";
+ reg = <0xb8010000 0x10000>;
+ interrupts = <11>;
+ clocks = <&clks 41>;
+ };
+
+ sata@b00f0000 {
+ compatible = "synopsys,dwc-ahsata";
+ reg = <0xb8020000 0x10000>;
+ interrupts = <37>;
+ };
+
+ security@b00f0000 {
+ compatible = "sirf,prima2-security";
+ reg = <0xb8030000 0x10000>;
+ interrupts = <42>;
+ clocks = <&clks 7>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/pxa168-aspenite.dts b/arch/arm/boot/dts/pxa168-aspenite.dts
new file mode 100644
index 000000000..0a988b3fb
--- /dev/null
+++ b/arch/arm/boot/dts/pxa168-aspenite.dts
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@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.
+ */
+
+/dts-v1/;
+#include "pxa168.dtsi"
+
+/ {
+ model = "Marvell PXA168 Aspenite Development Board";
+ compatible = "mrvl,pxa168-aspenite", "mrvl,pxa168";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on";
+ };
+
+ memory {
+ reg = <0x00000000 0x04000000>;
+ };
+
+ soc {
+ apb@d4000000 {
+ uart1: uart@d4017000 {
+ status = "okay";
+ };
+ twsi1: i2c@d4011000 {
+ status = "okay";
+ };
+ rtc: rtc@d4010000 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/pxa168.dtsi b/arch/arm/boot/dts/pxa168.dtsi
new file mode 100644
index 000000000..b899e25cb
--- /dev/null
+++ b/arch/arm/boot/dts/pxa168.dtsi
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@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 "skeleton.dtsi"
+#include <dt-bindings/clock/marvell,pxa168.h>
+
+/ {
+ aliases {
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ i2c0 = &twsi1;
+ i2c1 = &twsi2;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&intc>;
+ ranges;
+
+ axi@d4200000 { /* AXI */
+ compatible = "mrvl,axi-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd4200000 0x00200000>;
+ ranges;
+
+ intc: interrupt-controller@d4282000 {
+ compatible = "mrvl,mmp-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xd4282000 0x1000>;
+ mrvl,intc-nr-irqs = <64>;
+ };
+
+ };
+
+ apb@d4000000 { /* APB */
+ compatible = "mrvl,apb-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd4000000 0x00200000>;
+ ranges;
+
+ timer0: timer@d4014000 {
+ compatible = "mrvl,mmp-timer";
+ reg = <0xd4014000 0x100>;
+ interrupts = <13>;
+ };
+
+ uart1: uart@d4017000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4017000 0x1000>;
+ interrupts = <27>;
+ clocks = <&soc_clocks PXA168_CLK_UART0>;
+ resets = <&soc_clocks PXA168_CLK_UART0>;
+ status = "disabled";
+ };
+
+ uart2: uart@d4018000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4018000 0x1000>;
+ interrupts = <28>;
+ clocks = <&soc_clocks PXA168_CLK_UART1>;
+ resets = <&soc_clocks PXA168_CLK_UART1>;
+ status = "disabled";
+ };
+
+ uart3: uart@d4026000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4026000 0x1000>;
+ interrupts = <29>;
+ clocks = <&soc_clocks PXA168_CLK_UART2>;
+ resets = <&soc_clocks PXA168_CLK_UART2>;
+ status = "disabled";
+ };
+
+ gpio@d4019000 {
+ compatible = "marvell,mmp-gpio";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd4019000 0x1000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <49>;
+ clocks = <&soc_clocks PXA168_CLK_GPIO>;
+ resets = <&soc_clocks PXA168_CLK_GPIO>;
+ interrupt-names = "gpio_mux";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ ranges;
+
+ gcb0: gpio@d4019000 {
+ reg = <0xd4019000 0x4>;
+ };
+
+ gcb1: gpio@d4019004 {
+ reg = <0xd4019004 0x4>;
+ };
+
+ gcb2: gpio@d4019008 {
+ reg = <0xd4019008 0x4>;
+ };
+
+ gcb3: gpio@d4019100 {
+ reg = <0xd4019100 0x4>;
+ };
+ };
+
+ twsi1: i2c@d4011000 {
+ compatible = "mrvl,mmp-twsi";
+ reg = <0xd4011000 0x1000>;
+ interrupts = <7>;
+ clocks = <&soc_clocks PXA168_CLK_TWSI0>;
+ resets = <&soc_clocks PXA168_CLK_TWSI0>;
+ mrvl,i2c-fast-mode;
+ status = "disabled";
+ };
+
+ twsi2: i2c@d4025000 {
+ compatible = "mrvl,mmp-twsi";
+ reg = <0xd4025000 0x1000>;
+ interrupts = <58>;
+ clocks = <&soc_clocks PXA168_CLK_TWSI1>;
+ resets = <&soc_clocks PXA168_CLK_TWSI1>;
+ status = "disabled";
+ };
+
+ rtc: rtc@d4010000 {
+ compatible = "mrvl,mmp-rtc";
+ reg = <0xd4010000 0x1000>;
+ interrupts = <5 6>;
+ interrupt-names = "rtc 1Hz", "rtc alarm";
+ clocks = <&soc_clocks PXA168_CLK_RTC>;
+ resets = <&soc_clocks PXA168_CLK_RTC>;
+ status = "disabled";
+ };
+ };
+
+ soc_clocks: clocks{
+ compatible = "marvell,pxa168-clock";
+ reg = <0xd4050000 0x1000>,
+ <0xd4282800 0x400>,
+ <0xd4015000 0x1000>;
+ reg-names = "mpmu", "apmu", "apbc";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi
new file mode 100644
index 000000000..80fc5d7e9
--- /dev/null
+++ b/arch/arm/boot/dts/pxa27x.dtsi
@@ -0,0 +1,56 @@
+/* The pxa3xx skeleton simply augments the 2xx version */
+#include "pxa2xx.dtsi"
+#include "dt-bindings/clock/pxa2xx-clock.h"
+
+/ {
+ model = "Marvell PXA27x familiy SoC";
+ compatible = "marvell,pxa27x";
+
+ pxabus {
+ pxairq: interrupt-controller@40d00000 {
+ marvell,intc-priority;
+ marvell,intc-nr-irqs = <34>;
+ };
+
+ pwm0: pwm@40b00000 {
+ compatible = "marvell,pxa270-pwm", "marvell,pxa250-pwm";
+ reg = <0x40b00000 0x10>;
+ #pwm-cells = <1>;
+ };
+
+ pwm1: pwm@40b00010 {
+ compatible = "marvell,pxa270-pwm", "marvell,pxa250-pwm";
+ reg = <0x40b00010 0x10>;
+ #pwm-cells = <1>;
+ };
+
+ pwm2: pwm@40c00000 {
+ compatible = "marvell,pxa270-pwm", "marvell,pxa250-pwm";
+ reg = <0x40c00000 0x10>;
+ #pwm-cells = <1>;
+ };
+
+ pwm3: pwm@40c00010 {
+ compatible = "marvell,pxa270-pwm", "marvell,pxa250-pwm";
+ reg = <0x40c00010 0x10>;
+ #pwm-cells = <1>;
+ };
+ };
+
+ clocks {
+ /*
+ * The muxing of external clocks/internal dividers for osc* clock
+ * sources has been hidden under the carpet by now.
+ */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pxa2xx_clks: pxa2xx_clks@41300004 {
+ compatible = "marvell,pxa-clocks";
+ #clock-cells = <1>;
+ status = "okay";
+ };
+ };
+
+};
diff --git a/arch/arm/boot/dts/pxa2xx.dtsi b/arch/arm/boot/dts/pxa2xx.dtsi
new file mode 100644
index 000000000..c08f84629
--- /dev/null
+++ b/arch/arm/boot/dts/pxa2xx.dtsi
@@ -0,0 +1,135 @@
+/*
+ * pxa2xx.dtsi - Device Tree Include file for Marvell PXA2xx family SoC
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "Marvell PXA2xx family SoC";
+ compatible = "marvell,pxa2xx";
+ interrupt-parent = <&pxairq>;
+
+ aliases {
+ serial0 = &ffuart;
+ serial1 = &btuart;
+ serial2 = &stuart;
+ serial3 = &hwuart;
+ i2c0 = &pwri2c;
+ i2c1 = &pxai2c1;
+ };
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+ cpu {
+ compatible = "marvell,xscale";
+ device_type = "cpu";
+ };
+ };
+
+ pxabus {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pxairq: interrupt-controller@40d00000 {
+ #interrupt-cells = <1>;
+ compatible = "marvell,pxa-intc";
+ interrupt-controller;
+ interrupt-parent;
+ marvell,intc-nr-irqs = <32>;
+ reg = <0x40d00000 0xd0>;
+ };
+
+ gpio: gpio@40e00000 {
+ compatible = "mrvl,pxa-gpio";
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ reg = <0x40e00000 0x10000>;
+ gpio-controller;
+ #gpio-cells = <0x2>;
+ interrupts = <10>;
+ interrupt-names = "gpio_mux";
+ interrupt-controller;
+ #interrupt-cells = <0x2>;
+ ranges;
+
+ gcb0: gpio@40e00000 {
+ reg = <0x40e00000 0x4>;
+ };
+
+ gcb1: gpio@40e00004 {
+ reg = <0x40e00004 0x4>;
+ };
+
+ gcb2: gpio@40e00008 {
+ reg = <0x40e00008 0x4>;
+ };
+ gcb3: gpio@40e0000c {
+ reg = <0x40e0000c 0x4>;
+ };
+ };
+
+ ffuart: uart@40100000 {
+ compatible = "mrvl,pxa-uart";
+ reg = <0x40100000 0x30>;
+ interrupts = <22>;
+ status = "disabled";
+ };
+
+ btuart: uart@40200000 {
+ compatible = "mrvl,pxa-uart";
+ reg = <0x40200000 0x30>;
+ interrupts = <21>;
+ status = "disabled";
+ };
+
+ stuart: uart@40700000 {
+ compatible = "mrvl,pxa-uart";
+ reg = <0x40700000 0x30>;
+ interrupts = <20>;
+ status = "disabled";
+ };
+
+ hwuart: uart@41100000 {
+ compatible = "mrvl,pxa-uart";
+ reg = <0x41100000 0x30>;
+ interrupts = <7>;
+ status = "disabled";
+ };
+
+ pxai2c1: i2c@40301680 {
+ compatible = "mrvl,pxa-i2c";
+ reg = <0x40301680 0x30>;
+ interrupts = <18>;
+ #address-cells = <0x1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ usb0: ohci@4c000000 {
+ compatible = "marvell,pxa-ohci";
+ reg = <0x4c000000 0x10000>;
+ interrupts = <3>;
+ status = "disabled";
+ };
+
+ mmc0: mmc@41100000 {
+ compatible = "marvell,pxa-mmc";
+ reg = <0x41100000 0x1000>;
+ interrupts = <23>;
+ status = "disabled";
+ };
+
+ rtc@40900000 {
+ compatible = "marvell,pxa-rtc";
+ reg = <0x40900000 0x3c>;
+ interrupts = <30 31>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/pxa3xx.dtsi b/arch/arm/boot/dts/pxa3xx.dtsi
new file mode 100644
index 000000000..83bb0eff6
--- /dev/null
+++ b/arch/arm/boot/dts/pxa3xx.dtsi
@@ -0,0 +1,43 @@
+/* The pxa3xx skeleton simply augments the 2xx version */
+/include/ "pxa2xx.dtsi"
+
+/ {
+ model = "Marvell PXA3xx familiy SoC";
+ compatible = "marvell,pxa3xx";
+
+ pxabus {
+ pwri2c: i2c@40f500c0 {
+ compatible = "mrvl,pwri2c";
+ reg = <0x40f500c0 0x30>;
+ interrupts = <6>;
+ #address-cells = <0x1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ nand0: nand@43100000 {
+ compatible = "marvell,pxa3xx-nand";
+ reg = <0x43100000 90>;
+ interrupts = <45>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+ };
+
+ pxairq: interrupt-controller@40d00000 {
+ marvell,intc-priority;
+ marvell,intc-nr-irqs = <56>;
+ };
+
+ gpio: gpio@40e00000 {
+ compatible = "intel,pxa3xx-gpio";
+ reg = <0x40e00000 0x10000>;
+ interrupt-names = "gpio0", "gpio1", "gpio_mux";
+ interrupts = <8 9 10>;
+ gpio-controller;
+ #gpio-cells = <0x2>;
+ interrupt-controller;
+ #interrupt-cells = <0x2>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
new file mode 100644
index 000000000..c82f2810e
--- /dev/null
+++ b/arch/arm/boot/dts/pxa910-dkb.dts
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@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.
+ */
+
+/dts-v1/;
+#include "pxa910.dtsi"
+
+/ {
+ model = "Marvell PXA910 DKB Development Board";
+ compatible = "mrvl,pxa910-dkb", "mrvl,pxa910";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on";
+ };
+
+ memory {
+ reg = <0x00000000 0x10000000>;
+ };
+
+ soc {
+ apb@d4000000 {
+ uart1: uart@d4017000 {
+ status = "okay";
+ };
+ twsi1: i2c@d4011000 {
+ status = "okay";
+
+ pmic: 88pm860x@34 {
+ compatible = "marvell,88pm860x";
+ reg = <0x34>;
+ interrupts = <4>;
+ interrupt-parent = <&intc>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ marvell,88pm860x-irq-read-clr;
+ marvell,88pm860x-slave-addr = <0x11>;
+
+ regulators {
+ BUCK1 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ BUCK2 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ BUCK3 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO1 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO2 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ LDO5 {
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO9 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO10 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO12 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ LDO13 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ LDO14 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ rtc {
+ marvell,88pm860x-vrtc = <1>;
+ };
+ touch {
+ marvell,88pm860x-gpadc-prebias = <1>;
+ marvell,88pm860x-gpadc-slot-cycle = <1>;
+ marvell,88pm860x-tsi-prebias = <6>;
+ marvell,88pm860x-pen-prebias = <16>;
+ marvell,88pm860x-pen-prechg = <2>;
+ marvell,88pm860x-resistor-X = <300>;
+ };
+ backlights {
+ backlight-0 {
+ marvell,88pm860x-iset = <4>;
+ marvell,88pm860x-pwm = <3>;
+ };
+ backlight-2 {
+ };
+ };
+ leds {
+ led0-red {
+ marvell,88pm860x-iset = <12>;
+ };
+ led0-green {
+ marvell,88pm860x-iset = <12>;
+ };
+ led0-blue {
+ marvell,88pm860x-iset = <12>;
+ };
+ };
+ };
+ };
+ rtc: rtc@d4010000 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
new file mode 100644
index 000000000..0868f6729
--- /dev/null
+++ b/arch/arm/boot/dts/pxa910.dtsi
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@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 "skeleton.dtsi"
+#include <dt-bindings/clock/marvell,pxa910.h>
+
+/ {
+ aliases {
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ i2c0 = &twsi1;
+ i2c1 = &twsi2;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&intc>;
+ ranges;
+
+ L2: l2-cache {
+ compatible = "marvell,tauros2-cache";
+ marvell,tauros2-cache-features = <0x3>;
+ };
+
+ axi@d4200000 { /* AXI */
+ compatible = "mrvl,axi-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd4200000 0x00200000>;
+ ranges;
+
+ intc: interrupt-controller@d4282000 {
+ compatible = "mrvl,mmp-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xd4282000 0x1000>;
+ mrvl,intc-nr-irqs = <64>;
+ };
+
+ };
+
+ apb@d4000000 { /* APB */
+ compatible = "mrvl,apb-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd4000000 0x00200000>;
+ ranges;
+
+ timer0: timer@d4014000 {
+ compatible = "mrvl,mmp-timer";
+ reg = <0xd4014000 0x100>;
+ interrupts = <13>;
+ };
+
+ timer1: timer@d4016000 {
+ compatible = "mrvl,mmp-timer";
+ reg = <0xd4016000 0x100>;
+ interrupts = <29>;
+ status = "disabled";
+ };
+
+ uart1: uart@d4017000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4017000 0x1000>;
+ interrupts = <27>;
+ clocks = <&soc_clocks PXA910_CLK_UART0>;
+ resets = <&soc_clocks PXA910_CLK_UART0>;
+ status = "disabled";
+ };
+
+ uart2: uart@d4018000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4018000 0x1000>;
+ interrupts = <28>;
+ clocks = <&soc_clocks PXA910_CLK_UART1>;
+ resets = <&soc_clocks PXA910_CLK_UART1>;
+ status = "disabled";
+ };
+
+ uart3: uart@d4036000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4036000 0x1000>;
+ interrupts = <59>;
+ clocks = <&soc_clocks PXA910_CLK_UART2>;
+ resets = <&soc_clocks PXA910_CLK_UART2>;
+ status = "disabled";
+ };
+
+ gpio@d4019000 {
+ compatible = "marvell,mmp-gpio";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd4019000 0x1000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <49>;
+ interrupt-names = "gpio_mux";
+ clocks = <&soc_clocks PXA910_CLK_GPIO>;
+ resets = <&soc_clocks PXA910_CLK_GPIO>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ ranges;
+
+ gcb0: gpio@d4019000 {
+ reg = <0xd4019000 0x4>;
+ };
+
+ gcb1: gpio@d4019004 {
+ reg = <0xd4019004 0x4>;
+ };
+
+ gcb2: gpio@d4019008 {
+ reg = <0xd4019008 0x4>;
+ };
+
+ gcb3: gpio@d4019100 {
+ reg = <0xd4019100 0x4>;
+ };
+ };
+
+ twsi1: i2c@d4011000 {
+ compatible = "mrvl,mmp-twsi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xd4011000 0x1000>;
+ interrupts = <7>;
+ clocks = <&soc_clocks PXA910_CLK_TWSI0>;
+ resets = <&soc_clocks PXA910_CLK_TWSI0>;
+ mrvl,i2c-fast-mode;
+ status = "disabled";
+ };
+
+ twsi2: i2c@d4037000 {
+ compatible = "mrvl,mmp-twsi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xd4037000 0x1000>;
+ interrupts = <54>;
+ clocks = <&soc_clocks PXA910_CLK_TWSI1>;
+ resets = <&soc_clocks PXA910_CLK_TWSI1>;
+ status = "disabled";
+ };
+
+ rtc: rtc@d4010000 {
+ compatible = "mrvl,mmp-rtc";
+ reg = <0xd4010000 0x1000>;
+ interrupts = <5 6>;
+ interrupt-names = "rtc 1Hz", "rtc alarm";
+ clocks = <&soc_clocks PXA910_CLK_RTC>;
+ resets = <&soc_clocks PXA910_CLK_RTC>;
+ status = "disabled";
+ };
+ };
+
+ soc_clocks: clocks{
+ compatible = "marvell,pxa910-clock";
+ reg = <0xd4050000 0x1000>,
+ <0xd4282800 0x400>,
+ <0xd4015000 0x1000>,
+ <0xd403b000 0x1000>;
+ reg-names = "mpmu", "apmu", "apbc", "apbcp";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
new file mode 100644
index 000000000..5d75666f7
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
@@ -0,0 +1,59 @@
+#include "qcom-apq8064-v2.0.dtsi"
+
+/ {
+ model = "CompuLab CM-QS600";
+ compatible = "qcom,apq8064-cm-qs600", "qcom,apq8064";
+
+ soc {
+ pinctrl@800000 {
+ i2c1_pins: i2c1 {
+ mux {
+ pins = "gpio20", "gpio21";
+ function = "gsbi1";
+ };
+ };
+ };
+
+ gsbi@12440000 {
+ status = "okay";
+ qcom,mode = <GSBI_PROT_I2C>;
+
+ i2c@12460000 {
+ status = "okay";
+ clock-frequency = <200000>;
+ pinctrl-0 = <&i2c1_pins>;
+ pinctrl-names = "default";
+
+ eeprom: eeprom@50 {
+ compatible = "24c02";
+ reg = <0x50>;
+ pagesize = <32>;
+ };
+ };
+ };
+
+ gsbi@16600000 {
+ status = "ok";
+ qcom,mode = <GSBI_PROT_I2C_UART>;
+ serial@16640000 {
+ status = "ok";
+ };
+ };
+
+ amba {
+ /* eMMC */
+ sdcc1: sdcc@12400000 {
+ status = "okay";
+ };
+
+ /* External micro SD card */
+ sdcc3: sdcc@12180000 {
+ status = "okay";
+ };
+ /* WLAN */
+ sdcc4: sdcc@121c0000 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
new file mode 100644
index 000000000..e641001ca
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
@@ -0,0 +1,71 @@
+#include "qcom-apq8064-v2.0.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Qualcomm APQ8064/IFC6410";
+ compatible = "qcom,apq8064-ifc6410", "qcom,apq8064";
+
+ soc {
+ pinctrl@800000 {
+ i2c1_pins: i2c1 {
+ mux {
+ pins = "gpio20", "gpio21";
+ function = "gsbi1";
+ };
+ };
+
+ card_detect: card_detect {
+ mux {
+ pins = "gpio26";
+ function = "gpio";
+ bias-disable;
+ };
+ };
+ };
+
+ gsbi@12440000 {
+ status = "okay";
+ qcom,mode = <GSBI_PROT_I2C>;
+
+ i2c@12460000 {
+ status = "okay";
+ clock-frequency = <200000>;
+ pinctrl-0 = <&i2c1_pins>;
+ pinctrl-names = "default";
+
+ eeprom: eeprom@52 {
+ compatible = "atmel,24c128";
+ reg = <0x52>;
+ pagesize = <32>;
+ };
+ };
+ };
+
+ gsbi@16600000 {
+ status = "ok";
+ qcom,mode = <GSBI_PROT_I2C_UART>;
+ serial@16640000 {
+ status = "ok";
+ };
+ };
+
+ amba {
+ /* eMMC */
+ sdcc1: sdcc@12400000 {
+ status = "okay";
+ };
+
+ /* External micro SD card */
+ sdcc3: sdcc@12180000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&card_detect>;
+ cd-gpios = <&tlmm_pinmux 26 GPIO_ACTIVE_LOW>;
+ };
+ /* WLAN */
+ sdcc4: sdcc@121c0000 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-apq8064-v2.0.dtsi b/arch/arm/boot/dts/qcom-apq8064-v2.0.dtsi
new file mode 100644
index 000000000..935c3945f
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-apq8064-v2.0.dtsi
@@ -0,0 +1 @@
+#include "qcom-apq8064.dtsi"
diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
new file mode 100644
index 000000000..6c1511263
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
@@ -0,0 +1,388 @@
+/dts-v1/;
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/qcom,gcc-msm8960.h>
+#include <dt-bindings/clock/qcom,mmcc-msm8960.h>
+#include <dt-bindings/soc/qcom,gsbi.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ model = "Qualcomm APQ8064";
+ compatible = "qcom,apq8064";
+ interrupt-parent = <&intc>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "qcom,krait";
+ enable-method = "qcom,kpss-acc-v1";
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc0>;
+ qcom,saw = <&saw0>;
+ cpu-idle-states = <&CPU_SPC>;
+ };
+
+ cpu@1 {
+ compatible = "qcom,krait";
+ enable-method = "qcom,kpss-acc-v1";
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc1>;
+ qcom,saw = <&saw1>;
+ cpu-idle-states = <&CPU_SPC>;
+ };
+
+ cpu@2 {
+ compatible = "qcom,krait";
+ enable-method = "qcom,kpss-acc-v1";
+ device_type = "cpu";
+ reg = <2>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc2>;
+ qcom,saw = <&saw2>;
+ cpu-idle-states = <&CPU_SPC>;
+ };
+
+ cpu@3 {
+ compatible = "qcom,krait";
+ enable-method = "qcom,kpss-acc-v1";
+ device_type = "cpu";
+ reg = <3>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc3>;
+ qcom,saw = <&saw3>;
+ cpu-idle-states = <&CPU_SPC>;
+ };
+
+ L2: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ };
+
+ idle-states {
+ CPU_SPC: spc {
+ compatible = "qcom,idle-state-spc",
+ "arm,idle-state";
+ entry-latency-us = <400>;
+ exit-latency-us = <900>;
+ min-residency-us = <3000>;
+ };
+ };
+ };
+
+ cpu-pmu {
+ compatible = "qcom,krait-pmu";
+ interrupts = <1 10 0x304>;
+ };
+
+ soc: soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "simple-bus";
+
+ tlmm_pinmux: pinctrl@800000 {
+ compatible = "qcom,apq8064-pinctrl";
+ reg = <0x800000 0x4000>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <0 16 IRQ_TYPE_LEVEL_HIGH>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&ps_hold>;
+
+ sdc4_gpios: sdc4-gpios {
+ pios {
+ pins = "gpio63", "gpio64", "gpio65", "gpio66", "gpio67", "gpio68";
+ function = "sdc4";
+ };
+ };
+
+ ps_hold: ps_hold {
+ mux {
+ pins = "gpio78";
+ function = "ps_hold";
+ };
+ };
+ };
+
+ intc: interrupt-controller@2000000 {
+ compatible = "qcom,msm-qgic2";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x02000000 0x1000>,
+ <0x02002000 0x1000>;
+ };
+
+ timer@200a000 {
+ compatible = "qcom,kpss-timer", "qcom,msm-timer";
+ interrupts = <1 1 0x301>,
+ <1 2 0x301>,
+ <1 3 0x301>;
+ reg = <0x0200a000 0x100>;
+ clock-frequency = <27000000>,
+ <32768>;
+ cpu-offset = <0x80000>;
+ };
+
+ acc0: clock-controller@2088000 {
+ compatible = "qcom,kpss-acc-v1";
+ reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
+ };
+
+ acc1: clock-controller@2098000 {
+ compatible = "qcom,kpss-acc-v1";
+ reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
+ };
+
+ acc2: clock-controller@20a8000 {
+ compatible = "qcom,kpss-acc-v1";
+ reg = <0x020a8000 0x1000>, <0x02008000 0x1000>;
+ };
+
+ acc3: clock-controller@20b8000 {
+ compatible = "qcom,kpss-acc-v1";
+ reg = <0x020b8000 0x1000>, <0x02008000 0x1000>;
+ };
+
+ saw0: power-controller@2089000 {
+ compatible = "qcom,apq8064-saw2-v1.1-cpu", "qcom,saw2";
+ reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
+ regulator;
+ };
+
+ saw1: power-controller@2099000 {
+ compatible = "qcom,apq8064-saw2-v1.1-cpu", "qcom,saw2";
+ reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
+ regulator;
+ };
+
+ saw2: power-controller@20a9000 {
+ compatible = "qcom,apq8064-saw2-v1.1-cpu", "qcom,saw2";
+ reg = <0x020a9000 0x1000>, <0x02009000 0x1000>;
+ regulator;
+ };
+
+ saw3: power-controller@20b9000 {
+ compatible = "qcom,apq8064-saw2-v1.1-cpu", "qcom,saw2";
+ reg = <0x020b9000 0x1000>, <0x02009000 0x1000>;
+ regulator;
+ };
+
+ gsbi1: gsbi@12440000 {
+ status = "disabled";
+ compatible = "qcom,gsbi-v1.0.0";
+ cell-index = <1>;
+ reg = <0x12440000 0x100>;
+ clocks = <&gcc GSBI1_H_CLK>;
+ clock-names = "iface";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ syscon-tcsr = <&tcsr>;
+
+ i2c1: i2c@12460000 {
+ compatible = "qcom,i2c-qup-v1.1.1";
+ reg = <0x12460000 0x1000>;
+ interrupts = <0 194 IRQ_TYPE_NONE>;
+ clocks = <&gcc GSBI1_QUP_CLK>, <&gcc GSBI1_H_CLK>;
+ clock-names = "core", "iface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ gsbi2: gsbi@12480000 {
+ status = "disabled";
+ compatible = "qcom,gsbi-v1.0.0";
+ cell-index = <2>;
+ reg = <0x12480000 0x100>;
+ clocks = <&gcc GSBI2_H_CLK>;
+ clock-names = "iface";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ syscon-tcsr = <&tcsr>;
+
+ i2c2: i2c@124a0000 {
+ compatible = "qcom,i2c-qup-v1.1.1";
+ reg = <0x124a0000 0x1000>;
+ interrupts = <0 196 IRQ_TYPE_NONE>;
+ clocks = <&gcc GSBI2_QUP_CLK>, <&gcc GSBI2_H_CLK>;
+ clock-names = "core", "iface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ gsbi7: gsbi@16600000 {
+ status = "disabled";
+ compatible = "qcom,gsbi-v1.0.0";
+ cell-index = <7>;
+ reg = <0x16600000 0x100>;
+ clocks = <&gcc GSBI7_H_CLK>;
+ clock-names = "iface";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ syscon-tcsr = <&tcsr>;
+
+ serial@16640000 {
+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+ reg = <0x16640000 0x1000>,
+ <0x16600000 0x1000>;
+ interrupts = <0 158 0x0>;
+ clocks = <&gcc GSBI7_UART_CLK>, <&gcc GSBI7_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+ };
+
+ qcom,ssbi@500000 {
+ compatible = "qcom,ssbi";
+ reg = <0x00500000 0x1000>;
+ qcom,controller-type = "pmic-arbiter";
+ };
+
+ gcc: clock-controller@900000 {
+ compatible = "qcom,gcc-apq8064";
+ reg = <0x00900000 0x4000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ lcc: clock-controller@28000000 {
+ compatible = "qcom,lcc-apq8064";
+ reg = <0x28000000 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ mmcc: clock-controller@4000000 {
+ compatible = "qcom,mmcc-apq8064";
+ reg = <0x4000000 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ /* Temporary fixed regulator */
+ vsdcc_fixed: vsdcc-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "SDCC Power";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ regulator-always-on;
+ };
+
+ sdcc1bam:dma@12402000{
+ compatible = "qcom,bam-v1.3.0";
+ reg = <0x12402000 0x8000>;
+ interrupts = <0 98 0>;
+ clocks = <&gcc SDC1_H_CLK>;
+ clock-names = "bam_clk";
+ #dma-cells = <1>;
+ qcom,ee = <0>;
+ };
+
+ sdcc3bam:dma@12182000{
+ compatible = "qcom,bam-v1.3.0";
+ reg = <0x12182000 0x8000>;
+ interrupts = <0 96 0>;
+ clocks = <&gcc SDC3_H_CLK>;
+ clock-names = "bam_clk";
+ #dma-cells = <1>;
+ qcom,ee = <0>;
+ };
+
+ sdcc4bam:dma@121c2000{
+ compatible = "qcom,bam-v1.3.0";
+ reg = <0x121c2000 0x8000>;
+ interrupts = <0 95 0>;
+ clocks = <&gcc SDC4_H_CLK>;
+ clock-names = "bam_clk";
+ #dma-cells = <1>;
+ qcom,ee = <0>;
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ sdcc1: sdcc@12400000 {
+ status = "disabled";
+ compatible = "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x00051180>;
+ reg = <0x12400000 0x2000>;
+ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "cmd_irq";
+ clocks = <&gcc SDC1_CLK>, <&gcc SDC1_H_CLK>;
+ clock-names = "mclk", "apb_pclk";
+ bus-width = <8>;
+ max-frequency = <96000000>;
+ non-removable;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ vmmc-supply = <&vsdcc_fixed>;
+ dmas = <&sdcc1bam 2>, <&sdcc1bam 1>;
+ dma-names = "tx", "rx";
+ };
+
+ sdcc3: sdcc@12180000 {
+ compatible = "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x00051180>;
+ status = "disabled";
+ reg = <0x12180000 0x2000>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "cmd_irq";
+ clocks = <&gcc SDC3_CLK>, <&gcc SDC3_H_CLK>;
+ clock-names = "mclk", "apb_pclk";
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <192000000>;
+ no-1-8-v;
+ vmmc-supply = <&vsdcc_fixed>;
+ dmas = <&sdcc3bam 2>, <&sdcc3bam 1>;
+ dma-names = "tx", "rx";
+ };
+
+ sdcc4: sdcc@121c0000 {
+ compatible = "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x00051180>;
+ status = "disabled";
+ reg = <0x121c0000 0x2000>;
+ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "cmd_irq";
+ clocks = <&gcc SDC4_CLK>, <&gcc SDC4_H_CLK>;
+ clock-names = "mclk", "apb_pclk";
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <48000000>;
+ vmmc-supply = <&vsdcc_fixed>;
+ vqmmc-supply = <&vsdcc_fixed>;
+ dmas = <&sdcc4bam 2>, <&sdcc4bam 1>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdc4_gpios>;
+ };
+ };
+
+ tcsr: syscon@1a400000 {
+ compatible = "qcom,tcsr-apq8064", "syscon";
+ reg = <0x1a400000 0x100>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
new file mode 100644
index 000000000..d484d0816
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
@@ -0,0 +1,68 @@
+#include "qcom-msm8974.dtsi"
+#include "qcom-pm8841.dtsi"
+#include "qcom-pm8941.dtsi"
+
+/ {
+ model = "Qualcomm APQ8074 Dragonboard";
+ compatible = "qcom,apq8074-dragonboard", "qcom,apq8074";
+
+ soc {
+ serial@f991e000 {
+ status = "ok";
+ };
+
+ sdhci@f9824900 {
+ bus-width = <8>;
+ non-removable;
+ status = "ok";
+ };
+
+ sdhci@f98a4900 {
+ cd-gpios = <&msmgpio 62 0x1>;
+ bus-width = <4>;
+ };
+
+
+ pinctrl@fd510000 {
+ i2c11_pins: i2c11 {
+ mux {
+ pins = "gpio83", "gpio84";
+ function = "blsp_i2c11";
+ };
+ };
+
+ spi8_default: spi8_default {
+ mosi {
+ pins = "gpio45";
+ function = "blsp_spi8";
+ };
+ miso {
+ pins = "gpio46";
+ function = "blsp_spi8";
+ };
+ cs {
+ pins = "gpio47";
+ function = "blsp_spi8";
+ };
+ clk {
+ pins = "gpio48";
+ function = "blsp_spi8";
+ };
+ };
+ };
+
+ i2c@f9967000 {
+ status = "okay";
+ clock-frequency = <200000>;
+ pinctrl-0 = <&i2c11_pins>;
+ pinctrl-names = "default";
+
+ eeprom: eeprom@52 {
+ compatible = "atmel,24c128";
+ reg = <0x52>;
+ pagesize = <32>;
+ read-only;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-apq8084-ifc6540.dts b/arch/arm/boot/dts/qcom-apq8084-ifc6540.dts
new file mode 100644
index 000000000..f7725b966
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-apq8084-ifc6540.dts
@@ -0,0 +1,24 @@
+#include "qcom-apq8084.dtsi"
+#include "qcom-pma8084.dtsi"
+
+/ {
+ model = "Qualcomm APQ8084/IFC6540";
+ compatible = "qcom,apq8084-ifc6540", "qcom,apq8084";
+
+ soc {
+ serial@f995e000 {
+ status = "okay";
+ };
+
+ sdhci@f9824900 {
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+ };
+
+ sdhci@f98a4900 {
+ cd-gpios = <&tlmm 122 GPIO_ACTIVE_LOW>;
+ bus-width = <4>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-apq8084-mtp.dts b/arch/arm/boot/dts/qcom-apq8084-mtp.dts
new file mode 100644
index 000000000..cb43acfc5
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-apq8084-mtp.dts
@@ -0,0 +1,13 @@
+#include "qcom-apq8084.dtsi"
+#include "qcom-pma8084.dtsi"
+
+/ {
+ model = "Qualcomm APQ 8084-MTP";
+ compatible = "qcom,apq8084-mtp", "qcom,apq8084";
+
+ soc {
+ serial@f995e000 {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi
new file mode 100644
index 000000000..7084010ee
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-apq8084.dtsi
@@ -0,0 +1,284 @@
+/dts-v1/;
+
+#include "skeleton.dtsi"
+
+#include <dt-bindings/clock/qcom,gcc-apq8084.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Qualcomm APQ 8084";
+ compatible = "qcom,apq8084";
+ interrupt-parent = <&intc>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "qcom,krait";
+ reg = <0>;
+ enable-method = "qcom,kpss-acc-v2";
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc0>;
+ qcom,saw = <&saw0>;
+ cpu-idle-states = <&CPU_SPC>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "qcom,krait";
+ reg = <1>;
+ enable-method = "qcom,kpss-acc-v2";
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc1>;
+ qcom,saw = <&saw1>;
+ cpu-idle-states = <&CPU_SPC>;
+ };
+
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "qcom,krait";
+ reg = <2>;
+ enable-method = "qcom,kpss-acc-v2";
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc2>;
+ qcom,saw = <&saw2>;
+ cpu-idle-states = <&CPU_SPC>;
+ };
+
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "qcom,krait";
+ reg = <3>;
+ enable-method = "qcom,kpss-acc-v2";
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc3>;
+ qcom,saw = <&saw3>;
+ cpu-idle-states = <&CPU_SPC>;
+ };
+
+ L2: l2-cache {
+ compatible = "qcom,arch-cache";
+ cache-level = <2>;
+ qcom,saw = <&saw_l2>;
+ };
+
+ idle-states {
+ CPU_SPC: spc {
+ compatible = "qcom,idle-state-spc",
+ "arm,idle-state";
+ entry-latency-us = <150>;
+ exit-latency-us = <200>;
+ min-residency-us = <2000>;
+ };
+ };
+ };
+
+ cpu-pmu {
+ compatible = "qcom,krait-pmu";
+ interrupts = <1 7 0xf04>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <1 2 0xf08>,
+ <1 3 0xf08>,
+ <1 4 0xf08>,
+ <1 1 0xf08>;
+ clock-frequency = <19200000>;
+ };
+
+ soc: soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "simple-bus";
+
+ intc: interrupt-controller@f9000000 {
+ compatible = "qcom,msm-qgic2";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0xf9000000 0x1000>,
+ <0xf9002000 0x1000>;
+ };
+
+ timer@f9020000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "arm,armv7-timer-mem";
+ reg = <0xf9020000 0x1000>;
+ clock-frequency = <19200000>;
+
+ frame@f9021000 {
+ frame-number = <0>;
+ interrupts = <0 8 0x4>,
+ <0 7 0x4>;
+ reg = <0xf9021000 0x1000>,
+ <0xf9022000 0x1000>;
+ };
+
+ frame@f9023000 {
+ frame-number = <1>;
+ interrupts = <0 9 0x4>;
+ reg = <0xf9023000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9024000 {
+ frame-number = <2>;
+ interrupts = <0 10 0x4>;
+ reg = <0xf9024000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9025000 {
+ frame-number = <3>;
+ interrupts = <0 11 0x4>;
+ reg = <0xf9025000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9026000 {
+ frame-number = <4>;
+ interrupts = <0 12 0x4>;
+ reg = <0xf9026000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9027000 {
+ frame-number = <5>;
+ interrupts = <0 13 0x4>;
+ reg = <0xf9027000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9028000 {
+ frame-number = <6>;
+ interrupts = <0 14 0x4>;
+ reg = <0xf9028000 0x1000>;
+ status = "disabled";
+ };
+ };
+
+ saw0: power-controller@f9089000 {
+ compatible = "qcom,apq8084-saw2-v2.1-cpu", "qcom,saw2";
+ reg = <0xf9089000 0x1000>, <0xf9009000 0x1000>;
+ };
+
+ saw1: power-controller@f9099000 {
+ compatible = "qcom,apq8084-saw2-v2.1-cpu", "qcom,saw2";
+ reg = <0xf9099000 0x1000>, <0xf9009000 0x1000>;
+ };
+
+ saw2: power-controller@f90a9000 {
+ compatible = "qcom,apq8084-saw2-v2.1-cpu", "qcom,saw2";
+ reg = <0xf90a9000 0x1000>, <0xf9009000 0x1000>;
+ };
+
+ saw3: power-controller@f90b9000 {
+ compatible = "qcom,apq8084-saw2-v2.1-cpu", "qcom,saw2";
+ reg = <0xf90b9000 0x1000>, <0xf9009000 0x1000>;
+ };
+
+ saw_l2: power-controller@f9012000 {
+ compatible = "qcom,saw2";
+ reg = <0xf9012000 0x1000>;
+ regulator;
+ };
+
+ acc0: clock-controller@f9088000 {
+ compatible = "qcom,kpss-acc-v2";
+ reg = <0xf9088000 0x1000>,
+ <0xf9008000 0x1000>;
+ };
+
+ acc1: clock-controller@f9098000 {
+ compatible = "qcom,kpss-acc-v2";
+ reg = <0xf9098000 0x1000>,
+ <0xf9008000 0x1000>;
+ };
+
+ acc2: clock-controller@f90a8000 {
+ compatible = "qcom,kpss-acc-v2";
+ reg = <0xf90a8000 0x1000>,
+ <0xf9008000 0x1000>;
+ };
+
+ acc3: clock-controller@f90b8000 {
+ compatible = "qcom,kpss-acc-v2";
+ reg = <0xf90b8000 0x1000>,
+ <0xf9008000 0x1000>;
+ };
+
+ restart@fc4ab000 {
+ compatible = "qcom,pshold";
+ reg = <0xfc4ab000 0x4>;
+ };
+
+ gcc: clock-controller@fc400000 {
+ compatible = "qcom,gcc-apq8084";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ reg = <0xfc400000 0x4000>;
+ };
+
+ tlmm: pinctrl@fd510000 {
+ compatible = "qcom,apq8084-pinctrl";
+ reg = <0xfd510000 0x4000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <0 208 0>;
+ };
+
+ serial@f995e000 {
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0xf995e000 0x1000>;
+ interrupts = <0 114 0x0>;
+ clocks = <&gcc GCC_BLSP2_UART2_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+
+ sdhci@f9824900 {
+ compatible = "qcom,sdhci-msm-v4";
+ reg = <0xf9824900 0x11c>, <0xf9824000 0x800>;
+ reg-names = "hc_mem", "core_mem";
+ interrupts = <0 123 0>, <0 138 0>;
+ interrupt-names = "hc_irq", "pwr_irq";
+ clocks = <&gcc GCC_SDCC1_APPS_CLK>, <&gcc GCC_SDCC1_AHB_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+
+ sdhci@f98a4900 {
+ compatible = "qcom,sdhci-msm-v4";
+ reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>;
+ reg-names = "hc_mem", "core_mem";
+ interrupts = <0 125 0>, <0 221 0>;
+ interrupt-names = "hc_irq", "pwr_irq";
+ clocks = <&gcc GCC_SDCC2_APPS_CLK>, <&gcc GCC_SDCC2_AHB_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+
+ spmi_bus: spmi@fc4cf000 {
+ compatible = "qcom,spmi-pmic-arb";
+ reg-names = "core", "intr", "cnfg";
+ reg = <0xfc4cf000 0x1000>,
+ <0xfc4cb000 0x1000>,
+ <0xfc4ca000 0x1000>;
+ interrupt-names = "periph_irq";
+ interrupts = <0 190 0>;
+ qcom,ee = <0>;
+ qcom,channel = <0>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+ interrupt-controller;
+ #interrupt-cells = <4>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
new file mode 100644
index 000000000..55b2910ef
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
@@ -0,0 +1,93 @@
+#include "qcom-ipq8064-v1.0.dtsi"
+
+/ {
+ model = "Qualcomm IPQ8064/AP148";
+ compatible = "qcom,ipq8064-ap148", "qcom,ipq8064";
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ rsvd@41200000 {
+ reg = <0x41200000 0x300000>;
+ no-map;
+ };
+ };
+
+ soc {
+ pinmux@800000 {
+ i2c4_pins: i2c4_pinmux {
+ pins = "gpio12", "gpio13";
+ function = "gsbi4";
+ bias-disable;
+ };
+
+ spi_pins: spi_pins {
+ mux {
+ pins = "gpio18", "gpio19", "gpio21";
+ function = "gsbi5";
+ drive-strength = <10>;
+ bias-none;
+ };
+ };
+ };
+
+ gsbi@16300000 {
+ qcom,mode = <GSBI_PROT_I2C_UART>;
+ status = "ok";
+ serial@16340000 {
+ status = "ok";
+ };
+
+ i2c4: i2c@16380000 {
+ status = "ok";
+
+ clock-frequency = <200000>;
+
+ pinctrl-0 = <&i2c4_pins>;
+ pinctrl-names = "default";
+ };
+ };
+
+ gsbi5: gsbi@1a200000 {
+ qcom,mode = <GSBI_PROT_SPI>;
+ status = "ok";
+
+ spi4: spi@1a280000 {
+ status = "ok";
+ spi-max-frequency = <50000000>;
+
+ pinctrl-0 = <&spi_pins>;
+ pinctrl-names = "default";
+
+ cs-gpios = <&qcom_pinmux 20 0>;
+
+ flash: m25p80@0 {
+ compatible = "s25fl256s1";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <50000000>;
+ reg = <0>;
+
+ partition@0 {
+ label = "rootfs";
+ reg = <0x0 0x1000000>;
+ };
+
+ partition@1 {
+ label = "scratch";
+ reg = <0x1000000 0x1000000>;
+ };
+ };
+ };
+ };
+
+ sata-phy@1b400000 {
+ status = "ok";
+ };
+
+ sata@29000000 {
+ status = "ok";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi b/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi
new file mode 100644
index 000000000..7093b075e
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi
@@ -0,0 +1 @@
+#include "qcom-ipq8064.dtsi"
diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
new file mode 100644
index 000000000..9f727d8ea
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -0,0 +1,333 @@
+/dts-v1/;
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/qcom,gcc-ipq806x.h>
+#include <dt-bindings/clock/qcom,lcc-ipq806x.h>
+#include <dt-bindings/soc/qcom,gsbi.h>
+
+/ {
+ model = "Qualcomm IPQ8064";
+ compatible = "qcom,ipq8064";
+ interrupt-parent = <&intc>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "qcom,krait";
+ enable-method = "qcom,kpss-acc-v1";
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc0>;
+ qcom,saw = <&saw0>;
+ };
+
+ cpu@1 {
+ compatible = "qcom,krait";
+ enable-method = "qcom,kpss-acc-v1";
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc1>;
+ qcom,saw = <&saw1>;
+ };
+
+ L2: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ };
+ };
+
+ cpu-pmu {
+ compatible = "qcom,krait-pmu";
+ interrupts = <1 10 0x304>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ nss@40000000 {
+ reg = <0x40000000 0x1000000>;
+ no-map;
+ };
+
+ smem@41000000 {
+ reg = <0x41000000 0x200000>;
+ no-map;
+ };
+ };
+
+ clocks {
+ sleep_clk: sleep_clk {
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ #clock-cells = <0>;
+ };
+ };
+
+ soc: soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "simple-bus";
+
+ lpass@28100000 {
+ compatible = "qcom,lpass-cpu";
+ status = "disabled";
+ clocks = <&lcc AHBIX_CLK>,
+ <&lcc MI2S_OSR_CLK>,
+ <&lcc MI2S_BIT_CLK>;
+ clock-names = "ahbix-clk",
+ "mi2s-osr-clk",
+ "mi2s-bit-clk";
+ interrupts = <0 85 1>;
+ interrupt-names = "lpass-irq-lpaif";
+ reg = <0x28100000 0x10000>;
+ reg-names = "lpass-lpaif";
+ };
+
+ qcom_pinmux: pinmux@800000 {
+ compatible = "qcom,ipq8064-pinctrl";
+ reg = <0x800000 0x4000>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <0 16 0x4>;
+ };
+
+ intc: interrupt-controller@2000000 {
+ compatible = "qcom,msm-qgic2";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x02000000 0x1000>,
+ <0x02002000 0x1000>;
+ };
+
+ timer@200a000 {
+ compatible = "qcom,kpss-timer", "qcom,msm-timer";
+ interrupts = <1 1 0x301>,
+ <1 2 0x301>,
+ <1 3 0x301>,
+ <1 4 0x301>,
+ <1 5 0x301>;
+ reg = <0x0200a000 0x100>;
+ clock-frequency = <25000000>,
+ <32768>;
+ clocks = <&sleep_clk>;
+ clock-names = "sleep";
+ cpu-offset = <0x80000>;
+ };
+
+ acc0: clock-controller@2088000 {
+ compatible = "qcom,kpss-acc-v1";
+ reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
+ };
+
+ acc1: clock-controller@2098000 {
+ compatible = "qcom,kpss-acc-v1";
+ reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
+ };
+
+ saw0: regulator@2089000 {
+ compatible = "qcom,saw2";
+ reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
+ regulator;
+ };
+
+ saw1: regulator@2099000 {
+ compatible = "qcom,saw2";
+ reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
+ regulator;
+ };
+
+ gsbi2: gsbi@12480000 {
+ compatible = "qcom,gsbi-v1.0.0";
+ cell-index = <2>;
+ reg = <0x12480000 0x100>;
+ clocks = <&gcc GSBI2_H_CLK>;
+ clock-names = "iface";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ status = "disabled";
+
+ syscon-tcsr = <&tcsr>;
+
+ serial@12490000 {
+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+ reg = <0x12490000 0x1000>,
+ <0x12480000 0x1000>;
+ interrupts = <0 195 0x0>;
+ clocks = <&gcc GSBI2_UART_CLK>, <&gcc GSBI2_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+
+ i2c@124a0000 {
+ compatible = "qcom,i2c-qup-v1.1.1";
+ reg = <0x124a0000 0x1000>;
+ interrupts = <0 196 0>;
+
+ clocks = <&gcc GSBI2_QUP_CLK>, <&gcc GSBI2_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ };
+
+ gsbi4: gsbi@16300000 {
+ compatible = "qcom,gsbi-v1.0.0";
+ cell-index = <4>;
+ reg = <0x16300000 0x100>;
+ clocks = <&gcc GSBI4_H_CLK>;
+ clock-names = "iface";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ status = "disabled";
+
+ syscon-tcsr = <&tcsr>;
+
+ serial@16340000 {
+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+ reg = <0x16340000 0x1000>,
+ <0x16300000 0x1000>;
+ interrupts = <0 152 0x0>;
+ clocks = <&gcc GSBI4_UART_CLK>, <&gcc GSBI4_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+
+ i2c@16380000 {
+ compatible = "qcom,i2c-qup-v1.1.1";
+ reg = <0x16380000 0x1000>;
+ interrupts = <0 153 0>;
+
+ clocks = <&gcc GSBI4_QUP_CLK>, <&gcc GSBI4_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ gsbi5: gsbi@1a200000 {
+ compatible = "qcom,gsbi-v1.0.0";
+ cell-index = <5>;
+ reg = <0x1a200000 0x100>;
+ clocks = <&gcc GSBI5_H_CLK>;
+ clock-names = "iface";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ status = "disabled";
+
+ syscon-tcsr = <&tcsr>;
+
+ serial@1a240000 {
+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+ reg = <0x1a240000 0x1000>,
+ <0x1a200000 0x1000>;
+ interrupts = <0 154 0x0>;
+ clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+
+ i2c@1a280000 {
+ compatible = "qcom,i2c-qup-v1.1.1";
+ reg = <0x1a280000 0x1000>;
+ interrupts = <0 155 0>;
+
+ clocks = <&gcc GSBI5_QUP_CLK>, <&gcc GSBI5_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ spi@1a280000 {
+ compatible = "qcom,spi-qup-v1.1.1";
+ reg = <0x1a280000 0x1000>;
+ interrupts = <0 155 0>;
+
+ clocks = <&gcc GSBI5_QUP_CLK>, <&gcc GSBI5_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ sata_phy: sata-phy@1b400000 {
+ compatible = "qcom,ipq806x-sata-phy";
+ reg = <0x1b400000 0x200>;
+
+ clocks = <&gcc SATA_PHY_CFG_CLK>;
+ clock-names = "cfg";
+
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ sata@29000000 {
+ compatible = "qcom,ipq806x-ahci", "generic-ahci";
+ reg = <0x29000000 0x180>;
+
+ interrupts = <0 209 0x0>;
+
+ clocks = <&gcc SFAB_SATA_S_H_CLK>,
+ <&gcc SATA_H_CLK>,
+ <&gcc SATA_A_CLK>,
+ <&gcc SATA_RXOOB_CLK>,
+ <&gcc SATA_PMALIVE_CLK>;
+ clock-names = "slave_face", "iface", "core",
+ "rxoob", "pmalive";
+
+ assigned-clocks = <&gcc SATA_RXOOB_CLK>, <&gcc SATA_PMALIVE_CLK>;
+ assigned-clock-rates = <100000000>, <100000000>;
+
+ phys = <&sata_phy>;
+ phy-names = "sata-phy";
+ status = "disabled";
+ };
+
+ qcom,ssbi@500000 {
+ compatible = "qcom,ssbi";
+ reg = <0x00500000 0x1000>;
+ qcom,controller-type = "pmic-arbiter";
+ };
+
+ gcc: clock-controller@900000 {
+ compatible = "qcom,gcc-ipq8064";
+ reg = <0x00900000 0x4000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ tcsr: syscon@1a400000 {
+ compatible = "qcom,tcsr-ipq8064", "syscon";
+ reg = <0x1a400000 0x100>;
+ };
+
+ lcc: clock-controller@28000000 {
+ compatible = "qcom,lcc-ipq8064";
+ reg = <0x28000000 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-msm8660-surf.dts b/arch/arm/boot/dts/qcom-msm8660-surf.dts
new file mode 100644
index 000000000..e0883c376
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-msm8660-surf.dts
@@ -0,0 +1,58 @@
+#include <dt-bindings/input/input.h>
+
+#include "qcom-msm8660.dtsi"
+
+/ {
+ model = "Qualcomm MSM8660 SURF";
+ compatible = "qcom,msm8660-surf", "qcom,msm8660";
+
+ soc {
+ gsbi@19c00000 {
+ status = "ok";
+ qcom,mode = <GSBI_PROT_I2C_UART>;
+ serial@19c40000 {
+ status = "ok";
+ };
+ };
+
+ amba {
+ /* eMMC */
+ sdcc1: sdcc@12400000 {
+ status = "okay";
+ };
+
+ /* External micro SD card */
+ sdcc3: sdcc@12180000 {
+ status = "okay";
+ };
+ };
+ };
+};
+
+&pmicintc {
+ keypad@148 {
+ linux,keymap = <
+ MATRIX_KEY(0, 0, KEY_FN_F1)
+ MATRIX_KEY(0, 1, KEY_UP)
+ MATRIX_KEY(0, 2, KEY_LEFT)
+ MATRIX_KEY(0, 3, KEY_VOLUMEUP)
+ MATRIX_KEY(1, 0, KEY_FN_F2)
+ MATRIX_KEY(1, 1, KEY_RIGHT)
+ MATRIX_KEY(1, 2, KEY_DOWN)
+ MATRIX_KEY(1, 3, KEY_VOLUMEDOWN)
+ MATRIX_KEY(2, 3, KEY_ENTER)
+ MATRIX_KEY(4, 0, KEY_CAMERA_FOCUS)
+ MATRIX_KEY(4, 1, KEY_UP)
+ MATRIX_KEY(4, 2, KEY_LEFT)
+ MATRIX_KEY(4, 3, KEY_HOME)
+ MATRIX_KEY(4, 4, KEY_FN_F3)
+ MATRIX_KEY(5, 0, KEY_CAMERA)
+ MATRIX_KEY(5, 1, KEY_RIGHT)
+ MATRIX_KEY(5, 2, KEY_DOWN)
+ MATRIX_KEY(5, 3, KEY_BACK)
+ MATRIX_KEY(5, 4, KEY_MENU)
+ >;
+ keypad,num-rows = <6>;
+ keypad,num-columns = <5>;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom-msm8660.dtsi
new file mode 100644
index 000000000..20bbd19b9
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-msm8660.dtsi
@@ -0,0 +1,209 @@
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/qcom,gcc-msm8660.h>
+#include <dt-bindings/soc/qcom,gsbi.h>
+
+/ {
+ model = "Qualcomm MSM8660";
+ compatible = "qcom,msm8660";
+ interrupt-parent = <&intc>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "qcom,scorpion";
+ enable-method = "qcom,gcc-msm8660";
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ };
+
+ cpu@1 {
+ compatible = "qcom,scorpion";
+ enable-method = "qcom,gcc-msm8660";
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ };
+
+ L2: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ };
+ };
+
+ soc: soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "simple-bus";
+
+ intc: interrupt-controller@2080000 {
+ compatible = "qcom,msm-8660-qgic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = < 0x02080000 0x1000 >,
+ < 0x02081000 0x1000 >;
+ };
+
+ timer@2000000 {
+ compatible = "qcom,scss-timer", "qcom,msm-timer";
+ interrupts = <1 0 0x301>,
+ <1 1 0x301>,
+ <1 2 0x301>;
+ reg = <0x02000000 0x100>;
+ clock-frequency = <27000000>,
+ <32768>;
+ cpu-offset = <0x40000>;
+ };
+
+ msmgpio: gpio@800000 {
+ compatible = "qcom,msm-gpio";
+ reg = <0x00800000 0x4000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpio = <173>;
+ interrupts = <0 16 0x4>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gcc: clock-controller@900000 {
+ compatible = "qcom,gcc-msm8660";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ reg = <0x900000 0x4000>;
+ };
+
+ gsbi12: gsbi@19c00000 {
+ compatible = "qcom,gsbi-v1.0.0";
+ cell-index = <12>;
+ reg = <0x19c00000 0x100>;
+ clocks = <&gcc GSBI12_H_CLK>;
+ clock-names = "iface";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ syscon-tcsr = <&tcsr>;
+
+ serial@19c40000 {
+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+ reg = <0x19c40000 0x1000>,
+ <0x19c00000 0x1000>;
+ interrupts = <0 195 0x0>;
+ clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+ };
+
+ qcom,ssbi@500000 {
+ compatible = "qcom,ssbi";
+ reg = <0x500000 0x1000>;
+ qcom,controller-type = "pmic-arbiter";
+
+ pmicintc: pmic@0 {
+ compatible = "qcom,pm8058";
+ interrupt-parent = <&msmgpio>;
+ interrupts = <88 8>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pwrkey@1c {
+ compatible = "qcom,pm8058-pwrkey";
+ reg = <0x1c>;
+ interrupt-parent = <&pmicintc>;
+ interrupts = <50 1>, <51 1>;
+ debounce = <15625>;
+ pull-up;
+ };
+
+ keypad@148 {
+ compatible = "qcom,pm8058-keypad";
+ reg = <0x148>;
+ interrupt-parent = <&pmicintc>;
+ interrupts = <74 1>, <75 1>;
+ debounce = <15>;
+ scan-delay = <32>;
+ row-hold = <91500>;
+ };
+
+ rtc@11d {
+ compatible = "qcom,pm8058-rtc";
+ interrupt-parent = <&pmicintc>;
+ interrupts = <39 1>;
+ reg = <0x11d>;
+ allow-set-time;
+ };
+
+ vibrator@4a {
+ compatible = "qcom,pm8058-vib";
+ reg = <0x4a>;
+ };
+ };
+ };
+
+ /* Temporary fixed regulator */
+ vsdcc_fixed: vsdcc-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "SDCC Power";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ regulator-always-on;
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ sdcc1: sdcc@12400000 {
+ status = "disabled";
+ compatible = "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x00051180>;
+ reg = <0x12400000 0x8000>;
+ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "cmd_irq";
+ clocks = <&gcc SDC1_CLK>, <&gcc SDC1_H_CLK>;
+ clock-names = "mclk", "apb_pclk";
+ bus-width = <8>;
+ max-frequency = <48000000>;
+ non-removable;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ vmmc-supply = <&vsdcc_fixed>;
+ };
+
+ sdcc3: sdcc@12180000 {
+ compatible = "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x00051180>;
+ status = "disabled";
+ reg = <0x12180000 0x8000>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "cmd_irq";
+ clocks = <&gcc SDC3_CLK>, <&gcc SDC3_H_CLK>;
+ clock-names = "mclk", "apb_pclk";
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <48000000>;
+ no-1-8-v;
+ vmmc-supply = <&vsdcc_fixed>;
+ };
+ };
+
+ tcsr: syscon@1a400000 {
+ compatible = "qcom,tcsr-msm8660", "syscon";
+ reg = <0x1a400000 0x100>;
+ };
+ };
+
+};
diff --git a/arch/arm/boot/dts/qcom-msm8960-cdp.dts b/arch/arm/boot/dts/qcom-msm8960-cdp.dts
new file mode 100644
index 000000000..7f70fae90
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-msm8960-cdp.dts
@@ -0,0 +1,43 @@
+#include <dt-bindings/input/input.h>
+
+#include "qcom-msm8960.dtsi"
+
+/ {
+ model = "Qualcomm MSM8960 CDP";
+ compatible = "qcom,msm8960-cdp", "qcom,msm8960";
+
+ soc {
+ gsbi@16400000 {
+ status = "ok";
+ qcom,mode = <GSBI_PROT_I2C_UART>;
+ serial@16440000 {
+ status = "ok";
+ };
+ };
+
+ amba {
+ /* eMMC */
+ sdcc1: sdcc@12400000 {
+ status = "okay";
+ };
+
+ /* External micro SD card */
+ sdcc3: sdcc@12180000 {
+ status = "okay";
+ };
+ };
+ };
+};
+
+&pmicintc {
+ keypad@148 {
+ linux,keymap = <
+ MATRIX_KEY(0, 0, KEY_VOLUMEUP)
+ MATRIX_KEY(0, 1, KEY_VOLUMEDOWN)
+ MATRIX_KEY(0, 2, KEY_CAMERA_FOCUS)
+ MATRIX_KEY(0, 3, KEY_CAMERA)
+ >;
+ keypad,num-rows = <1>;
+ keypad,num-columns = <5>;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom-msm8960.dtsi
new file mode 100644
index 000000000..a02b984cc
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-msm8960.dtsi
@@ -0,0 +1,257 @@
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/qcom,gcc-msm8960.h>
+#include <dt-bindings/soc/qcom,gsbi.h>
+
+/ {
+ model = "Qualcomm MSM8960";
+ compatible = "qcom,msm8960";
+ interrupt-parent = <&intc>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <1 14 0x304>;
+
+ cpu@0 {
+ compatible = "qcom,krait";
+ enable-method = "qcom,kpss-acc-v1";
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc0>;
+ qcom,saw = <&saw0>;
+ };
+
+ cpu@1 {
+ compatible = "qcom,krait";
+ enable-method = "qcom,kpss-acc-v1";
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc1>;
+ qcom,saw = <&saw1>;
+ };
+
+ L2: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ };
+ };
+
+ cpu-pmu {
+ compatible = "qcom,krait-pmu";
+ interrupts = <1 10 0x304>;
+ qcom,no-pc-write;
+ };
+
+ soc: soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "simple-bus";
+
+ intc: interrupt-controller@2000000 {
+ compatible = "qcom,msm-qgic2";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x02000000 0x1000>,
+ <0x02002000 0x1000>;
+ };
+
+ timer@200a000 {
+ compatible = "qcom,kpss-timer", "qcom,msm-timer";
+ interrupts = <1 1 0x301>,
+ <1 2 0x301>,
+ <1 3 0x301>;
+ reg = <0x0200a000 0x100>;
+ clock-frequency = <27000000>,
+ <32768>;
+ cpu-offset = <0x80000>;
+ };
+
+ msmgpio: gpio@800000 {
+ compatible = "qcom,msm-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpio = <150>;
+ interrupts = <0 16 0x4>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x800000 0x4000>;
+ };
+
+ gcc: clock-controller@900000 {
+ compatible = "qcom,gcc-msm8960";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ reg = <0x900000 0x4000>;
+ };
+
+ lcc: clock-controller@28000000 {
+ compatible = "qcom,lcc-msm8960";
+ reg = <0x28000000 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ clock-controller@4000000 {
+ compatible = "qcom,mmcc-msm8960";
+ reg = <0x4000000 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ acc0: clock-controller@2088000 {
+ compatible = "qcom,kpss-acc-v1";
+ reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
+ };
+
+ acc1: clock-controller@2098000 {
+ compatible = "qcom,kpss-acc-v1";
+ reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
+ };
+
+ saw0: regulator@2089000 {
+ compatible = "qcom,saw2";
+ reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
+ regulator;
+ };
+
+ saw1: regulator@2099000 {
+ compatible = "qcom,saw2";
+ reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
+ regulator;
+ };
+
+ gsbi5: gsbi@16400000 {
+ compatible = "qcom,gsbi-v1.0.0";
+ cell-index = <5>;
+ reg = <0x16400000 0x100>;
+ clocks = <&gcc GSBI5_H_CLK>;
+ clock-names = "iface";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ syscon-tcsr = <&tcsr>;
+
+ serial@16440000 {
+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+ reg = <0x16440000 0x1000>,
+ <0x16400000 0x1000>;
+ interrupts = <0 154 0x0>;
+ clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+ };
+
+ qcom,ssbi@500000 {
+ compatible = "qcom,ssbi";
+ reg = <0x500000 0x1000>;
+ qcom,controller-type = "pmic-arbiter";
+
+ pmicintc: pmic@0 {
+ compatible = "qcom,pm8921";
+ interrupt-parent = <&msmgpio>;
+ interrupts = <104 8>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pwrkey@1c {
+ compatible = "qcom,pm8921-pwrkey";
+ reg = <0x1c>;
+ interrupt-parent = <&pmicintc>;
+ interrupts = <50 1>, <51 1>;
+ debounce = <15625>;
+ pull-up;
+ };
+
+ keypad@148 {
+ compatible = "qcom,pm8921-keypad";
+ reg = <0x148>;
+ interrupt-parent = <&pmicintc>;
+ interrupts = <74 1>, <75 1>;
+ debounce = <15>;
+ scan-delay = <32>;
+ row-hold = <91500>;
+ };
+
+ rtc@11d {
+ compatible = "qcom,pm8921-rtc";
+ interrupt-parent = <&pmicintc>;
+ interrupts = <39 1>;
+ reg = <0x11d>;
+ allow-set-time;
+ };
+ };
+ };
+
+ rng@1a500000 {
+ compatible = "qcom,prng";
+ reg = <0x1a500000 0x200>;
+ clocks = <&gcc PRNG_CLK>;
+ clock-names = "core";
+ };
+
+ /* Temporary fixed regulator */
+ vsdcc_fixed: vsdcc-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "SDCC Power";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ regulator-always-on;
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ sdcc1: sdcc@12400000 {
+ status = "disabled";
+ compatible = "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x00051180>;
+ reg = <0x12400000 0x8000>;
+ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "cmd_irq";
+ clocks = <&gcc SDC1_CLK>, <&gcc SDC1_H_CLK>;
+ clock-names = "mclk", "apb_pclk";
+ bus-width = <8>;
+ max-frequency = <96000000>;
+ non-removable;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ vmmc-supply = <&vsdcc_fixed>;
+ };
+
+ sdcc3: sdcc@12180000 {
+ compatible = "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x00051180>;
+ status = "disabled";
+ reg = <0x12180000 0x8000>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "cmd_irq";
+ clocks = <&gcc SDC3_CLK>, <&gcc SDC3_H_CLK>;
+ clock-names = "mclk", "apb_pclk";
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <192000000>;
+ no-1-8-v;
+ vmmc-supply = <&vsdcc_fixed>;
+ };
+ };
+
+ tcsr: syscon@1a400000 {
+ compatible = "qcom,tcsr-msm8960", "syscon";
+ reg = <0x1a400000 0x100>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
new file mode 100644
index 000000000..bd35b0674
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
@@ -0,0 +1,19 @@
+#include "qcom-msm8974.dtsi"
+#include "qcom-pm8841.dtsi"
+#include "qcom-pm8941.dtsi"
+
+/ {
+ model = "Sony Xperia Z1";
+ compatible = "sony,xperia-honami", "qcom,msm8974";
+
+ memory@0 {
+ reg = <0 0x40000000>, <0x40000000 0x40000000>;
+ device_type = "memory";
+ };
+};
+
+&soc {
+ serial@f991e000 {
+ status = "ok";
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
new file mode 100644
index 000000000..37b47b553
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -0,0 +1,305 @@
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clock/qcom,gcc-msm8974.h>
+#include "skeleton.dtsi"
+
+/ {
+ model = "Qualcomm MSM8974";
+ compatible = "qcom,msm8974";
+ interrupt-parent = <&intc>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <1 9 0xf04>;
+
+ cpu@0 {
+ compatible = "qcom,krait";
+ enable-method = "qcom,kpss-acc-v2";
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc0>;
+ qcom,saw = <&saw0>;
+ cpu-idle-states = <&CPU_SPC>;
+ };
+
+ cpu@1 {
+ compatible = "qcom,krait";
+ enable-method = "qcom,kpss-acc-v2";
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc1>;
+ qcom,saw = <&saw1>;
+ cpu-idle-states = <&CPU_SPC>;
+ };
+
+ cpu@2 {
+ compatible = "qcom,krait";
+ enable-method = "qcom,kpss-acc-v2";
+ device_type = "cpu";
+ reg = <2>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc2>;
+ qcom,saw = <&saw2>;
+ cpu-idle-states = <&CPU_SPC>;
+ };
+
+ cpu@3 {
+ compatible = "qcom,krait";
+ enable-method = "qcom,kpss-acc-v2";
+ device_type = "cpu";
+ reg = <3>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc3>;
+ qcom,saw = <&saw3>;
+ cpu-idle-states = <&CPU_SPC>;
+ };
+
+ L2: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ qcom,saw = <&saw_l2>;
+ };
+
+ idle-states {
+ CPU_SPC: spc {
+ compatible = "qcom,idle-state-spc",
+ "arm,idle-state";
+ entry-latency-us = <150>;
+ exit-latency-us = <200>;
+ min-residency-us = <2000>;
+ };
+ };
+ };
+
+ cpu-pmu {
+ compatible = "qcom,krait-pmu";
+ interrupts = <1 7 0xf04>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <1 2 0xf08>,
+ <1 3 0xf08>,
+ <1 4 0xf08>,
+ <1 1 0xf08>;
+ clock-frequency = <19200000>;
+ };
+
+ soc: soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "simple-bus";
+
+ intc: interrupt-controller@f9000000 {
+ compatible = "qcom,msm-qgic2";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0xf9000000 0x1000>,
+ <0xf9002000 0x1000>;
+ };
+
+ timer@f9020000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "arm,armv7-timer-mem";
+ reg = <0xf9020000 0x1000>;
+ clock-frequency = <19200000>;
+
+ frame@f9021000 {
+ frame-number = <0>;
+ interrupts = <0 8 0x4>,
+ <0 7 0x4>;
+ reg = <0xf9021000 0x1000>,
+ <0xf9022000 0x1000>;
+ };
+
+ frame@f9023000 {
+ frame-number = <1>;
+ interrupts = <0 9 0x4>;
+ reg = <0xf9023000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9024000 {
+ frame-number = <2>;
+ interrupts = <0 10 0x4>;
+ reg = <0xf9024000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9025000 {
+ frame-number = <3>;
+ interrupts = <0 11 0x4>;
+ reg = <0xf9025000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9026000 {
+ frame-number = <4>;
+ interrupts = <0 12 0x4>;
+ reg = <0xf9026000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9027000 {
+ frame-number = <5>;
+ interrupts = <0 13 0x4>;
+ reg = <0xf9027000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9028000 {
+ frame-number = <6>;
+ interrupts = <0 14 0x4>;
+ reg = <0xf9028000 0x1000>;
+ status = "disabled";
+ };
+ };
+
+ saw0: power-controller@f9089000 {
+ compatible = "qcom,msm8974-saw2-v2.1-cpu", "qcom,saw2";
+ reg = <0xf9089000 0x1000>, <0xf9009000 0x1000>;
+ };
+
+ saw1: power-controller@f9099000 {
+ compatible = "qcom,msm8974-saw2-v2.1-cpu", "qcom,saw2";
+ reg = <0xf9099000 0x1000>, <0xf9009000 0x1000>;
+ };
+
+ saw2: power-controller@f90a9000 {
+ compatible = "qcom,msm8974-saw2-v2.1-cpu", "qcom,saw2";
+ reg = <0xf90a9000 0x1000>, <0xf9009000 0x1000>;
+ };
+
+ saw3: power-controller@f90b9000 {
+ compatible = "qcom,msm8974-saw2-v2.1-cpu", "qcom,saw2";
+ reg = <0xf90b9000 0x1000>, <0xf9009000 0x1000>;
+ };
+
+ saw_l2: power-controller@f9012000 {
+ compatible = "qcom,saw2";
+ reg = <0xf9012000 0x1000>;
+ regulator;
+ };
+
+ acc0: clock-controller@f9088000 {
+ compatible = "qcom,kpss-acc-v2";
+ reg = <0xf9088000 0x1000>, <0xf9008000 0x1000>;
+ };
+
+ acc1: clock-controller@f9098000 {
+ compatible = "qcom,kpss-acc-v2";
+ reg = <0xf9098000 0x1000>, <0xf9008000 0x1000>;
+ };
+
+ acc2: clock-controller@f90a8000 {
+ compatible = "qcom,kpss-acc-v2";
+ reg = <0xf90a8000 0x1000>, <0xf9008000 0x1000>;
+ };
+
+ acc3: clock-controller@f90b8000 {
+ compatible = "qcom,kpss-acc-v2";
+ reg = <0xf90b8000 0x1000>, <0xf9008000 0x1000>;
+ };
+
+ restart@fc4ab000 {
+ compatible = "qcom,pshold";
+ reg = <0xfc4ab000 0x4>;
+ };
+
+ gcc: clock-controller@fc400000 {
+ compatible = "qcom,gcc-msm8974";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ reg = <0xfc400000 0x4000>;
+ };
+
+ mmcc: clock-controller@fd8c0000 {
+ compatible = "qcom,mmcc-msm8974";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ reg = <0xfd8c0000 0x6000>;
+ };
+
+ serial@f991e000 {
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0xf991e000 0x1000>;
+ interrupts = <0 108 0x0>;
+ clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+
+ sdhci@f9824900 {
+ compatible = "qcom,sdhci-msm-v4";
+ reg = <0xf9824900 0x11c>, <0xf9824000 0x800>;
+ reg-names = "hc_mem", "core_mem";
+ interrupts = <0 123 0>, <0 138 0>;
+ interrupt-names = "hc_irq", "pwr_irq";
+ clocks = <&gcc GCC_SDCC1_APPS_CLK>, <&gcc GCC_SDCC1_AHB_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+
+ sdhci@f98a4900 {
+ compatible = "qcom,sdhci-msm-v4";
+ reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>;
+ reg-names = "hc_mem", "core_mem";
+ interrupts = <0 125 0>, <0 221 0>;
+ interrupt-names = "hc_irq", "pwr_irq";
+ clocks = <&gcc GCC_SDCC2_APPS_CLK>, <&gcc GCC_SDCC2_AHB_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+
+ rng@f9bff000 {
+ compatible = "qcom,prng";
+ reg = <0xf9bff000 0x200>;
+ clocks = <&gcc GCC_PRNG_AHB_CLK>;
+ clock-names = "core";
+ };
+
+ msmgpio: pinctrl@fd510000 {
+ compatible = "qcom,msm8974-pinctrl";
+ reg = <0xfd510000 0x4000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <0 208 0>;
+ };
+
+ blsp_i2c11: i2c@f9967000 {
+ status = "disable";
+ compatible = "qcom,i2c-qup-v2.1.1";
+ reg = <0xf9967000 0x1000>;
+ interrupts = <0 105 IRQ_TYPE_NONE>;
+ clocks = <&gcc GCC_BLSP2_QUP5_I2C_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
+ clock-names = "core", "iface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ spmi_bus: spmi@fc4cf000 {
+ compatible = "qcom,spmi-pmic-arb";
+ reg-names = "core", "intr", "cnfg";
+ reg = <0xfc4cf000 0x1000>,
+ <0xfc4cb000 0x1000>,
+ <0xfc4ca000 0x1000>;
+ interrupt-names = "periph_irq";
+ interrupts = <0 190 0>;
+ qcom,ee = <0>;
+ qcom,channel = <0>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+ interrupt-controller;
+ #interrupt-cells = <4>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-pm8841.dtsi b/arch/arm/boot/dts/qcom-pm8841.dtsi
new file mode 100644
index 000000000..73813cc11
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-pm8841.dtsi
@@ -0,0 +1,18 @@
+#include <dt-bindings/spmi/spmi.h>
+
+&spmi_bus {
+
+ usid4: pm8841@4 {
+ compatible = "qcom,spmi-pmic";
+ reg = <0x4 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ usid5: pm8841@5 {
+ compatible = "qcom,spmi-pmic";
+ reg = <0x5 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-pm8941.dtsi b/arch/arm/boot/dts/qcom-pm8941.dtsi
new file mode 100644
index 000000000..24c5088ac
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-pm8941.dtsi
@@ -0,0 +1,18 @@
+#include <dt-bindings/spmi/spmi.h>
+
+&spmi_bus {
+
+ usid0: pm8941@0 {
+ compatible ="qcom,spmi-pmic";
+ reg = <0x0 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ usid1: pm8941@1 {
+ compatible ="qcom,spmi-pmic";
+ reg = <0x1 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-pma8084.dtsi b/arch/arm/boot/dts/qcom-pma8084.dtsi
new file mode 100644
index 000000000..a5a4fe695
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-pma8084.dtsi
@@ -0,0 +1,18 @@
+#include <dt-bindings/spmi/spmi.h>
+
+&spmi_bus {
+
+ usid0: pma8084@0 {
+ compatible = "qcom,spmi-pmic";
+ reg = <0x0 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ usid1: pma8084@1 {
+ compatible = "qcom,spmi-pmic";
+ reg = <0x1 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/r7s72100-genmai.dts b/arch/arm/boot/dts/r7s72100-genmai.dts
new file mode 100644
index 000000000..a9da7a89f
--- /dev/null
+++ b/arch/arm/boot/dts/r7s72100-genmai.dts
@@ -0,0 +1,74 @@
+/*
+ * Device Tree Source for the Genmai board
+ *
+ * Copyright (C) 2013-14 Renesas Solutions Corp.
+ * Copyright (C) 2014 Wolfram Sang, Sang Engineering <wsa@sang-engineering.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.
+ */
+
+/dts-v1/;
+#include "r7s72100.dtsi"
+
+/ {
+ model = "Genmai";
+ compatible = "renesas,genmai", "renesas,r7s72100";
+
+ aliases {
+ serial2 = &scif2;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
+ stdout-path = &scif2;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x08000000 0x08000000>;
+ };
+
+ lbsc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+};
+
+&extal_clk {
+ clock-frequency = <13330000>;
+};
+
+&usb_x1_clk {
+ clock-frequency = <48000000>;
+};
+
+&mtu2 {
+ status = "okay";
+};
+
+&i2c2 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ eeprom@50 {
+ compatible = "renesas,24c128";
+ reg = <0x50>;
+ pagesize = <64>;
+ };
+};
+
+&scif2 {
+ status = "okay";
+};
+
+&spi4 {
+ status = "okay";
+
+ codec: codec@0 {
+ compatible = "wlf,wm8978";
+ reg = <0>;
+ spi-max-frequency = <5000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi
new file mode 100644
index 000000000..277e73c11
--- /dev/null
+++ b/arch/arm/boot/dts/r7s72100.dtsi
@@ -0,0 +1,407 @@
+/*
+ * Device Tree Source for the r7s72100 SoC
+ *
+ * Copyright (C) 2013-14 Renesas Solutions Corp.
+ * Copyright (C) 2014 Wolfram Sang, Sang Engineering <wsa@sang-engineering.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 <dt-bindings/clock/r7s72100-clock.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "renesas,r7s72100";
+ interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ spi2 = &spi2;
+ spi3 = &spi3;
+ spi4 = &spi4;
+ };
+
+ clocks {
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /* External clocks */
+ extal_clk: extal_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ /* If clk present, value must be set by board */
+ clock-frequency = <0>;
+ clock-output-names = "extal";
+ };
+
+ usb_x1_clk: usb_x1_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ /* If clk present, value must be set by board */
+ clock-frequency = <0>;
+ clock-output-names = "usb_x1";
+ };
+
+ /* Fixed factor clocks */
+ b_clk: b_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R7S72100_CLK_PLL>;
+ clock-mult = <1>;
+ clock-div = <3>;
+ clock-output-names = "b";
+ };
+ p1_clk: p1_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R7S72100_CLK_PLL>;
+ clock-mult = <1>;
+ clock-div = <6>;
+ clock-output-names = "p1";
+ };
+ p0_clk: p0_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R7S72100_CLK_PLL>;
+ clock-mult = <1>;
+ clock-div = <12>;
+ clock-output-names = "p0";
+ };
+
+ /* Special CPG clocks */
+ cpg_clocks: cpg_clocks@fcfe0000 {
+ #clock-cells = <1>;
+ compatible = "renesas,r7s72100-cpg-clocks",
+ "renesas,rz-cpg-clocks";
+ reg = <0xfcfe0000 0x18>;
+ clocks = <&extal_clk>, <&usb_x1_clk>;
+ clock-output-names = "pll", "i", "g";
+ };
+
+ /* MSTP clocks */
+ mstp3_clks: mstp3_clks@fcfe0420 {
+ #clock-cells = <1>;
+ compatible = "renesas,r7s72100-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xfcfe0420 4>;
+ clocks = <&p0_clk>;
+ clock-indices = <R7S72100_CLK_MTU2>;
+ clock-output-names = "mtu2";
+ };
+
+ mstp4_clks: mstp4_clks@fcfe0424 {
+ #clock-cells = <1>;
+ compatible = "renesas,r7s72100-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xfcfe0424 4>;
+ clocks = <&p1_clk>, <&p1_clk>, <&p1_clk>, <&p1_clk>,
+ <&p1_clk>, <&p1_clk>, <&p1_clk>, <&p1_clk>;
+ clock-indices = <
+ R7S72100_CLK_SCIF0 R7S72100_CLK_SCIF1 R7S72100_CLK_SCIF2 R7S72100_CLK_SCIF3
+ R7S72100_CLK_SCIF4 R7S72100_CLK_SCIF5 R7S72100_CLK_SCIF6 R7S72100_CLK_SCIF7
+ >;
+ clock-output-names = "scif0", "scif1", "scif2", "scif3", "scif4", "scif5", "scif6", "scif7";
+ };
+
+ mstp9_clks: mstp9_clks@fcfe0438 {
+ #clock-cells = <1>;
+ compatible = "renesas,r7s72100-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xfcfe0438 4>;
+ clocks = <&p0_clk>, <&p0_clk>, <&p0_clk>, <&p0_clk>;
+ clock-indices = <
+ R7S72100_CLK_I2C0 R7S72100_CLK_I2C1 R7S72100_CLK_I2C2 R7S72100_CLK_I2C3
+ >;
+ clock-output-names = "i2c0", "i2c1", "i2c2", "i2c3";
+ };
+
+ mstp10_clks: mstp10_clks@fcfe043c {
+ #clock-cells = <1>;
+ compatible = "renesas,r7s72100-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xfcfe043c 4>;
+ clocks = <&p1_clk>, <&p1_clk>, <&p1_clk>, <&p1_clk>,
+ <&p1_clk>;
+ clock-indices = <
+ R7S72100_CLK_SPI0 R7S72100_CLK_SPI1 R7S72100_CLK_SPI2 R7S72100_CLK_SPI3
+ R7S72100_CLK_SPI4
+ >;
+ clock-output-names = "spi0", "spi1", "spi2", "spi3", "spi4";
+ };
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ clock-frequency = <400000000>;
+ };
+ };
+
+ scif0: serial@e8007000 {
+ compatible = "renesas,scif-r7s72100", "renesas,scif";
+ reg = <0xe8007000 64>;
+ interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>,
+ <0 191 IRQ_TYPE_LEVEL_HIGH>,
+ <0 192 IRQ_TYPE_LEVEL_HIGH>,
+ <0 189 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp4_clks R7S72100_CLK_SCIF0>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif1: serial@e8007800 {
+ compatible = "renesas,scif-r7s72100", "renesas,scif";
+ reg = <0xe8007800 64>;
+ interrupts = <0 194 IRQ_TYPE_LEVEL_HIGH>,
+ <0 195 IRQ_TYPE_LEVEL_HIGH>,
+ <0 196 IRQ_TYPE_LEVEL_HIGH>,
+ <0 193 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp4_clks R7S72100_CLK_SCIF1>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif2: serial@e8008000 {
+ compatible = "renesas,scif-r7s72100", "renesas,scif";
+ reg = <0xe8008000 64>;
+ interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>,
+ <0 199 IRQ_TYPE_LEVEL_HIGH>,
+ <0 200 IRQ_TYPE_LEVEL_HIGH>,
+ <0 197 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp4_clks R7S72100_CLK_SCIF2>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif3: serial@e8008800 {
+ compatible = "renesas,scif-r7s72100", "renesas,scif";
+ reg = <0xe8008800 64>;
+ interrupts = <0 202 IRQ_TYPE_LEVEL_HIGH>,
+ <0 203 IRQ_TYPE_LEVEL_HIGH>,
+ <0 204 IRQ_TYPE_LEVEL_HIGH>,
+ <0 201 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp4_clks R7S72100_CLK_SCIF3>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif4: serial@e8009000 {
+ compatible = "renesas,scif-r7s72100", "renesas,scif";
+ reg = <0xe8009000 64>;
+ interrupts = <0 206 IRQ_TYPE_LEVEL_HIGH>,
+ <0 207 IRQ_TYPE_LEVEL_HIGH>,
+ <0 208 IRQ_TYPE_LEVEL_HIGH>,
+ <0 205 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp4_clks R7S72100_CLK_SCIF4>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif5: serial@e8009800 {
+ compatible = "renesas,scif-r7s72100", "renesas,scif";
+ reg = <0xe8009800 64>;
+ interrupts = <0 210 IRQ_TYPE_LEVEL_HIGH>,
+ <0 211 IRQ_TYPE_LEVEL_HIGH>,
+ <0 212 IRQ_TYPE_LEVEL_HIGH>,
+ <0 209 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp4_clks R7S72100_CLK_SCIF5>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif6: serial@e800a000 {
+ compatible = "renesas,scif-r7s72100", "renesas,scif";
+ reg = <0xe800a000 64>;
+ interrupts = <0 214 IRQ_TYPE_LEVEL_HIGH>,
+ <0 215 IRQ_TYPE_LEVEL_HIGH>,
+ <0 216 IRQ_TYPE_LEVEL_HIGH>,
+ <0 213 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp4_clks R7S72100_CLK_SCIF6>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif7: serial@e800a800 {
+ compatible = "renesas,scif-r7s72100", "renesas,scif";
+ reg = <0xe800a800 64>;
+ interrupts = <0 218 IRQ_TYPE_LEVEL_HIGH>,
+ <0 219 IRQ_TYPE_LEVEL_HIGH>,
+ <0 220 IRQ_TYPE_LEVEL_HIGH>,
+ <0 217 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp4_clks R7S72100_CLK_SCIF7>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ spi0: spi@e800c800 {
+ compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz";
+ reg = <0xe800c800 0x24>;
+ interrupts = <0 238 IRQ_TYPE_LEVEL_HIGH>,
+ <0 239 IRQ_TYPE_LEVEL_HIGH>,
+ <0 240 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error", "rx", "tx";
+ clocks = <&mstp10_clks R7S72100_CLK_SPI0>;
+ num-cs = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi1: spi@e800d000 {
+ compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz";
+ reg = <0xe800d000 0x24>;
+ interrupts = <0 241 IRQ_TYPE_LEVEL_HIGH>,
+ <0 242 IRQ_TYPE_LEVEL_HIGH>,
+ <0 243 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error", "rx", "tx";
+ clocks = <&mstp10_clks R7S72100_CLK_SPI1>;
+ num-cs = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi2: spi@e800d800 {
+ compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz";
+ reg = <0xe800d800 0x24>;
+ interrupts = <0 244 IRQ_TYPE_LEVEL_HIGH>,
+ <0 245 IRQ_TYPE_LEVEL_HIGH>,
+ <0 246 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error", "rx", "tx";
+ clocks = <&mstp10_clks R7S72100_CLK_SPI2>;
+ num-cs = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi3: spi@e800e000 {
+ compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz";
+ reg = <0xe800e000 0x24>;
+ interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>,
+ <0 248 IRQ_TYPE_LEVEL_HIGH>,
+ <0 249 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error", "rx", "tx";
+ clocks = <&mstp10_clks R7S72100_CLK_SPI3>;
+ num-cs = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi4: spi@e800e800 {
+ compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz";
+ reg = <0xe800e800 0x24>;
+ interrupts = <0 250 IRQ_TYPE_LEVEL_HIGH>,
+ <0 251 IRQ_TYPE_LEVEL_HIGH>,
+ <0 252 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error", "rx", "tx";
+ clocks = <&mstp10_clks R7S72100_CLK_SPI4>;
+ num-cs = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@e8201000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0xe8201000 0x1000>,
+ <0xe8202000 0x1000>;
+ };
+
+ i2c0: i2c@fcfee000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
+ reg = <0xfcfee000 0x44>;
+ interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>,
+ <0 158 IRQ_TYPE_EDGE_RISING>,
+ <0 159 IRQ_TYPE_EDGE_RISING>,
+ <0 160 IRQ_TYPE_LEVEL_HIGH>,
+ <0 161 IRQ_TYPE_LEVEL_HIGH>,
+ <0 162 IRQ_TYPE_LEVEL_HIGH>,
+ <0 163 IRQ_TYPE_LEVEL_HIGH>,
+ <0 164 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R7S72100_CLK_I2C0>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@fcfee400 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
+ reg = <0xfcfee400 0x44>;
+ interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>,
+ <0 166 IRQ_TYPE_EDGE_RISING>,
+ <0 167 IRQ_TYPE_EDGE_RISING>,
+ <0 168 IRQ_TYPE_LEVEL_HIGH>,
+ <0 169 IRQ_TYPE_LEVEL_HIGH>,
+ <0 170 IRQ_TYPE_LEVEL_HIGH>,
+ <0 171 IRQ_TYPE_LEVEL_HIGH>,
+ <0 172 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R7S72100_CLK_I2C1>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@fcfee800 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
+ reg = <0xfcfee800 0x44>;
+ interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>,
+ <0 174 IRQ_TYPE_EDGE_RISING>,
+ <0 175 IRQ_TYPE_EDGE_RISING>,
+ <0 176 IRQ_TYPE_LEVEL_HIGH>,
+ <0 177 IRQ_TYPE_LEVEL_HIGH>,
+ <0 178 IRQ_TYPE_LEVEL_HIGH>,
+ <0 179 IRQ_TYPE_LEVEL_HIGH>,
+ <0 180 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R7S72100_CLK_I2C2>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@fcfeec00 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
+ reg = <0xfcfeec00 0x44>;
+ interrupts = <0 181 IRQ_TYPE_LEVEL_HIGH>,
+ <0 182 IRQ_TYPE_EDGE_RISING>,
+ <0 183 IRQ_TYPE_EDGE_RISING>,
+ <0 184 IRQ_TYPE_LEVEL_HIGH>,
+ <0 185 IRQ_TYPE_LEVEL_HIGH>,
+ <0 186 IRQ_TYPE_LEVEL_HIGH>,
+ <0 187 IRQ_TYPE_LEVEL_HIGH>,
+ <0 188 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R7S72100_CLK_I2C3>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ mtu2: timer@fcff0000 {
+ compatible = "renesas,mtu2-r7s72100", "renesas,mtu2";
+ reg = <0xfcff0000 0x400>;
+ interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tgi0a";
+ clocks = <&mstp3_clks R7S72100_CLK_MTU2>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm.dts b/arch/arm/boot/dts/r8a73a4-ape6evm.dts
new file mode 100644
index 000000000..81a38ceee
--- /dev/null
+++ b/arch/arm/boot/dts/r8a73a4-ape6evm.dts
@@ -0,0 +1,251 @@
+/*
+ * Device Tree Source for the APE6EVM board
+ *
+ * Copyright (C) 2013 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.
+ */
+
+/dts-v1/;
+#include "r8a73a4.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "APE6EVM";
+ compatible = "renesas,ape6evm", "renesas,r8a73a4";
+
+ aliases {
+ serial0 = &scifa0;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel root=/dev/nfs ip=dhcp rw";
+ stdout-path = &scifa0;
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0 0x40000000 0 0x40000000>;
+ };
+
+ memory@200000000 {
+ device_type = "memory";
+ reg = <2 0x00000000 0 0x40000000>;
+ };
+
+ vcc_mmc0: regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "MMC0 Vcc";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ vcc_sdhi0: regulator@1 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "SDHI0 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&pfc 76 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ /* Common 1.8V and 3.3V rails, used by several devices on APE6EVM */
+ ape6evm_fixed_1v8: regulator@2 {
+ compatible = "regulator-fixed";
+ regulator-name = "1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ape6evm_fixed_3v3: regulator@3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ led1 {
+ gpios = <&pfc 28 GPIO_ACTIVE_HIGH>;
+ label = "GNSS_EN";
+ };
+ led2 {
+ gpios = <&pfc 126 GPIO_ACTIVE_HIGH>;
+ label = "NFC_NRST";
+ };
+ led3 {
+ gpios = <&pfc 132 GPIO_ACTIVE_HIGH>;
+ label = "GNSS_NRST";
+ };
+ led4 {
+ gpios = <&pfc 232 GPIO_ACTIVE_HIGH>;
+ label = "BT_WAKEUP";
+ };
+ led5 {
+ gpios = <&pfc 250 GPIO_ACTIVE_HIGH>;
+ label = "STROBE";
+ };
+ led6 {
+ gpios = <&pfc 288 GPIO_ACTIVE_HIGH>;
+ label = "BBRESETOUT";
+ };
+ };
+
+ keyboard {
+ compatible = "gpio-keys";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&keyboard_pins>;
+
+ zero-key {
+ gpios = <&pfc 324 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_0>;
+ label = "S16";
+ gpio-key,wakeup;
+ };
+
+ menu-key {
+ gpios = <&pfc 325 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_MENU>;
+ label = "S17";
+ };
+
+ home-key {
+ gpios = <&pfc 326 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOME>;
+ label = "S18";
+ };
+
+ back-key {
+ gpios = <&pfc 327 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_BACK>;
+ label = "S19";
+ };
+
+ volup-key {
+ gpios = <&pfc 328 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ label = "S20";
+ };
+
+ voldown-key {
+ gpios = <&pfc 329 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ label = "S21";
+ };
+ };
+};
+
+&i2c5 {
+ status = "okay";
+ vdd_dvfs: max8973@1b {
+ compatible = "maxim,max8973";
+ reg = <0x1b>;
+
+ regulator-min-microvolt = <935000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_dvfs>;
+ operating-points = <
+ /* kHz uV */
+ 1950000 1115000
+ 1462500 995000
+ >;
+ voltage-tolerance = <1>; /* 1% */
+};
+
+&bsc {
+ ethernet@8000000 {
+ compatible = "smsc,lan9220", "smsc,lan9115";
+ reg = <0x08000000 0x1000>;
+ interrupt-parent = <&irqc1>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+ phy-mode = "mii";
+ reg-io-width = <4>;
+ smsc,irq-active-high;
+ smsc,irq-push-pull;
+ vdd33a-supply = <&ape6evm_fixed_3v3>;
+ vddvario-supply = <&ape6evm_fixed_1v8>;
+ };
+};
+
+&cmt1 {
+ status = "okay";
+};
+
+&pfc {
+ scifa0_pins: serial0 {
+ renesas,groups = "scifa0_data";
+ renesas,function = "scifa0";
+ };
+
+ mmc0_pins: mmc {
+ renesas,groups = "mmc0_data8", "mmc0_ctrl";
+ renesas,function = "mmc0";
+ };
+
+ sdhi0_pins: sd0 {
+ renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd";
+ renesas,function = "sdhi0";
+ };
+
+ sdhi1_pins: sd1 {
+ renesas,groups = "sdhi1_data4", "sdhi1_ctrl";
+ renesas,function = "sdhi1";
+ };
+
+ keyboard_pins: keyboard {
+ renesas,pins = "PORT324", "PORT325", "PORT326", "PORT327",
+ "PORT328", "PORT329";
+ bias-pull-up;
+ };
+};
+
+&mmcif0 {
+ vmmc-supply = <&vcc_mmc0>;
+ bus-width = <8>;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins>;
+ status = "okay";
+};
+
+&scifa0 {
+ pinctrl-0 = <&scifa0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&sdhi0 {
+ vmmc-supply = <&vcc_sdhi0>;
+ bus-width = <4>;
+ toshiba,mmc-wrprotect-disable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhi0_pins>;
+ status = "okay";
+};
+
+&sdhi1 {
+ vmmc-supply = <&ape6evm_fixed_3v3>;
+ bus-width = <4>;
+ broken-cd;
+ toshiba,mmc-wrprotect-disable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhi1_pins>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi
new file mode 100644
index 000000000..0fd889f88
--- /dev/null
+++ b/arch/arm/boot/dts/r8a73a4.dtsi
@@ -0,0 +1,891 @@
+/*
+ * Device Tree Source for the r8a73a4 SoC
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 Magnus Damm
+ *
+ * This file is licensed under the terms 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 <dt-bindings/clock/r8a73a4-clock.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "renesas,r8a73a4";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0>;
+ clock-frequency = <1500000000>;
+ power-domains = <&pd_a2sl>;
+ };
+ };
+
+ ptm {
+ compatible = "arm,coresight-etm3x";
+ power-domains = <&pd_d4>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ dbsc1: memory-controller@e6790000 {
+ compatible = "renesas,dbsc-r8a73a4";
+ reg = <0 0xe6790000 0 0x10000>;
+ power-domains = <&pd_a3bc>;
+ };
+
+ dbsc2: memory-controller@e67a0000 {
+ compatible = "renesas,dbsc-r8a73a4";
+ reg = <0 0xe67a0000 0 0x10000>;
+ power-domains = <&pd_a3bc>;
+ };
+
+ dmac: dma-multiplexer {
+ compatible = "renesas,shdma-mux";
+ #dma-cells = <1>;
+ dma-channels = <20>;
+ dma-requests = <256>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ dma0: dma-controller@e6700020 {
+ compatible = "renesas,shdma-r8a73a4";
+ reg = <0 0xe6700020 0 0x89e0>;
+ interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH
+ 0 200 IRQ_TYPE_LEVEL_HIGH
+ 0 201 IRQ_TYPE_LEVEL_HIGH
+ 0 202 IRQ_TYPE_LEVEL_HIGH
+ 0 203 IRQ_TYPE_LEVEL_HIGH
+ 0 204 IRQ_TYPE_LEVEL_HIGH
+ 0 205 IRQ_TYPE_LEVEL_HIGH
+ 0 206 IRQ_TYPE_LEVEL_HIGH
+ 0 207 IRQ_TYPE_LEVEL_HIGH
+ 0 208 IRQ_TYPE_LEVEL_HIGH
+ 0 209 IRQ_TYPE_LEVEL_HIGH
+ 0 210 IRQ_TYPE_LEVEL_HIGH
+ 0 211 IRQ_TYPE_LEVEL_HIGH
+ 0 212 IRQ_TYPE_LEVEL_HIGH
+ 0 213 IRQ_TYPE_LEVEL_HIGH
+ 0 214 IRQ_TYPE_LEVEL_HIGH
+ 0 215 IRQ_TYPE_LEVEL_HIGH
+ 0 216 IRQ_TYPE_LEVEL_HIGH
+ 0 217 IRQ_TYPE_LEVEL_HIGH
+ 0 218 IRQ_TYPE_LEVEL_HIGH
+ 0 219 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14", "ch15",
+ "ch16", "ch17", "ch18", "ch19";
+ clocks = <&mstp2_clks R8A73A4_CLK_DMAC>;
+ power-domains = <&pd_a3sp>;
+ };
+ };
+
+ i2c5: i2c@e60b0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
+ reg = <0 0xe60b0000 0 0x428>;
+ interrupts = <0 179 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp4_clks R8A73A4_CLK_IIC5>;
+ power-domains = <&pd_a3sp>;
+
+ status = "disabled";
+ };
+
+ cmt1: timer@e6130000 {
+ compatible = "renesas,cmt-48-r8a73a4", "renesas,cmt-48-gen2";
+ reg = <0 0xe6130000 0 0x1004>;
+ interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A73A4_CLK_CMT1>;
+ clock-names = "fck";
+ power-domains = <&pd_c5>;
+
+ renesas,channels-mask = <0xff>;
+
+ status = "disabled";
+ };
+
+ irqc0: interrupt-controller@e61c0000 {
+ compatible = "renesas,irqc-r8a73a4", "renesas,irqc";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0 0xe61c0000 0 0x200>;
+ interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>,
+ <0 1 IRQ_TYPE_LEVEL_HIGH>,
+ <0 2 IRQ_TYPE_LEVEL_HIGH>,
+ <0 3 IRQ_TYPE_LEVEL_HIGH>,
+ <0 4 IRQ_TYPE_LEVEL_HIGH>,
+ <0 5 IRQ_TYPE_LEVEL_HIGH>,
+ <0 6 IRQ_TYPE_LEVEL_HIGH>,
+ <0 7 IRQ_TYPE_LEVEL_HIGH>,
+ <0 8 IRQ_TYPE_LEVEL_HIGH>,
+ <0 9 IRQ_TYPE_LEVEL_HIGH>,
+ <0 10 IRQ_TYPE_LEVEL_HIGH>,
+ <0 11 IRQ_TYPE_LEVEL_HIGH>,
+ <0 12 IRQ_TYPE_LEVEL_HIGH>,
+ <0 13 IRQ_TYPE_LEVEL_HIGH>,
+ <0 14 IRQ_TYPE_LEVEL_HIGH>,
+ <0 15 IRQ_TYPE_LEVEL_HIGH>,
+ <0 16 IRQ_TYPE_LEVEL_HIGH>,
+ <0 17 IRQ_TYPE_LEVEL_HIGH>,
+ <0 18 IRQ_TYPE_LEVEL_HIGH>,
+ <0 19 IRQ_TYPE_LEVEL_HIGH>,
+ <0 20 IRQ_TYPE_LEVEL_HIGH>,
+ <0 21 IRQ_TYPE_LEVEL_HIGH>,
+ <0 22 IRQ_TYPE_LEVEL_HIGH>,
+ <0 23 IRQ_TYPE_LEVEL_HIGH>,
+ <0 24 IRQ_TYPE_LEVEL_HIGH>,
+ <0 25 IRQ_TYPE_LEVEL_HIGH>,
+ <0 26 IRQ_TYPE_LEVEL_HIGH>,
+ <0 27 IRQ_TYPE_LEVEL_HIGH>,
+ <0 28 IRQ_TYPE_LEVEL_HIGH>,
+ <0 29 IRQ_TYPE_LEVEL_HIGH>,
+ <0 30 IRQ_TYPE_LEVEL_HIGH>,
+ <0 31 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd_c4>;
+ };
+
+ irqc1: interrupt-controller@e61c0200 {
+ compatible = "renesas,irqc-r8a73a4", "renesas,irqc";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0 0xe61c0200 0 0x200>;
+ interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>,
+ <0 33 IRQ_TYPE_LEVEL_HIGH>,
+ <0 34 IRQ_TYPE_LEVEL_HIGH>,
+ <0 35 IRQ_TYPE_LEVEL_HIGH>,
+ <0 36 IRQ_TYPE_LEVEL_HIGH>,
+ <0 37 IRQ_TYPE_LEVEL_HIGH>,
+ <0 38 IRQ_TYPE_LEVEL_HIGH>,
+ <0 39 IRQ_TYPE_LEVEL_HIGH>,
+ <0 40 IRQ_TYPE_LEVEL_HIGH>,
+ <0 41 IRQ_TYPE_LEVEL_HIGH>,
+ <0 42 IRQ_TYPE_LEVEL_HIGH>,
+ <0 43 IRQ_TYPE_LEVEL_HIGH>,
+ <0 44 IRQ_TYPE_LEVEL_HIGH>,
+ <0 45 IRQ_TYPE_LEVEL_HIGH>,
+ <0 46 IRQ_TYPE_LEVEL_HIGH>,
+ <0 47 IRQ_TYPE_LEVEL_HIGH>,
+ <0 48 IRQ_TYPE_LEVEL_HIGH>,
+ <0 49 IRQ_TYPE_LEVEL_HIGH>,
+ <0 50 IRQ_TYPE_LEVEL_HIGH>,
+ <0 51 IRQ_TYPE_LEVEL_HIGH>,
+ <0 52 IRQ_TYPE_LEVEL_HIGH>,
+ <0 53 IRQ_TYPE_LEVEL_HIGH>,
+ <0 54 IRQ_TYPE_LEVEL_HIGH>,
+ <0 55 IRQ_TYPE_LEVEL_HIGH>,
+ <0 56 IRQ_TYPE_LEVEL_HIGH>,
+ <0 57 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd_c4>;
+ };
+
+ pfc: pfc@e6050000 {
+ compatible = "renesas,pfc-r8a73a4";
+ reg = <0 0xe6050000 0 0x9000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts-extended =
+ <&irqc0 0 0>, <&irqc0 1 0>, <&irqc0 2 0>, <&irqc0 3 0>,
+ <&irqc0 4 0>, <&irqc0 5 0>, <&irqc0 6 0>, <&irqc0 7 0>,
+ <&irqc0 8 0>, <&irqc0 9 0>, <&irqc0 10 0>, <&irqc0 11 0>,
+ <&irqc0 12 0>, <&irqc0 13 0>, <&irqc0 14 0>, <&irqc0 15 0>,
+ <&irqc0 16 0>, <&irqc0 17 0>, <&irqc0 18 0>, <&irqc0 19 0>,
+ <&irqc0 20 0>, <&irqc0 21 0>, <&irqc0 22 0>, <&irqc0 23 0>,
+ <&irqc0 24 0>, <&irqc0 25 0>, <&irqc0 26 0>, <&irqc0 27 0>,
+ <&irqc0 28 0>, <&irqc0 29 0>, <&irqc0 30 0>, <&irqc0 31 0>,
+ <&irqc1 0 0>, <&irqc1 1 0>, <&irqc1 2 0>, <&irqc1 3 0>,
+ <&irqc1 4 0>, <&irqc1 5 0>, <&irqc1 6 0>, <&irqc1 7 0>,
+ <&irqc1 8 0>, <&irqc1 9 0>, <&irqc1 10 0>, <&irqc1 11 0>,
+ <&irqc1 12 0>, <&irqc1 13 0>, <&irqc1 14 0>, <&irqc1 15 0>,
+ <&irqc1 16 0>, <&irqc1 17 0>, <&irqc1 18 0>, <&irqc1 19 0>,
+ <&irqc1 20 0>, <&irqc1 21 0>, <&irqc1 22 0>, <&irqc1 23 0>,
+ <&irqc1 24 0>, <&irqc1 25 0>;
+ power-domains = <&pd_c5>;
+ };
+
+ thermal@e61f0000 {
+ compatible = "renesas,thermal-r8a73a4", "renesas,rcar-thermal";
+ reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>,
+ <0 0xe61f0200 0 0x38>, <0 0xe61f0300 0 0x38>;
+ interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp5_clks R8A73A4_CLK_THERMAL>;
+ power-domains = <&pd_c5>;
+ };
+
+ i2c0: i2c@e6500000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
+ reg = <0 0xe6500000 0 0x428>;
+ interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A73A4_CLK_IIC0>;
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@e6510000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
+ reg = <0 0xe6510000 0 0x428>;
+ interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A73A4_CLK_IIC1>;
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@e6520000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
+ reg = <0 0xe6520000 0 0x428>;
+ interrupts = <0 176 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A73A4_CLK_IIC2>;
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@e6530000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
+ reg = <0 0xe6530000 0 0x428>;
+ interrupts = <0 177 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp4_clks R8A73A4_CLK_IIC3>;
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@e6540000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
+ reg = <0 0xe6540000 0 0x428>;
+ interrupts = <0 178 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp4_clks R8A73A4_CLK_IIC4>;
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ i2c6: i2c@e6550000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
+ reg = <0 0xe6550000 0 0x428>;
+ interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A73A4_CLK_IIC6>;
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ i2c7: i2c@e6560000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
+ reg = <0 0xe6560000 0 0x428>;
+ interrupts = <0 185 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A73A4_CLK_IIC7>;
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ i2c8: i2c@e6570000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
+ reg = <0 0xe6570000 0 0x428>;
+ interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp5_clks R8A73A4_CLK_IIC8>;
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifb0: serial@e6c20000 {
+ compatible = "renesas,scifb-r8a73a4", "renesas,scifb";
+ reg = <0 0xe6c20000 0 0x100>;
+ interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A73A4_CLK_SCIFB0>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifb1: serial@e6c30000 {
+ compatible = "renesas,scifb-r8a73a4", "renesas,scifb";
+ reg = <0 0xe6c30000 0 0x100>;
+ interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A73A4_CLK_SCIFB1>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa0: serial@e6c40000 {
+ compatible = "renesas,scifa-r8a73a4", "renesas,scifa";
+ reg = <0 0xe6c40000 0 0x100>;
+ interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A73A4_CLK_SCIFA0>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa1: serial@e6c50000 {
+ compatible = "renesas,scifa-r8a73a4", "renesas,scifa";
+ reg = <0 0xe6c50000 0 0x100>;
+ interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A73A4_CLK_SCIFA1>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifb2: serial@e6ce0000 {
+ compatible = "renesas,scifb-r8a73a4", "renesas,scifb";
+ reg = <0 0xe6ce0000 0 0x100>;
+ interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A73A4_CLK_SCIFB2>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifb3: serial@e6cf0000 {
+ compatible = "renesas,scifb-r8a73a4", "renesas,scifb";
+ reg = <0 0xe6cf0000 0 0x100>;
+ interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A73A4_CLK_SCIFB3>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_c4>;
+ status = "disabled";
+ };
+
+ sdhi0: sd@ee100000 {
+ compatible = "renesas,sdhi-r8a73a4";
+ reg = <0 0xee100000 0 0x100>;
+ interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A73A4_CLK_SDHI0>;
+ power-domains = <&pd_a3sp>;
+ cap-sd-highspeed;
+ status = "disabled";
+ };
+
+ sdhi1: sd@ee120000 {
+ compatible = "renesas,sdhi-r8a73a4";
+ reg = <0 0xee120000 0 0x100>;
+ interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A73A4_CLK_SDHI1>;
+ power-domains = <&pd_a3sp>;
+ cap-sd-highspeed;
+ status = "disabled";
+ };
+
+ sdhi2: sd@ee140000 {
+ compatible = "renesas,sdhi-r8a73a4";
+ reg = <0 0xee140000 0 0x100>;
+ interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A73A4_CLK_SDHI2>;
+ power-domains = <&pd_a3sp>;
+ cap-sd-highspeed;
+ status = "disabled";
+ };
+
+ mmcif0: mmc@ee200000 {
+ compatible = "renesas,sh-mmcif";
+ reg = <0 0xee200000 0 0x80>;
+ interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A73A4_CLK_MMCIF0>;
+ power-domains = <&pd_a3sp>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ mmcif1: mmc@ee220000 {
+ compatible = "renesas,sh-mmcif";
+ reg = <0 0xee220000 0 0x80>;
+ interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A73A4_CLK_MMCIF1>;
+ power-domains = <&pd_a3sp>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@f1001000 {
+ compatible = "arm,cortex-a15-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0 0xf1001000 0 0x1000>,
+ <0 0xf1002000 0 0x1000>,
+ <0 0xf1004000 0 0x2000>,
+ <0 0xf1006000 0 0x2000>;
+ interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ bsc: bus@fec10000 {
+ compatible = "renesas,bsc-r8a73a4", "renesas,bsc",
+ "simple-pm-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0 0x20000000>;
+ reg = <0 0xfec10000 0 0x400>;
+ clocks = <&zb_clk>;
+ power-domains = <&pd_c4>;
+ };
+
+ clocks {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* External root clocks */
+ extalr_clk: extalr_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "extalr";
+ };
+ extal1_clk: extal1_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ clock-output-names = "extal1";
+ };
+ extal2_clk: extal2_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <48000000>;
+ clock-output-names = "extal2";
+ };
+ fsiack_clk: fsiack_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ clock-output-names = "fsiack";
+ };
+ fsibck_clk: fsibck_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ clock-output-names = "fsibck";
+ };
+
+ /* Special CPG clocks */
+ cpg_clocks: cpg_clocks@e6150000 {
+ compatible = "renesas,r8a73a4-cpg-clocks";
+ reg = <0 0xe6150000 0 0x10000>;
+ clocks = <&extal1_clk>, <&extal2_clk>;
+ #clock-cells = <1>;
+ clock-output-names = "main", "pll0", "pll1", "pll2",
+ "pll2s", "pll2h", "z", "z2",
+ "i", "m3", "b", "m1", "m2",
+ "zx", "zs", "hp";
+ };
+
+ /* Variable factor clocks (DIV6) */
+ zb_clk: zb_clk@e6150010 {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150010 0 4>;
+ clocks = <&pll1_div2_clk>, <0>,
+ <&cpg_clocks R8A73A4_CLK_PLL2S>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "zb";
+ };
+ sdhi0_clk: sdhi0_clk@e6150074 {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150074 0 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>,
+ <0>, <&extal2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sdhi0ck";
+ };
+ sdhi1_clk: sdhi1_clk@e6150078 {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150078 0 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>,
+ <0>, <&extal2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sdhi1ck";
+ };
+ sdhi2_clk: sdhi2_clk@e615007c {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe615007c 0 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>,
+ <0>, <&extal2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sdhi2ck";
+ };
+ mmc0_clk: mmc0_clk@e6150240 {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150240 0 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>,
+ <0>, <&extal2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "mmc0";
+ };
+ mmc1_clk: mmc1_clk@e6150244 {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150244 0 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>,
+ <0>, <&extal2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "mmc1";
+ };
+ vclk1_clk: vclk1_clk@e6150008 {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150008 0 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>,
+ <0>, <&extal2_clk>, <&main_div2_clk>,
+ <&extalr_clk>, <0>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "vclk1";
+ };
+ vclk2_clk: vclk2_clk@e615000c {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe615000c 0 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>,
+ <0>, <&extal2_clk>, <&main_div2_clk>,
+ <&extalr_clk>, <0>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "vclk2";
+ };
+ vclk3_clk: vclk3_clk@e615001c {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe615001c 0 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>,
+ <0>, <&extal2_clk>, <&main_div2_clk>,
+ <&extalr_clk>, <0>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "vclk3";
+ };
+ vclk4_clk: vclk4_clk@e6150014 {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150014 0 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>,
+ <0>, <&extal2_clk>, <&main_div2_clk>,
+ <&extalr_clk>, <0>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "vclk4";
+ };
+ vclk5_clk: vclk5_clk@e6150034 {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150034 0 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>,
+ <0>, <&extal2_clk>, <&main_div2_clk>,
+ <&extalr_clk>, <0>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "vclk5";
+ };
+ fsia_clk: fsia_clk@e6150018 {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150018 0 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>,
+ <&fsiack_clk>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "fsia";
+ };
+ fsib_clk: fsib_clk@e6150090 {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150090 0 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>,
+ <&fsibck_clk>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "fsib";
+ };
+ mp_clk: mp_clk@e6150080 {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150080 0 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>,
+ <&extal2_clk>, <&extal2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "mp";
+ };
+ m4_clk: m4_clk@e6150098 {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150098 0 4>;
+ clocks = <&cpg_clocks R8A73A4_CLK_PLL2S>;
+ #clock-cells = <0>;
+ clock-output-names = "m4";
+ };
+ hsi_clk: hsi_clk@e615026c {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe615026c 0 4>;
+ clocks = <&cpg_clocks R8A73A4_CLK_PLL2H>, <&pll1_div2_clk>,
+ <&cpg_clocks R8A73A4_CLK_PLL2S>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "hsi";
+ };
+ spuv_clk: spuv_clk@e6150094 {
+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150094 0 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>,
+ <&extal2_clk>, <&extal2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "spuv";
+ };
+
+ /* Fixed factor clocks */
+ main_div2_clk: main_div2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A73A4_CLK_MAIN>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "main_div2";
+ };
+ pll0_div2_clk: pll0_div2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A73A4_CLK_PLL0>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "pll0_div2";
+ };
+ pll1_div2_clk: pll1_div2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A73A4_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "pll1_div2";
+ };
+ extal1_div2_clk: extal1_div2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&extal1_clk>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "extal1_div2";
+ };
+
+ /* Gate clocks */
+ mstp2_clks: mstp2_clks@e6150138 {
+ compatible = "renesas,r8a73a4-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
+ clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>,
+ <&mp_clk>, <&mp_clk>, <&cpg_clocks R8A73A4_CLK_HP>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A73A4_CLK_SCIFA0 R8A73A4_CLK_SCIFA1
+ R8A73A4_CLK_SCIFB0 R8A73A4_CLK_SCIFB1
+ R8A73A4_CLK_SCIFB2 R8A73A4_CLK_SCIFB3
+ R8A73A4_CLK_DMAC
+ >;
+ clock-output-names =
+ "scifa0", "scifa1", "scifb0", "scifb1",
+ "scifb2", "scifb3", "dmac";
+ };
+ mstp3_clks: mstp3_clks@e615013c {
+ compatible = "renesas,r8a73a4-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
+ clocks = <&cpg_clocks R8A73A4_CLK_HP>, <&mmc1_clk>,
+ <&sdhi2_clk>, <&sdhi1_clk>, <&sdhi0_clk>,
+ <&mmc0_clk>, <&cpg_clocks R8A73A4_CLK_HP>,
+ <&cpg_clocks R8A73A4_CLK_HP>, <&cpg_clocks
+ R8A73A4_CLK_HP>, <&cpg_clocks
+ R8A73A4_CLK_HP>, <&extalr_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A73A4_CLK_IIC2 R8A73A4_CLK_MMCIF1
+ R8A73A4_CLK_SDHI2 R8A73A4_CLK_SDHI1
+ R8A73A4_CLK_SDHI0 R8A73A4_CLK_MMCIF0
+ R8A73A4_CLK_IIC6 R8A73A4_CLK_IIC7
+ R8A73A4_CLK_IIC0 R8A73A4_CLK_IIC1
+ R8A73A4_CLK_CMT1
+ >;
+ clock-output-names =
+ "iic2", "mmcif1", "sdhi2", "sdhi1", "sdhi0",
+ "mmcif0", "iic6", "iic7", "iic0", "iic1",
+ "cmt1";
+ };
+ mstp4_clks: mstp4_clks@e6150140 {
+ compatible = "renesas,r8a73a4-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150140 0 4>, <0 0xe615004c 0 4>;
+ clocks = <&main_div2_clk>, <&cpg_clocks R8A73A4_CLK_HP>,
+ <&cpg_clocks R8A73A4_CLK_HP>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A73A4_CLK_IIC5 R8A73A4_CLK_IIC4
+ R8A73A4_CLK_IIC3
+ >;
+ clock-output-names =
+ "iic5", "iic4", "iic3";
+ };
+ mstp5_clks: mstp5_clks@e6150144 {
+ compatible = "renesas,r8a73a4-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>;
+ clocks = <&extal2_clk>, <&cpg_clocks R8A73A4_CLK_HP>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A73A4_CLK_THERMAL R8A73A4_CLK_IIC8
+ >;
+ clock-output-names =
+ "thermal", "iic8";
+ };
+ };
+
+ sysc: system-controller@e6180000 {
+ compatible = "renesas,sysc-r8a73a4", "renesas,sysc-rmobile";
+ reg = <0 0xe6180000 0 0x8000>, <0 0xe6188000 0 0x8000>;
+
+ pm-domains {
+ pd_c5: c5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_c4: c4@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a3sg: a3sg@16 {
+ reg = <16>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a3ex: a3ex@17 {
+ reg = <17>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a3sp: a3sp@18 {
+ reg = <18>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a2us: a2us@19 {
+ reg = <19>;
+ #power-domain-cells = <0>;
+ };
+ };
+
+ pd_a3sm: a3sm@20 {
+ reg = <20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a2sl: a2sl@21 {
+ reg = <21>;
+ #power-domain-cells = <0>;
+ };
+ };
+
+ pd_a3km: a3km@22 {
+ reg = <22>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a2kl: a2kl@23 {
+ reg = <23>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+
+ pd_c4ma: c4ma@1 {
+ reg = <1>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_c4cl: c4cl@2 {
+ reg = <2>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_d4: d4@3 {
+ reg = <3>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a4bc: a4bc@4 {
+ reg = <4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a3bc: a3bc@5 {
+ reg = <5>;
+ #power-domain-cells = <0>;
+ };
+ };
+
+ pd_a4l: a4l@6 {
+ reg = <6>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a4lc: a4lc@7 {
+ reg = <7>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a4mp: a4mp@8 {
+ reg = <8>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a3mp: a3mp@9 {
+ reg = <9>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a3vc: a3vc@10 {
+ reg = <10>;
+ #power-domain-cells = <0>;
+ };
+ };
+
+ pd_a4sf: a4sf@11 {
+ reg = <11>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a3r: a3r@12 {
+ reg = <12>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a2rv: a2rv@13 {
+ reg = <13>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a2is: a2is@14 {
+ reg = <14>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/r8a7740-armadillo800eva.dts b/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
new file mode 100644
index 000000000..9bd0cb439
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
@@ -0,0 +1,305 @@
+/*
+ * Device Tree Source for the armadillo 800 eva board
+ *
+ * Copyright (C) 2012 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.
+ */
+
+/dts-v1/;
+#include "r8a7740.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ model = "armadillo 800 eva";
+ compatible = "renesas,armadillo800eva", "renesas,r8a7740";
+
+ aliases {
+ serial1 = &scifa1;
+ };
+
+ chosen {
+ bootargs = "console=tty0 console=ttySC1,115200 earlyprintk=sh-sci.1,115200 ignore_loglevel root=/dev/nfs ip=dhcp rw";
+ stdout-path = &scifa1;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x40000000 0x20000000>;
+ };
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_sdhi0: regulator@1 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "SDHI0 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&pfc 75 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vccq_sdhi0: regulator@2 {
+ compatible = "regulator-gpio";
+
+ regulator-name = "SDHI0 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_sdhi0>;
+
+ enable-gpio = <&pfc 74 GPIO_ACTIVE_HIGH>;
+ gpios = <&pfc 17 GPIO_ACTIVE_HIGH>;
+ states = <3300000 0
+ 1800000 1>;
+
+ enable-active-high;
+ };
+
+ reg_5p0v: regulator@3 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-5.0V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ keyboard {
+ compatible = "gpio-keys";
+
+ power-key {
+ gpios = <&pfc 99 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ label = "SW3";
+ gpio-key,wakeup;
+ };
+
+ back-key {
+ gpios = <&pfc 100 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_BACK>;
+ label = "SW4";
+ };
+
+ menu-key {
+ gpios = <&pfc 97 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_MENU>;
+ label = "SW5";
+ };
+
+ home-key {
+ gpios = <&pfc 98 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOME>;
+ label = "SW6";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ led3 {
+ gpios = <&pfc 102 GPIO_ACTIVE_HIGH>;
+ label = "LED3";
+ };
+ led4 {
+ gpios = <&pfc 111 GPIO_ACTIVE_HIGH>;
+ label = "LED4";
+ };
+ led5 {
+ gpios = <&pfc 110 GPIO_ACTIVE_HIGH>;
+ label = "LED5";
+ };
+ led6 {
+ gpios = <&pfc 177 GPIO_ACTIVE_HIGH>;
+ label = "LED6";
+ };
+ };
+
+ i2c2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "i2c-gpio";
+ gpios = <&pfc 208 GPIO_ACTIVE_HIGH /* sda */
+ &pfc 91 GPIO_ACTIVE_HIGH /* scl */
+ >;
+ i2c-gpio,delay-us = <5>;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&tpu 2 33333 PWM_POLARITY_INVERTED>;
+ brightness-levels = <0 1 2 4 8 16 32 64 128 255>;
+ default-brightness-level = <9>;
+ pinctrl-0 = <&backlight_pins>;
+ pinctrl-names = "default";
+ power-supply = <&reg_5p0v>;
+ enable-gpios = <&pfc 61 GPIO_ACTIVE_HIGH>;
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+
+ simple-audio-card,format = "i2s";
+
+ simple-audio-card,cpu {
+ sound-dai = <&sh_fsi2 0>;
+ bitclock-inversion;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&wm8978>;
+ bitclock-master;
+ frame-master;
+ system-clock-frequency = <12288000>;
+ };
+ };
+};
+
+&ether {
+ pinctrl-0 = <&ether_pins>;
+ pinctrl-names = "default";
+
+ phy-handle = <&phy0>;
+ status = "okay";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&extal1_clk {
+ clock-frequency = <25000000>;
+};
+&extal2_clk {
+ clock-frequency = <48000000>;
+};
+&fsibck_clk {
+ clock-frequency = <12288000>;
+};
+&cpg_clocks {
+ renesas,mode = <0x05>; /* MD_CK0 | MD_CK2 */
+};
+
+&cmt1 {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+ touchscreen@55 {
+ compatible = "sitronix,st1232";
+ reg = <0x55>;
+ interrupt-parent = <&irqpin1>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-0 = <&st1232_pins>;
+ pinctrl-names = "default";
+ gpios = <&pfc 166 GPIO_ACTIVE_LOW>;
+ };
+
+ wm8978: wm8978@1a {
+ #sound-dai-cells = <0>;
+ compatible = "wlf,wm8978";
+ reg = <0x1a>;
+ };
+};
+
+&i2c2 {
+ status = "okay";
+ rtc@30 {
+ compatible = "sii,s35390a";
+ reg = <0x30>;
+ };
+};
+
+&pfc {
+ ether_pins: ether {
+ renesas,groups = "gether_mii", "gether_int";
+ renesas,function = "gether";
+ };
+
+ scifa1_pins: serial1 {
+ renesas,groups = "scifa1_data";
+ renesas,function = "scifa1";
+ };
+
+ st1232_pins: touchscreen {
+ renesas,groups = "intc_irq10";
+ renesas,function = "intc";
+ };
+
+ backlight_pins: backlight {
+ renesas,groups = "tpu0_to2_1";
+ renesas,function = "tpu0";
+ };
+
+ mmc0_pins: mmc0 {
+ renesas,groups = "mmc0_data8_1", "mmc0_ctrl_1";
+ renesas,function = "mmc0";
+ };
+
+ sdhi0_pins: sd0 {
+ renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_wp";
+ renesas,function = "sdhi0";
+ };
+
+ fsia_pins: sounda {
+ renesas,groups = "fsia_sclk_in", "fsia_mclk_out",
+ "fsia_data_in_1", "fsia_data_out_0";
+ renesas,function = "fsia";
+ };
+};
+
+&tpu {
+ status = "okay";
+};
+
+&mmcif0 {
+ pinctrl-0 = <&mmc0_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&reg_3p3v>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&scifa1 {
+ pinctrl-0 = <&scifa1_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&vcc_sdhi0>;
+ vqmmc-supply = <&vccq_sdhi0>;
+ bus-width = <4>;
+ cd-gpios = <&pfc 167 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&sh_fsi2 {
+ pinctrl-0 = <&fsia_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&tmu0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi
new file mode 100644
index 000000000..83c1c3ca1
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7740.dtsi
@@ -0,0 +1,728 @@
+/*
+ * Device Tree Source for the r8a7740 SoC
+ *
+ * Copyright (C) 2012 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/ "skeleton.dtsi"
+
+#include <dt-bindings/clock/r8a7740-clock.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "renesas,r8a7740";
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0x0>;
+ clock-frequency = <800000000>;
+ power-domains = <&pd_a3sm>;
+ };
+ };
+
+ gic: interrupt-controller@c2800000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0xc2800000 0x1000>,
+ <0xc2000000 0x1000>;
+ };
+
+ dbsc3: memory-controller@fe400000 {
+ compatible = "renesas,dbsc3-r8a7740";
+ reg = <0xfe400000 0x400>;
+ power-domains = <&pd_a4s>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ ptm {
+ compatible = "arm,coresight-etm3x";
+ power-domains = <&pd_d4>;
+ };
+
+ cmt1: timer@e6138000 {
+ compatible = "renesas,cmt-48-r8a7740", "renesas,cmt-48";
+ reg = <0xe6138000 0x170>;
+ interrupts = <0 58 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7740_CLK_CMT1>;
+ clock-names = "fck";
+ power-domains = <&pd_c5>;
+
+ renesas,channels-mask = <0x3f>;
+
+ status = "disabled";
+ };
+
+ /* irqpin0: IRQ0 - IRQ7 */
+ irqpin0: irqpin@e6900000 {
+ compatible = "renesas,intc-irqpin-r8a7740", "renesas,intc-irqpin";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0xe6900000 4>,
+ <0xe6900010 4>,
+ <0xe6900020 1>,
+ <0xe6900040 1>,
+ <0xe6900060 1>;
+ interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
+ power-domains = <&pd_a4s>;
+ };
+
+ /* irqpin1: IRQ8 - IRQ15 */
+ irqpin1: irqpin@e6900004 {
+ compatible = "renesas,intc-irqpin-r8a7740", "renesas,intc-irqpin";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0xe6900004 4>,
+ <0xe6900014 4>,
+ <0xe6900024 1>,
+ <0xe6900044 1>,
+ <0xe6900064 1>;
+ interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
+ power-domains = <&pd_a4s>;
+ };
+
+ /* irqpin2: IRQ16 - IRQ23 */
+ irqpin2: irqpin@e6900008 {
+ compatible = "renesas,intc-irqpin-r8a7740", "renesas,intc-irqpin";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0xe6900008 4>,
+ <0xe6900018 4>,
+ <0xe6900028 1>,
+ <0xe6900048 1>,
+ <0xe6900068 1>;
+ interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
+ power-domains = <&pd_a4s>;
+ };
+
+ /* irqpin3: IRQ24 - IRQ31 */
+ irqpin3: irqpin@e690000c {
+ compatible = "renesas,intc-irqpin-r8a7740", "renesas,intc-irqpin";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0xe690000c 4>,
+ <0xe690001c 4>,
+ <0xe690002c 1>,
+ <0xe690004c 1>,
+ <0xe690006c 1>;
+ interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
+ power-domains = <&pd_a4s>;
+ };
+
+ ether: ethernet@e9a00000 {
+ compatible = "renesas,gether-r8a7740";
+ reg = <0xe9a00000 0x800>,
+ <0xe9a01800 0x800>;
+ interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7740_CLK_GETHER>;
+ power-domains = <&pd_a4s>;
+ phy-mode = "mii";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@fff20000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a7740", "renesas,rmobile-iic";
+ reg = <0xfff20000 0x425>;
+ interrupts = <0 201 IRQ_TYPE_LEVEL_HIGH
+ 0 202 IRQ_TYPE_LEVEL_HIGH
+ 0 203 IRQ_TYPE_LEVEL_HIGH
+ 0 204 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7740_CLK_IIC0>;
+ power-domains = <&pd_a4r>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@e6c20000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a7740", "renesas,rmobile-iic";
+ reg = <0xe6c20000 0x425>;
+ interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH
+ 0 71 IRQ_TYPE_LEVEL_HIGH
+ 0 72 IRQ_TYPE_LEVEL_HIGH
+ 0 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7740_CLK_IIC1>;
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa0: serial@e6c40000 {
+ compatible = "renesas,scifa-r8a7740", "renesas,scifa";
+ reg = <0xe6c40000 0x100>;
+ interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7740_CLK_SCIFA0>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa1: serial@e6c50000 {
+ compatible = "renesas,scifa-r8a7740", "renesas,scifa";
+ reg = <0xe6c50000 0x100>;
+ interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7740_CLK_SCIFA1>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa2: serial@e6c60000 {
+ compatible = "renesas,scifa-r8a7740", "renesas,scifa";
+ reg = <0xe6c60000 0x100>;
+ interrupts = <0 102 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7740_CLK_SCIFA2>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa3: serial@e6c70000 {
+ compatible = "renesas,scifa-r8a7740", "renesas,scifa";
+ reg = <0xe6c70000 0x100>;
+ interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7740_CLK_SCIFA3>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa4: serial@e6c80000 {
+ compatible = "renesas,scifa-r8a7740", "renesas,scifa";
+ reg = <0xe6c80000 0x100>;
+ interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7740_CLK_SCIFA4>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa5: serial@e6cb0000 {
+ compatible = "renesas,scifa-r8a7740", "renesas,scifa";
+ reg = <0xe6cb0000 0x100>;
+ interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7740_CLK_SCIFA5>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa6: serial@e6cc0000 {
+ compatible = "renesas,scifa-r8a7740", "renesas,scifa";
+ reg = <0xe6cc0000 0x100>;
+ interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7740_CLK_SCIFA6>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa7: serial@e6cd0000 {
+ compatible = "renesas,scifa-r8a7740", "renesas,scifa";
+ reg = <0xe6cd0000 0x100>;
+ interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7740_CLK_SCIFA7>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifb8: serial@e6c30000 {
+ compatible = "renesas,scifb-r8a7740", "renesas,scifb";
+ reg = <0xe6c30000 0x100>;
+ interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7740_CLK_SCIFB>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ pfc: pfc@e6050000 {
+ compatible = "renesas,pfc-r8a7740";
+ reg = <0xe6050000 0x8000>,
+ <0xe605800c 0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts-extended =
+ <&irqpin0 0 0>, <&irqpin0 1 0>, <&irqpin0 2 0>, <&irqpin0 3 0>,
+ <&irqpin0 4 0>, <&irqpin0 5 0>, <&irqpin0 6 0>, <&irqpin0 7 0>,
+ <&irqpin1 0 0>, <&irqpin1 1 0>, <&irqpin1 2 0>, <&irqpin1 3 0>,
+ <&irqpin1 4 0>, <&irqpin1 5 0>, <&irqpin1 6 0>, <&irqpin1 7 0>,
+ <&irqpin2 0 0>, <&irqpin2 1 0>, <&irqpin2 2 0>, <&irqpin2 3 0>,
+ <&irqpin2 4 0>, <&irqpin2 5 0>, <&irqpin2 6 0>, <&irqpin2 7 0>,
+ <&irqpin3 0 0>, <&irqpin3 1 0>, <&irqpin3 2 0>, <&irqpin3 3 0>,
+ <&irqpin3 4 0>, <&irqpin3 5 0>, <&irqpin3 6 0>, <&irqpin3 7 0>;
+ power-domains = <&pd_c5>;
+ };
+
+ tpu: pwm@e6600000 {
+ compatible = "renesas,tpu-r8a7740", "renesas,tpu";
+ reg = <0xe6600000 0x100>;
+ clocks = <&mstp3_clks R8A7740_CLK_TPU0>;
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ #pwm-cells = <3>;
+ };
+
+ mmcif0: mmc@e6bd0000 {
+ compatible = "renesas,mmcif-r8a7740", "renesas,sh-mmcif";
+ reg = <0xe6bd0000 0x100>;
+ interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH
+ 0 57 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7740_CLK_MMC>;
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ sdhi0: sd@e6850000 {
+ compatible = "renesas,sdhi-r8a7740";
+ reg = <0xe6850000 0x100>;
+ interrupts = <0 117 IRQ_TYPE_LEVEL_HIGH
+ 0 118 IRQ_TYPE_LEVEL_HIGH
+ 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7740_CLK_SDHI0>;
+ power-domains = <&pd_a3sp>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ status = "disabled";
+ };
+
+ sdhi1: sd@e6860000 {
+ compatible = "renesas,sdhi-r8a7740";
+ reg = <0xe6860000 0x100>;
+ interrupts = <0 121 IRQ_TYPE_LEVEL_HIGH
+ 0 122 IRQ_TYPE_LEVEL_HIGH
+ 0 123 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7740_CLK_SDHI1>;
+ power-domains = <&pd_a3sp>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ status = "disabled";
+ };
+
+ sdhi2: sd@e6870000 {
+ compatible = "renesas,sdhi-r8a7740";
+ reg = <0xe6870000 0x100>;
+ interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH
+ 0 126 IRQ_TYPE_LEVEL_HIGH
+ 0 127 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp4_clks R8A7740_CLK_SDHI2>;
+ power-domains = <&pd_a3sp>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ status = "disabled";
+ };
+
+ sh_fsi2: sound@fe1f0000 {
+ #sound-dai-cells = <1>;
+ compatible = "renesas,fsi2-r8a7740", "renesas,sh_fsi2";
+ reg = <0xfe1f0000 0x400>;
+ interrupts = <0 9 0x4>;
+ clocks = <&mstp3_clks R8A7740_CLK_FSI>;
+ power-domains = <&pd_a4mp>;
+ status = "disabled";
+ };
+
+ tmu0: timer@fff80000 {
+ compatible = "renesas,tmu-r8a7740", "renesas,tmu";
+ reg = <0xfff80000 0x2c>;
+ interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>,
+ <0 199 IRQ_TYPE_LEVEL_HIGH>,
+ <0 200 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7740_CLK_TMU0>;
+ clock-names = "fck";
+ power-domains = <&pd_a4r>;
+
+ #renesas,channels = <3>;
+
+ status = "disabled";
+ };
+
+ tmu1: timer@fff90000 {
+ compatible = "renesas,tmu-r8a7740", "renesas,tmu";
+ reg = <0xfff90000 0x2c>;
+ interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>,
+ <0 171 IRQ_TYPE_LEVEL_HIGH>,
+ <0 172 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7740_CLK_TMU1>;
+ clock-names = "fck";
+ power-domains = <&pd_a4r>;
+
+ #renesas,channels = <3>;
+
+ status = "disabled";
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /* External root clock */
+ extalr_clk: extalr_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "extalr";
+ };
+ extal1_clk: extal1_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "extal1";
+ };
+ extal2_clk: extal2_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "extal2";
+ };
+ dv_clk: dv_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <27000000>;
+ clock-output-names = "dv";
+ };
+ fmsick_clk: fmsick_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "fmsick";
+ };
+ fmsock_clk: fmsock_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "fmsock";
+ };
+ fsiack_clk: fsiack_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "fsiack";
+ };
+ fsibck_clk: fsibck_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "fsibck";
+ };
+
+ /* Special CPG clocks */
+ cpg_clocks: cpg_clocks@e6150000 {
+ compatible = "renesas,r8a7740-cpg-clocks";
+ reg = <0xe6150000 0x10000>;
+ clocks = <&extal1_clk>, <&extalr_clk>;
+ #clock-cells = <1>;
+ clock-output-names = "system", "pllc0", "pllc1",
+ "pllc2", "r",
+ "usb24s",
+ "i", "zg", "b", "m1", "hp",
+ "hpp", "usbp", "s", "zb", "m3",
+ "cp";
+ };
+
+ /* Variable factor clocks (DIV6) */
+ vclk1_clk: vclk1_clk@e6150008 {
+ compatible = "renesas,r8a7740-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150008 4>;
+ clocks = <&pllc1_div2_clk>, <0>, <&dv_clk>,
+ <&cpg_clocks R8A7740_CLK_USB24S>,
+ <&extal1_div2_clk>, <&extalr_clk>, <0>,
+ <0>;
+ #clock-cells = <0>;
+ clock-output-names = "vclk1";
+ };
+ vclk2_clk: vclk2_clk@e615000c {
+ compatible = "renesas,r8a7740-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe615000c 4>;
+ clocks = <&pllc1_div2_clk>, <0>, <&dv_clk>,
+ <&cpg_clocks R8A7740_CLK_USB24S>,
+ <&extal1_div2_clk>, <&extalr_clk>, <0>,
+ <0>;
+ #clock-cells = <0>;
+ clock-output-names = "vclk2";
+ };
+ fmsi_clk: fmsi_clk@e6150010 {
+ compatible = "renesas,r8a7740-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150010 4>;
+ clocks = <&pllc1_div2_clk>, <&fmsick_clk>, <0>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "fmsi";
+ };
+ fmso_clk: fmso_clk@e6150014 {
+ compatible = "renesas,r8a7740-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150014 4>;
+ clocks = <&pllc1_div2_clk>, <&fmsock_clk>, <0>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "fmso";
+ };
+ fsia_clk: fsia_clk@e6150018 {
+ compatible = "renesas,r8a7740-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150018 4>;
+ clocks = <&pllc1_div2_clk>, <&fsiack_clk>, <0>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "fsia";
+ };
+ sub_clk: sub_clk@e6150080 {
+ compatible = "renesas,r8a7740-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150080 4>;
+ clocks = <&pllc1_div2_clk>,
+ <&cpg_clocks R8A7740_CLK_USB24S>, <0>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "sub";
+ };
+ spu_clk: spu_clk@e6150084 {
+ compatible = "renesas,r8a7740-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150084 4>;
+ clocks = <&pllc1_div2_clk>,
+ <&cpg_clocks R8A7740_CLK_USB24S>, <0>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "spu";
+ };
+ vou_clk: vou_clk@e6150088 {
+ compatible = "renesas,r8a7740-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150088 4>;
+ clocks = <&pllc1_div2_clk>, <&extal1_clk>, <&dv_clk>,
+ <0>;
+ #clock-cells = <0>;
+ clock-output-names = "vou";
+ };
+ stpro_clk: stpro_clk@e615009c {
+ compatible = "renesas,r8a7740-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe615009c 4>;
+ clocks = <&cpg_clocks R8A7740_CLK_PLLC0>;
+ #clock-cells = <0>;
+ clock-output-names = "stpro";
+ };
+
+ /* Fixed factor clocks */
+ pllc1_div2_clk: pllc1_div2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7740_CLK_PLLC1>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "pllc1_div2";
+ };
+ extal1_div2_clk: extal1_div2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&extal1_clk>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "extal1_div2";
+ };
+
+ /* Gate clocks */
+ subck_clks: subck_clks@e6150080 {
+ compatible = "renesas,r8a7740-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xe6150080 4>;
+ clocks = <&sub_clk>, <&sub_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7740_CLK_SUBCK R8A7740_CLK_SUBCK2
+ >;
+ clock-output-names =
+ "subck", "subck2";
+ };
+ mstp1_clks: mstp1_clks@e6150134 {
+ compatible = "renesas,r8a7740-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xe6150134 4>, <0xe6150038 4>;
+ clocks = <&cpg_clocks R8A7740_CLK_S>,
+ <&cpg_clocks R8A7740_CLK_S>, <&sub_clk>,
+ <&cpg_clocks R8A7740_CLK_B>,
+ <&cpg_clocks R8A7740_CLK_HPP>, <&sub_clk>,
+ <&cpg_clocks R8A7740_CLK_B>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7740_CLK_CEU21 R8A7740_CLK_CEU20 R8A7740_CLK_TMU0
+ R8A7740_CLK_LCDC1 R8A7740_CLK_IIC0 R8A7740_CLK_TMU1
+ R8A7740_CLK_LCDC0
+ >;
+ clock-output-names =
+ "ceu21", "ceu20", "tmu0", "lcdc1", "iic0",
+ "tmu1", "lcdc0";
+ };
+ mstp2_clks: mstp2_clks@e6150138 {
+ compatible = "renesas,r8a7740-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xe6150138 4>, <0xe6150040 4>;
+ clocks = <&sub_clk>, <&cpg_clocks R8A7740_CLK_HP>,
+ <&sub_clk>, <&cpg_clocks R8A7740_CLK_HP>,
+ <&cpg_clocks R8A7740_CLK_HP>,
+ <&cpg_clocks R8A7740_CLK_HP>,
+ <&cpg_clocks R8A7740_CLK_HP>,
+ <&sub_clk>, <&sub_clk>, <&sub_clk>,
+ <&sub_clk>, <&sub_clk>, <&sub_clk>,
+ <&sub_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7740_CLK_SCIFA6 R8A7740_CLK_INTCA
+ R8A7740_CLK_SCIFA7
+ R8A7740_CLK_DMAC1 R8A7740_CLK_DMAC2
+ R8A7740_CLK_DMAC3 R8A7740_CLK_USBDMAC
+ R8A7740_CLK_SCIFA5 R8A7740_CLK_SCIFB
+ R8A7740_CLK_SCIFA0 R8A7740_CLK_SCIFA1
+ R8A7740_CLK_SCIFA2 R8A7740_CLK_SCIFA3
+ R8A7740_CLK_SCIFA4
+ >;
+ clock-output-names =
+ "scifa6", "intca",
+ "scifa7", "dmac1", "dmac2", "dmac3",
+ "usbdmac", "scifa5", "scifb", "scifa0", "scifa1",
+ "scifa2", "scifa3", "scifa4";
+ };
+ mstp3_clks: mstp3_clks@e615013c {
+ compatible = "renesas,r8a7740-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xe615013c 4>, <0xe6150048 4>;
+ clocks = <&cpg_clocks R8A7740_CLK_R>,
+ <&cpg_clocks R8A7740_CLK_HP>,
+ <&sub_clk>,
+ <&cpg_clocks R8A7740_CLK_HP>,
+ <&cpg_clocks R8A7740_CLK_HP>,
+ <&cpg_clocks R8A7740_CLK_HP>,
+ <&cpg_clocks R8A7740_CLK_HP>,
+ <&cpg_clocks R8A7740_CLK_HP>,
+ <&cpg_clocks R8A7740_CLK_HP>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7740_CLK_CMT1 R8A7740_CLK_FSI R8A7740_CLK_IIC1
+ R8A7740_CLK_USBF R8A7740_CLK_SDHI0 R8A7740_CLK_SDHI1
+ R8A7740_CLK_MMC R8A7740_CLK_GETHER R8A7740_CLK_TPU0
+ >;
+ clock-output-names =
+ "cmt1", "fsi", "iic1", "usbf", "sdhi0", "sdhi1",
+ "mmc", "gether", "tpu0";
+ };
+ mstp4_clks: mstp4_clks@e6150140 {
+ compatible = "renesas,r8a7740-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xe6150140 4>, <0xe615004c 4>;
+ clocks = <&cpg_clocks R8A7740_CLK_HP>,
+ <&cpg_clocks R8A7740_CLK_HP>,
+ <&cpg_clocks R8A7740_CLK_HP>,
+ <&cpg_clocks R8A7740_CLK_HP>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7740_CLK_USBH R8A7740_CLK_SDHI2
+ R8A7740_CLK_USBFUNC R8A7740_CLK_USBPHY
+ >;
+ clock-output-names =
+ "usbhost", "sdhi2", "usbfunc", "usphy";
+ };
+ };
+
+ sysc: system-controller@e6180000 {
+ compatible = "renesas,sysc-r8a7740", "renesas,sysc-rmobile";
+ reg = <0xe6180000 0x8000>, <0xe6188000 0x8000>;
+
+ pm-domains {
+ pd_c5: c5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a4lc: a4lc@1 {
+ reg = <1>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a4mp: a4mp@2 {
+ reg = <2>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_d4: d4@3 {
+ reg = <3>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a4r: a4r@5 {
+ reg = <5>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a3rv: a3rv@6 {
+ reg = <6>;
+ #power-domain-cells = <0>;
+ };
+ };
+
+ pd_a4s: a4s@10 {
+ reg = <10>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a3sp: a3sp@11 {
+ reg = <11>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a3sm: a3sm@12 {
+ reg = <12>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a3sg: a3sg@13 {
+ reg = <13>;
+ #power-domain-cells = <0>;
+ };
+ };
+
+ pd_a4su: a4su@20 {
+ reg = <20>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/r8a7778-bockw-reference.dts b/arch/arm/boot/dts/r8a7778-bockw-reference.dts
new file mode 100644
index 000000000..04c0c37bb
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7778-bockw-reference.dts
@@ -0,0 +1,139 @@
+/*
+ * Reference Device Tree Source for the Bock-W board
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * based on r8a7779
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 Simon Horman
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "r8a7778.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "bockw";
+ compatible = "renesas,bockw-reference", "renesas,r8a7778";
+
+ aliases {
+ serial0 = &scif0;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel root=/dev/nfs ip=dhcp rw";
+ stdout-path = &scif0;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x60000000 0x10000000>;
+ };
+
+ fixedregulator3v3: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ethernet@18300000 {
+ compatible = "smsc,lan9220", "smsc,lan9115";
+ reg = <0x18300000 0x1000>;
+
+ phy-mode = "mii";
+ interrupt-parent = <&irqpin>;
+ interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+ reg-io-width = <4>;
+ vddvario-supply = <&fixedregulator3v3>;
+ vdd33a-supply = <&fixedregulator3v3>;
+ };
+
+};
+
+&mmcif {
+ pinctrl-0 = <&mmc_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&fixedregulator3v3>;
+ bus-width = <8>;
+ broken-cd;
+ status = "okay";
+};
+
+&irqpin {
+ status = "okay";
+};
+
+&tmu0 {
+ status = "okay";
+};
+
+&pfc {
+ scif0_pins: serial0 {
+ renesas,groups = "scif0_data_a", "scif0_ctrl";
+ renesas,function = "scif0";
+ };
+
+ mmc_pins: mmc {
+ renesas,groups = "mmc_data8", "mmc_ctrl";
+ renesas,function = "mmc";
+ };
+
+ sdhi0_pins: sd0 {
+ renesas,groups = "sdhi0_data4", "sdhi0_ctrl",
+ "sdhi0_cd";
+ renesas,function = "sdhi0";
+ };
+
+ hspi0_pins: hspi0 {
+ renesas,groups = "hspi0_a";
+ renesas,function = "hspi0";
+ };
+};
+
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&fixedregulator3v3>;
+ bus-width = <4>;
+ status = "okay";
+ wp-gpios = <&gpio3 18 GPIO_ACTIVE_HIGH>;
+};
+
+&hspi0 {
+ pinctrl-0 = <&hspi0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ flash: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25fl008k";
+ reg = <0>;
+ spi-max-frequency = <104000000>;
+ m25p,fast-read;
+
+ partition@0 {
+ label = "data(spi)";
+ reg = <0x00000000 0x00100000>;
+ };
+ };
+};
+
+&scif0 {
+ pinctrl-0 = <&scif0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/r8a7778-bockw.dts b/arch/arm/boot/dts/r8a7778-bockw.dts
new file mode 100644
index 000000000..787fa6f9f
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7778-bockw.dts
@@ -0,0 +1,206 @@
+/*
+ * Reference Device Tree Source for the Bock-W board
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * based on r8a7779
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 Simon Horman
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "r8a7778.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "bockw";
+ compatible = "renesas,bockw", "renesas,r8a7778";
+
+ aliases {
+ serial0 = &scif0;
+ };
+
+ chosen {
+ bootargs = "console=ttySC0,115200 ignore_loglevel ip=dhcp root=/dev/nfs rw";
+ stdout-path = &scif0;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x60000000 0x10000000>;
+ };
+
+ fixedregulator3v3: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+
+ simple-audio-card,format = "left_j";
+ simple-audio-card,bitclock-master = <&sndcodec>;
+ simple-audio-card,frame-master = <&sndcodec>;
+
+ sndcpu: simple-audio-card,cpu {
+ sound-dai = <&rcar_sound>;
+ };
+
+ sndcodec: simple-audio-card,codec {
+ sound-dai = <&ak4643>;
+ system-clock-frequency = <11289600>;
+ };
+ };
+};
+
+&bsc {
+ ethernet@18300000 {
+ compatible = "smsc,lan9220", "smsc,lan9115";
+ reg = <0x18300000 0x1000>;
+
+ phy-mode = "mii";
+ interrupt-parent = <&irqpin>;
+ interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+ reg-io-width = <4>;
+ vddvario-supply = <&fixedregulator3v3>;
+ vdd33a-supply = <&fixedregulator3v3>;
+ };
+};
+
+&extal_clk {
+ clock-frequency = <33333333>;
+};
+
+&i2c0 {
+ status = "okay";
+
+ ak4643: sound-codec@12 {
+ compatible = "asahi-kasei,ak4643";
+ #sound-dai-cells = <0>;
+ reg = <0x12>;
+ };
+
+ camera@41 {
+ compatible = "oki,ml86v7667";
+ reg = <0x41>;
+ };
+
+ camera@43 {
+ compatible = "oki,ml86v7667";
+ reg = <0x43>;
+ };
+
+ rx8581: rtc@51 {
+ compatible = "epson,rx8581";
+ reg = <0x51>;
+ };
+};
+
+&mmcif {
+ pinctrl-0 = <&mmc_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&fixedregulator3v3>;
+ bus-width = <8>;
+ broken-cd;
+ status = "okay";
+};
+
+&irqpin {
+ status = "okay";
+};
+
+&tmu0 {
+ status = "okay";
+};
+
+&pfc {
+ scif0_pins: serial0 {
+ renesas,groups = "scif0_data_a", "scif0_ctrl";
+ renesas,function = "scif0";
+ };
+
+ mmc_pins: mmc {
+ renesas,groups = "mmc_data8", "mmc_ctrl";
+ renesas,function = "mmc";
+ };
+
+ sdhi0_pins: sd0 {
+ renesas,groups = "sdhi0_data4", "sdhi0_ctrl",
+ "sdhi0_cd";
+ renesas,function = "sdhi0";
+ };
+
+ hspi0_pins: hspi0 {
+ renesas,groups = "hspi0_a";
+ renesas,function = "hspi0";
+ };
+
+ usb0_pins: usb0 {
+ renesas,groups = "usb0";
+ renesas,function = "usb0";
+ };
+
+ usb1_pins: usb1 {
+ renesas,groups = "usb1";
+ renesas,function = "usb1";
+ };
+
+ vin0_pins: vin0 {
+ renesas,groups = "vin0_data8", "vin0_clk";
+ renesas,function = "vin0";
+ };
+
+ vin1_pins: vin1 {
+ renesas,groups = "vin1_data8", "vin1_clk";
+ renesas,function = "vin1";
+ };
+};
+
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&fixedregulator3v3>;
+ bus-width = <4>;
+ status = "okay";
+ wp-gpios = <&gpio3 18 GPIO_ACTIVE_HIGH>;
+};
+
+&hspi0 {
+ pinctrl-0 = <&hspi0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ flash: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25fl008k";
+ reg = <0>;
+ spi-max-frequency = <104000000>;
+ m25p,fast-read;
+
+ partition@0 {
+ label = "data(spi)";
+ reg = <0x00000000 0x00100000>;
+ };
+ };
+};
+
+&scif0 {
+ pinctrl-0 = <&scif0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi
new file mode 100644
index 000000000..868f97309
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7778.dtsi
@@ -0,0 +1,590 @@
+/*
+ * Device Tree Source for Renesas r8a7778
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * based on r8a7779
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 Simon Horman
+ *
+ * This file is licensed under the terms 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/ "skeleton.dtsi"
+
+#include <dt-bindings/clock/r8a7778-clock.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "renesas,r8a7778";
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ clock-frequency = <800000000>;
+ };
+ };
+
+ aliases {
+ spi0 = &hspi0;
+ spi1 = &hspi1;
+ spi2 = &hspi2;
+ };
+
+ bsc: bus@1c000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0x1c000000>;
+ };
+
+ ether: ethernet@fde00000 {
+ compatible = "renesas,ether-r8a7778";
+ reg = <0xfde00000 0x400>;
+ interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7778_CLK_ETHER>;
+ phy-mode = "rmii";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@fe438000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0xfe438000 0x1000>,
+ <0xfe430000 0x100>;
+ };
+
+ /* irqpin: IRQ0 - IRQ3 */
+ irqpin: irqpin@fe78001c {
+ compatible = "renesas,intc-irqpin-r8a7778", "renesas,intc-irqpin";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ status = "disabled"; /* default off */
+ reg = <0xfe78001c 4>,
+ <0xfe780010 4>,
+ <0xfe780024 4>,
+ <0xfe780044 4>,
+ <0xfe780064 4>;
+ interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH
+ 0 28 IRQ_TYPE_LEVEL_HIGH
+ 0 29 IRQ_TYPE_LEVEL_HIGH
+ 0 30 IRQ_TYPE_LEVEL_HIGH>;
+ sense-bitfield-width = <2>;
+ };
+
+ gpio0: gpio@ffc40000 {
+ compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar";
+ reg = <0xffc40000 0x2c>;
+ interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 0 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio1: gpio@ffc41000 {
+ compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar";
+ reg = <0xffc41000 0x2c>;
+ interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 32 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio2: gpio@ffc42000 {
+ compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar";
+ reg = <0xffc42000 0x2c>;
+ interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 64 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio3: gpio@ffc43000 {
+ compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar";
+ reg = <0xffc43000 0x2c>;
+ interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 96 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio4: gpio@ffc44000 {
+ compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar";
+ reg = <0xffc44000 0x2c>;
+ interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 128 27>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ pfc: pfc@fffc0000 {
+ compatible = "renesas,pfc-r8a7778";
+ reg = <0xfffc0000 0x118>;
+ };
+
+ i2c0: i2c@ffc70000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7778";
+ reg = <0xffc70000 0x1000>;
+ interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7778_CLK_I2C0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@ffc71000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7778";
+ reg = <0xffc71000 0x1000>;
+ interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7778_CLK_I2C1>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@ffc72000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7778";
+ reg = <0xffc72000 0x1000>;
+ interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7778_CLK_I2C2>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@ffc73000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7778";
+ reg = <0xffc73000 0x1000>;
+ interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7778_CLK_I2C3>;
+ status = "disabled";
+ };
+
+ tmu0: timer@ffd80000 {
+ compatible = "renesas,tmu-r8a7778", "renesas,tmu";
+ reg = <0xffd80000 0x30>;
+ interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>,
+ <0 33 IRQ_TYPE_LEVEL_HIGH>,
+ <0 34 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7778_CLK_TMU0>;
+ clock-names = "fck";
+
+ #renesas,channels = <3>;
+
+ status = "disabled";
+ };
+
+ tmu1: timer@ffd81000 {
+ compatible = "renesas,tmu-r8a7778", "renesas,tmu";
+ reg = <0xffd81000 0x30>;
+ interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>,
+ <0 37 IRQ_TYPE_LEVEL_HIGH>,
+ <0 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7778_CLK_TMU1>;
+ clock-names = "fck";
+
+ #renesas,channels = <3>;
+
+ status = "disabled";
+ };
+
+ tmu2: timer@ffd82000 {
+ compatible = "renesas,tmu-r8a7778", "renesas,tmu";
+ reg = <0xffd82000 0x30>;
+ interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>,
+ <0 41 IRQ_TYPE_LEVEL_HIGH>,
+ <0 42 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7778_CLK_TMU2>;
+ clock-names = "fck";
+
+ #renesas,channels = <3>;
+
+ status = "disabled";
+ };
+
+ rcar_sound: sound@ffd90000 {
+ #sound-dai-cells = <1>;
+ compatible = "renesas,rcar_sound-r8a7778", "renesas,rcar_sound-gen1";
+ reg = <0xffd90000 0x1000>, /* SRU */
+ <0xffd91000 0x1240>, /* SSI */
+ <0xfffe0000 0x24>; /* ADG */
+ clocks = <&mstp3_clks R8A7778_CLK_SSI8>,
+ <&mstp3_clks R8A7778_CLK_SSI7>,
+ <&mstp3_clks R8A7778_CLK_SSI6>,
+ <&mstp3_clks R8A7778_CLK_SSI5>,
+ <&mstp3_clks R8A7778_CLK_SSI4>,
+ <&mstp0_clks R8A7778_CLK_SSI3>,
+ <&mstp0_clks R8A7778_CLK_SSI2>,
+ <&mstp0_clks R8A7778_CLK_SSI1>,
+ <&mstp0_clks R8A7778_CLK_SSI0>,
+ <&mstp5_clks R8A7778_CLK_SRU_SRC8>,
+ <&mstp5_clks R8A7778_CLK_SRU_SRC7>,
+ <&mstp5_clks R8A7778_CLK_SRU_SRC6>,
+ <&mstp5_clks R8A7778_CLK_SRU_SRC5>,
+ <&mstp5_clks R8A7778_CLK_SRU_SRC4>,
+ <&mstp5_clks R8A7778_CLK_SRU_SRC3>,
+ <&mstp5_clks R8A7778_CLK_SRU_SRC2>,
+ <&mstp5_clks R8A7778_CLK_SRU_SRC1>,
+ <&mstp5_clks R8A7778_CLK_SRU_SRC0>,
+ <&audio_clk_a>, <&audio_clk_b>, <&audio_clk_c>,
+ <&cpg_clocks R8A7778_CLK_S1>;
+ clock-names = "ssi.8", "ssi.7", "ssi.6", "ssi.5", "ssi.4",
+ "ssi.3", "ssi.2", "ssi.1", "ssi.0",
+ "src.8", "src.7", "src.6", "src.5", "src.4",
+ "src.3", "src.2", "src.1", "src.0",
+ "clk_a", "clk_b", "clk_c", "clk_i";
+
+ status = "disabled";
+
+ rcar_sound,src {
+ src3: src@3 { };
+ src4: src@4 { };
+ src5: src@5 { };
+ src6: src@6 { };
+ src7: src@7 { };
+ src8: src@8 { };
+ src9: src@9 { };
+ };
+
+ rcar_sound,ssi {
+ ssi3: ssi@3 { interrupts = <0 0x85 IRQ_TYPE_LEVEL_HIGH>; };
+ ssi4: ssi@4 { interrupts = <0 0x85 IRQ_TYPE_LEVEL_HIGH>; };
+ ssi5: ssi@5 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; };
+ ssi6: ssi@6 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; };
+ ssi7: ssi@7 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; };
+ ssi8: ssi@8 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; };
+ ssi9: ssi@9 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; };
+ };
+ };
+
+ scif0: serial@ffe40000 {
+ compatible = "renesas,scif-r8a7778", "renesas,scif";
+ reg = <0xffe40000 0x100>;
+ interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7778_CLK_SCIF0>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif1: serial@ffe41000 {
+ compatible = "renesas,scif-r8a7778", "renesas,scif";
+ reg = <0xffe41000 0x100>;
+ interrupts = <0 71 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7778_CLK_SCIF1>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif2: serial@ffe42000 {
+ compatible = "renesas,scif-r8a7778", "renesas,scif";
+ reg = <0xffe42000 0x100>;
+ interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7778_CLK_SCIF2>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif3: serial@ffe43000 {
+ compatible = "renesas,scif-r8a7778", "renesas,scif";
+ reg = <0xffe43000 0x100>;
+ interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7778_CLK_SCIF3>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif4: serial@ffe44000 {
+ compatible = "renesas,scif-r8a7778", "renesas,scif";
+ reg = <0xffe44000 0x100>;
+ interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7778_CLK_SCIF4>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif5: serial@ffe45000 {
+ compatible = "renesas,scif-r8a7778", "renesas,scif";
+ reg = <0xffe45000 0x100>;
+ interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7778_CLK_SCIF5>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ mmcif: mmc@ffe4e000 {
+ compatible = "renesas,sh-mmcif";
+ reg = <0xffe4e000 0x100>;
+ interrupts = <0 61 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7778_CLK_MMC>;
+ status = "disabled";
+ };
+
+ sdhi0: sd@ffe4c000 {
+ compatible = "renesas,sdhi-r8a7778";
+ reg = <0xffe4c000 0x100>;
+ interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7778_CLK_SDHI0>;
+ status = "disabled";
+ };
+
+ sdhi1: sd@ffe4d000 {
+ compatible = "renesas,sdhi-r8a7778";
+ reg = <0xffe4d000 0x100>;
+ interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7778_CLK_SDHI1>;
+ status = "disabled";
+ };
+
+ sdhi2: sd@ffe4f000 {
+ compatible = "renesas,sdhi-r8a7778";
+ reg = <0xffe4f000 0x100>;
+ interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7778_CLK_SDHI2>;
+ status = "disabled";
+ };
+
+ hspi0: spi@fffc7000 {
+ compatible = "renesas,hspi-r8a7778", "renesas,hspi";
+ reg = <0xfffc7000 0x18>;
+ interrupts = <0 63 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7778_CLK_HSPI>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ hspi1: spi@fffc8000 {
+ compatible = "renesas,hspi-r8a7778", "renesas,hspi";
+ reg = <0xfffc8000 0x18>;
+ interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7778_CLK_HSPI>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ hspi2: spi@fffc6000 {
+ compatible = "renesas,hspi-r8a7778", "renesas,hspi";
+ reg = <0xfffc6000 0x18>;
+ interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7778_CLK_HSPI>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /* External input clock */
+ extal_clk: extal_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "extal";
+ };
+
+ /* Special CPG clocks */
+ cpg_clocks: cpg_clocks@ffc80000 {
+ compatible = "renesas,r8a7778-cpg-clocks";
+ reg = <0xffc80000 0x80>;
+ #clock-cells = <1>;
+ clocks = <&extal_clk>;
+ clock-output-names = "plla", "pllb", "b",
+ "out", "p", "s", "s1";
+ };
+
+ /* Audio clocks; frequencies are set by boards if applicable. */
+ audio_clk_a: audio_clk_a {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-output-names = "audio_clk_a";
+ };
+ audio_clk_b: audio_clk_b {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-output-names = "audio_clk_b";
+ };
+ audio_clk_c: audio_clk_c {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-output-names = "audio_clk_c";
+ };
+
+ /* Fixed ratio clocks */
+ g_clk: g_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7778_CLK_PLLA>;
+ #clock-cells = <0>;
+ clock-div = <12>;
+ clock-mult = <1>;
+ clock-output-names = "g";
+ };
+ i_clk: i_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7778_CLK_PLLA>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ clock-output-names = "i";
+ };
+ s3_clk: s3_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7778_CLK_PLLA>;
+ #clock-cells = <0>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clock-output-names = "s3";
+ };
+ s4_clk: s4_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7778_CLK_PLLA>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "s4";
+ };
+ z_clk: z_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7778_CLK_PLLB>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ clock-output-names = "z";
+ };
+
+ /* Gate clocks */
+ mstp0_clks: mstp0_clks@ffc80030 {
+ compatible = "renesas,r8a7778-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xffc80030 4>;
+ clocks = <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_S>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7778_CLK_I2C0 R8A7778_CLK_I2C1
+ R8A7778_CLK_I2C2 R8A7778_CLK_I2C3
+ R8A7778_CLK_SCIF0 R8A7778_CLK_SCIF1
+ R8A7778_CLK_SCIF2 R8A7778_CLK_SCIF3
+ R8A7778_CLK_SCIF4 R8A7778_CLK_SCIF5
+ R8A7778_CLK_TMU0 R8A7778_CLK_TMU1
+ R8A7778_CLK_TMU2 R8A7778_CLK_SSI0
+ R8A7778_CLK_SSI1 R8A7778_CLK_SSI2
+ R8A7778_CLK_SSI3 R8A7778_CLK_SRU
+ R8A7778_CLK_HSPI
+ >;
+ clock-output-names =
+ "i2c0", "i2c1", "i2c2", "i2c3", "scif0",
+ "scif1", "scif2", "scif3", "scif4", "scif5",
+ "tmu0", "tmu1", "tmu2", "ssi0", "ssi1",
+ "ssi2", "ssi3", "sru", "hspi";
+ };
+ mstp1_clks: mstp1_clks@ffc80034 {
+ compatible = "renesas,r8a7778-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xffc80034 4>, <0xffc80044 4>;
+ clocks = <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_S>,
+ <&cpg_clocks R8A7778_CLK_S>,
+ <&cpg_clocks R8A7778_CLK_P>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7778_CLK_ETHER R8A7778_CLK_VIN0
+ R8A7778_CLK_VIN1 R8A7778_CLK_USB
+ >;
+ clock-output-names =
+ "ether", "vin0", "vin1", "usb";
+ };
+ mstp3_clks: mstp3_clks@ffc8003c {
+ compatible = "renesas,r8a7778-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xffc8003c 4>;
+ clocks = <&s4_clk>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7778_CLK_MMC R8A7778_CLK_SDHI0
+ R8A7778_CLK_SDHI1 R8A7778_CLK_SDHI2
+ R8A7778_CLK_SSI4 R8A7778_CLK_SSI5
+ R8A7778_CLK_SSI6 R8A7778_CLK_SSI7
+ R8A7778_CLK_SSI8
+ >;
+ clock-output-names =
+ "mmc", "sdhi0", "sdhi1", "sdhi2", "ssi4",
+ "ssi5", "ssi6", "ssi7", "ssi8";
+ };
+ mstp5_clks: mstp5_clks@ffc80054 {
+ compatible = "renesas,r8a7778-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xffc80054 4>;
+ clocks = <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>,
+ <&cpg_clocks R8A7778_CLK_P>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7778_CLK_SRU_SRC0 R8A7778_CLK_SRU_SRC1
+ R8A7778_CLK_SRU_SRC2 R8A7778_CLK_SRU_SRC3
+ R8A7778_CLK_SRU_SRC4 R8A7778_CLK_SRU_SRC5
+ R8A7778_CLK_SRU_SRC6 R8A7778_CLK_SRU_SRC7
+ R8A7778_CLK_SRU_SRC8
+ >;
+ clock-output-names =
+ "sru-src0", "sru-src1", "sru-src2",
+ "sru-src3", "sru-src4", "sru-src5",
+ "sru-src6", "sru-src7", "sru-src8";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/r8a7779-marzen.dts b/arch/arm/boot/dts/r8a7779-marzen.dts
new file mode 100644
index 000000000..540756cdf
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7779-marzen.dts
@@ -0,0 +1,238 @@
+/*
+ * Device Tree Source for the Marzen board
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 Simon Horman
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "r8a7779.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ model = "marzen";
+ compatible = "renesas,marzen", "renesas,r8a7779";
+
+ aliases {
+ serial2 = &scif2;
+ serial4 = &scif4;
+ };
+
+ chosen {
+ bootargs = "console=ttySC2,115200 ignore_loglevel root=/dev/nfs ip=on";
+ stdout-path = &scif2;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x60000000 0x40000000>;
+ };
+
+ fixedregulator3v3: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ lan0@18000000 {
+ compatible = "smsc,lan9220", "smsc,lan9115";
+ reg = <0x18000000 0x100>;
+ pinctrl-0 = <&lan0_pins>;
+ pinctrl-names = "default";
+
+ phy-mode = "mii";
+ interrupt-parent = <&irqpin0>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+ smsc,irq-push-pull;
+ reg-io-width = <4>;
+ vddvario-supply = <&fixedregulator3v3>;
+ vdd33a-supply = <&fixedregulator3v3>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ led2 {
+ gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+ };
+ led3 {
+ gpios = <&gpio4 30 GPIO_ACTIVE_HIGH>;
+ };
+ led4 {
+ gpios = <&gpio4 31 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ vga-encoder {
+ compatible = "adi,adv7123";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ vga_enc_in: endpoint {
+ remote-endpoint = <&du_out_rgb0>;
+ };
+ };
+ port@1 {
+ reg = <1>;
+ vga_enc_out: endpoint {
+ remote-endpoint = <&vga_in>;
+ };
+ };
+ };
+ };
+
+ vga {
+ compatible = "vga-connector";
+
+ port {
+ vga_in: endpoint {
+ remote-endpoint = <&vga_enc_out>;
+ };
+ };
+ };
+
+ lvds-encoder {
+ compatible = "thine,thc63lvdm83d";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ lvds_enc_in: endpoint {
+ remote-endpoint = <&du_out_rgb1>;
+ };
+ };
+ port@1 {
+ reg = <1>;
+ lvds_connector: endpoint {
+ };
+ };
+ };
+ };
+
+ x3_clk: x3-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <65000000>;
+ };
+};
+
+&du {
+ pinctrl-0 = <&du_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ clocks = <&mstp1_clks R8A7779_CLK_DU>, <&x3_clk>;
+ clock-names = "du", "dclkin.0";
+
+ ports {
+ port@0 {
+ endpoint {
+ remote-endpoint = <&vga_enc_in>;
+ };
+ };
+ port@1 {
+ endpoint {
+ remote-endpoint = <&lvds_enc_in>;
+ };
+ };
+ };
+};
+
+&irqpin0 {
+ status = "okay";
+};
+
+&extal_clk {
+ clock-frequency = <31250000>;
+};
+
+&tmu0 {
+ status = "okay";
+};
+
+&pfc {
+ du_pins: du {
+ du0 {
+ renesas,groups = "du0_rgb888", "du0_sync_1", "du0_clk_out_0";
+ renesas,function = "du0";
+ };
+ du1 {
+ renesas,groups = "du1_rgb666", "du1_sync_1", "du1_clk_out";
+ renesas,function = "du1";
+ };
+ };
+
+ lan0_pins: lan0 {
+ intc {
+ renesas,groups = "intc_irq1_b";
+ renesas,function = "intc";
+ };
+ lbsc {
+ renesas,groups = "lbsc_ex_cs0";
+ renesas,function = "lbsc";
+ };
+ };
+
+ scif2_pins: serial2 {
+ renesas,groups = "scif2_data_c";
+ renesas,function = "scif2";
+ };
+
+ scif4_pins: serial4 {
+ renesas,groups = "scif4_data";
+ renesas,function = "scif4";
+ };
+
+ sdhi0_pins: sd0 {
+ renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd";
+ renesas,function = "sdhi0";
+ };
+
+ hspi0_pins: hspi0 {
+ renesas,groups = "hspi0";
+ renesas,function = "hspi0";
+ };
+};
+
+&scif2 {
+ pinctrl-0 = <&scif2_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&scif4 {
+ pinctrl-0 = <&scif4_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&fixedregulator3v3>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&hspi0 {
+ pinctrl-0 = <&hspi0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi
new file mode 100644
index 000000000..5c2219b9f
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7779.dtsi
@@ -0,0 +1,549 @@
+/*
+ * Device Tree Source for Renesas r8a7779
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 Simon Horman
+ *
+ * This file is licensed under the terms 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/ "skeleton.dtsi"
+
+#include <dt-bindings/clock/r8a7779-clock.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "renesas,r8a7779";
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ clock-frequency = <1000000000>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ clock-frequency = <1000000000>;
+ };
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <2>;
+ clock-frequency = <1000000000>;
+ };
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <3>;
+ clock-frequency = <1000000000>;
+ };
+ };
+
+ aliases {
+ spi0 = &hspi0;
+ spi1 = &hspi1;
+ spi2 = &hspi2;
+ };
+
+ gic: interrupt-controller@f0001000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0xf0001000 0x1000>,
+ <0xf0000100 0x100>;
+ };
+
+ timer@f0000600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xf0000600 0x20>;
+ interrupts = <GIC_PPI 13
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ clocks = <&cpg_clocks R8A7779_CLK_ZS>;
+ };
+
+ gpio0: gpio@ffc40000 {
+ compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
+ reg = <0xffc40000 0x2c>;
+ interrupts = <0 141 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 0 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio1: gpio@ffc41000 {
+ compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
+ reg = <0xffc41000 0x2c>;
+ interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 32 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio2: gpio@ffc42000 {
+ compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
+ reg = <0xffc42000 0x2c>;
+ interrupts = <0 143 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 64 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio3: gpio@ffc43000 {
+ compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
+ reg = <0xffc43000 0x2c>;
+ interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 96 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio4: gpio@ffc44000 {
+ compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
+ reg = <0xffc44000 0x2c>;
+ interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 128 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio5: gpio@ffc45000 {
+ compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
+ reg = <0xffc45000 0x2c>;
+ interrupts = <0 146 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 160 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio6: gpio@ffc46000 {
+ compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
+ reg = <0xffc46000 0x2c>;
+ interrupts = <0 147 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 192 9>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ irqpin0: irqpin@fe780010 {
+ compatible = "renesas,intc-irqpin-r8a7779", "renesas,intc-irqpin";
+ #interrupt-cells = <2>;
+ status = "disabled";
+ interrupt-controller;
+ reg = <0xfe78001c 4>,
+ <0xfe780010 4>,
+ <0xfe780024 4>,
+ <0xfe780044 4>,
+ <0xfe780064 4>;
+ interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH
+ 0 28 IRQ_TYPE_LEVEL_HIGH
+ 0 29 IRQ_TYPE_LEVEL_HIGH
+ 0 30 IRQ_TYPE_LEVEL_HIGH>;
+ sense-bitfield-width = <2>;
+ };
+
+ i2c0: i2c@ffc70000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7779";
+ reg = <0xffc70000 0x1000>;
+ interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7779_CLK_I2C0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@ffc71000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7779";
+ reg = <0xffc71000 0x1000>;
+ interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7779_CLK_I2C1>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@ffc72000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7779";
+ reg = <0xffc72000 0x1000>;
+ interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7779_CLK_I2C2>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@ffc73000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7779";
+ reg = <0xffc73000 0x1000>;
+ interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7779_CLK_I2C3>;
+ status = "disabled";
+ };
+
+ scif0: serial@ffe40000 {
+ compatible = "renesas,scif-r8a7779", "renesas,scif";
+ reg = <0xffe40000 0x100>;
+ interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7779_CLK_SCIF0>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif1: serial@ffe41000 {
+ compatible = "renesas,scif-r8a7779", "renesas,scif";
+ reg = <0xffe41000 0x100>;
+ interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7779_CLK_SCIF1>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif2: serial@ffe42000 {
+ compatible = "renesas,scif-r8a7779", "renesas,scif";
+ reg = <0xffe42000 0x100>;
+ interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7779_CLK_SCIF2>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif3: serial@ffe43000 {
+ compatible = "renesas,scif-r8a7779", "renesas,scif";
+ reg = <0xffe43000 0x100>;
+ interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7779_CLK_SCIF3>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif4: serial@ffe44000 {
+ compatible = "renesas,scif-r8a7779", "renesas,scif";
+ reg = <0xffe44000 0x100>;
+ interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7779_CLK_SCIF4>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif5: serial@ffe45000 {
+ compatible = "renesas,scif-r8a7779", "renesas,scif";
+ reg = <0xffe45000 0x100>;
+ interrupts = <0 93 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7779_CLK_SCIF5>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ pfc: pfc@fffc0000 {
+ compatible = "renesas,pfc-r8a7779";
+ reg = <0xfffc0000 0x23c>;
+ };
+
+ thermal@ffc48000 {
+ compatible = "renesas,thermal-r8a7779", "renesas,rcar-thermal";
+ reg = <0xffc48000 0x38>;
+ };
+
+ tmu0: timer@ffd80000 {
+ compatible = "renesas,tmu-r8a7779", "renesas,tmu";
+ reg = <0xffd80000 0x30>;
+ interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>,
+ <0 33 IRQ_TYPE_LEVEL_HIGH>,
+ <0 34 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7779_CLK_TMU0>;
+ clock-names = "fck";
+
+ #renesas,channels = <3>;
+
+ status = "disabled";
+ };
+
+ tmu1: timer@ffd81000 {
+ compatible = "renesas,tmu-r8a7779", "renesas,tmu";
+ reg = <0xffd81000 0x30>;
+ interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>,
+ <0 37 IRQ_TYPE_LEVEL_HIGH>,
+ <0 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7779_CLK_TMU1>;
+ clock-names = "fck";
+
+ #renesas,channels = <3>;
+
+ status = "disabled";
+ };
+
+ tmu2: timer@ffd82000 {
+ compatible = "renesas,tmu-r8a7779", "renesas,tmu";
+ reg = <0xffd82000 0x30>;
+ interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>,
+ <0 41 IRQ_TYPE_LEVEL_HIGH>,
+ <0 42 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7779_CLK_TMU2>;
+ clock-names = "fck";
+
+ #renesas,channels = <3>;
+
+ status = "disabled";
+ };
+
+ sata: sata@fc600000 {
+ compatible = "renesas,sata-r8a7779", "renesas,rcar-sata";
+ reg = <0xfc600000 0x2000>;
+ interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7779_CLK_SATA>;
+ };
+
+ sdhi0: sd@ffe4c000 {
+ compatible = "renesas,sdhi-r8a7779";
+ reg = <0xffe4c000 0x100>;
+ interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7779_CLK_SDHI0>;
+ status = "disabled";
+ };
+
+ sdhi1: sd@ffe4d000 {
+ compatible = "renesas,sdhi-r8a7779";
+ reg = <0xffe4d000 0x100>;
+ interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7779_CLK_SDHI1>;
+ status = "disabled";
+ };
+
+ sdhi2: sd@ffe4e000 {
+ compatible = "renesas,sdhi-r8a7779";
+ reg = <0xffe4e000 0x100>;
+ interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7779_CLK_SDHI2>;
+ status = "disabled";
+ };
+
+ sdhi3: sd@ffe4f000 {
+ compatible = "renesas,sdhi-r8a7779";
+ reg = <0xffe4f000 0x100>;
+ interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7779_CLK_SDHI3>;
+ status = "disabled";
+ };
+
+ hspi0: spi@fffc7000 {
+ compatible = "renesas,hspi-r8a7779", "renesas,hspi";
+ reg = <0xfffc7000 0x18>;
+ interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mstp0_clks R8A7779_CLK_HSPI>;
+ status = "disabled";
+ };
+
+ hspi1: spi@fffc8000 {
+ compatible = "renesas,hspi-r8a7779", "renesas,hspi";
+ reg = <0xfffc8000 0x18>;
+ interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mstp0_clks R8A7779_CLK_HSPI>;
+ status = "disabled";
+ };
+
+ hspi2: spi@fffc6000 {
+ compatible = "renesas,hspi-r8a7779", "renesas,hspi";
+ reg = <0xfffc6000 0x18>;
+ interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mstp0_clks R8A7779_CLK_HSPI>;
+ status = "disabled";
+ };
+
+ du: display@fff80000 {
+ compatible = "renesas,du-r8a7779";
+ reg = <0 0xfff80000 0 0x40000>;
+ interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7779_CLK_DU>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ du_out_rgb0: endpoint {
+ };
+ };
+ port@1 {
+ reg = <1>;
+ du_out_rgb1: endpoint {
+ };
+ };
+ };
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /* External root clock */
+ extal_clk: extal_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overriden by the board. */
+ clock-frequency = <0>;
+ clock-output-names = "extal";
+ };
+
+ /* Special CPG clocks */
+ cpg_clocks: clocks@ffc80000 {
+ compatible = "renesas,r8a7779-cpg-clocks";
+ reg = <0xffc80000 0x30>;
+ clocks = <&extal_clk>;
+ #clock-cells = <1>;
+ clock-output-names = "plla", "z", "zs", "s",
+ "s1", "p", "b", "out";
+ };
+
+ /* Fixed factor clocks */
+ i_clk: i_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7779_CLK_PLLA>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "i";
+ };
+ s3_clk: s3_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7779_CLK_PLLA>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "s3";
+ };
+ s4_clk: s4_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7779_CLK_PLLA>;
+ #clock-cells = <0>;
+ clock-div = <16>;
+ clock-mult = <1>;
+ clock-output-names = "s4";
+ };
+ g_clk: g_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7779_CLK_PLLA>;
+ #clock-cells = <0>;
+ clock-div = <24>;
+ clock-mult = <1>;
+ clock-output-names = "g";
+ };
+
+ /* Gate clocks */
+ mstp0_clks: clocks@ffc80030 {
+ compatible = "renesas,r8a7779-mstp-clocks",
+ "renesas,cpg-mstp-clocks";
+ reg = <0xffc80030 4>;
+ clocks = <&cpg_clocks R8A7779_CLK_S>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_S>,
+ <&cpg_clocks R8A7779_CLK_S>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7779_CLK_HSPI R8A7779_CLK_TMU2
+ R8A7779_CLK_TMU1 R8A7779_CLK_TMU0
+ R8A7779_CLK_HSCIF1 R8A7779_CLK_HSCIF0
+ R8A7779_CLK_SCIF5 R8A7779_CLK_SCIF4
+ R8A7779_CLK_SCIF3 R8A7779_CLK_SCIF2
+ R8A7779_CLK_SCIF1 R8A7779_CLK_SCIF0
+ R8A7779_CLK_I2C3 R8A7779_CLK_I2C2
+ R8A7779_CLK_I2C1 R8A7779_CLK_I2C0
+ >;
+ clock-output-names =
+ "hspi", "tmu2", "tmu1", "tmu0", "hscif1",
+ "hscif0", "scif5", "scif4", "scif3", "scif2",
+ "scif1", "scif0", "i2c3", "i2c2", "i2c1",
+ "i2c0";
+ };
+ mstp1_clks: clocks@ffc80034 {
+ compatible = "renesas,r8a7779-mstp-clocks",
+ "renesas,cpg-mstp-clocks";
+ reg = <0xffc80034 4>, <0xffc80044 4>;
+ clocks = <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_S>,
+ <&cpg_clocks R8A7779_CLK_S>,
+ <&cpg_clocks R8A7779_CLK_S>,
+ <&cpg_clocks R8A7779_CLK_S>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_S>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7779_CLK_USB01 R8A7779_CLK_USB2
+ R8A7779_CLK_DU R8A7779_CLK_VIN2
+ R8A7779_CLK_VIN1 R8A7779_CLK_VIN0
+ R8A7779_CLK_ETHER R8A7779_CLK_SATA
+ R8A7779_CLK_PCIE R8A7779_CLK_VIN3
+ >;
+ clock-output-names =
+ "usb01", "usb2",
+ "du", "vin2",
+ "vin1", "vin0",
+ "ether", "sata",
+ "pcie", "vin3";
+ };
+ mstp3_clks: clocks@ffc8003c {
+ compatible = "renesas,r8a7779-mstp-clocks",
+ "renesas,cpg-mstp-clocks";
+ reg = <0xffc8003c 4>;
+ clocks = <&s4_clk>, <&s4_clk>, <&s4_clk>, <&s4_clk>,
+ <&s4_clk>, <&s4_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7779_CLK_SDHI3 R8A7779_CLK_SDHI2
+ R8A7779_CLK_SDHI1 R8A7779_CLK_SDHI0
+ R8A7779_CLK_MMC1 R8A7779_CLK_MMC0
+ >;
+ clock-output-names =
+ "sdhi3", "sdhi2", "sdhi1", "sdhi0",
+ "mmc1", "mmc0";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts
new file mode 100644
index 000000000..aaa4f258e
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7790-lager.dts
@@ -0,0 +1,686 @@
+/*
+ * Device Tree Source for the Lager board
+ *
+ * Copyright (C) 2013-2014 Renesas Solutions Corp.
+ * Copyright (C) 2014 Cogent Embedded, 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.
+ */
+
+/*
+ * SSI-AK4643
+ *
+ * SW1: 1: AK4643
+ * 2: CN22
+ * 3: ADV7511
+ *
+ * This command is required when Playback/Capture
+ *
+ * amixer set "LINEOUT Mixer DACL" on
+ * amixer set "DVC Out" 100%
+ * amixer set "DVC In" 100%
+ *
+ * You can use Mute
+ *
+ * amixer set "DVC Out Mute" on
+ * amixer set "DVC In Mute" on
+ *
+ * You can use Volume Ramp
+ *
+ * amixer set "DVC Out Ramp Up Rate" "0.125 dB/64 steps"
+ * amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps"
+ * amixer set "DVC Out Ramp" on
+ * aplay xxx.wav &
+ * amixer set "DVC Out" 80% // Volume Down
+ * amixer set "DVC Out" 100% // Volume Up
+ */
+
+/dts-v1/;
+#include "r8a7790.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "Lager";
+ compatible = "renesas,lager", "renesas,r8a7790";
+
+ aliases {
+ serial0 = &scifa0;
+ serial1 = &scifa1;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
+ stdout-path = &scifa0;
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0 0x40000000 0 0x40000000>;
+ };
+
+ memory@140000000 {
+ device_type = "memory";
+ reg = <1 0x40000000 0 0xc0000000>;
+ };
+
+ lbsc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ keyboard {
+ compatible = "gpio-keys";
+
+ button@1 {
+ linux,code = <KEY_1>;
+ label = "SW2-1";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ };
+ button@2 {
+ linux,code = <KEY_2>;
+ label = "SW2-2";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;
+ };
+ button@3 {
+ linux,code = <KEY_3>;
+ label = "SW2-3";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ gpios = <&gpio1 26 GPIO_ACTIVE_LOW>;
+ };
+ button@4 {
+ linux,code = <KEY_4>;
+ label = "SW2-4";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ gpios = <&gpio1 28 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ led6 {
+ gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>;
+ };
+ led7 {
+ gpios = <&gpio4 23 GPIO_ACTIVE_HIGH>;
+ };
+ led8 {
+ gpios = <&gpio5 17 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ fixedregulator3v3: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vcc_sdhi0: regulator@1 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "SDHI0 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&gpio5 24 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vccq_sdhi0: regulator@2 {
+ compatible = "regulator-gpio";
+
+ regulator-name = "SDHI0 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+ states = <3300000 1
+ 1800000 0>;
+ };
+
+ vcc_sdhi2: regulator@3 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "SDHI2 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&gpio5 25 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vccq_sdhi2: regulator@4 {
+ compatible = "regulator-gpio";
+
+ regulator-name = "SDHI2 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio5 30 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+ states = <3300000 1
+ 1800000 0>;
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+
+ simple-audio-card,format = "left_j";
+ simple-audio-card,bitclock-master = <&sndcodec>;
+ simple-audio-card,frame-master = <&sndcodec>;
+
+ sndcpu: simple-audio-card,cpu {
+ sound-dai = <&rcar_sound>;
+ };
+
+ sndcodec: simple-audio-card,codec {
+ sound-dai = <&ak4643>;
+ system-clock-frequency = <11289600>;
+ };
+ };
+
+ vga-encoder {
+ compatible = "adi,adv7123";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ adv7123_in: endpoint {
+ remote-endpoint = <&du_out_rgb>;
+ };
+ };
+ port@1 {
+ reg = <1>;
+ adv7123_out: endpoint {
+ remote-endpoint = <&vga_in>;
+ };
+ };
+ };
+ };
+
+ vga {
+ compatible = "vga-connector";
+
+ port {
+ vga_in: endpoint {
+ remote-endpoint = <&adv7123_out>;
+ };
+ };
+ };
+
+ hdmi-out {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con: endpoint {
+ remote-endpoint = <&adv7511_out>;
+ };
+ };
+ };
+
+ x2_clk: x2-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <148500000>;
+ };
+
+ x13_clk: x13-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <148500000>;
+ };
+};
+
+&du {
+ pinctrl-0 = <&du_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ clocks = <&mstp7_clks R8A7790_CLK_DU0>,
+ <&mstp7_clks R8A7790_CLK_DU1>,
+ <&mstp7_clks R8A7790_CLK_DU2>,
+ <&mstp7_clks R8A7790_CLK_LVDS0>,
+ <&mstp7_clks R8A7790_CLK_LVDS1>,
+ <&x13_clk>, <&x2_clk>;
+ clock-names = "du.0", "du.1", "du.2", "lvds.0", "lvds.1",
+ "dclkin.0", "dclkin.1";
+
+ ports {
+ port@0 {
+ endpoint {
+ remote-endpoint = <&adv7123_in>;
+ };
+ };
+ port@1 {
+ endpoint {
+ remote-endpoint = <&adv7511_in>;
+ };
+ };
+ port@2 {
+ lvds_connector: endpoint {
+ };
+ };
+ };
+};
+
+&extal_clk {
+ clock-frequency = <20000000>;
+};
+
+&pfc {
+ du_pins: du {
+ renesas,groups = "du_rgb666", "du_sync_1", "du_clk_out_0";
+ renesas,function = "du";
+ };
+
+ scifa0_pins: serial0 {
+ renesas,groups = "scifa0_data";
+ renesas,function = "scifa0";
+ };
+
+ ether_pins: ether {
+ renesas,groups = "eth_link", "eth_mdio", "eth_rmii";
+ renesas,function = "eth";
+ };
+
+ phy1_pins: phy1 {
+ renesas,groups = "intc_irq0";
+ renesas,function = "intc";
+ };
+
+ scifa1_pins: serial1 {
+ renesas,groups = "scifa1_data";
+ renesas,function = "scifa1";
+ };
+
+ sdhi0_pins: sd0 {
+ renesas,groups = "sdhi0_data4", "sdhi0_ctrl";
+ renesas,function = "sdhi0";
+ };
+
+ sdhi2_pins: sd2 {
+ renesas,groups = "sdhi2_data4", "sdhi2_ctrl";
+ renesas,function = "sdhi2";
+ };
+
+ mmc1_pins: mmc1 {
+ renesas,groups = "mmc1_data8", "mmc1_ctrl";
+ renesas,function = "mmc1";
+ };
+
+ qspi_pins: spi0 {
+ renesas,groups = "qspi_ctrl", "qspi_data4";
+ renesas,function = "qspi";
+ };
+
+ msiof1_pins: spi2 {
+ renesas,groups = "msiof1_clk", "msiof1_sync", "msiof1_rx",
+ "msiof1_tx";
+ renesas,function = "msiof1";
+ };
+
+ iic1_pins: iic1 {
+ renesas,groups = "iic1";
+ renesas,function = "iic1";
+ };
+
+ iic2_pins: iic2 {
+ renesas,groups = "iic2";
+ renesas,function = "iic2";
+ };
+
+ iic3_pins: iic3 {
+ renesas,groups = "iic3";
+ renesas,function = "iic3";
+ };
+
+ hsusb_pins: hsusb {
+ renesas,groups = "usb0_ovc_vbus";
+ renesas,function = "usb0";
+ };
+
+ usb0_pins: usb0 {
+ renesas,groups = "usb0";
+ renesas,function = "usb0";
+ };
+
+ usb1_pins: usb1 {
+ renesas,groups = "usb1";
+ renesas,function = "usb1";
+ };
+
+ usb2_pins: usb2 {
+ renesas,groups = "usb2";
+ renesas,function = "usb2";
+ };
+
+ vin1_pins: vin {
+ renesas,groups = "vin1_data8", "vin1_clk";
+ renesas,function = "vin1";
+ };
+
+ sound_pins: sound {
+ renesas,groups = "ssi0129_ctrl", "ssi0_data", "ssi1_data";
+ renesas,function = "ssi";
+ };
+
+ sound_clk_pins: sound_clk {
+ renesas,groups = "audio_clk_a";
+ renesas,function = "audio_clk";
+ };
+};
+
+&ether {
+ pinctrl-0 = <&ether_pins &phy1_pins>;
+ pinctrl-names = "default";
+
+ phy-handle = <&phy1>;
+ renesas,ether-link-active-low;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ interrupt-parent = <&irqc0>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ micrel,led-mode = <1>;
+ };
+};
+
+&cmt0 {
+ status = "okay";
+};
+
+&mmcif1 {
+ pinctrl-0 = <&mmc1_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&fixedregulator3v3>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&sata1 {
+ status = "okay";
+};
+
+&qspi {
+ pinctrl-0 = <&qspi_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ flash: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25fl512s";
+ reg = <0>;
+ spi-max-frequency = <30000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ spi-cpha;
+ spi-cpol;
+ m25p,fast-read;
+
+ partition@0 {
+ label = "loader";
+ reg = <0x00000000 0x00040000>;
+ read-only;
+ };
+ partition@40000 {
+ label = "user";
+ reg = <0x00040000 0x00400000>;
+ read-only;
+ };
+ partition@440000 {
+ label = "flash";
+ reg = <0x00440000 0x03bc0000>;
+ };
+ };
+};
+
+&scifa0 {
+ pinctrl-0 = <&scifa0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&scifa1 {
+ pinctrl-0 = <&scifa1_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&msiof1 {
+ pinctrl-0 = <&msiof1_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ pmic: pmic@0 {
+ compatible = "renesas,r2a11302ft";
+ reg = <0>;
+ spi-max-frequency = <6000000>;
+ spi-cpol;
+ spi-cpha;
+ };
+};
+
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&vcc_sdhi0>;
+ vqmmc-supply = <&vccq_sdhi0>;
+ cd-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&sdhi2 {
+ pinctrl-0 = <&sdhi2_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&vcc_sdhi2>;
+ vqmmc-supply = <&vccq_sdhi2>;
+ cd-gpios = <&gpio3 22 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_dvfs>;
+};
+
+&iic0 {
+ status = "okay";
+};
+
+&iic1 {
+ status = "okay";
+ pinctrl-0 = <&iic1_pins>;
+ pinctrl-names = "default";
+};
+
+&iic2 {
+ status = "okay";
+ pinctrl-0 = <&iic2_pins>;
+ pinctrl-names = "default";
+
+ clock-frequency = <100000>;
+
+ ak4643: sound-codec@12 {
+ compatible = "asahi-kasei,ak4643";
+ #sound-dai-cells = <0>;
+ reg = <0x12>;
+ };
+
+ composite-in@20 {
+ compatible = "adi,adv7180";
+ reg = <0x20>;
+ remote = <&vin1>;
+
+ port {
+ adv7180: endpoint {
+ bus-width = <8>;
+ remote-endpoint = <&vin1ep0>;
+ };
+ };
+ };
+
+ hdmi@39 {
+ compatible = "adi,adv7511w";
+ reg = <0x39>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
+
+ adi,input-depth = <8>;
+ adi,input-colorspace = "rgb";
+ adi,input-clock = "1x";
+ adi,input-style = <1>;
+ adi,input-justification = "evenly";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ adv7511_in: endpoint {
+ remote-endpoint = <&du_out_lvds0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ adv7511_out: endpoint {
+ remote-endpoint = <&hdmi_con>;
+ };
+ };
+ };
+ };
+};
+
+&iic3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&iic3_pins>;
+ status = "okay";
+
+ pmic@58 {
+ compatible = "dlg,da9063";
+ reg = <0x58>;
+ interrupt-parent = <&irqc0>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-controller;
+
+ rtc {
+ compatible = "dlg,da9063-rtc";
+ };
+
+ wdt {
+ compatible = "dlg,da9063-watchdog";
+ };
+ };
+
+ vdd_dvfs: regulator@68 {
+ compatible = "dlg,da9210";
+ reg = <0x68>;
+ interrupt-parent = <&irqc0>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&pci0 {
+ status = "okay";
+ pinctrl-0 = <&usb0_pins>;
+ pinctrl-names = "default";
+};
+
+&pci1 {
+ status = "okay";
+ pinctrl-0 = <&usb1_pins>;
+ pinctrl-names = "default";
+};
+
+&xhci {
+ status = "okay";
+ pinctrl-0 = <&usb2_pins>;
+ pinctrl-names = "default";
+};
+
+&pci2 {
+ status = "okay";
+ pinctrl-0 = <&usb2_pins>;
+ pinctrl-names = "default";
+};
+
+&hsusb {
+ status = "okay";
+ pinctrl-0 = <&hsusb_pins>;
+ pinctrl-names = "default";
+ renesas,enable-gpio = <&gpio5 18 GPIO_ACTIVE_HIGH>;
+};
+
+&usbphy {
+ status = "okay";
+};
+
+/* composite video input */
+&vin1 {
+ pinctrl-0 = <&vin1_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vin1ep0: endpoint {
+ remote-endpoint = <&adv7180>;
+ bus-width = <8>;
+ };
+ };
+};
+
+&rcar_sound {
+ pinctrl-0 = <&sound_pins &sound_clk_pins>;
+ pinctrl-names = "default";
+
+ /* Single DAI */
+ #sound-dai-cells = <0>;
+
+ status = "okay";
+
+ rcar_sound,dai {
+ dai0 {
+ playback = <&ssi0 &src2 &dvc0>;
+ capture = <&ssi1 &src3 &dvc1>;
+ };
+ };
+};
+
+&ssi1 {
+ shared-pin;
+};
diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
new file mode 100644
index 000000000..4bb2f4c17
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -0,0 +1,1651 @@
+/*
+ * Device Tree Source for the r8a7790 SoC
+ *
+ * Copyright (C) 2015 Renesas Electronics Corporation
+ * Copyright (C) 2013-2014 Renesas Solutions Corp.
+ * Copyright (C) 2014 Cogent Embedded 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 <dt-bindings/clock/r8a7790-clock.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "renesas,r8a7790";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &iic0;
+ i2c5 = &iic1;
+ i2c6 = &iic2;
+ i2c7 = &iic3;
+ spi0 = &qspi;
+ spi1 = &msiof0;
+ spi2 = &msiof1;
+ spi3 = &msiof2;
+ spi4 = &msiof3;
+ vin0 = &vin0;
+ vin1 = &vin1;
+ vin2 = &vin2;
+ vin3 = &vin3;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0>;
+ clock-frequency = <1300000000>;
+ voltage-tolerance = <1>; /* 1% */
+ clocks = <&cpg_clocks R8A7790_CLK_Z>;
+ clock-latency = <300000>; /* 300 us */
+
+ /* kHz - uV - OPPs unknown yet */
+ operating-points = <1400000 1000000>,
+ <1225000 1000000>,
+ <1050000 1000000>,
+ < 875000 1000000>,
+ < 700000 1000000>,
+ < 350000 1000000>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <1>;
+ clock-frequency = <1300000000>;
+ };
+
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <2>;
+ clock-frequency = <1300000000>;
+ };
+
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <3>;
+ clock-frequency = <1300000000>;
+ };
+
+ cpu4: cpu@4 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x100>;
+ clock-frequency = <780000000>;
+ };
+
+ cpu5: cpu@5 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x101>;
+ clock-frequency = <780000000>;
+ };
+
+ cpu6: cpu@6 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x102>;
+ clock-frequency = <780000000>;
+ };
+
+ cpu7: cpu@7 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x103>;
+ clock-frequency = <780000000>;
+ };
+ };
+
+ gic: interrupt-controller@f1001000 {
+ compatible = "arm,cortex-a15-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0 0xf1001000 0 0x1000>,
+ <0 0xf1002000 0 0x1000>,
+ <0 0xf1004000 0 0x2000>,
+ <0 0xf1006000 0 0x2000>;
+ interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ gpio0: gpio@e6050000 {
+ compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
+ reg = <0 0xe6050000 0 0x50>;
+ interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 0 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7790_CLK_GPIO0>;
+ };
+
+ gpio1: gpio@e6051000 {
+ compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
+ reg = <0 0xe6051000 0 0x50>;
+ interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 32 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7790_CLK_GPIO1>;
+ };
+
+ gpio2: gpio@e6052000 {
+ compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
+ reg = <0 0xe6052000 0 0x50>;
+ interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 64 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7790_CLK_GPIO2>;
+ };
+
+ gpio3: gpio@e6053000 {
+ compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
+ reg = <0 0xe6053000 0 0x50>;
+ interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 96 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7790_CLK_GPIO3>;
+ };
+
+ gpio4: gpio@e6054000 {
+ compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
+ reg = <0 0xe6054000 0 0x50>;
+ interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 128 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7790_CLK_GPIO4>;
+ };
+
+ gpio5: gpio@e6055000 {
+ compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
+ reg = <0 0xe6055000 0 0x50>;
+ interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 160 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7790_CLK_GPIO5>;
+ };
+
+ thermal@e61f0000 {
+ compatible = "renesas,thermal-r8a7790", "renesas,rcar-thermal";
+ reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
+ interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp5_clks R8A7790_CLK_THERMAL>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ cmt0: timer@ffca0000 {
+ compatible = "renesas,cmt-48-r8a7790", "renesas,cmt-48-gen2";
+ reg = <0 0xffca0000 0 0x1004>;
+ interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
+ <0 143 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
+ clock-names = "fck";
+
+ renesas,channels-mask = <0x60>;
+
+ status = "disabled";
+ };
+
+ cmt1: timer@e6130000 {
+ compatible = "renesas,cmt-48-r8a7790", "renesas,cmt-48-gen2";
+ reg = <0 0xe6130000 0 0x1004>;
+ interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>,
+ <0 121 IRQ_TYPE_LEVEL_HIGH>,
+ <0 122 IRQ_TYPE_LEVEL_HIGH>,
+ <0 123 IRQ_TYPE_LEVEL_HIGH>,
+ <0 124 IRQ_TYPE_LEVEL_HIGH>,
+ <0 125 IRQ_TYPE_LEVEL_HIGH>,
+ <0 126 IRQ_TYPE_LEVEL_HIGH>,
+ <0 127 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_CMT1>;
+ clock-names = "fck";
+
+ renesas,channels-mask = <0xff>;
+
+ status = "disabled";
+ };
+
+ irqc0: interrupt-controller@e61c0000 {
+ compatible = "renesas,irqc-r8a7790", "renesas,irqc";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0 0xe61c0000 0 0x200>;
+ interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>,
+ <0 1 IRQ_TYPE_LEVEL_HIGH>,
+ <0 2 IRQ_TYPE_LEVEL_HIGH>,
+ <0 3 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dmac0: dma-controller@e6700000 {
+ compatible = "renesas,rcar-dmac";
+ reg = <0 0xe6700000 0 0x20000>;
+ interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH
+ 0 200 IRQ_TYPE_LEVEL_HIGH
+ 0 201 IRQ_TYPE_LEVEL_HIGH
+ 0 202 IRQ_TYPE_LEVEL_HIGH
+ 0 203 IRQ_TYPE_LEVEL_HIGH
+ 0 204 IRQ_TYPE_LEVEL_HIGH
+ 0 205 IRQ_TYPE_LEVEL_HIGH
+ 0 206 IRQ_TYPE_LEVEL_HIGH
+ 0 207 IRQ_TYPE_LEVEL_HIGH
+ 0 208 IRQ_TYPE_LEVEL_HIGH
+ 0 209 IRQ_TYPE_LEVEL_HIGH
+ 0 210 IRQ_TYPE_LEVEL_HIGH
+ 0 211 IRQ_TYPE_LEVEL_HIGH
+ 0 212 IRQ_TYPE_LEVEL_HIGH
+ 0 213 IRQ_TYPE_LEVEL_HIGH
+ 0 214 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14";
+ clocks = <&mstp2_clks R8A7790_CLK_SYS_DMAC0>;
+ clock-names = "fck";
+ #dma-cells = <1>;
+ dma-channels = <15>;
+ };
+
+ dmac1: dma-controller@e6720000 {
+ compatible = "renesas,rcar-dmac";
+ reg = <0 0xe6720000 0 0x20000>;
+ interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH
+ 0 216 IRQ_TYPE_LEVEL_HIGH
+ 0 217 IRQ_TYPE_LEVEL_HIGH
+ 0 218 IRQ_TYPE_LEVEL_HIGH
+ 0 219 IRQ_TYPE_LEVEL_HIGH
+ 0 308 IRQ_TYPE_LEVEL_HIGH
+ 0 309 IRQ_TYPE_LEVEL_HIGH
+ 0 310 IRQ_TYPE_LEVEL_HIGH
+ 0 311 IRQ_TYPE_LEVEL_HIGH
+ 0 312 IRQ_TYPE_LEVEL_HIGH
+ 0 313 IRQ_TYPE_LEVEL_HIGH
+ 0 314 IRQ_TYPE_LEVEL_HIGH
+ 0 315 IRQ_TYPE_LEVEL_HIGH
+ 0 316 IRQ_TYPE_LEVEL_HIGH
+ 0 317 IRQ_TYPE_LEVEL_HIGH
+ 0 318 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14";
+ clocks = <&mstp2_clks R8A7790_CLK_SYS_DMAC1>;
+ clock-names = "fck";
+ #dma-cells = <1>;
+ dma-channels = <15>;
+ };
+
+ audma0: dma-controller@ec700000 {
+ compatible = "renesas,rcar-dmac";
+ reg = <0 0xec700000 0 0x10000>;
+ interrupts = <0 346 IRQ_TYPE_LEVEL_HIGH
+ 0 320 IRQ_TYPE_LEVEL_HIGH
+ 0 321 IRQ_TYPE_LEVEL_HIGH
+ 0 322 IRQ_TYPE_LEVEL_HIGH
+ 0 323 IRQ_TYPE_LEVEL_HIGH
+ 0 324 IRQ_TYPE_LEVEL_HIGH
+ 0 325 IRQ_TYPE_LEVEL_HIGH
+ 0 326 IRQ_TYPE_LEVEL_HIGH
+ 0 327 IRQ_TYPE_LEVEL_HIGH
+ 0 328 IRQ_TYPE_LEVEL_HIGH
+ 0 329 IRQ_TYPE_LEVEL_HIGH
+ 0 330 IRQ_TYPE_LEVEL_HIGH
+ 0 331 IRQ_TYPE_LEVEL_HIGH
+ 0 332 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12";
+ clocks = <&mstp5_clks R8A7790_CLK_AUDIO_DMAC0>;
+ clock-names = "fck";
+ #dma-cells = <1>;
+ dma-channels = <13>;
+ };
+
+ audma1: dma-controller@ec720000 {
+ compatible = "renesas,rcar-dmac";
+ reg = <0 0xec720000 0 0x10000>;
+ interrupts = <0 347 IRQ_TYPE_LEVEL_HIGH
+ 0 333 IRQ_TYPE_LEVEL_HIGH
+ 0 334 IRQ_TYPE_LEVEL_HIGH
+ 0 335 IRQ_TYPE_LEVEL_HIGH
+ 0 336 IRQ_TYPE_LEVEL_HIGH
+ 0 337 IRQ_TYPE_LEVEL_HIGH
+ 0 338 IRQ_TYPE_LEVEL_HIGH
+ 0 339 IRQ_TYPE_LEVEL_HIGH
+ 0 340 IRQ_TYPE_LEVEL_HIGH
+ 0 341 IRQ_TYPE_LEVEL_HIGH
+ 0 342 IRQ_TYPE_LEVEL_HIGH
+ 0 343 IRQ_TYPE_LEVEL_HIGH
+ 0 344 IRQ_TYPE_LEVEL_HIGH
+ 0 345 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12";
+ clocks = <&mstp5_clks R8A7790_CLK_AUDIO_DMAC1>;
+ clock-names = "fck";
+ #dma-cells = <1>;
+ dma-channels = <13>;
+ };
+
+ i2c0: i2c@e6508000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7790";
+ reg = <0 0xe6508000 0 0x40>;
+ interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7790_CLK_I2C0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@e6518000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7790";
+ reg = <0 0xe6518000 0 0x40>;
+ interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7790_CLK_I2C1>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@e6530000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7790";
+ reg = <0 0xe6530000 0 0x40>;
+ interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7790_CLK_I2C2>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@e6540000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7790";
+ reg = <0 0xe6540000 0 0x40>;
+ interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7790_CLK_I2C3>;
+ status = "disabled";
+ };
+
+ iic0: i2c@e6500000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic";
+ reg = <0 0xe6500000 0 0x425>;
+ interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_IIC0>;
+ dmas = <&dmac0 0x61>, <&dmac0 0x62>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ iic1: i2c@e6510000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic";
+ reg = <0 0xe6510000 0 0x425>;
+ interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_IIC1>;
+ dmas = <&dmac0 0x65>, <&dmac0 0x66>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ iic2: i2c@e6520000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic";
+ reg = <0 0xe6520000 0 0x425>;
+ interrupts = <0 176 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_IIC2>;
+ dmas = <&dmac0 0x69>, <&dmac0 0x6a>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ iic3: i2c@e60b0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic";
+ reg = <0 0xe60b0000 0 0x425>;
+ interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7790_CLK_IICDVFS>;
+ dmas = <&dmac0 0x77>, <&dmac0 0x78>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mmcif0: mmc@ee200000 {
+ compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif";
+ reg = <0 0xee200000 0 0x80>;
+ interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_MMCIF0>;
+ dmas = <&dmac0 0xd1>, <&dmac0 0xd2>;
+ dma-names = "tx", "rx";
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ mmcif1: mmc@ee220000 {
+ compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif";
+ reg = <0 0xee220000 0 0x80>;
+ interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_MMCIF1>;
+ dmas = <&dmac0 0xe1>, <&dmac0 0xe2>;
+ dma-names = "tx", "rx";
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ pfc: pfc@e6060000 {
+ compatible = "renesas,pfc-r8a7790";
+ reg = <0 0xe6060000 0 0x250>;
+ };
+
+ sdhi0: sd@ee100000 {
+ compatible = "renesas,sdhi-r8a7790";
+ reg = <0 0xee100000 0 0x328>;
+ interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_SDHI0>;
+ dmas = <&dmac1 0xcd>, <&dmac1 0xce>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ sdhi1: sd@ee120000 {
+ compatible = "renesas,sdhi-r8a7790";
+ reg = <0 0xee120000 0 0x328>;
+ interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_SDHI1>;
+ dmas = <&dmac1 0xc9>, <&dmac1 0xca>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ sdhi2: sd@ee140000 {
+ compatible = "renesas,sdhi-r8a7790";
+ reg = <0 0xee140000 0 0x100>;
+ interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_SDHI2>;
+ dmas = <&dmac1 0xc1>, <&dmac1 0xc2>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ sdhi3: sd@ee160000 {
+ compatible = "renesas,sdhi-r8a7790";
+ reg = <0 0xee160000 0 0x100>;
+ interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_SDHI3>;
+ dmas = <&dmac1 0xd3>, <&dmac1 0xd4>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ scifa0: serial@e6c40000 {
+ compatible = "renesas,scifa-r8a7790", "renesas,scifa";
+ reg = <0 0xe6c40000 0 64>;
+ interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7790_CLK_SCIFA0>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifa1: serial@e6c50000 {
+ compatible = "renesas,scifa-r8a7790", "renesas,scifa";
+ reg = <0 0xe6c50000 0 64>;
+ interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7790_CLK_SCIFA1>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifa2: serial@e6c60000 {
+ compatible = "renesas,scifa-r8a7790", "renesas,scifa";
+ reg = <0 0xe6c60000 0 64>;
+ interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7790_CLK_SCIFA2>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifb0: serial@e6c20000 {
+ compatible = "renesas,scifb-r8a7790", "renesas,scifb";
+ reg = <0 0xe6c20000 0 64>;
+ interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7790_CLK_SCIFB0>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifb1: serial@e6c30000 {
+ compatible = "renesas,scifb-r8a7790", "renesas,scifb";
+ reg = <0 0xe6c30000 0 64>;
+ interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7790_CLK_SCIFB1>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifb2: serial@e6ce0000 {
+ compatible = "renesas,scifb-r8a7790", "renesas,scifb";
+ reg = <0 0xe6ce0000 0 64>;
+ interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7790_CLK_SCIFB2>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif0: serial@e6e60000 {
+ compatible = "renesas,scif-r8a7790", "renesas,scif";
+ reg = <0 0xe6e60000 0 64>;
+ interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7790_CLK_SCIF0>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif1: serial@e6e68000 {
+ compatible = "renesas,scif-r8a7790", "renesas,scif";
+ reg = <0 0xe6e68000 0 64>;
+ interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7790_CLK_SCIF1>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ hscif0: serial@e62c0000 {
+ compatible = "renesas,hscif-r8a7790", "renesas,hscif";
+ reg = <0 0xe62c0000 0 96>;
+ interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7790_CLK_HSCIF0>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ hscif1: serial@e62c8000 {
+ compatible = "renesas,hscif-r8a7790", "renesas,hscif";
+ reg = <0 0xe62c8000 0 96>;
+ interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7790_CLK_HSCIF1>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ ether: ethernet@ee700000 {
+ compatible = "renesas,ether-r8a7790";
+ reg = <0 0xee700000 0 0x400>;
+ interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp8_clks R8A7790_CLK_ETHER>;
+ phy-mode = "rmii";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ sata0: sata@ee300000 {
+ compatible = "renesas,sata-r8a7790";
+ reg = <0 0xee300000 0 0x2000>;
+ interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp8_clks R8A7790_CLK_SATA0>;
+ status = "disabled";
+ };
+
+ sata1: sata@ee500000 {
+ compatible = "renesas,sata-r8a7790";
+ reg = <0 0xee500000 0 0x2000>;
+ interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp8_clks R8A7790_CLK_SATA1>;
+ status = "disabled";
+ };
+
+ hsusb: usb@e6590000 {
+ compatible = "renesas,usbhs-r8a7790";
+ reg = <0 0xe6590000 0 0x100>;
+ interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7790_CLK_HSUSB>;
+ renesas,buswait = <4>;
+ phys = <&usb0 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ usbphy: usb-phy@e6590100 {
+ compatible = "renesas,usb-phy-r8a7790";
+ reg = <0 0xe6590100 0 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mstp7_clks R8A7790_CLK_HSUSB>;
+ clock-names = "usbhs";
+ status = "disabled";
+
+ usb0: usb-channel@0 {
+ reg = <0>;
+ #phy-cells = <1>;
+ };
+ usb2: usb-channel@2 {
+ reg = <2>;
+ #phy-cells = <1>;
+ };
+ };
+
+ vin0: video@e6ef0000 {
+ compatible = "renesas,vin-r8a7790";
+ clocks = <&mstp8_clks R8A7790_CLK_VIN0>;
+ reg = <0 0xe6ef0000 0 0x1000>;
+ interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ vin1: video@e6ef1000 {
+ compatible = "renesas,vin-r8a7790";
+ clocks = <&mstp8_clks R8A7790_CLK_VIN1>;
+ reg = <0 0xe6ef1000 0 0x1000>;
+ interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ vin2: video@e6ef2000 {
+ compatible = "renesas,vin-r8a7790";
+ clocks = <&mstp8_clks R8A7790_CLK_VIN2>;
+ reg = <0 0xe6ef2000 0 0x1000>;
+ interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ vin3: video@e6ef3000 {
+ compatible = "renesas,vin-r8a7790";
+ clocks = <&mstp8_clks R8A7790_CLK_VIN3>;
+ reg = <0 0xe6ef3000 0 0x1000>;
+ interrupts = <0 191 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ vsp1@fe920000 {
+ compatible = "renesas,vsp1";
+ reg = <0 0xfe920000 0 0x8000>;
+ interrupts = <0 266 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7790_CLK_VSP1_R>;
+
+ renesas,has-sru;
+ renesas,#rpf = <5>;
+ renesas,#uds = <1>;
+ renesas,#wpf = <4>;
+ };
+
+ vsp1@fe928000 {
+ compatible = "renesas,vsp1";
+ reg = <0 0xfe928000 0 0x8000>;
+ interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7790_CLK_VSP1_S>;
+
+ renesas,has-lut;
+ renesas,has-sru;
+ renesas,#rpf = <5>;
+ renesas,#uds = <3>;
+ renesas,#wpf = <4>;
+ };
+
+ vsp1@fe930000 {
+ compatible = "renesas,vsp1";
+ reg = <0 0xfe930000 0 0x8000>;
+ interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU0>;
+
+ renesas,has-lif;
+ renesas,has-lut;
+ renesas,#rpf = <4>;
+ renesas,#uds = <1>;
+ renesas,#wpf = <4>;
+ };
+
+ vsp1@fe938000 {
+ compatible = "renesas,vsp1";
+ reg = <0 0xfe938000 0 0x8000>;
+ interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU1>;
+
+ renesas,has-lif;
+ renesas,has-lut;
+ renesas,#rpf = <4>;
+ renesas,#uds = <1>;
+ renesas,#wpf = <4>;
+ };
+
+ du: display@feb00000 {
+ compatible = "renesas,du-r8a7790";
+ reg = <0 0xfeb00000 0 0x70000>,
+ <0 0xfeb90000 0 0x1c>,
+ <0 0xfeb94000 0 0x1c>;
+ reg-names = "du", "lvds.0", "lvds.1";
+ interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>,
+ <0 268 IRQ_TYPE_LEVEL_HIGH>,
+ <0 269 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7790_CLK_DU0>,
+ <&mstp7_clks R8A7790_CLK_DU1>,
+ <&mstp7_clks R8A7790_CLK_DU2>,
+ <&mstp7_clks R8A7790_CLK_LVDS0>,
+ <&mstp7_clks R8A7790_CLK_LVDS1>;
+ clock-names = "du.0", "du.1", "du.2", "lvds.0", "lvds.1";
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ du_out_rgb: endpoint {
+ };
+ };
+ port@1 {
+ reg = <1>;
+ du_out_lvds0: endpoint {
+ };
+ };
+ port@2 {
+ reg = <2>;
+ du_out_lvds1: endpoint {
+ };
+ };
+ };
+ };
+
+ can0: can@e6e80000 {
+ compatible = "renesas,can-r8a7790";
+ reg = <0 0xe6e80000 0 0x1000>;
+ interrupts = <0 186 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7790_CLK_RCAN0>,
+ <&cpg_clocks R8A7790_CLK_RCAN>, <&can_clk>;
+ clock-names = "clkp1", "clkp2", "can_clk";
+ status = "disabled";
+ };
+
+ can1: can@e6e88000 {
+ compatible = "renesas,can-r8a7790";
+ reg = <0 0xe6e88000 0 0x1000>;
+ interrupts = <0 187 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7790_CLK_RCAN1>,
+ <&cpg_clocks R8A7790_CLK_RCAN>, <&can_clk>;
+ clock-names = "clkp1", "clkp2", "can_clk";
+ status = "disabled";
+ };
+
+ clocks {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* External root clock */
+ extal_clk: extal_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overriden by the board. */
+ clock-frequency = <0>;
+ clock-output-names = "extal";
+ };
+
+ /* External PCIe clock - can be overridden by the board */
+ pcie_bus_clk: pcie_bus_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ clock-output-names = "pcie_bus";
+ status = "disabled";
+ };
+
+ /*
+ * The external audio clocks are configured as 0 Hz fixed frequency clocks by
+ * default. Boards that provide audio clocks should override them.
+ */
+ audio_clk_a: audio_clk_a {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "audio_clk_a";
+ };
+ audio_clk_b: audio_clk_b {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "audio_clk_b";
+ };
+ audio_clk_c: audio_clk_c {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "audio_clk_c";
+ };
+
+ /* External USB clock - can be overridden by the board */
+ usb_extal_clk: usb_extal_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <48000000>;
+ clock-output-names = "usb_extal";
+ };
+
+ /* External CAN clock */
+ can_clk: can_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ clock-output-names = "can_clk";
+ status = "disabled";
+ };
+
+ /* Special CPG clocks */
+ cpg_clocks: cpg_clocks@e6150000 {
+ compatible = "renesas,r8a7790-cpg-clocks",
+ "renesas,rcar-gen2-cpg-clocks";
+ reg = <0 0xe6150000 0 0x1000>;
+ clocks = <&extal_clk &usb_extal_clk>;
+ #clock-cells = <1>;
+ clock-output-names = "main", "pll0", "pll1", "pll3",
+ "lb", "qspi", "sdh", "sd0", "sd1",
+ "z", "rcan", "adsp";
+ };
+
+ /* Variable factor clocks */
+ sd2_clk: sd2_clk@e6150078 {
+ compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150078 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sd2";
+ };
+ sd3_clk: sd3_clk@e615026c {
+ compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe615026c 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sd3";
+ };
+ mmc0_clk: mmc0_clk@e6150240 {
+ compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150240 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "mmc0";
+ };
+ mmc1_clk: mmc1_clk@e6150244 {
+ compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150244 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "mmc1";
+ };
+ ssp_clk: ssp_clk@e6150248 {
+ compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150248 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "ssp";
+ };
+ ssprs_clk: ssprs_clk@e615024c {
+ compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe615024c 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "ssprs";
+ };
+
+ /* Fixed factor clocks */
+ pll1_div2_clk: pll1_div2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "pll1_div2";
+ };
+ z2_clk: z2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "z2";
+ };
+ zg_clk: zg_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <3>;
+ clock-mult = <1>;
+ clock-output-names = "zg";
+ };
+ zx_clk: zx_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <3>;
+ clock-mult = <1>;
+ clock-output-names = "zx";
+ };
+ zs_clk: zs_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <6>;
+ clock-mult = <1>;
+ clock-output-names = "zs";
+ };
+ hp_clk: hp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <12>;
+ clock-mult = <1>;
+ clock-output-names = "hp";
+ };
+ i_clk: i_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "i";
+ };
+ b_clk: b_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <12>;
+ clock-mult = <1>;
+ clock-output-names = "b";
+ };
+ p_clk: p_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <24>;
+ clock-mult = <1>;
+ clock-output-names = "p";
+ };
+ cl_clk: cl_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <48>;
+ clock-mult = <1>;
+ clock-output-names = "cl";
+ };
+ m2_clk: m2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "m2";
+ };
+ imp_clk: imp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clock-output-names = "imp";
+ };
+ rclk_clk: rclk_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <(48 * 1024)>;
+ clock-mult = <1>;
+ clock-output-names = "rclk";
+ };
+ oscclk_clk: oscclk_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <(12 * 1024)>;
+ clock-mult = <1>;
+ clock-output-names = "oscclk";
+ };
+ zb3_clk: zb3_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL3>;
+ #clock-cells = <0>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clock-output-names = "zb3";
+ };
+ zb3d2_clk: zb3d2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL3>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "zb3d2";
+ };
+ ddr_clk: ddr_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL3>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "ddr";
+ };
+ mp_clk: mp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-div = <15>;
+ clock-mult = <1>;
+ clock-output-names = "mp";
+ };
+ cp_clk: cp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&extal_clk>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "cp";
+ };
+
+ /* Gate clocks */
+ mstp0_clks: mstp0_clks@e6150130 {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150130 0 4>, <0 0xe6150030 0 4>;
+ clocks = <&mp_clk>;
+ #clock-cells = <1>;
+ clock-indices = <R8A7790_CLK_MSIOF0>;
+ clock-output-names = "msiof0";
+ };
+ mstp1_clks: mstp1_clks@e6150134 {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>;
+ clocks = <&zs_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>, <&m2_clk>,
+ <&zs_clk>, <&p_clk>, <&zg_clk>, <&zs_clk>, <&zs_clk>,
+ <&zs_clk>, <&zs_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>,
+ <&cp_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7790_CLK_VCP1 R8A7790_CLK_VCP0 R8A7790_CLK_VPC1
+ R8A7790_CLK_VPC0 R8A7790_CLK_JPU R8A7790_CLK_SSP1
+ R8A7790_CLK_TMU1 R8A7790_CLK_3DG R8A7790_CLK_2DDMAC
+ R8A7790_CLK_FDP1_2 R8A7790_CLK_FDP1_1 R8A7790_CLK_FDP1_0
+ R8A7790_CLK_TMU3 R8A7790_CLK_TMU2 R8A7790_CLK_CMT0
+ R8A7790_CLK_TMU0 R8A7790_CLK_VSP1_DU1 R8A7790_CLK_VSP1_DU0
+ R8A7790_CLK_VSP1_R R8A7790_CLK_VSP1_S
+ >;
+ clock-output-names =
+ "vcp1", "vcp0", "vpc1", "vpc0", "jpu", "ssp1",
+ "tmu1", "3dg", "2ddmac", "fdp1-2", "fdp1-1",
+ "fdp1-0", "tmu3", "tmu2", "cmt0", "tmu0",
+ "vsp1-du1", "vsp1-du0", "vsp1-rt", "vsp1-sy";
+ };
+ mstp2_clks: mstp2_clks@e6150138 {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
+ clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>,
+ <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&zs_clk>,
+ <&zs_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7790_CLK_SCIFA2 R8A7790_CLK_SCIFA1 R8A7790_CLK_SCIFA0
+ R8A7790_CLK_MSIOF2 R8A7790_CLK_SCIFB0 R8A7790_CLK_SCIFB1
+ R8A7790_CLK_MSIOF1 R8A7790_CLK_MSIOF3 R8A7790_CLK_SCIFB2
+ R8A7790_CLK_SYS_DMAC1 R8A7790_CLK_SYS_DMAC0
+ >;
+ clock-output-names =
+ "scifa2", "scifa1", "scifa0", "msiof2", "scifb0",
+ "scifb1", "msiof1", "msiof3", "scifb2",
+ "sys-dmac1", "sys-dmac0";
+ };
+ mstp3_clks: mstp3_clks@e615013c {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
+ clocks = <&hp_clk>, <&cp_clk>, <&mmc1_clk>, <&sd3_clk>,
+ <&sd2_clk>, <&cpg_clocks R8A7790_CLK_SD1>, <&cpg_clocks R8A7790_CLK_SD0>, <&mmc0_clk>,
+ <&hp_clk>, <&mp_clk>, <&hp_clk>, <&mp_clk>, <&rclk_clk>,
+ <&hp_clk>, <&hp_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7790_CLK_IIC2 R8A7790_CLK_TPU0 R8A7790_CLK_MMCIF1 R8A7790_CLK_SDHI3
+ R8A7790_CLK_SDHI2 R8A7790_CLK_SDHI1 R8A7790_CLK_SDHI0 R8A7790_CLK_MMCIF0
+ R8A7790_CLK_IIC0 R8A7790_CLK_PCIEC R8A7790_CLK_IIC1 R8A7790_CLK_SSUSB R8A7790_CLK_CMT1
+ R8A7790_CLK_USBDMAC0 R8A7790_CLK_USBDMAC1
+ >;
+ clock-output-names =
+ "iic2", "tpu0", "mmcif1", "sdhi3",
+ "sdhi2", "sdhi1", "sdhi0", "mmcif0",
+ "iic0", "pciec", "iic1", "ssusb", "cmt1",
+ "usbdmac0", "usbdmac1";
+ };
+ mstp5_clks: mstp5_clks@e6150144 {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>;
+ clocks = <&hp_clk>, <&hp_clk>, <&cpg_clocks R8A7790_CLK_ADSP>,
+ <&extal_clk>, <&p_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7790_CLK_AUDIO_DMAC0 R8A7790_CLK_AUDIO_DMAC1
+ R8A7790_CLK_ADSP_MOD R8A7790_CLK_THERMAL
+ R8A7790_CLK_PWM
+ >;
+ clock-output-names = "audmac0", "audmac1", "adsp_mod",
+ "thermal", "pwm";
+ };
+ mstp7_clks: mstp7_clks@e615014c {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe615014c 0 4>, <0 0xe61501c4 0 4>;
+ clocks = <&mp_clk>, <&hp_clk>, <&zs_clk>, <&zs_clk>, <&p_clk>,
+ <&p_clk>, <&zx_clk>, <&zx_clk>, <&zx_clk>, <&zx_clk>,
+ <&zx_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7790_CLK_EHCI R8A7790_CLK_HSUSB R8A7790_CLK_HSCIF1
+ R8A7790_CLK_HSCIF0 R8A7790_CLK_SCIF1 R8A7790_CLK_SCIF0
+ R8A7790_CLK_DU2 R8A7790_CLK_DU1 R8A7790_CLK_DU0
+ R8A7790_CLK_LVDS1 R8A7790_CLK_LVDS0
+ >;
+ clock-output-names =
+ "ehci", "hsusb", "hscif1", "hscif0", "scif1",
+ "scif0", "du2", "du1", "du0", "lvds1", "lvds0";
+ };
+ mstp8_clks: mstp8_clks@e6150990 {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>;
+ clocks = <&hp_clk>, <&zg_clk>, <&zg_clk>, <&zg_clk>,
+ <&zg_clk>, <&p_clk>, <&zs_clk>, <&zs_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7790_CLK_MLB R8A7790_CLK_VIN3 R8A7790_CLK_VIN2
+ R8A7790_CLK_VIN1 R8A7790_CLK_VIN0 R8A7790_CLK_ETHER
+ R8A7790_CLK_SATA1 R8A7790_CLK_SATA0
+ >;
+ clock-output-names =
+ "mlb", "vin3", "vin2", "vin1", "vin0", "ether",
+ "sata1", "sata0";
+ };
+ mstp9_clks: mstp9_clks@e6150994 {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>;
+ clocks = <&cp_clk>, <&cp_clk>, <&cp_clk>,
+ <&cp_clk>, <&cp_clk>, <&cp_clk>,
+ <&p_clk>, <&p_clk>, <&cpg_clocks R8A7790_CLK_QSPI>, <&cp_clk>,
+ <&hp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7790_CLK_GPIO5 R8A7790_CLK_GPIO4 R8A7790_CLK_GPIO3
+ R8A7790_CLK_GPIO2 R8A7790_CLK_GPIO1 R8A7790_CLK_GPIO0
+ R8A7790_CLK_RCAN1 R8A7790_CLK_RCAN0 R8A7790_CLK_QSPI_MOD R8A7790_CLK_IICDVFS
+ R8A7790_CLK_I2C3 R8A7790_CLK_I2C2 R8A7790_CLK_I2C1 R8A7790_CLK_I2C0
+ >;
+ clock-output-names =
+ "gpio5", "gpio4", "gpio3", "gpio2", "gpio1", "gpio0",
+ "rcan1", "rcan0", "qspi_mod", "iic3",
+ "i2c3", "i2c2", "i2c1", "i2c0";
+ };
+ mstp10_clks: mstp10_clks@e6150998 {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150998 0 4>, <0 0xe61509a8 0 4>;
+ clocks = <&p_clk>,
+ <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
+ <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
+ <&p_clk>,
+ <&mstp10_clks R8A7790_CLK_SCU_ALL>, <&mstp10_clks R8A7790_CLK_SCU_ALL>,
+ <&mstp10_clks R8A7790_CLK_SCU_ALL>, <&mstp10_clks R8A7790_CLK_SCU_ALL>,
+ <&mstp10_clks R8A7790_CLK_SCU_ALL>, <&mstp10_clks R8A7790_CLK_SCU_ALL>,
+ <&mstp10_clks R8A7790_CLK_SCU_ALL>, <&mstp10_clks R8A7790_CLK_SCU_ALL>,
+ <&mstp10_clks R8A7790_CLK_SCU_ALL>, <&mstp10_clks R8A7790_CLK_SCU_ALL>,
+ <&mstp10_clks R8A7790_CLK_SCU_ALL>, <&mstp10_clks R8A7790_CLK_SCU_ALL>;
+
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7790_CLK_SSI_ALL
+ R8A7790_CLK_SSI9 R8A7790_CLK_SSI8 R8A7790_CLK_SSI7 R8A7790_CLK_SSI6 R8A7790_CLK_SSI5
+ R8A7790_CLK_SSI4 R8A7790_CLK_SSI3 R8A7790_CLK_SSI2 R8A7790_CLK_SSI1 R8A7790_CLK_SSI0
+ R8A7790_CLK_SCU_ALL
+ R8A7790_CLK_SCU_DVC1 R8A7790_CLK_SCU_DVC0
+ R8A7790_CLK_SCU_SRC9 R8A7790_CLK_SCU_SRC8 R8A7790_CLK_SCU_SRC7 R8A7790_CLK_SCU_SRC6 R8A7790_CLK_SCU_SRC5
+ R8A7790_CLK_SCU_SRC4 R8A7790_CLK_SCU_SRC3 R8A7790_CLK_SCU_SRC2 R8A7790_CLK_SCU_SRC1 R8A7790_CLK_SCU_SRC0
+ >;
+ clock-output-names =
+ "ssi-all",
+ "ssi9", "ssi8", "ssi7", "ssi6", "ssi5",
+ "ssi4", "ssi3", "ssi2", "ssi1", "ssi0",
+ "scu-all",
+ "scu-dvc1", "scu-dvc0",
+ "scu-src9", "scu-src8", "scu-src7", "scu-src6", "scu-src5",
+ "scu-src4", "scu-src3", "scu-src2", "scu-src1", "scu-src0";
+ };
+ };
+
+ qspi: spi@e6b10000 {
+ compatible = "renesas,qspi-r8a7790", "renesas,qspi";
+ reg = <0 0xe6b10000 0 0x2c>;
+ interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7790_CLK_QSPI_MOD>;
+ dmas = <&dmac0 0x17>, <&dmac0 0x18>;
+ dma-names = "tx", "rx";
+ num-cs = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof0: spi@e6e20000 {
+ compatible = "renesas,msiof-r8a7790";
+ reg = <0 0xe6e20000 0 0x0064>, <0 0xe7e20000 0 0x0064>;
+ interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7790_CLK_MSIOF0>;
+ dmas = <&dmac0 0x51>, <&dmac0 0x52>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof1: spi@e6e10000 {
+ compatible = "renesas,msiof-r8a7790";
+ reg = <0 0xe6e10000 0 0x0064>, <0 0xe7e10000 0 0x0064>;
+ interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7790_CLK_MSIOF1>;
+ dmas = <&dmac0 0x55>, <&dmac0 0x56>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof2: spi@e6e00000 {
+ compatible = "renesas,msiof-r8a7790";
+ reg = <0 0xe6e00000 0 0x0064>, <0 0xe7e00000 0 0x0064>;
+ interrupts = <0 158 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7790_CLK_MSIOF2>;
+ dmas = <&dmac0 0x41>, <&dmac0 0x42>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof3: spi@e6c90000 {
+ compatible = "renesas,msiof-r8a7790";
+ reg = <0 0xe6c90000 0 0x0064>, <0 0xe7c90000 0 0x0064>;
+ interrupts = <0 159 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7790_CLK_MSIOF3>;
+ dmas = <&dmac0 0x45>, <&dmac0 0x46>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ xhci: usb@ee000000 {
+ compatible = "renesas,xhci-r8a7790";
+ reg = <0 0xee000000 0 0xc00>;
+ interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_SSUSB>;
+ phys = <&usb2 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ pci0: pci@ee090000 {
+ compatible = "renesas,pci-r8a7790";
+ device_type = "pci";
+ clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
+ reg = <0 0xee090000 0 0xc00>,
+ <0 0xee080000 0 0x1100>;
+ interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+
+ bus-range = <0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
+ interrupt-map-mask = <0xff00 0 0 0x7>;
+ interrupt-map = <0x0000 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH
+ 0x0800 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH
+ 0x1000 0 0 2 &gic 0 108 IRQ_TYPE_LEVEL_HIGH>;
+
+ usb@0,1 {
+ reg = <0x800 0 0 0 0>;
+ device_type = "pci";
+ phys = <&usb0 0>;
+ phy-names = "usb";
+ };
+
+ usb@0,2 {
+ reg = <0x1000 0 0 0 0>;
+ device_type = "pci";
+ phys = <&usb0 0>;
+ phy-names = "usb";
+ };
+ };
+
+ pci1: pci@ee0b0000 {
+ compatible = "renesas,pci-r8a7790";
+ device_type = "pci";
+ clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
+ reg = <0 0xee0b0000 0 0xc00>,
+ <0 0xee0a0000 0 0x1100>;
+ interrupts = <0 112 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+
+ bus-range = <1 1>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x02000000 0 0xee0a0000 0 0xee0a0000 0 0x00010000>;
+ interrupt-map-mask = <0xff00 0 0 0x7>;
+ interrupt-map = <0x0000 0 0 1 &gic 0 112 IRQ_TYPE_LEVEL_HIGH
+ 0x0800 0 0 1 &gic 0 112 IRQ_TYPE_LEVEL_HIGH
+ 0x1000 0 0 2 &gic 0 112 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pci2: pci@ee0d0000 {
+ compatible = "renesas,pci-r8a7790";
+ device_type = "pci";
+ clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
+ reg = <0 0xee0d0000 0 0xc00>,
+ <0 0xee0c0000 0 0x1100>;
+ interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+
+ bus-range = <2 2>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
+ interrupt-map-mask = <0xff00 0 0 0x7>;
+ interrupt-map = <0x0000 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH
+ 0x0800 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH
+ 0x1000 0 0 2 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>;
+
+ usb@0,1 {
+ reg = <0x800 0 0 0 0>;
+ device_type = "pci";
+ phys = <&usb2 0>;
+ phy-names = "usb";
+ };
+
+ usb@0,2 {
+ reg = <0x1000 0 0 0 0>;
+ device_type = "pci";
+ phys = <&usb2 0>;
+ phy-names = "usb";
+ };
+ };
+
+ pciec: pcie@fe000000 {
+ compatible = "renesas,pcie-r8a7790";
+ reg = <0 0xfe000000 0 0x80000>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x00 0xff>;
+ device_type = "pci";
+ ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000
+ 0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000
+ 0x02000000 0 0x30000000 0 0x30000000 0 0x08000000
+ 0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
+ /* Map all possible DDR as inbound ranges */
+ dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000
+ 0x43000000 1 0x80000000 1 0x80000000 0 0x80000000>;
+ interrupts = <0 116 IRQ_TYPE_LEVEL_HIGH>,
+ <0 117 IRQ_TYPE_LEVEL_HIGH>,
+ <0 118 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic 0 116 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_PCIEC>, <&pcie_bus_clk>;
+ clock-names = "pcie", "pcie_bus";
+ status = "disabled";
+ };
+
+ rcar_sound: rcar_sound@ec500000 {
+ /*
+ * #sound-dai-cells is required
+ *
+ * Single DAI : #sound-dai-cells = <0>; <&rcar_sound>;
+ * Multi DAI : #sound-dai-cells = <1>; <&rcar_sound N>;
+ */
+ compatible = "renesas,rcar_sound-r8a7790", "renesas,rcar_sound-gen2";
+ reg = <0 0xec500000 0 0x1000>, /* SCU */
+ <0 0xec5a0000 0 0x100>, /* ADG */
+ <0 0xec540000 0 0x1000>, /* SSIU */
+ <0 0xec541000 0 0x1280>, /* SSI */
+ <0 0xec740000 0 0x200>; /* Audio DMAC peri peri*/
+ reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
+
+ clocks = <&mstp10_clks R8A7790_CLK_SSI_ALL>,
+ <&mstp10_clks R8A7790_CLK_SSI9>, <&mstp10_clks R8A7790_CLK_SSI8>,
+ <&mstp10_clks R8A7790_CLK_SSI7>, <&mstp10_clks R8A7790_CLK_SSI6>,
+ <&mstp10_clks R8A7790_CLK_SSI5>, <&mstp10_clks R8A7790_CLK_SSI4>,
+ <&mstp10_clks R8A7790_CLK_SSI3>, <&mstp10_clks R8A7790_CLK_SSI2>,
+ <&mstp10_clks R8A7790_CLK_SSI1>, <&mstp10_clks R8A7790_CLK_SSI0>,
+ <&mstp10_clks R8A7790_CLK_SCU_SRC9>, <&mstp10_clks R8A7790_CLK_SCU_SRC8>,
+ <&mstp10_clks R8A7790_CLK_SCU_SRC7>, <&mstp10_clks R8A7790_CLK_SCU_SRC6>,
+ <&mstp10_clks R8A7790_CLK_SCU_SRC5>, <&mstp10_clks R8A7790_CLK_SCU_SRC4>,
+ <&mstp10_clks R8A7790_CLK_SCU_SRC3>, <&mstp10_clks R8A7790_CLK_SCU_SRC2>,
+ <&mstp10_clks R8A7790_CLK_SCU_SRC1>, <&mstp10_clks R8A7790_CLK_SCU_SRC0>,
+ <&mstp10_clks R8A7790_CLK_SCU_DVC0>, <&mstp10_clks R8A7790_CLK_SCU_DVC1>,
+ <&audio_clk_a>, <&audio_clk_b>, <&audio_clk_c>, <&m2_clk>;
+ clock-names = "ssi-all",
+ "ssi.9", "ssi.8", "ssi.7", "ssi.6", "ssi.5",
+ "ssi.4", "ssi.3", "ssi.2", "ssi.1", "ssi.0",
+ "src.9", "src.8", "src.7", "src.6", "src.5",
+ "src.4", "src.3", "src.2", "src.1", "src.0",
+ "dvc.0", "dvc.1",
+ "clk_a", "clk_b", "clk_c", "clk_i";
+
+ status = "disabled";
+
+ rcar_sound,dvc {
+ dvc0: dvc@0 {
+ dmas = <&audma0 0xbc>;
+ dma-names = "tx";
+ };
+ dvc1: dvc@1 {
+ dmas = <&audma0 0xbe>;
+ dma-names = "tx";
+ };
+ };
+
+ rcar_sound,src {
+ src0: src@0 {
+ interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x85>, <&audma1 0x9a>;
+ dma-names = "rx", "tx";
+ };
+ src1: src@1 {
+ interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x87>, <&audma1 0x9c>;
+ dma-names = "rx", "tx";
+ };
+ src2: src@2 {
+ interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x89>, <&audma1 0x9e>;
+ dma-names = "rx", "tx";
+ };
+ src3: src@3 {
+ interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x8b>, <&audma1 0xa0>;
+ dma-names = "rx", "tx";
+ };
+ src4: src@4 {
+ interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x8d>, <&audma1 0xb0>;
+ dma-names = "rx", "tx";
+ };
+ src5: src@5 {
+ interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x8f>, <&audma1 0xb2>;
+ dma-names = "rx", "tx";
+ };
+ src6: src@6 {
+ interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x91>, <&audma1 0xb4>;
+ dma-names = "rx", "tx";
+ };
+ src7: src@7 {
+ interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x93>, <&audma1 0xb6>;
+ dma-names = "rx", "tx";
+ };
+ src8: src@8 {
+ interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x95>, <&audma1 0xb8>;
+ dma-names = "rx", "tx";
+ };
+ src9: src@9 {
+ interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x97>, <&audma1 0xba>;
+ dma-names = "rx", "tx";
+ };
+ };
+
+ rcar_sound,ssi {
+ ssi0: ssi@0 {
+ interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi1: ssi@1 {
+ interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi2: ssi@2 {
+ interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi3: ssi@3 {
+ interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi4: ssi@4 {
+ interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi5: ssi@5 {
+ interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi6: ssi@6 {
+ interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi7: ssi@7 {
+ interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi8: ssi@8 {
+ interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi9: ssi@9 {
+ interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ };
+ };
+
+ ipmmu_sy0: mmu@e6280000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xe6280000 0 0x1000>;
+ interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>,
+ <0 224 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ ipmmu_sy1: mmu@e6290000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xe6290000 0 0x1000>;
+ interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ ipmmu_ds: mmu@e6740000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xe6740000 0 0x1000>;
+ interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>,
+ <0 199 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ ipmmu_mp: mmu@ec680000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xec680000 0 0x1000>;
+ interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ ipmmu_mx: mmu@fe951000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xfe951000 0 0x1000>;
+ interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>,
+ <0 221 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ ipmmu_rt: mmu@ffc80000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xffc80000 0 0x1000>;
+ interrupts = <0 307 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/r8a7791-henninger.dts b/arch/arm/boot/dts/r8a7791-henninger.dts
new file mode 100644
index 000000000..e33e4047b
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7791-henninger.dts
@@ -0,0 +1,320 @@
+/*
+ * Device Tree Source for the Henninger board
+ *
+ * Copyright (C) 2014 Renesas Solutions Corp.
+ * Copyright (C) 2014 Cogent Embedded, 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.
+ */
+
+/dts-v1/;
+#include "r8a7791.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Henninger";
+ compatible = "renesas,henninger", "renesas,r8a7791";
+
+ aliases {
+ serial0 = &scif0;
+ };
+
+ chosen {
+ bootargs = "console=ttySC0,38400 ignore_loglevel rw root=/dev/nfs ip=dhcp";
+ stdout-path = &scif0;
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0 0x40000000 0 0x40000000>;
+ };
+
+ memory@200000000 {
+ device_type = "memory";
+ reg = <2 0x00000000 0 0x40000000>;
+ };
+
+ vcc_sdhi0: regulator@0 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "SDHI0 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vccq_sdhi0: regulator@1 {
+ compatible = "regulator-gpio";
+
+ regulator-name = "SDHI0 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio2 12 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+ states = <3300000 1
+ 1800000 0>;
+ };
+
+ vcc_sdhi2: regulator@2 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "SDHI2 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vccq_sdhi2: regulator@3 {
+ compatible = "regulator-gpio";
+
+ regulator-name = "SDHI2 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+ states = <3300000 1
+ 1800000 0>;
+ };
+};
+
+&extal_clk {
+ clock-frequency = <20000000>;
+};
+
+&pfc {
+ scif0_pins: serial0 {
+ renesas,groups = "scif0_data_d";
+ renesas,function = "scif0";
+ };
+
+ ether_pins: ether {
+ renesas,groups = "eth_link", "eth_mdio", "eth_rmii";
+ renesas,function = "eth";
+ };
+
+ phy1_pins: phy1 {
+ renesas,groups = "intc_irq0";
+ renesas,function = "intc";
+ };
+
+ sdhi0_pins: sd0 {
+ renesas,groups = "sdhi0_data4", "sdhi0_ctrl";
+ renesas,function = "sdhi0";
+ };
+
+ sdhi2_pins: sd2 {
+ renesas,groups = "sdhi2_data4", "sdhi2_ctrl";
+ renesas,function = "sdhi2";
+ };
+
+ i2c2_pins: i2c2 {
+ renesas,groups = "i2c2";
+ renesas,function = "i2c2";
+ };
+
+ qspi_pins: spi0 {
+ renesas,groups = "qspi_ctrl", "qspi_data4";
+ renesas,function = "qspi";
+ };
+
+ msiof0_pins: spi1 {
+ renesas,groups = "msiof0_clk", "msiof0_sync", "msiof0_rx",
+ "msiof0_tx";
+ renesas,function = "msiof0";
+ };
+
+ usb0_pins: usb0 {
+ renesas,groups = "usb0";
+ renesas,function = "usb0";
+ };
+
+ usb1_pins: usb1 {
+ renesas,groups = "usb1";
+ renesas,function = "usb1";
+ };
+
+ vin0_pins: vin0 {
+ renesas,groups = "vin0_data8", "vin0_clk";
+ renesas,function = "vin0";
+ };
+
+ can0_pins: can0 {
+ renesas,groups = "can0_data";
+ renesas,function = "can0";
+ };
+};
+
+&scif0 {
+ pinctrl-0 = <&scif0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&ether {
+ pinctrl-0 = <&ether_pins &phy1_pins>;
+ pinctrl-names = "default";
+
+ phy-handle = <&phy1>;
+ renesas,ether-link-active-low;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ interrupt-parent = <&irqc0>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ micrel,led-mode = <1>;
+ };
+};
+
+&sata0 {
+ status = "okay";
+};
+
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&vcc_sdhi0>;
+ vqmmc-supply = <&vccq_sdhi0>;
+ cd-gpios = <&gpio6 6 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&sdhi2 {
+ pinctrl-0 = <&sdhi2_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&vcc_sdhi2>;
+ vqmmc-supply = <&vccq_sdhi2>;
+ cd-gpios = <&gpio6 22 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-0 = <&i2c2_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+ clock-frequency = <400000>;
+
+ composite-in@20 {
+ compatible = "adi,adv7180";
+ reg = <0x20>;
+ remote = <&vin0>;
+
+ port {
+ adv7180: endpoint {
+ bus-width = <8>;
+ remote-endpoint = <&vin0ep>;
+ };
+ };
+ };
+};
+
+&qspi {
+ pinctrl-0 = <&qspi_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25fl512s";
+ reg = <0>;
+ spi-max-frequency = <30000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ m25p,fast-read;
+
+ partition@0 {
+ label = "loader_prg";
+ reg = <0x00000000 0x00040000>;
+ read-only;
+ };
+ partition@40000 {
+ label = "user_prg";
+ reg = <0x00040000 0x00400000>;
+ read-only;
+ };
+ partition@440000 {
+ label = "flash_fs";
+ reg = <0x00440000 0x03bc0000>;
+ };
+ };
+};
+
+&msiof0 {
+ pinctrl-0 = <&msiof0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ pmic@0 {
+ compatible = "renesas,r2a11302ft";
+ reg = <0>;
+ spi-max-frequency = <6000000>;
+ spi-cpol;
+ spi-cpha;
+ };
+};
+
+&pci0 {
+ status = "okay";
+ pinctrl-0 = <&usb0_pins>;
+ pinctrl-names = "default";
+};
+
+&pci1 {
+ status = "okay";
+ pinctrl-0 = <&usb1_pins>;
+ pinctrl-names = "default";
+};
+
+&hsusb {
+ status = "okay";
+ pinctrl-0 = <&usb0_pins>;
+ pinctrl-names = "default";
+ renesas,enable-gpio = <&gpio5 31 GPIO_ACTIVE_HIGH>;
+};
+
+&usbphy {
+ status = "okay";
+};
+
+&pcie_bus_clk {
+ status = "okay";
+};
+
+&pciec {
+ status = "okay";
+};
+
+/* composite video input */
+&vin0 {
+ status = "okay";
+ pinctrl-0 = <&vin0_pins>;
+ pinctrl-names = "default";
+
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vin0ep: endpoint {
+ remote-endpoint = <&adv7180>;
+ bus-width = <8>;
+ };
+ };
+};
+
+&can0 {
+ pinctrl-0 = <&can0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts
new file mode 100644
index 000000000..824ddab9c
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7791-koelsch.dts
@@ -0,0 +1,687 @@
+/*
+ * Device Tree Source for the Koelsch board
+ *
+ * Copyright (C) 2013 Renesas Electronics Corporation
+ * Copyright (C) 2013-2014 Renesas Solutions Corp.
+ * Copyright (C) 2014 Cogent Embedded, 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.
+ */
+
+/*
+ * SSI-AK4643
+ *
+ * SW1: 1: AK4643
+ * 2: CN22
+ * 3: ADV7511
+ *
+ * This command is required when Playback/Capture
+ *
+ * amixer set "LINEOUT Mixer DACL" on
+ * amixer set "DVC Out" 100%
+ * amixer set "DVC In" 100%
+ *
+ * You can use Mute
+ *
+ * amixer set "DVC Out Mute" on
+ * amixer set "DVC In Mute" on
+ *
+ * You can use Volume Ramp
+ *
+ * amixer set "DVC Out Ramp Up Rate" "0.125 dB/64 steps"
+ * amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps"
+ * amixer set "DVC Out Ramp" on
+ * aplay xxx.wav &
+ * amixer set "DVC Out" 80% // Volume Down
+ * amixer set "DVC Out" 100% // Volume Up
+ */
+
+/dts-v1/;
+#include "r8a7791.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "Koelsch";
+ compatible = "renesas,koelsch", "renesas,r8a7791";
+
+ aliases {
+ serial0 = &scif0;
+ serial1 = &scif1;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
+ stdout-path = &scif0;
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0 0x40000000 0 0x40000000>;
+ };
+
+ memory@200000000 {
+ device_type = "memory";
+ reg = <2 0x00000000 0 0x40000000>;
+ };
+
+ lbsc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ keyboard {
+ compatible = "gpio-keys";
+
+ key-1 {
+ gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_1>;
+ label = "SW2-1";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ key-2 {
+ gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_2>;
+ label = "SW2-2";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ key-3 {
+ gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_3>;
+ label = "SW2-3";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ key-4 {
+ gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_4>;
+ label = "SW2-4";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ key-a {
+ gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_A>;
+ label = "SW30";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ key-b {
+ gpios = <&gpio7 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_B>;
+ label = "SW31";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ key-c {
+ gpios = <&gpio7 2 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_C>;
+ label = "SW32";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ key-d {
+ gpios = <&gpio7 3 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_D>;
+ label = "SW33";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ key-e {
+ gpios = <&gpio7 4 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_E>;
+ label = "SW34";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ key-f {
+ gpios = <&gpio7 5 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_F>;
+ label = "SW35";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ key-g {
+ gpios = <&gpio7 6 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_G>;
+ label = "SW36";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ led6 {
+ gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ label = "LED6";
+ };
+ led7 {
+ gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>;
+ label = "LED7";
+ };
+ led8 {
+ gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
+ label = "LED8";
+ };
+ };
+
+ vcc_sdhi0: regulator@0 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "SDHI0 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&gpio7 17 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vccq_sdhi0: regulator@1 {
+ compatible = "regulator-gpio";
+
+ regulator-name = "SDHI0 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio2 12 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+ states = <3300000 1
+ 1800000 0>;
+ };
+
+ vcc_sdhi1: regulator@2 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "SDHI1 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&gpio7 18 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vccq_sdhi1: regulator@3 {
+ compatible = "regulator-gpio";
+
+ regulator-name = "SDHI1 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio2 13 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+ states = <3300000 1
+ 1800000 0>;
+ };
+
+ vcc_sdhi2: regulator@4 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "SDHI2 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&gpio7 19 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vccq_sdhi2: regulator@5 {
+ compatible = "regulator-gpio";
+
+ regulator-name = "SDHI2 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+ states = <3300000 1
+ 1800000 0>;
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+
+ simple-audio-card,format = "left_j";
+ simple-audio-card,bitclock-master = <&sndcodec>;
+ simple-audio-card,frame-master = <&sndcodec>;
+
+ sndcpu: simple-audio-card,cpu {
+ sound-dai = <&rcar_sound>;
+ };
+
+ sndcodec: simple-audio-card,codec {
+ sound-dai = <&ak4643>;
+ system-clock-frequency = <11289600>;
+ };
+ };
+
+ hdmi-out {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con: endpoint {
+ remote-endpoint = <&adv7511_out>;
+ };
+ };
+ };
+
+ x2_clk: x2-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <148500000>;
+ };
+
+ x13_clk: x13-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <148500000>;
+ };
+};
+
+&du {
+ pinctrl-0 = <&du_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ clocks = <&mstp7_clks R8A7791_CLK_DU0>,
+ <&mstp7_clks R8A7791_CLK_DU1>,
+ <&mstp7_clks R8A7791_CLK_LVDS0>,
+ <&x13_clk>, <&x2_clk>;
+ clock-names = "du.0", "du.1", "lvds.0",
+ "dclkin.0", "dclkin.1";
+
+ ports {
+ port@0 {
+ endpoint {
+ remote-endpoint = <&adv7511_in>;
+ };
+ };
+ port@1 {
+ lvds_connector: endpoint {
+ };
+ };
+ };
+};
+
+&extal_clk {
+ clock-frequency = <20000000>;
+};
+
+&pfc {
+ i2c2_pins: i2c2 {
+ renesas,groups = "i2c2";
+ renesas,function = "i2c2";
+ };
+
+ du_pins: du {
+ renesas,groups = "du_rgb666", "du_sync", "du_disp", "du_clk_out_0";
+ renesas,function = "du";
+ };
+
+ scif0_pins: serial0 {
+ renesas,groups = "scif0_data_d";
+ renesas,function = "scif0";
+ };
+
+ scif1_pins: serial1 {
+ renesas,groups = "scif1_data_d";
+ renesas,function = "scif1";
+ };
+
+ ether_pins: ether {
+ renesas,groups = "eth_link", "eth_mdio", "eth_rmii";
+ renesas,function = "eth";
+ };
+
+ phy1_pins: phy1 {
+ renesas,groups = "intc_irq0";
+ renesas,function = "intc";
+ };
+
+ sdhi0_pins: sd0 {
+ renesas,groups = "sdhi0_data4", "sdhi0_ctrl";
+ renesas,function = "sdhi0";
+ };
+
+ sdhi1_pins: sd1 {
+ renesas,groups = "sdhi1_data4", "sdhi1_ctrl";
+ renesas,function = "sdhi1";
+ };
+
+ sdhi2_pins: sd2 {
+ renesas,groups = "sdhi2_data4", "sdhi2_ctrl";
+ renesas,function = "sdhi2";
+ };
+
+ qspi_pins: spi0 {
+ renesas,groups = "qspi_ctrl", "qspi_data4";
+ renesas,function = "qspi";
+ };
+
+ msiof0_pins: spi1 {
+ renesas,groups = "msiof0_clk", "msiof0_sync", "msiof0_rx",
+ "msiof0_tx";
+ renesas,function = "msiof0";
+ };
+
+ usb0_pins: usb0 {
+ renesas,groups = "usb0";
+ renesas,function = "usb0";
+ };
+
+ usb1_pins: usb1 {
+ renesas,groups = "usb1";
+ renesas,function = "usb1";
+ };
+
+ vin1_pins: vin1 {
+ renesas,groups = "vin1_data8", "vin1_clk";
+ renesas,function = "vin1";
+ };
+
+ sound_pins: sound {
+ renesas,groups = "ssi0129_ctrl", "ssi0_data", "ssi1_data";
+ renesas,function = "ssi";
+ };
+
+ sound_clk_pins: sound_clk {
+ renesas,groups = "audio_clk_a";
+ renesas,function = "audio_clk";
+ };
+};
+
+&ether {
+ pinctrl-0 = <&ether_pins &phy1_pins>;
+ pinctrl-names = "default";
+
+ phy-handle = <&phy1>;
+ renesas,ether-link-active-low;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ interrupt-parent = <&irqc0>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ micrel,led-mode = <1>;
+ };
+};
+
+&cmt0 {
+ status = "okay";
+};
+
+&sata0 {
+ status = "okay";
+};
+
+&scif0 {
+ pinctrl-0 = <&scif0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&scif1 {
+ pinctrl-0 = <&scif1_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&vcc_sdhi0>;
+ vqmmc-supply = <&vccq_sdhi0>;
+ cd-gpios = <&gpio6 6 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&sdhi1 {
+ pinctrl-0 = <&sdhi1_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&vcc_sdhi1>;
+ vqmmc-supply = <&vccq_sdhi1>;
+ cd-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio6 15 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&sdhi2 {
+ pinctrl-0 = <&sdhi2_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&vcc_sdhi2>;
+ vqmmc-supply = <&vccq_sdhi2>;
+ cd-gpios = <&gpio6 22 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&qspi {
+ pinctrl-0 = <&qspi_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ flash: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25fl512s";
+ reg = <0>;
+ spi-max-frequency = <30000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ spi-cpha;
+ spi-cpol;
+ m25p,fast-read;
+
+ partition@0 {
+ label = "loader";
+ reg = <0x00000000 0x00080000>;
+ read-only;
+ };
+ partition@80000 {
+ label = "user";
+ reg = <0x00080000 0x00580000>;
+ read-only;
+ };
+ partition@600000 {
+ label = "flash";
+ reg = <0x00600000 0x03a00000>;
+ };
+ };
+};
+
+&msiof0 {
+ pinctrl-0 = <&msiof0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ pmic: pmic@0 {
+ compatible = "renesas,r2a11302ft";
+ reg = <0>;
+ spi-max-frequency = <6000000>;
+ spi-cpol;
+ spi-cpha;
+ };
+};
+
+&i2c2 {
+ pinctrl-0 = <&i2c2_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+ clock-frequency = <100000>;
+
+ ak4643: sound-codec@12 {
+ compatible = "asahi-kasei,ak4643";
+ #sound-dai-cells = <0>;
+ reg = <0x12>;
+ };
+
+ composite-in@20 {
+ compatible = "adi,adv7180";
+ reg = <0x20>;
+ remote = <&vin1>;
+
+ port {
+ adv7180: endpoint {
+ bus-width = <8>;
+ remote-endpoint = <&vin1ep>;
+ };
+ };
+ };
+
+ hdmi@39 {
+ compatible = "adi,adv7511w";
+ reg = <0x39>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
+
+ adi,input-depth = <8>;
+ adi,input-colorspace = "rgb";
+ adi,input-clock = "1x";
+ adi,input-style = <1>;
+ adi,input-justification = "evenly";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ adv7511_in: endpoint {
+ remote-endpoint = <&du_out_rgb>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ adv7511_out: endpoint {
+ remote-endpoint = <&hdmi_con>;
+ };
+ };
+ };
+ };
+
+ eeprom@50 {
+ compatible = "renesas,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+};
+
+&i2c6 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ pmic@58 {
+ compatible = "dlg,da9063";
+ reg = <0x58>;
+ interrupt-parent = <&irqc0>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-controller;
+
+ rtc {
+ compatible = "dlg,da9063-rtc";
+ };
+
+ wdt {
+ compatible = "dlg,da9063-watchdog";
+ };
+ };
+
+ vdd_dvfs: regulator@68 {
+ compatible = "dlg,da9210";
+ reg = <0x68>;
+ interrupt-parent = <&irqc0>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&pci0 {
+ status = "okay";
+ pinctrl-0 = <&usb0_pins>;
+ pinctrl-names = "default";
+};
+
+&pci1 {
+ status = "okay";
+ pinctrl-0 = <&usb1_pins>;
+ pinctrl-names = "default";
+};
+
+&hsusb {
+ status = "okay";
+ pinctrl-0 = <&usb0_pins>;
+ pinctrl-names = "default";
+ renesas,enable-gpio = <&gpio5 31 GPIO_ACTIVE_HIGH>;
+};
+
+&usbphy {
+ status = "okay";
+};
+
+&pcie_bus_clk {
+ status = "okay";
+};
+
+&pciec {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_dvfs>;
+};
+
+/* composite video input */
+&vin1 {
+ status = "okay";
+ pinctrl-0 = <&vin1_pins>;
+ pinctrl-names = "default";
+
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vin1ep: endpoint {
+ remote-endpoint = <&adv7180>;
+ bus-width = <8>;
+ };
+ };
+};
+
+&rcar_sound {
+ pinctrl-0 = <&sound_pins &sound_clk_pins>;
+ pinctrl-names = "default";
+
+ /* Single DAI */
+ #sound-dai-cells = <0>;
+
+ status = "okay";
+
+ rcar_sound,dai {
+ dai0 {
+ playback = <&ssi0 &src2 &dvc0>;
+ capture = <&ssi1 &src3 &dvc1>;
+ };
+ };
+};
+
+&ssi1 {
+ shared-pin;
+};
diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
new file mode 100644
index 000000000..4696062f6
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -0,0 +1,1643 @@
+/*
+ * Device Tree Source for the r8a7791 SoC
+ *
+ * Copyright (C) 2013-2015 Renesas Electronics Corporation
+ * Copyright (C) 2013-2014 Renesas Solutions Corp.
+ * Copyright (C) 2014 Cogent Embedded 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 <dt-bindings/clock/r8a7791-clock.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "renesas,r8a7791";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ i2c6 = &i2c6;
+ i2c7 = &i2c7;
+ i2c8 = &i2c8;
+ spi0 = &qspi;
+ spi1 = &msiof0;
+ spi2 = &msiof1;
+ spi3 = &msiof2;
+ vin0 = &vin0;
+ vin1 = &vin1;
+ vin2 = &vin2;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0>;
+ clock-frequency = <1500000000>;
+ voltage-tolerance = <1>; /* 1% */
+ clocks = <&cpg_clocks R8A7791_CLK_Z>;
+ clock-latency = <300000>; /* 300 us */
+
+ /* kHz - uV - OPPs unknown yet */
+ operating-points = <1500000 1000000>,
+ <1312500 1000000>,
+ <1125000 1000000>,
+ < 937500 1000000>,
+ < 750000 1000000>,
+ < 375000 1000000>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <1>;
+ clock-frequency = <1500000000>;
+ };
+ };
+
+ gic: interrupt-controller@f1001000 {
+ compatible = "arm,cortex-a15-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0 0xf1001000 0 0x1000>,
+ <0 0xf1002000 0 0x1000>,
+ <0 0xf1004000 0 0x2000>,
+ <0 0xf1006000 0 0x2000>;
+ interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ gpio0: gpio@e6050000 {
+ compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+ reg = <0 0xe6050000 0 0x50>;
+ interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 0 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7791_CLK_GPIO0>;
+ };
+
+ gpio1: gpio@e6051000 {
+ compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+ reg = <0 0xe6051000 0 0x50>;
+ interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 32 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7791_CLK_GPIO1>;
+ };
+
+ gpio2: gpio@e6052000 {
+ compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+ reg = <0 0xe6052000 0 0x50>;
+ interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 64 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7791_CLK_GPIO2>;
+ };
+
+ gpio3: gpio@e6053000 {
+ compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+ reg = <0 0xe6053000 0 0x50>;
+ interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 96 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7791_CLK_GPIO3>;
+ };
+
+ gpio4: gpio@e6054000 {
+ compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+ reg = <0 0xe6054000 0 0x50>;
+ interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 128 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7791_CLK_GPIO4>;
+ };
+
+ gpio5: gpio@e6055000 {
+ compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+ reg = <0 0xe6055000 0 0x50>;
+ interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 160 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7791_CLK_GPIO5>;
+ };
+
+ gpio6: gpio@e6055400 {
+ compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+ reg = <0 0xe6055400 0 0x50>;
+ interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 192 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7791_CLK_GPIO6>;
+ };
+
+ gpio7: gpio@e6055800 {
+ compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+ reg = <0 0xe6055800 0 0x50>;
+ interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 224 26>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7791_CLK_GPIO7>;
+ };
+
+ thermal@e61f0000 {
+ compatible = "renesas,thermal-r8a7791", "renesas,rcar-thermal";
+ reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
+ interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp5_clks R8A7791_CLK_THERMAL>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ cmt0: timer@ffca0000 {
+ compatible = "renesas,cmt-48-r8a7791", "renesas,cmt-48-gen2";
+ reg = <0 0xffca0000 0 0x1004>;
+ interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
+ <0 143 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7791_CLK_CMT0>;
+ clock-names = "fck";
+
+ renesas,channels-mask = <0x60>;
+
+ status = "disabled";
+ };
+
+ cmt1: timer@e6130000 {
+ compatible = "renesas,cmt-48-r8a7791", "renesas,cmt-48-gen2";
+ reg = <0 0xe6130000 0 0x1004>;
+ interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>,
+ <0 121 IRQ_TYPE_LEVEL_HIGH>,
+ <0 122 IRQ_TYPE_LEVEL_HIGH>,
+ <0 123 IRQ_TYPE_LEVEL_HIGH>,
+ <0 124 IRQ_TYPE_LEVEL_HIGH>,
+ <0 125 IRQ_TYPE_LEVEL_HIGH>,
+ <0 126 IRQ_TYPE_LEVEL_HIGH>,
+ <0 127 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7791_CLK_CMT1>;
+ clock-names = "fck";
+
+ renesas,channels-mask = <0xff>;
+
+ status = "disabled";
+ };
+
+ irqc0: interrupt-controller@e61c0000 {
+ compatible = "renesas,irqc-r8a7791", "renesas,irqc";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0 0xe61c0000 0 0x200>;
+ interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>,
+ <0 1 IRQ_TYPE_LEVEL_HIGH>,
+ <0 2 IRQ_TYPE_LEVEL_HIGH>,
+ <0 3 IRQ_TYPE_LEVEL_HIGH>,
+ <0 12 IRQ_TYPE_LEVEL_HIGH>,
+ <0 13 IRQ_TYPE_LEVEL_HIGH>,
+ <0 14 IRQ_TYPE_LEVEL_HIGH>,
+ <0 15 IRQ_TYPE_LEVEL_HIGH>,
+ <0 16 IRQ_TYPE_LEVEL_HIGH>,
+ <0 17 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dmac0: dma-controller@e6700000 {
+ compatible = "renesas,rcar-dmac";
+ reg = <0 0xe6700000 0 0x20000>;
+ interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH
+ 0 200 IRQ_TYPE_LEVEL_HIGH
+ 0 201 IRQ_TYPE_LEVEL_HIGH
+ 0 202 IRQ_TYPE_LEVEL_HIGH
+ 0 203 IRQ_TYPE_LEVEL_HIGH
+ 0 204 IRQ_TYPE_LEVEL_HIGH
+ 0 205 IRQ_TYPE_LEVEL_HIGH
+ 0 206 IRQ_TYPE_LEVEL_HIGH
+ 0 207 IRQ_TYPE_LEVEL_HIGH
+ 0 208 IRQ_TYPE_LEVEL_HIGH
+ 0 209 IRQ_TYPE_LEVEL_HIGH
+ 0 210 IRQ_TYPE_LEVEL_HIGH
+ 0 211 IRQ_TYPE_LEVEL_HIGH
+ 0 212 IRQ_TYPE_LEVEL_HIGH
+ 0 213 IRQ_TYPE_LEVEL_HIGH
+ 0 214 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14";
+ clocks = <&mstp2_clks R8A7791_CLK_SYS_DMAC0>;
+ clock-names = "fck";
+ #dma-cells = <1>;
+ dma-channels = <15>;
+ };
+
+ dmac1: dma-controller@e6720000 {
+ compatible = "renesas,rcar-dmac";
+ reg = <0 0xe6720000 0 0x20000>;
+ interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH
+ 0 216 IRQ_TYPE_LEVEL_HIGH
+ 0 217 IRQ_TYPE_LEVEL_HIGH
+ 0 218 IRQ_TYPE_LEVEL_HIGH
+ 0 219 IRQ_TYPE_LEVEL_HIGH
+ 0 308 IRQ_TYPE_LEVEL_HIGH
+ 0 309 IRQ_TYPE_LEVEL_HIGH
+ 0 310 IRQ_TYPE_LEVEL_HIGH
+ 0 311 IRQ_TYPE_LEVEL_HIGH
+ 0 312 IRQ_TYPE_LEVEL_HIGH
+ 0 313 IRQ_TYPE_LEVEL_HIGH
+ 0 314 IRQ_TYPE_LEVEL_HIGH
+ 0 315 IRQ_TYPE_LEVEL_HIGH
+ 0 316 IRQ_TYPE_LEVEL_HIGH
+ 0 317 IRQ_TYPE_LEVEL_HIGH
+ 0 318 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14";
+ clocks = <&mstp2_clks R8A7791_CLK_SYS_DMAC1>;
+ clock-names = "fck";
+ #dma-cells = <1>;
+ dma-channels = <15>;
+ };
+
+ audma0: dma-controller@ec700000 {
+ compatible = "renesas,rcar-dmac";
+ reg = <0 0xec700000 0 0x10000>;
+ interrupts = <0 346 IRQ_TYPE_LEVEL_HIGH
+ 0 320 IRQ_TYPE_LEVEL_HIGH
+ 0 321 IRQ_TYPE_LEVEL_HIGH
+ 0 322 IRQ_TYPE_LEVEL_HIGH
+ 0 323 IRQ_TYPE_LEVEL_HIGH
+ 0 324 IRQ_TYPE_LEVEL_HIGH
+ 0 325 IRQ_TYPE_LEVEL_HIGH
+ 0 326 IRQ_TYPE_LEVEL_HIGH
+ 0 327 IRQ_TYPE_LEVEL_HIGH
+ 0 328 IRQ_TYPE_LEVEL_HIGH
+ 0 329 IRQ_TYPE_LEVEL_HIGH
+ 0 330 IRQ_TYPE_LEVEL_HIGH
+ 0 331 IRQ_TYPE_LEVEL_HIGH
+ 0 332 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12";
+ clocks = <&mstp5_clks R8A7791_CLK_AUDIO_DMAC0>;
+ clock-names = "fck";
+ #dma-cells = <1>;
+ dma-channels = <13>;
+ };
+
+ audma1: dma-controller@ec720000 {
+ compatible = "renesas,rcar-dmac";
+ reg = <0 0xec720000 0 0x10000>;
+ interrupts = <0 347 IRQ_TYPE_LEVEL_HIGH
+ 0 333 IRQ_TYPE_LEVEL_HIGH
+ 0 334 IRQ_TYPE_LEVEL_HIGH
+ 0 335 IRQ_TYPE_LEVEL_HIGH
+ 0 336 IRQ_TYPE_LEVEL_HIGH
+ 0 337 IRQ_TYPE_LEVEL_HIGH
+ 0 338 IRQ_TYPE_LEVEL_HIGH
+ 0 339 IRQ_TYPE_LEVEL_HIGH
+ 0 340 IRQ_TYPE_LEVEL_HIGH
+ 0 341 IRQ_TYPE_LEVEL_HIGH
+ 0 342 IRQ_TYPE_LEVEL_HIGH
+ 0 343 IRQ_TYPE_LEVEL_HIGH
+ 0 344 IRQ_TYPE_LEVEL_HIGH
+ 0 345 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12";
+ clocks = <&mstp5_clks R8A7791_CLK_AUDIO_DMAC1>;
+ clock-names = "fck";
+ #dma-cells = <1>;
+ dma-channels = <13>;
+ };
+
+ /* The memory map in the User's Manual maps the cores to bus numbers */
+ i2c0: i2c@e6508000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7791";
+ reg = <0 0xe6508000 0 0x40>;
+ interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7791_CLK_I2C0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@e6518000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7791";
+ reg = <0 0xe6518000 0 0x40>;
+ interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7791_CLK_I2C1>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@e6530000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7791";
+ reg = <0 0xe6530000 0 0x40>;
+ interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7791_CLK_I2C2>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@e6540000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7791";
+ reg = <0 0xe6540000 0 0x40>;
+ interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7791_CLK_I2C3>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@e6520000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7791";
+ reg = <0 0xe6520000 0 0x40>;
+ interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7791_CLK_I2C4>;
+ status = "disabled";
+ };
+
+ i2c5: i2c@e6528000 {
+ /* doesn't need pinmux */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7791";
+ reg = <0 0xe6528000 0 0x40>;
+ interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7791_CLK_I2C5>;
+ status = "disabled";
+ };
+
+ i2c6: i2c@e60b0000 {
+ /* doesn't need pinmux */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a7791", "renesas,rmobile-iic";
+ reg = <0 0xe60b0000 0 0x425>;
+ interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7791_CLK_IICDVFS>;
+ dmas = <&dmac0 0x77>, <&dmac0 0x78>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ i2c7: i2c@e6500000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a7791", "renesas,rmobile-iic";
+ reg = <0 0xe6500000 0 0x425>;
+ interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7791_CLK_IIC0>;
+ dmas = <&dmac0 0x61>, <&dmac0 0x62>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ i2c8: i2c@e6510000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a7791", "renesas,rmobile-iic";
+ reg = <0 0xe6510000 0 0x425>;
+ interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7791_CLK_IIC1>;
+ dmas = <&dmac0 0x65>, <&dmac0 0x66>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ pfc: pfc@e6060000 {
+ compatible = "renesas,pfc-r8a7791";
+ reg = <0 0xe6060000 0 0x250>;
+ #gpio-range-cells = <3>;
+ };
+
+ mmcif0: mmc@ee200000 {
+ compatible = "renesas,mmcif-r8a7791", "renesas,sh-mmcif";
+ reg = <0 0xee200000 0 0x80>;
+ interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7791_CLK_MMCIF0>;
+ dmas = <&dmac0 0xd1>, <&dmac0 0xd2>;
+ dma-names = "tx", "rx";
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ sdhi0: sd@ee100000 {
+ compatible = "renesas,sdhi-r8a7791";
+ reg = <0 0xee100000 0 0x328>;
+ interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7791_CLK_SDHI0>;
+ dmas = <&dmac1 0xcd>, <&dmac1 0xce>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ sdhi1: sd@ee140000 {
+ compatible = "renesas,sdhi-r8a7791";
+ reg = <0 0xee140000 0 0x100>;
+ interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7791_CLK_SDHI1>;
+ dmas = <&dmac1 0xc1>, <&dmac1 0xc2>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ sdhi2: sd@ee160000 {
+ compatible = "renesas,sdhi-r8a7791";
+ reg = <0 0xee160000 0 0x100>;
+ interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7791_CLK_SDHI2>;
+ dmas = <&dmac1 0xd3>, <&dmac1 0xd4>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ scifa0: serial@e6c40000 {
+ compatible = "renesas,scifa-r8a7791", "renesas,scifa";
+ reg = <0 0xe6c40000 0 64>;
+ interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7791_CLK_SCIFA0>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifa1: serial@e6c50000 {
+ compatible = "renesas,scifa-r8a7791", "renesas,scifa";
+ reg = <0 0xe6c50000 0 64>;
+ interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7791_CLK_SCIFA1>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifa2: serial@e6c60000 {
+ compatible = "renesas,scifa-r8a7791", "renesas,scifa";
+ reg = <0 0xe6c60000 0 64>;
+ interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7791_CLK_SCIFA2>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifa3: serial@e6c70000 {
+ compatible = "renesas,scifa-r8a7791", "renesas,scifa";
+ reg = <0 0xe6c70000 0 64>;
+ interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp11_clks R8A7791_CLK_SCIFA3>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifa4: serial@e6c78000 {
+ compatible = "renesas,scifa-r8a7791", "renesas,scifa";
+ reg = <0 0xe6c78000 0 64>;
+ interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp11_clks R8A7791_CLK_SCIFA4>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifa5: serial@e6c80000 {
+ compatible = "renesas,scifa-r8a7791", "renesas,scifa";
+ reg = <0 0xe6c80000 0 64>;
+ interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp11_clks R8A7791_CLK_SCIFA5>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifb0: serial@e6c20000 {
+ compatible = "renesas,scifb-r8a7791", "renesas,scifb";
+ reg = <0 0xe6c20000 0 64>;
+ interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7791_CLK_SCIFB0>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifb1: serial@e6c30000 {
+ compatible = "renesas,scifb-r8a7791", "renesas,scifb";
+ reg = <0 0xe6c30000 0 64>;
+ interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7791_CLK_SCIFB1>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifb2: serial@e6ce0000 {
+ compatible = "renesas,scifb-r8a7791", "renesas,scifb";
+ reg = <0 0xe6ce0000 0 64>;
+ interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7791_CLK_SCIFB2>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif0: serial@e6e60000 {
+ compatible = "renesas,scif-r8a7791", "renesas,scif";
+ reg = <0 0xe6e60000 0 64>;
+ interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7791_CLK_SCIF0>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif1: serial@e6e68000 {
+ compatible = "renesas,scif-r8a7791", "renesas,scif";
+ reg = <0 0xe6e68000 0 64>;
+ interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7791_CLK_SCIF1>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif2: serial@e6e58000 {
+ compatible = "renesas,scif-r8a7791", "renesas,scif";
+ reg = <0 0xe6e58000 0 64>;
+ interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7791_CLK_SCIF2>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif3: serial@e6ea8000 {
+ compatible = "renesas,scif-r8a7791", "renesas,scif";
+ reg = <0 0xe6ea8000 0 64>;
+ interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7791_CLK_SCIF3>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif4: serial@e6ee0000 {
+ compatible = "renesas,scif-r8a7791", "renesas,scif";
+ reg = <0 0xe6ee0000 0 64>;
+ interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7791_CLK_SCIF4>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif5: serial@e6ee8000 {
+ compatible = "renesas,scif-r8a7791", "renesas,scif";
+ reg = <0 0xe6ee8000 0 64>;
+ interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7791_CLK_SCIF5>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ hscif0: serial@e62c0000 {
+ compatible = "renesas,hscif-r8a7791", "renesas,hscif";
+ reg = <0 0xe62c0000 0 96>;
+ interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7791_CLK_HSCIF0>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ hscif1: serial@e62c8000 {
+ compatible = "renesas,hscif-r8a7791", "renesas,hscif";
+ reg = <0 0xe62c8000 0 96>;
+ interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7791_CLK_HSCIF1>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ hscif2: serial@e62d0000 {
+ compatible = "renesas,hscif-r8a7791", "renesas,hscif";
+ reg = <0 0xe62d0000 0 96>;
+ interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7791_CLK_HSCIF2>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ ether: ethernet@ee700000 {
+ compatible = "renesas,ether-r8a7791";
+ reg = <0 0xee700000 0 0x400>;
+ interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp8_clks R8A7791_CLK_ETHER>;
+ phy-mode = "rmii";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ sata0: sata@ee300000 {
+ compatible = "renesas,sata-r8a7791";
+ reg = <0 0xee300000 0 0x2000>;
+ interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp8_clks R8A7791_CLK_SATA0>;
+ status = "disabled";
+ };
+
+ sata1: sata@ee500000 {
+ compatible = "renesas,sata-r8a7791";
+ reg = <0 0xee500000 0 0x2000>;
+ interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp8_clks R8A7791_CLK_SATA1>;
+ status = "disabled";
+ };
+
+ hsusb: usb@e6590000 {
+ compatible = "renesas,usbhs-r8a7791";
+ reg = <0 0xe6590000 0 0x100>;
+ interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7791_CLK_HSUSB>;
+ renesas,buswait = <4>;
+ phys = <&usb0 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ usbphy: usb-phy@e6590100 {
+ compatible = "renesas,usb-phy-r8a7791";
+ reg = <0 0xe6590100 0 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mstp7_clks R8A7791_CLK_HSUSB>;
+ clock-names = "usbhs";
+ status = "disabled";
+
+ usb0: usb-channel@0 {
+ reg = <0>;
+ #phy-cells = <1>;
+ };
+ usb2: usb-channel@2 {
+ reg = <2>;
+ #phy-cells = <1>;
+ };
+ };
+
+ vin0: video@e6ef0000 {
+ compatible = "renesas,vin-r8a7791";
+ clocks = <&mstp8_clks R8A7791_CLK_VIN0>;
+ reg = <0 0xe6ef0000 0 0x1000>;
+ interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ vin1: video@e6ef1000 {
+ compatible = "renesas,vin-r8a7791";
+ clocks = <&mstp8_clks R8A7791_CLK_VIN1>;
+ reg = <0 0xe6ef1000 0 0x1000>;
+ interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ vin2: video@e6ef2000 {
+ compatible = "renesas,vin-r8a7791";
+ clocks = <&mstp8_clks R8A7791_CLK_VIN2>;
+ reg = <0 0xe6ef2000 0 0x1000>;
+ interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ vsp1@fe928000 {
+ compatible = "renesas,vsp1";
+ reg = <0 0xfe928000 0 0x8000>;
+ interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7791_CLK_VSP1_S>;
+
+ renesas,has-lut;
+ renesas,has-sru;
+ renesas,#rpf = <5>;
+ renesas,#uds = <3>;
+ renesas,#wpf = <4>;
+ };
+
+ vsp1@fe930000 {
+ compatible = "renesas,vsp1";
+ reg = <0 0xfe930000 0 0x8000>;
+ interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU0>;
+
+ renesas,has-lif;
+ renesas,has-lut;
+ renesas,#rpf = <4>;
+ renesas,#uds = <1>;
+ renesas,#wpf = <4>;
+ };
+
+ vsp1@fe938000 {
+ compatible = "renesas,vsp1";
+ reg = <0 0xfe938000 0 0x8000>;
+ interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU1>;
+
+ renesas,has-lif;
+ renesas,has-lut;
+ renesas,#rpf = <4>;
+ renesas,#uds = <1>;
+ renesas,#wpf = <4>;
+ };
+
+ du: display@feb00000 {
+ compatible = "renesas,du-r8a7791";
+ reg = <0 0xfeb00000 0 0x40000>,
+ <0 0xfeb90000 0 0x1c>;
+ reg-names = "du", "lvds.0";
+ interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>,
+ <0 268 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7791_CLK_DU0>,
+ <&mstp7_clks R8A7791_CLK_DU1>,
+ <&mstp7_clks R8A7791_CLK_LVDS0>;
+ clock-names = "du.0", "du.1", "lvds.0";
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ du_out_rgb: endpoint {
+ };
+ };
+ port@1 {
+ reg = <1>;
+ du_out_lvds0: endpoint {
+ };
+ };
+ };
+ };
+
+ can0: can@e6e80000 {
+ compatible = "renesas,can-r8a7791";
+ reg = <0 0xe6e80000 0 0x1000>;
+ interrupts = <0 186 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7791_CLK_RCAN0>,
+ <&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>;
+ clock-names = "clkp1", "clkp2", "can_clk";
+ status = "disabled";
+ };
+
+ can1: can@e6e88000 {
+ compatible = "renesas,can-r8a7791";
+ reg = <0 0xe6e88000 0 0x1000>;
+ interrupts = <0 187 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7791_CLK_RCAN1>,
+ <&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>;
+ clock-names = "clkp1", "clkp2", "can_clk";
+ status = "disabled";
+ };
+
+ clocks {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* External root clock */
+ extal_clk: extal_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overriden by the board. */
+ clock-frequency = <0>;
+ clock-output-names = "extal";
+ };
+
+ /*
+ * The external audio clocks are configured as 0 Hz fixed frequency clocks by
+ * default. Boards that provide audio clocks should override them.
+ */
+ audio_clk_a: audio_clk_a {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "audio_clk_a";
+ };
+ audio_clk_b: audio_clk_b {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "audio_clk_b";
+ };
+ audio_clk_c: audio_clk_c {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "audio_clk_c";
+ };
+
+ /* External PCIe clock - can be overridden by the board */
+ pcie_bus_clk: pcie_bus_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ clock-output-names = "pcie_bus";
+ status = "disabled";
+ };
+
+ /* External USB clock - can be overridden by the board */
+ usb_extal_clk: usb_extal_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <48000000>;
+ clock-output-names = "usb_extal";
+ };
+
+ /* External CAN clock */
+ can_clk: can_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ clock-output-names = "can_clk";
+ status = "disabled";
+ };
+
+ /* Special CPG clocks */
+ cpg_clocks: cpg_clocks@e6150000 {
+ compatible = "renesas,r8a7791-cpg-clocks",
+ "renesas,rcar-gen2-cpg-clocks";
+ reg = <0 0xe6150000 0 0x1000>;
+ clocks = <&extal_clk &usb_extal_clk>;
+ #clock-cells = <1>;
+ clock-output-names = "main", "pll0", "pll1", "pll3",
+ "lb", "qspi", "sdh", "sd0", "z",
+ "rcan", "adsp";
+ };
+
+ /* Variable factor clocks */
+ sd2_clk: sd2_clk@e6150078 {
+ compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150078 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sd2";
+ };
+ sd3_clk: sd3_clk@e615026c {
+ compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe615026c 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sd3";
+ };
+ mmc0_clk: mmc0_clk@e6150240 {
+ compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150240 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "mmc0";
+ };
+ ssp_clk: ssp_clk@e6150248 {
+ compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150248 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "ssp";
+ };
+ ssprs_clk: ssprs_clk@e615024c {
+ compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe615024c 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "ssprs";
+ };
+
+ /* Fixed factor clocks */
+ pll1_div2_clk: pll1_div2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "pll1_div2";
+ };
+ zg_clk: zg_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <3>;
+ clock-mult = <1>;
+ clock-output-names = "zg";
+ };
+ zx_clk: zx_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <3>;
+ clock-mult = <1>;
+ clock-output-names = "zx";
+ };
+ zs_clk: zs_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <6>;
+ clock-mult = <1>;
+ clock-output-names = "zs";
+ };
+ hp_clk: hp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <12>;
+ clock-mult = <1>;
+ clock-output-names = "hp";
+ };
+ i_clk: i_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "i";
+ };
+ b_clk: b_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <12>;
+ clock-mult = <1>;
+ clock-output-names = "b";
+ };
+ p_clk: p_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <24>;
+ clock-mult = <1>;
+ clock-output-names = "p";
+ };
+ cl_clk: cl_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <48>;
+ clock-mult = <1>;
+ clock-output-names = "cl";
+ };
+ m2_clk: m2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "m2";
+ };
+ imp_clk: imp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clock-output-names = "imp";
+ };
+ rclk_clk: rclk_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <(48 * 1024)>;
+ clock-mult = <1>;
+ clock-output-names = "rclk";
+ };
+ oscclk_clk: oscclk_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <(12 * 1024)>;
+ clock-mult = <1>;
+ clock-output-names = "oscclk";
+ };
+ zb3_clk: zb3_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL3>;
+ #clock-cells = <0>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clock-output-names = "zb3";
+ };
+ zb3d2_clk: zb3d2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL3>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "zb3d2";
+ };
+ ddr_clk: ddr_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL3>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "ddr";
+ };
+ mp_clk: mp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-div = <15>;
+ clock-mult = <1>;
+ clock-output-names = "mp";
+ };
+ cp_clk: cp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&extal_clk>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "cp";
+ };
+
+ /* Gate clocks */
+ mstp0_clks: mstp0_clks@e6150130 {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150130 0 4>, <0 0xe6150030 0 4>;
+ clocks = <&mp_clk>;
+ #clock-cells = <1>;
+ clock-indices = <R8A7791_CLK_MSIOF0>;
+ clock-output-names = "msiof0";
+ };
+ mstp1_clks: mstp1_clks@e6150134 {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>;
+ clocks = <&zs_clk>, <&zs_clk>, <&m2_clk>, <&zs_clk>, <&p_clk>,
+ <&zg_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>, <&p_clk>,
+ <&p_clk>, <&rclk_clk>, <&cp_clk>, <&zs_clk>, <&zs_clk>,
+ <&zs_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7791_CLK_VCP0 R8A7791_CLK_VPC0 R8A7791_CLK_JPU
+ R8A7791_CLK_SSP1 R8A7791_CLK_TMU1 R8A7791_CLK_3DG
+ R8A7791_CLK_2DDMAC R8A7791_CLK_FDP1_1 R8A7791_CLK_FDP1_0
+ R8A7791_CLK_TMU3 R8A7791_CLK_TMU2 R8A7791_CLK_CMT0
+ R8A7791_CLK_TMU0 R8A7791_CLK_VSP1_DU1 R8A7791_CLK_VSP1_DU0
+ R8A7791_CLK_VSP1_S
+ >;
+ clock-output-names =
+ "vcp0", "vpc0", "jpu", "ssp1", "tmu1", "3dg",
+ "2ddmac", "fdp1-1", "fdp1-0", "tmu3", "tmu2", "cmt0",
+ "tmu0", "vsp1-du1", "vsp1-du0", "vsp1-sy";
+ };
+ mstp2_clks: mstp2_clks@e6150138 {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
+ clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>,
+ <&mp_clk>, <&mp_clk>, <&mp_clk>,
+ <&zs_clk>, <&zs_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7791_CLK_SCIFA2 R8A7791_CLK_SCIFA1 R8A7791_CLK_SCIFA0
+ R8A7791_CLK_MSIOF2 R8A7791_CLK_SCIFB0 R8A7791_CLK_SCIFB1
+ R8A7791_CLK_MSIOF1 R8A7791_CLK_SCIFB2
+ R8A7791_CLK_SYS_DMAC1 R8A7791_CLK_SYS_DMAC0
+ >;
+ clock-output-names =
+ "scifa2", "scifa1", "scifa0", "msiof2", "scifb0",
+ "scifb1", "msiof1", "scifb2",
+ "sys-dmac1", "sys-dmac0";
+ };
+ mstp3_clks: mstp3_clks@e615013c {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
+ clocks = <&cp_clk>, <&sd3_clk>, <&sd2_clk>, <&cpg_clocks R8A7791_CLK_SD0>,
+ <&mmc0_clk>, <&hp_clk>, <&mp_clk>, <&hp_clk>, <&mp_clk>, <&rclk_clk>,
+ <&hp_clk>, <&hp_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7791_CLK_TPU0 R8A7791_CLK_SDHI2 R8A7791_CLK_SDHI1 R8A7791_CLK_SDHI0
+ R8A7791_CLK_MMCIF0 R8A7791_CLK_IIC0 R8A7791_CLK_PCIEC R8A7791_CLK_IIC1
+ R8A7791_CLK_SSUSB R8A7791_CLK_CMT1
+ R8A7791_CLK_USBDMAC0 R8A7791_CLK_USBDMAC1
+ >;
+ clock-output-names =
+ "tpu0", "sdhi2", "sdhi1", "sdhi0",
+ "mmcif0", "i2c7", "pciec", "i2c8", "ssusb", "cmt1",
+ "usbdmac0", "usbdmac1";
+ };
+ mstp5_clks: mstp5_clks@e6150144 {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>;
+ clocks = <&hp_clk>, <&hp_clk>, <&cpg_clocks R8A7791_CLK_ADSP>,
+ <&extal_clk>, <&p_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7791_CLK_AUDIO_DMAC0 R8A7791_CLK_AUDIO_DMAC1
+ R8A7791_CLK_ADSP_MOD R8A7791_CLK_THERMAL
+ R8A7791_CLK_PWM
+ >;
+ clock-output-names = "audmac0", "audmac1", "adsp_mod",
+ "thermal", "pwm";
+ };
+ mstp7_clks: mstp7_clks@e615014c {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe615014c 0 4>, <0 0xe61501c4 0 4>;
+ clocks = <&mp_clk>, <&hp_clk>, <&zs_clk>, <&p_clk>, <&p_clk>, <&zs_clk>,
+ <&zs_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
+ <&zx_clk>, <&zx_clk>, <&zx_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7791_CLK_EHCI R8A7791_CLK_HSUSB R8A7791_CLK_HSCIF2 R8A7791_CLK_SCIF5
+ R8A7791_CLK_SCIF4 R8A7791_CLK_HSCIF1 R8A7791_CLK_HSCIF0
+ R8A7791_CLK_SCIF3 R8A7791_CLK_SCIF2 R8A7791_CLK_SCIF1
+ R8A7791_CLK_SCIF0 R8A7791_CLK_DU1 R8A7791_CLK_DU0
+ R8A7791_CLK_LVDS0
+ >;
+ clock-output-names =
+ "ehci", "hsusb", "hscif2", "scif5", "scif4", "hscif1", "hscif0",
+ "scif3", "scif2", "scif1", "scif0", "du1", "du0", "lvds0";
+ };
+ mstp8_clks: mstp8_clks@e6150990 {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>;
+ clocks = <&zx_clk>, <&hp_clk>, <&zg_clk>, <&zg_clk>,
+ <&zg_clk>, <&p_clk>, <&zs_clk>, <&zs_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7791_CLK_IPMMU_SGX R8A7791_CLK_MLB
+ R8A7791_CLK_VIN2 R8A7791_CLK_VIN1 R8A7791_CLK_VIN0
+ R8A7791_CLK_ETHER R8A7791_CLK_SATA1 R8A7791_CLK_SATA0
+ >;
+ clock-output-names =
+ "ipmmu_sgx", "mlb", "vin2", "vin1", "vin0", "ether",
+ "sata1", "sata0";
+ };
+ mstp9_clks: mstp9_clks@e6150994 {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>;
+ clocks = <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>,
+ <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>,
+ <&p_clk>, <&p_clk>, <&cpg_clocks R8A7791_CLK_QSPI>, <&hp_clk>,
+ <&cp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>,
+ <&hp_clk>, <&hp_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7791_CLK_GPIO7 R8A7791_CLK_GPIO6 R8A7791_CLK_GPIO5 R8A7791_CLK_GPIO4
+ R8A7791_CLK_GPIO3 R8A7791_CLK_GPIO2 R8A7791_CLK_GPIO1 R8A7791_CLK_GPIO0
+ R8A7791_CLK_RCAN1 R8A7791_CLK_RCAN0 R8A7791_CLK_QSPI_MOD R8A7791_CLK_I2C5
+ R8A7791_CLK_IICDVFS R8A7791_CLK_I2C4 R8A7791_CLK_I2C3 R8A7791_CLK_I2C2
+ R8A7791_CLK_I2C1 R8A7791_CLK_I2C0
+ >;
+ clock-output-names =
+ "gpio7", "gpio6", "gpio5", "gpio4", "gpio3", "gpio2", "gpio1", "gpio0",
+ "rcan1", "rcan0", "qspi_mod", "i2c5", "i2c6", "i2c4", "i2c3", "i2c2",
+ "i2c1", "i2c0";
+ };
+ mstp10_clks: mstp10_clks@e6150998 {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150998 0 4>, <0 0xe61509a8 0 4>;
+ clocks = <&p_clk>,
+ <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
+ <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
+ <&p_clk>,
+ <&mstp10_clks R8A7791_CLK_SCU_ALL>, <&mstp10_clks R8A7791_CLK_SCU_ALL>,
+ <&mstp10_clks R8A7791_CLK_SCU_ALL>, <&mstp10_clks R8A7791_CLK_SCU_ALL>,
+ <&mstp10_clks R8A7791_CLK_SCU_ALL>, <&mstp10_clks R8A7791_CLK_SCU_ALL>,
+ <&mstp10_clks R8A7791_CLK_SCU_ALL>, <&mstp10_clks R8A7791_CLK_SCU_ALL>,
+ <&mstp10_clks R8A7791_CLK_SCU_ALL>, <&mstp10_clks R8A7791_CLK_SCU_ALL>,
+ <&mstp10_clks R8A7791_CLK_SCU_ALL>, <&mstp10_clks R8A7791_CLK_SCU_ALL>;
+
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7791_CLK_SSI_ALL
+ R8A7791_CLK_SSI9 R8A7791_CLK_SSI8 R8A7791_CLK_SSI7 R8A7791_CLK_SSI6 R8A7791_CLK_SSI5
+ R8A7791_CLK_SSI4 R8A7791_CLK_SSI3 R8A7791_CLK_SSI2 R8A7791_CLK_SSI1 R8A7791_CLK_SSI0
+ R8A7791_CLK_SCU_ALL
+ R8A7791_CLK_SCU_DVC1 R8A7791_CLK_SCU_DVC0
+ R8A7791_CLK_SCU_SRC9 R8A7791_CLK_SCU_SRC8 R8A7791_CLK_SCU_SRC7 R8A7791_CLK_SCU_SRC6 R8A7791_CLK_SCU_SRC5
+ R8A7791_CLK_SCU_SRC4 R8A7791_CLK_SCU_SRC3 R8A7791_CLK_SCU_SRC2 R8A7791_CLK_SCU_SRC1 R8A7791_CLK_SCU_SRC0
+ >;
+ clock-output-names =
+ "ssi-all",
+ "ssi9", "ssi8", "ssi7", "ssi6", "ssi5",
+ "ssi4", "ssi3", "ssi2", "ssi1", "ssi0",
+ "scu-all",
+ "scu-dvc1", "scu-dvc0",
+ "scu-src9", "scu-src8", "scu-src7", "scu-src6", "scu-src5",
+ "scu-src4", "scu-src3", "scu-src2", "scu-src1", "scu-src0";
+ };
+ mstp11_clks: mstp11_clks@e615099c {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe615099c 0 4>, <0 0xe61509ac 0 4>;
+ clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7791_CLK_SCIFA3 R8A7791_CLK_SCIFA4 R8A7791_CLK_SCIFA5
+ >;
+ clock-output-names = "scifa3", "scifa4", "scifa5";
+ };
+ };
+
+ qspi: spi@e6b10000 {
+ compatible = "renesas,qspi-r8a7791", "renesas,qspi";
+ reg = <0 0xe6b10000 0 0x2c>;
+ interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7791_CLK_QSPI_MOD>;
+ dmas = <&dmac0 0x17>, <&dmac0 0x18>;
+ dma-names = "tx", "rx";
+ num-cs = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof0: spi@e6e20000 {
+ compatible = "renesas,msiof-r8a7791";
+ reg = <0 0xe6e20000 0 0x0064>, <0 0xe7e20000 0 0x0064>;
+ interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>;
+ dmas = <&dmac0 0x51>, <&dmac0 0x52>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof1: spi@e6e10000 {
+ compatible = "renesas,msiof-r8a7791";
+ reg = <0 0xe6e10000 0 0x0064>, <0 0xe7e10000 0 0x0064>;
+ interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7791_CLK_MSIOF1>;
+ dmas = <&dmac0 0x55>, <&dmac0 0x56>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof2: spi@e6e00000 {
+ compatible = "renesas,msiof-r8a7791";
+ reg = <0 0xe6e00000 0 0x0064>, <0 0xe7e00000 0 0x0064>;
+ interrupts = <0 158 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7791_CLK_MSIOF2>;
+ dmas = <&dmac0 0x41>, <&dmac0 0x42>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ xhci: usb@ee000000 {
+ compatible = "renesas,xhci-r8a7791";
+ reg = <0 0xee000000 0 0xc00>;
+ interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7791_CLK_SSUSB>;
+ phys = <&usb2 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ pci0: pci@ee090000 {
+ compatible = "renesas,pci-r8a7791";
+ device_type = "pci";
+ clocks = <&mstp7_clks R8A7791_CLK_EHCI>;
+ reg = <0 0xee090000 0 0xc00>,
+ <0 0xee080000 0 0x1100>;
+ interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+
+ bus-range = <0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
+ interrupt-map-mask = <0xff00 0 0 0x7>;
+ interrupt-map = <0x0000 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH
+ 0x0800 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH
+ 0x1000 0 0 2 &gic 0 108 IRQ_TYPE_LEVEL_HIGH>;
+
+ usb@0,1 {
+ reg = <0x800 0 0 0 0>;
+ device_type = "pci";
+ phys = <&usb0 0>;
+ phy-names = "usb";
+ };
+
+ usb@0,2 {
+ reg = <0x1000 0 0 0 0>;
+ device_type = "pci";
+ phys = <&usb0 0>;
+ phy-names = "usb";
+ };
+ };
+
+ pci1: pci@ee0d0000 {
+ compatible = "renesas,pci-r8a7791";
+ device_type = "pci";
+ clocks = <&mstp7_clks R8A7791_CLK_EHCI>;
+ reg = <0 0xee0d0000 0 0xc00>,
+ <0 0xee0c0000 0 0x1100>;
+ interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+
+ bus-range = <1 1>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
+ interrupt-map-mask = <0xff00 0 0 0x7>;
+ interrupt-map = <0x0000 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH
+ 0x0800 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH
+ 0x1000 0 0 2 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>;
+
+ usb@0,1 {
+ reg = <0x800 0 0 0 0>;
+ device_type = "pci";
+ phys = <&usb2 0>;
+ phy-names = "usb";
+ };
+
+ usb@0,2 {
+ reg = <0x1000 0 0 0 0>;
+ device_type = "pci";
+ phys = <&usb2 0>;
+ phy-names = "usb";
+ };
+ };
+
+ pciec: pcie@fe000000 {
+ compatible = "renesas,pcie-r8a7791";
+ reg = <0 0xfe000000 0 0x80000>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x00 0xff>;
+ device_type = "pci";
+ ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000
+ 0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000
+ 0x02000000 0 0x30000000 0 0x30000000 0 0x08000000
+ 0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
+ /* Map all possible DDR as inbound ranges */
+ dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000
+ 0x43000000 2 0x00000000 2 0x00000000 1 0x00000000>;
+ interrupts = <0 116 IRQ_TYPE_LEVEL_HIGH>,
+ <0 117 IRQ_TYPE_LEVEL_HIGH>,
+ <0 118 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic 0 116 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7791_CLK_PCIEC>, <&pcie_bus_clk>;
+ clock-names = "pcie", "pcie_bus";
+ status = "disabled";
+ };
+
+ ipmmu_sy0: mmu@e6280000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xe6280000 0 0x1000>;
+ interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>,
+ <0 224 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ ipmmu_sy1: mmu@e6290000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xe6290000 0 0x1000>;
+ interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ ipmmu_ds: mmu@e6740000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xe6740000 0 0x1000>;
+ interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>,
+ <0 199 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ ipmmu_mp: mmu@ec680000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xec680000 0 0x1000>;
+ interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ ipmmu_mx: mmu@fe951000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xfe951000 0 0x1000>;
+ interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>,
+ <0 221 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ ipmmu_rt: mmu@ffc80000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xffc80000 0 0x1000>;
+ interrupts = <0 307 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ ipmmu_gp: mmu@e62a0000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xe62a0000 0 0x1000>;
+ interrupts = <0 260 IRQ_TYPE_LEVEL_HIGH>,
+ <0 261 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ rcar_sound: rcar_sound@ec500000 {
+ /*
+ * #sound-dai-cells is required
+ *
+ * Single DAI : #sound-dai-cells = <0>; <&rcar_sound>;
+ * Multi DAI : #sound-dai-cells = <1>; <&rcar_sound N>;
+ */
+ compatible = "renesas,rcar_sound-r8a7791", "renesas,rcar_sound-gen2";
+ reg = <0 0xec500000 0 0x1000>, /* SCU */
+ <0 0xec5a0000 0 0x100>, /* ADG */
+ <0 0xec540000 0 0x1000>, /* SSIU */
+ <0 0xec541000 0 0x1280>, /* SSI */
+ <0 0xec740000 0 0x200>; /* Audio DMAC peri peri*/
+ reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
+
+ clocks = <&mstp10_clks R8A7791_CLK_SSI_ALL>,
+ <&mstp10_clks R8A7791_CLK_SSI9>, <&mstp10_clks R8A7791_CLK_SSI8>,
+ <&mstp10_clks R8A7791_CLK_SSI7>, <&mstp10_clks R8A7791_CLK_SSI6>,
+ <&mstp10_clks R8A7791_CLK_SSI5>, <&mstp10_clks R8A7791_CLK_SSI4>,
+ <&mstp10_clks R8A7791_CLK_SSI3>, <&mstp10_clks R8A7791_CLK_SSI2>,
+ <&mstp10_clks R8A7791_CLK_SSI1>, <&mstp10_clks R8A7791_CLK_SSI0>,
+ <&mstp10_clks R8A7791_CLK_SCU_SRC9>, <&mstp10_clks R8A7791_CLK_SCU_SRC8>,
+ <&mstp10_clks R8A7791_CLK_SCU_SRC7>, <&mstp10_clks R8A7791_CLK_SCU_SRC6>,
+ <&mstp10_clks R8A7791_CLK_SCU_SRC5>, <&mstp10_clks R8A7791_CLK_SCU_SRC4>,
+ <&mstp10_clks R8A7791_CLK_SCU_SRC3>, <&mstp10_clks R8A7791_CLK_SCU_SRC2>,
+ <&mstp10_clks R8A7791_CLK_SCU_SRC1>, <&mstp10_clks R8A7791_CLK_SCU_SRC0>,
+ <&mstp10_clks R8A7791_CLK_SCU_DVC0>, <&mstp10_clks R8A7791_CLK_SCU_DVC1>,
+ <&audio_clk_a>, <&audio_clk_b>, <&audio_clk_c>, <&m2_clk>;
+ clock-names = "ssi-all",
+ "ssi.9", "ssi.8", "ssi.7", "ssi.6", "ssi.5",
+ "ssi.4", "ssi.3", "ssi.2", "ssi.1", "ssi.0",
+ "src.9", "src.8", "src.7", "src.6", "src.5",
+ "src.4", "src.3", "src.2", "src.1", "src.0",
+ "dvc.0", "dvc.1",
+ "clk_a", "clk_b", "clk_c", "clk_i";
+
+ status = "disabled";
+
+ rcar_sound,dvc {
+ dvc0: dvc@0 {
+ dmas = <&audma0 0xbc>;
+ dma-names = "tx";
+ };
+ dvc1: dvc@1 {
+ dmas = <&audma0 0xbe>;
+ dma-names = "tx";
+ };
+ };
+
+ rcar_sound,src {
+ src0: src@0 {
+ interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x85>, <&audma1 0x9a>;
+ dma-names = "rx", "tx";
+ };
+ src1: src@1 {
+ interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x87>, <&audma1 0x9c>;
+ dma-names = "rx", "tx";
+ };
+ src2: src@2 {
+ interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x89>, <&audma1 0x9e>;
+ dma-names = "rx", "tx";
+ };
+ src3: src@3 {
+ interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x8b>, <&audma1 0xa0>;
+ dma-names = "rx", "tx";
+ };
+ src4: src@4 {
+ interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x8d>, <&audma1 0xb0>;
+ dma-names = "rx", "tx";
+ };
+ src5: src@5 {
+ interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x8f>, <&audma1 0xb2>;
+ dma-names = "rx", "tx";
+ };
+ src6: src@6 {
+ interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x91>, <&audma1 0xb4>;
+ dma-names = "rx", "tx";
+ };
+ src7: src@7 {
+ interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x93>, <&audma1 0xb6>;
+ dma-names = "rx", "tx";
+ };
+ src8: src@8 {
+ interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x95>, <&audma1 0xb8>;
+ dma-names = "rx", "tx";
+ };
+ src9: src@9 {
+ interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x97>, <&audma1 0xba>;
+ dma-names = "rx", "tx";
+ };
+ };
+
+ rcar_sound,ssi {
+ ssi0: ssi@0 {
+ interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi1: ssi@1 {
+ interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi2: ssi@2 {
+ interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi3: ssi@3 {
+ interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi4: ssi@4 {
+ interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi5: ssi@5 {
+ interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi6: ssi@6 {
+ interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi7: ssi@7 {
+ interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi8: ssi@8 {
+ interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi9: ssi@9 {
+ interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/r8a7794-alt.dts b/arch/arm/boot/dts/r8a7794-alt.dts
new file mode 100644
index 000000000..928cfa641
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7794-alt.dts
@@ -0,0 +1,61 @@
+/*
+ * Device Tree Source for the Alt board
+ *
+ * Copyright (C) 2014 Renesas Electronics 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.
+ */
+
+/dts-v1/;
+#include "r8a7794.dtsi"
+
+/ {
+ model = "Alt";
+ compatible = "renesas,alt", "renesas,r8a7794";
+
+ aliases {
+ serial0 = &scif2;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
+ stdout-path = &scif2;
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0 0x40000000 0 0x40000000>;
+ };
+
+ lbsc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+};
+
+&extal_clk {
+ clock-frequency = <20000000>;
+};
+
+&cmt0 {
+ status = "okay";
+};
+
+&ether {
+ phy-handle = <&phy1>;
+ renesas,ether-link-active-low;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ interrupt-parent = <&irqc0>;
+ interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+ micrel,led-mode = <1>;
+ };
+};
+
+&scif2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi
new file mode 100644
index 000000000..7a3ffa51a
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7794.dtsi
@@ -0,0 +1,733 @@
+/*
+ * Device Tree Source for the r8a7794 SoC
+ *
+ * Copyright (C) 2014 Renesas Electronics Corporation
+ * Copyright (C) 2014 Ulrich Hecht
+ *
+ * This file is licensed under the terms 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 <dt-bindings/clock/r8a7794-clock.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "renesas,r8a7794";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0>;
+ clock-frequency = <1000000000>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <1>;
+ clock-frequency = <1000000000>;
+ };
+ };
+
+ gic: interrupt-controller@f1001000 {
+ compatible = "arm,cortex-a7-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0 0xf1001000 0 0x1000>,
+ <0 0xf1002000 0 0x1000>,
+ <0 0xf1004000 0 0x2000>,
+ <0 0xf1006000 0 0x2000>;
+ interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ cmt0: timer@ffca0000 {
+ compatible = "renesas,cmt-48-gen2";
+ reg = <0 0xffca0000 0 0x1004>;
+ interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
+ <0 143 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7794_CLK_CMT0>;
+ clock-names = "fck";
+
+ renesas,channels-mask = <0x60>;
+
+ status = "disabled";
+ };
+
+ cmt1: timer@e6130000 {
+ compatible = "renesas,cmt-48-gen2";
+ reg = <0 0xe6130000 0 0x1004>;
+ interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>,
+ <0 121 IRQ_TYPE_LEVEL_HIGH>,
+ <0 122 IRQ_TYPE_LEVEL_HIGH>,
+ <0 123 IRQ_TYPE_LEVEL_HIGH>,
+ <0 124 IRQ_TYPE_LEVEL_HIGH>,
+ <0 125 IRQ_TYPE_LEVEL_HIGH>,
+ <0 126 IRQ_TYPE_LEVEL_HIGH>,
+ <0 127 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7794_CLK_CMT1>;
+ clock-names = "fck";
+
+ renesas,channels-mask = <0xff>;
+
+ status = "disabled";
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ irqc0: interrupt-controller@e61c0000 {
+ compatible = "renesas,irqc-r8a7794", "renesas,irqc";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0 0xe61c0000 0 0x200>;
+ interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>,
+ <0 1 IRQ_TYPE_LEVEL_HIGH>,
+ <0 2 IRQ_TYPE_LEVEL_HIGH>,
+ <0 3 IRQ_TYPE_LEVEL_HIGH>,
+ <0 12 IRQ_TYPE_LEVEL_HIGH>,
+ <0 13 IRQ_TYPE_LEVEL_HIGH>,
+ <0 14 IRQ_TYPE_LEVEL_HIGH>,
+ <0 15 IRQ_TYPE_LEVEL_HIGH>,
+ <0 16 IRQ_TYPE_LEVEL_HIGH>,
+ <0 17 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dmac0: dma-controller@e6700000 {
+ compatible = "renesas,rcar-dmac";
+ reg = <0 0xe6700000 0 0x20000>;
+ interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH
+ 0 200 IRQ_TYPE_LEVEL_HIGH
+ 0 201 IRQ_TYPE_LEVEL_HIGH
+ 0 202 IRQ_TYPE_LEVEL_HIGH
+ 0 203 IRQ_TYPE_LEVEL_HIGH
+ 0 204 IRQ_TYPE_LEVEL_HIGH
+ 0 205 IRQ_TYPE_LEVEL_HIGH
+ 0 206 IRQ_TYPE_LEVEL_HIGH
+ 0 207 IRQ_TYPE_LEVEL_HIGH
+ 0 208 IRQ_TYPE_LEVEL_HIGH
+ 0 209 IRQ_TYPE_LEVEL_HIGH
+ 0 210 IRQ_TYPE_LEVEL_HIGH
+ 0 211 IRQ_TYPE_LEVEL_HIGH
+ 0 212 IRQ_TYPE_LEVEL_HIGH
+ 0 213 IRQ_TYPE_LEVEL_HIGH
+ 0 214 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14";
+ clocks = <&mstp2_clks R8A7794_CLK_SYS_DMAC0>;
+ clock-names = "fck";
+ #dma-cells = <1>;
+ dma-channels = <15>;
+ };
+
+ dmac1: dma-controller@e6720000 {
+ compatible = "renesas,rcar-dmac";
+ reg = <0 0xe6720000 0 0x20000>;
+ interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH
+ 0 216 IRQ_TYPE_LEVEL_HIGH
+ 0 217 IRQ_TYPE_LEVEL_HIGH
+ 0 218 IRQ_TYPE_LEVEL_HIGH
+ 0 219 IRQ_TYPE_LEVEL_HIGH
+ 0 308 IRQ_TYPE_LEVEL_HIGH
+ 0 309 IRQ_TYPE_LEVEL_HIGH
+ 0 310 IRQ_TYPE_LEVEL_HIGH
+ 0 311 IRQ_TYPE_LEVEL_HIGH
+ 0 312 IRQ_TYPE_LEVEL_HIGH
+ 0 313 IRQ_TYPE_LEVEL_HIGH
+ 0 314 IRQ_TYPE_LEVEL_HIGH
+ 0 315 IRQ_TYPE_LEVEL_HIGH
+ 0 316 IRQ_TYPE_LEVEL_HIGH
+ 0 317 IRQ_TYPE_LEVEL_HIGH
+ 0 318 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14";
+ clocks = <&mstp2_clks R8A7794_CLK_SYS_DMAC1>;
+ clock-names = "fck";
+ #dma-cells = <1>;
+ dma-channels = <15>;
+ };
+
+ scifa0: serial@e6c40000 {
+ compatible = "renesas,scifa-r8a7794", "renesas,scifa";
+ reg = <0 0xe6c40000 0 64>;
+ interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7794_CLK_SCIFA0>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifa1: serial@e6c50000 {
+ compatible = "renesas,scifa-r8a7794", "renesas,scifa";
+ reg = <0 0xe6c50000 0 64>;
+ interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7794_CLK_SCIFA1>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifa2: serial@e6c60000 {
+ compatible = "renesas,scifa-r8a7794", "renesas,scifa";
+ reg = <0 0xe6c60000 0 64>;
+ interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7794_CLK_SCIFA2>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifa3: serial@e6c70000 {
+ compatible = "renesas,scifa-r8a7794", "renesas,scifa";
+ reg = <0 0xe6c70000 0 64>;
+ interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp11_clks R8A7794_CLK_SCIFA3>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifa4: serial@e6c78000 {
+ compatible = "renesas,scifa-r8a7794", "renesas,scifa";
+ reg = <0 0xe6c78000 0 64>;
+ interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp11_clks R8A7794_CLK_SCIFA4>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifa5: serial@e6c80000 {
+ compatible = "renesas,scifa-r8a7794", "renesas,scifa";
+ reg = <0 0xe6c80000 0 64>;
+ interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp11_clks R8A7794_CLK_SCIFA5>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifb0: serial@e6c20000 {
+ compatible = "renesas,scifb-r8a7794", "renesas,scifb";
+ reg = <0 0xe6c20000 0 64>;
+ interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7794_CLK_SCIFB0>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifb1: serial@e6c30000 {
+ compatible = "renesas,scifb-r8a7794", "renesas,scifb";
+ reg = <0 0xe6c30000 0 64>;
+ interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7794_CLK_SCIFB1>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scifb2: serial@e6ce0000 {
+ compatible = "renesas,scifb-r8a7794", "renesas,scifb";
+ reg = <0 0xe6ce0000 0 64>;
+ interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7794_CLK_SCIFB2>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif0: serial@e6e60000 {
+ compatible = "renesas,scif-r8a7794", "renesas,scif";
+ reg = <0 0xe6e60000 0 64>;
+ interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7794_CLK_SCIF0>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif1: serial@e6e68000 {
+ compatible = "renesas,scif-r8a7794", "renesas,scif";
+ reg = <0 0xe6e68000 0 64>;
+ interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7794_CLK_SCIF1>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif2: serial@e6e58000 {
+ compatible = "renesas,scif-r8a7794", "renesas,scif";
+ reg = <0 0xe6e58000 0 64>;
+ interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7794_CLK_SCIF2>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif3: serial@e6ea8000 {
+ compatible = "renesas,scif-r8a7794", "renesas,scif";
+ reg = <0 0xe6ea8000 0 64>;
+ interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7794_CLK_SCIF3>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif4: serial@e6ee0000 {
+ compatible = "renesas,scif-r8a7794", "renesas,scif";
+ reg = <0 0xe6ee0000 0 64>;
+ interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7794_CLK_SCIF4>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ scif5: serial@e6ee8000 {
+ compatible = "renesas,scif-r8a7794", "renesas,scif";
+ reg = <0 0xe6ee8000 0 64>;
+ interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7794_CLK_SCIF5>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ hscif0: serial@e62c0000 {
+ compatible = "renesas,hscif-r8a7794", "renesas,hscif";
+ reg = <0 0xe62c0000 0 96>;
+ interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7794_CLK_HSCIF0>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ hscif1: serial@e62c8000 {
+ compatible = "renesas,hscif-r8a7794", "renesas,hscif";
+ reg = <0 0xe62c8000 0 96>;
+ interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7794_CLK_HSCIF1>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ hscif2: serial@e62d0000 {
+ compatible = "renesas,hscif-r8a7794", "renesas,hscif";
+ reg = <0 0xe62d0000 0 96>;
+ interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7794_CLK_HSCIF2>;
+ clock-names = "sci_ick";
+ status = "disabled";
+ };
+
+ ether: ethernet@ee700000 {
+ compatible = "renesas,ether-r8a7794";
+ reg = <0 0xee700000 0 0x400>;
+ interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp8_clks R8A7794_CLK_ETHER>;
+ phy-mode = "rmii";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ sdhi0: sd@ee100000 {
+ compatible = "renesas,sdhi-r8a7794";
+ reg = <0 0xee100000 0 0x200>;
+ interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7794_CLK_SDHI0>;
+ status = "disabled";
+ };
+
+ sdhi1: sd@ee140000 {
+ compatible = "renesas,sdhi-r8a7794";
+ reg = <0 0xee140000 0 0x100>;
+ interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7794_CLK_SDHI1>;
+ status = "disabled";
+ };
+
+ sdhi2: sd@ee160000 {
+ compatible = "renesas,sdhi-r8a7794";
+ reg = <0 0xee160000 0 0x100>;
+ interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7794_CLK_SDHI2>;
+ status = "disabled";
+ };
+
+ clocks {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* External root clock */
+ extal_clk: extal_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overriden by the board. */
+ clock-frequency = <0>;
+ clock-output-names = "extal";
+ };
+
+ /* Special CPG clocks */
+ cpg_clocks: cpg_clocks@e6150000 {
+ compatible = "renesas,r8a7794-cpg-clocks",
+ "renesas,rcar-gen2-cpg-clocks";
+ reg = <0 0xe6150000 0 0x1000>;
+ clocks = <&extal_clk>;
+ #clock-cells = <1>;
+ clock-output-names = "main", "pll0", "pll1", "pll3",
+ "lb", "qspi", "sdh", "sd0", "z";
+ };
+ /* Variable factor clocks */
+ sd2_clk: sd2_clk@e6150078 {
+ compatible = "renesas,r8a7794-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150078 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sd2";
+ };
+ sd3_clk: sd3_clk@e615026c {
+ compatible = "renesas,r8a7794-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe615026c 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sd3";
+ };
+ mmc0_clk: mmc0_clk@e6150240 {
+ compatible = "renesas,r8a7794-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150240 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "mmc0";
+ };
+
+ /* Fixed factor clocks */
+ pll1_div2_clk: pll1_div2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "pll1_div2";
+ };
+ zg_clk: zg_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <6>;
+ clock-mult = <1>;
+ clock-output-names = "zg";
+ };
+ zx_clk: zx_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <3>;
+ clock-mult = <1>;
+ clock-output-names = "zx";
+ };
+ zs_clk: zs_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <6>;
+ clock-mult = <1>;
+ clock-output-names = "zs";
+ };
+ hp_clk: hp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <12>;
+ clock-mult = <1>;
+ clock-output-names = "hp";
+ };
+ i_clk: i_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "i";
+ };
+ b_clk: b_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <12>;
+ clock-mult = <1>;
+ clock-output-names = "b";
+ };
+ p_clk: p_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <24>;
+ clock-mult = <1>;
+ clock-output-names = "p";
+ };
+ cl_clk: cl_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <48>;
+ clock-mult = <1>;
+ clock-output-names = "cl";
+ };
+ m2_clk: m2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "m2";
+ };
+ imp_clk: imp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clock-output-names = "imp";
+ };
+ rclk_clk: rclk_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <(48 * 1024)>;
+ clock-mult = <1>;
+ clock-output-names = "rclk";
+ };
+ oscclk_clk: oscclk_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <(12 * 1024)>;
+ clock-mult = <1>;
+ clock-output-names = "oscclk";
+ };
+ zb3_clk: zb3_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL3>;
+ #clock-cells = <0>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clock-output-names = "zb3";
+ };
+ zb3d2_clk: zb3d2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL3>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "zb3d2";
+ };
+ ddr_clk: ddr_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL3>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "ddr";
+ };
+ mp_clk: mp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-div = <15>;
+ clock-mult = <1>;
+ clock-output-names = "mp";
+ };
+ cp_clk: cp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <48>;
+ clock-mult = <1>;
+ clock-output-names = "cp";
+ };
+
+ acp_clk: acp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&extal_clk>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "acp";
+ };
+
+ /* Gate clocks */
+ mstp0_clks: mstp0_clks@e6150130 {
+ compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150130 0 4>, <0 0xe6150030 0 4>;
+ clocks = <&mp_clk>;
+ #clock-cells = <1>;
+ clock-indices = <R8A7794_CLK_MSIOF0>;
+ clock-output-names = "msiof0";
+ };
+ mstp1_clks: mstp1_clks@e6150134 {
+ compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>;
+ clocks = <&zs_clk>, <&zs_clk>, <&p_clk>, <&zg_clk>, <&zs_clk>,
+ <&zs_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>, <&cp_clk>,
+ <&zs_clk>, <&zs_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7794_CLK_VCP0 R8A7794_CLK_VPC0 R8A7794_CLK_TMU1
+ R8A7794_CLK_3DG R8A7794_CLK_2DDMAC R8A7794_CLK_FDP1_0
+ R8A7794_CLK_TMU3 R8A7794_CLK_TMU2 R8A7794_CLK_CMT0
+ R8A7794_CLK_TMU0 R8A7794_CLK_VSP1_DU0 R8A7794_CLK_VSP1_S
+ >;
+ clock-output-names =
+ "vcp0", "vpc0", "tmu1", "3dg", "2ddmac", "fdp1-0",
+ "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du0", "vsps";
+ };
+ mstp2_clks: mstp2_clks@e6150138 {
+ compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
+ clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>,
+ <&mp_clk>, <&mp_clk>, <&mp_clk>,
+ <&zs_clk>, <&zs_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7794_CLK_SCIFA2 R8A7794_CLK_SCIFA1 R8A7794_CLK_SCIFA0
+ R8A7794_CLK_MSIOF2 R8A7794_CLK_SCIFB0 R8A7794_CLK_SCIFB1
+ R8A7794_CLK_MSIOF1 R8A7794_CLK_SCIFB2
+ R8A7794_CLK_SYS_DMAC1 R8A7794_CLK_SYS_DMAC0
+ >;
+ clock-output-names =
+ "scifa2", "scifa1", "scifa0", "msiof2", "scifb0",
+ "scifb1", "msiof1", "scifb2",
+ "sys-dmac1", "sys-dmac0";
+ };
+ mstp3_clks: mstp3_clks@e615013c {
+ compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
+ clocks = <&sd3_clk>, <&sd2_clk>, <&cpg_clocks R8A7794_CLK_SD0>,
+ <&mmc0_clk>, <&rclk_clk>, <&hp_clk>, <&hp_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7794_CLK_SDHI2 R8A7794_CLK_SDHI1 R8A7794_CLK_SDHI0
+ R8A7794_CLK_MMCIF0 R8A7794_CLK_CMT1
+ R8A7794_CLK_USBDMAC0 R8A7794_CLK_USBDMAC1
+ >;
+ clock-output-names =
+ "sdhi2", "sdhi1", "sdhi0",
+ "mmcif0", "cmt1", "usbdmac0", "usbdmac1";
+ };
+ mstp7_clks: mstp7_clks@e615014c {
+ compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe615014c 0 4>, <0 0xe61501c4 0 4>;
+ clocks = <&mp_clk>, <&mp_clk>,
+ <&zs_clk>, <&p_clk>, <&p_clk>, <&zs_clk>,
+ <&zs_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7794_CLK_EHCI R8A7794_CLK_HSUSB
+ R8A7794_CLK_HSCIF2 R8A7794_CLK_SCIF5
+ R8A7794_CLK_SCIF4 R8A7794_CLK_HSCIF1 R8A7794_CLK_HSCIF0
+ R8A7794_CLK_SCIF3 R8A7794_CLK_SCIF2 R8A7794_CLK_SCIF1
+ R8A7794_CLK_SCIF0
+ >;
+ clock-output-names =
+ "ehci", "hsusb",
+ "hscif2", "scif5", "scif4", "hscif1", "hscif0",
+ "scif3", "scif2", "scif1", "scif0";
+ };
+ mstp8_clks: mstp8_clks@e6150990 {
+ compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>;
+ clocks = <&zg_clk>, <&zg_clk>, <&p_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7794_CLK_VIN1 R8A7794_CLK_VIN0 R8A7794_CLK_ETHER
+ >;
+ clock-output-names =
+ "vin1", "vin0", "ether";
+ };
+ mstp9_clks: mstp9_clks@e6150994 {
+ compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>;
+ clocks = <&cpg_clocks R8A7794_CLK_QSPI>, <&hp_clk>, <&hp_clk>,
+ <&hp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7794_CLK_QSPI_MOD R8A7794_CLK_I2C5 R8A7794_CLK_I2C4
+ R8A7794_CLK_I2C3 R8A7794_CLK_I2C2 R8A7794_CLK_I2C1
+ R8A7794_CLK_I2C0
+ >;
+ clock-output-names =
+ "qspi_mod", "i2c5", "i2c4", "i2c3", "i2c2", "i2c1", "i2c0";
+ };
+ mstp11_clks: mstp11_clks@e615099c {
+ compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe615099c 0 4>, <0 0xe61509ac 0 4>;
+ clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7794_CLK_SCIFA3 R8A7794_CLK_SCIFA4 R8A7794_CLK_SCIFA5
+ >;
+ clock-output-names = "scifa3", "scifa4", "scifa5";
+ };
+ };
+
+ ipmmu_sy0: mmu@e6280000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xe6280000 0 0x1000>;
+ interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>,
+ <0 224 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ ipmmu_sy1: mmu@e6290000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xe6290000 0 0x1000>;
+ interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ ipmmu_ds: mmu@e6740000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xe6740000 0 0x1000>;
+ interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>,
+ <0 199 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_mp: mmu@ec680000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xec680000 0 0x1000>;
+ interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ ipmmu_mx: mmu@fe951000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xfe951000 0 0x1000>;
+ interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>,
+ <0 221 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_gp: mmu@e62a0000 {
+ compatible = "renesas,ipmmu-vmsa";
+ reg = <0 0xe62a0000 0 0x1000>;
+ interrupts = <0 260 IRQ_TYPE_LEVEL_HIGH>,
+ <0 261 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/r8a77xx-aa104xd12-panel.dtsi b/arch/arm/boot/dts/r8a77xx-aa104xd12-panel.dtsi
new file mode 100644
index 000000000..65cb50f0c
--- /dev/null
+++ b/arch/arm/boot/dts/r8a77xx-aa104xd12-panel.dtsi
@@ -0,0 +1,41 @@
+/*
+ * Common file for the AA104XD12 panel connected to Renesas R-Car boards
+ *
+ * Copyright (C) 2014 Renesas Electronics 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.
+ */
+
+/ {
+ panel {
+ compatible = "mitsubishi,aa104xd12", "panel-dpi";
+
+ width-mm = <210>;
+ height-mm = <158>;
+
+ panel-timing {
+ /* 1024x768 @65Hz */
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hsync-len = <136>;
+ hfront-porch = <20>;
+ hback-porch = <160>;
+ vfront-porch = <3>;
+ vback-porch = <29>;
+ vsync-len = <6>;
+ };
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&lvds_connector>;
+ };
+ };
+ };
+};
+
+&lvds_connector {
+ remote-endpoint = <&panel_in>;
+};
diff --git a/arch/arm/boot/dts/rk3066a-bqcurie2.dts b/arch/arm/boot/dts/rk3066a-bqcurie2.dts
new file mode 100644
index 000000000..baf21ac6c
--- /dev/null
+++ b/arch/arm/boot/dts/rk3066a-bqcurie2.dts
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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.
+ */
+
+/dts-v1/;
+#include "rk3066a.dtsi"
+
+/ {
+ model = "bq Curie 2";
+ compatible = "mundoreader,bq-curie2", "rockchip,rk3066a";
+
+ memory {
+ reg = <0x60000000 0x40000000>;
+ };
+
+ vcc_sd0: fixed-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "sdmmc-supply";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio3 7 GPIO_ACTIVE_LOW>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ autorepeat;
+
+ button@0 {
+ gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; /* GPIO6_A2 */
+ linux,code = <116>;
+ label = "GPIO Key Power";
+ linux,input-type = <1>;
+ gpio-key,wakeup = <1>;
+ debounce-interval = <100>;
+ };
+ button@1 {
+ gpios = <&gpio4 21 GPIO_ACTIVE_LOW>; /* GPIO4_C5 */
+ linux,code = <104>;
+ label = "GPIO Key Vol-";
+ linux,input-type = <1>;
+ gpio-key,wakeup = <0>;
+ debounce-interval = <100>;
+ };
+ /* VOL+ comes somehow thru the ADC */
+ };
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_arm>;
+};
+
+&i2c1 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ tps: tps@2d {
+ reg = <0x2d>;
+
+ interrupt-parent = <&gpio6>;
+ interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
+
+ vcc5-supply = <&vcc_io>;
+ vcc6-supply = <&vcc_io>;
+
+ regulators {
+ vcc_rtc: regulator@0 {
+ regulator-name = "vcc_rtc";
+ regulator-always-on;
+ };
+
+ vcc_io: regulator@1 {
+ regulator-name = "vcc_io";
+ regulator-always-on;
+ };
+
+ vdd_arm: regulator@2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vcc_ddr: regulator@3 {
+ regulator-name = "vcc_ddr";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vcc18_cif: regulator@5 {
+ regulator-name = "vcc18_cif";
+ regulator-always-on;
+ };
+
+ vdd_11: regulator@6 {
+ regulator-name = "vdd_11";
+ regulator-always-on;
+ };
+
+ vcc_25: regulator@7 {
+ regulator-name = "vcc_25";
+ regulator-always-on;
+ };
+
+ vcc_18: regulator@8 {
+ regulator-name = "vcc_18";
+ regulator-always-on;
+ };
+
+ vcc25_hdmi: regulator@9 {
+ regulator-name = "vcc25_hdmi";
+ regulator-always-on;
+ };
+
+ vcca_33: regulator@10 {
+ regulator-name = "vcca_33";
+ regulator-always-on;
+ };
+
+ vcc_tp: regulator@11 {
+ regulator-name = "vcc_tp";
+ regulator-always-on;
+ };
+
+ vcc28_cif: regulator@12 {
+ regulator-name = "vcc28_cif";
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+/* must be included after &tps gets defined */
+#include "tps65910.dtsi"
+
+&mmc0 { /* sdmmc */
+ num-slots = <1>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
+ vmmc-supply = <&vcc_sd0>;
+ bus-width = <4>;
+ disable-wp;
+};
+
+&mmc1 { /* wifi */
+ num-slots = <1>;
+ status = "okay";
+ non-removable;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus4>;
+
+ bus-width = <4>;
+ disable-wp;
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3066a-marsboard.dts b/arch/arm/boot/dts/rk3066a-marsboard.dts
new file mode 100644
index 000000000..0a7304beb
--- /dev/null
+++ b/arch/arm/boot/dts/rk3066a-marsboard.dts
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2014 Romain Perier <romain.perier@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3066a.dtsi"
+
+/ {
+ model = "MarsBoard RK3066";
+ compatible = "haoyu,marsboard-rk3066", "rockchip,rk3066a";
+
+ memory {
+ reg = <0x60000000 0x40000000>;
+ };
+
+ vcc_sd0: sdmmc-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "sdmmc-supply";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio3 7 GPIO_ACTIVE_LOW>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vsys: vsys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ tps: tps@2d {
+ reg = <0x2d>;
+
+ interrupt-parent = <&gpio6>;
+ interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
+
+ vcc1-supply = <&vsys>;
+ vcc2-supply = <&vsys>;
+ vcc3-supply = <&vsys>;
+ vcc4-supply = <&vsys>;
+ vcc5-supply = <&vcc_io>;
+ vcc6-supply = <&vcc_io>;
+ vcc7-supply = <&vsys>;
+ vccio-supply = <&vsys>;
+
+ regulators {
+ vcc_rtc: regulator@0 {
+ regulator-name = "vcc_rtc";
+ regulator-always-on;
+ };
+
+ vcc_io: regulator@1 {
+ regulator-name = "vcc_io";
+ regulator-always-on;
+ };
+
+ vdd_arm: regulator@2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vcc_ddr: regulator@3 {
+ regulator-name = "vcc_ddr";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vcc18_cif: regulator@5 {
+ regulator-name = "vcc18_cif";
+ regulator-always-on;
+ };
+
+ vdd_11: regulator@6 {
+ regulator-name = "vdd_11";
+ regulator-always-on;
+ };
+
+ vcc_25: regulator@7 {
+ regulator-name = "vcc_25";
+ regulator-always-on;
+ };
+
+ vcc_18: regulator@8 {
+ regulator-name = "vcc_18";
+ regulator-always-on;
+ };
+
+ vcc25_hdmi: regulator@9 {
+ regulator-name = "vcc25_hdmi";
+ regulator-always-on;
+ };
+
+ vcca_33: regulator@10 {
+ regulator-name = "vcca_33";
+ regulator-always-on;
+ };
+
+ vcc_rmii: regulator@11 {
+ regulator-name = "vcc_rmii";
+ };
+
+ vcc28_cif: regulator@12 {
+ regulator-name = "vcc28_cif";
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+/* must be included after &tps gets defined */
+#include "tps65910.dtsi"
+
+&emac {
+ status = "okay";
+
+ phy = <&phy0>;
+ phy-supply = <&vcc_rmii>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_xfer>, <&emac_mdio>, <&phy_int>;
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&pinctrl {
+ lan8720a {
+ phy_int: phy-int {
+ rockchip,pins = <RK_GPIO1 26 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3066a-rayeager.dts b/arch/arm/boot/dts/rk3066a-rayeager.dts
new file mode 100644
index 000000000..3ac151102
--- /dev/null
+++ b/arch/arm/boot/dts/rk3066a-rayeager.dts
@@ -0,0 +1,468 @@
+/*
+ * Copyright (c) 2014, 2015 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3066a.dtsi"
+
+/ {
+ model = "Rayeager PX2";
+ compatible = "chipspark,rayeager-px2", "rockchip,rk3066a";
+
+ memory {
+ reg = <0x60000000 0x40000000>;
+ };
+
+ ir: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio6 1 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_int>;
+ };
+
+ keys: gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@0 {
+ gpio-key,wakeup = <1>;
+ gpios = <&gpio6 2 GPIO_ACTIVE_LOW>;
+ label = "GPIO Power";
+ linux,code = <116>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwr_key>;
+ };
+ };
+
+ vsys: vsys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ /* input for 5V_STDBY is VSYS or DC5V, selectable by jumper J4 */
+ vcc_stdby: 5v-stdby-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "5v_stdby";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_emmc: emmc-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "emmc_vccq";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ vin-supply = <&vsys>;
+ };
+
+ vcc_sata: sata-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 22 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sata_pwr>;
+ regulator-name = "usb_5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&vcc_stdby>;
+ };
+
+ vcc_sd: sdmmc-regulator {
+ compatible = "regulator-fixed";
+ gpio = <&gpio3 7 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_pwr>;
+ regulator-name = "vcc_sd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_host: usb-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&host_drv>;
+ regulator-name = "host-pwr";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&vcc_stdby>;
+ };
+
+ vcc_otg: usb-otg-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&otg_drv>;
+ regulator-name = "vcc_otg";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&vcc_stdby>;
+ };
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_arm>;
+};
+
+&emac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_xfer>, <&emac_mdio>, <&rmii_rst>;
+ phy = <&phy0>;
+ phy-supply = <&vcc_rmii>;
+ status = "okay";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&emmc {
+ broken-cd;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_rst>;
+ vmmc-supply = <&vcc_emmc>;
+ vqmmc-supply = <&vcc_emmc>;
+ status = "okay";
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ ak8963: ak8963@0d {
+ compatible = "asahi-kasei,ak8975";
+ reg = <0x0d>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <17 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&comp_int>;
+ };
+
+ mma8452: mma8452@1d {
+ compatible = "fsl,mma8452";
+ reg = <0x1d>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <16 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gsensor_int>;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ tps: tps@2d {
+ reg = <0x2d>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <4 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int>, <&pwr_hold>;
+
+ vcc1-supply = <&vsys>;
+ vcc2-supply = <&vsys>;
+ vcc3-supply = <&vsys>;
+ vcc4-supply = <&vsys>;
+ vcc5-supply = <&vcc_io>;
+ vcc6-supply = <&vcc_io>;
+ vcc7-supply = <&vsys>;
+ vccio-supply = <&vsys>;
+
+ regulators {
+ vcc_rtc: regulator@0 {
+ regulator-name = "vcc_rtc";
+ regulator-always-on;
+ };
+
+ vcc_io: regulator@1 {
+ regulator-name = "vcc_io";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_arm: regulator@2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_ddr: regulator@3 {
+ regulator-name = "vcc_ddr";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc18: regulator@5 {
+ regulator-name = "vcc18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vdd_11: regulator@6 {
+ regulator-name = "vdd_11";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ vcc_25: regulator@7 {
+ regulator-name = "vcc_25";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ vccio_wl: regulator@8 {
+ regulator-name = "vccio_wl";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vcc25_hdmi: regulator@9 {
+ regulator-name = "vcc25_hdmi";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ };
+
+ vcca_33: regulator@10 {
+ regulator-name = "vcca_33";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc_rmii: regulator@11 {
+ regulator-name = "vcc_rmii";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc28_cif: regulator@12 {
+ regulator-name = "vcc28_cif";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+ };
+ };
+};
+
+#include "tps65910.dtsi"
+
+&i2c2 {
+ status = "okay";
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+};
+
+&mmc0 {
+ bus-width = <4>;
+ disable-wp;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
+ vmmc-supply = <&vcc_sd>;
+ status = "okay";
+};
+
+&mmc1 {
+ broken-cd;
+ bus-width = <4>;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_bus4>;
+ vmmc-supply = <&vccio_wl>;
+ status = "okay";
+};
+
+&pinctrl {
+ pcfg_output_high: pcfg-output-high {
+ output-high;
+ };
+
+ ak8963 {
+ comp_int: comp-int {
+ rockchip,pins = <4 17 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ emac {
+ rmii_rst: rmii-rst {
+ rockchip,pins = <1 30 RK_FUNC_GPIO &pcfg_output_high>;
+ };
+ };
+
+ ir {
+ ir_int: ir-int {
+ rockchip,pins = <6 1 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ keys {
+ pwr_key: pwr-key {
+ rockchip,pins = <6 2 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ mma8452 {
+ gsensor_int: gsensor-int {
+ rockchip,pins = <4 16 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ mmc {
+ sdmmc_pwr: sdmmc-pwr {
+ rockchip,pins = <3 7 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ usb_host {
+ host_drv: host-drv {
+ rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+
+ hub_rst: hub-rst {
+ rockchip,pins = <1 31 RK_FUNC_GPIO &pcfg_output_high>;
+ };
+
+ sata_pwr: sata-pwr {
+ rockchip,pins = <4 22 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+
+ sata_reset: sata-reset {
+ rockchip,pins = <0 13 RK_FUNC_GPIO &pcfg_output_high>;
+ };
+ };
+
+ usb_otg {
+ otg_drv: otg-drv {
+ rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ tps {
+ pmic_int: pmic-int {
+ rockchip,pins = <6 4 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+
+ pwr_hold: pwr-hold {
+ rockchip,pins = <6 8 RK_FUNC_GPIO &pcfg_output_high>;
+ };
+ };
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcc_25>;
+ status = "okay";
+};
+
+&spi0 {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer>, <&uart0_cts>, <&uart0_rts>;
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_xfer>, <&uart3_cts>, <&uart3_rts>;
+ status = "okay";
+};
+
+&usb_host {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hub_rst>, <&sata_reset>;
+ status = "okay";
+};
+
+&usb_otg {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi
new file mode 100644
index 000000000..41ffd4951
--- /dev/null
+++ b/arch/arm/boot/dts/rk3066a.dtsi
@@ -0,0 +1,611 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/clock/rk3066a-cru.h>
+#include "rk3xxx.dtsi"
+
+/ {
+ compatible = "rockchip,rk3066a";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "rockchip,rk3066-smp";
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x0>;
+ operating-points = <
+ /* kHz uV */
+ 1008000 1075000
+ 816000 1025000
+ 600000 1025000
+ 504000 1000000
+ 312000 975000
+ >;
+ clock-latency = <40000>;
+ clocks = <&cru ARMCLK>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x1>;
+ };
+ };
+
+ sram: sram@10080000 {
+ compatible = "mmio-sram";
+ reg = <0x10080000 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x10080000 0x10000>;
+
+ smp-sram@0 {
+ compatible = "rockchip,rk3066-smp-sram";
+ reg = <0x0 0x50>;
+ };
+ };
+
+ i2s0: i2s@10118000 {
+ compatible = "rockchip,rk3066-i2s";
+ reg = <0x10118000 0x2000>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_bus>;
+ dmas = <&dmac1_s 4>, <&dmac1_s 5>;
+ dma-names = "tx", "rx";
+ clock-names = "i2s_hclk", "i2s_clk";
+ clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>;
+ status = "disabled";
+ };
+
+ i2s1: i2s@1011a000 {
+ compatible = "rockchip,rk3066-i2s";
+ reg = <0x1011a000 0x2000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s1_bus>;
+ dmas = <&dmac1_s 6>, <&dmac1_s 7>;
+ dma-names = "tx", "rx";
+ clock-names = "i2s_hclk", "i2s_clk";
+ clocks = <&cru HCLK_I2S1>, <&cru SCLK_I2S1>;
+ status = "disabled";
+ };
+
+ i2s2: i2s@1011c000 {
+ compatible = "rockchip,rk3066-i2s";
+ reg = <0x1011c000 0x2000>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s2_bus>;
+ dmas = <&dmac1_s 9>, <&dmac1_s 10>;
+ dma-names = "tx", "rx";
+ clock-names = "i2s_hclk", "i2s_clk";
+ clocks = <&cru HCLK_I2S2>, <&cru SCLK_I2S2>;
+ status = "disabled";
+ };
+
+ cru: clock-controller@20000000 {
+ compatible = "rockchip,rk3066a-cru";
+ reg = <0x20000000 0x1000>;
+ rockchip,grf = <&grf>;
+
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ timer@2000e000 {
+ compatible = "snps,dw-apb-timer-osc";
+ reg = <0x2000e000 0x100>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_TIMER2>, <&cru PCLK_TIMER2>;
+ clock-names = "timer", "pclk";
+ };
+
+ timer@20038000 {
+ compatible = "snps,dw-apb-timer-osc";
+ reg = <0x20038000 0x100>;
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_TIMER0>, <&cru PCLK_TIMER0>;
+ clock-names = "timer", "pclk";
+ };
+
+ timer@2003a000 {
+ compatible = "snps,dw-apb-timer-osc";
+ reg = <0x2003a000 0x100>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_TIMER1>, <&cru PCLK_TIMER1>;
+ clock-names = "timer", "pclk";
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rk3066a-pinctrl";
+ rockchip,grf = <&grf>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio0: gpio0@20034000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20034000 0x100>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio1@2003c000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2003c000 0x100>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO1>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio2@2003e000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2003e000 0x100>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO2>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio3@20080000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20080000 0x100>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO3>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio4@20084000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20084000 0x100>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO4>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio6: gpio6@2000a000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2000a000 0x100>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO6>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pcfg_pull_default: pcfg_pull_default {
+ bias-pull-pin-default;
+ };
+
+ pcfg_pull_none: pcfg_pull_none {
+ bias-disable;
+ };
+
+ emac {
+ emac_xfer: emac-xfer {
+ rockchip,pins = <RK_GPIO1 16 RK_FUNC_2 &pcfg_pull_none>, /* mac_clk */
+ <RK_GPIO1 17 RK_FUNC_2 &pcfg_pull_none>, /* tx_en */
+ <RK_GPIO1 18 RK_FUNC_2 &pcfg_pull_none>, /* txd1 */
+ <RK_GPIO1 19 RK_FUNC_2 &pcfg_pull_none>, /* txd0 */
+ <RK_GPIO1 20 RK_FUNC_2 &pcfg_pull_none>, /* rx_err */
+ <RK_GPIO1 21 RK_FUNC_2 &pcfg_pull_none>, /* crs_dvalid */
+ <RK_GPIO1 22 RK_FUNC_2 &pcfg_pull_none>, /* rxd1 */
+ <RK_GPIO1 23 RK_FUNC_2 &pcfg_pull_none>; /* rxd0 */
+ };
+
+ emac_mdio: emac-mdio {
+ rockchip,pins = <RK_GPIO1 24 RK_FUNC_2 &pcfg_pull_none>, /* mac_md */
+ <RK_GPIO1 25 RK_FUNC_2 &pcfg_pull_none>; /* mac_mdclk */
+ };
+ };
+
+ emmc {
+ emmc_clk: emmc-clk {
+ rockchip,pins = <RK_GPIO3 31 RK_FUNC_2 &pcfg_pull_default>;
+ };
+
+ emmc_cmd: emmc-cmd {
+ rockchip,pins = <RK_GPIO4 9 RK_FUNC_2 &pcfg_pull_default>;
+ };
+
+ emmc_rst: emmc-rst {
+ rockchip,pins = <RK_GPIO4 10 RK_FUNC_2 &pcfg_pull_default>;
+ };
+
+ /*
+ * The data pins are shared between nandc and emmc and
+ * not accessible through pinctrl. Also they should've
+ * been already set correctly by firmware, as
+ * flash/emmc is the boot-device.
+ */
+ };
+
+ i2c0 {
+ i2c0_xfer: i2c0-xfer {
+ rockchip,pins = <RK_GPIO2 28 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO2 29 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c1 {
+ i2c1_xfer: i2c1-xfer {
+ rockchip,pins = <RK_GPIO2 30 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO2 31 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c2 {
+ i2c2_xfer: i2c2-xfer {
+ rockchip,pins = <RK_GPIO3 0 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 1 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c3 {
+ i2c3_xfer: i2c3-xfer {
+ rockchip,pins = <RK_GPIO3 2 RK_FUNC_2 &pcfg_pull_none>,
+ <RK_GPIO3 3 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ i2c4 {
+ i2c4_xfer: i2c4-xfer {
+ rockchip,pins = <RK_GPIO3 4 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 5 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm0 {
+ pwm0_out: pwm0-out {
+ rockchip,pins = <RK_GPIO0 3 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm1 {
+ pwm1_out: pwm1-out {
+ rockchip,pins = <RK_GPIO0 4 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm2 {
+ pwm2_out: pwm2-out {
+ rockchip,pins = <RK_GPIO0 30 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm3 {
+ pwm3_out: pwm3-out {
+ rockchip,pins = <RK_GPIO0 31 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ spi0 {
+ spi0_clk: spi0-clk {
+ rockchip,pins = <RK_GPIO1 5 RK_FUNC_2 &pcfg_pull_default>;
+ };
+ spi0_cs0: spi0-cs0 {
+ rockchip,pins = <RK_GPIO1 4 RK_FUNC_2 &pcfg_pull_default>;
+ };
+ spi0_tx: spi0-tx {
+ rockchip,pins = <RK_GPIO1 7 RK_FUNC_2 &pcfg_pull_default>;
+ };
+ spi0_rx: spi0-rx {
+ rockchip,pins = <RK_GPIO1 6 RK_FUNC_2 &pcfg_pull_default>;
+ };
+ spi0_cs1: spi0-cs1 {
+ rockchip,pins = <RK_GPIO4 15 RK_FUNC_1 &pcfg_pull_default>;
+ };
+ };
+
+ spi1 {
+ spi1_clk: spi1-clk {
+ rockchip,pins = <RK_GPIO2 19 RK_FUNC_2 &pcfg_pull_default>;
+ };
+ spi1_cs0: spi1-cs0 {
+ rockchip,pins = <RK_GPIO2 20 RK_FUNC_2 &pcfg_pull_default>;
+ };
+ spi1_rx: spi1-rx {
+ rockchip,pins = <RK_GPIO2 22 RK_FUNC_2 &pcfg_pull_default>;
+ };
+ spi1_tx: spi1-tx {
+ rockchip,pins = <RK_GPIO2 21 RK_FUNC_2 &pcfg_pull_default>;
+ };
+ spi1_cs1: spi1-cs1 {
+ rockchip,pins = <RK_GPIO2 23 RK_FUNC_2 &pcfg_pull_default>;
+ };
+ };
+
+ uart0 {
+ uart0_xfer: uart0-xfer {
+ rockchip,pins = <RK_GPIO1 0 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO1 1 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ uart0_cts: uart0-cts {
+ rockchip,pins = <RK_GPIO1 2 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ uart0_rts: uart0-rts {
+ rockchip,pins = <RK_GPIO1 3 RK_FUNC_1 &pcfg_pull_default>;
+ };
+ };
+
+ uart1 {
+ uart1_xfer: uart1-xfer {
+ rockchip,pins = <RK_GPIO1 4 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO1 5 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ uart1_cts: uart1-cts {
+ rockchip,pins = <RK_GPIO1 6 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ uart1_rts: uart1-rts {
+ rockchip,pins = <RK_GPIO1 7 RK_FUNC_1 &pcfg_pull_default>;
+ };
+ };
+
+ uart2 {
+ uart2_xfer: uart2-xfer {
+ rockchip,pins = <RK_GPIO1 8 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO1 9 RK_FUNC_1 &pcfg_pull_default>;
+ };
+ /* no rts / cts for uart2 */
+ };
+
+ uart3 {
+ uart3_xfer: uart3-xfer {
+ rockchip,pins = <RK_GPIO3 27 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO3 28 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ uart3_cts: uart3-cts {
+ rockchip,pins = <RK_GPIO3 29 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ uart3_rts: uart3-rts {
+ rockchip,pins = <RK_GPIO3 30 RK_FUNC_1 &pcfg_pull_default>;
+ };
+ };
+
+ sd0 {
+ sd0_clk: sd0-clk {
+ rockchip,pins = <RK_GPIO3 8 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ rockchip,pins = <RK_GPIO3 9 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ sd0_cd: sd0-cd {
+ rockchip,pins = <RK_GPIO3 14 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ sd0_wp: sd0-wp {
+ rockchip,pins = <RK_GPIO3 15 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ rockchip,pins = <RK_GPIO3 10 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ rockchip,pins = <RK_GPIO3 10 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO3 11 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO3 12 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO3 13 RK_FUNC_1 &pcfg_pull_default>;
+ };
+ };
+
+ sd1 {
+ sd1_clk: sd1-clk {
+ rockchip,pins = <RK_GPIO3 21 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ rockchip,pins = <RK_GPIO3 16 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ sd1_cd: sd1-cd {
+ rockchip,pins = <RK_GPIO3 22 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ sd1_wp: sd1-wp {
+ rockchip,pins = <RK_GPIO3 23 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO3 18 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO3 19 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO3 20 RK_FUNC_1 &pcfg_pull_default>;
+ };
+ };
+
+ i2s0 {
+ i2s0_bus: i2s0-bus {
+ rockchip,pins = <RK_GPIO0 7 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 8 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 9 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 10 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 11 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 12 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 13 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 14 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 15 RK_FUNC_1 &pcfg_pull_default>;
+ };
+ };
+
+ i2s1 {
+ i2s1_bus: i2s1-bus {
+ rockchip,pins = <RK_GPIO0 16 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 17 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 18 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 19 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 20 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 21 RK_FUNC_1 &pcfg_pull_default>;
+ };
+ };
+
+ i2s2 {
+ i2s2_bus: i2s2-bus {
+ rockchip,pins = <RK_GPIO0 24 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 25 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 26 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 27 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 28 RK_FUNC_1 &pcfg_pull_default>,
+ <RK_GPIO0 29 RK_FUNC_1 &pcfg_pull_default>;
+ };
+ };
+ };
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_xfer>;
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_xfer>;
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_xfer>;
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_xfer>;
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_xfer>;
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus4>;
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_cd &sd1_bus4>;
+};
+
+&pwm0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_out>;
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm1_out>;
+};
+
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm2_out>;
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_out>;
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>;
+};
+
+&spi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>;
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer>;
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_xfer>;
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_xfer>;
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_xfer>;
+};
+
+&wdt {
+ compatible = "rockchip,rk3066-wdt", "snps,dw-wdt";
+};
+
+&emac {
+ compatible = "rockchip,rk3066-emac";
+};
diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts
new file mode 100644
index 000000000..bdf857019
--- /dev/null
+++ b/arch/arm/boot/dts/rk3188-radxarock.dts
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.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.
+ */
+
+/dts-v1/;
+#include "rk3188.dtsi"
+
+/ {
+ model = "Radxa Rock";
+ compatible = "radxa,rock", "rockchip,rk3188";
+
+ memory {
+ reg = <0x60000000 0x80000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ autorepeat;
+
+ button@0 {
+ gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
+ linux,code = <116>;
+ label = "GPIO Key Power";
+ linux,input-type = <1>;
+ gpio-key,wakeup = <1>;
+ debounce-interval = <100>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ green {
+ label = "rock:green:user1";
+ gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ blue {
+ label = "rock:blue:user2";
+ gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ sleep {
+ label = "rock:red:power";
+ gpios = <&gpio0 15 0>;
+ default-state = "off";
+ };
+ };
+
+ ir_recv: gpio-ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio0 10 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_recv_pin>;
+ };
+
+ vcc_otg: usb-otg-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio2 31 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&otg_vbus_drv>;
+ regulator-name = "otg-vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_sd0: sdmmc-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "sdmmc-supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 1 GPIO_ACTIVE_LOW>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_host: usb-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 3 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&host_vbus_drv>;
+ regulator-name = "host-pwr";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vsys: vsys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ };
+};
+
+&emac {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_xfer>, <&emac_mdio>, <&phy_int>;
+
+ phy = <&phy0>;
+ phy-supply = <&vcc_rmii>;
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_arm>;
+};
+
+&i2c1 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtc_int>;
+ #clock-cells = <0>;
+ clock-output-names = "xin32k";
+ };
+
+ act8846: act8846@5a {
+ compatible = "active-semi,act8846";
+ reg = <0x5a>;
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&act8846_dvs0_ctl>;
+
+ vp1-supply = <&vsys>;
+ vp2-supply = <&vsys>;
+ vp3-supply = <&vsys>;
+ vp4-supply = <&vsys>;
+ inl1-supply = <&vcc_io>;
+ inl2-supply = <&vsys>;
+ inl3-supply = <&vsys>;
+
+ regulators {
+ vcc_ddr: REG1 {
+ regulator-name = "VCC_DDR";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ vdd_log: REG2 {
+ regulator-name = "VDD_LOG";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ vdd_arm: REG3 {
+ regulator-name = "VDD_ARM";
+ regulator-min-microvolt = <875000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+
+ vcc_io: REG4 {
+ regulator-name = "VCC_IO";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_10: REG5 {
+ regulator-name = "VDD_10";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ vdd_hdmi: REG6 {
+ regulator-name = "VDD_HDMI";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ vcc18: REG7 {
+ regulator-name = "VCC_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vcca_33: REG8 {
+ regulator-name = "VCCA_33";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vcc_rmii: REG9 {
+ regulator-name = "VCC_RMII";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vccio_wl: REG10 {
+ regulator-name = "VCCIO_WL";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vcc_18: REG11 {
+ regulator-name = "VCC18_IO";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vcc28: REG12 {
+ regulator-name = "VCC_28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&mmc0 {
+ num-slots = <1>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
+ vmmc-supply = <&vcc_sd0>;
+
+ bus-width = <4>;
+ disable-wp;
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&pwm3 {
+ status = "okay";
+};
+
+&pinctrl {
+ pcfg_output_low: pcfg-output-low {
+ output-low;
+ };
+
+ act8846 {
+ act8846_dvs0_ctl: act8846-dvs0-ctl {
+ rockchip,pins = <RK_GPIO3 27 RK_FUNC_GPIO &pcfg_output_low>;
+ };
+ };
+
+ hym8563 {
+ rtc_int: rtc-int {
+ rockchip,pins = <RK_GPIO0 0 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ lan8720a {
+ phy_int: phy-int {
+ rockchip,pins = <RK_GPIO3 26 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ ir-receiver {
+ ir_recv_pin: ir-recv-pin {
+ rockchip,pins = <RK_GPIO0 10 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb {
+ host_vbus_drv: host-vbus-drv {
+ rockchip,pins = <0 3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ otg_vbus_drv: otg-vbus-drv {
+ rockchip,pins = <2 31 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&usb_host {
+ status = "okay";
+};
+
+&usb_otg {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
new file mode 100644
index 000000000..1d4d79c66
--- /dev/null
+++ b/arch/arm/boot/dts/rk3188.dtsi
@@ -0,0 +1,536 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/clock/rk3188-cru.h>
+#include "rk3xxx.dtsi"
+
+/ {
+ compatible = "rockchip,rk3188";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "rockchip,rk3066-smp";
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x0>;
+ operating-points = <
+ /* kHz uV */
+ 1608000 1350000
+ 1416000 1250000
+ 1200000 1150000
+ 1008000 1075000
+ 816000 975000
+ 600000 950000
+ 504000 925000
+ 312000 875000
+ >;
+ clock-latency = <40000>;
+ clocks = <&cru ARMCLK>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x1>;
+ };
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x2>;
+ };
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x3>;
+ };
+ };
+
+ sram: sram@10080000 {
+ compatible = "mmio-sram";
+ reg = <0x10080000 0x8000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x10080000 0x8000>;
+
+ smp-sram@0 {
+ compatible = "rockchip,rk3066-smp-sram";
+ reg = <0x0 0x50>;
+ };
+ };
+
+ i2s0: i2s@1011a000 {
+ compatible = "rockchip,rk3188-i2s", "rockchip,rk3066-i2s";
+ reg = <0x1011a000 0x2000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_bus>;
+ dmas = <&dmac1_s 6>, <&dmac1_s 7>;
+ dma-names = "tx", "rx";
+ clock-names = "i2s_hclk", "i2s_clk";
+ clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>;
+ status = "disabled";
+ };
+
+ cru: clock-controller@20000000 {
+ compatible = "rockchip,rk3188-cru";
+ reg = <0x20000000 0x1000>;
+ rockchip,grf = <&grf>;
+
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rk3188-pinctrl";
+ rockchip,grf = <&grf>;
+ rockchip,pmu = <&pmu>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio0: gpio0@2000a000 {
+ compatible = "rockchip,rk3188-gpio-bank0";
+ reg = <0x2000a000 0x100>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio1@2003c000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2003c000 0x100>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO1>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio2@2003e000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2003e000 0x100>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO2>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio3@20080000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20080000 0x100>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO3>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pcfg_pull_up: pcfg_pull_up {
+ bias-pull-up;
+ };
+
+ pcfg_pull_down: pcfg_pull_down {
+ bias-pull-down;
+ };
+
+ pcfg_pull_none: pcfg_pull_none {
+ bias-disable;
+ };
+
+ emmc {
+ emmc_clk: emmc-clk {
+ rockchip,pins = <RK_GPIO0 24 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ emmc_cmd: emmc-cmd {
+ rockchip,pins = <RK_GPIO0 26 RK_FUNC_2 &pcfg_pull_up>;
+ };
+
+ emmc_rst: emmc-rst {
+ rockchip,pins = <RK_GPIO0 27 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ /*
+ * The data pins are shared between nandc and emmc and
+ * not accessible through pinctrl. Also they should've
+ * been already set correctly by firmware, as
+ * flash/emmc is the boot-device.
+ */
+ };
+
+ emac {
+ emac_xfer: emac-xfer {
+ rockchip,pins = <RK_GPIO3 16 RK_FUNC_2 &pcfg_pull_none>, /* tx_en */
+ <RK_GPIO3 17 RK_FUNC_2 &pcfg_pull_none>, /* txd1 */
+ <RK_GPIO3 18 RK_FUNC_2 &pcfg_pull_none>, /* txd0 */
+ <RK_GPIO3 19 RK_FUNC_2 &pcfg_pull_none>, /* rxd0 */
+ <RK_GPIO3 20 RK_FUNC_2 &pcfg_pull_none>, /* rxd1 */
+ <RK_GPIO3 21 RK_FUNC_2 &pcfg_pull_none>, /* mac_clk */
+ <RK_GPIO3 22 RK_FUNC_2 &pcfg_pull_none>, /* rx_err */
+ <RK_GPIO3 23 RK_FUNC_2 &pcfg_pull_none>; /* crs_dvalid */
+ };
+
+ emac_mdio: emac-mdio {
+ rockchip,pins = <RK_GPIO3 24 RK_FUNC_2 &pcfg_pull_none>,
+ <RK_GPIO3 25 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ i2c0 {
+ i2c0_xfer: i2c0-xfer {
+ rockchip,pins = <RK_GPIO1 24 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 25 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c1 {
+ i2c1_xfer: i2c1-xfer {
+ rockchip,pins = <RK_GPIO1 26 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 27 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c2 {
+ i2c2_xfer: i2c2-xfer {
+ rockchip,pins = <RK_GPIO1 28 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 29 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c3 {
+ i2c3_xfer: i2c3-xfer {
+ rockchip,pins = <RK_GPIO3 14 RK_FUNC_2 &pcfg_pull_none>,
+ <RK_GPIO3 15 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ i2c4 {
+ i2c4_xfer: i2c4-xfer {
+ rockchip,pins = <RK_GPIO1 30 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 31 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm0 {
+ pwm0_out: pwm0-out {
+ rockchip,pins = <RK_GPIO3 27 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm1 {
+ pwm1_out: pwm1-out {
+ rockchip,pins = <RK_GPIO3 28 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm2 {
+ pwm2_out: pwm2-out {
+ rockchip,pins = <RK_GPIO3 29 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm3 {
+ pwm3_out: pwm3-out {
+ rockchip,pins = <RK_GPIO3 30 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ spi0 {
+ spi0_clk: spi0-clk {
+ rockchip,pins = <RK_GPIO1 6 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi0_cs0: spi0-cs0 {
+ rockchip,pins = <RK_GPIO1 7 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi0_tx: spi0-tx {
+ rockchip,pins = <RK_GPIO1 5 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi0_rx: spi0-rx {
+ rockchip,pins = <RK_GPIO1 4 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi0_cs1: spi0-cs1 {
+ rockchip,pins = <RK_GPIO1 15 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ };
+
+ spi1 {
+ spi1_clk: spi1-clk {
+ rockchip,pins = <RK_GPIO0 30 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi1_cs0: spi1-cs0 {
+ rockchip,pins = <RK_GPIO0 31 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi1_rx: spi1-rx {
+ rockchip,pins = <RK_GPIO0 28 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi1_tx: spi1-tx {
+ rockchip,pins = <RK_GPIO0 29 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi1_cs1: spi1-cs1 {
+ rockchip,pins = <RK_GPIO1 14 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ };
+
+ uart0 {
+ uart0_xfer: uart0-xfer {
+ rockchip,pins = <RK_GPIO1 0 RK_FUNC_1 &pcfg_pull_up>,
+ <RK_GPIO1 1 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_cts: uart0-cts {
+ rockchip,pins = <RK_GPIO1 2 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_rts: uart0-rts {
+ rockchip,pins = <RK_GPIO1 3 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart1 {
+ uart1_xfer: uart1-xfer {
+ rockchip,pins = <RK_GPIO1 4 RK_FUNC_1 &pcfg_pull_up>,
+ <RK_GPIO1 5 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart1_cts: uart1-cts {
+ rockchip,pins = <RK_GPIO1 6 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart1_rts: uart1-rts {
+ rockchip,pins = <RK_GPIO1 7 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart2 {
+ uart2_xfer: uart2-xfer {
+ rockchip,pins = <RK_GPIO1 8 RK_FUNC_1 &pcfg_pull_up>,
+ <RK_GPIO1 9 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ /* no rts / cts for uart2 */
+ };
+
+ uart3 {
+ uart3_xfer: uart3-xfer {
+ rockchip,pins = <RK_GPIO1 10 RK_FUNC_1 &pcfg_pull_up>,
+ <RK_GPIO1 11 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart3_cts: uart3-cts {
+ rockchip,pins = <RK_GPIO1 12 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart3_rts: uart3-rts {
+ rockchip,pins = <RK_GPIO1 13 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ sd0 {
+ sd0_clk: sd0-clk {
+ rockchip,pins = <RK_GPIO3 2 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ rockchip,pins = <RK_GPIO3 3 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_cd: sd0-cd {
+ rockchip,pins = <RK_GPIO3 8 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_wp: sd0-wp {
+ rockchip,pins = <RK_GPIO3 9 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_pwr: sd0-pwr {
+ rockchip,pins = <RK_GPIO3 1 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ rockchip,pins = <RK_GPIO3 4 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ rockchip,pins = <RK_GPIO3 4 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 5 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 6 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 7 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ sd1 {
+ sd1_clk: sd1-clk {
+ rockchip,pins = <RK_GPIO3 21 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ rockchip,pins = <RK_GPIO3 16 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd1_cd: sd1-cd {
+ rockchip,pins = <RK_GPIO3 22 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd1_wp: sd1-wp {
+ rockchip,pins = <RK_GPIO3 23 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 18 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 19 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 20 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2s0 {
+ i2s0_bus: i2s0-bus {
+ rockchip,pins = <RK_GPIO1 16 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 17 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 18 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 19 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 20 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 21 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+ };
+};
+
+&emac {
+ compatible = "rockchip,rk3188-emac";
+};
+
+&global_timer {
+ interrupts = <GIC_PPI 11 0xf04>;
+};
+
+&local_timer {
+ interrupts = <GIC_PPI 13 0xf04>;
+};
+
+&i2c0 {
+ compatible = "rockchip,rk3188-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_xfer>;
+};
+
+&i2c1 {
+ compatible = "rockchip,rk3188-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_xfer>;
+};
+
+&i2c2 {
+ compatible = "rockchip,rk3188-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_xfer>;
+};
+
+&i2c3 {
+ compatible = "rockchip,rk3188-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_xfer>;
+};
+
+&i2c4 {
+ compatible = "rockchip,rk3188-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_xfer>;
+};
+
+&pwm0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_out>;
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm1_out>;
+};
+
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm2_out>;
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_out>;
+};
+
+&spi0 {
+ compatible = "rockchip,rk3188-spi", "rockchip,rk3066-spi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>;
+};
+
+&spi1 {
+ compatible = "rockchip,rk3188-spi", "rockchip,rk3066-spi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>;
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer>;
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_xfer>;
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_xfer>;
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_xfer>;
+};
+
+&wdt {
+ compatible = "rockchip,rk3188-wdt", "snps,dw-wdt";
+};
diff --git a/arch/arm/boot/dts/rk3288-evb-act8846.dts b/arch/arm/boot/dts/rk3288-evb-act8846.dts
new file mode 100644
index 000000000..1687e8336
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-evb-act8846.dts
@@ -0,0 +1,163 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+#include "rk3288-evb.dtsi"
+
+/ {
+ compatible = "rockchip,rk3288-evb-act8846", "rockchip,rk3288";
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_cpu>;
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+
+ vdd_cpu: syr827@40 {
+ compatible = "silergy,syr827";
+ fcs,suspend-voltage-selector = <1>;
+ reg = <0x40>;
+ regulator-name = "vdd_cpu";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ vdd_gpu: syr828@41 {
+ compatible = "silergy,syr828";
+ fcs,suspend-voltage-selector = <1>;
+ reg = <0x41>;
+ regulator-name = "vdd_gpu";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ hym8563@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+
+ interrupt-parent = <&gpio0>;
+ interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int>;
+
+ #clock-cells = <0>;
+ clock-output-names = "xin32k";
+ };
+
+ act8846: act8846@5a {
+ compatible = "active-semi,act8846";
+ reg = <0x5a>;
+ status = "okay";
+
+ vp1-supply = <&vcc_sys>;
+ vp2-supply = <&vcc_sys>;
+ vp3-supply = <&vcc_sys>;
+ vp4-supply = <&vcc_sys>;
+ inl1-supply = <&vcc_io>;
+ inl2-supply = <&vcc_sys>;
+ inl3-supply = <&vcc_20>;
+
+ regulators {
+ vcc_ddr: REG1 {
+ regulator-name = "VCC_DDR";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ vcc_io: REG2 {
+ regulator-name = "VCC_IO";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_log: REG3 {
+ regulator-name = "VDD_LOG";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ vcc_20: REG4 {
+ regulator-name = "VCC_20";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-always-on;
+ };
+
+ vccio_sd: REG5 {
+ regulator-name = "VCCIO_SD";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd10_lcd: REG6 {
+ regulator-name = "VDD10_LCD";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ vcca_codec: REG7 {
+ regulator-name = "VCCA_CODEC";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vcca_tp: REG8 {
+ regulator-name = "VCCA_TP";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vccio_pmu: REG9 {
+ regulator-name = "VCCIO_PMU";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_10: REG10 {
+ regulator-name = "VDD_10";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ vcc_18: REG11 {
+ regulator-name = "VCC_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vcc18_lcd: REG12 {
+ regulator-name = "VCC18_LCD";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/rk3288-evb-rk808.dts b/arch/arm/boot/dts/rk3288-evb-rk808.dts
new file mode 100644
index 000000000..f62ea7875
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-evb-rk808.dts
@@ -0,0 +1,234 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+#include "rk3288-evb.dtsi"
+
+/ {
+ compatible = "rockchip,rk3288-evb-rk808", "rockchip,rk3288";
+
+ ext_gmac: external-gmac-clock {
+ compatible = "fixed-clock";
+ clock-frequency = <125000000>;
+ clock-output-names = "ext_gmac";
+ #clock-cells = <0>;
+ };
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_cpu>;
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+
+ rk808: pmic@1b {
+ compatible = "rockchip,rk808";
+ reg = <0x1b>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int &global_pwroff>;
+ rockchip,system-power-controller;
+ wakeup-source;
+ #clock-cells = <1>;
+ clock-output-names = "xin32k", "rk808-clkout2";
+
+ vcc1-supply = <&vcc_sys>;
+ vcc2-supply = <&vcc_sys>;
+ vcc3-supply = <&vcc_sys>;
+ vcc4-supply = <&vcc_sys>;
+ vcc6-supply = <&vcc_sys>;
+ vcc7-supply = <&vcc_sys>;
+ vcc8-supply = <&vcc_18>;
+ vcc9-supply = <&vcc_io>;
+ vcc10-supply = <&vcc_io>;
+ vcc11-supply = <&vcc_sys>;
+ vcc12-supply = <&vcc_io>;
+ vddio-supply = <&vccio_pmu>;
+
+ regulators {
+ vdd_cpu: DCDC_REG1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-name = "vdd_arm";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_gpu: DCDC_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-name = "vdd_gpu";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vcc_ddr";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_io: DCDC_REG4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_io";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vccio_pmu: LDO_REG1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vccio_pmu";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_tp: LDO_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_tp";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_10: LDO_REG3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-name = "vdd_10";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
+ };
+
+ vcc18_lcd: LDO_REG4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc18_lcd";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vccio_sd: LDO_REG5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vccio_sd";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vdd10_lcd: LDO_REG6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-name = "vdd10_lcd";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
+ };
+
+ vcc_18: LDO_REG7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_18";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vcca_codec: LDO_REG8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcca_codec";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_wl: SWITCH_REG1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vcc_wl";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_lcd: SWITCH_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vcc_lcd";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&gmac {
+ phy-supply = <&vcc_phy>;
+ phy-mode = "rgmii";
+ clock_in_out = "input";
+ snps,reset-gpio = <&gpio4 7 0>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 1000000>;
+ assigned-clocks = <&cru SCLK_MAC>;
+ assigned-clock-parents = <&ext_gmac>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins>;
+ tx_delay = <0x30>;
+ rx_delay = <0x10>;
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi
new file mode 100644
index 000000000..4a457518d
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-evb.dtsi
@@ -0,0 +1,276 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <dt-bindings/pwm/pwm.h>
+#include "rk3288.dtsi"
+
+/ {
+ memory {
+ reg = <0x0 0x80000000>;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ brightness-levels = <
+ 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
+ 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47
+ 48 49 50 51 52 53 54 55
+ 56 57 58 59 60 61 62 63
+ 64 65 66 67 68 69 70 71
+ 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87
+ 88 89 90 91 92 93 94 95
+ 96 97 98 99 100 101 102 103
+ 104 105 106 107 108 109 110 111
+ 112 113 114 115 116 117 118 119
+ 120 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
+ 152 153 154 155 156 157 158 159
+ 160 161 162 163 164 165 166 167
+ 168 169 170 171 172 173 174 175
+ 176 177 178 179 180 181 182 183
+ 184 185 186 187 188 189 190 191
+ 192 193 194 195 196 197 198 199
+ 200 201 202 203 204 205 206 207
+ 208 209 210 211 212 213 214 215
+ 216 217 218 219 220 221 222 223
+ 224 225 226 227 228 229 230 231
+ 232 233 234 235 236 237 238 239
+ 240 241 242 243 244 245 246 247
+ 248 249 250 251 252 253 254 255>;
+ default-brightness-level = <128>;
+ enable-gpios = <&gpio7 2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bl_en>;
+ pwms = <&pwm0 0 1000000 PWM_POLARITY_INVERTED>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ autorepeat;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwrbtn>;
+
+ button@0 {
+ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
+ linux,code = <116>;
+ label = "GPIO Key Power";
+ linux,input-type = <1>;
+ gpio-key,wakeup = <1>;
+ debounce-interval = <100>;
+ };
+ };
+
+ /* This turns on USB vbus for both host0 (ehci) and host1 (dwc2) */
+ vcc_host: vcc-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&host_vbus_drv>;
+ regulator-name = "vcc_host";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_phy: vcc-phy-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&eth_phy_pwr>;
+ regulator-name = "vcc_phy";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_sys: vsys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_sys";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&emmc {
+ broken-cd;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c5>;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ disable-wp; /* wp not hooked up */
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+&i2c5 {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
+
+&pwm0 {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&uart4 {
+ status = "okay";
+};
+
+&tsadc {
+ rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */
+ rockchip,hw-tshut-polarity = <0>; /* tshut polarity 0:LOW 1:HIGH */
+ status = "okay";
+};
+
+&pinctrl {
+ pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
+ drive-strength = <8>;
+ };
+
+ pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma {
+ bias-pull-up;
+ drive-strength = <8>;
+ };
+
+ backlight {
+ bl_en: bl-en {
+ rockchip,pins = <7 2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ buttons {
+ pwrbtn: pwrbtn {
+ rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ pmic {
+ pmic_int: pmic-int {
+ rockchip,pins = <RK_GPIO0 4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ sdmmc {
+ /*
+ * Default drive strength isn't enough to achieve even
+ * high-speed mode on EVB board so bump up to 8ma.
+ */
+ sdmmc_bus4: sdmmc-bus4 {
+ rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
+ <6 17 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
+ <6 18 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
+ <6 19 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
+ };
+
+ sdmmc_clk: sdmmc-clk {
+ rockchip,pins = <6 20 RK_FUNC_1 &pcfg_pull_none_drv_8ma>;
+ };
+
+ sdmmc_cmd: sdmmc-cmd {
+ rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
+ };
+ };
+
+ usb {
+ host_vbus_drv: host-vbus-drv {
+ rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ eth_phy {
+ eth_phy_pwr: eth-phy-pwr {
+ rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&usbphy {
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host1 {
+ status = "okay";
+};
+
+&vopb {
+ status = "okay";
+};
+
+&vopb_mmu {
+ status = "okay";
+};
+
+&vopl {
+ status = "okay";
+};
+
+&vopl_mmu {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3288-firefly-beta.dts b/arch/arm/boot/dts/rk3288-firefly-beta.dts
new file mode 100644
index 000000000..75d77e38e
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-firefly-beta.dts
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014, 2015 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3288-firefly.dtsi"
+
+/ {
+ model = "Firefly-RK3288 Beta";
+ compatible = "firefly,firefly-rk3288-beta", "rockchip,rk3288";
+};
+
+&ir {
+ gpios = <&gpio7 5 GPIO_ACTIVE_LOW>;
+};
+
+&pinctrl {
+ act8846 {
+ pmic_vsel: pmic-vsel {
+ rockchip,pins = <7 1 RK_FUNC_GPIO &pcfg_output_low>;
+ };
+ };
+
+ ir {
+ ir_int: ir-int {
+ rockchip,pins = <7 5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&pwm0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3288-firefly.dts b/arch/arm/boot/dts/rk3288-firefly.dts
new file mode 100644
index 000000000..c07fe92dc
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-firefly.dts
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014, 2015 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3288-firefly.dtsi"
+
+/ {
+ model = "Firefly-RK3288";
+ compatible = "firefly,firefly-rk3288", "rockchip,rk3288";
+};
+
+&ir {
+ gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+};
+
+&pinctrl {
+ act8846 {
+ pmic_vsel: pmic-vsel {
+ rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_output_low>;
+ };
+ };
+
+ ir {
+ ir_int: ir-int {
+ rockchip,pins = <7 0 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&pwm1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi
new file mode 100644
index 000000000..b54dd7858
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-firefly.dtsi
@@ -0,0 +1,510 @@
+/*
+ * Copyright (c) 2014, 2015 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "rk3288.dtsi"
+
+/ {
+ memory {
+ reg = <0 0x80000000>;
+ };
+
+ ext_gmac: external-gmac-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <125000000>;
+ clock-output-names = "ext_gmac";
+ };
+
+ ir: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_int>;
+ };
+
+ keys: gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@0 {
+ gpio-key,wakeup = <1>;
+ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
+ label = "GPIO Power";
+ linux,code = <116>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwr_key>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ work {
+ gpios = <&gpio8 1 GPIO_ACTIVE_LOW>;
+ label = "firefly:blue:user";
+ linux,default-trigger = "rc-feedback";
+ pinctrl-names = "default";
+ pinctrl-0 = <&work_led>;
+ };
+
+ power {
+ gpios = <&gpio8 2 GPIO_ACTIVE_LOW>;
+ label = "firefly:green:power";
+ linux,default-trigger = "default-on";
+ pinctrl-names = "default";
+ pinctrl-0 = <&power_led>;
+ };
+ };
+
+ vcc_sys: vsys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_sys";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_sd: sdmmc-regulator {
+ compatible = "regulator-fixed";
+ gpio = <&gpio7 11 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_pwr>;
+ regulator-name = "vcc_sd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_flash: flash-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_flash";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_5v: usb-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ vcc_host_5v: usb-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&host_vbus_drv>;
+ regulator-name = "vcc_host_5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&vcc_5v>;
+ };
+
+ vcc_otg_5v: usb-otg-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&otg_vbus_drv>;
+ regulator-name = "vcc_otg_5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&vcc_5v>;
+ };
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_cpu>;
+};
+
+&emmc {
+ broken-cd;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_pwr>, <&emmc_bus8>;
+ vmmc-supply = <&vcc_io>;
+ vqmmc-supply = <&vcc_flash>;
+ status = "okay";
+};
+
+&gmac {
+ assigned-clocks = <&cru SCLK_MAC>;
+ assigned-clock-parents = <&ext_gmac>;
+ clock_in_out = "input";
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins>, <&phy_rst>, <&phy_pmeb>, <&phy_int>;
+ phy-supply = <&vcc_lan>;
+ phy-mode = "rgmii";
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 1000000>;
+ snps,reset-gpio = <&gpio4 8 GPIO_ACTIVE_LOW>;
+ tx_delay = <0x30>;
+ rx_delay = <0x10>;
+ status = "ok";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c5>;
+ status = "okay";
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ vdd_cpu: syr827@40 {
+ compatible = "silergy,syr827";
+ fcs,suspend-voltage-selector = <1>;
+ reg = <0x40>;
+ regulator-name = "vdd_cpu";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ vdd_gpu: syr828@41 {
+ compatible = "silergy,syr828";
+ fcs,suspend-voltage-selector = <1>;
+ reg = <0x41>;
+ regulator-name = "vdd_gpu";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ hym8563: hym8563@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ interrupt-parent = <&gpio7>;
+ interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtc_int>;
+ };
+
+ act8846: act8846@5a {
+ compatible = "active-semi,act8846";
+ reg = <0x5a>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_vsel>, <&pwr_hold>;
+ system-power-controller;
+
+ regulators {
+ vcc_ddr: REG1 {
+ regulator-name = "vcc_ddr";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ vcc_io: REG2 {
+ regulator-name = "vcc_io";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_log: REG3 {
+ regulator-name = "vdd_log";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ vcc_20: REG4 {
+ regulator-name = "vcc_20";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-always-on;
+ };
+
+ vccio_sd: REG5 {
+ regulator-name = "vccio_sd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd10_lcd: REG6 {
+ regulator-name = "vdd10_lcd";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ vcca_18: REG7 {
+ regulator-name = "vcca_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vcca_33: REG8 {
+ regulator-name = "vcca_33";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc_lan: REG9 {
+ regulator-name = "vcc_lan";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vdd_10: REG10 {
+ regulator-name = "vdd_10";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ vcc_18: REG11 {
+ regulator-name = "vcc_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vcc18_lcd: REG12 {
+ regulator-name = "vcc18_lcd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c1 {
+ status = "okay";
+};
+
+&i2c2 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+};
+
+&i2c5 {
+ status = "okay";
+};
+
+&pinctrl {
+ pcfg_output_high: pcfg-output-high {
+ output-high;
+ };
+
+ pcfg_output_low: pcfg-output-low {
+ output-low;
+ };
+
+ act8846 {
+ pwr_hold: pwr-hold {
+ rockchip,pins = <0 1 RK_FUNC_GPIO &pcfg_output_high>;
+ };
+ };
+
+ gmac {
+ phy_int: phy-int {
+ rockchip,pins = <0 9 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ phy_pmeb: phy-pmeb {
+ rockchip,pins = <0 8 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ phy_rst: phy-rst {
+ rockchip,pins = <4 8 RK_FUNC_GPIO &pcfg_output_high>;
+ };
+ };
+
+ hym8563 {
+ rtc_int: rtc-int {
+ rockchip,pins = <7 4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ keys {
+ pwr_key: pwr-key {
+ rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ leds {
+ power_led: power-led {
+ rockchip,pins = <8 2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ work_led: work-led {
+ rockchip,pins = <8 1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sdmmc {
+ sdmmc_pwr: sdmmc-pwr {
+ rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb_host {
+ host_vbus_drv: host-vbus-drv {
+ rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ usbhub_rst: usbhub-rst {
+ rockchip,pins = <8 3 RK_FUNC_GPIO &pcfg_output_high>;
+ };
+ };
+
+ usb_otg {
+ otg_vbus_drv: otg-vbus-drv {
+ rockchip,pins = <0 12 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&saradc {
+ vref-supply = <&vcc_18>;
+ status = "okay";
+};
+
+&sdio0 {
+ broken-cd;
+ bus-width = <4>;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdio0_bus4>, <&sdio0_cmd>, <&sdio0_clk>;
+ vmmc-supply = <&vcc_18>;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ disable-wp;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>;
+ vmmc-supply = <&vcc_sd>;
+ status = "okay";
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_clk>, <&spi0_cs0>, <&spi0_tx>, <&spi0_rx>, <&spi0_cs1>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer>, <&uart0_cts>, <&uart0_rts>;
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
+
+&usb_host1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usbhub_rst>;
+ status = "okay";
+};
+
+&usb_otg {
+ status = "okay";
+};
+
+&vopb {
+ status = "okay";
+};
+
+&vopb_mmu {
+ status = "okay";
+};
+
+&vopl {
+ status = "okay";
+};
+
+&vopl_mmu {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3288-popmetal.dts b/arch/arm/boot/dts/rk3288-popmetal.dts
new file mode 100644
index 000000000..d081f0e0d
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-popmetal.dts
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2014, 2015 Andy Yan <andy.yan@rock-chips.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "rk3288.dtsi"
+
+/ {
+ model = "PopMetal-RK3288";
+ compatible = "chipspark,popmetal-rk3288", "rockchip,rk3288";
+
+ memory{
+ reg = <0 0x80000000>;
+ };
+
+ ext_gmac: external-gmac-clock {
+ compatible = "fixed-clock";
+ clock-frequency = <125000000>;
+ clock-output-names = "ext_gmac";
+ #clock-cells = <0>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ autorepeat;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwrbtn>;
+
+ button@0 {
+ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
+ linux,code = <116>;
+ label = "GPIO Key Power";
+ linux,input-type = <1>;
+ gpio-key,wakeup = <1>;
+ debounce-interval = <100>;
+ };
+ };
+
+ ir: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_int>;
+ };
+
+ vcc_sys: vsys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_sys";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_cpu>;
+};
+
+&emmc {
+ broken-cd;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ disable-wp; /* wp not hooked up */
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
+ status = "okay";
+};
+
+&gmac {
+ phy-supply = <&vcc_lan>;
+ phy-mode = "rgmii";
+ clock_in_out = "input";
+ snps,reset-gpio = <&gpio4 7 0>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 1000000>;
+ assigned-clocks = <&cru SCLK_MAC>;
+ assigned-clock-parents = <&ext_gmac>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins>;
+ tx_delay = <0x30>;
+ rx_delay = <0x10>;
+ status = "ok";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c5>;
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ rk808: pmic@1b {
+ compatible = "rockchip,rk808";
+ reg = <0x1b>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int &global_pwroff>;
+ rockchip,system-power-controller;
+ wakeup-source;
+ #clock-cells = <1>;
+ clock-output-names = "xin32k", "rk808-clkout2";
+
+ vcc1-supply = <&vcc_sys>;
+ vcc2-supply = <&vcc_sys>;
+ vcc3-supply = <&vcc_sys>;
+ vcc4-supply = <&vcc_sys>;
+ vcc6-supply = <&vcc_sys>;
+ vcc7-supply = <&vcc_sys>;
+ vcc8-supply = <&vcc_18>;
+ vcc9-supply = <&vcc_io>;
+ vcc10-supply = <&vcc_io>;
+ vcc11-supply = <&vcc_sys>;
+ vcc12-supply = <&vcc_io>;
+ vddio-supply = <&vcc_io>;
+
+ regulators {
+ vdd_cpu: DCDC_REG1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-name = "vdd_arm";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_gpu: DCDC_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-name = "vdd_gpu";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vcc_ddr";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_io: DCDC_REG4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_io";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_lan: LDO_REG1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_lan";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vccio_sd: LDO_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vccio_sd";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_10: LDO_REG3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-name = "vdd_10";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
+ };
+
+ vcc18_lcd: LDO_REG4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc18_lcd";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ ldo5: LDO_REG5 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "ldo5";
+ };
+
+ vdd10_lcd: LDO_REG6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-name = "vdd10_lcd";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
+ };
+
+ vcc_18: LDO_REG7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_18";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vcca_codec: LDO_REG8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcca_codec";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_wl: SWITCH_REG1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vcc_wl";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_lcd: SWITCH_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vcc_lcd";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&i2c1 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ ak8963: ak8963@0d {
+ compatible = "asahi-kasei,ak8975";
+ reg = <0x0d>;
+ interrupt-parent = <&gpio8>;
+ interrupts = <1 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&comp_int>;
+ };
+
+ l3g4200d: l3g4200d@68 {
+ compatible = "st,l3g4200d-gyro";
+ st,drdy-int-pin = <2>;
+ reg = <0x6b>;
+ };
+
+ mma8452: mma8452@1d {
+ compatible = "fsl,mma8452";
+ reg = <0x1d>;
+ interrupt-parent = <&gpio8>;
+ interrupts = <0 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gsensor_int>;
+ };
+};
+
+&i2c2 {
+ status = "okay";
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+};
+
+&i2c5 {
+ status = "okay";
+};
+
+&pinctrl {
+ ak8963 {
+ comp_int: comp-int {
+ rockchip,pins = <8 1 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ buttons {
+ pwrbtn: pwrbtn {
+ rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ ir {
+ ir_int: ir-int {
+ rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ mma8452 {
+ gsensor_int: gsensor-int {
+ rockchip,pins = <8 0 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ pmic {
+ pmic_int: pmic-int {
+ rockchip,pins = <RK_GPIO0 4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&vopb {
+ status = "okay";
+};
+
+&vopb_mmu {
+ status = "okay";
+};
+
+&vopl {
+ status = "okay";
+};
+
+&vopl_mmu {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&uart4 {
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3288-thermal.dtsi b/arch/arm/boot/dts/rk3288-thermal.dtsi
new file mode 100644
index 000000000..2695200c0
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-thermal.dtsi
@@ -0,0 +1,74 @@
+/*
+ * Device Tree Source for RK3288 SoC thermal
+ *
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., 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.
+ */
+
+#include <dt-bindings/thermal/thermal.h>
+
+reserve_thermal: reserve_thermal {
+ polling-delay-passive = <1000>; /* milliseconds */
+ polling-delay = <5000>; /* milliseconds */
+
+ thermal-sensors = <&tsadc 0>;
+};
+
+cpu_thermal: cpu_thermal {
+ polling-delay-passive = <1000>; /* milliseconds */
+ polling-delay = <5000>; /* milliseconds */
+
+ thermal-sensors = <&tsadc 1>;
+
+ trips {
+ cpu_alert0: cpu_alert0 {
+ temperature = <70000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "passive";
+ };
+ cpu_crit: cpu_crit {
+ temperature = <90000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ cooling-device =
+ <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+};
+
+gpu_thermal: gpu_thermal {
+ polling-delay-passive = <1000>; /* milliseconds */
+ polling-delay = <5000>; /* milliseconds */
+
+ thermal-sensors = <&tsadc 2>;
+
+ trips {
+ gpu_alert0: gpu_alert0 {
+ temperature = <70000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "passive";
+ };
+ gpu_crit: gpu_crit {
+ temperature = <90000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&gpu_alert0>;
+ cooling-device =
+ <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
new file mode 100644
index 000000000..165968d51
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -0,0 +1,1273 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/clock/rk3288-cru.h>
+#include <dt-bindings/thermal/thermal.h>
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "rockchip,rk3288";
+
+ interrupt-parent = <&gic>;
+
+ aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ mshc0 = &emmc;
+ mshc1 = &sdmmc;
+ mshc2 = &sdio0;
+ mshc3 = &sdio1;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ spi2 = &spi2;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "rockchip,rk3066-smp";
+ rockchip,pmu = <&pmu>;
+
+ cpu0: cpu@500 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a12";
+ reg = <0x500>;
+ resets = <&cru SRST_CORE0>;
+ operating-points = <
+ /* KHz uV */
+ 1608000 1350000
+ 1512000 1300000
+ 1416000 1200000
+ 1200000 1100000
+ 1008000 1050000
+ 816000 1000000
+ 696000 950000
+ 600000 900000
+ 408000 900000
+ 312000 900000
+ 216000 900000
+ 126000 900000
+ >;
+ #cooling-cells = <2>; /* min followed by max */
+ clock-latency = <40000>;
+ clocks = <&cru ARMCLK>;
+ };
+ cpu@501 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a12";
+ reg = <0x501>;
+ resets = <&cru SRST_CORE1>;
+ };
+ cpu@502 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a12";
+ reg = <0x502>;
+ resets = <&cru SRST_CORE2>;
+ };
+ cpu@503 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a12";
+ reg = <0x503>;
+ resets = <&cru SRST_CORE3>;
+ };
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dmac_peri: dma-controller@ff250000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0xff250000 0x4000>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ clocks = <&cru ACLK_DMAC2>;
+ clock-names = "apb_pclk";
+ };
+
+ dmac_bus_ns: dma-controller@ff600000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0xff600000 0x4000>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ clocks = <&cru ACLK_DMAC1>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ dmac_bus_s: dma-controller@ffb20000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0xffb20000 0x4000>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ clocks = <&cru ACLK_DMAC1>;
+ clock-names = "apb_pclk";
+ };
+ };
+
+ xin24m: oscillator {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xin24m";
+ #clock-cells = <0>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ arm,cpu-registers-not-fw-configured;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ clock-frequency = <24000000>;
+ };
+
+ timer: timer@ff810000 {
+ compatible = "rockchip,rk3288-timer";
+ reg = <0xff810000 0x20>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&xin24m>, <&cru PCLK_TIMER>;
+ clock-names = "timer", "pclk";
+ };
+
+ display-subsystem {
+ compatible = "rockchip,display-subsystem";
+ ports = <&vopl_out>, <&vopb_out>;
+ };
+
+ sdmmc: dwmmc@ff0c0000 {
+ compatible = "rockchip,rk3288-dw-mshc";
+ clock-freq-min-max = <400000 150000000>;
+ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xff0c0000 0x4000>;
+ status = "disabled";
+ };
+
+ sdio0: dwmmc@ff0d0000 {
+ compatible = "rockchip,rk3288-dw-mshc";
+ clock-freq-min-max = <400000 150000000>;
+ clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xff0d0000 0x4000>;
+ status = "disabled";
+ };
+
+ sdio1: dwmmc@ff0e0000 {
+ compatible = "rockchip,rk3288-dw-mshc";
+ clock-freq-min-max = <400000 150000000>;
+ clocks = <&cru HCLK_SDIO1>, <&cru SCLK_SDIO1>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xff0e0000 0x4000>;
+ status = "disabled";
+ };
+
+ emmc: dwmmc@ff0f0000 {
+ compatible = "rockchip,rk3288-dw-mshc";
+ clock-freq-min-max = <400000 150000000>;
+ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xff0f0000 0x4000>;
+ status = "disabled";
+ };
+
+ saradc: saradc@ff100000 {
+ compatible = "rockchip,saradc";
+ reg = <0xff100000 0x100>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ #io-channel-cells = <1>;
+ clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
+ clock-names = "saradc", "apb_pclk";
+ status = "disabled";
+ };
+
+ spi0: spi@ff110000 {
+ compatible = "rockchip,rk3288-spi", "rockchip,rk3066-spi";
+ clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
+ clock-names = "spiclk", "apb_pclk";
+ dmas = <&dmac_peri 11>, <&dmac_peri 12>;
+ dma-names = "tx", "rx";
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>;
+ reg = <0xff110000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi1: spi@ff120000 {
+ compatible = "rockchip,rk3288-spi", "rockchip,rk3066-spi";
+ clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
+ clock-names = "spiclk", "apb_pclk";
+ dmas = <&dmac_peri 13>, <&dmac_peri 14>;
+ dma-names = "tx", "rx";
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>;
+ reg = <0xff120000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi2: spi@ff130000 {
+ compatible = "rockchip,rk3288-spi", "rockchip,rk3066-spi";
+ clocks = <&cru SCLK_SPI2>, <&cru PCLK_SPI2>;
+ clock-names = "spiclk", "apb_pclk";
+ dmas = <&dmac_peri 15>, <&dmac_peri 16>;
+ dma-names = "tx", "rx";
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_clk &spi2_tx &spi2_rx &spi2_cs0>;
+ reg = <0xff130000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@ff140000 {
+ compatible = "rockchip,rk3288-i2c";
+ reg = <0xff140000 0x1000>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-names = "i2c";
+ clocks = <&cru PCLK_I2C1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_xfer>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@ff150000 {
+ compatible = "rockchip,rk3288-i2c";
+ reg = <0xff150000 0x1000>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-names = "i2c";
+ clocks = <&cru PCLK_I2C3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_xfer>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@ff160000 {
+ compatible = "rockchip,rk3288-i2c";
+ reg = <0xff160000 0x1000>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-names = "i2c";
+ clocks = <&cru PCLK_I2C4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_xfer>;
+ status = "disabled";
+ };
+
+ i2c5: i2c@ff170000 {
+ compatible = "rockchip,rk3288-i2c";
+ reg = <0xff170000 0x1000>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-names = "i2c";
+ clocks = <&cru PCLK_I2C5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5_xfer>;
+ status = "disabled";
+ };
+
+ uart0: serial@ff180000 {
+ compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart";
+ reg = <0xff180000 0x100>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer>;
+ status = "disabled";
+ };
+
+ uart1: serial@ff190000 {
+ compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart";
+ reg = <0xff190000 0x100>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_xfer>;
+ status = "disabled";
+ };
+
+ uart2: serial@ff690000 {
+ compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart";
+ reg = <0xff690000 0x100>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_xfer>;
+ status = "disabled";
+ };
+
+ uart3: serial@ff1b0000 {
+ compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart";
+ reg = <0xff1b0000 0x100>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_xfer>;
+ status = "disabled";
+ };
+
+ uart4: serial@ff1c0000 {
+ compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart";
+ reg = <0xff1c0000 0x100>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_xfer>;
+ status = "disabled";
+ };
+
+ thermal-zones {
+ #include "rk3288-thermal.dtsi"
+ };
+
+ tsadc: tsadc@ff280000 {
+ compatible = "rockchip,rk3288-tsadc";
+ reg = <0xff280000 0x100>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>;
+ clock-names = "tsadc", "apb_pclk";
+ resets = <&cru SRST_TSADC>;
+ reset-names = "tsadc-apb";
+ pinctrl-names = "default";
+ pinctrl-0 = <&otp_out>;
+ #thermal-sensor-cells = <1>;
+ rockchip,hw-tshut-temp = <95000>;
+ status = "disabled";
+ };
+
+ gmac: ethernet@ff290000 {
+ compatible = "rockchip,rk3288-gmac";
+ reg = <0xff290000 0x10000>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ rockchip,grf = <&grf>;
+ clocks = <&cru SCLK_MAC>,
+ <&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>,
+ <&cru SCLK_MACREF>, <&cru SCLK_MACREF_OUT>,
+ <&cru ACLK_GMAC>, <&cru PCLK_GMAC>;
+ clock-names = "stmmaceth",
+ "mac_clk_rx", "mac_clk_tx",
+ "clk_mac_ref", "clk_mac_refout",
+ "aclk_mac", "pclk_mac";
+ status = "disabled";
+ };
+
+ usb_host0_ehci: usb@ff500000 {
+ compatible = "generic-ehci";
+ reg = <0xff500000 0x100>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_USBHOST0>;
+ clock-names = "usbhost";
+ phys = <&usbphy1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ /* NOTE: ohci@ff520000 doesn't actually work on hardware */
+
+ usb_host1: usb@ff540000 {
+ compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb",
+ "snps,dwc2";
+ reg = <0xff540000 0x40000>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_USBHOST1>;
+ clock-names = "otg";
+ phys = <&usbphy2>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ usb_otg: usb@ff580000 {
+ compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb",
+ "snps,dwc2";
+ reg = <0xff580000 0x40000>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_OTG0>;
+ clock-names = "otg";
+ phys = <&usbphy0>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ usb_hsic: usb@ff5c0000 {
+ compatible = "generic-ehci";
+ reg = <0xff5c0000 0x100>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_HSIC>;
+ clock-names = "usbhost";
+ status = "disabled";
+ };
+
+ i2c0: i2c@ff650000 {
+ compatible = "rockchip,rk3288-i2c";
+ reg = <0xff650000 0x1000>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-names = "i2c";
+ clocks = <&cru PCLK_I2C0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_xfer>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@ff660000 {
+ compatible = "rockchip,rk3288-i2c";
+ reg = <0xff660000 0x1000>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-names = "i2c";
+ clocks = <&cru PCLK_I2C2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_xfer>;
+ status = "disabled";
+ };
+
+ pwm0: pwm@ff680000 {
+ compatible = "rockchip,rk3288-pwm";
+ reg = <0xff680000 0x10>;
+ #pwm-cells = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pin>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ status = "disabled";
+ };
+
+ pwm1: pwm@ff680010 {
+ compatible = "rockchip,rk3288-pwm";
+ reg = <0xff680010 0x10>;
+ #pwm-cells = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm1_pin>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ status = "disabled";
+ };
+
+ pwm2: pwm@ff680020 {
+ compatible = "rockchip,rk3288-pwm";
+ reg = <0xff680020 0x10>;
+ #pwm-cells = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm2_pin>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ status = "disabled";
+ };
+
+ pwm3: pwm@ff680030 {
+ compatible = "rockchip,rk3288-pwm";
+ reg = <0xff680030 0x10>;
+ #pwm-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_pin>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ status = "disabled";
+ };
+
+ bus_intmem@ff700000 {
+ compatible = "mmio-sram";
+ reg = <0xff700000 0x18000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0xff700000 0x18000>;
+ smp-sram@0 {
+ compatible = "rockchip,rk3066-smp-sram";
+ reg = <0x00 0x10>;
+ };
+ };
+
+ sram@ff720000 {
+ compatible = "rockchip,rk3288-pmu-sram", "mmio-sram";
+ reg = <0xff720000 0x1000>;
+ };
+
+ pmu: power-management@ff730000 {
+ compatible = "rockchip,rk3288-pmu", "syscon";
+ reg = <0xff730000 0x100>;
+ };
+
+ sgrf: syscon@ff740000 {
+ compatible = "rockchip,rk3288-sgrf", "syscon";
+ reg = <0xff740000 0x1000>;
+ };
+
+ cru: clock-controller@ff760000 {
+ compatible = "rockchip,rk3288-cru";
+ reg = <0xff760000 0x1000>;
+ rockchip,grf = <&grf>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ assigned-clocks = <&cru PLL_GPLL>, <&cru PLL_CPLL>,
+ <&cru PLL_NPLL>, <&cru ACLK_CPU>,
+ <&cru HCLK_CPU>, <&cru PCLK_CPU>,
+ <&cru ACLK_PERI>, <&cru HCLK_PERI>,
+ <&cru PCLK_PERI>;
+ assigned-clock-rates = <594000000>, <400000000>,
+ <500000000>, <300000000>,
+ <150000000>, <75000000>,
+ <300000000>, <150000000>,
+ <75000000>;
+ };
+
+ grf: syscon@ff770000 {
+ compatible = "rockchip,rk3288-grf", "syscon";
+ reg = <0xff770000 0x1000>;
+ };
+
+ wdt: watchdog@ff800000 {
+ compatible = "rockchip,rk3288-wdt", "snps,dw-wdt";
+ reg = <0xff800000 0x100>;
+ clocks = <&cru PCLK_WDT>;
+ interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ i2s: i2s@ff890000 {
+ compatible = "rockchip,rk3288-i2s", "rockchip,rk3066-i2s";
+ reg = <0xff890000 0x10000>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dmas = <&dmac_bus_s 0>, <&dmac_bus_s 1>;
+ dma-names = "tx", "rx";
+ clock-names = "i2s_hclk", "i2s_clk";
+ clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_bus>;
+ status = "disabled";
+ };
+
+ vopb: vop@ff930000 {
+ compatible = "rockchip,rk3288-vop";
+ reg = <0xff930000 0x19c>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>;
+ clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+ resets = <&cru SRST_LCDC0_AXI>, <&cru SRST_LCDC0_AHB>, <&cru SRST_LCDC0_DCLK>;
+ reset-names = "axi", "ahb", "dclk";
+ iommus = <&vopb_mmu>;
+ status = "disabled";
+
+ vopb_out: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vopb_out_hdmi: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&hdmi_in_vopb>;
+ };
+ };
+ };
+
+ vopb_mmu: iommu@ff930300 {
+ compatible = "rockchip,iommu";
+ reg = <0xff930300 0x100>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "vopb_mmu";
+ #iommu-cells = <0>;
+ status = "disabled";
+ };
+
+ vopl: vop@ff940000 {
+ compatible = "rockchip,rk3288-vop";
+ reg = <0xff940000 0x19c>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_VOP1>, <&cru DCLK_VOP1>, <&cru HCLK_VOP1>;
+ clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+ resets = <&cru SRST_LCDC1_AXI>, <&cru SRST_LCDC1_AHB>, <&cru SRST_LCDC1_DCLK>;
+ reset-names = "axi", "ahb", "dclk";
+ iommus = <&vopl_mmu>;
+ status = "disabled";
+
+ vopl_out: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vopl_out_hdmi: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&hdmi_in_vopl>;
+ };
+ };
+ };
+
+ vopl_mmu: iommu@ff940300 {
+ compatible = "rockchip,iommu";
+ reg = <0xff940300 0x100>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "vopl_mmu";
+ #iommu-cells = <0>;
+ status = "disabled";
+ };
+
+ hdmi: hdmi@ff980000 {
+ compatible = "rockchip,rk3288-dw-hdmi";
+ reg = <0xff980000 0x20000>;
+ reg-io-width = <4>;
+ rockchip,grf = <&grf>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>;
+ clock-names = "iahb", "isfr";
+ status = "disabled";
+
+ ports {
+ hdmi_in: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ hdmi_in_vopb: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&vopb_out_hdmi>;
+ };
+ hdmi_in_vopl: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&vopl_out_hdmi>;
+ };
+ };
+ };
+ };
+
+ gic: interrupt-controller@ffc01000 {
+ compatible = "arm,gic-400";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+
+ reg = <0xffc01000 0x1000>,
+ <0xffc02000 0x1000>,
+ <0xffc04000 0x2000>,
+ <0xffc06000 0x2000>;
+ interrupts = <GIC_PPI 9 0xf04>;
+ };
+
+ usbphy: phy {
+ compatible = "rockchip,rk3288-usb-phy";
+ rockchip,grf = <&grf>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ usbphy0: usb-phy0 {
+ #phy-cells = <0>;
+ reg = <0x320>;
+ clocks = <&cru SCLK_OTGPHY0>;
+ clock-names = "phyclk";
+ };
+
+ usbphy1: usb-phy1 {
+ #phy-cells = <0>;
+ reg = <0x334>;
+ clocks = <&cru SCLK_OTGPHY1>;
+ clock-names = "phyclk";
+ };
+
+ usbphy2: usb-phy2 {
+ #phy-cells = <0>;
+ reg = <0x348>;
+ clocks = <&cru SCLK_OTGPHY2>;
+ clock-names = "phyclk";
+ };
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rk3288-pinctrl";
+ rockchip,grf = <&grf>;
+ rockchip,pmu = <&pmu>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio0: gpio0@ff750000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff750000 0x100>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio1@ff780000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff780000 0x100>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO1>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio2@ff790000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff790000 0x100>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO2>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio3@ff7a0000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff7a0000 0x100>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO3>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio4@ff7b0000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff7b0000 0x100>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO4>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio5: gpio5@ff7c0000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff7c0000 0x100>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO5>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio6: gpio6@ff7d0000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff7d0000 0x100>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO6>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio7: gpio7@ff7e0000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff7e0000 0x100>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO7>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio8: gpio8@ff7f0000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff7f0000 0x100>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO8>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pcfg_pull_up: pcfg-pull-up {
+ bias-pull-up;
+ };
+
+ pcfg_pull_down: pcfg-pull-down {
+ bias-pull-down;
+ };
+
+ pcfg_pull_none: pcfg-pull-none {
+ bias-disable;
+ };
+
+ pcfg_pull_none_12ma: pcfg-pull-none-12ma {
+ bias-disable;
+ drive-strength = <12>;
+ };
+
+ sleep {
+ global_pwroff: global-pwroff {
+ rockchip,pins = <0 0 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ ddrio_pwroff: ddrio-pwroff {
+ rockchip,pins = <0 1 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ ddr0_retention: ddr0-retention {
+ rockchip,pins = <0 2 RK_FUNC_1 &pcfg_pull_up>;
+ };
+
+ ddr1_retention: ddr1-retention {
+ rockchip,pins = <0 3 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ };
+
+ i2c0 {
+ i2c0_xfer: i2c0-xfer {
+ rockchip,pins = <0 15 RK_FUNC_1 &pcfg_pull_none>,
+ <0 16 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c1 {
+ i2c1_xfer: i2c1-xfer {
+ rockchip,pins = <8 4 RK_FUNC_1 &pcfg_pull_none>,
+ <8 5 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c2 {
+ i2c2_xfer: i2c2-xfer {
+ rockchip,pins = <6 9 RK_FUNC_1 &pcfg_pull_none>,
+ <6 10 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c3 {
+ i2c3_xfer: i2c3-xfer {
+ rockchip,pins = <2 16 RK_FUNC_1 &pcfg_pull_none>,
+ <2 17 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c4 {
+ i2c4_xfer: i2c4-xfer {
+ rockchip,pins = <7 17 RK_FUNC_1 &pcfg_pull_none>,
+ <7 18 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c5 {
+ i2c5_xfer: i2c5-xfer {
+ rockchip,pins = <7 19 RK_FUNC_1 &pcfg_pull_none>,
+ <7 20 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2s0 {
+ i2s0_bus: i2s0-bus {
+ rockchip,pins = <6 0 RK_FUNC_1 &pcfg_pull_none>,
+ <6 1 RK_FUNC_1 &pcfg_pull_none>,
+ <6 2 RK_FUNC_1 &pcfg_pull_none>,
+ <6 3 RK_FUNC_1 &pcfg_pull_none>,
+ <6 4 RK_FUNC_1 &pcfg_pull_none>,
+ <6 8 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ sdmmc {
+ sdmmc_clk: sdmmc-clk {
+ rockchip,pins = <6 20 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sdmmc_cmd: sdmmc-cmd {
+ rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up>;
+ };
+
+ sdmmc_cd: sdmcc-cd {
+ rockchip,pins = <6 22 RK_FUNC_1 &pcfg_pull_up>;
+ };
+
+ sdmmc_bus1: sdmmc-bus1 {
+ rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up>;
+ };
+
+ sdmmc_bus4: sdmmc-bus4 {
+ rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up>,
+ <6 17 RK_FUNC_1 &pcfg_pull_up>,
+ <6 18 RK_FUNC_1 &pcfg_pull_up>,
+ <6 19 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ };
+
+ sdio0 {
+ sdio0_bus1: sdio0-bus1 {
+ rockchip,pins = <4 20 RK_FUNC_1 &pcfg_pull_up>;
+ };
+
+ sdio0_bus4: sdio0-bus4 {
+ rockchip,pins = <4 20 RK_FUNC_1 &pcfg_pull_up>,
+ <4 21 RK_FUNC_1 &pcfg_pull_up>,
+ <4 22 RK_FUNC_1 &pcfg_pull_up>,
+ <4 23 RK_FUNC_1 &pcfg_pull_up>;
+ };
+
+ sdio0_cmd: sdio0-cmd {
+ rockchip,pins = <4 24 RK_FUNC_1 &pcfg_pull_up>;
+ };
+
+ sdio0_clk: sdio0-clk {
+ rockchip,pins = <4 25 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sdio0_cd: sdio0-cd {
+ rockchip,pins = <4 26 RK_FUNC_1 &pcfg_pull_up>;
+ };
+
+ sdio0_wp: sdio0-wp {
+ rockchip,pins = <4 27 RK_FUNC_1 &pcfg_pull_up>;
+ };
+
+ sdio0_pwr: sdio0-pwr {
+ rockchip,pins = <4 28 RK_FUNC_1 &pcfg_pull_up>;
+ };
+
+ sdio0_bkpwr: sdio0-bkpwr {
+ rockchip,pins = <4 29 RK_FUNC_1 &pcfg_pull_up>;
+ };
+
+ sdio0_int: sdio0-int {
+ rockchip,pins = <4 30 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ };
+
+ sdio1 {
+ sdio1_bus1: sdio1-bus1 {
+ rockchip,pins = <3 24 4 &pcfg_pull_up>;
+ };
+
+ sdio1_bus4: sdio1-bus4 {
+ rockchip,pins = <3 24 4 &pcfg_pull_up>,
+ <3 25 4 &pcfg_pull_up>,
+ <3 26 4 &pcfg_pull_up>,
+ <3 27 4 &pcfg_pull_up>;
+ };
+
+ sdio1_cd: sdio1-cd {
+ rockchip,pins = <3 28 4 &pcfg_pull_up>;
+ };
+
+ sdio1_wp: sdio1-wp {
+ rockchip,pins = <3 29 4 &pcfg_pull_up>;
+ };
+
+ sdio1_bkpwr: sdio1-bkpwr {
+ rockchip,pins = <3 30 4 &pcfg_pull_up>;
+ };
+
+ sdio1_int: sdio1-int {
+ rockchip,pins = <3 31 4 &pcfg_pull_up>;
+ };
+
+ sdio1_cmd: sdio1-cmd {
+ rockchip,pins = <4 6 4 &pcfg_pull_up>;
+ };
+
+ sdio1_clk: sdio1-clk {
+ rockchip,pins = <4 7 4 &pcfg_pull_none>;
+ };
+
+ sdio1_pwr: sdio1-pwr {
+ rockchip,pins = <4 9 4 &pcfg_pull_up>;
+ };
+ };
+
+ emmc {
+ emmc_clk: emmc-clk {
+ rockchip,pins = <3 18 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ emmc_cmd: emmc-cmd {
+ rockchip,pins = <3 16 RK_FUNC_2 &pcfg_pull_up>;
+ };
+
+ emmc_pwr: emmc-pwr {
+ rockchip,pins = <3 9 RK_FUNC_2 &pcfg_pull_up>;
+ };
+
+ emmc_bus1: emmc-bus1 {
+ rockchip,pins = <3 0 RK_FUNC_2 &pcfg_pull_up>;
+ };
+
+ emmc_bus4: emmc-bus4 {
+ rockchip,pins = <3 0 RK_FUNC_2 &pcfg_pull_up>,
+ <3 1 RK_FUNC_2 &pcfg_pull_up>,
+ <3 2 RK_FUNC_2 &pcfg_pull_up>,
+ <3 3 RK_FUNC_2 &pcfg_pull_up>;
+ };
+
+ emmc_bus8: emmc-bus8 {
+ rockchip,pins = <3 0 RK_FUNC_2 &pcfg_pull_up>,
+ <3 1 RK_FUNC_2 &pcfg_pull_up>,
+ <3 2 RK_FUNC_2 &pcfg_pull_up>,
+ <3 3 RK_FUNC_2 &pcfg_pull_up>,
+ <3 4 RK_FUNC_2 &pcfg_pull_up>,
+ <3 5 RK_FUNC_2 &pcfg_pull_up>,
+ <3 6 RK_FUNC_2 &pcfg_pull_up>,
+ <3 7 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ };
+
+ spi0 {
+ spi0_clk: spi0-clk {
+ rockchip,pins = <5 12 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi0_cs0: spi0-cs0 {
+ rockchip,pins = <5 13 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi0_tx: spi0-tx {
+ rockchip,pins = <5 14 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi0_rx: spi0-rx {
+ rockchip,pins = <5 15 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi0_cs1: spi0-cs1 {
+ rockchip,pins = <5 16 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ };
+ spi1 {
+ spi1_clk: spi1-clk {
+ rockchip,pins = <7 12 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi1_cs0: spi1-cs0 {
+ rockchip,pins = <7 13 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi1_rx: spi1-rx {
+ rockchip,pins = <7 14 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi1_tx: spi1-tx {
+ rockchip,pins = <7 15 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ };
+
+ spi2 {
+ spi2_cs1: spi2-cs1 {
+ rockchip,pins = <8 3 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi2_clk: spi2-clk {
+ rockchip,pins = <8 6 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi2_cs0: spi2-cs0 {
+ rockchip,pins = <8 7 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi2_rx: spi2-rx {
+ rockchip,pins = <8 8 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi2_tx: spi2-tx {
+ rockchip,pins = <8 9 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ };
+
+ uart0 {
+ uart0_xfer: uart0-xfer {
+ rockchip,pins = <4 16 RK_FUNC_1 &pcfg_pull_up>,
+ <4 17 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_cts: uart0-cts {
+ rockchip,pins = <4 18 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_rts: uart0-rts {
+ rockchip,pins = <4 19 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart1 {
+ uart1_xfer: uart1-xfer {
+ rockchip,pins = <5 8 RK_FUNC_1 &pcfg_pull_up>,
+ <5 9 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart1_cts: uart1-cts {
+ rockchip,pins = <5 10 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart1_rts: uart1-rts {
+ rockchip,pins = <5 11 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart2 {
+ uart2_xfer: uart2-xfer {
+ rockchip,pins = <7 22 RK_FUNC_1 &pcfg_pull_up>,
+ <7 23 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ /* no rts / cts for uart2 */
+ };
+
+ uart3 {
+ uart3_xfer: uart3-xfer {
+ rockchip,pins = <7 7 RK_FUNC_1 &pcfg_pull_up>,
+ <7 8 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart3_cts: uart3-cts {
+ rockchip,pins = <7 9 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart3_rts: uart3-rts {
+ rockchip,pins = <7 10 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart4 {
+ uart4_xfer: uart4-xfer {
+ rockchip,pins = <5 12 3 &pcfg_pull_up>,
+ <5 13 3 &pcfg_pull_none>;
+ };
+
+ uart4_cts: uart4-cts {
+ rockchip,pins = <5 14 3 &pcfg_pull_none>;
+ };
+
+ uart4_rts: uart4-rts {
+ rockchip,pins = <5 15 3 &pcfg_pull_none>;
+ };
+ };
+
+ tsadc {
+ otp_out: otp-out {
+ rockchip,pins = <0 10 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm0 {
+ pwm0_pin: pwm0-pin {
+ rockchip,pins = <7 0 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm1 {
+ pwm1_pin: pwm1-pin {
+ rockchip,pins = <7 1 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm2 {
+ pwm2_pin: pwm2-pin {
+ rockchip,pins = <7 22 3 &pcfg_pull_none>;
+ };
+ };
+
+ pwm3 {
+ pwm3_pin: pwm3-pin {
+ rockchip,pins = <7 23 3 &pcfg_pull_none>;
+ };
+ };
+
+ gmac {
+ rgmii_pins: rgmii-pins {
+ rockchip,pins = <3 30 3 &pcfg_pull_none>,
+ <3 31 3 &pcfg_pull_none>,
+ <3 26 3 &pcfg_pull_none>,
+ <3 27 3 &pcfg_pull_none>,
+ <3 28 3 &pcfg_pull_none_12ma>,
+ <3 29 3 &pcfg_pull_none_12ma>,
+ <3 24 3 &pcfg_pull_none_12ma>,
+ <3 25 3 &pcfg_pull_none_12ma>,
+ <4 0 3 &pcfg_pull_none>,
+ <4 5 3 &pcfg_pull_none>,
+ <4 6 3 &pcfg_pull_none>,
+ <4 9 3 &pcfg_pull_none_12ma>,
+ <4 4 3 &pcfg_pull_none_12ma>,
+ <4 1 3 &pcfg_pull_none>,
+ <4 3 3 &pcfg_pull_none>;
+ };
+
+ rmii_pins: rmii-pins {
+ rockchip,pins = <3 30 3 &pcfg_pull_none>,
+ <3 31 3 &pcfg_pull_none>,
+ <3 28 3 &pcfg_pull_none>,
+ <3 29 3 &pcfg_pull_none>,
+ <4 0 3 &pcfg_pull_none>,
+ <4 5 3 &pcfg_pull_none>,
+ <4 4 3 &pcfg_pull_none>,
+ <4 1 3 &pcfg_pull_none>,
+ <4 2 3 &pcfg_pull_none>,
+ <4 3 3 &pcfg_pull_none>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
new file mode 100644
index 000000000..c54a9715d
--- /dev/null
+++ b/arch/arm/boot/dts/rk3xxx.dtsi
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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 <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&gic>;
+
+ aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ mshc0 = &emmc;
+ mshc1 = &mmc0;
+ mshc2 = &mmc1;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dmac1_s: dma-controller@20018000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x20018000 0x4000>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ clocks = <&cru ACLK_DMA1>;
+ clock-names = "apb_pclk";
+ };
+
+ dmac1_ns: dma-controller@2001c000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x2001c000 0x4000>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ clocks = <&cru ACLK_DMA1>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ dmac2: dma-controller@20078000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x20078000 0x4000>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ clocks = <&cru ACLK_DMA2>;
+ clock-names = "apb_pclk";
+ };
+ };
+
+ xin24m: oscillator {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ #clock-cells = <0>;
+ clock-output-names = "xin24m";
+ };
+
+ L2: l2-cache-controller@10138000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x10138000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ scu@1013c000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0x1013c000 0x100>;
+ };
+
+ global_timer: global-timer@1013c200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x1013c200 0x20>;
+ interrupts = <GIC_PPI 11 0x304>;
+ clocks = <&cru CORE_PERI>;
+ };
+
+ local_timer: local-timer@1013c600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x1013c600 0x20>;
+ interrupts = <GIC_PPI 13 0x304>;
+ clocks = <&cru CORE_PERI>;
+ };
+
+ gic: interrupt-controller@1013d000 {
+ compatible = "arm,cortex-a9-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x1013d000 0x1000>,
+ <0x1013c100 0x0100>;
+ };
+
+ uart0: serial@10124000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x10124000 0x400>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ clock-names = "baudclk", "apb_pclk";
+ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+ status = "disabled";
+ };
+
+ uart1: serial@10126000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x10126000 0x400>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ clock-names = "baudclk", "apb_pclk";
+ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+ status = "disabled";
+ };
+
+ usb_otg: usb@10180000 {
+ compatible = "rockchip,rk3066-usb", "snps,dwc2";
+ reg = <0x10180000 0x40000>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_OTG0>;
+ clock-names = "otg";
+ status = "disabled";
+ };
+
+ usb_host: usb@101c0000 {
+ compatible = "snps,dwc2";
+ reg = <0x101c0000 0x40000>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_OTG1>;
+ clock-names = "otg";
+ status = "disabled";
+ };
+
+ emac: ethernet@10204000 {
+ compatible = "snps,arc-emac";
+ reg = <0x10204000 0x3c>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clocks = <&cru HCLK_EMAC>, <&cru SCLK_MAC>;
+ clock-names = "hclk", "macref";
+ max-speed = <100>;
+ phy-mode = "rmii";
+
+ status = "disabled";
+ };
+
+ mmc0: dwmmc@10214000 {
+ compatible = "rockchip,rk2928-dw-mshc";
+ reg = <0x10214000 0x1000>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <256>;
+ status = "disabled";
+ };
+
+ mmc1: dwmmc@10218000 {
+ compatible = "rockchip,rk2928-dw-mshc";
+ reg = <0x10218000 0x1000>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <256>;
+ status = "disabled";
+ };
+
+ emmc: dwmmc@1021c000 {
+ compatible = "rockchip,rk2928-dw-mshc";
+ reg = <0x1021c000 0x1000>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <256>;
+ status = "disabled";
+ };
+
+ pmu: pmu@20004000 {
+ compatible = "rockchip,rk3066-pmu", "syscon";
+ reg = <0x20004000 0x100>;
+ };
+
+ grf: grf@20008000 {
+ compatible = "syscon";
+ reg = <0x20008000 0x200>;
+ };
+
+ i2c0: i2c@2002d000 {
+ compatible = "rockchip,rk3066-i2c";
+ reg = <0x2002d000 0x1000>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clock-names = "i2c";
+ clocks = <&cru PCLK_I2C0>;
+
+ status = "disabled";
+ };
+
+ i2c1: i2c@2002f000 {
+ compatible = "rockchip,rk3066-i2c";
+ reg = <0x2002f000 0x1000>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clocks = <&cru PCLK_I2C1>;
+ clock-names = "i2c";
+
+ status = "disabled";
+ };
+
+ pwm0: pwm@20030000 {
+ compatible = "rockchip,rk2928-pwm";
+ reg = <0x20030000 0x10>;
+ #pwm-cells = <2>;
+ clocks = <&cru PCLK_PWM01>;
+ status = "disabled";
+ };
+
+ pwm1: pwm@20030010 {
+ compatible = "rockchip,rk2928-pwm";
+ reg = <0x20030010 0x10>;
+ #pwm-cells = <2>;
+ clocks = <&cru PCLK_PWM01>;
+ status = "disabled";
+ };
+
+ wdt: watchdog@2004c000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x2004c000 0x100>;
+ clocks = <&cru PCLK_WDT>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ pwm2: pwm@20050020 {
+ compatible = "rockchip,rk2928-pwm";
+ reg = <0x20050020 0x10>;
+ #pwm-cells = <2>;
+ clocks = <&cru PCLK_PWM23>;
+ status = "disabled";
+ };
+
+ pwm3: pwm@20050030 {
+ compatible = "rockchip,rk2928-pwm";
+ reg = <0x20050030 0x10>;
+ #pwm-cells = <2>;
+ clocks = <&cru PCLK_PWM23>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@20056000 {
+ compatible = "rockchip,rk3066-i2c";
+ reg = <0x20056000 0x1000>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clocks = <&cru PCLK_I2C2>;
+ clock-names = "i2c";
+
+ status = "disabled";
+ };
+
+ i2c3: i2c@2005a000 {
+ compatible = "rockchip,rk3066-i2c";
+ reg = <0x2005a000 0x1000>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clocks = <&cru PCLK_I2C3>;
+ clock-names = "i2c";
+
+ status = "disabled";
+ };
+
+ i2c4: i2c@2005e000 {
+ compatible = "rockchip,rk3066-i2c";
+ reg = <0x2005e000 0x1000>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clocks = <&cru PCLK_I2C4>;
+ clock-names = "i2c";
+
+ status = "disabled";
+ };
+
+ uart2: serial@20064000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x20064000 0x400>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ clock-names = "baudclk", "apb_pclk";
+ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+ status = "disabled";
+ };
+
+ uart3: serial@20068000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x20068000 0x400>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ clock-names = "baudclk", "apb_pclk";
+ clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+ status = "disabled";
+ };
+
+ saradc: saradc@2006c000 {
+ compatible = "rockchip,saradc";
+ reg = <0x2006c000 0x100>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ #io-channel-cells = <1>;
+ clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
+ clock-names = "saradc", "apb_pclk";
+ status = "disabled";
+ };
+
+ spi0: spi@20070000 {
+ compatible = "rockchip,rk3066-spi";
+ clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
+ clock-names = "spiclk", "apb_pclk";
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x20070000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dmas = <&dmac2 10>, <&dmac2 11>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ spi1: spi@20074000 {
+ compatible = "rockchip,rk3066-spi";
+ clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
+ clock-names = "spiclk", "apb_pclk";
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x20074000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dmas = <&dmac2 12>, <&dmac2 13>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/s3c2416-pinctrl.dtsi b/arch/arm/boot/dts/s3c2416-pinctrl.dtsi
new file mode 100644
index 000000000..527e31938
--- /dev/null
+++ b/arch/arm/boot/dts/s3c2416-pinctrl.dtsi
@@ -0,0 +1,173 @@
+/*
+ * Samsung S3C2416 pinctrl settings
+ *
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.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.
+ */
+
+&pinctrl_0 {
+ /*
+ * Pin banks
+ */
+
+ gpa: gpa {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpb: gpb {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpc: gpc {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpd: gpd {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpe: gpe {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpf: gpf {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg: gpg {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gph: gph {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpj: gpj {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpk: gpk {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpl: gpl {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpm: gpm {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ /*
+ * Pin groups
+ */
+
+ uart0_data: uart0-data {
+ samsung,pins = "gph-0", "gph-1";
+ samsung,pin-function = <2>;
+ };
+
+ uart0_fctl: uart0-fctl {
+ samsung,pins = "gph-8", "gph-9";
+ samsung,pin-function = <2>;
+ };
+
+ uart1_data: uart1-data {
+ samsung,pins = "gph-2", "gph-3";
+ samsung,pin-function = <2>;
+ };
+
+ uart1_fctl: uart1-fctl {
+ samsung,pins = "gph-10", "gph-11";
+ samsung,pin-function = <2>;
+ };
+
+ uart2_data: uart2-data {
+ samsung,pins = "gph-4", "gph-5";
+ samsung,pin-function = <2>;
+ };
+
+ uart2_fctl: uart2-fctl {
+ samsung,pins = "gph-6", "gph-7";
+ samsung,pin-function = <2>;
+ };
+
+ uart3_data: uart3-data {
+ samsung,pins = "gph-6", "gph-7";
+ samsung,pin-function = <2>;
+ };
+
+ extuart_clk: extuart-clk {
+ samsung,pins = "gph-12";
+ samsung,pin-function = <2>;
+ };
+
+ i2c0_bus: i2c0-bus {
+ samsung,pins = "gpe-14", "gpe-15";
+ samsung,pin-function = <2>;
+ };
+
+ spi0_bus: spi0-bus {
+ samsung,pins = "gpe-11", "gpe-12", "gpe-13";
+ samsung,pin-function = <2>;
+ };
+
+ sd0_clk: sd0-clk {
+ samsung,pins = "gpe-5";
+ samsung,pin-function = <2>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ samsung,pins = "gpe-6";
+ samsung,pin-function = <2>;
+ };
+
+ sd0_bus1: sd0-bus1 {
+ samsung,pins = "gpe-7";
+ samsung,pin-function = <2>;
+ };
+
+ sd0_bus4: sd0-bus4 {
+ samsung,pins = "gpe-8", "gpe-9", "gpe-10";
+ samsung,pin-function = <2>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ samsung,pins = "gpl-8";
+ samsung,pin-function = <2>;
+ };
+
+ sd1_clk: sd1-clk {
+ samsung,pins = "gpl-9";
+ samsung,pin-function = <2>;
+ };
+
+ sd1_bus1: sd1-bus1 {
+ samsung,pins = "gpl-0";
+ samsung,pin-function = <2>;
+ };
+
+ sd1_bus4: sd1-bus4 {
+ samsung,pins = "gpl-1", "gpl-2", "gpl-3";
+ samsung,pin-function = <2>;
+ };
+};
diff --git a/arch/arm/boot/dts/s3c2416-smdk2416.dts b/arch/arm/boot/dts/s3c2416-smdk2416.dts
new file mode 100644
index 000000000..ea92fd695
--- /dev/null
+++ b/arch/arm/boot/dts/s3c2416-smdk2416.dts
@@ -0,0 +1,85 @@
+/*
+ * SAMSUNG SMDK2416 board device tree source
+ *
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.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.
+ */
+
+/dts-v1/;
+#include "s3c2416.dtsi"
+
+/ {
+ model = "SMDK2416";
+ compatible = "samsung,s3c2416";
+
+ memory {
+ reg = <0x30000000 0x4000000>;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ xti: xti {
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ clock-output-names = "xti";
+ #clock-cells = <0>;
+ };
+ };
+
+ serial@50000000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_data>, <&uart0_fctl>;
+ };
+
+ serial@50004000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_data>, <&uart1_fctl>;
+ };
+
+ serial@50008000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_data>;
+ };
+
+ serial@5000C000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_data>;
+ };
+
+ watchdog@53000000 {
+ status = "okay";
+ };
+
+ rtc@57000000 {
+ status = "okay";
+ };
+
+ sdhci@4AC00000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk>, <&sd0_cmd>,
+ <&sd0_bus1>, <&sd0_bus4>;
+ bus-width = <4>;
+ cd-gpios = <&gpf 1 0>;
+ cd-inverted;
+ status = "okay";
+ };
+
+ sdhci@4A800000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd1_clk>, <&sd1_cmd>,
+ <&sd1_bus1>, <&sd1_bus4>;
+ bus-width = <4>;
+ broken-cd;
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/s3c2416.dtsi b/arch/arm/boot/dts/s3c2416.dtsi
new file mode 100644
index 000000000..30b8f7e47
--- /dev/null
+++ b/arch/arm/boot/dts/s3c2416.dtsi
@@ -0,0 +1,125 @@
+/*
+ * Samsung's S3C2416 SoC device tree source
+ *
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.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 <dt-bindings/clock/s3c2443.h>
+#include "s3c24xx.dtsi"
+#include "s3c2416-pinctrl.dtsi"
+
+/ {
+ model = "Samsung S3C2416 SoC";
+ compatible = "samsung,s3c2416";
+
+ aliases {
+ serial3 = &uart3;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm926ejs";
+ };
+ };
+
+ interrupt-controller@4a000000 {
+ compatible = "samsung,s3c2416-irq";
+ };
+
+ clocks: clock-controller@0x4c000000 {
+ compatible = "samsung,s3c2416-clock";
+ reg = <0x4c000000 0x40>;
+ #clock-cells = <1>;
+ };
+
+ pinctrl@56000000 {
+ compatible = "samsung,s3c2416-pinctrl";
+ };
+
+ timer@51000000 {
+ clocks = <&clocks PCLK_PWM>;
+ clock-names = "timers";
+ };
+
+ serial@50000000 {
+ compatible = "samsung,s3c2440-uart";
+ clock-names = "uart", "clk_uart_baud2",
+ "clk_uart_baud3";
+ clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>,
+ <&clocks SCLK_UART>;
+ };
+
+ serial@50004000 {
+ compatible = "samsung,s3c2440-uart";
+ clock-names = "uart", "clk_uart_baud2",
+ "clk_uart_baud3";
+ clocks = <&clocks PCLK_UART1>, <&clocks PCLK_UART1>,
+ <&clocks SCLK_UART>;
+ };
+
+ serial@50008000 {
+ compatible = "samsung,s3c2440-uart";
+ clock-names = "uart", "clk_uart_baud2",
+ "clk_uart_baud3";
+ clocks = <&clocks PCLK_UART2>, <&clocks PCLK_UART2>,
+ <&clocks SCLK_UART>;
+ };
+
+ uart3: serial@5000C000 {
+ compatible = "samsung,s3c2440-uart";
+ reg = <0x5000C000 0x4000>;
+ interrupts = <1 18 24 4>, <1 18 25 4>;
+ clock-names = "uart", "clk_uart_baud2",
+ "clk_uart_baud3";
+ clocks = <&clocks PCLK_UART3>, <&clocks PCLK_UART3>,
+ <&clocks SCLK_UART>;
+ status = "disabled";
+ };
+
+ sdhci@4AC00000 {
+ compatible = "samsung,s3c6410-sdhci";
+ reg = <0x4AC00000 0x100>;
+ interrupts = <0 0 21 3>;
+ clock-names = "hsmmc", "mmc_busclk.0",
+ "mmc_busclk.2";
+ clocks = <&clocks HCLK_HSMMC0>, <&clocks HCLK_HSMMC0>,
+ <&clocks MUX_HSMMC0>;
+ status = "disabled";
+ };
+
+ sdhci@4A800000 {
+ compatible = "samsung,s3c6410-sdhci";
+ reg = <0x4A800000 0x100>;
+ interrupts = <0 0 20 3>;
+ clock-names = "hsmmc", "mmc_busclk.0",
+ "mmc_busclk.2";
+ clocks = <&clocks HCLK_HSMMC1>, <&clocks HCLK_HSMMC1>,
+ <&clocks MUX_HSMMC1>;
+ status = "disabled";
+ };
+
+ watchdog@53000000 {
+ interrupts = <1 9 27 3>;
+ clocks = <&clocks PCLK_WDT>;
+ clock-names = "watchdog";
+ };
+
+ rtc@57000000 {
+ compatible = "samsung,s3c2416-rtc";
+ clocks = <&clocks PCLK_RTC>;
+ clock-names = "rtc";
+ };
+
+ i2c@54000000 {
+ compatible = "samsung,s3c2440-i2c";
+ clocks = <&clocks PCLK_I2C0>;
+ clock-names = "i2c";
+ };
+};
diff --git a/arch/arm/boot/dts/s3c24xx.dtsi b/arch/arm/boot/dts/s3c24xx.dtsi
new file mode 100644
index 000000000..5ed43b857
--- /dev/null
+++ b/arch/arm/boot/dts/s3c24xx.dtsi
@@ -0,0 +1,95 @@
+/*
+ * Samsung's S3C24XX family device tree source
+ *
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.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 "skeleton.dtsi"
+
+/ {
+ compatible = "samsung,s3c24xx";
+ interrupt-parent = <&intc>;
+
+ aliases {
+ pinctrl0 = &pinctrl_0;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ };
+
+ intc:interrupt-controller@4a000000 {
+ compatible = "samsung,s3c2410-irq";
+ reg = <0x4a000000 0x100>;
+ interrupt-controller;
+ #interrupt-cells = <4>;
+ };
+
+ pinctrl_0: pinctrl@56000000 {
+ reg = <0x56000000 0x1000>;
+
+ wakeup-interrupt-controller {
+ compatible = "samsung,s3c2410-wakeup-eint";
+ interrupts = <0 0 0 3>,
+ <0 0 1 3>,
+ <0 0 2 3>,
+ <0 0 3 3>,
+ <0 0 4 4>,
+ <0 0 5 4>;
+ };
+ };
+
+ timer@51000000 {
+ compatible = "samsung,s3c2410-pwm";
+ reg = <0x51000000 0x1000>;
+ interrupts = <0 0 10 3>, <0 0 11 3>, <0 0 12 3>, <0 0 13 3>, <0 0 14 3>;
+ #pwm-cells = <4>;
+ };
+
+ uart0: serial@50000000 {
+ compatible = "samsung,s3c2410-uart";
+ reg = <0x50000000 0x4000>;
+ interrupts = <1 28 0 4>, <1 28 1 4>;
+ status = "disabled";
+ };
+
+ uart1: serial@50004000 {
+ compatible = "samsung,s3c2410-uart";
+ reg = <0x50004000 0x4000>;
+ interrupts = <1 23 3 4>, <1 23 4 4>;
+ status = "disabled";
+ };
+
+ uart2: serial@50008000 {
+ compatible = "samsung,s3c2410-uart";
+ reg = <0x50008000 0x4000>;
+ interrupts = <1 15 6 4>, <1 15 7 4>;
+ status = "disabled";
+ };
+
+ watchdog@53000000 {
+ compatible = "samsung,s3c2410-wdt";
+ reg = <0x53000000 0x100>;
+ interrupts = <0 0 9 3>;
+ status = "disabled";
+ };
+
+ rtc@57000000 {
+ compatible = "samsung,s3c2410-rtc";
+ reg = <0x57000000 0x100>;
+ interrupts = <0 0 30 3>, <0 0 8 3>;
+ status = "disabled";
+ };
+
+ i2c@54000000 {
+ compatible = "samsung,s3c2410-i2c";
+ reg = <0x54000000 0x100>;
+ interrupts = <0 0 27 3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/s3c6400.dtsi b/arch/arm/boot/dts/s3c6400.dtsi
new file mode 100644
index 000000000..a7d1c8ec1
--- /dev/null
+++ b/arch/arm/boot/dts/s3c6400.dtsi
@@ -0,0 +1,41 @@
+/*
+ * Samsung's S3C6400 SoC device tree source
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Samsung's S3C6400 SoC device nodes are listed in this file. S3C6400
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * S3C6400 SoC. As device tree coverage for S3C6400 increases, additional
+ * nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include "s3c64xx.dtsi"
+
+/ {
+ compatible = "samsung,s3c6400";
+};
+
+&vic0 {
+ valid-mask = <0xfffffe1f>;
+ valid-wakeup-mask = <0x00200004>;
+};
+
+&vic1 {
+ valid-mask = <0xffffffff>;
+ valid-wakeup-mask = <0x53020000>;
+};
+
+&soc {
+ clocks: clock-controller@7e00f000 {
+ compatible = "samsung,s3c6400-clock";
+ reg = <0x7e00f000 0x1000>;
+ #clock-cells = <1>;
+ };
+};
diff --git a/arch/arm/boot/dts/s3c6410-mini6410.dts b/arch/arm/boot/dts/s3c6410-mini6410.dts
new file mode 100644
index 000000000..a25debb50
--- /dev/null
+++ b/arch/arm/boot/dts/s3c6410-mini6410.dts
@@ -0,0 +1,224 @@
+/*
+ * Samsung's S3C6410 based Mini6410 board device tree source
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Device tree source file for FriendlyARM Mini6410 board which is based on
+ * Samsung's S3C6410 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "s3c6410.dtsi"
+
+/ {
+ model = "FriendlyARM Mini6410 board based on S3C6410";
+ compatible = "friendlyarm,mini6410", "samsung,s3c6410";
+
+ memory {
+ reg = <0x50000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttySAC0,115200n8 earlyprintk rootwait root=/dev/mmcblk0p1";
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ fin_pll: oscillator@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ clock-frequency = <12000000>;
+ clock-output-names = "fin_pll";
+ #clock-cells = <0>;
+ };
+
+ xusbxti: oscillator@1 {
+ compatible = "fixed-clock";
+ reg = <1>;
+ clock-output-names = "xusbxti";
+ clock-frequency = <48000000>;
+ #clock-cells = <0>;
+ };
+ };
+
+ srom-cs1@18000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x18000000 0x8000000>;
+ ranges;
+
+ ethernet@18000000 {
+ compatible = "davicom,dm9000";
+ reg = <0x18000000 0x2 0x18000004 0x2>;
+ interrupt-parent = <&gpn>;
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
+ davicom,no-eeprom;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_keys>;
+ autorepeat;
+
+ button-k1 {
+ label = "K1";
+ gpios = <&gpn 0 GPIO_ACTIVE_LOW>;
+ linux,code = <2>;
+ debounce-interval = <20>;
+ };
+
+ button-k2 {
+ label = "K2";
+ gpios = <&gpn 1 GPIO_ACTIVE_LOW>;
+ linux,code = <3>;
+ debounce-interval = <20>;
+ };
+
+ button-k3 {
+ label = "K3";
+ gpios = <&gpn 2 GPIO_ACTIVE_LOW>;
+ linux,code = <4>;
+ debounce-interval = <20>;
+ };
+
+ button-k4 {
+ label = "K4";
+ gpios = <&gpn 3 GPIO_ACTIVE_LOW>;
+ linux,code = <5>;
+ debounce-interval = <20>;
+ };
+
+ button-k5 {
+ label = "K5";
+ gpios = <&gpn 4 GPIO_ACTIVE_LOW>;
+ linux,code = <6>;
+ debounce-interval = <20>;
+ };
+
+ button-k6 {
+ label = "K6";
+ gpios = <&gpn 5 GPIO_ACTIVE_LOW>;
+ linux,code = <7>;
+ debounce-interval = <20>;
+ };
+
+ button-k7 {
+ label = "K7";
+ gpios = <&gpl 11 GPIO_ACTIVE_LOW>;
+ linux,code = <8>;
+ debounce-interval = <20>;
+ };
+
+ button-k8 {
+ label = "K8";
+ gpios = <&gpl 12 GPIO_ACTIVE_LOW>;
+ linux,code = <9>;
+ debounce-interval = <20>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_leds>;
+
+ led-1 {
+ label = "LED1";
+ gpios = <&gpk 4 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ led-2 {
+ label = "LED2";
+ gpios = <&gpk 5 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "mmc0";
+ };
+
+ led-3 {
+ label = "LED3";
+ gpios = <&gpk 6 GPIO_ACTIVE_LOW>;
+ };
+
+ led-4 {
+ label = "LED4";
+ gpios = <&gpk 7 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ buzzer {
+ compatible = "pwm-beeper";
+ pwms = <&pwm 0 1000000 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_out>;
+ };
+};
+
+&sdhci0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_data>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_data>, <&uart1_fctl>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_data>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_data>;
+ status = "okay";
+};
+
+&pinctrl0 {
+ gpio_leds: gpio-leds {
+ samsung,pins = "gpk-4", "gpk-5", "gpk-6", "gpk-7";
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ gpio_keys: gpio-keys {
+ samsung,pins = "gpn-0", "gpn-1", "gpn-2", "gpn-3",
+ "gpn-4", "gpn-5", "gpl-11", "gpl-12";
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_bus>;
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "atmel,24c08";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+};
diff --git a/arch/arm/boot/dts/s3c6410-smdk6410.dts b/arch/arm/boot/dts/s3c6410-smdk6410.dts
new file mode 100644
index 000000000..ecf35ec46
--- /dev/null
+++ b/arch/arm/boot/dts/s3c6410-smdk6410.dts
@@ -0,0 +1,103 @@
+/*
+ * Samsung S3C6410 based SMDK6410 board device tree source.
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Device tree source file for SAMSUNG SMDK6410 board which is based on
+ * Samsung's S3C6410 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "s3c6410.dtsi"
+
+/ {
+ model = "SAMSUNG SMDK6410 board based on S3C6410";
+ compatible = "samsung,mini6410", "samsung,s3c6410";
+
+ memory {
+ reg = <0x50000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttySAC0,115200n8 earlyprintk rootwait root=/dev/mmcblk0p1";
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ fin_pll: oscillator@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ clock-frequency = <12000000>;
+ clock-output-names = "fin_pll";
+ #clock-cells = <0>;
+ };
+
+ xusbxti: oscillator@1 {
+ compatible = "fixed-clock";
+ reg = <1>;
+ clock-output-names = "xusbxti";
+ clock-frequency = <48000000>;
+ #clock-cells = <0>;
+ };
+ };
+
+ srom-cs1@18000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x18000000 0x8000000>;
+ ranges;
+
+ ethernet@18000000 {
+ compatible = "smsc,lan9115";
+ reg = <0x18000000 0x10000>;
+ interrupt-parent = <&gpn>;
+ interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
+ phy-mode = "mii";
+ reg-io-width = <4>;
+ smsc,force-internal-phy;
+ };
+ };
+};
+
+&sdhci0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_data>, <&uart0_fctl>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_data>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_data>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_data>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/s3c6410.dtsi b/arch/arm/boot/dts/s3c6410.dtsi
new file mode 100644
index 000000000..eb4226b34
--- /dev/null
+++ b/arch/arm/boot/dts/s3c6410.dtsi
@@ -0,0 +1,57 @@
+/*
+ * Samsung's S3C6410 SoC device tree source
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Samsung's S3C6410 SoC device nodes are listed in this file. S3C6410
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * S3C6410 SoC. As device tree coverage for S3C6410 increases, additional
+ * nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include "s3c64xx.dtsi"
+
+/ {
+ compatible = "samsung,s3c6410";
+
+ aliases {
+ i2c1 = &i2c1;
+ };
+};
+
+&vic0 {
+ valid-mask = <0xffffff7f>;
+ valid-wakeup-mask = <0x00200004>;
+};
+
+&vic1 {
+ valid-mask = <0xffffffff>;
+ valid-wakeup-mask = <0x53020000>;
+};
+
+&soc {
+ clocks: clock-controller@7e00f000 {
+ compatible = "samsung,s3c6410-clock";
+ reg = <0x7e00f000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ i2c1: i2c@7f00f000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x7f00f000 0x1000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <5>;
+ clock-names = "i2c";
+ clocks = <&clocks PCLK_IIC1>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi b/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi
new file mode 100644
index 000000000..b1197d8b0
--- /dev/null
+++ b/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi
@@ -0,0 +1,687 @@
+/*
+ * Samsung's S3C64xx SoC series common device tree source
+ * - pin control-related definitions
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Samsung's S3C64xx SoCs pin banks, pin-mux and pin-config options are
+ * listed as device tree nodes in this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define PIN_PULL_NONE 0
+#define PIN_PULL_DOWN 1
+#define PIN_PULL_UP 2
+
+&pinctrl0 {
+ /*
+ * Pin banks
+ */
+
+ gpa: gpa {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb: gpb {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc: gpc {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd: gpd {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpe: gpe {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpf: gpf {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg: gpg {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gph: gph {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpi: gpi {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpj: gpj {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpk: gpk {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpl: gpl {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpm: gpm {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpn: gpn {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpo: gpo {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpp: gpp {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpq: gpq {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /*
+ * Pin groups
+ */
+
+ uart0_data: uart0-data {
+ samsung,pins = "gpa-0", "gpa-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ uart0_fctl: uart0-fctl {
+ samsung,pins = "gpa-2", "gpa-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ uart1_data: uart1-data {
+ samsung,pins = "gpa-4", "gpa-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ uart1_fctl: uart1-fctl {
+ samsung,pins = "gpa-6", "gpa-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ uart2_data: uart2-data {
+ samsung,pins = "gpb-0", "gpb-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ uart3_data: uart3-data {
+ samsung,pins = "gpb-2", "gpb-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ ext_dma_0: ext-dma-0 {
+ samsung,pins = "gpb-0", "gpb-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ ext_dma_1: ext-dma-1 {
+ samsung,pins = "gpb-2", "gpb-3";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ irda_data_0: irda-data-0 {
+ samsung,pins = "gpb-0", "gpb-1";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ irda_data_1: irda-data-1 {
+ samsung,pins = "gpb-2", "gpb-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ irda_sdbw: irda-sdbw {
+ samsung,pins = "gpb-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ i2c0_bus: i2c0-bus {
+ samsung,pins = "gpb-5", "gpb-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ };
+
+ i2c1_bus: i2c1-bus {
+ /* S3C6410-only */
+ samsung,pins = "gpb-2", "gpb-3";
+ samsung,pin-function = <6>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ };
+
+ spi0_bus: spi0-bus {
+ samsung,pins = "gpc-0", "gpc-1", "gpc-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ };
+
+ spi0_cs: spi0-cs {
+ samsung,pins = "gpc-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ spi1_bus: spi1-bus {
+ samsung,pins = "gpc-4", "gpc-5", "gpc-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ };
+
+ spi1_cs: spi1-cs {
+ samsung,pins = "gpc-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ samsung,pins = "gpg-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ sd0_clk: sd0-clk {
+ samsung,pins = "gpg-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ sd0_bus1: sd0-bus1 {
+ samsung,pins = "gpg-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ sd0_bus4: sd0-bus4 {
+ samsung,pins = "gpg-2", "gpg-3", "gpg-4", "gpg-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ sd0_cd: sd0-cd {
+ samsung,pins = "gpg-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ samsung,pins = "gph-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ sd1_clk: sd1-clk {
+ samsung,pins = "gph-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ sd1_bus1: sd1-bus1 {
+ samsung,pins = "gph-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ sd1_bus4: sd1-bus4 {
+ samsung,pins = "gph-2", "gph-3", "gph-4", "gph-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ sd1_bus8: sd1-bus8 {
+ samsung,pins = "gph-2", "gph-3", "gph-4", "gph-5",
+ "gph-6", "gph-7", "gph-8", "gph-9";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ sd1_cd: sd1-cd {
+ samsung,pins = "gpg-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_UP>;
+ };
+
+ sd2_cmd: sd2-cmd {
+ samsung,pins = "gpc-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ sd2_clk: sd2-clk {
+ samsung,pins = "gpc-5";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ sd2_bus1: sd2-bus1 {
+ samsung,pins = "gph-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ sd2_bus4: sd2-bus4 {
+ samsung,pins = "gph-6", "gph-7", "gph-8", "gph-9";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ i2s0_bus: i2s0-bus {
+ samsung,pins = "gpd-0", "gpd-2", "gpd-3", "gpd-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ i2s0_cdclk: i2s0-cdclk {
+ samsung,pins = "gpd-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ i2s1_bus: i2s1-bus {
+ samsung,pins = "gpe-0", "gpe-2", "gpe-3", "gpe-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ i2s1_cdclk: i2s1-cdclk {
+ samsung,pins = "gpe-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ i2s2_bus: i2s2-bus {
+ /* S3C6410-only */
+ samsung,pins = "gpc-4", "gpc-5", "gpc-6", "gph-6",
+ "gph-8", "gph-9";
+ samsung,pin-function = <5>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ i2s2_cdclk: i2s2-cdclk {
+ /* S3C6410-only */
+ samsung,pins = "gph-7";
+ samsung,pin-function = <5>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ pcm0_bus: pcm0-bus {
+ samsung,pins = "gpd-0", "gpd-2", "gpd-3", "gpd-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ pcm0_extclk: pcm0-extclk {
+ samsung,pins = "gpd-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ pcm1_bus: pcm1-bus {
+ samsung,pins = "gpe-0", "gpe-2", "gpe-3", "gpe-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ pcm1_extclk: pcm1-extclk {
+ samsung,pins = "gpe-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ ac97_bus_0: ac97-bus-0 {
+ samsung,pins = "gpd-0", "gpd-1", "gpd-2", "gpd-3", "gpd-4";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ ac97_bus_1: ac97-bus-1 {
+ samsung,pins = "gpe-0", "gpe-1", "gpe-2", "gpe-3", "gpe-4";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ cam_port: cam-port {
+ samsung,pins = "gpf-0", "gpf-1", "gpf-2", "gpf-4",
+ "gpf-5", "gpf-6", "gpf-7", "gpf-8",
+ "gpf-9", "gpf-10", "gpf-11", "gpf-12";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ cam_rst: cam-rst {
+ samsung,pins = "gpf-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ cam_field: cam-field {
+ /* S3C6410-only */
+ samsung,pins = "gpb-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ pwm_extclk: pwm-extclk {
+ samsung,pins = "gpf-13";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ pwm0_out: pwm0-out {
+ samsung,pins = "gpf-14";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ pwm1_out: pwm1-out {
+ samsung,pins = "gpf-15";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ clkout0: clkout-0 {
+ samsung,pins = "gpf-14";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_col0_0: keypad-col0-0 {
+ samsung,pins = "gph-0";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_col1_0: keypad-col1-0 {
+ samsung,pins = "gph-1";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_col2_0: keypad-col2-0 {
+ samsung,pins = "gph-2";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_col3_0: keypad-col3-0 {
+ samsung,pins = "gph-3";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_col4_0: keypad-col4-0 {
+ samsung,pins = "gph-4";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_col5_0: keypad-col5-0 {
+ samsung,pins = "gph-5";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_col6_0: keypad-col6-0 {
+ samsung,pins = "gph-6";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_col7_0: keypad-col7-0 {
+ samsung,pins = "gph-7";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_col0_1: keypad-col0-1 {
+ samsung,pins = "gpl-0";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_col1_1: keypad-col1-1 {
+ samsung,pins = "gpl-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_col2_1: keypad-col2-1 {
+ samsung,pins = "gpl-2";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_col3_1: keypad-col3-1 {
+ samsung,pins = "gpl-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_col4_1: keypad-col4-1 {
+ samsung,pins = "gpl-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_col5_1: keypad-col5-1 {
+ samsung,pins = "gpl-5";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_col6_1: keypad-col6-1 {
+ samsung,pins = "gpl-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_col7_1: keypad-col7-1 {
+ samsung,pins = "gpl-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_row0_0: keypad-row0-0 {
+ samsung,pins = "gpk-8";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_row1_0: keypad-row1-0 {
+ samsung,pins = "gpk-9";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_row2_0: keypad-row2-0 {
+ samsung,pins = "gpk-10";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_row3_0: keypad-row3-0 {
+ samsung,pins = "gpk-11";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_row4_0: keypad-row4-0 {
+ samsung,pins = "gpk-12";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_row5_0: keypad-row5-0 {
+ samsung,pins = "gpk-13";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_row6_0: keypad-row6-0 {
+ samsung,pins = "gpk-14";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_row7_0: keypad-row7-0 {
+ samsung,pins = "gpk-15";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_row0_1: keypad-row0-1 {
+ samsung,pins = "gpn-0";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_row1_1: keypad-row1-1 {
+ samsung,pins = "gpn-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_row2_1: keypad-row2-1 {
+ samsung,pins = "gpn-2";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_row3_1: keypad-row3-1 {
+ samsung,pins = "gpn-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_row4_1: keypad-row4-1 {
+ samsung,pins = "gpn-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_row5_1: keypad-row5-1 {
+ samsung,pins = "gpn-5";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_row6_1: keypad-row6-1 {
+ samsung,pins = "gpn-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ keypad_row7_1: keypad-row7-1 {
+ samsung,pins = "gpn-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ lcd_ctrl: lcd-ctrl {
+ samsung,pins = "gpj-8", "gpj-9", "gpj-10", "gpj-11";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ lcd_data16: lcd-data-width16 {
+ samsung,pins = "gpi-3", "gpi-4", "gpi-5", "gpi-6",
+ "gpi-7", "gpi-10", "gpi-11", "gpi-12",
+ "gpi-13", "gpi-14", "gpi-15", "gpj-3",
+ "gpj-4", "gpj-5", "gpj-6", "gpj-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ lcd_data18: lcd-data-width18 {
+ samsung,pins = "gpi-2", "gpi-3", "gpi-4", "gpi-5",
+ "gpi-6", "gpi-7", "gpi-10", "gpi-11",
+ "gpi-12", "gpi-13", "gpi-14", "gpi-15",
+ "gpj-2", "gpj-3", "gpj-4", "gpj-5",
+ "gpj-6", "gpj-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ lcd_data24: lcd-data-width24 {
+ samsung,pins = "gpi-0", "gpi-1", "gpi-2", "gpi-3",
+ "gpi-4", "gpi-5", "gpi-6", "gpi-7",
+ "gpi-8", "gpi-9", "gpi-10", "gpi-11",
+ "gpi-12", "gpi-13", "gpi-14", "gpi-15",
+ "gpj-0", "gpj-1", "gpj-2", "gpj-3",
+ "gpj-4", "gpj-5", "gpj-6", "gpj-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+
+ hsi_bus: hsi-bus {
+ samsung,pins = "gpk-0", "gpk-1", "gpk-2", "gpk-3",
+ "gpk-4", "gpk-5", "gpk-6", "gpk-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <PIN_PULL_NONE>;
+ };
+};
diff --git a/arch/arm/boot/dts/s3c64xx.dtsi b/arch/arm/boot/dts/s3c64xx.dtsi
new file mode 100644
index 000000000..0ccb414cd
--- /dev/null
+++ b/arch/arm/boot/dts/s3c64xx.dtsi
@@ -0,0 +1,202 @@
+/*
+ * Samsung's S3C64xx SoC series common device tree source
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Samsung's S3C64xx SoC series device nodes are listed in this file.
+ * Particular SoCs from S3C64xx series can include this file and provide
+ * values for SoCs specfic bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * S3C64xx SoCs. As device tree coverage for S3C64xx increases, additional
+ * nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/samsung,s3c64xx-clock.h>
+
+/ {
+ aliases {
+ i2c0 = &i2c0;
+ pinctrl0 = &pinctrl0;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,arm1176jzf-s", "arm,arm1176";
+ reg = <0x0>;
+ };
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ vic0: interrupt-controller@71200000 {
+ compatible = "arm,pl192-vic";
+ interrupt-controller;
+ reg = <0x71200000 0x1000>;
+ #interrupt-cells = <1>;
+ };
+
+ vic1: interrupt-controller@71300000 {
+ compatible = "arm,pl192-vic";
+ interrupt-controller;
+ reg = <0x71300000 0x1000>;
+ #interrupt-cells = <1>;
+ };
+
+ sdhci0: sdhci@7c200000 {
+ compatible = "samsung,s3c6410-sdhci";
+ reg = <0x7c200000 0x100>;
+ interrupt-parent = <&vic1>;
+ interrupts = <24>;
+ clock-names = "hsmmc", "mmc_busclk.0", "mmc_busclk.2";
+ clocks = <&clocks HCLK_HSMMC0>, <&clocks HCLK_HSMMC0>,
+ <&clocks SCLK_MMC0>;
+ status = "disabled";
+ };
+
+ sdhci1: sdhci@7c300000 {
+ compatible = "samsung,s3c6410-sdhci";
+ reg = <0x7c300000 0x100>;
+ interrupt-parent = <&vic1>;
+ interrupts = <25>;
+ clock-names = "hsmmc", "mmc_busclk.0", "mmc_busclk.2";
+ clocks = <&clocks HCLK_HSMMC1>, <&clocks HCLK_HSMMC1>,
+ <&clocks SCLK_MMC1>;
+ status = "disabled";
+ };
+
+ sdhci2: sdhci@7c400000 {
+ compatible = "samsung,s3c6410-sdhci";
+ reg = <0x7c400000 0x100>;
+ interrupt-parent = <&vic1>;
+ interrupts = <17>;
+ clock-names = "hsmmc", "mmc_busclk.0", "mmc_busclk.2";
+ clocks = <&clocks HCLK_HSMMC2>, <&clocks HCLK_HSMMC2>,
+ <&clocks SCLK_MMC2>;
+ status = "disabled";
+ };
+
+ watchdog: watchdog@7e004000 {
+ compatible = "samsung,s3c2410-wdt";
+ reg = <0x7e004000 0x1000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <26>;
+ clock-names = "watchdog";
+ clocks = <&clocks PCLK_WDT>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@7f004000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x7f004000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <18>;
+ clock-names = "i2c";
+ clocks = <&clocks PCLK_IIC0>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ uart0: serial@7f005000 {
+ compatible = "samsung,s3c6400-uart";
+ reg = <0x7f005000 0x100>;
+ interrupt-parent = <&vic1>;
+ interrupts = <5>;
+ clock-names = "uart", "clk_uart_baud2",
+ "clk_uart_baud3";
+ clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>,
+ <&clocks SCLK_UART>;
+ status = "disabled";
+ };
+
+ uart1: serial@7f005400 {
+ compatible = "samsung,s3c6400-uart";
+ reg = <0x7f005400 0x100>;
+ interrupt-parent = <&vic1>;
+ interrupts = <6>;
+ clock-names = "uart", "clk_uart_baud2",
+ "clk_uart_baud3";
+ clocks = <&clocks PCLK_UART1>, <&clocks PCLK_UART1>,
+ <&clocks SCLK_UART>;
+ status = "disabled";
+ };
+
+ uart2: serial@7f005800 {
+ compatible = "samsung,s3c6400-uart";
+ reg = <0x7f005800 0x100>;
+ interrupt-parent = <&vic1>;
+ interrupts = <7>;
+ clock-names = "uart", "clk_uart_baud2",
+ "clk_uart_baud3";
+ clocks = <&clocks PCLK_UART2>, <&clocks PCLK_UART2>,
+ <&clocks SCLK_UART>;
+ status = "disabled";
+ };
+
+ uart3: serial@7f005c00 {
+ compatible = "samsung,s3c6400-uart";
+ reg = <0x7f005c00 0x100>;
+ interrupt-parent = <&vic1>;
+ interrupts = <8>;
+ clock-names = "uart", "clk_uart_baud2",
+ "clk_uart_baud3";
+ clocks = <&clocks PCLK_UART3>, <&clocks PCLK_UART3>,
+ <&clocks SCLK_UART>;
+ status = "disabled";
+ };
+
+ pwm: pwm@7f006000 {
+ compatible = "samsung,s3c6400-pwm";
+ reg = <0x7f006000 0x1000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <23>, <24>, <25>, <27>, <28>;
+ clock-names = "timers";
+ clocks = <&clocks PCLK_PWM>;
+ samsung,pwm-outputs = <0>, <1>;
+ #pwm-cells = <3>;
+ };
+
+ pinctrl0: pinctrl@7f008000 {
+ compatible = "samsung,s3c64xx-pinctrl";
+ reg = <0x7f008000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <21>;
+
+ pctrl_int_map: pinctrl-interrupt-map {
+ interrupt-map = <0 &vic0 0>,
+ <1 &vic0 1>,
+ <2 &vic1 0>,
+ <3 &vic1 1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+
+ wakeup-interrupt-controller {
+ compatible = "samsung,s3c64xx-wakeup-eint";
+ interrupts = <0>, <1>, <2>, <3>;
+ interrupt-parent = <&pctrl_int_map>;
+ };
+ };
+ };
+};
+
+#include "s3c64xx-pinctrl.dtsi"
diff --git a/arch/arm/boot/dts/s5pv210-aquila.dts b/arch/arm/boot/dts/s5pv210-aquila.dts
new file mode 100644
index 000000000..f00cea7ac
--- /dev/null
+++ b/arch/arm/boot/dts/s5pv210-aquila.dts
@@ -0,0 +1,393 @@
+/*
+ * Samsung's S5PV210 SoC device tree source
+ *
+ * Copyright (c) 2013-2014 Samsung Electronics, Co. Ltd.
+ *
+ * Mateusz Krawczuk <m.krawczuk@partner.samsung.com>
+ * Tomasz Figa <t.figa@samsung.com>
+ *
+ * Board device tree source for Samsung Aquila 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.
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include "s5pv210.dtsi"
+
+/ {
+ model = "Samsung Aquila based on S5PC110";
+ compatible = "samsung,aquila", "samsung,s5pv210";
+
+ aliases {
+ i2c3 = &i2c_pmic;
+ };
+
+ chosen {
+ bootargs = "console=ttySAC2,115200n8 root=/dev/mmcblk1p5 rw rootwait ignore_loglevel earlyprintk";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x30000000 0x05000000
+ 0x40000000 0x18000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vtf_reg: fixed-regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "V_TF_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpios = <&mp05 4 0>;
+ enable-active-high;
+ };
+
+ pda_reg: fixed-regulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_1.8V_PDA";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ reg = <1>;
+ };
+
+ bat_reg: fixed-regulator@2 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_BAT";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+ reg = <2>;
+ };
+ };
+
+ i2c_pmic: i2c-pmic {
+ compatible = "i2c-gpio";
+ gpios = <&gpj4 0 0>, /* sda */
+ <&gpj4 3 0>; /* scl */
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@66 {
+ compatible = "national,lp3974";
+ reg = <0x66>;
+
+ max8998,pmic-buck1-default-dvs-idx = <0>;
+ max8998,pmic-buck1-dvs-gpios = <&gph0 3 0>,
+ <&gph0 4 0>;
+ max8998,pmic-buck1-dvs-voltage = <1200000>, <1200000>,
+ <1200000>, <1200000>;
+
+ max8998,pmic-buck2-default-dvs-idx = <0>;
+ max8998,pmic-buck2-dvs-gpio = <&gph0 5 0>;
+ max8998,pmic-buck2-dvs-voltage = <1200000>, <1200000>;
+
+ regulators {
+ ldo2_reg: LDO2 {
+ regulator-name = "VALIVE_1.1V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "VUSB+MIPI_1.1V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "VADC_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "VTF_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "VCC_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "VCC_3.0V";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "VUSB+VDAC_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "VCC+VCAM_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "VPLL_1.1V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "CAM_IO_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "CAM_ISP_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "CAM_A_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "CAM_CIF_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "CAM_AF_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "VMIPI_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "CAM_8M_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "VARM_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "VINT_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "VCC_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "CAM_CORE_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ vichg_reg: ENVICHG {
+ regulator-name = "VICHG";
+ };
+
+ safeout1_reg: ESAFEOUT1 {
+ regulator-name = "SAFEOUT1";
+ regulator-always-on;
+ };
+
+ safeout2_reg: ESAFEOUT2 {
+ regulator-name = "SAFEOUT2";
+ regulator-boot-on;
+ };
+ };
+ };
+
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power-key {
+ gpios = <&gph2 6 1>;
+ linux,code = <KEY_POWER>;
+ label = "power";
+ debounce-interval = <1>;
+ gpio-key,wakeup;
+ };
+ };
+};
+
+&xusbxti {
+ clock-frequency = <24000000>;
+};
+
+&keypad {
+ linux,input-no-autorepeat;
+ linux,input-wakeup;
+ samsung,keypad-num-rows = <3>;
+ samsung,keypad-num-columns = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&keypad_row0>, <&keypad_row1>, <&keypad_row2>,
+ <&keypad_col0>, <&keypad_col1>, <&keypad_col2>;
+ status = "okay";
+
+ key_1 {
+ keypad,row = <0>;
+ keypad,column = <1>;
+ linux,code = <KEY_CONNECT>;
+ };
+
+ key_2 {
+ keypad,row = <0>;
+ keypad,column = <2>;
+ linux,code = <KEY_BACK>;
+ };
+
+ key_3 {
+ keypad,row = <1>;
+ keypad,column = <1>;
+ linux,code = <KEY_CAMERA_FOCUS>;
+ };
+
+ key_4 {
+ keypad,row = <1>;
+ keypad,column = <2>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ key_5 {
+ keypad,row = <2>;
+ keypad,column = <1>;
+ linux,code = <KEY_CAMERA>;
+ };
+
+ key_6 {
+ keypad,row = <2>;
+ keypad,column = <2>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&sdhci0 {
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+ vmmc-supply = <&ldo5_reg>;
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4>;
+ pinctrl-names = "default";
+};
+
+&sdhci2 {
+ bus-width = <4>;
+ cd-gpios = <&gph3 4 1>;
+ vmmc-supply = <&vtf_reg>;
+ cd-inverted;
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &t_flash_detect>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&onenand {
+ status = "okay";
+};
+
+&hsotg {
+ vusb_a-supply = <&ldo3_reg>;
+ vusb_d-supply = <&ldo8_reg>;
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
+
+&fimd {
+ pinctrl-0 = <&lcd_clk &lcd_data24 &pwm1_out>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing {
+ clock-frequency = <0>;
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <16>;
+ hback-porch = <16>;
+ hsync-len = <2>;
+ vback-porch = <3>;
+ vfront-porch = <28>;
+ vsync-len = <1>;
+ };
+ };
+};
+
+&pinctrl0 {
+ t_flash_detect: t-flash-detect {
+ samsung,pins = "gph3-4";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/s5pv210-goni.dts b/arch/arm/boot/dts/s5pv210-goni.dts
new file mode 100644
index 000000000..a3d4643b2
--- /dev/null
+++ b/arch/arm/boot/dts/s5pv210-goni.dts
@@ -0,0 +1,450 @@
+/*
+ * Samsung's S5PV210 SoC device tree source
+ *
+ * Copyright (c) 2013-2014 Samsung Electronics, Co. Ltd.
+ *
+ * Mateusz Krawczuk <m.krawczuk@partner.samsung.com>
+ * Tomasz Figa <t.figa@samsung.com>
+ *
+ * Board device tree source for Samsung Goni 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.
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include "s5pv210.dtsi"
+
+/ {
+ model = "Samsung Goni based on S5PC110";
+ compatible = "samsung,goni", "samsung,s5pv210";
+
+ aliases {
+ i2c3 = &i2c_pmic;
+ };
+
+ chosen {
+ bootargs = "console=ttySAC0,115200n8 root=/dev/mmcblk0p5 rw rootwait ignore_loglevel earlyprintk";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x30000000 0x05000000
+ 0x40000000 0x10000000
+ 0x50000000 0x08000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vtf_reg: fixed-regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_TF_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ reg = <0>;
+ gpios = <&mp05 4 0>;
+ enable-active-high;
+ };
+
+ pda_reg: fixed-regulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_1.8V_PDA";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ reg = <1>;
+ };
+
+ bat_reg: fixed-regulator@2 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_BAT";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+ reg = <2>;
+ };
+
+ tsp_reg: fixed-regulator@3 {
+ compatible = "regulator-fixed";
+ regulator-name = "TSP_VDD";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ reg = <3>;
+ gpios = <&gpj1 3 0>;
+ enable-active-high;
+ };
+ };
+
+ i2c_pmic: i2c-pmic {
+ compatible = "i2c-gpio";
+ gpios = <&gpj4 0 0>, /* sda */
+ <&gpj4 3 0>; /* scl */
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@66 {
+ compatible = "national,lp3974";
+ reg = <0x66>;
+
+ max8998,pmic-buck1-default-dvs-idx = <0>;
+ max8998,pmic-buck1-dvs-gpios = <&gph0 3 0>,
+ <&gph0 4 0>;
+ max8998,pmic-buck1-dvs-voltage = <1200000>, <1200000>,
+ <1200000>, <1200000>;
+
+ max8998,pmic-buck2-default-dvs-idx = <0>;
+ max8998,pmic-buck2-dvs-gpio = <&gph0 5 0>;
+ max8998,pmic-buck2-dvs-voltage = <1200000>, <1200000>;
+
+ regulators {
+ ldo2_reg: LDO2 {
+ regulator-name = "VALIVE_1.1V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "VUSB+MIPI_1.1V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "VADC_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "VTF_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "VCC_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "VLCD_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "VUSB+VDAC_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "VCC+VCAM_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "VPLL_1.1V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-boot-on;
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "CAM_IO_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "CAM_ISP_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "CAM_A_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "CAM_CIF_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "CAM_AF_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "VMIPI_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "CAM_8M_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "VARM_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "VINT_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "VCC_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "CAM_CORE_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+ };
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power-key {
+ gpios = <&gph2 6 1>;
+ linux,code = <KEY_POWER>;
+ label = "power";
+ debounce-interval = <1>;
+ gpio-key,wakeup;
+ };
+ };
+};
+
+&xusbxti {
+ clock-frequency = <24000000>;
+};
+
+&keypad {
+ linux,input-no-autorepeat;
+ linux,input-wakeup;
+ samsung,keypad-num-rows = <3>;
+ samsung,keypad-num-columns = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&keypad_row0>, <&keypad_row1>, <&keypad_row2>,
+ <&keypad_col0>, <&keypad_col1>, <&keypad_col2>;
+ status = "okay";
+
+ key_1 {
+ keypad,row = <0>;
+ keypad,column = <1>;
+ linux,code = <KEY_CONNECT>;
+ };
+
+ key_2 {
+ keypad,row = <0>;
+ keypad,column = <2>;
+ linux,code = <KEY_BACK>;
+ };
+
+ key_3 {
+ keypad,row = <1>;
+ keypad,column = <1>;
+ linux,code = <KEY_CAMERA_FOCUS>;
+ };
+
+ key_4 {
+ keypad,row = <1>;
+ keypad,column = <2>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ key_5 {
+ keypad,row = <2>;
+ keypad,column = <1>;
+ linux,code = <KEY_CAMERA>;
+ };
+
+ key_6 {
+ keypad,row = <2>;
+ keypad,column = <2>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&sdhci0 {
+ bus-width = <4>;
+ non-removable;
+ vmmc-supply = <&ldo5_reg>;
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus1 &sd0_bus4>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&sdhci2 {
+ bus-width = <4>;
+ cd-gpios = <&gph3 4 1>;
+ vmmc-supply = <&vtf_reg>;
+ cd-inverted;
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&hsotg {
+ vusb_a-supply = <&ldo3_reg>;
+ vusb_d-supply = <&ldo8_reg>;
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
+
+&i2c2 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <400000>;
+ samsung,i2c-slave-addr = <0x10>;
+ status = "okay";
+
+ tsp@4a {
+ compatible = "atmel,maxtouch";
+ reg = <0x4a>;
+ interrupt-parent = <&gpj0>;
+ interrupts = <5 2>;
+
+ atmel,x-line = <17>;
+ atmel,y-line = <11>;
+ atmel,x-size = <800>;
+ atmel,y-size = <480>;
+ atmel,burst-length = <0x21>;
+ atmel,threshold = <0x28>;
+ atmel,orientation = <1>;
+
+ vdd-supply = <&tsp_reg>;
+ };
+};
+
+&i2c0 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <100000>;
+ samsung,i2c-slave-addr = <0x10>;
+ status = "okay";
+
+ noon010pc30: sensor@30 {
+ compatible = "siliconfile,noon010pc30";
+ reg = <0x30>;
+ vddio-supply = <&ldo11_reg>;
+ vdda-supply = <&ldo13_reg>;
+ vdd_core-supply = <&ldo14_reg>;
+
+ clock-frequency = <16000000>;
+ clocks = <&clock_cam 0>;
+ clock-names = "mclk";
+ nreset-gpios = <&gpb 2 0>;
+ nstby-gpios = <&gpb 0 0>;
+
+ port {
+ noon010pc30_ep: endpoint {
+ remote-endpoint = <&fimc0_ep>;
+ bus-width = <8>;
+ hsync-active = <0>;
+ vsync-active = <1>;
+ pclk-sample = <1>;
+ };
+ };
+ };
+};
+
+&camera {
+ pinctrl-0 = <&cam_port_a_io &cam_port_a_clk_active>;
+ pinctrl-1 = <&cam_port_a_io &cam_port_a_clk_idle>;
+ pinctrl-names = "default", "idle";
+
+ parallel-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* camera A input */
+ port@1 {
+ reg = <1>;
+ fimc0_ep: endpoint {
+ remote-endpoint = <&noon010pc30_ep>;
+ bus-width = <8>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ pclk-sample = <0>;
+ };
+ };
+ };
+};
+
+&fimd {
+ pinctrl-0 = <&lcd_clk &lcd_data24>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing {
+ /* 480x800@55Hz */
+ clock-frequency = <23439570>;
+ hactive = <480>;
+ hfront-porch = <16>;
+ hback-porch = <16>;
+ hsync-len = <2>;
+ vactive = <800>;
+ vback-porch = <2>;
+ vfront-porch = <28>;
+ vsync-len = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <0>;
+ pixelclk-active = <0>;
+ };
+ };
+};
+
+&onenand {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/s5pv210-pinctrl.dtsi b/arch/arm/boot/dts/s5pv210-pinctrl.dtsi
new file mode 100644
index 000000000..8c714088e
--- /dev/null
+++ b/arch/arm/boot/dts/s5pv210-pinctrl.dtsi
@@ -0,0 +1,839 @@
+/*
+ * Samsung's S5PV210 SoC device tree source
+ *
+ * Copyright (c) 2013-2014 Samsung Electronics, Co. Ltd.
+ *
+ * Mateusz Krawczuk <m.krawczuk@partner.samsung.com>
+ * Tomasz Figa <t.figa@samsung.com>
+ *
+ * Samsung's S5PV210 SoC device nodes are listed in this file. S5PV210
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * S5PV210 SoC. As device tree coverage for S5PV210 increases, additional
+ * nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+&pinctrl0 {
+ gpa0: gpa0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpa1: gpa1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb: gpb {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc0: gpc0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc1: gpc1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd0: gpd0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd1: gpd1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpe0: gpe0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpe1: gpe1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf0: gpf0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf1: gpf1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf2: gpf2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf3: gpf3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg0: gpg0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg1: gpg1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg2: gpg2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg3: gpg3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpj0: gpj0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpj1: gpj1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpj2: gpj2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpj3: gpj3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpj4: gpj4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpgi: gpgi {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ mp01: mp01 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ mp02: mp02 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ mp03: mp03 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ mp04: mp04 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ mp05: mp05 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ mp06: mp06 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ mp07: mp07 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gph0: gph0 {
+ gpio-controller;
+ interrupt-controller;
+ interrupt-parent = <&vic0>;
+ interrupts = <0>, <1>, <2>, <3>,
+ <4>, <5>, <6>, <7>;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ };
+
+ gph1: gph1 {
+ gpio-controller;
+ interrupt-controller;
+ interrupt-parent = <&vic0>;
+ interrupts = <8>, <9>, <10>, <11>,
+ <12>, <13>, <14>, <15>;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ };
+
+ gph2: gph2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ };
+
+ gph3: gph3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ };
+
+ uart0_data: uart0-data {
+ samsung,pins = "gpa0-0", "gpa0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart0_fctl: uart0-fctl {
+ samsung,pins = "gpa0-2", "gpa0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_data: uart1-data {
+ samsung,pins = "gpa0-4", "gpa0-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_fctl: uart1-fctl {
+ samsung,pins = "gpa0-6", "gpa0-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart2_data: uart2-data {
+ samsung,pins = "gpa1-0", "gpa1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart2_fctl: uart2-fctl {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart3_data: uart3-data {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart_audio: uart-audio {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi0_bus: spi0-bus {
+ samsung,pins = "gpb-0", "gpb-2", "gpb-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi1_bus: spi1-bus {
+ samsung,pins = "gpb-4", "gpb-6", "gpb-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s0_bus: i2s0-bus {
+ samsung,pins = "gpi-0", "gpi-1", "gpi-2", "gpi-3",
+ "gpi-4", "gpi-5", "gpi-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s1_bus: i2s1-bus {
+ samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+ "gpc0-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s2_bus: i2s2-bus {
+ samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+ "gpc1-4";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm1_bus: pcm1-bus {
+ samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+ "gpc0-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ ac97_bus: ac97-bus {
+ samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+ "gpc0-4";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s2_bus: i2s2-bus {
+ samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+ "gpc1-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm2_bus: pcm2-bus {
+ samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+ "gpc1-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ spdif_bus: spdif-bus {
+ samsung,pins = "gpc1-0", "gpc1-1";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi2_bus: spi2-bus {
+ samsung,pins = "gpc1-1", "gpc1-2", "gpc1-3", "gpc1-4";
+ samsung,pin-function = <5>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c0_bus: i2c0-bus {
+ samsung,pins = "gpd1-0", "gpd1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c1_bus: i2c1-bus {
+ samsung,pins = "gpd1-2", "gpd1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c2_bus: i2c2-bus {
+ samsung,pins = "gpd1-4", "gpd1-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm0_out: pwm0-out {
+ samsung,pins = "gpd0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm1_out: pwm1-out {
+ samsung,pins = "gpd0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm2_out: pwm2-out {
+ samsung,pins = "gpd0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm3_out: pwm3-out {
+ samsung,pins = "gpd0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_row0: keypad-row-0 {
+ samsung,pins = "gph3-0";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_row1: keypad-row-1 {
+ samsung,pins = "gph3-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_row2: keypad-row-2 {
+ samsung,pins = "gph3-2";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_row3: keypad-row-3 {
+ samsung,pins = "gph3-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_row4: keypad-row-4 {
+ samsung,pins = "gph3-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_row5: keypad-row-5 {
+ samsung,pins = "gph3-5";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_row6: keypad-row-6 {
+ samsung,pins = "gph3-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_row7: keypad-row-7 {
+ samsung,pins = "gph3-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_col0: keypad-col-0 {
+ samsung,pins = "gph2-0";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_col1: keypad-col-1 {
+ samsung,pins = "gph2-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_col2: keypad-col-2 {
+ samsung,pins = "gph2-2";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_col3: keypad-col-3 {
+ samsung,pins = "gph2-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_col4: keypad-col-4 {
+ samsung,pins = "gph2-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_col5: keypad-col-5 {
+ samsung,pins = "gph2-5";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_col6: keypad-col-6 {
+ samsung,pins = "gph2-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ keypad_col7: keypad-col-7 {
+ samsung,pins = "gph2-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ sd0_clk: sd0-clk {
+ samsung,pins = "gpg0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ samsung,pins = "gpg0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cd: sd0-cd {
+ samsung,pins = "gpg0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ samsung,pins = "gpg0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ samsung,pins = "gpg0-3", "gpg0-4", "gpg0-5", "gpg0-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus8: sd0-bus-width8 {
+ samsung,pins = "gpg1-3", "gpg1-4", "gpg1-5", "gpg1-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_clk: sd1-clk {
+ samsung,pins = "gpg1-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ samsung,pins = "gpg1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cd: sd1-cd {
+ samsung,pins = "gpg1-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ samsung,pins = "gpg1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ samsung,pins = "gpg1-3", "gpg1-4", "gpg1-5", "gpg1-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_clk: sd2-clk {
+ samsung,pins = "gpg2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cmd: sd2-cmd {
+ samsung,pins = "gpg2-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cd: sd2-cd {
+ samsung,pins = "gpg2-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus1: sd2-bus-width1 {
+ samsung,pins = "gpg2-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus4: sd2-bus-width4 {
+ samsung,pins = "gpg2-3", "gpg2-4", "gpg2-5", "gpg2-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus8: sd2-bus-width8 {
+ samsung,pins = "gpg3-3", "gpg3-4", "gpg3-5", "gpg3-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_clk: sd3-clk {
+ samsung,pins = "gpg3-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_cmd: sd3-cmd {
+ samsung,pins = "gpg3-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_cd: sd3-cd {
+ samsung,pins = "gpg3-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_bus1: sd3-bus-width1 {
+ samsung,pins = "gpg3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_bus4: sd3-bus-width4 {
+ samsung,pins = "gpg3-3", "gpg3-4", "gpg3-5", "gpg3-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <2>;
+ samsung,pin-drv = <3>;
+ };
+
+ eint0: ext-int0 {
+ samsung,pins = "gph0-0";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ eint8: ext-int8 {
+ samsung,pins = "gph1-0";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ eint15: ext-int15 {
+ samsung,pins = "gph1-7";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ eint16: ext-int16 {
+ samsung,pins = "gph2-0";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ eint31: ext-int31 {
+ samsung,pins = "gph3-7";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_port_a_io: cam-port-a-io {
+ samsung,pins = "gpe0-0", "gpe0-1", "gpe0-2", "gpe0-3",
+ "gpe0-4", "gpe0-5", "gpe0-6", "gpe0-7",
+ "gpe1-0", "gpe1-1", "gpe1-2", "gpe1-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_port_a_clk_active: cam-port-a-clk-active {
+ samsung,pins = "gpe1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ cam_port_a_clk_idle: cam-port-a-clk-idle {
+ samsung,pins = "gpe1-3";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_port_b_io: cam-port-b-io {
+ samsung,pins = "gpj0-0", "gpj0-1", "gpj0-2", "gpj0-3",
+ "gpj0-4", "gpj0-5", "gpj0-6", "gpj0-7",
+ "gpj1-0", "gpj1-1", "gpj1-2", "gpj1-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ cam_port_b_clk_active: cam-port-b-clk-active {
+ samsung,pins = "gpj1-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ cam_port_b_clk_idle: cam-port-b-clk-idle {
+ samsung,pins = "gpj1-3";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_ctrl: lcd-ctrl {
+ samsung,pins = "gpd0-0", "gpd0-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_sync: lcd-sync {
+ samsung,pins = "gpf0-0", "gpf0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_clk: lcd-clk {
+ samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ lcd_data24: lcd-data-width24 {
+ samsung,pins = "gpf0-4", "gpf0-5", "gpf0-6", "gpf0-7",
+ "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3",
+ "gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7",
+ "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
+ "gpf2-4", "gpf2-5", "gpf2-6", "gpf2-7",
+ "gpf3-0", "gpf3-1", "gpf3-2", "gpf3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/s5pv210-smdkc110.dts b/arch/arm/boot/dts/s5pv210-smdkc110.dts
new file mode 100644
index 000000000..1eedab7ff
--- /dev/null
+++ b/arch/arm/boot/dts/s5pv210-smdkc110.dts
@@ -0,0 +1,78 @@
+/*
+ * Samsung's S5PV210 SoC device tree source
+ *
+ * Copyright (c) 2013-2014 Samsung Electronics, Co. Ltd.
+ *
+ * Mateusz Krawczuk <m.krawczuk@partner.samsung.com>
+ * Tomasz Figa <t.figa@samsung.com>
+ *
+ * Board device tree source for YIC System SMDC110 board.
+ *
+ * NOTE: This file is completely based on original board file for mach-smdkc110
+ * available in Linux 3.15 and intends to provide equivalent level of hardware
+ * support. Due to lack of hardware, _no_ testing has been performed.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include "s5pv210.dtsi"
+
+/ {
+ model = "YIC System SMDKC110 based on S5PC110";
+ compatible = "yic,smdkc110", "samsung,s5pv210";
+
+ chosen {
+ bootargs = "console=ttySAC0,115200n8 root=/dev/mmcblk0p1 rw rootwait ignore_loglevel earlyprintk";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x20000000 0x20000000>;
+ };
+};
+
+&xusbxti {
+ clock-frequency = <24000000>;
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&rtc {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ audio-codec@1b {
+ compatible = "wlf,wm8580";
+ reg = <0x1b>;
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c08";
+ reg = <0x50>;
+ };
+};
+
+&i2s0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/s5pv210-smdkv210.dts b/arch/arm/boot/dts/s5pv210-smdkv210.dts
new file mode 100644
index 000000000..da7d210df
--- /dev/null
+++ b/arch/arm/boot/dts/s5pv210-smdkv210.dts
@@ -0,0 +1,239 @@
+/*
+ * Samsung's S5PV210 SoC device tree source
+ *
+ * Copyright (c) 2013-2014 Samsung Electronics, Co. Ltd.
+ *
+ * Mateusz Krawczuk <m.krawczuk@partner.samsung.com>
+ * Tomasz Figa <t.figa@samsung.com>
+ *
+ * Board device tree source for YIC System SMDV210 board.
+ *
+ * NOTE: This file is completely based on original board file for mach-smdkv210
+ * available in Linux 3.15 and intends to provide equivalent level of hardware
+ * support. Due to lack of hardware, _no_ testing has been performed.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include "s5pv210.dtsi"
+
+/ {
+ model = "YIC System SMDKV210 based on S5PV210";
+ compatible = "yic,smdkv210", "samsung,s5pv210";
+
+ chosen {
+ bootargs = "console=ttySAC0,115200n8 root=/dev/mmcblk0p1 rw rootwait ignore_loglevel earlyprintk";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x20000000 0x40000000>;
+ };
+
+ ethernet@18000000 {
+ compatible = "davicom,dm9000";
+ reg = <0xA8000000 0x2 0xA8000002 0x2>;
+ interrupt-parent = <&gph1>;
+ interrupts = <1 4>;
+ local-mac-address = [00 00 de ad be ef];
+ davicom,no-eeprom;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 3 5000000 0>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_out>;
+ };
+};
+
+&xusbxti {
+ clock-frequency = <24000000>;
+};
+
+&keypad {
+ linux,input-no-autorepeat;
+ linux,input-wakeup;
+ samsung,keypad-num-rows = <8>;
+ samsung,keypad-num-columns = <8>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&keypad_row0>, <&keypad_row1>, <&keypad_row2>,
+ <&keypad_row3>, <&keypad_row4>, <&keypad_row5>,
+ <&keypad_row6>, <&keypad_row7>,
+ <&keypad_col0>, <&keypad_col1>, <&keypad_col2>,
+ <&keypad_col3>, <&keypad_col4>, <&keypad_col5>,
+ <&keypad_col6>, <&keypad_col7>;
+ status = "okay";
+
+ key_1 {
+ keypad,row = <0>;
+ keypad,column = <3>;
+ linux,code = <KEY_1>;
+ };
+
+ key_2 {
+ keypad,row = <0>;
+ keypad,column = <4>;
+ linux,code = <KEY_2>;
+ };
+
+ key_3 {
+ keypad,row = <0>;
+ keypad,column = <5>;
+ linux,code = <KEY_3>;
+ };
+
+ key_4 {
+ keypad,row = <0>;
+ keypad,column = <6>;
+ linux,code = <KEY_4>;
+ };
+
+ key_5 {
+ keypad,row = <0
+ >;
+ keypad,column = <7>;
+ linux,code = <KEY_5>;
+ };
+
+ key_6 {
+ keypad,row = <1>;
+ keypad,column = <3>;
+ linux,code = <KEY_A>;
+ };
+ key_7 {
+ keypad,row = <1>;
+ keypad,column = <4>;
+ linux,code = <KEY_B>;
+ };
+
+ key_8 {
+ keypad,row = <1>;
+ keypad,column = <5>;
+ linux,code = <KEY_C>;
+ };
+
+ key_9 {
+ keypad,row = <1>;
+ keypad,column = <6>;
+ linux,code = <KEY_D>;
+ };
+
+ key_10 {
+ keypad,row = <1>;
+ keypad,column = <7>;
+ linux,code = <KEY_E>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&rtc {
+ status = "okay";
+};
+
+&sdhci0 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus1 &sd0_bus4>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&sdhci1 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_cd &sd1_bus1 &sd1_bus4>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&sdhci2 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus1 &sd2_bus4>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&sdhci3 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_cd &sd3_bus1 &sd3_bus4>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&hsotg {
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
+
+&fimd {
+ pinctrl-0 = <&lcd_clk &lcd_data24>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ display-timings {
+ native-mode = <&timing0>;
+
+ timing0: timing@0 {
+ /* 800x480@60Hz */
+ clock-frequency = <24373920>;
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <8>;
+ hback-porch = <13>;
+ hsync-len = <3>;
+ vback-porch = <7>;
+ vfront-porch = <5>;
+ vsync-len = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+};
+
+&pwm {
+ samsung,pwm-outputs = <3>;
+};
+
+&i2c0 {
+ status = "okay";
+
+ audio-codec@1b {
+ compatible = "wlf,wm8580";
+ reg = <0x1b>;
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c08";
+ reg = <0x50>;
+ };
+};
+
+&i2s0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/s5pv210-torbreck.dts b/arch/arm/boot/dts/s5pv210-torbreck.dts
new file mode 100644
index 000000000..622599fd2
--- /dev/null
+++ b/arch/arm/boot/dts/s5pv210-torbreck.dts
@@ -0,0 +1,92 @@
+/*
+ * Samsung's S5PV210 SoC device tree source
+ *
+ * Copyright (c) 2013-2014 Samsung Electronics, Co. Ltd.
+ *
+ * Mateusz Krawczuk <m.krawczuk@partner.samsung.com>
+ * Tomasz Figa <t.figa@samsung.com>
+ *
+ * Board device tree source for Torbreck board.
+ *
+ * NOTE: This file is completely based on original board file for mach-torbreck
+ * available in Linux 3.15 and intends to provide equivalent level of hardware
+ * support. Due to lack of hardware, _no_ testing has been performed.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include "s5pv210.dtsi"
+
+/ {
+ model = "aESOP Torbreck based on S5PV210";
+ compatible = "aesop,torbreck", "samsung,s5pv210";
+
+ chosen {
+ bootargs = "console=ttySAC0,115200n8 root=/dev/mmcblk0p1 rw rootwait ignore_loglevel earlyprintk";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x20000000 0x20000000>;
+ };
+};
+
+&xusbxti {
+ clock-frequency = <24000000>;
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&rtc {
+ status = "okay";
+};
+
+&sdhci0 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus1 &sd0_bus4>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&sdhci1 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_cd &sd1_bus1 &sd1_bus4>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&sdhci2 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus1 &sd2_bus4>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&sdhci3 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_cd &sd3_bus1 &sd3_bus4>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&i2s0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/s5pv210.dtsi b/arch/arm/boot/dts/s5pv210.dtsi
new file mode 100644
index 000000000..8344a0ee2
--- /dev/null
+++ b/arch/arm/boot/dts/s5pv210.dtsi
@@ -0,0 +1,633 @@
+/*
+ * Samsung's S5PV210 SoC device tree source
+ *
+ * Copyright (c) 2013-2014 Samsung Electronics, Co. Ltd.
+ *
+ * Mateusz Krawczuk <m.krawczuk@partner.samsung.com>
+ * Tomasz Figa <t.figa@samsung.com>
+ *
+ * Samsung's S5PV210 SoC device nodes are listed in this file. S5PV210
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * S5PV210 SoC. As device tree coverage for S5PV210 increases, additional
+ * nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/s5pv210.h>
+#include <dt-bindings/clock/s5pv210-audss.h>
+
+/ {
+ aliases {
+ csis0 = &csis0;
+ fimc0 = &fimc0;
+ fimc1 = &fimc1;
+ fimc2 = &fimc2;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2s0 = &i2s0;
+ i2s1 = &i2s1;
+ i2s2 = &i2s2;
+ pinctrl0 = &pinctrl0;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a8";
+ reg = <0>;
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ external-clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ xxti: oscillator@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "xxti";
+ #clock-cells = <0>;
+ };
+
+ xusbxti: oscillator@1 {
+ compatible = "fixed-clock";
+ reg = <1>;
+ clock-frequency = <0>;
+ clock-output-names = "xusbxti";
+ #clock-cells = <0>;
+ };
+ };
+
+ onenand: onenand@b0000000 {
+ compatible = "samsung,s5pv210-onenand";
+ reg = <0xb0600000 0x2000>,
+ <0xb0000000 0x20000>,
+ <0xb0040000 0x20000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <31>;
+ clocks = <&clocks CLK_NANDXL>, <&clocks DOUT_FLASH>;
+ clock-names = "bus", "onenand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+ };
+
+ chipid@e0000000 {
+ compatible = "samsung,s5pv210-chipid";
+ reg = <0xe0000000 0x1000>;
+ };
+
+ clocks: clock-controller@e0100000 {
+ compatible = "samsung,s5pv210-clock", "simple-bus";
+ reg = <0xe0100000 0x10000>;
+ clock-names = "xxti", "xusbxti";
+ clocks = <&xxti>, <&xusbxti>;
+ #clock-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pmu_syscon: syscon@e0108000 {
+ compatible = "samsung-s5pv210-pmu", "syscon";
+ reg = <0xe0108000 0x8000>;
+ };
+ };
+
+ pinctrl0: pinctrl@e0200000 {
+ compatible = "samsung,s5pv210-pinctrl";
+ reg = <0xe0200000 0x1000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <30>;
+
+ wakeup-interrupt-controller {
+ compatible = "samsung,exynos4210-wakeup-eint";
+ interrupts = <16>;
+ interrupt-parent = <&vic0>;
+ };
+ };
+
+ amba {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "arm,amba-bus";
+ ranges;
+
+ pdma0: dma@e0900000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0xe0900000 0x1000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <19>;
+ clocks = <&clocks CLK_PDMA0>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+
+ pdma1: dma@e0a00000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0xe0a00000 0x1000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <20>;
+ clocks = <&clocks CLK_PDMA1>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+ };
+
+ spi0: spi@e1300000 {
+ compatible = "samsung,s5pv210-spi";
+ reg = <0xe1300000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <15>;
+ dmas = <&pdma0 7>, <&pdma0 6>;
+ dma-names = "tx", "rx";
+ clocks = <&clocks SCLK_SPI0>, <&clocks CLK_SPI0>;
+ clock-names = "spi", "spi_busclk0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_bus>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi1: spi@e1400000 {
+ compatible = "samsung,s5pv210-spi";
+ reg = <0xe1400000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <16>;
+ dmas = <&pdma1 7>, <&pdma1 6>;
+ dma-names = "tx", "rx";
+ clocks = <&clocks SCLK_SPI1>, <&clocks CLK_SPI1>;
+ clock-names = "spi", "spi_busclk0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_bus>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ keypad: keypad@e1600000 {
+ compatible = "samsung,s5pv210-keypad";
+ reg = <0xe1600000 0x1000>;
+ interrupt-parent = <&vic2>;
+ interrupts = <25>;
+ clocks = <&clocks CLK_KEYIF>;
+ clock-names = "keypad";
+ status = "disabled";
+ };
+
+ i2c0: i2c@e1800000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0xe1800000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <14>;
+ clocks = <&clocks CLK_I2C0>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_bus>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@e1a00000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0xe1a00000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <19>;
+ clocks = <&clocks CLK_I2C2>;
+ clock-names = "i2c";
+ pinctrl-0 = <&i2c2_bus>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ audio-subsystem {
+ compatible = "samsung,s5pv210-audss", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ clk_audss: clock-controller@eee10000 {
+ compatible = "samsung,s5pv210-audss-clock";
+ reg = <0xeee10000 0x1000>;
+ clock-names = "hclk", "xxti",
+ "fout_epll",
+ "sclk_audio0";
+ clocks = <&clocks DOUT_HCLKP>, <&xxti>,
+ <&clocks FOUT_EPLL>,
+ <&clocks SCLK_AUDIO0>;
+ #clock-cells = <1>;
+ };
+
+ i2s0: i2s@eee30000 {
+ compatible = "samsung,s5pv210-i2s";
+ reg = <0xeee30000 0x1000>;
+ interrupt-parent = <&vic2>;
+ interrupts = <16>;
+ dma-names = "rx", "tx", "tx-sec";
+ dmas = <&pdma1 9>, <&pdma1 10>, <&pdma1 11>;
+ clock-names = "iis",
+ "i2s_opclk0",
+ "i2s_opclk1";
+ clocks = <&clk_audss CLK_I2S>,
+ <&clk_audss CLK_I2S>,
+ <&clk_audss CLK_DOUT_AUD_BUS>;
+ samsung,idma-addr = <0xc0010000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_bus>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+ };
+
+ i2s1: i2s@e2100000 {
+ compatible = "samsung,s3c6410-i2s";
+ reg = <0xe2100000 0x1000>;
+ interrupt-parent = <&vic2>;
+ interrupts = <17>;
+ dma-names = "rx", "tx";
+ dmas = <&pdma1 12>, <&pdma1 13>;
+ clock-names = "iis", "i2s_opclk0";
+ clocks = <&clocks CLK_I2S1>, <&clocks SCLK_AUDIO1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s1_bus>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ i2s2: i2s@e2a00000 {
+ compatible = "samsung,s3c6410-i2s";
+ reg = <0xe2a00000 0x1000>;
+ interrupt-parent = <&vic2>;
+ interrupts = <18>;
+ dma-names = "rx", "tx";
+ dmas = <&pdma1 14>, <&pdma1 15>;
+ clock-names = "iis", "i2s_opclk0";
+ clocks = <&clocks CLK_I2S2>, <&clocks SCLK_AUDIO2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s2_bus>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ pwm: pwm@e2500000 {
+ compatible = "samsung,s5pc100-pwm";
+ reg = <0xe2500000 0x1000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <21>, <22>, <23>, <24>, <25>;
+ clock-names = "timers";
+ clocks = <&clocks CLK_PWM>;
+ #pwm-cells = <3>;
+ };
+
+ watchdog: watchdog@e2700000 {
+ compatible = "samsung,s3c2410-wdt";
+ reg = <0xe2700000 0x1000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <26>;
+ clock-names = "watchdog";
+ clocks = <&clocks CLK_WDT>;
+ };
+
+ rtc: rtc@e2800000 {
+ compatible = "samsung,s3c6410-rtc";
+ reg = <0xe2800000 0x100>;
+ interrupt-parent = <&vic0>;
+ interrupts = <28>, <29>;
+ clocks = <&clocks CLK_RTC>;
+ clock-names = "rtc";
+ status = "disabled";
+ };
+
+ uart0: serial@e2900000 {
+ compatible = "samsung,s5pv210-uart";
+ reg = <0xe2900000 0x400>;
+ interrupt-parent = <&vic1>;
+ interrupts = <10>;
+ clock-names = "uart", "clk_uart_baud0",
+ "clk_uart_baud1";
+ clocks = <&clocks CLK_UART0>, <&clocks CLK_UART0>,
+ <&clocks SCLK_UART0>;
+ status = "disabled";
+ };
+
+ uart1: serial@e2900400 {
+ compatible = "samsung,s5pv210-uart";
+ reg = <0xe2900400 0x400>;
+ interrupt-parent = <&vic1>;
+ interrupts = <11>;
+ clock-names = "uart", "clk_uart_baud0",
+ "clk_uart_baud1";
+ clocks = <&clocks CLK_UART1>, <&clocks CLK_UART1>,
+ <&clocks SCLK_UART1>;
+ status = "disabled";
+ };
+
+ uart2: serial@e2900800 {
+ compatible = "samsung,s5pv210-uart";
+ reg = <0xe2900800 0x400>;
+ interrupt-parent = <&vic1>;
+ interrupts = <12>;
+ clock-names = "uart", "clk_uart_baud0",
+ "clk_uart_baud1";
+ clocks = <&clocks CLK_UART2>, <&clocks CLK_UART2>,
+ <&clocks SCLK_UART2>;
+ status = "disabled";
+ };
+
+ uart3: serial@e2900c00 {
+ compatible = "samsung,s5pv210-uart";
+ reg = <0xe2900c00 0x400>;
+ interrupt-parent = <&vic1>;
+ interrupts = <13>;
+ clock-names = "uart", "clk_uart_baud0",
+ "clk_uart_baud1";
+ clocks = <&clocks CLK_UART3>, <&clocks CLK_UART3>,
+ <&clocks SCLK_UART3>;
+ status = "disabled";
+ };
+
+ sdhci0: sdhci@eb000000 {
+ compatible = "samsung,s3c6410-sdhci";
+ reg = <0xeb000000 0x100000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <26>;
+ clock-names = "hsmmc", "mmc_busclk.0", "mmc_busclk.2";
+ clocks = <&clocks CLK_HSMMC0>, <&clocks CLK_HSMMC0>,
+ <&clocks SCLK_MMC0>;
+ status = "disabled";
+ };
+
+ sdhci1: sdhci@eb100000 {
+ compatible = "samsung,s3c6410-sdhci";
+ reg = <0xeb100000 0x100000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <27>;
+ clock-names = "hsmmc", "mmc_busclk.0", "mmc_busclk.2";
+ clocks = <&clocks CLK_HSMMC1>, <&clocks CLK_HSMMC1>,
+ <&clocks SCLK_MMC1>;
+ status = "disabled";
+ };
+
+ sdhci2: sdhci@eb200000 {
+ compatible = "samsung,s3c6410-sdhci";
+ reg = <0xeb200000 0x100000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <28>;
+ clock-names = "hsmmc", "mmc_busclk.0", "mmc_busclk.2";
+ clocks = <&clocks CLK_HSMMC2>, <&clocks CLK_HSMMC2>,
+ <&clocks SCLK_MMC2>;
+ status = "disabled";
+ };
+
+ sdhci3: sdhci@eb300000 {
+ compatible = "samsung,s3c6410-sdhci";
+ reg = <0xeb300000 0x100000>;
+ interrupt-parent = <&vic3>;
+ interrupts = <2>;
+ clock-names = "hsmmc", "mmc_busclk.0", "mmc_busclk.3";
+ clocks = <&clocks CLK_HSMMC3>, <&clocks CLK_HSMMC3>,
+ <&clocks SCLK_MMC3>;
+ status = "disabled";
+ };
+
+ hsotg: hsotg@ec000000 {
+ compatible = "samsung,s3c6400-hsotg";
+ reg = <0xec000000 0x20000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <24>;
+ clocks = <&clocks CLK_USB_OTG>;
+ clock-names = "otg";
+ phy-names = "usb2-phy";
+ phys = <&usbphy 0>;
+ status = "disabled";
+ };
+
+ usbphy: usbphy@ec100000 {
+ compatible = "samsung,s5pv210-usb2-phy";
+ reg = <0xec100000 0x100>;
+ samsung,pmureg-phandle = <&pmu_syscon>;
+ clocks = <&clocks CLK_USB_OTG>, <&xusbxti>;
+ clock-names = "phy", "ref";
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
+ ehci: ehci@ec200000 {
+ compatible = "samsung,exynos4210-ehci";
+ reg = <0xec200000 0x100>;
+ interrupts = <23>;
+ interrupt-parent = <&vic1>;
+ clocks = <&clocks CLK_USB_HOST>;
+ clock-names = "usbhost";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+ phys = <&usbphy 1>;
+ };
+ };
+
+ ohci: ohci@ec300000 {
+ compatible = "samsung,exynos4210-ohci";
+ reg = <0xec300000 0x100>;
+ interrupts = <23>;
+ clocks = <&clocks CLK_USB_HOST>;
+ clock-names = "usbhost";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+ phys = <&usbphy 1>;
+ };
+ };
+
+ mfc: codec@f1700000 {
+ compatible = "samsung,mfc-v5";
+ reg = <0xf1700000 0x10000>;
+ interrupt-parent = <&vic2>;
+ interrupts = <14>;
+ clocks = <&clocks DOUT_MFC>, <&clocks CLK_MFC>;
+ clock-names = "sclk_mfc", "mfc";
+ };
+
+ vic0: interrupt-controller@f2000000 {
+ compatible = "arm,pl192-vic";
+ interrupt-controller;
+ reg = <0xf2000000 0x1000>;
+ #interrupt-cells = <1>;
+ };
+
+ vic1: interrupt-controller@f2100000 {
+ compatible = "arm,pl192-vic";
+ interrupt-controller;
+ reg = <0xf2100000 0x1000>;
+ #interrupt-cells = <1>;
+ };
+
+ vic2: interrupt-controller@f2200000 {
+ compatible = "arm,pl192-vic";
+ interrupt-controller;
+ reg = <0xf2200000 0x1000>;
+ #interrupt-cells = <1>;
+ };
+
+ vic3: interrupt-controller@f2300000 {
+ compatible = "arm,pl192-vic";
+ interrupt-controller;
+ reg = <0xf2300000 0x1000>;
+ #interrupt-cells = <1>;
+ };
+
+ fimd: fimd@f8000000 {
+ compatible = "samsung,exynos4210-fimd";
+ interrupt-parent = <&vic2>;
+ reg = <0xf8000000 0x20000>;
+ interrupt-names = "fifo", "vsync", "lcd_sys";
+ interrupts = <0>, <1>, <2>;
+ clocks = <&clocks SCLK_FIMD>, <&clocks CLK_FIMD>;
+ clock-names = "sclk_fimd", "fimd";
+ status = "disabled";
+ };
+
+ g2d: g2d@fa000000 {
+ compatible = "samsung,s5pv210-g2d";
+ reg = <0xfa000000 0x1000>;
+ interrupt-parent = <&vic2>;
+ interrupts = <9>;
+ clocks = <&clocks DOUT_G2D>, <&clocks CLK_G2D>;
+ clock-names = "sclk_fimg2d", "fimg2d";
+ };
+
+ mdma1: mdma@fa200000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0xfa200000 0x1000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <18>;
+ clocks = <&clocks CLK_MDMA>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <1>;
+ };
+
+ i2c1: i2c@fab00000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0xfab00000 0x1000>;
+ interrupt-parent = <&vic2>;
+ interrupts = <13>;
+ clocks = <&clocks CLK_I2C1>;
+ clock-names = "i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_bus>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ camera: camera {
+ compatible = "samsung,fimc", "simple-bus";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ clocks = <&clocks SCLK_CAM0>, <&clocks SCLK_CAM1>;
+ clock-names = "sclk_cam0", "sclk_cam1";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ clock_cam: clock-controller {
+ #clock-cells = <1>;
+ };
+
+ csis0: csis@fa600000 {
+ compatible = "samsung,s5pv210-csis";
+ reg = <0xfa600000 0x4000>;
+ interrupt-parent = <&vic2>;
+ interrupts = <29>;
+ clocks = <&clocks CLK_CSIS>,
+ <&clocks SCLK_CSIS>;
+ clock-names = "clk_csis",
+ "sclk_csis";
+ bus-width = <4>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ fimc0: fimc@fb200000 {
+ compatible = "samsung,s5pv210-fimc";
+ reg = <0xfb200000 0x1000>;
+ interrupts = <5>;
+ interrupt-parent = <&vic2>;
+ clocks = <&clocks CLK_FIMC0>,
+ <&clocks SCLK_FIMC0>;
+ clock-names = "fimc",
+ "sclk_fimc";
+ samsung,pix-limits = <4224 8192 1920 4224>;
+ samsung,mainscaler-ext;
+ samsung,cam-if;
+ };
+
+ fimc1: fimc@fb300000 {
+ compatible = "samsung,s5pv210-fimc";
+ reg = <0xfb300000 0x1000>;
+ interrupt-parent = <&vic2>;
+ interrupts = <6>;
+ clocks = <&clocks CLK_FIMC1>,
+ <&clocks SCLK_FIMC1>;
+ clock-names = "fimc",
+ "sclk_fimc";
+ samsung,pix-limits = <4224 8192 1920 4224>;
+ samsung,mainscaler-ext;
+ samsung,cam-if;
+ };
+
+ fimc2: fimc@fb400000 {
+ compatible = "samsung,s5pv210-fimc";
+ reg = <0xfb400000 0x1000>;
+ interrupt-parent = <&vic2>;
+ interrupts = <7>;
+ clocks = <&clocks CLK_FIMC2>,
+ <&clocks SCLK_FIMC2>;
+ clock-names = "fimc",
+ "sclk_fimc";
+ samsung,pix-limits = <4224 8192 1920 4224>;
+ samsung,mainscaler-ext;
+ samsung,lcd-wb;
+ };
+ };
+ };
+};
+
+#include "s5pv210-pinctrl.dtsi"
diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
new file mode 100644
index 000000000..37e6182f1
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d3.dtsi
@@ -0,0 +1,1489 @@
+/*
+ * sama5d3.dtsi - Device Tree Include file for SAMA5D3 family SoC
+ * applies to SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35, SAMA5D36 SoC
+ *
+ * Copyright (C) 2013 Atmel,
+ * 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/dma/at91.h>
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/at91.h>
+
+/ {
+ model = "Atmel SAMA5D3 family SoC";
+ compatible = "atmel,sama5d3", "atmel,sama5";
+ interrupt-parent = <&aic>;
+
+ aliases {
+ serial0 = &dbgu;
+ serial1 = &usart0;
+ serial2 = &usart1;
+ serial3 = &usart2;
+ serial4 = &usart3;
+ serial5 = &uart0;
+ gpio0 = &pioA;
+ gpio1 = &pioB;
+ gpio2 = &pioC;
+ gpio3 = &pioD;
+ gpio4 = &pioE;
+ tcb0 = &tcb0;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ ssc0 = &ssc0;
+ ssc1 = &ssc1;
+ pwm0 = &pwm0;
+ };
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a5";
+ reg = <0x0>;
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a5-pmu";
+ interrupts = <46 IRQ_TYPE_LEVEL_HIGH 0>;
+ };
+
+ memory {
+ reg = <0x20000000 0x8000000>;
+ };
+
+ clocks {
+ slow_xtal: slow_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ main_xtal: main_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ adc_op_clk: adc_op_clk{
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <20000000>;
+ };
+ };
+
+ sram: sram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x20000>;
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ mmc0: mmc@f0000000 {
+ compatible = "atmel,hsmci";
+ reg = <0xf0000000 0x600>;
+ interrupts = <21 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma0 2 AT91_DMA_CFG_PER_ID(0)>;
+ dma-names = "rxtx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_dat4_7>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mci0_clk>;
+ clock-names = "mci_clk";
+ };
+
+ spi0: spi@f0004000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xf0004000 0x100>;
+ interrupts = <24 IRQ_TYPE_LEVEL_HIGH 3>;
+ dmas = <&dma0 2 AT91_DMA_CFG_PER_ID(1)>,
+ <&dma0 2 AT91_DMA_CFG_PER_ID(2)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi0>;
+ clocks = <&spi0_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+
+ ssc0: ssc@f0008000 {
+ compatible = "atmel,at91sam9g45-ssc";
+ reg = <0xf0008000 0x4000>;
+ interrupts = <38 IRQ_TYPE_LEVEL_HIGH 4>;
+ dmas = <&dma0 2 AT91_DMA_CFG_PER_ID(13)>,
+ <&dma0 2 AT91_DMA_CFG_PER_ID(14)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
+ clocks = <&ssc0_clk>;
+ clock-names = "pclk";
+ status = "disabled";
+ };
+
+ tcb0: timer@f0010000 {
+ compatible = "atmel,at91sam9x5-tcb";
+ reg = <0xf0010000 0x100>;
+ interrupts = <26 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tcb0_clk>;
+ clock-names = "t0_clk";
+ };
+
+ i2c0: i2c@f0014000 {
+ compatible = "atmel,at91sam9x5-i2c";
+ reg = <0xf0014000 0x4000>;
+ interrupts = <18 IRQ_TYPE_LEVEL_HIGH 6>;
+ dmas = <&dma0 2 AT91_DMA_CFG_PER_ID(7)>,
+ <&dma0 2 AT91_DMA_CFG_PER_ID(8)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&twi0_clk>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@f0018000 {
+ compatible = "atmel,at91sam9x5-i2c";
+ reg = <0xf0018000 0x4000>;
+ interrupts = <19 IRQ_TYPE_LEVEL_HIGH 6>;
+ dmas = <&dma0 2 AT91_DMA_CFG_PER_ID(9)>,
+ <&dma0 2 AT91_DMA_CFG_PER_ID(10)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&twi1_clk>;
+ status = "disabled";
+ };
+
+ usart0: serial@f001c000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf001c000 0x100>;
+ interrupts = <12 IRQ_TYPE_LEVEL_HIGH 5>;
+ dmas = <&dma0 2 AT91_DMA_CFG_PER_ID(3)>,
+ <&dma0 2 (AT91_DMA_CFG_PER_ID(4) | AT91_DMA_CFG_FIFOCFG_ASAP)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
+ clocks = <&usart0_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart1: serial@f0020000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf0020000 0x100>;
+ interrupts = <13 IRQ_TYPE_LEVEL_HIGH 5>;
+ dmas = <&dma0 2 AT91_DMA_CFG_PER_ID(5)>,
+ <&dma0 2 (AT91_DMA_CFG_PER_ID(6) | AT91_DMA_CFG_FIFOCFG_ASAP)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
+ clocks = <&usart1_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ uart0: serial@f0024000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf0024000 0x100>;
+ interrupts = <16 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ clocks = <&uart0_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ pwm0: pwm@f002c000 {
+ compatible = "atmel,sama5d3-pwm";
+ reg = <0xf002c000 0x300>;
+ interrupts = <28 IRQ_TYPE_LEVEL_HIGH 4>;
+ #pwm-cells = <3>;
+ clocks = <&pwm_clk>;
+ status = "disabled";
+ };
+
+ isi: isi@f0034000 {
+ compatible = "atmel,at91sam9g45-isi";
+ reg = <0xf0034000 0x4000>;
+ interrupts = <37 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_isi_data_0_7>;
+ clocks = <&isi_clk>;
+ clock-names = "isi_clk";
+ status = "disabled";
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ sfr: sfr@f0038000 {
+ compatible = "atmel,sama5d3-sfr", "syscon";
+ reg = <0xf0038000 0x60>;
+ };
+
+ mmc1: mmc@f8000000 {
+ compatible = "atmel,hsmci";
+ reg = <0xf8000000 0x600>;
+ interrupts = <22 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(0)>;
+ dma-names = "rxtx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mci1_clk>;
+ clock-names = "mci_clk";
+ };
+
+ spi1: spi@f8008000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xf8008000 0x100>;
+ interrupts = <25 IRQ_TYPE_LEVEL_HIGH 3>;
+ dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(15)>,
+ <&dma1 2 AT91_DMA_CFG_PER_ID(16)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi1>;
+ clocks = <&spi1_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+
+ ssc1: ssc@f800c000 {
+ compatible = "atmel,at91sam9g45-ssc";
+ reg = <0xf800c000 0x4000>;
+ interrupts = <39 IRQ_TYPE_LEVEL_HIGH 4>;
+ dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(3)>,
+ <&dma1 2 AT91_DMA_CFG_PER_ID(4)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
+ clocks = <&ssc1_clk>;
+ clock-names = "pclk";
+ status = "disabled";
+ };
+
+ adc0: adc@f8018000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91sam9x5-adc";
+ reg = <0xf8018000 0x100>;
+ interrupts = <29 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &pinctrl_adc0_adtrg
+ &pinctrl_adc0_ad0
+ &pinctrl_adc0_ad1
+ &pinctrl_adc0_ad2
+ &pinctrl_adc0_ad3
+ &pinctrl_adc0_ad4
+ &pinctrl_adc0_ad5
+ &pinctrl_adc0_ad6
+ &pinctrl_adc0_ad7
+ &pinctrl_adc0_ad8
+ &pinctrl_adc0_ad9
+ &pinctrl_adc0_ad10
+ &pinctrl_adc0_ad11
+ >;
+ clocks = <&adc_clk>,
+ <&adc_op_clk>;
+ clock-names = "adc_clk", "adc_op_clk";
+ atmel,adc-channels-used = <0xfff>;
+ atmel,adc-startup-time = <40>;
+ atmel,adc-use-external-triggers;
+ atmel,adc-vref = <3000>;
+ atmel,adc-res = <10 12>;
+ atmel,adc-res-names = "lowres", "highres";
+ status = "disabled";
+
+ trigger@0 {
+ reg = <0>;
+ trigger-name = "external-rising";
+ trigger-value = <0x1>;
+ trigger-external;
+ };
+ trigger@1 {
+ reg = <1>;
+ trigger-name = "external-falling";
+ trigger-value = <0x2>;
+ trigger-external;
+ };
+ trigger@2 {
+ reg = <2>;
+ trigger-name = "external-any";
+ trigger-value = <0x3>;
+ trigger-external;
+ };
+ trigger@3 {
+ reg = <3>;
+ trigger-name = "continuous";
+ trigger-value = <0x6>;
+ };
+ };
+
+ i2c2: i2c@f801c000 {
+ compatible = "atmel,at91sam9x5-i2c";
+ reg = <0xf801c000 0x4000>;
+ interrupts = <20 IRQ_TYPE_LEVEL_HIGH 6>;
+ dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(11)>,
+ <&dma1 2 AT91_DMA_CFG_PER_ID(12)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&twi2_clk>;
+ status = "disabled";
+ };
+
+ usart2: serial@f8020000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf8020000 0x100>;
+ interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>;
+ dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(7)>,
+ <&dma1 2 (AT91_DMA_CFG_PER_ID(8) | AT91_DMA_CFG_FIFOCFG_ASAP)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
+ clocks = <&usart2_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart3: serial@f8024000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf8024000 0x100>;
+ interrupts = <15 IRQ_TYPE_LEVEL_HIGH 5>;
+ dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(9)>,
+ <&dma1 2 (AT91_DMA_CFG_PER_ID(10) | AT91_DMA_CFG_FIFOCFG_ASAP)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart3>;
+ clocks = <&usart3_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ sha@f8034000 {
+ compatible = "atmel,at91sam9g46-sha";
+ reg = <0xf8034000 0x100>;
+ interrupts = <42 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(17)>;
+ dma-names = "tx";
+ clocks = <&sha_clk>;
+ clock-names = "sha_clk";
+ };
+
+ aes@f8038000 {
+ compatible = "atmel,at91sam9g46-aes";
+ reg = <0xf8038000 0x100>;
+ interrupts = <43 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(18)>,
+ <&dma1 2 AT91_DMA_CFG_PER_ID(19)>;
+ dma-names = "tx", "rx";
+ clocks = <&aes_clk>;
+ clock-names = "aes_clk";
+ };
+
+ tdes@f803c000 {
+ compatible = "atmel,at91sam9g46-tdes";
+ reg = <0xf803c000 0x100>;
+ interrupts = <44 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(20)>,
+ <&dma1 2 AT91_DMA_CFG_PER_ID(21)>;
+ dma-names = "tx", "rx";
+ clocks = <&tdes_clk>;
+ clock-names = "tdes_clk";
+ };
+
+ dma0: dma-controller@ffffe600 {
+ compatible = "atmel,at91sam9g45-dma";
+ reg = <0xffffe600 0x200>;
+ interrupts = <30 IRQ_TYPE_LEVEL_HIGH 0>;
+ #dma-cells = <2>;
+ clocks = <&dma0_clk>;
+ clock-names = "dma_clk";
+ };
+
+ dma1: dma-controller@ffffe800 {
+ compatible = "atmel,at91sam9g45-dma";
+ reg = <0xffffe800 0x200>;
+ interrupts = <31 IRQ_TYPE_LEVEL_HIGH 0>;
+ #dma-cells = <2>;
+ clocks = <&dma1_clk>;
+ clock-names = "dma_clk";
+ };
+
+ ramc0: ramc@ffffea00 {
+ compatible = "atmel,sama5d3-ddramc";
+ reg = <0xffffea00 0x200>;
+ clocks = <&ddrck>, <&mpddr_clk>;
+ clock-names = "ddrck", "mpddr";
+ };
+
+ dbgu: serial@ffffee00 {
+ compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
+ reg = <0xffffee00 0x200>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH 7>;
+ dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(13)>,
+ <&dma1 2 (AT91_DMA_CFG_PER_ID(14) | AT91_DMA_CFG_FIFOCFG_ASAP)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
+ clocks = <&dbgu_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ aic: interrupt-controller@fffff000 {
+ #interrupt-cells = <3>;
+ compatible = "atmel,sama5d3-aic";
+ interrupt-controller;
+ reg = <0xfffff000 0x200>;
+ atmel,external-irqs = <47>;
+ };
+
+ pinctrl@fffff200 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,sama5d3-pinctrl", "atmel,at91sam9x5-pinctrl", "simple-bus";
+ ranges = <0xfffff200 0xfffff200 0xa00>;
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xc0fc0000 0xc0ff0000 /* pioA */
+ 0xffffffff 0x0ff8ffff 0x00000000 /* pioB */
+ 0xffffffff 0xbc00f1ff 0x7c00fc00 /* pioC */
+ 0xffffffff 0xc001c0e0 0x0001c1e0 /* pioD */
+ 0xffffffff 0xbf9f8000 0x18000000 /* pioE */
+ >;
+
+ /* shared pinctrl settings */
+ adc0 {
+ pinctrl_adc0_adtrg: adc0_adtrg {
+ atmel,pins =
+ <AT91_PIOD 19 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD19 periph A ADTRG */
+ };
+ pinctrl_adc0_ad0: adc0_ad0 {
+ atmel,pins =
+ <AT91_PIOD 20 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD20 periph A AD0 */
+ };
+ pinctrl_adc0_ad1: adc0_ad1 {
+ atmel,pins =
+ <AT91_PIOD 21 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD21 periph A AD1 */
+ };
+ pinctrl_adc0_ad2: adc0_ad2 {
+ atmel,pins =
+ <AT91_PIOD 22 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD22 periph A AD2 */
+ };
+ pinctrl_adc0_ad3: adc0_ad3 {
+ atmel,pins =
+ <AT91_PIOD 23 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD23 periph A AD3 */
+ };
+ pinctrl_adc0_ad4: adc0_ad4 {
+ atmel,pins =
+ <AT91_PIOD 24 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD24 periph A AD4 */
+ };
+ pinctrl_adc0_ad5: adc0_ad5 {
+ atmel,pins =
+ <AT91_PIOD 25 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD25 periph A AD5 */
+ };
+ pinctrl_adc0_ad6: adc0_ad6 {
+ atmel,pins =
+ <AT91_PIOD 26 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD26 periph A AD6 */
+ };
+ pinctrl_adc0_ad7: adc0_ad7 {
+ atmel,pins =
+ <AT91_PIOD 27 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD27 periph A AD7 */
+ };
+ pinctrl_adc0_ad8: adc0_ad8 {
+ atmel,pins =
+ <AT91_PIOD 28 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD28 periph A AD8 */
+ };
+ pinctrl_adc0_ad9: adc0_ad9 {
+ atmel,pins =
+ <AT91_PIOD 29 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD29 periph A AD9 */
+ };
+ pinctrl_adc0_ad10: adc0_ad10 {
+ atmel,pins =
+ <AT91_PIOD 30 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD30 periph A AD10, conflicts with PCK0 */
+ };
+ pinctrl_adc0_ad11: adc0_ad11 {
+ atmel,pins =
+ <AT91_PIOD 31 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD31 periph A AD11, conflicts with PCK1 */
+ };
+ };
+
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <AT91_PIOB 30 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB30 periph A */
+ AT91_PIOB 31 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PB31 periph A with pullup */
+ };
+ };
+
+ i2c0 {
+ pinctrl_i2c0: i2c0-0 {
+ atmel,pins =
+ <AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA30 periph A TWD0 pin, conflicts with URXD1, ISI_VSYNC */
+ AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA31 periph A TWCK0 pin, conflicts with UTXD1, ISI_HSYNC */
+ };
+ };
+
+ i2c1 {
+ pinctrl_i2c1: i2c1-0 {
+ atmel,pins =
+ <AT91_PIOC 26 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC26 periph B TWD1 pin, conflicts with SPI1_NPCS1, ISI_D11 */
+ AT91_PIOC 27 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC27 periph B TWCK1 pin, conflicts with SPI1_NPCS2, ISI_D10 */
+ };
+ };
+
+ i2c2 {
+ pinctrl_i2c2: i2c2-0 {
+ atmel,pins =
+ <AT91_PIOA 18 AT91_PERIPH_B AT91_PINCTRL_NONE /* TWD2 pin, conflicts with LCDDAT18, ISI_D2 */
+ AT91_PIOA 19 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* TWCK2 pin, conflicts with LCDDAT19, ISI_D3 */
+ };
+ };
+
+ isi {
+ pinctrl_isi_data_0_7: isi-0-data-0-7 {
+ atmel,pins =
+ <AT91_PIOA 16 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA16 periph C ISI_D0, conflicts with LCDDAT16 */
+ AT91_PIOA 17 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA17 periph C ISI_D1, conflicts with LCDDAT17 */
+ AT91_PIOA 18 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA18 periph C ISI_D2, conflicts with LCDDAT18, TWD2 */
+ AT91_PIOA 19 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA19 periph C ISI_D3, conflicts with LCDDAT19, TWCK2 */
+ AT91_PIOA 20 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA20 periph C ISI_D4, conflicts with LCDDAT20, PWMH0 */
+ AT91_PIOA 21 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA21 periph C ISI_D5, conflicts with LCDDAT21, PWML0 */
+ AT91_PIOA 22 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA22 periph C ISI_D6, conflicts with LCDDAT22, PWMH1 */
+ AT91_PIOA 23 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA23 periph C ISI_D7, conflicts with LCDDAT23, PWML1 */
+ AT91_PIOC 30 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC30 periph C ISI_PCK, conflicts with UTXD0 */
+ AT91_PIOA 31 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA31 periph C ISI_HSYNC, conflicts with TWCK0, UTXD1 */
+ AT91_PIOA 30 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PA30 periph C ISI_VSYNC, conflicts with TWD0, URXD1 */
+ };
+
+ pinctrl_isi_data_8_9: isi-0-data-8-9 {
+ atmel,pins =
+ <AT91_PIOC 29 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC29 periph C ISI_PD8, conflicts with URXD0, PWMFI2 */
+ AT91_PIOC 28 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC28 periph C ISI_PD9, conflicts with SPI1_NPCS3, PWMFI0 */
+ };
+
+ pinctrl_isi_data_10_11: isi-0-data-10-11 {
+ atmel,pins =
+ <AT91_PIOC 27 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC27 periph C ISI_PD10, conflicts with SPI1_NPCS2, TWCK1 */
+ AT91_PIOC 26 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC26 periph C ISI_PD11, conflicts with SPI1_NPCS1, TWD1 */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_clk_cmd_dat0: mmc0_clk_cmd_dat0 {
+ atmel,pins =
+ <AT91_PIOD 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD9 periph A MCI0_CK */
+ AT91_PIOD 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PD0 periph A MCI0_CDA with pullup */
+ AT91_PIOD 1 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PD1 periph A MCI0_DA0 with pullup */
+ };
+ pinctrl_mmc0_dat1_3: mmc0_dat1_3 {
+ atmel,pins =
+ <AT91_PIOD 2 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PD2 periph A MCI0_DA1 with pullup */
+ AT91_PIOD 3 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PD3 periph A MCI0_DA2 with pullup */
+ AT91_PIOD 4 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PD4 periph A MCI0_DA3 with pullup */
+ };
+ pinctrl_mmc0_dat4_7: mmc0_dat4_7 {
+ atmel,pins =
+ <AT91_PIOD 5 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PD5 periph A MCI0_DA4 with pullup, conflicts with TIOA0, PWMH2 */
+ AT91_PIOD 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PD6 periph A MCI0_DA5 with pullup, conflicts with TIOB0, PWML2 */
+ AT91_PIOD 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PD7 periph A MCI0_DA6 with pullup, conlicts with TCLK0, PWMH3 */
+ AT91_PIOD 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PD8 periph A MCI0_DA7 with pullup, conflicts with PWML3 */
+ };
+ };
+
+ mmc1 {
+ pinctrl_mmc1_clk_cmd_dat0: mmc1_clk_cmd_dat0 {
+ atmel,pins =
+ <AT91_PIOB 24 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB24 periph A MCI1_CK, conflicts with GRX5 */
+ AT91_PIOB 19 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PB19 periph A MCI1_CDA with pullup, conflicts with GTX4 */
+ AT91_PIOB 20 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PB20 periph A MCI1_DA0 with pullup, conflicts with GTX5 */
+ };
+ pinctrl_mmc1_dat1_3: mmc1_dat1_3 {
+ atmel,pins =
+ <AT91_PIOB 21 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PB21 periph A MCI1_DA1 with pullup, conflicts with GTX6 */
+ AT91_PIOB 22 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PB22 periph A MCI1_DA2 with pullup, conflicts with GTX7 */
+ AT91_PIOB 23 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PB23 periph A MCI1_DA3 with pullup, conflicts with GRX4 */
+ };
+ };
+
+ nand0 {
+ pinctrl_nand0_ale_cle: nand0_ale_cle-0 {
+ atmel,pins =
+ <AT91_PIOE 21 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PE21 periph A with pullup */
+ AT91_PIOE 22 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PE22 periph A with pullup */
+ };
+ };
+
+ pwm0 {
+ pinctrl_pwm0_pwmh0_0: pwm0_pwmh0-0 {
+ atmel,pins =
+ <AT91_PIOA 20 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* conflicts with ISI_D4 and LCDDAT20 */
+ };
+ pinctrl_pwm0_pwmh0_1: pwm0_pwmh0-1 {
+ atmel,pins =
+ <AT91_PIOB 0 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* conflicts with GTX0 */
+ };
+ pinctrl_pwm0_pwml0_0: pwm0_pwml0-0 {
+ atmel,pins =
+ <AT91_PIOA 21 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* conflicts with ISI_D5 and LCDDAT21 */
+ };
+ pinctrl_pwm0_pwml0_1: pwm0_pwml0-1 {
+ atmel,pins =
+ <AT91_PIOB 1 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* conflicts with GTX1 */
+ };
+
+ pinctrl_pwm0_pwmh1_0: pwm0_pwmh1-0 {
+ atmel,pins =
+ <AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* conflicts with ISI_D6 and LCDDAT22 */
+ };
+ pinctrl_pwm0_pwmh1_1: pwm0_pwmh1-1 {
+ atmel,pins =
+ <AT91_PIOB 4 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* conflicts with GRX0 */
+ };
+ pinctrl_pwm0_pwmh1_2: pwm0_pwmh1-2 {
+ atmel,pins =
+ <AT91_PIOB 27 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* conflicts with G125CKO and RTS1 */
+ };
+ pinctrl_pwm0_pwml1_0: pwm0_pwml1-0 {
+ atmel,pins =
+ <AT91_PIOA 23 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* conflicts with ISI_D7 and LCDDAT23 */
+ };
+ pinctrl_pwm0_pwml1_1: pwm0_pwml1-1 {
+ atmel,pins =
+ <AT91_PIOB 5 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* conflicts with GRX1 */
+ };
+ pinctrl_pwm0_pwml1_2: pwm0_pwml1-2 {
+ atmel,pins =
+ <AT91_PIOE 31 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* conflicts with IRQ */
+ };
+
+ pinctrl_pwm0_pwmh2_0: pwm0_pwmh2-0 {
+ atmel,pins =
+ <AT91_PIOB 8 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* conflicts with GTXCK */
+ };
+ pinctrl_pwm0_pwmh2_1: pwm0_pwmh2-1 {
+ atmel,pins =
+ <AT91_PIOD 5 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* conflicts with MCI0_DA4 and TIOA0 */
+ };
+ pinctrl_pwm0_pwml2_0: pwm0_pwml2-0 {
+ atmel,pins =
+ <AT91_PIOB 9 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* conflicts with GTXEN */
+ };
+ pinctrl_pwm0_pwml2_1: pwm0_pwml2-1 {
+ atmel,pins =
+ <AT91_PIOD 6 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* conflicts with MCI0_DA5 and TIOB0 */
+ };
+
+ pinctrl_pwm0_pwmh3_0: pwm0_pwmh3-0 {
+ atmel,pins =
+ <AT91_PIOB 12 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* conflicts with GRXDV */
+ };
+ pinctrl_pwm0_pwmh3_1: pwm0_pwmh3-1 {
+ atmel,pins =
+ <AT91_PIOD 7 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* conflicts with MCI0_DA6 and TCLK0 */
+ };
+ pinctrl_pwm0_pwml3_0: pwm0_pwml3-0 {
+ atmel,pins =
+ <AT91_PIOB 13 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* conflicts with GRXER */
+ };
+ pinctrl_pwm0_pwml3_1: pwm0_pwml3-1 {
+ atmel,pins =
+ <AT91_PIOD 8 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* conflicts with MCI0_DA7 */
+ };
+ };
+
+ spi0 {
+ pinctrl_spi0: spi0-0 {
+ atmel,pins =
+ <AT91_PIOD 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD10 periph A SPI0_MISO pin */
+ AT91_PIOD 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD11 periph A SPI0_MOSI pin */
+ AT91_PIOD 12 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD12 periph A SPI0_SPCK pin */
+ };
+ };
+
+ spi1 {
+ pinctrl_spi1: spi1-0 {
+ atmel,pins =
+ <AT91_PIOC 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC22 periph A SPI1_MISO pin */
+ AT91_PIOC 23 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC23 periph A SPI1_MOSI pin */
+ AT91_PIOC 24 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PC24 periph A SPI1_SPCK pin */
+ };
+ };
+
+ ssc0 {
+ pinctrl_ssc0_tx: ssc0_tx {
+ atmel,pins =
+ <AT91_PIOC 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC16 periph A TK0 */
+ AT91_PIOC 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC17 periph A TF0 */
+ AT91_PIOC 18 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PC18 periph A TD0 */
+ };
+
+ pinctrl_ssc0_rx: ssc0_rx {
+ atmel,pins =
+ <AT91_PIOC 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC19 periph A RK0 */
+ AT91_PIOC 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC20 periph A RF0 */
+ AT91_PIOC 21 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PC21 periph A RD0 */
+ };
+ };
+
+ ssc1 {
+ pinctrl_ssc1_tx: ssc1_tx {
+ atmel,pins =
+ <AT91_PIOB 2 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB2 periph B TK1, conflicts with GTX2 */
+ AT91_PIOB 3 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB3 periph B TF1, conflicts with GTX3 */
+ AT91_PIOB 6 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB6 periph B TD1, conflicts with TD1 */
+ };
+
+ pinctrl_ssc1_rx: ssc1_rx {
+ atmel,pins =
+ <AT91_PIOB 7 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB7 periph B RK1, conflicts with EREFCK */
+ AT91_PIOB 10 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB10 periph B RF1, conflicts with GTXER */
+ AT91_PIOB 11 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB11 periph B RD1, conflicts with GRXCK */
+ };
+ };
+
+ uart0 {
+ pinctrl_uart0: uart0-0 {
+ atmel,pins =
+ <AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* conflicts with PWMFI2, ISI_D8 */
+ AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* conflicts with ISI_PCK */
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1: uart1-0 {
+ atmel,pins =
+ <AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE /* conflicts with TWD0, ISI_VSYNC */
+ AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* conflicts with TWCK0, ISI_HSYNC */
+ };
+ };
+
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <AT91_PIOD 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD17 periph A */
+ AT91_PIOD 18 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PD18 periph A with pullup */
+ };
+
+ pinctrl_usart0_rts_cts: usart0_rts_cts-0 {
+ atmel,pins =
+ <AT91_PIOD 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD15 periph A, conflicts with SPI0_NPCS2, CANTX0 */
+ AT91_PIOD 16 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD16 periph A, conflicts with SPI0_NPCS3, PWMFI3 */
+ };
+ };
+
+ usart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <AT91_PIOB 28 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB28 periph A */
+ AT91_PIOB 29 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PB29 periph A with pullup */
+ };
+
+ pinctrl_usart1_rts_cts: usart1_rts_cts-0 {
+ atmel,pins =
+ <AT91_PIOB 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB26 periph A, conflicts with GRX7 */
+ AT91_PIOB 27 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB27 periph A, conflicts with G125CKO */
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <AT91_PIOE 25 AT91_PERIPH_B AT91_PINCTRL_NONE /* PE25 periph B, conflicts with A25 */
+ AT91_PIOE 26 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* PE26 periph B with pullup, conflicts NCS0 */
+ };
+
+ pinctrl_usart2_rts_cts: usart2_rts_cts-0 {
+ atmel,pins =
+ <AT91_PIOE 23 AT91_PERIPH_B AT91_PINCTRL_NONE /* PE23 periph B, conflicts with A23 */
+ AT91_PIOE 24 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PE24 periph B, conflicts with A24 */
+ };
+ };
+
+ usart3 {
+ pinctrl_usart3: usart3-0 {
+ atmel,pins =
+ <AT91_PIOE 18 AT91_PERIPH_B AT91_PINCTRL_NONE /* PE18 periph B, conflicts with A18 */
+ AT91_PIOE 19 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* PE19 periph B with pullup, conflicts with A19 */
+ };
+
+ pinctrl_usart3_rts_cts: usart3_rts_cts-0 {
+ atmel,pins =
+ <AT91_PIOE 16 AT91_PERIPH_B AT91_PINCTRL_NONE /* PE16 periph B, conflicts with A16 */
+ AT91_PIOE 17 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PE17 periph B, conflicts with A17 */
+ };
+ };
+
+
+ pioA: gpio@fffff200 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff200 0x100>;
+ interrupts = <6 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioA_clk>;
+ };
+
+ pioB: gpio@fffff400 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x100>;
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioB_clk>;
+ };
+
+ pioC: gpio@fffff600 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x100>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioC_clk>;
+ };
+
+ pioD: gpio@fffff800 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x100>;
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioD_clk>;
+ };
+
+ pioE: gpio@fffffa00 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x100>;
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioE_clk>;
+ };
+ };
+
+ pmc: pmc@fffffc00 {
+ compatible = "atmel,sama5d3-pmc";
+ reg = <0xfffffc00 0x120>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ main_rc_osc: main_rc_osc {
+ compatible = "atmel,at91sam9x5-clk-main-rc-osc";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_MOSCRCS>;
+ clock-frequency = <12000000>;
+ clock-accuracy = <50000000>;
+ };
+
+ main_osc: main_osc {
+ compatible = "atmel,at91rm9200-clk-main-osc";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_MOSCS>;
+ clocks = <&main_xtal>;
+ };
+
+ main: mainck {
+ compatible = "atmel,at91sam9x5-clk-main";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_MOSCSELS>;
+ clocks = <&main_rc_osc &main_osc>;
+ };
+
+ plla: pllack {
+ compatible = "atmel,sama5d3-clk-pll";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_LOCKA>;
+ clocks = <&main>;
+ reg = <0>;
+ atmel,clk-input-range = <8000000 50000000>;
+ #atmel,pll-clk-output-range-cells = <4>;
+ atmel,pll-clk-output-ranges = <400000000 1000000000 0 0>;
+ };
+
+ plladiv: plladivck {
+ compatible = "atmel,at91sam9x5-clk-plldiv";
+ #clock-cells = <0>;
+ clocks = <&plla>;
+ };
+
+ utmi: utmick {
+ compatible = "atmel,at91sam9x5-clk-utmi";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_LOCKU>;
+ clocks = <&main>;
+ };
+
+ mck: masterck {
+ compatible = "atmel,at91sam9x5-clk-master";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_MCKRDY>;
+ clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>;
+ atmel,clk-output-range = <0 166000000>;
+ atmel,clk-divisors = <1 2 4 3>;
+ };
+
+ usb: usbck {
+ compatible = "atmel,at91sam9x5-clk-usb";
+ #clock-cells = <0>;
+ clocks = <&plladiv>, <&utmi>;
+ };
+
+ prog: progck {
+ compatible = "atmel,at91sam9x5-clk-programmable";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-parent = <&pmc>;
+ clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>;
+
+ prog0: prog0 {
+ #clock-cells = <0>;
+ reg = <0>;
+ interrupts = <AT91_PMC_PCKRDY(0)>;
+ };
+
+ prog1: prog1 {
+ #clock-cells = <0>;
+ reg = <1>;
+ interrupts = <AT91_PMC_PCKRDY(1)>;
+ };
+
+ prog2: prog2 {
+ #clock-cells = <0>;
+ reg = <2>;
+ interrupts = <AT91_PMC_PCKRDY(2)>;
+ };
+ };
+
+ smd: smdclk {
+ compatible = "atmel,at91sam9x5-clk-smd";
+ #clock-cells = <0>;
+ clocks = <&plladiv>, <&utmi>;
+ };
+
+ systemck {
+ compatible = "atmel,at91rm9200-clk-system";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ddrck: ddrck {
+ #clock-cells = <0>;
+ reg = <2>;
+ clocks = <&mck>;
+ };
+
+ smdck: smdck {
+ #clock-cells = <0>;
+ reg = <4>;
+ clocks = <&smd>;
+ };
+
+ uhpck: uhpck {
+ #clock-cells = <0>;
+ reg = <6>;
+ clocks = <&usb>;
+ };
+
+ udpck: udpck {
+ #clock-cells = <0>;
+ reg = <7>;
+ clocks = <&usb>;
+ };
+
+ pck0: pck0 {
+ #clock-cells = <0>;
+ reg = <8>;
+ clocks = <&prog0>;
+ };
+
+ pck1: pck1 {
+ #clock-cells = <0>;
+ reg = <9>;
+ clocks = <&prog1>;
+ };
+
+ pck2: pck2 {
+ #clock-cells = <0>;
+ reg = <10>;
+ clocks = <&prog2>;
+ };
+ };
+
+ periphck {
+ compatible = "atmel,at91sam9x5-clk-peripheral";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mck>;
+
+ dbgu_clk: dbgu_clk {
+ #clock-cells = <0>;
+ reg = <2>;
+ };
+
+ hsmc_clk: hsmc_clk {
+ #clock-cells = <0>;
+ reg = <5>;
+ };
+
+ pioA_clk: pioA_clk {
+ #clock-cells = <0>;
+ reg = <6>;
+ };
+
+ pioB_clk: pioB_clk {
+ #clock-cells = <0>;
+ reg = <7>;
+ };
+
+ pioC_clk: pioC_clk {
+ #clock-cells = <0>;
+ reg = <8>;
+ };
+
+ pioD_clk: pioD_clk {
+ #clock-cells = <0>;
+ reg = <9>;
+ };
+
+ pioE_clk: pioE_clk {
+ #clock-cells = <0>;
+ reg = <10>;
+ };
+
+ usart0_clk: usart0_clk {
+ #clock-cells = <0>;
+ reg = <12>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ usart1_clk: usart1_clk {
+ #clock-cells = <0>;
+ reg = <13>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ usart2_clk: usart2_clk {
+ #clock-cells = <0>;
+ reg = <14>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ usart3_clk: usart3_clk {
+ #clock-cells = <0>;
+ reg = <15>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ uart0_clk: uart0_clk {
+ #clock-cells = <0>;
+ reg = <16>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ twi0_clk: twi0_clk {
+ reg = <18>;
+ #clock-cells = <0>;
+ atmel,clk-output-range = <0 16625000>;
+ };
+
+ twi1_clk: twi1_clk {
+ #clock-cells = <0>;
+ reg = <19>;
+ atmel,clk-output-range = <0 16625000>;
+ };
+
+ twi2_clk: twi2_clk {
+ #clock-cells = <0>;
+ reg = <20>;
+ atmel,clk-output-range = <0 16625000>;
+ };
+
+ mci0_clk: mci0_clk {
+ #clock-cells = <0>;
+ reg = <21>;
+ };
+
+ mci1_clk: mci1_clk {
+ #clock-cells = <0>;
+ reg = <22>;
+ };
+
+ spi0_clk: spi0_clk {
+ #clock-cells = <0>;
+ reg = <24>;
+ atmel,clk-output-range = <0 133000000>;
+ };
+
+ spi1_clk: spi1_clk {
+ #clock-cells = <0>;
+ reg = <25>;
+ atmel,clk-output-range = <0 133000000>;
+ };
+
+ tcb0_clk: tcb0_clk {
+ #clock-cells = <0>;
+ reg = <26>;
+ atmel,clk-output-range = <0 133000000>;
+ };
+
+ pwm_clk: pwm_clk {
+ #clock-cells = <0>;
+ reg = <28>;
+ };
+
+ adc_clk: adc_clk {
+ #clock-cells = <0>;
+ reg = <29>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ dma0_clk: dma0_clk {
+ #clock-cells = <0>;
+ reg = <30>;
+ };
+
+ dma1_clk: dma1_clk {
+ #clock-cells = <0>;
+ reg = <31>;
+ };
+
+ uhphs_clk: uhphs_clk {
+ #clock-cells = <0>;
+ reg = <32>;
+ };
+
+ udphs_clk: udphs_clk {
+ #clock-cells = <0>;
+ reg = <33>;
+ };
+
+ isi_clk: isi_clk {
+ #clock-cells = <0>;
+ reg = <37>;
+ };
+
+ ssc0_clk: ssc0_clk {
+ #clock-cells = <0>;
+ reg = <38>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ ssc1_clk: ssc1_clk {
+ #clock-cells = <0>;
+ reg = <39>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ sha_clk: sha_clk {
+ #clock-cells = <0>;
+ reg = <42>;
+ };
+
+ aes_clk: aes_clk {
+ #clock-cells = <0>;
+ reg = <43>;
+ };
+
+ tdes_clk: tdes_clk {
+ #clock-cells = <0>;
+ reg = <44>;
+ };
+
+ trng_clk: trng_clk {
+ #clock-cells = <0>;
+ reg = <45>;
+ };
+
+ fuse_clk: fuse_clk {
+ #clock-cells = <0>;
+ reg = <48>;
+ };
+
+ mpddr_clk: mpddr_clk {
+ #clock-cells = <0>;
+ reg = <49>;
+ };
+ };
+ };
+
+ rstc@fffffe00 {
+ compatible = "atmel,at91sam9g45-rstc";
+ reg = <0xfffffe00 0x10>;
+ };
+
+ shutdown-controller@fffffe10 {
+ compatible = "atmel,at91sam9x5-shdwc";
+ reg = <0xfffffe10 0x10>;
+ };
+
+ pit: timer@fffffe30 {
+ compatible = "atmel,at91sam9260-pit";
+ reg = <0xfffffe30 0xf>;
+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH 5>;
+ clocks = <&mck>;
+ };
+
+ watchdog@fffffe40 {
+ compatible = "atmel,at91sam9260-wdt";
+ reg = <0xfffffe40 0x10>;
+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH 7>;
+ atmel,watchdog-type = "hardware";
+ atmel,reset-type = "all";
+ atmel,dbg-halt;
+ status = "disabled";
+ };
+
+ sckc@fffffe50 {
+ compatible = "atmel,at91sam9x5-sckc";
+ reg = <0xfffffe50 0x4>;
+
+ slow_rc_osc: slow_rc_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-rc-osc";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-accuracy = <50000000>;
+ atmel,startup-time-usec = <75>;
+ };
+
+ slow_osc: slow_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-osc";
+ #clock-cells = <0>;
+ clocks = <&slow_xtal>;
+ atmel,startup-time-usec = <1200000>;
+ };
+
+ clk32k: slowck {
+ compatible = "atmel,at91sam9x5-clk-slow";
+ #clock-cells = <0>;
+ clocks = <&slow_rc_osc &slow_osc>;
+ };
+ };
+
+ rtc@fffffeb0 {
+ compatible = "atmel,at91rm9200-rtc";
+ reg = <0xfffffeb0 0x30>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ };
+ };
+
+ usb0: gadget@00500000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,sama5d3-udc";
+ reg = <0x00500000 0x100000
+ 0xf8030000 0x4000>;
+ interrupts = <33 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&udphs_clk>, <&utmi>;
+ clock-names = "pclk", "hclk";
+ status = "disabled";
+
+ ep0 {
+ reg = <0>;
+ atmel,fifo-size = <64>;
+ atmel,nb-banks = <1>;
+ };
+
+ ep1 {
+ reg = <1>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <3>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep2 {
+ reg = <2>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <3>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep3 {
+ reg = <3>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-dma;
+ };
+
+ ep4 {
+ reg = <4>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-dma;
+ };
+
+ ep5 {
+ reg = <5>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-dma;
+ };
+
+ ep6 {
+ reg = <6>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-dma;
+ };
+
+ ep7 {
+ reg = <7>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-dma;
+ };
+
+ ep8 {
+ reg = <8>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ };
+
+ ep9 {
+ reg = <9>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ };
+
+ ep10 {
+ reg = <10>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ };
+
+ ep11 {
+ reg = <11>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ };
+
+ ep12 {
+ reg = <12>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ };
+
+ ep13 {
+ reg = <13>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ };
+
+ ep14 {
+ reg = <14>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ };
+
+ ep15 {
+ reg = <15>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ };
+ };
+
+ usb1: ohci@00600000 {
+ compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+ reg = <0x00600000 0x100000>;
+ interrupts = <32 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>,
+ <&uhpck>;
+ clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck";
+ status = "disabled";
+ };
+
+ usb2: ehci@00700000 {
+ compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
+ reg = <0x00700000 0x100000>;
+ interrupts = <32 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&utmi>, <&uhphs_clk>, <&uhpck>;
+ clock-names = "usb_clk", "ehci_clk", "uhpck";
+ status = "disabled";
+ };
+
+ nand0: nand@60000000 {
+ compatible = "atmel,at91rm9200-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ reg = < 0x60000000 0x01000000 /* EBI CS3 */
+ 0xffffc070 0x00000490 /* SMC PMECC regs */
+ 0xffffc500 0x00000100 /* SMC PMECC Error Location regs */
+ 0x00110000 0x00018000 /* ROM code */
+ >;
+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH 6>;
+ atmel,nand-addr-offset = <21>;
+ atmel,nand-cmd-offset = <22>;
+ atmel,nand-has-dma;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand0_ale_cle>;
+ atmel,pmecc-lookup-table-offset = <0x0 0x8000>;
+ status = "disabled";
+
+ nfc@70000000 {
+ compatible = "atmel,sama5d3-nfc";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <
+ 0x70000000 0x10000000 /* NFC Command Registers */
+ 0xffffc000 0x00000070 /* NFC HSMC regs */
+ 0x00200000 0x00100000 /* NFC SRAM banks */
+ >;
+ clocks = <&hsmc_clk>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d31.dtsi b/arch/arm/boot/dts/sama5d31.dtsi
new file mode 100644
index 000000000..883878b32
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d31.dtsi
@@ -0,0 +1,16 @@
+/*
+ * sama5d31.dtsi - Device Tree Include file for SAMA5D31 SoC
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+#include "sama5d3.dtsi"
+#include "sama5d3_lcd.dtsi"
+#include "sama5d3_emac.dtsi"
+#include "sama5d3_mci2.dtsi"
+#include "sama5d3_uart.dtsi"
+
+/ {
+ compatible = "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
+};
diff --git a/arch/arm/boot/dts/sama5d31ek.dts b/arch/arm/boot/dts/sama5d31ek.dts
new file mode 100644
index 000000000..04eec0dfc
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d31ek.dts
@@ -0,0 +1,52 @@
+/*
+ * sama5d31ek.dts - Device Tree file for SAMA5D31-EK board
+ *
+ * Copyright (C) 2013 Atmel,
+ * 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "sama5d31.dtsi"
+#include "sama5d3xmb.dtsi"
+#include "sama5d3xdm.dtsi"
+
+/ {
+ model = "Atmel SAMA5D31-EK";
+ compatible = "atmel,sama5d31ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
+
+ ahb {
+ apb {
+ spi0: spi@f0004000 {
+ status = "okay";
+ };
+
+ ssc0: ssc@f0008000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@f0014000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@f0018000 {
+ status = "okay";
+ };
+
+ macb1: ethernet@f802c000 {
+ status = "okay";
+ };
+ };
+ };
+
+ leds {
+ d3 {
+ label = "d3";
+ gpios = <&pioE 24 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ sound {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d33.dtsi b/arch/arm/boot/dts/sama5d33.dtsi
new file mode 100644
index 000000000..4b4434aca
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d33.dtsi
@@ -0,0 +1,14 @@
+/*
+ * sama5d33.dtsi - Device Tree Include file for SAMA5D33 SoC
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+#include "sama5d3.dtsi"
+#include "sama5d3_lcd.dtsi"
+#include "sama5d3_gmac.dtsi"
+
+/ {
+ compatible = "atmel,sama5d33", "atmel,sama5d3", "atmel,sama5";
+};
diff --git a/arch/arm/boot/dts/sama5d33ek.dts b/arch/arm/boot/dts/sama5d33ek.dts
new file mode 100644
index 000000000..cbd6a3ff1
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d33ek.dts
@@ -0,0 +1,45 @@
+/*
+ * sama5d33ek.dts - Device Tree file for SAMA5D33-EK board
+ *
+ * Copyright (C) 2013 Atmel,
+ * 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "sama5d33.dtsi"
+#include "sama5d3xmb.dtsi"
+#include "sama5d3xdm.dtsi"
+
+/ {
+ model = "Atmel SAMA5D33-EK";
+ compatible = "atmel,sama5d33ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d33", "atmel,sama5d3", "atmel,sama5";
+
+ ahb {
+ apb {
+ spi0: spi@f0004000 {
+ status = "okay";
+ };
+
+ ssc0: ssc@f0008000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@f0014000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@f0018000 {
+ status = "okay";
+ };
+
+ macb0: ethernet@f0028000 {
+ status = "okay";
+ };
+ };
+ };
+
+ sound {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d34.dtsi b/arch/arm/boot/dts/sama5d34.dtsi
new file mode 100644
index 000000000..aa01573fd
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d34.dtsi
@@ -0,0 +1,16 @@
+/*
+ * sama5d34.dtsi - Device Tree Include file for SAMA5D34 SoC
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+#include "sama5d3.dtsi"
+#include "sama5d3_lcd.dtsi"
+#include "sama5d3_gmac.dtsi"
+#include "sama5d3_can.dtsi"
+#include "sama5d3_mci2.dtsi"
+
+/ {
+ compatible = "atmel,sama5d34", "atmel,sama5d3", "atmel,sama5";
+};
diff --git a/arch/arm/boot/dts/sama5d34ek.dts b/arch/arm/boot/dts/sama5d34ek.dts
new file mode 100644
index 000000000..878aa1642
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d34ek.dts
@@ -0,0 +1,62 @@
+/*
+ * sama5d34ek.dts - Device Tree file for SAMA5D34-EK board
+ *
+ * Copyright (C) 2013 Atmel,
+ * 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "sama5d34.dtsi"
+#include "sama5d3xmb.dtsi"
+#include "sama5d3xdm.dtsi"
+
+/ {
+ model = "Atmel SAMA5D34-EK";
+ compatible = "atmel,sama5d34ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d34", "atmel,sama5d3", "atmel,sama5";
+
+ ahb {
+ apb {
+ spi0: spi@f0004000 {
+ status = "okay";
+ };
+
+ ssc0: ssc@f0008000 {
+ status = "okay";
+ };
+
+ can0: can@f000c000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@f0014000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@f0018000 {
+ status = "okay";
+
+ 24c256@50 {
+ compatible = "24c256";
+ reg = <0x50>;
+ pagesize = <64>;
+ };
+ };
+
+ macb0: ethernet@f0028000 {
+ status = "okay";
+ };
+ };
+ };
+
+ leds {
+ d3 {
+ label = "d3";
+ gpios = <&pioE 24 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ sound {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d35.dtsi b/arch/arm/boot/dts/sama5d35.dtsi
new file mode 100644
index 000000000..16c39f4c9
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d35.dtsi
@@ -0,0 +1,18 @@
+/*
+ * sama5d35.dtsi - Device Tree Include file for SAMA5D35 SoC
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+#include "sama5d3.dtsi"
+#include "sama5d3_gmac.dtsi"
+#include "sama5d3_emac.dtsi"
+#include "sama5d3_can.dtsi"
+#include "sama5d3_mci2.dtsi"
+#include "sama5d3_uart.dtsi"
+#include "sama5d3_tcb1.dtsi"
+
+/ {
+ compatible = "atmel,sama5d35", "atmel,sama5d3", "atmel,sama5";
+};
diff --git a/arch/arm/boot/dts/sama5d35ek.dts b/arch/arm/boot/dts/sama5d35ek.dts
new file mode 100644
index 000000000..d9a9aca1c
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d35ek.dts
@@ -0,0 +1,55 @@
+/*
+ * sama5d35ek.dts - Device Tree file for SAMA5D35-EK board
+ *
+ * Copyright (C) 2013 Atmel,
+ * 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "sama5d35.dtsi"
+#include "sama5d3xmb.dtsi"
+
+/ {
+ model = "Atmel SAMA5D35-EK";
+ compatible = "atmel,sama5d35ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d35", "atmel,sama5d3", "atmel,sama5";
+
+ ahb {
+ apb {
+ spi0: spi@f0004000 {
+ status = "okay";
+ };
+
+ can0: can@f000c000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@f0018000 {
+ status = "okay";
+ };
+
+ macb0: ethernet@f0028000 {
+ status = "okay";
+ };
+
+ isi: isi@f0034000 {
+ status = "okay";
+ };
+
+ macb1: ethernet@f802c000 {
+ status = "okay";
+ };
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ pb_user1 {
+ label = "pb_user1";
+ gpios = <&pioE 27 GPIO_ACTIVE_HIGH>;
+ linux,code = <0x100>;
+ gpio-key,wakeup;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d36.dtsi b/arch/arm/boot/dts/sama5d36.dtsi
new file mode 100644
index 000000000..e85139ef4
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d36.dtsi
@@ -0,0 +1,20 @@
+/*
+ * sama5d36.dtsi - Device Tree Include file for SAMA5D36 SoC
+ *
+ * Copyright (C) 2013 Atmel,
+ * 2013 Josh Wu <josh.wu@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+#include "sama5d3.dtsi"
+#include "sama5d3_can.dtsi"
+#include "sama5d3_gmac.dtsi"
+#include "sama5d3_emac.dtsi"
+#include "sama5d3_lcd.dtsi"
+#include "sama5d3_mci2.dtsi"
+#include "sama5d3_tcb1.dtsi"
+#include "sama5d3_uart.dtsi"
+
+/ {
+ compatible = "atmel,sama5d36", "atmel,sama5d3", "atmel,sama5";
+};
diff --git a/arch/arm/boot/dts/sama5d36ek.dts b/arch/arm/boot/dts/sama5d36ek.dts
new file mode 100644
index 000000000..59576c6f9
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d36ek.dts
@@ -0,0 +1,53 @@
+/*
+ * sama5d36ek.dts - Device Tree file for SAMA5D36-EK board
+ *
+ * Copyright (C) 2013 Atmel,
+ * 2013 Josh Wu <josh.wu@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "sama5d36.dtsi"
+#include "sama5d3xmb.dtsi"
+#include "sama5d3xdm.dtsi"
+
+/ {
+ model = "Atmel SAMA5D36-EK";
+ compatible = "atmel,sama5d36ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d36", "atmel,sama5d3", "atmel,sama5";
+
+ ahb {
+ apb {
+ spi0: spi@f0004000 {
+ status = "okay";
+ };
+
+ ssc0: ssc@f0008000 {
+ status = "okay";
+ };
+
+ can0: can@f000c000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@f0014000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@f0018000 {
+ status = "okay";
+ };
+
+ macb0: ethernet@f0028000 {
+ status = "okay";
+ };
+
+ macb1: ethernet@f802c000 {
+ status = "okay";
+ };
+ };
+ };
+
+ sound {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d3_can.dtsi b/arch/arm/boot/dts/sama5d3_can.dtsi
new file mode 100644
index 000000000..c5a377274
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d3_can.dtsi
@@ -0,0 +1,74 @@
+/*
+ * sama5d3_can.dtsi - Device Tree Include file for SAMA5D3 SoC with
+ * CAN support
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ ahb {
+ apb {
+ pinctrl@fffff200 {
+ can0 {
+ pinctrl_can0_rx_tx: can0_rx_tx {
+ atmel,pins =
+ <AT91_PIOD 14 AT91_PERIPH_C AT91_PINCTRL_NONE /* PD14 periph C RX, conflicts with SCK0, SPI0_NPCS1 */
+ AT91_PIOD 15 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PD15 periph C TX, conflicts with CTS0, SPI0_NPCS2 */
+ };
+ };
+
+ can1 {
+ pinctrl_can1_rx_tx: can1_rx_tx {
+ atmel,pins =
+ <AT91_PIOB 14 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB14 periph B RX, conflicts with GCRS */
+ AT91_PIOB 15 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB15 periph B TX, conflicts with GCOL */
+ };
+ };
+
+ };
+
+ pmc: pmc@fffffc00 {
+ periphck {
+ can0_clk: can0_clk {
+ #clock-cells = <0>;
+ reg = <40>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ can1_clk: can1_clk {
+ #clock-cells = <0>;
+ reg = <41>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+ };
+ };
+
+ can0: can@f000c000 {
+ compatible = "atmel,at91sam9x5-can";
+ reg = <0xf000c000 0x300>;
+ interrupts = <40 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can0_rx_tx>;
+ clocks = <&can0_clk>;
+ clock-names = "can_clk";
+ status = "disabled";
+ };
+
+ can1: can@f8010000 {
+ compatible = "atmel,at91sam9x5-can";
+ reg = <0xf8010000 0x300>;
+ interrupts = <41 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can1_rx_tx>;
+ clocks = <&can1_clk>;
+ clock-names = "can_clk";
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d3_emac.dtsi b/arch/arm/boot/dts/sama5d3_emac.dtsi
new file mode 100644
index 000000000..7cb235ef0
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d3_emac.dtsi
@@ -0,0 +1,55 @@
+/*
+ * sama5d3_emac.dtsi - Device Tree Include file for SAMA5D3 SoC with
+ * Ethernet.
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ ahb {
+ apb {
+ pinctrl@fffff200 {
+ macb1 {
+ pinctrl_macb1_rmii: macb1_rmii-0 {
+ atmel,pins =
+ <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC0 periph A ETX0, conflicts with TIOA3 */
+ AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC1 periph A ETX1, conflicts with TIOB3 */
+ AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC2 periph A ERX0, conflicts with TCLK3 */
+ AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC3 periph A ERX1, conflicts with TIOA4 */
+ AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC4 periph A ETXEN, conflicts with TIOB4 */
+ AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC5 periph A ECRSDV,conflicts with TCLK4 */
+ AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC6 periph A ERXER, conflicts with TIOA5 */
+ AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC7 periph A EREFCK, conflicts with TIOB5 */
+ AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC8 periph A EMDC, conflicts with TCLK5 */
+ AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PC9 periph A EMDIO */
+ };
+ };
+ };
+
+ pmc: pmc@fffffc00 {
+ periphck {
+ macb1_clk: macb1_clk {
+ #clock-cells = <0>;
+ reg = <35>;
+ };
+ };
+ };
+
+ macb1: ethernet@f802c000 {
+ compatible = "cdns,at91sam9260-macb", "cdns,macb";
+ reg = <0xf802c000 0x100>;
+ interrupts = <35 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb1_rmii>;
+ clocks = <&macb1_clk>, <&macb1_clk>;
+ clock-names = "hclk", "pclk";
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d3_gmac.dtsi b/arch/arm/boot/dts/sama5d3_gmac.dtsi
new file mode 100644
index 000000000..23f225fbb
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d3_gmac.dtsi
@@ -0,0 +1,88 @@
+/*
+ * sama5d3_gmac.dtsi - Device Tree Include file for SAMA5D3 SoC with
+ * Gigabit Ethernet.
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ ahb {
+ apb {
+ pinctrl@fffff200 {
+ macb0 {
+ pinctrl_macb0_data_rgmii: macb0_data_rgmii {
+ atmel,pins =
+ <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB0 periph A GTX0, conflicts with PWMH0 */
+ AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB1 periph A GTX1, conflicts with PWML0 */
+ AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB2 periph A GTX2, conflicts with TK1 */
+ AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB3 periph A GTX3, conflicts with TF1 */
+ AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB4 periph A GRX0, conflicts with PWMH1 */
+ AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB5 periph A GRX1, conflicts with PWML1 */
+ AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB6 periph A GRX2, conflicts with TD1 */
+ AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB7 periph A GRX3, conflicts with RK1 */
+ };
+ pinctrl_macb0_data_gmii: macb0_data_gmii {
+ atmel,pins =
+ <AT91_PIOB 19 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB19 periph B GTX4, conflicts with MCI1_CDA */
+ AT91_PIOB 20 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB20 periph B GTX5, conflicts with MCI1_DA0 */
+ AT91_PIOB 21 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB21 periph B GTX6, conflicts with MCI1_DA1 */
+ AT91_PIOB 22 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB22 periph B GTX7, conflicts with MCI1_DA2 */
+ AT91_PIOB 23 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB23 periph B GRX4, conflicts with MCI1_DA3 */
+ AT91_PIOB 24 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB24 periph B GRX5, conflicts with MCI1_CK */
+ AT91_PIOB 25 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB25 periph B GRX6, conflicts with SCK1 */
+ AT91_PIOB 26 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB26 periph B GRX7, conflicts with CTS1 */
+ };
+ pinctrl_macb0_signal_rgmii: macb0_signal_rgmii {
+ atmel,pins =
+ <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB8 periph A GTXCK, conflicts with PWMH2 */
+ AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB9 periph A GTXEN, conflicts with PWML2 */
+ AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB11 periph A GRXCK, conflicts with RD1 */
+ AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB13 periph A GRXER, conflicts with PWML3 */
+ AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB16 periph A GMDC */
+ AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB17 periph A GMDIO */
+ AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB18 periph A G125CK */
+ };
+ pinctrl_macb0_signal_gmii: macb0_signal_gmii {
+ atmel,pins =
+ <AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB9 periph A GTXEN, conflicts with PWML2 */
+ AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB10 periph A GTXER, conflicts with RF1 */
+ AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB11 periph A GRXCK, conflicts with RD1 */
+ AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB12 periph A GRXDV, conflicts with PWMH3 */
+ AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB13 periph A GRXER, conflicts with PWML3 */
+ AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB14 periph A GCRS, conflicts with CANRX1 */
+ AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB15 periph A GCOL, conflicts with CANTX1 */
+ AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB16 periph A GMDC */
+ AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB17 periph A GMDIO */
+ AT91_PIOB 27 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB27 periph B G125CKO */
+ };
+
+ };
+ };
+
+ pmc: pmc@fffffc00 {
+ periphck {
+ macb0_clk: macb0_clk {
+ #clock-cells = <0>;
+ reg = <34>;
+ };
+ };
+ };
+
+ macb0: ethernet@f0028000 {
+ compatible = "atmel,sama5d3-gem";
+ reg = <0xf0028000 0x100>;
+ interrupts = <34 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb0_data_rgmii &pinctrl_macb0_signal_rgmii>;
+ clocks = <&macb0_clk>, <&macb0_clk>;
+ clock-names = "hclk", "pclk";
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d3_lcd.dtsi b/arch/arm/boot/dts/sama5d3_lcd.dtsi
new file mode 100644
index 000000000..be7cfefc6
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d3_lcd.dtsi
@@ -0,0 +1,215 @@
+/*
+ * sama5d3_lcd.dtsi - Device Tree Include file for SAMA5D3 SoC with
+ * LCD support
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ ahb {
+ apb {
+ hlcdc: hlcdc@f0030000 {
+ compatible = "atmel,sama5d3-hlcdc";
+ reg = <0xf0030000 0x2000>;
+ interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>;
+ clock-names = "periph_clk","sys_clk", "slow_clk";
+ status = "disabled";
+
+ hlcdc-display-controller {
+ compatible = "atmel,hlcdc-display-controller";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+ };
+
+ hlcdc_pwm: hlcdc-pwm {
+ compatible = "atmel,hlcdc-pwm";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcd_pwm>;
+ #pwm-cells = <3>;
+ };
+ };
+
+ pinctrl@fffff200 {
+ lcd {
+ pinctrl_lcd_base: lcd-base-0 {
+ atmel,pins =
+ <AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDVSYNC */
+ AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDHSYNC */
+ AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDDISP */
+ AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDDEN */
+ AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDPCK */
+ };
+
+ pinctrl_lcd_pwm: lcd-pwm-0 {
+ atmel,pins = <AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDPWM */
+ };
+
+ pinctrl_lcd_rgb444: lcd-rgb-0 {
+ atmel,pins =
+ <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */
+ AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */
+ AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */
+ AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */
+ AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */
+ AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */
+ AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */
+ AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */
+ AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */
+ AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */
+ AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD11 pin */
+ };
+
+ pinctrl_lcd_rgb565: lcd-rgb-1 {
+ atmel,pins =
+ <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */
+ AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */
+ AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */
+ AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */
+ AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */
+ AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */
+ AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */
+ AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */
+ AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */
+ AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */
+ AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */
+ AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */
+ AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */
+ AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */
+ AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD15 pin */
+ };
+
+ pinctrl_lcd_rgb666: lcd-rgb-2 {
+ atmel,pins =
+ <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */
+ AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */
+ AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */
+ AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */
+ AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */
+ AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */
+ AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */
+ AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */
+ AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */
+ AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */
+ AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */
+ AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */
+ AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */
+ AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */
+ AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */
+ AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD16 pin */
+ AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD17 pin */
+ };
+
+ pinctrl_lcd_rgb666_alt: lcd-rgb-2-alt {
+ atmel,pins =
+ <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */
+ AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */
+ AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */
+ AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */
+ AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */
+ AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */
+ AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */
+ AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */
+ AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */
+ AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */
+ AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */
+ AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */
+ AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */
+ AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */
+ AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */
+ AT91_PIOC 14 AT91_PERIPH_C AT91_PINCTRL_NONE /* LCDD16 pin */
+ AT91_PIOC 13 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* LCDD17 pin */
+ };
+
+ pinctrl_lcd_rgb888: lcd-rgb-3 {
+ atmel,pins =
+ <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */
+ AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */
+ AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */
+ AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */
+ AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */
+ AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */
+ AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */
+ AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */
+ AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */
+ AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */
+ AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */
+ AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */
+ AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */
+ AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */
+ AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */
+ AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD16 pin */
+ AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD17 pin */
+ AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD18 pin */
+ AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD19 pin */
+ AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD20 pin */
+ AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD21 pin */
+ AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD22 pin */
+ AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD23 pin */
+ };
+
+ pinctrl_lcd_rgb888_alt: lcd-rgb-3-alt {
+ atmel,pins =
+ <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */
+ AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */
+ AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */
+ AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */
+ AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */
+ AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */
+ AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */
+ AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */
+ AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */
+ AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */
+ AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */
+ AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */
+ AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */
+ AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */
+ AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */
+ AT91_PIOC 14 AT91_PERIPH_C AT91_PINCTRL_NONE /* LCDD16 pin */
+ AT91_PIOC 13 AT91_PERIPH_C AT91_PINCTRL_NONE /* LCDD17 pin */
+ AT91_PIOC 12 AT91_PERIPH_C AT91_PINCTRL_NONE /* LCDD18 pin */
+ AT91_PIOC 11 AT91_PERIPH_C AT91_PINCTRL_NONE /* LCDD19 pin */
+ AT91_PIOC 10 AT91_PERIPH_C AT91_PINCTRL_NONE /* LCDD20 pin */
+ AT91_PIOC 15 AT91_PERIPH_C AT91_PINCTRL_NONE /* LCDD21 pin */
+ AT91_PIOE 27 AT91_PERIPH_C AT91_PINCTRL_NONE /* LCDD22 pin */
+ AT91_PIOE 28 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* LCDD23 pin */
+ };
+ };
+ };
+
+ pmc: pmc@fffffc00 {
+ periphck {
+ lcdc_clk: lcdc_clk {
+ #clock-cells = <0>;
+ reg = <36>;
+ };
+ };
+
+ systemck {
+ lcdck: lcdck {
+ #clock-cells = <0>;
+ reg = <3>;
+ clocks = <&mck>;
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d3_mci2.dtsi b/arch/arm/boot/dts/sama5d3_mci2.dtsi
new file mode 100644
index 000000000..026b252f0
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d3_mci2.dtsi
@@ -0,0 +1,59 @@
+/*
+ * sama5d3_mci2.dtsi - Device Tree Include file for SAMA5D3 SoC with
+ * 3 MMC ports
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clock/at91.h>
+
+/ {
+ ahb {
+ apb {
+ pinctrl@fffff200 {
+ mmc2 {
+ pinctrl_mmc2_clk_cmd_dat0: mmc2_clk_cmd_dat0 {
+ atmel,pins =
+ <AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC15 periph A MCI2_CK, conflicts with PCK2 */
+ AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PC10 periph A MCI2_CDA with pullup */
+ AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PC11 periph A MCI2_DA0 with pullup */
+ };
+ pinctrl_mmc2_dat1_3: mmc2_dat1_3 {
+ atmel,pins =
+ <AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC12 periph A MCI2_DA1 with pullup, conflicts with TIOA1 */
+ AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC13 periph A MCI2_DA2 with pullup, conflicts with TIOB1 */
+ AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PC14 periph A MCI2_DA3 with pullup, conflicts with TCLK1 */
+ };
+ };
+ };
+
+ pmc: pmc@fffffc00 {
+ periphck {
+ mci2_clk: mci2_clk {
+ #clock-cells = <0>;
+ reg = <23>;
+ };
+ };
+ };
+
+ mmc2: mmc@f8004000 {
+ compatible = "atmel,hsmci";
+ reg = <0xf8004000 0x600>;
+ interrupts = <23 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(1)>;
+ dma-names = "rxtx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc2_clk_cmd_dat0 &pinctrl_mmc2_dat1_3>;
+ clocks = <&mci2_clk>;
+ clock-names = "mci_clk";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d3_tcb1.dtsi b/arch/arm/boot/dts/sama5d3_tcb1.dtsi
new file mode 100644
index 000000000..f7fa58fe0
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d3_tcb1.dtsi
@@ -0,0 +1,39 @@
+/*
+ * sama5d3_tcb1.dtsi - Device Tree Include file for SAMA5D3 SoC with
+ * 2 TC blocks.
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clock/at91.h>
+
+/ {
+ aliases {
+ tcb1 = &tcb1;
+ };
+
+ ahb {
+ apb {
+ pmc: pmc@fffffc00 {
+ periphck {
+ tcb1_clk: tcb1_clk {
+ #clock-cells = <0>;
+ reg = <27>;
+ };
+ };
+ };
+
+ tcb1: timer@f8014000 {
+ compatible = "atmel,at91sam9x5-tcb";
+ reg = <0xf8014000 0x100>;
+ interrupts = <27 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tcb1_clk>;
+ clock-names = "t0_clk";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d3_uart.dtsi b/arch/arm/boot/dts/sama5d3_uart.dtsi
new file mode 100644
index 000000000..2511d7488
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d3_uart.dtsi
@@ -0,0 +1,79 @@
+/*
+ * sama5d3_uart.dtsi - Device Tree Include file for SAMA5D3 SoC with
+ * UART support
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clock/at91.h>
+
+/ {
+ aliases {
+ serial5 = &uart0;
+ serial6 = &uart1;
+ };
+
+ ahb {
+ apb {
+ pinctrl@fffff200 {
+ uart0 {
+ pinctrl_uart0: uart0-0 {
+ atmel,pins =
+ <AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC29 periph A, conflicts with PWMFI2, ISI_D8 */
+ AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PC30 periph A with pullup, conflicts with ISI_PCK */
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1: uart1-0 {
+ atmel,pins =
+ <AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA30 periph B, conflicts with TWD0, ISI_VSYNC */
+ AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* PA31 periph B with pullup, conflicts with TWCK0, ISI_HSYNC */
+ };
+ };
+ };
+
+ pmc: pmc@fffffc00 {
+ periphck {
+ uart0_clk: uart0_clk {
+ #clock-cells = <0>;
+ reg = <16>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ uart1_clk: uart1_clk {
+ #clock-cells = <0>;
+ reg = <17>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+ };
+ };
+
+ uart0: serial@f0024000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf0024000 0x200>;
+ interrupts = <16 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ clocks = <&uart0_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ uart1: serial@f8028000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xf8028000 0x200>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ clocks = <&uart1_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d3xcm.dtsi b/arch/arm/boot/dts/sama5d3xcm.dtsi
new file mode 100644
index 000000000..7d6babdab
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d3xcm.dtsi
@@ -0,0 +1,128 @@
+/*
+ * sama5d3xcm.dtsi - Device Tree Include file for SAMA5D3x CPU Module
+ *
+ * Copyright (C) 2013 Atmel,
+ * 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/ {
+ compatible = "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 rootfstype=ubifs ubi.mtd=5 root=ubi0:rootfs";
+ };
+
+ memory {
+ reg = <0x20000000 0x20000000>;
+ };
+
+ clocks {
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ spi0: spi@f0004000 {
+ cs-gpios = <&pioD 13 0>, <0>, <0>, <0>;
+ };
+
+ macb0: ethernet@f0028000 {
+ phy-mode = "rgmii";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet-phy@1 {
+ reg = <0x1>;
+ interrupt-parent = <&pioB>;
+ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
+ txen-skew-ps = <800>;
+ txc-skew-ps = <3000>;
+ rxdv-skew-ps = <400>;
+ rxc-skew-ps = <3000>;
+ rxd0-skew-ps = <400>;
+ rxd1-skew-ps = <400>;
+ rxd2-skew-ps = <400>;
+ rxd3-skew-ps = <400>;
+ };
+
+ ethernet-phy@7 {
+ reg = <0x7>;
+ interrupt-parent = <&pioB>;
+ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
+ txen-skew-ps = <800>;
+ txc-skew-ps = <3000>;
+ rxdv-skew-ps = <400>;
+ rxc-skew-ps = <3000>;
+ rxd0-skew-ps = <400>;
+ rxd1-skew-ps = <400>;
+ rxd2-skew-ps = <400>;
+ rxd3-skew-ps = <400>;
+ };
+ };
+
+ pmc: pmc@fffffc00 {
+ main: mainck {
+ clock-frequency = <12000000>;
+ };
+ };
+ };
+
+ nand0: nand@60000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ atmel,has-pmecc;
+ atmel,pmecc-cap = <4>;
+ atmel,pmecc-sector-size = <512>;
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ bootloader@40000 {
+ label = "bootloader";
+ reg = <0x40000 0x80000>;
+ };
+
+ bootloaderenv@c0000 {
+ label = "bootloader env";
+ reg = <0xc0000 0xc0000>;
+ };
+
+ dtb@180000 {
+ label = "device tree";
+ reg = <0x180000 0x80000>;
+ };
+
+ kernel@200000 {
+ label = "kernel";
+ reg = <0x200000 0x600000>;
+ };
+
+ rootfs@800000 {
+ label = "rootfs";
+ reg = <0x800000 0x0f800000>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ d2 {
+ label = "d2";
+ gpios = <&pioE 25 GPIO_ACTIVE_LOW>; /* PE25, conflicts with A25, RXD2 */
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d3xdm.dtsi b/arch/arm/boot/dts/sama5d3xdm.dtsi
new file mode 100644
index 000000000..035ab72b3
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d3xdm.dtsi
@@ -0,0 +1,41 @@
+/*
+ * sama5d3dm.dtsi - Device Tree file for SAMA5 display module
+ *
+ * Copyright (C) 2013 Atmel,
+ * 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/ {
+ ahb {
+ apb {
+ i2c1: i2c@f0018000 {
+ qt1070: keyboard@1b {
+ compatible = "qt1070";
+ reg = <0x1b>;
+ interrupt-parent = <&pioE>;
+ interrupts = <31 0x0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qt1070_irq>;
+ wakeup-source;
+ };
+ };
+
+ adc0: adc@f8018000 {
+ atmel,adc-ts-wires = <4>;
+ atmel,adc-ts-pressure-threshold = <10000>;
+ status = "okay";
+ };
+
+ pinctrl@fffff200 {
+ board {
+ pinctrl_qt1070_irq: qt1070_irq {
+ atmel,pins =
+ <AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PE31 GPIO with pull up deglith */
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d3xmb.dtsi b/arch/arm/boot/dts/sama5d3xmb.dtsi
new file mode 100644
index 000000000..83bee7a3a
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d3xmb.dtsi
@@ -0,0 +1,219 @@
+/*
+ * sama5d3xmb.dts - Device Tree file for SAMA5D3x mother board
+ *
+ * Copyright (C) 2013 Atmel,
+ * 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+#include "sama5d3xcm.dtsi"
+
+/ {
+ compatible = "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5";
+
+ ahb {
+ apb {
+ mmc0: mmc@f0000000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_cd>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 17 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ spi0: spi@f0004000 {
+ dmas = <0>, <0>; /* Do not use DMA for spi0 */
+
+ m25p80@0 {
+ compatible = "atmel,at25df321a";
+ spi-max-frequency = <50000000>;
+ reg = <0>;
+ };
+ };
+
+ ssc0: ssc@f0008000 {
+ atmel,clk-from-rk-pin;
+ };
+
+ /*
+ * i2c0 conflicts with ISI:
+ * disable it to allow the use of ISI
+ * can not enable audio when i2c0 disabled
+ */
+ i2c0: i2c@f0014000 {
+ wm8904: wm8904@1a {
+ compatible = "wlf,wm8904";
+ reg = <0x1a>;
+ clocks = <&pck0>;
+ clock-names = "mclk";
+ };
+ };
+
+ i2c1: i2c@f0018000 {
+ ov2640: camera@0x30 {
+ compatible = "ovti,ov2640";
+ reg = <0x30>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pck1_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>;
+ resetb-gpios = <&pioE 24 GPIO_ACTIVE_LOW>;
+ pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>;
+ /* use pck1 for the master clock of ov2640 */
+ clocks = <&pck1>;
+ clock-names = "xvclk";
+ assigned-clocks = <&pck1>;
+ assigned-clock-rates = <25000000>;
+
+ port {
+ ov2640_0: endpoint {
+ remote-endpoint = <&isi_0>;
+ bus-width = <8>;
+ };
+ };
+ };
+ };
+
+ usart1: serial@f0020000 {
+ dmas = <0>, <0>; /* Do not use DMA for usart1 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>;
+ status = "okay";
+ };
+
+ isi: isi@f0034000 {
+ port {
+ isi_0: endpoint {
+ remote-endpoint = <&ov2640_0>;
+ bus-width = <8>;
+ };
+ };
+ };
+
+ mmc1: mmc@f8000000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 18 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ adc0: adc@f8018000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &pinctrl_adc0_adtrg
+ &pinctrl_adc0_ad0
+ &pinctrl_adc0_ad1
+ &pinctrl_adc0_ad2
+ &pinctrl_adc0_ad3
+ &pinctrl_adc0_ad4
+ >;
+ status = "okay";
+ };
+
+ macb1: ethernet@f802c000 {
+ phy-mode = "rmii";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy0: ethernet-phy@1 {
+ interrupt-parent = <&pioE>;
+ interrupts = <30 IRQ_TYPE_EDGE_FALLING>;
+ reg = <1>;
+ };
+ };
+
+ pinctrl@fffff200 {
+ board {
+ pinctrl_mmc0_cd: mmc0_cd {
+ atmel,pins =
+ <AT91_PIOD 17 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PD17 GPIO with pullup deglitch */
+ };
+
+ pinctrl_mmc1_cd: mmc1_cd {
+ atmel,pins =
+ <AT91_PIOD 18 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PD18 GPIO with pullup deglitch */
+ };
+
+ pinctrl_pck0_as_audio_mck: pck0_as_audio_mck {
+ atmel,pins =
+ <AT91_PIOD 30 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PD30 periph B */
+ };
+
+ pinctrl_pck1_as_isi_mck: pck1_as_isi_mck-0 {
+ atmel,pins =
+ <AT91_PIOD 31 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PD31 periph B ISI_MCK */
+ };
+
+ pinctrl_sensor_reset: sensor_reset-0 {
+ atmel,pins =
+ <AT91_PIOE 24 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; /* PE24 gpio */
+ };
+
+ pinctrl_sensor_power: sensor_power-0 {
+ atmel,pins =
+ <AT91_PIOE 29 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; /* PE29 gpio */
+ };
+
+ pinctrl_usba_vbus: usba_vbus {
+ atmel,pins =
+ <AT91_PIOD 29 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PD29 GPIO with deglitch */
+ };
+ };
+ };
+
+ dbgu: serial@ffffee00 {
+ dmas = <0>, <0>; /* Do not use DMA for dbgu */
+ status = "okay";
+ };
+
+ watchdog@fffffe40 {
+ status = "okay";
+ };
+ };
+
+ usb0: gadget@00500000 {
+ atmel,vbus-gpio = <&pioD 29 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usba_vbus>;
+ status = "okay";
+ };
+
+ usb1: ohci@00600000 {
+ num-ports = <3>;
+ atmel,vbus-gpio = <&pioD 25 GPIO_ACTIVE_HIGH
+ &pioD 26 GPIO_ACTIVE_LOW
+ &pioD 27 GPIO_ACTIVE_LOW
+ >;
+ status = "okay";
+ };
+
+ usb2: ehci@00700000 {
+ status = "okay";
+ };
+ };
+
+ sound {
+ compatible = "atmel,asoc-wm8904";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pck0_as_audio_mck>;
+
+ atmel,model = "wm8904 @ SAMA5D3EK";
+ atmel,audio-routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "IN2L", "Line In Jack",
+ "IN2R", "Line In Jack",
+ "Mic", "MICBIAS",
+ "IN1L", "Mic";
+
+ atmel,ssc-controller = <&ssc0>;
+ atmel,audio-codec = <&wm8904>;
+
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi
new file mode 100644
index 000000000..a5f5f4090
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d4.dtsi
@@ -0,0 +1,1675 @@
+/*
+ * sama5d4.dtsi - Device Tree Include file for SAMA5D4 family SoC
+ *
+ * Copyright (C) 2014 Atmel,
+ * 2014 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/at91.h>
+#include <dt-bindings/dma/at91.h>
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Atmel SAMA5D4 family SoC";
+ compatible = "atmel,sama5d4";
+ interrupt-parent = <&aic>;
+
+ aliases {
+ serial0 = &usart3;
+ serial1 = &usart4;
+ serial2 = &usart2;
+ gpio0 = &pioA;
+ gpio1 = &pioB;
+ gpio2 = &pioC;
+ gpio3 = &pioD;
+ gpio4 = &pioE;
+ pwm0 = &pwm0;
+ ssc0 = &ssc0;
+ ssc1 = &ssc1;
+ tcb0 = &tcb0;
+ tcb1 = &tcb1;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ };
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a5";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory {
+ reg = <0x20000000 0x20000000>;
+ };
+
+ clocks {
+ slow_xtal: slow_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ main_xtal: main_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ adc_op_clk: adc_op_clk{
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1000000>;
+ };
+ };
+
+ ns_sram: sram@00210000 {
+ compatible = "mmio-sram";
+ reg = <0x00210000 0x10000>;
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ usb0: gadget@00400000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,sama5d3-udc";
+ reg = <0x00400000 0x100000
+ 0xfc02c000 0x4000>;
+ interrupts = <47 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&udphs_clk>, <&utmi>;
+ clock-names = "pclk", "hclk";
+ status = "disabled";
+
+ ep0 {
+ reg = <0>;
+ atmel,fifo-size = <64>;
+ atmel,nb-banks = <1>;
+ };
+
+ ep1 {
+ reg = <1>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <3>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep2 {
+ reg = <2>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <3>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep3 {
+ reg = <3>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep4 {
+ reg = <4>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep5 {
+ reg = <5>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep6 {
+ reg = <6>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep7 {
+ reg = <7>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-dma;
+ atmel,can-isoc;
+ };
+
+ ep8 {
+ reg = <8>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-isoc;
+ };
+
+ ep9 {
+ reg = <9>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-isoc;
+ };
+
+ ep10 {
+ reg = <10>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-isoc;
+ };
+
+ ep11 {
+ reg = <11>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-isoc;
+ };
+
+ ep12 {
+ reg = <12>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-isoc;
+ };
+
+ ep13 {
+ reg = <13>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-isoc;
+ };
+
+ ep14 {
+ reg = <14>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-isoc;
+ };
+
+ ep15 {
+ reg = <15>;
+ atmel,fifo-size = <1024>;
+ atmel,nb-banks = <2>;
+ atmel,can-isoc;
+ };
+ };
+
+ usb1: ohci@00500000 {
+ compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+ reg = <0x00500000 0x100000>;
+ interrupts = <46 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>,
+ <&uhpck>;
+ clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck";
+ status = "disabled";
+ };
+
+ usb2: ehci@00600000 {
+ compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
+ reg = <0x00600000 0x100000>;
+ interrupts = <46 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&utmi>, <&uhphs_clk>, <&uhpck>;
+ clock-names = "usb_clk", "ehci_clk", "uhpck";
+ status = "disabled";
+ };
+
+ L2: cache-controller@00a00000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x00a00000 0x1000>;
+ interrupts = <67 IRQ_TYPE_LEVEL_HIGH 4>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ nand0: nand@80000000 {
+ compatible = "atmel,sama5d4-nand", "atmel,at91rm9200-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ reg = < 0x80000000 0x08000000 /* EBI CS3 */
+ 0xfc05c070 0x00000490 /* SMC PMECC regs */
+ 0xfc05c500 0x00000100 /* SMC PMECC Error Location regs */
+ >;
+ interrupts = <22 IRQ_TYPE_LEVEL_HIGH 6>;
+ atmel,nand-addr-offset = <21>;
+ atmel,nand-cmd-offset = <22>;
+ atmel,nand-has-dma;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
+ status = "disabled";
+
+ nfc@90000000 {
+ compatible = "atmel,sama5d3-nfc";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <
+ 0x90000000 0x10000000 /* NFC Command Registers */
+ 0xfc05c000 0x00000070 /* NFC HSMC regs */
+ 0x00100000 0x00100000 /* NFC SRAM banks */
+ >;
+ clocks = <&hsmc_clk>;
+ atmel,write-by-sram;
+ };
+ };
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ hlcdc: hlcdc@f0000000 {
+ compatible = "atmel,sama5d4-hlcdc";
+ reg = <0xf0000000 0x4000>;
+ interrupts = <51 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>;
+ clock-names = "periph_clk","sys_clk", "slow_clk";
+ status = "disabled";
+
+ hlcdc-display-controller {
+ compatible = "atmel,hlcdc-display-controller";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+ };
+
+ hlcdc_pwm: hlcdc-pwm {
+ compatible = "atmel,hlcdc-pwm";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcd_pwm>;
+ #pwm-cells = <3>;
+ };
+ };
+
+ dma1: dma-controller@f0004000 {
+ compatible = "atmel,sama5d4-dma";
+ reg = <0xf0004000 0x200>;
+ interrupts = <50 IRQ_TYPE_LEVEL_HIGH 0>;
+ #dma-cells = <1>;
+ clocks = <&dma1_clk>;
+ clock-names = "dma_clk";
+ };
+
+ isi: isi@f0008000 {
+ compatible = "atmel,at91sam9g45-isi";
+ reg = <0xf0008000 0x4000>;
+ interrupts = <52 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_isi_data_0_7>;
+ clocks = <&isi_clk>;
+ clock-names = "isi_clk";
+ status = "disabled";
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ ramc0: ramc@f0010000 {
+ compatible = "atmel,sama5d3-ddramc";
+ reg = <0xf0010000 0x200>;
+ clocks = <&ddrck>, <&mpddr_clk>;
+ clock-names = "ddrck", "mpddr";
+ };
+
+ dma0: dma-controller@f0014000 {
+ compatible = "atmel,sama5d4-dma";
+ reg = <0xf0014000 0x200>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH 0>;
+ #dma-cells = <1>;
+ clocks = <&dma0_clk>;
+ clock-names = "dma_clk";
+ };
+
+ pmc: pmc@f0018000 {
+ compatible = "atmel,sama5d3-pmc";
+ reg = <0xf0018000 0x120>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ main_rc_osc: main_rc_osc {
+ compatible = "atmel,at91sam9x5-clk-main-rc-osc";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_MOSCRCS>;
+ clock-frequency = <12000000>;
+ clock-accuracy = <100000000>;
+ };
+
+ main_osc: main_osc {
+ compatible = "atmel,at91rm9200-clk-main-osc";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_MOSCS>;
+ clocks = <&main_xtal>;
+ };
+
+ main: mainck {
+ compatible = "atmel,at91sam9x5-clk-main";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_MOSCSELS>;
+ clocks = <&main_rc_osc &main_osc>;
+ };
+
+ plla: pllack {
+ compatible = "atmel,sama5d3-clk-pll";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_LOCKA>;
+ clocks = <&main>;
+ reg = <0>;
+ atmel,clk-input-range = <12000000 12000000>;
+ #atmel,pll-clk-output-range-cells = <4>;
+ atmel,pll-clk-output-ranges = <600000000 1200000000 0 0>;
+ };
+
+ plladiv: plladivck {
+ compatible = "atmel,at91sam9x5-clk-plldiv";
+ #clock-cells = <0>;
+ clocks = <&plla>;
+ };
+
+ utmi: utmick {
+ compatible = "atmel,at91sam9x5-clk-utmi";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_LOCKU>;
+ clocks = <&main>;
+ };
+
+ mck: masterck {
+ compatible = "atmel,at91sam9x5-clk-master";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_MCKRDY>;
+ clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>;
+ atmel,clk-output-range = <125000000 177000000>;
+ atmel,clk-divisors = <1 2 4 3>;
+ };
+
+ h32ck: h32mxck {
+ #clock-cells = <0>;
+ compatible = "atmel,sama5d4-clk-h32mx";
+ clocks = <&mck>;
+ };
+
+ usb: usbck {
+ compatible = "atmel,at91sam9x5-clk-usb";
+ #clock-cells = <0>;
+ clocks = <&plladiv>, <&utmi>;
+ };
+
+ prog: progck {
+ compatible = "atmel,at91sam9x5-clk-programmable";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-parent = <&pmc>;
+ clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>;
+
+ prog0: prog0 {
+ #clock-cells = <0>;
+ reg = <0>;
+ interrupts = <AT91_PMC_PCKRDY(0)>;
+ };
+
+ prog1: prog1 {
+ #clock-cells = <0>;
+ reg = <1>;
+ interrupts = <AT91_PMC_PCKRDY(1)>;
+ };
+
+ prog2: prog2 {
+ #clock-cells = <0>;
+ reg = <2>;
+ interrupts = <AT91_PMC_PCKRDY(2)>;
+ };
+ };
+
+ smd: smdclk {
+ compatible = "atmel,at91sam9x5-clk-smd";
+ #clock-cells = <0>;
+ clocks = <&plladiv>, <&utmi>;
+ };
+
+ systemck {
+ compatible = "atmel,at91rm9200-clk-system";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ddrck: ddrck {
+ #clock-cells = <0>;
+ reg = <2>;
+ clocks = <&mck>;
+ };
+
+ lcdck: lcdck {
+ #clock-cells = <0>;
+ reg = <3>;
+ clocks = <&mck>;
+ };
+
+ smdck: smdck {
+ #clock-cells = <0>;
+ reg = <4>;
+ clocks = <&smd>;
+ };
+
+ uhpck: uhpck {
+ #clock-cells = <0>;
+ reg = <6>;
+ clocks = <&usb>;
+ };
+
+ udpck: udpck {
+ #clock-cells = <0>;
+ reg = <7>;
+ clocks = <&usb>;
+ };
+
+ pck0: pck0 {
+ #clock-cells = <0>;
+ reg = <8>;
+ clocks = <&prog0>;
+ };
+
+ pck1: pck1 {
+ #clock-cells = <0>;
+ reg = <9>;
+ clocks = <&prog1>;
+ };
+
+ pck2: pck2 {
+ #clock-cells = <0>;
+ reg = <10>;
+ clocks = <&prog2>;
+ };
+ };
+
+ periph32ck {
+ compatible = "atmel,at91sam9x5-clk-peripheral";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&h32ck>;
+
+ pioD_clk: pioD_clk {
+ #clock-cells = <0>;
+ reg = <5>;
+ };
+
+ usart0_clk: usart0_clk {
+ #clock-cells = <0>;
+ reg = <6>;
+ };
+
+ usart1_clk: usart1_clk {
+ #clock-cells = <0>;
+ reg = <7>;
+ };
+
+ icm_clk: icm_clk {
+ #clock-cells = <0>;
+ reg = <9>;
+ };
+
+ aes_clk: aes_clk {
+ #clock-cells = <0>;
+ reg = <12>;
+ };
+
+ tdes_clk: tdes_clk {
+ #clock-cells = <0>;
+ reg = <14>;
+ };
+
+ sha_clk: sha_clk {
+ #clock-cells = <0>;
+ reg = <15>;
+ };
+
+ matrix1_clk: matrix1_clk {
+ #clock-cells = <0>;
+ reg = <17>;
+ };
+
+ hsmc_clk: hsmc_clk {
+ #clock-cells = <0>;
+ reg = <22>;
+ };
+
+ pioA_clk: pioA_clk {
+ #clock-cells = <0>;
+ reg = <23>;
+ };
+
+ pioB_clk: pioB_clk {
+ #clock-cells = <0>;
+ reg = <24>;
+ };
+
+ pioC_clk: pioC_clk {
+ #clock-cells = <0>;
+ reg = <25>;
+ };
+
+ pioE_clk: pioE_clk {
+ #clock-cells = <0>;
+ reg = <26>;
+ };
+
+ uart0_clk: uart0_clk {
+ #clock-cells = <0>;
+ reg = <27>;
+ };
+
+ uart1_clk: uart1_clk {
+ #clock-cells = <0>;
+ reg = <28>;
+ };
+
+ usart2_clk: usart2_clk {
+ #clock-cells = <0>;
+ reg = <29>;
+ };
+
+ usart3_clk: usart3_clk {
+ #clock-cells = <0>;
+ reg = <30>;
+ };
+
+ usart4_clk: usart4_clk {
+ #clock-cells = <0>;
+ reg = <31>;
+ };
+
+ twi0_clk: twi0_clk {
+ reg = <32>;
+ #clock-cells = <0>;
+ };
+
+ twi1_clk: twi1_clk {
+ #clock-cells = <0>;
+ reg = <33>;
+ };
+
+ twi2_clk: twi2_clk {
+ #clock-cells = <0>;
+ reg = <34>;
+ };
+
+ mci0_clk: mci0_clk {
+ #clock-cells = <0>;
+ reg = <35>;
+ };
+
+ mci1_clk: mci1_clk {
+ #clock-cells = <0>;
+ reg = <36>;
+ };
+
+ spi0_clk: spi0_clk {
+ #clock-cells = <0>;
+ reg = <37>;
+ };
+
+ spi1_clk: spi1_clk {
+ #clock-cells = <0>;
+ reg = <38>;
+ };
+
+ spi2_clk: spi2_clk {
+ #clock-cells = <0>;
+ reg = <39>;
+ };
+
+ tcb0_clk: tcb0_clk {
+ #clock-cells = <0>;
+ reg = <40>;
+ };
+
+ tcb1_clk: tcb1_clk {
+ #clock-cells = <0>;
+ reg = <41>;
+ };
+
+ tcb2_clk: tcb2_clk {
+ #clock-cells = <0>;
+ reg = <42>;
+ };
+
+ pwm_clk: pwm_clk {
+ #clock-cells = <0>;
+ reg = <43>;
+ };
+
+ adc_clk: adc_clk {
+ #clock-cells = <0>;
+ reg = <44>;
+ };
+
+ dbgu_clk: dbgu_clk {
+ #clock-cells = <0>;
+ reg = <45>;
+ };
+
+ uhphs_clk: uhphs_clk {
+ #clock-cells = <0>;
+ reg = <46>;
+ };
+
+ udphs_clk: udphs_clk {
+ #clock-cells = <0>;
+ reg = <47>;
+ };
+
+ ssc0_clk: ssc0_clk {
+ #clock-cells = <0>;
+ reg = <48>;
+ };
+
+ ssc1_clk: ssc1_clk {
+ #clock-cells = <0>;
+ reg = <49>;
+ };
+
+ trng_clk: trng_clk {
+ #clock-cells = <0>;
+ reg = <53>;
+ };
+
+ macb0_clk: macb0_clk {
+ #clock-cells = <0>;
+ reg = <54>;
+ };
+
+ macb1_clk: macb1_clk {
+ #clock-cells = <0>;
+ reg = <55>;
+ };
+
+ fuse_clk: fuse_clk {
+ #clock-cells = <0>;
+ reg = <57>;
+ };
+
+ securam_clk: securam_clk {
+ #clock-cells = <0>;
+ reg = <59>;
+ };
+
+ smd_clk: smd_clk {
+ #clock-cells = <0>;
+ reg = <61>;
+ };
+
+ twi3_clk: twi3_clk {
+ #clock-cells = <0>;
+ reg = <62>;
+ };
+
+ catb_clk: catb_clk {
+ #clock-cells = <0>;
+ reg = <63>;
+ };
+ };
+
+ periph64ck {
+ compatible = "atmel,at91sam9x5-clk-peripheral";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mck>;
+
+ dma0_clk: dma0_clk {
+ #clock-cells = <0>;
+ reg = <8>;
+ };
+
+ cpkcc_clk: cpkcc_clk {
+ #clock-cells = <0>;
+ reg = <10>;
+ };
+
+ aesb_clk: aesb_clk {
+ #clock-cells = <0>;
+ reg = <13>;
+ };
+
+ mpddr_clk: mpddr_clk {
+ #clock-cells = <0>;
+ reg = <16>;
+ };
+
+ matrix0_clk: matrix0_clk {
+ #clock-cells = <0>;
+ reg = <18>;
+ };
+
+ vdec_clk: vdec_clk {
+ #clock-cells = <0>;
+ reg = <19>;
+ };
+
+ dma1_clk: dma1_clk {
+ #clock-cells = <0>;
+ reg = <50>;
+ };
+
+ lcdc_clk: lcdc_clk {
+ #clock-cells = <0>;
+ reg = <51>;
+ };
+
+ isi_clk: isi_clk {
+ #clock-cells = <0>;
+ reg = <52>;
+ };
+ };
+ };
+
+ mmc0: mmc@f8000000 {
+ compatible = "atmel,hsmci";
+ reg = <0xf8000000 0x600>;
+ interrupts = <35 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(0))>;
+ dma-names = "rxtx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mci0_clk>;
+ clock-names = "mci_clk";
+ };
+
+ ssc0: ssc@f8008000 {
+ compatible = "atmel,at91sam9g45-ssc";
+ reg = <0xf8008000 0x4000>;
+ interrupts = <48 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
+ dmas = <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(26))>,
+ <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(27))>;
+ dma-names = "tx", "rx";
+ clocks = <&ssc0_clk>;
+ clock-names = "pclk";
+ status = "disabled";
+ };
+
+ pwm0: pwm@f800c000 {
+ compatible = "atmel,sama5d3-pwm";
+ reg = <0xf800c000 0x300>;
+ interrupts = <43 IRQ_TYPE_LEVEL_HIGH 4>;
+ #pwm-cells = <3>;
+ clocks = <&pwm_clk>;
+ status = "disabled";
+ };
+
+ spi0: spi@f8010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "atmel,at91rm9200-spi";
+ reg = <0xf8010000 0x100>;
+ interrupts = <37 IRQ_TYPE_LEVEL_HIGH 3>;
+ dmas = <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(10))>,
+ <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(11))>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi0>;
+ clocks = <&spi0_clk>;
+ clock-names = "spi_clk";
+ status = "disabled";
+ };
+
+ i2c0: i2c@f8014000 {
+ compatible = "atmel,at91sam9x5-i2c";
+ reg = <0xf8014000 0x4000>;
+ interrupts = <32 IRQ_TYPE_LEVEL_HIGH 6>;
+ dmas = <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(2))>,
+ <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(3))>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&twi0_clk>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@f8018000 {
+ compatible = "atmel,at91sam9x5-i2c";
+ reg = <0xf8018000 0x4000>;
+ interrupts = <33 IRQ_TYPE_LEVEL_HIGH 6>;
+ dmas = <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1))
+ AT91_XDMAC_DT_PERID(4)>,
+ <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1))
+ AT91_XDMAC_DT_PERID(5)>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&twi1_clk>;
+ status = "disabled";
+ };
+
+ tcb0: timer@f801c000 {
+ compatible = "atmel,at91sam9x5-tcb";
+ reg = <0xf801c000 0x100>;
+ interrupts = <40 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tcb0_clk>;
+ clock-names = "t0_clk";
+ };
+
+ macb0: ethernet@f8020000 {
+ compatible = "atmel,sama5d4-gem";
+ reg = <0xf8020000 0x100>;
+ interrupts = <54 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb0_rmii>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&macb0_clk>, <&macb0_clk>;
+ clock-names = "hclk", "pclk";
+ status = "disabled";
+ };
+
+ i2c2: i2c@f8024000 {
+ compatible = "atmel,at91sam9x5-i2c";
+ reg = <0xf8024000 0x4000>;
+ interrupts = <34 IRQ_TYPE_LEVEL_HIGH 6>;
+ dmas = <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(6))>,
+ <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(7))>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&twi2_clk>;
+ status = "disabled";
+ };
+
+ sfr: sfr@f8028000 {
+ compatible = "atmel,sama5d4-sfr", "syscon";
+ reg = <0xf8028000 0x60>;
+ };
+
+ mmc1: mmc@fc000000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfc000000 0x600>;
+ interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(1))>;
+ dma-names = "rxtx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mci1_clk>;
+ clock-names = "mci_clk";
+ };
+
+ usart2: serial@fc008000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfc008000 0x100>;
+ interrupts = <29 IRQ_TYPE_LEVEL_HIGH 5>;
+ dmas = <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(16))>,
+ <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(17))>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rts &pinctrl_usart2_cts>;
+ clocks = <&usart2_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart3: serial@fc00c000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfc00c000 0x100>;
+ interrupts = <30 IRQ_TYPE_LEVEL_HIGH 5>;
+ dmas = <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(18))>,
+ <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(19))>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart3>;
+ clocks = <&usart3_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ usart4: serial@fc010000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfc010000 0x100>;
+ interrupts = <31 IRQ_TYPE_LEVEL_HIGH 5>;
+ dmas = <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(20))>,
+ <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(21))>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart4>;
+ clocks = <&usart4_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ ssc1: ssc@fc014000 {
+ compatible = "atmel,at91sam9g45-ssc";
+ reg = <0xfc014000 0x4000>;
+ interrupts = <49 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
+ dmas = <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(28))>,
+ <&dma1
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(29))>;
+ dma-names = "tx", "rx";
+ clocks = <&ssc1_clk>;
+ clock-names = "pclk";
+ status = "disabled";
+ };
+
+ tcb1: timer@fc020000 {
+ compatible = "atmel,at91sam9x5-tcb";
+ reg = <0xfc020000 0x100>;
+ interrupts = <41 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tcb1_clk>;
+ clock-names = "t0_clk";
+ };
+
+ adc0: adc@fc034000 {
+ compatible = "atmel,at91sam9x5-adc";
+ reg = <0xfc034000 0x100>;
+ interrupts = <44 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ /* external trigger is conflict with USBA_VBUS */
+ &pinctrl_adc0_ad0
+ &pinctrl_adc0_ad1
+ &pinctrl_adc0_ad2
+ &pinctrl_adc0_ad3
+ &pinctrl_adc0_ad4
+ >;
+ clocks = <&adc_clk>,
+ <&adc_op_clk>;
+ clock-names = "adc_clk", "adc_op_clk";
+ atmel,adc-channels-used = <0x01f>;
+ atmel,adc-startup-time = <40>;
+ atmel,adc-use-external;
+ atmel,adc-vref = <3000>;
+ atmel,adc-res = <8 10>;
+ atmel,adc-sample-hold-time = <11>;
+ atmel,adc-res-names = "lowres", "highres";
+ atmel,adc-ts-pressure-threshold = <10000>;
+ status = "disabled";
+
+ trigger@0 {
+ trigger-name = "external-rising";
+ trigger-value = <0x1>;
+ trigger-external;
+ };
+ trigger@1 {
+ trigger-name = "external-falling";
+ trigger-value = <0x2>;
+ trigger-external;
+ };
+ trigger@2 {
+ trigger-name = "external-any";
+ trigger-value = <0x3>;
+ trigger-external;
+ };
+ trigger@3 {
+ trigger-name = "continuous";
+ trigger-value = <0x6>;
+ };
+ };
+
+ aes@fc044000 {
+ compatible = "atmel,at91sam9g46-aes";
+ reg = <0xfc044000 0x100>;
+ interrupts = <12 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(41))>,
+ <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(40))>;
+ dma-names = "tx", "rx";
+ clocks = <&aes_clk>;
+ clock-names = "aes_clk";
+ status = "disabled";
+ };
+
+ tdes@fc04c000 {
+ compatible = "atmel,at91sam9g46-tdes";
+ reg = <0xfc04c000 0x100>;
+ interrupts = <14 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(42))>,
+ <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(43))>;
+ dma-names = "tx", "rx";
+ clocks = <&tdes_clk>;
+ clock-names = "tdes_clk";
+ status = "disabled";
+ };
+
+ sha@fc050000 {
+ compatible = "atmel,at91sam9g46-sha";
+ reg = <0xfc050000 0x100>;
+ interrupts = <15 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(44))>;
+ dma-names = "tx";
+ clocks = <&sha_clk>;
+ clock-names = "sha_clk";
+ status = "disabled";
+ };
+
+ rstc@fc068600 {
+ compatible = "atmel,at91sam9g45-rstc";
+ reg = <0xfc068600 0x10>;
+ };
+
+ shdwc@fc068610 {
+ compatible = "atmel,at91sam9x5-shdwc";
+ reg = <0xfc068610 0x10>;
+ };
+
+ pit: timer@fc068630 {
+ compatible = "atmel,at91sam9260-pit";
+ reg = <0xfc068630 0x10>;
+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH 5>;
+ clocks = <&h32ck>;
+ };
+
+ watchdog@fc068640 {
+ compatible = "atmel,at91sam9260-wdt";
+ reg = <0xfc068640 0x10>;
+ status = "disabled";
+ };
+
+ sckc@fc068650 {
+ compatible = "atmel,at91sam9x5-sckc";
+ reg = <0xfc068650 0x4>;
+
+ slow_rc_osc: slow_rc_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-rc-osc";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-accuracy = <250000000>;
+ atmel,startup-time-usec = <75>;
+ };
+
+ slow_osc: slow_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-osc";
+ #clock-cells = <0>;
+ clocks = <&slow_xtal>;
+ atmel,startup-time-usec = <1200000>;
+ };
+
+ clk32k: slowck {
+ compatible = "atmel,at91sam9x5-clk-slow";
+ #clock-cells = <0>;
+ clocks = <&slow_rc_osc &slow_osc>;
+ };
+ };
+
+ rtc@fc0686b0 {
+ compatible = "atmel,at91rm9200-rtc";
+ reg = <0xfc0686b0 0x30>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ };
+
+ dbgu: serial@fc069000 {
+ compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
+ reg = <0xfc069000 0x200>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
+ clocks = <&dbgu_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+
+ pinctrl@fc06a000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfc06a000 0xfc06a000 0x4000>;
+ /* WARNING: revisit as pin spec has changed */
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0x3ffcfe7c 0x1c010101 /* pioA */
+ 0x7fffffff 0xfffccc3a 0x3f00cc3a /* pioB */
+ 0xffffffff 0x3ff83fff 0xff00ffff /* pioC */
+ 0x00000000 0x00000000 0x00000000 /* pioD */
+ 0xffffffff 0x7fffffff 0x76fff1bf /* pioE */
+ >;
+
+ pioA: gpio@fc06a000 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfc06a000 0x100>;
+ interrupts = <23 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioA_clk>;
+ };
+
+ pioB: gpio@fc06b000 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfc06b000 0x100>;
+ interrupts = <24 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioB_clk>;
+ };
+
+ pioC: gpio@fc06c000 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfc06c000 0x100>;
+ interrupts = <25 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioC_clk>;
+ };
+
+ pioD: gpio@fc068000 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfc068000 0x100>;
+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioD_clk>;
+ status = "disabled";
+ };
+
+ pioE: gpio@fc06d000 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfc06d000 0x100>;
+ interrupts = <26 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioE_clk>;
+ };
+
+ /* pinctrl pin settings */
+ adc0 {
+ pinctrl_adc0_adtrg: adc0_adtrg {
+ atmel,pins =
+ <AT91_PIOE 31 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* conflicts with USBA_VBUS */
+ };
+ pinctrl_adc0_ad0: adc0_ad0 {
+ atmel,pins =
+ <AT91_PIOC 27 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ pinctrl_adc0_ad1: adc0_ad1 {
+ atmel,pins =
+ <AT91_PIOC 28 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ pinctrl_adc0_ad2: adc0_ad2 {
+ atmel,pins =
+ <AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ pinctrl_adc0_ad3: adc0_ad3 {
+ atmel,pins =
+ <AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ pinctrl_adc0_ad4: adc0_ad4 {
+ atmel,pins =
+ <AT91_PIOC 31 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <AT91_PIOB 24 AT91_PERIPH_A AT91_PINCTRL_NONE>, /* conflicts with D14 and TDI */
+ <AT91_PIOB 25 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* conflicts with D15 and TDO */
+ };
+ };
+
+ i2c0 {
+ pinctrl_i2c0: i2c0-0 {
+ atmel,pins =
+ <AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_NONE
+ AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+ };
+ };
+
+ i2c1 {
+ pinctrl_i2c1: i2c1-0 {
+ atmel,pins =
+ <AT91_PIOE 29 AT91_PERIPH_C AT91_PINCTRL_NONE /* TWD1, conflicts with UART0 RX and DIBP */
+ AT91_PIOE 30 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* TWCK1, conflicts with UART0 TX and DIBN */
+ };
+ };
+
+ i2c2 {
+ pinctrl_i2c2: i2c2-0 {
+ atmel,pins =
+ <AT91_PIOB 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* TWD2, conflicts with RD0 and PWML1 */
+ AT91_PIOB 30 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* TWCK2, conflicts with RF0 */
+ };
+ };
+
+ isi {
+ pinctrl_isi_data_0_7: isi-0-data-0-7 {
+ atmel,pins =
+ <AT91_PIOC 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* ISI_D0 */
+ AT91_PIOC 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* ISI_D1 */
+ AT91_PIOC 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* ISI_D2 */
+ AT91_PIOC 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* ISI_D3 */
+ AT91_PIOC 23 AT91_PERIPH_A AT91_PINCTRL_NONE /* ISI_D4 */
+ AT91_PIOC 24 AT91_PERIPH_A AT91_PINCTRL_NONE /* ISI_D5 */
+ AT91_PIOC 25 AT91_PERIPH_A AT91_PINCTRL_NONE /* ISI_D6 */
+ AT91_PIOC 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* ISI_D7 */
+ AT91_PIOB 1 AT91_PERIPH_C AT91_PINCTRL_NONE /* ISI_PCK, conflict with G0_RXCK */
+ AT91_PIOB 3 AT91_PERIPH_C AT91_PINCTRL_NONE /* ISI_VSYNC */
+ AT91_PIOB 4 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* ISI_HSYNC */
+ };
+ pinctrl_isi_data_8_9: isi-0-data-8-9 {
+ atmel,pins =
+ <AT91_PIOC 0 AT91_PERIPH_C AT91_PINCTRL_NONE /* ISI_D8, conflicts with SPI0_MISO, PWMH2 */
+ AT91_PIOC 1 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* ISI_D9, conflicts with SPI0_MOSI, PWML2 */
+ };
+ pinctrl_isi_data_10_11: isi-0-data-10-11 {
+ atmel,pins =
+ <AT91_PIOC 2 AT91_PERIPH_C AT91_PINCTRL_NONE /* ISI_D10, conflicts with SPI0_SPCK, PWMH3 */
+ AT91_PIOC 3 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* ISI_D11, conflicts with SPI0_NPCS0, PWML3 */
+ };
+ };
+
+ lcd {
+ pinctrl_lcd_base: lcd-base-0 {
+ atmel,pins =
+ <AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDVSYNC */
+ AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDHSYNC */
+ AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDDEN */
+ AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDPCK */
+ };
+ pinctrl_lcd_pwm: lcd-pwm-0 {
+ atmel,pins = <AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDPWM */
+ };
+ pinctrl_lcd_rgb444: lcd-rgb-0 {
+ atmel,pins =
+ <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */
+ AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */
+ AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */
+ AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */
+ AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */
+ AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */
+ AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */
+ AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */
+ AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */
+ AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */
+ AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD11 pin */
+ };
+ pinctrl_lcd_rgb565: lcd-rgb-1 {
+ atmel,pins =
+ <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */
+ AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */
+ AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */
+ AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */
+ AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */
+ AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */
+ AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */
+ AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */
+ AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */
+ AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */
+ AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */
+ AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */
+ AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */
+ AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */
+ AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD15 pin */
+ };
+ pinctrl_lcd_rgb666: lcd-rgb-2 {
+ atmel,pins =
+ <AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */
+ AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */
+ AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */
+ AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */
+ AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */
+ AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */
+ AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */
+ AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */
+ AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */
+ AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */
+ AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */
+ AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD18 pin */
+ AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD19 pin */
+ AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD20 pin */
+ AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD21 pin */
+ AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD22 pin */
+ AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD23 pin */
+ };
+ pinctrl_lcd_rgb777: lcd-rgb-3 {
+ atmel,pins =
+ /* LCDDAT0 conflicts with TMS */
+ <AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */
+ AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */
+ AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */
+ AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */
+ AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */
+ AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */
+ AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */
+ /* LCDDAT8 conflicts with TCK */
+ AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */
+ AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */
+ AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */
+ AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */
+ AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */
+ AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */
+ /* LCDDAT16 conflicts with NTRST */
+ AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD17 pin */
+ AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD18 pin */
+ AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD19 pin */
+ AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD20 pin */
+ AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD21 pin */
+ AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD22 pin */
+ AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD23 pin */
+ };
+ pinctrl_lcd_rgb888: lcd-rgb-4 {
+ atmel,pins =
+ <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */
+ AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */
+ AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */
+ AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */
+ AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */
+ AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */
+ AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */
+ AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */
+ AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */
+ AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */
+ AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */
+ AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */
+ AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */
+ AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */
+ AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */
+ AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD16 pin */
+ AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD17 pin */
+ AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD18 pin */
+ AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD19 pin */
+ AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD20 pin */
+ AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD21 pin */
+ AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD22 pin */
+ AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD23 pin */
+ };
+ };
+
+ macb0 {
+ pinctrl_macb0_rmii: macb0_rmii-0 {
+ atmel,pins =
+ <AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* G0_TX0 */
+ AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* G0_TX1 */
+ AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* G0_RX0 */
+ AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* G0_RX1 */
+ AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* G0_RXDV */
+ AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* G0_RXER */
+ AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* G0_TXEN */
+ AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* G0_TXCK */
+ AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* G0_MDC */
+ AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* G0_MDIO */
+ >;
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_clk_cmd_dat0: mmc0_clk_cmd_dat0 {
+ atmel,pins =
+ <AT91_PIOC 4 AT91_PERIPH_B AT91_PINCTRL_NONE /* MCI0_CK, conflict with PCK1(ISI_MCK) */
+ AT91_PIOC 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_CDB, conflict with NAND_D0 */
+ AT91_PIOC 6 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DB0, conflict with NAND_D1 */
+ >;
+ };
+ pinctrl_mmc0_dat1_3: mmc0_dat1_3 {
+ atmel,pins =
+ <AT91_PIOC 7 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DB1, conflict with NAND_D2 */
+ AT91_PIOC 8 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DB2, conflict with NAND_D3 */
+ AT91_PIOC 9 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DB3, conflict with NAND_D4 */
+ >;
+ };
+ };
+
+ mmc1 {
+ pinctrl_mmc1_clk_cmd_dat0: mmc1_clk_cmd_dat0 {
+ atmel,pins =
+ <AT91_PIOE 18 AT91_PERIPH_C AT91_PINCTRL_NONE /* MCI1_CK */
+ AT91_PIOE 19 AT91_PERIPH_C AT91_PINCTRL_PULL_UP /* MCI1_CDA */
+ AT91_PIOE 20 AT91_PERIPH_C AT91_PINCTRL_PULL_UP /* MCI1_DA0 */
+ >;
+ };
+ pinctrl_mmc1_dat1_3: mmc1_dat1_3 {
+ atmel,pins =
+ <AT91_PIOE 21 AT91_PERIPH_C AT91_PINCTRL_PULL_UP /* MCI1_DA1 */
+ AT91_PIOE 22 AT91_PERIPH_C AT91_PINCTRL_PULL_UP /* MCI1_DA2 */
+ AT91_PIOE 23 AT91_PERIPH_C AT91_PINCTRL_PULL_UP /* MCI1_DA3 */
+ >;
+ };
+ };
+
+ nand0 {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC13 periph A Read Enable */
+ AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC14 periph A Write Enable */
+
+ AT91_PIOC 17 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PC17 ALE */
+ AT91_PIOC 18 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PC18 CLE */
+
+ AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PC15 NCS3/Chip Enable */
+ AT91_PIOC 16 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PC16 NANDRDY */
+ AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC5 Data bit 0 */
+ AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC6 Data bit 1 */
+ AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC7 Data bit 2 */
+ AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC8 Data bit 3 */
+ AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC9 Data bit 4 */
+ AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC10 Data bit 5 */
+ AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC11 periph A Data bit 6 */
+ AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PC12 periph A Data bit 7 */
+ };
+ };
+
+ spi0 {
+ pinctrl_spi0: spi0-0 {
+ atmel,pins =
+ <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* SPI0_MISO */
+ AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* SPI0_MOSI */
+ AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* SPI0_SPCK */
+ >;
+ };
+ };
+
+ ssc0 {
+ pinctrl_ssc0_tx: ssc0_tx {
+ atmel,pins =
+ <AT91_PIOB 27 AT91_PERIPH_B AT91_PINCTRL_NONE /* TK0 */
+ AT91_PIOB 31 AT91_PERIPH_B AT91_PINCTRL_NONE /* TF0 */
+ AT91_PIOB 28 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* TD0 */
+ };
+
+ pinctrl_ssc0_rx: ssc0_rx {
+ atmel,pins =
+ <AT91_PIOB 26 AT91_PERIPH_B AT91_PINCTRL_NONE /* RK0 */
+ AT91_PIOB 30 AT91_PERIPH_B AT91_PINCTRL_NONE /* RF0 */
+ AT91_PIOB 29 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* RD0 */
+ };
+ };
+
+ ssc1 {
+ pinctrl_ssc1_tx: ssc1_tx {
+ atmel,pins =
+ <AT91_PIOC 19 AT91_PERIPH_B AT91_PINCTRL_NONE /* TK1 */
+ AT91_PIOC 20 AT91_PERIPH_B AT91_PINCTRL_NONE /* TF1 */
+ AT91_PIOC 21 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* TD1 */
+ };
+
+ pinctrl_ssc1_rx: ssc1_rx {
+ atmel,pins =
+ <AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE /* RK1 */
+ AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_NONE /* RF1 */
+ AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* RD1 */
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <AT91_PIOB 4 AT91_PERIPH_B AT91_PINCTRL_NONE /* RXD - conflicts with G0_CRS, ISI_HSYNC */
+ AT91_PIOB 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* TXD - conflicts with G0_COL, PCK2 */
+ >;
+ };
+ pinctrl_usart2_rts: usart2_rts-0 {
+ atmel,pins = <AT91_PIOB 11 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* conflicts with G0_RX3, PWMH1 */
+ };
+ pinctrl_usart2_cts: usart2_cts-0 {
+ atmel,pins = <AT91_PIOB 3 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* conflicts with G0_TXER, ISI_VSYNC */
+ };
+ };
+
+ usart3 {
+ pinctrl_usart3: usart3-0 {
+ atmel,pins =
+ <AT91_PIOE 16 AT91_PERIPH_B AT91_PINCTRL_NONE /* RXD */
+ AT91_PIOE 17 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* TXD */
+ >;
+ };
+ };
+
+ usart4 {
+ pinctrl_usart4: usart4-0 {
+ atmel,pins =
+ <AT91_PIOE 26 AT91_PERIPH_B AT91_PINCTRL_NONE /* RXD */
+ AT91_PIOE 27 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* TXD */
+ >;
+ };
+ pinctrl_usart4_rts: usart4_rts-0 {
+ atmel,pins = <AT91_PIOE 28 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* conflicts with NWAIT, A19 */
+ };
+ pinctrl_usart4_cts: usart4_cts-0 {
+ atmel,pins = <AT91_PIOE 0 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* conflicts with A0/NBS0, MCI0_CDB */
+ };
+ };
+ };
+
+ aic: interrupt-controller@fc06e000 {
+ #interrupt-cells = <3>;
+ compatible = "atmel,sama5d4-aic";
+ interrupt-controller;
+ reg = <0xfc06e000 0x200>;
+ atmel,external-irqs = <56>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/samsung_k3pe0e000b.dtsi b/arch/arm/boot/dts/samsung_k3pe0e000b.dtsi
new file mode 100644
index 000000000..9657a5cbc
--- /dev/null
+++ b/arch/arm/boot/dts/samsung_k3pe0e000b.dtsi
@@ -0,0 +1,67 @@
+/*
+ * Timings and Geometry for Samsung K3PE0E000B memory part
+ */
+
+/ {
+ samsung_K3PE0E000B: lpddr2 {
+ compatible = "Samsung,K3PE0E000B","jedec,lpddr2-s4";
+ density = <4096>;
+ io-width = <32>;
+
+ tRPab-min-tck = <3>;
+ tRCD-min-tck = <3>;
+ tWR-min-tck = <3>;
+ tRASmin-min-tck = <3>;
+ tRRD-min-tck = <2>;
+ tWTR-min-tck = <2>;
+ tXP-min-tck = <2>;
+ tRTP-min-tck = <2>;
+ tCKE-min-tck = <3>;
+ tCKESR-min-tck = <3>;
+ tFAW-min-tck = <8>;
+
+ timings_samsung_K3PE0E000B_533MHz: lpddr2-timings@0 {
+ compatible = "jedec,lpddr2-timings";
+ min-freq = <10000000>;
+ max-freq = <533333333>;
+ tRPab = <21000>;
+ tRCD = <18000>;
+ tWR = <15000>;
+ tRAS-min = <42000>;
+ tRRD = <10000>;
+ tWTR = <7500>;
+ tXP = <7500>;
+ tRTP = <7500>;
+ tCKESR = <15000>;
+ tDQSCK-max = <5500>;
+ tFAW = <50000>;
+ tZQCS = <90000>;
+ tZQCL = <360000>;
+ tZQinit = <1000000>;
+ tRAS-max-ns = <70000>;
+ tDQSCK-max-derated = <6000>;
+ };
+
+ timings_samsung_K3PE0E000B_266MHz: lpddr2-timings@1 {
+ compatible = "jedec,lpddr2-timings";
+ min-freq = <10000000>;
+ max-freq = <266666666>;
+ tRPab = <21000>;
+ tRCD = <18000>;
+ tWR = <15000>;
+ tRAS-min = <42000>;
+ tRRD = <10000>;
+ tWTR = <7500>;
+ tXP = <7500>;
+ tRTP = <7500>;
+ tCKESR = <15000>;
+ tDQSCK-max = <5500>;
+ tFAW = <50000>;
+ tZQCS = <90000>;
+ tZQCL = <360000>;
+ tZQinit = <1000000>;
+ tRAS-max-ns = <70000>;
+ tDQSCK-max-derated = <6000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sh73a0-kzm9g.dts b/arch/arm/boot/dts/sh73a0-kzm9g.dts
new file mode 100644
index 000000000..022ba505f
--- /dev/null
+++ b/arch/arm/boot/dts/sh73a0-kzm9g.dts
@@ -0,0 +1,400 @@
+/*
+ * Device Tree Source for the KZM-A9-GT board
+ *
+ * Copyright (C) 2012 Horms Solutions Ltd.
+ *
+ * Based on sh73a0-kzm9g.dts
+ * Copyright (C) 2012 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.
+ */
+
+/dts-v1/;
+#include "sh73a0.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ model = "KZM-A9-GT";
+ compatible = "renesas,kzm9g", "renesas,sh73a0";
+
+ aliases {
+ serial4 = &scifa4;
+ };
+
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vdd_dvfs>;
+ operating-points = <
+ /* kHz uV */
+ 1196000 1315000
+ 598000 1175000
+ 398667 1065000
+ >;
+ voltage-tolerance = <1>; /* 1% */
+ };
+ };
+
+ chosen {
+ bootargs = "console=tty0 console=ttySC4,115200 root=/dev/nfs ip=dhcp ignore_loglevel rw";
+ stdout-path = &scifa4;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x40000000 0x20000000>;
+ };
+
+ reg_1p8v: regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ reg_3p3v: regulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vmmc_sdhi0: regulator@2 {
+ compatible = "regulator-fixed";
+ regulator-name = "SDHI0 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pfc 15 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vmmc_sdhi2: regulator@3 {
+ compatible = "regulator-fixed";
+ regulator-name = "SDHI2 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pfc 14 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ led1 {
+ gpios = <&pfc 20 GPIO_ACTIVE_LOW>;
+ label = "LED1";
+ };
+ led2 {
+ gpios = <&pfc 21 GPIO_ACTIVE_LOW>;
+ label = "LED2";
+ };
+ led3 {
+ gpios = <&pfc 22 GPIO_ACTIVE_LOW>;
+ label = "LED3";
+ };
+ led4 {
+ gpios = <&pfc 23 GPIO_ACTIVE_LOW>;
+ label = "LED4";
+ };
+ };
+
+ keyboard {
+ compatible = "gpio-keys";
+
+ back-key {
+ gpios = <&pcf8575 8 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_BACK>;
+ label = "SW3";
+ };
+
+ right-key {
+ gpios = <&pcf8575 9 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RIGHT>;
+ label = "SW2-R";
+ };
+
+ left-key {
+ gpios = <&pcf8575 10 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_LEFT>;
+ label = "SW2-L";
+ };
+
+ enter-key {
+ gpios = <&pcf8575 11 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_ENTER>;
+ label = "SW2-P";
+ };
+
+ up-key {
+ gpios = <&pcf8575 12 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_UP>;
+ label = "SW2-U";
+ };
+
+ down-key {
+ gpios = <&pcf8575 13 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_DOWN>;
+ label = "SW2-D";
+ };
+
+ home-key {
+ gpios = <&pcf8575 14 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOME>;
+ label = "SW1";
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "left_j";
+ simple-audio-card,cpu {
+ sound-dai = <&sh_fsi2 0>;
+ };
+ simple-audio-card,codec {
+ sound-dai = <&ak4648>;
+ bitclock-master;
+ frame-master;
+ system-clock-frequency = <11289600>;
+ };
+ };
+};
+
+&bsc {
+ ethernet@10000000 {
+ compatible = "smsc,lan9220", "smsc,lan9115";
+ reg = <0x10000000 0x100>;
+ phy-mode = "mii";
+ interrupt-parent = <&irqpin0>;
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+ reg-io-width = <4>;
+ smsc,irq-push-pull;
+ smsc,save-mac-address;
+ vddvario-supply = <&reg_1p8v>;
+ vdd33a-supply = <&reg_3p3v>;
+ };
+};
+
+&cmt1 {
+ status = "okay";
+};
+
+&extal2_clk {
+ clock-frequency = <48000000>;
+};
+
+&i2c0 {
+ status = "okay";
+
+ compass@c {
+ compatible = "asahi-kasei,ak8975";
+ reg = <0x0c>;
+ interrupt-parent = <&irqpin3>;
+ interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
+ };
+
+ ak4648: codec@12 {
+ compatible = "asahi-kasei,ak4648";
+ reg = <0x12>;
+ #sound-dai-cells = <0>;
+ };
+
+ accelerometer@1d {
+ compatible = "adi,adxl34x";
+ reg = <0x1d>;
+ interrupt-parent = <&irqpin3>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH>,
+ <3 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ rtc@32 {
+ compatible = "ricoh,r2025sd";
+ reg = <0x32>;
+ };
+
+ as3711@40 {
+ compatible = "ams,as3711";
+ reg = <0x40>;
+
+ regulators {
+ vdd_dvfs: sd1 {
+ regulator-name = "1.315V CPU";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ sd2 {
+ regulator-name = "1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ sd4 {
+ regulator-name = "1.215V";
+ regulator-min-microvolt = <1215000>;
+ regulator-max-microvolt = <1235000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ ldo2 {
+ regulator-name = "2.8V CPU";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ ldo3 {
+ regulator-name = "3.0V CPU";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ ldo4 {
+ regulator-name = "2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ ldo5 {
+ regulator-name = "2.8V #2";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ ldo7 {
+ regulator-name = "1.15V CPU";
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ ldo8 {
+ regulator-name = "1.15V CPU #2";
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+};
+
+&i2c1 {
+ status = "okay";
+
+ touchscreen@55 {
+ compatible = "sitronix,st1232";
+ reg = <0x55>;
+ interrupt-parent = <&irqpin1>;
+ interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+ };
+};
+
+&i2c3 {
+ pinctrl-0 = <&i2c3_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ pcf8575: gpio@20 {
+ compatible = "nxp,pcf8575";
+ reg = <0x20>;
+ interrupt-parent = <&irqpin2>;
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+};
+
+&mmcif {
+ pinctrl-0 = <&mmcif_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <8>;
+ vmmc-supply = <&reg_1p8v>;
+ status = "okay";
+};
+
+&pfc {
+ i2c3_pins: i2c3 {
+ renesas,groups = "i2c3_1";
+ renesas,function = "i2c3";
+ };
+
+ mmcif_pins: mmc {
+ mux {
+ renesas,groups = "mmc0_data8_0", "mmc0_ctrl_0";
+ renesas,function = "mmc0";
+ };
+ cfg {
+ renesas,groups = "mmc0_data8_0";
+ renesas,pins = "PORT279";
+ bias-pull-up;
+ };
+ };
+
+ scifa4_pins: serial4 {
+ renesas,groups = "scifa4_data", "scifa4_ctrl";
+ renesas,function = "scifa4";
+ };
+
+ sdhi0_pins: sd0 {
+ renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd", "sdhi0_wp";
+ renesas,function = "sdhi0";
+ };
+
+ sdhi2_pins: sd2 {
+ renesas,groups = "sdhi2_data4", "sdhi2_ctrl";
+ renesas,function = "sdhi2";
+ };
+
+ fsia_pins: sounda {
+ renesas,groups = "fsia_mclk_in", "fsia_sclk_in",
+ "fsia_data_in", "fsia_data_out";
+ renesas,function = "fsia";
+ };
+};
+
+&scifa4 {
+ pinctrl-0 = <&scifa4_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&vmmc_sdhi0>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&sdhi2 {
+ pinctrl-0 = <&sdhi2_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&vmmc_sdhi2>;
+ bus-width = <4>;
+ broken-cd;
+ status = "okay";
+};
+
+&sh_fsi2 {
+ pinctrl-0 = <&fsia_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi
new file mode 100644
index 000000000..45b539ce4
--- /dev/null
+++ b/arch/arm/boot/dts/sh73a0.dtsi
@@ -0,0 +1,902 @@
+/*
+ * Device Tree Source for the SH73A0 SoC
+ *
+ * Copyright (C) 2012 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/ "skeleton.dtsi"
+
+#include <dt-bindings/clock/sh73a0-clock.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "renesas,sh73a0";
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ clock-frequency = <1196000000>;
+ power-domains = <&pd_a2sl>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ clock-frequency = <1196000000>;
+ power-domains = <&pd_a2sl>;
+ };
+ };
+
+ timer@f0000600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xf0000600 0x20>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+ clocks = <&twd_clk>;
+ };
+
+ gic: interrupt-controller@f0001000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0xf0001000 0x1000>,
+ <0xf0000100 0x100>;
+ };
+
+ sbsc2: memory-controller@fb400000 {
+ compatible = "renesas,sbsc-sh73a0";
+ reg = <0xfb400000 0x400>;
+ interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>,
+ <0 38 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "sec", "temp";
+ power-domains = <&pd_a4bc1>;
+ };
+
+ sbsc1: memory-controller@fe400000 {
+ compatible = "renesas,sbsc-sh73a0";
+ reg = <0xfe400000 0x400>;
+ interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>,
+ <0 36 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "sec", "temp";
+ power-domains = <&pd_a4bc0>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>,
+ <0 56 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ cmt1: timer@e6138000 {
+ compatible = "renesas,cmt-48-sh73a0", "renesas,cmt-48";
+ reg = <0xe6138000 0x200>;
+ interrupts = <0 65 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks SH73A0_CLK_CMT1>;
+ clock-names = "fck";
+ power-domains = <&pd_c5>;
+
+ renesas,channels-mask = <0x3f>;
+
+ status = "disabled";
+ };
+
+ irqpin0: irqpin@e6900000 {
+ compatible = "renesas,intc-irqpin-sh73a0", "renesas,intc-irqpin";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0xe6900000 4>,
+ <0xe6900010 4>,
+ <0xe6900020 1>,
+ <0xe6900040 1>,
+ <0xe6900060 1>;
+ interrupts = <0 1 IRQ_TYPE_LEVEL_HIGH
+ 0 2 IRQ_TYPE_LEVEL_HIGH
+ 0 3 IRQ_TYPE_LEVEL_HIGH
+ 0 4 IRQ_TYPE_LEVEL_HIGH
+ 0 5 IRQ_TYPE_LEVEL_HIGH
+ 0 6 IRQ_TYPE_LEVEL_HIGH
+ 0 7 IRQ_TYPE_LEVEL_HIGH
+ 0 8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp5_clks SH73A0_CLK_INTCA0>;
+ power-domains = <&pd_a4s>;
+ control-parent;
+ };
+
+ irqpin1: irqpin@e6900004 {
+ compatible = "renesas,intc-irqpin-sh73a0", "renesas,intc-irqpin";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0xe6900004 4>,
+ <0xe6900014 4>,
+ <0xe6900024 1>,
+ <0xe6900044 1>,
+ <0xe6900064 1>;
+ interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH
+ 0 10 IRQ_TYPE_LEVEL_HIGH
+ 0 11 IRQ_TYPE_LEVEL_HIGH
+ 0 12 IRQ_TYPE_LEVEL_HIGH
+ 0 13 IRQ_TYPE_LEVEL_HIGH
+ 0 14 IRQ_TYPE_LEVEL_HIGH
+ 0 15 IRQ_TYPE_LEVEL_HIGH
+ 0 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp5_clks SH73A0_CLK_INTCA0>;
+ power-domains = <&pd_a4s>;
+ control-parent;
+ };
+
+ irqpin2: irqpin@e6900008 {
+ compatible = "renesas,intc-irqpin-sh73a0", "renesas,intc-irqpin";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0xe6900008 4>,
+ <0xe6900018 4>,
+ <0xe6900028 1>,
+ <0xe6900048 1>,
+ <0xe6900068 1>;
+ interrupts = <0 17 IRQ_TYPE_LEVEL_HIGH
+ 0 18 IRQ_TYPE_LEVEL_HIGH
+ 0 19 IRQ_TYPE_LEVEL_HIGH
+ 0 20 IRQ_TYPE_LEVEL_HIGH
+ 0 21 IRQ_TYPE_LEVEL_HIGH
+ 0 22 IRQ_TYPE_LEVEL_HIGH
+ 0 23 IRQ_TYPE_LEVEL_HIGH
+ 0 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp5_clks SH73A0_CLK_INTCA0>;
+ power-domains = <&pd_a4s>;
+ control-parent;
+ };
+
+ irqpin3: irqpin@e690000c {
+ compatible = "renesas,intc-irqpin-sh73a0", "renesas,intc-irqpin";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0xe690000c 4>,
+ <0xe690001c 4>,
+ <0xe690002c 1>,
+ <0xe690004c 1>,
+ <0xe690006c 1>;
+ interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH
+ 0 26 IRQ_TYPE_LEVEL_HIGH
+ 0 27 IRQ_TYPE_LEVEL_HIGH
+ 0 28 IRQ_TYPE_LEVEL_HIGH
+ 0 29 IRQ_TYPE_LEVEL_HIGH
+ 0 30 IRQ_TYPE_LEVEL_HIGH
+ 0 31 IRQ_TYPE_LEVEL_HIGH
+ 0 32 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp5_clks SH73A0_CLK_INTCA0>;
+ power-domains = <&pd_a4s>;
+ control-parent;
+ };
+
+ i2c0: i2c@e6820000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic";
+ reg = <0xe6820000 0x425>;
+ interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH
+ 0 168 IRQ_TYPE_LEVEL_HIGH
+ 0 169 IRQ_TYPE_LEVEL_HIGH
+ 0 170 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks SH73A0_CLK_IIC0>;
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@e6822000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic";
+ reg = <0xe6822000 0x425>;
+ interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH
+ 0 52 IRQ_TYPE_LEVEL_HIGH
+ 0 53 IRQ_TYPE_LEVEL_HIGH
+ 0 54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks SH73A0_CLK_IIC1>;
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@e6824000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic";
+ reg = <0xe6824000 0x425>;
+ interrupts = <0 171 IRQ_TYPE_LEVEL_HIGH
+ 0 172 IRQ_TYPE_LEVEL_HIGH
+ 0 173 IRQ_TYPE_LEVEL_HIGH
+ 0 174 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks SH73A0_CLK_IIC2>;
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@e6826000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic";
+ reg = <0xe6826000 0x425>;
+ interrupts = <0 183 IRQ_TYPE_LEVEL_HIGH
+ 0 184 IRQ_TYPE_LEVEL_HIGH
+ 0 185 IRQ_TYPE_LEVEL_HIGH
+ 0 186 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp4_clks SH73A0_CLK_IIC3>;
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@e6828000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic";
+ reg = <0xe6828000 0x425>;
+ interrupts = <0 187 IRQ_TYPE_LEVEL_HIGH
+ 0 188 IRQ_TYPE_LEVEL_HIGH
+ 0 189 IRQ_TYPE_LEVEL_HIGH
+ 0 190 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp4_clks SH73A0_CLK_IIC4>;
+ power-domains = <&pd_c5>;
+ status = "disabled";
+ };
+
+ mmcif: mmc@e6bd0000 {
+ compatible = "renesas,sh-mmcif";
+ reg = <0xe6bd0000 0x100>;
+ interrupts = <0 140 IRQ_TYPE_LEVEL_HIGH
+ 0 141 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks SH73A0_CLK_MMCIF0>;
+ power-domains = <&pd_a3sp>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ sdhi0: sd@ee100000 {
+ compatible = "renesas,sdhi-sh73a0";
+ reg = <0xee100000 0x100>;
+ interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH
+ 0 84 IRQ_TYPE_LEVEL_HIGH
+ 0 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks SH73A0_CLK_SDHI0>;
+ power-domains = <&pd_a3sp>;
+ cap-sd-highspeed;
+ status = "disabled";
+ };
+
+ /* SDHI1 and SDHI2 have no CD pins, no need for CD IRQ */
+ sdhi1: sd@ee120000 {
+ compatible = "renesas,sdhi-sh73a0";
+ reg = <0xee120000 0x100>;
+ interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH
+ 0 89 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks SH73A0_CLK_SDHI1>;
+ power-domains = <&pd_a3sp>;
+ toshiba,mmc-wrprotect-disable;
+ cap-sd-highspeed;
+ status = "disabled";
+ };
+
+ sdhi2: sd@ee140000 {
+ compatible = "renesas,sdhi-sh73a0";
+ reg = <0xee140000 0x100>;
+ interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH
+ 0 105 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks SH73A0_CLK_SDHI2>;
+ power-domains = <&pd_a3sp>;
+ toshiba,mmc-wrprotect-disable;
+ cap-sd-highspeed;
+ status = "disabled";
+ };
+
+ scifa0: serial@e6c40000 {
+ compatible = "renesas,scifa-sh73a0", "renesas,scifa";
+ reg = <0xe6c40000 0x100>;
+ interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_SCIFA0>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa1: serial@e6c50000 {
+ compatible = "renesas,scifa-sh73a0", "renesas,scifa";
+ reg = <0xe6c50000 0x100>;
+ interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_SCIFA1>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa2: serial@e6c60000 {
+ compatible = "renesas,scifa-sh73a0", "renesas,scifa";
+ reg = <0xe6c60000 0x100>;
+ interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_SCIFA2>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa3: serial@e6c70000 {
+ compatible = "renesas,scifa-sh73a0", "renesas,scifa";
+ reg = <0xe6c70000 0x100>;
+ interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_SCIFA3>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa4: serial@e6c80000 {
+ compatible = "renesas,scifa-sh73a0", "renesas,scifa";
+ reg = <0xe6c80000 0x100>;
+ interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_SCIFA4>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa5: serial@e6cb0000 {
+ compatible = "renesas,scifa-sh73a0", "renesas,scifa";
+ reg = <0xe6cb0000 0x100>;
+ interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_SCIFA5>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa6: serial@e6cc0000 {
+ compatible = "renesas,scifa-sh73a0", "renesas,scifa";
+ reg = <0xe6cc0000 0x100>;
+ interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks SH73A0_CLK_SCIFA6>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifa7: serial@e6cd0000 {
+ compatible = "renesas,scifa-sh73a0", "renesas,scifa";
+ reg = <0xe6cd0000 0x100>;
+ interrupts = <0 143 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_SCIFA7>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ scifb8: serial@e6c30000 {
+ compatible = "renesas,scifb-sh73a0", "renesas,scifb";
+ reg = <0xe6c30000 0x100>;
+ interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_SCIFB>;
+ clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
+ status = "disabled";
+ };
+
+ pfc: pfc@e6050000 {
+ compatible = "renesas,pfc-sh73a0";
+ reg = <0xe6050000 0x8000>,
+ <0xe605801c 0x1c>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts-extended =
+ <&irqpin0 0 0>, <&irqpin0 1 0>, <&irqpin0 2 0>, <&irqpin0 3 0>,
+ <&irqpin0 4 0>, <&irqpin0 5 0>, <&irqpin0 6 0>, <&irqpin0 7 0>,
+ <&irqpin1 0 0>, <&irqpin1 1 0>, <&irqpin1 2 0>, <&irqpin1 3 0>,
+ <&irqpin1 4 0>, <&irqpin1 5 0>, <&irqpin1 6 0>, <&irqpin1 7 0>,
+ <&irqpin2 0 0>, <&irqpin2 1 0>, <&irqpin2 2 0>, <&irqpin2 3 0>,
+ <&irqpin2 4 0>, <&irqpin2 5 0>, <&irqpin2 6 0>, <&irqpin2 7 0>,
+ <&irqpin3 0 0>, <&irqpin3 1 0>, <&irqpin3 2 0>, <&irqpin3 3 0>,
+ <&irqpin3 4 0>, <&irqpin3 5 0>, <&irqpin3 6 0>, <&irqpin3 7 0>;
+ power-domains = <&pd_c5>;
+ };
+
+ sysc: system-controller@e6180000 {
+ compatible = "renesas,sysc-sh73a0", "renesas,sysc-rmobile";
+ reg = <0xe6180000 0x8000>, <0xe6188000 0x8000>;
+
+ pm-domains {
+ pd_c5: c5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_c4: c4@0 {
+ reg = <0>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_d4: d4@1 {
+ reg = <1>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a4bc0: a4bc0@4 {
+ reg = <4>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a4bc1: a4bc1@5 {
+ reg = <5>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a4lc0: a4lc0@6 {
+ reg = <6>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a4lc1: a4lc1@7 {
+ reg = <7>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a4mp: a4mp@8 {
+ reg = <8>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a3mp: a3mp@9 {
+ reg = <9>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a3vc: a3vc@10 {
+ reg = <10>;
+ #power-domain-cells = <0>;
+ };
+ };
+
+ pd_a4rm: a4rm@12 {
+ reg = <12>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a3r: a3r@13 {
+ reg = <13>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a2rv: a2rv@14 {
+ reg = <14>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+
+ pd_a4s: a4s@16 {
+ reg = <16>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a3sp: a3sp@17 {
+ reg = <17>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a3sg: a3sg@18 {
+ reg = <18>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a3sm: a3sm@19 {
+ reg = <19>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a2sl: a2sl@20 {
+ reg = <20>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+ };
+ };
+ };
+
+ sh_fsi2: sound@ec230000 {
+ #sound-dai-cells = <1>;
+ compatible = "renesas,fsi2-sh73a0", "renesas,sh_fsi2";
+ reg = <0xec230000 0x400>;
+ interrupts = <0 146 0x4>;
+ power-domains = <&pd_a4mp>;
+ status = "disabled";
+ };
+
+ bsc: bus@fec10000 {
+ compatible = "renesas,bsc-sh73a0", "renesas,bsc",
+ "simple-pm-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0x20000000>;
+ reg = <0xfec10000 0x400>;
+ interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&zb_clk>;
+ power-domains = <&pd_a4s>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /* External root clocks */
+ extalr_clk: extalr_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "extalr";
+ };
+ extal1_clk: extal1_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+ clock-output-names = "extal1";
+ };
+ extal2_clk: extal2_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-output-names = "extal2";
+ };
+ extcki_clk: extcki_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-output-names = "extcki";
+ };
+ fsiack_clk: fsiack_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "fsiack";
+ };
+ fsibck_clk: fsibck_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "fsibck";
+ };
+
+ /* Special CPG clocks */
+ cpg_clocks: cpg_clocks@e6150000 {
+ compatible = "renesas,sh73a0-cpg-clocks";
+ reg = <0xe6150000 0x10000>;
+ clocks = <&extal1_clk>, <&extal2_clk>;
+ #clock-cells = <1>;
+ clock-output-names = "main", "pll0", "pll1", "pll2",
+ "pll3", "dsi0phy", "dsi1phy",
+ "zg", "m3", "b", "m1", "m2",
+ "z", "zx", "hp";
+ };
+
+ /* Variable factor clocks (DIV6) */
+ vclk1_clk: vclk1_clk@e6150008 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150008 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks SH73A0_CLK_PLL2>,
+ <&extcki_clk>, <&extal2_clk>, <&main_div2_clk>,
+ <&extalr_clk>, <&cpg_clocks SH73A0_CLK_MAIN>,
+ <0>;
+ #clock-cells = <0>;
+ clock-output-names = "vclk1";
+ };
+ vclk2_clk: vclk2_clk@e615000c {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe615000c 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks SH73A0_CLK_PLL2>,
+ <&extcki_clk>, <&extal2_clk>, <&main_div2_clk>,
+ <&extalr_clk>, <&cpg_clocks SH73A0_CLK_MAIN>,
+ <0>;
+ #clock-cells = <0>;
+ clock-output-names = "vclk2";
+ };
+ vclk3_clk: vclk3_clk@e615001c {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe615001c 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks SH73A0_CLK_PLL2>,
+ <&extcki_clk>, <&extal2_clk>, <&main_div2_clk>,
+ <&extalr_clk>, <&cpg_clocks SH73A0_CLK_MAIN>,
+ <0>;
+ #clock-cells = <0>;
+ clock-output-names = "vclk3";
+ };
+ zb_clk: zb_clk@e6150010 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150010 4>;
+ clocks = <&pll1_div2_clk>, <0>,
+ <&cpg_clocks SH73A0_CLK_PLL2>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "zb";
+ };
+ flctl_clk: flctl_clk@e6150014 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150014 4>;
+ clocks = <&pll1_div2_clk>, <0>,
+ <&cpg_clocks SH73A0_CLK_PLL2>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "flctlck";
+ };
+ sdhi0_clk: sdhi0_clk@e6150074 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150074 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks SH73A0_CLK_PLL2>,
+ <&pll1_div13_clk>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "sdhi0ck";
+ };
+ sdhi1_clk: sdhi1_clk@e6150078 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150078 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks SH73A0_CLK_PLL2>,
+ <&pll1_div13_clk>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "sdhi1ck";
+ };
+ sdhi2_clk: sdhi2_clk@e615007c {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe615007c 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks SH73A0_CLK_PLL2>,
+ <&pll1_div13_clk>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "sdhi2ck";
+ };
+ fsia_clk: fsia_clk@e6150018 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150018 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks SH73A0_CLK_PLL2>,
+ <&fsiack_clk>, <&fsiack_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "fsia";
+ };
+ fsib_clk: fsib_clk@e6150090 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150090 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks SH73A0_CLK_PLL2>,
+ <&fsibck_clk>, <&fsibck_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "fsib";
+ };
+ sub_clk: sub_clk@e6150080 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150080 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks SH73A0_CLK_PLL2>,
+ <&extal2_clk>, <&extal2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sub";
+ };
+ spua_clk: spua_clk@e6150084 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150084 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks SH73A0_CLK_PLL2>,
+ <&extal2_clk>, <&extal2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "spua";
+ };
+ spuv_clk: spuv_clk@e6150094 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150094 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks SH73A0_CLK_PLL2>,
+ <&extal2_clk>, <&extal2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "spuv";
+ };
+ msu_clk: msu_clk@e6150088 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150088 4>;
+ clocks = <&pll1_div2_clk>, <0>,
+ <&cpg_clocks SH73A0_CLK_PLL2>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "msu";
+ };
+ hsi_clk: hsi_clk@e615008c {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe615008c 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks SH73A0_CLK_PLL2>,
+ <&pll1_div7_clk>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "hsi";
+ };
+ mfg1_clk: mfg1_clk@e6150098 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150098 4>;
+ clocks = <&pll1_div2_clk>, <0>,
+ <&cpg_clocks SH73A0_CLK_PLL2>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "mfg1";
+ };
+ mfg2_clk: mfg2_clk@e615009c {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe615009c 4>;
+ clocks = <&pll1_div2_clk>, <0>,
+ <&cpg_clocks SH73A0_CLK_PLL2>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "mfg2";
+ };
+ dsit_clk: dsit_clk@e6150060 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150060 4>;
+ clocks = <&pll1_div2_clk>, <0>,
+ <&cpg_clocks SH73A0_CLK_PLL2>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "dsit";
+ };
+ dsi0p_clk: dsi0p_clk@e6150064 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150064 4>;
+ clocks = <&pll1_div2_clk>, <&cpg_clocks SH73A0_CLK_PLL2>,
+ <&cpg_clocks SH73A0_CLK_MAIN>, <&extal2_clk>,
+ <&extcki_clk>, <0>, <0>, <0>;
+ #clock-cells = <0>;
+ clock-output-names = "dsi0pck";
+ };
+
+ /* Fixed factor clocks */
+ main_div2_clk: main_div2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks SH73A0_CLK_MAIN>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "main_div2";
+ };
+ pll1_div2_clk: pll1_div2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks SH73A0_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "pll1_div2";
+ };
+ pll1_div7_clk: pll1_div7_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks SH73A0_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <7>;
+ clock-mult = <1>;
+ clock-output-names = "pll1_div7";
+ };
+ pll1_div13_clk: pll1_div13_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks SH73A0_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <13>;
+ clock-mult = <1>;
+ clock-output-names = "pll1_div13";
+ };
+ twd_clk: twd_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks SH73A0_CLK_Z>;
+ #clock-cells = <0>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clock-output-names = "twd";
+ };
+
+ /* Gate clocks */
+ mstp0_clks: mstp0_clks@e6150130 {
+ compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xe6150130 4>, <0xe6150030 4>;
+ clocks = <&cpg_clocks SH73A0_CLK_HP>;
+ #clock-cells = <1>;
+ clock-indices = <
+ SH73A0_CLK_IIC2
+ >;
+ clock-output-names =
+ "iic2";
+ };
+ mstp1_clks: mstp1_clks@e6150134 {
+ compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xe6150134 4>, <0xe6150038 4>;
+ clocks = <&cpg_clocks SH73A0_CLK_B>,
+ <&cpg_clocks SH73A0_CLK_B>,
+ <&cpg_clocks SH73A0_CLK_B>,
+ <&cpg_clocks SH73A0_CLK_B>,
+ <&sub_clk>, <&cpg_clocks SH73A0_CLK_B>,
+ <&cpg_clocks SH73A0_CLK_HP>,
+ <&cpg_clocks SH73A0_CLK_ZG>,
+ <&cpg_clocks SH73A0_CLK_B>;
+ #clock-cells = <1>;
+ clock-indices = <
+ SH73A0_CLK_CEU1 SH73A0_CLK_CSI2_RX1
+ SH73A0_CLK_CEU0 SH73A0_CLK_CSI2_RX0
+ SH73A0_CLK_TMU0 SH73A0_CLK_DSITX0
+ SH73A0_CLK_IIC0 SH73A0_CLK_SGX
+ SH73A0_CLK_LCDC0
+ >;
+ clock-output-names =
+ "ceu1", "csi2_rx1", "ceu0", "csi2_rx0",
+ "tmu0", "dsitx0", "iic0", "sgx", "lcdc0";
+ };
+ mstp2_clks: mstp2_clks@e6150138 {
+ compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xe6150138 4>, <0xe6150040 4>;
+ clocks = <&sub_clk>, <&cpg_clocks SH73A0_CLK_HP>,
+ <&cpg_clocks SH73A0_CLK_HP>, <&sub_clk>,
+ <&sub_clk>, <&sub_clk>, <&sub_clk>, <&sub_clk>,
+ <&sub_clk>, <&sub_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ SH73A0_CLK_SCIFA7 SH73A0_CLK_SY_DMAC
+ SH73A0_CLK_MP_DMAC SH73A0_CLK_SCIFA5
+ SH73A0_CLK_SCIFB SH73A0_CLK_SCIFA0
+ SH73A0_CLK_SCIFA1 SH73A0_CLK_SCIFA2
+ SH73A0_CLK_SCIFA3 SH73A0_CLK_SCIFA4
+ >;
+ clock-output-names =
+ "scifa7", "sy_dmac", "mp_dmac", "scifa5",
+ "scifb", "scifa0", "scifa1", "scifa2",
+ "scifa3", "scifa4";
+ };
+ mstp3_clks: mstp3_clks@e615013c {
+ compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xe615013c 4>, <0xe6150048 4>;
+ clocks = <&sub_clk>, <&extalr_clk>,
+ <&cpg_clocks SH73A0_CLK_HP>, <&sub_clk>,
+ <&cpg_clocks SH73A0_CLK_HP>,
+ <&cpg_clocks SH73A0_CLK_HP>, <&flctl_clk>,
+ <&sdhi0_clk>, <&sdhi1_clk>,
+ <&cpg_clocks SH73A0_CLK_HP>, <&sdhi2_clk>,
+ <&main_div2_clk>, <&main_div2_clk>,
+ <&main_div2_clk>, <&main_div2_clk>,
+ <&main_div2_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ SH73A0_CLK_SCIFA6 SH73A0_CLK_CMT1
+ SH73A0_CLK_FSI SH73A0_CLK_IRDA
+ SH73A0_CLK_IIC1 SH73A0_CLK_USB SH73A0_CLK_FLCTL
+ SH73A0_CLK_SDHI0 SH73A0_CLK_SDHI1
+ SH73A0_CLK_MMCIF0 SH73A0_CLK_SDHI2
+ SH73A0_CLK_TPU0 SH73A0_CLK_TPU1
+ SH73A0_CLK_TPU2 SH73A0_CLK_TPU3
+ SH73A0_CLK_TPU4
+ >;
+ clock-output-names =
+ "scifa6", "cmt1", "fsi", "irda", "iic1",
+ "usb", "flctl", "sdhi0", "sdhi1", "mmcif0", "sdhi2",
+ "tpu0", "tpu1", "tpu2", "tpu3", "tpu4";
+ };
+ mstp4_clks: mstp4_clks@e6150140 {
+ compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xe6150140 4>, <0xe615004c 4>;
+ clocks = <&cpg_clocks SH73A0_CLK_HP>,
+ <&cpg_clocks SH73A0_CLK_HP>, <&extalr_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ SH73A0_CLK_IIC3 SH73A0_CLK_IIC4
+ SH73A0_CLK_KEYSC
+ >;
+ clock-output-names =
+ "iic3", "iic4", "keysc";
+ };
+ mstp5_clks: mstp5_clks@e6150144 {
+ compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xe6150144 4>, <0xe615003c 4>;
+ clocks = <&cpg_clocks SH73A0_CLK_HP>;
+ #clock-cells = <1>;
+ clock-indices = <
+ SH73A0_CLK_INTCA0
+ >;
+ clock-output-names =
+ "intca0";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/skeleton.dtsi b/arch/arm/boot/dts/skeleton.dtsi
new file mode 100644
index 000000000..b41d241de
--- /dev/null
+++ b/arch/arm/boot/dts/skeleton.dtsi
@@ -0,0 +1,13 @@
+/*
+ * Skeleton device tree; the bare minimum needed to boot; just include and
+ * add a compatible value. The bootloader will typically populate the memory
+ * node.
+ */
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ chosen { };
+ aliases { };
+ memory { device_type = "memory"; reg = <0 0>; };
+};
diff --git a/arch/arm/boot/dts/skeleton64.dtsi b/arch/arm/boot/dts/skeleton64.dtsi
new file mode 100644
index 000000000..b5d7f36f3
--- /dev/null
+++ b/arch/arm/boot/dts/skeleton64.dtsi
@@ -0,0 +1,13 @@
+/*
+ * Skeleton device tree in the 64 bits version; the bare minimum
+ * needed to boot; just include and add a compatible value. The
+ * bootloader will typically populate the memory node.
+ */
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ chosen { };
+ aliases { };
+ memory { device_type = "memory"; reg = <0 0 0 0>; };
+};
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
new file mode 100644
index 000000000..d9176e606
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga.dtsi
@@ -0,0 +1,788 @@
+/*
+ * Copyright (C) 2012 Altera <www.altera.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/reset/altr,rst-mgr.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &gmac0;
+ ethernet1 = &gmac1;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ timer0 = &timer0;
+ timer1 = &timer1;
+ timer2 = &timer2;
+ timer3 = &timer3;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ };
+ cpu@1 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ intc: intc@fffed000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0xfffed000 0x1000>,
+ <0xfffec100 0x100>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ device_type = "soc";
+ interrupt-parent = <&intc>;
+ ranges;
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pdma: pdma@ffe01000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0xffe01000 0x1000>;
+ interrupts = <0 104 4>,
+ <0 105 4>,
+ <0 106 4>,
+ <0 107 4>,
+ <0 108 4>,
+ <0 109 4>,
+ <0 110 4>,
+ <0 111 4>;
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ clocks = <&l4_main_clk>;
+ clock-names = "apb_pclk";
+ };
+ };
+
+ can0: can@ffc00000 {
+ compatible = "bosch,d_can";
+ reg = <0xffc00000 0x1000>;
+ interrupts = <0 131 4>, <0 132 4>, <0 133 4>, <0 134 4>;
+ clocks = <&can0_clk>;
+ status = "disabled";
+ };
+
+ can1: can@ffc01000 {
+ compatible = "bosch,d_can";
+ reg = <0xffc01000 0x1000>;
+ interrupts = <0 135 4>, <0 136 4>, <0 137 4>, <0 138 4>;
+ clocks = <&can1_clk>;
+ status = "disabled";
+ };
+
+ clkmgr@ffd04000 {
+ compatible = "altr,clk-mgr";
+ reg = <0xffd04000 0x1000>;
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ osc1: osc1 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ };
+
+ osc2: osc2 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ };
+
+ f2s_periph_ref_clk: f2s_periph_ref_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ };
+
+ f2s_sdram_ref_clk: f2s_sdram_ref_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ };
+
+ main_pll: main_pll {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-pll-clock";
+ clocks = <&osc1>;
+ reg = <0x40>;
+
+ mpuclk: mpuclk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&main_pll>;
+ div-reg = <0xe0 0 9>;
+ reg = <0x48>;
+ };
+
+ mainclk: mainclk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&main_pll>;
+ div-reg = <0xe4 0 9>;
+ reg = <0x4C>;
+ };
+
+ dbg_base_clk: dbg_base_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&main_pll>;
+ div-reg = <0xe8 0 9>;
+ reg = <0x50>;
+ };
+
+ main_qspi_clk: main_qspi_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&main_pll>;
+ reg = <0x54>;
+ };
+
+ main_nand_sdmmc_clk: main_nand_sdmmc_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&main_pll>;
+ reg = <0x58>;
+ };
+
+ cfg_h2f_usr0_clk: cfg_h2f_usr0_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&main_pll>;
+ reg = <0x5C>;
+ };
+ };
+
+ periph_pll: periph_pll {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-pll-clock";
+ clocks = <&osc1>, <&osc2>, <&f2s_periph_ref_clk>;
+ reg = <0x80>;
+
+ emac0_clk: emac0_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&periph_pll>;
+ reg = <0x88>;
+ };
+
+ emac1_clk: emac1_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&periph_pll>;
+ reg = <0x8C>;
+ };
+
+ per_qspi_clk: per_qsi_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&periph_pll>;
+ reg = <0x90>;
+ };
+
+ per_nand_mmc_clk: per_nand_mmc_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&periph_pll>;
+ reg = <0x94>;
+ };
+
+ per_base_clk: per_base_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&periph_pll>;
+ reg = <0x98>;
+ };
+
+ h2f_usr1_clk: h2f_usr1_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&periph_pll>;
+ reg = <0x9C>;
+ };
+ };
+
+ sdram_pll: sdram_pll {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-pll-clock";
+ clocks = <&osc1>, <&osc2>, <&f2s_sdram_ref_clk>;
+ reg = <0xC0>;
+
+ ddr_dqs_clk: ddr_dqs_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&sdram_pll>;
+ reg = <0xC8>;
+ };
+
+ ddr_2x_dqs_clk: ddr_2x_dqs_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&sdram_pll>;
+ reg = <0xCC>;
+ };
+
+ ddr_dq_clk: ddr_dq_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&sdram_pll>;
+ reg = <0xD0>;
+ };
+
+ h2f_usr2_clk: h2f_usr2_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&sdram_pll>;
+ reg = <0xD4>;
+ };
+ };
+
+ mpu_periph_clk: mpu_periph_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&mpuclk>;
+ fixed-divider = <4>;
+ };
+
+ mpu_l2_ram_clk: mpu_l2_ram_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&mpuclk>;
+ fixed-divider = <2>;
+ };
+
+ l4_main_clk: l4_main_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&mainclk>;
+ clk-gate = <0x60 0>;
+ };
+
+ l3_main_clk: l3_main_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-perip-clk";
+ clocks = <&mainclk>;
+ fixed-divider = <1>;
+ };
+
+ l3_mp_clk: l3_mp_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&mainclk>;
+ div-reg = <0x64 0 2>;
+ clk-gate = <0x60 1>;
+ };
+
+ l3_sp_clk: l3_sp_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&mainclk>;
+ div-reg = <0x64 2 2>;
+ };
+
+ l4_mp_clk: l4_mp_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&mainclk>, <&per_base_clk>;
+ div-reg = <0x64 4 3>;
+ clk-gate = <0x60 2>;
+ };
+
+ l4_sp_clk: l4_sp_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&mainclk>, <&per_base_clk>;
+ div-reg = <0x64 7 3>;
+ clk-gate = <0x60 3>;
+ };
+
+ dbg_at_clk: dbg_at_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&dbg_base_clk>;
+ div-reg = <0x68 0 2>;
+ clk-gate = <0x60 4>;
+ };
+
+ dbg_clk: dbg_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&dbg_base_clk>;
+ div-reg = <0x68 2 2>;
+ clk-gate = <0x60 5>;
+ };
+
+ dbg_trace_clk: dbg_trace_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&dbg_base_clk>;
+ div-reg = <0x6C 0 3>;
+ clk-gate = <0x60 6>;
+ };
+
+ dbg_timer_clk: dbg_timer_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&dbg_base_clk>;
+ clk-gate = <0x60 7>;
+ };
+
+ cfg_clk: cfg_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&cfg_h2f_usr0_clk>;
+ clk-gate = <0x60 8>;
+ };
+
+ h2f_user0_clk: h2f_user0_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&cfg_h2f_usr0_clk>;
+ clk-gate = <0x60 9>;
+ };
+
+ emac_0_clk: emac_0_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&emac0_clk>;
+ clk-gate = <0xa0 0>;
+ };
+
+ emac_1_clk: emac_1_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&emac1_clk>;
+ clk-gate = <0xa0 1>;
+ };
+
+ usb_mp_clk: usb_mp_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&per_base_clk>;
+ clk-gate = <0xa0 2>;
+ div-reg = <0xa4 0 3>;
+ };
+
+ spi_m_clk: spi_m_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&per_base_clk>;
+ clk-gate = <0xa0 3>;
+ div-reg = <0xa4 3 3>;
+ };
+
+ can0_clk: can0_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&per_base_clk>;
+ clk-gate = <0xa0 4>;
+ div-reg = <0xa4 6 3>;
+ };
+
+ can1_clk: can1_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&per_base_clk>;
+ clk-gate = <0xa0 5>;
+ div-reg = <0xa4 9 3>;
+ };
+
+ gpio_db_clk: gpio_db_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&per_base_clk>;
+ clk-gate = <0xa0 6>;
+ div-reg = <0xa8 0 24>;
+ };
+
+ h2f_user1_clk: h2f_user1_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&h2f_usr1_clk>;
+ clk-gate = <0xa0 7>;
+ };
+
+ sdmmc_clk: sdmmc_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>;
+ clk-gate = <0xa0 8>;
+ clk-phase = <0 135>;
+ };
+
+ nand_x_clk: nand_x_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>;
+ clk-gate = <0xa0 9>;
+ };
+
+ nand_clk: nand_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>;
+ clk-gate = <0xa0 10>;
+ fixed-divider = <4>;
+ };
+
+ qspi_clk: qspi_clk {
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-gate-clk";
+ clocks = <&f2s_periph_ref_clk>, <&main_qspi_clk>, <&per_qspi_clk>;
+ clk-gate = <0xa0 11>;
+ };
+ };
+ };
+
+ gmac0: ethernet@ff700000 {
+ compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac";
+ altr,sysmgr-syscon = <&sysmgr 0x60 0>;
+ reg = <0xff700000 0x2000>;
+ interrupts = <0 115 4>;
+ interrupt-names = "macirq";
+ mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */
+ clocks = <&emac0_clk>;
+ clock-names = "stmmaceth";
+ resets = <&rst EMAC0_RESET>;
+ reset-names = "stmmaceth";
+ snps,multicast-filter-bins = <256>;
+ snps,perfect-filter-entries = <128>;
+ status = "disabled";
+ };
+
+ gmac1: ethernet@ff702000 {
+ compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac";
+ altr,sysmgr-syscon = <&sysmgr 0x60 2>;
+ reg = <0xff702000 0x2000>;
+ interrupts = <0 120 4>;
+ interrupt-names = "macirq";
+ mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */
+ clocks = <&emac1_clk>;
+ clock-names = "stmmaceth";
+ resets = <&rst EMAC1_RESET>;
+ reset-names = "stmmaceth";
+ snps,multicast-filter-bins = <256>;
+ snps,perfect-filter-entries = <128>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@ffc04000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xffc04000 0x1000>;
+ clocks = <&l4_sp_clk>;
+ interrupts = <0 158 0x4>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@ffc05000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xffc05000 0x1000>;
+ clocks = <&l4_sp_clk>;
+ interrupts = <0 159 0x4>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@ffc06000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xffc06000 0x1000>;
+ clocks = <&l4_sp_clk>;
+ interrupts = <0 160 0x4>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@ffc07000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xffc07000 0x1000>;
+ clocks = <&l4_sp_clk>;
+ interrupts = <0 161 0x4>;
+ status = "disabled";
+ };
+
+ gpio0: gpio@ff708000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xff708000 0x1000>;
+ clocks = <&per_base_clk>;
+ status = "disabled";
+
+ porta: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <29>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <0 164 4>;
+ };
+ };
+
+ gpio1: gpio@ff709000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xff709000 0x1000>;
+ clocks = <&per_base_clk>;
+ status = "disabled";
+
+ portb: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <29>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <0 165 4>;
+ };
+ };
+
+ gpio2: gpio@ff70a000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xff70a000 0x1000>;
+ clocks = <&per_base_clk>;
+ status = "disabled";
+
+ portc: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <27>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <0 166 4>;
+ };
+ };
+
+ sdr: sdr@ffc25000 {
+ compatible = "syscon";
+ reg = <0xffc25000 0x1000>;
+ };
+
+ sdramedac {
+ compatible = "altr,sdram-edac";
+ altr,sdr-syscon = <&sdr>;
+ interrupts = <0 39 4>;
+ };
+
+ L2: l2-cache@fffef000 {
+ compatible = "arm,pl310-cache";
+ reg = <0xfffef000 0x1000>;
+ interrupts = <0 38 0x04>;
+ cache-unified;
+ cache-level = <2>;
+ arm,tag-latency = <1 1 1>;
+ arm,data-latency = <2 1 1>;
+ };
+
+ mmc: dwmmc0@ff704000 {
+ compatible = "altr,socfpga-dw-mshc";
+ reg = <0xff704000 0x1000>;
+ interrupts = <0 139 4>;
+ fifo-depth = <0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&l4_mp_clk>, <&sdmmc_clk>;
+ clock-names = "biu", "ciu";
+ };
+
+ ocram: sram@ffff0000 {
+ compatible = "mmio-sram";
+ reg = <0xffff0000 0x10000>;
+ };
+
+ spi0: spi@fff00000 {
+ compatible = "snps,dw-apb-ssi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xfff00000 0x1000>;
+ interrupts = <0 154 4>;
+ num-cs = <4>;
+ clocks = <&spi_m_clk>;
+ status = "disabled";
+ };
+
+ spi1: spi@fff01000 {
+ compatible = "snps,dw-apb-ssi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xfff01000 0x1000>;
+ interrupts = <0 155 4>;
+ num-cs = <4>;
+ clocks = <&spi_m_clk>;
+ status = "disabled";
+ };
+
+ /* Local timer */
+ timer@fffec600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xfffec600 0x100>;
+ interrupts = <1 13 0xf04>;
+ clocks = <&mpu_periph_clk>;
+ };
+
+ timer0: timer0@ffc08000 {
+ compatible = "snps,dw-apb-timer";
+ interrupts = <0 167 4>;
+ reg = <0xffc08000 0x1000>;
+ clocks = <&l4_sp_clk>;
+ clock-names = "timer";
+ };
+
+ timer1: timer1@ffc09000 {
+ compatible = "snps,dw-apb-timer";
+ interrupts = <0 168 4>;
+ reg = <0xffc09000 0x1000>;
+ clocks = <&l4_sp_clk>;
+ clock-names = "timer";
+ };
+
+ timer2: timer2@ffd00000 {
+ compatible = "snps,dw-apb-timer";
+ interrupts = <0 169 4>;
+ reg = <0xffd00000 0x1000>;
+ clocks = <&osc1>;
+ clock-names = "timer";
+ };
+
+ timer3: timer3@ffd01000 {
+ compatible = "snps,dw-apb-timer";
+ interrupts = <0 170 4>;
+ reg = <0xffd01000 0x1000>;
+ clocks = <&osc1>;
+ clock-names = "timer";
+ };
+
+ uart0: serial0@ffc02000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xffc02000 0x1000>;
+ interrupts = <0 162 4>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&l4_sp_clk>;
+ dmas = <&pdma 28>,
+ <&pdma 29>;
+ dma-names = "tx", "rx";
+ };
+
+ uart1: serial1@ffc03000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xffc03000 0x1000>;
+ interrupts = <0 163 4>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&l4_sp_clk>;
+ dmas = <&pdma 30>,
+ <&pdma 31>;
+ dma-names = "tx", "rx";
+ };
+
+ rst: rstmgr@ffd05000 {
+ #reset-cells = <1>;
+ compatible = "altr,rst-mgr";
+ reg = <0xffd05000 0x1000>;
+ };
+
+ usbphy0: usbphy@0 {
+ #phy-cells = <0>;
+ compatible = "usb-nop-xceiv";
+ status = "okay";
+ };
+
+ usb0: usb@ffb00000 {
+ compatible = "snps,dwc2";
+ reg = <0xffb00000 0xffff>;
+ interrupts = <0 125 4>;
+ clocks = <&usb_mp_clk>;
+ clock-names = "otg";
+ phys = <&usbphy0>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ usb1: usb@ffb40000 {
+ compatible = "snps,dwc2";
+ reg = <0xffb40000 0xffff>;
+ interrupts = <0 128 4>;
+ clocks = <&usb_mp_clk>;
+ clock-names = "otg";
+ phys = <&usbphy0>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ watchdog0: watchdog@ffd02000 {
+ compatible = "snps,dw-wdt";
+ reg = <0xffd02000 0x1000>;
+ interrupts = <0 171 4>;
+ clocks = <&osc1>;
+ status = "disabled";
+ };
+
+ watchdog1: watchdog@ffd03000 {
+ compatible = "snps,dw-wdt";
+ reg = <0xffd03000 0x1000>;
+ interrupts = <0 172 4>;
+ clocks = <&osc1>;
+ status = "disabled";
+ };
+
+ sysmgr: sysmgr@ffd08000 {
+ compatible = "altr,sys-mgr", "syscon";
+ reg = <0xffd08000 0x4000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi
new file mode 100644
index 000000000..8a05c47fd
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga_arria10.dtsi
@@ -0,0 +1,374 @@
+/*
+ * Copyright Altera Corporation (C) 2014. 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &gmac0;
+ ethernet1 = &gmac1;
+ ethernet2 = &gmac2;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ timer0 = &timer0;
+ timer1 = &timer1;
+ timer2 = &timer2;
+ timer3 = &timer3;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ };
+ cpu@1 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ intc: intc@ffffd000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0xffffd000 0x1000>,
+ <0xffffc100 0x100>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ device_type = "soc";
+ interrupt-parent = <&intc>;
+ ranges;
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pdma: pdma@ffda1000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0xffda1000 0x1000>;
+ interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>,
+ <0 84 IRQ_TYPE_LEVEL_HIGH>,
+ <0 85 IRQ_TYPE_LEVEL_HIGH>,
+ <0 86 IRQ_TYPE_LEVEL_HIGH>,
+ <0 87 IRQ_TYPE_LEVEL_HIGH>,
+ <0 88 IRQ_TYPE_LEVEL_HIGH>,
+ <0 89 IRQ_TYPE_LEVEL_HIGH>,
+ <0 90 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+ };
+
+ clkmgr@ffd04000 {
+ compatible = "altr,clk-mgr";
+ reg = <0xffd04000 0x1000>;
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ osc1: osc1 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ };
+
+ main_pll: main_pll {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-pll-clock";
+ clocks = <&osc1>;
+ };
+
+ periph_pll: periph_pll {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <0>;
+ compatible = "altr,socfpga-pll-clock";
+ clocks = <&osc1>;
+ };
+ };
+ };
+
+ gmac0: ethernet@ff800000 {
+ compatible = "altr,socfpga-stmmac", "snps,dwmac-3.72a", "snps,dwmac";
+ reg = <0xff800000 0x2000>;
+ interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ /* Filled in by bootloader */
+ mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ };
+
+ gmac1: ethernet@ff802000 {
+ compatible = "altr,socfpga-stmmac", "snps,dwmac-3.72a", "snps,dwmac";
+ reg = <0xff802000 0x2000>;
+ interrupts = <0 93 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ /* Filled in by bootloader */
+ mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ };
+
+ gmac2: ethernet@ff804000 {
+ compatible = "altr,socfpga-stmmac", "snps,dwmac-3.72a", "snps,dwmac";
+ reg = <0xff804000 0x2000>;
+ interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ /* Filled in by bootloader */
+ mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ };
+
+ gpio0: gpio@ffc02900 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xffc02900 0x100>;
+ status = "disabled";
+
+ porta: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <29>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <0 112 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ gpio1: gpio@ffc02a00 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xffc02a00 0x100>;
+ status = "disabled";
+
+ portb: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <29>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ gpio2: gpio@ffc02b00 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xffc02b00 0x100>;
+ status = "disabled";
+
+ portc: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <27>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <0 114 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ i2c0: i2c@ffc02200 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xffc02200 0x100>;
+ interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@ffc02300 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xffc02300 0x100>;
+ interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@ffc02400 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xffc02400 0x100>;
+ interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@ffc02500 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xffc02500 0x100>;
+ interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@ffc02600 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xffc02600 0x100>;
+ interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ L2: l2-cache@fffff000 {
+ compatible = "arm,pl310-cache";
+ reg = <0xfffff000 0x1000>;
+ interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ mmc: dwmmc0@ff808000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "altr,socfpga-dw-mshc";
+ reg = <0xff808000 0x1000>;
+ interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
+ fifo-depth = <0x400>;
+ };
+
+ ocram: sram@ffe00000 {
+ compatible = "mmio-sram";
+ reg = <0xffe00000 0x40000>;
+ };
+
+ rst: rstmgr@ffd05000 {
+ #reset-cells = <1>;
+ compatible = "altr,rst-mgr";
+ reg = <0xffd05000 0x100>;
+ };
+
+ sysmgr: sysmgr@ffd06000 {
+ compatible = "altr,sys-mgr", "syscon";
+ reg = <0xffd06000 0x300>;
+ };
+
+ /* Local timer */
+ timer@ffffc600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xffffc600 0x100>;
+ interrupts = <1 13 0xf04>;
+ };
+
+ timer0: timer0@ffc02700 {
+ compatible = "snps,dw-apb-timer";
+ interrupts = <0 115 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xffc02700 0x100>;
+ };
+
+ timer1: timer1@ffc02800 {
+ compatible = "snps,dw-apb-timer";
+ interrupts = <0 116 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xffc02800 0x100>;
+ };
+
+ timer2: timer2@ffd00000 {
+ compatible = "snps,dw-apb-timer";
+ interrupts = <0 117 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xffd00000 0x100>;
+ };
+
+ timer3: timer3@ffd00100 {
+ compatible = "snps,dw-apb-timer";
+ interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xffd01000 0x100>;
+ };
+
+ uart0: serial0@ffc02000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xffc02000 0x100>;
+ interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ uart1: serial1@ffc02100 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xffc02100 0x100>;
+ interrupts = <0 111 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ usbphy0: usbphy@0 {
+ #phy-cells = <0>;
+ compatible = "usb-nop-xceiv";
+ status = "okay";
+ };
+
+ usb0: usb@ffb00000 {
+ compatible = "snps,dwc2";
+ reg = <0xffb00000 0xffff>;
+ interrupts = <0 95 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usbphy0>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ usb1: usb@ffb40000 {
+ compatible = "snps,dwc2";
+ reg = <0xffb40000 0xffff>;
+ interrupts = <0 96 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usbphy0>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ watchdog0: watchdog@ffd00200 {
+ compatible = "snps,dw-wdt";
+ reg = <0xffd00200 0x100>;
+ interrupts = <0 119 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ watchdog1: watchdog@ffd00300 {
+ compatible = "snps,dw-wdt";
+ reg = <0xffd00300 0x100>;
+ interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/socfpga_arria10_socdk.dts b/arch/arm/boot/dts/socfpga_arria10_socdk.dts
new file mode 100755
index 000000000..3015ce8d3
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga_arria10_socdk.dts
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014 Altera Corporation <www.altera.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, see <http://www.gnu.org/licenses/>.
+ */
+
+/dts-v1/;
+#include "socfpga_arria10.dtsi"
+
+/ {
+ model = "Altera SOCFPGA Arria 10";
+ compatible = "altr,socfpga-arria10", "altr,socfpga";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 rootwait";
+ };
+
+ memory {
+ name = "memory";
+ device_type = "memory";
+ reg = <0x0 0x40000000>; /* 1GB */
+ };
+
+ soc {
+ clkmgr@ffd04000 {
+ clocks {
+ osc1 {
+ clock-frequency = <25000000>;
+ };
+ };
+ };
+
+ serial0@ffc02000 {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/socfpga_arria5.dtsi b/arch/arm/boot/dts/socfpga_arria5.dtsi
new file mode 100644
index 000000000..1907cc600
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga_arria5.dtsi
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2013 Altera Corporation <www.altera.com>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/dts-v1/;
+/* First 4KB has trampoline code for secondary cores. */
+/memreserve/ 0x00000000 0x0001000;
+#include "socfpga.dtsi"
+
+/ {
+ soc {
+ clkmgr@ffd04000 {
+ clocks {
+ osc1 {
+ clock-frequency = <25000000>;
+ };
+ };
+ };
+
+ mmc0: dwmmc0@ff704000 {
+ num-slots = <1>;
+ broken-cd;
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ };
+
+ sysmgr@ffd08000 {
+ cpu1-start-addr = <0xffd080c4>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/socfpga_arria5_socdk.dts b/arch/arm/boot/dts/socfpga_arria5_socdk.dts
new file mode 100644
index 000000000..ccaf41742
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga_arria5_socdk.dts
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2013 Altera Corporation <www.altera.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "socfpga_arria5.dtsi"
+
+/ {
+ model = "Altera SOCFPGA Arria V SoC Development Kit";
+ compatible = "altr,socfpga-arria5", "altr,socfpga";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ name = "memory";
+ device_type = "memory";
+ reg = <0x0 0x40000000>; /* 1GB */
+ };
+
+ aliases {
+ /* this allow the ethaddr uboot environmnet variable contents
+ * to be added to the gmac1 device tree blob.
+ */
+ ethernet0 = &gmac1;
+ };
+
+ regulator_3_3v: 3-3-v-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&gmac1 {
+ status = "okay";
+ phy-mode = "rgmii";
+
+ rxd0-skew-ps = <0>;
+ rxd1-skew-ps = <0>;
+ rxd2-skew-ps = <0>;
+ rxd3-skew-ps = <0>;
+ txen-skew-ps = <0>;
+ txc-skew-ps = <2600>;
+ rxdv-skew-ps = <0>;
+ rxc-skew-ps = <2000>;
+};
+
+&i2c0 {
+ status = "okay";
+
+ eeprom@51 {
+ compatible = "atmel,24c32";
+ reg = <0x51>;
+ pagesize = <32>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ };
+};
+
+&mmc0 {
+ vmmc-supply = <&regulator_3_3v>;
+ vqmmc-supply = <&regulator_3_3v>;
+};
+
+&usb1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5.dtsi b/arch/arm/boot/dts/socfpga_cyclone5.dtsi
new file mode 100644
index 000000000..06db951e0
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga_cyclone5.dtsi
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 Altera Corporation <www.altera.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, see <http://www.gnu.org/licenses/>.
+ */
+
+/dts-v1/;
+/* First 4KB has trampoline code for secondary cores. */
+/memreserve/ 0x00000000 0x0001000;
+#include "socfpga.dtsi"
+
+/ {
+ soc {
+ clkmgr@ffd04000 {
+ clocks {
+ osc1 {
+ clock-frequency = <25000000>;
+ };
+ };
+ };
+
+ mmc0: dwmmc0@ff704000 {
+ num-slots = <1>;
+ broken-cd;
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ };
+
+ ethernet@ff702000 {
+ phy-mode = "rgmii";
+ phy-addr = <0xffffffff>; /* probe for phy addr */
+ status = "okay";
+ };
+
+ sysmgr@ffd08000 {
+ cpu1-start-addr = <0xffd080c4>;
+ };
+ };
+};
+
+&watchdog0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
new file mode 100644
index 000000000..258865da8
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2012 Altera Corporation <www.altera.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "socfpga_cyclone5.dtsi"
+
+/ {
+ model = "Altera SOCFPGA Cyclone V SoC Development Kit";
+ compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ name = "memory";
+ device_type = "memory";
+ reg = <0x0 0x40000000>; /* 1GB */
+ };
+
+ aliases {
+ /* this allow the ethaddr uboot environmnet variable contents
+ * to be added to the gmac1 device tree blob.
+ */
+ ethernet0 = &gmac1;
+ };
+
+ regulator_3_3v: 3-3-v-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&gmac1 {
+ status = "okay";
+ phy-mode = "rgmii";
+
+ rxd0-skew-ps = <0>;
+ rxd1-skew-ps = <0>;
+ rxd2-skew-ps = <0>;
+ rxd3-skew-ps = <0>;
+ txen-skew-ps = <0>;
+ txc-skew-ps = <2600>;
+ rxdv-skew-ps = <0>;
+ rxc-skew-ps = <2000>;
+};
+
+&gpio1 {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ eeprom@51 {
+ compatible = "atmel,24c32";
+ reg = <0x51>;
+ pagesize = <32>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ };
+};
+
+&mmc0 {
+ cd-gpios = <&portb 18 0>;
+ vmmc-supply = <&regulator_3_3v>;
+ vqmmc-supply = <&regulator_3_3v>;
+};
+
+&usb1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
new file mode 100644
index 000000000..16ea6f5f2
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2013 Steffen Trumtrar <s.trumtrar@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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "socfpga_cyclone5.dtsi"
+
+/ {
+ model = "Terasic SoCkit";
+ compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ name = "memory";
+ device_type = "memory";
+ reg = <0x0 0x40000000>; /* 1GB */
+ };
+
+ aliases {
+ /* this allow the ethaddr uboot environmnet variable contents
+ * to be added to the gmac1 device tree blob.
+ */
+ ethernet0 = &gmac1;
+ };
+
+ regulator_3_3v: vcc3p3-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC3P3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&gmac1 {
+ status = "okay";
+ phy-mode = "rgmii";
+
+ rxd0-skew-ps = <0>;
+ rxd1-skew-ps = <0>;
+ rxd2-skew-ps = <0>;
+ rxd3-skew-ps = <0>;
+ txen-skew-ps = <0>;
+ txc-skew-ps = <2600>;
+ rxdv-skew-ps = <0>;
+ rxc-skew-ps = <2000>;
+};
+
+&mmc0 {
+ vmmc-supply = <&regulator_3_3v>;
+ vqmmc-supply = <&regulator_3_3v>;
+};
+
+&usb1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_socrates.dts b/arch/arm/boot/dts/socfpga_cyclone5_socrates.dts
new file mode 100644
index 000000000..a1814b457
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga_cyclone5_socrates.dts
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 Steffen Trumtrar <s.trumtrar@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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "socfpga_cyclone5.dtsi"
+
+/ {
+ model = "EBV SOCrates";
+ compatible = "ebv,socrates", "altr,socfpga-cyclone5", "altr,socfpga";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ name = "memory";
+ device_type = "memory";
+ reg = <0x0 0x40000000>; /* 1GB */
+ };
+};
+
+&gmac1 {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ rtc: rtc@68 {
+ compatible = "stm,m41t82";
+ reg = <0x68>;
+ };
+};
+
+&mmc {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/socfpga_vt.dts b/arch/arm/boot/dts/socfpga_vt.dts
new file mode 100644
index 000000000..f9345e02c
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga_vt.dts
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2013 Altera Corporation <www.altera.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, see <http://www.gnu.org/licenses/>.
+ */
+
+/dts-v1/;
+#include "socfpga.dtsi"
+
+/ {
+ model = "Altera SOCFPGA VT";
+ compatible = "altr,socfpga-vt", "altr,socfpga";
+
+ chosen {
+ bootargs = "console=ttyS0,57600";
+ };
+
+ memory {
+ name = "memory";
+ device_type = "memory";
+ reg = <0x0 0x40000000>; /* 1 GB */
+ };
+
+ soc {
+ clkmgr@ffd04000 {
+ clocks {
+ osc1 {
+ clock-frequency = <10000000>;
+ };
+ };
+ };
+
+ dwmmc0@ff704000 {
+ num-slots = <1>;
+ broken-cd;
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ };
+
+ ethernet@ff700000 {
+ phy-mode = "gmii";
+ status = "okay";
+ };
+
+ timer0@ffc08000 {
+ clock-frequency = <7000000>;
+ };
+
+ timer1@ffc09000 {
+ clock-frequency = <7000000>;
+ };
+
+ timer2@ffd00000 {
+ clock-frequency = <7000000>;
+ };
+
+ timer3@ffd01000 {
+ clock-frequency = <7000000>;
+ };
+
+ serial0@ffc02000 {
+ clock-frequency = <7372800>;
+ };
+
+ serial1@ffc03000 {
+ clock-frequency = <7372800>;
+ };
+
+ sysmgr@ffd08000 {
+ cpu1-start-addr = <0xffd08010>;
+ };
+ };
+};
+
+&gmac0 {
+ status = "okay";
+ phy-mode = "gmii";
+};
diff --git a/arch/arm/boot/dts/spear1310-evb.dts b/arch/arm/boot/dts/spear1310-evb.dts
new file mode 100644
index 000000000..d42c84b1d
--- /dev/null
+++ b/arch/arm/boot/dts/spear1310-evb.dts
@@ -0,0 +1,427 @@
+/*
+ * DTS file for SPEAr1310 Evaluation Baord
+ *
+ * Copyright 2012 Viresh Kumar <viresh.linux@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
+ */
+
+/dts-v1/;
+/include/ "spear1310.dtsi"
+
+/ {
+ model = "ST SPEAr1310 Evaluation Board";
+ compatible = "st,spear1310-evb", "st,spear1310";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ memory {
+ reg = <0 0x40000000>;
+ };
+
+ ahb {
+ pinmux@e0700000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ i2c0 {
+ st,pins = "i2c0_grp";
+ st,function = "i2c0";
+ };
+ i2s0 {
+ st,pins = "i2s0_grp";
+ st,function = "i2s0";
+ };
+ i2s1 {
+ st,pins = "i2s1_grp";
+ st,function = "i2s1";
+ };
+ gpio {
+ st,pins = "arm_gpio_grp";
+ st,function = "arm_gpio";
+ };
+ clcd {
+ st,pins = "clcd_grp" , "clcd_high_res";
+ st,function = "clcd";
+ };
+ eth {
+ st,pins = "gmii_grp";
+ st,function = "gmii";
+ };
+ ssp0 {
+ st,pins = "ssp0_grp";
+ st,function = "ssp0";
+ };
+ kbd {
+ st,pins = "keyboard_6x6_grp";
+ st,function = "keyboard";
+ };
+ sdhci {
+ st,pins = "sdhci_grp";
+ st,function = "sdhci";
+ };
+ smi-pmx {
+ st,pins = "smi_2_chips_grp";
+ st,function = "smi";
+ };
+ uart0 {
+ st,pins = "uart0_grp";
+ st,function = "uart0";
+ };
+ rs485 {
+ st,pins = "rs485_0_1_tdm_0_1_grp";
+ st,function = "rs485_0_1_tdm_0_1";
+ };
+ i2c1_2 {
+ st,pins = "i2c_1_2_grp";
+ st,function = "i2c_1_2";
+ };
+ smii {
+ st,pins = "smii_0_1_2_grp";
+ st,function = "smii_0_1_2";
+ };
+ nand {
+ st,pins = "nand_8bit_grp",
+ "nand_16bit_grp";
+ st,function = "nand";
+ };
+ sata {
+ st,pins = "sata0_grp";
+ st,function = "sata";
+ };
+ pcie {
+ st,pins = "pcie1_grp", "pcie2_grp";
+ st,function = "pci_express";
+ };
+ };
+ };
+
+ ahci@b1000000 {
+ status = "okay";
+ };
+
+ miphy@eb800000 {
+ status = "okay";
+ };
+
+ cf@b2800000 {
+ status = "okay";
+ };
+
+ dma@ea800000 {
+ status = "okay";
+ };
+
+ dma@eb000000 {
+ status = "okay";
+ };
+
+ fsmc: flash@b0000000 {
+ status = "okay";
+
+ partition@0 {
+ label = "xloader";
+ reg = <0x0 0x80000>;
+ };
+ partition@80000 {
+ label = "u-boot";
+ reg = <0x80000 0x140000>;
+ };
+ partition@1C0000 {
+ label = "environment";
+ reg = <0x1C0000 0x40000>;
+ };
+ partition@200000 {
+ label = "dtb";
+ reg = <0x200000 0x40000>;
+ };
+ partition@240000 {
+ label = "linux";
+ reg = <0x240000 0xC00000>;
+ };
+ partition@E40000 {
+ label = "rootfs";
+ reg = <0xE40000 0x0>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@1 {
+ label = "wakeup";
+ linux,code = <0x100>;
+ gpios = <&gpio0 7 0x4>;
+ debounce-interval = <20>;
+ gpio-key,wakeup = <1>;
+ };
+ };
+
+ gmac0: eth@e2000000 {
+ phy-mode = "gmii";
+ status = "okay";
+ };
+
+ sdhci@b3000000 {
+ status = "okay";
+ };
+
+ smi: flash@ea000000 {
+ status = "okay";
+ clock-rate=<50000000>;
+
+ flash@e6000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe6000000 0x800000>;
+ st,smi-fast-mode;
+
+ partition@0 {
+ label = "xloader";
+ reg = <0x0 0x10000>;
+ };
+ partition@10000 {
+ label = "u-boot";
+ reg = <0x10000 0x50000>;
+ };
+ partition@60000 {
+ label = "environment";
+ reg = <0x60000 0x10000>;
+ };
+ partition@70000 {
+ label = "dtb";
+ reg = <0x70000 0x10000>;
+ };
+ partition@80000 {
+ label = "linux";
+ reg = <0x80000 0x310000>;
+ };
+ partition@390000 {
+ label = "rootfs";
+ reg = <0x390000 0x0>;
+ };
+ };
+ };
+
+ ehci@e4800000 {
+ status = "okay";
+ };
+
+ ehci@e5800000 {
+ status = "okay";
+ };
+
+ ohci@e4000000 {
+ status = "okay";
+ };
+
+ ohci@e5000000 {
+ status = "okay";
+ };
+
+ apb {
+ adc@e0080000 {
+ status = "okay";
+ };
+
+ gpio0: gpio@e0600000 {
+ status = "okay";
+ };
+
+ gpio1: gpio@e0680000 {
+ status = "okay";
+ };
+
+ gpio@d8400000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@e0280000 {
+ status = "okay";
+ };
+
+ kbd@e0300000 {
+ linux,keymap = < 0x00000001
+ 0x00010002
+ 0x00020003
+ 0x00030004
+ 0x00040005
+ 0x00050006
+ 0x00060007
+ 0x00070008
+ 0x00080009
+ 0x0100000a
+ 0x0101000c
+ 0x0102000d
+ 0x0103000e
+ 0x0104000f
+ 0x01050010
+ 0x01060011
+ 0x01070012
+ 0x01080013
+ 0x02000014
+ 0x02010015
+ 0x02020016
+ 0x02030017
+ 0x02040018
+ 0x02050019
+ 0x0206001a
+ 0x0207001b
+ 0x0208001c
+ 0x0300001d
+ 0x0301001e
+ 0x0302001f
+ 0x03030020
+ 0x03040021
+ 0x03050022
+ 0x03060023
+ 0x03070024
+ 0x03080025
+ 0x04000026
+ 0x04010027
+ 0x04020028
+ 0x04030029
+ 0x0404002a
+ 0x0405002b
+ 0x0406002c
+ 0x0407002d
+ 0x0408002e
+ 0x0500002f
+ 0x05010030
+ 0x05020031
+ 0x05030032
+ 0x05040033
+ 0x05050034
+ 0x05060035
+ 0x05070036
+ 0x05080037
+ 0x06000038
+ 0x06010039
+ 0x0602003a
+ 0x0603003b
+ 0x0604003c
+ 0x0605003d
+ 0x0606003e
+ 0x0607003f
+ 0x06080040
+ 0x07000041
+ 0x07010042
+ 0x07020043
+ 0x07030044
+ 0x07040045
+ 0x07050046
+ 0x07060047
+ 0x07070048
+ 0x07080049
+ 0x0800004a
+ 0x0801004b
+ 0x0802004c
+ 0x0803004d
+ 0x0804004e
+ 0x0805004f
+ 0x08060050
+ 0x08070051
+ 0x08080052 >;
+ autorepeat;
+ st,mode = <0>;
+ suspended_rate = <2000000>;
+ status = "okay";
+ };
+
+ rtc@e0580000 {
+ status = "okay";
+ };
+
+ serial@e0000000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ spi0: spi@e0100000 {
+ status = "okay";
+ num-cs = <3>;
+ cs-gpios = <&gpio1 7 0>, <&spics 0>, <&spics 1>;
+
+ stmpe610@0 {
+ compatible = "st,stmpe610";
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ spi-max-frequency = <1000000>;
+ spi-cpha;
+ pl022,hierarchy = <0>;
+ pl022,interface = <0>;
+ pl022,slave-tx-disable;
+ pl022,com-mode = <0>;
+ pl022,rx-level-trig = <0>;
+ pl022,tx-level-trig = <0>;
+ pl022,ctrl-len = <0x7>;
+ pl022,wait-state = <0>;
+ pl022,duplex = <0>;
+ interrupts = <6 0x4>;
+ interrupt-parent = <&gpio1>;
+ irq-trigger = <0x2>;
+
+ stmpe_touchscreen {
+ compatible = "st,stmpe-ts";
+ ts,sample-time = <4>;
+ ts,mod-12b = <1>;
+ ts,ref-sel = <0>;
+ ts,adc-freq = <1>;
+ ts,ave-ctrl = <1>;
+ ts,touch-det-delay = <2>;
+ ts,settling = <2>;
+ ts,fraction-z = <7>;
+ ts,i-drive = <1>;
+ };
+ };
+
+ m25p80@1 {
+ compatible = "st,m25p80";
+ reg = <1>;
+ spi-max-frequency = <12000000>;
+ spi-cpol;
+ spi-cpha;
+ pl022,hierarchy = <0>;
+ pl022,interface = <0>;
+ pl022,slave-tx-disable;
+ pl022,com-mode = <0x2>;
+ pl022,rx-level-trig = <0>;
+ pl022,tx-level-trig = <0>;
+ pl022,ctrl-len = <0x11>;
+ pl022,wait-state = <0>;
+ pl022,duplex = <0>;
+ };
+
+ spidev@2 {
+ compatible = "spidev";
+ reg = <2>;
+ spi-max-frequency = <25000000>;
+ spi-cpha;
+ pl022,hierarchy = <0>;
+ pl022,interface = <0>;
+ pl022,slave-tx-disable;
+ pl022,com-mode = <0x2>;
+ pl022,rx-level-trig = <0>;
+ pl022,tx-level-trig = <0>;
+ pl022,ctrl-len = <0x11>;
+ pl022,wait-state = <0>;
+ pl022,duplex = <0>;
+ };
+ };
+
+ wdt@ec800620 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi
new file mode 100644
index 000000000..9d3429206
--- /dev/null
+++ b/arch/arm/boot/dts/spear1310.dtsi
@@ -0,0 +1,316 @@
+/*
+ * DTS file for all SPEAr1310 SoCs
+ *
+ * Copyright 2012 Viresh Kumar <viresh.linux@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/ "spear13xx.dtsi"
+
+/ {
+ compatible = "st,spear1310";
+
+ ahb {
+ spics: spics@e0700000{
+ compatible = "st,spear-spics-gpio";
+ reg = <0xe0700000 0x1000>;
+ st-spics,peripcfg-reg = <0x3b0>;
+ st-spics,sw-enable-bit = <12>;
+ st-spics,cs-value-bit = <11>;
+ st-spics,cs-enable-mask = <3>;
+ st-spics,cs-enable-shift = <8>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ miphy0: miphy@eb800000 {
+ compatible = "st,spear1310-miphy";
+ reg = <0xeb800000 0x4000>;
+ misc = <&misc>;
+ phy-id = <0>;
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
+ miphy1: miphy@eb804000 {
+ compatible = "st,spear1310-miphy";
+ reg = <0xeb804000 0x4000>;
+ misc = <&misc>;
+ phy-id = <1>;
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
+ miphy2: miphy@eb808000 {
+ compatible = "st,spear1310-miphy";
+ reg = <0xeb808000 0x4000>;
+ misc = <&misc>;
+ phy-id = <2>;
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
+ ahci0: ahci@b1000000 {
+ compatible = "snps,spear-ahci";
+ reg = <0xb1000000 0x10000>;
+ interrupts = <0 68 0x4>;
+ phys = <&miphy0 0>;
+ phy-names = "sata-phy";
+ status = "disabled";
+ };
+
+ ahci1: ahci@b1800000 {
+ compatible = "snps,spear-ahci";
+ reg = <0xb1800000 0x10000>;
+ interrupts = <0 69 0x4>;
+ phys = <&miphy1 0>;
+ phy-names = "sata-phy";
+ status = "disabled";
+ };
+
+ ahci2: ahci@b4000000 {
+ compatible = "snps,spear-ahci";
+ reg = <0xb4000000 0x10000>;
+ interrupts = <0 70 0x4>;
+ phys = <&miphy2 0>;
+ phy-names = "sata-phy";
+ status = "disabled";
+ };
+
+ pcie0: pcie@b1000000 {
+ compatible = "st,spear1340-pcie", "snps,dw-pcie";
+ reg = <0xb1000000 0x4000>, <0x80000000 0x20000>;
+ reg-names = "dbi", "config";
+ interrupts = <0 68 0x4>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0x0 0 &gic 0 68 0x4>;
+ num-lanes = <1>;
+ phys = <&miphy0 1>;
+ phy-names = "pcie-phy";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x81000000 0 0 0x80020000 0 0x00010000 /* downstream I/O */
+ 0x82000000 0 0x80030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */
+ status = "disabled";
+ };
+
+ pcie1: pcie@b1800000 {
+ compatible = "st,spear1340-pcie", "snps,dw-pcie";
+ reg = <0xb1800000 0x4000>, <0x90000000 0x20000>;
+ reg-names = "dbi", "config";
+ interrupts = <0 69 0x4>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0x0 0 &gic 0 69 0x4>;
+ num-lanes = <1>;
+ phys = <&miphy1 1>;
+ phy-names = "pcie-phy";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x81000000 0 0 0x90020000 0 0x00010000 /* downstream I/O */
+ 0x82000000 0 0x90030000 0x90030000 0 0x0ffd0000>; /* non-prefetchable memory */
+ status = "disabled";
+ };
+
+ pcie2: pcie@b4000000 {
+ compatible = "st,spear1340-pcie", "snps,dw-pcie";
+ reg = <0xb4000000 0x4000>, <0xc0000000 0x20000>;
+ reg-names = "dbi", "config";
+ interrupts = <0 70 0x4>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0x0 0 &gic 0 70 0x4>;
+ num-lanes = <1>;
+ phys = <&miphy2 1>;
+ phy-names = "pcie-phy";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x81000000 0 0 0xc0020000 0 0x00010000 /* downstream I/O */
+ 0x82000000 0 0xc0030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */
+ status = "disabled";
+ };
+
+ gmac1: eth@5c400000 {
+ compatible = "st,spear600-gmac";
+ reg = <0x5c400000 0x8000>;
+ interrupts = <0 95 0x4>;
+ interrupt-names = "macirq";
+ phy-mode = "mii";
+ status = "disabled";
+ };
+
+ gmac2: eth@5c500000 {
+ compatible = "st,spear600-gmac";
+ reg = <0x5c500000 0x8000>;
+ interrupts = <0 96 0x4>;
+ interrupt-names = "macirq";
+ phy-mode = "mii";
+ status = "disabled";
+ };
+
+ gmac3: eth@5c600000 {
+ compatible = "st,spear600-gmac";
+ reg = <0x5c600000 0x8000>;
+ interrupts = <0 97 0x4>;
+ interrupt-names = "macirq";
+ phy-mode = "rmii";
+ status = "disabled";
+ };
+
+ gmac4: eth@5c700000 {
+ compatible = "st,spear600-gmac";
+ reg = <0x5c700000 0x8000>;
+ interrupts = <0 98 0x4>;
+ interrupt-names = "macirq";
+ phy-mode = "rgmii";
+ status = "disabled";
+ };
+
+ pinmux: pinmux@e0700000 {
+ compatible = "st,spear1310-pinmux";
+ reg = <0xe0700000 0x1000>;
+ #gpio-range-cells = <3>;
+ };
+
+ apb {
+ i2c1: i2c@5cd00000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x5cd00000 0x1000>;
+ interrupts = <0 87 0x4>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@5ce00000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x5ce00000 0x1000>;
+ interrupts = <0 88 0x4>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@5cf00000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x5cf00000 0x1000>;
+ interrupts = <0 89 0x4>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@5d000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x5d000000 0x1000>;
+ interrupts = <0 90 0x4>;
+ status = "disabled";
+ };
+
+ i2c5: i2c@5d100000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x5d100000 0x1000>;
+ interrupts = <0 91 0x4>;
+ status = "disabled";
+ };
+
+ i2c6: i2c@5d200000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x5d200000 0x1000>;
+ interrupts = <0 92 0x4>;
+ status = "disabled";
+ };
+
+ i2c7: i2c@5d300000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x5d300000 0x1000>;
+ interrupts = <0 93 0x4>;
+ status = "disabled";
+ };
+
+ spi1: spi@5d400000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x5d400000 0x1000>;
+ interrupts = <0 99 0x4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ serial@5c800000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x5c800000 0x1000>;
+ interrupts = <0 82 0x4>;
+ status = "disabled";
+ };
+
+ serial@5c900000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x5c900000 0x1000>;
+ interrupts = <0 83 0x4>;
+ status = "disabled";
+ };
+
+ serial@5ca00000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x5ca00000 0x1000>;
+ interrupts = <0 84 0x4>;
+ status = "disabled";
+ };
+
+ serial@5cb00000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x5cb00000 0x1000>;
+ interrupts = <0 85 0x4>;
+ status = "disabled";
+ };
+
+ serial@5cc00000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x5cc00000 0x1000>;
+ interrupts = <0 86 0x4>;
+ status = "disabled";
+ };
+
+ thermal@e07008c4 {
+ st,thermal-flags = <0x7000>;
+ };
+
+ gpiopinctrl: gpio@d8400000 {
+ compatible = "st,spear-plgpio";
+ reg = <0xd8400000 0x1000>;
+ interrupts = <0 100 0x4>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinmux 0 0 246>;
+ status = "disabled";
+
+ st-plgpio,ngpio = <246>;
+ st-plgpio,enb-reg = <0xd0>;
+ st-plgpio,wdata-reg = <0x90>;
+ st-plgpio,dir-reg = <0xb0>;
+ st-plgpio,ie-reg = <0x30>;
+ st-plgpio,rdata-reg = <0x70>;
+ st-plgpio,mis-reg = <0x10>;
+ st-plgpio,eit-reg = <0x50>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear1340-evb.dts b/arch/arm/boot/dts/spear1340-evb.dts
new file mode 100644
index 000000000..b23e05ed1
--- /dev/null
+++ b/arch/arm/boot/dts/spear1340-evb.dts
@@ -0,0 +1,525 @@
+/*
+ * DTS file for SPEAr1340 Evaluation Baord
+ *
+ * Copyright 2012 Viresh Kumar <viresh.linux@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
+ */
+
+/dts-v1/;
+/include/ "spear1340.dtsi"
+
+/ {
+ model = "ST SPEAr1340 Evaluation Board";
+ compatible = "st,spear1340-evb", "st,spear1340";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ memory {
+ reg = <0 0x40000000>;
+ };
+
+ ahb {
+ pinmux@e0700000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ pads_as_gpio {
+ st,pins = "pads_as_gpio_grp";
+ st,function = "pads_as_gpio";
+ };
+ fsmc {
+ st,pins = "fsmc_8bit_grp";
+ st,function = "fsmc";
+ };
+ uart0 {
+ st,pins = "uart0_grp";
+ st,function = "uart0";
+ };
+ i2c0 {
+ st,pins = "i2c0_grp";
+ st,function = "i2c0";
+ };
+ i2c1 {
+ st,pins = "i2c1_grp";
+ st,function = "i2c1";
+ };
+ spdif-in {
+ st,pins = "spdif_in_grp";
+ st,function = "spdif_in";
+ };
+ spdif-out {
+ st,pins = "spdif_out_grp";
+ st,function = "spdif_out";
+ };
+ ssp0 {
+ st,pins = "ssp0_grp", "ssp0_cs1_grp", "ssp0_cs2_grp", "ssp0_cs3_grp";
+ st,function = "ssp0";
+ };
+ smi-pmx {
+ st,pins = "smi_grp";
+ st,function = "smi";
+ };
+ i2s {
+ st,pins = "i2s_in_grp", "i2s_out_grp";
+ st,function = "i2s";
+ };
+ gmac {
+ st,pins = "gmii_grp", "rgmii_grp";
+ st,function = "gmac";
+ };
+ cam0 {
+ st,pins = "cam0_grp";
+ st,function = "cam0";
+ };
+ cam1 {
+ st,pins = "cam1_grp";
+ st,function = "cam1";
+ };
+ cam2 {
+ st,pins = "cam2_grp";
+ st,function = "cam2";
+ };
+ cam3 {
+ st,pins = "cam3_grp";
+ st,function = "cam3";
+ };
+ cec0 {
+ st,pins = "cec0_grp";
+ st,function = "cec0";
+ };
+ cec1 {
+ st,pins = "cec1_grp";
+ st,function = "cec1";
+ };
+ sdhci {
+ st,pins = "sdhci_grp";
+ st,function = "sdhci";
+ };
+ clcd {
+ st,pins = "clcd_grp";
+ st,function = "clcd";
+ };
+ sata {
+ st,pins = "sata_grp";
+ st,function = "sata";
+ };
+ pcie {
+ st,pins = "pcie_grp";
+ st,function = "pcie";
+ };
+
+ };
+ };
+
+ ahci@b1000000 {
+ status = "okay";
+ };
+
+ miphy@eb800000 {
+ status = "okay";
+ };
+
+ dma@ea800000 {
+ status = "okay";
+ };
+
+ dma@eb000000 {
+ status = "okay";
+ };
+
+ fsmc: flash@b0000000 {
+ status = "okay";
+
+ partition@0 {
+ label = "xloader";
+ reg = <0x0 0x200000>;
+ };
+ partition@200000 {
+ label = "u-boot";
+ reg = <0x200000 0x200000>;
+ };
+ partition@400000 {
+ label = "environment";
+ reg = <0x400000 0x100000>;
+ };
+ partition@500000 {
+ label = "dtb";
+ reg = <0x500000 0x100000>;
+ };
+ partition@600000 {
+ label = "linux";
+ reg = <0x600000 0xC00000>;
+ };
+ partition@1200000 {
+ label = "rootfs";
+ reg = <0x1200000 0x0>;
+ };
+ };
+
+ gmac0: eth@e2000000 {
+ phy-mode = "rgmii";
+ status = "okay";
+ };
+
+ sdhci@b3000000 {
+ status = "okay";
+ };
+
+ smi: flash@ea000000 {
+ status = "okay";
+ clock-rate=<50000000>;
+
+ flash@e6000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe6000000 0x800000>;
+ st,smi-fast-mode;
+
+ partition@0 {
+ label = "xloader";
+ reg = <0x0 0x10000>;
+ };
+ partition@10000 {
+ label = "u-boot";
+ reg = <0x10000 0x50000>;
+ };
+ partition@60000 {
+ label = "environment";
+ reg = <0x60000 0x10000>;
+ };
+ partition@70000 {
+ label = "dtb";
+ reg = <0x70000 0x10000>;
+ };
+ partition@80000 {
+ label = "linux";
+ reg = <0x80000 0x310000>;
+ };
+ partition@390000 {
+ label = "rootfs";
+ reg = <0x390000 0x0>;
+ };
+ };
+ };
+
+ ehci@e4800000 {
+ status = "okay";
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@1 {
+ label = "wakeup";
+ linux,code = <0x100>;
+ gpios = <&gpio1 1 0x4>;
+ debounce-interval = <20>;
+ gpio-key,wakeup = <1>;
+ };
+ };
+
+ ehci@e5800000 {
+ status = "okay";
+ };
+
+ i2s0: i2s-play@b2400000 {
+ status = "okay";
+ };
+
+ i2s1: i2s-rec@b2000000 {
+ status = "okay";
+ };
+
+ incodec: dir-hifi {
+ compatible = "dummy,dir-hifi";
+ status = "okay";
+ };
+
+ ohci@e4000000 {
+ status = "okay";
+ };
+
+ ohci@e5000000 {
+ status = "okay";
+ };
+
+ outcodec: dit-hifi {
+ compatible = "dummy,dit-hifi";
+ status = "okay";
+ };
+
+ sound {
+ compatible = "spear,spear-evb";
+ audio-controllers = <&spdif0 &spdif1 &i2s0 &i2s1>;
+ audio-codecs = <&incodec &outcodec &sta529 &sta529>;
+ codec_dai_name = "dir-hifi", "dit-hifi", "sta529-audio", "sta529-audio";
+ stream_name = "spdif-cap", "spdif-play", "i2s-play", "i2s-cap";
+ dai_name = "spdifin-pcm", "spdifout-pcm", "i2s0-pcm", "i2s1-pcm";
+ nr_controllers = <4>;
+ status = "okay";
+ };
+
+ spdif0: spdif-in@d0100000 {
+ status = "okay";
+ };
+
+ spdif1: spdif-out@d0000000 {
+ status = "okay";
+ };
+
+ apb {
+ adc@e0080000 {
+ status = "okay";
+ };
+
+ i2s-play@b2400000 {
+ status = "okay";
+ };
+
+ i2s-rec@b2000000 {
+ status = "okay";
+ };
+
+ gpio0: gpio@e0600000 {
+ status = "okay";
+ };
+
+ gpio1: gpio@e0680000 {
+ status = "okay";
+ };
+
+ gpio@e2800000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@e0280000 {
+ status = "okay";
+
+ sta529: sta529@1a {
+ compatible = "st,sta529";
+ reg = <0x1a>;
+ };
+ };
+
+ i2c1: i2c@b4000000 {
+ status = "okay";
+
+ eeprom0@56 {
+ compatible = "st,eeprom";
+ reg = <0x56>;
+ };
+
+ stmpe801@41 {
+ compatible = "st,stmpe801";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x41>;
+ interrupts = <4 0x4>;
+ interrupt-parent = <&gpio0>;
+ irq-trigger = <0x2>;
+
+ stmpegpio: stmpe_gpio {
+ compatible = "st,stmpe-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+ };
+
+ kbd@e0300000 {
+ linux,keymap = < 0x00000001
+ 0x00010002
+ 0x00020003
+ 0x00030004
+ 0x00040005
+ 0x00050006
+ 0x00060007
+ 0x00070008
+ 0x00080009
+ 0x0100000a
+ 0x0101000c
+ 0x0102000d
+ 0x0103000e
+ 0x0104000f
+ 0x01050010
+ 0x01060011
+ 0x01070012
+ 0x01080013
+ 0x02000014
+ 0x02010015
+ 0x02020016
+ 0x02030017
+ 0x02040018
+ 0x02050019
+ 0x0206001a
+ 0x0207001b
+ 0x0208001c
+ 0x0300001d
+ 0x0301001e
+ 0x0302001f
+ 0x03030020
+ 0x03040021
+ 0x03050022
+ 0x03060023
+ 0x03070024
+ 0x03080025
+ 0x04000026
+ 0x04010027
+ 0x04020028
+ 0x04030029
+ 0x0404002a
+ 0x0405002b
+ 0x0406002c
+ 0x0407002d
+ 0x0408002e
+ 0x0500002f
+ 0x05010030
+ 0x05020031
+ 0x05030032
+ 0x05040033
+ 0x05050034
+ 0x05060035
+ 0x05070036
+ 0x05080037
+ 0x06000038
+ 0x06010039
+ 0x0602003a
+ 0x0603003b
+ 0x0604003c
+ 0x0605003d
+ 0x0606003e
+ 0x0607003f
+ 0x06080040
+ 0x07000041
+ 0x07010042
+ 0x07020043
+ 0x07030044
+ 0x07040045
+ 0x07050046
+ 0x07060047
+ 0x07070048
+ 0x07080049
+ 0x0800004a
+ 0x0801004b
+ 0x0802004c
+ 0x0803004d
+ 0x0804004e
+ 0x0805004f
+ 0x08060050
+ 0x08070051
+ 0x08080052 >;
+ autorepeat;
+ st,mode = <0>;
+ suspended_rate = <2000000>;
+ status = "okay";
+ };
+
+ rtc@e0580000 {
+ status = "okay";
+ };
+
+ serial@e0000000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ serial@b4100000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ spi0: spi@e0100000 {
+ status = "okay";
+ num-cs = <3>;
+ cs-gpios = <&gpiopinctrl 80 0>, <&gpiopinctrl 24 0>,
+ <&gpiopinctrl 85 0>;
+
+ m25p80@0 {
+ compatible = "m25p80";
+ reg = <0>;
+ spi-max-frequency = <12000000>;
+ spi-cpol;
+ spi-cpha;
+ pl022,hierarchy = <0>;
+ pl022,interface = <0>;
+ pl022,slave-tx-disable;
+ pl022,com-mode = <0x2>;
+ pl022,rx-level-trig = <0>;
+ pl022,tx-level-trig = <0>;
+ pl022,ctrl-len = <0x11>;
+ pl022,wait-state = <0>;
+ pl022,duplex = <0>;
+ };
+
+ stmpe610@1 {
+ compatible = "st,stmpe610";
+ spi-max-frequency = <1000000>;
+ spi-cpha;
+ reg = <1>;
+ pl022,hierarchy = <0>;
+ pl022,interface = <0>;
+ pl022,slave-tx-disable;
+ pl022,com-mode = <0>;
+ pl022,rx-level-trig = <0>;
+ pl022,tx-level-trig = <0>;
+ pl022,ctrl-len = <0x7>;
+ pl022,wait-state = <0>;
+ pl022,duplex = <0>;
+ interrupts = <100 0>;
+ interrupt-parent = <&gpiopinctrl>;
+ irq-trigger = <0x2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ stmpe_touchscreen {
+ compatible = "st,stmpe-ts";
+ ts,sample-time = <4>;
+ ts,mod-12b = <1>;
+ ts,ref-sel = <0>;
+ ts,adc-freq = <1>;
+ ts,ave-ctrl = <1>;
+ ts,touch-det-delay = <2>;
+ ts,settling = <2>;
+ ts,fraction-z = <7>;
+ ts,i-drive = <1>;
+ };
+ };
+
+ spidev@2 {
+ compatible = "spidev";
+ reg = <2>;
+ spi-max-frequency = <25000000>;
+ spi-cpha;
+ pl022,hierarchy = <0>;
+ pl022,interface = <0>;
+ pl022,slave-tx-disable;
+ pl022,com-mode = <0x2>;
+ pl022,rx-level-trig = <0>;
+ pl022,tx-level-trig = <0>;
+ pl022,ctrl-len = <0x11>;
+ pl022,wait-state = <0>;
+ pl022,duplex = <0>;
+ };
+ };
+
+ timer@ec800600 {
+ status = "okay";
+ };
+
+ wdt@ec800620 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi
new file mode 100644
index 000000000..13e1aa33d
--- /dev/null
+++ b/arch/arm/boot/dts/spear1340.dtsi
@@ -0,0 +1,174 @@
+/*
+ * DTS file for all SPEAr1340 SoCs
+ *
+ * Copyright 2012 Viresh Kumar <viresh.linux@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/ "spear13xx.dtsi"
+
+/ {
+ compatible = "st,spear1340";
+
+ ahb {
+
+ spics: spics@e0700000{
+ compatible = "st,spear-spics-gpio";
+ reg = <0xe0700000 0x1000>;
+ st-spics,peripcfg-reg = <0x42c>;
+ st-spics,sw-enable-bit = <21>;
+ st-spics,cs-value-bit = <20>;
+ st-spics,cs-enable-mask = <3>;
+ st-spics,cs-enable-shift = <18>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ status = "disabled";
+ };
+
+ miphy0: miphy@eb800000 {
+ compatible = "st,spear1340-miphy";
+ reg = <0xeb800000 0x4000>;
+ misc = <&misc>;
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
+ ahci0: ahci@b1000000 {
+ compatible = "snps,spear-ahci";
+ reg = <0xb1000000 0x10000>;
+ interrupts = <0 72 0x4>;
+ phys = <&miphy0 0>;
+ phy-names = "sata-phy";
+ status = "disabled";
+ };
+
+ pcie0: pcie@b1000000 {
+ compatible = "st,spear1340-pcie", "snps,dw-pcie";
+ reg = <0xb1000000 0x4000>, <0x80000000 0x20000>;
+ reg-names = "dbi", "config";
+ interrupts = <0 68 0x4>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0x0 0 &gic 0 68 0x4>;
+ num-lanes = <1>;
+ phys = <&miphy0 1>;
+ phy-names = "pcie-phy";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x81000000 0 0 0x80020000 0 0x00010000 /* downstream I/O */
+ 0x82000000 0 0x80030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */
+ status = "disabled";
+ };
+
+ i2s-play@b2400000 {
+ compatible = "snps,designware-i2s";
+ reg = <0xb2400000 0x10000>;
+ interrupt-names = "play_irq";
+ interrupts = <0 98 0x4
+ 0 99 0x4>;
+ play;
+ channel = <8>;
+ status = "disabled";
+ };
+
+ i2s-rec@b2000000 {
+ compatible = "snps,designware-i2s";
+ reg = <0xb2000000 0x10000>;
+ interrupt-names = "record_irq";
+ interrupts = <0 100 0x4
+ 0 101 0x4>;
+ record;
+ channel = <8>;
+ status = "disabled";
+ };
+
+ pinmux: pinmux@e0700000 {
+ compatible = "st,spear1340-pinmux";
+ reg = <0xe0700000 0x1000>;
+ #gpio-range-cells = <3>;
+ };
+
+ pwm: pwm@e0180000 {
+ compatible ="st,spear13xx-pwm";
+ reg = <0xe0180000 0x1000>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ spdif-in@d0100000 {
+ compatible = "st,spdif-in";
+ reg = < 0xd0100000 0x20000
+ 0xd0110000 0x10000 >;
+ interrupts = <0 84 0x4>;
+ status = "disabled";
+ };
+
+ spdif-out@d0000000 {
+ compatible = "st,spdif-out";
+ reg = <0xd0000000 0x20000>;
+ interrupts = <0 85 0x4>;
+ status = "disabled";
+ };
+
+ spi1: spi@5d400000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x5d400000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 99 0x4>;
+ status = "disabled";
+ };
+
+ apb {
+ i2c1: i2c@b4000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xb4000000 0x1000>;
+ interrupts = <0 104 0x4>;
+ write-16bit;
+ status = "disabled";
+ };
+
+ serial@b4100000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xb4100000 0x1000>;
+ interrupts = <0 105 0x4>;
+ status = "disabled";
+ dmas = <&dwdma0 0x600 0 0 1>, /* 0xC << 11 */
+ <&dwdma0 0x680 0 1 0>; /* 0xD << 7 */
+ dma-names = "tx", "rx";
+ };
+
+ thermal@e07008c4 {
+ st,thermal-flags = <0x2a00>;
+ };
+
+ gpiopinctrl: gpio@e2800000 {
+ compatible = "st,spear-plgpio";
+ reg = <0xe2800000 0x1000>;
+ interrupts = <0 107 0x4>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinmux 0 0 252>;
+ status = "disabled";
+
+ st-plgpio,ngpio = <250>;
+ st-plgpio,wdata-reg = <0x40>;
+ st-plgpio,dir-reg = <0x00>;
+ st-plgpio,ie-reg = <0x80>;
+ st-plgpio,rdata-reg = <0x20>;
+ st-plgpio,mis-reg = <0xa0>;
+ st-plgpio,eit-reg = <0x60>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi
new file mode 100644
index 000000000..40accc87e
--- /dev/null
+++ b/arch/arm/boot/dts/spear13xx.dtsi
@@ -0,0 +1,343 @@
+/*
+ * DTS file for all SPEAr13xx SoCs
+ *
+ * Copyright 2012 Viresh Kumar <viresh.linux@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/ "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ gic: interrupt-controller@ec801000 {
+ compatible = "arm,cortex-a9-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = < 0xec801000 0x1000 >,
+ < 0xec800100 0x0100 >;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 6 0x04
+ 0 7 0x04>;
+ };
+
+ L2: l2-cache {
+ compatible = "arm,pl310-cache";
+ reg = <0xed000000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ memory {
+ name = "memory";
+ device_type = "memory";
+ reg = <0 0x40000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyAMA0,115200";
+ };
+
+ cpufreq {
+ compatible = "st,cpufreq-spear";
+ cpufreq_tbl = < 166000
+ 200000
+ 250000
+ 300000
+ 400000
+ 500000
+ 600000 >;
+ status = "disabled";
+ };
+
+ ahb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x50000000 0x50000000 0x10000000
+ 0x80000000 0x80000000 0x20000000
+ 0xb0000000 0xb0000000 0x22000000
+ 0xd8000000 0xd8000000 0x01000000
+ 0xe0000000 0xe0000000 0x10000000>;
+
+ sdhci@b3000000 {
+ compatible = "st,sdhci-spear";
+ reg = <0xb3000000 0x100>;
+ interrupts = <0 28 0x4>;
+ status = "disabled";
+ };
+
+ cf@b2800000 {
+ compatible = "arasan,cf-spear1340";
+ reg = <0xb2800000 0x1000>;
+ interrupts = <0 29 0x4>;
+ status = "disabled";
+ dmas = <&dwdma0 0 0 0 0>;
+ dma-names = "data";
+ };
+
+ dwdma0: dma@ea800000 {
+ compatible = "snps,dma-spear1340";
+ reg = <0xea800000 0x1000>;
+ interrupts = <0 19 0x4>;
+ status = "disabled";
+
+ dma-channels = <8>;
+ #dma-cells = <3>;
+ dma-requests = <32>;
+ chan_allocation_order = <1>;
+ chan_priority = <1>;
+ block_size = <0xfff>;
+ dma-masters = <2>;
+ data_width = <3 3>;
+ };
+
+ dma@eb000000 {
+ compatible = "snps,dma-spear1340";
+ reg = <0xeb000000 0x1000>;
+ interrupts = <0 59 0x4>;
+ status = "disabled";
+
+ dma-requests = <32>;
+ dma-channels = <8>;
+ dma-masters = <2>;
+ #dma-cells = <3>;
+ chan_allocation_order = <1>;
+ chan_priority = <1>;
+ block_size = <0xfff>;
+ data_width = <3 3>;
+ };
+
+ fsmc: flash@b0000000 {
+ compatible = "st,spear600-fsmc-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xb0000000 0x1000 /* FSMC Register*/
+ 0xb0800000 0x0010 /* NAND Base DATA */
+ 0xb0820000 0x0010 /* NAND Base ADDR */
+ 0xb0810000 0x0010>; /* NAND Base CMD */
+ reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
+ interrupts = <0 20 0x4
+ 0 21 0x4
+ 0 22 0x4
+ 0 23 0x4>;
+ st,mode = <2>;
+ status = "disabled";
+ };
+
+ gmac0: eth@e2000000 {
+ compatible = "st,spear600-gmac";
+ reg = <0xe2000000 0x8000>;
+ interrupts = <0 33 0x4
+ 0 34 0x4>;
+ interrupt-names = "macirq", "eth_wake_irq";
+ status = "disabled";
+ };
+
+ pcm {
+ compatible = "st,pcm-audio";
+ #address-cells = <0>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ smi: flash@ea000000 {
+ compatible = "st,spear600-smi";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xea000000 0x1000>;
+ interrupts = <0 30 0x4>;
+ status = "disabled";
+ };
+
+ ehci@e4800000 {
+ compatible = "st,spear600-ehci", "usb-ehci";
+ reg = <0xe4800000 0x1000>;
+ interrupts = <0 64 0x4>;
+ usbh0_id = <0>;
+ status = "disabled";
+ };
+
+ ehci@e5800000 {
+ compatible = "st,spear600-ehci", "usb-ehci";
+ reg = <0xe5800000 0x1000>;
+ interrupts = <0 66 0x4>;
+ usbh1_id = <1>;
+ status = "disabled";
+ };
+
+ ohci@e4000000 {
+ compatible = "st,spear600-ohci", "usb-ohci";
+ reg = <0xe4000000 0x1000>;
+ interrupts = <0 65 0x4>;
+ usbh0_id = <0>;
+ status = "disabled";
+ };
+
+ ohci@e5000000 {
+ compatible = "st,spear600-ohci", "usb-ohci";
+ reg = <0xe5000000 0x1000>;
+ interrupts = <0 67 0x4>;
+ usbh1_id = <1>;
+ status = "disabled";
+ };
+
+ apb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x50000000 0x50000000 0x10000000
+ 0xb0000000 0xb0000000 0x10000000
+ 0xd0000000 0xd0000000 0x02000000
+ 0xd8000000 0xd8000000 0x01000000
+ 0xe0000000 0xe0000000 0x10000000>;
+
+ misc: syscon@e0700000 {
+ compatible = "st,spear1340-misc", "syscon";
+ reg = <0xe0700000 0x1000>;
+ };
+
+ gpio0: gpio@e0600000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xe0600000 0x1000>;
+ interrupts = <0 24 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio1: gpio@e0680000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xe0680000 0x1000>;
+ interrupts = <0 25 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ kbd@e0300000 {
+ compatible = "st,spear300-kbd";
+ reg = <0xe0300000 0x1000>;
+ interrupts = <0 52 0x4>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@e0280000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xe0280000 0x1000>;
+ interrupts = <0 41 0x4>;
+ status = "disabled";
+ };
+
+ i2s@e0180000 {
+ compatible = "st,designware-i2s";
+ reg = <0xe0180000 0x1000>;
+ interrupt-names = "play_irq", "record_irq";
+ interrupts = <0 10 0x4
+ 0 11 0x4 >;
+ status = "disabled";
+ };
+
+ i2s@e0200000 {
+ compatible = "st,designware-i2s";
+ reg = <0xe0200000 0x1000>;
+ interrupt-names = "play_irq", "record_irq";
+ interrupts = <0 26 0x4
+ 0 53 0x4>;
+ status = "disabled";
+ };
+
+ spi0: spi@e0100000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0xe0100000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 31 0x4>;
+ status = "disabled";
+ dmas = <&dwdma0 0x2000 0 0 0>, /* 0x4 << 11 */
+ <&dwdma0 0x0280 0 0 0>; /* 0x5 << 7 */
+ dma-names = "tx", "rx";
+ };
+
+ rtc@e0580000 {
+ compatible = "st,spear600-rtc";
+ reg = <0xe0580000 0x1000>;
+ interrupts = <0 36 0x4>;
+ status = "disabled";
+ };
+
+ serial@e0000000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xe0000000 0x1000>;
+ interrupts = <0 35 0x4>;
+ status = "disabled";
+ };
+
+ adc@e0080000 {
+ compatible = "st,spear600-adc";
+ reg = <0xe0080000 0x1000>;
+ interrupts = <0 12 0x4>;
+ status = "disabled";
+ };
+
+ timer@e0380000 {
+ compatible = "st,spear-timer";
+ reg = <0xe0380000 0x400>;
+ interrupts = <0 37 0x4>;
+ };
+
+ timer@ec800600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xec800600 0x20>;
+ interrupts = <1 13 0x4>;
+ status = "disabled";
+ };
+
+ wdt@ec800620 {
+ compatible = "arm,cortex-a9-twd-wdt";
+ reg = <0xec800620 0x20>;
+ status = "disabled";
+ };
+
+ thermal@e07008c4 {
+ compatible = "st,thermal-spear1340";
+ reg = <0xe07008c4 0x4>;
+ thermal_flags = <0x7000>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear300-evb.dts b/arch/arm/boot/dts/spear300-evb.dts
new file mode 100644
index 000000000..5de143165
--- /dev/null
+++ b/arch/arm/boot/dts/spear300-evb.dts
@@ -0,0 +1,255 @@
+/*
+ * DTS file for SPEAr300 Evaluation Baord
+ *
+ * Copyright 2012 Viresh Kumar <viresh.linux@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
+ */
+
+/dts-v1/;
+/include/ "spear300.dtsi"
+
+/ {
+ model = "ST SPEAr300 Evaluation Board";
+ compatible = "st,spear300-evb", "st,spear300";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ memory {
+ reg = <0 0x40000000>;
+ };
+
+ ahb {
+ pinmux@99000000 {
+ st,pinmux-mode = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ i2c0 {
+ st,pins = "i2c0_grp";
+ st,function = "i2c0";
+ };
+ ssp0 {
+ st,pins = "ssp0_grp";
+ st,function = "ssp0";
+ };
+ mii0 {
+ st,pins = "mii0_grp";
+ st,function = "mii0";
+ };
+ uart0 {
+ st,pins = "uart0_grp";
+ st,function = "uart0";
+ };
+ clcd {
+ st,pins = "clcd_pfmode_grp";
+ st,function = "clcd";
+ };
+ sdhci {
+ st,pins = "sdhci_4bit_grp";
+ st,function = "sdhci";
+ };
+ gpio1 {
+ st,pins = "gpio1_4_to_7_grp",
+ "gpio1_0_to_3_grp";
+ st,function = "gpio1";
+ };
+ };
+ };
+
+ clcd@60000000 {
+ status = "okay";
+ };
+
+ dma@fc400000 {
+ status = "okay";
+ };
+
+ fsmc: flash@94000000 {
+ status = "okay";
+ };
+
+ gmac: eth@e0800000 {
+ status = "okay";
+ };
+
+ sdhci@70000000 {
+ cd-gpios = <&gpio1 0 0>;
+ status = "okay";
+ };
+
+ smi: flash@fc000000 {
+ status = "okay";
+ clock-rate=<50000000>;
+
+ flash@f8000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf8000000 0x800000>;
+ st,smi-fast-mode;
+
+ partition@0 {
+ label = "xloader";
+ reg = <0x0 0x10000>;
+ };
+ partition@10000 {
+ label = "u-boot";
+ reg = <0x10000 0x50000>;
+ };
+ partition@60000 {
+ label = "environment";
+ reg = <0x60000 0x10000>;
+ };
+ partition@70000 {
+ label = "dtb";
+ reg = <0x70000 0x10000>;
+ };
+ partition@80000 {
+ label = "linux";
+ reg = <0x80000 0x310000>;
+ };
+ partition@390000 {
+ label = "rootfs";
+ reg = <0x390000 0x0>;
+ };
+ };
+ };
+
+ spi0: spi@d0100000 {
+ status = "okay";
+ };
+
+ ehci@e1800000 {
+ status = "okay";
+ };
+
+ ohci@e1900000 {
+ status = "okay";
+ };
+
+ ohci@e2100000 {
+ status = "okay";
+ };
+
+ apb {
+ gpio0: gpio@fc980000 {
+ status = "okay";
+ };
+
+ gpio1: gpio@a9000000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@d0180000 {
+ status = "okay";
+ };
+
+ kbd@a0000000 {
+ linux,keymap = < 0x00000001
+ 0x00010002
+ 0x00020003
+ 0x00030004
+ 0x00040005
+ 0x00050006
+ 0x00060007
+ 0x00070008
+ 0x00080009
+ 0x0100000a
+ 0x0101000c
+ 0x0102000d
+ 0x0103000e
+ 0x0104000f
+ 0x01050010
+ 0x01060011
+ 0x01070012
+ 0x01080013
+ 0x02000014
+ 0x02010015
+ 0x02020016
+ 0x02030017
+ 0x02040018
+ 0x02050019
+ 0x0206001a
+ 0x0207001b
+ 0x0208001c
+ 0x0300001d
+ 0x0301001e
+ 0x0302001f
+ 0x03030020
+ 0x03040021
+ 0x03050022
+ 0x03060023
+ 0x03070024
+ 0x03080025
+ 0x04000026
+ 0x04010027
+ 0x04020028
+ 0x04030029
+ 0x0404002a
+ 0x0405002b
+ 0x0406002c
+ 0x0407002d
+ 0x0408002e
+ 0x0500002f
+ 0x05010030
+ 0x05020031
+ 0x05030032
+ 0x05040033
+ 0x05050034
+ 0x05060035
+ 0x05070036
+ 0x05080037
+ 0x06000038
+ 0x06010039
+ 0x0602003a
+ 0x0603003b
+ 0x0604003c
+ 0x0605003d
+ 0x0606003e
+ 0x0607003f
+ 0x06080040
+ 0x07000041
+ 0x07010042
+ 0x07020043
+ 0x07030044
+ 0x07040045
+ 0x07050046
+ 0x07060047
+ 0x07070048
+ 0x07080049
+ 0x0800004a
+ 0x0801004b
+ 0x0802004c
+ 0x0803004d
+ 0x0804004e
+ 0x0805004f
+ 0x08060050
+ 0x08070051
+ 0x08080052 >;
+ autorepeat;
+ st,mode = <0>;
+ status = "okay";
+ };
+
+ rtc@fc900000 {
+ status = "okay";
+ };
+
+ serial@d0000000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ wdt@fc880000 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear300.dtsi b/arch/arm/boot/dts/spear300.dtsi
new file mode 100644
index 000000000..f79b3dfaa
--- /dev/null
+++ b/arch/arm/boot/dts/spear300.dtsi
@@ -0,0 +1,89 @@
+/*
+ * DTS file for SPEAr300 SoC
+ *
+ * Copyright 2012 Viresh Kumar <viresh.linux@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/ "spear3xx.dtsi"
+
+/ {
+ ahb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x60000000 0x60000000 0x50000000
+ 0xd0000000 0xd0000000 0x30000000>;
+
+ pinmux@99000000 {
+ compatible = "st,spear300-pinmux";
+ reg = <0x99000000 0x1000>;
+ };
+
+ clcd@60000000 {
+ compatible = "arm,pl110", "arm,primecell";
+ reg = <0x60000000 0x1000>;
+ interrupts = <30>;
+ status = "disabled";
+ };
+
+ fsmc: flash@94000000 {
+ compatible = "st,spear600-fsmc-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x94000000 0x1000 /* FSMC Register */
+ 0x80000000 0x0010 /* NAND Base DATA */
+ 0x80020000 0x0010 /* NAND Base ADDR */
+ 0x80010000 0x0010>; /* NAND Base CMD */
+ reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
+ status = "disabled";
+ };
+
+ sdhci@70000000 {
+ compatible = "st,sdhci-spear";
+ reg = <0x70000000 0x100>;
+ interrupts = <1>;
+ status = "disabled";
+ };
+
+ shirq: interrupt-controller@0x50000000 {
+ compatible = "st,spear300-shirq";
+ reg = <0x50000000 0x1000>;
+ interrupts = <28>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+
+ apb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0xa0000000 0xa0000000 0x10000000
+ 0xd0000000 0xd0000000 0x30000000>;
+
+ gpio1: gpio@a9000000 {
+ #gpio-cells = <2>;
+ compatible = "arm,pl061", "arm,primecell";
+ gpio-controller;
+ reg = <0xa9000000 0x1000>;
+ interrupts = <8>;
+ interrupt-parent = <&shirq>;
+ status = "disabled";
+ };
+
+ kbd@a0000000 {
+ compatible = "st,spear300-kbd";
+ reg = <0xa0000000 0x1000>;
+ interrupts = <7>;
+ interrupt-parent = <&shirq>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear310-evb.dts b/arch/arm/boot/dts/spear310-evb.dts
new file mode 100644
index 000000000..b09632963
--- /dev/null
+++ b/arch/arm/boot/dts/spear310-evb.dts
@@ -0,0 +1,208 @@
+/*
+ * DTS file for SPEAr310 Evaluation Baord
+ *
+ * Copyright 2012 Viresh Kumar <viresh.linux@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
+ */
+
+/dts-v1/;
+/include/ "spear310.dtsi"
+
+/ {
+ model = "ST SPEAr310 Evaluation Board";
+ compatible = "st,spear310-evb", "st,spear310";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ memory {
+ reg = <0 0x40000000>;
+ };
+
+ ahb {
+ pinmux@b4000000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ gpio0 {
+ st,pins = "gpio0_pin0_grp",
+ "gpio0_pin1_grp",
+ "gpio0_pin2_grp",
+ "gpio0_pin3_grp",
+ "gpio0_pin4_grp",
+ "gpio0_pin5_grp";
+ st,function = "gpio0";
+ };
+ i2c0 {
+ st,pins = "i2c0_grp";
+ st,function = "i2c0";
+ };
+ mii0 {
+ st,pins = "mii0_grp";
+ st,function = "mii0";
+ };
+ ssp0 {
+ st,pins = "ssp0_grp";
+ st,function = "ssp0";
+ };
+ uart0 {
+ st,pins = "uart0_grp";
+ st,function = "uart0";
+ };
+ emi {
+ st,pins = "emi_cs_0_to_5_grp";
+ st,function = "emi";
+ };
+ fsmc {
+ st,pins = "fsmc_grp";
+ st,function = "fsmc";
+ };
+ uart1 {
+ st,pins = "uart1_grp";
+ st,function = "uart1";
+ };
+ uart2 {
+ st,pins = "uart2_grp";
+ st,function = "uart2";
+ };
+ uart3 {
+ st,pins = "uart3_grp";
+ st,function = "uart3";
+ };
+ uart4 {
+ st,pins = "uart4_grp";
+ st,function = "uart4";
+ };
+ uart5 {
+ st,pins = "uart5_grp";
+ st,function = "uart5";
+ };
+ };
+ };
+
+ dma@fc400000 {
+ status = "okay";
+ };
+
+ fsmc: flash@44000000 {
+ status = "okay";
+ };
+
+ gmac: eth@e0800000 {
+ status = "okay";
+ };
+
+ smi: flash@fc000000 {
+ status = "okay";
+ clock-rate=<50000000>;
+
+ flash@f8000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf8000000 0x800000>;
+ st,smi-fast-mode;
+
+ partition@0 {
+ label = "xloader";
+ reg = <0x0 0x10000>;
+ };
+ partition@10000 {
+ label = "u-boot";
+ reg = <0x10000 0x50000>;
+ };
+ partition@60000 {
+ label = "environment";
+ reg = <0x60000 0x10000>;
+ };
+ partition@70000 {
+ label = "dtb";
+ reg = <0x70000 0x10000>;
+ };
+ partition@80000 {
+ label = "linux";
+ reg = <0x80000 0x310000>;
+ };
+ partition@390000 {
+ label = "rootfs";
+ reg = <0x390000 0x0>;
+ };
+ };
+ };
+
+ spi0: spi@d0100000 {
+ status = "okay";
+ };
+
+ ehci@e1800000 {
+ status = "okay";
+ };
+
+ ohci@e1900000 {
+ status = "okay";
+ };
+
+ ohci@e2100000 {
+ status = "okay";
+ };
+
+ apb {
+ gpio0: gpio@fc980000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@d0180000 {
+ status = "okay";
+ };
+
+ rtc@fc900000 {
+ status = "okay";
+ };
+
+ serial@d0000000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ serial@b2000000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ serial@b2080000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ serial@b2100000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ serial@b2180000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ serial@b2200000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ wdt@fc880000 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi
new file mode 100644
index 000000000..95372080e
--- /dev/null
+++ b/arch/arm/boot/dts/spear310.dtsi
@@ -0,0 +1,118 @@
+/*
+ * DTS file for SPEAr310 SoC
+ *
+ * Copyright 2012 Viresh Kumar <viresh.linux@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/ "spear3xx.dtsi"
+
+/ {
+ ahb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x40000000 0x40000000 0x10000000
+ 0xb0000000 0xb0000000 0x10000000
+ 0xd0000000 0xd0000000 0x30000000>;
+
+ pinmux: pinmux@b4000000 {
+ compatible = "st,spear310-pinmux";
+ reg = <0xb4000000 0x1000>;
+ #gpio-range-cells = <3>;
+ };
+
+ fsmc: flash@44000000 {
+ compatible = "st,spear600-fsmc-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x44000000 0x1000 /* FSMC Register */
+ 0x40000000 0x0010 /* NAND Base DATA */
+ 0x40020000 0x0010 /* NAND Base ADDR */
+ 0x40010000 0x0010>; /* NAND Base CMD */
+ reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
+ status = "disabled";
+ };
+
+ shirq: interrupt-controller@0xb4000000 {
+ compatible = "st,spear310-shirq";
+ reg = <0xb4000000 0x1000>;
+ interrupts = <28 29 30 1>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+
+ apb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0xb0000000 0xb0000000 0x10000000
+ 0xd0000000 0xd0000000 0x30000000>;
+
+ serial@b2000000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xb2000000 0x1000>;
+ interrupts = <8>;
+ interrupt-parent = <&shirq>;
+ status = "disabled";
+ };
+
+ serial@b2080000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xb2080000 0x1000>;
+ interrupts = <9>;
+ interrupt-parent = <&shirq>;
+ status = "disabled";
+ };
+
+ serial@b2100000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xb2100000 0x1000>;
+ interrupts = <10>;
+ interrupt-parent = <&shirq>;
+ status = "disabled";
+ };
+
+ serial@b2180000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xb2180000 0x1000>;
+ interrupts = <11>;
+ interrupt-parent = <&shirq>;
+ status = "disabled";
+ };
+
+ serial@b2200000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xb2200000 0x1000>;
+ interrupts = <12>;
+ interrupt-parent = <&shirq>;
+ status = "disabled";
+ };
+
+ gpiopinctrl: gpio@b4000000 {
+ compatible = "st,spear-plgpio";
+ reg = <0xb4000000 0x1000>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinmux 0 0 102>;
+ status = "disabled";
+
+ st-plgpio,ngpio = <102>;
+ st-plgpio,enb-reg = <0x10>;
+ st-plgpio,wdata-reg = <0x20>;
+ st-plgpio,dir-reg = <0x30>;
+ st-plgpio,ie-reg = <0x50>;
+ st-plgpio,rdata-reg = <0x40>;
+ st-plgpio,mis-reg = <0x60>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear320-evb.dts b/arch/arm/boot/dts/spear320-evb.dts
new file mode 100644
index 000000000..fdedbb514
--- /dev/null
+++ b/arch/arm/boot/dts/spear320-evb.dts
@@ -0,0 +1,207 @@
+/*
+ * DTS file for SPEAr320 Evaluation Baord
+ *
+ * Copyright 2012 Viresh Kumar <viresh.linux@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
+ */
+
+/dts-v1/;
+/include/ "spear320.dtsi"
+
+/ {
+ model = "ST SPEAr320 Evaluation Board";
+ compatible = "st,spear320-evb", "st,spear320";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ memory {
+ reg = <0 0x40000000>;
+ };
+
+ ahb {
+ pinmux@b3000000 {
+ st,pinmux-mode = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ i2c0 {
+ st,pins = "i2c0_grp";
+ st,function = "i2c0";
+ };
+ mii0 {
+ st,pins = "mii0_grp";
+ st,function = "mii0";
+ };
+ ssp0 {
+ st,pins = "ssp0_grp";
+ st,function = "ssp0";
+ };
+ uart0 {
+ st,pins = "uart0_grp";
+ st,function = "uart0";
+ };
+ sdhci {
+ st,pins = "sdhci_cd_51_grp";
+ st,function = "sdhci";
+ };
+ i2s {
+ st,pins = "i2s_grp";
+ st,function = "i2s";
+ };
+ uart1 {
+ st,pins = "uart1_grp";
+ st,function = "uart1";
+ };
+ uart2 {
+ st,pins = "uart2_grp";
+ st,function = "uart2";
+ };
+ can0 {
+ st,pins = "can0_grp";
+ st,function = "can0";
+ };
+ can1 {
+ st,pins = "can1_grp";
+ st,function = "can1";
+ };
+ mii2 {
+ st,pins = "mii2_grp";
+ st,function = "mii2";
+ };
+ pwm0_1 {
+ st,pins = "pwm0_1_pin_37_38_grp";
+ st,function = "pwm0_1";
+ };
+ };
+ };
+
+ dma@fc400000 {
+ status = "okay";
+ };
+
+ fsmc: flash@4c000000 {
+ status = "okay";
+ };
+
+ gmac: eth@e0800000 {
+ status = "okay";
+ };
+
+ sdhci@70000000 {
+ power-gpio = <&gpiopinctrl 61 1>;
+ status = "okay";
+ };
+
+ smi: flash@fc000000 {
+ status = "okay";
+ clock-rate=<50000000>;
+
+ flash@f8000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf8000000 0x800000>;
+ st,smi-fast-mode;
+
+ partition@0 {
+ label = "xloader";
+ reg = <0x0 0x10000>;
+ };
+ partition@10000 {
+ label = "u-boot";
+ reg = <0x10000 0x50000>;
+ };
+ partition@60000 {
+ label = "environment";
+ reg = <0x60000 0x10000>;
+ };
+ partition@70000 {
+ label = "dtb";
+ reg = <0x70000 0x10000>;
+ };
+ partition@80000 {
+ label = "linux";
+ reg = <0x80000 0x310000>;
+ };
+ partition@390000 {
+ label = "rootfs";
+ reg = <0x390000 0x0>;
+ };
+ };
+ };
+
+ spi0: spi@d0100000 {
+ status = "okay";
+ };
+
+ spi1: spi@a5000000 {
+ status = "okay";
+ };
+
+ spi2: spi@a6000000 {
+ status = "okay";
+ };
+
+ ehci@e1800000 {
+ status = "okay";
+ };
+
+ ohci@e1900000 {
+ status = "okay";
+ };
+
+ ohci@e2100000 {
+ status = "okay";
+ };
+
+ apb {
+ gpio0: gpio@fc980000 {
+ status = "okay";
+ };
+
+ gpio@b3000000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@d0180000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@a7000000 {
+ status = "okay";
+ };
+
+ rtc@fc900000 {
+ status = "okay";
+ };
+
+ serial@d0000000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ serial@a3000000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ serial@a4000000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ wdt@fc880000 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear320-hmi.dts b/arch/arm/boot/dts/spear320-hmi.dts
new file mode 100644
index 000000000..0aa6fef5c
--- /dev/null
+++ b/arch/arm/boot/dts/spear320-hmi.dts
@@ -0,0 +1,305 @@
+/*
+ * DTS file for SPEAr320 Evaluation Baord
+ *
+ * Copyright 2012 Shiraz Hashim <shiraz.linux.kernel@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
+ */
+
+/dts-v1/;
+/include/ "spear320.dtsi"
+
+/ {
+ model = "ST SPEAr320 HMI Board";
+ compatible = "st,spear320-hmi", "st,spear320";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ memory {
+ reg = <0 0x40000000>;
+ };
+
+ ahb {
+ pinmux@b3000000 {
+ st,pinmux-mode = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ i2c0 {
+ st,pins = "i2c0_grp";
+ st,function = "i2c0";
+ };
+ ssp0 {
+ st,pins = "ssp0_grp";
+ st,function = "ssp0";
+ };
+ uart0 {
+ st,pins = "uart0_grp";
+ st,function = "uart0";
+ };
+ clcd {
+ st,pins = "clcd_grp";
+ st,function = "clcd";
+ };
+ fsmc {
+ st,pins = "fsmc_8bit_grp";
+ st,function = "fsmc";
+ };
+ sdhci {
+ st,pins = "sdhci_cd_12_grp";
+ st,function = "sdhci";
+ };
+ i2s {
+ st,pins = "i2s_grp";
+ st,function = "i2s";
+ };
+ uart1 {
+ st,pins = "uart1_grp";
+ st,function = "uart1";
+ };
+ uart2 {
+ st,pins = "uart2_grp";
+ st,function = "uart2";
+ };
+ can0 {
+ st,pins = "can0_grp";
+ st,function = "can0";
+ };
+ can1 {
+ st,pins = "can1_grp";
+ st,function = "can1";
+ };
+ mii0_1 {
+ st,pins = "rmii0_1_grp";
+ st,function = "mii0_1";
+ };
+ pwm0_1 {
+ st,pins = "pwm0_1_pin_37_38_grp";
+ st,function = "pwm0_1";
+ };
+ pwm2 {
+ st,pins = "pwm2_pin_34_grp";
+ st,function = "pwm2";
+ };
+ };
+ };
+
+ clcd@90000000 {
+ status = "okay";
+ };
+
+ dma@fc400000 {
+ status = "okay";
+ };
+
+ ehci@e1800000 {
+ status = "okay";
+ };
+
+ fsmc: flash@4c000000 {
+ status = "okay";
+
+ partition@0 {
+ label = "xloader";
+ reg = <0x0 0x80000>;
+ };
+ partition@80000 {
+ label = "u-boot";
+ reg = <0x80000 0x140000>;
+ };
+ partition@1C0000 {
+ label = "environment";
+ reg = <0x1C0000 0x40000>;
+ };
+ partition@200000 {
+ label = "dtb";
+ reg = <0x200000 0x40000>;
+ };
+ partition@240000 {
+ label = "linux";
+ reg = <0x240000 0xC00000>;
+ };
+ partition@E40000 {
+ label = "rootfs";
+ reg = <0xE40000 0x0>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@1 {
+ label = "user button 1";
+ linux,code = <0x100>;
+ gpios = <&stmpegpio 3 0x4>;
+ debounce-interval = <20>;
+ gpio-key,wakeup = <1>;
+ };
+
+ button@2 {
+ label = "user button 2";
+ linux,code = <0x200>;
+ gpios = <&stmpegpio 2 0x4>;
+ debounce-interval = <20>;
+ gpio-key,wakeup = <1>;
+ };
+ };
+
+ ohci@e1900000 {
+ status = "okay";
+ };
+
+ ohci@e2100000 {
+ status = "okay";
+ };
+
+ pwm: pwm@a8000000 {
+ status = "okay";
+ };
+
+ sdhci@70000000 {
+ power-gpio = <&gpiopinctrl 50 1>;
+ power_always_enb;
+ status = "okay";
+ };
+
+ smi: flash@fc000000 {
+ status = "okay";
+ clock-rate=<50000000>;
+
+ flash@f8000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf8000000 0x800000>;
+ st,smi-fast-mode;
+
+ partition@0 {
+ label = "xloader";
+ reg = <0x0 0x10000>;
+ };
+ partition@10000 {
+ label = "u-boot";
+ reg = <0x10000 0x50000>;
+ };
+ partition@60000 {
+ label = "environment";
+ reg = <0x60000 0x10000>;
+ };
+ partition@70000 {
+ label = "dtb";
+ reg = <0x70000 0x10000>;
+ };
+ partition@80000 {
+ label = "linux";
+ reg = <0x80000 0x310000>;
+ };
+ partition@390000 {
+ label = "rootfs";
+ reg = <0x390000 0x0>;
+ };
+ };
+ };
+
+ spi0: spi@d0100000 {
+ status = "okay";
+ };
+
+ spi1: spi@a5000000 {
+ status = "okay";
+ };
+
+ spi2: spi@a6000000 {
+ status = "okay";
+ };
+
+ usbd@e1100000 {
+ status = "okay";
+ };
+
+ apb {
+ gpio0: gpio@fc980000 {
+ status = "okay";
+ };
+
+ gpio@b3000000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@d0180000 {
+ status = "okay";
+
+ stmpe811@41 {
+ compatible = "st,stmpe811";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x41>;
+ irq-over-gpio;
+ irq-gpios = <&gpiopinctrl 29 0x4>;
+ id = <0>;
+ blocks = <0x5>;
+ irq-trigger = <0x1>;
+
+ stmpegpio: stmpe-gpio {
+ compatible = "stmpe,gpio";
+ reg = <0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio,norequest-mask = <0xF3>;
+ };
+
+ stmpe610-ts {
+ compatible = "stmpe,ts";
+ reg = <0>;
+ ts,sample-time = <4>;
+ ts,mod-12b = <1>;
+ ts,ref-sel = <0>;
+ ts,adc-freq = <1>;
+ ts,ave-ctrl = <1>;
+ ts,touch-det-delay = <3>;
+ ts,settling = <4>;
+ ts,fraction-z = <7>;
+ ts,i-drive = <1>;
+ };
+ };
+ };
+
+ i2c1: i2c@a7000000 {
+ status = "okay";
+ };
+
+ rtc@fc900000 {
+ status = "okay";
+ };
+
+ serial@d0000000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ serial@a3000000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ serial@a4000000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ wdt@fc880000 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi
new file mode 100644
index 000000000..ffea342ae
--- /dev/null
+++ b/arch/arm/boot/dts/spear320.dtsi
@@ -0,0 +1,147 @@
+/*
+ * DTS file for SPEAr320 SoC
+ *
+ * Copyright 2012 Viresh Kumar <viresh.linux@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/ "spear3xx.dtsi"
+
+/ {
+ ahb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x40000000 0x40000000 0x80000000
+ 0xd0000000 0xd0000000 0x30000000>;
+
+ pinmux: pinmux@b3000000 {
+ compatible = "st,spear320-pinmux";
+ reg = <0xb3000000 0x1000>;
+ #gpio-range-cells = <3>;
+ };
+
+ clcd@90000000 {
+ compatible = "arm,pl110", "arm,primecell";
+ reg = <0x90000000 0x1000>;
+ interrupts = <8>;
+ interrupt-parent = <&shirq>;
+ status = "disabled";
+ };
+
+ fsmc: flash@4c000000 {
+ compatible = "st,spear600-fsmc-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x4c000000 0x1000 /* FSMC Register */
+ 0x50000000 0x0010 /* NAND Base DATA */
+ 0x50020000 0x0010 /* NAND Base ADDR */
+ 0x50010000 0x0010>; /* NAND Base CMD */
+ reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
+ status = "disabled";
+ };
+
+ sdhci@70000000 {
+ compatible = "st,sdhci-spear";
+ reg = <0x70000000 0x100>;
+ interrupts = <10>;
+ interrupt-parent = <&shirq>;
+ status = "disabled";
+ };
+
+ shirq: interrupt-controller@0xb3000000 {
+ compatible = "st,spear320-shirq";
+ reg = <0xb3000000 0x1000>;
+ interrupts = <30 28 29 1>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+
+ spi1: spi@a5000000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0xa5000000 0x1000>;
+ interrupts = <15>;
+ interrupt-parent = <&shirq>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi2: spi@a6000000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0xa6000000 0x1000>;
+ interrupts = <16>;
+ interrupt-parent = <&shirq>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ pwm: pwm@a8000000 {
+ compatible ="st,spear-pwm";
+ reg = <0xa8000000 0x1000>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ apb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0xa0000000 0xa0000000 0x20000000
+ 0xd0000000 0xd0000000 0x30000000>;
+
+ i2c1: i2c@a7000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xa7000000 0x1000>;
+ interrupts = <21>;
+ interrupt-parent = <&shirq>;
+ status = "disabled";
+ };
+
+ serial@a3000000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xa3000000 0x1000>;
+ interrupts = <13>;
+ interrupt-parent = <&shirq>;
+ status = "disabled";
+ };
+
+ serial@a4000000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xa4000000 0x1000>;
+ interrupts = <14>;
+ interrupt-parent = <&shirq>;
+ status = "disabled";
+ };
+
+ gpiopinctrl: gpio@b3000000 {
+ compatible = "st,spear-plgpio";
+ reg = <0xb3000000 0x1000>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinmux 0 0 102>;
+ status = "disabled";
+
+ st-plgpio,ngpio = <102>;
+ st-plgpio,enb-reg = <0x24>;
+ st-plgpio,wdata-reg = <0x34>;
+ st-plgpio,dir-reg = <0x44>;
+ st-plgpio,ie-reg = <0x64>;
+ st-plgpio,rdata-reg = <0x54>;
+ st-plgpio,mis-reg = <0x84>;
+ st-plgpio,eit-reg = <0x94>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear3xx.dtsi b/arch/arm/boot/dts/spear3xx.dtsi
new file mode 100644
index 000000000..f0e3fcf8e
--- /dev/null
+++ b/arch/arm/boot/dts/spear3xx.dtsi
@@ -0,0 +1,157 @@
+/*
+ * DTS file for all SPEAr3xx SoCs
+ *
+ * Copyright 2012 Viresh Kumar <viresh.linux@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/ "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&vic>;
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm926ej-s";
+ device_type = "cpu";
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x40000000>;
+ };
+
+ ahb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0xd0000000 0xd0000000 0x30000000>;
+
+ vic: interrupt-controller@f1100000 {
+ compatible = "arm,pl190-vic";
+ interrupt-controller;
+ reg = <0xf1100000 0x1000>;
+ #interrupt-cells = <1>;
+ };
+
+ dma@fc400000 {
+ compatible = "arm,pl080", "arm,primecell";
+ reg = <0xfc400000 0x1000>;
+ interrupt-parent = <&vic>;
+ interrupts = <8>;
+ status = "disabled";
+ };
+
+ gmac: eth@e0800000 {
+ compatible = "st,spear600-gmac";
+ reg = <0xe0800000 0x8000>;
+ interrupts = <23 22>;
+ interrupt-names = "macirq", "eth_wake_irq";
+ phy-mode = "mii";
+ status = "disabled";
+ };
+
+ smi: flash@fc000000 {
+ compatible = "st,spear600-smi";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xfc000000 0x1000>;
+ interrupts = <9>;
+ status = "disabled";
+ };
+
+ spi0: spi@d0100000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0xd0100000 0x1000>;
+ interrupts = <20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ ehci@e1800000 {
+ compatible = "st,spear600-ehci", "usb-ehci";
+ reg = <0xe1800000 0x1000>;
+ interrupts = <26>;
+ status = "disabled";
+ };
+
+ ohci@e1900000 {
+ compatible = "st,spear600-ohci", "usb-ohci";
+ reg = <0xe1900000 0x1000>;
+ interrupts = <25>;
+ status = "disabled";
+ };
+
+ ohci@e2100000 {
+ compatible = "st,spear600-ohci", "usb-ohci";
+ reg = <0xe2100000 0x1000>;
+ interrupts = <27>;
+ status = "disabled";
+ };
+
+ apb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0xd0000000 0xd0000000 0x30000000>;
+
+ gpio0: gpio@fc980000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc980000 0x1000>;
+ interrupts = <11>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@d0180000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xd0180000 0x1000>;
+ interrupts = <21>;
+ status = "disabled";
+ };
+
+ rtc@fc900000 {
+ compatible = "st,spear600-rtc";
+ reg = <0xfc900000 0x1000>;
+ interrupts = <10>;
+ status = "disabled";
+ };
+
+ serial@d0000000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xd0000000 0x1000>;
+ interrupts = <19>;
+ status = "disabled";
+ };
+
+ wdt@fc880000 {
+ compatible = "arm,sp805", "arm,primecell";
+ reg = <0xfc880000 0x1000>;
+ interrupts = <12>;
+ status = "disabled";
+ };
+
+ timer@f0000000 {
+ compatible = "st,spear-timer";
+ reg = <0xf0000000 0x400>;
+ interrupts = <2>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear600-evb.dts b/arch/arm/boot/dts/spear600-evb.dts
new file mode 100644
index 000000000..d865a8917
--- /dev/null
+++ b/arch/arm/boot/dts/spear600-evb.dts
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2012 Stefan Roese <sr@denx.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
+ */
+
+/dts-v1/;
+/include/ "spear600.dtsi"
+
+/ {
+ model = "ST SPEAr600 Evaluation Board";
+ compatible = "st,spear600-evb", "st,spear600";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x10000000>;
+ };
+
+ ahb {
+ clcd@fc200000 {
+ status = "okay";
+ };
+
+ dma@fc400000 {
+ status = "okay";
+ };
+
+ ehci@e1800000 {
+ status = "okay";
+ };
+
+ ehci@e2000000 {
+ status = "okay";
+ };
+
+ gmac: ethernet@e0800000 {
+ phy-mode = "gmii";
+ status = "okay";
+ };
+
+ ohci@e1900000 {
+ status = "okay";
+ };
+
+ ohci@e2100000 {
+ status = "okay";
+ };
+
+ smi: flash@fc000000 {
+ status = "okay";
+ clock-rate=<50000000>;
+
+ flash@f8000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf8000000 0x800000>;
+ st,smi-fast-mode;
+
+ partition@0 {
+ label = "xloader";
+ reg = <0x0 0x10000>;
+ };
+ partition@10000 {
+ label = "u-boot";
+ reg = <0x10000 0x50000>;
+ };
+ partition@60000 {
+ label = "environment";
+ reg = <0x60000 0x10000>;
+ };
+ partition@70000 {
+ label = "dtb";
+ reg = <0x70000 0x10000>;
+ };
+ partition@80000 {
+ label = "linux";
+ reg = <0x80000 0x310000>;
+ };
+ partition@390000 {
+ label = "rootfs";
+ reg = <0x390000 0x0>;
+ };
+ };
+ };
+
+ apb {
+ serial@d0000000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ serial@d0080000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <>;
+ };
+
+ rtc@fc900000 {
+ status = "okay";
+ };
+
+ i2c@d0200000 {
+ clock-frequency = <400000>;
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi
new file mode 100644
index 000000000..9f60a7b6a
--- /dev/null
+++ b/arch/arm/boot/dts/spear600.dtsi
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2012 Stefan Roese <sr@denx.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
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "st,spear600";
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm926ej-s";
+ device_type = "cpu";
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x40000000>;
+ };
+
+ ahb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0xd0000000 0xd0000000 0x30000000>;
+
+ vic0: interrupt-controller@f1100000 {
+ compatible = "arm,pl190-vic";
+ interrupt-controller;
+ reg = <0xf1100000 0x1000>;
+ #interrupt-cells = <1>;
+ };
+
+ vic1: interrupt-controller@f1000000 {
+ compatible = "arm,pl190-vic";
+ interrupt-controller;
+ reg = <0xf1000000 0x1000>;
+ #interrupt-cells = <1>;
+ };
+
+ clcd@fc200000 {
+ compatible = "arm,pl110", "arm,primecell";
+ reg = <0xfc200000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <12>;
+ status = "disabled";
+ };
+
+ dma@fc400000 {
+ compatible = "arm,pl080", "arm,primecell";
+ reg = <0xfc400000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <10>;
+ status = "disabled";
+ };
+
+ gmac: ethernet@e0800000 {
+ compatible = "st,spear600-gmac";
+ reg = <0xe0800000 0x8000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <24 23>;
+ interrupt-names = "macirq", "eth_wake_irq";
+ phy-mode = "gmii";
+ status = "disabled";
+ };
+
+ fsmc: flash@d1800000 {
+ compatible = "st,spear600-fsmc-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd1800000 0x1000 /* FSMC Register */
+ 0xd2000000 0x0010 /* NAND Base DATA */
+ 0xd2020000 0x0010 /* NAND Base ADDR */
+ 0xd2010000 0x0010>; /* NAND Base CMD */
+ reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
+ status = "disabled";
+ };
+
+ smi: flash@fc000000 {
+ compatible = "st,spear600-smi";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xfc000000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <12>;
+ status = "disabled";
+ };
+
+ ehci@e1800000 {
+ compatible = "st,spear600-ehci", "usb-ehci";
+ reg = <0xe1800000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <27>;
+ status = "disabled";
+ };
+
+ ehci@e2000000 {
+ compatible = "st,spear600-ehci", "usb-ehci";
+ reg = <0xe2000000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <29>;
+ status = "disabled";
+ };
+
+ ohci@e1900000 {
+ compatible = "st,spear600-ohci", "usb-ohci";
+ reg = <0xe1900000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <26>;
+ status = "disabled";
+ };
+
+ ohci@e2100000 {
+ compatible = "st,spear600-ohci", "usb-ohci";
+ reg = <0xe2100000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <28>;
+ status = "disabled";
+ };
+
+ apb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0xd0000000 0xd0000000 0x30000000>;
+
+ serial@d0000000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xd0000000 0x1000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <24>;
+ status = "disabled";
+ };
+
+ serial@d0080000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xd0080000 0x1000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <25>;
+ status = "disabled";
+ };
+
+ /* local/cpu GPIO */
+ gpio0: gpio@f0100000 {
+ #gpio-cells = <2>;
+ compatible = "arm,pl061", "arm,primecell";
+ gpio-controller;
+ reg = <0xf0100000 0x1000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <18>;
+ };
+
+ /* basic GPIO */
+ gpio1: gpio@fc980000 {
+ #gpio-cells = <2>;
+ compatible = "arm,pl061", "arm,primecell";
+ gpio-controller;
+ reg = <0xfc980000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <19>;
+ };
+
+ /* appl GPIO */
+ gpio2: gpio@d8100000 {
+ #gpio-cells = <2>;
+ compatible = "arm,pl061", "arm,primecell";
+ gpio-controller;
+ reg = <0xd8100000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <4>;
+ };
+
+ i2c@d0200000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xd0200000 0x1000>;
+ interrupt-parent = <&vic0>;
+ interrupts = <28>;
+ status = "disabled";
+ };
+
+ rtc@fc900000 {
+ compatible = "st,spear600-rtc";
+ reg = <0xfc900000 0x1000>;
+ interrupts = <10>;
+ status = "disabled";
+ };
+
+ timer@f0000000 {
+ compatible = "st,spear-timer";
+ reg = <0xf0000000 0x400>;
+ interrupt-parent = <&vic0>;
+ interrupts = <16>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/st-pincfg.h b/arch/arm/boot/dts/st-pincfg.h
new file mode 100644
index 000000000..4851c387d
--- /dev/null
+++ b/arch/arm/boot/dts/st-pincfg.h
@@ -0,0 +1,71 @@
+#ifndef _ST_PINCFG_H_
+#define _ST_PINCFG_H_
+
+/* Alternate functions */
+#define ALT1 1
+#define ALT2 2
+#define ALT3 3
+#define ALT4 4
+#define ALT5 5
+#define ALT6 6
+#define ALT7 7
+
+/* Output enable */
+#define OE (1 << 27)
+/* Pull Up */
+#define PU (1 << 26)
+/* Open Drain */
+#define OD (1 << 25)
+#define RT (1 << 23)
+#define INVERTCLK (1 << 22)
+#define CLKNOTDATA (1 << 21)
+#define DOUBLE_EDGE (1 << 20)
+#define CLK_A (0 << 18)
+#define CLK_B (1 << 18)
+#define CLK_C (2 << 18)
+#define CLK_D (3 << 18)
+
+/* User-frendly defines for Pin Direction */
+ /* oe = 0, pu = 0, od = 0 */
+#define IN (0)
+ /* oe = 0, pu = 1, od = 0 */
+#define IN_PU (PU)
+ /* oe = 1, pu = 0, od = 0 */
+#define OUT (OE)
+ /* oe = 1, pu = 0, od = 1 */
+#define BIDIR (OE | OD)
+ /* oe = 1, pu = 1, od = 1 */
+#define BIDIR_PU (OE | PU | OD)
+
+/* RETIME_TYPE */
+/*
+ * B Mode
+ * Bypass retime with optional delay parameter
+ */
+#define BYPASS (0)
+/*
+ * R0, R1, R0D, R1D modes
+ * single-edge data non inverted clock, retime data with clk
+ */
+#define SE_NICLK_IO (RT)
+/*
+ * RIV0, RIV1, RIV0D, RIV1D modes
+ * single-edge data inverted clock, retime data with clk
+ */
+#define SE_ICLK_IO (RT | INVERTCLK)
+/*
+ * R0E, R1E, R0ED, R1ED modes
+ * double-edge data, retime data with clk
+ */
+#define DE_IO (RT | DOUBLE_EDGE)
+/*
+ * CIV0, CIV1 modes with inverted clock
+ * Retiming the clk pins will park clock & reduce the noise within the core.
+ */
+#define ICLK (RT | CLKNOTDATA | INVERTCLK)
+/*
+ * CLK0, CLK1 modes with non-inverted clock
+ * Retiming the clk pins will park clock & reduce the noise within the core.
+ */
+#define NICLK (RT | CLKNOTDATA)
+#endif /* _ST_PINCFG_H_ */
diff --git a/arch/arm/boot/dts/ste-ccu8540-pinctrl.dtsi b/arch/arm/boot/dts/ste-ccu8540-pinctrl.dtsi
new file mode 100644
index 000000000..52dba2e39
--- /dev/null
+++ b/arch/arm/boot/dts/ste-ccu8540-pinctrl.dtsi
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2012 ST-Ericsson
+ *
+ * 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 "ste-nomadik-pinctrl.dtsi"
+
+/ {
+ soc {
+ pinctrl {
+ uart0 {
+ uart0_default_mux: uart0_mux {
+ default_mux {
+ function = "u0";
+ groups = "u0_a_1";
+ };
+ };
+
+ uart0_default_mode: uart0_default {
+ default_cfg1 {
+ pins = "GPIO0", "GPIO2";
+ ste,config = <&in_pu>;
+ };
+
+ default_cfg2 {
+ pins = "GPIO1", "GPIO3";
+ ste,config = <&out_hi>;
+ };
+ };
+
+ uart0_sleep_mode: uart0_sleep {
+ sleep_cfg1 {
+ pins = "GPIO0", "GPIO2";
+ ste,config = <&slpm_in_pu>;
+ };
+
+ sleep_cfg2 {
+ pins = "GPIO1", "GPIO3";
+ ste,config = <&slpm_out_hi>;
+ };
+ };
+ };
+
+ uart2 {
+ uart2_default_mode: uart2_default {
+ default_mux {
+ function = "u2";
+ groups = "u2txrx_a_1";
+ };
+
+ default_cfg1 {
+ pins = "GPIO120";
+ ste,config = <&in_pu>;
+ };
+
+ default_cfg2 {
+ pins = "GPIO121";
+ ste,config = <&out_hi>;
+ };
+ };
+
+ uart2_sleep_mode: uart2_sleep {
+ sleep_cfg1 {
+ pins = "GPIO120";
+ ste,config = <&slpm_in_pu>;
+ };
+
+ sleep_cfg2 {
+ pins = "GPIO121";
+ ste,config = <&slpm_out_hi>;
+ };
+ };
+ };
+
+ i2c0 {
+ i2c0_default_mux: i2c_mux {
+ default_mux {
+ function = "i2c0";
+ groups = "i2c0_a_1";
+ };
+ };
+
+ i2c0_default_mode: i2c_default {
+ default_cfg1 {
+ pins = "GPIO147", "GPIO148";
+ ste,config = <&in_pu>;
+ };
+ };
+
+ i2c0_sleep_mode: i2c_sleep {
+ sleep_cfg1 {
+ pins = "GPIO147", "GPIO148";
+ ste,config = <&slpm_in_pu>;
+ };
+ };
+ };
+
+ i2c1 {
+ i2c1_default_mux: i2c_mux {
+ default_mux {
+ function = "i2c1";
+ groups = "i2c1_b_2";
+ };
+ };
+
+ i2c1_default_mode: i2c_default {
+ default_cfg1 {
+ pins = "GPIO16", "GPIO17";
+ ste,config = <&in_pu>;
+ };
+ };
+
+ i2c1_sleep_mode: i2c_sleep {
+ sleep_cfg1 {
+ pins = "GPIO16", "GPIO17";
+ ste,config = <&slpm_in_pu>;
+ };
+ };
+ };
+
+ i2c2 {
+ i2c2_default_mux: i2c_mux {
+ default_mux {
+ function = "i2c2";
+ groups = "i2c2_b_2";
+ };
+ };
+
+ i2c2_default_mode: i2c_default {
+ default_cfg1 {
+ pins = "GPIO10", "GPIO11";
+ ste,config = <&in_pu>;
+ };
+ };
+
+ i2c2_sleep_mode: i2c_sleep {
+ sleep_cfg1 {
+ pins = "GPIO11", "GPIO11";
+ ste,config = <&slpm_in_pu>;
+ };
+ };
+ };
+
+ i2c4 {
+ i2c4_default_mux: i2c_mux {
+ default_mux {
+ function = "i2c4";
+ groups = "i2c4_b_2";
+ };
+ };
+
+ i2c4_default_mode: i2c_default {
+ default_cfg1 {
+ pins = "GPIO122", "GPIO123";
+ ste,config = <&in_pu>;
+ };
+ };
+
+ i2c4_sleep_mode: i2c_sleep {
+ sleep_cfg1 {
+ pins = "GPIO122", "GPIO123";
+ ste,config = <&slpm_in_pu>;
+ };
+ };
+ };
+
+ i2c5 {
+ i2c5_default_mux: i2c_mux {
+ default_mux {
+ function = "i2c5";
+ groups = "i2c5_c_2";
+ };
+ };
+
+ i2c5_default_mode: i2c_default {
+ default_cfg1 {
+ pins = "GPIO118", "GPIO119";
+ ste,config = <&in_pu>;
+ };
+ };
+
+ i2c5_sleep_mode: i2c_sleep {
+ sleep_cfg1 {
+ pins = "GPIO118", "GPIO119";
+ ste,config = <&slpm_in_pu>;
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-ccu8540.dts b/arch/arm/boot/dts/ste-ccu8540.dts
new file mode 100644
index 000000000..32dd55e5f
--- /dev/null
+++ b/arch/arm/boot/dts/ste-ccu8540.dts
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2013 ST-Ericsson AB
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "ste-dbx5x0.dtsi"
+#include "ste-ccu8540-pinctrl.dtsi"
+
+/ {
+ model = "ST-Ericsson U8540 platform with Device Tree";
+ compatible = "st-ericsson,ccu8540", "st-ericsson,u8540";
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x20000000 0x1f000000>, <0xc0000000 0x3f000000>;
+ };
+
+ soc {
+ pinctrl {
+ compatible = "stericsson,db8540-pinctrl";
+ };
+
+ prcmu@80157000 {
+ reg = <0x80157000 0x2000>, <0x801b0000 0x8000>, <0x801b8000 0x3000>;
+ reg-names = "prcmu", "prcmu-tcpm", "prcmu-tcdm";
+ };
+
+ uart@80120000 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&uart0_default_mux>, <&uart0_default_mode>;
+ pinctrl-1 = <&uart0_sleep_mode>;
+ status = "okay";
+ };
+
+ uart@80121000 {
+ status = "okay";
+ };
+
+ uart@80007000 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&uart2_default_mode>;
+ pinctrl-1 = <&uart2_sleep_mode>;
+ status = "okay";
+ };
+
+ i2c0: i2c@80004000 {
+ pinctrl-names = "default","sleep";
+ pinctrl-0 = <&i2c0_default_mux>, <&i2c0_default_mode>;
+ pinctrl-1 = <&i2c0_sleep_mode>;
+ };
+
+ i2c1: i2c@80122000 {
+ pinctrl-names = "default","sleep";
+ pinctrl-0 = <&i2c1_default_mux>, <&i2c1_default_mode>;
+ pinctrl-1 = <&i2c1_sleep_mode>;
+ };
+
+ i2c2: i2c@80128000 {
+ pinctrl-names = "default","sleep";
+ pinctrl-0 = <&i2c2_default_mux>, <&i2c2_default_mode>;
+ pinctrl-1 = <&i2c2_sleep_mode>;
+ };
+
+ i2c3: i2c@80110000 {
+ status = "disabled";
+ };
+
+ i2c4: i2c@8012a000 {
+ pinctrl-names = "default","sleep";
+ pinctrl-0 = <&i2c4_default_mux>, <&i2c4_default_mode>;
+ pinctrl-1 = <&i2c4_sleep_mode>;
+ };
+
+ i2c5: i2c@80001000 {
+ pinctrl-names = "default","sleep";
+ pinctrl-0 = <&i2c5_default_mux>, <&i2c5_default_mode>;
+ pinctrl-1 = <&i2c5_sleep_mode>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-ccu9540.dts b/arch/arm/boot/dts/ste-ccu9540.dts
new file mode 100644
index 000000000..651c56d40
--- /dev/null
+++ b/arch/arm/boot/dts/ste-ccu9540.dts
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "ste-dbx5x0.dtsi"
+
+/ {
+ model = "ST-Ericsson CCU9540 platform with Device Tree";
+ compatible = "st-ericsson,ccu9540", "st-ericsson,u9540";
+
+ memory {
+ reg = <0x00000000 0x20000000>;
+ };
+
+ soc {
+ uart@80120000 {
+ status = "okay";
+ };
+
+ uart@80121000 {
+ status = "okay";
+ };
+
+ uart@80007000 {
+ status = "okay";
+ };
+
+ // External Micro SD slot
+ sdi0_per1@80126000 {
+ arm,primecell-periphid = <0x10480180>;
+ max-frequency = <100000000>;
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ vmmc-supply = <&ab8500_ldo_aux3_reg>;
+
+ cd-gpios = <&gpio7 6 0x4>; // 230
+ cd-inverted;
+
+ status = "okay";
+ };
+
+
+ // WLAN SDIO channel
+ sdi1_per2@80118000 {
+ arm,primecell-periphid = <0x10480180>;
+ max-frequency = <100000000>;
+ bus-width = <4>;
+
+ status = "okay";
+ };
+
+ // On-board eMMC
+ sdi4_per2@80114000 {
+ arm,primecell-periphid = <0x10480180>;
+ max-frequency = <100000000>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ vmmc-supply = <&ab8500_ldo_aux2_reg>;
+
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi
new file mode 100644
index 000000000..2201cd5da
--- /dev/null
+++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi
@@ -0,0 +1,1054 @@
+/*
+ * Copyright 2012 Linaro Ltd
+ *
+ * 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 <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/mfd/dbx500-prcmu.h>
+#include <dt-bindings/arm/ux500_pm_domains.h>
+#include "skeleton.dtsi"
+
+/ {
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "stericsson,db8500";
+ interrupt-parent = <&intc>;
+ ranges;
+
+ intc: interrupt-controller@a0411000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <1>;
+ interrupt-controller;
+ reg = <0xa0411000 0x1000>,
+ <0xa0410100 0x100>;
+ };
+
+ L2: l2-cache {
+ compatible = "arm,pl310-cache";
+ reg = <0xa0412000 0x1000>;
+ interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pm_domains: pm_domains0 {
+ compatible = "stericsson,ux500-pm-domains";
+ #power-domain-cells = <1>;
+ };
+
+ clocks {
+ compatible = "stericsson,u8500-clks";
+
+ prcmu_clk: prcmu-clock {
+ #clock-cells = <1>;
+ };
+
+ prcc_pclk: prcc-periph-clock {
+ #clock-cells = <2>;
+ };
+
+ prcc_kclk: prcc-kernel-clock {
+ #clock-cells = <2>;
+ };
+
+ rtc_clk: rtc32k-clock {
+ #clock-cells = <0>;
+ };
+
+ smp_twd_clk: smp-twd-clock {
+ #clock-cells = <0>;
+ };
+ };
+
+ mtu@a03c6000 {
+ /* Nomadik System Timer */
+ compatible = "st,nomadik-mtu";
+ reg = <0xa03c6000 0x1000>;
+ interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&prcmu_clk PRCMU_TIMCLK>, <&prcc_pclk 6 6>;
+ clock-names = "timclk", "apb_pclk";
+ };
+
+ timer@a0410600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xa0410600 0x20>;
+ interrupts = <1 13 0x304>; /* IRQ level high per-CPU */
+
+ clocks = <&smp_twd_clk>;
+ };
+
+ rtc@80154000 {
+ compatible = "arm,rtc-pl031", "arm,primecell";
+ reg = <0x80154000 0x1000>;
+ interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&rtc_clk>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio0: gpio@8012e000 {
+ compatible = "stericsson,db8500-gpio",
+ "st,nomadik-gpio";
+ reg = <0x8012e000 0x80>;
+ interrupts = <0 119 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ st,supports-sleepmode;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-bank = <0>;
+
+ clocks = <&prcc_pclk 1 9>;
+ };
+
+ gpio1: gpio@8012e080 {
+ compatible = "stericsson,db8500-gpio",
+ "st,nomadik-gpio";
+ reg = <0x8012e080 0x80>;
+ interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ st,supports-sleepmode;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-bank = <1>;
+
+ clocks = <&prcc_pclk 1 9>;
+ };
+
+ gpio2: gpio@8000e000 {
+ compatible = "stericsson,db8500-gpio",
+ "st,nomadik-gpio";
+ reg = <0x8000e000 0x80>;
+ interrupts = <0 121 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ st,supports-sleepmode;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-bank = <2>;
+
+ clocks = <&prcc_pclk 3 8>;
+ };
+
+ gpio3: gpio@8000e080 {
+ compatible = "stericsson,db8500-gpio",
+ "st,nomadik-gpio";
+ reg = <0x8000e080 0x80>;
+ interrupts = <0 122 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ st,supports-sleepmode;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-bank = <3>;
+
+ clocks = <&prcc_pclk 3 8>;
+ };
+
+ gpio4: gpio@8000e100 {
+ compatible = "stericsson,db8500-gpio",
+ "st,nomadik-gpio";
+ reg = <0x8000e100 0x80>;
+ interrupts = <0 123 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ st,supports-sleepmode;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-bank = <4>;
+
+ clocks = <&prcc_pclk 3 8>;
+ };
+
+ gpio5: gpio@8000e180 {
+ compatible = "stericsson,db8500-gpio",
+ "st,nomadik-gpio";
+ reg = <0x8000e180 0x80>;
+ interrupts = <0 124 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ st,supports-sleepmode;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-bank = <5>;
+
+ clocks = <&prcc_pclk 3 8>;
+ };
+
+ gpio6: gpio@8011e000 {
+ compatible = "stericsson,db8500-gpio",
+ "st,nomadik-gpio";
+ reg = <0x8011e000 0x80>;
+ interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ st,supports-sleepmode;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-bank = <6>;
+
+ clocks = <&prcc_pclk 2 11>;
+ };
+
+ gpio7: gpio@8011e080 {
+ compatible = "stericsson,db8500-gpio",
+ "st,nomadik-gpio";
+ reg = <0x8011e080 0x80>;
+ interrupts = <0 126 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ st,supports-sleepmode;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-bank = <7>;
+
+ clocks = <&prcc_pclk 2 11>;
+ };
+
+ gpio8: gpio@a03fe000 {
+ compatible = "stericsson,db8500-gpio",
+ "st,nomadik-gpio";
+ reg = <0xa03fe000 0x80>;
+ interrupts = <0 127 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ st,supports-sleepmode;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-bank = <8>;
+
+ clocks = <&prcc_pclk 5 1>;
+ };
+
+ pinctrl {
+ compatible = "stericsson,db8500-pinctrl";
+ prcm = <&prcmu>;
+ };
+
+ usb_per5@a03e0000 {
+ compatible = "stericsson,db8500-musb";
+ reg = <0xa03e0000 0x10000>;
+ interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "mc";
+
+ dr_mode = "otg";
+
+ dmas = <&dma 38 0 0x2>, /* Logical - DevToMem */
+ <&dma 38 0 0x0>, /* Logical - MemToDev */
+ <&dma 37 0 0x2>, /* Logical - DevToMem */
+ <&dma 37 0 0x0>, /* Logical - MemToDev */
+ <&dma 36 0 0x2>, /* Logical - DevToMem */
+ <&dma 36 0 0x0>, /* Logical - MemToDev */
+ <&dma 19 0 0x2>, /* Logical - DevToMem */
+ <&dma 19 0 0x0>, /* Logical - MemToDev */
+ <&dma 18 0 0x2>, /* Logical - DevToMem */
+ <&dma 18 0 0x0>, /* Logical - MemToDev */
+ <&dma 17 0 0x2>, /* Logical - DevToMem */
+ <&dma 17 0 0x0>, /* Logical - MemToDev */
+ <&dma 16 0 0x2>, /* Logical - DevToMem */
+ <&dma 16 0 0x0>, /* Logical - MemToDev */
+ <&dma 39 0 0x2>, /* Logical - DevToMem */
+ <&dma 39 0 0x0>; /* Logical - MemToDev */
+
+ dma-names = "iep_1_9", "oep_1_9",
+ "iep_2_10", "oep_2_10",
+ "iep_3_11", "oep_3_11",
+ "iep_4_12", "oep_4_12",
+ "iep_5_13", "oep_5_13",
+ "iep_6_14", "oep_6_14",
+ "iep_7_15", "oep_7_15",
+ "iep_8", "oep_8";
+
+ clocks = <&prcc_pclk 5 0>;
+ };
+
+ dma: dma-controller@801C0000 {
+ compatible = "stericsson,db8500-dma40", "stericsson,dma40";
+ reg = <0x801C0000 0x1000 0x40010000 0x800>;
+ reg-names = "base", "lcpa";
+ interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
+
+ #dma-cells = <3>;
+ memcpy-channels = <56 57 58 59 60>;
+
+ clocks = <&prcmu_clk PRCMU_DMACLK>;
+ };
+
+ prcmu: prcmu@80157000 {
+ compatible = "stericsson,db8500-prcmu";
+ reg = <0x80157000 0x2000>, <0x801b0000 0x8000>, <0x801b8000 0x1000>;
+ reg-names = "prcmu", "prcmu-tcpm", "prcmu-tcdm";
+ interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ranges;
+
+ prcmu-timer-4@80157450 {
+ compatible = "stericsson,db8500-prcmu-timer-4";
+ reg = <0x80157450 0xC>;
+ };
+
+ cpufreq {
+ compatible = "stericsson,cpufreq-ux500";
+ clocks = <&prcmu_clk PRCMU_ARMSS>;
+ clock-names = "armss";
+ status = "disabled";
+ };
+
+ thermal@801573c0 {
+ compatible = "stericsson,db8500-thermal";
+ reg = <0x801573c0 0x40>;
+ interrupts = <21 IRQ_TYPE_LEVEL_HIGH>,
+ <22 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "IRQ_HOTMON_LOW", "IRQ_HOTMON_HIGH";
+ status = "disabled";
+ };
+
+ db8500-prcmu-regulators {
+ compatible = "stericsson,db8500-prcmu-regulator";
+
+ // DB8500_REGULATOR_VAPE
+ db8500_vape_reg: db8500_vape {
+ regulator-compatible = "db8500_vape";
+ regulator-always-on;
+ };
+
+ // DB8500_REGULATOR_VARM
+ db8500_varm_reg: db8500_varm {
+ regulator-compatible = "db8500_varm";
+ };
+
+ // DB8500_REGULATOR_VMODEM
+ db8500_vmodem_reg: db8500_vmodem {
+ regulator-compatible = "db8500_vmodem";
+ };
+
+ // DB8500_REGULATOR_VPLL
+ db8500_vpll_reg: db8500_vpll {
+ regulator-compatible = "db8500_vpll";
+ };
+
+ // DB8500_REGULATOR_VSMPS1
+ db8500_vsmps1_reg: db8500_vsmps1 {
+ regulator-compatible = "db8500_vsmps1";
+ };
+
+ // DB8500_REGULATOR_VSMPS2
+ db8500_vsmps2_reg: db8500_vsmps2 {
+ regulator-compatible = "db8500_vsmps2";
+ };
+
+ // DB8500_REGULATOR_VSMPS3
+ db8500_vsmps3_reg: db8500_vsmps3 {
+ regulator-compatible = "db8500_vsmps3";
+ };
+
+ // DB8500_REGULATOR_VRF1
+ db8500_vrf1_reg: db8500_vrf1 {
+ regulator-compatible = "db8500_vrf1";
+ };
+
+ // DB8500_REGULATOR_SWITCH_SVAMMDSP
+ db8500_sva_mmdsp_reg: db8500_sva_mmdsp {
+ regulator-compatible = "db8500_sva_mmdsp";
+ };
+
+ // DB8500_REGULATOR_SWITCH_SVAMMDSPRET
+ db8500_sva_mmdsp_ret_reg: db8500_sva_mmdsp_ret {
+ regulator-compatible = "db8500_sva_mmdsp_ret";
+ };
+
+ // DB8500_REGULATOR_SWITCH_SVAPIPE
+ db8500_sva_pipe_reg: db8500_sva_pipe {
+ regulator-compatible = "db8500_sva_pipe";
+ };
+
+ // DB8500_REGULATOR_SWITCH_SIAMMDSP
+ db8500_sia_mmdsp_reg: db8500_sia_mmdsp {
+ regulator-compatible = "db8500_sia_mmdsp";
+ };
+
+ // DB8500_REGULATOR_SWITCH_SIAMMDSPRET
+ db8500_sia_mmdsp_ret_reg: db8500_sia_mmdsp_ret {
+ };
+
+ // DB8500_REGULATOR_SWITCH_SIAPIPE
+ db8500_sia_pipe_reg: db8500_sia_pipe {
+ regulator-compatible = "db8500_sia_pipe";
+ };
+
+ // DB8500_REGULATOR_SWITCH_SGA
+ db8500_sga_reg: db8500_sga {
+ regulator-compatible = "db8500_sga";
+ vin-supply = <&db8500_vape_reg>;
+ };
+
+ // DB8500_REGULATOR_SWITCH_B2R2_MCDE
+ db8500_b2r2_mcde_reg: db8500_b2r2_mcde {
+ regulator-compatible = "db8500_b2r2_mcde";
+ vin-supply = <&db8500_vape_reg>;
+ };
+
+ // DB8500_REGULATOR_SWITCH_ESRAM12
+ db8500_esram12_reg: db8500_esram12 {
+ regulator-compatible = "db8500_esram12";
+ };
+
+ // DB8500_REGULATOR_SWITCH_ESRAM12RET
+ db8500_esram12_ret_reg: db8500_esram12_ret {
+ regulator-compatible = "db8500_esram12_ret";
+ };
+
+ // DB8500_REGULATOR_SWITCH_ESRAM34
+ db8500_esram34_reg: db8500_esram34 {
+ regulator-compatible = "db8500_esram34";
+ };
+
+ // DB8500_REGULATOR_SWITCH_ESRAM34RET
+ db8500_esram34_ret_reg: db8500_esram34_ret {
+ regulator-compatible = "db8500_esram34_ret";
+ };
+ };
+
+ ab8500 {
+ compatible = "stericsson,ab8500";
+ interrupt-parent = <&intc>;
+ interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ ab8500_gpio: ab8500-gpio {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ ab8500-rtc {
+ compatible = "stericsson,ab8500-rtc";
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH
+ 18 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "60S", "ALARM";
+ };
+
+ ab8500-gpadc {
+ compatible = "stericsson,ab8500-gpadc";
+ interrupts = <32 IRQ_TYPE_LEVEL_HIGH
+ 39 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "HW_CONV_END", "SW_CONV_END";
+ vddadc-supply = <&ab8500_ldo_tvout_reg>;
+ };
+
+ ab8500_battery: ab8500_battery {
+ stericsson,battery-type = "LIPO";
+ thermistor-on-batctrl;
+ };
+
+ ab8500_fg {
+ compatible = "stericsson,ab8500-fg";
+ battery = <&ab8500_battery>;
+ };
+
+ ab8500_btemp {
+ compatible = "stericsson,ab8500-btemp";
+ battery = <&ab8500_battery>;
+ };
+
+ ab8500_charger {
+ compatible = "stericsson,ab8500-charger";
+ battery = <&ab8500_battery>;
+ vddadc-supply = <&ab8500_ldo_tvout_reg>;
+ };
+
+ ab8500_chargalg {
+ compatible = "stericsson,ab8500-chargalg";
+ battery = <&ab8500_battery>;
+ };
+
+ ab8500_usb {
+ compatible = "stericsson,ab8500-usb";
+ interrupts = < 90 IRQ_TYPE_LEVEL_HIGH
+ 96 IRQ_TYPE_LEVEL_HIGH
+ 14 IRQ_TYPE_LEVEL_HIGH
+ 15 IRQ_TYPE_LEVEL_HIGH
+ 79 IRQ_TYPE_LEVEL_HIGH
+ 74 IRQ_TYPE_LEVEL_HIGH
+ 75 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "ID_WAKEUP_R",
+ "ID_WAKEUP_F",
+ "VBUS_DET_F",
+ "VBUS_DET_R",
+ "USB_LINK_STATUS",
+ "USB_ADP_PROBE_PLUG",
+ "USB_ADP_PROBE_UNPLUG";
+ vddulpivio18-supply = <&ab8500_ldo_intcore_reg>;
+ v-ape-supply = <&db8500_vape_reg>;
+ musb_1v8-supply = <&db8500_vsmps2_reg>;
+ };
+
+ ab8500-ponkey {
+ compatible = "stericsson,ab8500-poweron-key";
+ interrupts = <6 IRQ_TYPE_LEVEL_HIGH
+ 7 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "ONKEY_DBF", "ONKEY_DBR";
+ };
+
+ ab8500-sysctrl {
+ compatible = "stericsson,ab8500-sysctrl";
+ };
+
+ ab8500-pwm {
+ compatible = "stericsson,ab8500-pwm";
+ };
+
+ ab8500-debugfs {
+ compatible = "stericsson,ab8500-debug";
+ };
+
+ codec: ab8500-codec {
+ compatible = "stericsson,ab8500-codec";
+
+ V-AUD-supply = <&ab8500_ldo_audio_reg>;
+ V-AMIC1-supply = <&ab8500_ldo_anamic1_reg>;
+ V-AMIC2-supply = <&ab8500_ldo_anamic2_reg>;
+ V-DMIC-supply = <&ab8500_ldo_dmic_reg>;
+
+ stericsson,earpeice-cmv = <950>; /* Units in mV. */
+ };
+
+ ext_regulators: ab8500-ext-regulators {
+ compatible = "stericsson,ab8500-ext-regulator";
+
+ ab8500_ext1_reg: ab8500_ext1 {
+ regulator-compatible = "ab8500_ext1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ab8500_ext2_reg: ab8500_ext2 {
+ regulator-compatible = "ab8500_ext2";
+ regulator-min-microvolt = <1360000>;
+ regulator-max-microvolt = <1360000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ab8500_ext3_reg: ab8500_ext3 {
+ regulator-compatible = "ab8500_ext3";
+ regulator-min-microvolt = <3400000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ };
+ };
+
+ ab8500-regulators {
+ compatible = "stericsson,ab8500-regulator";
+ vin-supply = <&ab8500_ext3_reg>;
+
+ // supplies to the display/camera
+ ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
+ regulator-compatible = "ab8500_ldo_aux1";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-boot-on;
+ /* BUG: If turned off MMC will be affected. */
+ regulator-always-on;
+ };
+
+ // supplies to the on-board eMMC
+ ab8500_ldo_aux2_reg: ab8500_ldo_aux2 {
+ regulator-compatible = "ab8500_ldo_aux2";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ // supply for VAUX3; SDcard slots
+ ab8500_ldo_aux3_reg: ab8500_ldo_aux3 {
+ regulator-compatible = "ab8500_ldo_aux3";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ // supply for v-intcore12; VINTCORE12 LDO
+ ab8500_ldo_intcore_reg: ab8500_ldo_intcore {
+ regulator-compatible = "ab8500_ldo_intcore";
+ };
+
+ // supply for tvout; gpadc; TVOUT LDO
+ ab8500_ldo_tvout_reg: ab8500_ldo_tvout {
+ regulator-compatible = "ab8500_ldo_tvout";
+ };
+
+ // supply for ab8500-usb; USB LDO
+ ab8500_ldo_usb_reg: ab8500_ldo_usb {
+ regulator-compatible = "ab8500_ldo_usb";
+ };
+
+ // supply for ab8500-vaudio; VAUDIO LDO
+ ab8500_ldo_audio_reg: ab8500_ldo_audio {
+ regulator-compatible = "ab8500_ldo_audio";
+ };
+
+ // supply for v-anamic1 VAMIC1 LDO
+ ab8500_ldo_anamic1_reg: ab8500_ldo_anamic1 {
+ regulator-compatible = "ab8500_ldo_anamic1";
+ };
+
+ // supply for v-amic2; VAMIC2 LDO; reuse constants for AMIC1
+ ab8500_ldo_anamic2_reg: ab8500_ldo_anamic2 {
+ regulator-compatible = "ab8500_ldo_anamic2";
+ };
+
+ // supply for v-dmic; VDMIC LDO
+ ab8500_ldo_dmic_reg: ab8500_ldo_dmic {
+ regulator-compatible = "ab8500_ldo_dmic";
+ };
+
+ // supply for U8500 CSI/DSI; VANA LDO
+ ab8500_ldo_ana_reg: ab8500_ldo_ana {
+ regulator-compatible = "ab8500_ldo_ana";
+ };
+ };
+ };
+ };
+
+ i2c@80004000 {
+ compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
+ reg = <0x80004000 0x1000>;
+ interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ v-i2c-supply = <&db8500_vape_reg>;
+
+ clock-frequency = <400000>;
+ clocks = <&prcc_kclk 3 3>, <&prcc_pclk 3 3>;
+ clock-names = "i2cclk", "apb_pclk";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+ };
+
+ i2c@80122000 {
+ compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
+ reg = <0x80122000 0x1000>;
+ interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ v-i2c-supply = <&db8500_vape_reg>;
+
+ clock-frequency = <400000>;
+
+ clocks = <&prcc_kclk 1 2>, <&prcc_pclk 1 2>;
+ clock-names = "i2cclk", "apb_pclk";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+ };
+
+ i2c@80128000 {
+ compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
+ reg = <0x80128000 0x1000>;
+ interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ v-i2c-supply = <&db8500_vape_reg>;
+
+ clock-frequency = <400000>;
+
+ clocks = <&prcc_kclk 1 6>, <&prcc_pclk 1 6>;
+ clock-names = "i2cclk", "apb_pclk";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+ };
+
+ i2c@80110000 {
+ compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
+ reg = <0x80110000 0x1000>;
+ interrupts = <0 12 IRQ_TYPE_LEVEL_HIGH>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ v-i2c-supply = <&db8500_vape_reg>;
+
+ clock-frequency = <400000>;
+
+ clocks = <&prcc_kclk 2 0>, <&prcc_pclk 2 0>;
+ clock-names = "i2cclk", "apb_pclk";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+ };
+
+ i2c@8012a000 {
+ compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
+ reg = <0x8012a000 0x1000>;
+ interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ v-i2c-supply = <&db8500_vape_reg>;
+
+ clock-frequency = <400000>;
+
+ clocks = <&prcc_kclk 1 9>, <&prcc_pclk 1 10>;
+ clock-names = "i2cclk", "apb_pclk";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+ };
+
+ ssp@80002000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x80002000 0x1000>;
+ interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&prcc_kclk 3 1>, <&prcc_pclk 3 1>;
+ clock-names = "SSPCLK", "apb_pclk";
+ dmas = <&dma 8 0 0x2>, /* Logical - DevToMem */
+ <&dma 8 0 0x0>; /* Logical - MemToDev */
+ dma-names = "rx", "tx";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+ };
+
+ ssp@80003000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x80003000 0x1000>;
+ interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&prcc_kclk 3 2>, <&prcc_pclk 3 2>;
+ clock-names = "SSPCLK", "apb_pclk";
+ dmas = <&dma 9 0 0x2>, /* Logical - DevToMem */
+ <&dma 9 0 0x0>; /* Logical - MemToDev */
+ dma-names = "rx", "tx";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+ };
+
+ spi@8011a000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x8011a000 0x1000>;
+ interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /* Same clock wired to kernel and pclk */
+ clocks = <&prcc_pclk 2 8>, <&prcc_pclk 2 8>;
+ clock-names = "SSPCLK", "apb_pclk";
+ dmas = <&dma 0 0 0x2>, /* Logical - DevToMem */
+ <&dma 0 0 0x0>; /* Logical - MemToDev */
+ dma-names = "rx", "tx";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+ };
+
+ spi@80112000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x80112000 0x1000>;
+ interrupts = <0 96 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /* Same clock wired to kernel and pclk */
+ clocks = <&prcc_pclk 2 2>, <&prcc_pclk 2 2>;
+ clock-names = "SSPCLK", "apb_pclk";
+ dmas = <&dma 35 0 0x2>, /* Logical - DevToMem */
+ <&dma 35 0 0x0>; /* Logical - MemToDev */
+ dma-names = "rx", "tx";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+ };
+
+ spi@80111000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x80111000 0x1000>;
+ interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /* Same clock wired to kernel and pclk */
+ clocks = <&prcc_pclk 2 1>, <&prcc_pclk 2 1>;
+ clock-names = "SSPCLK", "apb_pclk";
+ dmas = <&dma 33 0 0x2>, /* Logical - DevToMem */
+ <&dma 33 0 0x0>; /* Logical - MemToDev */
+ dma-names = "rx", "tx";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+ };
+
+ spi@80129000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x80129000 0x1000>;
+ interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /* Same clock wired to kernel and pclk */
+ clocks = <&prcc_pclk 1 7>, <&prcc_pclk 1 7>;
+ clock-names = "SSPCLK", "apb_pclk";
+ dmas = <&dma 40 0 0x2>, /* Logical - DevToMem */
+ <&dma 40 0 0x0>; /* Logical - MemToDev */
+ dma-names = "rx", "tx";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+ };
+
+ uart@80120000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x80120000 0x1000>;
+ interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>;
+
+ dmas = <&dma 13 0 0x2>, /* Logical - DevToMem */
+ <&dma 13 0 0x0>; /* Logical - MemToDev */
+ dma-names = "rx", "tx";
+
+ clocks = <&prcc_kclk 1 0>, <&prcc_pclk 1 0>;
+ clock-names = "uart", "apb_pclk";
+
+ status = "disabled";
+ };
+
+ uart@80121000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x80121000 0x1000>;
+ interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>;
+
+ dmas = <&dma 12 0 0x2>, /* Logical - DevToMem */
+ <&dma 12 0 0x0>; /* Logical - MemToDev */
+ dma-names = "rx", "tx";
+
+ clocks = <&prcc_kclk 1 1>, <&prcc_pclk 1 1>;
+ clock-names = "uart", "apb_pclk";
+
+ status = "disabled";
+ };
+
+ uart@80007000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x80007000 0x1000>;
+ interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
+
+ dmas = <&dma 11 0 0x2>, /* Logical - DevToMem */
+ <&dma 11 0 0x0>; /* Logical - MemToDev */
+ dma-names = "rx", "tx";
+
+ clocks = <&prcc_kclk 3 6>, <&prcc_pclk 3 6>;
+ clock-names = "uart", "apb_pclk";
+
+ status = "disabled";
+ };
+
+ sdi0_per1@80126000 {
+ compatible = "arm,pl18x", "arm,primecell";
+ reg = <0x80126000 0x1000>;
+ interrupts = <0 60 IRQ_TYPE_LEVEL_HIGH>;
+
+ dmas = <&dma 29 0 0x2>, /* Logical - DevToMem */
+ <&dma 29 0 0x0>; /* Logical - MemToDev */
+ dma-names = "rx", "tx";
+
+ clocks = <&prcc_kclk 1 5>, <&prcc_pclk 1 5>;
+ clock-names = "sdi", "apb_pclk";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+
+ status = "disabled";
+ };
+
+ sdi1_per2@80118000 {
+ compatible = "arm,pl18x", "arm,primecell";
+ reg = <0x80118000 0x1000>;
+ interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
+
+ dmas = <&dma 32 0 0x2>, /* Logical - DevToMem */
+ <&dma 32 0 0x0>; /* Logical - MemToDev */
+ dma-names = "rx", "tx";
+
+ clocks = <&prcc_kclk 2 4>, <&prcc_pclk 2 6>;
+ clock-names = "sdi", "apb_pclk";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+
+ status = "disabled";
+ };
+
+ sdi2_per3@80005000 {
+ compatible = "arm,pl18x", "arm,primecell";
+ reg = <0x80005000 0x1000>;
+ interrupts = <0 41 IRQ_TYPE_LEVEL_HIGH>;
+
+ dmas = <&dma 28 0 0x2>, /* Logical - DevToMem */
+ <&dma 28 0 0x0>; /* Logical - MemToDev */
+ dma-names = "rx", "tx";
+
+ clocks = <&prcc_kclk 3 4>, <&prcc_pclk 3 4>;
+ clock-names = "sdi", "apb_pclk";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+
+ status = "disabled";
+ };
+
+ sdi3_per2@80119000 {
+ compatible = "arm,pl18x", "arm,primecell";
+ reg = <0x80119000 0x1000>;
+ interrupts = <0 59 IRQ_TYPE_LEVEL_HIGH>;
+
+ dmas = <&dma 41 0 0x2>, /* Logical - DevToMem */
+ <&dma 41 0 0x0>; /* Logical - MemToDev */
+ dma-names = "rx", "tx";
+
+ clocks = <&prcc_kclk 2 5>, <&prcc_pclk 2 7>;
+ clock-names = "sdi", "apb_pclk";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+
+ status = "disabled";
+ };
+
+ sdi4_per2@80114000 {
+ compatible = "arm,pl18x", "arm,primecell";
+ reg = <0x80114000 0x1000>;
+ interrupts = <0 99 IRQ_TYPE_LEVEL_HIGH>;
+
+ dmas = <&dma 42 0 0x2>, /* Logical - DevToMem */
+ <&dma 42 0 0x0>; /* Logical - MemToDev */
+ dma-names = "rx", "tx";
+
+ clocks = <&prcc_kclk 2 2>, <&prcc_pclk 2 4>;
+ clock-names = "sdi", "apb_pclk";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+
+ status = "disabled";
+ };
+
+ sdi5_per3@80008000 {
+ compatible = "arm,pl18x", "arm,primecell";
+ reg = <0x80008000 0x1000>;
+ interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
+
+ dmas = <&dma 43 0 0x2>, /* Logical - DevToMem */
+ <&dma 43 0 0x0>; /* Logical - MemToDev */
+ dma-names = "rx", "tx";
+
+ clocks = <&prcc_kclk 3 7>, <&prcc_pclk 3 7>;
+ clock-names = "sdi", "apb_pclk";
+ power-domains = <&pm_domains DOMAIN_VAPE>;
+
+ status = "disabled";
+ };
+
+ msp0: msp@80123000 {
+ compatible = "stericsson,ux500-msp-i2s";
+ reg = <0x80123000 0x1000>;
+ interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
+ v-ape-supply = <&db8500_vape_reg>;
+
+ dmas = <&dma 31 0 0x12>, /* Logical - DevToMem - HighPrio */
+ <&dma 31 0 0x10>; /* Logical - MemToDev - HighPrio */
+ dma-names = "rx", "tx";
+
+ clocks = <&prcc_kclk 1 3>, <&prcc_pclk 1 3>;
+ clock-names = "msp", "apb_pclk";
+
+ status = "disabled";
+ };
+
+ msp1: msp@80124000 {
+ compatible = "stericsson,ux500-msp-i2s";
+ reg = <0x80124000 0x1000>;
+ interrupts = <0 62 IRQ_TYPE_LEVEL_HIGH>;
+ v-ape-supply = <&db8500_vape_reg>;
+
+ /* This DMA channel only exist on DB8500 v1 */
+ dmas = <&dma 30 0 0x10>; /* Logical - MemToDev - HighPrio */
+ dma-names = "tx";
+
+ clocks = <&prcc_kclk 1 4>, <&prcc_pclk 1 4>;
+ clock-names = "msp", "apb_pclk";
+
+ status = "disabled";
+ };
+
+ // HDMI sound
+ msp2: msp@80117000 {
+ compatible = "stericsson,ux500-msp-i2s";
+ reg = <0x80117000 0x1000>;
+ interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
+ v-ape-supply = <&db8500_vape_reg>;
+
+ dmas = <&dma 14 0 0x12>, /* Logical - DevToMem - HighPrio */
+ <&dma 14 1 0x19>; /* Physical Chan 1 - MemToDev
+ HighPrio - Fixed */
+ dma-names = "rx", "tx";
+
+ clocks = <&prcc_kclk 2 3>, <&prcc_pclk 2 5>;
+ clock-names = "msp", "apb_pclk";
+
+ status = "disabled";
+ };
+
+ msp3: msp@80125000 {
+ compatible = "stericsson,ux500-msp-i2s";
+ reg = <0x80125000 0x1000>;
+ interrupts = <0 62 IRQ_TYPE_LEVEL_HIGH>;
+ v-ape-supply = <&db8500_vape_reg>;
+
+ /* This DMA channel only exist on DB8500 v2 */
+ dmas = <&dma 30 0 0x12>; /* Logical - DevToMem - HighPrio */
+ dma-names = "rx";
+
+ clocks = <&prcc_kclk 1 10>, <&prcc_pclk 1 11>;
+ clock-names = "msp", "apb_pclk";
+
+ status = "disabled";
+ };
+
+ external-bus@50000000 {
+ compatible = "simple-bus";
+ reg = <0x50000000 0x4000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x50000000 0x4000000>;
+ status = "disabled";
+ };
+
+ cpufreq-cooling {
+ compatible = "stericsson,db8500-cpufreq-cooling";
+ status = "disabled";
+ };
+
+ mcde@a0350000 {
+ compatible = "stericsson,mcde";
+ reg = <0xa0350000 0x1000>, /* MCDE */
+ <0xa0351000 0x1000>, /* DSI link 1 */
+ <0xa0352000 0x1000>, /* DSI link 2 */
+ <0xa0353000 0x1000>; /* DSI link 3 */
+ interrupts = <0 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&prcmu_clk PRCMU_MCDECLK>, /* Main MCDE clock */
+ <&prcmu_clk PRCMU_LCDCLK>, /* LCD clock */
+ <&prcmu_clk PRCMU_PLLDSI>, /* HDMI clock */
+ <&prcmu_clk PRCMU_DSI0CLK>, /* DSI 0 */
+ <&prcmu_clk PRCMU_DSI1CLK>, /* DSI 1 */
+ <&prcmu_clk PRCMU_DSI0ESCCLK>, /* TVout clock 0 */
+ <&prcmu_clk PRCMU_DSI1ESCCLK>, /* TVout clock 1 */
+ <&prcmu_clk PRCMU_DSI2ESCCLK>; /* TVout clock 2 */
+ };
+
+ cryp@a03cb000 {
+ compatible = "stericsson,ux500-cryp";
+ reg = <0xa03cb000 0x1000>;
+ interrupts = <0 15 IRQ_TYPE_LEVEL_HIGH>;
+
+ v-ape-supply = <&db8500_vape_reg>;
+ clocks = <&prcc_pclk 6 1>;
+ };
+
+ hash@a03c2000 {
+ compatible = "stericsson,ux500-hash";
+ reg = <0xa03c2000 0x1000>;
+
+ v-ape-supply = <&db8500_vape_reg>;
+ clocks = <&prcc_pclk 6 2>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-href-ab8500.dtsi b/arch/arm/boot/dts/ste-href-ab8500.dtsi
new file mode 100644
index 000000000..9b69bce92
--- /dev/null
+++ b/arch/arm/boot/dts/ste-href-ab8500.dtsi
@@ -0,0 +1,428 @@
+/*
+ * Copyright 2014 Linaro Ltd.
+ *
+ * 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
+ */
+
+/ {
+ soc {
+ prcmu@80157000 {
+ ab8500 {
+ ab8500-gpio {
+ /* Hog a few default settings */
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio2_default_mode>,
+ <&gpio4_default_mode>,
+ <&gpio10_default_mode>,
+ <&gpio11_default_mode>,
+ <&gpio12_default_mode>,
+ <&gpio13_default_mode>,
+ <&gpio16_default_mode>,
+ <&gpio24_default_mode>,
+ <&gpio25_default_mode>,
+ <&gpio36_default_mode>,
+ <&gpio37_default_mode>,
+ <&gpio38_default_mode>,
+ <&gpio39_default_mode>,
+ <&gpio42_default_mode>,
+ <&gpio26_default_mode>,
+ <&gpio35_default_mode>,
+ <&ycbcr_default_mode>,
+ <&pwm_default_mode>,
+ <&adi1_default_mode>,
+ <&usbuicc_default_mode>,
+ <&dmic_default_mode>,
+ <&extcpena_default_mode>,
+ <&modsclsda_default_mode>;
+
+ /*
+ * Pins 2, 4, 10, 11, 12, 13, 16, 24, 25, 36, 37, 38, 39 and 42
+ * are muxed in as GPIO, and configured as INPUT PULL DOWN
+ */
+ gpio2 {
+ gpio2_default_mode: gpio2_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio2_a_1";
+ };
+ default_cfg {
+ pins = "GPIO2_T9";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio4 {
+ gpio4_default_mode: gpio4_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio4_a_1";
+ };
+ default_cfg {
+ pins = "GPIO4_W2";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio10 {
+ gpio10_default_mode: gpio10_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio10_d_1";
+ };
+ default_cfg {
+ pins = "GPIO10_U17";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio11 {
+ gpio11_default_mode: gpio11_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio11_d_1";
+ };
+ default_cfg {
+ pins = "GPIO11_AA18";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio12 {
+ gpio12_default_mode: gpio12_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio12_d_1";
+ };
+ default_cfg {
+ pins = "GPIO12_U16";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio13 {
+ gpio13_default_mode: gpio13_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio13_d_1";
+ };
+ default_cfg {
+ pins = "GPIO13_W17";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio16 {
+ gpio16_default_mode: gpio16_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio16_a_1";
+ };
+ default_cfg {
+ pins = "GPIO16_F15";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio24 {
+ gpio24_default_mode: gpio24_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio24_a_1";
+ };
+ default_cfg {
+ pins = "GPIO24_T14";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio25 {
+ gpio25_default_mode: gpio25_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio25_a_1";
+ };
+ default_cfg {
+ pins = "GPIO25_R16";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio36 {
+ gpio36_default_mode: gpio36_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio36_a_1";
+ };
+ default_cfg {
+ pins = "GPIO36_A17";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio37 {
+ gpio37_default_mode: gpio37_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio37_a_1";
+ };
+ default_cfg {
+ pins = "GPIO37_E15";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio38 {
+ gpio38_default_mode: gpio38_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio38_a_1";
+ };
+ default_cfg {
+ pins = "GPIO38_C17";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio39 {
+ gpio39_default_mode: gpio39_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio39_a_1";
+ };
+ default_cfg {
+ pins = "GPIO39_E16";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio42 {
+ gpio42_default_mode: gpio42_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio42_a_1";
+ };
+ default_cfg {
+ pins = "GPIO42_U2";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ /*
+ * Pins 26 and 35 muxed in as GPIO, and configured as OUTPUT LOW
+ */
+ gpio26 {
+ gpio26_default_mode: gpio26_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio26_d_1";
+ };
+ default_cfg {
+ pins = "GPIO26_M16";
+ output-low;
+ };
+ };
+ };
+ gpio35 {
+ gpio35_default_mode: gpio35_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio35_d_1";
+ };
+ default_cfg {
+ pins = "GPIO35_W15";
+ output-low;
+ };
+ };
+ };
+ /*
+ * This sets up the YCBCR connector pins, i.e. analog video out.
+ * Set as input with no bias.
+ */
+ ycbcr {
+ ycbcr_default_mode: ycbcr_default {
+ default_mux {
+ function = "ycbcr";
+ groups = "ycbcr0123_d_1";
+ };
+ default_cfg {
+ pins = "GPIO6_Y18",
+ "GPIO7_AA20",
+ "GPIO8_W18",
+ "GPIO9_AA19";
+ input-enable;
+ bias-disable;
+ };
+ };
+ };
+ /* This sets up the PWM pins 14 and 15 */
+ pwm {
+ pwm_default_mode: pwm_default {
+ default_mux {
+ function = "pwmout";
+ groups = "pwmout1_d_1", "pwmout2_d_1";
+ };
+ default_cfg {
+ pins = "GPIO14_F14",
+ "GPIO15_B17";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ /* This sets up audio interface 1 */
+ adi1 {
+ adi1_default_mode: adi1_default {
+ default_mux {
+ function = "adi1";
+ groups = "adi1_d_1";
+ };
+ default_cfg {
+ pins = "GPIO17_P5",
+ "GPIO18_R5",
+ "GPIO19_U5",
+ "GPIO20_T5";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ /* This sets up the USB UICC pins */
+ usbuicc {
+ usbuicc_default_mode: usbuicc_default {
+ default_mux {
+ function = "usbuicc";
+ groups = "usbuicc_d_1";
+ };
+ default_cfg {
+ pins = "GPIO21_H19",
+ "GPIO22_G20",
+ "GPIO23_G19";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ /* This sets up the microphone pins */
+ dmic {
+ dmic_default_mode: dmic_default {
+ default_mux {
+ function = "dmic";
+ groups = "dmic12_d_1",
+ "dmic34_d_1",
+ "dmic56_d_1";
+ };
+ default_cfg {
+ pins = "GPIO27_J6",
+ "GPIO28_K6",
+ "GPIO29_G6",
+ "GPIO30_H6",
+ "GPIO31_F5",
+ "GPIO32_G5";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ extcpena {
+ extcpena_default_mode: extcpena_default {
+ default_mux {
+ function = "extcpena";
+ groups = "extcpena_d_1";
+ };
+ default_cfg {
+ pins = "GPIO34_R17";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ /* Modem I2C setup (SCL and SDA pins) */
+ modsclsda {
+ modsclsda_default_mode: modsclsda_default {
+ default_mux {
+ function = "modsclsda";
+ groups = "modsclsda_d_1";
+ };
+ default_cfg {
+ pins = "GPIO40_T19",
+ "GPIO41_U19";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ /*
+ * Clock output pins associated with regulators.
+ */
+ sysclkreq2 {
+ sysclkreq2_default_mode: sysclkreq2_default {
+ default_mux {
+ function = "sysclkreq";
+ groups = "sysclkreq2_d_1";
+ };
+ default_cfg {
+ pins = "GPIO1_T10";
+ input-enable;
+ bias-disable;
+ };
+ };
+ sysclkreq2_sleep_mode: sysclkreq2_sleep {
+ default_mux {
+ function = "gpio";
+ groups = "gpio1_a_1";
+ };
+ default_cfg {
+ pins = "GPIO1_T10";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ sysclkreq4 {
+ sysclkreq4_default_mode: sysclkreq4_default {
+ default_mux {
+ function = "sysclkreq";
+ groups = "sysclkreq4_d_1";
+ };
+ default_cfg {
+ pins = "GPIO3_U9";
+ input-enable;
+ bias-disable;
+ };
+ };
+ sysclkreq4_sleep_mode: sysclkreq4_sleep {
+ default_mux {
+ function = "gpio";
+ groups = "gpio3_a_1";
+ };
+ default_cfg {
+ pins = "GPIO3_U9";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-href-ab8505.dtsi b/arch/arm/boot/dts/ste-href-ab8505.dtsi
new file mode 100644
index 000000000..ccf37a9df
--- /dev/null
+++ b/arch/arm/boot/dts/ste-href-ab8505.dtsi
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2014 Linaro Ltd.
+ *
+ * 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
+ */
+
+/ {
+ soc {
+ prcmu@80157000 {
+ ab8505 {
+ ab8505-gpio {
+ /* Hog a few default settings */
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio2_default_mode>,
+ <&gpio10_default_mode>,
+ <&gpio11_default_mode>,
+ <&gpio13_default_mode>,
+ <&gpio34_default_mode>,
+ <&gpio50_default_mode>,
+ <&pwm_default_mode>,
+ <&adi2_default_mode>,
+ <&modsclsda_default_mode>,
+ <&resethw_default_mode>,
+ <&service_default_mode>;
+
+ /*
+ * Pins 2, 10, 11, 13, 34 and 50
+ * are muxed in as GPIO, and configured as INPUT PULL DOWN
+ */
+ gpio2 {
+ gpio2_default_mode: gpio2_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio2_a_1";
+ };
+ default_cfg {
+ pins = "GPIO2_R5";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio10 {
+ gpio10_default_mode: gpio10_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio10_d_1";
+ };
+ default_cfg {
+ pins = "GPIO10_B16";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio11 {
+ gpio11_default_mode: gpio11_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio11_d_1";
+ };
+ default_cfg {
+ pins = "GPIO11_B17";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio13 {
+ gpio13_default_mode: gpio13_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio13_d_1";
+ };
+ default_cfg {
+ pins = "GPIO13_D17";
+ input-enable;
+ bias-disable;
+ };
+ };
+ };
+ gpio34 {
+ gpio34_default_mode: gpio34_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio34_a_1";
+ };
+ default_cfg {
+ pins = "GPIO34_H14";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ gpio50 {
+ gpio50_default_mode: gpio50_default {
+ default_mux {
+ function = "gpio";
+ groups = "gpio50_d_1";
+ };
+ default_cfg {
+ pins = "GPIO50_L4";
+ input-enable;
+ bias-disable;
+ };
+ };
+ };
+ /* This sets up the PWM pin 14 */
+ pwm {
+ pwm_default_mode: pwm_default {
+ default_mux {
+ function = "pwmout";
+ groups = "pwmout1_d_1";
+ };
+ default_cfg {
+ pins = "GPIO14_C16";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ /* This sets up audio interface 2 */
+ adi2 {
+ adi2_default_mode: adi2_default {
+ default_mux {
+ function = "adi2";
+ groups = "adi2_d_1";
+ };
+ default_cfg {
+ pins = "GPIO17_P2",
+ "GPIO18_N3",
+ "GPIO19_T1",
+ "GPIO20_P3";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ /* Modem I2C setup (SCL and SDA pins) */
+ modsclsda {
+ modsclsda_default_mode: modsclsda_default {
+ default_mux {
+ function = "modsclsda";
+ groups = "modsclsda_d_1";
+ };
+ default_cfg {
+ pins = "GPIO40_J15",
+ "GPIO41_J14";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ resethw {
+ resethw_default_mode: resethw_default {
+ default_mux {
+ function = "resethw";
+ groups = "resethw_d_1";
+ };
+ default_cfg {
+ pins = "GPIO52_D16";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ service {
+ service_default_mode: service_default {
+ default_mux {
+ function = "service";
+ groups = "service_d_1";
+ };
+ default_cfg {
+ pins = "GPIO53_D15";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ /*
+ * Clock output pins associated with regulators.
+ */
+ sysclkreq2 {
+ sysclkreq2_default_mode: sysclkreq2_default {
+ default_mux {
+ function = "sysclkreq";
+ groups = "sysclkreq2_d_1";
+ };
+ default_cfg {
+ pins = "GPIO1_N4";
+ input-enable;
+ bias-disable;
+ };
+ };
+ sysclkreq2_sleep_mode: sysclkreq2_sleep {
+ default_mux {
+ function = "gpio";
+ groups = "gpio1_a_1";
+ };
+ default_cfg {
+ pins = "GPIO1_N4";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ sysclkreq4 {
+ sysclkreq4_default_mode: sysclkreq4_default {
+ default_mux {
+ function = "sysclkreq";
+ groups = "sysclkreq4_d_1";
+ };
+ default_cfg {
+ pins = "GPIO3_P5";
+ input-enable;
+ bias-disable;
+ };
+ };
+ sysclkreq4_sleep_mode: sysclkreq4_sleep {
+ default_mux {
+ function = "gpio";
+ groups = "gpio3_a_1";
+ };
+ default_cfg {
+ pins = "GPIO3_P5";
+ input-enable;
+ bias-pull-down;
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-href-family-pinctrl.dtsi b/arch/arm/boot/dts/ste-href-family-pinctrl.dtsi
new file mode 100644
index 000000000..5c5cea232
--- /dev/null
+++ b/arch/arm/boot/dts/ste-href-family-pinctrl.dtsi
@@ -0,0 +1,745 @@
+/*
+ * Copyright 2013 Linaro Ltd.
+ *
+ * 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 "ste-nomadik-pinctrl.dtsi"
+
+/ {
+ soc {
+ pinctrl {
+ /* Settings for all UART default and sleep states */
+ uart0 {
+ uart0_default_mode: uart0_default {
+ default_mux {
+ function = "u0";
+ groups = "u0_a_1";
+ };
+ default_cfg1 {
+ pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */
+ ste,config = <&in_pu>;
+ };
+
+ default_cfg2 {
+ pins = "GPIO1_AJ3", "GPIO3_AH3"; /* RTS+TXD */
+ ste,config = <&out_hi>;
+ };
+ };
+
+ uart0_sleep_mode: uart0_sleep {
+ sleep_cfg1 {
+ pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */
+ ste,config = <&slpm_in_wkup_pdis>;
+ };
+
+ sleep_cfg2 {
+ pins = "GPIO1_AJ3"; /* RTS */
+ ste,config = <&slpm_out_hi_wkup_pdis>;
+ };
+
+ sleep_cfg3 {
+ pins = "GPIO3_AH3"; /* TXD */
+ ste,config = <&slpm_out_wkup_pdis>;
+ };
+ };
+ };
+
+ uart1 {
+ uart1_default_mode: uart1_default {
+ default_mux {
+ function = "u1";
+ groups = "u1rxtx_a_1";
+ };
+ default_cfg1 {
+ pins = "GPIO4_AH6"; /* RXD */
+ ste,config = <&in_pu>;
+ };
+
+ default_cfg2 {
+ pins = "GPIO5_AG6"; /* TXD */
+ ste,config = <&out_hi>;
+ };
+ };
+
+ uart1_sleep_mode: uart1_sleep {
+ sleep_cfg1 {
+ pins = "GPIO4_AH6"; /* RXD */
+ ste,config = <&slpm_in_wkup_pdis>;
+ };
+
+ sleep_cfg2 {
+ pins = "GPIO5_AG6"; /* TXD */
+ ste,config = <&slpm_out_wkup_pdis>;
+ };
+ };
+ };
+
+ uart2 {
+ uart2_default_mode: uart2_default {
+ default_mux {
+ function = "u2";
+ groups = "u2rxtx_c_1";
+ };
+ default_cfg1 {
+ pins = "GPIO29_W2"; /* RXD */
+ ste,config = <&in_pu>;
+ };
+
+ default_cfg2 {
+ pins = "GPIO30_W3"; /* TXD */
+ ste,config = <&out_hi>;
+ };
+ };
+
+ uart2_sleep_mode: uart2_sleep {
+ sleep_cfg1 {
+ pins = "GPIO29_W2"; /* RXD */
+ ste,config = <&in_wkup_pdis>;
+ };
+
+ sleep_cfg2 {
+ pins = "GPIO30_W3"; /* TXD */
+ ste,config = <&out_wkup_pdis>;
+ };
+ };
+ };
+
+ /* Settings for all I2C default and sleep states */
+ i2c0 {
+ i2c0_default_mode: i2c_default {
+ default_mux {
+ function = "i2c0";
+ groups = "i2c0_a_1";
+ };
+ default_cfg1 {
+ pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */
+ ste,config = <&in_pu>;
+ };
+ };
+
+ i2c0_sleep_mode: i2c_sleep {
+ sleep_cfg1 {
+ pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */
+ ste,config = <&slpm_in_wkup_pdis>;
+ };
+ };
+ };
+
+ i2c1 {
+ i2c1_default_mode: i2c_default {
+ default_mux {
+ function = "i2c1";
+ groups = "i2c1_b_2";
+ };
+ default_cfg1 {
+ pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */
+ ste,config = <&in_pu>;
+ };
+ };
+
+ i2c1_sleep_mode: i2c_sleep {
+ sleep_cfg1 {
+ pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */
+ ste,config = <&slpm_in_wkup_pdis>;
+ };
+ };
+ };
+
+ i2c2 {
+ i2c2_default_mode: i2c_default {
+ default_mux {
+ function = "i2c2";
+ groups = "i2c2_b_2";
+ };
+ default_cfg1 {
+ pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */
+ ste,config = <&in_pu>;
+ };
+ };
+
+ i2c2_sleep_mode: i2c_sleep {
+ sleep_cfg1 {
+ pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */
+ ste,config = <&slpm_in_wkup_pdis>;
+ };
+ };
+ };
+
+ i2c3 {
+ i2c3_default_mode: i2c_default {
+ default_mux {
+ function = "i2c3";
+ groups = "i2c3_c_2";
+ };
+ default_cfg1 {
+ pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */
+ ste,config = <&in_pu>;
+ };
+ };
+
+ i2c3_sleep_mode: i2c_sleep {
+ sleep_cfg1 {
+ pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */
+ ste,config = <&slpm_in_wkup_pdis>;
+ };
+ };
+ };
+
+ /*
+ * Activating I2C4 will conflict with UART1 about the same pins so do not
+ * enable I2C4 and UART1 at the same time.
+ */
+ i2c4 {
+ i2c4_default_mode: i2c_default {
+ default_mux {
+ function = "i2c4";
+ groups = "i2c4_b_1";
+ };
+ default_cfg1 {
+ pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */
+ ste,config = <&in_pu>;
+ };
+ };
+
+ i2c4_sleep_mode: i2c_sleep {
+ sleep_cfg1 {
+ pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */
+ ste,config = <&slpm_in_wkup_pdis>;
+ };
+ };
+ };
+
+ /* Settings for all SPI default and sleep states */
+ spi2 {
+ spi2_default_mode: spi_default {
+ default_mux {
+ function = "spi2";
+ groups = "spi2_oc1_2";
+ };
+ default_cfg1 {
+ pins = "GPIO216_AG12"; /* FRM */
+ ste,config = <&gpio_out_hi>;
+ };
+ default_cfg2 {
+ pins = "GPIO218_AH11"; /* RXD */
+ ste,config = <&in_pd>;
+ };
+ default_cfg3 {
+ pins =
+ "GPIO215_AH13", /* TXD */
+ "GPIO217_AH12"; /* CLK */
+ ste,config = <&out_lo>;
+ };
+ };
+
+ spi2_idle_mode: spi_idle {
+ /*
+ * The idle mode is basically sleep mode sans wakeups. Also
+ * note that we have muxes the pins off the function here
+ * as we do not state any muxing.
+ */
+ idle_cfg1 {
+ pins = "GPIO218_AH11"; /* RXD */
+ ste,config = <&slpm_in_pdis>;
+ };
+ idle_cfg2 {
+ pins = "GPIO215_AH13"; /* TXD */
+ ste,config = <&slpm_out_lo_pdis>;
+ };
+ idle_cfg3 {
+ pins = "GPIO217_AH12"; /* CLK */
+ ste,config = <&slpm_pdis>;
+ };
+ };
+
+ spi2_sleep_mode: spi_sleep {
+ sleep_cfg1 {
+ pins =
+ "GPIO216_AG12", /* FRM */
+ "GPIO218_AH11"; /* RXD */
+ ste,config = <&slpm_in_wkup_pdis>;
+ };
+ sleep_cfg2 {
+ pins = "GPIO215_AH13"; /* TXD */
+ ste,config = <&slpm_out_lo_wkup_pdis>;
+ };
+ sleep_cfg3 {
+ pins = "GPIO217_AH12"; /* CLK */
+ ste,config = <&slpm_wkup_pdis>;
+ };
+ };
+ };
+
+ /* Settings for all MMC/SD/SDIO default and sleep states */
+ sdi0 {
+ /* This is the external SD card slot, 4 bits wide */
+ sdi0_default_mode: sdi0_default {
+ default_mux {
+ function = "mc0";
+ groups = "mc0_a_1";
+ };
+ default_cfg1 {
+ pins =
+ "GPIO18_AC2", /* CMDDIR */
+ "GPIO19_AC1", /* DAT0DIR */
+ "GPIO20_AB4"; /* DAT2DIR */
+ ste,config = <&out_hi>;
+ };
+ default_cfg2 {
+ pins = "GPIO22_AA3"; /* FBCLK */
+ ste,config = <&in_nopull>;
+ };
+ default_cfg3 {
+ pins = "GPIO23_AA4"; /* CLK */
+ ste,config = <&out_lo>;
+ };
+ default_cfg4 {
+ pins =
+ "GPIO24_AB2", /* CMD */
+ "GPIO25_Y4", /* DAT0 */
+ "GPIO26_Y2", /* DAT1 */
+ "GPIO27_AA2", /* DAT2 */
+ "GPIO28_AA1"; /* DAT3 */
+ ste,config = <&in_pu>;
+ };
+ };
+
+ sdi0_sleep_mode: sdi0_sleep {
+ sleep_cfg1 {
+ pins =
+ "GPIO18_AC2", /* CMDDIR */
+ "GPIO19_AC1", /* DAT0DIR */
+ "GPIO20_AB4"; /* DAT2DIR */
+ ste,config = <&slpm_out_hi_wkup_pdis>;
+ };
+ sleep_cfg2 {
+ pins =
+ "GPIO22_AA3", /* FBCLK */
+ "GPIO24_AB2", /* CMD */
+ "GPIO25_Y4", /* DAT0 */
+ "GPIO26_Y2", /* DAT1 */
+ "GPIO27_AA2", /* DAT2 */
+ "GPIO28_AA1"; /* DAT3 */
+ ste,config = <&slpm_in_wkup_pdis>;
+ };
+ sleep_cfg3 {
+ pins = "GPIO23_AA4"; /* CLK */
+ ste,config = <&slpm_out_lo_wkup_pdis>;
+ };
+ };
+ };
+
+ sdi1 {
+ /* This is the WLAN SDIO 4 bits wide */
+ sdi1_default_mode: sdi1_default {
+ default_mux {
+ function = "mc1";
+ groups = "mc1_a_1";
+ };
+ default_cfg1 {
+ pins = "GPIO208_AH16"; /* CLK */
+ ste,config = <&out_lo>;
+ };
+ default_cfg2 {
+ pins = "GPIO209_AG15"; /* FBCLK */
+ ste,config = <&in_nopull>;
+ };
+ default_cfg3 {
+ pins =
+ "GPIO210_AJ15", /* CMD */
+ "GPIO211_AG14", /* DAT0 */
+ "GPIO212_AF13", /* DAT1 */
+ "GPIO213_AG13", /* DAT2 */
+ "GPIO214_AH15"; /* DAT3 */
+ ste,config = <&in_pu>;
+ };
+ };
+
+ sdi1_sleep_mode: sdi1_sleep {
+ sleep_cfg1 {
+ pins = "GPIO208_AH16"; /* CLK */
+ ste,config = <&slpm_out_lo_wkup_pdis>;
+ };
+ sleep_cfg2 {
+ pins =
+ "GPIO209_AG15", /* FBCLK */
+ "GPIO210_AJ15", /* CMD */
+ "GPIO211_AG14", /* DAT0 */
+ "GPIO212_AF13", /* DAT1 */
+ "GPIO213_AG13", /* DAT2 */
+ "GPIO214_AH15"; /* DAT3 */
+ ste,config = <&slpm_in_wkup_pdis>;
+ };
+ };
+ };
+
+ sdi2 {
+ /* This is the eMMC 8 bits wide, usually PoP eMMC */
+ sdi2_default_mode: sdi2_default {
+ default_mux {
+ function = "mc2";
+ groups = "mc2_a_1";
+ };
+ default_cfg1 {
+ pins = "GPIO128_A5"; /* CLK */
+ ste,config = <&out_lo>;
+ };
+ default_cfg2 {
+ pins = "GPIO130_C8"; /* FBCLK */
+ ste,config = <&in_nopull>;
+ };
+ default_cfg3 {
+ pins =
+ "GPIO129_B4", /* CMD */
+ "GPIO131_A12", /* DAT0 */
+ "GPIO132_C10", /* DAT1 */
+ "GPIO133_B10", /* DAT2 */
+ "GPIO134_B9", /* DAT3 */
+ "GPIO135_A9", /* DAT4 */
+ "GPIO136_C7", /* DAT5 */
+ "GPIO137_A7", /* DAT6 */
+ "GPIO138_C5"; /* DAT7 */
+ ste,config = <&in_pu>;
+ };
+ };
+
+ sdi2_sleep_mode: sdi2_sleep {
+ sleep_cfg1 {
+ pins = "GPIO128_A5"; /* CLK */
+ ste,config = <&out_lo_wkup_pdis>;
+ };
+ sleep_cfg2 {
+ pins =
+ "GPIO130_C8", /* FBCLK */
+ "GPIO129_B4"; /* CMD */
+ ste,config = <&in_wkup_pdis_en>;
+ };
+ sleep_cfg3 {
+ pins =
+ "GPIO131_A12", /* DAT0 */
+ "GPIO132_C10", /* DAT1 */
+ "GPIO133_B10", /* DAT2 */
+ "GPIO134_B9", /* DAT3 */
+ "GPIO135_A9", /* DAT4 */
+ "GPIO136_C7", /* DAT5 */
+ "GPIO137_A7", /* DAT6 */
+ "GPIO138_C5"; /* DAT7 */
+ ste,config = <&in_wkup_pdis>;
+ };
+ };
+ };
+
+ sdi4 {
+ /* This is the eMMC 8 bits wide, usually PCB-mounted eMMC */
+ sdi4_default_mode: sdi4_default {
+ default_mux {
+ function = "mc4";
+ groups = "mc4_a_1";
+ };
+ default_cfg1 {
+ pins = "GPIO203_AE23"; /* CLK */
+ ste,config = <&out_lo>;
+ };
+ default_cfg2 {
+ pins = "GPIO202_AF25"; /* FBCLK */
+ ste,config = <&in_nopull>;
+ };
+ default_cfg3 {
+ pins =
+ "GPIO201_AF24", /* CMD */
+ "GPIO200_AH26", /* DAT0 */
+ "GPIO199_AH23", /* DAT1 */
+ "GPIO198_AG25", /* DAT2 */
+ "GPIO197_AH24", /* DAT3 */
+ "GPIO207_AJ23", /* DAT4 */
+ "GPIO206_AG24", /* DAT5 */
+ "GPIO205_AG23", /* DAT6 */
+ "GPIO204_AF23"; /* DAT7 */
+ ste,config = <&in_pu>;
+ };
+ };
+
+ sdi4_sleep_mode: sdi4_sleep {
+ sleep_cfg1 {
+ pins = "GPIO203_AE23"; /* CLK */
+ ste,config = <&out_lo_wkup_pdis>;
+ };
+ sleep_cfg2 {
+ pins =
+ "GPIO202_AF25", /* FBCLK */
+ "GPIO201_AF24", /* CMD */
+ "GPIO200_AH26", /* DAT0 */
+ "GPIO199_AH23", /* DAT1 */
+ "GPIO198_AG25", /* DAT2 */
+ "GPIO197_AH24", /* DAT3 */
+ "GPIO207_AJ23", /* DAT4 */
+ "GPIO206_AG24", /* DAT5 */
+ "GPIO205_AG23", /* DAT6 */
+ "GPIO204_AF23"; /* DAT7 */
+ ste,config = <&slpm_in_wkup_pdis>;
+ };
+ };
+ };
+
+ /*
+ * Multi-rate serial ports (MSPs) - MSP3 output is internal and
+ * cannot be muxed onto any pins.
+ */
+ msp0 {
+ msp0_default_mode: msp0_default {
+ default_msp0_mux {
+ function = "msp0";
+ groups = "msp0txrx_a_1", "msp0tfstck_a_1";
+ };
+ default_msp0_cfg {
+ pins =
+ "GPIO12_AC4", /* TXD */
+ "GPIO15_AC3", /* RXD */
+ "GPIO13_AF3", /* TFS */
+ "GPIO14_AE3"; /* TCK */
+ ste,config = <&in_nopull>;
+ };
+ };
+ };
+
+ msp1 {
+ msp1_default_mode: msp1_default {
+ default_mux {
+ function = "msp1";
+ groups = "msp1txrx_a_1", "msp1_a_1";
+ };
+ default_cfg1 {
+ pins = "GPIO33_AF2";
+ ste,config = <&out_lo>;
+ };
+ default_cfg2 {
+ pins =
+ "GPIO34_AE1",
+ "GPIO35_AE2",
+ "GPIO36_AG2";
+ ste,config = <&in_nopull>;
+ };
+
+ };
+ };
+
+ msp2 {
+ msp2_default_mode: msp2_default {
+ /* MSP2 usually used for HDMI audio */
+ default_mux {
+ function = "msp2";
+ groups = "msp2_a_1";
+ };
+ default_cfg1 {
+ pins =
+ "GPIO193_AH27", /* TXD */
+ "GPIO194_AF27", /* TCK */
+ "GPIO195_AG28"; /* TFS */
+ ste,config = <&in_pd>;
+ };
+ default_cfg2 {
+ pins = "GPIO196_AG26"; /* RXD */
+ ste,config = <&out_lo>;
+ };
+ };
+ };
+
+
+ musb {
+ musb_default_mode: musb_default {
+ default_mux {
+ function = "usb";
+ groups = "usb_a_1";
+ };
+ default_cfg1 {
+ pins =
+ "GPIO256_AF28", /* NXT */
+ "GPIO258_AD29", /* XCLK */
+ "GPIO259_AC29", /* DIR */
+ "GPIO260_AD28", /* DAT7 */
+ "GPIO261_AD26", /* DAT6 */
+ "GPIO262_AE26", /* DAT5 */
+ "GPIO263_AG29", /* DAT4 */
+ "GPIO264_AE27", /* DAT3 */
+ "GPIO265_AD27", /* DAT2 */
+ "GPIO266_AC28", /* DAT1 */
+ "GPIO267_AC27"; /* DAT0 */
+ ste,config = <&in_nopull>;
+ };
+ default_cfg2 {
+ pins = "GPIO257_AE29"; /* STP */
+ ste,config = <&out_hi>;
+ };
+ };
+
+ musb_sleep_mode: musb_sleep {
+ sleep_cfg1 {
+ pins =
+ "GPIO256_AF28", /* NXT */
+ "GPIO258_AD29", /* XCLK */
+ "GPIO259_AC29"; /* DIR */
+ ste,config = <&slpm_wkup_pdis_en>;
+ };
+ sleep_cfg2 {
+ pins = "GPIO257_AE29"; /* STP */
+ ste,config = <&slpm_out_hi_wkup_pdis>;
+ };
+ sleep_cfg3 {
+ pins =
+ "GPIO260_AD28", /* DAT7 */
+ "GPIO261_AD26", /* DAT6 */
+ "GPIO262_AE26", /* DAT5 */
+ "GPIO263_AG29", /* DAT4 */
+ "GPIO264_AE27", /* DAT3 */
+ "GPIO265_AD27", /* DAT2 */
+ "GPIO266_AC28", /* DAT1 */
+ "GPIO267_AC27"; /* DAT0 */
+ ste,config = <&slpm_in_wkup_pdis_en>;
+ };
+ };
+ };
+
+ mcde {
+ lcd_default_mode: lcd_default {
+ default_mux {
+ /* Mux in VSI0 and all the data lines */
+ function = "lcd";
+ groups =
+ "lcdvsi0_a_1", /* VSI0 for LCD */
+ "lcd_d0_d7_a_1", /* Data lines */
+ "lcd_d8_d11_a_1", /* TV-out */
+ "lcdaclk_b_1", /* Clock line for TV-out */
+ "lcdvsi1_a_1"; /* VSI1 for HDMI */
+ };
+ default_cfg1 {
+ pins =
+ "GPIO68_E1", /* VSI0 */
+ "GPIO69_E2"; /* VSI1 */
+ ste,config = <&in_pu>;
+ };
+ };
+ lcd_sleep_mode: lcd_sleep {
+ sleep_cfg1 {
+ pins = "GPIO69_E2"; /* VSI1 */
+ ste,config = <&slpm_in_wkup_pdis>;
+ };
+ };
+ };
+
+ ske {
+ /* SKE keys on position 2 in an 8x8 matrix */
+ ske_kpa2_default_mode: ske_kpa2_default {
+ default_mux {
+ function = "kp";
+ groups = "kp_a_2";
+ };
+ default_cfg1 {
+ pins =
+ "GPIO153_B17", /* I7 */
+ "GPIO154_C16", /* I6 */
+ "GPIO155_C19", /* I5 */
+ "GPIO156_C17", /* I4 */
+ "GPIO161_D21", /* I3 */
+ "GPIO162_D20", /* I2 */
+ "GPIO163_C20", /* I1 */
+ "GPIO164_B21"; /* I0 */
+ ste,config = <&in_pd>;
+ };
+ default_cfg2 {
+ pins =
+ "GPIO157_A18", /* O7 */
+ "GPIO158_C18", /* O6 */
+ "GPIO159_B19", /* O5 */
+ "GPIO160_B20", /* O4 */
+ "GPIO165_C21", /* O3 */
+ "GPIO166_A22", /* O2 */
+ "GPIO167_B24", /* O1 */
+ "GPIO168_C22"; /* O0 */
+ ste,config = <&out_lo>;
+ };
+ };
+ ske_kpa2_sleep_mode: ske_kpa2_sleep {
+ sleep_cfg1 {
+ pins =
+ "GPIO153_B17", /* I7 */
+ "GPIO154_C16", /* I6 */
+ "GPIO155_C19", /* I5 */
+ "GPIO156_C17", /* I4 */
+ "GPIO161_D21", /* I3 */
+ "GPIO162_D20", /* I2 */
+ "GPIO163_C20", /* I1 */
+ "GPIO164_B21"; /* I0 */
+ ste,config = <&slpm_in_pu_wkup_pdis_en>;
+ };
+ sleep_cfg2 {
+ pins =
+ "GPIO157_A18", /* O7 */
+ "GPIO158_C18", /* O6 */
+ "GPIO159_B19", /* O5 */
+ "GPIO160_B20", /* O4 */
+ "GPIO165_C21", /* O3 */
+ "GPIO166_A22", /* O2 */
+ "GPIO167_B24", /* O1 */
+ "GPIO168_C22"; /* O0 */
+ ste,config = <&slpm_out_lo_pdis>;
+ };
+ };
+ /*
+ * SKE keys on position 1 and "other C1" combi giving
+ * six rows of six keys.
+ */
+ ske_kpaoc1_default_mode: ske_kpaoc1_default {
+ default_mux {
+ function = "kp";
+ groups = "kp_a_1", "kp_oc1_1";
+ };
+ default_cfg1 {
+ pins =
+ "GPIO91_B6", /* KP_O0 */
+ "GPIO90_A3", /* KP_O1 */
+ "GPIO87_B3", /* KP_O2 */
+ "GPIO86_C6", /* KP_O3 */
+ "GPIO96_D8", /* KP_O6 */
+ "GPIO94_D7"; /* KP_O7 */
+ ste,config = <&out_lo>;
+ };
+ default_cfg2 {
+ pins =
+ "GPIO93_B7", /* KP_I0 */
+ "GPIO92_D6", /* KP_I1 */
+ "GPIO89_E6", /* KP_I2 */
+ "GPIO88_C4", /* KP_I3 */
+ "GPIO97_D9", /* KP_I6 */
+ "GPIO95_E8"; /* KP_I7 */
+ ste,config = <&in_pu>;
+ };
+ };
+ };
+
+ wlan {
+ wlan_default_mode: wlan_default {
+ /*
+ * Activate this mode with the WLAN chip.
+ * These are plain GPIO pins used by WLAN
+ */
+ default_cfg1 {
+ pins =
+ "GPIO226_AF8", /* WLAN_PMU_EN */
+ "GPIO85_D5"; /* WLAN_ENA */
+ ste,config = <&gpio_out_lo>;
+ };
+ default_cfg2 {
+ pins = "GPIO4_AH6"; /* WLAN_IRQ on UART1 */
+ ste,config = <&gpio_in_pu>;
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-href-stuib.dtsi b/arch/arm/boot/dts/ste-href-stuib.dtsi
new file mode 100644
index 000000000..7d4f8184c
--- /dev/null
+++ b/arch/arm/boot/dts/ste-href-stuib.dtsi
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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 <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ vdd-supply = <&ab8500_ldo_aux1_reg>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&prox_stuib_mode>, <&hall_stuib_mode>;
+
+ button@139 {
+ /* Proximity sensor */
+ gpios = <&gpio6 25 0x4>;
+ linux,code = <11>; /* SW_FRONT_PROXIMITY */
+ label = "SFH7741 Proximity Sensor";
+ };
+ button@145 {
+ /* Hall sensor */
+ gpios = <&gpio4 17 0x4>;
+ linux,code = <0>; /* SW_LID */
+ label = "HED54XXU11 Hall Effect Sensor";
+ };
+ };
+
+ soc {
+ i2c@80004000 {
+ stmpe1601: stmpe1601@40 {
+ compatible = "st,stmpe1601";
+ reg = <0x40>;
+ interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-parent = <&gpio6>;
+ interrupt-controller;
+ vcc-supply = <&db8500_vsmps2_reg>;
+ vio-supply = <&db8500_vsmps2_reg>;
+
+ wakeup-source;
+ st,autosleep-timeout = <1024>;
+
+ stmpe_keypad {
+ compatible = "st,stmpe-keypad";
+
+ debounce-interval = <64>;
+ st,scan-count = <8>;
+ st,no-autorepeat;
+
+ linux,keymap = <0x205006b
+ 0x4010074
+ 0x3050072
+ 0x1030004
+ 0x502006a
+ 0x500000a
+ 0x5008b
+ 0x706001c
+ 0x405000b
+ 0x6070003
+ 0x3040067
+ 0x303006c
+ 0x60400e7
+ 0x602009e
+ 0x4020073
+ 0x5050002
+ 0x4030069
+ 0x3020008>;
+ };
+ };
+ };
+
+ i2c@80110000 {
+ bu21013_tp@5c {
+ compatible = "rohm,bu21013_tp";
+ reg = <0x5c>;
+ avdd-supply = <&ab8500_ldo_aux1_reg>;
+
+ rohm,touch-max-x = <384>;
+ rohm,touch-max-y = <704>;
+ rohm,flip-y;
+ };
+
+ bu21013_tp@5d {
+ compatible = "rohm,bu21013_tp";
+ reg = <0x5d>;
+ avdd-supply = <&ab8500_ldo_aux1_reg>;
+
+ rohm,touch-max-x = <384>;
+ rohm,touch-max-y = <704>;
+ rohm,flip-y;
+ };
+ };
+
+ pinctrl {
+ prox {
+ prox_stuib_mode: prox_stuib {
+ stuib_cfg {
+ pins = "GPIO217_AH12";
+ ste,config = <&gpio_in_pu>;
+ };
+ };
+ };
+ hall {
+ hall_stuib_mode: stuib_tvk {
+ stuib_cfg {
+ pins = "GPIO145_C13";
+ ste,config = <&gpio_in_pu>;
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-href-tvk1281618.dtsi b/arch/arm/boot/dts/ste-href-tvk1281618.dtsi
new file mode 100644
index 000000000..062c6aae3
--- /dev/null
+++ b/arch/arm/boot/dts/ste-href-tvk1281618.dtsi
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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
+ *
+ * Device Tree for the TVK1281618 UIB
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ vdd-supply = <&ab8500_ldo_aux1_reg>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&prox_tvk_mode>, <&hall_tvk_mode>;
+
+ button@139 {
+ /* Proximity sensor */
+ gpios = <&gpio6 25 0x4>;
+ linux,code = <11>; /* SW_FRONT_PROXIMITY */
+ label = "SFH7741 Proximity Sensor";
+ };
+ button@145 {
+ /* Hall sensor */
+ gpios = <&gpio4 17 0x4>;
+ linux,code = <0>; /* SW_LID */
+ label = "HED54XXU11 Hall Effect Sensor";
+ };
+ };
+
+ soc {
+ /* Add Synaptics touch screen, TC35893 keypad etc here */
+ i2c@80004000 {
+ tc35893@44 {
+ compatible = "toshiba,tc35893";
+ reg = <0x44>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <26 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&tc35893_tvk_mode>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ tc3589x_gpio {
+ compatible = "toshiba,tc3589x-gpio";
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ tc3589x_keypad {
+ compatible = "toshiba,tc3589x-keypad";
+ interrupts = <6>;
+ debounce-delay-ms = <4>;
+ keypad,num-columns = <8>;
+ keypad,num-rows = <8>;
+ linux,no-autorepeat;
+ linux,wakeup;
+ linux,keymap = <0x0301006b
+ 0x04010066
+ 0x06040072
+ 0x040200d7
+ 0x0303006a
+ 0x0205000e
+ 0x0607008b
+ 0x0500001c
+ 0x0403000b
+ 0x03040034
+ 0x05020067
+ 0x0305006c
+ 0x040500e7
+ 0x0005009e
+ 0x06020073
+ 0x01030039
+ 0x07060069
+ 0x050500d9>;
+ };
+ };
+ };
+ /* Sensors mounted on this board variant */
+ i2c@80128000 {
+ lsm303dlh@18 {
+ /* Accelerometer */
+ compatible = "st,lsm303dlh-accel";
+ st,drdy-int-pin = <1>;
+ reg = <0x18>;
+ vdd-supply = <&ab8500_ldo_aux1_reg>;
+ vddio-supply = <&db8500_vsmps2_reg>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&accel_tvk_mode>;
+ };
+ lsm303dlm@1e {
+ /* Magnetometer */
+ compatible = "st,lsm303dlm-magn";
+ reg = <0x1e>;
+ vdd-supply = <&ab8500_ldo_aux1_reg>;
+ vddio-supply = <&db8500_vsmps2_reg>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&magneto_tvk_mode>;
+ };
+ l3g4200d@68 {
+ /* Gyroscope */
+ compatible = "st,l3g4200d-gyro";
+ st,drdy-int-pin = <2>;
+ reg = <0x68>;
+ vdd-supply = <&ab8500_ldo_aux1_reg>;
+ vddio-supply = <&db8500_vsmps2_reg>;
+ };
+ lsp001wm@5c {
+ /* Barometer/pressure sensor */
+ compatible = "st,lps001wp-press";
+ reg = <0x5c>;
+ vdd-supply = <&ab8500_ldo_aux1_reg>;
+ vddio-supply = <&db8500_vsmps2_reg>;
+ };
+ };
+ pinctrl {
+ /* Pull up this GPIO pin */
+ tc35893 {
+ tc35893_tvk_mode: tc35893_tvk {
+ tvk_cfg {
+ pins = "GPIO218_AH11";
+ ste,config = <&gpio_in_pu>;
+ };
+ };
+ };
+ prox {
+ prox_tvk_mode: prox_tvk {
+ tvk_cfg {
+ pins = "GPIO217_AH12";
+ ste,config = <&gpio_in_pu>;
+ };
+ };
+ };
+ hall {
+ hall_tvk_mode: hall_tvk {
+ tvk_cfg {
+ pins = "GPIO145_C13";
+ ste,config = <&gpio_in_pu>;
+ };
+ };
+ };
+ accelerometer {
+ accel_tvk_mode: accel_tvk {
+ /* Accelerometer interrupt lines 1 & 2 */
+ tvk_cfg {
+ pins = "GPIO82_C1", "GPIO83_D3";
+ ste,config = <&gpio_in_pu>;
+ };
+ };
+ };
+ magnetometer {
+ magneto_tvk_mode: magneto_tvk {
+ /* Magnetometer uses GPIO 31 and 32, pull these up/down respectively */
+ tvk_cfg1 {
+ pins = "GPIO31_V3";
+ ste,config = <&gpio_in_pu>;
+ };
+ tvk_cfg2 {
+ pins = "GPIO32_V2";
+ ste,config = <&gpio_in_pd>;
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi
new file mode 100644
index 000000000..744c1e3a7
--- /dev/null
+++ b/arch/arm/boot/dts/ste-href.dtsi
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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 <dt-bindings/interrupt-controller/irq.h>
+#include "ste-dbx5x0.dtsi"
+#include "ste-href-family-pinctrl.dtsi"
+
+/ {
+ memory {
+ reg = <0x00000000 0x20000000>;
+ };
+
+ soc {
+ usb_per5@a03e0000 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&musb_default_mode>;
+ pinctrl-1 = <&musb_sleep_mode>;
+ };
+
+ uart@80120000 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&uart0_default_mode>;
+ pinctrl-1 = <&uart0_sleep_mode>;
+ status = "okay";
+ };
+
+ uart@80121000 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&uart1_default_mode>;
+ pinctrl-1 = <&uart1_sleep_mode>;
+ status = "okay";
+ };
+
+ uart@80007000 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&uart2_default_mode>;
+ pinctrl-1 = <&uart2_sleep_mode>;
+ status = "okay";
+ };
+
+ i2c@80004000 {
+ pinctrl-names = "default","sleep";
+ pinctrl-0 = <&i2c0_default_mode>;
+ pinctrl-1 = <&i2c0_sleep_mode>;
+ };
+
+ i2c@80122000 {
+ pinctrl-names = "default","sleep";
+ pinctrl-0 = <&i2c1_default_mode>;
+ pinctrl-1 = <&i2c1_sleep_mode>;
+ };
+
+ i2c@80128000 {
+ pinctrl-names = "default","sleep";
+ pinctrl-0 = <&i2c2_default_mode>;
+ pinctrl-1 = <&i2c2_sleep_mode>;
+ lp5521@33 {
+ compatible = "national,lp5521";
+ reg = <0x33>;
+ label = "lp5521_pri";
+ clock-mode = /bits/ 8 <2>;
+ chan0 {
+ led-cur = /bits/ 8 <0x2f>;
+ max-cur = /bits/ 8 <0x5f>;
+ linux,default-trigger = "heartbeat";
+ };
+ chan1 {
+ led-cur = /bits/ 8 <0x2f>;
+ max-cur = /bits/ 8 <0x5f>;
+ };
+ chan2 {
+ led-cur = /bits/ 8 <0x2f>;
+ max-cur = /bits/ 8 <0x5f>;
+ };
+ };
+ lp5521@34 {
+ compatible = "national,lp5521";
+ reg = <0x34>;
+ label = "lp5521_sec";
+ clock-mode = /bits/ 8 <2>;
+ chan0 {
+ led-cur = /bits/ 8 <0x2f>;
+ max-cur = /bits/ 8 <0x5f>;
+ };
+ chan1 {
+ led-cur = /bits/ 8 <0x2f>;
+ max-cur = /bits/ 8 <0x5f>;
+ };
+ chan2 {
+ led-cur = /bits/ 8 <0x2f>;
+ max-cur = /bits/ 8 <0x5f>;
+ };
+ };
+ bh1780@29 {
+ compatible = "rohm,bh1780gli";
+ reg = <0x29>;
+ };
+ };
+
+ i2c@80110000 {
+ pinctrl-names = "default","sleep";
+ pinctrl-0 = <&i2c3_default_mode>;
+ pinctrl-1 = <&i2c3_sleep_mode>;
+ };
+
+ vmmci: regulator-gpio {
+ compatible = "regulator-gpio";
+
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-name = "mmci-reg";
+ regulator-type = "voltage";
+
+ startup-delay-us = <100>;
+ enable-active-high;
+
+ states = <1800000 0x1
+ 2900000 0x0>;
+ };
+
+ // External Micro SD slot
+ sdi0_per1@80126000 {
+ arm,primecell-periphid = <0x10480180>;
+ max-frequency = <100000000>;
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ full-pwr-cycle;
+ st,sig-dir-dat0;
+ st,sig-dir-dat2;
+ st,sig-dir-cmd;
+ st,sig-pin-fbclk;
+ vmmc-supply = <&ab8500_ldo_aux3_reg>;
+ vqmmc-supply = <&vmmci>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdi0_default_mode>;
+ pinctrl-1 = <&sdi0_sleep_mode>;
+
+ status = "okay";
+ };
+
+ // WLAN SDIO channel
+ sdi1_per2@80118000 {
+ arm,primecell-periphid = <0x10480180>;
+ max-frequency = <100000000>;
+ bus-width = <4>;
+ non-removable;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdi1_default_mode>;
+ pinctrl-1 = <&sdi1_sleep_mode>;
+
+ status = "okay";
+ };
+
+ // PoP:ed eMMC
+ sdi2_per3@80005000 {
+ arm,primecell-periphid = <0x10480180>;
+ max-frequency = <100000000>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ non-removable;
+ vmmc-supply = <&db8500_vsmps2_reg>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdi2_default_mode>;
+ pinctrl-1 = <&sdi2_sleep_mode>;
+
+ status = "okay";
+ };
+
+ // On-board eMMC
+ sdi4_per2@80114000 {
+ arm,primecell-periphid = <0x10480180>;
+ max-frequency = <100000000>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ non-removable;
+ vmmc-supply = <&ab8500_ldo_aux2_reg>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdi4_default_mode>;
+ pinctrl-1 = <&sdi4_sleep_mode>;
+
+ status = "okay";
+ };
+
+ sound {
+ compatible = "stericsson,snd-soc-mop500";
+
+ stericsson,cpu-dai = <&msp1 &msp3>;
+ stericsson,audio-codec = <&codec>;
+ };
+
+ msp0: msp@80123000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&msp0_default_mode>;
+ status = "okay";
+ };
+
+ msp1: msp@80124000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&msp1_default_mode>;
+ status = "okay";
+ };
+
+ msp2: msp@80117000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&msp2_default_mode>;
+ };
+
+ msp3: msp@80125000 {
+ status = "okay";
+ };
+
+ prcmu@80157000 {
+ ab8500 {
+ ab8500-gpio {
+ compatible = "stericsson,ab8500-gpio";
+ };
+
+ ab8500-regulators {
+ ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
+ regulator-name = "V-DISPLAY";
+ };
+
+ ab8500_ldo_aux2_reg: ab8500_ldo_aux2 {
+ regulator-name = "V-eMMC1";
+ };
+
+ ab8500_ldo_aux3_reg: ab8500_ldo_aux3 {
+ regulator-name = "V-MMC-SD";
+ };
+
+ ab8500_ldo_intcore_reg: ab8500_ldo_intcore {
+ regulator-name = "V-INTCORE";
+ };
+
+ ab8500_ldo_tvout_reg: ab8500_ldo_tvout {
+ regulator-name = "V-TVOUT";
+ };
+
+ ab8500_ldo_usb_reg: ab8500_ldo_usb {
+ regulator-name = "dummy";
+ };
+
+ ab8500_ldo_audio_reg: ab8500_ldo_audio {
+ regulator-name = "V-AUD";
+ };
+
+ ab8500_ldo_anamic1_reg: ab8500_ldo_anamic1 {
+ regulator-name = "V-AMIC1";
+ };
+
+ ab8500_ldo_anamic2_reg: ab8500_ldo_anamic2 {
+ regulator-name = "V-AMIC2";
+ };
+
+ ab8500_ldo_dmic_reg: ab8500_ldo_dmic {
+ regulator-name = "V-DMIC";
+ };
+
+ ab8500_ldo_ana_reg: ab8500_ldo_ana {
+ regulator-name = "V-CSI/DSI";
+ };
+ };
+ };
+ };
+
+ mcde@a0350000 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&lcd_default_mode>;
+ pinctrl-1 = <&lcd_sleep_mode>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-hrefprev60-stuib.dts b/arch/arm/boot/dts/ste-hrefprev60-stuib.dts
new file mode 100644
index 000000000..2b1cb5b58
--- /dev/null
+++ b/arch/arm/boot/dts/ste-hrefprev60-stuib.dts
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "ste-hrefprev60.dtsi"
+#include "ste-href-stuib.dtsi"
+
+/ {
+ model = "ST-Ericsson HREF (pre-v60) and ST UIB";
+ compatible = "st-ericsson,mop500", "st-ericsson,u8500";
+
+ soc {
+ /* Reset line for the BU21013 touchscreen */
+ i2c@80110000 {
+ /* Only one of these will be used */
+ bu21013_tp@5c {
+ touch-gpio = <&gpio2 12 0x4>;
+ reset-gpio = <&tc3589x_gpio 13 0x4>;
+ };
+ bu21013_tp@5d {
+ touch-gpio = <&gpio2 12 0x4>;
+ reset-gpio = <&tc3589x_gpio 13 0x4>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-hrefprev60-tvk.dts b/arch/arm/boot/dts/ste-hrefprev60-tvk.dts
new file mode 100644
index 000000000..59523f866
--- /dev/null
+++ b/arch/arm/boot/dts/ste-hrefprev60-tvk.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "ste-hrefprev60.dtsi"
+#include "ste-href-tvk1281618.dtsi"
+
+/ {
+ model = "ST-Ericsson HREF (pre-v60) and TVK1281618 UIB";
+ compatible = "st-ericsson,mop500", "st-ericsson,u8500";
+};
diff --git a/arch/arm/boot/dts/ste-hrefprev60.dtsi b/arch/arm/boot/dts/ste-hrefprev60.dtsi
new file mode 100644
index 000000000..7f3975b58
--- /dev/null
+++ b/arch/arm/boot/dts/ste-hrefprev60.dtsi
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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
+ *
+ * Device Tree for the HREF+ prior to the v60 variant.
+ */
+
+#include "ste-dbx5x0.dtsi"
+#include "ste-href-ab8500.dtsi"
+#include "ste-href.dtsi"
+
+/ {
+ gpio_keys {
+ button@1 {
+ gpios = <&tc3589x_gpio 7 0x4>;
+ };
+ };
+
+ soc {
+ i2c@80004000 {
+ tps61052@33 {
+ compatible = "tps61052";
+ reg = <0x33>;
+ };
+
+ tc35892@42 {
+ compatible = "toshiba,tc35892";
+ reg = <0x42>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <25 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&tc35892_hrefprev60_mode>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ tc3589x_gpio: tc3589x_gpio {
+ compatible = "tc3589x-gpio";
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+ };
+
+ ssp@80002000 {
+ /*
+ * On the first generation boards, this SSP/SPI port was connected
+ * to the AB8500.
+ */
+ pinctrl-names = "default";
+ pinctrl-0 = <&ssp0_hrefprev60_mode>;
+ };
+
+ // External Micro SD slot
+ sdi0_per1@80126000 {
+ cd-gpios = <&tc3589x_gpio 3 0x4>;
+ };
+
+ vmmci: regulator-gpio {
+ gpios = <&tc3589x_gpio 18 0x4>;
+ enable-gpio = <&tc3589x_gpio 17 0x4>;
+ };
+
+ pinctrl {
+ /* Set this up using hogs */
+ pinctrl-names = "default";
+ pinctrl-0 = <&ipgpio_hrefprev60_mode>;
+
+ ssp0 {
+ ssp0_hrefprev60_mode: ssp0_hrefprev60_default {
+ hrefprev60_mux {
+ function = "ssp0";
+ groups = "ssp0_a_1";
+ };
+ hrefprev60_cfg1 {
+ pins = "GPIO145_C13"; /* RXD */
+ ste,config = <&in_pd>;
+ };
+
+ };
+ };
+ sdi0 {
+ /* This additional pin needed on early MOP500 and HREFs previous to v60 */
+ sdi0_default_mode: sdi0_default {
+ hrefprev60_mux {
+ function = "mc0";
+ groups = "mc0dat31dir_a_1";
+ };
+ hrefprev60_cfg1 {
+ pins = "GPIO21_AB3"; /* DAT31DIR */
+ ste,config = <&out_hi>;
+ };
+
+ };
+ };
+ tc35892 {
+ tc35892_hrefprev60_mode: tc35892_hrefprev60 {
+ hrefprev60_cfg {
+ pins = "GPIO217_AH12";
+ ste,config = <&gpio_in_pu>;
+ };
+ };
+ };
+ ipgpio {
+ ipgpio_hrefprev60_mode: ipgpio_hrefprev60 {
+ hrefprev60_mux {
+ function = "ipgpio";
+ groups = "ipgpio0_c_1", "ipgpio1_c_1";
+ };
+ hrefprev60_cfg1 {
+ pins = "GPIO6_AF6", "GPIO7_AG5";
+ ste,config = <&in_pu>;
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-hrefv60plus-stuib.dts b/arch/arm/boot/dts/ste-hrefv60plus-stuib.dts
new file mode 100644
index 000000000..8c6a2de56
--- /dev/null
+++ b/arch/arm/boot/dts/ste-hrefv60plus-stuib.dts
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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
+ *
+ * Device Tree for the HREF version 60 or later with the ST UIB
+ */
+
+/dts-v1/;
+#include "ste-hrefv60plus.dtsi"
+#include "ste-href-stuib.dtsi"
+
+/ {
+ model = "ST-Ericsson HREF (v60+) and ST UIB";
+ compatible = "st-ericsson,hrefv60+", "st-ericsson,u8500";
+
+ soc {
+ /* Reset line for the BU21013 touchscreen */
+ i2c@80110000 {
+ /* Only one of these will be used */
+ bu21013_tp@5c {
+ touch-gpio = <&gpio2 20 0x4>;
+ reset-gpio = <&gpio4 17 0x4>;
+ };
+ bu21013_tp@5d {
+ touch-gpio = <&gpio2 20 0x4>;
+ reset-gpio = <&gpio4 17 0x4>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-hrefv60plus-tvk.dts b/arch/arm/boot/dts/ste-hrefv60plus-tvk.dts
new file mode 100644
index 000000000..d53cccdce
--- /dev/null
+++ b/arch/arm/boot/dts/ste-hrefv60plus-tvk.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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
+ *
+ * Device Tree for the HREF version 60 or later with the TVK1281618 UIB
+ */
+
+/dts-v1/;
+#include "ste-hrefv60plus.dtsi"
+#include "ste-href-tvk1281618.dtsi"
+
+/ {
+ model = "ST-Ericsson HREF (v60+) and TVK1281618 UIB";
+ compatible = "st-ericsson,hrefv60+", "st-ericsson,u8500";
+};
diff --git a/arch/arm/boot/dts/ste-hrefv60plus.dtsi b/arch/arm/boot/dts/ste-hrefv60plus.dtsi
new file mode 100644
index 000000000..a4bc9e77d
--- /dev/null
+++ b/arch/arm/boot/dts/ste-hrefv60plus.dtsi
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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 "ste-dbx5x0.dtsi"
+#include "ste-href-ab8500.dtsi"
+#include "ste-href.dtsi"
+
+/ {
+ model = "ST-Ericsson HREF (v60+) platform with Device Tree";
+ compatible = "st-ericsson,hrefv60+", "st-ericsson,u8500";
+
+ soc {
+ // External Micro SD slot
+ sdi0_per1@80126000 {
+ cd-gpios = <&gpio2 31 0x4>; // 95
+ };
+
+ vmmci: regulator-gpio {
+ gpios = <&gpio0 5 0x4>;
+ enable-gpio = <&gpio5 9 0x4>;
+ };
+
+ pinctrl {
+ /*
+ * Set this up using hogs, as time goes by and as seems fit, these
+ * can be moved over to being controlled by respective device.
+ */
+ pinctrl-names = "default";
+ pinctrl-0 = <&ipgpio_hrefv60_mode>,
+ <&etm_hrefv60_mode>,
+ <&nahj_hrefv60_mode>,
+ <&nfc_hrefv60_mode>,
+ <&force_hrefv60_mode>,
+ <&dipro_hrefv60_mode>,
+ <&vaudio_hf_hrefv60_mode>,
+ <&gbf_hrefv60_mode>,
+ <&hdtv_hrefv60_mode>,
+ <&touch_hrefv60_mode>;
+
+ sdi0 {
+ /* SD card detect GPIO pin, extend default state */
+ sdi0_default_mode: sdi0_default {
+ default_hrefv60_cfg1 {
+ pins = "GPIO95_E8";
+ ste,config = <&gpio_in_pu>;
+ };
+ };
+ };
+ ipgpio {
+ /*
+ * XENON Flashgun on image processor GPIO (controlled from image
+ * processor firmware), mux in these image processor GPIO lines 0
+ * (XENON_FLASH_ID), 1 (XENON_READY) and there is an assistant
+ * LED on IP GPIO 4 (XENON_EN2) on altfunction C, that need bias
+ * from GPIO21 so pull up 0, 1 and drive 4 and GPIO21 low as output.
+ */
+ ipgpio_hrefv60_mode: ipgpio_hrefv60 {
+ hrefv60_mux {
+ function = "ipgpio";
+ groups = "ipgpio0_c_1", "ipgpio1_c_1", "ipgpio4_c_1";
+ };
+ hrefv60_cfg1 {
+ pins = "GPIO6_AF6", "GPIO7_AG5";
+ ste,config = <&in_pu>;
+ };
+ hrefv60_cfg2 {
+ pins = "GPIO21_AB3";
+ ste,config = <&gpio_out_lo>;
+ };
+ hrefv60_cfg3 {
+ pins = "GPIO64_F3";
+ ste,config = <&out_lo>;
+ };
+ };
+ };
+ etm {
+ /*
+ * Drive D19-D23 for the ETM PTM trace interface low,
+ * (presumably pins are unconnected therefore grounded here,
+ * the "other alt C1" setting enables these pins)
+ */
+ etm_hrefv60_mode: etm_hrefv60 {
+ hrefv60_cfg1 {
+ pins =
+ "GPIO70_G5",
+ "GPIO71_G4",
+ "GPIO72_H4",
+ "GPIO73_H3",
+ "GPIO74_J3";
+ ste,config = <&gpio_out_lo>;
+ };
+ };
+ };
+ nahj {
+ nahj_hrefv60_mode: nahj_hrefv60 {
+ /* NAHJ CTRL on GPIO76 to low, CTRL_INV on GPIO216 to high */
+ hrefv60_cfg1 {
+ pins = "GPIO76_J2";
+ ste,config = <&gpio_out_lo>;
+ };
+ hrefv60_cfg2 {
+ pins = "GPIO216_AG12";
+ ste,config = <&gpio_out_hi>;
+ };
+ };
+ };
+ nfc {
+ nfc_hrefv60_mode: nfc_hrefv60 {
+ /* NFC ENA and RESET to low, pulldown IRQ line */
+ hrefv60_cfg1 {
+ pins =
+ "GPIO77_H1", /* NFC_ENA */
+ "GPIO142_C11"; /* NFC_RESET */
+ ste,config = <&gpio_out_lo>;
+ };
+ hrefv60_cfg2 {
+ pins = "GPIO144_B13"; /* NFC_IRQ */
+ ste,config = <&gpio_in_pd>;
+ };
+ };
+ };
+ force {
+ force_hrefv60_mode: force_hrefv60 {
+ hrefv60_cfg1 {
+ pins = "GPIO91_B6"; /* FORCE_SENSING_INT */
+ ste,config = <&gpio_in_pu>;
+ };
+ hrefv60_cfg2 {
+ pins =
+ "GPIO92_D6", /* FORCE_SENSING_RST */
+ "GPIO97_D9"; /* FORCE_SENSING_WU */
+ ste,config = <&gpio_out_lo>;
+ };
+ };
+ };
+ dipro {
+ dipro_hrefv60_mode: dipro_hrefv60 {
+ hrefv60_cfg1 {
+ pins = "GPIO139_C9"; /* DIPRO_INT */
+ ste,config = <&gpio_in_pu>;
+ };
+ };
+ };
+ vaudio_hf {
+ vaudio_hf_hrefv60_mode: vaudio_hf_hrefv60 {
+ /* Audio Amplifier HF enable GPIO */
+ hrefv60_cfg1 {
+ pins = "GPIO149_B14"; /* VAUDIO_HF_EN, enable MAX8968 */
+ ste,config = <&gpio_out_hi>;
+ };
+ };
+ };
+ gbf {
+ gbf_hrefv60_mode: gbf_hrefv60 {
+ /*
+ * GBF (GPS, Bluetooth, FM-radio) interface,
+ * pull low to reset state
+ */
+ hrefv60_cfg1 {
+ pins = "GPIO171_D23"; /* GBF_ENA_RESET */
+ ste,config = <&gpio_out_lo>;
+ };
+ };
+ };
+ hdtv {
+ hdtv_hrefv60_mode: hdtv_hrefv60 {
+ /* MSP : HDTV INTERFACE GPIO line */
+ hrefv60_cfg1 {
+ pins = "GPIO192_AJ27";
+ ste,config = <&gpio_in_pd>;
+ };
+ };
+ };
+ touch {
+ touch_hrefv60_mode: touch_hrefv60 {
+ /*
+ * Touch screen uses GPIO 143 for RST1, GPIO 146 for RST2 and
+ * GPIO 67 for interrupts. Pull-up the IRQ line and drive both
+ * reset signals low.
+ */
+ hrefv60_cfg1 {
+ pins = "GPIO143_D12", "GPIO146_D13";
+ ste,config = <&gpio_out_lo>;
+ };
+ hrefv60_cfg2 {
+ pins = "GPIO67_G2";
+ ste,config = <&gpio_in_pu>;
+ };
+ };
+ };
+ mcde {
+ lcd_hrefv60_mode: lcd_hrefv60 {
+ /*
+ * Display Interface 1 uses GPIO 65 for RST (reset).
+ * Display Interface 2 uses GPIO 66 for RST (reset).
+ * Drive DISP1 reset high (not reset), driver DISP2 reset low (reset)
+ */
+ hrefv60_cfg1 {
+ pins ="GPIO65_F1";
+ ste,config = <&gpio_out_hi>;
+ };
+ hrefv60_cfg2 {
+ pins ="GPIO66_G3";
+ ste,config = <&gpio_out_lo>;
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-nomadik-nhk15.dts b/arch/arm/boot/dts/ste-nomadik-nhk15.dts
new file mode 100644
index 000000000..3d0b8755c
--- /dev/null
+++ b/arch/arm/boot/dts/ste-nomadik-nhk15.dts
@@ -0,0 +1,151 @@
+/*
+ * Device Tree for the ST-Ericsson Nomadik S8815 board
+ * Produced by Calao Systems
+ */
+
+/dts-v1/;
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "ste-nomadik-stn8815.dtsi"
+
+/ {
+ model = "Nomadik STN8815NHK";
+ compatible = "st,nomadik-nhk-15";
+
+ chosen {
+ bootargs = "root=/dev/ram0 console=ttyAMA1,115200n8 earlyprintk";
+ };
+
+ aliases {
+ stmpe-i2c0 = &stmpe0;
+ stmpe-i2c1 = &stmpe1;
+ };
+
+ pinctrl {
+ stmpe2401_1 {
+ stmpe2401_1_nhk_mode: stmpe2401_1_nhk {
+ nhk_cfg1 {
+ pins = "GPIO76_B20"; // IRQ line
+ ste,input = <0>;
+ };
+ nhk_cfg2 {
+ pins = "GPIO77_B8"; // reset line
+ ste,output = <1>;
+ };
+ };
+ };
+ stmpe2401_2 {
+ stmpe2401_2_nhk_mode: stmpe2401_2_nhk {
+ nhk_cfg1 {
+ pins = "GPIO78_A8"; // IRQ line
+ ste,input = <0>;
+ };
+ nhk_cfg2 {
+ pins = "GPIO79_C9"; // reset line
+ ste,output = <1>;
+ };
+ };
+ };
+ };
+
+ src@101e0000 {
+ /* These chrystal outputs are not used on this board */
+ disable-sxtalo;
+ disable-mxtalo;
+ };
+
+ /* This is where the interrupt is routed on the NHK-15 debug board */
+ external-bus@34000000 {
+ compatible = "simple-bus";
+ reg = <0x34000000 0x1000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x34000000 0x1000000>;
+ ethernet@300 {
+ compatible = "smsc,lan91c111";
+ reg = <0x300 0x0fd00>;
+ reg-io-width = <2>;
+ reset-gpios = <&stmpe_gpio44 10 GPIO_ACTIVE_HIGH>;
+ interrupt-parent = <&stmpe_gpio44>;
+ interrupts = <11 IRQ_TYPE_EDGE_RISING>;
+ };
+ };
+
+ i2c0 {
+ stmpe0: stmpe2401@43 {
+ compatible = "st,stmpe2401";
+ reg = <0x43>;
+ reset-gpios = <&gpio2 13 GPIO_ACTIVE_LOW>; // GPIO77
+ interrupts = <12 IRQ_TYPE_EDGE_FALLING>; // GPIO76
+ interrupt-parent = <&gpio2>;
+ interrupt-controller;
+ wakeup-source;
+ pinctrl-names = "default";
+ pinctrl-0 = <&stmpe2401_1_nhk_mode>;
+ stmpe_gpio43: stmpe_gpio {
+ compatible = "st,stmpe-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ /* Some pins in alternate functions */
+ st,norequest-mask = <0xf0f002>;
+ };
+ stmpe_keypad {
+ compatible = "st,stmpe-keypad";
+ debounce-interval = <64>;
+ st,scan-count = <8>;
+ st,no-autorepeat;
+ keypad,num-rows = <8>;
+ keypad,num-columns = <8>;
+ linux,keymap = <0x00020072 // Vol down
+ 0x00030073 // Vol up
+ 0x0100009e // Back
+ 0x010100e3 // TV out
+ 0x01020098 // Lock
+ 0x0103013b // Start
+ 0x020000a3 // Next
+ 0x020100a4 // Play
+ 0x020200a5 // Prev
+ 0x02030160 // OK
+ 0x03000069 // Left
+ 0x0301006a // Right
+ 0x03020067 // Up
+ 0x0303006c>; // Down
+ };
+ };
+ stmpe1: stmpe2401@44 {
+ compatible = "st,stmpe2401";
+ reg = <0x44>;
+ reset-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>; // GPIO79
+ interrupts = <14 IRQ_TYPE_EDGE_FALLING>; // GPIO78
+ interrupt-parent = <&gpio2>;
+ interrupt-controller;
+ wakeup-source;
+ pinctrl-names = "default";
+ pinctrl-0 = <&stmpe2401_2_nhk_mode>;
+ stmpe_gpio44: stmpe_gpio {
+ compatible = "st,stmpe-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+ };
+
+ amba {
+ mmcsd: sdi@101f6000 {
+ cd-gpios = <&stmpe_gpio44 7 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&stmpe_gpio44 18 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ /* Custom board node with GPIO pins to active etc */
+ usb-s8815 {
+ /* This will turn off SATA so that MMC/SD can thrive */
+ mmcsd-gpio {
+ gpios = <&stmpe_gpio44 2 0x1>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-nomadik-pinctrl.dtsi b/arch/arm/boot/dts/ste-nomadik-pinctrl.dtsi
new file mode 100644
index 000000000..e6f22b266
--- /dev/null
+++ b/arch/arm/boot/dts/ste-nomadik-pinctrl.dtsi
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2012 ST-Ericsson
+ *
+ * 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 <dt-bindings/pinctrl/nomadik.h>
+
+/ {
+ in_nopull: in_nopull {
+ ste,input = <INPUT_NOPULL>;
+ };
+
+ in_pu: input_pull_up {
+ ste,input = <INPUT_PULLUP>;
+ };
+
+ in_pd: input_pull_down {
+ ste,input = <INPUT_PULLDOWN>;
+ };
+
+ out_hi: output_high {
+ ste,output = <OUTPUT_HIGH>;
+ };
+
+ out_lo: output_low {
+ ste,output = <OUTPUT_LOW>;
+ };
+
+ gpio_in_pu: gpio_input_pull_up {
+ ste,gpio = <GPIOMODE_ENABLED>;
+ ste,input = <INPUT_PULLUP>;
+ };
+
+ gpio_in_pd: gpio_input_pull_down {
+ ste,gpio = <GPIOMODE_ENABLED>;
+ ste,input = <INPUT_PULLDOWN>;
+ };
+
+ gpio_out_lo: gpio_output_low {
+ ste,gpio = <GPIOMODE_ENABLED>;
+ ste,output = <OUTPUT_LOW>;
+ };
+
+ gpio_out_hi: gpio_output_high {
+ ste,gpio = <GPIOMODE_ENABLED>;
+ ste,output = <OUTPUT_HIGH>;
+ };
+
+ slpm_pdis: slpm_pdis {
+ ste,sleep = <SLPM_ENABLED>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_DISABLE>;
+ ste,sleep-pull-disable = <SLPM_PDIS_DISABLED>;
+ };
+
+ slpm_wkup_pdis: slpm_wkup_pdis {
+ ste,sleep = <SLPM_ENABLED>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_ENABLE>;
+ ste,sleep-pull-disable = <SLPM_PDIS_DISABLED>;
+ };
+
+ slpm_wkup_pdis_en: slpm_wkup_pdis_en {
+ ste,sleep = <SLPM_ENABLED>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_ENABLE>;
+ ste,sleep-pull-disable = <SLPM_PDIS_ENABLED>;
+ };
+
+ slpm_in_pu: slpm_in_pu {
+ ste,sleep = <SLPM_ENABLED>;
+ ste,sleep-input = <SLPM_INPUT_PULLUP>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_ENABLE>;
+ };
+
+ slpm_in_pdis: slpm_in_pdis {
+ ste,sleep = <SLPM_ENABLED>;
+ ste,sleep-input = <SLPM_DIR_INPUT>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_DISABLE>;
+ ste,sleep-pull-disable = <SLPM_PDIS_DISABLED>;
+ };
+
+ slpm_in_wkup_pdis: slpm_in_wkup_pdis {
+ ste,sleep = <SLPM_ENABLED>;
+ ste,sleep-input = <SLPM_DIR_INPUT>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_ENABLE>;
+ ste,sleep-pull-disable = <SLPM_PDIS_DISABLED>;
+ };
+
+ slpm_in_wkup_pdis_en: slpm_in_wkup_pdis_en {
+ ste,sleep = <SLPM_ENABLED>;
+ ste,sleep-input = <SLPM_DIR_INPUT>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_ENABLE>;
+ ste,sleep-pull-disable = <SLPM_PDIS_ENABLED>;
+ };
+
+ slpm_in_pu_wkup_pdis_en: slpm_in_wkup_pdis_en {
+ ste,sleep = <SLPM_ENABLED>;
+ ste,sleep-input = <SLPM_INPUT_PULLUP>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_ENABLE>;
+ ste,sleep-pull-disable = <SLPM_PDIS_ENABLED>;
+ };
+
+ slpm_out_lo: slpm_out_lo {
+ ste,sleep = <SLPM_ENABLED>;
+ ste,sleep-output = <SLPM_OUTPUT_LOW>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_ENABLE>;
+ };
+
+ slpm_out_hi: slpm_out_hi {
+ ste,sleep = <SLPM_ENABLED>;
+ ste,sleep-output = <SLPM_OUTPUT_HIGH>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_ENABLE>;
+ };
+
+ slpm_out_hi_wkup_pdis: slpm_out_hi_wkup_pdis {
+ ste,sleep = <SLPM_ENABLED>;
+ ste,sleep-output = <SLPM_OUTPUT_HIGH>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_ENABLE>;
+ ste,sleep-pull-disable = <SLPM_PDIS_DISABLED>;
+ };
+
+ slpm_out_lo_pdis: slpm_out_lo_pdis {
+ ste,sleep = <SLPM_ENABLED>;
+ ste,sleep-output = <SLPM_OUTPUT_LOW>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_DISABLE>;
+ ste,sleep-pull-disable = <SLPM_PDIS_DISABLED>;
+ };
+
+ slpm_out_lo_wkup_pdis: slpm_out_lo_wkup_pdis {
+ ste,sleep = <SLPM_ENABLED>;
+ ste,sleep-output = <SLPM_OUTPUT_LOW>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_ENABLE>;
+ ste,sleep-pull-disable = <SLPM_PDIS_DISABLED>;
+ };
+
+ slpm_out_wkup_pdis: slpm_out_wkup_pdis {
+ ste,sleep = <SLPM_ENABLED>;
+ ste,sleep-output = <SLPM_DIR_OUTPUT>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_ENABLE>;
+ ste,sleep-pull-disable = <SLPM_PDIS_DISABLED>;
+ };
+
+ in_wkup_pdis: in_wkup_pdis {
+ ste,sleep-input = <SLPM_DIR_INPUT>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_ENABLE>;
+ ste,sleep-pull-disable = <SLPM_PDIS_DISABLED>;
+ };
+
+ in_wkup_pdis_en: in_wkup_pdis_en {
+ ste,sleep-input = <SLPM_DIR_INPUT>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_ENABLE>;
+ ste,sleep-pull-disable = <SLPM_PDIS_ENABLED>;
+ };
+
+ out_lo_wkup_pdis: out_lo_wkup_pdis {
+ ste,sleep-output = <SLPM_OUTPUT_LOW>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_ENABLE>;
+ ste,sleep-pull-disable = <SLPM_PDIS_DISABLED>;
+ };
+
+ out_hi_wkup_pdis: out_hi_wkup_pdis {
+ ste,sleep-output = <SLPM_OUTPUT_HIGH>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_ENABLE>;
+ ste,sleep-pull-disable = <SLPM_PDIS_DISABLED>;
+ };
+
+ out_wkup_pdis: out_wkup_pdis {
+ ste,sleep-output = <SLPM_DIR_OUTPUT>;
+ ste,sleep-wakeup = <SLPM_WAKEUP_ENABLE>;
+ ste,sleep-pull-disable = <SLPM_PDIS_DISABLED>;
+ };
+};
diff --git a/arch/arm/boot/dts/ste-nomadik-s8815.dts b/arch/arm/boot/dts/ste-nomadik-s8815.dts
new file mode 100644
index 000000000..85d3b95df
--- /dev/null
+++ b/arch/arm/boot/dts/ste-nomadik-s8815.dts
@@ -0,0 +1,141 @@
+/*
+ * Device Tree for the ST-Ericsson Nomadik S8815 board
+ * Produced by Calao Systems
+ */
+
+/dts-v1/;
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "ste-nomadik-stn8815.dtsi"
+
+/ {
+ model = "Calao Systems USB-S8815";
+ compatible = "calaosystems,usb-s8815";
+
+ chosen {
+ bootargs = "root=/dev/ram0 console=ttyAMA1,115200n8 earlyprintk";
+ };
+
+ src@101e0000 {
+ /* These chrystal drivers are not used on this board */
+ disable-sxtalo;
+ disable-mxtalo;
+ };
+
+ pinctrl {
+ /* Hog CD pins */
+ pinctrl-names = "default";
+ pinctrl-0 = <&cd_default_mode>;
+
+ mmcsd-cd {
+ cd_default_mode: cd_default {
+ cd_default_cfg1 {
+ /* CD input GPIO */
+ pins = "GPIO111_H21";
+ ste,input = <0>;
+ };
+ cd_default_cfg2 {
+ /* CD GPIO biasing */
+ pins = "GPIO112_J21";
+ ste,output = <0>;
+ };
+ };
+ };
+ gpioi2c {
+ gpioi2c_default_mode: gpioi2c_default {
+ gpioi2c_default_cfg {
+ pins = "GPIO73_C21", "GPIO74_C20";
+ ste,input = <0>;
+ };
+ };
+ };
+ user-led {
+ user_led_default_mode: user_led_default {
+ user_led_default_cfg {
+ pins = "GPIO2_C5";
+ ste,output = <1>;
+ };
+ };
+ };
+ user-button {
+ user_button_default_mode: user_button_default {
+ user_button_default_cfg {
+ pins = "GPIO3_A4";
+ ste,input = <0>;
+ };
+ };
+ };
+ };
+
+ /* Ethernet */
+ external-bus@34000000 {
+ compatible = "simple-bus";
+ reg = <0x34000000 0x1000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x34000000 0x1000000>;
+ ethernet@300 {
+ compatible = "smsc,lan91c111";
+ reg = <0x300 0x0fd00>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <8 IRQ_TYPE_EDGE_RISING>;
+ };
+ };
+
+ /* GPIO I2C connected to the USB portions of the STw4811 only */
+ gpio-i2c {
+ compatible = "i2c-gpio";
+ gpios = <&gpio2 10 0>, /* sda */
+ <&gpio2 9 0>; /* scl */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpioi2c_default_mode>;
+
+ stw4811@2d {
+ compatible = "st,stw4811-usb";
+ reg = <0x2d>;
+ };
+ };
+
+
+ /* Configure card detect for the uSD slot */
+ amba {
+ mmcsd: sdi@101f6000 {
+ cd-gpios = <&gpio3 15 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ /* Custom board node with GPIO pins to active etc */
+ usb-s8815 {
+ /* This will bias the MMC/SD card detect line */
+ mmcsd-gpio {
+ gpios = <&gpio3 16 0x1>;
+ };
+ };
+
+ /* The user LED on the board is set up to be used for heartbeat */
+ leds {
+ compatible = "gpio-leds";
+ user-led {
+ label = "user_led";
+ gpios = <&gpio0 2 0x1>;
+ default-state = "off";
+ linux,default-trigger = "heartbeat";
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_led_default_mode>;
+ };
+ };
+
+ /* User key mapped in as "escape" */
+ gpio-keys {
+ compatible = "gpio-keys";
+ user-button {
+ label = "user_button";
+ gpios = <&gpio0 3 0x1>;
+ linux,code = <1>; /* KEY_ESC */
+ gpio-key,wakeup;
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_button_default_mode>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
new file mode 100644
index 000000000..f182f6538
--- /dev/null
+++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
@@ -0,0 +1,814 @@
+/*
+ * Device Tree for the ST-Ericsson Nomadik 8815 STn8815 SoC
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include "skeleton.dtsi"
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ memory {
+ reg = <0x00000000 0x04000000>,
+ <0x08000000 0x04000000>;
+ };
+
+ L2: l2-cache {
+ compatible = "arm,l210-cache";
+ reg = <0x10210000 0x1000>;
+ interrupt-parent = <&vica>;
+ interrupts = <30>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ mtu0: mtu@101e2000 {
+ /* Nomadik system timer */
+ compatible = "st,nomadik-mtu";
+ reg = <0x101e2000 0x1000>;
+ interrupt-parent = <&vica>;
+ interrupts = <4>;
+ clocks = <&timclk>, <&pclk>;
+ clock-names = "timclk", "apb_pclk";
+ };
+
+ mtu1: mtu@101e3000 {
+ /* Secondary timer */
+ reg = <0x101e3000 0x1000>;
+ interrupt-parent = <&vica>;
+ interrupts = <5>;
+ clocks = <&timclk>, <&pclk>;
+ clock-names = "timclk", "apb_pclk";
+ };
+
+ gpio0: gpio@101e4000 {
+ compatible = "st,nomadik-gpio";
+ reg = <0x101e4000 0x80>;
+ interrupt-parent = <&vica>;
+ interrupts = <6>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-bank = <0>;
+ clocks = <&pclk>;
+ };
+
+ gpio1: gpio@101e5000 {
+ compatible = "st,nomadik-gpio";
+ reg = <0x101e5000 0x80>;
+ interrupt-parent = <&vica>;
+ interrupts = <7>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-bank = <1>;
+ clocks = <&pclk>;
+ };
+
+ gpio2: gpio@101e6000 {
+ compatible = "st,nomadik-gpio";
+ reg = <0x101e6000 0x80>;
+ interrupt-parent = <&vica>;
+ interrupts = <8>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-bank = <2>;
+ clocks = <&pclk>;
+ };
+
+ gpio3: gpio@101e7000 {
+ compatible = "st,nomadik-gpio";
+ reg = <0x101e7000 0x80>;
+ interrupt-parent = <&vica>;
+ interrupts = <9>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-bank = <3>;
+ clocks = <&pclk>;
+ };
+
+ pinctrl {
+ compatible = "stericsson,stn8815-pinctrl";
+ /* Pin configurations */
+ uart0 {
+ uart0_default_mux: uart0_mux {
+ u0_default_mux {
+ function = "u0";
+ groups = "u0_a_1";
+ };
+ };
+ };
+ uart1 {
+ uart1_default_mux: uart1_mux {
+ u1_default_mux {
+ function = "u1";
+ groups = "u1_a_1";
+ };
+ };
+ };
+ mmcsd {
+ mmcsd_default_mux: mmcsd_mux {
+ mmcsd_default_mux {
+ function = "mmcsd";
+ groups = "mmcsd_a_1", "mmcsd_b_1";
+ };
+ };
+ mmcsd_default_mode: mmcsd_default {
+ mmcsd_default_cfg1 {
+ /* MCCLK */
+ pins = "GPIO8_B10";
+ ste,output = <0>;
+ };
+ mmcsd_default_cfg2 {
+ /* MCCMDDIR, MCDAT0DIR, MCDAT31DIR, MCDATDIR2 */
+ pins = "GPIO10_C11", "GPIO15_A12",
+ "GPIO16_C13", "GPIO23_D15";
+ ste,output = <1>;
+ };
+ mmcsd_default_cfg3 {
+ /* MCCMD, MCDAT3-0, MCMSFBCLK */
+ pins = "GPIO9_A10", "GPIO11_B11",
+ "GPIO12_A11", "GPIO13_C12",
+ "GPIO14_B12", "GPIO24_C15";
+ ste,input = <1>;
+ };
+ };
+ };
+ i2c0 {
+ i2c0_default_mux: i2c0_mux {
+ i2c0_default_mux {
+ function = "i2c0";
+ groups = "i2c0_a_1";
+ };
+ };
+ i2c0_default_mode: i2c0_default {
+ i2c0_default_cfg {
+ pins = "GPIO62_D3", "GPIO63_D2";
+ ste,input = <0>;
+ };
+ };
+ };
+ i2c1 {
+ i2c1_default_mux: i2c1_mux {
+ i2c1_default_mux {
+ function = "i2c1";
+ groups = "i2c1_a_1";
+ };
+ };
+ i2c1_default_mode: i2c1_default {
+ i2c1_default_cfg {
+ pins = "GPIO53_L4", "GPIO54_L3";
+ ste,input = <0>;
+ };
+ };
+ };
+ };
+
+ src: src@101e0000 {
+ compatible = "stericsson,nomadik-src";
+ reg = <0x101e0000 0x1000>;
+
+ /*
+ * MXTAL "Main Chrystal" is a chrystal oscillator @19.2 MHz
+ * that is parent of TIMCLK, PLL1 and PLL2
+ */
+ mxtal: mxtal@19.2M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <19200000>;
+ };
+
+ /*
+ * The 2.4 MHz TIMCLK reference clock is active at
+ * boot time, this is actually the MXTALCLK @19.2 MHz
+ * divided by 8. This clock is used by the timers and
+ * watchdog. See page 105 ff.
+ */
+ timclk: timclk@2.4M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <8>;
+ clock-mult = <1>;
+ clocks = <&mxtal>;
+ };
+
+ /* PLL1 is locked to MXTALI and variable from 20.4 to 334 MHz */
+ pll1: pll1@0 {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-pll-clock";
+ pll-id = <1>;
+ clocks = <&mxtal>;
+ };
+
+ /* HCLK divides the PLL1 with 1,2,3 or 4 */
+ hclk: hclk@0 {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-hclk-clock";
+ clocks = <&pll1>;
+ };
+ /* The PCLK domain uses HCLK right off */
+ pclk: pclk@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <1>;
+ clock-mult = <1>;
+ clocks = <&hclk>;
+ };
+
+ /* PLL2 is usually 864 MHz and divided into a few fixed rates */
+ pll2: pll2@0 {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-pll-clock";
+ pll-id = <2>;
+ clocks = <&mxtal>;
+ };
+ clk216: clk216@216M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <4>;
+ clock-mult = <1>;
+ clocks = <&pll2>;
+ };
+ clk108: clk108@108M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <2>;
+ clock-mult = <1>;
+ clocks = <&clk216>;
+ };
+ clk72: clk72@72M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ /* The data sheet does not say how this is derived */
+ clock-div = <12>;
+ clock-mult = <1>;
+ clocks = <&pll2>;
+ };
+ clk48: clk48@48M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ /* The data sheet does not say how this is derived */
+ clock-div = <18>;
+ clock-mult = <1>;
+ clocks = <&pll2>;
+ };
+ clk27: clk27@27M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <4>;
+ clock-mult = <1>;
+ clocks = <&clk108>;
+ };
+
+ /* This apparently exists as well */
+ ulpiclk: ulpiclk@60M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <60000000>;
+ };
+
+ /*
+ * IP AMBA bus clocks, driving the bus side of the
+ * peripheral clocking, clock gates.
+ */
+
+ hclkdma0: hclkdma0@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <0>;
+ clocks = <&hclk>;
+ };
+ hclksmc: hclksmc@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <1>;
+ clocks = <&hclk>;
+ };
+ hclksdram: hclksdram@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <2>;
+ clocks = <&hclk>;
+ };
+ hclkdma1: hclkdma1@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <3>;
+ clocks = <&hclk>;
+ };
+ hclkclcd: hclkclcd@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <4>;
+ clocks = <&hclk>;
+ };
+ pclkirda: pclkirda@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <5>;
+ clocks = <&pclk>;
+ };
+ pclkssp: pclkssp@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <6>;
+ clocks = <&pclk>;
+ };
+ pclkuart0: pclkuart0@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <7>;
+ clocks = <&pclk>;
+ };
+ pclksdi: pclksdi@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <8>;
+ clocks = <&pclk>;
+ };
+ pclki2c0: pclki2c0@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <9>;
+ clocks = <&pclk>;
+ };
+ pclki2c1: pclki2c1@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <10>;
+ clocks = <&pclk>;
+ };
+ pclkuart1: pclkuart1@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <11>;
+ clocks = <&pclk>;
+ };
+ pclkmsp0: pclkmsp0@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <12>;
+ clocks = <&pclk>;
+ };
+ hclkusb: hclkusb@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <13>;
+ clocks = <&hclk>;
+ };
+ hclkdif: hclkdif@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <14>;
+ clocks = <&hclk>;
+ };
+ hclksaa: hclksaa@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <15>;
+ clocks = <&hclk>;
+ };
+ hclksva: hclksva@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <16>;
+ clocks = <&hclk>;
+ };
+ pclkhsi: pclkhsi@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <17>;
+ clocks = <&pclk>;
+ };
+ pclkxti: pclkxti@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <18>;
+ clocks = <&pclk>;
+ };
+ pclkuart2: pclkuart2@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <19>;
+ clocks = <&pclk>;
+ };
+ pclkmsp1: pclkmsp1@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <20>;
+ clocks = <&pclk>;
+ };
+ pclkmsp2: pclkmsp2@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <21>;
+ clocks = <&pclk>;
+ };
+ pclkowm: pclkowm@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <22>;
+ clocks = <&pclk>;
+ };
+ hclkhpi: hclkhpi@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <23>;
+ clocks = <&hclk>;
+ };
+ pclkske: pclkske@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <24>;
+ clocks = <&pclk>;
+ };
+ pclkhsem: pclkhsem@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <25>;
+ clocks = <&pclk>;
+ };
+ hclk3d: hclk3d@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <26>;
+ clocks = <&hclk>;
+ };
+ hclkhash: hclkhash@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <27>;
+ clocks = <&hclk>;
+ };
+ hclkcryp: hclkcryp@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <28>;
+ clocks = <&hclk>;
+ };
+ pclkmshc: pclkmshc@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <29>;
+ clocks = <&pclk>;
+ };
+ hclkusbm: hclkusbm@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <30>;
+ clocks = <&hclk>;
+ };
+ hclkrng: hclkrng@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <31>;
+ clocks = <&hclk>;
+ };
+
+ /* IP kernel clocks */
+ clcdclk: clcdclk@0 {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <36>;
+ clocks = <&clk72 &clk48>;
+ };
+ irdaclk: irdaclk@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <37>;
+ clocks = <&clk48>;
+ };
+ sspiclk: sspiclk@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <38>;
+ clocks = <&clk48>;
+ };
+ uart0clk: uart0clk@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <39>;
+ clocks = <&clk48>;
+ };
+ sdiclk: sdiclk@48M {
+ /* Also called MCCLK in some documents */
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <40>;
+ clocks = <&clk48>;
+ };
+ i2c0clk: i2c0clk@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <41>;
+ clocks = <&clk48>;
+ };
+ i2c1clk: i2c1clk@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <42>;
+ clocks = <&clk48>;
+ };
+ uart1clk: uart1clk@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <43>;
+ clocks = <&clk48>;
+ };
+ mspclk0: mspclk0@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <44>;
+ clocks = <&clk48>;
+ };
+ usbclk: usbclk@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <45>;
+ clocks = <&clk48>; /* 48 MHz not ULPI */
+ };
+ difclk: difclk@72M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <46>;
+ clocks = <&clk72>;
+ };
+ ipi2cclk: ipi2cclk@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <47>;
+ clocks = <&clk48>; /* Guess */
+ };
+ ipbmcclk: ipbmcclk@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <48>;
+ clocks = <&clk48>; /* Guess */
+ };
+ hsiclkrx: hsiclkrx@216M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <49>;
+ clocks = <&clk216>;
+ };
+ hsiclktx: hsiclktx@108M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <50>;
+ clocks = <&clk108>;
+ };
+ uart2clk: uart2clk@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <51>;
+ clocks = <&clk48>;
+ };
+ mspclk1: mspclk1@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <52>;
+ clocks = <&clk48>;
+ };
+ mspclk2: mspclk2@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <53>;
+ clocks = <&clk48>;
+ };
+ owmclk: owmclk@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <54>;
+ clocks = <&clk48>; /* Guess */
+ };
+ skeclk: skeclk@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <56>;
+ clocks = <&clk48>; /* Guess */
+ };
+ x3dclk: x3dclk@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <58>;
+ clocks = <&clk48>; /* Guess */
+ };
+ pclkmsp3: pclkmsp3@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <59>;
+ clocks = <&pclk>;
+ };
+ mspclk3: mspclk3@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <60>;
+ clocks = <&clk48>;
+ };
+ mshcclk: mshcclk@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <61>;
+ clocks = <&clk48>; /* Guess */
+ };
+ usbmclk: usbmclk@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <62>;
+ /* Stated as "48 MHz not ULPI clock" */
+ clocks = <&clk48>;
+ };
+ rngcclk: rngcclk@48M {
+ #clock-cells = <0>;
+ compatible = "st,nomadik-src-clock";
+ clock-id = <63>;
+ clocks = <&clk48>; /* Guess */
+ };
+ };
+
+ /* A NAND flash of 128 MiB */
+ fsmc: flash@40000000 {
+ compatible = "stericsson,fsmc-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x10100000 0x1000>, /* FSMC Register*/
+ <0x40000000 0x2000>, /* NAND Base DATA */
+ <0x41000000 0x2000>, /* NAND Base ADDR */
+ <0x40800000 0x2000>; /* NAND Base CMD */
+ reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
+ clocks = <&hclksmc>;
+ status = "okay";
+ timings = /bits/ 8 <0 0 0 0x10 0x0a 0>;
+
+ partition@0 {
+ label = "X-Loader(NAND)";
+ reg = <0x0 0x40000>;
+ };
+ partition@40000 {
+ label = "MemInit(NAND)";
+ reg = <0x40000 0x40000>;
+ };
+ partition@80000 {
+ label = "BootLoader(NAND)";
+ reg = <0x80000 0x200000>;
+ };
+ partition@280000 {
+ label = "Kernel zImage(NAND)";
+ reg = <0x280000 0x300000>;
+ };
+ partition@580000 {
+ label = "Root Filesystem(NAND)";
+ reg = <0x580000 0x1600000>;
+ };
+ partition@1b80000 {
+ label = "User Filesystem(NAND)";
+ reg = <0x1b80000 0x6480000>;
+ };
+ };
+
+ /* I2C0 connected to the STw4811 power management chip */
+ i2c0 {
+ compatible = "st,nomadik-i2c", "arm,primecell";
+ reg = <0x101f8000 0x1000>;
+ interrupt-parent = <&vica>;
+ interrupts = <20>;
+ clock-frequency = <100000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&i2c0clk>, <&pclki2c0>;
+ clock-names = "mclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_default_mux>, <&i2c0_default_mode>;
+
+ stw4811@2d {
+ compatible = "st,stw4811";
+ reg = <0x2d>;
+ vmmc_regulator: vmmc {
+ compatible = "st,stw481x-vmmc";
+ regulator-name = "VMMC";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
+
+ /* I2C1 connected to various sensors */
+ i2c1 {
+ compatible = "st,nomadik-i2c", "arm,primecell";
+ reg = <0x101f7000 0x1000>;
+ interrupt-parent = <&vica>;
+ interrupts = <21>;
+ clock-frequency = <100000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&i2c1clk>, <&pclki2c1>;
+ clock-names = "mclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_default_mux>, <&i2c1_default_mode>;
+
+ camera@2d {
+ compatible = "st,camera";
+ reg = <0x10>;
+ };
+ stw5095@1a {
+ compatible = "st,stw5095";
+ reg = <0x1a>;
+ };
+ lis3lv02dl@1d {
+ compatible = "st,lis3lv02dl";
+ reg = <0x1d>;
+ };
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ vica: intc@10140000 {
+ compatible = "arm,versatile-vic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x10140000 0x20>;
+ };
+
+ vicb: intc@10140020 {
+ compatible = "arm,versatile-vic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x10140020 0x20>;
+ };
+
+ uart0: uart@101fd000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x101fd000 0x1000>;
+ interrupt-parent = <&vica>;
+ interrupts = <12>;
+ clocks = <&uart0clk>, <&pclkuart0>;
+ clock-names = "uartclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_default_mux>;
+ };
+
+ uart1: uart@101fb000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x101fb000 0x1000>;
+ interrupt-parent = <&vica>;
+ interrupts = <17>;
+ clocks = <&uart1clk>, <&pclkuart1>;
+ clock-names = "uartclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_default_mux>;
+ };
+
+ uart2: uart@101f2000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x101f2000 0x1000>;
+ interrupt-parent = <&vica>;
+ interrupts = <28>;
+ clocks = <&uart2clk>, <&pclkuart2>;
+ clock-names = "uartclk", "apb_pclk";
+ status = "disabled";
+ };
+
+ rng: rng@101b0000 {
+ compatible = "arm,primecell";
+ reg = <0x101b0000 0x1000>;
+ clocks = <&rngcclk>, <&hclkrng>;
+ clock-names = "rng", "apb_pclk";
+ };
+
+ rtc: rtc@101e8000 {
+ compatible = "arm,pl031", "arm,primecell";
+ reg = <0x101e8000 0x1000>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ interrupt-parent = <&vica>;
+ interrupts = <10>;
+ };
+
+ mmcsd: sdi@101f6000 {
+ compatible = "arm,pl18x", "arm,primecell";
+ reg = <0x101f6000 0x1000>;
+ clocks = <&sdiclk>, <&pclksdi>;
+ clock-names = "mclk", "apb_pclk";
+ interrupt-parent = <&vica>;
+ interrupts = <22>;
+ max-frequency = <48000000>;
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmcsd_default_mux>, <&mmcsd_default_mode>;
+ vmmc-supply = <&vmmc_regulator>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts
new file mode 100644
index 000000000..1bc84ebdc
--- /dev/null
+++ b/arch/arm/boot/dts/ste-snowball.dts
@@ -0,0 +1,538 @@
+/*
+ * Copyright 2011 ST-Ericsson AB
+ *
+ * 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
+ */
+
+/dts-v1/;
+#include "ste-dbx5x0.dtsi"
+#include "ste-href-ab8500.dtsi"
+#include "ste-href-family-pinctrl.dtsi"
+
+/ {
+ model = "Calao Systems Snowball platform with device tree";
+ compatible = "calaosystems,snowball-a9500", "st-ericsson,u9500";
+
+ memory {
+ reg = <0x00000000 0x20000000>;
+ };
+
+ en_3v3_reg: en_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "en-3v3-fixed-supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ /* AB8500 GPIOs start from 1 - offset 25 is GPIO26. */
+ gpio = <&ab8500_gpio 25 0x4>;
+ startup-delay-us = <5000>;
+ enable-active-high;
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@1 {
+ debounce_interval = <50>;
+ wakeup = <1>;
+ linux,code = <2>;
+ label = "userpb";
+ gpios = <&gpio1 0 0x4>;
+ };
+ button@2 {
+ debounce_interval = <50>;
+ wakeup = <1>;
+ linux,code = <3>;
+ label = "extkb1";
+ gpios = <&gpio4 23 0x4>;
+ };
+ button@3 {
+ debounce_interval = <50>;
+ wakeup = <1>;
+ linux,code = <4>;
+ label = "extkb2";
+ gpios = <&gpio4 24 0x4>;
+ };
+ button@4 {
+ debounce_interval = <50>;
+ wakeup = <1>;
+ linux,code = <5>;
+ label = "extkb3";
+ gpios = <&gpio5 1 0x4>;
+ };
+ button@5 {
+ debounce_interval = <50>;
+ wakeup = <1>;
+ linux,code = <6>;
+ label = "extkb4";
+ gpios = <&gpio5 2 0x4>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpioled_snowball_mode>;
+ used-led {
+ label = "user_led";
+ gpios = <&gpio4 14 0x4>;
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ soc {
+ usb_per5@a03e0000 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&musb_default_mode>;
+ pinctrl-1 = <&musb_sleep_mode>;
+ };
+
+ sound {
+ compatible = "stericsson,snd-soc-mop500";
+
+ stericsson,cpu-dai = <&msp1 &msp3>;
+ stericsson,audio-codec = <&codec>;
+ };
+
+ msp0: msp@80123000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&msp0_default_mode>;
+ status = "okay";
+ };
+
+ msp1: msp@80124000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&msp1_default_mode>;
+ status = "okay";
+ };
+
+ msp2: msp@80117000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&msp2_default_mode>;
+ };
+
+ msp3: msp@80125000 {
+ status = "okay";
+ };
+
+ external-bus@50000000 {
+ status = "okay";
+
+ ethernet@0 {
+ compatible = "smsc,lan9115";
+ reg = <0 0x10000>;
+ interrupts = <12 IRQ_TYPE_EDGE_RISING>;
+ interrupt-parent = <&gpio4>;
+ vdd33a-supply = <&en_3v3_reg>;
+ vddvario-supply = <&db8500_vape_reg>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&eth_snowball_mode>;
+
+ reg-shift = <1>;
+ reg-io-width = <2>;
+ smsc,force-internal-phy;
+ smsc,irq-active-high;
+ smsc,irq-push-pull;
+
+ clocks = <&prcc_pclk 3 0>;
+ };
+ };
+
+ vmmci: regulator-gpio {
+ compatible = "regulator-gpio";
+
+ gpios = <&gpio7 4 0x4>;
+ enable-gpio = <&gpio6 25 0x4>;
+
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-name = "mmci-reg";
+ regulator-type = "voltage";
+
+ startup-delay-us = <100>;
+ enable-active-high;
+
+ states = <1800000 0x1
+ 2900000 0x0>;
+ };
+
+ // External Micro SD slot
+ sdi0_per1@80126000 {
+ arm,primecell-periphid = <0x10480180>;
+ max-frequency = <100000000>;
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ vmmc-supply = <&ab8500_ldo_aux3_reg>;
+ vqmmc-supply = <&vmmci>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdi0_default_mode>;
+ pinctrl-1 = <&sdi0_sleep_mode>;
+
+ cd-gpios = <&gpio6 26 0x4>; // 218
+ cd-inverted;
+
+ status = "okay";
+ };
+
+ // WLAN SDIO channel
+ sdi1_per2@80118000 {
+ arm,primecell-periphid = <0x10480180>;
+ max-frequency = <100000000>;
+ bus-width = <4>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdi1_default_mode>;
+ pinctrl-1 = <&sdi1_sleep_mode>;
+
+ status = "okay";
+ };
+
+ // Unused PoP eMMC - register and put it to sleep by default */
+ sdi2_per3@80005000 {
+ arm,primecell-periphid = <0x10480180>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdi2_sleep_mode>;
+
+ status = "okay";
+ };
+
+ // On-board eMMC
+ sdi4_per2@80114000 {
+ arm,primecell-periphid = <0x10480180>;
+ max-frequency = <100000000>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ vmmc-supply = <&ab8500_ldo_aux2_reg>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdi4_default_mode>;
+ pinctrl-1 = <&sdi4_sleep_mode>;
+
+ status = "okay";
+ };
+
+ uart@80120000 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&uart0_default_mode>;
+ pinctrl-1 = <&uart0_sleep_mode>;
+ status = "okay";
+ };
+
+ uart@80121000 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&uart1_default_mode>;
+ pinctrl-1 = <&uart1_sleep_mode>;
+ status = "okay";
+ };
+
+ uart@80007000 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&uart2_default_mode>;
+ pinctrl-1 = <&uart2_sleep_mode>;
+ status = "okay";
+ };
+
+ i2c@80004000 {
+ pinctrl-names = "default","sleep";
+ pinctrl-0 = <&i2c0_default_mode>;
+ pinctrl-1 = <&i2c0_sleep_mode>;
+ };
+
+ i2c@80122000 {
+ pinctrl-names = "default","sleep";
+ pinctrl-0 = <&i2c1_default_mode>;
+ pinctrl-1 = <&i2c1_sleep_mode>;
+ };
+
+ i2c@80128000 {
+ pinctrl-names = "default","sleep";
+ pinctrl-0 = <&i2c2_default_mode>;
+ pinctrl-1 = <&i2c2_sleep_mode>;
+ lsm303dlh@18 {
+ /* Accelerometer */
+ compatible = "st,lsm303dlh-accel";
+ st,drdy-int-pin = <1>;
+ reg = <0x18>;
+ vdd-supply = <&ab8500_ldo_aux1_reg>;
+ vddio-supply = <&db8500_vsmps2_reg>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&accel_snowball_mode>;
+ };
+ lsm303dlm@1e {
+ /* Magnetometer */
+ compatible = "st,lsm303dlm-magn";
+ reg = <0x1e>;
+ vdd-supply = <&ab8500_ldo_aux1_reg>;
+ vddio-supply = <&db8500_vsmps2_reg>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&magneto_snowball_mode>;
+ };
+ l3g4200d@68 {
+ /* Gyroscope */
+ compatible = "st,l3g4200d-gyro";
+ st,drdy-int-pin = <2>;
+ reg = <0x68>;
+ vdd-supply = <&ab8500_ldo_aux1_reg>;
+ vddio-supply = <&db8500_vsmps2_reg>;
+ };
+ lsp001wm@5c {
+ /* Barometer/pressure sensor */
+ compatible = "st,lps001wp-press";
+ reg = <0x5c>;
+ vdd-supply = <&ab8500_ldo_aux1_reg>;
+ vddio-supply = <&db8500_vsmps2_reg>;
+ };
+ };
+
+ i2c@80110000 {
+ pinctrl-names = "default","sleep";
+ pinctrl-0 = <&i2c3_default_mode>;
+ pinctrl-1 = <&i2c3_sleep_mode>;
+ };
+
+ ssp@80002000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ssp0_snowball_mode>;
+ };
+
+ cpufreq-cooling {
+ status = "okay";
+ };
+
+ prcmu@80157000 {
+ cpufreq {
+ status = "okay";
+ };
+
+ thermal@801573c0 {
+ num-trips = <4>;
+
+ trip0-temp = <70000>;
+ trip0-type = "active";
+ trip0-cdev-num = <1>;
+ trip0-cdev-name0 = "thermal-cpufreq-0";
+
+ trip1-temp = <75000>;
+ trip1-type = "active";
+ trip1-cdev-num = <1>;
+ trip1-cdev-name0 = "thermal-cpufreq-0";
+
+ trip2-temp = <80000>;
+ trip2-type = "active";
+ trip2-cdev-num = <1>;
+ trip2-cdev-name0 = "thermal-cpufreq-0";
+
+ trip3-temp = <85000>;
+ trip3-type = "critical";
+ trip3-cdev-num = <0>;
+
+ status = "okay";
+ };
+
+ ab8500 {
+ ab8500-gpio {
+ compatible = "stericsson,ab8500-gpio";
+ };
+
+ ext_regulators: ab8500-ext-regulators {
+ ab8500_ext1_reg: ab8500_ext1 {
+ regulator-name = "ab8500-ext-supply1";
+ };
+
+ ab8500_ext2_reg_reg: ab8500_ext2 {
+ regulator-name = "ab8500-ext-supply2";
+ };
+
+ ab8500_ext3_reg_reg: ab8500_ext3 {
+ regulator-name = "ab8500-ext-supply3";
+ };
+ };
+
+ ab8500-regulators {
+ ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
+ regulator-name = "V-DISPLAY";
+ };
+
+ ab8500_ldo_aux2_reg: ab8500_ldo_aux2 {
+ regulator-name = "V-eMMC1";
+ };
+
+ ab8500_ldo_aux3_reg: ab8500_ldo_aux3 {
+ regulator-name = "V-MMC-SD";
+ };
+
+ ab8500_ldo_intcore_reg: ab8500_ldo_intcore {
+ regulator-name = "V-INTCORE";
+ };
+
+ ab8500_ldo_tvout_reg: ab8500_ldo_tvout {
+ regulator-name = "V-TVOUT";
+ };
+
+ ab8500_ldo_usb_reg: ab8500_ldo_usb {
+ regulator-name = "dummy";
+ };
+
+ ab8500_ldo_audio_reg: ab8500_ldo_audio {
+ regulator-name = "V-AUD";
+ };
+
+ ab8500_ldo_anamic1_reg: ab8500_ldo_anamic1 {
+ regulator-name = "V-AMIC1";
+ };
+
+ ab8500_ldo_anamic2_reg: ab8500_ldo_anamic2 {
+ regulator-name = "V-AMIC2";
+ };
+
+ ab8500_ldo_dmic_reg: ab8500_ldo_dmic {
+ regulator-name = "V-DMIC";
+ };
+
+ ab8500_ldo_ana_reg: ab8500_ldo_ana {
+ regulator-name = "V-CSI/DSI";
+ };
+ };
+ };
+ };
+
+ pinctrl {
+ /*
+ * Set this up using hogs, as time goes by and as seems fit, these
+ * can be moved over to being controlled by respective device.
+ */
+ pinctrl-names = "default";
+ pinctrl-0 = <&gbf_snowball_mode>,
+ <&wlan_snowball_mode>;
+
+ ethernet {
+ /*
+ * Mux in "SM" which is used for the
+ * SMSC911x Ethernet adapter
+ */
+ eth_snowball_mode: eth_snowball {
+ snowball_mux {
+ function = "sm";
+ groups = "sm_b_1";
+ };
+ /* LAN IRQ pin */
+ snowball_cfg1 {
+ pins = "GPIO140_B11";
+ ste,config = <&in_nopull>;
+ };
+ /* LAN reset pin */
+ snowball_cfg2 {
+ pins = "GPIO141_C12";
+ ste,config = <&gpio_out_hi>;
+ };
+
+ };
+ };
+ sdi0 {
+ sdi0_default_mode: sdi0_default {
+ snowball_mux {
+ function = "mc0";
+ groups = "mc0dat31dir_a_1";
+ };
+ snowball_cfg1 {
+ pins = "GPIO21_AB3"; /* DAT31DIR */
+ ste,config = <&out_hi>;
+ };
+
+ };
+ };
+ ssp0 {
+ ssp0_snowball_mode: ssp0_snowball_default {
+ snowball_mux {
+ function = "ssp0";
+ groups = "ssp0_a_1";
+ };
+ snowball_cfg1 {
+ pins = "GPIO144_B13"; /* FRM */
+ ste,config = <&gpio_out_hi>;
+ };
+ snowball_cfg2 {
+ pins = "GPIO145_C13"; /* RXD */
+ ste,config = <&in_pd>;
+ };
+ snowball_cfg3 {
+ pins =
+ "GPIO146_D13", /* TXD */
+ "GPIO143_D12"; /* CLK */
+ ste,config = <&out_lo>;
+ };
+
+ };
+ };
+ gpio_led {
+ gpioled_snowball_mode: gpioled_default {
+ snowball_cfg1 {
+ pins = "GPIO142_C11";
+ ste,config = <&gpio_out_hi>;
+ };
+
+ };
+ };
+ accelerometer {
+ accel_snowball_mode: accel_snowball {
+ /* Accelerometer lines */
+ snowball_cfg1 {
+ pins =
+ "GPIO163_C20", /* ACCEL_IRQ1 */
+ "GPIO164_B21"; /* ACCEL_IRQ2 */
+ ste,config = <&gpio_in_pu>;
+ };
+ };
+ };
+ magnetometer {
+ magneto_snowball_mode: magneto_snowball {
+ snowball_cfg1 {
+ pins = "GPIO165_C21"; /* MAG_DRDY */
+ ste,config = <&gpio_in_pu>;
+ };
+ };
+ };
+ gbf {
+ gbf_snowball_mode: gbf_snowball {
+ /*
+ * GBF (GPS, Bluetooth, FM-radio) interface,
+ * pull low to reset state
+ */
+ snowball_cfg1 {
+ pins = "GPIO171_D23"; /* GBF_ENA_RESET */
+ ste,config = <&gpio_out_lo>;
+ };
+ };
+ };
+ wlan {
+ wlan_snowball_mode: wlan_snowball {
+ /*
+ * Activate this mode with the WLAN chip.
+ * These are plain GPIO pins used by WLAN
+ */
+ snowball_cfg1 {
+ pins =
+ "GPIO161_D21", /* WLAN_PMU_EN */
+ "GPIO215_AH13"; /* WLAN_ENA */
+ ste,config = <&gpio_out_lo>;
+ };
+ snowball_cfg2 {
+ pins = "GPIO216_AG12"; /* WLAN_IRQ */
+ ste,config = <&gpio_in_pu>;
+ };
+ };
+ };
+ };
+
+ mcde@a0350000 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&lcd_default_mode>;
+ pinctrl-1 = <&lcd_sleep_mode>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ste-u300.dts b/arch/arm/boot/dts/ste-u300.dts
new file mode 100644
index 000000000..82a661677
--- /dev/null
+++ b/arch/arm/boot/dts/ste-u300.dts
@@ -0,0 +1,473 @@
+/*
+ * Device Tree for the ST-Ericsson U300 Machine and SoC
+ */
+
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "ST-Ericsson U300";
+ compatible = "stericsson,u300";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ chosen {
+ bootargs = "root=/dev/ram0 console=ttyAMA0,115200n8 earlyprintk";
+ };
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ };
+
+ memory {
+ reg = <0x48000000 0x03c00000>;
+ };
+
+ s365 {
+ compatible = "stericsson,s365";
+ vana15-supply = <&ab3100_ldo_d_reg>;
+ syscon = <&syscon>;
+ };
+
+ syscon: syscon@c0011000 {
+ compatible = "stericsson,u300-syscon", "syscon";
+ reg = <0xc0011000 0x1000>;
+ clk32: app_32_clk@32k {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+ pll13: pll13@13M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ };
+ /* Slow bridge clocks under PLL13 */
+ slow_clk: slow_clk@13M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <0>; /* Slow */
+ clock-id = <0>;
+ clocks = <&pll13>;
+ };
+ uart0_clk: uart0_clk@13M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <0>; /* Slow */
+ clock-id = <1>;
+ clocks = <&slow_clk>;
+ };
+ gpio_clk: gpio_clk@13M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <0>; /* Slow */
+ clock-id = <4>;
+ clocks = <&slow_clk>;
+ };
+ rtc_clk: rtc_clk@13M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <0>; /* Slow */
+ clock-id = <6>;
+ clocks = <&slow_clk>;
+ };
+ apptimer_clk: app_tmr_clk@13M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <0>; /* Slow */
+ clock-id = <7>;
+ clocks = <&slow_clk>;
+ };
+ acc_tmr_clk@13M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <0>; /* Slow */
+ clock-id = <8>;
+ clocks = <&slow_clk>;
+ };
+ pll208: pll208@208M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <208000000>;
+ };
+ app208: app_208_clk@208M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <1>;
+ clock-mult = <1>;
+ clocks = <&pll208>;
+ };
+ cpu_clk@208M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <2>; /* Rest */
+ clock-id = <3>;
+ clocks = <&app208>;
+ };
+ app104: app_104_clk@104M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <2>;
+ clock-mult = <1>;
+ clocks = <&pll208>;
+ };
+ semi_clk@104M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <2>; /* Rest */
+ clock-id = <9>;
+ clocks = <&app104>;
+ };
+ app52: app_52_clk@52M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <4>;
+ clock-mult = <1>;
+ clocks = <&pll208>;
+ };
+ /* AHB subsystem clocks */
+ ahb_clk: ahb_subsys_clk@52M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <2>; /* Rest */
+ clock-id = <10>;
+ clocks = <&app52>;
+ };
+ intcon_clk@52M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <2>; /* Rest */
+ clock-id = <12>;
+ clocks = <&ahb_clk>;
+ };
+ emif_clk@52M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <2>; /* Rest */
+ clock-id = <5>;
+ clocks = <&ahb_clk>;
+ };
+ dmac_clk: dmac_clk@52M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <2>; /* Rest */
+ clock-id = <4>;
+ clocks = <&app52>;
+ };
+ fsmc_clk: fsmc_clk@52M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <2>; /* Rest */
+ clock-id = <6>;
+ clocks = <&app52>;
+ };
+ xgam_clk: xgam_clk@52M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <2>; /* Rest */
+ clock-id = <8>;
+ clocks = <&app52>;
+ };
+ app26: app_26_clk@26M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <2>;
+ clock-mult = <1>;
+ clocks = <&app52>;
+ };
+ /* Fast bridge clocks */
+ fast_clk: fast_clk@26M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <1>; /* Fast */
+ clock-id = <0>;
+ clocks = <&app26>;
+ };
+ i2c0_clk: i2c0_clk@26M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <1>; /* Fast */
+ clock-id = <1>;
+ clocks = <&fast_clk>;
+ };
+ i2c1_clk: i2c1_clk@26M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <1>; /* Fast */
+ clock-id = <2>;
+ clocks = <&fast_clk>;
+ };
+ mmc_pclk: mmc_p_clk@26M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <1>; /* Fast */
+ clock-id = <5>;
+ clocks = <&fast_clk>;
+ };
+ mmc_mclk: mmc_mclk {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-mclk";
+ clocks = <&mmc_pclk>;
+ };
+ spi_clk: spi_p_clk@26M {
+ #clock-cells = <0>;
+ compatible = "stericsson,u300-syscon-clk";
+ clock-type = <1>; /* Fast */
+ clock-id = <6>;
+ clocks = <&fast_clk>;
+ };
+ };
+
+ timer: timer@c0014000 {
+ compatible = "stericsson,u300-apptimer";
+ reg = <0xc0014000 0x1000>;
+ interrupt-parent = <&vica>;
+ interrupts = <24 25 26 27>;
+ clocks = <&apptimer_clk>;
+ };
+
+ gpio: gpio@c0016000 {
+ compatible = "stericsson,gpio-coh901";
+ reg = <0xc0016000 0x1000>;
+ interrupt-parent = <&vicb>;
+ interrupts = <0 1 2 18 21 22 23>;
+ clocks = <&gpio_clk>;
+ interrupt-names = "gpio0", "gpio1", "gpio2", "gpio3",
+ "gpio4", "gpio5", "gpio6";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pinctrl: pinctrl@c0011000 {
+ compatible = "stericsson,pinctrl-u300";
+ reg = <0xc0011000 0x1000>;
+ };
+
+ watchdog: watchdog@c0012000 {
+ compatible = "stericsson,coh901327";
+ reg = <0xc0012000 0x1000>;
+ interrupt-parent = <&vicb>;
+ interrupts = <3>;
+ clocks = <&clk32>;
+ };
+
+ rtc: rtc@c0017000 {
+ compatible = "stericsson,coh901331";
+ reg = <0xc0017000 0x1000>;
+ interrupt-parent = <&vicb>;
+ interrupts = <10>;
+ clocks = <&rtc_clk>;
+ };
+
+ dmac: dma-controller@c00020000 {
+ compatible = "stericsson,coh901318";
+ reg = <0xc0020000 0x1000>;
+ interrupt-parent = <&vica>;
+ interrupts = <2>;
+ #dma-cells = <1>;
+ dma-channels = <40>;
+ clocks = <&dmac_clk>;
+ };
+
+ /* A NAND flash of 128 MiB */
+ fsmc: flash@40000000 {
+ compatible = "stericsson,fsmc-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x9f800000 0x1000>, /* FSMC Register*/
+ <0x80000000 0x4000>, /* NAND Base DATA */
+ <0x80020000 0x4000>, /* NAND Base ADDR */
+ <0x80010000 0x4000>; /* NAND Base CMD */
+ reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
+ nand-skip-bbtscan;
+ clocks = <&fsmc_clk>;
+
+ partition@0 {
+ label = "boot records";
+ reg = <0x0 0x20000>;
+ };
+ partition@20000 {
+ label = "free";
+ reg = <0x20000 0x7e0000>;
+ };
+ partition@800000 {
+ label = "platform";
+ reg = <0x800000 0xf800000>;
+ };
+ };
+
+ i2c0: i2c@c0004000 {
+ compatible = "st,ddci2c";
+ reg = <0xc0004000 0x1000>;
+ interrupt-parent = <&vicb>;
+ interrupts = <8>;
+ clocks = <&i2c0_clk>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ab3100: ab3100@48 {
+ compatible = "stericsson,ab3100";
+ reg = <0x48>;
+ interrupt-parent = <&vica>;
+ interrupts = <0>; /* EXT0 IRQ */
+ ab3100-regulators {
+ compatible = "stericsson,ab3100-regulators";
+ ab3100_ldo_a_reg: ab3100_ldo_a {
+ regulator-compatible = "ab3100_ldo_a";
+ startup-delay-us = <200>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ ab3100_ldo_c_reg: ab3100_ldo_c {
+ regulator-compatible = "ab3100_ldo_c";
+ startup-delay-us = <200>;
+ };
+ ab3100_ldo_d_reg: ab3100_ldo_d {
+ regulator-compatible = "ab3100_ldo_d";
+ startup-delay-us = <200>;
+ };
+ ab3100_ldo_e_reg: ab3100_ldo_e {
+ regulator-compatible = "ab3100_ldo_e";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ startup-delay-us = <200>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ ab3100_ldo_f_reg: ab3100_ldo_f {
+ regulator-compatible = "ab3100_ldo_f";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ startup-delay-us = <600>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ ab3100_ldo_g_reg: ab3100_ldo_g {
+ regulator-compatible = "ab3100_ldo_g";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <2850000>;
+ startup-delay-us = <400>;
+ };
+ ab3100_ldo_h_reg: ab3100_ldo_h {
+ regulator-compatible = "ab3100_ldo_h";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <2750000>;
+ startup-delay-us = <200>;
+ };
+ ab3100_ldo_k_reg: ab3100_ldo_k {
+ regulator-compatible = "ab3100_ldo_k";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2750000>;
+ startup-delay-us = <200>;
+ };
+ ab3100_ext_reg: ab3100_ext {
+ regulator-compatible = "ab3100_ext";
+ };
+ ab3100_buck_reg: ab3100_buck {
+ regulator-compatible = "ab3100_buck";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1800000>;
+ startup-delay-us = <1000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+ };
+
+ i2c1: i2c@c0005000 {
+ compatible = "st,ddci2c";
+ reg = <0xc0005000 0x1000>;
+ interrupt-parent = <&vicb>;
+ interrupts = <9>;
+ clocks = <&i2c1_clk>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ fwcam0: fwcam@10 {
+ reg = <0x10>;
+ };
+ fwcam1: fwcam@5d {
+ reg = <0x5d>;
+ };
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ vica: interrupt-controller@a0001000 {
+ compatible = "arm,versatile-vic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xa0001000 0x20>;
+ };
+
+ vicb: interrupt-controller@a0002000 {
+ compatible = "arm,versatile-vic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xa0002000 0x20>;
+ };
+
+ uart0: serial@c0013000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xc0013000 0x1000>;
+ interrupt-parent = <&vica>;
+ interrupts = <22>;
+ clocks = <&uart0_clk>, <&uart0_clk>;
+ clock-names = "apb_pclk", "uart0_clk";
+ dmas = <&dmac 17 &dmac 18>;
+ dma-names = "tx", "rx";
+ };
+
+ uart1: serial@c0007000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xc0007000 0x1000>;
+ interrupt-parent = <&vicb>;
+ interrupts = <20>;
+ dmas = <&dmac 38 &dmac 39>;
+ dma-names = "tx", "rx";
+ };
+
+ mmcsd: mmcsd@c0001000 {
+ compatible = "arm,pl18x", "arm,primecell";
+ reg = <0xc0001000 0x1000>;
+ interrupt-parent = <&vicb>;
+ interrupts = <6 7>;
+ clocks = <&mmc_pclk>, <&mmc_mclk>;
+ clock-names = "apb_pclk", "mclk";
+ max-frequency = <24000000>;
+ bus-width = <4>; // SD-card slot
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio 12 0x4>;
+ cd-inverted;
+ vmmc-supply = <&ab3100_ldo_g_reg>;
+ dmas = <&dmac 14>;
+ dma-names = "rx";
+ };
+
+ spi: ssp@c0006000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0xc0006000 0x1000>;
+ interrupt-parent = <&vica>;
+ interrupts = <23>;
+ clocks = <&spi_clk>, <&spi_clk>;
+ clock-names = "SSPCLK", "apb_pclk";
+ dmas = <&dmac 27 &dmac 28>;
+ dma-names = "tx", "rx";
+ num-cs = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ spi-dummy@1 {
+ compatible = "arm,pl022-dummy";
+ reg = <1>;
+ spi-max-frequency = <20000000>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih407-b2120.dts b/arch/arm/boot/dts/stih407-b2120.dts
new file mode 100644
index 000000000..af487145c
--- /dev/null
+++ b/arch/arm/boot/dts/stih407-b2120.dts
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics (R&D) Limited.
+ * Author: Giuseppe Cavallaro <peppe.cavallaro@st.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.
+ */
+/dts-v1/;
+#include "stihxxx-b2120.dtsi"
+#include "stih407.dtsi"
+/ {
+ model = "STiH407 B2120";
+ compatible = "st,stih407-b2120", "st,stih407";
+
+ chosen {
+ bootargs = "console=ttyAS0,115200 clk_ignore_unused";
+ linux,stdout-path = &sbc_serial0;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x40000000 0x80000000>;
+ };
+
+ aliases {
+ ttyAS0 = &sbc_serial0;
+ };
+
+};
diff --git a/arch/arm/boot/dts/stih407-clock.dtsi b/arch/arm/boot/dts/stih407-clock.dtsi
new file mode 100644
index 000000000..e65744fc1
--- /dev/null
+++ b/arch/arm/boot/dts/stih407-clock.dtsi
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics R&D 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 <dt-bindings/clock/stih407-clks.h>
+/ {
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /*
+ * Fixed 30MHz oscillator inputs to SoC
+ */
+ clk_sysin: clk-sysin {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <30000000>;
+ };
+
+ /*
+ * ARM Peripheral clock for timers
+ */
+ arm_periph_clk: clk-m-a9-periphs {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+
+ clocks = <&clk_m_a9>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+
+ /*
+ * A9 PLL.
+ */
+ clockgen-a9@92b0000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x92b0000 0xffff>;
+
+ clockgen_a9_pll: clockgen-a9-pll {
+ #clock-cells = <1>;
+ compatible = "st,stih407-plls-c32-a9", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clockgen-a9-pll-odf";
+ };
+ };
+
+ /*
+ * ARM CPU related clocks.
+ */
+ clk_m_a9: clk-m-a9@92b0000 {
+ #clock-cells = <0>;
+ compatible = "st,stih407-clkgen-a9-mux", "st,clkgen-mux";
+ reg = <0x92b0000 0x10000>;
+
+ clocks = <&clockgen_a9_pll 0>,
+ <&clockgen_a9_pll 0>,
+ <&clk_s_c0_flexgen 13>,
+ <&clk_m_a9_ext2f_div2>;
+ };
+
+ /*
+ * ARM Peripheral clock for timers
+ */
+ clk_m_a9_ext2f_div2: clk-m-a9-ext2f-div2s {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+
+ clocks = <&clk_s_c0_flexgen 13>;
+
+ clock-output-names = "clk-m-a9-ext2f-div2";
+
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+
+ /*
+ * Bootloader initialized system infrastructure clock for
+ * serial devices.
+ */
+ clk_ext2f_a9: clockgen-c0@13 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <200000000>;
+ clock-output-names = "clk-s-icn-reg-0";
+ };
+
+ clockgen-a@090ff000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x90ff000 0x1000>;
+
+ clk_s_a0_pll: clk-s-a0-pll {
+ #clock-cells = <1>;
+ compatible = "st,stih407-plls-c32-a0", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-a0-pll-ofd-0";
+ };
+
+ clk_s_a0_flexgen: clk-s-a0-flexgen {
+ compatible = "st,flexgen";
+
+ #clock-cells = <1>;
+
+ clocks = <&clk_s_a0_pll 0>,
+ <&clk_sysin>;
+
+ clock-output-names = "clk-ic-lmi0";
+ };
+ };
+
+ clk_s_c0_quadfs: clk-s-c0-quadfs@9103000 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-quadfs660-C", "st,quadfs";
+ reg = <0x9103000 0x1000>;
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-c0-fs0-ch0",
+ "clk-s-c0-fs0-ch1",
+ "clk-s-c0-fs0-ch2",
+ "clk-s-c0-fs0-ch3";
+ };
+
+ clk_s_c0: clockgen-c@09103000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x9103000 0x1000>;
+
+ clk_s_c0_pll0: clk-s-c0-pll0 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-plls-c32-c0_0", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-c0-pll0-odf-0";
+ };
+
+ clk_s_c0_pll1: clk-s-c0-pll1 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-plls-c32-c0_1", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-c0-pll1-odf-0";
+ };
+
+ clk_s_c0_flexgen: clk-s-c0-flexgen {
+ #clock-cells = <1>;
+ compatible = "st,flexgen";
+
+ clocks = <&clk_s_c0_pll0 0>,
+ <&clk_s_c0_pll1 0>,
+ <&clk_s_c0_quadfs 0>,
+ <&clk_s_c0_quadfs 1>,
+ <&clk_s_c0_quadfs 2>,
+ <&clk_s_c0_quadfs 3>,
+ <&clk_sysin>;
+
+ clock-output-names = "clk-icn-gpu",
+ "clk-fdma",
+ "clk-nand",
+ "clk-hva",
+ "clk-proc-stfe",
+ "clk-proc-tp",
+ "clk-rx-icn-dmu",
+ "clk-rx-icn-hva",
+ "clk-icn-cpu",
+ "clk-tx-icn-dmu",
+ "clk-mmc-0",
+ "clk-mmc-1",
+ "clk-jpegdec",
+ "clk-ext2fa9",
+ "clk-ic-bdisp-0",
+ "clk-ic-bdisp-1",
+ "clk-pp-dmu",
+ "clk-vid-dmu",
+ "clk-dss-lpc",
+ "clk-st231-aud-0",
+ "clk-st231-gp-1",
+ "clk-st231-dmu",
+ "clk-icn-lmi",
+ "clk-tx-icn-disp-1",
+ "clk-icn-sbc",
+ "clk-stfe-frc2",
+ "clk-eth-phy",
+ "clk-eth-ref-phyclk",
+ "clk-flash-promip",
+ "clk-main-disp",
+ "clk-aux-disp",
+ "clk-compo-dvp";
+ };
+ };
+
+ clk_s_d0_quadfs: clk-s-d0-quadfs@9104000 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-quadfs660-D", "st,quadfs";
+ reg = <0x9104000 0x1000>;
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-d0-fs0-ch0",
+ "clk-s-d0-fs0-ch1",
+ "clk-s-d0-fs0-ch2",
+ "clk-s-d0-fs0-ch3";
+ };
+
+ clockgen-d0@09104000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x9104000 0x1000>;
+
+ clk_s_d0_flexgen: clk-s-d0-flexgen {
+ #clock-cells = <1>;
+ compatible = "st,flexgen";
+
+ clocks = <&clk_s_d0_quadfs 0>,
+ <&clk_s_d0_quadfs 1>,
+ <&clk_s_d0_quadfs 2>,
+ <&clk_s_d0_quadfs 3>,
+ <&clk_sysin>;
+
+ clock-output-names = "clk-pcm-0",
+ "clk-pcm-1",
+ "clk-pcm-2",
+ "clk-spdiff";
+ };
+ };
+
+ clk_s_d2_quadfs: clk-s-d2-quadfs@9106000 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-quadfs660-D", "st,quadfs";
+ reg = <0x9106000 0x1000>;
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-d2-fs0-ch0",
+ "clk-s-d2-fs0-ch1",
+ "clk-s-d2-fs0-ch2",
+ "clk-s-d2-fs0-ch3";
+ };
+
+ clk_tmdsout_hdmi: clk-tmdsout-hdmi {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ clockgen-d2@x9106000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x9106000 0x1000>;
+
+ clk_s_d2_flexgen: clk-s-d2-flexgen {
+ #clock-cells = <1>;
+ compatible = "st,flexgen";
+
+ clocks = <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 1>,
+ <&clk_s_d2_quadfs 2>,
+ <&clk_s_d2_quadfs 3>,
+ <&clk_sysin>,
+ <&clk_sysin>,
+ <&clk_tmdsout_hdmi>;
+
+ clock-output-names = "clk-pix-main-disp",
+ "clk-pix-pip",
+ "clk-pix-gdp1",
+ "clk-pix-gdp2",
+ "clk-pix-gdp3",
+ "clk-pix-gdp4",
+ "clk-pix-aux-disp",
+ "clk-denc",
+ "clk-pix-hddac",
+ "clk-hddac",
+ "clk-sddac",
+ "clk-pix-dvo",
+ "clk-dvo",
+ "clk-pix-hdmi",
+ "clk-tmds-hdmi",
+ "clk-ref-hdmiphy";
+ };
+ };
+
+ clk_s_d3_quadfs: clk-s-d3-quadfs@9107000 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-quadfs660-D", "st,quadfs";
+ reg = <0x9107000 0x1000>;
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-d3-fs0-ch0",
+ "clk-s-d3-fs0-ch1",
+ "clk-s-d3-fs0-ch2",
+ "clk-s-d3-fs0-ch3";
+ };
+
+ clockgen-d3@9107000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x9107000 0x1000>;
+
+ clk_s_d3_flexgen: clk-s-d3-flexgen {
+ #clock-cells = <1>;
+ compatible = "st,flexgen";
+
+ clocks = <&clk_s_d3_quadfs 0>,
+ <&clk_s_d3_quadfs 1>,
+ <&clk_s_d3_quadfs 2>,
+ <&clk_s_d3_quadfs 3>,
+ <&clk_sysin>;
+
+ clock-output-names = "clk-stfe-frc1",
+ "clk-tsout-0",
+ "clk-tsout-1",
+ "clk-mchi",
+ "clk-vsens-compo",
+ "clk-frc1-remote",
+ "clk-lpc-0",
+ "clk-lpc-1";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
new file mode 100644
index 000000000..c06a54681
--- /dev/null
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics Limited.
+ * Author: Giuseppe Cavallaro <peppe.cavallaro@st.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 "stih407-pinctrl.dtsi"
+#include <dt-bindings/reset-controller/stih407-resets.h>
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ };
+ };
+
+ intc: interrupt-controller@08761000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x08761000 0x1000>, <0x08760100 0x100>;
+ };
+
+ scu@08760000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0x08760000 0x1000>;
+ };
+
+ timer@08760200 {
+ interrupt-parent = <&intc>;
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x08760200 0x100>;
+ interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&arm_periph_clk>;
+ };
+
+ l2: cache-controller {
+ compatible = "arm,pl310-cache";
+ reg = <0x08762000 0x1000>;
+ arm,data-latency = <3 3 3>;
+ arm,tag-latency = <2 2 2>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&intc>;
+ ranges;
+ compatible = "simple-bus";
+
+ powerdown: powerdown-controller {
+ compatible = "st,stih407-powerdown";
+ #reset-cells = <1>;
+ };
+
+ softreset: softreset-controller {
+ compatible = "st,stih407-softreset";
+ #reset-cells = <1>;
+ };
+
+ picophyreset: picophyreset-controller {
+ compatible = "st,stih407-picophyreset";
+ #reset-cells = <1>;
+ };
+
+ syscfg_sbc: sbc-syscfg@9620000 {
+ compatible = "st,stih407-sbc-syscfg", "syscon";
+ reg = <0x9620000 0x1000>;
+ };
+
+ syscfg_front: front-syscfg@9280000 {
+ compatible = "st,stih407-front-syscfg", "syscon";
+ reg = <0x9280000 0x1000>;
+ };
+
+ syscfg_rear: rear-syscfg@9290000 {
+ compatible = "st,stih407-rear-syscfg", "syscon";
+ reg = <0x9290000 0x1000>;
+ };
+
+ syscfg_flash: flash-syscfg@92a0000 {
+ compatible = "st,stih407-flash-syscfg", "syscon";
+ reg = <0x92a0000 0x1000>;
+ };
+
+ syscfg_sbc_reg: fvdp-lite-syscfg@9600000 {
+ compatible = "st,stih407-sbc-reg-syscfg", "syscon";
+ reg = <0x9600000 0x1000>;
+ };
+
+ syscfg_core: core-syscfg@92b0000 {
+ compatible = "st,stih407-core-syscfg", "syscon";
+ reg = <0x92b0000 0x1000>;
+ };
+
+ syscfg_lpm: lpm-syscfg@94b5100 {
+ compatible = "st,stih407-lpm-syscfg", "syscon";
+ reg = <0x94b5100 0x1000>;
+ };
+
+ serial@9830000 {
+ compatible = "st,asc";
+ reg = <0x9830000 0x2c>;
+ interrupts = <GIC_SPI 122 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_serial0>;
+ clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>;
+
+ status = "disabled";
+ };
+
+ serial@9831000 {
+ compatible = "st,asc";
+ reg = <0x9831000 0x2c>;
+ interrupts = <GIC_SPI 123 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_serial1>;
+ clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>;
+
+ status = "disabled";
+ };
+
+ serial@9832000 {
+ compatible = "st,asc";
+ reg = <0x9832000 0x2c>;
+ interrupts = <GIC_SPI 124 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_serial2>;
+ clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>;
+
+ status = "disabled";
+ };
+
+ /* SBC_ASC0 - UART10 */
+ sbc_serial0: serial@9530000 {
+ compatible = "st,asc";
+ reg = <0x9530000 0x2c>;
+ interrupts = <GIC_SPI 138 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sbc_serial0>;
+ clocks = <&clk_sysin>;
+
+ status = "disabled";
+ };
+
+ serial@9531000 {
+ compatible = "st,asc";
+ reg = <0x9531000 0x2c>;
+ interrupts = <GIC_SPI 139 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sbc_serial1>;
+ clocks = <&clk_sysin>;
+
+ status = "disabled";
+ };
+
+ i2c@9840000 {
+ compatible = "st,comms-ssc4-i2c";
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x9840000 0x110>;
+ clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_default>;
+
+ status = "disabled";
+ };
+
+ i2c@9841000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0x9841000 0x110>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1_default>;
+
+ status = "disabled";
+ };
+
+ i2c@9842000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0x9842000 0x110>;
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2_default>;
+
+ status = "disabled";
+ };
+
+ i2c@9843000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0x9843000 0x110>;
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3_default>;
+
+ status = "disabled";
+ };
+
+ i2c@9844000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0x9844000 0x110>;
+ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4_default>;
+
+ status = "disabled";
+ };
+
+ i2c@9845000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0x9845000 0x110>;
+ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c5_default>;
+
+ status = "disabled";
+ };
+
+
+ /* SSCs on SBC */
+ i2c@9540000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0x9540000 0x110>;
+ interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_sysin>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c10_default>;
+
+ status = "disabled";
+ };
+
+ i2c@9541000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0x9541000 0x110>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_sysin>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c11_default>;
+
+ status = "disabled";
+ };
+
+ usb2_picophy0: phy1 {
+ compatible = "st,stih407-usb2-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core 0x100 0xf4>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
+ <&picophyreset STIH407_PICOPHY0_RESET>;
+ reset-names = "global", "port";
+ };
+
+ miphy28lp_phy: miphy28lp@9b22000 {
+ compatible = "st,miphy28lp-phy";
+ st,syscfg = <&syscfg_core>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ phy_port0: port@9b22000 {
+ reg = <0x9b22000 0xff>,
+ <0x9b09000 0xff>,
+ <0x9b04000 0xff>;
+ reg-names = "sata-up",
+ "pcie-up",
+ "pipew";
+
+ st,syscfg = <0x114 0x818 0xe0 0xec>;
+ #phy-cells = <1>;
+
+ reset-names = "miphy-sw-rst";
+ resets = <&softreset STIH407_MIPHY0_SOFTRESET>;
+ };
+
+ phy_port1: port@9b2a000 {
+ reg = <0x9b2a000 0xff>,
+ <0x9b19000 0xff>,
+ <0x9b14000 0xff>;
+ reg-names = "sata-up",
+ "pcie-up",
+ "pipew";
+
+ st,syscfg = <0x118 0x81c 0xe4 0xf0>;
+
+ #phy-cells = <1>;
+
+ reset-names = "miphy-sw-rst";
+ resets = <&softreset STIH407_MIPHY1_SOFTRESET>;
+ };
+
+ phy_port2: port@8f95000 {
+ reg = <0x8f95000 0xff>,
+ <0x8f90000 0xff>;
+ reg-names = "pipew",
+ "usb3-up";
+
+ st,syscfg = <0x11c 0x820>;
+
+ #phy-cells = <1>;
+
+ reset-names = "miphy-sw-rst";
+ resets = <&softreset STIH407_MIPHY2_SOFTRESET>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih407-pinctrl.dtsi b/arch/arm/boot/dts/stih407-pinctrl.dtsi
new file mode 100644
index 000000000..402844cb3
--- /dev/null
+++ b/arch/arm/boot/dts/stih407-pinctrl.dtsi
@@ -0,0 +1,615 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics Limited.
+ * Author: Giuseppe Cavallaro <peppe.cavallaro@st.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 "st-pincfg.h"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+/ {
+
+ aliases {
+ /* 0-5: PIO_SBC */
+ gpio0 = &pio0;
+ gpio1 = &pio1;
+ gpio2 = &pio2;
+ gpio3 = &pio3;
+ gpio4 = &pio4;
+ gpio5 = &pio5;
+ /* 10-19: PIO_FRONT0 */
+ gpio6 = &pio10;
+ gpio7 = &pio11;
+ gpio8 = &pio12;
+ gpio9 = &pio13;
+ gpio10 = &pio14;
+ gpio11 = &pio15;
+ gpio12 = &pio16;
+ gpio13 = &pio17;
+ gpio14 = &pio18;
+ gpio15 = &pio19;
+ /* 20: PIO_FRONT1 */
+ gpio16 = &pio20;
+ /* 30-35: PIO_REAR */
+ gpio17 = &pio30;
+ gpio18 = &pio31;
+ gpio19 = &pio32;
+ gpio20 = &pio33;
+ gpio21 = &pio34;
+ gpio22 = &pio35;
+ /* 40-42: PIO_FLASH */
+ gpio23 = &pio40;
+ gpio24 = &pio41;
+ gpio25 = &pio42;
+ };
+
+ soc {
+ pin-controller-sbc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stih407-sbc-pinctrl";
+ st,syscfg = <&syscfg_sbc>;
+ reg = <0x0961f080 0x4>;
+ reg-names = "irqmux";
+ interrupts = <GIC_SPI 188 IRQ_TYPE_NONE>;
+ interrupts-names = "irqmux";
+ ranges = <0 0x09610000 0x6000>;
+
+ pio0: gpio@09610000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x0 0x100>;
+ st,bank-name = "PIO0";
+ };
+ pio1: gpio@09611000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1000 0x100>;
+ st,bank-name = "PIO1";
+ };
+ pio2: gpio@09612000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x2000 0x100>;
+ st,bank-name = "PIO2";
+ };
+ pio3: gpio@09613000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x3000 0x100>;
+ st,bank-name = "PIO3";
+ };
+ pio4: gpio@09614000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x4000 0x100>;
+ st,bank-name = "PIO4";
+ };
+
+ pio5: gpio@09615000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x5000 0x100>;
+ st,bank-name = "PIO5";
+ };
+
+ rc {
+ pinctrl_ir: ir0 {
+ st,pins {
+ ir = <&pio4 0 ALT2 IN>;
+ };
+ };
+ };
+
+ /* SBC_ASC0 - UART10 */
+ sbc_serial0 {
+ pinctrl_sbc_serial0: sbc_serial0-0 {
+ st,pins {
+ tx = <&pio3 4 ALT1 OUT>;
+ rx = <&pio3 5 ALT1 IN>;
+ };
+ };
+ };
+ /* SBC_ASC1 - UART11 */
+ sbc_serial1 {
+ pinctrl_sbc_serial1: sbc_serial1-0 {
+ st,pins {
+ tx = <&pio2 6 ALT3 OUT>;
+ rx = <&pio2 7 ALT3 IN>;
+ };
+ };
+ };
+
+ i2c10 {
+ pinctrl_i2c10_default: i2c10-default {
+ st,pins {
+ sda = <&pio4 6 ALT1 BIDIR>;
+ scl = <&pio4 5 ALT1 BIDIR>;
+ };
+ };
+ };
+
+ i2c11 {
+ pinctrl_i2c11_default: i2c11-default {
+ st,pins {
+ sda = <&pio5 1 ALT1 BIDIR>;
+ scl = <&pio5 0 ALT1 BIDIR>;
+ };
+ };
+ };
+
+ keyscan {
+ pinctrl_keyscan: keyscan {
+ st,pins {
+ keyin0 = <&pio4 0 ALT6 IN>;
+ keyin1 = <&pio4 5 ALT4 IN>;
+ keyin2 = <&pio0 4 ALT2 IN>;
+ keyin3 = <&pio2 6 ALT2 IN>;
+
+ keyout0 = <&pio4 6 ALT4 OUT>;
+ keyout1 = <&pio1 7 ALT2 OUT>;
+ keyout2 = <&pio0 6 ALT2 OUT>;
+ keyout3 = <&pio2 7 ALT2 OUT>;
+ };
+ };
+ };
+
+ gmac1 {
+ /*
+ * Almost all the boards based on STiH407 SoC have an embedded
+ * switch where the mdio/mdc have been used for managing the SMI
+ * iface via I2C. For this reason these lines can be allocated
+ * by using dedicated configuration (in case of there will be a
+ * standard PHY transceiver on-board).
+ */
+ pinctrl_rgmii1: rgmii1-0 {
+ st,pins {
+
+ txd0 = <&pio0 0 ALT1 OUT DE_IO 0 CLK_A>;
+ txd1 = <&pio0 1 ALT1 OUT DE_IO 0 CLK_A>;
+ txd2 = <&pio0 2 ALT1 OUT DE_IO 0 CLK_A>;
+ txd3 = <&pio0 3 ALT1 OUT DE_IO 0 CLK_A>;
+ txen = <&pio0 5 ALT1 OUT DE_IO 0 CLK_A>;
+ txclk = <&pio0 6 ALT1 IN NICLK 0 CLK_A>;
+ rxd0 = <&pio1 4 ALT1 IN DE_IO 0 CLK_A>;
+ rxd1 = <&pio1 5 ALT1 IN DE_IO 0 CLK_A>;
+ rxd2 = <&pio1 6 ALT1 IN DE_IO 0 CLK_A>;
+ rxd3 = <&pio1 7 ALT1 IN DE_IO 0 CLK_A>;
+ rxdv = <&pio2 0 ALT1 IN DE_IO 0 CLK_A>;
+ rxclk = <&pio2 2 ALT1 IN NICLK 500 CLK_A>;
+ clk125 = <&pio3 7 ALT4 IN NICLK 0 CLK_A>;
+ phyclk = <&pio2 3 ALT4 OUT NICLK 1750 CLK_B>;
+ };
+ };
+
+ pinctrl_rgmii1_mdio: rgmii1-mdio {
+ st,pins {
+ mdio = <&pio1 0 ALT1 OUT BYPASS 0>;
+ mdc = <&pio1 1 ALT1 OUT NICLK 0 CLK_A>;
+ mdint = <&pio1 3 ALT1 IN BYPASS 0>;
+ };
+ };
+
+ pinctrl_mii1: mii1 {
+ st,pins {
+ txd0 = <&pio0 0 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txd1 = <&pio0 1 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txd2 = <&pio0 2 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txd3 = <&pio0 3 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txer = <&pio0 4 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txen = <&pio0 5 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txclk = <&pio0 6 ALT1 IN NICLK 0 CLK_A>;
+ col = <&pio0 7 ALT1 IN BYPASS 1000>;
+
+ mdio = <&pio1 0 ALT1 OUT BYPASS 1500>;
+ mdc = <&pio1 1 ALT1 OUT NICLK 0 CLK_A>;
+ crs = <&pio1 2 ALT1 IN BYPASS 1000>;
+ mdint = <&pio1 3 ALT1 IN BYPASS 0>;
+ rxd0 = <&pio1 4 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ rxd1 = <&pio1 5 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ rxd2 = <&pio1 6 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ rxd3 = <&pio1 7 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+
+ rxdv = <&pio2 0 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ rx_er = <&pio2 1 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ rxclk = <&pio2 2 ALT1 IN NICLK 0 CLK_A>;
+ phyclk = <&pio2 3 ALT1 OUT NICLK 0 CLK_A>;
+ };
+ };
+ };
+
+ pwm1 {
+ pinctrl_pwm1_chan0_default: pwm1-0-default {
+ st,pins {
+ pwm-out = <&pio3 0 ALT1 OUT>;
+ };
+ };
+ pinctrl_pwm1_chan1_default: pwm1-1-default {
+ st,pins {
+ pwm-out = <&pio4 4 ALT1 OUT>;
+ };
+ };
+ pinctrl_pwm1_chan2_default: pwm1-2-default {
+ st,pins {
+ pwm-out = <&pio4 6 ALT3 OUT>;
+ };
+ };
+ pinctrl_pwm1_chan3_default: pwm1-3-default {
+ st,pins {
+ pwm-out = <&pio4 7 ALT3 OUT>;
+ };
+ };
+ };
+ };
+
+ pin-controller-front0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stih407-front-pinctrl";
+ st,syscfg = <&syscfg_front>;
+ reg = <0x0920f080 0x4>;
+ reg-names = "irqmux";
+ interrupts = <GIC_SPI 189 IRQ_TYPE_NONE>;
+ interrupts-names = "irqmux";
+ ranges = <0 0x09200000 0x10000>;
+
+ pio10: pio@09200000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x0 0x100>;
+ st,bank-name = "PIO10";
+ };
+ pio11: pio@09201000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1000 0x100>;
+ st,bank-name = "PIO11";
+ };
+ pio12: pio@09202000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x2000 0x100>;
+ st,bank-name = "PIO12";
+ };
+ pio13: pio@09203000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x3000 0x100>;
+ st,bank-name = "PIO13";
+ };
+ pio14: pio@09204000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x4000 0x100>;
+ st,bank-name = "PIO14";
+ };
+ pio15: pio@09205000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x5000 0x100>;
+ st,bank-name = "PIO15";
+ };
+ pio16: pio@09206000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x6000 0x100>;
+ st,bank-name = "PIO16";
+ };
+ pio17: pio@09207000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x7000 0x100>;
+ st,bank-name = "PIO17";
+ };
+ pio18: pio@09208000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x8000 0x100>;
+ st,bank-name = "PIO18";
+ };
+ pio19: pio@09209000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x9000 0x100>;
+ st,bank-name = "PIO19";
+ };
+
+ /* Comms */
+ serial0 {
+ pinctrl_serial0: serial0-0 {
+ st,pins {
+ tx = <&pio17 0 ALT1 OUT>;
+ rx = <&pio17 1 ALT1 IN>;
+ };
+ };
+ };
+
+ serial1 {
+ pinctrl_serial1: serial1-0 {
+ st,pins {
+ tx = <&pio16 0 ALT1 OUT>;
+ rx = <&pio16 1 ALT1 IN>;
+ };
+ };
+ };
+
+ serial2 {
+ pinctrl_serial2: serial2-0 {
+ st,pins {
+ tx = <&pio15 0 ALT1 OUT>;
+ rx = <&pio15 1 ALT1 IN>;
+ };
+ };
+ };
+
+ mmc1 {
+ pinctrl_sd1: sd1-0 {
+ st,pins {
+ sd_clk = <&pio19 3 ALT5 BIDIR NICLK 0 CLK_B>;
+ sd_cmd = <&pio19 2 ALT5 BIDIR_PU BYPASS 0>;
+ sd_dat0 = <&pio19 4 ALT5 BIDIR_PU BYPASS 0>;
+ sd_dat1 = <&pio19 5 ALT5 BIDIR_PU BYPASS 0>;
+ sd_dat2 = <&pio19 6 ALT5 BIDIR_PU BYPASS 0>;
+ sd_dat3 = <&pio19 7 ALT5 BIDIR_PU BYPASS 0>;
+ sd_led = <&pio16 6 ALT6 OUT>;
+ sd_pwren = <&pio16 7 ALT6 OUT>;
+ sd_cd = <&pio19 0 ALT6 IN>;
+ sd_wp = <&pio19 1 ALT6 IN>;
+ };
+ };
+ };
+
+
+ i2c0 {
+ pinctrl_i2c0_default: i2c0-default {
+ st,pins {
+ sda = <&pio10 6 ALT2 BIDIR>;
+ scl = <&pio10 5 ALT2 BIDIR>;
+ };
+ };
+ };
+
+ i2c1 {
+ pinctrl_i2c1_default: i2c1-default {
+ st,pins {
+ sda = <&pio11 1 ALT2 BIDIR>;
+ scl = <&pio11 0 ALT2 BIDIR>;
+ };
+ };
+ };
+
+ i2c2 {
+ pinctrl_i2c2_default: i2c2-default {
+ st,pins {
+ sda = <&pio15 6 ALT2 BIDIR>;
+ scl = <&pio15 5 ALT2 BIDIR>;
+ };
+ };
+ };
+
+ i2c3 {
+ pinctrl_i2c3_default: i2c3-default {
+ st,pins {
+ sda = <&pio18 6 ALT1 BIDIR>;
+ scl = <&pio18 5 ALT1 BIDIR>;
+ };
+ };
+ };
+
+ spi0 {
+ pinctrl_spi0_default: spi0-default {
+ st,pins {
+ mtsr = <&pio12 6 ALT2 BIDIR>;
+ mrst = <&pio12 7 ALT2 BIDIR>;
+ scl = <&pio12 5 ALT2 BIDIR>;
+ };
+ };
+ };
+ };
+
+ pin-controller-front1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stih407-front-pinctrl";
+ st,syscfg = <&syscfg_front>;
+ reg = <0x0921f080 0x4>;
+ reg-names = "irqmux";
+ interrupts = <GIC_SPI 190 IRQ_TYPE_NONE>;
+ interrupts-names = "irqmux";
+ ranges = <0 0x09210000 0x10000>;
+
+ pio20: pio@09210000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x0 0x100>;
+ st,bank-name = "PIO20";
+ };
+ };
+
+ pin-controller-rear {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stih407-rear-pinctrl";
+ st,syscfg = <&syscfg_rear>;
+ reg = <0x0922f080 0x4>;
+ reg-names = "irqmux";
+ interrupts = <GIC_SPI 191 IRQ_TYPE_NONE>;
+ interrupts-names = "irqmux";
+ ranges = <0 0x09220000 0x6000>;
+
+ pio30: gpio@09220000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x0 0x100>;
+ st,bank-name = "PIO30";
+ };
+ pio31: gpio@09221000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1000 0x100>;
+ st,bank-name = "PIO31";
+ };
+ pio32: gpio@09222000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x2000 0x100>;
+ st,bank-name = "PIO32";
+ };
+ pio33: gpio@09223000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x3000 0x100>;
+ st,bank-name = "PIO33";
+ };
+ pio34: gpio@09224000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x4000 0x100>;
+ st,bank-name = "PIO34";
+ };
+ pio35: gpio@09225000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x5000 0x100>;
+ st,bank-name = "PIO35";
+ };
+
+ i2c4 {
+ pinctrl_i2c4_default: i2c4-default {
+ st,pins {
+ sda = <&pio30 1 ALT1 BIDIR>;
+ scl = <&pio30 0 ALT1 BIDIR>;
+ };
+ };
+ };
+
+ i2c5 {
+ pinctrl_i2c5_default: i2c5-default {
+ st,pins {
+ sda = <&pio34 4 ALT1 BIDIR>;
+ scl = <&pio34 3 ALT1 BIDIR>;
+ };
+ };
+ };
+
+ usb3 {
+ pinctrl_usb3: usb3-2 {
+ st,pins {
+ usb-oc-detect = <&pio35 4 ALT1 IN>;
+ usb-pwr-enable = <&pio35 5 ALT1 OUT>;
+ usb-vbus-valid = <&pio35 6 ALT1 IN>;
+ };
+ };
+ };
+
+ pwm0 {
+ pinctrl_pwm0_chan0_default: pwm0-0-default {
+ st,pins {
+ pwm-out = <&pio31 1 ALT1 OUT>;
+ };
+ };
+ };
+ };
+
+ pin-controller-flash {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stih407-flash-pinctrl";
+ st,syscfg = <&syscfg_flash>;
+ reg = <0x0923f080 0x4>;
+ reg-names = "irqmux";
+ interrupts = <GIC_SPI 192 IRQ_TYPE_NONE>;
+ interrupts-names = "irqmux";
+ ranges = <0 0x09230000 0x3000>;
+
+ pio40: gpio@09230000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0 0x100>;
+ st,bank-name = "PIO40";
+ };
+ pio41: gpio@09231000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1000 0x100>;
+ st,bank-name = "PIO41";
+ };
+ pio42: gpio@09232000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x2000 0x100>;
+ st,bank-name = "PIO42";
+ };
+
+ mmc0 {
+ pinctrl_mmc0: mmc0-0 {
+ st,pins {
+ emmc_clk = <&pio40 6 ALT1 BIDIR>;
+ emmc_cmd = <&pio40 7 ALT1 BIDIR_PU>;
+ emmc_d0 = <&pio41 0 ALT1 BIDIR_PU>;
+ emmc_d1 = <&pio41 1 ALT1 BIDIR_PU>;
+ emmc_d2 = <&pio41 2 ALT1 BIDIR_PU>;
+ emmc_d3 = <&pio41 3 ALT1 BIDIR_PU>;
+ emmc_d4 = <&pio41 4 ALT1 BIDIR_PU>;
+ emmc_d5 = <&pio41 5 ALT1 BIDIR_PU>;
+ emmc_d6 = <&pio41 6 ALT1 BIDIR_PU>;
+ emmc_d7 = <&pio41 7 ALT1 BIDIR_PU>;
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih407.dtsi b/arch/arm/boot/dts/stih407.dtsi
new file mode 100644
index 000000000..3efa3b2eb
--- /dev/null
+++ b/arch/arm/boot/dts/stih407.dtsi
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2015 STMicroelectronics Limited.
+ * Author: Gabriel Fernandez <gabriel.fernandez@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
+ * publishhed by the Free Software Foundation.
+ */
+#include "stih407-clock.dtsi"
+#include "stih407-family.dtsi"
+/ {
+ soc {
+ /* Display */
+ vtg_main: sti-vtg-main@8d02800 {
+ compatible = "st,vtg";
+ reg = <0x8d02800 0x200>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_NONE>;
+ };
+
+ vtg_aux: sti-vtg-aux@8d00200 {
+ compatible = "st,vtg";
+ reg = <0x8d00200 0x100>;
+ interrupts = <GIC_SPI 109 IRQ_TYPE_NONE>;
+ };
+
+ sti-display-subsystem {
+ compatible = "st,sti-display-subsystem";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ assigned-clocks = <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>,
+ <&clk_s_d2_flexgen CLK_PIX_AUX_DISP>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP1>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP2>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP3>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP4>;
+
+ assigned-clock-parents = <0>,
+ <0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>;
+
+ assigned-clock-rates = <297000000>, <297000000>;
+
+ ranges;
+
+ sti-compositor@9d11000 {
+ compatible = "st,stih407-compositor";
+ reg = <0x9d11000 0x1000>;
+
+ clock-names = "compo_main",
+ "compo_aux",
+ "pix_main",
+ "pix_aux",
+ "pix_gdp1",
+ "pix_gdp2",
+ "pix_gdp3",
+ "pix_gdp4",
+ "main_parent",
+ "aux_parent";
+
+ clocks = <&clk_s_c0_flexgen CLK_COMPO_DVP>,
+ <&clk_s_c0_flexgen CLK_COMPO_DVP>,
+ <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>,
+ <&clk_s_d2_flexgen CLK_PIX_AUX_DISP>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP1>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP2>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP3>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP4>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 1>;
+
+ reset-names = "compo-main", "compo-aux";
+ resets = <&softreset STIH407_COMPO_SOFTRESET>,
+ <&softreset STIH407_COMPO_SOFTRESET>;
+ st,vtg = <&vtg_main>, <&vtg_aux>;
+ };
+
+ sti-tvout@8d08000 {
+ compatible = "st,stih407-tvout";
+ reg = <0x8d08000 0x1000>;
+ reg-names = "tvout-reg";
+ reset-names = "tvout";
+ resets = <&softreset STIH407_HDTVOUT_SOFTRESET>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ assigned-clocks = <&clk_s_d2_flexgen CLK_PIX_HDMI>,
+ <&clk_s_d2_flexgen CLK_TMDS_HDMI>,
+ <&clk_s_d2_flexgen CLK_REF_HDMIPHY>,
+ <&clk_s_d0_flexgen CLK_PCM_0>,
+ <&clk_s_d2_flexgen CLK_PIX_HDDAC>,
+ <&clk_s_d2_flexgen CLK_HDDAC>;
+
+ assigned-clock-parents = <&clk_s_d2_quadfs 0>,
+ <&clk_tmdsout_hdmi>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d0_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>;
+ ranges;
+
+ sti-hdmi@8d04000 {
+ compatible = "st,stih407-hdmi";
+ reg = <0x8d04000 0x1000>;
+ reg-names = "hdmi-reg";
+ interrupts = <GIC_SPI 106 IRQ_TYPE_NONE>;
+ interrupt-names = "irq";
+ clock-names = "pix",
+ "tmds",
+ "phy",
+ "audio",
+ "main_parent",
+ "aux_parent";
+
+ clocks = <&clk_s_d2_flexgen CLK_PIX_HDMI>,
+ <&clk_s_d2_flexgen CLK_TMDS_HDMI>,
+ <&clk_s_d2_flexgen CLK_REF_HDMIPHY>,
+ <&clk_s_d0_flexgen CLK_PCM_0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 1>;
+
+ hdmi,hpd-gpio = <&pio5 3>;
+ reset-names = "hdmi";
+ resets = <&softreset STIH407_HDMI_TX_PHY_SOFTRESET>;
+ ddc = <&hdmiddc>;
+
+ };
+
+ sti-hda@8d02000 {
+ compatible = "st,stih407-hda";
+ reg = <0x8d02000 0x400>, <0x92b0120 0x4>;
+ reg-names = "hda-reg", "video-dacs-ctrl";
+ clock-names = "pix",
+ "hddac",
+ "main_parent",
+ "aux_parent";
+ clocks = <&clk_s_d2_flexgen CLK_PIX_HDDAC>,
+ <&clk_s_d2_flexgen CLK_HDDAC>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 1>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih410-b2120.dts b/arch/arm/boot/dts/stih410-b2120.dts
new file mode 100644
index 000000000..2f61a9960
--- /dev/null
+++ b/arch/arm/boot/dts/stih410-b2120.dts
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics (R&D) Limited.
+ * Author: Peter Griffin <peter.griffin@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.
+ */
+/dts-v1/;
+#include "stih410.dtsi"
+#include "stihxxx-b2120.dtsi"
+/ {
+ model = "STiH410 B2120";
+ compatible = "st,stih410-b2120", "st,stih410";
+
+ chosen {
+ bootargs = "console=ttyAS0,115200 clk_ignore_unused";
+ linux,stdout-path = &sbc_serial0;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x40000000 0x80000000>;
+ };
+
+ aliases {
+ ttyAS0 = &sbc_serial0;
+ };
+};
diff --git a/arch/arm/boot/dts/stih410-clock.dtsi b/arch/arm/boot/dts/stih410-clock.dtsi
new file mode 100644
index 000000000..6b5803a30
--- /dev/null
+++ b/arch/arm/boot/dts/stih410-clock.dtsi
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics R&D 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 <dt-bindings/clock/stih410-clks.h>
+/ {
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ compatible = "st,stih410-clk", "simple-bus";
+
+ /*
+ * Fixed 30MHz oscillator inputs to SoC
+ */
+ clk_sysin: clk-sysin {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <30000000>;
+ clock-output-names = "CLK_SYSIN";
+ };
+
+ /*
+ * ARM Peripheral clock for timers
+ */
+ arm_periph_clk: clk-m-a9-periphs {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&clk_m_a9>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+
+ /*
+ * A9 PLL.
+ */
+ clockgen-a9@92b0000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x92b0000 0xffff>;
+
+ clockgen_a9_pll: clockgen-a9-pll {
+ #clock-cells = <1>;
+ compatible = "st,stih407-plls-c32-a9", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clockgen-a9-pll-odf";
+ };
+ };
+
+ /*
+ * ARM CPU related clocks.
+ */
+ clk_m_a9: clk-m-a9@92b0000 {
+ #clock-cells = <0>;
+ compatible = "st,stih407-clkgen-a9-mux", "st,clkgen-mux";
+ reg = <0x92b0000 0x10000>;
+
+ clocks = <&clockgen_a9_pll 0>,
+ <&clockgen_a9_pll 0>,
+ <&clk_s_c0_flexgen 13>,
+ <&clk_m_a9_ext2f_div2>;
+ };
+
+ /*
+ * ARM Peripheral clock for timers
+ */
+ clk_m_a9_ext2f_div2: clk-m-a9-ext2f-div2s {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+
+ clocks = <&clk_s_c0_flexgen 13>;
+
+ clock-output-names = "clk-m-a9-ext2f-div2";
+
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+
+ /*
+ * Bootloader initialized system infrastructure clock for
+ * serial devices.
+ */
+ clk_ext2f_a9: clockgen-c0@13 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <200000000>;
+ clock-output-names = "clk-s-icn-reg-0";
+ };
+
+ clockgen-a@090ff000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x90ff000 0x1000>;
+
+ clk_s_a0_pll: clk-s-a0-pll {
+ #clock-cells = <1>;
+ compatible = "st,stih407-plls-c32-a0", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-a0-pll-ofd-0";
+ };
+
+ clk_s_a0_flexgen: clk-s-a0-flexgen {
+ compatible = "st,flexgen";
+
+ #clock-cells = <1>;
+
+ clocks = <&clk_s_a0_pll 0>,
+ <&clk_sysin>;
+
+ clock-output-names = "clk-ic-lmi0",
+ "clk-ic-lmi1";
+ };
+ };
+
+ clk_s_c0_quadfs: clk-s-c0-quadfs@9103000 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-quadfs660-C", "st,quadfs";
+ reg = <0x9103000 0x1000>;
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-c0-fs0-ch0",
+ "clk-s-c0-fs0-ch1",
+ "clk-s-c0-fs0-ch2",
+ "clk-s-c0-fs0-ch3";
+ };
+
+ clk_s_c0: clockgen-c@09103000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x9103000 0x1000>;
+
+ clk_s_c0_pll0: clk-s-c0-pll0 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-plls-c32-c0_0", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-c0-pll0-odf-0";
+ };
+
+ clk_s_c0_pll1: clk-s-c0-pll1 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-plls-c32-c0_1", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-c0-pll1-odf-0";
+ };
+
+ clk_s_c0_flexgen: clk-s-c0-flexgen {
+ #clock-cells = <1>;
+ compatible = "st,flexgen";
+
+ clocks = <&clk_s_c0_pll0 0>,
+ <&clk_s_c0_pll1 0>,
+ <&clk_s_c0_quadfs 0>,
+ <&clk_s_c0_quadfs 1>,
+ <&clk_s_c0_quadfs 2>,
+ <&clk_s_c0_quadfs 3>,
+ <&clk_sysin>;
+
+ clock-output-names = "clk-icn-gpu",
+ "clk-fdma",
+ "clk-nand",
+ "clk-hva",
+ "clk-proc-stfe",
+ "clk-proc-tp",
+ "clk-rx-icn-dmu",
+ "clk-rx-icn-hva",
+ "clk-icn-cpu",
+ "clk-tx-icn-dmu",
+ "clk-mmc-0",
+ "clk-mmc-1",
+ "clk-jpegdec",
+ "clk-ext2fa9",
+ "clk-ic-bdisp-0",
+ "clk-ic-bdisp-1",
+ "clk-pp-dmu",
+ "clk-vid-dmu",
+ "clk-dss-lpc",
+ "clk-st231-aud-0",
+ "clk-st231-gp-1",
+ "clk-st231-dmu",
+ "clk-icn-lmi",
+ "clk-tx-icn-disp-1",
+ "clk-icn-sbc",
+ "clk-stfe-frc2",
+ "clk-eth-phy",
+ "clk-eth-ref-phyclk",
+ "clk-flash-promip",
+ "clk-main-disp",
+ "clk-aux-disp",
+ "clk-compo-dvp",
+ "clk-tx-icn-hades",
+ "clk-rx-icn-hades",
+ "clk-icn-reg-16",
+ "clk-pp-hades",
+ "clk-clust-hades",
+ "clk-hwpe-hades",
+ "clk-fc-hades";
+ };
+ };
+
+ clk_s_d0_quadfs: clk-s-d0-quadfs@9104000 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-quadfs660-D", "st,quadfs";
+ reg = <0x9104000 0x1000>;
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-d0-fs0-ch0",
+ "clk-s-d0-fs0-ch1",
+ "clk-s-d0-fs0-ch2",
+ "clk-s-d0-fs0-ch3";
+ };
+
+ clockgen-d0@09104000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x9104000 0x1000>;
+
+ clk_s_d0_flexgen: clk-s-d0-flexgen {
+ #clock-cells = <1>;
+ compatible = "st,flexgen";
+
+ clocks = <&clk_s_d0_quadfs 0>,
+ <&clk_s_d0_quadfs 1>,
+ <&clk_s_d0_quadfs 2>,
+ <&clk_s_d0_quadfs 3>,
+ <&clk_sysin>;
+
+ clock-output-names = "clk-pcm-0",
+ "clk-pcm-1",
+ "clk-pcm-2",
+ "clk-spdiff",
+ "clk-pcmr10-master",
+ "clk-usb2-phy";
+ };
+ };
+
+ clk_s_d2_quadfs: clk-s-d2-quadfs@9106000 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-quadfs660-D", "st,quadfs";
+ reg = <0x9106000 0x1000>;
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-d2-fs0-ch0",
+ "clk-s-d2-fs0-ch1",
+ "clk-s-d2-fs0-ch2",
+ "clk-s-d2-fs0-ch3";
+ };
+
+ clk_tmdsout_hdmi: clk-tmdsout-hdmi {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ clockgen-d2@x9106000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x9106000 0x1000>;
+
+ clk_s_d2_flexgen: clk-s-d2-flexgen {
+ #clock-cells = <1>;
+ compatible = "st,flexgen";
+
+ clocks = <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 1>,
+ <&clk_s_d2_quadfs 2>,
+ <&clk_s_d2_quadfs 3>,
+ <&clk_sysin>,
+ <&clk_sysin>,
+ <&clk_tmdsout_hdmi>;
+
+ clock-output-names = "clk-pix-main-disp",
+ "clk-pix-pip",
+ "clk-pix-gdp1",
+ "clk-pix-gdp2",
+ "clk-pix-gdp3",
+ "clk-pix-gdp4",
+ "clk-pix-aux-disp",
+ "clk-denc",
+ "clk-pix-hddac",
+ "clk-hddac",
+ "clk-sddac",
+ "clk-pix-dvo",
+ "clk-dvo",
+ "clk-pix-hdmi",
+ "clk-tmds-hdmi",
+ "clk-ref-hdmiphy";
+ };
+ };
+
+ clk_s_d3_quadfs: clk-s-d3-quadfs@9107000 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-quadfs660-D", "st,quadfs";
+ reg = <0x9107000 0x1000>;
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-d3-fs0-ch0",
+ "clk-s-d3-fs0-ch1",
+ "clk-s-d3-fs0-ch2",
+ "clk-s-d3-fs0-ch3";
+ };
+
+ clockgen-d3@9107000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x9107000 0x1000>;
+
+ clk_s_d3_flexgen: clk-s-d3-flexgen {
+ #clock-cells = <1>;
+ compatible = "st,flexgen";
+
+ clocks = <&clk_s_d3_quadfs 0>,
+ <&clk_s_d3_quadfs 1>,
+ <&clk_s_d3_quadfs 2>,
+ <&clk_s_d3_quadfs 3>,
+ <&clk_sysin>;
+
+ clock-output-names = "clk-stfe-frc1",
+ "clk-tsout-0",
+ "clk-tsout-1",
+ "clk-mchi",
+ "clk-vsens-compo",
+ "clk-frc1-remote",
+ "clk-lpc-0",
+ "clk-lpc-1";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih410-pinctrl.dtsi b/arch/arm/boot/dts/stih410-pinctrl.dtsi
new file mode 100644
index 000000000..b3e9dfc81
--- /dev/null
+++ b/arch/arm/boot/dts/stih410-pinctrl.dtsi
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics Limited.
+ * Author: Peter Griffin <peter.griffin@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
+ * publishhed by the Free Software Foundation.
+ */
+#include "st-pincfg.h"
+/ {
+
+ soc {
+ pin-controller-rear {
+
+ usb0 {
+ pinctrl_usb0: usb2-0 {
+ st,pins {
+ usb-oc-detect = <&pio35 0 ALT1 IN>;
+ usb-pwr-enable = <&pio35 1 ALT1 OUT>;
+ };
+ };
+ };
+
+ usb1 {
+ pinctrl_usb1: usb2-1 {
+ st,pins {
+ usb-oc-detect = <&pio35 2 ALT1 IN>;
+ usb-pwr-enable = <&pio35 3 ALT1 OUT>;
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih410.dtsi b/arch/arm/boot/dts/stih410.dtsi
new file mode 100644
index 000000000..208b5e890
--- /dev/null
+++ b/arch/arm/boot/dts/stih410.dtsi
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics Limited.
+ * Author: Peter Griffin <peter.griffin@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
+ * publishhed by the Free Software Foundation.
+ */
+#include "stih410-clock.dtsi"
+#include "stih407-family.dtsi"
+#include "stih410-pinctrl.dtsi"
+/ {
+ soc {
+ usb2_picophy1: phy2 {
+ compatible = "st,stih407-usb2-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core 0xf8 0xf4>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
+ <&picophyreset STIH407_PICOPHY0_RESET>;
+ reset-names = "global", "port";
+ };
+
+ usb2_picophy2: phy3 {
+ compatible = "st,stih407-usb2-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core 0xfc 0xf4>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
+ <&picophyreset STIH407_PICOPHY1_RESET>;
+ reset-names = "global", "port";
+ };
+
+ ohci0: usb@9a03c00 {
+ compatible = "st,st-ohci-300x";
+ reg = <0x9a03c00 0x100>;
+ interrupts = <GIC_SPI 180 IRQ_TYPE_NONE>;
+ clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+ resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>,
+ <&softreset STIH407_USB2_PORT0_SOFTRESET>;
+ reset-names = "power", "softreset";
+ phys = <&usb2_picophy1>;
+ phy-names = "usb";
+ };
+
+ ehci0: usb@9a03e00 {
+ compatible = "st,st-ehci-300x";
+ reg = <0x9a03e00 0x100>;
+ interrupts = <GIC_SPI 151 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0>;
+ clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+ resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>,
+ <&softreset STIH407_USB2_PORT0_SOFTRESET>;
+ reset-names = "power", "softreset";
+ phys = <&usb2_picophy1>;
+ phy-names = "usb";
+ };
+
+ ohci1: usb@9a83c00 {
+ compatible = "st,st-ohci-300x";
+ reg = <0x9a83c00 0x100>;
+ interrupts = <GIC_SPI 181 IRQ_TYPE_NONE>;
+ clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+ resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>,
+ <&softreset STIH407_USB2_PORT1_SOFTRESET>;
+ reset-names = "power", "softreset";
+ phys = <&usb2_picophy2>;
+ phy-names = "usb";
+ };
+
+ ehci1: usb@9a83e00 {
+ compatible = "st,st-ehci-300x";
+ reg = <0x9a83e00 0x100>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb1>;
+ clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+ resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>,
+ <&softreset STIH407_USB2_PORT1_SOFTRESET>;
+ reset-names = "power", "softreset";
+ phys = <&usb2_picophy2>;
+ phy-names = "usb";
+ };
+
+ /* Display */
+ vtg_main: sti-vtg-main@8d02800 {
+ compatible = "st,vtg";
+ reg = <0x8d02800 0x200>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_NONE>;
+ };
+
+ vtg_aux: sti-vtg-aux@8d00200 {
+ compatible = "st,vtg";
+ reg = <0x8d00200 0x100>;
+ interrupts = <GIC_SPI 109 IRQ_TYPE_NONE>;
+ };
+
+ sti-display-subsystem {
+ compatible = "st,sti-display-subsystem";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ assigned-clocks = <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>,
+ <&clk_s_d2_flexgen CLK_PIX_AUX_DISP>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP1>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP2>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP3>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP4>;
+
+ assigned-clock-parents = <0>,
+ <0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>;
+
+ assigned-clock-rates = <297000000>, <297000000>;
+
+ ranges;
+
+ sti-compositor@9d11000 {
+ compatible = "st,stih407-compositor";
+ reg = <0x9d11000 0x1000>;
+
+ clock-names = "compo_main",
+ "compo_aux",
+ "pix_main",
+ "pix_aux",
+ "pix_gdp1",
+ "pix_gdp2",
+ "pix_gdp3",
+ "pix_gdp4",
+ "main_parent",
+ "aux_parent";
+
+ clocks = <&clk_s_c0_flexgen CLK_COMPO_DVP>,
+ <&clk_s_c0_flexgen CLK_COMPO_DVP>,
+ <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>,
+ <&clk_s_d2_flexgen CLK_PIX_AUX_DISP>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP1>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP2>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP3>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP4>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 1>;
+
+ reset-names = "compo-main", "compo-aux";
+ resets = <&softreset STIH407_COMPO_SOFTRESET>,
+ <&softreset STIH407_COMPO_SOFTRESET>;
+ st,vtg = <&vtg_main>, <&vtg_aux>;
+ };
+
+ sti-tvout@8d08000 {
+ compatible = "st,stih407-tvout";
+ reg = <0x8d08000 0x1000>;
+ reg-names = "tvout-reg";
+ reset-names = "tvout";
+ resets = <&softreset STIH407_HDTVOUT_SOFTRESET>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ assigned-clocks = <&clk_s_d2_flexgen CLK_PIX_HDMI>,
+ <&clk_s_d2_flexgen CLK_TMDS_HDMI>,
+ <&clk_s_d2_flexgen CLK_REF_HDMIPHY>,
+ <&clk_s_d0_flexgen CLK_PCM_0>,
+ <&clk_s_d2_flexgen CLK_PIX_HDDAC>,
+ <&clk_s_d2_flexgen CLK_HDDAC>;
+
+ assigned-clock-parents = <&clk_s_d2_quadfs 0>,
+ <&clk_tmdsout_hdmi>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d0_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>;
+ ranges;
+
+ sti-hdmi@8d04000 {
+ compatible = "st,stih407-hdmi";
+ reg = <0x8d04000 0x1000>;
+ reg-names = "hdmi-reg";
+ interrupts = <GIC_SPI 106 IRQ_TYPE_NONE>;
+ interrupt-names = "irq";
+ clock-names = "pix",
+ "tmds",
+ "phy",
+ "audio",
+ "main_parent",
+ "aux_parent";
+
+ clocks = <&clk_s_d2_flexgen CLK_PIX_HDMI>,
+ <&clk_s_d2_flexgen CLK_TMDS_HDMI>,
+ <&clk_s_d2_flexgen CLK_REF_HDMIPHY>,
+ <&clk_s_d0_flexgen CLK_PCM_0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 1>;
+
+ hdmi,hpd-gpio = <&pio5 3>;
+ reset-names = "hdmi";
+ resets = <&softreset STIH407_HDMI_TX_PHY_SOFTRESET>;
+ ddc = <&hdmiddc>;
+
+ };
+
+ sti-hda@8d02000 {
+ compatible = "st,stih407-hda";
+ reg = <0x8d02000 0x400>, <0x92b0120 0x4>;
+ reg-names = "hda-reg", "video-dacs-ctrl";
+ clock-names = "pix",
+ "hddac",
+ "main_parent",
+ "aux_parent";
+ clocks = <&clk_s_d2_flexgen CLK_PIX_HDDAC>,
+ <&clk_s_d2_flexgen CLK_HDDAC>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 1>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih415-b2000.dts b/arch/arm/boot/dts/stih415-b2000.dts
new file mode 100644
index 000000000..bdfbd3765
--- /dev/null
+++ b/arch/arm/boot/dts/stih415-b2000.dts
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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.
+ */
+/dts-v1/;
+#include "stih415.dtsi"
+#include "stih41x-b2000.dtsi"
+/ {
+ model = "STiH415 B2000 Board";
+ compatible = "st,stih415-b2000", "st,stih415";
+};
diff --git a/arch/arm/boot/dts/stih415-b2020.dts b/arch/arm/boot/dts/stih415-b2020.dts
new file mode 100644
index 000000000..71903a87b
--- /dev/null
+++ b/arch/arm/boot/dts/stih415-b2020.dts
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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.
+ */
+/dts-v1/;
+#include "stih415.dtsi"
+#include "stih41x-b2020.dtsi"
+/ {
+ model = "STiH415 B2020 Board";
+ compatible = "st,stih415-b2020", "st,stih415";
+};
diff --git a/arch/arm/boot/dts/stih415-clock.dtsi b/arch/arm/boot/dts/stih415-clock.dtsi
new file mode 100644
index 000000000..3ee34514b
--- /dev/null
+++ b/arch/arm/boot/dts/stih415-clock.dtsi
@@ -0,0 +1,533 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) 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 <dt-bindings/clock/stih415-clks.h>
+
+/ {
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /*
+ * Fixed 30MHz oscillator input to SoC
+ */
+ clk_sysin: clk-sysin {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <30000000>;
+ };
+
+ /*
+ * ClockGenAs on SASG1
+ */
+ clockgen-a@fee62000 {
+ reg = <0xfee62000 0xb48>;
+
+ clk_s_a0_pll: clk-s-a0-pll {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-plls-c65";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-a0-pll0-hs",
+ "clk-s-a0-pll0-ls",
+ "clk-s-a0-pll1";
+ };
+
+ clk_s_a0_osc_prediv: clk-s-a0-osc-prediv {
+ #clock-cells = <0>;
+ compatible = "st,clkgena-prediv-c65",
+ "st,clkgena-prediv";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-a0-osc-prediv";
+ };
+
+ clk_s_a0_hs: clk-s-a0-hs {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c65-hs",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_s_a0_osc_prediv>,
+ <&clk_s_a0_pll 0>, /* PLL0 HS */
+ <&clk_s_a0_pll 2>; /* PLL1 */
+
+ clock-output-names = "clk-s-fdma-0",
+ "clk-s-fdma-1",
+ ""; /* clk-s-jit-sense */
+ /* Fourth output unused */
+ };
+
+ clk_s_a0_ls: clk-s-a0-ls {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c65-ls",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_s_a0_osc_prediv>,
+ <&clk_s_a0_pll 1>, /* PLL0 LS */
+ <&clk_s_a0_pll 2>; /* PLL1 */
+
+ clock-output-names = "clk-s-icn-reg-0",
+ "clk-s-icn-if-0",
+ "clk-s-icn-reg-lp-0",
+ "clk-s-emiss",
+ "clk-s-eth1-phy",
+ "clk-s-mii-ref-out";
+ /* Remaining outputs unused */
+ };
+ };
+
+ clockgen-a@fee81000 {
+ reg = <0xfee81000 0xb48>;
+
+ clk_s_a1_pll: clk-s-a1-pll {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-plls-c65";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-a1-pll0-hs",
+ "clk-s-a1-pll0-ls",
+ "clk-s-a1-pll1";
+ };
+
+ clk_s_a1_osc_prediv: clk-s-a1-osc-prediv {
+ #clock-cells = <0>;
+ compatible = "st,clkgena-prediv-c65",
+ "st,clkgena-prediv";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-a1-osc-prediv";
+ };
+
+ clk_s_a1_hs: clk-s-a1-hs {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c65-hs",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_s_a1_osc_prediv>,
+ <&clk_s_a1_pll 0>, /* PLL0 HS */
+ <&clk_s_a1_pll 2>; /* PLL1 */
+
+ clock-output-names = "", /* Reserved */
+ "", /* Reserved */
+ "clk-s-stac-phy",
+ "clk-s-vtac-tx-phy";
+ };
+
+ clk_s_a1_ls: clk-s-a1-ls {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c65-ls",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_s_a1_osc_prediv>,
+ <&clk_s_a1_pll 1>, /* PLL0 LS */
+ <&clk_s_a1_pll 2>; /* PLL1 */
+
+ clock-output-names = "clk-s-icn-if-2",
+ "clk-s-card-mmc",
+ "clk-s-icn-if-1",
+ "clk-s-gmac0-phy",
+ "clk-s-nand-ctrl",
+ "", /* Reserved */
+ "clk-s-mii0-ref-out",
+ ""; /* clk-s-stac-sys */
+ /* Remaining outputs unused */
+ };
+ };
+
+ /*
+ * ClockGenAs on MPE41
+ */
+ clockgen-a@fde12000 {
+ reg = <0xfde12000 0xb50>;
+
+ clk_m_a0_pll0: clk-m-a0-pll0 {
+ #clock-cells = <1>;
+ compatible = "st,plls-c32-a1x-0", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a0-pll0-phi0",
+ "clk-m-a0-pll0-phi1",
+ "clk-m-a0-pll0-phi2",
+ "clk-m-a0-pll0-phi3";
+ };
+
+ clk_m_a0_pll1: clk-m-a0-pll1 {
+ #clock-cells = <1>;
+ compatible = "st,plls-c32-a1x-1", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a0-pll1-phi0",
+ "clk-m-a0-pll1-phi1",
+ "clk-m-a0-pll1-phi2",
+ "clk-m-a0-pll1-phi3";
+ };
+
+ clk_m_a0_osc_prediv: clk-m-a0-osc-prediv {
+ #clock-cells = <0>;
+ compatible = "st,clkgena-prediv-c32",
+ "st,clkgena-prediv";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a0-osc-prediv";
+ };
+
+ clk_m_a0_div0: clk-m-a0-div0 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf0",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a0_osc_prediv>,
+ <&clk_m_a0_pll0 0>, /* PLL0 PHI0 */
+ <&clk_m_a0_pll1 0>; /* PLL1 PHI0 */
+
+ clock-output-names = "clk-m-apb-pm", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "clk-m-pp-dmu-0",
+ "clk-m-pp-dmu-1",
+ "clk-m-icm-disp",
+ ""; /* Unused */
+ };
+
+ clk_m_a0_div1: clk-m-a0-div1 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf1",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a0_osc_prediv>,
+ <&clk_m_a0_pll0 1>, /* PLL0 PHI1 */
+ <&clk_m_a0_pll1 1>; /* PLL1 PHI1 */
+
+ clock-output-names = "", /* Unused */
+ "", /* Unused */
+ "clk-m-a9-ext2f",
+ "clk-m-st40rt",
+ "clk-m-st231-dmu-0",
+ "clk-m-st231-dmu-1",
+ "clk-m-st231-aud",
+ "clk-m-st231-gp-0";
+ };
+
+ clk_m_a0_div2: clk-m-a0-div2 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf2",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a0_osc_prediv>,
+ <&clk_m_a0_pll0 2>, /* PLL0 PHI2 */
+ <&clk_m_a0_pll1 2>; /* PLL1 PHI2 */
+
+ clock-output-names = "clk-m-st231-gp-1",
+ "clk-m-icn-cpu",
+ "clk-m-icn-stac",
+ "clk-m-icn-dmu-0",
+ "clk-m-icn-dmu-1",
+ "", /* Unused */
+ "", /* Unused */
+ ""; /* Unused */
+ };
+
+ clk_m_a0_div3: clk-m-a0-div3 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf3",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a0_osc_prediv>,
+ <&clk_m_a0_pll0 3>, /* PLL0 PHI3 */
+ <&clk_m_a0_pll1 3>; /* PLL1 PHI3 */
+
+ clock-output-names = "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "clk-m-icn-eram",
+ "clk-m-a9-trace";
+ };
+ };
+
+ clockgen-a@fd6db000 {
+ reg = <0xfd6db000 0xb50>;
+
+ clk_m_a1_pll0: clk-m-a1-pll0 {
+ #clock-cells = <1>;
+ compatible = "st,plls-c32-a1x-0", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a1-pll0-phi0",
+ "clk-m-a1-pll0-phi1",
+ "clk-m-a1-pll0-phi2",
+ "clk-m-a1-pll0-phi3";
+ };
+
+ clk_m_a1_pll1: clk-m-a1-pll1 {
+ #clock-cells = <1>;
+ compatible = "st,plls-c32-a1x-1", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a1-pll1-phi0",
+ "clk-m-a1-pll1-phi1",
+ "clk-m-a1-pll1-phi2",
+ "clk-m-a1-pll1-phi3";
+ };
+
+ clk_m_a1_osc_prediv: clk-m-a1-osc-prediv {
+ #clock-cells = <0>;
+ compatible = "st,clkgena-prediv-c32",
+ "st,clkgena-prediv";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a1-osc-prediv";
+ };
+
+ clk_m_a1_div0: clk-m-a1-div0 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf0",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a1_osc_prediv>,
+ <&clk_m_a1_pll0 0>, /* PLL0 PHI0 */
+ <&clk_m_a1_pll1 0>; /* PLL1 PHI0 */
+
+ clock-output-names = "clk-m-fdma-12",
+ "clk-m-fdma-10",
+ "clk-m-fdma-11",
+ "clk-m-hva-lmi",
+ "clk-m-proc-sc",
+ "clk-m-tp",
+ "clk-m-icn-gpu",
+ "clk-m-icn-vdp-0";
+ };
+
+ clk_m_a1_div1: clk-m-a1-div1 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf1",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a1_osc_prediv>,
+ <&clk_m_a1_pll0 1>, /* PLL0 PHI1 */
+ <&clk_m_a1_pll1 1>; /* PLL1 PHI1 */
+
+ clock-output-names = "clk-m-icn-vdp-1",
+ "clk-m-icn-vdp-2",
+ "clk-m-icn-vdp-3",
+ "clk-m-prv-t1-bus",
+ "clk-m-icn-vdp-4",
+ "clk-m-icn-reg-10",
+ "", /* Unused */
+ ""; /* clk-m-icn-st231 */
+ };
+
+ clk_m_a1_div2: clk-m-a1-div2 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf2",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a1_osc_prediv>,
+ <&clk_m_a1_pll0 2>, /* PLL0 PHI2 */
+ <&clk_m_a1_pll1 2>; /* PLL1 PHI2 */
+
+ clock-output-names = "clk-m-fvdp-proc-alt",
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ ""; /* Unused */
+ };
+
+ clk_m_a1_div3: clk-m-a1-div3 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf3",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a1_osc_prediv>,
+ <&clk_m_a1_pll0 3>, /* PLL0 PHI3 */
+ <&clk_m_a1_pll1 3>; /* PLL1 PHI3 */
+
+ clock-output-names = "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ ""; /* Unused */
+ };
+ };
+
+ clk_m_a9_ext2f_div2: clk-m-a9-ext2f-div2 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&clk_m_a0_div1 2>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+
+ clockgen-a@fd345000 {
+ reg = <0xfd345000 0xb50>;
+
+ clk_m_a2_pll0: clk-m-a2-pll0 {
+ #clock-cells = <1>;
+ compatible = "st,plls-c32-a1x-0", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a2-pll0-phi0",
+ "clk-m-a2-pll0-phi1",
+ "clk-m-a2-pll0-phi2",
+ "clk-m-a2-pll0-phi3";
+ };
+
+ clk_m_a2_pll1: clk-m-a2-pll1 {
+ #clock-cells = <1>;
+ compatible = "st,plls-c32-a1x-1", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a2-pll1-phi0",
+ "clk-m-a2-pll1-phi1",
+ "clk-m-a2-pll1-phi2",
+ "clk-m-a2-pll1-phi3";
+ };
+
+ clk_m_a2_osc_prediv: clk-m-a2-osc-prediv {
+ #clock-cells = <0>;
+ compatible = "st,clkgena-prediv-c32",
+ "st,clkgena-prediv";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a2-osc-prediv";
+ };
+
+ clk_m_a2_div0: clk-m-a2-div0 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf0",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a2_osc_prediv>,
+ <&clk_m_a2_pll0 0>, /* PLL0 PHI0 */
+ <&clk_m_a2_pll1 0>; /* PLL1 PHI0 */
+
+ clock-output-names = "clk-m-vtac-main-phy",
+ "clk-m-vtac-aux-phy",
+ "clk-m-stac-phy",
+ "clk-m-stac-sys",
+ "", /* clk-m-mpestac-pg */
+ "", /* clk-m-mpestac-wc */
+ "", /* clk-m-mpevtacaux-pg*/
+ ""; /* clk-m-mpevtacmain-pg*/
+ };
+
+ clk_m_a2_div1: clk-m-a2-div1 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf1",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a2_osc_prediv>,
+ <&clk_m_a2_pll0 1>, /* PLL0 PHI1 */
+ <&clk_m_a2_pll1 1>; /* PLL1 PHI1 */
+
+ clock-output-names = "", /* clk-m-mpevtacrx0-wc */
+ "", /* clk-m-mpevtacrx1-wc */
+ "clk-m-compo-main",
+ "clk-m-compo-aux",
+ "clk-m-bdisp-0",
+ "clk-m-bdisp-1",
+ "clk-m-icn-bdisp-0",
+ "clk-m-icn-bdisp-1";
+ };
+
+ clk_m_a2_div2: clk-m-a2-div2 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf2",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a2_osc_prediv>,
+ <&clk_m_a2_pll0 2>, /* PLL0 PHI2 */
+ <&clk_m_a2_pll1 2>; /* PLL1 PHI2 */
+
+ clock-output-names = "", /* clk-m-icn-hqvdp0 */
+ "", /* clk-m-icn-hqvdp1 */
+ "clk-m-icn-compo",
+ "", /* clk-m-icn-vdpaux */
+ "clk-m-icn-ts",
+ "clk-m-icn-reg-lp-10",
+ "clk-m-dcephy-impctrl",
+ ""; /* Unused */
+ };
+
+ clk_m_a2_div3: clk-m-a2-div3 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf3",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a2_osc_prediv>,
+ <&clk_m_a2_pll0 3>, /* PLL0 PHI3 */
+ <&clk_m_a2_pll1 3>; /* PLL1 PHI3 */
+
+ clock-output-names = ""; /* Unused */
+ /* Remaining outputs unused */
+ };
+ };
+
+ /*
+ * A9 PLL
+ */
+ clockgen-a9@fdde00d8 {
+ reg = <0xfdde00d8 0x70>;
+
+ clockgen_a9_pll: clockgen-a9-pll {
+ #clock-cells = <1>;
+ compatible = "st,stih415-plls-c32-a9", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+ clock-output-names = "clockgen-a9-pll-odf";
+ };
+ };
+
+ /*
+ * ARM CPU related clocks
+ */
+ clk_m_a9: clk-m-a9@fdde00d8 {
+ #clock-cells = <0>;
+ compatible = "st,stih415-clkgen-a9-mux", "st,clkgen-mux";
+ reg = <0xfdde00d8 0x4>;
+ clocks = <&clockgen_a9_pll 0>,
+ <&clockgen_a9_pll 0>,
+ <&clk_m_a0_div1 2>,
+ <&clk_m_a9_ext2f_div2>;
+ };
+
+ /*
+ * ARM Peripheral clock for timers
+ */
+ arm_periph_clk: clk-m-a9-periphs {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&clk_m_a9>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih415-pinctrl.dtsi b/arch/arm/boot/dts/stih415-pinctrl.dtsi
new file mode 100644
index 000000000..3791ad95d
--- /dev/null
+++ b/arch/arm/boot/dts/stih415-pinctrl.dtsi
@@ -0,0 +1,545 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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 "st-pincfg.h"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+/ {
+
+ aliases {
+ gpio0 = &pio0;
+ gpio1 = &pio1;
+ gpio2 = &pio2;
+ gpio3 = &pio3;
+ gpio4 = &pio4;
+ gpio5 = &pio5;
+ gpio6 = &pio6;
+ gpio7 = &pio7;
+ gpio8 = &pio8;
+ gpio9 = &pio9;
+ gpio10 = &pio10;
+ gpio11 = &pio11;
+ gpio12 = &pio12;
+ gpio13 = &pio13;
+ gpio14 = &pio14;
+ gpio15 = &pio15;
+ gpio16 = &pio16;
+ gpio17 = &pio17;
+ gpio18 = &pio18;
+ gpio19 = &pio100;
+ gpio20 = &pio101;
+ gpio21 = &pio102;
+ gpio22 = &pio103;
+ gpio23 = &pio104;
+ gpio24 = &pio105;
+ gpio25 = &pio106;
+ gpio26 = &pio107;
+ };
+
+ soc {
+ pin-controller-sbc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stih415-sbc-pinctrl";
+ st,syscfg = <&syscfg_sbc>;
+ reg = <0xfe61f080 0x4>;
+ reg-names = "irqmux";
+ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irqmux";
+ ranges = <0 0xfe610000 0x5000>;
+
+ pio0: gpio@fe610000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0 0x100>;
+ st,bank-name = "PIO0";
+ };
+ pio1: gpio@fe611000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1000 0x100>;
+ st,bank-name = "PIO1";
+ };
+ pio2: gpio@fe612000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x2000 0x100>;
+ st,bank-name = "PIO2";
+ };
+ pio3: gpio@fe613000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x3000 0x100>;
+ st,bank-name = "PIO3";
+ };
+ pio4: gpio@fe614000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x4000 0x100>;
+ st,bank-name = "PIO4";
+ };
+
+ sbc_serial1 {
+ pinctrl_sbc_serial1:sbc_serial1 {
+ st,pins {
+ tx = <&pio2 6 ALT3 OUT>;
+ rx = <&pio2 7 ALT3 IN>;
+ };
+ };
+ };
+
+ keyscan {
+ pinctrl_keyscan: keyscan {
+ st,pins {
+ keyin0 = <&pio0 2 ALT2 IN>;
+ keyin1 = <&pio0 3 ALT2 IN>;
+ keyin2 = <&pio0 4 ALT2 IN>;
+ keyin3 = <&pio2 6 ALT2 IN>;
+
+ keyout0 = <&pio1 6 ALT2 OUT>;
+ keyout1 = <&pio1 7 ALT2 OUT>;
+ keyout2 = <&pio0 6 ALT2 OUT>;
+ keyout3 = <&pio2 7 ALT2 OUT>;
+ };
+ };
+ };
+
+ sbc_i2c0 {
+ pinctrl_sbc_i2c0_default: sbc_i2c0-default {
+ st,pins {
+ sda = <&pio4 6 ALT1 BIDIR>;
+ scl = <&pio4 5 ALT1 BIDIR>;
+ };
+ };
+ };
+
+ sbc_i2c1 {
+ pinctrl_sbc_i2c1_default: sbc_i2c1-default {
+ st,pins {
+ sda = <&pio3 2 ALT2 BIDIR>;
+ scl = <&pio3 1 ALT2 BIDIR>;
+ };
+ };
+ };
+
+ rc{
+ pinctrl_ir: ir0 {
+ st,pins {
+ ir = <&pio4 0 ALT2 IN>;
+ };
+ };
+ };
+
+ gmac1 {
+ pinctrl_mii1: mii1 {
+ st,pins {
+ txd0 = <&pio0 0 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txd1 = <&pio0 1 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txd2 = <&pio0 2 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txd3 = <&pio0 3 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txer = <&pio0 4 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txen = <&pio0 5 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txclk = <&pio0 6 ALT1 IN NICLK 0 CLK_A>;
+ col = <&pio0 7 ALT1 IN BYPASS 1000>;
+ mdio = <&pio1 0 ALT1 OUT BYPASS 0>;
+ mdc = <&pio1 1 ALT1 OUT NICLK 0 CLK_A>;
+ crs = <&pio1 2 ALT1 IN BYPASS 1000>;
+ mdint = <&pio1 3 ALT1 IN BYPASS 0>;
+ rxd0 = <&pio1 4 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ rxd1 = <&pio1 5 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ rxd2 = <&pio1 6 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ rxd3 = <&pio1 7 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ rxdv = <&pio2 0 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ rx_er = <&pio2 1 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ rxclk = <&pio2 2 ALT1 IN NICLK 0 CLK_A>;
+ phyclk = <&pio2 3 ALT1 IN NICLK 1000 CLK_A>;
+ };
+ };
+
+ pinctrl_rgmii1: rgmii1-0 {
+ st,pins {
+ txd0 = <&pio0 0 ALT1 OUT DE_IO 1000 CLK_A>;
+ txd1 = <&pio0 1 ALT1 OUT DE_IO 1000 CLK_A>;
+ txd2 = <&pio0 2 ALT1 OUT DE_IO 1000 CLK_A>;
+ txd3 = <&pio0 3 ALT1 OUT DE_IO 1000 CLK_A>;
+ txen = <&pio0 5 ALT1 OUT DE_IO 0 CLK_A>;
+ txclk = <&pio0 6 ALT1 IN NICLK 0 CLK_A>;
+ mdio = <&pio1 0 ALT1 OUT BYPASS 0>;
+ mdc = <&pio1 1 ALT1 OUT NICLK 0 CLK_A>;
+ rxd0 = <&pio1 4 ALT1 IN DE_IO 0 CLK_A>;
+ rxd1 = <&pio1 5 ALT1 IN DE_IO 0 CLK_A>;
+ rxd2 = <&pio1 6 ALT1 IN DE_IO 0 CLK_A>;
+ rxd3 = <&pio1 7 ALT1 IN DE_IO 0 CLK_A>;
+
+ rxdv = <&pio2 0 ALT1 IN DE_IO 500 CLK_A>;
+ rxclk = <&pio2 2 ALT1 IN NICLK 0 CLK_A>;
+ phyclk = <&pio2 3 ALT4 OUT NICLK 0 CLK_B>;
+
+ clk125= <&pio3 7 ALT4 IN NICLK 0 CLK_A>;
+ };
+ };
+ };
+ };
+
+ pin-controller-front {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stih415-front-pinctrl";
+ st,syscfg = <&syscfg_front>;
+ reg = <0xfee0f080 0x4>;
+ reg-names = "irqmux";
+ interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irqmux";
+ ranges = <0 0xfee00000 0x8000>;
+
+ pio5: gpio@fee00000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0 0x100>;
+ st,bank-name = "PIO5";
+ };
+ pio6: gpio@fee01000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1000 0x100>;
+ st,bank-name = "PIO6";
+ };
+ pio7: gpio@fee02000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x2000 0x100>;
+ st,bank-name = "PIO7";
+ };
+ pio8: gpio@fee03000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x3000 0x100>;
+ st,bank-name = "PIO8";
+ };
+ pio9: gpio@fee04000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x4000 0x100>;
+ st,bank-name = "PIO9";
+ };
+ pio10: gpio@fee05000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x5000 0x100>;
+ st,bank-name = "PIO10";
+ };
+ pio11: gpio@fee06000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x6000 0x100>;
+ st,bank-name = "PIO11";
+ };
+ pio12: gpio@fee07000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x7000 0x100>;
+ st,bank-name = "PIO12";
+ };
+
+ i2c0 {
+ pinctrl_i2c0_default: i2c0-default {
+ st,pins {
+ sda = <&pio9 3 ALT1 BIDIR>;
+ scl = <&pio9 2 ALT1 BIDIR>;
+ };
+ };
+ };
+
+ i2c1 {
+ pinctrl_i2c1_default: i2c1-default {
+ st,pins {
+ sda = <&pio12 1 ALT1 BIDIR>;
+ scl = <&pio12 0 ALT1 BIDIR>;
+ };
+ };
+ };
+ };
+
+ pin-controller-rear {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stih415-rear-pinctrl";
+ st,syscfg = <&syscfg_rear>;
+ reg = <0xfe82f080 0x4>;
+ reg-names = "irqmux";
+ interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irqmux";
+ ranges = <0 0xfe820000 0x8000>;
+
+ pio13: gpio@fe820000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0 0x100>;
+ st,bank-name = "PIO13";
+ };
+ pio14: gpio@fe821000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1000 0x100>;
+ st,bank-name = "PIO14";
+ };
+ pio15: gpio@fe822000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x2000 0x100>;
+ st,bank-name = "PIO15";
+ };
+ pio16: gpio@fe823000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x3000 0x100>;
+ st,bank-name = "PIO16";
+ };
+ pio17: gpio@fe824000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x4000 0x100>;
+ st,bank-name = "PIO17";
+ };
+ pio18: gpio@fe825000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x5000 0x100>;
+ st,bank-name = "PIO18";
+ };
+
+ serial2 {
+ pinctrl_serial2: serial2-0 {
+ st,pins {
+ tx = <&pio17 4 ALT2 OUT>;
+ rx = <&pio17 5 ALT2 IN>;
+ };
+ };
+ };
+
+ gmac0{
+ pinctrl_mii0: mii0 {
+ st,pins {
+ mdint = <&pio13 6 ALT2 IN BYPASS 0>;
+ txen = <&pio13 7 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
+
+ txd0 = <&pio14 0 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
+ txd1 = <&pio14 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
+ txd2 = <&pio14 2 ALT2 OUT SE_NICLK_IO 0 CLK_B>;
+ txd3 = <&pio14 3 ALT2 OUT SE_NICLK_IO 0 CLK_B>;
+
+ txclk = <&pio15 0 ALT2 IN NICLK 0 CLK_A>;
+ txer = <&pio15 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
+ crs = <&pio15 2 ALT2 IN BYPASS 1000>;
+ col = <&pio15 3 ALT2 IN BYPASS 1000>;
+ mdio = <&pio15 4 ALT2 OUT BYPASS 3000>;
+ mdc = <&pio15 5 ALT2 OUT NICLK 0 CLK_B>;
+
+ rxd0 = <&pio16 0 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+ rxd1 = <&pio16 1 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+ rxd2 = <&pio16 2 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+ rxd3 = <&pio16 3 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+ rxdv = <&pio15 6 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+ rx_er = <&pio15 7 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+ rxclk = <&pio17 0 ALT2 IN NICLK 0 CLK_A>;
+ phyclk = <&pio13 5 ALT2 OUT NICLK 1000 CLK_A>;
+
+ };
+ };
+
+ pinctrl_gmii0: gmii0 {
+ st,pins {
+ mdint = <&pio13 6 ALT2 IN BYPASS 0>;
+ mdio = <&pio15 4 ALT2 OUT BYPASS 3000>;
+ mdc = <&pio15 5 ALT2 OUT NICLK 0 CLK_B>;
+ txen = <&pio13 7 ALT2 OUT SE_NICLK_IO 3000 CLK_A>;
+
+ txd0 = <&pio14 0 ALT2 OUT SE_NICLK_IO 3000 CLK_A>;
+ txd1 = <&pio14 1 ALT2 OUT SE_NICLK_IO 3000 CLK_A>;
+ txd2 = <&pio14 2 ALT2 OUT SE_NICLK_IO 3000 CLK_B>;
+ txd3 = <&pio14 3 ALT2 OUT SE_NICLK_IO 3000 CLK_B>;
+ txd4 = <&pio14 4 ALT2 OUT SE_NICLK_IO 3000 CLK_B>;
+ txd5 = <&pio14 5 ALT2 OUT SE_NICLK_IO 3000 CLK_B>;
+ txd6 = <&pio14 6 ALT2 OUT SE_NICLK_IO 3000 CLK_B>;
+ txd7 = <&pio14 7 ALT2 OUT SE_NICLK_IO 3000 CLK_B>;
+
+ txclk = <&pio15 0 ALT2 IN NICLK 0 CLK_A>;
+ txer = <&pio15 1 ALT2 OUT SE_NICLK_IO 3000 CLK_A>;
+ crs = <&pio15 2 ALT2 IN BYPASS 1000>;
+ col = <&pio15 3 ALT2 IN BYPASS 1000>;
+ rxdv = <&pio15 6 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
+ rx_er = <&pio15 7 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
+
+ rxd0 = <&pio16 0 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
+ rxd1 = <&pio16 1 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
+ rxd2 = <&pio16 2 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
+ rxd3 = <&pio16 3 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
+ rxd4 = <&pio16 4 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
+ rxd5 = <&pio16 5 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
+ rxd6 = <&pio16 6 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
+ rxd7 = <&pio16 7 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
+
+ rxclk = <&pio17 0 ALT2 IN NICLK 0 CLK_A>;
+ clk125 = <&pio17 6 ALT1 IN NICLK 0 CLK_A>;
+ phyclk = <&pio13 5 ALT4 OUT NICLK 0 CLK_B>;
+
+
+ };
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0: mmc0 {
+ st,pins {
+ mmcclk = <&pio13 4 ALT4 BIDIR_PU NICLK 0 CLK_B>;
+ data0 = <&pio14 4 ALT4 BIDIR_PU BYPASS 0>;
+ data1 = <&pio14 5 ALT4 BIDIR_PU BYPASS 0>;
+ data2 = <&pio14 6 ALT4 BIDIR_PU BYPASS 0>;
+ data3 = <&pio14 7 ALT4 BIDIR_PU BYPASS 0>;
+ cmd = <&pio15 1 ALT4 BIDIR_PU BYPASS 0>;
+ wp = <&pio15 3 ALT4 IN>;
+ data4 = <&pio16 4 ALT4 BIDIR_PU BYPASS 0>;
+ data5 = <&pio16 5 ALT4 BIDIR_PU BYPASS 0>;
+ data6 = <&pio16 6 ALT4 BIDIR_PU BYPASS 0>;
+ data7 = <&pio16 7 ALT4 BIDIR_PU BYPASS 0>;
+ pwr = <&pio17 1 ALT4 OUT>;
+ cd = <&pio17 2 ALT4 IN>;
+ led = <&pio17 3 ALT4 OUT>;
+ };
+ };
+ };
+ };
+
+ pin-controller-left {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stih415-left-pinctrl";
+ st,syscfg = <&syscfg_left>;
+ reg = <0xfd6bf080 0x4>;
+ reg-names = "irqmux";
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irqmux";
+ ranges = <0 0xfd6b0000 0x3000>;
+
+ pio100: gpio@fd6b0000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0 0x100>;
+ st,bank-name = "PIO100";
+ };
+ pio101: gpio@fd6b1000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1000 0x100>;
+ st,bank-name = "PIO101";
+ };
+ pio102: gpio@fd6b2000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x2000 0x100>;
+ st,bank-name = "PIO102";
+ };
+ };
+
+ pin-controller-right {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stih415-right-pinctrl";
+ st,syscfg = <&syscfg_right>;
+ reg = <0xfd33f080 0x4>;
+ reg-names = "irqmux";
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irqmux";
+ ranges = <0 0xfd330000 0x5000>;
+
+ pio103: gpio@fd330000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0 0x100>;
+ st,bank-name = "PIO103";
+ };
+ pio104: gpio@fd331000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1000 0x100>;
+ st,bank-name = "PIO104";
+ };
+ pio105: gpio@fd332000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x2000 0x100>;
+ st,bank-name = "PIO105";
+ };
+ pio106: gpio@fd333000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x3000 0x100>;
+ st,bank-name = "PIO106";
+ };
+ pio107: gpio@fd334000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x4000 0x100>;
+ st,bank-name = "PIO107";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih415.dtsi b/arch/arm/boot/dts/stih415.dtsi
new file mode 100644
index 000000000..19b019b5f
--- /dev/null
+++ b/arch/arm/boot/dts/stih415.dtsi
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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 "stih41x.dtsi"
+#include "stih415-clock.dtsi"
+#include "stih415-pinctrl.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset-controller/stih415-resets.h>
+/ {
+
+ L2: cache-controller {
+ compatible = "arm,pl310-cache";
+ reg = <0xfffe2000 0x1000>;
+ arm,data-latency = <3 2 2>;
+ arm,tag-latency = <1 1 1>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&intc>;
+ ranges;
+ compatible = "simple-bus";
+
+ powerdown: powerdown-controller {
+ #reset-cells = <1>;
+ compatible = "st,stih415-powerdown";
+ };
+
+ softreset: softreset-controller {
+ #reset-cells = <1>;
+ compatible = "st,stih415-softreset";
+ };
+
+ syscfg_sbc: sbc-syscfg@fe600000{
+ compatible = "st,stih415-sbc-syscfg", "syscon";
+ reg = <0xfe600000 0xb4>;
+ };
+
+ syscfg_front: front-syscfg@fee10000{
+ compatible = "st,stih415-front-syscfg", "syscon";
+ reg = <0xfee10000 0x194>;
+ };
+
+ syscfg_rear: rear-syscfg@fe830000{
+ compatible = "st,stih415-rear-syscfg", "syscon";
+ reg = <0xfe830000 0x190>;
+ };
+
+ /* MPE syscfgs */
+ syscfg_left: left-syscfg@fd690000{
+ compatible = "st,stih415-left-syscfg", "syscon";
+ reg = <0xfd690000 0x78>;
+ };
+
+ syscfg_right: right-syscfg@fd320000{
+ compatible = "st,stih415-right-syscfg", "syscon";
+ reg = <0xfd320000 0x180>;
+ };
+
+ syscfg_system: system-syscfg@fdde0000 {
+ compatible = "st,stih415-system-syscfg", "syscon";
+ reg = <0xfdde0000 0x15c>;
+ };
+
+ syscfg_lpm: lpm-syscfg@fe4b5100{
+ compatible = "st,stih415-lpm-syscfg", "syscon";
+ reg = <0xfe4b5100 0x08>;
+ };
+
+ serial2: serial@fed32000 {
+ compatible = "st,asc";
+ status = "disabled";
+ reg = <0xfed32000 0x2c>;
+ interrupts = <0 197 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_serial2>;
+ clocks = <&clk_s_a0_ls CLK_ICN_REG>;
+ };
+
+ /* SBC comms block ASCs in SASG1 */
+ sbc_serial1: serial@fe531000 {
+ compatible = "st,asc";
+ status = "disabled";
+ reg = <0xfe531000 0x2c>;
+ interrupts = <0 210 0>;
+ clocks = <&clk_sysin>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sbc_serial1>;
+ };
+
+ i2c@fed40000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0xfed40000 0x110>;
+ interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_s_a0_ls CLK_ICN_REG>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_default>;
+
+ status = "disabled";
+ };
+
+ i2c@fed41000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0xfed41000 0x110>;
+ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_s_a0_ls CLK_ICN_REG>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1_default>;
+
+ status = "disabled";
+ };
+
+ i2c@fe540000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0xfe540000 0x110>;
+ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_sysin>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sbc_i2c0_default>;
+
+ status = "disabled";
+ };
+
+ i2c@fe541000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0xfe541000 0x110>;
+ interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_sysin>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sbc_i2c1_default>;
+
+ status = "disabled";
+ };
+
+ ethernet0: dwmac@fe810000 {
+ device_type = "network";
+ compatible = "st,stih415-dwmac", "snps,dwmac", "snps,dwmac-3.610";
+ status = "disabled";
+
+ reg = <0xfe810000 0x8000>;
+ reg-names = "stmmaceth";
+
+ interrupts = <0 147 0>, <0 148 0>, <0 149 0>;
+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+ resets = <&softreset STIH415_ETH0_SOFTRESET>;
+ reset-names = "stmmaceth";
+
+ snps,pbl = <32>;
+ snps,mixed-burst;
+ snps,force_sf_dma_mode;
+
+ st,syscon = <&syscfg_rear 0x148>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mii0>;
+ clock-names = "stmmaceth", "sti-ethclk";
+ clocks = <&clk_s_a1_ls CLK_ICN_IF_2>, <&clk_s_a1_ls CLK_GMAC0_PHY>;
+ };
+
+ ethernet1: dwmac@fef08000 {
+ device_type = "network";
+ compatible = "st,stih415-dwmac", "snps,dwmac", "snps,dwmac-3.610";
+ status = "disabled";
+ reg = <0xfef08000 0x8000>;
+ reg-names = "stmmaceth";
+ interrupts = <0 150 0>, <0 151 0>, <0 152 0>;
+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+
+ snps,pbl = <32>;
+ snps,mixed-burst;
+ snps,force_sf_dma_mode;
+
+ st,syscon = <&syscfg_sbc 0x74>;
+
+ resets = <&softreset STIH415_ETH1_SOFTRESET>;
+ reset-names = "stmmaceth";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mii1>;
+ clock-names = "stmmaceth", "sti-ethclk";
+ clocks = <&clk_s_a0_ls CLK_ICN_REG>, <&clk_s_a0_ls CLK_ETH1_PHY>;
+ };
+
+ rc: rc@fe518000 {
+ compatible = "st,comms-irb";
+ reg = <0xfe518000 0x234>;
+ interrupts = <0 203 0>;
+ clocks = <&clk_sysin>;
+ rx-mode = "infrared";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ir>;
+ resets = <&softreset STIH415_IRB_SOFTRESET>;
+ };
+
+ keyscan: keyscan@fe4b0000 {
+ compatible = "st,sti-keyscan";
+ status = "disabled";
+ reg = <0xfe4b0000 0x2000>;
+ interrupts = <GIC_SPI 212 IRQ_TYPE_NONE>;
+ clocks = <&clk_sysin>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_keyscan>;
+ resets = <&powerdown STIH415_KEYSCAN_POWERDOWN>,
+ <&softreset STIH415_KEYSCAN_SOFTRESET>;
+ };
+
+ mmc0: sdhci@fe81e000 {
+ compatible = "st,sdhci";
+ status = "disabled";
+ reg = <0xfe81e000 0x1000>;
+ interrupts = <GIC_SPI 145 IRQ_TYPE_NONE>;
+ interrupt-names = "mmcirq";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc0>;
+ clock-names = "mmc";
+ clocks = <&clk_s_a1_ls 1>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih416-b2000.dts b/arch/arm/boot/dts/stih416-b2000.dts
new file mode 100644
index 000000000..488e80a5d
--- /dev/null
+++ b/arch/arm/boot/dts/stih416-b2000.dts
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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.
+ */
+/dts-v1/;
+#include "stih416.dtsi"
+#include "stih41x-b2000.dtsi"
+/ {
+ model = "STiH416 B2000";
+ compatible = "st,stih416-b2000", "st,stih416";
+};
diff --git a/arch/arm/boot/dts/stih416-b2020.dts b/arch/arm/boot/dts/stih416-b2020.dts
new file mode 100644
index 000000000..200a81844
--- /dev/null
+++ b/arch/arm/boot/dts/stih416-b2020.dts
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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.
+ */
+/dts-v1/;
+#include "stih416.dtsi"
+#include "stih41x-b2020.dtsi"
+/ {
+ model = "STiH416 B2020";
+ compatible = "st,stih416-b2020", "st,stih416";
+
+ soc {
+ mmc1: sdhci@fe81f000 {
+ status = "okay";
+ bus-width = <8>;
+ non-removable;
+ };
+
+ miphy365x_phy: phy@fe382000 {
+ phy_port0: port@fe382000 {
+ st,sata-gen = <3>;
+ };
+
+ phy_port1: port@fe38a000 {
+ st,pcie-tx-pol-inv;
+ };
+ };
+
+ sata0: sata@fe380000{
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih416-b2020e.dts b/arch/arm/boot/dts/stih416-b2020e.dts
new file mode 100644
index 000000000..961799e1d
--- /dev/null
+++ b/arch/arm/boot/dts/stih416-b2020e.dts
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics (R&D) Limited.
+ * Author: Lee Jones <lee.jones@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
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih416.dtsi"
+#include "stih41x-b2020.dtsi"
+/ {
+ model = "STiH416 B2020 REV-E";
+ compatible = "st,stih416-b2020", "st,stih416";
+
+ soc {
+ leds {
+ compatible = "gpio-leds";
+ red {
+ #gpio-cells = <1>;
+ label = "Front Panel LED";
+ gpios = <&pio4 1>;
+ linux,default-trigger = "heartbeat";
+ };
+ green {
+ gpios = <&pio1 3>;
+ default-state = "off";
+ };
+ };
+
+ ethernet1: dwmac@fef08000 {
+ snps,reset-gpio = <&pio0 7>;
+ };
+
+ mmc1: sdhci@fe81f000 {
+ status = "okay";
+ bus-width = <8>;
+ non-removable;
+ };
+
+ miphy365x_phy: phy@fe382000 {
+ phy_port0: port@fe382000 {
+ st,sata-gen = <3>;
+ };
+
+ phy_port1: port@fe38a000 {
+ st,pcie-tx-pol-inv;
+ };
+ };
+
+ sata0: sata@fe380000{
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih416-clock.dtsi b/arch/arm/boot/dts/stih416-clock.dtsi
new file mode 100644
index 000000000..5b4fb838c
--- /dev/null
+++ b/arch/arm/boot/dts/stih416-clock.dtsi
@@ -0,0 +1,756 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics R&D Limited
+ * <stlinux-devel@stlinux.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 <dt-bindings/clock/stih416-clks.h>
+
+/ {
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /*
+ * Fixed 30MHz oscillator inputs to SoC
+ */
+ clk_sysin: clk-sysin {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <30000000>;
+ };
+
+ /*
+ * ClockGenAs on SASG2
+ */
+ clockgen-a@fee62000 {
+ reg = <0xfee62000 0xb48>;
+
+ clk_s_a0_pll: clk-s-a0-pll {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-plls-c65";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-a0-pll0-hs",
+ "clk-s-a0-pll0-ls",
+ "clk-s-a0-pll1";
+ };
+
+ clk_s_a0_osc_prediv: clk-s-a0-osc-prediv {
+ #clock-cells = <0>;
+ compatible = "st,clkgena-prediv-c65",
+ "st,clkgena-prediv";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-a0-osc-prediv";
+ };
+
+ clk_s_a0_hs: clk-s-a0-hs {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c65-hs",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_s_a0_osc_prediv>,
+ <&clk_s_a0_pll 0>, /* PLL0 HS */
+ <&clk_s_a0_pll 2>; /* PLL1 */
+
+ clock-output-names = "clk-s-fdma-0",
+ "clk-s-fdma-1",
+ ""; /* clk-s-jit-sense */
+ /* Fourth output unused */
+ };
+
+ clk_s_a0_ls: clk-s-a0-ls {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c65-ls",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_s_a0_osc_prediv>,
+ <&clk_s_a0_pll 1>, /* PLL0 LS */
+ <&clk_s_a0_pll 2>; /* PLL1 */
+
+ clock-output-names = "clk-s-icn-reg-0",
+ "clk-s-icn-if-0",
+ "clk-s-icn-reg-lp-0",
+ "clk-s-emiss",
+ "clk-s-eth1-phy",
+ "clk-s-mii-ref-out";
+ /* Remaining outputs unused */
+ };
+ };
+
+ clockgen-a@fee81000 {
+ reg = <0xfee81000 0xb48>;
+
+ clk_s_a1_pll: clk-s-a1-pll {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-plls-c65";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-a1-pll0-hs",
+ "clk-s-a1-pll0-ls",
+ "clk-s-a1-pll1";
+ };
+
+ clk_s_a1_osc_prediv: clk-s-a1-osc-prediv {
+ #clock-cells = <0>;
+ compatible = "st,clkgena-prediv-c65",
+ "st,clkgena-prediv";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-a1-osc-prediv";
+ };
+
+ clk_s_a1_hs: clk-s-a1-hs {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c65-hs",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_s_a1_osc_prediv>,
+ <&clk_s_a1_pll 0>, /* PLL0 HS */
+ <&clk_s_a1_pll 2>; /* PLL1 */
+
+ clock-output-names = "", /* Reserved */
+ "", /* Reserved */
+ "clk-s-stac-phy",
+ "clk-s-vtac-tx-phy";
+ };
+
+ clk_s_a1_ls: clk-s-a1-ls {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c65-ls",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_s_a1_osc_prediv>,
+ <&clk_s_a1_pll 1>, /* PLL0 LS */
+ <&clk_s_a1_pll 2>; /* PLL1 */
+
+ clock-output-names = "clk-s-icn-if-2",
+ "clk-s-card-mmc-0",
+ "clk-s-icn-if-1",
+ "clk-s-gmac0-phy",
+ "clk-s-nand-ctrl",
+ "", /* Reserved */
+ "clk-s-mii0-ref-out",
+ "clk-s-stac-sys",
+ "clk-s-card-mmc-1";
+ /* Remaining outputs unused */
+ };
+ };
+
+ /*
+ * ClockGenAs on MPE42
+ */
+ clockgen-a@fde12000 {
+ reg = <0xfde12000 0xb50>;
+
+ clk_m_a0_pll0: clk-m-a0-pll0 {
+ #clock-cells = <1>;
+ compatible = "st,plls-c32-a1x-0", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a0-pll0-phi0",
+ "clk-m-a0-pll0-phi1",
+ "clk-m-a0-pll0-phi2",
+ "clk-m-a0-pll0-phi3";
+ };
+
+ clk_m_a0_pll1: clk-m-a0-pll1 {
+ #clock-cells = <1>;
+ compatible = "st,plls-c32-a1x-1", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a0-pll1-phi0",
+ "clk-m-a0-pll1-phi1",
+ "clk-m-a0-pll1-phi2",
+ "clk-m-a0-pll1-phi3";
+ };
+
+ clk_m_a0_osc_prediv: clk-m-a0-osc-prediv {
+ #clock-cells = <0>;
+ compatible = "st,clkgena-prediv-c32",
+ "st,clkgena-prediv";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a0-osc-prediv";
+ };
+
+ clk_m_a0_div0: clk-m-a0-div0 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf0",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a0_osc_prediv>,
+ <&clk_m_a0_pll0 0>, /* PLL0 PHI0 */
+ <&clk_m_a0_pll1 0>; /* PLL1 PHI0 */
+
+ clock-output-names = "", /* Unused */
+ "", /* Unused */
+ "clk-m-fdma-12",
+ "", /* Unused */
+ "clk-m-pp-dmu-0",
+ "clk-m-pp-dmu-1",
+ "clk-m-icm-lmi",
+ "clk-m-vid-dmu-0";
+ };
+
+ clk_m_a0_div1: clk-m-a0-div1 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf1",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a0_osc_prediv>,
+ <&clk_m_a0_pll0 1>, /* PLL0 PHI1 */
+ <&clk_m_a0_pll1 1>; /* PLL1 PHI1 */
+
+ clock-output-names = "clk-m-vid-dmu-1",
+ "", /* Unused */
+ "clk-m-a9-ext2f",
+ "clk-m-st40rt",
+ "clk-m-st231-dmu-0",
+ "clk-m-st231-dmu-1",
+ "clk-m-st231-aud",
+ "clk-m-st231-gp-0";
+ };
+
+ clk_m_a0_div2: clk-m-a0-div2 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf2",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a0_osc_prediv>,
+ <&clk_m_a0_pll0 2>, /* PLL0 PHI2 */
+ <&clk_m_a0_pll1 2>; /* PLL1 PHI2 */
+
+ clock-output-names = "clk-m-st231-gp-1",
+ "clk-m-icn-cpu",
+ "clk-m-icn-stac",
+ "clk-m-tx-icn-dmu-0",
+ "clk-m-tx-icn-dmu-1",
+ "clk-m-tx-icn-ts",
+ "clk-m-icn-vdp-0",
+ "clk-m-icn-vdp-1";
+ };
+
+ clk_m_a0_div3: clk-m-a0-div3 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf3",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a0_osc_prediv>,
+ <&clk_m_a0_pll0 3>, /* PLL0 PHI3 */
+ <&clk_m_a0_pll1 3>; /* PLL1 PHI3 */
+
+ clock-output-names = "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "clk-m-icn-vp8",
+ "", /* Unused */
+ "clk-m-icn-reg-11",
+ "clk-m-a9-trace";
+ };
+ };
+
+ clockgen-a@fd6db000 {
+ reg = <0xfd6db000 0xb50>;
+
+ clk_m_a1_pll0: clk-m-a1-pll0 {
+ #clock-cells = <1>;
+ compatible = "st,plls-c32-a1x-0", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a1-pll0-phi0",
+ "clk-m-a1-pll0-phi1",
+ "clk-m-a1-pll0-phi2",
+ "clk-m-a1-pll0-phi3";
+ };
+
+ clk_m_a1_pll1: clk-m-a1-pll1 {
+ #clock-cells = <1>;
+ compatible = "st,plls-c32-a1x-1", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a1-pll1-phi0",
+ "clk-m-a1-pll1-phi1",
+ "clk-m-a1-pll1-phi2",
+ "clk-m-a1-pll1-phi3";
+ };
+
+ clk_m_a1_osc_prediv: clk-m-a1-osc-prediv {
+ #clock-cells = <0>;
+ compatible = "st,clkgena-prediv-c32",
+ "st,clkgena-prediv";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a1-osc-prediv";
+ };
+
+ clk_m_a1_div0: clk-m-a1-div0 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf0",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a1_osc_prediv>,
+ <&clk_m_a1_pll0 0>, /* PLL0 PHI0 */
+ <&clk_m_a1_pll1 0>; /* PLL1 PHI0 */
+
+ clock-output-names = "", /* Unused */
+ "clk-m-fdma-10",
+ "clk-m-fdma-11",
+ "clk-m-hva-alt",
+ "clk-m-proc-sc",
+ "clk-m-tp",
+ "clk-m-rx-icn-dmu-0",
+ "clk-m-rx-icn-dmu-1";
+ };
+
+ clk_m_a1_div1: clk-m-a1-div1 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf1",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a1_osc_prediv>,
+ <&clk_m_a1_pll0 1>, /* PLL0 PHI1 */
+ <&clk_m_a1_pll1 1>; /* PLL1 PHI1 */
+
+ clock-output-names = "clk-m-rx-icn-ts",
+ "clk-m-rx-icn-vdp-0",
+ "", /* Unused */
+ "clk-m-prv-t1-bus",
+ "clk-m-icn-reg-12",
+ "clk-m-icn-reg-10",
+ "", /* Unused */
+ "clk-m-icn-st231";
+ };
+
+ clk_m_a1_div2: clk-m-a1-div2 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf2",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a1_osc_prediv>,
+ <&clk_m_a1_pll0 2>, /* PLL0 PHI2 */
+ <&clk_m_a1_pll1 2>; /* PLL1 PHI2 */
+
+ clock-output-names = "clk-m-fvdp-proc-alt",
+ "clk-m-icn-reg-13",
+ "clk-m-tx-icn-gpu",
+ "clk-m-rx-icn-gpu",
+ "", /* Unused */
+ "", /* Unused */
+ "", /* clk-m-apb-pm-12 */
+ ""; /* Unused */
+ };
+
+ clk_m_a1_div3: clk-m-a1-div3 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf3",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a1_osc_prediv>,
+ <&clk_m_a1_pll0 3>, /* PLL0 PHI3 */
+ <&clk_m_a1_pll1 3>; /* PLL1 PHI3 */
+
+ clock-output-names = "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ "", /* Unused */
+ ""; /* clk-m-gpu-alt */
+ };
+ };
+
+ clk_m_a9_ext2f_div2: clk-m-a9-ext2f-div2 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&clk_m_a0_div1 2>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+
+ clockgen-a@fd345000 {
+ reg = <0xfd345000 0xb50>;
+
+ clk_m_a2_pll0: clk-m-a2-pll0 {
+ #clock-cells = <1>;
+ compatible = "st,plls-c32-a1x-0", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a2-pll0-phi0",
+ "clk-m-a2-pll0-phi1",
+ "clk-m-a2-pll0-phi2",
+ "clk-m-a2-pll0-phi3";
+ };
+
+ clk_m_a2_pll1: clk-m-a2-pll1 {
+ #clock-cells = <1>;
+ compatible = "st,plls-c32-a1x-1", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a2-pll1-phi0",
+ "clk-m-a2-pll1-phi1",
+ "clk-m-a2-pll1-phi2",
+ "clk-m-a2-pll1-phi3";
+ };
+
+ clk_m_a2_osc_prediv: clk-m-a2-osc-prediv {
+ #clock-cells = <0>;
+ compatible = "st,clkgena-prediv-c32",
+ "st,clkgena-prediv";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-m-a2-osc-prediv";
+ };
+
+ clk_m_a2_div0: clk-m-a2-div0 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf0",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a2_osc_prediv>,
+ <&clk_m_a2_pll0 0>, /* PLL0 PHI0 */
+ <&clk_m_a2_pll1 0>; /* PLL1 PHI0 */
+
+ clock-output-names = "clk-m-vtac-main-phy",
+ "clk-m-vtac-aux-phy",
+ "clk-m-stac-phy",
+ "clk-m-stac-sys",
+ "", /* clk-m-mpestac-pg */
+ "", /* clk-m-mpestac-wc */
+ "", /* clk-m-mpevtacaux-pg*/
+ ""; /* clk-m-mpevtacmain-pg*/
+ };
+
+ clk_m_a2_div1: clk-m-a2-div1 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf1",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a2_osc_prediv>,
+ <&clk_m_a2_pll0 1>, /* PLL0 PHI1 */
+ <&clk_m_a2_pll1 1>; /* PLL1 PHI1 */
+
+ clock-output-names = "", /* clk-m-mpevtacrx0-wc */
+ "", /* clk-m-mpevtacrx1-wc */
+ "clk-m-compo-main",
+ "clk-m-compo-aux",
+ "clk-m-bdisp-0",
+ "clk-m-bdisp-1",
+ "clk-m-icn-bdisp",
+ "clk-m-icn-compo";
+ };
+
+ clk_m_a2_div2: clk-m-a2-div2 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf2",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a2_osc_prediv>,
+ <&clk_m_a2_pll0 2>, /* PLL0 PHI2 */
+ <&clk_m_a2_pll1 2>; /* PLL1 PHI2 */
+
+ clock-output-names = "clk-m-icn-vdp-2",
+ "", /* Unused */
+ "clk-m-icn-reg-14",
+ "clk-m-mdtp",
+ "clk-m-jpegdec",
+ "", /* Unused */
+ "clk-m-dcephy-impctrl",
+ ""; /* Unused */
+ };
+
+ clk_m_a2_div3: clk-m-a2-div3 {
+ #clock-cells = <1>;
+ compatible = "st,clkgena-divmux-c32-odf3",
+ "st,clkgena-divmux";
+
+ clocks = <&clk_m_a2_osc_prediv>,
+ <&clk_m_a2_pll0 3>, /* PLL0 PHI3 */
+ <&clk_m_a2_pll1 3>; /* PLL1 PHI3 */
+
+ clock-output-names = "", /* Unused */
+ ""; /* clk-m-apb-pm-11 */
+ /* Remaining outputs unused */
+ };
+ };
+
+ /*
+ * A9 PLL
+ */
+ clockgen-a9@fdde08b0 {
+ reg = <0xfdde08b0 0x70>;
+
+ clockgen_a9_pll: clockgen-a9-pll {
+ #clock-cells = <1>;
+ compatible = "st,stih416-plls-c32-a9", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+ clock-output-names = "clockgen-a9-pll-odf";
+ };
+ };
+
+ /*
+ * ARM CPU related clocks
+ */
+ clk_m_a9: clk-m-a9@fdde08ac {
+ #clock-cells = <0>;
+ compatible = "st,stih416-clkgen-a9-mux", "st,clkgen-mux";
+ reg = <0xfdde08ac 0x4>;
+ clocks = <&clockgen_a9_pll 0>,
+ <&clockgen_a9_pll 0>,
+ <&clk_m_a0_div1 2>,
+ <&clk_m_a9_ext2f_div2>;
+ };
+
+ /*
+ * ARM Peripheral clock for timers
+ */
+ arm_periph_clk: clk-m-a9-periphs {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&clk_m_a9>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+
+ /*
+ * Frequency synthesizers on the SASG2
+ */
+ clockgen_b0: clockgen-b0@fee108b4 {
+ #clock-cells = <1>;
+ compatible = "st,stih416-quadfs216", "st,quadfs";
+ reg = <0xfee108b4 0x44>;
+
+ clocks = <&clk_sysin>;
+ clock-output-names = "clk-s-usb48",
+ "clk-s-dss",
+ "clk-s-stfe-frc-2",
+ "clk-s-thsens-scard";
+ };
+
+ clockgen_b1: clockgen-b1@fe8308c4 {
+ #clock-cells = <1>;
+ compatible = "st,stih416-quadfs216", "st,quadfs";
+ reg = <0xfe8308c4 0x44>;
+
+ clocks = <&clk_sysin>;
+ clock-output-names = "clk-s-pcm-0",
+ "clk-s-pcm-1",
+ "clk-s-pcm-2",
+ "clk-s-pcm-3";
+ };
+
+ clockgen_c: clockgen-c@fe8307d0 {
+ #clock-cells = <1>;
+ compatible = "st,stih416-quadfs432", "st,quadfs";
+ reg = <0xfe8307d0 0x44>;
+
+ clocks = <&clk_sysin>;
+ clock-output-names = "clk-s-c-fs0-ch0",
+ "clk-s-c-vcc-sd",
+ "clk-s-c-fs0-ch2";
+ };
+
+ clk_s_vcc_hd: clk-s-vcc-hd@fe8308b8 {
+ #clock-cells = <0>;
+ compatible = "st,stih416-clkgenc-vcc-hd", "st,clkgen-mux";
+ reg = <0xfe8308b8 0x4>; /* SYSCFG2558 */
+
+ clocks = <&clk_sysin>,
+ <&clockgen_c 0>;
+ };
+
+ /*
+ * Add a dummy clock for the HDMI PHY for the VCC input mux
+ */
+ clk_s_tmds_fromphy: clk-s-tmds-fromphy {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ clockgen_c_vcc: clockgen-c-vcc@fe8308ac {
+ #clock-cells = <1>;
+ compatible = "st,stih416-clkgenc", "st,clkgen-vcc";
+ reg = <0xfe8308ac 0xc>; /* SYSCFG2555,2556,2557 */
+
+ clocks = <&clk_s_vcc_hd>,
+ <&clockgen_c 1>,
+ <&clk_s_tmds_fromphy>,
+ <&clockgen_c 2>;
+
+ clock-output-names = "clk-s-pix-hdmi",
+ "clk-s-pix-dvo",
+ "clk-s-out-dvo",
+ "clk-s-pix-hd",
+ "clk-s-hddac",
+ "clk-s-denc",
+ "clk-s-sddac",
+ "clk-s-pix-main",
+ "clk-s-pix-aux",
+ "clk-s-stfe-frc-0",
+ "clk-s-ref-mcru",
+ "clk-s-slave-mcru",
+ "clk-s-tmds-hdmi",
+ "clk-s-hdmi-reject-pll",
+ "clk-s-thsens";
+ };
+
+ clockgen_d: clockgen-d@fee107e0 {
+ #clock-cells = <1>;
+ compatible = "st,stih416-quadfs216", "st,quadfs";
+ reg = <0xfee107e0 0x44>;
+
+ clocks = <&clk_sysin>;
+ clock-output-names = "clk-s-ccsc",
+ "clk-s-stfe-frc-1",
+ "clk-s-tsout-1",
+ "clk-s-mchi";
+ };
+
+ /*
+ * Frequency synthesizers on the MPE42
+ */
+ clockgen_e: clockgen-e@fd3208bc {
+ #clock-cells = <1>;
+ compatible = "st,stih416-quadfs660-E", "st,quadfs";
+ reg = <0xfd3208bc 0xb0>;
+
+ clocks = <&clk_sysin>;
+ clock-output-names = "clk-m-pix-mdtp-0",
+ "clk-m-pix-mdtp-1",
+ "clk-m-pix-mdtp-2",
+ "clk-m-mpelpc";
+ };
+
+ clockgen_f: clockgen-f@fd320878 {
+ #clock-cells = <1>;
+ compatible = "st,stih416-quadfs660-F", "st,quadfs";
+ reg = <0xfd320878 0xf0>;
+
+ clocks = <&clk_sysin>;
+ clock-output-names = "clk-m-main-vidfs",
+ "clk-m-hva-fs",
+ "clk-m-fvdp-vcpu",
+ "clk-m-fvdp-proc-fs";
+ };
+
+ clk_m_fvdp_proc: clk-m-fvdp-proc@fd320910 {
+ #clock-cells = <0>;
+ compatible = "st,stih416-clkgenf-vcc-fvdp", "st,clkgen-mux";
+ reg = <0xfd320910 0x4>; /* SYSCFG8580 */
+
+ clocks = <&clk_m_a1_div2 0>,
+ <&clockgen_f 3>;
+ };
+
+ clk_m_hva: clk-m-hva@fd690868 {
+ #clock-cells = <0>;
+ compatible = "st,stih416-clkgenf-vcc-hva", "st,clkgen-mux";
+ reg = <0xfd690868 0x4>; /* SYSCFG9538 */
+
+ clocks = <&clockgen_f 1>,
+ <&clk_m_a1_div0 3>;
+ };
+
+ clk_m_f_vcc_hd: clk-m-f-vcc-hd@fd32086c {
+ #clock-cells = <0>;
+ compatible = "st,stih416-clkgenf-vcc-hd", "st,clkgen-mux";
+ reg = <0xfd32086c 0x4>; /* SYSCFG8539 */
+
+ clocks = <&clockgen_c_vcc 7>,
+ <&clockgen_f 0>;
+ };
+
+ clk_m_f_vcc_sd: clk-m-f-vcc-sd@fd32086c {
+ #clock-cells = <0>;
+ compatible = "st,stih416-clkgenf-vcc-sd", "st,clkgen-mux";
+ reg = <0xfd32086c 0x4>; /* SYSCFG8539 */
+
+ clocks = <&clockgen_c_vcc 8>,
+ <&clockgen_f 1>;
+ };
+
+ /*
+ * Add a dummy clock for the HDMIRx external signal clock
+ */
+ clk_m_pix_hdmirx_sas: clk-m-pix-hdmirx-sas {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ clockgen_f_vcc: clockgen-f-vcc@fd32086c {
+ #clock-cells = <1>;
+ compatible = "st,stih416-clkgenf", "st,clkgen-vcc";
+ reg = <0xfd32086c 0xc>; /* SYSCFG8539,8540,8541 */
+
+ clocks = <&clk_m_f_vcc_hd>,
+ <&clk_m_f_vcc_sd>,
+ <&clockgen_f 0>,
+ <&clk_m_pix_hdmirx_sas>;
+
+ clock-output-names = "clk-m-pix-main-pipe",
+ "clk-m-pix-aux-pipe",
+ "clk-m-pix-main-cru",
+ "clk-m-pix-aux-cru",
+ "clk-m-xfer-be-compo",
+ "clk-m-xfer-pip-compo",
+ "clk-m-xfer-aux-compo",
+ "clk-m-vsens",
+ "clk-m-pix-hdmirx-0",
+ "clk-m-pix-hdmirx-1";
+ };
+
+ /*
+ * DDR PLL
+ */
+ clockgen-ddr@0xfdde07d8 {
+ reg = <0xfdde07d8 0x110>;
+
+ clockgen_ddr_pll: clockgen-ddr-pll {
+ #clock-cells = <1>;
+ compatible = "st,stih416-plls-c32-ddr", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+ clock-output-names = "clockgen-ddr0",
+ "clockgen-ddr1";
+ };
+ };
+
+ /*
+ * GPU PLL
+ */
+ clockgen-gpu@fd68ff00 {
+ reg = <0xfd68ff00 0x910>;
+
+ clockgen_gpu_pll: clockgen-gpu-pll {
+ #clock-cells = <1>;
+ compatible = "st,stih416-gpu-pll-c32", "st,clkgengpu-pll-c32";
+
+ clocks = <&clk_sysin>;
+ clock-output-names = "clockgen-gpu-pll";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih416-pinctrl.dtsi b/arch/arm/boot/dts/stih416-pinctrl.dtsi
new file mode 100644
index 000000000..9cccf2d6a
--- /dev/null
+++ b/arch/arm/boot/dts/stih416-pinctrl.dtsi
@@ -0,0 +1,637 @@
+
+/*
+ * Copyright (C) 2013 STMicroelectronics Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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 "st-pincfg.h"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+/ {
+
+ aliases {
+ gpio0 = &pio0;
+ gpio1 = &pio1;
+ gpio2 = &pio2;
+ gpio3 = &pio3;
+ gpio4 = &pio4;
+ gpio5 = &pio40;
+ gpio6 = &pio5;
+ gpio7 = &pio6;
+ gpio8 = &pio7;
+ gpio9 = &pio8;
+ gpio10 = &pio9;
+ gpio11 = &pio10;
+ gpio12 = &pio11;
+ gpio13 = &pio12;
+ gpio14 = &pio30;
+ gpio15 = &pio31;
+ gpio16 = &pio13;
+ gpio17 = &pio14;
+ gpio18 = &pio15;
+ gpio19 = &pio16;
+ gpio20 = &pio17;
+ gpio21 = &pio18;
+ gpio22 = &pio100;
+ gpio23 = &pio101;
+ gpio24 = &pio102;
+ gpio25 = &pio103;
+ gpio26 = &pio104;
+ gpio27 = &pio105;
+ gpio28 = &pio106;
+ gpio29 = &pio107;
+ };
+
+ soc {
+ pin-controller-sbc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stih416-sbc-pinctrl";
+ st,syscfg = <&syscfg_sbc>;
+ reg = <0xfe61f080 0x4>;
+ reg-names = "irqmux";
+ interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irqmux";
+ ranges = <0 0xfe610000 0x6000>;
+
+ pio0: gpio@fe610000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0 0x100>;
+ st,bank-name = "PIO0";
+ };
+ pio1: gpio@fe611000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1000 0x100>;
+ st,bank-name = "PIO1";
+ };
+ pio2: gpio@fe612000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x2000 0x100>;
+ st,bank-name = "PIO2";
+ };
+ pio3: gpio@fe613000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x3000 0x100>;
+ st,bank-name = "PIO3";
+ };
+ pio4: gpio@fe614000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x4000 0x100>;
+ st,bank-name = "PIO4";
+ };
+ pio40: gpio@fe615000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x5000 0x100>;
+ st,bank-name = "PIO40";
+ st,retime-pin-mask = <0x7f>;
+ };
+
+ rc{
+ pinctrl_ir: ir0 {
+ st,pins {
+ ir = <&pio4 0 ALT2 IN>;
+ };
+ };
+ };
+ sbc_serial1 {
+ pinctrl_sbc_serial1: sbc_serial1 {
+ st,pins {
+ tx = <&pio2 6 ALT3 OUT>;
+ rx = <&pio2 7 ALT3 IN>;
+ };
+ };
+ };
+
+ keyscan {
+ pinctrl_keyscan: keyscan {
+ st,pins {
+ keyin0 = <&pio0 2 ALT2 IN>;
+ keyin1 = <&pio0 3 ALT2 IN>;
+ keyin2 = <&pio0 4 ALT2 IN>;
+ keyin3 = <&pio2 6 ALT2 IN>;
+
+ keyout0 = <&pio1 6 ALT2 OUT>;
+ keyout1 = <&pio1 7 ALT2 OUT>;
+ keyout2 = <&pio0 6 ALT2 OUT>;
+ keyout3 = <&pio2 7 ALT2 OUT>;
+ };
+ };
+ };
+
+ sbc_i2c0 {
+ pinctrl_sbc_i2c0_default: sbc_i2c0-default {
+ st,pins {
+ sda = <&pio4 6 ALT1 BIDIR>;
+ scl = <&pio4 5 ALT1 BIDIR>;
+ };
+ };
+ };
+
+ usb {
+ pinctrl_usb3: usb3 {
+ st,pins {
+ oc-detect = <&pio40 0 ALT1 IN>;
+ pwr-enable = <&pio40 1 ALT1 OUT>;
+ };
+ };
+ };
+
+ sbc_i2c1 {
+ pinctrl_sbc_i2c1_default: sbc_i2c1-default {
+ st,pins {
+ sda = <&pio3 2 ALT2 BIDIR>;
+ scl = <&pio3 1 ALT2 BIDIR>;
+ };
+ };
+ };
+
+ gmac1 {
+ pinctrl_mii1: mii1 {
+ st,pins {
+ txd0 = <&pio0 0 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txd1 = <&pio0 1 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txd2 = <&pio0 2 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txd3 = <&pio0 3 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txer = <&pio0 4 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txen = <&pio0 5 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txclk = <&pio0 6 ALT1 IN NICLK 0 CLK_A>;
+ col = <&pio0 7 ALT1 IN BYPASS 1000>;
+
+ mdio = <&pio1 0 ALT1 OUT BYPASS 1500>;
+ mdc = <&pio1 1 ALT1 OUT NICLK 0 CLK_A>;
+ crs = <&pio1 2 ALT1 IN BYPASS 1000>;
+ mdint = <&pio1 3 ALT1 IN BYPASS 0>;
+ rxd0 = <&pio1 4 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ rxd1 = <&pio1 5 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ rxd2 = <&pio1 6 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ rxd3 = <&pio1 7 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+
+ rxdv = <&pio2 0 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ rx_er = <&pio2 1 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ rxclk = <&pio2 2 ALT1 IN NICLK 0 CLK_A>;
+ phyclk = <&pio2 3 ALT1 OUT NICLK 0 CLK_A>;
+ };
+ };
+ pinctrl_rgmii1: rgmii1-0 {
+ st,pins {
+ txd0 = <&pio0 0 ALT1 OUT DE_IO 500 CLK_A>;
+ txd1 = <&pio0 1 ALT1 OUT DE_IO 500 CLK_A>;
+ txd2 = <&pio0 2 ALT1 OUT DE_IO 500 CLK_A>;
+ txd3 = <&pio0 3 ALT1 OUT DE_IO 500 CLK_A>;
+ txen = <&pio0 5 ALT1 OUT DE_IO 0 CLK_A>;
+ txclk = <&pio0 6 ALT1 IN NICLK 0 CLK_A>;
+
+ mdio = <&pio1 0 ALT1 OUT BYPASS 0>;
+ mdc = <&pio1 1 ALT1 OUT NICLK 0 CLK_A>;
+ rxd0 = <&pio1 4 ALT1 IN DE_IO 500 CLK_A>;
+ rxd1 = <&pio1 5 ALT1 IN DE_IO 500 CLK_A>;
+ rxd2 = <&pio1 6 ALT1 IN DE_IO 500 CLK_A>;
+ rxd3 = <&pio1 7 ALT1 IN DE_IO 500 CLK_A>;
+
+ rxdv = <&pio2 0 ALT1 IN DE_IO 500 CLK_A>;
+ rxclk = <&pio2 2 ALT1 IN NICLK 0 CLK_A>;
+ phyclk = <&pio2 3 ALT4 OUT NICLK 0 CLK_B>;
+
+ clk125= <&pio3 7 ALT4 IN NICLK 0 CLK_A>;
+ };
+ };
+ };
+ };
+
+ pin-controller-front {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stih416-front-pinctrl";
+ st,syscfg = <&syscfg_front>;
+ reg = <0xfee0f080 0x4>;
+ reg-names = "irqmux";
+ interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irqmux";
+ ranges = <0 0xfee00000 0x10000>;
+
+ pio5: gpio@fee00000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0 0x100>;
+ st,bank-name = "PIO5";
+ };
+ pio6: gpio@fee01000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1000 0x100>;
+ st,bank-name = "PIO6";
+ };
+ pio7: gpio@fee02000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x2000 0x100>;
+ st,bank-name = "PIO7";
+ };
+ pio8: gpio@fee03000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x3000 0x100>;
+ st,bank-name = "PIO8";
+ };
+ pio9: gpio@fee04000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x4000 0x100>;
+ st,bank-name = "PIO9";
+ };
+ pio10: gpio@fee05000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x5000 0x100>;
+ st,bank-name = "PIO10";
+ };
+ pio11: gpio@fee06000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x6000 0x100>;
+ st,bank-name = "PIO11";
+ };
+ pio12: gpio@fee07000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x7000 0x100>;
+ st,bank-name = "PIO12";
+ };
+ pio30: gpio@fee08000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x8000 0x100>;
+ st,bank-name = "PIO30";
+ };
+ pio31: gpio@fee09000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x9000 0x100>;
+ st,bank-name = "PIO31";
+ };
+
+ serial2-oe {
+ pinctrl_serial2_oe: serial2-1 {
+ st,pins {
+ output-enable = <&pio11 3 ALT2 OUT>;
+ };
+ };
+ };
+
+ i2c0 {
+ pinctrl_i2c0_default: i2c0-default {
+ st,pins {
+ sda = <&pio9 3 ALT1 BIDIR>;
+ scl = <&pio9 2 ALT1 BIDIR>;
+ };
+ };
+ };
+
+ usb {
+ pinctrl_usb0: usb0 {
+ st,pins {
+ oc-detect = <&pio9 4 ALT1 IN>;
+ pwr-enable = <&pio9 5 ALT1 OUT>;
+ };
+ };
+ };
+
+
+ i2c1 {
+ pinctrl_i2c1_default: i2c1-default {
+ st,pins {
+ sda = <&pio12 1 ALT1 BIDIR>;
+ scl = <&pio12 0 ALT1 BIDIR>;
+ };
+ };
+ };
+
+ fsm {
+ pinctrl_fsm: fsm {
+ st,pins {
+ spi-fsm-clk = <&pio12 2 ALT1 OUT>;
+ spi-fsm-cs = <&pio12 3 ALT1 OUT>;
+ spi-fsm-mosi = <&pio12 4 ALT1 OUT>;
+ spi-fsm-miso = <&pio12 5 ALT1 IN>;
+ spi-fsm-hol = <&pio12 6 ALT1 OUT>;
+ spi-fsm-wp = <&pio12 7 ALT1 OUT>;
+ };
+ };
+ };
+ };
+
+ pin-controller-rear {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stih416-rear-pinctrl";
+ st,syscfg = <&syscfg_rear>;
+ reg = <0xfe82f080 0x4>;
+ reg-names = "irqmux";
+ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irqmux";
+ ranges = <0 0xfe820000 0x6000>;
+
+ pio13: gpio@fe820000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0 0x100>;
+ st,bank-name = "PIO13";
+ };
+ pio14: gpio@fe821000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1000 0x100>;
+ st,bank-name = "PIO14";
+ };
+ pio15: gpio@fe822000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x2000 0x100>;
+ st,bank-name = "PIO15";
+ };
+ pio16: gpio@fe823000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x3000 0x100>;
+ st,bank-name = "PIO16";
+ };
+ pio17: gpio@fe824000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x4000 0x100>;
+ st,bank-name = "PIO17";
+ };
+ pio18: gpio@fe825000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x5000 0x100>;
+ st,bank-name = "PIO18";
+ st,retime-pin-mask = <0xf>;
+ };
+
+ serial2 {
+ pinctrl_serial2: serial2-0 {
+ st,pins {
+ tx = <&pio17 4 ALT2 OUT>;
+ rx = <&pio17 5 ALT2 IN>;
+ };
+ };
+ };
+
+ gmac0 {
+ pinctrl_mii0: mii0 {
+ st,pins {
+ mdint = <&pio13 6 ALT2 IN BYPASS 0>;
+ txen = <&pio13 7 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
+ txd0 = <&pio14 0 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
+ txd1 = <&pio14 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
+ txd2 = <&pio14 2 ALT2 OUT SE_NICLK_IO 0 CLK_B>;
+ txd3 = <&pio14 3 ALT2 OUT SE_NICLK_IO 0 CLK_B>;
+
+ txclk = <&pio15 0 ALT2 IN NICLK 0 CLK_A>;
+ txer = <&pio15 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
+ crs = <&pio15 2 ALT2 IN BYPASS 1000>;
+ col = <&pio15 3 ALT2 IN BYPASS 1000>;
+ mdio= <&pio15 4 ALT2 OUT BYPASS 1500>;
+ mdc = <&pio15 5 ALT2 OUT NICLK 0 CLK_B>;
+
+ rxd0 = <&pio16 0 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+ rxd1 = <&pio16 1 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+ rxd2 = <&pio16 2 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+ rxd3 = <&pio16 3 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+ rxdv = <&pio15 6 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+ rx_er = <&pio15 7 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+ rxclk = <&pio17 0 ALT2 IN NICLK 0 CLK_A>;
+ phyclk = <&pio13 5 ALT2 OUT NICLK 0 CLK_B>;
+ };
+ };
+
+ pinctrl_gmii0: gmii0 {
+ st,pins {
+ };
+ };
+ pinctrl_rgmii0: rgmii0 {
+ st,pins {
+ phyclk = <&pio13 5 ALT4 OUT NICLK 0 CLK_B>;
+ txen = <&pio13 7 ALT2 OUT DE_IO 0 CLK_A>;
+ txd0 = <&pio14 0 ALT2 OUT DE_IO 500 CLK_A>;
+ txd1 = <&pio14 1 ALT2 OUT DE_IO 500 CLK_A>;
+ txd2 = <&pio14 2 ALT2 OUT DE_IO 500 CLK_B>;
+ txd3 = <&pio14 3 ALT2 OUT DE_IO 500 CLK_B>;
+ txclk = <&pio15 0 ALT2 IN NICLK 0 CLK_A>;
+
+ mdio = <&pio15 4 ALT2 OUT BYPASS 0>;
+ mdc = <&pio15 5 ALT2 OUT NICLK 0 CLK_B>;
+
+ rxdv = <&pio15 6 ALT2 IN DE_IO 500 CLK_A>;
+ rxd0 =<&pio16 0 ALT2 IN DE_IO 500 CLK_A>;
+ rxd1 =<&pio16 1 ALT2 IN DE_IO 500 CLK_A>;
+ rxd2 =<&pio16 2 ALT2 IN DE_IO 500 CLK_A>;
+ rxd3 =<&pio16 3 ALT2 IN DE_IO 500 CLK_A>;
+ rxclk =<&pio17 0 ALT2 IN NICLK 0 CLK_A>;
+
+ clk125=<&pio17 6 ALT1 IN NICLK 0 CLK_A>;
+ };
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0: mmc0 {
+ st,pins {
+ mmcclk = <&pio13 4 ALT4 BIDIR_PU NICLK 0 CLK_B>;
+ data0 = <&pio14 4 ALT4 BIDIR_PU BYPASS 0>;
+ data1 = <&pio14 5 ALT4 BIDIR_PU BYPASS 0>;
+ data2 = <&pio14 6 ALT4 BIDIR_PU BYPASS 0>;
+ data3 = <&pio14 7 ALT4 BIDIR_PU BYPASS 0>;
+ cmd = <&pio15 1 ALT4 BIDIR_PU BYPASS 0>;
+ wp = <&pio15 3 ALT4 IN>;
+ data4 = <&pio16 4 ALT4 BIDIR_PU BYPASS 0>;
+ data5 = <&pio16 5 ALT4 BIDIR_PU BYPASS 0>;
+ data6 = <&pio16 6 ALT4 BIDIR_PU BYPASS 0>;
+ data7 = <&pio16 7 ALT4 BIDIR_PU BYPASS 0>;
+ pwr = <&pio17 1 ALT4 OUT>;
+ cd = <&pio17 2 ALT4 IN>;
+ led = <&pio17 3 ALT4 OUT>;
+ };
+ };
+ };
+ mmc1 {
+ pinctrl_mmc1: mmc1 {
+ st,pins {
+ mmcclk = <&pio15 0 ALT3 BIDIR_PU NICLK 0 CLK_B>;
+ data0 = <&pio13 7 ALT3 BIDIR_PU BYPASS 0>;
+ data1 = <&pio14 1 ALT3 BIDIR_PU BYPASS 0>;
+ data2 = <&pio14 2 ALT3 BIDIR_PU BYPASS 0>;
+ data3 = <&pio14 3 ALT3 BIDIR_PU BYPASS 0>;
+ cmd = <&pio15 4 ALT3 BIDIR_PU BYPASS 0>;
+ data4 = <&pio15 6 ALT3 BIDIR_PU BYPASS 0>;
+ data5 = <&pio15 7 ALT3 BIDIR_PU BYPASS 0>;
+ data6 = <&pio16 0 ALT3 BIDIR_PU BYPASS 0>;
+ data7 = <&pio16 1 ALT3 BIDIR_PU BYPASS 0>;
+ pwr = <&pio16 2 ALT3 OUT>;
+ nreset = <&pio13 6 ALT3 OUT>;
+ };
+ };
+ };
+
+ usb {
+ pinctrl_usb1: usb1 {
+ st,pins {
+ oc-detect = <&pio18 0 ALT1 IN>;
+ pwr-enable = <&pio18 1 ALT1 OUT>;
+ };
+ };
+ pinctrl_usb2: usb2 {
+ st,pins {
+ oc-detect = <&pio18 2 ALT1 IN>;
+ pwr-enable = <&pio18 3 ALT1 OUT>;
+ };
+ };
+ };
+ };
+
+ pin-controller-fvdp-fe {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stih416-fvdp-fe-pinctrl";
+ st,syscfg = <&syscfg_fvdp_fe>;
+ reg = <0xfd6bf080 0x4>;
+ reg-names = "irqmux";
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irqmux";
+ ranges = <0 0xfd6b0000 0x3000>;
+
+ pio100: gpio@fd6b0000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0 0x100>;
+ st,bank-name = "PIO100";
+ };
+ pio101: gpio@fd6b1000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1000 0x100>;
+ st,bank-name = "PIO101";
+ };
+ pio102: gpio@fd6b2000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x2000 0x100>;
+ st,bank-name = "PIO102";
+ };
+ };
+
+ pin-controller-fvdp-lite {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stih416-fvdp-lite-pinctrl";
+ st,syscfg = <&syscfg_fvdp_lite>;
+ reg = <0xfd33f080 0x4>;
+ reg-names = "irqmux";
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irqmux";
+ ranges = <0 0xfd330000 0x5000>;
+
+ pio103: gpio@fd330000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0 0x100>;
+ st,bank-name = "PIO103";
+ };
+ pio104: gpio@fd331000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1000 0x100>;
+ st,bank-name = "PIO104";
+ };
+ pio105: gpio@fd332000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x2000 0x100>;
+ st,bank-name = "PIO105";
+ };
+ pio106: gpio@fd333000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x3000 0x100>;
+ st,bank-name = "PIO106";
+ };
+
+ pio107: gpio@fd334000 {
+ gpio-controller;
+ #gpio-cells = <1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x4000 0x100>;
+ st,bank-name = "PIO107";
+ st,retime-pin-mask = <0xf>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih416.dtsi b/arch/arm/boot/dts/stih416.dtsi
new file mode 100644
index 000000000..eeb7afecb
--- /dev/null
+++ b/arch/arm/boot/dts/stih416.dtsi
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2012 STMicroelectronics Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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 "stih41x.dtsi"
+#include "stih416-clock.dtsi"
+#include "stih416-pinctrl.dtsi"
+
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset-controller/stih416-resets.h>
+/ {
+ L2: cache-controller {
+ compatible = "arm,pl310-cache";
+ reg = <0xfffe2000 0x1000>;
+ arm,data-latency = <3 3 3>;
+ arm,tag-latency = <2 2 2>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&intc>;
+ ranges;
+ compatible = "simple-bus";
+
+ powerdown: powerdown-controller {
+ #reset-cells = <1>;
+ compatible = "st,stih416-powerdown";
+ };
+
+ softreset: softreset-controller {
+ #reset-cells = <1>;
+ compatible = "st,stih416-softreset";
+ };
+
+ syscfg_sbc:sbc-syscfg@fe600000{
+ compatible = "st,stih416-sbc-syscfg", "syscon";
+ reg = <0xfe600000 0x1000>;
+ };
+
+ syscfg_front:front-syscfg@fee10000{
+ compatible = "st,stih416-front-syscfg", "syscon";
+ reg = <0xfee10000 0x1000>;
+ };
+
+ syscfg_rear:rear-syscfg@fe830000{
+ compatible = "st,stih416-rear-syscfg", "syscon";
+ reg = <0xfe830000 0x1000>;
+ };
+
+ /* MPE */
+ syscfg_fvdp_fe:fvdp-fe-syscfg@fddf0000{
+ compatible = "st,stih416-fvdp-fe-syscfg", "syscon";
+ reg = <0xfddf0000 0x1000>;
+ };
+
+ syscfg_fvdp_lite:fvdp-lite-syscfg@fd6a0000{
+ compatible = "st,stih416-fvdp-lite-syscfg", "syscon";
+ reg = <0xfd6a0000 0x1000>;
+ };
+
+ syscfg_cpu:cpu-syscfg@fdde0000{
+ compatible = "st,stih416-cpu-syscfg", "syscon";
+ reg = <0xfdde0000 0x1000>;
+ };
+
+ syscfg_compo:compo-syscfg@fd320000{
+ compatible = "st,stih416-compo-syscfg", "syscon";
+ reg = <0xfd320000 0x1000>;
+ };
+
+ syscfg_transport:transport-syscfg@fd690000{
+ compatible = "st,stih416-transport-syscfg", "syscon";
+ reg = <0xfd690000 0x1000>;
+ };
+
+ syscfg_lpm:lpm-syscfg@fe4b5100{
+ compatible = "st,stih416-lpm-syscfg", "syscon";
+ reg = <0xfe4b5100 0x8>;
+ };
+
+ serial2: serial@fed32000{
+ compatible = "st,asc";
+ status = "disabled";
+ reg = <0xfed32000 0x2c>;
+ interrupts = <0 197 0>;
+ clocks = <&clk_s_a0_ls CLK_ICN_REG>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_serial2 &pinctrl_serial2_oe>;
+ };
+
+ /* SBC_UART1 */
+ sbc_serial1: serial@fe531000 {
+ compatible = "st,asc";
+ status = "disabled";
+ reg = <0xfe531000 0x2c>;
+ interrupts = <0 210 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sbc_serial1>;
+ clocks = <&clk_sysin>;
+ };
+
+ i2c@fed40000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0xfed40000 0x110>;
+ interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_s_a0_ls CLK_ICN_REG>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_default>;
+
+ status = "disabled";
+ };
+
+ i2c@fed41000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0xfed41000 0x110>;
+ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_s_a0_ls CLK_ICN_REG>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1_default>;
+
+ status = "disabled";
+ };
+
+ i2c@fe540000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0xfe540000 0x110>;
+ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_sysin>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sbc_i2c0_default>;
+
+ status = "disabled";
+ };
+
+ i2c@fe541000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0xfe541000 0x110>;
+ interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_sysin>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sbc_i2c1_default>;
+
+ status = "disabled";
+ };
+
+ ethernet0: dwmac@fe810000 {
+ device_type = "network";
+ compatible = "st,stih416-dwmac", "snps,dwmac", "snps,dwmac-3.710";
+ status = "disabled";
+ reg = <0xfe810000 0x8000>;
+ reg-names = "stmmaceth";
+
+ interrupts = <0 133 0>, <0 134 0>, <0 135 0>;
+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+
+ snps,pbl = <32>;
+ snps,mixed-burst;
+
+ st,syscon = <&syscfg_rear 0x8bc>;
+ resets = <&softreset STIH416_ETH0_SOFTRESET>;
+ reset-names = "stmmaceth";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mii0>;
+ clock-names = "stmmaceth", "sti-ethclk";
+ clocks = <&clk_s_a1_ls CLK_ICN_IF_2>, <&clk_s_a1_ls CLK_GMAC0_PHY>;
+ };
+
+ ethernet1: dwmac@fef08000 {
+ device_type = "network";
+ compatible = "st,stih416-dwmac", "snps,dwmac", "snps,dwmac-3.710";
+ status = "disabled";
+ reg = <0xfef08000 0x8000>;
+ reg-names = "stmmaceth";
+ interrupts = <0 136 0>, <0 137 0>, <0 138 0>;
+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+
+ snps,pbl = <32>;
+ snps,mixed-burst;
+
+ st,syscon = <&syscfg_sbc 0x7f0>;
+
+ resets = <&softreset STIH416_ETH1_SOFTRESET>;
+ reset-names = "stmmaceth";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mii1>;
+ clock-names = "stmmaceth", "sti-ethclk";
+ clocks = <&clk_s_a0_ls CLK_ICN_REG>, <&clk_s_a0_ls CLK_ETH1_PHY>;
+ };
+
+ rc: rc@fe518000 {
+ compatible = "st,comms-irb";
+ reg = <0xfe518000 0x234>;
+ interrupts = <0 203 0>;
+ rx-mode = "infrared";
+ clocks = <&clk_sysin>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ir>;
+ resets = <&softreset STIH416_IRB_SOFTRESET>;
+ };
+
+ /* FSM */
+ spifsm: spifsm@fe902000 {
+ compatible = "st,spi-fsm";
+ reg = <0xfe902000 0x1000>;
+ pinctrl-0 = <&pinctrl_fsm>;
+
+ st,syscfg = <&syscfg_rear>;
+ st,boot-device-reg = <0x958>;
+ st,boot-device-spi = <0x1a>;
+
+ status = "disabled";
+ };
+
+ keyscan: keyscan@fe4b0000 {
+ compatible = "st,sti-keyscan";
+ status = "disabled";
+ reg = <0xfe4b0000 0x2000>;
+ interrupts = <GIC_SPI 212 IRQ_TYPE_NONE>;
+ clocks = <&clk_sysin>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_keyscan>;
+ resets = <&powerdown STIH416_KEYSCAN_POWERDOWN>,
+ <&softreset STIH416_KEYSCAN_SOFTRESET>;
+ };
+
+ temp0 {
+ compatible = "st,stih416-sas-thermal";
+ clock-names = "thermal";
+ clocks = <&clockgen_c_vcc 14>;
+
+ status = "okay";
+ };
+
+ temp1@fdfe8000 {
+ compatible = "st,stih416-mpe-thermal";
+ reg = <0xfdfe8000 0x10>;
+ clocks = <&clockgen_e 3>;
+ clock-names = "thermal";
+ interrupts = <GIC_SPI 23 IRQ_TYPE_EDGE_RISING>;
+
+ status = "okay";
+ };
+
+ mmc0: sdhci@fe81e000 {
+ compatible = "st,sdhci";
+ status = "disabled";
+ reg = <0xfe81e000 0x1000>;
+ interrupts = <GIC_SPI 127 IRQ_TYPE_NONE>;
+ interrupt-names = "mmcirq";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc0>;
+ clock-names = "mmc";
+ clocks = <&clk_s_a1_ls 1>;
+ };
+
+ mmc1: sdhci@fe81f000 {
+ compatible = "st,sdhci";
+ status = "disabled";
+ reg = <0xfe81f000 0x1000>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_NONE>;
+ interrupt-names = "mmcirq";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc1>;
+ clock-names = "mmc";
+ clocks = <&clk_s_a1_ls 8>;
+ };
+
+ miphy365x_phy: phy@fe382000 {
+ compatible = "st,miphy365x-phy";
+ st,syscfg = <&syscfg_rear 0x824 0x828>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ phy_port0: port@fe382000 {
+ #phy-cells = <1>;
+ reg = <0xfe382000 0x100>, <0xfe394000 0x100>;
+ reg-names = "sata", "pcie";
+ };
+
+ phy_port1: port@fe38a000 {
+ #phy-cells = <1>;
+ reg = <0xfe38a000 0x100>, <0xfe804000 0x100>;
+ reg-names = "sata", "pcie";
+ };
+ };
+
+ sata0: sata@fe380000 {
+ compatible = "st,sti-ahci";
+ reg = <0xfe380000 0x1000>;
+ interrupts = <GIC_SPI 157 IRQ_TYPE_NONE>;
+ interrupt-names = "hostc";
+ phys = <&phy_port0 PHY_TYPE_SATA>;
+ phy-names = "sata-phy";
+ resets = <&powerdown STIH416_SATA0_POWERDOWN>,
+ <&softreset STIH416_SATA0_SOFTRESET>;
+ reset-names = "pwr-dwn", "sw-rst";
+ clock-names = "ahci_clk";
+ clocks = <&clk_s_a0_ls CLK_ICN_REG>;
+
+ status = "disabled";
+ };
+
+ usb2_phy: phy@0 {
+ compatible = "st,stih416-usb-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_rear>;
+ clocks = <&clk_sysin>;
+ clock-names = "osc_phy";
+ };
+
+ ehci0: usb@fe1ffe00 {
+ compatible = "st,st-ehci-300x";
+ reg = <0xfe1ffe00 0x100>;
+ interrupts = <GIC_SPI 148 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0>;
+ clocks = <&clk_s_a1_ls 0>,
+ <&clockgen_b0 0>;
+ clock-names = "ic", "clk48";
+ phys = <&usb2_phy>;
+ phy-names = "usb";
+ resets = <&powerdown STIH416_USB0_POWERDOWN>,
+ <&softreset STIH416_USB0_SOFTRESET>;
+ reset-names = "power", "softreset";
+ };
+
+ ohci0: usb@fe1ffc00 {
+ compatible = "st,st-ohci-300x";
+ reg = <0xfe1ffc00 0x100>;
+ interrupts = <GIC_SPI 149 IRQ_TYPE_NONE>;
+ clocks = <&clk_s_a1_ls 0>,
+ <&clockgen_b0 0>;
+ clock-names = "ic", "clk48";
+ phys = <&usb2_phy>;
+ phy-names = "usb";
+ status = "okay";
+ resets = <&powerdown STIH416_USB0_POWERDOWN>,
+ <&softreset STIH416_USB0_SOFTRESET>;
+ reset-names = "power", "softreset";
+ };
+
+ ehci1: usb@fe203e00 {
+ compatible = "st,st-ehci-300x";
+ reg = <0xfe203e00 0x100>;
+ interrupts = <GIC_SPI 150 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb1>;
+ clocks = <&clk_s_a1_ls 0>,
+ <&clockgen_b0 0>;
+ clock-names = "ic", "clk48";
+ phys = <&usb2_phy>;
+ phy-names = "usb";
+ resets = <&powerdown STIH416_USB1_POWERDOWN>,
+ <&softreset STIH416_USB1_SOFTRESET>;
+ reset-names = "power", "softreset";
+ };
+
+ ohci1: usb@fe203c00 {
+ compatible = "st,st-ohci-300x";
+ reg = <0xfe203c00 0x100>;
+ interrupts = <GIC_SPI 151 IRQ_TYPE_NONE>;
+ clocks = <&clk_s_a1_ls 0>,
+ <&clockgen_b0 0>;
+ clock-names = "ic", "clk48";
+ phys = <&usb2_phy>;
+ phy-names = "usb";
+ resets = <&powerdown STIH416_USB1_POWERDOWN>,
+ <&softreset STIH416_USB1_SOFTRESET>;
+ reset-names = "power", "softreset";
+ };
+
+ ehci2: usb@fe303e00 {
+ compatible = "st,st-ehci-300x";
+ reg = <0xfe303e00 0x100>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb2>;
+ clocks = <&clk_s_a1_ls 0>,
+ <&clockgen_b0 0>;
+ clock-names = "ic", "clk48";
+ phys = <&usb2_phy>;
+ phy-names = "usb";
+ resets = <&powerdown STIH416_USB2_POWERDOWN>,
+ <&softreset STIH416_USB2_SOFTRESET>;
+ reset-names = "power", "softreset";
+ };
+
+ ohci2: usb@fe303c00 {
+ compatible = "st,st-ohci-300x";
+ reg = <0xfe303c00 0x100>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_NONE>;
+ clocks = <&clk_s_a1_ls 0>,
+ <&clockgen_b0 0>;
+ clock-names = "ic", "clk48";
+ phys = <&usb2_phy>;
+ phy-names = "usb";
+ resets = <&powerdown STIH416_USB2_POWERDOWN>,
+ <&softreset STIH416_USB2_SOFTRESET>;
+ reset-names = "power", "softreset";
+ };
+
+ ehci3: usb@fe343e00 {
+ compatible = "st,st-ehci-300x";
+ reg = <0xfe343e00 0x100>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb3>;
+ clocks = <&clk_s_a1_ls 0>,
+ <&clockgen_b0 0>;
+ clock-names = "ic", "clk48";
+ phys = <&usb2_phy>;
+ phy-names = "usb";
+ resets = <&powerdown STIH416_USB3_POWERDOWN>,
+ <&softreset STIH416_USB3_SOFTRESET>;
+ reset-names = "power", "softreset";
+ };
+
+ ohci3: usb@fe343c00 {
+ compatible = "st,st-ohci-300x";
+ reg = <0xfe343c00 0x100>;
+ interrupts = <GIC_SPI 155 IRQ_TYPE_NONE>;
+ clocks = <&clk_s_a1_ls 0>,
+ <&clockgen_b0 0>;
+ clock-names = "ic", "clk48";
+ phys = <&usb2_phy>;
+ phy-names = "usb";
+ resets = <&powerdown STIH416_USB3_POWERDOWN>,
+ <&softreset STIH416_USB3_SOFTRESET>;
+ reset-names = "power", "softreset";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih418-b2199.dts b/arch/arm/boot/dts/stih418-b2199.dts
new file mode 100644
index 000000000..926235c08
--- /dev/null
+++ b/arch/arm/boot/dts/stih418-b2199.dts
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 STMicroelectronics (R&D) Limited.
+ * Author: Maxime Coquelin <maxime.coquelin@st.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.
+ */
+/dts-v1/;
+#include "stih418.dtsi"
+/ {
+ model = "STiH418 B2199";
+ compatible = "st,stih418-b2199", "st,stih418";
+
+ chosen {
+ bootargs = "console=ttyAS0,115200 clk_ignore_unused";
+ linux,stdout-path = &sbc_serial0;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x40000000 0xc0000000>;
+ };
+
+ aliases {
+ ttyAS0 = &sbc_serial0;
+ };
+
+ soc {
+ sbc_serial0: serial@9530000 {
+ status = "okay";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ red {
+ #gpio-cells = <2>;
+ label = "Front Panel LED";
+ gpios = <&pio4 1 0>;
+ linux,default-trigger = "heartbeat";
+ };
+ green {
+ #gpio-cells = <2>;
+ gpios = <&pio1 3 0>;
+ default-state = "off";
+ };
+ };
+
+ i2c@9842000 {
+ status = "okay";
+ };
+
+ i2c@9843000 {
+ status = "okay";
+ };
+
+ i2c@9844000 {
+ status = "okay";
+ };
+
+ i2c@9845000 {
+ status = "okay";
+ };
+
+ i2c@9540000 {
+ status = "okay";
+ };
+
+ /* SSC11 to HDMI */
+ i2c@9541000 {
+ status = "okay";
+ /* HDMI V1.3a supports Standard mode only */
+ clock-frequency = <100000>;
+ st,i2c-min-scl-pulse-width-us = <0>;
+ st,i2c-min-sda-pulse-width-us = <5>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih418-clock.dtsi b/arch/arm/boot/dts/stih418-clock.dtsi
new file mode 100644
index 000000000..0ab23daa2
--- /dev/null
+++ b/arch/arm/boot/dts/stih418-clock.dtsi
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2015 STMicroelectronics R&D 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 <dt-bindings/clock/stih418-clks.h>
+/ {
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ compatible = "st,stih418-clk", "simple-bus";
+
+ /*
+ * Fixed 30MHz oscillator inputs to SoC
+ */
+ clk_sysin: clk-sysin {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <30000000>;
+ clock-output-names = "CLK_SYSIN";
+ };
+
+ /*
+ * ARM Peripheral clock for timers
+ */
+ arm_periph_clk: clk-m-a9-periphs {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&clk_m_a9>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+
+ /*
+ * A9 PLL.
+ */
+ clockgen-a9@92b0000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x92b0000 0xffff>;
+
+ clockgen_a9_pll: clockgen-a9-pll {
+ #clock-cells = <1>;
+ compatible = "st,stih407-plls-c32-a9", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clockgen-a9-pll-odf";
+ };
+ };
+
+ /*
+ * ARM CPU related clocks.
+ */
+ clk_m_a9: clk-m-a9@92b0000 {
+ #clock-cells = <0>;
+ compatible = "st,stih407-clkgen-a9-mux", "st,clkgen-mux";
+ reg = <0x92b0000 0x10000>;
+
+ clocks = <&clockgen_a9_pll 0>,
+ <&clockgen_a9_pll 0>,
+ <&clk_s_c0_flexgen 13>,
+ <&clk_m_a9_ext2f_div2>;
+ };
+
+ /*
+ * ARM Peripheral clock for timers
+ */
+ clk_m_a9_ext2f_div2: clk-m-a9-ext2f-div2s {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+
+ clocks = <&clk_s_c0_flexgen 13>;
+
+ clock-output-names = "clk-m-a9-ext2f-div2";
+
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+
+ /*
+ * Bootloader initialized system infrastructure clock for
+ * serial devices.
+ */
+ clk_ext2f_a9: clockgen-c0@13 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <200000000>;
+ clock-output-names = "clk-s-icn-reg-0";
+ };
+
+ clockgen-a@090ff000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x90ff000 0x1000>;
+
+ clk_s_a0_pll: clk-s-a0-pll {
+ #clock-cells = <1>;
+ compatible = "st,stih407-plls-c32-a0", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-a0-pll-ofd-0";
+ };
+
+ clk_s_a0_flexgen: clk-s-a0-flexgen {
+ compatible = "st,flexgen";
+
+ #clock-cells = <1>;
+
+ clocks = <&clk_s_a0_pll 0>,
+ <&clk_sysin>;
+
+ clock-output-names = "clk-ic-lmi0",
+ "clk-ic-lmi1";
+ };
+ };
+
+ clk_s_c0_quadfs: clk-s-c0-quadfs@9103000 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-quadfs660-C", "st,quadfs";
+ reg = <0x9103000 0x1000>;
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-c0-fs0-ch0",
+ "clk-s-c0-fs0-ch1",
+ "clk-s-c0-fs0-ch2",
+ "clk-s-c0-fs0-ch3";
+ };
+
+ clk_s_c0: clockgen-c@09103000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x9103000 0x1000>;
+
+ clk_s_c0_pll0: clk-s-c0-pll0 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-plls-c32-c0_0", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-c0-pll0-odf-0";
+ };
+
+ clk_s_c0_pll1: clk-s-c0-pll1 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-plls-c32-c0_1", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-c0-pll1-odf-0";
+ };
+
+ clk_s_c0_flexgen: clk-s-c0-flexgen {
+ #clock-cells = <1>;
+ compatible = "st,flexgen";
+
+ clocks = <&clk_s_c0_pll0 0>,
+ <&clk_s_c0_pll1 0>,
+ <&clk_s_c0_quadfs 0>,
+ <&clk_s_c0_quadfs 1>,
+ <&clk_s_c0_quadfs 2>,
+ <&clk_s_c0_quadfs 3>,
+ <&clk_sysin>;
+
+ clock-output-names = "clk-icn-gpu",
+ "clk-fdma",
+ "clk-nand",
+ "clk-hva",
+ "clk-proc-stfe",
+ "clk-tp",
+ "clk-rx-icn-dmu",
+ "clk-rx-icn-hva",
+ "clk-icn-cpu",
+ "clk-tx-icn-dmu",
+ "clk-mmc-0",
+ "clk-mmc-1",
+ "clk-jpegdec",
+ "clk-icn-reg",
+ "clk-proc-bdisp-0",
+ "clk-proc-bdisp-1",
+ "clk-pp-dmu",
+ "clk-vid-dmu",
+ "clk-dss-lpc",
+ "clk-st231-aud-0",
+ "clk-st231-gp-1",
+ "clk-st231-dmu",
+ "clk-icn-lmi",
+ "clk-tx-icn-1",
+ "clk-icn-sbc",
+ "clk-stfe-frc2",
+ "clk-eth-phyref",
+ "clk-eth-ref-phyclk",
+ "clk-flash-promip",
+ "clk-main-disp",
+ "clk-aux-disp",
+ "clk-compo-dvp",
+ "clk-tx-icn-hades",
+ "clk-rx-icn-hades",
+ "clk-icn-reg-16",
+ "clk-pp-hevc",
+ "clk-clust-hevc",
+ "clk-hwpe-hevc",
+ "clk-fc-hevc",
+ "clk-proc-mixer",
+ "clk-proc-sc",
+ "clk-avsp-hevc";
+ };
+ };
+
+ clk_s_d0_quadfs: clk-s-d0-quadfs@9104000 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-quadfs660-D", "st,quadfs";
+ reg = <0x9104000 0x1000>;
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-d0-fs0-ch0",
+ "clk-s-d0-fs0-ch1",
+ "clk-s-d0-fs0-ch2",
+ "clk-s-d0-fs0-ch3";
+ };
+
+ clockgen-d0@09104000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x9104000 0x1000>;
+
+ clk_s_d0_flexgen: clk-s-d0-flexgen {
+ #clock-cells = <1>;
+ compatible = "st,flexgen";
+
+ clocks = <&clk_s_d0_quadfs 0>,
+ <&clk_s_d0_quadfs 1>,
+ <&clk_s_d0_quadfs 2>,
+ <&clk_s_d0_quadfs 3>,
+ <&clk_sysin>;
+
+ clock-output-names = "clk-pcm-0",
+ "clk-pcm-1",
+ "clk-pcm-2",
+ "clk-spdiff",
+ "clk-pcmr10-master",
+ "clk-usb2-phy";
+ };
+ };
+
+ clk_s_d2_quadfs: clk-s-d2-quadfs@9106000 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-quadfs660-D", "st,quadfs";
+ reg = <0x9106000 0x1000>;
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-d2-fs0-ch0",
+ "clk-s-d2-fs0-ch1",
+ "clk-s-d2-fs0-ch2",
+ "clk-s-d2-fs0-ch3";
+ };
+
+ clk_tmdsout_hdmi: clk-tmdsout-hdmi {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ clockgen-d2@x9106000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x9106000 0x1000>;
+
+ clk_s_d2_flexgen: clk-s-d2-flexgen {
+ #clock-cells = <1>;
+ compatible = "st,flexgen";
+
+ clocks = <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 1>,
+ <&clk_s_d2_quadfs 2>,
+ <&clk_s_d2_quadfs 3>,
+ <&clk_sysin>,
+ <&clk_sysin>,
+ <&clk_tmdsout_hdmi>;
+
+ clock-output-names = "clk-pix-main-disp",
+ "",
+ "",
+ "",
+ "",
+ "clk-tmds-hdmi-div2",
+ "clk-pix-aux-disp",
+ "clk-denc",
+ "clk-pix-hddac",
+ "clk-hddac",
+ "clk-sddac",
+ "clk-pix-dvo",
+ "clk-dvo",
+ "clk-pix-hdmi",
+ "clk-tmds-hdmi",
+ "clk-ref-hdmiphy",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "", "clk-vp9";
+ };
+ };
+
+ clk_s_d3_quadfs: clk-s-d3-quadfs@9107000 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-quadfs660-D", "st,quadfs";
+ reg = <0x9107000 0x1000>;
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-d3-fs0-ch0",
+ "clk-s-d3-fs0-ch1",
+ "clk-s-d3-fs0-ch2",
+ "clk-s-d3-fs0-ch3";
+ };
+
+ clockgen-d3@9107000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x9107000 0x1000>;
+
+ clk_s_d3_flexgen: clk-s-d3-flexgen {
+ #clock-cells = <1>;
+ compatible = "st,flexgen";
+
+ clocks = <&clk_s_d3_quadfs 0>,
+ <&clk_s_d3_quadfs 1>,
+ <&clk_s_d3_quadfs 2>,
+ <&clk_s_d3_quadfs 3>,
+ <&clk_sysin>;
+
+ clock-output-names = "clk-stfe-frc1",
+ "clk-tsout-0",
+ "clk-tsout-1",
+ "clk-mchi",
+ "clk-vsens-compo",
+ "clk-frc1-remote",
+ "clk-lpc-0",
+ "clk-lpc-1";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih418.dtsi b/arch/arm/boot/dts/stih418.dtsi
new file mode 100644
index 000000000..354d90f52
--- /dev/null
+++ b/arch/arm/boot/dts/stih418.dtsi
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics Limited.
+ * Author: Peter Griffin <peter.griffin@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
+ * publishhed by the Free Software Foundation.
+ */
+#include "stih418-clock.dtsi"
+#include "stih407-family.dtsi"
+#include "stih410-pinctrl.dtsi"
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <2>;
+ };
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <3>;
+ };
+ };
+
+ soc {
+ usb2_picophy1: phy2 {
+ compatible = "st,stih407-usb2-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core 0xf8 0xf4>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
+ <&picophyreset STIH407_PICOPHY0_RESET>;
+ reset-names = "global", "port";
+ };
+
+ usb2_picophy2: phy3 {
+ compatible = "st,stih407-usb2-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core 0xfc 0xf4>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
+ <&picophyreset STIH407_PICOPHY1_RESET>;
+ reset-names = "global", "port";
+ };
+
+ ohci0: usb@9a03c00 {
+ compatible = "st,st-ohci-300x";
+ reg = <0x9a03c00 0x100>;
+ interrupts = <GIC_SPI 180 IRQ_TYPE_NONE>;
+ clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+ resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>,
+ <&softreset STIH407_USB2_PORT0_SOFTRESET>;
+ reset-names = "power", "softreset";
+ phys = <&usb2_picophy1>;
+ phy-names = "usb";
+ };
+
+ ehci0: usb@9a03e00 {
+ compatible = "st,st-ehci-300x";
+ reg = <0x9a03e00 0x100>;
+ interrupts = <GIC_SPI 151 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0>;
+ clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+ resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>,
+ <&softreset STIH407_USB2_PORT0_SOFTRESET>;
+ reset-names = "power", "softreset";
+ phys = <&usb2_picophy1>;
+ phy-names = "usb";
+ };
+
+ ohci1: usb@9a83c00 {
+ compatible = "st,st-ohci-300x";
+ reg = <0x9a83c00 0x100>;
+ interrupts = <GIC_SPI 181 IRQ_TYPE_NONE>;
+ clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+ resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>,
+ <&softreset STIH407_USB2_PORT1_SOFTRESET>;
+ reset-names = "power", "softreset";
+ phys = <&usb2_picophy2>;
+ phy-names = "usb";
+ };
+
+ ehci1: usb@9a83e00 {
+ compatible = "st,st-ehci-300x";
+ reg = <0x9a83e00 0x100>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb1>;
+ clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+ resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>,
+ <&softreset STIH407_USB2_PORT1_SOFTRESET>;
+ reset-names = "power", "softreset";
+ phys = <&usb2_picophy2>;
+ phy-names = "usb";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih41x-b2000.dtsi b/arch/arm/boot/dts/stih41x-b2000.dtsi
new file mode 100644
index 000000000..5f91f455f
--- /dev/null
+++ b/arch/arm/boot/dts/stih41x-b2000.dtsi
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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 <dt-bindings/input/input.h>
+/ {
+
+ memory{
+ device_type = "memory";
+ reg = <0x60000000 0x40000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyAS0,115200 clk_ignore_unused";
+ linux,stdout-path = &serial2;
+ };
+
+ aliases {
+ ttyAS0 = &serial2;
+ ethernet0 = &ethernet0;
+ ethernet1 = &ethernet1;
+ };
+
+ soc {
+ serial2: serial@fed32000 {
+ status = "okay";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ fp_led {
+ #gpio-cells = <1>;
+ label = "Front Panel LED";
+ gpios = <&pio105 7>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ /* HDMI Tx I2C */
+ i2c@fed41000 {
+ /* HDMI V1.3a supports Standard mode only */
+ clock-frequency = <100000>;
+ i2c-min-scl-pulse-width-us = <0>;
+ i2c-min-sda-pulse-width-us = <5>;
+
+ status = "okay";
+ };
+
+ ethernet0: dwmac@fe810000 {
+ status = "okay";
+ phy-mode = "mii";
+ pinctrl-0 = <&pinctrl_mii0>;
+
+ snps,reset-gpio = <&pio106 2>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 10000>;
+ };
+
+ ethernet1: dwmac@fef08000 {
+ status = "disabled";
+ phy-mode = "mii";
+ st,tx-retime-src = "txclk";
+
+ snps,reset-gpio = <&pio4 7>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 10000>;
+ };
+
+ keyscan: keyscan@fe4b0000 {
+ keypad,num-rows = <4>;
+ keypad,num-columns = <4>;
+ st,debounce-us = <5000>;
+ linux,keymap = < MATRIX_KEY(0x00, 0x00, KEY_F13)
+ MATRIX_KEY(0x00, 0x01, KEY_F9)
+ MATRIX_KEY(0x00, 0x02, KEY_F5)
+ MATRIX_KEY(0x00, 0x03, KEY_F1)
+ MATRIX_KEY(0x01, 0x00, KEY_F14)
+ MATRIX_KEY(0x01, 0x01, KEY_F10)
+ MATRIX_KEY(0x01, 0x02, KEY_F6)
+ MATRIX_KEY(0x01, 0x03, KEY_F2)
+ MATRIX_KEY(0x02, 0x00, KEY_F15)
+ MATRIX_KEY(0x02, 0x01, KEY_F11)
+ MATRIX_KEY(0x02, 0x02, KEY_F7)
+ MATRIX_KEY(0x02, 0x03, KEY_F3)
+ MATRIX_KEY(0x03, 0x00, KEY_F16)
+ MATRIX_KEY(0x03, 0x01, KEY_F12)
+ MATRIX_KEY(0x03, 0x02, KEY_F8)
+ MATRIX_KEY(0x03, 0x03, KEY_F4) >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih41x-b2020.dtsi b/arch/arm/boot/dts/stih41x-b2020.dtsi
new file mode 100644
index 000000000..487d7d87d
--- /dev/null
+++ b/arch/arm/boot/dts/stih41x-b2020.dtsi
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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 "stih41x-b2020x.dtsi"
+/ {
+ memory{
+ device_type = "memory";
+ reg = <0x40000000 0x80000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyAS0,115200 clk_ignore_unused";
+ linux,stdout-path = &sbc_serial1;
+ };
+
+ aliases {
+ ttyAS0 = &sbc_serial1;
+ ethernet1 = &ethernet1;
+ };
+ soc {
+ sbc_serial1: serial@fe531000 {
+ status = "okay";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ red {
+ #gpio-cells = <1>;
+ label = "Front Panel LED";
+ gpios = <&pio4 1>;
+ linux,default-trigger = "heartbeat";
+ };
+ green {
+ gpios = <&pio4 7>;
+ default-state = "off";
+ };
+ };
+
+ i2c@fed40000 {
+ status = "okay";
+ };
+
+ /* HDMI Tx I2C */
+ i2c@fed41000 {
+ /* HDMI V1.3a supports Standard mode only */
+ clock-frequency = <100000>;
+ i2c-min-scl-pulse-width-us = <0>;
+ i2c-min-sda-pulse-width-us = <5>;
+
+ status = "okay";
+ };
+
+ i2c@fe540000 {
+ status = "okay";
+ };
+
+ i2c@fe541000 {
+ status = "okay";
+ };
+
+ ethernet1: dwmac@fef08000 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ max-speed = <1000>;
+ st,tx-retime-src = "clk_125";
+ snps,reset-gpio = <&pio3 0>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 10000>;
+
+ pinctrl-0 = <&pinctrl_rgmii1>;
+ };
+
+ mmc0: sdhci@fe81e000 {
+ bus-width = <8>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih41x-b2020x.dtsi b/arch/arm/boot/dts/stih41x-b2020x.dtsi
new file mode 100644
index 000000000..f797a0607
--- /dev/null
+++ b/arch/arm/boot/dts/stih41x-b2020x.dtsi
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Lee Jones <lee.jones@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
+ * publishhed by the Free Software Foundation.
+ */
+/ {
+ soc {
+ mmc0: sdhci@fe81e000 {
+ status = "okay";
+ };
+
+ spifsm: spifsm@fe902000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ status = "okay";
+
+ partition@0 {
+ label = "SerialFlash1";
+ reg = <0x00000000 0x00500000>;
+ };
+
+ partition@500000 {
+ label = "SerialFlash2";
+ reg = <0x00500000 0x00b00000>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih41x.dtsi b/arch/arm/boot/dts/stih41x.dtsi
new file mode 100644
index 000000000..5cb0e6337
--- /dev/null
+++ b/arch/arm/boot/dts/stih41x.dtsi
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics 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
+ * publishhed by the Free Software Foundation.
+ */
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ };
+ };
+
+ intc: interrupt-controller@fffe1000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0xfffe1000 0x1000>,
+ <0xfffe0100 0x100>;
+ };
+
+ scu@fffe0000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0xfffe0000 0x1000>;
+ };
+
+ timer@fffe0200 {
+ interrupt-parent = <&intc>;
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0xfffe0200 0x100>;
+ interrupts = <1 11 0x04>;
+ clocks = <&arm_periph_clk>;
+ };
+};
diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
new file mode 100644
index 000000000..c1d859092
--- /dev/null
+++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics (R&D) Limited.
+ * Author: Giuseppe Cavallaro <peppe.cavallaro@st.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.
+ */
+/ {
+ soc {
+ sbc_serial0: serial@9530000 {
+ status = "okay";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ red {
+ #gpio-cells = <2>;
+ label = "Front Panel LED";
+ gpios = <&pio4 1 0>;
+ linux,default-trigger = "heartbeat";
+ };
+ green {
+ #gpio-cells = <2>;
+ gpios = <&pio1 3 0>;
+ default-state = "off";
+ };
+ };
+
+ i2c@9842000 {
+ status = "okay";
+ };
+
+ i2c@9843000 {
+ status = "okay";
+ };
+
+ i2c@9844000 {
+ status = "okay";
+ };
+
+ i2c@9845000 {
+ status = "okay";
+ };
+
+ i2c@9540000 {
+ status = "okay";
+ };
+
+ /* SSC11 to HDMI */
+ hdmiddc: i2c@9541000 {
+ status = "okay";
+ /* HDMI V1.3a supports Standard mode only */
+ clock-frequency = <100000>;
+ st,i2c-min-scl-pulse-width-us = <0>;
+ st,i2c-min-sda-pulse-width-us = <5>;
+ };
+
+ miphy28lp_phy: miphy28lp@9b22000 {
+
+ phy_port0: port@9b22000 {
+ st,osc-rdy;
+ };
+
+ phy_port1: port@9b2a000 {
+ st,osc-force-ext;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
new file mode 100644
index 000000000..b67e5be61
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2013 Emilio LĂ³pez
+ *
+ * Emilio LĂ³pez <emilio@elopez.com.ar>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Mele A1000";
+ compatible = "mele,a1000", "allwinner,sun4i-a10";
+
+ soc@01c00000 {
+ emac: ethernet@01c0b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_pins_a>;
+ phy = <&phy1>;
+ status = "okay";
+ };
+
+ mdio@01c0b080 {
+ phy-supply = <&reg_emac_3v3>;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ahci: sata@01c18000 {
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ emac_power_pin_a1000: emac_power_pin@0 {
+ allwinner,pins = "PH15";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ led_pins_a1000: led_pins@0 {
+ allwinner,pins = "PH10", "PH20";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ ir0: ir@01c21800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir0_pins_a>;
+ status = "okay";
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_a1000>;
+
+ red {
+ label = "a1000:red:usr";
+ gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>;
+ };
+
+ blue {
+ label = "a1000:blue:usr";
+ gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ reg_emac_3v3: emac-3v3 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_power_pin_a1000>;
+ regulator-name = "emac-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 7 15 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts b/arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts
new file mode 100644
index 000000000..490b77c9b
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "BA10 tvbox";
+ compatible = "allwinner,ba10-tvbox", "allwinner,sun4i-a10";
+
+ soc@01c00000 {
+ emac: ethernet@01c0b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_pins_a>;
+ phy = <&phy1>;
+ status = "okay";
+ };
+
+ mdio@01c0b080 {
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ usb2_vbus_pin_a: usb2_vbus_pin@0 {
+ allwinner,pins = "PH12";
+ };
+ };
+
+ ir0: ir@01c21800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir0_pins_a>;
+ status = "okay";
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ gpio = <&pio 7 12 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
new file mode 100644
index 000000000..58214f249
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Chuwi V7 CW0825";
+ compatible = "chuwi,v7-cw0825", "allwinner,sun4i-a10";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+};
+
+&reg_usb2_vbus {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usbphy {
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
new file mode 100644
index 000000000..4260c2b47
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2012 Stefan Roese
+ * Stefan Roese <sr@denx.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Cubietech Cubieboard";
+ compatible = "cubietech,a10-cubieboard", "allwinner,sun4i-a10";
+
+ soc@01c00000 {
+ emac: ethernet@01c0b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_pins_a>;
+ phy = <&phy1>;
+ status = "okay";
+ };
+
+ mdio@01c0b080 {
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ahci: sata@01c18000 {
+ target-supply = <&reg_ahci_5v>;
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ led_pins_cubieboard: led_pins@0 {
+ allwinner,pins = "PH20", "PH21";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ ir0: ir@01c21800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir0_pins_a>;
+ status = "okay";
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ reg = <0x34>;
+ interrupts = <0>;
+ };
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
+
+ spi0: spi@01c05000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins_a>;
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_cubieboard>;
+
+ blue {
+ label = "cubieboard:blue:usr";
+ gpios = <&pio 7 21 GPIO_ACTIVE_HIGH>; /* LED1 */
+ };
+
+ green {
+ label = "cubieboard:green:usr";
+ gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>; /* LED2 */
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ reg_ahci_5v: ahci-5v {
+ status = "okay";
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ status = "okay";
+ };
+};
+
+#include "axp209.dtsi"
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+ regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "avcc";
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-hackberry.dts b/arch/arm/boot/dts/sun4i-a10-hackberry.dts
new file mode 100644
index 000000000..d3f73ea25
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-hackberry.dts
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Miniand Hackberry";
+ compatible = "miniand,hackberry", "allwinner,sun4i-a10";
+
+ soc@01c00000 {
+ emac: ethernet@01c0b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_pins_a>;
+ phy = <&phy0>;
+ status = "okay";
+ };
+
+ mdio@01c0b080 {
+ phy-supply = <&reg_emac_3v3>;
+ status = "okay";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ pio: pinctrl@01c20800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hackberry_hogs>;
+
+ hackberry_hogs: hogs@0 {
+ allwinner,pins = "PH19";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ usb2_vbus_pin_hackberry: usb2_vbus_pin@0 {
+ allwinner,pins = "PH12";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ ir0: ir@01c21800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir0_pins_a>;
+ status = "okay";
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+ };
+
+ reg_emac_3v3: emac-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "emac-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 7 19 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ pinctrl-0 = <&usb2_vbus_pin_hackberry>;
+ gpio = <&pio 7 12 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts b/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts
new file mode 100644
index 000000000..c88382aac
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Hyundai A7HD";
+ compatible = "hyundai,a7hd", "allwinner,sun4i-a10";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+};
+
+&reg_usb2_vbus {
+ gpio = <&pio 7 6 GPIO_ACTIVE_HIGH>; /* PH6 */
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usb2_vbus_pin_a {
+ allwinner,pins = "PH6";
+};
+
+&usbphy {
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
new file mode 100644
index 000000000..482914333
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2014 Open Source Support GmbH
+ *
+ * David Lanzendörfer <david.lanzendoerfer@o2s.ch>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "INet-97F Rev 02";
+ compatible = "primux,inet97fv2", "allwinner,sun4i-a10";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-marsboard.dts b/arch/arm/boot/dts/sun4i-a10-marsboard.dts
new file mode 100644
index 000000000..9ee86a700
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-marsboard.dts
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2015 Aleksei Mamlin
+ * Aleksei Mamlin <mamlinav@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "HAOYU Electronics Marsboard A10";
+ compatible = "haoyu,a10-marsboard", "allwinner,sun4i-a10";
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_marsboard>;
+
+ red1 {
+ label = "marsboard:red1:usr";
+ gpios = <&pio 1 5 GPIO_ACTIVE_HIGH>;
+ };
+
+ red2 {
+ label = "marsboard:red2:usr";
+ gpios = <&pio 1 6 GPIO_ACTIVE_HIGH>;
+ };
+
+ red3 {
+ label = "marsboard:red3:usr";
+ gpios = <&pio 1 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ red4 {
+ label = "marsboard:red4:usr";
+ gpios = <&pio 1 8 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&ahci {
+ status = "okay";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&emac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_pins_a>;
+ phy = <&phy1>;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+};
+
+&mdio {
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&pio {
+ led_pins_marsboard: led_pins@0 {
+ allwinner,pins = "PB5", "PB6", "PB7", "PB8";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&reg_usb1_vbus {
+ status = "okay";
+};
+
+&reg_usb2_vbus {
+ status = "okay";
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins_a>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts
new file mode 100644
index 000000000..eb5fd6904
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "PineRiver Mini X-Plus";
+ compatible = "pineriver,mini-xplus", "allwinner,sun4i-a10";
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ ir0_pins_a: ir0@0 {
+ /* The ir receiver is not always populated */
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+ };
+
+ ir0: ir@01c21800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir0_pins_a>;
+ status = "okay";
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-mk802.dts b/arch/arm/boot/dts/sun4i-a10-mk802.dts
new file mode 100644
index 000000000..e9a6886f0
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-mk802.dts
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "MK802";
+ compatible = "allwinner,mk802", "allwinner,sun4i-a10";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&pio {
+ usb2_vbus_pin_mk802: usb2_vbus_pin@0 {
+ allwinner,pins = "PH12";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&reg_usb1_vbus {
+ status = "okay";
+};
+
+&reg_usb2_vbus {
+ pinctrl-0 = <&usb2_vbus_pin_mk802>;
+ gpio = <&pio 7 12 GPIO_ACTIVE_HIGH>; /* PH12 */
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-mk802ii.dts b/arch/arm/boot/dts/sun4i-a10-mk802ii.dts
new file mode 100644
index 000000000..802eda494
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-mk802ii.dts
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "MK802ii";
+ compatible = "allwinner,mk802ii", "allwinner,sun4i-a10";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&reg_usb1_vbus {
+ status = "okay";
+};
+
+&reg_usb2_vbus {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
new file mode 100644
index 000000000..75742f8f9
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2014 - Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Olimex A10-OLinuXino-LIME";
+ compatible = "olimex,a10-olinuxino-lime", "allwinner,sun4i-a10";
+
+ cpus {
+ cpu0: cpu@0 {
+ /*
+ * The A10-Lime is known to be unstable
+ * when running at 1008 MHz
+ */
+ operating-points = <
+ /* kHz uV */
+ 912000 1350000
+ 864000 1300000
+ 624000 1250000
+ >;
+ cooling-max-level = <2>;
+ };
+ };
+
+ soc@01c00000 {
+ emac: ethernet@01c0b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_pins_a>;
+ phy = <&phy1>;
+ status = "okay";
+ };
+
+ mdio@01c0b080 {
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ahci: sata@01c18000 {
+ target-supply = <&reg_ahci_5v>;
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ ahci_pwr_pin_olinuxinolime: ahci_pwr_pin@1 {
+ allwinner,pins = "PC3";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ led_pins_olinuxinolime: led_pins@0 {
+ allwinner,pins = "PH2";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_olinuxinolime>;
+
+ green {
+ label = "a10-olinuxino-lime:green:usr";
+ gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ reg_ahci_5v: ahci-5v {
+ pinctrl-0 = <&ahci_pwr_pin_olinuxinolime>;
+ gpio = <&pio 2 3 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-pcduino.dts b/arch/arm/boot/dts/sun4i-a10-pcduino.dts
new file mode 100644
index 000000000..9d1e5482c
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-pcduino.dts
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2014 Zoltan HERPAI
+ * Zoltan HERPAI <wigyori@uid0.hu>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "LinkSprite pcDuino";
+ compatible = "linksprite,a10-pcduino", "allwinner,sun4i-a10";
+
+ soc@01c00000 {
+ emac: ethernet@01c0b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_pins_a>;
+ phy = <&phy1>;
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ led_pins_pcduino: led_pins@0 {
+ allwinner,pins = "PH15", "PH16";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ key_pins_pcduino: key_pins@0 {
+ allwinner,pins = "PH17", "PH18", "PH19";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ mdio@01c0b080 {
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_pcduino>;
+
+ tx {
+ label = "pcduino:green:tx";
+ gpios = <&pio 7 15 GPIO_ACTIVE_LOW>;
+ };
+
+ rx {
+ label = "pcduino:green:rx";
+ gpios = <&pio 7 16 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&key_pins_pcduino>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@0 {
+ label = "Key Back";
+ linux,code = <KEY_BACK>;
+ gpios = <&pio 7 17 GPIO_ACTIVE_LOW>;
+ };
+
+ button@1 {
+ label = "Key Home";
+ linux,code = <KEY_HOME>;
+ gpios = <&pio 7 18 GPIO_ACTIVE_LOW>;
+ };
+
+ button@2 {
+ label = "Key Menu";
+ linux,code = <KEY_MENU>;
+ gpios = <&pio 7 19 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
new file mode 100644
index 000000000..eebb7853e
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -0,0 +1,968 @@
+/*
+ * Copyright 2012 Stefan Roese
+ * Stefan Roese <sr@denx.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
+ */
+
+#include "skeleton.dtsi"
+
+#include <dt-bindings/thermal/thermal.h>
+
+#include <dt-bindings/dma/sun4i-a10.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ interrupt-parent = <&intc>;
+
+ aliases {
+ ethernet0 = &emac;
+ };
+
+ chosen {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ framebuffer@0 {
+ compatible = "allwinner,simple-framebuffer", "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0-hdmi";
+ clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>,
+ <&ahb_gates 44>;
+ status = "disabled";
+ };
+
+ framebuffer@1 {
+ compatible = "allwinner,simple-framebuffer", "simple-framebuffer";
+ allwinner,pipeline = "de_fe0-de_be0-lcd0-hdmi";
+ clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>,
+ <&ahb_gates 44>, <&ahb_gates 46>;
+ status = "disabled";
+ };
+
+ framebuffer@2 {
+ compatible = "allwinner,simple-framebuffer",
+ "simple-framebuffer";
+ allwinner,pipeline = "de_fe0-de_be0-lcd0";
+ clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>,
+ <&ahb_gates 46>;
+ status = "disabled";
+ };
+
+ framebuffer@3 {
+ compatible = "allwinner,simple-framebuffer",
+ "simple-framebuffer";
+ allwinner,pipeline = "de_fe0-de_be0-lcd0-tve0";
+ clocks = <&pll5 1>, <&ahb_gates 34>, <&ahb_gates 36>,
+ <&ahb_gates 44>, <&ahb_gates 46>;
+ status = "disabled";
+ };
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a8";
+ reg = <0x0>;
+ clocks = <&cpu>;
+ clock-latency = <244144>; /* 8 32k periods */
+ operating-points = <
+ /* kHz uV */
+ 1008000 1400000
+ 912000 1350000
+ 864000 1300000
+ 624000 1250000
+ >;
+ #cooling-cells = <2>;
+ cooling-min-level = <0>;
+ cooling-max-level = <3>;
+ };
+ };
+
+ thermal-zones {
+ cpu_thermal {
+ /* milliseconds */
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&rtp>;
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
+ trips {
+ cpu_alert0: cpu_alert0 {
+ /* milliCelsius */
+ temperature = <850000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu_crit: cpu_crit {
+ /* milliCelsius */
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+ };
+
+ memory {
+ reg = <0x40000000 0x80000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /*
+ * This is a dummy clock, to be used as placeholder on
+ * other mux clocks when a specific parent clock is not
+ * yet implemented. It should be dropped when the driver
+ * is complete.
+ */
+ dummy: dummy {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ osc24M: clk@01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-osc-clk";
+ reg = <0x01c20050 0x4>;
+ clock-frequency = <24000000>;
+ clock-output-names = "osc24M";
+ };
+
+ osc32k: clk@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ clock-output-names = "osc32k";
+ };
+
+ pll1: clk@01c20000 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-pll1-clk";
+ reg = <0x01c20000 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll1";
+ };
+
+ pll4: clk@01c20018 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-pll1-clk";
+ reg = <0x01c20018 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll4";
+ };
+
+ pll5: clk@01c20020 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-pll5-clk";
+ reg = <0x01c20020 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll5_ddr", "pll5_other";
+ };
+
+ pll6: clk@01c20028 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-pll6-clk";
+ reg = <0x01c20028 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll6_sata", "pll6_other", "pll6";
+ };
+
+ /* dummy is 200M */
+ cpu: cpu@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-cpu-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
+ clock-output-names = "cpu";
+ };
+
+ axi: axi@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-axi-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&cpu>;
+ clock-output-names = "axi";
+ };
+
+ axi_gates: clk@01c2005c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-axi-gates-clk";
+ reg = <0x01c2005c 0x4>;
+ clocks = <&axi>;
+ clock-output-names = "axi_dram";
+ };
+
+ ahb: ahb@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-ahb-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&axi>;
+ clock-output-names = "ahb";
+ };
+
+ ahb_gates: clk@01c20060 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-ahb-gates-clk";
+ reg = <0x01c20060 0x8>;
+ clocks = <&ahb>;
+ clock-output-names = "ahb_usb0", "ahb_ehci0",
+ "ahb_ohci0", "ahb_ehci1", "ahb_ohci1", "ahb_ss",
+ "ahb_dma", "ahb_bist", "ahb_mmc0", "ahb_mmc1",
+ "ahb_mmc2", "ahb_mmc3", "ahb_ms", "ahb_nand",
+ "ahb_sdram", "ahb_ace", "ahb_emac", "ahb_ts",
+ "ahb_spi0", "ahb_spi1", "ahb_spi2", "ahb_spi3",
+ "ahb_pata", "ahb_sata", "ahb_gps", "ahb_ve",
+ "ahb_tvd", "ahb_tve0", "ahb_tve1", "ahb_lcd0",
+ "ahb_lcd1", "ahb_csi0", "ahb_csi1", "ahb_hdmi",
+ "ahb_de_be0", "ahb_de_be1", "ahb_de_fe0",
+ "ahb_de_fe1", "ahb_mp", "ahb_mali400";
+ };
+
+ apb0: apb0@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb0-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&ahb>;
+ clock-output-names = "apb0";
+ };
+
+ apb0_gates: clk@01c20068 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-apb0-gates-clk";
+ reg = <0x01c20068 0x4>;
+ clocks = <&apb0>;
+ clock-output-names = "apb0_codec", "apb0_spdif",
+ "apb0_ac97", "apb0_iis", "apb0_pio", "apb0_ir0",
+ "apb0_ir1", "apb0_keypad";
+ };
+
+ apb1: clk@01c20058 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb1-clk";
+ reg = <0x01c20058 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+ clock-output-names = "apb1";
+ };
+
+ apb1_gates: clk@01c2006c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-apb1-gates-clk";
+ reg = <0x01c2006c 0x4>;
+ clocks = <&apb1>;
+ clock-output-names = "apb1_i2c0", "apb1_i2c1",
+ "apb1_i2c2", "apb1_can", "apb1_scr",
+ "apb1_ps20", "apb1_ps21", "apb1_uart0",
+ "apb1_uart1", "apb1_uart2", "apb1_uart3",
+ "apb1_uart4", "apb1_uart5", "apb1_uart6",
+ "apb1_uart7";
+ };
+
+ nand_clk: clk@01c20080 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c20080 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "nand";
+ };
+
+ ms_clk: clk@01c20084 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c20084 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ms";
+ };
+
+ mmc0_clk: clk@01c20088 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20088 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "mmc0",
+ "mmc0_output",
+ "mmc0_sample";
+ };
+
+ mmc1_clk: clk@01c2008c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c2008c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "mmc1",
+ "mmc1_output",
+ "mmc1_sample";
+ };
+
+ mmc2_clk: clk@01c20090 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20090 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "mmc2",
+ "mmc2_output",
+ "mmc2_sample";
+ };
+
+ mmc3_clk: clk@01c20094 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20094 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "mmc3",
+ "mmc3_output",
+ "mmc3_sample";
+ };
+
+ ts_clk: clk@01c20098 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c20098 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ts";
+ };
+
+ ss_clk: clk@01c2009c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c2009c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ss";
+ };
+
+ spi0_clk: clk@01c200a0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200a0 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "spi0";
+ };
+
+ spi1_clk: clk@01c200a4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200a4 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "spi1";
+ };
+
+ spi2_clk: clk@01c200a8 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200a8 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "spi2";
+ };
+
+ pata_clk: clk@01c200ac {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200ac 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "pata";
+ };
+
+ ir0_clk: clk@01c200b0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200b0 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ir0";
+ };
+
+ ir1_clk: clk@01c200b4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200b4 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ir1";
+ };
+
+ usb_clk: clk@01c200cc {
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ compatible = "allwinner,sun4i-a10-usb-clk";
+ reg = <0x01c200cc 0x4>;
+ clocks = <&pll6 1>;
+ clock-output-names = "usb_ohci0", "usb_ohci1", "usb_phy";
+ };
+
+ spi3_clk: clk@01c200d4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200d4 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "spi3";
+ };
+ };
+
+ soc@01c00000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dma: dma-controller@01c02000 {
+ compatible = "allwinner,sun4i-a10-dma";
+ reg = <0x01c02000 0x1000>;
+ interrupts = <27>;
+ clocks = <&ahb_gates 6>;
+ #dma-cells = <2>;
+ };
+
+ spi0: spi@01c05000 {
+ compatible = "allwinner,sun4i-a10-spi";
+ reg = <0x01c05000 0x1000>;
+ interrupts = <10>;
+ clocks = <&ahb_gates 20>, <&spi0_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma SUN4I_DMA_DEDICATED 27>,
+ <&dma SUN4I_DMA_DEDICATED 26>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ spi1: spi@01c06000 {
+ compatible = "allwinner,sun4i-a10-spi";
+ reg = <0x01c06000 0x1000>;
+ interrupts = <11>;
+ clocks = <&ahb_gates 21>, <&spi1_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma SUN4I_DMA_DEDICATED 9>,
+ <&dma SUN4I_DMA_DEDICATED 8>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ emac: ethernet@01c0b000 {
+ compatible = "allwinner,sun4i-a10-emac";
+ reg = <0x01c0b000 0x1000>;
+ interrupts = <55>;
+ clocks = <&ahb_gates 17>;
+ status = "disabled";
+ };
+
+ mdio: mdio@01c0b080 {
+ compatible = "allwinner,sun4i-a10-mdio";
+ reg = <0x01c0b080 0x14>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ mmc0: mmc@01c0f000 {
+ compatible = "allwinner,sun4i-a10-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&ahb_gates 8>,
+ <&mmc0_clk 0>,
+ <&mmc0_clk 1>,
+ <&mmc0_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ interrupts = <32>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@01c10000 {
+ compatible = "allwinner,sun4i-a10-mmc";
+ reg = <0x01c10000 0x1000>;
+ clocks = <&ahb_gates 9>,
+ <&mmc1_clk 0>,
+ <&mmc1_clk 1>,
+ <&mmc1_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ interrupts = <33>;
+ status = "disabled";
+ };
+
+ mmc2: mmc@01c11000 {
+ compatible = "allwinner,sun4i-a10-mmc";
+ reg = <0x01c11000 0x1000>;
+ clocks = <&ahb_gates 10>,
+ <&mmc2_clk 0>,
+ <&mmc2_clk 1>,
+ <&mmc2_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ interrupts = <34>;
+ status = "disabled";
+ };
+
+ mmc3: mmc@01c12000 {
+ compatible = "allwinner,sun4i-a10-mmc";
+ reg = <0x01c12000 0x1000>;
+ clocks = <&ahb_gates 11>,
+ <&mmc3_clk 0>,
+ <&mmc3_clk 1>,
+ <&mmc3_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ interrupts = <35>;
+ status = "disabled";
+ };
+
+ usbphy: phy@01c13400 {
+ #phy-cells = <1>;
+ compatible = "allwinner,sun4i-a10-usb-phy";
+ reg = <0x01c13400 0x10 0x01c14800 0x4 0x01c1c800 0x4>;
+ reg-names = "phy_ctrl", "pmu1", "pmu2";
+ clocks = <&usb_clk 8>;
+ clock-names = "usb_phy";
+ resets = <&usb_clk 0>, <&usb_clk 1>, <&usb_clk 2>;
+ reset-names = "usb0_reset", "usb1_reset", "usb2_reset";
+ status = "disabled";
+ };
+
+ ehci0: usb@01c14000 {
+ compatible = "allwinner,sun4i-a10-ehci", "generic-ehci";
+ reg = <0x01c14000 0x100>;
+ interrupts = <39>;
+ clocks = <&ahb_gates 1>;
+ phys = <&usbphy 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ ohci0: usb@01c14400 {
+ compatible = "allwinner,sun4i-a10-ohci", "generic-ohci";
+ reg = <0x01c14400 0x100>;
+ interrupts = <64>;
+ clocks = <&usb_clk 6>, <&ahb_gates 2>;
+ phys = <&usbphy 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ spi2: spi@01c17000 {
+ compatible = "allwinner,sun4i-a10-spi";
+ reg = <0x01c17000 0x1000>;
+ interrupts = <12>;
+ clocks = <&ahb_gates 22>, <&spi2_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma SUN4I_DMA_DEDICATED 29>,
+ <&dma SUN4I_DMA_DEDICATED 28>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ ahci: sata@01c18000 {
+ compatible = "allwinner,sun4i-a10-ahci";
+ reg = <0x01c18000 0x1000>;
+ interrupts = <56>;
+ clocks = <&pll6 0>, <&ahb_gates 25>;
+ status = "disabled";
+ };
+
+ ehci1: usb@01c1c000 {
+ compatible = "allwinner,sun4i-a10-ehci", "generic-ehci";
+ reg = <0x01c1c000 0x100>;
+ interrupts = <40>;
+ clocks = <&ahb_gates 3>;
+ phys = <&usbphy 2>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ ohci1: usb@01c1c400 {
+ compatible = "allwinner,sun4i-a10-ohci", "generic-ohci";
+ reg = <0x01c1c400 0x100>;
+ interrupts = <65>;
+ clocks = <&usb_clk 7>, <&ahb_gates 4>;
+ phys = <&usbphy 2>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ spi3: spi@01c1f000 {
+ compatible = "allwinner,sun4i-a10-spi";
+ reg = <0x01c1f000 0x1000>;
+ interrupts = <50>;
+ clocks = <&ahb_gates 23>, <&spi3_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma SUN4I_DMA_DEDICATED 31>,
+ <&dma SUN4I_DMA_DEDICATED 30>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ intc: interrupt-controller@01c20400 {
+ compatible = "allwinner,sun4i-a10-ic";
+ reg = <0x01c20400 0x400>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ pio: pinctrl@01c20800 {
+ compatible = "allwinner,sun4i-a10-pinctrl";
+ reg = <0x01c20800 0x400>;
+ interrupts = <28>;
+ clocks = <&apb0_gates 5>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ #size-cells = <0>;
+ #gpio-cells = <3>;
+
+ pwm0_pins_a: pwm0@0 {
+ allwinner,pins = "PB2";
+ allwinner,function = "pwm";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ pwm1_pins_a: pwm1@0 {
+ allwinner,pins = "PI3";
+ allwinner,function = "pwm";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart0_pins_a: uart0@0 {
+ allwinner,pins = "PB22", "PB23";
+ allwinner,function = "uart0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart0_pins_b: uart0@1 {
+ allwinner,pins = "PF2", "PF4";
+ allwinner,function = "uart0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart1_pins_a: uart1@0 {
+ allwinner,pins = "PA10", "PA11";
+ allwinner,function = "uart1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c0_pins_a: i2c0@0 {
+ allwinner,pins = "PB0", "PB1";
+ allwinner,function = "i2c0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c1_pins_a: i2c1@0 {
+ allwinner,pins = "PB18", "PB19";
+ allwinner,function = "i2c1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c2_pins_a: i2c2@0 {
+ allwinner,pins = "PB20", "PB21";
+ allwinner,function = "i2c2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ emac_pins_a: emac0@0 {
+ allwinner,pins = "PA0", "PA1", "PA2",
+ "PA3", "PA4", "PA5", "PA6",
+ "PA7", "PA8", "PA9", "PA10",
+ "PA11", "PA12", "PA13", "PA14",
+ "PA15", "PA16";
+ allwinner,function = "emac";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_pins_a: mmc0@0 {
+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_cd_pin_reference_design: mmc0_cd_pin@0 {
+ allwinner,pins = "PH1";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ ir0_pins_a: ir0@0 {
+ allwinner,pins = "PB3","PB4";
+ allwinner,function = "ir0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ ir1_pins_a: ir1@0 {
+ allwinner,pins = "PB22","PB23";
+ allwinner,function = "ir1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ spi0_pins_a: spi0@0 {
+ allwinner,pins = "PI10", "PI11", "PI12", "PI13";
+ allwinner,function = "spi0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ spi1_pins_a: spi1@0 {
+ allwinner,pins = "PI16", "PI17", "PI18", "PI19";
+ allwinner,function = "spi1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ spi2_pins_a: spi2@0 {
+ allwinner,pins = "PB14", "PB15", "PB16", "PB17";
+ allwinner,function = "spi2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ spi2_pins_b: spi2@1 {
+ allwinner,pins = "PC19", "PC20", "PC21", "PC22";
+ allwinner,function = "spi2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ ps20_pins_a: ps20@0 {
+ allwinner,pins = "PI20", "PI21";
+ allwinner,function = "ps2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ ps21_pins_a: ps21@0 {
+ allwinner,pins = "PH12", "PH13";
+ allwinner,function = "ps2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ timer@01c20c00 {
+ compatible = "allwinner,sun4i-a10-timer";
+ reg = <0x01c20c00 0x90>;
+ interrupts = <22>;
+ clocks = <&osc24M>;
+ };
+
+ wdt: watchdog@01c20c90 {
+ compatible = "allwinner,sun4i-a10-wdt";
+ reg = <0x01c20c90 0x10>;
+ };
+
+ rtc: rtc@01c20d00 {
+ compatible = "allwinner,sun4i-a10-rtc";
+ reg = <0x01c20d00 0x20>;
+ interrupts = <24>;
+ };
+
+ pwm: pwm@01c20e00 {
+ compatible = "allwinner,sun4i-a10-pwm";
+ reg = <0x01c20e00 0xc>;
+ clocks = <&osc24M>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ ir0: ir@01c21800 {
+ compatible = "allwinner,sun4i-a10-ir";
+ clocks = <&apb0_gates 6>, <&ir0_clk>;
+ clock-names = "apb", "ir";
+ interrupts = <5>;
+ reg = <0x01c21800 0x40>;
+ status = "disabled";
+ };
+
+ ir1: ir@01c21c00 {
+ compatible = "allwinner,sun4i-a10-ir";
+ clocks = <&apb0_gates 7>, <&ir1_clk>;
+ clock-names = "apb", "ir";
+ interrupts = <6>;
+ reg = <0x01c21c00 0x40>;
+ status = "disabled";
+ };
+
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-a10-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <31>;
+ status = "disabled";
+ };
+
+ sid: eeprom@01c23800 {
+ compatible = "allwinner,sun4i-a10-sid";
+ reg = <0x01c23800 0x10>;
+ };
+
+ rtp: rtp@01c25000 {
+ compatible = "allwinner,sun4i-a10-ts";
+ reg = <0x01c25000 0x100>;
+ interrupts = <29>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ uart0: serial@01c28000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28000 0x400>;
+ interrupts = <1>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 16>;
+ status = "disabled";
+ };
+
+ uart1: serial@01c28400 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28400 0x400>;
+ interrupts = <2>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 17>;
+ status = "disabled";
+ };
+
+ uart2: serial@01c28800 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28800 0x400>;
+ interrupts = <3>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 18>;
+ status = "disabled";
+ };
+
+ uart3: serial@01c28c00 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28c00 0x400>;
+ interrupts = <4>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 19>;
+ status = "disabled";
+ };
+
+ uart4: serial@01c29000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c29000 0x400>;
+ interrupts = <17>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 20>;
+ status = "disabled";
+ };
+
+ uart5: serial@01c29400 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c29400 0x400>;
+ interrupts = <18>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 21>;
+ status = "disabled";
+ };
+
+ uart6: serial@01c29800 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c29800 0x400>;
+ interrupts = <19>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 22>;
+ status = "disabled";
+ };
+
+ uart7: serial@01c29c00 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c29c00 0x400>;
+ interrupts = <20>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 23>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ compatible = "allwinner,sun4i-a10-i2c";
+ reg = <0x01c2ac00 0x400>;
+ interrupts = <7>;
+ clocks = <&apb1_gates 0>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c1: i2c@01c2b000 {
+ compatible = "allwinner,sun4i-a10-i2c";
+ reg = <0x01c2b000 0x400>;
+ interrupts = <8>;
+ clocks = <&apb1_gates 1>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c2: i2c@01c2b400 {
+ compatible = "allwinner,sun4i-a10-i2c";
+ reg = <0x01c2b400 0x400>;
+ interrupts = <9>;
+ clocks = <&apb1_gates 2>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ ps20: ps2@01c2a000 {
+ compatible = "allwinner,sun4i-a10-ps2";
+ reg = <0x01c2a000 0x400>;
+ interrupts = <62>;
+ clocks = <&apb1_gates 6>;
+ status = "disabled";
+ };
+
+ ps21: ps2@01c2a400 {
+ compatible = "allwinner,sun4i-a10-ps2";
+ reg = <0x01c2a400 0x400>;
+ interrupts = <63>;
+ clocks = <&apb1_gates 7>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sun5i-a10s-mk802.dts b/arch/arm/boot/dts/sun5i-a10s-mk802.dts
new file mode 100644
index 000000000..b21af87d9
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a10s-mk802.dts
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun5i-a10s.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "MK802-A10s";
+ compatible = "allwinner,a10s-mk802", "allwinner,sun5i-a10s";
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_mk802>;
+
+ red {
+ label = "mk802:red:usr";
+ gpios = <&pio 1 2 GPIO_ACTIVE_HIGH>; /* PB2 */
+ };
+ };
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_mk802>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+ cd-inverted;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&pio {
+ led_pins_mk802: led_pins@0 {
+ allwinner,pins = "PB2";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_cd_pin_mk802: mmc0_cd_pin@0 {
+ allwinner,pins = "PG1";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ usb1_vbus_pin_mk802: usb1_vbus_pin@0 {
+ allwinner,pins = "PB10";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&reg_usb1_vbus {
+ pinctrl-0 = <&usb1_vbus_pin_mk802>;
+ gpio = <&pio 1 10 GPIO_ACTIVE_HIGH>; /* PB10 */
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
new file mode 100644
index 000000000..2bbc93b93
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2013 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun5i-a10s.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Olimex A10s-Olinuxino Micro";
+ compatible = "olimex,a10s-olinuxino-micro", "allwinner,sun5i-a10s";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ };
+
+ soc@01c00000 {
+ emac: ethernet@01c0b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_pins_a>;
+ phy = <&phy1>;
+ status = "okay";
+ };
+
+ mdio@01c0b080 {
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_olinuxino_micro>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ mmc1: mmc@01c10000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins_a>, <&mmc1_cd_pin_olinuxino_micro>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 6 13 GPIO_ACTIVE_HIGH>; /* PG13 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ mmc0_cd_pin_olinuxino_micro: mmc0_cd_pin@0 {
+ allwinner,pins = "PG1";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ mmc1_cd_pin_olinuxino_micro: mmc1_cd_pin@0 {
+ allwinner,pins = "PG13";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ led_pins_olinuxino: led_pins@0 {
+ allwinner,pins = "PE3";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ usb1_vbus_pin_olinuxino_m: usb1_vbus_pin@0 {
+ allwinner,pins = "PB10";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ lradc: lradc@01c22800 {
+ vref-supply = <&reg_vcc3v0>;
+ status = "okay";
+
+ button@191 {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ channel = <0>;
+ voltage = <191274>;
+ };
+
+ button@392 {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ channel = <0>;
+ voltage = <392644>;
+ };
+
+ button@601 {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ channel = <0>;
+ voltage = <601151>;
+ };
+
+ button@795 {
+ label = "Enter";
+ linux,code = <KEY_ENTER>;
+ channel = <0>;
+ voltage = <795090>;
+ };
+
+ button@987 {
+ label = "Home";
+ linux,code = <KEY_HOMEPAGE>;
+ channel = <0>;
+ voltage = <987387>;
+ };
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ uart2: serial@01c28800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins_a>;
+ status = "okay";
+ };
+
+ uart3: serial@01c28c00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+
+ at24@50 {
+ compatible = "at,24c16";
+ pagesize = <16>;
+ reg = <0x50>;
+ read-only;
+ };
+ };
+
+ i2c2: i2c@01c2b400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_olinuxino>;
+
+ green {
+ label = "a10s-olinuxino-micro:green:usr";
+ gpios = <&pio 4 3 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ pinctrl-0 = <&usb1_vbus_pin_olinuxino_m>;
+ gpio = <&pio 1 10 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun5i-a10s-r7-tv-dongle.dts b/arch/arm/boot/dts/sun5i-a10s-r7-tv-dongle.dts
new file mode 100644
index 000000000..7deddfc9d
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a10s-r7-tv-dongle.dts
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun5i-a10s.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "R7 A10s hdmi tv-stick";
+ compatible = "allwinner,r7-tv-dongle", "allwinner,sun5i-a10s";
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_r7>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ mmc1: mmc@01c10000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins_a>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ mmc0_cd_pin_r7: mmc0_cd_pin@0 {
+ allwinner,pins = "PG1";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ led_pins_r7: led_pins@0 {
+ allwinner,pins = "PB2";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ usb1_vbus_pin_r7: usb1_vbus_pin@0 {
+ allwinner,pins = "PG13";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_r7>;
+
+ green {
+ label = "r7-tv-dongle:green:usr";
+ gpios = <&pio 1 2 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ pinctrl-0 = <&usb1_vbus_pin_r7>;
+ gpio = <&pio 6 13 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
new file mode 100644
index 000000000..3794ca164
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -0,0 +1,659 @@
+/*
+ * Copyright 2013 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.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 "skeleton.dtsi"
+
+#include <dt-bindings/dma/sun4i-a10.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ interrupt-parent = <&intc>;
+
+ aliases {
+ ethernet0 = &emac;
+ };
+
+ chosen {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ framebuffer@0 {
+ compatible = "allwinner,simple-framebuffer", "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0-hdmi";
+ clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>,
+ <&ahb_gates 44>;
+ status = "disabled";
+ };
+
+ framebuffer@1 {
+ compatible = "allwinner,simple-framebuffer",
+ "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0";
+ clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>;
+ status = "disabled";
+ };
+ };
+
+ cpus {
+ cpu@0 {
+ compatible = "arm,cortex-a8";
+ };
+ };
+
+ memory {
+ reg = <0x40000000 0x20000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /*
+ * This is a dummy clock, to be used as placeholder on
+ * other mux clocks when a specific parent clock is not
+ * yet implemented. It should be dropped when the driver
+ * is complete.
+ */
+ dummy: dummy {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ osc24M: clk@01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-osc-clk";
+ reg = <0x01c20050 0x4>;
+ clock-frequency = <24000000>;
+ clock-output-names = "osc24M";
+ };
+
+ osc32k: clk@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ clock-output-names = "osc32k";
+ };
+
+ pll1: clk@01c20000 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-pll1-clk";
+ reg = <0x01c20000 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll1";
+ };
+
+ pll4: clk@01c20018 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-pll1-clk";
+ reg = <0x01c20018 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll4";
+ };
+
+ pll5: clk@01c20020 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-pll5-clk";
+ reg = <0x01c20020 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll5_ddr", "pll5_other";
+ };
+
+ pll6: clk@01c20028 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-pll6-clk";
+ reg = <0x01c20028 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll6_sata", "pll6_other", "pll6";
+ };
+
+ /* dummy is 200M */
+ cpu: cpu@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-cpu-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
+ clock-output-names = "cpu";
+ };
+
+ axi: axi@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-axi-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&cpu>;
+ clock-output-names = "axi";
+ };
+
+ axi_gates: clk@01c2005c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-axi-gates-clk";
+ reg = <0x01c2005c 0x4>;
+ clocks = <&axi>;
+ clock-output-names = "axi_dram";
+ };
+
+ ahb: ahb@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-ahb-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&axi>;
+ clock-output-names = "ahb";
+ };
+
+ ahb_gates: clk@01c20060 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun5i-a10s-ahb-gates-clk";
+ reg = <0x01c20060 0x8>;
+ clocks = <&ahb>;
+ clock-output-names = "ahb_usbotg", "ahb_ehci", "ahb_ohci",
+ "ahb_ss", "ahb_dma", "ahb_bist", "ahb_mmc0",
+ "ahb_mmc1", "ahb_mmc2", "ahb_nand", "ahb_sdram",
+ "ahb_emac", "ahb_ts", "ahb_spi0", "ahb_spi1",
+ "ahb_spi2", "ahb_gps", "ahb_stimer", "ahb_ve",
+ "ahb_tve", "ahb_lcd", "ahb_csi", "ahb_hdmi",
+ "ahb_de_be", "ahb_de_fe", "ahb_iep", "ahb_mali400";
+ };
+
+ apb0: apb0@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb0-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&ahb>;
+ clock-output-names = "apb0";
+ };
+
+ apb0_gates: clk@01c20068 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun5i-a10s-apb0-gates-clk";
+ reg = <0x01c20068 0x4>;
+ clocks = <&apb0>;
+ clock-output-names = "apb0_codec", "apb0_iis", "apb0_pio",
+ "apb0_ir", "apb0_keypad";
+ };
+
+ apb1: clk@01c20058 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb1-clk";
+ reg = <0x01c20058 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+ clock-output-names = "apb1";
+ };
+
+ apb1_gates: clk@01c2006c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun5i-a10s-apb1-gates-clk";
+ reg = <0x01c2006c 0x4>;
+ clocks = <&apb1>;
+ clock-output-names = "apb1_i2c0", "apb1_i2c1",
+ "apb1_i2c2", "apb1_uart0", "apb1_uart1",
+ "apb1_uart2", "apb1_uart3";
+ };
+
+ nand_clk: clk@01c20080 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c20080 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "nand";
+ };
+
+ ms_clk: clk@01c20084 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c20084 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ms";
+ };
+
+ mmc0_clk: clk@01c20088 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20088 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "mmc0",
+ "mmc0_output",
+ "mmc0_sample";
+ };
+
+ mmc1_clk: clk@01c2008c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c2008c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "mmc1",
+ "mmc1_output",
+ "mmc1_sample";
+ };
+
+ mmc2_clk: clk@01c20090 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20090 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "mmc2",
+ "mmc2_output",
+ "mmc2_sample";
+ };
+
+ ts_clk: clk@01c20098 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c20098 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ts";
+ };
+
+ ss_clk: clk@01c2009c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c2009c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ss";
+ };
+
+ spi0_clk: clk@01c200a0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200a0 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "spi0";
+ };
+
+ spi1_clk: clk@01c200a4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200a4 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "spi1";
+ };
+
+ spi2_clk: clk@01c200a8 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200a8 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "spi2";
+ };
+
+ ir0_clk: clk@01c200b0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200b0 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ir0";
+ };
+
+ usb_clk: clk@01c200cc {
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ compatible = "allwinner,sun5i-a13-usb-clk";
+ reg = <0x01c200cc 0x4>;
+ clocks = <&pll6 1>;
+ clock-output-names = "usb_ohci0", "usb_phy";
+ };
+
+ mbus_clk: clk@01c2015c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun5i-a13-mbus-clk";
+ reg = <0x01c2015c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "mbus";
+ };
+ };
+
+ soc@01c00000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dma: dma-controller@01c02000 {
+ compatible = "allwinner,sun4i-a10-dma";
+ reg = <0x01c02000 0x1000>;
+ interrupts = <27>;
+ clocks = <&ahb_gates 6>;
+ #dma-cells = <2>;
+ };
+
+ spi0: spi@01c05000 {
+ compatible = "allwinner,sun4i-a10-spi";
+ reg = <0x01c05000 0x1000>;
+ interrupts = <10>;
+ clocks = <&ahb_gates 20>, <&spi0_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma SUN4I_DMA_DEDICATED 27>,
+ <&dma SUN4I_DMA_DEDICATED 26>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ spi1: spi@01c06000 {
+ compatible = "allwinner,sun4i-a10-spi";
+ reg = <0x01c06000 0x1000>;
+ interrupts = <11>;
+ clocks = <&ahb_gates 21>, <&spi1_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma SUN4I_DMA_DEDICATED 9>,
+ <&dma SUN4I_DMA_DEDICATED 8>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ emac: ethernet@01c0b000 {
+ compatible = "allwinner,sun4i-a10-emac";
+ reg = <0x01c0b000 0x1000>;
+ interrupts = <55>;
+ clocks = <&ahb_gates 17>;
+ status = "disabled";
+ };
+
+ mdio: mdio@01c0b080 {
+ compatible = "allwinner,sun4i-a10-mdio";
+ reg = <0x01c0b080 0x14>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ mmc0: mmc@01c0f000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&ahb_gates 8>,
+ <&mmc0_clk 0>,
+ <&mmc0_clk 1>,
+ <&mmc0_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ interrupts = <32>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@01c10000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c10000 0x1000>;
+ clocks = <&ahb_gates 9>,
+ <&mmc1_clk 0>,
+ <&mmc1_clk 1>,
+ <&mmc1_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ interrupts = <33>;
+ status = "disabled";
+ };
+
+ mmc2: mmc@01c11000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c11000 0x1000>;
+ clocks = <&ahb_gates 10>,
+ <&mmc2_clk 0>,
+ <&mmc2_clk 1>,
+ <&mmc2_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ interrupts = <34>;
+ status = "disabled";
+ };
+
+ usbphy: phy@01c13400 {
+ #phy-cells = <1>;
+ compatible = "allwinner,sun5i-a13-usb-phy";
+ reg = <0x01c13400 0x10 0x01c14800 0x4>;
+ reg-names = "phy_ctrl", "pmu1";
+ clocks = <&usb_clk 8>;
+ clock-names = "usb_phy";
+ resets = <&usb_clk 0>, <&usb_clk 1>;
+ reset-names = "usb0_reset", "usb1_reset";
+ status = "disabled";
+ };
+
+ ehci0: usb@01c14000 {
+ compatible = "allwinner,sun5i-a10s-ehci", "generic-ehci";
+ reg = <0x01c14000 0x100>;
+ interrupts = <39>;
+ clocks = <&ahb_gates 1>;
+ phys = <&usbphy 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ ohci0: usb@01c14400 {
+ compatible = "allwinner,sun5i-a10s-ohci", "generic-ohci";
+ reg = <0x01c14400 0x100>;
+ interrupts = <40>;
+ clocks = <&usb_clk 6>, <&ahb_gates 2>;
+ phys = <&usbphy 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ spi2: spi@01c17000 {
+ compatible = "allwinner,sun4i-a10-spi";
+ reg = <0x01c17000 0x1000>;
+ interrupts = <12>;
+ clocks = <&ahb_gates 22>, <&spi2_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma SUN4I_DMA_DEDICATED 29>,
+ <&dma SUN4I_DMA_DEDICATED 28>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ intc: interrupt-controller@01c20400 {
+ compatible = "allwinner,sun4i-a10-ic";
+ reg = <0x01c20400 0x400>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ pio: pinctrl@01c20800 {
+ compatible = "allwinner,sun5i-a10s-pinctrl";
+ reg = <0x01c20800 0x400>;
+ interrupts = <28>;
+ clocks = <&apb0_gates 5>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ #size-cells = <0>;
+ #gpio-cells = <3>;
+
+ uart0_pins_a: uart0@0 {
+ allwinner,pins = "PB19", "PB20";
+ allwinner,function = "uart0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart2_pins_a: uart2@0 {
+ allwinner,pins = "PC18", "PC19";
+ allwinner,function = "uart2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart3_pins_a: uart3@0 {
+ allwinner,pins = "PG9", "PG10";
+ allwinner,function = "uart3";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ emac_pins_a: emac0@0 {
+ allwinner,pins = "PA0", "PA1", "PA2",
+ "PA3", "PA4", "PA5", "PA6",
+ "PA7", "PA8", "PA9", "PA10",
+ "PA11", "PA12", "PA13", "PA14",
+ "PA15", "PA16";
+ allwinner,function = "emac";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c0_pins_a: i2c0@0 {
+ allwinner,pins = "PB0", "PB1";
+ allwinner,function = "i2c0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c1_pins_a: i2c1@0 {
+ allwinner,pins = "PB15", "PB16";
+ allwinner,function = "i2c1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c2_pins_a: i2c2@0 {
+ allwinner,pins = "PB17", "PB18";
+ allwinner,function = "i2c2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_pins_a: mmc0@0 {
+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc1_pins_a: mmc1@0 {
+ allwinner,pins = "PG3","PG4","PG5","PG6","PG7","PG8";
+ allwinner,function = "mmc1";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ timer@01c20c00 {
+ compatible = "allwinner,sun4i-a10-timer";
+ reg = <0x01c20c00 0x90>;
+ interrupts = <22>;
+ clocks = <&osc24M>;
+ };
+
+ wdt: watchdog@01c20c90 {
+ compatible = "allwinner,sun4i-a10-wdt";
+ reg = <0x01c20c90 0x10>;
+ };
+
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-a10-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <31>;
+ status = "disabled";
+ };
+
+ sid: eeprom@01c23800 {
+ compatible = "allwinner,sun4i-a10-sid";
+ reg = <0x01c23800 0x10>;
+ };
+
+ rtp: rtp@01c25000 {
+ compatible = "allwinner,sun5i-a13-ts";
+ reg = <0x01c25000 0x100>;
+ interrupts = <29>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ uart0: serial@01c28000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28000 0x400>;
+ interrupts = <1>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 16>;
+ status = "disabled";
+ };
+
+ uart1: serial@01c28400 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28400 0x400>;
+ interrupts = <2>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 17>;
+ status = "disabled";
+ };
+
+ uart2: serial@01c28800 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28800 0x400>;
+ interrupts = <3>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 18>;
+ status = "disabled";
+ };
+
+ uart3: serial@01c28c00 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28c00 0x400>;
+ interrupts = <4>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 19>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "allwinner,sun5i-a10s-i2c", "allwinner,sun4i-a10-i2c";
+ reg = <0x01c2ac00 0x400>;
+ interrupts = <7>;
+ clocks = <&apb1_gates 0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@01c2b000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "allwinner,sun5i-a10s-i2c", "allwinner,sun4i-a10-i2c";
+ reg = <0x01c2b000 0x400>;
+ interrupts = <8>;
+ clocks = <&apb1_gates 1>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@01c2b400 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "allwinner,sun5i-a10s-i2c", "allwinner,sun4i-a10-i2c";
+ reg = <0x01c2b400 0x400>;
+ interrupts = <9>;
+ clocks = <&apb1_gates 2>;
+ status = "disabled";
+ };
+
+ timer@01c60000 {
+ compatible = "allwinner,sun5i-a13-hstimer";
+ reg = <0x01c60000 0x1000>;
+ interrupts = <82>, <83>;
+ clocks = <&ahb_gates 28>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts b/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts
new file mode 100644
index 000000000..03aa04555
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2014 Chen-Yu Tsai <wens@csie.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun5i-a13.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "HSG H702";
+ compatible = "hsg,h702", "allwinner,sun5i-a13";
+
+ aliases {
+ serial0 = &uart1;
+ };
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_h702>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_ldo3>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ mmc0_cd_pin_h702: mmc0_cd_pin@0 {
+ allwinner,pins = "PG0";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+ };
+
+ uart1: serial@01c28400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_b>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ reg = <0x34>;
+ interrupts = <0>;
+ };
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+
+ pcf8563: rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+ };
+
+ i2c2: i2c@01c2b400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+ };
+ };
+};
+
+#include "axp209.dtsi"
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+ regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "avcc";
+};
+
+&reg_ldo3 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi";
+};
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
new file mode 100644
index 000000000..03deb8426
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2012 Maxime Ripard <maxime.ripard@free-electrons.com>
+ * Copyright 2013 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun5i-a13.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Olimex A13-Olinuxino Micro";
+ compatible = "olimex,a13-olinuxino-micro", "allwinner,sun5i-a13";
+
+ aliases {
+ serial0 = &uart1;
+ };
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_olinuxinom>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ mmc0_cd_pin_olinuxinom: mmc0_cd_pin@0 {
+ allwinner,pins = "PG0";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ led_pins_olinuxinom: led_pins@0 {
+ allwinner,pins = "PG9";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ usb1_vbus_pin_olinuxinom: usb1_vbus_pin@0 {
+ allwinner,pins = "PG11";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ uart1: serial@01c28400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_b>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
+
+ i2c2: i2c@01c2b400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_olinuxinom>;
+
+ power {
+ label = "a13-olinuxino-micro:green:power";
+ gpios = <&pio 6 9 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ pinctrl-0 = <&usb1_vbus_pin_olinuxinom>;
+ gpio = <&pio 6 11 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
new file mode 100644
index 000000000..6b24876ed
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun5i-a13.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Olimex A13-Olinuxino";
+ compatible = "olimex,a13-olinuxino", "allwinner,sun5i-a13";
+
+ aliases {
+ serial0 = &uart1;
+ };
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_olinuxino>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ mmc0_cd_pin_olinuxino: mmc0_cd_pin@0 {
+ allwinner,pins = "PG0";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ led_pins_olinuxino: led_pins@0 {
+ allwinner,pins = "PG9";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ usb1_vbus_pin_olinuxino: usb1_vbus_pin@0 {
+ allwinner,pins = "PG11";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ lradc: lradc@01c22800 {
+ vref-supply = <&reg_vcc3v0>;
+ status = "okay";
+
+ button@191 {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ channel = <0>;
+ voltage = <191274>;
+ };
+
+ button@392 {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ channel = <0>;
+ voltage = <392644>;
+ };
+
+ button@601 {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ channel = <0>;
+ voltage = <601151>;
+ };
+
+ button@795 {
+ label = "Enter";
+ linux,code = <KEY_ENTER>;
+ channel = <0>;
+ voltage = <795090>;
+ };
+
+ button@987 {
+ label = "Home";
+ linux,code = <KEY_HOMEPAGE>;
+ channel = <0>;
+ voltage = <987387>;
+ };
+ };
+
+ uart1: serial@01c28400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_b>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
+
+ i2c2: i2c@01c2b400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_olinuxino>;
+
+ power {
+ gpios = <&pio 6 9 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ pinctrl-0 = <&usb1_vbus_pin_olinuxino>;
+ gpio = <&pio 6 11 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
new file mode 100644
index 000000000..5098185ab
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -0,0 +1,621 @@
+/*
+ * Copyright 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.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 "skeleton.dtsi"
+
+#include <dt-bindings/thermal/thermal.h>
+
+#include <dt-bindings/dma/sun4i-a10.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ interrupt-parent = <&intc>;
+
+ chosen {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ framebuffer@0 {
+ compatible = "allwinner,simple-framebuffer",
+ "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0";
+ clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>;
+ status = "disabled";
+ };
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a8";
+ reg = <0x0>;
+ clocks = <&cpu>;
+ clock-latency = <244144>; /* 8 32k periods */
+ operating-points = <
+ /* kHz uV */
+ 1008000 1400000
+ 912000 1350000
+ 864000 1300000
+ 624000 1200000
+ 576000 1200000
+ 432000 1200000
+ >;
+ #cooling-cells = <2>;
+ cooling-min-level = <0>;
+ cooling-max-level = <5>;
+ };
+ };
+
+ thermal-zones {
+ cpu_thermal {
+ /* milliseconds */
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&rtp>;
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
+ trips {
+ cpu_alert0: cpu_alert0 {
+ /* milliCelsius */
+ temperature = <850000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu_crit: cpu_crit {
+ /* milliCelsius */
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+ };
+
+ memory {
+ reg = <0x40000000 0x20000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /*
+ * This is a dummy clock, to be used as placeholder on
+ * other mux clocks when a specific parent clock is not
+ * yet implemented. It should be dropped when the driver
+ * is complete.
+ */
+ dummy: dummy {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ osc24M: clk@01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-osc-clk";
+ reg = <0x01c20050 0x4>;
+ clock-frequency = <24000000>;
+ clock-output-names = "osc24M";
+ };
+
+ osc32k: clk@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ clock-output-names = "osc32k";
+ };
+
+ pll1: clk@01c20000 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-pll1-clk";
+ reg = <0x01c20000 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll1";
+ };
+
+ pll4: clk@01c20018 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-pll1-clk";
+ reg = <0x01c20018 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll4";
+ };
+
+ pll5: clk@01c20020 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-pll5-clk";
+ reg = <0x01c20020 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll5_ddr", "pll5_other";
+ };
+
+ pll6: clk@01c20028 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-pll6-clk";
+ reg = <0x01c20028 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll6_sata", "pll6_other", "pll6";
+ };
+
+ /* dummy is 200M */
+ cpu: cpu@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-cpu-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
+ clock-output-names = "cpu";
+ };
+
+ axi: axi@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-axi-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&cpu>;
+ clock-output-names = "axi";
+ };
+
+ axi_gates: clk@01c2005c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-axi-gates-clk";
+ reg = <0x01c2005c 0x4>;
+ clocks = <&axi>;
+ clock-output-names = "axi_dram";
+ };
+
+ ahb: ahb@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-ahb-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&axi>;
+ clock-output-names = "ahb";
+ };
+
+ ahb_gates: clk@01c20060 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun5i-a13-ahb-gates-clk";
+ reg = <0x01c20060 0x8>;
+ clocks = <&ahb>;
+ clock-output-names = "ahb_usbotg", "ahb_ehci", "ahb_ohci",
+ "ahb_ss", "ahb_dma", "ahb_bist", "ahb_mmc0",
+ "ahb_mmc1", "ahb_mmc2", "ahb_nand", "ahb_sdram",
+ "ahb_spi0", "ahb_spi1", "ahb_spi2", "ahb_stimer",
+ "ahb_ve", "ahb_lcd", "ahb_csi", "ahb_de_be",
+ "ahb_de_fe", "ahb_iep", "ahb_mali400";
+ };
+
+ apb0: apb0@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb0-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&ahb>;
+ clock-output-names = "apb0";
+ };
+
+ apb0_gates: clk@01c20068 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun5i-a13-apb0-gates-clk";
+ reg = <0x01c20068 0x4>;
+ clocks = <&apb0>;
+ clock-output-names = "apb0_codec", "apb0_pio", "apb0_ir";
+ };
+
+ apb1: clk@01c20058 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb1-clk";
+ reg = <0x01c20058 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+ clock-output-names = "apb1";
+ };
+
+ apb1_gates: clk@01c2006c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun5i-a13-apb1-gates-clk";
+ reg = <0x01c2006c 0x4>;
+ clocks = <&apb1>;
+ clock-output-names = "apb1_i2c0", "apb1_i2c1",
+ "apb1_i2c2", "apb1_uart1", "apb1_uart3";
+ };
+
+ nand_clk: clk@01c20080 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c20080 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "nand";
+ };
+
+ ms_clk: clk@01c20084 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c20084 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ms";
+ };
+
+ mmc0_clk: clk@01c20088 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20088 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "mmc0",
+ "mmc0_output",
+ "mmc0_sample";
+ };
+
+ mmc1_clk: clk@01c2008c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c2008c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "mmc1",
+ "mmc1_output",
+ "mmc1_sample";
+ };
+
+ mmc2_clk: clk@01c20090 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20090 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "mmc2",
+ "mmc2_output",
+ "mmc2_sample";
+ };
+
+ ts_clk: clk@01c20098 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c20098 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ts";
+ };
+
+ ss_clk: clk@01c2009c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c2009c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ss";
+ };
+
+ spi0_clk: clk@01c200a0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200a0 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "spi0";
+ };
+
+ spi1_clk: clk@01c200a4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200a4 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "spi1";
+ };
+
+ spi2_clk: clk@01c200a8 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200a8 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "spi2";
+ };
+
+ ir0_clk: clk@01c200b0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200b0 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ir0";
+ };
+
+ usb_clk: clk@01c200cc {
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ compatible = "allwinner,sun5i-a13-usb-clk";
+ reg = <0x01c200cc 0x4>;
+ clocks = <&pll6 1>;
+ clock-output-names = "usb_ohci0", "usb_phy";
+ };
+
+ mbus_clk: clk@01c2015c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun5i-a13-mbus-clk";
+ reg = <0x01c2015c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "mbus";
+ };
+ };
+
+ soc@01c00000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dma: dma-controller@01c02000 {
+ compatible = "allwinner,sun4i-a10-dma";
+ reg = <0x01c02000 0x1000>;
+ interrupts = <27>;
+ clocks = <&ahb_gates 6>;
+ #dma-cells = <2>;
+ };
+
+ spi0: spi@01c05000 {
+ compatible = "allwinner,sun4i-a10-spi";
+ reg = <0x01c05000 0x1000>;
+ interrupts = <10>;
+ clocks = <&ahb_gates 20>, <&spi0_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma SUN4I_DMA_DEDICATED 27>,
+ <&dma SUN4I_DMA_DEDICATED 26>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ spi1: spi@01c06000 {
+ compatible = "allwinner,sun4i-a10-spi";
+ reg = <0x01c06000 0x1000>;
+ interrupts = <11>;
+ clocks = <&ahb_gates 21>, <&spi1_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma SUN4I_DMA_DEDICATED 9>,
+ <&dma SUN4I_DMA_DEDICATED 8>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ mmc0: mmc@01c0f000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&ahb_gates 8>,
+ <&mmc0_clk 0>,
+ <&mmc0_clk 1>,
+ <&mmc0_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ interrupts = <32>;
+ status = "disabled";
+ };
+
+ mmc2: mmc@01c11000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c11000 0x1000>;
+ clocks = <&ahb_gates 10>,
+ <&mmc2_clk 0>,
+ <&mmc2_clk 1>,
+ <&mmc2_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ interrupts = <34>;
+ status = "disabled";
+ };
+
+ usbphy: phy@01c13400 {
+ #phy-cells = <1>;
+ compatible = "allwinner,sun5i-a13-usb-phy";
+ reg = <0x01c13400 0x10 0x01c14800 0x4>;
+ reg-names = "phy_ctrl", "pmu1";
+ clocks = <&usb_clk 8>;
+ clock-names = "usb_phy";
+ resets = <&usb_clk 0>, <&usb_clk 1>;
+ reset-names = "usb0_reset", "usb1_reset";
+ status = "disabled";
+ };
+
+ ehci0: usb@01c14000 {
+ compatible = "allwinner,sun5i-a13-ehci", "generic-ehci";
+ reg = <0x01c14000 0x100>;
+ interrupts = <39>;
+ clocks = <&ahb_gates 1>;
+ phys = <&usbphy 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ ohci0: usb@01c14400 {
+ compatible = "allwinner,sun5i-a13-ohci", "generic-ohci";
+ reg = <0x01c14400 0x100>;
+ interrupts = <40>;
+ clocks = <&usb_clk 6>, <&ahb_gates 2>;
+ phys = <&usbphy 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ spi2: spi@01c17000 {
+ compatible = "allwinner,sun4i-a10-spi";
+ reg = <0x01c17000 0x1000>;
+ interrupts = <12>;
+ clocks = <&ahb_gates 22>, <&spi2_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma SUN4I_DMA_DEDICATED 29>,
+ <&dma SUN4I_DMA_DEDICATED 28>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ intc: interrupt-controller@01c20400 {
+ compatible = "allwinner,sun4i-a10-ic";
+ reg = <0x01c20400 0x400>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ pio: pinctrl@01c20800 {
+ compatible = "allwinner,sun5i-a13-pinctrl";
+ reg = <0x01c20800 0x400>;
+ interrupts = <28>;
+ clocks = <&apb0_gates 5>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ #size-cells = <0>;
+ #gpio-cells = <3>;
+
+ uart1_pins_a: uart1@0 {
+ allwinner,pins = "PE10", "PE11";
+ allwinner,function = "uart1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart1_pins_b: uart1@1 {
+ allwinner,pins = "PG3", "PG4";
+ allwinner,function = "uart1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c0_pins_a: i2c0@0 {
+ allwinner,pins = "PB0", "PB1";
+ allwinner,function = "i2c0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c1_pins_a: i2c1@0 {
+ allwinner,pins = "PB15", "PB16";
+ allwinner,function = "i2c1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c2_pins_a: i2c2@0 {
+ allwinner,pins = "PB17", "PB18";
+ allwinner,function = "i2c2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_pins_a: mmc0@0 {
+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ timer@01c20c00 {
+ compatible = "allwinner,sun4i-a10-timer";
+ reg = <0x01c20c00 0x90>;
+ interrupts = <22>;
+ clocks = <&osc24M>;
+ };
+
+ wdt: watchdog@01c20c90 {
+ compatible = "allwinner,sun4i-a10-wdt";
+ reg = <0x01c20c90 0x10>;
+ };
+
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-a10-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <31>;
+ status = "disabled";
+ };
+
+ sid: eeprom@01c23800 {
+ compatible = "allwinner,sun4i-a10-sid";
+ reg = <0x01c23800 0x10>;
+ };
+
+ rtp: rtp@01c25000 {
+ compatible = "allwinner,sun5i-a13-ts";
+ reg = <0x01c25000 0x100>;
+ interrupts = <29>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ uart1: serial@01c28400 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28400 0x400>;
+ interrupts = <2>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 17>;
+ status = "disabled";
+ };
+
+ uart3: serial@01c28c00 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28c00 0x400>;
+ interrupts = <4>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 19>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ compatible = "allwinner,sun5i-a13-i2c", "allwinner,sun4i-a10-i2c";
+ reg = <0x01c2ac00 0x400>;
+ interrupts = <7>;
+ clocks = <&apb1_gates 0>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c1: i2c@01c2b000 {
+ compatible = "allwinner,sun5i-a13-i2c", "allwinner,sun4i-a10-i2c";
+ reg = <0x01c2b000 0x400>;
+ interrupts = <8>;
+ clocks = <&apb1_gates 1>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c2: i2c@01c2b400 {
+ compatible = "allwinner,sun5i-a13-i2c", "allwinner,sun4i-a10-i2c";
+ reg = <0x01c2b400 0x400>;
+ interrupts = <9>;
+ clocks = <&apb1_gates 2>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ timer@01c60000 {
+ compatible = "allwinner,sun5i-a13-hstimer";
+ reg = <0x01c60000 0x1000>;
+ interrupts = <82>, <83>;
+ clocks = <&ahb_gates 28>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sun6i-a31-app4-evb1.dts b/arch/arm/boot/dts/sun6i-a31-app4-evb1.dts
new file mode 100644
index 000000000..be9f5ee6b
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31-app4-evb1.dts
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2014 Boris Brezillon
+ *
+ * Boris Brezillon <boris.brezillon@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun6i-a31.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Allwinner A31 APP4 EVB1 Evaluation Board";
+ compatible = "allwinner,app4-evb1", "allwinner,sun6i-a31";
+
+ chosen {
+ bootargs = "earlyprintk console=ttyS0,115200";
+ };
+
+ soc@01c00000 {
+ pio: pinctrl@01c20800 {
+ usb1_vbus_pin_a: usb1_vbus_pin@0 {
+ allwinner,pins = "PH27";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ usbphy: phy@01c19400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c1a000 {
+ status = "okay";
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ pinctrl-0 = <&usb1_vbus_pin_a>;
+ gpio = <&pio 7 27 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun6i-a31-colombus.dts b/arch/arm/boot/dts/sun6i-a31-colombus.dts
new file mode 100644
index 000000000..84630e56a
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31-colombus.dts
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2013 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun6i-a31.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "WITS A31 Colombus Evaluation Board";
+ compatible = "wits,colombus", "allwinner,sun6i-a31";
+
+ chosen {
+ bootargs = "earlyprintk console=ttyS0,115200";
+ };
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_colombus>;
+ vmmc-supply = <&reg_vcc3v0>;
+ bus-width = <4>;
+ cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c19400 {
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci1: usb@01c1b000 {
+ status = "okay";
+ };
+
+ pio: pinctrl@01c20800 {
+ mmc0_pins_a: mmc0@0 {
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ mmc0_cd_pin_colombus: mmc0_cd_pin@0 {
+ allwinner,pins = "PA8";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ usb2_vbus_pin_colombus: usb2_vbus_pin@0 {
+ allwinner,pins = "PH24";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "fail";
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
+
+ i2c2: i2c@01c2b400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+ };
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb2_vbus_pin_colombus>;
+ gpio = <&pio 7 24 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
new file mode 100644
index 000000000..8b61b1b34
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2014 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun6i-a31.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Merrii A31 Hummingbird";
+ compatible = "merrii,a31-hummingbird", "allwinner,sun6i-a31";
+
+ chosen {
+ bootargs = "earlyprintk console=ttyS0,115200";
+ };
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&gmac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_rgmii_a>;
+ phy = <&phy1>;
+ phy-mode = "rgmii";
+ snps,reset-gpio = <&pio 0 21 GPIO_ACTIVE_HIGH>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 30000>;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ /* pull-ups and devices require AXP221 DLDO3 */
+ status = "failed";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+
+ pcf8563: rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_hummingbird>;
+ vmmc-supply = <&reg_vcc3v0>;
+ bus-width = <4>;
+ cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
+ cd-inverted;
+ status = "okay";
+};
+
+&mmc0_pins_a {
+ /* external pull-ups missing for some pins */
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&pio {
+ mmc0_cd_pin_hummingbird: mmc0_cd_pin@0 {
+ allwinner,pins = "PA8";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+};
+
+&reg_usb1_vbus {
+ gpio = <&pio 7 24 GPIO_ACTIVE_HIGH>; /* PH24 */
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usb1_vbus_pin_a {
+ /* different pin from sunxi-common-regulators */
+ allwinner,pins = "PH24";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun6i-a31-m9.dts b/arch/arm/boot/dts/sun6i-a31-m9.dts
new file mode 100644
index 000000000..139a21e6b
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31-m9.dts
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun6i-a31.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Mele M9 / A1000G Quad top set box";
+ compatible = "mele,m9", "allwinner,sun6i-a31";
+
+ chosen {
+ bootargs = "earlyprintk console=ttyS0,115200";
+ };
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_m9>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 22 GPIO_ACTIVE_HIGH>; /* PH22 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c19400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c1a000 {
+ status = "okay";
+ };
+
+ ehci1: usb@01c1b000 {
+ status = "okay";
+ };
+
+ pio: pinctrl@01c20800 {
+ led_pins_m9: led_pins@0 {
+ allwinner,pins = "PH13";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_cd_pin_m9: mmc0_cd_pin@0 {
+ allwinner,pins = "PH22";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ usb1_vbus_pin_m9: usb1_vbus_pin@0 {
+ allwinner,pins = "PC27";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ gmac: ethernet@01c30000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_mii_a>;
+ phy = <&phy1>;
+ phy-mode = "mii";
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+
+ ir@01f02000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_pins_a>;
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_m9>;
+
+ blue {
+ label = "m9:blue:usr";
+ gpios = <&pio 7 13 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_vbus_pin_m9>;
+ gpio = <&pio 2 27 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
new file mode 100644
index 000000000..fa2f403cc
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -0,0 +1,978 @@
+/*
+ * Copyright 2013 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "skeleton.dtsi"
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ interrupt-parent = <&gic>;
+
+ aliases {
+ ethernet0 = &gmac;
+ };
+
+ chosen {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ framebuffer@0 {
+ compatible = "allwinner,simple-framebuffer", "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0-hdmi";
+ clocks = <&pll6 0>;
+ status = "disabled";
+ };
+
+ framebuffer@1 {
+ compatible = "allwinner,simple-framebuffer",
+ "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0";
+ clocks = <&pll6 0>;
+ status = "disabled";
+ };
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ clock-frequency = <24000000>;
+ arm,cpu-registers-not-fw-configured;
+ };
+
+ cpus {
+ enable-method = "allwinner,sun6i-a31";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <1>;
+ };
+
+ cpu@2 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <2>;
+ };
+
+ cpu@3 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <3>;
+ };
+ };
+
+ memory {
+ reg = <0x40000000 0x80000000>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a7-pmu", "arm,cortex-a15-pmu";
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ osc24M: osc24M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ osc32k: clk@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ clock-output-names = "osc32k";
+ };
+
+ pll1: clk@01c20000 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun6i-a31-pll1-clk";
+ reg = <0x01c20000 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll1";
+ };
+
+ pll6: clk@01c20028 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun6i-a31-pll6-clk";
+ reg = <0x01c20028 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll6", "pll6x2";
+ };
+
+ cpu: cpu@01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-cpu-clk";
+ reg = <0x01c20050 0x4>;
+
+ /*
+ * PLL1 is listed twice here.
+ * While it looks suspicious, it's actually documented
+ * that way both in the datasheet and in the code from
+ * Allwinner.
+ */
+ clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll1>;
+ clock-output-names = "cpu";
+ };
+
+ axi: axi@01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-axi-clk";
+ reg = <0x01c20050 0x4>;
+ clocks = <&cpu>;
+ clock-output-names = "axi";
+ };
+
+ ahb1: ahb1@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun6i-a31-ahb1-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>;
+ clock-output-names = "ahb1";
+ };
+
+ ahb1_gates: clk@01c20060 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun6i-a31-ahb1-gates-clk";
+ reg = <0x01c20060 0x8>;
+ clocks = <&ahb1>;
+ clock-output-names = "ahb1_mipidsi", "ahb1_ss",
+ "ahb1_dma", "ahb1_mmc0", "ahb1_mmc1",
+ "ahb1_mmc2", "ahb1_mmc3", "ahb1_nand1",
+ "ahb1_nand0", "ahb1_sdram",
+ "ahb1_gmac", "ahb1_ts", "ahb1_hstimer",
+ "ahb1_spi0", "ahb1_spi1", "ahb1_spi2",
+ "ahb1_spi3", "ahb1_otg", "ahb1_ehci0",
+ "ahb1_ehci1", "ahb1_ohci0",
+ "ahb1_ohci1", "ahb1_ohci2", "ahb1_ve",
+ "ahb1_lcd0", "ahb1_lcd1", "ahb1_csi",
+ "ahb1_hdmi", "ahb1_de0", "ahb1_de1",
+ "ahb1_fe0", "ahb1_fe1", "ahb1_mp",
+ "ahb1_gpu", "ahb1_deu0", "ahb1_deu1",
+ "ahb1_drc0", "ahb1_drc1";
+ };
+
+ apb1: apb1@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb0-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&ahb1>;
+ clock-output-names = "apb1";
+ };
+
+ apb1_gates: clk@01c20068 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun6i-a31-apb1-gates-clk";
+ reg = <0x01c20068 0x4>;
+ clocks = <&apb1>;
+ clock-output-names = "apb1_codec", "apb1_digital_mic",
+ "apb1_pio", "apb1_daudio0",
+ "apb1_daudio1";
+ };
+
+ apb2: clk@01c20058 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb1-clk";
+ reg = <0x01c20058 0x4>;
+ clocks = <&osc32k>, <&osc24M>, <&pll6 0>, <&pll6 0>;
+ clock-output-names = "apb2";
+ };
+
+ apb2_gates: clk@01c2006c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun6i-a31-apb2-gates-clk";
+ reg = <0x01c2006c 0x4>;
+ clocks = <&apb2>;
+ clock-output-names = "apb2_i2c0", "apb2_i2c1",
+ "apb2_i2c2", "apb2_i2c3", "apb2_uart0",
+ "apb2_uart1", "apb2_uart2", "apb2_uart3",
+ "apb2_uart4", "apb2_uart5";
+ };
+
+ mmc0_clk: clk@01c20088 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20088 0x4>;
+ clocks = <&osc24M>, <&pll6 0>;
+ clock-output-names = "mmc0",
+ "mmc0_output",
+ "mmc0_sample";
+ };
+
+ mmc1_clk: clk@01c2008c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c2008c 0x4>;
+ clocks = <&osc24M>, <&pll6 0>;
+ clock-output-names = "mmc1",
+ "mmc1_output",
+ "mmc1_sample";
+ };
+
+ mmc2_clk: clk@01c20090 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20090 0x4>;
+ clocks = <&osc24M>, <&pll6 0>;
+ clock-output-names = "mmc2",
+ "mmc2_output",
+ "mmc2_sample";
+ };
+
+ mmc3_clk: clk@01c20094 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20094 0x4>;
+ clocks = <&osc24M>, <&pll6 0>;
+ clock-output-names = "mmc3",
+ "mmc3_output",
+ "mmc3_sample";
+ };
+
+ spi0_clk: clk@01c200a0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200a0 0x4>;
+ clocks = <&osc24M>, <&pll6 0>;
+ clock-output-names = "spi0";
+ };
+
+ spi1_clk: clk@01c200a4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200a4 0x4>;
+ clocks = <&osc24M>, <&pll6 0>;
+ clock-output-names = "spi1";
+ };
+
+ spi2_clk: clk@01c200a8 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200a8 0x4>;
+ clocks = <&osc24M>, <&pll6 0>;
+ clock-output-names = "spi2";
+ };
+
+ spi3_clk: clk@01c200ac {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200ac 0x4>;
+ clocks = <&osc24M>, <&pll6 0>;
+ clock-output-names = "spi3";
+ };
+
+ usb_clk: clk@01c200cc {
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-usb-clk";
+ reg = <0x01c200cc 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "usb_phy0", "usb_phy1", "usb_phy2",
+ "usb_ohci0", "usb_ohci1",
+ "usb_ohci2";
+ };
+
+ /*
+ * The following two are dummy clocks, placeholders used in the gmac_tx
+ * clock. The gmac driver will choose one parent depending on the PHY
+ * interface mode, using clk_set_rate auto-reparenting.
+ * The actual TX clock rate is not controlled by the gmac_tx clock.
+ */
+ mii_phy_tx_clk: clk@1 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <25000000>;
+ clock-output-names = "mii_phy_tx";
+ };
+
+ gmac_int_tx_clk: clk@2 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <125000000>;
+ clock-output-names = "gmac_int_tx";
+ };
+
+ gmac_tx_clk: clk@01c200d0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun7i-a20-gmac-clk";
+ reg = <0x01c200d0 0x4>;
+ clocks = <&mii_phy_tx_clk>, <&gmac_int_tx_clk>;
+ clock-output-names = "gmac_tx";
+ };
+ };
+
+ soc@01c00000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dma: dma-controller@01c02000 {
+ compatible = "allwinner,sun6i-a31-dma";
+ reg = <0x01c02000 0x1000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb1_gates 6>;
+ resets = <&ahb1_rst 6>;
+ #dma-cells = <1>;
+
+ /* DMA controller requires AHB1 clocked from PLL6 */
+ assigned-clocks = <&ahb1>;
+ assigned-clock-parents = <&pll6 0>;
+ };
+
+ mmc0: mmc@01c0f000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&ahb1_gates 8>,
+ <&mmc0_clk 0>,
+ <&mmc0_clk 1>,
+ <&mmc0_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ resets = <&ahb1_rst 8>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@01c10000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c10000 0x1000>;
+ clocks = <&ahb1_gates 9>,
+ <&mmc1_clk 0>,
+ <&mmc1_clk 1>,
+ <&mmc1_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ resets = <&ahb1_rst 9>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc2: mmc@01c11000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c11000 0x1000>;
+ clocks = <&ahb1_gates 10>,
+ <&mmc2_clk 0>,
+ <&mmc2_clk 1>,
+ <&mmc2_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ resets = <&ahb1_rst 10>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc3: mmc@01c12000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c12000 0x1000>;
+ clocks = <&ahb1_gates 11>,
+ <&mmc3_clk 0>,
+ <&mmc3_clk 1>,
+ <&mmc3_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ resets = <&ahb1_rst 11>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ usbphy: phy@01c19400 {
+ compatible = "allwinner,sun6i-a31-usb-phy";
+ reg = <0x01c19400 0x10>,
+ <0x01c1a800 0x4>,
+ <0x01c1b800 0x4>;
+ reg-names = "phy_ctrl",
+ "pmu1",
+ "pmu2";
+ clocks = <&usb_clk 8>,
+ <&usb_clk 9>,
+ <&usb_clk 10>;
+ clock-names = "usb0_phy",
+ "usb1_phy",
+ "usb2_phy";
+ resets = <&usb_clk 0>,
+ <&usb_clk 1>,
+ <&usb_clk 2>;
+ reset-names = "usb0_reset",
+ "usb1_reset",
+ "usb2_reset";
+ status = "disabled";
+ #phy-cells = <1>;
+ };
+
+ ehci0: usb@01c1a000 {
+ compatible = "allwinner,sun6i-a31-ehci", "generic-ehci";
+ reg = <0x01c1a000 0x100>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb1_gates 26>;
+ resets = <&ahb1_rst 26>;
+ phys = <&usbphy 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ ohci0: usb@01c1a400 {
+ compatible = "allwinner,sun6i-a31-ohci", "generic-ohci";
+ reg = <0x01c1a400 0x100>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb1_gates 29>, <&usb_clk 16>;
+ resets = <&ahb1_rst 29>;
+ phys = <&usbphy 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ ehci1: usb@01c1b000 {
+ compatible = "allwinner,sun6i-a31-ehci", "generic-ehci";
+ reg = <0x01c1b000 0x100>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb1_gates 27>;
+ resets = <&ahb1_rst 27>;
+ phys = <&usbphy 2>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ ohci1: usb@01c1b400 {
+ compatible = "allwinner,sun6i-a31-ohci", "generic-ohci";
+ reg = <0x01c1b400 0x100>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb1_gates 30>, <&usb_clk 17>;
+ resets = <&ahb1_rst 30>;
+ phys = <&usbphy 2>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ ohci2: usb@01c1c400 {
+ compatible = "allwinner,sun6i-a31-ohci", "generic-ohci";
+ reg = <0x01c1c400 0x100>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb1_gates 31>, <&usb_clk 18>;
+ resets = <&ahb1_rst 31>;
+ status = "disabled";
+ };
+
+ pio: pinctrl@01c20800 {
+ compatible = "allwinner,sun6i-a31-pinctrl";
+ reg = <0x01c20800 0x400>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 5>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ #size-cells = <0>;
+ #gpio-cells = <3>;
+
+ uart0_pins_a: uart0@0 {
+ allwinner,pins = "PH20", "PH21";
+ allwinner,function = "uart0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c0_pins_a: i2c0@0 {
+ allwinner,pins = "PH14", "PH15";
+ allwinner,function = "i2c0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c1_pins_a: i2c1@0 {
+ allwinner,pins = "PH16", "PH17";
+ allwinner,function = "i2c1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c2_pins_a: i2c2@0 {
+ allwinner,pins = "PH18", "PH19";
+ allwinner,function = "i2c2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_pins_a: mmc0@0 {
+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ gmac_pins_mii_a: gmac_mii@0 {
+ allwinner,pins = "PA0", "PA1", "PA2", "PA3",
+ "PA8", "PA9", "PA11",
+ "PA12", "PA13", "PA14", "PA19",
+ "PA20", "PA21", "PA22", "PA23",
+ "PA24", "PA26", "PA27";
+ allwinner,function = "gmac";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ gmac_pins_gmii_a: gmac_gmii@0 {
+ allwinner,pins = "PA0", "PA1", "PA2", "PA3",
+ "PA4", "PA5", "PA6", "PA7",
+ "PA8", "PA9", "PA10", "PA11",
+ "PA12", "PA13", "PA14", "PA15",
+ "PA16", "PA17", "PA18", "PA19",
+ "PA20", "PA21", "PA22", "PA23",
+ "PA24", "PA25", "PA26", "PA27";
+ allwinner,function = "gmac";
+ /*
+ * data lines in GMII mode run at 125MHz and
+ * might need a higher signal drive strength
+ */
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ gmac_pins_rgmii_a: gmac_rgmii@0 {
+ allwinner,pins = "PA0", "PA1", "PA2", "PA3",
+ "PA9", "PA10", "PA11",
+ "PA12", "PA13", "PA14", "PA19",
+ "PA20", "PA25", "PA26", "PA27";
+ allwinner,function = "gmac";
+ /*
+ * data lines in RGMII mode use DDR mode
+ * and need a higher signal drive strength
+ */
+ allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ ahb1_rst: reset@01c202c0 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-ahb1-reset";
+ reg = <0x01c202c0 0xc>;
+ };
+
+ apb1_rst: reset@01c202d0 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ reg = <0x01c202d0 0x4>;
+ };
+
+ apb2_rst: reset@01c202d8 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ reg = <0x01c202d8 0x4>;
+ };
+
+ timer@01c20c00 {
+ compatible = "allwinner,sun4i-a10-timer";
+ reg = <0x01c20c00 0xa0>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc24M>;
+ };
+
+ wdt1: watchdog@01c20ca0 {
+ compatible = "allwinner,sun6i-a31-wdt";
+ reg = <0x01c20ca0 0x20>;
+ };
+
+ rtp: rtp@01c25000 {
+ compatible = "allwinner,sun6i-a31-ts";
+ reg = <0x01c25000 0x100>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ uart0: serial@01c28000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28000 0x400>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb2_gates 16>;
+ resets = <&apb2_rst 16>;
+ dmas = <&dma 6>, <&dma 6>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart1: serial@01c28400 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28400 0x400>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb2_gates 17>;
+ resets = <&apb2_rst 17>;
+ dmas = <&dma 7>, <&dma 7>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart2: serial@01c28800 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28800 0x400>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb2_gates 18>;
+ resets = <&apb2_rst 18>;
+ dmas = <&dma 8>, <&dma 8>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart3: serial@01c28c00 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28c00 0x400>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb2_gates 19>;
+ resets = <&apb2_rst 19>;
+ dmas = <&dma 9>, <&dma 9>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart4: serial@01c29000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c29000 0x400>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb2_gates 20>;
+ resets = <&apb2_rst 20>;
+ dmas = <&dma 10>, <&dma 10>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart5: serial@01c29400 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c29400 0x400>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb2_gates 21>;
+ resets = <&apb2_rst 21>;
+ dmas = <&dma 22>, <&dma 22>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ compatible = "allwinner,sun6i-a31-i2c";
+ reg = <0x01c2ac00 0x400>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb2_gates 0>;
+ resets = <&apb2_rst 0>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c1: i2c@01c2b000 {
+ compatible = "allwinner,sun6i-a31-i2c";
+ reg = <0x01c2b000 0x400>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb2_gates 1>;
+ resets = <&apb2_rst 1>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c2: i2c@01c2b400 {
+ compatible = "allwinner,sun6i-a31-i2c";
+ reg = <0x01c2b400 0x400>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb2_gates 2>;
+ resets = <&apb2_rst 2>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c3: i2c@01c2b800 {
+ compatible = "allwinner,sun6i-a31-i2c";
+ reg = <0x01c2b800 0x400>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb2_gates 3>;
+ resets = <&apb2_rst 3>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ gmac: ethernet@01c30000 {
+ compatible = "allwinner,sun7i-a20-gmac";
+ reg = <0x01c30000 0x1054>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ clocks = <&ahb1_gates 17>, <&gmac_tx_clk>;
+ clock-names = "stmmaceth", "allwinner_gmac_tx";
+ resets = <&ahb1_rst 17>;
+ reset-names = "stmmaceth";
+ snps,pbl = <2>;
+ snps,fixed-burst;
+ snps,force_sf_dma_mode;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ timer@01c60000 {
+ compatible = "allwinner,sun6i-a31-hstimer", "allwinner,sun7i-a20-hstimer";
+ reg = <0x01c60000 0x1000>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb1_gates 19>;
+ resets = <&ahb1_rst 19>;
+ };
+
+ spi0: spi@01c68000 {
+ compatible = "allwinner,sun6i-a31-spi";
+ reg = <0x01c68000 0x1000>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb1_gates 20>, <&spi0_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma 23>, <&dma 23>;
+ dma-names = "rx", "tx";
+ resets = <&ahb1_rst 20>;
+ status = "disabled";
+ };
+
+ spi1: spi@01c69000 {
+ compatible = "allwinner,sun6i-a31-spi";
+ reg = <0x01c69000 0x1000>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb1_gates 21>, <&spi1_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma 24>, <&dma 24>;
+ dma-names = "rx", "tx";
+ resets = <&ahb1_rst 21>;
+ status = "disabled";
+ };
+
+ spi2: spi@01c6a000 {
+ compatible = "allwinner,sun6i-a31-spi";
+ reg = <0x01c6a000 0x1000>;
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb1_gates 22>, <&spi2_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma 25>, <&dma 25>;
+ dma-names = "rx", "tx";
+ resets = <&ahb1_rst 22>;
+ status = "disabled";
+ };
+
+ spi3: spi@01c6b000 {
+ compatible = "allwinner,sun6i-a31-spi";
+ reg = <0x01c6b000 0x1000>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb1_gates 23>, <&spi3_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma 26>, <&dma 26>;
+ dma-names = "rx", "tx";
+ resets = <&ahb1_rst 23>;
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@01c81000 {
+ compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
+ reg = <0x01c81000 0x1000>,
+ <0x01c82000 0x1000>,
+ <0x01c84000 0x2000>,
+ <0x01c86000 0x2000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ rtc: rtc@01f00000 {
+ compatible = "allwinner,sun6i-a31-rtc";
+ reg = <0x01f00000 0x54>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ nmi_intc: interrupt-controller@01f00c0c {
+ compatible = "allwinner,sun6i-a31-sc-nmi";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x01f00c0c 0x38>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ prcm@01f01400 {
+ compatible = "allwinner,sun6i-a31-prcm";
+ reg = <0x01f01400 0x200>;
+
+ ar100: ar100_clk {
+ compatible = "allwinner,sun6i-a31-ar100-clk";
+ #clock-cells = <0>;
+ clocks = <&osc32k>, <&osc24M>, <&pll6 0>, <&pll6 0>;
+ clock-output-names = "ar100";
+ };
+
+ ahb0: ahb0_clk {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ clocks = <&ar100>;
+ clock-output-names = "ahb0";
+ };
+
+ apb0: apb0_clk {
+ compatible = "allwinner,sun6i-a31-apb0-clk";
+ #clock-cells = <0>;
+ clocks = <&ahb0>;
+ clock-output-names = "apb0";
+ };
+
+ apb0_gates: apb0_gates_clk {
+ compatible = "allwinner,sun6i-a31-apb0-gates-clk";
+ #clock-cells = <1>;
+ clocks = <&apb0>;
+ clock-output-names = "apb0_pio", "apb0_ir",
+ "apb0_timer", "apb0_p2wi",
+ "apb0_uart", "apb0_1wire",
+ "apb0_i2c";
+ };
+
+ ir_clk: ir_clk {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ clocks = <&osc32k>, <&osc24M>;
+ clock-output-names = "ir";
+ };
+
+ apb0_rst: apb0_rst {
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ #reset-cells = <1>;
+ };
+ };
+
+ cpucfg@01f01c00 {
+ compatible = "allwinner,sun6i-a31-cpuconfig";
+ reg = <0x01f01c00 0x300>;
+ };
+
+ ir: ir@01f02000 {
+ compatible = "allwinner,sun5i-a13-ir";
+ clocks = <&apb0_gates 1>, <&ir_clk>;
+ clock-names = "apb", "ir";
+ resets = <&apb0_rst 1>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x01f02000 0x40>;
+ status = "disabled";
+ };
+
+ r_pio: pinctrl@01f02c00 {
+ compatible = "allwinner,sun6i-a31-r-pinctrl";
+ reg = <0x01f02c00 0x400>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb0_gates 0>;
+ resets = <&apb0_rst 0>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ #size-cells = <0>;
+ #gpio-cells = <3>;
+
+ ir_pins_a: ir@0 {
+ allwinner,pins = "PL4";
+ allwinner,function = "s_ir";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sun6i-a31s-cs908.dts b/arch/arm/boot/dts/sun6i-a31s-cs908.dts
new file mode 100644
index 000000000..bc3734f67
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31s-cs908.dts
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun6i-a31s.dtsi"
+
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "CSQ CS908 top set box";
+ compatible = "csq,cs908", "allwinner,sun6i-a31s";
+};
+
+&usbphy {
+ status = "okay";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&pio {
+ usb1_vbus_pin_csq908: usb1_vbus_pin@0 {
+ allwinner,pins = "PC27";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&gmac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_mii_a>;
+ phy = <&phy1>;
+ phy-mode = "mii";
+ status = "okay";
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&ir {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_pins_a>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun6i-a31s.dtsi b/arch/arm/boot/dts/sun6i-a31s.dtsi
new file mode 100644
index 000000000..eaf5ec8fd
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31s.dtsi
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * The A31s is the same die as the A31 in a different package, this is
+ * reflected by it having different pinctrl compatible everything else is
+ * identical.
+ */
+
+#include "sun6i-a31.dtsi"
+
+&pio {
+ compatible = "allwinner,sun6i-a31s-pinctrl";
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi.dts b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
new file mode 100644
index 000000000..5dd139e77
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
+ *
+ * Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "LeMaker Banana Pi";
+ compatible = "lemaker,bananapi", "allwinner,sun7i-a20";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart3;
+ serial2 = &uart7;
+ };
+
+ soc@01c00000 {
+ spi0: spi@01c05000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins_a>;
+ status = "okay";
+ };
+
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bananapi>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>; /* PH10 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ahci: sata@01c18000 {
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ mmc0_cd_pin_bananapi: mmc0_cd_pin@0 {
+ allwinner,pins = "PH10";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ gmac_power_pin_bananapi: gmac_power_pin@0 {
+ allwinner,pins = "PH23";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ led_pins_bananapi: led_pins@0 {
+ allwinner,pins = "PH24";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ ir0: ir@01c21800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir0_pins_a>;
+ status = "okay";
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ uart3: serial@01c28c00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins_b>;
+ status = "okay";
+ };
+
+ uart7: serial@01c29c00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart7_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ i2c2: i2c@01c2b400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+ };
+
+ gmac: ethernet@01c50000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_rgmii_a>;
+ phy = <&phy1>;
+ phy-mode = "rgmii";
+ phy-supply = <&reg_gmac_3v3>;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_bananapi>;
+
+ green {
+ label = "bananapi:green:usr";
+ gpios = <&pio 7 24 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ status = "okay";
+ };
+
+ reg_gmac_3v3: gmac-3v3 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_power_pin_bananapi>;
+ regulator-name = "gmac-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <100000>;
+ enable-active-high;
+ gpio = <&pio 7 23 GPIO_ACTIVE_HIGH>;
+ };
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-bananapro.dts b/arch/arm/boot/dts/sun7i-a20-bananapro.dts
new file mode 100644
index 000000000..fb89fe7ed
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-bananapro.dts
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ model = "LeMaker Banana Pro";
+ compatible = "lemaker,bananapro", "allwinner,sun7i-a20";
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_bananapro>;
+
+ blue {
+ label = "bananapro:blue:usr";
+ gpios = <&pio 6 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ green {
+ label = "bananapro:green:usr";
+ gpios = <&pio 7 24 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ reg_gmac_3v3: gmac-3v3 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_power_pin_bananapro>;
+ regulator-name = "gmac-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <100000>;
+ enable-active-high;
+ gpio = <&pio 7 23 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_vmmc3: vmmc3 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&vmmc3_pin_bananapro>;
+ regulator-name = "vmmc3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 7 22 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&ahci {
+ status = "okay";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&gmac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_rgmii_a>;
+ phy = <&phy1>;
+ phy-mode = "rgmii";
+ phy-supply = <&reg_gmac_3v3>;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+};
+
+&ir0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir0_pins_a>;
+ status = "okay";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bananapro>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>; /* PH10 */
+ cd-inverted;
+ status = "okay";
+};
+
+&mmc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc3_pins_a>;
+ vmmc-supply = <&reg_vmmc3>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&pio {
+ gmac_power_pin_bananapro: gmac_power_pin@0 {
+ allwinner,pins = "PH23";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ led_pins_bananapro: led_pins@0 {
+ allwinner,pins = "PH24", "PG2";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_cd_pin_bananapro: mmc0_cd_pin@0 {
+ allwinner,pins = "PH10";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ usb1_vbus_pin_bananapro: usb1_vbus_pin@0 {
+ allwinner,pins = "PH0";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ usb2_vbus_pin_bananapro: usb2_vbus_pin@0 {
+ allwinner,pins = "PH1";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ vmmc3_pin_bananapro: vmmc3_pin@0 {
+ allwinner,pins = "PH22";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&reg_usb1_vbus {
+ pinctrl-0 = <&usb1_vbus_pin_bananapro>;
+ gpio = <&pio 7 0 GPIO_ACTIVE_HIGH>; /* PH0 */
+ status = "okay";
+};
+
+&reg_usb2_vbus {
+ pinctrl-0 = <&usb2_vbus_pin_bananapro>;
+ gpio = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ status = "okay";
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins_a>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins_a>;
+ status = "okay";
+};
+
+&uart7 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart7_pins_a>;
+ status = "okay";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
new file mode 100644
index 000000000..c4ab6edb6
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2013 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Cubietech Cubieboard2";
+ compatible = "cubietech,cubieboard2", "allwinner,sun7i-a20";
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ahci: sata@01c18000 {
+ target-supply = <&reg_ahci_5v>;
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ led_pins_cubieboard2: led_pins@0 {
+ allwinner,pins = "PH20", "PH21";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ ir0: ir@01c21800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir0_pins_a>;
+ status = "okay";
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ reg = <0x34>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
+
+ gmac: ethernet@01c50000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_mii_a>;
+ phy = <&phy1>;
+ phy-mode = "mii";
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_cubieboard2>;
+
+ blue {
+ label = "cubieboard2:blue:usr";
+ gpios = <&pio 7 21 GPIO_ACTIVE_HIGH>;
+ };
+
+ green {
+ label = "cubieboard2:green:usr";
+ gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ reg_ahci_5v: ahci-5v {
+ status = "okay";
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ status = "okay";
+ };
+};
+
+#include "axp209.dtsi"
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+ regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "avcc";
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
new file mode 100644
index 000000000..8f74a6495
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2013 Oliver Schinagl
+ *
+ * Oliver Schinagl <oliver@schinagl.nl>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Cubietech Cubietruck";
+ compatible = "cubietech,cubietruck", "allwinner,sun7i-a20";
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ mmc3: mmc@01c12000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc3_pins_a>;
+ vmmc-supply = <&reg_vmmc3>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb0_vbus-supply = <&reg_usb0_vbus>;
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ahci: sata@01c18000 {
+ target-supply = <&reg_ahci_5v>;
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ mmc3_pins_a: mmc3@0 {
+ /* AP6210 requires pull-up */
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ vmmc3_pin_cubietruck: vmmc3_pin@0 {
+ allwinner,pins = "PH9";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ ahci_pwr_pin_cubietruck: ahci_pwr_pin@1 {
+ allwinner,pins = "PH12";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ led_pins_cubietruck: led_pins@0 {
+ allwinner,pins = "PH7", "PH11", "PH20", "PH21";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ usb0_vbus_pin_a: usb0_vbus_pin@0 {
+ allwinner,pins = "PH17";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ pwm: pwm@01c20e00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pins_a>, <&pwm1_pins_a>;
+ status = "okay";
+ };
+
+ ir0: ir@01c21800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir0_pins_a>;
+ status = "okay";
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ reg = <0x34>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
+
+ i2c2: i2c@01c2b400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+ };
+
+ gmac: ethernet@01c50000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_rgmii_a>;
+ phy = <&phy1>;
+ phy-mode = "rgmii";
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_cubietruck>;
+
+ blue {
+ label = "cubietruck:blue:usr";
+ gpios = <&pio 7 21 GPIO_ACTIVE_HIGH>;
+ };
+
+ orange {
+ label = "cubietruck:orange:usr";
+ gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>;
+ };
+
+ white {
+ label = "cubietruck:white:usr";
+ gpios = <&pio 7 11 GPIO_ACTIVE_HIGH>;
+ };
+
+ green {
+ label = "cubietruck:green:usr";
+ gpios = <&pio 7 7 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ reg_ahci_5v: ahci-5v {
+ pinctrl-0 = <&ahci_pwr_pin_cubietruck>;
+ gpio = <&pio 7 12 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ reg_usb0_vbus: usb0-vbus {
+ pinctrl-0 = <&usb0_vbus_pin_a>;
+ gpio = <&pio 7 17 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ status = "okay";
+ };
+
+ reg_vmmc3: vmmc3 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&vmmc3_pin_cubietruck>;
+ regulator-name = "vmmc3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 7 9 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+#include "axp209.dtsi"
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+ regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "avcc";
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-hummingbird.dts b/arch/arm/boot/dts/sun7i-a20-hummingbird.dts
new file mode 100644
index 000000000..86a944ce1
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-hummingbird.dts
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2013 Wills Wang
+ *
+ * Wills Wang <wills.wang.open@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
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Merrii A20 Hummingbird";
+ compatible = "merrii,a20-hummingbird", "allwinner,sun7i-a20";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ };
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v0>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ mmc3: mmc@01c12000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc3_pins_a>;
+ vmmc-supply = <&reg_mmc3_vdd>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ahci: sata@01c18000 {
+ target-supply = <&reg_ahci_5v>;
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ pio: pinctrl@01c20800 {
+ ahci_pwr_pin_a20_hummingbird: ahci_pwr_pin@0 {
+ allwinner,pins = "PH15";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ usb1_vbus_pin_a20_hummingbird: usb1_vbus_pin@0 {
+ allwinner,pins = "PH2";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc3_vdd_pin_a20_hummingbird: mmc3_vdd_pin@0 {
+ allwinner,pins = "PH9";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ gmac_vdd_pin_a20_hummingbird: gmac_vdd_pin@0 {
+ allwinner,pins = "PH16";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ pwm: pwm@01c20e00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pins_a>;
+ status = "okay";
+ };
+
+ ir0: ir@01c21800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir0_pins_a>;
+ status = "okay";
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ uart2: serial@01c28800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins_a>;
+ status = "okay";
+ };
+
+ uart3: serial@01c28c00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins_a>;
+ status = "okay";
+ };
+
+ uart4: serial@01c29000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins_a>;
+ status = "okay";
+ };
+
+ uart5: serial@01c29400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart5_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
+
+ i2c2: i2c@01c2b400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+ };
+
+ i2c3: i2c@01c2b800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins_a>;
+ status = "okay";
+ };
+
+ spi2: spi@01c17000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_pins_b>;
+ status = "okay";
+ };
+
+ gmac: ethernet@01c50000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_rgmii_a>;
+ phy = <&phy1>;
+ phy-mode = "rgmii";
+ phy-supply = <&reg_gmac_vdd>;
+ /* phy reset config */
+ snps,reset-gpio = <&pio 0 17 GPIO_ACTIVE_HIGH>; /* PA17 */
+ snps,reset-active-low;
+ /* wait 1s after reset, otherwise fail to read phy id */
+ snps,reset-delays-us = <0 10000 1000000>;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ reg_ahci_5v: ahci-5v {
+ pinctrl-0 = <&ahci_pwr_pin_a20_hummingbird>;
+ gpio = <&pio 7 15 GPIO_ACTIVE_HIGH>; /* PH15 */
+ status = "okay";
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ pinctrl-0 = <&usb1_vbus_pin_a20_hummingbird>;
+ gpio = <&pio 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ status = "okay";
+ };
+
+ reg_mmc3_vdd: mmc3_vdd {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc3_vdd_pin_a20_hummingbird>;
+ regulator-name = "mmc3_vdd";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ enable-active-high;
+ gpio = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */
+ };
+
+ reg_gmac_vdd: gmac_vdd {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_vdd_pin_a20_hummingbird>;
+ regulator-name = "gmac_vdd";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ enable-active-high;
+ gpio = <&pio 7 16 GPIO_ACTIVE_HIGH>; /* PH16 */
+ };
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts b/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts
new file mode 100644
index 000000000..06148b4d0
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "I12 / Q5 / QT840A A20 tvbox";
+ compatible = "allwinner,i12-tvbox", "allwinner,sun7i-a20";
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ mmc3: mmc@01c12000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc3_pins_a>;
+ vmmc-supply = <&reg_vmmc3>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ mmc3_pins_a: mmc3@0 {
+ /* AP6210 / AP6330 requires pull-up */
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ vmmc3_pin_i12_tvbox: vmmc3_pin@0 {
+ allwinner,pins = "PH2";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ vmmc3_io_pin_i12_tvbox: vmmc3_io_pin@0 {
+ allwinner,pins = "PH12";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ gmac_power_pin_i12_tvbox: gmac_power_pin@0 {
+ allwinner,pins = "PH21";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ led_pins_i12_tvbox: led_pins@0 {
+ allwinner,pins = "PH9", "PH20";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ ir0: ir@01c21800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir0_pins_a>;
+ status = "okay";
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ gmac: ethernet@01c50000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_mii_a>;
+ phy = <&phy1>;
+ phy-mode = "mii";
+ phy-supply = <&reg_gmac_3v3>;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_i12_tvbox>;
+
+ red {
+ label = "i12_tvbox:red:usr";
+ gpios = <&pio 7 9 GPIO_ACTIVE_LOW>;
+ };
+
+ blue {
+ label = "i12_tvbox:blue:usr";
+ gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ status = "okay";
+ };
+
+ reg_vmmc3: vmmc3 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&vmmc3_pin_i12_tvbox>;
+ regulator-name = "vmmc3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 7 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_vmmc3_io: vmmc3-io {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&vmmc3_io_pin_i12_tvbox>;
+ regulator-name = "vmmc3-io";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ /* This controls VCC-PI, must be always on! */
+ regulator-always-on;
+ enable-active-high;
+ gpio = <&pio 7 12 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_gmac_3v3: gmac-3v3 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_power_pin_i12_tvbox>;
+ regulator-name = "gmac-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <50000>;
+ enable-active-high;
+ gpio = <&pio 7 21 GPIO_ACTIVE_HIGH>;
+ };
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-m3.dts b/arch/arm/boot/dts/sun7i-a20-m3.dts
new file mode 100644
index 000000000..5add9f243
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-m3.dts
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
+ *
+ * Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Mele M3";
+ compatible = "mele,m3", "allwinner,sun7i-a20";
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ mmc2: mmc@01c11000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins_a>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ led_pins_m3: led_pins@0 {
+ allwinner,pins = "PH20";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ ir0: ir@01c21800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir0_pins_a>;
+ status = "okay";
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ gmac: ethernet@01c50000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_mii_a>;
+ phy = <&phy1>;
+ phy-mode = "mii";
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_m3>;
+
+ blue {
+ label = "m3:blue:usr";
+ gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
new file mode 100644
index 000000000..12ded69d6
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
@@ -0,0 +1,177 @@
+/*
+ * This is based on sun4i-a10-olinuxino-lime.dts
+ *
+ * Copyright 2014 - Hans de Goede <hdegoede@redhat.com>
+ * Copyright (c) 2014 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Olimex A20-OLinuXino-LIME";
+ compatible = "olimex,a20-olinuxino-lime", "allwinner,sun7i-a20";
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ahci: sata@01c18000 {
+ target-supply = <&reg_ahci_5v>;
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ ahci_pwr_pin_olinuxinolime: ahci_pwr_pin@1 {
+ allwinner,pins = "PC3";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ led_pins_olinuxinolime: led_pins@0 {
+ allwinner,pins = "PH2";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ gmac: ethernet@01c50000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_mii_a>;
+ phy = <&phy1>;
+ phy-mode = "mii";
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_olinuxinolime>;
+
+ green {
+ label = "a20-olinuxino-lime:green:usr";
+ gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ reg_ahci_5v: ahci-5v {
+ pinctrl-0 = <&ahci_pwr_pin_olinuxinolime>;
+ gpio = <&pio 2 3 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
new file mode 100644
index 000000000..260dbd3bf
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2014 - Iain Paton <ipaton0@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Olimex A20-OLinuXino-LIME2";
+ compatible = "olimex,a20-olinuxino-lime2", "allwinner,sun7i-a20";
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ahci: sata@01c18000 {
+ target-supply = <&reg_ahci_5v>;
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ ahci_pwr_pin_olinuxinolime: ahci_pwr_pin@1 {
+ allwinner,pins = "PC3";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ led_pins_olinuxinolime: led_pins@0 {
+ allwinner,pins = "PH2";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ acin-supply = <&reg_axp_ipsout>;
+ vin2-supply = <&reg_axp_ipsout>;
+ vin3-supply = <&reg_axp_ipsout>;
+ ldo24in-supply = <&reg_axp_ipsout>;
+ ldo3in-supply = <&reg_axp_ipsout>;
+
+ regulators {
+ vdd_rtc: ldo1 {
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ };
+
+ avcc: ldo2 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vcc_csi0: ldo3 {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <3500000>;
+ regulator-always-on;
+ };
+
+ vcc_csi1: ldo4 {
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_cpu: dcdc2 {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <2275000>;
+ regulator-always-on;
+ };
+
+ vdd_int: dcdc3 {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <3500000>;
+ regulator-always-on;
+ };
+ };
+ };
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
+
+ gmac: ethernet@01c50000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_rgmii_a>;
+ phy = <&phy1>;
+ phy-mode = "rgmii";
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_olinuxinolime>;
+
+ green {
+ label = "a20-olinuxino-lime2:green:usr";
+ gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ reg_ahci_5v: ahci-5v {
+ pinctrl-0 = <&ahci_pwr_pin_olinuxinolime>;
+ gpio = <&pio 2 3 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ status = "okay";
+ };
+
+ reg_axp_ipsout: axp_ipsout {
+ compatible = "regulator-fixed";
+ regulator-name = "axp-ipsout";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
new file mode 100644
index 000000000..714e15ac5
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2013 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.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
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Olimex A20-Olinuxino Micro";
+ compatible = "olimex,a20-olinuxino-micro", "allwinner,sun7i-a20";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart6;
+ serial2 = &uart7;
+ spi0 = &spi1;
+ spi1 = &spi2;
+ };
+
+ soc@01c00000 {
+ spi1: spi@01c06000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins_a>;
+ status = "okay";
+ };
+
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ mmc3: mmc@01c12000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc3_pins_a>, <&mmc3_cd_pin_olinuxinom>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 11 GPIO_ACTIVE_HIGH>; /* PH11 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ spi2: spi@01c17000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_pins_a>;
+ status = "okay";
+ };
+
+ ahci: sata@01c18000 {
+ target-supply = <&reg_ahci_5v>;
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ mmc3_cd_pin_olinuxinom: mmc3_cd_pin@0 {
+ allwinner,pins = "PH11";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ led_pins_olinuxino: led_pins@0 {
+ allwinner,pins = "PH2";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ lradc: lradc@01c22800 {
+ vref-supply = <&reg_vcc3v0>;
+ status = "okay";
+
+ button@191 {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ channel = <0>;
+ voltage = <191274>;
+ };
+
+ button@392 {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ channel = <0>;
+ voltage = <392644>;
+ };
+
+ button@601 {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ channel = <0>;
+ voltage = <601151>;
+ };
+
+ button@795 {
+ label = "Search";
+ linux,code = <KEY_SEARCH>;
+ channel = <0>;
+ voltage = <795090>;
+ };
+
+ button@987 {
+ label = "Home";
+ linux,code = <KEY_HOMEPAGE>;
+ channel = <0>;
+ voltage = <987387>;
+ };
+
+ button@1184 {
+ label = "Esc";
+ linux,code = <KEY_ESC>;
+ channel = <0>;
+ voltage = <1184678>;
+ };
+
+ button@1398 {
+ label = "Enter";
+ linux,code = <KEY_ENTER>;
+ channel = <0>;
+ voltage = <1398804>;
+ };
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ uart6: serial@01c29800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart6_pins_a>;
+ status = "okay";
+ };
+
+ uart7: serial@01c29c00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart7_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
+
+ i2c2: i2c@01c2b400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+ };
+
+ gmac: ethernet@01c50000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_mii_a>;
+ phy = <&phy1>;
+ phy-mode = "mii";
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_olinuxino>;
+
+ green {
+ label = "a20-olinuxino-micro:green:usr";
+ gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ reg_ahci_5v: ahci-5v {
+ status = "okay";
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
new file mode 100644
index 000000000..0a2c2aeb4
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2014 Zoltan HERPAI
+ * Zoltan HERPAI <wigyori@uid0.hu>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "LinkSprite pcDuino3";
+ compatible = "linksprite,pcduino3", "allwinner,sun7i-a20";
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ usbphy: phy@01c13400 {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
+
+ ehci0: usb@01c14000 {
+ status = "okay";
+ };
+
+ ohci0: usb@01c14400 {
+ status = "okay";
+ };
+
+ ahci: sata@01c18000 {
+ target-supply = <&reg_ahci_5v>;
+ status = "okay";
+ };
+
+ ehci1: usb@01c1c000 {
+ status = "okay";
+ };
+
+ ohci1: usb@01c1c400 {
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ ahci_pwr_pin_a: ahci_pwr_pin@0 {
+ allwinner,pins = "PH2";
+ };
+
+ led_pins_pcduino3: led_pins@0 {
+ allwinner,pins = "PH15", "PH16";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ key_pins_pcduino3: key_pins@0 {
+ allwinner,pins = "PH17", "PH18", "PH19";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ ir0: ir@01c21800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir0_pins_a>;
+ status = "okay";
+ };
+
+ uart0: serial@01c28000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ gmac: ethernet@01c50000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_mii_a>;
+ phy = <&phy1>;
+ phy-mode = "mii";
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_pcduino3>;
+
+ tx {
+ label = "pcduino3:green:tx";
+ gpios = <&pio 7 15 GPIO_ACTIVE_LOW>;
+ };
+
+ rx {
+ label = "pcduino3:green:rx";
+ gpios = <&pio 7 16 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&key_pins_pcduino3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ button@0 {
+ label = "Key Back";
+ linux,code = <KEY_BACK>;
+ gpios = <&pio 7 17 GPIO_ACTIVE_LOW>;
+ };
+ button@1 {
+ label = "Key Home";
+ linux,code = <KEY_HOME>;
+ gpios = <&pio 7 18 GPIO_ACTIVE_LOW>;
+ };
+ button@2 {
+ label = "Key Menu";
+ linux,code = <KEY_MENU>;
+ gpios = <&pio 7 19 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ status = "okay";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ status = "okay";
+ };
+
+ reg_ahci_5v: ahci-5v {
+ gpio = <&pio 7 2 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
new file mode 100644
index 000000000..2b4847c7c
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -0,0 +1,1233 @@
+/*
+ * Copyright 2013 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "skeleton.dtsi"
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/thermal.h>
+
+#include <dt-bindings/dma/sun4i-a10.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ interrupt-parent = <&gic>;
+
+ aliases {
+ ethernet0 = &gmac;
+ };
+
+ chosen {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ framebuffer@0 {
+ compatible = "allwinner,simple-framebuffer", "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0-hdmi";
+ clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>,
+ <&ahb_gates 44>;
+ status = "disabled";
+ };
+
+ framebuffer@1 {
+ compatible = "allwinner,simple-framebuffer",
+ "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0";
+ clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>;
+ status = "disabled";
+ };
+
+ framebuffer@2 {
+ compatible = "allwinner,simple-framebuffer",
+ "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0-tve0";
+ clocks = <&pll5 1>, <&ahb_gates 34>, <&ahb_gates 36>,
+ <&ahb_gates 44>;
+ status = "disabled";
+ };
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0>;
+ clocks = <&cpu>;
+ clock-latency = <244144>; /* 8 32k periods */
+ operating-points = <
+ /* kHz uV */
+ 960000 1400000
+ 912000 1400000
+ 864000 1300000
+ 720000 1200000
+ 528000 1100000
+ 312000 1000000
+ 144000 900000
+ >;
+ #cooling-cells = <2>;
+ cooling-min-level = <0>;
+ cooling-max-level = <6>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <1>;
+ };
+ };
+
+ thermal-zones {
+ cpu_thermal {
+ /* milliseconds */
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&rtp>;
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
+ trips {
+ cpu_alert0: cpu_alert0 {
+ /* milliCelsius */
+ temperature = <75000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu_crit: cpu_crit {
+ /* milliCelsius */
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+ };
+
+ memory {
+ reg = <0x40000000 0x80000000>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a7-pmu", "arm,cortex-a15-pmu";
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ osc24M: clk@01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-osc-clk";
+ reg = <0x01c20050 0x4>;
+ clock-frequency = <24000000>;
+ clock-output-names = "osc24M";
+ };
+
+ osc32k: clk@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ clock-output-names = "osc32k";
+ };
+
+ pll1: clk@01c20000 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-pll1-clk";
+ reg = <0x01c20000 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll1";
+ };
+
+ pll4: clk@01c20018 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun7i-a20-pll4-clk";
+ reg = <0x01c20018 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll4";
+ };
+
+ pll5: clk@01c20020 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-pll5-clk";
+ reg = <0x01c20020 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll5_ddr", "pll5_other";
+ };
+
+ pll6: clk@01c20028 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-pll6-clk";
+ reg = <0x01c20028 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll6_sata", "pll6_other", "pll6";
+ };
+
+ pll8: clk@01c20040 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun7i-a20-pll4-clk";
+ reg = <0x01c20040 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll8";
+ };
+
+ cpu: cpu@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-cpu-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll6 1>;
+ clock-output-names = "cpu";
+ };
+
+ axi: axi@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-axi-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&cpu>;
+ clock-output-names = "axi";
+ };
+
+ ahb: ahb@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-ahb-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&axi>;
+ clock-output-names = "ahb";
+ };
+
+ ahb_gates: clk@01c20060 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun7i-a20-ahb-gates-clk";
+ reg = <0x01c20060 0x8>;
+ clocks = <&ahb>;
+ clock-output-names = "ahb_usb0", "ahb_ehci0",
+ "ahb_ohci0", "ahb_ehci1", "ahb_ohci1",
+ "ahb_ss", "ahb_dma", "ahb_bist", "ahb_mmc0",
+ "ahb_mmc1", "ahb_mmc2", "ahb_mmc3", "ahb_ms",
+ "ahb_nand", "ahb_sdram", "ahb_ace",
+ "ahb_emac", "ahb_ts", "ahb_spi0", "ahb_spi1",
+ "ahb_spi2", "ahb_spi3", "ahb_sata",
+ "ahb_hstimer", "ahb_ve", "ahb_tvd", "ahb_tve0",
+ "ahb_tve1", "ahb_lcd0", "ahb_lcd1", "ahb_csi0",
+ "ahb_csi1", "ahb_hdmi1", "ahb_hdmi0",
+ "ahb_de_be0", "ahb_de_be1", "ahb_de_fe0",
+ "ahb_de_fe1", "ahb_gmac", "ahb_mp",
+ "ahb_mali";
+ };
+
+ apb0: apb0@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb0-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&ahb>;
+ clock-output-names = "apb0";
+ };
+
+ apb0_gates: clk@01c20068 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun7i-a20-apb0-gates-clk";
+ reg = <0x01c20068 0x4>;
+ clocks = <&apb0>;
+ clock-output-names = "apb0_codec", "apb0_spdif",
+ "apb0_ac97", "apb0_iis0", "apb0_iis1",
+ "apb0_pio", "apb0_ir0", "apb0_ir1",
+ "apb0_iis2", "apb0_keypad";
+ };
+
+ apb1: clk@01c20058 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb1-clk";
+ reg = <0x01c20058 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+ clock-output-names = "apb1";
+ };
+
+ apb1_gates: clk@01c2006c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun7i-a20-apb1-gates-clk";
+ reg = <0x01c2006c 0x4>;
+ clocks = <&apb1>;
+ clock-output-names = "apb1_i2c0", "apb1_i2c1",
+ "apb1_i2c2", "apb1_i2c3", "apb1_can",
+ "apb1_scr", "apb1_ps20", "apb1_ps21",
+ "apb1_i2c4", "apb1_uart0", "apb1_uart1",
+ "apb1_uart2", "apb1_uart3", "apb1_uart4",
+ "apb1_uart5", "apb1_uart6", "apb1_uart7";
+ };
+
+ nand_clk: clk@01c20080 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c20080 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "nand";
+ };
+
+ ms_clk: clk@01c20084 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c20084 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ms";
+ };
+
+ mmc0_clk: clk@01c20088 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20088 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "mmc0",
+ "mmc0_output",
+ "mmc0_sample";
+ };
+
+ mmc1_clk: clk@01c2008c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c2008c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "mmc1",
+ "mmc1_output",
+ "mmc1_sample";
+ };
+
+ mmc2_clk: clk@01c20090 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20090 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "mmc2",
+ "mmc2_output",
+ "mmc2_sample";
+ };
+
+ mmc3_clk: clk@01c20094 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20094 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "mmc3",
+ "mmc3_output",
+ "mmc3_sample";
+ };
+
+ ts_clk: clk@01c20098 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c20098 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ts";
+ };
+
+ ss_clk: clk@01c2009c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c2009c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ss";
+ };
+
+ spi0_clk: clk@01c200a0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200a0 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "spi0";
+ };
+
+ spi1_clk: clk@01c200a4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200a4 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "spi1";
+ };
+
+ spi2_clk: clk@01c200a8 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200a8 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "spi2";
+ };
+
+ pata_clk: clk@01c200ac {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200ac 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "pata";
+ };
+
+ ir0_clk: clk@01c200b0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200b0 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ir0";
+ };
+
+ ir1_clk: clk@01c200b4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200b4 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "ir1";
+ };
+
+ usb_clk: clk@01c200cc {
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ compatible = "allwinner,sun4i-a10-usb-clk";
+ reg = <0x01c200cc 0x4>;
+ clocks = <&pll6 1>;
+ clock-output-names = "usb_ohci0", "usb_ohci1", "usb_phy";
+ };
+
+ spi3_clk: clk@01c200d4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200d4 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ clock-output-names = "spi3";
+ };
+
+ mbus_clk: clk@01c2015c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun5i-a13-mbus-clk";
+ reg = <0x01c2015c 0x4>;
+ clocks = <&osc24M>, <&pll6 2>, <&pll5 1>;
+ clock-output-names = "mbus";
+ };
+
+ /*
+ * The following two are dummy clocks, placeholders used in the gmac_tx
+ * clock. The gmac driver will choose one parent depending on the PHY
+ * interface mode, using clk_set_rate auto-reparenting.
+ * The actual TX clock rate is not controlled by the gmac_tx clock.
+ */
+ mii_phy_tx_clk: clk@2 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <25000000>;
+ clock-output-names = "mii_phy_tx";
+ };
+
+ gmac_int_tx_clk: clk@3 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <125000000>;
+ clock-output-names = "gmac_int_tx";
+ };
+
+ gmac_tx_clk: clk@01c20164 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun7i-a20-gmac-clk";
+ reg = <0x01c20164 0x4>;
+ clocks = <&mii_phy_tx_clk>, <&gmac_int_tx_clk>;
+ clock-output-names = "gmac_tx";
+ };
+
+ /*
+ * Dummy clock used by output clocks
+ */
+ osc24M_32k: clk@1 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <750>;
+ clock-mult = <1>;
+ clocks = <&osc24M>;
+ clock-output-names = "osc24M_32k";
+ };
+
+ clk_out_a: clk@01c201f0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun7i-a20-out-clk";
+ reg = <0x01c201f0 0x4>;
+ clocks = <&osc24M_32k>, <&osc32k>, <&osc24M>;
+ clock-output-names = "clk_out_a";
+ };
+
+ clk_out_b: clk@01c201f4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun7i-a20-out-clk";
+ reg = <0x01c201f4 0x4>;
+ clocks = <&osc24M_32k>, <&osc32k>, <&osc24M>;
+ clock-output-names = "clk_out_b";
+ };
+ };
+
+ soc@01c00000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ nmi_intc: interrupt-controller@01c00030 {
+ compatible = "allwinner,sun7i-a20-sc-nmi";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x01c00030 0x0c>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma: dma-controller@01c02000 {
+ compatible = "allwinner,sun4i-a10-dma";
+ reg = <0x01c02000 0x1000>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb_gates 6>;
+ #dma-cells = <2>;
+ };
+
+ spi0: spi@01c05000 {
+ compatible = "allwinner,sun4i-a10-spi";
+ reg = <0x01c05000 0x1000>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb_gates 20>, <&spi0_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma SUN4I_DMA_DEDICATED 27>,
+ <&dma SUN4I_DMA_DEDICATED 26>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ spi1: spi@01c06000 {
+ compatible = "allwinner,sun4i-a10-spi";
+ reg = <0x01c06000 0x1000>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb_gates 21>, <&spi1_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma SUN4I_DMA_DEDICATED 9>,
+ <&dma SUN4I_DMA_DEDICATED 8>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ emac: ethernet@01c0b000 {
+ compatible = "allwinner,sun4i-a10-emac";
+ reg = <0x01c0b000 0x1000>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb_gates 17>;
+ status = "disabled";
+ };
+
+ mdio: mdio@01c0b080 {
+ compatible = "allwinner,sun4i-a10-mdio";
+ reg = <0x01c0b080 0x14>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ mmc0: mmc@01c0f000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&ahb_gates 8>,
+ <&mmc0_clk 0>,
+ <&mmc0_clk 1>,
+ <&mmc0_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@01c10000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c10000 0x1000>;
+ clocks = <&ahb_gates 9>,
+ <&mmc1_clk 0>,
+ <&mmc1_clk 1>,
+ <&mmc1_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc2: mmc@01c11000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c11000 0x1000>;
+ clocks = <&ahb_gates 10>,
+ <&mmc2_clk 0>,
+ <&mmc2_clk 1>,
+ <&mmc2_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc3: mmc@01c12000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c12000 0x1000>;
+ clocks = <&ahb_gates 11>,
+ <&mmc3_clk 0>,
+ <&mmc3_clk 1>,
+ <&mmc3_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ usbphy: phy@01c13400 {
+ #phy-cells = <1>;
+ compatible = "allwinner,sun7i-a20-usb-phy";
+ reg = <0x01c13400 0x10 0x01c14800 0x4 0x01c1c800 0x4>;
+ reg-names = "phy_ctrl", "pmu1", "pmu2";
+ clocks = <&usb_clk 8>;
+ clock-names = "usb_phy";
+ resets = <&usb_clk 0>, <&usb_clk 1>, <&usb_clk 2>;
+ reset-names = "usb0_reset", "usb1_reset", "usb2_reset";
+ status = "disabled";
+ };
+
+ ehci0: usb@01c14000 {
+ compatible = "allwinner,sun7i-a20-ehci", "generic-ehci";
+ reg = <0x01c14000 0x100>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb_gates 1>;
+ phys = <&usbphy 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ ohci0: usb@01c14400 {
+ compatible = "allwinner,sun7i-a20-ohci", "generic-ohci";
+ reg = <0x01c14400 0x100>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&usb_clk 6>, <&ahb_gates 2>;
+ phys = <&usbphy 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ spi2: spi@01c17000 {
+ compatible = "allwinner,sun4i-a10-spi";
+ reg = <0x01c17000 0x1000>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb_gates 22>, <&spi2_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma SUN4I_DMA_DEDICATED 29>,
+ <&dma SUN4I_DMA_DEDICATED 28>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ ahci: sata@01c18000 {
+ compatible = "allwinner,sun4i-a10-ahci";
+ reg = <0x01c18000 0x1000>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&pll6 0>, <&ahb_gates 25>;
+ status = "disabled";
+ };
+
+ ehci1: usb@01c1c000 {
+ compatible = "allwinner,sun7i-a20-ehci", "generic-ehci";
+ reg = <0x01c1c000 0x100>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb_gates 3>;
+ phys = <&usbphy 2>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ ohci1: usb@01c1c400 {
+ compatible = "allwinner,sun7i-a20-ohci", "generic-ohci";
+ reg = <0x01c1c400 0x100>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&usb_clk 7>, <&ahb_gates 4>;
+ phys = <&usbphy 2>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ spi3: spi@01c1f000 {
+ compatible = "allwinner,sun4i-a10-spi";
+ reg = <0x01c1f000 0x1000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb_gates 23>, <&spi3_clk>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma SUN4I_DMA_DEDICATED 31>,
+ <&dma SUN4I_DMA_DEDICATED 30>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ pio: pinctrl@01c20800 {
+ compatible = "allwinner,sun7i-a20-pinctrl";
+ reg = <0x01c20800 0x400>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb0_gates 5>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ #size-cells = <0>;
+ #gpio-cells = <3>;
+
+ pwm0_pins_a: pwm0@0 {
+ allwinner,pins = "PB2";
+ allwinner,function = "pwm";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ pwm1_pins_a: pwm1@0 {
+ allwinner,pins = "PI3";
+ allwinner,function = "pwm";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart0_pins_a: uart0@0 {
+ allwinner,pins = "PB22", "PB23";
+ allwinner,function = "uart0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart2_pins_a: uart2@0 {
+ allwinner,pins = "PI16", "PI17", "PI18", "PI19";
+ allwinner,function = "uart2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart3_pins_a: uart3@0 {
+ allwinner,pins = "PG6", "PG7", "PG8", "PG9";
+ allwinner,function = "uart3";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart3_pins_b: uart3@1 {
+ allwinner,pins = "PH0", "PH1";
+ allwinner,function = "uart3";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart4_pins_a: uart4@0 {
+ allwinner,pins = "PG10", "PG11";
+ allwinner,function = "uart4";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart5_pins_a: uart5@0 {
+ allwinner,pins = "PI10", "PI11";
+ allwinner,function = "uart5";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart6_pins_a: uart6@0 {
+ allwinner,pins = "PI12", "PI13";
+ allwinner,function = "uart6";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart7_pins_a: uart7@0 {
+ allwinner,pins = "PI20", "PI21";
+ allwinner,function = "uart7";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c0_pins_a: i2c0@0 {
+ allwinner,pins = "PB0", "PB1";
+ allwinner,function = "i2c0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c1_pins_a: i2c1@0 {
+ allwinner,pins = "PB18", "PB19";
+ allwinner,function = "i2c1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c2_pins_a: i2c2@0 {
+ allwinner,pins = "PB20", "PB21";
+ allwinner,function = "i2c2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c3_pins_a: i2c3@0 {
+ allwinner,pins = "PI0", "PI1";
+ allwinner,function = "i2c3";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ emac_pins_a: emac0@0 {
+ allwinner,pins = "PA0", "PA1", "PA2",
+ "PA3", "PA4", "PA5", "PA6",
+ "PA7", "PA8", "PA9", "PA10",
+ "PA11", "PA12", "PA13", "PA14",
+ "PA15", "PA16";
+ allwinner,function = "emac";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ clk_out_a_pins_a: clk_out_a@0 {
+ allwinner,pins = "PI12";
+ allwinner,function = "clk_out_a";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ clk_out_b_pins_a: clk_out_b@0 {
+ allwinner,pins = "PI13";
+ allwinner,function = "clk_out_b";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ gmac_pins_mii_a: gmac_mii@0 {
+ allwinner,pins = "PA0", "PA1", "PA2",
+ "PA3", "PA4", "PA5", "PA6",
+ "PA7", "PA8", "PA9", "PA10",
+ "PA11", "PA12", "PA13", "PA14",
+ "PA15", "PA16";
+ allwinner,function = "gmac";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ gmac_pins_rgmii_a: gmac_rgmii@0 {
+ allwinner,pins = "PA0", "PA1", "PA2",
+ "PA3", "PA4", "PA5", "PA6",
+ "PA7", "PA8", "PA10",
+ "PA11", "PA12", "PA13",
+ "PA15", "PA16";
+ allwinner,function = "gmac";
+ /*
+ * data lines in RGMII mode use DDR mode
+ * and need a higher signal drive strength
+ */
+ allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ spi0_pins_a: spi0@0 {
+ allwinner,pins = "PI10", "PI11", "PI12", "PI13", "PI14";
+ allwinner,function = "spi0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ spi1_pins_a: spi1@0 {
+ allwinner,pins = "PI16", "PI17", "PI18", "PI19";
+ allwinner,function = "spi1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ spi2_pins_a: spi2@0 {
+ allwinner,pins = "PC19", "PC20", "PC21", "PC22";
+ allwinner,function = "spi2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ spi2_pins_b: spi2@1 {
+ allwinner,pins = "PB14", "PB15", "PB16", "PB17";
+ allwinner,function = "spi2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_pins_a: mmc0@0 {
+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_cd_pin_reference_design: mmc0_cd_pin@0 {
+ allwinner,pins = "PH1";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ mmc2_pins_a: mmc2@0 {
+ allwinner,pins = "PC6","PC7","PC8","PC9","PC10","PC11";
+ allwinner,function = "mmc2";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ mmc3_pins_a: mmc3@0 {
+ allwinner,pins = "PI4","PI5","PI6","PI7","PI8","PI9";
+ allwinner,function = "mmc3";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ ir0_pins_a: ir0@0 {
+ allwinner,pins = "PB3","PB4";
+ allwinner,function = "ir0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ ir1_pins_a: ir1@0 {
+ allwinner,pins = "PB22","PB23";
+ allwinner,function = "ir1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ ps20_pins_a: ps20@0 {
+ allwinner,pins = "PI20", "PI21";
+ allwinner,function = "ps2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ ps21_pins_a: ps21@0 {
+ allwinner,pins = "PH12", "PH13";
+ allwinner,function = "ps2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ timer@01c20c00 {
+ compatible = "allwinner,sun4i-a10-timer";
+ reg = <0x01c20c00 0x90>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc24M>;
+ };
+
+ wdt: watchdog@01c20c90 {
+ compatible = "allwinner,sun4i-a10-wdt";
+ reg = <0x01c20c90 0x10>;
+ };
+
+ rtc: rtc@01c20d00 {
+ compatible = "allwinner,sun7i-a20-rtc";
+ reg = <0x01c20d00 0x20>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pwm: pwm@01c20e00 {
+ compatible = "allwinner,sun7i-a20-pwm";
+ reg = <0x01c20e00 0xc>;
+ clocks = <&osc24M>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ ir0: ir@01c21800 {
+ compatible = "allwinner,sun4i-a10-ir";
+ clocks = <&apb0_gates 6>, <&ir0_clk>;
+ clock-names = "apb", "ir";
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x01c21800 0x40>;
+ status = "disabled";
+ };
+
+ ir1: ir@01c21c00 {
+ compatible = "allwinner,sun4i-a10-ir";
+ clocks = <&apb0_gates 7>, <&ir1_clk>;
+ clock-names = "apb", "ir";
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x01c21c00 0x40>;
+ status = "disabled";
+ };
+
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-a10-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ sid: eeprom@01c23800 {
+ compatible = "allwinner,sun7i-a20-sid";
+ reg = <0x01c23800 0x200>;
+ };
+
+ rtp: rtp@01c25000 {
+ compatible = "allwinner,sun5i-a13-ts";
+ reg = <0x01c25000 0x100>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ uart0: serial@01c28000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28000 0x400>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 16>;
+ status = "disabled";
+ };
+
+ uart1: serial@01c28400 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28400 0x400>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 17>;
+ status = "disabled";
+ };
+
+ uart2: serial@01c28800 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28800 0x400>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 18>;
+ status = "disabled";
+ };
+
+ uart3: serial@01c28c00 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28c00 0x400>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 19>;
+ status = "disabled";
+ };
+
+ uart4: serial@01c29000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c29000 0x400>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 20>;
+ status = "disabled";
+ };
+
+ uart5: serial@01c29400 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c29400 0x400>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 21>;
+ status = "disabled";
+ };
+
+ uart6: serial@01c29800 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c29800 0x400>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 22>;
+ status = "disabled";
+ };
+
+ uart7: serial@01c29c00 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c29c00 0x400>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 23>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
+ reg = <0x01c2ac00 0x400>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 0>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c1: i2c@01c2b000 {
+ compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
+ reg = <0x01c2b000 0x400>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 1>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c2: i2c@01c2b400 {
+ compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
+ reg = <0x01c2b400 0x400>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 2>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c3: i2c@01c2b800 {
+ compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
+ reg = <0x01c2b800 0x400>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 3>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c4: i2c@01c2c000 {
+ compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
+ reg = <0x01c2c000 0x400>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 15>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ gmac: ethernet@01c50000 {
+ compatible = "allwinner,sun7i-a20-gmac";
+ reg = <0x01c50000 0x10000>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ clocks = <&ahb_gates 49>, <&gmac_tx_clk>;
+ clock-names = "stmmaceth", "allwinner_gmac_tx";
+ snps,pbl = <2>;
+ snps,fixed-burst;
+ snps,force_sf_dma_mode;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ hstimer@01c60000 {
+ compatible = "allwinner,sun7i-a20-hstimer";
+ reg = <0x01c60000 0x1000>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb_gates 28>;
+ };
+
+ gic: interrupt-controller@01c81000 {
+ compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
+ reg = <0x01c81000 0x1000>,
+ <0x01c82000 0x1000>,
+ <0x01c84000 0x2000>,
+ <0x01c86000 0x2000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ ps20: ps2@01c2a000 {
+ compatible = "allwinner,sun4i-a10-ps2";
+ reg = <0x01c2a000 0x400>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 6>;
+ status = "disabled";
+ };
+
+ ps21: ps2@01c2a400 {
+ compatible = "allwinner,sun4i-a10-ps2";
+ reg = <0x01c2a400 0x400>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 7>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts
new file mode 100644
index 000000000..dd31c53e2
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * The Ippo Q8H v1.2 is almost identical to the v5, still it needs a separate
+ * dtb file since some gpio-s surrounding the wlan/bluetooth are different,
+ * and it uses different camera sensors.
+ */
+
+#include "sun8i-a23-ippo-q8h-v5.dts"
+
+/ {
+ model = "Ippo Q8H Dual Core Tablet (v1.2)";
+ compatible = "ippo,q8h-v1.2", "allwinner,sun8i-a23";
+};
diff --git a/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts
new file mode 100644
index 000000000..623573e46
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2014 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai <wens@csie.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun8i-a23.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Ippo Q8H Dual Core Tablet (v5)";
+ compatible = "ippo,q8h-v5", "allwinner,sun8i-a23";
+
+ aliases {
+ serial0 = &r_uart;
+ };
+
+ chosen {
+ bootargs = "earlyprintk console=ttyS0,115200";
+ };
+
+ soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_q8h>;
+ vmmc-supply = <&reg_vcc3v0>;
+ bus-width = <4>;
+ cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */
+ cd-inverted;
+ status = "okay";
+ };
+
+ pinctrl@01c20800 {
+ mmc0_cd_pin_q8h: mmc0_cd_pin@0 {
+ allwinner,pins = "PB4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+ };
+
+ lradc: lradc@01c22800 {
+ vref-supply = <&reg_vcc3v0>;
+ status = "okay";
+
+ button@200 {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ channel = <0>;
+ voltage = <200000>;
+ };
+
+ button@400 {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ channel = <0>;
+ voltage = <400000>;
+ };
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
+
+ i2c2: i2c@01c2b400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ /* pull-ups and devices require PMIC regulator */
+ status = "failed";
+ };
+
+ r_uart: serial@01f02800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&r_uart_pins_a>;
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi
new file mode 100644
index 000000000..382ebd137
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-a23.dtsi
@@ -0,0 +1,611 @@
+/*
+ * Copyright 2014 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai <wens@csie.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "skeleton.dtsi"
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ interrupt-parent = <&gic>;
+
+ chosen {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ framebuffer@0 {
+ compatible = "allwinner,simple-framebuffer",
+ "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0";
+ clocks = <&pll6 0>;
+ status = "disabled";
+ };
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <1>;
+ };
+ };
+
+ memory {
+ reg = <0x40000000 0x40000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ osc24M: osc24M_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "osc24M";
+ };
+
+ osc32k: osc32k_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ clock-output-names = "osc32k";
+ };
+
+ pll1: clk@01c20000 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun8i-a23-pll1-clk";
+ reg = <0x01c20000 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll1";
+ };
+
+ /* dummy clock until actually implemented */
+ pll5: pll5_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ clock-output-names = "pll5";
+ };
+
+ pll6: clk@01c20028 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun6i-a31-pll6-clk";
+ reg = <0x01c20028 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll6", "pll6x2";
+ };
+
+ cpu: cpu_clk@01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-cpu-clk";
+ reg = <0x01c20050 0x4>;
+
+ /*
+ * PLL1 is listed twice here.
+ * While it looks suspicious, it's actually documented
+ * that way both in the datasheet and in the code from
+ * Allwinner.
+ */
+ clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll1>;
+ clock-output-names = "cpu";
+ };
+
+ axi: axi_clk@01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun8i-a23-axi-clk";
+ reg = <0x01c20050 0x4>;
+ clocks = <&cpu>;
+ clock-output-names = "axi";
+ };
+
+ ahb1: ahb1_clk@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun6i-a31-ahb1-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>;
+ clock-output-names = "ahb1";
+ };
+
+ apb1: apb1_clk@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb0-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&ahb1>;
+ clock-output-names = "apb1";
+ };
+
+ ahb1_gates: clk@01c20060 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun8i-a23-ahb1-gates-clk";
+ reg = <0x01c20060 0x8>;
+ clocks = <&ahb1>;
+ clock-output-names = "ahb1_mipidsi", "ahb1_dma",
+ "ahb1_mmc0", "ahb1_mmc1", "ahb1_mmc2",
+ "ahb1_nand", "ahb1_sdram",
+ "ahb1_hstimer", "ahb1_spi0",
+ "ahb1_spi1", "ahb1_otg", "ahb1_ehci",
+ "ahb1_ohci", "ahb1_ve", "ahb1_lcd",
+ "ahb1_csi", "ahb1_be", "ahb1_fe",
+ "ahb1_gpu", "ahb1_spinlock",
+ "ahb1_drc";
+ };
+
+ apb1_gates: clk@01c20068 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun8i-a23-apb1-gates-clk";
+ reg = <0x01c20068 0x4>;
+ clocks = <&apb1>;
+ clock-output-names = "apb1_codec", "apb1_pio",
+ "apb1_daudio0", "apb1_daudio1";
+ };
+
+ apb2: clk@01c20058 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb1-clk";
+ reg = <0x01c20058 0x4>;
+ clocks = <&osc32k>, <&osc24M>, <&pll6 0>, <&pll6 0>;
+ clock-output-names = "apb2";
+ };
+
+ apb2_gates: clk@01c2006c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun8i-a23-apb2-gates-clk";
+ reg = <0x01c2006c 0x4>;
+ clocks = <&apb2>;
+ clock-output-names = "apb2_i2c0", "apb2_i2c1",
+ "apb2_i2c2", "apb2_uart0",
+ "apb2_uart1", "apb2_uart2",
+ "apb2_uart3", "apb2_uart4";
+ };
+
+ mmc0_clk: clk@01c20088 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20088 0x4>;
+ clocks = <&osc24M>, <&pll6 0>;
+ clock-output-names = "mmc0",
+ "mmc0_output",
+ "mmc0_sample";
+ };
+
+ mmc1_clk: clk@01c2008c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c2008c 0x4>;
+ clocks = <&osc24M>, <&pll6 0>;
+ clock-output-names = "mmc1",
+ "mmc1_output",
+ "mmc1_sample";
+ };
+
+ mmc2_clk: clk@01c20090 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20090 0x4>;
+ clocks = <&osc24M>, <&pll6 0>;
+ clock-output-names = "mmc2",
+ "mmc2_output",
+ "mmc2_sample";
+ };
+
+ mbus_clk: clk@01c2015c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun8i-a23-mbus-clk";
+ reg = <0x01c2015c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5>;
+ clock-output-names = "mbus";
+ };
+ };
+
+ soc@01c00000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dma: dma-controller@01c02000 {
+ compatible = "allwinner,sun8i-a23-dma";
+ reg = <0x01c02000 0x1000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb1_gates 6>;
+ resets = <&ahb1_rst 6>;
+ #dma-cells = <1>;
+ };
+
+ mmc0: mmc@01c0f000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&ahb1_gates 8>,
+ <&mmc0_clk 0>,
+ <&mmc0_clk 1>,
+ <&mmc0_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ resets = <&ahb1_rst 8>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@01c10000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c10000 0x1000>;
+ clocks = <&ahb1_gates 9>,
+ <&mmc1_clk 0>,
+ <&mmc1_clk 1>,
+ <&mmc1_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ resets = <&ahb1_rst 9>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc2: mmc@01c11000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c11000 0x1000>;
+ clocks = <&ahb1_gates 10>,
+ <&mmc2_clk 0>,
+ <&mmc2_clk 1>,
+ <&mmc2_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ resets = <&ahb1_rst 10>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ pio: pinctrl@01c20800 {
+ compatible = "allwinner,sun8i-a23-pinctrl";
+ reg = <0x01c20800 0x400>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 5>;
+ gpio-controller;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #gpio-cells = <3>;
+
+ uart0_pins_a: uart0@0 {
+ allwinner,pins = "PF2", "PF4";
+ allwinner,function = "uart0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_pins_a: mmc0@0 {
+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc1_pins_a: mmc1@0 {
+ allwinner,pins = "PG0","PG1","PG2","PG3","PG4","PG5";
+ allwinner,function = "mmc1";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c0_pins_a: i2c0@0 {
+ allwinner,pins = "PH2", "PH3";
+ allwinner,function = "i2c0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c1_pins_a: i2c1@0 {
+ allwinner,pins = "PH4", "PH5";
+ allwinner,function = "i2c1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ i2c2_pins_a: i2c2@0 {
+ allwinner,pins = "PE12", "PE13";
+ allwinner,function = "i2c2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ ahb1_rst: reset@01c202c0 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ reg = <0x01c202c0 0xc>;
+ };
+
+ apb1_rst: reset@01c202d0 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ reg = <0x01c202d0 0x4>;
+ };
+
+ apb2_rst: reset@01c202d8 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ reg = <0x01c202d8 0x4>;
+ };
+
+ timer@01c20c00 {
+ compatible = "allwinner,sun4i-a10-timer";
+ reg = <0x01c20c00 0xa0>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc24M>;
+ };
+
+ wdt0: watchdog@01c20ca0 {
+ compatible = "allwinner,sun6i-a31-wdt";
+ reg = <0x01c20ca0 0x20>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-a10-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ uart0: serial@01c28000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28000 0x400>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb2_gates 16>;
+ resets = <&apb2_rst 16>;
+ dmas = <&dma 6>, <&dma 6>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart1: serial@01c28400 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28400 0x400>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb2_gates 17>;
+ resets = <&apb2_rst 17>;
+ dmas = <&dma 7>, <&dma 7>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart2: serial@01c28800 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28800 0x400>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb2_gates 18>;
+ resets = <&apb2_rst 18>;
+ dmas = <&dma 8>, <&dma 8>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart3: serial@01c28c00 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28c00 0x400>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb2_gates 19>;
+ resets = <&apb2_rst 19>;
+ dmas = <&dma 9>, <&dma 9>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart4: serial@01c29000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c29000 0x400>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb2_gates 20>;
+ resets = <&apb2_rst 20>;
+ dmas = <&dma 10>, <&dma 10>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ compatible = "allwinner,sun6i-a31-i2c";
+ reg = <0x01c2ac00 0x400>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb2_gates 0>;
+ resets = <&apb2_rst 0>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c1: i2c@01c2b000 {
+ compatible = "allwinner,sun6i-a31-i2c";
+ reg = <0x01c2b000 0x400>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb2_gates 1>;
+ resets = <&apb2_rst 1>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c2: i2c@01c2b400 {
+ compatible = "allwinner,sun6i-a31-i2c";
+ reg = <0x01c2b400 0x400>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb2_gates 2>;
+ resets = <&apb2_rst 2>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ gic: interrupt-controller@01c81000 {
+ compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
+ reg = <0x01c81000 0x1000>,
+ <0x01c82000 0x1000>,
+ <0x01c84000 0x2000>,
+ <0x01c86000 0x2000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ rtc: rtc@01f00000 {
+ compatible = "allwinner,sun6i-a31-rtc";
+ reg = <0x01f00000 0x54>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ prcm@01f01400 {
+ compatible = "allwinner,sun8i-a23-prcm";
+ reg = <0x01f01400 0x200>;
+
+ ar100: ar100_clk {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ clocks = <&osc24M>;
+ clock-output-names = "ar100";
+ };
+
+ ahb0: ahb0_clk {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ clocks = <&ar100>;
+ clock-output-names = "ahb0";
+ };
+
+ apb0: apb0_clk {
+ compatible = "allwinner,sun8i-a23-apb0-clk";
+ #clock-cells = <0>;
+ clocks = <&ahb0>;
+ clock-output-names = "apb0";
+ };
+
+ apb0_gates: apb0_gates_clk {
+ compatible = "allwinner,sun8i-a23-apb0-gates-clk";
+ #clock-cells = <1>;
+ clocks = <&apb0>;
+ clock-output-names = "apb0_pio", "apb0_timer",
+ "apb0_rsb", "apb0_uart",
+ "apb0_i2c";
+ };
+
+ apb0_rst: apb0_rst {
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ #reset-cells = <1>;
+ };
+ };
+
+ r_uart: serial@01f02800 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01f02800 0x400>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb0_gates 4>;
+ resets = <&apb0_rst 4>;
+ status = "disabled";
+ };
+
+ r_pio: pinctrl@01f02c00 {
+ compatible = "allwinner,sun8i-a23-r-pinctrl";
+ reg = <0x01f02c00 0x400>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb0_gates 0>;
+ resets = <&apb0_rst 0>;
+ gpio-controller;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #gpio-cells = <3>;
+
+ r_uart_pins_a: r_uart@0 {
+ allwinner,pins = "PL2", "PL3";
+ allwinner,function = "s_uart";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts
new file mode 100644
index 000000000..a3fed2bdf
--- /dev/null
+++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2014 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai <wens@csie.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun9i-a80.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Merrii A80 Optimus Board";
+ compatible = "merrii,a80-optimus", "allwinner,sun9i-a80";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart4;
+ };
+
+ chosen {
+ bootargs = "earlyprintk console=ttyS0,115200";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_optimus>;
+
+ /* The LED names match those found on the board */
+
+ led2 {
+ label = "optimus:led2:usr";
+ gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>;
+ };
+
+ /* led3 is on PM15, in R_PIO */
+
+ led4 {
+ label = "optimus:led4:usr";
+ gpios = <&pio 7 0 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins_a>;
+ status = "okay";
+};
+
+&i2c3_pins_a {
+ /* Enable internal pull-up */
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+};
+
+&pio {
+ led_pins_optimus: led-pins@0 {
+ allwinner,pins = "PH0", "PH1";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_cd_pin_optimus: mmc0_cd_pin@0 {
+ allwinner,pins = "PH18";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins>, <&mmc0_cd_pin_optimus>;
+ vmmc-supply = <&reg_vcc3v0>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 18 GPIO_ACTIVE_HIGH>; /* PH8 */
+ cd-inverted;
+ status = "okay";
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_8bit_pins>;
+ vmmc-supply = <&reg_vcc3v0>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins_a>;
+ status = "okay";
+};
+
+&uart4_pins_a {
+ /* Enable internal pull-up */
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+};
diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
new file mode 100644
index 000000000..f0f6fb91f
--- /dev/null
+++ b/arch/arm/boot/dts/sun9i-a80.dtsi
@@ -0,0 +1,632 @@
+/*
+ * Copyright 2014 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai <wens@csie.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "skeleton64.dtsi"
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0x0>;
+ };
+
+ cpu1: cpu@1 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0x1>;
+ };
+
+ cpu2: cpu@2 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0x2>;
+ };
+
+ cpu3: cpu@3 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0x3>;
+ };
+
+ cpu4: cpu@100 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <0x100>;
+ };
+
+ cpu5: cpu@101 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <0x101>;
+ };
+
+ cpu6: cpu@102 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <0x102>;
+ };
+
+ cpu7: cpu@103 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <0x103>;
+ };
+ };
+
+ memory {
+ /* 8GB max. with LPAE */
+ reg = <0 0x20000000 0x02 0>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ /*
+ * map 64 bit address range down to 32 bits,
+ * as the peripherals are all under 512MB.
+ */
+ ranges = <0 0 0 0x20000000>;
+
+ osc24M: osc24M_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "osc24M";
+ };
+
+ osc32k: osc32k_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ clock-output-names = "osc32k";
+ };
+
+ pll4: clk@0600000c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun9i-a80-pll4-clk";
+ reg = <0x0600000c 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll4";
+ };
+
+ pll12: clk@0600002c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun9i-a80-pll4-clk";
+ reg = <0x0600002c 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll12";
+ };
+
+ gt_clk: clk@0600005c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun9i-a80-gt-clk";
+ reg = <0x0600005c 0x4>;
+ clocks = <&osc24M>, <&pll4>, <&pll12>, <&pll12>;
+ clock-output-names = "gt";
+ };
+
+ ahb0: clk@06000060 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun9i-a80-ahb-clk";
+ reg = <0x06000060 0x4>;
+ clocks = <&gt_clk>, <&pll4>, <&pll12>, <&pll12>;
+ clock-output-names = "ahb0";
+ };
+
+ ahb1: clk@06000064 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun9i-a80-ahb-clk";
+ reg = <0x06000064 0x4>;
+ clocks = <&gt_clk>, <&pll4>, <&pll12>, <&pll12>;
+ clock-output-names = "ahb1";
+ };
+
+ ahb2: clk@06000068 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun9i-a80-ahb-clk";
+ reg = <0x06000068 0x4>;
+ clocks = <&gt_clk>, <&pll4>, <&pll12>, <&pll12>;
+ clock-output-names = "ahb2";
+ };
+
+ apb0: clk@06000070 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun9i-a80-apb0-clk";
+ reg = <0x06000070 0x4>;
+ clocks = <&osc24M>, <&pll4>;
+ clock-output-names = "apb0";
+ };
+
+ apb1: clk@06000074 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun9i-a80-apb1-clk";
+ reg = <0x06000074 0x4>;
+ clocks = <&osc24M>, <&pll4>;
+ clock-output-names = "apb1";
+ };
+
+ cci400_clk: clk@06000078 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun9i-a80-gt-clk";
+ reg = <0x06000078 0x4>;
+ clocks = <&osc24M>, <&pll4>, <&pll12>, <&pll12>;
+ clock-output-names = "cci400";
+ };
+
+ mmc0_clk: clk@06000410 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun9i-a80-mmc-clk";
+ reg = <0x06000410 0x4>;
+ clocks = <&osc24M>, <&pll4>;
+ clock-output-names = "mmc0", "mmc0_output",
+ "mmc0_sample";
+ };
+
+ mmc1_clk: clk@06000414 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun9i-a80-mmc-clk";
+ reg = <0x06000414 0x4>;
+ clocks = <&osc24M>, <&pll4>;
+ clock-output-names = "mmc1", "mmc1_output",
+ "mmc1_sample";
+ };
+
+ mmc2_clk: clk@06000418 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun9i-a80-mmc-clk";
+ reg = <0x06000418 0x4>;
+ clocks = <&osc24M>, <&pll4>;
+ clock-output-names = "mmc2", "mmc2_output",
+ "mmc2_sample";
+ };
+
+ mmc3_clk: clk@0600041c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun9i-a80-mmc-clk";
+ reg = <0x0600041c 0x4>;
+ clocks = <&osc24M>, <&pll4>;
+ clock-output-names = "mmc3", "mmc3_output",
+ "mmc3_sample";
+ };
+
+ ahb0_gates: clk@06000580 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun9i-a80-ahb0-gates-clk";
+ reg = <0x06000580 0x4>;
+ clocks = <&ahb0>;
+ clock-indices = <0>, <1>, <3>, <5>, <8>, <12>, <13>,
+ <14>, <15>, <16>, <18>, <20>, <21>,
+ <22>, <23>;
+ clock-output-names = "ahb0_fd", "ahb0_ve", "ahb0_gpu",
+ "ahb0_ss", "ahb0_sd", "ahb0_nand1",
+ "ahb0_nand0", "ahb0_sdram",
+ "ahb0_mipi_hsi", "ahb0_sata", "ahb0_ts",
+ "ahb0_spi0","ahb0_spi1", "ahb0_spi2",
+ "ahb0_spi3";
+ };
+
+ ahb1_gates: clk@06000584 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun9i-a80-ahb1-gates-clk";
+ reg = <0x06000584 0x4>;
+ clocks = <&ahb1>;
+ clock-indices = <0>, <1>, <17>, <21>, <22>, <23>, <24>;
+ clock-output-names = "ahb1_usbotg", "ahb1_usbhci",
+ "ahb1_gmac", "ahb1_msgbox",
+ "ahb1_spinlock", "ahb1_hstimer",
+ "ahb1_dma";
+ };
+
+ ahb2_gates: clk@06000588 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun9i-a80-ahb2-gates-clk";
+ reg = <0x06000588 0x4>;
+ clocks = <&ahb2>;
+ clock-indices = <0>, <1>, <2>, <4>, <5>, <7>, <8>,
+ <11>;
+ clock-output-names = "ahb2_lcd0", "ahb2_lcd1",
+ "ahb2_edp", "ahb2_csi", "ahb2_hdmi",
+ "ahb2_de", "ahb2_mp", "ahb2_mipi_dsi";
+ };
+
+ apb0_gates: clk@06000590 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun9i-a80-apb0-gates-clk";
+ reg = <0x06000590 0x4>;
+ clocks = <&apb0>;
+ clock-indices = <1>, <5>, <11>, <12>, <13>, <15>,
+ <17>, <18>, <19>;
+ clock-output-names = "apb0_spdif", "apb0_pio",
+ "apb0_ac97", "apb0_i2s0", "apb0_i2s1",
+ "apb0_lradc", "apb0_gpadc", "apb0_twd",
+ "apb0_cirtx";
+ };
+
+ apb1_gates: clk@06000594 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun9i-a80-apb1-gates-clk";
+ reg = <0x06000594 0x4>;
+ clocks = <&apb1>;
+ clock-indices = <0>, <1>, <2>, <3>, <4>,
+ <16>, <17>, <18>, <19>, <20>, <21>;
+ clock-output-names = "apb1_i2c0", "apb1_i2c1",
+ "apb1_i2c2", "apb1_i2c3", "apb1_i2c4",
+ "apb1_uart0", "apb1_uart1",
+ "apb1_uart2", "apb1_uart3",
+ "apb1_uart4", "apb1_uart5";
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ /*
+ * map 64 bit address range down to 32 bits,
+ * as the peripherals are all under 512MB.
+ */
+ ranges = <0 0 0 0x20000000>;
+
+ mmc0: mmc@01c0f000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&mmc_config_clk 0>, <&mmc0_clk 0>,
+ <&mmc0_clk 1>, <&mmc0_clk 2>;
+ clock-names = "ahb", "mmc", "output", "sample";
+ resets = <&mmc_config_clk 0>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@01c10000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c10000 0x1000>;
+ clocks = <&mmc_config_clk 1>, <&mmc1_clk 0>,
+ <&mmc1_clk 1>, <&mmc1_clk 2>;
+ clock-names = "ahb", "mmc", "output", "sample";
+ resets = <&mmc_config_clk 1>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc2: mmc@01c11000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c11000 0x1000>;
+ clocks = <&mmc_config_clk 2>, <&mmc2_clk 0>,
+ <&mmc2_clk 1>, <&mmc2_clk 2>;
+ clock-names = "ahb", "mmc", "output", "sample";
+ resets = <&mmc_config_clk 2>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc3: mmc@01c12000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c12000 0x1000>;
+ clocks = <&mmc_config_clk 3>, <&mmc3_clk 0>,
+ <&mmc3_clk 1>, <&mmc3_clk 2>;
+ clock-names = "ahb", "mmc", "output", "sample";
+ resets = <&mmc_config_clk 3>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc_config_clk: clk@01c13000 {
+ compatible = "allwinner,sun9i-a80-mmc-config-clk";
+ reg = <0x01c13000 0x10>;
+ clocks = <&ahb0_gates 8>;
+ clock-names = "ahb";
+ resets = <&ahb0_resets 8>;
+ reset-names = "ahb";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ clock-output-names = "mmc0_config", "mmc1_config",
+ "mmc2_config", "mmc3_config";
+ };
+
+ gic: interrupt-controller@01c41000 {
+ compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
+ reg = <0x01c41000 0x1000>,
+ <0x01c42000 0x1000>,
+ <0x01c44000 0x2000>,
+ <0x01c46000 0x2000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ ahb0_resets: reset@060005a0 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ reg = <0x060005a0 0x4>;
+ };
+
+ ahb1_resets: reset@060005a4 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ reg = <0x060005a4 0x4>;
+ };
+
+ ahb2_resets: reset@060005a8 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ reg = <0x060005a8 0x4>;
+ };
+
+ apb0_resets: reset@060005b0 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ reg = <0x060005b0 0x4>;
+ };
+
+ apb1_resets: reset@060005b4 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ reg = <0x060005b4 0x4>;
+ };
+
+ timer@06000c00 {
+ compatible = "allwinner,sun4i-a10-timer";
+ reg = <0x06000c00 0xa0>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&osc24M>;
+ };
+
+ pio: pinctrl@06000800 {
+ compatible = "allwinner,sun9i-a80-pinctrl";
+ reg = <0x06000800 0x400>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb0_gates 5>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ #size-cells = <0>;
+ #gpio-cells = <3>;
+
+ i2c3_pins_a: i2c3@0 {
+ allwinner,pins = "PG10", "PG11";
+ allwinner,function = "i2c3";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_pins: mmc0 {
+ allwinner,pins = "PF0", "PF1" ,"PF2", "PF3",
+ "PF4", "PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc2_8bit_pins: mmc2_8bit {
+ allwinner,pins = "PC6", "PC7", "PC8", "PC9",
+ "PC10", "PC11", "PC12",
+ "PC13", "PC14", "PC15";
+ allwinner,function = "mmc2";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart0_pins_a: uart0@0 {
+ allwinner,pins = "PH12", "PH13";
+ allwinner,function = "uart0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart4_pins_a: uart4@0 {
+ allwinner,pins = "PG12", "PG13", "PG14", "PG15";
+ allwinner,function = "uart4";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ uart0: serial@07000000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x07000000 0x400>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 16>;
+ resets = <&apb1_resets 16>;
+ status = "disabled";
+ };
+
+ uart1: serial@07000400 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x07000400 0x400>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 17>;
+ resets = <&apb1_resets 17>;
+ status = "disabled";
+ };
+
+ uart2: serial@07000800 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x07000800 0x400>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 18>;
+ resets = <&apb1_resets 18>;
+ status = "disabled";
+ };
+
+ uart3: serial@07000c00 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x07000c00 0x400>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 19>;
+ resets = <&apb1_resets 19>;
+ status = "disabled";
+ };
+
+ uart4: serial@07001000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x07001000 0x400>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 20>;
+ resets = <&apb1_resets 20>;
+ status = "disabled";
+ };
+
+ uart5: serial@07001400 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x07001400 0x400>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 21>;
+ resets = <&apb1_resets 21>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@07002800 {
+ compatible = "allwinner,sun6i-a31-i2c";
+ reg = <0x07002800 0x400>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 0>;
+ resets = <&apb1_resets 0>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c1: i2c@07002c00 {
+ compatible = "allwinner,sun6i-a31-i2c";
+ reg = <0x07002c00 0x400>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 1>;
+ resets = <&apb1_resets 1>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c2: i2c@07003000 {
+ compatible = "allwinner,sun6i-a31-i2c";
+ reg = <0x07003000 0x400>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 2>;
+ resets = <&apb1_resets 2>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c3: i2c@07003400 {
+ compatible = "allwinner,sun6i-a31-i2c";
+ reg = <0x07003400 0x400>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 3>;
+ resets = <&apb1_resets 3>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c4: i2c@07003800 {
+ compatible = "allwinner,sun6i-a31-i2c";
+ reg = <0x07003800 0x400>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 4>;
+ resets = <&apb1_resets 4>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ r_wdt: watchdog@08001000 {
+ compatible = "allwinner,sun6i-a31-wdt";
+ reg = <0x08001000 0x20>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ r_uart: serial@08002800 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x08002800 0x400>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&osc24M>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sunxi-common-regulators.dtsi b/arch/arm/boot/dts/sunxi-common-regulators.dtsi
new file mode 100644
index 000000000..e02baa66b
--- /dev/null
+++ b/arch/arm/boot/dts/sunxi-common-regulators.dtsi
@@ -0,0 +1,153 @@
+/*
+ * sunxi boards common regulator (ahci target power supply, usb-vbus) code
+ *
+ * Copyright 2014 - Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) 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 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+&pio {
+ ahci_pwr_pin_a: ahci_pwr_pin@0 {
+ allwinner,pins = "PB8";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ usb0_vbus_pin_a: usb0_vbus_pin@0 {
+ allwinner,pins = "PB9";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ usb1_vbus_pin_a: usb1_vbus_pin@0 {
+ allwinner,pins = "PH6";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ usb2_vbus_pin_a: usb2_vbus_pin@0 {
+ allwinner,pins = "PH3";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+/ {
+ reg_ahci_5v: ahci-5v {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ahci_pwr_pin_a>;
+ regulator-name = "ahci-5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&pio 1 8 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+ };
+
+ reg_usb0_vbus: usb0-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_vbus_pin_a>;
+ regulator-name = "usb0-vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&pio 1 9 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+ };
+
+ reg_usb1_vbus: usb1-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_vbus_pin_a>;
+ regulator-name = "usb1-vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&pio 7 6 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb2_vbus_pin_a>;
+ regulator-name = "usb2-vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&pio 7 3 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+ };
+
+ reg_vcc3v0: vcc3v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v0";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ reg_vcc3v3: vcc3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_vcc5v0: vcc5v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts b/arch/arm/boot/dts/tegra114-dalmore.dts
new file mode 100644
index 000000000..8b7aa0dcd
--- /dev/null
+++ b/arch/arm/boot/dts/tegra114-dalmore.dts
@@ -0,0 +1,1287 @@
+/*
+ * This dts file supports Dalmore A04.
+ * Other board revisions are not supported
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra114.dtsi"
+
+/ {
+ model = "NVIDIA Tegra114 Dalmore evaluation board";
+ compatible = "nvidia,dalmore", "nvidia,tegra114";
+
+ aliases {
+ rtc0 = "/i2c@7000d000/tps65913@58";
+ rtc1 = "/rtc@7000e000";
+ serial0 = &uartd;
+ };
+
+ memory {
+ reg = <0x80000000 0x40000000>;
+ };
+
+ host1x@50000000 {
+ hdmi@54280000 {
+ status = "okay";
+
+ hdmi-supply = <&vdd_5v0_hdmi>;
+ vdd-supply = <&vdd_hdmi_reg>;
+ pll-supply = <&palmas_smps3_reg>;
+
+ nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio =
+ <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
+ };
+
+ dsi@54300000 {
+ status = "okay";
+
+ avdd-dsi-csi-supply = <&avdd_1v2_reg>;
+
+ panel@0 {
+ compatible = "panasonic,vvx10f004b00",
+ "simple-panel";
+ reg = <0>;
+
+ power-supply = <&avdd_lcd_reg>;
+ backlight = <&backlight>;
+ };
+ };
+ };
+
+ pinmux@70000868 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ clk1_out_pw4 {
+ nvidia,pins = "clk1_out_pw4";
+ nvidia,function = "extperiph1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_din_pn1 {
+ nvidia,pins = "dap1_din_pn1";
+ nvidia,function = "i2s0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap1_dout_pn2 {
+ nvidia,pins = "dap1_dout_pn2",
+ "dap1_fs_pn0",
+ "dap1_sclk_pn3";
+ nvidia,function = "i2s0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_din_pa4 {
+ nvidia,pins = "dap2_din_pa4";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_dout_pa5 {
+ nvidia,pins = "dap2_dout_pa5",
+ "dap2_fs_pa2",
+ "dap2_sclk_pa3";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap4_din_pp5 {
+ nvidia,pins = "dap4_din_pp5",
+ "dap4_dout_pp6",
+ "dap4_fs_pp4",
+ "dap4_sclk_pp7";
+ nvidia,function = "i2s3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dvfs_pwm_px0 {
+ nvidia,pins = "dvfs_pwm_px0",
+ "dvfs_clk_px2";
+ nvidia,function = "cldvfs";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_clk_py0 {
+ nvidia,pins = "ulpi_clk_py0",
+ "ulpi_data0_po1",
+ "ulpi_data1_po2",
+ "ulpi_data2_po3",
+ "ulpi_data3_po4",
+ "ulpi_data4_po5",
+ "ulpi_data5_po6",
+ "ulpi_data6_po7",
+ "ulpi_data7_po0";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_dir_py1 {
+ nvidia,pins = "ulpi_dir_py1",
+ "ulpi_nxt_py2";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_stp_py3 {
+ nvidia,pins = "ulpi_stp_py3";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ cam_i2c_scl_pbb1 {
+ nvidia,pins = "cam_i2c_scl_pbb1",
+ "cam_i2c_sda_pbb2";
+ nvidia,function = "i2c3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam_mclk_pcc0 {
+ nvidia,pins = "cam_mclk_pcc0",
+ "pbb0";
+ nvidia,function = "vi_alt3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ };
+ gen2_i2c_scl_pt5 {
+ nvidia,pins = "gen2_i2c_scl_pt5",
+ "gen2_i2c_sda_pt6";
+ nvidia,function = "i2c2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_a16_pj7 {
+ nvidia,pins = "gmi_a16_pj7";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_a17_pb0 {
+ nvidia,pins = "gmi_a17_pb0",
+ "gmi_a18_pb1";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_a19_pk7 {
+ nvidia,pins = "gmi_a19_pk7";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad5_pg5 {
+ nvidia,pins = "gmi_ad5_pg5",
+ "gmi_cs6_n_pi3",
+ "gmi_wr_n_pi0";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_ad6_pg6 {
+ nvidia,pins = "gmi_ad6_pg6",
+ "gmi_ad7_pg7";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_ad12_ph4 {
+ nvidia,pins = "gmi_ad12_ph4";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad9_ph1 {
+ nvidia,pins = "gmi_ad9_ph1";
+ nvidia,function = "pwm1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_cs1_n_pj2 {
+ nvidia,pins = "gmi_cs1_n_pj2",
+ "gmi_oe_n_pi1";
+ nvidia,function = "soc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ clk2_out_pw5 {
+ nvidia,pins = "clk2_out_pw5";
+ nvidia,function = "extperiph2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_clk_pz0 {
+ nvidia,pins = "sdmmc1_clk_pz0";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_cmd_pz1 {
+ nvidia,pins = "sdmmc1_cmd_pz1",
+ "sdmmc1_dat0_py7",
+ "sdmmc1_dat1_py6",
+ "sdmmc1_dat2_py5",
+ "sdmmc1_dat3_py4";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_wp_n_pv3 {
+ nvidia,pins = "sdmmc1_wp_n_pv3";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_clk_pa6 {
+ nvidia,pins = "sdmmc3_clk_pa6";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_cmd_pa7 {
+ nvidia,pins = "sdmmc3_cmd_pa7",
+ "sdmmc3_dat0_pb7",
+ "sdmmc3_dat1_pb6",
+ "sdmmc3_dat2_pb5",
+ "sdmmc3_dat3_pb4",
+ "kb_col4_pq4",
+ "sdmmc3_clk_lb_out_pee4",
+ "sdmmc3_clk_lb_in_pee5";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_clk_pcc4 {
+ nvidia,pins = "sdmmc4_clk_pcc4";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_cmd_pt7 {
+ nvidia,pins = "sdmmc4_cmd_pt7",
+ "sdmmc4_dat0_paa0",
+ "sdmmc4_dat1_paa1",
+ "sdmmc4_dat2_paa2",
+ "sdmmc4_dat3_paa3",
+ "sdmmc4_dat4_paa4",
+ "sdmmc4_dat5_paa5",
+ "sdmmc4_dat6_paa6",
+ "sdmmc4_dat7_paa7";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ clk_32k_out_pa0 {
+ nvidia,pins = "clk_32k_out_pa0";
+ nvidia,function = "blink";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_col0_pq0 {
+ nvidia,pins = "kb_col0_pq0",
+ "kb_col1_pq1",
+ "kb_col2_pq2",
+ "kb_row0_pr0",
+ "kb_row1_pr1",
+ "kb_row2_pr2";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap3_din_pp1 {
+ nvidia,pins = "dap3_din_pp1",
+ "dap3_sclk_pp3";
+ nvidia,function = "displayb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pv0 {
+ nvidia,pins = "pv0";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row7_pr7 {
+ nvidia,pins = "kb_row7_pr7";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row10_ps2 {
+ nvidia,pins = "kb_row10_ps2";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row9_ps1 {
+ nvidia,pins = "kb_row9_ps1";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_i2c_scl_pz6 {
+ nvidia,pins = "pwr_i2c_scl_pz6",
+ "pwr_i2c_sda_pz7";
+ nvidia,function = "i2cpwr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sys_clk_req_pz5 {
+ nvidia,pins = "sys_clk_req_pz5";
+ nvidia,function = "sysclk";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ core_pwr_req {
+ nvidia,pins = "core_pwr_req";
+ nvidia,function = "pwron";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ cpu_pwr_req {
+ nvidia,pins = "cpu_pwr_req";
+ nvidia,function = "cpu";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_int_n {
+ nvidia,pins = "pwr_int_n";
+ nvidia,function = "pmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ reset_out_n {
+ nvidia,pins = "reset_out_n";
+ nvidia,function = "reset_out_n";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ clk3_out_pee0 {
+ nvidia,pins = "clk3_out_pee0";
+ nvidia,function = "extperiph3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gen1_i2c_scl_pc4 {
+ nvidia,pins = "gen1_i2c_scl_pc4",
+ "gen1_i2c_sda_pc5";
+ nvidia,function = "i2c1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_cts_n_pj5 {
+ nvidia,pins = "uart2_cts_n_pj5";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart2_rts_n_pj6 {
+ nvidia,pins = "uart2_rts_n_pj6";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rxd_pc3 {
+ nvidia,pins = "uart2_rxd_pc3";
+ nvidia,function = "irda";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart2_txd_pc2 {
+ nvidia,pins = "uart2_txd_pc2";
+ nvidia,function = "irda";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_cts_n_pa1 {
+ nvidia,pins = "uart3_cts_n_pa1",
+ "uart3_rxd_pw7";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart3_rts_n_pc0 {
+ nvidia,pins = "uart3_rts_n_pc0",
+ "uart3_txd_pw6";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ owr {
+ nvidia,pins = "owr";
+ nvidia,function = "owr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ hdmi_cec_pee3 {
+ nvidia,pins = "hdmi_cec_pee3";
+ nvidia,function = "cec";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ ddc_scl_pv4 {
+ nvidia,pins = "ddc_scl_pv4",
+ "ddc_sda_pv5";
+ nvidia,function = "i2c4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_ENABLE>;
+ };
+ spdif_in_pk6 {
+ nvidia,pins = "spdif_in_pk6";
+ nvidia,function = "usb";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ };
+ usb_vbus_en0_pn4 {
+ nvidia,pins = "usb_vbus_en0_pn4";
+ nvidia,function = "usb";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ gpio_x6_aud_px6 {
+ nvidia,pins = "gpio_x6_aud_px6";
+ nvidia,function = "spi6";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gpio_x4_aud_px4 {
+ nvidia,pins = "gpio_x4_aud_px4",
+ "gpio_x7_aud_px7";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x5_aud_px5 {
+ nvidia,pins = "gpio_x5_aud_px5";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gpio_w2_aud_pw2 {
+ nvidia,pins = "gpio_w2_aud_pw2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gpio_w3_aud_pw3 {
+ nvidia,pins = "gpio_w3_aud_pw3";
+ nvidia,function = "spi6";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gpio_x1_aud_px1 {
+ nvidia,pins = "gpio_x1_aud_px1";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gpio_x3_aud_px3 {
+ nvidia,pins = "gpio_x3_aud_px3";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap3_fs_pp0 {
+ nvidia,pins = "dap3_fs_pp0";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap3_dout_pp2 {
+ nvidia,pins = "dap3_dout_pp2";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pv1 {
+ nvidia,pins = "pv1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pbb3 {
+ nvidia,pins = "pbb3",
+ "pbb5",
+ "pbb6",
+ "pbb7";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pcc1 {
+ nvidia,pins = "pcc1",
+ "pcc2";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_ad0_pg0 {
+ nvidia,pins = "gmi_ad0_pg0",
+ "gmi_ad1_pg1";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad10_ph2 {
+ nvidia,pins = "gmi_ad10_ph2",
+ "gmi_ad11_ph3",
+ "gmi_ad13_ph5",
+ "gmi_ad8_ph0",
+ "gmi_clk_pk1";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad2_pg2 {
+ nvidia,pins = "gmi_ad2_pg2",
+ "gmi_ad3_pg3";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_adv_n_pk0 {
+ nvidia,pins = "gmi_adv_n_pk0",
+ "gmi_cs0_n_pj0",
+ "gmi_cs2_n_pk3",
+ "gmi_cs4_n_pk2",
+ "gmi_cs7_n_pi6",
+ "gmi_dqs_p_pj3",
+ "gmi_iordy_pi5",
+ "gmi_wp_n_pc7";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_cs3_n_pk4 {
+ nvidia,pins = "gmi_cs3_n_pk4";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ clk2_req_pcc5 {
+ nvidia,pins = "clk2_req_pcc5";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_col3_pq3 {
+ nvidia,pins = "kb_col3_pq3",
+ "kb_col6_pq6",
+ "kb_col7_pq7";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_col5_pq5 {
+ nvidia,pins = "kb_col5_pq5";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row3_pr3 {
+ nvidia,pins = "kb_row3_pr3",
+ "kb_row4_pr4",
+ "kb_row6_pr6",
+ "kb_row8_ps0";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ clk3_req_pee1 {
+ nvidia,pins = "clk3_req_pee1";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pu4 {
+ nvidia,pins = "pu4";
+ nvidia,function = "displayb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pu5 {
+ nvidia,pins = "pu5",
+ "pu6";
+ nvidia,function = "displayb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ hdmi_int_pn7 {
+ nvidia,pins = "hdmi_int_pn7";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ clk1_req_pee2 {
+ nvidia,pins = "clk1_req_pee2",
+ "usb_vbus_en1_pn5";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ drive_sdio1 {
+ nvidia,pins = "drive_sdio1";
+ nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,pull-down-strength = <36>;
+ nvidia,pull-up-strength = <20>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOW>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOW>;
+ };
+ drive_sdio3 {
+ nvidia,pins = "drive_sdio3";
+ nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,pull-down-strength = <22>;
+ nvidia,pull-up-strength = <36>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ };
+ drive_gma {
+ nvidia,pins = "drive_gma";
+ nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,pull-down-strength = <2>;
+ nvidia,pull-up-strength = <1>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ };
+ };
+ };
+
+ serial@70006300 {
+ status = "okay";
+ };
+
+ pwm@7000a000 {
+ status = "okay";
+ };
+
+ i2c@7000c000 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ battery: smart-battery@b {
+ compatible = "ti,bq20z45", "sbs,sbs-battery";
+ reg = <0xb>;
+ battery-name = "battery";
+ sbs,i2c-retry-count = <2>;
+ sbs,poll-retry-count = <100>;
+ power-supplies = <&charger>;
+ };
+
+ rt5640: rt5640@1c {
+ compatible = "realtek,rt5640";
+ reg = <0x1c>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>;
+ realtek,ldo1-en-gpios =
+ <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
+ };
+
+ temperature-sensor@4c {
+ compatible = "onnn,nct1008";
+ reg = <0x4c>;
+ vcc-supply = <&palmas_ldo6_reg>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(O, 4) IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+
+ hdmi_ddc: i2c@7000c700 {
+ status = "okay";
+ };
+
+ i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ tps51632@43 {
+ compatible = "ti,tps51632";
+ reg = <0x43>;
+ regulator-name = "vdd-cpu";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1520000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ tps65090@48 {
+ compatible = "ti,tps65090";
+ reg = <0x48>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(J, 0) IRQ_TYPE_LEVEL_HIGH>;
+
+ vsys1-supply = <&vdd_ac_bat_reg>;
+ vsys2-supply = <&vdd_ac_bat_reg>;
+ vsys3-supply = <&vdd_ac_bat_reg>;
+ infet1-supply = <&vdd_ac_bat_reg>;
+ infet2-supply = <&vdd_ac_bat_reg>;
+ infet3-supply = <&tps65090_dcdc2_reg>;
+ infet4-supply = <&tps65090_dcdc2_reg>;
+ infet5-supply = <&tps65090_dcdc2_reg>;
+ infet6-supply = <&tps65090_dcdc2_reg>;
+ infet7-supply = <&tps65090_dcdc2_reg>;
+ vsys-l1-supply = <&vdd_ac_bat_reg>;
+ vsys-l2-supply = <&vdd_ac_bat_reg>;
+
+ charger: charger {
+ compatible = "ti,tps65090-charger";
+ ti,enable-low-current-chrg;
+ };
+
+ regulators {
+ tps65090_dcdc1_reg: dcdc1 {
+ regulator-name = "vdd-sys-5v0";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ tps65090_dcdc2_reg: dcdc2 {
+ regulator-name = "vdd-sys-3v3";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ tps65090_dcdc3_reg: dcdc3 {
+ regulator-name = "vdd-ao";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_bl_reg: fet1 {
+ regulator-name = "vdd-lcd-bl";
+ };
+
+ fet3 {
+ regulator-name = "vdd-modem-3v3";
+ };
+
+ avdd_lcd_reg: fet4 {
+ regulator-name = "avdd-lcd";
+ };
+
+ fet5 {
+ regulator-name = "vdd-lvds";
+ };
+
+ fet6 {
+ regulator-name = "vdd-sd-slot";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ fet7 {
+ regulator-name = "vdd-com-3v3";
+ };
+
+ ldo1 {
+ regulator-name = "vdd-sby-5v0";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo2 {
+ regulator-name = "vdd-sby-3v3";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+
+ palmas: tps65913@58 {
+ compatible = "ti,palmas";
+ reg = <0x58>;
+ interrupts = <0 86 IRQ_TYPE_LEVEL_LOW>;
+
+ #interrupt-cells = <2>;
+ interrupt-controller;
+
+ ti,system-power-controller;
+
+ palmas_gpio: gpio {
+ compatible = "ti,palmas-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pmic {
+ compatible = "ti,tps65913-pmic", "ti,palmas-pmic";
+ smps1-in-supply = <&tps65090_dcdc3_reg>;
+ smps3-in-supply = <&tps65090_dcdc3_reg>;
+ smps4-in-supply = <&tps65090_dcdc2_reg>;
+ smps7-in-supply = <&tps65090_dcdc2_reg>;
+ smps8-in-supply = <&tps65090_dcdc2_reg>;
+ smps9-in-supply = <&tps65090_dcdc2_reg>;
+ ldo1-in-supply = <&tps65090_dcdc2_reg>;
+ ldo2-in-supply = <&tps65090_dcdc2_reg>;
+ ldo3-in-supply = <&palmas_smps3_reg>;
+ ldo4-in-supply = <&tps65090_dcdc2_reg>;
+ ldo5-in-supply = <&vdd_ac_bat_reg>;
+ ldo6-in-supply = <&tps65090_dcdc2_reg>;
+ ldo7-in-supply = <&tps65090_dcdc2_reg>;
+ ldo8-in-supply = <&tps65090_dcdc3_reg>;
+ ldo9-in-supply = <&palmas_smps9_reg>;
+ ldoln-in-supply = <&tps65090_dcdc1_reg>;
+ ldousb-in-supply = <&tps65090_dcdc1_reg>;
+
+ regulators {
+ smps12 {
+ regulator-name = "vddio-ddr";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ palmas_smps3_reg: smps3 {
+ regulator-name = "vddio-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps45 {
+ regulator-name = "vdd-core";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps457 {
+ regulator-name = "vdd-core";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps8 {
+ regulator-name = "avdd-pll";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ palmas_smps9_reg: smps9 {
+ regulator-name = "sdhci-vdd-sd-slot";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo1 {
+ regulator-name = "avdd-cam1";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo2 {
+ regulator-name = "avdd-cam2";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ avdd_1v2_reg: ldo3 {
+ regulator-name = "avdd-dsi-csi";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo4 {
+ regulator-name = "vpp-fuse";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ palmas_ldo6_reg: ldo6 {
+ regulator-name = "vdd-sensor-2v85";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ ldo7 {
+ regulator-name = "vdd-af-cam1";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo8 {
+ regulator-name = "vdd-rtc";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ti,enable-ldo8-tracking;
+ };
+
+ ldo9 {
+ regulator-name = "vddio-sdmmc-2";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldoln {
+ regulator-name = "hvdd-usb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldousb {
+ regulator-name = "avdd-usb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ regen1 {
+ regulator-name = "rail-3v3";
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ regen2 {
+ regulator-name = "rail-5v0";
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+
+ rtc {
+ compatible = "ti,palmas-rtc";
+ interrupt-parent = <&palmas>;
+ interrupts = <8 0>;
+ };
+
+ pinmux {
+ compatible = "ti,tps65913-pinctrl";
+ pinctrl-names = "default";
+ pinctrl-0 = <&palmas_default>;
+
+ palmas_default: pinmux {
+ pin_gpio6 {
+ pins = "gpio6";
+ function = "gpio";
+ };
+ };
+ };
+ };
+ };
+
+ spi@7000da00 {
+ status = "okay";
+ spi-max-frequency = <25000000>;
+ spi-flash@0 {
+ compatible = "winbond,w25q32dw";
+ reg = <0>;
+ spi-max-frequency = <20000000>;
+ };
+ };
+
+ pmc@7000e400 {
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <1>;
+ nvidia,cpu-pwr-good-time = <500>;
+ nvidia,cpu-pwr-off-time = <300>;
+ nvidia,core-pwr-good-time = <641 3845>;
+ nvidia,core-pwr-off-time = <61036>;
+ nvidia,core-power-req-active-high;
+ nvidia,sys-clock-req-active-high;
+ };
+
+ ahub@70080000 {
+ i2s@70080400 {
+ status = "okay";
+ };
+ };
+
+ sdhci@78000400 {
+ cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio TEGRA_GPIO(Q, 4) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ status = "okay";
+ };
+
+ sdhci@78000600 {
+ bus-width = <8>;
+ status = "okay";
+ non-removable;
+ };
+
+ usb@7d008000 {
+ status = "okay";
+ };
+
+ usb-phy@7d008000 {
+ status = "okay";
+ vbus-supply = <&usb3_vbus_reg>;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+
+ enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
+ power-supply = <&vdd_bl_reg>;
+ pwms = <&pwm 1 1000000>;
+
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock@0 {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ home {
+ label = "Home";
+ gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOME>;
+ };
+
+ power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ gpio-key,wakeup;
+ };
+
+ volume_down {
+ label = "Volume Down";
+ gpios = <&gpio TEGRA_GPIO(R, 1) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
+ volume_up {
+ label = "Volume Up";
+ gpios = <&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdd_ac_bat_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vdd_ac_bat";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ dvdd_ts_reg: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "dvdd_ts";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(H, 5) GPIO_ACTIVE_HIGH>;
+ };
+
+ usb1_vbus_reg: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>;
+ gpio-open-drain;
+ vin-supply = <&tps65090_dcdc1_reg>;
+ };
+
+ usb3_vbus_reg: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "usb2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(K, 6) GPIO_ACTIVE_HIGH>;
+ gpio-open-drain;
+ vin-supply = <&tps65090_dcdc1_reg>;
+ };
+
+ vdd_hdmi_reg: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "vdd_hdmi_5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&tps65090_dcdc1_reg>;
+ };
+
+ vdd_cam_1v8_reg: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ regulator-name = "vdd_cam_1v8_reg";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ enable-active-high;
+ gpio = <&palmas_gpio 6 0>;
+ };
+
+ vdd_5v0_hdmi: regulator@7 {
+ compatible = "regulator-fixed";
+ reg = <7>;
+ regulator-name = "VDD_5V0_HDMI_CON";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(K, 1) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&tps65090_dcdc1_reg>;
+ };
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-rt5640-dalmore",
+ "nvidia,tegra-audio-rt5640";
+ nvidia,model = "NVIDIA Tegra Dalmore";
+
+ nvidia,audio-routing =
+ "Headphones", "HPOR",
+ "Headphones", "HPOL",
+ "Speakers", "SPORP",
+ "Speakers", "SPORN",
+ "Speakers", "SPOLP",
+ "Speakers", "SPOLN",
+ "Mic Jack", "MICBIAS1",
+ "IN2P", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&rt5640>;
+
+ nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(R, 7) GPIO_ACTIVE_HIGH>;
+
+ clocks = <&tegra_car TEGRA114_CLK_PLL_A>,
+ <&tegra_car TEGRA114_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA114_CLK_EXTERN1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
+};
diff --git a/arch/arm/boot/dts/tegra114-roth.dts b/arch/arm/boot/dts/tegra114-roth.dts
new file mode 100644
index 000000000..38acf78d7
--- /dev/null
+++ b/arch/arm/boot/dts/tegra114-roth.dts
@@ -0,0 +1,1126 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra114.dtsi"
+
+/ {
+ model = "NVIDIA SHIELD";
+ compatible = "nvidia,roth", "nvidia,tegra114";
+
+ chosen {
+ /* SHIELD's bootloader's arguments need to be overridden */
+ bootargs = "console=ttyS0,115200n8 console=tty1 gpt fbcon=rotate:1";
+ /* SHIELD's bootloader will place initrd at this address */
+ linux,initrd-start = <0x82000000>;
+ linux,initrd-end = <0x82800000>;
+ };
+
+ aliases {
+ serial0 = &uartd;
+ };
+
+ firmware {
+ trusted-foundations {
+ compatible = "tlm,trusted-foundations";
+ tlm,version-major = <2>;
+ tlm,version-minor = <8>;
+ };
+ };
+
+ memory {
+ /* memory >= 0x79600000 is reserved for firmware usage */
+ reg = <0x80000000 0x79600000>;
+ };
+
+ host1x@50000000 {
+ dsi@54300000 {
+ status = "okay";
+
+ vdd-supply = <&vdd_1v2_ap>;
+
+ panel@0 {
+ compatible = "lg,lh500wx1-sd03";
+ reg = <0>;
+
+ power-supply = <&vdd_lcd>;
+ backlight = <&backlight>;
+ };
+ };
+ };
+
+ pinmux@70000868 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ clk1_out_pw4 {
+ nvidia,pins = "clk1_out_pw4";
+ nvidia,function = "extperiph1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_din_pn1 {
+ nvidia,pins = "dap1_din_pn1";
+ nvidia,function = "i2s0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap1_dout_pn2 {
+ nvidia,pins = "dap1_dout_pn2",
+ "dap1_fs_pn0",
+ "dap1_sclk_pn3";
+ nvidia,function = "i2s0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_din_pa4 {
+ nvidia,pins = "dap2_din_pa4";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_dout_pa5 {
+ nvidia,pins = "dap2_dout_pa5",
+ "dap2_fs_pa2",
+ "dap2_sclk_pa3";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap4_din_pp5 {
+ nvidia,pins = "dap4_din_pp5",
+ "dap4_dout_pp6",
+ "dap4_fs_pp4",
+ "dap4_sclk_pp7";
+ nvidia,function = "i2s3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dvfs_pwm_px0 {
+ nvidia,pins = "dvfs_pwm_px0",
+ "dvfs_clk_px2";
+ nvidia,function = "cldvfs";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_clk_py0 {
+ nvidia,pins = "ulpi_clk_py0",
+ "ulpi_data0_po1",
+ "ulpi_data1_po2",
+ "ulpi_data2_po3",
+ "ulpi_data3_po4",
+ "ulpi_data4_po5",
+ "ulpi_data5_po6",
+ "ulpi_data6_po7",
+ "ulpi_data7_po0";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_dir_py1 {
+ nvidia,pins = "ulpi_dir_py1",
+ "ulpi_nxt_py2";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_stp_py3 {
+ nvidia,pins = "ulpi_stp_py3";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ cam_i2c_scl_pbb1 {
+ nvidia,pins = "cam_i2c_scl_pbb1",
+ "cam_i2c_sda_pbb2";
+ nvidia,function = "i2c3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam_mclk_pcc0 {
+ nvidia,pins = "cam_mclk_pcc0",
+ "pbb0";
+ nvidia,function = "vi_alt3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ };
+ pbb4 {
+ nvidia,pins = "pbb4";
+ nvidia,function = "vgp4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ };
+ gen2_i2c_scl_pt5 {
+ nvidia,pins = "gen2_i2c_scl_pt5",
+ "gen2_i2c_sda_pt6";
+ nvidia,function = "i2c2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_a16_pj7 {
+ nvidia,pins = "gmi_a16_pj7",
+ "gmi_a19_pk7";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_a17_pb0 {
+ nvidia,pins = "gmi_a17_pb0",
+ "gmi_a18_pb1";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_ad5_pg5 {
+ nvidia,pins = "gmi_ad5_pg5",
+ "gmi_wr_n_pi0";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_ad6_pg6 {
+ nvidia,pins = "gmi_ad6_pg6",
+ "gmi_ad7_pg7";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_ad12_ph4 {
+ nvidia,pins = "gmi_ad12_ph4";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_cs6_n_pi13 {
+ nvidia,pins = "gmi_cs6_n_pi3";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad9_ph1 {
+ nvidia,pins = "gmi_ad9_ph1";
+ nvidia,function = "pwm1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_cs1_n_pj2 {
+ nvidia,pins = "gmi_cs1_n_pj2",
+ "gmi_oe_n_pi1";
+ nvidia,function = "soc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_rst_n_pi4 {
+ nvidia,pins = "gmi_rst_n_pi4";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_iordy_pi5 {
+ nvidia,pins = "gmi_iordy_pi5";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ clk2_out_pw5 {
+ nvidia,pins = "clk2_out_pw5";
+ nvidia,function = "extperiph2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_clk_pz0 {
+ nvidia,pins = "sdmmc1_clk_pz0";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_cmd_pz1 {
+ nvidia,pins = "sdmmc1_cmd_pz1",
+ "sdmmc1_dat0_py7",
+ "sdmmc1_dat1_py6",
+ "sdmmc1_dat2_py5",
+ "sdmmc1_dat3_py4";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_clk_pa6 {
+ nvidia,pins = "sdmmc3_clk_pa6";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_cmd_pa7 {
+ nvidia,pins = "sdmmc3_cmd_pa7",
+ "sdmmc3_dat0_pb7",
+ "sdmmc3_dat1_pb6",
+ "sdmmc3_dat2_pb5",
+ "sdmmc3_dat3_pb4",
+ "sdmmc3_cd_n_pv2",
+ "sdmmc3_clk_lb_out_pee4",
+ "sdmmc3_clk_lb_in_pee5";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col4_pq4 {
+ nvidia,pins = "kb_col4_pq4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_clk_pcc4 {
+ nvidia,pins = "sdmmc4_clk_pcc4";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_cmd_pt7 {
+ nvidia,pins = "sdmmc4_cmd_pt7",
+ "sdmmc4_dat0_paa0",
+ "sdmmc4_dat1_paa1",
+ "sdmmc4_dat2_paa2",
+ "sdmmc4_dat3_paa3",
+ "sdmmc4_dat4_paa4",
+ "sdmmc4_dat5_paa5",
+ "sdmmc4_dat6_paa6",
+ "sdmmc4_dat7_paa7";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ clk_32k_out_pa0 {
+ nvidia,pins = "clk_32k_out_pa0";
+ nvidia,function = "blink";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_col0_pq0 {
+ nvidia,pins = "kb_col0_pq0",
+ "kb_col1_pq1",
+ "kb_col2_pq2",
+ "kb_row0_pr0",
+ "kb_row1_pr1",
+ "kb_row2_pr2",
+ "kb_row8_ps0";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row7_pr7 {
+ nvidia,pins = "kb_row7_pr7";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row10_ps2 {
+ nvidia,pins = "kb_row10_ps2";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row9_ps1 {
+ nvidia,pins = "kb_row9_ps1";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_i2c_scl_pz6 {
+ nvidia,pins = "pwr_i2c_scl_pz6",
+ "pwr_i2c_sda_pz7";
+ nvidia,function = "i2cpwr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sys_clk_req_pz5 {
+ nvidia,pins = "sys_clk_req_pz5";
+ nvidia,function = "sysclk";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ core_pwr_req {
+ nvidia,pins = "core_pwr_req";
+ nvidia,function = "pwron";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ cpu_pwr_req {
+ nvidia,pins = "cpu_pwr_req";
+ nvidia,function = "cpu";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_int_n {
+ nvidia,pins = "pwr_int_n";
+ nvidia,function = "pmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ reset_out_n {
+ nvidia,pins = "reset_out_n";
+ nvidia,function = "reset_out_n";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ clk3_out_pee0 {
+ nvidia,pins = "clk3_out_pee0";
+ nvidia,function = "extperiph3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gen1_i2c_scl_pc4 {
+ nvidia,pins = "gen1_i2c_scl_pc4",
+ "gen1_i2c_sda_pc5";
+ nvidia,function = "i2c1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_cts_n_pj5 {
+ nvidia,pins = "uart2_cts_n_pj5";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart2_rts_n_pj6 {
+ nvidia,pins = "uart2_rts_n_pj6";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rxd_pc3 {
+ nvidia,pins = "uart2_rxd_pc3";
+ nvidia,function = "irda";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart2_txd_pc2 {
+ nvidia,pins = "uart2_txd_pc2";
+ nvidia,function = "irda";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_cts_n_pa1 {
+ nvidia,pins = "uart3_cts_n_pa1",
+ "uart3_rxd_pw7";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart3_rts_n_pc0 {
+ nvidia,pins = "uart3_rts_n_pc0",
+ "uart3_txd_pw6";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ owr {
+ nvidia,pins = "owr";
+ nvidia,function = "owr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ hdmi_cec_pee3 {
+ nvidia,pins = "hdmi_cec_pee3";
+ nvidia,function = "cec";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ ddc_scl_pv4 {
+ nvidia,pins = "ddc_scl_pv4",
+ "ddc_sda_pv5";
+ nvidia,function = "i2c4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_ENABLE>;
+ };
+ spdif_in_pk6 {
+ nvidia,pins = "spdif_in_pk6";
+ nvidia,function = "usb";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ };
+ usb_vbus_en0_pn4 {
+ nvidia,pins = "usb_vbus_en0_pn4";
+ nvidia,function = "usb";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ gpio_x6_aud_px6 {
+ nvidia,pins = "gpio_x6_aud_px6";
+ nvidia,function = "spi6";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gpio_x1_aud_px1 {
+ nvidia,pins = "gpio_x1_aud_px1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gpio_x7_aud_px7 {
+ nvidia,pins = "gpio_x7_aud_px7";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_adv_n_pk0 {
+ nvidia,pins = "gmi_adv_n_pk0";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_cs0_n_pj0 {
+ nvidia,pins = "gmi_cs0_n_pj0";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu3 {
+ nvidia,pins = "pu3";
+ nvidia,function = "pwm0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x4_aud_px4 {
+ nvidia,pins = "gpio_x4_aud_px4",
+ "gpio_x5_aud_px5";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gpio_x3_aud_px3 {
+ nvidia,pins = "gpio_x3_aud_px3";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gpio_w2_aud_pw2 {
+ nvidia,pins = "gpio_w2_aud_pw2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gpio_w3_aud_pw3 {
+ nvidia,pins = "gpio_w3_aud_pw3";
+ nvidia,function = "spi6";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap3_fs_pp0 {
+ nvidia,pins = "dap3_fs_pp0",
+ "dap3_din_pp1",
+ "dap3_dout_pp2",
+ "dap3_sclk_pp3";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pv0 {
+ nvidia,pins = "pv0";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pv1 {
+ nvidia,pins = "pv1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pbb3 {
+ nvidia,pins = "pbb3",
+ "pbb5",
+ "pbb6",
+ "pbb7";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pcc1 {
+ nvidia,pins = "pcc1",
+ "pcc2";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_ad0_pg0 {
+ nvidia,pins = "gmi_ad0_pg0",
+ "gmi_ad1_pg1";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad10_ph2 {
+ nvidia,pins = "gmi_ad10_ph2",
+ "gmi_ad12_ph4",
+ "gmi_ad15_ph7",
+ "gmi_cs3_n_pk4";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad11_ph3 {
+ nvidia,pins = "gmi_ad11_ph3",
+ "gmi_ad13_ph5",
+ "gmi_ad8_ph0",
+ "gmi_clk_pk1",
+ "gmi_cs2_n_pk3";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad14_ph6 {
+ nvidia,pins = "gmi_ad14_ph6",
+ "gmi_cs0_n_pj0",
+ "gmi_cs4_n_pk2",
+ "gmi_cs7_n_pi6",
+ "gmi_dqs_p_pj3",
+ "gmi_wp_n_pc7";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_ad2_pg2 {
+ nvidia,pins = "gmi_ad2_pg2",
+ "gmi_ad3_pg3";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_wp_n_pv3 {
+ nvidia,pins = "sdmmc1_wp_n_pv3";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ clk2_req_pcc5 {
+ nvidia,pins = "clk2_req_pcc5";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_col3_pq3 {
+ nvidia,pins = "kb_col3_pq3";
+ nvidia,function = "pwm2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_col5_pq5 {
+ nvidia,pins = "kb_col5_pq5";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col6_pq6 {
+ nvidia,pins = "kb_col6_pq6",
+ "kb_col7_pq7";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row3_pr3 {
+ nvidia,pins = "kb_row3_pr3",
+ "kb_row4_pr4",
+ "kb_row6_pr6";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ clk3_req_pee1 {
+ nvidia,pins = "clk3_req_pee1";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pu2 {
+ nvidia,pins = "pu2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ hdmi_int_pn7 {
+ nvidia,pins = "hdmi_int_pn7";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ drive_sdio1 {
+ nvidia,pins = "drive_sdio1";
+ nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,pull-down-strength = <36>;
+ nvidia,pull-up-strength = <20>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOW>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOW>;
+ };
+ drive_sdio3 {
+ nvidia,pins = "drive_sdio3";
+ nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,pull-down-strength = <36>;
+ nvidia,pull-up-strength = <20>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ };
+ drive_gma {
+ nvidia,pins = "drive_gma";
+ nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,pull-down-strength = <2>;
+ nvidia,pull-up-strength = <2>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ };
+ };
+ };
+
+ /* Usable on reworked devices only */
+ serial@70006300 {
+ status = "okay";
+ };
+
+ pwm@7000a000 {
+ status = "okay";
+ };
+
+ i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ regulator@43 {
+ compatible = "ti,tps51632";
+ reg = <0x43>;
+ regulator-name = "vdd-cpu";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1520000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ palmas: pmic@58 {
+ compatible = "ti,palmas";
+ reg = <0x58>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_LOW>;
+
+ #interrupt-cells = <2>;
+ interrupt-controller;
+
+ ti,system-power-controller;
+
+ palmas_gpio: gpio {
+ compatible = "ti,palmas-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pmic {
+ compatible = "ti,tps65913-pmic", "ti,palmas-pmic";
+
+ regulators {
+ smps12 {
+ regulator-name = "vdd-ddr";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_1v8: smps3 {
+ regulator-name = "vdd-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ };
+
+ smps457 {
+ regulator-name = "vdd-soc";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps8 {
+ regulator-name = "avdd-pll-1v05";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps9 {
+ regulator-name = "vdd-2v85-emmc";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ smps10_out1 {
+ regulator-name = "vdd-fan";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps10_out2 {
+ regulator-name = "vdd-5v0-sys";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo2 {
+ regulator-name = "vdd-2v8-display";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_1v2_ap: ldo3 {
+ regulator-name = "avdd-1v2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo4 {
+ regulator-name = "vpp-fuse";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo5 {
+ regulator-name = "avdd-hdmi-pll";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo6 {
+ regulator-name = "vdd-sensor-2v8";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ ldo8 {
+ regulator-name = "vdd-rtc";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ti,enable-ldo8-tracking;
+ };
+
+ vddio_sdmmc3: ldo9 {
+ regulator-name = "vddio-sdmmc3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldousb {
+ regulator-name = "avdd-usb-hdmi";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_3v3_sys: regen1 {
+ regulator-name = "rail-3v3";
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ regen2 {
+ regulator-name = "rail-5v0";
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ };
+ };
+
+ rtc {
+ compatible = "ti,palmas-rtc";
+ interrupt-parent = <&palmas>;
+ interrupts = <8 0>;
+ };
+
+ };
+ };
+
+ pmc@7000e400 {
+ nvidia,invert-interrupt;
+ };
+
+ /* SD card */
+ sdhci@78000400 {
+ status = "okay";
+ bus-width = <4>;
+ vqmmc-supply = <&vddio_sdmmc3>;
+ cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
+ power-gpios = <&gpio TEGRA_GPIO(H, 0) GPIO_ACTIVE_HIGH>;
+ };
+
+ /* eMMC */
+ sdhci@78000600 {
+ status = "okay";
+ bus-width = <8>;
+ non-removable;
+ };
+
+ /* External USB port (must be powered) */
+ usb@7d000000 {
+ status = "okay";
+ };
+
+ usb-phy@7d000000 {
+ status = "okay";
+ nvidia,xcvr-setup = <7>;
+ nvidia,xcvr-lsfslew = <2>;
+ nvidia,xcvr-lsrslew = <2>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ /* Should be changed to "otg" once we have vbus_supply */
+ /* As of now, USB devices need to be powered externally */
+ dr_mode = "host";
+ };
+
+ /* SHIELD controller */
+ usb@7d008000 {
+ status = "okay";
+ };
+
+ usb-phy@7d008000 {
+ status = "okay";
+ nvidia,xcvr-setup = <7>;
+ nvidia,xcvr-lsfslew = <2>;
+ nvidia,xcvr-lsrslew = <2>;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 1 40000>;
+
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+
+ power-supply = <&lcd_bl_en>;
+ enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ back {
+ label = "Back";
+ gpios = <&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_BACK>;
+ };
+
+ home {
+ label = "Home";
+ gpios = <&gpio TEGRA_GPIO(R, 1) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOME>;
+ };
+
+ power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ gpio-key,wakeup;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ lcd_bl_en: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "lcd_bl_en";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ };
+
+ vdd_lcd: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "vdd_lcd_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vdd_1v8>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(U, 4) GPIO_ACTIVE_HIGH>;
+ regulator-boot-on;
+ };
+
+ regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "vdd_1v8_ts";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio TEGRA_GPIO(K, 3) GPIO_ACTIVE_LOW>;
+ regulator-boot-on;
+ };
+
+ regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "vdd_3v3_ts";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(H, 5) GPIO_ACTIVE_HIGH>;
+ regulator-boot-on;
+ };
+
+ regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "vdd_1v8_com";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vdd_1v8>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(X, 1) GPIO_ACTIVE_HIGH>;
+ regulator-boot-on;
+ };
+
+ regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "vdd_3v3_com";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vdd_3v3_sys>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(X, 7) GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra114-tn7.dts b/arch/arm/boot/dts/tegra114-tn7.dts
new file mode 100644
index 000000000..f91c2c9b2
--- /dev/null
+++ b/arch/arm/boot/dts/tegra114-tn7.dts
@@ -0,0 +1,351 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra114.dtsi"
+
+/ {
+ model = "Tegra Note 7";
+ compatible = "nvidia,tn7", "nvidia,tegra114";
+
+ chosen {
+ /* TN7's bootloader's arguments need to be overridden */
+ bootargs = "console=ttyS0,115200n8 console=tty1 gpt fbcon=rotate:2";
+ /* TN7's bootloader will place initrd at this address */
+ linux,initrd-start = <0x82000000>;
+ linux,initrd-end = <0x82800000>;
+ };
+
+ aliases {
+ serial0 = &uartd;
+ };
+
+ firmware {
+ trusted-foundations {
+ compatible = "tlm,trusted-foundations";
+ tlm,version-major = <2>;
+ tlm,version-minor = <8>;
+ };
+ };
+
+ memory {
+ /* memory >= 0x37e00000 is reserved for firmware usage */
+ reg = <0x80000000 0x37e00000>;
+ };
+
+ host1x@50000000 {
+ dsi@54300000 {
+ status = "okay";
+
+ vdd-supply = <&vdd_1v2_ap>;
+
+ panel@0 {
+ compatible = "lg,ld070wx3-sl01";
+ reg = <0>;
+
+ power-supply = <&vdd_lcd>;
+ backlight = <&backlight>;
+ };
+ };
+ };
+
+ serial@70006300 {
+ status = "okay";
+ };
+
+ pwm@7000a000 {
+ status = "okay";
+ };
+
+ i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ palmas: pmic@58 {
+ compatible = "ti,palmas";
+ reg = <0x58>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_LOW>;
+
+ #interrupt-cells = <2>;
+ interrupt-controller;
+
+ ti,system-power-controller;
+
+ palmas_gpio: gpio {
+ compatible = "ti,palmas-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pmic {
+ compatible = "ti,tps65913-pmic", "ti,palmas-pmic";
+
+ ldoln-in-supply = <&vdd_smps10_out2>;
+
+ regulators {
+ smps123 {
+ regulator-name = "vd-cpu";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps45 {
+ regulator-name = "vd-soc";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps6 {
+ regulator-name = "va-lcd-hv";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps7 {
+ regulator-name = "vd-ddr";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_1v8: smps8 {
+ regulator-name = "vs-pmu-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_2v9_sys: smps9 {
+ regulator-name = "vs-sys-2v9";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_smps10_out1: smps10_out1 {
+ regulator-name = "vd-smps10-out1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_smps10_out2: smps10_out2 {
+ regulator-name = "vd-smps10-out2";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo1 {
+ regulator-name = "va-pllx";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_1v2_ap: ldo2 {
+ regulator-name = "va-ap-1v2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo3 {
+ regulator-name = "vd-fuse";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo4 {
+ regulator-name = "vd-ts-hv";
+ regulator-min-microvolt = <3200000>;
+ regulator-max-microvolt = <3200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo5 {
+ regulator-name = "va-cam2-hv";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ };
+
+ ldo6 {
+ regulator-name = "va-sns-hv";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ ldo7 {
+ regulator-name = "va-cam1-hv";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ };
+
+ ldo8 {
+ regulator-name = "va-ap-rtc";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ ti,enable-ldo8-tracking;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo9 {
+ regulator-name = "vi-sdcard";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+ ldousb {
+ regulator-name = "avdd-usb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldoln {
+ regulator-name = "va-hdmi";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
+
+ rtc {
+ compatible = "ti,palmas-rtc";
+ interrupt-parent = <&palmas>;
+ interrupts = <8 0>;
+ };
+
+ };
+ };
+
+ pmc@7000e400 {
+ nvidia,invert-interrupt;
+ };
+
+ /* eMMC */
+ sdhci@78000600 {
+ status = "okay";
+ bus-width = <8>;
+ non-removable;
+ };
+
+ usb@7d000000 {
+ status = "okay";
+ };
+
+ usb-phy@7d000000 {
+ status = "okay";
+ nvidia,xcvr-setup = <7>;
+ nvidia,xcvr-lsfslew = <2>;
+ nvidia,xcvr-lsrslew = <2>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ /* Should be changed to "otg" once we have vbus_supply */
+ /* As of now, USB devices need to be powered externally */
+ dr_mode = "host";
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 1 40000>;
+
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+
+ power-supply = <&lcd_bl_en>;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg = <0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ gpio-key,wakeup;
+ };
+
+ volume_down {
+ label = "Volume Down";
+ gpios = <&gpio TEGRA_GPIO(Q, 2) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
+ volume_up {
+ label = "Volume Up";
+ gpios = <&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* FIXME: output of BQ24192 */
+ vs_sys: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "VS_SYS";
+ regulator-min-microvolt = <4200000>;
+ regulator-max-microvolt = <4200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ lcd_bl_en: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "VDD_LCD_BL";
+ regulator-min-microvolt = <16500000>;
+ regulator-max-microvolt = <16500000>;
+ gpio = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vs_sys>;
+ regulator-boot-on;
+ };
+
+ vdd_lcd: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "VD_LCD_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&palmas_gpio 4 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_1v8>;
+ regulator-boot-on;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi
new file mode 100644
index 000000000..f58a3d9d5
--- /dev/null
+++ b/arch/arm/boot/dts/tegra114.dtsi
@@ -0,0 +1,784 @@
+#include <dt-bindings/clock/tegra114-car.h>
+#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/memory/tegra114-mc.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "nvidia,tegra114";
+ interrupt-parent = <&lic>;
+
+ host1x@50000000 {
+ compatible = "nvidia,tegra114-host1x", "simple-bus";
+ reg = <0x50000000 0x00028000>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, /* syncpt */
+ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; /* general */
+ clocks = <&tegra_car TEGRA114_CLK_HOST1X>;
+ resets = <&tegra_car 28>;
+ reset-names = "host1x";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0x54000000 0x54000000 0x01000000>;
+
+ gr2d@54140000 {
+ compatible = "nvidia,tegra114-gr2d", "nvidia,tegra20-gr2d";
+ reg = <0x54140000 0x00040000>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_GR2D>;
+ resets = <&tegra_car 21>;
+ reset-names = "2d";
+ };
+
+ gr3d@54180000 {
+ compatible = "nvidia,tegra114-gr3d", "nvidia,tegra20-gr3d";
+ reg = <0x54180000 0x00040000>;
+ clocks = <&tegra_car TEGRA114_CLK_GR3D>;
+ resets = <&tegra_car 24>;
+ reset-names = "3d";
+ };
+
+ dc@54200000 {
+ compatible = "nvidia,tegra114-dc", "nvidia,tegra20-dc";
+ reg = <0x54200000 0x00040000>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_DISP1>,
+ <&tegra_car TEGRA114_CLK_PLL_P>;
+ clock-names = "dc", "parent";
+ resets = <&tegra_car 27>;
+ reset-names = "dc";
+
+ iommus = <&mc TEGRA_SWGROUP_DC>;
+
+ nvidia,head = <0>;
+
+ rgb {
+ status = "disabled";
+ };
+ };
+
+ dc@54240000 {
+ compatible = "nvidia,tegra114-dc", "nvidia,tegra20-dc";
+ reg = <0x54240000 0x00040000>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_DISP2>,
+ <&tegra_car TEGRA114_CLK_PLL_P>;
+ clock-names = "dc", "parent";
+ resets = <&tegra_car 26>;
+ reset-names = "dc";
+
+ iommus = <&mc TEGRA_SWGROUP_DCB>;
+
+ nvidia,head = <1>;
+
+ rgb {
+ status = "disabled";
+ };
+ };
+
+ hdmi@54280000 {
+ compatible = "nvidia,tegra114-hdmi";
+ reg = <0x54280000 0x00040000>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_HDMI>,
+ <&tegra_car TEGRA114_CLK_PLL_D2_OUT0>;
+ clock-names = "hdmi", "parent";
+ resets = <&tegra_car 51>;
+ reset-names = "hdmi";
+ status = "disabled";
+ };
+
+ dsi@54300000 {
+ compatible = "nvidia,tegra114-dsi";
+ reg = <0x54300000 0x00040000>;
+ clocks = <&tegra_car TEGRA114_CLK_DSIA>,
+ <&tegra_car TEGRA114_CLK_DSIALP>,
+ <&tegra_car TEGRA114_CLK_PLL_D_OUT0>;
+ clock-names = "dsi", "lp", "parent";
+ resets = <&tegra_car 48>;
+ reset-names = "dsi";
+ nvidia,mipi-calibrate = <&mipi 0x060>; /* DSIA & DSIB pads */
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ dsi@54400000 {
+ compatible = "nvidia,tegra114-dsi";
+ reg = <0x54400000 0x00040000>;
+ clocks = <&tegra_car TEGRA114_CLK_DSIB>,
+ <&tegra_car TEGRA114_CLK_DSIBLP>,
+ <&tegra_car TEGRA114_CLK_PLL_D2_OUT0>;
+ clock-names = "dsi", "lp", "parent";
+ resets = <&tegra_car 82>;
+ reset-names = "dsi";
+ nvidia,mipi-calibrate = <&mipi 0x180>; /* DSIC & DSID pads */
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ gic: interrupt-controller@50041000 {
+ compatible = "arm,cortex-a15-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x50041000 0x1000>,
+ <0x50042000 0x1000>,
+ <0x50044000 0x2000>,
+ <0x50046000 0x2000>;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-parent = <&gic>;
+ };
+
+ lic: interrupt-controller@60004000 {
+ compatible = "nvidia,tegra114-ictlr", "nvidia,tegra30-ictlr";
+ reg = <0x60004000 0x100>,
+ <0x60004100 0x50>,
+ <0x60004200 0x50>,
+ <0x60004300 0x50>,
+ <0x60004400 0x50>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ };
+
+ timer@60005000 {
+ compatible = "nvidia,tegra114-timer", "nvidia,tegra20-timer";
+ reg = <0x60005000 0x400>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_TIMER>;
+ };
+
+ tegra_car: clock@60006000 {
+ compatible = "nvidia,tegra114-car";
+ reg = <0x60006000 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ flow-controller@60007000 {
+ compatible = "nvidia,tegra114-flowctrl";
+ reg = <0x60007000 0x1000>;
+ };
+
+ apbdma: dma@6000a000 {
+ compatible = "nvidia,tegra114-apbdma";
+ reg = <0x6000a000 0x1400>;
+ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_APBDMA>;
+ resets = <&tegra_car 34>;
+ reset-names = "dma";
+ #dma-cells = <1>;
+ };
+
+ ahb: ahb@6000c004 {
+ compatible = "nvidia,tegra114-ahb", "nvidia,tegra30-ahb";
+ reg = <0x6000c004 0x14c>;
+ };
+
+ gpio: gpio@6000d000 {
+ compatible = "nvidia,tegra114-gpio", "nvidia,tegra30-gpio";
+ reg = <0x6000d000 0x1000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ apbmisc@70000800 {
+ compatible = "nvidia,tegra114-apbmisc", "nvidia,tegra20-apbmisc";
+ reg = <0x70000800 0x64 /* Chip revision */
+ 0x70000008 0x04>; /* Strapping options */
+ };
+
+ pinmux: pinmux@70000868 {
+ compatible = "nvidia,tegra114-pinmux";
+ reg = <0x70000868 0x148 /* Pad control registers */
+ 0x70003000 0x40c>; /* Mux registers */
+ };
+
+ /*
+ * There are two serial driver i.e. 8250 based simple serial
+ * driver and APB DMA based serial driver for higher baudrate
+ * and performace. To enable the 8250 based driver, the compatible
+ * is "nvidia,tegra114-uart", "nvidia,tegra20-uart" and to enable
+ * the APB DMA based serial driver, the comptible is
+ * "nvidia,tegra114-hsuart", "nvidia,tegra30-hsuart".
+ */
+ uarta: serial@70006000 {
+ compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
+ reg = <0x70006000 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_UARTA>;
+ resets = <&tegra_car 6>;
+ reset-names = "serial";
+ dmas = <&apbdma 8>, <&apbdma 8>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uartb: serial@70006040 {
+ compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
+ reg = <0x70006040 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_UARTB>;
+ resets = <&tegra_car 7>;
+ reset-names = "serial";
+ dmas = <&apbdma 9>, <&apbdma 9>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uartc: serial@70006200 {
+ compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
+ reg = <0x70006200 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_UARTC>;
+ resets = <&tegra_car 55>;
+ reset-names = "serial";
+ dmas = <&apbdma 10>, <&apbdma 10>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uartd: serial@70006300 {
+ compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
+ reg = <0x70006300 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_UARTD>;
+ resets = <&tegra_car 65>;
+ reset-names = "serial";
+ dmas = <&apbdma 19>, <&apbdma 19>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ pwm: pwm@7000a000 {
+ compatible = "nvidia,tegra114-pwm", "nvidia,tegra20-pwm";
+ reg = <0x7000a000 0x100>;
+ #pwm-cells = <2>;
+ clocks = <&tegra_car TEGRA114_CLK_PWM>;
+ resets = <&tegra_car 17>;
+ reset-names = "pwm";
+ status = "disabled";
+ };
+
+ i2c@7000c000 {
+ compatible = "nvidia,tegra114-i2c";
+ reg = <0x7000c000 0x100>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA114_CLK_I2C1>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 12>;
+ reset-names = "i2c";
+ dmas = <&apbdma 21>, <&apbdma 21>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@7000c400 {
+ compatible = "nvidia,tegra114-i2c";
+ reg = <0x7000c400 0x100>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA114_CLK_I2C2>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 54>;
+ reset-names = "i2c";
+ dmas = <&apbdma 22>, <&apbdma 22>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@7000c500 {
+ compatible = "nvidia,tegra114-i2c";
+ reg = <0x7000c500 0x100>;
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA114_CLK_I2C3>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 67>;
+ reset-names = "i2c";
+ dmas = <&apbdma 23>, <&apbdma 23>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@7000c700 {
+ compatible = "nvidia,tegra114-i2c";
+ reg = <0x7000c700 0x100>;
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA114_CLK_I2C4>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 103>;
+ reset-names = "i2c";
+ dmas = <&apbdma 26>, <&apbdma 26>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@7000d000 {
+ compatible = "nvidia,tegra114-i2c";
+ reg = <0x7000d000 0x100>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA114_CLK_I2C5>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 47>;
+ reset-names = "i2c";
+ dmas = <&apbdma 24>, <&apbdma 24>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000d400 {
+ compatible = "nvidia,tegra114-spi";
+ reg = <0x7000d400 0x200>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA114_CLK_SBC1>;
+ clock-names = "spi";
+ resets = <&tegra_car 41>;
+ reset-names = "spi";
+ dmas = <&apbdma 15>, <&apbdma 15>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000d600 {
+ compatible = "nvidia,tegra114-spi";
+ reg = <0x7000d600 0x200>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA114_CLK_SBC2>;
+ clock-names = "spi";
+ resets = <&tegra_car 44>;
+ reset-names = "spi";
+ dmas = <&apbdma 16>, <&apbdma 16>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000d800 {
+ compatible = "nvidia,tegra114-spi";
+ reg = <0x7000d800 0x200>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA114_CLK_SBC3>;
+ clock-names = "spi";
+ resets = <&tegra_car 46>;
+ reset-names = "spi";
+ dmas = <&apbdma 17>, <&apbdma 17>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000da00 {
+ compatible = "nvidia,tegra114-spi";
+ reg = <0x7000da00 0x200>;
+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA114_CLK_SBC4>;
+ clock-names = "spi";
+ resets = <&tegra_car 68>;
+ reset-names = "spi";
+ dmas = <&apbdma 18>, <&apbdma 18>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000dc00 {
+ compatible = "nvidia,tegra114-spi";
+ reg = <0x7000dc00 0x200>;
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA114_CLK_SBC5>;
+ clock-names = "spi";
+ resets = <&tegra_car 104>;
+ reset-names = "spi";
+ dmas = <&apbdma 27>, <&apbdma 27>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000de00 {
+ compatible = "nvidia,tegra114-spi";
+ reg = <0x7000de00 0x200>;
+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA114_CLK_SBC6>;
+ clock-names = "spi";
+ resets = <&tegra_car 105>;
+ reset-names = "spi";
+ dmas = <&apbdma 28>, <&apbdma 28>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ rtc@7000e000 {
+ compatible = "nvidia,tegra114-rtc", "nvidia,tegra20-rtc";
+ reg = <0x7000e000 0x100>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_RTC>;
+ };
+
+ kbc@7000e200 {
+ compatible = "nvidia,tegra114-kbc";
+ reg = <0x7000e200 0x100>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_KBC>;
+ resets = <&tegra_car 36>;
+ reset-names = "kbc";
+ status = "disabled";
+ };
+
+ pmc@7000e400 {
+ compatible = "nvidia,tegra114-pmc";
+ reg = <0x7000e400 0x400>;
+ clocks = <&tegra_car TEGRA114_CLK_PCLK>, <&clk32k_in>;
+ clock-names = "pclk", "clk32k_in";
+ };
+
+ fuse@7000f800 {
+ compatible = "nvidia,tegra114-efuse";
+ reg = <0x7000f800 0x400>;
+ clocks = <&tegra_car TEGRA114_CLK_FUSE>;
+ clock-names = "fuse";
+ resets = <&tegra_car 39>;
+ reset-names = "fuse";
+ };
+
+ mc: memory-controller@70019000 {
+ compatible = "nvidia,tegra114-mc";
+ reg = <0x70019000 0x1000>;
+ clocks = <&tegra_car TEGRA114_CLK_MC>;
+ clock-names = "mc";
+
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+
+ #iommu-cells = <1>;
+ };
+
+ ahub@70080000 {
+ compatible = "nvidia,tegra114-ahub";
+ reg = <0x70080000 0x200>,
+ <0x70080200 0x100>,
+ <0x70081000 0x200>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_D_AUDIO>,
+ <&tegra_car TEGRA114_CLK_APBIF>;
+ clock-names = "d_audio", "apbif";
+ resets = <&tegra_car 106>, /* d_audio */
+ <&tegra_car 107>, /* apbif */
+ <&tegra_car 30>, /* i2s0 */
+ <&tegra_car 11>, /* i2s1 */
+ <&tegra_car 18>, /* i2s2 */
+ <&tegra_car 101>, /* i2s3 */
+ <&tegra_car 102>, /* i2s4 */
+ <&tegra_car 108>, /* dam0 */
+ <&tegra_car 109>, /* dam1 */
+ <&tegra_car 110>, /* dam2 */
+ <&tegra_car 10>, /* spdif */
+ <&tegra_car 153>, /* amx */
+ <&tegra_car 154>; /* adx */
+ reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
+ "i2s3", "i2s4", "dam0", "dam1", "dam2",
+ "spdif", "amx", "adx";
+ dmas = <&apbdma 1>, <&apbdma 1>,
+ <&apbdma 2>, <&apbdma 2>,
+ <&apbdma 3>, <&apbdma 3>,
+ <&apbdma 4>, <&apbdma 4>,
+ <&apbdma 6>, <&apbdma 6>,
+ <&apbdma 7>, <&apbdma 7>,
+ <&apbdma 12>, <&apbdma 12>,
+ <&apbdma 13>, <&apbdma 13>,
+ <&apbdma 14>, <&apbdma 14>,
+ <&apbdma 29>, <&apbdma 29>;
+ dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2",
+ "rx3", "tx3", "rx4", "tx4", "rx5", "tx5",
+ "rx6", "tx6", "rx7", "tx7", "rx8", "tx8",
+ "rx9", "tx9";
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ tegra_i2s0: i2s@70080300 {
+ compatible = "nvidia,tegra114-i2s", "nvidia,tegra30-i2s";
+ reg = <0x70080300 0x100>;
+ nvidia,ahub-cif-ids = <4 4>;
+ clocks = <&tegra_car TEGRA114_CLK_I2S0>;
+ resets = <&tegra_car 30>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+
+ tegra_i2s1: i2s@70080400 {
+ compatible = "nvidia,tegra114-i2s", "nvidia,tegra30-i2s";
+ reg = <0x70080400 0x100>;
+ nvidia,ahub-cif-ids = <5 5>;
+ clocks = <&tegra_car TEGRA114_CLK_I2S1>;
+ resets = <&tegra_car 11>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+
+ tegra_i2s2: i2s@70080500 {
+ compatible = "nvidia,tegra114-i2s", "nvidia,tegra30-i2s";
+ reg = <0x70080500 0x100>;
+ nvidia,ahub-cif-ids = <6 6>;
+ clocks = <&tegra_car TEGRA114_CLK_I2S2>;
+ resets = <&tegra_car 18>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+
+ tegra_i2s3: i2s@70080600 {
+ compatible = "nvidia,tegra114-i2s", "nvidia,tegra30-i2s";
+ reg = <0x70080600 0x100>;
+ nvidia,ahub-cif-ids = <7 7>;
+ clocks = <&tegra_car TEGRA114_CLK_I2S3>;
+ resets = <&tegra_car 101>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+
+ tegra_i2s4: i2s@70080700 {
+ compatible = "nvidia,tegra114-i2s", "nvidia,tegra30-i2s";
+ reg = <0x70080700 0x100>;
+ nvidia,ahub-cif-ids = <8 8>;
+ clocks = <&tegra_car TEGRA114_CLK_I2S4>;
+ resets = <&tegra_car 102>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+ };
+
+ mipi: mipi@700e3000 {
+ compatible = "nvidia,tegra114-mipi";
+ reg = <0x700e3000 0x100>;
+ clocks = <&tegra_car TEGRA114_CLK_MIPI_CAL>;
+ #nvidia,mipi-calibrate-cells = <1>;
+ };
+
+ sdhci@78000000 {
+ compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+ reg = <0x78000000 0x200>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_SDMMC1>;
+ resets = <&tegra_car 14>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@78000200 {
+ compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+ reg = <0x78000200 0x200>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_SDMMC2>;
+ resets = <&tegra_car 9>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@78000400 {
+ compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+ reg = <0x78000400 0x200>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_SDMMC3>;
+ resets = <&tegra_car 69>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@78000600 {
+ compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+ reg = <0x78000600 0x200>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_SDMMC4>;
+ resets = <&tegra_car 15>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ usb@7d000000 {
+ compatible = "nvidia,tegra30-ehci", "usb-ehci";
+ reg = <0x7d000000 0x4000>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA114_CLK_USBD>;
+ resets = <&tegra_car 22>;
+ reset-names = "usb";
+ nvidia,phy = <&phy1>;
+ status = "disabled";
+ };
+
+ phy1: usb-phy@7d000000 {
+ compatible = "nvidia,tegra30-usb-phy";
+ reg = <0x7d000000 0x4000 0x7d000000 0x4000>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA114_CLK_USBD>,
+ <&tegra_car TEGRA114_CLK_PLL_U>,
+ <&tegra_car TEGRA114_CLK_USBD>;
+ clock-names = "reg", "pll_u", "utmi-pads";
+ resets = <&tegra_car 22>, <&tegra_car 22>;
+ reset-names = "usb", "utmi-pads";
+ nvidia,hssync-start-delay = <0>;
+ nvidia,idle-wait-delay = <17>;
+ nvidia,elastic-limit = <16>;
+ nvidia,term-range-adj = <6>;
+ nvidia,xcvr-setup = <9>;
+ nvidia,xcvr-lsfslew = <0>;
+ nvidia,xcvr-lsrslew = <3>;
+ nvidia,hssquelch-level = <2>;
+ nvidia,hsdiscon-level = <5>;
+ nvidia,xcvr-hsslew = <12>;
+ nvidia,has-utmi-pad-registers;
+ status = "disabled";
+ };
+
+ usb@7d008000 {
+ compatible = "nvidia,tegra30-ehci", "usb-ehci";
+ reg = <0x7d008000 0x4000>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA114_CLK_USB3>;
+ resets = <&tegra_car 59>;
+ reset-names = "usb";
+ nvidia,phy = <&phy3>;
+ status = "disabled";
+ };
+
+ phy3: usb-phy@7d008000 {
+ compatible = "nvidia,tegra30-usb-phy";
+ reg = <0x7d008000 0x4000 0x7d000000 0x4000>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA114_CLK_USB3>,
+ <&tegra_car TEGRA114_CLK_PLL_U>,
+ <&tegra_car TEGRA114_CLK_USBD>;
+ clock-names = "reg", "pll_u", "utmi-pads";
+ resets = <&tegra_car 59>, <&tegra_car 22>;
+ reset-names = "usb", "utmi-pads";
+ nvidia,hssync-start-delay = <0>;
+ nvidia,idle-wait-delay = <17>;
+ nvidia,elastic-limit = <16>;
+ nvidia,term-range-adj = <6>;
+ nvidia,xcvr-setup = <9>;
+ nvidia,xcvr-lsfslew = <0>;
+ nvidia,xcvr-lsrslew = <3>;
+ nvidia,hssquelch-level = <2>;
+ nvidia,hsdiscon-level = <5>;
+ nvidia,xcvr-hsslew = <12>;
+ status = "disabled";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <1>;
+ };
+
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <2>;
+ };
+
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <3>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts =
+ <GIC_PPI 13
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-parent = <&gic>;
+ };
+};
diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi b/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi
new file mode 100644
index 000000000..2c5cede68
--- /dev/null
+++ b/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi
@@ -0,0 +1,2421 @@
+/ {
+ clock@0,60006000 {
+ emc-timings-3 {
+ nvidia,ram-code = <3>;
+
+ timing-12750000 {
+ clock-frequency = <12750000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-20400000 {
+ clock-frequency = <20400000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-40800000 {
+ clock-frequency = <40800000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-68000000 {
+ clock-frequency = <68000000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-102000000 {
+ clock-frequency = <102000000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-204000000 {
+ clock-frequency = <204000000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-300000000 {
+ clock-frequency = <300000000>;
+ nvidia,parent-clock-frequency = <600000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_C>;
+ clock-names = "emc-parent";
+ };
+ timing-396000000 {
+ clock-frequency = <396000000>;
+ nvidia,parent-clock-frequency = <792000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_M>;
+ clock-names = "emc-parent";
+ };
+ timing-528000000 {
+ clock-frequency = <528000000>;
+ nvidia,parent-clock-frequency = <528000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_M_UD>;
+ clock-names = "emc-parent";
+ };
+ timing-600000000 {
+ clock-frequency = <600000000>;
+ nvidia,parent-clock-frequency = <600000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_C_UD>;
+ clock-names = "emc-parent";
+ };
+ timing-792000000 {
+ clock-frequency = <792000000>;
+ nvidia,parent-clock-frequency = <792000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_M_UD>;
+ clock-names = "emc-parent";
+ };
+ timing-924000000 {
+ clock-frequency = <924000000>;
+ nvidia,parent-clock-frequency = <924000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_M_UD>;
+ clock-names = "emc-parent";
+ };
+ };
+ };
+
+ emc@0,7001b000 {
+ emc-timings-3 {
+ nvidia,ram-code = <3>;
+
+ timing-12750000 {
+ clock-frequency = <12750000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x000008c5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000e000e>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00000000>;
+
+ nvidia,emc-configuration = <
+ 0x00000000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000a
+ 0x00000005
+ 0x0000000b
+ 0x00000000
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000c
+ 0x0000000d
+ 0x0000000f
+ 0x00000060
+ 0x00000000
+ 0x00000018
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x00000007
+ 0x0000000f
+ 0x00000005
+ 0x00000005
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000000
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000064
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000e0e
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000007
+ 0x00000000
+ 0x00000042
+ 0x000e000e
+ 0x00000000
+ 0x00000003
+ 0x0000f2f3
+ 0x800001c5
+ 0x0000000a
+ >;
+ };
+
+ timing-20400000 {
+ clock-frequency = <20400000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x000008c5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000e000e>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00000000>;
+
+ nvidia,emc-configuration = <
+ 0x00000000
+ 0x00000005
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000a
+ 0x00000005
+ 0x0000000b
+ 0x00000000
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000c
+ 0x0000000d
+ 0x0000000f
+ 0x0000009a
+ 0x00000000
+ 0x00000026
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x00000007
+ 0x0000000f
+ 0x00000006
+ 0x00000006
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000000
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x000000a0
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000e0e
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x0000000b
+ 0x00000000
+ 0x00000042
+ 0x000e000e
+ 0x00000000
+ 0x00000003
+ 0x0000f2f3
+ 0x8000023a
+ 0x0000000a
+ >;
+ };
+
+ timing-40800000 {
+ clock-frequency = <40800000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x000008c5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000e000e>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00000000>;
+
+ nvidia,emc-configuration = <
+ 0x00000001
+ 0x0000000a
+ 0x00000000
+ 0x00000001
+ 0x00000000
+ 0x00000004
+ 0x0000000a
+ 0x00000005
+ 0x0000000b
+ 0x00000000
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000c
+ 0x0000000d
+ 0x0000000f
+ 0x00000134
+ 0x00000000
+ 0x0000004d
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x00000008
+ 0x0000000f
+ 0x0000000c
+ 0x0000000c
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000000
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x0000013f
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000e0e
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000015
+ 0x00000000
+ 0x00000042
+ 0x000e000e
+ 0x00000000
+ 0x00000003
+ 0x0000f2f3
+ 0x80000370
+ 0x0000000a
+ >;
+ };
+
+ timing-68000000 {
+ clock-frequency = <68000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x000008c5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000e000e>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00000000>;
+
+ nvidia,emc-configuration = <
+ 0x00000003
+ 0x00000011
+ 0x00000000
+ 0x00000002
+ 0x00000000
+ 0x00000004
+ 0x0000000a
+ 0x00000005
+ 0x0000000b
+ 0x00000000
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000c
+ 0x0000000d
+ 0x0000000f
+ 0x00000202
+ 0x00000000
+ 0x00000080
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x0000000f
+ 0x0000000f
+ 0x00000013
+ 0x00000013
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000001
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000213
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000e0e
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000022
+ 0x00000000
+ 0x00000042
+ 0x000e000e
+ 0x00000000
+ 0x00000003
+ 0x0000f2f3
+ 0x8000050e
+ 0x0000000a
+ >;
+ };
+
+ timing-102000000 {
+ clock-frequency = <102000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x000008c5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000e000e>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00000000>;
+
+ nvidia,emc-configuration = <
+ 0x00000004
+ 0x0000001a
+ 0x00000000
+ 0x00000003
+ 0x00000001
+ 0x00000004
+ 0x0000000a
+ 0x00000005
+ 0x0000000b
+ 0x00000001
+ 0x00000001
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000c
+ 0x0000000d
+ 0x0000000f
+ 0x00000304
+ 0x00000000
+ 0x000000c1
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x00000018
+ 0x0000000f
+ 0x0000001c
+ 0x0000001c
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x0000031c
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000e0e
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000033
+ 0x00000000
+ 0x00000042
+ 0x000e000e
+ 0x00000000
+ 0x00000003
+ 0x0000f2f3
+ 0x80000713
+ 0x0000000a
+ >;
+ };
+
+ timing-204000000 {
+ clock-frequency = <204000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x000008cd>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000e000e>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x00000009
+ 0x00000035
+ 0x00000000
+ 0x00000006
+ 0x00000002
+ 0x00000005
+ 0x0000000a
+ 0x00000005
+ 0x0000000b
+ 0x00000002
+ 0x00000002
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000004
+ 0x00000006
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000003
+ 0x0000000d
+ 0x0000000f
+ 0x00000011
+ 0x00000607
+ 0x00000000
+ 0x00000181
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x00000032
+ 0x0000000f
+ 0x00000038
+ 0x00000038
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000006
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000638
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00080000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00008000
+ 0x00000000
+ 0x00000000
+ 0x00008000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00090000
+ 0x00090000
+ 0x00090000
+ 0x00090000
+ 0x00009000
+ 0x00009000
+ 0x00009000
+ 0x00009000
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000707
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000066
+ 0x00000000
+ 0x00000100
+ 0x000e000e
+ 0x00000000
+ 0x00000003
+ 0x0000d2b3
+ 0x80000d22
+ 0x0000000a
+ >;
+ };
+
+ timing-300000000 {
+ clock-frequency = <300000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000000>;
+ nvidia,emc-cfg = <0x73340000>;
+ nvidia,emc-cfg-2 = <0x000008d5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100002>;
+ nvidia,emc-mode-2 = <0x80200000>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80000321>;
+ nvidia,emc-mrs-wait-cnt = <0x0173000e>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x01231339>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x0000000d
+ 0x0000004d
+ 0x00000000
+ 0x00000009
+ 0x00000003
+ 0x00000004
+ 0x00000008
+ 0x00000002
+ 0x00000009
+ 0x00000003
+ 0x00000003
+ 0x00000002
+ 0x00000002
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000005
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x00000007
+ 0x00020000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000001
+ 0x0000000e
+ 0x00000010
+ 0x00000012
+ 0x000008e4
+ 0x00000000
+ 0x00000239
+ 0x00000001
+ 0x00000008
+ 0x00000001
+ 0x00000000
+ 0x0000004b
+ 0x0000000e
+ 0x00000052
+ 0x00000200
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000008
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000924
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x104ab098
+ 0x002c00a0
+ 0x00008000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00098000
+ 0x00098000
+ 0x00000000
+ 0x00098000
+ 0x00098000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00050000
+ 0x00050000
+ 0x00050000
+ 0x00050000
+ 0x00005000
+ 0x00005000
+ 0x00005000
+ 0x00005000
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000505
+ 0x81f1f108
+ 0x07070004
+ 0x00000000
+ 0x016eeeee
+ 0x51451420
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000096
+ 0x00000000
+ 0x00000100
+ 0x0173000e
+ 0x00000000
+ 0x00000003
+ 0x000052a3
+ 0x800012d7
+ 0x00000009
+ >;
+ };
+
+ timing-396000000 {
+ clock-frequency = <396000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000000>;
+ nvidia,emc-cfg = <0x73340000>;
+ nvidia,emc-cfg-2 = <0x00000895>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100002>;
+ nvidia,emc-mode-2 = <0x80200000>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80000521>;
+ nvidia,emc-mrs-wait-cnt = <0x015b000e>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+ nvidia,emc-xm2dqspadctrl2 = <0x01231339>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x00000011
+ 0x00000066
+ 0x00000000
+ 0x0000000c
+ 0x00000004
+ 0x00000004
+ 0x00000008
+ 0x00000002
+ 0x0000000a
+ 0x00000004
+ 0x00000004
+ 0x00000002
+ 0x00000002
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000005
+ 0x00000002
+ 0x00000000
+ 0x00000001
+ 0x00000008
+ 0x00020000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x0000000f
+ 0x00000010
+ 0x00000012
+ 0x00000bd1
+ 0x00000000
+ 0x000002f4
+ 0x00000001
+ 0x00000008
+ 0x00000001
+ 0x00000000
+ 0x00000063
+ 0x0000000f
+ 0x0000006c
+ 0x00000200
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x0000000b
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000c11
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x104ab098
+ 0x002c00a0
+ 0x00008000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00070000
+ 0x00070000
+ 0x00000000
+ 0x00070000
+ 0x00070000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00038000
+ 0x00038000
+ 0x00038000
+ 0x00038000
+ 0x00003800
+ 0x00003800
+ 0x00003800
+ 0x00003800
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000505
+ 0x81f1f108
+ 0x07070004
+ 0x00000000
+ 0x016eeeee
+ 0x51451420
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x000000c6
+ 0x00000000
+ 0x00000100
+ 0x015b000e
+ 0x00000000
+ 0x00000003
+ 0x000052a3
+ 0x8000188b
+ 0x00000009
+ >;
+ };
+
+ timing-528000000 {
+ clock-frequency = <528000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000000>;
+ nvidia,emc-cfg = <0x73300000>;
+ nvidia,emc-cfg-2 = <0x0000089d>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100002>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80000941>;
+ nvidia,emc-mrs-wait-cnt = <0x0139000e>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0123133d>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x00000018
+ 0x00000088
+ 0x00000000
+ 0x00000010
+ 0x00000006
+ 0x00000006
+ 0x00000009
+ 0x00000002
+ 0x0000000d
+ 0x00000006
+ 0x00000006
+ 0x00000002
+ 0x00000002
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000001
+ 0x00000009
+ 0x00030000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000010
+ 0x00000012
+ 0x00000014
+ 0x00000fd6
+ 0x00000000
+ 0x000003f5
+ 0x00000002
+ 0x0000000b
+ 0x00000001
+ 0x00000000
+ 0x00000085
+ 0x00000012
+ 0x00000090
+ 0x00000200
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000010
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00001017
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x104ab098
+ 0xe01200b1
+ 0x00008000
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00054000
+ 0x00054000
+ 0x00000000
+ 0x00054000
+ 0x00054000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x0000000c
+ 0x0000000c
+ 0x0000000c
+ 0x0000000c
+ 0x0000000c
+ 0x0000000c
+ 0x0000000c
+ 0x0000000c
+ 0x100002a0
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc085
+ 0x00000505
+ 0x81f1f108
+ 0x07070004
+ 0x00000000
+ 0x016eeeee
+ 0x51451420
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0606003f
+ 0x00000000
+ 0x00000000
+ 0x00000100
+ 0x0139000e
+ 0x00000000
+ 0x00000003
+ 0x000042a0
+ 0x80002062
+ 0x0000000a
+ >;
+ };
+
+ timing-600000000 {
+ clock-frequency = <600000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000000>;
+ nvidia,emc-cfg = <0x73300000>;
+ nvidia,emc-cfg-2 = <0x0000089d>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100002>;
+ nvidia,emc-mode-2 = <0x80200010>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80000b61>;
+ nvidia,emc-mrs-wait-cnt = <0x0127000e>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0121113d>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x0000001b
+ 0x0000009b
+ 0x00000000
+ 0x00000013
+ 0x00000007
+ 0x00000007
+ 0x0000000b
+ 0x00000003
+ 0x00000010
+ 0x00000007
+ 0x00000007
+ 0x00000002
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x0000000a
+ 0x00000002
+ 0x00000000
+ 0x00000003
+ 0x0000000b
+ 0x00070000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000002
+ 0x00000012
+ 0x00000016
+ 0x00000018
+ 0x00001208
+ 0x00000000
+ 0x00000482
+ 0x00000002
+ 0x0000000d
+ 0x00000001
+ 0x00000000
+ 0x00000097
+ 0x00000015
+ 0x000000a3
+ 0x00000200
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000013
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00001248
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x104ab098
+ 0xe00e00b1
+ 0x00008000
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00048000
+ 0x00048000
+ 0x00000000
+ 0x00048000
+ 0x00048000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x0000000d
+ 0x0000000d
+ 0x0000000d
+ 0x0000000d
+ 0x0000000d
+ 0x0000000d
+ 0x0000000d
+ 0x0000000d
+ 0x100002a0
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc085
+ 0x00000505
+ 0x81f1f108
+ 0x07070004
+ 0x00000000
+ 0x016eeeee
+ 0x51451420
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0606003f
+ 0x00000000
+ 0x00000000
+ 0x00000100
+ 0x0127000e
+ 0x00000000
+ 0x00000003
+ 0x000040a0
+ 0x800024aa
+ 0x0000000e
+ >;
+ };
+
+ timing-792000000 {
+ clock-frequency = <792000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000000>;
+ nvidia,emc-cfg = <0x73300000>;
+ nvidia,emc-cfg-2 = <0x0000089d>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100002>;
+ nvidia,emc-mode-2 = <0x80200018>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80000d71>;
+ nvidia,emc-mrs-wait-cnt = <0x00f7000e>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040000>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0120113d>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x00000024
+ 0x000000cd
+ 0x00000000
+ 0x00000019
+ 0x0000000a
+ 0x00000008
+ 0x0000000d
+ 0x00000004
+ 0x00000013
+ 0x0000000a
+ 0x0000000a
+ 0x00000004
+ 0x00000002
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x0000000b
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x0000000d
+ 0x00080000
+ 0x00000004
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000001
+ 0x00000014
+ 0x00000018
+ 0x0000001a
+ 0x000017e2
+ 0x00000000
+ 0x000005f8
+ 0x00000003
+ 0x00000011
+ 0x00000001
+ 0x00000000
+ 0x000000c7
+ 0x00000018
+ 0x000000d7
+ 0x00000200
+ 0x00000005
+ 0x00000006
+ 0x00000005
+ 0x00000019
+ 0x00000000
+ 0x00000008
+ 0x00000008
+ 0x00001822
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x104ab098
+ 0xe00700b1
+ 0x00008000
+ 0x007fc008
+ 0x007fc008
+ 0x007fc008
+ 0x007fc008
+ 0x007fc008
+ 0x007fc008
+ 0x007fc008
+ 0x007fc008
+ 0x007fc008
+ 0x007fc008
+ 0x007fc008
+ 0x007fc008
+ 0x007fc008
+ 0x007fc008
+ 0x007fc008
+ 0x007fc008
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00034000
+ 0x00034000
+ 0x00000000
+ 0x00034000
+ 0x00034000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x100002a0
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc085
+ 0x00000000
+ 0x81f1f108
+ 0x07070004
+ 0x00000000
+ 0x016eeeee
+ 0x61861820
+ 0x00514514
+ 0x00514514
+ 0x61861800
+ 0x0606003f
+ 0x00000000
+ 0x00000000
+ 0x00000100
+ 0x00f7000e
+ 0x00000000
+ 0x00000004
+ 0x00004080
+ 0x80003012
+ 0x0000000f
+ >;
+ };
+
+ timing-924000000 {
+ clock-frequency = <924000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430303>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000000>;
+ nvidia,emc-cfg = <0x73300000>;
+ nvidia,emc-cfg-2 = <0x0000089d>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100002>;
+ nvidia,emc-mode-2 = <0x80200020>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80000f15>;
+ nvidia,emc-mrs-wait-cnt = <0x00cd000e>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040000>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0120113d>;
+ nvidia,emc-zcal-cnt-long = <0x0000004c>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x0000002b
+ 0x000000f0
+ 0x00000000
+ 0x0000001e
+ 0x0000000b
+ 0x00000009
+ 0x0000000f
+ 0x00000005
+ 0x00000016
+ 0x0000000b
+ 0x0000000b
+ 0x00000004
+ 0x00000002
+ 0x00000000
+ 0x00000007
+ 0x00000007
+ 0x0000000d
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x0000000f
+ 0x000a0000
+ 0x00000004
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000001
+ 0x00000016
+ 0x0000001a
+ 0x0000001c
+ 0x00001be7
+ 0x00000000
+ 0x000006f9
+ 0x00000004
+ 0x00000015
+ 0x00000001
+ 0x00000000
+ 0x000000e7
+ 0x0000001b
+ 0x000000fb
+ 0x00000200
+ 0x00000006
+ 0x00000007
+ 0x00000006
+ 0x0000001e
+ 0x00000000
+ 0x0000000a
+ 0x0000000a
+ 0x00001c28
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x104ab898
+ 0xe00400b1
+ 0x00008000
+ 0x007f800a
+ 0x007f800a
+ 0x007f800a
+ 0x007f800a
+ 0x007f800a
+ 0x007f800a
+ 0x007f800a
+ 0x007f800a
+ 0x007f800a
+ 0x007f800a
+ 0x007f800a
+ 0x007f800a
+ 0x007f800a
+ 0x007f800a
+ 0x007f800a
+ 0x007f800a
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x0002c000
+ 0x0002c000
+ 0x00000000
+ 0x0002c000
+ 0x0002c000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x00000004
+ 0x00000004
+ 0x00000004
+ 0x00000004
+ 0x00000004
+ 0x00000004
+ 0x00000004
+ 0x00000004
+ 0x00000004
+ 0x00000004
+ 0x00000004
+ 0x00000004
+ 0x00000004
+ 0x00000004
+ 0x00000004
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x100002a0
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc085
+ 0x00000000
+ 0x81f1f108
+ 0x07070004
+ 0x00000000
+ 0x016eeeee
+ 0x5d75d720
+ 0x00514514
+ 0x00514514
+ 0x5d75d700
+ 0x0606003f
+ 0x00000000
+ 0x00000000
+ 0x00000128
+ 0x00cd000e
+ 0x00000000
+ 0x00000004
+ 0x00004080
+ 0x800037ea
+ 0x00000011
+ >;
+ };
+
+ };
+ };
+
+ memory-controller@0,70019000 {
+ emc-timings-3 {
+ nvidia,ram-code = <3>;
+
+ timing-12750000 {
+ clock-frequency = <12750000>;
+
+ nvidia,emem-configuration = <
+ 0x40040001
+ 0x8000000a
+ 0x00000001
+ 0x00000001
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x00000001
+ 0x00000003
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000003
+ 0x00000006
+ 0x06030203
+ 0x000a0502
+ 0x77e30303
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-20400000 {
+ clock-frequency = <20400000>;
+
+ nvidia,emem-configuration = <
+ 0x40020001
+ 0x80000012
+ 0x00000001
+ 0x00000001
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x00000001
+ 0x00000003
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000003
+ 0x00000006
+ 0x06030203
+ 0x000a0502
+ 0x76230303
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-40800000 {
+ clock-frequency = <40800000>;
+
+ nvidia,emem-configuration = <
+ 0xa0000001
+ 0x80000017
+ 0x00000001
+ 0x00000001
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x00000001
+ 0x00000003
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000003
+ 0x00000006
+ 0x06030203
+ 0x000a0502
+ 0x74a30303
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-68000000 {
+ clock-frequency = <68000000>;
+
+ nvidia,emem-configuration = <
+ 0x00000001
+ 0x8000001e
+ 0x00000001
+ 0x00000001
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x00000001
+ 0x00000003
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000003
+ 0x00000006
+ 0x06030203
+ 0x000a0502
+ 0x74230403
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-102000000 {
+ clock-frequency = <102000000>;
+
+ nvidia,emem-configuration = <
+ 0x08000001
+ 0x80000026
+ 0x00000001
+ 0x00000001
+ 0x00000003
+ 0x00000000
+ 0x00000002
+ 0x00000001
+ 0x00000003
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000003
+ 0x00000006
+ 0x06030203
+ 0x000a0503
+ 0x73c30504
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-204000000 {
+ clock-frequency = <204000000>;
+
+ nvidia,emem-configuration = <
+ 0x01000003
+ 0x80000040
+ 0x00000001
+ 0x00000001
+ 0x00000004
+ 0x00000002
+ 0x00000003
+ 0x00000001
+ 0x00000003
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000004
+ 0x00000006
+ 0x06040203
+ 0x000a0504
+ 0x73840a05
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-300000000 {
+ clock-frequency = <300000000>;
+
+ nvidia,emem-configuration = <
+ 0x08000004
+ 0x80000040
+ 0x00000001
+ 0x00000002
+ 0x00000007
+ 0x00000004
+ 0x00000004
+ 0x00000001
+ 0x00000002
+ 0x00000007
+ 0x00000002
+ 0x00000002
+ 0x00000004
+ 0x00000006
+ 0x06040202
+ 0x000b0607
+ 0x77450e08
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-396000000 {
+ clock-frequency = <396000000>;
+
+ nvidia,emem-configuration = <
+ 0x0f000005
+ 0x80000040
+ 0x00000001
+ 0x00000002
+ 0x00000009
+ 0x00000005
+ 0x00000006
+ 0x00000001
+ 0x00000002
+ 0x00000008
+ 0x00000002
+ 0x00000002
+ 0x00000004
+ 0x00000006
+ 0x06040202
+ 0x000d0709
+ 0x7586120a
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-528000000 {
+ clock-frequency = <528000000>;
+
+ nvidia,emem-configuration = <
+ 0x0f000007
+ 0x80000040
+ 0x00000002
+ 0x00000003
+ 0x0000000c
+ 0x00000007
+ 0x00000008
+ 0x00000001
+ 0x00000002
+ 0x00000009
+ 0x00000002
+ 0x00000002
+ 0x00000005
+ 0x00000006
+ 0x06050202
+ 0x0010090c
+ 0x7428180d
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-600000000 {
+ clock-frequency = <600000000>;
+
+ nvidia,emem-configuration = <
+ 0x00000009
+ 0x80000040
+ 0x00000003
+ 0x00000004
+ 0x0000000e
+ 0x00000009
+ 0x0000000a
+ 0x00000001
+ 0x00000003
+ 0x0000000b
+ 0x00000002
+ 0x00000002
+ 0x00000005
+ 0x00000007
+ 0x07050202
+ 0x00130b0e
+ 0x73a91b0f
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-792000000 {
+ clock-frequency = <792000000>;
+
+ nvidia,emem-configuration = <
+ 0x0e00000b
+ 0x80000040
+ 0x00000004
+ 0x00000005
+ 0x00000013
+ 0x0000000c
+ 0x0000000d
+ 0x00000002
+ 0x00000003
+ 0x0000000c
+ 0x00000002
+ 0x00000002
+ 0x00000006
+ 0x00000008
+ 0x08060202
+ 0x00170e13
+ 0x736c2414
+ 0x70000f02
+ 0x001f0000
+ >;
+ };
+
+ timing-924000000 {
+ clock-frequency = <924000000>;
+
+ nvidia,emem-configuration = <
+ 0x0e00000d
+ 0x80000040
+ 0x00000005
+ 0x00000006
+ 0x00000016
+ 0x0000000e
+ 0x0000000f
+ 0x00000002
+ 0x00000004
+ 0x0000000e
+ 0x00000002
+ 0x00000002
+ 0x00000006
+ 0x00000009
+ 0x09060202
+ 0x001a1016
+ 0x734e2a17
+ 0x70000f02
+ 0x001f0000
+ >;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1.dts b/arch/arm/boot/dts/tegra124-jetson-tk1.dts
new file mode 100644
index 000000000..ed8a8acd3
--- /dev/null
+++ b/arch/arm/boot/dts/tegra124-jetson-tk1.dts
@@ -0,0 +1,1949 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra124.dtsi"
+
+#include "tegra124-jetson-tk1-emc.dtsi"
+
+/ {
+ model = "NVIDIA Tegra124 Jetson TK1";
+ compatible = "nvidia,jetson-tk1", "nvidia,tegra124";
+
+ aliases {
+ rtc0 = "/i2c@0,7000d000/pmic@40";
+ rtc1 = "/rtc@0,7000e000";
+ serial0 = &uartd;
+ };
+
+ memory {
+ reg = <0x0 0x80000000 0x0 0x80000000>;
+ };
+
+ pcie-controller@0,01003000 {
+ status = "okay";
+
+ avddio-pex-supply = <&vdd_1v05_run>;
+ dvddio-pex-supply = <&vdd_1v05_run>;
+ avdd-pex-pll-supply = <&vdd_1v05_run>;
+ hvdd-pex-supply = <&vdd_3v3_lp0>;
+ hvdd-pex-pll-e-supply = <&vdd_3v3_lp0>;
+ vddio-pex-ctl-supply = <&vdd_3v3_lp0>;
+ avdd-pll-erefe-supply = <&avdd_1v05_run>;
+
+ pci@1,0 {
+ status = "okay";
+ };
+
+ pci@2,0 {
+ status = "okay";
+ };
+ };
+
+ host1x@0,50000000 {
+ hdmi@0,54280000 {
+ status = "okay";
+
+ hdmi-supply = <&vdd_5v0_hdmi>;
+ pll-supply = <&vdd_hdmi_pll>;
+ vdd-supply = <&vdd_3v3_hdmi>;
+
+ nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio =
+ <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ pinmux: pinmux@0,70000868 {
+ pinctrl-names = "boot";
+ pinctrl-0 = <&state_boot>;
+
+ state_boot: pinmux {
+ clk_32k_out_pa0 {
+ nvidia,pins = "clk_32k_out_pa0";
+ nvidia,function = "soc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart3_cts_n_pa1 {
+ nvidia,pins = "uart3_cts_n_pa1";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_fs_pa2 {
+ nvidia,pins = "dap2_fs_pa2";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_sclk_pa3 {
+ nvidia,pins = "dap2_sclk_pa3";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_din_pa4 {
+ nvidia,pins = "dap2_din_pa4";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_dout_pa5 {
+ nvidia,pins = "dap2_dout_pa5";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_clk_pa6 {
+ nvidia,pins = "sdmmc3_clk_pa6";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_cmd_pa7 {
+ nvidia,pins = "sdmmc3_cmd_pa7";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pb0 {
+ nvidia,pins = "pb0";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pb1 {
+ nvidia,pins = "pb1";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat3_pb4 {
+ nvidia,pins = "sdmmc3_dat3_pb4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat2_pb5 {
+ nvidia,pins = "sdmmc3_dat2_pb5";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat1_pb6 {
+ nvidia,pins = "sdmmc3_dat1_pb6";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat0_pb7 {
+ nvidia,pins = "sdmmc3_dat0_pb7";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart3_rts_n_pc0 {
+ nvidia,pins = "uart3_rts_n_pc0";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_txd_pc2 {
+ nvidia,pins = "uart2_txd_pc2";
+ nvidia,function = "irda";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rxd_pc3 {
+ nvidia,pins = "uart2_rxd_pc3";
+ nvidia,function = "irda";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gen1_i2c_scl_pc4 {
+ nvidia,pins = "gen1_i2c_scl_pc4";
+ nvidia,function = "i2c1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ gen1_i2c_sda_pc5 {
+ nvidia,pins = "gen1_i2c_sda_pc5";
+ nvidia,function = "i2c1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ pc7 {
+ nvidia,pins = "pc7";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pg0 {
+ nvidia,pins = "pg0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pg1 {
+ nvidia,pins = "pg1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pg2 {
+ nvidia,pins = "pg2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pg3 {
+ nvidia,pins = "pg3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pg4 {
+ nvidia,pins = "pg4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pg5 {
+ nvidia,pins = "pg5";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pg6 {
+ nvidia,pins = "pg6";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pg7 {
+ nvidia,pins = "pg7";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ph0 {
+ nvidia,pins = "ph0";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ph1 {
+ nvidia,pins = "ph1";
+ nvidia,function = "pwm1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ph2 {
+ nvidia,pins = "ph2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ph3 {
+ nvidia,pins = "ph3";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ph4 {
+ nvidia,pins = "ph4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ph5 {
+ nvidia,pins = "ph5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ph6 {
+ nvidia,pins = "ph6";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ph7 {
+ nvidia,pins = "ph7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pi0 {
+ nvidia,pins = "pi0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pi1 {
+ nvidia,pins = "pi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pi2 {
+ nvidia,pins = "pi2";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pi3 {
+ nvidia,pins = "pi3";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pi4 {
+ nvidia,pins = "pi4";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pi5 {
+ nvidia,pins = "pi5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pi6 {
+ nvidia,pins = "pi6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pi7 {
+ nvidia,pins = "pi7";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pj0 {
+ nvidia,pins = "pj0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pj2 {
+ nvidia,pins = "pj2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_cts_n_pj5 {
+ nvidia,pins = "uart2_cts_n_pj5";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart2_rts_n_pj6 {
+ nvidia,pins = "uart2_rts_n_pj6";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pj7 {
+ nvidia,pins = "pj7";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pk0 {
+ nvidia,pins = "pk0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pk1 {
+ nvidia,pins = "pk1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pk2 {
+ nvidia,pins = "pk2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pk3 {
+ nvidia,pins = "pk3";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pk4 {
+ nvidia,pins = "pk4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ spdif_out_pk5 {
+ nvidia,pins = "spdif_out_pk5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ spdif_in_pk6 {
+ nvidia,pins = "spdif_in_pk6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pk7 {
+ nvidia,pins = "pk7";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_fs_pn0 {
+ nvidia,pins = "dap1_fs_pn0";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_din_pn1 {
+ nvidia,pins = "dap1_din_pn1";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_dout_pn2 {
+ nvidia,pins = "dap1_dout_pn2";
+ nvidia,function = "sata";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_sclk_pn3 {
+ nvidia,pins = "dap1_sclk_pn3";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ usb_vbus_en0_pn4 {
+ nvidia,pins = "usb_vbus_en0_pn4";
+ nvidia,function = "usb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ usb_vbus_en1_pn5 {
+ nvidia,pins = "usb_vbus_en1_pn5";
+ nvidia,function = "usb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ hdmi_int_pn7 {
+ nvidia,pins = "hdmi_int_pn7";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data7_po0 {
+ nvidia,pins = "ulpi_data7_po0";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data0_po1 {
+ nvidia,pins = "ulpi_data0_po1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_data1_po2 {
+ nvidia,pins = "ulpi_data1_po2";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data2_po3 {
+ nvidia,pins = "ulpi_data2_po3";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data3_po4 {
+ nvidia,pins = "ulpi_data3_po4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_data4_po5 {
+ nvidia,pins = "ulpi_data4_po5";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data5_po6 {
+ nvidia,pins = "ulpi_data5_po6";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data6_po7 {
+ nvidia,pins = "ulpi_data6_po7";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap3_fs_pp0 {
+ nvidia,pins = "dap3_fs_pp0";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap3_din_pp1 {
+ nvidia,pins = "dap3_din_pp1";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap3_dout_pp2 {
+ nvidia,pins = "dap3_dout_pp2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap3_sclk_pp3 {
+ nvidia,pins = "dap3_sclk_pp3";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_fs_pp4 {
+ nvidia,pins = "dap4_fs_pp4";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_din_pp5 {
+ nvidia,pins = "dap4_din_pp5";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_dout_pp6 {
+ nvidia,pins = "dap4_dout_pp6";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_sclk_pp7 {
+ nvidia,pins = "dap4_sclk_pp7";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_col0_pq0 {
+ nvidia,pins = "kb_col0_pq0";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col1_pq1 {
+ nvidia,pins = "kb_col1_pq1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_col2_pq2 {
+ nvidia,pins = "kb_col2_pq2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_col3_pq3 {
+ nvidia,pins = "kb_col3_pq3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col4_pq4 {
+ nvidia,pins = "kb_col4_pq4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col5_pq5 {
+ nvidia,pins = "kb_col5_pq5";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col6_pq6 {
+ nvidia,pins = "kb_col6_pq6";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_col7_pq7 {
+ nvidia,pins = "kb_col7_pq7";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row0_pr0 {
+ nvidia,pins = "kb_row0_pr0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row1_pr1 {
+ nvidia,pins = "kb_row1_pr1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row2_pr2 {
+ nvidia,pins = "kb_row2_pr2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row3_pr3 {
+ nvidia,pins = "kb_row3_pr3";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row4_pr4 {
+ nvidia,pins = "kb_row4_pr4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row5_pr5 {
+ nvidia,pins = "kb_row5_pr5";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row6_pr6 {
+ nvidia,pins = "kb_row6_pr6";
+ nvidia,function = "displaya_alt";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row7_pr7 {
+ nvidia,pins = "kb_row7_pr7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row8_ps0 {
+ nvidia,pins = "kb_row8_ps0";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row9_ps1 {
+ nvidia,pins = "kb_row9_ps1";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row10_ps2 {
+ nvidia,pins = "kb_row10_ps2";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row11_ps3 {
+ nvidia,pins = "kb_row11_ps3";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row12_ps4 {
+ nvidia,pins = "kb_row12_ps4";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row13_ps5 {
+ nvidia,pins = "kb_row13_ps5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row14_ps6 {
+ nvidia,pins = "kb_row14_ps6";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row15_ps7 {
+ nvidia,pins = "kb_row15_ps7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row16_pt0 {
+ nvidia,pins = "kb_row16_pt0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row17_pt1 {
+ nvidia,pins = "kb_row17_pt1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gen2_i2c_scl_pt5 {
+ nvidia,pins = "gen2_i2c_scl_pt5";
+ nvidia,function = "i2c2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ gen2_i2c_sda_pt6 {
+ nvidia,pins = "gen2_i2c_sda_pt6";
+ nvidia,function = "i2c2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_cmd_pt7 {
+ nvidia,pins = "sdmmc4_cmd_pt7";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu0 {
+ nvidia,pins = "pu0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu1 {
+ nvidia,pins = "pu1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu2 {
+ nvidia,pins = "pu2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu3 {
+ nvidia,pins = "pu3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu4 {
+ nvidia,pins = "pu4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu5 {
+ nvidia,pins = "pu5";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu6 {
+ nvidia,pins = "pu6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pv0 {
+ nvidia,pins = "pv0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pv1 {
+ nvidia,pins = "pv1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_cd_n_pv2 {
+ nvidia,pins = "sdmmc3_cd_n_pv2";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_wp_n_pv3 {
+ nvidia,pins = "sdmmc1_wp_n_pv3";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ddc_scl_pv4 {
+ nvidia,pins = "ddc_scl_pv4";
+ nvidia,function = "i2c4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
+ };
+ ddc_sda_pv5 {
+ nvidia,pins = "ddc_sda_pv5";
+ nvidia,function = "i2c4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_w2_aud_pw2 {
+ nvidia,pins = "gpio_w2_aud_pw2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_w3_aud_pw3 {
+ nvidia,pins = "gpio_w3_aud_pw3";
+ nvidia,function = "spi6";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap_mclk1_pw4 {
+ nvidia,pins = "dap_mclk1_pw4";
+ nvidia,function = "extperiph1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ clk2_out_pw5 {
+ nvidia,pins = "clk2_out_pw5";
+ nvidia,function = "extperiph2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_txd_pw6 {
+ nvidia,pins = "uart3_txd_pw6";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_rxd_pw7 {
+ nvidia,pins = "uart3_rxd_pw7";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dvfs_pwm_px0 {
+ nvidia,pins = "dvfs_pwm_px0";
+ nvidia,function = "cldvfs";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x1_aud_px1 {
+ nvidia,pins = "gpio_x1_aud_px1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dvfs_clk_px2 {
+ nvidia,pins = "dvfs_clk_px2";
+ nvidia,function = "cldvfs";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x3_aud_px3 {
+ nvidia,pins = "gpio_x3_aud_px3";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x4_aud_px4 {
+ nvidia,pins = "gpio_x4_aud_px4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gpio_x5_aud_px5 {
+ nvidia,pins = "gpio_x5_aud_px5";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x6_aud_px6 {
+ nvidia,pins = "gpio_x6_aud_px6";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x7_aud_px7 {
+ nvidia,pins = "gpio_x7_aud_px7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_clk_py0 {
+ nvidia,pins = "ulpi_clk_py0";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_dir_py1 {
+ nvidia,pins = "ulpi_dir_py1";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_nxt_py2 {
+ nvidia,pins = "ulpi_nxt_py2";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_stp_py3 {
+ nvidia,pins = "ulpi_stp_py3";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat3_py4 {
+ nvidia,pins = "sdmmc1_dat3_py4";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat2_py5 {
+ nvidia,pins = "sdmmc1_dat2_py5";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat1_py6 {
+ nvidia,pins = "sdmmc1_dat1_py6";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat0_py7 {
+ nvidia,pins = "sdmmc1_dat0_py7";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_clk_pz0 {
+ nvidia,pins = "sdmmc1_clk_pz0";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_cmd_pz1 {
+ nvidia,pins = "sdmmc1_cmd_pz1";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_i2c_scl_pz6 {
+ nvidia,pins = "pwr_i2c_scl_pz6";
+ nvidia,function = "i2cpwr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ pwr_i2c_sda_pz7 {
+ nvidia,pins = "pwr_i2c_sda_pz7";
+ nvidia,function = "i2cpwr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat0_paa0 {
+ nvidia,pins = "sdmmc4_dat0_paa0";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat1_paa1 {
+ nvidia,pins = "sdmmc4_dat1_paa1";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat2_paa2 {
+ nvidia,pins = "sdmmc4_dat2_paa2";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat3_paa3 {
+ nvidia,pins = "sdmmc4_dat3_paa3";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat4_paa4 {
+ nvidia,pins = "sdmmc4_dat4_paa4";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat5_paa5 {
+ nvidia,pins = "sdmmc4_dat5_paa5";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat6_paa6 {
+ nvidia,pins = "sdmmc4_dat6_paa6";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat7_paa7 {
+ nvidia,pins = "sdmmc4_dat7_paa7";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pbb0 {
+ nvidia,pins = "pbb0";
+ nvidia,function = "vimclk2_alt";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ cam_i2c_scl_pbb1 {
+ nvidia,pins = "cam_i2c_scl_pbb1";
+ nvidia,function = "i2c3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ cam_i2c_sda_pbb2 {
+ nvidia,pins = "cam_i2c_sda_pbb2";
+ nvidia,function = "i2c3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ pbb3 {
+ nvidia,pins = "pbb3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pbb4 {
+ nvidia,pins = "pbb4";
+ nvidia,function = "vgp4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pbb5 {
+ nvidia,pins = "pbb5";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pbb6 {
+ nvidia,pins = "pbb6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pbb7 {
+ nvidia,pins = "pbb7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ cam_mclk_pcc0 {
+ nvidia,pins = "cam_mclk_pcc0";
+ nvidia,function = "vi_alt3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pcc1 {
+ nvidia,pins = "pcc1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pcc2 {
+ nvidia,pins = "pcc2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_clk_pcc4 {
+ nvidia,pins = "sdmmc4_clk_pcc4";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ clk2_req_pcc5 {
+ nvidia,pins = "clk2_req_pcc5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l0_rst_n_pdd1 {
+ nvidia,pins = "pex_l0_rst_n_pdd1";
+ nvidia,function = "pe0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l0_clkreq_n_pdd2 {
+ nvidia,pins = "pex_l0_clkreq_n_pdd2";
+ nvidia,function = "pe0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pex_wake_n_pdd3 {
+ nvidia,pins = "pex_wake_n_pdd3";
+ nvidia,function = "pe";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pex_l1_rst_n_pdd5 {
+ nvidia,pins = "pex_l1_rst_n_pdd5";
+ nvidia,function = "pe1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l1_clkreq_n_pdd6 {
+ nvidia,pins = "pex_l1_clkreq_n_pdd6";
+ nvidia,function = "pe1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ clk3_out_pee0 {
+ nvidia,pins = "clk3_out_pee0";
+ nvidia,function = "extperiph3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ clk3_req_pee1 {
+ nvidia,pins = "clk3_req_pee1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap_mclk1_req_pee2 {
+ nvidia,pins = "dap_mclk1_req_pee2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ hdmi_cec_pee3 {
+ nvidia,pins = "hdmi_cec_pee3";
+ nvidia,function = "cec";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_clk_lb_out_pee4 {
+ nvidia,pins = "sdmmc3_clk_lb_out_pee4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_clk_lb_in_pee5 {
+ nvidia,pins = "sdmmc3_clk_lb_in_pee5";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dp_hpd_pff0 {
+ nvidia,pins = "dp_hpd_pff0";
+ nvidia,function = "dp";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ usb_vbus_en2_pff1 {
+ nvidia,pins = "usb_vbus_en2_pff1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pff2 {
+ nvidia,pins = "pff2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ core_pwr_req {
+ nvidia,pins = "core_pwr_req";
+ nvidia,function = "pwron";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ cpu_pwr_req {
+ nvidia,pins = "cpu_pwr_req";
+ nvidia,function = "cpu";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_int_n {
+ nvidia,pins = "pwr_int_n";
+ nvidia,function = "pmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ reset_out_n {
+ nvidia,pins = "reset_out_n";
+ nvidia,function = "reset_out_n";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ owr {
+ nvidia,pins = "owr";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
+ };
+ clk_32k_in {
+ nvidia,pins = "clk_32k_in";
+ nvidia,function = "clk";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ jtag_rtck {
+ nvidia,pins = "jtag_rtck";
+ nvidia,function = "rtck";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ };
+ };
+
+ /* DB9 serial port */
+ serial@0,70006300 {
+ status = "okay";
+ };
+
+ /* Expansion GEN1_I2C_*, mini-PCIe I2C, on-board components */
+ i2c@0,7000c000 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ rt5639: audio-codec@1c {
+ compatible = "realtek,rt5639";
+ reg = <0x1c>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(H, 4) GPIO_ACTIVE_HIGH>;
+ realtek,ldo1-en-gpios =
+ <&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
+ };
+
+ temperature-sensor@4c {
+ compatible = "ti,tmp451";
+ reg = <0x4c>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(I, 6) IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ eeprom@56 {
+ compatible = "atmel,24c02";
+ reg = <0x56>;
+ pagesize = <8>;
+ };
+ };
+
+ /* Expansion GEN2_I2C_* */
+ i2c@0,7000c400 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ /* Expansion CAM_I2C_* */
+ i2c@0,7000c500 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ /* HDMI DDC */
+ hdmi_ddc: i2c@0,7000c700 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ /* Expansion PWR_I2C_*, on-board components */
+ i2c@0,7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ pmic: pmic@40 {
+ compatible = "ams,as3722";
+ reg = <0x40>;
+ interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
+
+ ams,system-power-controller;
+
+ #interrupt-cells = <2>;
+ interrupt-controller;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&as3722_default>;
+
+ as3722_default: pinmux {
+ gpio0 {
+ pins = "gpio0";
+ function = "gpio";
+ bias-pull-down;
+ };
+
+ gpio1_2_4_7 {
+ pins = "gpio1", "gpio2", "gpio4", "gpio7";
+ function = "gpio";
+ bias-pull-up;
+ };
+
+ gpio3_5_6 {
+ pins = "gpio3", "gpio5", "gpio6";
+ bias-high-impedance;
+ };
+ };
+
+ regulators {
+ vsup-sd2-supply = <&vdd_5v0_sys>;
+ vsup-sd3-supply = <&vdd_5v0_sys>;
+ vsup-sd4-supply = <&vdd_5v0_sys>;
+ vsup-sd5-supply = <&vdd_5v0_sys>;
+ vin-ldo0-supply = <&vdd_1v35_lp0>;
+ vin-ldo1-6-supply = <&vdd_3v3_run>;
+ vin-ldo2-5-7-supply = <&vddio_1v8>;
+ vin-ldo3-4-supply = <&vdd_3v3_sys>;
+ vin-ldo9-10-supply = <&vdd_5v0_sys>;
+ vin-ldo11-supply = <&vdd_3v3_run>;
+
+ sd0 {
+ regulator-name = "+VDD_CPU_AP";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-min-microamp = <3500000>;
+ regulator-max-microamp = <3500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ams,ext-control = <2>;
+ };
+
+ sd1 {
+ regulator-name = "+VDD_CORE";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-min-microamp = <2500000>;
+ regulator-max-microamp = <2500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ams,ext-control = <1>;
+ };
+
+ vdd_1v35_lp0: sd2 {
+ regulator-name = "+1.35V_LP0(sd2)";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ sd3 {
+ regulator-name = "+1.35V_LP0(sd3)";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_1v05_run: sd4 {
+ regulator-name = "+1.05V_RUN";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ vddio_1v8: sd5 {
+ regulator-name = "+1.8V_VDDIO";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sd6 {
+ regulator-name = "+VDD_GPU_AP";
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-min-microamp = <3500000>;
+ regulator-max-microamp = <3500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ avdd_1v05_run: ldo0 {
+ regulator-name = "+1.05V_RUN_AVDD";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ams,ext-control = <1>;
+ };
+
+ ldo1 {
+ regulator-name = "+1.8V_RUN_CAM";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo2 {
+ regulator-name = "+1.2V_GEN_AVDD";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3 {
+ regulator-name = "+1.05V_LP0_VDD_RTC";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ams,enable-tracking;
+ };
+
+ ldo4 {
+ regulator-name = "+2.8V_RUN_CAM";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo5 {
+ regulator-name = "+1.2V_RUN_CAM_FRONT";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vddio_sdmmc3: ldo6 {
+ regulator-name = "+VDDIO_SDMMC3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo7 {
+ regulator-name = "+1.05V_RUN_CAM_REAR";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ ldo9 {
+ regulator-name = "+3.3V_RUN_TOUCH";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo10 {
+ regulator-name = "+2.8V_RUN_CAM_AF";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo11 {
+ regulator-name = "+1.8V_RUN_VPP_FUSE";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+ };
+ };
+
+ /* Expansion TS_SPI_* */
+ spi@0,7000d400 {
+ status = "okay";
+ };
+
+ /* Internal SPI */
+ spi@0,7000da00 {
+ status = "okay";
+ spi-max-frequency = <25000000>;
+ spi-flash@0 {
+ compatible = "winbond,w25q32dw";
+ reg = <0>;
+ spi-max-frequency = <20000000>;
+ };
+ };
+
+ pmc@0,7000e400 {
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <1>;
+ nvidia,cpu-pwr-good-time = <500>;
+ nvidia,cpu-pwr-off-time = <300>;
+ nvidia,core-pwr-good-time = <641 3845>;
+ nvidia,core-pwr-off-time = <61036>;
+ nvidia,core-power-req-active-high;
+ nvidia,sys-clock-req-active-high;
+
+ i2c-thermtrip {
+ nvidia,i2c-controller-id = <4>;
+ nvidia,bus-addr = <0x40>;
+ nvidia,reg-addr = <0x36>;
+ nvidia,reg-data = <0x2>;
+ };
+ };
+
+ /* Serial ATA */
+ sata@0,70020000 {
+ status = "okay";
+
+ hvdd-supply = <&vdd_3v3_lp0>;
+ vddio-supply = <&vdd_1v05_run>;
+ avdd-supply = <&vdd_1v05_run>;
+
+ target-5v-supply = <&vdd_5v0_sata>;
+ target-12v-supply = <&vdd_12v0_sata>;
+ };
+
+ padctl@0,7009f000 {
+ pinctrl-0 = <&padctl_default>;
+ pinctrl-names = "default";
+
+ padctl_default: pinmux {
+ usb3 {
+ nvidia,lanes = "pcie-0", "pcie-1";
+ nvidia,function = "usb3";
+ nvidia,iddq = <0>;
+ };
+
+ pcie {
+ nvidia,lanes = "pcie-2", "pcie-3",
+ "pcie-4";
+ nvidia,function = "pcie";
+ nvidia,iddq = <0>;
+ };
+
+ sata {
+ nvidia,lanes = "sata-0";
+ nvidia,function = "sata";
+ nvidia,iddq = <0>;
+ };
+ };
+ };
+
+ /* SD card */
+ sdhci@0,700b0400 {
+ status = "okay";
+ cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
+ power-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_HIGH>;
+ wp-gpios = <&gpio TEGRA_GPIO(Q, 4) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ vqmmc-supply = <&vddio_sdmmc3>;
+ };
+
+ /* eMMC */
+ sdhci@0,700b0600 {
+ status = "okay";
+ bus-width = <8>;
+ non-removable;
+ };
+
+ ahub@0,70300000 {
+ i2s@0,70301100 {
+ status = "okay";
+ };
+ };
+
+ /* mini-PCIe USB */
+ usb@0,7d004000 {
+ status = "okay";
+ };
+
+ usb-phy@0,7d004000 {
+ status = "okay";
+ };
+
+ /* USB A connector */
+ usb@0,7d008000 {
+ status = "okay";
+ };
+
+ usb-phy@0,7d008000 {
+ status = "okay";
+ vbus-supply = <&vdd_usb3_vbus>;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdd_mux: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "+VDD_MUX";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_5v0_sys: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "+5V_SYS";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vdd_mux>;
+ };
+
+ vdd_3v3_sys: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "+3.3V_SYS";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vdd_mux>;
+ };
+
+ vdd_3v3_run: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "+3.3V_RUN";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&pmic 1 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_sys>;
+ };
+
+ vdd_3v3_hdmi: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "+3.3V_AVDD_HDMI_AP_GATED";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vdd_3v3_run>;
+ };
+
+ vdd_usb1_vbus: regulator@7 {
+ compatible = "regulator-fixed";
+ reg = <7>;
+ regulator-name = "+USB0_VBUS_SW";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ gpio-open-drain;
+ vin-supply = <&vdd_5v0_sys>;
+ };
+
+ vdd_usb3_vbus: regulator@8 {
+ compatible = "regulator-fixed";
+ reg = <8>;
+ regulator-name = "+5V_USB_HS";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ gpio-open-drain;
+ vin-supply = <&vdd_5v0_sys>;
+ };
+
+ vdd_3v3_lp0: regulator@10 {
+ compatible = "regulator-fixed";
+ reg = <10>;
+ regulator-name = "+3.3V_LP0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&pmic 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_sys>;
+ };
+
+ vdd_hdmi_pll: regulator@11 {
+ compatible = "regulator-fixed";
+ reg = <11>;
+ regulator-name = "+1.05V_RUN_AVDD_HDMI_PLL";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ gpio = <&gpio TEGRA_GPIO(H, 7) GPIO_ACTIVE_LOW>;
+ vin-supply = <&vdd_1v05_run>;
+ };
+
+ vdd_5v0_hdmi: regulator@12 {
+ compatible = "regulator-fixed";
+ reg = <12>;
+ regulator-name = "+5V_HDMI_CON";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(K, 6) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_5v0_sys>;
+ };
+
+ /* Molex power connector */
+ vdd_5v0_sata: regulator@13 {
+ compatible = "regulator-fixed";
+ reg = <13>;
+ regulator-name = "+5V_SATA";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(EE, 2) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_5v0_sys>;
+ };
+
+ vdd_12v0_sata: regulator@14 {
+ compatible = "regulator-fixed";
+ reg = <14>;
+ regulator-name = "+12V_SATA";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ gpio = <&gpio TEGRA_GPIO(EE, 2) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_mux>;
+ };
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-rt5640-jetson-tk1",
+ "nvidia,tegra-audio-rt5640";
+ nvidia,model = "NVIDIA Tegra Jetson TK1";
+
+ nvidia,audio-routing =
+ "Headphones", "HPOR",
+ "Headphones", "HPOL",
+ "Mic Jack", "MICBIAS1",
+ "IN2P", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&rt5639>;
+
+ nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(R, 7) GPIO_ACTIVE_LOW>;
+
+ clocks = <&tegra_car TEGRA124_CLK_PLL_A>,
+ <&tegra_car TEGRA124_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA124_CLK_EXTERN1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
+
+ thermal-zones {
+ cpu {
+ trips {
+ trip@0 {
+ temperature = <101000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ /* There are currently no cooling maps because there are no cooling devices */
+ };
+ };
+
+ mem {
+ trips {
+ trip@0 {
+ temperature = <101000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ /* There are currently no cooling maps because there are no cooling devices */
+ };
+ };
+
+ gpu {
+ trips {
+ trip@0 {
+ temperature = <101000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ /* There are currently no cooling maps because there are no cooling devices */
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi b/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi
new file mode 100644
index 000000000..1a5748d05
--- /dev/null
+++ b/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi
@@ -0,0 +1,2023 @@
+/ {
+ clock@0,60006000 {
+ emc-timings-1 {
+ nvidia,ram-code = <1>;
+
+ timing-12750000 {
+ clock-frequency = <12750000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-20400000 {
+ clock-frequency = <20400000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-40800000 {
+ clock-frequency = <40800000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-68000000 {
+ clock-frequency = <68000000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-102000000 {
+ clock-frequency = <102000000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-204000000 {
+ clock-frequency = <204000000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-300000000 {
+ clock-frequency = <300000000>;
+ nvidia,parent-clock-frequency = <600000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_C>;
+ clock-names = "emc-parent";
+ };
+ timing-396000000 {
+ clock-frequency = <396000000>;
+ nvidia,parent-clock-frequency = <792000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_M>;
+ clock-names = "emc-parent";
+ };
+ /* TODO: Add 528MHz frequency */
+ timing-600000000 {
+ clock-frequency = <600000000>;
+ nvidia,parent-clock-frequency = <600000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_C_UD>;
+ clock-names = "emc-parent";
+ };
+ timing-792000000 {
+ clock-frequency = <792000000>;
+ nvidia,parent-clock-frequency = <792000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_M_UD>;
+ clock-names = "emc-parent";
+ };
+ };
+ };
+
+ emc@0,7001b000 {
+ emc-timings-1 {
+ nvidia,ram-code = <1>;
+
+ timing-12750000 {
+ clock-frequency = <12750000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x000008c5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00000000>;
+
+ nvidia,emc-configuration = <
+ 0x00000000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000a
+ 0x00000003
+ 0x0000000b
+ 0x00000000
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000c
+ 0x0000000d
+ 0x0000000f
+ 0x00000060
+ 0x00000000
+ 0x00000018
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x00000007
+ 0x0000000f
+ 0x00000005
+ 0x00000005
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000000
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000064
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00004000
+ 0x00000000
+ 0x00000000
+ 0x00004000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000303
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000007
+ 0x00000000
+ 0x00000042
+ 0x000c000c
+ 0x00000000
+ 0x00000003
+ 0x0000f2f3
+ 0x800001c5
+ 0x0000000a
+ >;
+ };
+
+ timing-20400000 {
+ clock-frequency = <20400000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x000008c5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00000000>;
+
+ nvidia,emc-configuration = <
+ 0x00000000
+ 0x00000005
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000a
+ 0x00000003
+ 0x0000000b
+ 0x00000000
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000c
+ 0x0000000d
+ 0x0000000f
+ 0x0000009a
+ 0x00000000
+ 0x00000026
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x00000007
+ 0x0000000f
+ 0x00000006
+ 0x00000006
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000000
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x000000a0
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00004000
+ 0x00000000
+ 0x00000000
+ 0x00004000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000303
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x0000000b
+ 0x00000000
+ 0x00000042
+ 0x000c000c
+ 0x00000000
+ 0x00000003
+ 0x0000f2f3
+ 0x8000023a
+ 0x0000000a
+ >;
+ };
+
+ timing-40800000 {
+ clock-frequency = <40800000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x000008c5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00000000>;
+
+ nvidia,emc-configuration = <
+ 0x00000001
+ 0x0000000a
+ 0x00000000
+ 0x00000001
+ 0x00000000
+ 0x00000004
+ 0x0000000a
+ 0x00000003
+ 0x0000000b
+ 0x00000000
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000c
+ 0x0000000d
+ 0x0000000f
+ 0x00000134
+ 0x00000000
+ 0x0000004d
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x00000008
+ 0x0000000f
+ 0x0000000c
+ 0x0000000c
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000000
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x0000013f
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00004000
+ 0x00000000
+ 0x00000000
+ 0x00004000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000303
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000015
+ 0x00000000
+ 0x00000042
+ 0x000c000c
+ 0x00000000
+ 0x00000003
+ 0x0000f2f3
+ 0x80000370
+ 0x0000000a
+ >;
+ };
+
+ timing-68000000 {
+ clock-frequency = <68000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x000008c5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00000000>;
+
+ nvidia,emc-configuration = <
+ 0x00000003
+ 0x00000011
+ 0x00000000
+ 0x00000002
+ 0x00000000
+ 0x00000004
+ 0x0000000a
+ 0x00000003
+ 0x0000000b
+ 0x00000000
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000c
+ 0x0000000d
+ 0x0000000f
+ 0x00000202
+ 0x00000000
+ 0x00000080
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x0000000f
+ 0x0000000f
+ 0x00000013
+ 0x00000013
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000001
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000213
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00004000
+ 0x00000000
+ 0x00000000
+ 0x00004000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000303
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000022
+ 0x00000000
+ 0x00000042
+ 0x000c000c
+ 0x00000000
+ 0x00000003
+ 0x0000f2f3
+ 0x8000050e
+ 0x0000000a
+ >;
+ };
+
+ timing-102000000 {
+ clock-frequency = <102000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x000008c5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00000000>;
+
+ nvidia,emc-configuration = <
+ 0x00000004
+ 0x0000001a
+ 0x00000000
+ 0x00000003
+ 0x00000001
+ 0x00000004
+ 0x0000000a
+ 0x00000003
+ 0x0000000b
+ 0x00000001
+ 0x00000001
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000c
+ 0x0000000d
+ 0x0000000f
+ 0x00000304
+ 0x00000000
+ 0x000000c1
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x00000018
+ 0x0000000f
+ 0x0000001c
+ 0x0000001c
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000003
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x0000031c
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00004000
+ 0x00000000
+ 0x00000000
+ 0x00004000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000303
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000033
+ 0x00000000
+ 0x00000042
+ 0x000c000c
+ 0x00000000
+ 0x00000003
+ 0x0000f2f3
+ 0x80000713
+ 0x0000000a
+ >;
+ };
+
+ timing-204000000 {
+ clock-frequency = <204000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x0000088d>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x00000009
+ 0x00000035
+ 0x00000000
+ 0x00000007
+ 0x00000002
+ 0x00000005
+ 0x0000000a
+ 0x00000003
+ 0x0000000b
+ 0x00000002
+ 0x00000002
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000004
+ 0x00000006
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000003
+ 0x0000000d
+ 0x0000000f
+ 0x00000011
+ 0x00000607
+ 0x00000000
+ 0x00000181
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x00000032
+ 0x0000000f
+ 0x00000038
+ 0x00000038
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000007
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000638
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00004000
+ 0x00000000
+ 0x00000000
+ 0x00004000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00090000
+ 0x00090000
+ 0x00094000
+ 0x00094000
+ 0x00009400
+ 0x00009000
+ 0x00009000
+ 0x00009000
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000303
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000066
+ 0x00000000
+ 0x00000100
+ 0x000c000c
+ 0x00000000
+ 0x00000003
+ 0x0000d2b3
+ 0x80000d22
+ 0x0000000a
+ >;
+ };
+
+ timing-300000000 {
+ clock-frequency = <300000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000000>;
+ nvidia,emc-cfg = <0x73340000>;
+ nvidia,emc-cfg-2 = <0x000008d5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100002>;
+ nvidia,emc-mode-2 = <0x80200000>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80000321>;
+ nvidia,emc-mrs-wait-cnt = <0x0174000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x01231339>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x0000000d
+ 0x0000004c
+ 0x00000000
+ 0x00000009
+ 0x00000003
+ 0x00000004
+ 0x00000008
+ 0x00000002
+ 0x00000009
+ 0x00000003
+ 0x00000003
+ 0x00000002
+ 0x00000002
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000005
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x00000007
+ 0x00020000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000001
+ 0x0000000e
+ 0x00000010
+ 0x00000012
+ 0x000008e4
+ 0x00000000
+ 0x00000239
+ 0x00000001
+ 0x00000008
+ 0x00000001
+ 0x00000000
+ 0x0000004a
+ 0x0000000e
+ 0x00000051
+ 0x00000200
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000009
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000924
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x104ab098
+ 0x002c00a0
+ 0x00008000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00098000
+ 0x00098000
+ 0x00000000
+ 0x00098000
+ 0x00098000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00060000
+ 0x00060000
+ 0x00060000
+ 0x00060000
+ 0x00006000
+ 0x00006000
+ 0x00006000
+ 0x00006000
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000101
+ 0x81f1f108
+ 0x07070004
+ 0x00000000
+ 0x016eeeee
+ 0x51451420
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000096
+ 0x00000000
+ 0x00000100
+ 0x0174000c
+ 0x00000000
+ 0x00000003
+ 0x000052a3
+ 0x800012d7
+ 0x00000009
+ >;
+ };
+
+ timing-396000000 {
+ clock-frequency = <396000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000000>;
+ nvidia,emc-cfg = <0x73340000>;
+ nvidia,emc-cfg-2 = <0x00000895>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100002>;
+ nvidia,emc-mode-2 = <0x80200000>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80000521>;
+ nvidia,emc-mrs-wait-cnt = <0x015b000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+ nvidia,emc-xm2dqspadctrl2 = <0x01231339>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x00000012
+ 0x00000065
+ 0x00000000
+ 0x0000000c
+ 0x00000004
+ 0x00000005
+ 0x00000008
+ 0x00000002
+ 0x0000000a
+ 0x00000004
+ 0x00000004
+ 0x00000002
+ 0x00000002
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000005
+ 0x00000002
+ 0x00000000
+ 0x00000001
+ 0x00000008
+ 0x00020000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x0000000f
+ 0x00000010
+ 0x00000012
+ 0x00000bd1
+ 0x00000000
+ 0x000002f4
+ 0x00000001
+ 0x00000008
+ 0x00000001
+ 0x00000000
+ 0x00000063
+ 0x0000000f
+ 0x0000006b
+ 0x00000200
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x0000000d
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000c11
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x104ab098
+ 0x002c00a0
+ 0x00008000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00070000
+ 0x00070000
+ 0x00000000
+ 0x00070000
+ 0x00070000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00048000
+ 0x00048000
+ 0x00048000
+ 0x00048000
+ 0x00004800
+ 0x00004800
+ 0x00004800
+ 0x00004800
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000101
+ 0x81f1f108
+ 0x07070004
+ 0x00000000
+ 0x016eeeee
+ 0x51451420
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x000000c6
+ 0x00000000
+ 0x00000100
+ 0x015b000c
+ 0x00000000
+ 0x00000003
+ 0x000052a3
+ 0x8000188b
+ 0x00000009
+ >;
+ };
+
+ timing-600000000 {
+ clock-frequency = <600000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000000>;
+ nvidia,emc-cfg = <0x73300000>;
+ nvidia,emc-cfg-2 = <0x0000089d>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100002>;
+ nvidia,emc-mode-2 = <0x80200010>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80000b61>;
+ nvidia,emc-mrs-wait-cnt = <0x0128000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0121113d>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x0000001c
+ 0x0000009a
+ 0x00000000
+ 0x00000013
+ 0x00000007
+ 0x00000007
+ 0x0000000b
+ 0x00000003
+ 0x00000010
+ 0x00000007
+ 0x00000007
+ 0x00000002
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x0000000a
+ 0x00000002
+ 0x00000000
+ 0x00000003
+ 0x0000000b
+ 0x00070000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000002
+ 0x00000012
+ 0x00000016
+ 0x00000018
+ 0x00001208
+ 0x00000000
+ 0x00000482
+ 0x00000002
+ 0x0000000d
+ 0x00000001
+ 0x00000000
+ 0x00000096
+ 0x00000015
+ 0x000000a2
+ 0x00000200
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000015
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00001249
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x104ab098
+ 0xe00e00b1
+ 0x00008000
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00048000
+ 0x00048000
+ 0x00000000
+ 0x00048000
+ 0x00048000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x00000004
+ 0x00000002
+ 0x00000005
+ 0x00000006
+ 0x00000003
+ 0x00000006
+ 0x00000005
+ 0x00000004
+ 0x00000004
+ 0x00000002
+ 0x00000005
+ 0x00000006
+ 0x00000003
+ 0x00000006
+ 0x00000005
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x100002a0
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc085
+ 0x00000101
+ 0x81f1f108
+ 0x07070004
+ 0x00000000
+ 0x016eeeee
+ 0x51451420
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0606003f
+ 0x00000000
+ 0x00000000
+ 0x00000100
+ 0x0128000c
+ 0x00000000
+ 0x00000003
+ 0x000040a0
+ 0x800024aa
+ 0x0000000e
+ >;
+ };
+
+ timing-792000000 {
+ clock-frequency = <792000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000000>;
+ nvidia,emc-cfg = <0x73300000>;
+ nvidia,emc-cfg-2 = <0x0080089d>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100002>;
+ nvidia,emc-mode-2 = <0x80200418>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80000d71>;
+ nvidia,emc-mrs-wait-cnt = <0x00f8000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040000>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0120113d>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x00000025
+ 0x000000cc
+ 0x00000000
+ 0x0000001a
+ 0x00000009
+ 0x00000008
+ 0x0000000d
+ 0x00000004
+ 0x00000013
+ 0x00000009
+ 0x00000009
+ 0x00000003
+ 0x00000002
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x0000000b
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x0000000d
+ 0x00080000
+ 0x00000004
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000001
+ 0x00000014
+ 0x00000018
+ 0x0000001a
+ 0x000017e2
+ 0x00000000
+ 0x000005f8
+ 0x00000003
+ 0x00000011
+ 0x00000001
+ 0x00000000
+ 0x000000c6
+ 0x00000018
+ 0x000000d6
+ 0x00000200
+ 0x00000005
+ 0x00000006
+ 0x00000005
+ 0x0000001d
+ 0x00000000
+ 0x00000008
+ 0x00000008
+ 0x00001822
+ 0x00000000
+ 0x80000005
+ 0x00000000
+ 0x104ab198
+ 0xe00700b1
+ 0x00008000
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000005
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00034000
+ 0x00034000
+ 0x00000000
+ 0x00034000
+ 0x00034000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000008
+ 0x00000008
+ 0x00000005
+ 0x00000009
+ 0x00000009
+ 0x00000007
+ 0x00000009
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000005
+ 0x00000009
+ 0x00000009
+ 0x00000007
+ 0x00000009
+ 0x00000008
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x100002a0
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc085
+ 0x00000101
+ 0x81f1f108
+ 0x07070004
+ 0x00000000
+ 0x016eeeee
+ 0x61861820
+ 0x00514514
+ 0x00514514
+ 0x61861800
+ 0x0606003f
+ 0x00000000
+ 0x00000000
+ 0x00000100
+ 0x00f8000c
+ 0x00000007
+ 0x00000004
+ 0x00004080
+ 0x80003012
+ 0x0000000f
+ >;
+ };
+
+ };
+ };
+
+ memory-controller@0,70019000 {
+ emc-timings-1 {
+ nvidia,ram-code = <1>;
+
+
+ timing-12750000 {
+ clock-frequency = <12750000>;
+
+ nvidia,emem-configuration = <
+ 0x40040001
+ 0x8000000a
+ 0x00000001
+ 0x00000001
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x00000001
+ 0x00000002
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000003
+ 0x00000006
+ 0x06030203
+ 0x000a0402
+ 0x77e30303
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-20400000 {
+ clock-frequency = <20400000>;
+
+ nvidia,emem-configuration = <
+ 0x40020001
+ 0x80000012
+ 0x00000001
+ 0x00000001
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x00000001
+ 0x00000002
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000003
+ 0x00000006
+ 0x06030203
+ 0x000a0402
+ 0x76230303
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-40800000 {
+ clock-frequency = <40800000>;
+
+ nvidia,emem-configuration = <
+ 0xa0000001
+ 0x80000017
+ 0x00000001
+ 0x00000001
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x00000001
+ 0x00000002
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000003
+ 0x00000006
+ 0x06030203
+ 0x000a0402
+ 0x74a30303
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-68000000 {
+ clock-frequency = <68000000>;
+
+ nvidia,emem-configuration = <
+ 0x00000001
+ 0x8000001e
+ 0x00000001
+ 0x00000001
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x00000001
+ 0x00000002
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000003
+ 0x00000006
+ 0x06030203
+ 0x000a0402
+ 0x74230403
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-102000000 {
+ clock-frequency = <102000000>;
+
+ nvidia,emem-configuration = <
+ 0x08000001
+ 0x80000026
+ 0x00000001
+ 0x00000001
+ 0x00000003
+ 0x00000000
+ 0x00000002
+ 0x00000001
+ 0x00000002
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000003
+ 0x00000006
+ 0x06030203
+ 0x000a0403
+ 0x73c30504
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-204000000 {
+ clock-frequency = <204000000>;
+
+ nvidia,emem-configuration = <
+ 0x01000003
+ 0x80000040
+ 0x00000001
+ 0x00000001
+ 0x00000005
+ 0x00000002
+ 0x00000004
+ 0x00000001
+ 0x00000002
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000004
+ 0x00000006
+ 0x06040203
+ 0x000a0405
+ 0x73840a06
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-300000000 {
+ clock-frequency = <300000000>;
+
+ nvidia,emem-configuration = <
+ 0x08000004
+ 0x80000040
+ 0x00000001
+ 0x00000002
+ 0x00000007
+ 0x00000004
+ 0x00000005
+ 0x00000001
+ 0x00000002
+ 0x00000007
+ 0x00000002
+ 0x00000002
+ 0x00000004
+ 0x00000006
+ 0x06040202
+ 0x000b0607
+ 0x77450e08
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-396000000 {
+ clock-frequency = <396000000>;
+
+ nvidia,emem-configuration = <
+ 0x0f000005
+ 0x80000040
+ 0x00000001
+ 0x00000002
+ 0x00000009
+ 0x00000005
+ 0x00000007
+ 0x00000001
+ 0x00000002
+ 0x00000008
+ 0x00000002
+ 0x00000002
+ 0x00000004
+ 0x00000006
+ 0x06040202
+ 0x000d0709
+ 0x7586120a
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-600000000 {
+ clock-frequency = <600000000>;
+
+ nvidia,emem-configuration = <
+ 0x00000009
+ 0x80000040
+ 0x00000003
+ 0x00000004
+ 0x0000000e
+ 0x00000009
+ 0x0000000b
+ 0x00000001
+ 0x00000003
+ 0x0000000b
+ 0x00000002
+ 0x00000002
+ 0x00000005
+ 0x00000007
+ 0x07050202
+ 0x00130b0e
+ 0x73a91b0f
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-792000000 {
+ clock-frequency = <792000000>;
+
+ nvidia,emem-configuration = <
+ 0x0e00000b
+ 0x80000040
+ 0x00000004
+ 0x00000005
+ 0x00000013
+ 0x0000000c
+ 0x0000000f
+ 0x00000002
+ 0x00000003
+ 0x0000000c
+ 0x00000002
+ 0x00000002
+ 0x00000006
+ 0x00000008
+ 0x08060202
+ 0x00160d13
+ 0x734c2414
+ 0x70000f02
+ 0x001f0000
+ >;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra124-nyan-big.dts b/arch/arm/boot/dts/tegra124-nyan-big.dts
new file mode 100644
index 000000000..2d21253ea
--- /dev/null
+++ b/arch/arm/boot/dts/tegra124-nyan-big.dts
@@ -0,0 +1,1338 @@
+/dts-v1/;
+
+#include "tegra124-nyan.dtsi"
+
+#include "tegra124-nyan-big-emc.dtsi"
+
+/ {
+ model = "Acer Chromebook 13 CB5-311";
+ compatible = "google,nyan-big", "nvidia,tegra124";
+
+ panel: panel {
+ compatible = "auo,b133xtn01";
+
+ backlight = <&backlight>;
+ ddc-i2c-bus = <&dpaux>;
+ };
+
+ sdhci@0,700b0400 { /* SD Card on this bus */
+ wp-gpios = <&gpio TEGRA_GPIO(Q, 4) GPIO_ACTIVE_LOW>;
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-max98090-nyan-big",
+ "nvidia,tegra-audio-max98090-nyan",
+ "nvidia,tegra-audio-max98090";
+ nvidia,model = "GoogleNyanBig";
+ };
+
+ pinmux@0,70000868 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinmux_default>;
+
+ pinmux_default: common {
+ clk_32k_out_pa0 {
+ nvidia,pins = "clk_32k_out_pa0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart3_cts_n_pa1 {
+ nvidia,pins = "uart3_cts_n_pa1";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_fs_pa2 {
+ nvidia,pins = "dap2_fs_pa2";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_sclk_pa3 {
+ nvidia,pins = "dap2_sclk_pa3";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_din_pa4 {
+ nvidia,pins = "dap2_din_pa4";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_dout_pa5 {
+ nvidia,pins = "dap2_dout_pa5";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_clk_pa6 {
+ nvidia,pins = "sdmmc3_clk_pa6";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_cmd_pa7 {
+ nvidia,pins = "sdmmc3_cmd_pa7";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pb0 {
+ nvidia,pins = "pb0";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pb1 {
+ nvidia,pins = "pb1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_dat3_pb4 {
+ nvidia,pins = "sdmmc3_dat3_pb4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat2_pb5 {
+ nvidia,pins = "sdmmc3_dat2_pb5";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat1_pb6 {
+ nvidia,pins = "sdmmc3_dat1_pb6";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat0_pb7 {
+ nvidia,pins = "sdmmc3_dat0_pb7";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart3_rts_n_pc0 {
+ nvidia,pins = "uart3_rts_n_pc0";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_txd_pc2 {
+ nvidia,pins = "uart2_txd_pc2";
+ nvidia,function = "irda";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rxd_pc3 {
+ nvidia,pins = "uart2_rxd_pc3";
+ nvidia,function = "irda";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gen1_i2c_scl_pc4 {
+ nvidia,pins = "gen1_i2c_scl_pc4";
+ nvidia,function = "i2c1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ gen1_i2c_sda_pc5 {
+ nvidia,pins = "gen1_i2c_sda_pc5";
+ nvidia,function = "i2c1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ pc7 {
+ nvidia,pins = "pc7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pg0 {
+ nvidia,pins = "pg0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pg1 {
+ nvidia,pins = "pg1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pg2 {
+ nvidia,pins = "pg2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pg3 {
+ nvidia,pins = "pg3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pg4 {
+ nvidia,pins = "pg4";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pg5 {
+ nvidia,pins = "pg5";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pg6 {
+ nvidia,pins = "pg6";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pg7 {
+ nvidia,pins = "pg7";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ph0 {
+ nvidia,pins = "ph0";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ph1 {
+ nvidia,pins = "ph1";
+ nvidia,function = "pwm1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ph2 {
+ nvidia,pins = "ph2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ph3 {
+ nvidia,pins = "ph3";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ph4 {
+ nvidia,pins = "ph4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ph5 {
+ nvidia,pins = "ph5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ph6 {
+ nvidia,pins = "ph6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ph7 {
+ nvidia,pins = "ph7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pi0 {
+ nvidia,pins = "pi0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pi1 {
+ nvidia,pins = "pi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pi2 {
+ nvidia,pins = "pi2";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pi3 {
+ nvidia,pins = "pi3";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pi4 {
+ nvidia,pins = "pi4";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pi5 {
+ nvidia,pins = "pi5";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pi6 {
+ nvidia,pins = "pi6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pi7 {
+ nvidia,pins = "pi7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pj0 {
+ nvidia,pins = "pj0";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pj2 {
+ nvidia,pins = "pj2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_cts_n_pj5 {
+ nvidia,pins = "uart2_cts_n_pj5";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rts_n_pj6 {
+ nvidia,pins = "uart2_rts_n_pj6";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pj7 {
+ nvidia,pins = "pj7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pk0 {
+ nvidia,pins = "pk0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pk1 {
+ nvidia,pins = "pk1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pk2 {
+ nvidia,pins = "pk2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pk3 {
+ nvidia,pins = "pk3";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pk4 {
+ nvidia,pins = "pk4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ spdif_out_pk5 {
+ nvidia,pins = "spdif_out_pk5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ spdif_in_pk6 {
+ nvidia,pins = "spdif_in_pk6";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pk7 {
+ nvidia,pins = "pk7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap1_fs_pn0 {
+ nvidia,pins = "dap1_fs_pn0";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_din_pn1 {
+ nvidia,pins = "dap1_din_pn1";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_dout_pn2 {
+ nvidia,pins = "dap1_dout_pn2";
+ nvidia,function = "i2s0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_sclk_pn3 {
+ nvidia,pins = "dap1_sclk_pn3";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ usb_vbus_en0_pn4 {
+ nvidia,pins = "usb_vbus_en0_pn4";
+ nvidia,function = "usb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ usb_vbus_en1_pn5 {
+ nvidia,pins = "usb_vbus_en1_pn5";
+ nvidia,function = "usb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ hdmi_int_pn7 {
+ nvidia,pins = "hdmi_int_pn7";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data7_po0 {
+ nvidia,pins = "ulpi_data7_po0";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data0_po1 {
+ nvidia,pins = "ulpi_data0_po1";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data1_po2 {
+ nvidia,pins = "ulpi_data1_po2";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data2_po3 {
+ nvidia,pins = "ulpi_data2_po3";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data3_po4 {
+ nvidia,pins = "ulpi_data3_po4";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data4_po5 {
+ nvidia,pins = "ulpi_data4_po5";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data5_po6 {
+ nvidia,pins = "ulpi_data5_po6";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data6_po7 {
+ nvidia,pins = "ulpi_data6_po7";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap3_fs_pp0 {
+ nvidia,pins = "dap3_fs_pp0";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap3_din_pp1 {
+ nvidia,pins = "dap3_din_pp1";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap3_dout_pp2 {
+ nvidia,pins = "dap3_dout_pp2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap3_sclk_pp3 {
+ nvidia,pins = "dap3_sclk_pp3";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_fs_pp4 {
+ nvidia,pins = "dap4_fs_pp4";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_din_pp5 {
+ nvidia,pins = "dap4_din_pp5";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_dout_pp6 {
+ nvidia,pins = "dap4_dout_pp6";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_sclk_pp7 {
+ nvidia,pins = "dap4_sclk_pp7";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_col0_pq0 {
+ nvidia,pins = "kb_col0_pq0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col1_pq1 {
+ nvidia,pins = "kb_col1_pq1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_col2_pq2 {
+ nvidia,pins = "kb_col2_pq2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col3_pq3 {
+ nvidia,pins = "kb_col3_pq3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col4_pq4 {
+ nvidia,pins = "kb_col4_pq4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col5_pq5 {
+ nvidia,pins = "kb_col5_pq5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_col6_pq6 {
+ nvidia,pins = "kb_col6_pq6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col7_pq7 {
+ nvidia,pins = "kb_col7_pq7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row0_pr0 {
+ nvidia,pins = "kb_row0_pr0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row1_pr1 {
+ nvidia,pins = "kb_row1_pr1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row2_pr2 {
+ nvidia,pins = "kb_row2_pr2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row3_pr3 {
+ nvidia,pins = "kb_row3_pr3";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row4_pr4 {
+ nvidia,pins = "kb_row4_pr4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row5_pr5 {
+ nvidia,pins = "kb_row5_pr5";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row6_pr6 {
+ nvidia,pins = "kb_row6_pr6";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row7_pr7 {
+ nvidia,pins = "kb_row7_pr7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row8_ps0 {
+ nvidia,pins = "kb_row8_ps0";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row9_ps1 {
+ nvidia,pins = "kb_row9_ps1";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row10_ps2 {
+ nvidia,pins = "kb_row10_ps2";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row11_ps3 {
+ nvidia,pins = "kb_row11_ps3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row12_ps4 {
+ nvidia,pins = "kb_row12_ps4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row13_ps5 {
+ nvidia,pins = "kb_row13_ps5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row14_ps6 {
+ nvidia,pins = "kb_row14_ps6";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row15_ps7 {
+ nvidia,pins = "kb_row15_ps7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row16_pt0 {
+ nvidia,pins = "kb_row16_pt0";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row17_pt1 {
+ nvidia,pins = "kb_row17_pt1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gen2_i2c_scl_pt5 {
+ nvidia,pins = "gen2_i2c_scl_pt5";
+ nvidia,function = "i2c2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ gen2_i2c_sda_pt6 {
+ nvidia,pins = "gen2_i2c_sda_pt6";
+ nvidia,function = "i2c2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_cmd_pt7 {
+ nvidia,pins = "sdmmc4_cmd_pt7";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu0 {
+ nvidia,pins = "pu0";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pu1 {
+ nvidia,pins = "pu1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pu2 {
+ nvidia,pins = "pu2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pu3 {
+ nvidia,pins = "pu3";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pu4 {
+ nvidia,pins = "pu4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu5 {
+ nvidia,pins = "pu5";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu6 {
+ nvidia,pins = "pu6";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pv0 {
+ nvidia,pins = "pv0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pv1 {
+ nvidia,pins = "pv1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_cd_n_pv2 {
+ nvidia,pins = "sdmmc3_cd_n_pv2";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_wp_n_pv3 {
+ nvidia,pins = "sdmmc1_wp_n_pv3";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ddc_scl_pv4 {
+ nvidia,pins = "ddc_scl_pv4";
+ nvidia,function = "i2c4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
+ };
+ ddc_sda_pv5 {
+ nvidia,pins = "ddc_sda_pv5";
+ nvidia,function = "i2c4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_w2_aud_pw2 {
+ nvidia,pins = "gpio_w2_aud_pw2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_w3_aud_pw3 {
+ nvidia,pins = "gpio_w3_aud_pw3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap_mclk1_pw4 {
+ nvidia,pins = "dap_mclk1_pw4";
+ nvidia,function = "extperiph1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ clk2_out_pw5 {
+ nvidia,pins = "clk2_out_pw5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_txd_pw6 {
+ nvidia,pins = "uart3_txd_pw6";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_rxd_pw7 {
+ nvidia,pins = "uart3_rxd_pw7";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dvfs_pwm_px0 {
+ nvidia,pins = "dvfs_pwm_px0";
+ nvidia,function = "cldvfs";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x1_aud_px1 {
+ nvidia,pins = "gpio_x1_aud_px1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dvfs_clk_px2 {
+ nvidia,pins = "dvfs_clk_px2";
+ nvidia,function = "cldvfs";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x3_aud_px3 {
+ nvidia,pins = "gpio_x3_aud_px3";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x4_aud_px4 {
+ nvidia,pins = "gpio_x4_aud_px4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gpio_x5_aud_px5 {
+ nvidia,pins = "gpio_x5_aud_px5";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x6_aud_px6 {
+ nvidia,pins = "gpio_x6_aud_px6";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x7_aud_px7 {
+ nvidia,pins = "gpio_x7_aud_px7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_clk_py0 {
+ nvidia,pins = "ulpi_clk_py0";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_dir_py1 {
+ nvidia,pins = "ulpi_dir_py1";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_nxt_py2 {
+ nvidia,pins = "ulpi_nxt_py2";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_stp_py3 {
+ nvidia,pins = "ulpi_stp_py3";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat3_py4 {
+ nvidia,pins = "sdmmc1_dat3_py4";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_dat2_py5 {
+ nvidia,pins = "sdmmc1_dat2_py5";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_dat1_py6 {
+ nvidia,pins = "sdmmc1_dat1_py6";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_dat0_py7 {
+ nvidia,pins = "sdmmc1_dat0_py7";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_clk_pz0 {
+ nvidia,pins = "sdmmc1_clk_pz0";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_cmd_pz1 {
+ nvidia,pins = "sdmmc1_cmd_pz1";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pwr_i2c_scl_pz6 {
+ nvidia,pins = "pwr_i2c_scl_pz6";
+ nvidia,function = "i2cpwr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ pwr_i2c_sda_pz7 {
+ nvidia,pins = "pwr_i2c_sda_pz7";
+ nvidia,function = "i2cpwr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat0_paa0 {
+ nvidia,pins = "sdmmc4_dat0_paa0";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat1_paa1 {
+ nvidia,pins = "sdmmc4_dat1_paa1";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat2_paa2 {
+ nvidia,pins = "sdmmc4_dat2_paa2";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat3_paa3 {
+ nvidia,pins = "sdmmc4_dat3_paa3";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat4_paa4 {
+ nvidia,pins = "sdmmc4_dat4_paa4";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat5_paa5 {
+ nvidia,pins = "sdmmc4_dat5_paa5";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat6_paa6 {
+ nvidia,pins = "sdmmc4_dat6_paa6";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat7_paa7 {
+ nvidia,pins = "sdmmc4_dat7_paa7";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pbb0 {
+ nvidia,pins = "pbb0";
+ nvidia,function = "vgp6";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ cam_i2c_scl_pbb1 {
+ nvidia,pins = "cam_i2c_scl_pbb1";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam_i2c_sda_pbb2 {
+ nvidia,pins = "cam_i2c_sda_pbb2";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pbb3 {
+ nvidia,pins = "pbb3";
+ nvidia,function = "vgp3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pbb4 {
+ nvidia,pins = "pbb4";
+ nvidia,function = "vgp4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pbb5 {
+ nvidia,pins = "pbb5";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pbb6 {
+ nvidia,pins = "pbb6";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pbb7 {
+ nvidia,pins = "pbb7";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ cam_mclk_pcc0 {
+ nvidia,pins = "cam_mclk_pcc0";
+ nvidia,function = "vi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pcc1 {
+ nvidia,pins = "pcc1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pcc2 {
+ nvidia,pins = "pcc2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc4_clk_pcc4 {
+ nvidia,pins = "sdmmc4_clk_pcc4";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ clk2_req_pcc5 {
+ nvidia,pins = "clk2_req_pcc5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l0_rst_n_pdd1 {
+ nvidia,pins = "pex_l0_rst_n_pdd1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l0_clkreq_n_pdd2 {
+ nvidia,pins = "pex_l0_clkreq_n_pdd2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pex_wake_n_pdd3 {
+ nvidia,pins = "pex_wake_n_pdd3";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l1_rst_n_pdd5 {
+ nvidia,pins = "pex_l1_rst_n_pdd5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l1_clkreq_n_pdd6 {
+ nvidia,pins = "pex_l1_clkreq_n_pdd6";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ clk3_out_pee0 {
+ nvidia,pins = "clk3_out_pee0";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ clk3_req_pee1 {
+ nvidia,pins = "clk3_req_pee1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap_mclk1_req_pee2 {
+ nvidia,pins = "dap_mclk1_req_pee2";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ hdmi_cec_pee3 {
+ nvidia,pins = "hdmi_cec_pee3";
+ nvidia,function = "cec";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_clk_lb_out_pee4 {
+ nvidia,pins = "sdmmc3_clk_lb_out_pee4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_clk_lb_in_pee5 {
+ nvidia,pins = "sdmmc3_clk_lb_in_pee5";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dp_hpd_pff0 {
+ nvidia,pins = "dp_hpd_pff0";
+ nvidia,function = "dp";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ usb_vbus_en2_pff1 {
+ nvidia,pins = "usb_vbus_en2_pff1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pff2 {
+ nvidia,pins = "pff2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ core_pwr_req {
+ nvidia,pins = "core_pwr_req";
+ nvidia,function = "pwron";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ cpu_pwr_req {
+ nvidia,pins = "cpu_pwr_req";
+ nvidia,function = "cpu";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_int_n {
+ nvidia,pins = "pwr_int_n";
+ nvidia,function = "pmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ reset_out_n {
+ nvidia,pins = "reset_out_n";
+ nvidia,function = "reset_out_n";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ owr {
+ nvidia,pins = "owr";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
+ };
+ clk_32k_in {
+ nvidia,pins = "clk_32k_in";
+ nvidia,function = "clk";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ jtag_rtck {
+ nvidia,pins = "jtag_rtck";
+ nvidia,function = "rtck";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi b/arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi
new file mode 100644
index 000000000..9ecd108f5
--- /dev/null
+++ b/arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi
@@ -0,0 +1,2049 @@
+/ {
+ clock@0,60006000 {
+ emc-timings-1 {
+ nvidia,ram-code = <1>;
+
+ timing-12750000 {
+ clock-frequency = <12750000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-20400000 {
+ clock-frequency = <20400000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-40800000 {
+ clock-frequency = <40800000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-68000000 {
+ clock-frequency = <68000000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-102000000 {
+ clock-frequency = <102000000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-204000000 {
+ clock-frequency = <204000000>;
+ nvidia,parent-clock-frequency = <408000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "emc-parent";
+ };
+ timing-300000000 {
+ clock-frequency = <300000000>;
+ nvidia,parent-clock-frequency = <600000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_C>;
+ clock-names = "emc-parent";
+ };
+ timing-396000000 {
+ clock-frequency = <396000000>;
+ nvidia,parent-clock-frequency = <792000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_M>;
+ clock-names = "emc-parent";
+ };
+ /* TODO: Add 528MHz frequency */
+ timing-600000000 {
+ clock-frequency = <600000000>;
+ nvidia,parent-clock-frequency = <600000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_C_UD>;
+ clock-names = "emc-parent";
+ };
+ timing-792000000 {
+ clock-frequency = <792000000>;
+ nvidia,parent-clock-frequency = <792000000>;
+ clocks = <&tegra_car TEGRA124_CLK_PLL_M_UD>;
+ clock-names = "emc-parent";
+ };
+ };
+ };
+
+ emc@0,7001b000 {
+ emc-timings-1 {
+ nvidia,ram-code = <1>;
+
+ timing-12750000 {
+ clock-frequency = <12750000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x000008c5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00000000>;
+
+ nvidia,emc-configuration = <
+ 0x00000000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000a
+ 0x00000003
+ 0x0000000b
+ 0x00000000
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000c
+ 0x0000000d
+ 0x0000000f
+ 0x00000060
+ 0x00000000
+ 0x00000018
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x00000007
+ 0x0000000f
+ 0x00000005
+ 0x00000005
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000000
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000064
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x0000c000
+ 0x00000000
+ 0x00000000
+ 0x0000c000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000505
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000007
+ 0x00000000
+ 0x00000042
+ 0x000c000c
+ 0x00000000
+ 0x00000003
+ 0x0000f2f3
+ 0x800001c5
+ 0x0000000a
+ >;
+ };
+
+ timing-20400000 {
+ clock-frequency = <20400000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x000008c5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00000000>;
+
+ nvidia,emc-configuration = <
+ 0x00000000
+ 0x00000005
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000a
+ 0x00000003
+ 0x0000000b
+ 0x00000000
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000c
+ 0x0000000d
+ 0x0000000f
+ 0x0000009a
+ 0x00000000
+ 0x00000026
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x00000007
+ 0x0000000f
+ 0x00000006
+ 0x00000006
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000000
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x000000a0
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x0000c000
+ 0x00000000
+ 0x00000000
+ 0x0000c000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000505
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x0000000b
+ 0x00000000
+ 0x00000042
+ 0x000c000c
+ 0x00000000
+ 0x00000003
+ 0x0000f2f3
+ 0x8000023a
+ 0x0000000a
+ >;
+ };
+
+ timing-40800000 {
+ clock-frequency = <40800000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x000008c5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00000000>;
+
+ nvidia,emc-configuration = <
+ 0x00000001
+ 0x0000000a
+ 0x00000000
+ 0x00000001
+ 0x00000000
+ 0x00000004
+ 0x0000000a
+ 0x00000003
+ 0x0000000b
+ 0x00000000
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000c
+ 0x0000000d
+ 0x0000000f
+ 0x00000134
+ 0x00000000
+ 0x0000004d
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x00000008
+ 0x0000000f
+ 0x0000000c
+ 0x0000000c
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000000
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x0000013f
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x0000c000
+ 0x00000000
+ 0x00000000
+ 0x0000c000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000505
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000015
+ 0x00000000
+ 0x00000042
+ 0x000c000c
+ 0x00000000
+ 0x00000003
+ 0x0000f2f3
+ 0x80000370
+ 0x0000000a
+ >;
+ };
+
+ timing-68000000 {
+ clock-frequency = <68000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x000008c5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00000000>;
+
+ nvidia,emc-configuration = <
+ 0x00000003
+ 0x00000011
+ 0x00000000
+ 0x00000002
+ 0x00000000
+ 0x00000004
+ 0x0000000a
+ 0x00000003
+ 0x0000000b
+ 0x00000000
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000c
+ 0x0000000d
+ 0x0000000f
+ 0x00000202
+ 0x00000000
+ 0x00000080
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x0000000f
+ 0x0000000f
+ 0x00000013
+ 0x00000013
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000001
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000213
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x0000c000
+ 0x00000000
+ 0x00000000
+ 0x0000c000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000505
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000022
+ 0x00000000
+ 0x00000042
+ 0x000c000c
+ 0x00000000
+ 0x00000003
+ 0x0000f2f3
+ 0x8000050e
+ 0x0000000a
+ >;
+ };
+
+ timing-102000000 {
+ clock-frequency = <102000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x000008c5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00000000>;
+
+ nvidia,emc-configuration = <
+ 0x00000004
+ 0x0000001a
+ 0x00000000
+ 0x00000003
+ 0x00000001
+ 0x00000004
+ 0x0000000a
+ 0x00000003
+ 0x0000000b
+ 0x00000001
+ 0x00000001
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x0000000c
+ 0x0000000d
+ 0x0000000f
+ 0x00000304
+ 0x00000000
+ 0x000000c1
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x00000018
+ 0x0000000f
+ 0x0000001c
+ 0x0000001c
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000003
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x0000031c
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x0000c000
+ 0x00000000
+ 0x00000000
+ 0x0000c000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x000fc000
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x0000fc00
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000505
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000033
+ 0x00000000
+ 0x00000042
+ 0x000c000c
+ 0x00000000
+ 0x00000003
+ 0x0000f2f3
+ 0x80000713
+ 0x0000000a
+ >;
+ };
+
+ timing-204000000 {
+ clock-frequency = <204000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000008>;
+ nvidia,emc-cfg = <0x73240000>;
+ nvidia,emc-cfg-2 = <0x0000088d>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100003>;
+ nvidia,emc-mode-2 = <0x80200008>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80001221>;
+ nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x00000009
+ 0x00000035
+ 0x00000000
+ 0x00000007
+ 0x00000002
+ 0x00000005
+ 0x0000000a
+ 0x00000003
+ 0x0000000b
+ 0x00000002
+ 0x00000002
+ 0x00000003
+ 0x00000003
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000006
+ 0x00000002
+ 0x00000000
+ 0x00000004
+ 0x00000006
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000003
+ 0x0000000d
+ 0x0000000f
+ 0x00000011
+ 0x00000607
+ 0x00000000
+ 0x00000181
+ 0x00000002
+ 0x00000002
+ 0x00000001
+ 0x00000000
+ 0x00000032
+ 0x0000000f
+ 0x00000038
+ 0x00000038
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000007
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000638
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x106aa298
+ 0x002c00a0
+ 0x00008000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00064000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x0000c000
+ 0x00000000
+ 0x00000000
+ 0x0000c000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00090000
+ 0x00090000
+ 0x00090000
+ 0x00090000
+ 0x00009000
+ 0x00009000
+ 0x00009000
+ 0x00009000
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000505
+ 0x81f1f108
+ 0x07070004
+ 0x0000003f
+ 0x016eeeee
+ 0x51451400
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000066
+ 0x00000000
+ 0x00000100
+ 0x000c000c
+ 0x00000000
+ 0x00000003
+ 0x0000d2b3
+ 0x80000d22
+ 0x0000000a
+ >;
+ };
+
+ timing-300000000 {
+ clock-frequency = <300000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000000>;
+ nvidia,emc-cfg = <0x73340000>;
+ nvidia,emc-cfg-2 = <0x000008d5>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100002>;
+ nvidia,emc-mode-2 = <0x80200000>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80000321>;
+ nvidia,emc-mrs-wait-cnt = <0x0174000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+ nvidia,emc-xm2dqspadctrl2 = <0x01231339>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x0000000d
+ 0x0000004c
+ 0x00000000
+ 0x00000009
+ 0x00000003
+ 0x00000004
+ 0x00000008
+ 0x00000002
+ 0x00000009
+ 0x00000003
+ 0x00000003
+ 0x00000002
+ 0x00000002
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000005
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x00000007
+ 0x00020000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000001
+ 0x0000000e
+ 0x00000010
+ 0x00000012
+ 0x000008e4
+ 0x00000000
+ 0x00000239
+ 0x00000001
+ 0x00000008
+ 0x00000001
+ 0x00000000
+ 0x0000004a
+ 0x0000000e
+ 0x00000051
+ 0x00000200
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000009
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000924
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x104ab098
+ 0x002c00a0
+ 0x00008000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00090000
+ 0x00090000
+ 0x00000000
+ 0x00090000
+ 0x00090000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00060000
+ 0x00060000
+ 0x00060000
+ 0x00060000
+ 0x00006000
+ 0x00006000
+ 0x00006000
+ 0x00006000
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000202
+ 0x81f1f108
+ 0x07070004
+ 0x00000000
+ 0x016eeeee
+ 0x51451420
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x00000096
+ 0x00000000
+ 0x00000100
+ 0x0174000c
+ 0x00000000
+ 0x00000003
+ 0x000052a3
+ 0x800012d7
+ 0x00000009
+ >;
+ };
+
+ timing-396000000 {
+ clock-frequency = <396000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000000>;
+ nvidia,emc-cfg = <0x73340000>;
+ nvidia,emc-cfg-2 = <0x00000895>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100002>;
+ nvidia,emc-mode-2 = <0x80200000>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80000521>;
+ nvidia,emc-mrs-wait-cnt = <0x015b000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+ nvidia,emc-xm2dqspadctrl2 = <0x01231339>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x00000012
+ 0x00000065
+ 0x00000000
+ 0x0000000c
+ 0x00000004
+ 0x00000005
+ 0x00000008
+ 0x00000002
+ 0x0000000a
+ 0x00000004
+ 0x00000004
+ 0x00000002
+ 0x00000002
+ 0x00000000
+ 0x00000003
+ 0x00000003
+ 0x00000005
+ 0x00000002
+ 0x00000000
+ 0x00000001
+ 0x00000008
+ 0x00020000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x0000000f
+ 0x00000010
+ 0x00000012
+ 0x00000bd1
+ 0x00000000
+ 0x000002f4
+ 0x00000001
+ 0x00000008
+ 0x00000001
+ 0x00000000
+ 0x00000063
+ 0x0000000f
+ 0x0000006b
+ 0x00000200
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x0000000d
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x00000c11
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x104ab098
+ 0x002c00a0
+ 0x00008000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00030000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00068000
+ 0x00068000
+ 0x00000000
+ 0x00068000
+ 0x00068000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00058000
+ 0x00058000
+ 0x00058000
+ 0x00058000
+ 0x00005800
+ 0x00005800
+ 0x00005800
+ 0x00005800
+ 0x10000280
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc081
+ 0x00000202
+ 0x81f1f108
+ 0x07070004
+ 0x00000000
+ 0x016eeeee
+ 0x51451420
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0000003f
+ 0x000000c6
+ 0x00000000
+ 0x00000100
+ 0x015b000c
+ 0x00000000
+ 0x00000003
+ 0x000052a3
+ 0x8000188b
+ 0x00000009
+ >;
+ };
+
+ timing-600000000 {
+ clock-frequency = <600000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000000>;
+ nvidia,emc-cfg = <0x73300000>;
+ nvidia,emc-cfg-2 = <0x0000089d>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100002>;
+ nvidia,emc-mode-2 = <0x80200010>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80000b61>;
+ nvidia,emc-mrs-wait-cnt = <0x0128000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0121113d>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x0000001c
+ 0x0000009a
+ 0x00000000
+ 0x00000013
+ 0x00000007
+ 0x00000007
+ 0x0000000b
+ 0x00000003
+ 0x00000010
+ 0x00000007
+ 0x00000007
+ 0x00000002
+ 0x00000002
+ 0x00000000
+ 0x00000005
+ 0x00000005
+ 0x0000000a
+ 0x00000002
+ 0x00000000
+ 0x00000003
+ 0x0000000b
+ 0x00070000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000002
+ 0x00000012
+ 0x00000016
+ 0x00000018
+ 0x00001208
+ 0x00000000
+ 0x00000482
+ 0x00000002
+ 0x0000000d
+ 0x00000001
+ 0x00000000
+ 0x00000096
+ 0x00000015
+ 0x000000a2
+ 0x00000200
+ 0x00000004
+ 0x00000005
+ 0x00000004
+ 0x00000015
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x00001248
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x104ab098
+ 0xe00e00b1
+ 0x00008000
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x0000000a
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00040000
+ 0x00040000
+ 0x00000000
+ 0x00040000
+ 0x00040000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000004
+ 0x00000004
+ 0x00000001
+ 0x00000005
+ 0x00000007
+ 0x00000004
+ 0x00000006
+ 0x00000007
+ 0x00000004
+ 0x00000004
+ 0x00000001
+ 0x00000005
+ 0x00000007
+ 0x00000004
+ 0x00000006
+ 0x00000007
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x100002a0
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc085
+ 0x00000202
+ 0x81f1f108
+ 0x07070004
+ 0x00000000
+ 0x016eeeee
+ 0x51451420
+ 0x00514514
+ 0x00514514
+ 0x51451400
+ 0x0606003f
+ 0x00000000
+ 0x00000000
+ 0x00000100
+ 0x0128000c
+ 0x00000000
+ 0x00000003
+ 0x000040a0
+ 0x800024a9
+ 0x0000000e
+ >;
+ };
+
+ timing-792000000 {
+ clock-frequency = <792000000>;
+
+ nvidia,emc-auto-cal-config = <0xa1430000>;
+ nvidia,emc-auto-cal-config2 = <0x00000000>;
+ nvidia,emc-auto-cal-config3 = <0x00000000>;
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-bgbias-ctl0 = <0x00000000>;
+ nvidia,emc-cfg = <0x73300000>;
+ nvidia,emc-cfg-2 = <0x0000089d>;
+ nvidia,emc-ctt-term-ctrl = <0x00000802>;
+ nvidia,emc-mode-1 = <0x80100002>;
+ nvidia,emc-mode-2 = <0x80200018>;
+ nvidia,emc-mode-4 = <0x00000000>;
+ nvidia,emc-mode-reset = <0x80000d71>;
+ nvidia,emc-mrs-wait-cnt = <0x00f8000c>;
+ nvidia,emc-sel-dpd-ctrl = <0x00040000>;
+ nvidia,emc-xm2dqspadctrl2 = <0x0120113d>;
+ nvidia,emc-zcal-cnt-long = <0x00000042>;
+ nvidia,emc-zcal-interval = <0x00020000>;
+
+ nvidia,emc-configuration = <
+ 0x00000025
+ 0x000000cc
+ 0x00000000
+ 0x0000001a
+ 0x00000009
+ 0x00000008
+ 0x0000000d
+ 0x00000004
+ 0x00000013
+ 0x00000009
+ 0x00000009
+ 0x00000003
+ 0x00000002
+ 0x00000000
+ 0x00000006
+ 0x00000006
+ 0x0000000b
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x0000000d
+ 0x00080000
+ 0x00000004
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000001
+ 0x00000014
+ 0x00000018
+ 0x0000001a
+ 0x000017e2
+ 0x00000000
+ 0x000005f8
+ 0x00000003
+ 0x00000011
+ 0x00000001
+ 0x00000000
+ 0x000000c6
+ 0x00000018
+ 0x000000d6
+ 0x00000200
+ 0x00000005
+ 0x00000006
+ 0x00000005
+ 0x0000001d
+ 0x00000000
+ 0x00000008
+ 0x00000008
+ 0x00001822
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x104ab098
+ 0xe00700b1
+ 0x00008000
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000008
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x0002c000
+ 0x0002c000
+ 0x00000000
+ 0x0002c000
+ 0x0002c000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000008
+ 0x00000008
+ 0x00000005
+ 0x00000008
+ 0x0000000a
+ 0x00000008
+ 0x0000000a
+ 0x0000000a
+ 0x00000008
+ 0x00000008
+ 0x00000005
+ 0x00000008
+ 0x0000000a
+ 0x00000008
+ 0x0000000a
+ 0x0000000a
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x0000000e
+ 0x100002a0
+ 0x00000000
+ 0x00111111
+ 0x00000000
+ 0x00000000
+ 0x77ffc085
+ 0x00000202
+ 0x81f1f108
+ 0x07070004
+ 0x00000000
+ 0x016eeeee
+ 0x61861820
+ 0x00492492
+ 0x00492492
+ 0x61861800
+ 0x0606003f
+ 0x00000000
+ 0x00000000
+ 0x00000100
+ 0x00f8000c
+ 0x00000000
+ 0x00000004
+ 0x00004080
+ 0x80003012
+ 0x0000000f
+ >;
+ };
+
+ };
+ };
+
+ memory-controller@0,70019000 {
+ emc-timings-1 {
+ nvidia,ram-code = <1>;
+
+
+ timing-12750000 {
+ clock-frequency = <12750000>;
+
+ nvidia,emem-configuration = <
+ 0x40040001
+ 0x8000000a
+ 0x00000001
+ 0x00000001
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x00000001
+ 0x00000002
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000003
+ 0x00000006
+ 0x06030203
+ 0x000a0402
+ 0x77e30303
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-20400000 {
+ clock-frequency = <20400000>;
+
+ nvidia,emem-configuration = <
+ 0x40020001
+ 0x80000012
+ 0x00000001
+ 0x00000001
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x00000001
+ 0x00000002
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000003
+ 0x00000006
+ 0x06030203
+ 0x000a0402
+ 0x76230303
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-40800000 {
+ clock-frequency = <40800000>;
+
+ nvidia,emem-configuration = <
+ 0xa0000001
+ 0x80000017
+ 0x00000001
+ 0x00000001
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x00000001
+ 0x00000002
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000003
+ 0x00000006
+ 0x06030203
+ 0x000a0402
+ 0x74a30303
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-68000000 {
+ clock-frequency = <68000000>;
+
+ nvidia,emem-configuration = <
+ 0x00000001
+ 0x8000001e
+ 0x00000001
+ 0x00000001
+ 0x00000002
+ 0x00000000
+ 0x00000002
+ 0x00000001
+ 0x00000002
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000003
+ 0x00000006
+ 0x06030203
+ 0x000a0402
+ 0x74230403
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-102000000 {
+ clock-frequency = <102000000>;
+
+ nvidia,emem-configuration = <
+ 0x08000001
+ 0x80000026
+ 0x00000001
+ 0x00000001
+ 0x00000003
+ 0x00000000
+ 0x00000002
+ 0x00000001
+ 0x00000002
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000003
+ 0x00000006
+ 0x06030203
+ 0x000a0403
+ 0x73c30504
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-204000000 {
+ clock-frequency = <204000000>;
+
+ nvidia,emem-configuration = <
+ 0x01000003
+ 0x80000040
+ 0x00000001
+ 0x00000001
+ 0x00000005
+ 0x00000002
+ 0x00000004
+ 0x00000001
+ 0x00000002
+ 0x00000008
+ 0x00000003
+ 0x00000002
+ 0x00000004
+ 0x00000006
+ 0x06040203
+ 0x000a0405
+ 0x73840a06
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-300000000 {
+ clock-frequency = <300000000>;
+
+ nvidia,emem-configuration = <
+ 0x08000004
+ 0x80000040
+ 0x00000001
+ 0x00000002
+ 0x00000007
+ 0x00000004
+ 0x00000005
+ 0x00000001
+ 0x00000002
+ 0x00000007
+ 0x00000002
+ 0x00000002
+ 0x00000004
+ 0x00000006
+ 0x06040202
+ 0x000b0607
+ 0x77450e08
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-396000000 {
+ clock-frequency = <396000000>;
+
+ nvidia,emem-configuration = <
+ 0x0f000005
+ 0x80000040
+ 0x00000001
+ 0x00000002
+ 0x00000009
+ 0x00000005
+ 0x00000007
+ 0x00000001
+ 0x00000002
+ 0x00000008
+ 0x00000002
+ 0x00000002
+ 0x00000004
+ 0x00000006
+ 0x06040202
+ 0x000d0709
+ 0x7586120a
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-528000000 {
+ clock-frequency = <528000000>;
+
+ nvidia,emem-configuration = <
+ 0x0f000007
+ 0x80000040
+ 0x00000002
+ 0x00000003
+ 0x0000000d
+ 0x00000008
+ 0x0000000a
+ 0x00000001
+ 0x00000002
+ 0x00000009
+ 0x00000002
+ 0x00000002
+ 0x00000005
+ 0x00000006
+ 0x06050202
+ 0x0010090d
+ 0x7428180e
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-600000000 {
+ clock-frequency = <600000000>;
+
+ nvidia,emem-configuration = <
+ 0x00000009
+ 0x80000040
+ 0x00000003
+ 0x00000004
+ 0x0000000e
+ 0x00000009
+ 0x0000000b
+ 0x00000001
+ 0x00000003
+ 0x0000000b
+ 0x00000002
+ 0x00000002
+ 0x00000005
+ 0x00000007
+ 0x07050202
+ 0x00130b0e
+ 0x73a91b0f
+ 0x70000f03
+ 0x001f0000
+ >;
+ };
+
+ timing-792000000 {
+ clock-frequency = <792000000>;
+
+ nvidia,emem-configuration = <
+ 0x0e00000b
+ 0x80000040
+ 0x00000004
+ 0x00000005
+ 0x00000013
+ 0x0000000c
+ 0x0000000f
+ 0x00000002
+ 0x00000003
+ 0x0000000c
+ 0x00000002
+ 0x00000002
+ 0x00000006
+ 0x00000008
+ 0x08060202
+ 0x00160d13
+ 0x734c2414
+ 0x70000f02
+ 0x001f0000
+ >;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra124-nyan-blaze.dts b/arch/arm/boot/dts/tegra124-nyan-blaze.dts
new file mode 100644
index 000000000..0d30c514f
--- /dev/null
+++ b/arch/arm/boot/dts/tegra124-nyan-blaze.dts
@@ -0,0 +1,1334 @@
+/dts-v1/;
+
+#include "tegra124-nyan.dtsi"
+
+#include "tegra124-nyan-blaze-emc.dtsi"
+
+/ {
+ model = "HP Chromebook 14";
+ compatible = "google,nyan-blaze", "google,nyan", "nvidia,tegra124";
+
+ panel: panel {
+ compatible = "samsung,ltn140at29-301";
+
+ backlight = <&backlight>;
+ ddc-i2c-bus = <&dpaux>;
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-max98090-nyan-blaze",
+ "nvidia,tegra-audio-max98090-nyan",
+ "nvidia,tegra-audio-max98090";
+ nvidia,model = "GoogleNyanBlaze";
+ };
+
+ pinmux@0,70000868 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinmux_default>;
+
+ pinmux_default: common {
+ clk_32k_out_pa0 {
+ nvidia,pins = "clk_32k_out_pa0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart3_cts_n_pa1 {
+ nvidia,pins = "uart3_cts_n_pa1";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_fs_pa2 {
+ nvidia,pins = "dap2_fs_pa2";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_sclk_pa3 {
+ nvidia,pins = "dap2_sclk_pa3";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_din_pa4 {
+ nvidia,pins = "dap2_din_pa4";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_dout_pa5 {
+ nvidia,pins = "dap2_dout_pa5";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_clk_pa6 {
+ nvidia,pins = "sdmmc3_clk_pa6";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_cmd_pa7 {
+ nvidia,pins = "sdmmc3_cmd_pa7";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pb0 {
+ nvidia,pins = "pb0";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pb1 {
+ nvidia,pins = "pb1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_dat3_pb4 {
+ nvidia,pins = "sdmmc3_dat3_pb4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat2_pb5 {
+ nvidia,pins = "sdmmc3_dat2_pb5";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat1_pb6 {
+ nvidia,pins = "sdmmc3_dat1_pb6";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat0_pb7 {
+ nvidia,pins = "sdmmc3_dat0_pb7";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart3_rts_n_pc0 {
+ nvidia,pins = "uart3_rts_n_pc0";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_txd_pc2 {
+ nvidia,pins = "uart2_txd_pc2";
+ nvidia,function = "irda";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rxd_pc3 {
+ nvidia,pins = "uart2_rxd_pc3";
+ nvidia,function = "irda";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gen1_i2c_scl_pc4 {
+ nvidia,pins = "gen1_i2c_scl_pc4";
+ nvidia,function = "i2c1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ gen1_i2c_sda_pc5 {
+ nvidia,pins = "gen1_i2c_sda_pc5";
+ nvidia,function = "i2c1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ pc7 {
+ nvidia,pins = "pc7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pg0 {
+ nvidia,pins = "pg0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pg1 {
+ nvidia,pins = "pg1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pg2 {
+ nvidia,pins = "pg2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pg3 {
+ nvidia,pins = "pg3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pg4 {
+ nvidia,pins = "pg4";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pg5 {
+ nvidia,pins = "pg5";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pg6 {
+ nvidia,pins = "pg6";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pg7 {
+ nvidia,pins = "pg7";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ph0 {
+ nvidia,pins = "ph0";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ph1 {
+ nvidia,pins = "ph1";
+ nvidia,function = "pwm1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ph2 {
+ nvidia,pins = "ph2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ph3 {
+ nvidia,pins = "ph3";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ph4 {
+ nvidia,pins = "ph4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ph5 {
+ nvidia,pins = "ph5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ph6 {
+ nvidia,pins = "ph6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ph7 {
+ nvidia,pins = "ph7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pi0 {
+ nvidia,pins = "pi0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pi1 {
+ nvidia,pins = "pi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pi2 {
+ nvidia,pins = "pi2";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pi3 {
+ nvidia,pins = "pi3";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pi4 {
+ nvidia,pins = "pi4";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pi5 {
+ nvidia,pins = "pi5";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pi6 {
+ nvidia,pins = "pi6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pi7 {
+ nvidia,pins = "pi7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pj0 {
+ nvidia,pins = "pj0";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pj2 {
+ nvidia,pins = "pj2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_cts_n_pj5 {
+ nvidia,pins = "uart2_cts_n_pj5";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rts_n_pj6 {
+ nvidia,pins = "uart2_rts_n_pj6";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pj7 {
+ nvidia,pins = "pj7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pk0 {
+ nvidia,pins = "pk0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pk1 {
+ nvidia,pins = "pk1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pk2 {
+ nvidia,pins = "pk2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pk3 {
+ nvidia,pins = "pk3";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pk4 {
+ nvidia,pins = "pk4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ spdif_out_pk5 {
+ nvidia,pins = "spdif_out_pk5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ spdif_in_pk6 {
+ nvidia,pins = "spdif_in_pk6";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pk7 {
+ nvidia,pins = "pk7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap1_fs_pn0 {
+ nvidia,pins = "dap1_fs_pn0";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_din_pn1 {
+ nvidia,pins = "dap1_din_pn1";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_dout_pn2 {
+ nvidia,pins = "dap1_dout_pn2";
+ nvidia,function = "i2s0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_sclk_pn3 {
+ nvidia,pins = "dap1_sclk_pn3";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ usb_vbus_en0_pn4 {
+ nvidia,pins = "usb_vbus_en0_pn4";
+ nvidia,function = "usb";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ usb_vbus_en1_pn5 {
+ nvidia,pins = "usb_vbus_en1_pn5";
+ nvidia,function = "usb";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ hdmi_int_pn7 {
+ nvidia,pins = "hdmi_int_pn7";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data7_po0 {
+ nvidia,pins = "ulpi_data7_po0";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data0_po1 {
+ nvidia,pins = "ulpi_data0_po1";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data1_po2 {
+ nvidia,pins = "ulpi_data1_po2";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data2_po3 {
+ nvidia,pins = "ulpi_data2_po3";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data3_po4 {
+ nvidia,pins = "ulpi_data3_po4";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data4_po5 {
+ nvidia,pins = "ulpi_data4_po5";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data5_po6 {
+ nvidia,pins = "ulpi_data5_po6";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data6_po7 {
+ nvidia,pins = "ulpi_data6_po7";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap3_fs_pp0 {
+ nvidia,pins = "dap3_fs_pp0";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap3_din_pp1 {
+ nvidia,pins = "dap3_din_pp1";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap3_dout_pp2 {
+ nvidia,pins = "dap3_dout_pp2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap3_sclk_pp3 {
+ nvidia,pins = "dap3_sclk_pp3";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_fs_pp4 {
+ nvidia,pins = "dap4_fs_pp4";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_din_pp5 {
+ nvidia,pins = "dap4_din_pp5";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_dout_pp6 {
+ nvidia,pins = "dap4_dout_pp6";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_sclk_pp7 {
+ nvidia,pins = "dap4_sclk_pp7";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_col0_pq0 {
+ nvidia,pins = "kb_col0_pq0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col1_pq1 {
+ nvidia,pins = "kb_col1_pq1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_col2_pq2 {
+ nvidia,pins = "kb_col2_pq2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col3_pq3 {
+ nvidia,pins = "kb_col3_pq3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col4_pq4 {
+ nvidia,pins = "kb_col4_pq4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col5_pq5 {
+ nvidia,pins = "kb_col5_pq5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_col6_pq6 {
+ nvidia,pins = "kb_col6_pq6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col7_pq7 {
+ nvidia,pins = "kb_col7_pq7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row0_pr0 {
+ nvidia,pins = "kb_row0_pr0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row1_pr1 {
+ nvidia,pins = "kb_row1_pr1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row2_pr2 {
+ nvidia,pins = "kb_row2_pr2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row3_pr3 {
+ nvidia,pins = "kb_row3_pr3";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row4_pr4 {
+ nvidia,pins = "kb_row4_pr4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row5_pr5 {
+ nvidia,pins = "kb_row5_pr5";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row6_pr6 {
+ nvidia,pins = "kb_row6_pr6";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row7_pr7 {
+ nvidia,pins = "kb_row7_pr7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row8_ps0 {
+ nvidia,pins = "kb_row8_ps0";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row9_ps1 {
+ nvidia,pins = "kb_row9_ps1";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row10_ps2 {
+ nvidia,pins = "kb_row10_ps2";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row11_ps3 {
+ nvidia,pins = "kb_row11_ps3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row12_ps4 {
+ nvidia,pins = "kb_row12_ps4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row13_ps5 {
+ nvidia,pins = "kb_row13_ps5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row14_ps6 {
+ nvidia,pins = "kb_row14_ps6";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row15_ps7 {
+ nvidia,pins = "kb_row15_ps7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row16_pt0 {
+ nvidia,pins = "kb_row16_pt0";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row17_pt1 {
+ nvidia,pins = "kb_row17_pt1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gen2_i2c_scl_pt5 {
+ nvidia,pins = "gen2_i2c_scl_pt5";
+ nvidia,function = "i2c2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ gen2_i2c_sda_pt6 {
+ nvidia,pins = "gen2_i2c_sda_pt6";
+ nvidia,function = "i2c2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_cmd_pt7 {
+ nvidia,pins = "sdmmc4_cmd_pt7";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu0 {
+ nvidia,pins = "pu0";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pu1 {
+ nvidia,pins = "pu1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pu2 {
+ nvidia,pins = "pu2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pu3 {
+ nvidia,pins = "pu3";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pu4 {
+ nvidia,pins = "pu4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu5 {
+ nvidia,pins = "pu5";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu6 {
+ nvidia,pins = "pu6";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pv0 {
+ nvidia,pins = "pv0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pv1 {
+ nvidia,pins = "pv1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_cd_n_pv2 {
+ nvidia,pins = "sdmmc3_cd_n_pv2";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_wp_n_pv3 {
+ nvidia,pins = "sdmmc1_wp_n_pv3";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ddc_scl_pv4 {
+ nvidia,pins = "ddc_scl_pv4";
+ nvidia,function = "i2c4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
+ };
+ ddc_sda_pv5 {
+ nvidia,pins = "ddc_sda_pv5";
+ nvidia,function = "i2c4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_w2_aud_pw2 {
+ nvidia,pins = "gpio_w2_aud_pw2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_w3_aud_pw3 {
+ nvidia,pins = "gpio_w3_aud_pw3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap_mclk1_pw4 {
+ nvidia,pins = "dap_mclk1_pw4";
+ nvidia,function = "extperiph1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ clk2_out_pw5 {
+ nvidia,pins = "clk2_out_pw5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_txd_pw6 {
+ nvidia,pins = "uart3_txd_pw6";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_rxd_pw7 {
+ nvidia,pins = "uart3_rxd_pw7";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dvfs_pwm_px0 {
+ nvidia,pins = "dvfs_pwm_px0";
+ nvidia,function = "cldvfs";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x1_aud_px1 {
+ nvidia,pins = "gpio_x1_aud_px1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dvfs_clk_px2 {
+ nvidia,pins = "dvfs_clk_px2";
+ nvidia,function = "cldvfs";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x3_aud_px3 {
+ nvidia,pins = "gpio_x3_aud_px3";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x4_aud_px4 {
+ nvidia,pins = "gpio_x4_aud_px4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gpio_x5_aud_px5 {
+ nvidia,pins = "gpio_x5_aud_px5";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x6_aud_px6 {
+ nvidia,pins = "gpio_x6_aud_px6";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x7_aud_px7 {
+ nvidia,pins = "gpio_x7_aud_px7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_clk_py0 {
+ nvidia,pins = "ulpi_clk_py0";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_dir_py1 {
+ nvidia,pins = "ulpi_dir_py1";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_nxt_py2 {
+ nvidia,pins = "ulpi_nxt_py2";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_stp_py3 {
+ nvidia,pins = "ulpi_stp_py3";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat3_py4 {
+ nvidia,pins = "sdmmc1_dat3_py4";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_dat2_py5 {
+ nvidia,pins = "sdmmc1_dat2_py5";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_dat1_py6 {
+ nvidia,pins = "sdmmc1_dat1_py6";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_dat0_py7 {
+ nvidia,pins = "sdmmc1_dat0_py7";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_clk_pz0 {
+ nvidia,pins = "sdmmc1_clk_pz0";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_cmd_pz1 {
+ nvidia,pins = "sdmmc1_cmd_pz1";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pwr_i2c_scl_pz6 {
+ nvidia,pins = "pwr_i2c_scl_pz6";
+ nvidia,function = "i2cpwr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ pwr_i2c_sda_pz7 {
+ nvidia,pins = "pwr_i2c_sda_pz7";
+ nvidia,function = "i2cpwr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat0_paa0 {
+ nvidia,pins = "sdmmc4_dat0_paa0";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat1_paa1 {
+ nvidia,pins = "sdmmc4_dat1_paa1";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat2_paa2 {
+ nvidia,pins = "sdmmc4_dat2_paa2";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat3_paa3 {
+ nvidia,pins = "sdmmc4_dat3_paa3";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat4_paa4 {
+ nvidia,pins = "sdmmc4_dat4_paa4";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat5_paa5 {
+ nvidia,pins = "sdmmc4_dat5_paa5";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat6_paa6 {
+ nvidia,pins = "sdmmc4_dat6_paa6";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat7_paa7 {
+ nvidia,pins = "sdmmc4_dat7_paa7";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pbb0 {
+ nvidia,pins = "pbb0";
+ nvidia,function = "vgp6";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ cam_i2c_scl_pbb1 {
+ nvidia,pins = "cam_i2c_scl_pbb1";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam_i2c_sda_pbb2 {
+ nvidia,pins = "cam_i2c_sda_pbb2";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pbb3 {
+ nvidia,pins = "pbb3";
+ nvidia,function = "vgp3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pbb4 {
+ nvidia,pins = "pbb4";
+ nvidia,function = "vgp4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pbb5 {
+ nvidia,pins = "pbb5";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pbb6 {
+ nvidia,pins = "pbb6";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pbb7 {
+ nvidia,pins = "pbb7";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ cam_mclk_pcc0 {
+ nvidia,pins = "cam_mclk_pcc0";
+ nvidia,function = "vi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pcc1 {
+ nvidia,pins = "pcc1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pcc2 {
+ nvidia,pins = "pcc2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc4_clk_pcc4 {
+ nvidia,pins = "sdmmc4_clk_pcc4";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ clk2_req_pcc5 {
+ nvidia,pins = "clk2_req_pcc5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l0_rst_n_pdd1 {
+ nvidia,pins = "pex_l0_rst_n_pdd1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l0_clkreq_n_pdd2 {
+ nvidia,pins = "pex_l0_clkreq_n_pdd2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pex_wake_n_pdd3 {
+ nvidia,pins = "pex_wake_n_pdd3";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l1_rst_n_pdd5 {
+ nvidia,pins = "pex_l1_rst_n_pdd5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l1_clkreq_n_pdd6 {
+ nvidia,pins = "pex_l1_clkreq_n_pdd6";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ clk3_out_pee0 {
+ nvidia,pins = "clk3_out_pee0";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ clk3_req_pee1 {
+ nvidia,pins = "clk3_req_pee1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap_mclk1_req_pee2 {
+ nvidia,pins = "dap_mclk1_req_pee2";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ hdmi_cec_pee3 {
+ nvidia,pins = "hdmi_cec_pee3";
+ nvidia,function = "cec";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_clk_lb_out_pee4 {
+ nvidia,pins = "sdmmc3_clk_lb_out_pee4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_clk_lb_in_pee5 {
+ nvidia,pins = "sdmmc3_clk_lb_in_pee5";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dp_hpd_pff0 {
+ nvidia,pins = "dp_hpd_pff0";
+ nvidia,function = "dp";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ usb_vbus_en2_pff1 {
+ nvidia,pins = "usb_vbus_en2_pff1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pff2 {
+ nvidia,pins = "pff2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ core_pwr_req {
+ nvidia,pins = "core_pwr_req";
+ nvidia,function = "pwron";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ cpu_pwr_req {
+ nvidia,pins = "cpu_pwr_req";
+ nvidia,function = "cpu";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_int_n {
+ nvidia,pins = "pwr_int_n";
+ nvidia,function = "pmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ reset_out_n {
+ nvidia,pins = "reset_out_n";
+ nvidia,function = "reset_out_n";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ owr {
+ nvidia,pins = "owr";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
+ };
+ clk_32k_in {
+ nvidia,pins = "clk_32k_in";
+ nvidia,function = "clk";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ jtag_rtck {
+ nvidia,pins = "jtag_rtck";
+ nvidia,function = "rtck";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra124-nyan.dtsi b/arch/arm/boot/dts/tegra124-nyan.dtsi
new file mode 100644
index 000000000..a9aec23e0
--- /dev/null
+++ b/arch/arm/boot/dts/tegra124-nyan.dtsi
@@ -0,0 +1,695 @@
+#include <dt-bindings/input/input.h>
+#include "tegra124.dtsi"
+
+/ {
+ aliases {
+ rtc0 = "/i2c@0,7000d000/pmic@40";
+ rtc1 = "/rtc@0,7000e000";
+ serial0 = &uarta;
+ };
+
+ memory {
+ reg = <0x0 0x80000000 0x0 0x80000000>;
+ };
+
+ host1x@0,50000000 {
+ hdmi@0,54280000 {
+ status = "okay";
+
+ vdd-supply = <&vdd_3v3_hdmi>;
+ pll-supply = <&vdd_hdmi_pll>;
+ hdmi-supply = <&vdd_5v0_hdmi>;
+
+ nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio =
+ <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
+ };
+
+ sor@0,54540000 {
+ status = "okay";
+
+ nvidia,dpaux = <&dpaux>;
+ nvidia,panel = <&panel>;
+ };
+
+ dpaux@0,545c0000 {
+ vdd-supply = <&vdd_3v3_panel>;
+ status = "okay";
+ };
+ };
+
+ serial@0,70006000 {
+ /* Debug connector on the bottom of the board near SD card. */
+ status = "okay";
+ };
+
+ pwm@0,7000a000 {
+ status = "okay";
+ };
+
+ i2c@0,7000c000 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ acodec: audio-codec@10 {
+ compatible = "maxim,max98090";
+ reg = <0x10>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(H, 4) GPIO_ACTIVE_HIGH>;
+ };
+
+ temperature-sensor@4c {
+ compatible = "ti,tmp451";
+ reg = <0x4c>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(I, 6) IRQ_TYPE_LEVEL_LOW>;
+
+ #thermal-sensor-cells = <1>;
+ };
+ };
+
+ i2c@0,7000c400 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ trackpad@15 {
+ compatible = "elan,ekth3000";
+ reg = <0x15>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_EDGE_FALLING>;
+ wakeup-source;
+ };
+ };
+
+ i2c@0,7000c500 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ tpm@20 {
+ compatible = "infineon,slb9645tt";
+ reg = <0x20>;
+ };
+ };
+
+ hdmi_ddc: i2c@0,7000c700 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@0,7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ pmic: pmic@40 {
+ compatible = "ams,as3722";
+ reg = <0x40>;
+ interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
+
+ ams,system-power-controller;
+
+ #interrupt-cells = <2>;
+ interrupt-controller;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&as3722_default>;
+
+ as3722_default: pinmux {
+ gpio0 {
+ pins = "gpio0";
+ function = "gpio";
+ bias-pull-down;
+ };
+
+ gpio1 {
+ pins = "gpio1";
+ function = "gpio";
+ bias-pull-up;
+ };
+
+ gpio2_4_7 {
+ pins = "gpio2", "gpio4", "gpio7";
+ function = "gpio";
+ bias-pull-up;
+ };
+
+ gpio3_6 {
+ pins = "gpio3", "gpio6";
+ bias-high-impedance;
+ };
+
+ gpio5 {
+ pins = "gpio5";
+ function = "clk32k-out";
+ bias-pull-down;
+ };
+ };
+
+ regulators {
+ vsup-sd2-supply = <&vdd_5v0_sys>;
+ vsup-sd3-supply = <&vdd_5v0_sys>;
+ vsup-sd4-supply = <&vdd_5v0_sys>;
+ vsup-sd5-supply = <&vdd_5v0_sys>;
+ vin-ldo0-supply = <&vdd_1v35_lp0>;
+ vin-ldo1-6-supply = <&vdd_3v3_run>;
+ vin-ldo2-5-7-supply = <&vddio_1v8>;
+ vin-ldo3-4-supply = <&vdd_3v3_sys>;
+ vin-ldo9-10-supply = <&vdd_5v0_sys>;
+ vin-ldo11-supply = <&vdd_3v3_run>;
+
+ sd0 {
+ regulator-name = "+VDD_CPU_AP";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-min-microamp = <3500000>;
+ regulator-max-microamp = <3500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ams,ext-control = <2>;
+ };
+
+ sd1 {
+ regulator-name = "+VDD_CORE";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-min-microamp = <2500000>;
+ regulator-max-microamp = <4000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ams,ext-control = <1>;
+ };
+
+ vdd_1v35_lp0: sd2 {
+ regulator-name = "+1.35V_LP0(sd2)";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ sd3 {
+ regulator-name = "+1.35V_LP0(sd3)";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_1v05_run: sd4 {
+ regulator-name = "+1.05V_RUN";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ vddio_1v8: sd5 {
+ regulator-name = "+1.8V_VDDIO";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ sd6 {
+ regulator-name = "+VDD_GPU_AP";
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-min-microamp = <3500000>;
+ regulator-max-microamp = <3500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo0 {
+ regulator-name = "+1.05V_RUN_AVDD";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ams,ext-control = <1>;
+ };
+
+ ldo1 {
+ regulator-name = "+1.8V_RUN_CAM";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo2 {
+ regulator-name = "+1.2V_GEN_AVDD";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3 {
+ regulator-name = "+1.00V_LP0_VDD_RTC";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ams,enable-tracking;
+ };
+
+ vdd_run_cam: ldo4 {
+ regulator-name = "+3.3V_RUN_CAM";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo5 {
+ regulator-name = "+1.2V_RUN_CAM_FRONT";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vddio_sdmmc3: ldo6 {
+ regulator-name = "+VDDIO_SDMMC3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo7 {
+ regulator-name = "+1.05V_RUN_CAM_REAR";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ ldo9 {
+ regulator-name = "+2.8V_RUN_TOUCH";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo10 {
+ regulator-name = "+2.8V_RUN_CAM_AF";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo11 {
+ regulator-name = "+1.8V_RUN_VPP_FUSE";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+ };
+ };
+
+ spi@0,7000d400 {
+ status = "okay";
+
+ cros_ec: cros-ec@0 {
+ compatible = "google,cros-ec-spi";
+ spi-max-frequency = <3000000>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(C, 7) IRQ_TYPE_LEVEL_LOW>;
+ reg = <0>;
+
+ google,cros-ec-spi-msg-delay = <2000>;
+
+ i2c-tunnel {
+ compatible = "google,cros-ec-i2c-tunnel";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ google,remote-bus = <0>;
+
+ charger: bq24735@9 {
+ compatible = "ti,bq24735";
+ reg = <0x9>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(J, 0)
+ GPIO_ACTIVE_HIGH>;
+ ti,ac-detect-gpios = <&gpio
+ TEGRA_GPIO(J, 0)
+ GPIO_ACTIVE_HIGH>;
+ };
+
+ battery: sbs-battery@b {
+ compatible = "sbs,sbs-battery";
+ reg = <0xb>;
+ sbs,i2c-retry-count = <2>;
+ sbs,poll-retry-count = <10>;
+ power-supplies = <&charger>;
+ };
+ };
+ };
+ };
+
+ spi@0,7000da00 {
+ status = "okay";
+ spi-max-frequency = <25000000>;
+
+ flash@0 {
+ compatible = "winbond,w25q32dw";
+ spi-max-frequency = <25000000>;
+ reg = <0>;
+ };
+ };
+
+ pmc@0,7000e400 {
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <0>;
+ nvidia,cpu-pwr-good-time = <500>;
+ nvidia,cpu-pwr-off-time = <300>;
+ nvidia,core-pwr-good-time = <641 3845>;
+ nvidia,core-pwr-off-time = <61036>;
+ nvidia,core-power-req-active-high;
+ nvidia,sys-clock-req-active-high;
+ };
+
+ hda@0,70030000 {
+ status = "okay";
+ };
+
+ sdhci0_pwrseq: sdhci0_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+
+ reset-gpios = <&gpio TEGRA_GPIO(X, 7) GPIO_ACTIVE_LOW>;
+ };
+
+ sdhci@0,700b0000 { /* WiFi/BT on this bus */
+ status = "okay";
+ bus-width = <4>;
+ no-1-8-v;
+ non-removable;
+ mmc-pwrseq = <&sdhci0_pwrseq>;
+ vmmc-supply = <&vdd_3v3_lp0>;
+ vqmmc-supply = <&vddio_1v8>;
+ keep-power-in-suspend;
+ };
+
+ sdhci@0,700b0400 { /* SD Card on this bus */
+ status = "okay";
+ cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
+ power-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ no-1-8-v;
+ vqmmc-supply = <&vddio_sdmmc3>;
+ };
+
+ sdhci@0,700b0600 { /* eMMC on this bus */
+ status = "okay";
+ bus-width = <8>;
+ no-1-8-v;
+ non-removable;
+ };
+
+ ahub@0,70300000 {
+ i2s@0,70301100 {
+ status = "okay";
+ };
+ };
+
+ usb@0,7d000000 { /* Rear external USB port. */
+ status = "okay";
+ };
+
+ usb-phy@0,7d000000 {
+ status = "okay";
+ vbus-supply = <&vdd_usb1_vbus>;
+ };
+
+ usb@0,7d004000 { /* Internal webcam. */
+ status = "okay";
+ };
+
+ usb-phy@0,7d004000 {
+ status = "okay";
+ vbus-supply = <&vdd_run_cam>;
+ };
+
+ usb@0,7d008000 { /* Left external USB port. */
+ status = "okay";
+ };
+
+ usb-phy@0,7d008000 {
+ status = "okay";
+ vbus-supply = <&vdd_usb3_vbus>;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+
+ enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
+ power-supply = <&vdd_led>;
+ pwms = <&pwm 1 1000000>;
+
+ default-brightness-level = <224>;
+ brightness-levels =
+ < 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
+ 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47
+ 48 49 50 51 52 53 54 55
+ 56 57 58 59 60 61 62 63
+ 64 65 66 67 68 69 70 71
+ 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87
+ 88 89 90 91 92 93 94 95
+ 96 97 98 99 100 101 102 103
+ 104 105 106 107 108 109 110 111
+ 112 113 114 115 116 117 118 119
+ 120 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
+ 152 153 154 155 156 157 158 159
+ 160 161 162 163 164 165 166 167
+ 168 169 170 171 172 173 174 175
+ 176 177 178 179 180 181 182 183
+ 184 185 186 187 188 189 190 191
+ 192 193 194 195 196 197 198 199
+ 200 201 202 203 204 205 206 207
+ 208 209 210 211 212 213 214 215
+ 216 217 218 219 220 221 222 223
+ 224 225 226 227 228 229 230 231
+ 232 233 234 235 236 237 238 239
+ 240 241 242 243 244 245 246 247
+ 248 249 250 251 252 253 254 255
+ 256>;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ lid {
+ label = "Lid";
+ gpios = <&gpio TEGRA_GPIO(R, 4) GPIO_ACTIVE_LOW>;
+ linux,input-type = <5>;
+ linux,code = <KEY_RESERVED>;
+ debounce-interval = <1>;
+ gpio-key,wakeup;
+ };
+
+ power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ debounce-interval = <30>;
+ gpio-key,wakeup;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdd_mux: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "+VDD_MUX";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_5v0_sys: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "+5V_SYS";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vdd_mux>;
+ };
+
+ vdd_3v3_sys: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "+3.3V_SYS";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vdd_mux>;
+ };
+
+ vdd_3v3_run: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "+3.3V_RUN";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&pmic 1 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_sys>;
+ };
+
+ vdd_3v3_hdmi: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "+3.3V_AVDD_HDMI_AP_GATED";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vdd_3v3_run>;
+ };
+
+ vdd_led: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "+VDD_LED";
+ gpio = <&gpio TEGRA_GPIO(P, 2) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_mux>;
+ };
+
+ vdd_5v0_ts: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ regulator-name = "+5V_VDD_TS_SW";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ gpio = <&gpio TEGRA_GPIO(K, 1) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_5v0_sys>;
+ };
+
+ vdd_usb1_vbus: regulator@7 {
+ compatible = "regulator-fixed";
+ reg = <7>;
+ regulator-name = "+5V_USB_HS";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ gpio-open-drain;
+ vin-supply = <&vdd_5v0_sys>;
+ };
+
+ vdd_usb3_vbus: regulator@8 {
+ compatible = "regulator-fixed";
+ reg = <8>;
+ regulator-name = "+5V_USB_SS";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ gpio-open-drain;
+ vin-supply = <&vdd_5v0_sys>;
+ };
+
+ vdd_3v3_panel: regulator@9 {
+ compatible = "regulator-fixed";
+ reg = <9>;
+ regulator-name = "+3.3V_PANEL";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pmic 4 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_run>;
+ };
+
+ vdd_3v3_lp0: regulator@10 {
+ compatible = "regulator-fixed";
+ reg = <10>;
+ regulator-name = "+3.3V_LP0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ /*
+ * TODO: find a way to wire this up with the USB EHCI
+ * controllers so that it can be enabled on demand.
+ */
+ regulator-always-on;
+ gpio = <&pmic 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_sys>;
+ };
+
+ vdd_hdmi_pll: regulator@11 {
+ compatible = "regulator-fixed";
+ reg = <11>;
+ regulator-name = "+1.05V_RUN_AVDD_HDMI_PLL";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ gpio = <&gpio TEGRA_GPIO(H, 7) GPIO_ACTIVE_LOW>;
+ vin-supply = <&vdd_1v05_run>;
+ };
+
+ vdd_5v0_hdmi: regulator@12 {
+ compatible = "regulator-fixed";
+ reg = <12>;
+ regulator-name = "+5V_HDMI_CON";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(K, 6) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_5v0_sys>;
+ };
+ };
+
+ sound {
+ nvidia,audio-routing =
+ "Headphones", "HPR",
+ "Headphones", "HPL",
+ "Speakers", "SPKR",
+ "Speakers", "SPKL",
+ "Mic Jack", "MICBIAS",
+ "DMICL", "Int Mic",
+ "DMICR", "Int Mic",
+ "IN34", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&acodec>;
+
+ clocks = <&tegra_car TEGRA124_CLK_PLL_A>,
+ <&tegra_car TEGRA124_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA124_CLK_EXTERN1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+
+ nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(I, 7) GPIO_ACTIVE_HIGH>;
+ nvidia,mic-det-gpios =
+ <&gpio TEGRA_GPIO(R, 7) GPIO_ACTIVE_HIGH>;
+ };
+
+ gpio-restart {
+ compatible = "gpio-restart";
+ gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+ priority = <200>;
+ };
+};
+
+#include "cros-ec-keyboard.dtsi"
diff --git a/arch/arm/boot/dts/tegra124-venice2.dts b/arch/arm/boot/dts/tegra124-venice2.dts
new file mode 100644
index 000000000..5c3f78133
--- /dev/null
+++ b/arch/arm/boot/dts/tegra124-venice2.dts
@@ -0,0 +1,1156 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra124.dtsi"
+
+/ {
+ model = "NVIDIA Tegra124 Venice2";
+ compatible = "nvidia,venice2", "nvidia,tegra124";
+
+ aliases {
+ rtc0 = "/i2c@0,7000d000/pmic@40";
+ rtc1 = "/rtc@0,7000e000";
+ serial0 = &uarta;
+ };
+
+ memory {
+ reg = <0x0 0x80000000 0x0 0x80000000>;
+ };
+
+ host1x@0,50000000 {
+ hdmi@0,54280000 {
+ status = "okay";
+
+ vdd-supply = <&vdd_3v3_hdmi>;
+ pll-supply = <&vdd_hdmi_pll>;
+ hdmi-supply = <&vdd_5v0_hdmi>;
+
+ nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio =
+ <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
+ };
+
+ sor@0,54540000 {
+ status = "okay";
+
+ nvidia,dpaux = <&dpaux>;
+ nvidia,panel = <&panel>;
+ };
+
+ dpaux@0,545c0000 {
+ vdd-supply = <&vdd_3v3_panel>;
+ status = "okay";
+ };
+ };
+
+ pinmux: pinmux@0,70000868 {
+ pinctrl-names = "boot";
+ pinctrl-0 = <&pinmux_boot>;
+
+ pinmux_boot: common {
+ dap_mclk1_pw4 {
+ nvidia,pins = "dap_mclk1_pw4";
+ nvidia,function = "extperiph1";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_din_pn1 {
+ nvidia,pins = "dap1_din_pn1";
+ nvidia,function = "i2s0";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ dap1_dout_pn2 {
+ nvidia,pins = "dap1_dout_pn2",
+ "dap1_fs_pn0",
+ "dap1_sclk_pn3";
+ nvidia,function = "i2s0";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_din_pa4 {
+ nvidia,pins = "dap2_din_pa4";
+ nvidia,function = "i2s1";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_dout_pa5 {
+ nvidia,pins = "dap2_dout_pa5",
+ "dap2_fs_pa2",
+ "dap2_sclk_pa3";
+ nvidia,function = "i2s1";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ dvfs_pwm_px0 {
+ nvidia,pins = "dvfs_pwm_px0",
+ "dvfs_clk_px2";
+ nvidia,function = "cldvfs";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_clk_py0 {
+ nvidia,pins = "ulpi_clk_py0",
+ "ulpi_nxt_py2",
+ "ulpi_stp_py3";
+ nvidia,function = "spi1";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_dir_py1 {
+ nvidia,pins = "ulpi_dir_py1";
+ nvidia,function = "spi1";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ cam_i2c_scl_pbb1 {
+ nvidia,pins = "cam_i2c_scl_pbb1",
+ "cam_i2c_sda_pbb2";
+ nvidia,function = "i2c3";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ gen2_i2c_scl_pt5 {
+ nvidia,pins = "gen2_i2c_scl_pt5",
+ "gen2_i2c_sda_pt6";
+ nvidia,function = "i2c2";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ pg4 {
+ nvidia,pins = "pg4",
+ "pg5",
+ "pg6",
+ "pi3";
+ nvidia,function = "spi4";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ pg7 {
+ nvidia,pins = "pg7";
+ nvidia,function = "spi4";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ ph1 {
+ nvidia,pins = "ph1";
+ nvidia,function = "pwm1";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ pk0 {
+ nvidia,pins = "pk0",
+ "kb_row15_ps7",
+ "clk_32k_out_pa0";
+ nvidia,function = "soc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_clk_pz0 {
+ nvidia,pins = "sdmmc1_clk_pz0";
+ nvidia,function = "sdmmc1";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_cmd_pz1 {
+ nvidia,pins = "sdmmc1_cmd_pz1",
+ "sdmmc1_dat0_py7",
+ "sdmmc1_dat1_py6",
+ "sdmmc1_dat2_py5",
+ "sdmmc1_dat3_py4";
+ nvidia,function = "sdmmc1";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_clk_pa6 {
+ nvidia,pins = "sdmmc3_clk_pa6";
+ nvidia,function = "sdmmc3";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_cmd_pa7 {
+ nvidia,pins = "sdmmc3_cmd_pa7",
+ "sdmmc3_dat0_pb7",
+ "sdmmc3_dat1_pb6",
+ "sdmmc3_dat2_pb5",
+ "sdmmc3_dat3_pb4",
+ "sdmmc3_clk_lb_out_pee4",
+ "sdmmc3_clk_lb_in_pee5";
+ nvidia,function = "sdmmc3";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc4_clk_pcc4 {
+ nvidia,pins = "sdmmc4_clk_pcc4";
+ nvidia,function = "sdmmc4";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc4_cmd_pt7 {
+ nvidia,pins = "sdmmc4_cmd_pt7",
+ "sdmmc4_dat0_paa0",
+ "sdmmc4_dat1_paa1",
+ "sdmmc4_dat2_paa2",
+ "sdmmc4_dat3_paa3",
+ "sdmmc4_dat4_paa4",
+ "sdmmc4_dat5_paa5",
+ "sdmmc4_dat6_paa6",
+ "sdmmc4_dat7_paa7";
+ nvidia,function = "sdmmc4";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_i2c_scl_pz6 {
+ nvidia,pins = "pwr_i2c_scl_pz6",
+ "pwr_i2c_sda_pz7";
+ nvidia,function = "i2cpwr";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ jtag_rtck {
+ nvidia,pins = "jtag_rtck";
+ nvidia,function = "rtck";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ clk_32k_in {
+ nvidia,pins = "clk_32k_in";
+ nvidia,function = "clk";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ core_pwr_req {
+ nvidia,pins = "core_pwr_req";
+ nvidia,function = "pwron";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ cpu_pwr_req {
+ nvidia,pins = "cpu_pwr_req";
+ nvidia,function = "cpu";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_int_n {
+ nvidia,pins = "pwr_int_n";
+ nvidia,function = "pmi";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ reset_out_n {
+ nvidia,pins = "reset_out_n";
+ nvidia,function = "reset_out_n";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ clk3_out_pee0 {
+ nvidia,pins = "clk3_out_pee0";
+ nvidia,function = "extperiph3";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_din_pp5 {
+ nvidia,pins = "dap4_din_pp5";
+ nvidia,function = "i2s3";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ dap4_dout_pp6 {
+ nvidia,pins = "dap4_dout_pp6",
+ "dap4_fs_pp4",
+ "dap4_sclk_pp7";
+ nvidia,function = "i2s3";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ gen1_i2c_sda_pc5 {
+ nvidia,pins = "gen1_i2c_sda_pc5",
+ "gen1_i2c_scl_pc4";
+ nvidia,function = "i2c1";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ uart2_cts_n_pj5 {
+ nvidia,pins = "uart2_cts_n_pj5";
+ nvidia,function = "uartb";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rts_n_pj6 {
+ nvidia,pins = "uart2_rts_n_pj6";
+ nvidia,function = "uartb";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rxd_pc3 {
+ nvidia,pins = "uart2_rxd_pc3";
+ nvidia,function = "irda";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_txd_pc2 {
+ nvidia,pins = "uart2_txd_pc2";
+ nvidia,function = "irda";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_cts_n_pa1 {
+ nvidia,pins = "uart3_cts_n_pa1",
+ "uart3_rxd_pw7";
+ nvidia,function = "uartc";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_rts_n_pc0 {
+ nvidia,pins = "uart3_rts_n_pc0",
+ "uart3_txd_pw6";
+ nvidia,function = "uartc";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ hdmi_cec_pee3 {
+ nvidia,pins = "hdmi_cec_pee3";
+ nvidia,function = "cec";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ hdmi_int_pn7 {
+ nvidia,pins = "hdmi_int_pn7";
+ nvidia,function = "rsvd1";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ ddc_scl_pv4 {
+ nvidia,pins = "ddc_scl_pv4",
+ "ddc_sda_pv5";
+ nvidia,function = "i2c4";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_ENABLE>;
+ };
+ pj7 {
+ nvidia,pins = "pj7",
+ "pk7";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pb0 {
+ nvidia,pins = "pb0",
+ "pb1";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ph0 {
+ nvidia,pins = "ph0";
+ nvidia,function = "pwm0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row10_ps2 {
+ nvidia,pins = "kb_row10_ps2";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row9_ps1 {
+ nvidia,pins = "kb_row9_ps1";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row6_pr6 {
+ nvidia,pins = "kb_row6_pr6";
+ nvidia,function = "displaya_alt";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ usb_vbus_en0_pn4 {
+ nvidia,pins = "usb_vbus_en0_pn4",
+ "usb_vbus_en1_pn5";
+ nvidia,function = "usb";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ drive_sdio1 {
+ nvidia,pins = "drive_sdio1";
+ nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,pull-down-strength = <32>;
+ nvidia,pull-up-strength = <42>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ };
+ drive_sdio3 {
+ nvidia,pins = "drive_sdio3";
+ nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,pull-down-strength = <20>;
+ nvidia,pull-up-strength = <36>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ };
+ drive_gma {
+ nvidia,pins = "drive_gma";
+ nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
+ nvidia,pull-down-strength = <1>;
+ nvidia,pull-up-strength = <2>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,drive-type = <1>;
+ };
+ als_irq_l {
+ nvidia,pins = "gpio_x3_aud_px3";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ codec_irq_l {
+ nvidia,pins = "ph4";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_bl_en {
+ nvidia,pins = "ph2";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ touch_irq_l {
+ nvidia,pins = "gpio_w3_aud_pw3";
+ nvidia,function = "spi6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ tpm_davint_l {
+ nvidia,pins = "ph6";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ts_irq_l {
+ nvidia,pins = "pk2";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ts_reset_l {
+ nvidia,pins = "pk4";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ts_shdn_l {
+ nvidia,pins = "pk1";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ph7 {
+ nvidia,pins = "ph7";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col0_ap {
+ nvidia,pins = "kb_col0_pq0";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lid_open {
+ nvidia,pins = "kb_row4_pr4";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ en_vdd_sd {
+ nvidia,pins = "kb_row0_pr0";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ac_ok {
+ nvidia,pins = "pj0";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sensor_irq_l {
+ nvidia,pins = "pi6";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ wifi_en {
+ nvidia,pins = "gpio_x7_aud_px7";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ wifi_rst_l {
+ nvidia,pins = "clk2_req_pcc5";
+ nvidia,function = "dap";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ hp_det_l {
+ nvidia,pins = "ulpi_data1_po2";
+ nvidia,function = "spi3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ };
+ };
+
+ serial@0,70006000 {
+ status = "okay";
+ };
+
+ pwm@0,7000a000 {
+ status = "okay";
+ };
+
+ i2c@0,7000c000 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ acodec: audio-codec@10 {
+ compatible = "maxim,max98090";
+ reg = <0x10>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(H, 4) GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ i2c@0,7000c400 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ trackpad@4b {
+ compatible = "atmel,maxtouch";
+ reg = <0x4b>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_LEVEL_LOW>;
+ linux,gpio-keymap = <0 0 0 BTN_LEFT>;
+ };
+ };
+
+ i2c@0,7000c500 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ hdmi_ddc: i2c@0,7000c700 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@0,7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ pmic: pmic@40 {
+ compatible = "ams,as3722";
+ reg = <0x40>;
+ interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
+
+ ams,system-power-controller;
+
+ #interrupt-cells = <2>;
+ interrupt-controller;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&as3722_default>;
+
+ as3722_default: pinmux {
+ gpio0 {
+ pins = "gpio0";
+ function = "gpio";
+ bias-pull-down;
+ };
+
+ gpio1_2_4_7 {
+ pins = "gpio1", "gpio2", "gpio4", "gpio7";
+ function = "gpio";
+ bias-pull-up;
+ };
+
+ gpio3_6 {
+ pins = "gpio3", "gpio6";
+ bias-high-impedance;
+ };
+
+ gpio5 {
+ pins = "gpio5";
+ function = "clk32k-out";
+ };
+ };
+
+ regulators {
+ vsup-sd2-supply = <&vdd_5v0_sys>;
+ vsup-sd3-supply = <&vdd_5v0_sys>;
+ vsup-sd4-supply = <&vdd_5v0_sys>;
+ vsup-sd5-supply = <&vdd_5v0_sys>;
+ vin-ldo0-supply = <&vdd_1v35_lp0>;
+ vin-ldo1-6-supply = <&vdd_3v3_run>;
+ vin-ldo2-5-7-supply = <&vddio_1v8>;
+ vin-ldo3-4-supply = <&vdd_3v3_sys>;
+ vin-ldo9-10-supply = <&vdd_5v0_sys>;
+ vin-ldo11-supply = <&vdd_3v3_run>;
+
+ sd0 {
+ regulator-name = "+VDD_CPU_AP";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-min-microamp = <3500000>;
+ regulator-max-microamp = <3500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ams,ext-control = <2>;
+ };
+
+ sd1 {
+ regulator-name = "+VDD_CORE";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-min-microamp = <2500000>;
+ regulator-max-microamp = <2500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ams,ext-control = <1>;
+ };
+
+ vdd_1v35_lp0: sd2 {
+ regulator-name = "+1.35V_LP0(sd2)";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ sd3 {
+ regulator-name = "+1.35V_LP0(sd3)";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_1v05_run: sd4 {
+ regulator-name = "+1.05V_RUN";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ vddio_1v8: sd5 {
+ regulator-name = "+1.8V_VDDIO";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sd6 {
+ regulator-name = "+VDD_GPU_AP";
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-min-microamp = <3500000>;
+ regulator-max-microamp = <3500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo0 {
+ regulator-name = "+1.05V_RUN_AVDD";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ams,ext-control = <1>;
+ };
+
+ ldo1 {
+ regulator-name = "+1.8V_RUN_CAM";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo2 {
+ regulator-name = "+1.2V_GEN_AVDD";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3 {
+ regulator-name = "+1.00V_LP0_VDD_RTC";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ams,enable-tracking;
+ };
+
+ vdd_run_cam: ldo4 {
+ regulator-name = "+3.3V_RUN_CAM";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo5 {
+ regulator-name = "+1.2V_RUN_CAM_FRONT";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vddio_sdmmc3: ldo6 {
+ regulator-name = "+VDDIO_SDMMC3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo7 {
+ regulator-name = "+1.05V_RUN_CAM_REAR";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ ldo9 {
+ regulator-name = "+2.8V_RUN_TOUCH";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo10 {
+ regulator-name = "+2.8V_RUN_CAM_AF";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo11 {
+ regulator-name = "+1.8V_RUN_VPP_FUSE";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+ };
+ };
+
+ spi@0,7000d400 {
+ status = "okay";
+
+ cros_ec: cros-ec@0 {
+ compatible = "google,cros-ec-spi";
+ spi-max-frequency = <4000000>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(C, 7) IRQ_TYPE_LEVEL_LOW>;
+ reg = <0>;
+
+ google,cros-ec-spi-msg-delay = <2000>;
+
+ i2c-tunnel {
+ compatible = "google,cros-ec-i2c-tunnel";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ google,remote-bus = <0>;
+
+ charger: bq24735@9 {
+ compatible = "ti,bq24735";
+ reg = <0x9>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(J, 0)
+ GPIO_ACTIVE_HIGH>;
+ ti,ac-detect-gpios = <&gpio
+ TEGRA_GPIO(J, 0)
+ GPIO_ACTIVE_HIGH>;
+ };
+
+ battery: sbs-battery@b {
+ compatible = "sbs,sbs-battery";
+ reg = <0xb>;
+ sbs,i2c-retry-count = <2>;
+ sbs,poll-retry-count = <1>;
+ };
+ };
+ };
+ };
+
+ spi@0,7000da00 {
+ status = "okay";
+ spi-max-frequency = <25000000>;
+ spi-flash@0 {
+ compatible = "winbond,w25q32dw";
+ reg = <0>;
+ spi-max-frequency = <20000000>;
+ };
+ };
+
+ pmc@0,7000e400 {
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <1>;
+ nvidia,cpu-pwr-good-time = <500>;
+ nvidia,cpu-pwr-off-time = <300>;
+ nvidia,core-pwr-good-time = <641 3845>;
+ nvidia,core-pwr-off-time = <61036>;
+ nvidia,core-power-req-active-high;
+ nvidia,sys-clock-req-active-high;
+ };
+
+ hda@0,70030000 {
+ status = "okay";
+ };
+
+ sdhci@0,700b0400 {
+ cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
+ power-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_HIGH>;
+ wp-gpios = <&gpio TEGRA_GPIO(Q, 4) GPIO_ACTIVE_LOW>;
+ status = "okay";
+ bus-width = <4>;
+ vqmmc-supply = <&vddio_sdmmc3>;
+ };
+
+ sdhci@0,700b0600 {
+ status = "okay";
+ bus-width = <8>;
+ };
+
+ ahub@0,70300000 {
+ i2s@0,70301100 {
+ status = "okay";
+ };
+ };
+
+ usb@0,7d000000 {
+ status = "okay";
+ };
+
+ usb-phy@0,7d000000 {
+ status = "okay";
+ vbus-supply = <&vdd_usb1_vbus>;
+ };
+
+ usb@0,7d004000 {
+ status = "okay";
+ };
+
+ usb-phy@0,7d004000 {
+ status = "okay";
+ vbus-supply = <&vdd_run_cam>;
+ };
+
+ usb@0,7d008000 {
+ status = "okay";
+ };
+
+ usb-phy@0,7d008000 {
+ status = "okay";
+ vbus-supply = <&vdd_usb3_vbus>;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+
+ enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
+ power-supply = <&vdd_led>;
+ pwms = <&pwm 1 1000000>;
+
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ panel: panel {
+ compatible = "lg,lp129qe", "simple-panel";
+
+ backlight = <&backlight>;
+ ddc-i2c-bus = <&dpaux>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdd_mux: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "+VDD_MUX";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_5v0_sys: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "+5V_SYS";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vdd_mux>;
+ };
+
+ vdd_3v3_sys: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "+3.3V_SYS";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vdd_mux>;
+ };
+
+ vdd_3v3_run: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "+3.3V_RUN";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&pmic 1 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_sys>;
+ };
+
+ vdd_3v3_hdmi: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "+3.3V_AVDD_HDMI_AP_GATED";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vdd_3v3_run>;
+ };
+
+ vdd_led: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "+VDD_LED";
+ gpio = <&gpio TEGRA_GPIO(P, 2) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_mux>;
+ };
+
+ vdd_5v0_ts: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ regulator-name = "+5V_VDD_TS_SW";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ gpio = <&gpio TEGRA_GPIO(K, 1) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_5v0_sys>;
+ };
+
+ vdd_usb1_vbus: regulator@7 {
+ compatible = "regulator-fixed";
+ reg = <7>;
+ regulator-name = "+5V_USB_HS";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ gpio-open-drain;
+ vin-supply = <&vdd_5v0_sys>;
+ };
+
+ vdd_usb3_vbus: regulator@8 {
+ compatible = "regulator-fixed";
+ reg = <8>;
+ regulator-name = "+5V_USB_SS";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ gpio-open-drain;
+ vin-supply = <&vdd_5v0_sys>;
+ };
+
+ vdd_3v3_panel: regulator@9 {
+ compatible = "regulator-fixed";
+ reg = <9>;
+ regulator-name = "+3.3V_PANEL";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pmic 4 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_run>;
+ };
+
+ vdd_3v3_lp0: regulator@10 {
+ compatible = "regulator-fixed";
+ reg = <10>;
+ regulator-name = "+3.3V_LP0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ /*
+ * TODO: find a way to wire this up with the USB EHCI
+ * controllers so that it can be enabled on demand.
+ */
+ regulator-always-on;
+ gpio = <&pmic 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_sys>;
+ };
+
+ vdd_hdmi_pll: regulator@11 {
+ compatible = "regulator-fixed";
+ reg = <11>;
+ regulator-name = "+1.05V_RUN_AVDD_HDMI_PLL";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ gpio = <&gpio TEGRA_GPIO(H, 7) GPIO_ACTIVE_LOW>;
+ vin-supply = <&vdd_1v05_run>;
+ };
+
+ vdd_5v0_hdmi: regulator@12 {
+ compatible = "regulator-fixed";
+ reg = <12>;
+ regulator-name = "+5V_HDMI_CON";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(K, 6) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_5v0_sys>;
+ };
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-max98090-venice2",
+ "nvidia,tegra-audio-max98090";
+ nvidia,model = "NVIDIA Tegra Venice2";
+
+ nvidia,audio-routing =
+ "Headphones", "HPR",
+ "Headphones", "HPL",
+ "Speakers", "SPKR",
+ "Speakers", "SPKL",
+ "Mic Jack", "MICBIAS",
+ "IN34", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&acodec>;
+
+ clocks = <&tegra_car TEGRA124_CLK_PLL_A>,
+ <&tegra_car TEGRA124_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA124_CLK_EXTERN1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
+};
+
+#include "cros-ec-keyboard.dtsi"
diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
new file mode 100644
index 000000000..13cc7ca5e
--- /dev/null
+++ b/arch/arm/boot/dts/tegra124.dtsi
@@ -0,0 +1,992 @@
+#include <dt-bindings/clock/tegra124-car.h>
+#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/memory/tegra124-mc.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/tegra124-soctherm.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "nvidia,tegra124";
+ interrupt-parent = <&lic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ pcie-controller@0,01003000 {
+ compatible = "nvidia,tegra124-pcie";
+ device_type = "pci";
+ reg = <0x0 0x01003000 0x0 0x00000800 /* PADS registers */
+ 0x0 0x01003800 0x0 0x00000800 /* AFI registers */
+ 0x0 0x02000000 0x0 0x10000000>; /* configuration space */
+ reg-names = "pads", "afi", "cs";
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */
+ <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
+ interrupt-names = "intr", "msi";
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+
+ bus-range = <0x00 0xff>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ ranges = <0x82000000 0 0x01000000 0x0 0x01000000 0 0x00001000 /* port 0 configuration space */
+ 0x82000000 0 0x01001000 0x0 0x01001000 0 0x00001000 /* port 1 configuration space */
+ 0x81000000 0 0x0 0x0 0x12000000 0 0x00010000 /* downstream I/O (64 KiB) */
+ 0x82000000 0 0x13000000 0x0 0x13000000 0 0x0d000000 /* non-prefetchable memory (208 MiB) */
+ 0xc2000000 0 0x20000000 0x0 0x20000000 0 0x20000000>; /* prefetchable memory (512 MiB) */
+
+ clocks = <&tegra_car TEGRA124_CLK_PCIE>,
+ <&tegra_car TEGRA124_CLK_AFI>,
+ <&tegra_car TEGRA124_CLK_PLL_E>,
+ <&tegra_car TEGRA124_CLK_CML0>;
+ clock-names = "pex", "afi", "pll_e", "cml";
+ resets = <&tegra_car 70>,
+ <&tegra_car 72>,
+ <&tegra_car 74>;
+ reset-names = "pex", "afi", "pcie_x";
+ status = "disabled";
+
+ phys = <&padctl TEGRA_XUSB_PADCTL_PCIE>;
+ phy-names = "pcie";
+
+ pci@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x01000000 0 0x1000>;
+ reg = <0x000800 0 0 0 0>;
+ status = "disabled";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ nvidia,num-lanes = <2>;
+ };
+
+ pci@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82001000 0 0x01001000 0 0x1000>;
+ reg = <0x001000 0 0 0 0>;
+ status = "disabled";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ nvidia,num-lanes = <1>;
+ };
+ };
+
+ host1x@0,50000000 {
+ compatible = "nvidia,tegra124-host1x", "simple-bus";
+ reg = <0x0 0x50000000 0x0 0x00034000>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, /* syncpt */
+ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; /* general */
+ clocks = <&tegra_car TEGRA124_CLK_HOST1X>;
+ resets = <&tegra_car 28>;
+ reset-names = "host1x";
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ ranges = <0 0x54000000 0 0x54000000 0 0x01000000>;
+
+ dc@0,54200000 {
+ compatible = "nvidia,tegra124-dc";
+ reg = <0x0 0x54200000 0x0 0x00040000>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_DISP1>,
+ <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "dc", "parent";
+ resets = <&tegra_car 27>;
+ reset-names = "dc";
+
+ iommus = <&mc TEGRA_SWGROUP_DC>;
+
+ nvidia,head = <0>;
+ };
+
+ dc@0,54240000 {
+ compatible = "nvidia,tegra124-dc";
+ reg = <0x0 0x54240000 0x0 0x00040000>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_DISP2>,
+ <&tegra_car TEGRA124_CLK_PLL_P>;
+ clock-names = "dc", "parent";
+ resets = <&tegra_car 26>;
+ reset-names = "dc";
+
+ iommus = <&mc TEGRA_SWGROUP_DCB>;
+
+ nvidia,head = <1>;
+ };
+
+ hdmi@0,54280000 {
+ compatible = "nvidia,tegra124-hdmi";
+ reg = <0x0 0x54280000 0x0 0x00040000>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_HDMI>,
+ <&tegra_car TEGRA124_CLK_PLL_D2_OUT0>;
+ clock-names = "hdmi", "parent";
+ resets = <&tegra_car 51>;
+ reset-names = "hdmi";
+ status = "disabled";
+ };
+
+ sor@0,54540000 {
+ compatible = "nvidia,tegra124-sor";
+ reg = <0x0 0x54540000 0x0 0x00040000>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_SOR0>,
+ <&tegra_car TEGRA124_CLK_PLL_D_OUT0>,
+ <&tegra_car TEGRA124_CLK_PLL_DP>,
+ <&tegra_car TEGRA124_CLK_CLK_M>;
+ clock-names = "sor", "parent", "dp", "safe";
+ resets = <&tegra_car 182>;
+ reset-names = "sor";
+ status = "disabled";
+ };
+
+ dpaux: dpaux@0,545c0000 {
+ compatible = "nvidia,tegra124-dpaux";
+ reg = <0x0 0x545c0000 0x0 0x00040000>;
+ interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_DPAUX>,
+ <&tegra_car TEGRA124_CLK_PLL_DP>;
+ clock-names = "dpaux", "parent";
+ resets = <&tegra_car 181>;
+ reset-names = "dpaux";
+ status = "disabled";
+ };
+ };
+
+ gic: interrupt-controller@0,50041000 {
+ compatible = "arm,cortex-a15-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x0 0x50041000 0x0 0x1000>,
+ <0x0 0x50042000 0x0 0x1000>,
+ <0x0 0x50044000 0x0 0x2000>,
+ <0x0 0x50046000 0x0 0x2000>;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-parent = <&gic>;
+ };
+
+ gpu@0,57000000 {
+ compatible = "nvidia,gk20a";
+ reg = <0x0 0x57000000 0x0 0x01000000>,
+ <0x0 0x58000000 0x0 0x01000000>;
+ interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "stall", "nonstall";
+ clocks = <&tegra_car TEGRA124_CLK_GPU>,
+ <&tegra_car TEGRA124_CLK_PLL_P_OUT5>;
+ clock-names = "gpu", "pwr";
+ resets = <&tegra_car 184>;
+ reset-names = "gpu";
+ status = "disabled";
+ };
+
+ lic: interrupt-controller@60004000 {
+ compatible = "nvidia,tegra124-ictlr", "nvidia,tegra30-ictlr";
+ reg = <0x0 0x60004000 0x0 0x100>,
+ <0x0 0x60004100 0x0 0x100>,
+ <0x0 0x60004200 0x0 0x100>,
+ <0x0 0x60004300 0x0 0x100>,
+ <0x0 0x60004400 0x0 0x100>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ };
+
+ timer@0,60005000 {
+ compatible = "nvidia,tegra124-timer", "nvidia,tegra20-timer";
+ reg = <0x0 0x60005000 0x0 0x400>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_TIMER>;
+ };
+
+ tegra_car: clock@0,60006000 {
+ compatible = "nvidia,tegra124-car";
+ reg = <0x0 0x60006000 0x0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ nvidia,external-memory-controller = <&emc>;
+ };
+
+ flow-controller@0,60007000 {
+ compatible = "nvidia,tegra124-flowctrl";
+ reg = <0x0 0x60007000 0x0 0x1000>;
+ };
+
+ actmon@0,6000c800 {
+ compatible = "nvidia,tegra124-actmon";
+ reg = <0x0 0x6000c800 0x0 0x400>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_ACTMON>,
+ <&tegra_car TEGRA124_CLK_EMC>;
+ clock-names = "actmon", "emc";
+ resets = <&tegra_car 119>;
+ reset-names = "actmon";
+ };
+
+ gpio: gpio@0,6000d000 {
+ compatible = "nvidia,tegra124-gpio", "nvidia,tegra30-gpio";
+ reg = <0x0 0x6000d000 0x0 0x1000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ apbdma: dma@0,60020000 {
+ compatible = "nvidia,tegra124-apbdma", "nvidia,tegra148-apbdma";
+ reg = <0x0 0x60020000 0x0 0x1400>;
+ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_APBDMA>;
+ resets = <&tegra_car 34>;
+ reset-names = "dma";
+ #dma-cells = <1>;
+ };
+
+ apbmisc@0,70000800 {
+ compatible = "nvidia,tegra124-apbmisc", "nvidia,tegra20-apbmisc";
+ reg = <0x0 0x70000800 0x0 0x64>, /* Chip revision */
+ <0x0 0x7000E864 0x0 0x04>; /* Strapping options */
+ };
+
+ pinmux: pinmux@0,70000868 {
+ compatible = "nvidia,tegra124-pinmux";
+ reg = <0x0 0x70000868 0x0 0x164>, /* Pad control registers */
+ <0x0 0x70003000 0x0 0x434>, /* Mux registers */
+ <0x0 0x70000820 0x0 0x008>; /* MIPI pad control */
+ };
+
+ /*
+ * There are two serial driver i.e. 8250 based simple serial
+ * driver and APB DMA based serial driver for higher baudrate
+ * and performace. To enable the 8250 based driver, the compatible
+ * is "nvidia,tegra124-uart", "nvidia,tegra20-uart" and to enable
+ * the APB DMA based serial driver, the comptible is
+ * "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart".
+ */
+ uarta: serial@0,70006000 {
+ compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x70006000 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_UARTA>;
+ resets = <&tegra_car 6>;
+ reset-names = "serial";
+ dmas = <&apbdma 8>, <&apbdma 8>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uartb: serial@0,70006040 {
+ compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x70006040 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_UARTB>;
+ resets = <&tegra_car 7>;
+ reset-names = "serial";
+ dmas = <&apbdma 9>, <&apbdma 9>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uartc: serial@0,70006200 {
+ compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x70006200 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_UARTC>;
+ resets = <&tegra_car 55>;
+ reset-names = "serial";
+ dmas = <&apbdma 10>, <&apbdma 10>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uartd: serial@0,70006300 {
+ compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x70006300 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_UARTD>;
+ resets = <&tegra_car 65>;
+ reset-names = "serial";
+ dmas = <&apbdma 19>, <&apbdma 19>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ pwm: pwm@0,7000a000 {
+ compatible = "nvidia,tegra124-pwm", "nvidia,tegra20-pwm";
+ reg = <0x0 0x7000a000 0x0 0x100>;
+ #pwm-cells = <2>;
+ clocks = <&tegra_car TEGRA124_CLK_PWM>;
+ resets = <&tegra_car 17>;
+ reset-names = "pwm";
+ status = "disabled";
+ };
+
+ i2c@0,7000c000 {
+ compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x7000c000 0x0 0x100>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_I2C1>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 12>;
+ reset-names = "i2c";
+ dmas = <&apbdma 21>, <&apbdma 21>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@0,7000c400 {
+ compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x7000c400 0x0 0x100>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_I2C2>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 54>;
+ reset-names = "i2c";
+ dmas = <&apbdma 22>, <&apbdma 22>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@0,7000c500 {
+ compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x7000c500 0x0 0x100>;
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_I2C3>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 67>;
+ reset-names = "i2c";
+ dmas = <&apbdma 23>, <&apbdma 23>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@0,7000c700 {
+ compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x7000c700 0x0 0x100>;
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_I2C4>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 103>;
+ reset-names = "i2c";
+ dmas = <&apbdma 26>, <&apbdma 26>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@0,7000d000 {
+ compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x7000d000 0x0 0x100>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_I2C5>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 47>;
+ reset-names = "i2c";
+ dmas = <&apbdma 24>, <&apbdma 24>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@0,7000d100 {
+ compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x7000d100 0x0 0x100>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_I2C6>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 166>;
+ reset-names = "i2c";
+ dmas = <&apbdma 30>, <&apbdma 30>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@0,7000d400 {
+ compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+ reg = <0x0 0x7000d400 0x0 0x200>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_SBC1>;
+ clock-names = "spi";
+ resets = <&tegra_car 41>;
+ reset-names = "spi";
+ dmas = <&apbdma 15>, <&apbdma 15>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@0,7000d600 {
+ compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+ reg = <0x0 0x7000d600 0x0 0x200>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_SBC2>;
+ clock-names = "spi";
+ resets = <&tegra_car 44>;
+ reset-names = "spi";
+ dmas = <&apbdma 16>, <&apbdma 16>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@0,7000d800 {
+ compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+ reg = <0x0 0x7000d800 0x0 0x200>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_SBC3>;
+ clock-names = "spi";
+ resets = <&tegra_car 46>;
+ reset-names = "spi";
+ dmas = <&apbdma 17>, <&apbdma 17>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@0,7000da00 {
+ compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+ reg = <0x0 0x7000da00 0x0 0x200>;
+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_SBC4>;
+ clock-names = "spi";
+ resets = <&tegra_car 68>;
+ reset-names = "spi";
+ dmas = <&apbdma 18>, <&apbdma 18>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@0,7000dc00 {
+ compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+ reg = <0x0 0x7000dc00 0x0 0x200>;
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_SBC5>;
+ clock-names = "spi";
+ resets = <&tegra_car 104>;
+ reset-names = "spi";
+ dmas = <&apbdma 27>, <&apbdma 27>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@0,7000de00 {
+ compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+ reg = <0x0 0x7000de00 0x0 0x200>;
+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_SBC6>;
+ clock-names = "spi";
+ resets = <&tegra_car 105>;
+ reset-names = "spi";
+ dmas = <&apbdma 28>, <&apbdma 28>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ rtc@0,7000e000 {
+ compatible = "nvidia,tegra124-rtc", "nvidia,tegra20-rtc";
+ reg = <0x0 0x7000e000 0x0 0x100>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_RTC>;
+ };
+
+ pmc@0,7000e400 {
+ compatible = "nvidia,tegra124-pmc";
+ reg = <0x0 0x7000e400 0x0 0x400>;
+ clocks = <&tegra_car TEGRA124_CLK_PCLK>, <&clk32k_in>;
+ clock-names = "pclk", "clk32k_in";
+ };
+
+ fuse@0,7000f800 {
+ compatible = "nvidia,tegra124-efuse";
+ reg = <0x0 0x7000f800 0x0 0x400>;
+ clocks = <&tegra_car TEGRA124_CLK_FUSE>;
+ clock-names = "fuse";
+ resets = <&tegra_car 39>;
+ reset-names = "fuse";
+ };
+
+ mc: memory-controller@0,70019000 {
+ compatible = "nvidia,tegra124-mc";
+ reg = <0x0 0x70019000 0x0 0x1000>;
+ clocks = <&tegra_car TEGRA124_CLK_MC>;
+ clock-names = "mc";
+
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+
+ #iommu-cells = <1>;
+ };
+
+ emc: emc@0,7001b000 {
+ compatible = "nvidia,tegra124-emc";
+ reg = <0x0 0x7001b000 0x0 0x1000>;
+
+ nvidia,memory-controller = <&mc>;
+ };
+
+ sata@0,70020000 {
+ compatible = "nvidia,tegra124-ahci";
+
+ reg = <0x0 0x70027000 0x0 0x2000>, /* AHCI */
+ <0x0 0x70020000 0x0 0x7000>; /* SATA */
+
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&tegra_car TEGRA124_CLK_SATA>,
+ <&tegra_car TEGRA124_CLK_SATA_OOB>,
+ <&tegra_car TEGRA124_CLK_CML1>,
+ <&tegra_car TEGRA124_CLK_PLL_E>;
+ clock-names = "sata", "sata-oob", "cml1", "pll_e";
+
+ resets = <&tegra_car 124>,
+ <&tegra_car 123>,
+ <&tegra_car 129>;
+ reset-names = "sata", "sata-oob", "sata-cold";
+
+ phys = <&padctl TEGRA_XUSB_PADCTL_SATA>;
+ phy-names = "sata-phy";
+
+ status = "disabled";
+ };
+
+ hda@0,70030000 {
+ compatible = "nvidia,tegra124-hda", "nvidia,tegra30-hda";
+ reg = <0x0 0x70030000 0x0 0x10000>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_HDA>,
+ <&tegra_car TEGRA124_CLK_HDA2HDMI>,
+ <&tegra_car TEGRA124_CLK_HDA2CODEC_2X>;
+ clock-names = "hda", "hda2hdmi", "hdacodec_2x";
+ resets = <&tegra_car 125>, /* hda */
+ <&tegra_car 128>, /* hda2hdmi */
+ <&tegra_car 111>; /* hda2codec_2x */
+ reset-names = "hda", "hda2hdmi", "hdacodec_2x";
+ status = "disabled";
+ };
+
+ padctl: padctl@0,7009f000 {
+ compatible = "nvidia,tegra124-xusb-padctl";
+ reg = <0x0 0x7009f000 0x0 0x1000>;
+ resets = <&tegra_car 142>;
+ reset-names = "padctl";
+
+ #phy-cells = <1>;
+ };
+
+ sdhci@0,700b0000 {
+ compatible = "nvidia,tegra124-sdhci";
+ reg = <0x0 0x700b0000 0x0 0x200>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_SDMMC1>;
+ resets = <&tegra_car 14>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@0,700b0200 {
+ compatible = "nvidia,tegra124-sdhci";
+ reg = <0x0 0x700b0200 0x0 0x200>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_SDMMC2>;
+ resets = <&tegra_car 9>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@0,700b0400 {
+ compatible = "nvidia,tegra124-sdhci";
+ reg = <0x0 0x700b0400 0x0 0x200>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_SDMMC3>;
+ resets = <&tegra_car 69>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@0,700b0600 {
+ compatible = "nvidia,tegra124-sdhci";
+ reg = <0x0 0x700b0600 0x0 0x200>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_SDMMC4>;
+ resets = <&tegra_car 15>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ soctherm: thermal-sensor@0,700e2000 {
+ compatible = "nvidia,tegra124-soctherm";
+ reg = <0x0 0x700e2000 0x0 0x1000>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_TSENSOR>,
+ <&tegra_car TEGRA124_CLK_SOC_THERM>;
+ clock-names = "tsensor", "soctherm";
+ resets = <&tegra_car 78>;
+ reset-names = "soctherm";
+ #thermal-sensor-cells = <1>;
+ };
+
+ ahub@0,70300000 {
+ compatible = "nvidia,tegra124-ahub";
+ reg = <0x0 0x70300000 0x0 0x200>,
+ <0x0 0x70300800 0x0 0x800>,
+ <0x0 0x70300200 0x0 0x600>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_D_AUDIO>,
+ <&tegra_car TEGRA124_CLK_APBIF>;
+ clock-names = "d_audio", "apbif";
+ resets = <&tegra_car 106>, /* d_audio */
+ <&tegra_car 107>, /* apbif */
+ <&tegra_car 30>, /* i2s0 */
+ <&tegra_car 11>, /* i2s1 */
+ <&tegra_car 18>, /* i2s2 */
+ <&tegra_car 101>, /* i2s3 */
+ <&tegra_car 102>, /* i2s4 */
+ <&tegra_car 108>, /* dam0 */
+ <&tegra_car 109>, /* dam1 */
+ <&tegra_car 110>, /* dam2 */
+ <&tegra_car 10>, /* spdif */
+ <&tegra_car 153>, /* amx */
+ <&tegra_car 185>, /* amx1 */
+ <&tegra_car 154>, /* adx */
+ <&tegra_car 180>, /* adx1 */
+ <&tegra_car 186>, /* afc0 */
+ <&tegra_car 187>, /* afc1 */
+ <&tegra_car 188>, /* afc2 */
+ <&tegra_car 189>, /* afc3 */
+ <&tegra_car 190>, /* afc4 */
+ <&tegra_car 191>; /* afc5 */
+ reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
+ "i2s3", "i2s4", "dam0", "dam1", "dam2",
+ "spdif", "amx", "amx1", "adx", "adx1",
+ "afc0", "afc1", "afc2", "afc3", "afc4", "afc5";
+ dmas = <&apbdma 1>, <&apbdma 1>,
+ <&apbdma 2>, <&apbdma 2>,
+ <&apbdma 3>, <&apbdma 3>,
+ <&apbdma 4>, <&apbdma 4>,
+ <&apbdma 6>, <&apbdma 6>,
+ <&apbdma 7>, <&apbdma 7>,
+ <&apbdma 12>, <&apbdma 12>,
+ <&apbdma 13>, <&apbdma 13>,
+ <&apbdma 14>, <&apbdma 14>,
+ <&apbdma 29>, <&apbdma 29>;
+ dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2",
+ "rx3", "tx3", "rx4", "tx4", "rx5", "tx5",
+ "rx6", "tx6", "rx7", "tx7", "rx8", "tx8",
+ "rx9", "tx9";
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ tegra_i2s0: i2s@0,70301000 {
+ compatible = "nvidia,tegra124-i2s";
+ reg = <0x0 0x70301000 0x0 0x100>;
+ nvidia,ahub-cif-ids = <4 4>;
+ clocks = <&tegra_car TEGRA124_CLK_I2S0>;
+ resets = <&tegra_car 30>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+
+ tegra_i2s1: i2s@0,70301100 {
+ compatible = "nvidia,tegra124-i2s";
+ reg = <0x0 0x70301100 0x0 0x100>;
+ nvidia,ahub-cif-ids = <5 5>;
+ clocks = <&tegra_car TEGRA124_CLK_I2S1>;
+ resets = <&tegra_car 11>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+
+ tegra_i2s2: i2s@0,70301200 {
+ compatible = "nvidia,tegra124-i2s";
+ reg = <0x0 0x70301200 0x0 0x100>;
+ nvidia,ahub-cif-ids = <6 6>;
+ clocks = <&tegra_car TEGRA124_CLK_I2S2>;
+ resets = <&tegra_car 18>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+
+ tegra_i2s3: i2s@0,70301300 {
+ compatible = "nvidia,tegra124-i2s";
+ reg = <0x0 0x70301300 0x0 0x100>;
+ nvidia,ahub-cif-ids = <7 7>;
+ clocks = <&tegra_car TEGRA124_CLK_I2S3>;
+ resets = <&tegra_car 101>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+
+ tegra_i2s4: i2s@0,70301400 {
+ compatible = "nvidia,tegra124-i2s";
+ reg = <0x0 0x70301400 0x0 0x100>;
+ nvidia,ahub-cif-ids = <8 8>;
+ clocks = <&tegra_car TEGRA124_CLK_I2S4>;
+ resets = <&tegra_car 102>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+ };
+
+ usb@0,7d000000 {
+ compatible = "nvidia,tegra124-ehci", "nvidia,tegra30-ehci", "usb-ehci";
+ reg = <0x0 0x7d000000 0x0 0x4000>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA124_CLK_USBD>;
+ resets = <&tegra_car 22>;
+ reset-names = "usb";
+ nvidia,phy = <&phy1>;
+ status = "disabled";
+ };
+
+ phy1: usb-phy@0,7d000000 {
+ compatible = "nvidia,tegra124-usb-phy", "nvidia,tegra30-usb-phy";
+ reg = <0x0 0x7d000000 0x0 0x4000>,
+ <0x0 0x7d000000 0x0 0x4000>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA124_CLK_USBD>,
+ <&tegra_car TEGRA124_CLK_PLL_U>,
+ <&tegra_car TEGRA124_CLK_USBD>;
+ clock-names = "reg", "pll_u", "utmi-pads";
+ resets = <&tegra_car 22>, <&tegra_car 22>;
+ reset-names = "usb", "utmi-pads";
+ nvidia,hssync-start-delay = <0>;
+ nvidia,idle-wait-delay = <17>;
+ nvidia,elastic-limit = <16>;
+ nvidia,term-range-adj = <6>;
+ nvidia,xcvr-setup = <9>;
+ nvidia,xcvr-lsfslew = <0>;
+ nvidia,xcvr-lsrslew = <3>;
+ nvidia,hssquelch-level = <2>;
+ nvidia,hsdiscon-level = <5>;
+ nvidia,xcvr-hsslew = <12>;
+ nvidia,has-utmi-pad-registers;
+ status = "disabled";
+ };
+
+ usb@0,7d004000 {
+ compatible = "nvidia,tegra124-ehci", "nvidia,tegra30-ehci", "usb-ehci";
+ reg = <0x0 0x7d004000 0x0 0x4000>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA124_CLK_USB2>;
+ resets = <&tegra_car 58>;
+ reset-names = "usb";
+ nvidia,phy = <&phy2>;
+ status = "disabled";
+ };
+
+ phy2: usb-phy@0,7d004000 {
+ compatible = "nvidia,tegra124-usb-phy", "nvidia,tegra30-usb-phy";
+ reg = <0x0 0x7d004000 0x0 0x4000>,
+ <0x0 0x7d000000 0x0 0x4000>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA124_CLK_USB2>,
+ <&tegra_car TEGRA124_CLK_PLL_U>,
+ <&tegra_car TEGRA124_CLK_USBD>;
+ clock-names = "reg", "pll_u", "utmi-pads";
+ resets = <&tegra_car 58>, <&tegra_car 22>;
+ reset-names = "usb", "utmi-pads";
+ nvidia,hssync-start-delay = <0>;
+ nvidia,idle-wait-delay = <17>;
+ nvidia,elastic-limit = <16>;
+ nvidia,term-range-adj = <6>;
+ nvidia,xcvr-setup = <9>;
+ nvidia,xcvr-lsfslew = <0>;
+ nvidia,xcvr-lsrslew = <3>;
+ nvidia,hssquelch-level = <2>;
+ nvidia,hsdiscon-level = <5>;
+ nvidia,xcvr-hsslew = <12>;
+ status = "disabled";
+ };
+
+ usb@0,7d008000 {
+ compatible = "nvidia,tegra124-ehci", "nvidia,tegra30-ehci", "usb-ehci";
+ reg = <0x0 0x7d008000 0x0 0x4000>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA124_CLK_USB3>;
+ resets = <&tegra_car 59>;
+ reset-names = "usb";
+ nvidia,phy = <&phy3>;
+ status = "disabled";
+ };
+
+ phy3: usb-phy@0,7d008000 {
+ compatible = "nvidia,tegra124-usb-phy", "nvidia,tegra30-usb-phy";
+ reg = <0x0 0x7d008000 0x0 0x4000>,
+ <0x0 0x7d000000 0x0 0x4000>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA124_CLK_USB3>,
+ <&tegra_car TEGRA124_CLK_PLL_U>,
+ <&tegra_car TEGRA124_CLK_USBD>;
+ clock-names = "reg", "pll_u", "utmi-pads";
+ resets = <&tegra_car 59>, <&tegra_car 22>;
+ reset-names = "usb", "utmi-pads";
+ nvidia,hssync-start-delay = <0>;
+ nvidia,idle-wait-delay = <17>;
+ nvidia,elastic-limit = <16>;
+ nvidia,term-range-adj = <6>;
+ nvidia,xcvr-setup = <9>;
+ nvidia,xcvr-lsfslew = <0>;
+ nvidia,xcvr-lsrslew = <3>;
+ nvidia,hssquelch-level = <2>;
+ nvidia,hsdiscon-level = <5>;
+ nvidia,xcvr-hsslew = <12>;
+ status = "disabled";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <1>;
+ };
+
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <2>;
+ };
+
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <3>;
+ };
+ };
+
+ thermal-zones {
+ cpu {
+ polling-delay-passive = <1000>;
+ polling-delay = <1000>;
+
+ thermal-sensors =
+ <&soctherm TEGRA124_SOCTHERM_SENSOR_CPU>;
+ };
+
+ mem {
+ polling-delay-passive = <1000>;
+ polling-delay = <1000>;
+
+ thermal-sensors =
+ <&soctherm TEGRA124_SOCTHERM_SENSOR_MEM>;
+ };
+
+ gpu {
+ polling-delay-passive = <1000>;
+ polling-delay = <1000>;
+
+ thermal-sensors =
+ <&soctherm TEGRA124_SOCTHERM_SENSOR_GPU>;
+ };
+
+ pllx {
+ polling-delay-passive = <1000>;
+ polling-delay = <1000>;
+
+ thermal-sensors =
+ <&soctherm TEGRA124_SOCTHERM_SENSOR_PLLX>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupt-parent = <&gic>;
+ };
+};
diff --git a/arch/arm/boot/dts/tegra20-colibri-512.dtsi b/arch/arm/boot/dts/tegra20-colibri-512.dtsi
new file mode 100644
index 000000000..8e0066ad9
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20-colibri-512.dtsi
@@ -0,0 +1,533 @@
+#include "tegra20.dtsi"
+
+/ {
+ model = "Toradex Colibri T20 512MB";
+ compatible = "toradex,colibri_t20-512", "nvidia,tegra20";
+
+ aliases {
+ rtc0 = "/i2c@7000d000/tps6586x@34";
+ rtc1 = "/rtc@7000e000";
+ };
+
+ memory {
+ reg = <0x00000000 0x20000000>;
+ };
+
+ host1x@50000000 {
+ hdmi@54280000 {
+ vdd-supply = <&hdmi_vdd_reg>;
+ pll-supply = <&hdmi_pll_reg>;
+
+ nvidia,ddc-i2c-bus = <&i2c_ddc>;
+ nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+ GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ pinmux@70000014 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ audio_refclk {
+ nvidia,pins = "cdev1";
+ nvidia,function = "plla_out";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ crt {
+ nvidia,pins = "crtp";
+ nvidia,function = "crt";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ dap3 {
+ nvidia,pins = "dap3";
+ nvidia,function = "dap3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ displaya {
+ nvidia,pins = "ld0", "ld1", "ld2", "ld3",
+ "ld4", "ld5", "ld6", "ld7", "ld8",
+ "ld9", "ld10", "ld11", "ld12", "ld13",
+ "ld14", "ld15", "ld16", "ld17",
+ "lhs", "lpw0", "lpw2", "lsc0",
+ "lsc1", "lsck", "lsda", "lspi", "lvs";
+ nvidia,function = "displaya";
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ gpio_dte {
+ nvidia,pins = "dte";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_gmi {
+ nvidia,pins = "ata", "atc", "atd", "ate",
+ "dap1", "dap2", "dap4", "gpu", "irrx",
+ "irtx", "spia", "spib", "spic";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_pta {
+ nvidia,pins = "pta";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_uac {
+ nvidia,pins = "uac";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ hdint {
+ nvidia,pins = "hdint";
+ nvidia,function = "hdmi";
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ i2c1 {
+ nvidia,pins = "rm";
+ nvidia,function = "i2c1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ i2c3 {
+ nvidia,pins = "dtf";
+ nvidia,function = "i2c3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ i2cddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "i2c2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ i2cp {
+ nvidia,pins = "i2cp";
+ nvidia,function = "i2cp";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ irda {
+ nvidia,pins = "uad";
+ nvidia,function = "irda";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ nand {
+ nvidia,pins = "kbca", "kbcc", "kbcd",
+ "kbce", "kbcf";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ owc {
+ nvidia,pins = "owc";
+ nvidia,function = "owr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ pmc {
+ nvidia,pins = "pmc";
+ nvidia,function = "pwr_on";
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ pwm {
+ nvidia,pins = "sdb", "sdc", "sdd";
+ nvidia,function = "pwm";
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ sdio4 {
+ nvidia,pins = "atb", "gma", "gme";
+ nvidia,function = "sdio4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ spi1 {
+ nvidia,pins = "spid", "spie", "spif";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ spi4 {
+ nvidia,pins = "slxa", "slxc", "slxd", "slxk";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ uarta {
+ nvidia,pins = "sdio1";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ uartd {
+ nvidia,pins = "gmc";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi {
+ nvidia,pins = "uaa", "uab", "uda";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_refclk {
+ nvidia,pins = "cdev2";
+ nvidia,function = "pllp_out4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ usb_gpio {
+ nvidia,pins = "spig", "spih";
+ nvidia,function = "spi2_alt";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ vi {
+ nvidia,pins = "dta", "dtb", "dtc", "dtd";
+ nvidia,function = "vi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ vi_sc {
+ nvidia,pins = "csus";
+ nvidia,function = "vi_sensor_clk";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ };
+ };
+
+ ac97: ac97@70002000 {
+ status = "okay";
+ nvidia,codec-reset-gpio = <&gpio TEGRA_GPIO(V, 0)
+ GPIO_ACTIVE_HIGH>;
+ nvidia,codec-sync-gpio = <&gpio TEGRA_GPIO(P, 0)
+ GPIO_ACTIVE_HIGH>;
+ };
+
+ i2c@7000c000 {
+ clock-frequency = <400000>;
+ };
+
+ i2c_ddc: i2c@7000c400 {
+ clock-frequency = <100000>;
+ };
+
+ i2c@7000c500 {
+ clock-frequency = <400000>;
+ };
+
+ i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ pmic: tps6586x@34 {
+ compatible = "ti,tps6586x";
+ reg = <0x34>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+
+ ti,system-power-controller;
+
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ sys-supply = <&vdd_3v3_reg>;
+ vin-sm0-supply = <&sys_reg>;
+ vin-sm1-supply = <&sys_reg>;
+ vin-sm2-supply = <&sys_reg>;
+ vinldo01-supply = <&sm2_reg>;
+ vinldo23-supply = <&vdd_3v3_reg>;
+ vinldo4-supply = <&vdd_3v3_reg>;
+ vinldo678-supply = <&vdd_3v3_reg>;
+ vinldo9-supply = <&vdd_3v3_reg>;
+
+ regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sys_reg: regulator@0 {
+ reg = <0>;
+ regulator-compatible = "sys";
+ regulator-name = "vdd_sys";
+ regulator-always-on;
+ };
+
+ regulator@1 {
+ reg = <1>;
+ regulator-compatible = "sm0";
+ regulator-name = "vdd_sm0,vdd_core";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ regulator@2 {
+ reg = <2>;
+ regulator-compatible = "sm1";
+ regulator-name = "vdd_sm1,vdd_cpu";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ sm2_reg: regulator@3 {
+ reg = <3>;
+ regulator-compatible = "sm2";
+ regulator-name = "vdd_sm2,vin_ldo*";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ /* LDO0 is not connected to anything */
+
+ regulator@5 {
+ reg = <5>;
+ regulator-compatible = "ldo1";
+ regulator-name = "vdd_ldo1,avdd_pll*";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ regulator@6 {
+ reg = <6>;
+ regulator-compatible = "ldo2";
+ regulator-name = "vdd_ldo2,vdd_rtc";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ /* LDO3 is not connected to anything */
+
+ regulator@8 {
+ reg = <8>;
+ regulator-compatible = "ldo4";
+ regulator-name = "vdd_ldo4,avdd_osc,vddio_sys";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo5_reg: regulator@9 {
+ reg = <9>;
+ regulator-compatible = "ldo5";
+ regulator-name = "vdd_ldo5,vdd_fuse";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ regulator@10 {
+ reg = <10>;
+ regulator-compatible = "ldo6";
+ regulator-name = "vdd_ldo6,avdd_vdac,vddio_vi,vddio_cam";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ hdmi_vdd_reg: regulator@11 {
+ reg = <11>;
+ regulator-compatible = "ldo7";
+ regulator-name = "vdd_ldo7,avdd_hdmi";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ hdmi_pll_reg: regulator@12 {
+ reg = <12>;
+ regulator-compatible = "ldo8";
+ regulator-name = "vdd_ldo8,avdd_hdmi_pll";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ regulator@13 {
+ reg = <13>;
+ regulator-compatible = "ldo9";
+ regulator-name = "vdd_ldo9,avdd_2v85,vdd_ddr_rx";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ };
+
+ regulator@14 {
+ reg = <14>;
+ regulator-compatible = "ldo_rtc";
+ regulator-name = "vdd_rtc_out,vdd_cell";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ temperature-sensor@4c {
+ compatible = "national,lm95245";
+ reg = <0x4c>;
+ };
+ };
+
+ pmc@7000e400 {
+ nvidia,suspend-mode = <1>;
+ nvidia,cpu-pwr-good-time = <5000>;
+ nvidia,cpu-pwr-off-time = <5000>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <3875>;
+ nvidia,sys-clock-req-active-high;
+ };
+
+ memory-controller@7000f400 {
+ emc-table@83250 {
+ reg = <83250>;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = <83250>;
+ nvidia,emc-registers = <0x00000005 0x00000011
+ 0x00000004 0x00000002 0x00000004 0x00000004
+ 0x00000001 0x0000000a 0x00000002 0x00000002
+ 0x00000001 0x00000001 0x00000003 0x00000004
+ 0x00000003 0x00000009 0x0000000c 0x0000025f
+ 0x00000000 0x00000003 0x00000003 0x00000002
+ 0x00000002 0x00000001 0x00000008 0x000000c8
+ 0x00000003 0x00000005 0x00000003 0x0000000c
+ 0x00000002 0x00000000 0x00000000 0x00000002
+ 0x00000000 0x00000000 0x00000083 0x00520006
+ 0x00000010 0x00000008 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000>;
+ };
+ emc-table@133200 {
+ reg = <133200>;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = <133200>;
+ nvidia,emc-registers = <0x00000008 0x00000019
+ 0x00000006 0x00000002 0x00000004 0x00000004
+ 0x00000001 0x0000000a 0x00000002 0x00000002
+ 0x00000002 0x00000001 0x00000003 0x00000004
+ 0x00000003 0x00000009 0x0000000c 0x0000039f
+ 0x00000000 0x00000003 0x00000003 0x00000002
+ 0x00000002 0x00000001 0x00000008 0x000000c8
+ 0x00000003 0x00000007 0x00000003 0x0000000c
+ 0x00000002 0x00000000 0x00000000 0x00000002
+ 0x00000000 0x00000000 0x00000083 0x00510006
+ 0x00000010 0x00000008 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000>;
+ };
+ emc-table@166500 {
+ reg = <166500>;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = <166500>;
+ nvidia,emc-registers = <0x0000000a 0x00000021
+ 0x00000008 0x00000003 0x00000004 0x00000004
+ 0x00000002 0x0000000a 0x00000003 0x00000003
+ 0x00000002 0x00000001 0x00000003 0x00000004
+ 0x00000003 0x00000009 0x0000000c 0x000004df
+ 0x00000000 0x00000003 0x00000003 0x00000003
+ 0x00000003 0x00000001 0x00000009 0x000000c8
+ 0x00000003 0x00000009 0x00000004 0x0000000c
+ 0x00000002 0x00000000 0x00000000 0x00000002
+ 0x00000000 0x00000000 0x00000083 0x004f0006
+ 0x00000010 0x00000008 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000>;
+ };
+ emc-table@333000 {
+ reg = <333000>;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = <333000>;
+ nvidia,emc-registers = <0x00000014 0x00000041
+ 0x0000000f 0x00000005 0x00000004 0x00000005
+ 0x00000003 0x0000000a 0x00000005 0x00000005
+ 0x00000004 0x00000001 0x00000003 0x00000004
+ 0x00000003 0x00000009 0x0000000c 0x000009ff
+ 0x00000000 0x00000003 0x00000003 0x00000005
+ 0x00000005 0x00000001 0x0000000e 0x000000c8
+ 0x00000003 0x00000011 0x00000006 0x0000000c
+ 0x00000002 0x00000000 0x00000000 0x00000002
+ 0x00000000 0x00000000 0x00000083 0x00380006
+ 0x00000010 0x00000008 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000>;
+ };
+ };
+
+ usb@c5004000 {
+ status = "okay";
+ nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+ GPIO_ACTIVE_LOW>;
+ };
+
+ usb-phy@c5004000 {
+ status = "okay";
+ nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+ GPIO_ACTIVE_LOW>;
+ };
+
+ sdhci@c8000600 {
+ cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock@0 {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdd_3v3_reg: regulator@100 {
+ compatible = "regulator-fixed";
+ reg = <100>;
+ regulator-name = "vdd_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ regulator@101 {
+ compatible = "regulator-fixed";
+ reg = <101>;
+ regulator-name = "internal_usb";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-boot-on;
+ regulator-always-on;
+ gpio = <&gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-wm9712-colibri_t20",
+ "nvidia,tegra-audio-wm9712";
+ nvidia,model = "Colibri T20 AC97 Audio";
+
+ nvidia,audio-routing =
+ "Headphone", "HPOUTL",
+ "Headphone", "HPOUTR",
+ "LineIn", "LINEINL",
+ "LineIn", "LINEINR",
+ "Mic", "MIC1";
+
+ nvidia,ac97-controller = <&ac97>;
+
+ clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+ <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA20_CLK_CDEV1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
+};
diff --git a/arch/arm/boot/dts/tegra20-harmony.dts b/arch/arm/boot/dts/tegra20-harmony.dts
new file mode 100644
index 000000000..b926a07b9
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20-harmony.dts
@@ -0,0 +1,777 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra20.dtsi"
+
+/ {
+ model = "NVIDIA Tegra20 Harmony evaluation board";
+ compatible = "nvidia,harmony", "nvidia,tegra20";
+
+ aliases {
+ rtc0 = "/i2c@7000d000/tps6586x@34";
+ rtc1 = "/rtc@7000e000";
+ serial0 = &uartd;
+ };
+
+ memory {
+ reg = <0x00000000 0x40000000>;
+ };
+
+ host1x@50000000 {
+ dc@54200000 {
+ rgb {
+ status = "okay";
+
+ nvidia,panel = <&panel>;
+ };
+ };
+
+ hdmi@54280000 {
+ status = "okay";
+
+ hdmi-supply = <&vdd_5v0_hdmi>;
+ vdd-supply = <&hdmi_vdd_reg>;
+ pll-supply = <&hdmi_pll_reg>;
+
+ nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+ GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ pinmux@70000014 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ ata {
+ nvidia,pins = "ata";
+ nvidia,function = "ide";
+ };
+ atb {
+ nvidia,pins = "atb", "gma", "gme";
+ nvidia,function = "sdio4";
+ };
+ atc {
+ nvidia,pins = "atc";
+ nvidia,function = "nand";
+ };
+ atd {
+ nvidia,pins = "atd", "ate", "gmb", "gmd", "gpu",
+ "spia", "spib", "spic";
+ nvidia,function = "gmi";
+ };
+ cdev1 {
+ nvidia,pins = "cdev1";
+ nvidia,function = "plla_out";
+ };
+ cdev2 {
+ nvidia,pins = "cdev2";
+ nvidia,function = "pllp_out4";
+ };
+ crtp {
+ nvidia,pins = "crtp";
+ nvidia,function = "crt";
+ };
+ csus {
+ nvidia,pins = "csus";
+ nvidia,function = "vi_sensor_clk";
+ };
+ dap1 {
+ nvidia,pins = "dap1";
+ nvidia,function = "dap1";
+ };
+ dap2 {
+ nvidia,pins = "dap2";
+ nvidia,function = "dap2";
+ };
+ dap3 {
+ nvidia,pins = "dap3";
+ nvidia,function = "dap3";
+ };
+ dap4 {
+ nvidia,pins = "dap4";
+ nvidia,function = "dap4";
+ };
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "i2c2";
+ };
+ dta {
+ nvidia,pins = "dta", "dtd";
+ nvidia,function = "sdio2";
+ };
+ dtb {
+ nvidia,pins = "dtb", "dtc", "dte";
+ nvidia,function = "rsvd1";
+ };
+ dtf {
+ nvidia,pins = "dtf";
+ nvidia,function = "i2c3";
+ };
+ gmc {
+ nvidia,pins = "gmc";
+ nvidia,function = "uartd";
+ };
+ gpu7 {
+ nvidia,pins = "gpu7";
+ nvidia,function = "rtck";
+ };
+ gpv {
+ nvidia,pins = "gpv", "slxa", "slxk";
+ nvidia,function = "pcie";
+ };
+ hdint {
+ nvidia,pins = "hdint", "pta";
+ nvidia,function = "hdmi";
+ };
+ i2cp {
+ nvidia,pins = "i2cp";
+ nvidia,function = "i2cp";
+ };
+ irrx {
+ nvidia,pins = "irrx", "irtx";
+ nvidia,function = "uarta";
+ };
+ kbca {
+ nvidia,pins = "kbca", "kbcb", "kbcc", "kbcd",
+ "kbce", "kbcf";
+ nvidia,function = "kbc";
+ };
+ lcsn {
+ nvidia,pins = "lcsn", "ld0", "ld1", "ld2",
+ "ld3", "ld4", "ld5", "ld6", "ld7",
+ "ld8", "ld9", "ld10", "ld11", "ld12",
+ "ld13", "ld14", "ld15", "ld16", "ld17",
+ "ldc", "ldi", "lhp0", "lhp1", "lhp2",
+ "lhs", "lm0", "lm1", "lpp", "lpw0",
+ "lpw1", "lpw2", "lsc0", "lsc1", "lsck",
+ "lsda", "lsdi", "lspi", "lvp0", "lvp1",
+ "lvs";
+ nvidia,function = "displaya";
+ };
+ owc {
+ nvidia,pins = "owc", "spdi", "spdo", "uac";
+ nvidia,function = "rsvd2";
+ };
+ pmc {
+ nvidia,pins = "pmc";
+ nvidia,function = "pwr_on";
+ };
+ rm {
+ nvidia,pins = "rm";
+ nvidia,function = "i2c1";
+ };
+ sdb {
+ nvidia,pins = "sdb", "sdc", "sdd";
+ nvidia,function = "pwm";
+ };
+ sdio1 {
+ nvidia,pins = "sdio1";
+ nvidia,function = "sdio1";
+ };
+ slxc {
+ nvidia,pins = "slxc", "slxd";
+ nvidia,function = "spdif";
+ };
+ spid {
+ nvidia,pins = "spid", "spie", "spif";
+ nvidia,function = "spi1";
+ };
+ spig {
+ nvidia,pins = "spig", "spih";
+ nvidia,function = "spi2_alt";
+ };
+ uaa {
+ nvidia,pins = "uaa", "uab", "uda";
+ nvidia,function = "ulpi";
+ };
+ uad {
+ nvidia,pins = "uad";
+ nvidia,function = "irda";
+ };
+ uca {
+ nvidia,pins = "uca", "ucb";
+ nvidia,function = "uartc";
+ };
+ conf_ata {
+ nvidia,pins = "ata", "atb", "atc", "atd", "ate",
+ "cdev1", "cdev2", "dap1", "dtb", "gma",
+ "gmb", "gmc", "gmd", "gme", "gpu7",
+ "gpv", "i2cp", "pta", "rm", "slxa",
+ "slxk", "spia", "spib", "uac";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_ck32 {
+ nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
+ "pmcc", "pmcd", "pmce", "xm2c", "xm2d";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ };
+ conf_csus {
+ nvidia,pins = "csus", "spid", "spif";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_crtp {
+ nvidia,pins = "crtp", "dap2", "dap3", "dap4",
+ "dtc", "dte", "dtf", "gpu", "sdio1",
+ "slxc", "slxd", "spdi", "spdo", "spig",
+ "uda";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_ddc {
+ nvidia,pins = "ddc", "dta", "dtd", "kbca",
+ "kbcb", "kbcc", "kbcd", "kbce", "kbcf",
+ "sdc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_hdint {
+ nvidia,pins = "hdint", "lcsn", "ldc", "lm1",
+ "lpw1", "lsc1", "lsck", "lsda", "lsdi",
+ "lvp0", "owc", "sdb";
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_irrx {
+ nvidia,pins = "irrx", "irtx", "sdd", "spic",
+ "spie", "spih", "uaa", "uab", "uad",
+ "uca", "ucb";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_lc {
+ nvidia,pins = "lc", "ls";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ };
+ conf_ld0 {
+ nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4",
+ "ld5", "ld6", "ld7", "ld8", "ld9",
+ "ld10", "ld11", "ld12", "ld13", "ld14",
+ "ld15", "ld16", "ld17", "ldi", "lhp0",
+ "lhp1", "lhp2", "lhs", "lm0", "lpp",
+ "lpw0", "lpw2", "lsc0", "lspi", "lvp1",
+ "lvs", "pmc";
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_ld17_0 {
+ nvidia,pins = "ld17_0", "ld19_18", "ld21_20",
+ "ld23_22";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ };
+ };
+ };
+
+ i2s@70002800 {
+ status = "okay";
+ };
+
+ serial@70006300 {
+ status = "okay";
+ };
+
+ pwm: pwm@7000a000 {
+ status = "okay";
+ };
+
+ i2c@7000c000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ wm8903: wm8903@1a {
+ compatible = "wlf,wm8903";
+ reg = <0x1a>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(X, 3) IRQ_TYPE_LEVEL_HIGH>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ micdet-cfg = <0>;
+ micdet-delay = <100>;
+ gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>;
+ };
+ };
+
+ hdmi_ddc: i2c@7000c400 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@7000c500 {
+ status = "okay";
+ clock-frequency = <400000>;
+ };
+
+ i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ pmic: tps6586x@34 {
+ compatible = "ti,tps6586x";
+ reg = <0x34>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+
+ ti,system-power-controller;
+
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ sys-supply = <&vdd_5v0_reg>;
+ vin-sm0-supply = <&sys_reg>;
+ vin-sm1-supply = <&sys_reg>;
+ vin-sm2-supply = <&sys_reg>;
+ vinldo01-supply = <&sm2_reg>;
+ vinldo23-supply = <&sm2_reg>;
+ vinldo4-supply = <&sm2_reg>;
+ vinldo678-supply = <&sm2_reg>;
+ vinldo9-supply = <&sm2_reg>;
+
+ regulators {
+ sys_reg: sys {
+ regulator-name = "vdd_sys";
+ regulator-always-on;
+ };
+
+ sm0 {
+ regulator-name = "vdd_sm0,vdd_core";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ sm1 {
+ regulator-name = "vdd_sm1,vdd_cpu";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ sm2_reg: sm2 {
+ regulator-name = "vdd_sm2,vin_ldo*";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+ regulator-always-on;
+ };
+
+ pci_clk_reg: ldo0 {
+ regulator-name = "vdd_ldo0,vddio_pex_clk";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo1 {
+ regulator-name = "vdd_ldo1,avdd_pll*";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ ldo2 {
+ regulator-name = "vdd_ldo2,vdd_rtc";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo3 {
+ regulator-name = "vdd_ldo3,avdd_usb*";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo4 {
+ regulator-name = "vdd_ldo4,avdd_osc,vddio_sys";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo5 {
+ regulator-name = "vdd_ldo5,vcore_mmc";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ };
+
+ ldo6 {
+ regulator-name = "vdd_ldo6,avdd_vdac";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ hdmi_vdd_reg: ldo7 {
+ regulator-name = "vdd_ldo7,avdd_hdmi";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ hdmi_pll_reg: ldo8 {
+ regulator-name = "vdd_ldo8,avdd_hdmi_pll";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo9 {
+ regulator-name = "vdd_ldo9,avdd_2v85,vdd_ddr_rx";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ };
+
+ ldo_rtc {
+ regulator-name = "vdd_rtc_out,vdd_cell";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ temperature-sensor@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+
+ kbc@7000e200 {
+ status = "okay";
+ nvidia,debounce-delay-ms = <2>;
+ nvidia,repeat-delay-ms = <160>;
+ nvidia,kbc-row-pins = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
+ nvidia,kbc-col-pins = <16 17 18 19 20 21 22 23>;
+ linux,keymap = <MATRIX_KEY(0x00, 0x02, KEY_W)
+ MATRIX_KEY(0x00, 0x03, KEY_S)
+ MATRIX_KEY(0x00, 0x04, KEY_A)
+ MATRIX_KEY(0x00, 0x05, KEY_Z)
+ MATRIX_KEY(0x00, 0x07, KEY_FN)
+ MATRIX_KEY(0x01, 0x07, KEY_MENU)
+ MATRIX_KEY(0x02, 0x06, KEY_LEFTALT)
+ MATRIX_KEY(0x02, 0x07, KEY_RIGHTALT)
+ MATRIX_KEY(0x03, 0x00, KEY_5)
+ MATRIX_KEY(0x03, 0x01, KEY_4)
+ MATRIX_KEY(0x03, 0x02, KEY_R)
+ MATRIX_KEY(0x03, 0x03, KEY_E)
+ MATRIX_KEY(0x03, 0x04, KEY_F)
+ MATRIX_KEY(0x03, 0x05, KEY_D)
+ MATRIX_KEY(0x03, 0x06, KEY_X)
+ MATRIX_KEY(0x04, 0x00, KEY_7)
+ MATRIX_KEY(0x04, 0x01, KEY_6)
+ MATRIX_KEY(0x04, 0x02, KEY_T)
+ MATRIX_KEY(0x04, 0x03, KEY_H)
+ MATRIX_KEY(0x04, 0x04, KEY_G)
+ MATRIX_KEY(0x04, 0x05, KEY_V)
+ MATRIX_KEY(0x04, 0x06, KEY_C)
+ MATRIX_KEY(0x04, 0x07, KEY_SPACE)
+ MATRIX_KEY(0x05, 0x00, KEY_9)
+ MATRIX_KEY(0x05, 0x01, KEY_8)
+ MATRIX_KEY(0x05, 0x02, KEY_U)
+ MATRIX_KEY(0x05, 0x03, KEY_Y)
+ MATRIX_KEY(0x05, 0x04, KEY_J)
+ MATRIX_KEY(0x05, 0x05, KEY_N)
+ MATRIX_KEY(0x05, 0x06, KEY_B)
+ MATRIX_KEY(0x05, 0x07, KEY_BACKSLASH)
+ MATRIX_KEY(0x06, 0x00, KEY_MINUS)
+ MATRIX_KEY(0x06, 0x01, KEY_0)
+ MATRIX_KEY(0x06, 0x02, KEY_O)
+ MATRIX_KEY(0x06, 0x03, KEY_I)
+ MATRIX_KEY(0x06, 0x04, KEY_L)
+ MATRIX_KEY(0x06, 0x05, KEY_K)
+ MATRIX_KEY(0x06, 0x06, KEY_COMMA)
+ MATRIX_KEY(0x06, 0x07, KEY_M)
+ MATRIX_KEY(0x07, 0x01, KEY_EQUAL)
+ MATRIX_KEY(0x07, 0x02, KEY_RIGHTBRACE)
+ MATRIX_KEY(0x07, 0x03, KEY_ENTER)
+ MATRIX_KEY(0x07, 0x07, KEY_MENU)
+ MATRIX_KEY(0x08, 0x04, KEY_LEFTSHIFT)
+ MATRIX_KEY(0x08, 0x05, KEY_RIGHTSHIFT)
+ MATRIX_KEY(0x09, 0x05, KEY_LEFTCTRL)
+ MATRIX_KEY(0x09, 0x07, KEY_RIGHTCTRL)
+ MATRIX_KEY(0x0B, 0x00, KEY_LEFTBRACE)
+ MATRIX_KEY(0x0B, 0x01, KEY_P)
+ MATRIX_KEY(0x0B, 0x02, KEY_APOSTROPHE)
+ MATRIX_KEY(0x0B, 0x03, KEY_SEMICOLON)
+ MATRIX_KEY(0x0B, 0x04, KEY_SLASH)
+ MATRIX_KEY(0x0B, 0x05, KEY_DOT)
+ MATRIX_KEY(0x0C, 0x00, KEY_F10)
+ MATRIX_KEY(0x0C, 0x01, KEY_F9)
+ MATRIX_KEY(0x0C, 0x02, KEY_BACKSPACE)
+ MATRIX_KEY(0x0C, 0x03, KEY_3)
+ MATRIX_KEY(0x0C, 0x04, KEY_2)
+ MATRIX_KEY(0x0C, 0x05, KEY_UP)
+ MATRIX_KEY(0x0C, 0x06, KEY_PRINT)
+ MATRIX_KEY(0x0C, 0x07, KEY_PAUSE)
+ MATRIX_KEY(0x0D, 0x00, KEY_INSERT)
+ MATRIX_KEY(0x0D, 0x01, KEY_DELETE)
+ MATRIX_KEY(0x0D, 0x03, KEY_PAGEUP )
+ MATRIX_KEY(0x0D, 0x04, KEY_PAGEDOWN)
+ MATRIX_KEY(0x0D, 0x05, KEY_RIGHT)
+ MATRIX_KEY(0x0D, 0x06, KEY_DOWN)
+ MATRIX_KEY(0x0D, 0x07, KEY_LEFT)
+ MATRIX_KEY(0x0E, 0x00, KEY_F11)
+ MATRIX_KEY(0x0E, 0x01, KEY_F12)
+ MATRIX_KEY(0x0E, 0x02, KEY_F8)
+ MATRIX_KEY(0x0E, 0x03, KEY_Q)
+ MATRIX_KEY(0x0E, 0x04, KEY_F4)
+ MATRIX_KEY(0x0E, 0x05, KEY_F3)
+ MATRIX_KEY(0x0E, 0x06, KEY_1)
+ MATRIX_KEY(0x0E, 0x07, KEY_F7)
+ MATRIX_KEY(0x0F, 0x00, KEY_ESC)
+ MATRIX_KEY(0x0F, 0x01, KEY_GRAVE)
+ MATRIX_KEY(0x0F, 0x02, KEY_F5)
+ MATRIX_KEY(0x0F, 0x03, KEY_TAB)
+ MATRIX_KEY(0x0F, 0x04, KEY_F1)
+ MATRIX_KEY(0x0F, 0x05, KEY_F2)
+ MATRIX_KEY(0x0F, 0x06, KEY_CAPSLOCK)
+ MATRIX_KEY(0x0F, 0x07, KEY_F6)
+ MATRIX_KEY(0x14, 0x00, KEY_KP7)
+ MATRIX_KEY(0x15, 0x00, KEY_KP9)
+ MATRIX_KEY(0x15, 0x01, KEY_KP8)
+ MATRIX_KEY(0x15, 0x02, KEY_KP4)
+ MATRIX_KEY(0x15, 0x04, KEY_KP1)
+ MATRIX_KEY(0x16, 0x01, KEY_KPSLASH)
+ MATRIX_KEY(0x16, 0x02, KEY_KP6)
+ MATRIX_KEY(0x16, 0x03, KEY_KP5)
+ MATRIX_KEY(0x16, 0x04, KEY_KP3)
+ MATRIX_KEY(0x16, 0x05, KEY_KP2)
+ MATRIX_KEY(0x16, 0x07, KEY_KP0)
+ MATRIX_KEY(0x1B, 0x01, KEY_KPASTERISK)
+ MATRIX_KEY(0x1B, 0x03, KEY_KPMINUS)
+ MATRIX_KEY(0x1B, 0x04, KEY_KPPLUS)
+ MATRIX_KEY(0x1B, 0x05, KEY_KPDOT)
+ MATRIX_KEY(0x1C, 0x05, KEY_VOLUMEUP)
+ MATRIX_KEY(0x1D, 0x03, KEY_HOME)
+ MATRIX_KEY(0x1D, 0x04, KEY_END)
+ MATRIX_KEY(0x1D, 0x05, KEY_BRIGHTNESSUP)
+ MATRIX_KEY(0x1D, 0x06, KEY_VOLUMEDOWN)
+ MATRIX_KEY(0x1D, 0x07, KEY_BRIGHTNESSDOWN)
+ MATRIX_KEY(0x1E, 0x00, KEY_NUMLOCK)
+ MATRIX_KEY(0x1E, 0x01, KEY_SCROLLLOCK)
+ MATRIX_KEY(0x1E, 0x02, KEY_MUTE)
+ MATRIX_KEY(0x1F, 0x04, KEY_QUESTION)>;
+ };
+
+ pmc@7000e400 {
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <1>;
+ nvidia,cpu-pwr-good-time = <5000>;
+ nvidia,cpu-pwr-off-time = <5000>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <3875>;
+ nvidia,sys-clock-req-active-high;
+ };
+
+ pcie-controller@80003000 {
+ status = "okay";
+
+ avdd-pex-supply = <&pci_vdd_reg>;
+ vdd-pex-supply = <&pci_vdd_reg>;
+ avdd-pex-pll-supply = <&pci_vdd_reg>;
+ avdd-plle-supply = <&pci_vdd_reg>;
+ vddio-pex-clk-supply = <&pci_clk_reg>;
+
+ pci@1,0 {
+ status = "okay";
+ };
+
+ pci@2,0 {
+ status = "okay";
+ };
+ };
+
+ usb@c5000000 {
+ status = "okay";
+ };
+
+ usb-phy@c5000000 {
+ status = "okay";
+ };
+
+ usb@c5004000 {
+ status = "okay";
+ nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+ GPIO_ACTIVE_LOW>;
+ };
+
+ usb-phy@c5004000 {
+ status = "okay";
+ nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+ GPIO_ACTIVE_LOW>;
+ };
+
+ usb@c5008000 {
+ status = "okay";
+ };
+
+ usb-phy@c5008000 {
+ status = "okay";
+ };
+
+ sdhci@c8000200 {
+ status = "okay";
+ cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
+ power-gpios = <&gpio TEGRA_GPIO(T, 3) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ };
+
+ sdhci@c8000600 {
+ status = "okay";
+ cd-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>;
+ power-gpios = <&gpio TEGRA_GPIO(I, 6) GPIO_ACTIVE_HIGH>;
+ bus-width = <8>;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+
+ enable-gpios = <&gpio TEGRA_GPIO(B, 5) GPIO_ACTIVE_HIGH>;
+ power-supply = <&vdd_bl_reg>;
+ pwms = <&pwm 0 5000000>;
+
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock@0 {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ gpio-key,wakeup;
+ };
+ };
+
+ panel: panel {
+ compatible = "auo,b101aw03", "simple-panel";
+
+ power-supply = <&vdd_pnl_reg>;
+ enable-gpios = <&gpio TEGRA_GPIO(B, 2) GPIO_ACTIVE_HIGH>;
+
+ backlight = <&backlight>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdd_5v0_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vdd_5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "vdd_1v5";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ gpio = <&pmic 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "vdd_1v2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ gpio = <&pmic 1 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ pci_vdd_reg: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "vdd_1v05";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ gpio = <&pmic 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vdd_pnl_reg: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "vdd_pnl";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpio TEGRA_GPIO(C, 6) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vdd_bl_reg: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "vdd_bl";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpio TEGRA_GPIO(W, 0) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vdd_5v0_hdmi: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ regulator-name = "VDDIO_HDMI";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(T, 2) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_5v0_reg>;
+ };
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-wm8903-harmony",
+ "nvidia,tegra-audio-wm8903";
+ nvidia,model = "NVIDIA Tegra Harmony";
+
+ nvidia,audio-routing =
+ "Headphone Jack", "HPOUTR",
+ "Headphone Jack", "HPOUTL",
+ "Int Spk", "ROP",
+ "Int Spk", "RON",
+ "Int Spk", "LOP",
+ "Int Spk", "LON",
+ "Mic Jack", "MICBIAS",
+ "IN1L", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&wm8903>;
+
+ nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>;
+ nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2)
+ GPIO_ACTIVE_HIGH>;
+ nvidia,int-mic-en-gpios = <&gpio TEGRA_GPIO(X, 0)
+ GPIO_ACTIVE_HIGH>;
+ nvidia,ext-mic-en-gpios = <&gpio TEGRA_GPIO(X, 1)
+ GPIO_ACTIVE_HIGH>;
+
+ clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+ <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA20_CLK_CDEV1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
+};
diff --git a/arch/arm/boot/dts/tegra20-iris-512.dts b/arch/arm/boot/dts/tegra20-iris-512.dts
new file mode 100644
index 000000000..1dd7d7bfd
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20-iris-512.dts
@@ -0,0 +1,101 @@
+/dts-v1/;
+
+#include "tegra20-colibri-512.dtsi"
+
+/ {
+ model = "Toradex Colibri T20 512MB on Iris";
+ compatible = "toradex,iris", "toradex,colibri_t20-512", "nvidia,tegra20";
+
+ aliases {
+ serial0 = &uarta;
+ serial1 = &uartd;
+ };
+
+ host1x@50000000 {
+ hdmi@54280000 {
+ status = "okay";
+ };
+ };
+
+ pinmux@70000014 {
+ state_default: pinmux {
+ hdint {
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ i2cddc {
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ sdio4 {
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ uarta {
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ uartd {
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ };
+ };
+
+ serial@70006000 {
+ status = "okay";
+ };
+
+ serial@70006300 {
+ status = "okay";
+ };
+
+ i2c_ddc: i2c@7000c400 {
+ status = "okay";
+ };
+
+ usb@c5000000 {
+ status = "okay";
+ };
+
+ usb-phy@c5000000 {
+ status = "okay";
+ };
+
+ usb@c5008000 {
+ status = "okay";
+ };
+
+ usb-phy@c5008000 {
+ status = "okay";
+ };
+
+ sdhci@c8000600 {
+ status = "okay";
+ bus-width = <4>;
+ vmmc-supply = <&vcc_sd_reg>;
+ vqmmc-supply = <&vcc_sd_reg>;
+ };
+
+ regulators {
+ regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb_host_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>;
+ };
+
+ vcc_sd_reg: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "vcc_sd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra20-medcom-wide.dts b/arch/arm/boot/dts/tegra20-medcom-wide.dts
new file mode 100644
index 000000000..9b87526ab
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20-medcom-wide.dts
@@ -0,0 +1,130 @@
+/dts-v1/;
+
+#include "tegra20-tamonten.dtsi"
+
+/ {
+ model = "Avionic Design Medcom-Wide board";
+ compatible = "ad,medcom-wide", "ad,tamonten", "nvidia,tegra20";
+
+ aliases {
+ serial0 = &uartd;
+ };
+
+ pwm@7000a000 {
+ status = "okay";
+ };
+
+ host1x@50000000 {
+ dc@54200000 {
+ rgb {
+ status = "okay";
+ nvidia,panel = <&panel>;
+ };
+ };
+ };
+
+ i2c@7000c000 {
+ wm8903: wm8903@1a {
+ compatible = "wlf,wm8903";
+ reg = <0x1a>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(X, 3) IRQ_TYPE_LEVEL_HIGH>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ micdet-cfg = <0>;
+ micdet-delay = <100>;
+ gpio-cfg = <0xffffffff
+ 0xffffffff
+ 0
+ 0xffffffff
+ 0xffffffff>;
+ };
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 0 5000000>;
+
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
+ panel: panel {
+ compatible = "innolux,n156bge-l21", "simple-panel";
+
+ power-supply = <&vdd_1v8_reg>, <&vdd_3v3_reg>;
+ enable-gpios = <&gpio TEGRA_GPIO(B, 2) GPIO_ACTIVE_HIGH>;
+
+ backlight = <&backlight>;
+ };
+
+ sound {
+ compatible = "ad,tegra-audio-wm8903-medcom-wide",
+ "nvidia,tegra-audio-wm8903";
+ nvidia,model = "Avionic Design Medcom-Wide";
+
+ nvidia,audio-routing =
+ "Headphone Jack", "HPOUTR",
+ "Headphone Jack", "HPOUTL",
+ "Int Spk", "ROP",
+ "Int Spk", "RON",
+ "Int Spk", "LOP",
+ "Int Spk", "LON",
+ "Mic Jack", "MICBIAS",
+ "IN1L", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&wm8903>;
+
+ nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>;
+ nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>;
+
+ clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+ <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA20_CLK_CDEV1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
+
+ regulators {
+ vcc_24v_reg: regulator@100 {
+ compatible = "regulator-fixed";
+ reg = <100>;
+ regulator-name = "vcc_24v";
+ regulator-min-microvolt = <24000000>;
+ regulator-max-microvolt = <24000000>;
+ regulator-always-on;
+ };
+
+ vdd_5v0_reg: regulator@101 {
+ compatible = "regulator-fixed";
+ reg = <101>;
+ regulator-name = "vdd_5v0";
+ vin-supply = <&vcc_24v_reg>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ vdd_3v3_reg: regulator@102 {
+ compatible = "regulator-fixed";
+ reg = <102>;
+ regulator-name = "vdd_3v3";
+ vin-supply = <&vcc_24v_reg>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_1v8_reg: regulator@103 {
+ compatible = "regulator-fixed";
+ reg = <103>;
+ regulator-name = "vdd_1v8";
+ vin-supply = <&vdd_3v3_reg>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra20-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts
new file mode 100644
index 000000000..ed7e10093
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20-paz00.dts
@@ -0,0 +1,598 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra20.dtsi"
+
+/ {
+ model = "Toshiba AC100 / Dynabook AZ";
+ compatible = "compal,paz00", "nvidia,tegra20";
+
+ aliases {
+ rtc0 = "/i2c@7000d000/tps6586x@34";
+ rtc1 = "/rtc@7000e000";
+ serial0 = &uarta;
+ serial1 = &uartc;
+ };
+
+ memory {
+ reg = <0x00000000 0x20000000>;
+ };
+
+ host1x@50000000 {
+ dc@54200000 {
+ rgb {
+ status = "okay";
+
+ nvidia,panel = <&panel>;
+ };
+ };
+
+ hdmi@54280000 {
+ status = "okay";
+
+ vdd-supply = <&hdmi_vdd_reg>;
+ pll-supply = <&hdmi_pll_reg>;
+
+ nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+ GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ pinmux@70000014 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ ata {
+ nvidia,pins = "ata", "atc", "atd", "ate",
+ "dap2", "gmb", "gmc", "gmd", "spia",
+ "spib", "spic", "spid", "spie";
+ nvidia,function = "gmi";
+ };
+ atb {
+ nvidia,pins = "atb", "gma", "gme";
+ nvidia,function = "sdio4";
+ };
+ cdev1 {
+ nvidia,pins = "cdev1";
+ nvidia,function = "plla_out";
+ };
+ cdev2 {
+ nvidia,pins = "cdev2";
+ nvidia,function = "pllp_out4";
+ };
+ crtp {
+ nvidia,pins = "crtp";
+ nvidia,function = "crt";
+ };
+ csus {
+ nvidia,pins = "csus";
+ nvidia,function = "pllc_out1";
+ };
+ dap1 {
+ nvidia,pins = "dap1";
+ nvidia,function = "dap1";
+ };
+ dap3 {
+ nvidia,pins = "dap3";
+ nvidia,function = "dap3";
+ };
+ dap4 {
+ nvidia,pins = "dap4";
+ nvidia,function = "dap4";
+ };
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "i2c2";
+ };
+ dta {
+ nvidia,pins = "dta", "dtb", "dtc", "dtd", "dte";
+ nvidia,function = "rsvd1";
+ };
+ dtf {
+ nvidia,pins = "dtf";
+ nvidia,function = "i2c3";
+ };
+ gpu {
+ nvidia,pins = "gpu", "sdb", "sdd";
+ nvidia,function = "pwm";
+ };
+ gpu7 {
+ nvidia,pins = "gpu7";
+ nvidia,function = "rtck";
+ };
+ gpv {
+ nvidia,pins = "gpv", "slxa", "slxk";
+ nvidia,function = "pcie";
+ };
+ hdint {
+ nvidia,pins = "hdint", "pta";
+ nvidia,function = "hdmi";
+ };
+ i2cp {
+ nvidia,pins = "i2cp";
+ nvidia,function = "i2cp";
+ };
+ irrx {
+ nvidia,pins = "irrx", "irtx";
+ nvidia,function = "uarta";
+ };
+ kbca {
+ nvidia,pins = "kbca", "kbcc", "kbce", "kbcf";
+ nvidia,function = "kbc";
+ };
+ kbcb {
+ nvidia,pins = "kbcb", "kbcd";
+ nvidia,function = "sdio2";
+ };
+ lcsn {
+ nvidia,pins = "lcsn", "ld0", "ld1", "ld2",
+ "ld3", "ld4", "ld5", "ld6", "ld7",
+ "ld8", "ld9", "ld10", "ld11", "ld12",
+ "ld13", "ld14", "ld15", "ld16", "ld17",
+ "ldc", "ldi", "lhp0", "lhp1", "lhp2",
+ "lhs", "lm0", "lm1", "lpp", "lpw0",
+ "lpw1", "lpw2", "lsc0", "lsc1", "lsck",
+ "lsda", "lsdi", "lspi", "lvp0", "lvp1",
+ "lvs";
+ nvidia,function = "displaya";
+ };
+ owc {
+ nvidia,pins = "owc";
+ nvidia,function = "owr";
+ };
+ pmc {
+ nvidia,pins = "pmc";
+ nvidia,function = "pwr_on";
+ };
+ rm {
+ nvidia,pins = "rm";
+ nvidia,function = "i2c1";
+ };
+ sdc {
+ nvidia,pins = "sdc";
+ nvidia,function = "twc";
+ };
+ sdio1 {
+ nvidia,pins = "sdio1";
+ nvidia,function = "sdio1";
+ };
+ slxc {
+ nvidia,pins = "slxc", "slxd";
+ nvidia,function = "spi4";
+ };
+ spdi {
+ nvidia,pins = "spdi", "spdo";
+ nvidia,function = "rsvd2";
+ };
+ spif {
+ nvidia,pins = "spif", "uac";
+ nvidia,function = "rsvd4";
+ };
+ spig {
+ nvidia,pins = "spig", "spih";
+ nvidia,function = "spi2_alt";
+ };
+ uaa {
+ nvidia,pins = "uaa", "uab", "uda";
+ nvidia,function = "ulpi";
+ };
+ uad {
+ nvidia,pins = "uad";
+ nvidia,function = "spdif";
+ };
+ uca {
+ nvidia,pins = "uca", "ucb";
+ nvidia,function = "uartc";
+ };
+ conf_ata {
+ nvidia,pins = "ata", "atb", "atc", "atd", "ate",
+ "cdev1", "cdev2", "dap1", "dap2", "dtf",
+ "gma", "gmb", "gmc", "gmd", "gme",
+ "gpu", "gpu7", "gpv", "i2cp", "pta",
+ "rm", "sdio1", "slxk", "spdo", "uac",
+ "uda";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_ck32 {
+ nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
+ "pmcc", "pmcd", "pmce", "xm2c", "xm2d";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ };
+ conf_crtp {
+ nvidia,pins = "crtp", "dap3", "dap4", "dtb",
+ "dtc", "dte", "slxa", "slxc", "slxd",
+ "spdi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_csus {
+ nvidia,pins = "csus", "spia", "spib", "spid",
+ "spif";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_ddc {
+ nvidia,pins = "ddc", "irrx", "irtx", "kbca",
+ "kbcb", "kbcc", "kbcd", "kbce", "kbcf",
+ "spic", "spig", "uaa", "uab";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_dta {
+ nvidia,pins = "dta", "dtd", "owc", "sdc", "sdd",
+ "spie", "spih", "uad", "uca", "ucb";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_hdint {
+ nvidia,pins = "hdint", "ld0", "ld1", "ld2",
+ "ld3", "ld4", "ld5", "ld6", "ld7",
+ "ld8", "ld9", "ld10", "ld11", "ld12",
+ "ld13", "ld14", "ld15", "ld16", "ld17",
+ "ldc", "ldi", "lhs", "lsc0", "lspi",
+ "lvs", "pmc";
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_lc {
+ nvidia,pins = "lc", "ls";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ };
+ conf_lcsn {
+ nvidia,pins = "lcsn", "lhp0", "lhp1", "lhp2",
+ "lm0", "lm1", "lpp", "lpw0", "lpw1",
+ "lpw2", "lsc1", "lsck", "lsda", "lsdi",
+ "lvp0", "lvp1", "sdb";
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_ld17_0 {
+ nvidia,pins = "ld17_0", "ld19_18", "ld21_20",
+ "ld23_22";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ };
+ };
+ };
+
+ i2s@70002800 {
+ status = "okay";
+ };
+
+ serial@70006000 {
+ status = "okay";
+ };
+
+ serial@70006200 {
+ status = "okay";
+ };
+
+ pwm: pwm@7000a000 {
+ status = "okay";
+ };
+
+ lvds_ddc: i2c@7000c000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ alc5632: alc5632@1e {
+ compatible = "realtek,alc5632";
+ reg = <0x1e>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ hdmi_ddc: i2c@7000c400 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ nvec@7000c500 {
+ compatible = "nvidia,nvec";
+ reg = <0x7000c500 0x100>;
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <80000>;
+ request-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
+ slave-addr = <138>;
+ clocks = <&tegra_car TEGRA20_CLK_I2C3>,
+ <&tegra_car TEGRA20_CLK_PLL_P_OUT3>;
+ clock-names = "div-clk", "fast-clk";
+ resets = <&tegra_car 67>;
+ reset-names = "i2c";
+ };
+
+ i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ pmic: tps6586x@34 {
+ compatible = "ti,tps6586x";
+ reg = <0x34>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ sys-supply = <&p5valw_reg>;
+ vin-sm0-supply = <&sys_reg>;
+ vin-sm1-supply = <&sys_reg>;
+ vin-sm2-supply = <&sys_reg>;
+ vinldo01-supply = <&sm2_reg>;
+ vinldo23-supply = <&sm2_reg>;
+ vinldo4-supply = <&sm2_reg>;
+ vinldo678-supply = <&sm2_reg>;
+ vinldo9-supply = <&sm2_reg>;
+
+ regulators {
+ sys_reg: sys {
+ regulator-name = "vdd_sys";
+ regulator-always-on;
+ };
+
+ sm0 {
+ regulator-name = "+1.2vs_sm0,vdd_core";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ sm1 {
+ regulator-name = "+1.0vs_sm1,vdd_cpu";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ sm2_reg: sm2 {
+ regulator-name = "+3.7vs_sm2,vin_ldo*";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+ regulator-always-on;
+ };
+
+ /* LDO0 is not connected to anything */
+
+ ldo1 {
+ regulator-name = "+1.1vs_ldo1,avdd_pll*";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ ldo2 {
+ regulator-name = "+1.2vs_ldo2,vdd_rtc";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo3 {
+ regulator-name = "+3.3vs_ldo3,avdd_usb*";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo4 {
+ regulator-name = "+1.8vs_ldo4,avdd_osc,vddio_sys";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo5 {
+ regulator-name = "+2.85vs_ldo5,vcore_mmc";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ };
+
+ ldo6 {
+ /*
+ * Research indicates this should be
+ * 1.8v; other boards that use this
+ * rail for the same purpose need it
+ * set to 1.8v. The schematic signal
+ * name is incorrect; perhaps copied
+ * from an incorrect NVIDIA reference.
+ */
+ regulator-name = "+2.85vs_ldo6,avdd_vdac";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ hdmi_vdd_reg: ldo7 {
+ regulator-name = "+3.3vs_ldo7,avdd_hdmi";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ hdmi_pll_reg: ldo8 {
+ regulator-name = "+1.8vs_ldo8,avdd_hdmi_pll";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo9 {
+ regulator-name = "+2.85vs_ldo9,vdd_ddr_rx";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ };
+
+ ldo_rtc {
+ regulator-name = "+3.3vs_rtc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+
+ pmc@7000e400 {
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <1>;
+ nvidia,cpu-pwr-good-time = <2000>;
+ nvidia,cpu-pwr-off-time = <0>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <0>;
+ nvidia,sys-clock-req-active-high;
+ };
+
+ usb@c5000000 {
+ status = "okay";
+ };
+
+ usb-phy@c5000000 {
+ status = "okay";
+ };
+
+ usb@c5004000 {
+ status = "okay";
+ nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 0)
+ GPIO_ACTIVE_LOW>;
+ };
+
+ usb-phy@c5004000 {
+ status = "okay";
+ nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 0)
+ GPIO_ACTIVE_LOW>;
+ };
+
+ usb@c5008000 {
+ status = "okay";
+ };
+
+ usb-phy@c5008000 {
+ status = "okay";
+ };
+
+ sdhci@c8000000 {
+ status = "okay";
+ cd-gpios = <&gpio TEGRA_GPIO(V, 5) GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
+ power-gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ };
+
+ sdhci@c8000600 {
+ status = "okay";
+ bus-width = <8>;
+ non-removable;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+
+ enable-gpios = <&gpio TEGRA_GPIO(U, 4) GPIO_ACTIVE_HIGH>;
+ pwms = <&pwm 0 5000000>;
+
+ brightness-levels = <0 16 32 48 64 80 96 112 128 144 160 176 192 208 224 240 255>;
+ default-brightness-level = <10>;
+
+ backlight-boot-off;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock@0 {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(J, 7) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ gpio-key,wakeup;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ wifi {
+ label = "wifi-led";
+ gpios = <&gpio TEGRA_GPIO(D, 0) GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "rfkill0";
+ };
+ };
+
+ panel: panel {
+ compatible = "samsung,ltn101nt05", "simple-panel";
+
+ ddc-i2c-bus = <&lvds_ddc>;
+ power-supply = <&vdd_pnl_reg>;
+ enable-gpios = <&gpio TEGRA_GPIO(M, 6) GPIO_ACTIVE_HIGH>;
+
+ backlight = <&backlight>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ p5valw_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "+5valw";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ vdd_pnl_reg: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "+3VS,vdd_pnl";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio TEGRA_GPIO(A, 4) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-alc5632-paz00",
+ "nvidia,tegra-audio-alc5632";
+
+ nvidia,model = "Compal PAZ00";
+
+ nvidia,audio-routing =
+ "Int Spk", "SPKOUT",
+ "Int Spk", "SPKOUTN",
+ "Headset Mic", "MICBIAS1",
+ "MIC1", "Headset Mic",
+ "Headset Stereophone", "HPR",
+ "Headset Stereophone", "HPL",
+ "DMICDAT", "Digital Mic";
+
+ nvidia,audio-codec = <&alc5632>;
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2)
+ GPIO_ACTIVE_HIGH>;
+
+ clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+ <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA20_CLK_CDEV1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
+};
diff --git a/arch/arm/boot/dts/tegra20-plutux.dts b/arch/arm/boot/dts/tegra20-plutux.dts
new file mode 100644
index 000000000..a10b415bb
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20-plutux.dts
@@ -0,0 +1,102 @@
+/dts-v1/;
+
+#include "tegra20-tamonten.dtsi"
+
+/ {
+ model = "Avionic Design Plutux board";
+ compatible = "ad,plutux", "ad,tamonten", "nvidia,tegra20";
+
+ host1x@50000000 {
+ hdmi@54280000 {
+ status = "okay";
+ };
+ };
+
+ i2c@7000c000 {
+ wm8903: wm8903@1a {
+ compatible = "wlf,wm8903";
+ reg = <0x1a>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(X, 3) IRQ_TYPE_LEVEL_HIGH>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ micdet-cfg = <0>;
+ micdet-delay = <100>;
+ gpio-cfg = <0xffffffff
+ 0xffffffff
+ 0
+ 0xffffffff
+ 0xffffffff>;
+ };
+ };
+
+ sound {
+ compatible = "ad,tegra-audio-plutux",
+ "nvidia,tegra-audio-wm8903";
+ nvidia,model = "Avionic Design Plutux";
+
+ nvidia,audio-routing =
+ "Headphone Jack", "HPOUTR",
+ "Headphone Jack", "HPOUTL",
+ "Int Spk", "ROP",
+ "Int Spk", "RON",
+ "Int Spk", "LOP",
+ "Int Spk", "LON",
+ "Mic Jack", "MICBIAS",
+ "IN1L", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&wm8903>;
+
+ nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>;
+ nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>;
+
+ clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+ <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA20_CLK_CDEV1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
+
+ regulators {
+ vcc_24v_reg: regulator@100 {
+ compatible = "regulator-fixed";
+ reg = <100>;
+ regulator-name = "vcc_24v";
+ regulator-min-microvolt = <24000000>;
+ regulator-max-microvolt = <24000000>;
+ regulator-always-on;
+ };
+
+ vdd_5v0_reg: regulator@101 {
+ compatible = "regulator-fixed";
+ reg = <101>;
+ regulator-name = "vdd_5v0";
+ vin-supply = <&vcc_24v_reg>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ vdd_3v3_reg: regulator@102 {
+ compatible = "regulator-fixed";
+ reg = <102>;
+ regulator-name = "vdd_3v3";
+ vin-supply = <&vcc_24v_reg>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_1v8_reg: regulator@103 {
+ compatible = "regulator-fixed";
+ reg = <103>;
+ regulator-name = "vdd_1v8";
+ vin-supply = <&vdd_3v3_reg>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts
new file mode 100644
index 000000000..e2fed2712
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20-seaboard.dts
@@ -0,0 +1,924 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra20.dtsi"
+
+/ {
+ model = "NVIDIA Seaboard";
+ compatible = "nvidia,seaboard", "nvidia,tegra20";
+
+ aliases {
+ rtc0 = "/i2c@7000d000/tps6586x@34";
+ rtc1 = "/rtc@7000e000";
+ serial0 = &uartd;
+ };
+
+ memory {
+ reg = <0x00000000 0x40000000>;
+ };
+
+ host1x@50000000 {
+ dc@54200000 {
+ rgb {
+ status = "okay";
+
+ nvidia,panel = <&panel>;
+ };
+ };
+
+ hdmi@54280000 {
+ status = "okay";
+
+ vdd-supply = <&hdmi_vdd_reg>;
+ pll-supply = <&hdmi_pll_reg>;
+
+ nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+ GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ pinmux@70000014 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ ata {
+ nvidia,pins = "ata";
+ nvidia,function = "ide";
+ };
+ atb {
+ nvidia,pins = "atb", "gma", "gme";
+ nvidia,function = "sdio4";
+ };
+ atc {
+ nvidia,pins = "atc";
+ nvidia,function = "nand";
+ };
+ atd {
+ nvidia,pins = "atd", "ate", "gmb", "spia",
+ "spib", "spic";
+ nvidia,function = "gmi";
+ };
+ cdev1 {
+ nvidia,pins = "cdev1";
+ nvidia,function = "plla_out";
+ };
+ cdev2 {
+ nvidia,pins = "cdev2";
+ nvidia,function = "pllp_out4";
+ };
+ crtp {
+ nvidia,pins = "crtp", "lm1";
+ nvidia,function = "crt";
+ };
+ csus {
+ nvidia,pins = "csus";
+ nvidia,function = "vi_sensor_clk";
+ };
+ dap1 {
+ nvidia,pins = "dap1";
+ nvidia,function = "dap1";
+ };
+ dap2 {
+ nvidia,pins = "dap2";
+ nvidia,function = "dap2";
+ };
+ dap3 {
+ nvidia,pins = "dap3";
+ nvidia,function = "dap3";
+ };
+ dap4 {
+ nvidia,pins = "dap4";
+ nvidia,function = "dap4";
+ };
+ dta {
+ nvidia,pins = "dta", "dtb", "dtc", "dtd", "dte";
+ nvidia,function = "vi";
+ };
+ dtf {
+ nvidia,pins = "dtf";
+ nvidia,function = "i2c3";
+ };
+ gmc {
+ nvidia,pins = "gmc";
+ nvidia,function = "uartd";
+ };
+ gmd {
+ nvidia,pins = "gmd";
+ nvidia,function = "sflash";
+ };
+ gpu {
+ nvidia,pins = "gpu";
+ nvidia,function = "pwm";
+ };
+ gpu7 {
+ nvidia,pins = "gpu7";
+ nvidia,function = "rtck";
+ };
+ gpv {
+ nvidia,pins = "gpv", "slxa", "slxk";
+ nvidia,function = "pcie";
+ };
+ hdint {
+ nvidia,pins = "hdint", "lpw0", "lpw2", "lsc1",
+ "lsck", "lsda";
+ nvidia,function = "hdmi";
+ };
+ i2cp {
+ nvidia,pins = "i2cp";
+ nvidia,function = "i2cp";
+ };
+ irrx {
+ nvidia,pins = "irrx", "irtx";
+ nvidia,function = "uartb";
+ };
+ kbca {
+ nvidia,pins = "kbca", "kbcb", "kbcc", "kbcd",
+ "kbce", "kbcf";
+ nvidia,function = "kbc";
+ };
+ lcsn {
+ nvidia,pins = "lcsn", "ldc", "lm0", "lpw1",
+ "lsdi", "lvp0";
+ nvidia,function = "rsvd4";
+ };
+ ld0 {
+ nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4",
+ "ld5", "ld6", "ld7", "ld8", "ld9",
+ "ld10", "ld11", "ld12", "ld13", "ld14",
+ "ld15", "ld16", "ld17", "ldi", "lhp0",
+ "lhp1", "lhp2", "lhs", "lpp", "lsc0",
+ "lspi", "lvp1", "lvs";
+ nvidia,function = "displaya";
+ };
+ owc {
+ nvidia,pins = "owc", "spdi", "spdo", "uac";
+ nvidia,function = "rsvd2";
+ };
+ pmc {
+ nvidia,pins = "pmc";
+ nvidia,function = "pwr_on";
+ };
+ rm {
+ nvidia,pins = "rm";
+ nvidia,function = "i2c1";
+ };
+ sdb {
+ nvidia,pins = "sdb", "sdc", "sdd";
+ nvidia,function = "sdio3";
+ };
+ sdio1 {
+ nvidia,pins = "sdio1";
+ nvidia,function = "sdio1";
+ };
+ slxc {
+ nvidia,pins = "slxc", "slxd";
+ nvidia,function = "spdif";
+ };
+ spid {
+ nvidia,pins = "spid", "spie", "spif";
+ nvidia,function = "spi1";
+ };
+ spig {
+ nvidia,pins = "spig", "spih";
+ nvidia,function = "spi2_alt";
+ };
+ uaa {
+ nvidia,pins = "uaa", "uab", "uda";
+ nvidia,function = "ulpi";
+ };
+ uad {
+ nvidia,pins = "uad";
+ nvidia,function = "irda";
+ };
+ uca {
+ nvidia,pins = "uca", "ucb";
+ nvidia,function = "uartc";
+ };
+ conf_ata {
+ nvidia,pins = "ata", "atb", "atc", "atd",
+ "cdev1", "cdev2", "dap1", "dap2",
+ "dap4", "ddc", "dtf", "gma", "gmc", "gmd",
+ "gme", "gpu", "gpu7", "i2cp", "irrx",
+ "irtx", "pta", "rm", "sdc", "sdd",
+ "slxd", "slxk", "spdi", "spdo", "uac",
+ "uad", "uca", "ucb", "uda";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_ate {
+ nvidia,pins = "ate", "csus", "dap3",
+ "gpv", "owc", "slxc", "spib", "spid",
+ "spie";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_ck32 {
+ nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
+ "pmcc", "pmcd", "pmce", "xm2c", "xm2d";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ };
+ conf_crtp {
+ nvidia,pins = "crtp", "gmb", "slxa", "spia",
+ "spig", "spih";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_dta {
+ nvidia,pins = "dta", "dtb", "dtc", "dtd";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_dte {
+ nvidia,pins = "dte", "spif";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_hdint {
+ nvidia,pins = "hdint", "lcsn", "ldc", "lm1",
+ "lpw1", "lsc1", "lsck", "lsda", "lsdi",
+ "lvp0";
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_kbca {
+ nvidia,pins = "kbca", "kbcb", "kbcc", "kbcd",
+ "kbce", "kbcf", "sdio1", "spic", "uaa",
+ "uab";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_lc {
+ nvidia,pins = "lc", "ls";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ };
+ conf_ld0 {
+ nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4",
+ "ld5", "ld6", "ld7", "ld8", "ld9",
+ "ld10", "ld11", "ld12", "ld13", "ld14",
+ "ld15", "ld16", "ld17", "ldi", "lhp0",
+ "lhp1", "lhp2", "lhs", "lm0", "lpp",
+ "lpw0", "lpw2", "lsc0", "lspi", "lvp1",
+ "lvs", "pmc", "sdb";
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_ld17_0 {
+ nvidia,pins = "ld17_0", "ld19_18", "ld21_20",
+ "ld23_22";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ };
+ drive_sdio1 {
+ nvidia,pins = "drive_sdio1";
+ nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
+ nvidia,pull-down-strength = <31>;
+ nvidia,pull-up-strength = <31>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
+ };
+ };
+
+ state_i2cmux_ddc: pinmux_i2cmux_ddc {
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "i2c2";
+ };
+ pta {
+ nvidia,pins = "pta";
+ nvidia,function = "rsvd4";
+ };
+ };
+
+ state_i2cmux_pta: pinmux_i2cmux_pta {
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "rsvd4";
+ };
+ pta {
+ nvidia,pins = "pta";
+ nvidia,function = "i2c2";
+ };
+ };
+
+ state_i2cmux_idle: pinmux_i2cmux_idle {
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "rsvd4";
+ };
+ pta {
+ nvidia,pins = "pta";
+ nvidia,function = "rsvd4";
+ };
+ };
+ };
+
+ i2s@70002800 {
+ status = "okay";
+ };
+
+ serial@70006300 {
+ status = "okay";
+ };
+
+ pwm: pwm@7000a000 {
+ status = "okay";
+ };
+
+ i2c@7000c000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ wm8903: wm8903@1a {
+ compatible = "wlf,wm8903";
+ reg = <0x1a>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(X, 3) IRQ_TYPE_LEVEL_HIGH>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ micdet-cfg = <0>;
+ micdet-delay = <100>;
+ gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>;
+ };
+
+ /* ALS and proximity sensor */
+ isl29018@44 {
+ compatible = "isil,isl29018";
+ reg = <0x44>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(Z, 2) IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gyrometer@68 {
+ compatible = "invn,mpu3050";
+ reg = <0x68>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(Z, 4) IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ i2c@7000c400 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2cmux {
+ compatible = "i2c-mux-pinctrl";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c-parent = <&{/i2c@7000c400}>;
+
+ pinctrl-names = "ddc", "pta", "idle";
+ pinctrl-0 = <&state_i2cmux_ddc>;
+ pinctrl-1 = <&state_i2cmux_pta>;
+ pinctrl-2 = <&state_i2cmux_idle>;
+
+ hdmi_ddc: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ lvds_ddc: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ smart-battery@b {
+ compatible = "ti,bq20z75", "smart-battery-1.1";
+ reg = <0xb>;
+ ti,i2c-retry-count = <2>;
+ ti,poll-retry-count = <10>;
+ };
+ };
+ };
+
+ i2c@7000c500 {
+ status = "okay";
+ clock-frequency = <400000>;
+ };
+
+ i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ magnetometer@c {
+ compatible = "asahi-kasei,ak8975";
+ reg = <0xc>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(N, 5) IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pmic: tps6586x@34 {
+ compatible = "ti,tps6586x";
+ reg = <0x34>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+
+ ti,system-power-controller;
+
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ sys-supply = <&vdd_5v0_reg>;
+ vin-sm0-supply = <&sys_reg>;
+ vin-sm1-supply = <&sys_reg>;
+ vin-sm2-supply = <&sys_reg>;
+ vinldo01-supply = <&sm2_reg>;
+ vinldo23-supply = <&sm2_reg>;
+ vinldo4-supply = <&sm2_reg>;
+ vinldo678-supply = <&sm2_reg>;
+ vinldo9-supply = <&sm2_reg>;
+
+ regulators {
+ sys_reg: sys {
+ regulator-name = "vdd_sys";
+ regulator-always-on;
+ };
+
+ sm0 {
+ regulator-name = "vdd_sm0,vdd_core";
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ };
+
+ sm1 {
+ regulator-name = "vdd_sm1,vdd_cpu";
+ regulator-min-microvolt = <1125000>;
+ regulator-max-microvolt = <1125000>;
+ regulator-always-on;
+ };
+
+ sm2_reg: sm2 {
+ regulator-name = "vdd_sm2,vin_ldo*";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+ regulator-always-on;
+ };
+
+ /* LDO0 is not connected to anything */
+
+ ldo1 {
+ regulator-name = "vdd_ldo1,avdd_pll*";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ ldo2 {
+ regulator-name = "vdd_ldo2,vdd_rtc";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo3 {
+ regulator-name = "vdd_ldo3,avdd_usb*";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo4 {
+ regulator-name = "vdd_ldo4,avdd_osc,vddio_sys";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo5 {
+ regulator-name = "vdd_ldo5,vcore_mmc";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ };
+
+ ldo6 {
+ regulator-name = "vdd_ldo6,avdd_vdac,vddio_vi,vddio_cam";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ hdmi_vdd_reg: ldo7 {
+ regulator-name = "vdd_ldo7,avdd_hdmi,vdd_fuse";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ hdmi_pll_reg: ldo8 {
+ regulator-name = "vdd_ldo8,avdd_hdmi_pll";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo9 {
+ regulator-name = "vdd_ldo9,avdd_2v85,vdd_ddr_rx";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ };
+
+ ldo_rtc {
+ regulator-name = "vdd_rtc_out,vdd_cell";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ temperature-sensor@4c {
+ compatible = "onnn,nct1008";
+ reg = <0x4c>;
+ };
+ };
+
+ kbc@7000e200 {
+ status = "okay";
+ nvidia,debounce-delay-ms = <32>;
+ nvidia,repeat-delay-ms = <160>;
+ nvidia,ghost-filter;
+ nvidia,kbc-row-pins = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
+ nvidia,kbc-col-pins = <16 17 18 19 20 21 22 23>;
+ linux,keymap = <MATRIX_KEY(0x00, 0x02, KEY_W)
+ MATRIX_KEY(0x00, 0x03, KEY_S)
+ MATRIX_KEY(0x00, 0x04, KEY_A)
+ MATRIX_KEY(0x00, 0x05, KEY_Z)
+ MATRIX_KEY(0x00, 0x07, KEY_FN)
+
+ MATRIX_KEY(0x01, 0x07, KEY_LEFTMETA)
+ MATRIX_KEY(0x02, 0x06, KEY_RIGHTALT)
+ MATRIX_KEY(0x02, 0x07, KEY_LEFTALT)
+
+ MATRIX_KEY(0x03, 0x00, KEY_5)
+ MATRIX_KEY(0x03, 0x01, KEY_4)
+ MATRIX_KEY(0x03, 0x02, KEY_R)
+ MATRIX_KEY(0x03, 0x03, KEY_E)
+ MATRIX_KEY(0x03, 0x04, KEY_F)
+ MATRIX_KEY(0x03, 0x05, KEY_D)
+ MATRIX_KEY(0x03, 0x06, KEY_X)
+
+ MATRIX_KEY(0x04, 0x00, KEY_7)
+ MATRIX_KEY(0x04, 0x01, KEY_6)
+ MATRIX_KEY(0x04, 0x02, KEY_T)
+ MATRIX_KEY(0x04, 0x03, KEY_H)
+ MATRIX_KEY(0x04, 0x04, KEY_G)
+ MATRIX_KEY(0x04, 0x05, KEY_V)
+ MATRIX_KEY(0x04, 0x06, KEY_C)
+ MATRIX_KEY(0x04, 0x07, KEY_SPACE)
+
+ MATRIX_KEY(0x05, 0x00, KEY_9)
+ MATRIX_KEY(0x05, 0x01, KEY_8)
+ MATRIX_KEY(0x05, 0x02, KEY_U)
+ MATRIX_KEY(0x05, 0x03, KEY_Y)
+ MATRIX_KEY(0x05, 0x04, KEY_J)
+ MATRIX_KEY(0x05, 0x05, KEY_N)
+ MATRIX_KEY(0x05, 0x06, KEY_B)
+ MATRIX_KEY(0x05, 0x07, KEY_BACKSLASH)
+
+ MATRIX_KEY(0x06, 0x00, KEY_MINUS)
+ MATRIX_KEY(0x06, 0x01, KEY_0)
+ MATRIX_KEY(0x06, 0x02, KEY_O)
+ MATRIX_KEY(0x06, 0x03, KEY_I)
+ MATRIX_KEY(0x06, 0x04, KEY_L)
+ MATRIX_KEY(0x06, 0x05, KEY_K)
+ MATRIX_KEY(0x06, 0x06, KEY_COMMA)
+ MATRIX_KEY(0x06, 0x07, KEY_M)
+
+ MATRIX_KEY(0x07, 0x01, KEY_EQUAL)
+ MATRIX_KEY(0x07, 0x02, KEY_RIGHTBRACE)
+ MATRIX_KEY(0x07, 0x03, KEY_ENTER)
+ MATRIX_KEY(0x07, 0x07, KEY_MENU)
+
+ MATRIX_KEY(0x08, 0x04, KEY_RIGHTSHIFT)
+ MATRIX_KEY(0x08, 0x05, KEY_LEFTSHIFT)
+
+ MATRIX_KEY(0x09, 0x05, KEY_RIGHTCTRL)
+ MATRIX_KEY(0x09, 0x07, KEY_LEFTCTRL)
+
+ MATRIX_KEY(0x0B, 0x00, KEY_LEFTBRACE)
+ MATRIX_KEY(0x0B, 0x01, KEY_P)
+ MATRIX_KEY(0x0B, 0x02, KEY_APOSTROPHE)
+ MATRIX_KEY(0x0B, 0x03, KEY_SEMICOLON)
+ MATRIX_KEY(0x0B, 0x04, KEY_SLASH)
+ MATRIX_KEY(0x0B, 0x05, KEY_DOT)
+
+ MATRIX_KEY(0x0C, 0x00, KEY_F10)
+ MATRIX_KEY(0x0C, 0x01, KEY_F9)
+ MATRIX_KEY(0x0C, 0x02, KEY_BACKSPACE)
+ MATRIX_KEY(0x0C, 0x03, KEY_3)
+ MATRIX_KEY(0x0C, 0x04, KEY_2)
+ MATRIX_KEY(0x0C, 0x05, KEY_UP)
+ MATRIX_KEY(0x0C, 0x06, KEY_PRINT)
+ MATRIX_KEY(0x0C, 0x07, KEY_PAUSE)
+
+ MATRIX_KEY(0x0D, 0x00, KEY_INSERT)
+ MATRIX_KEY(0x0D, 0x01, KEY_DELETE)
+ MATRIX_KEY(0x0D, 0x03, KEY_PAGEUP )
+ MATRIX_KEY(0x0D, 0x04, KEY_PAGEDOWN)
+ MATRIX_KEY(0x0D, 0x05, KEY_RIGHT)
+ MATRIX_KEY(0x0D, 0x06, KEY_DOWN)
+ MATRIX_KEY(0x0D, 0x07, KEY_LEFT)
+
+ MATRIX_KEY(0x0E, 0x00, KEY_F11)
+ MATRIX_KEY(0x0E, 0x01, KEY_F12)
+ MATRIX_KEY(0x0E, 0x02, KEY_F8)
+ MATRIX_KEY(0x0E, 0x03, KEY_Q)
+ MATRIX_KEY(0x0E, 0x04, KEY_F4)
+ MATRIX_KEY(0x0E, 0x05, KEY_F3)
+ MATRIX_KEY(0x0E, 0x06, KEY_1)
+ MATRIX_KEY(0x0E, 0x07, KEY_F7)
+
+ MATRIX_KEY(0x0F, 0x00, KEY_ESC)
+ MATRIX_KEY(0x0F, 0x01, KEY_GRAVE)
+ MATRIX_KEY(0x0F, 0x02, KEY_F5)
+ MATRIX_KEY(0x0F, 0x03, KEY_TAB)
+ MATRIX_KEY(0x0F, 0x04, KEY_F1)
+ MATRIX_KEY(0x0F, 0x05, KEY_F2)
+ MATRIX_KEY(0x0F, 0x06, KEY_CAPSLOCK)
+ MATRIX_KEY(0x0F, 0x07, KEY_F6)
+
+ /* Software Handled Function Keys */
+ MATRIX_KEY(0x14, 0x00, KEY_KP7)
+
+ MATRIX_KEY(0x15, 0x00, KEY_KP9)
+ MATRIX_KEY(0x15, 0x01, KEY_KP8)
+ MATRIX_KEY(0x15, 0x02, KEY_KP4)
+ MATRIX_KEY(0x15, 0x04, KEY_KP1)
+
+ MATRIX_KEY(0x16, 0x01, KEY_KPSLASH)
+ MATRIX_KEY(0x16, 0x02, KEY_KP6)
+ MATRIX_KEY(0x16, 0x03, KEY_KP5)
+ MATRIX_KEY(0x16, 0x04, KEY_KP3)
+ MATRIX_KEY(0x16, 0x05, KEY_KP2)
+ MATRIX_KEY(0x16, 0x07, KEY_KP0)
+
+ MATRIX_KEY(0x1B, 0x01, KEY_KPASTERISK)
+ MATRIX_KEY(0x1B, 0x03, KEY_KPMINUS)
+ MATRIX_KEY(0x1B, 0x04, KEY_KPPLUS)
+ MATRIX_KEY(0x1B, 0x05, KEY_KPDOT)
+
+ MATRIX_KEY(0x1C, 0x05, KEY_VOLUMEUP)
+
+ MATRIX_KEY(0x1D, 0x03, KEY_HOME)
+ MATRIX_KEY(0x1D, 0x04, KEY_END)
+ MATRIX_KEY(0x1D, 0x05, KEY_BRIGHTNESSDOWN)
+ MATRIX_KEY(0x1D, 0x06, KEY_VOLUMEDOWN)
+ MATRIX_KEY(0x1D, 0x07, KEY_BRIGHTNESSUP)
+
+ MATRIX_KEY(0x1E, 0x00, KEY_NUMLOCK)
+ MATRIX_KEY(0x1E, 0x01, KEY_SCROLLLOCK)
+ MATRIX_KEY(0x1E, 0x02, KEY_MUTE)
+
+ MATRIX_KEY(0x1F, 0x04, KEY_HELP)>;
+ };
+
+ pmc@7000e400 {
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <1>;
+ nvidia,cpu-pwr-good-time = <5000>;
+ nvidia,cpu-pwr-off-time = <5000>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <3875>;
+ nvidia,sys-clock-req-active-high;
+ };
+
+ memory-controller@7000f400 {
+ emc-table@190000 {
+ reg = <190000>;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = <190000>;
+ nvidia,emc-registers = <0x0000000c 0x00000026
+ 0x00000009 0x00000003 0x00000004 0x00000004
+ 0x00000002 0x0000000c 0x00000003 0x00000003
+ 0x00000002 0x00000001 0x00000004 0x00000005
+ 0x00000004 0x00000009 0x0000000d 0x0000059f
+ 0x00000000 0x00000003 0x00000003 0x00000003
+ 0x00000003 0x00000001 0x0000000b 0x000000c8
+ 0x00000003 0x00000007 0x00000004 0x0000000f
+ 0x00000002 0x00000000 0x00000000 0x00000002
+ 0x00000000 0x00000000 0x00000083 0xa06204ae
+ 0x007dc010 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000>;
+ };
+
+ emc-table@380000 {
+ reg = <380000>;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = <380000>;
+ nvidia,emc-registers = <0x00000017 0x0000004b
+ 0x00000012 0x00000006 0x00000004 0x00000005
+ 0x00000003 0x0000000c 0x00000006 0x00000006
+ 0x00000003 0x00000001 0x00000004 0x00000005
+ 0x00000004 0x00000009 0x0000000d 0x00000b5f
+ 0x00000000 0x00000003 0x00000003 0x00000006
+ 0x00000006 0x00000001 0x00000011 0x000000c8
+ 0x00000003 0x0000000e 0x00000007 0x0000000f
+ 0x00000002 0x00000000 0x00000000 0x00000002
+ 0x00000000 0x00000000 0x00000083 0xe044048b
+ 0x007d8010 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000>;
+ };
+ };
+
+ usb@c5000000 {
+ status = "okay";
+ dr_mode = "otg";
+ };
+
+ usb-phy@c5000000 {
+ status = "okay";
+ vbus-supply = <&vbus_reg>;
+ dr_mode = "otg";
+ };
+
+ usb@c5004000 {
+ status = "okay";
+ nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+ GPIO_ACTIVE_LOW>;
+ };
+
+ usb-phy@c5004000 {
+ status = "okay";
+ nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+ GPIO_ACTIVE_LOW>;
+ };
+
+ usb@c5008000 {
+ status = "okay";
+ };
+
+ usb-phy@c5008000 {
+ status = "okay";
+ };
+
+ sdhci@c8000000 {
+ status = "okay";
+ power-gpios = <&gpio TEGRA_GPIO(K, 6) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ keep-power-in-suspend;
+ };
+
+ sdhci@c8000400 {
+ status = "okay";
+ cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
+ power-gpios = <&gpio TEGRA_GPIO(I, 6) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ };
+
+ sdhci@c8000600 {
+ status = "okay";
+ bus-width = <8>;
+ non-removable;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+
+ enable-gpios = <&gpio TEGRA_GPIO(D, 4) GPIO_ACTIVE_HIGH>;
+ power-supply = <&vdd_bl_reg>;
+ pwms = <&pwm 2 5000000>;
+
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock@0 {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ gpio-key,wakeup;
+ };
+
+ lid {
+ label = "Lid";
+ gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_HIGH>;
+ linux,input-type = <5>; /* EV_SW */
+ linux,code = <0>; /* SW_LID */
+ debounce-interval = <1>;
+ gpio-key,wakeup;
+ };
+ };
+
+ panel: panel {
+ compatible = "chunghwa,claa101wa01a", "simple-panel";
+
+ power-supply = <&vdd_pnl_reg>;
+ enable-gpios = <&gpio TEGRA_GPIO(B, 2) GPIO_ACTIVE_HIGH>;
+
+ backlight = <&backlight>;
+ ddc-i2c-bus = <&lvds_ddc>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdd_5v0_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vdd_5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "vdd_1v5";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ gpio = <&pmic 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "vdd_1v2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ gpio = <&pmic 1 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vbus_reg: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "vdd_vbus_wup1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(D, 0) 0>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_pnl_reg: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "vdd_pnl";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpio TEGRA_GPIO(C, 6) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vdd_bl_reg: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "vdd_bl";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpio TEGRA_GPIO(W, 0) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-wm8903-seaboard",
+ "nvidia,tegra-audio-wm8903";
+ nvidia,model = "NVIDIA Tegra Seaboard";
+
+ nvidia,audio-routing =
+ "Headphone Jack", "HPOUTR",
+ "Headphone Jack", "HPOUTL",
+ "Int Spk", "ROP",
+ "Int Spk", "RON",
+ "Int Spk", "LOP",
+ "Int Spk", "LON",
+ "Mic Jack", "MICBIAS",
+ "IN1R", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&wm8903>;
+
+ nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>;
+ nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(X, 1) GPIO_ACTIVE_HIGH>;
+
+ clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+ <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA20_CLK_CDEV1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
+};
diff --git a/arch/arm/boot/dts/tegra20-tamonten.dtsi b/arch/arm/boot/dts/tegra20-tamonten.dtsi
new file mode 100644
index 000000000..13d4e6185
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20-tamonten.dtsi
@@ -0,0 +1,529 @@
+#include "tegra20.dtsi"
+
+/ {
+ model = "Avionic Design Tamonten SOM";
+ compatible = "ad,tamonten", "nvidia,tegra20";
+
+ aliases {
+ rtc0 = "/i2c@7000d000/tps6586x@34";
+ rtc1 = "/rtc@7000e000";
+ serial0 = &uartd;
+ };
+
+ memory {
+ reg = <0x00000000 0x20000000>;
+ };
+
+ host1x@50000000 {
+ hdmi@54280000 {
+ vdd-supply = <&hdmi_vdd_reg>;
+ pll-supply = <&hdmi_pll_reg>;
+
+ nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+ GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ pinmux@70000014 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ ata {
+ nvidia,pins = "ata";
+ nvidia,function = "ide";
+ };
+ atb {
+ nvidia,pins = "atb", "gma", "gme";
+ nvidia,function = "sdio4";
+ };
+ atc {
+ nvidia,pins = "atc";
+ nvidia,function = "nand";
+ };
+ atd {
+ nvidia,pins = "atd", "ate", "gmb", "gmd", "gpu",
+ "spia", "spib", "spic";
+ nvidia,function = "gmi";
+ };
+ cdev1 {
+ nvidia,pins = "cdev1";
+ nvidia,function = "plla_out";
+ };
+ cdev2 {
+ nvidia,pins = "cdev2";
+ nvidia,function = "pllp_out4";
+ };
+ crtp {
+ nvidia,pins = "crtp";
+ nvidia,function = "crt";
+ };
+ csus {
+ nvidia,pins = "csus";
+ nvidia,function = "vi_sensor_clk";
+ };
+ dap1 {
+ nvidia,pins = "dap1";
+ nvidia,function = "dap1";
+ };
+ dap2 {
+ nvidia,pins = "dap2";
+ nvidia,function = "dap2";
+ };
+ dap3 {
+ nvidia,pins = "dap3";
+ nvidia,function = "dap3";
+ };
+ dap4 {
+ nvidia,pins = "dap4";
+ nvidia,function = "dap4";
+ };
+ dta {
+ nvidia,pins = "dta", "dtd";
+ nvidia,function = "sdio2";
+ };
+ dtb {
+ nvidia,pins = "dtb", "dtc", "dte";
+ nvidia,function = "rsvd1";
+ };
+ dtf {
+ nvidia,pins = "dtf";
+ nvidia,function = "i2c3";
+ };
+ gmc {
+ nvidia,pins = "gmc";
+ nvidia,function = "uartd";
+ };
+ gpu7 {
+ nvidia,pins = "gpu7";
+ nvidia,function = "rtck";
+ };
+ gpv {
+ nvidia,pins = "gpv", "slxa", "slxk";
+ nvidia,function = "pcie";
+ };
+ hdint {
+ nvidia,pins = "hdint";
+ nvidia,function = "hdmi";
+ };
+ i2cp {
+ nvidia,pins = "i2cp";
+ nvidia,function = "i2cp";
+ };
+ irrx {
+ nvidia,pins = "irrx", "irtx";
+ nvidia,function = "uarta";
+ };
+ kbca {
+ nvidia,pins = "kbca", "kbcb", "kbcc", "kbcd",
+ "kbce", "kbcf";
+ nvidia,function = "kbc";
+ };
+ lcsn {
+ nvidia,pins = "lcsn", "ld0", "ld1", "ld2",
+ "ld3", "ld4", "ld5", "ld6", "ld7",
+ "ld8", "ld9", "ld10", "ld11", "ld12",
+ "ld13", "ld14", "ld15", "ld16", "ld17",
+ "ldc", "ldi", "lhp0", "lhp1", "lhp2",
+ "lhs", "lm0", "lm1", "lpp", "lpw0",
+ "lpw1", "lpw2", "lsc0", "lsc1", "lsck",
+ "lsda", "lsdi", "lspi", "lvp0", "lvp1",
+ "lvs";
+ nvidia,function = "displaya";
+ };
+ owc {
+ nvidia,pins = "owc", "spdi", "spdo", "uac";
+ nvidia,function = "rsvd2";
+ };
+ pmc {
+ nvidia,pins = "pmc";
+ nvidia,function = "pwr_on";
+ };
+ rm {
+ nvidia,pins = "rm";
+ nvidia,function = "i2c1";
+ };
+ sdb {
+ nvidia,pins = "sdb", "sdc", "sdd";
+ nvidia,function = "pwm";
+ };
+ sdio1 {
+ nvidia,pins = "sdio1";
+ nvidia,function = "sdio1";
+ };
+ slxc {
+ nvidia,pins = "slxc", "slxd";
+ nvidia,function = "spdif";
+ };
+ spid {
+ nvidia,pins = "spid", "spie", "spif";
+ nvidia,function = "spi1";
+ };
+ spig {
+ nvidia,pins = "spig", "spih";
+ nvidia,function = "spi2_alt";
+ };
+ uaa {
+ nvidia,pins = "uaa", "uab", "uda";
+ nvidia,function = "ulpi";
+ };
+ uad {
+ nvidia,pins = "uad";
+ nvidia,function = "irda";
+ };
+ uca {
+ nvidia,pins = "uca", "ucb";
+ nvidia,function = "uartc";
+ };
+ conf_ata {
+ nvidia,pins = "ata", "atb", "atc", "atd", "ate",
+ "cdev1", "cdev2", "dap1", "dtb", "gma",
+ "gmb", "gmc", "gmd", "gme", "gpu7",
+ "gpv", "i2cp", "pta", "rm", "slxa",
+ "slxk", "spia", "spib", "uac";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_ck32 {
+ nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
+ "pmcc", "pmcd", "pmce", "xm2c", "xm2d";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ };
+ conf_csus {
+ nvidia,pins = "csus", "spid", "spif";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_crtp {
+ nvidia,pins = "crtp", "dap2", "dap3", "dap4",
+ "dtc", "dte", "dtf", "gpu", "sdio1",
+ "slxc", "slxd", "spdi", "spdo", "spig",
+ "uda";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_ddc {
+ nvidia,pins = "ddc", "dta", "dtd", "kbca",
+ "kbcb", "kbcc", "kbcd", "kbce", "kbcf",
+ "sdc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_hdint {
+ nvidia,pins = "hdint", "lcsn", "ldc", "lm1",
+ "lpw1", "lsc1", "lsck", "lsda", "lsdi",
+ "lvp0", "owc", "sdb";
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_irrx {
+ nvidia,pins = "irrx", "irtx", "sdd", "spic",
+ "spie", "spih", "uaa", "uab", "uad",
+ "uca", "ucb";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_lc {
+ nvidia,pins = "lc", "ls";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ };
+ conf_ld0 {
+ nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4",
+ "ld5", "ld6", "ld7", "ld8", "ld9",
+ "ld10", "ld11", "ld12", "ld13", "ld14",
+ "ld15", "ld16", "ld17", "ldi", "lhp0",
+ "lhp1", "lhp2", "lhs", "lm0", "lpp",
+ "lpw0", "lpw2", "lsc0", "lspi", "lvp1",
+ "lvs", "pmc";
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_ld17_0 {
+ nvidia,pins = "ld17_0", "ld19_18", "ld21_20",
+ "ld23_22";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ };
+ };
+
+ state_i2cmux_ddc: pinmux_i2cmux_ddc {
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "i2c2";
+ };
+ pta {
+ nvidia,pins = "pta";
+ nvidia,function = "rsvd4";
+ };
+ };
+
+ state_i2cmux_pta: pinmux_i2cmux_pta {
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "rsvd4";
+ };
+ pta {
+ nvidia,pins = "pta";
+ nvidia,function = "i2c2";
+ };
+ };
+
+ state_i2cmux_idle: pinmux_i2cmux_idle {
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "rsvd4";
+ };
+ pta {
+ nvidia,pins = "pta";
+ nvidia,function = "rsvd4";
+ };
+ };
+ };
+
+ i2s@70002800 {
+ status = "okay";
+ };
+
+ serial@70006300 {
+ status = "okay";
+ };
+
+ i2c@7000c000 {
+ clock-frequency = <400000>;
+ status = "okay";
+ };
+
+ i2c@7000c400 {
+ clock-frequency = <100000>;
+ status = "okay";
+ };
+
+ i2cmux {
+ compatible = "i2c-mux-pinctrl";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c-parent = <&{/i2c@7000c400}>;
+
+ pinctrl-names = "ddc", "pta", "idle";
+ pinctrl-0 = <&state_i2cmux_ddc>;
+ pinctrl-1 = <&state_i2cmux_pta>;
+ pinctrl-2 = <&state_i2cmux_idle>;
+
+ hdmi_ddc: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ i2c@7000d000 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ pmic: tps6586x@34 {
+ compatible = "ti,tps6586x";
+ reg = <0x34>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+
+ ti,system-power-controller;
+
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ /* vdd_5v0_reg must be provided by the base board */
+ sys-supply = <&vdd_5v0_reg>;
+ vin-sm0-supply = <&sys_reg>;
+ vin-sm1-supply = <&sys_reg>;
+ vin-sm2-supply = <&sys_reg>;
+ vinldo01-supply = <&sm2_reg>;
+ vinldo23-supply = <&sm2_reg>;
+ vinldo4-supply = <&sm2_reg>;
+ vinldo678-supply = <&sm2_reg>;
+ vinldo9-supply = <&sm2_reg>;
+
+ regulators {
+ sys_reg: sys {
+ regulator-name = "vdd_sys";
+ regulator-always-on;
+ };
+
+ sm0 {
+ regulator-name = "vdd_sys_sm0,vdd_core";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ sm1 {
+ regulator-name = "vdd_sys_sm1,vdd_cpu";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ sm2_reg: sm2 {
+ regulator-name = "vdd_sys_sm2,vin_ldo*";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+ regulator-always-on;
+ };
+
+ pci_clk_reg: ldo0 {
+ regulator-name = "vdd_ldo0,vddio_pex_clk";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo1 {
+ regulator-name = "vdd_ldo1,avdd_pll*";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ ldo2 {
+ regulator-name = "vdd_ldo2,vdd_rtc";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo3 {
+ regulator-name = "vdd_ldo3,avdd_usb*";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo4 {
+ regulator-name = "vdd_ldo4,avdd_osc,vddio_sys";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo5 {
+ regulator-name = "vdd_ldo5,vcore_mmc";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ ldo6 {
+ regulator-name = "vdd_ldo6,avdd_vdac";
+ /*
+ * According to the Tegra 2 Automotive
+ * DataSheet, a typical value for this
+ * would be 2.8V, but the PMIC only
+ * supports 2.85V.
+ */
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ hdmi_vdd_reg: ldo7 {
+ regulator-name = "vdd_ldo7,avdd_hdmi";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ hdmi_pll_reg: ldo8 {
+ regulator-name = "vdd_ldo8,avdd_hdmi_pll";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo9 {
+ regulator-name = "vdd_ldo9,vdd_ddr_rx,avdd_cam";
+ /*
+ * According to the Tegra 2 Automotive
+ * DataSheet, a typical value for this
+ * would be 2.8V, but the PMIC only
+ * supports 2.85V.
+ */
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ };
+
+ ldo_rtc {
+ regulator-name = "vdd_rtc_out";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ temperature-sensor@4c {
+ compatible = "onnn,nct1008";
+ reg = <0x4c>;
+ };
+ };
+
+ pmc@7000e400 {
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <1>;
+ nvidia,cpu-pwr-good-time = <5000>;
+ nvidia,cpu-pwr-off-time = <5000>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <3875>;
+ nvidia,sys-clock-req-active-high;
+ };
+
+ pcie-controller@80003000 {
+ avdd-pex-supply = <&pci_vdd_reg>;
+ vdd-pex-supply = <&pci_vdd_reg>;
+ avdd-pex-pll-supply = <&pci_vdd_reg>;
+ avdd-plle-supply = <&pci_vdd_reg>;
+ vddio-pex-clk-supply = <&pci_clk_reg>;
+ };
+
+ usb@c5008000 {
+ status = "okay";
+ };
+
+ usb-phy@c5008000 {
+ status = "okay";
+ };
+
+ sdhci@c8000600 {
+ cd-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ status = "okay";
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock@0 {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pci_vdd_reg: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "vdd_1v05";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ gpio = <&pmic 2 0>;
+ enable-active-high;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra20-tec.dts b/arch/arm/boot/dts/tegra20-tec.dts
new file mode 100644
index 000000000..c12d8bead
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20-tec.dts
@@ -0,0 +1,111 @@
+/dts-v1/;
+
+#include "tegra20-tamonten.dtsi"
+
+/ {
+ model = "Avionic Design Tamonten Evaluation Carrier";
+ compatible = "ad,tec", "ad,tamonten", "nvidia,tegra20";
+
+ host1x@50000000 {
+ hdmi@54280000 {
+ status = "okay";
+ };
+ };
+
+ i2c@7000c000 {
+ wm8903: wm8903@1a {
+ compatible = "wlf,wm8903";
+ reg = <0x1a>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(X, 3) IRQ_TYPE_LEVEL_HIGH>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ micdet-cfg = <0>;
+ micdet-delay = <100>;
+ gpio-cfg = <0xffffffff
+ 0xffffffff
+ 0
+ 0xffffffff
+ 0xffffffff>;
+ };
+ };
+
+ pcie-controller@80003000 {
+ status = "okay";
+
+ pci@1,0 {
+ status = "okay";
+ };
+ };
+
+ sound {
+ compatible = "ad,tegra-audio-wm8903-tec",
+ "nvidia,tegra-audio-wm8903";
+ nvidia,model = "Avionic Design TEC";
+
+ nvidia,audio-routing =
+ "Headphone Jack", "HPOUTR",
+ "Headphone Jack", "HPOUTL",
+ "Int Spk", "ROP",
+ "Int Spk", "RON",
+ "Int Spk", "LOP",
+ "Int Spk", "LON",
+ "Mic Jack", "MICBIAS",
+ "IN1L", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&wm8903>;
+
+ nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>;
+ nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2)
+ GPIO_ACTIVE_HIGH>;
+
+ clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+ <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA20_CLK_CDEV1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
+
+ regulators {
+ vcc_24v_reg: regulator@100 {
+ compatible = "regulator-fixed";
+ reg = <100>;
+ regulator-name = "vcc_24v";
+ regulator-min-microvolt = <24000000>;
+ regulator-max-microvolt = <24000000>;
+ regulator-always-on;
+ };
+
+ vdd_5v0_reg: regulator@101 {
+ compatible = "regulator-fixed";
+ reg = <101>;
+ regulator-name = "vdd_5v0";
+ vin-supply = <&vcc_24v_reg>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ vdd_3v3_reg: regulator@102 {
+ compatible = "regulator-fixed";
+ reg = <102>;
+ regulator-name = "vdd_3v3";
+ vin-supply = <&vcc_24v_reg>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_1v8_reg: regulator@103 {
+ compatible = "regulator-fixed";
+ reg = <103>;
+ regulator-name = "vdd_1v8";
+ vin-supply = <&vdd_3v3_reg>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra20-trimslice.dts b/arch/arm/boot/dts/tegra20-trimslice.dts
new file mode 100644
index 000000000..d99af4ef9
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20-trimslice.dts
@@ -0,0 +1,468 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra20.dtsi"
+
+/ {
+ model = "Compulab TrimSlice board";
+ compatible = "compulab,trimslice", "nvidia,tegra20";
+
+ aliases {
+ rtc0 = "/i2c@7000c500/rtc@56";
+ rtc1 = "/rtc@7000e000";
+ serial0 = &uarta;
+ };
+
+ memory {
+ reg = <0x00000000 0x40000000>;
+ };
+
+ host1x@50000000 {
+ hdmi@54280000 {
+ status = "okay";
+
+ vdd-supply = <&hdmi_vdd_reg>;
+ pll-supply = <&hdmi_pll_reg>;
+
+ nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+ GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ pinmux@70000014 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ ata {
+ nvidia,pins = "ata";
+ nvidia,function = "ide";
+ };
+ atb {
+ nvidia,pins = "atb", "gma";
+ nvidia,function = "sdio4";
+ };
+ atc {
+ nvidia,pins = "atc", "gmb";
+ nvidia,function = "nand";
+ };
+ atd {
+ nvidia,pins = "atd", "ate", "gme", "pta";
+ nvidia,function = "gmi";
+ };
+ cdev1 {
+ nvidia,pins = "cdev1";
+ nvidia,function = "plla_out";
+ };
+ cdev2 {
+ nvidia,pins = "cdev2";
+ nvidia,function = "pllp_out4";
+ };
+ crtp {
+ nvidia,pins = "crtp";
+ nvidia,function = "crt";
+ };
+ csus {
+ nvidia,pins = "csus";
+ nvidia,function = "vi_sensor_clk";
+ };
+ dap1 {
+ nvidia,pins = "dap1";
+ nvidia,function = "dap1";
+ };
+ dap2 {
+ nvidia,pins = "dap2";
+ nvidia,function = "dap2";
+ };
+ dap3 {
+ nvidia,pins = "dap3";
+ nvidia,function = "dap3";
+ };
+ dap4 {
+ nvidia,pins = "dap4";
+ nvidia,function = "dap4";
+ };
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "i2c2";
+ };
+ dta {
+ nvidia,pins = "dta", "dtb", "dtc", "dtd", "dte";
+ nvidia,function = "vi";
+ };
+ dtf {
+ nvidia,pins = "dtf";
+ nvidia,function = "i2c3";
+ };
+ gmc {
+ nvidia,pins = "gmc", "gmd";
+ nvidia,function = "sflash";
+ };
+ gpu {
+ nvidia,pins = "gpu";
+ nvidia,function = "uarta";
+ };
+ gpu7 {
+ nvidia,pins = "gpu7";
+ nvidia,function = "rtck";
+ };
+ gpv {
+ nvidia,pins = "gpv", "slxa", "slxk";
+ nvidia,function = "pcie";
+ };
+ hdint {
+ nvidia,pins = "hdint";
+ nvidia,function = "hdmi";
+ };
+ i2cp {
+ nvidia,pins = "i2cp";
+ nvidia,function = "i2cp";
+ };
+ irrx {
+ nvidia,pins = "irrx", "irtx";
+ nvidia,function = "uartb";
+ };
+ kbca {
+ nvidia,pins = "kbca", "kbcb", "kbcc", "kbcd",
+ "kbce", "kbcf";
+ nvidia,function = "kbc";
+ };
+ lcsn {
+ nvidia,pins = "lcsn", "ld0", "ld1", "ld2",
+ "ld3", "ld4", "ld5", "ld6", "ld7",
+ "ld8", "ld9", "ld10", "ld11", "ld12",
+ "ld13", "ld14", "ld15", "ld16", "ld17",
+ "ldc", "ldi", "lhp0", "lhp1", "lhp2",
+ "lhs", "lm0", "lm1", "lpp", "lpw0",
+ "lpw1", "lpw2", "lsc0", "lsc1", "lsck",
+ "lsda", "lsdi", "lspi", "lvp0", "lvp1",
+ "lvs";
+ nvidia,function = "displaya";
+ };
+ owc {
+ nvidia,pins = "owc", "uac";
+ nvidia,function = "rsvd2";
+ };
+ pmc {
+ nvidia,pins = "pmc";
+ nvidia,function = "pwr_on";
+ };
+ rm {
+ nvidia,pins = "rm";
+ nvidia,function = "i2c1";
+ };
+ sdb {
+ nvidia,pins = "sdb", "sdc", "sdd";
+ nvidia,function = "pwm";
+ };
+ sdio1 {
+ nvidia,pins = "sdio1";
+ nvidia,function = "sdio1";
+ };
+ slxc {
+ nvidia,pins = "slxc", "slxd";
+ nvidia,function = "sdio3";
+ };
+ spdi {
+ nvidia,pins = "spdi", "spdo";
+ nvidia,function = "spdif";
+ };
+ spia {
+ nvidia,pins = "spia", "spib", "spic";
+ nvidia,function = "spi2";
+ };
+ spid {
+ nvidia,pins = "spid", "spie", "spif";
+ nvidia,function = "spi1";
+ };
+ spig {
+ nvidia,pins = "spig", "spih";
+ nvidia,function = "spi2_alt";
+ };
+ uaa {
+ nvidia,pins = "uaa", "uab", "uda";
+ nvidia,function = "ulpi";
+ };
+ uad {
+ nvidia,pins = "uad";
+ nvidia,function = "irda";
+ };
+ uca {
+ nvidia,pins = "uca", "ucb";
+ nvidia,function = "uartc";
+ };
+ conf_ata {
+ nvidia,pins = "ata", "atc", "atd", "ate",
+ "crtp", "dap2", "dap3", "dap4", "dta",
+ "dtb", "dtc", "dtd", "dte", "gmb",
+ "gme", "i2cp", "pta", "slxc", "slxd",
+ "spdi", "spdo", "uda";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_atb {
+ nvidia,pins = "atb", "cdev1", "cdev2", "dap1",
+ "gma", "gmc", "gmd", "gpu", "gpu7",
+ "gpv", "sdio1", "slxa", "slxk", "uac";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_ck32 {
+ nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
+ "pmcc", "pmcd", "pmce", "xm2c", "xm2d";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ };
+ conf_csus {
+ nvidia,pins = "csus", "spia", "spib",
+ "spid", "spif";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_ddc {
+ nvidia,pins = "ddc", "dtf", "rm", "sdc", "sdd";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_hdint {
+ nvidia,pins = "hdint", "lcsn", "ldc", "lm1",
+ "lpw1", "lsc1", "lsck", "lsda", "lsdi",
+ "lvp0", "pmc";
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_irrx {
+ nvidia,pins = "irrx", "irtx", "kbca", "kbcb",
+ "kbcc", "kbcd", "kbce", "kbcf", "owc",
+ "spic", "spie", "spig", "spih", "uaa",
+ "uab", "uad", "uca", "ucb";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_lc {
+ nvidia,pins = "lc", "ls";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ };
+ conf_ld0 {
+ nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4",
+ "ld5", "ld6", "ld7", "ld8", "ld9",
+ "ld10", "ld11", "ld12", "ld13", "ld14",
+ "ld15", "ld16", "ld17", "ldi", "lhp0",
+ "lhp1", "lhp2", "lhs", "lm0", "lpp",
+ "lpw0", "lpw2", "lsc0", "lspi", "lvp1",
+ "lvs", "sdb";
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_ld17_0 {
+ nvidia,pins = "ld17_0", "ld19_18", "ld21_20",
+ "ld23_22";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ };
+ conf_spif {
+ nvidia,pins = "spif";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ };
+ };
+
+ i2s@70002800 {
+ status = "okay";
+ };
+
+ serial@70006000 {
+ status = "okay";
+ };
+
+ dvi_ddc: i2c@7000c000 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ spi@7000c380 {
+ status = "okay";
+ spi-max-frequency = <48000000>;
+ spi-flash@0 {
+ compatible = "winbond,w25q80bl";
+ reg = <0>;
+ spi-max-frequency = <48000000>;
+ };
+ };
+
+ hdmi_ddc: i2c@7000c400 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@7000c500 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ codec: codec@1a {
+ compatible = "ti,tlv320aic23";
+ reg = <0x1a>;
+ };
+
+ rtc@56 {
+ compatible = "emmicro,em3027";
+ reg = <0x56>;
+ };
+ };
+
+ pmc@7000e400 {
+ nvidia,suspend-mode = <1>;
+ nvidia,cpu-pwr-good-time = <5000>;
+ nvidia,cpu-pwr-off-time = <5000>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <3875>;
+ nvidia,sys-clock-req-active-high;
+ };
+
+ pcie-controller@80003000 {
+ status = "okay";
+
+ avdd-pex-supply = <&pci_vdd_reg>;
+ vdd-pex-supply = <&pci_vdd_reg>;
+ avdd-pex-pll-supply = <&pci_vdd_reg>;
+ avdd-plle-supply = <&pci_vdd_reg>;
+ vddio-pex-clk-supply = <&pci_clk_reg>;
+
+ pci@1,0 {
+ status = "okay";
+ };
+ };
+
+ usb@c5000000 {
+ status = "okay";
+ };
+
+ usb-phy@c5000000 {
+ status = "okay";
+ vbus-supply = <&vbus_reg>;
+ };
+
+ usb@c5004000 {
+ status = "okay";
+ nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 0)
+ GPIO_ACTIVE_LOW>;
+ };
+
+ usb-phy@c5004000 {
+ status = "okay";
+ nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 0)
+ GPIO_ACTIVE_LOW>;
+ };
+
+ usb@c5008000 {
+ status = "okay";
+ };
+
+ usb-phy@c5008000 {
+ status = "okay";
+ };
+
+ sdhci@c8000000 {
+ status = "okay";
+ bus-width = <4>;
+ };
+
+ sdhci@c8000600 {
+ status = "okay";
+ cd-gpios = <&gpio TEGRA_GPIO(P, 1) GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio TEGRA_GPIO(P, 2) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock@0 {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(X, 6) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ gpio-key,wakeup;
+ };
+ };
+
+ poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio TEGRA_GPIO(X, 7) GPIO_ACTIVE_LOW>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hdmi_vdd_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "avdd_hdmi";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ hdmi_pll_reg: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "avdd_hdmi_pll";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vbus_reg: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(V, 2) 0>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ pci_clk_reg: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "pci_clk";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ pci_vdd_reg: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "pci_vdd";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-always-on;
+ };
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-trimslice";
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&codec>;
+
+ clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+ <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA20_CLK_CDEV1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
+};
diff --git a/arch/arm/boot/dts/tegra20-ventana.dts b/arch/arm/boot/dts/tegra20-ventana.dts
new file mode 100644
index 000000000..04c58e9ca
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20-ventana.dts
@@ -0,0 +1,702 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra20.dtsi"
+
+/ {
+ model = "NVIDIA Tegra20 Ventana evaluation board";
+ compatible = "nvidia,ventana", "nvidia,tegra20";
+
+ aliases {
+ rtc0 = "/i2c@7000d000/tps6586x@34";
+ rtc1 = "/rtc@7000e000";
+ serial0 = &uartd;
+ };
+
+ memory {
+ reg = <0x00000000 0x40000000>;
+ };
+
+ host1x@50000000 {
+ dc@54200000 {
+ rgb {
+ status = "okay";
+
+ nvidia,panel = <&panel>;
+ };
+ };
+
+ hdmi@54280000 {
+ status = "okay";
+
+ vdd-supply = <&hdmi_vdd_reg>;
+ pll-supply = <&hdmi_pll_reg>;
+
+ nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+ GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ pinmux@70000014 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ ata {
+ nvidia,pins = "ata";
+ nvidia,function = "ide";
+ };
+ atb {
+ nvidia,pins = "atb", "gma", "gme";
+ nvidia,function = "sdio4";
+ };
+ atc {
+ nvidia,pins = "atc";
+ nvidia,function = "nand";
+ };
+ atd {
+ nvidia,pins = "atd", "ate", "gmb", "spia",
+ "spib", "spic";
+ nvidia,function = "gmi";
+ };
+ cdev1 {
+ nvidia,pins = "cdev1";
+ nvidia,function = "plla_out";
+ };
+ cdev2 {
+ nvidia,pins = "cdev2";
+ nvidia,function = "pllp_out4";
+ };
+ crtp {
+ nvidia,pins = "crtp", "lm1";
+ nvidia,function = "crt";
+ };
+ csus {
+ nvidia,pins = "csus";
+ nvidia,function = "vi_sensor_clk";
+ };
+ dap1 {
+ nvidia,pins = "dap1";
+ nvidia,function = "dap1";
+ };
+ dap2 {
+ nvidia,pins = "dap2";
+ nvidia,function = "dap2";
+ };
+ dap3 {
+ nvidia,pins = "dap3";
+ nvidia,function = "dap3";
+ };
+ dap4 {
+ nvidia,pins = "dap4";
+ nvidia,function = "dap4";
+ };
+ dta {
+ nvidia,pins = "dta", "dtb", "dtc", "dtd", "dte";
+ nvidia,function = "vi";
+ };
+ dtf {
+ nvidia,pins = "dtf";
+ nvidia,function = "i2c3";
+ };
+ gmc {
+ nvidia,pins = "gmc";
+ nvidia,function = "uartd";
+ };
+ gmd {
+ nvidia,pins = "gmd";
+ nvidia,function = "sflash";
+ };
+ gpu {
+ nvidia,pins = "gpu";
+ nvidia,function = "pwm";
+ };
+ gpu7 {
+ nvidia,pins = "gpu7";
+ nvidia,function = "rtck";
+ };
+ gpv {
+ nvidia,pins = "gpv", "slxa", "slxk";
+ nvidia,function = "pcie";
+ };
+ hdint {
+ nvidia,pins = "hdint";
+ nvidia,function = "hdmi";
+ };
+ i2cp {
+ nvidia,pins = "i2cp";
+ nvidia,function = "i2cp";
+ };
+ irrx {
+ nvidia,pins = "irrx", "irtx";
+ nvidia,function = "uartb";
+ };
+ kbca {
+ nvidia,pins = "kbca", "kbcb", "kbcc", "kbcd",
+ "kbce", "kbcf";
+ nvidia,function = "kbc";
+ };
+ lcsn {
+ nvidia,pins = "lcsn", "ldc", "lm0", "lpw1",
+ "lsdi", "lvp0";
+ nvidia,function = "rsvd4";
+ };
+ ld0 {
+ nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4",
+ "ld5", "ld6", "ld7", "ld8", "ld9",
+ "ld10", "ld11", "ld12", "ld13", "ld14",
+ "ld15", "ld16", "ld17", "ldi", "lhp0",
+ "lhp1", "lhp2", "lhs", "lpp", "lpw0",
+ "lpw2", "lsc0", "lsc1", "lsck", "lsda",
+ "lspi", "lvp1", "lvs";
+ nvidia,function = "displaya";
+ };
+ owc {
+ nvidia,pins = "owc", "spdi", "spdo", "uac";
+ nvidia,function = "rsvd2";
+ };
+ pmc {
+ nvidia,pins = "pmc";
+ nvidia,function = "pwr_on";
+ };
+ rm {
+ nvidia,pins = "rm";
+ nvidia,function = "i2c1";
+ };
+ sdb {
+ nvidia,pins = "sdb", "sdc", "sdd", "slxc";
+ nvidia,function = "sdio3";
+ };
+ sdio1 {
+ nvidia,pins = "sdio1";
+ nvidia,function = "sdio1";
+ };
+ slxd {
+ nvidia,pins = "slxd";
+ nvidia,function = "spdif";
+ };
+ spid {
+ nvidia,pins = "spid", "spie", "spif";
+ nvidia,function = "spi1";
+ };
+ spig {
+ nvidia,pins = "spig", "spih";
+ nvidia,function = "spi2_alt";
+ };
+ uaa {
+ nvidia,pins = "uaa", "uab", "uda";
+ nvidia,function = "ulpi";
+ };
+ uad {
+ nvidia,pins = "uad";
+ nvidia,function = "irda";
+ };
+ uca {
+ nvidia,pins = "uca", "ucb";
+ nvidia,function = "uartc";
+ };
+ conf_ata {
+ nvidia,pins = "ata", "atb", "atc", "atd",
+ "cdev1", "cdev2", "dap1", "dap2",
+ "dap4", "ddc", "dtf", "gma", "gmc",
+ "gme", "gpu", "gpu7", "i2cp", "irrx",
+ "irtx", "pta", "rm", "sdc", "sdd",
+ "slxc", "slxd", "slxk", "spdi", "spdo",
+ "uac", "uad", "uca", "ucb", "uda";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_ate {
+ nvidia,pins = "ate", "csus", "dap3", "gmd",
+ "gpv", "owc", "spia", "spib", "spic",
+ "spid", "spie", "spig";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_ck32 {
+ nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
+ "pmcc", "pmcd", "pmce", "xm2c", "xm2d";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ };
+ conf_crtp {
+ nvidia,pins = "crtp", "gmb", "slxa", "spih";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_dta {
+ nvidia,pins = "dta", "dtb", "dtc", "dtd";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_dte {
+ nvidia,pins = "dte", "spif";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_hdint {
+ nvidia,pins = "hdint", "lcsn", "ldc", "lm1",
+ "lpw1", "lsck", "lsda", "lsdi", "lvp0";
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_kbca {
+ nvidia,pins = "kbca", "kbcb", "kbcc", "kbcd",
+ "kbce", "kbcf", "sdio1", "uaa", "uab";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_lc {
+ nvidia,pins = "lc", "ls";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ };
+ conf_ld0 {
+ nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4",
+ "ld5", "ld6", "ld7", "ld8", "ld9",
+ "ld10", "ld11", "ld12", "ld13", "ld14",
+ "ld15", "ld16", "ld17", "ldi", "lhp0",
+ "lhp1", "lhp2", "lhs", "lm0", "lpp",
+ "lpw0", "lpw2", "lsc0", "lsc1", "lspi",
+ "lvp1", "lvs", "pmc", "sdb";
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_ld17_0 {
+ nvidia,pins = "ld17_0", "ld19_18", "ld21_20",
+ "ld23_22";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ };
+ drive_sdio1 {
+ nvidia,pins = "drive_sdio1";
+ nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>;
+ nvidia,schmitt = <TEGRA_PIN_ENABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
+ nvidia,pull-down-strength = <31>;
+ nvidia,pull-up-strength = <31>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
+ };
+ };
+
+ state_i2cmux_ddc: pinmux_i2cmux_ddc {
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "i2c2";
+ };
+ pta {
+ nvidia,pins = "pta";
+ nvidia,function = "rsvd4";
+ };
+ };
+
+ state_i2cmux_pta: pinmux_i2cmux_pta {
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "rsvd4";
+ };
+ pta {
+ nvidia,pins = "pta";
+ nvidia,function = "i2c2";
+ };
+ };
+
+ state_i2cmux_idle: pinmux_i2cmux_idle {
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "rsvd4";
+ };
+ pta {
+ nvidia,pins = "pta";
+ nvidia,function = "rsvd4";
+ };
+ };
+ };
+
+ i2s@70002800 {
+ status = "okay";
+ };
+
+ serial@70006300 {
+ status = "okay";
+ };
+
+ pwm: pwm@7000a000 {
+ status = "okay";
+ };
+
+ i2c@7000c000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ wm8903: wm8903@1a {
+ compatible = "wlf,wm8903";
+ reg = <0x1a>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(X, 3) IRQ_TYPE_LEVEL_HIGH>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ micdet-cfg = <0>;
+ micdet-delay = <100>;
+ gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>;
+ };
+
+ /* ALS and proximity sensor */
+ isl29018@44 {
+ compatible = "isil,isl29018";
+ reg = <0x44>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(Z, 2) IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ i2c@7000c400 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2cmux {
+ compatible = "i2c-mux-pinctrl";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c-parent = <&{/i2c@7000c400}>;
+
+ pinctrl-names = "ddc", "pta", "idle";
+ pinctrl-0 = <&state_i2cmux_ddc>;
+ pinctrl-1 = <&state_i2cmux_pta>;
+ pinctrl-2 = <&state_i2cmux_idle>;
+
+ hdmi_ddc: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ lvds_ddc: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ i2c@7000c500 {
+ status = "okay";
+ clock-frequency = <400000>;
+ };
+
+ i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ pmic: tps6586x@34 {
+ compatible = "ti,tps6586x";
+ reg = <0x34>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+
+ ti,system-power-controller;
+
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ sys-supply = <&vdd_5v0_reg>;
+ vin-sm0-supply = <&sys_reg>;
+ vin-sm1-supply = <&sys_reg>;
+ vin-sm2-supply = <&sys_reg>;
+ vinldo01-supply = <&sm2_reg>;
+ vinldo23-supply = <&sm2_reg>;
+ vinldo4-supply = <&sm2_reg>;
+ vinldo678-supply = <&sm2_reg>;
+ vinldo9-supply = <&sm2_reg>;
+
+ regulators {
+ sys_reg: sys {
+ regulator-name = "vdd_sys";
+ regulator-always-on;
+ };
+
+ sm0 {
+ regulator-name = "vdd_sm0,vdd_core";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ sm1 {
+ regulator-name = "vdd_sm1,vdd_cpu";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ sm2_reg: sm2 {
+ regulator-name = "vdd_sm2,vin_ldo*";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+ regulator-always-on;
+ };
+
+ /* LDO0 is not connected to anything */
+
+ ldo1 {
+ regulator-name = "vdd_ldo1,avdd_pll*";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ ldo2 {
+ regulator-name = "vdd_ldo2,vdd_rtc";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo3 {
+ regulator-name = "vdd_ldo3,avdd_usb*";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo4 {
+ regulator-name = "vdd_ldo4,avdd_osc,vddio_sys";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo5 {
+ regulator-name = "vdd_ldo5,vcore_mmc";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ };
+
+ ldo6 {
+ regulator-name = "vdd_ldo6,avdd_vdac";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ hdmi_vdd_reg: ldo7 {
+ regulator-name = "vdd_ldo7,avdd_hdmi,vdd_fuse";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ hdmi_pll_reg: ldo8 {
+ regulator-name = "vdd_ldo8,avdd_hdmi_pll";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo9 {
+ regulator-name = "vdd_ldo9,avdd_2v85,vdd_ddr_rx";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ };
+
+ ldo_rtc {
+ regulator-name = "vdd_rtc_out,vdd_cell";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ temperature-sensor@4c {
+ compatible = "onnn,nct1008";
+ reg = <0x4c>;
+ };
+ };
+
+ pmc@7000e400 {
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <1>;
+ nvidia,cpu-pwr-good-time = <2000>;
+ nvidia,cpu-pwr-off-time = <100>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <458>;
+ nvidia,sys-clock-req-active-high;
+ };
+
+ usb@c5000000 {
+ status = "okay";
+ };
+
+ usb-phy@c5000000 {
+ status = "okay";
+ };
+
+ usb@c5004000 {
+ status = "okay";
+ nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+ GPIO_ACTIVE_LOW>;
+ };
+
+ usb-phy@c5004000 {
+ status = "okay";
+ nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+ GPIO_ACTIVE_LOW>;
+ };
+
+ usb@c5008000 {
+ status = "okay";
+ };
+
+ usb-phy@c5008000 {
+ status = "okay";
+ };
+
+ sdhci@c8000000 {
+ status = "okay";
+ power-gpios = <&gpio TEGRA_GPIO(K, 6) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ keep-power-in-suspend;
+ };
+
+ sdhci@c8000400 {
+ status = "okay";
+ cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
+ power-gpios = <&gpio TEGRA_GPIO(I, 6) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ };
+
+ sdhci@c8000600 {
+ status = "okay";
+ bus-width = <8>;
+ non-removable;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+
+ enable-gpios = <&gpio TEGRA_GPIO(D, 4) GPIO_ACTIVE_HIGH>;
+ power-supply = <&vdd_bl_reg>;
+ pwms = <&pwm 2 5000000>;
+
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock@0 {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ gpio-key,wakeup;
+ };
+ };
+
+ panel: panel {
+ compatible = "chunghwa,claa101wa01a", "simple-panel";
+
+ power-supply = <&vdd_pnl_reg>;
+ enable-gpios = <&gpio TEGRA_GPIO(B, 2) GPIO_ACTIVE_HIGH>;
+
+ backlight = <&backlight>;
+ ddc-i2c-bus = <&lvds_ddc>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdd_5v0_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vdd_5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "vdd_1v5";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ gpio = <&pmic 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "vdd_1v2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ gpio = <&pmic 1 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vdd_pnl_reg: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "vdd_pnl";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpio TEGRA_GPIO(C, 6) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vdd_bl_reg: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "vdd_bl";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&gpio TEGRA_GPIO(W, 0) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-wm8903-ventana",
+ "nvidia,tegra-audio-wm8903";
+ nvidia,model = "NVIDIA Tegra Ventana";
+
+ nvidia,audio-routing =
+ "Headphone Jack", "HPOUTR",
+ "Headphone Jack", "HPOUTL",
+ "Int Spk", "ROP",
+ "Int Spk", "RON",
+ "Int Spk", "LOP",
+ "Int Spk", "LON",
+ "Mic Jack", "MICBIAS",
+ "IN1L", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&wm8903>;
+
+ nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>;
+ nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>;
+ nvidia,int-mic-en-gpios = <&gpio TEGRA_GPIO(X, 0)
+ GPIO_ACTIVE_HIGH>;
+ nvidia,ext-mic-en-gpios = <&gpio TEGRA_GPIO(X, 1)
+ GPIO_ACTIVE_HIGH>;
+
+ clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+ <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA20_CLK_CDEV1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
+};
diff --git a/arch/arm/boot/dts/tegra20-whistler.dts b/arch/arm/boot/dts/tegra20-whistler.dts
new file mode 100644
index 000000000..340d81108
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20-whistler.dts
@@ -0,0 +1,632 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra20.dtsi"
+
+/ {
+ model = "NVIDIA Tegra20 Whistler evaluation board";
+ compatible = "nvidia,whistler", "nvidia,tegra20";
+
+ aliases {
+ rtc0 = "/i2c@7000d000/max8907@3c";
+ rtc1 = "/rtc@7000e000";
+ serial0 = &uarta;
+ };
+
+ memory {
+ reg = <0x00000000 0x20000000>;
+ };
+
+ host1x@50000000 {
+ hdmi@54280000 {
+ status = "okay";
+
+ vdd-supply = <&hdmi_vdd_reg>;
+ pll-supply = <&hdmi_pll_reg>;
+
+ nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+ GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ pinmux@70000014 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ ata {
+ nvidia,pins = "ata", "atb", "ate", "gma", "gmb",
+ "gmc", "gmd", "gpu";
+ nvidia,function = "gmi";
+ };
+ atc {
+ nvidia,pins = "atc", "atd";
+ nvidia,function = "sdio4";
+ };
+ cdev1 {
+ nvidia,pins = "cdev1";
+ nvidia,function = "plla_out";
+ };
+ cdev2 {
+ nvidia,pins = "cdev2";
+ nvidia,function = "osc";
+ };
+ crtp {
+ nvidia,pins = "crtp";
+ nvidia,function = "crt";
+ };
+ csus {
+ nvidia,pins = "csus";
+ nvidia,function = "vi_sensor_clk";
+ };
+ dap1 {
+ nvidia,pins = "dap1";
+ nvidia,function = "dap1";
+ };
+ dap2 {
+ nvidia,pins = "dap2";
+ nvidia,function = "dap2";
+ };
+ dap3 {
+ nvidia,pins = "dap3";
+ nvidia,function = "dap3";
+ };
+ dap4 {
+ nvidia,pins = "dap4";
+ nvidia,function = "dap4";
+ };
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "i2c2";
+ };
+ dta {
+ nvidia,pins = "dta", "dtb", "dtc", "dtd";
+ nvidia,function = "vi";
+ };
+ dte {
+ nvidia,pins = "dte";
+ nvidia,function = "rsvd1";
+ };
+ dtf {
+ nvidia,pins = "dtf";
+ nvidia,function = "i2c3";
+ };
+ gme {
+ nvidia,pins = "gme";
+ nvidia,function = "dap5";
+ };
+ gpu7 {
+ nvidia,pins = "gpu7";
+ nvidia,function = "rtck";
+ };
+ gpv {
+ nvidia,pins = "gpv";
+ nvidia,function = "pcie";
+ };
+ hdint {
+ nvidia,pins = "hdint", "pta";
+ nvidia,function = "hdmi";
+ };
+ i2cp {
+ nvidia,pins = "i2cp";
+ nvidia,function = "i2cp";
+ };
+ irrx {
+ nvidia,pins = "irrx", "irtx";
+ nvidia,function = "uartb";
+ };
+ kbca {
+ nvidia,pins = "kbca", "kbcc", "kbce", "kbcf";
+ nvidia,function = "kbc";
+ };
+ kbcb {
+ nvidia,pins = "kbcb", "kbcd";
+ nvidia,function = "sdio2";
+ };
+ lcsn {
+ nvidia,pins = "lcsn", "lsck", "lsda", "lsdi",
+ "spia", "spib", "spic";
+ nvidia,function = "spi3";
+ };
+ ld0 {
+ nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4",
+ "ld5", "ld6", "ld7", "ld8", "ld9",
+ "ld10", "ld11", "ld12", "ld13", "ld14",
+ "ld15", "ld16", "ld17", "ldc", "ldi",
+ "lhp0", "lhp1", "lhp2", "lhs", "lm0",
+ "lm1", "lpp", "lpw0", "lpw1", "lpw2",
+ "lsc0", "lsc1", "lspi", "lvp0", "lvp1",
+ "lvs";
+ nvidia,function = "displaya";
+ };
+ owc {
+ nvidia,pins = "owc", "uac";
+ nvidia,function = "owr";
+ };
+ pmc {
+ nvidia,pins = "pmc";
+ nvidia,function = "pwr_on";
+ };
+ rm {
+ nvidia,pins = "rm";
+ nvidia,function = "i2c1";
+ };
+ sdb {
+ nvidia,pins = "sdb", "sdc", "sdd", "slxa",
+ "slxc", "slxd", "slxk";
+ nvidia,function = "sdio3";
+ };
+ sdio1 {
+ nvidia,pins = "sdio1";
+ nvidia,function = "sdio1";
+ };
+ spdi {
+ nvidia,pins = "spdi", "spdo";
+ nvidia,function = "rsvd2";
+ };
+ spid {
+ nvidia,pins = "spid", "spie", "spig", "spih";
+ nvidia,function = "spi2_alt";
+ };
+ spif {
+ nvidia,pins = "spif";
+ nvidia,function = "spi2";
+ };
+ uaa {
+ nvidia,pins = "uaa", "uab";
+ nvidia,function = "uarta";
+ };
+ uad {
+ nvidia,pins = "uad";
+ nvidia,function = "irda";
+ };
+ uca {
+ nvidia,pins = "uca", "ucb";
+ nvidia,function = "uartc";
+ };
+ uda {
+ nvidia,pins = "uda";
+ nvidia,function = "spi1";
+ };
+ conf_ata {
+ nvidia,pins = "ata", "atb", "atc", "ddc", "gma",
+ "gmb", "gmc", "gmd", "irrx", "irtx",
+ "kbca", "kbcb", "kbcc", "kbcd", "kbce",
+ "kbcf", "sdc", "sdd", "spie", "spig",
+ "spih", "uaa", "uab", "uad", "uca",
+ "ucb";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_atd {
+ nvidia,pins = "atd", "ate", "cdev1", "csus",
+ "dap1", "dap2", "dap3", "dap4", "dte",
+ "dtf", "gpu", "gpu7", "gpv", "i2cp",
+ "rm", "sdio1", "slxa", "slxc", "slxd",
+ "slxk", "spdi", "spdo", "uac", "uda";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_cdev2 {
+ nvidia,pins = "cdev2", "spia", "spib";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_ck32 {
+ nvidia,pins = "ck32", "ddrc", "lc", "pmca",
+ "pmcb", "pmcc", "pmcd", "xm2c",
+ "xm2d";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ };
+ conf_crtp {
+ nvidia,pins = "crtp";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_dta {
+ nvidia,pins = "dta", "dtb", "dtc", "dtd",
+ "spid", "spif";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ conf_gme {
+ nvidia,pins = "gme", "owc", "pta", "spic";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ conf_ld17_0 {
+ nvidia,pins = "ld17_0", "ld19_18", "ld21_20",
+ "ld23_22";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ };
+ conf_ls {
+ nvidia,pins = "ls", "pmce";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ };
+ drive_dap1 {
+ nvidia,pins = "drive_dap1";
+ nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>;
+ nvidia,schmitt = <TEGRA_PIN_ENABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_8>;
+ nvidia,pull-down-strength = <0>;
+ nvidia,pull-up-strength = <0>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ };
+ };
+ };
+
+ i2s@70002800 {
+ status = "okay";
+ };
+
+ serial@70006000 {
+ status = "okay";
+ };
+
+ hdmi_ddc: i2c@7000c400 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ codec: codec@1a {
+ compatible = "wlf,wm8753";
+ reg = <0x1a>;
+ };
+
+ tca6416: gpio@20 {
+ compatible = "ti,tca6416";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ max8907@3c {
+ compatible = "maxim,max8907";
+ reg = <0x3c>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+
+ maxim,system-power-controller;
+
+ mbatt-supply = <&usb0_vbus_reg>;
+ in-v1-supply = <&mbatt_reg>;
+ in-v2-supply = <&mbatt_reg>;
+ in-v3-supply = <&mbatt_reg>;
+ in1-supply = <&mbatt_reg>;
+ in2-supply = <&nvvdd_sv3_reg>;
+ in3-supply = <&mbatt_reg>;
+ in4-supply = <&mbatt_reg>;
+ in5-supply = <&mbatt_reg>;
+ in6-supply = <&mbatt_reg>;
+ in7-supply = <&mbatt_reg>;
+ in8-supply = <&mbatt_reg>;
+ in9-supply = <&mbatt_reg>;
+ in10-supply = <&mbatt_reg>;
+ in11-supply = <&mbatt_reg>;
+ in12-supply = <&mbatt_reg>;
+ in13-supply = <&mbatt_reg>;
+ in14-supply = <&mbatt_reg>;
+ in15-supply = <&mbatt_reg>;
+ in16-supply = <&mbatt_reg>;
+ in17-supply = <&nvvdd_sv3_reg>;
+ in18-supply = <&nvvdd_sv3_reg>;
+ in19-supply = <&mbatt_reg>;
+ in20-supply = <&mbatt_reg>;
+
+ regulators {
+ mbatt_reg: mbatt {
+ regulator-name = "vbat_pmu";
+ regulator-always-on;
+ };
+
+ sd1 {
+ regulator-name = "nvvdd_sv1,vdd_cpu_pmu";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ sd2 {
+ regulator-name = "nvvdd_sv2,vdd_core";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ nvvdd_sv3_reg: sd3 {
+ regulator-name = "nvvdd_sv3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo1 {
+ regulator-name = "nvvdd_ldo1,vddio_rx_ddr,vcore_acc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo2 {
+ regulator-name = "nvvdd_ldo2,avdd_pll*";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ ldo3 {
+ regulator-name = "nvvdd_ldo3,vcom_1v8b";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo4 {
+ regulator-name = "nvvdd_ldo4,avdd_usb*";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo5 {
+ regulator-name = "nvvdd_ldo5,vcore_mmc,avdd_lcd1,vddio_1wire";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ hdmi_pll_reg: ldo6 {
+ regulator-name = "nvvdd_ldo6,avdd_hdmi_pll";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo7 {
+ regulator-name = "nvvdd_ldo7,avddio_audio";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo8 {
+ regulator-name = "nvvdd_ldo8,vcom_3v0,vcore_cmps";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ ldo9 {
+ regulator-name = "nvvdd_ldo9,avdd_cam*";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo10 {
+ regulator-name = "nvvdd_ldo10,avdd_usb_ic_3v0";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ hdmi_vdd_reg: ldo11 {
+ regulator-name = "nvvdd_ldo11,vddio_pex_clk,vcom_33,avdd_hdmi";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo12 {
+ regulator-name = "nvvdd_ldo12,vddio_sdio";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo13 {
+ regulator-name = "nvvdd_ldo13,vcore_phtn,vdd_af";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo14 {
+ regulator-name = "nvvdd_ldo14,avdd_vdac";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo15 {
+ regulator-name = "nvvdd_ldo15,vcore_temp,vddio_hdcp";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo16 {
+ regulator-name = "nvvdd_ldo16,vdd_dbrtr";
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ ldo17 {
+ regulator-name = "nvvdd_ldo17,vddio_mipi";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo18 {
+ regulator-name = "nvvdd_ldo18,vddio_vi,vcore_cam*";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo19 {
+ regulator-name = "nvvdd_ldo19,avdd_lcd2,vddio_lx";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo20 {
+ regulator-name = "nvvdd_ldo20,vddio_ddr_1v2,vddio_hsic,vcom_1v2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ out5v {
+ regulator-name = "usb0_vbus_reg";
+ };
+
+ out33v {
+ regulator-name = "pmu_out3v3";
+ };
+
+ bbat {
+ regulator-name = "pmu_bbat";
+ regulator-min-microvolt = <2400000>;
+ regulator-max-microvolt = <2400000>;
+ regulator-always-on;
+ };
+
+ sdby {
+ regulator-name = "vdd_aon";
+ regulator-always-on;
+ };
+
+ vrtc {
+ regulator-name = "vrtc,pmu_vccadc";
+ regulator-always-on;
+ };
+ };
+ };
+ };
+
+ kbc@7000e200 {
+ status = "okay";
+ nvidia,debounce-delay-ms = <20>;
+ nvidia,repeat-delay-ms = <160>;
+ nvidia,kbc-row-pins = <0 1 2>;
+ nvidia,kbc-col-pins = <16 17>;
+ nvidia,wakeup-source;
+ linux,keymap = <MATRIX_KEY(0x00, 0x00, KEY_POWER)
+ MATRIX_KEY(0x01, 0x00, KEY_HOME)
+ MATRIX_KEY(0x01, 0x01, KEY_BACK)
+ MATRIX_KEY(0x02, 0x01, KEY_MENU)>;
+ };
+
+ pmc@7000e400 {
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <1>;
+ nvidia,cpu-pwr-good-time = <2000>;
+ nvidia,cpu-pwr-off-time = <1000>;
+ nvidia,core-pwr-good-time = <0 3845>;
+ nvidia,core-pwr-off-time = <93727>;
+ nvidia,core-power-req-active-high;
+ nvidia,sys-clock-req-active-high;
+ nvidia,combined-power-req;
+ };
+
+ usb@c5000000 {
+ status = "okay";
+ };
+
+ usb-phy@c5000000 {
+ status = "okay";
+ vbus-supply = <&vbus1_reg>;
+ };
+
+ usb@c5008000 {
+ status = "okay";
+ };
+
+ usb-phy@c5008000 {
+ status = "okay";
+ vbus-supply = <&vbus3_reg>;
+ };
+
+ sdhci@c8000400 {
+ status = "okay";
+ cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio TEGRA_GPIO(V, 5) GPIO_ACTIVE_HIGH>;
+ bus-width = <8>;
+ };
+
+ sdhci@c8000600 {
+ status = "okay";
+ bus-width = <8>;
+ non-removable;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock@0 {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb0_vbus_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb0_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ vbus1_reg: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "vbus1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&tca6416 0 0>; /* GPIO_PMU0 */
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vbus3_reg: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "vbus3";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&tca6416 1 0>; /* GPIO_PMU1 */
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-wm8753-whistler",
+ "nvidia,tegra-audio-wm8753";
+ nvidia,model = "NVIDIA Tegra Whistler";
+
+ nvidia,audio-routing =
+ "Headphone Jack", "LOUT1",
+ "Headphone Jack", "ROUT1",
+ "MIC2", "Mic Jack",
+ "MIC2N", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&codec>;
+
+ clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+ <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA20_CLK_CDEV1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
+};
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
new file mode 100644
index 000000000..adf6b048d
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -0,0 +1,792 @@
+#include <dt-bindings/clock/tegra20-car.h>
+#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "nvidia,tegra20";
+ interrupt-parent = <&lic>;
+
+ host1x@50000000 {
+ compatible = "nvidia,tegra20-host1x", "simple-bus";
+ reg = <0x50000000 0x00024000>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, /* syncpt */
+ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; /* general */
+ clocks = <&tegra_car TEGRA20_CLK_HOST1X>;
+ resets = <&tegra_car 28>;
+ reset-names = "host1x";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0x54000000 0x54000000 0x04000000>;
+
+ mpe@54040000 {
+ compatible = "nvidia,tegra20-mpe";
+ reg = <0x54040000 0x00040000>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_MPE>;
+ resets = <&tegra_car 60>;
+ reset-names = "mpe";
+ };
+
+ vi@54080000 {
+ compatible = "nvidia,tegra20-vi";
+ reg = <0x54080000 0x00040000>;
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_VI>;
+ resets = <&tegra_car 20>;
+ reset-names = "vi";
+ };
+
+ epp@540c0000 {
+ compatible = "nvidia,tegra20-epp";
+ reg = <0x540c0000 0x00040000>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_EPP>;
+ resets = <&tegra_car 19>;
+ reset-names = "epp";
+ };
+
+ isp@54100000 {
+ compatible = "nvidia,tegra20-isp";
+ reg = <0x54100000 0x00040000>;
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_ISP>;
+ resets = <&tegra_car 23>;
+ reset-names = "isp";
+ };
+
+ gr2d@54140000 {
+ compatible = "nvidia,tegra20-gr2d";
+ reg = <0x54140000 0x00040000>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_GR2D>;
+ resets = <&tegra_car 21>;
+ reset-names = "2d";
+ };
+
+ gr3d@54180000 {
+ compatible = "nvidia,tegra20-gr3d";
+ reg = <0x54180000 0x00040000>;
+ clocks = <&tegra_car TEGRA20_CLK_GR3D>;
+ resets = <&tegra_car 24>;
+ reset-names = "3d";
+ };
+
+ dc@54200000 {
+ compatible = "nvidia,tegra20-dc";
+ reg = <0x54200000 0x00040000>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_DISP1>,
+ <&tegra_car TEGRA20_CLK_PLL_P>;
+ clock-names = "dc", "parent";
+ resets = <&tegra_car 27>;
+ reset-names = "dc";
+
+ nvidia,head = <0>;
+
+ rgb {
+ status = "disabled";
+ };
+ };
+
+ dc@54240000 {
+ compatible = "nvidia,tegra20-dc";
+ reg = <0x54240000 0x00040000>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_DISP2>,
+ <&tegra_car TEGRA20_CLK_PLL_P>;
+ clock-names = "dc", "parent";
+ resets = <&tegra_car 26>;
+ reset-names = "dc";
+
+ nvidia,head = <1>;
+
+ rgb {
+ status = "disabled";
+ };
+ };
+
+ hdmi@54280000 {
+ compatible = "nvidia,tegra20-hdmi";
+ reg = <0x54280000 0x00040000>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_HDMI>,
+ <&tegra_car TEGRA20_CLK_PLL_D_OUT0>;
+ clock-names = "hdmi", "parent";
+ resets = <&tegra_car 51>;
+ reset-names = "hdmi";
+ status = "disabled";
+ };
+
+ tvo@542c0000 {
+ compatible = "nvidia,tegra20-tvo";
+ reg = <0x542c0000 0x00040000>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_TVO>;
+ status = "disabled";
+ };
+
+ dsi@54300000 {
+ compatible = "nvidia,tegra20-dsi";
+ reg = <0x54300000 0x00040000>;
+ clocks = <&tegra_car TEGRA20_CLK_DSI>;
+ resets = <&tegra_car 48>;
+ reset-names = "dsi";
+ status = "disabled";
+ };
+ };
+
+ timer@50040600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ interrupt-parent = <&intc>;
+ reg = <0x50040600 0x20>;
+ interrupts = <GIC_PPI 13
+ (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+ clocks = <&tegra_car TEGRA20_CLK_TWD>;
+ };
+
+ intc: interrupt-controller@50041000 {
+ compatible = "arm,cortex-a9-gic";
+ reg = <0x50041000 0x1000
+ 0x50040100 0x0100>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&intc>;
+ };
+
+ cache-controller@50043000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x50043000 0x1000>;
+ arm,data-latency = <5 5 2>;
+ arm,tag-latency = <4 4 2>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ lic: interrupt-controller@60004000 {
+ compatible = "nvidia,tegra20-ictlr";
+ reg = <0x60004000 0x100>,
+ <0x60004100 0x50>,
+ <0x60004200 0x50>,
+ <0x60004300 0x50>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&intc>;
+ };
+
+ timer@60005000 {
+ compatible = "nvidia,tegra20-timer";
+ reg = <0x60005000 0x60>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_TIMER>;
+ };
+
+ tegra_car: clock@60006000 {
+ compatible = "nvidia,tegra20-car";
+ reg = <0x60006000 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ flow-controller@60007000 {
+ compatible = "nvidia,tegra20-flowctrl";
+ reg = <0x60007000 0x1000>;
+ };
+
+ apbdma: dma@6000a000 {
+ compatible = "nvidia,tegra20-apbdma";
+ reg = <0x6000a000 0x1200>;
+ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_APBDMA>;
+ resets = <&tegra_car 34>;
+ reset-names = "dma";
+ #dma-cells = <1>;
+ };
+
+ ahb@6000c004 {
+ compatible = "nvidia,tegra20-ahb";
+ reg = <0x6000c004 0x10c>; /* AHB Arbitration + Gizmo Controller */
+ };
+
+ gpio: gpio@6000d000 {
+ compatible = "nvidia,tegra20-gpio";
+ reg = <0x6000d000 0x1000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ apbmisc@70000800 {
+ compatible = "nvidia,tegra20-apbmisc";
+ reg = <0x70000800 0x64 /* Chip revision */
+ 0x70000008 0x04>; /* Strapping options */
+ };
+
+ pinmux: pinmux@70000014 {
+ compatible = "nvidia,tegra20-pinmux";
+ reg = <0x70000014 0x10 /* Tri-state registers */
+ 0x70000080 0x20 /* Mux registers */
+ 0x700000a0 0x14 /* Pull-up/down registers */
+ 0x70000868 0xa8>; /* Pad control registers */
+ };
+
+ das@70000c00 {
+ compatible = "nvidia,tegra20-das";
+ reg = <0x70000c00 0x80>;
+ };
+
+ tegra_ac97: ac97@70002000 {
+ compatible = "nvidia,tegra20-ac97";
+ reg = <0x70002000 0x200>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_AC97>;
+ resets = <&tegra_car 3>;
+ reset-names = "ac97";
+ dmas = <&apbdma 12>, <&apbdma 12>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ tegra_i2s1: i2s@70002800 {
+ compatible = "nvidia,tegra20-i2s";
+ reg = <0x70002800 0x200>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_I2S1>;
+ resets = <&tegra_car 11>;
+ reset-names = "i2s";
+ dmas = <&apbdma 2>, <&apbdma 2>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ tegra_i2s2: i2s@70002a00 {
+ compatible = "nvidia,tegra20-i2s";
+ reg = <0x70002a00 0x200>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_I2S2>;
+ resets = <&tegra_car 18>;
+ reset-names = "i2s";
+ dmas = <&apbdma 1>, <&apbdma 1>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ /*
+ * There are two serial driver i.e. 8250 based simple serial
+ * driver and APB DMA based serial driver for higher baudrate
+ * and performace. To enable the 8250 based driver, the compatible
+ * is "nvidia,tegra20-uart" and to enable the APB DMA based serial
+ * driver, the comptible is "nvidia,tegra20-hsuart".
+ */
+ uarta: serial@70006000 {
+ compatible = "nvidia,tegra20-uart";
+ reg = <0x70006000 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_UARTA>;
+ resets = <&tegra_car 6>;
+ reset-names = "serial";
+ dmas = <&apbdma 8>, <&apbdma 8>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uartb: serial@70006040 {
+ compatible = "nvidia,tegra20-uart";
+ reg = <0x70006040 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_UARTB>;
+ resets = <&tegra_car 7>;
+ reset-names = "serial";
+ dmas = <&apbdma 9>, <&apbdma 9>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uartc: serial@70006200 {
+ compatible = "nvidia,tegra20-uart";
+ reg = <0x70006200 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_UARTC>;
+ resets = <&tegra_car 55>;
+ reset-names = "serial";
+ dmas = <&apbdma 10>, <&apbdma 10>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uartd: serial@70006300 {
+ compatible = "nvidia,tegra20-uart";
+ reg = <0x70006300 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_UARTD>;
+ resets = <&tegra_car 65>;
+ reset-names = "serial";
+ dmas = <&apbdma 19>, <&apbdma 19>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uarte: serial@70006400 {
+ compatible = "nvidia,tegra20-uart";
+ reg = <0x70006400 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_UARTE>;
+ resets = <&tegra_car 66>;
+ reset-names = "serial";
+ dmas = <&apbdma 20>, <&apbdma 20>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ pwm: pwm@7000a000 {
+ compatible = "nvidia,tegra20-pwm";
+ reg = <0x7000a000 0x100>;
+ #pwm-cells = <2>;
+ clocks = <&tegra_car TEGRA20_CLK_PWM>;
+ resets = <&tegra_car 17>;
+ reset-names = "pwm";
+ status = "disabled";
+ };
+
+ rtc@7000e000 {
+ compatible = "nvidia,tegra20-rtc";
+ reg = <0x7000e000 0x100>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_RTC>;
+ };
+
+ i2c@7000c000 {
+ compatible = "nvidia,tegra20-i2c";
+ reg = <0x7000c000 0x100>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA20_CLK_I2C1>,
+ <&tegra_car TEGRA20_CLK_PLL_P_OUT3>;
+ clock-names = "div-clk", "fast-clk";
+ resets = <&tegra_car 12>;
+ reset-names = "i2c";
+ dmas = <&apbdma 21>, <&apbdma 21>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000c380 {
+ compatible = "nvidia,tegra20-sflash";
+ reg = <0x7000c380 0x80>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA20_CLK_SPI>;
+ resets = <&tegra_car 43>;
+ reset-names = "spi";
+ dmas = <&apbdma 11>, <&apbdma 11>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@7000c400 {
+ compatible = "nvidia,tegra20-i2c";
+ reg = <0x7000c400 0x100>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA20_CLK_I2C2>,
+ <&tegra_car TEGRA20_CLK_PLL_P_OUT3>;
+ clock-names = "div-clk", "fast-clk";
+ resets = <&tegra_car 54>;
+ reset-names = "i2c";
+ dmas = <&apbdma 22>, <&apbdma 22>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@7000c500 {
+ compatible = "nvidia,tegra20-i2c";
+ reg = <0x7000c500 0x100>;
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA20_CLK_I2C3>,
+ <&tegra_car TEGRA20_CLK_PLL_P_OUT3>;
+ clock-names = "div-clk", "fast-clk";
+ resets = <&tegra_car 67>;
+ reset-names = "i2c";
+ dmas = <&apbdma 23>, <&apbdma 23>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@7000d000 {
+ compatible = "nvidia,tegra20-i2c-dvc";
+ reg = <0x7000d000 0x200>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA20_CLK_DVC>,
+ <&tegra_car TEGRA20_CLK_PLL_P_OUT3>;
+ clock-names = "div-clk", "fast-clk";
+ resets = <&tegra_car 47>;
+ reset-names = "i2c";
+ dmas = <&apbdma 24>, <&apbdma 24>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000d400 {
+ compatible = "nvidia,tegra20-slink";
+ reg = <0x7000d400 0x200>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA20_CLK_SBC1>;
+ resets = <&tegra_car 41>;
+ reset-names = "spi";
+ dmas = <&apbdma 15>, <&apbdma 15>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000d600 {
+ compatible = "nvidia,tegra20-slink";
+ reg = <0x7000d600 0x200>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA20_CLK_SBC2>;
+ resets = <&tegra_car 44>;
+ reset-names = "spi";
+ dmas = <&apbdma 16>, <&apbdma 16>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000d800 {
+ compatible = "nvidia,tegra20-slink";
+ reg = <0x7000d800 0x200>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA20_CLK_SBC3>;
+ resets = <&tegra_car 46>;
+ reset-names = "spi";
+ dmas = <&apbdma 17>, <&apbdma 17>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000da00 {
+ compatible = "nvidia,tegra20-slink";
+ reg = <0x7000da00 0x200>;
+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA20_CLK_SBC4>;
+ resets = <&tegra_car 68>;
+ reset-names = "spi";
+ dmas = <&apbdma 18>, <&apbdma 18>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ kbc@7000e200 {
+ compatible = "nvidia,tegra20-kbc";
+ reg = <0x7000e200 0x100>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_KBC>;
+ resets = <&tegra_car 36>;
+ reset-names = "kbc";
+ status = "disabled";
+ };
+
+ pmc@7000e400 {
+ compatible = "nvidia,tegra20-pmc";
+ reg = <0x7000e400 0x400>;
+ clocks = <&tegra_car TEGRA20_CLK_PCLK>, <&clk32k_in>;
+ clock-names = "pclk", "clk32k_in";
+ };
+
+ memory-controller@7000f000 {
+ compatible = "nvidia,tegra20-mc";
+ reg = <0x7000f000 0x024
+ 0x7000f03c 0x3c4>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ iommu@7000f024 {
+ compatible = "nvidia,tegra20-gart";
+ reg = <0x7000f024 0x00000018 /* controller registers */
+ 0x58000000 0x02000000>; /* GART aperture */
+ };
+
+ memory-controller@7000f400 {
+ compatible = "nvidia,tegra20-emc";
+ reg = <0x7000f400 0x200>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ fuse@7000f800 {
+ compatible = "nvidia,tegra20-efuse";
+ reg = <0x7000F800 0x400>;
+ clocks = <&tegra_car TEGRA20_CLK_FUSE>;
+ clock-names = "fuse";
+ resets = <&tegra_car 39>;
+ reset-names = "fuse";
+ };
+
+ pcie-controller@80003000 {
+ compatible = "nvidia,tegra20-pcie";
+ device_type = "pci";
+ reg = <0x80003000 0x00000800 /* PADS registers */
+ 0x80003800 0x00000200 /* AFI registers */
+ 0x90000000 0x10000000>; /* configuration space */
+ reg-names = "pads", "afi", "cs";
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH /* controller interrupt */
+ GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
+ interrupt-names = "intr", "msi";
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &intc GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+
+ bus-range = <0x00 0xff>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ ranges = <0x82000000 0 0x80000000 0x80000000 0 0x00001000 /* port 0 registers */
+ 0x82000000 0 0x80001000 0x80001000 0 0x00001000 /* port 1 registers */
+ 0x81000000 0 0 0x82000000 0 0x00010000 /* downstream I/O */
+ 0x82000000 0 0xa0000000 0xa0000000 0 0x08000000 /* non-prefetchable memory */
+ 0xc2000000 0 0xa8000000 0xa8000000 0 0x18000000>; /* prefetchable memory */
+
+ clocks = <&tegra_car TEGRA20_CLK_PEX>,
+ <&tegra_car TEGRA20_CLK_AFI>,
+ <&tegra_car TEGRA20_CLK_PLL_E>;
+ clock-names = "pex", "afi", "pll_e";
+ resets = <&tegra_car 70>,
+ <&tegra_car 72>,
+ <&tegra_car 74>;
+ reset-names = "pex", "afi", "pcie_x";
+ status = "disabled";
+
+ pci@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x80000000 0 0x1000>;
+ reg = <0x000800 0 0 0 0>;
+ status = "disabled";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ nvidia,num-lanes = <2>;
+ };
+
+ pci@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82001000 0 0x80001000 0 0x1000>;
+ reg = <0x001000 0 0 0 0>;
+ status = "disabled";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ nvidia,num-lanes = <2>;
+ };
+ };
+
+ usb@c5000000 {
+ compatible = "nvidia,tegra20-ehci", "usb-ehci";
+ reg = <0xc5000000 0x4000>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ phy_type = "utmi";
+ nvidia,has-legacy-mode;
+ clocks = <&tegra_car TEGRA20_CLK_USBD>;
+ resets = <&tegra_car 22>;
+ reset-names = "usb";
+ nvidia,needs-double-reset;
+ nvidia,phy = <&phy1>;
+ status = "disabled";
+ };
+
+ phy1: usb-phy@c5000000 {
+ compatible = "nvidia,tegra20-usb-phy";
+ reg = <0xc5000000 0x4000 0xc5000000 0x4000>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA20_CLK_USBD>,
+ <&tegra_car TEGRA20_CLK_PLL_U>,
+ <&tegra_car TEGRA20_CLK_CLK_M>,
+ <&tegra_car TEGRA20_CLK_USBD>;
+ clock-names = "reg", "pll_u", "timer", "utmi-pads";
+ resets = <&tegra_car 22>, <&tegra_car 22>;
+ reset-names = "usb", "utmi-pads";
+ nvidia,has-legacy-mode;
+ nvidia,hssync-start-delay = <9>;
+ nvidia,idle-wait-delay = <17>;
+ nvidia,elastic-limit = <16>;
+ nvidia,term-range-adj = <6>;
+ nvidia,xcvr-setup = <9>;
+ nvidia,xcvr-lsfslew = <1>;
+ nvidia,xcvr-lsrslew = <1>;
+ nvidia,has-utmi-pad-registers;
+ status = "disabled";
+ };
+
+ usb@c5004000 {
+ compatible = "nvidia,tegra20-ehci", "usb-ehci";
+ reg = <0xc5004000 0x4000>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ phy_type = "ulpi";
+ clocks = <&tegra_car TEGRA20_CLK_USB2>;
+ resets = <&tegra_car 58>;
+ reset-names = "usb";
+ nvidia,phy = <&phy2>;
+ status = "disabled";
+ };
+
+ phy2: usb-phy@c5004000 {
+ compatible = "nvidia,tegra20-usb-phy";
+ reg = <0xc5004000 0x4000>;
+ phy_type = "ulpi";
+ clocks = <&tegra_car TEGRA20_CLK_USB2>,
+ <&tegra_car TEGRA20_CLK_PLL_U>,
+ <&tegra_car TEGRA20_CLK_CDEV2>;
+ clock-names = "reg", "pll_u", "ulpi-link";
+ resets = <&tegra_car 58>, <&tegra_car 22>;
+ reset-names = "usb", "utmi-pads";
+ status = "disabled";
+ };
+
+ usb@c5008000 {
+ compatible = "nvidia,tegra20-ehci", "usb-ehci";
+ reg = <0xc5008000 0x4000>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA20_CLK_USB3>;
+ resets = <&tegra_car 59>;
+ reset-names = "usb";
+ nvidia,phy = <&phy3>;
+ status = "disabled";
+ };
+
+ phy3: usb-phy@c5008000 {
+ compatible = "nvidia,tegra20-usb-phy";
+ reg = <0xc5008000 0x4000 0xc5000000 0x4000>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA20_CLK_USB3>,
+ <&tegra_car TEGRA20_CLK_PLL_U>,
+ <&tegra_car TEGRA20_CLK_CLK_M>,
+ <&tegra_car TEGRA20_CLK_USBD>;
+ clock-names = "reg", "pll_u", "timer", "utmi-pads";
+ resets = <&tegra_car 59>, <&tegra_car 22>;
+ reset-names = "usb", "utmi-pads";
+ nvidia,hssync-start-delay = <9>;
+ nvidia,idle-wait-delay = <17>;
+ nvidia,elastic-limit = <16>;
+ nvidia,term-range-adj = <6>;
+ nvidia,xcvr-setup = <9>;
+ nvidia,xcvr-lsfslew = <2>;
+ nvidia,xcvr-lsrslew = <2>;
+ status = "disabled";
+ };
+
+ sdhci@c8000000 {
+ compatible = "nvidia,tegra20-sdhci";
+ reg = <0xc8000000 0x200>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_SDMMC1>;
+ resets = <&tegra_car 14>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@c8000200 {
+ compatible = "nvidia,tegra20-sdhci";
+ reg = <0xc8000200 0x200>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_SDMMC2>;
+ resets = <&tegra_car 9>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@c8000400 {
+ compatible = "nvidia,tegra20-sdhci";
+ reg = <0xc8000400 0x200>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_SDMMC3>;
+ resets = <&tegra_car 69>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@c8000600 {
+ compatible = "nvidia,tegra20-sdhci";
+ reg = <0xc8000600 0x200>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_SDMMC4>;
+ resets = <&tegra_car 15>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ };
+};
diff --git a/arch/arm/boot/dts/tegra30-apalis-eval.dts b/arch/arm/boot/dts/tegra30-apalis-eval.dts
new file mode 100644
index 000000000..6236bdecb
--- /dev/null
+++ b/arch/arm/boot/dts/tegra30-apalis-eval.dts
@@ -0,0 +1,264 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra30-apalis.dtsi"
+
+/ {
+ model = "Toradex Apalis T30 on Apalis Evaluation Board";
+ compatible = "toradex,apalis_t30-eval", "toradex,apalis_t30", "nvidia,tegra30";
+
+ aliases {
+ rtc0 = "/i2c@7000c000/rtc@68";
+ rtc1 = "/i2c@7000d000/tps65911@2d";
+ rtc2 = "/rtc@7000e000";
+ serial0 = &uarta;
+ serial1 = &uartb;
+ serial2 = &uartc;
+ serial3 = &uartd;
+ };
+
+ pcie-controller@00003000 {
+ status = "okay";
+
+ pci@1,0 {
+ status = "okay";
+ };
+
+ pci@2,0 {
+ status = "okay";
+ };
+
+ pci@3,0 {
+ status = "okay";
+ };
+ };
+
+ host1x@50000000 {
+ dc@54200000 {
+ rgb {
+ status = "okay";
+ nvidia,panel = <&panel>;
+ };
+ };
+ hdmi@54280000 {
+ status = "okay";
+ };
+ };
+
+ serial@70006000 {
+ status = "okay";
+ };
+
+ serial@70006040 {
+ compatible = "nvidia,tegra30-hsuart";
+ status = "okay";
+ };
+
+ serial@70006200 {
+ compatible = "nvidia,tegra30-hsuart";
+ status = "okay";
+ };
+
+ serial@70006300 {
+ compatible = "nvidia,tegra30-hsuart";
+ status = "okay";
+ };
+
+ pwm@7000a000 {
+ status = "okay";
+ };
+
+ /*
+ * GEN1_I2C: I2C1_SDA/SCL on MXM3 pin 209/211 (e.g. RTC on carrier
+ * board)
+ */
+ i2c@7000c000 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ pcie-switch@58 {
+ compatible = "plx,pex8605";
+ reg = <0x58>;
+ };
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc@68 {
+ compatible = "st,m41t00";
+ reg = <0x68>;
+ };
+ };
+
+ /* GEN2_I2C: unused */
+
+ /*
+ * CAM_I2C: I2C3_SDA/SCL on MXM3 pin 201/203 (e.g. camera sensor on
+ * carrier board)
+ */
+ cami2c: i2c@7000c500 {
+ status = "okay";
+ clock-frequency = <400000>;
+ };
+
+ /* DDC: I2C2_SDA/SCL on MXM3 pin 205/207 (e.g. display EDID) */
+ hdmiddc: i2c@7000c700 {
+ status = "okay";
+ };
+
+ /* SPI1: Apalis SPI1 */
+ spi@7000d400 {
+ status = "okay";
+ spi-max-frequency = <25000000>;
+ spidev0: spidev@1 {
+ compatible = "spidev";
+ reg = <1>;
+ spi-max-frequency = <25000000>;
+ };
+ };
+
+ /* SPI5: Apalis SPI2 */
+ spi@7000dc00 {
+ status = "okay";
+ spi-max-frequency = <25000000>;
+ spidev1: spidev@2 {
+ compatible = "spidev";
+ reg = <2>;
+ spi-max-frequency = <25000000>;
+ };
+ };
+
+ sd1: sdhci@78000000 {
+ status = "okay";
+ bus-width = <4>;
+ /* SD1_CD# */
+ cd-gpios = <&gpio TEGRA_GPIO(CC, 5) GPIO_ACTIVE_LOW>;
+ no-1-8-v;
+ };
+
+ mmc1: sdhci@78000400 {
+ status = "okay";
+ bus-width = <8>;
+ /* MMC1_CD# */
+ cd-gpios = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_LOW>;
+ no-1-8-v;
+ };
+
+ /* EHCI instance 0: USB1_DP/N -> USBO1_DP/N */
+ usb@7d000000 {
+ status = "okay";
+ };
+
+ usb-phy@7d000000 {
+ status = "okay";
+ vbus-supply = <&usbo1_vbus_reg>;
+ };
+
+ /* EHCI instance 1: USB2_DP/N -> USBH2_DP/N */
+ usb@7d004000 {
+ status = "okay";
+ };
+
+ usb-phy@7d004000 {
+ status = "okay";
+ vbus-supply = <&usbh_vbus_reg>;
+ };
+
+ /* EHCI instance 2: USB3_DP/N -> USBH3_DP/N */
+ usb@7d008000 {
+ status = "okay";
+ };
+
+ usb-phy@7d008000 {
+ status = "okay";
+ vbus-supply = <&usbh_vbus_reg>;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+
+ /* PWM0 */
+ pwms = <&pwm 0 5000000>;
+ brightness-levels = <255 231 223 207 191 159 127 0>;
+ default-brightness-level = <6>;
+ /* BKL1_ON */
+ enable-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ panel: panel {
+ /*
+ * edt,et057090dhu: EDT 5.7" LCD TFT
+ * edt,et070080dh6: EDT 7.0" LCD TFT
+ */
+ compatible = "edt,et057090dhu", "simple-panel";
+
+ backlight = <&backlight>;
+ };
+
+ pwmleds {
+ compatible = "pwm-leds";
+
+ pwm1 {
+ label = "PWM1";
+ pwms = <&pwm 3 19600>;
+ max-brightness = <255>;
+ };
+
+ pwm2 {
+ label = "PWM2";
+ pwms = <&pwm 2 19600>;
+ max-brightness = <255>;
+ };
+
+ pwm3 {
+ label = "PWM3";
+ pwms = <&pwm 1 19600>;
+ max-brightness = <255>;
+ };
+ };
+
+ regulators {
+ sys_5v0_reg: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ /* USBO1_EN */
+ usbo1_vbus_reg: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "usbo1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(T, 5) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&sys_5v0_reg>;
+ };
+
+ /* USBH_EN */
+ usbh_vbus_reg: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "usbh_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(DD, 1) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&sys_5v0_reg>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra30-apalis.dtsi b/arch/arm/boot/dts/tegra30-apalis.dtsi
new file mode 100644
index 000000000..a5446cba9
--- /dev/null
+++ b/arch/arm/boot/dts/tegra30-apalis.dtsi
@@ -0,0 +1,687 @@
+#include "tegra30.dtsi"
+
+/*
+ * Toradex Apalis T30 Device Tree
+ * Compatible for Revisions 1GB: V1.0A; 2GB: V1.0B, V1.0C
+ */
+/ {
+ model = "Toradex Apalis T30";
+ compatible = "toradex,apalis_t30", "nvidia,tegra30";
+
+ pcie-controller@00003000 {
+ avdd-pexa-supply = <&vdd2_reg>;
+ vdd-pexa-supply = <&vdd2_reg>;
+ avdd-pexb-supply = <&vdd2_reg>;
+ vdd-pexb-supply = <&vdd2_reg>;
+ avdd-pex-pll-supply = <&vdd2_reg>;
+ avdd-plle-supply = <&ldo6_reg>;
+ vddio-pex-ctl-supply = <&sys_3v3_reg>;
+ hvdd-pex-supply = <&sys_3v3_reg>;
+
+ pci@1,0 {
+ nvidia,num-lanes = <4>;
+ };
+
+ pci@2,0 {
+ nvidia,num-lanes = <1>;
+ };
+
+ pci@3,0 {
+ nvidia,num-lanes = <1>;
+ };
+ };
+
+ host1x@50000000 {
+ hdmi@54280000 {
+ vdd-supply = <&sys_3v3_reg>;
+ pll-supply = <&vio_reg>;
+
+ nvidia,hpd-gpio =
+ <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
+ nvidia,ddc-i2c-bus = <&hdmiddc>;
+ };
+ };
+
+ pinmux@70000868 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ /* Apalis BKL1_ON */
+ pv2 {
+ nvidia,pins = "pv2";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Apalis BKL1_PWM */
+ uart3_rts_n_pc0 {
+ nvidia,pins = "uart3_rts_n_pc0";
+ nvidia,function = "pwm0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ /* BKL1_PWM_EN#, disable TPS65911 PMIC PWM backlight */
+ uart3_cts_n_pa1 {
+ nvidia,pins = "uart3_cts_n_pa1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Apalis CAN1 on SPI6 */
+ spi2_cs0_n_px3 {
+ nvidia,pins = "spi2_cs0_n_px3",
+ "spi2_miso_px1",
+ "spi2_mosi_px0",
+ "spi2_sck_px2";
+ nvidia,function = "spi6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ /* CAN_INT1 */
+ spi2_cs1_n_pw2 {
+ nvidia,pins = "spi2_cs1_n_pw2";
+ nvidia,function = "spi3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Apalis CAN2 on SPI4 */
+ gmi_a16_pj7 {
+ nvidia,pins = "gmi_a16_pj7",
+ "gmi_a17_pb0",
+ "gmi_a18_pb1",
+ "gmi_a19_pk7";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ /* CAN_INT2 */
+ spi2_cs2_n_pw3 {
+ nvidia,pins = "spi2_cs2_n_pw3";
+ nvidia,function = "spi3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Apalis I2C3 */
+ cam_i2c_scl_pbb1 {
+ nvidia,pins = "cam_i2c_scl_pbb1",
+ "cam_i2c_sda_pbb2";
+ nvidia,function = "i2c3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Apalis MMC1 */
+ sdmmc3_clk_pa6 {
+ nvidia,pins = "sdmmc3_clk_pa6",
+ "sdmmc3_cmd_pa7";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_dat0_pb7 {
+ nvidia,pins = "sdmmc3_dat0_pb7",
+ "sdmmc3_dat1_pb6",
+ "sdmmc3_dat2_pb5",
+ "sdmmc3_dat3_pb4",
+ "sdmmc3_dat4_pd1",
+ "sdmmc3_dat5_pd0",
+ "sdmmc3_dat6_pd3",
+ "sdmmc3_dat7_pd4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ /* Apalis MMC1_CD# */
+ pv3 {
+ nvidia,pins = "pv3";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Apalis PWM1 */
+ gpio_pu6 {
+ nvidia,pins = "gpio_pu6";
+ nvidia,function = "pwm3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Apalis PWM2 */
+ gpio_pu5 {
+ nvidia,pins = "gpio_pu5";
+ nvidia,function = "pwm2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Apalis PWM3 */
+ gpio_pu4 {
+ nvidia,pins = "gpio_pu4";
+ nvidia,function = "pwm1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Apalis PWM4 */
+ gpio_pu3 {
+ nvidia,pins = "gpio_pu3";
+ nvidia,function = "pwm0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Apalis RESET_MOCI# */
+ gmi_rst_n_pi4 {
+ nvidia,pins = "gmi_rst_n_pi4";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Apalis SD1 */
+ sdmmc1_clk_pz0 {
+ nvidia,pins = "sdmmc1_clk_pz0";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_cmd_pz1 {
+ nvidia,pins = "sdmmc1_cmd_pz1",
+ "sdmmc1_dat0_py7",
+ "sdmmc1_dat1_py6",
+ "sdmmc1_dat2_py5",
+ "sdmmc1_dat3_py4";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ /* Apalis SD1_CD# */
+ clk2_req_pcc5 {
+ nvidia,pins = "clk2_req_pcc5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Apalis SPI1 */
+ spi1_sck_px5 {
+ nvidia,pins = "spi1_sck_px5",
+ "spi1_mosi_px4",
+ "spi1_miso_px7",
+ "spi1_cs0_n_px6";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Apalis SPI2 */
+ lcd_sck_pz4 {
+ nvidia,pins = "lcd_sck_pz4",
+ "lcd_sdout_pn5",
+ "lcd_sdin_pz2",
+ "lcd_cs0_n_pn4";
+ nvidia,function = "spi5";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Apalis UART1 */
+ ulpi_data0 {
+ nvidia,pins = "ulpi_data0_po1",
+ "ulpi_data1_po2",
+ "ulpi_data2_po3",
+ "ulpi_data3_po4",
+ "ulpi_data4_po5",
+ "ulpi_data5_po6",
+ "ulpi_data6_po7",
+ "ulpi_data7_po0";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Apalis UART2 */
+ ulpi_clk_py0 {
+ nvidia,pins = "ulpi_clk_py0",
+ "ulpi_dir_py1",
+ "ulpi_nxt_py2",
+ "ulpi_stp_py3";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Apalis UART3 */
+ uart2_rxd_pc3 {
+ nvidia,pins = "uart2_rxd_pc3",
+ "uart2_txd_pc2";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Apalis UART4 */
+ uart3_rxd_pw7 {
+ nvidia,pins = "uart3_rxd_pw7",
+ "uart3_txd_pw6";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Apalis USBO1_EN */
+ gen2_i2c_scl_pt5 {
+ nvidia,pins = "gen2_i2c_scl_pt5";
+ nvidia,function = "rsvd4";
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Apalis USBO1_OC# */
+ gen2_i2c_sda_pt6 {
+ nvidia,pins = "gen2_i2c_sda_pt6";
+ nvidia,function = "rsvd4";
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Apalis WAKE1_MICO */
+ pv1 {
+ nvidia,pins = "pv1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* eMMC (On-module) */
+ sdmmc4_clk_pcc4 {
+ nvidia,pins = "sdmmc4_clk_pcc4",
+ "sdmmc4_rst_n_pcc3";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc4_dat0_paa0 {
+ nvidia,pins = "sdmmc4_dat0_paa0",
+ "sdmmc4_dat1_paa1",
+ "sdmmc4_dat2_paa2",
+ "sdmmc4_dat3_paa3",
+ "sdmmc4_dat4_paa4",
+ "sdmmc4_dat5_paa5",
+ "sdmmc4_dat6_paa6",
+ "sdmmc4_dat7_paa7";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* LVDS Transceiver Configuration */
+ pbb0 {
+ nvidia,pins = "pbb0",
+ "pbb7",
+ "pcc1",
+ "pcc2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ };
+ pbb3 {
+ nvidia,pins = "pbb3",
+ "pbb4",
+ "pbb5",
+ "pbb6";
+ nvidia,function = "displayb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Power I2C (On-module) */
+ pwr_i2c_scl_pz6 {
+ nvidia,pins = "pwr_i2c_scl_pz6",
+ "pwr_i2c_sda_pz7";
+ nvidia,function = "i2cpwr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+
+ /*
+ * THERMD_ALERT#, unlatched I2C address pin of LM95245
+ * temperature sensor therefore requires disabling for
+ * now
+ */
+ lcd_dc1_pd2 {
+ nvidia,pins = "lcd_dc1_pd2";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* TOUCH_PEN_INT# */
+ pv0 {
+ nvidia,pins = "pv0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ };
+ };
+
+ hdmiddc: i2c@7000c700 {
+ clock-frequency = <100000>;
+ };
+
+ /*
+ * PWR_I2C: power I2C to audio codec, PMIC, temperature sensor and
+ * touch screen controller
+ */
+ i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ pmic: tps65911@2d {
+ compatible = "ti,tps65911";
+ reg = <0x2d>;
+
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+
+ ti,system-power-controller;
+
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ vcc1-supply = <&sys_3v3_reg>;
+ vcc2-supply = <&sys_3v3_reg>;
+ vcc3-supply = <&vio_reg>;
+ vcc4-supply = <&sys_3v3_reg>;
+ vcc5-supply = <&sys_3v3_reg>;
+ vcc6-supply = <&vio_reg>;
+ vcc7-supply = <&charge_pump_5v0_reg>;
+ vccio-supply = <&sys_3v3_reg>;
+
+ regulators {
+ /* SW1: +V1.35_VDDIO_DDR */
+ vdd1_reg: vdd1 {
+ regulator-name = "vddio_ddr_1v35";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+
+ /* SW2: +V1.05 */
+ vdd2_reg: vdd2 {
+ regulator-name =
+ "vdd_pexa,vdd_pexb,vdd_sata";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ /* SW CTRL: +V1.0_VDD_CPU */
+ vddctrl_reg: vddctrl {
+ regulator-name = "vdd_cpu,vdd_sys";
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-always-on;
+ };
+
+ /* SWIO: +V1.8 */
+ vio_reg: vio {
+ regulator-name = "vdd_1v8_gen";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ /* LDO1: unused */
+
+ /*
+ * EN_+V3.3 switching via FET:
+ * +V3.3_AUDIO_AVDD_S, +V3.3 and +V1.8_VDD_LAN
+ * see also v3_3 fixed supply
+ */
+ ldo2_reg: ldo2 {
+ regulator-name = "en_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ /* +V1.2_CSI */
+ ldo3_reg: ldo3 {
+ regulator-name =
+ "avdd_dsi_csi,pwrdet_mipi";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ /* +V1.2_VDD_RTC */
+ ldo4_reg: ldo4 {
+ regulator-name = "vdd_rtc";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ /*
+ * +V2.8_AVDD_VDAC:
+ * only required for analog RGB
+ */
+ ldo5_reg: ldo5 {
+ regulator-name = "avdd_vdac";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ /*
+ * +V1.05_AVDD_PLLE: avdd_plle should be 1.05V
+ * but LDO6 can't set voltage in 50mV
+ * granularity
+ */
+ ldo6_reg: ldo6 {
+ regulator-name = "avdd_plle";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ };
+
+ /* +V1.2_AVDD_PLL */
+ ldo7_reg: ldo7 {
+ regulator-name = "avdd_pll";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ /* +V1.0_VDD_DDR_HS */
+ ldo8_reg: ldo8 {
+ regulator-name = "vdd_ddr_hs";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ /* STMPE811 touch screen controller */
+ stmpe811@41 {
+ compatible = "st,stmpe811";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x41>;
+ interrupts = <TEGRA_GPIO(V, 0) IRQ_TYPE_LEVEL_LOW>;
+ interrupt-parent = <&gpio>;
+ interrupt-controller;
+ id = <0>;
+ blocks = <0x5>;
+ irq-trigger = <0x1>;
+
+ stmpe_touchscreen {
+ compatible = "st,stmpe-ts";
+ reg = <0>;
+ /* 3.25 MHz ADC clock speed */
+ st,adc-freq = <1>;
+ /* 8 sample average control */
+ st,ave-ctrl = <3>;
+ /* 7 length fractional part in z */
+ st,fraction-z = <7>;
+ /*
+ * 50 mA typical 80 mA max touchscreen drivers
+ * current limit value
+ */
+ st,i-drive = <1>;
+ /* 12-bit ADC */
+ st,mod-12b = <1>;
+ /* internal ADC reference */
+ st,ref-sel = <0>;
+ /* ADC converstion time: 80 clocks */
+ st,sample-time = <4>;
+ /* 1 ms panel driver settling time */
+ st,settling = <3>;
+ /* 5 ms touch detect interrupt delay */
+ st,touch-det-delay = <5>;
+ };
+ };
+
+ /*
+ * LM95245 temperature sensor
+ * Note: OVERT_N directly connected to PMIC PWRDN
+ */
+ temp-sensor@4c {
+ compatible = "national,lm95245";
+ reg = <0x4c>;
+ };
+
+ /* SW: +V1.2_VDD_CORE */
+ tps62362@60 {
+ compatible = "ti,tps62362";
+ reg = <0x60>;
+
+ regulator-name = "tps62362-vout";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ti,vsel0-state-low;
+ /* VSEL1: EN_CORE_DVFS_N low for DVFS */
+ ti,vsel1-state-low;
+ };
+ };
+
+ /* SPI4: CAN2 */
+ spi@7000da00 {
+ status = "okay";
+ spi-max-frequency = <10000000>;
+
+ can@1 {
+ compatible = "microchip,mcp2515";
+ reg = <1>;
+ clocks = <&clk16m>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_LOW>;
+ spi-max-frequency = <10000000>;
+ };
+ };
+
+ /* SPI6: CAN1 */
+ spi@7000de00 {
+ status = "okay";
+ spi-max-frequency = <10000000>;
+
+ can@0 {
+ compatible = "microchip,mcp2515";
+ reg = <0>;
+ clocks = <&clk16m>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>;
+ spi-max-frequency = <10000000>;
+ };
+ };
+
+ pmc@7000e400 {
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <1>;
+ nvidia,cpu-pwr-good-time = <5000>;
+ nvidia,cpu-pwr-off-time = <5000>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <0>;
+ nvidia,core-power-req-active-high;
+ nvidia,sys-clock-req-active-high;
+ };
+
+ sdhci@78000600 {
+ status = "okay";
+ bus-width = <8>;
+ non-removable;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clk@0 {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ clk16m: clk@1 {
+ compatible = "fixed-clock";
+ reg=<1>;
+ #clock-cells = <0>;
+ clock-frequency = <16000000>;
+ clock-output-names = "clk16m";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sys_3v3_reg: regulator@100 {
+ compatible = "regulator-fixed";
+ reg = <100>;
+ regulator-name = "3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ charge_pump_5v0_reg: regulator@101 {
+ compatible = "regulator-fixed";
+ reg = <101>;
+ regulator-name = "5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra30-beaver.dts b/arch/arm/boot/dts/tegra30-beaver.dts
new file mode 100644
index 000000000..3dede3934
--- /dev/null
+++ b/arch/arm/boot/dts/tegra30-beaver.dts
@@ -0,0 +1,2104 @@
+/dts-v1/;
+
+#include "tegra30.dtsi"
+
+/ {
+ model = "NVIDIA Tegra30 Beaver evaluation board";
+ compatible = "nvidia,beaver", "nvidia,tegra30";
+
+ aliases {
+ rtc0 = "/i2c@7000d000/tps65911@2d";
+ rtc1 = "/rtc@7000e000";
+ serial0 = &uarta;
+ };
+
+ memory {
+ reg = <0x80000000 0x7ff00000>;
+ };
+
+ pcie-controller@00003000 {
+ status = "okay";
+
+ avdd-pexa-supply = <&ldo1_reg>;
+ vdd-pexa-supply = <&ldo1_reg>;
+ avdd-pexb-supply = <&ldo1_reg>;
+ vdd-pexb-supply = <&ldo1_reg>;
+ avdd-pex-pll-supply = <&ldo1_reg>;
+ avdd-plle-supply = <&ldo1_reg>;
+ vddio-pex-ctl-supply = <&sys_3v3_reg>;
+ hvdd-pex-supply = <&sys_3v3_pexs_reg>;
+
+ pci@1,0 {
+ status = "okay";
+ nvidia,num-lanes = <2>;
+ };
+
+ pci@2,0 {
+ nvidia,num-lanes = <2>;
+ };
+
+ pci@3,0 {
+ status = "okay";
+ nvidia,num-lanes = <2>;
+ };
+ };
+
+ host1x@50000000 {
+ hdmi@54280000 {
+ status = "okay";
+
+ hdmi-supply = <&vdd_5v0_hdmi>;
+ vdd-supply = <&sys_3v3_reg>;
+ pll-supply = <&vio_reg>;
+
+ nvidia,hpd-gpio =
+ <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
+ nvidia,ddc-i2c-bus = <&hdmiddc>;
+ };
+ };
+
+ pinmux@70000868 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ clk_32k_out_pa0 {
+ nvidia,pins = "clk_32k_out_pa0";
+ nvidia,function = "blink";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_cts_n_pa1 {
+ nvidia,pins = "uart3_cts_n_pa1";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_fs_pa2 {
+ nvidia,pins = "dap2_fs_pa2";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_sclk_pa3 {
+ nvidia,pins = "dap2_sclk_pa3";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_din_pa4 {
+ nvidia,pins = "dap2_din_pa4";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_dout_pa5 {
+ nvidia,pins = "dap2_dout_pa5";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_clk_pa6 {
+ nvidia,pins = "sdmmc3_clk_pa6";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_cmd_pa7 {
+ nvidia,pins = "sdmmc3_cmd_pa7";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_a17_pb0 {
+ nvidia,pins = "gmi_a17_pb0";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_a18_pb1 {
+ nvidia,pins = "gmi_a18_pb1";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_pwr0_pb2 {
+ nvidia,pins = "lcd_pwr0_pb2";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_pclk_pb3 {
+ nvidia,pins = "lcd_pclk_pb3";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat3_pb4 {
+ nvidia,pins = "sdmmc3_dat3_pb4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat2_pb5 {
+ nvidia,pins = "sdmmc3_dat2_pb5";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat1_pb6 {
+ nvidia,pins = "sdmmc3_dat1_pb6";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat0_pb7 {
+ nvidia,pins = "sdmmc3_dat0_pb7";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart3_rts_n_pc0 {
+ nvidia,pins = "uart3_rts_n_pc0";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_pwr1_pc1 {
+ nvidia,pins = "lcd_pwr1_pc1";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart2_txd_pc2 {
+ nvidia,pins = "uart2_txd_pc2";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rxd_pc3 {
+ nvidia,pins = "uart2_rxd_pc3";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gen1_i2c_scl_pc4 {
+ nvidia,pins = "gen1_i2c_scl_pc4";
+ nvidia,function = "i2c1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ gen1_i2c_sda_pc5 {
+ nvidia,pins = "gen1_i2c_sda_pc5";
+ nvidia,function = "i2c1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_pwr2_pc6 {
+ nvidia,pins = "lcd_pwr2_pc6";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_wp_n_pc7 {
+ nvidia,pins = "gmi_wp_n_pc7";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat5_pd0 {
+ nvidia,pins = "sdmmc3_dat5_pd0";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat4_pd1 {
+ nvidia,pins = "sdmmc3_dat4_pd1";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_dc1_pd2 {
+ nvidia,pins = "lcd_dc1_pd2";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat6_pd3 {
+ nvidia,pins = "sdmmc3_dat6_pd3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3_dat7_pd4 {
+ nvidia,pins = "sdmmc3_dat7_pd4";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ vi_d1_pd5 {
+ nvidia,pins = "vi_d1_pd5";
+ nvidia,function = "sdmmc2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ vi_vsync_pd6 {
+ nvidia,pins = "vi_vsync_pd6";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ vi_hsync_pd7 {
+ nvidia,pins = "vi_hsync_pd7";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d0_pe0 {
+ nvidia,pins = "lcd_d0_pe0";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d1_pe1 {
+ nvidia,pins = "lcd_d1_pe1";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d2_pe2 {
+ nvidia,pins = "lcd_d2_pe2";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d3_pe3 {
+ nvidia,pins = "lcd_d3_pe3";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d4_pe4 {
+ nvidia,pins = "lcd_d4_pe4";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d5_pe5 {
+ nvidia,pins = "lcd_d5_pe5";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d6_pe6 {
+ nvidia,pins = "lcd_d6_pe6";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d7_pe7 {
+ nvidia,pins = "lcd_d7_pe7";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d8_pf0 {
+ nvidia,pins = "lcd_d8_pf0";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d9_pf1 {
+ nvidia,pins = "lcd_d9_pf1";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d10_pf2 {
+ nvidia,pins = "lcd_d10_pf2";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d11_pf3 {
+ nvidia,pins = "lcd_d11_pf3";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d12_pf4 {
+ nvidia,pins = "lcd_d12_pf4";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d13_pf5 {
+ nvidia,pins = "lcd_d13_pf5";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d14_pf6 {
+ nvidia,pins = "lcd_d14_pf6";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d15_pf7 {
+ nvidia,pins = "lcd_d15_pf7";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_ad0_pg0 {
+ nvidia,pins = "gmi_ad0_pg0";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad1_pg1 {
+ nvidia,pins = "gmi_ad1_pg1";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad2_pg2 {
+ nvidia,pins = "gmi_ad2_pg2";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad3_pg3 {
+ nvidia,pins = "gmi_ad3_pg3";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad4_pg4 {
+ nvidia,pins = "gmi_ad4_pg4";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad5_pg5 {
+ nvidia,pins = "gmi_ad5_pg5";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad6_pg6 {
+ nvidia,pins = "gmi_ad6_pg6";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad7_pg7 {
+ nvidia,pins = "gmi_ad7_pg7";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad8_ph0 {
+ nvidia,pins = "gmi_ad8_ph0";
+ nvidia,function = "pwm0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad9_ph1 {
+ nvidia,pins = "gmi_ad9_ph1";
+ nvidia,function = "pwm1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad10_ph2 {
+ nvidia,pins = "gmi_ad10_ph2";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad11_ph3 {
+ nvidia,pins = "gmi_ad11_ph3";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_ad12_ph4 {
+ nvidia,pins = "gmi_ad12_ph4";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_ad13_ph5 {
+ nvidia,pins = "gmi_ad13_ph5";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_ad14_ph6 {
+ nvidia,pins = "gmi_ad14_ph6";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_wr_n_pi0 {
+ nvidia,pins = "gmi_wr_n_pi0";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_oe_n_pi1 {
+ nvidia,pins = "gmi_oe_n_pi1";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_dqs_pi2 {
+ nvidia,pins = "gmi_dqs_pi2";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_iordy_pi5 {
+ nvidia,pins = "gmi_iordy_pi5";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_cs7_n_pi6 {
+ nvidia,pins = "gmi_cs7_n_pi6";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_wait_pi7 {
+ nvidia,pins = "gmi_wait_pi7";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_de_pj1 {
+ nvidia,pins = "lcd_de_pj1";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_hsync_pj3 {
+ nvidia,pins = "lcd_hsync_pj3";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_vsync_pj4 {
+ nvidia,pins = "lcd_vsync_pj4";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart2_cts_n_pj5 {
+ nvidia,pins = "uart2_cts_n_pj5";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart2_rts_n_pj6 {
+ nvidia,pins = "uart2_rts_n_pj6";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_a16_pj7 {
+ nvidia,pins = "gmi_a16_pj7";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_adv_n_pk0 {
+ nvidia,pins = "gmi_adv_n_pk0";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_clk_pk1 {
+ nvidia,pins = "gmi_clk_pk1";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gmi_cs2_n_pk3 {
+ nvidia,pins = "gmi_cs2_n_pk3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_cs3_n_pk4 {
+ nvidia,pins = "gmi_cs3_n_pk4";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ spdif_out_pk5 {
+ nvidia,pins = "spdif_out_pk5";
+ nvidia,function = "spdif";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ spdif_in_pk6 {
+ nvidia,pins = "spdif_in_pk6";
+ nvidia,function = "spdif";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gmi_a19_pk7 {
+ nvidia,pins = "gmi_a19_pk7";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ vi_d2_pl0 {
+ nvidia,pins = "vi_d2_pl0";
+ nvidia,function = "sdmmc2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ vi_d3_pl1 {
+ nvidia,pins = "vi_d3_pl1";
+ nvidia,function = "sdmmc2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ vi_d4_pl2 {
+ nvidia,pins = "vi_d4_pl2";
+ nvidia,function = "vi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ vi_d5_pl3 {
+ nvidia,pins = "vi_d5_pl3";
+ nvidia,function = "sdmmc2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ vi_d6_pl4 {
+ nvidia,pins = "vi_d6_pl4";
+ nvidia,function = "vi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ vi_d7_pl5 {
+ nvidia,pins = "vi_d7_pl5";
+ nvidia,function = "sdmmc2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ vi_d8_pl6 {
+ nvidia,pins = "vi_d8_pl6";
+ nvidia,function = "sdmmc2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ vi_d9_pl7 {
+ nvidia,pins = "vi_d9_pl7";
+ nvidia,function = "sdmmc2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d16_pm0 {
+ nvidia,pins = "lcd_d16_pm0";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d17_pm1 {
+ nvidia,pins = "lcd_d17_pm1";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d18_pm2 {
+ nvidia,pins = "lcd_d18_pm2";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d19_pm3 {
+ nvidia,pins = "lcd_d19_pm3";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d20_pm4 {
+ nvidia,pins = "lcd_d20_pm4";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d21_pm5 {
+ nvidia,pins = "lcd_d21_pm5";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d22_pm6 {
+ nvidia,pins = "lcd_d22_pm6";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_d23_pm7 {
+ nvidia,pins = "lcd_d23_pm7";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap1_fs_pn0 {
+ nvidia,pins = "dap1_fs_pn0";
+ nvidia,function = "i2s0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap1_din_pn1 {
+ nvidia,pins = "dap1_din_pn1";
+ nvidia,function = "i2s0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap1_dout_pn2 {
+ nvidia,pins = "dap1_dout_pn2";
+ nvidia,function = "i2s0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap1_sclk_pn3 {
+ nvidia,pins = "dap1_sclk_pn3";
+ nvidia,function = "i2s0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_cs0_n_pn4 {
+ nvidia,pins = "lcd_cs0_n_pn4";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_sdout_pn5 {
+ nvidia,pins = "lcd_sdout_pn5";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_dc0_pn6 {
+ nvidia,pins = "lcd_dc0_pn6";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ hdmi_int_pn7 {
+ nvidia,pins = "hdmi_int_pn7";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_data7_po0 {
+ nvidia,pins = "ulpi_data7_po0";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data0_po1 {
+ nvidia,pins = "ulpi_data0_po1";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_data1_po2 {
+ nvidia,pins = "ulpi_data1_po2";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_data2_po3 {
+ nvidia,pins = "ulpi_data2_po3";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_data3_po4 {
+ nvidia,pins = "ulpi_data3_po4";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_data4_po5 {
+ nvidia,pins = "ulpi_data4_po5";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_data5_po6 {
+ nvidia,pins = "ulpi_data5_po6";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_data6_po7 {
+ nvidia,pins = "ulpi_data6_po7";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap3_fs_pp0 {
+ nvidia,pins = "dap3_fs_pp0";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap3_din_pp1 {
+ nvidia,pins = "dap3_din_pp1";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap3_dout_pp2 {
+ nvidia,pins = "dap3_dout_pp2";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap3_sclk_pp3 {
+ nvidia,pins = "dap3_sclk_pp3";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap4_fs_pp4 {
+ nvidia,pins = "dap4_fs_pp4";
+ nvidia,function = "i2s3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap4_din_pp5 {
+ nvidia,pins = "dap4_din_pp5";
+ nvidia,function = "i2s3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap4_dout_pp6 {
+ nvidia,pins = "dap4_dout_pp6";
+ nvidia,function = "i2s3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap4_sclk_pp7 {
+ nvidia,pins = "dap4_sclk_pp7";
+ nvidia,function = "i2s3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col0_pq0 {
+ nvidia,pins = "kb_col0_pq0";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col1_pq1 {
+ nvidia,pins = "kb_col1_pq1";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col2_pq2 {
+ nvidia,pins = "kb_col2_pq2";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col3_pq3 {
+ nvidia,pins = "kb_col3_pq3";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col4_pq4 {
+ nvidia,pins = "kb_col4_pq4";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col5_pq5 {
+ nvidia,pins = "kb_col5_pq5";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col6_pq6 {
+ nvidia,pins = "kb_col6_pq6";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col7_pq7 {
+ nvidia,pins = "kb_col7_pq7";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row0_pr0 {
+ nvidia,pins = "kb_row0_pr0";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row1_pr1 {
+ nvidia,pins = "kb_row1_pr1";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row2_pr2 {
+ nvidia,pins = "kb_row2_pr2";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row3_pr3 {
+ nvidia,pins = "kb_row3_pr3";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row4_pr4 {
+ nvidia,pins = "kb_row4_pr4";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row5_pr5 {
+ nvidia,pins = "kb_row5_pr5";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row6_pr6 {
+ nvidia,pins = "kb_row6_pr6";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row7_pr7 {
+ nvidia,pins = "kb_row7_pr7";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row8_ps0 {
+ nvidia,pins = "kb_row8_ps0";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row9_ps1 {
+ nvidia,pins = "kb_row9_ps1";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row10_ps2 {
+ nvidia,pins = "kb_row10_ps2";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row11_ps3 {
+ nvidia,pins = "kb_row11_ps3";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row12_ps4 {
+ nvidia,pins = "kb_row12_ps4";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row13_ps5 {
+ nvidia,pins = "kb_row13_ps5";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row14_ps6 {
+ nvidia,pins = "kb_row14_ps6";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row15_ps7 {
+ nvidia,pins = "kb_row15_ps7";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ vi_pclk_pt0 {
+ nvidia,pins = "vi_pclk_pt0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ vi_mclk_pt1 {
+ nvidia,pins = "vi_mclk_pt1";
+ nvidia,function = "vi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ vi_d10_pt2 {
+ nvidia,pins = "vi_d10_pt2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ vi_d11_pt3 {
+ nvidia,pins = "vi_d11_pt3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ vi_d0_pt4 {
+ nvidia,pins = "vi_d0_pt4";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ gen2_i2c_scl_pt5 {
+ nvidia,pins = "gen2_i2c_scl_pt5";
+ nvidia,function = "i2c2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ gen2_i2c_sda_pt6 {
+ nvidia,pins = "gen2_i2c_sda_pt6";
+ nvidia,function = "i2c2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_cmd_pt7 {
+ nvidia,pins = "sdmmc4_cmd_pt7";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu0 {
+ nvidia,pins = "pu0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu1 {
+ nvidia,pins = "pu1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pu2 {
+ nvidia,pins = "pu2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu3 {
+ nvidia,pins = "pu3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pu4 {
+ nvidia,pins = "pu4";
+ nvidia,function = "pwm1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pu5 {
+ nvidia,pins = "pu5";
+ nvidia,function = "pwm2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pu6 {
+ nvidia,pins = "pu6";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ jtag_rtck_pu7 {
+ nvidia,pins = "jtag_rtck_pu7";
+ nvidia,function = "rtck";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pv0 {
+ nvidia,pins = "pv0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pv2 {
+ nvidia,pins = "pv2";
+ nvidia,function = "owr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pv3 {
+ nvidia,pins = "pv3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ddc_scl_pv4 {
+ nvidia,pins = "ddc_scl_pv4";
+ nvidia,function = "i2c4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ddc_sda_pv5 {
+ nvidia,pins = "ddc_sda_pv5";
+ nvidia,function = "i2c4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ crt_hsync_pv6 {
+ nvidia,pins = "crt_hsync_pv6";
+ nvidia,function = "crt";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ crt_vsync_pv7 {
+ nvidia,pins = "crt_vsync_pv7";
+ nvidia,function = "crt";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_cs1_n_pw0 {
+ nvidia,pins = "lcd_cs1_n_pw0";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_m1_pw1 {
+ nvidia,pins = "lcd_m1_pw1";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ spi2_cs1_n_pw2 {
+ nvidia,pins = "spi2_cs1_n_pw2";
+ nvidia,function = "spi2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ clk1_out_pw4 {
+ nvidia,pins = "clk1_out_pw4";
+ nvidia,function = "extperiph1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ clk2_out_pw5 {
+ nvidia,pins = "clk2_out_pw5";
+ nvidia,function = "extperiph2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uart3_txd_pw6 {
+ nvidia,pins = "uart3_txd_pw6";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_rxd_pw7 {
+ nvidia,pins = "uart3_rxd_pw7";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ spi2_sck_px2 {
+ nvidia,pins = "spi2_sck_px2";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ spi1_mosi_px4 {
+ nvidia,pins = "spi1_mosi_px4";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ spi1_sck_px5 {
+ nvidia,pins = "spi1_sck_px5";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ spi1_cs0_n_px6 {
+ nvidia,pins = "spi1_cs0_n_px6";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ spi1_miso_px7 {
+ nvidia,pins = "spi1_miso_px7";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_clk_py0 {
+ nvidia,pins = "ulpi_clk_py0";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_dir_py1 {
+ nvidia,pins = "ulpi_dir_py1";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_nxt_py2 {
+ nvidia,pins = "ulpi_nxt_py2";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ulpi_stp_py3 {
+ nvidia,pins = "ulpi_stp_py3";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat3_py4 {
+ nvidia,pins = "sdmmc1_dat3_py4";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_dat2_py5 {
+ nvidia,pins = "sdmmc1_dat2_py5";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_dat1_py6 {
+ nvidia,pins = "sdmmc1_dat1_py6";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_dat0_py7 {
+ nvidia,pins = "sdmmc1_dat0_py7";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_clk_pz0 {
+ nvidia,pins = "sdmmc1_clk_pz0";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_cmd_pz1 {
+ nvidia,pins = "sdmmc1_cmd_pz1";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_sdin_pz2 {
+ nvidia,pins = "lcd_sdin_pz2";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_wr_n_pz3 {
+ nvidia,pins = "lcd_wr_n_pz3";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_sck_pz4 {
+ nvidia,pins = "lcd_sck_pz4";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sys_clk_req_pz5 {
+ nvidia,pins = "sys_clk_req_pz5";
+ nvidia,function = "sysclk";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_i2c_scl_pz6 {
+ nvidia,pins = "pwr_i2c_scl_pz6";
+ nvidia,function = "i2cpwr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ pwr_i2c_sda_pz7 {
+ nvidia,pins = "pwr_i2c_sda_pz7";
+ nvidia,function = "i2cpwr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat0_paa0 {
+ nvidia,pins = "sdmmc4_dat0_paa0";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat1_paa1 {
+ nvidia,pins = "sdmmc4_dat1_paa1";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat2_paa2 {
+ nvidia,pins = "sdmmc4_dat2_paa2";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat3_paa3 {
+ nvidia,pins = "sdmmc4_dat3_paa3";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat4_paa4 {
+ nvidia,pins = "sdmmc4_dat4_paa4";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat5_paa5 {
+ nvidia,pins = "sdmmc4_dat5_paa5";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat6_paa6 {
+ nvidia,pins = "sdmmc4_dat6_paa6";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_dat7_paa7 {
+ nvidia,pins = "sdmmc4_dat7_paa7";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pbb0 {
+ nvidia,pins = "pbb0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ cam_i2c_scl_pbb1 {
+ nvidia,pins = "cam_i2c_scl_pbb1";
+ nvidia,function = "i2c3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ cam_i2c_sda_pbb2 {
+ nvidia,pins = "cam_i2c_sda_pbb2";
+ nvidia,function = "i2c3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ pbb3 {
+ nvidia,pins = "pbb3";
+ nvidia,function = "vgp3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pbb4 {
+ nvidia,pins = "pbb4";
+ nvidia,function = "vgp4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pbb5 {
+ nvidia,pins = "pbb5";
+ nvidia,function = "vgp5";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pbb6 {
+ nvidia,pins = "pbb6";
+ nvidia,function = "vgp6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pbb7 {
+ nvidia,pins = "pbb7";
+ nvidia,function = "i2s4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ cam_mclk_pcc0 {
+ nvidia,pins = "cam_mclk_pcc0";
+ nvidia,function = "vi_alt3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pcc1 {
+ nvidia,pins = "pcc1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pcc2 {
+ nvidia,pins = "pcc2";
+ nvidia,function = "i2s4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_rst_n_pcc3 {
+ nvidia,pins = "sdmmc4_rst_n_pcc3";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4_clk_pcc4 {
+ nvidia,pins = "sdmmc4_clk_pcc4";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ clk2_req_pcc5 {
+ nvidia,pins = "clk2_req_pcc5";
+ nvidia,function = "dap";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pex_l2_rst_n_pcc6 {
+ nvidia,pins = "pex_l2_rst_n_pcc6";
+ nvidia,function = "pcie";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l2_clkreq_n_pcc7 {
+ nvidia,pins = "pex_l2_clkreq_n_pcc7";
+ nvidia,function = "pcie";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pex_l0_prsnt_n_pdd0 {
+ nvidia,pins = "pex_l0_prsnt_n_pdd0";
+ nvidia,function = "pcie";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pex_l0_rst_n_pdd1 {
+ nvidia,pins = "pex_l0_rst_n_pdd1";
+ nvidia,function = "pcie";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l0_clkreq_n_pdd2 {
+ nvidia,pins = "pex_l0_clkreq_n_pdd2";
+ nvidia,function = "pcie";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pex_wake_n_pdd3 {
+ nvidia,pins = "pex_wake_n_pdd3";
+ nvidia,function = "pcie";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pex_l1_prsnt_n_pdd4 {
+ nvidia,pins = "pex_l1_prsnt_n_pdd4";
+ nvidia,function = "pcie";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pex_l1_rst_n_pdd5 {
+ nvidia,pins = "pex_l1_rst_n_pdd5";
+ nvidia,function = "pcie";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l1_clkreq_n_pdd6 {
+ nvidia,pins = "pex_l1_clkreq_n_pdd6";
+ nvidia,function = "pcie";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pex_l2_prsnt_n_pdd7 {
+ nvidia,pins = "pex_l2_prsnt_n_pdd7";
+ nvidia,function = "pcie";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ clk3_out_pee0 {
+ nvidia,pins = "clk3_out_pee0";
+ nvidia,function = "extperiph3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ clk3_req_pee1 {
+ nvidia,pins = "clk3_req_pee1";
+ nvidia,function = "dev3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ clk1_req_pee2 {
+ nvidia,pins = "clk1_req_pee2";
+ nvidia,function = "dap";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ hdmi_cec_pee3 {
+ nvidia,pins = "hdmi_cec_pee3";
+ nvidia,function = "cec";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ owr {
+ nvidia,pins = "owr";
+ nvidia,function = "owr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdio3 {
+ nvidia,pins = "drive_sdio3";
+ nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,pull-down-strength = <46>;
+ nvidia,pull-up-strength = <42>;
+ nvidia,slew-rate-rising = <1>;
+ nvidia,slew-rate-falling = <1>;
+ };
+ gpv {
+ nvidia,pins = "drive_gpv";
+ nvidia,pull-up-strength = <16>;
+ };
+ };
+ };
+
+ serial@70006000 {
+ status = "okay";
+ };
+
+ i2c@7000c000 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@7000c400 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@7000c500 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ hdmiddc: i2c@7000c700 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ rt5640: rt5640@1c {
+ compatible = "realtek,rt5640";
+ reg = <0x1c>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(X, 3) GPIO_ACTIVE_HIGH>;
+ realtek,ldo1-en-gpios =
+ <&gpio TEGRA_GPIO(X, 2) GPIO_ACTIVE_HIGH>;
+ };
+
+ pmic: tps65911@2d {
+ compatible = "ti,tps65911";
+ reg = <0x2d>;
+
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+
+ ti,system-power-controller;
+
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ vcc1-supply = <&vdd_5v_in_reg>;
+ vcc2-supply = <&vdd_5v_in_reg>;
+ vcc3-supply = <&vio_reg>;
+ vcc4-supply = <&vdd_5v_in_reg>;
+ vcc5-supply = <&vdd_5v_in_reg>;
+ vcc6-supply = <&vdd2_reg>;
+ vcc7-supply = <&vdd_5v_in_reg>;
+ vccio-supply = <&vdd_5v_in_reg>;
+
+ regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdd1_reg: vdd1 {
+ regulator-name = "vddio_ddr_1v2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ vdd2_reg: vdd2 {
+ regulator-name = "vdd_1v5_gen";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ };
+
+ vddctrl_reg: vddctrl {
+ regulator-name = "vdd_cpu,vdd_sys";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ vio_reg: vio {
+ regulator-name = "vdd_1v8_gen";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo1_reg: ldo1 {
+ regulator-name = "vdd_pexa,vdd_pexb";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ ldo2_reg: ldo2 {
+ regulator-name = "vdd_sata,avdd_plle";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ /* LDO3 is not connected to anything */
+
+ ldo4_reg: ldo4 {
+ regulator-name = "vdd_rtc";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ ldo5_reg: ldo5 {
+ regulator-name = "vddio_sdmmc,avdd_vdac";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo6_reg: ldo6 {
+ regulator-name = "avdd_dsi_csi,pwrdet_mipi";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo7_reg: ldo7 {
+ regulator-name = "vdd_pllm,x,u,a_p_c_s";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ ldo8_reg: ldo8 {
+ regulator-name = "vdd_ddr_hs";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ tps62361@60 {
+ compatible = "ti,tps62361";
+ reg = <0x60>;
+
+ regulator-name = "tps62361-vout";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ti,vsel0-state-high;
+ ti,vsel1-state-high;
+ };
+ };
+
+ spi@7000da00 {
+ status = "okay";
+ spi-max-frequency = <25000000>;
+ spi-flash@1 {
+ compatible = "winbond,w25q32";
+ reg = <1>;
+ spi-max-frequency = <20000000>;
+ };
+ };
+
+ pmc@7000e400 {
+ status = "okay";
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <1>;
+ nvidia,cpu-pwr-good-time = <2000>;
+ nvidia,cpu-pwr-off-time = <200>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <0>;
+ nvidia,core-power-req-active-high;
+ nvidia,sys-clock-req-active-high;
+ };
+
+ ahub@70080000 {
+ i2s@70080400 {
+ status = "okay";
+ };
+ };
+
+ sdhci@78000000 {
+ status = "okay";
+ cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio TEGRA_GPIO(T, 3) GPIO_ACTIVE_HIGH>;
+ power-gpios = <&gpio TEGRA_GPIO(D, 7) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ };
+
+ sdhci@78000600 {
+ status = "okay";
+ bus-width = <8>;
+ non-removable;
+ };
+
+ usb@7d004000 {
+ status = "okay";
+ };
+
+ phy2: usb-phy@7d004000 {
+ vbus-supply = <&sys_3v3_reg>;
+ status = "okay";
+ };
+
+ usb@7d008000 {
+ status = "okay";
+ };
+
+ usb-phy@7d008000 {
+ vbus-supply = <&usb3_vbus_reg>;
+ status = "okay";
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock@0 {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ gpled1 {
+ label = "LED1"; /* CR5A1 (blue) */
+ gpios = <&gpio TEGRA_GPIO(L, 1) GPIO_ACTIVE_HIGH>;
+ };
+ gpled2 {
+ label = "LED2"; /* CR4A2 (green) */
+ gpios = <&gpio TEGRA_GPIO(L, 0) GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdd_5v_in_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vdd_5v_in";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ chargepump_5v_reg: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "chargepump_5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ enable-active-high;
+ gpio = <&pmic 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ ddr_reg: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "vdd_ddr";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&pmic 7 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&vdd_5v_in_reg>;
+ };
+
+ vdd_5v_sata_reg: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "vdd_5v_sata";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(D, 6) GPIO_ACTIVE_HIGH>;
+ vin-supply = <&vdd_5v_in_reg>;
+ };
+
+ usb1_vbus_reg: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(DD, 6) GPIO_ACTIVE_HIGH>;
+ gpio-open-drain;
+ vin-supply = <&vdd_5v_in_reg>;
+ };
+
+ usb3_vbus_reg: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "usb3_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(DD, 4) GPIO_ACTIVE_HIGH>;
+ gpio-open-drain;
+ vin-supply = <&vdd_5v_in_reg>;
+ };
+
+ sys_3v3_reg: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ regulator-name = "sys_3v3,vdd_3v3_alw";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&vdd_5v_in_reg>;
+ };
+
+ sys_3v3_pexs_reg: regulator@7 {
+ compatible = "regulator-fixed";
+ reg = <7>;
+ regulator-name = "sys_3v3_pexs";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(L, 7) GPIO_ACTIVE_HIGH>;
+ vin-supply = <&sys_3v3_reg>;
+ };
+
+ vdd_5v0_hdmi: regulator@8 {
+ compatible = "regulator-fixed";
+ reg = <8>;
+ regulator-name = "+VDD_5V_HDMI";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&sys_3v3_reg>;
+ };
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-rt5640-beaver",
+ "nvidia,tegra-audio-rt5640";
+ nvidia,model = "NVIDIA Tegra Beaver";
+
+ nvidia,audio-routing =
+ "Headphones", "HPOR",
+ "Headphones", "HPOL",
+ "Mic Jack", "MICBIAS1",
+ "IN2P", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&rt5640>;
+
+ nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>;
+
+ clocks = <&tegra_car TEGRA30_CLK_PLL_A>,
+ <&tegra_car TEGRA30_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA30_CLK_EXTERN1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
+};
diff --git a/arch/arm/boot/dts/tegra30-cardhu-a02.dts b/arch/arm/boot/dts/tegra30-cardhu-a02.dts
new file mode 100644
index 000000000..c9bfedcca
--- /dev/null
+++ b/arch/arm/boot/dts/tegra30-cardhu-a02.dts
@@ -0,0 +1,94 @@
+/dts-v1/;
+
+#include "tegra30-cardhu.dtsi"
+
+/* This dts file support the cardhu A02 version of board */
+
+/ {
+ model = "NVIDIA Tegra30 Cardhu A02 evaluation board";
+ compatible = "nvidia,cardhu-a02", "nvidia,cardhu", "nvidia,tegra30";
+
+ sdhci@78000400 {
+ status = "okay";
+ power-gpios = <&gpio TEGRA_GPIO(D, 4) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ keep-power-in-suspend;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ddr_reg: regulator@100 {
+ compatible = "regulator-fixed";
+ reg = <100>;
+ regulator-name = "vdd_ddr";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+ };
+
+ sys_3v3_reg: regulator@101 {
+ compatible = "regulator-fixed";
+ reg = <101>;
+ regulator-name = "sys_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&pmic 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ usb1_vbus_reg: regulator@102 {
+ compatible = "regulator-fixed";
+ reg = <102>;
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(I, 4) GPIO_ACTIVE_HIGH>;
+ gpio-open-drain;
+ vin-supply = <&vdd_5v0_reg>;
+ };
+
+ usb3_vbus_reg: regulator@103 {
+ compatible = "regulator-fixed";
+ reg = <103>;
+ regulator-name = "usb3_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(H, 7) GPIO_ACTIVE_HIGH>;
+ gpio-open-drain;
+ vin-supply = <&vdd_5v0_reg>;
+ };
+
+ vdd_5v0_reg: regulator@104 {
+ compatible = "regulator-fixed";
+ reg = <104>;
+ regulator-name = "5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&pmic 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ vdd_bl_reg: regulator@105 {
+ compatible = "regulator-fixed";
+ reg = <105>;
+ regulator-name = "vdd_bl";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(K, 3) GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
diff --git a/arch/arm/boot/dts/tegra30-cardhu-a04.dts b/arch/arm/boot/dts/tegra30-cardhu-a04.dts
new file mode 100644
index 000000000..fadf55e46
--- /dev/null
+++ b/arch/arm/boot/dts/tegra30-cardhu-a04.dts
@@ -0,0 +1,105 @@
+/dts-v1/;
+
+#include "tegra30-cardhu.dtsi"
+
+/* This dts file support the cardhu A04 and later versions of board */
+
+/ {
+ model = "NVIDIA Tegra30 Cardhu A04 (A05, A06, A07) evaluation board";
+ compatible = "nvidia,cardhu-a04", "nvidia,cardhu", "nvidia,tegra30";
+
+ sdhci@78000400 {
+ status = "okay";
+ power-gpios = <&gpio TEGRA_GPIO(D, 3) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ keep-power-in-suspend;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ddr_reg: regulator@100 {
+ compatible = "regulator-fixed";
+ regulator-name = "ddr";
+ reg = <100>;
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&pmic 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ sys_3v3_reg: regulator@101 {
+ compatible = "regulator-fixed";
+ reg = <101>;
+ regulator-name = "sys_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+ };
+
+ usb1_vbus_reg: regulator@102 {
+ compatible = "regulator-fixed";
+ reg = <102>;
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(DD, 6) GPIO_ACTIVE_HIGH>;
+ gpio-open-drain;
+ vin-supply = <&vdd_5v0_reg>;
+ };
+
+ usb3_vbus_reg: regulator@103 {
+ compatible = "regulator-fixed";
+ reg = <103>;
+ regulator-name = "usb3_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(DD, 4) GPIO_ACTIVE_HIGH>;
+ gpio-open-drain;
+ vin-supply = <&vdd_5v0_reg>;
+ };
+
+ vdd_5v0_reg: regulator@104 {
+ compatible = "regulator-fixed";
+ reg = <104>;
+ regulator-name = "5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&pmic 8 GPIO_ACTIVE_HIGH>;
+ };
+
+ vdd_bl_reg: regulator@105 {
+ compatible = "regulator-fixed";
+ reg = <105>;
+ regulator-name = "vdd_bl";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(DD, 2) GPIO_ACTIVE_HIGH>;
+ };
+
+ vdd_bl2_reg: regulator@106 {
+ compatible = "regulator-fixed";
+ reg = <106>;
+ regulator-name = "vdd_bl2";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(DD, 0) GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi
new file mode 100644
index 000000000..a1b682ea0
--- /dev/null
+++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi
@@ -0,0 +1,618 @@
+#include "tegra30.dtsi"
+
+/**
+ * This file contains common DT entry for all fab version of Cardhu.
+ * There is multiple fab version of Cardhu starting from A01 to A07.
+ * Cardhu fab version A01 and A03 are not supported. Cardhu fab version
+ * A02 will have different sets of GPIOs for fixed regulator compare to
+ * Cardhu fab version A04. The Cardhu fab version A05, A06, A07 are
+ * compatible with fab version A04. Based on Cardhu fab version, the
+ * related dts file need to be chosen like for Cardhu fab version A02,
+ * use tegra30-cardhu-a02.dts, Cardhu fab version A04 and later, use
+ * tegra30-cardhu-a04.dts.
+ * The identification of board is done in two ways, by looking the sticker
+ * on PCB and by reading board id eeprom.
+ * The stciker will have number like 600-81291-1000-002 C.3. In this 4th
+ * number is the fab version like here it is 002 and hence fab version A02.
+ * The (downstream internal) U-Boot of Cardhu display the board-id as
+ * follows:
+ * BoardID: 0C5B, SKU: 0A01, Fab: 02, Rev: 45.00
+ * In this Fab version is 02 i.e. A02.
+ * The BoardID I2C eeprom is interfaced through i2c5 (pwr_i2c address 0x56).
+ * The location 0x8 of this eeprom contains the Fab version. It is 1 byte
+ * wide.
+ */
+
+/ {
+ model = "NVIDIA Tegra30 Cardhu evaluation board";
+ compatible = "nvidia,cardhu", "nvidia,tegra30";
+
+ aliases {
+ rtc0 = "/i2c@7000d000/tps65911@2d";
+ rtc1 = "/rtc@7000e000";
+ serial0 = &uarta;
+ serial1 = &uartc;
+ };
+
+ memory {
+ reg = <0x80000000 0x40000000>;
+ };
+
+ pcie-controller@00003000 {
+ status = "okay";
+
+ /* AVDD_PEXA and VDD_PEXA inputs are grounded on Cardhu. */
+ avdd-pexb-supply = <&ldo1_reg>;
+ vdd-pexb-supply = <&ldo1_reg>;
+ avdd-pex-pll-supply = <&ldo1_reg>;
+ hvdd-pex-supply = <&pex_hvdd_3v3_reg>;
+ vddio-pex-ctl-supply = <&sys_3v3_reg>;
+ avdd-plle-supply = <&ldo2_reg>;
+
+ pci@1,0 {
+ nvidia,num-lanes = <4>;
+ };
+
+ pci@2,0 {
+ nvidia,num-lanes = <1>;
+ };
+
+ pci@3,0 {
+ status = "okay";
+ nvidia,num-lanes = <1>;
+ };
+ };
+
+ host1x@50000000 {
+ dc@54200000 {
+ rgb {
+ status = "okay";
+
+ nvidia,panel = <&panel>;
+ };
+ };
+ };
+
+ pinmux@70000868 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ sdmmc1_clk_pz0 {
+ nvidia,pins = "sdmmc1_clk_pz0";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_cmd_pz1 {
+ nvidia,pins = "sdmmc1_cmd_pz1",
+ "sdmmc1_dat0_py7",
+ "sdmmc1_dat1_py6",
+ "sdmmc1_dat2_py5",
+ "sdmmc1_dat3_py4";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_clk_pa6 {
+ nvidia,pins = "sdmmc3_clk_pa6";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_cmd_pa7 {
+ nvidia,pins = "sdmmc3_cmd_pa7",
+ "sdmmc3_dat0_pb7",
+ "sdmmc3_dat1_pb6",
+ "sdmmc3_dat2_pb5",
+ "sdmmc3_dat3_pb4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc4_clk_pcc4 {
+ nvidia,pins = "sdmmc4_clk_pcc4",
+ "sdmmc4_rst_n_pcc3";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc4_dat0_paa0 {
+ nvidia,pins = "sdmmc4_dat0_paa0",
+ "sdmmc4_dat1_paa1",
+ "sdmmc4_dat2_paa2",
+ "sdmmc4_dat3_paa3",
+ "sdmmc4_dat4_paa4",
+ "sdmmc4_dat5_paa5",
+ "sdmmc4_dat6_paa6",
+ "sdmmc4_dat7_paa7";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_fs_pa2 {
+ nvidia,pins = "dap2_fs_pa2",
+ "dap2_sclk_pa3",
+ "dap2_din_pa4",
+ "dap2_dout_pa5";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdio3 {
+ nvidia,pins = "drive_sdio3";
+ nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,pull-down-strength = <46>;
+ nvidia,pull-up-strength = <42>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FAST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FAST>;
+ };
+ uart3_txd_pw6 {
+ nvidia,pins = "uart3_txd_pw6",
+ "uart3_cts_n_pa1",
+ "uart3_rts_n_pc0",
+ "uart3_rxd_pw7";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ };
+ };
+
+ serial@70006000 {
+ status = "okay";
+ };
+
+ serial@70006200 {
+ compatible = "nvidia,tegra30-hsuart";
+ status = "okay";
+ };
+
+ pwm@7000a000 {
+ status = "okay";
+ };
+
+ panelddc: i2c@7000c000 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@7000c400 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@7000c500 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ /* ALS and Proximity sensor */
+ isl29028@44 {
+ compatible = "isil,isl29028";
+ reg = <0x44>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(L, 0) IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ i2cmux@70 {
+ compatible = "nxp,pca9546";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70>;
+ };
+ };
+
+ i2c@7000c700 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ wm8903: wm8903@1a {
+ compatible = "wlf,wm8903";
+ reg = <0x1a>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_LEVEL_HIGH>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ micdet-cfg = <0>;
+ micdet-delay = <100>;
+ gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>;
+ };
+
+ pmic: tps65911@2d {
+ compatible = "ti,tps65911";
+ reg = <0x2d>;
+
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+
+ ti,system-power-controller;
+
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ vcc1-supply = <&vdd_ac_bat_reg>;
+ vcc2-supply = <&vdd_ac_bat_reg>;
+ vcc3-supply = <&vio_reg>;
+ vcc4-supply = <&vdd_5v0_reg>;
+ vcc5-supply = <&vdd_ac_bat_reg>;
+ vcc6-supply = <&vdd2_reg>;
+ vcc7-supply = <&vdd_ac_bat_reg>;
+ vccio-supply = <&vdd_ac_bat_reg>;
+
+ regulators {
+ vdd1_reg: vdd1 {
+ regulator-name = "vddio_ddr_1v2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ vdd2_reg: vdd2 {
+ regulator-name = "vdd_1v5_gen";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ };
+
+ vddctrl_reg: vddctrl {
+ regulator-name = "vdd_cpu,vdd_sys";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ vio_reg: vio {
+ regulator-name = "vdd_1v8_gen";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo1_reg: ldo1 {
+ regulator-name = "vdd_pexa,vdd_pexb";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ ldo2_reg: ldo2 {
+ regulator-name = "vdd_sata,avdd_plle";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ /* LDO3 is not connected to anything */
+
+ ldo4_reg: ldo4 {
+ regulator-name = "vdd_rtc";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ ldo5_reg: ldo5 {
+ regulator-name = "vddio_sdmmc,avdd_vdac";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo6_reg: ldo6 {
+ regulator-name = "avdd_dsi_csi,pwrdet_mipi";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo7_reg: ldo7 {
+ regulator-name = "vdd_pllm,x,u,a_p_c_s";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ ldo8_reg: ldo8 {
+ regulator-name = "vdd_ddr_hs";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ temperature-sensor@4c {
+ compatible = "onnn,nct1008";
+ reg = <0x4c>;
+ vcc-supply = <&sys_3v3_reg>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(CC, 2) IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ tps62361@60 {
+ compatible = "ti,tps62361";
+ reg = <0x60>;
+
+ regulator-name = "tps62361-vout";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ti,vsel0-state-high;
+ ti,vsel1-state-high;
+ };
+ };
+
+ spi@7000da00 {
+ status = "okay";
+ spi-max-frequency = <25000000>;
+ spi-flash@1 {
+ compatible = "winbond,w25q32";
+ reg = <1>;
+ spi-max-frequency = <20000000>;
+ };
+ };
+
+ pmc@7000e400 {
+ status = "okay";
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <1>;
+ nvidia,cpu-pwr-good-time = <2000>;
+ nvidia,cpu-pwr-off-time = <200>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <0>;
+ nvidia,core-power-req-active-high;
+ nvidia,sys-clock-req-active-high;
+ };
+
+ ahub@70080000 {
+ i2s@70080400 {
+ status = "okay";
+ };
+ };
+
+ sdhci@78000000 {
+ status = "okay";
+ cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio TEGRA_GPIO(T, 3) GPIO_ACTIVE_HIGH>;
+ power-gpios = <&gpio TEGRA_GPIO(D, 7) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ };
+
+ sdhci@78000600 {
+ status = "okay";
+ bus-width = <8>;
+ non-removable;
+ };
+
+ usb@7d008000 {
+ status = "okay";
+ };
+
+ usb-phy@7d008000 {
+ vbus-supply = <&usb3_vbus_reg>;
+ status = "okay";
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+
+ enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
+ power-supply = <&vdd_bl_reg>;
+ pwms = <&pwm 0 5000000>;
+
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock@0 {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ panel: panel {
+ compatible = "chunghwa,claa101wb01", "simple-panel";
+ ddc-i2c-bus = <&panelddc>;
+
+ power-supply = <&vdd_pnl1_reg>;
+ enable-gpios = <&gpio TEGRA_GPIO(L, 2) GPIO_ACTIVE_HIGH>;
+
+ backlight = <&backlight>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdd_ac_bat_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vdd_ac_bat";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ cam_1v8_reg: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "cam_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(BB, 4) GPIO_ACTIVE_HIGH>;
+ vin-supply = <&vio_reg>;
+ };
+
+ cp_5v_reg: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "cp_5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ enable-active-high;
+ gpio = <&pmic 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ emmc_3v3_reg: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "emmc_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(D, 1) GPIO_ACTIVE_HIGH>;
+ vin-supply = <&sys_3v3_reg>;
+ };
+
+ modem_3v3_reg: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "modem_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(D, 6) GPIO_ACTIVE_HIGH>;
+ };
+
+ pex_hvdd_3v3_reg: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "pex_hvdd_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(L, 7) GPIO_ACTIVE_HIGH>;
+ vin-supply = <&sys_3v3_reg>;
+ };
+
+ vdd_cam1_ldo_reg: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ regulator-name = "vdd_cam1_ldo";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(R, 6) GPIO_ACTIVE_HIGH>;
+ vin-supply = <&sys_3v3_reg>;
+ };
+
+ vdd_cam2_ldo_reg: regulator@7 {
+ compatible = "regulator-fixed";
+ reg = <7>;
+ regulator-name = "vdd_cam2_ldo";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(R, 7) GPIO_ACTIVE_HIGH>;
+ vin-supply = <&sys_3v3_reg>;
+ };
+
+ vdd_cam3_ldo_reg: regulator@8 {
+ compatible = "regulator-fixed";
+ reg = <8>;
+ regulator-name = "vdd_cam3_ldo";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(S, 0) GPIO_ACTIVE_HIGH>;
+ vin-supply = <&sys_3v3_reg>;
+ };
+
+ vdd_com_reg: regulator@9 {
+ compatible = "regulator-fixed";
+ reg = <9>;
+ regulator-name = "vdd_com";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(D, 0) GPIO_ACTIVE_HIGH>;
+ vin-supply = <&sys_3v3_reg>;
+ };
+
+ vdd_fuse_3v3_reg: regulator@10 {
+ compatible = "regulator-fixed";
+ reg = <10>;
+ regulator-name = "vdd_fuse_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(L, 6) GPIO_ACTIVE_HIGH>;
+ vin-supply = <&sys_3v3_reg>;
+ };
+
+ vdd_pnl1_reg: regulator@11 {
+ compatible = "regulator-fixed";
+ reg = <11>;
+ regulator-name = "vdd_pnl1";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(L, 4) GPIO_ACTIVE_HIGH>;
+ vin-supply = <&sys_3v3_reg>;
+ };
+
+ vdd_vid_reg: regulator@12 {
+ compatible = "regulator-fixed";
+ reg = <12>;
+ regulator-name = "vddio_vid";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(T, 0) GPIO_ACTIVE_HIGH>;
+ gpio-open-drain;
+ vin-supply = <&vdd_5v0_reg>;
+ };
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-wm8903-cardhu",
+ "nvidia,tegra-audio-wm8903";
+ nvidia,model = "NVIDIA Tegra Cardhu";
+
+ nvidia,audio-routing =
+ "Headphone Jack", "HPOUTR",
+ "Headphone Jack", "HPOUTL",
+ "Int Spk", "ROP",
+ "Int Spk", "RON",
+ "Int Spk", "LOP",
+ "Int Spk", "LON",
+ "Mic Jack", "MICBIAS",
+ "IN1L", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&wm8903>;
+
+ nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>;
+ nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2)
+ GPIO_ACTIVE_HIGH>;
+
+ clocks = <&tegra_car TEGRA30_CLK_PLL_A>,
+ <&tegra_car TEGRA30_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA30_CLK_EXTERN1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
+};
diff --git a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
new file mode 100644
index 000000000..4d3ddc585
--- /dev/null
+++ b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
@@ -0,0 +1,208 @@
+/dts-v1/;
+
+#include "tegra30-colibri.dtsi"
+
+/ {
+ model = "Toradex Colibri T30 on Colibri Evaluation Board";
+ compatible = "toradex,colibri_t30-eval-v3", "toradex,colibri_t30", "nvidia,tegra30";
+
+ aliases {
+ rtc0 = "/i2c@7000c000/rtc@68";
+ rtc1 = "/i2c@7000d000/tps65911@2d";
+ rtc2 = "/rtc@7000e000";
+ serial0 = &uarta;
+ serial1 = &uartb;
+ serial2 = &uartd;
+ };
+
+ host1x@50000000 {
+ dc@54200000 {
+ rgb {
+ status = "okay";
+ nvidia,panel = <&panel>;
+ };
+ };
+ hdmi@54280000 {
+ status = "okay";
+ };
+ };
+
+ serial@70006000 {
+ status = "okay";
+ };
+
+ serial@70006040 {
+ compatible = "nvidia,tegra30-hsuart";
+ status = "okay";
+ };
+
+ serial@70006300 {
+ compatible = "nvidia,tegra30-hsuart";
+ status = "okay";
+ };
+
+ pwm@7000a000 {
+ status = "okay";
+ };
+
+ /*
+ * GEN1_I2C: I2C_SDA/SCL on SODIMM pin 194/196 (e.g. RTC on carrier
+ * board)
+ */
+ i2c@7000c000 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc@68 {
+ compatible = "stm,m41t00";
+ reg = <0x68>;
+ };
+ };
+
+ /* DDC_CLOCK/DATA on X3 pin 15/16 (e.g. display EDID) */
+ hdmiddc: i2c@7000c700 {
+ status = "okay";
+ };
+
+ /* SPI1: Colibri SSP */
+ spi@7000d400 {
+ status = "okay";
+ spi-max-frequency = <25000000>;
+ can0: can@0 {
+ compatible = "microchip,mcp2515";
+ reg = <0>;
+ clocks = <&clk16m>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(S, 0) GPIO_ACTIVE_LOW>;
+ spi-max-frequency = <10000000>;
+ };
+ spidev0: spi@1 {
+ compatible = "spidev";
+ reg = <1>;
+ spi-max-frequency = <25000000>;
+ };
+ };
+
+ sdhci@78000200 {
+ status = "okay";
+ bus-width = <4>;
+ cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>;
+ no-1-8-v;
+ };
+
+ /* EHCI instance 0: USB1_DP/N -> USBC_P/N */
+ usb@7d000000 {
+ status = "okay";
+ };
+
+ usb-phy@7d000000 {
+ status = "okay";
+ dr_mode = "otg";
+ vbus-supply = <&usbc_vbus_reg>;
+ };
+
+ /* EHCI instance 2: USB3_DP/N -> USBH_P/N */
+ usb@7d008000 {
+ status = "okay";
+ };
+
+ usb-phy@7d008000 {
+ status = "okay";
+ vbus-supply = <&usbh_vbus_reg>;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+
+ /* PWM<A> */
+ pwms = <&pwm 0 5000000>;
+ brightness-levels = <255 128 64 32 16 8 4 0>;
+ default-brightness-level = <6>;
+ /* BL_ON */
+ enable-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
+ };
+
+ clocks {
+ clk16m: clk@1 {
+ compatible = "fixed-clock";
+ reg=<1>;
+ #clock-cells = <0>;
+ clock-frequency = <16000000>;
+ clock-output-names = "clk16m";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_HIGH>;
+ linux,code = <KEY_POWER>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ panel: panel {
+ /*
+ * edt,et057090dhu: EDT 5.7" LCD TFT
+ * edt,et070080dh6: EDT 7.0" LCD TFT
+ */
+ compatible = "edt,et057090dhu", "simple-panel";
+
+ backlight = <&backlight>;
+ };
+
+ pwmleds {
+ compatible = "pwm-leds";
+
+ pwmb {
+ label = "PWM<B>";
+ pwms = <&pwm 1 19600>;
+ max-brightness = <255>;
+ };
+ pwmc {
+ label = "PWM<C>";
+ pwms = <&pwm 2 19600>;
+ max-brightness = <255>;
+ };
+ pwmd {
+ label = "PWM<D>";
+ pwms = <&pwm 3 19600>;
+ max-brightness = <255>;
+ };
+ };
+
+ regulators {
+ sys_5v0_reg: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ usbc_vbus_reg: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "usbc_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&sys_5v0_reg>;
+ };
+
+ /* USBH_PEN */
+ usbh_vbus_reg: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "usbh_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>;
+ vin-supply = <&sys_5v0_reg>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi b/arch/arm/boot/dts/tegra30-colibri.dtsi
new file mode 100644
index 000000000..c4ed1bec4
--- /dev/null
+++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
@@ -0,0 +1,386 @@
+#include <dt-bindings/input/input.h>
+#include "tegra30.dtsi"
+
+/*
+ * Toradex Colibri T30 Device Tree
+ * Compatible for Revisions 1.1B/1.1C/1.1D
+ */
+/ {
+ model = "Toradex Colibri T30";
+ compatible = "toradex,colibri_t30", "nvidia,tegra30";
+
+ memory {
+ reg = <0x80000000 0x40000000>;
+ };
+
+ host1x@50000000 {
+ hdmi@54280000 {
+ vdd-supply = <&sys_3v3_reg>;
+ pll-supply = <&vio_reg>;
+
+ nvidia,hpd-gpio =
+ <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
+ nvidia,ddc-i2c-bus = <&hdmiddc>;
+ };
+ };
+
+ pinmux@70000868 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ /* Colibri BL_ON */
+ pv2 {
+ nvidia,pins = "pv2";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Colibri Backlight PWM<A> */
+ sdmmc3_dat3_pb4 {
+ nvidia,pins = "sdmmc3_dat3_pb4";
+ nvidia,function = "pwm0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Colibri CAN_INT */
+ kb_row8_ps0 {
+ nvidia,pins = "kb_row8_ps0";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /*
+ * Colibri L_BIAS, LCD_M1 is muxed with LCD_DE
+ * todays display need DE, disable LCD_M1
+ */
+ lcd_m1_pw1 {
+ nvidia,pins = "lcd_m1_pw1";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Thermal alert, need to be disabled */
+ lcd_dc1_pd2 {
+ nvidia,pins = "lcd_dc1_pd2";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Colibri MMC */
+ kb_row10_ps2 {
+ nvidia,pins = "kb_row10_ps2";
+ nvidia,function = "sdmmc2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row11_ps3 {
+ nvidia,pins = "kb_row11_ps3",
+ "kb_row12_ps4",
+ "kb_row13_ps5",
+ "kb_row14_ps6",
+ "kb_row15_ps7";
+ nvidia,function = "sdmmc2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Colibri SSP */
+ ulpi_clk_py0 {
+ nvidia,pins = "ulpi_clk_py0",
+ "ulpi_dir_py1",
+ "ulpi_nxt_py2",
+ "ulpi_stp_py3";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_dat6_pd3 {
+ nvidia,pins = "sdmmc3_dat6_pd3",
+ "sdmmc3_dat7_pd4";
+ nvidia,function = "spdif";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Colibri UART_A */
+ ulpi_data0 {
+ nvidia,pins = "ulpi_data0_po1",
+ "ulpi_data1_po2",
+ "ulpi_data2_po3",
+ "ulpi_data3_po4",
+ "ulpi_data4_po5",
+ "ulpi_data5_po6",
+ "ulpi_data6_po7",
+ "ulpi_data7_po0";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Colibri UART_B */
+ gmi_a16_pj7 {
+ nvidia,pins = "gmi_a16_pj7",
+ "gmi_a17_pb0",
+ "gmi_a18_pb1",
+ "gmi_a19_pk7";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Colibri UART_C */
+ uart2_rxd {
+ nvidia,pins = "uart2_rxd_pc3",
+ "uart2_txd_pc2";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* eMMC */
+ sdmmc4_clk_pcc4 {
+ nvidia,pins = "sdmmc4_clk_pcc4",
+ "sdmmc4_rst_n_pcc3";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc4_dat0_paa0 {
+ nvidia,pins = "sdmmc4_dat0_paa0",
+ "sdmmc4_dat1_paa1",
+ "sdmmc4_dat2_paa2",
+ "sdmmc4_dat3_paa3",
+ "sdmmc4_dat4_paa4",
+ "sdmmc4_dat5_paa5",
+ "sdmmc4_dat6_paa6",
+ "sdmmc4_dat7_paa7";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ };
+ };
+
+ hdmiddc: i2c@7000c700 {
+ clock-frequency = <100000>;
+ };
+
+ /*
+ * PWR_I2C: power I2C to audio codec, PMIC, temperature sensor and
+ * touch screen controller
+ */
+ i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ pmic: tps65911@2d {
+ compatible = "ti,tps65911";
+ reg = <0x2d>;
+
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+
+ ti,system-power-controller;
+
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ vcc1-supply = <&sys_3v3_reg>;
+ vcc2-supply = <&sys_3v3_reg>;
+ vcc3-supply = <&vio_reg>;
+ vcc4-supply = <&sys_3v3_reg>;
+ vcc5-supply = <&sys_3v3_reg>;
+ vcc6-supply = <&vio_reg>;
+ vcc7-supply = <&charge_pump_5v0_reg>;
+ vccio-supply = <&sys_3v3_reg>;
+
+ regulators {
+ /* SW1: +V1.35_VDDIO_DDR */
+ vdd1_reg: vdd1 {
+ regulator-name = "vddio_ddr_1v35";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+
+ /* SW2: unused */
+
+ /* SW CTRL: +V1.0_VDD_CPU */
+ vddctrl_reg: vddctrl {
+ regulator-name = "vdd_cpu,vdd_sys";
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-always-on;
+ };
+
+ /* SWIO: +V1.8 */
+ vio_reg: vio {
+ regulator-name = "vdd_1v8_gen";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ /* LDO1: unused */
+
+ /*
+ * EN_+V3.3 switching via FET:
+ * +V3.3_AUDIO_AVDD_S, +V3.3 and +V1.8_VDD_LAN
+ * see also v3_3 fixed supply
+ */
+ ldo2_reg: ldo2 {
+ regulator-name = "en_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ /* LDO3: unused */
+
+ /* +V1.2_VDD_RTC */
+ ldo4_reg: ldo4 {
+ regulator-name = "vdd_rtc";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ /*
+ * +V2.8_AVDD_VDAC:
+ * only required for analog RGB
+ */
+ ldo5_reg: ldo5 {
+ regulator-name = "avdd_vdac";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ /*
+ * +V1.05_AVDD_PLLE: avdd_plle should be 1.05V
+ * but LDO6 can't set voltage in 50mV
+ * granularity
+ */
+ ldo6_reg: ldo6 {
+ regulator-name = "avdd_plle";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ };
+
+ /* +V1.2_AVDD_PLL */
+ ldo7_reg: ldo7 {
+ regulator-name = "avdd_pll";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ /* +V1.0_VDD_DDR_HS */
+ ldo8_reg: ldo8 {
+ regulator-name = "vdd_ddr_hs";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ /*
+ * LM95245 temperature sensor
+ * Note: OVERT_N directly connected to PMIC PWRDN
+ */
+ temp-sensor@4c {
+ compatible = "national,lm95245";
+ reg = <0x4c>;
+ };
+
+ /* SW: +V1.2_VDD_CORE */
+ tps62362@60 {
+ compatible = "ti,tps62362";
+ reg = <0x60>;
+
+ regulator-name = "tps62362-vout";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ti,vsel0-state-low;
+ /* VSEL1: EN_CORE_DVFS_N low for DVFS */
+ ti,vsel1-state-low;
+ };
+ };
+
+ pmc@7000e400 {
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <1>;
+ nvidia,cpu-pwr-good-time = <5000>;
+ nvidia,cpu-pwr-off-time = <5000>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <0>;
+ nvidia,core-power-req-active-high;
+ nvidia,sys-clock-req-active-high;
+ };
+
+ emmc: sdhci@78000600 {
+ status = "okay";
+ bus-width = <8>;
+ non-removable;
+ };
+
+ /* EHCI instance 1: USB2_DP/N -> AX88772B */
+ usb@7d004000 {
+ status = "okay";
+ };
+
+ usb-phy@7d004000 {
+ status = "okay";
+ nvidia,is-wired = <1>;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clk@0 {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sys_3v3_reg: regulator@100 {
+ compatible = "regulator-fixed";
+ reg = <100>;
+ regulator-name = "3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ charge_pump_5v0_reg: regulator@101 {
+ compatible = "regulator-fixed";
+ reg = <101>;
+ regulator-name = "5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
new file mode 100644
index 000000000..60e205a0f
--- /dev/null
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -0,0 +1,926 @@
+#include <dt-bindings/clock/tegra30-car.h>
+#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/memory/tegra30-mc.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "nvidia,tegra30";
+ interrupt-parent = <&lic>;
+
+ pcie-controller@00003000 {
+ compatible = "nvidia,tegra30-pcie";
+ device_type = "pci";
+ reg = <0x00003000 0x00000800 /* PADS registers */
+ 0x00003800 0x00000200 /* AFI registers */
+ 0x10000000 0x10000000>; /* configuration space */
+ reg-names = "pads", "afi", "cs";
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH /* controller interrupt */
+ GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
+ interrupt-names = "intr", "msi";
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &intc GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+
+ bus-range = <0x00 0xff>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ ranges = <0x82000000 0 0x00000000 0x00000000 0 0x00001000 /* port 0 configuration space */
+ 0x82000000 0 0x00001000 0x00001000 0 0x00001000 /* port 1 configuration space */
+ 0x82000000 0 0x00004000 0x00004000 0 0x00001000 /* port 2 configuration space */
+ 0x81000000 0 0 0x02000000 0 0x00010000 /* downstream I/O */
+ 0x82000000 0 0x20000000 0x20000000 0 0x08000000 /* non-prefetchable memory */
+ 0xc2000000 0 0x28000000 0x28000000 0 0x18000000>; /* prefetchable memory */
+
+ clocks = <&tegra_car TEGRA30_CLK_PCIE>,
+ <&tegra_car TEGRA30_CLK_AFI>,
+ <&tegra_car TEGRA30_CLK_PLL_E>,
+ <&tegra_car TEGRA30_CLK_CML0>;
+ clock-names = "pex", "afi", "pll_e", "cml";
+ resets = <&tegra_car 70>,
+ <&tegra_car 72>,
+ <&tegra_car 74>;
+ reset-names = "pex", "afi", "pcie_x";
+ status = "disabled";
+
+ pci@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x00000000 0 0x1000>;
+ reg = <0x000800 0 0 0 0>;
+ status = "disabled";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ nvidia,num-lanes = <2>;
+ };
+
+ pci@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82001000 0 0x00001000 0 0x1000>;
+ reg = <0x001000 0 0 0 0>;
+ status = "disabled";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ nvidia,num-lanes = <2>;
+ };
+
+ pci@3,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82001800 0 0x00004000 0 0x1000>;
+ reg = <0x001800 0 0 0 0>;
+ status = "disabled";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ nvidia,num-lanes = <2>;
+ };
+ };
+
+ host1x@50000000 {
+ compatible = "nvidia,tegra30-host1x", "simple-bus";
+ reg = <0x50000000 0x00024000>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, /* syncpt */
+ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; /* general */
+ clocks = <&tegra_car TEGRA30_CLK_HOST1X>;
+ resets = <&tegra_car 28>;
+ reset-names = "host1x";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0x54000000 0x54000000 0x04000000>;
+
+ mpe@54040000 {
+ compatible = "nvidia,tegra30-mpe";
+ reg = <0x54040000 0x00040000>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_MPE>;
+ resets = <&tegra_car 60>;
+ reset-names = "mpe";
+ };
+
+ vi@54080000 {
+ compatible = "nvidia,tegra30-vi";
+ reg = <0x54080000 0x00040000>;
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_VI>;
+ resets = <&tegra_car 20>;
+ reset-names = "vi";
+ };
+
+ epp@540c0000 {
+ compatible = "nvidia,tegra30-epp";
+ reg = <0x540c0000 0x00040000>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_EPP>;
+ resets = <&tegra_car 19>;
+ reset-names = "epp";
+ };
+
+ isp@54100000 {
+ compatible = "nvidia,tegra30-isp";
+ reg = <0x54100000 0x00040000>;
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_ISP>;
+ resets = <&tegra_car 23>;
+ reset-names = "isp";
+ };
+
+ gr2d@54140000 {
+ compatible = "nvidia,tegra30-gr2d";
+ reg = <0x54140000 0x00040000>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_GR2D>;
+ resets = <&tegra_car 21>;
+ reset-names = "2d";
+ };
+
+ gr3d@54180000 {
+ compatible = "nvidia,tegra30-gr3d";
+ reg = <0x54180000 0x00040000>;
+ clocks = <&tegra_car TEGRA30_CLK_GR3D
+ &tegra_car TEGRA30_CLK_GR3D2>;
+ clock-names = "3d", "3d2";
+ resets = <&tegra_car 24>,
+ <&tegra_car 98>;
+ reset-names = "3d", "3d2";
+ };
+
+ dc@54200000 {
+ compatible = "nvidia,tegra30-dc", "nvidia,tegra20-dc";
+ reg = <0x54200000 0x00040000>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_DISP1>,
+ <&tegra_car TEGRA30_CLK_PLL_P>;
+ clock-names = "dc", "parent";
+ resets = <&tegra_car 27>;
+ reset-names = "dc";
+
+ iommus = <&mc TEGRA_SWGROUP_DC>;
+
+ nvidia,head = <0>;
+
+ rgb {
+ status = "disabled";
+ };
+ };
+
+ dc@54240000 {
+ compatible = "nvidia,tegra30-dc";
+ reg = <0x54240000 0x00040000>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_DISP2>,
+ <&tegra_car TEGRA30_CLK_PLL_P>;
+ clock-names = "dc", "parent";
+ resets = <&tegra_car 26>;
+ reset-names = "dc";
+
+ iommus = <&mc TEGRA_SWGROUP_DCB>;
+
+ nvidia,head = <1>;
+
+ rgb {
+ status = "disabled";
+ };
+ };
+
+ hdmi@54280000 {
+ compatible = "nvidia,tegra30-hdmi";
+ reg = <0x54280000 0x00040000>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_HDMI>,
+ <&tegra_car TEGRA30_CLK_PLL_D2_OUT0>;
+ clock-names = "hdmi", "parent";
+ resets = <&tegra_car 51>;
+ reset-names = "hdmi";
+ status = "disabled";
+ };
+
+ tvo@542c0000 {
+ compatible = "nvidia,tegra30-tvo";
+ reg = <0x542c0000 0x00040000>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_TVO>;
+ status = "disabled";
+ };
+
+ dsi@54300000 {
+ compatible = "nvidia,tegra30-dsi";
+ reg = <0x54300000 0x00040000>;
+ clocks = <&tegra_car TEGRA30_CLK_DSIA>;
+ resets = <&tegra_car 48>;
+ reset-names = "dsi";
+ status = "disabled";
+ };
+ };
+
+ timer@50040600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x50040600 0x20>;
+ interrupt-parent = <&intc>;
+ interrupts = <GIC_PPI 13
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ clocks = <&tegra_car TEGRA30_CLK_TWD>;
+ };
+
+ intc: interrupt-controller@50041000 {
+ compatible = "arm,cortex-a9-gic";
+ reg = <0x50041000 0x1000
+ 0x50040100 0x0100>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&intc>;
+ };
+
+ cache-controller@50043000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x50043000 0x1000>;
+ arm,data-latency = <6 6 2>;
+ arm,tag-latency = <5 5 2>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ lic: interrupt-controller@60004000 {
+ compatible = "nvidia,tegra30-ictlr";
+ reg = <0x60004000 0x100>,
+ <0x60004100 0x50>,
+ <0x60004200 0x50>,
+ <0x60004300 0x50>,
+ <0x60004400 0x50>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&intc>;
+ };
+
+ timer@60005000 {
+ compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer";
+ reg = <0x60005000 0x400>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_TIMER>;
+ };
+
+ tegra_car: clock@60006000 {
+ compatible = "nvidia,tegra30-car";
+ reg = <0x60006000 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ flow-controller@60007000 {
+ compatible = "nvidia,tegra30-flowctrl";
+ reg = <0x60007000 0x1000>;
+ };
+
+ apbdma: dma@6000a000 {
+ compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma";
+ reg = <0x6000a000 0x1400>;
+ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_APBDMA>;
+ resets = <&tegra_car 34>;
+ reset-names = "dma";
+ #dma-cells = <1>;
+ };
+
+ ahb: ahb@6000c004 {
+ compatible = "nvidia,tegra30-ahb";
+ reg = <0x6000c004 0x14c>; /* AHB Arbitration + Gizmo Controller */
+ };
+
+ gpio: gpio@6000d000 {
+ compatible = "nvidia,tegra30-gpio";
+ reg = <0x6000d000 0x1000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ apbmisc@70000800 {
+ compatible = "nvidia,tegra30-apbmisc", "nvidia,tegra20-apbmisc";
+ reg = <0x70000800 0x64 /* Chip revision */
+ 0x70000008 0x04>; /* Strapping options */
+ };
+
+ pinmux: pinmux@70000868 {
+ compatible = "nvidia,tegra30-pinmux";
+ reg = <0x70000868 0xd4 /* Pad control registers */
+ 0x70003000 0x3e4>; /* Mux registers */
+ };
+
+ /*
+ * There are two serial driver i.e. 8250 based simple serial
+ * driver and APB DMA based serial driver for higher baudrate
+ * and performace. To enable the 8250 based driver, the compatible
+ * is "nvidia,tegra30-uart", "nvidia,tegra20-uart" and to enable
+ * the APB DMA based serial driver, the comptible is
+ * "nvidia,tegra30-hsuart", "nvidia,tegra20-hsuart".
+ */
+ uarta: serial@70006000 {
+ compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
+ reg = <0x70006000 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_UARTA>;
+ resets = <&tegra_car 6>;
+ reset-names = "serial";
+ dmas = <&apbdma 8>, <&apbdma 8>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uartb: serial@70006040 {
+ compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
+ reg = <0x70006040 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_UARTB>;
+ resets = <&tegra_car 7>;
+ reset-names = "serial";
+ dmas = <&apbdma 9>, <&apbdma 9>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uartc: serial@70006200 {
+ compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
+ reg = <0x70006200 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_UARTC>;
+ resets = <&tegra_car 55>;
+ reset-names = "serial";
+ dmas = <&apbdma 10>, <&apbdma 10>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uartd: serial@70006300 {
+ compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
+ reg = <0x70006300 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_UARTD>;
+ resets = <&tegra_car 65>;
+ reset-names = "serial";
+ dmas = <&apbdma 19>, <&apbdma 19>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uarte: serial@70006400 {
+ compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
+ reg = <0x70006400 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_UARTE>;
+ resets = <&tegra_car 66>;
+ reset-names = "serial";
+ dmas = <&apbdma 20>, <&apbdma 20>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ pwm: pwm@7000a000 {
+ compatible = "nvidia,tegra30-pwm", "nvidia,tegra20-pwm";
+ reg = <0x7000a000 0x100>;
+ #pwm-cells = <2>;
+ clocks = <&tegra_car TEGRA30_CLK_PWM>;
+ resets = <&tegra_car 17>;
+ reset-names = "pwm";
+ status = "disabled";
+ };
+
+ rtc@7000e000 {
+ compatible = "nvidia,tegra30-rtc", "nvidia,tegra20-rtc";
+ reg = <0x7000e000 0x100>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_RTC>;
+ };
+
+ i2c@7000c000 {
+ compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+ reg = <0x7000c000 0x100>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA30_CLK_I2C1>,
+ <&tegra_car TEGRA30_CLK_PLL_P_OUT3>;
+ clock-names = "div-clk", "fast-clk";
+ resets = <&tegra_car 12>;
+ reset-names = "i2c";
+ dmas = <&apbdma 21>, <&apbdma 21>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@7000c400 {
+ compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+ reg = <0x7000c400 0x100>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA30_CLK_I2C2>,
+ <&tegra_car TEGRA30_CLK_PLL_P_OUT3>;
+ clock-names = "div-clk", "fast-clk";
+ resets = <&tegra_car 54>;
+ reset-names = "i2c";
+ dmas = <&apbdma 22>, <&apbdma 22>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@7000c500 {
+ compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+ reg = <0x7000c500 0x100>;
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA30_CLK_I2C3>,
+ <&tegra_car TEGRA30_CLK_PLL_P_OUT3>;
+ clock-names = "div-clk", "fast-clk";
+ resets = <&tegra_car 67>;
+ reset-names = "i2c";
+ dmas = <&apbdma 23>, <&apbdma 23>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@7000c700 {
+ compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+ reg = <0x7000c700 0x100>;
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA30_CLK_I2C4>,
+ <&tegra_car TEGRA30_CLK_PLL_P_OUT3>;
+ resets = <&tegra_car 103>;
+ reset-names = "i2c";
+ clock-names = "div-clk", "fast-clk";
+ dmas = <&apbdma 26>, <&apbdma 26>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@7000d000 {
+ compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+ reg = <0x7000d000 0x100>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA30_CLK_I2C5>,
+ <&tegra_car TEGRA30_CLK_PLL_P_OUT3>;
+ clock-names = "div-clk", "fast-clk";
+ resets = <&tegra_car 47>;
+ reset-names = "i2c";
+ dmas = <&apbdma 24>, <&apbdma 24>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000d400 {
+ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+ reg = <0x7000d400 0x200>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA30_CLK_SBC1>;
+ resets = <&tegra_car 41>;
+ reset-names = "spi";
+ dmas = <&apbdma 15>, <&apbdma 15>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000d600 {
+ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+ reg = <0x7000d600 0x200>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA30_CLK_SBC2>;
+ resets = <&tegra_car 44>;
+ reset-names = "spi";
+ dmas = <&apbdma 16>, <&apbdma 16>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000d800 {
+ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+ reg = <0x7000d800 0x200>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA30_CLK_SBC3>;
+ resets = <&tegra_car 46>;
+ reset-names = "spi";
+ dmas = <&apbdma 17>, <&apbdma 17>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000da00 {
+ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+ reg = <0x7000da00 0x200>;
+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA30_CLK_SBC4>;
+ resets = <&tegra_car 68>;
+ reset-names = "spi";
+ dmas = <&apbdma 18>, <&apbdma 18>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000dc00 {
+ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+ reg = <0x7000dc00 0x200>;
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA30_CLK_SBC5>;
+ resets = <&tegra_car 104>;
+ reset-names = "spi";
+ dmas = <&apbdma 27>, <&apbdma 27>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000de00 {
+ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+ reg = <0x7000de00 0x200>;
+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA30_CLK_SBC6>;
+ resets = <&tegra_car 106>;
+ reset-names = "spi";
+ dmas = <&apbdma 28>, <&apbdma 28>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ kbc@7000e200 {
+ compatible = "nvidia,tegra30-kbc", "nvidia,tegra20-kbc";
+ reg = <0x7000e200 0x100>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_KBC>;
+ resets = <&tegra_car 36>;
+ reset-names = "kbc";
+ status = "disabled";
+ };
+
+ pmc@7000e400 {
+ compatible = "nvidia,tegra30-pmc";
+ reg = <0x7000e400 0x400>;
+ clocks = <&tegra_car TEGRA30_CLK_PCLK>, <&clk32k_in>;
+ clock-names = "pclk", "clk32k_in";
+ };
+
+ mc: memory-controller@7000f000 {
+ compatible = "nvidia,tegra30-mc";
+ reg = <0x7000f000 0x400>;
+ clocks = <&tegra_car TEGRA30_CLK_MC>;
+ clock-names = "mc";
+
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+
+ #iommu-cells = <1>;
+ };
+
+ fuse@7000f800 {
+ compatible = "nvidia,tegra30-efuse";
+ reg = <0x7000f800 0x400>;
+ clocks = <&tegra_car TEGRA30_CLK_FUSE>;
+ clock-names = "fuse";
+ resets = <&tegra_car 39>;
+ reset-names = "fuse";
+ };
+
+ ahub@70080000 {
+ compatible = "nvidia,tegra30-ahub";
+ reg = <0x70080000 0x200
+ 0x70080200 0x100>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_D_AUDIO>,
+ <&tegra_car TEGRA30_CLK_APBIF>;
+ clock-names = "d_audio", "apbif";
+ resets = <&tegra_car 106>, /* d_audio */
+ <&tegra_car 107>, /* apbif */
+ <&tegra_car 30>, /* i2s0 */
+ <&tegra_car 11>, /* i2s1 */
+ <&tegra_car 18>, /* i2s2 */
+ <&tegra_car 101>, /* i2s3 */
+ <&tegra_car 102>, /* i2s4 */
+ <&tegra_car 108>, /* dam0 */
+ <&tegra_car 109>, /* dam1 */
+ <&tegra_car 110>, /* dam2 */
+ <&tegra_car 10>; /* spdif */
+ reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
+ "i2s3", "i2s4", "dam0", "dam1", "dam2",
+ "spdif";
+ dmas = <&apbdma 1>, <&apbdma 1>,
+ <&apbdma 2>, <&apbdma 2>,
+ <&apbdma 3>, <&apbdma 3>,
+ <&apbdma 4>, <&apbdma 4>;
+ dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2",
+ "rx3", "tx3";
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ tegra_i2s0: i2s@70080300 {
+ compatible = "nvidia,tegra30-i2s";
+ reg = <0x70080300 0x100>;
+ nvidia,ahub-cif-ids = <4 4>;
+ clocks = <&tegra_car TEGRA30_CLK_I2S0>;
+ resets = <&tegra_car 30>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+
+ tegra_i2s1: i2s@70080400 {
+ compatible = "nvidia,tegra30-i2s";
+ reg = <0x70080400 0x100>;
+ nvidia,ahub-cif-ids = <5 5>;
+ clocks = <&tegra_car TEGRA30_CLK_I2S1>;
+ resets = <&tegra_car 11>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+
+ tegra_i2s2: i2s@70080500 {
+ compatible = "nvidia,tegra30-i2s";
+ reg = <0x70080500 0x100>;
+ nvidia,ahub-cif-ids = <6 6>;
+ clocks = <&tegra_car TEGRA30_CLK_I2S2>;
+ resets = <&tegra_car 18>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+
+ tegra_i2s3: i2s@70080600 {
+ compatible = "nvidia,tegra30-i2s";
+ reg = <0x70080600 0x100>;
+ nvidia,ahub-cif-ids = <7 7>;
+ clocks = <&tegra_car TEGRA30_CLK_I2S3>;
+ resets = <&tegra_car 101>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+
+ tegra_i2s4: i2s@70080700 {
+ compatible = "nvidia,tegra30-i2s";
+ reg = <0x70080700 0x100>;
+ nvidia,ahub-cif-ids = <8 8>;
+ clocks = <&tegra_car TEGRA30_CLK_I2S4>;
+ resets = <&tegra_car 102>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+ };
+
+ sdhci@78000000 {
+ compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
+ reg = <0x78000000 0x200>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_SDMMC1>;
+ resets = <&tegra_car 14>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@78000200 {
+ compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
+ reg = <0x78000200 0x200>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_SDMMC2>;
+ resets = <&tegra_car 9>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@78000400 {
+ compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
+ reg = <0x78000400 0x200>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_SDMMC3>;
+ resets = <&tegra_car 69>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@78000600 {
+ compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
+ reg = <0x78000600 0x200>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA30_CLK_SDMMC4>;
+ resets = <&tegra_car 15>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ usb@7d000000 {
+ compatible = "nvidia,tegra30-ehci", "usb-ehci";
+ reg = <0x7d000000 0x4000>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA30_CLK_USBD>;
+ resets = <&tegra_car 22>;
+ reset-names = "usb";
+ nvidia,needs-double-reset;
+ nvidia,phy = <&phy1>;
+ status = "disabled";
+ };
+
+ phy1: usb-phy@7d000000 {
+ compatible = "nvidia,tegra30-usb-phy";
+ reg = <0x7d000000 0x4000 0x7d000000 0x4000>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA30_CLK_USBD>,
+ <&tegra_car TEGRA30_CLK_PLL_U>,
+ <&tegra_car TEGRA30_CLK_USBD>;
+ clock-names = "reg", "pll_u", "utmi-pads";
+ resets = <&tegra_car 22>, <&tegra_car 22>;
+ reset-names = "usb", "utmi-pads";
+ nvidia,hssync-start-delay = <9>;
+ nvidia,idle-wait-delay = <17>;
+ nvidia,elastic-limit = <16>;
+ nvidia,term-range-adj = <6>;
+ nvidia,xcvr-setup = <51>;
+ nvidia.xcvr-setup-use-fuses;
+ nvidia,xcvr-lsfslew = <1>;
+ nvidia,xcvr-lsrslew = <1>;
+ nvidia,xcvr-hsslew = <32>;
+ nvidia,hssquelch-level = <2>;
+ nvidia,hsdiscon-level = <5>;
+ nvidia,has-utmi-pad-registers;
+ status = "disabled";
+ };
+
+ usb@7d004000 {
+ compatible = "nvidia,tegra30-ehci", "usb-ehci";
+ reg = <0x7d004000 0x4000>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA30_CLK_USB2>;
+ resets = <&tegra_car 58>;
+ reset-names = "usb";
+ nvidia,phy = <&phy2>;
+ status = "disabled";
+ };
+
+ phy2: usb-phy@7d004000 {
+ compatible = "nvidia,tegra30-usb-phy";
+ reg = <0x7d004000 0x4000 0x7d000000 0x4000>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA30_CLK_USB2>,
+ <&tegra_car TEGRA30_CLK_PLL_U>,
+ <&tegra_car TEGRA30_CLK_USBD>;
+ clock-names = "reg", "pll_u", "utmi-pads";
+ resets = <&tegra_car 58>, <&tegra_car 22>;
+ reset-names = "usb", "utmi-pads";
+ nvidia,hssync-start-delay = <9>;
+ nvidia,idle-wait-delay = <17>;
+ nvidia,elastic-limit = <16>;
+ nvidia,term-range-adj = <6>;
+ nvidia,xcvr-setup = <51>;
+ nvidia.xcvr-setup-use-fuses;
+ nvidia,xcvr-lsfslew = <2>;
+ nvidia,xcvr-lsrslew = <2>;
+ nvidia,xcvr-hsslew = <32>;
+ nvidia,hssquelch-level = <2>;
+ nvidia,hsdiscon-level = <5>;
+ status = "disabled";
+ };
+
+ usb@7d008000 {
+ compatible = "nvidia,tegra30-ehci", "usb-ehci";
+ reg = <0x7d008000 0x4000>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA30_CLK_USB3>;
+ resets = <&tegra_car 59>;
+ reset-names = "usb";
+ nvidia,phy = <&phy3>;
+ status = "disabled";
+ };
+
+ phy3: usb-phy@7d008000 {
+ compatible = "nvidia,tegra30-usb-phy";
+ reg = <0x7d008000 0x4000 0x7d000000 0x4000>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA30_CLK_USB3>,
+ <&tegra_car TEGRA30_CLK_PLL_U>,
+ <&tegra_car TEGRA30_CLK_USBD>;
+ clock-names = "reg", "pll_u", "utmi-pads";
+ resets = <&tegra_car 59>, <&tegra_car 22>;
+ reset-names = "usb", "utmi-pads";
+ nvidia,hssync-start-delay = <0>;
+ nvidia,idle-wait-delay = <17>;
+ nvidia,elastic-limit = <16>;
+ nvidia,term-range-adj = <6>;
+ nvidia,xcvr-setup = <51>;
+ nvidia.xcvr-setup-use-fuses;
+ nvidia,xcvr-lsfslew = <2>;
+ nvidia,xcvr-lsrslew = <2>;
+ nvidia,xcvr-hsslew = <32>;
+ nvidia,hssquelch-level = <2>;
+ nvidia,hsdiscon-level = <5>;
+ status = "disabled";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ };
+
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <2>;
+ };
+
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <3>;
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ };
+};
diff --git a/arch/arm/boot/dts/tny_a9260.dts b/arch/arm/boot/dts/tny_a9260.dts
new file mode 100644
index 000000000..dabe23221
--- /dev/null
+++ b/arch/arm/boot/dts/tny_a9260.dts
@@ -0,0 +1,15 @@
+/*
+ * tny_a9260.dts - Device Tree file for Caloa TNY A9260 board
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+/dts-v1/;
+#include "at91sam9260.dtsi"
+#include "tny_a9260_common.dtsi"
+
+/ {
+ model = "Calao TNY A9260";
+ compatible = "calao,tny-a9260", "atmel,at91sam9260", "atmel,at91sam9";
+};
diff --git a/arch/arm/boot/dts/tny_a9260_common.dtsi b/arch/arm/boot/dts/tny_a9260_common.dtsi
new file mode 100644
index 000000000..ce7138c3a
--- /dev/null
+++ b/arch/arm/boot/dts/tny_a9260_common.dtsi
@@ -0,0 +1,91 @@
+/*
+ * tny_a9260_common.dtsi - Device Tree file for Caloa TNY A926x board
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+/ {
+ chosen {
+ bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock6 rw rootfstype=ubifs";
+ };
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x20000>;
+ };
+
+ barebox@20000 {
+ label = "barebox";
+ reg = <0x20000 0x40000>;
+ };
+
+ bareboxenv@60000 {
+ label = "bareboxenv";
+ reg = <0x60000 0x20000>;
+ };
+
+ bareboxenv2@80000 {
+ label = "bareboxenv2";
+ reg = <0x80000 0x20000>;
+ };
+
+ oftree@80000 {
+ label = "oftree";
+ reg = <0xa0000 0x20000>;
+ };
+
+ kernel@a0000 {
+ label = "kernel";
+ reg = <0xc0000 0x400000>;
+ };
+
+ rootfs@4a0000 {
+ label = "rootfs";
+ reg = <0x4c0000 0x7800000>;
+ };
+
+ data@7ca0000 {
+ label = "data";
+ reg = <0x7cc0000 0x8340000>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tny_a9263.dts b/arch/arm/boot/dts/tny_a9263.dts
new file mode 100644
index 000000000..304329634
--- /dev/null
+++ b/arch/arm/boot/dts/tny_a9263.dts
@@ -0,0 +1,105 @@
+/*
+ * usb_a9263.dts - Device Tree file for Caloa USB A9293 board
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 only
+ */
+/dts-v1/;
+#include "at91sam9263.dtsi"
+
+/ {
+ model = "Calao TNY A9263";
+ compatible = "atmel,tny-a9263", "atmel,at91sam9263", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock5 rw rootfstype=ubifs";
+ };
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@ffffee00 {
+ status = "okay";
+ };
+
+ usb1: gadget@fff78000 {
+ atmel,vbus-gpio = <&pioB 11 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x20000>;
+ };
+
+ barebox@20000 {
+ label = "barebox";
+ reg = <0x20000 0x40000>;
+ };
+
+ bareboxenv@60000 {
+ label = "bareboxenv";
+ reg = <0x60000 0x20000>;
+ };
+
+ bareboxenv2@80000 {
+ label = "bareboxenv2";
+ reg = <0x80000 0x20000>;
+ };
+
+ oftree@80000 {
+ label = "oftree";
+ reg = <0xa0000 0x20000>;
+ };
+
+ kernel@a0000 {
+ label = "kernel";
+ reg = <0xc0000 0x400000>;
+ };
+
+ rootfs@4a0000 {
+ label = "rootfs";
+ reg = <0x4c0000 0x7800000>;
+ };
+
+ data@7ca0000 {
+ label = "data";
+ reg = <0x7cc0000 0x8340000>;
+ };
+ };
+ };
+
+ i2c@0 {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/tny_a9g20.dts b/arch/arm/boot/dts/tny_a9g20.dts
new file mode 100644
index 000000000..8456d70bb
--- /dev/null
+++ b/arch/arm/boot/dts/tny_a9g20.dts
@@ -0,0 +1,15 @@
+/*
+ * tny_a9g20.dts - Device Tree file for Caloa TNY A9G20 board
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+/dts-v1/;
+#include "at91sam9g20.dtsi"
+#include "tny_a9260_common.dtsi"
+
+/ {
+ model = "Calao TNY A9G20";
+ compatible = "calao,tny-a9g20", "atmel,at91sam9g20", "atmel,at91sam9";
+};
diff --git a/arch/arm/boot/dts/tps6507x.dtsi b/arch/arm/boot/dts/tps6507x.dtsi
new file mode 100644
index 000000000..4c326e591
--- /dev/null
+++ b/arch/arm/boot/dts/tps6507x.dtsi
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+/*
+ * Integrated Power Management Chip
+ * http://www.ti.com/lit/ds/symlink/tps65070.pdf
+ */
+
+&tps {
+ compatible = "ti,tps6507x";
+
+ regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdcdc1_reg: regulator@0 {
+ reg = <0>;
+ regulator-compatible = "VDCDC1";
+ };
+
+ vdcdc2_reg: regulator@1 {
+ reg = <1>;
+ regulator-compatible = "VDCDC2";
+ };
+
+ vdcdc3_reg: regulator@2 {
+ reg = <2>;
+ regulator-compatible = "VDCDC3";
+ };
+
+ ldo1_reg: regulator@3 {
+ reg = <3>;
+ regulator-compatible = "LDO1";
+ };
+
+ ldo2_reg: regulator@4 {
+ reg = <4>;
+ regulator-compatible = "LDO2";
+ };
+
+ };
+};
diff --git a/arch/arm/boot/dts/tps65217.dtsi b/arch/arm/boot/dts/tps65217.dtsi
new file mode 100644
index 000000000..a63272422
--- /dev/null
+++ b/arch/arm/boot/dts/tps65217.dtsi
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/*
+ * Integrated Power Management Chip
+ * http://www.ti.com/lit/ds/symlink/tps65217.pdf
+ */
+
+&tps {
+ compatible = "ti,tps65217";
+
+ regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dcdc1_reg: regulator@0 {
+ reg = <0>;
+ regulator-compatible = "dcdc1";
+ };
+
+ dcdc2_reg: regulator@1 {
+ reg = <1>;
+ regulator-compatible = "dcdc2";
+ };
+
+ dcdc3_reg: regulator@2 {
+ reg = <2>;
+ regulator-compatible = "dcdc3";
+ };
+
+ ldo1_reg: regulator@3 {
+ reg = <3>;
+ regulator-compatible = "ldo1";
+ };
+
+ ldo2_reg: regulator@4 {
+ reg = <4>;
+ regulator-compatible = "ldo2";
+ };
+
+ ldo3_reg: regulator@5 {
+ reg = <5>;
+ regulator-compatible = "ldo3";
+ };
+
+ ldo4_reg: regulator@6 {
+ reg = <6>;
+ regulator-compatible = "ldo4";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tps65910.dtsi b/arch/arm/boot/dts/tps65910.dtsi
new file mode 100644
index 000000000..b0ac6657a
--- /dev/null
+++ b/arch/arm/boot/dts/tps65910.dtsi
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/*
+ * Integrated Power Management Chip
+ * http://www.ti.com/lit/ds/symlink/tps65910.pdf
+ */
+
+&tps {
+ compatible = "ti,tps65910";
+
+ regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vrtc_reg: regulator@0 {
+ reg = <0>;
+ regulator-compatible = "vrtc";
+ };
+
+ vio_reg: regulator@1 {
+ reg = <1>;
+ regulator-compatible = "vio";
+ };
+
+ vdd1_reg: regulator@2 {
+ reg = <2>;
+ regulator-compatible = "vdd1";
+ };
+
+ vdd2_reg: regulator@3 {
+ reg = <3>;
+ regulator-compatible = "vdd2";
+ };
+
+ vdd3_reg: regulator@4 {
+ reg = <4>;
+ regulator-compatible = "vdd3";
+ };
+
+ vdig1_reg: regulator@5 {
+ reg = <5>;
+ regulator-compatible = "vdig1";
+ };
+
+ vdig2_reg: regulator@6 {
+ reg = <6>;
+ regulator-compatible = "vdig2";
+ };
+
+ vpll_reg: regulator@7 {
+ reg = <7>;
+ regulator-compatible = "vpll";
+ };
+
+ vdac_reg: regulator@8 {
+ reg = <8>;
+ regulator-compatible = "vdac";
+ };
+
+ vaux1_reg: regulator@9 {
+ reg = <9>;
+ regulator-compatible = "vaux1";
+ };
+
+ vaux2_reg: regulator@10 {
+ reg = <10>;
+ regulator-compatible = "vaux2";
+ };
+
+ vaux33_reg: regulator@11 {
+ reg = <11>;
+ regulator-compatible = "vaux33";
+ };
+
+ vmmc_reg: regulator@12 {
+ reg = <12>;
+ regulator-compatible = "vmmc";
+ };
+
+ vbb_reg: regulator@13 {
+ reg = <13>;
+ regulator-compatible = "vbb";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/twl4030.dtsi b/arch/arm/boot/dts/twl4030.dtsi
new file mode 100644
index 000000000..36ae9160b
--- /dev/null
+++ b/arch/arm/boot/dts/twl4030.dtsi
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * Integrated Power Management Chip
+ */
+&twl {
+ compatible = "ti,twl4030";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ rtc {
+ compatible = "ti,twl4030-rtc";
+ interrupts = <11>;
+ };
+
+ charger: bci {
+ compatible = "ti,twl4030-bci";
+ interrupts = <9>, <2>;
+ bci3v1-supply = <&vusb3v1>;
+ };
+
+ watchdog {
+ compatible = "ti,twl4030-wdt";
+ };
+
+ vaux1: regulator-vaux1 {
+ compatible = "ti,twl4030-vaux1";
+ };
+
+ vaux2: regulator-vaux2 {
+ compatible = "ti,twl4030-vaux2";
+ };
+
+ vaux3: regulator-vaux3 {
+ compatible = "ti,twl4030-vaux3";
+ };
+
+ vaux4: regulator-vaux4 {
+ compatible = "ti,twl4030-vaux4";
+ };
+
+ vcc: regulator-vdd1 {
+ compatible = "ti,twl4030-vdd1";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1450000>;
+ };
+
+ vdac: regulator-vdac {
+ compatible = "ti,twl4030-vdac";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vio: regulator-vio {
+ compatible = "ti,twl4030-vio";
+ };
+
+ vintana1: regulator-vintana1 {
+ compatible = "ti,twl4030-vintana1";
+ };
+
+ vintana2: regulator-vintana2 {
+ compatible = "ti,twl4030-vintana2";
+ };
+
+ vintdig: regulator-vintdig {
+ compatible = "ti,twl4030-vintdig";
+ };
+
+ vmmc1: regulator-vmmc1 {
+ compatible = "ti,twl4030-vmmc1";
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <3150000>;
+ };
+
+ vmmc2: regulator-vmmc2 {
+ compatible = "ti,twl4030-vmmc2";
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <3150000>;
+ };
+
+ vusb1v5: regulator-vusb1v5 {
+ compatible = "ti,twl4030-vusb1v5";
+ };
+
+ vusb1v8: regulator-vusb1v8 {
+ compatible = "ti,twl4030-vusb1v8";
+ };
+
+ vusb3v1: regulator-vusb3v1 {
+ compatible = "ti,twl4030-vusb3v1";
+ };
+
+ vpll1: regulator-vpll1 {
+ compatible = "ti,twl4030-vpll1";
+ };
+
+ vpll2: regulator-vpll2 {
+ compatible = "ti,twl4030-vpll2";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vsim: regulator-vsim {
+ compatible = "ti,twl4030-vsim";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ twl_gpio: gpio {
+ compatible = "ti,twl4030-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ usb2_phy: twl4030-usb {
+ compatible = "ti,twl4030-usb";
+ interrupts = <10>, <4>;
+ usb1v5-supply = <&vusb1v5>;
+ usb1v8-supply = <&vusb1v8>;
+ usb3v1-supply = <&vusb3v1>;
+ usb_mode = <1>;
+ #phy-cells = <0>;
+ };
+
+ twl_pwm: pwm {
+ compatible = "ti,twl4030-pwm";
+ #pwm-cells = <2>;
+ };
+
+ twl_pwmled: pwmled {
+ compatible = "ti,twl4030-pwmled";
+ #pwm-cells = <2>;
+ };
+
+ twl_pwrbutton: pwrbutton {
+ compatible = "ti,twl4030-pwrbutton";
+ interrupts = <8>;
+ };
+
+ twl_keypad: keypad {
+ compatible = "ti,twl4030-keypad";
+ interrupts = <1>;
+ keypad,num-rows = <8>;
+ keypad,num-columns = <8>;
+ };
+
+ twl_madc: madc {
+ compatible = "ti,twl4030-madc";
+ interrupts = <3>;
+ #io-channel-cells = <1>;
+ };
+};
diff --git a/arch/arm/boot/dts/twl4030_omap3.dtsi b/arch/arm/boot/dts/twl4030_omap3.dtsi
new file mode 100644
index 000000000..3537ae5b2
--- /dev/null
+++ b/arch/arm/boot/dts/twl4030_omap3.dtsi
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 Linaro, 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.
+ */
+
+&twl {
+ pinctrl-names = "default";
+ pinctrl-0 = <&twl4030_pins &twl4030_vpins>;
+};
+
+&omap3_pmx_core {
+ /*
+ * On most OMAP3 platforms, the twl4030 IRQ line is connected
+ * to the SYS_NIRQ line on OMAP. Therefore, configure the
+ * defaults for the SYS_NIRQ pin here.
+ */
+ twl4030_pins: pinmux_twl4030_pins {
+ pinctrl-single,pins = <
+ 0x1b0 (PIN_INPUT_PULLUP | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* sys_nirq.sys_nirq */
+ >;
+ };
+};
+
+/*
+ * If your board is not using the I2C4 pins with twl4030, then don't include
+ * this file. For proper idle mode signaling with sys_clkreq and sys_off_mode
+ * pins we need to configure I2C4, or else use the legacy sys_nvmode1 and
+ * sys_nvmode2 signaling.
+ */
+&omap3_pmx_wkup {
+ twl4030_vpins: pinmux_twl4030_vpins {
+ pinctrl-single,pins = <
+ OMAP3_WKUP_IOPAD(0x2a00, PIN_INPUT | MUX_MODE0) /* i2c4_scl.i2c4_scl */
+ OMAP3_WKUP_IOPAD(0x2a02, PIN_INPUT | MUX_MODE0) /* i2c4_sda.i2c4_sda */
+ OMAP3_WKUP_IOPAD(0x2a06, PIN_OUTPUT | MUX_MODE0) /* sys_clkreq.sys_clkreq */
+ OMAP3_WKUP_IOPAD(0x2a18, PIN_OUTPUT | MUX_MODE0) /* sys_off_mode.sys_off_mode */
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/twl6030.dtsi b/arch/arm/boot/dts/twl6030.dtsi
new file mode 100644
index 000000000..55eb35f06
--- /dev/null
+++ b/arch/arm/boot/dts/twl6030.dtsi
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * Integrated Power Management Chip
+ * http://www.ti.com/lit/ds/symlink/twl6030.pdf
+ */
+&twl {
+ compatible = "ti,twl6030";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ rtc {
+ compatible = "ti,twl4030-rtc";
+ interrupts = <11>;
+ };
+
+ vaux1: regulator-vaux1 {
+ compatible = "ti,twl6030-vaux1";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ vaux2: regulator-vaux2 {
+ compatible = "ti,twl6030-vaux2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ vaux3: regulator-vaux3 {
+ compatible = "ti,twl6030-vaux3";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ vmmc: regulator-vmmc {
+ compatible = "ti,twl6030-vmmc";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ vpp: regulator-vpp {
+ compatible = "ti,twl6030-vpp";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2500000>;
+ };
+
+ vusim: regulator-vusim {
+ compatible = "ti,twl6030-vusim";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+ vdac: regulator-vdac {
+ compatible = "ti,twl6030-vdac";
+ };
+
+ vana: regulator-vana {
+ compatible = "ti,twl6030-vana";
+ };
+
+ vcxio: regulator-vcxio {
+ compatible = "ti,twl6030-vcxio";
+ regulator-always-on;
+ };
+
+ vusb: regulator-vusb {
+ compatible = "ti,twl6030-vusb";
+ };
+
+ v1v8: regulator-v1v8 {
+ compatible = "ti,twl6030-v1v8";
+ regulator-always-on;
+ };
+
+ v2v1: regulator-v2v1 {
+ compatible = "ti,twl6030-v2v1";
+ regulator-always-on;
+ };
+
+ twl_usb_comparator: usb-comparator {
+ compatible = "ti,twl6030-usb";
+ interrupts = <4>, <10>;
+ };
+
+ twl_pwm: pwm {
+ /* provides two PWMs (id 0, 1 for PWM1 and PWM2) */
+ compatible = "ti,twl6030-pwm";
+ #pwm-cells = <2>;
+ };
+
+ twl_pwmled: pwmled {
+ /* provides one PWM (id 0 for Charging indicator LED) */
+ compatible = "ti,twl6030-pwmled";
+ #pwm-cells = <2>;
+ };
+};
diff --git a/arch/arm/boot/dts/twl6030_omap4.dtsi b/arch/arm/boot/dts/twl6030_omap4.dtsi
new file mode 100644
index 000000000..a4fa5703c
--- /dev/null
+++ b/arch/arm/boot/dts/twl6030_omap4.dtsi
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+&twl {
+ /*
+ * On most OMAP4 platforms, the twl6030 IRQ line is connected
+ * to the SYS_NIRQ1 line on OMAP and the twl6030 MSECURE line is
+ * connected to the fref_clk0_out.sys_drm_msecure line.
+ * Therefore, configure the defaults for the SYS_NIRQ1 and
+ * fref_clk0_out.sys_drm_msecure pins here.
+ */
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &twl6030_pins
+ &twl6030_wkup_pins
+ >;
+};
+
+&omap4_pmx_wkup {
+ twl6030_wkup_pins: pinmux_twl6030_wkup_pins {
+ pinctrl-single,pins = <
+ 0x14 (PIN_OUTPUT | MUX_MODE2) /* fref_clk0_out.sys_drm_msecure */
+ >;
+ };
+};
+
+&omap4_pmx_core {
+ twl6030_pins: pinmux_twl6030_pins {
+ pinctrl-single,pins = <
+ 0x15e (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq1.sys_nirq1 */
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/usb_a9260.dts b/arch/arm/boot/dts/usb_a9260.dts
new file mode 100644
index 000000000..de0c24f52
--- /dev/null
+++ b/arch/arm/boot/dts/usb_a9260.dts
@@ -0,0 +1,32 @@
+/*
+ * usb_a9260.dts - Device Tree file for Caloa USB A9260 board
+ *
+ * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "at91sam9260.dtsi"
+#include "usb_a9260_common.dtsi"
+
+/ {
+ model = "Calao USB A9260";
+ compatible = "calao,usb-a9260", "atmel,at91sam9260", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock5 rw rootfstype=ubifs";
+ };
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ ahb {
+ apb {
+ shdwc@fffffd10 {
+ atmel,wakeup-counter = <10>;
+ atmel,wakeup-rtt-timer;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/usb_a9260_common.dtsi b/arch/arm/boot/dts/usb_a9260_common.dtsi
new file mode 100644
index 000000000..12edafefd
--- /dev/null
+++ b/arch/arm/boot/dts/usb_a9260_common.dtsi
@@ -0,0 +1,125 @@
+/*
+ * usb_a926x.dts - Device Tree file for Caloa USB A926x board
+ *
+ * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/ {
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ macb0: ethernet@fffc4000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ usb1: gadget@fffa4000 {
+ atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x20000>;
+ };
+
+ barebox@20000 {
+ label = "barebox";
+ reg = <0x20000 0x40000>;
+ };
+
+ bareboxenv@60000 {
+ label = "bareboxenv";
+ reg = <0x60000 0x20000>;
+ };
+
+ bareboxenv2@80000 {
+ label = "bareboxenv2";
+ reg = <0x80000 0x20000>;
+ };
+
+ oftree@80000 {
+ label = "oftree";
+ reg = <0xa0000 0x20000>;
+ };
+
+ kernel@a0000 {
+ label = "kernel";
+ reg = <0xc0000 0x400000>;
+ };
+
+ rootfs@4a0000 {
+ label = "rootfs";
+ reg = <0x4c0000 0x7800000>;
+ };
+
+ data@7ca0000 {
+ label = "data";
+ reg = <0x7cc0000 0x8340000>;
+ };
+ };
+
+ usb0: ohci@00500000 {
+ num-ports = <2>;
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ user_led {
+ label = "user_led";
+ gpios = <&pioB 21 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ user_pb {
+ label = "user_pb";
+ gpios = <&pioB 10 GPIO_ACTIVE_LOW>;
+ linux,code = <28>;
+ gpio-key,wakeup;
+ };
+ };
+
+ i2c@0 {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/usb_a9263.dts b/arch/arm/boot/dts/usb_a9263.dts
new file mode 100644
index 000000000..68c0de36c
--- /dev/null
+++ b/arch/arm/boot/dts/usb_a9263.dts
@@ -0,0 +1,153 @@
+/*
+ * usb_a9263.dts - Device Tree file for Caloa USB A9293 board
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 only
+ */
+/dts-v1/;
+#include "at91sam9263.dtsi"
+
+/ {
+ model = "Calao USB A9263";
+ compatible = "atmel,usb-a9263", "atmel,at91sam9263", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock5 rw rootfstype=ubifs";
+ };
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@ffffee00 {
+ status = "okay";
+ };
+
+ macb0: ethernet@fffbc000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ usb1: gadget@fff78000 {
+ atmel,vbus-gpio = <&pioB 11 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ spi0: spi@fffa4000 {
+ cs-gpios = <&pioB 15 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ mtd_dataflash@0 {
+ compatible = "atmel,at45", "atmel,dataflash";
+ reg = <0>;
+ spi-max-frequency = <15000000>;
+ };
+ };
+
+ shdwc@fffffd10 {
+ atmel,wakeup-counter = <10>;
+ atmel,wakeup-rtt-timer;
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x20000>;
+ };
+
+ barebox@20000 {
+ label = "barebox";
+ reg = <0x20000 0x40000>;
+ };
+
+ bareboxenv@60000 {
+ label = "bareboxenv";
+ reg = <0x60000 0x20000>;
+ };
+
+ bareboxenv2@80000 {
+ label = "bareboxenv2";
+ reg = <0x80000 0x20000>;
+ };
+
+ oftree@80000 {
+ label = "oftree";
+ reg = <0xa0000 0x20000>;
+ };
+
+ kernel@a0000 {
+ label = "kernel";
+ reg = <0xc0000 0x400000>;
+ };
+
+ rootfs@4a0000 {
+ label = "rootfs";
+ reg = <0x4c0000 0x7800000>;
+ };
+
+ data@7ca0000 {
+ label = "data";
+ reg = <0x7cc0000 0x8340000>;
+ };
+ };
+
+ usb0: ohci@00a00000 {
+ num-ports = <2>;
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ user_led {
+ label = "user_led";
+ gpios = <&pioB 21 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ user_pb {
+ label = "user_pb";
+ gpios = <&pioB 10 GPIO_ACTIVE_LOW>;
+ linux,code = <28>;
+ gpio-key,wakeup;
+ };
+ };
+
+ i2c@0 {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/usb_a9g20-dab-mmx.dtsi b/arch/arm/boot/dts/usb_a9g20-dab-mmx.dtsi
new file mode 100644
index 000000000..5b0ffc1a0
--- /dev/null
+++ b/arch/arm/boot/dts/usb_a9g20-dab-mmx.dtsi
@@ -0,0 +1,96 @@
+/*
+ * calao-dab-mmx.dtsi - Device Tree Include file for Calao DAB-MMX Daughter Board
+ *
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+/ {
+ ahb {
+ apb {
+ usart1: serial@fffb4000 {
+ status = "okay";
+ };
+
+ usart3: serial@fffd0000 {
+ status = "okay";
+ };
+ };
+ };
+
+ i2c-gpio@0 {
+ status = "okay";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ user_led1 {
+ label = "user_led1";
+ gpios = <&pioB 20 GPIO_ACTIVE_LOW>;
+ };
+
+/*
+* led already used by mother board but active as high
+* user_led2 {
+* label = "user_led2";
+* gpios = <&pioB 21 GPIO_ACTIVE_LOW>;
+* };
+*/
+ user_led3 {
+ label = "user_led3";
+ gpios = <&pioB 22 GPIO_ACTIVE_LOW>;
+ };
+
+ user_led4 {
+ label = "user_led4";
+ gpios = <&pioB 23 GPIO_ACTIVE_LOW>;
+ };
+
+ red {
+ label = "red";
+ gpios = <&pioB 24 GPIO_ACTIVE_LOW>;
+ };
+
+ orange {
+ label = "orange";
+ gpios = <&pioB 30 GPIO_ACTIVE_LOW>;
+ };
+
+ green {
+ label = "green";
+ gpios = <&pioB 31 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ user_pb1 {
+ label = "user_pb1";
+ gpios = <&pioB 25 GPIO_ACTIVE_LOW>;
+ linux,code = <0x100>;
+ };
+
+ user_pb2 {
+ label = "user_pb2";
+ gpios = <&pioB 13 GPIO_ACTIVE_LOW>;
+ linux,code = <0x101>;
+ };
+
+ user_pb3 {
+ label = "user_pb3";
+ gpios = <&pioA 26 GPIO_ACTIVE_LOW>;
+ linux,code = <0x102>;
+ };
+
+ user_pb4 {
+ label = "user_pb4";
+ gpios = <&pioC 9 GPIO_ACTIVE_LOW>;
+ linux,code = <0x103>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/usb_a9g20.dts b/arch/arm/boot/dts/usb_a9g20.dts
new file mode 100644
index 000000000..ec77cf8f9
--- /dev/null
+++ b/arch/arm/boot/dts/usb_a9g20.dts
@@ -0,0 +1,14 @@
+/*
+ * usb_a9g20.dts - Device Tree file for Caloa USB A9G20 board
+ *
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "usb_a9g20_common.dtsi"
+
+/ {
+ model = "Calao USB A9G20";
+ compatible = "calao,usb-a9g20", "atmel,at91sam9g20", "atmel,at91sam9";
+};
diff --git a/arch/arm/boot/dts/usb_a9g20_common.dtsi b/arch/arm/boot/dts/usb_a9g20_common.dtsi
new file mode 100644
index 000000000..0b3b36182
--- /dev/null
+++ b/arch/arm/boot/dts/usb_a9g20_common.dtsi
@@ -0,0 +1,27 @@
+/*
+ * usb_a9g20.dts - Device Tree file for Caloa USB A9G20 board
+ *
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include "at91sam9g20.dtsi"
+#include "usb_a9260_common.dtsi"
+
+/ {
+ chosen {
+ bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock5 rw rootfstype=ubifs";
+ };
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ i2c@0 {
+ rv3029c2@56 {
+ compatible = "rv3029c2";
+ reg = <0x56>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/usb_a9g20_lpw.dts b/arch/arm/boot/dts/usb_a9g20_lpw.dts
new file mode 100644
index 000000000..f8cb1b9a0
--- /dev/null
+++ b/arch/arm/boot/dts/usb_a9g20_lpw.dts
@@ -0,0 +1,31 @@
+/*
+ * usb_a9g20_lpw.dts - Device Tree file for Caloa USB A9G20 Low Power board
+ *
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "usb_a9g20_common.dtsi"
+
+/ {
+ model = "Calao USB A9G20 Low Power";
+ compatible = "calao,usb-a9g20-lpw", "calao,usb-a9g20", "atmel,at91sam9g20", "atmel,at91sam9";
+
+ ahb {
+ apb {
+ spi1: spi@fffcc000 {
+ cs-gpios = <&pioB 3 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ mmc-slot@0 {
+ compatible = "mmc-spi-slot";
+ reg = <0>;
+ voltage-ranges = <3200 3400>;
+ spi-max-frequency = <25000000>;
+ interrupt-parent = <&pioC>;
+ interrupts = <4 IRQ_TYPE_EDGE_BOTH>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts
new file mode 100644
index 000000000..01f40197e
--- /dev/null
+++ b/arch/arm/boot/dts/versatile-ab.dts
@@ -0,0 +1,292 @@
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "ARM Versatile AB";
+ compatible = "arm,versatile-ab";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&vic>;
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ i2c0 = &i2c0;
+ };
+
+ chosen {
+ stdout-path = &uart0;
+ };
+
+ memory {
+ reg = <0x0 0x08000000>;
+ };
+
+ xtal24mhz: xtal24mhz@24M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ core-module@10000000 {
+ compatible = "arm,core-module-versatile", "syscon";
+ reg = <0x10000000 0x200>;
+
+ /* OSC1 on AB, OSC4 on PB */
+ osc1: cm_aux_osc@24M {
+ #clock-cells = <0>;
+ compatible = "arm,versatile-cm-auxosc";
+ clocks = <&xtal24mhz>;
+ };
+
+ /* The timer clock is the 24 MHz oscillator divided to 1MHz */
+ timclk: timclk@1M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <24>;
+ clock-mult = <1>;
+ clocks = <&xtal24mhz>;
+ };
+
+ pclk: pclk@24M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <1>;
+ clock-mult = <1>;
+ clocks = <&xtal24mhz>;
+ };
+ };
+
+ flash@34000000 {
+ compatible = "arm,versatile-flash";
+ reg = <0x34000000 0x4000000>;
+ bank-width = <4>;
+ };
+
+ i2c0: i2c@10002000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "arm,versatile-i2c";
+ reg = <0x10002000 0x1000>;
+
+ rtc@68 {
+ compatible = "dallas,ds1338";
+ reg = <0x68>;
+ };
+ };
+
+ net@10010000 {
+ compatible = "smsc,lan91c111";
+ reg = <0x10010000 0x10000>;
+ interrupts = <25>;
+ };
+
+ lcd@10008000 {
+ compatible = "arm,versatile-lcd";
+ reg = <0x10008000 0x1000>;
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ vic: intc@10140000 {
+ compatible = "arm,versatile-vic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x10140000 0x1000>;
+ clear-mask = <0xffffffff>;
+ valid-mask = <0xffffffff>;
+ };
+
+ sic: intc@10003000 {
+ compatible = "arm,versatile-sic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x10003000 0x1000>;
+ interrupt-parent = <&vic>;
+ interrupts = <31>; /* Cascaded to vic */
+ clear-mask = <0xffffffff>;
+ valid-mask = <0xffc203f8>;
+ };
+
+ dma@10130000 {
+ compatible = "arm,pl081", "arm,primecell";
+ reg = <0x10130000 0x1000>;
+ interrupts = <17>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ uart0: uart@101f1000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x101f1000 0x1000>;
+ interrupts = <12>;
+ clocks = <&xtal24mhz>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ uart1: uart@101f2000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x101f2000 0x1000>;
+ interrupts = <13>;
+ clocks = <&xtal24mhz>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ uart2: uart@101f3000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x101f3000 0x1000>;
+ interrupts = <14>;
+ clocks = <&xtal24mhz>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ smc@10100000 {
+ compatible = "arm,primecell";
+ reg = <0x10100000 0x1000>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ mpmc@10110000 {
+ compatible = "arm,primecell";
+ reg = <0x10110000 0x1000>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ display@10120000 {
+ compatible = "arm,pl110", "arm,primecell";
+ reg = <0x10120000 0x1000>;
+ interrupts = <16>;
+ clocks = <&osc1>, <&pclk>;
+ clock-names = "clcd", "apb_pclk";
+ };
+
+ sctl@101e0000 {
+ compatible = "arm,primecell";
+ reg = <0x101e0000 0x1000>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ watchdog@101e1000 {
+ compatible = "arm,primecell";
+ reg = <0x101e1000 0x1000>;
+ interrupts = <0>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ timer@101e2000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x101e2000 0x1000>;
+ interrupts = <4>;
+ clocks = <&timclk>, <&timclk>, <&pclk>;
+ clock-names = "timer0", "timer1", "apb_pclk";
+ };
+
+ timer@101e3000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x101e3000 0x1000>;
+ interrupts = <5>;
+ clocks = <&timclk>, <&timclk>, <&pclk>;
+ clock-names = "timer0", "timer1", "apb_pclk";
+ };
+
+ gpio0: gpio@101e4000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x101e4000 0x1000>;
+ gpio-controller;
+ interrupts = <6>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio1: gpio@101e5000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x101e5000 0x1000>;
+ interrupts = <7>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ rtc@101e8000 {
+ compatible = "arm,pl030", "arm,primecell";
+ reg = <0x101e8000 0x1000>;
+ interrupts = <10>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ sci@101f0000 {
+ compatible = "arm,primecell";
+ reg = <0x101f0000 0x1000>;
+ interrupts = <15>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ ssp@101f4000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x101f4000 0x1000>;
+ interrupts = <11>;
+ clocks = <&xtal24mhz>, <&pclk>;
+ clock-names = "SSPCLK", "apb_pclk";
+ };
+
+ fpga {
+ compatible = "arm,versatile-fpga", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x10000000 0x10000>;
+
+ sysreg@0 {
+ compatible = "arm,versatile-sysreg", "syscon";
+ reg = <0x00000 0x1000>;
+ };
+
+ aaci@4000 {
+ compatible = "arm,primecell";
+ reg = <0x4000 0x1000>;
+ interrupts = <24>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+ mmc@5000 {
+ compatible = "arm,pl180", "arm,primecell";
+ reg = < 0x5000 0x1000>;
+ interrupts-extended = <&vic 22 &sic 2>;
+ clocks = <&xtal24mhz>, <&pclk>;
+ clock-names = "mclk", "apb_pclk";
+ };
+ kmi@6000 {
+ compatible = "arm,pl050", "arm,primecell";
+ reg = <0x6000 0x1000>;
+ interrupt-parent = <&sic>;
+ interrupts = <3>;
+ clocks = <&xtal24mhz>, <&pclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+ kmi@7000 {
+ compatible = "arm,pl050", "arm,primecell";
+ reg = <0x7000 0x1000>;
+ interrupt-parent = <&sic>;
+ interrupts = <4>;
+ clocks = <&xtal24mhz>, <&pclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/versatile-pb.dts b/arch/arm/boot/dts/versatile-pb.dts
new file mode 100644
index 000000000..b83137f66
--- /dev/null
+++ b/arch/arm/boot/dts/versatile-pb.dts
@@ -0,0 +1,95 @@
+#include <versatile-ab.dts>
+
+/ {
+ model = "ARM Versatile PB";
+ compatible = "arm,versatile-pb";
+
+ amba {
+ gpio2: gpio@101e6000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x101e6000 0x1000>;
+ interrupts = <8>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio3: gpio@101e7000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x101e7000 0x1000>;
+ interrupts = <9>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ pci-controller@10001000 {
+ compatible = "arm,versatile-pci";
+ device_type = "pci";
+ reg = <0x10001000 0x1000
+ 0x41000000 0x10000
+ 0x42000000 0x100000>;
+ bus-range = <0 0xff>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+
+ ranges = <0x01000000 0 0x00000000 0x43000000 0 0x00010000 /* downstream I/O */
+ 0x02000000 0 0x50000000 0x50000000 0 0x10000000 /* non-prefetchable memory */
+ 0x42000000 0 0x60000000 0x60000000 0 0x10000000>; /* prefetchable memory */
+
+ interrupt-map-mask = <0x1800 0 0 7>;
+ interrupt-map = <0x1800 0 0 1 &sic 28
+ 0x1800 0 0 2 &sic 29
+ 0x1800 0 0 3 &sic 30
+ 0x1800 0 0 4 &sic 27
+
+ 0x1000 0 0 1 &sic 27
+ 0x1000 0 0 2 &sic 28
+ 0x1000 0 0 3 &sic 29
+ 0x1000 0 0 4 &sic 30
+
+ 0x0800 0 0 1 &sic 30
+ 0x0800 0 0 2 &sic 27
+ 0x0800 0 0 3 &sic 28
+ 0x0800 0 0 4 &sic 29
+
+ 0x0000 0 0 1 &sic 29
+ 0x0000 0 0 2 &sic 30
+ 0x0000 0 0 3 &sic 27
+ 0x0000 0 0 4 &sic 28>;
+ };
+
+ fpga {
+ uart@9000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x9000 0x1000>;
+ interrupt-parent = <&sic>;
+ interrupts = <6>;
+ clocks = <&xtal24mhz>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+ sci@a000 {
+ compatible = "arm,primecell";
+ reg = <0xa000 0x1000>;
+ interrupt-parent = <&sic>;
+ interrupts = <5>;
+ clocks = <&xtal24mhz>;
+ clock-names = "apb_pclk";
+ };
+ mmc@b000 {
+ compatible = "arm,pl180", "arm,primecell";
+ reg = <0xb000 0x1000>;
+ interrupts-extended = <&vic 23 &sic 2>;
+ clocks = <&xtal24mhz>, <&pclk>;
+ clock-names = "mclk", "apb_pclk";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
new file mode 100644
index 000000000..2efb2058b
--- /dev/null
+++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
@@ -0,0 +1,440 @@
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * Motherboard Express uATX
+ * V2M-P1
+ *
+ * HBI-0190D
+ *
+ * RS1 memory map ("ARM Cortex-A Series memory map" in the board's
+ * Technical Reference Manual)
+ *
+ * WARNING! The hardware described in this file is independent from the
+ * original variant (vexpress-v2m.dtsi), but there is a strong
+ * correspondence between the two configurations.
+ *
+ * TAKE CARE WHEN MAINTAINING THIS FILE TO PROPAGATE ANY RELEVANT
+ * CHANGES TO vexpress-v2m.dtsi!
+ */
+
+ motherboard {
+ model = "V2M-P1";
+ arm,hbi = <0x190>;
+ arm,vexpress,site = <0>;
+ arm,v2m-memory-map = "rs1";
+ compatible = "arm,vexpress,v2m-p1", "simple-bus";
+ #address-cells = <2>; /* SMB chipselect number and offset */
+ #size-cells = <1>;
+ #interrupt-cells = <1>;
+ ranges;
+
+ flash@0,00000000 {
+ compatible = "arm,vexpress-flash", "cfi-flash";
+ reg = <0 0x00000000 0x04000000>,
+ <4 0x00000000 0x04000000>;
+ bank-width = <4>;
+ };
+
+ psram@1,00000000 {
+ compatible = "arm,vexpress-psram", "mtd-ram";
+ reg = <1 0x00000000 0x02000000>;
+ bank-width = <4>;
+ };
+
+ v2m_video_ram: vram@2,00000000 {
+ compatible = "arm,vexpress-vram";
+ reg = <2 0x00000000 0x00800000>;
+ };
+
+ ethernet@2,02000000 {
+ compatible = "smsc,lan9118", "smsc,lan9115";
+ reg = <2 0x02000000 0x10000>;
+ interrupts = <15>;
+ phy-mode = "mii";
+ reg-io-width = <4>;
+ smsc,irq-active-high;
+ smsc,irq-push-pull;
+ vdd33a-supply = <&v2m_fixed_3v3>;
+ vddvario-supply = <&v2m_fixed_3v3>;
+ };
+
+ usb@2,03000000 {
+ compatible = "nxp,usb-isp1761";
+ reg = <2 0x03000000 0x20000>;
+ interrupts = <16>;
+ port1-otg;
+ };
+
+ iofpga@3,00000000 {
+ compatible = "arm,amba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 3 0 0x200000>;
+
+ v2m_sysreg: sysreg@010000 {
+ compatible = "arm,vexpress-sysreg";
+ reg = <0x010000 0x1000>;
+
+ v2m_led_gpios: sys_led@08 {
+ compatible = "arm,vexpress-sysreg,sys_led";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ v2m_mmc_gpios: sys_mci@48 {
+ compatible = "arm,vexpress-sysreg,sys_mci";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ v2m_flash_gpios: sys_flash@4c {
+ compatible = "arm,vexpress-sysreg,sys_flash";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ v2m_sysctl: sysctl@020000 {
+ compatible = "arm,sp810", "arm,primecell";
+ reg = <0x020000 0x1000>;
+ clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
+ clock-names = "refclk", "timclk", "apb_pclk";
+ #clock-cells = <1>;
+ clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+ };
+
+ /* PCI-E I2C bus */
+ v2m_i2c_pcie: i2c@030000 {
+ compatible = "arm,versatile-i2c";
+ reg = <0x030000 0x1000>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pcie-switch@60 {
+ compatible = "idt,89hpes32h8";
+ reg = <0x60>;
+ };
+ };
+
+ aaci@040000 {
+ compatible = "arm,pl041", "arm,primecell";
+ reg = <0x040000 0x1000>;
+ interrupts = <11>;
+ clocks = <&smbclk>;
+ clock-names = "apb_pclk";
+ };
+
+ mmci@050000 {
+ compatible = "arm,pl180", "arm,primecell";
+ reg = <0x050000 0x1000>;
+ interrupts = <9 10>;
+ cd-gpios = <&v2m_mmc_gpios 0 0>;
+ wp-gpios = <&v2m_mmc_gpios 1 0>;
+ max-frequency = <12000000>;
+ vmmc-supply = <&v2m_fixed_3v3>;
+ clocks = <&v2m_clk24mhz>, <&smbclk>;
+ clock-names = "mclk", "apb_pclk";
+ };
+
+ kmi@060000 {
+ compatible = "arm,pl050", "arm,primecell";
+ reg = <0x060000 0x1000>;
+ interrupts = <12>;
+ clocks = <&v2m_clk24mhz>, <&smbclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+
+ kmi@070000 {
+ compatible = "arm,pl050", "arm,primecell";
+ reg = <0x070000 0x1000>;
+ interrupts = <13>;
+ clocks = <&v2m_clk24mhz>, <&smbclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+
+ v2m_serial0: uart@090000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x090000 0x1000>;
+ interrupts = <5>;
+ clocks = <&v2m_oscclk2>, <&smbclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ v2m_serial1: uart@0a0000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x0a0000 0x1000>;
+ interrupts = <6>;
+ clocks = <&v2m_oscclk2>, <&smbclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ v2m_serial2: uart@0b0000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x0b0000 0x1000>;
+ interrupts = <7>;
+ clocks = <&v2m_oscclk2>, <&smbclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ v2m_serial3: uart@0c0000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x0c0000 0x1000>;
+ interrupts = <8>;
+ clocks = <&v2m_oscclk2>, <&smbclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ wdt@0f0000 {
+ compatible = "arm,sp805", "arm,primecell";
+ reg = <0x0f0000 0x1000>;
+ interrupts = <0>;
+ clocks = <&v2m_refclk32khz>, <&smbclk>;
+ clock-names = "wdogclk", "apb_pclk";
+ };
+
+ v2m_timer01: timer@110000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x110000 0x1000>;
+ interrupts = <2>;
+ clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&smbclk>;
+ clock-names = "timclken1", "timclken2", "apb_pclk";
+ };
+
+ v2m_timer23: timer@120000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x120000 0x1000>;
+ interrupts = <3>;
+ clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&smbclk>;
+ clock-names = "timclken1", "timclken2", "apb_pclk";
+ };
+
+ /* DVI I2C bus */
+ v2m_i2c_dvi: i2c@160000 {
+ compatible = "arm,versatile-i2c";
+ reg = <0x160000 0x1000>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dvi-transmitter@39 {
+ compatible = "sil,sii9022-tpi", "sil,sii9022";
+ reg = <0x39>;
+ };
+
+ dvi-transmitter@60 {
+ compatible = "sil,sii9022-cpi", "sil,sii9022";
+ reg = <0x60>;
+ };
+ };
+
+ rtc@170000 {
+ compatible = "arm,pl031", "arm,primecell";
+ reg = <0x170000 0x1000>;
+ interrupts = <4>;
+ clocks = <&smbclk>;
+ clock-names = "apb_pclk";
+ };
+
+ compact-flash@1a0000 {
+ compatible = "arm,vexpress-cf", "ata-generic";
+ reg = <0x1a0000 0x100
+ 0x1a0100 0xf00>;
+ reg-shift = <2>;
+ };
+
+ clcd@1f0000 {
+ compatible = "arm,pl111", "arm,primecell";
+ reg = <0x1f0000 0x1000>;
+ interrupt-names = "combined";
+ interrupts = <14>;
+ clocks = <&v2m_oscclk1>, <&smbclk>;
+ clock-names = "clcdclk", "apb_pclk";
+ memory-region = <&v2m_video_ram>;
+ max-memory-bandwidth = <50350000>; /* 16bpp @ 25.175MHz */
+
+ port {
+ v2m_clcd_pads: endpoint {
+ remote-endpoint = <&v2m_clcd_panel>;
+ arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+ };
+ };
+
+ panel {
+ compatible = "panel-dpi";
+
+ port {
+ v2m_clcd_panel: endpoint {
+ remote-endpoint = <&v2m_clcd_pads>;
+ };
+ };
+
+ panel-timing {
+ clock-frequency = <25175000>;
+ hactive = <640>;
+ hback-porch = <40>;
+ hfront-porch = <24>;
+ hsync-len = <96>;
+ vactive = <480>;
+ vback-porch = <32>;
+ vfront-porch = <11>;
+ vsync-len = <2>;
+ };
+ };
+ };
+ };
+
+ v2m_fixed_3v3: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ v2m_clk24mhz: clk24mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "v2m:clk24mhz";
+ };
+
+ v2m_refclk1mhz: refclk1mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1000000>;
+ clock-output-names = "v2m:refclk1mhz";
+ };
+
+ v2m_refclk32khz: refclk32khz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "v2m:refclk32khz";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ user@1 {
+ label = "v2m:green:user1";
+ gpios = <&v2m_led_gpios 0 0>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ user@2 {
+ label = "v2m:green:user2";
+ gpios = <&v2m_led_gpios 1 0>;
+ linux,default-trigger = "mmc0";
+ };
+
+ user@3 {
+ label = "v2m:green:user3";
+ gpios = <&v2m_led_gpios 2 0>;
+ linux,default-trigger = "cpu0";
+ };
+
+ user@4 {
+ label = "v2m:green:user4";
+ gpios = <&v2m_led_gpios 3 0>;
+ linux,default-trigger = "cpu1";
+ };
+
+ user@5 {
+ label = "v2m:green:user5";
+ gpios = <&v2m_led_gpios 4 0>;
+ linux,default-trigger = "cpu2";
+ };
+
+ user@6 {
+ label = "v2m:green:user6";
+ gpios = <&v2m_led_gpios 5 0>;
+ linux,default-trigger = "cpu3";
+ };
+
+ user@7 {
+ label = "v2m:green:user7";
+ gpios = <&v2m_led_gpios 6 0>;
+ linux,default-trigger = "cpu4";
+ };
+
+ user@8 {
+ label = "v2m:green:user8";
+ gpios = <&v2m_led_gpios 7 0>;
+ linux,default-trigger = "cpu5";
+ };
+ };
+
+ mcc {
+ compatible = "arm,vexpress,config-bus";
+ arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+ osc@0 {
+ /* MCC static memory clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 0>;
+ freq-range = <25000000 60000000>;
+ #clock-cells = <0>;
+ clock-output-names = "v2m:oscclk0";
+ };
+
+ v2m_oscclk1: osc@1 {
+ /* CLCD clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 1>;
+ freq-range = <23750000 65000000>;
+ #clock-cells = <0>;
+ clock-output-names = "v2m:oscclk1";
+ };
+
+ v2m_oscclk2: osc@2 {
+ /* IO FPGA peripheral clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 2>;
+ freq-range = <24000000 24000000>;
+ #clock-cells = <0>;
+ clock-output-names = "v2m:oscclk2";
+ };
+
+ volt@0 {
+ /* Logic level voltage */
+ compatible = "arm,vexpress-volt";
+ arm,vexpress-sysreg,func = <2 0>;
+ regulator-name = "VIO";
+ regulator-always-on;
+ label = "VIO";
+ };
+
+ temp@0 {
+ /* MCC internal operating temperature */
+ compatible = "arm,vexpress-temp";
+ arm,vexpress-sysreg,func = <4 0>;
+ label = "MCC";
+ };
+
+ reset@0 {
+ compatible = "arm,vexpress-reset";
+ arm,vexpress-sysreg,func = <5 0>;
+ };
+
+ muxfpga@0 {
+ compatible = "arm,vexpress-muxfpga";
+ arm,vexpress-sysreg,func = <7 0>;
+ };
+
+ shutdown@0 {
+ compatible = "arm,vexpress-shutdown";
+ arm,vexpress-sysreg,func = <8 0>;
+ };
+
+ reboot@0 {
+ compatible = "arm,vexpress-reboot";
+ arm,vexpress-sysreg,func = <9 0>;
+ };
+
+ dvimode@0 {
+ compatible = "arm,vexpress-dvimode";
+ arm,vexpress-sysreg,func = <11 0>;
+ };
+ };
+ };
diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi
new file mode 100644
index 000000000..cb3090f91
--- /dev/null
+++ b/arch/arm/boot/dts/vexpress-v2m.dtsi
@@ -0,0 +1,439 @@
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * Motherboard Express uATX
+ * V2M-P1
+ *
+ * HBI-0190D
+ *
+ * Original memory map ("Legacy memory map" in the board's
+ * Technical Reference Manual)
+ *
+ * WARNING! The hardware described in this file is independent from the
+ * RS1 variant (vexpress-v2m-rs1.dtsi), but there is a strong
+ * correspondence between the two configurations.
+ *
+ * TAKE CARE WHEN MAINTAINING THIS FILE TO PROPAGATE ANY RELEVANT
+ * CHANGES TO vexpress-v2m-rs1.dtsi!
+ */
+
+ motherboard {
+ model = "V2M-P1";
+ arm,hbi = <0x190>;
+ arm,vexpress,site = <0>;
+ compatible = "arm,vexpress,v2m-p1", "simple-bus";
+ #address-cells = <2>; /* SMB chipselect number and offset */
+ #size-cells = <1>;
+ #interrupt-cells = <1>;
+ ranges;
+
+ flash@0,00000000 {
+ compatible = "arm,vexpress-flash", "cfi-flash";
+ reg = <0 0x00000000 0x04000000>,
+ <1 0x00000000 0x04000000>;
+ bank-width = <4>;
+ };
+
+ psram@2,00000000 {
+ compatible = "arm,vexpress-psram", "mtd-ram";
+ reg = <2 0x00000000 0x02000000>;
+ bank-width = <4>;
+ };
+
+ v2m_video_ram: vram@3,00000000 {
+ compatible = "arm,vexpress-vram";
+ reg = <3 0x00000000 0x00800000>;
+ };
+
+ ethernet@3,02000000 {
+ compatible = "smsc,lan9118", "smsc,lan9115";
+ reg = <3 0x02000000 0x10000>;
+ interrupts = <15>;
+ phy-mode = "mii";
+ reg-io-width = <4>;
+ smsc,irq-active-high;
+ smsc,irq-push-pull;
+ vdd33a-supply = <&v2m_fixed_3v3>;
+ vddvario-supply = <&v2m_fixed_3v3>;
+ };
+
+ usb@3,03000000 {
+ compatible = "nxp,usb-isp1761";
+ reg = <3 0x03000000 0x20000>;
+ interrupts = <16>;
+ port1-otg;
+ };
+
+ iofpga@7,00000000 {
+ compatible = "arm,amba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 7 0 0x20000>;
+
+ v2m_sysreg: sysreg@00000 {
+ compatible = "arm,vexpress-sysreg";
+ reg = <0x00000 0x1000>;
+
+ v2m_led_gpios: sys_led@08 {
+ compatible = "arm,vexpress-sysreg,sys_led";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ v2m_mmc_gpios: sys_mci@48 {
+ compatible = "arm,vexpress-sysreg,sys_mci";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ v2m_flash_gpios: sys_flash@4c {
+ compatible = "arm,vexpress-sysreg,sys_flash";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ v2m_sysctl: sysctl@01000 {
+ compatible = "arm,sp810", "arm,primecell";
+ reg = <0x01000 0x1000>;
+ clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
+ clock-names = "refclk", "timclk", "apb_pclk";
+ #clock-cells = <1>;
+ clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+ };
+
+ /* PCI-E I2C bus */
+ v2m_i2c_pcie: i2c@02000 {
+ compatible = "arm,versatile-i2c";
+ reg = <0x02000 0x1000>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pcie-switch@60 {
+ compatible = "idt,89hpes32h8";
+ reg = <0x60>;
+ };
+ };
+
+ aaci@04000 {
+ compatible = "arm,pl041", "arm,primecell";
+ reg = <0x04000 0x1000>;
+ interrupts = <11>;
+ clocks = <&smbclk>;
+ clock-names = "apb_pclk";
+ };
+
+ mmci@05000 {
+ compatible = "arm,pl180", "arm,primecell";
+ reg = <0x05000 0x1000>;
+ interrupts = <9 10>;
+ cd-gpios = <&v2m_mmc_gpios 0 0>;
+ wp-gpios = <&v2m_mmc_gpios 1 0>;
+ max-frequency = <12000000>;
+ vmmc-supply = <&v2m_fixed_3v3>;
+ clocks = <&v2m_clk24mhz>, <&smbclk>;
+ clock-names = "mclk", "apb_pclk";
+ };
+
+ kmi@06000 {
+ compatible = "arm,pl050", "arm,primecell";
+ reg = <0x06000 0x1000>;
+ interrupts = <12>;
+ clocks = <&v2m_clk24mhz>, <&smbclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+
+ kmi@07000 {
+ compatible = "arm,pl050", "arm,primecell";
+ reg = <0x07000 0x1000>;
+ interrupts = <13>;
+ clocks = <&v2m_clk24mhz>, <&smbclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+
+ v2m_serial0: uart@09000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x09000 0x1000>;
+ interrupts = <5>;
+ clocks = <&v2m_oscclk2>, <&smbclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ v2m_serial1: uart@0a000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x0a000 0x1000>;
+ interrupts = <6>;
+ clocks = <&v2m_oscclk2>, <&smbclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ v2m_serial2: uart@0b000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x0b000 0x1000>;
+ interrupts = <7>;
+ clocks = <&v2m_oscclk2>, <&smbclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ v2m_serial3: uart@0c000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x0c000 0x1000>;
+ interrupts = <8>;
+ clocks = <&v2m_oscclk2>, <&smbclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ wdt@0f000 {
+ compatible = "arm,sp805", "arm,primecell";
+ reg = <0x0f000 0x1000>;
+ interrupts = <0>;
+ clocks = <&v2m_refclk32khz>, <&smbclk>;
+ clock-names = "wdogclk", "apb_pclk";
+ };
+
+ v2m_timer01: timer@11000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x11000 0x1000>;
+ interrupts = <2>;
+ clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&smbclk>;
+ clock-names = "timclken1", "timclken2", "apb_pclk";
+ };
+
+ v2m_timer23: timer@12000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x12000 0x1000>;
+ interrupts = <3>;
+ clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&smbclk>;
+ clock-names = "timclken1", "timclken2", "apb_pclk";
+ };
+
+ /* DVI I2C bus */
+ v2m_i2c_dvi: i2c@16000 {
+ compatible = "arm,versatile-i2c";
+ reg = <0x16000 0x1000>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dvi-transmitter@39 {
+ compatible = "sil,sii9022-tpi", "sil,sii9022";
+ reg = <0x39>;
+ };
+
+ dvi-transmitter@60 {
+ compatible = "sil,sii9022-cpi", "sil,sii9022";
+ reg = <0x60>;
+ };
+ };
+
+ rtc@17000 {
+ compatible = "arm,pl031", "arm,primecell";
+ reg = <0x17000 0x1000>;
+ interrupts = <4>;
+ clocks = <&smbclk>;
+ clock-names = "apb_pclk";
+ };
+
+ compact-flash@1a000 {
+ compatible = "arm,vexpress-cf", "ata-generic";
+ reg = <0x1a000 0x100
+ 0x1a100 0xf00>;
+ reg-shift = <2>;
+ };
+
+ clcd@1f000 {
+ compatible = "arm,pl111", "arm,primecell";
+ reg = <0x1f000 0x1000>;
+ interrupt-names = "combined";
+ interrupts = <14>;
+ clocks = <&v2m_oscclk1>, <&smbclk>;
+ clock-names = "clcdclk", "apb_pclk";
+ memory-region = <&v2m_video_ram>;
+ max-memory-bandwidth = <50350000>; /* 16bpp @ 25.175MHz */
+
+ port {
+ v2m_clcd_pads: endpoint {
+ remote-endpoint = <&v2m_clcd_panel>;
+ arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+ };
+ };
+
+ panel {
+ compatible = "panel-dpi";
+
+ port {
+ v2m_clcd_panel: endpoint {
+ remote-endpoint = <&v2m_clcd_pads>;
+ };
+ };
+
+ panel-timing {
+ clock-frequency = <25175000>;
+ hactive = <640>;
+ hback-porch = <40>;
+ hfront-porch = <24>;
+ hsync-len = <96>;
+ vactive = <480>;
+ vback-porch = <32>;
+ vfront-porch = <11>;
+ vsync-len = <2>;
+ };
+ };
+ };
+ };
+
+ v2m_fixed_3v3: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ v2m_clk24mhz: clk24mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "v2m:clk24mhz";
+ };
+
+ v2m_refclk1mhz: refclk1mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1000000>;
+ clock-output-names = "v2m:refclk1mhz";
+ };
+
+ v2m_refclk32khz: refclk32khz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "v2m:refclk32khz";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ user@1 {
+ label = "v2m:green:user1";
+ gpios = <&v2m_led_gpios 0 0>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ user@2 {
+ label = "v2m:green:user2";
+ gpios = <&v2m_led_gpios 1 0>;
+ linux,default-trigger = "mmc0";
+ };
+
+ user@3 {
+ label = "v2m:green:user3";
+ gpios = <&v2m_led_gpios 2 0>;
+ linux,default-trigger = "cpu0";
+ };
+
+ user@4 {
+ label = "v2m:green:user4";
+ gpios = <&v2m_led_gpios 3 0>;
+ linux,default-trigger = "cpu1";
+ };
+
+ user@5 {
+ label = "v2m:green:user5";
+ gpios = <&v2m_led_gpios 4 0>;
+ linux,default-trigger = "cpu2";
+ };
+
+ user@6 {
+ label = "v2m:green:user6";
+ gpios = <&v2m_led_gpios 5 0>;
+ linux,default-trigger = "cpu3";
+ };
+
+ user@7 {
+ label = "v2m:green:user7";
+ gpios = <&v2m_led_gpios 6 0>;
+ linux,default-trigger = "cpu4";
+ };
+
+ user@8 {
+ label = "v2m:green:user8";
+ gpios = <&v2m_led_gpios 7 0>;
+ linux,default-trigger = "cpu5";
+ };
+ };
+
+ mcc {
+ compatible = "arm,vexpress,config-bus";
+ arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+ osc@0 {
+ /* MCC static memory clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 0>;
+ freq-range = <25000000 60000000>;
+ #clock-cells = <0>;
+ clock-output-names = "v2m:oscclk0";
+ };
+
+ v2m_oscclk1: osc@1 {
+ /* CLCD clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 1>;
+ freq-range = <23750000 65000000>;
+ #clock-cells = <0>;
+ clock-output-names = "v2m:oscclk1";
+ };
+
+ v2m_oscclk2: osc@2 {
+ /* IO FPGA peripheral clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 2>;
+ freq-range = <24000000 24000000>;
+ #clock-cells = <0>;
+ clock-output-names = "v2m:oscclk2";
+ };
+
+ volt@0 {
+ /* Logic level voltage */
+ compatible = "arm,vexpress-volt";
+ arm,vexpress-sysreg,func = <2 0>;
+ regulator-name = "VIO";
+ regulator-always-on;
+ label = "VIO";
+ };
+
+ temp@0 {
+ /* MCC internal operating temperature */
+ compatible = "arm,vexpress-temp";
+ arm,vexpress-sysreg,func = <4 0>;
+ label = "MCC";
+ };
+
+ reset@0 {
+ compatible = "arm,vexpress-reset";
+ arm,vexpress-sysreg,func = <5 0>;
+ };
+
+ muxfpga@0 {
+ compatible = "arm,vexpress-muxfpga";
+ arm,vexpress-sysreg,func = <7 0>;
+ };
+
+ shutdown@0 {
+ compatible = "arm,vexpress-shutdown";
+ arm,vexpress-sysreg,func = <8 0>;
+ };
+
+ reboot@0 {
+ compatible = "arm,vexpress-reboot";
+ arm,vexpress-sysreg,func = <9 0>;
+ };
+
+ dvimode@0 {
+ compatible = "arm,vexpress-dvimode";
+ arm,vexpress-sysreg,func = <11 0>;
+ };
+ };
+ };
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
new file mode 100644
index 000000000..9420053ac
--- /dev/null
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
@@ -0,0 +1,283 @@
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * CoreTile Express A15x2 (version with Test Chip 1)
+ * Cortex-A15 MPCore (V2P-CA15)
+ *
+ * HBI-0237A
+ */
+
+/dts-v1/;
+
+/ {
+ model = "V2P-CA15";
+ arm,hbi = <0x237>;
+ arm,vexpress,site = <0xf>;
+ compatible = "arm,vexpress,v2p-ca15,tc1", "arm,vexpress,v2p-ca15", "arm,vexpress";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ chosen { };
+
+ aliases {
+ serial0 = &v2m_serial0;
+ serial1 = &v2m_serial1;
+ serial2 = &v2m_serial2;
+ serial3 = &v2m_serial3;
+ i2c0 = &v2m_i2c_dvi;
+ i2c1 = &v2m_i2c_pcie;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <1>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0 0x80000000 0 0x40000000>;
+ };
+
+ hdlcd@2b000000 {
+ compatible = "arm,hdlcd";
+ reg = <0 0x2b000000 0 0x1000>;
+ interrupts = <0 85 4>;
+ clocks = <&oscclk5>;
+ clock-names = "pxlclk";
+ };
+
+ memory-controller@2b0a0000 {
+ compatible = "arm,pl341", "arm,primecell";
+ reg = <0 0x2b0a0000 0 0x1000>;
+ clocks = <&oscclk7>;
+ clock-names = "apb_pclk";
+ };
+
+ wdt@2b060000 {
+ compatible = "arm,sp805", "arm,primecell";
+ status = "disabled";
+ reg = <0 0x2b060000 0 0x1000>;
+ interrupts = <0 98 4>;
+ clocks = <&oscclk7>;
+ clock-names = "apb_pclk";
+ };
+
+ gic: interrupt-controller@2c001000 {
+ compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0 0x2c001000 0 0x1000>,
+ <0 0x2c002000 0 0x1000>,
+ <0 0x2c004000 0 0x2000>,
+ <0 0x2c006000 0 0x2000>;
+ interrupts = <1 9 0xf04>;
+ };
+
+ memory-controller@7ffd0000 {
+ compatible = "arm,pl354", "arm,primecell";
+ reg = <0 0x7ffd0000 0 0x1000>;
+ interrupts = <0 86 4>,
+ <0 87 4>;
+ clocks = <&oscclk7>;
+ clock-names = "apb_pclk";
+ };
+
+ dma@7ffb0000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0 0x7ffb0000 0 0x1000>;
+ interrupts = <0 92 4>,
+ <0 88 4>,
+ <0 89 4>,
+ <0 90 4>,
+ <0 91 4>;
+ clocks = <&oscclk7>;
+ clock-names = "apb_pclk";
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <1 13 0xf08>,
+ <1 14 0xf08>,
+ <1 11 0xf08>,
+ <1 10 0xf08>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a15-pmu";
+ interrupts = <0 68 4>,
+ <0 69 4>;
+ };
+
+ dcc {
+ compatible = "arm,vexpress,config-bus";
+ arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+ osc@0 {
+ /* CPU PLL reference clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 0>;
+ freq-range = <50000000 60000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk0";
+ };
+
+ osc@4 {
+ /* Multiplexed AXI master clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 4>;
+ freq-range = <20000000 40000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk4";
+ };
+
+ oscclk5: osc@5 {
+ /* HDLCD PLL reference clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 5>;
+ freq-range = <23750000 165000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk5";
+ };
+
+ smbclk: osc@6 {
+ /* SMB clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 6>;
+ freq-range = <20000000 50000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk6";
+ };
+
+ oscclk7: osc@7 {
+ /* SYS PLL reference clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 7>;
+ freq-range = <20000000 60000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk7";
+ };
+
+ osc@8 {
+ /* DDR2 PLL reference clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 8>;
+ freq-range = <40000000 40000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk8";
+ };
+
+ volt@0 {
+ /* CPU core voltage */
+ compatible = "arm,vexpress-volt";
+ arm,vexpress-sysreg,func = <2 0>;
+ regulator-name = "Cores";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-always-on;
+ label = "Cores";
+ };
+
+ amp@0 {
+ /* Total current for the two cores */
+ compatible = "arm,vexpress-amp";
+ arm,vexpress-sysreg,func = <3 0>;
+ label = "Cores";
+ };
+
+ temp@0 {
+ /* DCC internal temperature */
+ compatible = "arm,vexpress-temp";
+ arm,vexpress-sysreg,func = <4 0>;
+ label = "DCC";
+ };
+
+ power@0 {
+ /* Total power */
+ compatible = "arm,vexpress-power";
+ arm,vexpress-sysreg,func = <12 0>;
+ label = "Cores";
+ };
+
+ energy@0 {
+ /* Total energy */
+ compatible = "arm,vexpress-energy";
+ arm,vexpress-sysreg,func = <13 0>;
+ label = "Cores";
+ };
+ };
+
+ smb {
+ compatible = "simple-bus";
+
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0 0x08000000 0x04000000>,
+ <1 0 0 0x14000000 0x04000000>,
+ <2 0 0 0x18000000 0x04000000>,
+ <3 0 0 0x1c000000 0x04000000>,
+ <4 0 0 0x0c000000 0x04000000>,
+ <5 0 0 0x10000000 0x04000000>;
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 63>;
+ interrupt-map = <0 0 0 &gic 0 0 4>,
+ <0 0 1 &gic 0 1 4>,
+ <0 0 2 &gic 0 2 4>,
+ <0 0 3 &gic 0 3 4>,
+ <0 0 4 &gic 0 4 4>,
+ <0 0 5 &gic 0 5 4>,
+ <0 0 6 &gic 0 6 4>,
+ <0 0 7 &gic 0 7 4>,
+ <0 0 8 &gic 0 8 4>,
+ <0 0 9 &gic 0 9 4>,
+ <0 0 10 &gic 0 10 4>,
+ <0 0 11 &gic 0 11 4>,
+ <0 0 12 &gic 0 12 4>,
+ <0 0 13 &gic 0 13 4>,
+ <0 0 14 &gic 0 14 4>,
+ <0 0 15 &gic 0 15 4>,
+ <0 0 16 &gic 0 16 4>,
+ <0 0 17 &gic 0 17 4>,
+ <0 0 18 &gic 0 18 4>,
+ <0 0 19 &gic 0 19 4>,
+ <0 0 20 &gic 0 20 4>,
+ <0 0 21 &gic 0 21 4>,
+ <0 0 22 &gic 0 22 4>,
+ <0 0 23 &gic 0 23 4>,
+ <0 0 24 &gic 0 24 4>,
+ <0 0 25 &gic 0 25 4>,
+ <0 0 26 &gic 0 26 4>,
+ <0 0 27 &gic 0 27 4>,
+ <0 0 28 &gic 0 28 4>,
+ <0 0 29 &gic 0 29 4>,
+ <0 0 30 &gic 0 30 4>,
+ <0 0 31 &gic 0 31 4>,
+ <0 0 32 &gic 0 32 4>,
+ <0 0 33 &gic 0 33 4>,
+ <0 0 34 &gic 0 34 4>,
+ <0 0 35 &gic 0 35 4>,
+ <0 0 36 &gic 0 36 4>,
+ <0 0 37 &gic 0 37 4>,
+ <0 0 38 &gic 0 38 4>,
+ <0 0 39 &gic 0 39 4>,
+ <0 0 40 &gic 0 40 4>,
+ <0 0 41 &gic 0 41 4>,
+ <0 0 42 &gic 0 42 4>;
+
+ /include/ "vexpress-v2m-rs1.dtsi"
+ };
+};
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
new file mode 100644
index 000000000..107395c32
--- /dev/null
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
@@ -0,0 +1,620 @@
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * CoreTile Express A15x2 A7x3
+ * Cortex-A15_A7 MPCore (V2P-CA15_A7)
+ *
+ * HBI-0249A
+ */
+
+/dts-v1/;
+
+/ {
+ model = "V2P-CA15_CA7";
+ arm,hbi = <0x249>;
+ arm,vexpress,site = <0xf>;
+ compatible = "arm,vexpress,v2p-ca15_a7", "arm,vexpress";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ chosen { };
+
+ aliases {
+ serial0 = &v2m_serial0;
+ serial1 = &v2m_serial1;
+ serial2 = &v2m_serial2;
+ serial3 = &v2m_serial3;
+ i2c0 = &v2m_i2c_dvi;
+ i2c1 = &v2m_i2c_pcie;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0>;
+ cci-control-port = <&cci_control1>;
+ cpu-idle-states = <&CLUSTER_SLEEP_BIG>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <1>;
+ cci-control-port = <&cci_control1>;
+ cpu-idle-states = <&CLUSTER_SLEEP_BIG>;
+ };
+
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x100>;
+ cci-control-port = <&cci_control2>;
+ cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
+ };
+
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x101>;
+ cci-control-port = <&cci_control2>;
+ cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
+ };
+
+ cpu4: cpu@4 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x102>;
+ cci-control-port = <&cci_control2>;
+ cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
+ };
+
+ idle-states {
+ CLUSTER_SLEEP_BIG: cluster-sleep-big {
+ compatible = "arm,idle-state";
+ local-timer-stop;
+ entry-latency-us = <1000>;
+ exit-latency-us = <700>;
+ min-residency-us = <2000>;
+ };
+
+ CLUSTER_SLEEP_LITTLE: cluster-sleep-little {
+ compatible = "arm,idle-state";
+ local-timer-stop;
+ entry-latency-us = <1000>;
+ exit-latency-us = <500>;
+ min-residency-us = <2500>;
+ };
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0 0x80000000 0 0x40000000>;
+ };
+
+ wdt@2a490000 {
+ compatible = "arm,sp805", "arm,primecell";
+ reg = <0 0x2a490000 0 0x1000>;
+ interrupts = <0 98 4>;
+ clocks = <&oscclk6a>, <&oscclk6a>;
+ clock-names = "wdogclk", "apb_pclk";
+ };
+
+ hdlcd@2b000000 {
+ compatible = "arm,hdlcd";
+ reg = <0 0x2b000000 0 0x1000>;
+ interrupts = <0 85 4>;
+ clocks = <&oscclk5>;
+ clock-names = "pxlclk";
+ };
+
+ memory-controller@2b0a0000 {
+ compatible = "arm,pl341", "arm,primecell";
+ reg = <0 0x2b0a0000 0 0x1000>;
+ clocks = <&oscclk6a>;
+ clock-names = "apb_pclk";
+ };
+
+ gic: interrupt-controller@2c001000 {
+ compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0 0x2c001000 0 0x1000>,
+ <0 0x2c002000 0 0x1000>,
+ <0 0x2c004000 0 0x2000>,
+ <0 0x2c006000 0 0x2000>;
+ interrupts = <1 9 0xf04>;
+ };
+
+ cci@2c090000 {
+ compatible = "arm,cci-400";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0x2c090000 0 0x1000>;
+ ranges = <0x0 0x0 0x2c090000 0x10000>;
+
+ cci_control1: slave-if@4000 {
+ compatible = "arm,cci-400-ctrl-if";
+ interface-type = "ace";
+ reg = <0x4000 0x1000>;
+ };
+
+ cci_control2: slave-if@5000 {
+ compatible = "arm,cci-400-ctrl-if";
+ interface-type = "ace";
+ reg = <0x5000 0x1000>;
+ };
+ };
+
+ memory-controller@7ffd0000 {
+ compatible = "arm,pl354", "arm,primecell";
+ reg = <0 0x7ffd0000 0 0x1000>;
+ interrupts = <0 86 4>,
+ <0 87 4>;
+ clocks = <&oscclk6a>;
+ clock-names = "apb_pclk";
+ };
+
+ dma@7ff00000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0 0x7ff00000 0 0x1000>;
+ interrupts = <0 92 4>,
+ <0 88 4>,
+ <0 89 4>,
+ <0 90 4>,
+ <0 91 4>;
+ clocks = <&oscclk6a>;
+ clock-names = "apb_pclk";
+ };
+
+ scc@7fff0000 {
+ compatible = "arm,vexpress-scc,v2p-ca15_a7", "arm,vexpress-scc";
+ reg = <0 0x7fff0000 0 0x1000>;
+ interrupts = <0 95 4>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <1 13 0xf08>,
+ <1 14 0xf08>,
+ <1 11 0xf08>,
+ <1 10 0xf08>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a15-pmu";
+ interrupts = <0 68 4>,
+ <0 69 4>;
+ interrupt-affinity = <&cpu0>, <&cpu1>;
+ };
+
+ oscclk6a: oscclk6a {
+ /* Reference 24MHz clock */
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "oscclk6a";
+ };
+
+ dcc {
+ compatible = "arm,vexpress,config-bus";
+ arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+ osc@0 {
+ /* A15 PLL 0 reference clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 0>;
+ freq-range = <17000000 50000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk0";
+ };
+
+ osc@1 {
+ /* A15 PLL 1 reference clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 1>;
+ freq-range = <17000000 50000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk1";
+ };
+
+ osc@2 {
+ /* A7 PLL 0 reference clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 2>;
+ freq-range = <17000000 50000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk2";
+ };
+
+ osc@3 {
+ /* A7 PLL 1 reference clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 3>;
+ freq-range = <17000000 50000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk3";
+ };
+
+ osc@4 {
+ /* External AXI master clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 4>;
+ freq-range = <20000000 40000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk4";
+ };
+
+ oscclk5: osc@5 {
+ /* HDLCD PLL reference clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 5>;
+ freq-range = <23750000 165000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk5";
+ };
+
+ smbclk: osc@6 {
+ /* Static memory controller clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 6>;
+ freq-range = <20000000 40000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk6";
+ };
+
+ osc@7 {
+ /* SYS PLL reference clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 7>;
+ freq-range = <17000000 50000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk7";
+ };
+
+ osc@8 {
+ /* DDR2 PLL reference clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 8>;
+ freq-range = <20000000 50000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk8";
+ };
+
+ volt@0 {
+ /* A15 CPU core voltage */
+ compatible = "arm,vexpress-volt";
+ arm,vexpress-sysreg,func = <2 0>;
+ regulator-name = "A15 Vcore";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-always-on;
+ label = "A15 Vcore";
+ };
+
+ volt@1 {
+ /* A7 CPU core voltage */
+ compatible = "arm,vexpress-volt";
+ arm,vexpress-sysreg,func = <2 1>;
+ regulator-name = "A7 Vcore";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-always-on;
+ label = "A7 Vcore";
+ };
+
+ amp@0 {
+ /* Total current for the two A15 cores */
+ compatible = "arm,vexpress-amp";
+ arm,vexpress-sysreg,func = <3 0>;
+ label = "A15 Icore";
+ };
+
+ amp@1 {
+ /* Total current for the three A7 cores */
+ compatible = "arm,vexpress-amp";
+ arm,vexpress-sysreg,func = <3 1>;
+ label = "A7 Icore";
+ };
+
+ temp@0 {
+ /* DCC internal temperature */
+ compatible = "arm,vexpress-temp";
+ arm,vexpress-sysreg,func = <4 0>;
+ label = "DCC";
+ };
+
+ power@0 {
+ /* Total power for the two A15 cores */
+ compatible = "arm,vexpress-power";
+ arm,vexpress-sysreg,func = <12 0>;
+ label = "A15 Pcore";
+ };
+
+ power@1 {
+ /* Total power for the three A7 cores */
+ compatible = "arm,vexpress-power";
+ arm,vexpress-sysreg,func = <12 1>;
+ label = "A7 Pcore";
+ };
+
+ energy@0 {
+ /* Total energy for the two A15 cores */
+ compatible = "arm,vexpress-energy";
+ arm,vexpress-sysreg,func = <13 0>, <13 1>;
+ label = "A15 Jcore";
+ };
+
+ energy@2 {
+ /* Total energy for the three A7 cores */
+ compatible = "arm,vexpress-energy";
+ arm,vexpress-sysreg,func = <13 2>, <13 3>;
+ label = "A7 Jcore";
+ };
+ };
+
+ etb@0,20010000 {
+ compatible = "arm,coresight-etb10", "arm,primecell";
+ reg = <0 0x20010000 0 0x1000>;
+
+ clocks = <&oscclk6a>;
+ clock-names = "apb_pclk";
+ port {
+ etb_in_port: endpoint@0 {
+ slave-mode;
+ remote-endpoint = <&replicator_out_port0>;
+ };
+ };
+ };
+
+ tpiu@0,20030000 {
+ compatible = "arm,coresight-tpiu", "arm,primecell";
+ reg = <0 0x20030000 0 0x1000>;
+
+ clocks = <&oscclk6a>;
+ clock-names = "apb_pclk";
+ port {
+ tpiu_in_port: endpoint@0 {
+ slave-mode;
+ remote-endpoint = <&replicator_out_port1>;
+ };
+ };
+ };
+
+ replicator {
+ /* non-configurable replicators don't show up on the
+ * AMBA bus. As such no need to add "arm,primecell".
+ */
+ compatible = "arm,coresight-replicator";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* replicator output ports */
+ port@0 {
+ reg = <0>;
+ replicator_out_port0: endpoint {
+ remote-endpoint = <&etb_in_port>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ replicator_out_port1: endpoint {
+ remote-endpoint = <&tpiu_in_port>;
+ };
+ };
+
+ /* replicator input port */
+ port@2 {
+ reg = <0>;
+ replicator_in_port0: endpoint {
+ slave-mode;
+ remote-endpoint = <&funnel_out_port0>;
+ };
+ };
+ };
+ };
+
+ funnel@0,20040000 {
+ compatible = "arm,coresight-funnel", "arm,primecell";
+ reg = <0 0x20040000 0 0x1000>;
+
+ clocks = <&oscclk6a>;
+ clock-names = "apb_pclk";
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* funnel output port */
+ port@0 {
+ reg = <0>;
+ funnel_out_port0: endpoint {
+ remote-endpoint =
+ <&replicator_in_port0>;
+ };
+ };
+
+ /* funnel input ports */
+ port@1 {
+ reg = <0>;
+ funnel_in_port0: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm0_out_port>;
+ };
+ };
+
+ port@2 {
+ reg = <1>;
+ funnel_in_port1: endpoint {
+ slave-mode;
+ remote-endpoint = <&ptm1_out_port>;
+ };
+ };
+
+ port@3 {
+ reg = <2>;
+ funnel_in_port2: endpoint {
+ slave-mode;
+ remote-endpoint = <&etm0_out_port>;
+ };
+ };
+
+ /* Input port #3 is for ITM, not supported here */
+
+ port@4 {
+ reg = <4>;
+ funnel_in_port4: endpoint {
+ slave-mode;
+ remote-endpoint = <&etm1_out_port>;
+ };
+ };
+
+ port@5 {
+ reg = <5>;
+ funnel_in_port5: endpoint {
+ slave-mode;
+ remote-endpoint = <&etm2_out_port>;
+ };
+ };
+ };
+ };
+
+ ptm@0,2201c000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0x2201c000 0 0x1000>;
+
+ cpu = <&cpu0>;
+ clocks = <&oscclk6a>;
+ clock-names = "apb_pclk";
+ port {
+ ptm0_out_port: endpoint {
+ remote-endpoint = <&funnel_in_port0>;
+ };
+ };
+ };
+
+ ptm@0,2201d000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0x2201d000 0 0x1000>;
+
+ cpu = <&cpu1>;
+ clocks = <&oscclk6a>;
+ clock-names = "apb_pclk";
+ port {
+ ptm1_out_port: endpoint {
+ remote-endpoint = <&funnel_in_port1>;
+ };
+ };
+ };
+
+ etm@0,2203c000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0x2203c000 0 0x1000>;
+
+ cpu = <&cpu2>;
+ clocks = <&oscclk6a>;
+ clock-names = "apb_pclk";
+ port {
+ etm0_out_port: endpoint {
+ remote-endpoint = <&funnel_in_port2>;
+ };
+ };
+ };
+
+ etm@0,2203d000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0x2203d000 0 0x1000>;
+
+ cpu = <&cpu3>;
+ clocks = <&oscclk6a>;
+ clock-names = "apb_pclk";
+ port {
+ etm1_out_port: endpoint {
+ remote-endpoint = <&funnel_in_port4>;
+ };
+ };
+ };
+
+ etm@0,2203e000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0 0x2203e000 0 0x1000>;
+
+ cpu = <&cpu4>;
+ clocks = <&oscclk6a>;
+ clock-names = "apb_pclk";
+ port {
+ etm2_out_port: endpoint {
+ remote-endpoint = <&funnel_in_port5>;
+ };
+ };
+ };
+
+ smb {
+ compatible = "simple-bus";
+
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0 0x08000000 0x04000000>,
+ <1 0 0 0x14000000 0x04000000>,
+ <2 0 0 0x18000000 0x04000000>,
+ <3 0 0 0x1c000000 0x04000000>,
+ <4 0 0 0x0c000000 0x04000000>,
+ <5 0 0 0x10000000 0x04000000>;
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 63>;
+ interrupt-map = <0 0 0 &gic 0 0 4>,
+ <0 0 1 &gic 0 1 4>,
+ <0 0 2 &gic 0 2 4>,
+ <0 0 3 &gic 0 3 4>,
+ <0 0 4 &gic 0 4 4>,
+ <0 0 5 &gic 0 5 4>,
+ <0 0 6 &gic 0 6 4>,
+ <0 0 7 &gic 0 7 4>,
+ <0 0 8 &gic 0 8 4>,
+ <0 0 9 &gic 0 9 4>,
+ <0 0 10 &gic 0 10 4>,
+ <0 0 11 &gic 0 11 4>,
+ <0 0 12 &gic 0 12 4>,
+ <0 0 13 &gic 0 13 4>,
+ <0 0 14 &gic 0 14 4>,
+ <0 0 15 &gic 0 15 4>,
+ <0 0 16 &gic 0 16 4>,
+ <0 0 17 &gic 0 17 4>,
+ <0 0 18 &gic 0 18 4>,
+ <0 0 19 &gic 0 19 4>,
+ <0 0 20 &gic 0 20 4>,
+ <0 0 21 &gic 0 21 4>,
+ <0 0 22 &gic 0 22 4>,
+ <0 0 23 &gic 0 23 4>,
+ <0 0 24 &gic 0 24 4>,
+ <0 0 25 &gic 0 25 4>,
+ <0 0 26 &gic 0 26 4>,
+ <0 0 27 &gic 0 27 4>,
+ <0 0 28 &gic 0 28 4>,
+ <0 0 29 &gic 0 29 4>,
+ <0 0 30 &gic 0 30 4>,
+ <0 0 31 &gic 0 31 4>,
+ <0 0 32 &gic 0 32 4>,
+ <0 0 33 &gic 0 33 4>,
+ <0 0 34 &gic 0 34 4>,
+ <0 0 35 &gic 0 35 4>,
+ <0 0 36 &gic 0 36 4>,
+ <0 0 37 &gic 0 37 4>,
+ <0 0 38 &gic 0 38 4>,
+ <0 0 39 &gic 0 39 4>,
+ <0 0 40 &gic 0 40 4>,
+ <0 0 41 &gic 0 41 4>,
+ <0 0 42 &gic 0 42 4>;
+
+ /include/ "vexpress-v2m-rs1.dtsi"
+ };
+};
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
new file mode 100644
index 000000000..d2709b733
--- /dev/null
+++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
@@ -0,0 +1,253 @@
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * CoreTile Express A5x2
+ * Cortex-A5 MPCore (V2P-CA5s)
+ *
+ * HBI-0225B
+ */
+
+/dts-v1/;
+
+/ {
+ model = "V2P-CA5s";
+ arm,hbi = <0x225>;
+ arm,vexpress,site = <0xf>;
+ compatible = "arm,vexpress,v2p-ca5s", "arm,vexpress";
+ interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ chosen { };
+
+ aliases {
+ serial0 = &v2m_serial0;
+ serial1 = &v2m_serial1;
+ serial2 = &v2m_serial2;
+ serial3 = &v2m_serial3;
+ i2c0 = &v2m_i2c_dvi;
+ i2c1 = &v2m_i2c_pcie;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a5";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a5";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>;
+ };
+
+ hdlcd@2a110000 {
+ compatible = "arm,hdlcd";
+ reg = <0x2a110000 0x1000>;
+ interrupts = <0 85 4>;
+ clocks = <&oscclk3>;
+ clock-names = "pxlclk";
+ };
+
+ memory-controller@2a150000 {
+ compatible = "arm,pl341", "arm,primecell";
+ reg = <0x2a150000 0x1000>;
+ clocks = <&oscclk1>;
+ clock-names = "apb_pclk";
+ };
+
+ memory-controller@2a190000 {
+ compatible = "arm,pl354", "arm,primecell";
+ reg = <0x2a190000 0x1000>;
+ interrupts = <0 86 4>,
+ <0 87 4>;
+ clocks = <&oscclk1>;
+ clock-names = "apb_pclk";
+ };
+
+ scu@2c000000 {
+ compatible = "arm,cortex-a5-scu";
+ reg = <0x2c000000 0x58>;
+ };
+
+ timer@2c000600 {
+ compatible = "arm,cortex-a5-twd-timer";
+ reg = <0x2c000600 0x20>;
+ interrupts = <1 13 0x304>;
+ };
+
+ timer@2c000200 {
+ compatible = "arm,cortex-a5-global-timer",
+ "arm,cortex-a9-global-timer";
+ reg = <0x2c000200 0x20>;
+ interrupts = <1 11 0x304>;
+ clocks = <&oscclk0>;
+ };
+
+ watchdog@2c000620 {
+ compatible = "arm,cortex-a5-twd-wdt";
+ reg = <0x2c000620 0x20>;
+ interrupts = <1 14 0x304>;
+ };
+
+ gic: interrupt-controller@2c001000 {
+ compatible = "arm,cortex-a5-gic", "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x2c001000 0x1000>,
+ <0x2c000100 0x100>;
+ };
+
+ L2: cache-controller@2c0f0000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x2c0f0000 0x1000>;
+ interrupts = <0 84 4>;
+ cache-level = <2>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a5-pmu";
+ interrupts = <0 68 4>,
+ <0 69 4>;
+ };
+
+ dcc {
+ compatible = "arm,vexpress,config-bus";
+ arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+ oscclk0: osc@0 {
+ /* CPU and internal AXI reference clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 0>;
+ freq-range = <50000000 100000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk0";
+ };
+
+ oscclk1: osc@1 {
+ /* Multiplexed AXI master clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 1>;
+ freq-range = <5000000 50000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk1";
+ };
+
+ osc@2 {
+ /* DDR2 */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 2>;
+ freq-range = <80000000 120000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk2";
+ };
+
+ oscclk3: osc@3 {
+ /* HDLCD */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 3>;
+ freq-range = <23750000 165000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk3";
+ };
+
+ osc@4 {
+ /* Test chip gate configuration */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 4>;
+ freq-range = <80000000 80000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk4";
+ };
+
+ smbclk: osc@5 {
+ /* SMB clock */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 5>;
+ freq-range = <25000000 60000000>;
+ #clock-cells = <0>;
+ clock-output-names = "oscclk5";
+ };
+
+ temp@0 {
+ /* DCC internal operating temperature */
+ compatible = "arm,vexpress-temp";
+ arm,vexpress-sysreg,func = <4 0>;
+ label = "DCC";
+ };
+ };
+
+ smb {
+ compatible = "simple-bus";
+
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0x08000000 0x04000000>,
+ <1 0 0x14000000 0x04000000>,
+ <2 0 0x18000000 0x04000000>,
+ <3 0 0x1c000000 0x04000000>,
+ <4 0 0x0c000000 0x04000000>,
+ <5 0 0x10000000 0x04000000>;
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 63>;
+ interrupt-map = <0 0 0 &gic 0 0 4>,
+ <0 0 1 &gic 0 1 4>,
+ <0 0 2 &gic 0 2 4>,
+ <0 0 3 &gic 0 3 4>,
+ <0 0 4 &gic 0 4 4>,
+ <0 0 5 &gic 0 5 4>,
+ <0 0 6 &gic 0 6 4>,
+ <0 0 7 &gic 0 7 4>,
+ <0 0 8 &gic 0 8 4>,
+ <0 0 9 &gic 0 9 4>,
+ <0 0 10 &gic 0 10 4>,
+ <0 0 11 &gic 0 11 4>,
+ <0 0 12 &gic 0 12 4>,
+ <0 0 13 &gic 0 13 4>,
+ <0 0 14 &gic 0 14 4>,
+ <0 0 15 &gic 0 15 4>,
+ <0 0 16 &gic 0 16 4>,
+ <0 0 17 &gic 0 17 4>,
+ <0 0 18 &gic 0 18 4>,
+ <0 0 19 &gic 0 19 4>,
+ <0 0 20 &gic 0 20 4>,
+ <0 0 21 &gic 0 21 4>,
+ <0 0 22 &gic 0 22 4>,
+ <0 0 23 &gic 0 23 4>,
+ <0 0 24 &gic 0 24 4>,
+ <0 0 25 &gic 0 25 4>,
+ <0 0 26 &gic 0 26 4>,
+ <0 0 27 &gic 0 27 4>,
+ <0 0 28 &gic 0 28 4>,
+ <0 0 29 &gic 0 29 4>,
+ <0 0 30 &gic 0 30 4>,
+ <0 0 31 &gic 0 31 4>,
+ <0 0 32 &gic 0 32 4>,
+ <0 0 33 &gic 0 33 4>,
+ <0 0 34 &gic 0 34 4>,
+ <0 0 35 &gic 0 35 4>,
+ <0 0 36 &gic 0 36 4>,
+ <0 0 37 &gic 0 37 4>,
+ <0 0 38 &gic 0 38 4>,
+ <0 0 39 &gic 0 39 4>,
+ <0 0 40 &gic 0 40 4>,
+ <0 0 41 &gic 0 41 4>,
+ <0 0 42 &gic 0 42 4>;
+
+ /include/ "vexpress-v2m-rs1.dtsi"
+ };
+};
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
new file mode 100644
index 000000000..d949facba
--- /dev/null
+++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
@@ -0,0 +1,362 @@
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * CoreTile Express A9x4
+ * Cortex-A9 MPCore (V2P-CA9)
+ *
+ * HBI-0191B
+ */
+
+/dts-v1/;
+
+/ {
+ model = "V2P-CA9";
+ arm,hbi = <0x191>;
+ arm,vexpress,site = <0xf>;
+ compatible = "arm,vexpress,v2p-ca9", "arm,vexpress";
+ interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ chosen { };
+
+ aliases {
+ serial0 = &v2m_serial0;
+ serial1 = &v2m_serial1;
+ serial2 = &v2m_serial2;
+ serial3 = &v2m_serial3;
+ i2c0 = &v2m_i2c_dvi;
+ i2c1 = &v2m_i2c_pcie;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ A9_0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ };
+
+ A9_1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ };
+
+ A9_2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <2>;
+ next-level-cache = <&L2>;
+ };
+
+ A9_3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <3>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory@60000000 {
+ device_type = "memory";
+ reg = <0x60000000 0x40000000>;
+ };
+
+ clcd@10020000 {
+ compatible = "arm,pl111", "arm,primecell";
+ reg = <0x10020000 0x1000>;
+ interrupt-names = "combined";
+ interrupts = <0 44 4>;
+ clocks = <&oscclk1>, <&oscclk2>;
+ clock-names = "clcdclk", "apb_pclk";
+ max-memory-bandwidth = <130000000>; /* 16bpp @ 63.5MHz */
+
+ port {
+ clcd_pads: endpoint {
+ remote-endpoint = <&clcd_panel>;
+ arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+ };
+ };
+
+ panel {
+ compatible = "panel-dpi";
+
+ port {
+ clcd_panel: endpoint {
+ remote-endpoint = <&clcd_pads>;
+ };
+ };
+
+ panel-timing {
+ clock-frequency = <63500127>;
+ hactive = <1024>;
+ hback-porch = <152>;
+ hfront-porch = <48>;
+ hsync-len = <104>;
+ vactive = <768>;
+ vback-porch = <23>;
+ vfront-porch = <3>;
+ vsync-len = <4>;
+ };
+ };
+ };
+
+ memory-controller@100e0000 {
+ compatible = "arm,pl341", "arm,primecell";
+ reg = <0x100e0000 0x1000>;
+ clocks = <&oscclk2>;
+ clock-names = "apb_pclk";
+ };
+
+ memory-controller@100e1000 {
+ compatible = "arm,pl354", "arm,primecell";
+ reg = <0x100e1000 0x1000>;
+ interrupts = <0 45 4>,
+ <0 46 4>;
+ clocks = <&oscclk2>;
+ clock-names = "apb_pclk";
+ };
+
+ timer@100e4000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x100e4000 0x1000>;
+ interrupts = <0 48 4>,
+ <0 49 4>;
+ clocks = <&oscclk2>, <&oscclk2>;
+ clock-names = "timclk", "apb_pclk";
+ status = "disabled";
+ };
+
+ watchdog@100e5000 {
+ compatible = "arm,sp805", "arm,primecell";
+ reg = <0x100e5000 0x1000>;
+ interrupts = <0 51 4>;
+ clocks = <&oscclk2>, <&oscclk2>;
+ clock-names = "wdogclk", "apb_pclk";
+ };
+
+ scu@1e000000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0x1e000000 0x58>;
+ };
+
+ timer@1e000600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x1e000600 0x20>;
+ interrupts = <1 13 0xf04>;
+ };
+
+ watchdog@1e000620 {
+ compatible = "arm,cortex-a9-twd-wdt";
+ reg = <0x1e000620 0x20>;
+ interrupts = <1 14 0xf04>;
+ };
+
+ gic: interrupt-controller@1e001000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x1e001000 0x1000>,
+ <0x1e000100 0x100>;
+ };
+
+ L2: cache-controller@1e00a000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x1e00a000 0x1000>;
+ interrupts = <0 43 4>;
+ cache-unified;
+ cache-level = <2>;
+ arm,data-latency = <1 1 1>;
+ arm,tag-latency = <1 1 1>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 60 4>,
+ <0 61 4>,
+ <0 62 4>,
+ <0 63 4>;
+ interrupt-affinity = <&A9_0>, <&A9_1>, <&A9_2>, <&A9_3>;
+
+ };
+
+ dcc {
+ compatible = "arm,vexpress,config-bus";
+ arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+ osc@0 {
+ /* ACLK clock to the AXI master port on the test chip */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 0>;
+ freq-range = <30000000 50000000>;
+ #clock-cells = <0>;
+ clock-output-names = "extsaxiclk";
+ };
+
+ oscclk1: osc@1 {
+ /* Reference clock for the CLCD */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 1>;
+ freq-range = <10000000 80000000>;
+ #clock-cells = <0>;
+ clock-output-names = "clcdclk";
+ };
+
+ smbclk: oscclk2: osc@2 {
+ /* Reference clock for the test chip internal PLLs */
+ compatible = "arm,vexpress-osc";
+ arm,vexpress-sysreg,func = <1 2>;
+ freq-range = <33000000 100000000>;
+ #clock-cells = <0>;
+ clock-output-names = "tcrefclk";
+ };
+
+ volt@0 {
+ /* Test Chip internal logic voltage */
+ compatible = "arm,vexpress-volt";
+ arm,vexpress-sysreg,func = <2 0>;
+ regulator-name = "VD10";
+ regulator-always-on;
+ label = "VD10";
+ };
+
+ volt@1 {
+ /* PL310, L2 cache, RAM cell supply (not PL310 logic) */
+ compatible = "arm,vexpress-volt";
+ arm,vexpress-sysreg,func = <2 1>;
+ regulator-name = "VD10_S2";
+ regulator-always-on;
+ label = "VD10_S2";
+ };
+
+ volt@2 {
+ /* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */
+ compatible = "arm,vexpress-volt";
+ arm,vexpress-sysreg,func = <2 2>;
+ regulator-name = "VD10_S3";
+ regulator-always-on;
+ label = "VD10_S3";
+ };
+
+ volt@3 {
+ /* DDR2 SDRAM and Test Chip DDR2 I/O supply */
+ compatible = "arm,vexpress-volt";
+ arm,vexpress-sysreg,func = <2 3>;
+ regulator-name = "VCC1V8";
+ regulator-always-on;
+ label = "VCC1V8";
+ };
+
+ volt@4 {
+ /* DDR2 SDRAM VTT termination voltage */
+ compatible = "arm,vexpress-volt";
+ arm,vexpress-sysreg,func = <2 4>;
+ regulator-name = "DDR2VTT";
+ regulator-always-on;
+ label = "DDR2VTT";
+ };
+
+ volt@5 {
+ /* Local board supply for miscellaneous logic external to the Test Chip */
+ arm,vexpress-sysreg,func = <2 5>;
+ compatible = "arm,vexpress-volt";
+ regulator-name = "VCC3V3";
+ regulator-always-on;
+ label = "VCC3V3";
+ };
+
+ amp@0 {
+ /* PL310, L2 cache, RAM cell supply (not PL310 logic) */
+ compatible = "arm,vexpress-amp";
+ arm,vexpress-sysreg,func = <3 0>;
+ label = "VD10_S2";
+ };
+
+ amp@1 {
+ /* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */
+ compatible = "arm,vexpress-amp";
+ arm,vexpress-sysreg,func = <3 1>;
+ label = "VD10_S3";
+ };
+
+ power@0 {
+ /* PL310, L2 cache, RAM cell supply (not PL310 logic) */
+ compatible = "arm,vexpress-power";
+ arm,vexpress-sysreg,func = <12 0>;
+ label = "PVD10_S2";
+ };
+
+ power@1 {
+ /* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */
+ compatible = "arm,vexpress-power";
+ arm,vexpress-sysreg,func = <12 1>;
+ label = "PVD10_S3";
+ };
+ };
+
+ smb {
+ compatible = "simple-bus";
+
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0x40000000 0x04000000>,
+ <1 0 0x44000000 0x04000000>,
+ <2 0 0x48000000 0x04000000>,
+ <3 0 0x4c000000 0x04000000>,
+ <7 0 0x10000000 0x00020000>;
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 63>;
+ interrupt-map = <0 0 0 &gic 0 0 4>,
+ <0 0 1 &gic 0 1 4>,
+ <0 0 2 &gic 0 2 4>,
+ <0 0 3 &gic 0 3 4>,
+ <0 0 4 &gic 0 4 4>,
+ <0 0 5 &gic 0 5 4>,
+ <0 0 6 &gic 0 6 4>,
+ <0 0 7 &gic 0 7 4>,
+ <0 0 8 &gic 0 8 4>,
+ <0 0 9 &gic 0 9 4>,
+ <0 0 10 &gic 0 10 4>,
+ <0 0 11 &gic 0 11 4>,
+ <0 0 12 &gic 0 12 4>,
+ <0 0 13 &gic 0 13 4>,
+ <0 0 14 &gic 0 14 4>,
+ <0 0 15 &gic 0 15 4>,
+ <0 0 16 &gic 0 16 4>,
+ <0 0 17 &gic 0 17 4>,
+ <0 0 18 &gic 0 18 4>,
+ <0 0 19 &gic 0 19 4>,
+ <0 0 20 &gic 0 20 4>,
+ <0 0 21 &gic 0 21 4>,
+ <0 0 22 &gic 0 22 4>,
+ <0 0 23 &gic 0 23 4>,
+ <0 0 24 &gic 0 24 4>,
+ <0 0 25 &gic 0 25 4>,
+ <0 0 26 &gic 0 26 4>,
+ <0 0 27 &gic 0 27 4>,
+ <0 0 28 &gic 0 28 4>,
+ <0 0 29 &gic 0 29 4>,
+ <0 0 30 &gic 0 30 4>,
+ <0 0 31 &gic 0 31 4>,
+ <0 0 32 &gic 0 32 4>,
+ <0 0 33 &gic 0 33 4>,
+ <0 0 34 &gic 0 34 4>,
+ <0 0 35 &gic 0 35 4>,
+ <0 0 36 &gic 0 36 4>,
+ <0 0 37 &gic 0 37 4>,
+ <0 0 38 &gic 0 38 4>,
+ <0 0 39 &gic 0 39 4>,
+ <0 0 40 &gic 0 40 4>,
+ <0 0 41 &gic 0 41 4>,
+ <0 0 42 &gic 0 42 4>;
+
+ /include/ "vexpress-v2m.dtsi"
+ };
+};
diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
new file mode 100644
index 000000000..606753eb7
--- /dev/null
+++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2014 Toradex AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/ {
+ chosen {
+ bootargs = "console=ttyLP0,115200";
+ };
+
+ clk16m: clk16m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <16000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sys_5v0_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ /* USBH_PEN */
+ usbh_vbus_reg: regulator@1 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1_reg>;
+ reg = <1>;
+ regulator-name = "usbh_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio2 19 GPIO_ACTIVE_LOW>;
+ vin-supply = <&sys_5v0_reg>;
+ };
+ };
+};
+
+&bl {
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ status = "okay";
+};
+
+&dspi1 {
+ status = "okay";
+
+ mcp2515can: can@0 {
+ compatible = "microchip,mcp2515";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can_int>;
+ reg = <0>;
+ clocks = <&clk16m>;
+ spi-max-frequency = <10000000>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <11 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&fec1 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc: m41t0m6@68 {
+ compatible = "st,m41t00";
+ reg = <0x68>;
+ };
+};
+
+&pwm0 {
+ status = "okay";
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&usbh_vbus_reg>;
+};
+
+&iomuxc {
+ vf610-colibri {
+ pinctrl_can_int: can_int {
+ fsl,pins = <
+ VF610_PAD_PTB21__GPIO_43 0x22ed
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi
new file mode 100644
index 000000000..fbef0828e
--- /dev/null
+++ b/arch/arm/boot/dts/vf-colibri.dtsi
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2014 Toradex AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/ {
+ bl: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm0 0 5000000 0>;
+ status = "disabled";
+ };
+};
+
+&adc0 {
+ status = "okay";
+};
+
+&adc1 {
+ status = "okay";
+};
+
+&dspi1 {
+ bus-num = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dspi1>;
+};
+
+&edma0 {
+ status = "okay";
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ bus-width = <4>;
+ cd-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+};
+
+&fec1 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+};
+
+&pwm0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm0>;
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+};
+
+&usbdev0 {
+ disable-over-current;
+ status = "okay";
+};
+
+&usbh1 {
+ disable-over-current;
+ status = "okay";
+};
+
+&usbmisc0 {
+ status = "okay";
+};
+
+&usbmisc1 {
+ status = "okay";
+};
+
+&usbphy0 {
+ status = "okay";
+};
+
+&usbphy1 {
+ status = "okay";
+};
+
+&iomuxc {
+ vf610-colibri {
+ pinctrl_gpio_ext: gpio_ext {
+ fsl,pins = <
+ VF610_PAD_PTD10__GPIO_89 0x22ed /* EXT_IO_0 */
+ VF610_PAD_PTD9__GPIO_88 0x22ed /* EXT_IO_1 */
+ VF610_PAD_PTD26__GPIO_68 0x22ed /* EXT_IO_2 */
+ >;
+ };
+
+ pinctrl_dspi1: dspi1grp {
+ fsl,pins = <
+ VF610_PAD_PTD5__DSPI1_CS0 0x33e2
+ VF610_PAD_PTD6__DSPI1_SIN 0x33e1
+ VF610_PAD_PTD7__DSPI1_SOUT 0x33e2
+ VF610_PAD_PTD8__DSPI1_SCK 0x33e2
+ >;
+ };
+
+ pinctrl_esdhc1: esdhc1grp {
+ fsl,pins = <
+ VF610_PAD_PTA24__ESDHC1_CLK 0x31ef
+ VF610_PAD_PTA25__ESDHC1_CMD 0x31ef
+ VF610_PAD_PTA26__ESDHC1_DAT0 0x31ef
+ VF610_PAD_PTA27__ESDHC1_DAT1 0x31ef
+ VF610_PAD_PTA28__ESDHC1_DATA2 0x31ef
+ VF610_PAD_PTA29__ESDHC1_DAT3 0x31ef
+ VF610_PAD_PTB20__GPIO_42 0x219d
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ VF610_PAD_PTA6__RMII_CLKOUT 0x30d2
+ VF610_PAD_PTC9__ENET_RMII1_MDC 0x30d2
+ VF610_PAD_PTC10__ENET_RMII1_MDIO 0x30d3
+ VF610_PAD_PTC11__ENET_RMII1_CRS 0x30d1
+ VF610_PAD_PTC12__ENET_RMII_RXD1 0x30d1
+ VF610_PAD_PTC13__ENET_RMII1_RXD0 0x30d1
+ VF610_PAD_PTC14__ENET_RMII1_RXER 0x30d1
+ VF610_PAD_PTC15__ENET_RMII1_TXD1 0x30d2
+ VF610_PAD_PTC16__ENET_RMII1_TXD0 0x30d2
+ VF610_PAD_PTC17__ENET_RMII1_TXEN 0x30d2
+ >;
+ };
+
+ pinctrl_i2c0: i2c0grp {
+ fsl,pins = <
+ VF610_PAD_PTB14__I2C0_SCL 0x37ff
+ VF610_PAD_PTB15__I2C0_SDA 0x37ff
+ >;
+ };
+
+ pinctrl_pwm0: pwm0grp {
+ fsl,pins = <
+ VF610_PAD_PTB0__FTM0_CH0 0x1182
+ VF610_PAD_PTB1__FTM0_CH1 0x1182
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ VF610_PAD_PTB8__FTM1_CH0 0x1182
+ VF610_PAD_PTB9__FTM1_CH1 0x1182
+ >;
+ };
+
+ pinctrl_uart0: uart0grp {
+ fsl,pins = <
+ VF610_PAD_PTB10__UART0_TX 0x21a2
+ VF610_PAD_PTB11__UART0_RX 0x21a1
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ VF610_PAD_PTB4__UART1_TX 0x21a2
+ VF610_PAD_PTB5__UART1_RX 0x21a1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ VF610_PAD_PTD0__UART2_TX 0x21a2
+ VF610_PAD_PTD1__UART2_RX 0x21a1
+ VF610_PAD_PTD2__UART2_RTS 0x21a2
+ VF610_PAD_PTD3__UART2_CTS 0x21a1
+ >;
+ };
+
+ pinctrl_usbh1_reg: gpio_usb_vbus {
+ fsl,pins = <
+ VF610_PAD_PTD4__GPIO_83 0x22ed
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/vf500-colibri-eval-v3.dts b/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
new file mode 100644
index 000000000..7fc782c4f
--- /dev/null
+++ b/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2014 Toradex AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/dts-v1/;
+#include "vf500-colibri.dtsi"
+#include "vf-colibri-eval-v3.dtsi"
+
+/ {
+ model = "Toradex Colibri VF50 on Colibri Evaluation Board";
+ compatible = "toradex,vf500-colibri_vf50-on-eval", "toradex,vf500-colibri_vf50", "fsl,vf500";
+};
diff --git a/arch/arm/boot/dts/vf500-colibri.dtsi b/arch/arm/boot/dts/vf500-colibri.dtsi
new file mode 100644
index 000000000..cee34a32f
--- /dev/null
+++ b/arch/arm/boot/dts/vf500-colibri.dtsi
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2014 Toradex AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 "vf500.dtsi"
+#include "vf-colibri.dtsi"
+
+/ {
+ model = "Toradex Colibri VF50 COM";
+ compatible = "toradex,vf610-colibri_vf50", "fsl,vf500";
+
+ memory {
+ reg = <0x80000000 0x8000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/vf500.dtsi b/arch/arm/boot/dts/vf500.dtsi
new file mode 100644
index 000000000..e976d2fa1
--- /dev/null
+++ b/arch/arm/boot/dts/vf500.dtsi
@@ -0,0 +1,55 @@
+/*
+ * Copyright 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.
+ */
+
+#include "skeleton.dtsi"
+#include "vfxxx.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ a5_cpu: cpu@0 {
+ compatible = "arm,cortex-a5";
+ device_type = "cpu";
+ reg = <0x0>;
+ };
+ };
+
+ soc {
+ aips-bus@40000000 {
+
+ intc: interrupt-controller@40002000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ interrupt-parent = <&intc>;
+ reg = <0x40003000 0x1000>,
+ <0x40002100 0x100>;
+ };
+
+ global_timer: timer@40002200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x40002200 0x20>;
+ interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&intc>;
+ clocks = <&clks VF610_CLK_PLATFORM_BUS>;
+ };
+ };
+ };
+};
+
+&mscm_ir {
+ interrupt-parent = <&intc>;
+};
+
+&wdoga5 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/vf610-colibri-eval-v3.dts b/arch/arm/boot/dts/vf610-colibri-eval-v3.dts
new file mode 100644
index 000000000..10ebe99e2
--- /dev/null
+++ b/arch/arm/boot/dts/vf610-colibri-eval-v3.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2014 Toradex AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/dts-v1/;
+#include "vf610-colibri.dtsi"
+#include "vf-colibri-eval-v3.dtsi"
+
+/ {
+ model = "Toradex Colibri VF61 on Colibri Evaluation Board";
+ compatible = "toradex,vf610-colibri_vf61-on-eval", "toradex,vf610-colibri_vf61", "fsl,vf610";
+}; \ No newline at end of file
diff --git a/arch/arm/boot/dts/vf610-colibri.dtsi b/arch/arm/boot/dts/vf610-colibri.dtsi
new file mode 100644
index 000000000..19fe045b8
--- /dev/null
+++ b/arch/arm/boot/dts/vf610-colibri.dtsi
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2014 Toradex AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 "vf610.dtsi"
+#include "vf-colibri.dtsi"
+
+/ {
+ model = "Toradex Colibri VF61 COM";
+ compatible = "toradex,vf610-colibri_vf61", "fsl,vf610";
+
+ memory {
+ reg = <0x80000000 0x10000000>;
+ };
+};
+
+&L2 {
+ arm,data-latency = <2 1 2>;
+ arm,tag-latency = <3 2 3>;
+};
diff --git a/arch/arm/boot/dts/vf610-cosmic.dts b/arch/arm/boot/dts/vf610-cosmic.dts
new file mode 100644
index 000000000..fd8758b63
--- /dev/null
+++ b/arch/arm/boot/dts/vf610-cosmic.dts
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ * Copyright 2013 Linaro 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.
+ */
+
+/dts-v1/;
+#include "vf610.dtsi"
+
+/ {
+ model = "PHYTEC Cosmic/Cosmic+ Board";
+ compatible = "phytec,vf610-cosmic", "fsl,vf610";
+
+ chosen {
+ bootargs = "console=ttyLP1,115200";
+ };
+
+ memory {
+ reg = <0x80000000 0x10000000>;
+ };
+
+ enet_ext: enet_ext {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <50000000>;
+ };
+};
+
+&clks {
+ clocks = <&sxosc>, <&fxosc>, <&enet_ext>;
+ clock-names = "sxosc", "fxosc", "enet_ext";
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&fec1 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ status = "okay";
+};
+
+&iomuxc {
+ vf610-cosmic {
+ pinctrl_esdhc1: esdhc1grp {
+ fsl,pins = <
+ VF610_PAD_PTA24__ESDHC1_CLK 0x31ef
+ VF610_PAD_PTA25__ESDHC1_CMD 0x31ef
+ VF610_PAD_PTA26__ESDHC1_DAT0 0x31ef
+ VF610_PAD_PTA27__ESDHC1_DAT1 0x31ef
+ VF610_PAD_PTA28__ESDHC1_DATA2 0x31ef
+ VF610_PAD_PTA29__ESDHC1_DAT3 0x31ef
+ VF610_PAD_PTB28__GPIO_98 0x219d
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ VF610_PAD_PTC9__ENET_RMII1_MDC 0x30d2
+ VF610_PAD_PTC10__ENET_RMII1_MDIO 0x30d3
+ VF610_PAD_PTC11__ENET_RMII1_CRS 0x30d1
+ VF610_PAD_PTC12__ENET_RMII_RXD1 0x30d1
+ VF610_PAD_PTC13__ENET_RMII1_RXD0 0x30d1
+ VF610_PAD_PTC14__ENET_RMII1_RXER 0x30d1
+ VF610_PAD_PTC15__ENET_RMII1_TXD1 0x30d2
+ VF610_PAD_PTC16__ENET_RMII1_TXD0 0x30d2
+ VF610_PAD_PTC17__ENET_RMII1_TXEN 0x30d2
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ VF610_PAD_PTB4__UART1_TX 0x21a2
+ VF610_PAD_PTB5__UART1_RX 0x21a1
+ >;
+ };
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/vf610-pinfunc.h b/arch/arm/boot/dts/vf610-pinfunc.h
new file mode 100644
index 000000000..1ee681f7c
--- /dev/null
+++ b/arch/arm/boot/dts/vf610-pinfunc.h
@@ -0,0 +1,810 @@
+/*
+ * Copyright 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_VF610_PINFUNC_H
+#define __DTS_VF610_PINFUNC_H
+
+/*
+ * The pin function ID for VF610 is a tuple of:
+ * <mux_reg input_reg mux_mode input_val>
+ */
+
+#define ALT0 0x0
+#define ALT1 0x1
+#define ALT2 0x2
+#define ALT3 0x3
+#define ALT4 0x4
+#define ALT5 0x5
+#define ALT6 0x6
+#define ALT7 0x7
+
+
+#define VF610_PAD_PTA6__GPIO_0 0x000 0x000 ALT0 0x0
+#define VF610_PAD_PTA6__RMII_CLKOUT 0x000 0x000 ALT1 0x0
+#define VF610_PAD_PTA6__RMII_CLKIN 0x000 0x2F0 ALT2 0x0
+#define VF610_PAD_PTA6__DCU1_TCON11 0x000 0x000 ALT4 0x0
+#define VF610_PAD_PTA6__DCU1_R2 0x000 0x000 ALT7 0x0
+#define VF610_PAD_PTA8__GPIO_1 0x004 0x000 ALT0 0x0
+#define VF610_PAD_PTA8__TCLK 0x004 0x000 ALT1 0x0
+#define VF610_PAD_PTA8__DCU0_R0 0x004 0x000 ALT4 0x0
+#define VF610_PAD_PTA8__MLB_CLK 0x004 0x354 ALT7 0x0
+#define VF610_PAD_PTA9__GPIO_2 0x008 0x000 ALT0 0x0
+#define VF610_PAD_PTA9__TDI 0x008 0x000 ALT1 0x0
+#define VF610_PAD_PTA9__RMII_CLKOUT 0x008 0x000 ALT2 0x0
+#define VF610_PAD_PTA9__RMII_CLKIN 0x008 0x2F0 ALT3 0x1
+#define VF610_PAD_PTA9__DCU0_R1 0x008 0x000 ALT4 0x0
+#define VF610_PAD_PTA9__WDOG_B 0x008 0x000 ALT6 0x0
+#define VF610_PAD_PTA10__GPIO_3 0x00C 0x000 ALT0 0x0
+#define VF610_PAD_PTA10__TDO 0x00C 0x000 ALT1 0x0
+#define VF610_PAD_PTA10__EXT_AUDIO_MCLK 0x00C 0x2EC ALT2 0x0
+#define VF610_PAD_PTA10__DCU0_G0 0x00C 0x000 ALT4 0x0
+#define VF610_PAD_PTA10__ENET_TS_CLKIN 0x00C 0x2F4 ALT6 0x0
+#define VF610_PAD_PTA10__MLB_SIGNAL 0x00C 0x35C ALT7 0x0
+#define VF610_PAD_PTA11__GPIO_4 0x010 0x000 ALT0 0x0
+#define VF610_PAD_PTA11__TMS 0x010 0x000 ALT1 0x0
+#define VF610_PAD_PTA11__DCU0_G1 0x010 0x000 ALT4 0x0
+#define VF610_PAD_PTA11__MLB_DATA 0x010 0x358 ALT7 0x0
+#define VF610_PAD_PTA12__GPIO_5 0x014 0x000 ALT0 0x0
+#define VF610_PAD_PTA12__TRACECK 0x014 0x000 ALT1 0x0
+#define VF610_PAD_PTA12__EXT_AUDIO_MCLK 0x014 0x2EC ALT2 0x1
+#define VF610_PAD_PTA12__VIU_DATA13 0x014 0x000 ALT6 0x0
+#define VF610_PAD_PTA12__I2C0_SCL 0x014 0x33C ALT7 0x0
+#define VF610_PAD_PTA16__GPIO_6 0x018 0x000 ALT0 0x0
+#define VF610_PAD_PTA16__TRACED0 0x018 0x000 ALT1 0x0
+#define VF610_PAD_PTA16__USB0_VBUS_EN 0x018 0x000 ALT2 0x0
+#define VF610_PAD_PTA16__ADC1_SE0 0x018 0x000 ALT3 0x0
+#define VF610_PAD_PTA16__LCD29 0x018 0x000 ALT4 0x0
+#define VF610_PAD_PTA16__SAI2_TX_BCLK 0x018 0x370 ALT5 0x0
+#define VF610_PAD_PTA16__VIU_DATA14 0x018 0x000 ALT6 0x0
+#define VF610_PAD_PTA16__I2C0_SDA 0x018 0x340 ALT7 0x0
+#define VF610_PAD_PTA17__GPIO_7 0x01C 0x000 ALT0 0x0
+#define VF610_PAD_PTA17__TRACED1 0x01C 0x000 ALT1 0x0
+#define VF610_PAD_PTA17__USB0_VBUS_OC 0x01C 0x000 ALT2 0x0
+#define VF610_PAD_PTA17__ADC1_SE1 0x01C 0x000 ALT3 0x0
+#define VF610_PAD_PTA17__LCD30 0x01C 0x000 ALT4 0x0
+#define VF610_PAD_PTA17__USB0_SOF_PULSE 0x01C 0x000 ALT5 0x0
+#define VF610_PAD_PTA17__VIU_DATA15 0x01C 0x000 ALT6 0x0
+#define VF610_PAD_PTA17__I2C1_SCL 0x01C 0x344 ALT7 0x0
+#define VF610_PAD_PTA18__GPIO_8 0x020 0x000 ALT0 0x0
+#define VF610_PAD_PTA18__TRACED2 0x020 0x000 ALT1 0x0
+#define VF610_PAD_PTA18__ADC0_SE0 0x020 0x000 ALT2 0x0
+#define VF610_PAD_PTA18__FTM1_QD_PHA 0x020 0x334 ALT3 0x0
+#define VF610_PAD_PTA18__LCD31 0x020 0x000 ALT4 0x0
+#define VF610_PAD_PTA18__SAI2_TX_DATA 0x020 0x000 ALT5 0x0
+#define VF610_PAD_PTA18__VIU_DATA16 0x020 0x000 ALT6 0x0
+#define VF610_PAD_PTA18__I2C1_SDA 0x020 0x348 ALT7 0x0
+#define VF610_PAD_PTA19__GPIO_9 0x024 0x000 ALT0 0x0
+#define VF610_PAD_PTA19__TRACED3 0x024 0x000 ALT1 0x0
+#define VF610_PAD_PTA19__ADC0_SE1 0x024 0x000 ALT2 0x0
+#define VF610_PAD_PTA19__FTM1_QD_PHB 0x024 0x338 ALT3 0x0
+#define VF610_PAD_PTA19__LCD32 0x024 0x000 ALT4 0x0
+#define VF610_PAD_PTA19__SAI2_TX_SYNC 0x024 0x000 ALT5 0x0
+#define VF610_PAD_PTA19__VIU_DATA17 0x024 0x000 ALT6 0x0
+#define VF610_PAD_PTA19__QSPI1_A_QSCK 0x024 0x374 ALT7 0x0
+#define VF610_PAD_PTA20__GPIO_10 0x028 0x000 ALT0 0x0
+#define VF610_PAD_PTA20__TRACED4 0x028 0x000 ALT1 0x0
+#define VF610_PAD_PTA20__LCD33 0x028 0x000 ALT4 0x0
+#define VF610_PAD_PTA20__UART3_TX 0x028 0x394 ALT6 0x0
+#define VF610_PAD_PTA20__DCU1_HSYNC 0x028 0x000 ALT7 0x0
+#define VF610_PAD_PTA21__GPIO_11 0x02C 0x000 ALT0 0x0
+#define VF610_PAD_PTA21__TRACED5 0x02C 0x000 ALT1 0x0
+#define VF610_PAD_PTA21__SAI2_RX_BCLK 0x02C 0x364 ALT5 0x0
+#define VF610_PAD_PTA21__UART3_RX 0x02C 0x390 ALT6 0x0
+#define VF610_PAD_PTA21__DCU1_VSYNC 0x02C 0x000 ALT7 0x0
+#define VF610_PAD_PTA22__GPIO_12 0x030 0x000 ALT0 0x0
+#define VF610_PAD_PTA22__TRACED6 0x030 0x000 ALT1 0x0
+#define VF610_PAD_PTA22__SAI2_RX_DATA 0x030 0x368 ALT5 0x0
+#define VF610_PAD_PTA22__I2C2_SCL 0x030 0x34C ALT6 0x0
+#define VF610_PAD_PTA22__DCU1_TAG 0x030 0x000 ALT7 0x0
+#define VF610_PAD_PTA23__GPIO_13 0x034 0x000 ALT0 0x0
+#define VF610_PAD_PTA23__TRACED7 0x034 0x000 ALT1 0x0
+#define VF610_PAD_PTA23__SAI2_RX_SYNC 0x034 0x36C ALT5 0x0
+#define VF610_PAD_PTA23__I2C2_SDA 0x034 0x350 ALT6 0x0
+#define VF610_PAD_PTA23__DCU1_DE 0x034 0x000 ALT7 0x0
+#define VF610_PAD_PTA24__GPIO_14 0x038 0x000 ALT0 0x0
+#define VF610_PAD_PTA24__TRACED8 0x038 0x000 ALT1 0x0
+#define VF610_PAD_PTA24__USB1_VBUS_EN 0x038 0x000 ALT2 0x0
+#define VF610_PAD_PTA24__ESDHC1_CLK 0x038 0x000 ALT5 0x0
+#define VF610_PAD_PTA24__DCU1_TCON4 0x038 0x000 ALT6 0x0
+#define VF610_PAD_PTA24__DDR_TEST_PAD_CTRL 0x038 0x000 ALT7 0x0
+#define VF610_PAD_PTA25__GPIO_15 0x03C 0x000 ALT0 0x0
+#define VF610_PAD_PTA25__TRACED9 0x03C 0x000 ALT1 0x0
+#define VF610_PAD_PTA25__USB1_VBUS_OC 0x03C 0x000 ALT2 0x0
+#define VF610_PAD_PTA25__ESDHC1_CMD 0x03C 0x000 ALT5 0x0
+#define VF610_PAD_PTA25__DCU1_TCON5 0x03C 0x000 ALT6 0x0
+#define VF610_PAD_PTA26__GPIO_16 0x040 0x000 ALT0 0x0
+#define VF610_PAD_PTA26__TRACED10 0x040 0x000 ALT1 0x0
+#define VF610_PAD_PTA26__SAI3_TX_BCLK 0x040 0x000 ALT2 0x0
+#define VF610_PAD_PTA26__ESDHC1_DAT0 0x040 0x000 ALT5 0x0
+#define VF610_PAD_PTA26__DCU1_TCON6 0x040 0x000 ALT6 0x0
+#define VF610_PAD_PTA27__GPIO_17 0x044 0x000 ALT0 0x0
+#define VF610_PAD_PTA27__TRACED11 0x044 0x000 ALT1 0x0
+#define VF610_PAD_PTA27__SAI3_RX_BCLK 0x044 0x000 ALT2 0x0
+#define VF610_PAD_PTA27__ESDHC1_DAT1 0x044 0x000 ALT5 0x0
+#define VF610_PAD_PTA27__DCU1_TCON7 0x044 0x000 ALT6 0x0
+#define VF610_PAD_PTA28__GPIO_18 0x048 0x000 ALT0 0x0
+#define VF610_PAD_PTA28__TRACED12 0x048 0x000 ALT1 0x0
+#define VF610_PAD_PTA28__SAI3_RX_DATA 0x048 0x000 ALT2 0x0
+#define VF610_PAD_PTA28__ENET1_1588_TMR0 0x048 0x000 ALT3 0x0
+#define VF610_PAD_PTA28__UART4_TX 0x048 0x000 ALT4 0x0
+#define VF610_PAD_PTA28__ESDHC1_DATA2 0x048 0x000 ALT5 0x0
+#define VF610_PAD_PTA28__DCU1_TCON8 0x048 0x000 ALT6 0x0
+#define VF610_PAD_PTA29__GPIO_19 0x04C 0x000 ALT0 0x0
+#define VF610_PAD_PTA29__TRACED13 0x04C 0x000 ALT1 0x0
+#define VF610_PAD_PTA29__SAI3_TX_DATA 0x04C 0x000 ALT2 0x0
+#define VF610_PAD_PTA29__ENET1_1588_TMR1 0x04C 0x000 ALT3 0x0
+#define VF610_PAD_PTA29__UART4_RX 0x04C 0x000 ALT4 0x0
+#define VF610_PAD_PTA29__ESDHC1_DAT3 0x04C 0x000 ALT5 0x0
+#define VF610_PAD_PTA29__DCU1_TCON9 0x04C 0x000 ALT6 0x0
+#define VF610_PAD_PTA30__GPIO_20 0x050 0x000 ALT0 0x0
+#define VF610_PAD_PTA30__TRACED14 0x050 0x000 ALT1 0x0
+#define VF610_PAD_PTA30__SAI3_RX_SYNC 0x050 0x000 ALT2 0x0
+#define VF610_PAD_PTA30__ENET1_1588_TMR2 0x050 0x000 ALT3 0x0
+#define VF610_PAD_PTA30__UART4_RTS 0x050 0x000 ALT4 0x0
+#define VF610_PAD_PTA30__I2C3_SCL 0x050 0x000 ALT5 0x0
+#define VF610_PAD_PTA30__UART3_TX 0x050 0x394 ALT7 0x1
+#define VF610_PAD_PTA31__GPIO_21 0x054 0x000 ALT0 0x0
+#define VF610_PAD_PTA31__TRACED15 0x054 0x000 ALT1 0x0
+#define VF610_PAD_PTA31__SAI3_TX_SYNC 0x054 0x000 ALT2 0x0
+#define VF610_PAD_PTA31__ENET1_1588_TMR3 0x054 0x000 ALT3 0x0
+#define VF610_PAD_PTA31__UART4_CTS 0x054 0x000 ALT4 0x0
+#define VF610_PAD_PTA31__I2C3_SDA 0x054 0x000 ALT5 0x0
+#define VF610_PAD_PTA31__UART3_RX 0x054 0x390 ALT7 0x1
+#define VF610_PAD_PTB0__GPIO_22 0x058 0x000 ALT0 0x0
+#define VF610_PAD_PTB0__FTM0_CH0 0x058 0x000 ALT1 0x0
+#define VF610_PAD_PTB0__ADC0_SE2 0x058 0x000 ALT2 0x0
+#define VF610_PAD_PTB0__TRACE_CTL 0x058 0x000 ALT3 0x0
+#define VF610_PAD_PTB0__LCD34 0x058 0x000 ALT4 0x0
+#define VF610_PAD_PTB0__SAI2_RX_BCLK 0x058 0x364 ALT5 0x1
+#define VF610_PAD_PTB0__VIU_DATA18 0x058 0x000 ALT6 0x0
+#define VF610_PAD_PTB0__QSPI1_A_QPCS0 0x058 0x000 ALT7 0x0
+#define VF610_PAD_PTB1__GPIO_23 0x05C 0x000 ALT0 0x0
+#define VF610_PAD_PTB1__FTM0_CH1 0x05C 0x000 ALT1 0x0
+#define VF610_PAD_PTB1__ADC0_SE3 0x05C 0x000 ALT2 0x0
+#define VF610_PAD_PTB1__SRC_RCON30 0x05C 0x000 ALT3 0x0
+#define VF610_PAD_PTB1__LCD35 0x05C 0x000 ALT4 0x0
+#define VF610_PAD_PTB1__SAI2_RX_DATA 0x05C 0x368 ALT5 0x1
+#define VF610_PAD_PTB1__VIU_DATA19 0x05C 0x000 ALT6 0x0
+#define VF610_PAD_PTB1__QSPI1_A_DATA3 0x05C 0x000 ALT7 0x0
+#define VF610_PAD_PTB2__GPIO_24 0x060 0x000 ALT0 0x0
+#define VF610_PAD_PTB2__FTM0_CH2 0x060 0x000 ALT1 0x0
+#define VF610_PAD_PTB2__ADC1_SE2 0x060 0x000 ALT2 0x0
+#define VF610_PAD_PTB2__SRC_RCON31 0x060 0x000 ALT3 0x0
+#define VF610_PAD_PTB2__LCD36 0x060 0x000 ALT4 0x0
+#define VF610_PAD_PTB2__SAI2_RX_SYNC 0x060 0x36C ALT5 0x1
+#define VF610_PAD_PTB2__VIDEO_IN0_DATA20 0x060 0x000 ALT6 0x0
+#define VF610_PAD_PTB2__QSPI1_A_DATA2 0x060 0x000 ALT7 0x0
+#define VF610_PAD_PTB3__GPIO_25 0x064 0x000 ALT0 0x0
+#define VF610_PAD_PTB3__FTM0_CH3 0x064 0x000 ALT1 0x0
+#define VF610_PAD_PTB3__ADC1_SE3 0x064 0x000 ALT2 0x0
+#define VF610_PAD_PTB3__PDB_EXTRIG 0x064 0x000 ALT3 0x0
+#define VF610_PAD_PTB3__LCD37 0x064 0x000 ALT4 0x0
+#define VF610_PAD_PTB3__VIU_DATA21 0x064 0x000 ALT6 0x0
+#define VF610_PAD_PTB3__QSPI1_A_DATA1 0x064 0x000 ALT7 0x0
+#define VF610_PAD_PTB4__GPIO_26 0x068 0x000 ALT0 0x0
+#define VF610_PAD_PTB4__FTM0_CH4 0x068 0x000 ALT1 0x0
+#define VF610_PAD_PTB4__UART1_TX 0x068 0x380 ALT2 0x0
+#define VF610_PAD_PTB4__ADC0_SE4 0x068 0x000 ALT3 0x0
+#define VF610_PAD_PTB4__LCD38 0x068 0x000 ALT4 0x0
+#define VF610_PAD_PTB4__VIU_FID 0x068 0x3A8 ALT5 0x0
+#define VF610_PAD_PTB4__VIU_DATA22 0x068 0x000 ALT6 0x0
+#define VF610_PAD_PTB4__QSPI1_A_DATA0 0x068 0x000 ALT7 0x0
+#define VF610_PAD_PTB5__GPIO_27 0x06C 0x000 ALT0 0x0
+#define VF610_PAD_PTB5__FTM0_CH5 0x06C 0x000 ALT1 0x0
+#define VF610_PAD_PTB5__UART1_RX 0x06C 0x37C ALT2 0x0
+#define VF610_PAD_PTB5__ADC1_SE4 0x06C 0x000 ALT3 0x0
+#define VF610_PAD_PTB5__LCD39 0x06C 0x000 ALT4 0x0
+#define VF610_PAD_PTB5__VIU_DE 0x06C 0x3A4 ALT5 0x0
+#define VF610_PAD_PTB5__QSPI1_A_DQS 0x06C 0x000 ALT7 0x0
+#define VF610_PAD_PTB6__GPIO_28 0x070 0x000 ALT0 0x0
+#define VF610_PAD_PTB6__FTM0_CH6 0x070 0x000 ALT1 0x0
+#define VF610_PAD_PTB6__UART1_RTS 0x070 0x000 ALT2 0x0
+#define VF610_PAD_PTB6__QSPI0_QPCS1_A 0x070 0x000 ALT3 0x0
+#define VF610_PAD_PTB6__LCD_LCD40 0x070 0x000 ALT4 0x0
+#define VF610_PAD_PTB6__FB_CLKOUT 0x070 0x000 ALT5 0x0
+#define VF610_PAD_PTB6__VIU_HSYNC 0x070 0x000 ALT6 0x0
+#define VF610_PAD_PTB6__UART2_TX 0x070 0x38C ALT7 0x0
+#define VF610_PAD_PTB7__GPIO_29 0x074 0x000 ALT0 0x0
+#define VF610_PAD_PTB7__FTM0_CH7 0x074 0x000 ALT1 0x0
+#define VF610_PAD_PTB7__UART1_CTS 0x074 0x378 ALT2 0x0
+#define VF610_PAD_PTB7__QSPI0_B_QPCS1 0x074 0x000 ALT3 0x0
+#define VF610_PAD_PTB7__LCD41 0x074 0x000 ALT4 0x0
+#define VF610_PAD_PTB7__VIU_VSYNC 0x074 0x000 ALT6 0x0
+#define VF610_PAD_PTB7__UART2_RX 0x074 0x388 ALT7 0x0
+#define VF610_PAD_PTB8__GPIO_30 0x078 0x000 ALT0 0x0
+#define VF610_PAD_PTB8__FTM1_CH0 0x078 0x32C ALT1 0x0
+#define VF610_PAD_PTB8__FTM1_QD_PHA 0x078 0x334 ALT3 0x1
+#define VF610_PAD_PTB8__VIU_DE 0x078 0x3A4 ALT5 0x1
+#define VF610_PAD_PTB8__DCU1_R6 0x078 0x000 ALT7 0x0
+#define VF610_PAD_PTB9__GPIO_31 0x07C 0x000 ALT0 0x0
+#define VF610_PAD_PTB9__FTM1_CH1 0x07C 0x330 ALT1 0x0
+#define VF610_PAD_PTB9__FTM1_QD_PHB 0x07C 0x338 ALT3 0x1
+#define VF610_PAD_PTB9__DCU1_R7 0x07C 0x000 ALT7 0x0
+#define VF610_PAD_PTB10__GPIO_32 0x080 0x000 ALT0 0x0
+#define VF610_PAD_PTB10__UART0_TX 0x080 0x000 ALT1 0x0
+#define VF610_PAD_PTB10__DCU0_TCON4 0x080 0x000 ALT4 0x0
+#define VF610_PAD_PTB10__VIU_DE 0x080 0x3A4 ALT5 0x2
+#define VF610_PAD_PTB10__CKO1 0x080 0x000 ALT6 0x0
+#define VF610_PAD_PTB10__ENET_TS_CLKIN 0x080 0x2F4 ALT7 0x1
+#define VF610_PAD_PTB11__GPIO_33 0x084 0x000 ALT0 0x0
+#define VF610_PAD_PTB11__UART0_RX 0x084 0x000 ALT1 0x0
+#define VF610_PAD_PTB11__DCU0_TCON5 0x084 0x000 ALT4 0x0
+#define VF610_PAD_PTB11__SNVS_ALARM_OUT_B 0x084 0x000 ALT5 0x0
+#define VF610_PAD_PTB11__CKO2 0x084 0x000 ALT6 0x0
+#define VF610_PAD_PTB11_ENET0_1588_TMR0 0x084 0x304 ALT7 0x0
+#define VF610_PAD_PTB12__GPIO_34 0x088 0x000 ALT0 0x0
+#define VF610_PAD_PTB12__UART0_RTS 0x088 0x000 ALT1 0x0
+#define VF610_PAD_PTB12__DSPI0_CS5 0x088 0x000 ALT3 0x0
+#define VF610_PAD_PTB12__DCU0_TCON6 0x088 0x000 ALT4 0x0
+#define VF610_PAD_PTB12__FB_AD1 0x088 0x000 ALT5 0x0
+#define VF610_PAD_PTB12__NMI 0x088 0x000 ALT6 0x0
+#define VF610_PAD_PTB12__ENET0_1588_TMR1 0x088 0x308 ALT7 0x0
+#define VF610_PAD_PTB13__GPIO_35 0x08C 0x000 ALT0 0x0
+#define VF610_PAD_PTB13__UART0_CTS 0x08C 0x000 ALT1 0x0
+#define VF610_PAD_PTB13__DSPI0_CS4 0x08C 0x000 ALT3 0x0
+#define VF610_PAD_PTB13__DCU0_TCON7 0x08C 0x000 ALT4 0x0
+#define VF610_PAD_PTB13__FB_AD0 0x08C 0x000 ALT5 0x0
+#define VF610_PAD_PTB13__TRACE_CTL 0x08C 0x000 ALT6 0x0
+#define VF610_PAD_PTB14__GPIO_36 0x090 0x000 ALT0 0x0
+#define VF610_PAD_PTB14__CAN0_RX 0x090 0x000 ALT1 0x0
+#define VF610_PAD_PTB14__I2C0_SCL 0x090 0x33C ALT2 0x1
+#define VF610_PAD_PTB14__DCU0_TCON8 0x090 0x000 ALT4 0x0
+#define VF610_PAD_PTB14__DCU1_PCLK 0x090 0x000 ALT7 0x0
+#define VF610_PAD_PTB15__GPIO_37 0x094 0x000 ALT0 0x0
+#define VF610_PAD_PTB15__CAN0_TX 0x094 0x000 ALT1 0x0
+#define VF610_PAD_PTB15__I2C0_SDA 0x094 0x340 ALT2 0x1
+#define VF610_PAD_PTB15__DCU0_TCON9 0x094 0x000 ALT4 0x0
+#define VF610_PAD_PTB15__VIU_PIX_CLK 0x094 0x3AC ALT7 0x0
+#define VF610_PAD_PTB16__GPIO_38 0x098 0x000 ALT0 0x0
+#define VF610_PAD_PTB16__CAN1_RX 0x098 0x000 ALT1 0x0
+#define VF610_PAD_PTB16__I2C1_SCL 0x098 0x344 ALT2 0x1
+#define VF610_PAD_PTB16__DCU0_TCON10 0x098 0x000 ALT4 0x0
+#define VF610_PAD_PTB17__GPIO_39 0x09C 0x000 ALT0 0x0
+#define VF610_PAD_PTB17__CAN1_TX 0x09C 0x000 ALT1 0x0
+#define VF610_PAD_PTB17__I2C1_SDA 0x09C 0x348 ALT2 0x1
+#define VF610_PAD_PTB17__DCU0_TCON11 0x09C 0x000 ALT4 0x0
+#define VF610_PAD_PTB18__GPIO_40 0x0A0 0x000 ALT0 0x0
+#define VF610_PAD_PTB18__DSPI0_CS1 0x0A0 0x000 ALT1 0x0
+#define VF610_PAD_PTB18__EXT_AUDIO_MCLK 0x0A0 0x2EC ALT2 0x2
+#define VF610_PAD_PTB18__VIU_DATA9 0x0A0 0x000 ALT6 0x0
+#define VF610_PAD_PTB19__GPIO_41 0x0A4 0x000 ALT0 0x0
+#define VF610_PAD_PTB19__DSPI0_CS0 0x0A4 0x000 ALT1 0x0
+#define VF610_PAD_PTB19__VIU_DATA10 0x0A4 0x000 ALT6 0x0
+#define VF610_PAD_PTB20__GPIO_42 0x0A8 0x000 ALT0 0x0
+#define VF610_PAD_PTB20__DSPI0_SIN 0x0A8 0x000 ALT1 0x0
+#define VF610_PAD_PTB20__LCD42 0x0A8 0x000 ALT4 0x0
+#define VF610_PAD_PTB20__VIU_DATA11 0x0A8 0x000 ALT6 0x0
+#define VF610_PAD_PTB21__GPIO_43 0x0AC 0x000 ALT0 0x0
+#define VF610_PAD_PTB21__DSPI0_SOUT 0x0AC 0x000 ALT1 0x0
+#define VF610_PAD_PTB21__LCD43 0x0AC 0x000 ALT4 0x0
+#define VF610_PAD_PTB21__VIU_DATA12 0x0AC 0x000 ALT6 0x0
+#define VF610_PAD_PTB21__DCU1_PCLK 0x0AC 0x000 ALT7 0x0
+#define VF610_PAD_PTB22__GPIO_44 0x0B0 0x000 ALT0 0x0
+#define VF610_PAD_PTB22__DSPI0_SCK 0x0B0 0x000 ALT1 0x0
+#define VF610_PAD_PTB22__VLCD 0x0B0 0x000 ALT4 0x0
+#define VF610_PAD_PTB22__VIU_FID 0x0B0 0x3A8 ALT5 0x1
+#define VF610_PAD_PTC0__GPIO_45 0x0B4 0x000 ALT0 0x0
+#define VF610_PAD_PTC0__ENET_RMII0_MDC 0x0B4 0x000 ALT1 0x0
+#define VF610_PAD_PTC0__FTM1_CH0 0x0B4 0x32C ALT2 0x1
+#define VF610_PAD_PTC0__DSPI0_CS3 0x0B4 0x000 ALT3 0x0
+#define VF610_PAD_PTC0__ESAI_SCKT 0x0B4 0x310 ALT4 0x0
+#define VF610_PAD_PTC0__ESDHC0_CLK 0x0B4 0x000 ALT5 0x0
+#define VF610_PAD_PTC0__VIU_DATA0 0x0B4 0x000 ALT6 0x0
+#define VF610_PAD_PTC0__SRC_RCON18 0x0B4 0x398 ALT7 0x0
+#define VF610_PAD_PTC1__GPIO_46 0x0B8 0x000 ALT0 0x0
+#define VF610_PAD_PTC1__ENET_RMII0_MDIO 0x0B8 0x000 ALT1 0x0
+#define VF610_PAD_PTC1__FTM1_CH1 0x0B8 0x330 ALT2 0x1
+#define VF610_PAD_PTC1__DSPI0_CS2 0x0B8 0x000 ALT3 0x0
+#define VF610_PAD_PTC1__ESAI_FST 0x0B8 0x30C ALT4 0x0
+#define VF610_PAD_PTC1__ESDHC0_CMD 0x0B8 0x000 ALT5 0x0
+#define VF610_PAD_PTC1__VIU_DATA1 0x0B8 0x000 ALT6 0x0
+#define VF610_PAD_PTC1__SRC_RCON19 0x0B8 0x39C ALT7 0x0
+#define VF610_PAD_PTC2__GPIO_47 0x0BC 0x000 ALT0 0x0
+#define VF610_PAD_PTC2__ENET_RMII0_CRS 0x0BC 0x000 ALT1 0x0
+#define VF610_PAD_PTC2__UART1_TX 0x0BC 0x380 ALT2 0x1
+#define VF610_PAD_PTC2__ESAI_SDO0 0x0BC 0x314 ALT4 0x0
+#define VF610_PAD_PTC2__ESDHC0_DAT0 0x0BC 0x000 ALT5 0x0
+#define VF610_PAD_PTC2__VIU_DATA2 0x0BC 0x000 ALT6 0x0
+#define VF610_PAD_PTC2__SRC_RCON20 0x0BC 0x3A0 ALT7 0x0
+#define VF610_PAD_PTC3__GPIO_48 0x0C0 0x000 ALT0 0x0
+#define VF610_PAD_PTC3__ENET_RMII0_RXD1 0x0C0 0x000 ALT1 0x0
+#define VF610_PAD_PTC3__UART1_RX 0x0C0 0x37C ALT2 0x1
+#define VF610_PAD_PTC3__ESAI_SDO1 0x0C0 0x318 ALT4 0x0
+#define VF610_PAD_PTC3__ESDHC0_DAT1 0x0C0 0x000 ALT5 0x0
+#define VF610_PAD_PTC3__VIU_DATA3 0x0C0 0x000 ALT6 0x0
+#define VF610_PAD_PTC3__DCU0_R0 0x0C0 0x000 ALT7 0x0
+#define VF610_PAD_PTC4__GPIO_49 0x0C4 0x000 ALT0 0x0
+#define VF610_PAD_PTC4__ENET_RMII0_RXD0 0x0C4 0x000 ALT1 0x0
+#define VF610_PAD_PTC4__UART1_RTS 0x0C4 0x000 ALT2 0x0
+#define VF610_PAD_PTC4__DSPI1_CS1 0x0C4 0x000 ALT3 0x0
+#define VF610_PAD_PTC4__ESAI_SDO2 0x0C4 0x31C ALT4 0x0
+#define VF610_PAD_PTC4__ESDHC0_DAT2 0x0C4 0x000 ALT5 0x0
+#define VF610_PAD_PTC4__VIU_DATA4 0x0C4 0x000 ALT6 0x0
+#define VF610_PAD_PTC4__DCU0_R1 0x0C4 0x000 ALT7 0x0
+#define VF610_PAD_PTC5__GPIO_50 0x0C8 0x000 ALT0 0x0
+#define VF610_PAD_PTC5__ENET_RMII0_RXER 0x0C8 0x000 ALT1 0x0
+#define VF610_PAD_PTC5__UART1_CTS 0x0C8 0x378 ALT2 0x1
+#define VF610_PAD_PTC5__DSPI1_CS0 0x0C8 0x300 ALT3 0x0
+#define VF610_PAD_PTC5__ESAI_SDO3 0x0C8 0x320 ALT4 0x0
+#define VF610_PAD_PTC5__ESDHC0_DAT3 0x0C8 0x000 ALT5 0x0
+#define VF610_PAD_PTC5__VIU_DATA5 0x0C8 0x000 ALT6 0x0
+#define VF610_PAD_PTC5__DCU0_G0 0x0C8 0x000 ALT7 0x0
+#define VF610_PAD_PTC6__GPIO_51 0x0CC 0x000 ALT0 0x0
+#define VF610_PAD_PTC6__ENET_RMII0_TXD1 0x0CC 0x000 ALT1 0x0
+#define VF610_PAD_PTC6__DSPI1_SIN 0x0CC 0x2FC ALT3 0x0
+#define VF610_PAD_PTC6__ESAI_SDI0 0x0CC 0x328 ALT4 0x0
+#define VF610_PAD_PTC6__ESDHC0_WP 0x0CC 0x000 ALT5 0x0
+#define VF610_PAD_PTC6__VIU_DATA6 0x0CC 0x000 ALT6 0x0
+#define VF610_PAD_PTC6__DCU0_G1 0x0CC 0x000 ALT7 0x0
+#define VF610_PAD_PTC7__GPIO_52 0x0D0 0x000 ALT0 0x0
+#define VF610_PAD_PTC7__ENET_RMII0_TXD0 0x0D0 0x000 ALT1 0x0
+#define VF610_PAD_PTC7__DSPI1_SOUT 0x0D0 0x000 ALT3 0x0
+#define VF610_PAD_PTC7__ESAI_SDI1 0x0D0 0x324 ALT4 0x0
+#define VF610_PAD_PTC7__VIU_DATA7 0x0D0 0x000 ALT6 0x0
+#define VF610_PAD_PTC7__DCU0_B0 0x0D0 0x000 ALT7 0x0
+#define VF610_PAD_PTC8__GPIO_53 0x0D4 0x000 ALT0 0x0
+#define VF610_PAD_PTC8__ENET_RMII0_TXEN 0x0D4 0x000 ALT1 0x0
+#define VF610_PAD_PTC8__DSPI1_SCK 0x0D4 0x2F8 ALT3 0x0
+#define VF610_PAD_PTC8__VIU_DATA8 0x0D4 0x000 ALT6 0x0
+#define VF610_PAD_PTC8__DCU0_B1 0x0D4 0x000 ALT7 0x0
+#define VF610_PAD_PTC9__GPIO_54 0x0D8 0x000 ALT0 0x0
+#define VF610_PAD_PTC9__ENET_RMII1_MDC 0x0D8 0x000 ALT1 0x0
+#define VF610_PAD_PTC9__ESAI_SCKT 0x0D8 0x310 ALT3 0x1
+#define VF610_PAD_PTC9__MLB_CLK 0x0D8 0x354 ALT6 0x1
+#define VF610_PAD_PTC9__DEBUG_OUT0 0x0D8 0x000 ALT7 0x0
+#define VF610_PAD_PTC10__GPIO_55 0x0DC 0x000 ALT0 0x0
+#define VF610_PAD_PTC10__ENET_RMII1_MDIO 0x0DC 0x000 ALT1 0x0
+#define VF610_PAD_PTC10__ESAI_FST 0x0DC 0x30C ALT3 0x1
+#define VF610_PAD_PTC10__MLB_SIGNAL 0x0DC 0x35C ALT6 0x1
+#define VF610_PAD_PTC10__DEBUG_OUT1 0x0DC 0x000 ALT7 0x0
+#define VF610_PAD_PTC11__GPIO_56 0x0E0 0x000 ALT0 0x0
+#define VF610_PAD_PTC11__ENET_RMII1_CRS 0x0E0 0x000 ALT1 0x0
+#define VF610_PAD_PTC11__ESAI_SDO0 0x0E0 0x314 ALT3 0x1
+#define VF610_PAD_PTC11__MLB_DATA 0x0E0 0x358 ALT6 0x1
+#define VF610_PAD_PTC11__DEBUG_OUT 0x0E0 0x000 ALT7 0x0
+#define VF610_PAD_PTC12__GPIO_57 0x0E4 0x000 ALT0 0x0
+#define VF610_PAD_PTC12__ENET_RMII_RXD1 0x0E4 0x000 ALT1 0x0
+#define VF610_PAD_PTC12__ESAI_SDO1 0x0E4 0x318 ALT3 0x1
+#define VF610_PAD_PTC12__SAI2_TX_BCLK 0x0E4 0x370 ALT5 0x1
+#define VF610_PAD_PTC12__DEBUG_OUT3 0x0E4 0x000 ALT7 0x0
+#define VF610_PAD_PTC13__GPIO_58 0x0E8 0x000 ALT0 0x0
+#define VF610_PAD_PTC13__ENET_RMII1_RXD0 0x0E8 0x000 ALT1 0x0
+#define VF610_PAD_PTC13__ESAI_SDO2 0x0E8 0x31C ALT3 0x1
+#define VF610_PAD_PTC13__SAI2_RX_BCLK 0x0E8 0x364 ALT5 0x2
+#define VF610_PAD_PTC13__DEBUG_OUT4 0x0E8 0x000 ALT7 0x0
+#define VF610_PAD_PTC14__GPIO_59 0x0EC 0x000 ALT0 0x0
+#define VF610_PAD_PTC14__ENET_RMII1_RXER 0x0EC 0x000 ALT1 0x0
+#define VF610_PAD_PTC14__ESAI_SDO3 0x0EC 0x320 ALT3 0x1
+#define VF610_PAD_PTC14__UART5_TX 0x0EC 0x000 ALT4 0x0
+#define VF610_PAD_PTC14__SAI2_RX_DATA 0x0EC 0x368 ALT5 0x2
+#define VF610_PAD_PTC14__ADC0_SE6 0x0EC 0x000 ALT6 0x0
+#define VF610_PAD_PTC14__DEBUG_OUT5 0x0EC 0x000 ALT7 0x0
+#define VF610_PAD_PTC15__GPIO_60 0x0F0 0x000 ALT0 0x0
+#define VF610_PAD_PTC15__ENET_RMII1_TXD1 0x0F0 0x000 ALT1 0x0
+#define VF610_PAD_PTC15__ESAI_SDI0 0x0F0 0x328 ALT3 0x1
+#define VF610_PAD_PTC15__UART5_RX 0x0F0 0x000 ALT4 0x0
+#define VF610_PAD_PTC15__SAI2_TX_DATA 0x0F0 0x000 ALT5 0x0
+#define VF610_PAD_PTC15__ADC0_SE7 0x0F0 0x000 ALT6 0x0
+#define VF610_PAD_PTC15__DEBUG_OUT6 0x0F0 0x000 ALT7 0x0
+#define VF610_PAD_PTC16__GPIO_61 0x0F4 0x000 ALT0 0x0
+#define VF610_PAD_PTC16__ENET_RMII1_TXD0 0x0F4 0x000 ALT1 0x0
+#define VF610_PAD_PTC16__ESAI_SDI1 0x0F4 0x324 ALT3 0x1
+#define VF610_PAD_PTC16__UART5_RTS 0x0F4 0x000 ALT4 0x0
+#define VF610_PAD_PTC16__SAI2_RX_SYNC 0x0F4 0x36C ALT5 0x2
+#define VF610_PAD_PTC16__ADC1_SE6 0x0F4 0x000 ALT6 0x0
+#define VF610_PAD_PTC16__DEBUG_OUT7 0x0F4 0x000 ALT7 0x0
+#define VF610_PAD_PTC17__GPIO_62 0x0F8 0x000 ALT0 0x0
+#define VF610_PAD_PTC17__ENET_RMII1_TXEN 0x0F8 0x000 ALT1 0x0
+#define VF610_PAD_PTC17__ADC1_SE7 0x0F8 0x000 ALT3 0x0
+#define VF610_PAD_PTC17__UART5_CTS 0x0F8 0x000 ALT4 0x0
+#define VF610_PAD_PTC17__SAI2_TX_SYNC 0x0F8 0x374 ALT5 0x1
+#define VF610_PAD_PTC17__USB1_SOF_PULSE 0x0F8 0x000 ALT6 0x0
+#define VF610_PAD_PTC17__DEBUG_OUT8 0x0F8 0x000 ALT7 0x0
+#define VF610_PAD_PTD31__GPIO_63 0x0FC 0x000 ALT0 0x0
+#define VF610_PAD_PTD31__FB_AD31 0x0FC 0x000 ALT1 0x0
+#define VF610_PAD_PTD31__NF_IO15 0x0FC 0x000 ALT2 0x0
+#define VF610_PAD_PTD31__FTM3_CH0 0x0FC 0x000 ALT4 0x0
+#define VF610_PAD_PTD31__DSPI2_CS1 0x0FC 0x000 ALT5 0x0
+#define VF610_PAD_PTD31__DEBUG_OUT9 0x0FC 0x000 ALT7 0x0
+#define VF610_PAD_PTD30__GPIO_64 0x100 0x000 ALT0 0x0
+#define VF610_PAD_PTD30__FB_AD30 0x100 0x000 ALT1 0x0
+#define VF610_PAD_PTD30__NF_IO14 0x100 0x000 ALT2 0x0
+#define VF610_PAD_PTD30__FTM3_CH1 0x100 0x000 ALT4 0x0
+#define VF610_PAD_PTD30__DSPI2_CS0 0x100 0x000 ALT5 0x0
+#define VF610_PAD_PTD30__DEBUG_OUT10 0x100 0x000 ALT7 0x0
+#define VF610_PAD_PTD29__GPIO_65 0x104 0x000 ALT0 0x0
+#define VF610_PAD_PTD29__FB_AD29 0x104 0x000 ALT1 0x0
+#define VF610_PAD_PTD29__NF_IO13 0x104 0x000 ALT2 0x0
+#define VF610_PAD_PTD29__FTM3_CH2 0x104 0x000 ALT4 0x0
+#define VF610_PAD_PTD29__DSPI2_SIN 0x104 0x000 ALT5 0x0
+#define VF610_PAD_PTD29__DEBUG_OUT11 0x104 0x000 ALT7 0x0
+#define VF610_PAD_PTD28__GPIO_66 0x108 0x000 ALT0 0x0
+#define VF610_PAD_PTD28__FB_AD28 0x108 0x000 ALT1 0x0
+#define VF610_PAD_PTD28__NF_IO12 0x108 0x000 ALT2 0x0
+#define VF610_PAD_PTD28__I2C2_SCL 0x108 0x34C ALT3 0x1
+#define VF610_PAD_PTD28__FTM3_CH3 0x108 0x000 ALT4 0x0
+#define VF610_PAD_PTD28__DSPI2_SOUT 0x108 0x000 ALT5 0x0
+#define VF610_PAD_PTD28__DEBUG_OUT12 0x108 0x000 ALT7 0x0
+#define VF610_PAD_PTD27__GPIO_67 0x10C 0x000 ALT0 0x0
+#define VF610_PAD_PTD27__FB_AD27 0x10C 0x000 ALT1 0x0
+#define VF610_PAD_PTD27__NF_IO11 0x10C 0x000 ALT2 0x0
+#define VF610_PAD_PTD27__I2C2_SDA 0x10C 0x350 ALT3 0x1
+#define VF610_PAD_PTD27__FTM3_CH4 0x10C 0x000 ALT4 0x0
+#define VF610_PAD_PTD27__DSPI2_SCK 0x10C 0x000 ALT5 0x0
+#define VF610_PAD_PTD27__DEBUG_OUT13 0x10C 0x000 ALT7 0x0
+#define VF610_PAD_PTD26__GPIO_68 0x110 0x000 ALT0 0x0
+#define VF610_PAD_PTD26__FB_AD26 0x110 0x000 ALT1 0x0
+#define VF610_PAD_PTD26__NF_IO10 0x110 0x000 ALT2 0x0
+#define VF610_PAD_PTD26__FTM3_CH5 0x110 0x000 ALT4 0x0
+#define VF610_PAD_PTD26__ESDHC1_WP 0x110 0x000 ALT5 0x0
+#define VF610_PAD_PTD26__DEBUG_OUT14 0x110 0x000 ALT7 0x0
+#define VF610_PAD_PTD25__GPIO_69 0x114 0x000 ALT0 0x0
+#define VF610_PAD_PTD25__FB_AD25 0x114 0x000 ALT1 0x0
+#define VF610_PAD_PTD25__NF_IO9 0x114 0x000 ALT2 0x0
+#define VF610_PAD_PTD25__FTM3_CH6 0x114 0x000 ALT4 0x0
+#define VF610_PAD_PTD25__DEBUG_OUT15 0x114 0x000 ALT7 0x0
+#define VF610_PAD_PTD24__GPIO_70 0x118 0x000 ALT0 0x0
+#define VF610_PAD_PTD24__FB_AD24 0x118 0x000 ALT1 0x0
+#define VF610_PAD_PTD24__NF_IO8 0x118 0x000 ALT2 0x0
+#define VF610_PAD_PTD24__FTM3_CH7 0x118 0x000 ALT4 0x0
+#define VF610_PAD_PTD24__DEBUG_OUT16 0x118 0x000 ALT7 0x0
+#define VF610_PAD_PTD23__GPIO_71 0x11C 0x000 ALT0 0x0
+#define VF610_PAD_PTD23__FB_AD23 0x11C 0x000 ALT1 0x0
+#define VF610_PAD_PTD23__NF_IO7 0x11C 0x000 ALT2 0x0
+#define VF610_PAD_PTD23__FTM2_CH0 0x11C 0x000 ALT3 0x0
+#define VF610_PAD_PTD23__ENET0_1588_TMR0 0x11C 0x304 ALT4 0x1
+#define VF610_PAD_PTD23__ESDHC0_DAT4 0x11C 0x000 ALT5 0x0
+#define VF610_PAD_PTD23__UART2_TX 0x11C 0x38C ALT6 0x1
+#define VF610_PAD_PTD23__DCU1_R3 0x11C 0x000 ALT7 0x0
+#define VF610_PAD_PTD22__GPIO_72 0x120 0x000 ALT0 0x0
+#define VF610_PAD_PTD22__FB_AD22 0x120 0x000 ALT1 0x0
+#define VF610_PAD_PTD22__NF_IO6 0x120 0x000 ALT2 0x0
+#define VF610_PAD_PTD22__FTM2_CH1 0x120 0x000 ALT3 0x0
+#define VF610_PAD_PTD22__ENET0_1588_TMR1 0x120 0x308 ALT4 0x1
+#define VF610_PAD_PTD22__ESDHC0_DAT5 0x120 0x000 ALT5 0x0
+#define VF610_PAD_PTD22__UART2_RX 0x120 0x388 ALT6 0x1
+#define VF610_PAD_PTD22__DCU1_R4 0x120 0x000 ALT7 0x0
+#define VF610_PAD_PTD21__GPIO_73 0x124 0x000 ALT0 0x0
+#define VF610_PAD_PTD21__FB_AD21 0x124 0x000 ALT1 0x0
+#define VF610_PAD_PTD21__NF_IO5 0x124 0x000 ALT2 0x0
+#define VF610_PAD_PTD21__ENET0_1588_TMR2 0x124 0x000 ALT4 0x0
+#define VF610_PAD_PTD21__ESDHC0_DAT6 0x124 0x000 ALT5 0x0
+#define VF610_PAD_PTD21__UART2_RTS 0x124 0x000 ALT6 0x0
+#define VF610_PAD_PTD21__DCU1_R5 0x124 0x000 ALT7 0x0
+#define VF610_PAD_PTD20__GPIO_74 0x128 0x000 ALT0 0x0
+#define VF610_PAD_PTD20__FB_AD20 0x128 0x000 ALT1 0x0
+#define VF610_PAD_PTD20__NF_IO4 0x128 0x000 ALT2 0x0
+#define VF610_PAD_PTD20__ENET0_1588_TMR3 0x128 0x000 ALT4 0x0
+#define VF610_PAD_PTD20__ESDHC0_DAT7 0x128 0x000 ALT5 0x0
+#define VF610_PAD_PTD20__UART2_CTS 0x128 0x384 ALT6 0x0
+#define VF610_PAD_PTD20__DCU1_R0 0x128 0x000 ALT7 0x0
+#define VF610_PAD_PTD19__GPIO_75 0x12C 0x000 ALT0 0x0
+#define VF610_PAD_PTD19__FB_AD19 0x12C 0x000 ALT1 0x0
+#define VF610_PAD_PTD19__NF_IO3 0x12C 0x000 ALT2 0x0
+#define VF610_PAD_PTD19__ESAI_SCKR 0x12C 0x000 ALT3 0x0
+#define VF610_PAD_PTD19__I2C0_SCL 0x12C 0x33C ALT4 0x2
+#define VF610_PAD_PTD19__FTM2_QD_PHA 0x12C 0x000 ALT5 0x0
+#define VF610_PAD_PTD19__DCU1_R1 0x12C 0x000 ALT7 0x0
+#define VF610_PAD_PTD18__GPIO_76 0x130 0x000 ALT0 0x0
+#define VF610_PAD_PTD18__FB_AD18 0x130 0x000 ALT1 0x0
+#define VF610_PAD_PTD18__NF_IO2 0x130 0x000 ALT2 0x0
+#define VF610_PAD_PTD18__ESAI_FSR 0x130 0x000 ALT3 0x0
+#define VF610_PAD_PTD18__I2C0_SDA 0x130 0x340 ALT4 0x2
+#define VF610_PAD_PTD18__FTM2_QD_PHB 0x130 0x000 ALT5 0x0
+#define VF610_PAD_PTD18__DCU1_G0 0x130 0x000 ALT7 0x0
+#define VF610_PAD_PTD17__GPIO_77 0x134 0x000 ALT0 0x0
+#define VF610_PAD_PTD17__FB_AD17 0x134 0x000 ALT1 0x0
+#define VF610_PAD_PTD17__NF_IO1 0x134 0x000 ALT2 0x0
+#define VF610_PAD_PTD17__ESAI_HCKR 0x134 0x000 ALT3 0x0
+#define VF610_PAD_PTD17__I2C1_SCL 0x134 0x344 ALT4 0x2
+#define VF610_PAD_PTD17__DCU1_G1 0x134 0x000 ALT7 0x0
+#define VF610_PAD_PTD16__GPIO_78 0x138 0x000 ALT0 0x0
+#define VF610_PAD_PTD16__FB_AD16 0x138 0x000 ALT1 0x0
+#define VF610_PAD_PTD16__NF_IO0 0x138 0x000 ALT2 0x0
+#define VF610_PAD_PTD16__ESAI_HCKT 0x138 0x000 ALT3 0x0
+#define VF610_PAD_PTD16__I2C1_SDA 0x138 0x348 ALT4 0x2
+#define VF610_PAD_PTD16__DCU1_G2 0x138 0x000 ALT7 0x0
+#define VF610_PAD_PTD0__GPIO_79 0x13C 0x000 ALT0 0x0
+#define VF610_PAD_PTD0__QSPI0_A_QSCK 0x13C 0x000 ALT1 0x0
+#define VF610_PAD_PTD0__UART2_TX 0x13C 0x38C ALT2 0x2
+#define VF610_PAD_PTD0__FB_AD15 0x13C 0x000 ALT4 0x0
+#define VF610_PAD_PTD0__SPDIF_EXTCLK 0x13C 0x000 ALT5 0x0
+#define VF610_PAD_PTD0__DEBUG_OUT17 0x13C 0x000 ALT7 0x0
+#define VF610_PAD_PTD1__GPIO_80 0x140 0x000 ALT0 0x0
+#define VF610_PAD_PTD1__QSPI0_A_CS0 0x140 0x000 ALT1 0x0
+#define VF610_PAD_PTD1__UART2_RX 0x140 0x388 ALT2 0x2
+#define VF610_PAD_PTD1__FB_AD14 0x140 0x000 ALT4 0x0
+#define VF610_PAD_PTD1__SPDIF_IN1 0x140 0x000 ALT5 0x0
+#define VF610_PAD_PTD1__DEBUG_OUT18 0x140 0x000 ALT7 0x0
+#define VF610_PAD_PTD2__GPIO_81 0x144 0x000 ALT0 0x0
+#define VF610_PAD_PTD2__QSPI0_A_DATA3 0x144 0x000 ALT1 0x0
+#define VF610_PAD_PTD2__UART2_RTS 0x144 0x000 ALT2 0x0
+#define VF610_PAD_PTD2__DSPI1_CS3 0x144 0x000 ALT3 0x0
+#define VF610_PAD_PTD2__FB_AD13 0x144 0x000 ALT4 0x0
+#define VF610_PAD_PTD2__SPDIF_OUT1 0x144 0x000 ALT5 0x0
+#define VF610_PAD_PTD2__DEBUG_OUT19 0x144 0x000 ALT7 0x0
+#define VF610_PAD_PTD3__GPIO_82 0x148 0x000 ALT0 0x0
+#define VF610_PAD_PTD3__QSPI0_A_DATA2 0x148 0x000 ALT1 0x0
+#define VF610_PAD_PTD3__UART2_CTS 0x148 0x384 ALT2 0x1
+#define VF610_PAD_PTD3__DSPI1_CS2 0x148 0x000 ALT3 0x0
+#define VF610_PAD_PTD3__FB_AD12 0x148 0x000 ALT4 0x0
+#define VF610_PAD_PTD3__SPDIF_PLOCK 0x148 0x000 ALT5 0x0
+#define VF610_PAD_PTD3__DEBUG_OUT20 0x148 0x000 ALT7 0x0
+#define VF610_PAD_PTD4__GPIO_83 0x14C 0x000 ALT0 0x0
+#define VF610_PAD_PTD4__QSPI0_A_DATA1 0x14C 0x000 ALT1 0x0
+#define VF610_PAD_PTD4__DSPI1_CS1 0x14C 0x000 ALT3 0x0
+#define VF610_PAD_PTD4__FB_AD11 0x14C 0x000 ALT4 0x0
+#define VF610_PAD_PTD4__SPDIF_SRCLK 0x14C 0x000 ALT5 0x0
+#define VF610_PAD_PTD4__DEBUG_OUT21 0x14C 0x000 ALT7 0x0
+#define VF610_PAD_PTD5__GPIO_84 0x150 0x000 ALT0 0x0
+#define VF610_PAD_PTD5__QSPI0_A_DATA0 0x150 0x000 ALT1 0x0
+#define VF610_PAD_PTD5__DSPI1_CS0 0x150 0x300 ALT3 0x1
+#define VF610_PAD_PTD5__FB_AD10 0x150 0x000 ALT4 0x0
+#define VF610_PAD_PTD5__DEBUG_OUT22 0x150 0x000 ALT7 0x0
+#define VF610_PAD_PTD6__GPIO_85 0x154 0x000 ALT0 0x0
+#define VF610_PAD_PTD6__QSPI1_A_DQS 0x154 0x000 ALT1 0x0
+#define VF610_PAD_PTD6__DSPI1_SIN 0x154 0x2FC ALT3 0x1
+#define VF610_PAD_PTD6__FB_AD9 0x154 0x000 ALT4 0x0
+#define VF610_PAD_PTD6__DEBUG_OUT23 0x154 0x000 ALT7 0x0
+#define VF610_PAD_PTD7__GPIO_86 0x158 0x000 ALT0 0x0
+#define VF610_PAD_PTD7__QSPI0_B_QSCK 0x158 0x000 ALT1 0x0
+#define VF610_PAD_PTD7__DSPI1_SOUT 0x158 0x000 ALT3 0x0
+#define VF610_PAD_PTD7__FB_AD8 0x158 0x000 ALT4 0x0
+#define VF610_PAD_PTD7__DEBUG_OUT24 0x158 0x000 ALT7 0x0
+#define VF610_PAD_PTD8__GPIO_87 0x15C 0x000 ALT0 0x0
+#define VF610_PAD_PTD8__QSPI0_B_CS0 0x15C 0x000 ALT1 0x0
+#define VF610_PAD_PTD8__FB_CLKOUT 0x15C 0x000 ALT2 0x0
+#define VF610_PAD_PTD8__DSPI1_SCK 0x15C 0x2F8 ALT3 0x1
+#define VF610_PAD_PTD8__FB_AD7 0x15C 0x000 ALT4 0x0
+#define VF610_PAD_PTD8__DEBUG_OUT25 0x15C 0x000 ALT7 0x0
+#define VF610_PAD_PTD9__GPIO_88 0x160 0x000 ALT0 0x0
+#define VF610_PAD_PTD9__QSPI0_B_DATA3 0x160 0x000 ALT1 0x0
+#define VF610_PAD_PTD9__DSPI3_CS1 0x160 0x000 ALT2 0x0
+#define VF610_PAD_PTD9__FB_AD6 0x160 0x000 ALT4 0x0
+#define VF610_PAD_PTD9__SAI1_TX_SYNC 0x160 0x360 ALT6 0x0
+#define VF610_PAD_PTD9__DCU1_B0 0x160 0x000 ALT7 0x0
+#define VF610_PAD_PTD10__GPIO_89 0x164 0x000 ALT0 0x0
+#define VF610_PAD_PTD10__QSPI0_B_DATA2 0x164 0x000 ALT1 0x0
+#define VF610_PAD_PTD10__DSPI3_CS0 0x164 0x000 ALT2 0x0
+#define VF610_PAD_PTD10__FB_AD5 0x164 0x000 ALT4 0x0
+#define VF610_PAD_PTD10__DCU1_B1 0x164 0x000 ALT7 0x0
+#define VF610_PAD_PTD11__GPIO_90 0x168 0x000 ALT0 0x0
+#define VF610_PAD_PTD11__QSPI0_B_DATA1 0x168 0x000 ALT1 0x0
+#define VF610_PAD_PTD11__DSPI3_SIN 0x168 0x000 ALT2 0x0
+#define VF610_PAD_PTD11__FB_AD4 0x168 0x000 ALT4 0x0
+#define VF610_PAD_PTD11__DEBUG_OUT26 0x168 0x000 ALT7 0x0
+#define VF610_PAD_PTD12__GPIO_91 0x16C 0x000 ALT0 0x0
+#define VF610_PAD_PTD12__QSPI0_B_DATA0 0x16C 0x000 ALT1 0x0
+#define VF610_PAD_PTD12__DSPI3_SOUT 0x16C 0x000 ALT2 0x0
+#define VF610_PAD_PTD12__FB_AD3 0x16C 0x000 ALT4 0x0
+#define VF610_PAD_PTD12__DEBUG_OUT27 0x16C 0x000 ALT7 0x0
+#define VF610_PAD_PTD13__GPIO_92 0x170 0x000 ALT0 0x0
+#define VF610_PAD_PTD13__QSPI0_B_DQS 0x170 0x000 ALT1 0x0
+#define VF610_PAD_PTD13__DSPI3_SCK 0x170 0x000 ALT2 0x0
+#define VF610_PAD_PTD13__FB_AD2 0x170 0x000 ALT4 0x0
+#define VF610_PAD_PTD13__DEBUG_OUT28 0x170 0x000 ALT7 0x0
+#define VF610_PAD_PTB23__GPIO_93 0x174 0x000 ALT0 0x0
+#define VF610_PAD_PTB23__SAI0_TX_BCLK 0x174 0x000 ALT1 0x0
+#define VF610_PAD_PTB23__UART1_TX 0x174 0x380 ALT2 0x2
+#define VF610_PAD_PTB23__SRC_RCON18 0x174 0x398 ALT3 0x1
+#define VF610_PAD_PTB23__FB_MUXED_ALE 0x174 0x000 ALT4 0x0
+#define VF610_PAD_PTB23__FB_TS_B 0x174 0x000 ALT5 0x0
+#define VF610_PAD_PTB23__UART3_RTS 0x174 0x000 ALT6 0x0
+#define VF610_PAD_PTB23__DCU1_G3 0x174 0x000 ALT7 0x0
+#define VF610_PAD_PTB24__GPIO_94 0x178 0x000 ALT0 0x0
+#define VF610_PAD_PTB24__SAI0_RX_BCLK 0x178 0x000 ALT1 0x0
+#define VF610_PAD_PTB24__UART1_RX 0x178 0x37C ALT2 0x2
+#define VF610_PAD_PTB24__SRC_RCON19 0x178 0x39C ALT3 0x1
+#define VF610_PAD_PTB24__FB_MUXED_TSIZ0 0x178 0x000 ALT4 0x0
+#define VF610_PAD_PTB24__NF_WE_B 0x178 0x000 ALT5 0x0
+#define VF610_PAD_PTB24__UART3_CTS 0x178 0x000 ALT6 0x0
+#define VF610_PAD_PTB24__DCU1_G4 0x178 0x000 ALT7 0x0
+#define VF610_PAD_PTB25__GPIO_95 0x17C 0x000 ALT0 0x0
+#define VF610_PAD_PTB25__SAI0_RX_DATA 0x17C 0x000 ALT1 0x0
+#define VF610_PAD_PTB25__UART1_RTS 0x17C 0x000 ALT2 0x0
+#define VF610_PAD_PTB25__SRC_RCON20 0x17C 0x3A0 ALT3 0x1
+#define VF610_PAD_PTB25__FB_CS1_B 0x17C 0x000 ALT4 0x0
+#define VF610_PAD_PTB25__NF_CE0_B 0x17C 0x000 ALT5 0x0
+#define VF610_PAD_PTB25__DCU1_G5 0x17C 0x000 ALT7 0x0
+#define VF610_PAD_PTB26__GPIO_96 0x180 0x000 ALT0 0x0
+#define VF610_PAD_PTB26__SAI0_TX_DATA 0x180 0x000 ALT1 0x0
+#define VF610_PAD_PTB26__UART1_CTS 0x180 0x378 ALT2 0x2
+#define VF610_PAD_PTB26__SRC_RCON21 0x180 0x000 ALT3 0x0
+#define VF610_PAD_PTB26__FB_CS0_B 0x180 0x000 ALT4 0x0
+#define VF610_PAD_PTB26__NF_CE1_B 0x180 0x000 ALT5 0x0
+#define VF610_PAD_PTB26__DCU1_G6 0x180 0x000 ALT7 0x0
+#define VF610_PAD_PTB27__GPIO_97 0x184 0x000 ALT0 0x0
+#define VF610_PAD_PTB27__SAI0_RX_SYNC 0x184 0x000 ALT1 0x0
+#define VF610_PAD_PTB27__SRC_RCON22 0x184 0x000 ALT3 0x0
+#define VF610_PAD_PTB27__FB_OE_B 0x184 0x000 ALT4 0x0
+#define VF610_PAD_PTB27__FB_MUXED_TBST_B 0x184 0x000 ALT5 0x0
+#define VF610_PAD_PTB27__NF_RE_B 0x184 0x000 ALT6 0x0
+#define VF610_PAD_PTB27__DCU1_G7 0x184 0x000 ALT7 0x0
+#define VF610_PAD_PTB28__GPIO_98 0x188 0x000 ALT0 0x0
+#define VF610_PAD_PTB28__SAI0_TX_SYNC 0x188 0x000 ALT1 0x0
+#define VF610_PAD_PTB28__SRC_RCON23 0x188 0x000 ALT3 0x0
+#define VF610_PAD_PTB28__FB_RW_B 0x188 0x000 ALT4 0x0
+#define VF610_PAD_PTB28__DCU1_B6 0x188 0x000 ALT7 0x0
+#define VF610_PAD_PTC26__GPIO_99 0x18C 0x000 ALT0 0x0
+#define VF610_PAD_PTC26__SAI1_TX_BCLK 0x18C 0x000 ALT1 0x0
+#define VF610_PAD_PTC26__DSPI0_CS5 0x18C 0x000 ALT2 0x0
+#define VF610_PAD_PTC26__SRC_RCON24 0x18C 0x000 ALT3 0x0
+#define VF610_PAD_PTC26__FB_TA_B 0x18C 0x000 ALT4 0x0
+#define VF610_PAD_PTC26__NF_RB_B 0x18C 0x000 ALT5 0x0
+#define VF610_PAD_PTC26__DCU1_B7 0x18C 0x000 ALT7 0x0
+#define VF610_PAD_PTC27__GPIO_100 0x190 0x000 ALT0 0x0
+#define VF610_PAD_PTC27__SAI1_RX_BCLK 0x190 0x000 ALT1 0x0
+#define VF610_PAD_PTC27__DSPI0_CS4 0x190 0x000 ALT2 0x0
+#define VF610_PAD_PTC27__SRC_RCON25 0x190 0x000 ALT3 0x0
+#define VF610_PAD_PTC27__FB_BE3_B 0x190 0x000 ALT4 0x0
+#define VF610_PAD_PTC27__FB_CS3_B 0x190 0x000 ALT5 0x0
+#define VF610_PAD_PTC27__NF_ALE 0x190 0x000 ALT6 0x0
+#define VF610_PAD_PTC27__DCU1_B2 0x190 0x000 ALT7 0x0
+#define VF610_PAD_PTC28__GPIO_101 0x194 0x000 ALT0 0x0
+#define VF610_PAD_PTC28__SAI1_RX_DATA 0x194 0x000 ALT1 0x0
+#define VF610_PAD_PTC28__DSPI0_CS3 0x194 0x000 ALT2 0x0
+#define VF610_PAD_PTC28__SRC_RCON26 0x194 0x000 ALT3 0x0
+#define VF610_PAD_PTC28__FB_BE2_B 0x194 0x000 ALT4 0x0
+#define VF610_PAD_PTC28__FB_CS2_B 0x194 0x000 ALT5 0x0
+#define VF610_PAD_PTC28__NF_CLE 0x194 0x000 ALT6 0x0
+#define VF610_PAD_PTC28__DCU1_B3 0x194 0x000 ALT7 0x0
+#define VF610_PAD_PTC29__GPIO_102 0x198 0x000 ALT0 0x0
+#define VF610_PAD_PTC29__SAI1_TX_DATA 0x198 0x000 ALT1 0x0
+#define VF610_PAD_PTC29__DSPI0_CS2 0x198 0x000 ALT2 0x0
+#define VF610_PAD_PTC29__SRC_RCON27 0x198 0x000 ALT3 0x0
+#define VF610_PAD_PTC29__FB_BE1_B 0x198 0x000 ALT4 0x0
+#define VF610_PAD_PTC29__FB_MUXED_TSIZE1 0x198 0x000 ALT5 0x0
+#define VF610_PAD_PTC29__DCU1_B4 0x198 0x000 ALT7 0x0
+#define VF610_PAD_PTC30__GPIO_103 0x19C 0x000 ALT0 0x0
+#define VF610_PAD_PTC30__SAI1_RX_SYNC 0x19C 0x000 ALT1 0x0
+#define VF610_PAD_PTC30__DSPI1_CS2 0x19C 0x000 ALT2 0x0
+#define VF610_PAD_PTC30__SRC_RCON28 0x19C 0x000 ALT3 0x0
+#define VF610_PAD_PTC30__FB_MUXED_BE0_B 0x19C 0x000 ALT4 0x0
+#define VF610_PAD_PTC30__FB_TSIZ0 0x19C 0x000 ALT5 0x0
+#define VF610_PAD_PTC30__ADC0_SE5 0x19C 0x000 ALT6 0x0
+#define VF610_PAD_PTC30__DCU1_B5 0x19C 0x000 ALT7 0x0
+#define VF610_PAD_PTC31__GPIO_104 0x1A0 0x000 ALT0 0x0
+#define VF610_PAD_PTC31__SAI1_TX_SYNC 0x1A0 0x360 ALT1 0x1
+#define VF610_PAD_PTC31__SRC_RCON29 0x1A0 0x000 ALT3 0x0
+#define VF610_PAD_PTC31__ADC1_SE5 0x1A0 0x000 ALT6 0x0
+#define VF610_PAD_PTC31__DCU1_B6 0x1A0 0x000 ALT7 0x0
+#define VF610_PAD_PTE0__GPIO_105 0x1A4 0x000 ALT0 0x0
+#define VF610_PAD_PTE0__DCU0_HSYNC 0x1A4 0x000 ALT1 0x0
+#define VF610_PAD_PTE0__SRC_BMODE1 0x1A4 0x000 ALT2 0x0
+#define VF610_PAD_PTE0__LCD0 0x1A4 0x000 ALT4 0x0
+#define VF610_PAD_PTE0__DEBUG_OUT29 0x1A4 0x000 ALT7 0x0
+#define VF610_PAD_PTE1__GPIO_106 0x1A8 0x000 ALT0 0x0
+#define VF610_PAD_PTE1__DCU0_VSYNC 0x1A8 0x000 ALT1 0x0
+#define VF610_PAD_PTE1__SRC_BMODE0 0x1A8 0x000 ALT2 0x0
+#define VF610_PAD_PTE1__LCD1 0x1A8 0x000 ALT4 0x0
+#define VF610_PAD_PTE1__DEBUG_OUT30 0x1A8 0x000 ALT7 0x0
+#define VF610_PAD_PTE2__GPIO_107 0x1AC 0x000 ALT0 0x0
+#define VF610_PAD_PTE2__DCU0_PCLK 0x1AC 0x000 ALT1 0x0
+#define VF610_PAD_PTE2__LCD2 0x1AC 0x000 ALT4 0x0
+#define VF610_PAD_PTE2__DEBUG_OUT31 0x1AC 0x000 ALT7 0x0
+#define VF610_PAD_PTE3__GPIO_108 0x1B0 0x000 ALT0 0x0
+#define VF610_PAD_PTE3__DCU0_TAG 0x1B0 0x000 ALT1 0x0
+#define VF610_PAD_PTE3__LCD3 0x1B0 0x000 ALT4 0x0
+#define VF610_PAD_PTE3__DEBUG_OUT32 0x1B0 0x000 ALT7 0x0
+#define VF610_PAD_PTE4__GPIO_109 0x1B4 0x000 ALT0 0x0
+#define VF610_PAD_PTE4__DCU0_DE 0x1B4 0x000 ALT1 0x0
+#define VF610_PAD_PTE4__LCD4 0x1B4 0x000 ALT4 0x0
+#define VF610_PAD_PTE4__DEBUG_OUT33 0x1B4 0x000 ALT7 0x0
+#define VF610_PAD_PTE5__GPIO_110 0x1B8 0x000 ALT0 0x0
+#define VF610_PAD_PTE5__DCU0_R0 0x1B8 0x000 ALT1 0x0
+#define VF610_PAD_PTE5__LCD5 0x1B8 0x000 ALT4 0x0
+#define VF610_PAD_PTE5__DEBUG_OUT34 0x1B8 0x000 ALT7 0x0
+#define VF610_PAD_PTE6__GPIO_111 0x1BC 0x000 ALT0 0x0
+#define VF610_PAD_PTE6__DCU0_R1 0x1BC 0x000 ALT1 0x0
+#define VF610_PAD_PTE6__LCD6 0x1BC 0x000 ALT4 0x0
+#define VF610_PAD_PTE6__DEBUG_OUT35 0x1BC 0x000 ALT7 0x0
+#define VF610_PAD_PTE7__GPIO_112 0x1C0 0x000 ALT0 0x0
+#define VF610_PAD_PTE7__DCU0_R2 0x1C0 0x000 ALT1 0x0
+#define VF610_PAD_PTE7__SRC_RCON0 0x1C0 0x000 ALT3 0x0
+#define VF610_PAD_PTE7__LCD7 0x1C0 0x000 ALT4 0x0
+#define VF610_PAD_PTE7__DEBUG_OUT36 0x1C0 0x000 ALT7 0x0
+#define VF610_PAD_PTE8__GPIO_113 0x1C4 0x000 ALT0 0x0
+#define VF610_PAD_PTE8__DCU0_R3 0x1C4 0x000 ALT1 0x0
+#define VF610_PAD_PTE8__SRC_RCON1 0x1C4 0x000 ALT3 0x0
+#define VF610_PAD_PTE8__LCD8 0x1C4 0x000 ALT4 0x0
+#define VF610_PAD_PTE8__DEBUG_OUT37 0x1C4 0x000 ALT7 0x0
+#define VF610_PAD_PTE9__GPIO_114 0x1C8 0x000 ALT0 0x0
+#define VF610_PAD_PTE9__DCU0_R4 0x1C8 0x000 ALT1 0x0
+#define VF610_PAD_PTE9__SRC_RCON2 0x1C8 0x000 ALT3 0x0
+#define VF610_PAD_PTE9__LCD9 0x1C8 0x000 ALT4 0x0
+#define VF610_PAD_PTE9__DEBUG_OUT38 0x1C8 0x000 ALT7 0x0
+#define VF610_PAD_PTE10__GPIO_115 0x1CC 0x000 ALT0 0x0
+#define VF610_PAD_PTE10__DCU0_R5 0x1CC 0x000 ALT1 0x0
+#define VF610_PAD_PTE10__SRC_RCON3 0x1CC 0x000 ALT3 0x0
+#define VF610_PAD_PTE10__LCD10 0x1CC 0x000 ALT4 0x0
+#define VF610_PAD_PTE10__DEBUG_OUT39 0x1CC 0x000 ALT7 0x0
+#define VF610_PAD_PTE11__GPIO_116 0x1D0 0x000 ALT0 0x0
+#define VF610_PAD_PTE11__DCU0_R6 0x1D0 0x000 ALT1 0x0
+#define VF610_PAD_PTE11__SRC_RCON4 0x1D0 0x000 ALT3 0x0
+#define VF610_PAD_PTE11__LCD11 0x1D0 0x000 ALT4 0x0
+#define VF610_PAD_PTE11__DEBUG_OUT40 0x1D0 0x000 ALT7 0x0
+#define VF610_PAD_PTE12__GPIO_117 0x1D4 0x000 ALT0 0x0
+#define VF610_PAD_PTE12__DCU0_R7 0x1D4 0x000 ALT1 0x0
+#define VF610_PAD_PTE12__DSPI1_CS3 0x1D4 0x000 ALT2 0x0
+#define VF610_PAD_PTE12__SRC_RCON5 0x1D4 0x000 ALT3 0x0
+#define VF610_PAD_PTE12__LCD12 0x1D4 0x000 ALT4 0x0
+#define VF610_PAD_PTE12__LPT_ALT0 0x1D4 0x000 ALT7 0x0
+#define VF610_PAD_PTE13__GPIO_118 0x1D8 0x000 ALT0 0x0
+#define VF610_PAD_PTE13__DCU0_G0 0x1D8 0x000 ALT1 0x0
+#define VF610_PAD_PTE13__LCD13 0x1D8 0x000 ALT4 0x0
+#define VF610_PAD_PTE13__DEBUG_OUT41 0x1D8 0x000 ALT7 0x0
+#define VF610_PAD_PTE14__GPIO_119 0x1DC 0x000 ALT0 0x0
+#define VF610_PAD_PTE14__DCU0_G1 0x1DC 0x000 ALT1 0x0
+#define VF610_PAD_PTE14__LCD14 0x1DC 0x000 ALT4 0x0
+#define VF610_PAD_PTE14__DEBUG_OUT42 0x1DC 0x000 ALT7 0x0
+#define VF610_PAD_PTE15__GPIO_120 0x1E0 0x000 ALT0 0x0
+#define VF610_PAD_PTE15__DCU0_G2 0x1E0 0x000 ALT1 0x0
+#define VF610_PAD_PTE15__SRC_RCON6 0x1E0 0x000 ALT3 0x0
+#define VF610_PAD_PTE15__LCD15 0x1E0 0x000 ALT4 0x0
+#define VF610_PAD_PTE15__DEBUG_OUT43 0x1E0 0x000 ALT7 0x0
+#define VF610_PAD_PTE16__GPIO_121 0x1E4 0x000 ALT0 0x0
+#define VF610_PAD_PTE16__DCU0_G3 0x1E4 0x000 ALT1 0x0
+#define VF610_PAD_PTE16__SRC_RCON7 0x1E4 0x000 ALT3 0x0
+#define VF610_PAD_PTE16__LCD16 0x1E4 0x000 ALT4 0x0
+#define VF610_PAD_PTE17__GPIO_122 0x1E8 0x000 ALT0 0x0
+#define VF610_PAD_PTE17__DCU0_G4 0x1E8 0x000 ALT1 0x0
+#define VF610_PAD_PTE17__SRC_RCON8 0x1E8 0x000 ALT3 0x0
+#define VF610_PAD_PTE17__LCD17 0x1E8 0x000 ALT4 0x0
+#define VF610_PAD_PTE18__GPIO_123 0x1EC 0x000 ALT0 0x0
+#define VF610_PAD_PTE18__DCU0_G5 0x1EC 0x000 ALT1 0x0
+#define VF610_PAD_PTE18__SRC_RCON9 0x1EC 0x000 ALT3 0x0
+#define VF610_PAD_PTE18__LCD18 0x1EC 0x000 ALT4 0x0
+#define VF610_PAD_PTE19__GPIO_124 0x1F0 0x000 ALT0 0x0
+#define VF610_PAD_PTE19__DCU0_G6 0x1F0 0x000 ALT1 0x0
+#define VF610_PAD_PTE19__SRC_RCON10 0x1F0 0x000 ALT3 0x0
+#define VF610_PAD_PTE19__LCD19 0x1F0 0x000 ALT4 0x0
+#define VF610_PAD_PTE19__I2C0_SCL 0x1F0 0x33C ALT5 0x3
+#define VF610_PAD_PTE20__GPIO_125 0x1F4 0x000 ALT0 0x0
+#define VF610_PAD_PTE20__DCU0_G7 0x1F4 0x000 ALT1 0x0
+#define VF610_PAD_PTE20__SRC_RCON11 0x1F4 0x000 ALT3 0x0
+#define VF610_PAD_PTE20__LCD20 0x1F4 0x000 ALT4 0x0
+#define VF610_PAD_PTE20__I2C0_SDA 0x1F4 0x340 ALT5 0x3
+#define VF610_PAD_PTE20__EWM_IN 0x1F4 0x000 ALT7 0x0
+#define VF610_PAD_PTE21__GPIO_126 0x1F8 0x000 ALT0 0x0
+#define VF610_PAD_PTE21__DCU0_B0 0x1F8 0x000 ALT1 0x0
+#define VF610_PAD_PTE21__LCD21 0x1F8 0x000 ALT4 0x0
+#define VF610_PAD_PTE22__GPIO_127 0x1FC 0x000 ALT0 0x0
+#define VF610_PAD_PTE22__DCU0_B1 0x1FC 0x000 ALT1 0x0
+#define VF610_PAD_PTE22__LCD22 0x1FC 0x000 ALT4 0x0
+#define VF610_PAD_PTE23__GPIO_128 0x200 0x000 ALT0 0x0
+#define VF610_PAD_PTE23__DCU0_B2 0x200 0x000 ALT1 0x0
+#define VF610_PAD_PTE23__SRC_RCON12 0x200 0x000 ALT3 0x0
+#define VF610_PAD_PTE23__LCD23 0x200 0x000 ALT4 0x0
+#define VF610_PAD_PTE24__GPIO_129 0x204 0x000 ALT0 0x0
+#define VF610_PAD_PTE24__DCU0_B3 0x204 0x000 ALT1 0x0
+#define VF610_PAD_PTE24__SRC_RCON13 0x204 0x000 ALT3 0x0
+#define VF610_PAD_PTE24__LCD24 0x204 0x000 ALT4 0x0
+#define VF610_PAD_PTE25__GPIO_130 0x208 0x000 ALT0 0x0
+#define VF610_PAD_PTE25__DCU0_B4 0x208 0x000 ALT1 0x0
+#define VF610_PAD_PTE25__SRC_RCON14 0x208 0x000 ALT3 0x0
+#define VF610_PAD_PTE25__LCD25 0x208 0x000 ALT4 0x0
+#define VF610_PAD_PTE26__GPIO_131 0x20C 0x000 ALT0 0x0
+#define VF610_PAD_PTE26__DCU0_B5 0x20C 0x000 ALT1 0x0
+#define VF610_PAD_PTE26__SRC_RCON15 0x20C 0x000 ALT3 0x0
+#define VF610_PAD_PTE26__LCD26 0x20C 0x000 ALT4 0x0
+#define VF610_PAD_PTE27__GPIO_132 0x210 0x000 ALT0 0x0
+#define VF610_PAD_PTE27__DCU0_B6 0x210 0x000 ALT1 0x0
+#define VF610_PAD_PTE27__SRC_RCON16 0x210 0x000 ALT3 0x0
+#define VF610_PAD_PTE27__LCD27 0x210 0x000 ALT4 0x0
+#define VF610_PAD_PTE27__I2C1_SCL 0x210 0x344 ALT5 0x3
+#define VF610_PAD_PTE28__GPIO_133 0x214 0x000 ALT0 0x0
+#define VF610_PAD_PTE28__DCU0_B7 0x214 0x000 ALT1 0x0
+#define VF610_PAD_PTE28__SRC_RCON17 0x214 0x000 ALT3 0x0
+#define VF610_PAD_PTE28__LCD28 0x214 0x000 ALT4 0x0
+#define VF610_PAD_PTE28__I2C1_SDA 0x214 0x348 ALT5 0x3
+#define VF610_PAD_PTE28__EWM_OUT 0x214 0x000 ALT7 0x0
+#define VF610_PAD_PTA7__GPIO_134 0x218 0x000 ALT0 0x0
+#define VF610_PAD_PTA7__VIU_PIX_CLK 0x218 0x3AC ALT1 0x1
+
+#endif
diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts
new file mode 100644
index 000000000..f64fddce3
--- /dev/null
+++ b/arch/arm/boot/dts/vf610-twr.dts
@@ -0,0 +1,326 @@
+/*
+ * Copyright 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.
+ */
+
+/dts-v1/;
+#include "vf610.dtsi"
+
+/ {
+ model = "VF610 Tower Board";
+ compatible = "fsl,vf610-twr", "fsl,vf610";
+
+ chosen {
+ bootargs = "console=ttyLP1,115200";
+ };
+
+ memory {
+ reg = <0x80000000 0x8000000>;
+ };
+
+ audio_ext: mclk_osc {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24576000>;
+ };
+
+ enet_ext: eth_osc {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <50000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_3p3v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_vcc_3v3_mcu: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "vcc_3v3_mcu";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,widgets =
+ "Microphone", "Microphone Jack",
+ "Headphone", "Headphone Jack",
+ "Speaker", "Speaker Ext",
+ "Line", "Line In Jack";
+ simple-audio-card,routing =
+ "MIC_IN", "Microphone Jack",
+ "Microphone Jack", "Mic Bias",
+ "LINE_IN", "Line In Jack",
+ "Headphone Jack", "HP_OUT",
+ "Speaker Ext", "LINE_OUT";
+
+ simple-audio-card,cpu {
+ sound-dai = <&sai2>;
+ frame-master;
+ bitclock-master;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&codec>;
+ frame-master;
+ bitclock-master;
+ };
+ };
+};
+
+&adc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0_ad5>;
+ vref-supply = <&reg_vcc_3v3_mcu>;
+ status = "okay";
+};
+
+&clks {
+ clocks = <&sxosc>, <&fxosc>, <&enet_ext>, <&audio_ext>;
+ clock-names = "sxosc", "fxosc", "enet_ext", "audio_ext";
+};
+
+&dspi0 {
+ bus-num = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dspi0>;
+ status = "okay";
+
+ sflash: at26df081a@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at26df081a";
+ spi-max-frequency = <16000000>;
+ spi-cpol;
+ spi-cpha;
+ reg = <0>;
+ };
+};
+
+&edma0 {
+ status = "okay";
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ bus-width = <4>;
+ cd-gpios = <&gpio4 6 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&fec0 {
+ phy-mode = "rmii";
+ phy-handle = <&ethphy0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec0>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+};
+
+&fec1 {
+ phy-mode = "rmii";
+ phy-handle = <&ethphy1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ status = "okay";
+};
+
+&i2c0 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ status = "okay";
+
+ codec: sgtl5000@0a {
+ #sound-dai-cells = <0>;
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ VDDA-supply = <&reg_3p3v>;
+ VDDIO-supply = <&reg_3p3v>;
+ clocks = <&clks VF610_CLK_SAI2>;
+ };
+};
+
+&iomuxc {
+ vf610-twr {
+ pinctrl_adc0_ad5: adc0ad5grp {
+ fsl,pins = <
+ VF610_PAD_PTC30__ADC0_SE5 0xa1
+ >;
+ };
+
+ pinctrl_dspi0: dspi0grp {
+ fsl,pins = <
+ VF610_PAD_PTB19__DSPI0_CS0 0x1182
+ VF610_PAD_PTB20__DSPI0_SIN 0x1181
+ VF610_PAD_PTB21__DSPI0_SOUT 0x1182
+ VF610_PAD_PTB22__DSPI0_SCK 0x1182
+ >;
+ };
+
+ pinctrl_esdhc1: esdhc1grp {
+ fsl,pins = <
+ VF610_PAD_PTA24__ESDHC1_CLK 0x31ef
+ VF610_PAD_PTA25__ESDHC1_CMD 0x31ef
+ VF610_PAD_PTA26__ESDHC1_DAT0 0x31ef
+ VF610_PAD_PTA27__ESDHC1_DAT1 0x31ef
+ VF610_PAD_PTA28__ESDHC1_DATA2 0x31ef
+ VF610_PAD_PTA29__ESDHC1_DAT3 0x31ef
+ VF610_PAD_PTA7__GPIO_134 0x219d
+ >;
+ };
+
+ pinctrl_fec0: fec0grp {
+ fsl,pins = <
+ VF610_PAD_PTA6__RMII_CLKIN 0x30d1
+ VF610_PAD_PTC0__ENET_RMII0_MDC 0x30d3
+ VF610_PAD_PTC1__ENET_RMII0_MDIO 0x30d1
+ VF610_PAD_PTC2__ENET_RMII0_CRS 0x30d1
+ VF610_PAD_PTC3__ENET_RMII0_RXD1 0x30d1
+ VF610_PAD_PTC4__ENET_RMII0_RXD0 0x30d1
+ VF610_PAD_PTC5__ENET_RMII0_RXER 0x30d1
+ VF610_PAD_PTC6__ENET_RMII0_TXD1 0x30d2
+ VF610_PAD_PTC7__ENET_RMII0_TXD0 0x30d2
+ VF610_PAD_PTC8__ENET_RMII0_TXEN 0x30d2
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ VF610_PAD_PTC9__ENET_RMII1_MDC 0x30d2
+ VF610_PAD_PTC10__ENET_RMII1_MDIO 0x30d3
+ VF610_PAD_PTC11__ENET_RMII1_CRS 0x30d1
+ VF610_PAD_PTC12__ENET_RMII_RXD1 0x30d1
+ VF610_PAD_PTC13__ENET_RMII1_RXD0 0x30d1
+ VF610_PAD_PTC14__ENET_RMII1_RXER 0x30d1
+ VF610_PAD_PTC15__ENET_RMII1_TXD1 0x30d2
+ VF610_PAD_PTC16__ENET_RMII1_TXD0 0x30d2
+ VF610_PAD_PTC17__ENET_RMII1_TXEN 0x30d2
+ >;
+ };
+
+ pinctrl_i2c0: i2c0grp {
+ fsl,pins = <
+ VF610_PAD_PTB14__I2C0_SCL 0x30d3
+ VF610_PAD_PTB15__I2C0_SDA 0x30d3
+ >;
+ };
+
+ pinctrl_pwm0: pwm0grp {
+ fsl,pins = <
+ VF610_PAD_PTB0__FTM0_CH0 0x1582
+ VF610_PAD_PTB1__FTM0_CH1 0x1582
+ VF610_PAD_PTB2__FTM0_CH2 0x1582
+ VF610_PAD_PTB3__FTM0_CH3 0x1582
+ >;
+ };
+
+ pinctrl_sai2: sai2grp {
+ fsl,pins = <
+ VF610_PAD_PTA16__SAI2_TX_BCLK 0x02ed
+ VF610_PAD_PTA18__SAI2_TX_DATA 0x02ee
+ VF610_PAD_PTA19__SAI2_TX_SYNC 0x02ed
+ VF610_PAD_PTA21__SAI2_RX_BCLK 0x02ed
+ VF610_PAD_PTA22__SAI2_RX_DATA 0x02ed
+ VF610_PAD_PTA23__SAI2_RX_SYNC 0x02ed
+ VF610_PAD_PTB18__EXT_AUDIO_MCLK 0x02ed
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ VF610_PAD_PTB4__UART1_TX 0x21a2
+ VF610_PAD_PTB5__UART1_RX 0x21a1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ VF610_PAD_PTB6__UART2_TX 0x21a2
+ VF610_PAD_PTB7__UART2_RX 0x21a1
+ >;
+ };
+ };
+};
+
+&pwm0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm0>;
+ status = "okay";
+};
+
+&sai2 {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&usbdev0 {
+ disable-over-current;
+ status = "okay";
+};
+
+&usbh1 {
+ disable-over-current;
+ status = "okay";
+};
+
+&usbmisc0 {
+ status = "okay";
+};
+
+&usbmisc1 {
+ status = "okay";
+};
+
+&usbphy0 {
+ status = "okay";
+};
+
+&usbphy1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
new file mode 100644
index 000000000..5f8eb1bd7
--- /dev/null
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -0,0 +1,25 @@
+/*
+ * Copyright 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.
+ */
+
+#include "vf500.dtsi"
+
+&a5_cpu {
+ next-level-cache = <&L2>;
+};
+
+&aips0 {
+ L2: l2-cache@40006000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x40006000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ arm,data-latency = <1 1 1>;
+ arm,tag-latency = <2 2 2>;
+ };
+};
diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
new file mode 100644
index 000000000..4aa335166
--- /dev/null
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -0,0 +1,525 @@
+/*
+ * Copyright 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.
+ */
+
+#include "vf610-pinfunc.h"
+#include <dt-bindings/clock/vf610-clock.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ aliases {
+ can0 = &can0;
+ can1 = &can1;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ serial5 = &uart5;
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ gpio3 = &gpio3;
+ gpio4 = &gpio4;
+ usbphy0 = &usbphy0;
+ usbphy1 = &usbphy1;
+ };
+
+ fxosc: fxosc {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
+
+ sxosc: sxosc {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+
+ reboot: syscon-reboot {
+ compatible = "syscon-reboot";
+ regmap = <&src>;
+ offset = <0x0>;
+ mask = <0x1000>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&mscm_ir>;
+ ranges;
+
+ aips0: aips-bus@40000000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ mscm_cpucfg: cpucfg@40001000 {
+ compatible = "fsl,vf610-mscm-cpucfg", "syscon";
+ reg = <0x40001000 0x800>;
+ };
+
+ mscm_ir: interrupt-controller@40001800 {
+ compatible = "fsl,vf610-mscm-ir";
+ reg = <0x40001800 0x400>;
+ fsl,cpucfg = <&mscm_cpucfg>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ edma0: dma-controller@40018000 {
+ #dma-cells = <2>;
+ compatible = "fsl,vf610-edma";
+ reg = <0x40018000 0x2000>,
+ <0x40024000 0x1000>,
+ <0x40025000 0x1000>;
+ dma-channels = <32>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>,
+ <9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma-tx", "edma-err";
+ clock-names = "dmamux0", "dmamux1";
+ clocks = <&clks VF610_CLK_DMAMUX0>,
+ <&clks VF610_CLK_DMAMUX1>;
+ status = "disabled";
+ };
+
+ can0: flexcan@40020000 {
+ compatible = "fsl,vf610-flexcan";
+ reg = <0x40020000 0x4000>;
+ interrupts = <58 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_FLEXCAN0>,
+ <&clks VF610_CLK_FLEXCAN0>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart0: serial@40027000 {
+ compatible = "fsl,vf610-lpuart";
+ reg = <0x40027000 0x1000>;
+ interrupts = <61 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_UART0>;
+ clock-names = "ipg";
+ dmas = <&edma0 0 2>,
+ <&edma0 0 3>;
+ dma-names = "rx","tx";
+ status = "disabled";
+ };
+
+ uart1: serial@40028000 {
+ compatible = "fsl,vf610-lpuart";
+ reg = <0x40028000 0x1000>;
+ interrupts = <62 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_UART1>;
+ clock-names = "ipg";
+ dmas = <&edma0 0 4>,
+ <&edma0 0 5>;
+ dma-names = "rx","tx";
+ status = "disabled";
+ };
+
+ uart2: serial@40029000 {
+ compatible = "fsl,vf610-lpuart";
+ reg = <0x40029000 0x1000>;
+ interrupts = <63 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_UART2>;
+ clock-names = "ipg";
+ dmas = <&edma0 0 6>,
+ <&edma0 0 7>;
+ dma-names = "rx","tx";
+ status = "disabled";
+ };
+
+ uart3: serial@4002a000 {
+ compatible = "fsl,vf610-lpuart";
+ reg = <0x4002a000 0x1000>;
+ interrupts = <64 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_UART3>;
+ clock-names = "ipg";
+ dmas = <&edma0 0 8>,
+ <&edma0 0 9>;
+ dma-names = "rx","tx";
+ status = "disabled";
+ };
+
+ dspi0: dspi0@4002c000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,vf610-dspi";
+ reg = <0x4002c000 0x1000>;
+ interrupts = <67 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_DSPI0>;
+ clock-names = "dspi";
+ spi-num-chipselects = <5>;
+ status = "disabled";
+ };
+
+ dspi1: dspi1@4002d000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,vf610-dspi";
+ reg = <0x4002d000 0x1000>;
+ interrupts = <68 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_DSPI1>;
+ clock-names = "dspi";
+ spi-num-chipselects = <5>;
+ status = "disabled";
+ };
+
+ sai2: sai@40031000 {
+ compatible = "fsl,vf610-sai";
+ reg = <0x40031000 0x1000>;
+ interrupts = <86 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_SAI2>;
+ clock-names = "sai";
+ dma-names = "tx", "rx";
+ dmas = <&edma0 0 21>,
+ <&edma0 0 20>;
+ status = "disabled";
+ };
+
+ pit: pit@40037000 {
+ compatible = "fsl,vf610-pit";
+ reg = <0x40037000 0x1000>;
+ interrupts = <39 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_PIT>;
+ clock-names = "pit";
+ };
+
+ pwm0: pwm@40038000 {
+ compatible = "fsl,vf610-ftm-pwm";
+ #pwm-cells = <3>;
+ reg = <0x40038000 0x1000>;
+ clock-names = "ftm_sys", "ftm_ext",
+ "ftm_fix", "ftm_cnt_clk_en";
+ clocks = <&clks VF610_CLK_FTM0>,
+ <&clks VF610_CLK_FTM0_EXT_SEL>,
+ <&clks VF610_CLK_FTM0_FIX_SEL>,
+ <&clks VF610_CLK_FTM0_EXT_FIX_EN>;
+ status = "disabled";
+ };
+
+ pwm1: pwm@40039000 {
+ compatible = "fsl,vf610-ftm-pwm";
+ #pwm-cells = <3>;
+ reg = <0x40039000 0x1000>;
+ clock-names = "ftm_sys", "ftm_ext",
+ "ftm_fix", "ftm_cnt_clk_en";
+ clocks = <&clks VF610_CLK_FTM1>,
+ <&clks VF610_CLK_FTM1_EXT_SEL>,
+ <&clks VF610_CLK_FTM1_FIX_SEL>,
+ <&clks VF610_CLK_FTM1_EXT_FIX_EN>;
+ status = "disabled";
+ };
+
+ adc0: adc@4003b000 {
+ compatible = "fsl,vf610-adc";
+ reg = <0x4003b000 0x1000>;
+ interrupts = <53 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_ADC0>;
+ clock-names = "adc";
+ status = "disabled";
+ };
+
+ wdoga5: wdog@4003e000 {
+ compatible = "fsl,vf610-wdt", "fsl,imx21-wdt";
+ reg = <0x4003e000 0x1000>;
+ interrupts = <20 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_WDT>;
+ clock-names = "wdog";
+ status = "disabled";
+ };
+
+ qspi0: quadspi@40044000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,vf610-qspi";
+ reg = <0x40044000 0x1000>;
+ interrupts = <24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_QSPI0_EN>,
+ <&clks VF610_CLK_QSPI0>;
+ clock-names = "qspi_en", "qspi";
+ status = "disabled";
+ };
+
+ iomuxc: iomuxc@40048000 {
+ compatible = "fsl,vf610-iomuxc";
+ reg = <0x40048000 0x1000>;
+ };
+
+ gpio0: gpio@40049000 {
+ compatible = "fsl,vf610-gpio";
+ reg = <0x40049000 0x1000 0x400ff000 0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <107 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-ranges = <&iomuxc 0 0 32>;
+ };
+
+ gpio1: gpio@4004a000 {
+ compatible = "fsl,vf610-gpio";
+ reg = <0x4004a000 0x1000 0x400ff040 0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <108 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-ranges = <&iomuxc 0 32 32>;
+ };
+
+ gpio2: gpio@4004b000 {
+ compatible = "fsl,vf610-gpio";
+ reg = <0x4004b000 0x1000 0x400ff080 0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <109 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-ranges = <&iomuxc 0 64 32>;
+ };
+
+ gpio3: gpio@4004c000 {
+ compatible = "fsl,vf610-gpio";
+ reg = <0x4004c000 0x1000 0x400ff0c0 0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <110 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-ranges = <&iomuxc 0 96 32>;
+ };
+
+ gpio4: gpio@4004d000 {
+ compatible = "fsl,vf610-gpio";
+ reg = <0x4004d000 0x1000 0x400ff100 0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <111 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-ranges = <&iomuxc 0 128 7>;
+ };
+
+ anatop: anatop@40050000 {
+ compatible = "fsl,vf610-anatop", "syscon";
+ reg = <0x40050000 0x400>;
+ };
+
+ usbphy0: usbphy@40050800 {
+ compatible = "fsl,vf610-usbphy";
+ reg = <0x40050800 0x400>;
+ interrupts = <50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_USBPHY0>;
+ fsl,anatop = <&anatop>;
+ status = "disabled";
+ };
+
+ usbphy1: usbphy@40050c00 {
+ compatible = "fsl,vf610-usbphy";
+ reg = <0x40050c00 0x400>;
+ interrupts = <51 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_USBPHY1>;
+ fsl,anatop = <&anatop>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@40066000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,vf610-i2c";
+ reg = <0x40066000 0x1000>;
+ interrupts = <71 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_I2C0>;
+ clock-names = "ipg";
+ dmas = <&edma0 0 50>,
+ <&edma0 0 51>;
+ dma-names = "rx","tx";
+ status = "disabled";
+ };
+
+ clks: ccm@4006b000 {
+ compatible = "fsl,vf610-ccm";
+ reg = <0x4006b000 0x1000>;
+ clocks = <&sxosc>, <&fxosc>;
+ clock-names = "sxosc", "fxosc";
+ #clock-cells = <1>;
+ };
+
+ usbdev0: usb@40034000 {
+ compatible = "fsl,vf610-usb", "fsl,imx27-usb";
+ reg = <0x40034000 0x800>;
+ interrupts = <75 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_USBC0>;
+ fsl,usbphy = <&usbphy0>;
+ fsl,usbmisc = <&usbmisc0 0>;
+ dr_mode = "peripheral";
+ status = "disabled";
+ };
+
+ usbmisc0: usb@40034800 {
+ #index-cells = <1>;
+ compatible = "fsl,vf610-usbmisc";
+ reg = <0x40034800 0x200>;
+ clocks = <&clks VF610_CLK_USBC0>;
+ status = "disabled";
+ };
+
+ src: src@4006e000 {
+ compatible = "fsl,vf610-src", "syscon";
+ reg = <0x4006e000 0x1000>;
+ interrupts = <96 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ aips1: aips-bus@40080000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ edma1: dma-controller@40098000 {
+ #dma-cells = <2>;
+ compatible = "fsl,vf610-edma";
+ reg = <0x40098000 0x2000>,
+ <0x400a1000 0x1000>,
+ <0x400a2000 0x1000>;
+ dma-channels = <32>;
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH>,
+ <11 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma-tx", "edma-err";
+ clock-names = "dmamux0", "dmamux1";
+ clocks = <&clks VF610_CLK_DMAMUX2>,
+ <&clks VF610_CLK_DMAMUX3>;
+ status = "disabled";
+ };
+
+ snvs0: snvs@400a7000 {
+ compatible = "fsl,sec-v4.0-mon", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x400a7000 0x2000>;
+
+ snvsrtc: snvs-rtc-lp@34 {
+ compatible = "fsl,sec-v4.0-mon-rtc-lp";
+ reg = <0x34 0x58>;
+ interrupts = <100 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_SNVS>;
+ clock-names = "snvs-rtc";
+ };
+ };
+
+ uart4: serial@400a9000 {
+ compatible = "fsl,vf610-lpuart";
+ reg = <0x400a9000 0x1000>;
+ interrupts = <65 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_UART4>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ uart5: serial@400aa000 {
+ compatible = "fsl,vf610-lpuart";
+ reg = <0x400aa000 0x1000>;
+ interrupts = <66 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_UART5>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ adc1: adc@400bb000 {
+ compatible = "fsl,vf610-adc";
+ reg = <0x400bb000 0x1000>;
+ interrupts = <54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_ADC1>;
+ clock-names = "adc";
+ status = "disabled";
+ };
+
+ esdhc1: esdhc@400b2000 {
+ compatible = "fsl,imx53-esdhc";
+ reg = <0x400b2000 0x1000>;
+ interrupts = <28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_IPG_BUS>,
+ <&clks VF610_CLK_PLATFORM_BUS>,
+ <&clks VF610_CLK_ESDHC1>;
+ clock-names = "ipg", "ahb", "per";
+ status = "disabled";
+ };
+
+ usbh1: usb@400b4000 {
+ compatible = "fsl,vf610-usb", "fsl,imx27-usb";
+ reg = <0x400b4000 0x800>;
+ interrupts = <76 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_USBC1>;
+ fsl,usbphy = <&usbphy1>;
+ fsl,usbmisc = <&usbmisc1 0>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usbmisc1: usb@400b4800 {
+ #index-cells = <1>;
+ compatible = "fsl,vf610-usbmisc";
+ reg = <0x400b4800 0x200>;
+ clocks = <&clks VF610_CLK_USBC1>;
+ status = "disabled";
+ };
+
+ ftm: ftm@400b8000 {
+ compatible = "fsl,ftm-timer";
+ reg = <0x400b8000 0x1000 0x400b9000 0x1000>;
+ interrupts = <44 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "ftm-evt", "ftm-src",
+ "ftm-evt-counter-en", "ftm-src-counter-en";
+ clocks = <&clks VF610_CLK_FTM2>,
+ <&clks VF610_CLK_FTM3>,
+ <&clks VF610_CLK_FTM2_EXT_FIX_EN>,
+ <&clks VF610_CLK_FTM3_EXT_FIX_EN>;
+ status = "disabled";
+ };
+
+ fec0: ethernet@400d0000 {
+ compatible = "fsl,mvf600-fec";
+ reg = <0x400d0000 0x1000>;
+ interrupts = <78 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_ENET0>,
+ <&clks VF610_CLK_ENET0>,
+ <&clks VF610_CLK_ENET>;
+ clock-names = "ipg", "ahb", "ptp";
+ status = "disabled";
+ };
+
+ fec1: ethernet@400d1000 {
+ compatible = "fsl,mvf600-fec";
+ reg = <0x400d1000 0x1000>;
+ interrupts = <79 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_ENET1>,
+ <&clks VF610_CLK_ENET1>,
+ <&clks VF610_CLK_ENET>;
+ clock-names = "ipg", "ahb", "ptp";
+ status = "disabled";
+ };
+
+ can1: flexcan@400d4000 {
+ compatible = "fsl,vf610-flexcan";
+ reg = <0x400d4000 0x4000>;
+ interrupts = <59 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_FLEXCAN1>,
+ <&clks VF610_CLK_FLEXCAN1>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/vt8500-bv07.dts b/arch/arm/boot/dts/vt8500-bv07.dts
new file mode 100644
index 000000000..87f33310e
--- /dev/null
+++ b/arch/arm/boot/dts/vt8500-bv07.dts
@@ -0,0 +1,36 @@
+/*
+ * vt8500-bv07.dts - Device tree file for Benign BV07 Netbook
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/dts-v1/;
+/include/ "vt8500.dtsi"
+
+/ {
+ model = "Benign BV07 Netbook";
+};
+
+&fb {
+ bits-per-pixel = <16>;
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: 800x480 {
+ clock-frequency = <0>; /* unused but required */
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <40>;
+ hback-porch = <88>;
+ hsync-len = <0>;
+ vback-porch = <32>;
+ vfront-porch = <11>;
+ vsync-len = <1>;
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/vt8500.dtsi b/arch/arm/boot/dts/vt8500.dtsi
new file mode 100644
index 000000000..1929ad390
--- /dev/null
+++ b/arch/arm/boot/dts/vt8500.dtsi
@@ -0,0 +1,175 @@
+/*
+ * vt8500.dtsi - Device tree file for VIA VT8500 SoC
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "via,vt8500";
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ device_type = "cpu";
+ compatible = "arm,arm926ej-s";
+ };
+ };
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ interrupt-parent = <&intc>;
+
+ intc: interrupt-controller@d8140000 {
+ compatible = "via,vt8500-intc";
+ interrupt-controller;
+ reg = <0xd8140000 0x10000>;
+ #interrupt-cells = <1>;
+ };
+
+ pinctrl: pinctrl@d8110000 {
+ compatible = "via,vt8500-pinctrl";
+ reg = <0xd8110000 0x10000>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pmc@d8130000 {
+ compatible = "via,vt8500-pmc";
+ reg = <0xd8130000 0x1000>;
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ref24: ref24M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ clkuart0: uart0 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x250>;
+ enable-bit = <1>;
+ };
+
+ clkuart1: uart1 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x250>;
+ enable-bit = <2>;
+ };
+
+ clkuart2: uart2 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x250>;
+ enable-bit = <3>;
+ };
+
+ clkuart3: uart3 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x250>;
+ enable-bit = <4>;
+ };
+ };
+ };
+
+ timer@d8130100 {
+ compatible = "via,vt8500-timer";
+ reg = <0xd8130100 0x28>;
+ interrupts = <36>;
+ };
+
+ ehci@d8007900 {
+ compatible = "via,vt8500-ehci";
+ reg = <0xd8007900 0x200>;
+ interrupts = <43>;
+ };
+
+ uhci@d8007b00 {
+ compatible = "platform-uhci";
+ reg = <0xd8007b00 0x200>;
+ interrupts = <43>;
+ };
+
+ fb: fb@d8050800 {
+ compatible = "via,vt8500-fb";
+ reg = <0xd800e400 0x400>;
+ interrupts = <12>;
+ };
+
+ ge_rops@d8050400 {
+ compatible = "wm,prizm-ge-rops";
+ reg = <0xd8050400 0x100>;
+ };
+
+ uart0: serial@d8200000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd8200000 0x1040>;
+ interrupts = <32>;
+ clocks = <&clkuart0>;
+ status = "disabled";
+ };
+
+ uart1: serial@d82b0000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd82b0000 0x1040>;
+ interrupts = <33>;
+ clocks = <&clkuart1>;
+ status = "disabled";
+ };
+
+ uart2: serial@d8210000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd8210000 0x1040>;
+ interrupts = <47>;
+ clocks = <&clkuart2>;
+ status = "disabled";
+ };
+
+ uart3: serial@d82c0000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd82c0000 0x1040>;
+ interrupts = <50>;
+ clocks = <&clkuart3>;
+ status = "disabled";
+ };
+
+ rtc@d8100000 {
+ compatible = "via,vt8500-rtc";
+ reg = <0xd8100000 0x10000>;
+ interrupts = <48>;
+ };
+
+ ethernet@d8004000 {
+ compatible = "via,vt8500-rhine";
+ reg = <0xd8004000 0x100>;
+ interrupts = <10>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/wm8505-ref.dts b/arch/arm/boot/dts/wm8505-ref.dts
new file mode 100644
index 000000000..e3e6b9eb0
--- /dev/null
+++ b/arch/arm/boot/dts/wm8505-ref.dts
@@ -0,0 +1,36 @@
+/*
+ * wm8505-ref.dts - Device tree file for Wondermedia WM8505 reference netbook
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/dts-v1/;
+/include/ "wm8505.dtsi"
+
+/ {
+ model = "Wondermedia WM8505 Netbook";
+};
+
+&fb {
+ bits-per-pixel = <32>;
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: 800x480 {
+ clock-frequency = <0>; /* unused but required */
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <40>;
+ hback-porch = <88>;
+ hsync-len = <0>;
+ vback-porch = <32>;
+ vfront-porch = <11>;
+ vsync-len = <1>;
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/wm8505.dtsi b/arch/arm/boot/dts/wm8505.dtsi
new file mode 100644
index 000000000..a1a854b8a
--- /dev/null
+++ b/arch/arm/boot/dts/wm8505.dtsi
@@ -0,0 +1,290 @@
+/*
+ * wm8505.dtsi - Device tree file for Wondermedia WM8505 SoC
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "wm,wm8505";
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ device_type = "cpu";
+ compatible = "arm,arm926ej-s";
+ };
+ };
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ serial5 = &uart5;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ interrupt-parent = <&intc0>;
+
+ intc0: interrupt-controller@d8140000 {
+ compatible = "via,vt8500-intc";
+ interrupt-controller;
+ reg = <0xd8140000 0x10000>;
+ #interrupt-cells = <1>;
+ };
+
+ /* Secondary IC cascaded to intc0 */
+ intc1: interrupt-controller@d8150000 {
+ compatible = "via,vt8500-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xD8150000 0x10000>;
+ interrupts = <56 57 58 59 60 61 62 63>;
+ };
+
+ pinctrl: pinctrl@d8110000 {
+ compatible = "wm,wm8505-pinctrl";
+ reg = <0xd8110000 0x10000>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pmc@d8130000 {
+ compatible = "via,vt8500-pmc";
+ reg = <0xd8130000 0x1000>;
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ref24: ref24M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ ref25: ref25M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <25000000>;
+ };
+
+ plla: plla {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-pll-clock";
+ clocks = <&ref25>;
+ reg = <0x200>;
+ };
+
+ pllb: pllb {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-pll-clock";
+ clocks = <&ref25>;
+ reg = <0x204>;
+ };
+
+ pllc: pllc {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-pll-clock";
+ clocks = <&ref25>;
+ reg = <0x208>;
+ };
+
+ plld: plld {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-pll-clock";
+ clocks = <&ref25>;
+ reg = <0x20c>;
+ };
+
+ clkarm: arm {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&plla>;
+ divisor-reg = <0x300>;
+ };
+
+ clkahb: ahb {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&pllb>;
+ divisor-reg = <0x304>;
+ };
+
+ clkapb: apb {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&pllb>;
+ divisor-reg = <0x350>;
+ };
+
+ clkddr: ddr {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&plld>;
+ divisor-reg = <0x310>;
+ };
+
+ clkuart0: uart0 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x250>;
+ enable-bit = <1>;
+ };
+
+ clkuart1: uart1 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x250>;
+ enable-bit = <2>;
+ };
+
+ clkuart2: uart2 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x250>;
+ enable-bit = <3>;
+ };
+
+ clkuart3: uart3 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x250>;
+ enable-bit = <4>;
+ };
+
+ clkuart4: uart4 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x250>;
+ enable-bit = <22>;
+ };
+
+ clkuart5: uart5 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x250>;
+ enable-bit = <23>;
+ };
+
+ clksdhc: sdhc {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&pllb>;
+ divisor-reg = <0x328>;
+ divisor-mask = <0x3f>;
+ enable-reg = <0x254>;
+ enable-bit = <18>;
+ };
+ };
+ };
+
+ timer@d8130100 {
+ compatible = "via,vt8500-timer";
+ reg = <0xd8130100 0x28>;
+ interrupts = <36>;
+ };
+
+ ehci@d8007100 {
+ compatible = "via,vt8500-ehci";
+ reg = <0xd8007100 0x200>;
+ interrupts = <1>;
+ };
+
+ uhci@d8007300 {
+ compatible = "platform-uhci";
+ reg = <0xd8007300 0x200>;
+ interrupts = <0>;
+ };
+
+ fb: fb@d8050800 {
+ compatible = "wm,wm8505-fb";
+ reg = <0xd8050800 0x200>;
+ };
+
+ ge_rops@d8050400 {
+ compatible = "wm,prizm-ge-rops";
+ reg = <0xd8050400 0x100>;
+ };
+
+ uart0: serial@d8200000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd8200000 0x1040>;
+ interrupts = <32>;
+ clocks = <&clkuart0>;
+ status = "disabled";
+ };
+
+ uart1: serial@d82b0000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd82b0000 0x1040>;
+ interrupts = <33>;
+ clocks = <&clkuart1>;
+ status = "disabled";
+ };
+
+ uart2: serial@d8210000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd8210000 0x1040>;
+ interrupts = <47>;
+ clocks = <&clkuart2>;
+ status = "disabled";
+ };
+
+ uart3: serial@d82c0000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd82c0000 0x1040>;
+ interrupts = <50>;
+ clocks = <&clkuart3>;
+ status = "disabled";
+ };
+
+ uart4: serial@d8370000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd8370000 0x1040>;
+ interrupts = <31>;
+ clocks = <&clkuart4>;
+ status = "disabled";
+ };
+
+ uart5: serial@d8380000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd8380000 0x1040>;
+ interrupts = <30>;
+ clocks = <&clkuart5>;
+ status = "disabled";
+ };
+
+ rtc@d8100000 {
+ compatible = "via,vt8500-rtc";
+ reg = <0xd8100000 0x10000>;
+ interrupts = <48>;
+ };
+
+ sdhc@d800a000 {
+ compatible = "wm,wm8505-sdhc";
+ reg = <0xd800a000 0x1000>;
+ interrupts = <20 21>;
+ clocks = <&clksdhc>;
+ bus-width = <4>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/wm8650-mid.dts b/arch/arm/boot/dts/wm8650-mid.dts
new file mode 100644
index 000000000..dd0d1b602
--- /dev/null
+++ b/arch/arm/boot/dts/wm8650-mid.dts
@@ -0,0 +1,37 @@
+/*
+ * wm8650-mid.dts - Device tree file for Wondermedia WM8650-MID Tablet
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/dts-v1/;
+/include/ "wm8650.dtsi"
+
+/ {
+ model = "Wondermedia WM8650-MID Tablet";
+};
+
+&fb {
+ bits-per-pixel = <16>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: 800x480 {
+ clock-frequency = <0>; /* unused but required */
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <40>;
+ hback-porch = <88>;
+ hsync-len = <0>;
+ vback-porch = <32>;
+ vfront-porch = <11>;
+ vsync-len = <1>;
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/wm8650.dtsi b/arch/arm/boot/dts/wm8650.dtsi
new file mode 100644
index 000000000..b1c59a766
--- /dev/null
+++ b/arch/arm/boot/dts/wm8650.dtsi
@@ -0,0 +1,228 @@
+/*
+ * wm8650.dtsi - Device tree file for Wondermedia WM8650 SoC
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "wm,wm8650";
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ device_type = "cpu";
+ compatible = "arm,arm926ej-s";
+ };
+ };
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ interrupt-parent = <&intc0>;
+
+ intc0: interrupt-controller@d8140000 {
+ compatible = "via,vt8500-intc";
+ interrupt-controller;
+ reg = <0xd8140000 0x10000>;
+ #interrupt-cells = <1>;
+ };
+
+ /* Secondary IC cascaded to intc0 */
+ intc1: interrupt-controller@d8150000 {
+ compatible = "via,vt8500-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xD8150000 0x10000>;
+ interrupts = <56 57 58 59 60 61 62 63>;
+ };
+
+ pinctrl: pinctrl@d8110000 {
+ compatible = "wm,wm8650-pinctrl";
+ reg = <0xd8110000 0x10000>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pmc@d8130000 {
+ compatible = "via,vt8500-pmc";
+ reg = <0xd8130000 0x1000>;
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ref25: ref25M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <25000000>;
+ };
+
+ ref24: ref24M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ plla: plla {
+ #clock-cells = <0>;
+ compatible = "wm,wm8650-pll-clock";
+ clocks = <&ref25>;
+ reg = <0x200>;
+ };
+
+ pllb: pllb {
+ #clock-cells = <0>;
+ compatible = "wm,wm8650-pll-clock";
+ clocks = <&ref25>;
+ reg = <0x204>;
+ };
+
+ pllc: pllc {
+ #clock-cells = <0>;
+ compatible = "wm,wm8650-pll-clock";
+ clocks = <&ref25>;
+ reg = <0x208>;
+ };
+
+ plld: plld {
+ #clock-cells = <0>;
+ compatible = "wm,wm8650-pll-clock";
+ clocks = <&ref25>;
+ reg = <0x20c>;
+ };
+
+ plle: plle {
+ #clock-cells = <0>;
+ compatible = "wm,wm8650-pll-clock";
+ clocks = <&ref25>;
+ reg = <0x210>;
+ };
+
+ clkarm: arm {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&plla>;
+ divisor-reg = <0x300>;
+ };
+
+ clkahb: ahb {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&pllb>;
+ divisor-reg = <0x304>;
+ };
+
+ clkapb: apb {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&pllb>;
+ divisor-reg = <0x320>;
+ };
+
+ clkddr: ddr {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&plld>;
+ divisor-reg = <0x310>;
+ };
+
+ clkuart0: uart0 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x250>;
+ enable-bit = <1>;
+ };
+
+ clkuart1: uart1 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x250>;
+ enable-bit = <2>;
+ };
+
+ clksdhc: sdhc {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&pllb>;
+ divisor-reg = <0x328>;
+ divisor-mask = <0x3f>;
+ enable-reg = <0x254>;
+ enable-bit = <18>;
+ };
+ };
+ };
+
+ timer@d8130100 {
+ compatible = "via,vt8500-timer";
+ reg = <0xd8130100 0x28>;
+ interrupts = <36>;
+ };
+
+ ehci@d8007900 {
+ compatible = "via,vt8500-ehci";
+ reg = <0xd8007900 0x200>;
+ interrupts = <43>;
+ };
+
+ uhci@d8007b00 {
+ compatible = "platform-uhci";
+ reg = <0xd8007b00 0x200>;
+ interrupts = <43>;
+ };
+
+ fb: fb@d8050800 {
+ compatible = "wm,wm8505-fb";
+ reg = <0xd8050800 0x200>;
+ };
+
+ ge_rops@d8050400 {
+ compatible = "wm,prizm-ge-rops";
+ reg = <0xd8050400 0x100>;
+ };
+
+ uart0: serial@d8200000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd8200000 0x1040>;
+ interrupts = <32>;
+ clocks = <&clkuart0>;
+ status = "disabled";
+ };
+
+ uart1: serial@d82b0000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd82b0000 0x1040>;
+ interrupts = <33>;
+ clocks = <&clkuart1>;
+ status = "disabled";
+ };
+
+ rtc@d8100000 {
+ compatible = "via,vt8500-rtc";
+ reg = <0xd8100000 0x10000>;
+ interrupts = <48>;
+ };
+
+ ethernet@d8004000 {
+ compatible = "via,vt8500-rhine";
+ reg = <0xd8004000 0x100>;
+ interrupts = <10>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/wm8750-apc8750.dts b/arch/arm/boot/dts/wm8750-apc8750.dts
new file mode 100644
index 000000000..37e4a408b
--- /dev/null
+++ b/arch/arm/boot/dts/wm8750-apc8750.dts
@@ -0,0 +1,30 @@
+/*
+ * wm8750-apc8750.dts
+ * - Device tree file for VIA APC8750
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/dts-v1/;
+/include/ "wm8750.dtsi"
+
+/ {
+ model = "VIA APC8750";
+};
+
+&pinctrl {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c>;
+
+ i2c: i2c {
+ wm,pins = <168 169 170 171>;
+ wm,function = <2>; /* alt */
+ wm,pull = <2>; /* pull-up */
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/wm8750.dtsi b/arch/arm/boot/dts/wm8750.dtsi
new file mode 100644
index 000000000..557a9c2ac
--- /dev/null
+++ b/arch/arm/boot/dts/wm8750.dtsi
@@ -0,0 +1,347 @@
+/*
+ * wm8750.dtsi - Device tree file for Wondermedia WM8750 SoC
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "wm,wm8750";
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ device_type = "cpu";
+ compatible = "arm,arm1176ej-s";
+ };
+ };
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ serial5 = &uart5;
+ i2c0 = &i2c_0;
+ i2c1 = &i2c_1;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ interrupt-parent = <&intc0>;
+
+ intc0: interrupt-controller@d8140000 {
+ compatible = "via,vt8500-intc";
+ interrupt-controller;
+ reg = <0xd8140000 0x10000>;
+ #interrupt-cells = <1>;
+ };
+
+ /* Secondary IC cascaded to intc0 */
+ intc1: interrupt-controller@d8150000 {
+ compatible = "via,vt8500-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xD8150000 0x10000>;
+ interrupts = <56 57 58 59 60 61 62 63>;
+ };
+
+ pinctrl: pinctrl@d8110000 {
+ compatible = "wm,wm8750-pinctrl";
+ reg = <0xd8110000 0x10000>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pmc@d8130000 {
+ compatible = "via,vt8500-pmc";
+ reg = <0xd8130000 0x1000>;
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ref24: ref24M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ ref25: ref25M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <25000000>;
+ };
+
+ plla: plla {
+ #clock-cells = <0>;
+ compatible = "wm,wm8750-pll-clock";
+ clocks = <&ref25>;
+ reg = <0x200>;
+ };
+
+ pllb: pllb {
+ #clock-cells = <0>;
+ compatible = "wm,wm8750-pll-clock";
+ clocks = <&ref25>;
+ reg = <0x204>;
+ };
+
+ pllc: pllc {
+ #clock-cells = <0>;
+ compatible = "wm,wm8750-pll-clock";
+ clocks = <&ref25>;
+ reg = <0x208>;
+ };
+
+ plld: plld {
+ #clock-cells = <0>;
+ compatible = "wm,wm8750-pll-clock";
+ clocks = <&ref25>;
+ reg = <0x20C>;
+ };
+
+ plle: plle {
+ #clock-cells = <0>;
+ compatible = "wm,wm8750-pll-clock";
+ clocks = <&ref25>;
+ reg = <0x210>;
+ };
+
+ clkarm: arm {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&plla>;
+ divisor-reg = <0x300>;
+ };
+
+ clkahb: ahb {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&pllb>;
+ divisor-reg = <0x304>;
+ };
+
+ clkapb: apb {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&pllb>;
+ divisor-reg = <0x320>;
+ };
+
+ clkddr: ddr {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&plld>;
+ divisor-reg = <0x310>;
+ };
+
+ clkuart0: uart0 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x254>;
+ enable-bit = <24>;
+ };
+
+ clkuart1: uart1 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x254>;
+ enable-bit = <25>;
+ };
+
+ clkuart2: uart2 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x254>;
+ enable-bit = <26>;
+ };
+
+ clkuart3: uart3 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x254>;
+ enable-bit = <27>;
+ };
+
+ clkuart4: uart4 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x254>;
+ enable-bit = <28>;
+ };
+
+ clkuart5: uart5 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x254>;
+ enable-bit = <29>;
+ };
+
+ clkpwm: pwm {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&pllb>;
+ divisor-reg = <0x350>;
+ enable-reg = <0x250>;
+ enable-bit = <17>;
+ };
+
+ clksdhc: sdhc {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&pllb>;
+ divisor-reg = <0x330>;
+ divisor-mask = <0x3f>;
+ enable-reg = <0x250>;
+ enable-bit = <0>;
+ };
+
+ clki2c0: i2c0clk {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&pllb>;
+ divisor-reg = <0x3A0>;
+ enable-reg = <0x250>;
+ enable-bit = <8>;
+ };
+
+ clki2c1: i2c1clk {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&pllb>;
+ divisor-reg = <0x3A4>;
+ enable-reg = <0x250>;
+ enable-bit = <9>;
+ };
+ };
+ };
+
+ pwm: pwm@d8220000 {
+ #pwm-cells = <3>;
+ compatible = "via,vt8500-pwm";
+ reg = <0xd8220000 0x100>;
+ clocks = <&clkpwm>;
+ };
+
+ timer@d8130100 {
+ compatible = "via,vt8500-timer";
+ reg = <0xd8130100 0x28>;
+ interrupts = <36>;
+ };
+
+ ehci@d8007900 {
+ compatible = "via,vt8500-ehci";
+ reg = <0xd8007900 0x200>;
+ interrupts = <26>;
+ };
+
+ uhci@d8007b00 {
+ compatible = "platform-uhci";
+ reg = <0xd8007b00 0x200>;
+ interrupts = <26>;
+ };
+
+ uhci@d8008d00 {
+ compatible = "platform-uhci";
+ reg = <0xd8008d00 0x200>;
+ interrupts = <26>;
+ };
+
+ uart0: serial@d8200000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd8200000 0x1040>;
+ interrupts = <32>;
+ clocks = <&clkuart0>;
+ status = "disabled";
+ };
+
+ uart1: serial@d82b0000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd82b0000 0x1040>;
+ interrupts = <33>;
+ clocks = <&clkuart1>;
+ status = "disabled";
+ };
+
+ uart2: serial@d8210000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd8210000 0x1040>;
+ interrupts = <47>;
+ clocks = <&clkuart2>;
+ status = "disabled";
+ };
+
+ uart3: serial@d82c0000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd82c0000 0x1040>;
+ interrupts = <50>;
+ clocks = <&clkuart3>;
+ status = "disabled";
+ };
+
+ uart4: serial@d8370000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd8370000 0x1040>;
+ interrupts = <30>;
+ clocks = <&clkuart4>;
+ status = "disabled";
+ };
+
+ uart5: serial@d8380000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd8380000 0x1040>;
+ interrupts = <43>;
+ clocks = <&clkuart5>;
+ status = "disabled";
+ };
+
+ rtc@d8100000 {
+ compatible = "via,vt8500-rtc";
+ reg = <0xd8100000 0x10000>;
+ interrupts = <48>;
+ };
+
+ sdhc@d800a000 {
+ compatible = "wm,wm8505-sdhc";
+ reg = <0xd800a000 0x1000>;
+ interrupts = <20 21>;
+ clocks = <&clksdhc>;
+ bus-width = <4>;
+ sdon-inverted;
+ };
+
+ i2c_0: i2c@d8280000 {
+ compatible = "wm,wm8505-i2c";
+ reg = <0xd8280000 0x1000>;
+ interrupts = <19>;
+ clocks = <&clki2c0>;
+ clock-frequency = <400000>;
+ };
+
+ i2c_1: i2c@d8320000 {
+ compatible = "wm,wm8505-i2c";
+ reg = <0xd8320000 0x1000>;
+ interrupts = <18>;
+ clocks = <&clki2c1>;
+ clock-frequency = <400000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/wm8850-w70v2.dts b/arch/arm/boot/dts/wm8850-w70v2.dts
new file mode 100644
index 000000000..7a563d252
--- /dev/null
+++ b/arch/arm/boot/dts/wm8850-w70v2.dts
@@ -0,0 +1,48 @@
+/*
+ * wm8850-w70v2.dts
+ * - Device tree file for Wondermedia WM8850 Tablet
+ * - 'W70-V2' mainboard
+ * - HongLianYing 'HLY070ML268-21A' 7" LCD panel
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/dts-v1/;
+/include/ "wm8850.dtsi"
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ model = "Wondermedia WM8850-W70v2 Tablet";
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
+
+ brightness-levels = <0 40 60 80 100 130 190 255>;
+ default-brightness-level = <5>;
+ };
+};
+
+&fb {
+ bits-per-pixel = <16>;
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: 800x480 {
+ clock-frequency = <0>; /* unused but required */
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <40>;
+ hback-porch = <88>;
+ hsync-len = <0>;
+ vback-porch = <32>;
+ vfront-porch = <11>;
+ vsync-len = <1>;
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/wm8850.dtsi b/arch/arm/boot/dts/wm8850.dtsi
new file mode 100644
index 000000000..8fbccfbe7
--- /dev/null
+++ b/arch/arm/boot/dts/wm8850.dtsi
@@ -0,0 +1,308 @@
+/*
+ * wm8850.dtsi - Device tree file for Wondermedia WM8850 SoC
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "wm,wm8850";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0x0>;
+ };
+ };
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ interrupt-parent = <&intc0>;
+
+ intc0: interrupt-controller@d8140000 {
+ compatible = "via,vt8500-intc";
+ interrupt-controller;
+ reg = <0xd8140000 0x10000>;
+ #interrupt-cells = <1>;
+ };
+
+ /* Secondary IC cascaded to intc0 */
+ intc1: interrupt-controller@d8150000 {
+ compatible = "via,vt8500-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xD8150000 0x10000>;
+ interrupts = <56 57 58 59 60 61 62 63>;
+ };
+
+ pinctrl: pinctrl@d8110000 {
+ compatible = "wm,wm8850-pinctrl";
+ reg = <0xd8110000 0x10000>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ pmc@d8130000 {
+ compatible = "via,vt8500-pmc";
+ reg = <0xd8130000 0x1000>;
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ref25: ref25M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <25000000>;
+ };
+
+ ref24: ref24M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ plla: plla {
+ #clock-cells = <0>;
+ compatible = "wm,wm8850-pll-clock";
+ clocks = <&ref24>;
+ reg = <0x200>;
+ };
+
+ pllb: pllb {
+ #clock-cells = <0>;
+ compatible = "wm,wm8850-pll-clock";
+ clocks = <&ref24>;
+ reg = <0x204>;
+ };
+
+ pllc: pllc {
+ #clock-cells = <0>;
+ compatible = "wm,wm8850-pll-clock";
+ clocks = <&ref24>;
+ reg = <0x208>;
+ };
+
+ plld: plld {
+ #clock-cells = <0>;
+ compatible = "wm,wm8850-pll-clock";
+ clocks = <&ref24>;
+ reg = <0x20c>;
+ };
+
+ plle: plle {
+ #clock-cells = <0>;
+ compatible = "wm,wm8850-pll-clock";
+ clocks = <&ref24>;
+ reg = <0x210>;
+ };
+
+ pllf: pllf {
+ #clock-cells = <0>;
+ compatible = "wm,wm8850-pll-clock";
+ clocks = <&ref24>;
+ reg = <0x214>;
+ };
+
+ pllg: pllg {
+ #clock-cells = <0>;
+ compatible = "wm,wm8850-pll-clock";
+ clocks = <&ref24>;
+ reg = <0x218>;
+ };
+
+ clkarm: arm {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&plla>;
+ divisor-reg = <0x300>;
+ };
+
+ clkahb: ahb {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&pllb>;
+ divisor-reg = <0x304>;
+ };
+
+ clkapb: apb {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&pllb>;
+ divisor-reg = <0x320>;
+ };
+
+ clkddr: ddr {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&plld>;
+ divisor-reg = <0x310>;
+ };
+
+ clkuart0: uart0 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x254>;
+ enable-bit = <24>;
+ };
+
+ clkuart1: uart1 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x254>;
+ enable-bit = <25>;
+ };
+
+ clkuart2: uart2 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x254>;
+ enable-bit = <26>;
+ };
+
+ clkuart3: uart3 {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&ref24>;
+ enable-reg = <0x254>;
+ enable-bit = <27>;
+ };
+
+ clkpwm: pwm {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&pllb>;
+ divisor-reg = <0x350>;
+ enable-reg = <0x250>;
+ enable-bit = <17>;
+ };
+
+ clksdhc: sdhc {
+ #clock-cells = <0>;
+ compatible = "via,vt8500-device-clock";
+ clocks = <&pllb>;
+ divisor-reg = <0x330>;
+ divisor-mask = <0x3f>;
+ enable-reg = <0x250>;
+ enable-bit = <0>;
+ };
+ };
+ };
+
+ fb: fb@d8051700 {
+ compatible = "wm,wm8505-fb";
+ reg = <0xd8051700 0x200>;
+ };
+
+ ge_rops@d8050400 {
+ compatible = "wm,prizm-ge-rops";
+ reg = <0xd8050400 0x100>;
+ };
+
+ pwm: pwm@d8220000 {
+ #pwm-cells = <3>;
+ compatible = "via,vt8500-pwm";
+ reg = <0xd8220000 0x100>;
+ clocks = <&clkpwm>;
+ };
+
+ timer@d8130100 {
+ compatible = "via,vt8500-timer";
+ reg = <0xd8130100 0x28>;
+ interrupts = <36>;
+ };
+
+ ehci@d8007900 {
+ compatible = "via,vt8500-ehci";
+ reg = <0xd8007900 0x200>;
+ interrupts = <26>;
+ };
+
+ uhci@d8007b00 {
+ compatible = "platform-uhci";
+ reg = <0xd8007b00 0x200>;
+ interrupts = <26>;
+ };
+
+ uhci@d8008d00 {
+ compatible = "platform-uhci";
+ reg = <0xd8008d00 0x200>;
+ interrupts = <26>;
+ };
+
+ uart0: serial@d8200000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd8200000 0x1040>;
+ interrupts = <32>;
+ clocks = <&clkuart0>;
+ status = "disabled";
+ };
+
+ uart1: serial@d82b0000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd82b0000 0x1040>;
+ interrupts = <33>;
+ clocks = <&clkuart1>;
+ status = "disabled";
+ };
+
+ uart2: serial@d8210000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd8210000 0x1040>;
+ interrupts = <47>;
+ clocks = <&clkuart2>;
+ status = "disabled";
+ };
+
+ uart3: serial@d82c0000 {
+ compatible = "via,vt8500-uart";
+ reg = <0xd82c0000 0x1040>;
+ interrupts = <50>;
+ clocks = <&clkuart3>;
+ status = "disabled";
+ };
+
+ rtc@d8100000 {
+ compatible = "via,vt8500-rtc";
+ reg = <0xd8100000 0x10000>;
+ interrupts = <48>;
+ };
+
+ sdhc@d800a000 {
+ compatible = "wm,wm8505-sdhc";
+ reg = <0xd800a000 0x1000>;
+ interrupts = <20 21>;
+ clocks = <&clksdhc>;
+ bus-width = <4>;
+ sdon-inverted;
+ };
+
+ ethernet@d8004000 {
+ compatible = "via,vt8500-rhine";
+ reg = <0xd8004000 0x100>;
+ interrupts = <10>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/xenvm-4.2.dts b/arch/arm/boot/dts/xenvm-4.2.dts
new file mode 100644
index 000000000..336915151
--- /dev/null
+++ b/arch/arm/boot/dts/xenvm-4.2.dts
@@ -0,0 +1,81 @@
+/*
+ * Xen Virtual Machine for unprivileged guests
+ *
+ * Based on ARM Ltd. Versatile Express CoreTile Express (single CPU)
+ * Cortex-A15 MPCore (V2P-CA15)
+ *
+ */
+
+/dts-v1/;
+
+/ {
+ model = "XENVM-4.2";
+ compatible = "xen,xenvm-4.2", "xen,xenvm";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ chosen {
+ /* this field is going to be adjusted by the hypervisor */
+ bootargs = "console=hvc0 root=/dev/xvda";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <1>;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci";
+ method = "hvc";
+ cpu_off = <1>;
+ cpu_on = <2>;
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ /* this field is going to be adjusted by the hypervisor */
+ reg = <0 0x80000000 0 0x08000000>;
+ };
+
+ gic: interrupt-controller@2c001000 {
+ compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0 0x2c001000 0 0x1000>,
+ <0 0x2c002000 0 0x100>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <1 13 0xf08>,
+ <1 14 0xf08>,
+ <1 11 0xf08>,
+ <1 10 0xf08>;
+ };
+
+ hypervisor {
+ compatible = "xen,xen-4.2", "xen,xen";
+ /* this field is going to be adjusted by the hypervisor */
+ reg = <0 0xb0000000 0 0x20000>;
+ /* this field is going to be adjusted by the hypervisor */
+ interrupts = <1 15 0xf08>;
+ };
+
+ motherboard {
+ arm,v2m-memory-map = "rs1";
+ };
+};
diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi
new file mode 100644
index 000000000..9ea54b3db
--- /dev/null
+++ b/arch/arm/boot/dts/zynq-7000.dtsi
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2011 - 2014 Xilinx
+ *
+ * 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/ "skeleton.dtsi"
+
+/ {
+ compatible = "xlnx,zynq-7000";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0>;
+ clocks = <&clkc 3>;
+ clock-latency = <1000>;
+ cpu0-supply = <&regulator_vccpint>;
+ operating-points = <
+ /* kHz uV */
+ 666667 1000000
+ 333334 1000000
+ >;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <1>;
+ clocks = <&clkc 3>;
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 5 4>, <0 6 4>;
+ interrupt-parent = <&intc>;
+ reg = < 0xf8891000 0x1000 0xf8893000 0x1000 >;
+ };
+
+ regulator_vccpint: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCCPINT";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ amba {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&intc>;
+ ranges;
+
+ adc: adc@f8007100 {
+ compatible = "xlnx,zynq-xadc-1.00.a";
+ reg = <0xf8007100 0x20>;
+ interrupts = <0 7 4>;
+ interrupt-parent = <&intc>;
+ clocks = <&clkc 12>;
+ };
+
+ can0: can@e0008000 {
+ compatible = "xlnx,zynq-can-1.0";
+ status = "disabled";
+ clocks = <&clkc 19>, <&clkc 36>;
+ clock-names = "can_clk", "pclk";
+ reg = <0xe0008000 0x1000>;
+ interrupts = <0 28 4>;
+ interrupt-parent = <&intc>;
+ tx-fifo-depth = <0x40>;
+ rx-fifo-depth = <0x40>;
+ };
+
+ can1: can@e0009000 {
+ compatible = "xlnx,zynq-can-1.0";
+ status = "disabled";
+ clocks = <&clkc 20>, <&clkc 37>;
+ clock-names = "can_clk", "pclk";
+ reg = <0xe0009000 0x1000>;
+ interrupts = <0 51 4>;
+ interrupt-parent = <&intc>;
+ tx-fifo-depth = <0x40>;
+ rx-fifo-depth = <0x40>;
+ };
+
+ gpio0: gpio@e000a000 {
+ compatible = "xlnx,zynq-gpio-1.0";
+ #gpio-cells = <2>;
+ clocks = <&clkc 42>;
+ gpio-controller;
+ interrupt-parent = <&intc>;
+ interrupts = <0 20 4>;
+ reg = <0xe000a000 0x1000>;
+ };
+
+ i2c0: i2c@e0004000 {
+ compatible = "cdns,i2c-r1p10";
+ status = "disabled";
+ clocks = <&clkc 38>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 25 4>;
+ reg = <0xe0004000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c1: i2c@e0005000 {
+ compatible = "cdns,i2c-r1p10";
+ status = "disabled";
+ clocks = <&clkc 39>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 48 4>;
+ reg = <0xe0005000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ intc: interrupt-controller@f8f01000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0xF8F01000 0x1000>,
+ <0xF8F00100 0x100>;
+ };
+
+ L2: cache-controller@f8f02000 {
+ compatible = "arm,pl310-cache";
+ reg = <0xF8F02000 0x1000>;
+ arm,data-latency = <3 2 2>;
+ arm,tag-latency = <2 2 2>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ mc: memory-controller@f8006000 {
+ compatible = "xlnx,zynq-ddrc-a05";
+ reg = <0xf8006000 0x1000>;
+ };
+
+ uart0: serial@e0000000 {
+ compatible = "xlnx,xuartps", "cdns,uart-r1p8";
+ status = "disabled";
+ clocks = <&clkc 23>, <&clkc 40>;
+ clock-names = "uart_clk", "pclk";
+ reg = <0xE0000000 0x1000>;
+ interrupts = <0 27 4>;
+ };
+
+ uart1: serial@e0001000 {
+ compatible = "xlnx,xuartps", "cdns,uart-r1p8";
+ status = "disabled";
+ clocks = <&clkc 24>, <&clkc 41>;
+ clock-names = "uart_clk", "pclk";
+ reg = <0xE0001000 0x1000>;
+ interrupts = <0 50 4>;
+ };
+
+ spi0: spi@e0006000 {
+ compatible = "xlnx,zynq-spi-r1p6";
+ reg = <0xe0006000 0x1000>;
+ status = "disabled";
+ interrupt-parent = <&intc>;
+ interrupts = <0 26 4>;
+ clocks = <&clkc 25>, <&clkc 34>;
+ clock-names = "ref_clk", "pclk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ spi1: spi@e0007000 {
+ compatible = "xlnx,zynq-spi-r1p6";
+ reg = <0xe0007000 0x1000>;
+ status = "disabled";
+ interrupt-parent = <&intc>;
+ interrupts = <0 49 4>;
+ clocks = <&clkc 26>, <&clkc 35>;
+ clock-names = "ref_clk", "pclk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ gem0: ethernet@e000b000 {
+ compatible = "cdns,zynq-gem";
+ reg = <0xe000b000 0x1000>;
+ status = "disabled";
+ interrupts = <0 22 4>;
+ clocks = <&clkc 30>, <&clkc 30>, <&clkc 13>;
+ clock-names = "pclk", "hclk", "tx_clk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ gem1: ethernet@e000c000 {
+ compatible = "cdns,zynq-gem";
+ reg = <0xe000c000 0x1000>;
+ status = "disabled";
+ interrupts = <0 45 4>;
+ clocks = <&clkc 31>, <&clkc 31>, <&clkc 14>;
+ clock-names = "pclk", "hclk", "tx_clk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sdhci0: sdhci@e0100000 {
+ compatible = "arasan,sdhci-8.9a";
+ status = "disabled";
+ clock-names = "clk_xin", "clk_ahb";
+ clocks = <&clkc 21>, <&clkc 32>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 24 4>;
+ reg = <0xe0100000 0x1000>;
+ };
+
+ sdhci1: sdhci@e0101000 {
+ compatible = "arasan,sdhci-8.9a";
+ status = "disabled";
+ clock-names = "clk_xin", "clk_ahb";
+ clocks = <&clkc 22>, <&clkc 33>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 47 4>;
+ reg = <0xe0101000 0x1000>;
+ };
+
+ slcr: slcr@f8000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "xlnx,zynq-slcr", "syscon", "simple-bus";
+ reg = <0xF8000000 0x1000>;
+ ranges;
+ clkc: clkc@100 {
+ #clock-cells = <1>;
+ compatible = "xlnx,ps7-clkc";
+ fclk-enable = <0>;
+ clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x",
+ "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x",
+ "dci", "lqspi", "smc", "pcap", "gem0", "gem1",
+ "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1",
+ "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1",
+ "dma", "usb0_aper", "usb1_aper", "gem0_aper",
+ "gem1_aper", "sdio0_aper", "sdio1_aper",
+ "spi0_aper", "spi1_aper", "can0_aper", "can1_aper",
+ "i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper",
+ "gpio_aper", "lqspi_aper", "smc_aper", "swdt",
+ "dbg_trc", "dbg_apb";
+ reg = <0x100 0x100>;
+ };
+
+ pinctrl0: pinctrl@700 {
+ compatible = "xlnx,pinctrl-zynq";
+ reg = <0x700 0x200>;
+ syscon = <&slcr>;
+ };
+ };
+
+ dmac_s: dmac@f8003000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0xf8003000 0x1000>;
+ interrupt-parent = <&intc>;
+ interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3",
+ "dma4", "dma5", "dma6", "dma7";
+ interrupts = <0 13 4>,
+ <0 14 4>, <0 15 4>,
+ <0 16 4>, <0 17 4>,
+ <0 40 4>, <0 41 4>,
+ <0 42 4>, <0 43 4>;
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <4>;
+ clocks = <&clkc 27>;
+ clock-names = "apb_pclk";
+ };
+
+ devcfg: devcfg@f8007000 {
+ compatible = "xlnx,zynq-devcfg-1.0";
+ reg = <0xf8007000 0x100>;
+ };
+
+ global_timer: timer@f8f00200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0xf8f00200 0x20>;
+ interrupts = <1 11 0x301>;
+ interrupt-parent = <&intc>;
+ clocks = <&clkc 4>;
+ };
+
+ ttc0: timer@f8001000 {
+ interrupt-parent = <&intc>;
+ interrupts = <0 10 4>, <0 11 4>, <0 12 4>;
+ compatible = "cdns,ttc";
+ clocks = <&clkc 6>;
+ reg = <0xF8001000 0x1000>;
+ };
+
+ ttc1: timer@f8002000 {
+ interrupt-parent = <&intc>;
+ interrupts = <0 37 4>, <0 38 4>, <0 39 4>;
+ compatible = "cdns,ttc";
+ clocks = <&clkc 6>;
+ reg = <0xF8002000 0x1000>;
+ };
+
+ scutimer: timer@f8f00600 {
+ interrupt-parent = <&intc>;
+ interrupts = <1 13 0x301>;
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xf8f00600 0x20>;
+ clocks = <&clkc 4>;
+ };
+
+ usb0: usb@e0002000 {
+ compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
+ status = "disabled";
+ clocks = <&clkc 28>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 21 4>;
+ reg = <0xe0002000 0x1000>;
+ phy_type = "ulpi";
+ };
+
+ usb1: usb@e0003000 {
+ compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
+ status = "disabled";
+ clocks = <&clkc 29>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 44 4>;
+ reg = <0xe0003000 0x1000>;
+ phy_type = "ulpi";
+ };
+
+ watchdog0: watchdog@f8005000 {
+ clocks = <&clkc 45>;
+ compatible = "cdns,wdt-r1p2";
+ interrupt-parent = <&intc>;
+ interrupts = <0 9 1>;
+ reg = <0xf8005000 0x1000>;
+ timeout-sec = <10>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/zynq-parallella.dts b/arch/arm/boot/dts/zynq-parallella.dts
new file mode 100644
index 000000000..174571232
--- /dev/null
+++ b/arch/arm/boot/dts/zynq-parallella.dts
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * Derived from zynq-zed.dts:
+ *
+ * Copyright (C) 2011 Xilinx
+ * Copyright (C) 2012 National Instruments Corp.
+ * Copyright (C) 2013 Xilinx
+ *
+ * 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.
+ */
+/dts-v1/;
+/include/ "zynq-7000.dtsi"
+
+/ {
+ model = "Adapteva Parallella Board";
+ compatible = "adapteva,parallella", "xlnx,zynq-7000";
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x40000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyPS0,115200 earlyprintk root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait";
+ linux,stdout-path = "/amba/serial@e0001000";
+ };
+};
+
+&clkc {
+ fclk-enable = <0xf>;
+ ps-clk-frequency = <33333333>;
+};
+
+&gem0 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethernet_phy>;
+
+ ethernet_phy: ethernet-phy@0 {
+ /* Marvell 88E1318 */
+ compatible = "ethernet-phy-id0141.0e90",
+ "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ marvell,reg-init = <0x3 0x10 0xff00 0x1e>,
+ <0x3 0x11 0xfff0 0xa>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+
+ isl9305: isl9305@68 {
+ compatible = "isil,isl9305";
+ reg = <0x68>;
+
+ regulators {
+ dcd1 {
+ regulator-name = "VDD_DSP";
+ regulator-always-on;
+ };
+ dcd2 {
+ regulator-name = "1P35V";
+ regulator-always-on;
+ };
+ ldo1 {
+ regulator-name = "VDD_ADJ";
+ };
+ ldo2 {
+ regulator-name = "VDD_GPIO";
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&sdhci1 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts
new file mode 100644
index 000000000..1fc1d3911
--- /dev/null
+++ b/arch/arm/boot/dts/zynq-zc702.dts
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2011 - 2014 Xilinx
+ * Copyright (C) 2012 National Instruments Corp.
+ *
+ * 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.
+ */
+/dts-v1/;
+/include/ "zynq-7000.dtsi"
+
+/ {
+ model = "Zynq ZC702 Development Board";
+ compatible = "xlnx,zynq-zc702", "xlnx,zynq-7000";
+
+ aliases {
+ ethernet0 = &gem0;
+ i2c0 = &i2c0;
+ serial0 = &uart1;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x40000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyPS0,115200 earlyprintk";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ ds23 {
+ label = "ds23";
+ gpios = <&gpio0 10 0>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ usb_phy0: phy0 {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
+ };
+};
+
+&can0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can0_default>;
+};
+
+&clkc {
+ ps-clk-frequency = <33333333>;
+};
+
+&gem0 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethernet_phy>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gem0_default>;
+
+ ethernet_phy: ethernet-phy@7 {
+ reg = <7>;
+ };
+};
+
+&gpio0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio0_default>;
+};
+
+&i2c0 {
+ status = "okay";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_default>;
+
+ i2cswitch@74 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x74>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ si570: clock-generator@5d {
+ #clock-cells = <0>;
+ compatible = "silabs,si570";
+ temperature-stability = <50>;
+ reg = <0x5d>;
+ factory-fout = <156250000>;
+ clock-frequency = <148500000>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ eeprom@54 {
+ compatible = "at,24c08";
+ reg = <0x54>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ gpio@21 {
+ compatible = "ti,tca6416";
+ reg = <0x21>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+ };
+
+ i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ hwmon@52 {
+ compatible = "ti,ucd9248";
+ reg = <52>;
+ };
+ hwmon@53 {
+ compatible = "ti,ucd9248";
+ reg = <53>;
+ };
+ hwmon@54 {
+ compatible = "ti,ucd9248";
+ reg = <54>;
+ };
+ };
+ };
+};
+
+&pinctrl0 {
+ pinctrl_can0_default: can0-default {
+ mux {
+ function = "can0";
+ groups = "can0_9_grp";
+ };
+
+ conf {
+ groups = "can0_9_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-rx {
+ pins = "MIO46";
+ bias-high-impedance;
+ };
+
+ conf-tx {
+ pins = "MIO47";
+ bias-disable;
+ };
+ };
+
+ pinctrl_gem0_default: gem0-default {
+ mux {
+ function = "ethernet0";
+ groups = "ethernet0_0_grp";
+ };
+
+ conf {
+ groups = "ethernet0_0_grp";
+ slew-rate = <0>;
+ io-standard = <4>;
+ };
+
+ conf-rx {
+ pins = "MIO22", "MIO23", "MIO24", "MIO25", "MIO26", "MIO27";
+ bias-high-impedance;
+ low-power-disable;
+ };
+
+ conf-tx {
+ pins = "MIO16", "MIO17", "MIO18", "MIO19", "MIO20", "MIO21";
+ bias-disable;
+ low-power-enable;
+ };
+
+ mux-mdio {
+ function = "mdio0";
+ groups = "mdio0_0_grp";
+ };
+
+ conf-mdio {
+ groups = "mdio0_0_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio0_default: gpio0-default {
+ mux {
+ function = "gpio0";
+ groups = "gpio0_7_grp", "gpio0_8_grp", "gpio0_9_grp",
+ "gpio0_10_grp", "gpio0_11_grp", "gpio0_12_grp",
+ "gpio0_13_grp", "gpio0_14_grp";
+ };
+
+ conf {
+ groups = "gpio0_7_grp", "gpio0_8_grp", "gpio0_9_grp",
+ "gpio0_10_grp", "gpio0_11_grp", "gpio0_12_grp",
+ "gpio0_13_grp", "gpio0_14_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-pull-up {
+ pins = "MIO9", "MIO10", "MIO11", "MIO12", "MIO13", "MIO14";
+ bias-pull-up;
+ };
+
+ conf-pull-none {
+ pins = "MIO7", "MIO8";
+ bias-disable;
+ };
+ };
+
+ pinctrl_i2c0_default: i2c0-default {
+ mux {
+ groups = "i2c0_10_grp";
+ function = "i2c0";
+ };
+
+ conf {
+ groups = "i2c0_10_grp";
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ };
+
+ pinctrl_sdhci0_default: sdhci0-default {
+ mux {
+ groups = "sdio0_2_grp";
+ function = "sdio0";
+ };
+
+ conf {
+ groups = "sdio0_2_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ bias-disable;
+ };
+
+ mux-cd {
+ groups = "gpio0_0_grp";
+ function = "sdio0_cd";
+ };
+
+ conf-cd {
+ groups = "gpio0_0_grp";
+ bias-high-impedance;
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ mux-wp {
+ groups = "gpio0_15_grp";
+ function = "sdio0_wp";
+ };
+
+ conf-wp {
+ groups = "gpio0_15_grp";
+ bias-high-impedance;
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ };
+
+ pinctrl_uart1_default: uart1-default {
+ mux {
+ groups = "uart1_10_grp";
+ function = "uart1";
+ };
+
+ conf {
+ groups = "uart1_10_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-rx {
+ pins = "MIO49";
+ bias-high-impedance;
+ };
+
+ conf-tx {
+ pins = "MIO48";
+ bias-disable;
+ };
+ };
+
+ pinctrl_usb0_default: usb0-default {
+ mux {
+ groups = "usb0_0_grp";
+ function = "usb0";
+ };
+
+ conf {
+ groups = "usb0_0_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-rx {
+ pins = "MIO29", "MIO31", "MIO36";
+ bias-high-impedance;
+ };
+
+ conf-tx {
+ pins = "MIO28", "MIO30", "MIO32", "MIO33", "MIO34",
+ "MIO35", "MIO37", "MIO38", "MIO39";
+ bias-disable;
+ };
+ };
+};
+
+&sdhci0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdhci0_default>;
+};
+
+&uart1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_default>;
+};
+
+&usb0 {
+ status = "okay";
+ dr_mode = "host";
+ usb-phy = <&usb_phy0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0_default>;
+};
diff --git a/arch/arm/boot/dts/zynq-zc706.dts b/arch/arm/boot/dts/zynq-zc706.dts
new file mode 100644
index 000000000..850518d9b
--- /dev/null
+++ b/arch/arm/boot/dts/zynq-zc706.dts
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2011 - 2014 Xilinx
+ * Copyright (C) 2012 National Instruments Corp.
+ *
+ * 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.
+ */
+/dts-v1/;
+/include/ "zynq-7000.dtsi"
+
+/ {
+ model = "Zynq ZC706 Development Board";
+ compatible = "xlnx,zynq-zc706", "xlnx,zynq-7000";
+
+ aliases {
+ ethernet0 = &gem0;
+ i2c0 = &i2c0;
+ serial0 = &uart1;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x40000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyPS0,115200 earlyprintk";
+ };
+
+ usb_phy0: phy0 {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
+ };
+};
+
+&clkc {
+ ps-clk-frequency = <33333333>;
+};
+
+&gem0 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethernet_phy>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gem0_default>;
+
+ ethernet_phy: ethernet-phy@7 {
+ reg = <7>;
+ };
+};
+
+&gpio0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio0_default>;
+};
+
+&i2c0 {
+ status = "okay";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_default>;
+
+ i2cswitch@74 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x74>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ si570: clock-generator@5d {
+ #clock-cells = <0>;
+ compatible = "silabs,si570";
+ temperature-stability = <50>;
+ reg = <0x5d>;
+ factory-fout = <156250000>;
+ clock-frequency = <148500000>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ eeprom@54 {
+ compatible = "at,24c08";
+ reg = <0x54>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ gpio@21 {
+ compatible = "ti,tca6416";
+ reg = <0x21>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+ };
+
+ i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ ucd90120@65 {
+ compatible = "ti,ucd90120";
+ reg = <0x65>;
+ };
+ };
+ };
+};
+
+&pinctrl0 {
+ pinctrl_gem0_default: gem0-default {
+ mux {
+ function = "ethernet0";
+ groups = "ethernet0_0_grp";
+ };
+
+ conf {
+ groups = "ethernet0_0_grp";
+ slew-rate = <0>;
+ io-standard = <4>;
+ };
+
+ conf-rx {
+ pins = "MIO22", "MIO23", "MIO24", "MIO25", "MIO26", "MIO27";
+ bias-high-impedance;
+ low-power-disable;
+ };
+
+ conf-tx {
+ pins = "MIO16", "MIO17", "MIO18", "MIO19", "MIO20", "MIO21";
+ low-power-enable;
+ bias-disable;
+ };
+
+ mux-mdio {
+ function = "mdio0";
+ groups = "mdio0_0_grp";
+ };
+
+ conf-mdio {
+ groups = "mdio0_0_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio0_default: gpio0-default {
+ mux {
+ function = "gpio0";
+ groups = "gpio0_7_grp", "gpio0_46_grp", "gpio0_47_grp";
+ };
+
+ conf {
+ groups = "gpio0_7_grp", "gpio0_46_grp", "gpio0_47_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-pull-up {
+ pins = "MIO46", "MIO47";
+ bias-pull-up;
+ };
+
+ conf-pull-none {
+ pins = "MIO7";
+ bias-disable;
+ };
+ };
+
+ pinctrl_i2c0_default: i2c0-default {
+ mux {
+ groups = "i2c0_10_grp";
+ function = "i2c0";
+ };
+
+ conf {
+ groups = "i2c0_10_grp";
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ };
+
+ pinctrl_sdhci0_default: sdhci0-default {
+ mux {
+ groups = "sdio0_2_grp";
+ function = "sdio0";
+ };
+
+ conf {
+ groups = "sdio0_2_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ bias-disable;
+ };
+
+ mux-cd {
+ groups = "gpio0_14_grp";
+ function = "sdio0_cd";
+ };
+
+ conf-cd {
+ groups = "gpio0_14_grp";
+ bias-high-impedance;
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ mux-wp {
+ groups = "gpio0_15_grp";
+ function = "sdio0_wp";
+ };
+
+ conf-wp {
+ groups = "gpio0_15_grp";
+ bias-high-impedance;
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ };
+
+ pinctrl_uart1_default: uart1-default {
+ mux {
+ groups = "uart1_10_grp";
+ function = "uart1";
+ };
+
+ conf {
+ groups = "uart1_10_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-rx {
+ pins = "MIO49";
+ bias-high-impedance;
+ };
+
+ conf-tx {
+ pins = "MIO48";
+ bias-disable;
+ };
+ };
+
+ pinctrl_usb0_default: usb0-default {
+ mux {
+ groups = "usb0_0_grp";
+ function = "usb0";
+ };
+
+ conf {
+ groups = "usb0_0_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-rx {
+ pins = "MIO29", "MIO31", "MIO36";
+ bias-high-impedance;
+ };
+
+ conf-tx {
+ pins = "MIO28", "MIO30", "MIO32", "MIO33", "MIO34",
+ "MIO35", "MIO37", "MIO38", "MIO39";
+ bias-disable;
+ };
+ };
+};
+
+&sdhci0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdhci0_default>;
+};
+
+&uart1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_default>;
+};
+
+&usb0 {
+ status = "okay";
+ dr_mode = "host";
+ usb-phy = <&usb_phy0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0_default>;
+};
diff --git a/arch/arm/boot/dts/zynq-zed.dts b/arch/arm/boot/dts/zynq-zed.dts
new file mode 100644
index 000000000..5658bc843
--- /dev/null
+++ b/arch/arm/boot/dts/zynq-zed.dts
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 - 2014 Xilinx
+ * Copyright (C) 2012 National Instruments Corp.
+ *
+ * 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.
+ */
+/dts-v1/;
+/include/ "zynq-7000.dtsi"
+
+/ {
+ model = "Zynq Zed Development Board";
+ compatible = "xlnx,zynq-zed", "xlnx,zynq-7000";
+
+ aliases {
+ ethernet0 = &gem0;
+ serial0 = &uart1;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x20000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyPS0,115200 earlyprintk";
+ };
+
+ usb_phy0: phy0 {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
+ };
+};
+
+&clkc {
+ ps-clk-frequency = <33333333>;
+};
+
+&gem0 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethernet_phy>;
+
+ ethernet_phy: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&sdhci0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+ dr_mode = "host";
+ usb-phy = <&usb_phy0>;
+};
diff --git a/arch/arm/boot/dts/zynq-zybo.dts b/arch/arm/boot/dts/zynq-zybo.dts
new file mode 100644
index 000000000..a9a12ce50
--- /dev/null
+++ b/arch/arm/boot/dts/zynq-zybo.dts
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 - 2014 Xilinx
+ * Copyright (C) 2012 National Instruments Corp.
+ *
+ * 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.
+ */
+/dts-v1/;
+/include/ "zynq-7000.dtsi"
+
+/ {
+ model = "Zynq ZYBO Development Board";
+ compatible = "digilent,zynq-zybo", "xlnx,zynq-7000";
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x20000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyPS0,115200 earlyprintk";
+ };
+
+};
+
+&clkc {
+ ps-clk-frequency = <50000000>;
+};
+
+&gem0 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethernet_phy>;
+
+ ethernet_phy: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&sdhci0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/install.sh b/arch/arm/boot/install.sh
new file mode 100644
index 000000000..2a45092a4
--- /dev/null
+++ b/arch/arm/boot/install.sh
@@ -0,0 +1,66 @@
+#!/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)
+#
+
+verify () {
+ if [ ! -f "$1" ]; then
+ echo "" 1>&2
+ echo " *** Missing file: $1" 1>&2
+ echo ' *** You need to run "make" before "make install".' 1>&2
+ echo "" 1>&2
+ exit 1
+ fi
+}
+
+# Make sure the files actually exist
+verify "$2"
+verify "$3"
+
+# 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 000000000..c3a4e9ceb
--- /dev/null
+++ b/arch/arm/common/Kconfig
@@ -0,0 +1,22 @@
+config ICST
+ bool
+
+config SA1111
+ bool
+ select DMABOUNCE if !ARCH_PXA
+
+config DMABOUNCE
+ bool
+ select ZONE_DMA
+
+config SHARP_LOCOMO
+ bool
+
+config SHARP_PARAM
+ bool
+
+config SHARP_SCOOP
+ bool
+
+config TI_PRIV_EDMA
+ bool
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
new file mode 100644
index 000000000..70b1eff47
--- /dev/null
+++ b/arch/arm/common/Makefile
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y += firmware.o
+
+obj-$(CONFIG_ICST) += icst.o
+obj-$(CONFIG_SA1111) += sa1111.o
+obj-$(CONFIG_DMABOUNCE) += dmabounce.o
+obj-$(CONFIG_SHARP_LOCOMO) += locomo.o
+obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o
+obj-$(CONFIG_SHARP_SCOOP) += scoop.o
+obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
+obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
+obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o
+CFLAGS_REMOVE_mcpm_entry.o = -pg
+AFLAGS_mcpm_head.o := -march=armv7-a
+AFLAGS_vlock.o := -march=armv7-a
+obj-$(CONFIG_TI_PRIV_EDMA) += edma.o
+obj-$(CONFIG_BL_SWITCHER) += bL_switcher.o
+obj-$(CONFIG_BL_SWITCHER_DUMMY_IF) += bL_switcher_dummy_if.o
diff --git a/arch/arm/common/bL_switcher.c b/arch/arm/common/bL_switcher.c
new file mode 100644
index 000000000..37dc0fe10
--- /dev/null
+++ b/arch/arm/common/bL_switcher.c
@@ -0,0 +1,802 @@
+/*
+ * arch/arm/common/bL_switcher.c -- big.LITTLE cluster switcher core driver
+ *
+ * Created by: Nicolas Pitre, March 2012
+ * Copyright: (C) 2012-2013 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.
+ */
+
+#include <linux/atomic.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/cpu_pm.h>
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
+#include <linux/time.h>
+#include <linux/clockchips.h>
+#include <linux/hrtimer.h>
+#include <linux/tick.h>
+#include <linux/notifier.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/moduleparam.h>
+
+#include <asm/smp_plat.h>
+#include <asm/cputype.h>
+#include <asm/suspend.h>
+#include <asm/mcpm.h>
+#include <asm/bL_switcher.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/power_cpu_migrate.h>
+
+
+/*
+ * Use our own MPIDR accessors as the generic ones in asm/cputype.h have
+ * __attribute_const__ and we don't want the compiler to assume any
+ * constness here as the value _does_ change along some code paths.
+ */
+
+static int read_mpidr(void)
+{
+ unsigned int id;
+ asm volatile ("mrc p15, 0, %0, c0, c0, 5" : "=r" (id));
+ return id & MPIDR_HWID_BITMASK;
+}
+
+/*
+ * bL switcher core code.
+ */
+
+static void bL_do_switch(void *_arg)
+{
+ unsigned ib_mpidr, ib_cpu, ib_cluster;
+ long volatile handshake, **handshake_ptr = _arg;
+
+ pr_debug("%s\n", __func__);
+
+ ib_mpidr = cpu_logical_map(smp_processor_id());
+ ib_cpu = MPIDR_AFFINITY_LEVEL(ib_mpidr, 0);
+ ib_cluster = MPIDR_AFFINITY_LEVEL(ib_mpidr, 1);
+
+ /* Advertise our handshake location */
+ if (handshake_ptr) {
+ handshake = 0;
+ *handshake_ptr = &handshake;
+ } else
+ handshake = -1;
+
+ /*
+ * Our state has been saved at this point. Let's release our
+ * inbound CPU.
+ */
+ mcpm_set_entry_vector(ib_cpu, ib_cluster, cpu_resume);
+ sev();
+
+ /*
+ * From this point, we must assume that our counterpart CPU might
+ * have taken over in its parallel world already, as if execution
+ * just returned from cpu_suspend(). It is therefore important to
+ * be very careful not to make any change the other guy is not
+ * expecting. This is why we need stack isolation.
+ *
+ * Fancy under cover tasks could be performed here. For now
+ * we have none.
+ */
+
+ /*
+ * Let's wait until our inbound is alive.
+ */
+ while (!handshake) {
+ wfe();
+ smp_mb();
+ }
+
+ /* Let's put ourself down. */
+ mcpm_cpu_power_down();
+
+ /* should never get here */
+ BUG();
+}
+
+/*
+ * Stack isolation. To ensure 'current' remains valid, we just use another
+ * piece of our thread's stack space which should be fairly lightly used.
+ * The selected area starts just above the thread_info structure located
+ * at the very bottom of the stack, aligned to a cache line, and indexed
+ * with the cluster number.
+ */
+#define STACK_SIZE 512
+extern void call_with_stack(void (*fn)(void *), void *arg, void *sp);
+static int bL_switchpoint(unsigned long _arg)
+{
+ unsigned int mpidr = read_mpidr();
+ unsigned int clusterid = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+ void *stack = current_thread_info() + 1;
+ stack = PTR_ALIGN(stack, L1_CACHE_BYTES);
+ stack += clusterid * STACK_SIZE + STACK_SIZE;
+ call_with_stack(bL_do_switch, (void *)_arg, stack);
+ BUG();
+}
+
+/*
+ * Generic switcher interface
+ */
+
+static unsigned int bL_gic_id[MAX_CPUS_PER_CLUSTER][MAX_NR_CLUSTERS];
+static int bL_switcher_cpu_pairing[NR_CPUS];
+
+/*
+ * bL_switch_to - Switch to a specific cluster for the current CPU
+ * @new_cluster_id: the ID of the cluster to switch to.
+ *
+ * This function must be called on the CPU to be switched.
+ * Returns 0 on success, else a negative status code.
+ */
+static int bL_switch_to(unsigned int new_cluster_id)
+{
+ unsigned int mpidr, this_cpu, that_cpu;
+ unsigned int ob_mpidr, ob_cpu, ob_cluster, ib_mpidr, ib_cpu, ib_cluster;
+ struct completion inbound_alive;
+ long volatile *handshake_ptr;
+ int ipi_nr, ret;
+
+ this_cpu = smp_processor_id();
+ ob_mpidr = read_mpidr();
+ ob_cpu = MPIDR_AFFINITY_LEVEL(ob_mpidr, 0);
+ ob_cluster = MPIDR_AFFINITY_LEVEL(ob_mpidr, 1);
+ BUG_ON(cpu_logical_map(this_cpu) != ob_mpidr);
+
+ if (new_cluster_id == ob_cluster)
+ return 0;
+
+ that_cpu = bL_switcher_cpu_pairing[this_cpu];
+ ib_mpidr = cpu_logical_map(that_cpu);
+ ib_cpu = MPIDR_AFFINITY_LEVEL(ib_mpidr, 0);
+ ib_cluster = MPIDR_AFFINITY_LEVEL(ib_mpidr, 1);
+
+ pr_debug("before switch: CPU %d MPIDR %#x -> %#x\n",
+ this_cpu, ob_mpidr, ib_mpidr);
+
+ this_cpu = smp_processor_id();
+
+ /* Close the gate for our entry vectors */
+ mcpm_set_entry_vector(ob_cpu, ob_cluster, NULL);
+ mcpm_set_entry_vector(ib_cpu, ib_cluster, NULL);
+
+ /* Install our "inbound alive" notifier. */
+ init_completion(&inbound_alive);
+ ipi_nr = register_ipi_completion(&inbound_alive, this_cpu);
+ ipi_nr |= ((1 << 16) << bL_gic_id[ob_cpu][ob_cluster]);
+ mcpm_set_early_poke(ib_cpu, ib_cluster, gic_get_sgir_physaddr(), ipi_nr);
+
+ /*
+ * Let's wake up the inbound CPU now in case it requires some delay
+ * to come online, but leave it gated in our entry vector code.
+ */
+ ret = mcpm_cpu_power_up(ib_cpu, ib_cluster);
+ if (ret) {
+ pr_err("%s: mcpm_cpu_power_up() returned %d\n", __func__, ret);
+ return ret;
+ }
+
+ /*
+ * Raise a SGI on the inbound CPU to make sure it doesn't stall
+ * in a possible WFI, such as in bL_power_down().
+ */
+ gic_send_sgi(bL_gic_id[ib_cpu][ib_cluster], 0);
+
+ /*
+ * Wait for the inbound to come up. This allows for other
+ * tasks to be scheduled in the mean time.
+ */
+ wait_for_completion(&inbound_alive);
+ mcpm_set_early_poke(ib_cpu, ib_cluster, 0, 0);
+
+ /*
+ * From this point we are entering the switch critical zone
+ * and can't take any interrupts anymore.
+ */
+ local_irq_disable();
+ local_fiq_disable();
+ trace_cpu_migrate_begin(ktime_get_real_ns(), ob_mpidr);
+
+ /* redirect GIC's SGIs to our counterpart */
+ gic_migrate_target(bL_gic_id[ib_cpu][ib_cluster]);
+
+ tick_suspend_local();
+
+ ret = cpu_pm_enter();
+
+ /* we can not tolerate errors at this point */
+ if (ret)
+ panic("%s: cpu_pm_enter() returned %d\n", __func__, ret);
+
+ /* Swap the physical CPUs in the logical map for this logical CPU. */
+ cpu_logical_map(this_cpu) = ib_mpidr;
+ cpu_logical_map(that_cpu) = ob_mpidr;
+
+ /* Let's do the actual CPU switch. */
+ ret = cpu_suspend((unsigned long)&handshake_ptr, bL_switchpoint);
+ if (ret > 0)
+ panic("%s: cpu_suspend() returned %d\n", __func__, ret);
+
+ /* We are executing on the inbound CPU at this point */
+ mpidr = read_mpidr();
+ pr_debug("after switch: CPU %d MPIDR %#x\n", this_cpu, mpidr);
+ BUG_ON(mpidr != ib_mpidr);
+
+ mcpm_cpu_powered_up();
+
+ ret = cpu_pm_exit();
+
+ tick_resume_local();
+
+ trace_cpu_migrate_finish(ktime_get_real_ns(), ib_mpidr);
+ local_fiq_enable();
+ local_irq_enable();
+
+ *handshake_ptr = 1;
+ dsb_sev();
+
+ if (ret)
+ pr_err("%s exiting with error %d\n", __func__, ret);
+ return ret;
+}
+
+struct bL_thread {
+ spinlock_t lock;
+ struct task_struct *task;
+ wait_queue_head_t wq;
+ int wanted_cluster;
+ struct completion started;
+ bL_switch_completion_handler completer;
+ void *completer_cookie;
+};
+
+static struct bL_thread bL_threads[NR_CPUS];
+
+static int bL_switcher_thread(void *arg)
+{
+ struct bL_thread *t = arg;
+ struct sched_param param = { .sched_priority = 1 };
+ int cluster;
+ bL_switch_completion_handler completer;
+ void *completer_cookie;
+
+ sched_setscheduler_nocheck(current, SCHED_FIFO, &param);
+ complete(&t->started);
+
+ do {
+ if (signal_pending(current))
+ flush_signals(current);
+ wait_event_interruptible(t->wq,
+ t->wanted_cluster != -1 ||
+ kthread_should_stop());
+
+ spin_lock(&t->lock);
+ cluster = t->wanted_cluster;
+ completer = t->completer;
+ completer_cookie = t->completer_cookie;
+ t->wanted_cluster = -1;
+ t->completer = NULL;
+ spin_unlock(&t->lock);
+
+ if (cluster != -1) {
+ bL_switch_to(cluster);
+
+ if (completer)
+ completer(completer_cookie);
+ }
+ } while (!kthread_should_stop());
+
+ return 0;
+}
+
+static struct task_struct *bL_switcher_thread_create(int cpu, void *arg)
+{
+ struct task_struct *task;
+
+ task = kthread_create_on_node(bL_switcher_thread, arg,
+ cpu_to_node(cpu), "kswitcher_%d", cpu);
+ if (!IS_ERR(task)) {
+ kthread_bind(task, cpu);
+ wake_up_process(task);
+ } else
+ pr_err("%s failed for CPU %d\n", __func__, cpu);
+ return task;
+}
+
+/*
+ * bL_switch_request_cb - Switch to a specific cluster for the given CPU,
+ * with completion notification via a callback
+ *
+ * @cpu: the CPU to switch
+ * @new_cluster_id: the ID of the cluster to switch to.
+ * @completer: switch completion callback. if non-NULL,
+ * @completer(@completer_cookie) will be called on completion of
+ * the switch, in non-atomic context.
+ * @completer_cookie: opaque context argument for @completer.
+ *
+ * This function causes a cluster switch on the given CPU by waking up
+ * the appropriate switcher thread. This function may or may not return
+ * before the switch has occurred.
+ *
+ * If a @completer callback function is supplied, it will be called when
+ * the switch is complete. This can be used to determine asynchronously
+ * when the switch is complete, regardless of when bL_switch_request()
+ * returns. When @completer is supplied, no new switch request is permitted
+ * for the affected CPU until after the switch is complete, and @completer
+ * has returned.
+ */
+int bL_switch_request_cb(unsigned int cpu, unsigned int new_cluster_id,
+ bL_switch_completion_handler completer,
+ void *completer_cookie)
+{
+ struct bL_thread *t;
+
+ if (cpu >= ARRAY_SIZE(bL_threads)) {
+ pr_err("%s: cpu %d out of bounds\n", __func__, cpu);
+ return -EINVAL;
+ }
+
+ t = &bL_threads[cpu];
+
+ if (IS_ERR(t->task))
+ return PTR_ERR(t->task);
+ if (!t->task)
+ return -ESRCH;
+
+ spin_lock(&t->lock);
+ if (t->completer) {
+ spin_unlock(&t->lock);
+ return -EBUSY;
+ }
+ t->completer = completer;
+ t->completer_cookie = completer_cookie;
+ t->wanted_cluster = new_cluster_id;
+ spin_unlock(&t->lock);
+ wake_up(&t->wq);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(bL_switch_request_cb);
+
+/*
+ * Activation and configuration code.
+ */
+
+static DEFINE_MUTEX(bL_switcher_activation_lock);
+static BLOCKING_NOTIFIER_HEAD(bL_activation_notifier);
+static unsigned int bL_switcher_active;
+static unsigned int bL_switcher_cpu_original_cluster[NR_CPUS];
+static cpumask_t bL_switcher_removed_logical_cpus;
+
+int bL_switcher_register_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(&bL_activation_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(bL_switcher_register_notifier);
+
+int bL_switcher_unregister_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(&bL_activation_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(bL_switcher_unregister_notifier);
+
+static int bL_activation_notify(unsigned long val)
+{
+ int ret;
+
+ ret = blocking_notifier_call_chain(&bL_activation_notifier, val, NULL);
+ if (ret & NOTIFY_STOP_MASK)
+ pr_err("%s: notifier chain failed with status 0x%x\n",
+ __func__, ret);
+ return notifier_to_errno(ret);
+}
+
+static void bL_switcher_restore_cpus(void)
+{
+ int i;
+
+ for_each_cpu(i, &bL_switcher_removed_logical_cpus) {
+ struct device *cpu_dev = get_cpu_device(i);
+ int ret = device_online(cpu_dev);
+ if (ret)
+ dev_err(cpu_dev, "switcher: unable to restore CPU\n");
+ }
+}
+
+static int bL_switcher_halve_cpus(void)
+{
+ int i, j, cluster_0, gic_id, ret;
+ unsigned int cpu, cluster, mask;
+ cpumask_t available_cpus;
+
+ /* First pass to validate what we have */
+ mask = 0;
+ for_each_online_cpu(i) {
+ cpu = MPIDR_AFFINITY_LEVEL(cpu_logical_map(i), 0);
+ cluster = MPIDR_AFFINITY_LEVEL(cpu_logical_map(i), 1);
+ if (cluster >= 2) {
+ pr_err("%s: only dual cluster systems are supported\n", __func__);
+ return -EINVAL;
+ }
+ if (WARN_ON(cpu >= MAX_CPUS_PER_CLUSTER))
+ return -EINVAL;
+ mask |= (1 << cluster);
+ }
+ if (mask != 3) {
+ pr_err("%s: no CPU pairing possible\n", __func__);
+ return -EINVAL;
+ }
+
+ /*
+ * Now let's do the pairing. We match each CPU with another CPU
+ * from a different cluster. To get a uniform scheduling behavior
+ * without fiddling with CPU topology and compute capacity data,
+ * we'll use logical CPUs initially belonging to the same cluster.
+ */
+ memset(bL_switcher_cpu_pairing, -1, sizeof(bL_switcher_cpu_pairing));
+ cpumask_copy(&available_cpus, cpu_online_mask);
+ cluster_0 = -1;
+ for_each_cpu(i, &available_cpus) {
+ int match = -1;
+ cluster = MPIDR_AFFINITY_LEVEL(cpu_logical_map(i), 1);
+ if (cluster_0 == -1)
+ cluster_0 = cluster;
+ if (cluster != cluster_0)
+ continue;
+ cpumask_clear_cpu(i, &available_cpus);
+ for_each_cpu(j, &available_cpus) {
+ cluster = MPIDR_AFFINITY_LEVEL(cpu_logical_map(j), 1);
+ /*
+ * Let's remember the last match to create "odd"
+ * pairings on purpose in order for other code not
+ * to assume any relation between physical and
+ * logical CPU numbers.
+ */
+ if (cluster != cluster_0)
+ match = j;
+ }
+ if (match != -1) {
+ bL_switcher_cpu_pairing[i] = match;
+ cpumask_clear_cpu(match, &available_cpus);
+ pr_info("CPU%d paired with CPU%d\n", i, match);
+ }
+ }
+
+ /*
+ * Now we disable the unwanted CPUs i.e. everything that has no
+ * pairing information (that includes the pairing counterparts).
+ */
+ cpumask_clear(&bL_switcher_removed_logical_cpus);
+ for_each_online_cpu(i) {
+ cpu = MPIDR_AFFINITY_LEVEL(cpu_logical_map(i), 0);
+ cluster = MPIDR_AFFINITY_LEVEL(cpu_logical_map(i), 1);
+
+ /* Let's take note of the GIC ID for this CPU */
+ gic_id = gic_get_cpu_id(i);
+ if (gic_id < 0) {
+ pr_err("%s: bad GIC ID for CPU %d\n", __func__, i);
+ bL_switcher_restore_cpus();
+ return -EINVAL;
+ }
+ bL_gic_id[cpu][cluster] = gic_id;
+ pr_info("GIC ID for CPU %u cluster %u is %u\n",
+ cpu, cluster, gic_id);
+
+ if (bL_switcher_cpu_pairing[i] != -1) {
+ bL_switcher_cpu_original_cluster[i] = cluster;
+ continue;
+ }
+
+ ret = device_offline(get_cpu_device(i));
+ if (ret) {
+ bL_switcher_restore_cpus();
+ return ret;
+ }
+ cpumask_set_cpu(i, &bL_switcher_removed_logical_cpus);
+ }
+
+ return 0;
+}
+
+/* Determine the logical CPU a given physical CPU is grouped on. */
+int bL_switcher_get_logical_index(u32 mpidr)
+{
+ int cpu;
+
+ if (!bL_switcher_active)
+ return -EUNATCH;
+
+ mpidr &= MPIDR_HWID_BITMASK;
+ for_each_online_cpu(cpu) {
+ int pairing = bL_switcher_cpu_pairing[cpu];
+ if (pairing == -1)
+ continue;
+ if ((mpidr == cpu_logical_map(cpu)) ||
+ (mpidr == cpu_logical_map(pairing)))
+ return cpu;
+ }
+ return -EINVAL;
+}
+
+static void bL_switcher_trace_trigger_cpu(void *__always_unused info)
+{
+ trace_cpu_migrate_current(ktime_get_real_ns(), read_mpidr());
+}
+
+int bL_switcher_trace_trigger(void)
+{
+ int ret;
+
+ preempt_disable();
+
+ bL_switcher_trace_trigger_cpu(NULL);
+ ret = smp_call_function(bL_switcher_trace_trigger_cpu, NULL, true);
+
+ preempt_enable();
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(bL_switcher_trace_trigger);
+
+static int bL_switcher_enable(void)
+{
+ int cpu, ret;
+
+ mutex_lock(&bL_switcher_activation_lock);
+ lock_device_hotplug();
+ if (bL_switcher_active) {
+ unlock_device_hotplug();
+ mutex_unlock(&bL_switcher_activation_lock);
+ return 0;
+ }
+
+ pr_info("big.LITTLE switcher initializing\n");
+
+ ret = bL_activation_notify(BL_NOTIFY_PRE_ENABLE);
+ if (ret)
+ goto error;
+
+ ret = bL_switcher_halve_cpus();
+ if (ret)
+ goto error;
+
+ bL_switcher_trace_trigger();
+
+ for_each_online_cpu(cpu) {
+ struct bL_thread *t = &bL_threads[cpu];
+ spin_lock_init(&t->lock);
+ init_waitqueue_head(&t->wq);
+ init_completion(&t->started);
+ t->wanted_cluster = -1;
+ t->task = bL_switcher_thread_create(cpu, t);
+ }
+
+ bL_switcher_active = 1;
+ bL_activation_notify(BL_NOTIFY_POST_ENABLE);
+ pr_info("big.LITTLE switcher initialized\n");
+ goto out;
+
+error:
+ pr_warn("big.LITTLE switcher initialization failed\n");
+ bL_activation_notify(BL_NOTIFY_POST_DISABLE);
+
+out:
+ unlock_device_hotplug();
+ mutex_unlock(&bL_switcher_activation_lock);
+ return ret;
+}
+
+#ifdef CONFIG_SYSFS
+
+static void bL_switcher_disable(void)
+{
+ unsigned int cpu, cluster;
+ struct bL_thread *t;
+ struct task_struct *task;
+
+ mutex_lock(&bL_switcher_activation_lock);
+ lock_device_hotplug();
+
+ if (!bL_switcher_active)
+ goto out;
+
+ if (bL_activation_notify(BL_NOTIFY_PRE_DISABLE) != 0) {
+ bL_activation_notify(BL_NOTIFY_POST_ENABLE);
+ goto out;
+ }
+
+ bL_switcher_active = 0;
+
+ /*
+ * To deactivate the switcher, we must shut down the switcher
+ * threads to prevent any other requests from being accepted.
+ * Then, if the final cluster for given logical CPU is not the
+ * same as the original one, we'll recreate a switcher thread
+ * just for the purpose of switching the CPU back without any
+ * possibility for interference from external requests.
+ */
+ for_each_online_cpu(cpu) {
+ t = &bL_threads[cpu];
+ task = t->task;
+ t->task = NULL;
+ if (!task || IS_ERR(task))
+ continue;
+ kthread_stop(task);
+ /* no more switch may happen on this CPU at this point */
+ cluster = MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 1);
+ if (cluster == bL_switcher_cpu_original_cluster[cpu])
+ continue;
+ init_completion(&t->started);
+ t->wanted_cluster = bL_switcher_cpu_original_cluster[cpu];
+ task = bL_switcher_thread_create(cpu, t);
+ if (!IS_ERR(task)) {
+ wait_for_completion(&t->started);
+ kthread_stop(task);
+ cluster = MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 1);
+ if (cluster == bL_switcher_cpu_original_cluster[cpu])
+ continue;
+ }
+ /* If execution gets here, we're in trouble. */
+ pr_crit("%s: unable to restore original cluster for CPU %d\n",
+ __func__, cpu);
+ pr_crit("%s: CPU %d can't be restored\n",
+ __func__, bL_switcher_cpu_pairing[cpu]);
+ cpumask_clear_cpu(bL_switcher_cpu_pairing[cpu],
+ &bL_switcher_removed_logical_cpus);
+ }
+
+ bL_switcher_restore_cpus();
+ bL_switcher_trace_trigger();
+
+ bL_activation_notify(BL_NOTIFY_POST_DISABLE);
+
+out:
+ unlock_device_hotplug();
+ mutex_unlock(&bL_switcher_activation_lock);
+}
+
+static ssize_t bL_switcher_active_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%u\n", bL_switcher_active);
+}
+
+static ssize_t bL_switcher_active_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ int ret;
+
+ switch (buf[0]) {
+ case '0':
+ bL_switcher_disable();
+ ret = 0;
+ break;
+ case '1':
+ ret = bL_switcher_enable();
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return (ret >= 0) ? count : ret;
+}
+
+static ssize_t bL_switcher_trace_trigger_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ int ret = bL_switcher_trace_trigger();
+
+ return ret ? ret : count;
+}
+
+static struct kobj_attribute bL_switcher_active_attr =
+ __ATTR(active, 0644, bL_switcher_active_show, bL_switcher_active_store);
+
+static struct kobj_attribute bL_switcher_trace_trigger_attr =
+ __ATTR(trace_trigger, 0200, NULL, bL_switcher_trace_trigger_store);
+
+static struct attribute *bL_switcher_attrs[] = {
+ &bL_switcher_active_attr.attr,
+ &bL_switcher_trace_trigger_attr.attr,
+ NULL,
+};
+
+static struct attribute_group bL_switcher_attr_group = {
+ .attrs = bL_switcher_attrs,
+};
+
+static struct kobject *bL_switcher_kobj;
+
+static int __init bL_switcher_sysfs_init(void)
+{
+ int ret;
+
+ bL_switcher_kobj = kobject_create_and_add("bL_switcher", kernel_kobj);
+ if (!bL_switcher_kobj)
+ return -ENOMEM;
+ ret = sysfs_create_group(bL_switcher_kobj, &bL_switcher_attr_group);
+ if (ret)
+ kobject_put(bL_switcher_kobj);
+ return ret;
+}
+
+#endif /* CONFIG_SYSFS */
+
+bool bL_switcher_get_enabled(void)
+{
+ mutex_lock(&bL_switcher_activation_lock);
+
+ return bL_switcher_active;
+}
+EXPORT_SYMBOL_GPL(bL_switcher_get_enabled);
+
+void bL_switcher_put_enabled(void)
+{
+ mutex_unlock(&bL_switcher_activation_lock);
+}
+EXPORT_SYMBOL_GPL(bL_switcher_put_enabled);
+
+/*
+ * Veto any CPU hotplug operation on those CPUs we've removed
+ * while the switcher is active.
+ * We're just not ready to deal with that given the trickery involved.
+ */
+static int bL_switcher_hotplug_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ if (bL_switcher_active) {
+ int pairing = bL_switcher_cpu_pairing[(unsigned long)hcpu];
+ switch (action & 0xf) {
+ case CPU_UP_PREPARE:
+ case CPU_DOWN_PREPARE:
+ if (pairing == -1)
+ return NOTIFY_BAD;
+ }
+ }
+ return NOTIFY_DONE;
+}
+
+static bool no_bL_switcher;
+core_param(no_bL_switcher, no_bL_switcher, bool, 0644);
+
+static int __init bL_switcher_init(void)
+{
+ int ret;
+
+ if (!mcpm_is_available())
+ return -ENODEV;
+
+ cpu_notifier(bL_switcher_hotplug_callback, 0);
+
+ if (!no_bL_switcher) {
+ ret = bL_switcher_enable();
+ if (ret)
+ return ret;
+ }
+
+#ifdef CONFIG_SYSFS
+ ret = bL_switcher_sysfs_init();
+ if (ret)
+ pr_err("%s: unable to create sysfs entry\n", __func__);
+#endif
+
+ return 0;
+}
+
+late_initcall(bL_switcher_init);
diff --git a/arch/arm/common/bL_switcher_dummy_if.c b/arch/arm/common/bL_switcher_dummy_if.c
new file mode 100644
index 000000000..3f47f1203
--- /dev/null
+++ b/arch/arm/common/bL_switcher_dummy_if.c
@@ -0,0 +1,71 @@
+/*
+ * arch/arm/common/bL_switcher_dummy_if.c -- b.L switcher dummy interface
+ *
+ * Created by: Nicolas Pitre, November 2012
+ * Copyright: (C) 2012-2013 Linaro Limited
+ *
+ * Dummy interface to user space for debugging purpose only.
+ *
+ * This program is free software; you can redistribute it 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/fs.h>
+#include <linux/miscdevice.h>
+#include <asm/uaccess.h>
+#include <asm/bL_switcher.h>
+
+static ssize_t bL_switcher_write(struct file *file, const char __user *buf,
+ size_t len, loff_t *pos)
+{
+ unsigned char val[3];
+ unsigned int cpu, cluster;
+ int ret;
+
+ pr_debug("%s\n", __func__);
+
+ if (len < 3)
+ return -EINVAL;
+
+ if (copy_from_user(val, buf, 3))
+ return -EFAULT;
+
+ /* format: <cpu#>,<cluster#> */
+ if (val[0] < '0' || val[0] > '9' ||
+ val[1] != ',' ||
+ val[2] < '0' || val[2] > '1')
+ return -EINVAL;
+
+ cpu = val[0] - '0';
+ cluster = val[2] - '0';
+ ret = bL_switch_request(cpu, cluster);
+
+ return ret ? : len;
+}
+
+static const struct file_operations bL_switcher_fops = {
+ .write = bL_switcher_write,
+ .owner = THIS_MODULE,
+};
+
+static struct miscdevice bL_switcher_device = {
+ MISC_DYNAMIC_MINOR,
+ "b.L_switcher",
+ &bL_switcher_fops
+};
+
+static int __init bL_switcher_dummy_if_init(void)
+{
+ return misc_register(&bL_switcher_device);
+}
+
+static void __exit bL_switcher_dummy_if_exit(void)
+{
+ misc_deregister(&bL_switcher_device);
+}
+
+module_init(bL_switcher_dummy_if_init);
+module_exit(bL_switcher_dummy_if_exit);
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
new file mode 100644
index 000000000..1143c4d5c
--- /dev/null
+++ b/arch/arm/common/dmabounce.c
@@ -0,0 +1,579 @@
+/*
+ * 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;
+
+ int (*needs_bounce)(struct device *, dma_addr_t, size_t);
+};
+
+#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 &&
+ b->safe_dma_addr + b->size > 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)) {
+ dev_err(dev, "Trying to %s invalid mapping\n", where);
+ return NULL;
+ }
+ return find_safe_buffer(dev->archdata.dmabounce, dma_addr);
+}
+
+static int needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
+{
+ if (!dev || !dev->archdata.dmabounce)
+ return 0;
+
+ if (dev->dma_mask) {
+ unsigned long limit, mask = *dev->dma_mask;
+
+ 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 -E2BIG;
+ }
+
+ /* Figure out if we need to bounce from the DMA mask. */
+ if ((dma_addr | (dma_addr + size - 1)) & ~mask)
+ return 1;
+ }
+
+ return !!dev->archdata.dmabounce->needs_bounce(dev, dma_addr, size);
+}
+
+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;
+ struct safe_buffer *buf;
+
+ if (device_info)
+ DO_STATS ( device_info->map_op_count++ );
+
+ buf = alloc_safe_buffer(device_info, ptr, size, dir);
+ if (buf == NULL) {
+ dev_err(dev, "%s: unable to map unsafe buffer %p!\n",
+ __func__, ptr);
+ return DMA_ERROR_CODE;
+ }
+
+ 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);
+ }
+
+ return buf->safe_dma_addr;
+}
+
+static inline void unmap_single(struct device *dev, struct safe_buffer *buf,
+ size_t size, enum dma_data_direction dir)
+{
+ 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);
+}
+
+/* ************************************************** */
+
+/*
+ * 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)
+ */
+static dma_addr_t dmabounce_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ dma_addr_t dma_addr;
+ int ret;
+
+ dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n",
+ __func__, page, offset, size, dir);
+
+ dma_addr = pfn_to_dma(dev, page_to_pfn(page)) + offset;
+
+ ret = needs_bounce(dev, dma_addr, size);
+ if (ret < 0)
+ return DMA_ERROR_CODE;
+
+ if (ret == 0) {
+ arm_dma_ops.sync_single_for_device(dev, dma_addr, size, dir);
+ return dma_addr;
+ }
+
+ if (PageHighMem(page)) {
+ dev_err(dev, "DMA buffer bouncing of HIGHMEM pages is not supported\n");
+ return DMA_ERROR_CODE;
+ }
+
+ return map_single(dev, page_address(page) + offset, size, dir);
+}
+
+/*
+ * 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)
+ */
+static void dmabounce_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ struct safe_buffer *buf;
+
+ dev_dbg(dev, "%s(dma=%#x,size=%d,dir=%x)\n",
+ __func__, dma_addr, size, dir);
+
+ buf = find_safe_buffer_dev(dev, dma_addr, __func__);
+ if (!buf) {
+ arm_dma_ops.sync_single_for_cpu(dev, dma_addr, size, dir);
+ return;
+ }
+
+ unmap_single(dev, buf, size, dir);
+}
+
+static int __dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
+ size_t sz, enum dma_data_direction dir)
+{
+ struct safe_buffer *buf;
+ unsigned long off;
+
+ dev_dbg(dev, "%s(dma=%#x,sz=%zx,dir=%x)\n",
+ __func__, addr, sz, dir);
+
+ buf = find_safe_buffer_dev(dev, addr, __func__);
+ if (!buf)
+ return 1;
+
+ off = addr - buf->safe_dma_addr;
+
+ BUG_ON(buf->direction != dir);
+
+ dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x off=%#lx) mapped to %p (dma=%#x)\n",
+ __func__, buf->ptr, virt_to_dma(dev, buf->ptr), off,
+ 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;
+}
+
+static void dmabounce_sync_for_cpu(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ if (!__dmabounce_sync_for_cpu(dev, handle, size, dir))
+ return;
+
+ arm_dma_ops.sync_single_for_cpu(dev, handle, size, dir);
+}
+
+static int __dmabounce_sync_for_device(struct device *dev, dma_addr_t addr,
+ size_t sz, enum dma_data_direction dir)
+{
+ struct safe_buffer *buf;
+ unsigned long off;
+
+ dev_dbg(dev, "%s(dma=%#x,sz=%zx,dir=%x)\n",
+ __func__, addr, sz, dir);
+
+ buf = find_safe_buffer_dev(dev, addr, __func__);
+ if (!buf)
+ return 1;
+
+ off = addr - buf->safe_dma_addr;
+
+ BUG_ON(buf->direction != dir);
+
+ dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x off=%#lx) mapped to %p (dma=%#x)\n",
+ __func__, buf->ptr, virt_to_dma(dev, buf->ptr), off,
+ 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;
+}
+
+static void dmabounce_sync_for_device(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ if (!__dmabounce_sync_for_device(dev, handle, size, dir))
+ return;
+
+ arm_dma_ops.sync_single_for_device(dev, handle, size, dir);
+}
+
+static int dmabounce_set_mask(struct device *dev, u64 dma_mask)
+{
+ if (dev->archdata.dmabounce)
+ return 0;
+
+ return arm_dma_ops.set_dma_mask(dev, dma_mask);
+}
+
+static struct dma_map_ops dmabounce_ops = {
+ .alloc = arm_dma_alloc,
+ .free = arm_dma_free,
+ .mmap = arm_dma_mmap,
+ .get_sgtable = arm_dma_get_sgtable,
+ .map_page = dmabounce_map_page,
+ .unmap_page = dmabounce_unmap_page,
+ .sync_single_for_cpu = dmabounce_sync_for_cpu,
+ .sync_single_for_device = dmabounce_sync_for_device,
+ .map_sg = arm_dma_map_sg,
+ .unmap_sg = arm_dma_unmap_sg,
+ .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu,
+ .sync_sg_for_device = arm_dma_sync_sg_for_device,
+ .set_dma_mask = dmabounce_set_mask,
+};
+
+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,
+ int (*needs_bounce_fn)(struct device *, dma_addr_t, size_t))
+{
+ 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);
+ device_info->needs_bounce = needs_bounce_fn;
+
+#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;
+ set_dma_ops(dev, &dmabounce_ops);
+
+ 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;
+ set_dma_ops(dev, 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/edma.c b/arch/arm/common/edma.c
new file mode 100644
index 000000000..5662a8726
--- /dev/null
+++ b/arch/arm/common/edma.c
@@ -0,0 +1,1873 @@
+/*
+ * 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/err.h>
+#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 <linux/edma.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_dma.h>
+#include <linux/of_irq.h>
+#include <linux/pm_runtime.h>
+
+#include <linux/platform_data/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 */
+
+/* CCCFG register */
+#define GET_NUM_DMACH(x) (x & 0x7) /* bits 0-2 */
+#define GET_NUM_PAENTRY(x) ((x & 0x7000) >> 12) /* bits 12-14 */
+#define GET_NUM_EVQUE(x) ((x & 0x70000) >> 16) /* bits 16-18 */
+#define GET_NUM_REGN(x) ((x & 0x300000) >> 20) /* bits 20-21 */
+#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;
+ enum dma_event_q default_queue;
+
+ /* list of channels with no even trigger; terminated by "-1" */
+ const s8 *noevent;
+
+ struct edma_soc_info *info;
+
+ /* 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 const struct of_device_id edma_of_ids[] = {
+ { .compatible = "ti,edma3", },
+ {}
+};
+
+/*****************************************************************************/
+
+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 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 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 ctlr;
+ u32 sh_ier;
+ u32 sh_ipr;
+ u32 bank;
+
+ ctlr = irq2ctlr(irq);
+ if (ctlr < 0)
+ return IRQ_NONE;
+
+ dev_dbg(data, "dma_irq_handler\n");
+
+ sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 0);
+ if (!sh_ipr) {
+ sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 1);
+ if (!sh_ipr)
+ return IRQ_NONE;
+ sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 1);
+ bank = 1;
+ } else {
+ sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 0);
+ bank = 0;
+ }
+
+ do {
+ u32 slot;
+ u32 channel;
+
+ dev_dbg(data, "IPR%d %08x\n", bank, sh_ipr);
+
+ slot = __ffs(sh_ipr);
+ sh_ipr &= ~(BIT(slot));
+
+ if (sh_ier & BIT(slot)) {
+ channel = (bank << 5) | slot;
+ /* Clear the corresponding IPR bits */
+ edma_shadow0_write_array(ctlr, SH_ICR, bank,
+ BIT(slot));
+ if (edma_cc[ctlr]->intr_data[channel].callback)
+ edma_cc[ctlr]->intr_data[channel].callback(
+ channel, EDMA_DMA_COMPLETE,
+ edma_cc[ctlr]->intr_data[channel].data);
+ }
+ } while (sh_ipr);
+
+ 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,
+ EDMA_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;
+}
+
+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;
+
+ j = start_slot;
+ for_each_set_bit_from(j, tmp_inuse, stop_slot)
+ 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, count, ctlr;
+ struct of_phandle_args dma_spec;
+
+ if (dev->of_node) {
+ count = of_property_count_strings(dev->of_node, "dma-names");
+ if (count < 0)
+ return 0;
+ for (i = 0; i < count; i++) {
+ if (of_parse_phandle_with_args(dev->of_node, "dmas",
+ "#dma-cells", i,
+ &dma_spec))
+ continue;
+
+ if (!of_match_node(edma_of_ids, dma_spec.np)) {
+ of_node_put(dma_spec.np);
+ continue;
+ }
+
+ clear_bit(EDMA_CHAN_SLOT(dma_spec.args[0]),
+ edma_cc[0]->edma_unused);
+ of_node_put(dma_spec.np);
+ }
+ return 0;
+ }
+
+ /* For non-OF case */
+ 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 (!edma_cc[ctlr])
+ return -EINVAL;
+
+ 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 point
+ * @slot: parameter RAM slot being examined
+ * @dst: true selects the dest position, false the source
+ *
+ * Returns the position of the current active slot
+ */
+dma_addr_t edma_get_position(unsigned slot, bool dst)
+{
+ u32 offs, ctlr = EDMA_CTLR(slot);
+
+ slot = EDMA_CHAN_SLOT(slot);
+
+ offs = PARM_OFFSET(slot);
+ offs += dst ? PARM_DST : PARM_SRC;
+
+ return edma_read(ctlr, offs);
+}
+
+/**
+ * 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);
+
+int edma_trigger_channel(unsigned channel)
+{
+ unsigned ctlr;
+ unsigned int mask;
+
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+ mask = BIT(channel & 0x1f);
+
+ edma_shadow0_write_array(ctlr, SH_ESR, (channel >> 5), mask);
+
+ pr_debug("EDMA: ESR%d %08x\n", (channel >> 5),
+ edma_shadow0_read_array(ctlr, SH_ESR, (channel >> 5)));
+ return 0;
+}
+EXPORT_SYMBOL(edma_trigger_channel);
+
+/**
+ * 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);
+
+/*
+ * edma_assign_channel_eventq - move given channel to desired eventq
+ * Arguments:
+ * channel - channel number
+ * eventq_no - queue to move the channel
+ *
+ * Can be used to move a channel to a selected event queue.
+ */
+void edma_assign_channel_eventq(unsigned channel, enum dma_event_q eventq_no)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+
+ if (channel >= edma_cc[ctlr]->num_channels)
+ return;
+
+ /* default to low priority queue */
+ if (eventq_no == EVENTQ_DEFAULT)
+ eventq_no = edma_cc[ctlr]->default_queue;
+ if (eventq_no >= edma_cc[ctlr]->num_tc)
+ return;
+
+ map_dmach_queue(ctlr, channel, eventq_no);
+}
+EXPORT_SYMBOL(edma_assign_channel_eventq);
+
+static int edma_setup_from_hw(struct device *dev, struct edma_soc_info *pdata,
+ struct edma *edma_cc, int cc_id)
+{
+ int i;
+ u32 value, cccfg;
+ s8 (*queue_priority_map)[2];
+
+ /* Decode the eDMA3 configuration from CCCFG register */
+ cccfg = edma_read(cc_id, EDMA_CCCFG);
+
+ value = GET_NUM_REGN(cccfg);
+ edma_cc->num_region = BIT(value);
+
+ value = GET_NUM_DMACH(cccfg);
+ edma_cc->num_channels = BIT(value + 1);
+
+ value = GET_NUM_PAENTRY(cccfg);
+ edma_cc->num_slots = BIT(value + 4);
+
+ value = GET_NUM_EVQUE(cccfg);
+ edma_cc->num_tc = value + 1;
+
+ dev_dbg(dev, "eDMA3 CC%d HW configuration (cccfg: 0x%08x):\n", cc_id,
+ cccfg);
+ dev_dbg(dev, "num_region: %u\n", edma_cc->num_region);
+ dev_dbg(dev, "num_channel: %u\n", edma_cc->num_channels);
+ dev_dbg(dev, "num_slot: %u\n", edma_cc->num_slots);
+ dev_dbg(dev, "num_tc: %u\n", edma_cc->num_tc);
+
+ /* Nothing need to be done if queue priority is provided */
+ if (pdata->queue_priority_mapping)
+ return 0;
+
+ /*
+ * Configure TC/queue priority as follows:
+ * Q0 - priority 0
+ * Q1 - priority 1
+ * Q2 - priority 2
+ * ...
+ * The meaning of priority numbers: 0 highest priority, 7 lowest
+ * priority. So Q0 is the highest priority queue and the last queue has
+ * the lowest priority.
+ */
+ queue_priority_map = devm_kzalloc(dev,
+ (edma_cc->num_tc + 1) * sizeof(s8),
+ GFP_KERNEL);
+ if (!queue_priority_map)
+ return -ENOMEM;
+
+ for (i = 0; i < edma_cc->num_tc; i++) {
+ queue_priority_map[i][0] = i;
+ queue_priority_map[i][1] = i;
+ }
+ queue_priority_map[i][0] = -1;
+ queue_priority_map[i][1] = -1;
+
+ pdata->queue_priority_mapping = queue_priority_map;
+ /* Default queue has the lowest priority */
+ pdata->default_queue = i - 1;
+
+ return 0;
+}
+
+#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DMADEVICES)
+
+static int edma_xbar_event_map(struct device *dev, struct device_node *node,
+ struct edma_soc_info *pdata, size_t sz)
+{
+ const char pname[] = "ti,edma-xbar-event-map";
+ struct resource res;
+ void __iomem *xbar;
+ s16 (*xbar_chans)[2];
+ size_t nelm = sz / sizeof(s16);
+ u32 shift, offset, mux;
+ int ret, i;
+
+ xbar_chans = devm_kzalloc(dev, (nelm + 2) * sizeof(s16), GFP_KERNEL);
+ if (!xbar_chans)
+ return -ENOMEM;
+
+ ret = of_address_to_resource(node, 1, &res);
+ if (ret)
+ return -ENOMEM;
+
+ xbar = devm_ioremap(dev, res.start, resource_size(&res));
+ if (!xbar)
+ return -ENOMEM;
+
+ ret = of_property_read_u16_array(node, pname, (u16 *)xbar_chans, nelm);
+ if (ret)
+ return -EIO;
+
+ /* Invalidate last entry for the other user of this mess */
+ nelm >>= 1;
+ xbar_chans[nelm][0] = xbar_chans[nelm][1] = -1;
+
+ for (i = 0; i < nelm; i++) {
+ shift = (xbar_chans[i][1] & 0x03) << 3;
+ offset = xbar_chans[i][1] & 0xfffffffc;
+ mux = readl(xbar + offset);
+ mux &= ~(0xff << shift);
+ mux |= xbar_chans[i][0] << shift;
+ writel(mux, (xbar + offset));
+ }
+
+ pdata->xbar_chans = (const s16 (*)[2]) xbar_chans;
+ return 0;
+}
+
+static int edma_of_parse_dt(struct device *dev,
+ struct device_node *node,
+ struct edma_soc_info *pdata)
+{
+ int ret = 0;
+ struct property *prop;
+ size_t sz;
+ struct edma_rsv_info *rsv_info;
+
+ rsv_info = devm_kzalloc(dev, sizeof(struct edma_rsv_info), GFP_KERNEL);
+ if (!rsv_info)
+ return -ENOMEM;
+ pdata->rsv = rsv_info;
+
+ prop = of_find_property(node, "ti,edma-xbar-event-map", &sz);
+ if (prop)
+ ret = edma_xbar_event_map(dev, node, pdata, sz);
+
+ return ret;
+}
+
+static struct of_dma_filter_info edma_filter_info = {
+ .filter_fn = edma_filter_fn,
+};
+
+static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
+ struct device_node *node)
+{
+ struct edma_soc_info *info;
+ int ret;
+
+ info = devm_kzalloc(dev, sizeof(struct edma_soc_info), GFP_KERNEL);
+ if (!info)
+ return ERR_PTR(-ENOMEM);
+
+ ret = edma_of_parse_dt(dev, node, info);
+ if (ret)
+ return ERR_PTR(ret);
+
+ dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap);
+ dma_cap_set(DMA_CYCLIC, edma_filter_info.dma_cap);
+ of_dma_controller_register(dev->of_node, of_dma_simple_xlate,
+ &edma_filter_info);
+
+ return info;
+}
+#else
+static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
+ struct device_node *node)
+{
+ return ERR_PTR(-ENOSYS);
+}
+#endif
+
+static int edma_probe(struct platform_device *pdev)
+{
+ struct edma_soc_info **info = pdev->dev.platform_data;
+ struct edma_soc_info *ninfo[EDMA_MAX_CC] = {NULL};
+ s8 (*queue_priority_mapping)[2];
+ int i, j, off, ln, found = 0;
+ int status = -1;
+ const s16 (*rsv_chans)[2];
+ const s16 (*rsv_slots)[2];
+ const s16 (*xbar_chans)[2];
+ int irq[EDMA_MAX_CC] = {0, 0};
+ int err_irq[EDMA_MAX_CC] = {0, 0};
+ struct resource *r[EDMA_MAX_CC] = {NULL};
+ struct resource res[EDMA_MAX_CC];
+ char res_name[10];
+ struct device_node *node = pdev->dev.of_node;
+ struct device *dev = &pdev->dev;
+ int ret;
+ struct platform_device_info edma_dev_info = {
+ .name = "edma-dma-engine",
+ .dma_mask = DMA_BIT_MASK(32),
+ .parent = &pdev->dev,
+ };
+
+ if (node) {
+ /* Check if this is a second instance registered */
+ if (arch_num_cc) {
+ dev_err(dev, "only one EDMA instance is supported via DT\n");
+ return -ENODEV;
+ }
+
+ ninfo[0] = edma_setup_info_from_dt(dev, node);
+ if (IS_ERR(ninfo[0])) {
+ dev_err(dev, "failed to get DT data\n");
+ return PTR_ERR(ninfo[0]);
+ }
+
+ info = ninfo;
+ }
+
+ if (!info)
+ return -ENODEV;
+
+ pm_runtime_enable(dev);
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ dev_err(dev, "pm_runtime_get_sync() failed\n");
+ return ret;
+ }
+
+ for (j = 0; j < EDMA_MAX_CC; j++) {
+ if (!info[j]) {
+ if (!found)
+ return -ENODEV;
+ break;
+ }
+ if (node) {
+ ret = of_address_to_resource(node, j, &res[j]);
+ if (!ret)
+ r[j] = &res[j];
+ } else {
+ sprintf(res_name, "edma_cc%d", j);
+ r[j] = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM,
+ res_name);
+ }
+ if (!r[j]) {
+ if (found)
+ break;
+ else
+ return -ENODEV;
+ } else {
+ found = 1;
+ }
+
+ edmacc_regs_base[j] = devm_ioremap_resource(&pdev->dev, r[j]);
+ if (IS_ERR(edmacc_regs_base[j]))
+ return PTR_ERR(edmacc_regs_base[j]);
+
+ edma_cc[j] = devm_kzalloc(&pdev->dev, sizeof(struct edma),
+ GFP_KERNEL);
+ if (!edma_cc[j])
+ return -ENOMEM;
+
+ /* Get eDMA3 configuration from IP */
+ ret = edma_setup_from_hw(dev, info[j], edma_cc[j], j);
+ if (ret)
+ return ret;
+
+ edma_cc[j]->default_queue = info[j]->default_queue;
+
+ 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);
+ }
+ }
+ }
+
+ /* Clear the xbar mapped channels in unused list */
+ xbar_chans = info[j]->xbar_chans;
+ if (xbar_chans) {
+ for (i = 0; xbar_chans[i][1] != -1; i++) {
+ off = xbar_chans[i][1];
+ clear_bits(off, 1,
+ edma_cc[j]->edma_unused);
+ }
+ }
+
+ if (node) {
+ irq[j] = irq_of_parse_and_map(node, 0);
+ err_irq[j] = irq_of_parse_and_map(node, 2);
+ } else {
+ char irq_name[10];
+
+ sprintf(irq_name, "edma%d", j);
+ irq[j] = platform_get_irq_byname(pdev, irq_name);
+
+ sprintf(irq_name, "edma%d_err", j);
+ err_irq[j] = platform_get_irq_byname(pdev, irq_name);
+ }
+ edma_cc[j]->irq_res_start = irq[j];
+ edma_cc[j]->irq_res_end = err_irq[j];
+
+ status = devm_request_irq(dev, irq[j], dma_irq_handler, 0,
+ "edma", dev);
+ if (status < 0) {
+ dev_dbg(&pdev->dev,
+ "devm_request_irq %d failed --> %d\n",
+ irq[j], status);
+ return status;
+ }
+
+ status = devm_request_irq(dev, err_irq[j], dma_ccerr_handler, 0,
+ "edma_error", dev);
+ if (status < 0) {
+ dev_dbg(&pdev->dev,
+ "devm_request_irq %d failed --> %d\n",
+ err_irq[j], status);
+ return status;
+ }
+
+ for (i = 0; i < edma_cc[j]->num_channels; i++)
+ map_dmach_queue(j, i, info[j]->default_queue);
+
+ queue_priority_mapping = info[j]->queue_priority_mapping;
+
+ /* 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 < edma_cc[j]->num_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);
+ }
+ edma_cc[j]->info = info[j];
+ arch_num_cc++;
+
+ edma_dev_info.id = j;
+ platform_device_register_full(&edma_dev_info);
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int edma_pm_resume(struct device *dev)
+{
+ int i, j;
+
+ for (j = 0; j < arch_num_cc; j++) {
+ struct edma *cc = edma_cc[j];
+
+ s8 (*queue_priority_mapping)[2];
+
+ queue_priority_mapping = cc->info->queue_priority_mapping;
+
+ /* 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 < cc->num_channels; i++) {
+ if (test_bit(i, cc->edma_inuse)) {
+ /* ensure access through shadow region 0 */
+ edma_or_array2(j, EDMA_DRAE, 0, i >> 5,
+ BIT(i & 0x1f));
+
+ setup_dma_interrupt(i,
+ cc->intr_data[i].callback,
+ cc->intr_data[i].data);
+ }
+ }
+ }
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops edma_pm_ops = {
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, edma_pm_resume)
+};
+
+static struct platform_driver edma_driver = {
+ .driver = {
+ .name = "edma",
+ .pm = &edma_pm_ops,
+ .of_match_table = edma_of_ids,
+ },
+ .probe = edma_probe,
+};
+
+static int __init edma_init(void)
+{
+ return platform_driver_probe(&edma_driver, edma_probe);
+}
+arch_initcall(edma_init);
+
diff --git a/arch/arm/common/firmware.c b/arch/arm/common/firmware.c
new file mode 100644
index 000000000..27ddccb11
--- /dev/null
+++ b/arch/arm/common/firmware.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics.
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ * Tomasz Figa <t.figa@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/suspend.h>
+
+#include <asm/firmware.h>
+
+static const struct firmware_ops default_firmware_ops;
+
+const struct firmware_ops *firmware_ops = &default_firmware_ops;
diff --git a/arch/arm/common/icst.c b/arch/arm/common/icst.c
new file mode 100644
index 000000000..2dc6da70a
--- /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 000000000..5114b68e9
--- /dev/null
+++ b/arch/arm/common/it8152.c
@@ -0,0 +1,355 @@
+/*
+ * 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 <linux/export.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(const 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;
+}
+
+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
+ */
+static int it8152_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 (dma_addr + size - PHYS_OFFSET) >= SZ_64M;
+}
+
+/*
+ * 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_is_pci(dev)) {
+ 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, it8152_needs_bounce);
+ }
+ return 0;
+}
+
+static int it8152_pci_platform_notify_remove(struct device *dev)
+{
+ if (dev_is_pci(dev))
+ dmabounce_unregister_dev(dev);
+
+ return 0;
+}
+
+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)
+{
+ /*
+ * FIXME: use pci_ioremap_io to remap the IO space here and
+ * move over to the generic io.h implementation.
+ * This requires solving the same problem for PXA PCMCIA
+ * support.
+ */
+ it8152_io.start = (unsigned long)IT8152_IO_BASE + 0x12000;
+ it8152_io.end = (unsigned long)IT8152_IO_BASE + 0x12000 + 0x100000;
+
+ sys->mem_offset = 0x10000000;
+ sys->io_offset = (unsigned long)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;
+ }
+
+ pci_add_resource_offset(&sys->resources, &it8152_io, sys->io_offset);
+ pci_add_resource_offset(&sys->resources, &it8152_mem, sys->mem_offset);
+
+ 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;
+}
+
+/* ITE bridge requires setting latency timer to avoid early bus access
+ termination by PCI bus master devices
+*/
+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);
+}
+
+
+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 000000000..b55c3625d
--- /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/mcpm_entry.c b/arch/arm/common/mcpm_entry.c
new file mode 100644
index 000000000..5f8a52ac7
--- /dev/null
+++ b/arch/arm/common/mcpm_entry.c
@@ -0,0 +1,486 @@
+/*
+ * arch/arm/common/mcpm_entry.c -- entry point for multi-cluster PM
+ *
+ * Created by: Nicolas Pitre, March 2012
+ * Copyright: (C) 2012-2013 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irqflags.h>
+#include <linux/cpu_pm.h>
+
+#include <asm/mcpm.h>
+#include <asm/cacheflush.h>
+#include <asm/idmap.h>
+#include <asm/cputype.h>
+#include <asm/suspend.h>
+
+extern unsigned long mcpm_entry_vectors[MAX_NR_CLUSTERS][MAX_CPUS_PER_CLUSTER];
+
+void mcpm_set_entry_vector(unsigned cpu, unsigned cluster, void *ptr)
+{
+ unsigned long val = ptr ? virt_to_phys(ptr) : 0;
+ mcpm_entry_vectors[cluster][cpu] = val;
+ sync_cache_w(&mcpm_entry_vectors[cluster][cpu]);
+}
+
+extern unsigned long mcpm_entry_early_pokes[MAX_NR_CLUSTERS][MAX_CPUS_PER_CLUSTER][2];
+
+void mcpm_set_early_poke(unsigned cpu, unsigned cluster,
+ unsigned long poke_phys_addr, unsigned long poke_val)
+{
+ unsigned long *poke = &mcpm_entry_early_pokes[cluster][cpu][0];
+ poke[0] = poke_phys_addr;
+ poke[1] = poke_val;
+ __sync_cache_range_w(poke, 2 * sizeof(*poke));
+}
+
+static const struct mcpm_platform_ops *platform_ops;
+
+int __init mcpm_platform_register(const struct mcpm_platform_ops *ops)
+{
+ if (platform_ops)
+ return -EBUSY;
+ platform_ops = ops;
+ return 0;
+}
+
+bool mcpm_is_available(void)
+{
+ return (platform_ops) ? true : false;
+}
+
+/*
+ * We can't use regular spinlocks. In the switcher case, it is possible
+ * for an outbound CPU to call power_down() after its inbound counterpart
+ * is already live using the same logical CPU number which trips lockdep
+ * debugging.
+ */
+static arch_spinlock_t mcpm_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+
+static int mcpm_cpu_use_count[MAX_NR_CLUSTERS][MAX_CPUS_PER_CLUSTER];
+
+static inline bool mcpm_cluster_unused(unsigned int cluster)
+{
+ int i, cnt;
+ for (i = 0, cnt = 0; i < MAX_CPUS_PER_CLUSTER; i++)
+ cnt |= mcpm_cpu_use_count[cluster][i];
+ return !cnt;
+}
+
+int mcpm_cpu_power_up(unsigned int cpu, unsigned int cluster)
+{
+ bool cpu_is_down, cluster_is_down;
+ int ret = 0;
+
+ if (!platform_ops)
+ return -EUNATCH; /* try not to shadow power_up errors */
+ might_sleep();
+
+ /* backward compatibility callback */
+ if (platform_ops->power_up)
+ return platform_ops->power_up(cpu, cluster);
+
+ pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+
+ /*
+ * Since this is called with IRQs enabled, and no arch_spin_lock_irq
+ * variant exists, we need to disable IRQs manually here.
+ */
+ local_irq_disable();
+ arch_spin_lock(&mcpm_lock);
+
+ cpu_is_down = !mcpm_cpu_use_count[cluster][cpu];
+ cluster_is_down = mcpm_cluster_unused(cluster);
+
+ mcpm_cpu_use_count[cluster][cpu]++;
+ /*
+ * The only possible values are:
+ * 0 = CPU down
+ * 1 = CPU (still) up
+ * 2 = CPU requested to be up before it had a chance
+ * to actually make itself down.
+ * Any other value is a bug.
+ */
+ BUG_ON(mcpm_cpu_use_count[cluster][cpu] != 1 &&
+ mcpm_cpu_use_count[cluster][cpu] != 2);
+
+ if (cluster_is_down)
+ ret = platform_ops->cluster_powerup(cluster);
+ if (cpu_is_down && !ret)
+ ret = platform_ops->cpu_powerup(cpu, cluster);
+
+ arch_spin_unlock(&mcpm_lock);
+ local_irq_enable();
+ return ret;
+}
+
+typedef void (*phys_reset_t)(unsigned long);
+
+void mcpm_cpu_power_down(void)
+{
+ unsigned int mpidr, cpu, cluster;
+ bool cpu_going_down, last_man;
+ phys_reset_t phys_reset;
+
+ if (WARN_ON_ONCE(!platform_ops))
+ return;
+ BUG_ON(!irqs_disabled());
+
+ /*
+ * Do this before calling into the power_down method,
+ * as it might not always be safe to do afterwards.
+ */
+ setup_mm_for_reboot();
+
+ /* backward compatibility callback */
+ if (platform_ops->power_down) {
+ platform_ops->power_down();
+ goto not_dead;
+ }
+
+ mpidr = read_cpuid_mpidr();
+ cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+ pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+
+ __mcpm_cpu_going_down(cpu, cluster);
+
+ arch_spin_lock(&mcpm_lock);
+ BUG_ON(__mcpm_cluster_state(cluster) != CLUSTER_UP);
+
+ mcpm_cpu_use_count[cluster][cpu]--;
+ BUG_ON(mcpm_cpu_use_count[cluster][cpu] != 0 &&
+ mcpm_cpu_use_count[cluster][cpu] != 1);
+ cpu_going_down = !mcpm_cpu_use_count[cluster][cpu];
+ last_man = mcpm_cluster_unused(cluster);
+
+ if (last_man && __mcpm_outbound_enter_critical(cpu, cluster)) {
+ platform_ops->cpu_powerdown_prepare(cpu, cluster);
+ platform_ops->cluster_powerdown_prepare(cluster);
+ arch_spin_unlock(&mcpm_lock);
+ platform_ops->cluster_cache_disable();
+ __mcpm_outbound_leave_critical(cluster, CLUSTER_DOWN);
+ } else {
+ if (cpu_going_down)
+ platform_ops->cpu_powerdown_prepare(cpu, cluster);
+ arch_spin_unlock(&mcpm_lock);
+ /*
+ * If cpu_going_down is false here, that means a power_up
+ * request raced ahead of us. Even if we do not want to
+ * shut this CPU down, the caller still expects execution
+ * to return through the system resume entry path, like
+ * when the WFI is aborted due to a new IRQ or the like..
+ * So let's continue with cache cleaning in all cases.
+ */
+ platform_ops->cpu_cache_disable();
+ }
+
+ __mcpm_cpu_down(cpu, cluster);
+
+ /* Now we are prepared for power-down, do it: */
+ if (cpu_going_down)
+ wfi();
+
+not_dead:
+ /*
+ * It is possible for a power_up request to happen concurrently
+ * with a power_down request for the same CPU. In this case the
+ * CPU might not be able to actually enter a powered down state
+ * with the WFI instruction if the power_up request has removed
+ * the required reset condition. We must perform a re-entry in
+ * the kernel as if the power_up method just had deasserted reset
+ * on the CPU.
+ */
+ phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset);
+ phys_reset(virt_to_phys(mcpm_entry_point));
+
+ /* should never get here */
+ BUG();
+}
+
+int mcpm_wait_for_cpu_powerdown(unsigned int cpu, unsigned int cluster)
+{
+ int ret;
+
+ if (WARN_ON_ONCE(!platform_ops || !platform_ops->wait_for_powerdown))
+ return -EUNATCH;
+
+ ret = platform_ops->wait_for_powerdown(cpu, cluster);
+ if (ret)
+ pr_warn("%s: cpu %u, cluster %u failed to power down (%d)\n",
+ __func__, cpu, cluster, ret);
+
+ return ret;
+}
+
+void mcpm_cpu_suspend(u64 expected_residency)
+{
+ if (WARN_ON_ONCE(!platform_ops))
+ return;
+
+ /* backward compatibility callback */
+ if (platform_ops->suspend) {
+ phys_reset_t phys_reset;
+ BUG_ON(!irqs_disabled());
+ setup_mm_for_reboot();
+ platform_ops->suspend(expected_residency);
+ phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset);
+ phys_reset(virt_to_phys(mcpm_entry_point));
+ BUG();
+ }
+
+ /* Some platforms might have to enable special resume modes, etc. */
+ if (platform_ops->cpu_suspend_prepare) {
+ unsigned int mpidr = read_cpuid_mpidr();
+ unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+ arch_spin_lock(&mcpm_lock);
+ platform_ops->cpu_suspend_prepare(cpu, cluster);
+ arch_spin_unlock(&mcpm_lock);
+ }
+ mcpm_cpu_power_down();
+}
+
+int mcpm_cpu_powered_up(void)
+{
+ unsigned int mpidr, cpu, cluster;
+ bool cpu_was_down, first_man;
+ unsigned long flags;
+
+ if (!platform_ops)
+ return -EUNATCH;
+
+ /* backward compatibility callback */
+ if (platform_ops->powered_up) {
+ platform_ops->powered_up();
+ return 0;
+ }
+
+ mpidr = read_cpuid_mpidr();
+ cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+ local_irq_save(flags);
+ arch_spin_lock(&mcpm_lock);
+
+ cpu_was_down = !mcpm_cpu_use_count[cluster][cpu];
+ first_man = mcpm_cluster_unused(cluster);
+
+ if (first_man && platform_ops->cluster_is_up)
+ platform_ops->cluster_is_up(cluster);
+ if (cpu_was_down)
+ mcpm_cpu_use_count[cluster][cpu] = 1;
+ if (platform_ops->cpu_is_up)
+ platform_ops->cpu_is_up(cpu, cluster);
+
+ arch_spin_unlock(&mcpm_lock);
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+#ifdef CONFIG_ARM_CPU_SUSPEND
+
+static int __init nocache_trampoline(unsigned long _arg)
+{
+ void (*cache_disable)(void) = (void *)_arg;
+ unsigned int mpidr = read_cpuid_mpidr();
+ unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+ phys_reset_t phys_reset;
+
+ mcpm_set_entry_vector(cpu, cluster, cpu_resume);
+ setup_mm_for_reboot();
+
+ __mcpm_cpu_going_down(cpu, cluster);
+ BUG_ON(!__mcpm_outbound_enter_critical(cpu, cluster));
+ cache_disable();
+ __mcpm_outbound_leave_critical(cluster, CLUSTER_DOWN);
+ __mcpm_cpu_down(cpu, cluster);
+
+ phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset);
+ phys_reset(virt_to_phys(mcpm_entry_point));
+ BUG();
+}
+
+int __init mcpm_loopback(void (*cache_disable)(void))
+{
+ int ret;
+
+ /*
+ * We're going to soft-restart the current CPU through the
+ * low-level MCPM code by leveraging the suspend/resume
+ * infrastructure. Let's play it safe by using cpu_pm_enter()
+ * in case the CPU init code path resets the VFP or similar.
+ */
+ local_irq_disable();
+ local_fiq_disable();
+ ret = cpu_pm_enter();
+ if (!ret) {
+ ret = cpu_suspend((unsigned long)cache_disable, nocache_trampoline);
+ cpu_pm_exit();
+ }
+ local_fiq_enable();
+ local_irq_enable();
+ if (ret)
+ pr_err("%s returned %d\n", __func__, ret);
+ return ret;
+}
+
+#endif
+
+struct sync_struct mcpm_sync;
+
+/*
+ * __mcpm_cpu_going_down: Indicates that the cpu is being torn down.
+ * This must be called at the point of committing to teardown of a CPU.
+ * The CPU cache (SCTRL.C bit) is expected to still be active.
+ */
+void __mcpm_cpu_going_down(unsigned int cpu, unsigned int cluster)
+{
+ mcpm_sync.clusters[cluster].cpus[cpu].cpu = CPU_GOING_DOWN;
+ sync_cache_w(&mcpm_sync.clusters[cluster].cpus[cpu].cpu);
+}
+
+/*
+ * __mcpm_cpu_down: Indicates that cpu teardown is complete and that the
+ * cluster can be torn down without disrupting this CPU.
+ * To avoid deadlocks, this must be called before a CPU is powered down.
+ * The CPU cache (SCTRL.C bit) is expected to be off.
+ * However L2 cache might or might not be active.
+ */
+void __mcpm_cpu_down(unsigned int cpu, unsigned int cluster)
+{
+ dmb();
+ mcpm_sync.clusters[cluster].cpus[cpu].cpu = CPU_DOWN;
+ sync_cache_w(&mcpm_sync.clusters[cluster].cpus[cpu].cpu);
+ sev();
+}
+
+/*
+ * __mcpm_outbound_leave_critical: Leave the cluster teardown critical section.
+ * @state: the final state of the cluster:
+ * CLUSTER_UP: no destructive teardown was done and the cluster has been
+ * restored to the previous state (CPU cache still active); or
+ * CLUSTER_DOWN: the cluster has been torn-down, ready for power-off
+ * (CPU cache disabled, L2 cache either enabled or disabled).
+ */
+void __mcpm_outbound_leave_critical(unsigned int cluster, int state)
+{
+ dmb();
+ mcpm_sync.clusters[cluster].cluster = state;
+ sync_cache_w(&mcpm_sync.clusters[cluster].cluster);
+ sev();
+}
+
+/*
+ * __mcpm_outbound_enter_critical: Enter the cluster teardown critical section.
+ * This function should be called by the last man, after local CPU teardown
+ * is complete. CPU cache expected to be active.
+ *
+ * Returns:
+ * false: the critical section was not entered because an inbound CPU was
+ * observed, or the cluster is already being set up;
+ * true: the critical section was entered: it is now safe to tear down the
+ * cluster.
+ */
+bool __mcpm_outbound_enter_critical(unsigned int cpu, unsigned int cluster)
+{
+ unsigned int i;
+ struct mcpm_sync_struct *c = &mcpm_sync.clusters[cluster];
+
+ /* Warn inbound CPUs that the cluster is being torn down: */
+ c->cluster = CLUSTER_GOING_DOWN;
+ sync_cache_w(&c->cluster);
+
+ /* Back out if the inbound cluster is already in the critical region: */
+ sync_cache_r(&c->inbound);
+ if (c->inbound == INBOUND_COMING_UP)
+ goto abort;
+
+ /*
+ * Wait for all CPUs to get out of the GOING_DOWN state, so that local
+ * teardown is complete on each CPU before tearing down the cluster.
+ *
+ * If any CPU has been woken up again from the DOWN state, then we
+ * shouldn't be taking the cluster down at all: abort in that case.
+ */
+ sync_cache_r(&c->cpus);
+ for (i = 0; i < MAX_CPUS_PER_CLUSTER; i++) {
+ int cpustate;
+
+ if (i == cpu)
+ continue;
+
+ while (1) {
+ cpustate = c->cpus[i].cpu;
+ if (cpustate != CPU_GOING_DOWN)
+ break;
+
+ wfe();
+ sync_cache_r(&c->cpus[i].cpu);
+ }
+
+ switch (cpustate) {
+ case CPU_DOWN:
+ continue;
+
+ default:
+ goto abort;
+ }
+ }
+
+ return true;
+
+abort:
+ __mcpm_outbound_leave_critical(cluster, CLUSTER_UP);
+ return false;
+}
+
+int __mcpm_cluster_state(unsigned int cluster)
+{
+ sync_cache_r(&mcpm_sync.clusters[cluster].cluster);
+ return mcpm_sync.clusters[cluster].cluster;
+}
+
+extern unsigned long mcpm_power_up_setup_phys;
+
+int __init mcpm_sync_init(
+ void (*power_up_setup)(unsigned int affinity_level))
+{
+ unsigned int i, j, mpidr, this_cluster;
+
+ BUILD_BUG_ON(MCPM_SYNC_CLUSTER_SIZE * MAX_NR_CLUSTERS != sizeof mcpm_sync);
+ BUG_ON((unsigned long)&mcpm_sync & (__CACHE_WRITEBACK_GRANULE - 1));
+
+ /*
+ * Set initial CPU and cluster states.
+ * Only one cluster is assumed to be active at this point.
+ */
+ for (i = 0; i < MAX_NR_CLUSTERS; i++) {
+ mcpm_sync.clusters[i].cluster = CLUSTER_DOWN;
+ mcpm_sync.clusters[i].inbound = INBOUND_NOT_COMING_UP;
+ for (j = 0; j < MAX_CPUS_PER_CLUSTER; j++)
+ mcpm_sync.clusters[i].cpus[j].cpu = CPU_DOWN;
+ }
+ mpidr = read_cpuid_mpidr();
+ this_cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+ for_each_online_cpu(i) {
+ mcpm_cpu_use_count[this_cluster][i] = 1;
+ mcpm_sync.clusters[this_cluster].cpus[i].cpu = CPU_UP;
+ }
+ mcpm_sync.clusters[this_cluster].cluster = CLUSTER_UP;
+ sync_cache_w(&mcpm_sync);
+
+ if (power_up_setup) {
+ mcpm_power_up_setup_phys = virt_to_phys(power_up_setup);
+ sync_cache_w(&mcpm_power_up_setup_phys);
+ }
+
+ return 0;
+}
diff --git a/arch/arm/common/mcpm_head.S b/arch/arm/common/mcpm_head.S
new file mode 100644
index 000000000..e02db4b81
--- /dev/null
+++ b/arch/arm/common/mcpm_head.S
@@ -0,0 +1,233 @@
+/*
+ * arch/arm/common/mcpm_head.S -- kernel entry point for multi-cluster PM
+ *
+ * Created by: Nicolas Pitre, March 2012
+ * Copyright: (C) 2012-2013 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.
+ *
+ *
+ * Refer to Documentation/arm/cluster-pm-race-avoidance.txt
+ * for details of the synchronisation algorithms used here.
+ */
+
+#include <linux/linkage.h>
+#include <asm/mcpm.h>
+#include <asm/assembler.h>
+
+#include "vlock.h"
+
+.if MCPM_SYNC_CLUSTER_CPUS
+.error "cpus must be the first member of struct mcpm_sync_struct"
+.endif
+
+ .macro pr_dbg string
+#if defined(CONFIG_DEBUG_LL) && defined(DEBUG)
+ b 1901f
+1902: .asciz "CPU"
+1903: .asciz " cluster"
+1904: .asciz ": \string"
+ .align
+1901: adr r0, 1902b
+ bl printascii
+ mov r0, r9
+ bl printhex2
+ adr r0, 1903b
+ bl printascii
+ mov r0, r10
+ bl printhex2
+ adr r0, 1904b
+ bl printascii
+#endif
+ .endm
+
+ .arm
+ .align
+
+ENTRY(mcpm_entry_point)
+
+ ARM_BE8(setend be)
+ THUMB( adr r12, BSYM(1f) )
+ THUMB( bx r12 )
+ THUMB( .thumb )
+1:
+ mrc p15, 0, r0, c0, c0, 5 @ MPIDR
+ ubfx r9, r0, #0, #8 @ r9 = cpu
+ ubfx r10, r0, #8, #8 @ r10 = cluster
+ mov r3, #MAX_CPUS_PER_CLUSTER
+ mla r4, r3, r10, r9 @ r4 = canonical CPU index
+ cmp r4, #(MAX_CPUS_PER_CLUSTER * MAX_NR_CLUSTERS)
+ blo 2f
+
+ /* We didn't expect this CPU. Try to cheaply make it quiet. */
+1: wfi
+ wfe
+ b 1b
+
+2: pr_dbg "kernel mcpm_entry_point\n"
+
+ /*
+ * MMU is off so we need to get to various variables in a
+ * position independent way.
+ */
+ adr r5, 3f
+ ldmia r5, {r0, r6, r7, r8, r11}
+ add r0, r5, r0 @ r0 = mcpm_entry_early_pokes
+ add r6, r5, r6 @ r6 = mcpm_entry_vectors
+ ldr r7, [r5, r7] @ r7 = mcpm_power_up_setup_phys
+ add r8, r5, r8 @ r8 = mcpm_sync
+ add r11, r5, r11 @ r11 = first_man_locks
+
+ @ Perform an early poke, if any
+ add r0, r0, r4, lsl #3
+ ldmia r0, {r0, r1}
+ teq r0, #0
+ strne r1, [r0]
+
+ mov r0, #MCPM_SYNC_CLUSTER_SIZE
+ mla r8, r0, r10, r8 @ r8 = sync cluster base
+
+ @ Signal that this CPU is coming UP:
+ mov r0, #CPU_COMING_UP
+ mov r5, #MCPM_SYNC_CPU_SIZE
+ mla r5, r9, r5, r8 @ r5 = sync cpu address
+ strb r0, [r5]
+
+ @ At this point, the cluster cannot unexpectedly enter the GOING_DOWN
+ @ state, because there is at least one active CPU (this CPU).
+
+ mov r0, #VLOCK_SIZE
+ mla r11, r0, r10, r11 @ r11 = cluster first man lock
+ mov r0, r11
+ mov r1, r9 @ cpu
+ bl vlock_trylock @ implies DMB
+
+ cmp r0, #0 @ failed to get the lock?
+ bne mcpm_setup_wait @ wait for cluster setup if so
+
+ ldrb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER]
+ cmp r0, #CLUSTER_UP @ cluster already up?
+ bne mcpm_setup @ if not, set up the cluster
+
+ @ Otherwise, release the first man lock and skip setup:
+ mov r0, r11
+ bl vlock_unlock
+ b mcpm_setup_complete
+
+mcpm_setup:
+ @ Control dependency implies strb not observable before previous ldrb.
+
+ @ Signal that the cluster is being brought up:
+ mov r0, #INBOUND_COMING_UP
+ strb r0, [r8, #MCPM_SYNC_CLUSTER_INBOUND]
+ dmb
+
+ @ Any CPU trying to take the cluster into CLUSTER_GOING_DOWN from this
+ @ point onwards will observe INBOUND_COMING_UP and abort.
+
+ @ Wait for any previously-pending cluster teardown operations to abort
+ @ or complete:
+mcpm_teardown_wait:
+ ldrb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER]
+ cmp r0, #CLUSTER_GOING_DOWN
+ bne first_man_setup
+ wfe
+ b mcpm_teardown_wait
+
+first_man_setup:
+ dmb
+
+ @ If the outbound gave up before teardown started, skip cluster setup:
+
+ cmp r0, #CLUSTER_UP
+ beq mcpm_setup_leave
+
+ @ power_up_setup is now responsible for setting up the cluster:
+
+ cmp r7, #0
+ mov r0, #1 @ second (cluster) affinity level
+ blxne r7 @ Call power_up_setup if defined
+ dmb
+
+ mov r0, #CLUSTER_UP
+ strb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER]
+ dmb
+
+mcpm_setup_leave:
+ @ Leave the cluster setup critical section:
+
+ mov r0, #INBOUND_NOT_COMING_UP
+ strb r0, [r8, #MCPM_SYNC_CLUSTER_INBOUND]
+ dsb st
+ sev
+
+ mov r0, r11
+ bl vlock_unlock @ implies DMB
+ b mcpm_setup_complete
+
+ @ In the contended case, non-first men wait here for cluster setup
+ @ to complete:
+mcpm_setup_wait:
+ ldrb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER]
+ cmp r0, #CLUSTER_UP
+ wfene
+ bne mcpm_setup_wait
+ dmb
+
+mcpm_setup_complete:
+ @ If a platform-specific CPU setup hook is needed, it is
+ @ called from here.
+
+ cmp r7, #0
+ mov r0, #0 @ first (CPU) affinity level
+ blxne r7 @ Call power_up_setup if defined
+ dmb
+
+ @ Mark the CPU as up:
+
+ mov r0, #CPU_UP
+ strb r0, [r5]
+
+ @ Observability order of CPU_UP and opening of the gate does not matter.
+
+mcpm_entry_gated:
+ ldr r5, [r6, r4, lsl #2] @ r5 = CPU entry vector
+ cmp r5, #0
+ wfeeq
+ beq mcpm_entry_gated
+ dmb
+
+ pr_dbg "released\n"
+ bx r5
+
+ .align 2
+
+3: .word mcpm_entry_early_pokes - .
+ .word mcpm_entry_vectors - 3b
+ .word mcpm_power_up_setup_phys - 3b
+ .word mcpm_sync - 3b
+ .word first_man_locks - 3b
+
+ENDPROC(mcpm_entry_point)
+
+ .bss
+
+ .align CACHE_WRITEBACK_ORDER
+ .type first_man_locks, #object
+first_man_locks:
+ .space VLOCK_SIZE * MAX_NR_CLUSTERS
+ .align CACHE_WRITEBACK_ORDER
+
+ .type mcpm_entry_vectors, #object
+ENTRY(mcpm_entry_vectors)
+ .space 4 * MAX_NR_CLUSTERS * MAX_CPUS_PER_CLUSTER
+
+ .type mcpm_entry_early_pokes, #object
+ENTRY(mcpm_entry_early_pokes)
+ .space 8 * MAX_NR_CLUSTERS * MAX_CPUS_PER_CLUSTER
+
+ .type mcpm_power_up_setup_phys, #object
+ENTRY(mcpm_power_up_setup_phys)
+ .space 4 @ set by mcpm_sync_init()
diff --git a/arch/arm/common/mcpm_platsmp.c b/arch/arm/common/mcpm_platsmp.c
new file mode 100644
index 000000000..92e54d7c6
--- /dev/null
+++ b/arch/arm/common/mcpm_platsmp.c
@@ -0,0 +1,103 @@
+/*
+ * linux/arch/arm/mach-vexpress/mcpm_platsmp.c
+ *
+ * Created by: Nicolas Pitre, November 2012
+ * Copyright: (C) 2012-2013 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.
+ *
+ * Code to handle secondary CPU bringup and hotplug for the cluster power API.
+ */
+
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+
+#include <asm/mcpm.h>
+#include <asm/smp.h>
+#include <asm/smp_plat.h>
+
+static void cpu_to_pcpu(unsigned int cpu,
+ unsigned int *pcpu, unsigned int *pcluster)
+{
+ unsigned int mpidr;
+
+ mpidr = cpu_logical_map(cpu);
+ *pcpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ *pcluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+}
+
+static int mcpm_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ unsigned int pcpu, pcluster, ret;
+ extern void secondary_startup(void);
+
+ cpu_to_pcpu(cpu, &pcpu, &pcluster);
+
+ pr_debug("%s: logical CPU %d is physical CPU %d cluster %d\n",
+ __func__, cpu, pcpu, pcluster);
+
+ mcpm_set_entry_vector(pcpu, pcluster, NULL);
+ ret = mcpm_cpu_power_up(pcpu, pcluster);
+ if (ret)
+ return ret;
+ mcpm_set_entry_vector(pcpu, pcluster, secondary_startup);
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+ dsb_sev();
+ return 0;
+}
+
+static void mcpm_secondary_init(unsigned int cpu)
+{
+ mcpm_cpu_powered_up();
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+static int mcpm_cpu_kill(unsigned int cpu)
+{
+ unsigned int pcpu, pcluster;
+
+ cpu_to_pcpu(cpu, &pcpu, &pcluster);
+
+ return !mcpm_wait_for_cpu_powerdown(pcpu, pcluster);
+}
+
+static int mcpm_cpu_disable(unsigned int cpu)
+{
+ /*
+ * We assume all CPUs may be shut down.
+ * This would be the hook to use for eventual Secure
+ * OS migration requests as described in the PSCI spec.
+ */
+ return 0;
+}
+
+static void mcpm_cpu_die(unsigned int cpu)
+{
+ unsigned int mpidr, pcpu, pcluster;
+ mpidr = read_cpuid_mpidr();
+ pcpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ pcluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+ mcpm_set_entry_vector(pcpu, pcluster, NULL);
+ mcpm_cpu_power_down();
+}
+
+#endif
+
+static struct smp_operations __initdata mcpm_smp_ops = {
+ .smp_boot_secondary = mcpm_boot_secondary,
+ .smp_secondary_init = mcpm_secondary_init,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_kill = mcpm_cpu_kill,
+ .cpu_disable = mcpm_cpu_disable,
+ .cpu_die = mcpm_cpu_die,
+#endif
+};
+
+void __init mcpm_smp_set_ops(void)
+{
+ smp_set_ops(&mcpm_smp_ops);
+}
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
new file mode 100644
index 000000000..5cc779c8e
--- /dev/null
+++ b/arch/arm/common/sa1111.c
@@ -0,0 +1,1456 @@
+/*
+ * 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/irq.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/irq.h>
+#include <asm/mach-types.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)
+#define SA1111_IRQ_NR (55)
+
+extern void sa1110_mb_enable(void);
+extern void sa1110_mb_disable(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;
+ struct sa1111_platform_data *pdata;
+#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;
+ bool dma;
+ unsigned int devid;
+ unsigned int irq[6];
+};
+
+static struct sa1111_dev_info sa1111_devices[] = {
+ {
+ .offset = SA1111_USB,
+ .skpcr_mask = SKPCR_UCLKEN,
+ .dma = true,
+ .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,
+ .dma = true,
+ .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_KBD,
+ .irq = {
+ IRQ_TPRXINT,
+ IRQ_TPTXINT
+ },
+ },
+ {
+ .offset = SA1111_MSE,
+ .skpcr_mask = SKPCR_PMCLKEN,
+ .devid = SA1111_DEVID_PS2_MSE,
+ .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)
+ pr_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)
+ pr_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 int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base)
+{
+ void __iomem *irqbase = sachip->base + SA1111_INTC;
+ unsigned i, irq;
+ int ret;
+
+ /*
+ * We're guaranteed that this region hasn't been taken.
+ */
+ request_mem_region(sachip->phys + SA1111_INTC, 512, "irq");
+
+ ret = irq_alloc_descs(-1, irq_base, SA1111_IRQ_NR, -1);
+ if (ret <= 0) {
+ dev_err(sachip->dev, "unable to allocate %u irqs: %d\n",
+ SA1111_IRQ_NR, ret);
+ if (ret == 0)
+ ret = -EINVAL;
+ return ret;
+ }
+
+ sachip->irq_base = ret;
+
+ /* 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 (i = IRQ_GPAIN0; i <= SSPROR; i++) {
+ irq = sachip->irq_base + i;
+ 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 (i = AUDXMTDMADONEA; i <= IRQ_S1_BVD1_STSCHG; i++) {
+ irq = sachip->irq_base + i;
+ 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);
+
+ dev_info(sachip->dev, "Providing IRQ%u-%u\n",
+ sachip->irq_base, sachip->irq_base + SA1111_IRQ_NR - 1);
+
+ return 0;
+}
+
+/*
+ * 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);
+
+ kfree(dev);
+}
+
+static int
+sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
+ struct sa1111_dev_info *info)
+{
+ struct sa1111_dev *dev;
+ unsigned i;
+ int ret;
+
+ dev = kzalloc(sizeof(struct sa1111_dev), GFP_KERNEL);
+ if (!dev) {
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+
+ device_initialize(&dev->dev);
+ 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->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;
+
+ for (i = 0; i < ARRAY_SIZE(info->irq); i++)
+ dev->irq[i] = sachip->irq_base + info->irq[i];
+
+ /*
+ * If the parent device has a DMA mask associated with it, and
+ * this child supports DMA, propagate it down to the children.
+ */
+ if (info->dma && sachip->dev->dma_mask) {
+ dev->dma_mask = *sachip->dev->dma_mask;
+ dev->dev.dma_mask = &dev->dma_mask;
+ dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask;
+ }
+
+ ret = request_resource(parent, &dev->res);
+ if (ret) {
+ dev_err(sachip->dev, "failed to allocate resource for %s\n",
+ dev->res.name);
+ goto err_resource;
+ }
+
+ ret = device_add(&dev->dev);
+ if (ret)
+ goto err_add;
+ return 0;
+
+ err_add:
+ release_resource(&dev->res);
+ err_resource:
+ put_device(&dev->dev);
+ err_alloc:
+ 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.
+ * %-EINVAL no platform data passed
+ * %0 successful.
+ */
+static int __sa1111_probe(struct device *me, struct resource *mem, int irq)
+{
+ struct sa1111_platform_data *pd = me->platform_data;
+ struct sa1111 *sachip;
+ unsigned long id;
+ unsigned int has_devs;
+ int i, ret = -ENODEV;
+
+ if (!pd)
+ return -EINVAL;
+
+ 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;
+ }
+
+ ret = clk_prepare(sachip->clk);
+ if (ret)
+ goto err_clkput;
+
+ spin_lock_init(&sachip->lock);
+
+ sachip->dev = me;
+ dev_set_drvdata(sachip->dev, sachip);
+
+ sachip->pdata = pd;
+ 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_clk_unprep;
+ }
+
+ /*
+ * 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;
+ }
+
+ pr_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);
+
+ /*
+ * The interrupt controller must be initialised before any
+ * other device to ensure that the interrupts are available.
+ */
+ if (sachip->irq != NO_IRQ) {
+ ret = sa1111_setup_irq(sachip, pd->irq_base);
+ if (ret)
+ goto err_unmap;
+ }
+
+#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
+
+ g_sa1111 = sachip;
+
+ has_devs = ~0;
+ if (pd)
+ has_devs &= ~pd->disable_devs;
+
+ for (i = 0; i < ARRAY_SIZE(sa1111_devices); i++)
+ if (sa1111_devices[i].devid & has_devs)
+ sa1111_init_one_child(sachip, mem, &sa1111_devices[i]);
+
+ return 0;
+
+ err_unmap:
+ iounmap(sachip->base);
+ err_clk_unprep:
+ clk_unprepare(sachip->clk);
+ err_clkput:
+ clk_put(sachip->clk);
+ err_free:
+ kfree(sachip);
+ return ret;
+}
+
+static int sa1111_remove_one(struct device *dev, void *data)
+{
+ struct sa1111_dev *sadev = SA1111_DEV(dev);
+ device_del(&sadev->dev);
+ release_resource(&sadev->res);
+ put_device(&sadev->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);
+ clk_unprepare(sachip->clk);
+
+ if (sachip->irq != NO_IRQ) {
+ irq_set_chained_handler(sachip->irq, NULL);
+ irq_set_handler_data(sachip->irq, NULL);
+ irq_free_descs(sachip->irq_base, SA1111_IRQ_NR);
+
+ release_mem_region(sachip->phys + SA1111_INTC, 512);
+ }
+
+ iounmap(sachip->base);
+ clk_put(sachip->clk);
+ kfree(sachip);
+}
+
+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);
+
+ sa1111_writel(0, sachip->base + SA1111_SKPWM0);
+ sa1111_writel(0, sachip->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);
+
+ clk_disable(sachip->clk);
+
+ spin_unlock_irqrestore(&sachip->lock, flags);
+
+#ifdef CONFIG_ARCH_SA1100
+ sa1110_mb_disable();
+#endif
+
+ 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);
+
+#ifdef CONFIG_ARCH_SA1100
+ /* Enable the memory bus request/grant signals */
+ sa1110_mb_enable();
+#endif
+
+ /*
+ * 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 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
+ */
+int sa1111_enable_device(struct sa1111_dev *sadev)
+{
+ struct sa1111 *sachip = sa1111_chip_driver(sadev);
+ unsigned long flags;
+ unsigned int val;
+ int ret = 0;
+
+ if (sachip->pdata && sachip->pdata->enable)
+ ret = sachip->pdata->enable(sachip->pdata->data, sadev->devid);
+
+ if (ret == 0) {
+ 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);
+ }
+ return ret;
+}
+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);
+
+ if (sachip->pdata && sachip->pdata->disable)
+ sachip->pdata->disable(sachip->pdata->data, sadev->devid);
+}
+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 void sa1111_bus_shutdown(struct device *dev)
+{
+ struct sa1111_driver *drv = SA1111_DRV(dev->driver);
+
+ if (drv && drv->shutdown)
+ drv->shutdown(SA1111_DEV(dev));
+}
+
+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,
+ .shutdown = sa1111_bus_shutdown,
+};
+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);
+
+#ifdef CONFIG_DMABOUNCE
+/*
+ * 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.
+ */
+static int sa1111_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);
+}
+
+static int sa1111_notifier_call(struct notifier_block *n, unsigned long action,
+ void *data)
+{
+ struct sa1111_dev *dev = SA1111_DEV(data);
+
+ switch (action) {
+ case BUS_NOTIFY_ADD_DEVICE:
+ if (dev->dev.dma_mask && dev->dma_mask < 0xffffffffUL) {
+ int ret = dmabounce_register_dev(&dev->dev, 1024, 4096,
+ sa1111_needs_bounce);
+ if (ret)
+ dev_err(&dev->dev, "failed to register with dmabounce: %d\n", ret);
+ }
+ break;
+
+ case BUS_NOTIFY_DEL_DEVICE:
+ if (dev->dev.dma_mask && dev->dma_mask < 0xffffffffUL)
+ dmabounce_unregister_dev(&dev->dev);
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block sa1111_bus_notifier = {
+ .notifier_call = sa1111_notifier_call,
+};
+#endif
+
+static int __init sa1111_init(void)
+{
+ int ret = bus_register(&sa1111_bus_type);
+#ifdef CONFIG_DMABOUNCE
+ if (ret == 0)
+ bus_register_notifier(&sa1111_bus_type, &sa1111_bus_notifier);
+#endif
+ if (ret == 0)
+ platform_driver_register(&sa1111_device_driver);
+ return ret;
+}
+
+static void __exit sa1111_exit(void)
+{
+ platform_driver_unregister(&sa1111_device_driver);
+#ifdef CONFIG_DMABOUNCE
+ bus_unregister_notifier(&sa1111_bus_type, &sa1111_bus_notifier);
+#endif
+ 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 000000000..45f4c21e3
--- /dev/null
+++ b/arch/arm/common/scoop.c
@@ -0,0 +1,275 @@
+/*
+ * 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/gpio.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/export.h>
+#include <linux/io.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 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;
+
+ 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, resource_size(mem));
+
+ 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;
+
+err_gpio:
+ platform_set_drvdata(pdev, NULL);
+err_ioremap:
+ iounmap(devptr->base);
+ kfree(devptr);
+
+ return ret;
+}
+
+static int scoop_remove(struct platform_device *pdev)
+{
+ struct scoop_dev *sdev = platform_get_drvdata(pdev);
+
+ if (!sdev)
+ return -EINVAL;
+
+ if (sdev->gpio.base != -1)
+ gpiochip_remove(&sdev->gpio);
+
+ platform_set_drvdata(pdev, NULL);
+ iounmap(sdev->base);
+ kfree(sdev);
+
+ return 0;
+}
+
+static struct platform_driver scoop_driver = {
+ .probe = scoop_probe,
+ .remove = 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 000000000..025f6ce38
--- /dev/null
+++ b/arch/arm/common/sharpsl_param.c
@@ -0,0 +1,65 @@
+/*
+ * 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>
+#include <asm/memory.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
+#define param_start(x) (void *)(x)
+#else
+#define PARAM_BASE 0xa0000a00
+#define param_start(x) __va(x)
+#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, param_start(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/timer-sp.c b/arch/arm/common/timer-sp.c
new file mode 100644
index 000000000..192113247
--- /dev/null
+++ b/arch/arm/common/timer-sp.c
@@ -0,0 +1,304 @@
+/*
+ * 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 <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/sched_clock.h>
+
+#include <asm/hardware/arm_timer.h>
+#include <asm/hardware/timer-sp.h>
+
+static long __init sp804_get_clock_rate(struct clk *clk)
+{
+ long rate;
+ int err;
+
+ err = clk_prepare(clk);
+ if (err) {
+ pr_err("sp804: clock failed to prepare: %d\n", err);
+ clk_put(clk);
+ return err;
+ }
+
+ err = clk_enable(clk);
+ if (err) {
+ pr_err("sp804: clock failed to enable: %d\n", err);
+ clk_unprepare(clk);
+ clk_put(clk);
+ return err;
+ }
+
+ rate = clk_get_rate(clk);
+ if (rate < 0) {
+ pr_err("sp804: clock failed to get rate: %ld\n", rate);
+ clk_disable(clk);
+ clk_unprepare(clk);
+ clk_put(clk);
+ }
+
+ return rate;
+}
+
+static void __iomem *sched_clock_base;
+
+static u64 notrace sp804_read(void)
+{
+ return ~readl_relaxed(sched_clock_base + TIMER_VALUE);
+}
+
+void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base,
+ const char *name,
+ struct clk *clk,
+ int use_sched_clock)
+{
+ long rate;
+
+ if (!clk) {
+ clk = clk_get_sys("sp804", name);
+ if (IS_ERR(clk)) {
+ pr_err("sp804: clock not found: %d\n",
+ (int)PTR_ERR(clk));
+ return;
+ }
+ }
+
+ rate = sp804_get_clock_rate(clk);
+
+ 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);
+
+ if (use_sched_clock) {
+ sched_clock_base = base;
+ sched_clock_register(sp804_read, 32, rate);
+ }
+}
+
+
+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 = {
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
+ CLOCK_EVT_FEAT_DYNIRQ,
+ .set_mode = sp804_set_mode,
+ .set_next_event = sp804_set_next_event,
+ .rating = 300,
+};
+
+static struct irqaction sp804_timer_irq = {
+ .name = "timer",
+ .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = sp804_timer_interrupt,
+ .dev_id = &sp804_clockevent,
+};
+
+void __init __sp804_clockevents_init(void __iomem *base, unsigned int irq, struct clk *clk, const char *name)
+{
+ struct clock_event_device *evt = &sp804_clockevent;
+ long rate;
+
+ if (!clk)
+ 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;
+ }
+
+ rate = sp804_get_clock_rate(clk);
+ if (rate < 0)
+ return;
+
+ clkevt_base = base;
+ clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ);
+ evt->name = name;
+ evt->irq = irq;
+ evt->cpumask = cpu_possible_mask;
+
+ writel(0, base + TIMER_CTRL);
+
+ setup_irq(irq, &sp804_timer_irq);
+ clockevents_config_and_register(evt, rate, 0xf, 0xffffffff);
+}
+
+static void __init sp804_of_init(struct device_node *np)
+{
+ static bool initialized = false;
+ void __iomem *base;
+ int irq;
+ u32 irq_num = 0;
+ struct clk *clk1, *clk2;
+ const char *name = of_get_property(np, "compatible", NULL);
+
+ base = of_iomap(np, 0);
+ if (WARN_ON(!base))
+ return;
+
+ /* Ensure timers are disabled */
+ writel(0, base + TIMER_CTRL);
+ writel(0, base + TIMER_2_BASE + TIMER_CTRL);
+
+ if (initialized || !of_device_is_available(np))
+ goto err;
+
+ clk1 = of_clk_get(np, 0);
+ if (IS_ERR(clk1))
+ clk1 = NULL;
+
+ /* Get the 2nd clock if the timer has 3 timer clocks */
+ if (of_count_phandle_with_args(np, "clocks", "#clock-cells") == 3) {
+ clk2 = of_clk_get(np, 1);
+ if (IS_ERR(clk2)) {
+ pr_err("sp804: %s clock not found: %d\n", np->name,
+ (int)PTR_ERR(clk2));
+ clk2 = NULL;
+ }
+ } else
+ clk2 = clk1;
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (irq <= 0)
+ goto err;
+
+ of_property_read_u32(np, "arm,sp804-has-irq", &irq_num);
+ if (irq_num == 2) {
+ __sp804_clockevents_init(base + TIMER_2_BASE, irq, clk2, name);
+ __sp804_clocksource_and_sched_clock_init(base, name, clk1, 1);
+ } else {
+ __sp804_clockevents_init(base, irq, clk1 , name);
+ __sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE,
+ name, clk2, 1);
+ }
+ initialized = true;
+
+ return;
+err:
+ iounmap(base);
+}
+CLOCKSOURCE_OF_DECLARE(sp804, "arm,sp804", sp804_of_init);
+
+static void __init integrator_cp_of_init(struct device_node *np)
+{
+ static int init_count = 0;
+ void __iomem *base;
+ int irq;
+ const char *name = of_get_property(np, "compatible", NULL);
+ struct clk *clk;
+
+ base = of_iomap(np, 0);
+ if (WARN_ON(!base))
+ return;
+ clk = of_clk_get(np, 0);
+ if (WARN_ON(IS_ERR(clk)))
+ return;
+
+ /* Ensure timer is disabled */
+ writel(0, base + TIMER_CTRL);
+
+ if (init_count == 2 || !of_device_is_available(np))
+ goto err;
+
+ if (!init_count)
+ __sp804_clocksource_and_sched_clock_init(base, name, clk, 0);
+ else {
+ irq = irq_of_parse_and_map(np, 0);
+ if (irq <= 0)
+ goto err;
+
+ __sp804_clockevents_init(base, irq, clk, name);
+ }
+
+ init_count++;
+ return;
+err:
+ iounmap(base);
+}
+CLOCKSOURCE_OF_DECLARE(intcp, "arm,integrator-cp-timer", integrator_cp_of_init);
diff --git a/arch/arm/common/vlock.S b/arch/arm/common/vlock.S
new file mode 100644
index 000000000..8b7df283f
--- /dev/null
+++ b/arch/arm/common/vlock.S
@@ -0,0 +1,108 @@
+/*
+ * vlock.S - simple voting lock implementation for ARM
+ *
+ * Created by: Dave Martin, 2012-08-16
+ * Copyright: (C) 2012-2013 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.
+ *
+ *
+ * This algorithm is described in more detail in
+ * Documentation/arm/vlocks.txt.
+ */
+
+#include <linux/linkage.h>
+#include "vlock.h"
+
+/* Select different code if voting flags can fit in a single word. */
+#if VLOCK_VOTING_SIZE > 4
+#define FEW(x...)
+#define MANY(x...) x
+#else
+#define FEW(x...) x
+#define MANY(x...)
+#endif
+
+@ voting lock for first-man coordination
+
+.macro voting_begin rbase:req, rcpu:req, rscratch:req
+ mov \rscratch, #1
+ strb \rscratch, [\rbase, \rcpu]
+ dmb
+.endm
+
+.macro voting_end rbase:req, rcpu:req, rscratch:req
+ dmb
+ mov \rscratch, #0
+ strb \rscratch, [\rbase, \rcpu]
+ dsb st
+ sev
+.endm
+
+/*
+ * The vlock structure must reside in Strongly-Ordered or Device memory.
+ * This implementation deliberately eliminates most of the barriers which
+ * would be required for other memory types, and assumes that independent
+ * writes to neighbouring locations within a cacheline do not interfere
+ * with one another.
+ */
+
+@ r0: lock structure base
+@ r1: CPU ID (0-based index within cluster)
+ENTRY(vlock_trylock)
+ add r1, r1, #VLOCK_VOTING_OFFSET
+
+ voting_begin r0, r1, r2
+
+ ldrb r2, [r0, #VLOCK_OWNER_OFFSET] @ check whether lock is held
+ cmp r2, #VLOCK_OWNER_NONE
+ bne trylock_fail @ fail if so
+
+ @ Control dependency implies strb not observable before previous ldrb.
+
+ strb r1, [r0, #VLOCK_OWNER_OFFSET] @ submit my vote
+
+ voting_end r0, r1, r2 @ implies DMB
+
+ @ Wait for the current round of voting to finish:
+
+ MANY( mov r3, #VLOCK_VOTING_OFFSET )
+0:
+ MANY( ldr r2, [r0, r3] )
+ FEW( ldr r2, [r0, #VLOCK_VOTING_OFFSET] )
+ cmp r2, #0
+ wfene
+ bne 0b
+ MANY( add r3, r3, #4 )
+ MANY( cmp r3, #VLOCK_VOTING_OFFSET + VLOCK_VOTING_SIZE )
+ MANY( bne 0b )
+
+ @ Check who won:
+
+ dmb
+ ldrb r2, [r0, #VLOCK_OWNER_OFFSET]
+ eor r0, r1, r2 @ zero if I won, else nonzero
+ bx lr
+
+trylock_fail:
+ voting_end r0, r1, r2
+ mov r0, #1 @ nonzero indicates that I lost
+ bx lr
+ENDPROC(vlock_trylock)
+
+@ r0: lock structure base
+ENTRY(vlock_unlock)
+ dmb
+ mov r1, #VLOCK_OWNER_NONE
+ strb r1, [r0, #VLOCK_OWNER_OFFSET]
+ dsb st
+ sev
+ bx lr
+ENDPROC(vlock_unlock)
diff --git a/arch/arm/common/vlock.h b/arch/arm/common/vlock.h
new file mode 100644
index 000000000..3b441475a
--- /dev/null
+++ b/arch/arm/common/vlock.h
@@ -0,0 +1,29 @@
+/*
+ * vlock.h - simple voting lock implementation
+ *
+ * Created by: Dave Martin, 2012-08-16
+ * Copyright: (C) 2012-2013 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.
+ */
+
+#ifndef __VLOCK_H
+#define __VLOCK_H
+
+#include <asm/mcpm.h>
+
+/* Offsets and sizes are rounded to a word (4 bytes) */
+#define VLOCK_OWNER_OFFSET 0
+#define VLOCK_VOTING_OFFSET 4
+#define VLOCK_VOTING_SIZE ((MAX_CPUS_PER_CLUSTER + 3) / 4 * 4)
+#define VLOCK_SIZE (VLOCK_VOTING_OFFSET + VLOCK_VOTING_SIZE)
+#define VLOCK_OWNER_NONE 0
+
+#endif /* ! __VLOCK_H */
diff --git a/arch/arm/configs/acs5k_defconfig b/arch/arm/configs/acs5k_defconfig
new file mode 100644
index 000000000..92b0f90d1
--- /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 000000000..2a27a1474
--- /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/am200epdkit_defconfig b/arch/arm/configs/am200epdkit_defconfig
new file mode 100644
index 000000000..f0dea52e4
--- /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/armadillo800eva_defconfig b/arch/arm/configs/armadillo800eva_defconfig
new file mode 100644
index 000000000..5666e3700
--- /dev/null
+++ b/arch/arm/configs/armadillo800eva_defconfig
@@ -0,0 +1,162 @@
+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_PID_NS is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_PERF_EVENTS=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_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_SHMOBILE_LEGACY=y
+CONFIG_ARCH_R8A7740=y
+CONFIG_MACH_ARMADILLO800EVA=y
+# CONFIG_SH_TIMER_TMU is not set
+CONFIG_ARM_THUMB=y
+CONFIG_CACHE_L2X0=y
+CONFIG_ARM_ERRATA_430973=y
+CONFIG_ARM_ERRATA_458693=y
+CONFIG_ARM_ERRATA_460075=y
+CONFIG_PL310_ERRATA_588369=y
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_PL310_ERRATA_727915=y
+CONFIG_ARM_ERRATA_743622=y
+CONFIG_ARM_ERRATA_751472=y
+CONFIG_PL310_ERRATA_753970=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_PL310_ERRATA_769419=y
+CONFIG_ARM_ERRATA_775420=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_FORCE_MAX_ZONEORDER=13
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_KEXEC=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+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_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_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+CONFIG_SH_ETH=y
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX 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_TOUCHSCREEN_ST1232=y
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=9
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_GPIO=y
+CONFIG_I2C_SH_MOBILE=y
+# CONFIG_HWMON is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_VIDEO_DEV=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_MT9T112=y
+CONFIG_VIDEO_SH_MOBILE_CEU=y
+CONFIG_FB=y
+CONFIG_FB_SH_MOBILE_LCDC=y
+CONFIG_FB_SH_MOBILE_HDMI=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_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_SOC_SH4_FSI=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_RENESAS_USBHS=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_RENESAS_USBHS_UDC=y
+CONFIG_USB_ETH=m
+CONFIG_MMC=y
+CONFIG_MMC_SDHI=y
+CONFIG_MMC_SH_MMCIF=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_S35390A=y
+CONFIG_DMADEVICES=y
+CONFIG_SH_DMAE=y
+CONFIG_UIO=y
+CONFIG_UIO_PDRV_GENIRQ=y
+CONFIG_PWM=y
+CONFIG_PWM_RENESAS_TPU=y
+# CONFIG_DNOTIFY 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_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_ROOT_NFS=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_ARM_UNWIND is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_XZ_DEC=y
diff --git a/arch/arm/configs/assabet_defconfig b/arch/arm/configs/assabet_defconfig
new file mode 100644
index 000000000..558ecd8f6
--- /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/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig
new file mode 100644
index 000000000..bcef49a21
--- /dev/null
+++ b/arch/arm/configs/at91_dt_defconfig
@@ -0,0 +1,221 @@
+# 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_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=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_IOSCHED_CFQ is not set
+CONFIG_ARCH_MULTI_V4T=y
+CONFIG_ARCH_MULTI_V5=y
+# CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_ARCH_AT91=y
+CONFIG_SOC_SAM_V4_V5=y
+CONFIG_SOC_AT91RM9200=y
+CONFIG_SOC_AT91SAM9=y
+CONFIG_AEABI=y
+CONFIG_UACCESS_WITH_MEMCPY=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CMDLINE="console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw"
+CONFIG_KEXEC=y
+CONFIG_AUTO_ZRELADDR=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_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_DIAG is not set
+CONFIG_IPV6=y
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+CONFIG_IPV6_SIT_6RD=y
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# 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_DATAFLASH=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=4
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_SSC=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_ARM_AT91_ETHER=y
+CONFIG_MACB=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+CONFIG_DM9000=y
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_DAVICOM_PHY=y
+CONFIG_MICREL_PHY=y
+CONFIG_RTL8187=m
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_SDIO=m
+CONFIG_LIBERTAS_SPI=m
+CONFIG_RT2X00=m
+CONFIG_RT2500USB=m
+CONFIG_RT73USB=m
+CONFIG_RT2800USB=m
+CONFIG_RT2800USB_RT53XX=y
+CONFIG_RT2800USB_RT55XX=y
+CONFIG_RT2800USB_UNKNOWN=y
+CONFIG_RTL8192CU=m
+# CONFIG_RTLWIFI_DEBUG is not set
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+CONFIG_MWIFIEX_USB=m
+CONFIG_INPUT_POLLDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=480
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=272
+CONFIG_INPUT_JOYDEV=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_QT1070=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_SERIO is not set
+CONFIG_LEGACY_PTY_COUNT=4
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_AT91=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+CONFIG_SSB=m
+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_SOC=y
+CONFIG_SND_ATMEL_SOC=y
+CONFIG_SND_AT91_SOC_SAM9G20_WM8731=y
+CONFIG_SND_ATMEL_SOC_WM8904=y
+CONFIG_SND_AT91_SOC_SAM9X5_WM8731=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_FTDI_SIO=y
+CONFIG_USB_SERIAL_PL2303=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_AT91=y
+CONFIG_USB_ATMEL_USBA=y
+CONFIG_USB_G_SERIAL=y
+CONFIG_MMC=y
+CONFIG_MMC_ATMELMCI=y
+CONFIG_MMC_SPI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=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_RV3029C2=y
+CONFIG_RTC_DRV_AT91RM9200=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_DMADEVICES=y
+CONFIG_AT_HDMAC=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_IIO=y
+CONFIG_AT91_ADC=y
+CONFIG_PWM=y
+CONFIG_PWM_ATMEL=y
+CONFIG_PWM_ATMEL_TCB=y
+CONFIG_EXT4_FS=y
+CONFIG_FANOTIFY=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=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_NLS_UTF8=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC7=m
+CONFIG_AVERAGE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_ACORN_8x8=y
+CONFIG_FONT_MINI_4x6=y
diff --git a/arch/arm/configs/axm55xx_defconfig b/arch/arm/configs/axm55xx_defconfig
new file mode 100644
index 000000000..d3260d7d5
--- /dev/null
+++ b/arch/arm/configs/axm55xx_defconfig
@@ -0,0 +1,248 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_AUDIT=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=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_LOG_BUF_SHIFT=16
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_AXXIA=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_ARM_LPAE=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_ERRATA_430973=y
+CONFIG_ARM_ERRATA_643719=y
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_754327=y
+CONFIG_ARM_ERRATA_764369=y
+CONFIG_ARM_ERRATA_775420=y
+CONFIG_ARM_ERRATA_798181=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCIE_AXXIA=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=16
+CONFIG_HOTPLUG_CPU=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_HIGHMEM=y
+CONFIG_KSM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_MISC=y
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_SUB_POLICY=y
+CONFIG_XFRM_MIGRATE=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETWORK_PHY_TIMESTAMPING=y
+CONFIG_BRIDGE=y
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_AFS_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_M25P80=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_ATA=y
+CONFIG_PATA_PLATFORM=y
+CONFIG_PATA_OF_PLATFORM=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_UEVENT=y
+CONFIG_NETDEVICES=y
+CONFIG_TUN=y
+CONFIG_VETH=y
+CONFIG_VIRTIO_NET=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_BROADCOM_PHY=y
+# CONFIG_WLAN is not set
+# CONFIG_MOUSE_PS2_ALPS is not set
+# CONFIG_MOUSE_PS2_LOGIPS2PP is not set
+# CONFIG_MOUSE_PS2_SYNAPTICS is not set
+# CONFIG_MOUSE_PS2_TRACKPOINT is not set
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_AMBAKMI=y
+CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_VIRTIO_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_AXXIA=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_DP83640_PHY=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PL061=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_AXXIA=y
+CONFIG_SENSORS_ADT7475=y
+CONFIG_SENSORS_JC42=y
+CONFIG_SENSORS_LM75=y
+CONFIG_PMBUS=y
+CONFIG_SENSORS_LTC2978=y
+CONFIG_WATCHDOG=y
+CONFIG_ARM_SP805_WATCHDOG=y
+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_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_DRAGONRISE=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LOGITECH=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_ORTEK=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=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_EHCI_HCD=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_HCD_AXXIA=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=y
+CONFIG_DMADEVICES=y
+CONFIG_PL330_DMA=y
+CONFIG_VIRT_DRIVERS=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_MAILBOX=y
+CONFIG_PL320_MBOX=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT4_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=y
+CONFIG_FSCACHE=y
+CONFIG_FSCACHE_STATS=y
+CONFIG_FSCACHE_HISTOGRAM=y
+CONFIG_FSCACHE_DEBUG=y
+CONFIG_FSCACHE_OBJECT_LIST=y
+CONFIG_CACHEFILES=y
+CONFIG_CACHEFILES_HISTOGRAM=y
+CONFIG_ISO9660_FS=y
+CONFIG_UDF_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_SUNRPC_DEBUG=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_SHA256=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM=y
diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig
new file mode 100644
index 000000000..d59009878
--- /dev/null
+++ b/arch/arm/configs/badge4_defconfig
@@ -0,0 +1,119 @@
+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_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_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/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig
new file mode 100644
index 000000000..31cb07388
--- /dev/null
+++ b/arch/arm/configs/bcm2835_defconfig
@@ -0,0 +1,141 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_PERF=y
+CONFIG_CFS_BANDWIDTH=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_NAMESPACES=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_JUMP_LABEL=y
+CONFIG_ARCH_MULTI_V6=y
+# CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_ARCH_BCM=y
+CONFIG_ARCH_BCM2835=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_AEABI=y
+CONFIG_KSM=y
+CONFIG_CLEANCACHE=y
+CONFIG_SECCOMP=y
+CONFIG_CC_STACKPROTECTOR=y
+CONFIG_KEXEC=y
+CONFIG_CRASH_DUMP=y
+CONFIG_VFP=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_NETDEVICES=y
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_SMSC95XX=y
+CONFIG_ZD1211RW=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_TTY_PRINTK=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_BCM2835=y
+CONFIG_SPI=y
+CONFIG_SPI_BCM2835=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_SIMPLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_USB=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_BCM2835=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_TRANSIENT=y
+CONFIG_LEDS_TRIGGER_CAMERA=y
+CONFIG_STAGING=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_DWC2_HOST=y
+# CONFIG_IOMMU_SUPPORT is not set
+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_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_FANOTIFY=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFSD=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_BOOT_PRINTK_DELAY=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_SCHED_TRACER=y
+CONFIG_STACK_TRACER=y
+CONFIG_FUNCTION_PROFILER=y
+CONFIG_TEST_KSTRTOX=y
+CONFIG_KGDB=y
+CONFIG_KGDB_KDB=y
+CONFIG_STRICT_DEVMEM=y
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_XZ_DEC_ARM is not set
+# CONFIG_XZ_DEC_ARMTHUMB is not set
diff --git a/arch/arm/configs/bcm_defconfig b/arch/arm/configs/bcm_defconfig
new file mode 100644
index 000000000..7117662ba
--- /dev/null
+++ b/arch/arm/configs/bcm_defconfig
@@ -0,0 +1,142 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=19
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_BLK_CGROUP=y
+CONFIG_NAMESPACES=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ARCH_BCM=y
+CONFIG_ARCH_BCM_21664=y
+CONFIG_ARCH_BCM_281XX=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_COMPACTION is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200n8 mem=128M"
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=y
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_SYN_COOKIES=y
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_BLK_DEV is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_INPUT_FF_MEMLESS=y
+CONFIG_INPUT_JOYDEV=y
+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_INPUT_UINPUT=y
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+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_SERIAL_8250_DW=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_HWMON is not set
+CONFIG_MFD_BCM590XX=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_USERSPACE_CONSUMER=y
+CONFIG_REGULATOR_BCM590XX=y
+
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_TEST=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_BCM_KONA=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_PWM=y
+CONFIG_PWM_BCM_KONA=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=110
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
+# CONFIG_FTRACE is not set
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC7=y
+CONFIG_XZ_DEC=y
+CONFIG_AVERAGE=y
+CONFIG_PINCTRL_BCM281XX=y
+CONFIG_WATCHDOG=y
+CONFIG_BCM_KONA_WDT=y
+CONFIG_BCM_KONA_WDT_DEBUG=y
diff --git a/arch/arm/configs/bockw_defconfig b/arch/arm/configs/bockw_defconfig
new file mode 100644
index 000000000..3125e00f0
--- /dev/null
+++ b/arch/arm/configs/bockw_defconfig
@@ -0,0 +1,133 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_KERNEL_LZMA=y
+CONFIG_NO_HZ=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_SHMOBILE_LEGACY=y
+CONFIG_ARCH_R8A7778=y
+CONFIG_MACH_BOCKW=y
+CONFIG_MEMORY_START=0x60000000
+CONFIG_MEMORY_SIZE=0x10000000
+CONFIG_SHMOBILE_TIMER_HZ=1024
+# CONFIG_SH_TIMER_CMT is not set
+# CONFIG_EM_TIMER_STI is not set
+CONFIG_ARM_ERRATA_430973=y
+CONFIG_ARM_ERRATA_458693=y
+CONFIG_ARM_ERRATA_460075=y
+CONFIG_ARM_ERRATA_743622=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_VFP=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+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_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_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+CONFIG_SMSC911X=y
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_I2C=y
+CONFIG_I2C_RCAR=y
+CONFIG_GPIO_RCAR=y
+CONFIG_REGULATOR=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_VIDEO_RCAR_VIN=y
+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
+CONFIG_VIDEO_ML86V7667=y
+CONFIG_SPI=y
+CONFIG_SPI_SH_HSPI=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_RCAR=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_RCAR_PHY=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHI=y
+CONFIG_MMC_SH_MMCIF=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_RX8581=y
+CONFIG_DMADEVICES=y
+CONFIG_RCAR_HPB_DMAE=y
+CONFIG_UIO=y
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
+CONFIG_NFS_V4_1=y
+CONFIG_ROOT_NFS=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_AVERAGE=y
diff --git a/arch/arm/configs/cerfcube_defconfig b/arch/arm/configs/cerfcube_defconfig
new file mode 100644
index 000000000..dce912d14
--- /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/clps711x_defconfig b/arch/arm/configs/clps711x_defconfig
new file mode 100644
index 000000000..fc105c917
--- /dev/null
+++ b/arch/arm/configs/clps711x_defconfig
@@ -0,0 +1,91 @@
+CONFIG_KERNEL_LZMA=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_LZMA=y
+CONFIG_EMBEDDED=y
+CONFIG_SLOB=y
+CONFIG_JUMP_LABEL=y
+# CONFIG_LBDAF is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_CLPS711X=y
+CONFIG_ARCH_AUTCPU12=y
+CONFIG_ARCH_CDB89712=y
+CONFIG_ARCH_CLEP7312=y
+CONFIG_ARCH_EDB7211=y
+CONFIG_ARCH_P720T=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+# CONFIG_COREDUMP is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IPV6 is not set
+CONFIG_IRDA=y
+CONFIG_IRTTY_SIR=y
+# CONFIG_WIRELESS is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=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_CFI_STAA=y
+CONFIG_MTD_PLATRAM=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_GPIO=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+CONFIG_CS89x0=y
+CONFIG_CS89x0_PLATFORM=y
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_WLAN is not set
+# 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_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_CLPS711X=y
+CONFIG_GPIO_CLPS711X=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_CLPS711X=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_PWM=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PWM=y
+CONFIG_PWM_CLPS711X=y
+CONFIG_EXT2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_MINIX_FS=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=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/cm_x2xx_defconfig b/arch/arm/configs/cm_x2xx_defconfig
new file mode 100644
index 000000000..dc01c049a
--- /dev/null
+++ b/arch/arm/configs/cm_x2xx_defconfig
@@ -0,0 +1,188 @@
+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_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 000000000..7df040e91
--- /dev/null
+++ b/arch/arm/configs/cm_x300_defconfig
@@ -0,0 +1,177 @@
+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_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_GPIO_PCA953X=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_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=y
+CONFIG_BT_SCO=y
+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_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_LEGACY_PTYS is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+# 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_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_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_ZEROPLUS=y
+CONFIG_USB=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_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_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_SCHED_DEBUG 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_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 000000000..b1ff5cdba
--- /dev/null
+++ b/arch/arm/configs/cns3420vb_defconfig
@@ -0,0 +1,75 @@
+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_MULTI_V6=y
+#CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_ARCH_CNS3XXX=y
+CONFIG_MACH_CNS3420VB=y
+CONFIG_DEBUG_CNS3XXX=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 000000000..18c311ae1
--- /dev/null
+++ b/arch/arm/configs/colibri_pxa270_defconfig
@@ -0,0 +1,179 @@
+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_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 000000000..be02fe2b1
--- /dev/null
+++ b/arch/arm/configs/colibri_pxa300_defconfig
@@ -0,0 +1,71 @@
+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_ANNOUNCE_NEW_DEVICES=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 000000000..6c56ad086
--- /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 000000000..c1470a00f
--- /dev/null
+++ b/arch/arm/configs/corgi_defconfig
@@ -0,0 +1,272 @@
+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_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_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_MASS_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/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
new file mode 100644
index 000000000..235842c9b
--- /dev/null
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -0,0 +1,222 @@
+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_CGROUPS=y
+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_ARCH_DAVINCI_DA830=y
+CONFIG_ARCH_DAVINCI_DA850=y
+CONFIG_MACH_DA8XX_DT=y
+CONFIG_MACH_SFFSDR=y
+CONFIG_MACH_NEUROS_OSD2=y
+CONFIG_MACH_DM355_LEOPARD=y
+CONFIG_MACH_MITYOMAPL138=y
+CONFIG_MACH_OMAPL138_HAWKBOARD=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_USE_OF=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_AUTO_ZRELADDR=y
+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_PM=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_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# 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_PROC_DEVICETREE=y
+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_MII=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_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_SERIAL_OF_PLATFORM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_DAVINCI=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_GPIO_PCF857X=y
+CONFIG_WATCHDOG=y
+CONFIG_DAVINCI_WATCHDOG=m
+CONFIG_MFD_DM355EVM_MSP=y
+CONFIG_TPS6507X=y
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_TPS6507X=y
+CONFIG_FB=y
+CONFIG_FB_DA8XX=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_MON=m
+CONFIG_USB_MUSB_HDRC=m
+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_MASS_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_DMADEVICES=y
+CONFIG_TI_EDMA=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
+CONFIG_GPIO_PCA953X=y
+CONFIG_KEYBOARD_GPIO_POLLED=y
diff --git a/arch/arm/configs/dove_defconfig b/arch/arm/configs/dove_defconfig
new file mode 100644
index 000000000..701677f92
--- /dev/null
+++ b/arch/arm/configs/dove_defconfig
@@ -0,0 +1,146 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=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_PARTITION_ADVANCED=y
+CONFIG_ARCH_DOVE=y
+CONFIG_MACH_DOVE_DB=y
+CONFIG_MACH_CM_A510=y
+CONFIG_MACH_DOVE_DT=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MVEBU=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=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_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=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_SPI_NOR=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_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_RUNTIME_UARTS=2
+CONFIG_SERIAL_OF_PLATFORM=y
+# 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_THERMAL=y
+CONFIG_DOVE_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_ORION_WATCHDOG=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_DOVE=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_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_EXT4_FS=y
+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_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_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=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_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_CRYPTO_DEV_MV_CESA=y
+CONFIG_CRC_CCITT=y
+CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/ebsa110_defconfig b/arch/arm/configs/ebsa110_defconfig
new file mode 100644
index 000000000..14559dbb4
--- /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/efm32_defconfig b/arch/arm/configs/efm32_defconfig
new file mode 100644
index 000000000..c4c17e3a8
--- /dev/null
+++ b/arch/arm/configs/efm32_defconfig
@@ -0,0 +1,103 @@
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_LOG_BUF_SHIFT=12
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_UID16 is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+# 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_EFM32=y
+CONFIG_SET_MEM_PARAM=y
+CONFIG_DRAM_BASE=0x88000000
+CONFIG_DRAM_SIZE=0x00400000
+CONFIG_FLASH_MEM_BASE=0x8c000000
+CONFIG_FLASH_SIZE=0x01000000
+CONFIG_PREEMPT=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_XIP_KERNEL=y
+CONFIG_XIP_PHYS_ADDR=0x8c000000
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_SHARED_FLAT=y
+# CONFIG_COREDUMP is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_BLOCK_RO=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_UCLINUX=y
+# CONFIG_BLK_DEV is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+CONFIG_KS8851=y
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_EFM32_UART=y
+CONFIG_SERIAL_EFM32_UART_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_EFM32=y
+CONFIG_SPI=y
+CONFIG_SPI_EFM32=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_SPI=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=y
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_MTD=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig
new file mode 100644
index 000000000..4560c9ca6
--- /dev/null
+++ b/arch/arm/configs/em_x270_defconfig
@@ -0,0 +1,193 @@
+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_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 000000000..72233b9c9
--- /dev/null
+++ b/arch/arm/configs/ep93xx_defconfig
@@ -0,0 +1,112 @@
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+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_PARTITION_ADVANCED=y
+# 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_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_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_NAND=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_EP93XX_ETH=y
+CONFIG_USB_RTL8150=y
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_AMBA_PL010=y
+CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
+# 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_DYNAMIC_MINORS=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=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_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_UART_PL01X=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 000000000..d68ac67c2
--- /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/exynos_defconfig b/arch/arm/configs/exynos_defconfig
new file mode 100644
index 000000000..d034c96c0
--- /dev/null
+++ b/arch/arm/configs/exynos_defconfig
@@ -0,0 +1,231 @@
+CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_CGROUPS=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_PARTITION_ADVANCED=y
+CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS3=y
+CONFIG_EXYNOS5420_MCPM=y
+CONFIG_SMP=y
+CONFIG_BIG_LITTLE=y
+CONFIG_BL_SWITCHER=y
+CONFIG_BL_SWITCHER_DUMMY_IF=y
+CONFIG_NR_CPUS=8
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_CMA=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc mem=256M"
+CONFIG_CPU_IDLE=y
+CONFIG_ARM_EXYNOS_CPUIDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=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_WIRELESS=y
+CONFIG_CFG80211=y
+CONFIG_MWIFIEX=y
+CONFIG_MWIFIEX_SDIO=y
+CONFIG_RFKILL_REGULATOR=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=64
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=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_DM=y
+CONFIG_DM_CRYPT=m
+CONFIG_NETDEVICES=y
+CONFIG_SMSC911X=y
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_SMSC75XX=y
+CONFIG_USB_NET_SMSC95XX=y
+CONFIG_USB_GADGET=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_CROS_EC=y
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_MOUSE_CYAPA=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_HW_RANDOM=y
+CONFIG_TCG_TPM=y
+CONFIG_TCG_TIS_I2C_INFINEON=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_ARB_GPIO_CHALLENGE=y
+CONFIG_I2C_EXYNOS5=y
+CONFIG_I2C_GPIO=y
+CONFIG_I2C_CROS_EC_TUNNEL=y
+CONFIG_SPI=y
+CONFIG_SPI_S3C64XX=y
+CONFIG_I2C_S3C2410=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_SBS=y
+CONFIG_BATTERY_MAX17040=y
+CONFIG_BATTERY_MAX17042=y
+CONFIG_CHARGER_MAX14577=y
+CONFIG_CHARGER_MAX77693=y
+CONFIG_CHARGER_TPS65090=y
+CONFIG_HWMON=y
+CONFIG_SENSORS_LM90=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_THERMAL=y
+CONFIG_THERMAL=y
+CONFIG_EXYNOS_THERMAL=y
+CONFIG_THERMAL_EMULATION=y
+CONFIG_WATCHDOG=y
+CONFIG_S3C2410_WATCHDOG=y
+CONFIG_MFD_CROS_EC=y
+CONFIG_MFD_CROS_EC_I2C=y
+CONFIG_MFD_CROS_EC_SPI=y
+CONFIG_MFD_MAX14577=y
+CONFIG_MFD_MAX77686=y
+CONFIG_MFD_MAX77693=y
+CONFIG_MFD_MAX8997=y
+CONFIG_MFD_SEC_CORE=y
+CONFIG_MFD_TPS65090=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_MAX14577=y
+CONFIG_REGULATOR_MAX8997=y
+CONFIG_REGULATOR_MAX77686=y
+CONFIG_REGULATOR_MAX77802=y
+CONFIG_REGULATOR_MAX77693=y
+CONFIG_REGULATOR_S2MPA01=y
+CONFIG_REGULATOR_S2MPS11=y
+CONFIG_REGULATOR_S5M8767=y
+CONFIG_REGULATOR_TPS65090=y
+CONFIG_DRM=y
+CONFIG_DRM_EXYNOS_HDMI=y
+CONFIG_DRM_BRIDGE=y
+CONFIG_DRM_PTN3460=y
+CONFIG_DRM_PS8622=y
+CONFIG_DRM_EXYNOS=y
+CONFIG_DRM_EXYNOS_FIMD=y
+CONFIG_DRM_EXYNOS_DP=y
+CONFIG_DRM_PANEL=y
+CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_SIMPLE=y
+CONFIG_EXYNOS_VIDEO=y
+CONFIG_EXYNOS_MIPI_DSI=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_7x14=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_SAMSUNG=y
+CONFIG_SND_SOC_SNOW=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EXYNOS=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_EXYNOS=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_HSIC_USB3503=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK_MINORS=16
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_S3C=y
+CONFIG_MMC_SDHCI_S3C_DMA=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_IDMAC=y
+CONFIG_MMC_DW_EXYNOS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_MAX77686=y
+CONFIG_RTC_DRV_MAX77802=y
+CONFIG_RTC_DRV_S5M=y
+CONFIG_RTC_DRV_S3C=y
+CONFIG_DMADEVICES=y
+CONFIG_PL330_DMA=y
+CONFIG_CHROME_PLATFORMS=y
+CONFIG_CROS_EC_CHARDEV=y
+CONFIG_COMMON_CLK_MAX77686=y
+CONFIG_COMMON_CLK_MAX77802=y
+CONFIG_COMMON_CLK_S2MPS11=y
+CONFIG_EXTCON=y
+CONFIG_EXTCON_MAX14577=y
+CONFIG_EXTCON_MAX77693=y
+CONFIG_IIO=y
+CONFIG_EXYNOS_ADC=y
+CONFIG_PWM=y
+CONFIG_PWM_SAMSUNG=y
+CONFIG_PHY_EXYNOS5250_SATA=y
+CONFIG_PHY_SAMSUNG_USB2=y
+CONFIG_PHY_EXYNOS4210_USB2=y
+CONFIG_PHY_EXYNOS4X12_USB2=y
+CONFIG_PHY_EXYNOS5250_USB2=y
+CONFIG_PHY_EXYNOS5_USBDRD=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_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_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=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_LOCKUP_DETECTOR=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/ezx_defconfig b/arch/arm/configs/ezx_defconfig
new file mode 100644
index 000000000..ea316c4b8
--- /dev/null
+++ b/arch/arm/configs/ezx_defconfig
@@ -0,0 +1,418 @@
+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_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_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 000000000..87e020f30
--- /dev/null
+++ b/arch/arm/configs/footbridge_defconfig
@@ -0,0 +1,125 @@
+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_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/h3600_defconfig b/arch/arm/configs/h3600_defconfig
new file mode 100644
index 000000000..0142ec37e
--- /dev/null
+++ b/arch/arm/configs/h3600_defconfig
@@ -0,0 +1,69 @@
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=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_PREEMPT=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+# CONFIG_CPU_FREQ_STAT is not set
+CONFIG_FPE_NWFPE=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_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_REDBOOT_PARTS=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_IDE=y
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_NETDEVICES=y
+CONFIG_PCMCIA_PCNET=y
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_ASYNC=m
+# CONFIG_WLAN 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_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_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_NLS=y
diff --git a/arch/arm/configs/h5000_defconfig b/arch/arm/configs/h5000_defconfig
new file mode 100644
index 000000000..37903e3f0
--- /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/hackkit_defconfig b/arch/arm/configs/hackkit_defconfig
new file mode 100644
index 000000000..bed804729
--- /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/hisi_defconfig b/arch/arm/configs/hisi_defconfig
new file mode 100644
index 000000000..c34da5878
--- /dev/null
+++ b/arch/arm/configs/hisi_defconfig
@@ -0,0 +1,91 @@
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_LZMA=y
+CONFIG_ARCH_HISI=y
+CONFIG_ARCH_HI3xxx=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_CMDLINE_PARTITION=y
+CONFIG_ARCH_HIX5HD2=y
+CONFIG_ARCH_HIP01=y
+CONFIG_ARCH_HIP04=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=16
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_NEON=y
+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=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_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_NETDEVICES=y
+CONFIG_HIX5HD2_GMAC=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_MFD_SYSCON=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_DRM=y
+CONFIG_FB_SIMPLE=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MXC=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_MMC=y
+CONFIG_RTC_CLASS=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_IDMAC=y
+CONFIG_MMC_DW_PLTFM=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_DMADEVICES=y
+CONFIG_DW_DMAC=y
+CONFIG_PL330_DMA=y
+CONFIG_PWM=y
+CONFIG_PHY_HIX5HD2_SATA=y
+CONFIG_EXT4_FS=y
+CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_VFP=y
+CONFIG_VFPv3=y
diff --git a/arch/arm/configs/imote2_defconfig b/arch/arm/configs/imote2_defconfig
new file mode 100644
index 000000000..18e59feaa
--- /dev/null
+++ b/arch/arm/configs/imote2_defconfig
@@ -0,0 +1,390 @@
+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_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_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/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig
new file mode 100644
index 000000000..d3a801863
--- /dev/null
+++ b/arch/arm/configs/imx_v4_v5_defconfig
@@ -0,0 +1,192 @@
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CGROUPS=y
+CONFIG_EXPERT=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_MULTI_V4T=y
+CONFIG_ARCH_MULTI_V5=y
+# CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_ARCH_MXC=y
+CONFIG_MACH_SCB9328=y
+CONFIG_MACH_APF9328=y
+CONFIG_MACH_MX21ADS=y
+CONFIG_MACH_EUKREA_CPUIMX25SD=y
+CONFIG_SOC_IMX25=y
+CONFIG_MACH_MX27ADS=y
+CONFIG_MACH_MX27_3DS=y
+CONFIG_MACH_IMX27_VISSTRIM_M10=y
+CONFIG_MACH_PCA100=y
+CONFIG_MACH_MXT_TD60=y
+CONFIG_MACH_IMX27_DT=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+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_NETFILTER=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_IMX_WEIM=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=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_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_EEPROM_AT25=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_IMX=y
+CONFIG_NETDEVICES=y
+CONFIG_CS89x0=y
+CONFIG_CS89x0_PLATFORM=y
+CONFIG_DM9000=y
+CONFIG_SMC91X=y
+CONFIG_SMC911X=y
+CONFIG_SMSC911X=y
+CONFIG_SMSC_PHY=y
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_IMX=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=m
+CONFIG_TOUCHSCREEN_MC13783=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_IMX=y
+CONFIG_SPI=y
+CONFIG_SPI_IMX=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_W1=y
+CONFIG_W1_MASTER_MXC=y
+CONFIG_W1_SLAVE_THERM=y
+CONFIG_HWMON=m
+CONFIG_SENSORS_MC13783_ADC=m
+CONFIG_WATCHDOG=y
+CONFIG_IMX2_WDT=y
+CONFIG_MFD_MC13XXX_SPI=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_MC13783=y
+CONFIG_REGULATOR_MC13892=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_VIDEO_MX2=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_CODA=y
+CONFIG_SOC_CAMERA_OV2640=y
+CONFIG_FB=y
+CONFIG_FB_IMX=y
+CONFIG_LCD_L4F00242T03=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_SOC_MX27VIS_AIC32X4=y
+CONFIG_SND_SOC_PHYCORE_AC97=y
+CONFIG_SND_SOC_EUKREA_TLV320=y
+CONFIG_SND_SOC_IMX_SGTL5000=y
+CONFIG_SND_SOC_IMX_MC13783=y
+CONFIG_USB_HID=m
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MXC=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_MMC_MXC=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_MC13783=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_PCF8563=y
+CONFIG_RTC_DRV_IMXDI=y
+CONFIG_RTC_DRV_MC13XXX=y
+CONFIG_RTC_DRV_MXC=y
+CONFIG_DMADEVICES=y
+CONFIG_IMX_SDMA=y
+CONFIG_IMX_DMA=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_VFAT_FS=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_UBIFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
new file mode 100644
index 000000000..fdeb1c83d
--- /dev/null
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -0,0 +1,356 @@
+CONFIG_KERNEL_LZO=y
+CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_CGROUPS=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+CONFIG_PERF_EVENTS=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_BLK_DEV_BSG is not set
+CONFIG_ARCH_MULTI_V6=y
+CONFIG_ARCH_MXC=y
+CONFIG_MACH_MX31LILLY=y
+CONFIG_MACH_MX31LITE=y
+CONFIG_MACH_PCM037=y
+CONFIG_MACH_PCM037_EET=y
+CONFIG_MACH_MX31_3DS=y
+CONFIG_MACH_MX31MOBOARD=y
+CONFIG_MACH_QONG=y
+CONFIG_MACH_ARMADILLO5X0=y
+CONFIG_MACH_KZM_ARM11_01=y
+CONFIG_MACH_IMX31_DT=y
+CONFIG_MACH_IMX35_DT=y
+CONFIG_MACH_PCM043=y
+CONFIG_MACH_MX35_3DS=y
+CONFIG_MACH_VPR200=y
+CONFIG_SOC_IMX50=y
+CONFIG_SOC_IMX51=y
+CONFIG_SOC_IMX53=y
+CONFIG_SOC_IMX6Q=y
+CONFIG_SOC_IMX6SL=y
+CONFIG_SOC_IMX6SX=y
+CONFIG_SOC_VF610=y
+CONFIG_PCI=y
+CONFIG_PCI_IMX6=y
+CONFIG_SMP=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_CMA=y
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_ARM_IMX6Q_CPUFREQ=y
+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=y
+CONFIG_NETFILTER=y
+CONFIG_CAN=y
+CONFIG_CAN_FLEXCAN=y
+CONFIG_BT=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_3WIRE=y
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_DMA_CMA=y
+CONFIG_IMX_WEIM=y
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=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_CFI_STAA=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SST25L=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_GPMI_NAND=y
+CONFIG_MTD_NAND_MXC=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_SPI_FSL_QUADSPI=y
+CONFIG_MTD_UBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_AHCI_IMX=y
+CONFIG_PATA_IMX=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+CONFIG_CS89x0=y
+CONFIG_CS89x0_PLATFORM=y
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+CONFIG_SMC91X=y
+CONFIG_SMC911X=y
+CONFIG_SMSC911X=y
+# CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_AT803X_PHY=y
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_RTL8152=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_CDC_EEM=m
+CONFIG_BRCMFMAC=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_IMX=y
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_PS2_ELANTECH=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_EGALAX=y
+CONFIG_TOUCHSCREEN_MC13783=y
+CONFIG_TOUCHSCREEN_TSC2007=y
+CONFIG_TOUCHSCREEN_STMPE=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_MMA8450=y
+CONFIG_SERIO_SERPORT=m
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_HW_RANDOM=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+CONFIG_I2C_IMX=y
+CONFIG_SPI=y
+CONFIG_SPI_IMX=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_MC9S08DZ60=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_STMPE=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_IMX=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_SENSORS_GPIO_FAN=y
+CONFIG_THERMAL=y
+CONFIG_CPU_THERMAL=y
+CONFIG_IMX_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_IMX2_WDT=y
+CONFIG_MFD_DA9052_I2C=y
+CONFIG_MFD_MC13XXX_SPI=y
+CONFIG_MFD_MC13XXX_I2C=y
+CONFIG_MFD_STMPE=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_ANATOP=y
+CONFIG_REGULATOR_DA9052=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_MC13783=y
+CONFIG_REGULATOR_MC13892=y
+CONFIG_REGULATOR_PFUZE100=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_RC_SUPPORT=y
+CONFIG_RC_DEVICES=y
+CONFIG_IR_GPIO_CIR=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_VIDEO_MX3=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_CODA=y
+CONFIG_SOC_CAMERA_OV2640=y
+CONFIG_IMX_IPUV3_CORE=y
+CONFIG_DRM=y
+CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_L4F00242T03=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_FB_MXS=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_BACKLIGHT_GPIO=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_FSL_SAI=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_SOC_PHYCORE_AC97=y
+CONFIG_SND_SOC_EUKREA_TLV320=y
+CONFIG_SND_SOC_IMX_WM8962=y
+CONFIG_SND_SOC_IMX_SGTL5000=y
+CONFIG_SND_SOC_IMX_SPDIF=y
+CONFIG_SND_SOC_IMX_MC13783=y
+CONFIG_SND_SOC_TLV320AIC3X=y
+CONFIG_SND_SIMPLE_CARD=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MXC=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_EHSET_TEST_FIXTURE=m
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_CONFIGFS=m
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_LB_SS=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_G_NCM=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=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_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_ISL1208=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_DRV_MC13XXX=y
+CONFIG_RTC_DRV_MXC=y
+CONFIG_RTC_DRV_SNVS=y
+CONFIG_DMADEVICES=y
+CONFIG_IMX_SDMA=y
+CONFIG_MXS_DMA=y
+CONFIG_FSL_EDMA=y
+CONFIG_STAGING=y
+CONFIG_DRM_IMX=y
+CONFIG_DRM_IMX_FB_HELPER=y
+CONFIG_DRM_IMX_PARALLEL_DISPLAY=y
+CONFIG_DRM_IMX_TVE=y
+CONFIG_DRM_IMX_LDB=y
+CONFIG_DRM_IMX_IPUV3=y
+CONFIG_DRM_IMX_HDMI=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PWM=y
+CONFIG_PWM_IMX=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_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_JFFS2_FS=y
+CONFIG_UBIFS_FS=y
+CONFIG_NFS_FS=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=y
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_PROVE_LOCKING=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_SECURITYFS=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
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig
new file mode 100644
index 000000000..71f14675d
--- /dev/null
+++ b/arch/arm/configs/integrator_defconfig
@@ -0,0 +1,91 @@
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=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_PARTITION_ADVANCED=y
+CONFIG_ARCH_MULTI_V4T=y
+CONFIG_ARCH_MULTI_V5=y
+# CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_ARCH_INTEGRATOR=y
+CONFIG_ARCH_INTEGRATOR_AP=y
+CONFIG_ARCH_INTEGRATOR_CP=y
+CONFIG_INTEGRATOR_IMPD1=y
+CONFIG_CPU_ARM720T=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_ARM922T=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_ARM1020=y
+CONFIG_CPU_ARM1022=y
+CONFIG_CPU_ARM1026=y
+CONFIG_PCI=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_ATAGS is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyAM0,38400n8 root=/dev/nfs ip=bootp"
+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_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_CMDLINE_PARTS=y
+CONFIG_MTD_AFS_PARTS=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_PROC_DEVICETREE=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_NETDEVICES=y
+CONFIG_E100=y
+CONFIG_SMC91X=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+# CONFIG_VGA_CONSOLE 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_LEDS_TRIGGER_CPU=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PL030=y
+CONFIG_EXT2_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
diff --git a/arch/arm/configs/iop13xx_defconfig b/arch/arm/configs/iop13xx_defconfig
new file mode 100644
index 000000000..4fa94a1f1
--- /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 000000000..c3058da63
--- /dev/null
+++ b/arch/arm/configs/iop32x_defconfig
@@ -0,0 +1,136 @@
+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_DEBUG_LL_UART_8250=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 000000000..713faeee8
--- /dev/null
+++ b/arch/arm/configs/iop33x_defconfig
@@ -0,0 +1,92 @@
+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_DEBUG_LL_UART_8250=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
new file mode 100644
index 000000000..24636cfdf
--- /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_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
+CONFIG_DEBUG_LL_UART_8250=y
diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig
new file mode 100644
index 000000000..ea80e7e86
--- /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/keystone_defconfig b/arch/arm/configs/keystone_defconfig
new file mode 100644
index 000000000..f8a1c8f2c
--- /dev/null
+++ b/arch/arm/configs/keystone_defconfig
@@ -0,0 +1,204 @@
+# CONFIG_SWAP is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_ELF_CORE is not set
+# CONFIG_BASE_FULL is not set
+CONFIG_EMBEDDED=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_ARCH_KEYSTONE=y
+CONFIG_ARM_LPAE=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_KEYSTONE=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_SUSPEND is not set
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_SUB_POLICY=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=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_IPIP=y
+CONFIG_NET_IPGRE_DEMUX=y
+CONFIG_NET_IPGRE=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_INET_AH=y
+CONFIG_INET_IPCOMP=y
+CONFIG_IPV6=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_PIMSM_V2=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+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=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NF_CONNTRACK_IPV4=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_ULOG=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_CLUSTERIP=y
+CONFIG_IP_NF_TARGET_ECN=y
+CONFIG_IP_NF_TARGET_TTL=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP_SCTP=y
+CONFIG_VLAN_8021Q=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_CMA=y
+CONFIG_DMA_CMA=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_PLATRAM=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_DAVINCI=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_UBI=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_EEPROM_AT24=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_DAVINCI=y
+CONFIG_SPI=y
+CONFIG_SPI_DAVINCI=y
+CONFIG_SPI_SPIDEV=y
+# CONFIG_HWMON is not set
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_KEYSTONE=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_DAVINCI_WATCHDOG=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_MON=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_DEBUG=y
+CONFIG_USB_DWC3_VERBOSE=y
+CONFIG_KEYSTONE_USB_PHY=y
+CONFIG_DMADEVICES=y
+CONFIG_TI_EDMA=y
+CONFIG_MEMORY=y
+CONFIG_TI_AEMIF=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+CONFIG_UBIFS_FS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_DAVINCI=y
+CONFIG_LEDS_CLASS=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_KEYSTONE_IRQ=y
+CONFIG_GPIO_SYSCON=y
+CONFIG_TI_DAVINCI_MDIO=y
+CONFIG_MARVELL_PHY=y
+CONFIG_DEVTMPFS=y
diff --git a/arch/arm/configs/ks8695_defconfig b/arch/arm/configs/ks8695_defconfig
new file mode 100644
index 000000000..47c488379
--- /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/kzm9g_defconfig b/arch/arm/configs/kzm9g_defconfig
new file mode 100644
index 000000000..23e8d146d
--- /dev/null
+++ b/arch/arm/configs/kzm9g_defconfig
@@ -0,0 +1,154 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+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_NET_NS is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=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_LEGACY=y
+CONFIG_ARCH_SH73A0=y
+CONFIG_MACH_KZM9G=y
+CONFIG_MEMORY_START=0x41000000
+CONFIG_MEMORY_SIZE=0x1f000000
+CONFIG_ARM_ERRATA_743622=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SMP=y
+CONFIG_SCHED_MC=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_KEXEC=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+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_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=y
+CONFIG_SH_IRDA=y
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+CONFIG_SMSC911X=y
+# CONFIG_WLAN is not set
+CONFIG_INPUT_SPARSEKMAP=y
+# 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_TOUCHSCREEN_ST1232=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_ADXL34X=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=9
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_SH_MOBILE=y
+CONFIG_GPIO_PCF857X=y
+# CONFIG_HWMON is not set
+CONFIG_MFD_AS3711=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_AS3711=y
+CONFIG_FB=y
+CONFIG_FB_SH_MOBILE_LCDC=y
+CONFIG_BACKLIGHT_AS3711=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_FB_SH_MOBILE_MERAM=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_SH4_FSI=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_R8A66597_HCD=y
+CONFIG_USB_RENESAS_USBHS=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_RENESAS_USBHS_UDC=y
+CONFIG_USB_ETH=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_MMC=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_SDHI=y
+CONFIG_MMC_SH_MMCIF=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_RS5C372=y
+CONFIG_DMADEVICES=y
+CONFIG_SH_DMAE=y
+CONFIG_ASYNC_TX_DMA=y
+CONFIG_STAGING=y
+CONFIG_IIO=y
+CONFIG_AK8975=y
+# CONFIG_DNOTIFY is not set
+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_ISO8859_1=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRC16=y
diff --git a/arch/arm/configs/lart_defconfig b/arch/arm/configs/lart_defconfig
new file mode 100644
index 000000000..faa286565
--- /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/lpc32xx_defconfig b/arch/arm/configs/lpc32xx_defconfig
new file mode 100644
index 000000000..c100b7df5
--- /dev/null
+++ b/arch/arm/configs/lpc32xx_defconfig
@@ -0,0 +1,211 @@
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ARCH_LPC32XX=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_KEYBOARD_GPIO_POLLED=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CMDLINE="console=ttyS0,115200n81 root=/dev/ram0"
+CONFIG_CPU_IDLE=y
+CONFIG_FPE_NWFPE=y
+CONFIG_VFP=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+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_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_IPV6_PRIVACY=y
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_SLC_LPC32XX=y
+CONFIG_MTD_NAND_MLC_LPC32XX=y
+CONFIG_MTD_UBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+CONFIG_LPC_ENET=y
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_WLAN is not set
+# 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_KEYBOARD_LPC32XX=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_LPC32XX=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_HS_LPC32XX=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PNX=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_GPIO_EM=y
+CONFIG_GPIO_PL061=y
+CONFIG_GPIO_MAX7300=y
+CONFIG_GPIO_MAX732X=y
+CONFIG_GPIO_PCF857X=y
+CONFIG_GPIO_SX150X=y
+CONFIG_GPIO_ADP5588=y
+CONFIG_GPIO_ADNP=y
+CONFIG_GPIO_MAX7301=y
+CONFIG_GPIO_MCP23S08=y
+CONFIG_GPIO_MC33880=y
+CONFIG_GPIO_74X164=y
+CONFIG_SENSORS_DS620=y
+CONFIG_SENSORS_MAX6639=y
+CONFIG_WATCHDOG=y
+CONFIG_PNX4008_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_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_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+CONFIG_SND_DEBUG=y
+CONFIG_SND_DEBUG_VERBOSE=y
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_SOC=y
+CONFIG_USB=y
+CONFIG_USB_PHY=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_LPC32XX=y
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_MMC=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_ARMMMCI=y
+CONFIG_MMC_SPI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_PCA9532=y
+CONFIG_LEDS_PCA9532_GPIO=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=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_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_DS1374=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_DRV_LPC32XX=y
+CONFIG_DMADEVICES=y
+CONFIG_AMBA_PL08X=y
+CONFIG_STAGING=y
+CONFIG_LPC32XX_ADC=y
+CONFIG_IIO=y
+CONFIG_MAX517=y
+CONFIG_PWM=y
+CONFIG_PWM_LPC32XX=y
+CONFIG_EXT2_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+CONFIG_UBIFS_FS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_FTRACE is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_UART_8250=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/lpd270_defconfig b/arch/arm/configs/lpd270_defconfig
new file mode 100644
index 000000000..1c8c9ee71
--- /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 000000000..c4ba27458
--- /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/magician_defconfig b/arch/arm/configs/magician_defconfig
new file mode 100644
index 000000000..557dd2912
--- /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_GPIO=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_MASS_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 000000000..04efa1b3e
--- /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/marzen_defconfig b/arch/arm/configs/marzen_defconfig
new file mode 100644
index 000000000..3c8b6d823
--- /dev/null
+++ b/arch/arm/configs/marzen_defconfig
@@ -0,0 +1,124 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_KERNEL_LZMA=y
+CONFIG_NO_HZ=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_SHMOBILE_LEGACY=y
+CONFIG_ARCH_R8A7779=y
+CONFIG_MACH_MARZEN=y
+CONFIG_MEMORY_START=0x60000000
+CONFIG_MEMORY_SIZE=0x10000000
+CONFIG_SHMOBILE_TIMER_HZ=1024
+# CONFIG_SH_TIMER_CMT is not set
+# CONFIG_SWP_EMULATE is not set
+CONFIG_ARM_ERRATA_430973=y
+CONFIG_ARM_ERRATA_458693=y
+CONFIG_ARM_ERRATA_460075=y
+CONFIG_ARM_ERRATA_743622=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_SMP=y
+# CONFIG_ARM_CPU_TOPOLOGY is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_VFP=y
+CONFIG_KEXEC=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+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_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_ATA_SFF=y
+CONFIG_ATA_BMDMA=y
+CONFIG_SATA_RCAR=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+CONFIG_SMSC911X=y
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_RCAR=y
+CONFIG_SPI=y
+CONFIG_SPI_SH_HSPI=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_RCAR=y
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_RCAR_THERMAL=y
+CONFIG_SSB=y
+CONFIG_REGULATOR=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_VIDEO_RCAR_VIN=y
+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
+CONFIG_VIDEO_ADV7180=y
+CONFIG_DRM=y
+CONFIG_DRM_RCAR_DU=y
+CONFIG_USB=y
+CONFIG_USB_RCAR_PHY=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHI=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_DMADEVICES=y
+CONFIG_RCAR_HPB_DMAE=y
+CONFIG_UIO=y
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_REDUCED=y
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_AVERAGE=y
diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig
new file mode 100644
index 000000000..9c93f5655
--- /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_S3C24XX=y
+# CONFIG_CPU_S3C2410 is not set
+CONFIG_CPU_S3C2440=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_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_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_MASS_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 000000000..f1cb95e58
--- /dev/null
+++ b/arch/arm/configs/mmp2_defconfig
@@ -0,0 +1,98 @@
+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_BROWNSTONE=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 earlyprintk"
+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_MMC=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+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 is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_MMP_UART3=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/moxart_defconfig b/arch/arm/configs/moxart_defconfig
new file mode 100644
index 000000000..a3cb76cfb
--- /dev/null
+++ b/arch/arm/configs/moxart_defconfig
@@ -0,0 +1,149 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_ELF_CORE is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_MULTI_V4T=y
+# CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_KEYBOARD_GPIO_POLLED=y
+CONFIG_ARCH_MOXART=y
+CONFIG_MACH_UC7112LX=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_ATAGS is not set
+CONFIG_ARM_APPENDED_DTB=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_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=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_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_NETDEVICES=y
+CONFIG_NETCONSOLE=y
+CONFIG_NETCONSOLE_DYNAMIC=y
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+CONFIG_ARM_MOXART_ETHER=y
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_REALTEK_PHY=y
+CONFIG_MDIO_MOXART=y
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_MOXART=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_MOXART_WDT=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI_MOXART=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_MOXART=y
+CONFIG_DMADEVICES=y
+CONFIG_MOXART_DMA=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT3_FS=y
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_DEBUG_OBJECTS=y
+CONFIG_DEBUG_KMEMLEAK=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_PROVE_LOCKING=y
+CONFIG_DMA_API_DEBUG=y
+CONFIG_KGDB=y
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_UART_8250=y
+CONFIG_DEBUG_UART_PHYS=0x98200000
+CONFIG_DEBUG_UART_VIRT=0xf9820000
+CONFIG_EARLY_PRINTK=y
+CONFIG_KEYS=y
+CONFIG_CRC32_BIT=y
diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig
new file mode 100644
index 000000000..f69a459f4
--- /dev/null
+++ b/arch/arm/configs/multi_v5_defconfig
@@ -0,0 +1,195 @@
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=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_MULTI_V7 is not set
+CONFIG_ARCH_MVEBU=y
+CONFIG_MACH_KIRKWOOD=y
+CONFIG_MACH_NETXBIG=y
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMX25=y
+CONFIG_MACH_IMX27_DT=y
+CONFIG_ARCH_U300=y
+CONFIG_PCI_MVEBU=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_IDLE=y
+CONFIG_ARM_KIRKWOOD_CPUIDLE=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_CFG80211=y
+CONFIG_MAC80211=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=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_EEPROM_AT24=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_AHCI=y
+CONFIG_SATA_MV=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_DSA_MV88E6123_61_65=y
+CONFIG_NET_DSA_MV88E6171=y
+CONFIG_MV643XX_ETH=y
+CONFIG_R8169=y
+CONFIG_MARVELL_PHY=y
+CONFIG_MWL8K=m
+CONFIG_LIBERTAS=y
+CONFIG_LIBERTAS_SDIO=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE 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_RUNTIME_UARTS=2
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MV64XXX=y
+CONFIG_I2C_NOMADIK=y
+CONFIG_SPI=y
+CONFIG_SPI_ORION=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_QNAP=y
+CONFIG_SENSORS_ADT7475=y
+CONFIG_SENSORS_G762=y
+CONFIG_SENSORS_LM63=y
+CONFIG_SENSORS_LM75=y
+CONFIG_SENSORS_LM85=y
+CONFIG_THERMAL=y
+CONFIG_KIRKWOOD_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_ORION_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_KIRKWOOD_SOC=y
+CONFIG_SND_KIRKWOOD_SOC_T5325=y
+CONFIG_SND_SOC_ALC5623=y
+CONFIG_SND_SIMPLE_CARD=y
+# CONFIG_ABX500_CORE is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=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_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=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_RS5C372=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_DRV_S35390A=y
+CONFIG_RTC_DRV_MV=y
+CONFIG_DMADEVICES=y
+CONFIG_MV_XOR=y
+CONFIG_STAGING=y
+CONFIG_FB_XGI=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=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_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_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=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_LIBCRC32C=y
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
new file mode 100644
index 000000000..fbbb1915c
--- /dev/null
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -0,0 +1,592 @@
+CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_CGROUPS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_CMDLINE_PARTITION=y
+CONFIG_ARCH_VIRT=y
+CONFIG_ARCH_ALPINE=y
+CONFIG_ARCH_MVEBU=y
+CONFIG_MACH_ARMADA_370=y
+CONFIG_MACH_ARMADA_375=y
+CONFIG_MACH_ARMADA_38X=y
+CONFIG_MACH_ARMADA_39X=y
+CONFIG_MACH_ARMADA_XP=y
+CONFIG_MACH_DOVE=y
+CONFIG_ARCH_BCM=y
+CONFIG_ARCH_BCM_CYGNUS=y
+CONFIG_ARCH_BCM_21664=y
+CONFIG_ARCH_BCM_281XX=y
+CONFIG_ARCH_BCM_5301X=y
+CONFIG_ARCH_BRCMSTB=y
+CONFIG_ARCH_BERLIN=y
+CONFIG_MACH_BERLIN_BG2=y
+CONFIG_MACH_BERLIN_BG2CD=y
+CONFIG_MACH_BERLIN_BG2Q=y
+CONFIG_ARCH_HIGHBANK=y
+CONFIG_ARCH_HISI=y
+CONFIG_ARCH_HI3xxx=y
+CONFIG_ARCH_HIX5HD2=y
+CONFIG_ARCH_HIP01=y
+CONFIG_ARCH_HIP04=y
+CONFIG_ARCH_KEYSTONE=y
+CONFIG_ARCH_MESON=y
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMX50=y
+CONFIG_SOC_IMX51=y
+CONFIG_SOC_IMX53=y
+CONFIG_SOC_IMX6Q=y
+CONFIG_SOC_IMX6SL=y
+CONFIG_SOC_IMX6SX=y
+CONFIG_SOC_VF610=y
+CONFIG_SOC_LS1021A=y
+CONFIG_ARCH_OMAP3=y
+CONFIG_ARCH_OMAP4=y
+CONFIG_SOC_OMAP5=y
+CONFIG_SOC_AM33XX=y
+CONFIG_SOC_AM43XX=y
+CONFIG_SOC_DRA7XX=y
+CONFIG_ARCH_QCOM=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_ARCH_MSM8X60=y
+CONFIG_ARCH_MSM8960=y
+CONFIG_ARCH_MSM8974=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_ARCH_SOCFPGA=y
+CONFIG_PLAT_SPEAR=y
+CONFIG_ARCH_SPEAR13XX=y
+CONFIG_MACH_SPEAR1310=y
+CONFIG_MACH_SPEAR1340=y
+CONFIG_ARCH_STI=y
+CONFIG_ARCH_EXYNOS=y
+CONFIG_EXYNOS5420_MCPM=y
+CONFIG_ARCH_SHMOBILE_MULTI=y
+CONFIG_ARCH_EMEV2=y
+CONFIG_ARCH_R7S72100=y
+CONFIG_ARCH_R8A73A4=y
+CONFIG_ARCH_R8A7740=y
+CONFIG_ARCH_R8A7779=y
+CONFIG_ARCH_R8A7790=y
+CONFIG_ARCH_R8A7791=y
+CONFIG_ARCH_R8A7794=y
+CONFIG_ARCH_SH73A0=y
+CONFIG_MACH_MARZEN=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_ARCH_SIRF=y
+CONFIG_ARCH_TEGRA=y
+CONFIG_ARCH_TEGRA_2x_SOC=y
+CONFIG_ARCH_TEGRA_3x_SOC=y
+CONFIG_ARCH_TEGRA_114_SOC=y
+CONFIG_ARCH_TEGRA_124_SOC=y
+CONFIG_TEGRA_EMC_SCALING_ENABLE=y
+CONFIG_ARCH_U8500=y
+CONFIG_MACH_HREFV60=y
+CONFIG_MACH_SNOWBALL=y
+CONFIG_MACH_UX500_DT=y
+CONFIG_ARCH_VEXPRESS=y
+CONFIG_ARCH_VEXPRESS_CA9X4=y
+CONFIG_ARCH_WM8850=y
+CONFIG_ARCH_ZYNQ=y
+CONFIG_TRUSTED_FOUNDATIONS=y
+CONFIG_PCI=y
+CONFIG_PCI_HOST_GENERIC=y
+CONFIG_PCI_KEYSTONE=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MVEBU=y
+CONFIG_PCI_TEGRA=y
+CONFIG_PCI_RCAR_GEN2=y
+CONFIG_PCI_RCAR_GEN2_PCIE=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=16
+CONFIG_HIGHPTE=y
+CONFIG_CMA=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_KEXEC=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_IDLE=y
+CONFIG_NEON=y
+CONFIG_ARM_ZYNQ_CPUIDLE=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_ROUTER_PREF=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+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_CAN=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+CONFIG_CAN_DEV=y
+CONFIG_CAN_XILINXCAN=y
+CONFIG_CAN_MCP251X=y
+CONFIG_BT=m
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_RFKILL_GPIO=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=64
+CONFIG_OMAP_OCP2SCP=y
+CONFIG_SIMPLE_PM_BUS=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_DAVINCI=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_UBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_AD525X_DPOT=y
+CONFIG_AD525X_DPOT_I2C=y
+CONFIG_ICS932S401=y
+CONFIG_APDS9802ALS=y
+CONFIG_ISL29003=y
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_SUNXI_SID=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_AHCI_ST=y
+CONFIG_AHCI_SUNXI=y
+CONFIG_AHCI_TEGRA=y
+CONFIG_SATA_HIGHBANK=y
+CONFIG_SATA_MV=y
+CONFIG_SATA_RCAR=y
+CONFIG_NETDEVICES=y
+CONFIG_HIX5HD2_GMAC=y
+CONFIG_SUN4I_EMAC=y
+CONFIG_MACB=y
+CONFIG_NET_CALXEDA_XGMAC=y
+CONFIG_IGB=y
+CONFIG_MV643XX_ETH=y
+CONFIG_MVNETA=y
+CONFIG_KS8851=y
+CONFIG_R8169=y
+CONFIG_SH_ETH=y
+CONFIG_SMSC911X=y
+CONFIG_STMMAC_ETH=y
+CONFIG_TI_CPSW=y
+CONFIG_XILINX_EMACLITE=y
+CONFIG_AT803X_PHY=y
+CONFIG_MARVELL_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_MICREL_PHY=y
+CONFIG_USB_PEGASUS=y
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_SMSC75XX=y
+CONFIG_USB_NET_SMSC95XX=y
+CONFIG_BRCMFMAC=m
+CONFIG_RT2X00=m
+CONFIG_RT2800USB=m
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+CONFIG_INPUT_JOYDEV=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_TEGRA=y
+CONFIG_KEYBOARD_SPEAR=y
+CONFIG_KEYBOARD_ST_KEYSCAN=y
+CONFIG_KEYBOARD_CROS_EC=y
+CONFIG_MOUSE_PS2_ELANTECH=y
+CONFIG_MOUSE_ELAN_I2C=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_ST1232=m
+CONFIG_TOUCHSCREEN_STMPE=y
+CONFIG_TOUCHSCREEN_SUN4I=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_MPU3050=y
+CONFIG_INPUT_AXP20X_PEK=y
+CONFIG_INPUT_ADXL34X=m
+CONFIG_SERIO_AMBAKMI=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_8250_EM=y
+CONFIG_SERIAL_8250_MT6577=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_MESON=y
+CONFIG_SERIAL_MESON_CONSOLE=y
+CONFIG_SERIAL_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_SERIAL_SIRFSOC=y
+CONFIG_SERIAL_SIRFSOC_CONSOLE=y
+CONFIG_SERIAL_TEGRA=y
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=20
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_SERIAL_VT8500=y
+CONFIG_SERIAL_VT8500_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_OMAP=y
+CONFIG_SERIAL_OMAP_CONSOLE=y
+CONFIG_SERIAL_XILINX_PS_UART=y
+CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_SERIAL_ST_ASC=y
+CONFIG_SERIAL_ST_ASC_CONSOLE=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_DAVINCI=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_MUX_PINCTRL=y
+CONFIG_I2C_CADENCE=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_I2C_GPIO=m
+CONFIG_I2C_EXYNOS5=y
+CONFIG_I2C_MV64XXX=y
+CONFIG_I2C_RIIC=y
+CONFIG_I2C_S3C2410=y
+CONFIG_I2C_SH_MOBILE=y
+CONFIG_I2C_SIRF=y
+CONFIG_I2C_ST=y
+CONFIG_I2C_TEGRA=y
+CONFIG_I2C_XILINX=y
+CONFIG_I2C_RCAR=y
+CONFIG_SPI=y
+CONFIG_SPI_CADENCE=y
+CONFIG_SPI_DAVINCI=y
+CONFIG_SPI_OMAP24XX=y
+CONFIG_SPI_ORION=y
+CONFIG_SPI_PL022=y
+CONFIG_SPI_RSPI=y
+CONFIG_SPI_SH_MSIOF=m
+CONFIG_SPI_SH_HSPI=y
+CONFIG_SPI_SIRF=y
+CONFIG_SPI_SUN4I=y
+CONFIG_SPI_SUN6I=y
+CONFIG_SPI_TEGRA114=y
+CONFIG_SPI_TEGRA20_SFLASH=y
+CONFIG_SPI_TEGRA20_SLINK=y
+CONFIG_SPI_XILINX=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_PINCTRL_AS3722=y
+CONFIG_PINCTRL_PALMAS=y
+CONFIG_PINCTRL_APQ8084=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_GPIO_DAVINCI=y
+CONFIG_GPIO_DWAPB=y
+CONFIG_GPIO_EM=y
+CONFIG_GPIO_RCAR=y
+CONFIG_GPIO_XILINX=y
+CONFIG_GPIO_ZYNQ=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_GPIO_PCF857X=y
+CONFIG_GPIO_TWL4030=y
+CONFIG_GPIO_PALMAS=y
+CONFIG_GPIO_SYSCON=y
+CONFIG_GPIO_TPS6586X=y
+CONFIG_GPIO_TPS65910=y
+CONFIG_BATTERY_SBS=y
+CONFIG_CHARGER_TPS65090=y
+CONFIG_POWER_RESET_AS3722=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_GPIO_RESTART=y
+CONFIG_POWER_RESET_KEYSTONE=y
+CONFIG_POWER_RESET_SUN6I=y
+CONFIG_POWER_RESET_RMOBILE=y
+CONFIG_SENSORS_LM90=y
+CONFIG_SENSORS_LM95245=y
+CONFIG_THERMAL=y
+CONFIG_CPU_THERMAL=y
+CONFIG_RCAR_THERMAL=y
+CONFIG_ARMADA_THERMAL=y
+CONFIG_DAVINCI_WATCHDOG
+CONFIG_ST_THERMAL_SYSCFG=y
+CONFIG_ST_THERMAL_MEMMAP=y
+CONFIG_WATCHDOG=y
+CONFIG_XILINX_WATCHDOG=y
+CONFIG_ARM_SP805_WATCHDOG=y
+CONFIG_ORION_WATCHDOG=y
+CONFIG_SUNXI_WATCHDOG=y
+CONFIG_MESON_WATCHDOG=y
+CONFIG_MFD_AS3711=y
+CONFIG_MFD_AS3722=y
+CONFIG_MFD_BCM590XX=y
+CONFIG_MFD_AXP20X=y
+CONFIG_MFD_CROS_EC=y
+CONFIG_MFD_CROS_EC_SPI=y
+CONFIG_MFD_MAX77686=y
+CONFIG_MFD_MAX8907=y
+CONFIG_MFD_SEC_CORE=y
+CONFIG_MFD_STMPE=y
+CONFIG_MFD_PALMAS=y
+CONFIG_MFD_TPS65090=y
+CONFIG_MFD_TPS6586X=y
+CONFIG_MFD_TPS65910=y
+CONFIG_REGULATOR_AB8500=y
+CONFIG_REGULATOR_AS3711=y
+CONFIG_REGULATOR_AS3722=y
+CONFIG_REGULATOR_AXP20X=y
+CONFIG_REGULATOR_BCM590XX=y
+CONFIG_REGULATOR_DA9210=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_MFD_SYSCON=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_REGULATOR_MAX8907=y
+CONFIG_REGULATOR_MAX8973=y
+CONFIG_REGULATOR_MAX77686=y
+CONFIG_REGULATOR_PALMAS=y
+CONFIG_REGULATOR_S2MPS11=y
+CONFIG_REGULATOR_S5M8767=y
+CONFIG_REGULATOR_TPS51632=y
+CONFIG_REGULATOR_TPS62360=y
+CONFIG_REGULATOR_TPS65090=y
+CONFIG_REGULATOR_TPS6586X=y
+CONFIG_REGULATOR_TPS65910=y
+CONFIG_REGULATOR_TWL4030=y
+CONFIG_REGULATOR_VEXPRESS=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_USB_GSPCA=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=m
+CONFIG_SOC_CAMERA_PLATFORM=m
+CONFIG_VIDEO_RCAR_VIN=m
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_RENESAS_VSP1=m
+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
+CONFIG_VIDEO_ADV7180=m
+CONFIG_DRM=y
+CONFIG_DRM_RCAR_DU=m
+CONFIG_DRM_TEGRA=y
+CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_FB_WM8505=y
+CONFIG_FB_SH_MOBILE_LCDC=y
+CONFIG_FB_SIMPLE=y
+CONFIG_FB_SH_MOBILE_MERAM=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_BACKLIGHT_AS3711=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_SH4_FSI=m
+CONFIG_SND_SOC_RCAR=m
+CONFIG_SND_SOC_TEGRA=y
+CONFIG_SND_SOC_TEGRA_RT5640=y
+CONFIG_SND_SOC_TEGRA_WM8753=y
+CONFIG_SND_SOC_TEGRA_WM8903=y
+CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
+CONFIG_SND_SOC_TEGRA_ALC5632=y
+CONFIG_SND_SOC_TEGRA_MAX98090=y
+CONFIG_SND_SOC_AK4642=m
+CONFIG_SND_SOC_WM8978=m
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_MVEBU=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EXYNOS=y
+CONFIG_USB_EHCI_TEGRA=y
+CONFIG_USB_EHCI_HCD_STI=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_ISP1760=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_STI=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_R8A66597_HCD=m
+CONFIG_USB_RENESAS_USBHS=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_AB8500_USB=y
+CONFIG_KEYSTONE_USB_PHY=y
+CONFIG_OMAP_USB3=y
+CONFIG_SAMSUNG_USB2PHY=y
+CONFIG_SAMSUNG_USB3PHY=y
+CONFIG_USB_GPIO_VBUS=y
+CONFIG_USB_ISP1301=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_USB_RCAR_PHY=m
+CONFIG_USB_RCAR_GEN2_PHY=m
+CONFIG_USB_GADGET=y
+CONFIG_USB_RENESAS_USBHS_UDC=m
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK_MINORS=16
+CONFIG_MMC_ARMMMCI=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_OF_ARASAN=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_MMC_SDHCI_DOVE=y
+CONFIG_MMC_SDHCI_TEGRA=y
+CONFIG_MMC_SDHCI_PXAV3=y
+CONFIG_MMC_SDHCI_SPEAR=y
+CONFIG_MMC_SDHCI_S3C=y
+CONFIG_MMC_SDHCI_S3C_DMA=y
+CONFIG_MMC_SDHCI_BCM_KONA=y
+CONFIG_MMC_SDHCI_ST=y
+CONFIG_MMC_OMAP=y
+CONFIG_MMC_OMAP_HS=y
+CONFIG_MMC_MVSDIO=y
+CONFIG_MMC_SDHI=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_IDMAC=y
+CONFIG_MMC_DW_PLTFM=y
+CONFIG_MMC_DW_EXYNOS=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_SH_MMCIF=y
+CONFIG_MMC_SUNXI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_TRANSIENT=y
+CONFIG_LEDS_TRIGGER_CAMERA=y
+CONFIG_EDAC=y
+CONFIG_EDAC_MM_EDAC=y
+CONFIG_EDAC_HIGHBANK_MC=y
+CONFIG_EDAC_HIGHBANK_L2=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AS3722=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_MAX8907=y
+CONFIG_RTC_DRV_MAX77686=y
+CONFIG_RTC_DRV_RS5C372=m
+CONFIG_RTC_DRV_PALMAS=y
+CONFIG_RTC_DRV_TWL4030=y
+CONFIG_RTC_DRV_TPS6586X=y
+CONFIG_RTC_DRV_TPS65910=y
+CONFIG_RTC_DRV_S35390A=m
+CONFIG_RTC_DRV_EM3027=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_RTC_DRV_VT8500=y
+CONFIG_RTC_DRV_SUN6I=y
+CONFIG_RTC_DRV_SUNXI=y
+CONFIG_RTC_DRV_MV=y
+CONFIG_RTC_DRV_TEGRA=y
+CONFIG_DMADEVICES=y
+CONFIG_DW_DMAC=y
+CONFIG_MV_XOR=y
+CONFIG_TEGRA20_APB_DMA=y
+CONFIG_SH_DMAE=y
+CONFIG_RCAR_DMAC=y
+CONFIG_STE_DMA40=y
+CONFIG_SIRF_DMA=y
+CONFIG_TI_EDMA=y
+CONFIG_PL330_DMA=y
+CONFIG_IMX_SDMA=y
+CONFIG_IMX_DMA=y
+CONFIG_MXS_DMA=y
+CONFIG_DMA_OMAP=y
+CONFIG_XILINX_VDMA=y
+CONFIG_STAGING=y
+CONFIG_SENSORS_ISL29018=y
+CONFIG_SENSORS_ISL29028=y
+CONFIG_MFD_NVEC=y
+CONFIG_KEYBOARD_NVEC=y
+CONFIG_SERIO_NVEC_PS2=y
+CONFIG_NVEC_POWER=y
+CONFIG_NVEC_PAZ00=y
+CONFIG_QCOM_GSBI=y
+CONFIG_COMMON_CLK_QCOM=y
+CONFIG_COMMON_CLK_MAX77686=y
+CONFIG_APQ_MMCC_8084=y
+CONFIG_MSM_GCC_8660=y
+CONFIG_MSM_MMCC_8960=y
+CONFIG_MSM_MMCC_8974=y
+CONFIG_TEGRA_IOMMU_GART=y
+CONFIG_TEGRA_IOMMU_SMMU=y
+CONFIG_PM_DEVFREQ=y
+CONFIG_ARM_TEGRA_DEVFREQ=m
+CONFIG_MEMORY=y
+CONFIG_TI_AEMIF=y
+CONFIG_IIO=y
+CONFIG_XILINX_XADC=y
+CONFIG_AK8975=y
+CONFIG_PWM=y
+CONFIG_PWM_RENESAS_TPU=y
+CONFIG_PWM_TEGRA=y
+CONFIG_PWM_VT8500=y
+CONFIG_PHY_HIX5HD2_SATA=y
+CONFIG_OMAP_USB2=y
+CONFIG_TI_PIPE3=y
+CONFIG_PHY_MIPHY28LP=y
+CONFIG_PHY_MIPHY365X=y
+CONFIG_PHY_STIH41X_USB=y
+CONFIG_PHY_STIH407_USB=y
+CONFIG_PHY_SUN4I_USB=y
+CONFIG_PHY_SUN9I_USB=y
+CONFIG_EXT4_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_UBIFS_FS=y
+CONFIG_TMPFS=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_CRYPTO_DEV_TEGRA_AES=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_KEYSTONE_IRQ=y
diff --git a/arch/arm/configs/mv78xx0_defconfig b/arch/arm/configs/mv78xx0_defconfig
new file mode 100644
index 000000000..85d10d2e3
--- /dev/null
+++ b/arch/arm/configs/mv78xx0_defconfig
@@ -0,0 +1,139 @@
+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_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_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_DEBUG_LL_UART_8250=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/mvebu_v5_defconfig b/arch/arm/configs/mvebu_v5_defconfig
new file mode 100644
index 000000000..824de4992
--- /dev/null
+++ b/arch/arm/configs/mvebu_v5_defconfig
@@ -0,0 +1,192 @@
+CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=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_MULTI_V7 is not set
+CONFIG_ARCH_MVEBU=y
+CONFIG_MACH_KIRKWOOD=y
+CONFIG_MACH_NETXBIG=y
+# CONFIG_CPU_FEROCEON_OLD_ID is not set
+CONFIG_PCI_MVEBU=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+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_PKTGEN=m
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=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_MTD_SPI_NOR=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_EEPROM_AT24=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_AHCI=y
+CONFIG_SATA_MV=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_DSA_MV88E6123_61_65=y
+CONFIG_NET_DSA_MV88E6171=y
+CONFIG_MV643XX_ETH=y
+CONFIG_R8169=y
+CONFIG_MARVELL_PHY=y
+CONFIG_MWL8K=m
+CONFIG_LIBERTAS=y
+CONFIG_LIBERTAS_SDIO=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE 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_RUNTIME_UARTS=2
+CONFIG_SERIAL_OF_PLATFORM=y
+# 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_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_QNAP=y
+CONFIG_SENSORS_ADT7475=y
+CONFIG_SENSORS_G762=y
+CONFIG_SENSORS_LM63=y
+CONFIG_SENSORS_LM75=y
+CONFIG_SENSORS_LM85=y
+CONFIG_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_ORION_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_KIRKWOOD_SOC=y
+CONFIG_SND_KIRKWOOD_SOC_T5325=y
+CONFIG_SND_SOC_ALC5623=y
+CONFIG_SND_SIMPLE_CARD=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=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_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=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_RS5C372=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_DRV_S35390A=y
+CONFIG_RTC_DRV_MV=y
+CONFIG_DMADEVICES=y
+CONFIG_MV_XOR=y
+CONFIG_STAGING=y
+CONFIG_FB_XGI=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=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_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_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=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_LIBCRC32C=y
diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig
new file mode 100644
index 000000000..cacc9f405
--- /dev/null
+++ b/arch/arm/configs/mvebu_v7_defconfig
@@ -0,0 +1,144 @@
+CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+CONFIG_PERF_EVENTS=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_ARCH_MVEBU=y
+CONFIG_MACH_ARMADA_370=y
+CONFIG_MACH_ARMADA_375=y
+CONFIG_MACH_ARMADA_38X=y
+CONFIG_MACH_ARMADA_39X=y
+CONFIG_MACH_ARMADA_XP=y
+CONFIG_MACH_DOVE=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MVEBU=y
+CONFIG_SMP=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+# CONFIG_COMPACTION is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_CPU_IDLE=y
+CONFIG_ARM_MVEBU_V7_CPUIDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=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_BT=y
+CONFIG_BT_MRVL=y
+CONFIG_BT_MRVL_SDIO=y
+CONFIG_CFG80211=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_PXA3xx=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_AHCI_MVEBU=y
+CONFIG_SATA_MV=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_DSA_MV88E6171=y
+CONFIG_MV643XX_ETH=y
+CONFIG_MVNETA=y
+CONFIG_MVPP2=y
+CONFIG_MARVELL_PHY=y
+CONFIG_FIXED_PHY=y
+CONFIG_MWIFIEX=y
+CONFIG_MWIFIEX_SDIO=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MV64XXX=y
+CONFIG_SPI=y
+CONFIG_SPI_ORION=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_SENSORS_GPIO_FAN=y
+CONFIG_THERMAL=y
+CONFIG_ARMADA_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_ORION_WATCHDOG=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_KIRKWOOD_SOC=y
+CONFIG_SND_SOC_CS42L51_I2C=y
+CONFIG_SND_SOC_SPDIF=y
+CONFIG_SND_SIMPLE_CARD=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_MVEBU=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_DOVE=y
+CONFIG_MMC_SDHCI_PXAV3=y
+CONFIG_MMC_MVSDIO=y
+CONFIG_LEDS_GPIO=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_S35390A=y
+CONFIG_RTC_DRV_MV=y
+CONFIG_RTC_DRV_ARMADA38X=y
+CONFIG_DMADEVICES=y
+CONFIG_MV_XOR=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_MEMORY=y
+CONFIG_EXT4_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=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_NLS_ISO8859_2=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
new file mode 100644
index 000000000..b47e7c662
--- /dev/null
+++ b/arch/arm/configs/mxs_defconfig
@@ -0,0 +1,185 @@
+CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=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_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_MULTI_V7 is not set
+CONFIG_ARCH_MXS=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_AEABI=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_FLEXCAN=m
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SST25L=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_GPMI_NAND=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_UBI=y
+# CONFIG_BLK_DEV is not set
+CONFIG_EEPROM_AT24=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+CONFIG_ENC28J60=y
+CONFIG_SMSC_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_MICREL_PHY=y
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_SMSC95XX=y
+# CONFIG_WLAN 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_TSC2007=m
+# CONFIG_SERIO is not set
+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_SERIAL_MXS_AUART=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MXS=y
+CONFIG_SPI=y
+CONFIG_SPI_GPIO=m
+CONFIG_SPI_MXS=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_STMP3XXX_RTC_WATCHDOG=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_FB=y
+CONFIG_FB_MXS=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_MXS_SOC=y
+CONFIG_SND_SOC_MXS_SGTL5000=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_MMC=y
+CONFIG_MMC_MXS=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_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_STMP=y
+CONFIG_DMADEVICES=y
+CONFIG_MXS_DMA=y
+CONFIG_STAGING=y
+CONFIG_MXS_LRADC=y
+CONFIG_IIO=y
+CONFIG_IIO_SYSFS_TRIGGER=y
+CONFIG_PWM=y
+CONFIG_PWM_MXS=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_FSCACHE=m
+CONFIG_FSCACHE_STATS=y
+CONFIG_CACHEFILES=m
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_NFS_FS=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_NLS_ISO8859_15=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_FRAME_WARN=2048
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_TIMER_STATS=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_STRICT_DEVMEM=y
+CONFIG_DEBUG_USER=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_DEV_MXS_DCP=y
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC7=m
+CONFIG_FONTS=y
diff --git a/arch/arm/configs/neponset_defconfig b/arch/arm/configs/neponset_defconfig
new file mode 100644
index 000000000..460dca4a4
--- /dev/null
+++ b/arch/arm/configs/neponset_defconfig
@@ -0,0 +1,88 @@
+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_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 000000000..25ed772df
--- /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 000000000..9c0ad7993
--- /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 000000000..7d2ad30d9
--- /dev/null
+++ b/arch/arm/configs/nhk8815_defconfig
@@ -0,0 +1,134 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+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_MULTI_V7 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_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_IP_MROUTE=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_BT=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_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_FSMC=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_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_NETDEVICES=y
+CONFIG_NETCONSOLE=m
+CONFIG_TUN=y
+CONFIG_SMC91X=y
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_STMPE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_STMPE=y
+# CONFIG_HWMON is not set
+CONFIG_MFD_STMPE=y
+CONFIG_REGULATOR=y
+CONFIG_MMC=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_ARMMMCI=y
+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_PL031=y
+CONFIG_DMADEVICES=y
+CONFIG_AMBA_PL08X=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=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_ACL=y
+CONFIG_ROOT_NFS=y
+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_DEBUG_INFO=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_BUGVERBOSE 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 000000000..10180cfde
--- /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 000000000..27aa87313
--- /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 000000000..56fd7ad0f
--- /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 000000000..0c8a78734
--- /dev/null
+++ b/arch/arm/configs/omap1_defconfig
@@ -0,0 +1,258 @@
+# 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_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_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_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_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_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_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_CMDLINE_PARTS=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_NETDEVICES=y
+CONFIG_TUN=y
+CONFIG_PHYLIB=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_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_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_PHY=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_MASS_STORAGE=m
+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_DEBUG_USER=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 000000000..3743ca221
--- /dev/null
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -0,0 +1,451 @@
+CONFIG_KERNEL_LZMA=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_AUDIT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_SWAP=y
+CONFIG_MEMCG_KMEM=y
+CONFIG_CGROUP_PERF=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_CFS_BANDWIDTH=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_BLK_CGROUP=y
+CONFIG_NAMESPACES=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=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_PARTITION_ADVANCED=y
+CONFIG_ARCH_MULTI_V6=y
+CONFIG_POWER_AVS_OMAP=y
+CONFIG_POWER_AVS_OMAP_CLASS3=y
+CONFIG_OMAP_RESET_CLOCKS=y
+CONFIG_OMAP_MUX_DEBUG=y
+CONFIG_ARCH_OMAP2=y
+CONFIG_ARCH_OMAP3=y
+CONFIG_ARCH_OMAP4=y
+CONFIG_SOC_OMAP5=y
+CONFIG_SOC_AM33XX=y
+CONFIG_SOC_AM43XX=y
+CONFIG_SOC_DRA7XX=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_ERRATA_411920=y
+CONFIG_ARM_ERRATA_430973=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+CONFIG_CMA=y
+CONFIG_SECCOMP=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
+CONFIG_KEXEC=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPUFREQ_DT=y
+# CONFIG_ARM_OMAP2PLUS_CPUFREQ is not set
+CONFIG_CPU_IDLE=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_NETFILTER=y
+CONFIG_PHONET=m
+CONFIG_CAN=m
+CONFIG_CAN_C_CAN=m
+CONFIG_CAN_C_CAN_PLATFORM=m
+CONFIG_BT=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_HCIUART_3WIRE=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_CFG80211=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
+CONFIG_AF_RXRPC=m
+CONFIG_RXKAD=m
+CONFIG_MAC80211=m
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_DMA_CMA=y
+CONFIG_OMAP_OCP2SCP=y
+CONFIG_CONNECTOR=m
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_OOPS=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ECC_BCH=y
+CONFIG_MTD_NAND_OMAP2=y
+CONFIG_MTD_NAND_OMAP_BCH=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_SENSORS_TSL2550=m
+CONFIG_BMP085_I2C=m
+CONFIG_SRAM=y
+CONFIG_SENSORS_LIS3_I2C=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_ATA=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_HISILICON is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+CONFIG_KS8851=y
+CONFIG_KS8851_MLL=y
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+CONFIG_SMC91X=y
+CONFIG_SMSC911X=y
+# CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_TI_DAVINCI_EMAC=y
+CONFIG_TI_CPSW=y
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_AT803X_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_SMSC95XX=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_KC2190=y
+CONFIG_USB_CDC_PHONET=m
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_USB=m
+CONFIG_LIBERTAS_SDIO=m
+CONFIG_LIBERTAS_DEBUG=y
+CONFIG_WL_TI=y
+CONFIG_WL12XX=m
+CONFIG_WL18XX=m
+CONFIG_WLCORE_SPI=m
+CONFIG_WLCORE_SDIO=m
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+CONFIG_MWIFIEX_USB=m
+CONFIG_INPUT_JOYDEV=m
+CONFIG_INPUT_EVDEV=m
+CONFIG_KEYBOARD_ATKBD=m
+CONFIG_KEYBOARD_GPIO=m
+CONFIG_KEYBOARD_MATRIX=m
+CONFIG_KEYBOARD_OMAP4=m
+CONFIG_KEYBOARD_TWL4030=m
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=m
+CONFIG_TOUCHSCREEN_EDT_FT5X06=m
+CONFIG_TOUCHSCREEN_TSC2005=m
+CONFIG_TOUCHSCREEN_TSC2007=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_TPS65218_PWRBUTTON=m
+CONFIG_INPUT_TWL4030_PWRBUTTON=m
+CONFIG_INPUT_PALMAS_PWRBUTTON=m
+CONFIG_SERIO=m
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_OMAP=y
+CONFIG_SERIAL_OMAP_CONSOLE=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_SPI=y
+CONFIG_SPI_OMAP24XX=y
+CONFIG_SPI_TI_QSPI=m
+CONFIG_HSI=m
+CONFIG_OMAP_SSI=m
+CONFIG_NOKIA_MODEM=m
+CONFIG_SSI_PROTOCOL=m
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PCF857X=m
+CONFIG_GPIO_TWL4030=y
+CONFIG_GPIO_PALMAS=y
+CONFIG_W1=m
+CONFIG_HDQ_MASTER_OMAP=m
+CONFIG_BATTERY_BQ27x00=m
+CONFIG_CHARGER_ISP1704=m
+CONFIG_CHARGER_TWL4030=m
+CONFIG_CHARGER_BQ2415X=m
+CONFIG_CHARGER_BQ24190=m
+CONFIG_CHARGER_BQ24735=m
+CONFIG_POWER_RESET=y
+CONFIG_POWER_AVS=y
+CONFIG_HWMON=m
+CONFIG_SENSORS_GPIO_FAN=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_TMP102=m
+CONFIG_THERMAL=m
+CONFIG_THERMAL_GOV_FAIR_SHARE=y
+CONFIG_THERMAL_GOV_USER_SPACE=y
+CONFIG_CPU_THERMAL=y
+CONFIG_TI_SOC_THERMAL=m
+CONFIG_TI_THERMAL=y
+CONFIG_OMAP4_THERMAL=y
+CONFIG_OMAP5_THERMAL=y
+CONFIG_DRA752_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_OMAP_WATCHDOG=m
+CONFIG_TWL4030_WATCHDOG=m
+CONFIG_MFD_PALMAS=y
+CONFIG_MFD_TPS65217=y
+CONFIG_MFD_TPS65218=y
+CONFIG_MFD_TPS65910=y
+CONFIG_TWL6040_CORE=y
+CONFIG_REGULATOR_PALMAS=y
+CONFIG_REGULATOR_PBIAS=y
+CONFIG_REGULATOR_TI_ABB=y
+CONFIG_REGULATOR_TPS62360=m
+CONFIG_REGULATOR_TPS65023=y
+CONFIG_REGULATOR_TPS6507X=y
+CONFIG_REGULATOR_TPS65217=y
+CONFIG_REGULATOR_TPS65218=y
+CONFIG_REGULATOR_TPS65910=y
+CONFIG_REGULATOR_TWL4030=y
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_OMAP2_DSS=m
+CONFIG_OMAP5_DSS_HDMI=y
+CONFIG_OMAP2_DSS_SDI=y
+CONFIG_OMAP2_DSS_DSI=y
+CONFIG_FB_OMAP2=m
+CONFIG_DISPLAY_ENCODER_TFP410=m
+CONFIG_DISPLAY_ENCODER_TPD12S015=m
+CONFIG_DISPLAY_CONNECTOR_DVI=m
+CONFIG_DISPLAY_CONNECTOR_HDMI=m
+CONFIG_DISPLAY_CONNECTOR_ANALOG_TV=m
+CONFIG_DISPLAY_PANEL_DPI=m
+CONFIG_DISPLAY_PANEL_DSI_CM=m
+CONFIG_DISPLAY_PANEL_SONY_ACX565AKM=m
+CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02=m
+CONFIG_DISPLAY_PANEL_SHARP_LS037V7DW01=m
+CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1=m
+CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1=m
+CONFIG_DISPLAY_PANEL_NEC_NL8048HL11=m
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=m
+CONFIG_BACKLIGHT_PWM=m
+CONFIG_BACKLIGHT_PANDORA=m
+CONFIG_BACKLIGHT_GPIO=m
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=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_EDMA_SOC=m
+CONFIG_SND_AM33XX_SOC_EVM=m
+CONFIG_SND_OMAP_SOC=m
+CONFIG_SND_OMAP_SOC_OMAP_TWL4030=m
+CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040=m
+CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m
+CONFIG_HID_GENERIC=m
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+CONFIG_USB=m
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_MON=m
+CONFIG_USB_XHCI_HCD=m
+CONFIG_USB_WDM=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_MUSB_HDRC=m
+CONFIG_USB_MUSB_OMAP2PLUS=m
+CONFIG_USB_MUSB_AM35X=m
+CONFIG_USB_MUSB_DSPS=m
+CONFIG_USB_DWC3=m
+CONFIG_USB_TEST=m
+CONFIG_AM335X_PHY_USB=y
+CONFIG_USB_GADGET=m
+CONFIG_USB_GADGET_DEBUG=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_DEBUG_FS=y
+CONFIG_USB_CONFIGFS=m
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_PHONET=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_LB_SS=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_UAC1=y
+CONFIG_USB_CONFIGFS_F_UAC2=y
+CONFIG_USB_CONFIGFS_F_MIDI=y
+CONFIG_USB_CONFIGFS_F_HID=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_G_NOKIA=m
+CONFIG_MMC=y
+CONFIG_SDIO_UART=y
+CONFIG_MMC_OMAP=y
+CONFIG_MMC_OMAP_HS=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_PWM=m
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_ONESHOT=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_GPIO=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_PALMAS=m
+CONFIG_RTC_DRV_TWL92330=y
+CONFIG_RTC_DRV_TWL4030=m
+CONFIG_RTC_DRV_OMAP=m
+CONFIG_DMADEVICES=y
+CONFIG_TI_EDMA=y
+CONFIG_DMA_OMAP=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXTCON=m
+CONFIG_EXTCON_USB_GPIO=m
+CONFIG_EXTCON_PALMAS=m
+CONFIG_TI_EMIF=m
+CONFIG_PWM=y
+CONFIG_PWM_TIECAP=m
+CONFIG_PWM_TIEHRPWM=m
+CONFIG_PWM_TWL=m
+CONFIG_PWM_TWL_LED=m
+CONFIG_OMAP_USB2=m
+CONFIG_TI_PIPE3=y
+CONFIG_TWL4030_USB=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
+CONFIG_FANOTIFY=y
+CONFIG_QUOTA=y
+CONFIG_QFMT_V2=y
+CONFIG_AUTOFS4_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=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_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+CONFIG_PROVE_LOCKING=y
+# CONFIG_DEBUG_BUGVERBOSE 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
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
new file mode 100644
index 000000000..855143fac
--- /dev/null
+++ b/arch/arm/configs/orion5x_defconfig
@@ -0,0 +1,165 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_LOG_BUF_SHIFT=14
+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_PARTITION_ADVANCED=y
+CONFIG_BSD_DISKLABEL=y
+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_DT=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_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+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_DSA=y
+CONFIG_NET_PKTGEN=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+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_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_NAND=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_MII=y
+CONFIG_NET_DSA_MV88E6131=y
+CONFIG_NET_DSA_MV88E6123_61_65=y
+CONFIG_MV643XX_ETH=y
+CONFIG_MARVELL_PHY=y
+# 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_LEGACY_PTY_COUNT=16
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_OF_PLATFORM=y
+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_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=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_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_ROOT_NFS=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_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_LATENCYTOP=y
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_UART_8250=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 000000000..4baa83c1c
--- /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 000000000..0a847d04d
--- /dev/null
+++ b/arch/arm/configs/pcm027_defconfig
@@ -0,0 +1,101 @@
+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_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/pleb_defconfig b/arch/arm/configs/pleb_defconfig
new file mode 100644
index 000000000..cb08cc561
--- /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/prima2_defconfig b/arch/arm/configs/prima2_defconfig
new file mode 100644
index 000000000..f610230b9
--- /dev/null
+++ b/arch/arm/configs/prima2_defconfig
@@ -0,0 +1,71 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_RELAY=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_PARTITION_ADVANCED=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_ARCH_SIRF=y
+# CONFIG_SWP_EMULATE is not set
+CONFIG_SMP=y
+CONFIG_SCHED_MC=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_KEXEC=y
+CONFIG_BINFMT_MISC=y
+CONFIG_PM=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_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_SERIAL_SIRFSOC=y
+CONFIG_SERIAL_SIRFSOC_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_SIRF=y
+CONFIG_SPI=y
+CONFIG_SPI_SIRF=y
+CONFIG_SPI_SPIDEV=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_DMADEVICES=y
+CONFIG_DMADEVICES_DEBUG=y
+CONFIG_DMADEVICES_VDEBUG=y
+CONFIG_SIRF_DMA=y
+# CONFIG_IOMMU_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_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SECTION_MISMATCH=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_INFO=y
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/pxa168_defconfig b/arch/arm/configs/pxa168_defconfig
new file mode 100644
index 000000000..74d7e0104
--- /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 000000000..917a070b4
--- /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 000000000..5f337d7ce
--- /dev/null
+++ b/arch/arm/configs/pxa3xx_defconfig
@@ -0,0 +1,132 @@
+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_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_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 000000000..3bb7771d3
--- /dev/null
+++ b/arch/arm/configs/pxa910_defconfig
@@ -0,0 +1,80 @@
+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 earlyprintk"
+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_SPI=y
+CONFIG_FB=y
+CONFIG_MMP_DISP=y
+CONFIG_MMP_DISP_CONTROLLER=y
+CONFIG_MMP_SPI=y
+CONFIG_MMP_PANEL_TPOHVGA=y
+CONFIG_MMP_FB=y
+CONFIG_LOGO=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_DEBUG_MMP_UART2=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig
new file mode 100644
index 000000000..d2f2babfd
--- /dev/null
+++ b/arch/arm/configs/qcom_defconfig
@@ -0,0 +1,172 @@
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ARCH_QCOM=y
+CONFIG_ARCH_MSM8X60=y
+CONFIG_ARCH_MSM8960=y
+CONFIG_ARCH_MSM8974=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_CLEANCACHE=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CPU_IDLE=y
+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_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_VERBOSE=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_CFG80211=y
+CONFIG_RFKILL=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_GPIO=y
+CONFIG_SLIP=y
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_USB_USBNET=y
+# CONFIG_USB_NET_AX8817X is not set
+# CONFIG_USB_NET_ZAURUS is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_QUP=y
+CONFIG_SPI=y
+CONFIG_SPI_QUP=y
+CONFIG_SPMI=y
+CONFIG_PINCTRL_APQ8064=y
+CONFIG_PINCTRL_APQ8084=y
+CONFIG_PINCTRL_IPQ8064=y
+CONFIG_PINCTRL_MSM8960=y
+CONFIG_PINCTRL_MSM8X74=y
+CONFIG_GPIOLIB=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_MSM=y
+CONFIG_THERMAL=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_FB=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_HID_BATTERY_STRENGTH=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_MON=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_ACM=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_ARMMMCI=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_RTC_CLASS=y
+CONFIG_DMADEVICES=y
+CONFIG_QCOM_BAM_DMA=y
+CONFIG_STAGING=y
+CONFIG_COMMON_CLK_QCOM=y
+CONFIG_APQ_MMCC_8084=y
+CONFIG_IPQ_LCC_806X=y
+CONFIG_MSM_GCC_8660=y
+CONFIG_MSM_LCC_8960=y
+CONFIG_MSM_MMCC_8960=y
+CONFIG_MSM_MMCC_8974=y
+CONFIG_MSM_IOMMU=y
+CONFIG_QCOM_GSBI=y
+CONFIG_PHY_QCOM_APQ8064_SATA=y
+CONFIG_PHY_QCOM_IPQ806X_SATA=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_CIFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOCKUP_DETECTOR=y
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
diff --git a/arch/arm/configs/raumfeld_defconfig b/arch/arm/configs/raumfeld_defconfig
new file mode 100644
index 000000000..3d833aea5
--- /dev/null
+++ b/arch/arm/configs/raumfeld_defconfig
@@ -0,0 +1,207 @@
+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_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 000000000..1da5d9e48
--- /dev/null
+++ b/arch/arm/configs/realview-smp_defconfig
@@ -0,0 +1,103 @@
+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_VERSATILE=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_CPU=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 000000000..d02e9d911
--- /dev/null
+++ b/arch/arm/configs/realview_defconfig
@@ -0,0 +1,102 @@
+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_VERSATILE=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_CPU=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 000000000..89631795a
--- /dev/null
+++ b/arch/arm/configs/rpc_defconfig
@@ -0,0 +1,134 @@
+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_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
+CONFIG_DEBUG_LL_UART_8250=y
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
new file mode 100644
index 000000000..f3142369f
--- /dev/null
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -0,0 +1,466 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=m
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_ARCH_S3C24XX=y
+CONFIG_S3C_BOOT_ERROR_RESET=y
+CONFIG_S3C_ADC=y
+CONFIG_S3C24XX_PWM=y
+CONFIG_CPU_S3C2412=y
+CONFIG_CPU_S3C2416=y
+CONFIG_CPU_S3C2440=y
+CONFIG_CPU_S3C2442=y
+CONFIG_CPU_S3C2443=y
+CONFIG_MACH_AML_M5900=y
+CONFIG_ARCH_BAST=y
+CONFIG_ARCH_H1940=y
+CONFIG_MACH_N30=y
+CONFIG_MACH_OTOM=y
+CONFIG_MACH_QT2410=y
+CONFIG_ARCH_SMDK2410=y
+CONFIG_MACH_TCT_HAMMER=y
+CONFIG_MACH_VR1000=y
+CONFIG_MACH_JIVE=y
+CONFIG_MACH_SMDK2412=y
+CONFIG_MACH_VSTMS=y
+CONFIG_MACH_SMDK2416=y
+CONFIG_MACH_ANUBIS=y
+CONFIG_MACH_AT2440EVB=y
+CONFIG_MACH_MINI2440=y
+CONFIG_MACH_NEXCODER_2440=y
+CONFIG_MACH_OSIRIS=y
+CONFIG_MACH_OSIRIS_DVS=m
+CONFIG_MACH_RX3715=y
+CONFIG_ARCH_S3C2440=y
+CONFIG_MACH_NEO1973_GTA02=y
+CONFIG_MACH_RX1950=y
+CONFIG_SMDK2440_CPU2442=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_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_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_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_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_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_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_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_IDE=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDETAPE=m
+CONFIG_BLK_DEV_PLATFORM=y
+CONFIG_SCSI=y
+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_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_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_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_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_USB_HID is not set
+CONFIG_USB=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_S3C24XX=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_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_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_SYSCTL_SYSCALL_CHECK=y
+CONFIG_DEBUG_USER=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 000000000..e2f9fa5bb
--- /dev/null
+++ b/arch/arm/configs/s3c6400_defconfig
@@ -0,0 +1,95 @@
+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_MINI6410=y
+CONFIG_MACH_REAL6410=y
+CONFIG_MACH_SMDK6410=y
+CONFIG_MACH_NCP=y
+CONFIG_MACH_HMT=y
+CONFIG_MACH_SMARTQ5=y
+CONFIG_MACH_SMARTQ7=y
+CONFIG_MACH_WLF_CRAGG_6410=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_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/s5pv210_defconfig b/arch/arm/configs/s5pv210_defconfig
new file mode 100644
index 000000000..fa9899022
--- /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/sama5_defconfig b/arch/arm/configs/sama5_defconfig
new file mode 100644
index 000000000..510c747c6
--- /dev/null
+++ b/arch/arm/configs/sama5_defconfig
@@ -0,0 +1,216 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_LBDAF=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_SOC_SAM_V7=y
+CONFIG_SOC_SAMA5D3=y
+CONFIG_SOC_SAMA5D4=y
+CONFIG_AEABI=y
+CONFIG_UACCESS_WITH_MEMCPY=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_CMDLINE="console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw"
+CONFIG_KEXEC=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_KERNEL_MODE_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_ADVANCED_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_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=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_6RD=y
+CONFIG_CAN=y
+CONFIG_CAN_AT91=y
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
+CONFIG_MAC80211_LEDS=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# 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_CFI=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=4
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_SSC=y
+CONFIG_EEPROM_AT24=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_MACB=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_MICREL_PHY=y
+CONFIG_LIBERTAS_THINFIRM=m
+CONFIG_LIBERTAS_THINFIRM_USB=m
+CONFIG_RTL8187=m
+CONFIG_RT2X00=m
+CONFIG_RT2500USB=m
+CONFIG_RT73USB=m
+CONFIG_RT2800USB=m
+CONFIG_RT2800USB_RT53XX=y
+CONFIG_RT2800USB_RT55XX=y
+CONFIG_RT2800USB_UNKNOWN=y
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+CONFIG_MWIFIEX_USB=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_QT1070=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+# CONFIG_SERIO is not set
+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_AT91=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+CONFIG_SPI_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+# CONFIG_HWMON is not set
+CONFIG_SSB=m
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_ACT8865=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_OV2640=y
+CONFIG_VIDEO_ATMEL_ISI=y
+CONFIG_FB=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_FRAMEBUFFER_CONSOLE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_ATMEL_SOC=y
+CONFIG_SND_ATMEL_SOC_WM8904=y
+# CONFIG_HID_GENERIC is not set
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_FTDI_SIO=y
+CONFIG_USB_SERIAL_PL2303=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ATMEL_USBA=y
+CONFIG_USB_G_SERIAL=y
+CONFIG_MMC=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_ATMELMCI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91RM9200=y
+CONFIG_DMADEVICES=y
+CONFIG_AT_XDMAC=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_IIO=y
+CONFIG_AT91_ADC=y
+CONFIG_PWM=y
+CONFIG_PWM_ATMEL=y
+CONFIG_PWM_ATMEL_TCB=y
+CONFIG_EXT4_FS=y
+CONFIG_FANOTIFY=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=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_NLS_UTF8=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
+CONFIG_CRYPTO_DEV_ATMEL_AES=y
+CONFIG_CRYPTO_DEV_ATMEL_TDES=y
+CONFIG_CRYPTO_DEV_ATMEL_SHA=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC_ITU_T=m
diff --git a/arch/arm/configs/shannon_defconfig b/arch/arm/configs/shannon_defconfig
new file mode 100644
index 000000000..b0b96942f
--- /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/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
new file mode 100644
index 000000000..b58618e2d
--- /dev/null
+++ b/arch/arm/configs/shmobile_defconfig
@@ -0,0 +1,199 @@
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+CONFIG_SLAB=y
+CONFIG_ARCH_SHMOBILE_MULTI=y
+CONFIG_ARCH_EMEV2=y
+CONFIG_ARCH_R7S72100=y
+CONFIG_ARCH_R8A73A4=y
+CONFIG_ARCH_R8A7740=y
+CONFIG_ARCH_R8A7778=y
+CONFIG_ARCH_R8A7779=y
+CONFIG_ARCH_R8A7790=y
+CONFIG_ARCH_R8A7791=y
+CONFIG_ARCH_R8A7794=y
+CONFIG_ARCH_SH73A0=y
+CONFIG_MACH_MARZEN=y
+CONFIG_CPU_BPREDICT_DISABLE=y
+CONFIG_PL310_ERRATA_588369=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_PCI=y
+CONFIG_PCI_RCAR_GEN2=y
+CONFIG_PCI_RCAR_GEN2_PCIE=y
+CONFIG_SMP=y
+CONFIG_SCHED_MC=y
+CONFIG_HAVE_ARM_ARCH_TIMER=y
+CONFIG_NR_CPUS=8
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_KEXEC=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPUFREQ_DT=y
+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_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_SIMPLE_PM_BUS=y
+CONFIG_MTD=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_EEPROM_AT24=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_SATA_RCAR=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+CONFIG_SH_ETH=y
+# CONFIG_NET_VENDOR_SEEQ is not set
+CONFIG_SMSC911X=y
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_SMSC_PHY=y
+CONFIG_MICREL_PHY=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ST1232=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_ADXL34X=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EM=y
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=20
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_I2C_RIIC=y
+CONFIG_I2C_SH_MOBILE=y
+CONFIG_I2C_RCAR=y
+CONFIG_SPI=y
+CONFIG_SPI_RSPI=y
+CONFIG_SPI_SH_MSIOF=y
+CONFIG_SPI_SH_HSPI=y
+CONFIG_GPIO_EM=y
+CONFIG_GPIO_RCAR=y
+CONFIG_GPIO_PCF857X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_RMOBILE=y
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_CPU_THERMAL=y
+CONFIG_RCAR_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_DA9063_WATCHDOG=y
+CONFIG_MFD_AS3711=y
+CONFIG_MFD_DA9063=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_AS3711=y
+CONFIG_REGULATOR_DA9210=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_MAX8973=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_PLATFORM=y
+CONFIG_VIDEO_RCAR_VIN=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_RENESAS_VSP1=y
+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
+CONFIG_VIDEO_ADV7180=y
+CONFIG_VIDEO_ML86V7667=y
+CONFIG_DRM=y
+CONFIG_DRM_RCAR_DU=y
+CONFIG_FB_SH_MOBILE_LCDC=y
+CONFIG_FB_SH_MOBILE_MERAM=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_BACKLIGHT_AS3711=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_SH4_FSI=y
+CONFIG_SND_SOC_RCAR=y
+CONFIG_SND_SOC_AK4642=y
+CONFIG_SND_SOC_WM8978=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_R8A66597_HCD=y
+CONFIG_USB_RENESAS_USBHS=y
+CONFIG_USB_RCAR_PHY=y
+CONFIG_USB_RCAR_GEN2_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_RENESAS_USBHS_UDC=y
+CONFIG_USB_ETH=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHI=y
+CONFIG_MMC_SH_MMCIF=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_RS5C372=y
+CONFIG_RTC_DRV_S35390A=y
+CONFIG_RTC_DRV_RX8581=y
+CONFIG_DMADEVICES=y
+CONFIG_SH_DMAE=y
+CONFIG_RCAR_DMAC=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_IIO=y
+CONFIG_AK8975=y
+CONFIG_PWM=y
+CONFIG_PWM_RENESAS_TPU=y
+# CONFIG_DNOTIFY 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_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_ROOT_NFS=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_ARM_UNWIND is not set
diff --git a/arch/arm/configs/simpad_defconfig b/arch/arm/configs/simpad_defconfig
new file mode 100644
index 000000000..d3358155b
--- /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/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig
new file mode 100644
index 000000000..a2956c311
--- /dev/null
+++ b/arch/arm/configs/socfpga_defconfig
@@ -0,0 +1,110 @@
+CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CGROUPS=y
+CONFIG_CPUSETS=y
+CONFIG_NAMESPACES=y
+CONFIG_EMBEDDED=y
+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_SOCFPGA=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=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_IPV6=y
+CONFIG_NETWORK_PHY_TIMESTAMPING=y
+CONFIG_VLAN_8021Q=y
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_CAN=y
+CONFIG_CAN_C_CAN=y
+CONFIG_CAN_C_CAN_PLATFORM=y
+CONFIG_CAN_DEBUG_DEVICES=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_SRAM=y
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_STMMAC_ETH=y
+CONFIG_DWMAC_SOCFPGA=y
+CONFIG_MICREL_PHY=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_AMBAKMI=y
+CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_DW=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_DWAPB=y
+CONFIG_PMBUS=y
+CONFIG_SENSORS_LTC2978=y
+CONFIG_SENSORS_LTC2978_REGULATOR=y
+CONFIG_WATCHDOG=y
+CONFIG_DW_WATCHDOG=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_USB=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_DWC2_HOST=y
+CONFIG_MMC=y
+CONFIG_MMC_DW=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=y
+CONFIG_NTFS_RW=y
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_ENABLE_DEFAULT_TRACERS=y
+CONFIG_DEBUG_USER=y
+CONFIG_XZ_DEC=y
diff --git a/arch/arm/configs/spear13xx_defconfig b/arch/arm/configs/spear13xx_defconfig
new file mode 100644
index 000000000..d271b263f
--- /dev/null
+++ b/arch/arm/configs/spear13xx_defconfig
@@ -0,0 +1,110 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_PLAT_SPEAR=y
+CONFIG_ARCH_SPEAR13XX=y
+CONFIG_MACH_SPEAR1310=y
+CONFIG_MACH_SPEAR1340=y
+# CONFIG_SWP_EMULATE is not set
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCIE_SPEAR13XX=y
+CONFIG_SMP=y
+# CONFIG_SMP_ON_UP is not set
+# CONFIG_ARM_CPU_TOPOLOGY is not set
+CONFIG_AEABI=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_VFP=y
+CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_FSMC=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+# CONFIG_SATA_PMP is not set
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_PATA_ARASAN_CF=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+CONFIG_STMMAC_ETH=y
+# CONFIG_WLAN is not set
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_SPEAR=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+CONFIG_I2C=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PL061=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SPEAR=y
+CONFIG_RTC_CLASS=y
+CONFIG_DMADEVICES=y
+CONFIG_DW_DMAC=y
+CONFIG_DMATEST=m
+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_FUSE_FS=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=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_INFO=y
diff --git a/arch/arm/configs/spear3xx_defconfig b/arch/arm/configs/spear3xx_defconfig
new file mode 100644
index 000000000..7ff23a077
--- /dev/null
+++ b/arch/arm/configs/spear3xx_defconfig
@@ -0,0 +1,89 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_PLAT_SPEAR=y
+CONFIG_ARCH_SPEAR3XX=y
+CONFIG_MACH_SPEAR300=y
+CONFIG_MACH_SPEAR310=y
+CONFIG_MACH_SPEAR320=y
+CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_FSMC=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+CONFIG_STMMAC_ETH=y
+# CONFIG_WLAN is not set
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_SPEAR=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+CONFIG_I2C=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PL061=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_ARM_SP805_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SPEAR=y
+CONFIG_RTC_CLASS=y
+CONFIG_DMADEVICES=y
+CONFIG_AMBA_PL08X=y
+CONFIG_DMATEST=m
+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_JFFS2_FS=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_INFO=y
diff --git a/arch/arm/configs/spear6xx_defconfig b/arch/arm/configs/spear6xx_defconfig
new file mode 100644
index 000000000..7822980d7
--- /dev/null
+++ b/arch/arm/configs/spear6xx_defconfig
@@ -0,0 +1,78 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_PLAT_SPEAR=y
+CONFIG_ARCH_SPEAR6XX=y
+CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_FSMC=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+CONFIG_STMMAC_ETH=y
+# CONFIG_WLAN is not set
+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_LEGACY_PTYS is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+CONFIG_I2C=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PL061=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_ARM_SP805_WATCHDOG=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_RTC_CLASS=y
+CONFIG_DMADEVICES=y
+CONFIG_AMBA_PL08X=y
+CONFIG_DMATEST=m
+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_JFFS2_FS=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_INFO=y
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
new file mode 100644
index 000000000..a1ede1966
--- /dev/null
+++ b/arch/arm/configs/spitz_defconfig
@@ -0,0 +1,273 @@
+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_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_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_MASS_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/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig
new file mode 100644
index 000000000..8ecba00dc
--- /dev/null
+++ b/arch/arm/configs/sunxi_defconfig
@@ -0,0 +1,121 @@
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_PERF_EVENTS=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=8
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_VFP=y
+CONFIG_NEON=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_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_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_EEPROM_SUNXI_SID=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_AHCI_SUNXI=y
+CONFIG_NETDEVICES=y
+CONFIG_SUN4I_EMAC=y
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+CONFIG_STMMAC_ETH=y
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_AXP20X_PEK=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_SUN4I=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_RUNTIME_UARTS=8
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MV64XXX=y
+CONFIG_SPI=y
+CONFIG_SPI_SUN4I=y
+CONFIG_SPI_SUN6I=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_SUN6I=y
+CONFIG_THERMAL=y
+CONFIG_CPU_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_SUNXI_WATCHDOG=y
+CONFIG_MFD_AXP20X=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_AXP20X=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_MMC=y
+CONFIG_MMC_SUNXI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_INTF_SYSFS is not set
+# CONFIG_RTC_INTF_PROC is not set
+CONFIG_RTC_DRV_SUN6I=y
+CONFIG_RTC_DRV_SUNXI=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PHY_SUN4I_USB=y
+CONFIG_PHY_SUN9I_USB=y
+CONFIG_EXT4_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
diff --git a/arch/arm/configs/tct_hammer_defconfig b/arch/arm/configs/tct_hammer_defconfig
new file mode 100644
index 000000000..7209a2cae
--- /dev/null
+++ b/arch/arm/configs/tct_hammer_defconfig
@@ -0,0 +1,69 @@
+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_BUGVERBOSE 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_S3C24XX=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_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 000000000..d199eb249
--- /dev/null
+++ b/arch/arm/configs/tegra_defconfig
@@ -0,0 +1,294 @@
+CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_ELF_CORE is not set
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_TEGRA=y
+CONFIG_ARCH_TEGRA_2x_SOC=y
+CONFIG_ARCH_TEGRA_3x_SOC=y
+CONFIG_ARCH_TEGRA_114_SOC=y
+CONFIG_ARCH_TEGRA_124_SOC=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_TEGRA=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_CMA=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_KEXEC=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=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_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_CAN=y
+CONFIG_CAN_MCP251X=y
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIBTUSB=m
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_RFKILL_GPIO=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=64
+CONFIG_MTD=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_AD525X_DPOT=y
+CONFIG_AD525X_DPOT_I2C=y
+CONFIG_ICS932S401=y
+CONFIG_APDS9802ALS=y
+CONFIG_ISL29003=y
+CONFIG_EEPROM_AT24=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
+CONFIG_AHCI_TEGRA=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_IGB=y
+CONFIG_R8169=y
+CONFIG_USB_PEGASUS=y
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_SMSC75XX=y
+CONFIG_USB_NET_SMSC95XX=y
+CONFIG_BRCMFMAC=m
+CONFIG_RT2X00=y
+CONFIG_RT2800USB=m
+CONFIG_INPUT_JOYDEV=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_TEGRA=y
+CONFIG_KEYBOARD_CROS_EC=y
+CONFIG_MOUSE_PS2_ELANTECH=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_STMPE=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_MPU3050=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_TEGRA=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_MUX_PINCTRL=y
+CONFIG_I2C_TEGRA=y
+CONFIG_SPI=y
+CONFIG_SPI_TEGRA114=y
+CONFIG_SPI_TEGRA20_SFLASH=y
+CONFIG_SPI_TEGRA20_SLINK=y
+CONFIG_PINCTRL_AS3722=y
+CONFIG_PINCTRL_PALMAS=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_GPIO_PALMAS=y
+CONFIG_GPIO_TPS6586X=y
+CONFIG_GPIO_TPS65910=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_SBS=y
+CONFIG_CHARGER_TPS65090=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_AS3722=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_SENSORS_LM90=y
+CONFIG_SENSORS_LM95245=y
+CONFIG_MFD_AS3722=y
+CONFIG_MFD_CROS_EC=y
+CONFIG_MFD_CROS_EC_SPI=y
+CONFIG_MFD_MAX8907=y
+CONFIG_MFD_STMPE=y
+CONFIG_MFD_PALMAS=y
+CONFIG_MFD_TPS65090=y
+CONFIG_MFD_TPS6586X=y
+CONFIG_MFD_TPS65910=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_AS3722=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_MAX8907=y
+CONFIG_REGULATOR_PALMAS=y
+CONFIG_REGULATOR_TPS51632=y
+CONFIG_REGULATOR_TPS62360=y
+CONFIG_REGULATOR_TPS65090=y
+CONFIG_REGULATOR_TPS6586X=y
+CONFIG_REGULATOR_TPS65910=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_USB_GSPCA=y
+CONFIG_DRM=y
+CONFIG_DRM_TEGRA=y
+CONFIG_DRM_PANEL_SIMPLE=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_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_SUPPORT_OLD_API 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_TEGRA=y
+CONFIG_SND_SOC_TEGRA_RT5640=y
+CONFIG_SND_SOC_TEGRA_WM8753=y
+CONFIG_SND_SOC_TEGRA_WM8903=y
+CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
+CONFIG_SND_SOC_TEGRA_ALC5632=y
+CONFIG_SND_SOC_TEGRA_MAX98090=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_TEGRA=y
+CONFIG_USB_ACM=y
+CONFIG_USB_WDM=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK_MINORS=16
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_TEGRA=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_TRANSIENT=y
+CONFIG_LEDS_TRIGGER_CAMERA=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AS3722=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_MAX8907=y
+CONFIG_RTC_DRV_PALMAS=y
+CONFIG_RTC_DRV_TPS6586X=y
+CONFIG_RTC_DRV_TPS65910=y
+CONFIG_RTC_DRV_EM3027=y
+CONFIG_RTC_DRV_TEGRA=y
+CONFIG_DMADEVICES=y
+CONFIG_TEGRA20_APB_DMA=y
+CONFIG_STAGING=y
+CONFIG_SENSORS_ISL29018=y
+CONFIG_SENSORS_ISL29028=y
+CONFIG_MFD_NVEC=y
+CONFIG_KEYBOARD_NVEC=y
+CONFIG_SERIO_NVEC_PS2=y
+CONFIG_NVEC_POWER=y
+CONFIG_NVEC_PAZ00=y
+CONFIG_TEGRA_IOMMU_GART=y
+CONFIG_TEGRA_IOMMU_SMMU=y
+CONFIG_MEMORY=y
+CONFIG_IIO=y
+CONFIG_AK8975=y
+CONFIG_PWM=y
+CONFIG_PWM_TEGRA=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_EXT4_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_DEBUG_VM=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_SG=y
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CRYPTO_TWOFISH=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig
new file mode 100644
index 000000000..932ee4e4a
--- /dev/null
+++ b/arch/arm/configs/trizeps4_defconfig
@@ -0,0 +1,225 @@
+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_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 000000000..aaa95ab60
--- /dev/null
+++ b/arch/arm/configs/u300_defconfig
@@ -0,0 +1,71 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=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_PARTITION_ADVANCED=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_ARCH_U300=y
+CONFIG_MACH_U300_SPIDUMMY=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_SUSPEND is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_FSMC=y
+# 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_LEGACY_PTY_COUNT=16
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_FB=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+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_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_PREEMPT is not set
diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig
new file mode 100644
index 000000000..6a1c9898f
--- /dev/null
+++ b/arch/arm/configs/u8500_defconfig
@@ -0,0 +1,140 @@
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=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_PARTITION_ADVANCED=y
+CONFIG_ARCH_U8500=y
+CONFIG_MACH_HREFV60=y
+CONFIG_MACH_SNOWBALL=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA2,115200n8"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_IDLE=y
+CONFIG_ARM_U8500_CPUIDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=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_NETFILTER=y
+CONFIG_PHONET=y
+CONFIG_CFG80211=y
+CONFIG_CFG80211_DEBUGFS=y
+CONFIG_MAC80211=y
+CONFIG_MAC80211_LEDS=y
+CONFIG_CAIF=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_SENSORS_BH1780=y
+CONFIG_NETDEVICES=y
+CONFIG_SMSC911X=y
+CONFIG_SMSC_PHY=y
+CONFIG_CW1200=y
+CONFIG_CW1200_WLAN_SDIO=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_LEGACY_PTYS is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_GPIO_STMPE=y
+CONFIG_GPIO_TC3589X=y
+CONFIG_THERMAL=y
+CONFIG_CPU_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_MFD_STMPE=y
+CONFIG_MFD_TC3589X=y
+CONFIG_REGULATOR_AB8500=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_UX500=y
+CONFIG_SND_SOC_UX500_MACH_MOP500=y
+CONFIG_USB=y
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_UX500=y
+CONFIG_AB8500_USB=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_LM3530=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_LP5521=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=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_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
+CONFIG_HSEM_U8500=y
+CONFIG_IIO=y
+CONFIG_IIO_ST_ACCEL_3AXIS=y
+CONFIG_IIO_ST_GYRO_3AXIS=y
+CONFIG_IIO_ST_MAGN_3AXIS=y
+CONFIG_IIO_ST_PRESS=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_EXT4_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_DEV_UX500=y
+CONFIG_CRYPTO_DEV_UX500_CRYP=y
+CONFIG_CRYPTO_DEV_UX500_HASH=y
+CONFIG_CRYPTO_DEV_UX500_DEBUG=y
diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig
new file mode 100644
index 000000000..ea49d3756
--- /dev/null
+++ b/arch/arm/configs/versatile_defconfig
@@ -0,0 +1,87 @@
+# 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_PARTITION_ADVANCED=y
+CONFIG_ARCH_VERSATILE=y
+CONFIG_MACH_VERSATILE_AB=y
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=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_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_CMDLINE_PARTS=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_SMC91X=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_AMBAKMI=y
+CONFIG_LEGACY_PTY_COUNT=16
+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_I2C=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_PL061=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_FRAMEBUFFER_CONSOLE=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_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_VERSATILE=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_CPU=y
+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_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=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_LL=y
+CONFIG_DEBUG_LL_UART_PL01X=y
+CONFIG_FONTS=y
+CONFIG_FONT_ACORN_8x8=y
diff --git a/arch/arm/configs/vexpress_defconfig b/arch/arm/configs/vexpress_defconfig
new file mode 100644
index 000000000..37fe607a4
--- /dev/null
+++ b/arch/arm/configs/vexpress_defconfig
@@ -0,0 +1,161 @@
+# 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_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+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_ARCH_VEXPRESS_DCSCB=y
+CONFIG_ARCH_VEXPRESS_TC2_PM=y
+# CONFIG_SWP_EMULATE is not set
+CONFIG_SMP=y
+CONFIG_HAVE_ARM_ARCH_TIMER=y
+CONFIG_MCPM=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_NR_CPUS=8
+CONFIG_ARM_PSCI=y
+CONFIG_AEABI=y
+CONFIG_CMA=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyAMA0"
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
+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_NET_9P=y
+CONFIG_NET_9P_VIRTIO=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_PLATRAM=y
+CONFIG_MTD_UBI=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_VIRTIO_BLK=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_VIRTIO=y
+CONFIG_ATA=y
+# CONFIG_SATA_PMP is not set
+CONFIG_NETDEVICES=y
+CONFIG_VIRTIO_NET=y
+CONFIG_SMC91X=y
+CONFIG_SMSC911X=y
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_AMBAKMI=y
+CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_VIRTIO=y
+CONFIG_I2C=y
+CONFIG_I2C_VERSATILE=y
+CONFIG_SENSORS_VEXPRESS=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_VEXPRESS=y
+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_MON=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_ISP1760=y
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_VIRTIO_BALLOON=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=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_EXT4_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_UBIFS_FS=y
+CONFIG_CRAMFS=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_9P_FS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_SCHED_DEBUG 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/viper_defconfig b/arch/arm/configs/viper_defconfig
new file mode 100644
index 000000000..0d717a5ef
--- /dev/null
+++ b/arch/arm/configs/viper_defconfig
@@ -0,0 +1,173 @@
+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_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_MASS_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/vt8500_v6_v7_defconfig b/arch/arm/configs/vt8500_v6_v7_defconfig
new file mode 100644
index 000000000..1bfaa7bfc
--- /dev/null
+++ b/arch/arm/configs/vt8500_v6_v7_defconfig
@@ -0,0 +1,89 @@
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_ARCH_MULTI_V6=y
+CONFIG_ARCH_WM8750=y
+CONFIG_ARCH_WM8850=y
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_775420=y
+CONFIG_HAVE_ARM_ARCH_TIMER=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_EEPROM_93CX6=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_VIA_VELOCITY=y
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PHYLIB=y
+CONFIG_INPUT_MATRIXKMAP=y
+CONFIG_SERIAL_VT8500=y
+CONFIG_SERIAL_VT8500_CONSOLE=y
+CONFIG_I2C=y
+CONFIG_I2C_WMT=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_PINCTRL_WM8750=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_MFD_SYSCON=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_UHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_GPIO_VBUS=y
+CONFIG_USB_ULPI=y
+CONFIG_MMC=y
+CONFIG_MMC_DEBUG=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_VT8500=y
+CONFIG_DMADEVICES=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PWM=y
+CONFIG_PWM_VT8500=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_GENERIC_PHY=y
+CONFIG_EXT4_FS=y
+CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOCKUP_DETECTOR=y
diff --git a/arch/arm/configs/xcep_defconfig b/arch/arm/configs/xcep_defconfig
new file mode 100644
index 000000000..721832ffe
--- /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 000000000..cd11da8b5
--- /dev/null
+++ b/arch/arm/configs/zeus_defconfig
@@ -0,0 +1,188 @@
+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_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_MASS_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/crypto/.gitignore b/arch/arm/crypto/.gitignore
new file mode 100644
index 000000000..6231d36b3
--- /dev/null
+++ b/arch/arm/crypto/.gitignore
@@ -0,0 +1 @@
+aesbs-core.S
diff --git a/arch/arm/crypto/Kconfig b/arch/arm/crypto/Kconfig
new file mode 100644
index 000000000..8da2207b0
--- /dev/null
+++ b/arch/arm/crypto/Kconfig
@@ -0,0 +1,130 @@
+
+menuconfig ARM_CRYPTO
+ bool "ARM Accelerated Cryptographic Algorithms"
+ depends on ARM
+ help
+ Say Y here to choose from a selection of cryptographic algorithms
+ implemented using ARM specific CPU features or instructions.
+
+if ARM_CRYPTO
+
+config CRYPTO_SHA1_ARM
+ tristate "SHA1 digest algorithm (ARM-asm)"
+ select CRYPTO_SHA1
+ select CRYPTO_HASH
+ help
+ SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented
+ using optimized ARM assembler.
+
+config CRYPTO_SHA1_ARM_NEON
+ tristate "SHA1 digest algorithm (ARM NEON)"
+ depends on KERNEL_MODE_NEON
+ select CRYPTO_SHA1_ARM
+ select CRYPTO_SHA1
+ select CRYPTO_HASH
+ help
+ SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented
+ using optimized ARM NEON assembly, when NEON instructions are
+ available.
+
+config CRYPTO_SHA1_ARM_CE
+ tristate "SHA1 digest algorithm (ARM v8 Crypto Extensions)"
+ depends on KERNEL_MODE_NEON
+ select CRYPTO_SHA1_ARM
+ select CRYPTO_HASH
+ help
+ SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented
+ using special ARMv8 Crypto Extensions.
+
+config CRYPTO_SHA2_ARM_CE
+ tristate "SHA-224/256 digest algorithm (ARM v8 Crypto Extensions)"
+ depends on KERNEL_MODE_NEON
+ select CRYPTO_SHA256_ARM
+ select CRYPTO_HASH
+ help
+ SHA-256 secure hash standard (DFIPS 180-2) implemented
+ using special ARMv8 Crypto Extensions.
+
+config CRYPTO_SHA256_ARM
+ tristate "SHA-224/256 digest algorithm (ARM-asm and NEON)"
+ select CRYPTO_HASH
+ depends on !CPU_V7M
+ help
+ SHA-256 secure hash standard (DFIPS 180-2) implemented
+ using optimized ARM assembler and NEON, when available.
+
+config CRYPTO_SHA512_ARM_NEON
+ tristate "SHA384 and SHA512 digest algorithm (ARM NEON)"
+ depends on KERNEL_MODE_NEON
+ select CRYPTO_SHA512
+ select CRYPTO_HASH
+ help
+ SHA-512 secure hash standard (DFIPS 180-2) implemented
+ using ARM NEON instructions, when available.
+
+ This version of SHA implements a 512 bit hash with 256 bits of
+ security against collision attacks.
+
+ This code also includes SHA-384, a 384 bit hash with 192 bits
+ of security against collision attacks.
+
+config CRYPTO_AES_ARM
+ tristate "AES cipher algorithms (ARM-asm)"
+ depends on ARM
+ select CRYPTO_ALGAPI
+ select CRYPTO_AES
+ help
+ Use optimized AES assembler routines for ARM platforms.
+
+ AES cipher algorithms (FIPS-197). AES uses the Rijndael
+ algorithm.
+
+ Rijndael appears to be consistently a very good performer in
+ both hardware and software across a wide range of computing
+ environments regardless of its use in feedback or non-feedback
+ modes. Its key setup time is excellent, and its key agility is
+ good. Rijndael's very low memory requirements make it very well
+ suited for restricted-space environments, in which it also
+ demonstrates excellent performance. Rijndael's operations are
+ among the easiest to defend against power and timing attacks.
+
+ The AES specifies three key sizes: 128, 192 and 256 bits
+
+ See <http://csrc.nist.gov/encryption/aes/> for more information.
+
+config CRYPTO_AES_ARM_BS
+ tristate "Bit sliced AES using NEON instructions"
+ depends on KERNEL_MODE_NEON
+ select CRYPTO_ALGAPI
+ select CRYPTO_AES_ARM
+ select CRYPTO_ABLK_HELPER
+ help
+ Use a faster and more secure NEON based implementation of AES in CBC,
+ CTR and XTS modes
+
+ Bit sliced AES gives around 45% speedup on Cortex-A15 for CTR mode
+ and for XTS mode encryption, CBC and XTS mode decryption speedup is
+ around 25%. (CBC encryption speed is not affected by this driver.)
+ This implementation does not rely on any lookup tables so it is
+ believed to be invulnerable to cache timing attacks.
+
+config CRYPTO_AES_ARM_CE
+ tristate "Accelerated AES using ARMv8 Crypto Extensions"
+ depends on KERNEL_MODE_NEON
+ select CRYPTO_ALGAPI
+ select CRYPTO_ABLK_HELPER
+ help
+ Use an implementation of AES in CBC, CTR and XTS modes that uses
+ ARMv8 Crypto Extensions
+
+config CRYPTO_GHASH_ARM_CE
+ tristate "PMULL-accelerated GHASH using ARMv8 Crypto Extensions"
+ depends on KERNEL_MODE_NEON
+ select CRYPTO_HASH
+ select CRYPTO_CRYPTD
+ help
+ Use an implementation of GHASH (used by the GCM AEAD chaining mode)
+ that uses the 64x64 to 128 bit polynomial multiplication (vmull.p64)
+ that is part of the ARMv8 Crypto Extensions
+
+endif
diff --git a/arch/arm/crypto/Makefile b/arch/arm/crypto/Makefile
new file mode 100644
index 000000000..6ea828241
--- /dev/null
+++ b/arch/arm/crypto/Makefile
@@ -0,0 +1,48 @@
+#
+# Arch-specific CryptoAPI modules.
+#
+
+obj-$(CONFIG_CRYPTO_AES_ARM) += aes-arm.o
+obj-$(CONFIG_CRYPTO_AES_ARM_BS) += aes-arm-bs.o
+obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o
+obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o
+obj-$(CONFIG_CRYPTO_SHA256_ARM) += sha256-arm.o
+obj-$(CONFIG_CRYPTO_SHA512_ARM_NEON) += sha512-arm-neon.o
+
+ce-obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o
+ce-obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o
+ce-obj-$(CONFIG_CRYPTO_SHA2_ARM_CE) += sha2-arm-ce.o
+ce-obj-$(CONFIG_CRYPTO_GHASH_ARM_CE) += ghash-arm-ce.o
+
+ifneq ($(ce-obj-y)$(ce-obj-m),)
+ifeq ($(call as-instr,.fpu crypto-neon-fp-armv8,y,n),y)
+obj-y += $(ce-obj-y)
+obj-m += $(ce-obj-m)
+else
+$(warning These ARMv8 Crypto Extensions modules need binutils 2.23 or higher)
+$(warning $(ce-obj-y) $(ce-obj-m))
+endif
+endif
+
+aes-arm-y := aes-armv4.o aes_glue.o
+aes-arm-bs-y := aesbs-core.o aesbs-glue.o
+sha1-arm-y := sha1-armv4-large.o sha1_glue.o
+sha1-arm-neon-y := sha1-armv7-neon.o sha1_neon_glue.o
+sha256-arm-neon-$(CONFIG_KERNEL_MODE_NEON) := sha256_neon_glue.o
+sha256-arm-y := sha256-core.o sha256_glue.o $(sha256-arm-neon-y)
+sha512-arm-neon-y := sha512-armv7-neon.o sha512_neon_glue.o
+sha1-arm-ce-y := sha1-ce-core.o sha1-ce-glue.o
+sha2-arm-ce-y := sha2-ce-core.o sha2-ce-glue.o
+aes-arm-ce-y := aes-ce-core.o aes-ce-glue.o
+ghash-arm-ce-y := ghash-ce-core.o ghash-ce-glue.o
+
+quiet_cmd_perl = PERL $@
+ cmd_perl = $(PERL) $(<) > $(@)
+
+$(src)/aesbs-core.S_shipped: $(src)/bsaes-armv7.pl
+ $(call cmd,perl)
+
+$(src)/sha256-core.S_shipped: $(src)/sha256-armv4.pl
+ $(call cmd,perl)
+
+.PRECIOUS: $(obj)/aesbs-core.S $(obj)/sha256-core.S
diff --git a/arch/arm/crypto/aes-armv4.S b/arch/arm/crypto/aes-armv4.S
new file mode 100644
index 000000000..ebb9761fb
--- /dev/null
+++ b/arch/arm/crypto/aes-armv4.S
@@ -0,0 +1,1089 @@
+#define __ARM_ARCH__ __LINUX_ARM_ARCH__
+@ ====================================================================
+@ Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+@ project. The module is, however, dual licensed under OpenSSL and
+@ CRYPTOGAMS licenses depending on where you obtain it. For further
+@ details see http://www.openssl.org/~appro/cryptogams/.
+@ ====================================================================
+
+@ AES for ARMv4
+
+@ January 2007.
+@
+@ Code uses single 1K S-box and is >2 times faster than code generated
+@ by gcc-3.4.1. This is thanks to unique feature of ARMv4 ISA, which
+@ allows to merge logical or arithmetic operation with shift or rotate
+@ in one instruction and emit combined result every cycle. The module
+@ is endian-neutral. The performance is ~42 cycles/byte for 128-bit
+@ key [on single-issue Xscale PXA250 core].
+
+@ May 2007.
+@
+@ AES_set_[en|de]crypt_key is added.
+
+@ July 2010.
+@
+@ Rescheduling for dual-issue pipeline resulted in 12% improvement on
+@ Cortex A8 core and ~25 cycles per byte processed with 128-bit key.
+
+@ February 2011.
+@
+@ Profiler-assisted and platform-specific optimization resulted in 16%
+@ improvement on Cortex A8 core and ~21.5 cycles per byte.
+
+@ A little glue here to select the correct code below for the ARM CPU
+@ that is being targetted.
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+.text
+
+.type AES_Te,%object
+.align 5
+AES_Te:
+.word 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d
+.word 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554
+.word 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d
+.word 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a
+.word 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87
+.word 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b
+.word 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea
+.word 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b
+.word 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a
+.word 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f
+.word 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108
+.word 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f
+.word 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e
+.word 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5
+.word 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d
+.word 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f
+.word 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e
+.word 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb
+.word 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce
+.word 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497
+.word 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c
+.word 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed
+.word 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b
+.word 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a
+.word 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16
+.word 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594
+.word 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81
+.word 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3
+.word 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a
+.word 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504
+.word 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163
+.word 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d
+.word 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f
+.word 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739
+.word 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47
+.word 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395
+.word 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f
+.word 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883
+.word 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c
+.word 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76
+.word 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e
+.word 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4
+.word 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6
+.word 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b
+.word 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7
+.word 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0
+.word 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25
+.word 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818
+.word 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72
+.word 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651
+.word 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21
+.word 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85
+.word 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa
+.word 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12
+.word 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0
+.word 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9
+.word 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133
+.word 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7
+.word 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920
+.word 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a
+.word 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17
+.word 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8
+.word 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11
+.word 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
+@ Te4[256]
+.byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
+.byte 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+.byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+.byte 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+.byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+.byte 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+.byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+.byte 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+.byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+.byte 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+.byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+.byte 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+.byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+.byte 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+.byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+.byte 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+.byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+.byte 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+.byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+.byte 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+.byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+.byte 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+.byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+.byte 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+.byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+.byte 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+.byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+.byte 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+.byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+.byte 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+.byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+.byte 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+@ rcon[]
+.word 0x01000000, 0x02000000, 0x04000000, 0x08000000
+.word 0x10000000, 0x20000000, 0x40000000, 0x80000000
+.word 0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
+.size AES_Te,.-AES_Te
+
+@ void AES_encrypt(const unsigned char *in, unsigned char *out,
+@ const AES_KEY *key) {
+.align 5
+ENTRY(AES_encrypt)
+ adr r3,AES_encrypt
+ stmdb sp!,{r1,r4-r12,lr}
+ mov r12,r0 @ inp
+ mov r11,r2
+ sub r10,r3,#AES_encrypt-AES_Te @ Te
+#if __ARM_ARCH__<7
+ ldrb r0,[r12,#3] @ load input data in endian-neutral
+ ldrb r4,[r12,#2] @ manner...
+ ldrb r5,[r12,#1]
+ ldrb r6,[r12,#0]
+ orr r0,r0,r4,lsl#8
+ ldrb r1,[r12,#7]
+ orr r0,r0,r5,lsl#16
+ ldrb r4,[r12,#6]
+ orr r0,r0,r6,lsl#24
+ ldrb r5,[r12,#5]
+ ldrb r6,[r12,#4]
+ orr r1,r1,r4,lsl#8
+ ldrb r2,[r12,#11]
+ orr r1,r1,r5,lsl#16
+ ldrb r4,[r12,#10]
+ orr r1,r1,r6,lsl#24
+ ldrb r5,[r12,#9]
+ ldrb r6,[r12,#8]
+ orr r2,r2,r4,lsl#8
+ ldrb r3,[r12,#15]
+ orr r2,r2,r5,lsl#16
+ ldrb r4,[r12,#14]
+ orr r2,r2,r6,lsl#24
+ ldrb r5,[r12,#13]
+ ldrb r6,[r12,#12]
+ orr r3,r3,r4,lsl#8
+ orr r3,r3,r5,lsl#16
+ orr r3,r3,r6,lsl#24
+#else
+ ldr r0,[r12,#0]
+ ldr r1,[r12,#4]
+ ldr r2,[r12,#8]
+ ldr r3,[r12,#12]
+#ifdef __ARMEL__
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+#endif
+#endif
+ bl _armv4_AES_encrypt
+
+ ldr r12,[sp],#4 @ pop out
+#if __ARM_ARCH__>=7
+#ifdef __ARMEL__
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+#endif
+ str r0,[r12,#0]
+ str r1,[r12,#4]
+ str r2,[r12,#8]
+ str r3,[r12,#12]
+#else
+ mov r4,r0,lsr#24 @ write output in endian-neutral
+ mov r5,r0,lsr#16 @ manner...
+ mov r6,r0,lsr#8
+ strb r4,[r12,#0]
+ strb r5,[r12,#1]
+ mov r4,r1,lsr#24
+ strb r6,[r12,#2]
+ mov r5,r1,lsr#16
+ strb r0,[r12,#3]
+ mov r6,r1,lsr#8
+ strb r4,[r12,#4]
+ strb r5,[r12,#5]
+ mov r4,r2,lsr#24
+ strb r6,[r12,#6]
+ mov r5,r2,lsr#16
+ strb r1,[r12,#7]
+ mov r6,r2,lsr#8
+ strb r4,[r12,#8]
+ strb r5,[r12,#9]
+ mov r4,r3,lsr#24
+ strb r6,[r12,#10]
+ mov r5,r3,lsr#16
+ strb r2,[r12,#11]
+ mov r6,r3,lsr#8
+ strb r4,[r12,#12]
+ strb r5,[r12,#13]
+ strb r6,[r12,#14]
+ strb r3,[r12,#15]
+#endif
+ ldmia sp!,{r4-r12,pc}
+ENDPROC(AES_encrypt)
+
+.type _armv4_AES_encrypt,%function
+.align 2
+_armv4_AES_encrypt:
+ str lr,[sp,#-4]! @ push lr
+ ldmia r11!,{r4-r7}
+ eor r0,r0,r4
+ ldr r12,[r11,#240-16]
+ eor r1,r1,r5
+ eor r2,r2,r6
+ eor r3,r3,r7
+ sub r12,r12,#1
+ mov lr,#255
+
+ and r7,lr,r0
+ and r8,lr,r0,lsr#8
+ and r9,lr,r0,lsr#16
+ mov r0,r0,lsr#24
+.Lenc_loop:
+ ldr r4,[r10,r7,lsl#2] @ Te3[s0>>0]
+ and r7,lr,r1,lsr#16 @ i0
+ ldr r5,[r10,r8,lsl#2] @ Te2[s0>>8]
+ and r8,lr,r1
+ ldr r6,[r10,r9,lsl#2] @ Te1[s0>>16]
+ and r9,lr,r1,lsr#8
+ ldr r0,[r10,r0,lsl#2] @ Te0[s0>>24]
+ mov r1,r1,lsr#24
+
+ ldr r7,[r10,r7,lsl#2] @ Te1[s1>>16]
+ ldr r8,[r10,r8,lsl#2] @ Te3[s1>>0]
+ ldr r9,[r10,r9,lsl#2] @ Te2[s1>>8]
+ eor r0,r0,r7,ror#8
+ ldr r1,[r10,r1,lsl#2] @ Te0[s1>>24]
+ and r7,lr,r2,lsr#8 @ i0
+ eor r5,r5,r8,ror#8
+ and r8,lr,r2,lsr#16 @ i1
+ eor r6,r6,r9,ror#8
+ and r9,lr,r2
+ ldr r7,[r10,r7,lsl#2] @ Te2[s2>>8]
+ eor r1,r1,r4,ror#24
+ ldr r8,[r10,r8,lsl#2] @ Te1[s2>>16]
+ mov r2,r2,lsr#24
+
+ ldr r9,[r10,r9,lsl#2] @ Te3[s2>>0]
+ eor r0,r0,r7,ror#16
+ ldr r2,[r10,r2,lsl#2] @ Te0[s2>>24]
+ and r7,lr,r3 @ i0
+ eor r1,r1,r8,ror#8
+ and r8,lr,r3,lsr#8 @ i1
+ eor r6,r6,r9,ror#16
+ and r9,lr,r3,lsr#16 @ i2
+ ldr r7,[r10,r7,lsl#2] @ Te3[s3>>0]
+ eor r2,r2,r5,ror#16
+ ldr r8,[r10,r8,lsl#2] @ Te2[s3>>8]
+ mov r3,r3,lsr#24
+
+ ldr r9,[r10,r9,lsl#2] @ Te1[s3>>16]
+ eor r0,r0,r7,ror#24
+ ldr r7,[r11],#16
+ eor r1,r1,r8,ror#16
+ ldr r3,[r10,r3,lsl#2] @ Te0[s3>>24]
+ eor r2,r2,r9,ror#8
+ ldr r4,[r11,#-12]
+ eor r3,r3,r6,ror#8
+
+ ldr r5,[r11,#-8]
+ eor r0,r0,r7
+ ldr r6,[r11,#-4]
+ and r7,lr,r0
+ eor r1,r1,r4
+ and r8,lr,r0,lsr#8
+ eor r2,r2,r5
+ and r9,lr,r0,lsr#16
+ eor r3,r3,r6
+ mov r0,r0,lsr#24
+
+ subs r12,r12,#1
+ bne .Lenc_loop
+
+ add r10,r10,#2
+
+ ldrb r4,[r10,r7,lsl#2] @ Te4[s0>>0]
+ and r7,lr,r1,lsr#16 @ i0
+ ldrb r5,[r10,r8,lsl#2] @ Te4[s0>>8]
+ and r8,lr,r1
+ ldrb r6,[r10,r9,lsl#2] @ Te4[s0>>16]
+ and r9,lr,r1,lsr#8
+ ldrb r0,[r10,r0,lsl#2] @ Te4[s0>>24]
+ mov r1,r1,lsr#24
+
+ ldrb r7,[r10,r7,lsl#2] @ Te4[s1>>16]
+ ldrb r8,[r10,r8,lsl#2] @ Te4[s1>>0]
+ ldrb r9,[r10,r9,lsl#2] @ Te4[s1>>8]
+ eor r0,r7,r0,lsl#8
+ ldrb r1,[r10,r1,lsl#2] @ Te4[s1>>24]
+ and r7,lr,r2,lsr#8 @ i0
+ eor r5,r8,r5,lsl#8
+ and r8,lr,r2,lsr#16 @ i1
+ eor r6,r9,r6,lsl#8
+ and r9,lr,r2
+ ldrb r7,[r10,r7,lsl#2] @ Te4[s2>>8]
+ eor r1,r4,r1,lsl#24
+ ldrb r8,[r10,r8,lsl#2] @ Te4[s2>>16]
+ mov r2,r2,lsr#24
+
+ ldrb r9,[r10,r9,lsl#2] @ Te4[s2>>0]
+ eor r0,r7,r0,lsl#8
+ ldrb r2,[r10,r2,lsl#2] @ Te4[s2>>24]
+ and r7,lr,r3 @ i0
+ eor r1,r1,r8,lsl#16
+ and r8,lr,r3,lsr#8 @ i1
+ eor r6,r9,r6,lsl#8
+ and r9,lr,r3,lsr#16 @ i2
+ ldrb r7,[r10,r7,lsl#2] @ Te4[s3>>0]
+ eor r2,r5,r2,lsl#24
+ ldrb r8,[r10,r8,lsl#2] @ Te4[s3>>8]
+ mov r3,r3,lsr#24
+
+ ldrb r9,[r10,r9,lsl#2] @ Te4[s3>>16]
+ eor r0,r7,r0,lsl#8
+ ldr r7,[r11,#0]
+ ldrb r3,[r10,r3,lsl#2] @ Te4[s3>>24]
+ eor r1,r1,r8,lsl#8
+ ldr r4,[r11,#4]
+ eor r2,r2,r9,lsl#16
+ ldr r5,[r11,#8]
+ eor r3,r6,r3,lsl#24
+ ldr r6,[r11,#12]
+
+ eor r0,r0,r7
+ eor r1,r1,r4
+ eor r2,r2,r5
+ eor r3,r3,r6
+
+ sub r10,r10,#2
+ ldr pc,[sp],#4 @ pop and return
+.size _armv4_AES_encrypt,.-_armv4_AES_encrypt
+
+.align 5
+ENTRY(private_AES_set_encrypt_key)
+_armv4_AES_set_encrypt_key:
+ adr r3,_armv4_AES_set_encrypt_key
+ teq r0,#0
+ moveq r0,#-1
+ beq .Labrt
+ teq r2,#0
+ moveq r0,#-1
+ beq .Labrt
+
+ teq r1,#128
+ beq .Lok
+ teq r1,#192
+ beq .Lok
+ teq r1,#256
+ movne r0,#-1
+ bne .Labrt
+
+.Lok: stmdb sp!,{r4-r12,lr}
+ sub r10,r3,#_armv4_AES_set_encrypt_key-AES_Te-1024 @ Te4
+
+ mov r12,r0 @ inp
+ mov lr,r1 @ bits
+ mov r11,r2 @ key
+
+#if __ARM_ARCH__<7
+ ldrb r0,[r12,#3] @ load input data in endian-neutral
+ ldrb r4,[r12,#2] @ manner...
+ ldrb r5,[r12,#1]
+ ldrb r6,[r12,#0]
+ orr r0,r0,r4,lsl#8
+ ldrb r1,[r12,#7]
+ orr r0,r0,r5,lsl#16
+ ldrb r4,[r12,#6]
+ orr r0,r0,r6,lsl#24
+ ldrb r5,[r12,#5]
+ ldrb r6,[r12,#4]
+ orr r1,r1,r4,lsl#8
+ ldrb r2,[r12,#11]
+ orr r1,r1,r5,lsl#16
+ ldrb r4,[r12,#10]
+ orr r1,r1,r6,lsl#24
+ ldrb r5,[r12,#9]
+ ldrb r6,[r12,#8]
+ orr r2,r2,r4,lsl#8
+ ldrb r3,[r12,#15]
+ orr r2,r2,r5,lsl#16
+ ldrb r4,[r12,#14]
+ orr r2,r2,r6,lsl#24
+ ldrb r5,[r12,#13]
+ ldrb r6,[r12,#12]
+ orr r3,r3,r4,lsl#8
+ str r0,[r11],#16
+ orr r3,r3,r5,lsl#16
+ str r1,[r11,#-12]
+ orr r3,r3,r6,lsl#24
+ str r2,[r11,#-8]
+ str r3,[r11,#-4]
+#else
+ ldr r0,[r12,#0]
+ ldr r1,[r12,#4]
+ ldr r2,[r12,#8]
+ ldr r3,[r12,#12]
+#ifdef __ARMEL__
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+#endif
+ str r0,[r11],#16
+ str r1,[r11,#-12]
+ str r2,[r11,#-8]
+ str r3,[r11,#-4]
+#endif
+
+ teq lr,#128
+ bne .Lnot128
+ mov r12,#10
+ str r12,[r11,#240-16]
+ add r6,r10,#256 @ rcon
+ mov lr,#255
+
+.L128_loop:
+ and r5,lr,r3,lsr#24
+ and r7,lr,r3,lsr#16
+ ldrb r5,[r10,r5]
+ and r8,lr,r3,lsr#8
+ ldrb r7,[r10,r7]
+ and r9,lr,r3
+ ldrb r8,[r10,r8]
+ orr r5,r5,r7,lsl#24
+ ldrb r9,[r10,r9]
+ orr r5,r5,r8,lsl#16
+ ldr r4,[r6],#4 @ rcon[i++]
+ orr r5,r5,r9,lsl#8
+ eor r5,r5,r4
+ eor r0,r0,r5 @ rk[4]=rk[0]^...
+ eor r1,r1,r0 @ rk[5]=rk[1]^rk[4]
+ str r0,[r11],#16
+ eor r2,r2,r1 @ rk[6]=rk[2]^rk[5]
+ str r1,[r11,#-12]
+ eor r3,r3,r2 @ rk[7]=rk[3]^rk[6]
+ str r2,[r11,#-8]
+ subs r12,r12,#1
+ str r3,[r11,#-4]
+ bne .L128_loop
+ sub r2,r11,#176
+ b .Ldone
+
+.Lnot128:
+#if __ARM_ARCH__<7
+ ldrb r8,[r12,#19]
+ ldrb r4,[r12,#18]
+ ldrb r5,[r12,#17]
+ ldrb r6,[r12,#16]
+ orr r8,r8,r4,lsl#8
+ ldrb r9,[r12,#23]
+ orr r8,r8,r5,lsl#16
+ ldrb r4,[r12,#22]
+ orr r8,r8,r6,lsl#24
+ ldrb r5,[r12,#21]
+ ldrb r6,[r12,#20]
+ orr r9,r9,r4,lsl#8
+ orr r9,r9,r5,lsl#16
+ str r8,[r11],#8
+ orr r9,r9,r6,lsl#24
+ str r9,[r11,#-4]
+#else
+ ldr r8,[r12,#16]
+ ldr r9,[r12,#20]
+#ifdef __ARMEL__
+ rev r8,r8
+ rev r9,r9
+#endif
+ str r8,[r11],#8
+ str r9,[r11,#-4]
+#endif
+
+ teq lr,#192
+ bne .Lnot192
+ mov r12,#12
+ str r12,[r11,#240-24]
+ add r6,r10,#256 @ rcon
+ mov lr,#255
+ mov r12,#8
+
+.L192_loop:
+ and r5,lr,r9,lsr#24
+ and r7,lr,r9,lsr#16
+ ldrb r5,[r10,r5]
+ and r8,lr,r9,lsr#8
+ ldrb r7,[r10,r7]
+ and r9,lr,r9
+ ldrb r8,[r10,r8]
+ orr r5,r5,r7,lsl#24
+ ldrb r9,[r10,r9]
+ orr r5,r5,r8,lsl#16
+ ldr r4,[r6],#4 @ rcon[i++]
+ orr r5,r5,r9,lsl#8
+ eor r9,r5,r4
+ eor r0,r0,r9 @ rk[6]=rk[0]^...
+ eor r1,r1,r0 @ rk[7]=rk[1]^rk[6]
+ str r0,[r11],#24
+ eor r2,r2,r1 @ rk[8]=rk[2]^rk[7]
+ str r1,[r11,#-20]
+ eor r3,r3,r2 @ rk[9]=rk[3]^rk[8]
+ str r2,[r11,#-16]
+ subs r12,r12,#1
+ str r3,[r11,#-12]
+ subeq r2,r11,#216
+ beq .Ldone
+
+ ldr r7,[r11,#-32]
+ ldr r8,[r11,#-28]
+ eor r7,r7,r3 @ rk[10]=rk[4]^rk[9]
+ eor r9,r8,r7 @ rk[11]=rk[5]^rk[10]
+ str r7,[r11,#-8]
+ str r9,[r11,#-4]
+ b .L192_loop
+
+.Lnot192:
+#if __ARM_ARCH__<7
+ ldrb r8,[r12,#27]
+ ldrb r4,[r12,#26]
+ ldrb r5,[r12,#25]
+ ldrb r6,[r12,#24]
+ orr r8,r8,r4,lsl#8
+ ldrb r9,[r12,#31]
+ orr r8,r8,r5,lsl#16
+ ldrb r4,[r12,#30]
+ orr r8,r8,r6,lsl#24
+ ldrb r5,[r12,#29]
+ ldrb r6,[r12,#28]
+ orr r9,r9,r4,lsl#8
+ orr r9,r9,r5,lsl#16
+ str r8,[r11],#8
+ orr r9,r9,r6,lsl#24
+ str r9,[r11,#-4]
+#else
+ ldr r8,[r12,#24]
+ ldr r9,[r12,#28]
+#ifdef __ARMEL__
+ rev r8,r8
+ rev r9,r9
+#endif
+ str r8,[r11],#8
+ str r9,[r11,#-4]
+#endif
+
+ mov r12,#14
+ str r12,[r11,#240-32]
+ add r6,r10,#256 @ rcon
+ mov lr,#255
+ mov r12,#7
+
+.L256_loop:
+ and r5,lr,r9,lsr#24
+ and r7,lr,r9,lsr#16
+ ldrb r5,[r10,r5]
+ and r8,lr,r9,lsr#8
+ ldrb r7,[r10,r7]
+ and r9,lr,r9
+ ldrb r8,[r10,r8]
+ orr r5,r5,r7,lsl#24
+ ldrb r9,[r10,r9]
+ orr r5,r5,r8,lsl#16
+ ldr r4,[r6],#4 @ rcon[i++]
+ orr r5,r5,r9,lsl#8
+ eor r9,r5,r4
+ eor r0,r0,r9 @ rk[8]=rk[0]^...
+ eor r1,r1,r0 @ rk[9]=rk[1]^rk[8]
+ str r0,[r11],#32
+ eor r2,r2,r1 @ rk[10]=rk[2]^rk[9]
+ str r1,[r11,#-28]
+ eor r3,r3,r2 @ rk[11]=rk[3]^rk[10]
+ str r2,[r11,#-24]
+ subs r12,r12,#1
+ str r3,[r11,#-20]
+ subeq r2,r11,#256
+ beq .Ldone
+
+ and r5,lr,r3
+ and r7,lr,r3,lsr#8
+ ldrb r5,[r10,r5]
+ and r8,lr,r3,lsr#16
+ ldrb r7,[r10,r7]
+ and r9,lr,r3,lsr#24
+ ldrb r8,[r10,r8]
+ orr r5,r5,r7,lsl#8
+ ldrb r9,[r10,r9]
+ orr r5,r5,r8,lsl#16
+ ldr r4,[r11,#-48]
+ orr r5,r5,r9,lsl#24
+
+ ldr r7,[r11,#-44]
+ ldr r8,[r11,#-40]
+ eor r4,r4,r5 @ rk[12]=rk[4]^...
+ ldr r9,[r11,#-36]
+ eor r7,r7,r4 @ rk[13]=rk[5]^rk[12]
+ str r4,[r11,#-16]
+ eor r8,r8,r7 @ rk[14]=rk[6]^rk[13]
+ str r7,[r11,#-12]
+ eor r9,r9,r8 @ rk[15]=rk[7]^rk[14]
+ str r8,[r11,#-8]
+ str r9,[r11,#-4]
+ b .L256_loop
+
+.Ldone: mov r0,#0
+ ldmia sp!,{r4-r12,lr}
+.Labrt: ret lr
+ENDPROC(private_AES_set_encrypt_key)
+
+.align 5
+ENTRY(private_AES_set_decrypt_key)
+ str lr,[sp,#-4]! @ push lr
+#if 0
+ @ kernel does both of these in setkey so optimise this bit out by
+ @ expecting the key to already have the enc_key work done (see aes_glue.c)
+ bl _armv4_AES_set_encrypt_key
+#else
+ mov r0,#0
+#endif
+ teq r0,#0
+ ldrne lr,[sp],#4 @ pop lr
+ bne .Labrt
+
+ stmdb sp!,{r4-r12}
+
+ ldr r12,[r2,#240] @ AES_set_encrypt_key preserves r2,
+ mov r11,r2 @ which is AES_KEY *key
+ mov r7,r2
+ add r8,r2,r12,lsl#4
+
+.Linv: ldr r0,[r7]
+ ldr r1,[r7,#4]
+ ldr r2,[r7,#8]
+ ldr r3,[r7,#12]
+ ldr r4,[r8]
+ ldr r5,[r8,#4]
+ ldr r6,[r8,#8]
+ ldr r9,[r8,#12]
+ str r0,[r8],#-16
+ str r1,[r8,#16+4]
+ str r2,[r8,#16+8]
+ str r3,[r8,#16+12]
+ str r4,[r7],#16
+ str r5,[r7,#-12]
+ str r6,[r7,#-8]
+ str r9,[r7,#-4]
+ teq r7,r8
+ bne .Linv
+ ldr r0,[r11,#16]! @ prefetch tp1
+ mov r7,#0x80
+ mov r8,#0x1b
+ orr r7,r7,#0x8000
+ orr r8,r8,#0x1b00
+ orr r7,r7,r7,lsl#16
+ orr r8,r8,r8,lsl#16
+ sub r12,r12,#1
+ mvn r9,r7
+ mov r12,r12,lsl#2 @ (rounds-1)*4
+
+.Lmix: and r4,r0,r7
+ and r1,r0,r9
+ sub r4,r4,r4,lsr#7
+ and r4,r4,r8
+ eor r1,r4,r1,lsl#1 @ tp2
+
+ and r4,r1,r7
+ and r2,r1,r9
+ sub r4,r4,r4,lsr#7
+ and r4,r4,r8
+ eor r2,r4,r2,lsl#1 @ tp4
+
+ and r4,r2,r7
+ and r3,r2,r9
+ sub r4,r4,r4,lsr#7
+ and r4,r4,r8
+ eor r3,r4,r3,lsl#1 @ tp8
+
+ eor r4,r1,r2
+ eor r5,r0,r3 @ tp9
+ eor r4,r4,r3 @ tpe
+ eor r4,r4,r1,ror#24
+ eor r4,r4,r5,ror#24 @ ^= ROTATE(tpb=tp9^tp2,8)
+ eor r4,r4,r2,ror#16
+ eor r4,r4,r5,ror#16 @ ^= ROTATE(tpd=tp9^tp4,16)
+ eor r4,r4,r5,ror#8 @ ^= ROTATE(tp9,24)
+
+ ldr r0,[r11,#4] @ prefetch tp1
+ str r4,[r11],#4
+ subs r12,r12,#1
+ bne .Lmix
+
+ mov r0,#0
+ ldmia sp!,{r4-r12,pc}
+ENDPROC(private_AES_set_decrypt_key)
+
+.type AES_Td,%object
+.align 5
+AES_Td:
+.word 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96
+.word 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393
+.word 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25
+.word 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f
+.word 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1
+.word 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6
+.word 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da
+.word 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844
+.word 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd
+.word 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4
+.word 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45
+.word 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94
+.word 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7
+.word 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a
+.word 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5
+.word 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c
+.word 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1
+.word 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a
+.word 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75
+.word 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051
+.word 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46
+.word 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff
+.word 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77
+.word 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb
+.word 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000
+.word 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e
+.word 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927
+.word 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a
+.word 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e
+.word 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16
+.word 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d
+.word 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8
+.word 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd
+.word 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34
+.word 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163
+.word 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120
+.word 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d
+.word 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0
+.word 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422
+.word 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef
+.word 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36
+.word 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4
+.word 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662
+.word 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5
+.word 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3
+.word 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b
+.word 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8
+.word 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6
+.word 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6
+.word 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0
+.word 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815
+.word 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f
+.word 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df
+.word 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f
+.word 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e
+.word 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713
+.word 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89
+.word 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c
+.word 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf
+.word 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86
+.word 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f
+.word 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541
+.word 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190
+.word 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
+@ Td4[256]
+.byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
+.byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+.byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
+.byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+.byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
+.byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+.byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
+.byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+.byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
+.byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+.byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
+.byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+.byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
+.byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+.byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
+.byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+.byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
+.byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+.byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
+.byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+.byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
+.byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+.byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
+.byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+.byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
+.byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+.byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
+.byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+.byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
+.byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+.byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
+.byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+.size AES_Td,.-AES_Td
+
+@ void AES_decrypt(const unsigned char *in, unsigned char *out,
+@ const AES_KEY *key) {
+.align 5
+ENTRY(AES_decrypt)
+ adr r3,AES_decrypt
+ stmdb sp!,{r1,r4-r12,lr}
+ mov r12,r0 @ inp
+ mov r11,r2
+ sub r10,r3,#AES_decrypt-AES_Td @ Td
+#if __ARM_ARCH__<7
+ ldrb r0,[r12,#3] @ load input data in endian-neutral
+ ldrb r4,[r12,#2] @ manner...
+ ldrb r5,[r12,#1]
+ ldrb r6,[r12,#0]
+ orr r0,r0,r4,lsl#8
+ ldrb r1,[r12,#7]
+ orr r0,r0,r5,lsl#16
+ ldrb r4,[r12,#6]
+ orr r0,r0,r6,lsl#24
+ ldrb r5,[r12,#5]
+ ldrb r6,[r12,#4]
+ orr r1,r1,r4,lsl#8
+ ldrb r2,[r12,#11]
+ orr r1,r1,r5,lsl#16
+ ldrb r4,[r12,#10]
+ orr r1,r1,r6,lsl#24
+ ldrb r5,[r12,#9]
+ ldrb r6,[r12,#8]
+ orr r2,r2,r4,lsl#8
+ ldrb r3,[r12,#15]
+ orr r2,r2,r5,lsl#16
+ ldrb r4,[r12,#14]
+ orr r2,r2,r6,lsl#24
+ ldrb r5,[r12,#13]
+ ldrb r6,[r12,#12]
+ orr r3,r3,r4,lsl#8
+ orr r3,r3,r5,lsl#16
+ orr r3,r3,r6,lsl#24
+#else
+ ldr r0,[r12,#0]
+ ldr r1,[r12,#4]
+ ldr r2,[r12,#8]
+ ldr r3,[r12,#12]
+#ifdef __ARMEL__
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+#endif
+#endif
+ bl _armv4_AES_decrypt
+
+ ldr r12,[sp],#4 @ pop out
+#if __ARM_ARCH__>=7
+#ifdef __ARMEL__
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+#endif
+ str r0,[r12,#0]
+ str r1,[r12,#4]
+ str r2,[r12,#8]
+ str r3,[r12,#12]
+#else
+ mov r4,r0,lsr#24 @ write output in endian-neutral
+ mov r5,r0,lsr#16 @ manner...
+ mov r6,r0,lsr#8
+ strb r4,[r12,#0]
+ strb r5,[r12,#1]
+ mov r4,r1,lsr#24
+ strb r6,[r12,#2]
+ mov r5,r1,lsr#16
+ strb r0,[r12,#3]
+ mov r6,r1,lsr#8
+ strb r4,[r12,#4]
+ strb r5,[r12,#5]
+ mov r4,r2,lsr#24
+ strb r6,[r12,#6]
+ mov r5,r2,lsr#16
+ strb r1,[r12,#7]
+ mov r6,r2,lsr#8
+ strb r4,[r12,#8]
+ strb r5,[r12,#9]
+ mov r4,r3,lsr#24
+ strb r6,[r12,#10]
+ mov r5,r3,lsr#16
+ strb r2,[r12,#11]
+ mov r6,r3,lsr#8
+ strb r4,[r12,#12]
+ strb r5,[r12,#13]
+ strb r6,[r12,#14]
+ strb r3,[r12,#15]
+#endif
+ ldmia sp!,{r4-r12,pc}
+ENDPROC(AES_decrypt)
+
+.type _armv4_AES_decrypt,%function
+.align 2
+_armv4_AES_decrypt:
+ str lr,[sp,#-4]! @ push lr
+ ldmia r11!,{r4-r7}
+ eor r0,r0,r4
+ ldr r12,[r11,#240-16]
+ eor r1,r1,r5
+ eor r2,r2,r6
+ eor r3,r3,r7
+ sub r12,r12,#1
+ mov lr,#255
+
+ and r7,lr,r0,lsr#16
+ and r8,lr,r0,lsr#8
+ and r9,lr,r0
+ mov r0,r0,lsr#24
+.Ldec_loop:
+ ldr r4,[r10,r7,lsl#2] @ Td1[s0>>16]
+ and r7,lr,r1 @ i0
+ ldr r5,[r10,r8,lsl#2] @ Td2[s0>>8]
+ and r8,lr,r1,lsr#16
+ ldr r6,[r10,r9,lsl#2] @ Td3[s0>>0]
+ and r9,lr,r1,lsr#8
+ ldr r0,[r10,r0,lsl#2] @ Td0[s0>>24]
+ mov r1,r1,lsr#24
+
+ ldr r7,[r10,r7,lsl#2] @ Td3[s1>>0]
+ ldr r8,[r10,r8,lsl#2] @ Td1[s1>>16]
+ ldr r9,[r10,r9,lsl#2] @ Td2[s1>>8]
+ eor r0,r0,r7,ror#24
+ ldr r1,[r10,r1,lsl#2] @ Td0[s1>>24]
+ and r7,lr,r2,lsr#8 @ i0
+ eor r5,r8,r5,ror#8
+ and r8,lr,r2 @ i1
+ eor r6,r9,r6,ror#8
+ and r9,lr,r2,lsr#16
+ ldr r7,[r10,r7,lsl#2] @ Td2[s2>>8]
+ eor r1,r1,r4,ror#8
+ ldr r8,[r10,r8,lsl#2] @ Td3[s2>>0]
+ mov r2,r2,lsr#24
+
+ ldr r9,[r10,r9,lsl#2] @ Td1[s2>>16]
+ eor r0,r0,r7,ror#16
+ ldr r2,[r10,r2,lsl#2] @ Td0[s2>>24]
+ and r7,lr,r3,lsr#16 @ i0
+ eor r1,r1,r8,ror#24
+ and r8,lr,r3,lsr#8 @ i1
+ eor r6,r9,r6,ror#8
+ and r9,lr,r3 @ i2
+ ldr r7,[r10,r7,lsl#2] @ Td1[s3>>16]
+ eor r2,r2,r5,ror#8
+ ldr r8,[r10,r8,lsl#2] @ Td2[s3>>8]
+ mov r3,r3,lsr#24
+
+ ldr r9,[r10,r9,lsl#2] @ Td3[s3>>0]
+ eor r0,r0,r7,ror#8
+ ldr r7,[r11],#16
+ eor r1,r1,r8,ror#16
+ ldr r3,[r10,r3,lsl#2] @ Td0[s3>>24]
+ eor r2,r2,r9,ror#24
+
+ ldr r4,[r11,#-12]
+ eor r0,r0,r7
+ ldr r5,[r11,#-8]
+ eor r3,r3,r6,ror#8
+ ldr r6,[r11,#-4]
+ and r7,lr,r0,lsr#16
+ eor r1,r1,r4
+ and r8,lr,r0,lsr#8
+ eor r2,r2,r5
+ and r9,lr,r0
+ eor r3,r3,r6
+ mov r0,r0,lsr#24
+
+ subs r12,r12,#1
+ bne .Ldec_loop
+
+ add r10,r10,#1024
+
+ ldr r5,[r10,#0] @ prefetch Td4
+ ldr r6,[r10,#32]
+ ldr r4,[r10,#64]
+ ldr r5,[r10,#96]
+ ldr r6,[r10,#128]
+ ldr r4,[r10,#160]
+ ldr r5,[r10,#192]
+ ldr r6,[r10,#224]
+
+ ldrb r0,[r10,r0] @ Td4[s0>>24]
+ ldrb r4,[r10,r7] @ Td4[s0>>16]
+ and r7,lr,r1 @ i0
+ ldrb r5,[r10,r8] @ Td4[s0>>8]
+ and r8,lr,r1,lsr#16
+ ldrb r6,[r10,r9] @ Td4[s0>>0]
+ and r9,lr,r1,lsr#8
+
+ ldrb r7,[r10,r7] @ Td4[s1>>0]
+ ARM( ldrb r1,[r10,r1,lsr#24] ) @ Td4[s1>>24]
+ THUMB( add r1,r10,r1,lsr#24 ) @ Td4[s1>>24]
+ THUMB( ldrb r1,[r1] )
+ ldrb r8,[r10,r8] @ Td4[s1>>16]
+ eor r0,r7,r0,lsl#24
+ ldrb r9,[r10,r9] @ Td4[s1>>8]
+ eor r1,r4,r1,lsl#8
+ and r7,lr,r2,lsr#8 @ i0
+ eor r5,r5,r8,lsl#8
+ and r8,lr,r2 @ i1
+ ldrb r7,[r10,r7] @ Td4[s2>>8]
+ eor r6,r6,r9,lsl#8
+ ldrb r8,[r10,r8] @ Td4[s2>>0]
+ and r9,lr,r2,lsr#16
+
+ ARM( ldrb r2,[r10,r2,lsr#24] ) @ Td4[s2>>24]
+ THUMB( add r2,r10,r2,lsr#24 ) @ Td4[s2>>24]
+ THUMB( ldrb r2,[r2] )
+ eor r0,r0,r7,lsl#8
+ ldrb r9,[r10,r9] @ Td4[s2>>16]
+ eor r1,r8,r1,lsl#16
+ and r7,lr,r3,lsr#16 @ i0
+ eor r2,r5,r2,lsl#16
+ and r8,lr,r3,lsr#8 @ i1
+ ldrb r7,[r10,r7] @ Td4[s3>>16]
+ eor r6,r6,r9,lsl#16
+ ldrb r8,[r10,r8] @ Td4[s3>>8]
+ and r9,lr,r3 @ i2
+
+ ldrb r9,[r10,r9] @ Td4[s3>>0]
+ ARM( ldrb r3,[r10,r3,lsr#24] ) @ Td4[s3>>24]
+ THUMB( add r3,r10,r3,lsr#24 ) @ Td4[s3>>24]
+ THUMB( ldrb r3,[r3] )
+ eor r0,r0,r7,lsl#16
+ ldr r7,[r11,#0]
+ eor r1,r1,r8,lsl#8
+ ldr r4,[r11,#4]
+ eor r2,r9,r2,lsl#8
+ ldr r5,[r11,#8]
+ eor r3,r6,r3,lsl#24
+ ldr r6,[r11,#12]
+
+ eor r0,r0,r7
+ eor r1,r1,r4
+ eor r2,r2,r5
+ eor r3,r3,r6
+
+ sub r10,r10,#1024
+ ldr pc,[sp],#4 @ pop and return
+.size _armv4_AES_decrypt,.-_armv4_AES_decrypt
+.asciz "AES for ARMv4, CRYPTOGAMS by <appro@openssl.org>"
+.align 2
diff --git a/arch/arm/crypto/aes-ce-core.S b/arch/arm/crypto/aes-ce-core.S
new file mode 100644
index 000000000..8cfa468ee
--- /dev/null
+++ b/arch/arm/crypto/aes-ce-core.S
@@ -0,0 +1,518 @@
+/*
+ * aes-ce-core.S - AES in CBC/CTR/XTS mode using ARMv8 Crypto Extensions
+ *
+ * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@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 <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+ .fpu crypto-neon-fp-armv8
+ .align 3
+
+ .macro enc_round, state, key
+ aese.8 \state, \key
+ aesmc.8 \state, \state
+ .endm
+
+ .macro dec_round, state, key
+ aesd.8 \state, \key
+ aesimc.8 \state, \state
+ .endm
+
+ .macro enc_dround, key1, key2
+ enc_round q0, \key1
+ enc_round q0, \key2
+ .endm
+
+ .macro dec_dround, key1, key2
+ dec_round q0, \key1
+ dec_round q0, \key2
+ .endm
+
+ .macro enc_fround, key1, key2, key3
+ enc_round q0, \key1
+ aese.8 q0, \key2
+ veor q0, q0, \key3
+ .endm
+
+ .macro dec_fround, key1, key2, key3
+ dec_round q0, \key1
+ aesd.8 q0, \key2
+ veor q0, q0, \key3
+ .endm
+
+ .macro enc_dround_3x, key1, key2
+ enc_round q0, \key1
+ enc_round q1, \key1
+ enc_round q2, \key1
+ enc_round q0, \key2
+ enc_round q1, \key2
+ enc_round q2, \key2
+ .endm
+
+ .macro dec_dround_3x, key1, key2
+ dec_round q0, \key1
+ dec_round q1, \key1
+ dec_round q2, \key1
+ dec_round q0, \key2
+ dec_round q1, \key2
+ dec_round q2, \key2
+ .endm
+
+ .macro enc_fround_3x, key1, key2, key3
+ enc_round q0, \key1
+ enc_round q1, \key1
+ enc_round q2, \key1
+ aese.8 q0, \key2
+ aese.8 q1, \key2
+ aese.8 q2, \key2
+ veor q0, q0, \key3
+ veor q1, q1, \key3
+ veor q2, q2, \key3
+ .endm
+
+ .macro dec_fround_3x, key1, key2, key3
+ dec_round q0, \key1
+ dec_round q1, \key1
+ dec_round q2, \key1
+ aesd.8 q0, \key2
+ aesd.8 q1, \key2
+ aesd.8 q2, \key2
+ veor q0, q0, \key3
+ veor q1, q1, \key3
+ veor q2, q2, \key3
+ .endm
+
+ .macro do_block, dround, fround
+ cmp r3, #12 @ which key size?
+ vld1.8 {q10-q11}, [ip]!
+ \dround q8, q9
+ vld1.8 {q12-q13}, [ip]!
+ \dround q10, q11
+ vld1.8 {q10-q11}, [ip]!
+ \dround q12, q13
+ vld1.8 {q12-q13}, [ip]!
+ \dround q10, q11
+ blo 0f @ AES-128: 10 rounds
+ vld1.8 {q10-q11}, [ip]!
+ beq 1f @ AES-192: 12 rounds
+ \dround q12, q13
+ vld1.8 {q12-q13}, [ip]
+ \dround q10, q11
+0: \fround q12, q13, q14
+ bx lr
+
+1: \dround q12, q13
+ \fround q10, q11, q14
+ bx lr
+ .endm
+
+ /*
+ * Internal, non-AAPCS compliant functions that implement the core AES
+ * transforms. These should preserve all registers except q0 - q2 and ip
+ * Arguments:
+ * q0 : first in/output block
+ * q1 : second in/output block (_3x version only)
+ * q2 : third in/output block (_3x version only)
+ * q8 : first round key
+ * q9 : secound round key
+ * ip : address of 3rd round key
+ * q14 : final round key
+ * r3 : number of rounds
+ */
+ .align 6
+aes_encrypt:
+ add ip, r2, #32 @ 3rd round key
+.Laes_encrypt_tweak:
+ do_block enc_dround, enc_fround
+ENDPROC(aes_encrypt)
+
+ .align 6
+aes_decrypt:
+ add ip, r2, #32 @ 3rd round key
+ do_block dec_dround, dec_fround
+ENDPROC(aes_decrypt)
+
+ .align 6
+aes_encrypt_3x:
+ add ip, r2, #32 @ 3rd round key
+ do_block enc_dround_3x, enc_fround_3x
+ENDPROC(aes_encrypt_3x)
+
+ .align 6
+aes_decrypt_3x:
+ add ip, r2, #32 @ 3rd round key
+ do_block dec_dround_3x, dec_fround_3x
+ENDPROC(aes_decrypt_3x)
+
+ .macro prepare_key, rk, rounds
+ add ip, \rk, \rounds, lsl #4
+ vld1.8 {q8-q9}, [\rk] @ load first 2 round keys
+ vld1.8 {q14}, [ip] @ load last round key
+ .endm
+
+ /*
+ * aes_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
+ * int blocks)
+ * aes_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
+ * int blocks)
+ */
+ENTRY(ce_aes_ecb_encrypt)
+ push {r4, lr}
+ ldr r4, [sp, #8]
+ prepare_key r2, r3
+.Lecbencloop3x:
+ subs r4, r4, #3
+ bmi .Lecbenc1x
+ vld1.8 {q0-q1}, [r1, :64]!
+ vld1.8 {q2}, [r1, :64]!
+ bl aes_encrypt_3x
+ vst1.8 {q0-q1}, [r0, :64]!
+ vst1.8 {q2}, [r0, :64]!
+ b .Lecbencloop3x
+.Lecbenc1x:
+ adds r4, r4, #3
+ beq .Lecbencout
+.Lecbencloop:
+ vld1.8 {q0}, [r1, :64]!
+ bl aes_encrypt
+ vst1.8 {q0}, [r0, :64]!
+ subs r4, r4, #1
+ bne .Lecbencloop
+.Lecbencout:
+ pop {r4, pc}
+ENDPROC(ce_aes_ecb_encrypt)
+
+ENTRY(ce_aes_ecb_decrypt)
+ push {r4, lr}
+ ldr r4, [sp, #8]
+ prepare_key r2, r3
+.Lecbdecloop3x:
+ subs r4, r4, #3
+ bmi .Lecbdec1x
+ vld1.8 {q0-q1}, [r1, :64]!
+ vld1.8 {q2}, [r1, :64]!
+ bl aes_decrypt_3x
+ vst1.8 {q0-q1}, [r0, :64]!
+ vst1.8 {q2}, [r0, :64]!
+ b .Lecbdecloop3x
+.Lecbdec1x:
+ adds r4, r4, #3
+ beq .Lecbdecout
+.Lecbdecloop:
+ vld1.8 {q0}, [r1, :64]!
+ bl aes_decrypt
+ vst1.8 {q0}, [r0, :64]!
+ subs r4, r4, #1
+ bne .Lecbdecloop
+.Lecbdecout:
+ pop {r4, pc}
+ENDPROC(ce_aes_ecb_decrypt)
+
+ /*
+ * aes_cbc_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
+ * int blocks, u8 iv[])
+ * aes_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
+ * int blocks, u8 iv[])
+ */
+ENTRY(ce_aes_cbc_encrypt)
+ push {r4-r6, lr}
+ ldrd r4, r5, [sp, #16]
+ vld1.8 {q0}, [r5]
+ prepare_key r2, r3
+.Lcbcencloop:
+ vld1.8 {q1}, [r1, :64]! @ get next pt block
+ veor q0, q0, q1 @ ..and xor with iv
+ bl aes_encrypt
+ vst1.8 {q0}, [r0, :64]!
+ subs r4, r4, #1
+ bne .Lcbcencloop
+ vst1.8 {q0}, [r5]
+ pop {r4-r6, pc}
+ENDPROC(ce_aes_cbc_encrypt)
+
+ENTRY(ce_aes_cbc_decrypt)
+ push {r4-r6, lr}
+ ldrd r4, r5, [sp, #16]
+ vld1.8 {q6}, [r5] @ keep iv in q6
+ prepare_key r2, r3
+.Lcbcdecloop3x:
+ subs r4, r4, #3
+ bmi .Lcbcdec1x
+ vld1.8 {q0-q1}, [r1, :64]!
+ vld1.8 {q2}, [r1, :64]!
+ vmov q3, q0
+ vmov q4, q1
+ vmov q5, q2
+ bl aes_decrypt_3x
+ veor q0, q0, q6
+ veor q1, q1, q3
+ veor q2, q2, q4
+ vmov q6, q5
+ vst1.8 {q0-q1}, [r0, :64]!
+ vst1.8 {q2}, [r0, :64]!
+ b .Lcbcdecloop3x
+.Lcbcdec1x:
+ adds r4, r4, #3
+ beq .Lcbcdecout
+ vmov q15, q14 @ preserve last round key
+.Lcbcdecloop:
+ vld1.8 {q0}, [r1, :64]! @ get next ct block
+ veor q14, q15, q6 @ combine prev ct with last key
+ vmov q6, q0
+ bl aes_decrypt
+ vst1.8 {q0}, [r0, :64]!
+ subs r4, r4, #1
+ bne .Lcbcdecloop
+.Lcbcdecout:
+ vst1.8 {q6}, [r5] @ keep iv in q6
+ pop {r4-r6, pc}
+ENDPROC(ce_aes_cbc_decrypt)
+
+ /*
+ * aes_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
+ * int blocks, u8 ctr[])
+ */
+ENTRY(ce_aes_ctr_encrypt)
+ push {r4-r6, lr}
+ ldrd r4, r5, [sp, #16]
+ vld1.8 {q6}, [r5] @ load ctr
+ prepare_key r2, r3
+ vmov r6, s27 @ keep swabbed ctr in r6
+ rev r6, r6
+ cmn r6, r4 @ 32 bit overflow?
+ bcs .Lctrloop
+.Lctrloop3x:
+ subs r4, r4, #3
+ bmi .Lctr1x
+ add r6, r6, #1
+ vmov q0, q6
+ vmov q1, q6
+ rev ip, r6
+ add r6, r6, #1
+ vmov q2, q6
+ vmov s7, ip
+ rev ip, r6
+ add r6, r6, #1
+ vmov s11, ip
+ vld1.8 {q3-q4}, [r1, :64]!
+ vld1.8 {q5}, [r1, :64]!
+ bl aes_encrypt_3x
+ veor q0, q0, q3
+ veor q1, q1, q4
+ veor q2, q2, q5
+ rev ip, r6
+ vst1.8 {q0-q1}, [r0, :64]!
+ vst1.8 {q2}, [r0, :64]!
+ vmov s27, ip
+ b .Lctrloop3x
+.Lctr1x:
+ adds r4, r4, #3
+ beq .Lctrout
+.Lctrloop:
+ vmov q0, q6
+ bl aes_encrypt
+ subs r4, r4, #1
+ bmi .Lctrhalfblock @ blocks < 0 means 1/2 block
+ vld1.8 {q3}, [r1, :64]!
+ veor q3, q0, q3
+ vst1.8 {q3}, [r0, :64]!
+
+ adds r6, r6, #1 @ increment BE ctr
+ rev ip, r6
+ vmov s27, ip
+ bcs .Lctrcarry
+ teq r4, #0
+ bne .Lctrloop
+.Lctrout:
+ vst1.8 {q6}, [r5]
+ pop {r4-r6, pc}
+
+.Lctrhalfblock:
+ vld1.8 {d1}, [r1, :64]
+ veor d0, d0, d1
+ vst1.8 {d0}, [r0, :64]
+ pop {r4-r6, pc}
+
+.Lctrcarry:
+ .irp sreg, s26, s25, s24
+ vmov ip, \sreg @ load next word of ctr
+ rev ip, ip @ ... to handle the carry
+ adds ip, ip, #1
+ rev ip, ip
+ vmov \sreg, ip
+ bcc 0f
+ .endr
+0: teq r4, #0
+ beq .Lctrout
+ b .Lctrloop
+ENDPROC(ce_aes_ctr_encrypt)
+
+ /*
+ * aes_xts_encrypt(u8 out[], u8 const in[], u8 const rk1[], int rounds,
+ * int blocks, u8 iv[], u8 const rk2[], int first)
+ * aes_xts_decrypt(u8 out[], u8 const in[], u8 const rk1[], int rounds,
+ * int blocks, u8 iv[], u8 const rk2[], int first)
+ */
+
+ .macro next_tweak, out, in, const, tmp
+ vshr.s64 \tmp, \in, #63
+ vand \tmp, \tmp, \const
+ vadd.u64 \out, \in, \in
+ vext.8 \tmp, \tmp, \tmp, #8
+ veor \out, \out, \tmp
+ .endm
+
+ .align 3
+.Lxts_mul_x:
+ .quad 1, 0x87
+
+ce_aes_xts_init:
+ vldr d14, .Lxts_mul_x
+ vldr d15, .Lxts_mul_x + 8
+
+ ldrd r4, r5, [sp, #16] @ load args
+ ldr r6, [sp, #28]
+ vld1.8 {q0}, [r5] @ load iv
+ teq r6, #1 @ start of a block?
+ bxne lr
+
+ @ Encrypt the IV in q0 with the second AES key. This should only
+ @ be done at the start of a block.
+ ldr r6, [sp, #24] @ load AES key 2
+ prepare_key r6, r3
+ add ip, r6, #32 @ 3rd round key of key 2
+ b .Laes_encrypt_tweak @ tail call
+ENDPROC(ce_aes_xts_init)
+
+ENTRY(ce_aes_xts_encrypt)
+ push {r4-r6, lr}
+
+ bl ce_aes_xts_init @ run shared prologue
+ prepare_key r2, r3
+ vmov q3, q0
+
+ teq r6, #0 @ start of a block?
+ bne .Lxtsenc3x
+
+.Lxtsencloop3x:
+ next_tweak q3, q3, q7, q6
+.Lxtsenc3x:
+ subs r4, r4, #3
+ bmi .Lxtsenc1x
+ vld1.8 {q0-q1}, [r1, :64]! @ get 3 pt blocks
+ vld1.8 {q2}, [r1, :64]!
+ next_tweak q4, q3, q7, q6
+ veor q0, q0, q3
+ next_tweak q5, q4, q7, q6
+ veor q1, q1, q4
+ veor q2, q2, q5
+ bl aes_encrypt_3x
+ veor q0, q0, q3
+ veor q1, q1, q4
+ veor q2, q2, q5
+ vst1.8 {q0-q1}, [r0, :64]! @ write 3 ct blocks
+ vst1.8 {q2}, [r0, :64]!
+ vmov q3, q5
+ teq r4, #0
+ beq .Lxtsencout
+ b .Lxtsencloop3x
+.Lxtsenc1x:
+ adds r4, r4, #3
+ beq .Lxtsencout
+.Lxtsencloop:
+ vld1.8 {q0}, [r1, :64]!
+ veor q0, q0, q3
+ bl aes_encrypt
+ veor q0, q0, q3
+ vst1.8 {q0}, [r0, :64]!
+ subs r4, r4, #1
+ beq .Lxtsencout
+ next_tweak q3, q3, q7, q6
+ b .Lxtsencloop
+.Lxtsencout:
+ vst1.8 {q3}, [r5]
+ pop {r4-r6, pc}
+ENDPROC(ce_aes_xts_encrypt)
+
+
+ENTRY(ce_aes_xts_decrypt)
+ push {r4-r6, lr}
+
+ bl ce_aes_xts_init @ run shared prologue
+ prepare_key r2, r3
+ vmov q3, q0
+
+ teq r6, #0 @ start of a block?
+ bne .Lxtsdec3x
+
+.Lxtsdecloop3x:
+ next_tweak q3, q3, q7, q6
+.Lxtsdec3x:
+ subs r4, r4, #3
+ bmi .Lxtsdec1x
+ vld1.8 {q0-q1}, [r1, :64]! @ get 3 ct blocks
+ vld1.8 {q2}, [r1, :64]!
+ next_tweak q4, q3, q7, q6
+ veor q0, q0, q3
+ next_tweak q5, q4, q7, q6
+ veor q1, q1, q4
+ veor q2, q2, q5
+ bl aes_decrypt_3x
+ veor q0, q0, q3
+ veor q1, q1, q4
+ veor q2, q2, q5
+ vst1.8 {q0-q1}, [r0, :64]! @ write 3 pt blocks
+ vst1.8 {q2}, [r0, :64]!
+ vmov q3, q5
+ teq r4, #0
+ beq .Lxtsdecout
+ b .Lxtsdecloop3x
+.Lxtsdec1x:
+ adds r4, r4, #3
+ beq .Lxtsdecout
+.Lxtsdecloop:
+ vld1.8 {q0}, [r1, :64]!
+ veor q0, q0, q3
+ add ip, r2, #32 @ 3rd round key
+ bl aes_decrypt
+ veor q0, q0, q3
+ vst1.8 {q0}, [r0, :64]!
+ subs r4, r4, #1
+ beq .Lxtsdecout
+ next_tweak q3, q3, q7, q6
+ b .Lxtsdecloop
+.Lxtsdecout:
+ vst1.8 {q3}, [r5]
+ pop {r4-r6, pc}
+ENDPROC(ce_aes_xts_decrypt)
+
+ /*
+ * u32 ce_aes_sub(u32 input) - use the aese instruction to perform the
+ * AES sbox substitution on each byte in
+ * 'input'
+ */
+ENTRY(ce_aes_sub)
+ vdup.32 q1, r0
+ veor q0, q0, q0
+ aese.8 q0, q1
+ vmov r0, s0
+ bx lr
+ENDPROC(ce_aes_sub)
+
+ /*
+ * void ce_aes_invert(u8 *dst, u8 *src) - perform the Inverse MixColumns
+ * operation on round key *src
+ */
+ENTRY(ce_aes_invert)
+ vld1.8 {q0}, [r1]
+ aesimc.8 q0, q0
+ vst1.8 {q0}, [r0]
+ bx lr
+ENDPROC(ce_aes_invert)
diff --git a/arch/arm/crypto/aes-ce-glue.c b/arch/arm/crypto/aes-ce-glue.c
new file mode 100644
index 000000000..b445a5d56
--- /dev/null
+++ b/arch/arm/crypto/aes-ce-glue.c
@@ -0,0 +1,524 @@
+/*
+ * aes-ce-glue.c - wrapper code for ARMv8 AES
+ *
+ * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@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 <asm/hwcap.h>
+#include <asm/neon.h>
+#include <asm/hwcap.h>
+#include <crypto/aes.h>
+#include <crypto/ablk_helper.h>
+#include <crypto/algapi.h>
+#include <linux/module.h>
+
+MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 Crypto Extensions");
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_LICENSE("GPL v2");
+
+/* defined in aes-ce-core.S */
+asmlinkage u32 ce_aes_sub(u32 input);
+asmlinkage void ce_aes_invert(void *dst, void *src);
+
+asmlinkage void ce_aes_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[],
+ int rounds, int blocks);
+asmlinkage void ce_aes_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[],
+ int rounds, int blocks);
+
+asmlinkage void ce_aes_cbc_encrypt(u8 out[], u8 const in[], u8 const rk[],
+ int rounds, int blocks, u8 iv[]);
+asmlinkage void ce_aes_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
+ int rounds, int blocks, u8 iv[]);
+
+asmlinkage void ce_aes_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
+ int rounds, int blocks, u8 ctr[]);
+
+asmlinkage void ce_aes_xts_encrypt(u8 out[], u8 const in[], u8 const rk1[],
+ int rounds, int blocks, u8 iv[],
+ u8 const rk2[], int first);
+asmlinkage void ce_aes_xts_decrypt(u8 out[], u8 const in[], u8 const rk1[],
+ int rounds, int blocks, u8 iv[],
+ u8 const rk2[], int first);
+
+struct aes_block {
+ u8 b[AES_BLOCK_SIZE];
+};
+
+static int num_rounds(struct crypto_aes_ctx *ctx)
+{
+ /*
+ * # of rounds specified by AES:
+ * 128 bit key 10 rounds
+ * 192 bit key 12 rounds
+ * 256 bit key 14 rounds
+ * => n byte key => 6 + (n/4) rounds
+ */
+ return 6 + ctx->key_length / 4;
+}
+
+static int ce_aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key,
+ unsigned int key_len)
+{
+ /*
+ * The AES key schedule round constants
+ */
+ static u8 const rcon[] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36,
+ };
+
+ u32 kwords = key_len / sizeof(u32);
+ struct aes_block *key_enc, *key_dec;
+ int i, j;
+
+ if (key_len != AES_KEYSIZE_128 &&
+ key_len != AES_KEYSIZE_192 &&
+ key_len != AES_KEYSIZE_256)
+ return -EINVAL;
+
+ memcpy(ctx->key_enc, in_key, key_len);
+ ctx->key_length = key_len;
+
+ kernel_neon_begin();
+ for (i = 0; i < sizeof(rcon); i++) {
+ u32 *rki = ctx->key_enc + (i * kwords);
+ u32 *rko = rki + kwords;
+
+ rko[0] = ror32(ce_aes_sub(rki[kwords - 1]), 8);
+ rko[0] = rko[0] ^ rki[0] ^ rcon[i];
+ rko[1] = rko[0] ^ rki[1];
+ rko[2] = rko[1] ^ rki[2];
+ rko[3] = rko[2] ^ rki[3];
+
+ if (key_len == AES_KEYSIZE_192) {
+ if (i >= 7)
+ break;
+ rko[4] = rko[3] ^ rki[4];
+ rko[5] = rko[4] ^ rki[5];
+ } else if (key_len == AES_KEYSIZE_256) {
+ if (i >= 6)
+ break;
+ rko[4] = ce_aes_sub(rko[3]) ^ rki[4];
+ rko[5] = rko[4] ^ rki[5];
+ rko[6] = rko[5] ^ rki[6];
+ rko[7] = rko[6] ^ rki[7];
+ }
+ }
+
+ /*
+ * Generate the decryption keys for the Equivalent Inverse Cipher.
+ * This involves reversing the order of the round keys, and applying
+ * the Inverse Mix Columns transformation on all but the first and
+ * the last one.
+ */
+ key_enc = (struct aes_block *)ctx->key_enc;
+ key_dec = (struct aes_block *)ctx->key_dec;
+ j = num_rounds(ctx);
+
+ key_dec[0] = key_enc[j];
+ for (i = 1, j--; j > 0; i++, j--)
+ ce_aes_invert(key_dec + i, key_enc + j);
+ key_dec[i] = key_enc[0];
+
+ kernel_neon_end();
+ return 0;
+}
+
+static int ce_aes_setkey(struct crypto_tfm *tfm, const u8 *in_key,
+ unsigned int key_len)
+{
+ struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+ int ret;
+
+ ret = ce_aes_expandkey(ctx, in_key, key_len);
+ if (!ret)
+ return 0;
+
+ tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+}
+
+struct crypto_aes_xts_ctx {
+ struct crypto_aes_ctx key1;
+ struct crypto_aes_ctx __aligned(8) key2;
+};
+
+static int xts_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+ unsigned int key_len)
+{
+ struct crypto_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm);
+ int ret;
+
+ ret = ce_aes_expandkey(&ctx->key1, in_key, key_len / 2);
+ if (!ret)
+ ret = ce_aes_expandkey(&ctx->key2, &in_key[key_len / 2],
+ key_len / 2);
+ if (!ret)
+ return 0;
+
+ tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+}
+
+static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ unsigned int blocks;
+ int err;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ kernel_neon_begin();
+ while ((blocks = (walk.nbytes / AES_BLOCK_SIZE))) {
+ ce_aes_ecb_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
+ (u8 *)ctx->key_enc, num_rounds(ctx), blocks);
+ err = blkcipher_walk_done(desc, &walk,
+ walk.nbytes % AES_BLOCK_SIZE);
+ }
+ kernel_neon_end();
+ return err;
+}
+
+static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ unsigned int blocks;
+ int err;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ kernel_neon_begin();
+ while ((blocks = (walk.nbytes / AES_BLOCK_SIZE))) {
+ ce_aes_ecb_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
+ (u8 *)ctx->key_dec, num_rounds(ctx), blocks);
+ err = blkcipher_walk_done(desc, &walk,
+ walk.nbytes % AES_BLOCK_SIZE);
+ }
+ kernel_neon_end();
+ return err;
+}
+
+static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ unsigned int blocks;
+ int err;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ kernel_neon_begin();
+ while ((blocks = (walk.nbytes / AES_BLOCK_SIZE))) {
+ ce_aes_cbc_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
+ (u8 *)ctx->key_enc, num_rounds(ctx), blocks,
+ walk.iv);
+ err = blkcipher_walk_done(desc, &walk,
+ walk.nbytes % AES_BLOCK_SIZE);
+ }
+ kernel_neon_end();
+ return err;
+}
+
+static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ unsigned int blocks;
+ int err;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ kernel_neon_begin();
+ while ((blocks = (walk.nbytes / AES_BLOCK_SIZE))) {
+ ce_aes_cbc_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
+ (u8 *)ctx->key_dec, num_rounds(ctx), blocks,
+ walk.iv);
+ err = blkcipher_walk_done(desc, &walk,
+ walk.nbytes % AES_BLOCK_SIZE);
+ }
+ kernel_neon_end();
+ return err;
+}
+
+static int ctr_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err, blocks;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE);
+
+ kernel_neon_begin();
+ while ((blocks = (walk.nbytes / AES_BLOCK_SIZE))) {
+ ce_aes_ctr_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
+ (u8 *)ctx->key_enc, num_rounds(ctx), blocks,
+ walk.iv);
+ nbytes -= blocks * AES_BLOCK_SIZE;
+ if (nbytes && nbytes == walk.nbytes % AES_BLOCK_SIZE)
+ break;
+ err = blkcipher_walk_done(desc, &walk,
+ walk.nbytes % AES_BLOCK_SIZE);
+ }
+ if (nbytes) {
+ u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
+ u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
+ u8 __aligned(8) tail[AES_BLOCK_SIZE];
+
+ /*
+ * Minimum alignment is 8 bytes, so if nbytes is <= 8, we need
+ * to tell aes_ctr_encrypt() to only read half a block.
+ */
+ blocks = (nbytes <= 8) ? -1 : 1;
+
+ ce_aes_ctr_encrypt(tail, tsrc, (u8 *)ctx->key_enc,
+ num_rounds(ctx), blocks, walk.iv);
+ memcpy(tdst, tail, nbytes);
+ err = blkcipher_walk_done(desc, &walk, 0);
+ }
+ kernel_neon_end();
+
+ return err;
+}
+
+static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct crypto_aes_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ int err, first, rounds = num_rounds(&ctx->key1);
+ struct blkcipher_walk walk;
+ unsigned int blocks;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ kernel_neon_begin();
+ for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
+ ce_aes_xts_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
+ (u8 *)ctx->key1.key_enc, rounds, blocks,
+ walk.iv, (u8 *)ctx->key2.key_enc, first);
+ err = blkcipher_walk_done(desc, &walk,
+ walk.nbytes % AES_BLOCK_SIZE);
+ }
+ kernel_neon_end();
+
+ return err;
+}
+
+static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct crypto_aes_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ int err, first, rounds = num_rounds(&ctx->key1);
+ struct blkcipher_walk walk;
+ unsigned int blocks;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ kernel_neon_begin();
+ for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
+ ce_aes_xts_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
+ (u8 *)ctx->key1.key_dec, rounds, blocks,
+ walk.iv, (u8 *)ctx->key2.key_enc, first);
+ err = blkcipher_walk_done(desc, &walk,
+ walk.nbytes % AES_BLOCK_SIZE);
+ }
+ kernel_neon_end();
+
+ return err;
+}
+
+static struct crypto_alg aes_algs[] = { {
+ .cra_name = "__ecb-aes-ce",
+ .cra_driver_name = "__driver-ecb-aes-ce",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
+ CRYPTO_ALG_INTERNAL,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto_aes_ctx),
+ .cra_alignmask = 7,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_blkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = ce_aes_setkey,
+ .encrypt = ecb_encrypt,
+ .decrypt = ecb_decrypt,
+ },
+}, {
+ .cra_name = "__cbc-aes-ce",
+ .cra_driver_name = "__driver-cbc-aes-ce",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
+ CRYPTO_ALG_INTERNAL,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto_aes_ctx),
+ .cra_alignmask = 7,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_blkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = ce_aes_setkey,
+ .encrypt = cbc_encrypt,
+ .decrypt = cbc_decrypt,
+ },
+}, {
+ .cra_name = "__ctr-aes-ce",
+ .cra_driver_name = "__driver-ctr-aes-ce",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
+ CRYPTO_ALG_INTERNAL,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct crypto_aes_ctx),
+ .cra_alignmask = 7,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_blkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = ce_aes_setkey,
+ .encrypt = ctr_encrypt,
+ .decrypt = ctr_encrypt,
+ },
+}, {
+ .cra_name = "__xts-aes-ce",
+ .cra_driver_name = "__driver-xts-aes-ce",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
+ CRYPTO_ALG_INTERNAL,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto_aes_xts_ctx),
+ .cra_alignmask = 7,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_blkcipher = {
+ .min_keysize = 2 * AES_MIN_KEY_SIZE,
+ .max_keysize = 2 * AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = xts_set_key,
+ .encrypt = xts_encrypt,
+ .decrypt = xts_decrypt,
+ },
+}, {
+ .cra_name = "ecb(aes)",
+ .cra_driver_name = "ecb-aes-ce",
+ .cra_priority = 300,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_helper_ctx),
+ .cra_alignmask = 7,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = ablk_init,
+ .cra_exit = ablk_exit,
+ .cra_ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ }
+}, {
+ .cra_name = "cbc(aes)",
+ .cra_driver_name = "cbc-aes-ce",
+ .cra_priority = 300,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_helper_ctx),
+ .cra_alignmask = 7,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = ablk_init,
+ .cra_exit = ablk_exit,
+ .cra_ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ }
+}, {
+ .cra_name = "ctr(aes)",
+ .cra_driver_name = "ctr-aes-ce",
+ .cra_priority = 300,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct async_helper_ctx),
+ .cra_alignmask = 7,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = ablk_init,
+ .cra_exit = ablk_exit,
+ .cra_ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ }
+}, {
+ .cra_name = "xts(aes)",
+ .cra_driver_name = "xts-aes-ce",
+ .cra_priority = 300,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_helper_ctx),
+ .cra_alignmask = 7,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = ablk_init,
+ .cra_exit = ablk_exit,
+ .cra_ablkcipher = {
+ .min_keysize = 2 * AES_MIN_KEY_SIZE,
+ .max_keysize = 2 * AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ }
+} };
+
+static int __init aes_init(void)
+{
+ if (!(elf_hwcap2 & HWCAP2_AES))
+ return -ENODEV;
+ return crypto_register_algs(aes_algs, ARRAY_SIZE(aes_algs));
+}
+
+static void __exit aes_exit(void)
+{
+ crypto_unregister_algs(aes_algs, ARRAY_SIZE(aes_algs));
+}
+
+module_init(aes_init);
+module_exit(aes_exit);
diff --git a/arch/arm/crypto/aes_glue.c b/arch/arm/crypto/aes_glue.c
new file mode 100644
index 000000000..0409b8f89
--- /dev/null
+++ b/arch/arm/crypto/aes_glue.c
@@ -0,0 +1,98 @@
+/*
+ * Glue Code for the asm optimized version of the AES Cipher Algorithm
+ */
+
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include <crypto/aes.h>
+
+#include "aes_glue.h"
+
+EXPORT_SYMBOL(AES_encrypt);
+EXPORT_SYMBOL(AES_decrypt);
+EXPORT_SYMBOL(private_AES_set_encrypt_key);
+EXPORT_SYMBOL(private_AES_set_decrypt_key);
+
+static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ struct AES_CTX *ctx = crypto_tfm_ctx(tfm);
+ AES_encrypt(src, dst, &ctx->enc_key);
+}
+
+static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ struct AES_CTX *ctx = crypto_tfm_ctx(tfm);
+ AES_decrypt(src, dst, &ctx->dec_key);
+}
+
+static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+ unsigned int key_len)
+{
+ struct AES_CTX *ctx = crypto_tfm_ctx(tfm);
+
+ switch (key_len) {
+ case AES_KEYSIZE_128:
+ key_len = 128;
+ break;
+ case AES_KEYSIZE_192:
+ key_len = 192;
+ break;
+ case AES_KEYSIZE_256:
+ key_len = 256;
+ break;
+ default:
+ tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+
+ if (private_AES_set_encrypt_key(in_key, key_len, &ctx->enc_key) == -1) {
+ tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+ /* private_AES_set_decrypt_key expects an encryption key as input */
+ ctx->dec_key = ctx->enc_key;
+ if (private_AES_set_decrypt_key(in_key, key_len, &ctx->dec_key) == -1) {
+ tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static struct crypto_alg aes_alg = {
+ .cra_name = "aes",
+ .cra_driver_name = "aes-asm",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct AES_CTX),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = AES_MIN_KEY_SIZE,
+ .cia_max_keysize = AES_MAX_KEY_SIZE,
+ .cia_setkey = aes_set_key,
+ .cia_encrypt = aes_encrypt,
+ .cia_decrypt = aes_decrypt
+ }
+ }
+};
+
+static int __init aes_init(void)
+{
+ return crypto_register_alg(&aes_alg);
+}
+
+static void __exit aes_fini(void)
+{
+ crypto_unregister_alg(&aes_alg);
+}
+
+module_init(aes_init);
+module_exit(aes_fini);
+
+MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm (ASM)");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_CRYPTO("aes");
+MODULE_ALIAS_CRYPTO("aes-asm");
+MODULE_AUTHOR("David McCullough <ucdevel@gmail.com>");
diff --git a/arch/arm/crypto/aes_glue.h b/arch/arm/crypto/aes_glue.h
new file mode 100644
index 000000000..cca3e51eb
--- /dev/null
+++ b/arch/arm/crypto/aes_glue.h
@@ -0,0 +1,19 @@
+
+#define AES_MAXNR 14
+
+struct AES_KEY {
+ unsigned int rd_key[4 * (AES_MAXNR + 1)];
+ int rounds;
+};
+
+struct AES_CTX {
+ struct AES_KEY enc_key;
+ struct AES_KEY dec_key;
+};
+
+asmlinkage void AES_encrypt(const u8 *in, u8 *out, struct AES_KEY *ctx);
+asmlinkage void AES_decrypt(const u8 *in, u8 *out, struct AES_KEY *ctx);
+asmlinkage int private_AES_set_decrypt_key(const unsigned char *userKey,
+ const int bits, struct AES_KEY *key);
+asmlinkage int private_AES_set_encrypt_key(const unsigned char *userKey,
+ const int bits, struct AES_KEY *key);
diff --git a/arch/arm/crypto/aesbs-core.S_shipped b/arch/arm/crypto/aesbs-core.S_shipped
new file mode 100644
index 000000000..1d1800f71
--- /dev/null
+++ b/arch/arm/crypto/aesbs-core.S_shipped
@@ -0,0 +1,2548 @@
+
+@ ====================================================================
+@ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+@ project. The module is, however, dual licensed under OpenSSL and
+@ CRYPTOGAMS licenses depending on where you obtain it. For further
+@ details see http://www.openssl.org/~appro/cryptogams/.
+@
+@ Specific modes and adaptation for Linux kernel by Ard Biesheuvel
+@ <ard.biesheuvel@linaro.org>. Permission to use under GPL terms is
+@ granted.
+@ ====================================================================
+
+@ Bit-sliced AES for ARM NEON
+@
+@ February 2012.
+@
+@ This implementation is direct adaptation of bsaes-x86_64 module for
+@ ARM NEON. Except that this module is endian-neutral [in sense that
+@ it can be compiled for either endianness] by courtesy of vld1.8's
+@ neutrality. Initial version doesn't implement interface to OpenSSL,
+@ only low-level primitives and unsupported entry points, just enough
+@ to collect performance results, which for Cortex-A8 core are:
+@
+@ encrypt 19.5 cycles per byte processed with 128-bit key
+@ decrypt 22.1 cycles per byte processed with 128-bit key
+@ key conv. 440 cycles per 128-bit key/0.18 of 8x block
+@
+@ Snapdragon S4 encrypts byte in 17.6 cycles and decrypts in 19.7,
+@ which is [much] worse than anticipated (for further details see
+@ http://www.openssl.org/~appro/Snapdragon-S4.html).
+@
+@ Cortex-A15 manages in 14.2/16.1 cycles [when integer-only code
+@ manages in 20.0 cycles].
+@
+@ When comparing to x86_64 results keep in mind that NEON unit is
+@ [mostly] single-issue and thus can't [fully] benefit from
+@ instruction-level parallelism. And when comparing to aes-armv4
+@ results keep in mind key schedule conversion overhead (see
+@ bsaes-x86_64.pl for further details)...
+@
+@ <appro@openssl.org>
+
+@ April-August 2013
+@
+@ Add CBC, CTR and XTS subroutines, adapt for kernel use.
+@
+@ <ard.biesheuvel@linaro.org>
+
+#ifndef __KERNEL__
+# include "arm_arch.h"
+
+# define VFP_ABI_PUSH vstmdb sp!,{d8-d15}
+# define VFP_ABI_POP vldmia sp!,{d8-d15}
+# define VFP_ABI_FRAME 0x40
+#else
+# define VFP_ABI_PUSH
+# define VFP_ABI_POP
+# define VFP_ABI_FRAME 0
+# define BSAES_ASM_EXTENDED_KEY
+# define XTS_CHAIN_TWEAK
+# define __ARM_ARCH__ __LINUX_ARM_ARCH__
+# define __ARM_MAX_ARCH__ 7
+#endif
+
+#ifdef __thumb__
+# define adrl adr
+#endif
+
+#if __ARM_MAX_ARCH__>=7
+.arch armv7-a
+.fpu neon
+
+.text
+.syntax unified @ ARMv7-capable assembler is expected to handle this
+#ifdef __thumb2__
+.thumb
+#else
+.code 32
+#endif
+
+.type _bsaes_decrypt8,%function
+.align 4
+_bsaes_decrypt8:
+ adr r6,_bsaes_decrypt8
+ vldmia r4!, {q9} @ round 0 key
+ add r6,r6,#.LM0ISR-_bsaes_decrypt8
+
+ vldmia r6!, {q8} @ .LM0ISR
+ veor q10, q0, q9 @ xor with round0 key
+ veor q11, q1, q9
+ vtbl.8 d0, {q10}, d16
+ vtbl.8 d1, {q10}, d17
+ veor q12, q2, q9
+ vtbl.8 d2, {q11}, d16
+ vtbl.8 d3, {q11}, d17
+ veor q13, q3, q9
+ vtbl.8 d4, {q12}, d16
+ vtbl.8 d5, {q12}, d17
+ veor q14, q4, q9
+ vtbl.8 d6, {q13}, d16
+ vtbl.8 d7, {q13}, d17
+ veor q15, q5, q9
+ vtbl.8 d8, {q14}, d16
+ vtbl.8 d9, {q14}, d17
+ veor q10, q6, q9
+ vtbl.8 d10, {q15}, d16
+ vtbl.8 d11, {q15}, d17
+ veor q11, q7, q9
+ vtbl.8 d12, {q10}, d16
+ vtbl.8 d13, {q10}, d17
+ vtbl.8 d14, {q11}, d16
+ vtbl.8 d15, {q11}, d17
+ vmov.i8 q8,#0x55 @ compose .LBS0
+ vmov.i8 q9,#0x33 @ compose .LBS1
+ vshr.u64 q10, q6, #1
+ vshr.u64 q11, q4, #1
+ veor q10, q10, q7
+ veor q11, q11, q5
+ vand q10, q10, q8
+ vand q11, q11, q8
+ veor q7, q7, q10
+ vshl.u64 q10, q10, #1
+ veor q5, q5, q11
+ vshl.u64 q11, q11, #1
+ veor q6, q6, q10
+ veor q4, q4, q11
+ vshr.u64 q10, q2, #1
+ vshr.u64 q11, q0, #1
+ veor q10, q10, q3
+ veor q11, q11, q1
+ vand q10, q10, q8
+ vand q11, q11, q8
+ veor q3, q3, q10
+ vshl.u64 q10, q10, #1
+ veor q1, q1, q11
+ vshl.u64 q11, q11, #1
+ veor q2, q2, q10
+ veor q0, q0, q11
+ vmov.i8 q8,#0x0f @ compose .LBS2
+ vshr.u64 q10, q5, #2
+ vshr.u64 q11, q4, #2
+ veor q10, q10, q7
+ veor q11, q11, q6
+ vand q10, q10, q9
+ vand q11, q11, q9
+ veor q7, q7, q10
+ vshl.u64 q10, q10, #2
+ veor q6, q6, q11
+ vshl.u64 q11, q11, #2
+ veor q5, q5, q10
+ veor q4, q4, q11
+ vshr.u64 q10, q1, #2
+ vshr.u64 q11, q0, #2
+ veor q10, q10, q3
+ veor q11, q11, q2
+ vand q10, q10, q9
+ vand q11, q11, q9
+ veor q3, q3, q10
+ vshl.u64 q10, q10, #2
+ veor q2, q2, q11
+ vshl.u64 q11, q11, #2
+ veor q1, q1, q10
+ veor q0, q0, q11
+ vshr.u64 q10, q3, #4
+ vshr.u64 q11, q2, #4
+ veor q10, q10, q7
+ veor q11, q11, q6
+ vand q10, q10, q8
+ vand q11, q11, q8
+ veor q7, q7, q10
+ vshl.u64 q10, q10, #4
+ veor q6, q6, q11
+ vshl.u64 q11, q11, #4
+ veor q3, q3, q10
+ veor q2, q2, q11
+ vshr.u64 q10, q1, #4
+ vshr.u64 q11, q0, #4
+ veor q10, q10, q5
+ veor q11, q11, q4
+ vand q10, q10, q8
+ vand q11, q11, q8
+ veor q5, q5, q10
+ vshl.u64 q10, q10, #4
+ veor q4, q4, q11
+ vshl.u64 q11, q11, #4
+ veor q1, q1, q10
+ veor q0, q0, q11
+ sub r5,r5,#1
+ b .Ldec_sbox
+.align 4
+.Ldec_loop:
+ vldmia r4!, {q8-q11}
+ veor q8, q8, q0
+ veor q9, q9, q1
+ vtbl.8 d0, {q8}, d24
+ vtbl.8 d1, {q8}, d25
+ vldmia r4!, {q8}
+ veor q10, q10, q2
+ vtbl.8 d2, {q9}, d24
+ vtbl.8 d3, {q9}, d25
+ vldmia r4!, {q9}
+ veor q11, q11, q3
+ vtbl.8 d4, {q10}, d24
+ vtbl.8 d5, {q10}, d25
+ vldmia r4!, {q10}
+ vtbl.8 d6, {q11}, d24
+ vtbl.8 d7, {q11}, d25
+ vldmia r4!, {q11}
+ veor q8, q8, q4
+ veor q9, q9, q5
+ vtbl.8 d8, {q8}, d24
+ vtbl.8 d9, {q8}, d25
+ veor q10, q10, q6
+ vtbl.8 d10, {q9}, d24
+ vtbl.8 d11, {q9}, d25
+ veor q11, q11, q7
+ vtbl.8 d12, {q10}, d24
+ vtbl.8 d13, {q10}, d25
+ vtbl.8 d14, {q11}, d24
+ vtbl.8 d15, {q11}, d25
+.Ldec_sbox:
+ veor q1, q1, q4
+ veor q3, q3, q4
+
+ veor q4, q4, q7
+ veor q1, q1, q6
+ veor q2, q2, q7
+ veor q6, q6, q4
+
+ veor q0, q0, q1
+ veor q2, q2, q5
+ veor q7, q7, q6
+ veor q3, q3, q0
+ veor q5, q5, q0
+ veor q1, q1, q3
+ veor q11, q3, q0
+ veor q10, q7, q4
+ veor q9, q1, q6
+ veor q13, q4, q0
+ vmov q8, q10
+ veor q12, q5, q2
+
+ vorr q10, q10, q9
+ veor q15, q11, q8
+ vand q14, q11, q12
+ vorr q11, q11, q12
+ veor q12, q12, q9
+ vand q8, q8, q9
+ veor q9, q6, q2
+ vand q15, q15, q12
+ vand q13, q13, q9
+ veor q9, q3, q7
+ veor q12, q1, q5
+ veor q11, q11, q13
+ veor q10, q10, q13
+ vand q13, q9, q12
+ vorr q9, q9, q12
+ veor q11, q11, q15
+ veor q8, q8, q13
+ veor q10, q10, q14
+ veor q9, q9, q15
+ veor q8, q8, q14
+ vand q12, q4, q6
+ veor q9, q9, q14
+ vand q13, q0, q2
+ vand q14, q7, q1
+ vorr q15, q3, q5
+ veor q11, q11, q12
+ veor q9, q9, q14
+ veor q8, q8, q15
+ veor q10, q10, q13
+
+ @ Inv_GF16 0, 1, 2, 3, s0, s1, s2, s3
+
+ @ new smaller inversion
+
+ vand q14, q11, q9
+ vmov q12, q8
+
+ veor q13, q10, q14
+ veor q15, q8, q14
+ veor q14, q8, q14 @ q14=q15
+
+ vbsl q13, q9, q8
+ vbsl q15, q11, q10
+ veor q11, q11, q10
+
+ vbsl q12, q13, q14
+ vbsl q8, q14, q13
+
+ vand q14, q12, q15
+ veor q9, q9, q8
+
+ veor q14, q14, q11
+ veor q12, q5, q2
+ veor q8, q1, q6
+ veor q10, q15, q14
+ vand q10, q10, q5
+ veor q5, q5, q1
+ vand q11, q1, q15
+ vand q5, q5, q14
+ veor q1, q11, q10
+ veor q5, q5, q11
+ veor q15, q15, q13
+ veor q14, q14, q9
+ veor q11, q15, q14
+ veor q10, q13, q9
+ vand q11, q11, q12
+ vand q10, q10, q2
+ veor q12, q12, q8
+ veor q2, q2, q6
+ vand q8, q8, q15
+ vand q6, q6, q13
+ vand q12, q12, q14
+ vand q2, q2, q9
+ veor q8, q8, q12
+ veor q2, q2, q6
+ veor q12, q12, q11
+ veor q6, q6, q10
+ veor q5, q5, q12
+ veor q2, q2, q12
+ veor q1, q1, q8
+ veor q6, q6, q8
+
+ veor q12, q3, q0
+ veor q8, q7, q4
+ veor q11, q15, q14
+ veor q10, q13, q9
+ vand q11, q11, q12
+ vand q10, q10, q0
+ veor q12, q12, q8
+ veor q0, q0, q4
+ vand q8, q8, q15
+ vand q4, q4, q13
+ vand q12, q12, q14
+ vand q0, q0, q9
+ veor q8, q8, q12
+ veor q0, q0, q4
+ veor q12, q12, q11
+ veor q4, q4, q10
+ veor q15, q15, q13
+ veor q14, q14, q9
+ veor q10, q15, q14
+ vand q10, q10, q3
+ veor q3, q3, q7
+ vand q11, q7, q15
+ vand q3, q3, q14
+ veor q7, q11, q10
+ veor q3, q3, q11
+ veor q3, q3, q12
+ veor q0, q0, q12
+ veor q7, q7, q8
+ veor q4, q4, q8
+ veor q1, q1, q7
+ veor q6, q6, q5
+
+ veor q4, q4, q1
+ veor q2, q2, q7
+ veor q5, q5, q7
+ veor q4, q4, q2
+ veor q7, q7, q0
+ veor q4, q4, q5
+ veor q3, q3, q6
+ veor q6, q6, q1
+ veor q3, q3, q4
+
+ veor q4, q4, q0
+ veor q7, q7, q3
+ subs r5,r5,#1
+ bcc .Ldec_done
+ @ multiplication by 0x05-0x00-0x04-0x00
+ vext.8 q8, q0, q0, #8
+ vext.8 q14, q3, q3, #8
+ vext.8 q15, q5, q5, #8
+ veor q8, q8, q0
+ vext.8 q9, q1, q1, #8
+ veor q14, q14, q3
+ vext.8 q10, q6, q6, #8
+ veor q15, q15, q5
+ vext.8 q11, q4, q4, #8
+ veor q9, q9, q1
+ vext.8 q12, q2, q2, #8
+ veor q10, q10, q6
+ vext.8 q13, q7, q7, #8
+ veor q11, q11, q4
+ veor q12, q12, q2
+ veor q13, q13, q7
+
+ veor q0, q0, q14
+ veor q1, q1, q14
+ veor q6, q6, q8
+ veor q2, q2, q10
+ veor q4, q4, q9
+ veor q1, q1, q15
+ veor q6, q6, q15
+ veor q2, q2, q14
+ veor q7, q7, q11
+ veor q4, q4, q14
+ veor q3, q3, q12
+ veor q2, q2, q15
+ veor q7, q7, q15
+ veor q5, q5, q13
+ vext.8 q8, q0, q0, #12 @ x0 <<< 32
+ vext.8 q9, q1, q1, #12
+ veor q0, q0, q8 @ x0 ^ (x0 <<< 32)
+ vext.8 q10, q6, q6, #12
+ veor q1, q1, q9
+ vext.8 q11, q4, q4, #12
+ veor q6, q6, q10
+ vext.8 q12, q2, q2, #12
+ veor q4, q4, q11
+ vext.8 q13, q7, q7, #12
+ veor q2, q2, q12
+ vext.8 q14, q3, q3, #12
+ veor q7, q7, q13
+ vext.8 q15, q5, q5, #12
+ veor q3, q3, q14
+
+ veor q9, q9, q0
+ veor q5, q5, q15
+ vext.8 q0, q0, q0, #8 @ (x0 ^ (x0 <<< 32)) <<< 64)
+ veor q10, q10, q1
+ veor q8, q8, q5
+ veor q9, q9, q5
+ vext.8 q1, q1, q1, #8
+ veor q13, q13, q2
+ veor q0, q0, q8
+ veor q14, q14, q7
+ veor q1, q1, q9
+ vext.8 q8, q2, q2, #8
+ veor q12, q12, q4
+ vext.8 q9, q7, q7, #8
+ veor q15, q15, q3
+ vext.8 q2, q4, q4, #8
+ veor q11, q11, q6
+ vext.8 q7, q5, q5, #8
+ veor q12, q12, q5
+ vext.8 q4, q3, q3, #8
+ veor q11, q11, q5
+ vext.8 q3, q6, q6, #8
+ veor q5, q9, q13
+ veor q11, q11, q2
+ veor q7, q7, q15
+ veor q6, q4, q14
+ veor q4, q8, q12
+ veor q2, q3, q10
+ vmov q3, q11
+ @ vmov q5, q9
+ vldmia r6, {q12} @ .LISR
+ ite eq @ Thumb2 thing, sanity check in ARM
+ addeq r6,r6,#0x10
+ bne .Ldec_loop
+ vldmia r6, {q12} @ .LISRM0
+ b .Ldec_loop
+.align 4
+.Ldec_done:
+ vmov.i8 q8,#0x55 @ compose .LBS0
+ vmov.i8 q9,#0x33 @ compose .LBS1
+ vshr.u64 q10, q3, #1
+ vshr.u64 q11, q2, #1
+ veor q10, q10, q5
+ veor q11, q11, q7
+ vand q10, q10, q8
+ vand q11, q11, q8
+ veor q5, q5, q10
+ vshl.u64 q10, q10, #1
+ veor q7, q7, q11
+ vshl.u64 q11, q11, #1
+ veor q3, q3, q10
+ veor q2, q2, q11
+ vshr.u64 q10, q6, #1
+ vshr.u64 q11, q0, #1
+ veor q10, q10, q4
+ veor q11, q11, q1
+ vand q10, q10, q8
+ vand q11, q11, q8
+ veor q4, q4, q10
+ vshl.u64 q10, q10, #1
+ veor q1, q1, q11
+ vshl.u64 q11, q11, #1
+ veor q6, q6, q10
+ veor q0, q0, q11
+ vmov.i8 q8,#0x0f @ compose .LBS2
+ vshr.u64 q10, q7, #2
+ vshr.u64 q11, q2, #2
+ veor q10, q10, q5
+ veor q11, q11, q3
+ vand q10, q10, q9
+ vand q11, q11, q9
+ veor q5, q5, q10
+ vshl.u64 q10, q10, #2
+ veor q3, q3, q11
+ vshl.u64 q11, q11, #2
+ veor q7, q7, q10
+ veor q2, q2, q11
+ vshr.u64 q10, q1, #2
+ vshr.u64 q11, q0, #2
+ veor q10, q10, q4
+ veor q11, q11, q6
+ vand q10, q10, q9
+ vand q11, q11, q9
+ veor q4, q4, q10
+ vshl.u64 q10, q10, #2
+ veor q6, q6, q11
+ vshl.u64 q11, q11, #2
+ veor q1, q1, q10
+ veor q0, q0, q11
+ vshr.u64 q10, q4, #4
+ vshr.u64 q11, q6, #4
+ veor q10, q10, q5
+ veor q11, q11, q3
+ vand q10, q10, q8
+ vand q11, q11, q8
+ veor q5, q5, q10
+ vshl.u64 q10, q10, #4
+ veor q3, q3, q11
+ vshl.u64 q11, q11, #4
+ veor q4, q4, q10
+ veor q6, q6, q11
+ vshr.u64 q10, q1, #4
+ vshr.u64 q11, q0, #4
+ veor q10, q10, q7
+ veor q11, q11, q2
+ vand q10, q10, q8
+ vand q11, q11, q8
+ veor q7, q7, q10
+ vshl.u64 q10, q10, #4
+ veor q2, q2, q11
+ vshl.u64 q11, q11, #4
+ veor q1, q1, q10
+ veor q0, q0, q11
+ vldmia r4, {q8} @ last round key
+ veor q6, q6, q8
+ veor q4, q4, q8
+ veor q2, q2, q8
+ veor q7, q7, q8
+ veor q3, q3, q8
+ veor q5, q5, q8
+ veor q0, q0, q8
+ veor q1, q1, q8
+ bx lr
+.size _bsaes_decrypt8,.-_bsaes_decrypt8
+
+.type _bsaes_const,%object
+.align 6
+_bsaes_const:
+.LM0ISR: @ InvShiftRows constants
+ .quad 0x0a0e0206070b0f03, 0x0004080c0d010509
+.LISR:
+ .quad 0x0504070602010003, 0x0f0e0d0c080b0a09
+.LISRM0:
+ .quad 0x01040b0e0205080f, 0x0306090c00070a0d
+.LM0SR: @ ShiftRows constants
+ .quad 0x0a0e02060f03070b, 0x0004080c05090d01
+.LSR:
+ .quad 0x0504070600030201, 0x0f0e0d0c0a09080b
+.LSRM0:
+ .quad 0x0304090e00050a0f, 0x01060b0c0207080d
+.LM0:
+ .quad 0x02060a0e03070b0f, 0x0004080c0105090d
+.LREVM0SR:
+ .quad 0x090d01050c000408, 0x03070b0f060a0e02
+.asciz "Bit-sliced AES for NEON, CRYPTOGAMS by <appro@openssl.org>"
+.align 6
+.size _bsaes_const,.-_bsaes_const
+
+.type _bsaes_encrypt8,%function
+.align 4
+_bsaes_encrypt8:
+ adr r6,_bsaes_encrypt8
+ vldmia r4!, {q9} @ round 0 key
+ sub r6,r6,#_bsaes_encrypt8-.LM0SR
+
+ vldmia r6!, {q8} @ .LM0SR
+_bsaes_encrypt8_alt:
+ veor q10, q0, q9 @ xor with round0 key
+ veor q11, q1, q9
+ vtbl.8 d0, {q10}, d16
+ vtbl.8 d1, {q10}, d17
+ veor q12, q2, q9
+ vtbl.8 d2, {q11}, d16
+ vtbl.8 d3, {q11}, d17
+ veor q13, q3, q9
+ vtbl.8 d4, {q12}, d16
+ vtbl.8 d5, {q12}, d17
+ veor q14, q4, q9
+ vtbl.8 d6, {q13}, d16
+ vtbl.8 d7, {q13}, d17
+ veor q15, q5, q9
+ vtbl.8 d8, {q14}, d16
+ vtbl.8 d9, {q14}, d17
+ veor q10, q6, q9
+ vtbl.8 d10, {q15}, d16
+ vtbl.8 d11, {q15}, d17
+ veor q11, q7, q9
+ vtbl.8 d12, {q10}, d16
+ vtbl.8 d13, {q10}, d17
+ vtbl.8 d14, {q11}, d16
+ vtbl.8 d15, {q11}, d17
+_bsaes_encrypt8_bitslice:
+ vmov.i8 q8,#0x55 @ compose .LBS0
+ vmov.i8 q9,#0x33 @ compose .LBS1
+ vshr.u64 q10, q6, #1
+ vshr.u64 q11, q4, #1
+ veor q10, q10, q7
+ veor q11, q11, q5
+ vand q10, q10, q8
+ vand q11, q11, q8
+ veor q7, q7, q10
+ vshl.u64 q10, q10, #1
+ veor q5, q5, q11
+ vshl.u64 q11, q11, #1
+ veor q6, q6, q10
+ veor q4, q4, q11
+ vshr.u64 q10, q2, #1
+ vshr.u64 q11, q0, #1
+ veor q10, q10, q3
+ veor q11, q11, q1
+ vand q10, q10, q8
+ vand q11, q11, q8
+ veor q3, q3, q10
+ vshl.u64 q10, q10, #1
+ veor q1, q1, q11
+ vshl.u64 q11, q11, #1
+ veor q2, q2, q10
+ veor q0, q0, q11
+ vmov.i8 q8,#0x0f @ compose .LBS2
+ vshr.u64 q10, q5, #2
+ vshr.u64 q11, q4, #2
+ veor q10, q10, q7
+ veor q11, q11, q6
+ vand q10, q10, q9
+ vand q11, q11, q9
+ veor q7, q7, q10
+ vshl.u64 q10, q10, #2
+ veor q6, q6, q11
+ vshl.u64 q11, q11, #2
+ veor q5, q5, q10
+ veor q4, q4, q11
+ vshr.u64 q10, q1, #2
+ vshr.u64 q11, q0, #2
+ veor q10, q10, q3
+ veor q11, q11, q2
+ vand q10, q10, q9
+ vand q11, q11, q9
+ veor q3, q3, q10
+ vshl.u64 q10, q10, #2
+ veor q2, q2, q11
+ vshl.u64 q11, q11, #2
+ veor q1, q1, q10
+ veor q0, q0, q11
+ vshr.u64 q10, q3, #4
+ vshr.u64 q11, q2, #4
+ veor q10, q10, q7
+ veor q11, q11, q6
+ vand q10, q10, q8
+ vand q11, q11, q8
+ veor q7, q7, q10
+ vshl.u64 q10, q10, #4
+ veor q6, q6, q11
+ vshl.u64 q11, q11, #4
+ veor q3, q3, q10
+ veor q2, q2, q11
+ vshr.u64 q10, q1, #4
+ vshr.u64 q11, q0, #4
+ veor q10, q10, q5
+ veor q11, q11, q4
+ vand q10, q10, q8
+ vand q11, q11, q8
+ veor q5, q5, q10
+ vshl.u64 q10, q10, #4
+ veor q4, q4, q11
+ vshl.u64 q11, q11, #4
+ veor q1, q1, q10
+ veor q0, q0, q11
+ sub r5,r5,#1
+ b .Lenc_sbox
+.align 4
+.Lenc_loop:
+ vldmia r4!, {q8-q11}
+ veor q8, q8, q0
+ veor q9, q9, q1
+ vtbl.8 d0, {q8}, d24
+ vtbl.8 d1, {q8}, d25
+ vldmia r4!, {q8}
+ veor q10, q10, q2
+ vtbl.8 d2, {q9}, d24
+ vtbl.8 d3, {q9}, d25
+ vldmia r4!, {q9}
+ veor q11, q11, q3
+ vtbl.8 d4, {q10}, d24
+ vtbl.8 d5, {q10}, d25
+ vldmia r4!, {q10}
+ vtbl.8 d6, {q11}, d24
+ vtbl.8 d7, {q11}, d25
+ vldmia r4!, {q11}
+ veor q8, q8, q4
+ veor q9, q9, q5
+ vtbl.8 d8, {q8}, d24
+ vtbl.8 d9, {q8}, d25
+ veor q10, q10, q6
+ vtbl.8 d10, {q9}, d24
+ vtbl.8 d11, {q9}, d25
+ veor q11, q11, q7
+ vtbl.8 d12, {q10}, d24
+ vtbl.8 d13, {q10}, d25
+ vtbl.8 d14, {q11}, d24
+ vtbl.8 d15, {q11}, d25
+.Lenc_sbox:
+ veor q2, q2, q1
+ veor q5, q5, q6
+ veor q3, q3, q0
+ veor q6, q6, q2
+ veor q5, q5, q0
+
+ veor q6, q6, q3
+ veor q3, q3, q7
+ veor q7, q7, q5
+ veor q3, q3, q4
+ veor q4, q4, q5
+
+ veor q2, q2, q7
+ veor q3, q3, q1
+ veor q1, q1, q5
+ veor q11, q7, q4
+ veor q10, q1, q2
+ veor q9, q5, q3
+ veor q13, q2, q4
+ vmov q8, q10
+ veor q12, q6, q0
+
+ vorr q10, q10, q9
+ veor q15, q11, q8
+ vand q14, q11, q12
+ vorr q11, q11, q12
+ veor q12, q12, q9
+ vand q8, q8, q9
+ veor q9, q3, q0
+ vand q15, q15, q12
+ vand q13, q13, q9
+ veor q9, q7, q1
+ veor q12, q5, q6
+ veor q11, q11, q13
+ veor q10, q10, q13
+ vand q13, q9, q12
+ vorr q9, q9, q12
+ veor q11, q11, q15
+ veor q8, q8, q13
+ veor q10, q10, q14
+ veor q9, q9, q15
+ veor q8, q8, q14
+ vand q12, q2, q3
+ veor q9, q9, q14
+ vand q13, q4, q0
+ vand q14, q1, q5
+ vorr q15, q7, q6
+ veor q11, q11, q12
+ veor q9, q9, q14
+ veor q8, q8, q15
+ veor q10, q10, q13
+
+ @ Inv_GF16 0, 1, 2, 3, s0, s1, s2, s3
+
+ @ new smaller inversion
+
+ vand q14, q11, q9
+ vmov q12, q8
+
+ veor q13, q10, q14
+ veor q15, q8, q14
+ veor q14, q8, q14 @ q14=q15
+
+ vbsl q13, q9, q8
+ vbsl q15, q11, q10
+ veor q11, q11, q10
+
+ vbsl q12, q13, q14
+ vbsl q8, q14, q13
+
+ vand q14, q12, q15
+ veor q9, q9, q8
+
+ veor q14, q14, q11
+ veor q12, q6, q0
+ veor q8, q5, q3
+ veor q10, q15, q14
+ vand q10, q10, q6
+ veor q6, q6, q5
+ vand q11, q5, q15
+ vand q6, q6, q14
+ veor q5, q11, q10
+ veor q6, q6, q11
+ veor q15, q15, q13
+ veor q14, q14, q9
+ veor q11, q15, q14
+ veor q10, q13, q9
+ vand q11, q11, q12
+ vand q10, q10, q0
+ veor q12, q12, q8
+ veor q0, q0, q3
+ vand q8, q8, q15
+ vand q3, q3, q13
+ vand q12, q12, q14
+ vand q0, q0, q9
+ veor q8, q8, q12
+ veor q0, q0, q3
+ veor q12, q12, q11
+ veor q3, q3, q10
+ veor q6, q6, q12
+ veor q0, q0, q12
+ veor q5, q5, q8
+ veor q3, q3, q8
+
+ veor q12, q7, q4
+ veor q8, q1, q2
+ veor q11, q15, q14
+ veor q10, q13, q9
+ vand q11, q11, q12
+ vand q10, q10, q4
+ veor q12, q12, q8
+ veor q4, q4, q2
+ vand q8, q8, q15
+ vand q2, q2, q13
+ vand q12, q12, q14
+ vand q4, q4, q9
+ veor q8, q8, q12
+ veor q4, q4, q2
+ veor q12, q12, q11
+ veor q2, q2, q10
+ veor q15, q15, q13
+ veor q14, q14, q9
+ veor q10, q15, q14
+ vand q10, q10, q7
+ veor q7, q7, q1
+ vand q11, q1, q15
+ vand q7, q7, q14
+ veor q1, q11, q10
+ veor q7, q7, q11
+ veor q7, q7, q12
+ veor q4, q4, q12
+ veor q1, q1, q8
+ veor q2, q2, q8
+ veor q7, q7, q0
+ veor q1, q1, q6
+ veor q6, q6, q0
+ veor q4, q4, q7
+ veor q0, q0, q1
+
+ veor q1, q1, q5
+ veor q5, q5, q2
+ veor q2, q2, q3
+ veor q3, q3, q5
+ veor q4, q4, q5
+
+ veor q6, q6, q3
+ subs r5,r5,#1
+ bcc .Lenc_done
+ vext.8 q8, q0, q0, #12 @ x0 <<< 32
+ vext.8 q9, q1, q1, #12
+ veor q0, q0, q8 @ x0 ^ (x0 <<< 32)
+ vext.8 q10, q4, q4, #12
+ veor q1, q1, q9
+ vext.8 q11, q6, q6, #12
+ veor q4, q4, q10
+ vext.8 q12, q3, q3, #12
+ veor q6, q6, q11
+ vext.8 q13, q7, q7, #12
+ veor q3, q3, q12
+ vext.8 q14, q2, q2, #12
+ veor q7, q7, q13
+ vext.8 q15, q5, q5, #12
+ veor q2, q2, q14
+
+ veor q9, q9, q0
+ veor q5, q5, q15
+ vext.8 q0, q0, q0, #8 @ (x0 ^ (x0 <<< 32)) <<< 64)
+ veor q10, q10, q1
+ veor q8, q8, q5
+ veor q9, q9, q5
+ vext.8 q1, q1, q1, #8
+ veor q13, q13, q3
+ veor q0, q0, q8
+ veor q14, q14, q7
+ veor q1, q1, q9
+ vext.8 q8, q3, q3, #8
+ veor q12, q12, q6
+ vext.8 q9, q7, q7, #8
+ veor q15, q15, q2
+ vext.8 q3, q6, q6, #8
+ veor q11, q11, q4
+ vext.8 q7, q5, q5, #8
+ veor q12, q12, q5
+ vext.8 q6, q2, q2, #8
+ veor q11, q11, q5
+ vext.8 q2, q4, q4, #8
+ veor q5, q9, q13
+ veor q4, q8, q12
+ veor q3, q3, q11
+ veor q7, q7, q15
+ veor q6, q6, q14
+ @ vmov q4, q8
+ veor q2, q2, q10
+ @ vmov q5, q9
+ vldmia r6, {q12} @ .LSR
+ ite eq @ Thumb2 thing, samity check in ARM
+ addeq r6,r6,#0x10
+ bne .Lenc_loop
+ vldmia r6, {q12} @ .LSRM0
+ b .Lenc_loop
+.align 4
+.Lenc_done:
+ vmov.i8 q8,#0x55 @ compose .LBS0
+ vmov.i8 q9,#0x33 @ compose .LBS1
+ vshr.u64 q10, q2, #1
+ vshr.u64 q11, q3, #1
+ veor q10, q10, q5
+ veor q11, q11, q7
+ vand q10, q10, q8
+ vand q11, q11, q8
+ veor q5, q5, q10
+ vshl.u64 q10, q10, #1
+ veor q7, q7, q11
+ vshl.u64 q11, q11, #1
+ veor q2, q2, q10
+ veor q3, q3, q11
+ vshr.u64 q10, q4, #1
+ vshr.u64 q11, q0, #1
+ veor q10, q10, q6
+ veor q11, q11, q1
+ vand q10, q10, q8
+ vand q11, q11, q8
+ veor q6, q6, q10
+ vshl.u64 q10, q10, #1
+ veor q1, q1, q11
+ vshl.u64 q11, q11, #1
+ veor q4, q4, q10
+ veor q0, q0, q11
+ vmov.i8 q8,#0x0f @ compose .LBS2
+ vshr.u64 q10, q7, #2
+ vshr.u64 q11, q3, #2
+ veor q10, q10, q5
+ veor q11, q11, q2
+ vand q10, q10, q9
+ vand q11, q11, q9
+ veor q5, q5, q10
+ vshl.u64 q10, q10, #2
+ veor q2, q2, q11
+ vshl.u64 q11, q11, #2
+ veor q7, q7, q10
+ veor q3, q3, q11
+ vshr.u64 q10, q1, #2
+ vshr.u64 q11, q0, #2
+ veor q10, q10, q6
+ veor q11, q11, q4
+ vand q10, q10, q9
+ vand q11, q11, q9
+ veor q6, q6, q10
+ vshl.u64 q10, q10, #2
+ veor q4, q4, q11
+ vshl.u64 q11, q11, #2
+ veor q1, q1, q10
+ veor q0, q0, q11
+ vshr.u64 q10, q6, #4
+ vshr.u64 q11, q4, #4
+ veor q10, q10, q5
+ veor q11, q11, q2
+ vand q10, q10, q8
+ vand q11, q11, q8
+ veor q5, q5, q10
+ vshl.u64 q10, q10, #4
+ veor q2, q2, q11
+ vshl.u64 q11, q11, #4
+ veor q6, q6, q10
+ veor q4, q4, q11
+ vshr.u64 q10, q1, #4
+ vshr.u64 q11, q0, #4
+ veor q10, q10, q7
+ veor q11, q11, q3
+ vand q10, q10, q8
+ vand q11, q11, q8
+ veor q7, q7, q10
+ vshl.u64 q10, q10, #4
+ veor q3, q3, q11
+ vshl.u64 q11, q11, #4
+ veor q1, q1, q10
+ veor q0, q0, q11
+ vldmia r4, {q8} @ last round key
+ veor q4, q4, q8
+ veor q6, q6, q8
+ veor q3, q3, q8
+ veor q7, q7, q8
+ veor q2, q2, q8
+ veor q5, q5, q8
+ veor q0, q0, q8
+ veor q1, q1, q8
+ bx lr
+.size _bsaes_encrypt8,.-_bsaes_encrypt8
+.type _bsaes_key_convert,%function
+.align 4
+_bsaes_key_convert:
+ adr r6,_bsaes_key_convert
+ vld1.8 {q7}, [r4]! @ load round 0 key
+ sub r6,r6,#_bsaes_key_convert-.LM0
+ vld1.8 {q15}, [r4]! @ load round 1 key
+
+ vmov.i8 q8, #0x01 @ bit masks
+ vmov.i8 q9, #0x02
+ vmov.i8 q10, #0x04
+ vmov.i8 q11, #0x08
+ vmov.i8 q12, #0x10
+ vmov.i8 q13, #0x20
+ vldmia r6, {q14} @ .LM0
+
+#ifdef __ARMEL__
+ vrev32.8 q7, q7
+ vrev32.8 q15, q15
+#endif
+ sub r5,r5,#1
+ vstmia r12!, {q7} @ save round 0 key
+ b .Lkey_loop
+
+.align 4
+.Lkey_loop:
+ vtbl.8 d14,{q15},d28
+ vtbl.8 d15,{q15},d29
+ vmov.i8 q6, #0x40
+ vmov.i8 q15, #0x80
+
+ vtst.8 q0, q7, q8
+ vtst.8 q1, q7, q9
+ vtst.8 q2, q7, q10
+ vtst.8 q3, q7, q11
+ vtst.8 q4, q7, q12
+ vtst.8 q5, q7, q13
+ vtst.8 q6, q7, q6
+ vtst.8 q7, q7, q15
+ vld1.8 {q15}, [r4]! @ load next round key
+ vmvn q0, q0 @ "pnot"
+ vmvn q1, q1
+ vmvn q5, q5
+ vmvn q6, q6
+#ifdef __ARMEL__
+ vrev32.8 q15, q15
+#endif
+ subs r5,r5,#1
+ vstmia r12!,{q0-q7} @ write bit-sliced round key
+ bne .Lkey_loop
+
+ vmov.i8 q7,#0x63 @ compose .L63
+ @ don't save last round key
+ bx lr
+.size _bsaes_key_convert,.-_bsaes_key_convert
+.extern AES_cbc_encrypt
+.extern AES_decrypt
+
+.global bsaes_cbc_encrypt
+.type bsaes_cbc_encrypt,%function
+.align 5
+bsaes_cbc_encrypt:
+#ifndef __KERNEL__
+ cmp r2, #128
+#ifndef __thumb__
+ blo AES_cbc_encrypt
+#else
+ bhs 1f
+ b AES_cbc_encrypt
+1:
+#endif
+#endif
+
+ @ it is up to the caller to make sure we are called with enc == 0
+
+ mov ip, sp
+ stmdb sp!, {r4-r10, lr}
+ VFP_ABI_PUSH
+ ldr r8, [ip] @ IV is 1st arg on the stack
+ mov r2, r2, lsr#4 @ len in 16 byte blocks
+ sub sp, #0x10 @ scratch space to carry over the IV
+ mov r9, sp @ save sp
+
+ ldr r10, [r3, #240] @ get # of rounds
+#ifndef BSAES_ASM_EXTENDED_KEY
+ @ allocate the key schedule on the stack
+ sub r12, sp, r10, lsl#7 @ 128 bytes per inner round key
+ add r12, #96 @ sifze of bit-slices key schedule
+
+ @ populate the key schedule
+ mov r4, r3 @ pass key
+ mov r5, r10 @ pass # of rounds
+ mov sp, r12 @ sp is sp
+ bl _bsaes_key_convert
+ vldmia sp, {q6}
+ vstmia r12, {q15} @ save last round key
+ veor q7, q7, q6 @ fix up round 0 key
+ vstmia sp, {q7}
+#else
+ ldr r12, [r3, #244]
+ eors r12, #1
+ beq 0f
+
+ @ populate the key schedule
+ str r12, [r3, #244]
+ mov r4, r3 @ pass key
+ mov r5, r10 @ pass # of rounds
+ add r12, r3, #248 @ pass key schedule
+ bl _bsaes_key_convert
+ add r4, r3, #248
+ vldmia r4, {q6}
+ vstmia r12, {q15} @ save last round key
+ veor q7, q7, q6 @ fix up round 0 key
+ vstmia r4, {q7}
+
+.align 2
+0:
+#endif
+
+ vld1.8 {q15}, [r8] @ load IV
+ b .Lcbc_dec_loop
+
+.align 4
+.Lcbc_dec_loop:
+ subs r2, r2, #0x8
+ bmi .Lcbc_dec_loop_finish
+
+ vld1.8 {q0-q1}, [r0]! @ load input
+ vld1.8 {q2-q3}, [r0]!
+#ifndef BSAES_ASM_EXTENDED_KEY
+ mov r4, sp @ pass the key
+#else
+ add r4, r3, #248
+#endif
+ vld1.8 {q4-q5}, [r0]!
+ mov r5, r10
+ vld1.8 {q6-q7}, [r0]
+ sub r0, r0, #0x60
+ vstmia r9, {q15} @ put aside IV
+
+ bl _bsaes_decrypt8
+
+ vldmia r9, {q14} @ reload IV
+ vld1.8 {q8-q9}, [r0]! @ reload input
+ veor q0, q0, q14 @ ^= IV
+ vld1.8 {q10-q11}, [r0]!
+ veor q1, q1, q8
+ veor q6, q6, q9
+ vld1.8 {q12-q13}, [r0]!
+ veor q4, q4, q10
+ veor q2, q2, q11
+ vld1.8 {q14-q15}, [r0]!
+ veor q7, q7, q12
+ vst1.8 {q0-q1}, [r1]! @ write output
+ veor q3, q3, q13
+ vst1.8 {q6}, [r1]!
+ veor q5, q5, q14
+ vst1.8 {q4}, [r1]!
+ vst1.8 {q2}, [r1]!
+ vst1.8 {q7}, [r1]!
+ vst1.8 {q3}, [r1]!
+ vst1.8 {q5}, [r1]!
+
+ b .Lcbc_dec_loop
+
+.Lcbc_dec_loop_finish:
+ adds r2, r2, #8
+ beq .Lcbc_dec_done
+
+ vld1.8 {q0}, [r0]! @ load input
+ cmp r2, #2
+ blo .Lcbc_dec_one
+ vld1.8 {q1}, [r0]!
+#ifndef BSAES_ASM_EXTENDED_KEY
+ mov r4, sp @ pass the key
+#else
+ add r4, r3, #248
+#endif
+ mov r5, r10
+ vstmia r9, {q15} @ put aside IV
+ beq .Lcbc_dec_two
+ vld1.8 {q2}, [r0]!
+ cmp r2, #4
+ blo .Lcbc_dec_three
+ vld1.8 {q3}, [r0]!
+ beq .Lcbc_dec_four
+ vld1.8 {q4}, [r0]!
+ cmp r2, #6
+ blo .Lcbc_dec_five
+ vld1.8 {q5}, [r0]!
+ beq .Lcbc_dec_six
+ vld1.8 {q6}, [r0]!
+ sub r0, r0, #0x70
+
+ bl _bsaes_decrypt8
+
+ vldmia r9, {q14} @ reload IV
+ vld1.8 {q8-q9}, [r0]! @ reload input
+ veor q0, q0, q14 @ ^= IV
+ vld1.8 {q10-q11}, [r0]!
+ veor q1, q1, q8
+ veor q6, q6, q9
+ vld1.8 {q12-q13}, [r0]!
+ veor q4, q4, q10
+ veor q2, q2, q11
+ vld1.8 {q15}, [r0]!
+ veor q7, q7, q12
+ vst1.8 {q0-q1}, [r1]! @ write output
+ veor q3, q3, q13
+ vst1.8 {q6}, [r1]!
+ vst1.8 {q4}, [r1]!
+ vst1.8 {q2}, [r1]!
+ vst1.8 {q7}, [r1]!
+ vst1.8 {q3}, [r1]!
+ b .Lcbc_dec_done
+.align 4
+.Lcbc_dec_six:
+ sub r0, r0, #0x60
+ bl _bsaes_decrypt8
+ vldmia r9,{q14} @ reload IV
+ vld1.8 {q8-q9}, [r0]! @ reload input
+ veor q0, q0, q14 @ ^= IV
+ vld1.8 {q10-q11}, [r0]!
+ veor q1, q1, q8
+ veor q6, q6, q9
+ vld1.8 {q12}, [r0]!
+ veor q4, q4, q10
+ veor q2, q2, q11
+ vld1.8 {q15}, [r0]!
+ veor q7, q7, q12
+ vst1.8 {q0-q1}, [r1]! @ write output
+ vst1.8 {q6}, [r1]!
+ vst1.8 {q4}, [r1]!
+ vst1.8 {q2}, [r1]!
+ vst1.8 {q7}, [r1]!
+ b .Lcbc_dec_done
+.align 4
+.Lcbc_dec_five:
+ sub r0, r0, #0x50
+ bl _bsaes_decrypt8
+ vldmia r9, {q14} @ reload IV
+ vld1.8 {q8-q9}, [r0]! @ reload input
+ veor q0, q0, q14 @ ^= IV
+ vld1.8 {q10-q11}, [r0]!
+ veor q1, q1, q8
+ veor q6, q6, q9
+ vld1.8 {q15}, [r0]!
+ veor q4, q4, q10
+ vst1.8 {q0-q1}, [r1]! @ write output
+ veor q2, q2, q11
+ vst1.8 {q6}, [r1]!
+ vst1.8 {q4}, [r1]!
+ vst1.8 {q2}, [r1]!
+ b .Lcbc_dec_done
+.align 4
+.Lcbc_dec_four:
+ sub r0, r0, #0x40
+ bl _bsaes_decrypt8
+ vldmia r9, {q14} @ reload IV
+ vld1.8 {q8-q9}, [r0]! @ reload input
+ veor q0, q0, q14 @ ^= IV
+ vld1.8 {q10}, [r0]!
+ veor q1, q1, q8
+ veor q6, q6, q9
+ vld1.8 {q15}, [r0]!
+ veor q4, q4, q10
+ vst1.8 {q0-q1}, [r1]! @ write output
+ vst1.8 {q6}, [r1]!
+ vst1.8 {q4}, [r1]!
+ b .Lcbc_dec_done
+.align 4
+.Lcbc_dec_three:
+ sub r0, r0, #0x30
+ bl _bsaes_decrypt8
+ vldmia r9, {q14} @ reload IV
+ vld1.8 {q8-q9}, [r0]! @ reload input
+ veor q0, q0, q14 @ ^= IV
+ vld1.8 {q15}, [r0]!
+ veor q1, q1, q8
+ veor q6, q6, q9
+ vst1.8 {q0-q1}, [r1]! @ write output
+ vst1.8 {q6}, [r1]!
+ b .Lcbc_dec_done
+.align 4
+.Lcbc_dec_two:
+ sub r0, r0, #0x20
+ bl _bsaes_decrypt8
+ vldmia r9, {q14} @ reload IV
+ vld1.8 {q8}, [r0]! @ reload input
+ veor q0, q0, q14 @ ^= IV
+ vld1.8 {q15}, [r0]! @ reload input
+ veor q1, q1, q8
+ vst1.8 {q0-q1}, [r1]! @ write output
+ b .Lcbc_dec_done
+.align 4
+.Lcbc_dec_one:
+ sub r0, r0, #0x10
+ mov r10, r1 @ save original out pointer
+ mov r1, r9 @ use the iv scratch space as out buffer
+ mov r2, r3
+ vmov q4,q15 @ just in case ensure that IV
+ vmov q5,q0 @ and input are preserved
+ bl AES_decrypt
+ vld1.8 {q0}, [r9,:64] @ load result
+ veor q0, q0, q4 @ ^= IV
+ vmov q15, q5 @ q5 holds input
+ vst1.8 {q0}, [r10] @ write output
+
+.Lcbc_dec_done:
+#ifndef BSAES_ASM_EXTENDED_KEY
+ vmov.i32 q0, #0
+ vmov.i32 q1, #0
+.Lcbc_dec_bzero: @ wipe key schedule [if any]
+ vstmia sp!, {q0-q1}
+ cmp sp, r9
+ bne .Lcbc_dec_bzero
+#endif
+
+ mov sp, r9
+ add sp, #0x10 @ add sp,r9,#0x10 is no good for thumb
+ vst1.8 {q15}, [r8] @ return IV
+ VFP_ABI_POP
+ ldmia sp!, {r4-r10, pc}
+.size bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
+.extern AES_encrypt
+.global bsaes_ctr32_encrypt_blocks
+.type bsaes_ctr32_encrypt_blocks,%function
+.align 5
+bsaes_ctr32_encrypt_blocks:
+ cmp r2, #8 @ use plain AES for
+ blo .Lctr_enc_short @ small sizes
+
+ mov ip, sp
+ stmdb sp!, {r4-r10, lr}
+ VFP_ABI_PUSH
+ ldr r8, [ip] @ ctr is 1st arg on the stack
+ sub sp, sp, #0x10 @ scratch space to carry over the ctr
+ mov r9, sp @ save sp
+
+ ldr r10, [r3, #240] @ get # of rounds
+#ifndef BSAES_ASM_EXTENDED_KEY
+ @ allocate the key schedule on the stack
+ sub r12, sp, r10, lsl#7 @ 128 bytes per inner round key
+ add r12, #96 @ size of bit-sliced key schedule
+
+ @ populate the key schedule
+ mov r4, r3 @ pass key
+ mov r5, r10 @ pass # of rounds
+ mov sp, r12 @ sp is sp
+ bl _bsaes_key_convert
+ veor q7,q7,q15 @ fix up last round key
+ vstmia r12, {q7} @ save last round key
+
+ vld1.8 {q0}, [r8] @ load counter
+ add r8, r6, #.LREVM0SR-.LM0 @ borrow r8
+ vldmia sp, {q4} @ load round0 key
+#else
+ ldr r12, [r3, #244]
+ eors r12, #1
+ beq 0f
+
+ @ populate the key schedule
+ str r12, [r3, #244]
+ mov r4, r3 @ pass key
+ mov r5, r10 @ pass # of rounds
+ add r12, r3, #248 @ pass key schedule
+ bl _bsaes_key_convert
+ veor q7,q7,q15 @ fix up last round key
+ vstmia r12, {q7} @ save last round key
+
+.align 2
+0: add r12, r3, #248
+ vld1.8 {q0}, [r8] @ load counter
+ adrl r8, .LREVM0SR @ borrow r8
+ vldmia r12, {q4} @ load round0 key
+ sub sp, #0x10 @ place for adjusted round0 key
+#endif
+
+ vmov.i32 q8,#1 @ compose 1<<96
+ veor q9,q9,q9
+ vrev32.8 q0,q0
+ vext.8 q8,q9,q8,#4
+ vrev32.8 q4,q4
+ vadd.u32 q9,q8,q8 @ compose 2<<96
+ vstmia sp, {q4} @ save adjusted round0 key
+ b .Lctr_enc_loop
+
+.align 4
+.Lctr_enc_loop:
+ vadd.u32 q10, q8, q9 @ compose 3<<96
+ vadd.u32 q1, q0, q8 @ +1
+ vadd.u32 q2, q0, q9 @ +2
+ vadd.u32 q3, q0, q10 @ +3
+ vadd.u32 q4, q1, q10
+ vadd.u32 q5, q2, q10
+ vadd.u32 q6, q3, q10
+ vadd.u32 q7, q4, q10
+ vadd.u32 q10, q5, q10 @ next counter
+
+ @ Borrow prologue from _bsaes_encrypt8 to use the opportunity
+ @ to flip byte order in 32-bit counter
+
+ vldmia sp, {q9} @ load round0 key
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x10 @ pass next round key
+#else
+ add r4, r3, #264
+#endif
+ vldmia r8, {q8} @ .LREVM0SR
+ mov r5, r10 @ pass rounds
+ vstmia r9, {q10} @ save next counter
+ sub r6, r8, #.LREVM0SR-.LSR @ pass constants
+
+ bl _bsaes_encrypt8_alt
+
+ subs r2, r2, #8
+ blo .Lctr_enc_loop_done
+
+ vld1.8 {q8-q9}, [r0]! @ load input
+ vld1.8 {q10-q11}, [r0]!
+ veor q0, q8
+ veor q1, q9
+ vld1.8 {q12-q13}, [r0]!
+ veor q4, q10
+ veor q6, q11
+ vld1.8 {q14-q15}, [r0]!
+ veor q3, q12
+ vst1.8 {q0-q1}, [r1]! @ write output
+ veor q7, q13
+ veor q2, q14
+ vst1.8 {q4}, [r1]!
+ veor q5, q15
+ vst1.8 {q6}, [r1]!
+ vmov.i32 q8, #1 @ compose 1<<96
+ vst1.8 {q3}, [r1]!
+ veor q9, q9, q9
+ vst1.8 {q7}, [r1]!
+ vext.8 q8, q9, q8, #4
+ vst1.8 {q2}, [r1]!
+ vadd.u32 q9,q8,q8 @ compose 2<<96
+ vst1.8 {q5}, [r1]!
+ vldmia r9, {q0} @ load counter
+
+ bne .Lctr_enc_loop
+ b .Lctr_enc_done
+
+.align 4
+.Lctr_enc_loop_done:
+ add r2, r2, #8
+ vld1.8 {q8}, [r0]! @ load input
+ veor q0, q8
+ vst1.8 {q0}, [r1]! @ write output
+ cmp r2, #2
+ blo .Lctr_enc_done
+ vld1.8 {q9}, [r0]!
+ veor q1, q9
+ vst1.8 {q1}, [r1]!
+ beq .Lctr_enc_done
+ vld1.8 {q10}, [r0]!
+ veor q4, q10
+ vst1.8 {q4}, [r1]!
+ cmp r2, #4
+ blo .Lctr_enc_done
+ vld1.8 {q11}, [r0]!
+ veor q6, q11
+ vst1.8 {q6}, [r1]!
+ beq .Lctr_enc_done
+ vld1.8 {q12}, [r0]!
+ veor q3, q12
+ vst1.8 {q3}, [r1]!
+ cmp r2, #6
+ blo .Lctr_enc_done
+ vld1.8 {q13}, [r0]!
+ veor q7, q13
+ vst1.8 {q7}, [r1]!
+ beq .Lctr_enc_done
+ vld1.8 {q14}, [r0]
+ veor q2, q14
+ vst1.8 {q2}, [r1]!
+
+.Lctr_enc_done:
+ vmov.i32 q0, #0
+ vmov.i32 q1, #0
+#ifndef BSAES_ASM_EXTENDED_KEY
+.Lctr_enc_bzero: @ wipe key schedule [if any]
+ vstmia sp!, {q0-q1}
+ cmp sp, r9
+ bne .Lctr_enc_bzero
+#else
+ vstmia sp, {q0-q1}
+#endif
+
+ mov sp, r9
+ add sp, #0x10 @ add sp,r9,#0x10 is no good for thumb
+ VFP_ABI_POP
+ ldmia sp!, {r4-r10, pc} @ return
+
+.align 4
+.Lctr_enc_short:
+ ldr ip, [sp] @ ctr pointer is passed on stack
+ stmdb sp!, {r4-r8, lr}
+
+ mov r4, r0 @ copy arguments
+ mov r5, r1
+ mov r6, r2
+ mov r7, r3
+ ldr r8, [ip, #12] @ load counter LSW
+ vld1.8 {q1}, [ip] @ load whole counter value
+#ifdef __ARMEL__
+ rev r8, r8
+#endif
+ sub sp, sp, #0x10
+ vst1.8 {q1}, [sp,:64] @ copy counter value
+ sub sp, sp, #0x10
+
+.Lctr_enc_short_loop:
+ add r0, sp, #0x10 @ input counter value
+ mov r1, sp @ output on the stack
+ mov r2, r7 @ key
+
+ bl AES_encrypt
+
+ vld1.8 {q0}, [r4]! @ load input
+ vld1.8 {q1}, [sp,:64] @ load encrypted counter
+ add r8, r8, #1
+#ifdef __ARMEL__
+ rev r0, r8
+ str r0, [sp, #0x1c] @ next counter value
+#else
+ str r8, [sp, #0x1c] @ next counter value
+#endif
+ veor q0,q0,q1
+ vst1.8 {q0}, [r5]! @ store output
+ subs r6, r6, #1
+ bne .Lctr_enc_short_loop
+
+ vmov.i32 q0, #0
+ vmov.i32 q1, #0
+ vstmia sp!, {q0-q1}
+
+ ldmia sp!, {r4-r8, pc}
+.size bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
+.globl bsaes_xts_encrypt
+.type bsaes_xts_encrypt,%function
+.align 4
+bsaes_xts_encrypt:
+ mov ip, sp
+ stmdb sp!, {r4-r10, lr} @ 0x20
+ VFP_ABI_PUSH
+ mov r6, sp @ future r3
+
+ mov r7, r0
+ mov r8, r1
+ mov r9, r2
+ mov r10, r3
+
+ sub r0, sp, #0x10 @ 0x10
+ bic r0, #0xf @ align at 16 bytes
+ mov sp, r0
+
+#ifdef XTS_CHAIN_TWEAK
+ ldr r0, [ip] @ pointer to input tweak
+#else
+ @ generate initial tweak
+ ldr r0, [ip, #4] @ iv[]
+ mov r1, sp
+ ldr r2, [ip, #0] @ key2
+ bl AES_encrypt
+ mov r0,sp @ pointer to initial tweak
+#endif
+
+ ldr r1, [r10, #240] @ get # of rounds
+ mov r3, r6
+#ifndef BSAES_ASM_EXTENDED_KEY
+ @ allocate the key schedule on the stack
+ sub r12, sp, r1, lsl#7 @ 128 bytes per inner round key
+ @ add r12, #96 @ size of bit-sliced key schedule
+ sub r12, #48 @ place for tweak[9]
+
+ @ populate the key schedule
+ mov r4, r10 @ pass key
+ mov r5, r1 @ pass # of rounds
+ mov sp, r12
+ add r12, #0x90 @ pass key schedule
+ bl _bsaes_key_convert
+ veor q7, q7, q15 @ fix up last round key
+ vstmia r12, {q7} @ save last round key
+#else
+ ldr r12, [r10, #244]
+ eors r12, #1
+ beq 0f
+
+ str r12, [r10, #244]
+ mov r4, r10 @ pass key
+ mov r5, r1 @ pass # of rounds
+ add r12, r10, #248 @ pass key schedule
+ bl _bsaes_key_convert
+ veor q7, q7, q15 @ fix up last round key
+ vstmia r12, {q7}
+
+.align 2
+0: sub sp, #0x90 @ place for tweak[9]
+#endif
+
+ vld1.8 {q8}, [r0] @ initial tweak
+ adr r2, .Lxts_magic
+
+ subs r9, #0x80
+ blo .Lxts_enc_short
+ b .Lxts_enc_loop
+
+.align 4
+.Lxts_enc_loop:
+ vldmia r2, {q5} @ load XTS magic
+ vshr.s64 q6, q8, #63
+ mov r0, sp
+ vand q6, q6, q5
+ vadd.u64 q9, q8, q8
+ vst1.64 {q8}, [r0,:128]!
+ vswp d13,d12
+ vshr.s64 q7, q9, #63
+ veor q9, q9, q6
+ vand q7, q7, q5
+ vadd.u64 q10, q9, q9
+ vst1.64 {q9}, [r0,:128]!
+ vswp d15,d14
+ vshr.s64 q6, q10, #63
+ veor q10, q10, q7
+ vand q6, q6, q5
+ vld1.8 {q0}, [r7]!
+ vadd.u64 q11, q10, q10
+ vst1.64 {q10}, [r0,:128]!
+ vswp d13,d12
+ vshr.s64 q7, q11, #63
+ veor q11, q11, q6
+ vand q7, q7, q5
+ vld1.8 {q1}, [r7]!
+ veor q0, q0, q8
+ vadd.u64 q12, q11, q11
+ vst1.64 {q11}, [r0,:128]!
+ vswp d15,d14
+ vshr.s64 q6, q12, #63
+ veor q12, q12, q7
+ vand q6, q6, q5
+ vld1.8 {q2}, [r7]!
+ veor q1, q1, q9
+ vadd.u64 q13, q12, q12
+ vst1.64 {q12}, [r0,:128]!
+ vswp d13,d12
+ vshr.s64 q7, q13, #63
+ veor q13, q13, q6
+ vand q7, q7, q5
+ vld1.8 {q3}, [r7]!
+ veor q2, q2, q10
+ vadd.u64 q14, q13, q13
+ vst1.64 {q13}, [r0,:128]!
+ vswp d15,d14
+ vshr.s64 q6, q14, #63
+ veor q14, q14, q7
+ vand q6, q6, q5
+ vld1.8 {q4}, [r7]!
+ veor q3, q3, q11
+ vadd.u64 q15, q14, q14
+ vst1.64 {q14}, [r0,:128]!
+ vswp d13,d12
+ vshr.s64 q7, q15, #63
+ veor q15, q15, q6
+ vand q7, q7, q5
+ vld1.8 {q5}, [r7]!
+ veor q4, q4, q12
+ vadd.u64 q8, q15, q15
+ vst1.64 {q15}, [r0,:128]!
+ vswp d15,d14
+ veor q8, q8, q7
+ vst1.64 {q8}, [r0,:128] @ next round tweak
+
+ vld1.8 {q6-q7}, [r7]!
+ veor q5, q5, q13
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, r10, #248 @ pass key schedule
+#endif
+ veor q6, q6, q14
+ mov r5, r1 @ pass rounds
+ veor q7, q7, q15
+ mov r0, sp
+
+ bl _bsaes_encrypt8
+
+ vld1.64 {q8-q9}, [r0,:128]!
+ vld1.64 {q10-q11}, [r0,:128]!
+ veor q0, q0, q8
+ vld1.64 {q12-q13}, [r0,:128]!
+ veor q1, q1, q9
+ veor q8, q4, q10
+ vst1.8 {q0-q1}, [r8]!
+ veor q9, q6, q11
+ vld1.64 {q14-q15}, [r0,:128]!
+ veor q10, q3, q12
+ vst1.8 {q8-q9}, [r8]!
+ veor q11, q7, q13
+ veor q12, q2, q14
+ vst1.8 {q10-q11}, [r8]!
+ veor q13, q5, q15
+ vst1.8 {q12-q13}, [r8]!
+
+ vld1.64 {q8}, [r0,:128] @ next round tweak
+
+ subs r9, #0x80
+ bpl .Lxts_enc_loop
+
+.Lxts_enc_short:
+ adds r9, #0x70
+ bmi .Lxts_enc_done
+
+ vldmia r2, {q5} @ load XTS magic
+ vshr.s64 q7, q8, #63
+ mov r0, sp
+ vand q7, q7, q5
+ vadd.u64 q9, q8, q8
+ vst1.64 {q8}, [r0,:128]!
+ vswp d15,d14
+ vshr.s64 q6, q9, #63
+ veor q9, q9, q7
+ vand q6, q6, q5
+ vadd.u64 q10, q9, q9
+ vst1.64 {q9}, [r0,:128]!
+ vswp d13,d12
+ vshr.s64 q7, q10, #63
+ veor q10, q10, q6
+ vand q7, q7, q5
+ vld1.8 {q0}, [r7]!
+ subs r9, #0x10
+ bmi .Lxts_enc_1
+ vadd.u64 q11, q10, q10
+ vst1.64 {q10}, [r0,:128]!
+ vswp d15,d14
+ vshr.s64 q6, q11, #63
+ veor q11, q11, q7
+ vand q6, q6, q5
+ vld1.8 {q1}, [r7]!
+ subs r9, #0x10
+ bmi .Lxts_enc_2
+ veor q0, q0, q8
+ vadd.u64 q12, q11, q11
+ vst1.64 {q11}, [r0,:128]!
+ vswp d13,d12
+ vshr.s64 q7, q12, #63
+ veor q12, q12, q6
+ vand q7, q7, q5
+ vld1.8 {q2}, [r7]!
+ subs r9, #0x10
+ bmi .Lxts_enc_3
+ veor q1, q1, q9
+ vadd.u64 q13, q12, q12
+ vst1.64 {q12}, [r0,:128]!
+ vswp d15,d14
+ vshr.s64 q6, q13, #63
+ veor q13, q13, q7
+ vand q6, q6, q5
+ vld1.8 {q3}, [r7]!
+ subs r9, #0x10
+ bmi .Lxts_enc_4
+ veor q2, q2, q10
+ vadd.u64 q14, q13, q13
+ vst1.64 {q13}, [r0,:128]!
+ vswp d13,d12
+ vshr.s64 q7, q14, #63
+ veor q14, q14, q6
+ vand q7, q7, q5
+ vld1.8 {q4}, [r7]!
+ subs r9, #0x10
+ bmi .Lxts_enc_5
+ veor q3, q3, q11
+ vadd.u64 q15, q14, q14
+ vst1.64 {q14}, [r0,:128]!
+ vswp d15,d14
+ vshr.s64 q6, q15, #63
+ veor q15, q15, q7
+ vand q6, q6, q5
+ vld1.8 {q5}, [r7]!
+ subs r9, #0x10
+ bmi .Lxts_enc_6
+ veor q4, q4, q12
+ sub r9, #0x10
+ vst1.64 {q15}, [r0,:128] @ next round tweak
+
+ vld1.8 {q6}, [r7]!
+ veor q5, q5, q13
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, r10, #248 @ pass key schedule
+#endif
+ veor q6, q6, q14
+ mov r5, r1 @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_encrypt8
+
+ vld1.64 {q8-q9}, [r0,:128]!
+ vld1.64 {q10-q11}, [r0,:128]!
+ veor q0, q0, q8
+ vld1.64 {q12-q13}, [r0,:128]!
+ veor q1, q1, q9
+ veor q8, q4, q10
+ vst1.8 {q0-q1}, [r8]!
+ veor q9, q6, q11
+ vld1.64 {q14}, [r0,:128]!
+ veor q10, q3, q12
+ vst1.8 {q8-q9}, [r8]!
+ veor q11, q7, q13
+ veor q12, q2, q14
+ vst1.8 {q10-q11}, [r8]!
+ vst1.8 {q12}, [r8]!
+
+ vld1.64 {q8}, [r0,:128] @ next round tweak
+ b .Lxts_enc_done
+.align 4
+.Lxts_enc_6:
+ vst1.64 {q14}, [r0,:128] @ next round tweak
+
+ veor q4, q4, q12
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, r10, #248 @ pass key schedule
+#endif
+ veor q5, q5, q13
+ mov r5, r1 @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_encrypt8
+
+ vld1.64 {q8-q9}, [r0,:128]!
+ vld1.64 {q10-q11}, [r0,:128]!
+ veor q0, q0, q8
+ vld1.64 {q12-q13}, [r0,:128]!
+ veor q1, q1, q9
+ veor q8, q4, q10
+ vst1.8 {q0-q1}, [r8]!
+ veor q9, q6, q11
+ veor q10, q3, q12
+ vst1.8 {q8-q9}, [r8]!
+ veor q11, q7, q13
+ vst1.8 {q10-q11}, [r8]!
+
+ vld1.64 {q8}, [r0,:128] @ next round tweak
+ b .Lxts_enc_done
+
+@ put this in range for both ARM and Thumb mode adr instructions
+.align 5
+.Lxts_magic:
+ .quad 1, 0x87
+
+.align 5
+.Lxts_enc_5:
+ vst1.64 {q13}, [r0,:128] @ next round tweak
+
+ veor q3, q3, q11
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, r10, #248 @ pass key schedule
+#endif
+ veor q4, q4, q12
+ mov r5, r1 @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_encrypt8
+
+ vld1.64 {q8-q9}, [r0,:128]!
+ vld1.64 {q10-q11}, [r0,:128]!
+ veor q0, q0, q8
+ vld1.64 {q12}, [r0,:128]!
+ veor q1, q1, q9
+ veor q8, q4, q10
+ vst1.8 {q0-q1}, [r8]!
+ veor q9, q6, q11
+ veor q10, q3, q12
+ vst1.8 {q8-q9}, [r8]!
+ vst1.8 {q10}, [r8]!
+
+ vld1.64 {q8}, [r0,:128] @ next round tweak
+ b .Lxts_enc_done
+.align 4
+.Lxts_enc_4:
+ vst1.64 {q12}, [r0,:128] @ next round tweak
+
+ veor q2, q2, q10
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, r10, #248 @ pass key schedule
+#endif
+ veor q3, q3, q11
+ mov r5, r1 @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_encrypt8
+
+ vld1.64 {q8-q9}, [r0,:128]!
+ vld1.64 {q10-q11}, [r0,:128]!
+ veor q0, q0, q8
+ veor q1, q1, q9
+ veor q8, q4, q10
+ vst1.8 {q0-q1}, [r8]!
+ veor q9, q6, q11
+ vst1.8 {q8-q9}, [r8]!
+
+ vld1.64 {q8}, [r0,:128] @ next round tweak
+ b .Lxts_enc_done
+.align 4
+.Lxts_enc_3:
+ vst1.64 {q11}, [r0,:128] @ next round tweak
+
+ veor q1, q1, q9
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, r10, #248 @ pass key schedule
+#endif
+ veor q2, q2, q10
+ mov r5, r1 @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_encrypt8
+
+ vld1.64 {q8-q9}, [r0,:128]!
+ vld1.64 {q10}, [r0,:128]!
+ veor q0, q0, q8
+ veor q1, q1, q9
+ veor q8, q4, q10
+ vst1.8 {q0-q1}, [r8]!
+ vst1.8 {q8}, [r8]!
+
+ vld1.64 {q8}, [r0,:128] @ next round tweak
+ b .Lxts_enc_done
+.align 4
+.Lxts_enc_2:
+ vst1.64 {q10}, [r0,:128] @ next round tweak
+
+ veor q0, q0, q8
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, r10, #248 @ pass key schedule
+#endif
+ veor q1, q1, q9
+ mov r5, r1 @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_encrypt8
+
+ vld1.64 {q8-q9}, [r0,:128]!
+ veor q0, q0, q8
+ veor q1, q1, q9
+ vst1.8 {q0-q1}, [r8]!
+
+ vld1.64 {q8}, [r0,:128] @ next round tweak
+ b .Lxts_enc_done
+.align 4
+.Lxts_enc_1:
+ mov r0, sp
+ veor q0, q8
+ mov r1, sp
+ vst1.8 {q0}, [sp,:128]
+ mov r2, r10
+ mov r4, r3 @ preserve fp
+
+ bl AES_encrypt
+
+ vld1.8 {q0}, [sp,:128]
+ veor q0, q0, q8
+ vst1.8 {q0}, [r8]!
+ mov r3, r4
+
+ vmov q8, q9 @ next round tweak
+
+.Lxts_enc_done:
+#ifndef XTS_CHAIN_TWEAK
+ adds r9, #0x10
+ beq .Lxts_enc_ret
+ sub r6, r8, #0x10
+
+.Lxts_enc_steal:
+ ldrb r0, [r7], #1
+ ldrb r1, [r8, #-0x10]
+ strb r0, [r8, #-0x10]
+ strb r1, [r8], #1
+
+ subs r9, #1
+ bhi .Lxts_enc_steal
+
+ vld1.8 {q0}, [r6]
+ mov r0, sp
+ veor q0, q0, q8
+ mov r1, sp
+ vst1.8 {q0}, [sp,:128]
+ mov r2, r10
+ mov r4, r3 @ preserve fp
+
+ bl AES_encrypt
+
+ vld1.8 {q0}, [sp,:128]
+ veor q0, q0, q8
+ vst1.8 {q0}, [r6]
+ mov r3, r4
+#endif
+
+.Lxts_enc_ret:
+ bic r0, r3, #0xf
+ vmov.i32 q0, #0
+ vmov.i32 q1, #0
+#ifdef XTS_CHAIN_TWEAK
+ ldr r1, [r3, #0x20+VFP_ABI_FRAME] @ chain tweak
+#endif
+.Lxts_enc_bzero: @ wipe key schedule [if any]
+ vstmia sp!, {q0-q1}
+ cmp sp, r0
+ bne .Lxts_enc_bzero
+
+ mov sp, r3
+#ifdef XTS_CHAIN_TWEAK
+ vst1.8 {q8}, [r1]
+#endif
+ VFP_ABI_POP
+ ldmia sp!, {r4-r10, pc} @ return
+
+.size bsaes_xts_encrypt,.-bsaes_xts_encrypt
+
+.globl bsaes_xts_decrypt
+.type bsaes_xts_decrypt,%function
+.align 4
+bsaes_xts_decrypt:
+ mov ip, sp
+ stmdb sp!, {r4-r10, lr} @ 0x20
+ VFP_ABI_PUSH
+ mov r6, sp @ future r3
+
+ mov r7, r0
+ mov r8, r1
+ mov r9, r2
+ mov r10, r3
+
+ sub r0, sp, #0x10 @ 0x10
+ bic r0, #0xf @ align at 16 bytes
+ mov sp, r0
+
+#ifdef XTS_CHAIN_TWEAK
+ ldr r0, [ip] @ pointer to input tweak
+#else
+ @ generate initial tweak
+ ldr r0, [ip, #4] @ iv[]
+ mov r1, sp
+ ldr r2, [ip, #0] @ key2
+ bl AES_encrypt
+ mov r0, sp @ pointer to initial tweak
+#endif
+
+ ldr r1, [r10, #240] @ get # of rounds
+ mov r3, r6
+#ifndef BSAES_ASM_EXTENDED_KEY
+ @ allocate the key schedule on the stack
+ sub r12, sp, r1, lsl#7 @ 128 bytes per inner round key
+ @ add r12, #96 @ size of bit-sliced key schedule
+ sub r12, #48 @ place for tweak[9]
+
+ @ populate the key schedule
+ mov r4, r10 @ pass key
+ mov r5, r1 @ pass # of rounds
+ mov sp, r12
+ add r12, #0x90 @ pass key schedule
+ bl _bsaes_key_convert
+ add r4, sp, #0x90
+ vldmia r4, {q6}
+ vstmia r12, {q15} @ save last round key
+ veor q7, q7, q6 @ fix up round 0 key
+ vstmia r4, {q7}
+#else
+ ldr r12, [r10, #244]
+ eors r12, #1
+ beq 0f
+
+ str r12, [r10, #244]
+ mov r4, r10 @ pass key
+ mov r5, r1 @ pass # of rounds
+ add r12, r10, #248 @ pass key schedule
+ bl _bsaes_key_convert
+ add r4, r10, #248
+ vldmia r4, {q6}
+ vstmia r12, {q15} @ save last round key
+ veor q7, q7, q6 @ fix up round 0 key
+ vstmia r4, {q7}
+
+.align 2
+0: sub sp, #0x90 @ place for tweak[9]
+#endif
+ vld1.8 {q8}, [r0] @ initial tweak
+ adr r2, .Lxts_magic
+
+#ifndef XTS_CHAIN_TWEAK
+ tst r9, #0xf @ if not multiple of 16
+ it ne @ Thumb2 thing, sanity check in ARM
+ subne r9, #0x10 @ subtract another 16 bytes
+#endif
+ subs r9, #0x80
+
+ blo .Lxts_dec_short
+ b .Lxts_dec_loop
+
+.align 4
+.Lxts_dec_loop:
+ vldmia r2, {q5} @ load XTS magic
+ vshr.s64 q6, q8, #63
+ mov r0, sp
+ vand q6, q6, q5
+ vadd.u64 q9, q8, q8
+ vst1.64 {q8}, [r0,:128]!
+ vswp d13,d12
+ vshr.s64 q7, q9, #63
+ veor q9, q9, q6
+ vand q7, q7, q5
+ vadd.u64 q10, q9, q9
+ vst1.64 {q9}, [r0,:128]!
+ vswp d15,d14
+ vshr.s64 q6, q10, #63
+ veor q10, q10, q7
+ vand q6, q6, q5
+ vld1.8 {q0}, [r7]!
+ vadd.u64 q11, q10, q10
+ vst1.64 {q10}, [r0,:128]!
+ vswp d13,d12
+ vshr.s64 q7, q11, #63
+ veor q11, q11, q6
+ vand q7, q7, q5
+ vld1.8 {q1}, [r7]!
+ veor q0, q0, q8
+ vadd.u64 q12, q11, q11
+ vst1.64 {q11}, [r0,:128]!
+ vswp d15,d14
+ vshr.s64 q6, q12, #63
+ veor q12, q12, q7
+ vand q6, q6, q5
+ vld1.8 {q2}, [r7]!
+ veor q1, q1, q9
+ vadd.u64 q13, q12, q12
+ vst1.64 {q12}, [r0,:128]!
+ vswp d13,d12
+ vshr.s64 q7, q13, #63
+ veor q13, q13, q6
+ vand q7, q7, q5
+ vld1.8 {q3}, [r7]!
+ veor q2, q2, q10
+ vadd.u64 q14, q13, q13
+ vst1.64 {q13}, [r0,:128]!
+ vswp d15,d14
+ vshr.s64 q6, q14, #63
+ veor q14, q14, q7
+ vand q6, q6, q5
+ vld1.8 {q4}, [r7]!
+ veor q3, q3, q11
+ vadd.u64 q15, q14, q14
+ vst1.64 {q14}, [r0,:128]!
+ vswp d13,d12
+ vshr.s64 q7, q15, #63
+ veor q15, q15, q6
+ vand q7, q7, q5
+ vld1.8 {q5}, [r7]!
+ veor q4, q4, q12
+ vadd.u64 q8, q15, q15
+ vst1.64 {q15}, [r0,:128]!
+ vswp d15,d14
+ veor q8, q8, q7
+ vst1.64 {q8}, [r0,:128] @ next round tweak
+
+ vld1.8 {q6-q7}, [r7]!
+ veor q5, q5, q13
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, r10, #248 @ pass key schedule
+#endif
+ veor q6, q6, q14
+ mov r5, r1 @ pass rounds
+ veor q7, q7, q15
+ mov r0, sp
+
+ bl _bsaes_decrypt8
+
+ vld1.64 {q8-q9}, [r0,:128]!
+ vld1.64 {q10-q11}, [r0,:128]!
+ veor q0, q0, q8
+ vld1.64 {q12-q13}, [r0,:128]!
+ veor q1, q1, q9
+ veor q8, q6, q10
+ vst1.8 {q0-q1}, [r8]!
+ veor q9, q4, q11
+ vld1.64 {q14-q15}, [r0,:128]!
+ veor q10, q2, q12
+ vst1.8 {q8-q9}, [r8]!
+ veor q11, q7, q13
+ veor q12, q3, q14
+ vst1.8 {q10-q11}, [r8]!
+ veor q13, q5, q15
+ vst1.8 {q12-q13}, [r8]!
+
+ vld1.64 {q8}, [r0,:128] @ next round tweak
+
+ subs r9, #0x80
+ bpl .Lxts_dec_loop
+
+.Lxts_dec_short:
+ adds r9, #0x70
+ bmi .Lxts_dec_done
+
+ vldmia r2, {q5} @ load XTS magic
+ vshr.s64 q7, q8, #63
+ mov r0, sp
+ vand q7, q7, q5
+ vadd.u64 q9, q8, q8
+ vst1.64 {q8}, [r0,:128]!
+ vswp d15,d14
+ vshr.s64 q6, q9, #63
+ veor q9, q9, q7
+ vand q6, q6, q5
+ vadd.u64 q10, q9, q9
+ vst1.64 {q9}, [r0,:128]!
+ vswp d13,d12
+ vshr.s64 q7, q10, #63
+ veor q10, q10, q6
+ vand q7, q7, q5
+ vld1.8 {q0}, [r7]!
+ subs r9, #0x10
+ bmi .Lxts_dec_1
+ vadd.u64 q11, q10, q10
+ vst1.64 {q10}, [r0,:128]!
+ vswp d15,d14
+ vshr.s64 q6, q11, #63
+ veor q11, q11, q7
+ vand q6, q6, q5
+ vld1.8 {q1}, [r7]!
+ subs r9, #0x10
+ bmi .Lxts_dec_2
+ veor q0, q0, q8
+ vadd.u64 q12, q11, q11
+ vst1.64 {q11}, [r0,:128]!
+ vswp d13,d12
+ vshr.s64 q7, q12, #63
+ veor q12, q12, q6
+ vand q7, q7, q5
+ vld1.8 {q2}, [r7]!
+ subs r9, #0x10
+ bmi .Lxts_dec_3
+ veor q1, q1, q9
+ vadd.u64 q13, q12, q12
+ vst1.64 {q12}, [r0,:128]!
+ vswp d15,d14
+ vshr.s64 q6, q13, #63
+ veor q13, q13, q7
+ vand q6, q6, q5
+ vld1.8 {q3}, [r7]!
+ subs r9, #0x10
+ bmi .Lxts_dec_4
+ veor q2, q2, q10
+ vadd.u64 q14, q13, q13
+ vst1.64 {q13}, [r0,:128]!
+ vswp d13,d12
+ vshr.s64 q7, q14, #63
+ veor q14, q14, q6
+ vand q7, q7, q5
+ vld1.8 {q4}, [r7]!
+ subs r9, #0x10
+ bmi .Lxts_dec_5
+ veor q3, q3, q11
+ vadd.u64 q15, q14, q14
+ vst1.64 {q14}, [r0,:128]!
+ vswp d15,d14
+ vshr.s64 q6, q15, #63
+ veor q15, q15, q7
+ vand q6, q6, q5
+ vld1.8 {q5}, [r7]!
+ subs r9, #0x10
+ bmi .Lxts_dec_6
+ veor q4, q4, q12
+ sub r9, #0x10
+ vst1.64 {q15}, [r0,:128] @ next round tweak
+
+ vld1.8 {q6}, [r7]!
+ veor q5, q5, q13
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, r10, #248 @ pass key schedule
+#endif
+ veor q6, q6, q14
+ mov r5, r1 @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_decrypt8
+
+ vld1.64 {q8-q9}, [r0,:128]!
+ vld1.64 {q10-q11}, [r0,:128]!
+ veor q0, q0, q8
+ vld1.64 {q12-q13}, [r0,:128]!
+ veor q1, q1, q9
+ veor q8, q6, q10
+ vst1.8 {q0-q1}, [r8]!
+ veor q9, q4, q11
+ vld1.64 {q14}, [r0,:128]!
+ veor q10, q2, q12
+ vst1.8 {q8-q9}, [r8]!
+ veor q11, q7, q13
+ veor q12, q3, q14
+ vst1.8 {q10-q11}, [r8]!
+ vst1.8 {q12}, [r8]!
+
+ vld1.64 {q8}, [r0,:128] @ next round tweak
+ b .Lxts_dec_done
+.align 4
+.Lxts_dec_6:
+ vst1.64 {q14}, [r0,:128] @ next round tweak
+
+ veor q4, q4, q12
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, r10, #248 @ pass key schedule
+#endif
+ veor q5, q5, q13
+ mov r5, r1 @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_decrypt8
+
+ vld1.64 {q8-q9}, [r0,:128]!
+ vld1.64 {q10-q11}, [r0,:128]!
+ veor q0, q0, q8
+ vld1.64 {q12-q13}, [r0,:128]!
+ veor q1, q1, q9
+ veor q8, q6, q10
+ vst1.8 {q0-q1}, [r8]!
+ veor q9, q4, q11
+ veor q10, q2, q12
+ vst1.8 {q8-q9}, [r8]!
+ veor q11, q7, q13
+ vst1.8 {q10-q11}, [r8]!
+
+ vld1.64 {q8}, [r0,:128] @ next round tweak
+ b .Lxts_dec_done
+.align 4
+.Lxts_dec_5:
+ vst1.64 {q13}, [r0,:128] @ next round tweak
+
+ veor q3, q3, q11
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, r10, #248 @ pass key schedule
+#endif
+ veor q4, q4, q12
+ mov r5, r1 @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_decrypt8
+
+ vld1.64 {q8-q9}, [r0,:128]!
+ vld1.64 {q10-q11}, [r0,:128]!
+ veor q0, q0, q8
+ vld1.64 {q12}, [r0,:128]!
+ veor q1, q1, q9
+ veor q8, q6, q10
+ vst1.8 {q0-q1}, [r8]!
+ veor q9, q4, q11
+ veor q10, q2, q12
+ vst1.8 {q8-q9}, [r8]!
+ vst1.8 {q10}, [r8]!
+
+ vld1.64 {q8}, [r0,:128] @ next round tweak
+ b .Lxts_dec_done
+.align 4
+.Lxts_dec_4:
+ vst1.64 {q12}, [r0,:128] @ next round tweak
+
+ veor q2, q2, q10
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, r10, #248 @ pass key schedule
+#endif
+ veor q3, q3, q11
+ mov r5, r1 @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_decrypt8
+
+ vld1.64 {q8-q9}, [r0,:128]!
+ vld1.64 {q10-q11}, [r0,:128]!
+ veor q0, q0, q8
+ veor q1, q1, q9
+ veor q8, q6, q10
+ vst1.8 {q0-q1}, [r8]!
+ veor q9, q4, q11
+ vst1.8 {q8-q9}, [r8]!
+
+ vld1.64 {q8}, [r0,:128] @ next round tweak
+ b .Lxts_dec_done
+.align 4
+.Lxts_dec_3:
+ vst1.64 {q11}, [r0,:128] @ next round tweak
+
+ veor q1, q1, q9
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, r10, #248 @ pass key schedule
+#endif
+ veor q2, q2, q10
+ mov r5, r1 @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_decrypt8
+
+ vld1.64 {q8-q9}, [r0,:128]!
+ vld1.64 {q10}, [r0,:128]!
+ veor q0, q0, q8
+ veor q1, q1, q9
+ veor q8, q6, q10
+ vst1.8 {q0-q1}, [r8]!
+ vst1.8 {q8}, [r8]!
+
+ vld1.64 {q8}, [r0,:128] @ next round tweak
+ b .Lxts_dec_done
+.align 4
+.Lxts_dec_2:
+ vst1.64 {q10}, [r0,:128] @ next round tweak
+
+ veor q0, q0, q8
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, r10, #248 @ pass key schedule
+#endif
+ veor q1, q1, q9
+ mov r5, r1 @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_decrypt8
+
+ vld1.64 {q8-q9}, [r0,:128]!
+ veor q0, q0, q8
+ veor q1, q1, q9
+ vst1.8 {q0-q1}, [r8]!
+
+ vld1.64 {q8}, [r0,:128] @ next round tweak
+ b .Lxts_dec_done
+.align 4
+.Lxts_dec_1:
+ mov r0, sp
+ veor q0, q8
+ mov r1, sp
+ vst1.8 {q0}, [sp,:128]
+ mov r2, r10
+ mov r4, r3 @ preserve fp
+ mov r5, r2 @ preserve magic
+
+ bl AES_decrypt
+
+ vld1.8 {q0}, [sp,:128]
+ veor q0, q0, q8
+ vst1.8 {q0}, [r8]!
+ mov r3, r4
+ mov r2, r5
+
+ vmov q8, q9 @ next round tweak
+
+.Lxts_dec_done:
+#ifndef XTS_CHAIN_TWEAK
+ adds r9, #0x10
+ beq .Lxts_dec_ret
+
+ @ calculate one round of extra tweak for the stolen ciphertext
+ vldmia r2, {q5}
+ vshr.s64 q6, q8, #63
+ vand q6, q6, q5
+ vadd.u64 q9, q8, q8
+ vswp d13,d12
+ veor q9, q9, q6
+
+ @ perform the final decryption with the last tweak value
+ vld1.8 {q0}, [r7]!
+ mov r0, sp
+ veor q0, q0, q9
+ mov r1, sp
+ vst1.8 {q0}, [sp,:128]
+ mov r2, r10
+ mov r4, r3 @ preserve fp
+
+ bl AES_decrypt
+
+ vld1.8 {q0}, [sp,:128]
+ veor q0, q0, q9
+ vst1.8 {q0}, [r8]
+
+ mov r6, r8
+.Lxts_dec_steal:
+ ldrb r1, [r8]
+ ldrb r0, [r7], #1
+ strb r1, [r8, #0x10]
+ strb r0, [r8], #1
+
+ subs r9, #1
+ bhi .Lxts_dec_steal
+
+ vld1.8 {q0}, [r6]
+ mov r0, sp
+ veor q0, q8
+ mov r1, sp
+ vst1.8 {q0}, [sp,:128]
+ mov r2, r10
+
+ bl AES_decrypt
+
+ vld1.8 {q0}, [sp,:128]
+ veor q0, q0, q8
+ vst1.8 {q0}, [r6]
+ mov r3, r4
+#endif
+
+.Lxts_dec_ret:
+ bic r0, r3, #0xf
+ vmov.i32 q0, #0
+ vmov.i32 q1, #0
+#ifdef XTS_CHAIN_TWEAK
+ ldr r1, [r3, #0x20+VFP_ABI_FRAME] @ chain tweak
+#endif
+.Lxts_dec_bzero: @ wipe key schedule [if any]
+ vstmia sp!, {q0-q1}
+ cmp sp, r0
+ bne .Lxts_dec_bzero
+
+ mov sp, r3
+#ifdef XTS_CHAIN_TWEAK
+ vst1.8 {q8}, [r1]
+#endif
+ VFP_ABI_POP
+ ldmia sp!, {r4-r10, pc} @ return
+
+.size bsaes_xts_decrypt,.-bsaes_xts_decrypt
+#endif
diff --git a/arch/arm/crypto/aesbs-glue.c b/arch/arm/crypto/aesbs-glue.c
new file mode 100644
index 000000000..6d6852986
--- /dev/null
+++ b/arch/arm/crypto/aesbs-glue.c
@@ -0,0 +1,437 @@
+/*
+ * linux/arch/arm/crypto/aesbs-glue.c - glue code for NEON bit sliced AES
+ *
+ * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@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 <asm/neon.h>
+#include <crypto/aes.h>
+#include <crypto/ablk_helper.h>
+#include <crypto/algapi.h>
+#include <linux/module.h>
+
+#include "aes_glue.h"
+
+#define BIT_SLICED_KEY_MAXSIZE (128 * (AES_MAXNR - 1) + 2 * AES_BLOCK_SIZE)
+
+struct BS_KEY {
+ struct AES_KEY rk;
+ int converted;
+ u8 __aligned(8) bs[BIT_SLICED_KEY_MAXSIZE];
+} __aligned(8);
+
+asmlinkage void bsaes_enc_key_convert(u8 out[], struct AES_KEY const *in);
+asmlinkage void bsaes_dec_key_convert(u8 out[], struct AES_KEY const *in);
+
+asmlinkage void bsaes_cbc_encrypt(u8 const in[], u8 out[], u32 bytes,
+ struct BS_KEY *key, u8 iv[]);
+
+asmlinkage void bsaes_ctr32_encrypt_blocks(u8 const in[], u8 out[], u32 blocks,
+ struct BS_KEY *key, u8 const iv[]);
+
+asmlinkage void bsaes_xts_encrypt(u8 const in[], u8 out[], u32 bytes,
+ struct BS_KEY *key, u8 tweak[]);
+
+asmlinkage void bsaes_xts_decrypt(u8 const in[], u8 out[], u32 bytes,
+ struct BS_KEY *key, u8 tweak[]);
+
+struct aesbs_cbc_ctx {
+ struct AES_KEY enc;
+ struct BS_KEY dec;
+};
+
+struct aesbs_ctr_ctx {
+ struct BS_KEY enc;
+};
+
+struct aesbs_xts_ctx {
+ struct BS_KEY enc;
+ struct BS_KEY dec;
+ struct AES_KEY twkey;
+};
+
+static int aesbs_cbc_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+ unsigned int key_len)
+{
+ struct aesbs_cbc_ctx *ctx = crypto_tfm_ctx(tfm);
+ int bits = key_len * 8;
+
+ if (private_AES_set_encrypt_key(in_key, bits, &ctx->enc)) {
+ tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+ ctx->dec.rk = ctx->enc;
+ private_AES_set_decrypt_key(in_key, bits, &ctx->dec.rk);
+ ctx->dec.converted = 0;
+ return 0;
+}
+
+static int aesbs_ctr_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+ unsigned int key_len)
+{
+ struct aesbs_ctr_ctx *ctx = crypto_tfm_ctx(tfm);
+ int bits = key_len * 8;
+
+ if (private_AES_set_encrypt_key(in_key, bits, &ctx->enc.rk)) {
+ tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+ ctx->enc.converted = 0;
+ return 0;
+}
+
+static int aesbs_xts_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+ unsigned int key_len)
+{
+ struct aesbs_xts_ctx *ctx = crypto_tfm_ctx(tfm);
+ int bits = key_len * 4;
+
+ if (private_AES_set_encrypt_key(in_key, bits, &ctx->enc.rk)) {
+ tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+ ctx->dec.rk = ctx->enc.rk;
+ private_AES_set_decrypt_key(in_key, bits, &ctx->dec.rk);
+ private_AES_set_encrypt_key(in_key + key_len / 2, bits, &ctx->twkey);
+ ctx->enc.converted = ctx->dec.converted = 0;
+ return 0;
+}
+
+static int aesbs_cbc_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct aesbs_cbc_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ while (walk.nbytes) {
+ u32 blocks = walk.nbytes / AES_BLOCK_SIZE;
+ u8 *src = walk.src.virt.addr;
+
+ if (walk.dst.virt.addr == walk.src.virt.addr) {
+ u8 *iv = walk.iv;
+
+ do {
+ crypto_xor(src, iv, AES_BLOCK_SIZE);
+ AES_encrypt(src, src, &ctx->enc);
+ iv = src;
+ src += AES_BLOCK_SIZE;
+ } while (--blocks);
+ memcpy(walk.iv, iv, AES_BLOCK_SIZE);
+ } else {
+ u8 *dst = walk.dst.virt.addr;
+
+ do {
+ crypto_xor(walk.iv, src, AES_BLOCK_SIZE);
+ AES_encrypt(walk.iv, dst, &ctx->enc);
+ memcpy(walk.iv, dst, AES_BLOCK_SIZE);
+ src += AES_BLOCK_SIZE;
+ dst += AES_BLOCK_SIZE;
+ } while (--blocks);
+ }
+ err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE);
+ }
+ return err;
+}
+
+static int aesbs_cbc_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct aesbs_cbc_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt_block(desc, &walk, 8 * AES_BLOCK_SIZE);
+
+ while ((walk.nbytes / AES_BLOCK_SIZE) >= 8) {
+ kernel_neon_begin();
+ bsaes_cbc_encrypt(walk.src.virt.addr, walk.dst.virt.addr,
+ walk.nbytes, &ctx->dec, walk.iv);
+ kernel_neon_end();
+ err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE);
+ }
+ while (walk.nbytes) {
+ u32 blocks = walk.nbytes / AES_BLOCK_SIZE;
+ u8 *dst = walk.dst.virt.addr;
+ u8 *src = walk.src.virt.addr;
+ u8 bk[2][AES_BLOCK_SIZE];
+ u8 *iv = walk.iv;
+
+ do {
+ if (walk.dst.virt.addr == walk.src.virt.addr)
+ memcpy(bk[blocks & 1], src, AES_BLOCK_SIZE);
+
+ AES_decrypt(src, dst, &ctx->dec.rk);
+ crypto_xor(dst, iv, AES_BLOCK_SIZE);
+
+ if (walk.dst.virt.addr == walk.src.virt.addr)
+ iv = bk[blocks & 1];
+ else
+ iv = src;
+
+ dst += AES_BLOCK_SIZE;
+ src += AES_BLOCK_SIZE;
+ } while (--blocks);
+ err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE);
+ }
+ return err;
+}
+
+static void inc_be128_ctr(__be32 ctr[], u32 addend)
+{
+ int i;
+
+ for (i = 3; i >= 0; i--, addend = 1) {
+ u32 n = be32_to_cpu(ctr[i]) + addend;
+
+ ctr[i] = cpu_to_be32(n);
+ if (n >= addend)
+ break;
+ }
+}
+
+static int aesbs_ctr_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct aesbs_ctr_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ u32 blocks;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt_block(desc, &walk, 8 * AES_BLOCK_SIZE);
+
+ while ((blocks = walk.nbytes / AES_BLOCK_SIZE)) {
+ u32 tail = walk.nbytes % AES_BLOCK_SIZE;
+ __be32 *ctr = (__be32 *)walk.iv;
+ u32 headroom = UINT_MAX - be32_to_cpu(ctr[3]);
+
+ /* avoid 32 bit counter overflow in the NEON code */
+ if (unlikely(headroom < blocks)) {
+ blocks = headroom + 1;
+ tail = walk.nbytes - blocks * AES_BLOCK_SIZE;
+ }
+ kernel_neon_begin();
+ bsaes_ctr32_encrypt_blocks(walk.src.virt.addr,
+ walk.dst.virt.addr, blocks,
+ &ctx->enc, walk.iv);
+ kernel_neon_end();
+ inc_be128_ctr(ctr, blocks);
+
+ nbytes -= blocks * AES_BLOCK_SIZE;
+ if (nbytes && nbytes == tail && nbytes <= AES_BLOCK_SIZE)
+ break;
+
+ err = blkcipher_walk_done(desc, &walk, tail);
+ }
+ if (walk.nbytes) {
+ u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
+ u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
+ u8 ks[AES_BLOCK_SIZE];
+
+ AES_encrypt(walk.iv, ks, &ctx->enc.rk);
+ if (tdst != tsrc)
+ memcpy(tdst, tsrc, nbytes);
+ crypto_xor(tdst, ks, nbytes);
+ err = blkcipher_walk_done(desc, &walk, 0);
+ }
+ return err;
+}
+
+static int aesbs_xts_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct aesbs_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt_block(desc, &walk, 8 * AES_BLOCK_SIZE);
+
+ /* generate the initial tweak */
+ AES_encrypt(walk.iv, walk.iv, &ctx->twkey);
+
+ while (walk.nbytes) {
+ kernel_neon_begin();
+ bsaes_xts_encrypt(walk.src.virt.addr, walk.dst.virt.addr,
+ walk.nbytes, &ctx->enc, walk.iv);
+ kernel_neon_end();
+ err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE);
+ }
+ return err;
+}
+
+static int aesbs_xts_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct aesbs_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt_block(desc, &walk, 8 * AES_BLOCK_SIZE);
+
+ /* generate the initial tweak */
+ AES_encrypt(walk.iv, walk.iv, &ctx->twkey);
+
+ while (walk.nbytes) {
+ kernel_neon_begin();
+ bsaes_xts_decrypt(walk.src.virt.addr, walk.dst.virt.addr,
+ walk.nbytes, &ctx->dec, walk.iv);
+ kernel_neon_end();
+ err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE);
+ }
+ return err;
+}
+
+static struct crypto_alg aesbs_algs[] = { {
+ .cra_name = "__cbc-aes-neonbs",
+ .cra_driver_name = "__driver-cbc-aes-neonbs",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
+ CRYPTO_ALG_INTERNAL,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct aesbs_cbc_ctx),
+ .cra_alignmask = 7,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_blkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = aesbs_cbc_set_key,
+ .encrypt = aesbs_cbc_encrypt,
+ .decrypt = aesbs_cbc_decrypt,
+ },
+}, {
+ .cra_name = "__ctr-aes-neonbs",
+ .cra_driver_name = "__driver-ctr-aes-neonbs",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
+ CRYPTO_ALG_INTERNAL,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct aesbs_ctr_ctx),
+ .cra_alignmask = 7,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_blkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = aesbs_ctr_set_key,
+ .encrypt = aesbs_ctr_encrypt,
+ .decrypt = aesbs_ctr_encrypt,
+ },
+}, {
+ .cra_name = "__xts-aes-neonbs",
+ .cra_driver_name = "__driver-xts-aes-neonbs",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
+ CRYPTO_ALG_INTERNAL,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct aesbs_xts_ctx),
+ .cra_alignmask = 7,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_blkcipher = {
+ .min_keysize = 2 * AES_MIN_KEY_SIZE,
+ .max_keysize = 2 * AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = aesbs_xts_set_key,
+ .encrypt = aesbs_xts_encrypt,
+ .decrypt = aesbs_xts_decrypt,
+ },
+}, {
+ .cra_name = "cbc(aes)",
+ .cra_driver_name = "cbc-aes-neonbs",
+ .cra_priority = 300,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_helper_ctx),
+ .cra_alignmask = 7,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = ablk_init,
+ .cra_exit = ablk_exit,
+ .cra_ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = __ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ }
+}, {
+ .cra_name = "ctr(aes)",
+ .cra_driver_name = "ctr-aes-neonbs",
+ .cra_priority = 300,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct async_helper_ctx),
+ .cra_alignmask = 7,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = ablk_init,
+ .cra_exit = ablk_exit,
+ .cra_ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ }
+}, {
+ .cra_name = "xts(aes)",
+ .cra_driver_name = "xts-aes-neonbs",
+ .cra_priority = 300,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_helper_ctx),
+ .cra_alignmask = 7,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = ablk_init,
+ .cra_exit = ablk_exit,
+ .cra_ablkcipher = {
+ .min_keysize = 2 * AES_MIN_KEY_SIZE,
+ .max_keysize = 2 * AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ }
+} };
+
+static int __init aesbs_mod_init(void)
+{
+ if (!cpu_has_neon())
+ return -ENODEV;
+
+ return crypto_register_algs(aesbs_algs, ARRAY_SIZE(aesbs_algs));
+}
+
+static void __exit aesbs_mod_exit(void)
+{
+ crypto_unregister_algs(aesbs_algs, ARRAY_SIZE(aesbs_algs));
+}
+
+module_init(aesbs_mod_init);
+module_exit(aesbs_mod_exit);
+
+MODULE_DESCRIPTION("Bit sliced AES in CBC/CTR/XTS modes using NEON");
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/crypto/bsaes-armv7.pl b/arch/arm/crypto/bsaes-armv7.pl
new file mode 100644
index 000000000..a4d3856e7
--- /dev/null
+++ b/arch/arm/crypto/bsaes-armv7.pl
@@ -0,0 +1,2471 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+#
+# Specific modes and adaptation for Linux kernel by Ard Biesheuvel
+# <ard.biesheuvel@linaro.org>. Permission to use under GPL terms is
+# granted.
+# ====================================================================
+
+# Bit-sliced AES for ARM NEON
+#
+# February 2012.
+#
+# This implementation is direct adaptation of bsaes-x86_64 module for
+# ARM NEON. Except that this module is endian-neutral [in sense that
+# it can be compiled for either endianness] by courtesy of vld1.8's
+# neutrality. Initial version doesn't implement interface to OpenSSL,
+# only low-level primitives and unsupported entry points, just enough
+# to collect performance results, which for Cortex-A8 core are:
+#
+# encrypt 19.5 cycles per byte processed with 128-bit key
+# decrypt 22.1 cycles per byte processed with 128-bit key
+# key conv. 440 cycles per 128-bit key/0.18 of 8x block
+#
+# Snapdragon S4 encrypts byte in 17.6 cycles and decrypts in 19.7,
+# which is [much] worse than anticipated (for further details see
+# http://www.openssl.org/~appro/Snapdragon-S4.html).
+#
+# Cortex-A15 manages in 14.2/16.1 cycles [when integer-only code
+# manages in 20.0 cycles].
+#
+# When comparing to x86_64 results keep in mind that NEON unit is
+# [mostly] single-issue and thus can't [fully] benefit from
+# instruction-level parallelism. And when comparing to aes-armv4
+# results keep in mind key schedule conversion overhead (see
+# bsaes-x86_64.pl for further details)...
+#
+# <appro@openssl.org>
+
+# April-August 2013
+#
+# Add CBC, CTR and XTS subroutines, adapt for kernel use.
+#
+# <ard.biesheuvel@linaro.org>
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+my ($inp,$out,$len,$key)=("r0","r1","r2","r3");
+my @XMM=map("q$_",(0..15));
+
+{
+my ($key,$rounds,$const)=("r4","r5","r6");
+
+sub Dlo() { shift=~m|q([1]?[0-9])|?"d".($1*2):""; }
+sub Dhi() { shift=~m|q([1]?[0-9])|?"d".($1*2+1):""; }
+
+sub Sbox {
+# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
+# output in lsb > [b0, b1, b4, b6, b3, b7, b2, b5] < msb
+my @b=@_[0..7];
+my @t=@_[8..11];
+my @s=@_[12..15];
+ &InBasisChange (@b);
+ &Inv_GF256 (@b[6,5,0,3,7,1,4,2],@t,@s);
+ &OutBasisChange (@b[7,1,4,2,6,5,0,3]);
+}
+
+sub InBasisChange {
+# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
+# output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb
+my @b=@_[0..7];
+$code.=<<___;
+ veor @b[2], @b[2], @b[1]
+ veor @b[5], @b[5], @b[6]
+ veor @b[3], @b[3], @b[0]
+ veor @b[6], @b[6], @b[2]
+ veor @b[5], @b[5], @b[0]
+
+ veor @b[6], @b[6], @b[3]
+ veor @b[3], @b[3], @b[7]
+ veor @b[7], @b[7], @b[5]
+ veor @b[3], @b[3], @b[4]
+ veor @b[4], @b[4], @b[5]
+
+ veor @b[2], @b[2], @b[7]
+ veor @b[3], @b[3], @b[1]
+ veor @b[1], @b[1], @b[5]
+___
+}
+
+sub OutBasisChange {
+# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
+# output in lsb > [b6, b1, b2, b4, b7, b0, b3, b5] < msb
+my @b=@_[0..7];
+$code.=<<___;
+ veor @b[0], @b[0], @b[6]
+ veor @b[1], @b[1], @b[4]
+ veor @b[4], @b[4], @b[6]
+ veor @b[2], @b[2], @b[0]
+ veor @b[6], @b[6], @b[1]
+
+ veor @b[1], @b[1], @b[5]
+ veor @b[5], @b[5], @b[3]
+ veor @b[3], @b[3], @b[7]
+ veor @b[7], @b[7], @b[5]
+ veor @b[2], @b[2], @b[5]
+
+ veor @b[4], @b[4], @b[7]
+___
+}
+
+sub InvSbox {
+# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
+# output in lsb > [b0, b1, b6, b4, b2, b7, b3, b5] < msb
+my @b=@_[0..7];
+my @t=@_[8..11];
+my @s=@_[12..15];
+ &InvInBasisChange (@b);
+ &Inv_GF256 (@b[5,1,2,6,3,7,0,4],@t,@s);
+ &InvOutBasisChange (@b[3,7,0,4,5,1,2,6]);
+}
+
+sub InvInBasisChange { # OutBasisChange in reverse (with twist)
+my @b=@_[5,1,2,6,3,7,0,4];
+$code.=<<___
+ veor @b[1], @b[1], @b[7]
+ veor @b[4], @b[4], @b[7]
+
+ veor @b[7], @b[7], @b[5]
+ veor @b[1], @b[1], @b[3]
+ veor @b[2], @b[2], @b[5]
+ veor @b[3], @b[3], @b[7]
+
+ veor @b[6], @b[6], @b[1]
+ veor @b[2], @b[2], @b[0]
+ veor @b[5], @b[5], @b[3]
+ veor @b[4], @b[4], @b[6]
+ veor @b[0], @b[0], @b[6]
+ veor @b[1], @b[1], @b[4]
+___
+}
+
+sub InvOutBasisChange { # InBasisChange in reverse
+my @b=@_[2,5,7,3,6,1,0,4];
+$code.=<<___;
+ veor @b[1], @b[1], @b[5]
+ veor @b[2], @b[2], @b[7]
+
+ veor @b[3], @b[3], @b[1]
+ veor @b[4], @b[4], @b[5]
+ veor @b[7], @b[7], @b[5]
+ veor @b[3], @b[3], @b[4]
+ veor @b[5], @b[5], @b[0]
+ veor @b[3], @b[3], @b[7]
+ veor @b[6], @b[6], @b[2]
+ veor @b[2], @b[2], @b[1]
+ veor @b[6], @b[6], @b[3]
+
+ veor @b[3], @b[3], @b[0]
+ veor @b[5], @b[5], @b[6]
+___
+}
+
+sub Mul_GF4 {
+#;*************************************************************
+#;* Mul_GF4: Input x0-x1,y0-y1 Output x0-x1 Temp t0 (8) *
+#;*************************************************************
+my ($x0,$x1,$y0,$y1,$t0,$t1)=@_;
+$code.=<<___;
+ veor $t0, $y0, $y1
+ vand $t0, $t0, $x0
+ veor $x0, $x0, $x1
+ vand $t1, $x1, $y0
+ vand $x0, $x0, $y1
+ veor $x1, $t1, $t0
+ veor $x0, $x0, $t1
+___
+}
+
+sub Mul_GF4_N { # not used, see next subroutine
+# multiply and scale by N
+my ($x0,$x1,$y0,$y1,$t0)=@_;
+$code.=<<___;
+ veor $t0, $y0, $y1
+ vand $t0, $t0, $x0
+ veor $x0, $x0, $x1
+ vand $x1, $x1, $y0
+ vand $x0, $x0, $y1
+ veor $x1, $x1, $x0
+ veor $x0, $x0, $t0
+___
+}
+
+sub Mul_GF4_N_GF4 {
+# interleaved Mul_GF4_N and Mul_GF4
+my ($x0,$x1,$y0,$y1,$t0,
+ $x2,$x3,$y2,$y3,$t1)=@_;
+$code.=<<___;
+ veor $t0, $y0, $y1
+ veor $t1, $y2, $y3
+ vand $t0, $t0, $x0
+ vand $t1, $t1, $x2
+ veor $x0, $x0, $x1
+ veor $x2, $x2, $x3
+ vand $x1, $x1, $y0
+ vand $x3, $x3, $y2
+ vand $x0, $x0, $y1
+ vand $x2, $x2, $y3
+ veor $x1, $x1, $x0
+ veor $x2, $x2, $x3
+ veor $x0, $x0, $t0
+ veor $x3, $x3, $t1
+___
+}
+sub Mul_GF16_2 {
+my @x=@_[0..7];
+my @y=@_[8..11];
+my @t=@_[12..15];
+$code.=<<___;
+ veor @t[0], @x[0], @x[2]
+ veor @t[1], @x[1], @x[3]
+___
+ &Mul_GF4 (@x[0], @x[1], @y[0], @y[1], @t[2..3]);
+$code.=<<___;
+ veor @y[0], @y[0], @y[2]
+ veor @y[1], @y[1], @y[3]
+___
+ Mul_GF4_N_GF4 (@t[0], @t[1], @y[0], @y[1], @t[3],
+ @x[2], @x[3], @y[2], @y[3], @t[2]);
+$code.=<<___;
+ veor @x[0], @x[0], @t[0]
+ veor @x[2], @x[2], @t[0]
+ veor @x[1], @x[1], @t[1]
+ veor @x[3], @x[3], @t[1]
+
+ veor @t[0], @x[4], @x[6]
+ veor @t[1], @x[5], @x[7]
+___
+ &Mul_GF4_N_GF4 (@t[0], @t[1], @y[0], @y[1], @t[3],
+ @x[6], @x[7], @y[2], @y[3], @t[2]);
+$code.=<<___;
+ veor @y[0], @y[0], @y[2]
+ veor @y[1], @y[1], @y[3]
+___
+ &Mul_GF4 (@x[4], @x[5], @y[0], @y[1], @t[2..3]);
+$code.=<<___;
+ veor @x[4], @x[4], @t[0]
+ veor @x[6], @x[6], @t[0]
+ veor @x[5], @x[5], @t[1]
+ veor @x[7], @x[7], @t[1]
+___
+}
+sub Inv_GF256 {
+#;********************************************************************
+#;* Inv_GF256: Input x0-x7 Output x0-x7 Temp t0-t3,s0-s3 (144) *
+#;********************************************************************
+my @x=@_[0..7];
+my @t=@_[8..11];
+my @s=@_[12..15];
+# direct optimizations from hardware
+$code.=<<___;
+ veor @t[3], @x[4], @x[6]
+ veor @t[2], @x[5], @x[7]
+ veor @t[1], @x[1], @x[3]
+ veor @s[1], @x[7], @x[6]
+ vmov @t[0], @t[2]
+ veor @s[0], @x[0], @x[2]
+
+ vorr @t[2], @t[2], @t[1]
+ veor @s[3], @t[3], @t[0]
+ vand @s[2], @t[3], @s[0]
+ vorr @t[3], @t[3], @s[0]
+ veor @s[0], @s[0], @t[1]
+ vand @t[0], @t[0], @t[1]
+ veor @t[1], @x[3], @x[2]
+ vand @s[3], @s[3], @s[0]
+ vand @s[1], @s[1], @t[1]
+ veor @t[1], @x[4], @x[5]
+ veor @s[0], @x[1], @x[0]
+ veor @t[3], @t[3], @s[1]
+ veor @t[2], @t[2], @s[1]
+ vand @s[1], @t[1], @s[0]
+ vorr @t[1], @t[1], @s[0]
+ veor @t[3], @t[3], @s[3]
+ veor @t[0], @t[0], @s[1]
+ veor @t[2], @t[2], @s[2]
+ veor @t[1], @t[1], @s[3]
+ veor @t[0], @t[0], @s[2]
+ vand @s[0], @x[7], @x[3]
+ veor @t[1], @t[1], @s[2]
+ vand @s[1], @x[6], @x[2]
+ vand @s[2], @x[5], @x[1]
+ vorr @s[3], @x[4], @x[0]
+ veor @t[3], @t[3], @s[0]
+ veor @t[1], @t[1], @s[2]
+ veor @t[0], @t[0], @s[3]
+ veor @t[2], @t[2], @s[1]
+
+ @ Inv_GF16 \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
+
+ @ new smaller inversion
+
+ vand @s[2], @t[3], @t[1]
+ vmov @s[0], @t[0]
+
+ veor @s[1], @t[2], @s[2]
+ veor @s[3], @t[0], @s[2]
+ veor @s[2], @t[0], @s[2] @ @s[2]=@s[3]
+
+ vbsl @s[1], @t[1], @t[0]
+ vbsl @s[3], @t[3], @t[2]
+ veor @t[3], @t[3], @t[2]
+
+ vbsl @s[0], @s[1], @s[2]
+ vbsl @t[0], @s[2], @s[1]
+
+ vand @s[2], @s[0], @s[3]
+ veor @t[1], @t[1], @t[0]
+
+ veor @s[2], @s[2], @t[3]
+___
+# output in s3, s2, s1, t1
+
+# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \t2, \t3, \t0, \t1, \s0, \s1, \s2, \s3
+
+# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3
+ &Mul_GF16_2(@x,@s[3,2,1],@t[1],@s[0],@t[0,2,3]);
+
+### output msb > [x3,x2,x1,x0,x7,x6,x5,x4] < lsb
+}
+
+# AES linear components
+
+sub ShiftRows {
+my @x=@_[0..7];
+my @t=@_[8..11];
+my $mask=pop;
+$code.=<<___;
+ vldmia $key!, {@t[0]-@t[3]}
+ veor @t[0], @t[0], @x[0]
+ veor @t[1], @t[1], @x[1]
+ vtbl.8 `&Dlo(@x[0])`, {@t[0]}, `&Dlo($mask)`
+ vtbl.8 `&Dhi(@x[0])`, {@t[0]}, `&Dhi($mask)`
+ vldmia $key!, {@t[0]}
+ veor @t[2], @t[2], @x[2]
+ vtbl.8 `&Dlo(@x[1])`, {@t[1]}, `&Dlo($mask)`
+ vtbl.8 `&Dhi(@x[1])`, {@t[1]}, `&Dhi($mask)`
+ vldmia $key!, {@t[1]}
+ veor @t[3], @t[3], @x[3]
+ vtbl.8 `&Dlo(@x[2])`, {@t[2]}, `&Dlo($mask)`
+ vtbl.8 `&Dhi(@x[2])`, {@t[2]}, `&Dhi($mask)`
+ vldmia $key!, {@t[2]}
+ vtbl.8 `&Dlo(@x[3])`, {@t[3]}, `&Dlo($mask)`
+ vtbl.8 `&Dhi(@x[3])`, {@t[3]}, `&Dhi($mask)`
+ vldmia $key!, {@t[3]}
+ veor @t[0], @t[0], @x[4]
+ veor @t[1], @t[1], @x[5]
+ vtbl.8 `&Dlo(@x[4])`, {@t[0]}, `&Dlo($mask)`
+ vtbl.8 `&Dhi(@x[4])`, {@t[0]}, `&Dhi($mask)`
+ veor @t[2], @t[2], @x[6]
+ vtbl.8 `&Dlo(@x[5])`, {@t[1]}, `&Dlo($mask)`
+ vtbl.8 `&Dhi(@x[5])`, {@t[1]}, `&Dhi($mask)`
+ veor @t[3], @t[3], @x[7]
+ vtbl.8 `&Dlo(@x[6])`, {@t[2]}, `&Dlo($mask)`
+ vtbl.8 `&Dhi(@x[6])`, {@t[2]}, `&Dhi($mask)`
+ vtbl.8 `&Dlo(@x[7])`, {@t[3]}, `&Dlo($mask)`
+ vtbl.8 `&Dhi(@x[7])`, {@t[3]}, `&Dhi($mask)`
+___
+}
+
+sub MixColumns {
+# modified to emit output in order suitable for feeding back to aesenc[last]
+my @x=@_[0..7];
+my @t=@_[8..15];
+my $inv=@_[16]; # optional
+$code.=<<___;
+ vext.8 @t[0], @x[0], @x[0], #12 @ x0 <<< 32
+ vext.8 @t[1], @x[1], @x[1], #12
+ veor @x[0], @x[0], @t[0] @ x0 ^ (x0 <<< 32)
+ vext.8 @t[2], @x[2], @x[2], #12
+ veor @x[1], @x[1], @t[1]
+ vext.8 @t[3], @x[3], @x[3], #12
+ veor @x[2], @x[2], @t[2]
+ vext.8 @t[4], @x[4], @x[4], #12
+ veor @x[3], @x[3], @t[3]
+ vext.8 @t[5], @x[5], @x[5], #12
+ veor @x[4], @x[4], @t[4]
+ vext.8 @t[6], @x[6], @x[6], #12
+ veor @x[5], @x[5], @t[5]
+ vext.8 @t[7], @x[7], @x[7], #12
+ veor @x[6], @x[6], @t[6]
+
+ veor @t[1], @t[1], @x[0]
+ veor @x[7], @x[7], @t[7]
+ vext.8 @x[0], @x[0], @x[0], #8 @ (x0 ^ (x0 <<< 32)) <<< 64)
+ veor @t[2], @t[2], @x[1]
+ veor @t[0], @t[0], @x[7]
+ veor @t[1], @t[1], @x[7]
+ vext.8 @x[1], @x[1], @x[1], #8
+ veor @t[5], @t[5], @x[4]
+ veor @x[0], @x[0], @t[0]
+ veor @t[6], @t[6], @x[5]
+ veor @x[1], @x[1], @t[1]
+ vext.8 @t[0], @x[4], @x[4], #8
+ veor @t[4], @t[4], @x[3]
+ vext.8 @t[1], @x[5], @x[5], #8
+ veor @t[7], @t[7], @x[6]
+ vext.8 @x[4], @x[3], @x[3], #8
+ veor @t[3], @t[3], @x[2]
+ vext.8 @x[5], @x[7], @x[7], #8
+ veor @t[4], @t[4], @x[7]
+ vext.8 @x[3], @x[6], @x[6], #8
+ veor @t[3], @t[3], @x[7]
+ vext.8 @x[6], @x[2], @x[2], #8
+ veor @x[7], @t[1], @t[5]
+___
+$code.=<<___ if (!$inv);
+ veor @x[2], @t[0], @t[4]
+ veor @x[4], @x[4], @t[3]
+ veor @x[5], @x[5], @t[7]
+ veor @x[3], @x[3], @t[6]
+ @ vmov @x[2], @t[0]
+ veor @x[6], @x[6], @t[2]
+ @ vmov @x[7], @t[1]
+___
+$code.=<<___ if ($inv);
+ veor @t[3], @t[3], @x[4]
+ veor @x[5], @x[5], @t[7]
+ veor @x[2], @x[3], @t[6]
+ veor @x[3], @t[0], @t[4]
+ veor @x[4], @x[6], @t[2]
+ vmov @x[6], @t[3]
+ @ vmov @x[7], @t[1]
+___
+}
+
+sub InvMixColumns_orig {
+my @x=@_[0..7];
+my @t=@_[8..15];
+
+$code.=<<___;
+ @ multiplication by 0x0e
+ vext.8 @t[7], @x[7], @x[7], #12
+ vmov @t[2], @x[2]
+ veor @x[2], @x[2], @x[5] @ 2 5
+ veor @x[7], @x[7], @x[5] @ 7 5
+ vext.8 @t[0], @x[0], @x[0], #12
+ vmov @t[5], @x[5]
+ veor @x[5], @x[5], @x[0] @ 5 0 [1]
+ veor @x[0], @x[0], @x[1] @ 0 1
+ vext.8 @t[1], @x[1], @x[1], #12
+ veor @x[1], @x[1], @x[2] @ 1 25
+ veor @x[0], @x[0], @x[6] @ 01 6 [2]
+ vext.8 @t[3], @x[3], @x[3], #12
+ veor @x[1], @x[1], @x[3] @ 125 3 [4]
+ veor @x[2], @x[2], @x[0] @ 25 016 [3]
+ veor @x[3], @x[3], @x[7] @ 3 75
+ veor @x[7], @x[7], @x[6] @ 75 6 [0]
+ vext.8 @t[6], @x[6], @x[6], #12
+ vmov @t[4], @x[4]
+ veor @x[6], @x[6], @x[4] @ 6 4
+ veor @x[4], @x[4], @x[3] @ 4 375 [6]
+ veor @x[3], @x[3], @x[7] @ 375 756=36
+ veor @x[6], @x[6], @t[5] @ 64 5 [7]
+ veor @x[3], @x[3], @t[2] @ 36 2
+ vext.8 @t[5], @t[5], @t[5], #12
+ veor @x[3], @x[3], @t[4] @ 362 4 [5]
+___
+ my @y = @x[7,5,0,2,1,3,4,6];
+$code.=<<___;
+ @ multiplication by 0x0b
+ veor @y[1], @y[1], @y[0]
+ veor @y[0], @y[0], @t[0]
+ vext.8 @t[2], @t[2], @t[2], #12
+ veor @y[1], @y[1], @t[1]
+ veor @y[0], @y[0], @t[5]
+ vext.8 @t[4], @t[4], @t[4], #12
+ veor @y[1], @y[1], @t[6]
+ veor @y[0], @y[0], @t[7]
+ veor @t[7], @t[7], @t[6] @ clobber t[7]
+
+ veor @y[3], @y[3], @t[0]
+ veor @y[1], @y[1], @y[0]
+ vext.8 @t[0], @t[0], @t[0], #12
+ veor @y[2], @y[2], @t[1]
+ veor @y[4], @y[4], @t[1]
+ vext.8 @t[1], @t[1], @t[1], #12
+ veor @y[2], @y[2], @t[2]
+ veor @y[3], @y[3], @t[2]
+ veor @y[5], @y[5], @t[2]
+ veor @y[2], @y[2], @t[7]
+ vext.8 @t[2], @t[2], @t[2], #12
+ veor @y[3], @y[3], @t[3]
+ veor @y[6], @y[6], @t[3]
+ veor @y[4], @y[4], @t[3]
+ veor @y[7], @y[7], @t[4]
+ vext.8 @t[3], @t[3], @t[3], #12
+ veor @y[5], @y[5], @t[4]
+ veor @y[7], @y[7], @t[7]
+ veor @t[7], @t[7], @t[5] @ clobber t[7] even more
+ veor @y[3], @y[3], @t[5]
+ veor @y[4], @y[4], @t[4]
+
+ veor @y[5], @y[5], @t[7]
+ vext.8 @t[4], @t[4], @t[4], #12
+ veor @y[6], @y[6], @t[7]
+ veor @y[4], @y[4], @t[7]
+
+ veor @t[7], @t[7], @t[5]
+ vext.8 @t[5], @t[5], @t[5], #12
+
+ @ multiplication by 0x0d
+ veor @y[4], @y[4], @y[7]
+ veor @t[7], @t[7], @t[6] @ restore t[7]
+ veor @y[7], @y[7], @t[4]
+ vext.8 @t[6], @t[6], @t[6], #12
+ veor @y[2], @y[2], @t[0]
+ veor @y[7], @y[7], @t[5]
+ vext.8 @t[7], @t[7], @t[7], #12
+ veor @y[2], @y[2], @t[2]
+
+ veor @y[3], @y[3], @y[1]
+ veor @y[1], @y[1], @t[1]
+ veor @y[0], @y[0], @t[0]
+ veor @y[3], @y[3], @t[0]
+ veor @y[1], @y[1], @t[5]
+ veor @y[0], @y[0], @t[5]
+ vext.8 @t[0], @t[0], @t[0], #12
+ veor @y[1], @y[1], @t[7]
+ veor @y[0], @y[0], @t[6]
+ veor @y[3], @y[3], @y[1]
+ veor @y[4], @y[4], @t[1]
+ vext.8 @t[1], @t[1], @t[1], #12
+
+ veor @y[7], @y[7], @t[7]
+ veor @y[4], @y[4], @t[2]
+ veor @y[5], @y[5], @t[2]
+ veor @y[2], @y[2], @t[6]
+ veor @t[6], @t[6], @t[3] @ clobber t[6]
+ vext.8 @t[2], @t[2], @t[2], #12
+ veor @y[4], @y[4], @y[7]
+ veor @y[3], @y[3], @t[6]
+
+ veor @y[6], @y[6], @t[6]
+ veor @y[5], @y[5], @t[5]
+ vext.8 @t[5], @t[5], @t[5], #12
+ veor @y[6], @y[6], @t[4]
+ vext.8 @t[4], @t[4], @t[4], #12
+ veor @y[5], @y[5], @t[6]
+ veor @y[6], @y[6], @t[7]
+ vext.8 @t[7], @t[7], @t[7], #12
+ veor @t[6], @t[6], @t[3] @ restore t[6]
+ vext.8 @t[3], @t[3], @t[3], #12
+
+ @ multiplication by 0x09
+ veor @y[4], @y[4], @y[1]
+ veor @t[1], @t[1], @y[1] @ t[1]=y[1]
+ veor @t[0], @t[0], @t[5] @ clobber t[0]
+ vext.8 @t[6], @t[6], @t[6], #12
+ veor @t[1], @t[1], @t[5]
+ veor @y[3], @y[3], @t[0]
+ veor @t[0], @t[0], @y[0] @ t[0]=y[0]
+ veor @t[1], @t[1], @t[6]
+ veor @t[6], @t[6], @t[7] @ clobber t[6]
+ veor @y[4], @y[4], @t[1]
+ veor @y[7], @y[7], @t[4]
+ veor @y[6], @y[6], @t[3]
+ veor @y[5], @y[5], @t[2]
+ veor @t[4], @t[4], @y[4] @ t[4]=y[4]
+ veor @t[3], @t[3], @y[3] @ t[3]=y[3]
+ veor @t[5], @t[5], @y[5] @ t[5]=y[5]
+ veor @t[2], @t[2], @y[2] @ t[2]=y[2]
+ veor @t[3], @t[3], @t[7]
+ veor @XMM[5], @t[5], @t[6]
+ veor @XMM[6], @t[6], @y[6] @ t[6]=y[6]
+ veor @XMM[2], @t[2], @t[6]
+ veor @XMM[7], @t[7], @y[7] @ t[7]=y[7]
+
+ vmov @XMM[0], @t[0]
+ vmov @XMM[1], @t[1]
+ @ vmov @XMM[2], @t[2]
+ vmov @XMM[3], @t[3]
+ vmov @XMM[4], @t[4]
+ @ vmov @XMM[5], @t[5]
+ @ vmov @XMM[6], @t[6]
+ @ vmov @XMM[7], @t[7]
+___
+}
+
+sub InvMixColumns {
+my @x=@_[0..7];
+my @t=@_[8..15];
+
+# Thanks to Jussi Kivilinna for providing pointer to
+#
+# | 0e 0b 0d 09 | | 02 03 01 01 | | 05 00 04 00 |
+# | 09 0e 0b 0d | = | 01 02 03 01 | x | 00 05 00 04 |
+# | 0d 09 0e 0b | | 01 01 02 03 | | 04 00 05 00 |
+# | 0b 0d 09 0e | | 03 01 01 02 | | 00 04 00 05 |
+
+$code.=<<___;
+ @ multiplication by 0x05-0x00-0x04-0x00
+ vext.8 @t[0], @x[0], @x[0], #8
+ vext.8 @t[6], @x[6], @x[6], #8
+ vext.8 @t[7], @x[7], @x[7], #8
+ veor @t[0], @t[0], @x[0]
+ vext.8 @t[1], @x[1], @x[1], #8
+ veor @t[6], @t[6], @x[6]
+ vext.8 @t[2], @x[2], @x[2], #8
+ veor @t[7], @t[7], @x[7]
+ vext.8 @t[3], @x[3], @x[3], #8
+ veor @t[1], @t[1], @x[1]
+ vext.8 @t[4], @x[4], @x[4], #8
+ veor @t[2], @t[2], @x[2]
+ vext.8 @t[5], @x[5], @x[5], #8
+ veor @t[3], @t[3], @x[3]
+ veor @t[4], @t[4], @x[4]
+ veor @t[5], @t[5], @x[5]
+
+ veor @x[0], @x[0], @t[6]
+ veor @x[1], @x[1], @t[6]
+ veor @x[2], @x[2], @t[0]
+ veor @x[4], @x[4], @t[2]
+ veor @x[3], @x[3], @t[1]
+ veor @x[1], @x[1], @t[7]
+ veor @x[2], @x[2], @t[7]
+ veor @x[4], @x[4], @t[6]
+ veor @x[5], @x[5], @t[3]
+ veor @x[3], @x[3], @t[6]
+ veor @x[6], @x[6], @t[4]
+ veor @x[4], @x[4], @t[7]
+ veor @x[5], @x[5], @t[7]
+ veor @x[7], @x[7], @t[5]
+___
+ &MixColumns (@x,@t,1); # flipped 2<->3 and 4<->6
+}
+
+sub swapmove {
+my ($a,$b,$n,$mask,$t)=@_;
+$code.=<<___;
+ vshr.u64 $t, $b, #$n
+ veor $t, $t, $a
+ vand $t, $t, $mask
+ veor $a, $a, $t
+ vshl.u64 $t, $t, #$n
+ veor $b, $b, $t
+___
+}
+sub swapmove2x {
+my ($a0,$b0,$a1,$b1,$n,$mask,$t0,$t1)=@_;
+$code.=<<___;
+ vshr.u64 $t0, $b0, #$n
+ vshr.u64 $t1, $b1, #$n
+ veor $t0, $t0, $a0
+ veor $t1, $t1, $a1
+ vand $t0, $t0, $mask
+ vand $t1, $t1, $mask
+ veor $a0, $a0, $t0
+ vshl.u64 $t0, $t0, #$n
+ veor $a1, $a1, $t1
+ vshl.u64 $t1, $t1, #$n
+ veor $b0, $b0, $t0
+ veor $b1, $b1, $t1
+___
+}
+
+sub bitslice {
+my @x=reverse(@_[0..7]);
+my ($t0,$t1,$t2,$t3)=@_[8..11];
+$code.=<<___;
+ vmov.i8 $t0,#0x55 @ compose .LBS0
+ vmov.i8 $t1,#0x33 @ compose .LBS1
+___
+ &swapmove2x(@x[0,1,2,3],1,$t0,$t2,$t3);
+ &swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
+$code.=<<___;
+ vmov.i8 $t0,#0x0f @ compose .LBS2
+___
+ &swapmove2x(@x[0,2,1,3],2,$t1,$t2,$t3);
+ &swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
+
+ &swapmove2x(@x[0,4,1,5],4,$t0,$t2,$t3);
+ &swapmove2x(@x[2,6,3,7],4,$t0,$t2,$t3);
+}
+
+$code.=<<___;
+#ifndef __KERNEL__
+# include "arm_arch.h"
+
+# define VFP_ABI_PUSH vstmdb sp!,{d8-d15}
+# define VFP_ABI_POP vldmia sp!,{d8-d15}
+# define VFP_ABI_FRAME 0x40
+#else
+# define VFP_ABI_PUSH
+# define VFP_ABI_POP
+# define VFP_ABI_FRAME 0
+# define BSAES_ASM_EXTENDED_KEY
+# define XTS_CHAIN_TWEAK
+# define __ARM_ARCH__ __LINUX_ARM_ARCH__
+# define __ARM_MAX_ARCH__ 7
+#endif
+
+#ifdef __thumb__
+# define adrl adr
+#endif
+
+#if __ARM_MAX_ARCH__>=7
+.arch armv7-a
+.fpu neon
+
+.text
+.syntax unified @ ARMv7-capable assembler is expected to handle this
+#ifdef __thumb2__
+.thumb
+#else
+.code 32
+#endif
+
+.type _bsaes_decrypt8,%function
+.align 4
+_bsaes_decrypt8:
+ adr $const,_bsaes_decrypt8
+ vldmia $key!, {@XMM[9]} @ round 0 key
+ add $const,$const,#.LM0ISR-_bsaes_decrypt8
+
+ vldmia $const!, {@XMM[8]} @ .LM0ISR
+ veor @XMM[10], @XMM[0], @XMM[9] @ xor with round0 key
+ veor @XMM[11], @XMM[1], @XMM[9]
+ vtbl.8 `&Dlo(@XMM[0])`, {@XMM[10]}, `&Dlo(@XMM[8])`
+ vtbl.8 `&Dhi(@XMM[0])`, {@XMM[10]}, `&Dhi(@XMM[8])`
+ veor @XMM[12], @XMM[2], @XMM[9]
+ vtbl.8 `&Dlo(@XMM[1])`, {@XMM[11]}, `&Dlo(@XMM[8])`
+ vtbl.8 `&Dhi(@XMM[1])`, {@XMM[11]}, `&Dhi(@XMM[8])`
+ veor @XMM[13], @XMM[3], @XMM[9]
+ vtbl.8 `&Dlo(@XMM[2])`, {@XMM[12]}, `&Dlo(@XMM[8])`
+ vtbl.8 `&Dhi(@XMM[2])`, {@XMM[12]}, `&Dhi(@XMM[8])`
+ veor @XMM[14], @XMM[4], @XMM[9]
+ vtbl.8 `&Dlo(@XMM[3])`, {@XMM[13]}, `&Dlo(@XMM[8])`
+ vtbl.8 `&Dhi(@XMM[3])`, {@XMM[13]}, `&Dhi(@XMM[8])`
+ veor @XMM[15], @XMM[5], @XMM[9]
+ vtbl.8 `&Dlo(@XMM[4])`, {@XMM[14]}, `&Dlo(@XMM[8])`
+ vtbl.8 `&Dhi(@XMM[4])`, {@XMM[14]}, `&Dhi(@XMM[8])`
+ veor @XMM[10], @XMM[6], @XMM[9]
+ vtbl.8 `&Dlo(@XMM[5])`, {@XMM[15]}, `&Dlo(@XMM[8])`
+ vtbl.8 `&Dhi(@XMM[5])`, {@XMM[15]}, `&Dhi(@XMM[8])`
+ veor @XMM[11], @XMM[7], @XMM[9]
+ vtbl.8 `&Dlo(@XMM[6])`, {@XMM[10]}, `&Dlo(@XMM[8])`
+ vtbl.8 `&Dhi(@XMM[6])`, {@XMM[10]}, `&Dhi(@XMM[8])`
+ vtbl.8 `&Dlo(@XMM[7])`, {@XMM[11]}, `&Dlo(@XMM[8])`
+ vtbl.8 `&Dhi(@XMM[7])`, {@XMM[11]}, `&Dhi(@XMM[8])`
+___
+ &bitslice (@XMM[0..7, 8..11]);
+$code.=<<___;
+ sub $rounds,$rounds,#1
+ b .Ldec_sbox
+.align 4
+.Ldec_loop:
+___
+ &ShiftRows (@XMM[0..7, 8..12]);
+$code.=".Ldec_sbox:\n";
+ &InvSbox (@XMM[0..7, 8..15]);
+$code.=<<___;
+ subs $rounds,$rounds,#1
+ bcc .Ldec_done
+___
+ &InvMixColumns (@XMM[0,1,6,4,2,7,3,5, 8..15]);
+$code.=<<___;
+ vldmia $const, {@XMM[12]} @ .LISR
+ ite eq @ Thumb2 thing, sanity check in ARM
+ addeq $const,$const,#0x10
+ bne .Ldec_loop
+ vldmia $const, {@XMM[12]} @ .LISRM0
+ b .Ldec_loop
+.align 4
+.Ldec_done:
+___
+ &bitslice (@XMM[0,1,6,4,2,7,3,5, 8..11]);
+$code.=<<___;
+ vldmia $key, {@XMM[8]} @ last round key
+ veor @XMM[6], @XMM[6], @XMM[8]
+ veor @XMM[4], @XMM[4], @XMM[8]
+ veor @XMM[2], @XMM[2], @XMM[8]
+ veor @XMM[7], @XMM[7], @XMM[8]
+ veor @XMM[3], @XMM[3], @XMM[8]
+ veor @XMM[5], @XMM[5], @XMM[8]
+ veor @XMM[0], @XMM[0], @XMM[8]
+ veor @XMM[1], @XMM[1], @XMM[8]
+ bx lr
+.size _bsaes_decrypt8,.-_bsaes_decrypt8
+
+.type _bsaes_const,%object
+.align 6
+_bsaes_const:
+.LM0ISR: @ InvShiftRows constants
+ .quad 0x0a0e0206070b0f03, 0x0004080c0d010509
+.LISR:
+ .quad 0x0504070602010003, 0x0f0e0d0c080b0a09
+.LISRM0:
+ .quad 0x01040b0e0205080f, 0x0306090c00070a0d
+.LM0SR: @ ShiftRows constants
+ .quad 0x0a0e02060f03070b, 0x0004080c05090d01
+.LSR:
+ .quad 0x0504070600030201, 0x0f0e0d0c0a09080b
+.LSRM0:
+ .quad 0x0304090e00050a0f, 0x01060b0c0207080d
+.LM0:
+ .quad 0x02060a0e03070b0f, 0x0004080c0105090d
+.LREVM0SR:
+ .quad 0x090d01050c000408, 0x03070b0f060a0e02
+.asciz "Bit-sliced AES for NEON, CRYPTOGAMS by <appro\@openssl.org>"
+.align 6
+.size _bsaes_const,.-_bsaes_const
+
+.type _bsaes_encrypt8,%function
+.align 4
+_bsaes_encrypt8:
+ adr $const,_bsaes_encrypt8
+ vldmia $key!, {@XMM[9]} @ round 0 key
+ sub $const,$const,#_bsaes_encrypt8-.LM0SR
+
+ vldmia $const!, {@XMM[8]} @ .LM0SR
+_bsaes_encrypt8_alt:
+ veor @XMM[10], @XMM[0], @XMM[9] @ xor with round0 key
+ veor @XMM[11], @XMM[1], @XMM[9]
+ vtbl.8 `&Dlo(@XMM[0])`, {@XMM[10]}, `&Dlo(@XMM[8])`
+ vtbl.8 `&Dhi(@XMM[0])`, {@XMM[10]}, `&Dhi(@XMM[8])`
+ veor @XMM[12], @XMM[2], @XMM[9]
+ vtbl.8 `&Dlo(@XMM[1])`, {@XMM[11]}, `&Dlo(@XMM[8])`
+ vtbl.8 `&Dhi(@XMM[1])`, {@XMM[11]}, `&Dhi(@XMM[8])`
+ veor @XMM[13], @XMM[3], @XMM[9]
+ vtbl.8 `&Dlo(@XMM[2])`, {@XMM[12]}, `&Dlo(@XMM[8])`
+ vtbl.8 `&Dhi(@XMM[2])`, {@XMM[12]}, `&Dhi(@XMM[8])`
+ veor @XMM[14], @XMM[4], @XMM[9]
+ vtbl.8 `&Dlo(@XMM[3])`, {@XMM[13]}, `&Dlo(@XMM[8])`
+ vtbl.8 `&Dhi(@XMM[3])`, {@XMM[13]}, `&Dhi(@XMM[8])`
+ veor @XMM[15], @XMM[5], @XMM[9]
+ vtbl.8 `&Dlo(@XMM[4])`, {@XMM[14]}, `&Dlo(@XMM[8])`
+ vtbl.8 `&Dhi(@XMM[4])`, {@XMM[14]}, `&Dhi(@XMM[8])`
+ veor @XMM[10], @XMM[6], @XMM[9]
+ vtbl.8 `&Dlo(@XMM[5])`, {@XMM[15]}, `&Dlo(@XMM[8])`
+ vtbl.8 `&Dhi(@XMM[5])`, {@XMM[15]}, `&Dhi(@XMM[8])`
+ veor @XMM[11], @XMM[7], @XMM[9]
+ vtbl.8 `&Dlo(@XMM[6])`, {@XMM[10]}, `&Dlo(@XMM[8])`
+ vtbl.8 `&Dhi(@XMM[6])`, {@XMM[10]}, `&Dhi(@XMM[8])`
+ vtbl.8 `&Dlo(@XMM[7])`, {@XMM[11]}, `&Dlo(@XMM[8])`
+ vtbl.8 `&Dhi(@XMM[7])`, {@XMM[11]}, `&Dhi(@XMM[8])`
+_bsaes_encrypt8_bitslice:
+___
+ &bitslice (@XMM[0..7, 8..11]);
+$code.=<<___;
+ sub $rounds,$rounds,#1
+ b .Lenc_sbox
+.align 4
+.Lenc_loop:
+___
+ &ShiftRows (@XMM[0..7, 8..12]);
+$code.=".Lenc_sbox:\n";
+ &Sbox (@XMM[0..7, 8..15]);
+$code.=<<___;
+ subs $rounds,$rounds,#1
+ bcc .Lenc_done
+___
+ &MixColumns (@XMM[0,1,4,6,3,7,2,5, 8..15]);
+$code.=<<___;
+ vldmia $const, {@XMM[12]} @ .LSR
+ ite eq @ Thumb2 thing, samity check in ARM
+ addeq $const,$const,#0x10
+ bne .Lenc_loop
+ vldmia $const, {@XMM[12]} @ .LSRM0
+ b .Lenc_loop
+.align 4
+.Lenc_done:
+___
+ # output in lsb > [t0, t1, t4, t6, t3, t7, t2, t5] < msb
+ &bitslice (@XMM[0,1,4,6,3,7,2,5, 8..11]);
+$code.=<<___;
+ vldmia $key, {@XMM[8]} @ last round key
+ veor @XMM[4], @XMM[4], @XMM[8]
+ veor @XMM[6], @XMM[6], @XMM[8]
+ veor @XMM[3], @XMM[3], @XMM[8]
+ veor @XMM[7], @XMM[7], @XMM[8]
+ veor @XMM[2], @XMM[2], @XMM[8]
+ veor @XMM[5], @XMM[5], @XMM[8]
+ veor @XMM[0], @XMM[0], @XMM[8]
+ veor @XMM[1], @XMM[1], @XMM[8]
+ bx lr
+.size _bsaes_encrypt8,.-_bsaes_encrypt8
+___
+}
+{
+my ($out,$inp,$rounds,$const)=("r12","r4","r5","r6");
+
+sub bitslice_key {
+my @x=reverse(@_[0..7]);
+my ($bs0,$bs1,$bs2,$t2,$t3)=@_[8..12];
+
+ &swapmove (@x[0,1],1,$bs0,$t2,$t3);
+$code.=<<___;
+ @ &swapmove(@x[2,3],1,$t0,$t2,$t3);
+ vmov @x[2], @x[0]
+ vmov @x[3], @x[1]
+___
+ #&swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
+
+ &swapmove2x (@x[0,2,1,3],2,$bs1,$t2,$t3);
+$code.=<<___;
+ @ &swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
+ vmov @x[4], @x[0]
+ vmov @x[6], @x[2]
+ vmov @x[5], @x[1]
+ vmov @x[7], @x[3]
+___
+ &swapmove2x (@x[0,4,1,5],4,$bs2,$t2,$t3);
+ &swapmove2x (@x[2,6,3,7],4,$bs2,$t2,$t3);
+}
+
+$code.=<<___;
+.type _bsaes_key_convert,%function
+.align 4
+_bsaes_key_convert:
+ adr $const,_bsaes_key_convert
+ vld1.8 {@XMM[7]}, [$inp]! @ load round 0 key
+ sub $const,$const,#_bsaes_key_convert-.LM0
+ vld1.8 {@XMM[15]}, [$inp]! @ load round 1 key
+
+ vmov.i8 @XMM[8], #0x01 @ bit masks
+ vmov.i8 @XMM[9], #0x02
+ vmov.i8 @XMM[10], #0x04
+ vmov.i8 @XMM[11], #0x08
+ vmov.i8 @XMM[12], #0x10
+ vmov.i8 @XMM[13], #0x20
+ vldmia $const, {@XMM[14]} @ .LM0
+
+#ifdef __ARMEL__
+ vrev32.8 @XMM[7], @XMM[7]
+ vrev32.8 @XMM[15], @XMM[15]
+#endif
+ sub $rounds,$rounds,#1
+ vstmia $out!, {@XMM[7]} @ save round 0 key
+ b .Lkey_loop
+
+.align 4
+.Lkey_loop:
+ vtbl.8 `&Dlo(@XMM[7])`,{@XMM[15]},`&Dlo(@XMM[14])`
+ vtbl.8 `&Dhi(@XMM[7])`,{@XMM[15]},`&Dhi(@XMM[14])`
+ vmov.i8 @XMM[6], #0x40
+ vmov.i8 @XMM[15], #0x80
+
+ vtst.8 @XMM[0], @XMM[7], @XMM[8]
+ vtst.8 @XMM[1], @XMM[7], @XMM[9]
+ vtst.8 @XMM[2], @XMM[7], @XMM[10]
+ vtst.8 @XMM[3], @XMM[7], @XMM[11]
+ vtst.8 @XMM[4], @XMM[7], @XMM[12]
+ vtst.8 @XMM[5], @XMM[7], @XMM[13]
+ vtst.8 @XMM[6], @XMM[7], @XMM[6]
+ vtst.8 @XMM[7], @XMM[7], @XMM[15]
+ vld1.8 {@XMM[15]}, [$inp]! @ load next round key
+ vmvn @XMM[0], @XMM[0] @ "pnot"
+ vmvn @XMM[1], @XMM[1]
+ vmvn @XMM[5], @XMM[5]
+ vmvn @XMM[6], @XMM[6]
+#ifdef __ARMEL__
+ vrev32.8 @XMM[15], @XMM[15]
+#endif
+ subs $rounds,$rounds,#1
+ vstmia $out!,{@XMM[0]-@XMM[7]} @ write bit-sliced round key
+ bne .Lkey_loop
+
+ vmov.i8 @XMM[7],#0x63 @ compose .L63
+ @ don't save last round key
+ bx lr
+.size _bsaes_key_convert,.-_bsaes_key_convert
+___
+}
+
+if (0) { # following four functions are unsupported interface
+ # used for benchmarking...
+$code.=<<___;
+.globl bsaes_enc_key_convert
+.type bsaes_enc_key_convert,%function
+.align 4
+bsaes_enc_key_convert:
+ stmdb sp!,{r4-r6,lr}
+ vstmdb sp!,{d8-d15} @ ABI specification says so
+
+ ldr r5,[$inp,#240] @ pass rounds
+ mov r4,$inp @ pass key
+ mov r12,$out @ pass key schedule
+ bl _bsaes_key_convert
+ veor @XMM[7],@XMM[7],@XMM[15] @ fix up last round key
+ vstmia r12, {@XMM[7]} @ save last round key
+
+ vldmia sp!,{d8-d15}
+ ldmia sp!,{r4-r6,pc}
+.size bsaes_enc_key_convert,.-bsaes_enc_key_convert
+
+.globl bsaes_encrypt_128
+.type bsaes_encrypt_128,%function
+.align 4
+bsaes_encrypt_128:
+ stmdb sp!,{r4-r6,lr}
+ vstmdb sp!,{d8-d15} @ ABI specification says so
+.Lenc128_loop:
+ vld1.8 {@XMM[0]-@XMM[1]}, [$inp]! @ load input
+ vld1.8 {@XMM[2]-@XMM[3]}, [$inp]!
+ mov r4,$key @ pass the key
+ vld1.8 {@XMM[4]-@XMM[5]}, [$inp]!
+ mov r5,#10 @ pass rounds
+ vld1.8 {@XMM[6]-@XMM[7]}, [$inp]!
+
+ bl _bsaes_encrypt8
+
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
+ vst1.8 {@XMM[4]}, [$out]!
+ vst1.8 {@XMM[6]}, [$out]!
+ vst1.8 {@XMM[3]}, [$out]!
+ vst1.8 {@XMM[7]}, [$out]!
+ vst1.8 {@XMM[2]}, [$out]!
+ subs $len,$len,#0x80
+ vst1.8 {@XMM[5]}, [$out]!
+ bhi .Lenc128_loop
+
+ vldmia sp!,{d8-d15}
+ ldmia sp!,{r4-r6,pc}
+.size bsaes_encrypt_128,.-bsaes_encrypt_128
+
+.globl bsaes_dec_key_convert
+.type bsaes_dec_key_convert,%function
+.align 4
+bsaes_dec_key_convert:
+ stmdb sp!,{r4-r6,lr}
+ vstmdb sp!,{d8-d15} @ ABI specification says so
+
+ ldr r5,[$inp,#240] @ pass rounds
+ mov r4,$inp @ pass key
+ mov r12,$out @ pass key schedule
+ bl _bsaes_key_convert
+ vldmia $out, {@XMM[6]}
+ vstmia r12, {@XMM[15]} @ save last round key
+ veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key
+ vstmia $out, {@XMM[7]}
+
+ vldmia sp!,{d8-d15}
+ ldmia sp!,{r4-r6,pc}
+.size bsaes_dec_key_convert,.-bsaes_dec_key_convert
+
+.globl bsaes_decrypt_128
+.type bsaes_decrypt_128,%function
+.align 4
+bsaes_decrypt_128:
+ stmdb sp!,{r4-r6,lr}
+ vstmdb sp!,{d8-d15} @ ABI specification says so
+.Ldec128_loop:
+ vld1.8 {@XMM[0]-@XMM[1]}, [$inp]! @ load input
+ vld1.8 {@XMM[2]-@XMM[3]}, [$inp]!
+ mov r4,$key @ pass the key
+ vld1.8 {@XMM[4]-@XMM[5]}, [$inp]!
+ mov r5,#10 @ pass rounds
+ vld1.8 {@XMM[6]-@XMM[7]}, [$inp]!
+
+ bl _bsaes_decrypt8
+
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
+ vst1.8 {@XMM[6]}, [$out]!
+ vst1.8 {@XMM[4]}, [$out]!
+ vst1.8 {@XMM[2]}, [$out]!
+ vst1.8 {@XMM[7]}, [$out]!
+ vst1.8 {@XMM[3]}, [$out]!
+ subs $len,$len,#0x80
+ vst1.8 {@XMM[5]}, [$out]!
+ bhi .Ldec128_loop
+
+ vldmia sp!,{d8-d15}
+ ldmia sp!,{r4-r6,pc}
+.size bsaes_decrypt_128,.-bsaes_decrypt_128
+___
+}
+{
+my ($inp,$out,$len,$key, $ivp,$fp,$rounds)=map("r$_",(0..3,8..10));
+my ($keysched)=("sp");
+
+$code.=<<___;
+.extern AES_cbc_encrypt
+.extern AES_decrypt
+
+.global bsaes_cbc_encrypt
+.type bsaes_cbc_encrypt,%function
+.align 5
+bsaes_cbc_encrypt:
+#ifndef __KERNEL__
+ cmp $len, #128
+#ifndef __thumb__
+ blo AES_cbc_encrypt
+#else
+ bhs 1f
+ b AES_cbc_encrypt
+1:
+#endif
+#endif
+
+ @ it is up to the caller to make sure we are called with enc == 0
+
+ mov ip, sp
+ stmdb sp!, {r4-r10, lr}
+ VFP_ABI_PUSH
+ ldr $ivp, [ip] @ IV is 1st arg on the stack
+ mov $len, $len, lsr#4 @ len in 16 byte blocks
+ sub sp, #0x10 @ scratch space to carry over the IV
+ mov $fp, sp @ save sp
+
+ ldr $rounds, [$key, #240] @ get # of rounds
+#ifndef BSAES_ASM_EXTENDED_KEY
+ @ allocate the key schedule on the stack
+ sub r12, sp, $rounds, lsl#7 @ 128 bytes per inner round key
+ add r12, #`128-32` @ sifze of bit-slices key schedule
+
+ @ populate the key schedule
+ mov r4, $key @ pass key
+ mov r5, $rounds @ pass # of rounds
+ mov sp, r12 @ sp is $keysched
+ bl _bsaes_key_convert
+ vldmia $keysched, {@XMM[6]}
+ vstmia r12, {@XMM[15]} @ save last round key
+ veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key
+ vstmia $keysched, {@XMM[7]}
+#else
+ ldr r12, [$key, #244]
+ eors r12, #1
+ beq 0f
+
+ @ populate the key schedule
+ str r12, [$key, #244]
+ mov r4, $key @ pass key
+ mov r5, $rounds @ pass # of rounds
+ add r12, $key, #248 @ pass key schedule
+ bl _bsaes_key_convert
+ add r4, $key, #248
+ vldmia r4, {@XMM[6]}
+ vstmia r12, {@XMM[15]} @ save last round key
+ veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key
+ vstmia r4, {@XMM[7]}
+
+.align 2
+0:
+#endif
+
+ vld1.8 {@XMM[15]}, [$ivp] @ load IV
+ b .Lcbc_dec_loop
+
+.align 4
+.Lcbc_dec_loop:
+ subs $len, $len, #0x8
+ bmi .Lcbc_dec_loop_finish
+
+ vld1.8 {@XMM[0]-@XMM[1]}, [$inp]! @ load input
+ vld1.8 {@XMM[2]-@XMM[3]}, [$inp]!
+#ifndef BSAES_ASM_EXTENDED_KEY
+ mov r4, $keysched @ pass the key
+#else
+ add r4, $key, #248
+#endif
+ vld1.8 {@XMM[4]-@XMM[5]}, [$inp]!
+ mov r5, $rounds
+ vld1.8 {@XMM[6]-@XMM[7]}, [$inp]
+ sub $inp, $inp, #0x60
+ vstmia $fp, {@XMM[15]} @ put aside IV
+
+ bl _bsaes_decrypt8
+
+ vldmia $fp, {@XMM[14]} @ reload IV
+ vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input
+ veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV
+ vld1.8 {@XMM[10]-@XMM[11]}, [$inp]!
+ veor @XMM[1], @XMM[1], @XMM[8]
+ veor @XMM[6], @XMM[6], @XMM[9]
+ vld1.8 {@XMM[12]-@XMM[13]}, [$inp]!
+ veor @XMM[4], @XMM[4], @XMM[10]
+ veor @XMM[2], @XMM[2], @XMM[11]
+ vld1.8 {@XMM[14]-@XMM[15]}, [$inp]!
+ veor @XMM[7], @XMM[7], @XMM[12]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
+ veor @XMM[3], @XMM[3], @XMM[13]
+ vst1.8 {@XMM[6]}, [$out]!
+ veor @XMM[5], @XMM[5], @XMM[14]
+ vst1.8 {@XMM[4]}, [$out]!
+ vst1.8 {@XMM[2]}, [$out]!
+ vst1.8 {@XMM[7]}, [$out]!
+ vst1.8 {@XMM[3]}, [$out]!
+ vst1.8 {@XMM[5]}, [$out]!
+
+ b .Lcbc_dec_loop
+
+.Lcbc_dec_loop_finish:
+ adds $len, $len, #8
+ beq .Lcbc_dec_done
+
+ vld1.8 {@XMM[0]}, [$inp]! @ load input
+ cmp $len, #2
+ blo .Lcbc_dec_one
+ vld1.8 {@XMM[1]}, [$inp]!
+#ifndef BSAES_ASM_EXTENDED_KEY
+ mov r4, $keysched @ pass the key
+#else
+ add r4, $key, #248
+#endif
+ mov r5, $rounds
+ vstmia $fp, {@XMM[15]} @ put aside IV
+ beq .Lcbc_dec_two
+ vld1.8 {@XMM[2]}, [$inp]!
+ cmp $len, #4
+ blo .Lcbc_dec_three
+ vld1.8 {@XMM[3]}, [$inp]!
+ beq .Lcbc_dec_four
+ vld1.8 {@XMM[4]}, [$inp]!
+ cmp $len, #6
+ blo .Lcbc_dec_five
+ vld1.8 {@XMM[5]}, [$inp]!
+ beq .Lcbc_dec_six
+ vld1.8 {@XMM[6]}, [$inp]!
+ sub $inp, $inp, #0x70
+
+ bl _bsaes_decrypt8
+
+ vldmia $fp, {@XMM[14]} @ reload IV
+ vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input
+ veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV
+ vld1.8 {@XMM[10]-@XMM[11]}, [$inp]!
+ veor @XMM[1], @XMM[1], @XMM[8]
+ veor @XMM[6], @XMM[6], @XMM[9]
+ vld1.8 {@XMM[12]-@XMM[13]}, [$inp]!
+ veor @XMM[4], @XMM[4], @XMM[10]
+ veor @XMM[2], @XMM[2], @XMM[11]
+ vld1.8 {@XMM[15]}, [$inp]!
+ veor @XMM[7], @XMM[7], @XMM[12]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
+ veor @XMM[3], @XMM[3], @XMM[13]
+ vst1.8 {@XMM[6]}, [$out]!
+ vst1.8 {@XMM[4]}, [$out]!
+ vst1.8 {@XMM[2]}, [$out]!
+ vst1.8 {@XMM[7]}, [$out]!
+ vst1.8 {@XMM[3]}, [$out]!
+ b .Lcbc_dec_done
+.align 4
+.Lcbc_dec_six:
+ sub $inp, $inp, #0x60
+ bl _bsaes_decrypt8
+ vldmia $fp,{@XMM[14]} @ reload IV
+ vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input
+ veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV
+ vld1.8 {@XMM[10]-@XMM[11]}, [$inp]!
+ veor @XMM[1], @XMM[1], @XMM[8]
+ veor @XMM[6], @XMM[6], @XMM[9]
+ vld1.8 {@XMM[12]}, [$inp]!
+ veor @XMM[4], @XMM[4], @XMM[10]
+ veor @XMM[2], @XMM[2], @XMM[11]
+ vld1.8 {@XMM[15]}, [$inp]!
+ veor @XMM[7], @XMM[7], @XMM[12]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
+ vst1.8 {@XMM[6]}, [$out]!
+ vst1.8 {@XMM[4]}, [$out]!
+ vst1.8 {@XMM[2]}, [$out]!
+ vst1.8 {@XMM[7]}, [$out]!
+ b .Lcbc_dec_done
+.align 4
+.Lcbc_dec_five:
+ sub $inp, $inp, #0x50
+ bl _bsaes_decrypt8
+ vldmia $fp, {@XMM[14]} @ reload IV
+ vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input
+ veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV
+ vld1.8 {@XMM[10]-@XMM[11]}, [$inp]!
+ veor @XMM[1], @XMM[1], @XMM[8]
+ veor @XMM[6], @XMM[6], @XMM[9]
+ vld1.8 {@XMM[15]}, [$inp]!
+ veor @XMM[4], @XMM[4], @XMM[10]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
+ veor @XMM[2], @XMM[2], @XMM[11]
+ vst1.8 {@XMM[6]}, [$out]!
+ vst1.8 {@XMM[4]}, [$out]!
+ vst1.8 {@XMM[2]}, [$out]!
+ b .Lcbc_dec_done
+.align 4
+.Lcbc_dec_four:
+ sub $inp, $inp, #0x40
+ bl _bsaes_decrypt8
+ vldmia $fp, {@XMM[14]} @ reload IV
+ vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input
+ veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV
+ vld1.8 {@XMM[10]}, [$inp]!
+ veor @XMM[1], @XMM[1], @XMM[8]
+ veor @XMM[6], @XMM[6], @XMM[9]
+ vld1.8 {@XMM[15]}, [$inp]!
+ veor @XMM[4], @XMM[4], @XMM[10]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
+ vst1.8 {@XMM[6]}, [$out]!
+ vst1.8 {@XMM[4]}, [$out]!
+ b .Lcbc_dec_done
+.align 4
+.Lcbc_dec_three:
+ sub $inp, $inp, #0x30
+ bl _bsaes_decrypt8
+ vldmia $fp, {@XMM[14]} @ reload IV
+ vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input
+ veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV
+ vld1.8 {@XMM[15]}, [$inp]!
+ veor @XMM[1], @XMM[1], @XMM[8]
+ veor @XMM[6], @XMM[6], @XMM[9]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
+ vst1.8 {@XMM[6]}, [$out]!
+ b .Lcbc_dec_done
+.align 4
+.Lcbc_dec_two:
+ sub $inp, $inp, #0x20
+ bl _bsaes_decrypt8
+ vldmia $fp, {@XMM[14]} @ reload IV
+ vld1.8 {@XMM[8]}, [$inp]! @ reload input
+ veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV
+ vld1.8 {@XMM[15]}, [$inp]! @ reload input
+ veor @XMM[1], @XMM[1], @XMM[8]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
+ b .Lcbc_dec_done
+.align 4
+.Lcbc_dec_one:
+ sub $inp, $inp, #0x10
+ mov $rounds, $out @ save original out pointer
+ mov $out, $fp @ use the iv scratch space as out buffer
+ mov r2, $key
+ vmov @XMM[4],@XMM[15] @ just in case ensure that IV
+ vmov @XMM[5],@XMM[0] @ and input are preserved
+ bl AES_decrypt
+ vld1.8 {@XMM[0]}, [$fp,:64] @ load result
+ veor @XMM[0], @XMM[0], @XMM[4] @ ^= IV
+ vmov @XMM[15], @XMM[5] @ @XMM[5] holds input
+ vst1.8 {@XMM[0]}, [$rounds] @ write output
+
+.Lcbc_dec_done:
+#ifndef BSAES_ASM_EXTENDED_KEY
+ vmov.i32 q0, #0
+ vmov.i32 q1, #0
+.Lcbc_dec_bzero: @ wipe key schedule [if any]
+ vstmia $keysched!, {q0-q1}
+ cmp $keysched, $fp
+ bne .Lcbc_dec_bzero
+#endif
+
+ mov sp, $fp
+ add sp, #0x10 @ add sp,$fp,#0x10 is no good for thumb
+ vst1.8 {@XMM[15]}, [$ivp] @ return IV
+ VFP_ABI_POP
+ ldmia sp!, {r4-r10, pc}
+.size bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
+___
+}
+{
+my ($inp,$out,$len,$key, $ctr,$fp,$rounds)=(map("r$_",(0..3,8..10)));
+my $const = "r6"; # shared with _bsaes_encrypt8_alt
+my $keysched = "sp";
+
+$code.=<<___;
+.extern AES_encrypt
+.global bsaes_ctr32_encrypt_blocks
+.type bsaes_ctr32_encrypt_blocks,%function
+.align 5
+bsaes_ctr32_encrypt_blocks:
+ cmp $len, #8 @ use plain AES for
+ blo .Lctr_enc_short @ small sizes
+
+ mov ip, sp
+ stmdb sp!, {r4-r10, lr}
+ VFP_ABI_PUSH
+ ldr $ctr, [ip] @ ctr is 1st arg on the stack
+ sub sp, sp, #0x10 @ scratch space to carry over the ctr
+ mov $fp, sp @ save sp
+
+ ldr $rounds, [$key, #240] @ get # of rounds
+#ifndef BSAES_ASM_EXTENDED_KEY
+ @ allocate the key schedule on the stack
+ sub r12, sp, $rounds, lsl#7 @ 128 bytes per inner round key
+ add r12, #`128-32` @ size of bit-sliced key schedule
+
+ @ populate the key schedule
+ mov r4, $key @ pass key
+ mov r5, $rounds @ pass # of rounds
+ mov sp, r12 @ sp is $keysched
+ bl _bsaes_key_convert
+ veor @XMM[7],@XMM[7],@XMM[15] @ fix up last round key
+ vstmia r12, {@XMM[7]} @ save last round key
+
+ vld1.8 {@XMM[0]}, [$ctr] @ load counter
+ add $ctr, $const, #.LREVM0SR-.LM0 @ borrow $ctr
+ vldmia $keysched, {@XMM[4]} @ load round0 key
+#else
+ ldr r12, [$key, #244]
+ eors r12, #1
+ beq 0f
+
+ @ populate the key schedule
+ str r12, [$key, #244]
+ mov r4, $key @ pass key
+ mov r5, $rounds @ pass # of rounds
+ add r12, $key, #248 @ pass key schedule
+ bl _bsaes_key_convert
+ veor @XMM[7],@XMM[7],@XMM[15] @ fix up last round key
+ vstmia r12, {@XMM[7]} @ save last round key
+
+.align 2
+0: add r12, $key, #248
+ vld1.8 {@XMM[0]}, [$ctr] @ load counter
+ adrl $ctr, .LREVM0SR @ borrow $ctr
+ vldmia r12, {@XMM[4]} @ load round0 key
+ sub sp, #0x10 @ place for adjusted round0 key
+#endif
+
+ vmov.i32 @XMM[8],#1 @ compose 1<<96
+ veor @XMM[9],@XMM[9],@XMM[9]
+ vrev32.8 @XMM[0],@XMM[0]
+ vext.8 @XMM[8],@XMM[9],@XMM[8],#4
+ vrev32.8 @XMM[4],@XMM[4]
+ vadd.u32 @XMM[9],@XMM[8],@XMM[8] @ compose 2<<96
+ vstmia $keysched, {@XMM[4]} @ save adjusted round0 key
+ b .Lctr_enc_loop
+
+.align 4
+.Lctr_enc_loop:
+ vadd.u32 @XMM[10], @XMM[8], @XMM[9] @ compose 3<<96
+ vadd.u32 @XMM[1], @XMM[0], @XMM[8] @ +1
+ vadd.u32 @XMM[2], @XMM[0], @XMM[9] @ +2
+ vadd.u32 @XMM[3], @XMM[0], @XMM[10] @ +3
+ vadd.u32 @XMM[4], @XMM[1], @XMM[10]
+ vadd.u32 @XMM[5], @XMM[2], @XMM[10]
+ vadd.u32 @XMM[6], @XMM[3], @XMM[10]
+ vadd.u32 @XMM[7], @XMM[4], @XMM[10]
+ vadd.u32 @XMM[10], @XMM[5], @XMM[10] @ next counter
+
+ @ Borrow prologue from _bsaes_encrypt8 to use the opportunity
+ @ to flip byte order in 32-bit counter
+
+ vldmia $keysched, {@XMM[9]} @ load round0 key
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, $keysched, #0x10 @ pass next round key
+#else
+ add r4, $key, #`248+16`
+#endif
+ vldmia $ctr, {@XMM[8]} @ .LREVM0SR
+ mov r5, $rounds @ pass rounds
+ vstmia $fp, {@XMM[10]} @ save next counter
+ sub $const, $ctr, #.LREVM0SR-.LSR @ pass constants
+
+ bl _bsaes_encrypt8_alt
+
+ subs $len, $len, #8
+ blo .Lctr_enc_loop_done
+
+ vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ load input
+ vld1.8 {@XMM[10]-@XMM[11]}, [$inp]!
+ veor @XMM[0], @XMM[8]
+ veor @XMM[1], @XMM[9]
+ vld1.8 {@XMM[12]-@XMM[13]}, [$inp]!
+ veor @XMM[4], @XMM[10]
+ veor @XMM[6], @XMM[11]
+ vld1.8 {@XMM[14]-@XMM[15]}, [$inp]!
+ veor @XMM[3], @XMM[12]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
+ veor @XMM[7], @XMM[13]
+ veor @XMM[2], @XMM[14]
+ vst1.8 {@XMM[4]}, [$out]!
+ veor @XMM[5], @XMM[15]
+ vst1.8 {@XMM[6]}, [$out]!
+ vmov.i32 @XMM[8], #1 @ compose 1<<96
+ vst1.8 {@XMM[3]}, [$out]!
+ veor @XMM[9], @XMM[9], @XMM[9]
+ vst1.8 {@XMM[7]}, [$out]!
+ vext.8 @XMM[8], @XMM[9], @XMM[8], #4
+ vst1.8 {@XMM[2]}, [$out]!
+ vadd.u32 @XMM[9],@XMM[8],@XMM[8] @ compose 2<<96
+ vst1.8 {@XMM[5]}, [$out]!
+ vldmia $fp, {@XMM[0]} @ load counter
+
+ bne .Lctr_enc_loop
+ b .Lctr_enc_done
+
+.align 4
+.Lctr_enc_loop_done:
+ add $len, $len, #8
+ vld1.8 {@XMM[8]}, [$inp]! @ load input
+ veor @XMM[0], @XMM[8]
+ vst1.8 {@XMM[0]}, [$out]! @ write output
+ cmp $len, #2
+ blo .Lctr_enc_done
+ vld1.8 {@XMM[9]}, [$inp]!
+ veor @XMM[1], @XMM[9]
+ vst1.8 {@XMM[1]}, [$out]!
+ beq .Lctr_enc_done
+ vld1.8 {@XMM[10]}, [$inp]!
+ veor @XMM[4], @XMM[10]
+ vst1.8 {@XMM[4]}, [$out]!
+ cmp $len, #4
+ blo .Lctr_enc_done
+ vld1.8 {@XMM[11]}, [$inp]!
+ veor @XMM[6], @XMM[11]
+ vst1.8 {@XMM[6]}, [$out]!
+ beq .Lctr_enc_done
+ vld1.8 {@XMM[12]}, [$inp]!
+ veor @XMM[3], @XMM[12]
+ vst1.8 {@XMM[3]}, [$out]!
+ cmp $len, #6
+ blo .Lctr_enc_done
+ vld1.8 {@XMM[13]}, [$inp]!
+ veor @XMM[7], @XMM[13]
+ vst1.8 {@XMM[7]}, [$out]!
+ beq .Lctr_enc_done
+ vld1.8 {@XMM[14]}, [$inp]
+ veor @XMM[2], @XMM[14]
+ vst1.8 {@XMM[2]}, [$out]!
+
+.Lctr_enc_done:
+ vmov.i32 q0, #0
+ vmov.i32 q1, #0
+#ifndef BSAES_ASM_EXTENDED_KEY
+.Lctr_enc_bzero: @ wipe key schedule [if any]
+ vstmia $keysched!, {q0-q1}
+ cmp $keysched, $fp
+ bne .Lctr_enc_bzero
+#else
+ vstmia $keysched, {q0-q1}
+#endif
+
+ mov sp, $fp
+ add sp, #0x10 @ add sp,$fp,#0x10 is no good for thumb
+ VFP_ABI_POP
+ ldmia sp!, {r4-r10, pc} @ return
+
+.align 4
+.Lctr_enc_short:
+ ldr ip, [sp] @ ctr pointer is passed on stack
+ stmdb sp!, {r4-r8, lr}
+
+ mov r4, $inp @ copy arguments
+ mov r5, $out
+ mov r6, $len
+ mov r7, $key
+ ldr r8, [ip, #12] @ load counter LSW
+ vld1.8 {@XMM[1]}, [ip] @ load whole counter value
+#ifdef __ARMEL__
+ rev r8, r8
+#endif
+ sub sp, sp, #0x10
+ vst1.8 {@XMM[1]}, [sp,:64] @ copy counter value
+ sub sp, sp, #0x10
+
+.Lctr_enc_short_loop:
+ add r0, sp, #0x10 @ input counter value
+ mov r1, sp @ output on the stack
+ mov r2, r7 @ key
+
+ bl AES_encrypt
+
+ vld1.8 {@XMM[0]}, [r4]! @ load input
+ vld1.8 {@XMM[1]}, [sp,:64] @ load encrypted counter
+ add r8, r8, #1
+#ifdef __ARMEL__
+ rev r0, r8
+ str r0, [sp, #0x1c] @ next counter value
+#else
+ str r8, [sp, #0x1c] @ next counter value
+#endif
+ veor @XMM[0],@XMM[0],@XMM[1]
+ vst1.8 {@XMM[0]}, [r5]! @ store output
+ subs r6, r6, #1
+ bne .Lctr_enc_short_loop
+
+ vmov.i32 q0, #0
+ vmov.i32 q1, #0
+ vstmia sp!, {q0-q1}
+
+ ldmia sp!, {r4-r8, pc}
+.size bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
+___
+}
+{
+######################################################################
+# void bsaes_xts_[en|de]crypt(const char *inp,char *out,size_t len,
+# const AES_KEY *key1, const AES_KEY *key2,
+# const unsigned char iv[16]);
+#
+my ($inp,$out,$len,$key,$rounds,$magic,$fp)=(map("r$_",(7..10,1..3)));
+my $const="r6"; # returned by _bsaes_key_convert
+my $twmask=@XMM[5];
+my @T=@XMM[6..7];
+
+$code.=<<___;
+.globl bsaes_xts_encrypt
+.type bsaes_xts_encrypt,%function
+.align 4
+bsaes_xts_encrypt:
+ mov ip, sp
+ stmdb sp!, {r4-r10, lr} @ 0x20
+ VFP_ABI_PUSH
+ mov r6, sp @ future $fp
+
+ mov $inp, r0
+ mov $out, r1
+ mov $len, r2
+ mov $key, r3
+
+ sub r0, sp, #0x10 @ 0x10
+ bic r0, #0xf @ align at 16 bytes
+ mov sp, r0
+
+#ifdef XTS_CHAIN_TWEAK
+ ldr r0, [ip] @ pointer to input tweak
+#else
+ @ generate initial tweak
+ ldr r0, [ip, #4] @ iv[]
+ mov r1, sp
+ ldr r2, [ip, #0] @ key2
+ bl AES_encrypt
+ mov r0,sp @ pointer to initial tweak
+#endif
+
+ ldr $rounds, [$key, #240] @ get # of rounds
+ mov $fp, r6
+#ifndef BSAES_ASM_EXTENDED_KEY
+ @ allocate the key schedule on the stack
+ sub r12, sp, $rounds, lsl#7 @ 128 bytes per inner round key
+ @ add r12, #`128-32` @ size of bit-sliced key schedule
+ sub r12, #`32+16` @ place for tweak[9]
+
+ @ populate the key schedule
+ mov r4, $key @ pass key
+ mov r5, $rounds @ pass # of rounds
+ mov sp, r12
+ add r12, #0x90 @ pass key schedule
+ bl _bsaes_key_convert
+ veor @XMM[7], @XMM[7], @XMM[15] @ fix up last round key
+ vstmia r12, {@XMM[7]} @ save last round key
+#else
+ ldr r12, [$key, #244]
+ eors r12, #1
+ beq 0f
+
+ str r12, [$key, #244]
+ mov r4, $key @ pass key
+ mov r5, $rounds @ pass # of rounds
+ add r12, $key, #248 @ pass key schedule
+ bl _bsaes_key_convert
+ veor @XMM[7], @XMM[7], @XMM[15] @ fix up last round key
+ vstmia r12, {@XMM[7]}
+
+.align 2
+0: sub sp, #0x90 @ place for tweak[9]
+#endif
+
+ vld1.8 {@XMM[8]}, [r0] @ initial tweak
+ adr $magic, .Lxts_magic
+
+ subs $len, #0x80
+ blo .Lxts_enc_short
+ b .Lxts_enc_loop
+
+.align 4
+.Lxts_enc_loop:
+ vldmia $magic, {$twmask} @ load XTS magic
+ vshr.s64 @T[0], @XMM[8], #63
+ mov r0, sp
+ vand @T[0], @T[0], $twmask
+___
+for($i=9;$i<16;$i++) {
+$code.=<<___;
+ vadd.u64 @XMM[$i], @XMM[$i-1], @XMM[$i-1]
+ vst1.64 {@XMM[$i-1]}, [r0,:128]!
+ vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
+ vshr.s64 @T[1], @XMM[$i], #63
+ veor @XMM[$i], @XMM[$i], @T[0]
+ vand @T[1], @T[1], $twmask
+___
+ @T=reverse(@T);
+
+$code.=<<___ if ($i>=10);
+ vld1.8 {@XMM[$i-10]}, [$inp]!
+___
+$code.=<<___ if ($i>=11);
+ veor @XMM[$i-11], @XMM[$i-11], @XMM[$i-3]
+___
+}
+$code.=<<___;
+ vadd.u64 @XMM[8], @XMM[15], @XMM[15]
+ vst1.64 {@XMM[15]}, [r0,:128]!
+ vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
+ veor @XMM[8], @XMM[8], @T[0]
+ vst1.64 {@XMM[8]}, [r0,:128] @ next round tweak
+
+ vld1.8 {@XMM[6]-@XMM[7]}, [$inp]!
+ veor @XMM[5], @XMM[5], @XMM[13]
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, $key, #248 @ pass key schedule
+#endif
+ veor @XMM[6], @XMM[6], @XMM[14]
+ mov r5, $rounds @ pass rounds
+ veor @XMM[7], @XMM[7], @XMM[15]
+ mov r0, sp
+
+ bl _bsaes_encrypt8
+
+ vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
+ vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
+ veor @XMM[0], @XMM[0], @XMM[ 8]
+ vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]!
+ veor @XMM[1], @XMM[1], @XMM[ 9]
+ veor @XMM[8], @XMM[4], @XMM[10]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
+ veor @XMM[9], @XMM[6], @XMM[11]
+ vld1.64 {@XMM[14]-@XMM[15]}, [r0,:128]!
+ veor @XMM[10], @XMM[3], @XMM[12]
+ vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
+ veor @XMM[11], @XMM[7], @XMM[13]
+ veor @XMM[12], @XMM[2], @XMM[14]
+ vst1.8 {@XMM[10]-@XMM[11]}, [$out]!
+ veor @XMM[13], @XMM[5], @XMM[15]
+ vst1.8 {@XMM[12]-@XMM[13]}, [$out]!
+
+ vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
+
+ subs $len, #0x80
+ bpl .Lxts_enc_loop
+
+.Lxts_enc_short:
+ adds $len, #0x70
+ bmi .Lxts_enc_done
+
+ vldmia $magic, {$twmask} @ load XTS magic
+ vshr.s64 @T[0], @XMM[8], #63
+ mov r0, sp
+ vand @T[0], @T[0], $twmask
+___
+for($i=9;$i<16;$i++) {
+$code.=<<___;
+ vadd.u64 @XMM[$i], @XMM[$i-1], @XMM[$i-1]
+ vst1.64 {@XMM[$i-1]}, [r0,:128]!
+ vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
+ vshr.s64 @T[1], @XMM[$i], #63
+ veor @XMM[$i], @XMM[$i], @T[0]
+ vand @T[1], @T[1], $twmask
+___
+ @T=reverse(@T);
+
+$code.=<<___ if ($i>=10);
+ vld1.8 {@XMM[$i-10]}, [$inp]!
+ subs $len, #0x10
+ bmi .Lxts_enc_`$i-9`
+___
+$code.=<<___ if ($i>=11);
+ veor @XMM[$i-11], @XMM[$i-11], @XMM[$i-3]
+___
+}
+$code.=<<___;
+ sub $len, #0x10
+ vst1.64 {@XMM[15]}, [r0,:128] @ next round tweak
+
+ vld1.8 {@XMM[6]}, [$inp]!
+ veor @XMM[5], @XMM[5], @XMM[13]
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, $key, #248 @ pass key schedule
+#endif
+ veor @XMM[6], @XMM[6], @XMM[14]
+ mov r5, $rounds @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_encrypt8
+
+ vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
+ vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
+ veor @XMM[0], @XMM[0], @XMM[ 8]
+ vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]!
+ veor @XMM[1], @XMM[1], @XMM[ 9]
+ veor @XMM[8], @XMM[4], @XMM[10]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
+ veor @XMM[9], @XMM[6], @XMM[11]
+ vld1.64 {@XMM[14]}, [r0,:128]!
+ veor @XMM[10], @XMM[3], @XMM[12]
+ vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
+ veor @XMM[11], @XMM[7], @XMM[13]
+ veor @XMM[12], @XMM[2], @XMM[14]
+ vst1.8 {@XMM[10]-@XMM[11]}, [$out]!
+ vst1.8 {@XMM[12]}, [$out]!
+
+ vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
+ b .Lxts_enc_done
+.align 4
+.Lxts_enc_6:
+ vst1.64 {@XMM[14]}, [r0,:128] @ next round tweak
+
+ veor @XMM[4], @XMM[4], @XMM[12]
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, $key, #248 @ pass key schedule
+#endif
+ veor @XMM[5], @XMM[5], @XMM[13]
+ mov r5, $rounds @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_encrypt8
+
+ vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
+ vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
+ veor @XMM[0], @XMM[0], @XMM[ 8]
+ vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]!
+ veor @XMM[1], @XMM[1], @XMM[ 9]
+ veor @XMM[8], @XMM[4], @XMM[10]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
+ veor @XMM[9], @XMM[6], @XMM[11]
+ veor @XMM[10], @XMM[3], @XMM[12]
+ vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
+ veor @XMM[11], @XMM[7], @XMM[13]
+ vst1.8 {@XMM[10]-@XMM[11]}, [$out]!
+
+ vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
+ b .Lxts_enc_done
+
+@ put this in range for both ARM and Thumb mode adr instructions
+.align 5
+.Lxts_magic:
+ .quad 1, 0x87
+
+.align 5
+.Lxts_enc_5:
+ vst1.64 {@XMM[13]}, [r0,:128] @ next round tweak
+
+ veor @XMM[3], @XMM[3], @XMM[11]
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, $key, #248 @ pass key schedule
+#endif
+ veor @XMM[4], @XMM[4], @XMM[12]
+ mov r5, $rounds @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_encrypt8
+
+ vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
+ vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
+ veor @XMM[0], @XMM[0], @XMM[ 8]
+ vld1.64 {@XMM[12]}, [r0,:128]!
+ veor @XMM[1], @XMM[1], @XMM[ 9]
+ veor @XMM[8], @XMM[4], @XMM[10]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
+ veor @XMM[9], @XMM[6], @XMM[11]
+ veor @XMM[10], @XMM[3], @XMM[12]
+ vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
+ vst1.8 {@XMM[10]}, [$out]!
+
+ vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
+ b .Lxts_enc_done
+.align 4
+.Lxts_enc_4:
+ vst1.64 {@XMM[12]}, [r0,:128] @ next round tweak
+
+ veor @XMM[2], @XMM[2], @XMM[10]
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, $key, #248 @ pass key schedule
+#endif
+ veor @XMM[3], @XMM[3], @XMM[11]
+ mov r5, $rounds @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_encrypt8
+
+ vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
+ vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
+ veor @XMM[0], @XMM[0], @XMM[ 8]
+ veor @XMM[1], @XMM[1], @XMM[ 9]
+ veor @XMM[8], @XMM[4], @XMM[10]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
+ veor @XMM[9], @XMM[6], @XMM[11]
+ vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
+
+ vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
+ b .Lxts_enc_done
+.align 4
+.Lxts_enc_3:
+ vst1.64 {@XMM[11]}, [r0,:128] @ next round tweak
+
+ veor @XMM[1], @XMM[1], @XMM[9]
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, $key, #248 @ pass key schedule
+#endif
+ veor @XMM[2], @XMM[2], @XMM[10]
+ mov r5, $rounds @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_encrypt8
+
+ vld1.64 {@XMM[8]-@XMM[9]}, [r0,:128]!
+ vld1.64 {@XMM[10]}, [r0,:128]!
+ veor @XMM[0], @XMM[0], @XMM[ 8]
+ veor @XMM[1], @XMM[1], @XMM[ 9]
+ veor @XMM[8], @XMM[4], @XMM[10]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
+ vst1.8 {@XMM[8]}, [$out]!
+
+ vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
+ b .Lxts_enc_done
+.align 4
+.Lxts_enc_2:
+ vst1.64 {@XMM[10]}, [r0,:128] @ next round tweak
+
+ veor @XMM[0], @XMM[0], @XMM[8]
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, $key, #248 @ pass key schedule
+#endif
+ veor @XMM[1], @XMM[1], @XMM[9]
+ mov r5, $rounds @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_encrypt8
+
+ vld1.64 {@XMM[8]-@XMM[9]}, [r0,:128]!
+ veor @XMM[0], @XMM[0], @XMM[ 8]
+ veor @XMM[1], @XMM[1], @XMM[ 9]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
+
+ vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
+ b .Lxts_enc_done
+.align 4
+.Lxts_enc_1:
+ mov r0, sp
+ veor @XMM[0], @XMM[8]
+ mov r1, sp
+ vst1.8 {@XMM[0]}, [sp,:128]
+ mov r2, $key
+ mov r4, $fp @ preserve fp
+
+ bl AES_encrypt
+
+ vld1.8 {@XMM[0]}, [sp,:128]
+ veor @XMM[0], @XMM[0], @XMM[8]
+ vst1.8 {@XMM[0]}, [$out]!
+ mov $fp, r4
+
+ vmov @XMM[8], @XMM[9] @ next round tweak
+
+.Lxts_enc_done:
+#ifndef XTS_CHAIN_TWEAK
+ adds $len, #0x10
+ beq .Lxts_enc_ret
+ sub r6, $out, #0x10
+
+.Lxts_enc_steal:
+ ldrb r0, [$inp], #1
+ ldrb r1, [$out, #-0x10]
+ strb r0, [$out, #-0x10]
+ strb r1, [$out], #1
+
+ subs $len, #1
+ bhi .Lxts_enc_steal
+
+ vld1.8 {@XMM[0]}, [r6]
+ mov r0, sp
+ veor @XMM[0], @XMM[0], @XMM[8]
+ mov r1, sp
+ vst1.8 {@XMM[0]}, [sp,:128]
+ mov r2, $key
+ mov r4, $fp @ preserve fp
+
+ bl AES_encrypt
+
+ vld1.8 {@XMM[0]}, [sp,:128]
+ veor @XMM[0], @XMM[0], @XMM[8]
+ vst1.8 {@XMM[0]}, [r6]
+ mov $fp, r4
+#endif
+
+.Lxts_enc_ret:
+ bic r0, $fp, #0xf
+ vmov.i32 q0, #0
+ vmov.i32 q1, #0
+#ifdef XTS_CHAIN_TWEAK
+ ldr r1, [$fp, #0x20+VFP_ABI_FRAME] @ chain tweak
+#endif
+.Lxts_enc_bzero: @ wipe key schedule [if any]
+ vstmia sp!, {q0-q1}
+ cmp sp, r0
+ bne .Lxts_enc_bzero
+
+ mov sp, $fp
+#ifdef XTS_CHAIN_TWEAK
+ vst1.8 {@XMM[8]}, [r1]
+#endif
+ VFP_ABI_POP
+ ldmia sp!, {r4-r10, pc} @ return
+
+.size bsaes_xts_encrypt,.-bsaes_xts_encrypt
+
+.globl bsaes_xts_decrypt
+.type bsaes_xts_decrypt,%function
+.align 4
+bsaes_xts_decrypt:
+ mov ip, sp
+ stmdb sp!, {r4-r10, lr} @ 0x20
+ VFP_ABI_PUSH
+ mov r6, sp @ future $fp
+
+ mov $inp, r0
+ mov $out, r1
+ mov $len, r2
+ mov $key, r3
+
+ sub r0, sp, #0x10 @ 0x10
+ bic r0, #0xf @ align at 16 bytes
+ mov sp, r0
+
+#ifdef XTS_CHAIN_TWEAK
+ ldr r0, [ip] @ pointer to input tweak
+#else
+ @ generate initial tweak
+ ldr r0, [ip, #4] @ iv[]
+ mov r1, sp
+ ldr r2, [ip, #0] @ key2
+ bl AES_encrypt
+ mov r0, sp @ pointer to initial tweak
+#endif
+
+ ldr $rounds, [$key, #240] @ get # of rounds
+ mov $fp, r6
+#ifndef BSAES_ASM_EXTENDED_KEY
+ @ allocate the key schedule on the stack
+ sub r12, sp, $rounds, lsl#7 @ 128 bytes per inner round key
+ @ add r12, #`128-32` @ size of bit-sliced key schedule
+ sub r12, #`32+16` @ place for tweak[9]
+
+ @ populate the key schedule
+ mov r4, $key @ pass key
+ mov r5, $rounds @ pass # of rounds
+ mov sp, r12
+ add r12, #0x90 @ pass key schedule
+ bl _bsaes_key_convert
+ add r4, sp, #0x90
+ vldmia r4, {@XMM[6]}
+ vstmia r12, {@XMM[15]} @ save last round key
+ veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key
+ vstmia r4, {@XMM[7]}
+#else
+ ldr r12, [$key, #244]
+ eors r12, #1
+ beq 0f
+
+ str r12, [$key, #244]
+ mov r4, $key @ pass key
+ mov r5, $rounds @ pass # of rounds
+ add r12, $key, #248 @ pass key schedule
+ bl _bsaes_key_convert
+ add r4, $key, #248
+ vldmia r4, {@XMM[6]}
+ vstmia r12, {@XMM[15]} @ save last round key
+ veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key
+ vstmia r4, {@XMM[7]}
+
+.align 2
+0: sub sp, #0x90 @ place for tweak[9]
+#endif
+ vld1.8 {@XMM[8]}, [r0] @ initial tweak
+ adr $magic, .Lxts_magic
+
+#ifndef XTS_CHAIN_TWEAK
+ tst $len, #0xf @ if not multiple of 16
+ it ne @ Thumb2 thing, sanity check in ARM
+ subne $len, #0x10 @ subtract another 16 bytes
+#endif
+ subs $len, #0x80
+
+ blo .Lxts_dec_short
+ b .Lxts_dec_loop
+
+.align 4
+.Lxts_dec_loop:
+ vldmia $magic, {$twmask} @ load XTS magic
+ vshr.s64 @T[0], @XMM[8], #63
+ mov r0, sp
+ vand @T[0], @T[0], $twmask
+___
+for($i=9;$i<16;$i++) {
+$code.=<<___;
+ vadd.u64 @XMM[$i], @XMM[$i-1], @XMM[$i-1]
+ vst1.64 {@XMM[$i-1]}, [r0,:128]!
+ vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
+ vshr.s64 @T[1], @XMM[$i], #63
+ veor @XMM[$i], @XMM[$i], @T[0]
+ vand @T[1], @T[1], $twmask
+___
+ @T=reverse(@T);
+
+$code.=<<___ if ($i>=10);
+ vld1.8 {@XMM[$i-10]}, [$inp]!
+___
+$code.=<<___ if ($i>=11);
+ veor @XMM[$i-11], @XMM[$i-11], @XMM[$i-3]
+___
+}
+$code.=<<___;
+ vadd.u64 @XMM[8], @XMM[15], @XMM[15]
+ vst1.64 {@XMM[15]}, [r0,:128]!
+ vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
+ veor @XMM[8], @XMM[8], @T[0]
+ vst1.64 {@XMM[8]}, [r0,:128] @ next round tweak
+
+ vld1.8 {@XMM[6]-@XMM[7]}, [$inp]!
+ veor @XMM[5], @XMM[5], @XMM[13]
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, $key, #248 @ pass key schedule
+#endif
+ veor @XMM[6], @XMM[6], @XMM[14]
+ mov r5, $rounds @ pass rounds
+ veor @XMM[7], @XMM[7], @XMM[15]
+ mov r0, sp
+
+ bl _bsaes_decrypt8
+
+ vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
+ vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
+ veor @XMM[0], @XMM[0], @XMM[ 8]
+ vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]!
+ veor @XMM[1], @XMM[1], @XMM[ 9]
+ veor @XMM[8], @XMM[6], @XMM[10]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
+ veor @XMM[9], @XMM[4], @XMM[11]
+ vld1.64 {@XMM[14]-@XMM[15]}, [r0,:128]!
+ veor @XMM[10], @XMM[2], @XMM[12]
+ vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
+ veor @XMM[11], @XMM[7], @XMM[13]
+ veor @XMM[12], @XMM[3], @XMM[14]
+ vst1.8 {@XMM[10]-@XMM[11]}, [$out]!
+ veor @XMM[13], @XMM[5], @XMM[15]
+ vst1.8 {@XMM[12]-@XMM[13]}, [$out]!
+
+ vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
+
+ subs $len, #0x80
+ bpl .Lxts_dec_loop
+
+.Lxts_dec_short:
+ adds $len, #0x70
+ bmi .Lxts_dec_done
+
+ vldmia $magic, {$twmask} @ load XTS magic
+ vshr.s64 @T[0], @XMM[8], #63
+ mov r0, sp
+ vand @T[0], @T[0], $twmask
+___
+for($i=9;$i<16;$i++) {
+$code.=<<___;
+ vadd.u64 @XMM[$i], @XMM[$i-1], @XMM[$i-1]
+ vst1.64 {@XMM[$i-1]}, [r0,:128]!
+ vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
+ vshr.s64 @T[1], @XMM[$i], #63
+ veor @XMM[$i], @XMM[$i], @T[0]
+ vand @T[1], @T[1], $twmask
+___
+ @T=reverse(@T);
+
+$code.=<<___ if ($i>=10);
+ vld1.8 {@XMM[$i-10]}, [$inp]!
+ subs $len, #0x10
+ bmi .Lxts_dec_`$i-9`
+___
+$code.=<<___ if ($i>=11);
+ veor @XMM[$i-11], @XMM[$i-11], @XMM[$i-3]
+___
+}
+$code.=<<___;
+ sub $len, #0x10
+ vst1.64 {@XMM[15]}, [r0,:128] @ next round tweak
+
+ vld1.8 {@XMM[6]}, [$inp]!
+ veor @XMM[5], @XMM[5], @XMM[13]
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, $key, #248 @ pass key schedule
+#endif
+ veor @XMM[6], @XMM[6], @XMM[14]
+ mov r5, $rounds @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_decrypt8
+
+ vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
+ vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
+ veor @XMM[0], @XMM[0], @XMM[ 8]
+ vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]!
+ veor @XMM[1], @XMM[1], @XMM[ 9]
+ veor @XMM[8], @XMM[6], @XMM[10]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
+ veor @XMM[9], @XMM[4], @XMM[11]
+ vld1.64 {@XMM[14]}, [r0,:128]!
+ veor @XMM[10], @XMM[2], @XMM[12]
+ vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
+ veor @XMM[11], @XMM[7], @XMM[13]
+ veor @XMM[12], @XMM[3], @XMM[14]
+ vst1.8 {@XMM[10]-@XMM[11]}, [$out]!
+ vst1.8 {@XMM[12]}, [$out]!
+
+ vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
+ b .Lxts_dec_done
+.align 4
+.Lxts_dec_6:
+ vst1.64 {@XMM[14]}, [r0,:128] @ next round tweak
+
+ veor @XMM[4], @XMM[4], @XMM[12]
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, $key, #248 @ pass key schedule
+#endif
+ veor @XMM[5], @XMM[5], @XMM[13]
+ mov r5, $rounds @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_decrypt8
+
+ vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
+ vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
+ veor @XMM[0], @XMM[0], @XMM[ 8]
+ vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]!
+ veor @XMM[1], @XMM[1], @XMM[ 9]
+ veor @XMM[8], @XMM[6], @XMM[10]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
+ veor @XMM[9], @XMM[4], @XMM[11]
+ veor @XMM[10], @XMM[2], @XMM[12]
+ vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
+ veor @XMM[11], @XMM[7], @XMM[13]
+ vst1.8 {@XMM[10]-@XMM[11]}, [$out]!
+
+ vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
+ b .Lxts_dec_done
+.align 4
+.Lxts_dec_5:
+ vst1.64 {@XMM[13]}, [r0,:128] @ next round tweak
+
+ veor @XMM[3], @XMM[3], @XMM[11]
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, $key, #248 @ pass key schedule
+#endif
+ veor @XMM[4], @XMM[4], @XMM[12]
+ mov r5, $rounds @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_decrypt8
+
+ vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
+ vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
+ veor @XMM[0], @XMM[0], @XMM[ 8]
+ vld1.64 {@XMM[12]}, [r0,:128]!
+ veor @XMM[1], @XMM[1], @XMM[ 9]
+ veor @XMM[8], @XMM[6], @XMM[10]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
+ veor @XMM[9], @XMM[4], @XMM[11]
+ veor @XMM[10], @XMM[2], @XMM[12]
+ vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
+ vst1.8 {@XMM[10]}, [$out]!
+
+ vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
+ b .Lxts_dec_done
+.align 4
+.Lxts_dec_4:
+ vst1.64 {@XMM[12]}, [r0,:128] @ next round tweak
+
+ veor @XMM[2], @XMM[2], @XMM[10]
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, $key, #248 @ pass key schedule
+#endif
+ veor @XMM[3], @XMM[3], @XMM[11]
+ mov r5, $rounds @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_decrypt8
+
+ vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
+ vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
+ veor @XMM[0], @XMM[0], @XMM[ 8]
+ veor @XMM[1], @XMM[1], @XMM[ 9]
+ veor @XMM[8], @XMM[6], @XMM[10]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
+ veor @XMM[9], @XMM[4], @XMM[11]
+ vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
+
+ vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
+ b .Lxts_dec_done
+.align 4
+.Lxts_dec_3:
+ vst1.64 {@XMM[11]}, [r0,:128] @ next round tweak
+
+ veor @XMM[1], @XMM[1], @XMM[9]
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, $key, #248 @ pass key schedule
+#endif
+ veor @XMM[2], @XMM[2], @XMM[10]
+ mov r5, $rounds @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_decrypt8
+
+ vld1.64 {@XMM[8]-@XMM[9]}, [r0,:128]!
+ vld1.64 {@XMM[10]}, [r0,:128]!
+ veor @XMM[0], @XMM[0], @XMM[ 8]
+ veor @XMM[1], @XMM[1], @XMM[ 9]
+ veor @XMM[8], @XMM[6], @XMM[10]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
+ vst1.8 {@XMM[8]}, [$out]!
+
+ vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
+ b .Lxts_dec_done
+.align 4
+.Lxts_dec_2:
+ vst1.64 {@XMM[10]}, [r0,:128] @ next round tweak
+
+ veor @XMM[0], @XMM[0], @XMM[8]
+#ifndef BSAES_ASM_EXTENDED_KEY
+ add r4, sp, #0x90 @ pass key schedule
+#else
+ add r4, $key, #248 @ pass key schedule
+#endif
+ veor @XMM[1], @XMM[1], @XMM[9]
+ mov r5, $rounds @ pass rounds
+ mov r0, sp
+
+ bl _bsaes_decrypt8
+
+ vld1.64 {@XMM[8]-@XMM[9]}, [r0,:128]!
+ veor @XMM[0], @XMM[0], @XMM[ 8]
+ veor @XMM[1], @XMM[1], @XMM[ 9]
+ vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
+
+ vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
+ b .Lxts_dec_done
+.align 4
+.Lxts_dec_1:
+ mov r0, sp
+ veor @XMM[0], @XMM[8]
+ mov r1, sp
+ vst1.8 {@XMM[0]}, [sp,:128]
+ mov r2, $key
+ mov r4, $fp @ preserve fp
+ mov r5, $magic @ preserve magic
+
+ bl AES_decrypt
+
+ vld1.8 {@XMM[0]}, [sp,:128]
+ veor @XMM[0], @XMM[0], @XMM[8]
+ vst1.8 {@XMM[0]}, [$out]!
+ mov $fp, r4
+ mov $magic, r5
+
+ vmov @XMM[8], @XMM[9] @ next round tweak
+
+.Lxts_dec_done:
+#ifndef XTS_CHAIN_TWEAK
+ adds $len, #0x10
+ beq .Lxts_dec_ret
+
+ @ calculate one round of extra tweak for the stolen ciphertext
+ vldmia $magic, {$twmask}
+ vshr.s64 @XMM[6], @XMM[8], #63
+ vand @XMM[6], @XMM[6], $twmask
+ vadd.u64 @XMM[9], @XMM[8], @XMM[8]
+ vswp `&Dhi("@XMM[6]")`,`&Dlo("@XMM[6]")`
+ veor @XMM[9], @XMM[9], @XMM[6]
+
+ @ perform the final decryption with the last tweak value
+ vld1.8 {@XMM[0]}, [$inp]!
+ mov r0, sp
+ veor @XMM[0], @XMM[0], @XMM[9]
+ mov r1, sp
+ vst1.8 {@XMM[0]}, [sp,:128]
+ mov r2, $key
+ mov r4, $fp @ preserve fp
+
+ bl AES_decrypt
+
+ vld1.8 {@XMM[0]}, [sp,:128]
+ veor @XMM[0], @XMM[0], @XMM[9]
+ vst1.8 {@XMM[0]}, [$out]
+
+ mov r6, $out
+.Lxts_dec_steal:
+ ldrb r1, [$out]
+ ldrb r0, [$inp], #1
+ strb r1, [$out, #0x10]
+ strb r0, [$out], #1
+
+ subs $len, #1
+ bhi .Lxts_dec_steal
+
+ vld1.8 {@XMM[0]}, [r6]
+ mov r0, sp
+ veor @XMM[0], @XMM[8]
+ mov r1, sp
+ vst1.8 {@XMM[0]}, [sp,:128]
+ mov r2, $key
+
+ bl AES_decrypt
+
+ vld1.8 {@XMM[0]}, [sp,:128]
+ veor @XMM[0], @XMM[0], @XMM[8]
+ vst1.8 {@XMM[0]}, [r6]
+ mov $fp, r4
+#endif
+
+.Lxts_dec_ret:
+ bic r0, $fp, #0xf
+ vmov.i32 q0, #0
+ vmov.i32 q1, #0
+#ifdef XTS_CHAIN_TWEAK
+ ldr r1, [$fp, #0x20+VFP_ABI_FRAME] @ chain tweak
+#endif
+.Lxts_dec_bzero: @ wipe key schedule [if any]
+ vstmia sp!, {q0-q1}
+ cmp sp, r0
+ bne .Lxts_dec_bzero
+
+ mov sp, $fp
+#ifdef XTS_CHAIN_TWEAK
+ vst1.8 {@XMM[8]}, [r1]
+#endif
+ VFP_ABI_POP
+ ldmia sp!, {r4-r10, pc} @ return
+
+.size bsaes_xts_decrypt,.-bsaes_xts_decrypt
+___
+}
+$code.=<<___;
+#endif
+___
+
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+
+open SELF,$0;
+while(<SELF>) {
+ next if (/^#!/);
+ last if (!s/^#/@/ and !/^$/);
+ print;
+}
+close SELF;
+
+print $code;
+
+close STDOUT;
diff --git a/arch/arm/crypto/ghash-ce-core.S b/arch/arm/crypto/ghash-ce-core.S
new file mode 100644
index 000000000..f6ab8bcc9
--- /dev/null
+++ b/arch/arm/crypto/ghash-ce-core.S
@@ -0,0 +1,94 @@
+/*
+ * Accelerated GHASH implementation with ARMv8 vmull.p64 instructions.
+ *
+ * Copyright (C) 2015 Linaro Ltd. <ard.biesheuvel@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 <linux/linkage.h>
+#include <asm/assembler.h>
+
+ SHASH .req q0
+ SHASH2 .req q1
+ T1 .req q2
+ T2 .req q3
+ MASK .req q4
+ XL .req q5
+ XM .req q6
+ XH .req q7
+ IN1 .req q7
+
+ SHASH_L .req d0
+ SHASH_H .req d1
+ SHASH2_L .req d2
+ T1_L .req d4
+ MASK_L .req d8
+ XL_L .req d10
+ XL_H .req d11
+ XM_L .req d12
+ XM_H .req d13
+ XH_L .req d14
+
+ .text
+ .fpu crypto-neon-fp-armv8
+
+ /*
+ * void pmull_ghash_update(int blocks, u64 dg[], const char *src,
+ * struct ghash_key const *k, const char *head)
+ */
+ENTRY(pmull_ghash_update)
+ vld1.64 {SHASH}, [r3]
+ vld1.64 {XL}, [r1]
+ vmov.i8 MASK, #0xe1
+ vext.8 SHASH2, SHASH, SHASH, #8
+ vshl.u64 MASK, MASK, #57
+ veor SHASH2, SHASH2, SHASH
+
+ /* do the head block first, if supplied */
+ ldr ip, [sp]
+ teq ip, #0
+ beq 0f
+ vld1.64 {T1}, [ip]
+ teq r0, #0
+ b 1f
+
+0: vld1.64 {T1}, [r2]!
+ subs r0, r0, #1
+
+1: /* multiply XL by SHASH in GF(2^128) */
+#ifndef CONFIG_CPU_BIG_ENDIAN
+ vrev64.8 T1, T1
+#endif
+ vext.8 T2, XL, XL, #8
+ vext.8 IN1, T1, T1, #8
+ veor T1, T1, T2
+ veor XL, XL, IN1
+
+ vmull.p64 XH, SHASH_H, XL_H @ a1 * b1
+ veor T1, T1, XL
+ vmull.p64 XL, SHASH_L, XL_L @ a0 * b0
+ vmull.p64 XM, SHASH2_L, T1_L @ (a1 + a0)(b1 + b0)
+
+ vext.8 T1, XL, XH, #8
+ veor T2, XL, XH
+ veor XM, XM, T1
+ veor XM, XM, T2
+ vmull.p64 T2, XL_L, MASK_L
+
+ vmov XH_L, XM_H
+ vmov XM_H, XL_L
+
+ veor XL, XM, T2
+ vext.8 T2, XL, XL, #8
+ vmull.p64 XL, XL_L, MASK_L
+ veor T2, T2, XH
+ veor XL, XL, T2
+
+ bne 0b
+
+ vst1.64 {XL}, [r1]
+ bx lr
+ENDPROC(pmull_ghash_update)
diff --git a/arch/arm/crypto/ghash-ce-glue.c b/arch/arm/crypto/ghash-ce-glue.c
new file mode 100644
index 000000000..03a39fe29
--- /dev/null
+++ b/arch/arm/crypto/ghash-ce-glue.c
@@ -0,0 +1,320 @@
+/*
+ * Accelerated GHASH implementation with ARMv8 vmull.p64 instructions.
+ *
+ * Copyright (C) 2015 Linaro Ltd. <ard.biesheuvel@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 <asm/hwcap.h>
+#include <asm/neon.h>
+#include <asm/simd.h>
+#include <asm/unaligned.h>
+#include <crypto/cryptd.h>
+#include <crypto/internal/hash.h>
+#include <crypto/gf128mul.h>
+#include <linux/crypto.h>
+#include <linux/module.h>
+
+MODULE_DESCRIPTION("GHASH secure hash using ARMv8 Crypto Extensions");
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_LICENSE("GPL v2");
+
+#define GHASH_BLOCK_SIZE 16
+#define GHASH_DIGEST_SIZE 16
+
+struct ghash_key {
+ u64 a;
+ u64 b;
+};
+
+struct ghash_desc_ctx {
+ u64 digest[GHASH_DIGEST_SIZE/sizeof(u64)];
+ u8 buf[GHASH_BLOCK_SIZE];
+ u32 count;
+};
+
+struct ghash_async_ctx {
+ struct cryptd_ahash *cryptd_tfm;
+};
+
+asmlinkage void pmull_ghash_update(int blocks, u64 dg[], const char *src,
+ struct ghash_key const *k, const char *head);
+
+static int ghash_init(struct shash_desc *desc)
+{
+ struct ghash_desc_ctx *ctx = shash_desc_ctx(desc);
+
+ *ctx = (struct ghash_desc_ctx){};
+ return 0;
+}
+
+static int ghash_update(struct shash_desc *desc, const u8 *src,
+ unsigned int len)
+{
+ struct ghash_desc_ctx *ctx = shash_desc_ctx(desc);
+ unsigned int partial = ctx->count % GHASH_BLOCK_SIZE;
+
+ ctx->count += len;
+
+ if ((partial + len) >= GHASH_BLOCK_SIZE) {
+ struct ghash_key *key = crypto_shash_ctx(desc->tfm);
+ int blocks;
+
+ if (partial) {
+ int p = GHASH_BLOCK_SIZE - partial;
+
+ memcpy(ctx->buf + partial, src, p);
+ src += p;
+ len -= p;
+ }
+
+ blocks = len / GHASH_BLOCK_SIZE;
+ len %= GHASH_BLOCK_SIZE;
+
+ kernel_neon_begin();
+ pmull_ghash_update(blocks, ctx->digest, src, key,
+ partial ? ctx->buf : NULL);
+ kernel_neon_end();
+ src += blocks * GHASH_BLOCK_SIZE;
+ partial = 0;
+ }
+ if (len)
+ memcpy(ctx->buf + partial, src, len);
+ return 0;
+}
+
+static int ghash_final(struct shash_desc *desc, u8 *dst)
+{
+ struct ghash_desc_ctx *ctx = shash_desc_ctx(desc);
+ unsigned int partial = ctx->count % GHASH_BLOCK_SIZE;
+
+ if (partial) {
+ struct ghash_key *key = crypto_shash_ctx(desc->tfm);
+
+ memset(ctx->buf + partial, 0, GHASH_BLOCK_SIZE - partial);
+ kernel_neon_begin();
+ pmull_ghash_update(1, ctx->digest, ctx->buf, key, NULL);
+ kernel_neon_end();
+ }
+ put_unaligned_be64(ctx->digest[1], dst);
+ put_unaligned_be64(ctx->digest[0], dst + 8);
+
+ *ctx = (struct ghash_desc_ctx){};
+ return 0;
+}
+
+static int ghash_setkey(struct crypto_shash *tfm,
+ const u8 *inkey, unsigned int keylen)
+{
+ struct ghash_key *key = crypto_shash_ctx(tfm);
+ u64 a, b;
+
+ if (keylen != GHASH_BLOCK_SIZE) {
+ crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
+ return -EINVAL;
+ }
+
+ /* perform multiplication by 'x' in GF(2^128) */
+ b = get_unaligned_be64(inkey);
+ a = get_unaligned_be64(inkey + 8);
+
+ key->a = (a << 1) | (b >> 63);
+ key->b = (b << 1) | (a >> 63);
+
+ if (b >> 63)
+ key->b ^= 0xc200000000000000UL;
+
+ return 0;
+}
+
+static struct shash_alg ghash_alg = {
+ .digestsize = GHASH_DIGEST_SIZE,
+ .init = ghash_init,
+ .update = ghash_update,
+ .final = ghash_final,
+ .setkey = ghash_setkey,
+ .descsize = sizeof(struct ghash_desc_ctx),
+ .base = {
+ .cra_name = "ghash",
+ .cra_driver_name = "__driver-ghash-ce",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH | CRYPTO_ALG_INTERNAL,
+ .cra_blocksize = GHASH_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct ghash_key),
+ .cra_module = THIS_MODULE,
+ },
+};
+
+static int ghash_async_init(struct ahash_request *req)
+{
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
+ struct ahash_request *cryptd_req = ahash_request_ctx(req);
+ struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
+
+ if (!may_use_simd()) {
+ memcpy(cryptd_req, req, sizeof(*req));
+ ahash_request_set_tfm(cryptd_req, &cryptd_tfm->base);
+ return crypto_ahash_init(cryptd_req);
+ } else {
+ struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
+ struct crypto_shash *child = cryptd_ahash_child(cryptd_tfm);
+
+ desc->tfm = child;
+ desc->flags = req->base.flags;
+ return crypto_shash_init(desc);
+ }
+}
+
+static int ghash_async_update(struct ahash_request *req)
+{
+ struct ahash_request *cryptd_req = ahash_request_ctx(req);
+
+ if (!may_use_simd()) {
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
+ struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
+
+ memcpy(cryptd_req, req, sizeof(*req));
+ ahash_request_set_tfm(cryptd_req, &cryptd_tfm->base);
+ return crypto_ahash_update(cryptd_req);
+ } else {
+ struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
+ return shash_ahash_update(req, desc);
+ }
+}
+
+static int ghash_async_final(struct ahash_request *req)
+{
+ struct ahash_request *cryptd_req = ahash_request_ctx(req);
+
+ if (!may_use_simd()) {
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
+ struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
+
+ memcpy(cryptd_req, req, sizeof(*req));
+ ahash_request_set_tfm(cryptd_req, &cryptd_tfm->base);
+ return crypto_ahash_final(cryptd_req);
+ } else {
+ struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
+ return crypto_shash_final(desc, req->result);
+ }
+}
+
+static int ghash_async_digest(struct ahash_request *req)
+{
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
+ struct ahash_request *cryptd_req = ahash_request_ctx(req);
+ struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
+
+ if (!may_use_simd()) {
+ memcpy(cryptd_req, req, sizeof(*req));
+ ahash_request_set_tfm(cryptd_req, &cryptd_tfm->base);
+ return crypto_ahash_digest(cryptd_req);
+ } else {
+ struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
+ struct crypto_shash *child = cryptd_ahash_child(cryptd_tfm);
+
+ desc->tfm = child;
+ desc->flags = req->base.flags;
+ return shash_ahash_digest(req, desc);
+ }
+}
+
+static int ghash_async_setkey(struct crypto_ahash *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
+ struct crypto_ahash *child = &ctx->cryptd_tfm->base;
+ int err;
+
+ crypto_ahash_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+ crypto_ahash_set_flags(child, crypto_ahash_get_flags(tfm)
+ & CRYPTO_TFM_REQ_MASK);
+ err = crypto_ahash_setkey(child, key, keylen);
+ crypto_ahash_set_flags(tfm, crypto_ahash_get_flags(child)
+ & CRYPTO_TFM_RES_MASK);
+
+ return err;
+}
+
+static int ghash_async_init_tfm(struct crypto_tfm *tfm)
+{
+ struct cryptd_ahash *cryptd_tfm;
+ struct ghash_async_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ cryptd_tfm = cryptd_alloc_ahash("__driver-ghash-ce",
+ CRYPTO_ALG_INTERNAL,
+ CRYPTO_ALG_INTERNAL);
+ if (IS_ERR(cryptd_tfm))
+ return PTR_ERR(cryptd_tfm);
+ ctx->cryptd_tfm = cryptd_tfm;
+ crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
+ sizeof(struct ahash_request) +
+ crypto_ahash_reqsize(&cryptd_tfm->base));
+
+ return 0;
+}
+
+static void ghash_async_exit_tfm(struct crypto_tfm *tfm)
+{
+ struct ghash_async_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ cryptd_free_ahash(ctx->cryptd_tfm);
+}
+
+static struct ahash_alg ghash_async_alg = {
+ .init = ghash_async_init,
+ .update = ghash_async_update,
+ .final = ghash_async_final,
+ .setkey = ghash_async_setkey,
+ .digest = ghash_async_digest,
+ .halg.digestsize = GHASH_DIGEST_SIZE,
+ .halg.base = {
+ .cra_name = "ghash",
+ .cra_driver_name = "ghash-ce",
+ .cra_priority = 300,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = GHASH_BLOCK_SIZE,
+ .cra_type = &crypto_ahash_type,
+ .cra_ctxsize = sizeof(struct ghash_async_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_init = ghash_async_init_tfm,
+ .cra_exit = ghash_async_exit_tfm,
+ },
+};
+
+static int __init ghash_ce_mod_init(void)
+{
+ int err;
+
+ if (!(elf_hwcap2 & HWCAP2_PMULL))
+ return -ENODEV;
+
+ err = crypto_register_shash(&ghash_alg);
+ if (err)
+ return err;
+ err = crypto_register_ahash(&ghash_async_alg);
+ if (err)
+ goto err_shash;
+
+ return 0;
+
+err_shash:
+ crypto_unregister_shash(&ghash_alg);
+ return err;
+}
+
+static void __exit ghash_ce_mod_exit(void)
+{
+ crypto_unregister_ahash(&ghash_async_alg);
+ crypto_unregister_shash(&ghash_alg);
+}
+
+module_init(ghash_ce_mod_init);
+module_exit(ghash_ce_mod_exit);
diff --git a/arch/arm/crypto/sha1-armv4-large.S b/arch/arm/crypto/sha1-armv4-large.S
new file mode 100644
index 000000000..99207c45e
--- /dev/null
+++ b/arch/arm/crypto/sha1-armv4-large.S
@@ -0,0 +1,497 @@
+#define __ARM_ARCH__ __LINUX_ARM_ARCH__
+@ ====================================================================
+@ Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+@ project. The module is, however, dual licensed under OpenSSL and
+@ CRYPTOGAMS licenses depending on where you obtain it. For further
+@ details see http://www.openssl.org/~appro/cryptogams/.
+@ ====================================================================
+
+@ sha1_block procedure for ARMv4.
+@
+@ January 2007.
+
+@ Size/performance trade-off
+@ ====================================================================
+@ impl size in bytes comp cycles[*] measured performance
+@ ====================================================================
+@ thumb 304 3212 4420
+@ armv4-small 392/+29% 1958/+64% 2250/+96%
+@ armv4-compact 740/+89% 1552/+26% 1840/+22%
+@ armv4-large 1420/+92% 1307/+19% 1370/+34%[***]
+@ full unroll ~5100/+260% ~1260/+4% ~1300/+5%
+@ ====================================================================
+@ thumb = same as 'small' but in Thumb instructions[**] and
+@ with recurring code in two private functions;
+@ small = detached Xload/update, loops are folded;
+@ compact = detached Xload/update, 5x unroll;
+@ large = interleaved Xload/update, 5x unroll;
+@ full unroll = interleaved Xload/update, full unroll, estimated[!];
+@
+@ [*] Manually counted instructions in "grand" loop body. Measured
+@ performance is affected by prologue and epilogue overhead,
+@ i-cache availability, branch penalties, etc.
+@ [**] While each Thumb instruction is twice smaller, they are not as
+@ diverse as ARM ones: e.g., there are only two arithmetic
+@ instructions with 3 arguments, no [fixed] rotate, addressing
+@ modes are limited. As result it takes more instructions to do
+@ the same job in Thumb, therefore the code is never twice as
+@ small and always slower.
+@ [***] which is also ~35% better than compiler generated code. Dual-
+@ issue Cortex A8 core was measured to process input block in
+@ ~990 cycles.
+
+@ August 2010.
+@
+@ Rescheduling for dual-issue pipeline resulted in 13% improvement on
+@ Cortex A8 core and in absolute terms ~870 cycles per input block
+@ [or 13.6 cycles per byte].
+
+@ February 2011.
+@
+@ Profiler-assisted and platform-specific optimization resulted in 10%
+@ improvement on Cortex A8 core and 12.2 cycles per byte.
+
+#include <linux/linkage.h>
+
+.text
+
+.align 2
+ENTRY(sha1_block_data_order)
+ stmdb sp!,{r4-r12,lr}
+ add r2,r1,r2,lsl#6 @ r2 to point at the end of r1
+ ldmia r0,{r3,r4,r5,r6,r7}
+.Lloop:
+ ldr r8,.LK_00_19
+ mov r14,sp
+ sub sp,sp,#15*4
+ mov r5,r5,ror#30
+ mov r6,r6,ror#30
+ mov r7,r7,ror#30 @ [6]
+.L_00_15:
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r7,r8,r7,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r5,r6 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r7,r8,r7,ror#2 @ E+=K_00_19
+ eor r10,r5,r6 @ F_xx_xx
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r4,r10,ror#2
+ add r7,r7,r9 @ E+=X[i]
+ eor r10,r10,r6,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r7,r7,r10 @ E+=F_00_19(B,C,D)
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r6,r8,r6,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r4,r5 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r6,r6,r7,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r6,r8,r6,ror#2 @ E+=K_00_19
+ eor r10,r4,r5 @ F_xx_xx
+ add r6,r6,r7,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r3,r10,ror#2
+ add r6,r6,r9 @ E+=X[i]
+ eor r10,r10,r5,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r6,r6,r10 @ E+=F_00_19(B,C,D)
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r5,r8,r5,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r3,r4 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r5,r5,r6,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r5,r8,r5,ror#2 @ E+=K_00_19
+ eor r10,r3,r4 @ F_xx_xx
+ add r5,r5,r6,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r7,r10,ror#2
+ add r5,r5,r9 @ E+=X[i]
+ eor r10,r10,r4,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r5,r5,r10 @ E+=F_00_19(B,C,D)
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r4,r8,r4,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r7,r3 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r4,r4,r5,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r4,r8,r4,ror#2 @ E+=K_00_19
+ eor r10,r7,r3 @ F_xx_xx
+ add r4,r4,r5,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r6,r10,ror#2
+ add r4,r4,r9 @ E+=X[i]
+ eor r10,r10,r3,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r4,r4,r10 @ E+=F_00_19(B,C,D)
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r3,r8,r3,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r6,r7 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r3,r3,r4,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r3,r8,r3,ror#2 @ E+=K_00_19
+ eor r10,r6,r7 @ F_xx_xx
+ add r3,r3,r4,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r5,r10,ror#2
+ add r3,r3,r9 @ E+=X[i]
+ eor r10,r10,r7,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r3,r3,r10 @ E+=F_00_19(B,C,D)
+ cmp r14,sp
+ bne .L_00_15 @ [((11+4)*5+2)*3]
+ sub sp,sp,#25*4
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r7,r8,r7,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r5,r6 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r7,r8,r7,ror#2 @ E+=K_00_19
+ eor r10,r5,r6 @ F_xx_xx
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r4,r10,ror#2
+ add r7,r7,r9 @ E+=X[i]
+ eor r10,r10,r6,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r7,r7,r10 @ E+=F_00_19(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r6,r8,r6,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r4,r5 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r6,r6,r7,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r3,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r6,r6,r9 @ E+=X[i]
+ eor r10,r10,r5,ror#2 @ F_00_19(B,C,D)
+ add r6,r6,r10 @ E+=F_00_19(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r5,r8,r5,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r3,r4 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r5,r5,r6,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r7,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r5,r5,r9 @ E+=X[i]
+ eor r10,r10,r4,ror#2 @ F_00_19(B,C,D)
+ add r5,r5,r10 @ E+=F_00_19(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r4,r8,r4,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r7,r3 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r4,r4,r5,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r6,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r4,r4,r9 @ E+=X[i]
+ eor r10,r10,r3,ror#2 @ F_00_19(B,C,D)
+ add r4,r4,r10 @ E+=F_00_19(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r3,r8,r3,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r6,r7 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r3,r3,r4,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r5,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r3,r3,r9 @ E+=X[i]
+ eor r10,r10,r7,ror#2 @ F_00_19(B,C,D)
+ add r3,r3,r10 @ E+=F_00_19(B,C,D)
+
+ ldr r8,.LK_20_39 @ [+15+16*4]
+ cmn sp,#0 @ [+3], clear carry to denote 20_39
+.L_20_39_or_60_79:
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r7,r8,r7,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r5,r6 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ eor r10,r4,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r7,r7,r9 @ E+=X[i]
+ add r7,r7,r10 @ E+=F_20_39(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r6,r8,r6,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r4,r5 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r6,r6,r7,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ eor r10,r3,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r6,r6,r9 @ E+=X[i]
+ add r6,r6,r10 @ E+=F_20_39(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r5,r8,r5,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r3,r4 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r5,r5,r6,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ eor r10,r7,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r5,r5,r9 @ E+=X[i]
+ add r5,r5,r10 @ E+=F_20_39(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r4,r8,r4,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r7,r3 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r4,r4,r5,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ eor r10,r6,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r4,r4,r9 @ E+=X[i]
+ add r4,r4,r10 @ E+=F_20_39(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r3,r8,r3,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r6,r7 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r3,r3,r4,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ eor r10,r5,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r3,r3,r9 @ E+=X[i]
+ add r3,r3,r10 @ E+=F_20_39(B,C,D)
+ ARM( teq r14,sp ) @ preserve carry
+ THUMB( mov r11,sp )
+ THUMB( teq r14,r11 ) @ preserve carry
+ bne .L_20_39_or_60_79 @ [+((12+3)*5+2)*4]
+ bcs .L_done @ [+((12+3)*5+2)*4], spare 300 bytes
+
+ ldr r8,.LK_40_59
+ sub sp,sp,#20*4 @ [+2]
+.L_40_59:
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r7,r8,r7,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r5,r6 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r4,r10,ror#2 @ F_xx_xx
+ and r11,r5,r6 @ F_xx_xx
+ add r7,r7,r9 @ E+=X[i]
+ add r7,r7,r10 @ E+=F_40_59(B,C,D)
+ add r7,r7,r11,ror#2
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r6,r8,r6,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r4,r5 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r6,r6,r7,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r3,r10,ror#2 @ F_xx_xx
+ and r11,r4,r5 @ F_xx_xx
+ add r6,r6,r9 @ E+=X[i]
+ add r6,r6,r10 @ E+=F_40_59(B,C,D)
+ add r6,r6,r11,ror#2
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r5,r8,r5,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r3,r4 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r5,r5,r6,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r7,r10,ror#2 @ F_xx_xx
+ and r11,r3,r4 @ F_xx_xx
+ add r5,r5,r9 @ E+=X[i]
+ add r5,r5,r10 @ E+=F_40_59(B,C,D)
+ add r5,r5,r11,ror#2
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r4,r8,r4,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r7,r3 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r4,r4,r5,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r6,r10,ror#2 @ F_xx_xx
+ and r11,r7,r3 @ F_xx_xx
+ add r4,r4,r9 @ E+=X[i]
+ add r4,r4,r10 @ E+=F_40_59(B,C,D)
+ add r4,r4,r11,ror#2
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r3,r8,r3,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r6,r7 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r3,r3,r4,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r5,r10,ror#2 @ F_xx_xx
+ and r11,r6,r7 @ F_xx_xx
+ add r3,r3,r9 @ E+=X[i]
+ add r3,r3,r10 @ E+=F_40_59(B,C,D)
+ add r3,r3,r11,ror#2
+ cmp r14,sp
+ bne .L_40_59 @ [+((12+5)*5+2)*4]
+
+ ldr r8,.LK_60_79
+ sub sp,sp,#20*4
+ cmp sp,#0 @ set carry to denote 60_79
+ b .L_20_39_or_60_79 @ [+4], spare 300 bytes
+.L_done:
+ add sp,sp,#80*4 @ "deallocate" stack frame
+ ldmia r0,{r8,r9,r10,r11,r12}
+ add r3,r8,r3
+ add r4,r9,r4
+ add r5,r10,r5,ror#2
+ add r6,r11,r6,ror#2
+ add r7,r12,r7,ror#2
+ stmia r0,{r3,r4,r5,r6,r7}
+ teq r1,r2
+ bne .Lloop @ [+18], total 1307
+
+ ldmia sp!,{r4-r12,pc}
+.align 2
+.LK_00_19: .word 0x5a827999
+.LK_20_39: .word 0x6ed9eba1
+.LK_40_59: .word 0x8f1bbcdc
+.LK_60_79: .word 0xca62c1d6
+ENDPROC(sha1_block_data_order)
+.asciz "SHA1 block transform for ARMv4, CRYPTOGAMS by <appro@openssl.org>"
+.align 2
diff --git a/arch/arm/crypto/sha1-armv7-neon.S b/arch/arm/crypto/sha1-armv7-neon.S
new file mode 100644
index 000000000..dcd01f3f0
--- /dev/null
+++ b/arch/arm/crypto/sha1-armv7-neon.S
@@ -0,0 +1,639 @@
+/* sha1-armv7-neon.S - ARM/NEON accelerated SHA-1 transform function
+ *
+ * Copyright © 2013-2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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/assembler.h>
+
+.syntax unified
+.code 32
+.fpu neon
+
+.text
+
+
+/* Context structure */
+
+#define state_h0 0
+#define state_h1 4
+#define state_h2 8
+#define state_h3 12
+#define state_h4 16
+
+
+/* Constants */
+
+#define K1 0x5A827999
+#define K2 0x6ED9EBA1
+#define K3 0x8F1BBCDC
+#define K4 0xCA62C1D6
+.align 4
+.LK_VEC:
+.LK1: .long K1, K1, K1, K1
+.LK2: .long K2, K2, K2, K2
+.LK3: .long K3, K3, K3, K3
+.LK4: .long K4, K4, K4, K4
+
+
+/* Register macros */
+
+#define RSTATE r0
+#define RDATA r1
+#define RNBLKS r2
+#define ROLDSTACK r3
+#define RWK lr
+
+#define _a r4
+#define _b r5
+#define _c r6
+#define _d r7
+#define _e r8
+
+#define RT0 r9
+#define RT1 r10
+#define RT2 r11
+#define RT3 r12
+
+#define W0 q0
+#define W1 q7
+#define W2 q2
+#define W3 q3
+#define W4 q4
+#define W5 q6
+#define W6 q5
+#define W7 q1
+
+#define tmp0 q8
+#define tmp1 q9
+#define tmp2 q10
+#define tmp3 q11
+
+#define qK1 q12
+#define qK2 q13
+#define qK3 q14
+#define qK4 q15
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define ARM_LE(code...)
+#else
+#define ARM_LE(code...) code
+#endif
+
+/* Round function macros. */
+
+#define WK_offs(i) (((i) & 15) * 4)
+
+#define _R_F1(a,b,c,d,e,i,pre1,pre2,pre3,i16,\
+ W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ ldr RT3, [sp, WK_offs(i)]; \
+ pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ bic RT0, d, b; \
+ add e, e, a, ror #(32 - 5); \
+ and RT1, c, b; \
+ pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ add RT0, RT0, RT3; \
+ add e, e, RT1; \
+ ror b, #(32 - 30); \
+ pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ add e, e, RT0;
+
+#define _R_F2(a,b,c,d,e,i,pre1,pre2,pre3,i16,\
+ W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ ldr RT3, [sp, WK_offs(i)]; \
+ pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ eor RT0, d, b; \
+ add e, e, a, ror #(32 - 5); \
+ eor RT0, RT0, c; \
+ pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ add e, e, RT3; \
+ ror b, #(32 - 30); \
+ pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ add e, e, RT0; \
+
+#define _R_F3(a,b,c,d,e,i,pre1,pre2,pre3,i16,\
+ W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ ldr RT3, [sp, WK_offs(i)]; \
+ pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ eor RT0, b, c; \
+ and RT1, b, c; \
+ add e, e, a, ror #(32 - 5); \
+ pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ and RT0, RT0, d; \
+ add RT1, RT1, RT3; \
+ add e, e, RT0; \
+ ror b, #(32 - 30); \
+ pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ add e, e, RT1;
+
+#define _R_F4(a,b,c,d,e,i,pre1,pre2,pre3,i16,\
+ W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ _R_F2(a,b,c,d,e,i,pre1,pre2,pre3,i16,\
+ W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28)
+
+#define _R(a,b,c,d,e,f,i,pre1,pre2,pre3,i16,\
+ W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ _R_##f(a,b,c,d,e,i,pre1,pre2,pre3,i16,\
+ W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28)
+
+#define R(a,b,c,d,e,f,i) \
+ _R_##f(a,b,c,d,e,i,dummy,dummy,dummy,i16,\
+ W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28)
+
+#define dummy(...)
+
+
+/* Input expansion macros. */
+
+/********* Precalc macros for rounds 0-15 *************************************/
+
+#define W_PRECALC_00_15() \
+ add RWK, sp, #(WK_offs(0)); \
+ \
+ vld1.32 {W0, W7}, [RDATA]!; \
+ ARM_LE(vrev32.8 W0, W0; ) /* big => little */ \
+ vld1.32 {W6, W5}, [RDATA]!; \
+ vadd.u32 tmp0, W0, curK; \
+ ARM_LE(vrev32.8 W7, W7; ) /* big => little */ \
+ ARM_LE(vrev32.8 W6, W6; ) /* big => little */ \
+ vadd.u32 tmp1, W7, curK; \
+ ARM_LE(vrev32.8 W5, W5; ) /* big => little */ \
+ vadd.u32 tmp2, W6, curK; \
+ vst1.32 {tmp0, tmp1}, [RWK]!; \
+ vadd.u32 tmp3, W5, curK; \
+ vst1.32 {tmp2, tmp3}, [RWK]; \
+
+#define WPRECALC_00_15_0(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vld1.32 {W0, W7}, [RDATA]!; \
+
+#define WPRECALC_00_15_1(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ add RWK, sp, #(WK_offs(0)); \
+
+#define WPRECALC_00_15_2(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ ARM_LE(vrev32.8 W0, W0; ) /* big => little */ \
+
+#define WPRECALC_00_15_3(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vld1.32 {W6, W5}, [RDATA]!; \
+
+#define WPRECALC_00_15_4(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vadd.u32 tmp0, W0, curK; \
+
+#define WPRECALC_00_15_5(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ ARM_LE(vrev32.8 W7, W7; ) /* big => little */ \
+
+#define WPRECALC_00_15_6(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ ARM_LE(vrev32.8 W6, W6; ) /* big => little */ \
+
+#define WPRECALC_00_15_7(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vadd.u32 tmp1, W7, curK; \
+
+#define WPRECALC_00_15_8(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ ARM_LE(vrev32.8 W5, W5; ) /* big => little */ \
+
+#define WPRECALC_00_15_9(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vadd.u32 tmp2, W6, curK; \
+
+#define WPRECALC_00_15_10(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vst1.32 {tmp0, tmp1}, [RWK]!; \
+
+#define WPRECALC_00_15_11(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vadd.u32 tmp3, W5, curK; \
+
+#define WPRECALC_00_15_12(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vst1.32 {tmp2, tmp3}, [RWK]; \
+
+
+/********* Precalc macros for rounds 16-31 ************************************/
+
+#define WPRECALC_16_31_0(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ veor tmp0, tmp0; \
+ vext.8 W, W_m16, W_m12, #8; \
+
+#define WPRECALC_16_31_1(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ add RWK, sp, #(WK_offs(i)); \
+ vext.8 tmp0, W_m04, tmp0, #4; \
+
+#define WPRECALC_16_31_2(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ veor tmp0, tmp0, W_m16; \
+ veor.32 W, W, W_m08; \
+
+#define WPRECALC_16_31_3(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ veor tmp1, tmp1; \
+ veor W, W, tmp0; \
+
+#define WPRECALC_16_31_4(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vshl.u32 tmp0, W, #1; \
+
+#define WPRECALC_16_31_5(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vext.8 tmp1, tmp1, W, #(16-12); \
+ vshr.u32 W, W, #31; \
+
+#define WPRECALC_16_31_6(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vorr tmp0, tmp0, W; \
+ vshr.u32 W, tmp1, #30; \
+
+#define WPRECALC_16_31_7(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vshl.u32 tmp1, tmp1, #2; \
+
+#define WPRECALC_16_31_8(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ veor tmp0, tmp0, W; \
+
+#define WPRECALC_16_31_9(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ veor W, tmp0, tmp1; \
+
+#define WPRECALC_16_31_10(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vadd.u32 tmp0, W, curK; \
+
+#define WPRECALC_16_31_11(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vst1.32 {tmp0}, [RWK];
+
+
+/********* Precalc macros for rounds 32-79 ************************************/
+
+#define WPRECALC_32_79_0(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ veor W, W_m28; \
+
+#define WPRECALC_32_79_1(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vext.8 tmp0, W_m08, W_m04, #8; \
+
+#define WPRECALC_32_79_2(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ veor W, W_m16; \
+
+#define WPRECALC_32_79_3(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ veor W, tmp0; \
+
+#define WPRECALC_32_79_4(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ add RWK, sp, #(WK_offs(i&~3)); \
+
+#define WPRECALC_32_79_5(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vshl.u32 tmp1, W, #2; \
+
+#define WPRECALC_32_79_6(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vshr.u32 tmp0, W, #30; \
+
+#define WPRECALC_32_79_7(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vorr W, tmp0, tmp1; \
+
+#define WPRECALC_32_79_8(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vadd.u32 tmp0, W, curK; \
+
+#define WPRECALC_32_79_9(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ vst1.32 {tmp0}, [RWK];
+
+
+/*
+ * Transform nblks*64 bytes (nblks*16 32-bit words) at DATA.
+ *
+ * unsigned int
+ * sha1_transform_neon (void *ctx, const unsigned char *data,
+ * unsigned int nblks)
+ */
+.align 3
+ENTRY(sha1_transform_neon)
+ /* input:
+ * r0: ctx, CTX
+ * r1: data (64*nblks bytes)
+ * r2: nblks
+ */
+
+ cmp RNBLKS, #0;
+ beq .Ldo_nothing;
+
+ push {r4-r12, lr};
+ /*vpush {q4-q7};*/
+
+ adr RT3, .LK_VEC;
+
+ mov ROLDSTACK, sp;
+
+ /* Align stack. */
+ sub RT0, sp, #(16*4);
+ and RT0, #(~(16-1));
+ mov sp, RT0;
+
+ vld1.32 {qK1-qK2}, [RT3]!; /* Load K1,K2 */
+
+ /* Get the values of the chaining variables. */
+ ldm RSTATE, {_a-_e};
+
+ vld1.32 {qK3-qK4}, [RT3]; /* Load K3,K4 */
+
+#undef curK
+#define curK qK1
+ /* Precalc 0-15. */
+ W_PRECALC_00_15();
+
+.Loop:
+ /* Transform 0-15 + Precalc 16-31. */
+ _R( _a, _b, _c, _d, _e, F1, 0,
+ WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 16,
+ W4, W5, W6, W7, W0, _, _, _ );
+ _R( _e, _a, _b, _c, _d, F1, 1,
+ WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 16,
+ W4, W5, W6, W7, W0, _, _, _ );
+ _R( _d, _e, _a, _b, _c, F1, 2,
+ WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 16,
+ W4, W5, W6, W7, W0, _, _, _ );
+ _R( _c, _d, _e, _a, _b, F1, 3,
+ WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,16,
+ W4, W5, W6, W7, W0, _, _, _ );
+
+#undef curK
+#define curK qK2
+ _R( _b, _c, _d, _e, _a, F1, 4,
+ WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 20,
+ W3, W4, W5, W6, W7, _, _, _ );
+ _R( _a, _b, _c, _d, _e, F1, 5,
+ WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 20,
+ W3, W4, W5, W6, W7, _, _, _ );
+ _R( _e, _a, _b, _c, _d, F1, 6,
+ WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 20,
+ W3, W4, W5, W6, W7, _, _, _ );
+ _R( _d, _e, _a, _b, _c, F1, 7,
+ WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,20,
+ W3, W4, W5, W6, W7, _, _, _ );
+
+ _R( _c, _d, _e, _a, _b, F1, 8,
+ WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 24,
+ W2, W3, W4, W5, W6, _, _, _ );
+ _R( _b, _c, _d, _e, _a, F1, 9,
+ WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 24,
+ W2, W3, W4, W5, W6, _, _, _ );
+ _R( _a, _b, _c, _d, _e, F1, 10,
+ WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 24,
+ W2, W3, W4, W5, W6, _, _, _ );
+ _R( _e, _a, _b, _c, _d, F1, 11,
+ WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,24,
+ W2, W3, W4, W5, W6, _, _, _ );
+
+ _R( _d, _e, _a, _b, _c, F1, 12,
+ WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 28,
+ W1, W2, W3, W4, W5, _, _, _ );
+ _R( _c, _d, _e, _a, _b, F1, 13,
+ WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 28,
+ W1, W2, W3, W4, W5, _, _, _ );
+ _R( _b, _c, _d, _e, _a, F1, 14,
+ WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 28,
+ W1, W2, W3, W4, W5, _, _, _ );
+ _R( _a, _b, _c, _d, _e, F1, 15,
+ WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,28,
+ W1, W2, W3, W4, W5, _, _, _ );
+
+ /* Transform 16-63 + Precalc 32-79. */
+ _R( _e, _a, _b, _c, _d, F1, 16,
+ WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 32,
+ W0, W1, W2, W3, W4, W5, W6, W7);
+ _R( _d, _e, _a, _b, _c, F1, 17,
+ WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 32,
+ W0, W1, W2, W3, W4, W5, W6, W7);
+ _R( _c, _d, _e, _a, _b, F1, 18,
+ WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 32,
+ W0, W1, W2, W3, W4, W5, W6, W7);
+ _R( _b, _c, _d, _e, _a, F1, 19,
+ WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 32,
+ W0, W1, W2, W3, W4, W5, W6, W7);
+
+ _R( _a, _b, _c, _d, _e, F2, 20,
+ WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 36,
+ W7, W0, W1, W2, W3, W4, W5, W6);
+ _R( _e, _a, _b, _c, _d, F2, 21,
+ WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 36,
+ W7, W0, W1, W2, W3, W4, W5, W6);
+ _R( _d, _e, _a, _b, _c, F2, 22,
+ WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 36,
+ W7, W0, W1, W2, W3, W4, W5, W6);
+ _R( _c, _d, _e, _a, _b, F2, 23,
+ WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 36,
+ W7, W0, W1, W2, W3, W4, W5, W6);
+
+#undef curK
+#define curK qK3
+ _R( _b, _c, _d, _e, _a, F2, 24,
+ WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 40,
+ W6, W7, W0, W1, W2, W3, W4, W5);
+ _R( _a, _b, _c, _d, _e, F2, 25,
+ WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 40,
+ W6, W7, W0, W1, W2, W3, W4, W5);
+ _R( _e, _a, _b, _c, _d, F2, 26,
+ WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 40,
+ W6, W7, W0, W1, W2, W3, W4, W5);
+ _R( _d, _e, _a, _b, _c, F2, 27,
+ WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 40,
+ W6, W7, W0, W1, W2, W3, W4, W5);
+
+ _R( _c, _d, _e, _a, _b, F2, 28,
+ WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 44,
+ W5, W6, W7, W0, W1, W2, W3, W4);
+ _R( _b, _c, _d, _e, _a, F2, 29,
+ WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 44,
+ W5, W6, W7, W0, W1, W2, W3, W4);
+ _R( _a, _b, _c, _d, _e, F2, 30,
+ WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 44,
+ W5, W6, W7, W0, W1, W2, W3, W4);
+ _R( _e, _a, _b, _c, _d, F2, 31,
+ WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 44,
+ W5, W6, W7, W0, W1, W2, W3, W4);
+
+ _R( _d, _e, _a, _b, _c, F2, 32,
+ WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 48,
+ W4, W5, W6, W7, W0, W1, W2, W3);
+ _R( _c, _d, _e, _a, _b, F2, 33,
+ WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 48,
+ W4, W5, W6, W7, W0, W1, W2, W3);
+ _R( _b, _c, _d, _e, _a, F2, 34,
+ WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 48,
+ W4, W5, W6, W7, W0, W1, W2, W3);
+ _R( _a, _b, _c, _d, _e, F2, 35,
+ WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 48,
+ W4, W5, W6, W7, W0, W1, W2, W3);
+
+ _R( _e, _a, _b, _c, _d, F2, 36,
+ WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 52,
+ W3, W4, W5, W6, W7, W0, W1, W2);
+ _R( _d, _e, _a, _b, _c, F2, 37,
+ WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 52,
+ W3, W4, W5, W6, W7, W0, W1, W2);
+ _R( _c, _d, _e, _a, _b, F2, 38,
+ WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 52,
+ W3, W4, W5, W6, W7, W0, W1, W2);
+ _R( _b, _c, _d, _e, _a, F2, 39,
+ WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 52,
+ W3, W4, W5, W6, W7, W0, W1, W2);
+
+ _R( _a, _b, _c, _d, _e, F3, 40,
+ WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 56,
+ W2, W3, W4, W5, W6, W7, W0, W1);
+ _R( _e, _a, _b, _c, _d, F3, 41,
+ WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 56,
+ W2, W3, W4, W5, W6, W7, W0, W1);
+ _R( _d, _e, _a, _b, _c, F3, 42,
+ WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 56,
+ W2, W3, W4, W5, W6, W7, W0, W1);
+ _R( _c, _d, _e, _a, _b, F3, 43,
+ WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 56,
+ W2, W3, W4, W5, W6, W7, W0, W1);
+
+#undef curK
+#define curK qK4
+ _R( _b, _c, _d, _e, _a, F3, 44,
+ WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 60,
+ W1, W2, W3, W4, W5, W6, W7, W0);
+ _R( _a, _b, _c, _d, _e, F3, 45,
+ WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 60,
+ W1, W2, W3, W4, W5, W6, W7, W0);
+ _R( _e, _a, _b, _c, _d, F3, 46,
+ WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 60,
+ W1, W2, W3, W4, W5, W6, W7, W0);
+ _R( _d, _e, _a, _b, _c, F3, 47,
+ WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 60,
+ W1, W2, W3, W4, W5, W6, W7, W0);
+
+ _R( _c, _d, _e, _a, _b, F3, 48,
+ WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 64,
+ W0, W1, W2, W3, W4, W5, W6, W7);
+ _R( _b, _c, _d, _e, _a, F3, 49,
+ WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 64,
+ W0, W1, W2, W3, W4, W5, W6, W7);
+ _R( _a, _b, _c, _d, _e, F3, 50,
+ WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 64,
+ W0, W1, W2, W3, W4, W5, W6, W7);
+ _R( _e, _a, _b, _c, _d, F3, 51,
+ WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 64,
+ W0, W1, W2, W3, W4, W5, W6, W7);
+
+ _R( _d, _e, _a, _b, _c, F3, 52,
+ WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 68,
+ W7, W0, W1, W2, W3, W4, W5, W6);
+ _R( _c, _d, _e, _a, _b, F3, 53,
+ WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 68,
+ W7, W0, W1, W2, W3, W4, W5, W6);
+ _R( _b, _c, _d, _e, _a, F3, 54,
+ WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 68,
+ W7, W0, W1, W2, W3, W4, W5, W6);
+ _R( _a, _b, _c, _d, _e, F3, 55,
+ WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 68,
+ W7, W0, W1, W2, W3, W4, W5, W6);
+
+ _R( _e, _a, _b, _c, _d, F3, 56,
+ WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 72,
+ W6, W7, W0, W1, W2, W3, W4, W5);
+ _R( _d, _e, _a, _b, _c, F3, 57,
+ WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 72,
+ W6, W7, W0, W1, W2, W3, W4, W5);
+ _R( _c, _d, _e, _a, _b, F3, 58,
+ WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 72,
+ W6, W7, W0, W1, W2, W3, W4, W5);
+ _R( _b, _c, _d, _e, _a, F3, 59,
+ WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 72,
+ W6, W7, W0, W1, W2, W3, W4, W5);
+
+ subs RNBLKS, #1;
+
+ _R( _a, _b, _c, _d, _e, F4, 60,
+ WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 76,
+ W5, W6, W7, W0, W1, W2, W3, W4);
+ _R( _e, _a, _b, _c, _d, F4, 61,
+ WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 76,
+ W5, W6, W7, W0, W1, W2, W3, W4);
+ _R( _d, _e, _a, _b, _c, F4, 62,
+ WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 76,
+ W5, W6, W7, W0, W1, W2, W3, W4);
+ _R( _c, _d, _e, _a, _b, F4, 63,
+ WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 76,
+ W5, W6, W7, W0, W1, W2, W3, W4);
+
+ beq .Lend;
+
+ /* Transform 64-79 + Precalc 0-15 of next block. */
+#undef curK
+#define curK qK1
+ _R( _b, _c, _d, _e, _a, F4, 64,
+ WPRECALC_00_15_0, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _a, _b, _c, _d, _e, F4, 65,
+ WPRECALC_00_15_1, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _e, _a, _b, _c, _d, F4, 66,
+ WPRECALC_00_15_2, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _d, _e, _a, _b, _c, F4, 67,
+ WPRECALC_00_15_3, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+
+ _R( _c, _d, _e, _a, _b, F4, 68,
+ dummy, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _b, _c, _d, _e, _a, F4, 69,
+ dummy, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _a, _b, _c, _d, _e, F4, 70,
+ WPRECALC_00_15_4, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _e, _a, _b, _c, _d, F4, 71,
+ WPRECALC_00_15_5, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+
+ _R( _d, _e, _a, _b, _c, F4, 72,
+ dummy, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _c, _d, _e, _a, _b, F4, 73,
+ dummy, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _b, _c, _d, _e, _a, F4, 74,
+ WPRECALC_00_15_6, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _a, _b, _c, _d, _e, F4, 75,
+ WPRECALC_00_15_7, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+
+ _R( _e, _a, _b, _c, _d, F4, 76,
+ WPRECALC_00_15_8, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _d, _e, _a, _b, _c, F4, 77,
+ WPRECALC_00_15_9, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _c, _d, _e, _a, _b, F4, 78,
+ WPRECALC_00_15_10, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _b, _c, _d, _e, _a, F4, 79,
+ WPRECALC_00_15_11, dummy, WPRECALC_00_15_12, _, _, _, _, _, _, _, _, _ );
+
+ /* Update the chaining variables. */
+ ldm RSTATE, {RT0-RT3};
+ add _a, RT0;
+ ldr RT0, [RSTATE, #state_h4];
+ add _b, RT1;
+ add _c, RT2;
+ add _d, RT3;
+ add _e, RT0;
+ stm RSTATE, {_a-_e};
+
+ b .Loop;
+
+.Lend:
+ /* Transform 64-79 */
+ R( _b, _c, _d, _e, _a, F4, 64 );
+ R( _a, _b, _c, _d, _e, F4, 65 );
+ R( _e, _a, _b, _c, _d, F4, 66 );
+ R( _d, _e, _a, _b, _c, F4, 67 );
+ R( _c, _d, _e, _a, _b, F4, 68 );
+ R( _b, _c, _d, _e, _a, F4, 69 );
+ R( _a, _b, _c, _d, _e, F4, 70 );
+ R( _e, _a, _b, _c, _d, F4, 71 );
+ R( _d, _e, _a, _b, _c, F4, 72 );
+ R( _c, _d, _e, _a, _b, F4, 73 );
+ R( _b, _c, _d, _e, _a, F4, 74 );
+ R( _a, _b, _c, _d, _e, F4, 75 );
+ R( _e, _a, _b, _c, _d, F4, 76 );
+ R( _d, _e, _a, _b, _c, F4, 77 );
+ R( _c, _d, _e, _a, _b, F4, 78 );
+ R( _b, _c, _d, _e, _a, F4, 79 );
+
+ mov sp, ROLDSTACK;
+
+ /* Update the chaining variables. */
+ ldm RSTATE, {RT0-RT3};
+ add _a, RT0;
+ ldr RT0, [RSTATE, #state_h4];
+ add _b, RT1;
+ add _c, RT2;
+ add _d, RT3;
+ /*vpop {q4-q7};*/
+ add _e, RT0;
+ stm RSTATE, {_a-_e};
+
+ pop {r4-r12, pc};
+
+.Ldo_nothing:
+ bx lr
+ENDPROC(sha1_transform_neon)
diff --git a/arch/arm/crypto/sha1-ce-core.S b/arch/arm/crypto/sha1-ce-core.S
new file mode 100644
index 000000000..b623f51cc
--- /dev/null
+++ b/arch/arm/crypto/sha1-ce-core.S
@@ -0,0 +1,125 @@
+/*
+ * sha1-ce-core.S - SHA-1 secure hash using ARMv8 Crypto Extensions
+ *
+ * Copyright (C) 2015 Linaro Ltd.
+ * Author: Ard Biesheuvel <ard.biesheuvel@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 <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+ .fpu crypto-neon-fp-armv8
+
+ k0 .req q0
+ k1 .req q1
+ k2 .req q2
+ k3 .req q3
+
+ ta0 .req q4
+ ta1 .req q5
+ tb0 .req q5
+ tb1 .req q4
+
+ dga .req q6
+ dgb .req q7
+ dgbs .req s28
+
+ dg0 .req q12
+ dg1a0 .req q13
+ dg1a1 .req q14
+ dg1b0 .req q14
+ dg1b1 .req q13
+
+ .macro add_only, op, ev, rc, s0, dg1
+ .ifnb \s0
+ vadd.u32 tb\ev, q\s0, \rc
+ .endif
+ sha1h.32 dg1b\ev, dg0
+ .ifb \dg1
+ sha1\op\().32 dg0, dg1a\ev, ta\ev
+ .else
+ sha1\op\().32 dg0, \dg1, ta\ev
+ .endif
+ .endm
+
+ .macro add_update, op, ev, rc, s0, s1, s2, s3, dg1
+ sha1su0.32 q\s0, q\s1, q\s2
+ add_only \op, \ev, \rc, \s1, \dg1
+ sha1su1.32 q\s0, q\s3
+ .endm
+
+ .align 6
+.Lsha1_rcon:
+ .word 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999
+ .word 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1
+ .word 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc
+ .word 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6
+
+ /*
+ * void sha1_ce_transform(struct sha1_state *sst, u8 const *src,
+ * int blocks);
+ */
+ENTRY(sha1_ce_transform)
+ /* load round constants */
+ adr ip, .Lsha1_rcon
+ vld1.32 {k0-k1}, [ip, :128]!
+ vld1.32 {k2-k3}, [ip, :128]
+
+ /* load state */
+ vld1.32 {dga}, [r0]
+ vldr dgbs, [r0, #16]
+
+ /* load input */
+0: vld1.32 {q8-q9}, [r1]!
+ vld1.32 {q10-q11}, [r1]!
+ subs r2, r2, #1
+
+#ifndef CONFIG_CPU_BIG_ENDIAN
+ vrev32.8 q8, q8
+ vrev32.8 q9, q9
+ vrev32.8 q10, q10
+ vrev32.8 q11, q11
+#endif
+
+ vadd.u32 ta0, q8, k0
+ vmov dg0, dga
+
+ add_update c, 0, k0, 8, 9, 10, 11, dgb
+ add_update c, 1, k0, 9, 10, 11, 8
+ add_update c, 0, k0, 10, 11, 8, 9
+ add_update c, 1, k0, 11, 8, 9, 10
+ add_update c, 0, k1, 8, 9, 10, 11
+
+ add_update p, 1, k1, 9, 10, 11, 8
+ add_update p, 0, k1, 10, 11, 8, 9
+ add_update p, 1, k1, 11, 8, 9, 10
+ add_update p, 0, k1, 8, 9, 10, 11
+ add_update p, 1, k2, 9, 10, 11, 8
+
+ add_update m, 0, k2, 10, 11, 8, 9
+ add_update m, 1, k2, 11, 8, 9, 10
+ add_update m, 0, k2, 8, 9, 10, 11
+ add_update m, 1, k2, 9, 10, 11, 8
+ add_update m, 0, k3, 10, 11, 8, 9
+
+ add_update p, 1, k3, 11, 8, 9, 10
+ add_only p, 0, k3, 9
+ add_only p, 1, k3, 10
+ add_only p, 0, k3, 11
+ add_only p, 1
+
+ /* update state */
+ vadd.u32 dga, dga, dg0
+ vadd.u32 dgb, dgb, dg1a0
+ bne 0b
+
+ /* store new state */
+ vst1.32 {dga}, [r0]
+ vstr dgbs, [r0, #16]
+ bx lr
+ENDPROC(sha1_ce_transform)
diff --git a/arch/arm/crypto/sha1-ce-glue.c b/arch/arm/crypto/sha1-ce-glue.c
new file mode 100644
index 000000000..80bc2fcd2
--- /dev/null
+++ b/arch/arm/crypto/sha1-ce-glue.c
@@ -0,0 +1,96 @@
+/*
+ * sha1-ce-glue.c - SHA-1 secure hash using ARMv8 Crypto Extensions
+ *
+ * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@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 <crypto/internal/hash.h>
+#include <crypto/sha.h>
+#include <crypto/sha1_base.h>
+#include <linux/crypto.h>
+#include <linux/module.h>
+
+#include <asm/hwcap.h>
+#include <asm/neon.h>
+#include <asm/simd.h>
+
+#include "sha1.h"
+
+MODULE_DESCRIPTION("SHA1 secure hash using ARMv8 Crypto Extensions");
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_LICENSE("GPL v2");
+
+asmlinkage void sha1_ce_transform(struct sha1_state *sst, u8 const *src,
+ int blocks);
+
+static int sha1_ce_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ struct sha1_state *sctx = shash_desc_ctx(desc);
+
+ if (!may_use_simd() ||
+ (sctx->count % SHA1_BLOCK_SIZE) + len < SHA1_BLOCK_SIZE)
+ return sha1_update_arm(desc, data, len);
+
+ kernel_neon_begin();
+ sha1_base_do_update(desc, data, len, sha1_ce_transform);
+ kernel_neon_end();
+
+ return 0;
+}
+
+static int sha1_ce_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ if (!may_use_simd())
+ return sha1_finup_arm(desc, data, len, out);
+
+ kernel_neon_begin();
+ if (len)
+ sha1_base_do_update(desc, data, len, sha1_ce_transform);
+ sha1_base_do_finalize(desc, sha1_ce_transform);
+ kernel_neon_end();
+
+ return sha1_base_finish(desc, out);
+}
+
+static int sha1_ce_final(struct shash_desc *desc, u8 *out)
+{
+ return sha1_ce_finup(desc, NULL, 0, out);
+}
+
+static struct shash_alg alg = {
+ .init = sha1_base_init,
+ .update = sha1_ce_update,
+ .final = sha1_ce_final,
+ .finup = sha1_ce_finup,
+ .descsize = sizeof(struct sha1_state),
+ .digestsize = SHA1_DIGEST_SIZE,
+ .base = {
+ .cra_name = "sha1",
+ .cra_driver_name = "sha1-ce",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA1_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+};
+
+static int __init sha1_ce_mod_init(void)
+{
+ if (!(elf_hwcap2 & HWCAP2_SHA1))
+ return -ENODEV;
+ return crypto_register_shash(&alg);
+}
+
+static void __exit sha1_ce_mod_fini(void)
+{
+ crypto_unregister_shash(&alg);
+}
+
+module_init(sha1_ce_mod_init);
+module_exit(sha1_ce_mod_fini);
diff --git a/arch/arm/crypto/sha1.h b/arch/arm/crypto/sha1.h
new file mode 100644
index 000000000..ffd8bd08b
--- /dev/null
+++ b/arch/arm/crypto/sha1.h
@@ -0,0 +1,13 @@
+#ifndef ASM_ARM_CRYPTO_SHA1_H
+#define ASM_ARM_CRYPTO_SHA1_H
+
+#include <linux/crypto.h>
+#include <crypto/sha.h>
+
+extern int sha1_update_arm(struct shash_desc *desc, const u8 *data,
+ unsigned int len);
+
+extern int sha1_finup_arm(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out);
+
+#endif
diff --git a/arch/arm/crypto/sha1_glue.c b/arch/arm/crypto/sha1_glue.c
new file mode 100644
index 000000000..6fc73bf87
--- /dev/null
+++ b/arch/arm/crypto/sha1_glue.c
@@ -0,0 +1,95 @@
+/*
+ * Cryptographic API.
+ * Glue code for the SHA1 Secure Hash Algorithm assembler implementation
+ *
+ * This file is based on sha1_generic.c and sha1_ssse3_glue.c
+ *
+ * Copyright (c) Alan Smithee.
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
+ * Copyright (c) Mathias Krause <minipli@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 <crypto/internal/hash.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/cryptohash.h>
+#include <linux/types.h>
+#include <crypto/sha.h>
+#include <crypto/sha1_base.h>
+#include <asm/byteorder.h>
+
+#include "sha1.h"
+
+asmlinkage void sha1_block_data_order(u32 *digest,
+ const unsigned char *data, unsigned int rounds);
+
+int sha1_update_arm(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ /* make sure casting to sha1_block_fn() is safe */
+ BUILD_BUG_ON(offsetof(struct sha1_state, state) != 0);
+
+ return sha1_base_do_update(desc, data, len,
+ (sha1_block_fn *)sha1_block_data_order);
+}
+EXPORT_SYMBOL_GPL(sha1_update_arm);
+
+static int sha1_final(struct shash_desc *desc, u8 *out)
+{
+ sha1_base_do_finalize(desc, (sha1_block_fn *)sha1_block_data_order);
+ return sha1_base_finish(desc, out);
+}
+
+int sha1_finup_arm(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ sha1_base_do_update(desc, data, len,
+ (sha1_block_fn *)sha1_block_data_order);
+ return sha1_final(desc, out);
+}
+EXPORT_SYMBOL_GPL(sha1_finup_arm);
+
+static struct shash_alg alg = {
+ .digestsize = SHA1_DIGEST_SIZE,
+ .init = sha1_base_init,
+ .update = sha1_update_arm,
+ .final = sha1_final,
+ .finup = sha1_finup_arm,
+ .descsize = sizeof(struct sha1_state),
+ .base = {
+ .cra_name = "sha1",
+ .cra_driver_name= "sha1-asm",
+ .cra_priority = 150,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA1_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+};
+
+
+static int __init sha1_mod_init(void)
+{
+ return crypto_register_shash(&alg);
+}
+
+
+static void __exit sha1_mod_fini(void)
+{
+ crypto_unregister_shash(&alg);
+}
+
+
+module_init(sha1_mod_init);
+module_exit(sha1_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm (ARM)");
+MODULE_ALIAS_CRYPTO("sha1");
+MODULE_AUTHOR("David McCullough <ucdevel@gmail.com>");
diff --git a/arch/arm/crypto/sha1_neon_glue.c b/arch/arm/crypto/sha1_neon_glue.c
new file mode 100644
index 000000000..4e22f122f
--- /dev/null
+++ b/arch/arm/crypto/sha1_neon_glue.c
@@ -0,0 +1,110 @@
+/*
+ * Glue code for the SHA1 Secure Hash Algorithm assembler implementation using
+ * ARM NEON instructions.
+ *
+ * Copyright © 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is based on sha1_generic.c and sha1_ssse3_glue.c:
+ * Copyright (c) Alan Smithee.
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
+ * Copyright (c) Mathias Krause <minipli@googlemail.com>
+ * Copyright (c) Chandramouli Narayanan <mouli@linux.intel.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 <crypto/internal/hash.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/cryptohash.h>
+#include <linux/types.h>
+#include <crypto/sha.h>
+#include <crypto/sha1_base.h>
+#include <asm/neon.h>
+#include <asm/simd.h>
+
+#include "sha1.h"
+
+asmlinkage void sha1_transform_neon(void *state_h, const char *data,
+ unsigned int rounds);
+
+static int sha1_neon_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ struct sha1_state *sctx = shash_desc_ctx(desc);
+
+ if (!may_use_simd() ||
+ (sctx->count % SHA1_BLOCK_SIZE) + len < SHA1_BLOCK_SIZE)
+ return sha1_update_arm(desc, data, len);
+
+ kernel_neon_begin();
+ sha1_base_do_update(desc, data, len,
+ (sha1_block_fn *)sha1_transform_neon);
+ kernel_neon_end();
+
+ return 0;
+}
+
+static int sha1_neon_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ if (!may_use_simd())
+ return sha1_finup_arm(desc, data, len, out);
+
+ kernel_neon_begin();
+ if (len)
+ sha1_base_do_update(desc, data, len,
+ (sha1_block_fn *)sha1_transform_neon);
+ sha1_base_do_finalize(desc, (sha1_block_fn *)sha1_transform_neon);
+ kernel_neon_end();
+
+ return sha1_base_finish(desc, out);
+}
+
+static int sha1_neon_final(struct shash_desc *desc, u8 *out)
+{
+ return sha1_neon_finup(desc, NULL, 0, out);
+}
+
+static struct shash_alg alg = {
+ .digestsize = SHA1_DIGEST_SIZE,
+ .init = sha1_base_init,
+ .update = sha1_neon_update,
+ .final = sha1_neon_final,
+ .finup = sha1_neon_finup,
+ .descsize = sizeof(struct sha1_state),
+ .base = {
+ .cra_name = "sha1",
+ .cra_driver_name = "sha1-neon",
+ .cra_priority = 250,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA1_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+};
+
+static int __init sha1_neon_mod_init(void)
+{
+ if (!cpu_has_neon())
+ return -ENODEV;
+
+ return crypto_register_shash(&alg);
+}
+
+static void __exit sha1_neon_mod_fini(void)
+{
+ crypto_unregister_shash(&alg);
+}
+
+module_init(sha1_neon_mod_init);
+module_exit(sha1_neon_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, NEON accelerated");
+MODULE_ALIAS_CRYPTO("sha1");
diff --git a/arch/arm/crypto/sha2-ce-core.S b/arch/arm/crypto/sha2-ce-core.S
new file mode 100644
index 000000000..87ec11a5f
--- /dev/null
+++ b/arch/arm/crypto/sha2-ce-core.S
@@ -0,0 +1,125 @@
+/*
+ * sha2-ce-core.S - SHA-224/256 secure hash using ARMv8 Crypto Extensions
+ *
+ * Copyright (C) 2015 Linaro Ltd.
+ * Author: Ard Biesheuvel <ard.biesheuvel@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 <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+ .fpu crypto-neon-fp-armv8
+
+ k0 .req q7
+ k1 .req q8
+ rk .req r3
+
+ ta0 .req q9
+ ta1 .req q10
+ tb0 .req q10
+ tb1 .req q9
+
+ dga .req q11
+ dgb .req q12
+
+ dg0 .req q13
+ dg1 .req q14
+ dg2 .req q15
+
+ .macro add_only, ev, s0
+ vmov dg2, dg0
+ .ifnb \s0
+ vld1.32 {k\ev}, [rk, :128]!
+ .endif
+ sha256h.32 dg0, dg1, tb\ev
+ sha256h2.32 dg1, dg2, tb\ev
+ .ifnb \s0
+ vadd.u32 ta\ev, q\s0, k\ev
+ .endif
+ .endm
+
+ .macro add_update, ev, s0, s1, s2, s3
+ sha256su0.32 q\s0, q\s1
+ add_only \ev, \s1
+ sha256su1.32 q\s0, q\s2, q\s3
+ .endm
+
+ .align 6
+.Lsha256_rcon:
+ .word 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
+ .word 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
+ .word 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
+ .word 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
+ .word 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
+ .word 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
+ .word 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
+ .word 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
+ .word 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
+ .word 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
+ .word 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
+ .word 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
+ .word 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
+ .word 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
+ .word 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
+ .word 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+
+ /*
+ * void sha2_ce_transform(struct sha256_state *sst, u8 const *src,
+ int blocks);
+ */
+ENTRY(sha2_ce_transform)
+ /* load state */
+ vld1.32 {dga-dgb}, [r0]
+
+ /* load input */
+0: vld1.32 {q0-q1}, [r1]!
+ vld1.32 {q2-q3}, [r1]!
+ subs r2, r2, #1
+
+#ifndef CONFIG_CPU_BIG_ENDIAN
+ vrev32.8 q0, q0
+ vrev32.8 q1, q1
+ vrev32.8 q2, q2
+ vrev32.8 q3, q3
+#endif
+
+ /* load first round constant */
+ adr rk, .Lsha256_rcon
+ vld1.32 {k0}, [rk, :128]!
+
+ vadd.u32 ta0, q0, k0
+ vmov dg0, dga
+ vmov dg1, dgb
+
+ add_update 1, 0, 1, 2, 3
+ add_update 0, 1, 2, 3, 0
+ add_update 1, 2, 3, 0, 1
+ add_update 0, 3, 0, 1, 2
+ add_update 1, 0, 1, 2, 3
+ add_update 0, 1, 2, 3, 0
+ add_update 1, 2, 3, 0, 1
+ add_update 0, 3, 0, 1, 2
+ add_update 1, 0, 1, 2, 3
+ add_update 0, 1, 2, 3, 0
+ add_update 1, 2, 3, 0, 1
+ add_update 0, 3, 0, 1, 2
+
+ add_only 1, 1
+ add_only 0, 2
+ add_only 1, 3
+ add_only 0
+
+ /* update state */
+ vadd.u32 dga, dga, dg0
+ vadd.u32 dgb, dgb, dg1
+ bne 0b
+
+ /* store new state */
+ vst1.32 {dga-dgb}, [r0]
+ bx lr
+ENDPROC(sha2_ce_transform)
diff --git a/arch/arm/crypto/sha2-ce-glue.c b/arch/arm/crypto/sha2-ce-glue.c
new file mode 100644
index 000000000..0755b2d65
--- /dev/null
+++ b/arch/arm/crypto/sha2-ce-glue.c
@@ -0,0 +1,114 @@
+/*
+ * sha2-ce-glue.c - SHA-224/SHA-256 using ARMv8 Crypto Extensions
+ *
+ * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@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 <crypto/internal/hash.h>
+#include <crypto/sha.h>
+#include <crypto/sha256_base.h>
+#include <linux/crypto.h>
+#include <linux/module.h>
+
+#include <asm/hwcap.h>
+#include <asm/simd.h>
+#include <asm/neon.h>
+#include <asm/unaligned.h>
+
+#include "sha256_glue.h"
+
+MODULE_DESCRIPTION("SHA-224/SHA-256 secure hash using ARMv8 Crypto Extensions");
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_LICENSE("GPL v2");
+
+asmlinkage void sha2_ce_transform(struct sha256_state *sst, u8 const *src,
+ int blocks);
+
+static int sha2_ce_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ struct sha256_state *sctx = shash_desc_ctx(desc);
+
+ if (!may_use_simd() ||
+ (sctx->count % SHA256_BLOCK_SIZE) + len < SHA256_BLOCK_SIZE)
+ return crypto_sha256_arm_update(desc, data, len);
+
+ kernel_neon_begin();
+ sha256_base_do_update(desc, data, len,
+ (sha256_block_fn *)sha2_ce_transform);
+ kernel_neon_end();
+
+ return 0;
+}
+
+static int sha2_ce_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ if (!may_use_simd())
+ return crypto_sha256_arm_finup(desc, data, len, out);
+
+ kernel_neon_begin();
+ if (len)
+ sha256_base_do_update(desc, data, len,
+ (sha256_block_fn *)sha2_ce_transform);
+ sha256_base_do_finalize(desc, (sha256_block_fn *)sha2_ce_transform);
+ kernel_neon_end();
+
+ return sha256_base_finish(desc, out);
+}
+
+static int sha2_ce_final(struct shash_desc *desc, u8 *out)
+{
+ return sha2_ce_finup(desc, NULL, 0, out);
+}
+
+static struct shash_alg algs[] = { {
+ .init = sha224_base_init,
+ .update = sha2_ce_update,
+ .final = sha2_ce_final,
+ .finup = sha2_ce_finup,
+ .descsize = sizeof(struct sha256_state),
+ .digestsize = SHA224_DIGEST_SIZE,
+ .base = {
+ .cra_name = "sha224",
+ .cra_driver_name = "sha224-ce",
+ .cra_priority = 300,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA256_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+}, {
+ .init = sha256_base_init,
+ .update = sha2_ce_update,
+ .final = sha2_ce_final,
+ .finup = sha2_ce_finup,
+ .descsize = sizeof(struct sha256_state),
+ .digestsize = SHA256_DIGEST_SIZE,
+ .base = {
+ .cra_name = "sha256",
+ .cra_driver_name = "sha256-ce",
+ .cra_priority = 300,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA256_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+} };
+
+static int __init sha2_ce_mod_init(void)
+{
+ if (!(elf_hwcap2 & HWCAP2_SHA2))
+ return -ENODEV;
+ return crypto_register_shashes(algs, ARRAY_SIZE(algs));
+}
+
+static void __exit sha2_ce_mod_fini(void)
+{
+ crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
+}
+
+module_init(sha2_ce_mod_init);
+module_exit(sha2_ce_mod_fini);
diff --git a/arch/arm/crypto/sha256-armv4.pl b/arch/arm/crypto/sha256-armv4.pl
new file mode 100644
index 000000000..fac0533ea
--- /dev/null
+++ b/arch/arm/crypto/sha256-armv4.pl
@@ -0,0 +1,716 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+#
+# Permission to use under GPL terms is granted.
+# ====================================================================
+
+# SHA256 block procedure for ARMv4. May 2007.
+
+# Performance is ~2x better than gcc 3.4 generated code and in "abso-
+# lute" terms is ~2250 cycles per 64-byte block or ~35 cycles per
+# byte [on single-issue Xscale PXA250 core].
+
+# July 2010.
+#
+# Rescheduling for dual-issue pipeline resulted in 22% improvement on
+# Cortex A8 core and ~20 cycles per processed byte.
+
+# February 2011.
+#
+# Profiler-assisted and platform-specific optimization resulted in 16%
+# improvement on Cortex A8 core and ~15.4 cycles per processed byte.
+
+# September 2013.
+#
+# Add NEON implementation. On Cortex A8 it was measured to process one
+# byte in 12.5 cycles or 23% faster than integer-only code. Snapdragon
+# S4 does it in 12.5 cycles too, but it's 50% faster than integer-only
+# code (meaning that latter performs sub-optimally, nothing was done
+# about it).
+
+# May 2014.
+#
+# Add ARMv8 code path performing at 2.0 cpb on Apple A7.
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+$ctx="r0"; $t0="r0";
+$inp="r1"; $t4="r1";
+$len="r2"; $t1="r2";
+$T1="r3"; $t3="r3";
+$A="r4";
+$B="r5";
+$C="r6";
+$D="r7";
+$E="r8";
+$F="r9";
+$G="r10";
+$H="r11";
+@V=($A,$B,$C,$D,$E,$F,$G,$H);
+$t2="r12";
+$Ktbl="r14";
+
+@Sigma0=( 2,13,22);
+@Sigma1=( 6,11,25);
+@sigma0=( 7,18, 3);
+@sigma1=(17,19,10);
+
+sub BODY_00_15 {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
+
+$code.=<<___ if ($i<16);
+#if __ARM_ARCH__>=7
+ @ ldr $t1,[$inp],#4 @ $i
+# if $i==15
+ str $inp,[sp,#17*4] @ make room for $t4
+# endif
+ eor $t0,$e,$e,ror#`$Sigma1[1]-$Sigma1[0]`
+ add $a,$a,$t2 @ h+=Maj(a,b,c) from the past
+ eor $t0,$t0,$e,ror#`$Sigma1[2]-$Sigma1[0]` @ Sigma1(e)
+# ifndef __ARMEB__
+ rev $t1,$t1
+# endif
+#else
+ @ ldrb $t1,[$inp,#3] @ $i
+ add $a,$a,$t2 @ h+=Maj(a,b,c) from the past
+ ldrb $t2,[$inp,#2]
+ ldrb $t0,[$inp,#1]
+ orr $t1,$t1,$t2,lsl#8
+ ldrb $t2,[$inp],#4
+ orr $t1,$t1,$t0,lsl#16
+# if $i==15
+ str $inp,[sp,#17*4] @ make room for $t4
+# endif
+ eor $t0,$e,$e,ror#`$Sigma1[1]-$Sigma1[0]`
+ orr $t1,$t1,$t2,lsl#24
+ eor $t0,$t0,$e,ror#`$Sigma1[2]-$Sigma1[0]` @ Sigma1(e)
+#endif
+___
+$code.=<<___;
+ ldr $t2,[$Ktbl],#4 @ *K256++
+ add $h,$h,$t1 @ h+=X[i]
+ str $t1,[sp,#`$i%16`*4]
+ eor $t1,$f,$g
+ add $h,$h,$t0,ror#$Sigma1[0] @ h+=Sigma1(e)
+ and $t1,$t1,$e
+ add $h,$h,$t2 @ h+=K256[i]
+ eor $t1,$t1,$g @ Ch(e,f,g)
+ eor $t0,$a,$a,ror#`$Sigma0[1]-$Sigma0[0]`
+ add $h,$h,$t1 @ h+=Ch(e,f,g)
+#if $i==31
+ and $t2,$t2,#0xff
+ cmp $t2,#0xf2 @ done?
+#endif
+#if $i<15
+# if __ARM_ARCH__>=7
+ ldr $t1,[$inp],#4 @ prefetch
+# else
+ ldrb $t1,[$inp,#3]
+# endif
+ eor $t2,$a,$b @ a^b, b^c in next round
+#else
+ ldr $t1,[sp,#`($i+2)%16`*4] @ from future BODY_16_xx
+ eor $t2,$a,$b @ a^b, b^c in next round
+ ldr $t4,[sp,#`($i+15)%16`*4] @ from future BODY_16_xx
+#endif
+ eor $t0,$t0,$a,ror#`$Sigma0[2]-$Sigma0[0]` @ Sigma0(a)
+ and $t3,$t3,$t2 @ (b^c)&=(a^b)
+ add $d,$d,$h @ d+=h
+ eor $t3,$t3,$b @ Maj(a,b,c)
+ add $h,$h,$t0,ror#$Sigma0[0] @ h+=Sigma0(a)
+ @ add $h,$h,$t3 @ h+=Maj(a,b,c)
+___
+ ($t2,$t3)=($t3,$t2);
+}
+
+sub BODY_16_XX {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
+
+$code.=<<___;
+ @ ldr $t1,[sp,#`($i+1)%16`*4] @ $i
+ @ ldr $t4,[sp,#`($i+14)%16`*4]
+ mov $t0,$t1,ror#$sigma0[0]
+ add $a,$a,$t2 @ h+=Maj(a,b,c) from the past
+ mov $t2,$t4,ror#$sigma1[0]
+ eor $t0,$t0,$t1,ror#$sigma0[1]
+ eor $t2,$t2,$t4,ror#$sigma1[1]
+ eor $t0,$t0,$t1,lsr#$sigma0[2] @ sigma0(X[i+1])
+ ldr $t1,[sp,#`($i+0)%16`*4]
+ eor $t2,$t2,$t4,lsr#$sigma1[2] @ sigma1(X[i+14])
+ ldr $t4,[sp,#`($i+9)%16`*4]
+
+ add $t2,$t2,$t0
+ eor $t0,$e,$e,ror#`$Sigma1[1]-$Sigma1[0]` @ from BODY_00_15
+ add $t1,$t1,$t2
+ eor $t0,$t0,$e,ror#`$Sigma1[2]-$Sigma1[0]` @ Sigma1(e)
+ add $t1,$t1,$t4 @ X[i]
+___
+ &BODY_00_15(@_);
+}
+
+$code=<<___;
+#ifndef __KERNEL__
+# include "arm_arch.h"
+#else
+# define __ARM_ARCH__ __LINUX_ARM_ARCH__
+# define __ARM_MAX_ARCH__ 7
+#endif
+
+.text
+#if __ARM_ARCH__<7
+.code 32
+#else
+.syntax unified
+# ifdef __thumb2__
+# define adrl adr
+.thumb
+# else
+.code 32
+# endif
+#endif
+
+.type K256,%object
+.align 5
+K256:
+.word 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+.word 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+.word 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+.word 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+.word 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+.word 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+.word 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+.word 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+.word 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+.word 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+.word 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+.word 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+.word 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+.word 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+.word 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+.word 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+.size K256,.-K256
+.word 0 @ terminator
+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
+.LOPENSSL_armcap:
+.word OPENSSL_armcap_P-sha256_block_data_order
+#endif
+.align 5
+
+.global sha256_block_data_order
+.type sha256_block_data_order,%function
+sha256_block_data_order:
+#if __ARM_ARCH__<7
+ sub r3,pc,#8 @ sha256_block_data_order
+#else
+ adr r3,sha256_block_data_order
+#endif
+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
+ ldr r12,.LOPENSSL_armcap
+ ldr r12,[r3,r12] @ OPENSSL_armcap_P
+ tst r12,#ARMV8_SHA256
+ bne .LARMv8
+ tst r12,#ARMV7_NEON
+ bne .LNEON
+#endif
+ add $len,$inp,$len,lsl#6 @ len to point at the end of inp
+ stmdb sp!,{$ctx,$inp,$len,r4-r11,lr}
+ ldmia $ctx,{$A,$B,$C,$D,$E,$F,$G,$H}
+ sub $Ktbl,r3,#256+32 @ K256
+ sub sp,sp,#16*4 @ alloca(X[16])
+.Loop:
+# if __ARM_ARCH__>=7
+ ldr $t1,[$inp],#4
+# else
+ ldrb $t1,[$inp,#3]
+# endif
+ eor $t3,$B,$C @ magic
+ eor $t2,$t2,$t2
+___
+for($i=0;$i<16;$i++) { &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
+$code.=".Lrounds_16_xx:\n";
+for (;$i<32;$i++) { &BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+#if __ARM_ARCH__>=7
+ ite eq @ Thumb2 thing, sanity check in ARM
+#endif
+ ldreq $t3,[sp,#16*4] @ pull ctx
+ bne .Lrounds_16_xx
+
+ add $A,$A,$t2 @ h+=Maj(a,b,c) from the past
+ ldr $t0,[$t3,#0]
+ ldr $t1,[$t3,#4]
+ ldr $t2,[$t3,#8]
+ add $A,$A,$t0
+ ldr $t0,[$t3,#12]
+ add $B,$B,$t1
+ ldr $t1,[$t3,#16]
+ add $C,$C,$t2
+ ldr $t2,[$t3,#20]
+ add $D,$D,$t0
+ ldr $t0,[$t3,#24]
+ add $E,$E,$t1
+ ldr $t1,[$t3,#28]
+ add $F,$F,$t2
+ ldr $inp,[sp,#17*4] @ pull inp
+ ldr $t2,[sp,#18*4] @ pull inp+len
+ add $G,$G,$t0
+ add $H,$H,$t1
+ stmia $t3,{$A,$B,$C,$D,$E,$F,$G,$H}
+ cmp $inp,$t2
+ sub $Ktbl,$Ktbl,#256 @ rewind Ktbl
+ bne .Loop
+
+ add sp,sp,#`16+3`*4 @ destroy frame
+#if __ARM_ARCH__>=5
+ ldmia sp!,{r4-r11,pc}
+#else
+ ldmia sp!,{r4-r11,lr}
+ tst lr,#1
+ moveq pc,lr @ be binary compatible with V4, yet
+ bx lr @ interoperable with Thumb ISA:-)
+#endif
+.size sha256_block_data_order,.-sha256_block_data_order
+___
+######################################################################
+# NEON stuff
+#
+{{{
+my @X=map("q$_",(0..3));
+my ($T0,$T1,$T2,$T3,$T4,$T5)=("q8","q9","q10","q11","d24","d25");
+my $Xfer=$t4;
+my $j=0;
+
+sub Dlo() { shift=~m|q([1]?[0-9])|?"d".($1*2):""; }
+sub Dhi() { shift=~m|q([1]?[0-9])|?"d".($1*2+1):""; }
+
+sub AUTOLOAD() # thunk [simplified] x86-style perlasm
+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; $opcode =~ s/_/\./;
+ my $arg = pop;
+ $arg = "#$arg" if ($arg*1 eq $arg);
+ $code .= "\t$opcode\t".join(',',@_,$arg)."\n";
+}
+
+sub Xupdate()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body);
+ my ($a,$b,$c,$d,$e,$f,$g,$h);
+
+ &vext_8 ($T0,@X[0],@X[1],4); # X[1..4]
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vext_8 ($T1,@X[2],@X[3],4); # X[9..12]
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vshr_u32 ($T2,$T0,$sigma0[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vadd_i32 (@X[0],@X[0],$T1); # X[0..3] += X[9..12]
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vshr_u32 ($T1,$T0,$sigma0[2]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vsli_32 ($T2,$T0,32-$sigma0[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vshr_u32 ($T3,$T0,$sigma0[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &veor ($T1,$T1,$T2);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vsli_32 ($T3,$T0,32-$sigma0[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vshr_u32 ($T4,&Dhi(@X[3]),$sigma1[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &veor ($T1,$T1,$T3); # sigma0(X[1..4])
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vsli_32 ($T4,&Dhi(@X[3]),32-$sigma1[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vshr_u32 ($T5,&Dhi(@X[3]),$sigma1[2]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vadd_i32 (@X[0],@X[0],$T1); # X[0..3] += sigma0(X[1..4])
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &veor ($T5,$T5,$T4);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vshr_u32 ($T4,&Dhi(@X[3]),$sigma1[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vsli_32 ($T4,&Dhi(@X[3]),32-$sigma1[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &veor ($T5,$T5,$T4); # sigma1(X[14..15])
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vadd_i32 (&Dlo(@X[0]),&Dlo(@X[0]),$T5);# X[0..1] += sigma1(X[14..15])
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vshr_u32 ($T4,&Dlo(@X[0]),$sigma1[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vsli_32 ($T4,&Dlo(@X[0]),32-$sigma1[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vshr_u32 ($T5,&Dlo(@X[0]),$sigma1[2]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &veor ($T5,$T5,$T4);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vshr_u32 ($T4,&Dlo(@X[0]),$sigma1[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vld1_32 ("{$T0}","[$Ktbl,:128]!");
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vsli_32 ($T4,&Dlo(@X[0]),32-$sigma1[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &veor ($T5,$T5,$T4); # sigma1(X[16..17])
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vadd_i32 (&Dhi(@X[0]),&Dhi(@X[0]),$T5);# X[2..3] += sigma1(X[16..17])
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vadd_i32 ($T0,$T0,@X[0]);
+ while($#insns>=2) { eval(shift(@insns)); }
+ &vst1_32 ("{$T0}","[$Xfer,:128]!");
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ push(@X,shift(@X)); # "rotate" X[]
+}
+
+sub Xpreload()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body);
+ my ($a,$b,$c,$d,$e,$f,$g,$h);
+
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vld1_32 ("{$T0}","[$Ktbl,:128]!");
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vrev32_8 (@X[0],@X[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &vadd_i32 ($T0,$T0,@X[0]);
+ foreach (@insns) { eval; } # remaining instructions
+ &vst1_32 ("{$T0}","[$Xfer,:128]!");
+
+ push(@X,shift(@X)); # "rotate" X[]
+}
+
+sub body_00_15 () {
+ (
+ '($a,$b,$c,$d,$e,$f,$g,$h)=@V;'.
+ '&add ($h,$h,$t1)', # h+=X[i]+K[i]
+ '&eor ($t1,$f,$g)',
+ '&eor ($t0,$e,$e,"ror#".($Sigma1[1]-$Sigma1[0]))',
+ '&add ($a,$a,$t2)', # h+=Maj(a,b,c) from the past
+ '&and ($t1,$t1,$e)',
+ '&eor ($t2,$t0,$e,"ror#".($Sigma1[2]-$Sigma1[0]))', # Sigma1(e)
+ '&eor ($t0,$a,$a,"ror#".($Sigma0[1]-$Sigma0[0]))',
+ '&eor ($t1,$t1,$g)', # Ch(e,f,g)
+ '&add ($h,$h,$t2,"ror#$Sigma1[0]")', # h+=Sigma1(e)
+ '&eor ($t2,$a,$b)', # a^b, b^c in next round
+ '&eor ($t0,$t0,$a,"ror#".($Sigma0[2]-$Sigma0[0]))', # Sigma0(a)
+ '&add ($h,$h,$t1)', # h+=Ch(e,f,g)
+ '&ldr ($t1,sprintf "[sp,#%d]",4*(($j+1)&15)) if (($j&15)!=15);'.
+ '&ldr ($t1,"[$Ktbl]") if ($j==15);'.
+ '&ldr ($t1,"[sp,#64]") if ($j==31)',
+ '&and ($t3,$t3,$t2)', # (b^c)&=(a^b)
+ '&add ($d,$d,$h)', # d+=h
+ '&add ($h,$h,$t0,"ror#$Sigma0[0]");'. # h+=Sigma0(a)
+ '&eor ($t3,$t3,$b)', # Maj(a,b,c)
+ '$j++; unshift(@V,pop(@V)); ($t2,$t3)=($t3,$t2);'
+ )
+}
+
+$code.=<<___;
+#if __ARM_MAX_ARCH__>=7
+.arch armv7-a
+.fpu neon
+
+.global sha256_block_data_order_neon
+.type sha256_block_data_order_neon,%function
+.align 4
+sha256_block_data_order_neon:
+.LNEON:
+ stmdb sp!,{r4-r12,lr}
+
+ sub $H,sp,#16*4+16
+ adrl $Ktbl,K256
+ bic $H,$H,#15 @ align for 128-bit stores
+ mov $t2,sp
+ mov sp,$H @ alloca
+ add $len,$inp,$len,lsl#6 @ len to point at the end of inp
+
+ vld1.8 {@X[0]},[$inp]!
+ vld1.8 {@X[1]},[$inp]!
+ vld1.8 {@X[2]},[$inp]!
+ vld1.8 {@X[3]},[$inp]!
+ vld1.32 {$T0},[$Ktbl,:128]!
+ vld1.32 {$T1},[$Ktbl,:128]!
+ vld1.32 {$T2},[$Ktbl,:128]!
+ vld1.32 {$T3},[$Ktbl,:128]!
+ vrev32.8 @X[0],@X[0] @ yes, even on
+ str $ctx,[sp,#64]
+ vrev32.8 @X[1],@X[1] @ big-endian
+ str $inp,[sp,#68]
+ mov $Xfer,sp
+ vrev32.8 @X[2],@X[2]
+ str $len,[sp,#72]
+ vrev32.8 @X[3],@X[3]
+ str $t2,[sp,#76] @ save original sp
+ vadd.i32 $T0,$T0,@X[0]
+ vadd.i32 $T1,$T1,@X[1]
+ vst1.32 {$T0},[$Xfer,:128]!
+ vadd.i32 $T2,$T2,@X[2]
+ vst1.32 {$T1},[$Xfer,:128]!
+ vadd.i32 $T3,$T3,@X[3]
+ vst1.32 {$T2},[$Xfer,:128]!
+ vst1.32 {$T3},[$Xfer,:128]!
+
+ ldmia $ctx,{$A-$H}
+ sub $Xfer,$Xfer,#64
+ ldr $t1,[sp,#0]
+ eor $t2,$t2,$t2
+ eor $t3,$B,$C
+ b .L_00_48
+
+.align 4
+.L_00_48:
+___
+ &Xupdate(\&body_00_15);
+ &Xupdate(\&body_00_15);
+ &Xupdate(\&body_00_15);
+ &Xupdate(\&body_00_15);
+$code.=<<___;
+ teq $t1,#0 @ check for K256 terminator
+ ldr $t1,[sp,#0]
+ sub $Xfer,$Xfer,#64
+ bne .L_00_48
+
+ ldr $inp,[sp,#68]
+ ldr $t0,[sp,#72]
+ sub $Ktbl,$Ktbl,#256 @ rewind $Ktbl
+ teq $inp,$t0
+ it eq
+ subeq $inp,$inp,#64 @ avoid SEGV
+ vld1.8 {@X[0]},[$inp]! @ load next input block
+ vld1.8 {@X[1]},[$inp]!
+ vld1.8 {@X[2]},[$inp]!
+ vld1.8 {@X[3]},[$inp]!
+ it ne
+ strne $inp,[sp,#68]
+ mov $Xfer,sp
+___
+ &Xpreload(\&body_00_15);
+ &Xpreload(\&body_00_15);
+ &Xpreload(\&body_00_15);
+ &Xpreload(\&body_00_15);
+$code.=<<___;
+ ldr $t0,[$t1,#0]
+ add $A,$A,$t2 @ h+=Maj(a,b,c) from the past
+ ldr $t2,[$t1,#4]
+ ldr $t3,[$t1,#8]
+ ldr $t4,[$t1,#12]
+ add $A,$A,$t0 @ accumulate
+ ldr $t0,[$t1,#16]
+ add $B,$B,$t2
+ ldr $t2,[$t1,#20]
+ add $C,$C,$t3
+ ldr $t3,[$t1,#24]
+ add $D,$D,$t4
+ ldr $t4,[$t1,#28]
+ add $E,$E,$t0
+ str $A,[$t1],#4
+ add $F,$F,$t2
+ str $B,[$t1],#4
+ add $G,$G,$t3
+ str $C,[$t1],#4
+ add $H,$H,$t4
+ str $D,[$t1],#4
+ stmia $t1,{$E-$H}
+
+ ittte ne
+ movne $Xfer,sp
+ ldrne $t1,[sp,#0]
+ eorne $t2,$t2,$t2
+ ldreq sp,[sp,#76] @ restore original sp
+ itt ne
+ eorne $t3,$B,$C
+ bne .L_00_48
+
+ ldmia sp!,{r4-r12,pc}
+.size sha256_block_data_order_neon,.-sha256_block_data_order_neon
+#endif
+___
+}}}
+######################################################################
+# ARMv8 stuff
+#
+{{{
+my ($ABCD,$EFGH,$abcd)=map("q$_",(0..2));
+my @MSG=map("q$_",(8..11));
+my ($W0,$W1,$ABCD_SAVE,$EFGH_SAVE)=map("q$_",(12..15));
+my $Ktbl="r3";
+
+$code.=<<___;
+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
+
+# ifdef __thumb2__
+# define INST(a,b,c,d) .byte c,d|0xc,a,b
+# else
+# define INST(a,b,c,d) .byte a,b,c,d
+# endif
+
+.type sha256_block_data_order_armv8,%function
+.align 5
+sha256_block_data_order_armv8:
+.LARMv8:
+ vld1.32 {$ABCD,$EFGH},[$ctx]
+# ifdef __thumb2__
+ adr $Ktbl,.LARMv8
+ sub $Ktbl,$Ktbl,#.LARMv8-K256
+# else
+ adrl $Ktbl,K256
+# endif
+ add $len,$inp,$len,lsl#6 @ len to point at the end of inp
+
+.Loop_v8:
+ vld1.8 {@MSG[0]-@MSG[1]},[$inp]!
+ vld1.8 {@MSG[2]-@MSG[3]},[$inp]!
+ vld1.32 {$W0},[$Ktbl]!
+ vrev32.8 @MSG[0],@MSG[0]
+ vrev32.8 @MSG[1],@MSG[1]
+ vrev32.8 @MSG[2],@MSG[2]
+ vrev32.8 @MSG[3],@MSG[3]
+ vmov $ABCD_SAVE,$ABCD @ offload
+ vmov $EFGH_SAVE,$EFGH
+ teq $inp,$len
+___
+for($i=0;$i<12;$i++) {
+$code.=<<___;
+ vld1.32 {$W1},[$Ktbl]!
+ vadd.i32 $W0,$W0,@MSG[0]
+ sha256su0 @MSG[0],@MSG[1]
+ vmov $abcd,$ABCD
+ sha256h $ABCD,$EFGH,$W0
+ sha256h2 $EFGH,$abcd,$W0
+ sha256su1 @MSG[0],@MSG[2],@MSG[3]
+___
+ ($W0,$W1)=($W1,$W0); push(@MSG,shift(@MSG));
+}
+$code.=<<___;
+ vld1.32 {$W1},[$Ktbl]!
+ vadd.i32 $W0,$W0,@MSG[0]
+ vmov $abcd,$ABCD
+ sha256h $ABCD,$EFGH,$W0
+ sha256h2 $EFGH,$abcd,$W0
+
+ vld1.32 {$W0},[$Ktbl]!
+ vadd.i32 $W1,$W1,@MSG[1]
+ vmov $abcd,$ABCD
+ sha256h $ABCD,$EFGH,$W1
+ sha256h2 $EFGH,$abcd,$W1
+
+ vld1.32 {$W1},[$Ktbl]
+ vadd.i32 $W0,$W0,@MSG[2]
+ sub $Ktbl,$Ktbl,#256-16 @ rewind
+ vmov $abcd,$ABCD
+ sha256h $ABCD,$EFGH,$W0
+ sha256h2 $EFGH,$abcd,$W0
+
+ vadd.i32 $W1,$W1,@MSG[3]
+ vmov $abcd,$ABCD
+ sha256h $ABCD,$EFGH,$W1
+ sha256h2 $EFGH,$abcd,$W1
+
+ vadd.i32 $ABCD,$ABCD,$ABCD_SAVE
+ vadd.i32 $EFGH,$EFGH,$EFGH_SAVE
+ it ne
+ bne .Loop_v8
+
+ vst1.32 {$ABCD,$EFGH},[$ctx]
+
+ ret @ bx lr
+.size sha256_block_data_order_armv8,.-sha256_block_data_order_armv8
+#endif
+___
+}}}
+$code.=<<___;
+.asciz "SHA256 block transform for ARMv4/NEON/ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
+.align 2
+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
+.comm OPENSSL_armcap_P,4,4
+#endif
+___
+
+open SELF,$0;
+while(<SELF>) {
+ next if (/^#!/);
+ last if (!s/^#/@/ and !/^$/);
+ print;
+}
+close SELF;
+
+{ my %opcode = (
+ "sha256h" => 0xf3000c40, "sha256h2" => 0xf3100c40,
+ "sha256su0" => 0xf3ba03c0, "sha256su1" => 0xf3200c40 );
+
+ sub unsha256 {
+ my ($mnemonic,$arg)=@_;
+
+ if ($arg =~ m/q([0-9]+)(?:,\s*q([0-9]+))?,\s*q([0-9]+)/o) {
+ my $word = $opcode{$mnemonic}|(($1&7)<<13)|(($1&8)<<19)
+ |(($2&7)<<17)|(($2&8)<<4)
+ |(($3&7)<<1) |(($3&8)<<2);
+ # since ARMv7 instructions are always encoded little-endian.
+ # correct solution is to use .inst directive, but older
+ # assemblers don't implement it:-(
+ sprintf "INST(0x%02x,0x%02x,0x%02x,0x%02x)\t@ %s %s",
+ $word&0xff,($word>>8)&0xff,
+ ($word>>16)&0xff,($word>>24)&0xff,
+ $mnemonic,$arg;
+ }
+ }
+}
+
+foreach (split($/,$code)) {
+
+ s/\`([^\`]*)\`/eval $1/geo;
+
+ s/\b(sha256\w+)\s+(q.*)/unsha256($1,$2)/geo;
+
+ s/\bret\b/bx lr/go or
+ s/\bbx\s+lr\b/.word\t0xe12fff1e/go; # make it possible to compile with -march=armv4
+
+ print $_,"\n";
+}
+
+close STDOUT; # enforce flush
diff --git a/arch/arm/crypto/sha256-core.S_shipped b/arch/arm/crypto/sha256-core.S_shipped
new file mode 100644
index 000000000..555a1a8ee
--- /dev/null
+++ b/arch/arm/crypto/sha256-core.S_shipped
@@ -0,0 +1,2808 @@
+
+@ ====================================================================
+@ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+@ project. The module is, however, dual licensed under OpenSSL and
+@ CRYPTOGAMS licenses depending on where you obtain it. For further
+@ details see http://www.openssl.org/~appro/cryptogams/.
+@
+@ Permission to use under GPL terms is granted.
+@ ====================================================================
+
+@ SHA256 block procedure for ARMv4. May 2007.
+
+@ Performance is ~2x better than gcc 3.4 generated code and in "abso-
+@ lute" terms is ~2250 cycles per 64-byte block or ~35 cycles per
+@ byte [on single-issue Xscale PXA250 core].
+
+@ July 2010.
+@
+@ Rescheduling for dual-issue pipeline resulted in 22% improvement on
+@ Cortex A8 core and ~20 cycles per processed byte.
+
+@ February 2011.
+@
+@ Profiler-assisted and platform-specific optimization resulted in 16%
+@ improvement on Cortex A8 core and ~15.4 cycles per processed byte.
+
+@ September 2013.
+@
+@ Add NEON implementation. On Cortex A8 it was measured to process one
+@ byte in 12.5 cycles or 23% faster than integer-only code. Snapdragon
+@ S4 does it in 12.5 cycles too, but it's 50% faster than integer-only
+@ code (meaning that latter performs sub-optimally, nothing was done
+@ about it).
+
+@ May 2014.
+@
+@ Add ARMv8 code path performing at 2.0 cpb on Apple A7.
+
+#ifndef __KERNEL__
+# include "arm_arch.h"
+#else
+# define __ARM_ARCH__ __LINUX_ARM_ARCH__
+# define __ARM_MAX_ARCH__ 7
+#endif
+
+.text
+#if __ARM_ARCH__<7
+.code 32
+#else
+.syntax unified
+# ifdef __thumb2__
+# define adrl adr
+.thumb
+# else
+.code 32
+# endif
+#endif
+
+.type K256,%object
+.align 5
+K256:
+.word 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+.word 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+.word 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+.word 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+.word 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+.word 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+.word 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+.word 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+.word 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+.word 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+.word 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+.word 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+.word 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+.word 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+.word 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+.word 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+.size K256,.-K256
+.word 0 @ terminator
+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
+.LOPENSSL_armcap:
+.word OPENSSL_armcap_P-sha256_block_data_order
+#endif
+.align 5
+
+.global sha256_block_data_order
+.type sha256_block_data_order,%function
+sha256_block_data_order:
+#if __ARM_ARCH__<7
+ sub r3,pc,#8 @ sha256_block_data_order
+#else
+ adr r3,sha256_block_data_order
+#endif
+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
+ ldr r12,.LOPENSSL_armcap
+ ldr r12,[r3,r12] @ OPENSSL_armcap_P
+ tst r12,#ARMV8_SHA256
+ bne .LARMv8
+ tst r12,#ARMV7_NEON
+ bne .LNEON
+#endif
+ add r2,r1,r2,lsl#6 @ len to point at the end of inp
+ stmdb sp!,{r0,r1,r2,r4-r11,lr}
+ ldmia r0,{r4,r5,r6,r7,r8,r9,r10,r11}
+ sub r14,r3,#256+32 @ K256
+ sub sp,sp,#16*4 @ alloca(X[16])
+.Loop:
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r5,r6 @ magic
+ eor r12,r12,r12
+#if __ARM_ARCH__>=7
+ @ ldr r2,[r1],#4 @ 0
+# if 0==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r8,r8,ror#5
+ add r4,r4,r12 @ h+=Maj(a,b,c) from the past
+ eor r0,r0,r8,ror#19 @ Sigma1(e)
+# ifndef __ARMEB__
+ rev r2,r2
+# endif
+#else
+ @ ldrb r2,[r1,#3] @ 0
+ add r4,r4,r12 @ h+=Maj(a,b,c) from the past
+ ldrb r12,[r1,#2]
+ ldrb r0,[r1,#1]
+ orr r2,r2,r12,lsl#8
+ ldrb r12,[r1],#4
+ orr r2,r2,r0,lsl#16
+# if 0==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r8,r8,ror#5
+ orr r2,r2,r12,lsl#24
+ eor r0,r0,r8,ror#19 @ Sigma1(e)
+#endif
+ ldr r12,[r14],#4 @ *K256++
+ add r11,r11,r2 @ h+=X[i]
+ str r2,[sp,#0*4]
+ eor r2,r9,r10
+ add r11,r11,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r8
+ add r11,r11,r12 @ h+=K256[i]
+ eor r2,r2,r10 @ Ch(e,f,g)
+ eor r0,r4,r4,ror#11
+ add r11,r11,r2 @ h+=Ch(e,f,g)
+#if 0==31
+ and r12,r12,#0xff
+ cmp r12,#0xf2 @ done?
+#endif
+#if 0<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r12,r4,r5 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#2*4] @ from future BODY_16_xx
+ eor r12,r4,r5 @ a^b, b^c in next round
+ ldr r1,[sp,#15*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r4,ror#20 @ Sigma0(a)
+ and r3,r3,r12 @ (b^c)&=(a^b)
+ add r7,r7,r11 @ d+=h
+ eor r3,r3,r5 @ Maj(a,b,c)
+ add r11,r11,r0,ror#2 @ h+=Sigma0(a)
+ @ add r11,r11,r3 @ h+=Maj(a,b,c)
+#if __ARM_ARCH__>=7
+ @ ldr r2,[r1],#4 @ 1
+# if 1==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r7,r7,ror#5
+ add r11,r11,r3 @ h+=Maj(a,b,c) from the past
+ eor r0,r0,r7,ror#19 @ Sigma1(e)
+# ifndef __ARMEB__
+ rev r2,r2
+# endif
+#else
+ @ ldrb r2,[r1,#3] @ 1
+ add r11,r11,r3 @ h+=Maj(a,b,c) from the past
+ ldrb r3,[r1,#2]
+ ldrb r0,[r1,#1]
+ orr r2,r2,r3,lsl#8
+ ldrb r3,[r1],#4
+ orr r2,r2,r0,lsl#16
+# if 1==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r7,r7,ror#5
+ orr r2,r2,r3,lsl#24
+ eor r0,r0,r7,ror#19 @ Sigma1(e)
+#endif
+ ldr r3,[r14],#4 @ *K256++
+ add r10,r10,r2 @ h+=X[i]
+ str r2,[sp,#1*4]
+ eor r2,r8,r9
+ add r10,r10,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r7
+ add r10,r10,r3 @ h+=K256[i]
+ eor r2,r2,r9 @ Ch(e,f,g)
+ eor r0,r11,r11,ror#11
+ add r10,r10,r2 @ h+=Ch(e,f,g)
+#if 1==31
+ and r3,r3,#0xff
+ cmp r3,#0xf2 @ done?
+#endif
+#if 1<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r11,r4 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#3*4] @ from future BODY_16_xx
+ eor r3,r11,r4 @ a^b, b^c in next round
+ ldr r1,[sp,#0*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r11,ror#20 @ Sigma0(a)
+ and r12,r12,r3 @ (b^c)&=(a^b)
+ add r6,r6,r10 @ d+=h
+ eor r12,r12,r4 @ Maj(a,b,c)
+ add r10,r10,r0,ror#2 @ h+=Sigma0(a)
+ @ add r10,r10,r12 @ h+=Maj(a,b,c)
+#if __ARM_ARCH__>=7
+ @ ldr r2,[r1],#4 @ 2
+# if 2==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r6,r6,ror#5
+ add r10,r10,r12 @ h+=Maj(a,b,c) from the past
+ eor r0,r0,r6,ror#19 @ Sigma1(e)
+# ifndef __ARMEB__
+ rev r2,r2
+# endif
+#else
+ @ ldrb r2,[r1,#3] @ 2
+ add r10,r10,r12 @ h+=Maj(a,b,c) from the past
+ ldrb r12,[r1,#2]
+ ldrb r0,[r1,#1]
+ orr r2,r2,r12,lsl#8
+ ldrb r12,[r1],#4
+ orr r2,r2,r0,lsl#16
+# if 2==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r6,r6,ror#5
+ orr r2,r2,r12,lsl#24
+ eor r0,r0,r6,ror#19 @ Sigma1(e)
+#endif
+ ldr r12,[r14],#4 @ *K256++
+ add r9,r9,r2 @ h+=X[i]
+ str r2,[sp,#2*4]
+ eor r2,r7,r8
+ add r9,r9,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r6
+ add r9,r9,r12 @ h+=K256[i]
+ eor r2,r2,r8 @ Ch(e,f,g)
+ eor r0,r10,r10,ror#11
+ add r9,r9,r2 @ h+=Ch(e,f,g)
+#if 2==31
+ and r12,r12,#0xff
+ cmp r12,#0xf2 @ done?
+#endif
+#if 2<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r12,r10,r11 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#4*4] @ from future BODY_16_xx
+ eor r12,r10,r11 @ a^b, b^c in next round
+ ldr r1,[sp,#1*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r10,ror#20 @ Sigma0(a)
+ and r3,r3,r12 @ (b^c)&=(a^b)
+ add r5,r5,r9 @ d+=h
+ eor r3,r3,r11 @ Maj(a,b,c)
+ add r9,r9,r0,ror#2 @ h+=Sigma0(a)
+ @ add r9,r9,r3 @ h+=Maj(a,b,c)
+#if __ARM_ARCH__>=7
+ @ ldr r2,[r1],#4 @ 3
+# if 3==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r5,r5,ror#5
+ add r9,r9,r3 @ h+=Maj(a,b,c) from the past
+ eor r0,r0,r5,ror#19 @ Sigma1(e)
+# ifndef __ARMEB__
+ rev r2,r2
+# endif
+#else
+ @ ldrb r2,[r1,#3] @ 3
+ add r9,r9,r3 @ h+=Maj(a,b,c) from the past
+ ldrb r3,[r1,#2]
+ ldrb r0,[r1,#1]
+ orr r2,r2,r3,lsl#8
+ ldrb r3,[r1],#4
+ orr r2,r2,r0,lsl#16
+# if 3==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r5,r5,ror#5
+ orr r2,r2,r3,lsl#24
+ eor r0,r0,r5,ror#19 @ Sigma1(e)
+#endif
+ ldr r3,[r14],#4 @ *K256++
+ add r8,r8,r2 @ h+=X[i]
+ str r2,[sp,#3*4]
+ eor r2,r6,r7
+ add r8,r8,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r5
+ add r8,r8,r3 @ h+=K256[i]
+ eor r2,r2,r7 @ Ch(e,f,g)
+ eor r0,r9,r9,ror#11
+ add r8,r8,r2 @ h+=Ch(e,f,g)
+#if 3==31
+ and r3,r3,#0xff
+ cmp r3,#0xf2 @ done?
+#endif
+#if 3<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r9,r10 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#5*4] @ from future BODY_16_xx
+ eor r3,r9,r10 @ a^b, b^c in next round
+ ldr r1,[sp,#2*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r9,ror#20 @ Sigma0(a)
+ and r12,r12,r3 @ (b^c)&=(a^b)
+ add r4,r4,r8 @ d+=h
+ eor r12,r12,r10 @ Maj(a,b,c)
+ add r8,r8,r0,ror#2 @ h+=Sigma0(a)
+ @ add r8,r8,r12 @ h+=Maj(a,b,c)
+#if __ARM_ARCH__>=7
+ @ ldr r2,[r1],#4 @ 4
+# if 4==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r4,r4,ror#5
+ add r8,r8,r12 @ h+=Maj(a,b,c) from the past
+ eor r0,r0,r4,ror#19 @ Sigma1(e)
+# ifndef __ARMEB__
+ rev r2,r2
+# endif
+#else
+ @ ldrb r2,[r1,#3] @ 4
+ add r8,r8,r12 @ h+=Maj(a,b,c) from the past
+ ldrb r12,[r1,#2]
+ ldrb r0,[r1,#1]
+ orr r2,r2,r12,lsl#8
+ ldrb r12,[r1],#4
+ orr r2,r2,r0,lsl#16
+# if 4==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r4,r4,ror#5
+ orr r2,r2,r12,lsl#24
+ eor r0,r0,r4,ror#19 @ Sigma1(e)
+#endif
+ ldr r12,[r14],#4 @ *K256++
+ add r7,r7,r2 @ h+=X[i]
+ str r2,[sp,#4*4]
+ eor r2,r5,r6
+ add r7,r7,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r4
+ add r7,r7,r12 @ h+=K256[i]
+ eor r2,r2,r6 @ Ch(e,f,g)
+ eor r0,r8,r8,ror#11
+ add r7,r7,r2 @ h+=Ch(e,f,g)
+#if 4==31
+ and r12,r12,#0xff
+ cmp r12,#0xf2 @ done?
+#endif
+#if 4<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r12,r8,r9 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#6*4] @ from future BODY_16_xx
+ eor r12,r8,r9 @ a^b, b^c in next round
+ ldr r1,[sp,#3*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r8,ror#20 @ Sigma0(a)
+ and r3,r3,r12 @ (b^c)&=(a^b)
+ add r11,r11,r7 @ d+=h
+ eor r3,r3,r9 @ Maj(a,b,c)
+ add r7,r7,r0,ror#2 @ h+=Sigma0(a)
+ @ add r7,r7,r3 @ h+=Maj(a,b,c)
+#if __ARM_ARCH__>=7
+ @ ldr r2,[r1],#4 @ 5
+# if 5==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r11,r11,ror#5
+ add r7,r7,r3 @ h+=Maj(a,b,c) from the past
+ eor r0,r0,r11,ror#19 @ Sigma1(e)
+# ifndef __ARMEB__
+ rev r2,r2
+# endif
+#else
+ @ ldrb r2,[r1,#3] @ 5
+ add r7,r7,r3 @ h+=Maj(a,b,c) from the past
+ ldrb r3,[r1,#2]
+ ldrb r0,[r1,#1]
+ orr r2,r2,r3,lsl#8
+ ldrb r3,[r1],#4
+ orr r2,r2,r0,lsl#16
+# if 5==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r11,r11,ror#5
+ orr r2,r2,r3,lsl#24
+ eor r0,r0,r11,ror#19 @ Sigma1(e)
+#endif
+ ldr r3,[r14],#4 @ *K256++
+ add r6,r6,r2 @ h+=X[i]
+ str r2,[sp,#5*4]
+ eor r2,r4,r5
+ add r6,r6,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r11
+ add r6,r6,r3 @ h+=K256[i]
+ eor r2,r2,r5 @ Ch(e,f,g)
+ eor r0,r7,r7,ror#11
+ add r6,r6,r2 @ h+=Ch(e,f,g)
+#if 5==31
+ and r3,r3,#0xff
+ cmp r3,#0xf2 @ done?
+#endif
+#if 5<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r7,r8 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#7*4] @ from future BODY_16_xx
+ eor r3,r7,r8 @ a^b, b^c in next round
+ ldr r1,[sp,#4*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r7,ror#20 @ Sigma0(a)
+ and r12,r12,r3 @ (b^c)&=(a^b)
+ add r10,r10,r6 @ d+=h
+ eor r12,r12,r8 @ Maj(a,b,c)
+ add r6,r6,r0,ror#2 @ h+=Sigma0(a)
+ @ add r6,r6,r12 @ h+=Maj(a,b,c)
+#if __ARM_ARCH__>=7
+ @ ldr r2,[r1],#4 @ 6
+# if 6==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r10,r10,ror#5
+ add r6,r6,r12 @ h+=Maj(a,b,c) from the past
+ eor r0,r0,r10,ror#19 @ Sigma1(e)
+# ifndef __ARMEB__
+ rev r2,r2
+# endif
+#else
+ @ ldrb r2,[r1,#3] @ 6
+ add r6,r6,r12 @ h+=Maj(a,b,c) from the past
+ ldrb r12,[r1,#2]
+ ldrb r0,[r1,#1]
+ orr r2,r2,r12,lsl#8
+ ldrb r12,[r1],#4
+ orr r2,r2,r0,lsl#16
+# if 6==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r10,r10,ror#5
+ orr r2,r2,r12,lsl#24
+ eor r0,r0,r10,ror#19 @ Sigma1(e)
+#endif
+ ldr r12,[r14],#4 @ *K256++
+ add r5,r5,r2 @ h+=X[i]
+ str r2,[sp,#6*4]
+ eor r2,r11,r4
+ add r5,r5,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r10
+ add r5,r5,r12 @ h+=K256[i]
+ eor r2,r2,r4 @ Ch(e,f,g)
+ eor r0,r6,r6,ror#11
+ add r5,r5,r2 @ h+=Ch(e,f,g)
+#if 6==31
+ and r12,r12,#0xff
+ cmp r12,#0xf2 @ done?
+#endif
+#if 6<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r12,r6,r7 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#8*4] @ from future BODY_16_xx
+ eor r12,r6,r7 @ a^b, b^c in next round
+ ldr r1,[sp,#5*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r6,ror#20 @ Sigma0(a)
+ and r3,r3,r12 @ (b^c)&=(a^b)
+ add r9,r9,r5 @ d+=h
+ eor r3,r3,r7 @ Maj(a,b,c)
+ add r5,r5,r0,ror#2 @ h+=Sigma0(a)
+ @ add r5,r5,r3 @ h+=Maj(a,b,c)
+#if __ARM_ARCH__>=7
+ @ ldr r2,[r1],#4 @ 7
+# if 7==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r9,r9,ror#5
+ add r5,r5,r3 @ h+=Maj(a,b,c) from the past
+ eor r0,r0,r9,ror#19 @ Sigma1(e)
+# ifndef __ARMEB__
+ rev r2,r2
+# endif
+#else
+ @ ldrb r2,[r1,#3] @ 7
+ add r5,r5,r3 @ h+=Maj(a,b,c) from the past
+ ldrb r3,[r1,#2]
+ ldrb r0,[r1,#1]
+ orr r2,r2,r3,lsl#8
+ ldrb r3,[r1],#4
+ orr r2,r2,r0,lsl#16
+# if 7==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r9,r9,ror#5
+ orr r2,r2,r3,lsl#24
+ eor r0,r0,r9,ror#19 @ Sigma1(e)
+#endif
+ ldr r3,[r14],#4 @ *K256++
+ add r4,r4,r2 @ h+=X[i]
+ str r2,[sp,#7*4]
+ eor r2,r10,r11
+ add r4,r4,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r9
+ add r4,r4,r3 @ h+=K256[i]
+ eor r2,r2,r11 @ Ch(e,f,g)
+ eor r0,r5,r5,ror#11
+ add r4,r4,r2 @ h+=Ch(e,f,g)
+#if 7==31
+ and r3,r3,#0xff
+ cmp r3,#0xf2 @ done?
+#endif
+#if 7<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r5,r6 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#9*4] @ from future BODY_16_xx
+ eor r3,r5,r6 @ a^b, b^c in next round
+ ldr r1,[sp,#6*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r5,ror#20 @ Sigma0(a)
+ and r12,r12,r3 @ (b^c)&=(a^b)
+ add r8,r8,r4 @ d+=h
+ eor r12,r12,r6 @ Maj(a,b,c)
+ add r4,r4,r0,ror#2 @ h+=Sigma0(a)
+ @ add r4,r4,r12 @ h+=Maj(a,b,c)
+#if __ARM_ARCH__>=7
+ @ ldr r2,[r1],#4 @ 8
+# if 8==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r8,r8,ror#5
+ add r4,r4,r12 @ h+=Maj(a,b,c) from the past
+ eor r0,r0,r8,ror#19 @ Sigma1(e)
+# ifndef __ARMEB__
+ rev r2,r2
+# endif
+#else
+ @ ldrb r2,[r1,#3] @ 8
+ add r4,r4,r12 @ h+=Maj(a,b,c) from the past
+ ldrb r12,[r1,#2]
+ ldrb r0,[r1,#1]
+ orr r2,r2,r12,lsl#8
+ ldrb r12,[r1],#4
+ orr r2,r2,r0,lsl#16
+# if 8==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r8,r8,ror#5
+ orr r2,r2,r12,lsl#24
+ eor r0,r0,r8,ror#19 @ Sigma1(e)
+#endif
+ ldr r12,[r14],#4 @ *K256++
+ add r11,r11,r2 @ h+=X[i]
+ str r2,[sp,#8*4]
+ eor r2,r9,r10
+ add r11,r11,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r8
+ add r11,r11,r12 @ h+=K256[i]
+ eor r2,r2,r10 @ Ch(e,f,g)
+ eor r0,r4,r4,ror#11
+ add r11,r11,r2 @ h+=Ch(e,f,g)
+#if 8==31
+ and r12,r12,#0xff
+ cmp r12,#0xf2 @ done?
+#endif
+#if 8<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r12,r4,r5 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#10*4] @ from future BODY_16_xx
+ eor r12,r4,r5 @ a^b, b^c in next round
+ ldr r1,[sp,#7*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r4,ror#20 @ Sigma0(a)
+ and r3,r3,r12 @ (b^c)&=(a^b)
+ add r7,r7,r11 @ d+=h
+ eor r3,r3,r5 @ Maj(a,b,c)
+ add r11,r11,r0,ror#2 @ h+=Sigma0(a)
+ @ add r11,r11,r3 @ h+=Maj(a,b,c)
+#if __ARM_ARCH__>=7
+ @ ldr r2,[r1],#4 @ 9
+# if 9==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r7,r7,ror#5
+ add r11,r11,r3 @ h+=Maj(a,b,c) from the past
+ eor r0,r0,r7,ror#19 @ Sigma1(e)
+# ifndef __ARMEB__
+ rev r2,r2
+# endif
+#else
+ @ ldrb r2,[r1,#3] @ 9
+ add r11,r11,r3 @ h+=Maj(a,b,c) from the past
+ ldrb r3,[r1,#2]
+ ldrb r0,[r1,#1]
+ orr r2,r2,r3,lsl#8
+ ldrb r3,[r1],#4
+ orr r2,r2,r0,lsl#16
+# if 9==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r7,r7,ror#5
+ orr r2,r2,r3,lsl#24
+ eor r0,r0,r7,ror#19 @ Sigma1(e)
+#endif
+ ldr r3,[r14],#4 @ *K256++
+ add r10,r10,r2 @ h+=X[i]
+ str r2,[sp,#9*4]
+ eor r2,r8,r9
+ add r10,r10,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r7
+ add r10,r10,r3 @ h+=K256[i]
+ eor r2,r2,r9 @ Ch(e,f,g)
+ eor r0,r11,r11,ror#11
+ add r10,r10,r2 @ h+=Ch(e,f,g)
+#if 9==31
+ and r3,r3,#0xff
+ cmp r3,#0xf2 @ done?
+#endif
+#if 9<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r11,r4 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#11*4] @ from future BODY_16_xx
+ eor r3,r11,r4 @ a^b, b^c in next round
+ ldr r1,[sp,#8*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r11,ror#20 @ Sigma0(a)
+ and r12,r12,r3 @ (b^c)&=(a^b)
+ add r6,r6,r10 @ d+=h
+ eor r12,r12,r4 @ Maj(a,b,c)
+ add r10,r10,r0,ror#2 @ h+=Sigma0(a)
+ @ add r10,r10,r12 @ h+=Maj(a,b,c)
+#if __ARM_ARCH__>=7
+ @ ldr r2,[r1],#4 @ 10
+# if 10==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r6,r6,ror#5
+ add r10,r10,r12 @ h+=Maj(a,b,c) from the past
+ eor r0,r0,r6,ror#19 @ Sigma1(e)
+# ifndef __ARMEB__
+ rev r2,r2
+# endif
+#else
+ @ ldrb r2,[r1,#3] @ 10
+ add r10,r10,r12 @ h+=Maj(a,b,c) from the past
+ ldrb r12,[r1,#2]
+ ldrb r0,[r1,#1]
+ orr r2,r2,r12,lsl#8
+ ldrb r12,[r1],#4
+ orr r2,r2,r0,lsl#16
+# if 10==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r6,r6,ror#5
+ orr r2,r2,r12,lsl#24
+ eor r0,r0,r6,ror#19 @ Sigma1(e)
+#endif
+ ldr r12,[r14],#4 @ *K256++
+ add r9,r9,r2 @ h+=X[i]
+ str r2,[sp,#10*4]
+ eor r2,r7,r8
+ add r9,r9,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r6
+ add r9,r9,r12 @ h+=K256[i]
+ eor r2,r2,r8 @ Ch(e,f,g)
+ eor r0,r10,r10,ror#11
+ add r9,r9,r2 @ h+=Ch(e,f,g)
+#if 10==31
+ and r12,r12,#0xff
+ cmp r12,#0xf2 @ done?
+#endif
+#if 10<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r12,r10,r11 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#12*4] @ from future BODY_16_xx
+ eor r12,r10,r11 @ a^b, b^c in next round
+ ldr r1,[sp,#9*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r10,ror#20 @ Sigma0(a)
+ and r3,r3,r12 @ (b^c)&=(a^b)
+ add r5,r5,r9 @ d+=h
+ eor r3,r3,r11 @ Maj(a,b,c)
+ add r9,r9,r0,ror#2 @ h+=Sigma0(a)
+ @ add r9,r9,r3 @ h+=Maj(a,b,c)
+#if __ARM_ARCH__>=7
+ @ ldr r2,[r1],#4 @ 11
+# if 11==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r5,r5,ror#5
+ add r9,r9,r3 @ h+=Maj(a,b,c) from the past
+ eor r0,r0,r5,ror#19 @ Sigma1(e)
+# ifndef __ARMEB__
+ rev r2,r2
+# endif
+#else
+ @ ldrb r2,[r1,#3] @ 11
+ add r9,r9,r3 @ h+=Maj(a,b,c) from the past
+ ldrb r3,[r1,#2]
+ ldrb r0,[r1,#1]
+ orr r2,r2,r3,lsl#8
+ ldrb r3,[r1],#4
+ orr r2,r2,r0,lsl#16
+# if 11==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r5,r5,ror#5
+ orr r2,r2,r3,lsl#24
+ eor r0,r0,r5,ror#19 @ Sigma1(e)
+#endif
+ ldr r3,[r14],#4 @ *K256++
+ add r8,r8,r2 @ h+=X[i]
+ str r2,[sp,#11*4]
+ eor r2,r6,r7
+ add r8,r8,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r5
+ add r8,r8,r3 @ h+=K256[i]
+ eor r2,r2,r7 @ Ch(e,f,g)
+ eor r0,r9,r9,ror#11
+ add r8,r8,r2 @ h+=Ch(e,f,g)
+#if 11==31
+ and r3,r3,#0xff
+ cmp r3,#0xf2 @ done?
+#endif
+#if 11<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r9,r10 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#13*4] @ from future BODY_16_xx
+ eor r3,r9,r10 @ a^b, b^c in next round
+ ldr r1,[sp,#10*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r9,ror#20 @ Sigma0(a)
+ and r12,r12,r3 @ (b^c)&=(a^b)
+ add r4,r4,r8 @ d+=h
+ eor r12,r12,r10 @ Maj(a,b,c)
+ add r8,r8,r0,ror#2 @ h+=Sigma0(a)
+ @ add r8,r8,r12 @ h+=Maj(a,b,c)
+#if __ARM_ARCH__>=7
+ @ ldr r2,[r1],#4 @ 12
+# if 12==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r4,r4,ror#5
+ add r8,r8,r12 @ h+=Maj(a,b,c) from the past
+ eor r0,r0,r4,ror#19 @ Sigma1(e)
+# ifndef __ARMEB__
+ rev r2,r2
+# endif
+#else
+ @ ldrb r2,[r1,#3] @ 12
+ add r8,r8,r12 @ h+=Maj(a,b,c) from the past
+ ldrb r12,[r1,#2]
+ ldrb r0,[r1,#1]
+ orr r2,r2,r12,lsl#8
+ ldrb r12,[r1],#4
+ orr r2,r2,r0,lsl#16
+# if 12==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r4,r4,ror#5
+ orr r2,r2,r12,lsl#24
+ eor r0,r0,r4,ror#19 @ Sigma1(e)
+#endif
+ ldr r12,[r14],#4 @ *K256++
+ add r7,r7,r2 @ h+=X[i]
+ str r2,[sp,#12*4]
+ eor r2,r5,r6
+ add r7,r7,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r4
+ add r7,r7,r12 @ h+=K256[i]
+ eor r2,r2,r6 @ Ch(e,f,g)
+ eor r0,r8,r8,ror#11
+ add r7,r7,r2 @ h+=Ch(e,f,g)
+#if 12==31
+ and r12,r12,#0xff
+ cmp r12,#0xf2 @ done?
+#endif
+#if 12<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r12,r8,r9 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#14*4] @ from future BODY_16_xx
+ eor r12,r8,r9 @ a^b, b^c in next round
+ ldr r1,[sp,#11*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r8,ror#20 @ Sigma0(a)
+ and r3,r3,r12 @ (b^c)&=(a^b)
+ add r11,r11,r7 @ d+=h
+ eor r3,r3,r9 @ Maj(a,b,c)
+ add r7,r7,r0,ror#2 @ h+=Sigma0(a)
+ @ add r7,r7,r3 @ h+=Maj(a,b,c)
+#if __ARM_ARCH__>=7
+ @ ldr r2,[r1],#4 @ 13
+# if 13==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r11,r11,ror#5
+ add r7,r7,r3 @ h+=Maj(a,b,c) from the past
+ eor r0,r0,r11,ror#19 @ Sigma1(e)
+# ifndef __ARMEB__
+ rev r2,r2
+# endif
+#else
+ @ ldrb r2,[r1,#3] @ 13
+ add r7,r7,r3 @ h+=Maj(a,b,c) from the past
+ ldrb r3,[r1,#2]
+ ldrb r0,[r1,#1]
+ orr r2,r2,r3,lsl#8
+ ldrb r3,[r1],#4
+ orr r2,r2,r0,lsl#16
+# if 13==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r11,r11,ror#5
+ orr r2,r2,r3,lsl#24
+ eor r0,r0,r11,ror#19 @ Sigma1(e)
+#endif
+ ldr r3,[r14],#4 @ *K256++
+ add r6,r6,r2 @ h+=X[i]
+ str r2,[sp,#13*4]
+ eor r2,r4,r5
+ add r6,r6,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r11
+ add r6,r6,r3 @ h+=K256[i]
+ eor r2,r2,r5 @ Ch(e,f,g)
+ eor r0,r7,r7,ror#11
+ add r6,r6,r2 @ h+=Ch(e,f,g)
+#if 13==31
+ and r3,r3,#0xff
+ cmp r3,#0xf2 @ done?
+#endif
+#if 13<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r7,r8 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#15*4] @ from future BODY_16_xx
+ eor r3,r7,r8 @ a^b, b^c in next round
+ ldr r1,[sp,#12*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r7,ror#20 @ Sigma0(a)
+ and r12,r12,r3 @ (b^c)&=(a^b)
+ add r10,r10,r6 @ d+=h
+ eor r12,r12,r8 @ Maj(a,b,c)
+ add r6,r6,r0,ror#2 @ h+=Sigma0(a)
+ @ add r6,r6,r12 @ h+=Maj(a,b,c)
+#if __ARM_ARCH__>=7
+ @ ldr r2,[r1],#4 @ 14
+# if 14==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r10,r10,ror#5
+ add r6,r6,r12 @ h+=Maj(a,b,c) from the past
+ eor r0,r0,r10,ror#19 @ Sigma1(e)
+# ifndef __ARMEB__
+ rev r2,r2
+# endif
+#else
+ @ ldrb r2,[r1,#3] @ 14
+ add r6,r6,r12 @ h+=Maj(a,b,c) from the past
+ ldrb r12,[r1,#2]
+ ldrb r0,[r1,#1]
+ orr r2,r2,r12,lsl#8
+ ldrb r12,[r1],#4
+ orr r2,r2,r0,lsl#16
+# if 14==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r10,r10,ror#5
+ orr r2,r2,r12,lsl#24
+ eor r0,r0,r10,ror#19 @ Sigma1(e)
+#endif
+ ldr r12,[r14],#4 @ *K256++
+ add r5,r5,r2 @ h+=X[i]
+ str r2,[sp,#14*4]
+ eor r2,r11,r4
+ add r5,r5,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r10
+ add r5,r5,r12 @ h+=K256[i]
+ eor r2,r2,r4 @ Ch(e,f,g)
+ eor r0,r6,r6,ror#11
+ add r5,r5,r2 @ h+=Ch(e,f,g)
+#if 14==31
+ and r12,r12,#0xff
+ cmp r12,#0xf2 @ done?
+#endif
+#if 14<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r12,r6,r7 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#0*4] @ from future BODY_16_xx
+ eor r12,r6,r7 @ a^b, b^c in next round
+ ldr r1,[sp,#13*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r6,ror#20 @ Sigma0(a)
+ and r3,r3,r12 @ (b^c)&=(a^b)
+ add r9,r9,r5 @ d+=h
+ eor r3,r3,r7 @ Maj(a,b,c)
+ add r5,r5,r0,ror#2 @ h+=Sigma0(a)
+ @ add r5,r5,r3 @ h+=Maj(a,b,c)
+#if __ARM_ARCH__>=7
+ @ ldr r2,[r1],#4 @ 15
+# if 15==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r9,r9,ror#5
+ add r5,r5,r3 @ h+=Maj(a,b,c) from the past
+ eor r0,r0,r9,ror#19 @ Sigma1(e)
+# ifndef __ARMEB__
+ rev r2,r2
+# endif
+#else
+ @ ldrb r2,[r1,#3] @ 15
+ add r5,r5,r3 @ h+=Maj(a,b,c) from the past
+ ldrb r3,[r1,#2]
+ ldrb r0,[r1,#1]
+ orr r2,r2,r3,lsl#8
+ ldrb r3,[r1],#4
+ orr r2,r2,r0,lsl#16
+# if 15==15
+ str r1,[sp,#17*4] @ make room for r1
+# endif
+ eor r0,r9,r9,ror#5
+ orr r2,r2,r3,lsl#24
+ eor r0,r0,r9,ror#19 @ Sigma1(e)
+#endif
+ ldr r3,[r14],#4 @ *K256++
+ add r4,r4,r2 @ h+=X[i]
+ str r2,[sp,#15*4]
+ eor r2,r10,r11
+ add r4,r4,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r9
+ add r4,r4,r3 @ h+=K256[i]
+ eor r2,r2,r11 @ Ch(e,f,g)
+ eor r0,r5,r5,ror#11
+ add r4,r4,r2 @ h+=Ch(e,f,g)
+#if 15==31
+ and r3,r3,#0xff
+ cmp r3,#0xf2 @ done?
+#endif
+#if 15<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r5,r6 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#1*4] @ from future BODY_16_xx
+ eor r3,r5,r6 @ a^b, b^c in next round
+ ldr r1,[sp,#14*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r5,ror#20 @ Sigma0(a)
+ and r12,r12,r3 @ (b^c)&=(a^b)
+ add r8,r8,r4 @ d+=h
+ eor r12,r12,r6 @ Maj(a,b,c)
+ add r4,r4,r0,ror#2 @ h+=Sigma0(a)
+ @ add r4,r4,r12 @ h+=Maj(a,b,c)
+.Lrounds_16_xx:
+ @ ldr r2,[sp,#1*4] @ 16
+ @ ldr r1,[sp,#14*4]
+ mov r0,r2,ror#7
+ add r4,r4,r12 @ h+=Maj(a,b,c) from the past
+ mov r12,r1,ror#17
+ eor r0,r0,r2,ror#18
+ eor r12,r12,r1,ror#19
+ eor r0,r0,r2,lsr#3 @ sigma0(X[i+1])
+ ldr r2,[sp,#0*4]
+ eor r12,r12,r1,lsr#10 @ sigma1(X[i+14])
+ ldr r1,[sp,#9*4]
+
+ add r12,r12,r0
+ eor r0,r8,r8,ror#5 @ from BODY_00_15
+ add r2,r2,r12
+ eor r0,r0,r8,ror#19 @ Sigma1(e)
+ add r2,r2,r1 @ X[i]
+ ldr r12,[r14],#4 @ *K256++
+ add r11,r11,r2 @ h+=X[i]
+ str r2,[sp,#0*4]
+ eor r2,r9,r10
+ add r11,r11,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r8
+ add r11,r11,r12 @ h+=K256[i]
+ eor r2,r2,r10 @ Ch(e,f,g)
+ eor r0,r4,r4,ror#11
+ add r11,r11,r2 @ h+=Ch(e,f,g)
+#if 16==31
+ and r12,r12,#0xff
+ cmp r12,#0xf2 @ done?
+#endif
+#if 16<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r12,r4,r5 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#2*4] @ from future BODY_16_xx
+ eor r12,r4,r5 @ a^b, b^c in next round
+ ldr r1,[sp,#15*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r4,ror#20 @ Sigma0(a)
+ and r3,r3,r12 @ (b^c)&=(a^b)
+ add r7,r7,r11 @ d+=h
+ eor r3,r3,r5 @ Maj(a,b,c)
+ add r11,r11,r0,ror#2 @ h+=Sigma0(a)
+ @ add r11,r11,r3 @ h+=Maj(a,b,c)
+ @ ldr r2,[sp,#2*4] @ 17
+ @ ldr r1,[sp,#15*4]
+ mov r0,r2,ror#7
+ add r11,r11,r3 @ h+=Maj(a,b,c) from the past
+ mov r3,r1,ror#17
+ eor r0,r0,r2,ror#18
+ eor r3,r3,r1,ror#19
+ eor r0,r0,r2,lsr#3 @ sigma0(X[i+1])
+ ldr r2,[sp,#1*4]
+ eor r3,r3,r1,lsr#10 @ sigma1(X[i+14])
+ ldr r1,[sp,#10*4]
+
+ add r3,r3,r0
+ eor r0,r7,r7,ror#5 @ from BODY_00_15
+ add r2,r2,r3
+ eor r0,r0,r7,ror#19 @ Sigma1(e)
+ add r2,r2,r1 @ X[i]
+ ldr r3,[r14],#4 @ *K256++
+ add r10,r10,r2 @ h+=X[i]
+ str r2,[sp,#1*4]
+ eor r2,r8,r9
+ add r10,r10,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r7
+ add r10,r10,r3 @ h+=K256[i]
+ eor r2,r2,r9 @ Ch(e,f,g)
+ eor r0,r11,r11,ror#11
+ add r10,r10,r2 @ h+=Ch(e,f,g)
+#if 17==31
+ and r3,r3,#0xff
+ cmp r3,#0xf2 @ done?
+#endif
+#if 17<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r11,r4 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#3*4] @ from future BODY_16_xx
+ eor r3,r11,r4 @ a^b, b^c in next round
+ ldr r1,[sp,#0*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r11,ror#20 @ Sigma0(a)
+ and r12,r12,r3 @ (b^c)&=(a^b)
+ add r6,r6,r10 @ d+=h
+ eor r12,r12,r4 @ Maj(a,b,c)
+ add r10,r10,r0,ror#2 @ h+=Sigma0(a)
+ @ add r10,r10,r12 @ h+=Maj(a,b,c)
+ @ ldr r2,[sp,#3*4] @ 18
+ @ ldr r1,[sp,#0*4]
+ mov r0,r2,ror#7
+ add r10,r10,r12 @ h+=Maj(a,b,c) from the past
+ mov r12,r1,ror#17
+ eor r0,r0,r2,ror#18
+ eor r12,r12,r1,ror#19
+ eor r0,r0,r2,lsr#3 @ sigma0(X[i+1])
+ ldr r2,[sp,#2*4]
+ eor r12,r12,r1,lsr#10 @ sigma1(X[i+14])
+ ldr r1,[sp,#11*4]
+
+ add r12,r12,r0
+ eor r0,r6,r6,ror#5 @ from BODY_00_15
+ add r2,r2,r12
+ eor r0,r0,r6,ror#19 @ Sigma1(e)
+ add r2,r2,r1 @ X[i]
+ ldr r12,[r14],#4 @ *K256++
+ add r9,r9,r2 @ h+=X[i]
+ str r2,[sp,#2*4]
+ eor r2,r7,r8
+ add r9,r9,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r6
+ add r9,r9,r12 @ h+=K256[i]
+ eor r2,r2,r8 @ Ch(e,f,g)
+ eor r0,r10,r10,ror#11
+ add r9,r9,r2 @ h+=Ch(e,f,g)
+#if 18==31
+ and r12,r12,#0xff
+ cmp r12,#0xf2 @ done?
+#endif
+#if 18<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r12,r10,r11 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#4*4] @ from future BODY_16_xx
+ eor r12,r10,r11 @ a^b, b^c in next round
+ ldr r1,[sp,#1*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r10,ror#20 @ Sigma0(a)
+ and r3,r3,r12 @ (b^c)&=(a^b)
+ add r5,r5,r9 @ d+=h
+ eor r3,r3,r11 @ Maj(a,b,c)
+ add r9,r9,r0,ror#2 @ h+=Sigma0(a)
+ @ add r9,r9,r3 @ h+=Maj(a,b,c)
+ @ ldr r2,[sp,#4*4] @ 19
+ @ ldr r1,[sp,#1*4]
+ mov r0,r2,ror#7
+ add r9,r9,r3 @ h+=Maj(a,b,c) from the past
+ mov r3,r1,ror#17
+ eor r0,r0,r2,ror#18
+ eor r3,r3,r1,ror#19
+ eor r0,r0,r2,lsr#3 @ sigma0(X[i+1])
+ ldr r2,[sp,#3*4]
+ eor r3,r3,r1,lsr#10 @ sigma1(X[i+14])
+ ldr r1,[sp,#12*4]
+
+ add r3,r3,r0
+ eor r0,r5,r5,ror#5 @ from BODY_00_15
+ add r2,r2,r3
+ eor r0,r0,r5,ror#19 @ Sigma1(e)
+ add r2,r2,r1 @ X[i]
+ ldr r3,[r14],#4 @ *K256++
+ add r8,r8,r2 @ h+=X[i]
+ str r2,[sp,#3*4]
+ eor r2,r6,r7
+ add r8,r8,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r5
+ add r8,r8,r3 @ h+=K256[i]
+ eor r2,r2,r7 @ Ch(e,f,g)
+ eor r0,r9,r9,ror#11
+ add r8,r8,r2 @ h+=Ch(e,f,g)
+#if 19==31
+ and r3,r3,#0xff
+ cmp r3,#0xf2 @ done?
+#endif
+#if 19<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r9,r10 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#5*4] @ from future BODY_16_xx
+ eor r3,r9,r10 @ a^b, b^c in next round
+ ldr r1,[sp,#2*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r9,ror#20 @ Sigma0(a)
+ and r12,r12,r3 @ (b^c)&=(a^b)
+ add r4,r4,r8 @ d+=h
+ eor r12,r12,r10 @ Maj(a,b,c)
+ add r8,r8,r0,ror#2 @ h+=Sigma0(a)
+ @ add r8,r8,r12 @ h+=Maj(a,b,c)
+ @ ldr r2,[sp,#5*4] @ 20
+ @ ldr r1,[sp,#2*4]
+ mov r0,r2,ror#7
+ add r8,r8,r12 @ h+=Maj(a,b,c) from the past
+ mov r12,r1,ror#17
+ eor r0,r0,r2,ror#18
+ eor r12,r12,r1,ror#19
+ eor r0,r0,r2,lsr#3 @ sigma0(X[i+1])
+ ldr r2,[sp,#4*4]
+ eor r12,r12,r1,lsr#10 @ sigma1(X[i+14])
+ ldr r1,[sp,#13*4]
+
+ add r12,r12,r0
+ eor r0,r4,r4,ror#5 @ from BODY_00_15
+ add r2,r2,r12
+ eor r0,r0,r4,ror#19 @ Sigma1(e)
+ add r2,r2,r1 @ X[i]
+ ldr r12,[r14],#4 @ *K256++
+ add r7,r7,r2 @ h+=X[i]
+ str r2,[sp,#4*4]
+ eor r2,r5,r6
+ add r7,r7,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r4
+ add r7,r7,r12 @ h+=K256[i]
+ eor r2,r2,r6 @ Ch(e,f,g)
+ eor r0,r8,r8,ror#11
+ add r7,r7,r2 @ h+=Ch(e,f,g)
+#if 20==31
+ and r12,r12,#0xff
+ cmp r12,#0xf2 @ done?
+#endif
+#if 20<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r12,r8,r9 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#6*4] @ from future BODY_16_xx
+ eor r12,r8,r9 @ a^b, b^c in next round
+ ldr r1,[sp,#3*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r8,ror#20 @ Sigma0(a)
+ and r3,r3,r12 @ (b^c)&=(a^b)
+ add r11,r11,r7 @ d+=h
+ eor r3,r3,r9 @ Maj(a,b,c)
+ add r7,r7,r0,ror#2 @ h+=Sigma0(a)
+ @ add r7,r7,r3 @ h+=Maj(a,b,c)
+ @ ldr r2,[sp,#6*4] @ 21
+ @ ldr r1,[sp,#3*4]
+ mov r0,r2,ror#7
+ add r7,r7,r3 @ h+=Maj(a,b,c) from the past
+ mov r3,r1,ror#17
+ eor r0,r0,r2,ror#18
+ eor r3,r3,r1,ror#19
+ eor r0,r0,r2,lsr#3 @ sigma0(X[i+1])
+ ldr r2,[sp,#5*4]
+ eor r3,r3,r1,lsr#10 @ sigma1(X[i+14])
+ ldr r1,[sp,#14*4]
+
+ add r3,r3,r0
+ eor r0,r11,r11,ror#5 @ from BODY_00_15
+ add r2,r2,r3
+ eor r0,r0,r11,ror#19 @ Sigma1(e)
+ add r2,r2,r1 @ X[i]
+ ldr r3,[r14],#4 @ *K256++
+ add r6,r6,r2 @ h+=X[i]
+ str r2,[sp,#5*4]
+ eor r2,r4,r5
+ add r6,r6,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r11
+ add r6,r6,r3 @ h+=K256[i]
+ eor r2,r2,r5 @ Ch(e,f,g)
+ eor r0,r7,r7,ror#11
+ add r6,r6,r2 @ h+=Ch(e,f,g)
+#if 21==31
+ and r3,r3,#0xff
+ cmp r3,#0xf2 @ done?
+#endif
+#if 21<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r7,r8 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#7*4] @ from future BODY_16_xx
+ eor r3,r7,r8 @ a^b, b^c in next round
+ ldr r1,[sp,#4*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r7,ror#20 @ Sigma0(a)
+ and r12,r12,r3 @ (b^c)&=(a^b)
+ add r10,r10,r6 @ d+=h
+ eor r12,r12,r8 @ Maj(a,b,c)
+ add r6,r6,r0,ror#2 @ h+=Sigma0(a)
+ @ add r6,r6,r12 @ h+=Maj(a,b,c)
+ @ ldr r2,[sp,#7*4] @ 22
+ @ ldr r1,[sp,#4*4]
+ mov r0,r2,ror#7
+ add r6,r6,r12 @ h+=Maj(a,b,c) from the past
+ mov r12,r1,ror#17
+ eor r0,r0,r2,ror#18
+ eor r12,r12,r1,ror#19
+ eor r0,r0,r2,lsr#3 @ sigma0(X[i+1])
+ ldr r2,[sp,#6*4]
+ eor r12,r12,r1,lsr#10 @ sigma1(X[i+14])
+ ldr r1,[sp,#15*4]
+
+ add r12,r12,r0
+ eor r0,r10,r10,ror#5 @ from BODY_00_15
+ add r2,r2,r12
+ eor r0,r0,r10,ror#19 @ Sigma1(e)
+ add r2,r2,r1 @ X[i]
+ ldr r12,[r14],#4 @ *K256++
+ add r5,r5,r2 @ h+=X[i]
+ str r2,[sp,#6*4]
+ eor r2,r11,r4
+ add r5,r5,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r10
+ add r5,r5,r12 @ h+=K256[i]
+ eor r2,r2,r4 @ Ch(e,f,g)
+ eor r0,r6,r6,ror#11
+ add r5,r5,r2 @ h+=Ch(e,f,g)
+#if 22==31
+ and r12,r12,#0xff
+ cmp r12,#0xf2 @ done?
+#endif
+#if 22<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r12,r6,r7 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#8*4] @ from future BODY_16_xx
+ eor r12,r6,r7 @ a^b, b^c in next round
+ ldr r1,[sp,#5*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r6,ror#20 @ Sigma0(a)
+ and r3,r3,r12 @ (b^c)&=(a^b)
+ add r9,r9,r5 @ d+=h
+ eor r3,r3,r7 @ Maj(a,b,c)
+ add r5,r5,r0,ror#2 @ h+=Sigma0(a)
+ @ add r5,r5,r3 @ h+=Maj(a,b,c)
+ @ ldr r2,[sp,#8*4] @ 23
+ @ ldr r1,[sp,#5*4]
+ mov r0,r2,ror#7
+ add r5,r5,r3 @ h+=Maj(a,b,c) from the past
+ mov r3,r1,ror#17
+ eor r0,r0,r2,ror#18
+ eor r3,r3,r1,ror#19
+ eor r0,r0,r2,lsr#3 @ sigma0(X[i+1])
+ ldr r2,[sp,#7*4]
+ eor r3,r3,r1,lsr#10 @ sigma1(X[i+14])
+ ldr r1,[sp,#0*4]
+
+ add r3,r3,r0
+ eor r0,r9,r9,ror#5 @ from BODY_00_15
+ add r2,r2,r3
+ eor r0,r0,r9,ror#19 @ Sigma1(e)
+ add r2,r2,r1 @ X[i]
+ ldr r3,[r14],#4 @ *K256++
+ add r4,r4,r2 @ h+=X[i]
+ str r2,[sp,#7*4]
+ eor r2,r10,r11
+ add r4,r4,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r9
+ add r4,r4,r3 @ h+=K256[i]
+ eor r2,r2,r11 @ Ch(e,f,g)
+ eor r0,r5,r5,ror#11
+ add r4,r4,r2 @ h+=Ch(e,f,g)
+#if 23==31
+ and r3,r3,#0xff
+ cmp r3,#0xf2 @ done?
+#endif
+#if 23<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r5,r6 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#9*4] @ from future BODY_16_xx
+ eor r3,r5,r6 @ a^b, b^c in next round
+ ldr r1,[sp,#6*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r5,ror#20 @ Sigma0(a)
+ and r12,r12,r3 @ (b^c)&=(a^b)
+ add r8,r8,r4 @ d+=h
+ eor r12,r12,r6 @ Maj(a,b,c)
+ add r4,r4,r0,ror#2 @ h+=Sigma0(a)
+ @ add r4,r4,r12 @ h+=Maj(a,b,c)
+ @ ldr r2,[sp,#9*4] @ 24
+ @ ldr r1,[sp,#6*4]
+ mov r0,r2,ror#7
+ add r4,r4,r12 @ h+=Maj(a,b,c) from the past
+ mov r12,r1,ror#17
+ eor r0,r0,r2,ror#18
+ eor r12,r12,r1,ror#19
+ eor r0,r0,r2,lsr#3 @ sigma0(X[i+1])
+ ldr r2,[sp,#8*4]
+ eor r12,r12,r1,lsr#10 @ sigma1(X[i+14])
+ ldr r1,[sp,#1*4]
+
+ add r12,r12,r0
+ eor r0,r8,r8,ror#5 @ from BODY_00_15
+ add r2,r2,r12
+ eor r0,r0,r8,ror#19 @ Sigma1(e)
+ add r2,r2,r1 @ X[i]
+ ldr r12,[r14],#4 @ *K256++
+ add r11,r11,r2 @ h+=X[i]
+ str r2,[sp,#8*4]
+ eor r2,r9,r10
+ add r11,r11,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r8
+ add r11,r11,r12 @ h+=K256[i]
+ eor r2,r2,r10 @ Ch(e,f,g)
+ eor r0,r4,r4,ror#11
+ add r11,r11,r2 @ h+=Ch(e,f,g)
+#if 24==31
+ and r12,r12,#0xff
+ cmp r12,#0xf2 @ done?
+#endif
+#if 24<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r12,r4,r5 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#10*4] @ from future BODY_16_xx
+ eor r12,r4,r5 @ a^b, b^c in next round
+ ldr r1,[sp,#7*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r4,ror#20 @ Sigma0(a)
+ and r3,r3,r12 @ (b^c)&=(a^b)
+ add r7,r7,r11 @ d+=h
+ eor r3,r3,r5 @ Maj(a,b,c)
+ add r11,r11,r0,ror#2 @ h+=Sigma0(a)
+ @ add r11,r11,r3 @ h+=Maj(a,b,c)
+ @ ldr r2,[sp,#10*4] @ 25
+ @ ldr r1,[sp,#7*4]
+ mov r0,r2,ror#7
+ add r11,r11,r3 @ h+=Maj(a,b,c) from the past
+ mov r3,r1,ror#17
+ eor r0,r0,r2,ror#18
+ eor r3,r3,r1,ror#19
+ eor r0,r0,r2,lsr#3 @ sigma0(X[i+1])
+ ldr r2,[sp,#9*4]
+ eor r3,r3,r1,lsr#10 @ sigma1(X[i+14])
+ ldr r1,[sp,#2*4]
+
+ add r3,r3,r0
+ eor r0,r7,r7,ror#5 @ from BODY_00_15
+ add r2,r2,r3
+ eor r0,r0,r7,ror#19 @ Sigma1(e)
+ add r2,r2,r1 @ X[i]
+ ldr r3,[r14],#4 @ *K256++
+ add r10,r10,r2 @ h+=X[i]
+ str r2,[sp,#9*4]
+ eor r2,r8,r9
+ add r10,r10,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r7
+ add r10,r10,r3 @ h+=K256[i]
+ eor r2,r2,r9 @ Ch(e,f,g)
+ eor r0,r11,r11,ror#11
+ add r10,r10,r2 @ h+=Ch(e,f,g)
+#if 25==31
+ and r3,r3,#0xff
+ cmp r3,#0xf2 @ done?
+#endif
+#if 25<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r11,r4 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#11*4] @ from future BODY_16_xx
+ eor r3,r11,r4 @ a^b, b^c in next round
+ ldr r1,[sp,#8*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r11,ror#20 @ Sigma0(a)
+ and r12,r12,r3 @ (b^c)&=(a^b)
+ add r6,r6,r10 @ d+=h
+ eor r12,r12,r4 @ Maj(a,b,c)
+ add r10,r10,r0,ror#2 @ h+=Sigma0(a)
+ @ add r10,r10,r12 @ h+=Maj(a,b,c)
+ @ ldr r2,[sp,#11*4] @ 26
+ @ ldr r1,[sp,#8*4]
+ mov r0,r2,ror#7
+ add r10,r10,r12 @ h+=Maj(a,b,c) from the past
+ mov r12,r1,ror#17
+ eor r0,r0,r2,ror#18
+ eor r12,r12,r1,ror#19
+ eor r0,r0,r2,lsr#3 @ sigma0(X[i+1])
+ ldr r2,[sp,#10*4]
+ eor r12,r12,r1,lsr#10 @ sigma1(X[i+14])
+ ldr r1,[sp,#3*4]
+
+ add r12,r12,r0
+ eor r0,r6,r6,ror#5 @ from BODY_00_15
+ add r2,r2,r12
+ eor r0,r0,r6,ror#19 @ Sigma1(e)
+ add r2,r2,r1 @ X[i]
+ ldr r12,[r14],#4 @ *K256++
+ add r9,r9,r2 @ h+=X[i]
+ str r2,[sp,#10*4]
+ eor r2,r7,r8
+ add r9,r9,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r6
+ add r9,r9,r12 @ h+=K256[i]
+ eor r2,r2,r8 @ Ch(e,f,g)
+ eor r0,r10,r10,ror#11
+ add r9,r9,r2 @ h+=Ch(e,f,g)
+#if 26==31
+ and r12,r12,#0xff
+ cmp r12,#0xf2 @ done?
+#endif
+#if 26<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r12,r10,r11 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#12*4] @ from future BODY_16_xx
+ eor r12,r10,r11 @ a^b, b^c in next round
+ ldr r1,[sp,#9*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r10,ror#20 @ Sigma0(a)
+ and r3,r3,r12 @ (b^c)&=(a^b)
+ add r5,r5,r9 @ d+=h
+ eor r3,r3,r11 @ Maj(a,b,c)
+ add r9,r9,r0,ror#2 @ h+=Sigma0(a)
+ @ add r9,r9,r3 @ h+=Maj(a,b,c)
+ @ ldr r2,[sp,#12*4] @ 27
+ @ ldr r1,[sp,#9*4]
+ mov r0,r2,ror#7
+ add r9,r9,r3 @ h+=Maj(a,b,c) from the past
+ mov r3,r1,ror#17
+ eor r0,r0,r2,ror#18
+ eor r3,r3,r1,ror#19
+ eor r0,r0,r2,lsr#3 @ sigma0(X[i+1])
+ ldr r2,[sp,#11*4]
+ eor r3,r3,r1,lsr#10 @ sigma1(X[i+14])
+ ldr r1,[sp,#4*4]
+
+ add r3,r3,r0
+ eor r0,r5,r5,ror#5 @ from BODY_00_15
+ add r2,r2,r3
+ eor r0,r0,r5,ror#19 @ Sigma1(e)
+ add r2,r2,r1 @ X[i]
+ ldr r3,[r14],#4 @ *K256++
+ add r8,r8,r2 @ h+=X[i]
+ str r2,[sp,#11*4]
+ eor r2,r6,r7
+ add r8,r8,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r5
+ add r8,r8,r3 @ h+=K256[i]
+ eor r2,r2,r7 @ Ch(e,f,g)
+ eor r0,r9,r9,ror#11
+ add r8,r8,r2 @ h+=Ch(e,f,g)
+#if 27==31
+ and r3,r3,#0xff
+ cmp r3,#0xf2 @ done?
+#endif
+#if 27<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r9,r10 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#13*4] @ from future BODY_16_xx
+ eor r3,r9,r10 @ a^b, b^c in next round
+ ldr r1,[sp,#10*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r9,ror#20 @ Sigma0(a)
+ and r12,r12,r3 @ (b^c)&=(a^b)
+ add r4,r4,r8 @ d+=h
+ eor r12,r12,r10 @ Maj(a,b,c)
+ add r8,r8,r0,ror#2 @ h+=Sigma0(a)
+ @ add r8,r8,r12 @ h+=Maj(a,b,c)
+ @ ldr r2,[sp,#13*4] @ 28
+ @ ldr r1,[sp,#10*4]
+ mov r0,r2,ror#7
+ add r8,r8,r12 @ h+=Maj(a,b,c) from the past
+ mov r12,r1,ror#17
+ eor r0,r0,r2,ror#18
+ eor r12,r12,r1,ror#19
+ eor r0,r0,r2,lsr#3 @ sigma0(X[i+1])
+ ldr r2,[sp,#12*4]
+ eor r12,r12,r1,lsr#10 @ sigma1(X[i+14])
+ ldr r1,[sp,#5*4]
+
+ add r12,r12,r0
+ eor r0,r4,r4,ror#5 @ from BODY_00_15
+ add r2,r2,r12
+ eor r0,r0,r4,ror#19 @ Sigma1(e)
+ add r2,r2,r1 @ X[i]
+ ldr r12,[r14],#4 @ *K256++
+ add r7,r7,r2 @ h+=X[i]
+ str r2,[sp,#12*4]
+ eor r2,r5,r6
+ add r7,r7,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r4
+ add r7,r7,r12 @ h+=K256[i]
+ eor r2,r2,r6 @ Ch(e,f,g)
+ eor r0,r8,r8,ror#11
+ add r7,r7,r2 @ h+=Ch(e,f,g)
+#if 28==31
+ and r12,r12,#0xff
+ cmp r12,#0xf2 @ done?
+#endif
+#if 28<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r12,r8,r9 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#14*4] @ from future BODY_16_xx
+ eor r12,r8,r9 @ a^b, b^c in next round
+ ldr r1,[sp,#11*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r8,ror#20 @ Sigma0(a)
+ and r3,r3,r12 @ (b^c)&=(a^b)
+ add r11,r11,r7 @ d+=h
+ eor r3,r3,r9 @ Maj(a,b,c)
+ add r7,r7,r0,ror#2 @ h+=Sigma0(a)
+ @ add r7,r7,r3 @ h+=Maj(a,b,c)
+ @ ldr r2,[sp,#14*4] @ 29
+ @ ldr r1,[sp,#11*4]
+ mov r0,r2,ror#7
+ add r7,r7,r3 @ h+=Maj(a,b,c) from the past
+ mov r3,r1,ror#17
+ eor r0,r0,r2,ror#18
+ eor r3,r3,r1,ror#19
+ eor r0,r0,r2,lsr#3 @ sigma0(X[i+1])
+ ldr r2,[sp,#13*4]
+ eor r3,r3,r1,lsr#10 @ sigma1(X[i+14])
+ ldr r1,[sp,#6*4]
+
+ add r3,r3,r0
+ eor r0,r11,r11,ror#5 @ from BODY_00_15
+ add r2,r2,r3
+ eor r0,r0,r11,ror#19 @ Sigma1(e)
+ add r2,r2,r1 @ X[i]
+ ldr r3,[r14],#4 @ *K256++
+ add r6,r6,r2 @ h+=X[i]
+ str r2,[sp,#13*4]
+ eor r2,r4,r5
+ add r6,r6,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r11
+ add r6,r6,r3 @ h+=K256[i]
+ eor r2,r2,r5 @ Ch(e,f,g)
+ eor r0,r7,r7,ror#11
+ add r6,r6,r2 @ h+=Ch(e,f,g)
+#if 29==31
+ and r3,r3,#0xff
+ cmp r3,#0xf2 @ done?
+#endif
+#if 29<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r7,r8 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#15*4] @ from future BODY_16_xx
+ eor r3,r7,r8 @ a^b, b^c in next round
+ ldr r1,[sp,#12*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r7,ror#20 @ Sigma0(a)
+ and r12,r12,r3 @ (b^c)&=(a^b)
+ add r10,r10,r6 @ d+=h
+ eor r12,r12,r8 @ Maj(a,b,c)
+ add r6,r6,r0,ror#2 @ h+=Sigma0(a)
+ @ add r6,r6,r12 @ h+=Maj(a,b,c)
+ @ ldr r2,[sp,#15*4] @ 30
+ @ ldr r1,[sp,#12*4]
+ mov r0,r2,ror#7
+ add r6,r6,r12 @ h+=Maj(a,b,c) from the past
+ mov r12,r1,ror#17
+ eor r0,r0,r2,ror#18
+ eor r12,r12,r1,ror#19
+ eor r0,r0,r2,lsr#3 @ sigma0(X[i+1])
+ ldr r2,[sp,#14*4]
+ eor r12,r12,r1,lsr#10 @ sigma1(X[i+14])
+ ldr r1,[sp,#7*4]
+
+ add r12,r12,r0
+ eor r0,r10,r10,ror#5 @ from BODY_00_15
+ add r2,r2,r12
+ eor r0,r0,r10,ror#19 @ Sigma1(e)
+ add r2,r2,r1 @ X[i]
+ ldr r12,[r14],#4 @ *K256++
+ add r5,r5,r2 @ h+=X[i]
+ str r2,[sp,#14*4]
+ eor r2,r11,r4
+ add r5,r5,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r10
+ add r5,r5,r12 @ h+=K256[i]
+ eor r2,r2,r4 @ Ch(e,f,g)
+ eor r0,r6,r6,ror#11
+ add r5,r5,r2 @ h+=Ch(e,f,g)
+#if 30==31
+ and r12,r12,#0xff
+ cmp r12,#0xf2 @ done?
+#endif
+#if 30<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r12,r6,r7 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#0*4] @ from future BODY_16_xx
+ eor r12,r6,r7 @ a^b, b^c in next round
+ ldr r1,[sp,#13*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r6,ror#20 @ Sigma0(a)
+ and r3,r3,r12 @ (b^c)&=(a^b)
+ add r9,r9,r5 @ d+=h
+ eor r3,r3,r7 @ Maj(a,b,c)
+ add r5,r5,r0,ror#2 @ h+=Sigma0(a)
+ @ add r5,r5,r3 @ h+=Maj(a,b,c)
+ @ ldr r2,[sp,#0*4] @ 31
+ @ ldr r1,[sp,#13*4]
+ mov r0,r2,ror#7
+ add r5,r5,r3 @ h+=Maj(a,b,c) from the past
+ mov r3,r1,ror#17
+ eor r0,r0,r2,ror#18
+ eor r3,r3,r1,ror#19
+ eor r0,r0,r2,lsr#3 @ sigma0(X[i+1])
+ ldr r2,[sp,#15*4]
+ eor r3,r3,r1,lsr#10 @ sigma1(X[i+14])
+ ldr r1,[sp,#8*4]
+
+ add r3,r3,r0
+ eor r0,r9,r9,ror#5 @ from BODY_00_15
+ add r2,r2,r3
+ eor r0,r0,r9,ror#19 @ Sigma1(e)
+ add r2,r2,r1 @ X[i]
+ ldr r3,[r14],#4 @ *K256++
+ add r4,r4,r2 @ h+=X[i]
+ str r2,[sp,#15*4]
+ eor r2,r10,r11
+ add r4,r4,r0,ror#6 @ h+=Sigma1(e)
+ and r2,r2,r9
+ add r4,r4,r3 @ h+=K256[i]
+ eor r2,r2,r11 @ Ch(e,f,g)
+ eor r0,r5,r5,ror#11
+ add r4,r4,r2 @ h+=Ch(e,f,g)
+#if 31==31
+ and r3,r3,#0xff
+ cmp r3,#0xf2 @ done?
+#endif
+#if 31<15
+# if __ARM_ARCH__>=7
+ ldr r2,[r1],#4 @ prefetch
+# else
+ ldrb r2,[r1,#3]
+# endif
+ eor r3,r5,r6 @ a^b, b^c in next round
+#else
+ ldr r2,[sp,#1*4] @ from future BODY_16_xx
+ eor r3,r5,r6 @ a^b, b^c in next round
+ ldr r1,[sp,#14*4] @ from future BODY_16_xx
+#endif
+ eor r0,r0,r5,ror#20 @ Sigma0(a)
+ and r12,r12,r3 @ (b^c)&=(a^b)
+ add r8,r8,r4 @ d+=h
+ eor r12,r12,r6 @ Maj(a,b,c)
+ add r4,r4,r0,ror#2 @ h+=Sigma0(a)
+ @ add r4,r4,r12 @ h+=Maj(a,b,c)
+#if __ARM_ARCH__>=7
+ ite eq @ Thumb2 thing, sanity check in ARM
+#endif
+ ldreq r3,[sp,#16*4] @ pull ctx
+ bne .Lrounds_16_xx
+
+ add r4,r4,r12 @ h+=Maj(a,b,c) from the past
+ ldr r0,[r3,#0]
+ ldr r2,[r3,#4]
+ ldr r12,[r3,#8]
+ add r4,r4,r0
+ ldr r0,[r3,#12]
+ add r5,r5,r2
+ ldr r2,[r3,#16]
+ add r6,r6,r12
+ ldr r12,[r3,#20]
+ add r7,r7,r0
+ ldr r0,[r3,#24]
+ add r8,r8,r2
+ ldr r2,[r3,#28]
+ add r9,r9,r12
+ ldr r1,[sp,#17*4] @ pull inp
+ ldr r12,[sp,#18*4] @ pull inp+len
+ add r10,r10,r0
+ add r11,r11,r2
+ stmia r3,{r4,r5,r6,r7,r8,r9,r10,r11}
+ cmp r1,r12
+ sub r14,r14,#256 @ rewind Ktbl
+ bne .Loop
+
+ add sp,sp,#19*4 @ destroy frame
+#if __ARM_ARCH__>=5
+ ldmia sp!,{r4-r11,pc}
+#else
+ ldmia sp!,{r4-r11,lr}
+ tst lr,#1
+ moveq pc,lr @ be binary compatible with V4, yet
+ .word 0xe12fff1e @ interoperable with Thumb ISA:-)
+#endif
+.size sha256_block_data_order,.-sha256_block_data_order
+#if __ARM_MAX_ARCH__>=7
+.arch armv7-a
+.fpu neon
+
+.global sha256_block_data_order_neon
+.type sha256_block_data_order_neon,%function
+.align 4
+sha256_block_data_order_neon:
+.LNEON:
+ stmdb sp!,{r4-r12,lr}
+
+ sub r11,sp,#16*4+16
+ adrl r14,K256
+ bic r11,r11,#15 @ align for 128-bit stores
+ mov r12,sp
+ mov sp,r11 @ alloca
+ add r2,r1,r2,lsl#6 @ len to point at the end of inp
+
+ vld1.8 {q0},[r1]!
+ vld1.8 {q1},[r1]!
+ vld1.8 {q2},[r1]!
+ vld1.8 {q3},[r1]!
+ vld1.32 {q8},[r14,:128]!
+ vld1.32 {q9},[r14,:128]!
+ vld1.32 {q10},[r14,:128]!
+ vld1.32 {q11},[r14,:128]!
+ vrev32.8 q0,q0 @ yes, even on
+ str r0,[sp,#64]
+ vrev32.8 q1,q1 @ big-endian
+ str r1,[sp,#68]
+ mov r1,sp
+ vrev32.8 q2,q2
+ str r2,[sp,#72]
+ vrev32.8 q3,q3
+ str r12,[sp,#76] @ save original sp
+ vadd.i32 q8,q8,q0
+ vadd.i32 q9,q9,q1
+ vst1.32 {q8},[r1,:128]!
+ vadd.i32 q10,q10,q2
+ vst1.32 {q9},[r1,:128]!
+ vadd.i32 q11,q11,q3
+ vst1.32 {q10},[r1,:128]!
+ vst1.32 {q11},[r1,:128]!
+
+ ldmia r0,{r4-r11}
+ sub r1,r1,#64
+ ldr r2,[sp,#0]
+ eor r12,r12,r12
+ eor r3,r5,r6
+ b .L_00_48
+
+.align 4
+.L_00_48:
+ vext.8 q8,q0,q1,#4
+ add r11,r11,r2
+ eor r2,r9,r10
+ eor r0,r8,r8,ror#5
+ vext.8 q9,q2,q3,#4
+ add r4,r4,r12
+ and r2,r2,r8
+ eor r12,r0,r8,ror#19
+ vshr.u32 q10,q8,#7
+ eor r0,r4,r4,ror#11
+ eor r2,r2,r10
+ vadd.i32 q0,q0,q9
+ add r11,r11,r12,ror#6
+ eor r12,r4,r5
+ vshr.u32 q9,q8,#3
+ eor r0,r0,r4,ror#20
+ add r11,r11,r2
+ vsli.32 q10,q8,#25
+ ldr r2,[sp,#4]
+ and r3,r3,r12
+ vshr.u32 q11,q8,#18
+ add r7,r7,r11
+ add r11,r11,r0,ror#2
+ eor r3,r3,r5
+ veor q9,q9,q10
+ add r10,r10,r2
+ vsli.32 q11,q8,#14
+ eor r2,r8,r9
+ eor r0,r7,r7,ror#5
+ vshr.u32 d24,d7,#17
+ add r11,r11,r3
+ and r2,r2,r7
+ veor q9,q9,q11
+ eor r3,r0,r7,ror#19
+ eor r0,r11,r11,ror#11
+ vsli.32 d24,d7,#15
+ eor r2,r2,r9
+ add r10,r10,r3,ror#6
+ vshr.u32 d25,d7,#10
+ eor r3,r11,r4
+ eor r0,r0,r11,ror#20
+ vadd.i32 q0,q0,q9
+ add r10,r10,r2
+ ldr r2,[sp,#8]
+ veor d25,d25,d24
+ and r12,r12,r3
+ add r6,r6,r10
+ vshr.u32 d24,d7,#19
+ add r10,r10,r0,ror#2
+ eor r12,r12,r4
+ vsli.32 d24,d7,#13
+ add r9,r9,r2
+ eor r2,r7,r8
+ veor d25,d25,d24
+ eor r0,r6,r6,ror#5
+ add r10,r10,r12
+ vadd.i32 d0,d0,d25
+ and r2,r2,r6
+ eor r12,r0,r6,ror#19
+ vshr.u32 d24,d0,#17
+ eor r0,r10,r10,ror#11
+ eor r2,r2,r8
+ vsli.32 d24,d0,#15
+ add r9,r9,r12,ror#6
+ eor r12,r10,r11
+ vshr.u32 d25,d0,#10
+ eor r0,r0,r10,ror#20
+ add r9,r9,r2
+ veor d25,d25,d24
+ ldr r2,[sp,#12]
+ and r3,r3,r12
+ vshr.u32 d24,d0,#19
+ add r5,r5,r9
+ add r9,r9,r0,ror#2
+ eor r3,r3,r11
+ vld1.32 {q8},[r14,:128]!
+ add r8,r8,r2
+ vsli.32 d24,d0,#13
+ eor r2,r6,r7
+ eor r0,r5,r5,ror#5
+ veor d25,d25,d24
+ add r9,r9,r3
+ and r2,r2,r5
+ vadd.i32 d1,d1,d25
+ eor r3,r0,r5,ror#19
+ eor r0,r9,r9,ror#11
+ vadd.i32 q8,q8,q0
+ eor r2,r2,r7
+ add r8,r8,r3,ror#6
+ eor r3,r9,r10
+ eor r0,r0,r9,ror#20
+ add r8,r8,r2
+ ldr r2,[sp,#16]
+ and r12,r12,r3
+ add r4,r4,r8
+ vst1.32 {q8},[r1,:128]!
+ add r8,r8,r0,ror#2
+ eor r12,r12,r10
+ vext.8 q8,q1,q2,#4
+ add r7,r7,r2
+ eor r2,r5,r6
+ eor r0,r4,r4,ror#5
+ vext.8 q9,q3,q0,#4
+ add r8,r8,r12
+ and r2,r2,r4
+ eor r12,r0,r4,ror#19
+ vshr.u32 q10,q8,#7
+ eor r0,r8,r8,ror#11
+ eor r2,r2,r6
+ vadd.i32 q1,q1,q9
+ add r7,r7,r12,ror#6
+ eor r12,r8,r9
+ vshr.u32 q9,q8,#3
+ eor r0,r0,r8,ror#20
+ add r7,r7,r2
+ vsli.32 q10,q8,#25
+ ldr r2,[sp,#20]
+ and r3,r3,r12
+ vshr.u32 q11,q8,#18
+ add r11,r11,r7
+ add r7,r7,r0,ror#2
+ eor r3,r3,r9
+ veor q9,q9,q10
+ add r6,r6,r2
+ vsli.32 q11,q8,#14
+ eor r2,r4,r5
+ eor r0,r11,r11,ror#5
+ vshr.u32 d24,d1,#17
+ add r7,r7,r3
+ and r2,r2,r11
+ veor q9,q9,q11
+ eor r3,r0,r11,ror#19
+ eor r0,r7,r7,ror#11
+ vsli.32 d24,d1,#15
+ eor r2,r2,r5
+ add r6,r6,r3,ror#6
+ vshr.u32 d25,d1,#10
+ eor r3,r7,r8
+ eor r0,r0,r7,ror#20
+ vadd.i32 q1,q1,q9
+ add r6,r6,r2
+ ldr r2,[sp,#24]
+ veor d25,d25,d24
+ and r12,r12,r3
+ add r10,r10,r6
+ vshr.u32 d24,d1,#19
+ add r6,r6,r0,ror#2
+ eor r12,r12,r8
+ vsli.32 d24,d1,#13
+ add r5,r5,r2
+ eor r2,r11,r4
+ veor d25,d25,d24
+ eor r0,r10,r10,ror#5
+ add r6,r6,r12
+ vadd.i32 d2,d2,d25
+ and r2,r2,r10
+ eor r12,r0,r10,ror#19
+ vshr.u32 d24,d2,#17
+ eor r0,r6,r6,ror#11
+ eor r2,r2,r4
+ vsli.32 d24,d2,#15
+ add r5,r5,r12,ror#6
+ eor r12,r6,r7
+ vshr.u32 d25,d2,#10
+ eor r0,r0,r6,ror#20
+ add r5,r5,r2
+ veor d25,d25,d24
+ ldr r2,[sp,#28]
+ and r3,r3,r12
+ vshr.u32 d24,d2,#19
+ add r9,r9,r5
+ add r5,r5,r0,ror#2
+ eor r3,r3,r7
+ vld1.32 {q8},[r14,:128]!
+ add r4,r4,r2
+ vsli.32 d24,d2,#13
+ eor r2,r10,r11
+ eor r0,r9,r9,ror#5
+ veor d25,d25,d24
+ add r5,r5,r3
+ and r2,r2,r9
+ vadd.i32 d3,d3,d25
+ eor r3,r0,r9,ror#19
+ eor r0,r5,r5,ror#11
+ vadd.i32 q8,q8,q1
+ eor r2,r2,r11
+ add r4,r4,r3,ror#6
+ eor r3,r5,r6
+ eor r0,r0,r5,ror#20
+ add r4,r4,r2
+ ldr r2,[sp,#32]
+ and r12,r12,r3
+ add r8,r8,r4
+ vst1.32 {q8},[r1,:128]!
+ add r4,r4,r0,ror#2
+ eor r12,r12,r6
+ vext.8 q8,q2,q3,#4
+ add r11,r11,r2
+ eor r2,r9,r10
+ eor r0,r8,r8,ror#5
+ vext.8 q9,q0,q1,#4
+ add r4,r4,r12
+ and r2,r2,r8
+ eor r12,r0,r8,ror#19
+ vshr.u32 q10,q8,#7
+ eor r0,r4,r4,ror#11
+ eor r2,r2,r10
+ vadd.i32 q2,q2,q9
+ add r11,r11,r12,ror#6
+ eor r12,r4,r5
+ vshr.u32 q9,q8,#3
+ eor r0,r0,r4,ror#20
+ add r11,r11,r2
+ vsli.32 q10,q8,#25
+ ldr r2,[sp,#36]
+ and r3,r3,r12
+ vshr.u32 q11,q8,#18
+ add r7,r7,r11
+ add r11,r11,r0,ror#2
+ eor r3,r3,r5
+ veor q9,q9,q10
+ add r10,r10,r2
+ vsli.32 q11,q8,#14
+ eor r2,r8,r9
+ eor r0,r7,r7,ror#5
+ vshr.u32 d24,d3,#17
+ add r11,r11,r3
+ and r2,r2,r7
+ veor q9,q9,q11
+ eor r3,r0,r7,ror#19
+ eor r0,r11,r11,ror#11
+ vsli.32 d24,d3,#15
+ eor r2,r2,r9
+ add r10,r10,r3,ror#6
+ vshr.u32 d25,d3,#10
+ eor r3,r11,r4
+ eor r0,r0,r11,ror#20
+ vadd.i32 q2,q2,q9
+ add r10,r10,r2
+ ldr r2,[sp,#40]
+ veor d25,d25,d24
+ and r12,r12,r3
+ add r6,r6,r10
+ vshr.u32 d24,d3,#19
+ add r10,r10,r0,ror#2
+ eor r12,r12,r4
+ vsli.32 d24,d3,#13
+ add r9,r9,r2
+ eor r2,r7,r8
+ veor d25,d25,d24
+ eor r0,r6,r6,ror#5
+ add r10,r10,r12
+ vadd.i32 d4,d4,d25
+ and r2,r2,r6
+ eor r12,r0,r6,ror#19
+ vshr.u32 d24,d4,#17
+ eor r0,r10,r10,ror#11
+ eor r2,r2,r8
+ vsli.32 d24,d4,#15
+ add r9,r9,r12,ror#6
+ eor r12,r10,r11
+ vshr.u32 d25,d4,#10
+ eor r0,r0,r10,ror#20
+ add r9,r9,r2
+ veor d25,d25,d24
+ ldr r2,[sp,#44]
+ and r3,r3,r12
+ vshr.u32 d24,d4,#19
+ add r5,r5,r9
+ add r9,r9,r0,ror#2
+ eor r3,r3,r11
+ vld1.32 {q8},[r14,:128]!
+ add r8,r8,r2
+ vsli.32 d24,d4,#13
+ eor r2,r6,r7
+ eor r0,r5,r5,ror#5
+ veor d25,d25,d24
+ add r9,r9,r3
+ and r2,r2,r5
+ vadd.i32 d5,d5,d25
+ eor r3,r0,r5,ror#19
+ eor r0,r9,r9,ror#11
+ vadd.i32 q8,q8,q2
+ eor r2,r2,r7
+ add r8,r8,r3,ror#6
+ eor r3,r9,r10
+ eor r0,r0,r9,ror#20
+ add r8,r8,r2
+ ldr r2,[sp,#48]
+ and r12,r12,r3
+ add r4,r4,r8
+ vst1.32 {q8},[r1,:128]!
+ add r8,r8,r0,ror#2
+ eor r12,r12,r10
+ vext.8 q8,q3,q0,#4
+ add r7,r7,r2
+ eor r2,r5,r6
+ eor r0,r4,r4,ror#5
+ vext.8 q9,q1,q2,#4
+ add r8,r8,r12
+ and r2,r2,r4
+ eor r12,r0,r4,ror#19
+ vshr.u32 q10,q8,#7
+ eor r0,r8,r8,ror#11
+ eor r2,r2,r6
+ vadd.i32 q3,q3,q9
+ add r7,r7,r12,ror#6
+ eor r12,r8,r9
+ vshr.u32 q9,q8,#3
+ eor r0,r0,r8,ror#20
+ add r7,r7,r2
+ vsli.32 q10,q8,#25
+ ldr r2,[sp,#52]
+ and r3,r3,r12
+ vshr.u32 q11,q8,#18
+ add r11,r11,r7
+ add r7,r7,r0,ror#2
+ eor r3,r3,r9
+ veor q9,q9,q10
+ add r6,r6,r2
+ vsli.32 q11,q8,#14
+ eor r2,r4,r5
+ eor r0,r11,r11,ror#5
+ vshr.u32 d24,d5,#17
+ add r7,r7,r3
+ and r2,r2,r11
+ veor q9,q9,q11
+ eor r3,r0,r11,ror#19
+ eor r0,r7,r7,ror#11
+ vsli.32 d24,d5,#15
+ eor r2,r2,r5
+ add r6,r6,r3,ror#6
+ vshr.u32 d25,d5,#10
+ eor r3,r7,r8
+ eor r0,r0,r7,ror#20
+ vadd.i32 q3,q3,q9
+ add r6,r6,r2
+ ldr r2,[sp,#56]
+ veor d25,d25,d24
+ and r12,r12,r3
+ add r10,r10,r6
+ vshr.u32 d24,d5,#19
+ add r6,r6,r0,ror#2
+ eor r12,r12,r8
+ vsli.32 d24,d5,#13
+ add r5,r5,r2
+ eor r2,r11,r4
+ veor d25,d25,d24
+ eor r0,r10,r10,ror#5
+ add r6,r6,r12
+ vadd.i32 d6,d6,d25
+ and r2,r2,r10
+ eor r12,r0,r10,ror#19
+ vshr.u32 d24,d6,#17
+ eor r0,r6,r6,ror#11
+ eor r2,r2,r4
+ vsli.32 d24,d6,#15
+ add r5,r5,r12,ror#6
+ eor r12,r6,r7
+ vshr.u32 d25,d6,#10
+ eor r0,r0,r6,ror#20
+ add r5,r5,r2
+ veor d25,d25,d24
+ ldr r2,[sp,#60]
+ and r3,r3,r12
+ vshr.u32 d24,d6,#19
+ add r9,r9,r5
+ add r5,r5,r0,ror#2
+ eor r3,r3,r7
+ vld1.32 {q8},[r14,:128]!
+ add r4,r4,r2
+ vsli.32 d24,d6,#13
+ eor r2,r10,r11
+ eor r0,r9,r9,ror#5
+ veor d25,d25,d24
+ add r5,r5,r3
+ and r2,r2,r9
+ vadd.i32 d7,d7,d25
+ eor r3,r0,r9,ror#19
+ eor r0,r5,r5,ror#11
+ vadd.i32 q8,q8,q3
+ eor r2,r2,r11
+ add r4,r4,r3,ror#6
+ eor r3,r5,r6
+ eor r0,r0,r5,ror#20
+ add r4,r4,r2
+ ldr r2,[r14]
+ and r12,r12,r3
+ add r8,r8,r4
+ vst1.32 {q8},[r1,:128]!
+ add r4,r4,r0,ror#2
+ eor r12,r12,r6
+ teq r2,#0 @ check for K256 terminator
+ ldr r2,[sp,#0]
+ sub r1,r1,#64
+ bne .L_00_48
+
+ ldr r1,[sp,#68]
+ ldr r0,[sp,#72]
+ sub r14,r14,#256 @ rewind r14
+ teq r1,r0
+ it eq
+ subeq r1,r1,#64 @ avoid SEGV
+ vld1.8 {q0},[r1]! @ load next input block
+ vld1.8 {q1},[r1]!
+ vld1.8 {q2},[r1]!
+ vld1.8 {q3},[r1]!
+ it ne
+ strne r1,[sp,#68]
+ mov r1,sp
+ add r11,r11,r2
+ eor r2,r9,r10
+ eor r0,r8,r8,ror#5
+ add r4,r4,r12
+ vld1.32 {q8},[r14,:128]!
+ and r2,r2,r8
+ eor r12,r0,r8,ror#19
+ eor r0,r4,r4,ror#11
+ eor r2,r2,r10
+ vrev32.8 q0,q0
+ add r11,r11,r12,ror#6
+ eor r12,r4,r5
+ eor r0,r0,r4,ror#20
+ add r11,r11,r2
+ vadd.i32 q8,q8,q0
+ ldr r2,[sp,#4]
+ and r3,r3,r12
+ add r7,r7,r11
+ add r11,r11,r0,ror#2
+ eor r3,r3,r5
+ add r10,r10,r2
+ eor r2,r8,r9
+ eor r0,r7,r7,ror#5
+ add r11,r11,r3
+ and r2,r2,r7
+ eor r3,r0,r7,ror#19
+ eor r0,r11,r11,ror#11
+ eor r2,r2,r9
+ add r10,r10,r3,ror#6
+ eor r3,r11,r4
+ eor r0,r0,r11,ror#20
+ add r10,r10,r2
+ ldr r2,[sp,#8]
+ and r12,r12,r3
+ add r6,r6,r10
+ add r10,r10,r0,ror#2
+ eor r12,r12,r4
+ add r9,r9,r2
+ eor r2,r7,r8
+ eor r0,r6,r6,ror#5
+ add r10,r10,r12
+ and r2,r2,r6
+ eor r12,r0,r6,ror#19
+ eor r0,r10,r10,ror#11
+ eor r2,r2,r8
+ add r9,r9,r12,ror#6
+ eor r12,r10,r11
+ eor r0,r0,r10,ror#20
+ add r9,r9,r2
+ ldr r2,[sp,#12]
+ and r3,r3,r12
+ add r5,r5,r9
+ add r9,r9,r0,ror#2
+ eor r3,r3,r11
+ add r8,r8,r2
+ eor r2,r6,r7
+ eor r0,r5,r5,ror#5
+ add r9,r9,r3
+ and r2,r2,r5
+ eor r3,r0,r5,ror#19
+ eor r0,r9,r9,ror#11
+ eor r2,r2,r7
+ add r8,r8,r3,ror#6
+ eor r3,r9,r10
+ eor r0,r0,r9,ror#20
+ add r8,r8,r2
+ ldr r2,[sp,#16]
+ and r12,r12,r3
+ add r4,r4,r8
+ add r8,r8,r0,ror#2
+ eor r12,r12,r10
+ vst1.32 {q8},[r1,:128]!
+ add r7,r7,r2
+ eor r2,r5,r6
+ eor r0,r4,r4,ror#5
+ add r8,r8,r12
+ vld1.32 {q8},[r14,:128]!
+ and r2,r2,r4
+ eor r12,r0,r4,ror#19
+ eor r0,r8,r8,ror#11
+ eor r2,r2,r6
+ vrev32.8 q1,q1
+ add r7,r7,r12,ror#6
+ eor r12,r8,r9
+ eor r0,r0,r8,ror#20
+ add r7,r7,r2
+ vadd.i32 q8,q8,q1
+ ldr r2,[sp,#20]
+ and r3,r3,r12
+ add r11,r11,r7
+ add r7,r7,r0,ror#2
+ eor r3,r3,r9
+ add r6,r6,r2
+ eor r2,r4,r5
+ eor r0,r11,r11,ror#5
+ add r7,r7,r3
+ and r2,r2,r11
+ eor r3,r0,r11,ror#19
+ eor r0,r7,r7,ror#11
+ eor r2,r2,r5
+ add r6,r6,r3,ror#6
+ eor r3,r7,r8
+ eor r0,r0,r7,ror#20
+ add r6,r6,r2
+ ldr r2,[sp,#24]
+ and r12,r12,r3
+ add r10,r10,r6
+ add r6,r6,r0,ror#2
+ eor r12,r12,r8
+ add r5,r5,r2
+ eor r2,r11,r4
+ eor r0,r10,r10,ror#5
+ add r6,r6,r12
+ and r2,r2,r10
+ eor r12,r0,r10,ror#19
+ eor r0,r6,r6,ror#11
+ eor r2,r2,r4
+ add r5,r5,r12,ror#6
+ eor r12,r6,r7
+ eor r0,r0,r6,ror#20
+ add r5,r5,r2
+ ldr r2,[sp,#28]
+ and r3,r3,r12
+ add r9,r9,r5
+ add r5,r5,r0,ror#2
+ eor r3,r3,r7
+ add r4,r4,r2
+ eor r2,r10,r11
+ eor r0,r9,r9,ror#5
+ add r5,r5,r3
+ and r2,r2,r9
+ eor r3,r0,r9,ror#19
+ eor r0,r5,r5,ror#11
+ eor r2,r2,r11
+ add r4,r4,r3,ror#6
+ eor r3,r5,r6
+ eor r0,r0,r5,ror#20
+ add r4,r4,r2
+ ldr r2,[sp,#32]
+ and r12,r12,r3
+ add r8,r8,r4
+ add r4,r4,r0,ror#2
+ eor r12,r12,r6
+ vst1.32 {q8},[r1,:128]!
+ add r11,r11,r2
+ eor r2,r9,r10
+ eor r0,r8,r8,ror#5
+ add r4,r4,r12
+ vld1.32 {q8},[r14,:128]!
+ and r2,r2,r8
+ eor r12,r0,r8,ror#19
+ eor r0,r4,r4,ror#11
+ eor r2,r2,r10
+ vrev32.8 q2,q2
+ add r11,r11,r12,ror#6
+ eor r12,r4,r5
+ eor r0,r0,r4,ror#20
+ add r11,r11,r2
+ vadd.i32 q8,q8,q2
+ ldr r2,[sp,#36]
+ and r3,r3,r12
+ add r7,r7,r11
+ add r11,r11,r0,ror#2
+ eor r3,r3,r5
+ add r10,r10,r2
+ eor r2,r8,r9
+ eor r0,r7,r7,ror#5
+ add r11,r11,r3
+ and r2,r2,r7
+ eor r3,r0,r7,ror#19
+ eor r0,r11,r11,ror#11
+ eor r2,r2,r9
+ add r10,r10,r3,ror#6
+ eor r3,r11,r4
+ eor r0,r0,r11,ror#20
+ add r10,r10,r2
+ ldr r2,[sp,#40]
+ and r12,r12,r3
+ add r6,r6,r10
+ add r10,r10,r0,ror#2
+ eor r12,r12,r4
+ add r9,r9,r2
+ eor r2,r7,r8
+ eor r0,r6,r6,ror#5
+ add r10,r10,r12
+ and r2,r2,r6
+ eor r12,r0,r6,ror#19
+ eor r0,r10,r10,ror#11
+ eor r2,r2,r8
+ add r9,r9,r12,ror#6
+ eor r12,r10,r11
+ eor r0,r0,r10,ror#20
+ add r9,r9,r2
+ ldr r2,[sp,#44]
+ and r3,r3,r12
+ add r5,r5,r9
+ add r9,r9,r0,ror#2
+ eor r3,r3,r11
+ add r8,r8,r2
+ eor r2,r6,r7
+ eor r0,r5,r5,ror#5
+ add r9,r9,r3
+ and r2,r2,r5
+ eor r3,r0,r5,ror#19
+ eor r0,r9,r9,ror#11
+ eor r2,r2,r7
+ add r8,r8,r3,ror#6
+ eor r3,r9,r10
+ eor r0,r0,r9,ror#20
+ add r8,r8,r2
+ ldr r2,[sp,#48]
+ and r12,r12,r3
+ add r4,r4,r8
+ add r8,r8,r0,ror#2
+ eor r12,r12,r10
+ vst1.32 {q8},[r1,:128]!
+ add r7,r7,r2
+ eor r2,r5,r6
+ eor r0,r4,r4,ror#5
+ add r8,r8,r12
+ vld1.32 {q8},[r14,:128]!
+ and r2,r2,r4
+ eor r12,r0,r4,ror#19
+ eor r0,r8,r8,ror#11
+ eor r2,r2,r6
+ vrev32.8 q3,q3
+ add r7,r7,r12,ror#6
+ eor r12,r8,r9
+ eor r0,r0,r8,ror#20
+ add r7,r7,r2
+ vadd.i32 q8,q8,q3
+ ldr r2,[sp,#52]
+ and r3,r3,r12
+ add r11,r11,r7
+ add r7,r7,r0,ror#2
+ eor r3,r3,r9
+ add r6,r6,r2
+ eor r2,r4,r5
+ eor r0,r11,r11,ror#5
+ add r7,r7,r3
+ and r2,r2,r11
+ eor r3,r0,r11,ror#19
+ eor r0,r7,r7,ror#11
+ eor r2,r2,r5
+ add r6,r6,r3,ror#6
+ eor r3,r7,r8
+ eor r0,r0,r7,ror#20
+ add r6,r6,r2
+ ldr r2,[sp,#56]
+ and r12,r12,r3
+ add r10,r10,r6
+ add r6,r6,r0,ror#2
+ eor r12,r12,r8
+ add r5,r5,r2
+ eor r2,r11,r4
+ eor r0,r10,r10,ror#5
+ add r6,r6,r12
+ and r2,r2,r10
+ eor r12,r0,r10,ror#19
+ eor r0,r6,r6,ror#11
+ eor r2,r2,r4
+ add r5,r5,r12,ror#6
+ eor r12,r6,r7
+ eor r0,r0,r6,ror#20
+ add r5,r5,r2
+ ldr r2,[sp,#60]
+ and r3,r3,r12
+ add r9,r9,r5
+ add r5,r5,r0,ror#2
+ eor r3,r3,r7
+ add r4,r4,r2
+ eor r2,r10,r11
+ eor r0,r9,r9,ror#5
+ add r5,r5,r3
+ and r2,r2,r9
+ eor r3,r0,r9,ror#19
+ eor r0,r5,r5,ror#11
+ eor r2,r2,r11
+ add r4,r4,r3,ror#6
+ eor r3,r5,r6
+ eor r0,r0,r5,ror#20
+ add r4,r4,r2
+ ldr r2,[sp,#64]
+ and r12,r12,r3
+ add r8,r8,r4
+ add r4,r4,r0,ror#2
+ eor r12,r12,r6
+ vst1.32 {q8},[r1,:128]!
+ ldr r0,[r2,#0]
+ add r4,r4,r12 @ h+=Maj(a,b,c) from the past
+ ldr r12,[r2,#4]
+ ldr r3,[r2,#8]
+ ldr r1,[r2,#12]
+ add r4,r4,r0 @ accumulate
+ ldr r0,[r2,#16]
+ add r5,r5,r12
+ ldr r12,[r2,#20]
+ add r6,r6,r3
+ ldr r3,[r2,#24]
+ add r7,r7,r1
+ ldr r1,[r2,#28]
+ add r8,r8,r0
+ str r4,[r2],#4
+ add r9,r9,r12
+ str r5,[r2],#4
+ add r10,r10,r3
+ str r6,[r2],#4
+ add r11,r11,r1
+ str r7,[r2],#4
+ stmia r2,{r8-r11}
+
+ ittte ne
+ movne r1,sp
+ ldrne r2,[sp,#0]
+ eorne r12,r12,r12
+ ldreq sp,[sp,#76] @ restore original sp
+ itt ne
+ eorne r3,r5,r6
+ bne .L_00_48
+
+ ldmia sp!,{r4-r12,pc}
+.size sha256_block_data_order_neon,.-sha256_block_data_order_neon
+#endif
+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
+
+# ifdef __thumb2__
+# define INST(a,b,c,d) .byte c,d|0xc,a,b
+# else
+# define INST(a,b,c,d) .byte a,b,c,d
+# endif
+
+.type sha256_block_data_order_armv8,%function
+.align 5
+sha256_block_data_order_armv8:
+.LARMv8:
+ vld1.32 {q0,q1},[r0]
+# ifdef __thumb2__
+ adr r3,.LARMv8
+ sub r3,r3,#.LARMv8-K256
+# else
+ adrl r3,K256
+# endif
+ add r2,r1,r2,lsl#6 @ len to point at the end of inp
+
+.Loop_v8:
+ vld1.8 {q8-q9},[r1]!
+ vld1.8 {q10-q11},[r1]!
+ vld1.32 {q12},[r3]!
+ vrev32.8 q8,q8
+ vrev32.8 q9,q9
+ vrev32.8 q10,q10
+ vrev32.8 q11,q11
+ vmov q14,q0 @ offload
+ vmov q15,q1
+ teq r1,r2
+ vld1.32 {q13},[r3]!
+ vadd.i32 q12,q12,q8
+ INST(0xe2,0x03,0xfa,0xf3) @ sha256su0 q8,q9
+ vmov q2,q0
+ INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12
+ INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12
+ INST(0xe6,0x0c,0x64,0xf3) @ sha256su1 q8,q10,q11
+ vld1.32 {q12},[r3]!
+ vadd.i32 q13,q13,q9
+ INST(0xe4,0x23,0xfa,0xf3) @ sha256su0 q9,q10
+ vmov q2,q0
+ INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13
+ INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13
+ INST(0xe0,0x2c,0x66,0xf3) @ sha256su1 q9,q11,q8
+ vld1.32 {q13},[r3]!
+ vadd.i32 q12,q12,q10
+ INST(0xe6,0x43,0xfa,0xf3) @ sha256su0 q10,q11
+ vmov q2,q0
+ INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12
+ INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12
+ INST(0xe2,0x4c,0x60,0xf3) @ sha256su1 q10,q8,q9
+ vld1.32 {q12},[r3]!
+ vadd.i32 q13,q13,q11
+ INST(0xe0,0x63,0xfa,0xf3) @ sha256su0 q11,q8
+ vmov q2,q0
+ INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13
+ INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13
+ INST(0xe4,0x6c,0x62,0xf3) @ sha256su1 q11,q9,q10
+ vld1.32 {q13},[r3]!
+ vadd.i32 q12,q12,q8
+ INST(0xe2,0x03,0xfa,0xf3) @ sha256su0 q8,q9
+ vmov q2,q0
+ INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12
+ INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12
+ INST(0xe6,0x0c,0x64,0xf3) @ sha256su1 q8,q10,q11
+ vld1.32 {q12},[r3]!
+ vadd.i32 q13,q13,q9
+ INST(0xe4,0x23,0xfa,0xf3) @ sha256su0 q9,q10
+ vmov q2,q0
+ INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13
+ INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13
+ INST(0xe0,0x2c,0x66,0xf3) @ sha256su1 q9,q11,q8
+ vld1.32 {q13},[r3]!
+ vadd.i32 q12,q12,q10
+ INST(0xe6,0x43,0xfa,0xf3) @ sha256su0 q10,q11
+ vmov q2,q0
+ INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12
+ INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12
+ INST(0xe2,0x4c,0x60,0xf3) @ sha256su1 q10,q8,q9
+ vld1.32 {q12},[r3]!
+ vadd.i32 q13,q13,q11
+ INST(0xe0,0x63,0xfa,0xf3) @ sha256su0 q11,q8
+ vmov q2,q0
+ INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13
+ INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13
+ INST(0xe4,0x6c,0x62,0xf3) @ sha256su1 q11,q9,q10
+ vld1.32 {q13},[r3]!
+ vadd.i32 q12,q12,q8
+ INST(0xe2,0x03,0xfa,0xf3) @ sha256su0 q8,q9
+ vmov q2,q0
+ INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12
+ INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12
+ INST(0xe6,0x0c,0x64,0xf3) @ sha256su1 q8,q10,q11
+ vld1.32 {q12},[r3]!
+ vadd.i32 q13,q13,q9
+ INST(0xe4,0x23,0xfa,0xf3) @ sha256su0 q9,q10
+ vmov q2,q0
+ INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13
+ INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13
+ INST(0xe0,0x2c,0x66,0xf3) @ sha256su1 q9,q11,q8
+ vld1.32 {q13},[r3]!
+ vadd.i32 q12,q12,q10
+ INST(0xe6,0x43,0xfa,0xf3) @ sha256su0 q10,q11
+ vmov q2,q0
+ INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12
+ INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12
+ INST(0xe2,0x4c,0x60,0xf3) @ sha256su1 q10,q8,q9
+ vld1.32 {q12},[r3]!
+ vadd.i32 q13,q13,q11
+ INST(0xe0,0x63,0xfa,0xf3) @ sha256su0 q11,q8
+ vmov q2,q0
+ INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13
+ INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13
+ INST(0xe4,0x6c,0x62,0xf3) @ sha256su1 q11,q9,q10
+ vld1.32 {q13},[r3]!
+ vadd.i32 q12,q12,q8
+ vmov q2,q0
+ INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12
+ INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12
+
+ vld1.32 {q12},[r3]!
+ vadd.i32 q13,q13,q9
+ vmov q2,q0
+ INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13
+ INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13
+
+ vld1.32 {q13},[r3]
+ vadd.i32 q12,q12,q10
+ sub r3,r3,#256-16 @ rewind
+ vmov q2,q0
+ INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12
+ INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12
+
+ vadd.i32 q13,q13,q11
+ vmov q2,q0
+ INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13
+ INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13
+
+ vadd.i32 q0,q0,q14
+ vadd.i32 q1,q1,q15
+ it ne
+ bne .Loop_v8
+
+ vst1.32 {q0,q1},[r0]
+
+ bx lr @ bx lr
+.size sha256_block_data_order_armv8,.-sha256_block_data_order_armv8
+#endif
+.asciz "SHA256 block transform for ARMv4/NEON/ARMv8, CRYPTOGAMS by <appro@openssl.org>"
+.align 2
+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
+.comm OPENSSL_armcap_P,4,4
+#endif
diff --git a/arch/arm/crypto/sha256_glue.c b/arch/arm/crypto/sha256_glue.c
new file mode 100644
index 000000000..a84e869ef
--- /dev/null
+++ b/arch/arm/crypto/sha256_glue.c
@@ -0,0 +1,128 @@
+/*
+ * Glue code for the SHA256 Secure Hash Algorithm assembly implementation
+ * using optimized ARM assembler and NEON instructions.
+ *
+ * Copyright © 2015 Google Inc.
+ *
+ * This file is based on sha256_ssse3_glue.c:
+ * Copyright (C) 2013 Intel Corporation
+ * Author: Tim Chen <tim.c.chen@linux.intel.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 <crypto/internal/hash.h>
+#include <linux/crypto.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/cryptohash.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <crypto/sha.h>
+#include <crypto/sha256_base.h>
+#include <asm/simd.h>
+#include <asm/neon.h>
+
+#include "sha256_glue.h"
+
+asmlinkage void sha256_block_data_order(u32 *digest, const void *data,
+ unsigned int num_blks);
+
+int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ /* make sure casting to sha256_block_fn() is safe */
+ BUILD_BUG_ON(offsetof(struct sha256_state, state) != 0);
+
+ return sha256_base_do_update(desc, data, len,
+ (sha256_block_fn *)sha256_block_data_order);
+}
+EXPORT_SYMBOL(crypto_sha256_arm_update);
+
+static int sha256_final(struct shash_desc *desc, u8 *out)
+{
+ sha256_base_do_finalize(desc,
+ (sha256_block_fn *)sha256_block_data_order);
+ return sha256_base_finish(desc, out);
+}
+
+int crypto_sha256_arm_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ sha256_base_do_update(desc, data, len,
+ (sha256_block_fn *)sha256_block_data_order);
+ return sha256_final(desc, out);
+}
+EXPORT_SYMBOL(crypto_sha256_arm_finup);
+
+static struct shash_alg algs[] = { {
+ .digestsize = SHA256_DIGEST_SIZE,
+ .init = sha256_base_init,
+ .update = crypto_sha256_arm_update,
+ .final = sha256_final,
+ .finup = crypto_sha256_arm_finup,
+ .descsize = sizeof(struct sha256_state),
+ .base = {
+ .cra_name = "sha256",
+ .cra_driver_name = "sha256-asm",
+ .cra_priority = 150,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA256_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+}, {
+ .digestsize = SHA224_DIGEST_SIZE,
+ .init = sha224_base_init,
+ .update = crypto_sha256_arm_update,
+ .final = sha256_final,
+ .finup = crypto_sha256_arm_finup,
+ .descsize = sizeof(struct sha256_state),
+ .base = {
+ .cra_name = "sha224",
+ .cra_driver_name = "sha224-asm",
+ .cra_priority = 150,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA224_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+} };
+
+static int __init sha256_mod_init(void)
+{
+ int res = crypto_register_shashes(algs, ARRAY_SIZE(algs));
+
+ if (res < 0)
+ return res;
+
+ if (IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && cpu_has_neon()) {
+ res = crypto_register_shashes(sha256_neon_algs,
+ ARRAY_SIZE(sha256_neon_algs));
+
+ if (res < 0)
+ crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
+ }
+
+ return res;
+}
+
+static void __exit sha256_mod_fini(void)
+{
+ crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
+
+ if (IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && cpu_has_neon())
+ crypto_unregister_shashes(sha256_neon_algs,
+ ARRAY_SIZE(sha256_neon_algs));
+}
+
+module_init(sha256_mod_init);
+module_exit(sha256_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm (ARM), including NEON");
+
+MODULE_ALIAS_CRYPTO("sha256");
diff --git a/arch/arm/crypto/sha256_glue.h b/arch/arm/crypto/sha256_glue.h
new file mode 100644
index 000000000..7cf0bf786
--- /dev/null
+++ b/arch/arm/crypto/sha256_glue.h
@@ -0,0 +1,14 @@
+#ifndef _CRYPTO_SHA256_GLUE_H
+#define _CRYPTO_SHA256_GLUE_H
+
+#include <linux/crypto.h>
+
+extern struct shash_alg sha256_neon_algs[2];
+
+int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len);
+
+int crypto_sha256_arm_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *hash);
+
+#endif /* _CRYPTO_SHA256_GLUE_H */
diff --git a/arch/arm/crypto/sha256_neon_glue.c b/arch/arm/crypto/sha256_neon_glue.c
new file mode 100644
index 000000000..39ccd6588
--- /dev/null
+++ b/arch/arm/crypto/sha256_neon_glue.c
@@ -0,0 +1,101 @@
+/*
+ * Glue code for the SHA256 Secure Hash Algorithm assembly implementation
+ * using NEON instructions.
+ *
+ * Copyright © 2015 Google Inc.
+ *
+ * This file is based on sha512_neon_glue.c:
+ * Copyright © 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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 <crypto/internal/hash.h>
+#include <linux/cryptohash.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <crypto/sha.h>
+#include <crypto/sha256_base.h>
+#include <asm/byteorder.h>
+#include <asm/simd.h>
+#include <asm/neon.h>
+
+#include "sha256_glue.h"
+
+asmlinkage void sha256_block_data_order_neon(u32 *digest, const void *data,
+ unsigned int num_blks);
+
+static int sha256_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ struct sha256_state *sctx = shash_desc_ctx(desc);
+
+ if (!may_use_simd() ||
+ (sctx->count % SHA256_BLOCK_SIZE) + len < SHA256_BLOCK_SIZE)
+ return crypto_sha256_arm_update(desc, data, len);
+
+ kernel_neon_begin();
+ sha256_base_do_update(desc, data, len,
+ (sha256_block_fn *)sha256_block_data_order_neon);
+ kernel_neon_end();
+
+ return 0;
+}
+
+static int sha256_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ if (!may_use_simd())
+ return crypto_sha256_arm_finup(desc, data, len, out);
+
+ kernel_neon_begin();
+ if (len)
+ sha256_base_do_update(desc, data, len,
+ (sha256_block_fn *)sha256_block_data_order_neon);
+ sha256_base_do_finalize(desc,
+ (sha256_block_fn *)sha256_block_data_order_neon);
+ kernel_neon_end();
+
+ return sha256_base_finish(desc, out);
+}
+
+static int sha256_final(struct shash_desc *desc, u8 *out)
+{
+ return sha256_finup(desc, NULL, 0, out);
+}
+
+struct shash_alg sha256_neon_algs[] = { {
+ .digestsize = SHA256_DIGEST_SIZE,
+ .init = sha256_base_init,
+ .update = sha256_update,
+ .final = sha256_final,
+ .finup = sha256_finup,
+ .descsize = sizeof(struct sha256_state),
+ .base = {
+ .cra_name = "sha256",
+ .cra_driver_name = "sha256-neon",
+ .cra_priority = 250,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA256_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+}, {
+ .digestsize = SHA224_DIGEST_SIZE,
+ .init = sha224_base_init,
+ .update = sha256_update,
+ .final = sha256_final,
+ .finup = sha256_finup,
+ .descsize = sizeof(struct sha256_state),
+ .base = {
+ .cra_name = "sha224",
+ .cra_driver_name = "sha224-neon",
+ .cra_priority = 250,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA224_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+} };
diff --git a/arch/arm/crypto/sha512-armv7-neon.S b/arch/arm/crypto/sha512-armv7-neon.S
new file mode 100644
index 000000000..fe99472e5
--- /dev/null
+++ b/arch/arm/crypto/sha512-armv7-neon.S
@@ -0,0 +1,455 @@
+/* sha512-armv7-neon.S - ARM/NEON assembly implementation of SHA-512 transform
+ *
+ * Copyright © 2013-2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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>
+
+
+.syntax unified
+.code 32
+.fpu neon
+
+.text
+
+/* structure of SHA512_CONTEXT */
+#define hd_a 0
+#define hd_b ((hd_a) + 8)
+#define hd_c ((hd_b) + 8)
+#define hd_d ((hd_c) + 8)
+#define hd_e ((hd_d) + 8)
+#define hd_f ((hd_e) + 8)
+#define hd_g ((hd_f) + 8)
+
+/* register macros */
+#define RK %r2
+
+#define RA d0
+#define RB d1
+#define RC d2
+#define RD d3
+#define RE d4
+#define RF d5
+#define RG d6
+#define RH d7
+
+#define RT0 d8
+#define RT1 d9
+#define RT2 d10
+#define RT3 d11
+#define RT4 d12
+#define RT5 d13
+#define RT6 d14
+#define RT7 d15
+
+#define RT01q q4
+#define RT23q q5
+#define RT45q q6
+#define RT67q q7
+
+#define RW0 d16
+#define RW1 d17
+#define RW2 d18
+#define RW3 d19
+#define RW4 d20
+#define RW5 d21
+#define RW6 d22
+#define RW7 d23
+#define RW8 d24
+#define RW9 d25
+#define RW10 d26
+#define RW11 d27
+#define RW12 d28
+#define RW13 d29
+#define RW14 d30
+#define RW15 d31
+
+#define RW01q q8
+#define RW23q q9
+#define RW45q q10
+#define RW67q q11
+#define RW89q q12
+#define RW1011q q13
+#define RW1213q q14
+#define RW1415q q15
+
+/***********************************************************************
+ * ARM assembly implementation of sha512 transform
+ ***********************************************************************/
+#define rounds2_0_63(ra, rb, rc, rd, re, rf, rg, rh, rw0, rw1, rw01q, rw2, \
+ rw23q, rw1415q, rw9, rw10, interleave_op, arg1) \
+ /* t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t]; */ \
+ vshr.u64 RT2, re, #14; \
+ vshl.u64 RT3, re, #64 - 14; \
+ interleave_op(arg1); \
+ vshr.u64 RT4, re, #18; \
+ vshl.u64 RT5, re, #64 - 18; \
+ vld1.64 {RT0}, [RK]!; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT4, re, #41; \
+ vshl.u64 RT5, re, #64 - 41; \
+ vadd.u64 RT0, RT0, rw0; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vmov.64 RT7, re; \
+ veor.64 RT1, RT2, RT3; \
+ vbsl.64 RT7, rf, rg; \
+ \
+ vadd.u64 RT1, RT1, rh; \
+ vshr.u64 RT2, ra, #28; \
+ vshl.u64 RT3, ra, #64 - 28; \
+ vadd.u64 RT1, RT1, RT0; \
+ vshr.u64 RT4, ra, #34; \
+ vshl.u64 RT5, ra, #64 - 34; \
+ vadd.u64 RT1, RT1, RT7; \
+ \
+ /* h = Sum0 (a) + Maj (a, b, c); */ \
+ veor.64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT4, ra, #39; \
+ vshl.u64 RT5, ra, #64 - 39; \
+ veor.64 RT0, ra, rb; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vbsl.64 RT0, rc, rb; \
+ vadd.u64 rd, rd, RT1; /* d+=t1; */ \
+ veor.64 rh, RT2, RT3; \
+ \
+ /* t1 = g + Sum1 (d) + Ch (d, e, f) + k[t] + w[t]; */ \
+ vshr.u64 RT2, rd, #14; \
+ vshl.u64 RT3, rd, #64 - 14; \
+ vadd.u64 rh, rh, RT0; \
+ vshr.u64 RT4, rd, #18; \
+ vshl.u64 RT5, rd, #64 - 18; \
+ vadd.u64 rh, rh, RT1; /* h+=t1; */ \
+ vld1.64 {RT0}, [RK]!; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT4, rd, #41; \
+ vshl.u64 RT5, rd, #64 - 41; \
+ vadd.u64 RT0, RT0, rw1; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vmov.64 RT7, rd; \
+ veor.64 RT1, RT2, RT3; \
+ vbsl.64 RT7, re, rf; \
+ \
+ vadd.u64 RT1, RT1, rg; \
+ vshr.u64 RT2, rh, #28; \
+ vshl.u64 RT3, rh, #64 - 28; \
+ vadd.u64 RT1, RT1, RT0; \
+ vshr.u64 RT4, rh, #34; \
+ vshl.u64 RT5, rh, #64 - 34; \
+ vadd.u64 RT1, RT1, RT7; \
+ \
+ /* g = Sum0 (h) + Maj (h, a, b); */ \
+ veor.64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT4, rh, #39; \
+ vshl.u64 RT5, rh, #64 - 39; \
+ veor.64 RT0, rh, ra; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vbsl.64 RT0, rb, ra; \
+ vadd.u64 rc, rc, RT1; /* c+=t1; */ \
+ veor.64 rg, RT2, RT3; \
+ \
+ /* w[0] += S1 (w[14]) + w[9] + S0 (w[1]); */ \
+ /* w[1] += S1 (w[15]) + w[10] + S0 (w[2]); */ \
+ \
+ /**** S0(w[1:2]) */ \
+ \
+ /* w[0:1] += w[9:10] */ \
+ /* RT23q = rw1:rw2 */ \
+ vext.u64 RT23q, rw01q, rw23q, #1; \
+ vadd.u64 rw0, rw9; \
+ vadd.u64 rg, rg, RT0; \
+ vadd.u64 rw1, rw10;\
+ vadd.u64 rg, rg, RT1; /* g+=t1; */ \
+ \
+ vshr.u64 RT45q, RT23q, #1; \
+ vshl.u64 RT67q, RT23q, #64 - 1; \
+ vshr.u64 RT01q, RT23q, #8; \
+ veor.u64 RT45q, RT45q, RT67q; \
+ vshl.u64 RT67q, RT23q, #64 - 8; \
+ veor.u64 RT45q, RT45q, RT01q; \
+ vshr.u64 RT01q, RT23q, #7; \
+ veor.u64 RT45q, RT45q, RT67q; \
+ \
+ /**** S1(w[14:15]) */ \
+ vshr.u64 RT23q, rw1415q, #6; \
+ veor.u64 RT01q, RT01q, RT45q; \
+ vshr.u64 RT45q, rw1415q, #19; \
+ vshl.u64 RT67q, rw1415q, #64 - 19; \
+ veor.u64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT45q, rw1415q, #61; \
+ veor.u64 RT23q, RT23q, RT67q; \
+ vshl.u64 RT67q, rw1415q, #64 - 61; \
+ veor.u64 RT23q, RT23q, RT45q; \
+ vadd.u64 rw01q, RT01q; /* w[0:1] += S(w[1:2]) */ \
+ veor.u64 RT01q, RT23q, RT67q;
+#define vadd_RT01q(rw01q) \
+ /* w[0:1] += S(w[14:15]) */ \
+ vadd.u64 rw01q, RT01q;
+
+#define dummy(_) /*_*/
+
+#define rounds2_64_79(ra, rb, rc, rd, re, rf, rg, rh, rw0, rw1, \
+ interleave_op1, arg1, interleave_op2, arg2) \
+ /* t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t]; */ \
+ vshr.u64 RT2, re, #14; \
+ vshl.u64 RT3, re, #64 - 14; \
+ interleave_op1(arg1); \
+ vshr.u64 RT4, re, #18; \
+ vshl.u64 RT5, re, #64 - 18; \
+ interleave_op2(arg2); \
+ vld1.64 {RT0}, [RK]!; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT4, re, #41; \
+ vshl.u64 RT5, re, #64 - 41; \
+ vadd.u64 RT0, RT0, rw0; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vmov.64 RT7, re; \
+ veor.64 RT1, RT2, RT3; \
+ vbsl.64 RT7, rf, rg; \
+ \
+ vadd.u64 RT1, RT1, rh; \
+ vshr.u64 RT2, ra, #28; \
+ vshl.u64 RT3, ra, #64 - 28; \
+ vadd.u64 RT1, RT1, RT0; \
+ vshr.u64 RT4, ra, #34; \
+ vshl.u64 RT5, ra, #64 - 34; \
+ vadd.u64 RT1, RT1, RT7; \
+ \
+ /* h = Sum0 (a) + Maj (a, b, c); */ \
+ veor.64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT4, ra, #39; \
+ vshl.u64 RT5, ra, #64 - 39; \
+ veor.64 RT0, ra, rb; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vbsl.64 RT0, rc, rb; \
+ vadd.u64 rd, rd, RT1; /* d+=t1; */ \
+ veor.64 rh, RT2, RT3; \
+ \
+ /* t1 = g + Sum1 (d) + Ch (d, e, f) + k[t] + w[t]; */ \
+ vshr.u64 RT2, rd, #14; \
+ vshl.u64 RT3, rd, #64 - 14; \
+ vadd.u64 rh, rh, RT0; \
+ vshr.u64 RT4, rd, #18; \
+ vshl.u64 RT5, rd, #64 - 18; \
+ vadd.u64 rh, rh, RT1; /* h+=t1; */ \
+ vld1.64 {RT0}, [RK]!; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT4, rd, #41; \
+ vshl.u64 RT5, rd, #64 - 41; \
+ vadd.u64 RT0, RT0, rw1; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vmov.64 RT7, rd; \
+ veor.64 RT1, RT2, RT3; \
+ vbsl.64 RT7, re, rf; \
+ \
+ vadd.u64 RT1, RT1, rg; \
+ vshr.u64 RT2, rh, #28; \
+ vshl.u64 RT3, rh, #64 - 28; \
+ vadd.u64 RT1, RT1, RT0; \
+ vshr.u64 RT4, rh, #34; \
+ vshl.u64 RT5, rh, #64 - 34; \
+ vadd.u64 RT1, RT1, RT7; \
+ \
+ /* g = Sum0 (h) + Maj (h, a, b); */ \
+ veor.64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT4, rh, #39; \
+ vshl.u64 RT5, rh, #64 - 39; \
+ veor.64 RT0, rh, ra; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vbsl.64 RT0, rb, ra; \
+ vadd.u64 rc, rc, RT1; /* c+=t1; */ \
+ veor.64 rg, RT2, RT3;
+#define vadd_rg_RT0(rg) \
+ vadd.u64 rg, rg, RT0;
+#define vadd_rg_RT1(rg) \
+ vadd.u64 rg, rg, RT1; /* g+=t1; */
+
+.align 3
+ENTRY(sha512_transform_neon)
+ /* Input:
+ * %r0: SHA512_CONTEXT
+ * %r1: data
+ * %r2: u64 k[] constants
+ * %r3: nblks
+ */
+ push {%lr};
+
+ mov %lr, #0;
+
+ /* Load context to d0-d7 */
+ vld1.64 {RA-RD}, [%r0]!;
+ vld1.64 {RE-RH}, [%r0];
+ sub %r0, #(4*8);
+
+ /* Load input to w[16], d16-d31 */
+ /* NOTE: Assumes that on ARMv7 unaligned accesses are always allowed. */
+ vld1.64 {RW0-RW3}, [%r1]!;
+ vld1.64 {RW4-RW7}, [%r1]!;
+ vld1.64 {RW8-RW11}, [%r1]!;
+ vld1.64 {RW12-RW15}, [%r1]!;
+#ifdef __ARMEL__
+ /* byteswap */
+ vrev64.8 RW01q, RW01q;
+ vrev64.8 RW23q, RW23q;
+ vrev64.8 RW45q, RW45q;
+ vrev64.8 RW67q, RW67q;
+ vrev64.8 RW89q, RW89q;
+ vrev64.8 RW1011q, RW1011q;
+ vrev64.8 RW1213q, RW1213q;
+ vrev64.8 RW1415q, RW1415q;
+#endif
+
+ /* EABI says that d8-d15 must be preserved by callee. */
+ /*vpush {RT0-RT7};*/
+
+.Loop:
+ rounds2_0_63(RA, RB, RC, RD, RE, RF, RG, RH, RW0, RW1, RW01q, RW2,
+ RW23q, RW1415q, RW9, RW10, dummy, _);
+ b .Lenter_rounds;
+
+.Loop_rounds:
+ rounds2_0_63(RA, RB, RC, RD, RE, RF, RG, RH, RW0, RW1, RW01q, RW2,
+ RW23q, RW1415q, RW9, RW10, vadd_RT01q, RW1415q);
+.Lenter_rounds:
+ rounds2_0_63(RG, RH, RA, RB, RC, RD, RE, RF, RW2, RW3, RW23q, RW4,
+ RW45q, RW01q, RW11, RW12, vadd_RT01q, RW01q);
+ rounds2_0_63(RE, RF, RG, RH, RA, RB, RC, RD, RW4, RW5, RW45q, RW6,
+ RW67q, RW23q, RW13, RW14, vadd_RT01q, RW23q);
+ rounds2_0_63(RC, RD, RE, RF, RG, RH, RA, RB, RW6, RW7, RW67q, RW8,
+ RW89q, RW45q, RW15, RW0, vadd_RT01q, RW45q);
+ rounds2_0_63(RA, RB, RC, RD, RE, RF, RG, RH, RW8, RW9, RW89q, RW10,
+ RW1011q, RW67q, RW1, RW2, vadd_RT01q, RW67q);
+ rounds2_0_63(RG, RH, RA, RB, RC, RD, RE, RF, RW10, RW11, RW1011q, RW12,
+ RW1213q, RW89q, RW3, RW4, vadd_RT01q, RW89q);
+ add %lr, #16;
+ rounds2_0_63(RE, RF, RG, RH, RA, RB, RC, RD, RW12, RW13, RW1213q, RW14,
+ RW1415q, RW1011q, RW5, RW6, vadd_RT01q, RW1011q);
+ cmp %lr, #64;
+ rounds2_0_63(RC, RD, RE, RF, RG, RH, RA, RB, RW14, RW15, RW1415q, RW0,
+ RW01q, RW1213q, RW7, RW8, vadd_RT01q, RW1213q);
+ bne .Loop_rounds;
+
+ subs %r3, #1;
+
+ rounds2_64_79(RA, RB, RC, RD, RE, RF, RG, RH, RW0, RW1,
+ vadd_RT01q, RW1415q, dummy, _);
+ rounds2_64_79(RG, RH, RA, RB, RC, RD, RE, RF, RW2, RW3,
+ vadd_rg_RT0, RG, vadd_rg_RT1, RG);
+ beq .Lhandle_tail;
+ vld1.64 {RW0-RW3}, [%r1]!;
+ rounds2_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW4, RW5,
+ vadd_rg_RT0, RE, vadd_rg_RT1, RE);
+ rounds2_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW6, RW7,
+ vadd_rg_RT0, RC, vadd_rg_RT1, RC);
+#ifdef __ARMEL__
+ vrev64.8 RW01q, RW01q;
+ vrev64.8 RW23q, RW23q;
+#endif
+ vld1.64 {RW4-RW7}, [%r1]!;
+ rounds2_64_79(RA, RB, RC, RD, RE, RF, RG, RH, RW8, RW9,
+ vadd_rg_RT0, RA, vadd_rg_RT1, RA);
+ rounds2_64_79(RG, RH, RA, RB, RC, RD, RE, RF, RW10, RW11,
+ vadd_rg_RT0, RG, vadd_rg_RT1, RG);
+#ifdef __ARMEL__
+ vrev64.8 RW45q, RW45q;
+ vrev64.8 RW67q, RW67q;
+#endif
+ vld1.64 {RW8-RW11}, [%r1]!;
+ rounds2_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW12, RW13,
+ vadd_rg_RT0, RE, vadd_rg_RT1, RE);
+ rounds2_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW14, RW15,
+ vadd_rg_RT0, RC, vadd_rg_RT1, RC);
+#ifdef __ARMEL__
+ vrev64.8 RW89q, RW89q;
+ vrev64.8 RW1011q, RW1011q;
+#endif
+ vld1.64 {RW12-RW15}, [%r1]!;
+ vadd_rg_RT0(RA);
+ vadd_rg_RT1(RA);
+
+ /* Load context */
+ vld1.64 {RT0-RT3}, [%r0]!;
+ vld1.64 {RT4-RT7}, [%r0];
+ sub %r0, #(4*8);
+
+#ifdef __ARMEL__
+ vrev64.8 RW1213q, RW1213q;
+ vrev64.8 RW1415q, RW1415q;
+#endif
+
+ vadd.u64 RA, RT0;
+ vadd.u64 RB, RT1;
+ vadd.u64 RC, RT2;
+ vadd.u64 RD, RT3;
+ vadd.u64 RE, RT4;
+ vadd.u64 RF, RT5;
+ vadd.u64 RG, RT6;
+ vadd.u64 RH, RT7;
+
+ /* Store the first half of context */
+ vst1.64 {RA-RD}, [%r0]!;
+ sub RK, $(8*80);
+ vst1.64 {RE-RH}, [%r0]; /* Store the last half of context */
+ mov %lr, #0;
+ sub %r0, #(4*8);
+
+ b .Loop;
+
+.Lhandle_tail:
+ rounds2_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW4, RW5,
+ vadd_rg_RT0, RE, vadd_rg_RT1, RE);
+ rounds2_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW6, RW7,
+ vadd_rg_RT0, RC, vadd_rg_RT1, RC);
+ rounds2_64_79(RA, RB, RC, RD, RE, RF, RG, RH, RW8, RW9,
+ vadd_rg_RT0, RA, vadd_rg_RT1, RA);
+ rounds2_64_79(RG, RH, RA, RB, RC, RD, RE, RF, RW10, RW11,
+ vadd_rg_RT0, RG, vadd_rg_RT1, RG);
+ rounds2_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW12, RW13,
+ vadd_rg_RT0, RE, vadd_rg_RT1, RE);
+ rounds2_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW14, RW15,
+ vadd_rg_RT0, RC, vadd_rg_RT1, RC);
+
+ /* Load context to d16-d23 */
+ vld1.64 {RW0-RW3}, [%r0]!;
+ vadd_rg_RT0(RA);
+ vld1.64 {RW4-RW7}, [%r0];
+ vadd_rg_RT1(RA);
+ sub %r0, #(4*8);
+
+ vadd.u64 RA, RW0;
+ vadd.u64 RB, RW1;
+ vadd.u64 RC, RW2;
+ vadd.u64 RD, RW3;
+ vadd.u64 RE, RW4;
+ vadd.u64 RF, RW5;
+ vadd.u64 RG, RW6;
+ vadd.u64 RH, RW7;
+
+ /* Store the first half of context */
+ vst1.64 {RA-RD}, [%r0]!;
+
+ /* Clear used registers */
+ /* d16-d31 */
+ veor.u64 RW01q, RW01q;
+ veor.u64 RW23q, RW23q;
+ veor.u64 RW45q, RW45q;
+ veor.u64 RW67q, RW67q;
+ vst1.64 {RE-RH}, [%r0]; /* Store the last half of context */
+ veor.u64 RW89q, RW89q;
+ veor.u64 RW1011q, RW1011q;
+ veor.u64 RW1213q, RW1213q;
+ veor.u64 RW1415q, RW1415q;
+ /* d8-d15 */
+ /*vpop {RT0-RT7};*/
+ /* d0-d7 (q0-q3) */
+ veor.u64 %q0, %q0;
+ veor.u64 %q1, %q1;
+ veor.u64 %q2, %q2;
+ veor.u64 %q3, %q3;
+
+ pop {%pc};
+ENDPROC(sha512_transform_neon)
diff --git a/arch/arm/crypto/sha512_neon_glue.c b/arch/arm/crypto/sha512_neon_glue.c
new file mode 100644
index 000000000..b124dce83
--- /dev/null
+++ b/arch/arm/crypto/sha512_neon_glue.c
@@ -0,0 +1,305 @@
+/*
+ * Glue code for the SHA512 Secure Hash Algorithm assembly implementation
+ * using NEON instructions.
+ *
+ * Copyright © 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is based on sha512_ssse3_glue.c:
+ * Copyright (C) 2013 Intel Corporation
+ * Author: Tim Chen <tim.c.chen@linux.intel.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 <crypto/internal/hash.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/cryptohash.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <crypto/sha.h>
+#include <asm/byteorder.h>
+#include <asm/simd.h>
+#include <asm/neon.h>
+
+
+static const u64 sha512_k[] = {
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+ 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+ 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+ 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+ 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+ 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+ 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+ 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+ 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+ 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+ 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+ 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+ 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+ 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+ 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+ 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+ 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+ 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+ 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+ 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+ 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+ 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+ 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+ 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+ 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+ 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+ 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+ 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+ 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+ 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+ 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+ 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+ 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+ 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+ 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+ 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+ 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+ 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+
+
+asmlinkage void sha512_transform_neon(u64 *digest, const void *data,
+ const u64 k[], unsigned int num_blks);
+
+
+static int sha512_neon_init(struct shash_desc *desc)
+{
+ struct sha512_state *sctx = shash_desc_ctx(desc);
+
+ sctx->state[0] = SHA512_H0;
+ sctx->state[1] = SHA512_H1;
+ sctx->state[2] = SHA512_H2;
+ sctx->state[3] = SHA512_H3;
+ sctx->state[4] = SHA512_H4;
+ sctx->state[5] = SHA512_H5;
+ sctx->state[6] = SHA512_H6;
+ sctx->state[7] = SHA512_H7;
+ sctx->count[0] = sctx->count[1] = 0;
+
+ return 0;
+}
+
+static int __sha512_neon_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len, unsigned int partial)
+{
+ struct sha512_state *sctx = shash_desc_ctx(desc);
+ unsigned int done = 0;
+
+ sctx->count[0] += len;
+ if (sctx->count[0] < len)
+ sctx->count[1]++;
+
+ if (partial) {
+ done = SHA512_BLOCK_SIZE - partial;
+ memcpy(sctx->buf + partial, data, done);
+ sha512_transform_neon(sctx->state, sctx->buf, sha512_k, 1);
+ }
+
+ if (len - done >= SHA512_BLOCK_SIZE) {
+ const unsigned int rounds = (len - done) / SHA512_BLOCK_SIZE;
+
+ sha512_transform_neon(sctx->state, data + done, sha512_k,
+ rounds);
+
+ done += rounds * SHA512_BLOCK_SIZE;
+ }
+
+ memcpy(sctx->buf, data + done, len - done);
+
+ return 0;
+}
+
+static int sha512_neon_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ struct sha512_state *sctx = shash_desc_ctx(desc);
+ unsigned int partial = sctx->count[0] % SHA512_BLOCK_SIZE;
+ int res;
+
+ /* Handle the fast case right here */
+ if (partial + len < SHA512_BLOCK_SIZE) {
+ sctx->count[0] += len;
+ if (sctx->count[0] < len)
+ sctx->count[1]++;
+ memcpy(sctx->buf + partial, data, len);
+
+ return 0;
+ }
+
+ if (!may_use_simd()) {
+ res = crypto_sha512_update(desc, data, len);
+ } else {
+ kernel_neon_begin();
+ res = __sha512_neon_update(desc, data, len, partial);
+ kernel_neon_end();
+ }
+
+ return res;
+}
+
+
+/* Add padding and return the message digest. */
+static int sha512_neon_final(struct shash_desc *desc, u8 *out)
+{
+ struct sha512_state *sctx = shash_desc_ctx(desc);
+ unsigned int i, index, padlen;
+ __be64 *dst = (__be64 *)out;
+ __be64 bits[2];
+ static const u8 padding[SHA512_BLOCK_SIZE] = { 0x80, };
+
+ /* save number of bits */
+ bits[1] = cpu_to_be64(sctx->count[0] << 3);
+ bits[0] = cpu_to_be64(sctx->count[1] << 3 | sctx->count[0] >> 61);
+
+ /* Pad out to 112 mod 128 and append length */
+ index = sctx->count[0] & 0x7f;
+ padlen = (index < 112) ? (112 - index) : ((128+112) - index);
+
+ if (!may_use_simd()) {
+ crypto_sha512_update(desc, padding, padlen);
+ crypto_sha512_update(desc, (const u8 *)&bits, sizeof(bits));
+ } else {
+ kernel_neon_begin();
+ /* We need to fill a whole block for __sha512_neon_update() */
+ if (padlen <= 112) {
+ sctx->count[0] += padlen;
+ if (sctx->count[0] < padlen)
+ sctx->count[1]++;
+ memcpy(sctx->buf + index, padding, padlen);
+ } else {
+ __sha512_neon_update(desc, padding, padlen, index);
+ }
+ __sha512_neon_update(desc, (const u8 *)&bits,
+ sizeof(bits), 112);
+ kernel_neon_end();
+ }
+
+ /* Store state in digest */
+ for (i = 0; i < 8; i++)
+ dst[i] = cpu_to_be64(sctx->state[i]);
+
+ /* Wipe context */
+ memset(sctx, 0, sizeof(*sctx));
+
+ return 0;
+}
+
+static int sha512_neon_export(struct shash_desc *desc, void *out)
+{
+ struct sha512_state *sctx = shash_desc_ctx(desc);
+
+ memcpy(out, sctx, sizeof(*sctx));
+
+ return 0;
+}
+
+static int sha512_neon_import(struct shash_desc *desc, const void *in)
+{
+ struct sha512_state *sctx = shash_desc_ctx(desc);
+
+ memcpy(sctx, in, sizeof(*sctx));
+
+ return 0;
+}
+
+static int sha384_neon_init(struct shash_desc *desc)
+{
+ struct sha512_state *sctx = shash_desc_ctx(desc);
+
+ sctx->state[0] = SHA384_H0;
+ sctx->state[1] = SHA384_H1;
+ sctx->state[2] = SHA384_H2;
+ sctx->state[3] = SHA384_H3;
+ sctx->state[4] = SHA384_H4;
+ sctx->state[5] = SHA384_H5;
+ sctx->state[6] = SHA384_H6;
+ sctx->state[7] = SHA384_H7;
+
+ sctx->count[0] = sctx->count[1] = 0;
+
+ return 0;
+}
+
+static int sha384_neon_final(struct shash_desc *desc, u8 *hash)
+{
+ u8 D[SHA512_DIGEST_SIZE];
+
+ sha512_neon_final(desc, D);
+
+ memcpy(hash, D, SHA384_DIGEST_SIZE);
+ memzero_explicit(D, SHA512_DIGEST_SIZE);
+
+ return 0;
+}
+
+static struct shash_alg algs[] = { {
+ .digestsize = SHA512_DIGEST_SIZE,
+ .init = sha512_neon_init,
+ .update = sha512_neon_update,
+ .final = sha512_neon_final,
+ .export = sha512_neon_export,
+ .import = sha512_neon_import,
+ .descsize = sizeof(struct sha512_state),
+ .statesize = sizeof(struct sha512_state),
+ .base = {
+ .cra_name = "sha512",
+ .cra_driver_name = "sha512-neon",
+ .cra_priority = 250,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA512_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+}, {
+ .digestsize = SHA384_DIGEST_SIZE,
+ .init = sha384_neon_init,
+ .update = sha512_neon_update,
+ .final = sha384_neon_final,
+ .export = sha512_neon_export,
+ .import = sha512_neon_import,
+ .descsize = sizeof(struct sha512_state),
+ .statesize = sizeof(struct sha512_state),
+ .base = {
+ .cra_name = "sha384",
+ .cra_driver_name = "sha384-neon",
+ .cra_priority = 250,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA384_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+} };
+
+static int __init sha512_neon_mod_init(void)
+{
+ if (!cpu_has_neon())
+ return -ENODEV;
+
+ return crypto_register_shashes(algs, ARRAY_SIZE(algs));
+}
+
+static void __exit sha512_neon_mod_fini(void)
+{
+ crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
+}
+
+module_init(sha512_neon_mod_init);
+module_exit(sha512_neon_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA512 Secure Hash Algorithm, NEON accelerated");
+
+MODULE_ALIAS_CRYPTO("sha512");
+MODULE_ALIAS_CRYPTO("sha384");
diff --git a/arch/arm/firmware/Kconfig b/arch/arm/firmware/Kconfig
new file mode 100644
index 000000000..ad396af68
--- /dev/null
+++ b/arch/arm/firmware/Kconfig
@@ -0,0 +1,29 @@
+config ARCH_SUPPORTS_FIRMWARE
+ bool
+
+config ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
+ bool
+ select ARCH_SUPPORTS_FIRMWARE
+
+menu "Firmware options"
+ depends on ARCH_SUPPORTS_FIRMWARE
+
+config TRUSTED_FOUNDATIONS
+ bool "Trusted Foundations secure monitor support"
+ depends on ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
+ default y
+ help
+ Some devices (including most Tegra-based consumer devices on the
+ market) are booted with the Trusted Foundations secure monitor
+ active, requiring some core operations to be performed by the secure
+ monitor instead of the kernel.
+
+ This option allows the kernel to invoke the secure monitor whenever
+ required on devices using Trusted Foundations. See
+ arch/arm/include/asm/trusted_foundations.h or the
+ tlm,trusted-foundations device tree binding documentation for details
+ on how to use it.
+
+ Say n if you don't know what this is about.
+
+endmenu
diff --git a/arch/arm/firmware/Makefile b/arch/arm/firmware/Makefile
new file mode 100644
index 000000000..a71f16536
--- /dev/null
+++ b/arch/arm/firmware/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o
diff --git a/arch/arm/firmware/trusted_foundations.c b/arch/arm/firmware/trusted_foundations.c
new file mode 100644
index 000000000..3fb1b5a1d
--- /dev/null
+++ b/arch/arm/firmware/trusted_foundations.c
@@ -0,0 +1,99 @@
+/*
+ * Trusted Foundations support for ARM CPUs
+ *
+ * Copyright (c) 2013, 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <asm/firmware.h>
+#include <asm/trusted_foundations.h>
+
+#define TF_SET_CPU_BOOT_ADDR_SMC 0xfffff200
+
+#define TF_CPU_PM 0xfffffffc
+#define TF_CPU_PM_S3 0xffffffe3
+#define TF_CPU_PM_S2 0xffffffe6
+#define TF_CPU_PM_S2_NO_MC_CLK 0xffffffe5
+#define TF_CPU_PM_S1 0xffffffe4
+#define TF_CPU_PM_S1_NOFLUSH_L2 0xffffffe7
+
+static unsigned long cpu_boot_addr;
+
+static void __naked tf_generic_smc(u32 type, u32 arg1, u32 arg2)
+{
+ asm volatile(
+ ".arch_extension sec\n\t"
+ "stmfd sp!, {r4 - r11, lr}\n\t"
+ __asmeq("%0", "r0")
+ __asmeq("%1", "r1")
+ __asmeq("%2", "r2")
+ "mov r3, #0\n\t"
+ "mov r4, #0\n\t"
+ "smc #0\n\t"
+ "ldmfd sp!, {r4 - r11, pc}"
+ :
+ : "r" (type), "r" (arg1), "r" (arg2)
+ : "memory");
+}
+
+static int tf_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
+{
+ cpu_boot_addr = boot_addr;
+ tf_generic_smc(TF_SET_CPU_BOOT_ADDR_SMC, cpu_boot_addr, 0);
+
+ return 0;
+}
+
+static int tf_prepare_idle(void)
+{
+ tf_generic_smc(TF_CPU_PM, TF_CPU_PM_S1_NOFLUSH_L2, cpu_boot_addr);
+
+ return 0;
+}
+
+static const struct firmware_ops trusted_foundations_ops = {
+ .set_cpu_boot_addr = tf_set_cpu_boot_addr,
+ .prepare_idle = tf_prepare_idle,
+};
+
+void register_trusted_foundations(struct trusted_foundations_platform_data *pd)
+{
+ /*
+ * we are not using version information for now since currently
+ * supported SMCs are compatible with all TF releases
+ */
+ register_firmware_ops(&trusted_foundations_ops);
+}
+
+void of_register_trusted_foundations(void)
+{
+ struct device_node *node;
+ struct trusted_foundations_platform_data pdata;
+ int err;
+
+ node = of_find_compatible_node(NULL, NULL, "tlm,trusted-foundations");
+ if (!node)
+ return;
+
+ err = of_property_read_u32(node, "tlm,version-major",
+ &pdata.version_major);
+ if (err != 0)
+ panic("Trusted Foundation: missing version-major property\n");
+ err = of_property_read_u32(node, "tlm,version-minor",
+ &pdata.version_minor);
+ if (err != 0)
+ panic("Trusted Foundation: missing version-minor property\n");
+ register_trusted_foundations(&pdata);
+}
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
new file mode 100644
index 000000000..3c4596d0c
--- /dev/null
+++ b/arch/arm/include/asm/Kbuild
@@ -0,0 +1,39 @@
+
+
+generic-y += bitsperlong.h
+generic-y += cputime.h
+generic-y += current.h
+generic-y += emergency-restart.h
+generic-y += errno.h
+generic-y += exec.h
+generic-y += ioctl.h
+generic-y += ipcbuf.h
+generic-y += irq_regs.h
+generic-y += kdebug.h
+generic-y += local.h
+generic-y += local64.h
+generic-y += mcs_spinlock.h
+generic-y += msgbuf.h
+generic-y += param.h
+generic-y += parport.h
+generic-y += poll.h
+generic-y += preempt.h
+generic-y += resource.h
+generic-y += rwsem.h
+generic-y += scatterlist.h
+generic-y += seccomp.h
+generic-y += sections.h
+generic-y += segment.h
+generic-y += sembuf.h
+generic-y += serial.h
+generic-y += shmbuf.h
+generic-y += siginfo.h
+generic-y += simd.h
+generic-y += sizes.h
+generic-y += socket.h
+generic-y += sockios.h
+generic-y += termbits.h
+generic-y += termios.h
+generic-y += timex.h
+generic-y += trace_clock.h
+generic-y += unaligned.h
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
new file mode 100644
index 000000000..d4ebf5679
--- /dev/null
+++ b/arch/arm/include/asm/arch_timer.h
@@ -0,0 +1,113 @@
+#ifndef __ASMARM_ARCH_TIMER_H
+#define __ASMARM_ARCH_TIMER_H
+
+#include <asm/barrier.h>
+#include <asm/errno.h>
+#include <linux/clocksource.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include <clocksource/arm_arch_timer.h>
+
+#ifdef CONFIG_ARM_ARCH_TIMER
+int arch_timer_arch_init(void);
+
+/*
+ * These register accessors are marked inline so the compiler can
+ * nicely work out which register we want, and chuck away the rest of
+ * the code. At least it does so with a recent GCC (4.6.3).
+ */
+static __always_inline
+void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val)
+{
+ if (access == ARCH_TIMER_PHYS_ACCESS) {
+ switch (reg) {
+ case ARCH_TIMER_REG_CTRL:
+ asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
+ break;
+ case ARCH_TIMER_REG_TVAL:
+ asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val));
+ break;
+ }
+ } else if (access == ARCH_TIMER_VIRT_ACCESS) {
+ switch (reg) {
+ case ARCH_TIMER_REG_CTRL:
+ asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val));
+ break;
+ case ARCH_TIMER_REG_TVAL:
+ asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" (val));
+ break;
+ }
+ }
+
+ isb();
+}
+
+static __always_inline
+u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
+{
+ u32 val = 0;
+
+ if (access == ARCH_TIMER_PHYS_ACCESS) {
+ switch (reg) {
+ case ARCH_TIMER_REG_CTRL:
+ asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
+ break;
+ case ARCH_TIMER_REG_TVAL:
+ asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
+ break;
+ }
+ } else if (access == ARCH_TIMER_VIRT_ACCESS) {
+ switch (reg) {
+ case ARCH_TIMER_REG_CTRL:
+ asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val));
+ break;
+ case ARCH_TIMER_REG_TVAL:
+ asm volatile("mrc p15, 0, %0, c14, c3, 0" : "=r" (val));
+ break;
+ }
+ }
+
+ return val;
+}
+
+static inline u32 arch_timer_get_cntfrq(void)
+{
+ u32 val;
+ asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
+ return val;
+}
+
+static inline u64 arch_counter_get_cntpct(void)
+{
+ u64 cval;
+
+ isb();
+ asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
+ return cval;
+}
+
+static inline u64 arch_counter_get_cntvct(void)
+{
+ u64 cval;
+
+ isb();
+ asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval));
+ return cval;
+}
+
+static inline u32 arch_timer_get_cntkctl(void)
+{
+ u32 cntkctl;
+ asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r" (cntkctl));
+ return cntkctl;
+}
+
+static inline void arch_timer_set_cntkctl(u32 cntkctl)
+{
+ asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl));
+}
+
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/arm-cci.h b/arch/arm/include/asm/arm-cci.h
new file mode 100644
index 000000000..fe77f7ab7
--- /dev/null
+++ b/arch/arm/include/asm/arm-cci.h
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/include/asm/arm-cci.h
+ *
+ * Copyright (C) 2015 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ASM_ARM_CCI_H
+#define __ASM_ARM_CCI_H
+
+#ifdef CONFIG_MCPM
+#include <asm/mcpm.h>
+
+/*
+ * We don't have a reliable way of detecting whether,
+ * if we have access to secure-only registers, unless
+ * mcpm is registered.
+ */
+static inline bool platform_has_secure_cci_access(void)
+{
+ return mcpm_is_available();
+}
+
+#else
+static inline bool platform_has_secure_cci_access(void)
+{
+ return false;
+}
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/asm-offsets.h b/arch/arm/include/asm/asm-offsets.h
new file mode 100644
index 000000000..d370ee36a
--- /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 000000000..186270b3e
--- /dev/null
+++ b/arch/arm/include/asm/assembler.h
@@ -0,0 +1,454 @@
+/*
+ * 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>
+#include <asm/opcodes-virt.h>
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/thread_info.h>
+
+#define IOMEM(x) (x)
+
+/*
+ * Endian independent macros for shifting bytes within registers.
+ */
+#ifndef __ARMEB__
+#define lspull lsr
+#define lspush 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 lspull lsl
+#define lspush 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
+
+/* Select code for any configuration running in BE8 mode */
+#ifdef CONFIG_CPU_ENDIAN_BE8
+#define ARM_BE8(code...) code
+#else
+#define ARM_BE8(code...)
+#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
+#ifdef CONFIG_CPU_V7M
+ mrs \oldcpsr, primask
+#else
+ mrs \oldcpsr, cpsr
+#endif
+ 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
+#ifdef CONFIG_CPU_V7M
+ msr primask, \oldcpsr
+#else
+ msr cpsr_c, \oldcpsr
+#endif
+ .endm
+
+ .macro restore_irqs, oldcpsr
+ tst \oldcpsr, #PSR_I_BIT
+ asm_trace_hardirqs_on_cond eq
+ restore_irqs_notrace \oldcpsr
+ .endm
+
+/*
+ * Get current thread_info.
+ */
+ .macro get_thread_info, rd
+ ARM( mov \rd, sp, lsr #THREAD_SIZE_ORDER + PAGE_SHIFT )
+ THUMB( mov \rd, sp )
+ THUMB( lsr \rd, \rd, #THREAD_SIZE_ORDER + PAGE_SHIFT )
+ mov \rd, \rd, lsl #THREAD_SIZE_ORDER + PAGE_SHIFT
+ .endm
+
+/*
+ * Increment/decrement the preempt count.
+ */
+#ifdef CONFIG_PREEMPT_COUNT
+ .macro inc_preempt_count, ti, tmp
+ ldr \tmp, [\ti, #TI_PREEMPT] @ get preempt count
+ add \tmp, \tmp, #1 @ increment it
+ str \tmp, [\ti, #TI_PREEMPT]
+ .endm
+
+ .macro dec_preempt_count, ti, tmp
+ ldr \tmp, [\ti, #TI_PREEMPT] @ get preempt count
+ sub \tmp, \tmp, #1 @ decrement it
+ str \tmp, [\ti, #TI_PREEMPT]
+ .endm
+
+ .macro dec_preempt_count_ti, ti, tmp
+ get_thread_info \ti
+ dec_preempt_count \ti, \tmp
+ .endm
+#else
+ .macro inc_preempt_count, ti, tmp
+ .endm
+
+ .macro dec_preempt_count, ti, tmp
+ .endm
+
+ .macro dec_preempt_count_ti, ti, tmp
+ .endm
+#endif
+
+#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 == 2 ;\
+ nop ;\
+ .endif ;\
+ .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
+
+/*
+ * Instruction barrier
+ */
+ .macro instr_sync
+#if __LINUX_ARM_ARCH__ >= 7
+ isb
+#elif __LINUX_ARM_ARCH__ == 6
+ mcr p15, 0, r0, c7, c5, 4
+#endif
+ .endm
+
+/*
+ * SMP data memory barrier
+ */
+ .macro smp_dmb mode
+#ifdef CONFIG_SMP
+#if __LINUX_ARM_ARCH__ >= 7
+ .ifeqs "\mode","arm"
+ ALT_SMP(dmb ish)
+ .else
+ ALT_SMP(W(dmb) ish)
+ .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
+
+#if defined(CONFIG_CPU_V7M)
+ /*
+ * setmode is used to assert to be in svc mode during boot. For v7-M
+ * this is done in __v7m_setup, so setmode can be empty here.
+ */
+ .macro setmode, mode, reg
+ .endm
+#elif defined(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
+
+/*
+ * Helper macro to enter SVC mode cleanly and mask interrupts. reg is
+ * a scratch register for the macro to overwrite.
+ *
+ * This macro is intended for forcing the CPU into SVC mode at boot time.
+ * you cannot return to the original mode.
+ */
+.macro safe_svcmode_maskall reg:req
+#if __LINUX_ARM_ARCH__ >= 6 && !defined(CONFIG_CPU_V7M)
+ mrs \reg , cpsr
+ eor \reg, \reg, #HYP_MODE
+ tst \reg, #MODE_MASK
+ bic \reg , \reg , #MODE_MASK
+ orr \reg , \reg , #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+THUMB( orr \reg , \reg , #PSR_T_BIT )
+ bne 1f
+ orr \reg, \reg, #PSR_A_BIT
+ adr lr, BSYM(2f)
+ msr spsr_cxsf, \reg
+ __MSR_ELR_HYP(14)
+ __ERET
+1: msr cpsr_c, \reg
+2:
+#else
+/*
+ * workaround for possibly broken pre-v6 hardware
+ * (akita, Sharp Zaurus C-1000, PXA270-based)
+ */
+ setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, \reg
+#endif
+.endm
+
+/*
+ * 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
+
+ .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req
+#ifndef CONFIG_CPU_USE_DOMAINS
+ adds \tmp, \addr, #\size - 1
+ sbcccs \tmp, \tmp, \limit
+ bcs \bad
+#endif
+ .endm
+
+ .irp c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo
+ .macro ret\c, reg
+#if __LINUX_ARM_ARCH__ < 6
+ mov\c pc, \reg
+#else
+ .ifeqs "\reg", "lr"
+ bx\c \reg
+ .else
+ mov\c pc, \reg
+ .endif
+#endif
+ .endm
+ .endr
+
+ .macro ret.w, reg
+ ret \reg
+#ifdef CONFIG_THUMB2_KERNEL
+ nop
+#endif
+ .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 000000000..e22c11970
--- /dev/null
+++ b/arch/arm/include/asm/atomic.h
@@ -0,0 +1,446 @@
+/*
+ * 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/prefetch.h>
+#include <linux/types.h>
+#include <linux/irqflags.h>
+#include <asm/barrier.h>
+#include <asm/cmpxchg.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) ACCESS_ONCE((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.
+ */
+
+#define ATOMIC_OP(op, c_op, asm_op) \
+static inline void atomic_##op(int i, atomic_t *v) \
+{ \
+ unsigned long tmp; \
+ int result; \
+ \
+ prefetchw(&v->counter); \
+ __asm__ __volatile__("@ atomic_" #op "\n" \
+"1: ldrex %0, [%3]\n" \
+" " #asm_op " %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"); \
+} \
+
+#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
+static inline int atomic_##op##_return(int i, atomic_t *v) \
+{ \
+ unsigned long tmp; \
+ int result; \
+ \
+ smp_mb(); \
+ prefetchw(&v->counter); \
+ \
+ __asm__ __volatile__("@ atomic_" #op "_return\n" \
+"1: ldrex %0, [%3]\n" \
+" " #asm_op " %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)
+{
+ int oldval;
+ unsigned long res;
+
+ smp_mb();
+ prefetchw(&ptr->counter);
+
+ 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 int __atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int oldval, newval;
+ unsigned long tmp;
+
+ smp_mb();
+ prefetchw(&v->counter);
+
+ __asm__ __volatile__ ("@ atomic_add_unless\n"
+"1: ldrex %0, [%4]\n"
+" teq %0, %5\n"
+" beq 2f\n"
+" add %1, %0, %6\n"
+" strex %2, %1, [%4]\n"
+" teq %2, #0\n"
+" bne 1b\n"
+"2:"
+ : "=&r" (oldval), "=&r" (newval), "=&r" (tmp), "+Qo" (v->counter)
+ : "r" (&v->counter), "r" (u), "r" (a)
+ : "cc");
+
+ if (oldval != u)
+ smp_mb();
+
+ return oldval;
+}
+
+#else /* ARM_ARCH_6 */
+
+#ifdef CONFIG_SMP
+#error SMP not supported on pre-ARMv6 CPUs
+#endif
+
+#define ATOMIC_OP(op, c_op, asm_op) \
+static inline void atomic_##op(int i, atomic_t *v) \
+{ \
+ unsigned long flags; \
+ \
+ raw_local_irq_save(flags); \
+ v->counter c_op i; \
+ raw_local_irq_restore(flags); \
+} \
+
+#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
+static inline int atomic_##op##_return(int i, atomic_t *v) \
+{ \
+ unsigned long flags; \
+ int val; \
+ \
+ raw_local_irq_save(flags); \
+ v->counter c_op i; \
+ val = v->counter; \
+ raw_local_irq_restore(flags); \
+ \
+ return val; \
+}
+
+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 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;
+}
+
+#endif /* __LINUX_ARM_ARCH__ */
+
+#define ATOMIC_OPS(op, c_op, asm_op) \
+ ATOMIC_OP(op, c_op, asm_op) \
+ ATOMIC_OP_RETURN(op, c_op, asm_op)
+
+ATOMIC_OPS(add, +=, add)
+ATOMIC_OPS(sub, -=, sub)
+
+#undef ATOMIC_OPS
+#undef ATOMIC_OP_RETURN
+#undef ATOMIC_OP
+
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+#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)
+
+#ifndef CONFIG_GENERIC_ATOMIC64
+typedef struct {
+ long long counter;
+} atomic64_t;
+
+#define ATOMIC64_INIT(i) { (i) }
+
+#ifdef CONFIG_ARM_LPAE
+static inline long long atomic64_read(const atomic64_t *v)
+{
+ long long result;
+
+ __asm__ __volatile__("@ atomic64_read\n"
+" ldrd %0, %H0, [%1]"
+ : "=&r" (result)
+ : "r" (&v->counter), "Qo" (v->counter)
+ );
+
+ return result;
+}
+
+static inline void atomic64_set(atomic64_t *v, long long i)
+{
+ __asm__ __volatile__("@ atomic64_set\n"
+" strd %2, %H2, [%1]"
+ : "=Qo" (v->counter)
+ : "r" (&v->counter), "r" (i)
+ );
+}
+#else
+static inline long long atomic64_read(const atomic64_t *v)
+{
+ long long 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, long long i)
+{
+ long long tmp;
+
+ prefetchw(&v->counter);
+ __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");
+}
+#endif
+
+#define ATOMIC64_OP(op, op1, op2) \
+static inline void atomic64_##op(long long i, atomic64_t *v) \
+{ \
+ long long result; \
+ unsigned long tmp; \
+ \
+ prefetchw(&v->counter); \
+ __asm__ __volatile__("@ atomic64_" #op "\n" \
+"1: ldrexd %0, %H0, [%3]\n" \
+" " #op1 " %Q0, %Q0, %Q4\n" \
+" " #op2 " %R0, %R0, %R4\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"); \
+} \
+
+#define ATOMIC64_OP_RETURN(op, op1, op2) \
+static inline long long atomic64_##op##_return(long long i, atomic64_t *v) \
+{ \
+ long long result; \
+ unsigned long tmp; \
+ \
+ smp_mb(); \
+ prefetchw(&v->counter); \
+ \
+ __asm__ __volatile__("@ atomic64_" #op "_return\n" \
+"1: ldrexd %0, %H0, [%3]\n" \
+" " #op1 " %Q0, %Q0, %Q4\n" \
+" " #op2 " %R0, %R0, %R4\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; \
+}
+
+#define ATOMIC64_OPS(op, op1, op2) \
+ ATOMIC64_OP(op, op1, op2) \
+ ATOMIC64_OP_RETURN(op, op1, op2)
+
+ATOMIC64_OPS(add, adds, adc)
+ATOMIC64_OPS(sub, subs, sbc)
+
+#undef ATOMIC64_OPS
+#undef ATOMIC64_OP_RETURN
+#undef ATOMIC64_OP
+
+static inline long long atomic64_cmpxchg(atomic64_t *ptr, long long old,
+ long long new)
+{
+ long long oldval;
+ unsigned long res;
+
+ smp_mb();
+ prefetchw(&ptr->counter);
+
+ 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 long long atomic64_xchg(atomic64_t *ptr, long long new)
+{
+ long long result;
+ unsigned long tmp;
+
+ smp_mb();
+ prefetchw(&ptr->counter);
+
+ __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 long long atomic64_dec_if_positive(atomic64_t *v)
+{
+ long long result;
+ unsigned long tmp;
+
+ smp_mb();
+ prefetchw(&v->counter);
+
+ __asm__ __volatile__("@ atomic64_dec_if_positive\n"
+"1: ldrexd %0, %H0, [%3]\n"
+" subs %Q0, %Q0, #1\n"
+" sbc %R0, %R0, #0\n"
+" teq %R0, #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, long long a, long long u)
+{
+ long long val;
+ unsigned long tmp;
+ int ret = 1;
+
+ smp_mb();
+ prefetchw(&v->counter);
+
+ __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 %Q0, %Q0, %Q6\n"
+" adc %R0, %R0, %R6\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)
+
+#endif /* !CONFIG_GENERIC_ATOMIC64 */
+#endif
+#endif
diff --git a/arch/arm/include/asm/auxvec.h b/arch/arm/include/asm/auxvec.h
new file mode 100644
index 000000000..fbd388c46
--- /dev/null
+++ b/arch/arm/include/asm/auxvec.h
@@ -0,0 +1 @@
+#include <uapi/asm/auxvec.h>
diff --git a/arch/arm/include/asm/bL_switcher.h b/arch/arm/include/asm/bL_switcher.h
new file mode 100644
index 000000000..1714800fa
--- /dev/null
+++ b/arch/arm/include/asm/bL_switcher.h
@@ -0,0 +1,77 @@
+/*
+ * arch/arm/include/asm/bL_switcher.h
+ *
+ * Created by: Nicolas Pitre, April 2012
+ * Copyright: (C) 2012-2013 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.
+ */
+
+#ifndef ASM_BL_SWITCHER_H
+#define ASM_BL_SWITCHER_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+typedef void (*bL_switch_completion_handler)(void *cookie);
+
+int bL_switch_request_cb(unsigned int cpu, unsigned int new_cluster_id,
+ bL_switch_completion_handler completer,
+ void *completer_cookie);
+static inline int bL_switch_request(unsigned int cpu, unsigned int new_cluster_id)
+{
+ return bL_switch_request_cb(cpu, new_cluster_id, NULL, NULL);
+}
+
+/*
+ * Register here to be notified about runtime enabling/disabling of
+ * the switcher.
+ *
+ * The notifier chain is called with the switcher activation lock held:
+ * the switcher will not be enabled or disabled during callbacks.
+ * Callbacks must not call bL_switcher_{get,put}_enabled().
+ */
+#define BL_NOTIFY_PRE_ENABLE 0
+#define BL_NOTIFY_POST_ENABLE 1
+#define BL_NOTIFY_PRE_DISABLE 2
+#define BL_NOTIFY_POST_DISABLE 3
+
+#ifdef CONFIG_BL_SWITCHER
+
+int bL_switcher_register_notifier(struct notifier_block *nb);
+int bL_switcher_unregister_notifier(struct notifier_block *nb);
+
+/*
+ * Use these functions to temporarily prevent enabling/disabling of
+ * the switcher.
+ * bL_switcher_get_enabled() returns true if the switcher is currently
+ * enabled. Each call to bL_switcher_get_enabled() must be followed
+ * by a call to bL_switcher_put_enabled(). These functions are not
+ * recursive.
+ */
+bool bL_switcher_get_enabled(void);
+void bL_switcher_put_enabled(void);
+
+int bL_switcher_trace_trigger(void);
+int bL_switcher_get_logical_index(u32 mpidr);
+
+#else
+static inline int bL_switcher_register_notifier(struct notifier_block *nb)
+{
+ return 0;
+}
+
+static inline int bL_switcher_unregister_notifier(struct notifier_block *nb)
+{
+ return 0;
+}
+
+static inline bool bL_switcher_get_enabled(void) { return false; }
+static inline void bL_switcher_put_enabled(void) { }
+static inline int bL_switcher_trace_trigger(void) { return 0; }
+static inline int bL_switcher_get_logical_index(u32 mpidr) { return -EUNATCH; }
+#endif /* CONFIG_BL_SWITCHER */
+
+#endif
diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h
new file mode 100644
index 000000000..d2f81e6b8
--- /dev/null
+++ b/arch/arm/include/asm/barrier.h
@@ -0,0 +1,90 @@
+#ifndef __ASM_BARRIER_H
+#define __ASM_BARRIER_H
+
+#ifndef __ASSEMBLY__
+#include <asm/outercache.h>
+
+#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
+
+#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(option) __asm__ __volatile__ ("isb " #option : : : "memory")
+#define dsb(option) __asm__ __volatile__ ("dsb " #option : : : "memory")
+#define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory")
+#elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6
+#define isb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
+ : : "r" (0) : "memory")
+#define dsb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
+ : : "r" (0) : "memory")
+#define dmb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
+ : : "r" (0) : "memory")
+#elif defined(CONFIG_CPU_FA526)
+#define isb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
+ : : "r" (0) : "memory")
+#define dsb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
+ : : "r" (0) : "memory")
+#define dmb(x) __asm__ __volatile__ ("" : : : "memory")
+#else
+#define isb(x) __asm__ __volatile__ ("" : : : "memory")
+#define dsb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
+ : : "r" (0) : "memory")
+#define dmb(x) __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() do { dsb(st); outer_sync(); } while (0)
+#define dma_rmb() dmb(osh)
+#define dma_wmb() dmb(oshst)
+#else
+#define mb() barrier()
+#define rmb() barrier()
+#define wmb() barrier()
+#define dma_rmb() barrier()
+#define dma_wmb() barrier()
+#endif
+
+#ifndef CONFIG_SMP
+#define smp_mb() barrier()
+#define smp_rmb() barrier()
+#define smp_wmb() barrier()
+#else
+#define smp_mb() dmb(ish)
+#define smp_rmb() smp_mb()
+#define smp_wmb() dmb(ishst)
+#endif
+
+#define smp_store_release(p, v) \
+do { \
+ compiletime_assert_atomic_type(*p); \
+ smp_mb(); \
+ ACCESS_ONCE(*p) = (v); \
+} while (0)
+
+#define smp_load_acquire(p) \
+({ \
+ typeof(*p) ___p1 = ACCESS_ONCE(*p); \
+ compiletime_assert_atomic_type(*p); \
+ smp_mb(); \
+ ___p1; \
+})
+
+#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 smp_mb__before_atomic() smp_mb()
+#define smp_mb__after_atomic() smp_mb()
+
+#endif /* !__ASSEMBLY__ */
+#endif /* __ASM_BARRIER_H */
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
new file mode 100644
index 000000000..56380995f
--- /dev/null
+++ b/arch/arm/include/asm/bitops.h
@@ -0,0 +1,349 @@
+/*
+ * 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 <linux/irqflags.h>
+#include <asm/barrier.h>
+
+/*
+ * 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. __clz returns
+ * the number of leading zeros, zero input will return 32, and
+ * 0x80000000 will return 0.
+ */
+static inline unsigned int __clz(unsigned int x)
+{
+ unsigned int ret;
+
+ asm("clz\t%0, %1" : "=r" (ret) : "r" (x));
+
+ return ret;
+}
+
+/*
+ * fls() returns zero if the input is zero, otherwise returns the bit
+ * position of the last set bit, where the LSB is 1 and MSB is 32.
+ */
+static inline int fls(int x)
+{
+ if (__builtin_constant_p(x))
+ return constant_fls(x);
+
+ return 32 - __clz(x);
+}
+
+/*
+ * __fls() returns the bit position of the last bit set, where the
+ * LSB is 0 and MSB is 31. Zero input is undefined.
+ */
+static inline unsigned long __fls(unsigned long x)
+{
+ return fls(x) - 1;
+}
+
+/*
+ * ffs() returns zero if the input was zero, otherwise returns the bit
+ * position of the first set bit, where the LSB is 1 and MSB is 32.
+ */
+static inline int ffs(int x)
+{
+ return fls(x & -x);
+}
+
+/*
+ * __ffs() returns the bit position of the first bit set, where the
+ * LSB is 0 and MSB is 31. Zero input is undefined.
+ */
+static inline unsigned long __ffs(unsigned long x)
+{
+ return 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.
+ */
+#include <asm-generic/bitops/ext2-atomic-setbit.h>
+
+#endif /* __KERNEL__ */
+
+#endif /* _ARM_BITOPS_H */
diff --git a/arch/arm/include/asm/bitrev.h b/arch/arm/include/asm/bitrev.h
new file mode 100644
index 000000000..ec291c350
--- /dev/null
+++ b/arch/arm/include/asm/bitrev.h
@@ -0,0 +1,20 @@
+#ifndef __ASM_BITREV_H
+#define __ASM_BITREV_H
+
+static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
+{
+ __asm__ ("rbit %0, %1" : "=r" (x) : "r" (x));
+ return x;
+}
+
+static __always_inline __attribute_const__ u16 __arch_bitrev16(u16 x)
+{
+ return __arch_bitrev32((u32)x) >> 16;
+}
+
+static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x)
+{
+ return __arch_bitrev32((u32)x) >> 24;
+}
+
+#endif
diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h
new file mode 100644
index 000000000..b274bde24
--- /dev/null
+++ b/arch/arm/include/asm/bug.h
@@ -0,0 +1,92 @@
+#ifndef _ASMARM_BUG_H
+#define _ASMARM_BUG_H
+
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <asm/opcodes.h>
+
+#ifdef CONFIG_BUG
+
+/*
+ * Use a suitable undefined instruction to use for ARM/Thumb2 bug handling.
+ * We need to be careful not to conflict with those used by other modules and
+ * the register_undef_hook() system.
+ */
+#ifdef CONFIG_THUMB2_KERNEL
+#define BUG_INSTR_VALUE 0xde02
+#define BUG_INSTR(__value) __inst_thumb16(__value)
+#else
+#define BUG_INSTR_VALUE 0xe7f001f2
+#define BUG_INSTR(__value) __inst_arm(__value)
+#endif
+
+
+#define BUG() _BUG(__FILE__, __LINE__, BUG_INSTR_VALUE)
+#define _BUG(file, line, value) __BUG(file, line, value)
+
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+
+/*
+ * The extra indirection is to ensure that the __FILE__ string comes through
+ * OK. Many version of gcc do not support the asm %c parameter which would be
+ * preferable to this unpleasantness. We use mergeable string sections to
+ * avoid multiple copies of the string appearing in the kernel image.
+ */
+
+#define __BUG(__file, __line, __value) \
+do { \
+ asm volatile("1:\t" BUG_INSTR(__value) "\n" \
+ ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \
+ "2:\t.asciz " #__file "\n" \
+ ".popsection\n" \
+ ".pushsection __bug_table,\"a\"\n" \
+ "3:\t.word 1b, 2b\n" \
+ "\t.hword " #__line ", 0\n" \
+ ".popsection"); \
+ unreachable(); \
+} while (0)
+
+#else /* not CONFIG_DEBUG_BUGVERBOSE */
+
+#define __BUG(__file, __line, __value) \
+do { \
+ asm volatile(BUG_INSTR(__value) "\n"); \
+ unreachable(); \
+} while (0)
+#endif /* CONFIG_DEBUG_BUGVERBOSE */
+
+#define HAVE_ARCH_BUG
+#endif /* CONFIG_BUG */
+
+#include <asm-generic/bug.h>
+
+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);
+
+#ifdef CONFIG_ARM_LPAE
+#define FAULT_CODE_ALIGNMENT 33
+#define FAULT_CODE_DEBUG 34
+#else
+#define FAULT_CODE_ALIGNMENT 1
+#define FAULT_CODE_DEBUG 2
+#endif
+
+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);
+
+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 *);
+
+#endif
diff --git a/arch/arm/include/asm/bugs.h b/arch/arm/include/asm/bugs.h
new file mode 100644
index 000000000..a97f1ea70
--- /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/cache.h b/arch/arm/include/asm/cache.h
new file mode 100644
index 000000000..75fe66bc0
--- /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 000000000..2d46862e7
--- /dev/null
+++ b/arch/arm/include/asm/cacheflush.h
@@ -0,0 +1,502 @@
+/*
+ * 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_kern_louis()
+ *
+ * Flush data cache levels up to the level of unification
+ * inner shareable and invalidate the I-cache.
+ * Only needed from v7 onwards, falls back to flush_cache_all()
+ * for all other processor versions.
+ *
+ * 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_kern_louis)(void);
+ void (*flush_user_all)(void);
+ void (*flush_user_range)(unsigned long, unsigned long, unsigned int);
+
+ void (*coherent_kern_range)(unsigned long, unsigned long);
+ int (*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_kern_louis cpu_cache.flush_kern_louis
+#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_kern_louis(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 int __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();
+ dsb(ishst);
+}
+
+/*
+ * Flush caches up to Level of Unification Inner Shareable
+ */
+#define flush_cache_louis() __cpuc_flush_kern_louis()
+
+#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)
+{
+ struct mm_struct *mm = vma->vm_mm;
+
+ if (!mm || cpumask_test_cpu(smp_processor_id(), mm_cpumask(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)
+{
+ struct mm_struct *mm = vma->vm_mm;
+
+ if (!mm || cpumask_test_cpu(smp_processor_id(), mm_cpumask(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(s,e) __cpuc_coherent_user_range(s,e)
+
+/*
+ * 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
+extern void flush_kernel_dcache_page(struct 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(ishst);
+}
+
+static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
+{
+ if (!cache_is_vipt_nonaliasing())
+ flush_cache_all();
+}
+
+/*
+ * Memory synchronization helpers for mixed cached vs non cached accesses.
+ *
+ * Some synchronization algorithms have to set states in memory with the
+ * cache enabled or disabled depending on the code path. It is crucial
+ * to always ensure proper cache maintenance to update main memory right
+ * away in that case.
+ *
+ * Any cached write must be followed by a cache clean operation.
+ * Any cached read must be preceded by a cache invalidate operation.
+ * Yet, in the read case, a cache flush i.e. atomic clean+invalidate
+ * operation is needed to avoid discarding possible concurrent writes to the
+ * accessed memory.
+ *
+ * Also, in order to prevent a cached writer from interfering with an
+ * adjacent non-cached writer, each state variable must be located to
+ * a separate cache line.
+ */
+
+/*
+ * This needs to be >= the max cache writeback size of all
+ * supported platforms included in the current kernel configuration.
+ * This is used to align state variables to their own cache lines.
+ */
+#define __CACHE_WRITEBACK_ORDER 6 /* guessed from existing platforms */
+#define __CACHE_WRITEBACK_GRANULE (1 << __CACHE_WRITEBACK_ORDER)
+
+/*
+ * There is no __cpuc_clean_dcache_area but we use it anyway for
+ * code intent clarity, and alias it to __cpuc_flush_dcache_area.
+ */
+#define __cpuc_clean_dcache_area __cpuc_flush_dcache_area
+
+/*
+ * Ensure preceding writes to *p by this CPU are visible to
+ * subsequent reads by other CPUs:
+ */
+static inline void __sync_cache_range_w(volatile void *p, size_t size)
+{
+ char *_p = (char *)p;
+
+ __cpuc_clean_dcache_area(_p, size);
+ outer_clean_range(__pa(_p), __pa(_p + size));
+}
+
+/*
+ * Ensure preceding writes to *p by other CPUs are visible to
+ * subsequent reads by this CPU. We must be careful not to
+ * discard data simultaneously written by another CPU, hence the
+ * usage of flush rather than invalidate operations.
+ */
+static inline void __sync_cache_range_r(volatile void *p, size_t size)
+{
+ char *_p = (char *)p;
+
+#ifdef CONFIG_OUTER_CACHE
+ if (outer_cache.flush_range) {
+ /*
+ * Ensure dirty data migrated from other CPUs into our cache
+ * are cleaned out safely before the outer cache is cleaned:
+ */
+ __cpuc_clean_dcache_area(_p, size);
+
+ /* Clean and invalidate stale data for *p from outer ... */
+ outer_flush_range(__pa(_p), __pa(_p + size));
+ }
+#endif
+
+ /* ... and inner cache: */
+ __cpuc_flush_dcache_area(_p, size);
+}
+
+#define sync_cache_w(ptr) __sync_cache_range_w(ptr, sizeof *(ptr))
+#define sync_cache_r(ptr) __sync_cache_range_r(ptr, sizeof *(ptr))
+
+/*
+ * Disabling cache access for one CPU in an ARMv7 SMP system is tricky.
+ * To do so we must:
+ *
+ * - Clear the SCTLR.C bit to prevent further cache allocations
+ * - Flush the desired level of cache
+ * - Clear the ACTLR "SMP" bit to disable local coherency
+ *
+ * ... and so without any intervening memory access in between those steps,
+ * not even to the stack.
+ *
+ * WARNING -- After this has been called:
+ *
+ * - No ldrex/strex (and similar) instructions must be used.
+ * - The CPU is obviously no longer coherent with the other CPUs.
+ * - This is unlikely to work as expected if Linux is running non-secure.
+ *
+ * Note:
+ *
+ * - This is known to apply to several ARMv7 processor implementations,
+ * however some exceptions may exist. Caveat emptor.
+ *
+ * - The clobber list is dictated by the call to v7_flush_dcache_*.
+ * fp is preserved to the stack explicitly prior disabling the cache
+ * since adding it to the clobber list is incompatible with having
+ * CONFIG_FRAME_POINTER=y. ip is saved as well if ever r12-clobbering
+ * trampoline are inserted by the linker and to keep sp 64-bit aligned.
+ */
+#define v7_exit_coherency_flush(level) \
+ asm volatile( \
+ ".arch armv7-a \n\t" \
+ "stmfd sp!, {fp, ip} \n\t" \
+ "mrc p15, 0, r0, c1, c0, 0 @ get SCTLR \n\t" \
+ "bic r0, r0, #"__stringify(CR_C)" \n\t" \
+ "mcr p15, 0, r0, c1, c0, 0 @ set SCTLR \n\t" \
+ "isb \n\t" \
+ "bl v7_flush_dcache_"__stringify(level)" \n\t" \
+ "mrc p15, 0, r0, c1, c0, 1 @ get ACTLR \n\t" \
+ "bic r0, r0, #(1 << 6) @ disable local coherency \n\t" \
+ "mcr p15, 0, r0, c1, c0, 1 @ set ACTLR \n\t" \
+ "isb \n\t" \
+ "dsb \n\t" \
+ "ldmfd sp!, {fp, ip}" \
+ : : : "r0","r1","r2","r3","r4","r5","r6","r7", \
+ "r9","r10","lr","memory" )
+
+int set_memory_ro(unsigned long addr, int numpages);
+int set_memory_rw(unsigned long addr, int numpages);
+int set_memory_x(unsigned long addr, int numpages);
+int set_memory_nx(unsigned long addr, int numpages);
+
+#ifdef CONFIG_DEBUG_RODATA
+void mark_rodata_ro(void);
+void set_kernel_text_rw(void);
+void set_kernel_text_ro(void);
+#else
+static inline void set_kernel_text_rw(void) { }
+static inline void set_kernel_text_ro(void) { }
+#endif
+
+void flush_uprobe_xol_access(struct page *page, unsigned long uaddr,
+ void *kaddr, unsigned long len);
+
+#endif
diff --git a/arch/arm/include/asm/cachetype.h b/arch/arm/include/asm/cachetype.h
new file mode 100644
index 000000000..7ea78144a
--- /dev/null
+++ b/arch/arm/include/asm/cachetype.h
@@ -0,0 +1,59 @@
+#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)
+#define CACHEID_PIPT (1 << 5)
+
+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)
+#define icache_is_pipt() cacheid_is(CACHEID_PIPT)
+
+/*
+ * __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 |\
+ CACHEID_PIPT)
+#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 000000000..523315115
--- /dev/null
+++ b/arch/arm/include/asm/checksum.h
@@ -0,0 +1,153 @@
+/*
+ * 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)
+{
+ u32 lenprot = len | proto << 16;
+ if (__builtin_constant_p(sum) && sum == 0) {
+ __asm__(
+ "adds %0, %1, %2 @ csum_tcpudp_nofold0 \n\t"
+#ifdef __ARMEB__
+ "adcs %0, %0, %3 \n\t"
+#else
+ "adcs %0, %0, %3, ror #8 \n\t"
+#endif
+ "adc %0, %0, #0"
+ : "=&r" (sum)
+ : "r" (daddr), "r" (saddr), "r" (lenprot)
+ : "cc");
+ } else {
+ __asm__(
+ "adds %0, %1, %2 @ csum_tcpudp_nofold \n\t"
+ "adcs %0, %0, %3 \n\t"
+#ifdef __ARMEB__
+ "adcs %0, %0, %4 \n\t"
+#else
+ "adcs %0, %0, %4, ror #8 \n\t"
+#endif
+ "adc %0, %0, #0"
+ : "=&r"(sum)
+ : "r" (sum), "r" (daddr), "r" (saddr), "r" (lenprot)
+ : "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 000000000..4e8a4b27d
--- /dev/null
+++ b/arch/arm/include/asm/clkdev.h
@@ -0,0 +1,31 @@
+/*
+ * 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>
+
+#ifndef CONFIG_COMMON_CLK
+#ifdef CONFIG_HAVE_MACH_CLKDEV
+#include <mach/clkdev.h>
+#else
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+#endif
+#endif
+
+static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
+{
+ return kzalloc(size, GFP_KERNEL);
+}
+
+#endif
diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h
new file mode 100644
index 000000000..abb2c3769
--- /dev/null
+++ b/arch/arm/include/asm/cmpxchg.h
@@ -0,0 +1,288 @@
+#ifndef __ASM_ARM_CMPXCHG_H
+#define __ASM_ARM_CMPXCHG_H
+
+#include <linux/irqflags.h>
+#include <linux/prefetch.h>
+#include <asm/barrier.h>
+
+#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();
+ prefetchw((const void *)ptr);
+
+ 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;
+}
+
+#define xchg(ptr,x) \
+ ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+
+#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;
+
+ prefetchw((const void *)ptr);
+
+ 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;
+}
+
+static inline unsigned long long __cmpxchg64(unsigned long long *ptr,
+ unsigned long long old,
+ unsigned long long new)
+{
+ unsigned long long oldval;
+ unsigned long res;
+
+ prefetchw(ptr);
+
+ __asm__ __volatile__(
+"1: ldrexd %1, %H1, [%3]\n"
+" teq %1, %4\n"
+" teqeq %H1, %H4\n"
+" bne 2f\n"
+" strexd %0, %5, %H5, [%3]\n"
+" teq %0, #0\n"
+" bne 1b\n"
+"2:"
+ : "=&r" (res), "=&r" (oldval), "+Qo" (*ptr)
+ : "r" (ptr), "r" (old), "r" (new)
+ : "cc");
+
+ return oldval;
+}
+
+static inline unsigned long long __cmpxchg64_mb(unsigned long long *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 cmpxchg_local(ptr,o,n) \
+ ((__typeof__(*(ptr)))__cmpxchg_local((ptr), \
+ (unsigned long)(o), \
+ (unsigned long)(n), \
+ sizeof(*(ptr))))
+
+#define cmpxchg64(ptr, o, n) \
+ ((__typeof__(*(ptr)))__cmpxchg64_mb((ptr), \
+ (unsigned long long)(o), \
+ (unsigned long long)(n)))
+
+#define cmpxchg64_relaxed(ptr, o, n) \
+ ((__typeof__(*(ptr)))__cmpxchg64((ptr), \
+ (unsigned long long)(o), \
+ (unsigned long long)(n)))
+
+#define cmpxchg64_local(ptr, o, n) cmpxchg64_relaxed((ptr), (o), (n))
+
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
+
+#endif /* __ASM_ARM_CMPXCHG_H */
diff --git a/arch/arm/include/asm/compiler.h b/arch/arm/include/asm/compiler.h
new file mode 100644
index 000000000..29fe85e59
--- /dev/null
+++ b/arch/arm/include/asm/compiler.h
@@ -0,0 +1,28 @@
+#ifndef __ASM_ARM_COMPILER_H
+#define __ASM_ARM_COMPILER_H
+
+/*
+ * 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)
+ * For compatibility with clang, we have to specifically take the equivalence
+ * of 'r11' <-> 'fp' and 'r12' <-> 'ip' into account as well.
+ */
+#define __asmeq(x, y) \
+ ".ifnc " x "," y "; " \
+ ".ifnc " x y ",fpr11; " \
+ ".ifnc " x y ",r11fp; " \
+ ".ifnc " x y ",ipr12; " \
+ ".ifnc " x y ",r12ip; " \
+ ".err; " \
+ ".endif; " \
+ ".endif; " \
+ ".endif; " \
+ ".endif; " \
+ ".endif\n\t"
+
+
+#endif /* __ASM_ARM_COMPILER_H */
diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h
new file mode 100644
index 000000000..c3f11524f
--- /dev/null
+++ b/arch/arm/include/asm/cp15.h
@@ -0,0 +1,119 @@
+#ifndef __ASM_ARM_CP15_H
+#define __ASM_ARM_CP15_H
+
+#include <asm/barrier.h>
+
+/*
+ * 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)
+#ifdef CONFIG_MMU
+#define CR_HA (1 << 17) /* Hardware management of Access Flag */
+#else
+#define CR_BR (1 << 17) /* MPU Background region enable (PMSA) */
+#endif
+#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 */
+
+#ifndef __ASSEMBLY__
+
+#if __LINUX_ARM_ARCH__ >= 4
+#define vectors_high() (get_cr() & CR_V)
+#else
+#define vectors_high() (0)
+#endif
+
+#ifdef CONFIG_CPU_CP15
+
+extern unsigned long cr_alignment; /* defined in entry-armv.S */
+
+static inline unsigned long get_cr(void)
+{
+ unsigned long val;
+ asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc");
+ return val;
+}
+
+static inline void set_cr(unsigned long val)
+{
+ asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR"
+ : : "r" (val) : "cc");
+ isb();
+}
+
+static inline unsigned int get_auxcr(void)
+{
+ unsigned int val;
+ asm("mrc p15, 0, %0, c1, c0, 1 @ get AUXCR" : "=r" (val));
+ return val;
+}
+
+static inline void set_auxcr(unsigned int val)
+{
+ asm volatile("mcr p15, 0, %0, c1, c0, 1 @ set AUXCR"
+ : : "r" (val));
+ isb();
+}
+
+#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();
+}
+
+#else /* ifdef CONFIG_CPU_CP15 */
+
+/*
+ * cr_alignment is tightly coupled to cp15 (at least in the minds of the
+ * developers). Yielding 0 for machines without a cp15 (and making it
+ * read-only) is fine for most cases and saves quite some #ifdeffery.
+ */
+#define cr_alignment UL(0)
+
+static inline unsigned long get_cr(void)
+{
+ return 0;
+}
+
+#endif /* ifdef CONFIG_CPU_CP15 / else */
+
+#endif /* ifndef __ASSEMBLY__ */
+
+#endif
diff --git a/arch/arm/include/asm/cpu.h b/arch/arm/include/asm/cpu.h
new file mode 100644
index 000000000..2744f0602
--- /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;
+ u32 cpuid;
+#ifdef CONFIG_SMP
+ unsigned int loops_per_jiffy;
+#endif
+};
+
+DECLARE_PER_CPU(struct cpuinfo_arm, cpu_data);
+
+#endif
diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h
new file mode 100644
index 000000000..0f8424924
--- /dev/null
+++ b/arch/arm/include/asm/cpuidle.h
@@ -0,0 +1,51 @@
+#ifndef __ASM_ARM_CPUIDLE_H
+#define __ASM_ARM_CPUIDLE_H
+
+#include <asm/proc-fns.h>
+
+#ifdef CONFIG_CPU_IDLE
+extern int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index);
+#else
+static inline int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index) { return -ENODEV; }
+#endif
+
+/* Common ARM WFI state */
+#define ARM_CPUIDLE_WFI_STATE_PWR(p) {\
+ .enter = arm_cpuidle_simple_enter,\
+ .exit_latency = 1,\
+ .target_residency = 1,\
+ .power_usage = p,\
+ .name = "WFI",\
+ .desc = "ARM WFI",\
+}
+
+/*
+ * in case power_specified == 1, give a default WFI power value needed
+ * by some governors
+ */
+#define ARM_CPUIDLE_WFI_STATE ARM_CPUIDLE_WFI_STATE_PWR(UINT_MAX)
+
+struct device_node;
+
+struct cpuidle_ops {
+ int (*suspend)(int cpu, unsigned long arg);
+ int (*init)(struct device_node *, int cpu);
+};
+
+struct of_cpuidle_method {
+ const char *method;
+ struct cpuidle_ops *ops;
+};
+
+#define CPUIDLE_METHOD_OF_DECLARE(name, _method, _ops) \
+ static const struct of_cpuidle_method __cpuidle_method_of_table_##name \
+ __used __section(__cpuidle_method_of_table) \
+ = { .method = _method, .ops = _ops }
+
+extern int arm_cpuidle_suspend(int index);
+
+extern int arm_cpuidle_init(int cpu);
+
+#endif
diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
new file mode 100644
index 000000000..85e374f87
--- /dev/null
+++ b/arch/arm/include/asm/cputype.h
@@ -0,0 +1,272 @@
+#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_MPUIR 4
+#define CPUID_MPIDR 5
+#define CPUID_REVIDR 6
+
+#ifdef CONFIG_CPU_V7M
+#define CPUID_EXT_PFR0 0x40
+#define CPUID_EXT_PFR1 0x44
+#define CPUID_EXT_DFR0 0x48
+#define CPUID_EXT_AFR0 0x4c
+#define CPUID_EXT_MMFR0 0x50
+#define CPUID_EXT_MMFR1 0x54
+#define CPUID_EXT_MMFR2 0x58
+#define CPUID_EXT_MMFR3 0x5c
+#define CPUID_EXT_ISAR0 0x60
+#define CPUID_EXT_ISAR1 0x64
+#define CPUID_EXT_ISAR2 0x68
+#define CPUID_EXT_ISAR3 0x6c
+#define CPUID_EXT_ISAR4 0x70
+#define CPUID_EXT_ISAR5 0x74
+#else
+#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"
+#endif
+
+#define MPIDR_SMP_BITMASK (0x3 << 30)
+#define MPIDR_SMP_VALUE (0x2 << 30)
+
+#define MPIDR_MT_BITMASK (0x1 << 24)
+
+#define MPIDR_HWID_BITMASK 0xFFFFFF
+
+#define MPIDR_INVALID (~MPIDR_HWID_BITMASK)
+
+#define MPIDR_LEVEL_BITS 8
+#define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
+
+#define MPIDR_AFFINITY_LEVEL(mpidr, level) \
+ ((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK)
+
+#define ARM_CPU_IMP_ARM 0x41
+#define ARM_CPU_IMP_INTEL 0x69
+
+/* ARM implemented processors */
+#define ARM_CPU_PART_ARM1136 0x4100b360
+#define ARM_CPU_PART_ARM1156 0x4100b560
+#define ARM_CPU_PART_ARM1176 0x4100b760
+#define ARM_CPU_PART_ARM11MPCORE 0x4100b020
+#define ARM_CPU_PART_CORTEX_A8 0x4100c080
+#define ARM_CPU_PART_CORTEX_A9 0x4100c090
+#define ARM_CPU_PART_CORTEX_A5 0x4100c050
+#define ARM_CPU_PART_CORTEX_A7 0x4100c070
+#define ARM_CPU_PART_CORTEX_A12 0x4100c0d0
+#define ARM_CPU_PART_CORTEX_A17 0x4100c0e0
+#define ARM_CPU_PART_CORTEX_A15 0x4100c0f0
+#define ARM_CPU_PART_MASK 0xff00fff0
+
+#define ARM_CPU_XSCALE_ARCH_MASK 0xe000
+#define ARM_CPU_XSCALE_ARCH_V1 0x2000
+#define ARM_CPU_XSCALE_ARCH_V2 0x4000
+#define ARM_CPU_XSCALE_ARCH_V3 0x6000
+
+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; \
+ })
+
+/*
+ * The memory clobber prevents gcc 4.5 from reordering the mrc before
+ * any is_smp() tests, which can cause undefined instruction aborts on
+ * ARM1136 r0 due to the missing extended CP15 registers.
+ */
+#define read_cpuid_ext(ext_reg) \
+ ({ \
+ unsigned int __val; \
+ asm("mrc p15, 0, %0, c0, " ext_reg \
+ : "=r" (__val) \
+ : \
+ : "memory"); \
+ __val; \
+ })
+
+#elif defined(CONFIG_CPU_V7M)
+
+#include <asm/io.h>
+#include <asm/v7m.h>
+
+#define read_cpuid(reg) \
+ ({ \
+ WARN_ON_ONCE(1); \
+ 0; \
+ })
+
+static inline unsigned int __attribute_const__ read_cpuid_ext(unsigned offset)
+{
+ return readl(BASEADDR_V7M_SCB + offset);
+}
+
+#else /* ifdef CONFIG_CPU_CP15 / elif defined (CONFIG_CPU_V7M) */
+
+/*
+ * read_cpuid and read_cpuid_ext should only ever be called on machines that
+ * have cp15 so warn on other usages.
+ */
+#define read_cpuid(reg) \
+ ({ \
+ WARN_ON_ONCE(1); \
+ 0; \
+ })
+
+#define read_cpuid_ext(reg) read_cpuid(reg)
+
+#endif /* ifdef CONFIG_CPU_CP15 / else */
+
+#ifdef CONFIG_CPU_CP15
+/*
+ * 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);
+}
+
+#elif defined(CONFIG_CPU_V7M)
+
+static inline unsigned int __attribute_const__ read_cpuid_id(void)
+{
+ return readl(BASEADDR_V7M_SCB + V7M_SCB_CPUID);
+}
+
+#else /* ifdef CONFIG_CPU_CP15 / elif defined(CONFIG_CPU_V7M) */
+
+static inline unsigned int __attribute_const__ read_cpuid_id(void)
+{
+ return processor_id;
+}
+
+#endif /* ifdef CONFIG_CPU_CP15 / else */
+
+static inline unsigned int __attribute_const__ read_cpuid_implementor(void)
+{
+ return (read_cpuid_id() & 0xFF000000) >> 24;
+}
+
+/*
+ * The CPU part number is meaningless without referring to the CPU
+ * implementer: implementers are free to define their own part numbers
+ * which are permitted to clash with other implementer part numbers.
+ */
+static inline unsigned int __attribute_const__ read_cpuid_part(void)
+{
+ return read_cpuid_id() & ARM_CPU_PART_MASK;
+}
+
+static inline unsigned int __attribute_const__ __deprecated read_cpuid_part_number(void)
+{
+ return read_cpuid_id() & 0xFFF0;
+}
+
+static inline unsigned int __attribute_const__ xscale_cpu_arch_version(void)
+{
+ return read_cpuid_id() & ARM_CPU_XSCALE_ARCH_MASK;
+}
+
+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);
+}
+
+static inline unsigned int __attribute_const__ read_cpuid_mpidr(void)
+{
+ return read_cpuid(CPUID_MPIDR);
+}
+
+/*
+ * 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
+
+/*
+ * Marvell's PJ4 and PJ4B cores are based on V7 version,
+ * but require a specical sequence for enabling coprocessors.
+ * For this reason, we need a way to distinguish them.
+ */
+#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B)
+static inline int cpu_is_pj4(void)
+{
+ unsigned int id;
+
+ id = read_cpuid_id();
+ if ((id & 0xff0fff00) == 0x560f5800)
+ return 1;
+
+ return 0;
+}
+#else
+#define cpu_is_pj4() 0
+#endif
+
+static inline int __attribute_const__ cpuid_feature_extract_field(u32 features,
+ int field)
+{
+ int feature = (features >> field) & 15;
+
+ /* feature registers are signed values */
+ if (feature > 8)
+ feature -= 16;
+
+ return feature;
+}
+
+#define cpuid_feature_extract(reg, field) \
+ cpuid_feature_extract_field(read_cpuid_ext(reg), field)
+
+#endif
diff --git a/arch/arm/include/asm/cti.h b/arch/arm/include/asm/cti.h
new file mode 100644
index 000000000..2381199ac
--- /dev/null
+++ b/arch/arm/include/asm/cti.h
@@ -0,0 +1,159 @@
+#ifndef __ASMARM_CTI_H
+#define __ASMARM_CTI_H
+
+#include <asm/io.h>
+#include <asm/hardware/coresight.h>
+
+/* The registers' definition is from section 3.2 of
+ * Embedded Cross Trigger Revision: r0p0
+ */
+#define CTICONTROL 0x000
+#define CTISTATUS 0x004
+#define CTILOCK 0x008
+#define CTIPROTECTION 0x00C
+#define CTIINTACK 0x010
+#define CTIAPPSET 0x014
+#define CTIAPPCLEAR 0x018
+#define CTIAPPPULSE 0x01c
+#define CTIINEN 0x020
+#define CTIOUTEN 0x0A0
+#define CTITRIGINSTATUS 0x130
+#define CTITRIGOUTSTATUS 0x134
+#define CTICHINSTATUS 0x138
+#define CTICHOUTSTATUS 0x13c
+#define CTIPERIPHID0 0xFE0
+#define CTIPERIPHID1 0xFE4
+#define CTIPERIPHID2 0xFE8
+#define CTIPERIPHID3 0xFEC
+#define CTIPCELLID0 0xFF0
+#define CTIPCELLID1 0xFF4
+#define CTIPCELLID2 0xFF8
+#define CTIPCELLID3 0xFFC
+
+/* The below are from section 3.6.4 of
+ * CoreSight v1.0 Architecture Specification
+ */
+#define LOCKACCESS 0xFB0
+#define LOCKSTATUS 0xFB4
+
+/**
+ * struct cti - cross trigger interface struct
+ * @base: mapped virtual address for the cti base
+ * @irq: irq number for the cti
+ * @trig_out_for_irq: triger out number which will cause
+ * the @irq happen
+ *
+ * cti struct used to operate cti registers.
+ */
+struct cti {
+ void __iomem *base;
+ int irq;
+ int trig_out_for_irq;
+};
+
+/**
+ * cti_init - initialize the cti instance
+ * @cti: cti instance
+ * @base: mapped virtual address for the cti base
+ * @irq: irq number for the cti
+ * @trig_out: triger out number which will cause
+ * the @irq happen
+ *
+ * called by machine code to pass the board dependent
+ * @base, @irq and @trig_out to cti.
+ */
+static inline void cti_init(struct cti *cti,
+ void __iomem *base, int irq, int trig_out)
+{
+ cti->base = base;
+ cti->irq = irq;
+ cti->trig_out_for_irq = trig_out;
+}
+
+/**
+ * cti_map_trigger - use the @chan to map @trig_in to @trig_out
+ * @cti: cti instance
+ * @trig_in: trigger in number
+ * @trig_out: trigger out number
+ * @channel: channel number
+ *
+ * This function maps one trigger in of @trig_in to one trigger
+ * out of @trig_out using the channel @chan.
+ */
+static inline void cti_map_trigger(struct cti *cti,
+ int trig_in, int trig_out, int chan)
+{
+ void __iomem *base = cti->base;
+ unsigned long val;
+
+ val = __raw_readl(base + CTIINEN + trig_in * 4);
+ val |= BIT(chan);
+ __raw_writel(val, base + CTIINEN + trig_in * 4);
+
+ val = __raw_readl(base + CTIOUTEN + trig_out * 4);
+ val |= BIT(chan);
+ __raw_writel(val, base + CTIOUTEN + trig_out * 4);
+}
+
+/**
+ * cti_enable - enable the cti module
+ * @cti: cti instance
+ *
+ * enable the cti module
+ */
+static inline void cti_enable(struct cti *cti)
+{
+ __raw_writel(0x1, cti->base + CTICONTROL);
+}
+
+/**
+ * cti_disable - disable the cti module
+ * @cti: cti instance
+ *
+ * enable the cti module
+ */
+static inline void cti_disable(struct cti *cti)
+{
+ __raw_writel(0, cti->base + CTICONTROL);
+}
+
+/**
+ * cti_irq_ack - clear the cti irq
+ * @cti: cti instance
+ *
+ * clear the cti irq
+ */
+static inline void cti_irq_ack(struct cti *cti)
+{
+ void __iomem *base = cti->base;
+ unsigned long val;
+
+ val = __raw_readl(base + CTIINTACK);
+ val |= BIT(cti->trig_out_for_irq);
+ __raw_writel(val, base + CTIINTACK);
+}
+
+/**
+ * cti_unlock - unlock cti module
+ * @cti: cti instance
+ *
+ * unlock the cti module, or else any writes to the cti
+ * module is not allowed.
+ */
+static inline void cti_unlock(struct cti *cti)
+{
+ __raw_writel(CS_LAR_KEY, cti->base + LOCKACCESS);
+}
+
+/**
+ * cti_lock - lock cti module
+ * @cti: cti instance
+ *
+ * lock the cti module, so any writes to the cti
+ * module will be not allowed.
+ */
+static inline void cti_lock(struct cti *cti)
+{
+ __raw_writel(~CS_LAR_KEY, cti->base + LOCKACCESS);
+}
+#endif
diff --git a/arch/arm/include/asm/dcc.h b/arch/arm/include/asm/dcc.h
new file mode 100644
index 000000000..b74899de0
--- /dev/null
+++ b/arch/arm/include/asm/dcc.h
@@ -0,0 +1,41 @@
+/* Copyright (c) 2010, 2014 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <asm/barrier.h>
+
+static inline u32 __dcc_getstatus(void)
+{
+ u32 __ret;
+ asm volatile("mrc p14, 0, %0, c0, c1, 0 @ read comms ctrl reg"
+ : "=r" (__ret) : : "cc");
+
+ return __ret;
+}
+
+static inline char __dcc_getchar(void)
+{
+ char __c;
+
+ asm volatile("mrc p14, 0, %0, c0, c5, 0 @ read comms data reg"
+ : "=r" (__c));
+ isb();
+
+ return __c;
+}
+
+static inline void __dcc_putchar(char c)
+{
+ asm volatile("mcr p14, 0, %0, c0, c5, 0 @ write a char"
+ : /* no output register */
+ : "r" (c));
+ isb();
+}
diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h
new file mode 100644
index 000000000..dff714d88
--- /dev/null
+++ b/arch/arm/include/asm/delay.h
@@ -0,0 +1,72 @@
+/*
+ * 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/memory.h>
+#include <asm/param.h> /* HZ */
+
+#define MAX_UDELAY_MS 2
+#define UDELAY_MULT ((UL(2199023) * HZ) >> 11)
+#define UDELAY_SHIFT 30
+
+#ifndef __ASSEMBLY__
+
+struct delay_timer {
+ unsigned long (*read_current_timer)(void);
+ unsigned long freq;
+};
+
+extern struct arm_delay_ops {
+ void (*delay)(unsigned long);
+ void (*const_udelay)(unsigned long);
+ void (*udelay)(unsigned long);
+ unsigned long ticks_per_jiffy;
+} arm_delay_ops;
+
+#define __delay(n) arm_delay_ops.delay(n)
+
+/*
+ * 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 ( < 2 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)
+ */
+#define __udelay(n) arm_delay_ops.udelay(n)
+#define __const_udelay(n) arm_delay_ops.const_udelay(n)
+
+#define udelay(n) \
+ (__builtin_constant_p(n) ? \
+ ((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() : \
+ __const_udelay((n) * UDELAY_MULT)) : \
+ __udelay(n))
+
+/* Loop-based definitions for assembly code. */
+extern void __loop_delay(unsigned long loops);
+extern void __loop_udelay(unsigned long usecs);
+extern void __loop_const_udelay(unsigned long);
+
+/* Delay-loop timer registration. */
+#define ARCH_HAS_READ_CURRENT_TIMER
+extern void register_current_timer_delay(const struct delay_timer *timer);
+
+#endif /* __ASSEMBLY__ */
+
+#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 000000000..4111592f0
--- /dev/null
+++ b/arch/arm/include/asm/device.h
@@ -0,0 +1,37 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ */
+#ifndef ASMARM_DEVICE_H
+#define ASMARM_DEVICE_H
+
+struct dev_archdata {
+ struct dma_map_ops *dma_ops;
+#ifdef CONFIG_DMABOUNCE
+ struct dmabounce_device_info *dmabounce;
+#endif
+#ifdef CONFIG_IOMMU_API
+ void *iommu; /* private IOMMU data */
+#endif
+#ifdef CONFIG_ARM_DMA_USE_IOMMU
+ struct dma_iommu_mapping *mapping;
+#endif
+ bool dma_coherent;
+};
+
+struct omap_device;
+
+struct pdev_archdata {
+#ifdef CONFIG_ARCH_OMAP
+ struct omap_device *od;
+#endif
+};
+
+#ifdef CONFIG_ARM_DMA_USE_IOMMU
+#define to_dma_iommu_mapping(dev) ((dev)->archdata.mapping)
+#else
+#define to_dma_iommu_mapping(dev) NULL
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h
new file mode 100644
index 000000000..662c7bd06
--- /dev/null
+++ b/arch/arm/include/asm/div64.h
@@ -0,0 +1,227 @@
+#ifndef __ASM_ARM_DIV64
+#define __ASM_ARM_DIV64
+
+#include <linux/types.h>
+#include <asm/compiler.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 || !defined(CONFIG_AEABI)
+
+/*
+ * 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, %Q1, %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-contiguous.h b/arch/arm/include/asm/dma-contiguous.h
new file mode 100644
index 000000000..4f8e9e551
--- /dev/null
+++ b/arch/arm/include/asm/dma-contiguous.h
@@ -0,0 +1,14 @@
+#ifndef ASMARM_DMA_CONTIGUOUS_H
+#define ASMARM_DMA_CONTIGUOUS_H
+
+#ifdef __KERNEL__
+#ifdef CONFIG_DMA_CMA
+
+#include <linux/types.h>
+
+void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size);
+
+#endif
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h
new file mode 100644
index 000000000..2ef282f96
--- /dev/null
+++ b/arch/arm/include/asm/dma-iommu.h
@@ -0,0 +1,37 @@
+#ifndef ASMARM_DMA_IOMMU_H
+#define ASMARM_DMA_IOMMU_H
+
+#ifdef __KERNEL__
+
+#include <linux/mm_types.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-debug.h>
+#include <linux/kmemcheck.h>
+#include <linux/kref.h>
+
+struct dma_iommu_mapping {
+ /* iommu specific data */
+ struct iommu_domain *domain;
+
+ unsigned long **bitmaps; /* array of bitmaps */
+ unsigned int nr_bitmaps; /* nr of elements in array */
+ unsigned int extensions;
+ size_t bitmap_size; /* size of a single bitmap */
+ size_t bits; /* per bitmap */
+ dma_addr_t base;
+
+ spinlock_t lock;
+ struct kref kref;
+};
+
+struct dma_iommu_mapping *
+arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, u64 size);
+
+void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping);
+
+int arm_iommu_attach_device(struct device *dev,
+ struct dma_iommu_mapping *mapping);
+void arm_iommu_detach_device(struct device *dev);
+
+#endif /* __KERNEL__ */
+#endif
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
new file mode 100644
index 000000000..b52101d37
--- /dev/null
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -0,0 +1,338 @@
+#ifndef ASMARM_DMA_MAPPING_H
+#define ASMARM_DMA_MAPPING_H
+
+#ifdef __KERNEL__
+
+#include <linux/mm_types.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-attrs.h>
+#include <linux/dma-debug.h>
+
+#include <asm-generic/dma-coherent.h>
+#include <asm/memory.h>
+
+#include <xen/xen.h>
+#include <asm/xen/hypervisor.h>
+
+#define DMA_ERROR_CODE (~0)
+extern struct dma_map_ops arm_dma_ops;
+extern struct dma_map_ops arm_coherent_dma_ops;
+
+static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
+{
+ if (dev && dev->archdata.dma_ops)
+ return dev->archdata.dma_ops;
+ return &arm_dma_ops;
+}
+
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+ if (xen_initial_domain())
+ return xen_dma_ops;
+ else
+ return __generic_dma_ops(dev);
+}
+
+static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
+{
+ BUG_ON(!dev);
+ dev->archdata.dma_ops = ops;
+}
+
+#include <asm-generic/dma-mapping-common.h>
+
+static inline int dma_set_mask(struct device *dev, u64 mask)
+{
+ return get_dma_ops(dev)->set_dma_mask(dev, mask);
+}
+
+#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)
+{
+ if (dev)
+ pfn -= dev->dma_pfn_offset;
+ return (dma_addr_t)__pfn_to_bus(pfn);
+}
+
+static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr)
+{
+ unsigned long pfn = __bus_to_pfn(addr);
+
+ if (dev)
+ pfn += dev->dma_pfn_offset;
+
+ return pfn;
+}
+
+static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
+{
+ if (dev) {
+ unsigned long pfn = dma_to_pfn(dev, addr);
+
+ return phys_to_virt(__pfn_to_phys(pfn));
+ }
+
+ return (void *)__bus_to_virt((unsigned long)addr);
+}
+
+static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
+{
+ if (dev)
+ return pfn_to_dma(dev, virt_to_pfn(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 ARM override for dma_max_pfn() */
+static inline unsigned long dma_max_pfn(struct device *dev)
+{
+ return PHYS_PFN_OFFSET + dma_to_pfn(dev, *dev->dma_mask);
+}
+#define dma_max_pfn(dev) dma_max_pfn(dev)
+
+#define arch_setup_dma_ops arch_setup_dma_ops
+extern void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ struct iommu_ops *iommu, bool coherent);
+
+#define arch_teardown_dma_ops arch_teardown_dma_ops
+extern void arch_teardown_dma_ops(struct device *dev);
+
+/* do not use this function in a driver */
+static inline bool is_device_dma_coherent(struct device *dev)
+{
+ return dev->archdata.dma_coherent;
+}
+
+static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+ unsigned int offset = paddr & ~PAGE_MASK;
+ return pfn_to_dma(dev, __phys_to_pfn(paddr)) + offset;
+}
+
+static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr)
+{
+ unsigned int offset = dev_addr & ~PAGE_MASK;
+ return __pfn_to_phys(dma_to_pfn(dev, dev_addr)) + offset;
+}
+
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+ u64 limit, mask;
+
+ if (!dev->dma_mask)
+ return 0;
+
+ mask = *dev->dma_mask;
+
+ limit = (mask + 1) & ~mask;
+ if (limit && size > limit)
+ return 0;
+
+ if ((addr | (addr + size - 1)) & ~mask)
+ return 0;
+
+ return 1;
+}
+
+static inline void dma_mark_clean(void *addr, size_t size) { }
+
+/*
+ * 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)
+{
+ debug_dma_mapping_error(dev, dma_addr);
+ return dma_addr == DMA_ERROR_CODE;
+}
+
+/*
+ * 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)
+{
+}
+
+extern int dma_supported(struct device *dev, u64 mask);
+
+extern int arm_dma_set_mask(struct device *dev, u64 dma_mask);
+
+/**
+ * arm_dma_alloc - 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
+ * @attrs: optinal attributes that specific mapping properties
+ *
+ * Allocate some 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 *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+ gfp_t gfp, struct dma_attrs *attrs);
+
+#define dma_alloc_coherent(d, s, h, f) dma_alloc_attrs(d, s, h, f, NULL)
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag,
+ struct dma_attrs *attrs)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ void *cpu_addr;
+ BUG_ON(!ops);
+
+ cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs);
+ debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
+ return cpu_addr;
+}
+
+/**
+ * arm_dma_free - free memory allocated by arm_dma_alloc
+ * @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
+ * @attrs: optinal attributes that specific mapping properties
+ *
+ * Free (and unmap) a DMA buffer previously allocated by
+ * arm_dma_alloc().
+ *
+ * References to memory and mappings associated with cpu_addr/handle
+ * during and after this call executing are illegal.
+ */
+extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle, struct dma_attrs *attrs);
+
+#define dma_free_coherent(d, s, c, h) dma_free_attrs(d, s, c, h, NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+ void *cpu_addr, dma_addr_t dma_handle,
+ struct dma_attrs *attrs)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ BUG_ON(!ops);
+
+ debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
+ ops->free(dev, size, cpu_addr, dma_handle, attrs);
+}
+
+/**
+ * arm_dma_mmap - 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
+ * @attrs: optinal attributes that specific mapping properties
+ *
+ * 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.
+ */
+extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size,
+ struct dma_attrs *attrs);
+
+/*
+ * This can be called during early boot to increase the size of the atomic
+ * coherent DMA pool above the default value of 256KiB. It must be called
+ * before postcore_initcall.
+ */
+extern void __init init_dma_coherent_pool_size(unsigned long size);
+
+/*
+ * 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)
+ * @needs_bounce_fn: called to determine whether buffer needs bouncing
+ *
+ * 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, int (*)(struct device *, dma_addr_t, size_t));
+
+/**
+ * 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 *);
+
+
+
+/*
+ * The scatter list versions of the above methods.
+ */
+extern int arm_dma_map_sg(struct device *, struct scatterlist *, int,
+ enum dma_data_direction, struct dma_attrs *attrs);
+extern void arm_dma_unmap_sg(struct device *, struct scatterlist *, int,
+ enum dma_data_direction, struct dma_attrs *attrs);
+extern void arm_dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
+ enum dma_data_direction);
+extern void arm_dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
+ enum dma_data_direction);
+extern int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size,
+ struct dma_attrs *attrs);
+
+#endif /* __KERNEL__ */
+#endif
diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h
new file mode 100644
index 000000000..99084431d
--- /dev/null
+++ b/arch/arm/include/asm/dma.h
@@ -0,0 +1,151 @@
+#ifndef __ASM_ARM_DMA_H
+#define __ASM_ARM_DMA_H
+
+/*
+ * This is the maximum virtual address which can be DMA'd from.
+ */
+#ifndef CONFIG_ZONE_DMA
+#define MAX_DMA_ADDRESS 0xffffffffUL
+#else
+#define MAX_DMA_ADDRESS ({ \
+ extern phys_addr_t arm_dma_zone_size; \
+ arm_dma_zone_size && arm_dma_zone_size < (0x10000000 - PAGE_OFFSET) ? \
+ (PAGE_OFFSET + arm_dma_zone_size) : 0xffffffffUL; })
+#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/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 raw_spinlock_t dma_spin_lock;
+
+static inline unsigned long claim_dma_lock(void)
+{
+ unsigned long flags;
+ raw_spin_lock_irqsave(&dma_spin_lock, flags);
+ return flags;
+}
+
+static inline void release_dma_lock(unsigned long flags)
+{
+ raw_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, (void *)__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 000000000..6ddbe4464
--- /dev/null
+++ b/arch/arm/include/asm/domain.h
@@ -0,0 +1,109 @@
+/*
+ * 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
+
+#ifndef __ASSEMBLY__
+#include <asm/barrier.h>
+#endif
+
+/*
+ * 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
+static inline void set_domain(unsigned val)
+{
+ asm volatile(
+ "mcr p15, 0, %0, c3, c0 @ set domain"
+ : : "r" (val));
+ isb();
+}
+
+#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
+static inline void set_domain(unsigned val) { }
+static inline void modify_domain(unsigned dom, unsigned type) { }
+#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 000000000..eaea14676
--- /dev/null
+++ b/arch/arm/include/asm/ecard.h
@@ -0,0 +1,218 @@
+/*
+ * 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 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/edac.h b/arch/arm/include/asm/edac.h
new file mode 100644
index 000000000..0df7a2c1f
--- /dev/null
+++ b/arch/arm/include/asm/edac.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2011 Calxeda, Inc.
+ * Based on PPC version Copyright 2007 MontaVista Software, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef ASM_EDAC_H
+#define ASM_EDAC_H
+/*
+ * ECC atomic, DMA, SMP and interrupt safe scrub function.
+ * Implements the per arch atomic_scrub() that EDAC use for software
+ * ECC scrubbing. It reads memory and then writes back the original
+ * value, allowing the hardware to detect and correct memory errors.
+ */
+static inline void atomic_scrub(void *va, u32 size)
+{
+#if __LINUX_ARM_ARCH__ >= 6
+ unsigned int *virt_addr = va;
+ unsigned int temp, temp2;
+ unsigned int i;
+
+ for (i = 0; i < size / sizeof(*virt_addr); i++, virt_addr++) {
+ /* Very carefully read and write to memory atomically
+ * so we are interrupt, DMA and SMP safe.
+ */
+ __asm__ __volatile__("\n"
+ "1: ldrex %0, [%2]\n"
+ " strex %1, %0, [%2]\n"
+ " teq %1, #0\n"
+ " bne 1b\n"
+ : "=&r"(temp), "=&r"(temp2)
+ : "r"(virt_addr)
+ : "cc");
+ }
+#endif
+}
+
+#endif
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
new file mode 100644
index 000000000..d2315ffd8
--- /dev/null
+++ b/arch/arm/include/asm/elf.h
@@ -0,0 +1,143 @@
+#ifndef __ASMARM_ELF_H
+#define __ASMARM_ELF_H
+
+#include <asm/auxvec.h>
+#include <asm/hwcap.h>
+#include <asm/vdso_datapage.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 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_TARGET1 38
+#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 (TASK_SIZE / 3 * 2)
+
+/* 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))
+
+#ifdef CONFIG_MMU
+#ifdef CONFIG_VDSO
+#define ARCH_DLINFO \
+do { \
+ NEW_AUX_ENT(AT_SYSINFO_EHDR, \
+ (elf_addr_t)current->mm->context.vdso); \
+} while (0)
+#endif
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+struct linux_binprm;
+int arch_setup_additional_pages(struct linux_binprm *, int);
+#endif
+
+#endif
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 000000000..469a2b30f
--- /dev/null
+++ b/arch/arm/include/asm/entry-macro-multi.S
@@ -0,0 +1,39 @@
+#include <asm/assembler.h>
+
+/*
+ * Interrupt handling. Preserves r7, r8, r9
+ */
+ .macro arch_irq_handler_default
+ get_irqnr_preamble r6, lr
+1: get_irqnr_and_base r0, r2, r6, 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 (r2) and base (r6) are
+ * preserved from get_irqnr_and_base above
+ */
+ ALT_SMP(test_for_ipi r0, r2, r6, lr)
+ ALT_UP_B(9997f)
+ movne r1, sp
+ adrne lr, BSYM(1b)
+ bne do_IPI
+#endif
+9997:
+ .endm
+
+ .macro arch_irq_handler, symbol_name
+ .align 5
+ .global \symbol_name
+\symbol_name:
+ mov r8, lr
+ arch_irq_handler_default
+ ret r8
+ .endm
diff --git a/arch/arm/include/asm/exception.h b/arch/arm/include/asm/exception.h
new file mode 100644
index 000000000..5abaf5bbd
--- /dev/null
+++ b/arch/arm/include/asm/exception.h
@@ -0,0 +1,19 @@
+/*
+ * Annotations for marking C functions as exception handlers.
+ *
+ * These should only be used for C functions that are called from the low
+ * level exception entry code and not any intervening C code.
+ */
+#ifndef __ASM_ARM_EXCEPTION_H
+#define __ASM_ARM_EXCEPTION_H
+
+#include <linux/ftrace.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
+
+#endif /* __ASM_ARM_EXCEPTION_H */
diff --git a/arch/arm/include/asm/fb.h b/arch/arm/include/asm/fb.h
new file mode 100644
index 000000000..d92e99cd8
--- /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/fiq.h b/arch/arm/include/asm/fiq.h
new file mode 100644
index 000000000..d493d0b74
--- /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/firmware.h b/arch/arm/include/asm/firmware.h
new file mode 100644
index 000000000..89aefe10d
--- /dev/null
+++ b/arch/arm/include/asm/firmware.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics.
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ * Tomasz Figa <t.figa@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_ARM_FIRMWARE_H
+#define __ASM_ARM_FIRMWARE_H
+
+#include <linux/bug.h>
+
+/*
+ * struct firmware_ops
+ *
+ * A structure to specify available firmware operations.
+ *
+ * A filled up structure can be registered with register_firmware_ops().
+ */
+struct firmware_ops {
+ /*
+ * Inform the firmware we intend to enter CPU idle mode
+ */
+ int (*prepare_idle)(void);
+ /*
+ * Enters CPU idle mode
+ */
+ int (*do_idle)(unsigned long mode);
+ /*
+ * Sets boot address of specified physical CPU
+ */
+ int (*set_cpu_boot_addr)(int cpu, unsigned long boot_addr);
+ /*
+ * Boots specified physical CPU
+ */
+ int (*cpu_boot)(int cpu);
+ /*
+ * Initializes L2 cache
+ */
+ int (*l2x0_init)(void);
+ /*
+ * Enter system-wide suspend.
+ */
+ int (*suspend)(void);
+ /*
+ * Restore state of privileged hardware after system-wide suspend.
+ */
+ int (*resume)(void);
+};
+
+/* Global pointer for current firmware_ops structure, can't be NULL. */
+extern const struct firmware_ops *firmware_ops;
+
+/*
+ * call_firmware_op(op, ...)
+ *
+ * Checks if firmware operation is present and calls it,
+ * otherwise returns -ENOSYS
+ */
+#define call_firmware_op(op, ...) \
+ ((firmware_ops->op) ? firmware_ops->op(__VA_ARGS__) : (-ENOSYS))
+
+/*
+ * register_firmware_ops(ops)
+ *
+ * A function to register platform firmware_ops struct.
+ */
+static inline void register_firmware_ops(const struct firmware_ops *ops)
+{
+ BUG_ON(!ops);
+
+ firmware_ops = ops;
+}
+
+#endif
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
new file mode 100644
index 000000000..0415eae1d
--- /dev/null
+++ b/arch/arm/include/asm/fixmap.h
@@ -0,0 +1,25 @@
+#ifndef _ASM_FIXMAP_H
+#define _ASM_FIXMAP_H
+
+#define FIXADDR_START 0xffc00000UL
+#define FIXADDR_END 0xfff00000UL
+#define FIXADDR_TOP (FIXADDR_END - PAGE_SIZE)
+
+#include <asm/kmap_types.h>
+
+enum fixed_addresses {
+ FIX_KMAP_BEGIN,
+ FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
+
+ /* Support writing RO kernel text via kprobes, jump labels, etc. */
+ FIX_TEXT_POKE0,
+ FIX_TEXT_POKE1,
+
+ __end_of_fixed_addresses
+};
+
+void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot);
+
+#include <asm-generic/fixmap.h>
+
+#endif
diff --git a/arch/arm/include/asm/flat.h b/arch/arm/include/asm/flat.h
new file mode 100644
index 000000000..e847d2335
--- /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) ((void)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 000000000..f4882553f
--- /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,\
+ 0,"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 000000000..de5354746
--- /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 000000000..3ad4c10d0
--- /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 000000000..bfe2a2f5a
--- /dev/null
+++ b/arch/arm/include/asm/ftrace.h
@@ -0,0 +1,59 @@
+#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
+
+static inline void *return_address(unsigned int level)
+{
+ return NULL;
+}
+
+#endif
+
+#define ftrace_return_address(n) return_address(n)
+
+#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 000000000..4e78065a1
--- /dev/null
+++ b/arch/arm/include/asm/futex.h
@@ -0,0 +1,166 @@
+#ifndef _ASM_ARM_FUTEX_H
+#define _ASM_ARM_FUTEX_H
+
+#ifdef __KERNEL__
+
+#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 .text.fixup,\"ax\"\n" \
+ " .align 2\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(); \
+ prefetchw(uaddr); \
+ __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();
+ /* Prefetching cannot fault */
+ prefetchw(uaddr);
+ __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 /* __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 000000000..a3c24cd5b
--- /dev/null
+++ b/arch/arm/include/asm/glue-cache.h
@@ -0,0 +1,166 @@
+/*
+ * 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_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(CONFIG_CPU_V7M)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE nop
+# endif
+#endif
+
+#if !defined(_CACHE) && !defined(MULTI_CACHE)
+#error Unknown cache maintenance model
+#endif
+
+#ifndef __ASSEMBLER__
+static inline void nop_flush_icache_all(void) { }
+static inline void nop_flush_kern_cache_all(void) { }
+static inline void nop_flush_kern_cache_louis(void) { }
+static inline void nop_flush_user_cache_all(void) { }
+static inline void nop_flush_user_cache_range(unsigned long a,
+ unsigned long b, unsigned int c) { }
+
+static inline void nop_coherent_kern_range(unsigned long a, unsigned long b) { }
+static inline int nop_coherent_user_range(unsigned long a,
+ unsigned long b) { return 0; }
+static inline void nop_flush_kern_dcache_area(void *a, size_t s) { }
+
+static inline void nop_dma_flush_range(const void *a, const void *b) { }
+
+static inline void nop_dma_map_area(const void *s, size_t l, int f) { }
+static inline void nop_dma_unmap_area(const void *s, size_t l, int f) { }
+#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_kern_louis __glue(_CACHE,_flush_kern_cache_louis)
+#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 000000000..04e18b656
--- /dev/null
+++ b/arch/arm/include/asm/glue-df.h
@@ -0,0 +1,102 @@
+/*
+ * 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:
+ * 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
+ * v5t_early - ARMv5 with Thumb early abort handler
+ * v5tj_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
+
+#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_LV4T
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER v4t_late_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_EV5T
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER v5t_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_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
+
+#ifdef CONFIG_CPU_ABRT_NOMMU
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER nommu_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 000000000..d385f37c1
--- /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 000000000..74be7c220
--- /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_ARM7TDMI
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm7tdmi
+# 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_V7M
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_v7m
+# endif
+#endif
+
+#ifdef CONFIG_CPU_PJ4B
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_pj4b
+# endif
+#endif
+
+#ifdef CONFIG_CPU_V7
+/*
+ * Cortex-A9 needs a different suspend/resume function, so we need
+ * multiple CPU support for ARMv7 anyway.
+ */
+# undef MULTI_CPU
+# define MULTI_CPU
+#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 000000000..fbf71d75e
--- /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 000000000..504dcddeb
--- /dev/null
+++ b/arch/arm/include/asm/gpio.h
@@ -0,0 +1,25 @@
+#ifndef _ARCH_ARM_GPIO_H
+#define _ARCH_ARM_GPIO_H
+
+#if CONFIG_ARCH_NR_GPIO > 0
+#define ARCH_NR_GPIOS CONFIG_ARCH_NR_GPIO
+#endif
+
+/* Note: this may rely upon the value of ARCH_NR_GPIOS set in mach/gpio.h */
+#include <asm-generic/gpio.h>
+
+/* The trivial gpiolib dispatchers */
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+
+/*
+ * Provide a default gpio_to_irq() which should satisfy every case.
+ * However, some platforms want to do this differently, so allow them
+ * to override it.
+ */
+#ifndef gpio_to_irq
+#define gpio_to_irq __gpio_to_irq
+#endif
+
+#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 000000000..fe3ea776d
--- /dev/null
+++ b/arch/arm/include/asm/hardirq.h
@@ -0,0 +1,32 @@
+#ifndef __ASM_HARDIRQ_H
+#define __ASM_HARDIRQ_H
+
+#include <linux/cache.h>
+#include <linux/threads.h>
+#include <asm/irq.h>
+
+#define NR_IPI 8
+
+typedef struct {
+ unsigned int __softirq_pending;
+#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
+
+#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 000000000..d6030ff59
--- /dev/null
+++ b/arch/arm/include/asm/hardware/arm_timer.h
@@ -0,0 +1,35 @@
+#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.
+ *
+ * Every SP804 contains two identical timers.
+ */
+#define TIMER_1_BASE 0x00
+#define TIMER_2_BASE 0x20
+
+#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-feroceon-l2.h b/arch/arm/include/asm/hardware/cache-feroceon-l2.h
new file mode 100644
index 000000000..12e1588dc
--- /dev/null
+++ b/arch/arm/include/asm/hardware/cache-feroceon-l2.h
@@ -0,0 +1,13 @@
+/*
+ * arch/arm/include/asm/hardware/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);
+extern int __init feroceon_of_init(void);
+
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 000000000..3a5ec1c25
--- /dev/null
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -0,0 +1,181 @@
+/*
+ * 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
+
+#include <linux/errno.h>
+
+#define L2X0_CACHE_ID 0x000
+#define L2X0_CACHE_TYPE 0x004
+#define L2X0_CTRL 0x100
+#define L2X0_AUX_CTRL 0x104
+#define L310_TAG_LATENCY_CTRL 0x108
+#define L310_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
+/*
+ * The lockdown registers repeat 8 times for L310, the L210 has only one
+ * D and one I lockdown register at 0x0900 and 0x0904.
+ */
+#define L2X0_LOCKDOWN_WAY_D_BASE 0x900
+#define L2X0_LOCKDOWN_WAY_I_BASE 0x904
+#define L2X0_LOCKDOWN_STRIDE 0x08
+#define L310_ADDR_FILTER_START 0xC00
+#define L310_ADDR_FILTER_END 0xC04
+#define L2X0_TEST_OPERATION 0xF00
+#define L2X0_LINE_DATA 0xF10
+#define L2X0_LINE_TAG 0xF30
+#define L2X0_DEBUG_CTRL 0xF40
+#define L310_PREFETCH_CTRL 0xF60
+#define L310_POWER_CTRL 0xF80
+#define L310_DYNAMIC_CLK_GATING_EN (1 << 1)
+#define L310_STNDBY_MODE_EN (1 << 0)
+
+/* Registers shifts and masks */
+#define L2X0_CACHE_ID_PART_MASK (0xf << 6)
+#define L2X0_CACHE_ID_PART_L210 (1 << 6)
+#define L2X0_CACHE_ID_PART_L220 (2 << 6)
+#define L2X0_CACHE_ID_PART_L310 (3 << 6)
+#define L2X0_CACHE_ID_RTL_MASK 0x3f
+#define L210_CACHE_ID_RTL_R0P2_02 0x00
+#define L210_CACHE_ID_RTL_R0P1 0x01
+#define L210_CACHE_ID_RTL_R0P2_01 0x02
+#define L210_CACHE_ID_RTL_R0P3 0x03
+#define L210_CACHE_ID_RTL_R0P4 0x0b
+#define L210_CACHE_ID_RTL_R0P5 0x0f
+#define L220_CACHE_ID_RTL_R1P7_01REL0 0x06
+#define L310_CACHE_ID_RTL_R0P0 0x00
+#define L310_CACHE_ID_RTL_R1P0 0x02
+#define L310_CACHE_ID_RTL_R2P0 0x04
+#define L310_CACHE_ID_RTL_R3P0 0x05
+#define L310_CACHE_ID_RTL_R3P1 0x06
+#define L310_CACHE_ID_RTL_R3P1_50REL0 0x07
+#define L310_CACHE_ID_RTL_R3P2 0x08
+#define L310_CACHE_ID_RTL_R3P3 0x09
+
+/* L2C auxiliary control register - bits common to L2C-210/220/310 */
+#define L2C_AUX_CTRL_WAY_SIZE_SHIFT 17
+#define L2C_AUX_CTRL_WAY_SIZE_MASK (7 << 17)
+#define L2C_AUX_CTRL_WAY_SIZE(n) ((n) << 17)
+#define L2C_AUX_CTRL_EVTMON_ENABLE BIT(20)
+#define L2C_AUX_CTRL_PARITY_ENABLE BIT(21)
+#define L2C_AUX_CTRL_SHARED_OVERRIDE BIT(22)
+/* L2C-210/220 common bits */
+#define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT 0
+#define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK (7 << 0)
+#define L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT 3
+#define L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK (7 << 3)
+#define L2X0_AUX_CTRL_TAG_LATENCY_SHIFT 6
+#define L2X0_AUX_CTRL_TAG_LATENCY_MASK (7 << 6)
+#define L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT 9
+#define L2X0_AUX_CTRL_DIRTY_LATENCY_MASK (7 << 9)
+#define L2X0_AUX_CTRL_ASSOC_SHIFT 13
+#define L2X0_AUX_CTRL_ASSOC_MASK (15 << 13)
+/* L2C-210 specific bits */
+#define L210_AUX_CTRL_WRAP_DISABLE BIT(12)
+#define L210_AUX_CTRL_WA_OVERRIDE BIT(23)
+#define L210_AUX_CTRL_EXCLUSIVE_ABORT BIT(24)
+/* L2C-220 specific bits */
+#define L220_AUX_CTRL_EXCLUSIVE_CACHE BIT(12)
+#define L220_AUX_CTRL_FWA_SHIFT 23
+#define L220_AUX_CTRL_FWA_MASK (3 << 23)
+#define L220_AUX_CTRL_NS_LOCKDOWN BIT(26)
+#define L220_AUX_CTRL_NS_INT_CTRL BIT(27)
+/* L2C-310 specific bits */
+#define L310_AUX_CTRL_FULL_LINE_ZERO BIT(0) /* R2P0+ */
+#define L310_AUX_CTRL_HIGHPRIO_SO_DEV BIT(10) /* R2P0+ */
+#define L310_AUX_CTRL_STORE_LIMITATION BIT(11) /* R2P0+ */
+#define L310_AUX_CTRL_EXCLUSIVE_CACHE BIT(12)
+#define L310_AUX_CTRL_ASSOCIATIVITY_16 BIT(16)
+#define L310_AUX_CTRL_CACHE_REPLACE_RR BIT(25) /* R2P0+ */
+#define L310_AUX_CTRL_NS_LOCKDOWN BIT(26)
+#define L310_AUX_CTRL_NS_INT_CTRL BIT(27)
+#define L310_AUX_CTRL_DATA_PREFETCH BIT(28)
+#define L310_AUX_CTRL_INSTR_PREFETCH BIT(29)
+#define L310_AUX_CTRL_EARLY_BRESP BIT(30) /* R2P0+ */
+
+#define L310_LATENCY_CTRL_SETUP(n) ((n) << 0)
+#define L310_LATENCY_CTRL_RD(n) ((n) << 4)
+#define L310_LATENCY_CTRL_WR(n) ((n) << 8)
+
+#define L310_ADDR_FILTER_EN 1
+
+#define L310_PREFETCH_CTRL_OFFSET_MASK 0x1f
+#define L310_PREFETCH_CTRL_DBL_LINEFILL_INCR BIT(23)
+#define L310_PREFETCH_CTRL_PREFETCH_DROP BIT(24)
+#define L310_PREFETCH_CTRL_DBL_LINEFILL_WRAP BIT(27)
+#define L310_PREFETCH_CTRL_DATA_PREFETCH BIT(28)
+#define L310_PREFETCH_CTRL_INSTR_PREFETCH BIT(29)
+#define L310_PREFETCH_CTRL_DBL_LINEFILL BIT(30)
+
+#define L2X0_CTRL_EN 1
+
+#define L2X0_WAY_SIZE_SHIFT 3
+
+#ifndef __ASSEMBLY__
+extern void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask);
+#if defined(CONFIG_CACHE_L2X0) && defined(CONFIG_OF)
+extern int l2x0_of_init(u32 aux_val, u32 aux_mask);
+#else
+static inline int l2x0_of_init(u32 aux_val, u32 aux_mask)
+{
+ return -ENODEV;
+}
+#endif
+
+struct l2x0_regs {
+ unsigned long phy_base;
+ unsigned long aux_ctrl;
+ /*
+ * Whether the following registers need to be saved/restored
+ * depends on platform
+ */
+ unsigned long tag_latency;
+ unsigned long data_latency;
+ unsigned long filter_start;
+ unsigned long filter_end;
+ unsigned long prefetch_ctrl;
+ unsigned long pwr_ctrl;
+ unsigned long ctrl;
+ unsigned long aux2_ctrl;
+};
+
+extern struct l2x0_regs l2x0_saved_regs;
+
+#endif /* __ASSEMBLY__ */
+
+#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 000000000..295e2e401
--- /dev/null
+++ b/arch/arm/include/asm/hardware/cache-tauros2.h
@@ -0,0 +1,14 @@
+/*
+ * 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.
+ */
+
+#define CACHE_TAUROS2_PREFETCH_ON (1 << 0)
+#define CACHE_TAUROS2_LINEFILL_BURST8 (1 << 1)
+
+extern void __init tauros2_init(unsigned int features);
diff --git a/arch/arm/include/asm/hardware/cp14.h b/arch/arm/include/asm/hardware/cp14.h
new file mode 100644
index 000000000..61576dc58
--- /dev/null
+++ b/arch/arm/include/asm/hardware/cp14.h
@@ -0,0 +1,542 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * 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_HARDWARE_CP14_H
+#define __ASM_HARDWARE_CP14_H
+
+#include <linux/types.h>
+
+/* Accessors for CP14 registers */
+#define dbg_read(reg) RCP14_##reg()
+#define dbg_write(val, reg) WCP14_##reg(val)
+#define etm_read(reg) RCP14_##reg()
+#define etm_write(val, reg) WCP14_##reg(val)
+
+/* MRC14 and MCR14 */
+#define MRC14(op1, crn, crm, op2) \
+({ \
+u32 val; \
+asm volatile("mrc p14, "#op1", %0, "#crn", "#crm", "#op2 : "=r" (val)); \
+val; \
+})
+
+#define MCR14(val, op1, crn, crm, op2) \
+({ \
+asm volatile("mcr p14, "#op1", %0, "#crn", "#crm", "#op2 : : "r" (val));\
+})
+
+/*
+ * Debug Registers
+ *
+ * Available only in DBGv7
+ * DBGECR, DBGDSCCR, DBGDSMCR, DBGDRCR
+ *
+ * Available only in DBGv7.1
+ * DBGBXVRm, DBGOSDLR, DBGDEVID2, DBGDEVID1
+ *
+ * Read only
+ * DBGDIDR, DBGDSCRint, DBGDTRRXint, DBGDRAR, DBGOSLSR, DBGOSSRR, DBGPRSR,
+ * DBGPRSR, DBGDSAR, DBGAUTHSTATUS, DBGDEVID2, DBGDEVID1, DBGDEVID
+ *
+ * Write only
+ * DBGDTRTXint, DBGOSLAR
+ */
+#define RCP14_DBGDIDR() MRC14(0, c0, c0, 0)
+#define RCP14_DBGDSCRint() MRC14(0, c0, c1, 0)
+#define RCP14_DBGDTRRXint() MRC14(0, c0, c5, 0)
+#define RCP14_DBGWFAR() MRC14(0, c0, c6, 0)
+#define RCP14_DBGVCR() MRC14(0, c0, c7, 0)
+#define RCP14_DBGECR() MRC14(0, c0, c9, 0)
+#define RCP14_DBGDSCCR() MRC14(0, c0, c10, 0)
+#define RCP14_DBGDSMCR() MRC14(0, c0, c11, 0)
+#define RCP14_DBGDTRRXext() MRC14(0, c0, c0, 2)
+#define RCP14_DBGDSCRext() MRC14(0, c0, c2, 2)
+#define RCP14_DBGDTRTXext() MRC14(0, c0, c3, 2)
+#define RCP14_DBGDRCR() MRC14(0, c0, c4, 2)
+#define RCP14_DBGBVR0() MRC14(0, c0, c0, 4)
+#define RCP14_DBGBVR1() MRC14(0, c0, c1, 4)
+#define RCP14_DBGBVR2() MRC14(0, c0, c2, 4)
+#define RCP14_DBGBVR3() MRC14(0, c0, c3, 4)
+#define RCP14_DBGBVR4() MRC14(0, c0, c4, 4)
+#define RCP14_DBGBVR5() MRC14(0, c0, c5, 4)
+#define RCP14_DBGBVR6() MRC14(0, c0, c6, 4)
+#define RCP14_DBGBVR7() MRC14(0, c0, c7, 4)
+#define RCP14_DBGBVR8() MRC14(0, c0, c8, 4)
+#define RCP14_DBGBVR9() MRC14(0, c0, c9, 4)
+#define RCP14_DBGBVR10() MRC14(0, c0, c10, 4)
+#define RCP14_DBGBVR11() MRC14(0, c0, c11, 4)
+#define RCP14_DBGBVR12() MRC14(0, c0, c12, 4)
+#define RCP14_DBGBVR13() MRC14(0, c0, c13, 4)
+#define RCP14_DBGBVR14() MRC14(0, c0, c14, 4)
+#define RCP14_DBGBVR15() MRC14(0, c0, c15, 4)
+#define RCP14_DBGBCR0() MRC14(0, c0, c0, 5)
+#define RCP14_DBGBCR1() MRC14(0, c0, c1, 5)
+#define RCP14_DBGBCR2() MRC14(0, c0, c2, 5)
+#define RCP14_DBGBCR3() MRC14(0, c0, c3, 5)
+#define RCP14_DBGBCR4() MRC14(0, c0, c4, 5)
+#define RCP14_DBGBCR5() MRC14(0, c0, c5, 5)
+#define RCP14_DBGBCR6() MRC14(0, c0, c6, 5)
+#define RCP14_DBGBCR7() MRC14(0, c0, c7, 5)
+#define RCP14_DBGBCR8() MRC14(0, c0, c8, 5)
+#define RCP14_DBGBCR9() MRC14(0, c0, c9, 5)
+#define RCP14_DBGBCR10() MRC14(0, c0, c10, 5)
+#define RCP14_DBGBCR11() MRC14(0, c0, c11, 5)
+#define RCP14_DBGBCR12() MRC14(0, c0, c12, 5)
+#define RCP14_DBGBCR13() MRC14(0, c0, c13, 5)
+#define RCP14_DBGBCR14() MRC14(0, c0, c14, 5)
+#define RCP14_DBGBCR15() MRC14(0, c0, c15, 5)
+#define RCP14_DBGWVR0() MRC14(0, c0, c0, 6)
+#define RCP14_DBGWVR1() MRC14(0, c0, c1, 6)
+#define RCP14_DBGWVR2() MRC14(0, c0, c2, 6)
+#define RCP14_DBGWVR3() MRC14(0, c0, c3, 6)
+#define RCP14_DBGWVR4() MRC14(0, c0, c4, 6)
+#define RCP14_DBGWVR5() MRC14(0, c0, c5, 6)
+#define RCP14_DBGWVR6() MRC14(0, c0, c6, 6)
+#define RCP14_DBGWVR7() MRC14(0, c0, c7, 6)
+#define RCP14_DBGWVR8() MRC14(0, c0, c8, 6)
+#define RCP14_DBGWVR9() MRC14(0, c0, c9, 6)
+#define RCP14_DBGWVR10() MRC14(0, c0, c10, 6)
+#define RCP14_DBGWVR11() MRC14(0, c0, c11, 6)
+#define RCP14_DBGWVR12() MRC14(0, c0, c12, 6)
+#define RCP14_DBGWVR13() MRC14(0, c0, c13, 6)
+#define RCP14_DBGWVR14() MRC14(0, c0, c14, 6)
+#define RCP14_DBGWVR15() MRC14(0, c0, c15, 6)
+#define RCP14_DBGWCR0() MRC14(0, c0, c0, 7)
+#define RCP14_DBGWCR1() MRC14(0, c0, c1, 7)
+#define RCP14_DBGWCR2() MRC14(0, c0, c2, 7)
+#define RCP14_DBGWCR3() MRC14(0, c0, c3, 7)
+#define RCP14_DBGWCR4() MRC14(0, c0, c4, 7)
+#define RCP14_DBGWCR5() MRC14(0, c0, c5, 7)
+#define RCP14_DBGWCR6() MRC14(0, c0, c6, 7)
+#define RCP14_DBGWCR7() MRC14(0, c0, c7, 7)
+#define RCP14_DBGWCR8() MRC14(0, c0, c8, 7)
+#define RCP14_DBGWCR9() MRC14(0, c0, c9, 7)
+#define RCP14_DBGWCR10() MRC14(0, c0, c10, 7)
+#define RCP14_DBGWCR11() MRC14(0, c0, c11, 7)
+#define RCP14_DBGWCR12() MRC14(0, c0, c12, 7)
+#define RCP14_DBGWCR13() MRC14(0, c0, c13, 7)
+#define RCP14_DBGWCR14() MRC14(0, c0, c14, 7)
+#define RCP14_DBGWCR15() MRC14(0, c0, c15, 7)
+#define RCP14_DBGDRAR() MRC14(0, c1, c0, 0)
+#define RCP14_DBGBXVR0() MRC14(0, c1, c0, 1)
+#define RCP14_DBGBXVR1() MRC14(0, c1, c1, 1)
+#define RCP14_DBGBXVR2() MRC14(0, c1, c2, 1)
+#define RCP14_DBGBXVR3() MRC14(0, c1, c3, 1)
+#define RCP14_DBGBXVR4() MRC14(0, c1, c4, 1)
+#define RCP14_DBGBXVR5() MRC14(0, c1, c5, 1)
+#define RCP14_DBGBXVR6() MRC14(0, c1, c6, 1)
+#define RCP14_DBGBXVR7() MRC14(0, c1, c7, 1)
+#define RCP14_DBGBXVR8() MRC14(0, c1, c8, 1)
+#define RCP14_DBGBXVR9() MRC14(0, c1, c9, 1)
+#define RCP14_DBGBXVR10() MRC14(0, c1, c10, 1)
+#define RCP14_DBGBXVR11() MRC14(0, c1, c11, 1)
+#define RCP14_DBGBXVR12() MRC14(0, c1, c12, 1)
+#define RCP14_DBGBXVR13() MRC14(0, c1, c13, 1)
+#define RCP14_DBGBXVR14() MRC14(0, c1, c14, 1)
+#define RCP14_DBGBXVR15() MRC14(0, c1, c15, 1)
+#define RCP14_DBGOSLSR() MRC14(0, c1, c1, 4)
+#define RCP14_DBGOSSRR() MRC14(0, c1, c2, 4)
+#define RCP14_DBGOSDLR() MRC14(0, c1, c3, 4)
+#define RCP14_DBGPRCR() MRC14(0, c1, c4, 4)
+#define RCP14_DBGPRSR() MRC14(0, c1, c5, 4)
+#define RCP14_DBGDSAR() MRC14(0, c2, c0, 0)
+#define RCP14_DBGITCTRL() MRC14(0, c7, c0, 4)
+#define RCP14_DBGCLAIMSET() MRC14(0, c7, c8, 6)
+#define RCP14_DBGCLAIMCLR() MRC14(0, c7, c9, 6)
+#define RCP14_DBGAUTHSTATUS() MRC14(0, c7, c14, 6)
+#define RCP14_DBGDEVID2() MRC14(0, c7, c0, 7)
+#define RCP14_DBGDEVID1() MRC14(0, c7, c1, 7)
+#define RCP14_DBGDEVID() MRC14(0, c7, c2, 7)
+
+#define WCP14_DBGDTRTXint(val) MCR14(val, 0, c0, c5, 0)
+#define WCP14_DBGWFAR(val) MCR14(val, 0, c0, c6, 0)
+#define WCP14_DBGVCR(val) MCR14(val, 0, c0, c7, 0)
+#define WCP14_DBGECR(val) MCR14(val, 0, c0, c9, 0)
+#define WCP14_DBGDSCCR(val) MCR14(val, 0, c0, c10, 0)
+#define WCP14_DBGDSMCR(val) MCR14(val, 0, c0, c11, 0)
+#define WCP14_DBGDTRRXext(val) MCR14(val, 0, c0, c0, 2)
+#define WCP14_DBGDSCRext(val) MCR14(val, 0, c0, c2, 2)
+#define WCP14_DBGDTRTXext(val) MCR14(val, 0, c0, c3, 2)
+#define WCP14_DBGDRCR(val) MCR14(val, 0, c0, c4, 2)
+#define WCP14_DBGBVR0(val) MCR14(val, 0, c0, c0, 4)
+#define WCP14_DBGBVR1(val) MCR14(val, 0, c0, c1, 4)
+#define WCP14_DBGBVR2(val) MCR14(val, 0, c0, c2, 4)
+#define WCP14_DBGBVR3(val) MCR14(val, 0, c0, c3, 4)
+#define WCP14_DBGBVR4(val) MCR14(val, 0, c0, c4, 4)
+#define WCP14_DBGBVR5(val) MCR14(val, 0, c0, c5, 4)
+#define WCP14_DBGBVR6(val) MCR14(val, 0, c0, c6, 4)
+#define WCP14_DBGBVR7(val) MCR14(val, 0, c0, c7, 4)
+#define WCP14_DBGBVR8(val) MCR14(val, 0, c0, c8, 4)
+#define WCP14_DBGBVR9(val) MCR14(val, 0, c0, c9, 4)
+#define WCP14_DBGBVR10(val) MCR14(val, 0, c0, c10, 4)
+#define WCP14_DBGBVR11(val) MCR14(val, 0, c0, c11, 4)
+#define WCP14_DBGBVR12(val) MCR14(val, 0, c0, c12, 4)
+#define WCP14_DBGBVR13(val) MCR14(val, 0, c0, c13, 4)
+#define WCP14_DBGBVR14(val) MCR14(val, 0, c0, c14, 4)
+#define WCP14_DBGBVR15(val) MCR14(val, 0, c0, c15, 4)
+#define WCP14_DBGBCR0(val) MCR14(val, 0, c0, c0, 5)
+#define WCP14_DBGBCR1(val) MCR14(val, 0, c0, c1, 5)
+#define WCP14_DBGBCR2(val) MCR14(val, 0, c0, c2, 5)
+#define WCP14_DBGBCR3(val) MCR14(val, 0, c0, c3, 5)
+#define WCP14_DBGBCR4(val) MCR14(val, 0, c0, c4, 5)
+#define WCP14_DBGBCR5(val) MCR14(val, 0, c0, c5, 5)
+#define WCP14_DBGBCR6(val) MCR14(val, 0, c0, c6, 5)
+#define WCP14_DBGBCR7(val) MCR14(val, 0, c0, c7, 5)
+#define WCP14_DBGBCR8(val) MCR14(val, 0, c0, c8, 5)
+#define WCP14_DBGBCR9(val) MCR14(val, 0, c0, c9, 5)
+#define WCP14_DBGBCR10(val) MCR14(val, 0, c0, c10, 5)
+#define WCP14_DBGBCR11(val) MCR14(val, 0, c0, c11, 5)
+#define WCP14_DBGBCR12(val) MCR14(val, 0, c0, c12, 5)
+#define WCP14_DBGBCR13(val) MCR14(val, 0, c0, c13, 5)
+#define WCP14_DBGBCR14(val) MCR14(val, 0, c0, c14, 5)
+#define WCP14_DBGBCR15(val) MCR14(val, 0, c0, c15, 5)
+#define WCP14_DBGWVR0(val) MCR14(val, 0, c0, c0, 6)
+#define WCP14_DBGWVR1(val) MCR14(val, 0, c0, c1, 6)
+#define WCP14_DBGWVR2(val) MCR14(val, 0, c0, c2, 6)
+#define WCP14_DBGWVR3(val) MCR14(val, 0, c0, c3, 6)
+#define WCP14_DBGWVR4(val) MCR14(val, 0, c0, c4, 6)
+#define WCP14_DBGWVR5(val) MCR14(val, 0, c0, c5, 6)
+#define WCP14_DBGWVR6(val) MCR14(val, 0, c0, c6, 6)
+#define WCP14_DBGWVR7(val) MCR14(val, 0, c0, c7, 6)
+#define WCP14_DBGWVR8(val) MCR14(val, 0, c0, c8, 6)
+#define WCP14_DBGWVR9(val) MCR14(val, 0, c0, c9, 6)
+#define WCP14_DBGWVR10(val) MCR14(val, 0, c0, c10, 6)
+#define WCP14_DBGWVR11(val) MCR14(val, 0, c0, c11, 6)
+#define WCP14_DBGWVR12(val) MCR14(val, 0, c0, c12, 6)
+#define WCP14_DBGWVR13(val) MCR14(val, 0, c0, c13, 6)
+#define WCP14_DBGWVR14(val) MCR14(val, 0, c0, c14, 6)
+#define WCP14_DBGWVR15(val) MCR14(val, 0, c0, c15, 6)
+#define WCP14_DBGWCR0(val) MCR14(val, 0, c0, c0, 7)
+#define WCP14_DBGWCR1(val) MCR14(val, 0, c0, c1, 7)
+#define WCP14_DBGWCR2(val) MCR14(val, 0, c0, c2, 7)
+#define WCP14_DBGWCR3(val) MCR14(val, 0, c0, c3, 7)
+#define WCP14_DBGWCR4(val) MCR14(val, 0, c0, c4, 7)
+#define WCP14_DBGWCR5(val) MCR14(val, 0, c0, c5, 7)
+#define WCP14_DBGWCR6(val) MCR14(val, 0, c0, c6, 7)
+#define WCP14_DBGWCR7(val) MCR14(val, 0, c0, c7, 7)
+#define WCP14_DBGWCR8(val) MCR14(val, 0, c0, c8, 7)
+#define WCP14_DBGWCR9(val) MCR14(val, 0, c0, c9, 7)
+#define WCP14_DBGWCR10(val) MCR14(val, 0, c0, c10, 7)
+#define WCP14_DBGWCR11(val) MCR14(val, 0, c0, c11, 7)
+#define WCP14_DBGWCR12(val) MCR14(val, 0, c0, c12, 7)
+#define WCP14_DBGWCR13(val) MCR14(val, 0, c0, c13, 7)
+#define WCP14_DBGWCR14(val) MCR14(val, 0, c0, c14, 7)
+#define WCP14_DBGWCR15(val) MCR14(val, 0, c0, c15, 7)
+#define WCP14_DBGBXVR0(val) MCR14(val, 0, c1, c0, 1)
+#define WCP14_DBGBXVR1(val) MCR14(val, 0, c1, c1, 1)
+#define WCP14_DBGBXVR2(val) MCR14(val, 0, c1, c2, 1)
+#define WCP14_DBGBXVR3(val) MCR14(val, 0, c1, c3, 1)
+#define WCP14_DBGBXVR4(val) MCR14(val, 0, c1, c4, 1)
+#define WCP14_DBGBXVR5(val) MCR14(val, 0, c1, c5, 1)
+#define WCP14_DBGBXVR6(val) MCR14(val, 0, c1, c6, 1)
+#define WCP14_DBGBXVR7(val) MCR14(val, 0, c1, c7, 1)
+#define WCP14_DBGBXVR8(val) MCR14(val, 0, c1, c8, 1)
+#define WCP14_DBGBXVR9(val) MCR14(val, 0, c1, c9, 1)
+#define WCP14_DBGBXVR10(val) MCR14(val, 0, c1, c10, 1)
+#define WCP14_DBGBXVR11(val) MCR14(val, 0, c1, c11, 1)
+#define WCP14_DBGBXVR12(val) MCR14(val, 0, c1, c12, 1)
+#define WCP14_DBGBXVR13(val) MCR14(val, 0, c1, c13, 1)
+#define WCP14_DBGBXVR14(val) MCR14(val, 0, c1, c14, 1)
+#define WCP14_DBGBXVR15(val) MCR14(val, 0, c1, c15, 1)
+#define WCP14_DBGOSLAR(val) MCR14(val, 0, c1, c0, 4)
+#define WCP14_DBGOSSRR(val) MCR14(val, 0, c1, c2, 4)
+#define WCP14_DBGOSDLR(val) MCR14(val, 0, c1, c3, 4)
+#define WCP14_DBGPRCR(val) MCR14(val, 0, c1, c4, 4)
+#define WCP14_DBGITCTRL(val) MCR14(val, 0, c7, c0, 4)
+#define WCP14_DBGCLAIMSET(val) MCR14(val, 0, c7, c8, 6)
+#define WCP14_DBGCLAIMCLR(val) MCR14(val, 0, c7, c9, 6)
+
+/*
+ * ETM Registers
+ *
+ * Available only in ETMv3.3, 3.4, 3.5
+ * ETMASICCR, ETMTECR2, ETMFFRR, ETMVDEVR, ETMVDCR1, ETMVDCR2, ETMVDCR3,
+ * ETMDCVRn, ETMDCMRn
+ *
+ * Available only in ETMv3.5 as read only
+ * ETMIDR2
+ *
+ * Available only in ETMv3.5, PFTv1.0, 1.1
+ * ETMTSEVR, ETMVMIDCVR, ETMPDCR
+ *
+ * Read only
+ * ETMCCR, ETMSCR, ETMIDR, ETMCCER, ETMOSLSR
+ * ETMLSR, ETMAUTHSTATUS, ETMDEVID, ETMDEVTYPE, ETMPIDR4, ETMPIDR5, ETMPIDR6,
+ * ETMPIDR7, ETMPIDR0, ETMPIDR1, ETMPIDR2, ETMPIDR2, ETMPIDR3, ETMCIDR0,
+ * ETMCIDR1, ETMCIDR2, ETMCIDR3
+ *
+ * Write only
+ * ETMOSLAR, ETMLAR
+ * Note: ETMCCER[11] controls WO nature of certain regs. Refer ETM arch spec.
+ */
+#define RCP14_ETMCR() MRC14(1, c0, c0, 0)
+#define RCP14_ETMCCR() MRC14(1, c0, c1, 0)
+#define RCP14_ETMTRIGGER() MRC14(1, c0, c2, 0)
+#define RCP14_ETMASICCR() MRC14(1, c0, c3, 0)
+#define RCP14_ETMSR() MRC14(1, c0, c4, 0)
+#define RCP14_ETMSCR() MRC14(1, c0, c5, 0)
+#define RCP14_ETMTSSCR() MRC14(1, c0, c6, 0)
+#define RCP14_ETMTECR2() MRC14(1, c0, c7, 0)
+#define RCP14_ETMTEEVR() MRC14(1, c0, c8, 0)
+#define RCP14_ETMTECR1() MRC14(1, c0, c9, 0)
+#define RCP14_ETMFFRR() MRC14(1, c0, c10, 0)
+#define RCP14_ETMFFLR() MRC14(1, c0, c11, 0)
+#define RCP14_ETMVDEVR() MRC14(1, c0, c12, 0)
+#define RCP14_ETMVDCR1() MRC14(1, c0, c13, 0)
+#define RCP14_ETMVDCR2() MRC14(1, c0, c14, 0)
+#define RCP14_ETMVDCR3() MRC14(1, c0, c15, 0)
+#define RCP14_ETMACVR0() MRC14(1, c0, c0, 1)
+#define RCP14_ETMACVR1() MRC14(1, c0, c1, 1)
+#define RCP14_ETMACVR2() MRC14(1, c0, c2, 1)
+#define RCP14_ETMACVR3() MRC14(1, c0, c3, 1)
+#define RCP14_ETMACVR4() MRC14(1, c0, c4, 1)
+#define RCP14_ETMACVR5() MRC14(1, c0, c5, 1)
+#define RCP14_ETMACVR6() MRC14(1, c0, c6, 1)
+#define RCP14_ETMACVR7() MRC14(1, c0, c7, 1)
+#define RCP14_ETMACVR8() MRC14(1, c0, c8, 1)
+#define RCP14_ETMACVR9() MRC14(1, c0, c9, 1)
+#define RCP14_ETMACVR10() MRC14(1, c0, c10, 1)
+#define RCP14_ETMACVR11() MRC14(1, c0, c11, 1)
+#define RCP14_ETMACVR12() MRC14(1, c0, c12, 1)
+#define RCP14_ETMACVR13() MRC14(1, c0, c13, 1)
+#define RCP14_ETMACVR14() MRC14(1, c0, c14, 1)
+#define RCP14_ETMACVR15() MRC14(1, c0, c15, 1)
+#define RCP14_ETMACTR0() MRC14(1, c0, c0, 2)
+#define RCP14_ETMACTR1() MRC14(1, c0, c1, 2)
+#define RCP14_ETMACTR2() MRC14(1, c0, c2, 2)
+#define RCP14_ETMACTR3() MRC14(1, c0, c3, 2)
+#define RCP14_ETMACTR4() MRC14(1, c0, c4, 2)
+#define RCP14_ETMACTR5() MRC14(1, c0, c5, 2)
+#define RCP14_ETMACTR6() MRC14(1, c0, c6, 2)
+#define RCP14_ETMACTR7() MRC14(1, c0, c7, 2)
+#define RCP14_ETMACTR8() MRC14(1, c0, c8, 2)
+#define RCP14_ETMACTR9() MRC14(1, c0, c9, 2)
+#define RCP14_ETMACTR10() MRC14(1, c0, c10, 2)
+#define RCP14_ETMACTR11() MRC14(1, c0, c11, 2)
+#define RCP14_ETMACTR12() MRC14(1, c0, c12, 2)
+#define RCP14_ETMACTR13() MRC14(1, c0, c13, 2)
+#define RCP14_ETMACTR14() MRC14(1, c0, c14, 2)
+#define RCP14_ETMACTR15() MRC14(1, c0, c15, 2)
+#define RCP14_ETMDCVR0() MRC14(1, c0, c0, 3)
+#define RCP14_ETMDCVR2() MRC14(1, c0, c2, 3)
+#define RCP14_ETMDCVR4() MRC14(1, c0, c4, 3)
+#define RCP14_ETMDCVR6() MRC14(1, c0, c6, 3)
+#define RCP14_ETMDCVR8() MRC14(1, c0, c8, 3)
+#define RCP14_ETMDCVR10() MRC14(1, c0, c10, 3)
+#define RCP14_ETMDCVR12() MRC14(1, c0, c12, 3)
+#define RCP14_ETMDCVR14() MRC14(1, c0, c14, 3)
+#define RCP14_ETMDCMR0() MRC14(1, c0, c0, 4)
+#define RCP14_ETMDCMR2() MRC14(1, c0, c2, 4)
+#define RCP14_ETMDCMR4() MRC14(1, c0, c4, 4)
+#define RCP14_ETMDCMR6() MRC14(1, c0, c6, 4)
+#define RCP14_ETMDCMR8() MRC14(1, c0, c8, 4)
+#define RCP14_ETMDCMR10() MRC14(1, c0, c10, 4)
+#define RCP14_ETMDCMR12() MRC14(1, c0, c12, 4)
+#define RCP14_ETMDCMR14() MRC14(1, c0, c14, 4)
+#define RCP14_ETMCNTRLDVR0() MRC14(1, c0, c0, 5)
+#define RCP14_ETMCNTRLDVR1() MRC14(1, c0, c1, 5)
+#define RCP14_ETMCNTRLDVR2() MRC14(1, c0, c2, 5)
+#define RCP14_ETMCNTRLDVR3() MRC14(1, c0, c3, 5)
+#define RCP14_ETMCNTENR0() MRC14(1, c0, c4, 5)
+#define RCP14_ETMCNTENR1() MRC14(1, c0, c5, 5)
+#define RCP14_ETMCNTENR2() MRC14(1, c0, c6, 5)
+#define RCP14_ETMCNTENR3() MRC14(1, c0, c7, 5)
+#define RCP14_ETMCNTRLDEVR0() MRC14(1, c0, c8, 5)
+#define RCP14_ETMCNTRLDEVR1() MRC14(1, c0, c9, 5)
+#define RCP14_ETMCNTRLDEVR2() MRC14(1, c0, c10, 5)
+#define RCP14_ETMCNTRLDEVR3() MRC14(1, c0, c11, 5)
+#define RCP14_ETMCNTVR0() MRC14(1, c0, c12, 5)
+#define RCP14_ETMCNTVR1() MRC14(1, c0, c13, 5)
+#define RCP14_ETMCNTVR2() MRC14(1, c0, c14, 5)
+#define RCP14_ETMCNTVR3() MRC14(1, c0, c15, 5)
+#define RCP14_ETMSQ12EVR() MRC14(1, c0, c0, 6)
+#define RCP14_ETMSQ21EVR() MRC14(1, c0, c1, 6)
+#define RCP14_ETMSQ23EVR() MRC14(1, c0, c2, 6)
+#define RCP14_ETMSQ31EVR() MRC14(1, c0, c3, 6)
+#define RCP14_ETMSQ32EVR() MRC14(1, c0, c4, 6)
+#define RCP14_ETMSQ13EVR() MRC14(1, c0, c5, 6)
+#define RCP14_ETMSQR() MRC14(1, c0, c7, 6)
+#define RCP14_ETMEXTOUTEVR0() MRC14(1, c0, c8, 6)
+#define RCP14_ETMEXTOUTEVR1() MRC14(1, c0, c9, 6)
+#define RCP14_ETMEXTOUTEVR2() MRC14(1, c0, c10, 6)
+#define RCP14_ETMEXTOUTEVR3() MRC14(1, c0, c11, 6)
+#define RCP14_ETMCIDCVR0() MRC14(1, c0, c12, 6)
+#define RCP14_ETMCIDCVR1() MRC14(1, c0, c13, 6)
+#define RCP14_ETMCIDCVR2() MRC14(1, c0, c14, 6)
+#define RCP14_ETMCIDCMR() MRC14(1, c0, c15, 6)
+#define RCP14_ETMIMPSPEC0() MRC14(1, c0, c0, 7)
+#define RCP14_ETMIMPSPEC1() MRC14(1, c0, c1, 7)
+#define RCP14_ETMIMPSPEC2() MRC14(1, c0, c2, 7)
+#define RCP14_ETMIMPSPEC3() MRC14(1, c0, c3, 7)
+#define RCP14_ETMIMPSPEC4() MRC14(1, c0, c4, 7)
+#define RCP14_ETMIMPSPEC5() MRC14(1, c0, c5, 7)
+#define RCP14_ETMIMPSPEC6() MRC14(1, c0, c6, 7)
+#define RCP14_ETMIMPSPEC7() MRC14(1, c0, c7, 7)
+#define RCP14_ETMSYNCFR() MRC14(1, c0, c8, 7)
+#define RCP14_ETMIDR() MRC14(1, c0, c9, 7)
+#define RCP14_ETMCCER() MRC14(1, c0, c10, 7)
+#define RCP14_ETMEXTINSELR() MRC14(1, c0, c11, 7)
+#define RCP14_ETMTESSEICR() MRC14(1, c0, c12, 7)
+#define RCP14_ETMEIBCR() MRC14(1, c0, c13, 7)
+#define RCP14_ETMTSEVR() MRC14(1, c0, c14, 7)
+#define RCP14_ETMAUXCR() MRC14(1, c0, c15, 7)
+#define RCP14_ETMTRACEIDR() MRC14(1, c1, c0, 0)
+#define RCP14_ETMIDR2() MRC14(1, c1, c2, 0)
+#define RCP14_ETMVMIDCVR() MRC14(1, c1, c0, 1)
+#define RCP14_ETMOSLSR() MRC14(1, c1, c1, 4)
+/* Not available in PFTv1.1 */
+#define RCP14_ETMOSSRR() MRC14(1, c1, c2, 4)
+#define RCP14_ETMPDCR() MRC14(1, c1, c4, 4)
+#define RCP14_ETMPDSR() MRC14(1, c1, c5, 4)
+#define RCP14_ETMITCTRL() MRC14(1, c7, c0, 4)
+#define RCP14_ETMCLAIMSET() MRC14(1, c7, c8, 6)
+#define RCP14_ETMCLAIMCLR() MRC14(1, c7, c9, 6)
+#define RCP14_ETMLSR() MRC14(1, c7, c13, 6)
+#define RCP14_ETMAUTHSTATUS() MRC14(1, c7, c14, 6)
+#define RCP14_ETMDEVID() MRC14(1, c7, c2, 7)
+#define RCP14_ETMDEVTYPE() MRC14(1, c7, c3, 7)
+#define RCP14_ETMPIDR4() MRC14(1, c7, c4, 7)
+#define RCP14_ETMPIDR5() MRC14(1, c7, c5, 7)
+#define RCP14_ETMPIDR6() MRC14(1, c7, c6, 7)
+#define RCP14_ETMPIDR7() MRC14(1, c7, c7, 7)
+#define RCP14_ETMPIDR0() MRC14(1, c7, c8, 7)
+#define RCP14_ETMPIDR1() MRC14(1, c7, c9, 7)
+#define RCP14_ETMPIDR2() MRC14(1, c7, c10, 7)
+#define RCP14_ETMPIDR3() MRC14(1, c7, c11, 7)
+#define RCP14_ETMCIDR0() MRC14(1, c7, c12, 7)
+#define RCP14_ETMCIDR1() MRC14(1, c7, c13, 7)
+#define RCP14_ETMCIDR2() MRC14(1, c7, c14, 7)
+#define RCP14_ETMCIDR3() MRC14(1, c7, c15, 7)
+
+#define WCP14_ETMCR(val) MCR14(val, 1, c0, c0, 0)
+#define WCP14_ETMTRIGGER(val) MCR14(val, 1, c0, c2, 0)
+#define WCP14_ETMASICCR(val) MCR14(val, 1, c0, c3, 0)
+#define WCP14_ETMSR(val) MCR14(val, 1, c0, c4, 0)
+#define WCP14_ETMTSSCR(val) MCR14(val, 1, c0, c6, 0)
+#define WCP14_ETMTECR2(val) MCR14(val, 1, c0, c7, 0)
+#define WCP14_ETMTEEVR(val) MCR14(val, 1, c0, c8, 0)
+#define WCP14_ETMTECR1(val) MCR14(val, 1, c0, c9, 0)
+#define WCP14_ETMFFRR(val) MCR14(val, 1, c0, c10, 0)
+#define WCP14_ETMFFLR(val) MCR14(val, 1, c0, c11, 0)
+#define WCP14_ETMVDEVR(val) MCR14(val, 1, c0, c12, 0)
+#define WCP14_ETMVDCR1(val) MCR14(val, 1, c0, c13, 0)
+#define WCP14_ETMVDCR2(val) MCR14(val, 1, c0, c14, 0)
+#define WCP14_ETMVDCR3(val) MCR14(val, 1, c0, c15, 0)
+#define WCP14_ETMACVR0(val) MCR14(val, 1, c0, c0, 1)
+#define WCP14_ETMACVR1(val) MCR14(val, 1, c0, c1, 1)
+#define WCP14_ETMACVR2(val) MCR14(val, 1, c0, c2, 1)
+#define WCP14_ETMACVR3(val) MCR14(val, 1, c0, c3, 1)
+#define WCP14_ETMACVR4(val) MCR14(val, 1, c0, c4, 1)
+#define WCP14_ETMACVR5(val) MCR14(val, 1, c0, c5, 1)
+#define WCP14_ETMACVR6(val) MCR14(val, 1, c0, c6, 1)
+#define WCP14_ETMACVR7(val) MCR14(val, 1, c0, c7, 1)
+#define WCP14_ETMACVR8(val) MCR14(val, 1, c0, c8, 1)
+#define WCP14_ETMACVR9(val) MCR14(val, 1, c0, c9, 1)
+#define WCP14_ETMACVR10(val) MCR14(val, 1, c0, c10, 1)
+#define WCP14_ETMACVR11(val) MCR14(val, 1, c0, c11, 1)
+#define WCP14_ETMACVR12(val) MCR14(val, 1, c0, c12, 1)
+#define WCP14_ETMACVR13(val) MCR14(val, 1, c0, c13, 1)
+#define WCP14_ETMACVR14(val) MCR14(val, 1, c0, c14, 1)
+#define WCP14_ETMACVR15(val) MCR14(val, 1, c0, c15, 1)
+#define WCP14_ETMACTR0(val) MCR14(val, 1, c0, c0, 2)
+#define WCP14_ETMACTR1(val) MCR14(val, 1, c0, c1, 2)
+#define WCP14_ETMACTR2(val) MCR14(val, 1, c0, c2, 2)
+#define WCP14_ETMACTR3(val) MCR14(val, 1, c0, c3, 2)
+#define WCP14_ETMACTR4(val) MCR14(val, 1, c0, c4, 2)
+#define WCP14_ETMACTR5(val) MCR14(val, 1, c0, c5, 2)
+#define WCP14_ETMACTR6(val) MCR14(val, 1, c0, c6, 2)
+#define WCP14_ETMACTR7(val) MCR14(val, 1, c0, c7, 2)
+#define WCP14_ETMACTR8(val) MCR14(val, 1, c0, c8, 2)
+#define WCP14_ETMACTR9(val) MCR14(val, 1, c0, c9, 2)
+#define WCP14_ETMACTR10(val) MCR14(val, 1, c0, c10, 2)
+#define WCP14_ETMACTR11(val) MCR14(val, 1, c0, c11, 2)
+#define WCP14_ETMACTR12(val) MCR14(val, 1, c0, c12, 2)
+#define WCP14_ETMACTR13(val) MCR14(val, 1, c0, c13, 2)
+#define WCP14_ETMACTR14(val) MCR14(val, 1, c0, c14, 2)
+#define WCP14_ETMACTR15(val) MCR14(val, 1, c0, c15, 2)
+#define WCP14_ETMDCVR0(val) MCR14(val, 1, c0, c0, 3)
+#define WCP14_ETMDCVR2(val) MCR14(val, 1, c0, c2, 3)
+#define WCP14_ETMDCVR4(val) MCR14(val, 1, c0, c4, 3)
+#define WCP14_ETMDCVR6(val) MCR14(val, 1, c0, c6, 3)
+#define WCP14_ETMDCVR8(val) MCR14(val, 1, c0, c8, 3)
+#define WCP14_ETMDCVR10(val) MCR14(val, 1, c0, c10, 3)
+#define WCP14_ETMDCVR12(val) MCR14(val, 1, c0, c12, 3)
+#define WCP14_ETMDCVR14(val) MCR14(val, 1, c0, c14, 3)
+#define WCP14_ETMDCMR0(val) MCR14(val, 1, c0, c0, 4)
+#define WCP14_ETMDCMR2(val) MCR14(val, 1, c0, c2, 4)
+#define WCP14_ETMDCMR4(val) MCR14(val, 1, c0, c4, 4)
+#define WCP14_ETMDCMR6(val) MCR14(val, 1, c0, c6, 4)
+#define WCP14_ETMDCMR8(val) MCR14(val, 1, c0, c8, 4)
+#define WCP14_ETMDCMR10(val) MCR14(val, 1, c0, c10, 4)
+#define WCP14_ETMDCMR12(val) MCR14(val, 1, c0, c12, 4)
+#define WCP14_ETMDCMR14(val) MCR14(val, 1, c0, c14, 4)
+#define WCP14_ETMCNTRLDVR0(val) MCR14(val, 1, c0, c0, 5)
+#define WCP14_ETMCNTRLDVR1(val) MCR14(val, 1, c0, c1, 5)
+#define WCP14_ETMCNTRLDVR2(val) MCR14(val, 1, c0, c2, 5)
+#define WCP14_ETMCNTRLDVR3(val) MCR14(val, 1, c0, c3, 5)
+#define WCP14_ETMCNTENR0(val) MCR14(val, 1, c0, c4, 5)
+#define WCP14_ETMCNTENR1(val) MCR14(val, 1, c0, c5, 5)
+#define WCP14_ETMCNTENR2(val) MCR14(val, 1, c0, c6, 5)
+#define WCP14_ETMCNTENR3(val) MCR14(val, 1, c0, c7, 5)
+#define WCP14_ETMCNTRLDEVR0(val) MCR14(val, 1, c0, c8, 5)
+#define WCP14_ETMCNTRLDEVR1(val) MCR14(val, 1, c0, c9, 5)
+#define WCP14_ETMCNTRLDEVR2(val) MCR14(val, 1, c0, c10, 5)
+#define WCP14_ETMCNTRLDEVR3(val) MCR14(val, 1, c0, c11, 5)
+#define WCP14_ETMCNTVR0(val) MCR14(val, 1, c0, c12, 5)
+#define WCP14_ETMCNTVR1(val) MCR14(val, 1, c0, c13, 5)
+#define WCP14_ETMCNTVR2(val) MCR14(val, 1, c0, c14, 5)
+#define WCP14_ETMCNTVR3(val) MCR14(val, 1, c0, c15, 5)
+#define WCP14_ETMSQ12EVR(val) MCR14(val, 1, c0, c0, 6)
+#define WCP14_ETMSQ21EVR(val) MCR14(val, 1, c0, c1, 6)
+#define WCP14_ETMSQ23EVR(val) MCR14(val, 1, c0, c2, 6)
+#define WCP14_ETMSQ31EVR(val) MCR14(val, 1, c0, c3, 6)
+#define WCP14_ETMSQ32EVR(val) MCR14(val, 1, c0, c4, 6)
+#define WCP14_ETMSQ13EVR(val) MCR14(val, 1, c0, c5, 6)
+#define WCP14_ETMSQR(val) MCR14(val, 1, c0, c7, 6)
+#define WCP14_ETMEXTOUTEVR0(val) MCR14(val, 1, c0, c8, 6)
+#define WCP14_ETMEXTOUTEVR1(val) MCR14(val, 1, c0, c9, 6)
+#define WCP14_ETMEXTOUTEVR2(val) MCR14(val, 1, c0, c10, 6)
+#define WCP14_ETMEXTOUTEVR3(val) MCR14(val, 1, c0, c11, 6)
+#define WCP14_ETMCIDCVR0(val) MCR14(val, 1, c0, c12, 6)
+#define WCP14_ETMCIDCVR1(val) MCR14(val, 1, c0, c13, 6)
+#define WCP14_ETMCIDCVR2(val) MCR14(val, 1, c0, c14, 6)
+#define WCP14_ETMCIDCMR(val) MCR14(val, 1, c0, c15, 6)
+#define WCP14_ETMIMPSPEC0(val) MCR14(val, 1, c0, c0, 7)
+#define WCP14_ETMIMPSPEC1(val) MCR14(val, 1, c0, c1, 7)
+#define WCP14_ETMIMPSPEC2(val) MCR14(val, 1, c0, c2, 7)
+#define WCP14_ETMIMPSPEC3(val) MCR14(val, 1, c0, c3, 7)
+#define WCP14_ETMIMPSPEC4(val) MCR14(val, 1, c0, c4, 7)
+#define WCP14_ETMIMPSPEC5(val) MCR14(val, 1, c0, c5, 7)
+#define WCP14_ETMIMPSPEC6(val) MCR14(val, 1, c0, c6, 7)
+#define WCP14_ETMIMPSPEC7(val) MCR14(val, 1, c0, c7, 7)
+/* Can be read only in ETMv3.4, ETMv3.5 */
+#define WCP14_ETMSYNCFR(val) MCR14(val, 1, c0, c8, 7)
+#define WCP14_ETMEXTINSELR(val) MCR14(val, 1, c0, c11, 7)
+#define WCP14_ETMTESSEICR(val) MCR14(val, 1, c0, c12, 7)
+#define WCP14_ETMEIBCR(val) MCR14(val, 1, c0, c13, 7)
+#define WCP14_ETMTSEVR(val) MCR14(val, 1, c0, c14, 7)
+#define WCP14_ETMAUXCR(val) MCR14(val, 1, c0, c15, 7)
+#define WCP14_ETMTRACEIDR(val) MCR14(val, 1, c1, c0, 0)
+#define WCP14_ETMIDR2(val) MCR14(val, 1, c1, c2, 0)
+#define WCP14_ETMVMIDCVR(val) MCR14(val, 1, c1, c0, 1)
+#define WCP14_ETMOSLAR(val) MCR14(val, 1, c1, c0, 4)
+/* Not available in PFTv1.1 */
+#define WCP14_ETMOSSRR(val) MCR14(val, 1, c1, c2, 4)
+#define WCP14_ETMPDCR(val) MCR14(val, 1, c1, c4, 4)
+#define WCP14_ETMPDSR(val) MCR14(val, 1, c1, c5, 4)
+#define WCP14_ETMITCTRL(val) MCR14(val, 1, c7, c0, 4)
+#define WCP14_ETMCLAIMSET(val) MCR14(val, 1, c7, c8, 6)
+#define WCP14_ETMCLAIMCLR(val) MCR14(val, 1, c7, c9, 6)
+/* Writes to this from CP14 interface are ignored */
+#define WCP14_ETMLAR(val) MCR14(val, 1, c7, c12, 6)
+
+#endif
diff --git a/arch/arm/include/asm/hardware/dec21285.h b/arch/arm/include/asm/hardware/dec21285.h
new file mode 100644
index 000000000..0d7552751
--- /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-iomd.S b/arch/arm/include/asm/hardware/entry-macro-iomd.S
new file mode 100644
index 000000000..8c215acd9
--- /dev/null
+++ b/arch/arm/include/asm/hardware/entry-macro-iomd.S
@@ -0,0 +1,131 @@
+/*
+ * 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 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/icst.h b/arch/arm/include/asm/hardware/icst.h
new file mode 100644
index 000000000..794220b08
--- /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 000000000..1f6b8013b
--- /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 000000000..f9ee69e4f
--- /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 000000000..240b29ef1
--- /dev/null
+++ b/arch/arm/include/asm/hardware/iop3xx-adma.h
@@ -0,0 +1,932 @@
+/*
+ * 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 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.h b/arch/arm/include/asm/hardware/iop3xx.h
new file mode 100644
index 000000000..2594a95ff
--- /dev/null
+++ b/arch/arm/include/asm/hardware/iop3xx.h
@@ -0,0 +1,312 @@
+/*
+ * 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 IOP3XX_GPIO_LINE(x) (x)
+
+#ifndef __ASSEMBLY__
+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 0xfedfe000
+#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)
+
+/* 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_LOWER_IO_PA 0x90000000
+#define IOP3XX_PCI_LOWER_IO_BA 0x00000000
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <linux/reboot.h>
+
+void iop3xx_map_io(void);
+void iop_init_cp6_handler(void);
+void iop_init_time(unsigned long tickrate);
+void iop3xx_restart(enum reboot_mode, const char *);
+
+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 000000000..250760e08
--- /dev/null
+++ b/arch/arm/include/asm/hardware/iop_adma.h
@@ -0,0 +1,119 @@
+/*
+ * 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
+ * @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;
+ 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
+ * @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;
+ 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 000000000..d36a73d7c
--- /dev/null
+++ b/arch/arm/include/asm/hardware/it8152.h
@@ -0,0 +1,115 @@
+/*
+ * 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
+
+#include <mach/irqs.h>
+
+extern void __iomem *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(const struct pci_dev *dev, u8 slot, u8 pin);
+extern int it8152_pci_setup(int nr, struct pci_sys_data *sys);
+extern struct pci_ops it8152_ops;
+
+#endif /* __ASM_HARDWARE_IT8152_H */
diff --git a/arch/arm/include/asm/hardware/locomo.h b/arch/arm/include/asm/hardware/locomo.h
new file mode 100644
index 000000000..74e51d6bd
--- /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 000000000..42ba7c167
--- /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/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h
new file mode 100644
index 000000000..7c2bbc7f0
--- /dev/null
+++ b/arch/arm/include/asm/hardware/sa1111.h
@@ -0,0 +1,475 @@
+/*
+ * 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
+
+/*
+ * 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 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 */
+#define SA1111_KBD 0x0a00
+#define SA1111_MSE 0x0c00
+
+/* PCMCIA Interface */
+#define SA1111_PCMCIA 0x1600
+
+
+
+
+
+extern struct bus_type sa1111_bus_type;
+
+#define SA1111_DEVID_SBI (1 << 0)
+#define SA1111_DEVID_SK (1 << 1)
+#define SA1111_DEVID_USB (1 << 2)
+#define SA1111_DEVID_SAC (1 << 3)
+#define SA1111_DEVID_SSP (1 << 4)
+#define SA1111_DEVID_PS2 (3 << 5)
+#define SA1111_DEVID_PS2_KBD (1 << 5)
+#define SA1111_DEVID_PS2_MSE (1 << 6)
+#define SA1111_DEVID_GPIO (1 << 7)
+#define SA1111_DEVID_INT (1 << 8)
+#define SA1111_DEVID_PCMCIA (1 << 9)
+
+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 *);
+ void (*shutdown)(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, and call platform specific
+ * enable/disable functions.
+ */
+int 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 */
+ unsigned disable_devs;
+ void *data;
+ int (*enable)(void *, unsigned);
+ void (*disable)(void *, unsigned);
+};
+
+#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 000000000..58cdf5d84
--- /dev/null
+++ b/arch/arm/include/asm/hardware/scoop.h
@@ -0,0 +1,71 @@
+/*
+ * 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 (*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/ssp.h b/arch/arm/include/asm/hardware/ssp.h
new file mode 100644
index 000000000..3b42e1819
--- /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 000000000..bb28af7c3
--- /dev/null
+++ b/arch/arm/include/asm/hardware/timer-sp.h
@@ -0,0 +1,23 @@
+struct clk;
+
+void __sp804_clocksource_and_sched_clock_init(void __iomem *,
+ const char *, struct clk *, int);
+void __sp804_clockevents_init(void __iomem *, unsigned int,
+ struct clk *, const char *);
+
+static inline void sp804_clocksource_init(void __iomem *base, const char *name)
+{
+ __sp804_clocksource_and_sched_clock_init(base, name, NULL, 0);
+}
+
+static inline void sp804_clocksource_and_sched_clock_init(void __iomem *base,
+ const char *name)
+{
+ __sp804_clocksource_and_sched_clock_init(base, name, NULL, 1);
+}
+
+static inline void sp804_clockevents_init(void __iomem *base, unsigned int irq, const char *name)
+{
+ __sp804_clockevents_init(base, irq, NULL, name);
+
+}
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
new file mode 100644
index 000000000..535579511
--- /dev/null
+++ b/arch/arm/include/asm/highmem.h
@@ -0,0 +1,74 @@
+#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 pte_t *fixmap_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
+
+/*
+ * Needed to be able to broadcast the TLB invalidation for kmap.
+ */
+#ifdef CONFIG_ARM_ERRATA_798181
+#undef ARCH_NEEDS_KMAP_HIGH_GET
+#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/hugetlb-3level.h b/arch/arm/include/asm/hugetlb-3level.h
new file mode 100644
index 000000000..d4014fbe5
--- /dev/null
+++ b/arch/arm/include/asm/hugetlb-3level.h
@@ -0,0 +1,71 @@
+/*
+ * arch/arm/include/asm/hugetlb-3level.h
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * Based on arch/x86/include/asm/hugetlb.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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_HUGETLB_3LEVEL_H
+#define _ASM_ARM_HUGETLB_3LEVEL_H
+
+
+/*
+ * If our huge pte is non-zero then mark the valid bit.
+ * This allows pte_present(huge_ptep_get(ptep)) to return true for non-zero
+ * ptes.
+ * (The valid bit is automatically cleared by set_pte_at for PROT_NONE ptes).
+ */
+static inline pte_t huge_ptep_get(pte_t *ptep)
+{
+ pte_t retval = *ptep;
+ if (pte_val(retval))
+ pte_val(retval) |= L_PTE_VALID;
+ return retval;
+}
+
+static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte)
+{
+ set_pte_at(mm, addr, ptep, pte);
+}
+
+static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+{
+ ptep_clear_flush(vma, addr, ptep);
+}
+
+static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ ptep_set_wrprotect(mm, addr, ptep);
+}
+
+static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ return ptep_get_and_clear(mm, addr, ptep);
+}
+
+static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ pte_t pte, int dirty)
+{
+ return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
+}
+
+#endif /* _ASM_ARM_HUGETLB_3LEVEL_H */
diff --git a/arch/arm/include/asm/hugetlb.h b/arch/arm/include/asm/hugetlb.h
new file mode 100644
index 000000000..1f1b1cd11
--- /dev/null
+++ b/arch/arm/include/asm/hugetlb.h
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/include/asm/hugetlb.h
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * Based on arch/x86/include/asm/hugetlb.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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_HUGETLB_H
+#define _ASM_ARM_HUGETLB_H
+
+#include <asm/page.h>
+#include <asm-generic/hugetlb.h>
+
+#include <asm/hugetlb-3level.h>
+
+static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
+ unsigned long addr, unsigned long end,
+ unsigned long floor,
+ unsigned long ceiling)
+{
+ free_pgd_range(tlb, addr, end, floor, ceiling);
+}
+
+
+static inline int is_hugepage_only_range(struct mm_struct *mm,
+ unsigned long addr, unsigned long len)
+{
+ return 0;
+}
+
+static inline int prepare_hugepage_range(struct file *file,
+ unsigned long addr, unsigned long len)
+{
+ struct hstate *h = hstate_file(file);
+ if (len & ~huge_page_mask(h))
+ return -EINVAL;
+ if (addr & ~huge_page_mask(h))
+ return -EINVAL;
+ return 0;
+}
+
+static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm)
+{
+}
+
+static inline int huge_pte_none(pte_t pte)
+{
+ return pte_none(pte);
+}
+
+static inline pte_t huge_pte_wrprotect(pte_t pte)
+{
+ return pte_wrprotect(pte);
+}
+
+static inline int arch_prepare_hugepage(struct page *page)
+{
+ return 0;
+}
+
+static inline void arch_release_hugepage(struct page *page)
+{
+}
+
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+ clear_bit(PG_dcache_clean, &page->flags);
+}
+
+#endif /* _ASM_ARM_HUGETLB_H */
diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h
new file mode 100644
index 000000000..8e427c7b4
--- /dev/null
+++ b/arch/arm/include/asm/hw_breakpoint.h
@@ -0,0 +1,139 @@
+#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
+#define ARM_DEBUG_ARCH_V7_1 5
+#define ARM_DEBUG_ARCH_V8 6
+
+/* Breakpoint */
+#define ARM_BREAKPOINT_EXECUTE 0
+
+/* Watchpoints */
+#define ARM_BREAKPOINT_LOAD 1
+#define ARM_BREAKPOINT_STORE 2
+#define ARM_FSR_ACCESS_MASK (1 << 11)
+
+/* 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)
+
+/* OSLSR os lock model bits */
+#define ARM_OSLSR_OSLM0 (1 << 0)
+
+/* 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(N, M, OP2, VAL) do {\
+ asm volatile("mrc p14, 0, %0, " #N "," #M ", " #OP2 : "=r" (VAL));\
+} while (0)
+
+#define ARM_DBG_WRITE(N, M, OP2, VAL) do {\
+ asm volatile("mcr p14, 0, %0, " #N "," #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 000000000..af79da40a
--- /dev/null
+++ b/arch/arm/include/asm/hw_irq.h
@@ -0,0 +1,22 @@
+/*
+ * 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++;
+ pr_crit("unexpected IRQ trap at vector %02x\n", irq);
+}
+
+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 000000000..6e183fd26
--- /dev/null
+++ b/arch/arm/include/asm/hwcap.h
@@ -0,0 +1,15 @@
+#ifndef __ASMARM_HWCAP_H
+#define __ASMARM_HWCAP_H
+
+#include <uapi/asm/hwcap.h>
+
+#if !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)
+#define ELF_HWCAP2 (elf_hwcap2)
+extern unsigned int elf_hwcap, elf_hwcap2;
+#endif
+#endif
diff --git a/arch/arm/include/asm/hypervisor.h b/arch/arm/include/asm/hypervisor.h
new file mode 100644
index 000000000..b90d9e523
--- /dev/null
+++ b/arch/arm/include/asm/hypervisor.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_ARM_HYPERVISOR_H
+#define _ASM_ARM_HYPERVISOR_H
+
+#include <asm/xen/hypervisor.h>
+
+#endif
diff --git a/arch/arm/include/asm/ide.h b/arch/arm/include/asm/ide.h
new file mode 100644
index 000000000..b507ce8e5
--- /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/idmap.h b/arch/arm/include/asm/idmap.h
new file mode 100644
index 000000000..bf863edb5
--- /dev/null
+++ b/arch/arm/include/asm/idmap.h
@@ -0,0 +1,14 @@
+#ifndef __ASM_IDMAP_H
+#define __ASM_IDMAP_H
+
+#include <linux/compiler.h>
+#include <asm/pgtable.h>
+
+/* Tag a function as requiring to be executed via an identity mapping. */
+#define __idmap __section(.idmap.text) noinline notrace
+
+extern pgd_t *idmap_pgd;
+
+void setup_mm_for_reboot(void);
+
+#endif /* __ASM_IDMAP_H */
diff --git a/arch/arm/include/asm/insn.h b/arch/arm/include/asm/insn.h
new file mode 100644
index 000000000..e96065da4
--- /dev/null
+++ b/arch/arm/include/asm/insn.h
@@ -0,0 +1,29 @@
+#ifndef __ASM_ARM_INSN_H
+#define __ASM_ARM_INSN_H
+
+static inline unsigned long
+arm_gen_nop(void)
+{
+#ifdef CONFIG_THUMB2_KERNEL
+ return 0xf3af8000; /* nop.w */
+#else
+ return 0xe1a00000; /* mov r0, r0 */
+#endif
+}
+
+unsigned long
+__arm_gen_branch(unsigned long pc, unsigned long addr, bool link);
+
+static inline unsigned long
+arm_gen_branch(unsigned long pc, unsigned long addr)
+{
+ return __arm_gen_branch(pc, addr, false);
+}
+
+static inline unsigned long
+arm_gen_branch_link(unsigned long pc, unsigned long addr)
+{
+ return __arm_gen_branch(pc, addr, true);
+}
+
+#endif
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
new file mode 100644
index 000000000..db58deb00
--- /dev/null
+++ b/arch/arm/include/asm/io.h
@@ -0,0 +1,406 @@
+/*
+ * 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 <linux/blk_types.h>
+#include <asm/byteorder.h>
+#include <asm/memory.h>
+#include <asm-generic/pci_iomap.h>
+#include <xen/xen.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
+
+/*
+ * Atomic MMIO-wide IO modify
+ */
+extern void atomic_io_modify(void __iomem *reg, u32 mask, u32 set);
+extern void atomic_io_modify_relaxed(void __iomem *reg, u32 mask, u32 set);
+
+/*
+ * Generic IO read/write. These perform native-endian accesses. Note
+ * that some architectures will want to re-define __raw_{read,write}w.
+ */
+void __raw_writesb(volatile void __iomem *addr, const void *data, int bytelen);
+void __raw_writesw(volatile void __iomem *addr, const void *data, int wordlen);
+void __raw_writesl(volatile void __iomem *addr, const void *data, int longlen);
+
+void __raw_readsb(const volatile void __iomem *addr, void *data, int bytelen);
+void __raw_readsw(const volatile void __iomem *addr, void *data, int wordlen);
+void __raw_readsl(const volatile void __iomem *addr, void *data, int longlen);
+
+#if __LINUX_ARM_ARCH__ < 6
+/*
+ * Half-word accesses are problematic with RiscPC due to limitations of
+ * the bus. Rather than special-case the machine, just let the compiler
+ * generate the access for CPUs prior to ARMv6.
+ */
+#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
+#define __raw_writew(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v)))
+#else
+/*
+ * When running under a hypervisor, we want to avoid I/O accesses with
+ * writeback addressing modes as these incur a significant performance
+ * overhead (the address generation must be emulated in software).
+ */
+#define __raw_writew __raw_writew
+static inline void __raw_writew(u16 val, volatile void __iomem *addr)
+{
+ asm volatile("strh %1, %0"
+ : "+Q" (*(volatile u16 __force *)addr)
+ : "r" (val));
+}
+
+#define __raw_readw __raw_readw
+static inline u16 __raw_readw(const volatile void __iomem *addr)
+{
+ u16 val;
+ asm volatile("ldrh %1, %0"
+ : "+Q" (*(volatile u16 __force *)addr),
+ "=r" (val));
+ return val;
+}
+#endif
+
+#define __raw_writeb __raw_writeb
+static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
+{
+ asm volatile("strb %1, %0"
+ : "+Qo" (*(volatile u8 __force *)addr)
+ : "r" (val));
+}
+
+#define __raw_writel __raw_writel
+static inline void __raw_writel(u32 val, volatile void __iomem *addr)
+{
+ asm volatile("str %1, %0"
+ : "+Qo" (*(volatile u32 __force *)addr)
+ : "r" (val));
+}
+
+#define __raw_readb __raw_readb
+static inline u8 __raw_readb(const volatile void __iomem *addr)
+{
+ u8 val;
+ asm volatile("ldrb %1, %0"
+ : "+Qo" (*(volatile u8 __force *)addr),
+ "=r" (val));
+ return val;
+}
+
+#define __raw_readl __raw_readl
+static inline u32 __raw_readl(const volatile void __iomem *addr)
+{
+ u32 val;
+ asm volatile("ldr %1, %0"
+ : "+Qo" (*(volatile u32 __force *)addr),
+ "=r" (val));
+ return val;
+}
+
+/*
+ * 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(phys_addr_t, size_t, unsigned int,
+ void *);
+
+extern void __iomem *__arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int);
+extern void __iomem *__arm_ioremap(phys_addr_t, size_t, unsigned int);
+extern void __iomem *__arm_ioremap_exec(phys_addr_t, size_t, bool cached);
+extern void __iounmap(volatile void __iomem *addr);
+extern void __arm_iounmap(volatile void __iomem *addr);
+
+extern void __iomem * (*arch_ioremap_caller)(phys_addr_t, size_t,
+ unsigned int, void *);
+extern void (*arch_iounmap)(volatile void __iomem *);
+
+/*
+ * 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;
+}
+
+#define IOMEM(x) ((void __force __iomem *)(x))
+
+/* IO barriers */
+#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
+#include <asm/barrier.h>
+#define __iormb() rmb()
+#define __iowmb() wmb()
+#else
+#define __iormb() do { } while (0)
+#define __iowmb() do { } while (0)
+#endif
+
+/* PCI fixed i/o mapping */
+#define PCI_IO_VIRT_BASE 0xfee00000
+#define PCI_IOBASE ((void __iomem *)PCI_IO_VIRT_BASE)
+
+#if defined(CONFIG_PCI)
+void pci_ioremap_set_mem_type(int mem_type);
+#else
+static inline void pci_ioremap_set_mem_type(int mem_type) {}
+#endif
+
+extern int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr);
+
+/*
+ * Now, pick up the machine-defined IO definitions
+ */
+#ifdef CONFIG_NEED_MACH_IO_H
+#include <mach/io.h>
+#elif defined(CONFIG_PCI)
+#define IO_SPACE_LIMIT ((resource_size_t)0xfffff)
+#define __io(a) __typesafe_io(PCI_IO_VIRT_BASE + ((a) & IO_SPACE_LIMIT))
+#else
+#define __io(a) __typesafe_io((a) & IO_SPACE_LIMIT)
+#endif
+
+/*
+ * This is the limit of PC card/PCI/ISA IO space, which is by default
+ * 64K if we have PC card, PCI or ISA support. Otherwise, default to
+ * zero to prevent ISA/PCI drivers claiming IO space (and potentially
+ * oopsing.)
+ *
+ * Only set this larger if you really need inb() et.al. to operate over
+ * a larger address space. Note that SOC_COMMON ioremaps each sockets
+ * IO space area, and so inb() et.al. must be defined to operate as per
+ * readb() et.al. on such platforms.
+ */
+#ifndef IO_SPACE_LIMIT
+#if defined(CONFIG_PCMCIA_SOC_COMMON) || defined(CONFIG_PCMCIA_SOC_COMMON_MODULE)
+#define IO_SPACE_LIMIT ((resource_size_t)0xffffffff)
+#elif defined(CONFIG_PCI) || defined(CONFIG_ISA) || defined(CONFIG_PCCARD)
+#define IO_SPACE_LIMIT ((resource_size_t)0xffff)
+#else
+#define IO_SPACE_LIMIT ((resource_size_t)0)
+#endif
+#endif
+
+/*
+ * 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
+
+/*
+ * 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.
+ */
+#ifndef readl
+#define readb_relaxed(c) ({ u8 __r = __raw_readb(c); __r; })
+#define readw_relaxed(c) ({ u16 __r = le16_to_cpu((__force __le16) \
+ __raw_readw(c)); __r; })
+#define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \
+ __raw_readl(c)); __r; })
+
+#define writeb_relaxed(v,c) __raw_writeb(v,c)
+#define writew_relaxed(v,c) __raw_writew((__force u16) cpu_to_le16(v),c)
+#define writel_relaxed(v,c) __raw_writel((__force u32) cpu_to_le32(v),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(p,d,l)
+#define readsw(p,d,l) __raw_readsw(p,d,l)
+#define readsl(p,d,l) __raw_readsl(p,d,l)
+
+#define writesb(p,d,l) __raw_writesb(p,d,l)
+#define writesw(p,d,l) __raw_writesw(p,d,l)
+#define writesl(p,d,l) __raw_writesl(p,d,l)
+
+#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 /* readl */
+
+/*
+ * ioremap and friends.
+ *
+ * ioremap takes a PCI memory address, as specified in
+ * Documentation/io-mapping.txt.
+ *
+ */
+#define ioremap(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE)
+#define ioremap_nocache(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE)
+#define ioremap_cache(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_CACHED)
+#define ioremap_wc(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_WC)
+#define iounmap __arm_iounmap
+
+/*
+ * io{read,write}{16,32}be() macros
+ */
+#define ioread16be(p) ({ __u16 __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; })
+#define ioread32be(p) ({ __u32 __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; })
+
+#define iowrite16be(v,p) ({ __iowmb(); __raw_writew((__force __u16)cpu_to_be16(v), p); })
+#define iowrite32be(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); })
+
+#ifndef ioport_map
+#define ioport_map ioport_map
+extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
+#endif
+#ifndef ioport_unmap
+#define ioport_unmap ioport_unmap
+extern void ioport_unmap(void __iomem *addr);
+#endif
+
+struct pci_dev;
+
+#define pci_iounmap pci_iounmap
+extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
+
+/*
+ * 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
+
+#include <asm-generic/io.h>
+
+/*
+ * 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)))
+
+struct bio_vec;
+extern bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
+ const struct bio_vec *vec2);
+#define BIOVEC_PHYS_MERGEABLE(vec1, vec2) \
+ (__BIOVEC_PHYS_MERGEABLE(vec1, vec2) && \
+ (!xen_domain() || xen_biovec_phys_mergeable(vec1, vec2)))
+
+#ifdef CONFIG_MMU
+#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
+extern int valid_phys_addr_range(phys_addr_t 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
+
+/*
+ * 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/irq.h b/arch/arm/include/asm/irq.h
new file mode 100644
index 000000000..53c15dec7
--- /dev/null
+++ b/arch/arm/include/asm/irq.h
@@ -0,0 +1,41 @@
+#ifndef __ASM_ARM_IRQ_H
+#define __ASM_ARM_IRQ_H
+
+#define NR_IRQS_LEGACY 16
+
+#ifndef CONFIG_SPARSE_IRQ
+#include <mach/irqs.h>
+#else
+#define NR_IRQS NR_IRQS_LEGACY
+#endif
+
+#ifndef irq_canonicalize
+#define irq_canonicalize(i) (i)
+#endif
+
+/*
+ * 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);
+
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+extern void (*handle_arch_irq)(struct pt_regs *);
+extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
+#endif
+
+#endif
+
+#endif
+
diff --git a/arch/arm/include/asm/irq_work.h b/arch/arm/include/asm/irq_work.h
new file mode 100644
index 000000000..712d03e59
--- /dev/null
+++ b/arch/arm/include/asm/irq_work.h
@@ -0,0 +1,11 @@
+#ifndef __ASM_ARM_IRQ_WORK_H
+#define __ASM_ARM_IRQ_WORK_H
+
+#include <asm/smp_plat.h>
+
+static inline bool arch_irq_work_has_interrupt(void)
+{
+ return is_smp();
+}
+
+#endif /* _ASM_ARM_IRQ_WORK_H */
diff --git a/arch/arm/include/asm/irqflags.h b/arch/arm/include/asm/irqflags.h
new file mode 100644
index 000000000..3b763d665
--- /dev/null
+++ b/arch/arm/include/asm/irqflags.h
@@ -0,0 +1,165 @@
+#ifndef __ASM_ARM_IRQFLAGS_H
+#define __ASM_ARM_IRQFLAGS_H
+
+#ifdef __KERNEL__
+
+#include <asm/ptrace.h>
+
+/*
+ * CPU interrupt mask handling.
+ */
+#ifdef CONFIG_CPU_V7M
+#define IRQMASK_REG_NAME_R "primask"
+#define IRQMASK_REG_NAME_W "primask"
+#define IRQMASK_I_BIT 1
+#else
+#define IRQMASK_REG_NAME_R "cpsr"
+#define IRQMASK_REG_NAME_W "cpsr_c"
+#define IRQMASK_I_BIT PSR_I_BIT
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 6
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags;
+
+ asm volatile(
+ " mrs %0, " IRQMASK_REG_NAME_R " @ 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, " IRQMASK_REG_NAME_R " @ 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 " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore"
+ :
+ : "r" (flags)
+ : "memory", "cc");
+}
+
+static inline int arch_irqs_disabled_flags(unsigned long flags)
+{
+ return flags & IRQMASK_I_BIT;
+}
+
+#endif /* ifdef __KERNEL__ */
+#endif /* ifndef __ASM_ARM_IRQFLAGS_H */
diff --git a/arch/arm/include/asm/jump_label.h b/arch/arm/include/asm/jump_label.h
new file mode 100644
index 000000000..5f337dc5c
--- /dev/null
+++ b/arch/arm/include/asm/jump_label.h
@@ -0,0 +1,39 @@
+#ifndef _ASM_ARM_JUMP_LABEL_H
+#define _ASM_ARM_JUMP_LABEL_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+#define JUMP_LABEL_NOP_SIZE 4
+
+#ifdef CONFIG_THUMB2_KERNEL
+#define JUMP_LABEL_NOP "nop.w"
+#else
+#define JUMP_LABEL_NOP "nop"
+#endif
+
+static __always_inline bool arch_static_branch(struct static_key *key)
+{
+ asm_volatile_goto("1:\n\t"
+ JUMP_LABEL_NOP "\n\t"
+ ".pushsection __jump_table, \"aw\"\n\t"
+ ".word 1b, %l[l_yes], %c0\n\t"
+ ".popsection\n\t"
+ : : "i" (key) : : l_yes);
+
+ return false;
+l_yes:
+ return true;
+}
+
+typedef u32 jump_label_t;
+
+struct jump_entry {
+ jump_label_t code;
+ jump_label_t target;
+ jump_label_t key;
+};
+
+#endif /* __ASSEMBLY__ */
+#endif
diff --git a/arch/arm/include/asm/kexec.h b/arch/arm/include/asm/kexec.h
new file mode 100644
index 000000000..c2b9b4bde
--- /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 000000000..0a9d5dd93
--- /dev/null
+++ b/arch/arm/include/asm/kgdb.h
@@ -0,0 +1,106 @@
+/*
+ * 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>
+#include <asm/opcodes.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(__inst_arm(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 000000000..83eb2f772
--- /dev/null
+++ b/arch/arm/include/asm/kmap_types.h
@@ -0,0 +1,9 @@
+#ifndef __ARM_KMAP_TYPES_H
+#define __ARM_KMAP_TYPES_H
+
+/*
+ * This is the "bare minimum". AIO seems to require this.
+ */
+#define KM_TYPE_NR 16
+
+#endif
diff --git a/arch/arm/include/asm/kprobes.h b/arch/arm/include/asm/kprobes.h
new file mode 100644
index 000000000..3ea9be559
--- /dev/null
+++ b/arch/arm/include/asm/kprobes.h
@@ -0,0 +1,86 @@
+/*
+ * 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/notifier.h>
+
+#define __ARCH_WANT_KPROBES_INSN_SLOT
+#define MAX_INSN_SIZE 2
+
+#define flush_insn_slot(p) do { } while (0)
+#define kretprobe_blacklist_size 0
+
+typedef u32 kprobe_opcode_t;
+struct kprobe;
+#include <asm/probes.h>
+
+#define arch_specific_insn arch_probes_insn
+
+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 *);
+int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
+int kprobe_exceptions_notify(struct notifier_block *self,
+ unsigned long val, void *data);
+
+/* optinsn template addresses */
+extern __visible kprobe_opcode_t optprobe_template_entry;
+extern __visible kprobe_opcode_t optprobe_template_val;
+extern __visible kprobe_opcode_t optprobe_template_call;
+extern __visible kprobe_opcode_t optprobe_template_end;
+extern __visible kprobe_opcode_t optprobe_template_sub_sp;
+extern __visible kprobe_opcode_t optprobe_template_add_sp;
+extern __visible kprobe_opcode_t optprobe_template_restore_begin;
+extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn;
+extern __visible kprobe_opcode_t optprobe_template_restore_end;
+
+#define MAX_OPTIMIZED_LENGTH 4
+#define MAX_OPTINSN_SIZE \
+ ((unsigned long)&optprobe_template_end - \
+ (unsigned long)&optprobe_template_entry)
+#define RELATIVEJUMP_SIZE 4
+
+struct arch_optimized_insn {
+ /*
+ * copy of the original instructions.
+ * Different from x86, ARM kprobe_opcode_t is u32.
+ */
+#define MAX_COPIED_INSN DIV_ROUND_UP(RELATIVEJUMP_SIZE, sizeof(kprobe_opcode_t))
+ kprobe_opcode_t copied_insn[MAX_COPIED_INSN];
+ /* detour code buffer */
+ kprobe_opcode_t *insn;
+ /*
+ * We always copy one instruction on ARM,
+ * so size will always be 4, and unlike x86, there is no
+ * need for a size field.
+ */
+};
+
+#endif /* _ARM_KPROBES_H */
diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h
new file mode 100644
index 000000000..d995821f1
--- /dev/null
+++ b/arch/arm/include/asm/kvm_arm.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ARM_KVM_ARM_H__
+#define __ARM_KVM_ARM_H__
+
+#include <linux/types.h>
+
+/* Hyp Configuration Register (HCR) bits */
+#define HCR_TGE (1 << 27)
+#define HCR_TVM (1 << 26)
+#define HCR_TTLB (1 << 25)
+#define HCR_TPU (1 << 24)
+#define HCR_TPC (1 << 23)
+#define HCR_TSW (1 << 22)
+#define HCR_TAC (1 << 21)
+#define HCR_TIDCP (1 << 20)
+#define HCR_TSC (1 << 19)
+#define HCR_TID3 (1 << 18)
+#define HCR_TID2 (1 << 17)
+#define HCR_TID1 (1 << 16)
+#define HCR_TID0 (1 << 15)
+#define HCR_TWE (1 << 14)
+#define HCR_TWI (1 << 13)
+#define HCR_DC (1 << 12)
+#define HCR_BSU (3 << 10)
+#define HCR_BSU_IS (1 << 10)
+#define HCR_FB (1 << 9)
+#define HCR_VA (1 << 8)
+#define HCR_VI (1 << 7)
+#define HCR_VF (1 << 6)
+#define HCR_AMO (1 << 5)
+#define HCR_IMO (1 << 4)
+#define HCR_FMO (1 << 3)
+#define HCR_PTW (1 << 2)
+#define HCR_SWIO (1 << 1)
+#define HCR_VM 1
+
+/*
+ * The bits we set in HCR:
+ * TAC: Trap ACTLR
+ * TSC: Trap SMC
+ * TVM: Trap VM ops (until MMU and caches are on)
+ * TSW: Trap cache operations by set/way
+ * TWI: Trap WFI
+ * TWE: Trap WFE
+ * TIDCP: Trap L2CTLR/L2ECTLR
+ * BSU_IS: Upgrade barriers to the inner shareable domain
+ * FB: Force broadcast of all maintainance operations
+ * AMO: Override CPSR.A and enable signaling with VA
+ * IMO: Override CPSR.I and enable signaling with VI
+ * FMO: Override CPSR.F and enable signaling with VF
+ * SWIO: Turn set/way invalidates into set/way clean+invalidate
+ */
+#define HCR_GUEST_MASK (HCR_TSC | HCR_TSW | HCR_TWI | HCR_VM | HCR_BSU_IS | \
+ HCR_FB | HCR_TAC | HCR_AMO | HCR_IMO | HCR_FMO | \
+ HCR_TVM | HCR_TWE | HCR_SWIO | HCR_TIDCP)
+
+/* System Control Register (SCTLR) bits */
+#define SCTLR_TE (1 << 30)
+#define SCTLR_EE (1 << 25)
+#define SCTLR_V (1 << 13)
+
+/* Hyp System Control Register (HSCTLR) bits */
+#define HSCTLR_TE (1 << 30)
+#define HSCTLR_EE (1 << 25)
+#define HSCTLR_FI (1 << 21)
+#define HSCTLR_WXN (1 << 19)
+#define HSCTLR_I (1 << 12)
+#define HSCTLR_C (1 << 2)
+#define HSCTLR_A (1 << 1)
+#define HSCTLR_M 1
+#define HSCTLR_MASK (HSCTLR_M | HSCTLR_A | HSCTLR_C | HSCTLR_I | \
+ HSCTLR_WXN | HSCTLR_FI | HSCTLR_EE | HSCTLR_TE)
+
+/* TTBCR and HTCR Registers bits */
+#define TTBCR_EAE (1 << 31)
+#define TTBCR_IMP (1 << 30)
+#define TTBCR_SH1 (3 << 28)
+#define TTBCR_ORGN1 (3 << 26)
+#define TTBCR_IRGN1 (3 << 24)
+#define TTBCR_EPD1 (1 << 23)
+#define TTBCR_A1 (1 << 22)
+#define TTBCR_T1SZ (7 << 16)
+#define TTBCR_SH0 (3 << 12)
+#define TTBCR_ORGN0 (3 << 10)
+#define TTBCR_IRGN0 (3 << 8)
+#define TTBCR_EPD0 (1 << 7)
+#define TTBCR_T0SZ (7 << 0)
+#define HTCR_MASK (TTBCR_T0SZ | TTBCR_IRGN0 | TTBCR_ORGN0 | TTBCR_SH0)
+
+/* Hyp System Trap Register */
+#define HSTR_T(x) (1 << x)
+#define HSTR_TTEE (1 << 16)
+#define HSTR_TJDBX (1 << 17)
+
+/* Hyp Coprocessor Trap Register */
+#define HCPTR_TCP(x) (1 << x)
+#define HCPTR_TCP_MASK (0x3fff)
+#define HCPTR_TASE (1 << 15)
+#define HCPTR_TTA (1 << 20)
+#define HCPTR_TCPAC (1 << 31)
+
+/* Hyp Debug Configuration Register bits */
+#define HDCR_TDRA (1 << 11)
+#define HDCR_TDOSA (1 << 10)
+#define HDCR_TDA (1 << 9)
+#define HDCR_TDE (1 << 8)
+#define HDCR_HPME (1 << 7)
+#define HDCR_TPM (1 << 6)
+#define HDCR_TPMCR (1 << 5)
+#define HDCR_HPMN_MASK (0x1F)
+
+/*
+ * The architecture supports 40-bit IPA as input to the 2nd stage translations
+ * and PTRS_PER_S2_PGD becomes 1024, because each entry covers 1GB of address
+ * space.
+ */
+#define KVM_PHYS_SHIFT (40)
+#define KVM_PHYS_SIZE (1ULL << KVM_PHYS_SHIFT)
+#define KVM_PHYS_MASK (KVM_PHYS_SIZE - 1ULL)
+#define PTRS_PER_S2_PGD (1ULL << (KVM_PHYS_SHIFT - 30))
+#define S2_PGD_ORDER get_order(PTRS_PER_S2_PGD * sizeof(pgd_t))
+
+/* Virtualization Translation Control Register (VTCR) bits */
+#define VTCR_SH0 (3 << 12)
+#define VTCR_ORGN0 (3 << 10)
+#define VTCR_IRGN0 (3 << 8)
+#define VTCR_SL0 (3 << 6)
+#define VTCR_S (1 << 4)
+#define VTCR_T0SZ (0xf)
+#define VTCR_MASK (VTCR_SH0 | VTCR_ORGN0 | VTCR_IRGN0 | VTCR_SL0 | \
+ VTCR_S | VTCR_T0SZ)
+#define VTCR_HTCR_SH (VTCR_SH0 | VTCR_ORGN0 | VTCR_IRGN0)
+#define VTCR_SL_L2 (0 << 6) /* Starting-level: 2 */
+#define VTCR_SL_L1 (1 << 6) /* Starting-level: 1 */
+#define KVM_VTCR_SL0 VTCR_SL_L1
+/* stage-2 input address range defined as 2^(32-T0SZ) */
+#define KVM_T0SZ (32 - KVM_PHYS_SHIFT)
+#define KVM_VTCR_T0SZ (KVM_T0SZ & VTCR_T0SZ)
+#define KVM_VTCR_S ((KVM_VTCR_T0SZ << 1) & VTCR_S)
+
+/* Virtualization Translation Table Base Register (VTTBR) bits */
+#if KVM_VTCR_SL0 == VTCR_SL_L2 /* see ARM DDI 0406C: B4-1720 */
+#define VTTBR_X (14 - KVM_T0SZ)
+#else
+#define VTTBR_X (5 - KVM_T0SZ)
+#endif
+#define VTTBR_BADDR_SHIFT (VTTBR_X - 1)
+#define VTTBR_BADDR_MASK (((1LLU << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
+#define VTTBR_VMID_SHIFT (48LLU)
+#define VTTBR_VMID_MASK (0xffLLU << VTTBR_VMID_SHIFT)
+
+/* Hyp Syndrome Register (HSR) bits */
+#define HSR_EC_SHIFT (26)
+#define HSR_EC (0x3fU << HSR_EC_SHIFT)
+#define HSR_IL (1U << 25)
+#define HSR_ISS (HSR_IL - 1)
+#define HSR_ISV_SHIFT (24)
+#define HSR_ISV (1U << HSR_ISV_SHIFT)
+#define HSR_SRT_SHIFT (16)
+#define HSR_SRT_MASK (0xf << HSR_SRT_SHIFT)
+#define HSR_FSC (0x3f)
+#define HSR_FSC_TYPE (0x3c)
+#define HSR_SSE (1 << 21)
+#define HSR_WNR (1 << 6)
+#define HSR_CV_SHIFT (24)
+#define HSR_CV (1U << HSR_CV_SHIFT)
+#define HSR_COND_SHIFT (20)
+#define HSR_COND (0xfU << HSR_COND_SHIFT)
+
+#define FSC_FAULT (0x04)
+#define FSC_ACCESS (0x08)
+#define FSC_PERM (0x0c)
+
+/* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
+#define HPFAR_MASK (~0xf)
+
+#define HSR_EC_UNKNOWN (0x00)
+#define HSR_EC_WFI (0x01)
+#define HSR_EC_CP15_32 (0x03)
+#define HSR_EC_CP15_64 (0x04)
+#define HSR_EC_CP14_MR (0x05)
+#define HSR_EC_CP14_LS (0x06)
+#define HSR_EC_CP_0_13 (0x07)
+#define HSR_EC_CP10_ID (0x08)
+#define HSR_EC_JAZELLE (0x09)
+#define HSR_EC_BXJ (0x0A)
+#define HSR_EC_CP14_64 (0x0C)
+#define HSR_EC_SVC_HYP (0x11)
+#define HSR_EC_HVC (0x12)
+#define HSR_EC_SMC (0x13)
+#define HSR_EC_IABT (0x20)
+#define HSR_EC_IABT_HYP (0x21)
+#define HSR_EC_DABT (0x24)
+#define HSR_EC_DABT_HYP (0x25)
+
+#define HSR_WFI_IS_WFE (1U << 0)
+
+#define HSR_HVC_IMM_MASK ((1UL << 16) - 1)
+
+#define HSR_DABT_S1PTW (1U << 7)
+#define HSR_DABT_CM (1U << 8)
+#define HSR_DABT_EA (1U << 9)
+
+#endif /* __ARM_KVM_ARM_H__ */
diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
new file mode 100644
index 000000000..25410b2d8
--- /dev/null
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ARM_KVM_ASM_H__
+#define __ARM_KVM_ASM_H__
+
+/* 0 is reserved as an invalid value. */
+#define c0_MPIDR 1 /* MultiProcessor ID Register */
+#define c0_CSSELR 2 /* Cache Size Selection Register */
+#define c1_SCTLR 3 /* System Control Register */
+#define c1_ACTLR 4 /* Auxilliary Control Register */
+#define c1_CPACR 5 /* Coprocessor Access Control */
+#define c2_TTBR0 6 /* Translation Table Base Register 0 */
+#define c2_TTBR0_high 7 /* TTBR0 top 32 bits */
+#define c2_TTBR1 8 /* Translation Table Base Register 1 */
+#define c2_TTBR1_high 9 /* TTBR1 top 32 bits */
+#define c2_TTBCR 10 /* Translation Table Base Control R. */
+#define c3_DACR 11 /* Domain Access Control Register */
+#define c5_DFSR 12 /* Data Fault Status Register */
+#define c5_IFSR 13 /* Instruction Fault Status Register */
+#define c5_ADFSR 14 /* Auxilary Data Fault Status R */
+#define c5_AIFSR 15 /* Auxilary Instrunction Fault Status R */
+#define c6_DFAR 16 /* Data Fault Address Register */
+#define c6_IFAR 17 /* Instruction Fault Address Register */
+#define c7_PAR 18 /* Physical Address Register */
+#define c7_PAR_high 19 /* PAR top 32 bits */
+#define c9_L2CTLR 20 /* Cortex A15/A7 L2 Control Register */
+#define c10_PRRR 21 /* Primary Region Remap Register */
+#define c10_NMRR 22 /* Normal Memory Remap Register */
+#define c12_VBAR 23 /* Vector Base Address Register */
+#define c13_CID 24 /* Context ID Register */
+#define c13_TID_URW 25 /* Thread ID, User R/W */
+#define c13_TID_URO 26 /* Thread ID, User R/O */
+#define c13_TID_PRIV 27 /* Thread ID, Privileged */
+#define c14_CNTKCTL 28 /* Timer Control Register (PL1) */
+#define c10_AMAIR0 29 /* Auxilary Memory Attribute Indirection Reg0 */
+#define c10_AMAIR1 30 /* Auxilary Memory Attribute Indirection Reg1 */
+#define NR_CP15_REGS 31 /* Number of regs (incl. invalid) */
+
+#define ARM_EXCEPTION_RESET 0
+#define ARM_EXCEPTION_UNDEFINED 1
+#define ARM_EXCEPTION_SOFTWARE 2
+#define ARM_EXCEPTION_PREF_ABORT 3
+#define ARM_EXCEPTION_DATA_ABORT 4
+#define ARM_EXCEPTION_IRQ 5
+#define ARM_EXCEPTION_FIQ 6
+#define ARM_EXCEPTION_HVC 7
+
+/*
+ * The rr_lo_hi macro swaps a pair of registers depending on
+ * current endianness. It is used in conjunction with ldrd and strd
+ * instructions that load/store a 64-bit value from/to memory to/from
+ * a pair of registers which are used with the mrrc and mcrr instructions.
+ * If used with the ldrd/strd instructions, the a1 parameter is the first
+ * source/destination register and the a2 parameter is the second
+ * source/destination register. Note that the ldrd/strd instructions
+ * already swap the bytes within the words correctly according to the
+ * endianness setting, but the order of the registers need to be effectively
+ * swapped when used with the mrrc/mcrr instructions.
+ */
+#ifdef CONFIG_CPU_ENDIAN_BE8
+#define rr_lo_hi(a1, a2) a2, a1
+#else
+#define rr_lo_hi(a1, a2) a1, a2
+#endif
+
+#ifndef __ASSEMBLY__
+struct kvm;
+struct kvm_vcpu;
+
+extern char __kvm_hyp_init[];
+extern char __kvm_hyp_init_end[];
+
+extern char __kvm_hyp_exit[];
+extern char __kvm_hyp_exit_end[];
+
+extern char __kvm_hyp_vector[];
+
+extern char __kvm_hyp_code_start[];
+extern char __kvm_hyp_code_end[];
+
+extern void __kvm_flush_vm_context(void);
+extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
+extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
+
+extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
+#endif
+
+#endif /* __ARM_KVM_ASM_H__ */
diff --git a/arch/arm/include/asm/kvm_coproc.h b/arch/arm/include/asm/kvm_coproc.h
new file mode 100644
index 000000000..4917c2f7e
--- /dev/null
+++ b/arch/arm/include/asm/kvm_coproc.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 Rusty Russell IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ARM_KVM_COPROC_H__
+#define __ARM_KVM_COPROC_H__
+#include <linux/kvm_host.h>
+
+void kvm_reset_coprocs(struct kvm_vcpu *vcpu);
+
+struct kvm_coproc_target_table {
+ unsigned target;
+ const struct coproc_reg *table;
+ size_t num;
+};
+void kvm_register_target_coproc_table(struct kvm_coproc_target_table *table);
+
+int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_cp_0_13_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
+
+unsigned long kvm_arm_num_guest_msrs(struct kvm_vcpu *vcpu);
+int kvm_arm_copy_msrindices(struct kvm_vcpu *vcpu, u64 __user *uindices);
+void kvm_coproc_table_init(void);
+
+struct kvm_one_reg;
+int kvm_arm_copy_coproc_indices(struct kvm_vcpu *vcpu, u64 __user *uindices);
+int kvm_arm_coproc_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *);
+int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *);
+unsigned long kvm_arm_num_coproc_regs(struct kvm_vcpu *vcpu);
+#endif /* __ARM_KVM_COPROC_H__ */
diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h
new file mode 100644
index 000000000..a9c80a2ea
--- /dev/null
+++ b/arch/arm/include/asm/kvm_emulate.h
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ARM_KVM_EMULATE_H__
+#define __ARM_KVM_EMULATE_H__
+
+#include <linux/kvm_host.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_mmio.h>
+#include <asm/kvm_arm.h>
+#include <asm/cputype.h>
+
+unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num);
+unsigned long *vcpu_spsr(struct kvm_vcpu *vcpu);
+
+bool kvm_condition_valid(struct kvm_vcpu *vcpu);
+void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr);
+void kvm_inject_undefined(struct kvm_vcpu *vcpu);
+void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr);
+void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr);
+
+static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.hcr = HCR_GUEST_MASK;
+}
+
+static inline unsigned long vcpu_get_hcr(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.hcr;
+}
+
+static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long hcr)
+{
+ vcpu->arch.hcr = hcr;
+}
+
+static inline bool vcpu_mode_is_32bit(struct kvm_vcpu *vcpu)
+{
+ return 1;
+}
+
+static inline unsigned long *vcpu_pc(struct kvm_vcpu *vcpu)
+{
+ return &vcpu->arch.regs.usr_regs.ARM_pc;
+}
+
+static inline unsigned long *vcpu_cpsr(struct kvm_vcpu *vcpu)
+{
+ return &vcpu->arch.regs.usr_regs.ARM_cpsr;
+}
+
+static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu)
+{
+ *vcpu_cpsr(vcpu) |= PSR_T_BIT;
+}
+
+static inline bool mode_has_spsr(struct kvm_vcpu *vcpu)
+{
+ unsigned long cpsr_mode = vcpu->arch.regs.usr_regs.ARM_cpsr & MODE_MASK;
+ return (cpsr_mode > USR_MODE && cpsr_mode < SYSTEM_MODE);
+}
+
+static inline bool vcpu_mode_priv(struct kvm_vcpu *vcpu)
+{
+ unsigned long cpsr_mode = vcpu->arch.regs.usr_regs.ARM_cpsr & MODE_MASK;
+ return cpsr_mode > USR_MODE;;
+}
+
+static inline u32 kvm_vcpu_get_hsr(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.fault.hsr;
+}
+
+static inline unsigned long kvm_vcpu_get_hfar(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.fault.hxfar;
+}
+
+static inline phys_addr_t kvm_vcpu_get_fault_ipa(struct kvm_vcpu *vcpu)
+{
+ return ((phys_addr_t)vcpu->arch.fault.hpfar & HPFAR_MASK) << 8;
+}
+
+static inline unsigned long kvm_vcpu_get_hyp_pc(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.fault.hyp_pc;
+}
+
+static inline bool kvm_vcpu_dabt_isvalid(struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_get_hsr(vcpu) & HSR_ISV;
+}
+
+static inline bool kvm_vcpu_dabt_iswrite(struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_get_hsr(vcpu) & HSR_WNR;
+}
+
+static inline bool kvm_vcpu_dabt_issext(struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_get_hsr(vcpu) & HSR_SSE;
+}
+
+static inline int kvm_vcpu_dabt_get_rd(struct kvm_vcpu *vcpu)
+{
+ return (kvm_vcpu_get_hsr(vcpu) & HSR_SRT_MASK) >> HSR_SRT_SHIFT;
+}
+
+static inline bool kvm_vcpu_dabt_isextabt(struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_get_hsr(vcpu) & HSR_DABT_EA;
+}
+
+static inline bool kvm_vcpu_dabt_iss1tw(struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_get_hsr(vcpu) & HSR_DABT_S1PTW;
+}
+
+/* Get Access Size from a data abort */
+static inline int kvm_vcpu_dabt_get_as(struct kvm_vcpu *vcpu)
+{
+ switch ((kvm_vcpu_get_hsr(vcpu) >> 22) & 0x3) {
+ case 0:
+ return 1;
+ case 1:
+ return 2;
+ case 2:
+ return 4;
+ default:
+ kvm_err("Hardware is weird: SAS 0b11 is reserved\n");
+ return -EFAULT;
+ }
+}
+
+/* This one is not specific to Data Abort */
+static inline bool kvm_vcpu_trap_il_is32bit(struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_get_hsr(vcpu) & HSR_IL;
+}
+
+static inline u8 kvm_vcpu_trap_get_class(struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_get_hsr(vcpu) >> HSR_EC_SHIFT;
+}
+
+static inline bool kvm_vcpu_trap_is_iabt(struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_trap_get_class(vcpu) == HSR_EC_IABT;
+}
+
+static inline u8 kvm_vcpu_trap_get_fault(struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_get_hsr(vcpu) & HSR_FSC;
+}
+
+static inline u8 kvm_vcpu_trap_get_fault_type(struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_get_hsr(vcpu) & HSR_FSC_TYPE;
+}
+
+static inline u32 kvm_vcpu_hvc_get_imm(struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_get_hsr(vcpu) & HSR_HVC_IMM_MASK;
+}
+
+static inline unsigned long kvm_vcpu_get_mpidr_aff(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.cp15[c0_MPIDR] & MPIDR_HWID_BITMASK;
+}
+
+static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu)
+{
+ *vcpu_cpsr(vcpu) |= PSR_E_BIT;
+}
+
+static inline bool kvm_vcpu_is_be(struct kvm_vcpu *vcpu)
+{
+ return !!(*vcpu_cpsr(vcpu) & PSR_E_BIT);
+}
+
+static inline unsigned long vcpu_data_guest_to_host(struct kvm_vcpu *vcpu,
+ unsigned long data,
+ unsigned int len)
+{
+ if (kvm_vcpu_is_be(vcpu)) {
+ switch (len) {
+ case 1:
+ return data & 0xff;
+ case 2:
+ return be16_to_cpu(data & 0xffff);
+ default:
+ return be32_to_cpu(data);
+ }
+ } else {
+ switch (len) {
+ case 1:
+ return data & 0xff;
+ case 2:
+ return le16_to_cpu(data & 0xffff);
+ default:
+ return le32_to_cpu(data);
+ }
+ }
+}
+
+static inline unsigned long vcpu_data_host_to_guest(struct kvm_vcpu *vcpu,
+ unsigned long data,
+ unsigned int len)
+{
+ if (kvm_vcpu_is_be(vcpu)) {
+ switch (len) {
+ case 1:
+ return data & 0xff;
+ case 2:
+ return cpu_to_be16(data & 0xffff);
+ default:
+ return cpu_to_be32(data);
+ }
+ } else {
+ switch (len) {
+ case 1:
+ return data & 0xff;
+ case 2:
+ return cpu_to_le16(data & 0xffff);
+ default:
+ return cpu_to_le32(data);
+ }
+ }
+}
+
+#endif /* __ARM_KVM_EMULATE_H__ */
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
new file mode 100644
index 000000000..d71607c16
--- /dev/null
+++ b/arch/arm/include/asm/kvm_host.h
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ARM_KVM_HOST_H__
+#define __ARM_KVM_HOST_H__
+
+#include <linux/types.h>
+#include <linux/kvm_types.h>
+#include <asm/kvm.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_mmio.h>
+#include <asm/fpstate.h>
+#include <kvm/arm_arch_timer.h>
+
+#define __KVM_HAVE_ARCH_INTC_INITIALIZED
+
+#if defined(CONFIG_KVM_ARM_MAX_VCPUS)
+#define KVM_MAX_VCPUS CONFIG_KVM_ARM_MAX_VCPUS
+#else
+#define KVM_MAX_VCPUS 0
+#endif
+
+#define KVM_USER_MEM_SLOTS 32
+#define KVM_PRIVATE_MEM_SLOTS 4
+#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
+#define KVM_HAVE_ONE_REG
+
+#define KVM_VCPU_MAX_FEATURES 2
+
+#include <kvm/arm_vgic.h>
+
+u32 *kvm_vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num, u32 mode);
+int __attribute_const__ kvm_target_cpu(void);
+int kvm_reset_vcpu(struct kvm_vcpu *vcpu);
+void kvm_reset_coprocs(struct kvm_vcpu *vcpu);
+
+struct kvm_arch {
+ /* VTTBR value associated with below pgd and vmid */
+ u64 vttbr;
+
+ /* Timer */
+ struct arch_timer_kvm timer;
+
+ /*
+ * Anything that is not used directly from assembly code goes
+ * here.
+ */
+
+ /* The VMID generation used for the virt. memory system */
+ u64 vmid_gen;
+ u32 vmid;
+
+ /* Stage-2 page table */
+ pgd_t *pgd;
+
+ /* Interrupt controller */
+ struct vgic_dist vgic;
+ int max_vcpus;
+};
+
+#define KVM_NR_MEM_OBJS 40
+
+/*
+ * We don't want allocation failures within the mmu code, so we preallocate
+ * enough memory for a single page fault in a cache.
+ */
+struct kvm_mmu_memory_cache {
+ int nobjs;
+ void *objects[KVM_NR_MEM_OBJS];
+};
+
+struct kvm_vcpu_fault_info {
+ u32 hsr; /* Hyp Syndrome Register */
+ u32 hxfar; /* Hyp Data/Inst. Fault Address Register */
+ u32 hpfar; /* Hyp IPA Fault Address Register */
+ u32 hyp_pc; /* PC when exception was taken from Hyp mode */
+};
+
+typedef struct vfp_hard_struct kvm_cpu_context_t;
+
+struct kvm_vcpu_arch {
+ struct kvm_regs regs;
+
+ int target; /* Processor target */
+ DECLARE_BITMAP(features, KVM_VCPU_MAX_FEATURES);
+
+ /* System control coprocessor (cp15) */
+ u32 cp15[NR_CP15_REGS];
+
+ /* The CPU type we expose to the VM */
+ u32 midr;
+
+ /* HYP trapping configuration */
+ u32 hcr;
+
+ /* Interrupt related fields */
+ u32 irq_lines; /* IRQ and FIQ levels */
+
+ /* Exception Information */
+ struct kvm_vcpu_fault_info fault;
+
+ /* Floating point registers (VFP and Advanced SIMD/NEON) */
+ struct vfp_hard_struct vfp_guest;
+
+ /* Host FP context */
+ kvm_cpu_context_t *host_cpu_context;
+
+ /* VGIC state */
+ struct vgic_cpu vgic_cpu;
+ struct arch_timer_cpu timer_cpu;
+
+ /*
+ * Anything that is not used directly from assembly code goes
+ * here.
+ */
+
+ /* Don't run the guest on this vcpu */
+ bool pause;
+
+ /* IO related fields */
+ struct kvm_decode mmio_decode;
+
+ /* Cache some mmu pages needed inside spinlock regions */
+ struct kvm_mmu_memory_cache mmu_page_cache;
+
+ /* Detect first run of a vcpu */
+ bool has_run_once;
+};
+
+struct kvm_vm_stat {
+ u32 remote_tlb_flush;
+};
+
+struct kvm_vcpu_stat {
+ u32 halt_successful_poll;
+ u32 halt_wakeup;
+};
+
+int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init);
+unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu);
+int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
+int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+u64 kvm_call_hyp(void *hypfn, ...);
+void force_vm_exit(const cpumask_t *mask);
+
+#define KVM_ARCH_WANT_MMU_NOTIFIER
+int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
+int kvm_unmap_hva_range(struct kvm *kvm,
+ unsigned long start, unsigned long end);
+void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
+
+unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu);
+int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
+int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end);
+int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
+
+/* We do not have shadow page tables, hence the empty hooks */
+static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm,
+ unsigned long address)
+{
+}
+
+struct kvm_vcpu *kvm_arm_get_running_vcpu(void);
+struct kvm_vcpu __percpu **kvm_get_running_vcpus(void);
+
+int kvm_arm_copy_coproc_indices(struct kvm_vcpu *vcpu, u64 __user *uindices);
+unsigned long kvm_arm_num_coproc_regs(struct kvm_vcpu *vcpu);
+int kvm_arm_coproc_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *);
+int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *);
+
+int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
+ int exception_index);
+
+static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
+ phys_addr_t pgd_ptr,
+ unsigned long hyp_stack_ptr,
+ unsigned long vector_ptr)
+{
+ /*
+ * Call initialization code, and switch to the full blown HYP
+ * code. The init code doesn't need to preserve these
+ * registers as r0-r3 are already callee saved according to
+ * the AAPCS.
+ * Note that we slightly misuse the prototype by casing the
+ * stack pointer to a void *.
+ *
+ * We don't have enough registers to perform the full init in
+ * one go. Install the boot PGD first, and then install the
+ * runtime PGD, stack pointer and vectors. The PGDs are always
+ * passed as the third argument, in order to be passed into
+ * r2-r3 to the init code (yes, this is compliant with the
+ * PCS!).
+ */
+
+ kvm_call_hyp(NULL, 0, boot_pgd_ptr);
+
+ kvm_call_hyp((void*)hyp_stack_ptr, vector_ptr, pgd_ptr);
+}
+
+static inline int kvm_arch_dev_ioctl_check_extension(long ext)
+{
+ return 0;
+}
+
+static inline void vgic_arch_setup(const struct vgic_params *vgic)
+{
+ BUG_ON(vgic->type != VGIC_V2);
+}
+
+int kvm_perf_init(void);
+int kvm_perf_teardown(void);
+
+void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
+
+struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
+
+static inline void kvm_arch_hardware_disable(void) {}
+static inline void kvm_arch_hardware_unsetup(void) {}
+static inline void kvm_arch_sync_events(struct kvm *kvm) {}
+static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
+
+#endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm/include/asm/kvm_mmio.h b/arch/arm/include/asm/kvm_mmio.h
new file mode 100644
index 000000000..d8e90c8cb
--- /dev/null
+++ b/arch/arm/include/asm/kvm_mmio.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ARM_KVM_MMIO_H__
+#define __ARM_KVM_MMIO_H__
+
+#include <linux/kvm_host.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_arm.h>
+
+struct kvm_decode {
+ unsigned long rt;
+ bool sign_extend;
+};
+
+int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
+ phys_addr_t fault_ipa);
+
+#endif /* __ARM_KVM_MMIO_H__ */
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
new file mode 100644
index 000000000..405aa1883
--- /dev/null
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ARM_KVM_MMU_H__
+#define __ARM_KVM_MMU_H__
+
+#include <asm/memory.h>
+#include <asm/page.h>
+
+/*
+ * We directly use the kernel VA for the HYP, as we can directly share
+ * the mapping (HTTBR "covers" TTBR1).
+ */
+#define HYP_PAGE_OFFSET_MASK UL(~0)
+#define HYP_PAGE_OFFSET PAGE_OFFSET
+#define KERN_TO_HYP(kva) (kva)
+
+/*
+ * Our virtual mapping for the boot-time MMU-enable code. Must be
+ * shared across all the page-tables. Conveniently, we use the vectors
+ * page, where no kernel data will ever be shared with HYP.
+ */
+#define TRAMPOLINE_VA UL(CONFIG_VECTORS_BASE)
+
+/*
+ * KVM_MMU_CACHE_MIN_PAGES is the number of stage2 page table translation levels.
+ */
+#define KVM_MMU_CACHE_MIN_PAGES 2
+
+#ifndef __ASSEMBLY__
+
+#include <linux/highmem.h>
+#include <asm/cacheflush.h>
+#include <asm/pgalloc.h>
+
+int create_hyp_mappings(void *from, void *to);
+int create_hyp_io_mappings(void *from, void *to, phys_addr_t);
+void free_boot_hyp_pgd(void);
+void free_hyp_pgds(void);
+
+void stage2_unmap_vm(struct kvm *kvm);
+int kvm_alloc_stage2_pgd(struct kvm *kvm);
+void kvm_free_stage2_pgd(struct kvm *kvm);
+int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
+ phys_addr_t pa, unsigned long size, bool writable);
+
+int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run);
+
+void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu);
+
+phys_addr_t kvm_mmu_get_httbr(void);
+phys_addr_t kvm_mmu_get_boot_httbr(void);
+phys_addr_t kvm_get_idmap_vector(void);
+int kvm_mmu_init(void);
+void kvm_clear_hyp_idmap(void);
+
+static inline void kvm_set_pmd(pmd_t *pmd, pmd_t new_pmd)
+{
+ *pmd = new_pmd;
+ flush_pmd_entry(pmd);
+}
+
+static inline void kvm_set_pte(pte_t *pte, pte_t new_pte)
+{
+ *pte = new_pte;
+ /*
+ * flush_pmd_entry just takes a void pointer and cleans the necessary
+ * cache entries, so we can reuse the function for ptes.
+ */
+ flush_pmd_entry(pte);
+}
+
+static inline void kvm_clean_pgd(pgd_t *pgd)
+{
+ clean_dcache_area(pgd, PTRS_PER_S2_PGD * sizeof(pgd_t));
+}
+
+static inline void kvm_clean_pmd(pmd_t *pmd)
+{
+ clean_dcache_area(pmd, PTRS_PER_PMD * sizeof(pmd_t));
+}
+
+static inline void kvm_clean_pmd_entry(pmd_t *pmd)
+{
+ clean_pmd_entry(pmd);
+}
+
+static inline void kvm_clean_pte(pte_t *pte)
+{
+ clean_pte_table(pte);
+}
+
+static inline void kvm_set_s2pte_writable(pte_t *pte)
+{
+ pte_val(*pte) |= L_PTE_S2_RDWR;
+}
+
+static inline void kvm_set_s2pmd_writable(pmd_t *pmd)
+{
+ pmd_val(*pmd) |= L_PMD_S2_RDWR;
+}
+
+static inline void kvm_set_s2pte_readonly(pte_t *pte)
+{
+ pte_val(*pte) = (pte_val(*pte) & ~L_PTE_S2_RDWR) | L_PTE_S2_RDONLY;
+}
+
+static inline bool kvm_s2pte_readonly(pte_t *pte)
+{
+ return (pte_val(*pte) & L_PTE_S2_RDWR) == L_PTE_S2_RDONLY;
+}
+
+static inline void kvm_set_s2pmd_readonly(pmd_t *pmd)
+{
+ pmd_val(*pmd) = (pmd_val(*pmd) & ~L_PMD_S2_RDWR) | L_PMD_S2_RDONLY;
+}
+
+static inline bool kvm_s2pmd_readonly(pmd_t *pmd)
+{
+ return (pmd_val(*pmd) & L_PMD_S2_RDWR) == L_PMD_S2_RDONLY;
+}
+
+
+/* Open coded p*d_addr_end that can deal with 64bit addresses */
+#define kvm_pgd_addr_end(addr, end) \
+({ u64 __boundary = ((addr) + PGDIR_SIZE) & PGDIR_MASK; \
+ (__boundary - 1 < (end) - 1)? __boundary: (end); \
+})
+
+#define kvm_pud_addr_end(addr,end) (end)
+
+#define kvm_pmd_addr_end(addr, end) \
+({ u64 __boundary = ((addr) + PMD_SIZE) & PMD_MASK; \
+ (__boundary - 1 < (end) - 1)? __boundary: (end); \
+})
+
+#define kvm_pgd_index(addr) pgd_index(addr)
+
+static inline bool kvm_page_empty(void *ptr)
+{
+ struct page *ptr_page = virt_to_page(ptr);
+ return page_count(ptr_page) == 1;
+}
+
+#define kvm_pte_table_empty(kvm, ptep) kvm_page_empty(ptep)
+#define kvm_pmd_table_empty(kvm, pmdp) kvm_page_empty(pmdp)
+#define kvm_pud_table_empty(kvm, pudp) (0)
+
+#define KVM_PREALLOC_LEVEL 0
+
+static inline void *kvm_get_hwpgd(struct kvm *kvm)
+{
+ return kvm->arch.pgd;
+}
+
+static inline unsigned int kvm_get_hwpgd_size(void)
+{
+ return PTRS_PER_S2_PGD * sizeof(pgd_t);
+}
+
+struct kvm;
+
+#define kvm_flush_dcache_to_poc(a,l) __cpuc_flush_dcache_area((a), (l))
+
+static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu)
+{
+ return (vcpu->arch.cp15[c1_SCTLR] & 0b101) == 0b101;
+}
+
+static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu, pfn_t pfn,
+ unsigned long size,
+ bool ipa_uncached)
+{
+ /*
+ * If we are going to insert an instruction page and the icache is
+ * either VIPT or PIPT, there is a potential problem where the host
+ * (or another VM) may have used the same page as this guest, and we
+ * read incorrect data from the icache. If we're using a PIPT cache,
+ * we can invalidate just that page, but if we are using a VIPT cache
+ * we need to invalidate the entire icache - damn shame - as written
+ * in the ARM ARM (DDI 0406C.b - Page B3-1393).
+ *
+ * VIVT caches are tagged using both the ASID and the VMID and doesn't
+ * need any kind of flushing (DDI 0406C.b - Page B3-1392).
+ *
+ * We need to do this through a kernel mapping (using the
+ * user-space mapping has proved to be the wrong
+ * solution). For that, we need to kmap one page at a time,
+ * and iterate over the range.
+ */
+
+ bool need_flush = !vcpu_has_cache_enabled(vcpu) || ipa_uncached;
+
+ VM_BUG_ON(size & ~PAGE_MASK);
+
+ if (!need_flush && !icache_is_pipt())
+ goto vipt_cache;
+
+ while (size) {
+ void *va = kmap_atomic_pfn(pfn);
+
+ if (need_flush)
+ kvm_flush_dcache_to_poc(va, PAGE_SIZE);
+
+ if (icache_is_pipt())
+ __cpuc_coherent_user_range((unsigned long)va,
+ (unsigned long)va + PAGE_SIZE);
+
+ size -= PAGE_SIZE;
+ pfn++;
+
+ kunmap_atomic(va);
+ }
+
+vipt_cache:
+ if (!icache_is_pipt() && !icache_is_vivt_asid_tagged()) {
+ /* any kind of VIPT cache */
+ __flush_icache_all();
+ }
+}
+
+static inline void __kvm_flush_dcache_pte(pte_t pte)
+{
+ void *va = kmap_atomic(pte_page(pte));
+
+ kvm_flush_dcache_to_poc(va, PAGE_SIZE);
+
+ kunmap_atomic(va);
+}
+
+static inline void __kvm_flush_dcache_pmd(pmd_t pmd)
+{
+ unsigned long size = PMD_SIZE;
+ pfn_t pfn = pmd_pfn(pmd);
+
+ while (size) {
+ void *va = kmap_atomic_pfn(pfn);
+
+ kvm_flush_dcache_to_poc(va, PAGE_SIZE);
+
+ pfn++;
+ size -= PAGE_SIZE;
+
+ kunmap_atomic(va);
+ }
+}
+
+static inline void __kvm_flush_dcache_pud(pud_t pud)
+{
+}
+
+#define kvm_virt_to_phys(x) virt_to_idmap((unsigned long)(x))
+
+void kvm_set_way_flush(struct kvm_vcpu *vcpu);
+void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled);
+
+static inline bool __kvm_cpu_uses_extended_idmap(void)
+{
+ return false;
+}
+
+static inline void __kvm_extend_hypmap(pgd_t *boot_hyp_pgd,
+ pgd_t *hyp_pgd,
+ pgd_t *merged_hyp_pgd,
+ unsigned long hyp_idmap_start) { }
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ARM_KVM_MMU_H__ */
diff --git a/arch/arm/include/asm/kvm_psci.h b/arch/arm/include/asm/kvm_psci.h
new file mode 100644
index 000000000..6bda945d3
--- /dev/null
+++ b/arch/arm/include/asm/kvm_psci.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARM_KVM_PSCI_H__
+#define __ARM_KVM_PSCI_H__
+
+#define KVM_ARM_PSCI_0_1 1
+#define KVM_ARM_PSCI_0_2 2
+
+int kvm_psci_version(struct kvm_vcpu *vcpu);
+int kvm_psci_call(struct kvm_vcpu *vcpu);
+
+#endif /* __ARM_KVM_PSCI_H__ */
diff --git a/arch/arm/include/asm/limits.h b/arch/arm/include/asm/limits.h
new file mode 100644
index 000000000..08d8c6600
--- /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 000000000..5a25632b1
--- /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/mach-types.h b/arch/arm/include/asm/mach-types.h
new file mode 100644
index 000000000..948178cc6
--- /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 000000000..0406cb3f1
--- /dev/null
+++ b/arch/arm/include/asm/mach/arch.h
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+#include <linux/types.h>
+
+#ifndef __ASSEMBLY__
+#include <linux/reboot.h>
+
+struct tag;
+struct pt_regs;
+struct smp_operations;
+#ifdef CONFIG_SMP
+#define smp_ops(ops) (&(ops))
+#define smp_init_ops(ops) (&(ops))
+#else
+#define smp_ops(ops) (struct smp_operations *)NULL
+#define smp_init_ops(ops) (bool (*)(void))NULL
+#endif
+
+struct machine_desc {
+ unsigned int nr; /* architecture number */
+ const char *name; /* architecture name */
+ unsigned long atag_offset; /* tagged list (relative) */
+ const char *const *dt_compat; /* array of device tree
+ * 'compatible' strings */
+
+ unsigned int nr_irqs; /* number of IRQs */
+
+#ifdef CONFIG_ZONE_DMA
+ phys_addr_t dma_zone_size; /* size of DMA-able area */
+#endif
+
+ unsigned int video_start; /* start of video RAM */
+ unsigned int video_end; /* end of video RAM */
+
+ unsigned char reserve_lp0 :1; /* never has lp0 */
+ unsigned char reserve_lp1 :1; /* never has lp1 */
+ unsigned char reserve_lp2 :1; /* never has lp2 */
+ enum reboot_mode reboot_mode; /* default restart mode */
+ unsigned l2c_aux_val; /* L2 cache aux value */
+ unsigned l2c_aux_mask; /* L2 cache aux mask */
+ void (*l2c_write_sec)(unsigned long, unsigned);
+ struct smp_operations *smp; /* SMP operations */
+ bool (*smp_init)(void);
+ void (*fixup)(struct tag *, char **);
+ void (*dt_fixup)(void);
+ void (*init_meminfo)(void);
+ void (*reserve)(void);/* reserve mem blocks */
+ void (*map_io)(void);/* IO mapping function */
+ void (*init_early)(void);
+ void (*init_irq)(void);
+ void (*init_time)(void);
+ void (*init_machine)(void);
+ void (*init_late)(void);
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+ void (*handle_irq)(struct pt_regs *);
+#endif
+ void (*restart)(enum reboot_mode, const char *);
+};
+
+/*
+ * Current machine - only accessible during boot.
+ */
+extern const struct machine_desc *machine_desc;
+
+/*
+ * Machine type table - also only accessible during boot
+ */
+extern const 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 \
+};
+
+#define DT_MACHINE_START(_name, _namestr) \
+static const struct machine_desc __mach_desc_##_name \
+ __used \
+ __attribute__((__section__(".arch.info.init"))) = { \
+ .nr = ~0, \
+ .name = _namestr,
+
+#endif
diff --git a/arch/arm/include/asm/mach/dma.h b/arch/arm/include/asm/mach/dma.h
new file mode 100644
index 000000000..9e614a18e
--- /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 000000000..4ca69fe2c
--- /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/irq.h b/arch/arm/include/asm/mach/irq.h
new file mode 100644
index 000000000..2092ee1e1
--- /dev/null
+++ b/arch/arm/include/asm/mach/irq.h
@@ -0,0 +1,33 @@
+/*
+ * 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(int);
+extern int show_fiq_list(struct seq_file *, int);
+
+/*
+ * 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)
+
+#endif
diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h
new file mode 100644
index 000000000..f98c7f32c
--- /dev/null
+++ b/arch/arm/include/asm/mach/map.h
@@ -0,0 +1,65 @@
+/*
+ * 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
+ */
+#ifndef __ASM_MACH_MAP_H
+#define __ASM_MACH_MAP_H
+
+#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 */
+enum {
+ MT_UNCACHED = 4,
+ MT_CACHECLEAN,
+ MT_MINICLEAN,
+ MT_LOW_VECTORS,
+ MT_HIGH_VECTORS,
+ MT_MEMORY_RWX,
+ MT_MEMORY_RW,
+ MT_ROM,
+ MT_MEMORY_RWX_NONCACHED,
+ MT_MEMORY_RW_DTCM,
+ MT_MEMORY_RWX_ITCM,
+ MT_MEMORY_RW_SO,
+ MT_MEMORY_DMA_READY,
+};
+
+#ifdef CONFIG_MMU
+extern void iotable_init(struct map_desc *, int);
+extern void vm_reserve_area_early(unsigned long addr, unsigned long size,
+ void *caller);
+
+#ifdef CONFIG_DEBUG_LL
+extern void debug_ll_addr(unsigned long *paddr, unsigned long *vaddr);
+extern void debug_ll_io_init(void);
+#else
+static inline void debug_ll_io_init(void) {}
+#endif
+
+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)
+#define vm_reserve_area_early(a,s,c) do { } while (0)
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
new file mode 100644
index 000000000..28b9bb359
--- /dev/null
+++ b/arch/arm/include/asm/mach/pci.h
@@ -0,0 +1,105 @@
+/*
+ * 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
+
+#include <linux/ioport.h>
+
+struct pci_sys_data;
+struct pci_ops;
+struct pci_bus;
+struct device;
+
+struct hw_pci {
+#ifdef CONFIG_PCI_MSI
+ struct msi_controller *msi_ctrl;
+#endif
+ struct pci_ops *ops;
+ int nr_controllers;
+ void **private_data;
+ 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)(const struct pci_dev *dev, u8 slot, u8 pin);
+ resource_size_t (*align_resource)(struct pci_dev *dev,
+ const struct resource *res,
+ resource_size_t start,
+ resource_size_t size,
+ resource_size_t align);
+};
+
+/*
+ * Per-controller structure
+ */
+struct pci_sys_data {
+#ifdef CONFIG_PCI_MSI
+ struct msi_controller *msi_ctrl;
+#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 list_head resources; /* root bus resources (apertures) */
+ struct resource io_res;
+ char io_res_name[12];
+ /* Bridge swizzling */
+ u8 (*swizzle)(struct pci_dev *, u8 *);
+ /* IRQ mapping */
+ int (*map_irq)(const struct pci_dev *, u8, u8);
+ /* Resource alignement requirements */
+ resource_size_t (*align_resource)(struct pci_dev *dev,
+ const struct resource *res,
+ resource_size_t start,
+ resource_size_t size,
+ resource_size_t align);
+ void *private_data; /* platform controller private data */
+};
+
+/*
+ * Call this with your hw_pci struct to initialise the PCI system.
+ */
+void pci_common_init_dev(struct device *, struct hw_pci *);
+
+/*
+ * Compatibility wrapper for older platforms that do not care about
+ * passing the parent device.
+ */
+static inline void pci_common_init(struct hw_pci *hw)
+{
+ pci_common_init_dev(NULL, hw);
+}
+
+/*
+ * Setup early fixed I/O mapping.
+ */
+#if defined(CONFIG_PCI)
+extern void pci_map_io_early(unsigned long pfn);
+#else
+static inline void pci_map_io_early(unsigned long pfn) {}
+#endif
+
+/*
+ * PCI controllers
+ */
+extern struct pci_ops iop3xx_ops;
+extern int iop3xx_pci_setup(int nr, struct pci_sys_data *);
+extern void iop3xx_pci_preinit(void);
+extern void iop3xx_pci_preinit_cond(void);
+
+extern struct pci_ops dc21285_ops;
+extern int dc21285_setup(int nr, struct pci_sys_data *);
+extern void dc21285_preinit(void);
+extern void dc21285_postinit(void);
+
+#endif /* __ASM_MACH_PCI_H */
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 000000000..7a24ecf04
--- /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 000000000..0f79e4dec
--- /dev/null
+++ b/arch/arm/include/asm/mach/time.h
@@ -0,0 +1,19 @@
+/*
+ * 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
+
+extern void timer_tick(void);
+
+typedef void (*clock_access_fn)(struct timespec64 *);
+extern int register_persistent_clock(clock_access_fn read_boot,
+ clock_access_fn read_persistent);
+
+#endif
diff --git a/arch/arm/include/asm/mc146818rtc.h b/arch/arm/include/asm/mc146818rtc.h
new file mode 100644
index 000000000..e8567bb99
--- /dev/null
+++ b/arch/arm/include/asm/mc146818rtc.h
@@ -0,0 +1,30 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+
+#define RTC_IRQ BUILD_BUG_ON(1)
+
+#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/mcpm.h b/arch/arm/include/asm/mcpm.h
new file mode 100644
index 000000000..50b378f59
--- /dev/null
+++ b/arch/arm/include/asm/mcpm.h
@@ -0,0 +1,358 @@
+/*
+ * arch/arm/include/asm/mcpm.h
+ *
+ * Created by: Nicolas Pitre, April 2012
+ * Copyright: (C) 2012-2013 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.
+ */
+
+#ifndef MCPM_H
+#define MCPM_H
+
+/*
+ * Maximum number of possible clusters / CPUs per cluster.
+ *
+ * This should be sufficient for quite a while, while keeping the
+ * (assembly) code simpler. When this starts to grow then we'll have
+ * to consider dynamic allocation.
+ */
+#define MAX_CPUS_PER_CLUSTER 4
+
+#ifdef CONFIG_MCPM_QUAD_CLUSTER
+#define MAX_NR_CLUSTERS 4
+#else
+#define MAX_NR_CLUSTERS 2
+#endif
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Platform specific code should use this symbol to set up secondary
+ * entry location for processors to use when released from reset.
+ */
+extern void mcpm_entry_point(void);
+
+/*
+ * This is used to indicate where the given CPU from given cluster should
+ * branch once it is ready to re-enter the kernel using ptr, or NULL if it
+ * should be gated. A gated CPU is held in a WFE loop until its vector
+ * becomes non NULL.
+ */
+void mcpm_set_entry_vector(unsigned cpu, unsigned cluster, void *ptr);
+
+/*
+ * This sets an early poke i.e a value to be poked into some address
+ * from very early assembly code before the CPU is ungated. The
+ * address must be physical, and if 0 then nothing will happen.
+ */
+void mcpm_set_early_poke(unsigned cpu, unsigned cluster,
+ unsigned long poke_phys_addr, unsigned long poke_val);
+
+/*
+ * CPU/cluster power operations API for higher subsystems to use.
+ */
+
+/**
+ * mcpm_is_available - returns whether MCPM is initialized and available
+ *
+ * This returns true or false accordingly.
+ */
+bool mcpm_is_available(void);
+
+/**
+ * mcpm_cpu_power_up - make given CPU in given cluster runable
+ *
+ * @cpu: CPU number within given cluster
+ * @cluster: cluster number for the CPU
+ *
+ * The identified CPU is brought out of reset. If the cluster was powered
+ * down then it is brought up as well, taking care not to let the other CPUs
+ * in the cluster run, and ensuring appropriate cluster setup.
+ *
+ * Caller must ensure the appropriate entry vector is initialized with
+ * mcpm_set_entry_vector() prior to calling this.
+ *
+ * This must be called in a sleepable context. However, the implementation
+ * is strongly encouraged to return early and let the operation happen
+ * asynchronously, especially when significant delays are expected.
+ *
+ * If the operation cannot be performed then an error code is returned.
+ */
+int mcpm_cpu_power_up(unsigned int cpu, unsigned int cluster);
+
+/**
+ * mcpm_cpu_power_down - power the calling CPU down
+ *
+ * The calling CPU is powered down.
+ *
+ * If this CPU is found to be the "last man standing" in the cluster
+ * then the cluster is prepared for power-down too.
+ *
+ * This must be called with interrupts disabled.
+ *
+ * On success this does not return. Re-entry in the kernel is expected
+ * via mcpm_entry_point.
+ *
+ * This will return if mcpm_platform_register() has not been called
+ * previously in which case the caller should take appropriate action.
+ *
+ * On success, the CPU is not guaranteed to be truly halted until
+ * mcpm_wait_for_cpu_powerdown() subsequently returns non-zero for the
+ * specified cpu. Until then, other CPUs should make sure they do not
+ * trash memory the target CPU might be executing/accessing.
+ */
+void mcpm_cpu_power_down(void);
+
+/**
+ * mcpm_wait_for_cpu_powerdown - wait for a specified CPU to halt, and
+ * make sure it is powered off
+ *
+ * @cpu: CPU number within given cluster
+ * @cluster: cluster number for the CPU
+ *
+ * Call this function to ensure that a pending powerdown has taken
+ * effect and the CPU is safely parked before performing non-mcpm
+ * operations that may affect the CPU (such as kexec trashing the
+ * kernel text).
+ *
+ * It is *not* necessary to call this function if you only need to
+ * serialise a pending powerdown with mcpm_cpu_power_up() or a wakeup
+ * event.
+ *
+ * Do not call this function unless the specified CPU has already
+ * called mcpm_cpu_power_down() or has committed to doing so.
+ *
+ * @return:
+ * - zero if the CPU is in a safely parked state
+ * - nonzero otherwise (e.g., timeout)
+ */
+int mcpm_wait_for_cpu_powerdown(unsigned int cpu, unsigned int cluster);
+
+/**
+ * mcpm_cpu_suspend - bring the calling CPU in a suspended state
+ *
+ * @expected_residency: duration in microseconds the CPU is expected
+ * to remain suspended, or 0 if unknown/infinity.
+ *
+ * The calling CPU is suspended. The expected residency argument is used
+ * as a hint by the platform specific backend to implement the appropriate
+ * sleep state level according to the knowledge it has on wake-up latency
+ * for the given hardware.
+ *
+ * If this CPU is found to be the "last man standing" in the cluster
+ * then the cluster may be prepared for power-down too, if the expected
+ * residency makes it worthwhile.
+ *
+ * This must be called with interrupts disabled.
+ *
+ * On success this does not return. Re-entry in the kernel is expected
+ * via mcpm_entry_point.
+ *
+ * This will return if mcpm_platform_register() has not been called
+ * previously in which case the caller should take appropriate action.
+ */
+void mcpm_cpu_suspend(u64 expected_residency);
+
+/**
+ * mcpm_cpu_powered_up - housekeeping workafter a CPU has been powered up
+ *
+ * This lets the platform specific backend code perform needed housekeeping
+ * work. This must be called by the newly activated CPU as soon as it is
+ * fully operational in kernel space, before it enables interrupts.
+ *
+ * If the operation cannot be performed then an error code is returned.
+ */
+int mcpm_cpu_powered_up(void);
+
+/*
+ * Platform specific callbacks used in the implementation of the above API.
+ *
+ * cpu_powerup:
+ * Make given CPU runable. Called with MCPM lock held and IRQs disabled.
+ * The given cluster is assumed to be set up (cluster_powerup would have
+ * been called beforehand). Must return 0 for success or negative error code.
+ *
+ * cluster_powerup:
+ * Set up power for given cluster. Called with MCPM lock held and IRQs
+ * disabled. Called before first cpu_powerup when cluster is down. Must
+ * return 0 for success or negative error code.
+ *
+ * cpu_suspend_prepare:
+ * Special suspend configuration. Called on target CPU with MCPM lock held
+ * and IRQs disabled. This callback is optional. If provided, it is called
+ * before cpu_powerdown_prepare.
+ *
+ * cpu_powerdown_prepare:
+ * Configure given CPU for power down. Called on target CPU with MCPM lock
+ * held and IRQs disabled. Power down must be effective only at the next WFI instruction.
+ *
+ * cluster_powerdown_prepare:
+ * Configure given cluster for power down. Called on one CPU from target
+ * cluster with MCPM lock held and IRQs disabled. A cpu_powerdown_prepare
+ * for each CPU in the cluster has happened when this occurs.
+ *
+ * cpu_cache_disable:
+ * Clean and disable CPU level cache for the calling CPU. Called on with IRQs
+ * disabled only. The CPU is no longer cache coherent with the rest of the
+ * system when this returns.
+ *
+ * cluster_cache_disable:
+ * Clean and disable the cluster wide cache as well as the CPU level cache
+ * for the calling CPU. No call to cpu_cache_disable will happen for this
+ * CPU. Called with IRQs disabled and only when all the other CPUs are done
+ * with their own cpu_cache_disable. The cluster is no longer cache coherent
+ * with the rest of the system when this returns.
+ *
+ * cpu_is_up:
+ * Called on given CPU after it has been powered up or resumed. The MCPM lock
+ * is held and IRQs disabled. This callback is optional.
+ *
+ * cluster_is_up:
+ * Called by the first CPU to be powered up or resumed in given cluster.
+ * The MCPM lock is held and IRQs disabled. This callback is optional. If
+ * provided, it is called before cpu_is_up for that CPU.
+ *
+ * wait_for_powerdown:
+ * Wait until given CPU is powered down. This is called in sleeping context.
+ * Some reasonable timeout must be considered. Must return 0 for success or
+ * negative error code.
+ */
+struct mcpm_platform_ops {
+ int (*cpu_powerup)(unsigned int cpu, unsigned int cluster);
+ int (*cluster_powerup)(unsigned int cluster);
+ void (*cpu_suspend_prepare)(unsigned int cpu, unsigned int cluster);
+ void (*cpu_powerdown_prepare)(unsigned int cpu, unsigned int cluster);
+ void (*cluster_powerdown_prepare)(unsigned int cluster);
+ void (*cpu_cache_disable)(void);
+ void (*cluster_cache_disable)(void);
+ void (*cpu_is_up)(unsigned int cpu, unsigned int cluster);
+ void (*cluster_is_up)(unsigned int cluster);
+ int (*wait_for_powerdown)(unsigned int cpu, unsigned int cluster);
+
+ /* deprecated callbacks */
+ int (*power_up)(unsigned int cpu, unsigned int cluster);
+ void (*power_down)(void);
+ void (*suspend)(u64);
+ void (*powered_up)(void);
+};
+
+/**
+ * mcpm_platform_register - register platform specific power methods
+ *
+ * @ops: mcpm_platform_ops structure to register
+ *
+ * An error is returned if the registration has been done previously.
+ */
+int __init mcpm_platform_register(const struct mcpm_platform_ops *ops);
+
+/* Synchronisation structures for coordinating safe cluster setup/teardown: */
+
+/*
+ * When modifying this structure, make sure you update the MCPM_SYNC_ defines
+ * to match.
+ */
+struct mcpm_sync_struct {
+ /* individual CPU states */
+ struct {
+ s8 cpu __aligned(__CACHE_WRITEBACK_GRANULE);
+ } cpus[MAX_CPUS_PER_CLUSTER];
+
+ /* cluster state */
+ s8 cluster __aligned(__CACHE_WRITEBACK_GRANULE);
+
+ /* inbound-side state */
+ s8 inbound __aligned(__CACHE_WRITEBACK_GRANULE);
+};
+
+struct sync_struct {
+ struct mcpm_sync_struct clusters[MAX_NR_CLUSTERS];
+};
+
+void __mcpm_cpu_going_down(unsigned int cpu, unsigned int cluster);
+void __mcpm_cpu_down(unsigned int cpu, unsigned int cluster);
+void __mcpm_outbound_leave_critical(unsigned int cluster, int state);
+bool __mcpm_outbound_enter_critical(unsigned int this_cpu, unsigned int cluster);
+int __mcpm_cluster_state(unsigned int cluster);
+
+/**
+ * mcpm_sync_init - Initialize the cluster synchronization support
+ *
+ * @power_up_setup: platform specific function invoked during very
+ * early CPU/cluster bringup stage.
+ *
+ * This prepares memory used by vlocks and the MCPM state machine used
+ * across CPUs that may have their caches active or inactive. Must be
+ * called only after a successful call to mcpm_platform_register().
+ *
+ * The power_up_setup argument is a pointer to assembly code called when
+ * the MMU and caches are still disabled during boot and no stack space is
+ * available. The affinity level passed to that code corresponds to the
+ * resource that needs to be initialized (e.g. 1 for cluster level, 0 for
+ * CPU level). Proper exclusion mechanisms are already activated at that
+ * point.
+ */
+int __init mcpm_sync_init(
+ void (*power_up_setup)(unsigned int affinity_level));
+
+/**
+ * mcpm_loopback - make a run through the MCPM low-level code
+ *
+ * @cache_disable: pointer to function performing cache disabling
+ *
+ * This exercises the MCPM machinery by soft resetting the CPU and branching
+ * to the MCPM low-level entry code before returning to the caller.
+ * The @cache_disable function must do the necessary cache disabling to
+ * let the regular kernel init code turn it back on as if the CPU was
+ * hotplugged in. The MCPM state machine is set as if the cluster was
+ * initialized meaning the power_up_setup callback passed to mcpm_sync_init()
+ * will be invoked for all affinity levels. This may be useful to initialize
+ * some resources such as enabling the CCI that requires the cache to be off, or simply for testing purposes.
+ */
+int __init mcpm_loopback(void (*cache_disable)(void));
+
+void __init mcpm_smp_set_ops(void);
+
+#else
+
+/*
+ * asm-offsets.h causes trouble when included in .c files, and cacheflush.h
+ * cannot be included in asm files. Let's work around the conflict like this.
+ */
+#include <asm/asm-offsets.h>
+#define __CACHE_WRITEBACK_GRANULE CACHE_WRITEBACK_GRANULE
+
+#endif /* ! __ASSEMBLY__ */
+
+/* Definitions for mcpm_sync_struct */
+#define CPU_DOWN 0x11
+#define CPU_COMING_UP 0x12
+#define CPU_UP 0x13
+#define CPU_GOING_DOWN 0x14
+
+#define CLUSTER_DOWN 0x21
+#define CLUSTER_UP 0x22
+#define CLUSTER_GOING_DOWN 0x23
+
+#define INBOUND_NOT_COMING_UP 0x31
+#define INBOUND_COMING_UP 0x32
+
+/*
+ * Offsets for the mcpm_sync_struct members, for use in asm.
+ * We don't want to make them global to the kernel via asm-offsets.c.
+ */
+#define MCPM_SYNC_CLUSTER_CPUS 0
+#define MCPM_SYNC_CPU_SIZE __CACHE_WRITEBACK_GRANULE
+#define MCPM_SYNC_CLUSTER_CLUSTER \
+ (MCPM_SYNC_CLUSTER_CPUS + MCPM_SYNC_CPU_SIZE * MAX_CPUS_PER_CLUSTER)
+#define MCPM_SYNC_CLUSTER_INBOUND \
+ (MCPM_SYNC_CLUSTER_CLUSTER + __CACHE_WRITEBACK_GRANULE)
+#define MCPM_SYNC_CLUSTER_SIZE \
+ (MCPM_SYNC_CLUSTER_INBOUND + __CACHE_WRITEBACK_GRANULE)
+
+#endif
diff --git a/arch/arm/include/asm/mcs_spinlock.h b/arch/arm/include/asm/mcs_spinlock.h
new file mode 100644
index 000000000..f652ad658
--- /dev/null
+++ b/arch/arm/include/asm/mcs_spinlock.h
@@ -0,0 +1,23 @@
+#ifndef __ASM_MCS_LOCK_H
+#define __ASM_MCS_LOCK_H
+
+#ifdef CONFIG_SMP
+#include <asm/spinlock.h>
+
+/* MCS spin-locking. */
+#define arch_mcs_spin_lock_contended(lock) \
+do { \
+ /* Ensure prior stores are observed before we enter wfe. */ \
+ smp_mb(); \
+ while (!(smp_load_acquire(lock))) \
+ wfe(); \
+} while (0) \
+
+#define arch_mcs_spin_unlock_contended(lock) \
+do { \
+ smp_store_release(lock, 1); \
+ dsb_sev(); \
+} while (0)
+
+#endif /* CONFIG_SMP */
+#endif /* __ASM_MCS_LOCK_H */
diff --git a/arch/arm/include/asm/memblock.h b/arch/arm/include/asm/memblock.h
new file mode 100644
index 000000000..bf47a6c11
--- /dev/null
+++ b/arch/arm/include/asm/memblock.h
@@ -0,0 +1,9 @@
+#ifndef _ASM_ARM_MEMBLOCK_H
+#define _ASM_ARM_MEMBLOCK_H
+
+struct machine_desc;
+
+void arm_memblock_init(const struct machine_desc *);
+phys_addr_t arm_memblock_steal(phys_addr_t size, phys_addr_t align);
+
+#endif
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
new file mode 100644
index 000000000..184def0e1
--- /dev/null
+++ b/arch/arm/include/asm/memory.h
@@ -0,0 +1,359 @@
+/*
+ * 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 <linux/sizes.h>
+
+#include <asm/cache.h>
+
+#ifdef CONFIG_NEED_MACH_MEMORY_H
+#include <mach/memory.h>
+#endif
+
+/*
+ * 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)
+
+/* PAGE_OFFSET - the virtual address of the start of the kernel image */
+#define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET)
+
+#ifdef CONFIG_MMU
+
+/*
+ * TASK_SIZE - the maximum size of a user space task.
+ * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area
+ */
+#define TASK_SIZE (UL(CONFIG_PAGE_OFFSET) - UL(SZ_16M))
+#define TASK_UNMAPPED_BASE ALIGN(TASK_SIZE / 3, SZ_16M)
+
+/*
+ * The maximum size of a 26-bit user space task.
+ */
+#define TASK_SIZE_26 (UL(1) << 26)
+
+/*
+ * 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 - SZ_16M)
+#else
+/* smaller range for Thumb-2 symbols relocation (2^24)*/
+#define MODULES_VADDR (PAGE_OFFSET - SZ_8M)
+#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
+
+#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.
+ */
+#define TASK_SIZE UL(0xffffffff)
+
+#ifndef TASK_UNMAPPED_BASE
+#define TASK_UNMAPPED_BASE UL(0x00000000)
+#endif
+
+#ifndef END_MEM
+#define END_MEM (UL(CONFIG_DRAM_BASE) + CONFIG_DRAM_SIZE)
+#endif
+
+/*
+ * The module can be at any place in ram in nommu mode.
+ */
+#define MODULES_END (END_MEM)
+#define MODULES_VADDR PAGE_OFFSET
+
+#define XIP_VIRT_ADDR(physaddr) (physaddr)
+
+#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)))
+
+/*
+ * Minimum guaranted alignment in pgd_alloc(). The page table pointers passed
+ * around in head.S and proc-*.S are shifted by this amount, in order to
+ * leave spare high bits for systems with physical address extension. This
+ * does not fully accomodate the 40-bit addressing capability of ARM LPAE, but
+ * gives us about 38-bits or so.
+ */
+#ifdef CONFIG_ARM_LPAE
+#define ARCH_PGD_SHIFT L1_CACHE_SHIFT
+#else
+#define ARCH_PGD_SHIFT 0
+#endif
+#define ARCH_PGD_MASK ((1 << ARCH_PGD_SHIFT) - 1)
+
+/*
+ * PLAT_PHYS_OFFSET is the offset (from zero) of the start of physical
+ * memory. This is used for XIP and NoMMU kernels, and on platforms that don't
+ * have CONFIG_ARM_PATCH_PHYS_VIRT. Assembly code must always use
+ * PLAT_PHYS_OFFSET and not PHYS_OFFSET.
+ */
+#define PLAT_PHYS_OFFSET UL(CONFIG_PHYS_OFFSET)
+
+#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.
+ *
+ * PFNs are used to describe any physical page; this means
+ * PFN 0 == physical address 0.
+ */
+#if defined(__virt_to_phys)
+#define PHYS_OFFSET PLAT_PHYS_OFFSET
+#define PHYS_PFN_OFFSET ((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT))
+
+#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT)
+
+#elif defined(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_7_0 0x81
+
+extern unsigned long __pv_phys_pfn_offset;
+extern u64 __pv_offset;
+extern void fixup_pv_table(const void *, unsigned long);
+extern const void *__pv_table_begin, *__pv_table_end;
+
+#define PHYS_OFFSET ((phys_addr_t)__pv_phys_pfn_offset << PAGE_SHIFT)
+#define PHYS_PFN_OFFSET (__pv_phys_pfn_offset)
+
+#define virt_to_pfn(kaddr) \
+ ((((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT) + \
+ PHYS_PFN_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))
+
+#define __pv_stub_mov_hi(t) \
+ __asm__ volatile("@ __pv_stub_mov\n" \
+ "1: mov %R0, %1\n" \
+ " .pushsection .pv_table,\"a\"\n" \
+ " .long 1b\n" \
+ " .popsection\n" \
+ : "=r" (t) \
+ : "I" (__PV_BITS_7_0))
+
+#define __pv_add_carry_stub(x, y) \
+ __asm__ volatile("@ __pv_add_carry_stub\n" \
+ "1: adds %Q0, %1, %2\n" \
+ " adc %R0, %R0, #0\n" \
+ " .pushsection .pv_table,\"a\"\n" \
+ " .long 1b\n" \
+ " .popsection\n" \
+ : "+r" (y) \
+ : "r" (x), "I" (__PV_BITS_31_24) \
+ : "cc")
+
+static inline phys_addr_t __virt_to_phys(unsigned long x)
+{
+ phys_addr_t t;
+
+ if (sizeof(phys_addr_t) == 4) {
+ __pv_stub(x, t, "add", __PV_BITS_31_24);
+ } else {
+ __pv_stub_mov_hi(t);
+ __pv_add_carry_stub(x, t);
+ }
+ return t;
+}
+
+static inline unsigned long __phys_to_virt(phys_addr_t x)
+{
+ unsigned long t;
+
+ /*
+ * 'unsigned long' cast discard upper word when
+ * phys_addr_t is 64 bit, and makes sure that inline
+ * assembler expression receives 32 bit argument
+ * in place where 'r' 32 bit operand is expected.
+ */
+ __pv_stub((unsigned long) x, t, "sub", __PV_BITS_31_24);
+ return t;
+}
+
+#else
+
+#define PHYS_OFFSET PLAT_PHYS_OFFSET
+#define PHYS_PFN_OFFSET ((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT))
+
+static inline phys_addr_t __virt_to_phys(unsigned long x)
+{
+ return (phys_addr_t)x - PAGE_OFFSET + PHYS_OFFSET;
+}
+
+static inline unsigned long __phys_to_virt(phys_addr_t x)
+{
+ return x - PHYS_OFFSET + PAGE_OFFSET;
+}
+
+#define virt_to_pfn(kaddr) \
+ ((((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT) + \
+ PHYS_PFN_OFFSET)
+
+#endif
+
+/*
+ * 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.
+ */
+#define virt_to_phys virt_to_phys
+static inline phys_addr_t virt_to_phys(const volatile void *x)
+{
+ return __virt_to_phys((unsigned long)(x));
+}
+
+#define phys_to_virt phys_to_virt
+static inline void *phys_to_virt(phys_addr_t x)
+{
+ return (void *)__phys_to_virt(x);
+}
+
+/*
+ * Drivers should NOT use these either.
+ */
+#define __pa(x) __virt_to_phys((unsigned long)(x))
+#define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x)))
+#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
+
+extern phys_addr_t (*arch_virt_to_idmap)(unsigned long x);
+
+/*
+ * These are for systems that have a hardware interconnect supported alias of
+ * physical memory for idmap purposes. Most cases should leave these
+ * untouched.
+ */
+static inline phys_addr_t __virt_to_idmap(unsigned long x)
+{
+ if (arch_virt_to_idmap)
+ return arch_virt_to_idmap(x);
+ else
+ return __virt_to_phys(x);
+}
+
+#define virt_to_idmap(x) __virt_to_idmap((unsigned long)(x))
+
+/*
+ * 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
+
+#ifdef CONFIG_VIRT_TO_BUS
+#define virt_to_bus virt_to_bus
+static inline __deprecated unsigned long virt_to_bus(void *x)
+{
+ return __virt_to_bus((unsigned long)x);
+}
+
+#define bus_to_virt bus_to_virt
+static inline __deprecated void *bus_to_virt(unsigned long x)
+{
+ return (void *)__bus_to_virt(x);
+}
+#endif
+
+/*
+ * Conversion between a struct page and a physical 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(virt_to_pfn(kaddr))
+#define virt_addr_valid(kaddr) (((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) \
+ && pfn_valid(virt_to_pfn(kaddr)))
+
+#endif
+
+#include <asm-generic/memory_model.h>
+
+#endif
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
new file mode 100644
index 000000000..a5b474210
--- /dev/null
+++ b/arch/arm/include/asm/mmu.h
@@ -0,0 +1,40 @@
+#ifndef __ARM_MMU_H
+#define __ARM_MMU_H
+
+#ifdef CONFIG_MMU
+
+typedef struct {
+#ifdef CONFIG_CPU_HAS_ASID
+ atomic64_t id;
+#else
+ int switch_pending;
+#endif
+ unsigned int vmalloc_seq;
+ unsigned long sigpage;
+#ifdef CONFIG_VDSO
+ unsigned long vdso;
+#endif
+} mm_context_t;
+
+#ifdef CONFIG_CPU_HAS_ASID
+#define ASID_BITS 8
+#define ASID_MASK ((~0ULL) << ASID_BITS)
+#define ASID(mm) ((unsigned int)((mm)->context.id.counter & ~ASID_MASK))
+#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 000000000..9b32f76bb
--- /dev/null
+++ b/arch/arm/include/asm/mmu_context.h
@@ -0,0 +1,142 @@
+/*
+ * 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>
+#include <asm/smp_plat.h>
+#include <asm-generic/mm_hooks.h>
+
+void __check_vmalloc_seq(struct mm_struct *mm);
+
+#ifdef CONFIG_CPU_HAS_ASID
+
+void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk);
+#define init_new_context(tsk,mm) ({ atomic64_set(&mm->context.id, 0); 0; })
+
+#ifdef CONFIG_ARM_ERRATA_798181
+void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm,
+ cpumask_t *mask);
+#else /* !CONFIG_ARM_ERRATA_798181 */
+static inline void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm,
+ cpumask_t *mask)
+{
+}
+#endif /* CONFIG_ARM_ERRATA_798181 */
+
+#else /* !CONFIG_CPU_HAS_ASID */
+
+#ifdef CONFIG_MMU
+
+static inline void check_and_switch_context(struct mm_struct *mm,
+ struct task_struct *tsk)
+{
+ if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq))
+ __check_vmalloc_seq(mm);
+
+ if (irqs_disabled())
+ /*
+ * cpu_switch_mm() needs to flush the VIVT caches. To avoid
+ * high interrupt latencies, defer the call and continue
+ * running with the old mm. Since we only support UP systems
+ * on non-ASID CPUs, the old mm will remain valid until the
+ * finish_arch_post_lock_switch() call.
+ */
+ mm->context.switch_pending = 1;
+ else
+ cpu_switch_mm(mm->pgd, mm);
+}
+
+#define finish_arch_post_lock_switch \
+ finish_arch_post_lock_switch
+static inline void finish_arch_post_lock_switch(void)
+{
+ struct mm_struct *mm = current->mm;
+
+ if (mm && mm->context.switch_pending) {
+ /*
+ * Preemption must be disabled during cpu_switch_mm() as we
+ * have some stateful cache flush implementations. Check
+ * switch_pending again in case we were preempted and the
+ * switch to this mm was already done.
+ */
+ preempt_disable();
+ if (mm->context.switch_pending) {
+ mm->context.switch_pending = 0;
+ cpu_switch_mm(mm->pgd, mm);
+ }
+ preempt_enable_no_resched();
+ }
+}
+
+#endif /* CONFIG_MMU */
+
+#define init_new_context(tsk,mm) 0
+
+#endif /* CONFIG_CPU_HAS_ASID */
+
+#define destroy_context(mm) do { } while(0)
+#define activate_mm(prev,next) switch_mm(prev, next, NULL)
+
+/*
+ * 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();
+
+ /*
+ * __sync_icache_dcache doesn't broadcast the I-cache invalidation,
+ * so check for possible thread migration and invalidate the I-cache
+ * if we're new to this CPU.
+ */
+ if (cache_ops_need_broadcast() &&
+ !cpumask_empty(mm_cpumask(next)) &&
+ !cpumask_test_cpu(cpu, mm_cpumask(next)))
+ __flush_icache_all();
+
+ if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) {
+ check_and_switch_context(next, tsk);
+ if (cache_is_vivt())
+ cpumask_clear_cpu(cpu, mm_cpumask(prev));
+ }
+#endif
+}
+
+#define deactivate_mm(tsk,mm) do { } while (0)
+
+#endif
diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h
new file mode 100644
index 000000000..ed690c49e
--- /dev/null
+++ b/arch/arm/include/asm/module.h
@@ -0,0 +1,49 @@
+#ifndef _ASM_ARM_MODULE_H
+#define _ASM_ARM_MODULE_H
+
+#include <asm-generic/module.h>
+
+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_HOT,
+ ARM_SEC_UNLIKELY,
+ ARM_SEC_MAX,
+};
+
+struct mod_arch_specific {
+ 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
+#define MODULE_ARCH_VERMAGIC_P2V "p2v8 "
+#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/mpu.h b/arch/arm/include/asm/mpu.h
new file mode 100644
index 000000000..c3247cc2f
--- /dev/null
+++ b/arch/arm/include/asm/mpu.h
@@ -0,0 +1,76 @@
+#ifndef __ARM_MPU_H
+#define __ARM_MPU_H
+
+#ifdef CONFIG_ARM_MPU
+
+/* MPUIR layout */
+#define MPUIR_nU 1
+#define MPUIR_DREGION 8
+#define MPUIR_IREGION 16
+#define MPUIR_DREGION_SZMASK (0xFF << MPUIR_DREGION)
+#define MPUIR_IREGION_SZMASK (0xFF << MPUIR_IREGION)
+
+/* ID_MMFR0 data relevant to MPU */
+#define MMFR0_PMSA (0xF << 4)
+#define MMFR0_PMSAv7 (3 << 4)
+
+/* MPU D/I Size Register fields */
+#define MPU_RSR_SZ 1
+#define MPU_RSR_EN 0
+
+/* The D/I RSR value for an enabled region spanning the whole of memory */
+#define MPU_RSR_ALL_MEM 63
+
+/* Individual bits in the DR/IR ACR */
+#define MPU_ACR_XN (1 << 12)
+#define MPU_ACR_SHARED (1 << 2)
+
+/* C, B and TEX[2:0] bits only have semantic meanings when grouped */
+#define MPU_RGN_CACHEABLE 0xB
+#define MPU_RGN_SHARED_CACHEABLE (MPU_RGN_CACHEABLE | MPU_ACR_SHARED)
+#define MPU_RGN_STRONGLY_ORDERED 0
+
+/* Main region should only be shared for SMP */
+#ifdef CONFIG_SMP
+#define MPU_RGN_NORMAL (MPU_RGN_CACHEABLE | MPU_ACR_SHARED)
+#else
+#define MPU_RGN_NORMAL MPU_RGN_CACHEABLE
+#endif
+
+/* Access permission bits of ACR (only define those that we use)*/
+#define MPU_AP_PL1RW_PL0RW (0x3 << 8)
+#define MPU_AP_PL1RW_PL0R0 (0x2 << 8)
+#define MPU_AP_PL1RW_PL0NA (0x1 << 8)
+
+/* For minimal static MPU region configurations */
+#define MPU_PROBE_REGION 0
+#define MPU_BG_REGION 1
+#define MPU_RAM_REGION 2
+#define MPU_VECTORS_REGION 3
+
+/* Maximum number of regions Linux is interested in */
+#define MPU_MAX_REGIONS 16
+
+#define MPU_DATA_SIDE 0
+#define MPU_INSTR_SIDE 1
+
+#ifndef __ASSEMBLY__
+
+struct mpu_rgn {
+ /* Assume same attributes for d/i-side */
+ u32 drbar;
+ u32 drsr;
+ u32 dracr;
+};
+
+struct mpu_rgn_info {
+ u32 mpuir;
+ struct mpu_rgn rgns[MPU_MAX_REGIONS];
+};
+extern struct mpu_rgn_info mpu_rgn_info;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* CONFIG_ARM_MPU */
+
+#endif
diff --git a/arch/arm/include/asm/mtd-xip.h b/arch/arm/include/asm/mtd-xip.h
new file mode 100644
index 000000000..d79d66d2c
--- /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 000000000..87c044910
--- /dev/null
+++ b/arch/arm/include/asm/mutex.h
@@ -0,0 +1,21 @@
+/*
+ * 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
+/*
+ * On pre-ARMv6 hardware this results in a swp-based implementation,
+ * which is the most efficient. For ARMv6+, we have exclusive memory
+ * accessors and use atomic_dec to avoid the extra xchg operations
+ * on the locking slowpaths.
+ */
+#if __LINUX_ARM_ARCH__ < 6
+#include <asm-generic/mutex-xchg.h>
+#else
+#include <asm-generic/mutex-dec.h>
+#endif
+#endif /* _ASM_MUTEX_H */
diff --git a/arch/arm/include/asm/neon.h b/arch/arm/include/asm/neon.h
new file mode 100644
index 000000000..8f730fe70
--- /dev/null
+++ b/arch/arm/include/asm/neon.h
@@ -0,0 +1,36 @@
+/*
+ * linux/arch/arm/include/asm/neon.h
+ *
+ * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@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 <asm/hwcap.h>
+
+#define cpu_has_neon() (!!(elf_hwcap & HWCAP_NEON))
+
+#ifdef __ARM_NEON__
+
+/*
+ * If you are affected by the BUILD_BUG below, it probably means that you are
+ * using NEON code /and/ calling the kernel_neon_begin() function from the same
+ * compilation unit. To prevent issues that may arise from GCC reordering or
+ * generating(1) NEON instructions outside of these begin/end functions, the
+ * only supported way of using NEON code in the kernel is by isolating it in a
+ * separate compilation unit, and calling it from another unit from inside a
+ * kernel_neon_begin/kernel_neon_end pair.
+ *
+ * (1) Current GCC (4.7) might generate NEON instructions at O3 level if
+ * -mpfu=neon is set.
+ */
+
+#define kernel_neon_begin() \
+ BUILD_BUG_ON_MSG(1, "kernel_neon_begin() called from NEON code")
+
+#else
+void kernel_neon_begin(void);
+#endif
+void kernel_neon_end(void);
diff --git a/arch/arm/include/asm/nwflash.h b/arch/arm/include/asm/nwflash.h
new file mode 100644
index 000000000..04e5a557a
--- /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/opcodes-sec.h b/arch/arm/include/asm/opcodes-sec.h
new file mode 100644
index 000000000..bc3a91744
--- /dev/null
+++ b/arch/arm/include/asm/opcodes-sec.h
@@ -0,0 +1,24 @@
+/*
+ * This program is free software; you can 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.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#ifndef __ASM_ARM_OPCODES_SEC_H
+#define __ASM_ARM_OPCODES_SEC_H
+
+#include <asm/opcodes.h>
+
+#define __SMC(imm4) __inst_arm_thumb32( \
+ 0xE1600070 | (((imm4) & 0xF) << 0), \
+ 0xF7F08000 | (((imm4) & 0xF) << 16) \
+)
+
+#endif /* __ASM_ARM_OPCODES_SEC_H */
diff --git a/arch/arm/include/asm/opcodes-virt.h b/arch/arm/include/asm/opcodes-virt.h
new file mode 100644
index 000000000..efcfdf92d
--- /dev/null
+++ b/arch/arm/include/asm/opcodes-virt.h
@@ -0,0 +1,39 @@
+/*
+ * opcodes-virt.h: Opcode definitions for the ARM virtualization extensions
+ * Copyright (C) 2012 Linaro 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef __ASM_ARM_OPCODES_VIRT_H
+#define __ASM_ARM_OPCODES_VIRT_H
+
+#include <asm/opcodes.h>
+
+#define __HVC(imm16) __inst_arm_thumb32( \
+ 0xE1400070 | (((imm16) & 0xFFF0) << 4) | ((imm16) & 0x000F), \
+ 0xF7E08000 | (((imm16) & 0xF000) << 4) | ((imm16) & 0x0FFF) \
+)
+
+#define __ERET __inst_arm_thumb32( \
+ 0xE160006E, \
+ 0xF3DE8F00 \
+)
+
+#define __MSR_ELR_HYP(regnum) __inst_arm_thumb32( \
+ 0xE12EF300 | regnum, \
+ 0xF3808E30 | (regnum << 16) \
+)
+
+#endif /* ! __ASM_ARM_OPCODES_VIRT_H */
diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h
new file mode 100644
index 000000000..e796c5985
--- /dev/null
+++ b/arch/arm/include/asm/opcodes.h
@@ -0,0 +1,231 @@
+/*
+ * arch/arm/include/asm/opcodes.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_OPCODES_H
+#define __ASM_ARM_OPCODES_H
+
+#ifndef __ASSEMBLY__
+#include <linux/linkage.h>
+extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr);
+#endif
+
+#define ARM_OPCODE_CONDTEST_FAIL 0
+#define ARM_OPCODE_CONDTEST_PASS 1
+#define ARM_OPCODE_CONDTEST_UNCOND 2
+
+
+/*
+ * Assembler opcode byteswap helpers.
+ * These are only intended for use by this header: don't use them directly,
+ * because they will be suboptimal in most cases.
+ */
+#define ___asm_opcode_swab32(x) ( \
+ (((x) << 24) & 0xFF000000) \
+ | (((x) << 8) & 0x00FF0000) \
+ | (((x) >> 8) & 0x0000FF00) \
+ | (((x) >> 24) & 0x000000FF) \
+)
+#define ___asm_opcode_swab16(x) ( \
+ (((x) << 8) & 0xFF00) \
+ | (((x) >> 8) & 0x00FF) \
+)
+#define ___asm_opcode_swahb32(x) ( \
+ (((x) << 8) & 0xFF00FF00) \
+ | (((x) >> 8) & 0x00FF00FF) \
+)
+#define ___asm_opcode_swahw32(x) ( \
+ (((x) << 16) & 0xFFFF0000) \
+ | (((x) >> 16) & 0x0000FFFF) \
+)
+#define ___asm_opcode_identity32(x) ((x) & 0xFFFFFFFF)
+#define ___asm_opcode_identity16(x) ((x) & 0xFFFF)
+
+
+/*
+ * Opcode byteswap helpers
+ *
+ * These macros help with converting instructions between a canonical integer
+ * format and in-memory representation, in an endianness-agnostic manner.
+ *
+ * __mem_to_opcode_*() convert from in-memory representation to canonical form.
+ * __opcode_to_mem_*() convert from canonical form to in-memory representation.
+ *
+ *
+ * Canonical instruction representation:
+ *
+ * ARM: 0xKKLLMMNN
+ * Thumb 16-bit: 0x0000KKLL, where KK < 0xE8
+ * Thumb 32-bit: 0xKKLLMMNN, where KK >= 0xE8
+ *
+ * There is no way to distinguish an ARM instruction in canonical representation
+ * from a Thumb instruction (just as these cannot be distinguished in memory).
+ * Where this distinction is important, it needs to be tracked separately.
+ *
+ * Note that values in the range 0x0000E800..0xE7FFFFFF intentionally do not
+ * represent any valid Thumb-2 instruction. For this range,
+ * __opcode_is_thumb32() and __opcode_is_thumb16() will both be false.
+ *
+ * The ___asm variants are intended only for use by this header, in situations
+ * involving inline assembler. For .S files, the normal __opcode_*() macros
+ * should do the right thing.
+ */
+#ifdef __ASSEMBLY__
+
+#define ___opcode_swab32(x) ___asm_opcode_swab32(x)
+#define ___opcode_swab16(x) ___asm_opcode_swab16(x)
+#define ___opcode_swahb32(x) ___asm_opcode_swahb32(x)
+#define ___opcode_swahw32(x) ___asm_opcode_swahw32(x)
+#define ___opcode_identity32(x) ___asm_opcode_identity32(x)
+#define ___opcode_identity16(x) ___asm_opcode_identity16(x)
+
+#else /* ! __ASSEMBLY__ */
+
+#include <linux/types.h>
+#include <linux/swab.h>
+
+#define ___opcode_swab32(x) swab32(x)
+#define ___opcode_swab16(x) swab16(x)
+#define ___opcode_swahb32(x) swahb32(x)
+#define ___opcode_swahw32(x) swahw32(x)
+#define ___opcode_identity32(x) ((u32)(x))
+#define ___opcode_identity16(x) ((u16)(x))
+
+#endif /* ! __ASSEMBLY__ */
+
+
+#ifdef CONFIG_CPU_ENDIAN_BE8
+
+#define __opcode_to_mem_arm(x) ___opcode_swab32(x)
+#define __opcode_to_mem_thumb16(x) ___opcode_swab16(x)
+#define __opcode_to_mem_thumb32(x) ___opcode_swahb32(x)
+#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_swab32(x)
+#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_swab16(x)
+#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahb32(x)
+
+#else /* ! CONFIG_CPU_ENDIAN_BE8 */
+
+#define __opcode_to_mem_arm(x) ___opcode_identity32(x)
+#define __opcode_to_mem_thumb16(x) ___opcode_identity16(x)
+#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_identity32(x)
+#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_identity16(x)
+#ifndef CONFIG_CPU_ENDIAN_BE32
+/*
+ * On BE32 systems, using 32-bit accesses to store Thumb instructions will not
+ * work in all cases, due to alignment constraints. For now, a correct
+ * version is not provided for BE32.
+ */
+#define __opcode_to_mem_thumb32(x) ___opcode_swahw32(x)
+#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahw32(x)
+#endif
+
+#endif /* ! CONFIG_CPU_ENDIAN_BE8 */
+
+#define __mem_to_opcode_arm(x) __opcode_to_mem_arm(x)
+#define __mem_to_opcode_thumb16(x) __opcode_to_mem_thumb16(x)
+#ifndef CONFIG_CPU_ENDIAN_BE32
+#define __mem_to_opcode_thumb32(x) __opcode_to_mem_thumb32(x)
+#endif
+
+/* Operations specific to Thumb opcodes */
+
+/* Instruction size checks: */
+#define __opcode_is_thumb32(x) ( \
+ ((x) & 0xF8000000) == 0xE8000000 \
+ || ((x) & 0xF0000000) == 0xF0000000 \
+)
+#define __opcode_is_thumb16(x) ( \
+ ((x) & 0xFFFF0000) == 0 \
+ && !(((x) & 0xF800) == 0xE800 || ((x) & 0xF000) == 0xF000) \
+)
+
+/* Operations to construct or split 32-bit Thumb instructions: */
+#define __opcode_thumb32_first(x) (___opcode_identity16((x) >> 16))
+#define __opcode_thumb32_second(x) (___opcode_identity16(x))
+#define __opcode_thumb32_compose(first, second) ( \
+ (___opcode_identity32(___opcode_identity16(first)) << 16) \
+ | ___opcode_identity32(___opcode_identity16(second)) \
+)
+#define ___asm_opcode_thumb32_first(x) (___asm_opcode_identity16((x) >> 16))
+#define ___asm_opcode_thumb32_second(x) (___asm_opcode_identity16(x))
+#define ___asm_opcode_thumb32_compose(first, second) ( \
+ (___asm_opcode_identity32(___asm_opcode_identity16(first)) << 16) \
+ | ___asm_opcode_identity32(___asm_opcode_identity16(second)) \
+)
+
+/*
+ * Opcode injection helpers
+ *
+ * In rare cases it is necessary to assemble an opcode which the
+ * assembler does not support directly, or which would normally be
+ * rejected because of the CFLAGS or AFLAGS used to build the affected
+ * file.
+ *
+ * Before using these macros, consider carefully whether it is feasible
+ * instead to change the build flags for your file, or whether it really
+ * makes sense to support old assembler versions when building that
+ * particular kernel feature.
+ *
+ * The macros defined here should only be used where there is no viable
+ * alternative.
+ *
+ *
+ * __inst_arm(x): emit the specified ARM opcode
+ * __inst_thumb16(x): emit the specified 16-bit Thumb opcode
+ * __inst_thumb32(x): emit the specified 32-bit Thumb opcode
+ *
+ * __inst_arm_thumb16(arm, thumb): emit either the specified arm or
+ * 16-bit Thumb opcode, depending on whether an ARM or Thumb-2
+ * kernel is being built
+ *
+ * __inst_arm_thumb32(arm, thumb): emit either the specified arm or
+ * 32-bit Thumb opcode, depending on whether an ARM or Thumb-2
+ * kernel is being built
+ *
+ *
+ * Note that using these macros directly is poor practice. Instead, you
+ * should use them to define human-readable wrapper macros to encode the
+ * instructions that you care about. In code which might run on ARMv7 or
+ * above, you can usually use the __inst_arm_thumb{16,32} macros to
+ * specify the ARM and Thumb alternatives at the same time. This ensures
+ * that the correct opcode gets emitted depending on the instruction set
+ * used for the kernel build.
+ *
+ * Look at opcodes-virt.h for an example of how to use these macros.
+ */
+#include <linux/stringify.h>
+
+#define __inst_arm(x) ___inst_arm(___asm_opcode_to_mem_arm(x))
+#define __inst_thumb32(x) ___inst_thumb32( \
+ ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_first(x)), \
+ ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_second(x)) \
+)
+#define __inst_thumb16(x) ___inst_thumb16(___asm_opcode_to_mem_thumb16(x))
+
+#ifdef CONFIG_THUMB2_KERNEL
+#define __inst_arm_thumb16(arm_opcode, thumb_opcode) \
+ __inst_thumb16(thumb_opcode)
+#define __inst_arm_thumb32(arm_opcode, thumb_opcode) \
+ __inst_thumb32(thumb_opcode)
+#else
+#define __inst_arm_thumb16(arm_opcode, thumb_opcode) __inst_arm(arm_opcode)
+#define __inst_arm_thumb32(arm_opcode, thumb_opcode) __inst_arm(arm_opcode)
+#endif
+
+/* Helpers for the helpers. Don't use these directly. */
+#ifdef __ASSEMBLY__
+#define ___inst_arm(x) .long x
+#define ___inst_thumb16(x) .short x
+#define ___inst_thumb32(first, second) .short first, second
+#else
+#define ___inst_arm(x) ".long " __stringify(x) "\n\t"
+#define ___inst_thumb16(x) ".short " __stringify(x) "\n\t"
+#define ___inst_thumb32(first, second) \
+ ".short " __stringify(first) ", " __stringify(second) "\n\t"
+#endif
+
+#endif /* __ASM_ARM_OPCODES_H */
diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
new file mode 100644
index 000000000..563b92fc2
--- /dev/null
+++ b/arch/arm/include/asm/outercache.h
@@ -0,0 +1,149 @@
+/*
+ * 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 l2x0_regs;
+
+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 (*disable)(void);
+#ifdef CONFIG_OUTER_CACHE_SYNC
+ void (*sync)(void);
+#endif
+ void (*resume)(void);
+
+ /* This is an ARM L2C thing */
+ void (*write_sec)(unsigned long, unsigned);
+ void (*configure)(const struct l2x0_regs *);
+};
+
+extern struct outer_cache_fns outer_cache;
+
+#ifdef CONFIG_OUTER_CACHE
+/**
+ * outer_inv_range - invalidate range of outer cache lines
+ * @start: starting physical address, inclusive
+ * @end: end physical address, exclusive
+ */
+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);
+}
+
+/**
+ * outer_clean_range - clean dirty outer cache lines
+ * @start: starting physical address, inclusive
+ * @end: end physical address, exclusive
+ */
+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);
+}
+
+/**
+ * outer_flush_range - clean and invalidate outer cache lines
+ * @start: starting physical address, inclusive
+ * @end: end physical address, exclusive
+ */
+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);
+}
+
+/**
+ * outer_flush_all - clean and invalidate all cache lines in the outer cache
+ *
+ * Note: depending on implementation, this may not be atomic - it must
+ * only be called with interrupts disabled and no other active outer
+ * cache masters.
+ *
+ * It is intended that this function is only used by implementations
+ * needing to override the outer_cache.disable() method due to security.
+ * (Some implementations perform this as a clean followed by an invalidate.)
+ */
+static inline void outer_flush_all(void)
+{
+ if (outer_cache.flush_all)
+ outer_cache.flush_all();
+}
+
+/**
+ * outer_disable - clean, invalidate and disable the outer cache
+ *
+ * Disable the outer cache, ensuring that any data contained in the outer
+ * cache is pushed out to lower levels of system memory. The note and
+ * conditions above concerning outer_flush_all() applies here.
+ */
+extern void outer_disable(void);
+
+/**
+ * outer_resume - restore the cache configuration and re-enable outer cache
+ *
+ * Restore any configuration that the cache had when previously enabled,
+ * and re-enable the outer cache.
+ */
+static inline void outer_resume(void)
+{
+ if (outer_cache.resume)
+ outer_cache.resume();
+}
+
+#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_disable(void) { }
+static inline void outer_resume(void) { }
+
+#endif
+
+#ifdef CONFIG_OUTER_CACHE_SYNC
+/**
+ * outer_sync - perform a sync point for outer cache
+ *
+ * Ensure that all outer cache operations are complete and any store
+ * buffers are drained.
+ */
+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 000000000..d1b162a18
--- /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 000000000..4355f0ec4
--- /dev/null
+++ b/arch/arm/include/asm/page.h
@@ -0,0 +1,173 @@
+/*
+ * 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 (~((1 << PAGE_SHIFT) - 1))
+
+#ifndef __ASSEMBLY__
+
+#ifndef CONFIG_MMU
+
+#include <asm/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:
+ * 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_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);
+
+#ifdef CONFIG_KUSER_HELPERS
+#define __HAVE_ARCH_GATE_AREA 1
+#endif
+
+#ifdef CONFIG_ARM_LPAE
+#include <asm/pgtable-3level-types.h>
+#else
+#include <asm/pgtable-2level-types.h>
+#endif
+
+#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/patch.h b/arch/arm/include/asm/patch.h
new file mode 100644
index 000000000..77e054c2f
--- /dev/null
+++ b/arch/arm/include/asm/patch.h
@@ -0,0 +1,17 @@
+#ifndef _ARM_KERNEL_PATCH_H
+#define _ARM_KERNEL_PATCH_H
+
+void patch_text(void *addr, unsigned int insn);
+void __patch_text_real(void *addr, unsigned int insn, bool remap);
+
+static inline void __patch_text(void *addr, unsigned int insn)
+{
+ __patch_text_real(addr, insn, true);
+}
+
+static inline void __patch_text_early(void *addr, unsigned int insn)
+{
+ __patch_text_real(addr, insn, false);
+}
+
+#endif
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
new file mode 100644
index 000000000..585dc33a7
--- /dev/null
+++ b/arch/arm/include/asm/pci.h
@@ -0,0 +1,55 @@
+#ifndef ASMARM_PCI_H
+#define ASMARM_PCI_H
+
+#ifdef __KERNEL__
+#include <asm-generic/pci-dma-compat.h>
+#include <asm-generic/pci-bridge.h>
+
+#include <asm/mach/pci.h> /* for pci_sys_data */
+
+extern unsigned long pcibios_min_io;
+#define PCIBIOS_MIN_IO pcibios_min_io
+extern unsigned long pcibios_min_mem;
+#define PCIBIOS_MIN_MEM pcibios_min_mem
+
+static inline int pcibios_assign_all_busses(void)
+{
+ return pci_has_flag(PCI_REASSIGN_ALL_RSRC);
+}
+
+#ifdef CONFIG_PCI_DOMAINS
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+ return pci_domain_nr(bus);
+}
+#endif /* CONFIG_PCI_DOMAINS */
+
+/*
+ * 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);
+
+static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
+{
+ return channel ? 15 : 14;
+}
+
+#endif /* __KERNEL__ */
+
+#endif
diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h
new file mode 100644
index 000000000..a89b4076c
--- /dev/null
+++ b/arch/arm/include/asm/percpu.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012 Calxeda, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _ASM_ARM_PERCPU_H_
+#define _ASM_ARM_PERCPU_H_
+
+/*
+ * Same as asm-generic/percpu.h, except that we store the per cpu offset
+ * in the TPIDRPRW. TPIDRPRW only exists on V6K and V7
+ */
+#if defined(CONFIG_SMP) && !defined(CONFIG_CPU_V6)
+static inline void set_my_cpu_offset(unsigned long off)
+{
+ /* Set TPIDRPRW */
+ asm volatile("mcr p15, 0, %0, c13, c0, 4" : : "r" (off) : "memory");
+}
+
+static inline unsigned long __my_cpu_offset(void)
+{
+ unsigned long off;
+
+ /*
+ * Read TPIDRPRW.
+ * We want to allow caching the value, so avoid using volatile and
+ * instead use a fake stack read to hazard against barrier().
+ */
+ asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off)
+ : "Q" (*(const unsigned long *)current_stack_pointer));
+
+ return off;
+}
+#define __my_cpu_offset __my_cpu_offset()
+#else
+#define set_my_cpu_offset(x) do {} while(0)
+
+#endif /* CONFIG_SMP */
+
+#include <asm-generic/percpu.h>
+
+#endif /* _ASM_ARM_PERCPU_H_ */
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
new file mode 100644
index 000000000..d9cf138fd
--- /dev/null
+++ b/arch/arm/include/asm/perf_event.h
@@ -0,0 +1,22 @@
+/*
+ * 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__
+
+#ifdef CONFIG_PERF_EVENTS
+struct pt_regs;
+extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
+extern unsigned long perf_misc_flags(struct pt_regs *regs);
+#define perf_misc_flags(regs) perf_misc_flags(regs)
+#endif
+
+#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 000000000..19cfab526
--- /dev/null
+++ b/arch/arm/include/asm/pgalloc.h
@@ -0,0 +1,174 @@
+/*
+ * 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))
+
+#ifdef CONFIG_ARM_LPAE
+
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+ return (pmd_t *)get_zeroed_page(GFP_KERNEL | __GFP_REPEAT);
+}
+
+static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
+{
+ BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
+ free_page((unsigned long)pmd);
+}
+
+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+{
+ set_pud(pud, __pud(__pa(pmd) | PMD_TYPE_TABLE));
+}
+
+#else /* !CONFIG_ARM_LPAE */
+
+/*
+ * 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 pud_populate(mm,pmd,pte) BUG()
+
+#endif /* CONFIG_ARM_LPAE */
+
+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)
+ return NULL;
+ if (!PageHighMem(pte))
+ clean_pte_table(page_address(pte));
+ if (!pgtable_page_ctor(pte)) {
+ __free_page(pte);
+ return NULL;
+ }
+ 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,
+ pmdval_t prot)
+{
+ pmdval_t pmdval = (pte + PTE_HWTABLE_OFF) | prot;
+ pmdp[0] = __pmd(pmdval);
+#ifndef CONFIG_ARM_LPAE
+ pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
+#endif
+ 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)
+{
+ extern pmdval_t user_pmd_table;
+ pmdval_t prot;
+
+ if (__LINUX_ARM_ARCH__ >= 6 && !IS_ENABLED(CONFIG_ARM_LPAE))
+ prot = user_pmd_table;
+ else
+ prot = _PAGE_USER_TABLE;
+
+ __pmd_populate(pmdp, page_to_phys(ptep), prot);
+}
+#define pmd_pgtable(pmd) pmd_page(pmd)
+
+#endif /* CONFIG_MMU */
+
+#endif
diff --git a/arch/arm/include/asm/pgtable-2level-hwdef.h b/arch/arm/include/asm/pgtable-2level-hwdef.h
new file mode 100644
index 000000000..5e68278e9
--- /dev/null
+++ b/arch/arm/include/asm/pgtable-2level-hwdef.h
@@ -0,0 +1,95 @@
+/*
+ * arch/arm/include/asm/pgtable-2level-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 _ASM_PGTABLE_2LEVEL_HWDEF_H
+#define _ASM_PGTABLE_2LEVEL_HWDEF_H
+
+/*
+ * Hardware page table definitions.
+ *
+ * + Level 1 descriptor (PMD)
+ * - common
+ */
+#define PMD_TYPE_MASK (_AT(pmdval_t, 3) << 0)
+#define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0)
+#define PMD_TYPE_TABLE (_AT(pmdval_t, 1) << 0)
+#define PMD_TYPE_SECT (_AT(pmdval_t, 2) << 0)
+#define PMD_PXNTABLE (_AT(pmdval_t, 1) << 2) /* v7 */
+#define PMD_BIT4 (_AT(pmdval_t, 1) << 4)
+#define PMD_DOMAIN(x) (_AT(pmdval_t, (x)) << 5)
+#define PMD_PROTECTION (_AT(pmdval_t, 1) << 9) /* v5 */
+/*
+ * - section
+ */
+#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 0) /* v7 */
+#define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2)
+#define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3)
+#define PMD_SECT_XN (_AT(pmdval_t, 1) << 4) /* v6 */
+#define PMD_SECT_AP_WRITE (_AT(pmdval_t, 1) << 10)
+#define PMD_SECT_AP_READ (_AT(pmdval_t, 1) << 11)
+#define PMD_SECT_TEX(x) (_AT(pmdval_t, (x)) << 12) /* v5 */
+#define PMD_SECT_APX (_AT(pmdval_t, 1) << 15) /* v6 */
+#define PMD_SECT_S (_AT(pmdval_t, 1) << 16) /* v6 */
+#define PMD_SECT_nG (_AT(pmdval_t, 1) << 17) /* v6 */
+#define PMD_SECT_SUPER (_AT(pmdval_t, 1) << 18) /* v6 */
+#define PMD_SECT_AF (_AT(pmdval_t, 0))
+
+#define PMD_SECT_UNCACHED (_AT(pmdval_t, 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 (_AT(pteval_t, 3) << 0)
+#define PTE_TYPE_FAULT (_AT(pteval_t, 0) << 0)
+#define PTE_TYPE_LARGE (_AT(pteval_t, 1) << 0)
+#define PTE_TYPE_SMALL (_AT(pteval_t, 2) << 0)
+#define PTE_TYPE_EXT (_AT(pteval_t, 3) << 0) /* v5 */
+#define PTE_BUFFERABLE (_AT(pteval_t, 1) << 2)
+#define PTE_CACHEABLE (_AT(pteval_t, 1) << 3)
+
+/*
+ * - extended small page/tiny page
+ */
+#define PTE_EXT_XN (_AT(pteval_t, 1) << 0) /* v6 */
+#define PTE_EXT_AP_MASK (_AT(pteval_t, 3) << 4)
+#define PTE_EXT_AP0 (_AT(pteval_t, 1) << 4)
+#define PTE_EXT_AP1 (_AT(pteval_t, 2) << 4)
+#define PTE_EXT_AP_UNO_SRO (_AT(pteval_t, 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) (_AT(pteval_t, (x)) << 6) /* v5 */
+#define PTE_EXT_APX (_AT(pteval_t, 1) << 9) /* v6 */
+#define PTE_EXT_COHERENT (_AT(pteval_t, 1) << 9) /* XScale3 */
+#define PTE_EXT_SHARED (_AT(pteval_t, 1) << 10) /* v6 */
+#define PTE_EXT_NG (_AT(pteval_t, 1) << 11) /* v6 */
+
+/*
+ * - small page
+ */
+#define PTE_SMALL_AP_MASK (_AT(pteval_t, 0xff) << 4)
+#define PTE_SMALL_AP_UNO_SRO (_AT(pteval_t, 0x00) << 4)
+#define PTE_SMALL_AP_UNO_SRW (_AT(pteval_t, 0x55) << 4)
+#define PTE_SMALL_AP_URO_SRW (_AT(pteval_t, 0xaa) << 4)
+#define PTE_SMALL_AP_URW_SRW (_AT(pteval_t, 0xff) << 4)
+
+#define PHYS_MASK (~0UL)
+
+#endif
diff --git a/arch/arm/include/asm/pgtable-2level-types.h b/arch/arm/include/asm/pgtable-2level-types.h
new file mode 100644
index 000000000..66cb5b0e8
--- /dev/null
+++ b/arch/arm/include/asm/pgtable-2level-types.h
@@ -0,0 +1,67 @@
+/*
+ * arch/arm/include/asm/pgtable-2level-types.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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_PGTABLE_2LEVEL_TYPES_H
+#define _ASM_PGTABLE_2LEVEL_TYPES_H
+
+#include <asm/types.h>
+
+typedef u32 pteval_t;
+typedef u32 pmdval_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 { pmdval_t pmd; } pmd_t;
+typedef struct { pmdval_t pgd[2]; } pgd_t;
+typedef struct { pteval_t 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 pmdval_t pmd_t;
+typedef pmdval_t pgd_t[2];
+typedef pteval_t 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 /* _ASM_PGTABLE_2LEVEL_TYPES_H */
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
new file mode 100644
index 000000000..bfd662e49
--- /dev/null
+++ b/arch/arm/include/asm/pgtable-2level.h
@@ -0,0 +1,198 @@
+/*
+ * arch/arm/include/asm/pgtable-2level.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 _ASM_PGTABLE_2LEVEL_H
+#define _ASM_PGTABLE_2LEVEL_H
+
+#define __PAGETABLE_PMD_FOLDED
+
+/*
+ * 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 PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~(PMD_SIZE-1))
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+/*
+ * 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))
+
+#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
+
+/*
+ * "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_VALID (_AT(pteval_t, 1) << 0) /* Valid */
+#define L_PTE_PRESENT (_AT(pteval_t, 1) << 0)
+#define L_PTE_YOUNG (_AT(pteval_t, 1) << 1)
+#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) */
+#define L_PTE_NONE (_AT(pteval_t, 1) << 11)
+
+/*
+ * 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_VECTORS (_AT(pteval_t, 0x0f) << 2) /* 1111 */
+#define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * The "pud_xxx()" functions here are trivial when the pmd is folded into
+ * the pud: the pud entry is never bad, always exists, and can't be set or
+ * cleared.
+ */
+#define pud_none(pud) (0)
+#define pud_bad(pud) (0)
+#define pud_present(pud) (1)
+#define pud_clear(pudp) do { } while (0)
+#define set_pud(pud,pudp) do { } while (0)
+
+static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
+{
+ return (pmd_t *)pud;
+}
+
+#define pmd_large(pmd) (pmd_val(pmd) & 2)
+#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)
+
+/* we don't need complex calculations here as the pmd is folded into the pgd */
+#define pmd_addr_end(addr,end) (end)
+
+#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
+#define pte_special(pte) (0)
+static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
+
+/*
+ * We don't have huge page support for short descriptors, for the moment
+ * define empty stubs for use by pin_page_for_write.
+ */
+#define pmd_hugewillfault(pmd) (0)
+#define pmd_thp_or_huge(pmd) (0)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_PGTABLE_2LEVEL_H */
diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h
new file mode 100644
index 000000000..f8f1cff62
--- /dev/null
+++ b/arch/arm/include/asm/pgtable-3level-hwdef.h
@@ -0,0 +1,108 @@
+/*
+ * arch/arm/include/asm/pgtable-3level-hwdef.h
+ *
+ * Copyright (C) 2011 ARM Ltd.
+ * Author: 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_PGTABLE_3LEVEL_HWDEF_H
+#define _ASM_PGTABLE_3LEVEL_HWDEF_H
+
+/*
+ * Hardware page table definitions.
+ *
+ * + Level 1/2 descriptor
+ * - common
+ */
+#define PMD_TYPE_MASK (_AT(pmdval_t, 3) << 0)
+#define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0)
+#define PMD_TYPE_TABLE (_AT(pmdval_t, 3) << 0)
+#define PMD_TYPE_SECT (_AT(pmdval_t, 1) << 0)
+#define PMD_TABLE_BIT (_AT(pmdval_t, 1) << 1)
+#define PMD_BIT4 (_AT(pmdval_t, 0))
+#define PMD_DOMAIN(x) (_AT(pmdval_t, 0))
+#define PMD_APTABLE_SHIFT (61)
+#define PMD_APTABLE (_AT(pgdval_t, 3) << PGD_APTABLE_SHIFT)
+#define PMD_PXNTABLE (_AT(pgdval_t, 1) << 59)
+
+/*
+ * - section
+ */
+#define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2)
+#define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3)
+#define PMD_SECT_USER (_AT(pmdval_t, 1) << 6) /* AP[1] */
+#define PMD_SECT_AP2 (_AT(pmdval_t, 1) << 7) /* read only */
+#define PMD_SECT_S (_AT(pmdval_t, 3) << 8)
+#define PMD_SECT_AF (_AT(pmdval_t, 1) << 10)
+#define PMD_SECT_nG (_AT(pmdval_t, 1) << 11)
+#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 53)
+#define PMD_SECT_XN (_AT(pmdval_t, 1) << 54)
+#define PMD_SECT_AP_WRITE (_AT(pmdval_t, 0))
+#define PMD_SECT_AP_READ (_AT(pmdval_t, 0))
+#define PMD_SECT_AP1 (_AT(pmdval_t, 1) << 6)
+#define PMD_SECT_TEX(x) (_AT(pmdval_t, 0))
+
+/*
+ * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
+ */
+#define PMD_SECT_UNCACHED (_AT(pmdval_t, 0) << 2) /* strongly ordered */
+#define PMD_SECT_BUFFERED (_AT(pmdval_t, 1) << 2) /* normal non-cacheable */
+#define PMD_SECT_WT (_AT(pmdval_t, 2) << 2) /* normal inner write-through */
+#define PMD_SECT_WB (_AT(pmdval_t, 3) << 2) /* normal inner write-back */
+#define PMD_SECT_WBWA (_AT(pmdval_t, 7) << 2) /* normal inner write-alloc */
+
+/*
+ * + Level 3 descriptor (PTE)
+ */
+#define PTE_TYPE_MASK (_AT(pteval_t, 3) << 0)
+#define PTE_TYPE_FAULT (_AT(pteval_t, 0) << 0)
+#define PTE_TYPE_PAGE (_AT(pteval_t, 3) << 0)
+#define PTE_TABLE_BIT (_AT(pteval_t, 1) << 1)
+#define PTE_BUFFERABLE (_AT(pteval_t, 1) << 2) /* AttrIndx[0] */
+#define PTE_CACHEABLE (_AT(pteval_t, 1) << 3) /* AttrIndx[1] */
+#define PTE_AP2 (_AT(pteval_t, 1) << 7) /* AP[2] */
+#define PTE_EXT_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */
+#define PTE_EXT_AF (_AT(pteval_t, 1) << 10) /* Access Flag */
+#define PTE_EXT_NG (_AT(pteval_t, 1) << 11) /* nG */
+#define PTE_EXT_PXN (_AT(pteval_t, 1) << 53) /* PXN */
+#define PTE_EXT_XN (_AT(pteval_t, 1) << 54) /* XN */
+
+/*
+ * 40-bit physical address supported.
+ */
+#define PHYS_MASK_SHIFT (40)
+#define PHYS_MASK ((1ULL << PHYS_MASK_SHIFT) - 1)
+
+/*
+ * TTBR0/TTBR1 split (PAGE_OFFSET):
+ * 0x40000000: T0SZ = 2, T1SZ = 0 (not used)
+ * 0x80000000: T0SZ = 0, T1SZ = 1
+ * 0xc0000000: T0SZ = 0, T1SZ = 2
+ *
+ * Only use this feature if PHYS_OFFSET <= PAGE_OFFSET, otherwise
+ * booting secondary CPUs would end up using TTBR1 for the identity
+ * mapping set up in TTBR0.
+ */
+#if defined CONFIG_VMSPLIT_2G
+#define TTBR1_OFFSET 16 /* skip two L1 entries */
+#elif defined CONFIG_VMSPLIT_3G
+#define TTBR1_OFFSET (4096 * (1 + 3)) /* only L2, skip pgd + 3*pmd */
+#else
+#define TTBR1_OFFSET 0
+#endif
+
+#define TTBR1_SIZE (((PAGE_OFFSET >> 30) - 1) << 16)
+
+#endif
diff --git a/arch/arm/include/asm/pgtable-3level-types.h b/arch/arm/include/asm/pgtable-3level-types.h
new file mode 100644
index 000000000..921aa3025
--- /dev/null
+++ b/arch/arm/include/asm/pgtable-3level-types.h
@@ -0,0 +1,70 @@
+/*
+ * arch/arm/include/asm/pgtable-3level-types.h
+ *
+ * Copyright (C) 2011 ARM Ltd.
+ * Author: 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_PGTABLE_3LEVEL_TYPES_H
+#define _ASM_PGTABLE_3LEVEL_TYPES_H
+
+#include <asm/types.h>
+
+typedef u64 pteval_t;
+typedef u64 pmdval_t;
+typedef u64 pgdval_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 { pmdval_t pmd; } pmd_t;
+typedef struct { pgdval_t pgd; } pgd_t;
+typedef struct { pteval_t pgprot; } pgprot_t;
+
+#define pte_val(x) ((x).pte)
+#define pmd_val(x) ((x).pmd)
+#define pgd_val(x) ((x).pgd)
+#define pgprot_val(x) ((x).pgprot)
+
+#define __pte(x) ((pte_t) { (x) } )
+#define __pmd(x) ((pmd_t) { (x) } )
+#define __pgd(x) ((pgd_t) { (x) } )
+#define __pgprot(x) ((pgprot_t) { (x) } )
+
+#else /* !STRICT_MM_TYPECHECKS */
+
+typedef pteval_t pte_t;
+typedef pmdval_t pmd_t;
+typedef pgdval_t pgd_t;
+typedef pteval_t pgprot_t;
+
+#define pte_val(x) (x)
+#define pmd_val(x) (x)
+#define pgd_val(x) (x)
+#define pgprot_val(x) (x)
+
+#define __pte(x) (x)
+#define __pmd(x) (x)
+#define __pgd(x) (x)
+#define __pgprot(x) (x)
+
+#endif /* STRICT_MM_TYPECHECKS */
+
+#endif /* _ASM_PGTABLE_3LEVEL_TYPES_H */
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
new file mode 100644
index 000000000..a745a2a53
--- /dev/null
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -0,0 +1,299 @@
+/*
+ * arch/arm/include/asm/pgtable-3level.h
+ *
+ * Copyright (C) 2011 ARM Ltd.
+ * Author: 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_PGTABLE_3LEVEL_H
+#define _ASM_PGTABLE_3LEVEL_H
+
+/*
+ * With LPAE, there are 3 levels of page tables. Each level has 512 entries of
+ * 8 bytes each, occupying a 4K page. The first level table covers a range of
+ * 512GB, each entry representing 1GB. Since we are limited to 4GB input
+ * address range, only 4 entries in the PGD are used.
+ *
+ * There are enough spare bits in a page table entry for the kernel specific
+ * state.
+ */
+#define PTRS_PER_PTE 512
+#define PTRS_PER_PMD 512
+#define PTRS_PER_PGD 4
+
+#define PTE_HWTABLE_PTRS (0)
+#define PTE_HWTABLE_OFF (0)
+#define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u64))
+
+/*
+ * PGDIR_SHIFT determines the size a top-level page table entry can map.
+ */
+#define PGDIR_SHIFT 30
+
+/*
+ * PMD_SHIFT determines the size a middle-level page table entry can map.
+ */
+#define PMD_SHIFT 21
+
+#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~((1 << PMD_SHIFT) - 1))
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~((1 << PGDIR_SHIFT) - 1))
+
+/*
+ * section address mask and size definitions.
+ */
+#define SECTION_SHIFT 21
+#define SECTION_SIZE (1UL << SECTION_SHIFT)
+#define SECTION_MASK (~((1 << SECTION_SHIFT) - 1))
+
+#define USER_PTRS_PER_PGD (PAGE_OFFSET / PGDIR_SIZE)
+
+/*
+ * Hugetlb definitions.
+ */
+#define HPAGE_SHIFT PMD_SHIFT
+#define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT)
+#define HPAGE_MASK (~(HPAGE_SIZE - 1))
+#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
+
+/*
+ * "Linux" PTE definitions for LPAE.
+ *
+ * These bits overlap with the hardware bits but the naming is preserved for
+ * consistency with the classic page table format.
+ */
+#define L_PTE_VALID (_AT(pteval_t, 1) << 0) /* Valid */
+#define L_PTE_PRESENT (_AT(pteval_t, 3) << 0) /* Present */
+#define L_PTE_USER (_AT(pteval_t, 1) << 6) /* AP[1] */
+#define L_PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */
+#define L_PTE_YOUNG (_AT(pteval_t, 1) << 10) /* AF */
+#define L_PTE_XN (_AT(pteval_t, 1) << 54) /* XN */
+#define L_PTE_DIRTY (_AT(pteval_t, 1) << 55)
+#define L_PTE_SPECIAL (_AT(pteval_t, 1) << 56)
+#define L_PTE_NONE (_AT(pteval_t, 1) << 57) /* PROT_NONE */
+#define L_PTE_RDONLY (_AT(pteval_t, 1) << 58) /* READ ONLY */
+
+#define L_PMD_SECT_VALID (_AT(pmdval_t, 1) << 0)
+#define L_PMD_SECT_DIRTY (_AT(pmdval_t, 1) << 55)
+#define L_PMD_SECT_SPLITTING (_AT(pmdval_t, 1) << 56)
+#define L_PMD_SECT_NONE (_AT(pmdval_t, 1) << 57)
+#define L_PMD_SECT_RDONLY (_AT(pteval_t, 1) << 58)
+
+/*
+ * To be used in assembly code with the upper page attributes.
+ */
+#define L_PTE_XN_HIGH (1 << (54 - 32))
+#define L_PTE_DIRTY_HIGH (1 << (55 - 32))
+
+/*
+ * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
+ */
+#define L_PTE_MT_UNCACHED (_AT(pteval_t, 0) << 2) /* strongly ordered */
+#define L_PTE_MT_BUFFERABLE (_AT(pteval_t, 1) << 2) /* normal non-cacheable */
+#define L_PTE_MT_WRITETHROUGH (_AT(pteval_t, 2) << 2) /* normal inner write-through */
+#define L_PTE_MT_WRITEBACK (_AT(pteval_t, 3) << 2) /* normal inner write-back */
+#define L_PTE_MT_WRITEALLOC (_AT(pteval_t, 7) << 2) /* normal inner write-alloc */
+#define L_PTE_MT_DEV_SHARED (_AT(pteval_t, 4) << 2) /* device */
+#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 4) << 2) /* device */
+#define L_PTE_MT_DEV_WC (_AT(pteval_t, 1) << 2) /* normal non-cacheable */
+#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 3) << 2) /* normal inner write-back */
+#define L_PTE_MT_MASK (_AT(pteval_t, 7) << 2)
+
+/*
+ * Software PGD flags.
+ */
+#define L_PGD_SWAPPER (_AT(pgdval_t, 1) << 55) /* swapper_pg_dir entry */
+
+/*
+ * 2nd stage PTE definitions for LPAE.
+ */
+#define L_PTE_S2_MT_UNCACHED (_AT(pteval_t, 0x0) << 2) /* strongly ordered */
+#define L_PTE_S2_MT_WRITETHROUGH (_AT(pteval_t, 0xa) << 2) /* normal inner write-through */
+#define L_PTE_S2_MT_WRITEBACK (_AT(pteval_t, 0xf) << 2) /* normal inner write-back */
+#define L_PTE_S2_MT_DEV_SHARED (_AT(pteval_t, 0x1) << 2) /* device */
+#define L_PTE_S2_MT_MASK (_AT(pteval_t, 0xf) << 2)
+
+#define L_PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[1] */
+#define L_PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */
+
+#define L_PMD_S2_RDONLY (_AT(pmdval_t, 1) << 6) /* HAP[1] */
+#define L_PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */
+
+/*
+ * Hyp-mode PL2 PTE definitions for LPAE.
+ */
+#define L_PTE_HYP L_PTE_USER
+
+#ifndef __ASSEMBLY__
+
+#define pud_none(pud) (!pud_val(pud))
+#define pud_bad(pud) (!(pud_val(pud) & 2))
+#define pud_present(pud) (pud_val(pud))
+#define pmd_table(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) == \
+ PMD_TYPE_TABLE)
+#define pmd_sect(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) == \
+ PMD_TYPE_SECT)
+#define pmd_large(pmd) pmd_sect(pmd)
+
+#define pud_clear(pudp) \
+ do { \
+ *pudp = __pud(0); \
+ clean_pmd_entry(pudp); \
+ } while (0)
+
+#define set_pud(pudp, pud) \
+ do { \
+ *pudp = pud; \
+ flush_pmd_entry(pudp); \
+ } while (0)
+
+static inline pmd_t *pud_page_vaddr(pud_t pud)
+{
+ return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK);
+}
+
+/* Find an entry in the second-level page table.. */
+#define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
+static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
+{
+ return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr);
+}
+
+#define pmd_bad(pmd) (!(pmd_val(pmd) & 2))
+
+#define copy_pmd(pmdpd,pmdps) \
+ do { \
+ *pmdpd = *pmdps; \
+ flush_pmd_entry(pmdpd); \
+ } while (0)
+
+#define pmd_clear(pmdp) \
+ do { \
+ *pmdp = __pmd(0); \
+ clean_pmd_entry(pmdp); \
+ } while (0)
+
+/*
+ * For 3 levels of paging the PTE_EXT_NG bit will be set for user address ptes
+ * that are written to a page table but not for ptes created with mk_pte.
+ *
+ * In hugetlb_no_page, a new huge pte (new_pte) is generated and passed to
+ * hugetlb_cow, where it is compared with an entry in a page table.
+ * This comparison test fails erroneously leading ultimately to a memory leak.
+ *
+ * To correct this behaviour, we mask off PTE_EXT_NG for any pte that is
+ * present before running the comparison.
+ */
+#define __HAVE_ARCH_PTE_SAME
+#define pte_same(pte_a,pte_b) ((pte_present(pte_a) ? pte_val(pte_a) & ~PTE_EXT_NG \
+ : pte_val(pte_a)) \
+ == (pte_present(pte_b) ? pte_val(pte_b) & ~PTE_EXT_NG \
+ : pte_val(pte_b)))
+
+#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,__pte(pte_val(pte)|(ext)))
+
+#define pte_huge(pte) (pte_val(pte) && !(pte_val(pte) & PTE_TABLE_BIT))
+#define pte_mkhuge(pte) (__pte(pte_val(pte) & ~PTE_TABLE_BIT))
+
+#define pmd_isset(pmd, val) ((u32)(val) == (val) ? pmd_val(pmd) & (val) \
+ : !!(pmd_val(pmd) & (val)))
+#define pmd_isclear(pmd, val) (!(pmd_val(pmd) & (val)))
+
+#define pmd_young(pmd) (pmd_isset((pmd), PMD_SECT_AF))
+#define pte_special(pte) (pte_isset((pte), L_PTE_SPECIAL))
+static inline pte_t pte_mkspecial(pte_t pte)
+{
+ pte_val(pte) |= L_PTE_SPECIAL;
+ return pte;
+}
+#define __HAVE_ARCH_PTE_SPECIAL
+
+#define __HAVE_ARCH_PMD_WRITE
+#define pmd_write(pmd) (pmd_isclear((pmd), L_PMD_SECT_RDONLY))
+#define pmd_dirty(pmd) (pmd_isset((pmd), L_PMD_SECT_DIRTY))
+#define pud_page(pud) pmd_page(__pmd(pud_val(pud)))
+#define pud_write(pud) pmd_write(__pmd(pud_val(pud)))
+
+#define pmd_hugewillfault(pmd) (!pmd_young(pmd) || !pmd_write(pmd))
+#define pmd_thp_or_huge(pmd) (pmd_huge(pmd) || pmd_trans_huge(pmd))
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define pmd_trans_huge(pmd) (pmd_val(pmd) && !pmd_table(pmd))
+#define pmd_trans_splitting(pmd) (pmd_isset((pmd), L_PMD_SECT_SPLITTING))
+
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
+void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
+ pmd_t *pmdp);
+#endif
+#endif
+
+#define PMD_BIT_FUNC(fn,op) \
+static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; }
+
+PMD_BIT_FUNC(wrprotect, |= L_PMD_SECT_RDONLY);
+PMD_BIT_FUNC(mkold, &= ~PMD_SECT_AF);
+PMD_BIT_FUNC(mksplitting, |= L_PMD_SECT_SPLITTING);
+PMD_BIT_FUNC(mkwrite, &= ~L_PMD_SECT_RDONLY);
+PMD_BIT_FUNC(mkdirty, |= L_PMD_SECT_DIRTY);
+PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF);
+
+#define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
+
+#define pmd_pfn(pmd) (((pmd_val(pmd) & PMD_MASK) & PHYS_MASK) >> PAGE_SHIFT)
+#define pfn_pmd(pfn,prot) (__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
+#define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot)
+
+/* represent a notpresent pmd by zero, this is used by pmdp_invalidate */
+static inline pmd_t pmd_mknotpresent(pmd_t pmd)
+{
+ return __pmd(0);
+}
+
+static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+{
+ const pmdval_t mask = PMD_SECT_USER | PMD_SECT_XN | L_PMD_SECT_RDONLY |
+ L_PMD_SECT_VALID | L_PMD_SECT_NONE;
+ pmd_val(pmd) = (pmd_val(pmd) & ~mask) | (pgprot_val(newprot) & mask);
+ return pmd;
+}
+
+static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+ pmd_t *pmdp, pmd_t pmd)
+{
+ BUG_ON(addr >= TASK_SIZE);
+
+ /* create a faulting entry if PROT_NONE protected */
+ if (pmd_val(pmd) & L_PMD_SECT_NONE)
+ pmd_val(pmd) &= ~L_PMD_SECT_VALID;
+
+ if (pmd_write(pmd) && pmd_dirty(pmd))
+ pmd_val(pmd) &= ~PMD_SECT_AP2;
+ else
+ pmd_val(pmd) |= PMD_SECT_AP2;
+
+ *pmdp = __pmd(pmd_val(pmd) | PMD_SECT_nG);
+ flush_pmd_entry(pmdp);
+}
+
+static inline int has_transparent_hugepage(void)
+{
+ return 1;
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_PGTABLE_3LEVEL_H */
diff --git a/arch/arm/include/asm/pgtable-hwdef.h b/arch/arm/include/asm/pgtable-hwdef.h
new file mode 100644
index 000000000..8426229ba
--- /dev/null
+++ b/arch/arm/include/asm/pgtable-hwdef.h
@@ -0,0 +1,19 @@
+/*
+ * 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
+
+#ifdef CONFIG_ARM_LPAE
+#include <asm/pgtable-3level-hwdef.h>
+#else
+#include <asm/pgtable-2level-hwdef.h>
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/pgtable-nommu.h b/arch/arm/include/asm/pgtable-nommu.h
new file mode 100644
index 000000000..add094d09
--- /dev/null
+++ b/arch/arm/include/asm/pgtable-nommu.h
@@ -0,0 +1,114 @@
+/*
+ * 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;
+
+/*
+ * 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)
+
+/*
+ * 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 0UL
+
+#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 000000000..f40354198
--- /dev/null
+++ b/arch/arm/include/asm/pgtable.h
@@ -0,0 +1,363 @@
+/*
+ * 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/proc-fns.h>
+
+#ifndef CONFIG_MMU
+
+#include <asm-generic/4level-fixup.h>
+#include <asm/pgtable-nommu.h>
+
+#else
+
+#include <asm-generic/pgtable-nopud.h>
+#include <asm/memory.h>
+#include <asm/pgtable-hwdef.h>
+
+
+#include <asm/tlbflush.h>
+
+#ifdef CONFIG_ARM_LPAE
+#include <asm/pgtable-3level.h>
+#else
+#include <asm/pgtable-2level.h>
+#endif
+
+/*
+ * 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_OFFSET (8*1024*1024)
+#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_END 0xff000000UL
+
+#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)
+
+/*
+ * 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 * 2)
+
+/*
+ * Use TASK_SIZE as the ceiling argument for free_pgtables() and
+ * free_pgd_range() to avoid freeing the modules pmd when LPAE is enabled (pmd
+ * page shared between user and kernel).
+ */
+#ifdef CONFIG_ARM_LPAE
+#define USER_PGTABLES_CEILING TASK_SIZE
+#endif
+
+/*
+ * 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;
+extern pgprot_t pgprot_hyp_device;
+extern pgprot_t pgprot_s2;
+extern pgprot_t pgprot_s2_device;
+
+#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b))
+
+#define PAGE_NONE _MOD_PROT(pgprot_user, L_PTE_XN | L_PTE_RDONLY | L_PTE_NONE)
+#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_HYP _MOD_PROT(pgprot_kernel, L_PTE_HYP)
+#define PAGE_HYP_DEVICE _MOD_PROT(pgprot_hyp_device, L_PTE_HYP)
+#define PAGE_S2 _MOD_PROT(pgprot_s2, L_PTE_S2_RDONLY)
+#define PAGE_S2_DEVICE _MOD_PROT(pgprot_s2_device, L_PTE_S2_RDONLY)
+
+#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN | L_PTE_NONE)
+#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_stronglyordered(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
+
+#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)
+
+#define pmd_none(pmd) (!pmd_val(pmd))
+#define pmd_present(pmd) (pmd_val(pmd))
+
+static inline pte_t *pmd_page_vaddr(pmd_t pmd)
+{
+ return __va(pmd_val(pmd) & PHYS_MASK & (s32)PAGE_MASK);
+}
+
+#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
+
+#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) & PHYS_MASK) >> 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 pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
+
+#define pte_isset(pte, val) ((u32)(val) == (val) ? pte_val(pte) & (val) \
+ : !!(pte_val(pte) & (val)))
+#define pte_isclear(pte, val) (!(pte_val(pte) & (val)))
+
+#define pte_none(pte) (!pte_val(pte))
+#define pte_present(pte) (pte_isset((pte), L_PTE_PRESENT))
+#define pte_valid(pte) (pte_isset((pte), L_PTE_VALID))
+#define pte_accessible(mm, pte) (mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid(pte))
+#define pte_write(pte) (pte_isclear((pte), L_PTE_RDONLY))
+#define pte_dirty(pte) (pte_isset((pte), L_PTE_DIRTY))
+#define pte_young(pte) (pte_isset((pte), L_PTE_YOUNG))
+#define pte_exec(pte) (pte_isclear((pte), L_PTE_XN))
+
+#define pte_valid_user(pte) \
+ (pte_valid(pte) && pte_isset((pte), L_PTE_USER) && pte_young(pte))
+
+#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)
+{
+ unsigned long ext = 0;
+
+ if (addr < TASK_SIZE && pte_valid_user(pteval)) {
+ if (!pte_special(pteval))
+ __sync_icache_dcache(pteval);
+ ext |= PTE_EXT_NG;
+ }
+
+ set_pte_ext(ptep, pteval, ext);
+}
+
+static inline pte_t clear_pte_bit(pte_t pte, pgprot_t prot)
+{
+ pte_val(pte) &= ~pgprot_val(prot);
+ return pte;
+}
+
+static inline pte_t set_pte_bit(pte_t pte, pgprot_t prot)
+{
+ pte_val(pte) |= pgprot_val(prot);
+ return pte;
+}
+
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+ return set_pte_bit(pte, __pgprot(L_PTE_RDONLY));
+}
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+ return clear_pte_bit(pte, __pgprot(L_PTE_RDONLY));
+}
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+ return clear_pte_bit(pte, __pgprot(L_PTE_DIRTY));
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+ return set_pte_bit(pte, __pgprot(L_PTE_DIRTY));
+}
+
+static inline pte_t pte_mkold(pte_t pte)
+{
+ return clear_pte_bit(pte, __pgprot(L_PTE_YOUNG));
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+ return set_pte_bit(pte, __pgprot(L_PTE_YOUNG));
+}
+
+static inline pte_t pte_mkexec(pte_t pte)
+{
+ return clear_pte_bit(pte, __pgprot(L_PTE_XN));
+}
+
+static inline pte_t pte_mknexec(pte_t pte)
+{
+ return set_pte_bit(pte, __pgprot(L_PTE_XN));
+}
+
+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 |
+ L_PTE_NONE | L_PTE_VALID;
+ 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
+ *
+ * This gives us up to 31 swap files and 128GB per swap file. Note that
+ * the offset field is always non-zero.
+ */
+#define __SWP_TYPE_SHIFT 2
+#define __SWP_TYPE_BITS 5
+#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)
+
+/* 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
+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+
+#define pgtable_cache_init() do { } while (0)
+
+#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 000000000..675e4ab79
--- /dev/null
+++ b/arch/arm/include/asm/pmu.h
@@ -0,0 +1,163 @@
+/*
+ * 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>
+#include <linux/perf_event.h>
+
+#include <asm/cputype.h>
+
+/*
+ * 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.
+ * @runtime_resume: an optional handler which will be called by the
+ * runtime PM framework following a call to pm_runtime_get().
+ * Note that if pm_runtime_get() is called more than once in
+ * succession this handler will only be called once.
+ * @runtime_suspend: an optional handler which will be called by the
+ * runtime PM framework following a call to pm_runtime_put().
+ * Note that if pm_runtime_get() is called more than once in
+ * succession this handler will only be called following the
+ * final call to pm_runtime_put() that actually disables the
+ * hardware.
+ */
+struct arm_pmu_platdata {
+ irqreturn_t (*handle_irq)(int irq, void *dev,
+ irq_handler_t pmu_handler);
+ int (*runtime_resume)(struct device *dev);
+ int (*runtime_suspend)(struct device *dev);
+};
+
+#ifdef CONFIG_HW_PERF_EVENTS
+
+/*
+ * The ARMv7 CPU PMU supports up to 32 event counters.
+ */
+#define ARMPMU_MAX_HWEVENTS 32
+
+#define HW_OP_UNSUPPORTED 0xFFFF
+#define C(_x) PERF_COUNT_HW_CACHE_##_x
+#define CACHE_OP_UNSUPPORTED 0xFFFF
+
+#define PERF_MAP_ALL_UNSUPPORTED \
+ [0 ... PERF_COUNT_HW_MAX - 1] = HW_OP_UNSUPPORTED
+
+#define PERF_CACHE_MAP_ALL_UNSUPPORTED \
+[0 ... C(MAX) - 1] = { \
+ [0 ... C(OP_MAX) - 1] = { \
+ [0 ... C(RESULT_MAX) - 1] = CACHE_OP_UNSUPPORTED, \
+ }, \
+}
+
+/* The events for a given PMU register set. */
+struct pmu_hw_events {
+ /*
+ * The events that are active on the PMU for the given index.
+ */
+ 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.
+ */
+ DECLARE_BITMAP(used_mask, ARMPMU_MAX_HWEVENTS);
+
+ /*
+ * Hardware lock to serialize accesses to PMU registers. Needed for the
+ * read/modify/write sequences.
+ */
+ raw_spinlock_t pmu_lock;
+
+ /*
+ * When using percpu IRQs, we need a percpu dev_id. Place it here as we
+ * already have to allocate this struct per cpu.
+ */
+ struct arm_pmu *percpu_pmu;
+};
+
+struct arm_pmu {
+ struct pmu pmu;
+ cpumask_t active_irqs;
+ int *irq_affinity;
+ char *name;
+ irqreturn_t (*handle_irq)(int irq_num, void *dev);
+ void (*enable)(struct perf_event *event);
+ void (*disable)(struct perf_event *event);
+ int (*get_event_idx)(struct pmu_hw_events *hw_events,
+ struct perf_event *event);
+ void (*clear_event_idx)(struct pmu_hw_events *hw_events,
+ struct perf_event *event);
+ int (*set_event_filter)(struct hw_perf_event *evt,
+ struct perf_event_attr *attr);
+ u32 (*read_counter)(struct perf_event *event);
+ void (*write_counter)(struct perf_event *event, u32 val);
+ void (*start)(struct arm_pmu *);
+ void (*stop)(struct arm_pmu *);
+ void (*reset)(void *);
+ int (*request_irq)(struct arm_pmu *, irq_handler_t handler);
+ void (*free_irq)(struct arm_pmu *);
+ int (*map_event)(struct perf_event *event);
+ int num_events;
+ atomic_t active_events;
+ struct mutex reserve_mutex;
+ u64 max_period;
+ struct platform_device *plat_device;
+ struct pmu_hw_events __percpu *hw_events;
+ struct notifier_block hotplug_nb;
+};
+
+#define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
+
+extern const struct dev_pm_ops armpmu_dev_pm_ops;
+
+int armpmu_register(struct arm_pmu *armpmu, int type);
+
+u64 armpmu_event_update(struct perf_event *event);
+
+int armpmu_event_set_period(struct perf_event *event);
+
+int armpmu_map_event(struct perf_event *event,
+ const unsigned (*event_map)[PERF_COUNT_HW_MAX],
+ const unsigned (*cache_map)[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX],
+ u32 raw_event_mask);
+
+struct pmu_probe_info {
+ unsigned int cpuid;
+ unsigned int mask;
+ int (*init)(struct arm_pmu *);
+};
+
+#define PMU_PROBE(_cpuid, _mask, _fn) \
+{ \
+ .cpuid = (_cpuid), \
+ .mask = (_mask), \
+ .init = (_fn), \
+}
+
+#define ARM_PMU_PROBE(_cpuid, _fn) \
+ PMU_PROBE(_cpuid, ARM_CPU_PART_MASK, _fn)
+
+#define ARM_PMU_XSCALE_MASK ((0xff << 24) | ARM_CPU_XSCALE_ARCH_MASK)
+
+#define XSCALE_PMU_PROBE(_version, _fn) \
+ PMU_PROBE(ARM_CPU_IMP_INTEL << 24 | _version, ARM_PMU_XSCALE_MASK, _fn)
+
+#endif /* CONFIG_HW_PERF_EVENTS */
+
+#endif /* __ARM_PMU_H__ */
diff --git a/arch/arm/include/asm/probes.h b/arch/arm/include/asm/probes.h
new file mode 100644
index 000000000..1e5b9bb92
--- /dev/null
+++ b/arch/arm/include/asm/probes.h
@@ -0,0 +1,58 @@
+/*
+ * arch/arm/include/asm/probes.h
+ *
+ * Original contents copied from arch/arm/include/asm/kprobes.h
+ * which contains the following notice...
+ *
+ * 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 _ASM_PROBES_H
+#define _ASM_PROBES_H
+
+#ifndef __ASSEMBLY__
+
+typedef u32 probes_opcode_t;
+
+struct arch_probes_insn;
+typedef void (probes_insn_handler_t)(probes_opcode_t,
+ struct arch_probes_insn *,
+ struct pt_regs *);
+typedef unsigned long (probes_check_cc)(unsigned long);
+typedef void (probes_insn_singlestep_t)(probes_opcode_t,
+ struct arch_probes_insn *,
+ struct pt_regs *);
+typedef void (probes_insn_fn_t)(void);
+
+/* Architecture specific copy of original instruction. */
+struct arch_probes_insn {
+ probes_opcode_t *insn;
+ probes_insn_handler_t *insn_handler;
+ probes_check_cc *insn_check_cc;
+ probes_insn_singlestep_t *insn_singlestep;
+ probes_insn_fn_t *insn_fn;
+ int stack_space;
+ unsigned long register_usage_flags;
+ bool kprobe_direct_exec;
+};
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * We assume one instruction can consume at most 64 bytes stack, which is
+ * 'push {r0-r15}'. Instructions consume more or unknown stack space like
+ * 'str r0, [sp, #-80]' and 'str r0, [sp, r1]' should be prohibit to probe.
+ * Both kprobe and jprobe use this macro.
+ */
+#define MAX_STACK_SIZE 64
+
+#endif
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
new file mode 100644
index 000000000..5324c1112
--- /dev/null
+++ b/arch/arm/include/asm/proc-fns.h
@@ -0,0 +1,160 @@
+/*
+ * 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)(phys_addr_t pgd_phys, struct mm_struct *mm);
+ /*
+ * Set a possibly extended PTE. Non-extended PTEs should
+ * ignore 'ext'.
+ */
+#ifdef CONFIG_ARM_LPAE
+ void (*set_pte_ext)(pte_t *ptep, pte_t pte);
+#else
+ void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
+#endif
+
+ /* 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(phys_addr_t pgd_phys, struct mm_struct *mm);
+#ifdef CONFIG_ARM_LPAE
+extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte);
+#else
+extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+#endif
+extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
+
+/* These three are private to arch/arm/kernel/suspend.c */
+extern void cpu_do_suspend(void *);
+extern void cpu_do_resume(void *);
+#else
+#define cpu_proc_init processor._proc_init
+#define cpu_proc_fin processor._proc_fin
+#define cpu_reset processor.reset
+#define cpu_do_idle processor._do_idle
+#define cpu_dcache_clean_area processor.dcache_clean_area
+#define cpu_set_pte_ext processor.set_pte_ext
+#define cpu_do_switch_mm processor.switch_mm
+
+/* These three are private to arch/arm/kernel/suspend.c */
+#define cpu_do_suspend processor.do_suspend
+#define cpu_do_resume processor.do_resume
+#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)
+
+#ifdef CONFIG_ARM_LPAE
+
+#define cpu_get_ttbr(nr) \
+ ({ \
+ u64 ttbr; \
+ __asm__("mrrc p15, " #nr ", %Q0, %R0, c2" \
+ : "=r" (ttbr)); \
+ ttbr; \
+ })
+
+#define cpu_set_ttbr(nr, val) \
+ do { \
+ u64 ttbr = val; \
+ __asm__("mcrr p15, " #nr ", %Q0, %R0, c2" \
+ : : "r" (ttbr)); \
+ } while (0)
+
+#define cpu_get_pgd() \
+ ({ \
+ u64 pg = cpu_get_ttbr(0); \
+ pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1); \
+ (pgd_t *)phys_to_virt(pg); \
+ })
+#else
+#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
+
+#else /*!CONFIG_MMU */
+
+#define cpu_switch_mm(pgd,mm) { }
+
+#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 000000000..8a1e8e995
--- /dev/null
+++ b/arch/arm/include/asm/processor.h
@@ -0,0 +1,136 @@
+/*
+ * 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>
+#include <asm/unified.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) \
+({ \
+ 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 */ \
+ 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 *);
+
+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
+
+#define cpu_relax_lowlatency() cpu_relax()
+
+#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
+
+#ifdef CONFIG_SMP
+#define __ALT_SMP_ASM(smp, up) \
+ "9998: " smp "\n" \
+ " .pushsection \".alt.smp.init\", \"a\"\n" \
+ " .long 9998b\n" \
+ " " up "\n" \
+ " .popsection\n"
+#else
+#define __ALT_SMP_ASM(smp, up) up
+#endif
+
+/*
+ * 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));
+}
+
+#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
+#define ARCH_HAS_PREFETCHW
+static inline void prefetchw(const void *ptr)
+{
+ __asm__ __volatile__(
+ ".arch_extension mp\n"
+ __ALT_SMP_ASM(
+ WASM(pldw) "\t%a0",
+ WASM(pld) "\t%a0"
+ )
+ :: "p" (ptr));
+}
+#endif
+#endif
+
+#define HAVE_ARCH_PICK_MMAP_LAYOUT
+
+#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 000000000..ca52e584e
--- /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 000000000..cd94ef2ef
--- /dev/null
+++ b/arch/arm/include/asm/prom.h
@@ -0,0 +1,29 @@
+/*
+ * 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
+
+extern const struct machine_desc *setup_machine_fdt(unsigned int dt_phys);
+extern void __init arm_dt_init_cpu_maps(void);
+
+#else /* CONFIG_OF */
+
+static inline const struct machine_desc *setup_machine_fdt(unsigned int dt_phys)
+{
+ return NULL;
+}
+
+static inline void arm_dt_init_cpu_maps(void) { }
+
+#endif /* CONFIG_OF */
+#endif /* ASMARM_PROM_H */
diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
new file mode 100644
index 000000000..c25ef3ec6
--- /dev/null
+++ b/arch/arm/include/asm/psci.h
@@ -0,0 +1,48 @@
+/*
+ * This program is free software; you can 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.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#ifndef __ASM_ARM_PSCI_H
+#define __ASM_ARM_PSCI_H
+
+#define PSCI_POWER_STATE_TYPE_STANDBY 0
+#define PSCI_POWER_STATE_TYPE_POWER_DOWN 1
+
+struct psci_power_state {
+ u16 id;
+ u8 type;
+ u8 affinity_level;
+};
+
+struct psci_operations {
+ int (*cpu_suspend)(struct psci_power_state state,
+ unsigned long entry_point);
+ int (*cpu_off)(struct psci_power_state state);
+ int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
+ int (*migrate)(unsigned long cpuid);
+ int (*affinity_info)(unsigned long target_affinity,
+ unsigned long lowest_affinity_level);
+ int (*migrate_info_type)(void);
+};
+
+extern struct psci_operations psci_ops;
+extern struct smp_operations psci_smp_ops;
+
+#ifdef CONFIG_ARM_PSCI
+int psci_init(void);
+bool psci_smp_available(void);
+#else
+static inline int psci_init(void) { return 0; }
+static inline bool psci_smp_available(void) { return false; }
+#endif
+
+#endif /* __ASM_ARM_PSCI_H */
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
new file mode 100644
index 000000000..51622ba7c
--- /dev/null
+++ b/arch/arm/include/asm/ptrace.h
@@ -0,0 +1,162 @@
+/*
+ * 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 <uapi/asm/ptrace.h>
+
+#ifndef __ASSEMBLY__
+struct pt_regs {
+ unsigned long uregs[18];
+};
+
+#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
+
+#ifndef CONFIG_CPU_V7M
+#define isa_mode(regs) \
+ ((((regs)->ARM_cpsr & PSR_J_BIT) >> (__ffs(PSR_J_BIT) - 1)) | \
+ (((regs)->ARM_cpsr & PSR_T_BIT) >> (__ffs(PSR_T_BIT))))
+#else
+#define isa_mode(regs) 1 /* Thumb */
+#endif
+
+#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)
+{
+#ifndef CONFIG_CPU_V7M
+ 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;
+#else /* ifndef CONFIG_CPU_V7M */
+ return 1;
+#endif
+}
+
+static inline long regs_return_value(struct pt_regs *regs)
+{
+ return regs->ARM_r0;
+}
+
+#define instruction_pointer(regs) (regs)->ARM_pc
+
+#ifdef CONFIG_THUMB2_KERNEL
+#define frame_pointer(regs) (regs)->ARM_r7
+#else
+#define frame_pointer(regs) (regs)->ARM_fp
+#endif
+
+static inline void instruction_pointer_set(struct pt_regs *regs,
+ unsigned long val)
+{
+ instruction_pointer(regs) = val;
+}
+
+#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
+
+/*
+ * True if instr is a 32-bit thumb instruction. This works if instr
+ * is the first or only half-word of a thumb instruction. It also works
+ * when instr holds all 32-bits of a wide thumb instruction if stored
+ * in the form (first_half<<16)|(second_half)
+ */
+#define is_wide_instruction(instr) ((unsigned)(instr) >= 0xe800)
+
+/*
+ * 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;
+}
+
+static inline unsigned long user_stack_pointer(struct pt_regs *regs)
+{
+ return regs->ARM_sp;
+}
+
+#define current_pt_regs(void) ({ (struct pt_regs *) \
+ ((current_stack_pointer | (THREAD_SIZE - 1)) - 7) - 1; \
+})
+
+#endif /* __ASSEMBLY__ */
+#endif
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
new file mode 100644
index 000000000..e0adb9f1b
--- /dev/null
+++ b/arch/arm/include/asm/setup.h
@@ -0,0 +1,28 @@
+/*
+ * 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 <uapi/asm/setup.h>
+
+
+#define __tag __used __attribute__((__section__(".taglist.init")))
+#define __tagtable(tag, fn) \
+static const struct tagtable __tagtable_##fn __tag = { tag, fn }
+
+extern int arm_add_memory(u64 start, u64 size);
+extern void early_print(const char *str, ...);
+extern void dump_machine_table(void);
+
+#endif
diff --git a/arch/arm/include/asm/shmparam.h b/arch/arm/include/asm/shmparam.h
new file mode 100644
index 000000000..a5223b3a9
--- /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/signal.h b/arch/arm/include/asm/signal.h
new file mode 100644
index 000000000..c0eb412af
--- /dev/null
+++ b/arch/arm/include/asm/signal.h
@@ -0,0 +1,22 @@
+#ifndef _ASMARM_SIGNAL_H
+#define _ASMARM_SIGNAL_H
+
+#include <uapi/asm/signal.h>
+
+/* 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;
+
+#define __ARCH_HAS_SA_RESTORER
+
+#include <asm/sigcontext.h>
+#endif
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
new file mode 100644
index 000000000..18f5a5541
--- /dev/null
+++ b/arch/arm/include/asm/smp.h
@@ -0,0 +1,126 @@
+/*
+ * 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);
+
+/*
+ * Called from C code, this handles an IPI.
+ */
+void handle_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));
+
+/*
+ * Called from platform specific assembly code, this is the
+ * secondary CPU entry point.
+ */
+asmlinkage void secondary_start_kernel(void);
+
+
+/*
+ * Initial data for bringing up a secondary CPU.
+ */
+struct secondary_data {
+ union {
+ unsigned long mpu_rgn_szr;
+ unsigned long pgdir;
+ };
+ unsigned long swapper_pg_dir;
+ void *stack;
+};
+extern struct secondary_data secondary_data;
+extern volatile int pen_release;
+extern void secondary_startup(void);
+
+extern int __cpu_disable(void);
+
+extern void __cpu_die(unsigned int cpu);
+extern void cpu_die(void);
+
+extern void arch_send_call_function_single_ipi(int cpu);
+extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+extern void arch_send_wakeup_ipi_mask(const struct cpumask *mask);
+
+extern int register_ipi_completion(struct completion *completion, int cpu);
+
+struct smp_operations {
+#ifdef CONFIG_SMP
+ /*
+ * Setup the set of possible CPUs (via set_cpu_possible)
+ */
+ void (*smp_init_cpus)(void);
+ /*
+ * Initialize cpu_possible map, and enable coherency
+ */
+ void (*smp_prepare_cpus)(unsigned int max_cpus);
+
+ /*
+ * Perform platform specific initialisation of the specified CPU.
+ */
+ void (*smp_secondary_init)(unsigned int cpu);
+ /*
+ * Boot a secondary CPU, and assign it the specified idle task.
+ * This also gives us the initial stack to use for this CPU.
+ */
+ int (*smp_boot_secondary)(unsigned int cpu, struct task_struct *idle);
+#ifdef CONFIG_HOTPLUG_CPU
+ int (*cpu_kill)(unsigned int cpu);
+ void (*cpu_die)(unsigned int cpu);
+ int (*cpu_disable)(unsigned int cpu);
+#endif
+#endif
+};
+
+struct of_cpu_method {
+ const char *method;
+ struct smp_operations *ops;
+};
+
+#define CPU_METHOD_OF_DECLARE(name, _method, _ops) \
+ static const struct of_cpu_method __cpu_method_of_table_##name \
+ __used __section(__cpu_method_of_table) \
+ = { .method = _method, .ops = _ops }
+/*
+ * set platform specific SMP operations
+ */
+extern void smp_set_ops(struct smp_operations *);
+
+#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 000000000..993e5224d
--- /dev/null
+++ b/arch/arm/include/asm/smp_plat.h
@@ -0,0 +1,110 @@
+/*
+ * ARM specific SMP header, this contains our implementation
+ * details.
+ */
+#ifndef __ASMARM_SMP_PLAT_H
+#define __ASMARM_SMP_PLAT_H
+
+#include <linux/cpumask.h>
+#include <linux/err.h>
+
+#include <asm/cpu.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
+}
+
+/**
+ * smp_cpuid_part() - return part id for a given cpu
+ * @cpu: logical cpu id.
+ *
+ * Return: part id of logical cpu passed as argument.
+ */
+static inline unsigned int smp_cpuid_part(int cpu)
+{
+ struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpu);
+
+ return is_smp() ? cpu_info->cpuid & ARM_CPU_PART_MASK :
+ read_cpuid_part();
+}
+
+/* all SMP configurations have the extended CPUID registers */
+#ifndef CONFIG_MMU
+#define tlb_ops_need_broadcast() 0
+#else
+static inline int tlb_ops_need_broadcast(void)
+{
+ if (!is_smp())
+ return 0;
+
+ return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
+}
+#endif
+
+#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
+
+/*
+ * Logical CPU mapping.
+ */
+extern u32 __cpu_logical_map[];
+#define cpu_logical_map(cpu) __cpu_logical_map[cpu]
+/*
+ * Retrieve logical cpu index corresponding to a given MPIDR[23:0]
+ * - mpidr: MPIDR[23:0] to be used for the look-up
+ *
+ * Returns the cpu logical index or -EINVAL on look-up error
+ */
+static inline int get_logical_index(u32 mpidr)
+{
+ int cpu;
+ for (cpu = 0; cpu < nr_cpu_ids; cpu++)
+ if (cpu_logical_map(cpu) == mpidr)
+ return cpu;
+ return -EINVAL;
+}
+
+/*
+ * NOTE ! Assembly code relies on the following
+ * structure memory layout in order to carry out load
+ * multiple from its base address. For more
+ * information check arch/arm/kernel/sleep.S
+ */
+struct mpidr_hash {
+ u32 mask; /* used by sleep.S */
+ u32 shift_aff[3]; /* used by sleep.S */
+ u32 bits;
+};
+
+extern struct mpidr_hash mpidr_hash;
+
+static inline u32 mpidr_hash_size(void)
+{
+ return 1 << mpidr_hash.bits;
+}
+
+extern int platform_can_secondary_boot(void);
+extern int platform_can_cpu_hotplug(void);
+
+#endif
diff --git a/arch/arm/include/asm/smp_scu.h b/arch/arm/include/asm/smp_scu.h
new file mode 100644
index 000000000..bfe163c40
--- /dev/null
+++ b/arch/arm/include/asm/smp_scu.h
@@ -0,0 +1,48 @@
+#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__
+
+#include <asm/cputype.h>
+
+static inline bool scu_a9_has_base(void)
+{
+ return read_cpuid_part() == ARM_CPU_PART_CORTEX_A9;
+}
+
+static inline unsigned long scu_a9_get_base(void)
+{
+ unsigned long pa;
+
+ asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (pa));
+
+ return pa;
+}
+
+#ifdef CONFIG_HAVE_ARM_SCU
+unsigned int scu_get_core_count(void __iomem *);
+int scu_power_mode(void __iomem *, unsigned int);
+#else
+static inline unsigned int scu_get_core_count(void __iomem *scu_base)
+{
+ return 0;
+}
+static inline int scu_power_mode(void __iomem *scu_base, unsigned int mode)
+{
+ return -EINVAL;
+}
+#endif
+
+#if defined(CONFIG_SMP) && defined(CONFIG_HAVE_ARM_SCU)
+void scu_enable(void __iomem *scu_base);
+#else
+static inline void scu_enable(void __iomem *scu_base) {}
+#endif
+
+#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 000000000..7b2899c2f
--- /dev/null
+++ b/arch/arm/include/asm/smp_twd.h
@@ -0,0 +1,37 @@
+#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)
+
+#include <linux/ioport.h>
+
+struct twd_local_timer {
+ struct resource res[2];
+};
+
+#define DEFINE_TWD_LOCAL_TIMER(name,base,irq) \
+struct twd_local_timer name __initdata = { \
+ .res = { \
+ DEFINE_RES_MEM(base, 0x10), \
+ DEFINE_RES_IRQ(irq), \
+ }, \
+};
+
+int twd_local_timer_register(struct twd_local_timer *);
+
+#endif
diff --git a/arch/arm/include/asm/sparsemem.h b/arch/arm/include/asm/sparsemem.h
new file mode 100644
index 000000000..00098615c
--- /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 000000000..0fa418463
--- /dev/null
+++ b/arch/arm/include/asm/spinlock.h
@@ -0,0 +1,287 @@
+#ifndef __ASM_SPINLOCK_H
+#define __ASM_SPINLOCK_H
+
+#if __LINUX_ARM_ARCH__ < 6
+#error SMP not supported on pre-ARMv6 CPUs
+#endif
+
+#include <linux/prefetch.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.
+ */
+#ifdef CONFIG_THUMB2_KERNEL
+/*
+ * 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_ASM( \
+ "it " cond "\n\t" \
+ "wfe" cond ".n", \
+ \
+ "nop.w" \
+)
+#else
+#define WFE(cond) __ALT_SMP_ASM("wfe" cond, "nop")
+#endif
+
+#define SEV __ALT_SMP_ASM(WASM(sev), WASM(nop))
+
+static inline void dsb_sev(void)
+{
+
+ dsb(ishst);
+ __asm__(SEV);
+}
+
+/*
+ * ARMv6 ticket-based spin-locking.
+ *
+ * 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.
+ */
+
+#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;
+ u32 newval;
+ arch_spinlock_t lockval;
+
+ prefetchw(&lock->slock);
+ __asm__ __volatile__(
+"1: ldrex %0, [%3]\n"
+" add %1, %0, %4\n"
+" strex %2, %1, [%3]\n"
+" teq %2, #0\n"
+" bne 1b"
+ : "=&r" (lockval), "=&r" (newval), "=&r" (tmp)
+ : "r" (&lock->slock), "I" (1 << TICKET_SHIFT)
+ : "cc");
+
+ while (lockval.tickets.next != lockval.tickets.owner) {
+ wfe();
+ lockval.tickets.owner = ACCESS_ONCE(lock->tickets.owner);
+ }
+
+ smp_mb();
+}
+
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
+{
+ unsigned long contended, res;
+ u32 slock;
+
+ prefetchw(&lock->slock);
+ do {
+ __asm__ __volatile__(
+ " ldrex %0, [%3]\n"
+ " mov %2, #0\n"
+ " subs %1, %0, %0, ror #16\n"
+ " addeq %0, %0, %4\n"
+ " strexeq %2, %0, [%3]"
+ : "=&r" (slock), "=&r" (contended), "=&r" (res)
+ : "r" (&lock->slock), "I" (1 << TICKET_SHIFT)
+ : "cc");
+ } while (res);
+
+ if (!contended) {
+ smp_mb();
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
+{
+ smp_mb();
+ lock->tickets.owner++;
+ dsb_sev();
+}
+
+static inline int arch_spin_value_unlocked(arch_spinlock_t lock)
+{
+ return lock.tickets.owner == lock.tickets.next;
+}
+
+static inline int arch_spin_is_locked(arch_spinlock_t *lock)
+{
+ return !arch_spin_value_unlocked(READ_ONCE(*lock));
+}
+
+static inline int arch_spin_is_contended(arch_spinlock_t *lock)
+{
+ struct __raw_tickets tickets = READ_ONCE(lock->tickets);
+ return (tickets.next - tickets.owner) > 1;
+}
+#define arch_spin_is_contended arch_spin_is_contended
+
+/*
+ * 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;
+
+ prefetchw(&rw->lock);
+ __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 contended, res;
+
+ prefetchw(&rw->lock);
+ do {
+ __asm__ __volatile__(
+ " ldrex %0, [%2]\n"
+ " mov %1, #0\n"
+ " teq %0, #0\n"
+ " strexeq %1, %3, [%2]"
+ : "=&r" (contended), "=&r" (res)
+ : "r" (&rw->lock), "r" (0x80000000)
+ : "cc");
+ } while (res);
+
+ if (!contended) {
+ 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) (ACCESS_ONCE((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;
+
+ prefetchw(&rw->lock);
+ __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();
+
+ prefetchw(&rw->lock);
+ __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 contended, res;
+
+ prefetchw(&rw->lock);
+ do {
+ __asm__ __volatile__(
+ " ldrex %0, [%2]\n"
+ " mov %1, #0\n"
+ " adds %0, %0, #1\n"
+ " strexpl %1, %0, [%2]"
+ : "=&r" (contended), "=&r" (res)
+ : "r" (&rw->lock)
+ : "cc");
+ } while (res);
+
+ /* If the lock is negative, then it is already held for write. */
+ if (contended < 0x80000000) {
+ smp_mb();
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/* read_can_lock - would read_trylock() succeed? */
+#define arch_read_can_lock(x) (ACCESS_ONCE((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 000000000..47663fcb1
--- /dev/null
+++ b/arch/arm/include/asm/spinlock_types.h
@@ -0,0 +1,33 @@
+#ifndef __ASM_SPINLOCK_TYPES_H
+#define __ASM_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+#define TICKET_SHIFT 16
+
+typedef struct {
+ union {
+ u32 slock;
+ struct __raw_tickets {
+#ifdef __ARMEB__
+ u16 next;
+ u16 owner;
+#else
+ u16 owner;
+ u16 next;
+#endif
+ } tickets;
+ };
+} arch_spinlock_t;
+
+#define __ARCH_SPIN_LOCK_UNLOCKED { { 0 } }
+
+typedef struct {
+ u32 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 000000000..de003327b
--- /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 000000000..7722201ea
--- /dev/null
+++ b/arch/arm/include/asm/stacktrace.h
@@ -0,0 +1,30 @@
+#ifndef __ASM_STACKTRACE_H
+#define __ASM_STACKTRACE_H
+
+#include <asm/ptrace.h>
+
+struct stackframe {
+ /*
+ * FP member should hold R7 when CONFIG_THUMB2_KERNEL is enabled
+ * and R11 otherwise.
+ */
+ unsigned long fp;
+ unsigned long sp;
+ unsigned long lr;
+ unsigned long pc;
+};
+
+static __always_inline
+void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe *frame)
+{
+ frame->fp = frame_pointer(regs);
+ frame->sp = regs->ARM_sp;
+ frame->lr = regs->ARM_lr;
+ frame->pc = regs->ARM_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/string.h b/arch/arm/include/asm/string.h
new file mode 100644
index 000000000..cf4f3aad0
--- /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/suspend.h b/arch/arm/include/asm/suspend.h
new file mode 100644
index 000000000..cd20029bc
--- /dev/null
+++ b/arch/arm/include/asm/suspend.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_ARM_SUSPEND_H
+#define __ASM_ARM_SUSPEND_H
+
+struct sleep_save_sp {
+ u32 *save_ptr_stash;
+ u32 save_ptr_stash_phys;
+};
+
+extern void cpu_resume(void);
+extern int cpu_suspend(unsigned long, int (*)(unsigned long));
+
+#endif
diff --git a/arch/arm/include/asm/swab.h b/arch/arm/include/asm/swab.h
new file mode 100644
index 000000000..537fc9b91
--- /dev/null
+++ b/arch/arm/include/asm/swab.h
@@ -0,0 +1,38 @@
+/*
+ * 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 <uapi/asm/swab.h>
+
+#if __LINUX_ARM_ARCH__ >= 6
+
+static inline __attribute_const__ __u32 __arch_swahb32(__u32 x)
+{
+ __asm__ ("rev16 %0, %1" : "=r" (x) : "r" (x));
+ return x;
+}
+#define __arch_swahb32 __arch_swahb32
+#define __arch_swab16(x) ((__u16)__arch_swahb32(x))
+
+static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
+{
+ __asm__ ("rev %0, %1" : "=r" (x) : "r" (x));
+ return x;
+}
+#define __arch_swab32 __arch_swab32
+
+#endif
+#endif
diff --git a/arch/arm/include/asm/switch_to.h b/arch/arm/include/asm/switch_to.h
new file mode 100644
index 000000000..c99e25946
--- /dev/null
+++ b/arch/arm/include/asm/switch_to.h
@@ -0,0 +1,28 @@
+#ifndef __ASM_ARM_SWITCH_TO_H
+#define __ASM_ARM_SWITCH_TO_H
+
+#include <linux/thread_info.h>
+
+/*
+ * For v7 SMP cores running a preemptible kernel we may be pre-empted
+ * during a TLB maintenance operation, so execute an inner-shareable dsb
+ * to ensure that the maintenance completes in case we migrate to another
+ * CPU.
+ */
+#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP) && defined(CONFIG_CPU_V7)
+#define finish_arch_switch(prev) dsb(ish)
+#endif
+
+/*
+ * 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)
+
+#endif /* __ASM_ARM_SWITCH_TO_H */
diff --git a/arch/arm/include/asm/sync_bitops.h b/arch/arm/include/asm/sync_bitops.h
new file mode 100644
index 000000000..9732b8e11
--- /dev/null
+++ b/arch/arm/include/asm/sync_bitops.h
@@ -0,0 +1,26 @@
+#ifndef __ASM_SYNC_BITOPS_H__
+#define __ASM_SYNC_BITOPS_H__
+
+#include <asm/bitops.h>
+
+/* sync_bitops functions are equivalent to the SMP implementation of the
+ * original functions, independently from CONFIG_SMP being defined.
+ *
+ * We need them because _set_bit etc are not SMP safe if !CONFIG_SMP. But
+ * under Xen you might be communicating with a completely external entity
+ * who might be on another CPU (e.g. two uniprocessor guests communicating
+ * via event channels and grant tables). So we need a variant of the bit
+ * ops which are SMP safe even on a UP kernel.
+ */
+
+#define sync_set_bit(nr, p) _set_bit(nr, p)
+#define sync_clear_bit(nr, p) _clear_bit(nr, p)
+#define sync_change_bit(nr, p) _change_bit(nr, p)
+#define sync_test_and_set_bit(nr, p) _test_and_set_bit(nr, p)
+#define sync_test_and_clear_bit(nr, p) _test_and_clear_bit(nr, p)
+#define sync_test_and_change_bit(nr, p) _test_and_change_bit(nr, p)
+#define sync_test_bit(nr, addr) test_bit(nr, addr)
+#define sync_cmpxchg cmpxchg
+
+
+#endif
diff --git a/arch/arm/include/asm/syscall.h b/arch/arm/include/asm/syscall.h
new file mode 100644
index 000000000..e86c985b8
--- /dev/null
+++ b/arch/arm/include/asm/syscall.h
@@ -0,0 +1,112 @@
+/*
+ * Access to user system call parameters and results
+ *
+ * See asm-generic/syscall.h for descriptions of what we must do here.
+ */
+
+#ifndef _ASM_ARM_SYSCALL_H
+#define _ASM_ARM_SYSCALL_H
+
+#include <uapi/linux/audit.h> /* for AUDIT_ARCH_* */
+#include <linux/elf.h> /* for ELF_EM */
+#include <linux/err.h>
+#include <linux/sched.h>
+
+#include <asm/unistd.h>
+
+#define NR_syscalls (__NR_syscalls)
+
+extern const unsigned long sys_call_table[];
+
+static inline int syscall_get_nr(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return task_thread_info(task)->syscall;
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ regs->ARM_r0 = regs->ARM_ORIG_r0;
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ unsigned long error = regs->ARM_r0;
+ return IS_ERR_VALUE(error) ? error : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return regs->ARM_r0;
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+ struct pt_regs *regs,
+ int error, long val)
+{
+ regs->ARM_r0 = (long) error ? error : val;
+}
+
+#define SYSCALL_MAX_ARGS 7
+
+static inline void syscall_get_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ unsigned long *args)
+{
+ if (n == 0)
+ return;
+
+ if (i + n > SYSCALL_MAX_ARGS) {
+ unsigned long *args_bad = args + SYSCALL_MAX_ARGS - i;
+ unsigned int n_bad = n + i - SYSCALL_MAX_ARGS;
+ pr_warn("%s called with max args %d, handling only %d\n",
+ __func__, i + n, SYSCALL_MAX_ARGS);
+ memset(args_bad, 0, n_bad * sizeof(args[0]));
+ n = SYSCALL_MAX_ARGS - i;
+ }
+
+ if (i == 0) {
+ args[0] = regs->ARM_ORIG_r0;
+ args++;
+ i++;
+ n--;
+ }
+
+ memcpy(args, &regs->ARM_r0 + i, n * sizeof(args[0]));
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ const unsigned long *args)
+{
+ if (n == 0)
+ return;
+
+ if (i + n > SYSCALL_MAX_ARGS) {
+ pr_warn("%s called with max args %d, handling only %d\n",
+ __func__, i + n, SYSCALL_MAX_ARGS);
+ n = SYSCALL_MAX_ARGS - i;
+ }
+
+ if (i == 0) {
+ regs->ARM_ORIG_r0 = args[0];
+ args++;
+ i++;
+ n--;
+ }
+
+ memcpy(&regs->ARM_r0 + i, args, n * sizeof(args[0]));
+}
+
+static inline int syscall_get_arch(void)
+{
+ /* ARM tasks don't change audit architectures on the fly. */
+ return AUDIT_ARCH_ARM;
+}
+
+#endif /* _ASM_ARM_SYSCALL_H */
diff --git a/arch/arm/include/asm/system_info.h b/arch/arm/include/asm/system_info.h
new file mode 100644
index 000000000..720ea0320
--- /dev/null
+++ b/arch/arm/include/asm/system_info.h
@@ -0,0 +1,28 @@
+#ifndef __ASM_ARM_SYSTEM_INFO_H
+#define __ASM_ARM_SYSTEM_INFO_H
+
+#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
+#define CPU_ARCH_ARMv7M 10
+
+#ifndef __ASSEMBLY__
+
+/* 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;
+
+extern int __pure cpu_architecture(void);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_ARM_SYSTEM_INFO_H */
diff --git a/arch/arm/include/asm/system_misc.h b/arch/arm/include/asm/system_misc.h
new file mode 100644
index 000000000..a3d61ad98
--- /dev/null
+++ b/arch/arm/include/asm/system_misc.h
@@ -0,0 +1,27 @@
+#ifndef __ASM_ARM_SYSTEM_MISC_H
+#define __ASM_ARM_SYSTEM_MISC_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/compiler.h>
+#include <linux/linkage.h>
+#include <linux/irqflags.h>
+#include <linux/reboot.h>
+
+extern void cpu_init(void);
+
+void soft_restart(unsigned long);
+extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
+extern void (*arm_pm_idle)(void);
+
+#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;
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_ARM_SYSTEM_MISC_H */
diff --git a/arch/arm/include/asm/tcm.h b/arch/arm/include/asm/tcm.h
new file mode 100644
index 000000000..8578d726a
--- /dev/null
+++ b/arch/arm/include/asm/tcm.h
@@ -0,0 +1,33 @@
+/*
+ *
+ * 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);
+bool tcm_dtcm_present(void);
+bool tcm_itcm_present(void);
+
+#endif
diff --git a/arch/arm/include/asm/therm.h b/arch/arm/include/asm/therm.h
new file mode 100644
index 000000000..f002f0197
--- /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 000000000..bd32eded3
--- /dev/null
+++ b/arch/arm/include/asm/thread_info.h
@@ -0,0 +1,181 @@
+/*
+ * 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>
+#include <asm/page.h>
+
+#define THREAD_SIZE_ORDER 1
+#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
+#define THREAD_START_SP (THREAD_SIZE - 8)
+
+#ifndef __ASSEMBLY__
+
+struct task_struct;
+
+#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 */
+ __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[2]; /* TLS registers */
+#ifdef CONFIG_CRUNCH
+ struct crunch_state crunchstate;
+#endif
+ union fp_state fpstate __attribute__((aligned(8)));
+ union vfp_state vfpstate;
+#ifdef CONFIG_ARM_THUMBEE
+ unsigned long thumbee_state; /* ThumbEE Handler Base register */
+#endif
+};
+
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .task = &tsk, \
+ .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), \
+}
+
+#define init_thread_info (init_thread_union.thread_info)
+#define init_stack (init_thread_union.stack)
+
+/*
+ * how to get the current stack pointer in C
+ */
+register unsigned long current_stack_pointer asm ("sp");
+
+/*
+ * 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)
+{
+ return (struct thread_info *)
+ (current_stack_pointer & ~(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))
+
+#ifndef CONFIG_THUMB2_KERNEL
+#define thread_saved_fp(tsk) \
+ ((unsigned long)(task_thread_info(tsk)->cpu_context.fp))
+#else
+#define thread_saved_fp(tsk) \
+ ((unsigned long)(task_thread_info(tsk)->cpu_context.r7))
+#endif
+
+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 *);
+
+struct user_vfp;
+struct user_vfp_exc;
+
+extern int vfp_preserve_user_clear_hwstate(struct user_vfp __user *,
+ struct user_vfp_exc __user *);
+extern int vfp_restore_user_hwstate(struct user_vfp __user *,
+ struct user_vfp_exc __user *);
+#endif
+
+/*
+ * thread information flags:
+ * TIF_SYSCALL_TRACE - syscall trace active
+ * TIF_SYSCAL_AUDIT - syscall auditing 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_UPROBE 7
+#define TIF_SYSCALL_TRACE 8
+#define TIF_SYSCALL_AUDIT 9
+#define TIF_SYSCALL_TRACEPOINT 10
+#define TIF_SECCOMP 11 /* seccomp syscall filtering active */
+#define TIF_NOHZ 12 /* in adaptive nohz mode */
+#define TIF_USING_IWMMXT 17
+#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
+#define TIF_RESTORE_SIGMASK 20
+
+#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
+#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
+#define _TIF_UPROBE (1 << TIF_UPROBE)
+#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
+#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
+#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
+#define _TIF_SECCOMP (1 << TIF_SECCOMP)
+#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
+
+/* Checks for any syscall work in entry-common.S */
+#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
+ _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP)
+
+/*
+ * Change these and you break ASM code in entry-common.S
+ */
+#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
+ _TIF_NOTIFY_RESUME | _TIF_UPROBE)
+
+#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 000000000..1dc980675
--- /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 000000000..f6fcc67ef
--- /dev/null
+++ b/arch/arm/include/asm/timex.h
@@ -0,0 +1,18 @@
+/*
+ * 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
+
+typedef unsigned long cycles_t;
+#define get_cycles() ({ cycles_t c; read_current_timer(&c) ? 0 : c; })
+
+#endif
diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h
new file mode 100644
index 000000000..3cadb726e
--- /dev/null
+++ b/arch/arm/include/asm/tlb.h
@@ -0,0 +1,267 @@
+/*
+ * 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>
+
+#define MMU_GATHER_BUNDLE 8
+
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+static inline void __tlb_remove_table(void *_table)
+{
+ free_page_and_swap_cache((struct page *)_table);
+}
+
+struct mmu_table_batch {
+ struct rcu_head rcu;
+ unsigned int nr;
+ void *tables[0];
+};
+
+#define MAX_TABLE_BATCH \
+ ((PAGE_SIZE - sizeof(struct mmu_table_batch)) / sizeof(void *))
+
+extern void tlb_table_flush(struct mmu_gather *tlb);
+extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
+
+#define tlb_remove_entry(tlb, entry) tlb_remove_table(tlb, entry)
+#else
+#define tlb_remove_entry(tlb, entry) tlb_remove_page(tlb, entry)
+#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
+
+/*
+ * 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;
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+ struct mmu_table_batch *batch;
+ unsigned int need_flush;
+#endif
+ unsigned int fullmm;
+ struct vm_area_struct *vma;
+ unsigned long start, end;
+ 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_tlbonly(struct mmu_gather *tlb)
+{
+ tlb_flush(tlb);
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+ tlb_table_flush(tlb);
+#endif
+}
+
+static inline void tlb_flush_mmu_free(struct mmu_gather *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_flush_mmu(struct mmu_gather *tlb)
+{
+ tlb_flush_mmu_tlbonly(tlb);
+ tlb_flush_mmu_free(tlb);
+}
+
+static inline void
+tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
+{
+ tlb->mm = mm;
+ tlb->fullmm = !(start | (end+1));
+ tlb->start = start;
+ tlb->end = end;
+ tlb->vma = NULL;
+ tlb->max = ARRAY_SIZE(tlb->local);
+ tlb->pages = tlb->local;
+ tlb->nr = 0;
+ __tlb_alloc_page(tlb);
+
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+ tlb->batch = NULL;
+#endif
+}
+
+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)
+{
+ 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);
+
+#ifdef CONFIG_ARM_LPAE
+ tlb_add_flush(tlb, addr);
+#else
+ /*
+ * With the classic ARM MMU, a pte page has two corresponding pmd
+ * entries, each covering 1MB.
+ */
+ addr &= PMD_MASK;
+ tlb_add_flush(tlb, addr + SZ_1M - PAGE_SIZE);
+ tlb_add_flush(tlb, addr + SZ_1M);
+#endif
+
+ tlb_remove_entry(tlb, pte);
+}
+
+static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
+ unsigned long addr)
+{
+#ifdef CONFIG_ARM_LPAE
+ tlb_add_flush(tlb, addr);
+ tlb_remove_entry(tlb, virt_to_page(pmdp));
+#endif
+}
+
+static inline void
+tlb_remove_pmd_tlb_entry(struct mmu_gather *tlb, pmd_t *pmdp, unsigned long addr)
+{
+ tlb_add_flush(tlb, addr);
+}
+
+#define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr)
+#define pmd_free_tlb(tlb, pmdp, addr) __pmd_free_tlb(tlb, pmdp, addr)
+#define pud_free_tlb(tlb, pudp, addr) pud_free((tlb)->mm, pudp)
+
+#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 000000000..def9e5701
--- /dev/null
+++ b/arch/arm/include/asm/tlbflush.h
@@ -0,0 +1,686 @@
+/*
+ * 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_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_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_V6_BP (1 << 19)
+
+/* Unified Inner Shareable TLB operations (ARMv7 MP extensions) */
+#define TLB_V7_UIS_PAGE (1 << 20)
+#define TLB_V7_UIS_FULL (1 << 21)
+#define TLB_V7_UIS_ASID (1 << 22)
+#define TLB_V7_UIS_BP (1 << 23)
+
+#define TLB_BARRIER (1 << 28)
+#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:
+ * 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)
+ * 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 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_DCLEAN | TLB_BARRIER | \
+ 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_BARRIER | \
+ TLB_V6_I_FULL | TLB_V6_D_FULL | \
+ TLB_V6_I_PAGE | TLB_V6_D_PAGE | \
+ TLB_V6_I_ASID | TLB_V6_D_ASID | \
+ TLB_V6_BP)
+
+#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_BARRIER | \
+ TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | \
+ TLB_V7_UIS_ASID | TLB_V7_UIS_BP)
+#define v7wbi_tlb_flags_up (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \
+ TLB_V6_U_FULL | TLB_V6_U_PAGE | \
+ TLB_V6_U_ASID | TLB_V6_BP)
+
+#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 (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 (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)))
+
+#define __tlb_op(f, insnarg, arg) \
+ do { \
+ if (always_tlb_flags & (f)) \
+ asm("mcr " insnarg \
+ : : "r" (arg) : "cc"); \
+ else if (possible_tlb_flags & (f)) \
+ asm("tst %1, %2\n\t" \
+ "mcrne " insnarg \
+ : : "r" (arg), "r" (__tlb_flag), "Ir" (f) \
+ : "cc"); \
+ } while (0)
+
+#define tlb_op(f, regs, arg) __tlb_op(f, "p15, 0, %0, " regs, arg)
+#define tlb_l2_op(f, regs, arg) __tlb_op(f, "p15, 1, %0, " regs, arg)
+
+static inline void __local_flush_tlb_all(void)
+{
+ const int zero = 0;
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ tlb_op(TLB_V4_U_FULL | TLB_V6_U_FULL, "c8, c7, 0", zero);
+ tlb_op(TLB_V4_D_FULL | TLB_V6_D_FULL, "c8, c6, 0", zero);
+ tlb_op(TLB_V4_I_FULL | TLB_V6_I_FULL, "c8, c5, 0", zero);
+}
+
+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(nshst);
+
+ __local_flush_tlb_all();
+ tlb_op(TLB_V7_UIS_FULL, "c8, c7, 0", zero);
+
+ if (tlb_flag(TLB_BARRIER)) {
+ dsb(nsh);
+ isb();
+ }
+}
+
+static inline void __flush_tlb_all(void)
+{
+ const int zero = 0;
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ if (tlb_flag(TLB_WB))
+ dsb(ishst);
+
+ __local_flush_tlb_all();
+ tlb_op(TLB_V7_UIS_FULL, "c8, c3, 0", zero);
+
+ if (tlb_flag(TLB_BARRIER)) {
+ dsb(ish);
+ 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 (possible_tlb_flags & (TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) {
+ if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) {
+ tlb_op(TLB_V4_U_FULL, "c8, c7, 0", zero);
+ tlb_op(TLB_V4_D_FULL, "c8, c6, 0", zero);
+ tlb_op(TLB_V4_I_FULL, "c8, c5, 0", zero);
+ }
+ }
+
+ tlb_op(TLB_V6_U_ASID, "c8, c7, 2", asid);
+ tlb_op(TLB_V6_D_ASID, "c8, c6, 2", asid);
+ tlb_op(TLB_V6_I_ASID, "c8, c5, 2", asid);
+}
+
+static inline void local_flush_tlb_mm(struct mm_struct *mm)
+{
+ const int asid = ASID(mm);
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ if (tlb_flag(TLB_WB))
+ dsb(nshst);
+
+ __local_flush_tlb_mm(mm);
+ tlb_op(TLB_V7_UIS_ASID, "c8, c7, 2", asid);
+
+ if (tlb_flag(TLB_BARRIER))
+ dsb(nsh);
+}
+
+static inline void __flush_tlb_mm(struct mm_struct *mm)
+{
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ if (tlb_flag(TLB_WB))
+ dsb(ishst);
+
+ __local_flush_tlb_mm(mm);
+#ifdef CONFIG_ARM_ERRATA_720789
+ tlb_op(TLB_V7_UIS_ASID, "c8, c3, 0", 0);
+#else
+ tlb_op(TLB_V7_UIS_ASID, "c8, c3, 2", ASID(mm));
+#endif
+
+ if (tlb_flag(TLB_BARRIER))
+ dsb(ish);
+}
+
+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 (possible_tlb_flags & (TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) &&
+ cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
+ tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", uaddr);
+ tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", uaddr);
+ tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", uaddr);
+ if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
+ asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
+ }
+
+ tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", uaddr);
+ tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", uaddr);
+ tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", uaddr);
+}
+
+static inline void
+local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
+{
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm);
+
+ if (tlb_flag(TLB_WB))
+ dsb(nshst);
+
+ __local_flush_tlb_page(vma, uaddr);
+ tlb_op(TLB_V7_UIS_PAGE, "c8, c7, 1", uaddr);
+
+ if (tlb_flag(TLB_BARRIER))
+ dsb(nsh);
+}
+
+static inline void
+__flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
+{
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm);
+
+ if (tlb_flag(TLB_WB))
+ dsb(ishst);
+
+ __local_flush_tlb_page(vma, uaddr);
+#ifdef CONFIG_ARM_ERRATA_720789
+ tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 3", uaddr & PAGE_MASK);
+#else
+ tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 1", uaddr);
+#endif
+
+ if (tlb_flag(TLB_BARRIER))
+ dsb(ish);
+}
+
+static inline void __local_flush_tlb_kernel_page(unsigned long kaddr)
+{
+ const int zero = 0;
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", kaddr);
+ tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", kaddr);
+ tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", kaddr);
+ if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
+ asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
+
+ tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", kaddr);
+ tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", kaddr);
+ tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", kaddr);
+}
+
+static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
+{
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ kaddr &= PAGE_MASK;
+
+ if (tlb_flag(TLB_WB))
+ dsb(nshst);
+
+ __local_flush_tlb_kernel_page(kaddr);
+ tlb_op(TLB_V7_UIS_PAGE, "c8, c7, 1", kaddr);
+
+ if (tlb_flag(TLB_BARRIER)) {
+ dsb(nsh);
+ isb();
+ }
+}
+
+static inline void __flush_tlb_kernel_page(unsigned long kaddr)
+{
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ kaddr &= PAGE_MASK;
+
+ if (tlb_flag(TLB_WB))
+ dsb(ishst);
+
+ __local_flush_tlb_kernel_page(kaddr);
+ tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 1", kaddr);
+
+ if (tlb_flag(TLB_BARRIER)) {
+ dsb(ish);
+ isb();
+ }
+}
+
+/*
+ * Branch predictor maintenance is paired with full TLB invalidation, so
+ * there is no need for any barriers here.
+ */
+static inline void __local_flush_bp_all(void)
+{
+ const int zero = 0;
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ if (tlb_flag(TLB_V6_BP))
+ asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero));
+}
+
+static inline void local_flush_bp_all(void)
+{
+ const int zero = 0;
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ __local_flush_bp_all();
+ if (tlb_flag(TLB_V7_UIS_BP))
+ asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero));
+}
+
+static inline void __flush_bp_all(void)
+{
+ const int zero = 0;
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ __local_flush_bp_all();
+ if (tlb_flag(TLB_V7_UIS_BP))
+ asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero));
+}
+
+/*
+ * 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(void *pmd)
+{
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ tlb_op(TLB_DCLEAN, "c7, c10, 1 @ flush_pmd", pmd);
+ tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1 @ L2 flush_pmd", pmd);
+
+ if (tlb_flag(TLB_WB))
+ dsb(ishst);
+}
+
+static inline void clean_pmd_entry(void *pmd)
+{
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ tlb_op(TLB_DCLEAN, "c7, c10, 1 @ flush_pmd", pmd);
+ tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1 @ L2 flush_pmd", pmd);
+}
+
+#undef tlb_op
+#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
+#define flush_bp_all local_flush_bp_all
+#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);
+extern void flush_bp_all(void);
+#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
+
+#define update_mmu_cache_pmd(vma, address, pmd) do { } while (0)
+
+#endif
+
+#elif defined(CONFIG_SMP) /* !CONFIG_MMU */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/mm_types.h>
+
+static inline void local_flush_tlb_all(void) { }
+static inline void local_flush_tlb_mm(struct mm_struct *mm) { }
+static inline void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) { }
+static inline void local_flush_tlb_kernel_page(unsigned long kaddr) { }
+static inline void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { }
+static inline void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) { }
+static inline void local_flush_bp_all(void) { }
+
+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);
+extern void flush_bp_all(void);
+#endif /* __ASSEMBLY__ */
+
+#endif
+
+#ifndef __ASSEMBLY__
+#ifdef CONFIG_ARM_ERRATA_798181
+extern void erratum_a15_798181_init(void);
+#else
+static inline void erratum_a15_798181_init(void) {}
+#endif
+extern bool (*erratum_a15_798181_handler)(void);
+
+static inline bool erratum_a15_798181(void)
+{
+ if (unlikely(IS_ENABLED(CONFIG_ARM_ERRATA_798181) &&
+ erratum_a15_798181_handler))
+ return erratum_a15_798181_handler();
+ return false;
+}
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h
new file mode 100644
index 000000000..5f833f7ad
--- /dev/null
+++ b/arch/arm/include/asm/tls.h
@@ -0,0 +1,127 @@
+#ifndef __ASMARM_TLS_H
+#define __ASMARM_TLS_H
+
+#include <linux/compiler.h>
+#include <asm/thread_info.h>
+
+#ifdef __ASSEMBLY__
+#include <asm/asm-offsets.h>
+ .macro switch_tls_none, base, tp, tpuser, tmp1, tmp2
+ .endm
+
+ .macro switch_tls_v6k, base, tp, tpuser, tmp1, tmp2
+ mrc p15, 0, \tmp2, c13, c0, 2 @ get the user r/w register
+ mcr p15, 0, \tp, c13, c0, 3 @ set TLS register
+ mcr p15, 0, \tpuser, c13, c0, 2 @ and the user r/w register
+ str \tmp2, [\base, #TI_TP_VALUE + 4] @ save it
+ .endm
+
+ .macro switch_tls_v6, base, tp, tpuser, tmp1, tmp2
+ ldr \tmp1, =elf_hwcap
+ ldr \tmp1, [\tmp1, #0]
+ mov \tmp2, #0xffff0fff
+ tst \tmp1, #HWCAP_TLS @ hardware TLS available?
+ streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0
+ mrcne p15, 0, \tmp2, c13, c0, 2 @ get the user r/w register
+ mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register
+ mcrne p15, 0, \tpuser, c13, c0, 2 @ set user r/w register
+ strne \tmp2, [\base, #TI_TP_VALUE + 4] @ save it
+ .endm
+
+ .macro switch_tls_software, base, tp, tpuser, 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 switch_tls switch_tls_none
+#elif defined(CONFIG_CPU_V6)
+#define tls_emu 0
+#define has_tls_reg (elf_hwcap & HWCAP_TLS)
+#define switch_tls switch_tls_v6
+#elif defined(CONFIG_CPU_32v6K)
+#define tls_emu 0
+#define has_tls_reg 1
+#define switch_tls switch_tls_v6k
+#else
+#define tls_emu 0
+#define has_tls_reg 0
+#define switch_tls switch_tls_software
+#endif
+
+#ifndef __ASSEMBLY__
+
+static inline void set_tls(unsigned long val)
+{
+ struct thread_info *thread;
+
+ thread = current_thread_info();
+
+ thread->tp_value[0] = val;
+
+ /*
+ * This code runs with preemption enabled and therefore must
+ * be reentrant with respect to switch_tls.
+ *
+ * We need to ensure ordering between the shadow state and the
+ * hardware state, so that we don't corrupt the hardware state
+ * with a stale shadow state during context switch.
+ *
+ * If we're preempted here, switch_tls will load TPIDRURO from
+ * thread_info upon resuming execution and the following mcr
+ * is merely redundant.
+ */
+ barrier();
+
+ if (!tls_emu) {
+ if (has_tls_reg) {
+ asm("mcr p15, 0, %0, c13, c0, 3"
+ : : "r" (val));
+ } else {
+#ifdef CONFIG_KUSER_HELPERS
+ /*
+ * 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) = val;
+#endif
+ }
+
+ }
+}
+
+static inline unsigned long get_tpuser(void)
+{
+ unsigned long reg = 0;
+
+ if (has_tls_reg && !tls_emu)
+ __asm__("mrc p15, 0, %0, c13, c0, 2" : "=r" (reg));
+
+ return reg;
+}
+
+static inline void set_tpuser(unsigned long val)
+{
+ /* Since TPIDRURW is fully context-switched (unlike TPIDRURO),
+ * we need not update thread_info.
+ */
+ if (has_tls_reg && !tls_emu) {
+ asm("mcr p15, 0, %0, c13, c0, 2"
+ : : "r" (val));
+ }
+}
+
+static inline void flush_tls(void)
+{
+ set_tls(0);
+ set_tpuser(0);
+}
+
+#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 000000000..2fe85fff5
--- /dev/null
+++ b/arch/arm/include/asm/topology.h
@@ -0,0 +1,36 @@
+#ifndef _ASM_ARM_TOPOLOGY_H
+#define _ASM_ARM_TOPOLOGY_H
+
+#ifdef CONFIG_ARM_CPU_TOPOLOGY
+
+#include <linux/cpumask.h>
+
+struct cputopo_arm {
+ int thread_id;
+ int core_id;
+ int socket_id;
+ cpumask_t thread_sibling;
+ cpumask_t core_sibling;
+};
+
+extern struct cputopo_arm cpu_topology[NR_CPUS];
+
+#define topology_physical_package_id(cpu) (cpu_topology[cpu].socket_id)
+#define topology_core_id(cpu) (cpu_topology[cpu].core_id)
+#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling)
+#define topology_thread_cpumask(cpu) (&cpu_topology[cpu].thread_sibling)
+
+void init_cpu_topology(void);
+void store_cpu_topology(unsigned int cpuid);
+const struct cpumask *cpu_coregroup_mask(int cpu);
+
+#else
+
+static inline void init_cpu_topology(void) { }
+static inline void store_cpu_topology(unsigned int cpuid) { }
+
+#endif
+
+#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 000000000..f555bb366
--- /dev/null
+++ b/arch/arm/include/asm/traps.h
@@ -0,0 +1,55 @@
+#ifndef _ASMARM_TRAP_H
+#define _ASMARM_TRAP_H
+
+#include <linux/list.h>
+
+struct pt_regs;
+struct task_struct;
+
+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/trusted_foundations.h b/arch/arm/include/asm/trusted_foundations.h
new file mode 100644
index 000000000..624e1d436
--- /dev/null
+++ b/arch/arm/include/asm/trusted_foundations.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+/*
+ * Support for the Trusted Foundations secure monitor.
+ *
+ * Trusted Foundation comes active on some ARM consumer devices (most
+ * Tegra-based devices sold on the market are concerned). Such devices can only
+ * perform some basic operations, like setting the CPU reset vector, through
+ * SMC calls to the secure monitor. The calls are completely specific to
+ * Trusted Foundations, and do *not* follow the SMC calling convention or the
+ * PSCI standard.
+ */
+
+#ifndef __ASM_ARM_TRUSTED_FOUNDATIONS_H
+#define __ASM_ARM_TRUSTED_FOUNDATIONS_H
+
+#include <linux/kconfig.h>
+#include <linux/printk.h>
+#include <linux/bug.h>
+#include <linux/of.h>
+#include <linux/cpu.h>
+#include <linux/smp.h>
+
+struct trusted_foundations_platform_data {
+ unsigned int version_major;
+ unsigned int version_minor;
+};
+
+#if IS_ENABLED(CONFIG_TRUSTED_FOUNDATIONS)
+
+void register_trusted_foundations(struct trusted_foundations_platform_data *pd);
+void of_register_trusted_foundations(void);
+
+#else /* CONFIG_TRUSTED_FOUNDATIONS */
+
+static inline void register_trusted_foundations(
+ struct trusted_foundations_platform_data *pd)
+{
+ /*
+ * If the system requires TF and we cannot provide it, continue booting
+ * but disable features that cannot be provided.
+ */
+ pr_err("No support for Trusted Foundations, continuing in degraded mode.\n");
+ pr_err("Secondary processors as well as CPU PM will be disabled.\n");
+#if IS_ENABLED(CONFIG_SMP)
+ setup_max_cpus = 0;
+#endif
+ cpu_idle_poll_ctrl(true);
+}
+
+static inline void of_register_trusted_foundations(void)
+{
+ /*
+ * If we find the target should enable TF but does not support it,
+ * fail as the system won't be able to do much anyway
+ */
+ if (of_find_compatible_node(NULL, NULL, "tlm,trusted-foundations"))
+ register_trusted_foundations(NULL);
+}
+#endif /* CONFIG_TRUSTED_FOUNDATIONS */
+
+#endif
diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h
new file mode 100644
index 000000000..a53cdb8f0
--- /dev/null
+++ b/arch/arm/include/asm/types.h
@@ -0,0 +1,40 @@
+#ifndef _ASM_TYPES_H
+#define _ASM_TYPES_H
+
+#include <asm-generic/int-ll64.h>
+
+/*
+ * The C99 types uintXX_t that are usually defined in 'stdint.h' are not as
+ * unambiguous on ARM as you would expect. For the types below, there is a
+ * difference on ARM between GCC built for bare metal ARM, GCC built for glibc
+ * and the kernel itself, which results in build errors if you try to build with
+ * -ffreestanding and include 'stdint.h' (such as when you include 'arm_neon.h'
+ * in order to use NEON intrinsics)
+ *
+ * As the typedefs for these types in 'stdint.h' are based on builtin defines
+ * supplied by GCC, we can tweak these to align with the kernel's idea of those
+ * types, so 'linux/types.h' and 'stdint.h' can be safely included from the same
+ * source file (provided that -ffreestanding is used).
+ *
+ * int32_t uint32_t uintptr_t
+ * bare metal GCC long unsigned long unsigned int
+ * glibc GCC int unsigned int unsigned int
+ * kernel int unsigned int unsigned long
+ */
+
+#ifdef __INT32_TYPE__
+#undef __INT32_TYPE__
+#define __INT32_TYPE__ int
+#endif
+
+#ifdef __UINT32_TYPE__
+#undef __UINT32_TYPE__
+#define __UINT32_TYPE__ unsigned int
+#endif
+
+#ifdef __UINTPTR_TYPE__
+#undef __UINTPTR_TYPE__
+#define __UINTPTR_TYPE__ unsigned long
+#endif
+
+#endif /* _ASM_TYPES_H */
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
new file mode 100644
index 000000000..74b17d09e
--- /dev/null
+++ b/arch/arm/include/asm/uaccess.h
@@ -0,0 +1,519 @@
+/*
+ * 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/unified.h>
+#include <asm/compiler.h>
+
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+#include <asm-generic/uaccess-unaligned.h>
+#else
+#define __get_user_unaligned __get_user
+#define __put_user_unaligned __put_user
+#endif
+
+#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 *);
+extern int __get_user_32t_8(void *);
+extern int __get_user_8(void *);
+extern int __get_user_64t_1(void *);
+extern int __get_user_64t_2(void *);
+extern int __get_user_64t_4(void *);
+
+#define __GUP_CLOBBER_1 "lr", "cc"
+#ifdef CONFIG_CPU_USE_DOMAINS
+#define __GUP_CLOBBER_2 "ip", "lr", "cc"
+#else
+#define __GUP_CLOBBER_2 "lr", "cc"
+#endif
+#define __GUP_CLOBBER_4 "lr", "cc"
+#define __GUP_CLOBBER_32t_8 "lr", "cc"
+#define __GUP_CLOBBER_8 "lr", "cc"
+
+#define __get_user_x(__r2, __p, __e, __l, __s) \
+ __asm__ __volatile__ ( \
+ __asmeq("%0", "r0") __asmeq("%1", "r2") \
+ __asmeq("%3", "r1") \
+ "bl __get_user_" #__s \
+ : "=&r" (__e), "=r" (__r2) \
+ : "0" (__p), "r" (__l) \
+ : __GUP_CLOBBER_##__s)
+
+/* narrowing a double-word get into a single 32bit word register: */
+#ifdef __ARMEB__
+#define __get_user_x_32t(__r2, __p, __e, __l, __s) \
+ __get_user_x(__r2, __p, __e, __l, 32t_8)
+#else
+#define __get_user_x_32t __get_user_x
+#endif
+
+/*
+ * storing result into proper least significant word of 64bit target var,
+ * different only for big endian case where 64 bit __r2 lsw is r3:
+ */
+#ifdef __ARMEB__
+#define __get_user_x_64t(__r2, __p, __e, __l, __s) \
+ __asm__ __volatile__ ( \
+ __asmeq("%0", "r0") __asmeq("%1", "r2") \
+ __asmeq("%3", "r1") \
+ "bl __get_user_64t_" #__s \
+ : "=&r" (__e), "=r" (__r2) \
+ : "0" (__p), "r" (__l) \
+ : __GUP_CLOBBER_##__s)
+#else
+#define __get_user_x_64t __get_user_x
+#endif
+
+
+#define __get_user_check(x, p) \
+ ({ \
+ unsigned long __limit = current_thread_info()->addr_limit - 1; \
+ register const typeof(*(p)) __user *__p asm("r0") = (p);\
+ register typeof(x) __r2 asm("r2"); \
+ register unsigned long __l asm("r1") = __limit; \
+ register int __e asm("r0"); \
+ switch (sizeof(*(__p))) { \
+ case 1: \
+ if (sizeof((x)) >= 8) \
+ __get_user_x_64t(__r2, __p, __e, __l, 1); \
+ else \
+ __get_user_x(__r2, __p, __e, __l, 1); \
+ break; \
+ case 2: \
+ if (sizeof((x)) >= 8) \
+ __get_user_x_64t(__r2, __p, __e, __l, 2); \
+ else \
+ __get_user_x(__r2, __p, __e, __l, 2); \
+ break; \
+ case 4: \
+ if (sizeof((x)) >= 8) \
+ __get_user_x_64t(__r2, __p, __e, __l, 4); \
+ else \
+ __get_user_x(__r2, __p, __e, __l, 4); \
+ break; \
+ case 8: \
+ if (sizeof((x)) < 8) \
+ __get_user_x_32t(__r2, __p, __e, __l, 4); \
+ else \
+ __get_user_x(__r2, __p, __e, __l, 8); \
+ break; \
+ default: __e = __get_user_bad(); break; \
+ } \
+ x = (typeof(*(p))) __r2; \
+ __e; \
+ })
+
+#define get_user(x, p) \
+ ({ \
+ might_fault(); \
+ __get_user_check(x, p); \
+ })
+
+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, __l, __s) \
+ __asm__ __volatile__ ( \
+ __asmeq("%0", "r0") __asmeq("%2", "r2") \
+ __asmeq("%3", "r1") \
+ "bl __put_user_" #__s \
+ : "=&r" (__e) \
+ : "0" (__p), "r" (__r2), "r" (__l) \
+ : "ip", "lr", "cc")
+
+#define __put_user_check(x, p) \
+ ({ \
+ unsigned long __limit = current_thread_info()->addr_limit - 1; \
+ const typeof(*(p)) __user *__tmp_p = (p); \
+ register const typeof(*(p)) __r2 asm("r2") = (x); \
+ register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \
+ register unsigned long __l asm("r1") = __limit; \
+ register int __e asm("r0"); \
+ switch (sizeof(*(__p))) { \
+ case 1: \
+ __put_user_x(__r2, __p, __e, __l, 1); \
+ break; \
+ case 2: \
+ __put_user_x(__r2, __p, __e, __l, 2); \
+ break; \
+ case 4: \
+ __put_user_x(__r2, __p, __e, __l, 4); \
+ break; \
+ case 8: \
+ __put_user_x(__r2, __p, __e, __l, 8); \
+ break; \
+ default: __e = __put_user_bad(); break; \
+ } \
+ __e; \
+ })
+
+#define put_user(x, p) \
+ ({ \
+ might_fault(); \
+ __put_user_check(x, p); \
+ })
+
+#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) ((void)(addr), 1)
+#define __range_ok(addr, size) ((void)(addr), 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)
+
+#define user_addr_max() \
+ (segment_eq(get_fs(), KERNEL_DS) ? ~0UL : get_fs())
+
+/*
+ * 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); \
+ might_fault(); \
+ 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 .text.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 .text.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); \
+ might_fault(); \
+ 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 .text.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 = (__force 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 = (__force 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 .text.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 .text.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
+
+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;
+}
+
+extern long strncpy_from_user(char *dest, const char __user *src, long count);
+
+extern __must_check long strlen_user(const char __user *str);
+extern __must_check long strnlen_user(const char __user *str, long n);
+
+#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 000000000..14749aec9
--- /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/unified.h b/arch/arm/include/asm/unified.h
new file mode 100644
index 000000000..200f9a7cd
--- /dev/null
+++ b/arch/arm/include/asm/unified.h
@@ -0,0 +1,142 @@
+/*
+ * 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_CPU_V7M
+#define AR_CLASS(x...)
+#define M_CLASS(x...) x
+#else
+#define AR_CLASS(x...) x
+#define M_CLASS(x...)
+#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
+#define BSYM(sym) sym + 1
+#else
+#define WASM(instr) #instr ".w"
+#endif
+
+#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
+#define BSYM(sym) sym
+#else
+#define WASM(instr) #instr
+#endif
+
+#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 000000000..32640c431
--- /dev/null
+++ b/arch/arm/include/asm/unistd.h
@@ -0,0 +1,62 @@
+/*
+ * 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
+
+#include <uapi/asm/unistd.h>
+
+/*
+ * This may need to be greater than __NR_last_syscall+1 in order to
+ * account for the padding in the syscall table
+ */
+#define __NR_syscalls (388)
+
+/*
+ * *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.
+ */
+#define __ARM_NR_cmpxchg (__ARM_NR_BASE+0x00fff0)
+
+#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_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
+#define __ARCH_WANT_SYS_FORK
+#define __ARCH_WANT_SYS_VFORK
+#define __ARCH_WANT_SYS_CLONE
+
+/*
+ * Unimplemented (or alternatively implemented) syscalls
+ */
+#define __IGNORE_fadvise64_64
+#define __IGNORE_migrate_pages
+
+#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 000000000..d1c3f3a71
--- /dev/null
+++ b/arch/arm/include/asm/unwind.h
@@ -0,0 +1,61 @@
+/*
+ * 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_offset;
+ unsigned long insn;
+};
+
+struct unwind_table {
+ struct list_head list;
+ const struct unwind_idx *start;
+ const struct unwind_idx *origin;
+ const 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);
+
+#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/uprobes.h b/arch/arm/include/asm/uprobes.h
new file mode 100644
index 000000000..9472c20b7
--- /dev/null
+++ b/arch/arm/include/asm/uprobes.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2012 Rabin Vincent <rabin at rab.in>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _ASM_UPROBES_H
+#define _ASM_UPROBES_H
+
+#include <asm/probes.h>
+#include <asm/opcodes.h>
+
+typedef u32 uprobe_opcode_t;
+
+#define MAX_UINSN_BYTES 4
+#define UPROBE_XOL_SLOT_BYTES 64
+
+#define UPROBE_SWBP_ARM_INSN 0xe7f001f9
+#define UPROBE_SS_ARM_INSN 0xe7f001fa
+#define UPROBE_SWBP_INSN __opcode_to_mem_arm(UPROBE_SWBP_ARM_INSN)
+#define UPROBE_SWBP_INSN_SIZE 4
+
+struct arch_uprobe_task {
+ u32 backup;
+ unsigned long saved_trap_no;
+};
+
+struct arch_uprobe {
+ u8 insn[MAX_UINSN_BYTES];
+ unsigned long ixol[2];
+ uprobe_opcode_t bpinsn;
+ bool simulate;
+ u32 pcreg;
+ void (*prehandler)(struct arch_uprobe *auprobe,
+ struct arch_uprobe_task *autask,
+ struct pt_regs *regs);
+ void (*posthandler)(struct arch_uprobe *auprobe,
+ struct arch_uprobe_task *autask,
+ struct pt_regs *regs);
+ struct arch_probes_insn asi;
+};
+
+#endif
diff --git a/arch/arm/include/asm/user.h b/arch/arm/include/asm/user.h
new file mode 100644
index 000000000..35917b3a9
--- /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/v7m.h b/arch/arm/include/asm/v7m.h
new file mode 100644
index 000000000..615781c61
--- /dev/null
+++ b/arch/arm/include/asm/v7m.h
@@ -0,0 +1,56 @@
+/*
+ * Common defines for v7m cpus
+ */
+#define V7M_SCS_ICTR IOMEM(0xe000e004)
+#define V7M_SCS_ICTR_INTLINESNUM_MASK 0x0000000f
+
+#define BASEADDR_V7M_SCB IOMEM(0xe000ed00)
+
+#define V7M_SCB_CPUID 0x00
+
+#define V7M_SCB_ICSR 0x04
+#define V7M_SCB_ICSR_PENDSVSET (1 << 28)
+#define V7M_SCB_ICSR_PENDSVCLR (1 << 27)
+#define V7M_SCB_ICSR_RETTOBASE (1 << 11)
+
+#define V7M_SCB_VTOR 0x08
+
+#define V7M_SCB_AIRCR 0x0c
+#define V7M_SCB_AIRCR_VECTKEY (0x05fa << 16)
+#define V7M_SCB_AIRCR_SYSRESETREQ (1 << 2)
+
+#define V7M_SCB_SCR 0x10
+#define V7M_SCB_SCR_SLEEPDEEP (1 << 2)
+
+#define V7M_SCB_CCR 0x14
+#define V7M_SCB_CCR_STKALIGN (1 << 9)
+
+#define V7M_SCB_SHPR2 0x1c
+#define V7M_SCB_SHPR3 0x20
+
+#define V7M_SCB_SHCSR 0x24
+#define V7M_SCB_SHCSR_USGFAULTENA (1 << 18)
+#define V7M_SCB_SHCSR_BUSFAULTENA (1 << 17)
+#define V7M_SCB_SHCSR_MEMFAULTENA (1 << 16)
+
+#define V7M_xPSR_FRAMEPTRALIGN 0x00000200
+#define V7M_xPSR_EXCEPTIONNO 0x000001ff
+
+/*
+ * When branching to an address that has bits [31:28] == 0xf an exception return
+ * occurs. Bits [27:5] are reserved (SBOP). If the processor implements the FP
+ * extension Bit [4] defines if the exception frame has space allocated for FP
+ * state information, SBOP otherwise. Bit [3] defines the mode that is returned
+ * to (0 -> handler mode; 1 -> thread mode). Bit [2] defines which sp is used
+ * (0 -> msp; 1 -> psp). Bits [1:0] are fixed to 0b01.
+ */
+#define EXC_RET_STACK_MASK 0x00000004
+#define EXC_RET_THREADMODE_PROCESSSTACK 0xfffffffd
+
+#ifndef __ASSEMBLY__
+
+enum reboot_mode;
+
+void armv7m_restart(enum reboot_mode mode, const char *cmd);
+
+#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/vdso.h b/arch/arm/include/asm/vdso.h
new file mode 100644
index 000000000..d0295f1dd
--- /dev/null
+++ b/arch/arm/include/asm/vdso.h
@@ -0,0 +1,32 @@
+#ifndef __ASM_VDSO_H
+#define __ASM_VDSO_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+struct mm_struct;
+
+#ifdef CONFIG_VDSO
+
+void arm_install_vdso(struct mm_struct *mm, unsigned long addr);
+
+extern char vdso_start, vdso_end;
+
+extern unsigned int vdso_total_pages;
+
+#else /* CONFIG_VDSO */
+
+static inline void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
+{
+}
+
+#define vdso_total_pages 0
+
+#endif /* CONFIG_VDSO */
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_VDSO_H */
diff --git a/arch/arm/include/asm/vdso_datapage.h b/arch/arm/include/asm/vdso_datapage.h
new file mode 100644
index 000000000..9be259442
--- /dev/null
+++ b/arch/arm/include/asm/vdso_datapage.h
@@ -0,0 +1,60 @@
+/*
+ * Adapted from arm64 version.
+ *
+ * Copyright (C) 2012 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __ASM_VDSO_DATAPAGE_H
+#define __ASM_VDSO_DATAPAGE_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#include <asm/page.h>
+
+/* Try to be cache-friendly on systems that don't implement the
+ * generic timer: fit the unconditionally updated fields in the first
+ * 32 bytes.
+ */
+struct vdso_data {
+ u32 seq_count; /* sequence count - odd during updates */
+ u16 tk_is_cntvct; /* fall back to syscall if false */
+ u16 cs_shift; /* clocksource shift */
+ u32 xtime_coarse_sec; /* coarse time */
+ u32 xtime_coarse_nsec;
+
+ u32 wtm_clock_sec; /* wall to monotonic offset */
+ u32 wtm_clock_nsec;
+ u32 xtime_clock_sec; /* CLOCK_REALTIME - seconds */
+ u32 cs_mult; /* clocksource multiplier */
+
+ u64 cs_cycle_last; /* last cycle value */
+ u64 cs_mask; /* clocksource mask */
+
+ u64 xtime_clock_snsec; /* CLOCK_REALTIME sub-ns base */
+ u32 tz_minuteswest; /* timezone info for gettimeofday(2) */
+ u32 tz_dsttime;
+};
+
+union vdso_data_store {
+ struct vdso_data data;
+ u8 page[PAGE_SIZE];
+};
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_VDSO_DATAPAGE_H */
diff --git a/arch/arm/include/asm/vfp.h b/arch/arm/include/asm/vfp.h
new file mode 100644
index 000000000..ee5f30842
--- /dev/null
+++ b/arch/arm/include/asm/vfp.h
@@ -0,0 +1,89 @@
+/*
+ * 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_CPUID_ARCH_MASK (0x7F << 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)
+#define MVFR0_SP_BIT (4)
+#define MVFR0_SP_MASK (0xf << MVFR0_SP_BIT)
+#define MVFR0_DP_BIT (8)
+#define MVFR0_DP_MASK (0xf << MVFR0_DP_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 000000000..301c1db3e
--- /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 <asm/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_VFPD32
+ ldcnel p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31}
+ addeq \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_VFPD32
+ stcnel p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31}
+ addeq \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 000000000..91f40217b
--- /dev/null
+++ b/arch/arm/include/asm/vga.h
@@ -0,0 +1,13 @@
+#ifndef ASMARM_VGA_H
+#define ASMARM_VGA_H
+
+#include <linux/io.h>
+
+extern unsigned long vga_base;
+
+#define VGA_MAP_MEM(x,s) (vga_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/virt.h b/arch/arm/include/asm/virt.h
new file mode 100644
index 000000000..4371f45c5
--- /dev/null
+++ b/arch/arm/include/asm/virt.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2012 Linaro 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef VIRT_H
+#define VIRT_H
+
+#include <asm/ptrace.h>
+
+/*
+ * Flag indicating that the kernel was not entered in the same mode on every
+ * CPU. The zImage loader stashes this value in an SPSR, so we need an
+ * architecturally defined flag bit here.
+ */
+#define BOOT_CPU_MODE_MISMATCH PSR_N_BIT
+
+#ifndef __ASSEMBLY__
+#include <asm/cacheflush.h>
+
+#ifdef CONFIG_ARM_VIRT_EXT
+/*
+ * __boot_cpu_mode records what mode the primary CPU was booted in.
+ * A correctly-implemented bootloader must start all CPUs in the same mode:
+ * if it fails to do this, the flag BOOT_CPU_MODE_MISMATCH is set to indicate
+ * that some CPU(s) were booted in a different mode.
+ *
+ * This allows the kernel to flag an error when the secondaries have come up.
+ */
+extern int __boot_cpu_mode;
+
+static inline void sync_boot_mode(void)
+{
+ /*
+ * As secondaries write to __boot_cpu_mode with caches disabled, we
+ * must flush the corresponding cache entries to ensure the visibility
+ * of their writes.
+ */
+ sync_cache_r(&__boot_cpu_mode);
+}
+
+void __hyp_set_vectors(unsigned long phys_vector_base);
+unsigned long __hyp_get_vectors(void);
+#else
+#define __boot_cpu_mode (SVC_MODE)
+#define sync_boot_mode()
+#endif
+
+#ifndef ZIMAGE
+void hyp_mode_check(void);
+
+/* Reports the availability of HYP mode */
+static inline bool is_hyp_mode_available(void)
+{
+ return ((__boot_cpu_mode & MODE_MASK) == HYP_MODE &&
+ !(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH));
+}
+
+/* Check if the bootloader has booted CPUs in different modes */
+static inline bool is_hyp_mode_mismatched(void)
+{
+ return !!(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH);
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* ! VIRT_H */
diff --git a/arch/arm/include/asm/word-at-a-time.h b/arch/arm/include/asm/word-at-a-time.h
new file mode 100644
index 000000000..5831dce4b
--- /dev/null
+++ b/arch/arm/include/asm/word-at-a-time.h
@@ -0,0 +1,98 @@
+#ifndef __ASM_ARM_WORD_AT_A_TIME_H
+#define __ASM_ARM_WORD_AT_A_TIME_H
+
+#ifndef __ARMEB__
+
+/*
+ * Little-endian word-at-a-time zero byte handling.
+ * Heavily based on the x86 algorithm.
+ */
+#include <linux/kernel.h>
+
+struct word_at_a_time {
+ const unsigned long one_bits, high_bits;
+};
+
+#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) }
+
+static inline unsigned long has_zero(unsigned long a, unsigned long *bits,
+ const struct word_at_a_time *c)
+{
+ unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits;
+ *bits = mask;
+ return mask;
+}
+
+#define prep_zero_mask(a, bits, c) (bits)
+
+static inline unsigned long create_zero_mask(unsigned long bits)
+{
+ bits = (bits - 1) & ~bits;
+ return bits >> 7;
+}
+
+static inline unsigned long find_zero(unsigned long mask)
+{
+ unsigned long ret;
+
+#if __LINUX_ARM_ARCH__ >= 5
+ /* We have clz available. */
+ ret = fls(mask) >> 3;
+#else
+ /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */
+ ret = (0x0ff0001 + mask) >> 23;
+ /* Fix the 1 for 00 case */
+ ret &= mask;
+#endif
+
+ return ret;
+}
+
+#define zero_bytemask(mask) (mask)
+
+#else /* __ARMEB__ */
+#include <asm-generic/word-at-a-time.h>
+#endif
+
+#ifdef CONFIG_DCACHE_WORD_ACCESS
+
+/*
+ * Load an unaligned word from kernel space.
+ *
+ * In the (very unlikely) case of the word being a page-crosser
+ * and the next page not being mapped, take the exception and
+ * return zeroes in the non-existing part.
+ */
+static inline unsigned long load_unaligned_zeropad(const void *addr)
+{
+ unsigned long ret, offset;
+
+ /* Load word from unaligned pointer addr */
+ asm(
+ "1: ldr %0, [%2]\n"
+ "2:\n"
+ " .pushsection .text.fixup,\"ax\"\n"
+ " .align 2\n"
+ "3: and %1, %2, #0x3\n"
+ " bic %2, %2, #0x3\n"
+ " ldr %0, [%2]\n"
+ " lsl %1, %1, #0x3\n"
+#ifndef __ARMEB__
+ " lsr %0, %0, %1\n"
+#else
+ " lsl %0, %0, %1\n"
+#endif
+ " b 2b\n"
+ " .popsection\n"
+ " .pushsection __ex_table,\"a\"\n"
+ " .align 3\n"
+ " .long 1b, 3b\n"
+ " .popsection"
+ : "=&r" (ret), "=&r" (offset)
+ : "r" (addr), "Qo" (*(unsigned long *)addr));
+
+ return ret;
+}
+
+#endif /* DCACHE_WORD_ACCESS */
+#endif /* __ASM_ARM_WORD_AT_A_TIME_H */
diff --git a/arch/arm/include/asm/xen/events.h b/arch/arm/include/asm/xen/events.h
new file mode 100644
index 000000000..8b1f37bfe
--- /dev/null
+++ b/arch/arm/include/asm/xen/events.h
@@ -0,0 +1,23 @@
+#ifndef _ASM_ARM_XEN_EVENTS_H
+#define _ASM_ARM_XEN_EVENTS_H
+
+#include <asm/ptrace.h>
+#include <asm/atomic.h>
+
+enum ipi_vector {
+ XEN_PLACEHOLDER_VECTOR,
+
+ /* Xen IPIs go here */
+ XEN_NR_IPIS,
+};
+
+static inline int xen_irqs_disabled(struct pt_regs *regs)
+{
+ return raw_irqs_disabled_flags(regs->ARM_cpsr);
+}
+
+#define xchg_xen_ulong(ptr, val) atomic64_xchg(container_of((ptr), \
+ atomic64_t, \
+ counter), (val))
+
+#endif /* _ASM_ARM_XEN_EVENTS_H */
diff --git a/arch/arm/include/asm/xen/hypercall.h b/arch/arm/include/asm/xen/hypercall.h
new file mode 100644
index 000000000..712b50e0a
--- /dev/null
+++ b/arch/arm/include/asm/xen/hypercall.h
@@ -0,0 +1,77 @@
+/******************************************************************************
+ * hypercall.h
+ *
+ * Linux-specific hypervisor handling.
+ *
+ * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef _ASM_ARM_XEN_HYPERCALL_H
+#define _ASM_ARM_XEN_HYPERCALL_H
+
+#include <xen/interface/xen.h>
+#include <xen/interface/sched.h>
+
+long privcmd_call(unsigned call, unsigned long a1,
+ unsigned long a2, unsigned long a3,
+ unsigned long a4, unsigned long a5);
+int HYPERVISOR_xen_version(int cmd, void *arg);
+int HYPERVISOR_console_io(int cmd, int count, char *str);
+int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
+int HYPERVISOR_sched_op(int cmd, void *arg);
+int HYPERVISOR_event_channel_op(int cmd, void *arg);
+unsigned long HYPERVISOR_hvm_op(int op, void *arg);
+int HYPERVISOR_memory_op(unsigned int cmd, void *arg);
+int HYPERVISOR_physdev_op(int cmd, void *arg);
+int HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args);
+int HYPERVISOR_tmem_op(void *arg);
+int HYPERVISOR_multicall(struct multicall_entry *calls, uint32_t nr);
+
+static inline int
+HYPERVISOR_suspend(unsigned long start_info_mfn)
+{
+ struct sched_shutdown r = { .reason = SHUTDOWN_suspend };
+
+ /* start_info_mfn is unused on ARM */
+ return HYPERVISOR_sched_op(SCHEDOP_shutdown, &r);
+}
+
+static inline void
+MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va,
+ unsigned int new_val, unsigned long flags)
+{
+ BUG();
+}
+
+static inline void
+MULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req,
+ int count, int *success_count, domid_t domid)
+{
+ BUG();
+}
+
+#endif /* _ASM_ARM_XEN_HYPERCALL_H */
diff --git a/arch/arm/include/asm/xen/hypervisor.h b/arch/arm/include/asm/xen/hypervisor.h
new file mode 100644
index 000000000..1317ee40f
--- /dev/null
+++ b/arch/arm/include/asm/xen/hypervisor.h
@@ -0,0 +1,21 @@
+#ifndef _ASM_ARM_XEN_HYPERVISOR_H
+#define _ASM_ARM_XEN_HYPERVISOR_H
+
+extern struct shared_info *HYPERVISOR_shared_info;
+extern struct start_info *xen_start_info;
+
+/* Lazy mode for batching updates / context switch */
+enum paravirt_lazy_mode {
+ PARAVIRT_LAZY_NONE,
+ PARAVIRT_LAZY_MMU,
+ PARAVIRT_LAZY_CPU,
+};
+
+static inline enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
+{
+ return PARAVIRT_LAZY_NONE;
+}
+
+extern struct dma_map_ops *xen_dma_ops;
+
+#endif /* _ASM_ARM_XEN_HYPERVISOR_H */
diff --git a/arch/arm/include/asm/xen/interface.h b/arch/arm/include/asm/xen/interface.h
new file mode 100644
index 000000000..50066006e
--- /dev/null
+++ b/arch/arm/include/asm/xen/interface.h
@@ -0,0 +1,82 @@
+/******************************************************************************
+ * Guest OS interface to ARM Xen.
+ *
+ * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
+ */
+
+#ifndef _ASM_ARM_XEN_INTERFACE_H
+#define _ASM_ARM_XEN_INTERFACE_H
+
+#include <linux/types.h>
+
+#define uint64_aligned_t uint64_t __attribute__((aligned(8)))
+
+#define __DEFINE_GUEST_HANDLE(name, type) \
+ typedef struct { union { type *p; uint64_aligned_t q; }; } \
+ __guest_handle_ ## name
+
+#define DEFINE_GUEST_HANDLE_STRUCT(name) \
+ __DEFINE_GUEST_HANDLE(name, struct name)
+#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name)
+#define GUEST_HANDLE(name) __guest_handle_ ## name
+
+#define set_xen_guest_handle(hnd, val) \
+ do { \
+ if (sizeof(hnd) == 8) \
+ *(uint64_t *)&(hnd) = 0; \
+ (hnd).p = val; \
+ } while (0)
+
+#ifndef __ASSEMBLY__
+/* Explicitly size integers that represent pfns in the interface with
+ * Xen so that we can have one ABI that works for 32 and 64 bit guests.
+ * Note that this means that the xen_pfn_t type may be capable of
+ * representing pfn's which the guest cannot represent in its own pfn
+ * type. However since pfn space is controlled by the guest this is
+ * fine since it simply wouldn't be able to create any sure pfns in
+ * the first place.
+ */
+typedef uint64_t xen_pfn_t;
+#define PRI_xen_pfn "llx"
+typedef uint64_t xen_ulong_t;
+#define PRI_xen_ulong "llx"
+typedef int64_t xen_long_t;
+#define PRI_xen_long "llx"
+/* Guest handles for primitive C types. */
+__DEFINE_GUEST_HANDLE(uchar, unsigned char);
+__DEFINE_GUEST_HANDLE(uint, unsigned int);
+DEFINE_GUEST_HANDLE(char);
+DEFINE_GUEST_HANDLE(int);
+DEFINE_GUEST_HANDLE(void);
+DEFINE_GUEST_HANDLE(uint64_t);
+DEFINE_GUEST_HANDLE(uint32_t);
+DEFINE_GUEST_HANDLE(xen_pfn_t);
+DEFINE_GUEST_HANDLE(xen_ulong_t);
+
+/* Maximum number of virtual CPUs in multi-processor guests. */
+#define MAX_VIRT_CPUS 1
+
+struct arch_vcpu_info { };
+struct arch_shared_info { };
+
+/* TODO: Move pvclock definitions some place arch independent */
+struct pvclock_vcpu_time_info {
+ u32 version;
+ u32 pad0;
+ u64 tsc_timestamp;
+ u64 system_time;
+ u32 tsc_to_system_mul;
+ s8 tsc_shift;
+ u8 flags;
+ u8 pad[2];
+} __attribute__((__packed__)); /* 32 bytes */
+
+/* It is OK to have a 12 bytes struct with no padding because it is packed */
+struct pvclock_wall_clock {
+ u32 version;
+ u32 sec;
+ u32 nsec;
+} __attribute__((__packed__));
+#endif
+
+#endif /* _ASM_ARM_XEN_INTERFACE_H */
diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
new file mode 100644
index 000000000..efd562412
--- /dev/null
+++ b/arch/arm/include/asm/xen/page-coherent.h
@@ -0,0 +1,87 @@
+#ifndef _ASM_ARM_XEN_PAGE_COHERENT_H
+#define _ASM_ARM_XEN_PAGE_COHERENT_H
+
+#include <asm/page.h>
+#include <linux/dma-attrs.h>
+#include <linux/dma-mapping.h>
+
+void __xen_dma_map_page(struct device *hwdev, struct page *page,
+ dma_addr_t dev_addr, unsigned long offset, size_t size,
+ enum dma_data_direction dir, struct dma_attrs *attrs);
+void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs);
+void __xen_dma_sync_single_for_cpu(struct device *hwdev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir);
+
+void __xen_dma_sync_single_for_device(struct device *hwdev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir);
+
+static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flags,
+ struct dma_attrs *attrs)
+{
+ return __generic_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
+}
+
+static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
+ void *cpu_addr, dma_addr_t dma_handle,
+ struct dma_attrs *attrs)
+{
+ __generic_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
+}
+
+static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
+ dma_addr_t dev_addr, unsigned long offset, size_t size,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ bool local = PFN_DOWN(dev_addr) == page_to_pfn(page);
+ /* Dom0 is mapped 1:1, so if pfn == mfn the page is local otherwise
+ * is a foreign page grant-mapped in dom0. If the page is local we
+ * can safely call the native dma_ops function, otherwise we call
+ * the xen specific function. */
+ if (local)
+ __generic_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs);
+ else
+ __xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs);
+}
+
+static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ unsigned long pfn = PFN_DOWN(handle);
+ /* Dom0 is mapped 1:1, so calling pfn_valid on a foreign mfn will
+ * always return false. If the page is local we can safely call the
+ * native dma_ops function, otherwise we call the xen specific
+ * function. */
+ if (pfn_valid(pfn)) {
+ if (__generic_dma_ops(hwdev)->unmap_page)
+ __generic_dma_ops(hwdev)->unmap_page(hwdev, handle, size, dir, attrs);
+ } else
+ __xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
+}
+
+static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ unsigned long pfn = PFN_DOWN(handle);
+ if (pfn_valid(pfn)) {
+ if (__generic_dma_ops(hwdev)->sync_single_for_cpu)
+ __generic_dma_ops(hwdev)->sync_single_for_cpu(hwdev, handle, size, dir);
+ } else
+ __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
+}
+
+static inline void xen_dma_sync_single_for_device(struct device *hwdev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ unsigned long pfn = PFN_DOWN(handle);
+ if (pfn_valid(pfn)) {
+ if (__generic_dma_ops(hwdev)->sync_single_for_device)
+ __generic_dma_ops(hwdev)->sync_single_for_device(hwdev, handle, size, dir);
+ } else
+ __xen_dma_sync_single_for_device(hwdev, handle, size, dir);
+}
+
+#endif /* _ASM_ARM_XEN_PAGE_COHERENT_H */
diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
new file mode 100644
index 000000000..0b579b2f4
--- /dev/null
+++ b/arch/arm/include/asm/xen/page.h
@@ -0,0 +1,115 @@
+#ifndef _ASM_ARM_XEN_PAGE_H
+#define _ASM_ARM_XEN_PAGE_H
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include <linux/pfn.h>
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+
+#include <xen/xen.h>
+#include <xen/interface/grant_table.h>
+
+#define phys_to_machine_mapping_valid(pfn) (1)
+#define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT))
+
+#define pte_mfn pte_pfn
+#define mfn_pte pfn_pte
+
+/* Xen machine address */
+typedef struct xmaddr {
+ phys_addr_t maddr;
+} xmaddr_t;
+
+/* Xen pseudo-physical address */
+typedef struct xpaddr {
+ phys_addr_t paddr;
+} xpaddr_t;
+
+#define XMADDR(x) ((xmaddr_t) { .maddr = (x) })
+#define XPADDR(x) ((xpaddr_t) { .paddr = (x) })
+
+#define INVALID_P2M_ENTRY (~0UL)
+
+unsigned long __pfn_to_mfn(unsigned long pfn);
+extern struct rb_root phys_to_mach;
+
+static inline unsigned long pfn_to_mfn(unsigned long pfn)
+{
+ unsigned long mfn;
+
+ if (phys_to_mach.rb_node != NULL) {
+ mfn = __pfn_to_mfn(pfn);
+ if (mfn != INVALID_P2M_ENTRY)
+ return mfn;
+ }
+
+ return pfn;
+}
+
+static inline unsigned long mfn_to_pfn(unsigned long mfn)
+{
+ return mfn;
+}
+
+#define mfn_to_local_pfn(mfn) mfn_to_pfn(mfn)
+
+static inline xmaddr_t phys_to_machine(xpaddr_t phys)
+{
+ unsigned offset = phys.paddr & ~PAGE_MASK;
+ return XMADDR(PFN_PHYS(pfn_to_mfn(PFN_DOWN(phys.paddr))) | offset);
+}
+
+static inline xpaddr_t machine_to_phys(xmaddr_t machine)
+{
+ unsigned offset = machine.maddr & ~PAGE_MASK;
+ return XPADDR(PFN_PHYS(mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset);
+}
+/* VIRT <-> MACHINE conversion */
+#define virt_to_machine(v) (phys_to_machine(XPADDR(__pa(v))))
+#define virt_to_mfn(v) (pfn_to_mfn(virt_to_pfn(v)))
+#define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT))
+
+static inline xmaddr_t arbitrary_virt_to_machine(void *vaddr)
+{
+ /* TODO: assuming it is mapped in the kernel 1:1 */
+ return virt_to_machine(vaddr);
+}
+
+/* TODO: this shouldn't be here but it is because the frontend drivers
+ * are using it (its rolled in headers) even though we won't hit the code path.
+ * So for right now just punt with this.
+ */
+static inline pte_t *lookup_address(unsigned long address, unsigned int *level)
+{
+ BUG();
+ return NULL;
+}
+
+extern int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
+ struct gnttab_map_grant_ref *kmap_ops,
+ struct page **pages, unsigned int count);
+
+extern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
+ struct gnttab_unmap_grant_ref *kunmap_ops,
+ struct page **pages, unsigned int count);
+
+bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
+bool __set_phys_to_machine_multi(unsigned long pfn, unsigned long mfn,
+ unsigned long nr_pages);
+
+static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+{
+ return __set_phys_to_machine(pfn, mfn);
+}
+
+#define xen_remap(cookie, size) ioremap_cache((cookie), (size))
+#define xen_unmap(cookie) iounmap((cookie))
+
+bool xen_arch_need_swiotlb(struct device *dev,
+ unsigned long pfn,
+ unsigned long mfn);
+unsigned long xen_get_swiotlb_free_pages(unsigned int order);
+
+#endif /* _ASM_ARM_XEN_PAGE_H */
diff --git a/arch/arm/include/asm/xor.h b/arch/arm/include/asm/xor.h
new file mode 100644
index 000000000..4ffb26d4c
--- /dev/null
+++ b/arch/arm/include/asm/xor.h
@@ -0,0 +1,214 @@
+/*
+ * 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 <linux/hardirq.h>
+#include <asm-generic/xor.h>
+#include <asm/hwcap.h>
+#include <asm/neon.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); \
+ NEON_TEMPLATES; \
+ } while (0)
+
+#ifdef CONFIG_KERNEL_MODE_NEON
+
+extern struct xor_block_template const xor_block_neon_inner;
+
+static void
+xor_neon_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+{
+ if (in_interrupt()) {
+ xor_arm4regs_2(bytes, p1, p2);
+ } else {
+ kernel_neon_begin();
+ xor_block_neon_inner.do_2(bytes, p1, p2);
+ kernel_neon_end();
+ }
+}
+
+static void
+xor_neon_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+ unsigned long *p3)
+{
+ if (in_interrupt()) {
+ xor_arm4regs_3(bytes, p1, p2, p3);
+ } else {
+ kernel_neon_begin();
+ xor_block_neon_inner.do_3(bytes, p1, p2, p3);
+ kernel_neon_end();
+ }
+}
+
+static void
+xor_neon_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+ unsigned long *p3, unsigned long *p4)
+{
+ if (in_interrupt()) {
+ xor_arm4regs_4(bytes, p1, p2, p3, p4);
+ } else {
+ kernel_neon_begin();
+ xor_block_neon_inner.do_4(bytes, p1, p2, p3, p4);
+ kernel_neon_end();
+ }
+}
+
+static void
+xor_neon_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+ unsigned long *p3, unsigned long *p4, unsigned long *p5)
+{
+ if (in_interrupt()) {
+ xor_arm4regs_5(bytes, p1, p2, p3, p4, p5);
+ } else {
+ kernel_neon_begin();
+ xor_block_neon_inner.do_5(bytes, p1, p2, p3, p4, p5);
+ kernel_neon_end();
+ }
+}
+
+static struct xor_block_template xor_block_neon = {
+ .name = "neon",
+ .do_2 = xor_neon_2,
+ .do_3 = xor_neon_3,
+ .do_4 = xor_neon_4,
+ .do_5 = xor_neon_5
+};
+
+#define NEON_TEMPLATES \
+ do { if (cpu_has_neon()) xor_speed(&xor_block_neon); } while (0)
+#else
+#define NEON_TEMPLATES
+#endif
diff --git a/arch/arm/include/debug/8250.S b/arch/arm/include/debug/8250.S
new file mode 100644
index 000000000..7a2baf913
--- /dev/null
+++ b/arch/arm/include/debug/8250.S
@@ -0,0 +1,54 @@
+/*
+ * arch/arm/include/debug/8250.S
+ *
+ * Copyright (C) 1994-2013 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 addruart, rp, rv, tmp
+ ldr \rp, =CONFIG_DEBUG_UART_PHYS
+ ldr \rv, =CONFIG_DEBUG_UART_VIRT
+ .endm
+
+#ifdef CONFIG_DEBUG_UART_8250_WORD
+ .macro store, rd, rx:vararg
+ str \rd, \rx
+ .endm
+
+ .macro load, rd, rx:vararg
+ ldr \rd, \rx
+ .endm
+#else
+ .macro store, rd, rx:vararg
+ strb \rd, \rx
+ .endm
+
+ .macro load, rd, rx:vararg
+ ldrb \rd, \rx
+ .endm
+#endif
+
+#define UART_SHIFT CONFIG_DEBUG_UART_8250_SHIFT
+
+ .macro senduart,rd,rx
+ store \rd, [\rx, #UART_TX << UART_SHIFT]
+ .endm
+
+ .macro busyuart,rd,rx
+1002: load \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 CONFIG_DEBUG_UART_8250_FLOW_CONTROL
+1001: load \rd, [\rx, #UART_MSR << UART_SHIFT]
+ tst \rd, #UART_MSR_CTS
+ beq 1001b
+#endif
+ .endm
diff --git a/arch/arm/include/debug/asm9260.S b/arch/arm/include/debug/asm9260.S
new file mode 100644
index 000000000..292f85b49
--- /dev/null
+++ b/arch/arm/include/debug/asm9260.S
@@ -0,0 +1,29 @@
+/* Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ * Modified for ASM9260 by Oleksij Remepl <linux@rempel-privat.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, tmp
+ ldr \rp, = CONFIG_DEBUG_UART_PHYS
+ ldr \rv, = CONFIG_DEBUG_UART_VIRT
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #0x50] @ TXDATA
+ .endm
+
+ .macro busyuart,rd,rx
+1002: ldr \rd, [\rx, #0x60] @ STAT
+ tst \rd, #1 << 27 @ TXEMPTY
+ beq 1002b @ wait until transmit done
+ .endm
diff --git a/arch/arm/include/debug/at91.S b/arch/arm/include/debug/at91.S
new file mode 100644
index 000000000..c3c45e628
--- /dev/null
+++ b/arch/arm/include/debug/at91.S
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ *
+*/
+
+#if defined(CONFIG_AT91_DEBUG_LL_DBGU0)
+#define AT91_DBGU 0xfffff200 /* AT91_BASE_DBGU0 */
+#elif defined(CONFIG_AT91_DEBUG_LL_DBGU1)
+#define AT91_DBGU 0xffffee00 /* AT91_BASE_DBGU1 */
+#else
+/* On sama5d4, use USART3 as low level serial console */
+#define AT91_DBGU 0xfc00c000 /* SAMA5D4_BASE_USART3 */
+#endif
+
+#ifdef CONFIG_MMU
+#define AT91_IO_P2V(x) ((x) - 0x01000000)
+#else
+#define AT91_IO_P2V(x) (x)
+#endif
+
+#define AT91_DBGU_SR (0x14) /* Status Register */
+#define AT91_DBGU_THR (0x1c) /* Transmitter Holding Register */
+#define AT91_DBGU_TXRDY (1 << 1) /* Transmitter Ready */
+#define AT91_DBGU_TXEMPTY (1 << 9) /* Transmitter Empty */
+
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =AT91_DBGU @ System peripherals (phys address)
+ ldr \rv, =AT91_IO_P2V(AT91_DBGU) @ System peripherals (virt address)
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #(AT91_DBGU_THR)] @ Write to Transmitter Holding Register
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #(AT91_DBGU_SR)] @ 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)] @ Read Status Register
+ tst \rd, #AT91_DBGU_TXEMPTY @ DBGU_TXEMPTY = 1 when transmission complete
+ beq 1001b
+ .endm
+
diff --git a/arch/arm/include/debug/bcm63xx.S b/arch/arm/include/debug/bcm63xx.S
new file mode 100644
index 000000000..e7164d570
--- /dev/null
+++ b/arch/arm/include/debug/bcm63xx.S
@@ -0,0 +1,33 @@
+/*
+ * Broadcom BCM63xx low-level UART debug
+ *
+ * Copyright (C) 2014 Broadcom 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/serial_bcm63xx.h>
+
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =CONFIG_DEBUG_UART_PHYS
+ ldr \rv, =CONFIG_DEBUG_UART_VIRT
+ .endm
+
+ .macro senduart, rd, rx
+ /* word access do not work */
+ strb \rd, [\rx, #UART_FIFO_REG]
+ .endm
+
+ .macro waituart, rd, rx
+1001: ldr \rd, [\rx, #UART_IR_REG]
+ tst \rd, #(1 << UART_IR_TXEMPTY)
+ beq 1001b
+ .endm
+
+ .macro busyuart, rd, rx
+1002: ldr \rd, [\rx, #UART_IR_REG]
+ tst \rd, #(1 << UART_IR_TXTRESH)
+ beq 1002b
+ .endm
diff --git a/arch/arm/include/debug/clps711x.S b/arch/arm/include/debug/clps711x.S
new file mode 100644
index 000000000..abe225436
--- /dev/null
+++ b/arch/arm/include/debug/clps711x.S
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 CONFIG_DEBUG_CLPS711X_UART2
+#define CLPS711X_UART_PADDR (0x80000000 + 0x0000)
+#define CLPS711X_UART_VADDR (0xfeff0000 + 0x0000)
+#else
+#define CLPS711X_UART_PADDR (0x80000000 + 0x1000)
+#define CLPS711X_UART_VADDR (0xfeff0000 + 0x1000)
+#endif
+
+#define SYSFLG (0x0140)
+#define SYSFLG_UBUSY (1 << 11)
+#define UARTDR (0x0480)
+
+ .macro addruart, rp, rv, tmp
+ ldr \rv, =CLPS711X_UART_VADDR
+ ldr \rp, =CLPS711X_UART_PADDR
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #UARTDR]
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #SYSFLG]
+ tst \rd, #SYSFLG_UBUSY
+ bne 1001b
+ .endm
diff --git a/arch/arm/include/debug/digicolor.S b/arch/arm/include/debug/digicolor.S
new file mode 100644
index 000000000..c95171507
--- /dev/null
+++ b/arch/arm/include/debug/digicolor.S
@@ -0,0 +1,35 @@
+/*
+ * Debugging macro include header for Conexant Digicolor USART
+ *
+ * Copyright (C) 2014 Paradox Innovation 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.
+ *
+*/
+
+#define UA0_STATUS 0x0742
+#define UA0_EMI_REC 0x0744
+
+#define UA0_STATUS_TX_READY 0x40
+
+#ifdef CONFIG_DEBUG_UART_PHYS
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =CONFIG_DEBUG_UART_PHYS
+ ldr \rv, =CONFIG_DEBUG_UART_VIRT
+ .endm
+#endif
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #UA0_EMI_REC]
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldrb \rd, [\rx, #UA0_STATUS]
+ tst \rd, #UA0_STATUS_TX_READY
+ beq 1001b
+ .endm
diff --git a/arch/arm/include/debug/efm32.S b/arch/arm/include/debug/efm32.S
new file mode 100644
index 000000000..2265a1992
--- /dev/null
+++ b/arch/arm/include/debug/efm32.S
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#define UARTn_CMD 0x000c
+#define UARTn_CMD_TXEN 0x0004
+
+#define UARTn_STATUS 0x0010
+#define UARTn_STATUS_TXC 0x0020
+#define UARTn_STATUS_TXBL 0x0040
+
+#define UARTn_TXDATA 0x0034
+
+ .macro addruart, rx, tmp
+ ldr \rx, =(CONFIG_DEBUG_UART_PHYS)
+
+ /*
+ * enable TX. The driver might disable it to save energy. We
+ * don't care about disabling at the end as during debug power
+ * consumption isn't that important.
+ */
+ ldr \tmp, =(UARTn_CMD_TXEN)
+ str \tmp, [\rx, #UARTn_CMD]
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #UARTn_TXDATA]
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #UARTn_STATUS]
+ tst \rd, #UARTn_STATUS_TXBL
+ beq 1001b
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, UARTn_STATUS]
+ tst \rd, #UARTn_STATUS_TXC
+ bne 1001b
+ .endm
diff --git a/arch/arm/include/debug/exynos.S b/arch/arm/include/debug/exynos.S
new file mode 100644
index 000000000..b17fdb7fb
--- /dev/null
+++ b/arch/arm/include/debug/exynos.S
@@ -0,0 +1,39 @@
+/*
+ * 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.
+*/
+
+/* pull in the relevant register and map files. */
+
+#define S3C_ADDR_BASE 0xF6000000
+#define S3C_VA_UART S3C_ADDR_BASE + 0x01000000
+#define EXYNOS4_PA_UART 0x13800000
+#define EXYNOS5_PA_UART 0x12C00000
+
+ /* 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, tmp
+ mrc p15, 0, \tmp, c0, c0, 0
+ and \tmp, \tmp, #0xf0
+ teq \tmp, #0xf0 @@ A15
+ ldreq \rp, =EXYNOS5_PA_UART
+ movne \rp, #EXYNOS4_PA_UART @@ EXYNOS4
+ 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 <debug/samsung.S>
diff --git a/arch/arm/include/debug/icedcc.S b/arch/arm/include/debug/icedcc.S
new file mode 100644
index 000000000..43afcb021
--- /dev/null
+++ b/arch/arm/include/debug/icedcc.S
@@ -0,0 +1,90 @@
+/*
+ * arch/arm/include/debug/icedcc.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.
+ *
+ */
+
+ @@ debug using ARM EmbeddedICE DCC channel
+
+ .macro addruart, rp, rv, tmp
+ .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 */
diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h
new file mode 100644
index 000000000..032a316eb
--- /dev/null
+++ b/arch/arm/include/debug/imx-uart.h
@@ -0,0 +1,119 @@
+/*
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __DEBUG_IMX_UART_H
+#define __DEBUG_IMX_UART_H
+
+#define IMX1_UART1_BASE_ADDR 0x00206000
+#define IMX1_UART2_BASE_ADDR 0x00207000
+#define IMX1_UART_BASE_ADDR(n) IMX1_UART##n##_BASE_ADDR
+#define IMX1_UART_BASE(n) IMX1_UART_BASE_ADDR(n)
+
+#define IMX21_UART1_BASE_ADDR 0x1000a000
+#define IMX21_UART2_BASE_ADDR 0x1000b000
+#define IMX21_UART3_BASE_ADDR 0x1000c000
+#define IMX21_UART4_BASE_ADDR 0x1000d000
+#define IMX21_UART_BASE_ADDR(n) IMX21_UART##n##_BASE_ADDR
+#define IMX21_UART_BASE(n) IMX21_UART_BASE_ADDR(n)
+
+#define IMX25_UART1_BASE_ADDR 0x43f90000
+#define IMX25_UART2_BASE_ADDR 0x43f94000
+#define IMX25_UART3_BASE_ADDR 0x5000c000
+#define IMX25_UART4_BASE_ADDR 0x50008000
+#define IMX25_UART5_BASE_ADDR 0x5002c000
+#define IMX25_UART_BASE_ADDR(n) IMX25_UART##n##_BASE_ADDR
+#define IMX25_UART_BASE(n) IMX25_UART_BASE_ADDR(n)
+
+#define IMX31_UART1_BASE_ADDR 0x43f90000
+#define IMX31_UART2_BASE_ADDR 0x43f94000
+#define IMX31_UART3_BASE_ADDR 0x5000c000
+#define IMX31_UART4_BASE_ADDR 0x43fb0000
+#define IMX31_UART5_BASE_ADDR 0x43fb4000
+#define IMX31_UART_BASE_ADDR(n) IMX31_UART##n##_BASE_ADDR
+#define IMX31_UART_BASE(n) IMX31_UART_BASE_ADDR(n)
+
+#define IMX35_UART1_BASE_ADDR 0x43f90000
+#define IMX35_UART2_BASE_ADDR 0x43f94000
+#define IMX35_UART3_BASE_ADDR 0x5000c000
+#define IMX35_UART_BASE_ADDR(n) IMX35_UART##n##_BASE_ADDR
+#define IMX35_UART_BASE(n) IMX35_UART_BASE_ADDR(n)
+
+#define IMX50_UART1_BASE_ADDR 0x53fbc000
+#define IMX50_UART2_BASE_ADDR 0x53fc0000
+#define IMX50_UART3_BASE_ADDR 0x5000c000
+#define IMX50_UART4_BASE_ADDR 0x53ff0000
+#define IMX50_UART5_BASE_ADDR 0x63f90000
+#define IMX50_UART_BASE_ADDR(n) IMX50_UART##n##_BASE_ADDR
+#define IMX50_UART_BASE(n) IMX50_UART_BASE_ADDR(n)
+
+#define IMX51_UART1_BASE_ADDR 0x73fbc000
+#define IMX51_UART2_BASE_ADDR 0x73fc0000
+#define IMX51_UART3_BASE_ADDR 0x7000c000
+#define IMX51_UART_BASE_ADDR(n) IMX51_UART##n##_BASE_ADDR
+#define IMX51_UART_BASE(n) IMX51_UART_BASE_ADDR(n)
+
+#define IMX53_UART1_BASE_ADDR 0x53fbc000
+#define IMX53_UART2_BASE_ADDR 0x53fc0000
+#define IMX53_UART3_BASE_ADDR 0x5000c000
+#define IMX53_UART4_BASE_ADDR 0x53ff0000
+#define IMX53_UART5_BASE_ADDR 0x63f90000
+#define IMX53_UART_BASE_ADDR(n) IMX53_UART##n##_BASE_ADDR
+#define IMX53_UART_BASE(n) IMX53_UART_BASE_ADDR(n)
+
+#define IMX6Q_UART1_BASE_ADDR 0x02020000
+#define IMX6Q_UART2_BASE_ADDR 0x021e8000
+#define IMX6Q_UART3_BASE_ADDR 0x021ec000
+#define IMX6Q_UART4_BASE_ADDR 0x021f0000
+#define IMX6Q_UART5_BASE_ADDR 0x021f4000
+#define IMX6Q_UART_BASE_ADDR(n) IMX6Q_UART##n##_BASE_ADDR
+#define IMX6Q_UART_BASE(n) IMX6Q_UART_BASE_ADDR(n)
+
+#define IMX6SL_UART1_BASE_ADDR 0x02020000
+#define IMX6SL_UART2_BASE_ADDR 0x02024000
+#define IMX6SL_UART3_BASE_ADDR 0x02034000
+#define IMX6SL_UART4_BASE_ADDR 0x02038000
+#define IMX6SL_UART5_BASE_ADDR 0x02018000
+#define IMX6SL_UART_BASE_ADDR(n) IMX6SL_UART##n##_BASE_ADDR
+#define IMX6SL_UART_BASE(n) IMX6SL_UART_BASE_ADDR(n)
+
+#define IMX6SX_UART1_BASE_ADDR 0x02020000
+#define IMX6SX_UART2_BASE_ADDR 0x021e8000
+#define IMX6SX_UART3_BASE_ADDR 0x021ec000
+#define IMX6SX_UART4_BASE_ADDR 0x021f0000
+#define IMX6SX_UART5_BASE_ADDR 0x021f4000
+#define IMX6SX_UART6_BASE_ADDR 0x022a0000
+#define IMX6SX_UART_BASE_ADDR(n) IMX6SX_UART##n##_BASE_ADDR
+#define IMX6SX_UART_BASE(n) IMX6SX_UART_BASE_ADDR(n)
+
+#define IMX_DEBUG_UART_BASE(soc) soc##_UART_BASE(CONFIG_DEBUG_IMX_UART_PORT)
+
+#ifdef CONFIG_DEBUG_IMX1_UART
+#define UART_PADDR IMX_DEBUG_UART_BASE(IMX1)
+#elif defined(CONFIG_DEBUG_IMX21_IMX27_UART)
+#define UART_PADDR IMX_DEBUG_UART_BASE(IMX21)
+#elif defined(CONFIG_DEBUG_IMX25_UART)
+#define UART_PADDR IMX_DEBUG_UART_BASE(IMX25)
+#elif defined(CONFIG_DEBUG_IMX31_UART)
+#define UART_PADDR IMX_DEBUG_UART_BASE(IMX31)
+#elif defined(CONFIG_DEBUG_IMX35_UART)
+#define UART_PADDR IMX_DEBUG_UART_BASE(IMX35)
+#elif defined(CONFIG_DEBUG_IMX50_UART)
+#define UART_PADDR IMX_DEBUG_UART_BASE(IMX50)
+#elif defined(CONFIG_DEBUG_IMX51_UART)
+#define UART_PADDR IMX_DEBUG_UART_BASE(IMX51)
+#elif defined(CONFIG_DEBUG_IMX53_UART)
+#define UART_PADDR IMX_DEBUG_UART_BASE(IMX53)
+#elif defined(CONFIG_DEBUG_IMX6Q_UART)
+#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6Q)
+#elif defined(CONFIG_DEBUG_IMX6SL_UART)
+#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SL)
+#elif defined(CONFIG_DEBUG_IMX6SX_UART)
+#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SX)
+#endif
+
+#endif /* __DEBUG_IMX_UART_H */
diff --git a/arch/arm/include/debug/imx.S b/arch/arm/include/debug/imx.S
new file mode 100644
index 000000000..619d8cc1a
--- /dev/null
+++ b/arch/arm/include/debug/imx.S
@@ -0,0 +1,47 @@
+/* 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 "imx-uart.h"
+
+/*
+ * FIXME: This is a copy of IMX_IO_P2V in hardware.h, and needs to
+ * stay sync with that. It's hard to maintain, and should be fixed
+ * globally for multi-platform build to use a fixed virtual address
+ * for low-level debug uart port across platforms.
+ */
+#define IMX_IO_P2V(x) ( \
+ (((x) & 0x80000000) >> 7) | \
+ (0xf4000000 + \
+ (((x) & 0x50000000) >> 6) + \
+ (((x) & 0x0b000000) >> 4) + \
+ (((x) & 0x000fffff))))
+
+#define UART_VADDR IMX_IO_P2V(UART_PADDR)
+
+ .macro addruart, rp, rv, tmp
+ 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/include/debug/ks8695.S b/arch/arm/include/debug/ks8695.S
new file mode 100644
index 000000000..961da1f32
--- /dev/null
+++ b/arch/arm/include/debug/ks8695.S
@@ -0,0 +1,40 @@
+/*
+ * arch/arm/include/debug/ks8695.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.
+ */
+
+#define KS8695_UART_PA 0x03ffe000
+#define KS8695_UART_VA 0xf00fe000
+#define KS8695_URTH (0x04)
+#define KS8695_URLS (0x14)
+#define URLS_URTE (1 << 6)
+#define URLS_URTHRE (1 << 5)
+
+ .macro addruart, rp, rv, tmp
+ 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/include/debug/meson.S b/arch/arm/include/debug/meson.S
new file mode 100644
index 000000000..1bae99bf6
--- /dev/null
+++ b/arch/arm/include/debug/meson.S
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 Carlo Caione
+ * Carlo Caione <carlo@caione.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.
+ */
+
+#define MESON_AO_UART_WFIFO 0x0
+#define MESON_AO_UART_STATUS 0xc
+
+#define MESON_AO_UART_TX_FIFO_EMPTY (1 << 22)
+#define MESON_AO_UART_TX_FIFO_FULL (1 << 21)
+
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =(CONFIG_DEBUG_UART_PHYS) @ physical
+ ldr \rv, =(CONFIG_DEBUG_UART_VIRT) @ virtual
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #MESON_AO_UART_WFIFO]
+ .endm
+
+ .macro busyuart,rd,rx
+1002: ldr \rd, [\rx, #MESON_AO_UART_STATUS]
+ tst \rd, #MESON_AO_UART_TX_FIFO_EMPTY
+ beq 1002b
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #MESON_AO_UART_STATUS]
+ tst \rd, #MESON_AO_UART_TX_FIFO_FULL
+ bne 1001b
+ .endm
diff --git a/arch/arm/include/debug/msm.S b/arch/arm/include/debug/msm.S
new file mode 100644
index 000000000..b03024fa6
--- /dev/null
+++ b/arch/arm/include/debug/msm.S
@@ -0,0 +1,54 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =CONFIG_DEBUG_UART_PHYS
+ ldr \rv, =CONFIG_DEBUG_UART_VIRT
+ .endm
+
+ .macro senduart, rd, rx
+ARM_BE8(rev \rd, \rd )
+ @ Write the 1 character to UARTDM_TF
+ str \rd, [\rx, #0x70]
+ .endm
+
+ .macro waituart, rd, rx
+ @ check for TX_EMT in UARTDM_SR
+ ldr \rd, [\rx, #0x08]
+ARM_BE8(rev \rd, \rd )
+ tst \rd, #0x08
+ bne 1002f
+ @ wait for TXREADY in UARTDM_ISR
+1001: ldr \rd, [\rx, #0x14]
+ARM_BE8(rev \rd, \rd )
+ tst \rd, #0x80
+ beq 1001b
+1002:
+ @ Clear TX_READY by writing to the UARTDM_CR register
+ mov \rd, #0x300
+ARM_BE8(rev \rd, \rd )
+ str \rd, [\rx, #0x10]
+ @ Write 0x1 to NCF register
+ mov \rd, #0x1
+ARM_BE8(rev \rd, \rd )
+ str \rd, [\rx, #0x40]
+ @ UARTDM reg. Read to induce delay
+ ldr \rd, [\rx, #0x08]
+ .endm
+
+ .macro busyuart, rd, rx
+ .endm
diff --git a/arch/arm/include/debug/netx.S b/arch/arm/include/debug/netx.S
new file mode 100644
index 000000000..81e1b2af7
--- /dev/null
+++ b/arch/arm/include/debug/netx.S
@@ -0,0 +1,36 @@
+/*
+ * 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 UART_DATA 0
+#define UART_FLAG 0x18
+#define UART_FLAG_BUSY (1 << 3)
+
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =CONFIG_DEBUG_UART_PHYS
+ ldr \rv, =CONFIG_DEBUG_UART_VIRT
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #UART_DATA]
+ .endm
+
+ .macro busyuart,rd,rx
+1002: ldr \rd, [\rx, #UART_FLAG]
+ tst \rd, #UART_FLAG_BUSY
+ bne 1002b
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #UART_FLAG]
+ tst \rd, #UART_FLAG_BUSY
+ bne 1001b
+ .endm
diff --git a/arch/arm/include/debug/omap2plus.S b/arch/arm/include/debug/omap2plus.S
new file mode 100644
index 000000000..6d867aef1
--- /dev/null
+++ b/arch/arm/include/debug/omap2plus.S
@@ -0,0 +1,190 @@
+/*
+ * 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>
+
+/* 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 */
+#define OMAP3_UART4_AM35XX_BASE 0x4809E000 /* Only on AM35xx */
+
+/* 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
+
+/* TI81XX serial ports */
+#define TI81XX_UART1_BASE 0x48020000
+#define TI81XX_UART2_BASE 0x48022000
+#define TI81XX_UART3_BASE 0x48024000
+
+/* AM3505/3517 UART4 */
+#define AM35XX_UART4_BASE 0x4809E000 /* Only on AM3505/3517 */
+
+/* AM33XX serial port */
+#define AM33XX_UART1_BASE 0x44E09000
+
+/* OMAP5 serial ports */
+#define OMAP5_UART1_BASE OMAP2_UART1_BASE
+#define OMAP5_UART2_BASE OMAP2_UART2_BASE
+#define OMAP5_UART3_BASE OMAP4_UART3_BASE
+#define OMAP5_UART4_BASE OMAP4_UART4_BASE
+#define OMAP5_UART5_BASE 0x48066000
+#define OMAP5_UART6_BASE 0x48068000
+
+/* External port on Zoom2/3 */
+#define ZOOM_UART_BASE 0x10000000
+#define ZOOM_UART_VIRT 0xfa400000
+
+#define OMAP_PORT_SHIFT 2
+#define ZOOM_PORT_SHIFT 1
+
+#define UART_OFFSET(addr) ((addr) & 0x00ffffff)
+
+ .pushsection .data
+omap_uart_phys: .word 0
+omap_uart_virt: .word 0
+omap_uart_lsr: .word 0
+ .popsection
+
+ .macro addruart, rp, rv, tmp
+
+ /* Use omap_uart_phys/virt if already configured */
+10: adr \rp, 99f @ get effective addr of 99f
+ ldr \rv, [\rp] @ get absolute addr of 99f
+ sub \rv, \rv, \rp @ offset between the two
+ ldr \rp, [\rp, #4] @ abs addr of omap_uart_phys
+ sub \tmp, \rp, \rv @ make it effective
+ ldr \rp, [\tmp, #0] @ omap_uart_phys
+ ldr \rv, [\tmp, #4] @ omap_uart_virt
+ cmp \rp, #0 @ is port configured?
+ cmpne \rv, #0
+ bne 100f @ already configured
+
+ /* Configure the UART offset from the phys/virt base */
+#ifdef CONFIG_DEBUG_OMAP2UART1
+ mov \rp, #UART_OFFSET(OMAP2_UART1_BASE) @ omap2/3/4
+ b 98f
+#endif
+#ifdef CONFIG_DEBUG_OMAP2UART2
+ mov \rp, #UART_OFFSET(OMAP2_UART2_BASE) @ omap2/3/4
+ b 98f
+#endif
+#ifdef CONFIG_DEBUG_OMAP2UART3
+ mov \rp, #UART_OFFSET(OMAP2_UART3_BASE)
+ b 98f
+#endif
+#ifdef CONFIG_DEBUG_OMAP3UART3
+ mov \rp, #UART_OFFSET(OMAP3_UART1_BASE)
+ add \rp, \rp, #0x00fb0000
+ add \rp, \rp, #0x00006000 @ OMAP3_UART3_BASE
+ b 98f
+#endif
+#ifdef CONFIG_DEBUG_OMAP4UART3
+ mov \rp, #UART_OFFSET(OMAP4_UART3_BASE)
+ b 98f
+#endif
+#ifdef CONFIG_DEBUG_OMAP3UART4
+ mov \rp, #UART_OFFSET(OMAP3_UART1_BASE)
+ add \rp, \rp, #0x00fb0000
+ add \rp, \rp, #0x00028000 @ OMAP3_UART4_BASE
+ b 98f
+#endif
+#ifdef CONFIG_DEBUG_OMAP4UART4
+ mov \rp, #UART_OFFSET(OMAP4_UART4_BASE)
+ b 98f
+#endif
+#ifdef CONFIG_DEBUG_TI81XXUART1
+ mov \rp, #UART_OFFSET(TI81XX_UART1_BASE)
+ b 98f
+#endif
+#ifdef CONFIG_DEBUG_TI81XXUART2
+ mov \rp, #UART_OFFSET(TI81XX_UART2_BASE)
+ b 98f
+#endif
+#ifdef CONFIG_DEBUG_TI81XXUART3
+ mov \rp, #UART_OFFSET(TI81XX_UART3_BASE)
+ b 98f
+#endif
+#ifdef CONFIG_DEBUG_AM33XXUART1
+ ldr \rp, =AM33XX_UART1_BASE
+ and \rp, \rp, #0x00ffffff
+ b 97f
+#endif
+#ifdef CONFIG_DEBUG_ZOOM_UART
+ ldr \rp, =ZOOM_UART_BASE
+ str \rp, [\tmp, #0] @ omap_uart_phys
+ ldr \rp, =ZOOM_UART_VIRT
+ str \rp, [\tmp, #4] @ omap_uart_virt
+ mov \rp, #(UART_LSR << ZOOM_PORT_SHIFT)
+ str \rp, [\tmp, #8] @ omap_uart_lsr
+#endif
+ b 10b
+
+ /* AM33XX: Store both phys and virt address for the uart */
+97: add \rp, \rp, #0x44000000 @ phys base
+ str \rp, [\tmp, #0] @ omap_uart_phys
+ sub \rp, \rp, #0x44000000 @ phys base
+ add \rp, \rp, #0xf9000000 @ virt base
+ str \rp, [\tmp, #4] @ omap_uart_virt
+ mov \rp, #(UART_LSR << OMAP_PORT_SHIFT)
+ str \rp, [\tmp, #8] @ omap_uart_lsr
+
+ b 10b
+
+ /* Store both phys and virt address for the uart */
+98: add \rp, \rp, #0x48000000 @ phys base
+ str \rp, [\tmp, #0] @ omap_uart_phys
+ sub \rp, \rp, #0x48000000 @ phys base
+ add \rp, \rp, #0xfa000000 @ virt base
+ str \rp, [\tmp, #4] @ omap_uart_virt
+ mov \rp, #(UART_LSR << OMAP_PORT_SHIFT)
+ str \rp, [\tmp, #8] @ omap_uart_lsr
+
+ b 10b
+
+ .align
+99: .word .
+ .word omap_uart_phys
+ .ltorg
+
+100: /* Pass the UART_LSR reg address */
+ ldr \tmp, [\tmp, #8] @ omap_uart_lsr
+ add \rp, \rp, \tmp
+ add \rv, \rv, \tmp
+ .endm
+
+ .macro senduart,rd,rx
+ orr \rd, \rd, \rx, lsl #24 @ preserve LSR reg offset
+ bic \rx, \rx, #0xff @ get base (THR) reg address
+ strb \rd, [\rx] @ send lower byte of rd
+ orr \rx, \rx, \rd, lsr #24 @ restore original rx (LSR)
+ bic \rd, \rd, #(0xff << 24) @ restore original rd
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldrb \rd, [\rx] @ rx contains UART_LSR address
+ 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/include/debug/pl01x.S b/arch/arm/include/debug/pl01x.S
new file mode 100644
index 000000000..92ef808a2
--- /dev/null
+++ b/arch/arm/include/debug/pl01x.S
@@ -0,0 +1,38 @@
+/* arch/arm/include/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>
+
+#ifdef CONFIG_DEBUG_UART_PHYS
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =CONFIG_DEBUG_UART_PHYS
+ ldr \rv, =CONFIG_DEBUG_UART_VIRT
+ .endm
+#endif
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #UART01x_DR]
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #UART01x_FR]
+ ARM_BE8( rev \rd, \rd )
+ tst \rd, #UART01x_FR_TXFF
+ bne 1001b
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #UART01x_FR]
+ ARM_BE8( rev \rd, \rd )
+ tst \rd, #UART01x_FR_BUSY
+ bne 1001b
+ .endm
diff --git a/arch/arm/include/debug/renesas-scif.S b/arch/arm/include/debug/renesas-scif.S
new file mode 100644
index 000000000..97820a8df
--- /dev/null
+++ b/arch/arm/include/debug/renesas-scif.S
@@ -0,0 +1,52 @@
+/*
+ * Renesas SCIF(A) debugging macro include header
+ *
+ * Based on r8a7790.S
+ *
+ * Copyright (C) 2012-2013 Renesas Electronics Corporation
+ * 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.
+ */
+
+#define SCIF_PHYS CONFIG_DEBUG_UART_PHYS
+#define SCIF_VIRT ((SCIF_PHYS & 0x00ffffff) | 0xfd000000)
+
+#if CONFIG_DEBUG_UART_PHYS < 0xe6e00000
+/* SCIFA */
+#define FTDR 0x20
+#define FSR 0x14
+#else
+/* SCIF */
+#define FTDR 0x0c
+#define FSR 0x10
+#endif
+
+#define TDFE (1 << 5)
+#define TEND (1 << 6)
+
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =SCIF_PHYS
+ ldr \rv, =SCIF_VIRT
+ .endm
+
+ .macro waituart, rd, rx
+1001: ldrh \rd, [\rx, #FSR]
+ tst \rd, #TDFE
+ beq 1001b
+ .endm
+
+ .macro senduart, rd, rx
+ strb \rd, [\rx, #FTDR]
+ ldrh \rd, [\rx, #FSR]
+ bic \rd, \rd, #TEND
+ strh \rd, [\rx, #FSR]
+ .endm
+
+ .macro busyuart, rd, rx
+1001: ldrh \rd, [\rx, #FSR]
+ tst \rd, #TEND
+ beq 1001b
+ .endm
diff --git a/arch/arm/include/debug/s3c24xx.S b/arch/arm/include/debug/s3c24xx.S
new file mode 100644
index 000000000..b1f54dc48
--- /dev/null
+++ b/arch/arm/include/debug/s3c24xx.S
@@ -0,0 +1,46 @@
+/* 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 <linux/serial_s3c.h>
+
+#define S3C2410_UART1_OFF (0x4000)
+
+ .macro addruart, rp, rv, tmp
+ ldr \rp, = CONFIG_DEBUG_UART_PHYS
+ ldr \rv, = CONFIG_DEBUG_UART_VIRT
+ .endm
+
+ .macro fifo_full_s3c2410 rd, rx
+ ldr \rd, [\rx, # S3C2410_UFSTAT]
+ tst \rd, #S3C2410_UFSTAT_TXFULL
+ .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_DEBUG_S3C2410_UART)
+#define fifo_full fifo_full_s3c2410
+#define fifo_level fifo_level_s3c2410
+#endif
+
+/* include the reset of the code which will do the work */
+
+#include <debug/samsung.S>
diff --git a/arch/arm/include/debug/s5pv210.S b/arch/arm/include/debug/s5pv210.S
new file mode 100644
index 000000000..4f1a73e2c
--- /dev/null
+++ b/arch/arm/include/debug/s5pv210.S
@@ -0,0 +1,34 @@
+/*
+ * 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.
+*/
+
+/* pull in the relevant register and map files. */
+
+#define S3C_ADDR_BASE 0xF6000000
+#define S3C_VA_UART S3C_ADDR_BASE + 0x01000000
+#define S5PV210_PA_UART 0xe2900000
+
+ /* 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, tmp
+ ldr \rp, =S5PV210_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 <debug/samsung.S>
diff --git a/arch/arm/include/debug/sa1100.S b/arch/arm/include/debug/sa1100.S
new file mode 100644
index 000000000..a0ae4f4cd
--- /dev/null
+++ b/arch/arm/include/debug/sa1100.S
@@ -0,0 +1,68 @@
+/* arch/arm/include/debug/sa1100.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 UTCR3 0x0c
+#define UTDR 0x14
+#define UTSR1 0x20
+#define UTCR3_TXE 0x00000002 /* Transmit Enable */
+#define UTSR1_TBY 0x00000001 /* Transmitter BusY (read) */
+#define UTSR1_TNF 0x00000004 /* Transmit FIFO Not Full (read) */
+
+ .macro addruart, rp, rv, tmp
+ 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/include/debug/samsung.S b/arch/arm/include/debug/samsung.S
new file mode 100644
index 000000000..8d8d922e5
--- /dev/null
+++ b/arch/arm/include/debug/samsung.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 <linux/serial_s3c.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/include/debug/sirf.S b/arch/arm/include/debug/sirf.S
new file mode 100644
index 000000000..630f231f2
--- /dev/null
+++ b/arch/arm/include/debug/sirf.S
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/mach-prima2/include/mach/debug-macro.S
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#define SIRF_LLUART_TXFIFO_STATUS 0x0114
+#define SIRF_LLUART_TXFIFO_DATA 0x0118
+
+#define SIRF_LLUART_TXFIFO_FULL (1 << 5)
+
+#ifdef CONFIG_DEBUG_SIRFATLAS7_UART0
+#define SIRF_LLUART_TXFIFO_EMPTY (1 << 8)
+#else
+#define SIRF_LLUART_TXFIFO_EMPTY (1 << 6)
+#endif
+
+
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =CONFIG_DEBUG_UART_PHYS @ physical
+ ldr \rv, =CONFIG_DEBUG_UART_VIRT @ virtual
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #SIRF_LLUART_TXFIFO_DATA]
+ .endm
+
+ .macro busyuart,rd,rx
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #SIRF_LLUART_TXFIFO_STATUS]
+ tst \rd, #SIRF_LLUART_TXFIFO_EMPTY
+ beq 1001b
+ .endm
+
diff --git a/arch/arm/include/debug/sti.S b/arch/arm/include/debug/sti.S
new file mode 100644
index 000000000..e3aa58ff1
--- /dev/null
+++ b/arch/arm/include/debug/sti.S
@@ -0,0 +1,61 @@
+/*
+ * arch/arm/include/debug/sti.S
+ *
+ * Debugging macro include header
+ * Copyright (C) 2013 STMicroelectronics (R&D) 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.
+ */
+
+#define STIH41X_COMMS_BASE 0xfed00000
+#define STIH41X_ASC2_BASE (STIH41X_COMMS_BASE+0x32000)
+
+#define STIH41X_SBC_LPM_BASE 0xfe400000
+#define STIH41X_SBC_COMMS_BASE (STIH41X_SBC_LPM_BASE + 0x100000)
+#define STIH41X_SBC_ASC1_BASE (STIH41X_SBC_COMMS_BASE + 0x31000)
+
+
+#define VIRT_ADDRESS(x) (x - 0x1000000)
+
+#if IS_ENABLED(CONFIG_STIH41X_DEBUG_ASC2)
+#define DEBUG_LL_UART_BASE STIH41X_ASC2_BASE
+#endif
+
+#if IS_ENABLED(CONFIG_STIH41X_DEBUG_SBC_ASC1)
+#define DEBUG_LL_UART_BASE STIH41X_SBC_ASC1_BASE
+#endif
+
+#ifndef DEBUG_LL_UART_BASE
+#error "DEBUG UART is not Configured"
+#endif
+
+#define ASC_TX_BUF_OFF 0x04
+#define ASC_CTRL_OFF 0x0c
+#define ASC_STA_OFF 0x14
+
+#define ASC_STA_TX_FULL (1<<9)
+#define ASC_STA_TX_EMPTY (1<<1)
+
+
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =DEBUG_LL_UART_BASE @ physical base
+ ldr \rv, =VIRT_ADDRESS(DEBUG_LL_UART_BASE) @ virt base
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #ASC_TX_BUF_OFF]
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #ASC_STA_OFF]
+ tst \rd, #ASC_STA_TX_FULL
+ bne 1001b
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #ASC_STA_OFF]
+ tst \rd, #ASC_STA_TX_EMPTY
+ beq 1001b
+ .endm
diff --git a/arch/arm/include/debug/tegra.S b/arch/arm/include/debug/tegra.S
new file mode 100644
index 000000000..3bc80599c
--- /dev/null
+++ b/arch/arm/include/debug/tegra.S
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2010,2011 Google, Inc.
+ * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ * Doug Anderson <dianders@chromium.org>
+ * Stephen Warren <swarren@nvidia.com>
+ *
+ * Portions based on mach-omap2's debug-macro.S
+ * Copyright (C) 1994-1999 Russell King
+ *
+ * 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/serial_reg.h>
+
+#define UART_SHIFT 2
+
+/* Physical addresses */
+#define TEGRA_CLK_RESET_BASE 0x60006000
+#define TEGRA_APB_MISC_BASE 0x70000000
+#define TEGRA_UARTA_BASE 0x70006000
+#define TEGRA_UARTB_BASE 0x70006040
+#define TEGRA_UARTC_BASE 0x70006200
+#define TEGRA_UARTD_BASE 0x70006300
+#define TEGRA_UARTE_BASE 0x70006400
+#define TEGRA_PMC_BASE 0x7000e400
+
+#define TEGRA_CLK_RST_DEVICES_L (TEGRA_CLK_RESET_BASE + 0x04)
+#define TEGRA_CLK_RST_DEVICES_H (TEGRA_CLK_RESET_BASE + 0x08)
+#define TEGRA_CLK_RST_DEVICES_U (TEGRA_CLK_RESET_BASE + 0x0c)
+#define TEGRA_CLK_OUT_ENB_L (TEGRA_CLK_RESET_BASE + 0x10)
+#define TEGRA_CLK_OUT_ENB_H (TEGRA_CLK_RESET_BASE + 0x14)
+#define TEGRA_CLK_OUT_ENB_U (TEGRA_CLK_RESET_BASE + 0x18)
+#define TEGRA_PMC_SCRATCH20 (TEGRA_PMC_BASE + 0xa0)
+#define TEGRA_APB_MISC_GP_HIDREV (TEGRA_APB_MISC_BASE + 0x804)
+
+/*
+ * Must be section-aligned since a section mapping is used early on.
+ * Must not overlap with regions in mach-tegra/io.c:tegra_io_desc[].
+ */
+#define UART_VIRTUAL_BASE 0xfe800000
+
+#define checkuart(rp, rv, lhu, bit, uart) \
+ /* Load address of CLK_RST register */ \
+ ldr rp, =TEGRA_CLK_RST_DEVICES_##lhu ; \
+ /* Load value from CLK_RST register */ \
+ ldr rp, [rp, #0] ; \
+ /* Test UART's reset bit */ \
+ tst rp, #(1 << bit) ; \
+ /* If set, can't use UART; jump to save no UART */ \
+ bne 90f ; \
+ /* Load address of CLK_OUT_ENB register */ \
+ ldr rp, =TEGRA_CLK_OUT_ENB_##lhu ; \
+ /* Load value from CLK_OUT_ENB register */ \
+ ldr rp, [rp, #0] ; \
+ /* Test UART's clock enable bit */ \
+ tst rp, #(1 << bit) ; \
+ /* If clear, can't use UART; jump to save no UART */ \
+ beq 90f ; \
+ /* Passed all tests, load address of UART registers */ \
+ ldr rp, =TEGRA_UART##uart##_BASE ; \
+ /* Jump to save UART address */ \
+ b 91f
+
+ .macro addruart, rp, rv, tmp
+ adr \rp, 99f @ actual addr of 99f
+ ldr \rv, [\rp] @ linked addr is stored there
+ sub \rv, \rv, \rp @ offset between the two
+ ldr \rp, [\rp, #4] @ linked tegra_uart_config
+ sub \tmp, \rp, \rv @ actual tegra_uart_config
+ ldr \rp, [\tmp] @ Load tegra_uart_config
+ cmp \rp, #1 @ needs initialization?
+ bne 100f @ no; go load the addresses
+ mov \rv, #0 @ yes; record init is done
+ str \rv, [\tmp]
+
+#ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA
+ /* Check ODMDATA */
+10: ldr \rp, =TEGRA_PMC_SCRATCH20
+ ldr \rp, [\rp, #0] @ Load PMC_SCRATCH20
+ lsr \rv, \rp, #18 @ 19:18 are console type
+ and \rv, \rv, #3
+ cmp \rv, #2 @ 2 and 3 mean DCC, UART
+ beq 11f @ some boards swap the meaning
+ cmp \rv, #3 @ so accept either
+ bne 90f
+11: lsr \rv, \rp, #15 @ 17:15 are UART ID
+ and \rv, #7
+ cmp \rv, #0 @ UART 0?
+ beq 20f
+ cmp \rv, #1 @ UART 1?
+ beq 21f
+ cmp \rv, #2 @ UART 2?
+ beq 22f
+ cmp \rv, #3 @ UART 3?
+ beq 23f
+ cmp \rv, #4 @ UART 4?
+ beq 24f
+ b 90f @ invalid
+#endif
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTA) || \
+ defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+ /* Check UART A validity */
+20: checkuart(\rp, \rv, L, 6, A)
+#endif
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTB) || \
+ defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+ /* Check UART B validity */
+21: checkuart(\rp, \rv, L, 7, B)
+#endif
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTC) || \
+ defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+ /* Check UART C validity */
+22: checkuart(\rp, \rv, H, 23, C)
+#endif
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTD) || \
+ defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+ /* Check UART D validity */
+23: checkuart(\rp, \rv, U, 1, D)
+#endif
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTE) || \
+ defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+ /* Check UART E validity */
+24:
+ checkuart(\rp, \rv, U, 2, E)
+#endif
+
+ /* No valid UART found */
+90: mov \rp, #0
+ /* fall through */
+
+ /* Record whichever UART we chose */
+91: str \rp, [\tmp, #4] @ Store in tegra_uart_phys
+ cmp \rp, #0 @ Valid UART address?
+ bne 92f @ Yes, go process it
+ str \rp, [\tmp, #8] @ Store 0 in tegra_uart_virt
+ b 100f @ Done
+92: and \rv, \rp, #0xffffff @ offset within 1MB section
+ add \rv, \rv, #UART_VIRTUAL_BASE
+ str \rv, [\tmp, #8] @ Store in tegra_uart_virt
+ b 100f
+
+ .align
+99: .word .
+ .word tegra_uart_config
+ .ltorg
+
+ /* Load previously selected UART address */
+100: ldr \rp, [\tmp, #4] @ Load tegra_uart_phys
+ ldr \rv, [\tmp, #8] @ Load tegra_uart_virt
+ .endm
+
+/*
+ * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra
+ * check to make sure that the UART address is actually valid.
+ */
+
+ .macro senduart, rd, rx
+ cmp \rx, #0
+ strneb \rd, [\rx, #UART_TX << UART_SHIFT]
+1001:
+ .endm
+
+ .macro busyuart, rd, rx
+ cmp \rx, #0
+ beq 1002f
+1001: ldrb \rd, [\rx, #UART_LSR << UART_SHIFT]
+ and \rd, \rd, #UART_LSR_THRE
+ teq \rd, #UART_LSR_THRE
+ bne 1001b
+1002:
+ .endm
+
+ .macro waituart, rd, rx
+#ifdef FLOW_CONTROL
+ cmp \rx, #0
+ beq 1002f
+1001: ldrb \rd, [\rx, #UART_MSR << UART_SHIFT]
+ tst \rd, #UART_MSR_CTS
+ beq 1001b
+1002:
+#endif
+ .endm
+
+/*
+ * Storage for the state maintained by the macros above.
+ *
+ * In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c.
+ * That's because this header is included from multiple files, and we only
+ * want a single copy of the data. In particular, the UART probing code above
+ * assumes it's running using physical addresses. This is true when this file
+ * is included from head.o, but not when included from debug.o. So we need
+ * to share the probe results between the two copies, rather than having
+ * to re-run the probing again later.
+ *
+ * In the decompressor, we put the symbol/storage right here, since common.c
+ * isn't included in the decompressor build. This symbol gets put in .text
+ * even though it's really data, since .data is discarded from the
+ * decompressor. Luckily, .text is writeable in the decompressor, unless
+ * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug.
+ */
+#if defined(ZIMAGE)
+tegra_uart_config:
+ /* Debug UART initialization required */
+ .word 1
+ /* Debug UART physical address */
+ .word 0
+ /* Debug UART virtual address */
+ .word 0
+#endif
diff --git a/arch/arm/include/debug/uncompress.h b/arch/arm/include/debug/uncompress.h
new file mode 100644
index 000000000..0e2949b0f
--- /dev/null
+++ b/arch/arm/include/debug/uncompress.h
@@ -0,0 +1,7 @@
+#ifdef CONFIG_DEBUG_UNCOMPRESS
+extern void putc(int c);
+#else
+static inline void putc(int c) {}
+#endif
+static inline void flush(void) {}
+static inline void arch_decomp_setup(void) {}
diff --git a/arch/arm/include/debug/ux500.S b/arch/arm/include/debug/ux500.S
new file mode 100644
index 000000000..aa7f63a8b
--- /dev/null
+++ b/arch/arm/include/debug/ux500.S
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ *
+ */
+
+
+#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_DB8500
+#define U8500_UART0_PHYS_BASE (0x80120000)
+#define U8500_UART1_PHYS_BASE (0x80121000)
+#define U8500_UART2_PHYS_BASE (0x80007000)
+#define U8500_UART0_VIRT_BASE (0xf8120000)
+#define U8500_UART1_VIRT_BASE (0xf8121000)
+#define U8500_UART2_VIRT_BASE (0xf8007000)
+#define __UX500_PHYS_UART(n) U8500_UART##n##_PHYS_BASE
+#define __UX500_VIRT_UART(n) U8500_UART##n##_VIRT_BASE
+#endif
+
+#if !defined(__UX500_PHYS_UART) || !defined(__UX500_VIRT_UART)
+#error Unknown SOC
+#endif
+
+#define UX500_PHYS_UART(n) __UX500_PHYS_UART(n)
+#define UX500_VIRT_UART(n) __UX500_VIRT_UART(n)
+#define UART_PHYS_BASE UX500_PHYS_UART(CONFIG_UX500_DEBUG_UART)
+#define UART_VIRT_BASE UX500_VIRT_UART(CONFIG_UX500_DEBUG_UART)
+
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =UART_PHYS_BASE @ no, physical address
+ ldr \rv, =UART_VIRT_BASE @ yes, virtual address
+ .endm
+
+#include <debug/pl01x.S>
diff --git a/arch/arm/include/debug/vexpress.S b/arch/arm/include/debug/vexpress.S
new file mode 100644
index 000000000..524acd5a2
--- /dev/null
+++ b/arch/arm/include/debug/vexpress.S
@@ -0,0 +1,51 @@
+/* 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_PHYS_BASE 0x10000000
+#define DEBUG_LL_UART_OFFSET 0x00009000
+
+#define DEBUG_LL_PHYS_BASE_RS1 0x1c000000
+#define DEBUG_LL_UART_OFFSET_RS1 0x00090000
+
+#define DEBUG_LL_UART_PHYS_CRX 0xb0090000
+
+#define DEBUG_LL_VIRT_BASE 0xf8000000
+
+#if defined(CONFIG_DEBUG_VEXPRESS_UART0_DETECT)
+
+ .macro addruart,rp,rv,tmp
+ .arch armv7-a
+
+ @ Make an educated guess regarding the memory map:
+ @ - the original A9 core tile (based on ARM Cortex-A9 r0p1)
+ @ should use UART at 0x10009000
+ @ - all other (RS1 complaint) tiles use UART mapped
+ @ at 0x1c090000
+ mrc p15, 0, \rp, c0, c0, 0
+ movw \rv, #0xc091
+ movt \rv, #0x410f
+ cmp \rp, \rv
+
+ @ Original memory map
+ moveq \rp, #DEBUG_LL_UART_OFFSET
+ orreq \rv, \rp, #DEBUG_LL_VIRT_BASE
+ orreq \rp, \rp, #DEBUG_LL_PHYS_BASE
+
+ @ RS1 memory map
+ movne \rp, #DEBUG_LL_UART_OFFSET_RS1
+ orrne \rv, \rp, #DEBUG_LL_VIRT_BASE
+ orrne \rp, \rp, #DEBUG_LL_PHYS_BASE_RS1
+
+ .endm
+
+#include <debug/pl01x.S>
+#endif
diff --git a/arch/arm/include/debug/vf.S b/arch/arm/include/debug/vf.S
new file mode 100644
index 000000000..b88933849
--- /dev/null
+++ b/arch/arm/include/debug/vf.S
@@ -0,0 +1,37 @@
+/*
+ * Copyright 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define VF_UART0_BASE_ADDR 0x40027000
+#define VF_UART1_BASE_ADDR 0x40028000
+#define VF_UART2_BASE_ADDR 0x40029000
+#define VF_UART3_BASE_ADDR 0x4002a000
+#define VF_UART_BASE_ADDR(n) VF_UART##n##_BASE_ADDR
+#define VF_UART_BASE(n) VF_UART_BASE_ADDR(n)
+#define VF_UART_PHYSICAL_BASE VF_UART_BASE(CONFIG_DEBUG_VF_UART_PORT)
+
+#define VF_UART_VIRTUAL_BASE 0xfe000000
+
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =VF_UART_PHYSICAL_BASE @ physical
+ and \rv, \rp, #0xffffff @ offset within 16MB section
+ add \rv, \rv, #VF_UART_VIRTUAL_BASE
+ .endm
+
+ .macro senduart, rd, rx
+ strb \rd, [\rx, #0x7] @ Data Register
+ .endm
+
+ .macro busyuart, rd, rx
+1001: ldrb \rd, [\rx, #0x4] @ Status Register 1
+ tst \rd, #1 << 6 @ TC
+ beq 1001b @ wait until transmit done
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
diff --git a/arch/arm/include/debug/vt8500.S b/arch/arm/include/debug/vt8500.S
new file mode 100644
index 000000000..0e0ca0869
--- /dev/null
+++ b/arch/arm/include/debug/vt8500.S
@@ -0,0 +1,37 @@
+/*
+ * Debugging macro include header
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ * Moved from arch/arm/mach-vt8500/include/mach/debug-macro.S
+ * Minor changes for readability.
+ *
+ * This program is free software; you can 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_PHYS_BASE 0xD8000000
+#define DEBUG_LL_VIRT_BASE 0xF8000000
+#define DEBUG_LL_UART_OFFSET 0x00200000
+
+#if defined(CONFIG_DEBUG_VT8500_UART0)
+ .macro addruart, rp, rv, tmp
+ mov \rp, #DEBUG_LL_UART_OFFSET
+ orr \rv, \rp, #DEBUG_LL_VIRT_BASE
+ orr \rp, \rp, #DEBUG_LL_PHYS_BASE
+ .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
+
+#endif
diff --git a/arch/arm/include/debug/zynq.S b/arch/arm/include/debug/zynq.S
new file mode 100644
index 000000000..bd13dedbd
--- /dev/null
+++ b/arch/arm/include/debug/zynq.S
@@ -0,0 +1,56 @@
+/*
+ * Debugging macro include header
+ *
+ * Copyright (C) 2011 Xilinx
+ *
+ * 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 UART_CR_OFFSET 0x00 /* Control Register [8:0] */
+#define UART_SR_OFFSET 0x2C /* Channel Status [11:0] */
+#define UART_FIFO_OFFSET 0x30 /* FIFO [15:0] or [7:0] */
+
+#define UART_SR_TXFULL 0x00000010 /* TX FIFO full */
+#define UART_SR_TXEMPTY 0x00000008 /* TX FIFO empty */
+
+#define UART0_PHYS 0xE0000000
+#define UART0_VIRT 0xF0000000
+#define UART1_PHYS 0xE0001000
+#define UART1_VIRT 0xF0001000
+
+#if IS_ENABLED(CONFIG_DEBUG_ZYNQ_UART1)
+# define LL_UART_PADDR UART1_PHYS
+# define LL_UART_VADDR UART1_VIRT
+#else
+# define LL_UART_PADDR UART0_PHYS
+# define LL_UART_VADDR UART0_VIRT
+#endif
+
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =LL_UART_PADDR @ physical
+ ldr \rv, =LL_UART_VADDR @ virtual
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #UART_FIFO_OFFSET] @ TXDATA
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #UART_SR_OFFSET]
+ARM_BE8( rev \rd, \rd )
+ tst \rd, #UART_SR_TXEMPTY
+ beq 1001b
+ .endm
+
+ .macro busyuart,rd,rx
+1002: ldr \rd, [\rx, #UART_SR_OFFSET] @ get status register
+ARM_BE8( rev \rd, \rd )
+ tst \rd, #UART_SR_TXFULL @
+ bne 1002b @ wait if FIFO is full
+ .endm
diff --git a/arch/arm/include/uapi/asm/Kbuild b/arch/arm/include/uapi/asm/Kbuild
new file mode 100644
index 000000000..a1c05f93d
--- /dev/null
+++ b/arch/arm/include/uapi/asm/Kbuild
@@ -0,0 +1,20 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += auxvec.h
+header-y += byteorder.h
+header-y += fcntl.h
+header-y += hwcap.h
+header-y += ioctls.h
+header-y += kvm_para.h
+header-y += mman.h
+header-y += perf_regs.h
+header-y += posix_types.h
+header-y += ptrace.h
+header-y += setup.h
+header-y += sigcontext.h
+header-y += signal.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += unistd.h
diff --git a/arch/arm/include/uapi/asm/auxvec.h b/arch/arm/include/uapi/asm/auxvec.h
new file mode 100644
index 000000000..cb02a767a
--- /dev/null
+++ b/arch/arm/include/uapi/asm/auxvec.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_AUXVEC_H
+#define __ASM_AUXVEC_H
+
+/* VDSO location */
+#define AT_SYSINFO_EHDR 33
+
+#endif
diff --git a/arch/arm/include/uapi/asm/byteorder.h b/arch/arm/include/uapi/asm/byteorder.h
new file mode 100644
index 000000000..77379748b
--- /dev/null
+++ b/arch/arm/include/uapi/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/uapi/asm/fcntl.h b/arch/arm/include/uapi/asm/fcntl.h
new file mode 100644
index 000000000..a80b6607b
--- /dev/null
+++ b/arch/arm/include/uapi/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/uapi/asm/hwcap.h b/arch/arm/include/uapi/asm/hwcap.h
new file mode 100644
index 000000000..20d12f230
--- /dev/null
+++ b/arch/arm/include/uapi/asm/hwcap.h
@@ -0,0 +1,40 @@
+#ifndef _UAPI__ASMARM_HWCAP_H
+#define _UAPI__ASMARM_HWCAP_H
+
+/*
+ * HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
+ */
+#define HWCAP_SWP (1 << 0)
+#define HWCAP_HALF (1 << 1)
+#define HWCAP_THUMB (1 << 2)
+#define HWCAP_26BIT (1 << 3) /* Play it safe */
+#define HWCAP_FAST_MULT (1 << 4)
+#define HWCAP_FPA (1 << 5)
+#define HWCAP_VFP (1 << 6)
+#define HWCAP_EDSP (1 << 7)
+#define HWCAP_JAVA (1 << 8)
+#define HWCAP_IWMMXT (1 << 9)
+#define HWCAP_CRUNCH (1 << 10)
+#define HWCAP_THUMBEE (1 << 11)
+#define HWCAP_NEON (1 << 12)
+#define HWCAP_VFPv3 (1 << 13)
+#define HWCAP_VFPv3D16 (1 << 14) /* also set for VFPv4-D16 */
+#define HWCAP_TLS (1 << 15)
+#define HWCAP_VFPv4 (1 << 16)
+#define HWCAP_IDIVA (1 << 17)
+#define HWCAP_IDIVT (1 << 18)
+#define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */
+#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
+#define HWCAP_LPAE (1 << 20)
+#define HWCAP_EVTSTRM (1 << 21)
+
+/*
+ * HWCAP2 flags - for elf_hwcap2 (in kernel) and AT_HWCAP2
+ */
+#define HWCAP2_AES (1 << 0)
+#define HWCAP2_PMULL (1 << 1)
+#define HWCAP2_SHA1 (1 << 2)
+#define HWCAP2_SHA2 (1 << 3)
+#define HWCAP2_CRC32 (1 << 4)
+
+#endif /* _UAPI__ASMARM_HWCAP_H */
diff --git a/arch/arm/include/uapi/asm/ioctls.h b/arch/arm/include/uapi/asm/ioctls.h
new file mode 100644
index 000000000..9c9629816
--- /dev/null
+++ b/arch/arm/include/uapi/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/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
new file mode 100644
index 000000000..df3f60cb1
--- /dev/null
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ARM_KVM_H__
+#define __ARM_KVM_H__
+
+#include <linux/types.h>
+#include <linux/psci.h>
+#include <asm/ptrace.h>
+
+#define __KVM_HAVE_GUEST_DEBUG
+#define __KVM_HAVE_IRQ_LINE
+#define __KVM_HAVE_READONLY_MEM
+
+#define KVM_REG_SIZE(id) \
+ (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
+
+/* Valid for svc_regs, abt_regs, und_regs, irq_regs in struct kvm_regs */
+#define KVM_ARM_SVC_sp svc_regs[0]
+#define KVM_ARM_SVC_lr svc_regs[1]
+#define KVM_ARM_SVC_spsr svc_regs[2]
+#define KVM_ARM_ABT_sp abt_regs[0]
+#define KVM_ARM_ABT_lr abt_regs[1]
+#define KVM_ARM_ABT_spsr abt_regs[2]
+#define KVM_ARM_UND_sp und_regs[0]
+#define KVM_ARM_UND_lr und_regs[1]
+#define KVM_ARM_UND_spsr und_regs[2]
+#define KVM_ARM_IRQ_sp irq_regs[0]
+#define KVM_ARM_IRQ_lr irq_regs[1]
+#define KVM_ARM_IRQ_spsr irq_regs[2]
+
+/* Valid only for fiq_regs in struct kvm_regs */
+#define KVM_ARM_FIQ_r8 fiq_regs[0]
+#define KVM_ARM_FIQ_r9 fiq_regs[1]
+#define KVM_ARM_FIQ_r10 fiq_regs[2]
+#define KVM_ARM_FIQ_fp fiq_regs[3]
+#define KVM_ARM_FIQ_ip fiq_regs[4]
+#define KVM_ARM_FIQ_sp fiq_regs[5]
+#define KVM_ARM_FIQ_lr fiq_regs[6]
+#define KVM_ARM_FIQ_spsr fiq_regs[7]
+
+struct kvm_regs {
+ struct pt_regs usr_regs; /* R0_usr - R14_usr, PC, CPSR */
+ unsigned long svc_regs[3]; /* SP_svc, LR_svc, SPSR_svc */
+ unsigned long abt_regs[3]; /* SP_abt, LR_abt, SPSR_abt */
+ unsigned long und_regs[3]; /* SP_und, LR_und, SPSR_und */
+ unsigned long irq_regs[3]; /* SP_irq, LR_irq, SPSR_irq */
+ unsigned long fiq_regs[8]; /* R8_fiq - R14_fiq, SPSR_fiq */
+};
+
+/* Supported Processor Types */
+#define KVM_ARM_TARGET_CORTEX_A15 0
+#define KVM_ARM_TARGET_CORTEX_A7 1
+#define KVM_ARM_NUM_TARGETS 2
+
+/* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */
+#define KVM_ARM_DEVICE_TYPE_SHIFT 0
+#define KVM_ARM_DEVICE_TYPE_MASK (0xffff << KVM_ARM_DEVICE_TYPE_SHIFT)
+#define KVM_ARM_DEVICE_ID_SHIFT 16
+#define KVM_ARM_DEVICE_ID_MASK (0xffff << KVM_ARM_DEVICE_ID_SHIFT)
+
+/* Supported device IDs */
+#define KVM_ARM_DEVICE_VGIC_V2 0
+
+/* Supported VGIC address types */
+#define KVM_VGIC_V2_ADDR_TYPE_DIST 0
+#define KVM_VGIC_V2_ADDR_TYPE_CPU 1
+
+#define KVM_VGIC_V2_DIST_SIZE 0x1000
+#define KVM_VGIC_V2_CPU_SIZE 0x2000
+
+#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
+#define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
+
+struct kvm_vcpu_init {
+ __u32 target;
+ __u32 features[7];
+};
+
+struct kvm_sregs {
+};
+
+struct kvm_fpu {
+};
+
+struct kvm_guest_debug_arch {
+};
+
+struct kvm_debug_exit_arch {
+};
+
+struct kvm_sync_regs {
+};
+
+struct kvm_arch_memory_slot {
+};
+
+/* If you need to interpret the index values, here is the key: */
+#define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000
+#define KVM_REG_ARM_COPROC_SHIFT 16
+#define KVM_REG_ARM_32_OPC2_MASK 0x0000000000000007
+#define KVM_REG_ARM_32_OPC2_SHIFT 0
+#define KVM_REG_ARM_OPC1_MASK 0x0000000000000078
+#define KVM_REG_ARM_OPC1_SHIFT 3
+#define KVM_REG_ARM_CRM_MASK 0x0000000000000780
+#define KVM_REG_ARM_CRM_SHIFT 7
+#define KVM_REG_ARM_32_CRN_MASK 0x0000000000007800
+#define KVM_REG_ARM_32_CRN_SHIFT 11
+
+#define ARM_CP15_REG_SHIFT_MASK(x,n) \
+ (((x) << KVM_REG_ARM_ ## n ## _SHIFT) & KVM_REG_ARM_ ## n ## _MASK)
+
+#define __ARM_CP15_REG(op1,crn,crm,op2) \
+ (KVM_REG_ARM | (15 << KVM_REG_ARM_COPROC_SHIFT) | \
+ ARM_CP15_REG_SHIFT_MASK(op1, OPC1) | \
+ ARM_CP15_REG_SHIFT_MASK(crn, 32_CRN) | \
+ ARM_CP15_REG_SHIFT_MASK(crm, CRM) | \
+ ARM_CP15_REG_SHIFT_MASK(op2, 32_OPC2))
+
+#define ARM_CP15_REG32(...) (__ARM_CP15_REG(__VA_ARGS__) | KVM_REG_SIZE_U32)
+
+#define __ARM_CP15_REG64(op1,crm) \
+ (__ARM_CP15_REG(op1, 0, crm, 0) | KVM_REG_SIZE_U64)
+#define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__)
+
+#define KVM_REG_ARM_TIMER_CTL ARM_CP15_REG32(0, 14, 3, 1)
+#define KVM_REG_ARM_TIMER_CNT ARM_CP15_REG64(1, 14)
+#define KVM_REG_ARM_TIMER_CVAL ARM_CP15_REG64(3, 14)
+
+/* Normal registers are mapped as coprocessor 16. */
+#define KVM_REG_ARM_CORE (0x0010 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_CORE_REG(name) (offsetof(struct kvm_regs, name) / 4)
+
+/* Some registers need more space to represent values. */
+#define KVM_REG_ARM_DEMUX (0x0011 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_DEMUX_ID_MASK 0x000000000000FF00
+#define KVM_REG_ARM_DEMUX_ID_SHIFT 8
+#define KVM_REG_ARM_DEMUX_ID_CCSIDR (0x00 << KVM_REG_ARM_DEMUX_ID_SHIFT)
+#define KVM_REG_ARM_DEMUX_VAL_MASK 0x00000000000000FF
+#define KVM_REG_ARM_DEMUX_VAL_SHIFT 0
+
+/* VFP registers: we could overload CP10 like ARM does, but that's ugly. */
+#define KVM_REG_ARM_VFP (0x0012 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_VFP_MASK 0x000000000000FFFF
+#define KVM_REG_ARM_VFP_BASE_REG 0x0
+#define KVM_REG_ARM_VFP_FPSID 0x1000
+#define KVM_REG_ARM_VFP_FPSCR 0x1001
+#define KVM_REG_ARM_VFP_MVFR1 0x1006
+#define KVM_REG_ARM_VFP_MVFR0 0x1007
+#define KVM_REG_ARM_VFP_FPEXC 0x1008
+#define KVM_REG_ARM_VFP_FPINST 0x1009
+#define KVM_REG_ARM_VFP_FPINST2 0x100A
+
+/* Device Control API: ARM VGIC */
+#define KVM_DEV_ARM_VGIC_GRP_ADDR 0
+#define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
+#define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2
+#define KVM_DEV_ARM_VGIC_CPUID_SHIFT 32
+#define KVM_DEV_ARM_VGIC_CPUID_MASK (0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT)
+#define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0
+#define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
+#define KVM_DEV_ARM_VGIC_GRP_NR_IRQS 3
+#define KVM_DEV_ARM_VGIC_GRP_CTRL 4
+#define KVM_DEV_ARM_VGIC_CTRL_INIT 0
+
+/* KVM_IRQ_LINE irq field index values */
+#define KVM_ARM_IRQ_TYPE_SHIFT 24
+#define KVM_ARM_IRQ_TYPE_MASK 0xff
+#define KVM_ARM_IRQ_VCPU_SHIFT 16
+#define KVM_ARM_IRQ_VCPU_MASK 0xff
+#define KVM_ARM_IRQ_NUM_SHIFT 0
+#define KVM_ARM_IRQ_NUM_MASK 0xffff
+
+/* irq_type field */
+#define KVM_ARM_IRQ_TYPE_CPU 0
+#define KVM_ARM_IRQ_TYPE_SPI 1
+#define KVM_ARM_IRQ_TYPE_PPI 2
+
+/* out-of-kernel GIC cpu interrupt injection irq_number field */
+#define KVM_ARM_IRQ_CPU_IRQ 0
+#define KVM_ARM_IRQ_CPU_FIQ 1
+
+/*
+ * This used to hold the highest supported SPI, but it is now obsolete
+ * and only here to provide source code level compatibility with older
+ * userland. The highest SPI number can be set via KVM_DEV_ARM_VGIC_GRP_NR_IRQS.
+ */
+#ifndef __KERNEL__
+#define KVM_ARM_IRQ_GIC_MAX 127
+#endif
+
+/* One single KVM irqchip, ie. the VGIC */
+#define KVM_NR_IRQCHIPS 1
+
+/* PSCI interface */
+#define KVM_PSCI_FN_BASE 0x95c1ba5e
+#define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
+
+#define KVM_PSCI_FN_CPU_SUSPEND KVM_PSCI_FN(0)
+#define KVM_PSCI_FN_CPU_OFF KVM_PSCI_FN(1)
+#define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
+#define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
+
+#define KVM_PSCI_RET_SUCCESS PSCI_RET_SUCCESS
+#define KVM_PSCI_RET_NI PSCI_RET_NOT_SUPPORTED
+#define KVM_PSCI_RET_INVAL PSCI_RET_INVALID_PARAMS
+#define KVM_PSCI_RET_DENIED PSCI_RET_DENIED
+
+#endif /* __ARM_KVM_H__ */
diff --git a/arch/arm/include/uapi/asm/kvm_para.h b/arch/arm/include/uapi/asm/kvm_para.h
new file mode 100644
index 000000000..14fab8f0b
--- /dev/null
+++ b/arch/arm/include/uapi/asm/kvm_para.h
@@ -0,0 +1 @@
+#include <asm-generic/kvm_para.h>
diff --git a/arch/arm/include/uapi/asm/mman.h b/arch/arm/include/uapi/asm/mman.h
new file mode 100644
index 000000000..41f99c573
--- /dev/null
+++ b/arch/arm/include/uapi/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/uapi/asm/perf_regs.h b/arch/arm/include/uapi/asm/perf_regs.h
new file mode 100644
index 000000000..ce5944845
--- /dev/null
+++ b/arch/arm/include/uapi/asm/perf_regs.h
@@ -0,0 +1,23 @@
+#ifndef _ASM_ARM_PERF_REGS_H
+#define _ASM_ARM_PERF_REGS_H
+
+enum perf_event_arm_regs {
+ PERF_REG_ARM_R0,
+ PERF_REG_ARM_R1,
+ PERF_REG_ARM_R2,
+ PERF_REG_ARM_R3,
+ PERF_REG_ARM_R4,
+ PERF_REG_ARM_R5,
+ PERF_REG_ARM_R6,
+ PERF_REG_ARM_R7,
+ PERF_REG_ARM_R8,
+ PERF_REG_ARM_R9,
+ PERF_REG_ARM_R10,
+ PERF_REG_ARM_FP,
+ PERF_REG_ARM_IP,
+ PERF_REG_ARM_SP,
+ PERF_REG_ARM_LR,
+ PERF_REG_ARM_PC,
+ PERF_REG_ARM_MAX,
+};
+#endif /* _ASM_ARM_PERF_REGS_H */
diff --git a/arch/arm/include/uapi/asm/posix_types.h b/arch/arm/include/uapi/asm/posix_types.h
new file mode 100644
index 000000000..d2de9cbbc
--- /dev/null
+++ b/arch/arm/include/uapi/asm/posix_types.h
@@ -0,0 +1,37 @@
+/*
+ * 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 short __kernel_mode_t;
+#define __kernel_mode_t __kernel_mode_t
+
+typedef unsigned short __kernel_ipc_pid_t;
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
+
+typedef unsigned short __kernel_uid_t;
+typedef unsigned short __kernel_gid_t;
+#define __kernel_uid_t __kernel_uid_t
+
+typedef unsigned short __kernel_old_dev_t;
+#define __kernel_old_dev_t __kernel_old_dev_t
+
+#include <asm-generic/posix_types.h>
+
+#endif
diff --git a/arch/arm/include/uapi/asm/ptrace.h b/arch/arm/include/uapi/asm/ptrace.h
new file mode 100644
index 000000000..5af0ed1b8
--- /dev/null
+++ b/arch/arm/include/uapi/asm/ptrace.h
@@ -0,0 +1,157 @@
+/*
+ * 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 _UAPI__ASM_ARM_PTRACE_H
+#define _UAPI__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
+ * Note on V7M there is no mode contained in the PSR
+ */
+#define USR26_MODE 0x00000000
+#define FIQ26_MODE 0x00000001
+#define IRQ26_MODE 0x00000002
+#define SVC26_MODE 0x00000003
+#if defined(__KERNEL__) && defined(CONFIG_CPU_V7M)
+/*
+ * Use 0 here to get code right that creates a userspace
+ * or kernel space thread.
+ */
+#define USR_MODE 0x00000000
+#define SVC_MODE 0x00000000
+#else
+#define USR_MODE 0x00000010
+#define SVC_MODE 0x00000013
+#endif
+#define FIQ_MODE 0x00000011
+#define IRQ_MODE 0x00000012
+#define ABT_MODE 0x00000017
+#define HYP_MODE 0x0000001a
+#define UND_MODE 0x0000001b
+#define SYSTEM_MODE 0x0000001f
+#define MODE32_BIT 0x00000010
+#define MODE_MASK 0x0000001f
+
+#define V4_PSR_T_BIT 0x00000020 /* >= V4T, but not V7M */
+#define V7M_PSR_T_BIT 0x01000000
+#if defined(__KERNEL__) && defined(CONFIG_CPU_V7M)
+#define PSR_T_BIT V7M_PSR_T_BIT
+#else
+/* for compatibility */
+#define PSR_T_BIT V4_PSR_T_BIT
+#endif
+
+#define PSR_F_BIT 0x00000040 /* >= V4, but not V7M */
+#define PSR_I_BIT 0x00000080 /* >= V4, but not V7M */
+#define PSR_A_BIT 0x00000100 /* >= V6, but not V7M */
+#define PSR_E_BIT 0x00000200 /* >= V6, but not V7M */
+#define PSR_J_BIT 0x01000000 /* >= V5J, but not V7M */
+#define PSR_Q_BIT 0x08000000 /* >= V5E, including V7M */
+#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 PSR bits
+ */
+#define APSR_MASK 0xf80f0000 /* N, Z, C, V, Q and GE flags */
+#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];
+};
+#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*/ )
+
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _UAPI__ASM_ARM_PTRACE_H */
diff --git a/arch/arm/include/uapi/asm/setup.h b/arch/arm/include/uapi/asm/setup.h
new file mode 100644
index 000000000..979ff4016
--- /dev/null
+++ b/arch/arm/include/uapi/asm/setup.h
@@ -0,0 +1,187 @@
+/*
+ * 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 _UAPI__ASMARM_SETUP_H
+#define _UAPI__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))
+
+
+#endif /* _UAPI__ASMARM_SETUP_H */
diff --git a/arch/arm/include/uapi/asm/sigcontext.h b/arch/arm/include/uapi/asm/sigcontext.h
new file mode 100644
index 000000000..fc0b80b6a
--- /dev/null
+++ b/arch/arm/include/uapi/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/uapi/asm/signal.h b/arch/arm/include/uapi/asm/signal.h
new file mode 100644
index 000000000..33073bdcf
--- /dev/null
+++ b/arch/arm/include/uapi/asm/signal.h
@@ -0,0 +1,120 @@
+#ifndef _UAPI_ASMARM_SIGNAL_H
+#define _UAPI_ASMARM_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems. */
+struct siginfo;
+
+#ifndef __KERNEL__
+/* 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
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
+#include <asm-generic/signal-defs.h>
+
+#ifndef __KERNEL__
+/* 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;
+
+
+#endif /* _UAPI_ASMARM_SIGNAL_H */
diff --git a/arch/arm/include/uapi/asm/stat.h b/arch/arm/include/uapi/asm/stat.h
new file mode 100644
index 000000000..42c0c1399
--- /dev/null
+++ b/arch/arm/include/uapi/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/uapi/asm/statfs.h b/arch/arm/include/uapi/asm/statfs.h
new file mode 100644
index 000000000..079447c05
--- /dev/null
+++ b/arch/arm/include/uapi/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/uapi/asm/swab.h b/arch/arm/include/uapi/asm/swab.h
new file mode 100644
index 000000000..6fcb32a5c
--- /dev/null
+++ b/arch/arm/include/uapi/asm/swab.h
@@ -0,0 +1,53 @@
+/*
+ * 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 _UAPI__ASM_ARM_SWAB_H
+#define _UAPI__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__ __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 /* _UAPI__ASM_ARM_SWAB_H */
diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h
new file mode 100644
index 000000000..0c3f5a0da
--- /dev/null
+++ b/arch/arm/include/uapi/asm/unistd.h
@@ -0,0 +1,448 @@
+/*
+ * 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 _UAPI__ASM_ARM_UNISTD_H
+#define _UAPI__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)
+#define __NR_process_vm_readv (__NR_SYSCALL_BASE+376)
+#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377)
+#define __NR_kcmp (__NR_SYSCALL_BASE+378)
+#define __NR_finit_module (__NR_SYSCALL_BASE+379)
+#define __NR_sched_setattr (__NR_SYSCALL_BASE+380)
+#define __NR_sched_getattr (__NR_SYSCALL_BASE+381)
+#define __NR_renameat2 (__NR_SYSCALL_BASE+382)
+#define __NR_seccomp (__NR_SYSCALL_BASE+383)
+#define __NR_getrandom (__NR_SYSCALL_BASE+384)
+#define __NR_memfd_create (__NR_SYSCALL_BASE+385)
+#define __NR_bpf (__NR_SYSCALL_BASE+386)
+#define __NR_execveat (__NR_SYSCALL_BASE+387)
+
+/*
+ * 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)
+
+/*
+ * The following syscalls are obsolete and no longer available for EABI.
+ */
+#if !defined(__KERNEL__)
+#if defined(__ARM_EABI__)
+#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
+#endif
+
+#endif /* _UAPI__ASM_ARM_UNISTD_H */
diff --git a/arch/arm/kernel/.gitignore b/arch/arm/kernel/.gitignore
new file mode 100644
index 000000000..c5f676c3c
--- /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 000000000..752725dcb
--- /dev/null
+++ b/arch/arm/kernel/Makefile
@@ -0,0 +1,93 @@
+#
+# 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
+CFLAGS_REMOVE_insn.o = -pg
+CFLAGS_REMOVE_patch.o = -pg
+endif
+
+CFLAGS_REMOVE_return_address.o = -pg
+
+# Object file lists.
+
+obj-y := elf.o entry-common.o irq.o opcodes.o \
+ process.o ptrace.o reboot.o return_address.o \
+ setup.o signal.o sigreturn_codes.o \
+ stacktrace.o sys_arm.o time.o traps.o
+
+obj-$(CONFIG_ATAGS) += atags_parse.o
+obj-$(CONFIG_ATAGS_PROC) += atags_proc.o
+obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o
+
+ifeq ($(CONFIG_CPU_V7M),y)
+obj-y += entry-v7m.o v7m.o
+else
+obj-y += entry-armv.o
+endif
+
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
+obj-$(CONFIG_ISA_DMA_API) += dma.o
+obj-$(CONFIG_FIQ) += fiq.o fiqasm.o
+obj-$(CONFIG_MODULES) += armksyms.o module.o
+obj-$(CONFIG_ISA_DMA) += dma-isa.o
+obj-$(CONFIG_PCI) += bios32.o isa.o
+obj-$(CONFIG_ARM_CPU_SUSPEND) += sleep.o suspend.o
+obj-$(CONFIG_HIBERNATION) += hibernate.o
+obj-$(CONFIG_SMP) += smp.o
+ifdef CONFIG_MMU
+obj-$(CONFIG_SMP) += smp_tlb.o
+endif
+obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
+obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
+obj-$(CONFIG_ARM_ARCH_TIMER) += arch_timer.o
+obj-$(CONFIG_FUNCTION_TRACER) += entry-ftrace.o
+obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o
+obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o
+obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
+# Main staffs in KPROBES are in arch/arm/probes/ .
+obj-$(CONFIG_KPROBES) += patch.o insn.o
+obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
+obj-$(CONFIG_ARM_THUMBEE) += thumbee.o
+obj-$(CONFIG_KGDB) += kgdb.o patch.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_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_CPU_PJ4B) += pj4-cp0.o
+obj-$(CONFIG_IWMMXT) += iwmmxt.o
+obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
+obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o perf_event_cpu.o
+CFLAGS_pj4-cp0.o := -marm
+AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
+obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
+obj-$(CONFIG_VDSO) += vdso.o
+
+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
+
+obj-$(CONFIG_ARM_VIRT_EXT) += hyp-stub.o
+ifeq ($(CONFIG_ARM_PSCI),y)
+obj-y += psci.o psci-call.o
+obj-$(CONFIG_SMP) += psci_smp.o
+endif
+
+extra-y := $(head-y) vmlinux.lds
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
new file mode 100644
index 000000000..1791f12c1
--- /dev/null
+++ b/arch/arm/kernel/arch_timer.c
@@ -0,0 +1,44 @@
+/*
+ * linux/arch/arm/kernel/arch_timer.c
+ *
+ * Copyright (C) 2011 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/types.h>
+#include <linux/errno.h>
+
+#include <asm/delay.h>
+
+#include <clocksource/arm_arch_timer.h>
+
+static unsigned long arch_timer_read_counter_long(void)
+{
+ return arch_timer_read_counter();
+}
+
+static struct delay_timer arch_delay_timer;
+
+static void __init arch_timer_delay_timer_register(void)
+{
+ /* Use the architected timer for the delay loop. */
+ arch_delay_timer.read_current_timer = arch_timer_read_counter_long;
+ arch_delay_timer.freq = arch_timer_get_rate();
+ register_current_timer_delay(&arch_delay_timer);
+}
+
+int __init arch_timer_arch_init(void)
+{
+ u32 arch_timer_rate = arch_timer_get_rate();
+
+ if (arch_timer_rate == 0)
+ return -ENXIO;
+
+ arch_timer_delay_timer_register();
+
+ return 0;
+}
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
new file mode 100644
index 000000000..a88671cfe
--- /dev/null
+++ b/arch/arm/kernel/armksyms.c
@@ -0,0 +1,171 @@
+/*
+ * 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/export.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/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 __bswapsi2(void);
+extern void __bswapdi2(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);
+
+ /* platform dependent support */
+EXPORT_SYMBOL(arm_delay_ops);
+
+ /* 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);
+
+#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(__get_user_8);
+
+#ifdef __ARMEB__
+EXPORT_SYMBOL(__get_user_64t_1);
+EXPORT_SYMBOL(__get_user_64t_2);
+EXPORT_SYMBOL(__get_user_64t_4);
+EXPORT_SYMBOL(__get_user_32t_8);
+#endif
+
+EXPORT_SYMBOL(__put_user_1);
+EXPORT_SYMBOL(__put_user_2);
+EXPORT_SYMBOL(__put_user_4);
+EXPORT_SYMBOL(__put_user_8);
+#endif
+
+ /* 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);
+EXPORT_SYMBOL(__bswapsi2);
+EXPORT_SYMBOL(__bswapdi2);
+
+#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_pfn_offset);
+EXPORT_SYMBOL(__pv_offset);
+#endif
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
new file mode 100644
index 000000000..871b8267d
--- /dev/null
+++ b/arch/arm/kernel/asm-offsets.c
@@ -0,0 +1,214 @@
+/*
+ * 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/compiler.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#ifdef CONFIG_KVM_ARM_HOST
+#include <linux/kvm_host.h>
+#endif
+#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 <asm/suspend.h>
+#include <asm/vdso_datapage.h>
+#include <asm/hardware/cache-l2x0.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
+ * GCC 4.8.0-4.8.2: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58854
+ * miscompiles find_get_entry(), and can result in EXT3 and EXT4
+ * filesystem corruption (possibly other FS too).
+ */
+#ifdef __GNUC__
+#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
+#error Your compiler is too buggy; it is known to miscompile kernels.
+#error Known good compilers: 3.3, 4.x
+#endif
+#if GCC_VERSION >= 40800 && GCC_VERSION < 40803
+#error Your compiler is too buggy; it is known to miscompile kernels
+#error and result in filesystem corruption and oopses.
+#endif
+#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_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));
+#ifdef CONFIG_VFP
+ DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate));
+#ifdef CONFIG_SMP
+ DEFINE(VFP_CPU, offsetof(union vfp_state, hard.cpu));
+#endif
+#endif
+#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_CACHE_L2X0
+ DEFINE(L2X0_R_PHY_BASE, offsetof(struct l2x0_regs, phy_base));
+ DEFINE(L2X0_R_AUX_CTRL, offsetof(struct l2x0_regs, aux_ctrl));
+ DEFINE(L2X0_R_TAG_LATENCY, offsetof(struct l2x0_regs, tag_latency));
+ DEFINE(L2X0_R_DATA_LATENCY, offsetof(struct l2x0_regs, data_latency));
+ DEFINE(L2X0_R_FILTER_START, offsetof(struct l2x0_regs, filter_start));
+ DEFINE(L2X0_R_FILTER_END, offsetof(struct l2x0_regs, filter_end));
+ DEFINE(L2X0_R_PREFETCH_CTRL, offsetof(struct l2x0_regs, prefetch_ctrl));
+ DEFINE(L2X0_R_PWR_CTRL, offsetof(struct l2x0_regs, pwr_ctrl));
+ BLANK();
+#endif
+#ifdef CONFIG_CPU_HAS_ASID
+ DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id.counter));
+ 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
+#ifdef CONFIG_ARM_CPU_SUSPEND
+ DEFINE(SLEEP_SAVE_SP_SZ, sizeof(struct sleep_save_sp));
+ DEFINE(SLEEP_SAVE_SP_PHYS, offsetof(struct sleep_save_sp, save_ptr_stash_phys));
+ DEFINE(SLEEP_SAVE_SP_VIRT, offsetof(struct sleep_save_sp, save_ptr_stash));
+#endif
+ BLANK();
+ DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL);
+ DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE);
+ DEFINE(DMA_FROM_DEVICE, DMA_FROM_DEVICE);
+ BLANK();
+ DEFINE(CACHE_WRITEBACK_ORDER, __CACHE_WRITEBACK_ORDER);
+ DEFINE(CACHE_WRITEBACK_GRANULE, __CACHE_WRITEBACK_GRANULE);
+ BLANK();
+#ifdef CONFIG_KVM_ARM_HOST
+ DEFINE(VCPU_KVM, offsetof(struct kvm_vcpu, kvm));
+ DEFINE(VCPU_MIDR, offsetof(struct kvm_vcpu, arch.midr));
+ DEFINE(VCPU_CP15, offsetof(struct kvm_vcpu, arch.cp15));
+ DEFINE(VCPU_VFP_GUEST, offsetof(struct kvm_vcpu, arch.vfp_guest));
+ DEFINE(VCPU_VFP_HOST, offsetof(struct kvm_vcpu, arch.host_cpu_context));
+ DEFINE(VCPU_REGS, offsetof(struct kvm_vcpu, arch.regs));
+ DEFINE(VCPU_USR_REGS, offsetof(struct kvm_vcpu, arch.regs.usr_regs));
+ DEFINE(VCPU_SVC_REGS, offsetof(struct kvm_vcpu, arch.regs.svc_regs));
+ DEFINE(VCPU_ABT_REGS, offsetof(struct kvm_vcpu, arch.regs.abt_regs));
+ DEFINE(VCPU_UND_REGS, offsetof(struct kvm_vcpu, arch.regs.und_regs));
+ DEFINE(VCPU_IRQ_REGS, offsetof(struct kvm_vcpu, arch.regs.irq_regs));
+ DEFINE(VCPU_FIQ_REGS, offsetof(struct kvm_vcpu, arch.regs.fiq_regs));
+ DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.regs.usr_regs.ARM_pc));
+ DEFINE(VCPU_CPSR, offsetof(struct kvm_vcpu, arch.regs.usr_regs.ARM_cpsr));
+ DEFINE(VCPU_HCR, offsetof(struct kvm_vcpu, arch.hcr));
+ DEFINE(VCPU_IRQ_LINES, offsetof(struct kvm_vcpu, arch.irq_lines));
+ DEFINE(VCPU_HSR, offsetof(struct kvm_vcpu, arch.fault.hsr));
+ DEFINE(VCPU_HxFAR, offsetof(struct kvm_vcpu, arch.fault.hxfar));
+ DEFINE(VCPU_HPFAR, offsetof(struct kvm_vcpu, arch.fault.hpfar));
+ DEFINE(VCPU_HYP_PC, offsetof(struct kvm_vcpu, arch.fault.hyp_pc));
+ DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu));
+ DEFINE(VGIC_V2_CPU_HCR, offsetof(struct vgic_cpu, vgic_v2.vgic_hcr));
+ DEFINE(VGIC_V2_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v2.vgic_vmcr));
+ DEFINE(VGIC_V2_CPU_MISR, offsetof(struct vgic_cpu, vgic_v2.vgic_misr));
+ DEFINE(VGIC_V2_CPU_EISR, offsetof(struct vgic_cpu, vgic_v2.vgic_eisr));
+ DEFINE(VGIC_V2_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_v2.vgic_elrsr));
+ DEFINE(VGIC_V2_CPU_APR, offsetof(struct vgic_cpu, vgic_v2.vgic_apr));
+ DEFINE(VGIC_V2_CPU_LR, offsetof(struct vgic_cpu, vgic_v2.vgic_lr));
+ DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr));
+ DEFINE(VCPU_TIMER_CNTV_CTL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl));
+ DEFINE(VCPU_TIMER_CNTV_CVAL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_cval));
+ DEFINE(KVM_TIMER_CNTVOFF, offsetof(struct kvm, arch.timer.cntvoff));
+ DEFINE(KVM_TIMER_ENABLED, offsetof(struct kvm, arch.timer.enabled));
+ DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base));
+ DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr));
+#endif
+ BLANK();
+#ifdef CONFIG_VDSO
+ DEFINE(VDSO_DATA_SIZE, sizeof(union vdso_data_store));
+#endif
+ return 0;
+}
diff --git a/arch/arm/kernel/atags.h b/arch/arm/kernel/atags.h
new file mode 100644
index 000000000..ec4164da6
--- /dev/null
+++ b/arch/arm/kernel/atags.h
@@ -0,0 +1,20 @@
+#ifdef CONFIG_ATAGS_PROC
+extern void save_atags(struct tag *tags);
+#else
+static inline void save_atags(struct tag *tags) { }
+#endif
+
+void convert_to_tag_list(struct tag *tags);
+
+#ifdef CONFIG_ATAGS
+const struct machine_desc *setup_machine_tags(phys_addr_t __atags_pointer,
+ unsigned int machine_nr);
+#else
+static inline const struct machine_desc *
+setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr)
+{
+ early_print("no ATAGS support: can't continue\n");
+ while (true);
+ unreachable();
+}
+#endif
diff --git a/arch/arm/kernel/atags_compat.c b/arch/arm/kernel/atags_compat.c
new file mode 100644
index 000000000..05c28b123
--- /dev/null
+++ b/arch/arm/kernel/atags_compat.c
@@ -0,0 +1,217 @@
+/*
+ * linux/arch/arm/kernel/atags_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 "atags.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) {
+ pr_warn("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) {
+ pr_warn("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/atags_parse.c b/arch/arm/kernel/atags_parse.c
new file mode 100644
index 000000000..68c6ae0b9
--- /dev/null
+++ b/arch/arm/kernel/atags_parse.c
@@ -0,0 +1,238 @@
+/*
+ * Tag parsing.
+ *
+ * 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.
+ */
+
+/*
+ * This is the traditional 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).
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/root_dev.h>
+#include <linux/screen_info.h>
+#include <linux/memblock.h>
+
+#include <asm/setup.h>
+#include <asm/system_info.h>
+#include <asm/page.h>
+#include <asm/mach/arch.h>
+
+#include "atags.h"
+
+static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
+
+#ifndef MEM_SIZE
+#define MEM_SIZE (16*1024*1024)
+#endif
+
+static struct {
+ struct tag_header hdr1;
+ struct tag_core core;
+ struct tag_header hdr2;
+ struct tag_mem32 mem;
+ struct tag_header hdr3;
+} default_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 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)
+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
+
+#ifdef CONFIG_BLK_DEV_RAM
+static int __init parse_tag_ramdisk(const struct tag *tag)
+{
+ extern int rd_size, rd_image_start, rd_prompt, rd_doload;
+
+ rd_image_start = tag->u.ramdisk.start;
+ rd_doload = (tag->u.ramdisk.flags & 1) == 0;
+ rd_prompt = (tag->u.ramdisk.flags & 2) == 0;
+
+ if (tag->u.ramdisk.size)
+ rd_size = tag->u.ramdisk.size;
+
+ return 0;
+}
+
+__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
+#endif
+
+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_warn("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))
+ pr_warn("Ignoring unrecognised tag 0x%08x\n",
+ t->hdr.tag);
+}
+
+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;
+}
+
+const struct machine_desc * __init
+setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr)
+{
+ struct tag *tags = (struct tag *)&default_tags;
+ const struct machine_desc *mdesc = NULL, *p;
+ char *from = default_command_line;
+
+ default_tags.mem.start = PHYS_OFFSET;
+
+ /*
+ * locate machine in the list of supported machines.
+ */
+ for_each_machine_desc(p)
+ if (machine_nr == p->nr) {
+ pr_info("Machine: %s\n", p->name);
+ mdesc = p;
+ break;
+ }
+
+ if (!mdesc) {
+ early_print("\nError: unrecognized/unsupported machine ID"
+ " (r1 = 0x%08x).\n\n", machine_nr);
+ dump_machine_table(); /* does not return */
+ }
+
+ if (__atags_pointer)
+ tags = phys_to_virt(__atags_pointer);
+ else if (mdesc->atag_offset)
+ tags = (void *)(PAGE_OFFSET + mdesc->atag_offset);
+
+#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) {
+ early_print("Warning: Neither atags nor dtb found\n");
+ tags = (struct tag *)&default_tags;
+ }
+
+ if (mdesc->fixup)
+ mdesc->fixup(tags, &from);
+
+ if (tags->hdr.tag == ATAG_CORE) {
+ if (memblock_phys_mem_size())
+ 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;
+}
diff --git a/arch/arm/kernel/atags_proc.c b/arch/arm/kernel/atags_proc.c
new file mode 100644
index 000000000..5a3379055
--- /dev/null
+++ b/arch/arm/kernel/atags_proc.c
@@ -0,0 +1,75 @@
+#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 ssize_t atags_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct buffer *b = PDE_DATA(file_inode(file));
+ return simple_read_from_buffer(buf, count, ppos, b->data, b->size);
+}
+
+static const struct file_operations atags_fops = {
+ .read = atags_read,
+ .llseek = default_llseek,
+};
+
+#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) {
+ pr_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 = proc_create_data("atags", 0400, NULL, &atags_fops, b);
+ if (!tags_entry)
+ goto nomem;
+
+ return 0;
+
+nomem:
+ kfree(b);
+ pr_err("Exporting ATAGs: not enough memory\n");
+
+ return -ENOMEM;
+}
+arch_initcall(init_atags_procfs);
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
new file mode 100644
index 000000000..fcbbbb1b9
--- /dev/null
+++ b/arch/arm/kernel/bios32.c
@@ -0,0 +1,647 @@
+/*
+ * linux/arch/arm/kernel/bios32.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/export.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/map.h>
+#include <asm/mach/pci.h>
+
+static int debug_pci;
+
+#ifdef CONFIG_PCI_MSI
+struct msi_controller *pcibios_msi_controller(struct pci_dev *dev)
+{
+ struct pci_sys_data *sysdata = dev->bus->sysdata;
+
+ return sysdata->msi_ctrl;
+}
+#endif
+
+/*
+ * We can't use pci_get_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 pci_bus *bus;
+
+ list_for_each_entry(bus, &pci_root_buses, node)
+ 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 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 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 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 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 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 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 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);
+
+/*
+ * 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));
+
+}
+
+/*
+ * 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_dev *dev;
+ u16 features = PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_FAST_BACK;
+
+ /*
+ * 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;
+
+ 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
+ */
+ pr_info("PCI: bus%d: Fast back to back transfers %sabled\n",
+ bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
+}
+EXPORT_SYMBOL(pcibios_fixup_bus);
+
+/*
+ * Swizzle the device pin each time we cross a bridge. If a platform does
+ * not provide a swizzle function, we perform the standard PCI swizzling.
+ *
+ * The default swizzling walks up the bus tree one level at a time, applying
+ * the standard swizzle function at each step, stopping when it finds the PCI
+ * root bus. This will return the slot number of the bridge device on the
+ * root bus and the interrupt pin on that device which should correspond
+ * with the downstream device interrupt.
+ *
+ * Platforms may override this, in which case the slot and pin returned
+ * depend entirely on the platform code. However, please note that the
+ * PCI standard swizzle is implemented on plug-in cards and Cardbus based
+ * PCI extenders, so it can not be ignored.
+ */
+static u8 pcibios_swizzle(struct pci_dev *dev, u8 *pin)
+{
+ struct pci_sys_data *sys = dev->sysdata;
+ int slot, oldpin = *pin;
+
+ if (sys->swizzle)
+ slot = sys->swizzle(dev, pin);
+ else
+ slot = pci_common_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(const 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 int pcibios_init_resources(int busnr, struct pci_sys_data *sys)
+{
+ int ret;
+ struct resource_entry *window;
+
+ if (list_empty(&sys->resources)) {
+ pci_add_resource_offset(&sys->resources,
+ &iomem_resource, sys->mem_offset);
+ }
+
+ resource_list_for_each_entry(window, &sys->resources)
+ if (resource_type(window->res) == IORESOURCE_IO)
+ return 0;
+
+ sys->io_res.start = (busnr * SZ_64K) ? : pcibios_min_io;
+ sys->io_res.end = (busnr + 1) * SZ_64K - 1;
+ sys->io_res.flags = IORESOURCE_IO;
+ sys->io_res.name = sys->io_res_name;
+ sprintf(sys->io_res_name, "PCI%d I/O", busnr);
+
+ ret = request_resource(&ioport_resource, &sys->io_res);
+ if (ret) {
+ pr_err("PCI: unable to allocate I/O port region (%d)\n", ret);
+ return ret;
+ }
+ pci_add_resource_offset(&sys->resources, &sys->io_res,
+ sys->io_offset);
+
+ return 0;
+}
+
+static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
+ struct list_head *head)
+{
+ 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_MSI
+ sys->msi_ctrl = hw->msi_ctrl;
+#endif
+ sys->busnr = busnr;
+ sys->swizzle = hw->swizzle;
+ sys->map_irq = hw->map_irq;
+ sys->align_resource = hw->align_resource;
+ INIT_LIST_HEAD(&sys->resources);
+
+ if (hw->private_data)
+ sys->private_data = hw->private_data[nr];
+
+ ret = hw->setup(nr, sys);
+
+ if (ret > 0) {
+ ret = pcibios_init_resources(nr, sys);
+ if (ret) {
+ kfree(sys);
+ break;
+ }
+
+ if (hw->scan)
+ sys->bus = hw->scan(nr, sys);
+ else
+ sys->bus = pci_scan_root_bus(parent, sys->busnr,
+ hw->ops, sys, &sys->resources);
+
+ if (!sys->bus)
+ panic("PCI: unable to scan bus!");
+
+ busnr = sys->bus->busn_res.end + 1;
+
+ list_add(&sys->node, head);
+ } else {
+ kfree(sys);
+ if (ret < 0)
+ break;
+ }
+ }
+}
+
+void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
+{
+ struct pci_sys_data *sys;
+ LIST_HEAD(head);
+
+ pci_add_flags(PCI_REASSIGN_ALL_RSRC);
+ if (hw->preinit)
+ hw->preinit();
+ pcibios_init_hw(parent, hw, &head);
+ if (hw->postinit)
+ hw->postinit();
+
+ pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq);
+
+ list_for_each_entry(sys, &head, node) {
+ struct pci_bus *bus = sys->bus;
+
+ if (!pci_has_flag(PCI_PROBE_ONLY)) {
+ /*
+ * Size the bridge windows.
+ */
+ pci_bus_size_bridges(bus);
+
+ /*
+ * Assign resources.
+ */
+ pci_bus_assign_resources(bus);
+ }
+
+ /*
+ * Tell drivers about devices found.
+ */
+ pci_bus_add_devices(bus);
+ }
+
+ list_for_each_entry(sys, &head, node) {
+ struct pci_bus *bus = sys->bus;
+
+ /* Configure PCI Express settings */
+ if (bus && !pci_has_flag(PCI_PROBE_ONLY)) {
+ struct pci_bus *child;
+
+ list_for_each_entry(child, &bus->children, node)
+ pcie_bus_configure_settings(child);
+ }
+ }
+}
+
+#ifndef CONFIG_PCI_HOST_ITE8152
+void pcibios_set_master(struct pci_dev *dev)
+{
+ /* No special bus mastering setup handling */
+}
+#endif
+
+char * __init pcibios_setup(char *str)
+{
+ if (!strcmp(str, "debug")) {
+ debug_pci = 1;
+ return NULL;
+ } else if (!strcmp(str, "firmware")) {
+ pci_add_flags(PCI_PROBE_ONLY);
+ 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)
+{
+ struct pci_dev *dev = data;
+ struct pci_sys_data *sys = dev->sysdata;
+ resource_size_t start = res->start;
+
+ if (res->flags & IORESOURCE_IO && start & 0x300)
+ start = (start + 0x3ff) & ~0x3ff;
+
+ start = (start + align - 1) & ~(align - 1);
+
+ if (sys->align_resource)
+ return sys->align_resource(dev, res, start, size, align);
+
+ 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)
+{
+ if (pci_has_flag(PCI_PROBE_ONLY))
+ return 0;
+
+ return pci_enable_resources(dev, mask);
+}
+
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state, int write_combine)
+{
+ if (mmap_state == pci_mmap_io)
+ return -EINVAL;
+
+ /*
+ * Mark this as IO
+ */
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot))
+ return -EAGAIN;
+
+ return 0;
+}
+
+void __init pci_map_io_early(unsigned long pfn)
+{
+ struct map_desc pci_io_desc = {
+ .virtual = PCI_IO_VIRT_BASE,
+ .type = MT_DEVICE,
+ .length = SZ_64K,
+ };
+
+ pci_io_desc.pfn = pfn;
+ iotable_init(&pci_io_desc, 1);
+}
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
new file mode 100644
index 000000000..05745eb83
--- /dev/null
+++ b/arch/arm/kernel/calls.S
@@ -0,0 +1,406 @@
+/*
+ * 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)
+ 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)
+ 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)
+ 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_ni_syscall) /* was 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)
+ CALL(sys_sendfile)
+ CALL(sys_ni_syscall) /* getpmsg */
+ CALL(sys_ni_syscall) /* putpmsg */
+/* 190 */ CALL(sys_vfork)
+ 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)
+ CALL(sys_process_vm_readv)
+ CALL(sys_process_vm_writev)
+ CALL(sys_kcmp)
+ CALL(sys_finit_module)
+/* 380 */ CALL(sys_sched_setattr)
+ CALL(sys_sched_getattr)
+ CALL(sys_renameat2)
+ CALL(sys_seccomp)
+ CALL(sys_getrandom)
+/* 385 */ CALL(sys_memfd_create)
+ CALL(sys_bpf)
+ CALL(sys_execveat)
+#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/cpuidle.c b/arch/arm/kernel/cpuidle.c
new file mode 100644
index 000000000..318da3346
--- /dev/null
+++ b/arch/arm/kernel/cpuidle.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2012 Linaro Ltd.
+ *
+ * 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/cpuidle.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <asm/cpuidle.h>
+
+extern struct of_cpuidle_method __cpuidle_method_of_table[];
+
+static const struct of_cpuidle_method __cpuidle_method_of_table_sentinel
+ __used __section(__cpuidle_method_of_table_end);
+
+static struct cpuidle_ops cpuidle_ops[NR_CPUS];
+
+/**
+ * arm_cpuidle_simple_enter() - a wrapper to cpu_do_idle()
+ * @dev: not used
+ * @drv: not used
+ * @index: not used
+ *
+ * A trivial wrapper to allow the cpu_do_idle function to be assigned as a
+ * cpuidle callback by matching the function signature.
+ *
+ * Returns the index passed as parameter
+ */
+int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ cpu_do_idle();
+
+ return index;
+}
+
+/**
+ * arm_cpuidle_suspend() - function to enter low power idle states
+ * @index: an integer used as an identifier for the low level PM callbacks
+ *
+ * This function calls the underlying arch specific low level PM code as
+ * registered at the init time.
+ *
+ * Returns -EOPNOTSUPP if no suspend callback is defined, the result of the
+ * callback otherwise.
+ */
+int arm_cpuidle_suspend(int index)
+{
+ int ret = -EOPNOTSUPP;
+ int cpu = smp_processor_id();
+
+ if (cpuidle_ops[cpu].suspend)
+ ret = cpuidle_ops[cpu].suspend(cpu, index);
+
+ return ret;
+}
+
+/**
+ * arm_cpuidle_get_ops() - find a registered cpuidle_ops by name
+ * @method: the method name
+ *
+ * Search in the __cpuidle_method_of_table array the cpuidle ops matching the
+ * method name.
+ *
+ * Returns a struct cpuidle_ops pointer, NULL if not found.
+ */
+static struct cpuidle_ops *__init arm_cpuidle_get_ops(const char *method)
+{
+ struct of_cpuidle_method *m = __cpuidle_method_of_table;
+
+ for (; m->method; m++)
+ if (!strcmp(m->method, method))
+ return m->ops;
+
+ return NULL;
+}
+
+/**
+ * arm_cpuidle_read_ops() - Initialize the cpuidle ops with the device tree
+ * @dn: a pointer to a struct device node corresponding to a cpu node
+ * @cpu: the cpu identifier
+ *
+ * Get the method name defined in the 'enable-method' property, retrieve the
+ * associated cpuidle_ops and do a struct copy. This copy is needed because all
+ * cpuidle_ops are tagged __initdata and will be unloaded after the init
+ * process.
+ *
+ * Return 0 on sucess, -ENOENT if no 'enable-method' is defined, -EOPNOTSUPP if
+ * no cpuidle_ops is registered for the 'enable-method'.
+ */
+static int __init arm_cpuidle_read_ops(struct device_node *dn, int cpu)
+{
+ const char *enable_method;
+ struct cpuidle_ops *ops;
+
+ enable_method = of_get_property(dn, "enable-method", NULL);
+ if (!enable_method)
+ return -ENOENT;
+
+ ops = arm_cpuidle_get_ops(enable_method);
+ if (!ops) {
+ pr_warn("%s: unsupported enable-method property: %s\n",
+ dn->full_name, enable_method);
+ return -EOPNOTSUPP;
+ }
+
+ cpuidle_ops[cpu] = *ops; /* structure copy */
+
+ pr_notice("cpuidle: enable-method property '%s'"
+ " found operations\n", enable_method);
+
+ return 0;
+}
+
+/**
+ * arm_cpuidle_init() - Initialize cpuidle_ops for a specific cpu
+ * @cpu: the cpu to be initialized
+ *
+ * Initialize the cpuidle ops with the device for the cpu and then call
+ * the cpu's idle initialization callback. This may fail if the underlying HW
+ * is not operational.
+ *
+ * Returns:
+ * 0 on success,
+ * -ENODEV if it fails to find the cpu node in the device tree,
+ * -EOPNOTSUPP if it does not find a registered cpuidle_ops for this cpu,
+ * -ENOENT if it fails to find an 'enable-method' property,
+ * -ENXIO if the HW reports a failure or a misconfiguration,
+ * -ENOMEM if the HW report an memory allocation failure
+ */
+int __init arm_cpuidle_init(int cpu)
+{
+ struct device_node *cpu_node = of_cpu_device_node_get(cpu);
+ int ret;
+
+ if (!cpu_node)
+ return -ENODEV;
+
+ ret = arm_cpuidle_read_ops(cpu_node, cpu);
+ if (!ret && cpuidle_ops[cpu].init)
+ ret = cpuidle_ops[cpu].init(cpu_node, cpu);
+
+ of_node_put(cpu_node);
+
+ return ret;
+}
diff --git a/arch/arm/kernel/crash_dump.c b/arch/arm/kernel/crash_dump.c
new file mode 100644
index 000000000..5d1286d51
--- /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_to_phys(pfn), 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/debug.S b/arch/arm/kernel/debug.S
new file mode 100644
index 000000000..78c91b5f9
--- /dev/null
+++ b/arch/arm/kernel/debug.S
@@ -0,0 +1,138 @@
+/*
+ * 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>
+#include <asm/assembler.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_SEMIHOSTING)
+#include CONFIG_DEBUG_LL_INCLUDE
+#endif
+
+#ifdef CONFIG_MMU
+ .macro addruart_current, rx, tmp1, tmp2
+ addruart \tmp1, \tmp2, \rx
+ 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)
+
+hexbuf: .space 16
+
+ .ltorg
+
+#ifndef CONFIG_DEBUG_SEMIHOSTING
+
+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
+ ret lr
+ENDPROC(printascii)
+
+ENTRY(printch)
+ addruart_current r3, r1, r2
+ mov r1, r0
+ mov r0, #0
+ b 1b
+ENDPROC(printch)
+
+#ifdef CONFIG_MMU
+ENTRY(debug_ll_addr)
+ addruart r2, r3, ip
+ str r2, [r0]
+ str r3, [r1]
+ ret lr
+ENDPROC(debug_ll_addr)
+#endif
+
+#else
+
+ENTRY(printascii)
+ mov r1, r0
+ mov r0, #0x04 @ SYS_WRITE0
+ ARM( svc #0x123456 )
+ THUMB( svc #0xab )
+ ret lr
+ENDPROC(printascii)
+
+ENTRY(printch)
+ adr r1, hexbuf
+ strb r0, [r1]
+ mov r0, #0x03 @ SYS_WRITEC
+ ARM( svc #0x123456 )
+ THUMB( svc #0xab )
+ ret lr
+ENDPROC(printch)
+
+ENTRY(debug_ll_addr)
+ mov r2, #0
+ str r2, [r0]
+ str r2, [r1]
+ ret lr
+ENDPROC(debug_ll_addr)
+
+#endif
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
new file mode 100644
index 000000000..11c54de9f
--- /dev/null
+++ b/arch/arm/kernel/devtree.c
@@ -0,0 +1,250 @@
+/*
+ * 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/export.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 <linux/smp.h>
+
+#include <asm/cputype.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/smp_plat.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+
+#ifdef CONFIG_SMP
+extern struct of_cpu_method __cpu_method_of_table[];
+
+static const struct of_cpu_method __cpu_method_of_table_sentinel
+ __used __section(__cpu_method_of_table_end);
+
+
+static int __init set_smp_ops_by_method(struct device_node *node)
+{
+ const char *method;
+ struct of_cpu_method *m = __cpu_method_of_table;
+
+ if (of_property_read_string(node, "enable-method", &method))
+ return 0;
+
+ for (; m->method; m++)
+ if (!strcmp(m->method, method)) {
+ smp_set_ops(m->ops);
+ return 1;
+ }
+
+ return 0;
+}
+#else
+static inline int set_smp_ops_by_method(struct device_node *node)
+{
+ return 1;
+}
+#endif
+
+
+/*
+ * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree
+ * and builds the cpu logical map array containing MPIDR values related to
+ * logical cpus
+ *
+ * Updates the cpu possible mask with the number of parsed cpu nodes
+ */
+void __init arm_dt_init_cpu_maps(void)
+{
+ /*
+ * Temp logical map is initialized with UINT_MAX values that are
+ * considered invalid logical map entries since the logical map must
+ * contain a list of MPIDR[23:0] values where MPIDR[31:24] must
+ * read as 0.
+ */
+ struct device_node *cpu, *cpus;
+ int found_method = 0;
+ u32 i, j, cpuidx = 1;
+ u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;
+
+ u32 tmp_map[NR_CPUS] = { [0 ... NR_CPUS-1] = MPIDR_INVALID };
+ bool bootcpu_valid = false;
+ cpus = of_find_node_by_path("/cpus");
+
+ if (!cpus)
+ return;
+
+ for_each_child_of_node(cpus, cpu) {
+ u32 hwid;
+
+ if (of_node_cmp(cpu->type, "cpu"))
+ continue;
+
+ pr_debug(" * %s...\n", cpu->full_name);
+ /*
+ * A device tree containing CPU nodes with missing "reg"
+ * properties is considered invalid to build the
+ * cpu_logical_map.
+ */
+ if (of_property_read_u32(cpu, "reg", &hwid)) {
+ pr_debug(" * %s missing reg property\n",
+ cpu->full_name);
+ return;
+ }
+
+ /*
+ * 8 MSBs must be set to 0 in the DT since the reg property
+ * defines the MPIDR[23:0].
+ */
+ if (hwid & ~MPIDR_HWID_BITMASK)
+ return;
+
+ /*
+ * Duplicate MPIDRs are a recipe for disaster.
+ * Scan all initialized entries and check for
+ * duplicates. If any is found just bail out.
+ * temp values were initialized to UINT_MAX
+ * to avoid matching valid MPIDR[23:0] values.
+ */
+ for (j = 0; j < cpuidx; j++)
+ if (WARN(tmp_map[j] == hwid, "Duplicate /cpu reg "
+ "properties in the DT\n"))
+ return;
+
+ /*
+ * Build a stashed array of MPIDR values. Numbering scheme
+ * requires that if detected the boot CPU must be assigned
+ * logical id 0. Other CPUs get sequential indexes starting
+ * from 1. If a CPU node with a reg property matching the
+ * boot CPU MPIDR is detected, this is recorded so that the
+ * logical map built from DT is validated and can be used
+ * to override the map created in smp_setup_processor_id().
+ */
+ if (hwid == mpidr) {
+ i = 0;
+ bootcpu_valid = true;
+ } else {
+ i = cpuidx++;
+ }
+
+ if (WARN(cpuidx > nr_cpu_ids, "DT /cpu %u nodes greater than "
+ "max cores %u, capping them\n",
+ cpuidx, nr_cpu_ids)) {
+ cpuidx = nr_cpu_ids;
+ break;
+ }
+
+ tmp_map[i] = hwid;
+
+ if (!found_method)
+ found_method = set_smp_ops_by_method(cpu);
+ }
+
+ /*
+ * Fallback to an enable-method in the cpus node if nothing found in
+ * a cpu node.
+ */
+ if (!found_method)
+ set_smp_ops_by_method(cpus);
+
+ if (!bootcpu_valid) {
+ pr_warn("DT missing boot CPU MPIDR[23:0], fall back to default cpu_logical_map\n");
+ return;
+ }
+
+ /*
+ * Since the boot CPU node contains proper data, and all nodes have
+ * a reg property, the DT CPU list can be considered valid and the
+ * logical map created in smp_setup_processor_id() can be overridden
+ */
+ for (i = 0; i < cpuidx; i++) {
+ set_cpu_possible(i, true);
+ cpu_logical_map(i) = tmp_map[i];
+ pr_debug("cpu logical map 0x%x\n", cpu_logical_map(i));
+ }
+}
+
+bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+ return phys_id == cpu_logical_map(cpu);
+}
+
+static const void * __init arch_get_next_mach(const char *const **match)
+{
+ static const struct machine_desc *mdesc = __arch_info_begin;
+ const struct machine_desc *m = mdesc;
+
+ if (m >= __arch_info_end)
+ return NULL;
+
+ mdesc++;
+ *match = m->dt_compat;
+ return m;
+}
+
+/**
+ * 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.
+ */
+const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
+{
+ const struct machine_desc *mdesc, *mdesc_best = NULL;
+
+#ifdef CONFIG_ARCH_MULTIPLATFORM
+ DT_MACHINE_START(GENERIC_DT, "Generic DT based system")
+ MACHINE_END
+
+ mdesc_best = &__mach_desc_GENERIC_DT;
+#endif
+
+ if (!dt_phys || !early_init_dt_verify(phys_to_virt(dt_phys)))
+ return NULL;
+
+ mdesc = of_flat_dt_match_machine(mdesc_best, arch_get_next_mach);
+
+ if (!mdesc) {
+ const char *prop;
+ int size;
+ unsigned long dt_root;
+
+ early_print("\nError: unrecognized/unsupported "
+ "device tree compatible list:\n[ ");
+
+ dt_root = of_get_flat_dt_root();
+ 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 */
+ }
+
+ /* We really don't want to do this, but sometimes firmware provides buggy data */
+ if (mdesc->dt_fixup)
+ mdesc->dt_fixup();
+
+ early_init_dt_scan_nodes();
+
+ /* Change machine number to match the mdesc we're using */
+ __machine_arch_type = mdesc->nr;
+
+ return mdesc;
+}
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
new file mode 100644
index 000000000..84363fe7b
--- /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)
+ pr_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 000000000..e651c4d0a
--- /dev/null
+++ b/arch/arm/kernel/dma.c
@@ -0,0 +1,298 @@
+/*
+ * 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_RAW_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:
+ pr_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) {
+ pr_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;
+ }
+
+ pr_err("dma%d: trying to free free DMA\n", chan);
+ return;
+
+bad_dma:
+ pr_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)
+ pr_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)
+ pr_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)
+ pr_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)
+ pr_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:
+ pr_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:
+ pr_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)
+{
+ pr_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 000000000..430765369
--- /dev/null
+++ b/arch/arm/kernel/early_printk.c
@@ -0,0 +1,46 @@
+/*
+ * 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_dev = {
+ .name = "earlycon",
+ .write = early_console_write,
+ .flags = CON_PRINTBUFFER | CON_BOOT,
+ .index = -1,
+};
+
+static int __init setup_early_printk(char *buf)
+{
+ early_console = &early_console_dev;
+ register_console(&early_console_dev);
+ return 0;
+}
+
+early_param("earlyprintk", setup_early_printk);
diff --git a/arch/arm/kernel/elf.c b/arch/arm/kernel/elf.c
new file mode 100644
index 000000000..d0d1e8315
--- /dev/null
+++ b/arch/arm/kernel/elf.c
@@ -0,0 +1,91 @@
+#include <linux/export.h>
+#include <linux/sched.h>
+#include <linux/personality.h>
+#include <linux/binfmts.h>
+#include <linux/elf.h>
+#include <asm/system_info.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 000000000..570306c49
--- /dev/null
+++ b/arch/arm/kernel/entry-armv.S
@@ -0,0 +1,1238 @@
+/*
+ * 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/assembler.h>
+#include <asm/memory.h>
+#include <asm/glue-df.h>
+#include <asm/glue-pf.h>
+#include <asm/vfpmacros.h>
+#ifndef CONFIG_MULTI_IRQ_HANDLER
+#include <mach/entry-macro.S>
+#endif
+#include <asm/thread_notify.h>
+#include <asm/unwind.h>
+#include <asm/unistd.h>
+#include <asm/tls.h>
+#include <asm/system_info.h>
+
+#include "entry-header.S"
+#include <asm/entry-macro-multi.S>
+#include <asm/probes.h>
+
+/*
+ * Interrupt handling.
+ */
+ .macro irq_handler
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+ ldr r1, =handle_arch_irq
+ mov r0, sp
+ adr lr, BSYM(9997f)
+ ldr pc, [r1]
+#else
+ arch_irq_handler_default
+#endif
+9997:
+ .endm
+
+ .macro pabt_helper
+ @ PABORT handler takes pt_regs in r2, fault address in r4 and psr in r5
+#ifdef MULTI_PABORT
+ ldr ip, .LCprocfns
+ mov lr, pc
+ ldr pc, [ip, #PROCESSOR_PABT_FUNC]
+#else
+ bl CPU_PABORT_HANDLER
+#endif
+ .endm
+
+ .macro dabt_helper
+
+ @
+ @ Call the processor-specific abort handler:
+ @
+ @ r2 - pt_regs
+ @ r4 - aborted context pc
+ @ r5 - aborted context psr
+ @
+ @ 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 ip, .LCprocfns
+ mov lr, pc
+ ldr pc, [ip, #PROCESSOR_DABT_FUNC]
+#else
+ bl CPU_DABORT_HANDLER
+#endif
+ .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, trace=1
+ 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, {r3 - r5}
+ add r7, sp, #S_SP - 4 @ here for interlock avoidance
+ mov r6, #-1 @ "" "" "" ""
+ add r2, sp, #(S_FRAME_SIZE + \stack_hole - 4)
+ SPFIX( addeq r2, r2, #4 )
+ str r3, [sp, #-4]! @ save the "real" r0 copied
+ @ from the exception stack
+
+ mov r3, lr
+
+ @
+ @ We are now ready to fill in the remaining blanks on the stack:
+ @
+ @ r2 - sp_svc
+ @ r3 - lr_svc
+ @ r4 - lr_<exception>, already fixed up for correct return/restart
+ @ r5 - spsr_<exception>
+ @ r6 - orig_r0 (see pt_regs definition in ptrace.h)
+ @
+ stmia r7, {r2 - r6}
+
+ .if \trace
+#ifdef CONFIG_TRACE_IRQFLAGS
+ bl trace_hardirqs_off
+#endif
+ .endif
+ .endm
+
+ .align 5
+__dabt_svc:
+ svc_entry
+ mov r2, sp
+ dabt_helper
+ THUMB( ldr r5, [sp, #S_PSR] ) @ potentially updated CPSR
+ svc_exit r5 @ return from exception
+ UNWIND(.fnend )
+ENDPROC(__dabt_svc)
+
+ .align 5
+__irq_svc:
+ svc_entry
+ irq_handler
+
+#ifdef CONFIG_PREEMPT
+ get_thread_info tsk
+ ldr r8, [tsk, #TI_PREEMPT] @ get 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
+
+ svc_exit r5, irq = 1 @ 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
+ reteq r8 @ go again
+ b 1b
+#endif
+
+__und_fault:
+ @ Correct the PC such that it is pointing at the instruction
+ @ which caused the fault. If the faulting instruction was ARM
+ @ the PC will be pointing at the next instruction, and have to
+ @ subtract 4. Otherwise, it is Thumb, and the PC will be
+ @ pointing at the second half of the Thumb instruction. We
+ @ have to subtract 2.
+ ldr r2, [r0, #S_PC]
+ sub r2, r2, r1
+ str r2, [r0, #S_PC]
+ b do_undefinstr
+ENDPROC(__und_fault)
+
+ .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 MAX_STACK_SIZE
+#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, [r4, #-4]
+#else
+ mov r1, #2
+ ldrh r0, [r4, #-2] @ Thumb instruction at LR - 2
+ cmp r0, #0xe800 @ 32-bit instruction if xx >= 0
+ blo __und_svc_fault
+ ldrh r9, [r4] @ bottom 16 bits
+ add r4, r4, #2
+ str r4, [sp, #S_PC]
+ orr r0, r9, r0, lsl #16
+#endif
+ adr r9, BSYM(__und_svc_finish)
+ mov r2, r4
+ bl call_fpe
+
+ mov r1, #4 @ PC correction to apply
+__und_svc_fault:
+ mov r0, sp @ struct pt_regs *regs
+ bl __und_fault
+
+__und_svc_finish:
+ ldr r5, [sp, #S_PSR] @ Get SVC cpsr
+ svc_exit r5 @ return from exception
+ UNWIND(.fnend )
+ENDPROC(__und_svc)
+
+ .align 5
+__pabt_svc:
+ svc_entry
+ mov r2, sp @ regs
+ pabt_helper
+ svc_exit r5 @ return from exception
+ UNWIND(.fnend )
+ENDPROC(__pabt_svc)
+
+ .align 5
+__fiq_svc:
+ svc_entry trace=0
+ mov r0, sp @ struct pt_regs *regs
+ bl handle_fiq_as_nmi
+ svc_exit_via_fiq
+ UNWIND(.fnend )
+ENDPROC(__fiq_svc)
+
+ .align 5
+.LCcralign:
+ .word cr_alignment
+#ifdef MULTI_DABORT
+.LCprocfns:
+ .word processor
+#endif
+.LCfp:
+ .word fp_enter
+
+/*
+ * Abort mode handlers
+ */
+
+@
+@ Taking a FIQ in abort mode is similar to taking a FIQ in SVC mode
+@ and reuses the same macros. However in abort mode we must also
+@ save/restore lr_abt and spsr_abt to make nested aborts safe.
+@
+ .align 5
+__fiq_abt:
+ svc_entry trace=0
+
+ ARM( msr cpsr_c, #ABT_MODE | PSR_I_BIT | PSR_F_BIT )
+ THUMB( mov r0, #ABT_MODE | PSR_I_BIT | PSR_F_BIT )
+ THUMB( msr cpsr_c, r0 )
+ mov r1, lr @ Save lr_abt
+ mrs r2, spsr @ Save spsr_abt, abort is now safe
+ ARM( msr cpsr_c, #SVC_MODE | PSR_I_BIT | PSR_F_BIT )
+ THUMB( mov r0, #SVC_MODE | PSR_I_BIT | PSR_F_BIT )
+ THUMB( msr cpsr_c, r0 )
+ stmfd sp!, {r1 - r2}
+
+ add r0, sp, #8 @ struct pt_regs *regs
+ bl handle_fiq_as_nmi
+
+ ldmfd sp!, {r1 - r2}
+ ARM( msr cpsr_c, #ABT_MODE | PSR_I_BIT | PSR_F_BIT )
+ THUMB( mov r0, #ABT_MODE | PSR_I_BIT | PSR_F_BIT )
+ THUMB( msr cpsr_c, r0 )
+ mov lr, r1 @ Restore lr_abt, abort is unsafe
+ msr spsr_cxsf, r2 @ Restore spsr_abt
+ ARM( msr cpsr_c, #SVC_MODE | PSR_I_BIT | PSR_F_BIT )
+ THUMB( mov r0, #SVC_MODE | PSR_I_BIT | PSR_F_BIT )
+ THUMB( msr cpsr_c, r0 )
+
+ svc_exit_via_fiq
+ UNWIND(.fnend )
+ENDPROC(__fiq_abt)
+
+/*
+ * 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, trace=1
+ 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} )
+
+ ATRAP( mrc p15, 0, r7, c1, c0, 0)
+ ATRAP( ldr r8, .LCcralign)
+
+ ldmia r0, {r3 - r5}
+ add r0, sp, #S_PC @ here for interlock avoidance
+ mov r6, #-1 @ "" "" "" ""
+
+ str r3, [sp] @ save the "real" r0 copied
+ @ from the exception stack
+
+ ATRAP( ldr r8, [r8, #0])
+
+ @
+ @ We are now ready to fill in the remaining blanks on the stack:
+ @
+ @ r4 - lr_<exception>, already fixed up for correct return/restart
+ @ r5 - spsr_<exception>
+ @ r6 - orig_r0 (see pt_regs definition in ptrace.h)
+ @
+ @ Also, separately save sp_usr and lr_usr
+ @
+ stmia r0, {r4 - r6}
+ ARM( stmdb r0, {sp, lr}^ )
+ THUMB( store_user_sp_lr r0, r1, S_SP - S_PC )
+
+ @ Enable the alignment trap while in kernel mode
+ ATRAP( teq r8, r7)
+ ATRAP( mcrne p15, 0, r8, c1, c0, 0)
+
+ @
+ @ Clear FP to mark the first stack frame
+ @
+ zero_fp
+
+ .if \trace
+#ifdef CONFIG_IRQSOFF_TRACER
+ bl trace_hardirqs_off
+#endif
+ ct_user_exit save = 0
+ .endif
+ .endm
+
+ .macro kuser_cmpxchg_check
+#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \
+ !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 r4, #TASK_SIZE
+ blhs kuser_cmpxchg64_fixup
+#endif
+#endif
+ .endm
+
+ .align 5
+__dabt_usr:
+ usr_entry
+ kuser_cmpxchg_check
+ mov r2, sp
+ dabt_helper
+ b ret_from_exception
+ UNWIND(.fnend )
+ENDPROC(__dabt_usr)
+
+ .align 5
+__irq_usr:
+ usr_entry
+ kuser_cmpxchg_check
+ irq_handler
+ get_thread_info tsk
+ mov why, #0
+ b ret_to_user_from_irq
+ UNWIND(.fnend )
+ENDPROC(__irq_usr)
+
+ .ltorg
+
+ .align 5
+__und_usr:
+ usr_entry
+
+ mov r2, r4
+ mov r3, r5
+
+ @ r2 = regs->ARM_pc, which is either 2 or 4 bytes ahead of the
+ @ faulting instruction depending on Thumb mode.
+ @ r3 = regs->ARM_cpsr
+ @
+ @ The emulation code 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
+ @
+ adr r9, BSYM(ret_from_exception)
+
+ @ IRQs must be enabled before attempting to read the instruction from
+ @ user space since that could cause a page/translation fault if the
+ @ page table was modified by another CPU.
+ enable_irq
+
+ tst r3, #PSR_T_BIT @ Thumb mode?
+ bne __und_usr_thumb
+ sub r4, r2, #4 @ ARM instr at LR - 4
+1: ldrt r0, [r4]
+ ARM_BE8(rev r0, r0) @ little endian instruction
+
+ @ r0 = 32-bit ARM instruction which caused the exception
+ @ r2 = PC value for the following instruction (:= regs->ARM_pc)
+ @ r4 = PC value for the faulting instruction
+ @ lr = 32-bit undefined instruction function
+ adr lr, BSYM(__und_usr_fault_32)
+ b call_fpe
+
+__und_usr_thumb:
+ @ Thumb instruction
+ sub r4, r2, #2 @ First half of thumb instr at LR - 2
+#if CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7
+/*
+ * Thumb-2 instruction handling. Note that because pre-v6 and >= v6 platforms
+ * can never be supported in a single kernel, this code is not applicable at
+ * all when __LINUX_ARM_ARCH__ < 6. This allows simplifying assumptions to be
+ * made about .arch directives.
+ */
+#if __LINUX_ARM_ARCH__ < 7
+/* If the target CPU may not be Thumb-2-capable, a run-time check is needed: */
+#define NEED_CPU_ARCHITECTURE
+ ldr r5, .LCcpu_architecture
+ ldr r5, [r5]
+ cmp r5, #CPU_ARCH_ARMv7
+ blo __und_usr_fault_16 @ 16bit undefined instruction
+/*
+ * The following code won't get run unless the running CPU really is v7, so
+ * coding round the lack of ldrht on older arches is pointless. Temporarily
+ * override the assembler target arch with the minimum required instead:
+ */
+ .arch armv6t2
+#endif
+2: ldrht r5, [r4]
+ARM_BE8(rev16 r5, r5) @ little endian instruction
+ cmp r5, #0xe800 @ 32bit instruction if xx != 0
+ blo __und_usr_fault_16 @ 16bit undefined instruction
+3: ldrht r0, [r2]
+ARM_BE8(rev16 r0, r0) @ little endian instruction
+ add r2, r2, #2 @ r2 is PC + 2, make it PC + 4
+ str r2, [sp, #S_PC] @ it's a 2x16bit instr, update
+ orr r0, r0, r5, lsl #16
+ adr lr, BSYM(__und_usr_fault_32)
+ @ r0 = the two 16-bit Thumb instructions which caused the exception
+ @ r2 = PC value for the following Thumb instruction (:= regs->ARM_pc)
+ @ r4 = PC value for the first 16-bit Thumb instruction
+ @ lr = 32bit undefined instruction function
+
+#if __LINUX_ARM_ARCH__ < 7
+/* If the target arch was overridden, change it back: */
+#ifdef CONFIG_CPU_32v6K
+ .arch armv6k
+#else
+ .arch armv6
+#endif
+#endif /* __LINUX_ARM_ARCH__ < 7 */
+#else /* !(CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7) */
+ b __und_usr_fault_16
+#endif
+ UNWIND(.fnend)
+ENDPROC(__und_usr)
+
+/*
+ * The out of line fixup for the ldrt instructions above.
+ */
+ .pushsection .text.fixup, "ax"
+ .align 2
+4: str r4, [sp, #S_PC] @ retry current instruction
+ ret r9
+ .popsection
+ .pushsection __ex_table,"a"
+ .long 1b, 4b
+#if CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7
+ .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 (32-bit ARM or two 16-bit Thumb)
+ * r2 = PC value to resume execution after successful emulation
+ * r9 = normal "successful" return address
+ * r10 = this threads thread_info structure
+ * lr = unrecognised instruction return address
+ * IRQs enabled, FIQs enabled.
+ */
+ @
+ @ Fall-through from Thumb-2 __und_usr
+ @
+#ifdef CONFIG_NEON
+ get_thread_info r10 @ get current thread
+ adr r6, .LCneon_thumb_opcodes
+ b 2f
+#endif
+call_fpe:
+ get_thread_info r10 @ get current thread
+#ifdef CONFIG_NEON
+ adr r6, .LCneon_arm_opcodes
+2: ldr r5, [r6], #4 @ mask value
+ ldr r7, [r6], #4 @ opcode bits matching in mask
+ cmp r5, #0 @ end mask?
+ beq 1f
+ and r8, r0, r5
+ cmp r8, r7 @ NEON instruction?
+ bne 2b
+ 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
+ reteq lr
+ 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
+
+ ret.w lr @ CP#0
+ W(b) do_fpe @ CP#1 (FPE)
+ W(b) do_fpe @ CP#2 (FPE)
+ ret.w 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
+ ret.w lr @ CP#4
+ ret.w lr @ CP#5
+ ret.w lr @ CP#6
+#endif
+ ret.w lr @ CP#7
+ ret.w lr @ CP#8
+ ret.w lr @ CP#9
+#ifdef CONFIG_VFP
+ W(b) do_vfp @ CP#10 (VFP)
+ W(b) do_vfp @ CP#11 (VFP)
+#else
+ ret.w lr @ CP#10 (VFP)
+ ret.w lr @ CP#11 (VFP)
+#endif
+ ret.w lr @ CP#12
+ ret.w lr @ CP#13
+ ret.w lr @ CP#14 (Debug)
+ ret.w lr @ CP#15 (Control)
+
+#ifdef NEED_CPU_ARCHITECTURE
+ .align 2
+.LCcpu_architecture:
+ .word __cpu_architecture
+#endif
+
+#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:
+ 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)
+ ret lr
+ENDPROC(no_fp)
+
+__und_usr_fault_32:
+ mov r1, #4
+ b 1f
+__und_usr_fault_16:
+ mov r1, #2
+1: mov r0, sp
+ adr lr, BSYM(ret_from_exception)
+ b __und_fault
+ENDPROC(__und_usr_fault_32)
+ENDPROC(__und_usr_fault_16)
+
+ .align 5
+__pabt_usr:
+ usr_entry
+ mov r2, sp @ regs
+ pabt_helper
+ 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)
+
+ .align 5
+__fiq_usr:
+ usr_entry trace=0
+ kuser_cmpxchg_check
+ mov r0, sp @ struct pt_regs *regs
+ bl handle_fiq_as_nmi
+ get_thread_info tsk
+ restore_user_regs fast = 0, offset = 0
+ UNWIND(.fnend )
+ENDPROC(__fiq_usr)
+
+/*
+ * 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
+ 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 )
+ ldr r4, [r2, #TI_TP_VALUE]
+ ldr r5, [r2, #TI_TP_VALUE + 4]
+#ifdef CONFIG_CPU_USE_DOMAINS
+ ldr r6, [r2, #TI_CPU_DOMAIN]
+#endif
+ switch_tls r1, r4, r5, r3, r7
+#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.
+ *
+ * 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.
+ *
+ * See Documentation/arm/kernel_user_helpers.txt for formal definitions.
+ */
+ THUMB( .arm )
+
+ .macro usr_ret, reg
+#ifdef CONFIG_ARM_THUMB
+ bx \reg
+#else
+ ret \reg
+#endif
+ .endm
+
+ .macro kuser_pad, sym, size
+ .if (. - \sym) & 3
+ .rept 4 - (. - \sym) & 3
+ .byte 0
+ .endr
+ .endif
+ .rept (\size - (. - \sym)) / 4
+ .word 0xe7fddef1
+ .endr
+ .endm
+
+#ifdef CONFIG_KUSER_HELPERS
+ .align 5
+ .globl __kuser_helper_start
+__kuser_helper_start:
+
+/*
+ * Due to the length of some sequences, __kuser_cmpxchg64 spans 2 regular
+ * kuser "slots", therefore 0xffff0f80 is not used as a valid entry point.
+ */
+
+__kuser_cmpxchg64: @ 0xffff0f60
+
+#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_cmpxchg64
+ ldmfd sp!, {r7, pc}
+1: .word __ARM_NR_cmpxchg64
+
+#elif defined(CONFIG_CPU_32v6K)
+
+ stmfd sp!, {r4, r5, r6, r7}
+ ldrd r4, r5, [r0] @ load old val
+ ldrd r6, r7, [r1] @ load new val
+ smp_dmb arm
+1: ldrexd r0, r1, [r2] @ load current val
+ eors r3, r0, r4 @ compare with oldval (1)
+ eoreqs r3, r1, r5 @ compare with oldval (2)
+ strexdeq r3, r6, r7, [r2] @ store newval if eq
+ teqeq r3, #1 @ success?
+ beq 1b @ if no then retry
+ smp_dmb arm
+ rsbs r0, r3, #0 @ set returned val and C flag
+ ldmfd sp!, {r4, r5, r6, r7}
+ usr_ret lr
+
+#elif !defined(CONFIG_SMP)
+
+#ifdef CONFIG_MMU
+
+ /*
+ * The only thing that can break atomicity in this cmpxchg64
+ * implementation is either an IRQ or a data abort exception
+ * causing another process/thread to be scheduled in the middle of
+ * the critical sequence. The same strategy as for cmpxchg is used.
+ */
+ stmfd sp!, {r4, r5, r6, lr}
+ ldmia r0, {r4, r5} @ load old val
+ ldmia r1, {r6, lr} @ load new val
+1: ldmia r2, {r0, r1} @ load current val
+ eors r3, r0, r4 @ compare with oldval (1)
+ eoreqs r3, r1, r5 @ compare with oldval (2)
+2: stmeqia r2, {r6, lr} @ store newval if eq
+ rsbs r0, r3, #0 @ set return val and C flag
+ ldmfd sp!, {r4, r5, r6, pc}
+
+ .text
+kuser_cmpxchg64_fixup:
+ @ Called from kuser_cmpxchg_fixup.
+ @ r4 = address of interrupted insn (must be preserved).
+ @ sp = saved regs. r7 and r8 are clobbered.
+ @ 1b = first critical insn, 2b = last critical insn.
+ @ If r4 >= 1b and r4 <= 2b then saved pc_usr is set to 1b.
+ mov r7, #0xffff0fff
+ sub r7, r7, #(0xffff0fff - (0xffff0f60 + (1b - __kuser_cmpxchg64)))
+ subs r8, r4, r7
+ rsbcss r8, r8, #(2b - 1b)
+ strcs r7, [sp, #S_PC]
+#if __LINUX_ARM_ARCH__ < 6
+ bcc kuser_cmpxchg32_fixup
+#endif
+ ret lr
+ .previous
+
+#else
+#warning "NPTL on non MMU needs fixing"
+ mov r0, #-1
+ adds r0, r0, #0
+ usr_ret lr
+#endif
+
+#else
+#error "incoherent kernel configuration"
+#endif
+
+ kuser_pad __kuser_cmpxchg64, 64
+
+__kuser_memory_barrier: @ 0xffff0fa0
+ smp_dmb arm
+ usr_ret lr
+
+ kuser_pad __kuser_memory_barrier, 32
+
+__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_cmpxchg32_fixup:
+ @ Called from kuser_cmpxchg_check macro.
+ @ r4 = address of interrupted insn (must be preserved).
+ @ sp = saved regs. r7 and r8 are clobbered.
+ @ 1b = first critical insn, 2b = last critical insn.
+ @ If r4 >= 1b and r4 <= 2b then saved pc_usr is set to 1b.
+ mov r7, #0xffff0fff
+ sub r7, r7, #(0xffff0fff - (0xffff0fc0 + (1b - __kuser_cmpxchg)))
+ subs r8, r4, r7
+ rsbcss r8, r8, #(2b - 1b)
+ strcs r7, [sp, #S_PC]
+ ret 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
+
+ kuser_pad __kuser_cmpxchg, 32
+
+__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
+ kuser_pad __kuser_get_tls, 16
+ .rep 3
+ .word 0 @ 0xffff0ff0 software TLS value, then
+ .endr @ pad up to __kuser_helper_version
+
+__kuser_helper_version: @ 0xffff0ffc
+ .word ((__kuser_helper_end - __kuser_helper_start) >> 5)
+
+ .globl __kuser_helper_end
+__kuser_helper_end:
+
+#endif
+
+ THUMB( .thumb )
+
+/*
+ * Vector stubs.
+ *
+ * This code is copied to 0xffff1000 so we can use branches in the
+ * vectors, rather than ldr's. Note that this code must not exceed
+ * a page size.
+ *
+ * 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
+
+ .section .stubs, "ax", %progbits
+__stubs_start:
+ @ This must be the first word
+ .word vector_swi
+
+vector_rst:
+ ARM( swi SYS_ERROR0 )
+ THUMB( svc #0 )
+ THUMB( nop )
+ b vector_und
+
+/*
+ * 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
+
+/*=============================================================================
+ * 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
+
+/*=============================================================================
+ * FIQ "NMI" handler
+ *-----------------------------------------------------------------------------
+ * Handle a FIQ using the SVC stack allowing FIQ act like NMI on x86
+ * systems.
+ */
+ vector_stub fiq, FIQ_MODE, 4
+
+ .long __fiq_usr @ 0 (USR_26 / USR_32)
+ .long __fiq_svc @ 1 (FIQ_26 / FIQ_32)
+ .long __fiq_svc @ 2 (IRQ_26 / IRQ_32)
+ .long __fiq_svc @ 3 (SVC_26 / SVC_32)
+ .long __fiq_svc @ 4
+ .long __fiq_svc @ 5
+ .long __fiq_svc @ 6
+ .long __fiq_abt @ 7
+ .long __fiq_svc @ 8
+ .long __fiq_svc @ 9
+ .long __fiq_svc @ a
+ .long __fiq_svc @ b
+ .long __fiq_svc @ c
+ .long __fiq_svc @ d
+ .long __fiq_svc @ e
+ .long __fiq_svc @ f
+
+ .globl vector_fiq_offset
+ .equ vector_fiq_offset, vector_fiq
+
+ .section .vectors, "ax", %progbits
+__vectors_start:
+ W(b) vector_rst
+ W(b) vector_und
+ W(ldr) pc, __vectors_start + 0x1000
+ W(b) vector_pabt
+ W(b) vector_dabt
+ W(b) vector_addrexcptn
+ W(b) vector_irq
+ W(b) vector_fiq
+
+ .data
+
+ .globl cr_alignment
+cr_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 000000000..4e7f40c57
--- /dev/null
+++ b/arch/arm/kernel/entry-common.S
@@ -0,0 +1,388 @@
+/*
+ * 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/assembler.h>
+#include <asm/unistd.h>
+#include <asm/ftrace.h>
+#include <asm/unwind.h>
+
+#ifdef CONFIG_NEED_RET_TO_USER
+#include <mach/entry-macro.S>
+#else
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+#endif
+
+#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] @ re-check for syscall tracing
+ tst r1, #_TIF_SYSCALL_WORK
+ bne __sys_trace_return
+ tst r1, #_TIF_WORK_MASK
+ bne fast_work_pending
+ asm_trace_hardirqs_on
+
+ /* perform architecture specific actions before user return */
+ arch_ret_to_user r1, lr
+ ct_user_enter
+
+ 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:
+ mov r0, sp @ 'regs'
+ mov r2, why @ 'syscall'
+ bl do_work_pending
+ cmp r0, #0
+ beq no_work_pending
+ movlt scno, #(__NR_restart_syscall - __NR_SYSCALL_BASE)
+ ldmia sp, {r0 - r6} @ have to reload r0 - r6
+ b local_restart @ ... and off we go
+
+/*
+ * "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:
+ asm_trace_hardirqs_on
+
+ /* perform architecture specific actions before user return */
+ arch_ret_to_user r1, lr
+ ct_user_enter save = 0
+
+ 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
+ cmp r5, #0
+ movne r0, r4
+ adrne lr, BSYM(1f)
+ retne r5
+1: get_thread_info tsk
+ b ret_slow_syscall
+ENDPROC(ret_from_fork)
+
+ .equ NR_syscalls,0
+#define CALL(x) .equ NR_syscalls,NR_syscalls+1
+#include "calls.S"
+
+/*
+ * Ensure that the system call table is equal to __NR_syscalls,
+ * which is the value the rest of the system sees
+ */
+.ifne NR_syscalls - __NR_syscalls
+.error "__NR_syscalls is not equal to the size of the syscall table"
+.endif
+
+#undef CALL
+#define CALL(x) .long x
+
+/*=============================================================================
+ * SWI handler
+ *-----------------------------------------------------------------------------
+ */
+
+ .align 5
+ENTRY(vector_swi)
+#ifdef CONFIG_CPU_V7M
+ v7m_exception_entry
+#else
+ 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
+#endif
+ zero_fp
+ alignment_trap r10, ip, __cr_alignment
+ enable_irq
+ ct_user_exit
+ get_thread_info tsk
+
+ /*
+ * 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
+ USER( ldreq r10, [lr, #-4] ) @ get SWI instruction
+#else
+ USER( ldr r10, [lr, #-4] ) @ get SWI instruction
+#endif
+ ARM_BE8(rev r10, r10) @ little endian instruction
+
+#elif defined(CONFIG_AEABI)
+
+ /*
+ * Pure EABI user space always put syscall number into scno (r7).
+ */
+#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
+ USER( ldreq scno, [lr, #-4] )
+
+#else
+ /* Legacy ABI only. */
+ USER( ldr scno, [lr, #-4] ) @ get SWI instruction
+#endif
+
+ 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
+
+local_restart:
+ ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing
+ stmdb sp!, {r4, r5} @ push fifth and sixth args
+
+ tst r10, #_TIF_SYSCALL_WORK @ 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: cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
+ eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back
+ bcs arm_syscall
+ mov why, #0 @ no longer a real syscall
+ b sys_ni_syscall @ not private func
+
+#if defined(CONFIG_OABI_COMPAT) || !defined(CONFIG_AEABI)
+ /*
+ * We failed to handle a fault trying to access the page
+ * containing the swi instruction, but we're not really in a
+ * position to return -EFAULT. Instead, return back to the
+ * instruction and re-enter the user fault handling path trying
+ * to page it in. This will likely result in sending SEGV to the
+ * current task.
+ */
+9001:
+ sub lr, lr, #4
+ str lr, [sp, #S_PC]
+ b ret_fast_syscall
+#endif
+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 r1, scno
+ add r0, sp, #S_OFF
+ bl syscall_trace_enter
+
+ 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 - r6} @ have to reload r0 - r6
+ stmccia sp, {r4, r5} @ and update the stack args
+ ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
+ cmp scno, #-1 @ skip the syscall?
+ bne 2b
+ add sp, sp, #S_OFF @ restore stack
+ b ret_slow_syscall
+
+__sys_trace_return:
+ str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
+ mov r0, sp
+ bl syscall_trace_exit
+ 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_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_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
+ ret 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-ftrace.S b/arch/arm/kernel/entry-ftrace.S
new file mode 100644
index 000000000..fe57c73e7
--- /dev/null
+++ b/arch/arm/kernel/entry-ftrace.S
@@ -0,0 +1,243 @@
+/*
+ * This program is free software; you can redistribute 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/assembler.h>
+#include <asm/ftrace.h>
+#include <asm/unwind.h>
+
+#include "entry-header.S"
+
+/*
+ * 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_adjust_addr rd, rn
+ bic \rd, \rn, #1 @ clear the Thumb bit if present
+ sub \rd, \rd, #MCOUNT_INSN_SIZE
+.endm
+
+.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
+ mcount_adjust_addr r0, lr @ instrumented function
+ 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
+ mcount_adjust_addr r0, lr @ instrumented function
+
+ .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)
+ mcount_adjust_addr r1, r1
+#else
+ @ called from __mcount, untouched in lr
+ mcount_adjust_addr r1, lr @ instrumented routine (func)
+#endif
+ 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
+/*
+ * This pad compensates for the push {lr} at the call site. Note that we are
+ * unable to unwind through a function which does not otherwise save its lr.
+ */
+ UNWIND(.pad #4)
+ stmdb sp!, {r0-r3, lr}
+ UNWIND(.save {r0-r3, lr})
+.endm
+
+.macro mcount_get_lr reg
+ ldr \reg, [sp, #20]
+.endm
+
+.macro mcount_exit
+ ldmia sp!, {r0-r3, ip, lr}
+ ret ip
+.endm
+
+ENTRY(__gnu_mcount_nc)
+UNWIND(.fnstart)
+#ifdef CONFIG_DYNAMIC_FTRACE
+ mov ip, lr
+ ldmia sp!, {lr}
+ ret ip
+#else
+ __mcount
+#endif
+UNWIND(.fnend)
+ENDPROC(__gnu_mcount_nc)
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+ENTRY(ftrace_caller)
+UNWIND(.fnstart)
+ __ftrace_caller
+UNWIND(.fnend)
+ENDPROC(ftrace_caller)
+#endif
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ENTRY(ftrace_graph_caller)
+UNWIND(.fnstart)
+ __ftrace_graph_caller
+UNWIND(.fnend)
+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}
+ ret lr
+#endif
+
+ENTRY(ftrace_stub)
+.Lftrace_stub:
+ ret lr
+ENDPROC(ftrace_stub)
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
new file mode 100644
index 000000000..1a0045abe
--- /dev/null
+++ b/arch/arm/kernel/entry-header.S
@@ -0,0 +1,401 @@
+#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>
+#include <asm/v7m.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
+
+#ifdef CONFIG_ALIGNMENT_TRAP
+#define ATRAP(x...) x
+#else
+#define ATRAP(x...)
+#endif
+
+ .macro alignment_trap, rtmp1, rtmp2, label
+#ifdef CONFIG_ALIGNMENT_TRAP
+ mrc p15, 0, \rtmp2, c1, c0, 0
+ ldr \rtmp1, \label
+ ldr \rtmp1, [\rtmp1]
+ teq \rtmp1, \rtmp2
+ mcrne p15, 0, \rtmp1, c1, c0, 0
+#endif
+ .endm
+
+#ifdef CONFIG_CPU_V7M
+/*
+ * ARMv7-M exception entry/exit macros.
+ *
+ * xPSR, ReturnAddress(), LR (R14), R12, R3, R2, R1, and R0 are
+ * automatically saved on the current stack (32 words) before
+ * switching to the exception stack (SP_main).
+ *
+ * If exception is taken while in user mode, SP_main is
+ * empty. Otherwise, SP_main is aligned to 64 bit automatically
+ * (CCR.STKALIGN set).
+ *
+ * Linux assumes that the interrupts are disabled when entering an
+ * exception handler and it may BUG if this is not the case. Interrupts
+ * are disabled during entry and reenabled in the exit macro.
+ *
+ * v7m_exception_slow_exit is used when returning from SVC or PendSV.
+ * When returning to kernel mode, we don't return from exception.
+ */
+ .macro v7m_exception_entry
+ @ determine the location of the registers saved by the core during
+ @ exception entry. Depending on the mode the cpu was in when the
+ @ exception happend that is either on the main or the process stack.
+ @ Bit 2 of EXC_RETURN stored in the lr register specifies which stack
+ @ was used.
+ tst lr, #EXC_RET_STACK_MASK
+ mrsne r12, psp
+ moveq r12, sp
+
+ @ we cannot rely on r0-r3 and r12 matching the value saved in the
+ @ exception frame because of tail-chaining. So these have to be
+ @ reloaded.
+ ldmia r12!, {r0-r3}
+
+ @ Linux expects to have irqs off. Do it here before taking stack space
+ cpsid i
+
+ sub sp, #S_FRAME_SIZE-S_IP
+ stmdb sp!, {r0-r11}
+
+ @ load saved r12, lr, return address and xPSR.
+ @ r0-r7 are used for signals and never touched from now on. Clobbering
+ @ r8-r12 is OK.
+ mov r9, r12
+ ldmia r9!, {r8, r10-r12}
+
+ @ calculate the original stack pointer value.
+ @ r9 currently points to the memory location just above the auto saved
+ @ xPSR.
+ @ The cpu might automatically 8-byte align the stack. Bit 9
+ @ of the saved xPSR specifies if stack aligning took place. In this case
+ @ another 32-bit value is included in the stack.
+
+ tst r12, V7M_xPSR_FRAMEPTRALIGN
+ addne r9, r9, #4
+
+ @ store saved r12 using str to have a register to hold the base for stm
+ str r8, [sp, #S_IP]
+ add r8, sp, #S_SP
+ @ store r13-r15, xPSR
+ stmia r8!, {r9-r12}
+ @ store old_r0
+ str r0, [r8]
+ .endm
+
+ /*
+ * PENDSV and SVCALL are configured to have the same exception
+ * priorities. As a kernel thread runs at SVCALL execution priority it
+ * can never be preempted and so we will never have to return to a
+ * kernel thread here.
+ */
+ .macro v7m_exception_slow_exit ret_r0
+ cpsid i
+ ldr lr, =EXC_RET_THREADMODE_PROCESSSTACK
+
+ @ read original r12, sp, lr, pc and xPSR
+ add r12, sp, #S_IP
+ ldmia r12, {r1-r5}
+
+ @ an exception frame is always 8-byte aligned. To tell the hardware if
+ @ the sp to be restored is aligned or not set bit 9 of the saved xPSR
+ @ accordingly.
+ tst r2, #4
+ subne r2, r2, #4
+ orrne r5, V7M_xPSR_FRAMEPTRALIGN
+ biceq r5, V7M_xPSR_FRAMEPTRALIGN
+
+ @ ensure bit 0 is cleared in the PC, otherwise behaviour is
+ @ unpredictable
+ bic r4, #1
+
+ @ write basic exception frame
+ stmdb r2!, {r1, r3-r5}
+ ldmia sp, {r1, r3-r5}
+ .if \ret_r0
+ stmdb r2!, {r0, r3-r5}
+ .else
+ stmdb r2!, {r1, r3-r5}
+ .endif
+
+ @ restore process sp
+ msr psp, r2
+
+ @ restore original r4-r11
+ ldmia sp!, {r0-r11}
+
+ @ restore main sp
+ add sp, sp, #S_FRAME_SIZE-S_IP
+
+ cpsie i
+ bx lr
+ .endm
+#endif /* CONFIG_CPU_V7M */
+
+ @
+ @ 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, irq = 0
+ .if \irq != 0
+ @ IRQs already off
+#ifdef CONFIG_TRACE_IRQFLAGS
+ @ The parent context IRQs must have been enabled to get here in
+ @ the first place, so there's no point checking the PSR I bit.
+ bl trace_hardirqs_on
+#endif
+ .else
+ @ IRQs off again before pulling preserved data off the stack
+ disable_irq_notrace
+#ifdef CONFIG_TRACE_IRQFLAGS
+ tst \rpsr, #PSR_I_BIT
+ bleq trace_hardirqs_on
+ tst \rpsr, #PSR_I_BIT
+ blne trace_hardirqs_off
+#endif
+ .endif
+ msr spsr_cxsf, \rpsr
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K)
+ @ We must avoid clrex due to Cortex-A15 erratum #830321
+ sub r0, sp, #4 @ uninhabited address
+ strex r1, r2, [r0] @ clear the exclusive monitor
+#endif
+ ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
+ .endm
+
+ @
+ @ svc_exit_via_fiq - like svc_exit but switches to FIQ mode before exit
+ @
+ @ This macro acts in a similar manner to svc_exit but switches to FIQ
+ @ mode to restore the final part of the register state.
+ @
+ @ We cannot use the normal svc_exit procedure because that would
+ @ clobber spsr_svc (FIQ could be delivered during the first few
+ @ instructions of vector_swi meaning its contents have not been
+ @ saved anywhere).
+ @
+ @ Note that, unlike svc_exit, this macro also does not allow a caller
+ @ supplied rpsr. This is because the FIQ exceptions are not re-entrant
+ @ and the handlers cannot call into the scheduler (meaning the value
+ @ on the stack remains correct).
+ @
+ .macro svc_exit_via_fiq
+ mov r0, sp
+ ldmib r0, {r1 - r14} @ abort is deadly from here onward (it will
+ @ clobber state restored below)
+ msr cpsr_c, #FIQ_MODE | PSR_I_BIT | PSR_F_BIT
+ add r8, r0, #S_PC
+ ldr r9, [r0, #S_PSR]
+ msr spsr_cxsf, r9
+ ldr r0, [r0, #S_R0]
+ ldmia r8, {pc}^
+ .endm
+
+ .macro restore_user_regs, fast = 0, offset = 0
+ mov r2, sp
+ ldr r1, [r2, #\offset + S_PSR] @ get calling cpsr
+ ldr lr, [r2, #\offset + S_PC]! @ get pc
+ msr spsr_cxsf, r1 @ save in spsr_svc
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K)
+ @ We must avoid clrex due to Cortex-A15 erratum #830321
+ strex r1, r2, [r2] @ clear the exclusive monitor
+#endif
+ .if \fast
+ ldmdb r2, {r1 - lr}^ @ get calling r1 - lr
+ .else
+ ldmdb r2, {r0 - lr}^ @ get calling r0 - lr
+ .endif
+ mov r0, r0 @ ARMv5T and earlier require a nop
+ @ after ldm {}^
+ add sp, sp, #\offset + S_FRAME_SIZE
+ movs pc, lr @ return & move spsr_svc into cpsr
+ .endm
+
+#else /* CONFIG_THUMB2_KERNEL */
+ .macro svc_exit, rpsr, irq = 0
+ .if \irq != 0
+ @ IRQs already off
+#ifdef CONFIG_TRACE_IRQFLAGS
+ @ The parent context IRQs must have been enabled to get here in
+ @ the first place, so there's no point checking the PSR I bit.
+ bl trace_hardirqs_on
+#endif
+ .else
+ @ IRQs off again before pulling preserved data off the stack
+ disable_irq_notrace
+#ifdef CONFIG_TRACE_IRQFLAGS
+ tst \rpsr, #PSR_I_BIT
+ bleq trace_hardirqs_on
+ tst \rpsr, #PSR_I_BIT
+ blne trace_hardirqs_off
+#endif
+ .endif
+ ldr lr, [sp, #S_SP] @ top of the stack
+ ldrd r0, r1, [sp, #S_LR] @ calling lr and pc
+
+ @ We must avoid clrex due to Cortex-A15 erratum #830321
+ strex r2, r1, [sp, #S_LR] @ clear the exclusive monitor
+
+ stmdb lr!, {r0, r1, \rpsr} @ calling lr and rfe context
+ ldmia sp, {r0 - r12}
+ mov sp, lr
+ ldr lr, [sp], #4
+ rfeia sp!
+ .endm
+
+ @
+ @ svc_exit_via_fiq - like svc_exit but switches to FIQ mode before exit
+ @
+ @ For full details see non-Thumb implementation above.
+ @
+ .macro svc_exit_via_fiq
+ add r0, sp, #S_R2
+ ldr lr, [sp, #S_LR]
+ ldr sp, [sp, #S_SP] @ abort is deadly from here onward (it will
+ @ clobber state restored below)
+ ldmia r0, {r2 - r12}
+ mov r1, #FIQ_MODE | PSR_I_BIT | PSR_F_BIT
+ msr cpsr_c, r1
+ sub r0, #S_R2
+ add r8, r0, #S_PC
+ ldmia r0, {r0 - r1}
+ rfeia r8
+ .endm
+
+#ifdef CONFIG_CPU_V7M
+ /*
+ * Note we don't need to do clrex here as clearing the local monitor is
+ * part of each exception entry and exit sequence.
+ */
+ .macro restore_user_regs, fast = 0, offset = 0
+ .if \offset
+ add sp, #\offset
+ .endif
+ v7m_exception_slow_exit ret_r0 = \fast
+ .endm
+#else /* ifdef CONFIG_CPU_V7M */
+ .macro restore_user_regs, fast = 0, offset = 0
+ 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
+
+ @ We must avoid clrex due to Cortex-A15 erratum #830321
+ strex r1, r2, [sp] @ clear the exclusive monitor
+
+ .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
+#endif /* ifdef CONFIG_CPU_V7M / else */
+#endif /* !CONFIG_THUMB2_KERNEL */
+
+/*
+ * Context tracking subsystem. Used to instrument transitions
+ * between user and kernel mode.
+ */
+ .macro ct_user_exit, save = 1
+#ifdef CONFIG_CONTEXT_TRACKING
+ .if \save
+ stmdb sp!, {r0-r3, ip, lr}
+ bl context_tracking_user_exit
+ ldmia sp!, {r0-r3, ip, lr}
+ .else
+ bl context_tracking_user_exit
+ .endif
+#endif
+ .endm
+
+ .macro ct_user_enter, save = 1
+#ifdef CONFIG_CONTEXT_TRACKING
+ .if \save
+ stmdb sp!, {r0-r3, ip, lr}
+ bl context_tracking_user_enter
+ ldmia sp!, {r0-r3, ip, lr}
+ .else
+ bl context_tracking_user_enter
+ .endif
+#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/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
new file mode 100644
index 000000000..8944f4991
--- /dev/null
+++ b/arch/arm/kernel/entry-v7m.S
@@ -0,0 +1,143 @@
+/*
+ * linux/arch/arm/kernel/entry-v7m.S
+ *
+ * Copyright (C) 2008 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.
+ *
+ * Low-level vector interface routines for the ARMv7-M architecture
+ */
+#include <asm/memory.h>
+#include <asm/glue.h>
+#include <asm/thread_notify.h>
+#include <asm/v7m.h>
+
+#include "entry-header.S"
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+#error "CONFIG_TRACE_IRQFLAGS not supported on the current ARMv7M implementation"
+#endif
+
+__invalid_entry:
+ v7m_exception_entry
+#ifdef CONFIG_PRINTK
+ adr r0, strerr
+ mrs r1, ipsr
+ mov r2, lr
+ bl printk
+#endif
+ mov r0, sp
+ bl show_regs
+1: b 1b
+ENDPROC(__invalid_entry)
+
+strerr: .asciz "\nUnhandled exception: IPSR = %08lx LR = %08lx\n"
+
+ .align 2
+__irq_entry:
+ v7m_exception_entry
+
+ @
+ @ Invoke the IRQ handler
+ @
+ mrs r0, ipsr
+ ldr r1, =V7M_xPSR_EXCEPTIONNO
+ and r0, r1
+ sub r0, #16
+ mov r1, sp
+ stmdb sp!, {lr}
+ @ routine called with r0 = irq number, r1 = struct pt_regs *
+ bl nvic_handle_irq
+
+ pop {lr}
+ @
+ @ Check for any pending work if returning to user
+ @
+ ldr r1, =BASEADDR_V7M_SCB
+ ldr r0, [r1, V7M_SCB_ICSR]
+ tst r0, V7M_SCB_ICSR_RETTOBASE
+ beq 2f
+
+ get_thread_info tsk
+ ldr r2, [tsk, #TI_FLAGS]
+ tst r2, #_TIF_WORK_MASK
+ beq 2f @ no work pending
+ mov r0, #V7M_SCB_ICSR_PENDSVSET
+ str r0, [r1, V7M_SCB_ICSR] @ raise PendSV
+
+2:
+ @ registers r0-r3 and r12 are automatically restored on exception
+ @ return. r4-r7 were not clobbered in v7m_exception_entry so for
+ @ correctness they don't need to be restored. So only r8-r11 must be
+ @ restored here. The easiest way to do so is to restore r0-r7, too.
+ ldmia sp!, {r0-r11}
+ add sp, #S_FRAME_SIZE-S_IP
+ cpsie i
+ bx lr
+ENDPROC(__irq_entry)
+
+__pendsv_entry:
+ v7m_exception_entry
+
+ ldr r1, =BASEADDR_V7M_SCB
+ mov r0, #V7M_SCB_ICSR_PENDSVCLR
+ str r0, [r1, V7M_SCB_ICSR] @ clear PendSV
+
+ @ execute the pending work, including reschedule
+ get_thread_info tsk
+ mov why, #0
+ b ret_to_user
+ENDPROC(__pendsv_entry)
+
+/*
+ * Register switch for ARMv7-M 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)
+ .fnstart
+ .cantunwind
+ add ip, r1, #TI_CPU_SAVE
+ stmia ip!, {r4 - r11} @ Store most regs on stack
+ str sp, [ip], #4
+ str lr, [ip], #4
+ mov r5, r0
+ add r4, r2, #TI_CPU_SAVE
+ ldr r0, =thread_notify_head
+ mov r1, #THREAD_NOTIFY_SWITCH
+ bl atomic_notifier_call_chain
+ mov ip, r4
+ mov r0, r5
+ ldmia ip!, {r4 - r11} @ Load all regs saved previously
+ ldr sp, [ip]
+ ldr pc, [ip, #4]!
+ .fnend
+ENDPROC(__switch_to)
+
+ .data
+ .align 8
+/*
+ * Vector table (64 words => 256 bytes natural alignment)
+ */
+ENTRY(vector_table)
+ .long 0 @ 0 - Reset stack pointer
+ .long __invalid_entry @ 1 - Reset
+ .long __invalid_entry @ 2 - NMI
+ .long __invalid_entry @ 3 - HardFault
+ .long __invalid_entry @ 4 - MemManage
+ .long __invalid_entry @ 5 - BusFault
+ .long __invalid_entry @ 6 - UsageFault
+ .long __invalid_entry @ 7 - Reserved
+ .long __invalid_entry @ 8 - Reserved
+ .long __invalid_entry @ 9 - Reserved
+ .long __invalid_entry @ 10 - Reserved
+ .long vector_swi @ 11 - SVCall
+ .long __invalid_entry @ 12 - Debug Monitor
+ .long __invalid_entry @ 13 - Reserved
+ .long __pendsv_entry @ 14 - PendSV
+ .long __invalid_entry @ 15 - SysTick
+ .rept 64 - 16
+ .long __irq_entry @ 16..64 - External Interrupts
+ .endr
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
new file mode 100644
index 000000000..059c3da0f
--- /dev/null
+++ b/arch/arm/kernel/fiq.c
@@ -0,0 +1,164 @@
+/*
+ * 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/cp15.h>
+#include <asm/fiq.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+
+#define FIQ_OFFSET ({ \
+ extern void *vector_fiq_offset; \
+ (unsigned)&vector_fiq_offset; \
+ })
+
+static unsigned long dfl_fiq_insn;
+static struct pt_regs dfl_fiq_regs;
+
+/* Default reacquire function
+ * - we always relinquish FIQ control
+ * - we always reacquire FIQ control
+ */
+static int fiq_def_op(void *ref, int relinquish)
+{
+ if (!relinquish) {
+ /* Restore default handler and registers */
+ local_fiq_disable();
+ set_fiq_regs(&dfl_fiq_regs);
+ set_fiq_handler(&dfl_fiq_insn, sizeof(dfl_fiq_insn));
+ local_fiq_enable();
+
+ /* FIXME: notify irq controller to standard enable FIQs */
+ }
+
+ 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)
+{
+ void *base = vectors_page;
+ unsigned offset = FIQ_OFFSET;
+
+ memcpy(base + offset, start, length);
+ if (!cache_is_vipt_nonaliasing())
+ flush_icache_range((unsigned long)base + offset, offset +
+ length);
+ flush_icache_range(0xffff0000 + offset, 0xffff0000 + offset + 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) {
+ pr_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));
+}
+
+static int fiq_start;
+
+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(int start)
+{
+ unsigned offset = FIQ_OFFSET;
+ dfl_fiq_insn = *(unsigned long *)(0xffff0000 + offset);
+ get_fiq_regs(&dfl_fiq_regs);
+ fiq_start = start;
+}
diff --git a/arch/arm/kernel/fiqasm.S b/arch/arm/kernel/fiqasm.S
new file mode 100644
index 000000000..8dd26e1a9
--- /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
+ ret 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
+ ret lr
+ENDPROC(__get_fiq_regs)
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
new file mode 100644
index 000000000..709ee1d6d
--- /dev/null
+++ b/arch/arm/kernel/ftrace.c
@@ -0,0 +1,274 @@
+/*
+ * 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 <linux/module.h>
+#include <linux/stop_machine.h>
+
+#include <asm/cacheflush.h>
+#include <asm/opcodes.h>
+#include <asm/ftrace.h>
+#include <asm/insn.h>
+
+#ifdef CONFIG_THUMB2_KERNEL
+#define NOP 0xf85deb04 /* 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 int __ftrace_modify_code(void *data)
+{
+ int *command = data;
+
+ set_kernel_text_rw();
+ ftrace_modify_all_code(*command);
+ set_kernel_text_ro();
+
+ return 0;
+}
+
+void arch_ftrace_update_code(int command)
+{
+ stop_machine(__ftrace_modify_code, &command, NULL);
+}
+
+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
+
+int ftrace_arch_code_modify_prepare(void)
+{
+ set_all_modules_text_rw();
+ return 0;
+}
+
+int ftrace_arch_code_modify_post_process(void)
+{
+ set_all_modules_text_ro();
+ /* Make sure any TLB misses during machine stop are cleared. */
+ flush_tlb_all();
+ return 0;
+}
+
+static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
+{
+ return arm_gen_branch_link(pc, addr);
+}
+
+static int ftrace_modify_code(unsigned long pc, unsigned long old,
+ unsigned long new, bool validate)
+{
+ unsigned long replaced;
+
+ if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
+ old = __opcode_to_mem_thumb32(old);
+ new = __opcode_to_mem_thumb32(new);
+ } else {
+ old = __opcode_to_mem_arm(old);
+ new = __opcode_to_mem_arm(new);
+ }
+
+ if (validate) {
+ 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;
+ unsigned long new;
+ int ret;
+
+ pc = (unsigned long)&ftrace_call;
+ new = ftrace_call_replace(pc, (unsigned long)func);
+
+ ret = ftrace_modify_code(pc, 0, new, false);
+
+#ifdef CONFIG_OLD_MCOUNT
+ if (!ret) {
+ pc = (unsigned long)&ftrace_call_old;
+ new = ftrace_call_replace(pc, (unsigned long)func);
+
+ ret = ftrace_modify_code(pc, 0, new, false);
+ }
+#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, true);
+}
+
+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, true);
+
+#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, true);
+ }
+#endif
+
+ return ret;
+}
+
+int __init ftrace_dyn_arch_init(void)
+{
+ 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;
+
+ trace.func = self_addr;
+ trace.depth = current->curr_ret_stack + 1;
+
+ /* Only trace if the calling function expects to */
+ if (!ftrace_graph_entry(&trace)) {
+ *parent = old;
+ return;
+ }
+
+ err = ftrace_push_return_trace(old, self_addr, &trace.depth,
+ frame_pointer);
+ if (err == -EBUSY) {
+ *parent = old;
+ return;
+ }
+}
+
+#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 = arm_gen_branch(pc, caller_fn);
+ 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, true);
+}
+
+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 000000000..8733012d2
--- /dev/null
+++ b/arch/arm/kernel/head-common.S
@@ -0,0 +1,223 @@
+/*
+ * 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.
+ *
+ */
+#include <asm/assembler.h>
+
+#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: ret lr @ atag/dtb pointer is ok
+
+1: mov r2, #0
+ ret 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
+ cmp r7, #0
+ strne r0, [r7] @ 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
+#ifdef CONFIG_CPU_CP15
+ .long cr_alignment @ r7
+#else
+ .long 0 @ r7
+#endif
+ .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)
+
+ __FINIT
+ .text
+
+/*
+ * Read processor ID register (CP#15, CR0), and look up in the linker-built
+ * supported processor list. Note that we can't use the absolute addresses
+ * for the __proc_info lists since we aren't running with the MMU on
+ * (and therefore, we are not in the correct address space). We have to
+ * calculate the offset.
+ *
+ * r9 = cpuid
+ * Returns:
+ * r3, r4, r6 corrupted
+ * r5 = proc_info pointer in physical address space
+ * r9 = cpuid (preserved)
+ */
+__lookup_processor_type:
+ adr r3, __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: ret 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_lpae:
+#ifdef CONFIG_DEBUG_LL
+ adr r0, str_lpae
+ bl printascii
+ b __error
+str_lpae: .asciz "\nError: Kernel with LPAE support, but CPU does not support LPAE.\n"
+#else
+ b __error
+#endif
+ .align
+ENDPROC(__error_lpae)
+
+__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 000000000..aebfbf79a
--- /dev/null
+++ b/arch/arm/kernel/head-nommu.S
@@ -0,0 +1,260 @@
+/*
+ * 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/memory.h>
+#include <asm/cp15.h>
+#include <asm/thread_info.h>
+#include <asm/v7m.h>
+#include <asm/mpu.h>
+#include <asm/page.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
+
+#ifdef CONFIG_CPU_THUMBONLY
+ .thumb
+ENTRY(stext)
+#else
+ .arm
+ENTRY(stext)
+
+ THUMB( adr r9, BSYM(1f) ) @ Kernel is always entered in ARM.
+ THUMB( bx r9 ) @ If this is a Thumb-2 kernel,
+ THUMB( .thumb ) @ switch to Thumb now.
+ THUMB(1: )
+#endif
+
+ setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
+ @ and irqs disabled
+#if defined(CONFIG_CPU_CP15)
+ mrc p15, 0, r9, c0, c0 @ get processor id
+#elif defined(CONFIG_CPU_V7M)
+ ldr r9, =BASEADDR_V7M_SCB
+ ldr r9, [r9, V7M_SCB_CPUID]
+#else
+ ldr r9, =CONFIG_PROCESSOR_ID
+#endif
+ bl __lookup_processor_type @ r5=procinfo r9=cpuid
+ movs r10, r5 @ invalid processor (r5=0)?
+ beq __error_p @ yes, error 'p'
+
+#ifdef CONFIG_ARM_MPU
+ /* Calculate the size of a region covering just the kernel */
+ ldr r5, =PLAT_PHYS_OFFSET @ Region start: PHYS_OFFSET
+ ldr r6, =(_end) @ Cover whole kernel
+ sub r6, r6, r5 @ Minimum size of region to map
+ clz r6, r6 @ Region size must be 2^N...
+ rsb r6, r6, #31 @ ...so round up region size
+ lsl r6, r6, #MPU_RSR_SZ @ Put size in right field
+ orr r6, r6, #(1 << MPU_RSR_EN) @ Set region enabled bit
+ bl __setup_mpu
+#endif
+ ldr r13, =__mmap_switched @ address to jump to after
+ @ initialising sctlr
+ adr lr, BSYM(1f) @ return (PIC) address
+ ldr r12, [r10, #PROCINFO_INITFUNC]
+ add r12, r12, r10
+ ret r12
+ 1: b __after_proc_init
+ENDPROC(stext)
+
+#ifdef CONFIG_SMP
+ .text
+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
+#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?
+ beq __error_p @ yes, error 'p'
+
+ adr r4, __secondary_data
+ ldmia r4, {r7, r12}
+
+#ifdef CONFIG_ARM_MPU
+ /* Use MPU region info supplied by __cpu_up */
+ ldr r6, [r7] @ get secondary_data.mpu_szr
+ bl __setup_mpu @ Initialize the MPU
+#endif
+
+ adr lr, BSYM(__after_proc_init) @ return address
+ mov r13, r12 @ __secondary_switched address
+ ldr r12, [r10, #PROCINFO_INITFUNC]
+ add r12, r12, r10
+ ret r12
+ENDPROC(secondary_startup)
+
+ENTRY(__secondary_switched)
+ ldr sp, [r7, #8] @ set up the stack pointer
+ mov fp, #0
+ b secondary_start_kernel
+ENDPROC(__secondary_switched)
+
+ .type __secondary_data, %object
+__secondary_data:
+ .long secondary_data
+ .long __secondary_switched
+#endif /* CONFIG_SMP */
+
+/*
+ * 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.
+ */
+#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
+#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 */
+ ret r13
+ENDPROC(__after_proc_init)
+ .ltorg
+
+#ifdef CONFIG_ARM_MPU
+
+
+/* Set which MPU region should be programmed */
+.macro set_region_nr tmp, rgnr
+ mov \tmp, \rgnr @ Use static region numbers
+ mcr p15, 0, \tmp, c6, c2, 0 @ Write RGNR
+.endm
+
+/* Setup a single MPU region, either D or I side (D-side for unified) */
+.macro setup_region bar, acr, sr, side = MPU_DATA_SIDE
+ mcr p15, 0, \bar, c6, c1, (0 + \side) @ I/DRBAR
+ mcr p15, 0, \acr, c6, c1, (4 + \side) @ I/DRACR
+ mcr p15, 0, \sr, c6, c1, (2 + \side) @ I/DRSR
+.endm
+
+/*
+ * Setup the MPU and initial MPU Regions. We create the following regions:
+ * Region 0: Use this for probing the MPU details, so leave disabled.
+ * Region 1: Background region - covers the whole of RAM as strongly ordered
+ * Region 2: Normal, Shared, cacheable for RAM. From PHYS_OFFSET, size from r6
+ * Region 3: Normal, shared, inaccessible from PL0 to protect the vectors page
+ *
+ * r6: Value to be written to DRSR (and IRSR if required) for MPU_RAM_REGION
+*/
+
+ENTRY(__setup_mpu)
+
+ /* Probe for v7 PMSA compliance */
+ mrc p15, 0, r0, c0, c1, 4 @ Read ID_MMFR0
+ and r0, r0, #(MMFR0_PMSA) @ PMSA field
+ teq r0, #(MMFR0_PMSAv7) @ PMSA v7
+ bne __error_p @ Fail: ARM_MPU on NOT v7 PMSA
+
+ /* Determine whether the D/I-side memory map is unified. We set the
+ * flags here and continue to use them for the rest of this function */
+ mrc p15, 0, r0, c0, c0, 4 @ MPUIR
+ ands r5, r0, #MPUIR_DREGION_SZMASK @ 0 size d region => No MPU
+ beq __error_p @ Fail: ARM_MPU and no MPU
+ tst r0, #MPUIR_nU @ MPUIR_nU = 0 for unified
+
+ /* Setup second region first to free up r6 */
+ set_region_nr r0, #MPU_RAM_REGION
+ isb
+ /* Full access from PL0, PL1, shared for CONFIG_SMP, cacheable */
+ ldr r0, =PLAT_PHYS_OFFSET @ RAM starts at PHYS_OFFSET
+ ldr r5,=(MPU_AP_PL1RW_PL0RW | MPU_RGN_NORMAL)
+
+ setup_region r0, r5, r6, MPU_DATA_SIDE @ PHYS_OFFSET, shared, enabled
+ beq 1f @ Memory-map not unified
+ setup_region r0, r5, r6, MPU_INSTR_SIDE @ PHYS_OFFSET, shared, enabled
+1: isb
+
+ /* First/background region */
+ set_region_nr r0, #MPU_BG_REGION
+ isb
+ /* Execute Never, strongly ordered, inaccessible to PL0, rw PL1 */
+ mov r0, #0 @ BG region starts at 0x0
+ ldr r5,=(MPU_ACR_XN | MPU_RGN_STRONGLY_ORDERED | MPU_AP_PL1RW_PL0NA)
+ mov r6, #MPU_RSR_ALL_MEM @ 4GB region, enabled
+
+ setup_region r0, r5, r6, MPU_DATA_SIDE @ 0x0, BG region, enabled
+ beq 2f @ Memory-map not unified
+ setup_region r0, r5, r6, MPU_INSTR_SIDE @ 0x0, BG region, enabled
+2: isb
+
+ /* Vectors region */
+ set_region_nr r0, #MPU_VECTORS_REGION
+ isb
+ /* Shared, inaccessible to PL0, rw PL1 */
+ mov r0, #CONFIG_VECTORS_BASE @ Cover from VECTORS_BASE
+ ldr r5,=(MPU_AP_PL1RW_PL0NA | MPU_RGN_NORMAL)
+ /* Writing N to bits 5:1 (RSR_SZ) --> region size 2^N+1 */
+ mov r6, #(((PAGE_SHIFT - 1) << MPU_RSR_SZ) | 1 << MPU_RSR_EN)
+
+ setup_region r0, r5, r6, MPU_DATA_SIDE @ VECTORS_BASE, PL0 NA, enabled
+ beq 3f @ Memory-map not unified
+ setup_region r0, r5, r6, MPU_INSTR_SIDE @ VECTORS_BASE, PL0 NA, enabled
+3: isb
+
+ /* Enable the MPU */
+ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR
+ bic r0, r0, #CR_BR @ Disable the 'default mem-map'
+ orr r0, r0, #CR_M @ Set SCTRL.M (MPU on)
+ mcr p15, 0, r0, c1, c0, 0 @ Enable MPU
+ isb
+ ret lr
+ENDPROC(__setup_mpu)
+#endif
+#include "head-common.S"
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
new file mode 100644
index 000000000..3637973a9
--- /dev/null
+++ b/arch/arm/kernel/head.S
@@ -0,0 +1,712 @@
+/*
+ * 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/cp15.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/pgtable.h>
+
+#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_SEMIHOSTING)
+#include CONFIG_DEBUG_LL_INCLUDE
+#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
+
+#ifdef CONFIG_ARM_LPAE
+ /* LPAE requires an additional page for the PGD */
+#define PG_DIR_SIZE 0x5000
+#define PMD_ORDER 3
+#else
+#define PG_DIR_SIZE 0x4000
+#define PMD_ORDER 2
+#endif
+
+ .globl swapper_pg_dir
+ .equ swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE
+
+ .macro pgtbl, rd, phys
+ add \rd, \phys, #TEXT_OFFSET
+ sub \rd, \rd, #PG_DIR_SIZE
+ .endm
+
+/*
+ * 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.
+ */
+ .arm
+
+ __HEAD
+ENTRY(stext)
+ ARM_BE8(setend be ) @ ensure we are in BE8 mode
+
+ THUMB( adr r9, BSYM(1f) ) @ Kernel is always entered in ARM.
+ THUMB( bx r9 ) @ If this is a Thumb-2 kernel,
+ THUMB( .thumb ) @ switch to Thumb now.
+ THUMB(1: )
+
+#ifdef CONFIG_ARM_VIRT_EXT
+ bl __hyp_stub_install
+#endif
+ @ ensure svc mode and all interrupts masked
+ safe_svcmode_maskall r9
+
+ 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'
+
+#ifdef CONFIG_ARM_LPAE
+ mrc p15, 0, r3, c0, c1, 4 @ read ID_MMFR0
+ and r3, r3, #0xf @ extract VMSA support
+ cmp r3, #5 @ long-descriptor translation table format?
+ THUMB( it lo ) @ force fixup-able long branch encoding
+ blo __error_lpae @ only classic page table format
+#endif
+
+#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 @ always constant in this case
+#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
+ ldr r12, [r10, #PROCINFO_INITFUNC]
+ add r12, r12, r10
+ ret 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 = page table (see ARCH_PGD_SHIFT in asm/memory.h)
+ */
+__create_page_tables:
+ pgtbl r4, r8 @ page table address
+
+ /*
+ * Clear the swapper page table
+ */
+ mov r0, r4
+ mov r3, #0
+ add r6, r0, #PG_DIR_SIZE
+1: str r3, [r0], #4
+ str r3, [r0], #4
+ str r3, [r0], #4
+ str r3, [r0], #4
+ teq r0, r6
+ bne 1b
+
+#ifdef CONFIG_ARM_LPAE
+ /*
+ * Build the PGD table (first level) to point to the PMD table. A PGD
+ * entry is 64-bit wide.
+ */
+ mov r0, r4
+ add r3, r4, #0x1000 @ first PMD table address
+ orr r3, r3, #3 @ PGD block type
+ mov r6, #4 @ PTRS_PER_PGD
+ mov r7, #1 << (55 - 32) @ L_PGD_SWAPPER
+1:
+#ifdef CONFIG_CPU_ENDIAN_BE8
+ str r7, [r0], #4 @ set top PGD entry bits
+ str r3, [r0], #4 @ set bottom PGD entry bits
+#else
+ str r3, [r0], #4 @ set bottom PGD entry bits
+ str r7, [r0], #4 @ set top PGD entry bits
+#endif
+ add r3, r3, #0x1000 @ next PMD table
+ subs r6, r6, #1
+ bne 1b
+
+ add r4, r4, #0x1000 @ point to the PMD tables
+#ifdef CONFIG_CPU_ENDIAN_BE8
+ add r4, r4, #4 @ we only write the bottom word
+#endif
+#endif
+
+ 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, __turn_mmu_on_loc
+ ldmia r0, {r3, r5, r6}
+ sub r0, r0, r3 @ virt->phys offset
+ add r5, r5, r0 @ phys __turn_mmu_on
+ add r6, r6, r0 @ phys __turn_mmu_on_end
+ mov r5, r5, lsr #SECTION_SHIFT
+ mov r6, r6, lsr #SECTION_SHIFT
+
+1: orr r3, r7, r5, lsl #SECTION_SHIFT @ flags + kernel base
+ str r3, [r4, r5, lsl #PMD_ORDER] @ identity mapping
+ cmp r5, r6
+ addlo r5, r5, #1 @ next section
+ blo 1b
+
+ /*
+ * Map our RAM from the start to the end of the kernel .bss section.
+ */
+ add r0, r4, #PAGE_OFFSET >> (SECTION_SHIFT - PMD_ORDER)
+ ldr r6, =(_end - 1)
+ orr r3, r8, r7
+ add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
+1: str r3, [r0], #1 << PMD_ORDER
+ add r3, r3, #1 << SECTION_SHIFT
+ cmp r0, r6
+ bls 1b
+
+#ifdef CONFIG_XIP_KERNEL
+ /*
+ * Map the kernel image separately as it is not located in RAM.
+ */
+#define XIP_START XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
+ mov r3, pc
+ mov r3, r3, lsr #SECTION_SHIFT
+ orr r3, r7, r3, lsl #SECTION_SHIFT
+ add r0, r4, #(XIP_START & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER)
+ str r3, [r0, #((XIP_START & 0x00f00000) >> SECTION_SHIFT) << PMD_ORDER]!
+ ldr r6, =(_edata_loc - 1)
+ add r0, r0, #1 << PMD_ORDER
+ add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
+1: cmp r0, r6
+ add r3, r3, #1 << SECTION_SHIFT
+ strls r3, [r0], #1 << PMD_ORDER
+ bls 1b
+#endif
+
+ /*
+ * Then map boot params address in r2 if specified.
+ * We map 2 sections in case the ATAGs/DTB crosses a section boundary.
+ */
+ mov r0, r2, lsr #SECTION_SHIFT
+ movs r0, r0, lsl #SECTION_SHIFT
+ subne r3, r0, r8
+ addne r3, r3, #PAGE_OFFSET
+ addne r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER)
+ orrne r6, r7, r0
+ strne r6, [r3], #1 << PMD_ORDER
+ addne r6, r6, #1 << SECTION_SHIFT
+ strne r6, [r3]
+
+#if defined(CONFIG_ARM_LPAE) && defined(CONFIG_CPU_ENDIAN_BE8)
+ sub r4, r4, #4 @ Fixup page table pointer
+ @ for 64-bit descriptors
+#endif
+
+#ifdef CONFIG_DEBUG_LL
+#if !defined(CONFIG_DEBUG_ICEDCC) && !defined(CONFIG_DEBUG_SEMIHOSTING)
+ /*
+ * Map in IO space for serial debugging.
+ * This allows debug messages to be output
+ * via a serial console before paging_init.
+ */
+ addruart r7, r3, r0
+
+ mov r3, r3, lsr #SECTION_SHIFT
+ mov r3, r3, lsl #PMD_ORDER
+
+ add r0, r4, r3
+ mov r3, r7, lsr #SECTION_SHIFT
+ ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
+ orr r3, r7, r3, lsl #SECTION_SHIFT
+#ifdef CONFIG_ARM_LPAE
+ mov r7, #1 << (54 - 32) @ XN
+#ifdef CONFIG_CPU_ENDIAN_BE8
+ str r7, [r0], #4
+ str r3, [r0], #4
+#else
+ str r3, [r0], #4
+ str r7, [r0], #4
+#endif
+#else
+ orr r3, r3, #PMD_SECT_XN
+ str r3, [r0], #4
+#endif
+
+#else /* CONFIG_DEBUG_ICEDCC || CONFIG_DEBUG_SEMIHOSTING */
+ /* we don't need any serial debugging mappings */
+ ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
+#endif
+
+#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 >> (SECTION_SHIFT - PMD_ORDER)
+ 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 >> (SECTION_SHIFT - PMD_ORDER)
+ orr r3, r7, #0x02000000
+ str r3, [r0]
+ add r0, r4, #0xd8000000 >> (SECTION_SHIFT - PMD_ORDER)
+ str r3, [r0]
+#endif
+#endif
+#ifdef CONFIG_ARM_LPAE
+ sub r4, r4, #0x1000 @ point to the PGD table
+ mov r4, r4, lsr #ARCH_PGD_SHIFT
+#endif
+ ret lr
+ENDPROC(__create_page_tables)
+ .ltorg
+ .align
+__turn_mmu_on_loc:
+ .long .
+ .long __turn_mmu_on
+ .long __turn_mmu_on_end
+
+#if defined(CONFIG_SMP)
+ .text
+ENTRY(secondary_startup_arm)
+ .arm
+ THUMB( adr r9, BSYM(1f) ) @ Kernel is entered in ARM.
+ THUMB( bx r9 ) @ If this is a Thumb-2 kernel,
+ THUMB( .thumb ) @ switch to Thumb now.
+ THUMB(1: )
+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.
+ */
+
+ ARM_BE8(setend be) @ ensure we are in BE8 mode
+
+#ifdef CONFIG_ARM_VIRT_EXT
+ bl __hyp_stub_install_secondary
+#endif
+ safe_svcmode_maskall 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
+ ldr r12, [r10, #PROCINFO_INITFUNC]
+ add r12, r12, r10 @ initialise processor
+ @ (return control reg)
+ ret r12
+ENDPROC(secondary_startup)
+ENDPROC(secondary_startup_arm)
+
+ /*
+ * 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 (see ARCH_PGD_SHIFT in asm/memory.h)
+ * 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
+#ifndef CONFIG_ARM_LPAE
+ 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
+#endif
+ 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
+ .pushsection .idmap.text, "ax"
+ENTRY(__turn_mmu_on)
+ mov r0, r0
+ instr_sync
+ mcr p15, 0, r0, c1, c0, 0 @ write control reg
+ mrc p15, 0, r3, c0, c0, 0 @ read id reg
+ instr_sync
+ mov r3, r3
+ mov r3, r13
+ ret r3
+__turn_mmu_on_end:
+ENDPROC(__turn_mmu_on)
+ .popsection
+
+
+#ifdef CONFIG_SMP_ON_UP
+ __HEAD
+__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?
+ reteq 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?
+ bne __fixup_smp_on_up @ no, assume UP
+
+ @ Core indicates it is SMP. Check for Aegis SOC where a single
+ @ Cortex-A9 CPU is present but SMP operations fault.
+ mov r4, #0x41000000
+ orr r4, r4, #0x0000c000
+ orr r4, r4, #0x00000090
+ teq r3, r4 @ Check for ARM Cortex-A9
+ retne lr @ Not ARM Cortex-A9,
+
+ @ If a future SoC *does* use 0x0 as the PERIPH_BASE, then the
+ @ below address check will need to be #ifdef'd or equivalent
+ @ for the Aegis platform.
+ mrc p15, 4, r0, c15, c0 @ get SCU base address
+ teq r0, #0x0 @ '0' on actual UP A9 hardware
+ beq __fixup_smp_on_up @ So its an A9 UP
+ ldr r0, [r0, #4] @ read SCU Config
+ARM_BE8(rev r0, r0) @ byteswap if big endian
+ and r0, r0, #0x3 @ number of CPUs
+ teq r0, #0x0 @ is 1?
+ retne lr
+
+__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
+ reths 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 __ARMEB__
+#define LOW_OFFSET 0x4
+#define HIGH_OFFSET 0x0
+#else
+#define LOW_OFFSET 0x0
+#define HIGH_OFFSET 0x4
+#endif
+
+#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-r7}
+ mvn ip, #0
+ subs r3, r0, r3 @ PHYS_OFFSET - PAGE_OFFSET
+ add r4, r4, r3 @ adjust table start address
+ add r5, r5, r3 @ adjust table end address
+ add r6, r6, r3 @ adjust __pv_phys_pfn_offset address
+ add r7, r7, r3 @ adjust __pv_offset address
+ mov r0, r8, lsr #PAGE_SHIFT @ convert to PFN
+ str r0, [r6] @ save computed PHYS_OFFSET to __pv_phys_pfn_offset
+ strcc ip, [r7, #HIGH_OFFSET] @ save to __pv_offset high bits
+ mov r6, r3, lsr #24 @ constant for add/sub instructions
+ teq r3, r6, lsl #24 @ must be 16MiB aligned
+THUMB( it ne @ cross section branch )
+ bne __error
+ str r3, [r7, #LOW_OFFSET] @ save to __pv_offset low bits
+ b __fixup_a_pv_table
+ENDPROC(__fixup_pv_table)
+
+ .align
+1: .long .
+ .long __pv_table_begin
+ .long __pv_table_end
+2: .long __pv_phys_pfn_offset
+ .long __pv_offset
+
+ .text
+__fixup_a_pv_table:
+ adr r0, 3f
+ ldr r6, [r0]
+ add r6, r6, r3
+ ldr r0, [r6, #HIGH_OFFSET] @ pv_offset high word
+ ldr r6, [r6, #LOW_OFFSET] @ pv_offset low word
+ mov r6, r6, lsr #24
+ cmn r0, #1
+#ifdef CONFIG_THUMB2_KERNEL
+ moveq r0, #0x200000 @ set bit 21, mov to mvn instruction
+ lsls r6, #24
+ beq 2f
+ 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 2f
+1: add r7, r3
+ ldrh ip, [r7, #2]
+ARM_BE8(rev16 ip, ip)
+ tst ip, #0x4000
+ and ip, #0x8f00
+ orrne ip, r6 @ mask in offset bits 31-24
+ orreq ip, r0 @ mask in offset bits 7-0
+ARM_BE8(rev16 ip, ip)
+ strh ip, [r7, #2]
+ bne 2f
+ ldrh ip, [r7]
+ARM_BE8(rev16 ip, ip)
+ bic ip, #0x20
+ orr ip, ip, r0, lsr #16
+ARM_BE8(rev16 ip, ip)
+ strh ip, [r7]
+2: cmp r4, r5
+ ldrcc r7, [r4], #4 @ use branch for delay slot
+ bcc 1b
+ bx lr
+#else
+#ifdef CONFIG_CPU_ENDIAN_BE8
+ moveq r0, #0x00004000 @ set bit 22, mov to mvn instruction
+#else
+ moveq r0, #0x400000 @ set bit 22, mov to mvn instruction
+#endif
+ b 2f
+1: ldr ip, [r7, r3]
+#ifdef CONFIG_CPU_ENDIAN_BE8
+ @ in BE8, we load data in BE, but instructions still in LE
+ bic ip, ip, #0xff000000
+ tst ip, #0x000f0000 @ check the rotation field
+ orrne ip, ip, r6, lsl #24 @ mask in offset bits 31-24
+ biceq ip, ip, #0x00004000 @ clear bit 22
+ orreq ip, ip, r0 @ mask in offset bits 7-0
+#else
+ bic ip, ip, #0x000000ff
+ tst ip, #0xf00 @ check the rotation field
+ orrne ip, ip, r6 @ mask in offset bits 31-24
+ biceq ip, ip, #0x400000 @ clear bit 22
+ orreq ip, ip, r0 @ mask in offset bits 7-0
+#endif
+ str ip, [r7, r3]
+2: cmp r4, r5
+ ldrcc r7, [r4], #4 @ use branch for delay slot
+ bcc 1b
+ ret lr
+#endif
+ENDPROC(__fixup_a_pv_table)
+
+ .align
+3: .long __pv_offset
+
+ENTRY(fixup_pv_table)
+ stmfd sp!, {r4 - r7, lr}
+ mov r3, #0 @ no offset
+ mov r4, r0 @ r0 = table start
+ add r5, r0, r1 @ r1 = table size
+ bl __fixup_a_pv_table
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(fixup_pv_table)
+
+ .data
+ .globl __pv_phys_pfn_offset
+ .type __pv_phys_pfn_offset, %object
+__pv_phys_pfn_offset:
+ .word 0
+ .size __pv_phys_pfn_offset, . -__pv_phys_pfn_offset
+
+ .globl __pv_offset
+ .type __pv_offset, %object
+__pv_offset:
+ .quad 0
+ .size __pv_offset, . -__pv_offset
+#endif
+
+#include "head-common.S"
diff --git a/arch/arm/kernel/hibernate.c b/arch/arm/kernel/hibernate.c
new file mode 100644
index 000000000..a71501ff6
--- /dev/null
+++ b/arch/arm/kernel/hibernate.c
@@ -0,0 +1,106 @@
+/*
+ * Hibernation support specific for ARM
+ *
+ * Derived from work on ARM hibernation support by:
+ *
+ * Ubuntu project, hibernation support for mach-dove
+ * Copyright (C) 2010 Nokia Corporation (Hiroshi Doyu)
+ * Copyright (C) 2010 Texas Instruments, Inc. (Teerth Reddy et al.)
+ * https://lkml.org/lkml/2010/6/18/4
+ * https://lists.linux-foundation.org/pipermail/linux-pm/2010-June/027422.html
+ * https://patchwork.kernel.org/patch/96442/
+ *
+ * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/mm.h>
+#include <linux/suspend.h>
+#include <asm/system_misc.h>
+#include <asm/idmap.h>
+#include <asm/suspend.h>
+#include <asm/memory.h>
+#include <asm/sections.h>
+#include "reboot.h"
+
+int pfn_is_nosave(unsigned long pfn)
+{
+ unsigned long nosave_begin_pfn = virt_to_pfn(&__nosave_begin);
+ unsigned long nosave_end_pfn = virt_to_pfn(&__nosave_end - 1);
+
+ return (pfn >= nosave_begin_pfn) && (pfn <= nosave_end_pfn);
+}
+
+void notrace save_processor_state(void)
+{
+ WARN_ON(num_online_cpus() != 1);
+ local_fiq_disable();
+}
+
+void notrace restore_processor_state(void)
+{
+ local_fiq_enable();
+}
+
+/*
+ * Snapshot kernel memory and reset the system.
+ *
+ * swsusp_save() is executed in the suspend finisher so that the CPU
+ * context pointer and memory are part of the saved image, which is
+ * required by the resume kernel image to restart execution from
+ * swsusp_arch_suspend().
+ *
+ * soft_restart is not technically needed, but is used to get success
+ * returned from cpu_suspend.
+ *
+ * When soft reboot completes, the hibernation snapshot is written out.
+ */
+static int notrace arch_save_image(unsigned long unused)
+{
+ int ret;
+
+ ret = swsusp_save();
+ if (ret == 0)
+ _soft_restart(virt_to_phys(cpu_resume), false);
+ return ret;
+}
+
+/*
+ * Save the current CPU state before suspend / poweroff.
+ */
+int notrace swsusp_arch_suspend(void)
+{
+ return cpu_suspend(0, arch_save_image);
+}
+
+/*
+ * Restore page contents for physical pages that were in use during loading
+ * hibernation image. Switch to idmap_pgd so the physical page tables
+ * are overwritten with the same contents.
+ */
+static void notrace arch_restore_image(void *unused)
+{
+ struct pbe *pbe;
+
+ cpu_switch_mm(idmap_pgd, &init_mm);
+ for (pbe = restore_pblist; pbe; pbe = pbe->next)
+ copy_page(pbe->orig_address, pbe->address);
+
+ _soft_restart(virt_to_phys(cpu_resume), false);
+}
+
+static u64 resume_stack[PAGE_SIZE/2/sizeof(u64)] __nosavedata;
+
+/*
+ * Resume from the hibernation image.
+ * Due to the kernel heap / data restore, stack contents change underneath
+ * and that would make function calls impossible; switch to a temporary
+ * stack within the nosave region to avoid that problem.
+ */
+int swsusp_arch_resume(void)
+{
+ call_with_stack(arch_restore_image, 0,
+ resume_stack + ARRAY_SIZE(resume_stack));
+ return 0;
+}
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
new file mode 100644
index 000000000..dc7d0a95b
--- /dev/null
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -0,0 +1,1134 @@
+/*
+ * This program is free software; you can 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 <linux/cpu_pm.h>
+#include <linux/coresight.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cputype.h>
+#include <asm/current.h>
+#include <asm/hw_breakpoint.h>
+#include <asm/kdebug.h>
+#include <asm/traps.h>
+
+/* Breakpoint currently in use for each BRP. */
+static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[ARM_MAX_BRP]);
+
+/* Watchpoint currently in use for each WRP. */
+static DEFINE_PER_CPU(struct perf_event *, wp_on_reg[ARM_MAX_WRP]);
+
+/* Number of BRP/WRP registers on this CPU. */
+static int core_num_brps;
+static int core_num_wrps;
+
+/* Debug architecture version. */
+static u8 debug_arch;
+
+/* Does debug architecture support OS Save and Restore? */
+static bool has_ossr;
+
+/* Maximum supported watchpoint length. */
+static u8 max_watchpoint_len;
+
+#define READ_WB_REG_CASE(OP2, M, VAL) \
+ case ((OP2 << 4) + M): \
+ ARM_DBG_READ(c0, c ## M, OP2, VAL); \
+ break
+
+#define WRITE_WB_REG_CASE(OP2, M, VAL) \
+ case ((OP2 << 4) + M): \
+ ARM_DBG_WRITE(c0, 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_warn("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_warn("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 (((read_cpuid_id() >> 16) & 0xf) != 0xf) {
+ pr_warn_once("CPUID feature registers not supported. "
+ "Assuming v6 debug is present.\n");
+ return ARM_DEBUG_ARCH_V6;
+ }
+
+ ARM_DBG_READ(c0, 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();
+
+ /* We don't support the memory-mapped interface. */
+ return (arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14) ||
+ arch >= ARM_DEBUG_ARCH_V7_1;
+}
+
+/* Can we determine the watchpoint access type from the fsr? */
+static int debug_exception_updates_fsr(void)
+{
+ return get_debug_arch() >= ARM_DEBUG_ARCH_V8;
+}
+
+/* Determine number of WRP registers available. */
+static int get_num_wrp_resources(void)
+{
+ u32 didr;
+ ARM_DBG_READ(c0, c0, 0, didr);
+ return ((didr >> 28) & 0xf) + 1;
+}
+
+/* Determine number of BRP registers available. */
+static int get_num_brp_resources(void)
+{
+ u32 didr;
+ ARM_DBG_READ(c0, 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)
+{
+ /*
+ * On debug architectures prior to 7.1, 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 (get_debug_arch() < ARM_DEBUG_ARCH_V7_1)
+ return 1;
+
+ return get_num_wrp_resources();
+}
+
+/* Determine number of usable BRPs available. */
+static int get_num_brps(void)
+{
+ int brps = get_num_brp_resources();
+ return core_has_mismatch_brps() ? brps - 1 : 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 monitor_mode_enabled(void)
+{
+ u32 dscr;
+ ARM_DBG_READ(c0, c1, 0, dscr);
+ return !!(dscr & ARM_DSCR_MDBGEN);
+}
+
+static int enable_monitor_mode(void)
+{
+ u32 dscr;
+ ARM_DBG_READ(c0, c1, 0, dscr);
+
+ /* 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(c0, c1, 0, (dscr | ARM_DSCR_MDBGEN));
+ break;
+ case ARM_DEBUG_ARCH_V7_ECP14:
+ case ARM_DEBUG_ARCH_V7_1:
+ case ARM_DEBUG_ARCH_V8:
+ ARM_DBG_WRITE(c0, c2, 2, (dscr | ARM_DSCR_MDBGEN));
+ isb();
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ /* Check that the write made it through. */
+ ARM_DBG_READ(c0, c1, 0, dscr);
+ if (!(dscr & ARM_DSCR_MDBGEN)) {
+ pr_warn_once("Failed to enable monitor mode on CPU %d.\n",
+ smp_processor_id());
+ return -EPERM;
+ }
+
+out:
+ return 0;
+}
+
+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_warn("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;
+ u32 addr, ctrl;
+
+ 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 = this_cpu_ptr(bp_on_reg);
+ max_slots = core_num_brps;
+ } else {
+ /* Watchpoint */
+ ctrl_base = ARM_BASE_WCR;
+ val_base = ARM_BASE_WVR;
+ slots = this_cpu_ptr(wp_on_reg);
+ max_slots = core_num_wrps;
+ }
+
+ for (i = 0; i < max_slots; ++i) {
+ slot = &slots[i];
+
+ if (!*slot) {
+ *slot = bp;
+ break;
+ }
+ }
+
+ if (i == max_slots) {
+ pr_warn("Can't find any breakpoint slot\n");
+ return -EBUSY;
+ }
+
+ /* Override the breakpoint data with the step data. */
+ if (info->step_ctrl.enabled) {
+ addr = info->trigger & ~0x3;
+ ctrl = encode_ctrl_reg(info->step_ctrl);
+ if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE) {
+ i = 0;
+ ctrl_base = ARM_BASE_BCR + core_num_brps;
+ val_base = ARM_BASE_BVR + core_num_brps;
+ }
+ }
+
+ /* Setup the address register. */
+ write_wb_reg(val_base + i, addr);
+
+ /* Setup the control register. */
+ write_wb_reg(ctrl_base + i, ctrl);
+ return 0;
+}
+
+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 = this_cpu_ptr(bp_on_reg);
+ max_slots = core_num_brps;
+ } else {
+ /* Watchpoint */
+ base = ARM_BASE_WCR;
+ slots = this_cpu_ptr(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 (i == max_slots) {
+ pr_warn("Can't find any breakpoint slot\n");
+ return;
+ }
+
+ /* Ensure that we disable the mismatch breakpoint. */
+ if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE &&
+ info->step_ctrl.enabled) {
+ i = 0;
+ base = ARM_BASE_BCR + core_num_brps;
+ }
+
+ /* 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;
+
+ /* Ensure that we are in monitor debug mode. */
+ if (!monitor_mode_enabled())
+ return -ENODEV;
+
+ /* 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:
+ case 2:
+ /* Allow halfword watchpoints and breakpoints. */
+ if (info->ctrl.len == ARM_BREAKPOINT_LEN_2)
+ break;
+ case 3:
+ /* Allow single byte watchpoint. */
+ if (info->ctrl.len == ARM_BREAKPOINT_LEN_1)
+ break;
+ default:
+ ret = -EINVAL;
+ goto out;
+ }
+
+ info->address &= ~alignment_mask;
+ info->ctrl.len <<= offset;
+
+ if (!bp->overflow_handler) {
+ /*
+ * Mismatch breakpoints are required for single-stepping
+ * breakpoints.
+ */
+ if (!core_has_mismatch_brps())
+ return -EINVAL;
+
+ /* We don't allow mismatch breakpoints in kernel space. */
+ if (arch_check_bp_in_kernelspace(bp))
+ return -EPERM;
+
+ /*
+ * Per-cpu breakpoints are not supported by our stepping
+ * mechanism.
+ */
+ if (!bp->hw.target)
+ return -EINVAL;
+
+ /*
+ * We only support specific access types if the fsr
+ * reports them.
+ */
+ if (!debug_exception_updates_fsr() &&
+ (info->ctrl.type == ARM_BREAKPOINT_LOAD ||
+ info->ctrl.type == ARM_BREAKPOINT_STORE))
+ return -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 addr, unsigned int fsr,
+ struct pt_regs *regs)
+{
+ int i, access;
+ u32 val, ctrl_reg, alignment_mask;
+ struct perf_event *wp, **slots;
+ struct arch_hw_breakpoint *info;
+ struct arch_hw_breakpoint_ctrl ctrl;
+
+ slots = this_cpu_ptr(wp_on_reg);
+
+ for (i = 0; i < core_num_wrps; ++i) {
+ rcu_read_lock();
+
+ wp = slots[i];
+
+ if (wp == NULL)
+ goto unlock;
+
+ info = counter_arch_bp(wp);
+ /*
+ * The DFAR is an unknown value on debug architectures prior
+ * to 7.1. Since we only allow a single watchpoint on these
+ * older CPUs, we can set the trigger to the lowest possible
+ * faulting address.
+ */
+ if (debug_arch < ARM_DEBUG_ARCH_V7_1) {
+ BUG_ON(i > 0);
+ info->trigger = wp->attr.bp_addr;
+ } else {
+ if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
+ alignment_mask = 0x7;
+ else
+ alignment_mask = 0x3;
+
+ /* Check if the watchpoint value matches. */
+ val = read_wb_reg(ARM_BASE_WVR + i);
+ if (val != (addr & ~alignment_mask))
+ goto unlock;
+
+ /* Possible match, check the byte address select. */
+ ctrl_reg = read_wb_reg(ARM_BASE_WCR + i);
+ decode_ctrl_reg(ctrl_reg, &ctrl);
+ if (!((1 << (addr & alignment_mask)) & ctrl.len))
+ goto unlock;
+
+ /* Check that the access type matches. */
+ if (debug_exception_updates_fsr()) {
+ access = (fsr & ARM_FSR_ACCESS_MASK) ?
+ HW_BREAKPOINT_W : HW_BREAKPOINT_R;
+ if (!(access & hw_breakpoint_type(wp)))
+ goto unlock;
+ }
+
+ /* We have a winner. */
+ info->trigger = 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));
+
+unlock:
+ 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 = this_cpu_ptr(wp_on_reg);
+
+ for (i = 0; i < core_num_wrps; ++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 = this_cpu_ptr(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 interrupts disabled.
+ */
+static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
+ struct pt_regs *regs)
+{
+ int ret = 0;
+ u32 dscr;
+
+ preempt_disable();
+
+ if (interrupts_enabled(regs))
+ local_irq_enable();
+
+ /* We only handle watchpoints and hardware breakpoints. */
+ ARM_DBG_READ(c0, 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, fsr, regs);
+ break;
+ default:
+ ret = 1; /* Unhandled fault. */
+ }
+
+ preempt_enable();
+
+ return ret;
+}
+
+/*
+ * One-time initialisation.
+ */
+static cpumask_t debug_err_mask;
+
+static int debug_reg_trap(struct pt_regs *regs, unsigned int instr)
+{
+ int cpu = smp_processor_id();
+
+ pr_warn("Debug register access (0x%x) caused undefined instruction on CPU %d\n",
+ instr, cpu);
+
+ /* Set the error flag for this CPU and skip the faulting instruction. */
+ cpumask_set_cpu(cpu, &debug_err_mask);
+ instruction_pointer(regs) += 4;
+ return 0;
+}
+
+static struct undef_hook debug_reg_hook = {
+ .instr_mask = 0x0fe80f10,
+ .instr_val = 0x0e000e10,
+ .fn = debug_reg_trap,
+};
+
+/* Does this core support OS Save and Restore? */
+static bool core_has_os_save_restore(void)
+{
+ u32 oslsr;
+
+ switch (get_debug_arch()) {
+ case ARM_DEBUG_ARCH_V7_1:
+ return true;
+ case ARM_DEBUG_ARCH_V7_ECP14:
+ ARM_DBG_READ(c1, c1, 4, oslsr);
+ if (oslsr & ARM_OSLSR_OSLM0)
+ return true;
+ default:
+ return false;
+ }
+}
+
+static void reset_ctrl_regs(void *unused)
+{
+ int i, raw_num_brps, err = 0, cpu = smp_processor_id();
+ u32 val;
+
+ /*
+ * 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.
+ */
+ switch (debug_arch) {
+ case ARM_DEBUG_ARCH_V6:
+ case ARM_DEBUG_ARCH_V6_1:
+ /* ARMv6 cores clear the registers out of reset. */
+ goto out_mdbgen;
+ case ARM_DEBUG_ARCH_V7_ECP14:
+ /*
+ * Ensure sticky power-down is clear (i.e. debug logic is
+ * powered up).
+ */
+ ARM_DBG_READ(c1, c5, 4, val);
+ if ((val & 0x1) == 0)
+ err = -EPERM;
+
+ if (!has_ossr)
+ goto clear_vcr;
+ break;
+ case ARM_DEBUG_ARCH_V7_1:
+ /*
+ * Ensure the OS double lock is clear.
+ */
+ ARM_DBG_READ(c1, c3, 4, val);
+ if ((val & 0x1) == 1)
+ err = -EPERM;
+ break;
+ }
+
+ if (err) {
+ pr_warn_once("CPU %d debug is powered down!\n", cpu);
+ cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu));
+ return;
+ }
+
+ /*
+ * Unconditionally clear the OS lock by writing a value
+ * other than CS_LAR_KEY to the access register.
+ */
+ ARM_DBG_WRITE(c1, c0, 4, ~CORESIGHT_UNLOCK);
+ isb();
+
+ /*
+ * Clear any configured vector-catch events before
+ * enabling monitor mode.
+ */
+clear_vcr:
+ ARM_DBG_WRITE(c0, c7, 0, 0);
+ isb();
+
+ if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) {
+ pr_warn_once("CPU %d failed to disable vector catch\n", cpu);
+ return;
+ }
+
+ /*
+ * The control/value register pairs are UNKNOWN out of reset so
+ * clear them to avoid spurious debug events.
+ */
+ raw_num_brps = get_num_brp_resources();
+ for (i = 0; i < raw_num_brps; ++i) {
+ write_wb_reg(ARM_BASE_BCR + i, 0UL);
+ write_wb_reg(ARM_BASE_BVR + i, 0UL);
+ }
+
+ for (i = 0; i < core_num_wrps; ++i) {
+ write_wb_reg(ARM_BASE_WCR + i, 0UL);
+ write_wb_reg(ARM_BASE_WVR + i, 0UL);
+ }
+
+ if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) {
+ pr_warn_once("CPU %d failed to clear debug register pairs\n", cpu);
+ return;
+ }
+
+ /*
+ * Have a crack at enabling monitor mode. We don't actually need
+ * it yet, but reporting an error early is useful if it fails.
+ */
+out_mdbgen:
+ if (enable_monitor_mode())
+ cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu));
+}
+
+static int dbg_reset_notify(struct notifier_block *self,
+ unsigned long action, void *cpu)
+{
+ if ((action & ~CPU_TASKS_FROZEN) == CPU_ONLINE)
+ smp_call_function_single((int)cpu, reset_ctrl_regs, NULL, 1);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block dbg_reset_nb = {
+ .notifier_call = dbg_reset_notify,
+};
+
+#ifdef CONFIG_CPU_PM
+static int dbg_cpu_pm_notify(struct notifier_block *self, unsigned long action,
+ void *v)
+{
+ if (action == CPU_PM_EXIT)
+ reset_ctrl_regs(NULL);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block dbg_cpu_pm_nb = {
+ .notifier_call = dbg_cpu_pm_notify,
+};
+
+static void __init pm_init(void)
+{
+ cpu_pm_register_notifier(&dbg_cpu_pm_nb);
+}
+#else
+static inline void pm_init(void)
+{
+}
+#endif
+
+static int __init arch_hw_breakpoint_init(void)
+{
+ debug_arch = get_debug_arch();
+
+ if (!debug_arch_supported()) {
+ pr_info("debug architecture 0x%x unsupported.\n", debug_arch);
+ return 0;
+ }
+
+ has_ossr = core_has_os_save_restore();
+
+ /* Determine how many BRPs/WRPs are available. */
+ core_num_brps = get_num_brps();
+ core_num_wrps = get_num_wrps();
+
+ cpu_notifier_register_begin();
+
+ /*
+ * We need to tread carefully here because DBGSWENABLE may be
+ * driven low on this core and there isn't an architected way to
+ * determine that.
+ */
+ register_undef_hook(&debug_reg_hook);
+
+ /*
+ * 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, NULL, 1);
+ unregister_undef_hook(&debug_reg_hook);
+ if (!cpumask_empty(&debug_err_mask)) {
+ core_num_brps = 0;
+ core_num_wrps = 0;
+ cpu_notifier_register_done();
+ return 0;
+ }
+
+ pr_info("found %d " "%s" "breakpoint and %d watchpoint registers.\n",
+ core_num_brps, core_has_mismatch_brps() ? "(+1 reserved) " :
+ "", core_num_wrps);
+
+ /* 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(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP,
+ TRAP_HWBKPT, "watchpoint debug exception");
+ hook_ifault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP,
+ TRAP_HWBKPT, "breakpoint debug exception");
+
+ /* Register hotplug and PM notifiers. */
+ __register_cpu_notifier(&dbg_reset_nb);
+
+ cpu_notifier_register_done();
+
+ pm_init();
+ 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/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
new file mode 100644
index 000000000..2a55373f4
--- /dev/null
+++ b/arch/arm/kernel/hyp-stub.S
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2012 Linaro 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/virt.h>
+
+#ifndef ZIMAGE
+/*
+ * For the kernel proper, we need to find out the CPU boot mode long after
+ * boot, so we need to store it in a writable variable.
+ *
+ * This is not in .bss, because we set it sufficiently early that the boot-time
+ * zeroing of .bss would clobber it.
+ */
+.data
+ENTRY(__boot_cpu_mode)
+ .long 0
+.text
+
+ /*
+ * Save the primary CPU boot mode. Requires 3 scratch registers.
+ */
+ .macro store_primary_cpu_mode reg1, reg2, reg3
+ mrs \reg1, cpsr
+ and \reg1, \reg1, #MODE_MASK
+ adr \reg2, .L__boot_cpu_mode_offset
+ ldr \reg3, [\reg2]
+ str \reg1, [\reg2, \reg3]
+ .endm
+
+ /*
+ * Compare the current mode with the one saved on the primary CPU.
+ * If they don't match, record that fact. The Z bit indicates
+ * if there's a match or not.
+ * Requires 3 additionnal scratch registers.
+ */
+ .macro compare_cpu_mode_with_primary mode, reg1, reg2, reg3
+ adr \reg2, .L__boot_cpu_mode_offset
+ ldr \reg3, [\reg2]
+ ldr \reg1, [\reg2, \reg3]
+ cmp \mode, \reg1 @ matches primary CPU boot mode?
+ orrne \reg1, \reg1, #BOOT_CPU_MODE_MISMATCH
+ strne \reg1, [\reg2, \reg3] @ record what happened and give up
+ .endm
+
+#else /* ZIMAGE */
+
+ .macro store_primary_cpu_mode reg1:req, reg2:req, reg3:req
+ .endm
+
+/*
+ * The zImage loader only runs on one CPU, so we don't bother with mult-CPU
+ * consistency checking:
+ */
+ .macro compare_cpu_mode_with_primary mode, reg1, reg2, reg3
+ cmp \mode, \mode
+ .endm
+
+#endif /* ZIMAGE */
+
+/*
+ * Hypervisor stub installation functions.
+ *
+ * These must be called with the MMU and D-cache off.
+ * They are not ABI compliant and are only intended to be called from the kernel
+ * entry points in head.S.
+ */
+@ Call this from the primary CPU
+ENTRY(__hyp_stub_install)
+ store_primary_cpu_mode r4, r5, r6
+ENDPROC(__hyp_stub_install)
+
+ @ fall through...
+
+@ Secondary CPUs should call here
+ENTRY(__hyp_stub_install_secondary)
+ mrs r4, cpsr
+ and r4, r4, #MODE_MASK
+
+ /*
+ * If the secondary has booted with a different mode, give up
+ * immediately.
+ */
+ compare_cpu_mode_with_primary r4, r5, r6, r7
+ retne lr
+
+ /*
+ * Once we have given up on one CPU, we do not try to install the
+ * stub hypervisor on the remaining ones: because the saved boot mode
+ * is modified, it can't compare equal to the CPSR mode field any
+ * more.
+ *
+ * Otherwise...
+ */
+
+ cmp r4, #HYP_MODE
+ retne lr @ give up if the CPU is not in HYP mode
+
+/*
+ * Configure HSCTLR to set correct exception endianness/instruction set
+ * state etc.
+ * Turn off all traps
+ * Eventually, CPU-specific code might be needed -- assume not for now
+ *
+ * This code relies on the "eret" instruction to synchronize the
+ * various coprocessor accesses. This is done when we switch to SVC
+ * (see safe_svcmode_maskall).
+ */
+ @ Now install the hypervisor stub:
+ adr r7, __hyp_stub_vectors
+ mcr p15, 4, r7, c12, c0, 0 @ set hypervisor vector base (HVBAR)
+
+ @ Disable all traps, so we don't get any nasty surprise
+ mov r7, #0
+ mcr p15, 4, r7, c1, c1, 0 @ HCR
+ mcr p15, 4, r7, c1, c1, 2 @ HCPTR
+ mcr p15, 4, r7, c1, c1, 3 @ HSTR
+
+THUMB( orr r7, #(1 << 30) ) @ HSCTLR.TE
+ARM_BE8(orr r7, r7, #(1 << 25)) @ HSCTLR.EE
+ mcr p15, 4, r7, c1, c0, 0 @ HSCTLR
+
+ mrc p15, 4, r7, c1, c1, 1 @ HDCR
+ and r7, #0x1f @ Preserve HPMN
+ mcr p15, 4, r7, c1, c1, 1 @ HDCR
+
+#if !defined(ZIMAGE) && defined(CONFIG_ARM_ARCH_TIMER)
+ @ make CNTP_* and CNTPCT accessible from PL1
+ mrc p15, 0, r7, c0, c1, 1 @ ID_PFR1
+ lsr r7, #16
+ and r7, #0xf
+ cmp r7, #1
+ bne 1f
+ mrc p15, 4, r7, c14, c1, 0 @ CNTHCTL
+ orr r7, r7, #3 @ PL1PCEN | PL1PCTEN
+ mcr p15, 4, r7, c14, c1, 0 @ CNTHCTL
+ mov r7, #0
+ mcrr p15, 4, r7, r7, c14 @ CNTVOFF
+
+ @ Disable virtual timer in case it was counting
+ mrc p15, 0, r7, c14, c3, 1 @ CNTV_CTL
+ bic r7, #1 @ Clear ENABLE
+ mcr p15, 0, r7, c14, c3, 1 @ CNTV_CTL
+1:
+#endif
+
+ bx lr @ The boot CPU mode is left in r4.
+ENDPROC(__hyp_stub_install_secondary)
+
+__hyp_stub_do_trap:
+ cmp r0, #-1
+ mrceq p15, 4, r0, c12, c0, 0 @ get HVBAR
+ mcrne p15, 4, r0, c12, c0, 0 @ set HVBAR
+ __ERET
+ENDPROC(__hyp_stub_do_trap)
+
+/*
+ * __hyp_set_vectors: Call this after boot to set the initial hypervisor
+ * vectors as part of hypervisor installation. On an SMP system, this should
+ * be called on each CPU.
+ *
+ * r0 must be the physical address of the new vector table (which must lie in
+ * the bottom 4GB of physical address space.
+ *
+ * r0 must be 32-byte aligned.
+ *
+ * Before calling this, you must check that the stub hypervisor is installed
+ * everywhere, by waiting for any secondary CPUs to be brought up and then
+ * checking that BOOT_CPU_MODE_HAVE_HYP(__boot_cpu_mode) is true.
+ *
+ * If not, there is a pre-existing hypervisor, some CPUs failed to boot, or
+ * something else went wrong... in such cases, trying to install a new
+ * hypervisor is unlikely to work as desired.
+ *
+ * When you call into your shiny new hypervisor, sp_hyp will contain junk,
+ * so you will need to set that to something sensible at the new hypervisor's
+ * initialisation entry point.
+ */
+ENTRY(__hyp_get_vectors)
+ mov r0, #-1
+ENDPROC(__hyp_get_vectors)
+ @ fall through
+ENTRY(__hyp_set_vectors)
+ __HVC(0)
+ ret lr
+ENDPROC(__hyp_set_vectors)
+
+#ifndef ZIMAGE
+.align 2
+.L__boot_cpu_mode_offset:
+ .long __boot_cpu_mode - .
+#endif
+
+.align 5
+__hyp_stub_vectors:
+__hyp_stub_reset: W(b) .
+__hyp_stub_und: W(b) .
+__hyp_stub_svc: W(b) .
+__hyp_stub_pabort: W(b) .
+__hyp_stub_dabort: W(b) .
+__hyp_stub_trap: W(b) __hyp_stub_do_trap
+__hyp_stub_irq: W(b) .
+__hyp_stub_fiq: W(b) .
+ENDPROC(__hyp_stub_vectors)
+
diff --git a/arch/arm/kernel/insn.c b/arch/arm/kernel/insn.c
new file mode 100644
index 000000000..b760340b7
--- /dev/null
+++ b/arch/arm/kernel/insn.c
@@ -0,0 +1,62 @@
+#include <linux/bug.h>
+#include <linux/kernel.h>
+#include <asm/opcodes.h>
+
+static unsigned long
+__arm_gen_branch_thumb2(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 __opcode_thumb32_compose(first, second);
+}
+
+static unsigned long
+__arm_gen_branch_arm(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)) {
+ WARN_ON_ONCE(1);
+ return 0;
+ }
+
+ offset = (offset >> 2) & 0x00ffffff;
+
+ return opcode | offset;
+}
+
+unsigned long
+__arm_gen_branch(unsigned long pc, unsigned long addr, bool link)
+{
+ if (IS_ENABLED(CONFIG_THUMB2_KERNEL))
+ return __arm_gen_branch_thumb2(pc, addr, link);
+ else
+ return __arm_gen_branch_arm(pc, addr, link);
+}
diff --git a/arch/arm/kernel/io.c b/arch/arm/kernel/io.c
new file mode 100644
index 000000000..eedefe050
--- /dev/null
+++ b/arch/arm/kernel/io.c
@@ -0,0 +1,84 @@
+#include <linux/export.h>
+#include <linux/types.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+static DEFINE_RAW_SPINLOCK(__io_lock);
+
+/*
+ * Generic atomic MMIO modify.
+ *
+ * Allows thread-safe access to registers shared by unrelated subsystems.
+ * The access is protected by a single MMIO-wide lock.
+ */
+void atomic_io_modify_relaxed(void __iomem *reg, u32 mask, u32 set)
+{
+ unsigned long flags;
+ u32 value;
+
+ raw_spin_lock_irqsave(&__io_lock, flags);
+ value = readl_relaxed(reg) & ~mask;
+ value |= (set & mask);
+ writel_relaxed(value, reg);
+ raw_spin_unlock_irqrestore(&__io_lock, flags);
+}
+EXPORT_SYMBOL(atomic_io_modify_relaxed);
+
+void atomic_io_modify(void __iomem *reg, u32 mask, u32 set)
+{
+ unsigned long flags;
+ u32 value;
+
+ raw_spin_lock_irqsave(&__io_lock, flags);
+ value = readl_relaxed(reg) & ~mask;
+ value |= (set & mask);
+ writel(value, reg);
+ raw_spin_unlock_irqrestore(&__io_lock, flags);
+}
+EXPORT_SYMBOL(atomic_io_modify);
+
+/*
+ * 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++;
+ }
+}
+EXPORT_SYMBOL(_memcpy_fromio);
+
+/*
+ * 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++;
+ }
+}
+EXPORT_SYMBOL(_memcpy_toio);
+
+/*
+ * "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(_memset_io);
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
new file mode 100644
index 000000000..350f188c9
--- /dev/null
+++ b/arch/arm/kernel/irq.c
@@ -0,0 +1,198 @@
+/*
+ * 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/signal.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/random.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/seq_file.h>
+#include <linux/ratelimit.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/kallsyms.h>
+#include <linux/proc_fs.h>
+#include <linux/export.h>
+
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/exception.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+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
+ 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)
+{
+ __handle_domain_irq(NULL, irq, false, 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) {
+ pr_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);
+}
+EXPORT_SYMBOL_GPL(set_irq_flags);
+
+void __init init_IRQ(void)
+{
+ int ret;
+
+ if (IS_ENABLED(CONFIG_OF) && !machine_desc->init_irq)
+ irqchip_init();
+ else
+ machine_desc->init_irq();
+
+ if (IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_CACHE_L2X0) &&
+ (machine_desc->l2c_aux_mask || machine_desc->l2c_aux_val)) {
+ if (!outer_cache.write_sec)
+ outer_cache.write_sec = machine_desc->l2c_write_sec;
+ ret = l2x0_of_init(machine_desc->l2c_aux_val,
+ machine_desc->l2c_aux_mask);
+ if (ret)
+ pr_err("L2C: failed to init: %d\n", ret);
+ }
+}
+
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+void __init set_handle_irq(void (*handle_irq)(struct pt_regs *))
+{
+ if (handle_arch_irq)
+ return;
+
+ handle_arch_irq = handle_irq;
+}
+#endif
+
+#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, false) == 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)
+ pr_warn_ratelimited("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 000000000..9d1cf7156
--- /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 struct 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 struct ctl_table ctl_isa[2] = {
+ {
+ .procname = "isa",
+ .mode = 0555,
+ .child = ctl_isa_vars,
+ }, {}
+};
+
+static struct 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 000000000..49fadbda8
--- /dev/null
+++ b/arch/arm/kernel/iwmmxt.S
@@ -0,0 +1,372 @@
+/*
+ * 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>
+#include <asm/assembler.h>
+
+#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B)
+#define PJ4(code...) code
+#define XSC(code...)
+#elif defined(CONFIG_CPU_MOHAWK) || \
+ defined(CONFIG_CPU_XSC3) || \
+ defined(CONFIG_CPU_XSCALE)
+#define PJ4(code...)
+#define XSC(code...) code
+#else
+#error "Unsupported iWMMXt architecture"
+#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
+ .arm
+
+/*
+ * 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 enabled
+ */
+
+ENTRY(iwmmxt_task_enable)
+ inc_preempt_count r10, r3
+
+ 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)
+ bne 4f @ 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
+ bl concan_save
+
+#ifdef CONFIG_PREEMPT_COUNT
+ get_thread_info r10
+#endif
+4: dec_preempt_count r10, r3
+ ret r9 @ normal exit from exception
+
+concan_save:
+
+ teq r1, #0 @ test for last ownership
+ beq concan_load @ no owner, skip 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?
+ reteq lr @ if not, return
+
+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
+ reteq lr
+
+ tmcr wCon, r2
+ ret lr
+
+ENDPROC(iwmmxt_task_enable)
+
+/*
+ * 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, #0x3)
+ XSC(mcr p15, 0, r4, c15, c1, 0)
+ PJ4(mrc p15, 0, r4, c1, c0, 2)
+ PJ4(orr r4, r4, #0xf)
+ 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}
+
+ENDPROC(iwmmxt_task_disable)
+
+/*
+ * 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
+ ret r3
+
+ENDPROC(iwmmxt_task_copy)
+
+/*
+ * 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
+ ret r3
+
+ENDPROC(iwmmxt_task_restore)
+
+/*
+ * 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?
+ retne lr @ no: leave Concan disabled
+
+1: @ flip Concan 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
+
+ENDPROC(iwmmxt_task_switch)
+
+/*
+ * 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
+ ret lr
+
+ENDPROC(iwmmxt_task_release)
+
+ .data
+concan_owner:
+ .word 0
+
diff --git a/arch/arm/kernel/jump_label.c b/arch/arm/kernel/jump_label.c
new file mode 100644
index 000000000..e39cbf488
--- /dev/null
+++ b/arch/arm/kernel/jump_label.c
@@ -0,0 +1,38 @@
+#include <linux/kernel.h>
+#include <linux/jump_label.h>
+#include <asm/patch.h>
+#include <asm/insn.h>
+
+#ifdef HAVE_JUMP_LABEL
+
+static void __arch_jump_label_transform(struct jump_entry *entry,
+ enum jump_label_type type,
+ bool is_static)
+{
+ void *addr = (void *)entry->code;
+ unsigned int insn;
+
+ if (type == JUMP_LABEL_ENABLE)
+ insn = arm_gen_branch(entry->code, entry->target);
+ else
+ insn = arm_gen_nop();
+
+ if (is_static)
+ __patch_text_early(addr, insn);
+ else
+ patch_text(addr, insn);
+}
+
+void arch_jump_label_transform(struct jump_entry *entry,
+ enum jump_label_type type)
+{
+ __arch_jump_label_transform(entry, type, false);
+}
+
+void arch_jump_label_transform_static(struct jump_entry *entry,
+ enum jump_label_type type)
+{
+ __arch_jump_label_transform(entry, type, true);
+}
+
+#endif
diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
new file mode 100644
index 000000000..a6ad93c9b
--- /dev/null
+++ b/arch/arm/kernel/kgdb.c
@@ -0,0 +1,287 @@
+/*
+ * 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 <linux/uaccess.h>
+
+#include <asm/patch.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,
+ .cpsr_mask = MODE_MASK,
+ .cpsr_val = SVC_MODE,
+ .fn = kgdb_brk_fn
+};
+
+static struct undef_hook kgdb_compiled_brkpt_hook = {
+ .instr_mask = 0xffffffff,
+ .instr_val = KGDB_COMPILED_BREAK,
+ .cpsr_mask = MODE_MASK,
+ .cpsr_val = SVC_MODE,
+ .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);
+}
+
+int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
+{
+ int err;
+
+ /* patch_text() only supports int-sized breakpoints */
+ BUILD_BUG_ON(sizeof(int) != BREAK_INSTR_SIZE);
+
+ err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
+ BREAK_INSTR_SIZE);
+ if (err)
+ return err;
+
+ patch_text((void *)bpt->bpt_addr,
+ *(unsigned int *)arch_kgdb_ops.gdb_bpt_instr);
+
+ return err;
+}
+
+int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
+{
+ patch_text((void *)bpt->bpt_addr, *(unsigned int *)bpt->saved_instr);
+
+ return 0;
+}
+
+/*
+ * 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/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
new file mode 100644
index 000000000..8bf3b7c09
--- /dev/null
+++ b/arch/arm/kernel/machine_kexec.c
@@ -0,0 +1,195 @@
+/*
+ * 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 <linux/irq.h>
+#include <linux/memblock.h>
+#include <asm/pgtable.h>
+#include <linux/of_fdt.h>
+#include <asm/pgalloc.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+#include <asm/fncpy.h>
+#include <asm/mach-types.h>
+#include <asm/smp_plat.h>
+#include <asm/system_misc.h>
+
+extern void relocate_new_kernel(void);
+extern const unsigned int relocate_new_kernel_size;
+
+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;
+
+static unsigned long dt_mem;
+/*
+ * 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)
+{
+ struct kexec_segment *current_segment;
+ __be32 header;
+ int i, err;
+
+ /*
+ * Validate that if the current HW supports SMP, then the SW supports
+ * and implements CPU hotplug for the current HW. If not, we won't be
+ * able to kexec reliably, so fail the prepare operation.
+ */
+ if (num_possible_cpus() > 1 && platform_can_secondary_boot() &&
+ !platform_can_cpu_hotplug())
+ return -EINVAL;
+
+ /*
+ * No segment at default ATAGs address. try to locate
+ * a dtb using magic.
+ */
+ for (i = 0; i < image->nr_segments; i++) {
+ current_segment = &image->segment[i];
+
+ if (!memblock_is_region_memory(current_segment->mem,
+ current_segment->memsz))
+ return -EINVAL;
+
+ err = get_user(header, (__be32*)current_segment->buf);
+ if (err)
+ return err;
+
+ if (be32_to_cpu(header) == OF_DT_HEADER)
+ dt_mem = current_segment->mem;
+ }
+ 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();
+
+ set_cpu_online(smp_processor_id(), false);
+ atomic_dec(&waiting_for_crash_ipi);
+ while (1)
+ cpu_relax();
+}
+
+static void machine_kexec_mask_interrupts(void)
+{
+ unsigned int i;
+ struct irq_desc *desc;
+
+ for_each_irq_desc(i, desc) {
+ struct irq_chip *chip;
+
+ chip = irq_desc_get_chip(desc);
+ if (!chip)
+ continue;
+
+ if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
+ chip->irq_eoi(&desc->irq_data);
+
+ if (chip->irq_mask)
+ chip->irq_mask(&desc->irq_data);
+
+ if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
+ chip->irq_disable(&desc->irq_data);
+ }
+}
+
+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)
+ pr_warn("Non-crashing CPUs did not react to IPI\n");
+
+ crash_save_cpu(regs, smp_processor_id());
+ machine_kexec_mask_interrupts();
+
+ pr_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;
+ unsigned long reboot_entry = (unsigned long)relocate_new_kernel;
+ unsigned long reboot_entry_phys;
+ void *reboot_code_buffer;
+
+ /*
+ * This can only happen if machine_shutdown() failed to disable some
+ * CPU, and that can only happen if the checks in
+ * machine_kexec_prepare() were not correct. If this fails, we can't
+ * reliably kexec anyway, so BUG_ON is appropriate.
+ */
+ BUG_ON(num_online_cpus() > 1);
+
+ 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*/
+ set_kernel_text_rw();
+ kexec_start_address = image->start;
+ kexec_indirection_page = page_list;
+ kexec_mach_type = machine_arch_type;
+ kexec_boot_atags = dt_mem ?: image->start - KEXEC_ARM_ZIMAGE_OFFSET
+ + KEXEC_ARM_ATAGS_OFFSET;
+
+ /* copy our kernel relocation code to the control code page */
+ reboot_entry = fncpy(reboot_code_buffer,
+ reboot_entry,
+ relocate_new_kernel_size);
+ reboot_entry_phys = (unsigned long)reboot_entry +
+ (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer);
+
+ pr_info("Bye!\n");
+
+ if (kexec_reinit)
+ kexec_reinit();
+
+ soft_restart(reboot_entry_phys);
+}
+
+void arch_crash_save_vmcoreinfo(void)
+{
+#ifdef CONFIG_ARM_LPAE
+ VMCOREINFO_CONFIG(ARM_LPAE);
+#endif
+}
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
new file mode 100644
index 000000000..af791f4a6
--- /dev/null
+++ b/arch/arm/kernel/module.c
@@ -0,0 +1,366 @@
+/*
+ * 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>
+#include <asm/opcodes.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 + ~PMD_MASK) & PMD_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, 0, NUMA_NO_NODE,
+ __builtin_return_address(0));
+}
+#endif
+
+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;
+ u32 tmp;
+#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:
+ case R_ARM_TARGET1:
+ *(u32 *)loc += sym->st_value;
+ break;
+
+ case R_ARM_PC24:
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
+ if (sym->st_value & 3) {
+ pr_err("%s: section %u reloc %u sym '%s': unsupported interworking call (ARM -> Thumb)\n",
+ module->name, relindex, i, symname);
+ return -ENOEXEC;
+ }
+
+ offset = __mem_to_opcode_arm(*(u32 *)loc);
+ offset = (offset & 0x00ffffff) << 2;
+ if (offset & 0x02000000)
+ offset -= 0x04000000;
+
+ offset += sym->st_value - loc;
+ if (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;
+ offset &= 0x00ffffff;
+
+ *(u32 *)loc &= __opcode_to_mem_arm(0xff000000);
+ *(u32 *)loc |= __opcode_to_mem_arm(offset);
+ break;
+
+ case R_ARM_V4BX:
+ /* Preserve Rm and the condition code. Alter
+ * other bits to re-code instruction as
+ * MOV PC,Rm.
+ */
+ *(u32 *)loc &= __opcode_to_mem_arm(0xf000000f);
+ *(u32 *)loc |= __opcode_to_mem_arm(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 = tmp = __mem_to_opcode_arm(*(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;
+
+ tmp &= 0xfff0f000;
+ tmp |= ((offset & 0xf000) << 4) |
+ (offset & 0x0fff);
+
+ *(u32 *)loc = __opcode_to_mem_arm(tmp);
+ break;
+
+#ifdef CONFIG_THUMB2_KERNEL
+ case R_ARM_THM_CALL:
+ case R_ARM_THM_JUMP24:
+ /*
+ * 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 &&
+ !(sym->st_value & 1)) {
+ pr_err("%s: section %u reloc %u sym '%s': unsupported interworking call (Thumb -> ARM)\n",
+ module->name, relindex, i, symname);
+ return -ENOEXEC;
+ }
+
+ upper = __mem_to_opcode_thumb16(*(u16 *)loc);
+ lower = __mem_to_opcode_thumb16(*(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;
+
+ if (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);
+ upper = (u16)((upper & 0xf800) | (sign << 10) |
+ ((offset >> 12) & 0x03ff));
+ lower = (u16)((lower & 0xd000) |
+ (j1 << 13) | (j2 << 11) |
+ ((offset >> 1) & 0x07ff));
+
+ *(u16 *)loc = __opcode_to_mem_thumb16(upper);
+ *(u16 *)(loc + 2) = __opcode_to_mem_thumb16(lower);
+ break;
+
+ case R_ARM_THM_MOVW_ABS_NC:
+ case R_ARM_THM_MOVT_ABS:
+ upper = __mem_to_opcode_thumb16(*(u16 *)loc);
+ lower = __mem_to_opcode_thumb16(*(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;
+
+ upper = (u16)((upper & 0xfbf0) |
+ ((offset & 0xf000) >> 12) |
+ ((offset & 0x0800) >> 1));
+ lower = (u16)((lower & 0x8f00) |
+ ((offset & 0x0700) << 4) |
+ (offset & 0x00ff));
+ *(u16 *)loc = __opcode_to_mem_thumb16(upper);
+ *(u16 *)(loc + 2) = __opcode_to_mem_thumb16(lower);
+ break;
+#endif
+
+ default:
+ pr_err("%s: unknown relocation: %u\n",
+ module->name, ELF32_R_TYPE(rel->r_info));
+ return -ENOEXEC;
+ }
+ }
+ return 0;
+}
+
+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", 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.text.unlikely", secname) == 0)
+ maps[ARM_SEC_UNLIKELY].unw_sec = s;
+ else if (strcmp(".ARM.exidx.text.hot", secname) == 0)
+ maps[ARM_SEC_HOT].unw_sec = s;
+ else if (strcmp(".init.text", secname) == 0)
+ maps[ARM_SEC_INIT].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(".text.unlikely", secname) == 0)
+ maps[ARM_SEC_UNLIKELY].txt_sec = s;
+ else if (strcmp(".text.hot", secname) == 0)
+ maps[ARM_SEC_HOT].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())
+#ifdef CONFIG_SMP_ON_UP
+ fixup_smp((void *)s->sh_addr, s->sh_size);
+#else
+ return -EINVAL;
+#endif
+ 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/opcodes.c b/arch/arm/kernel/opcodes.c
new file mode 100644
index 000000000..f8179c6a8
--- /dev/null
+++ b/arch/arm/kernel/opcodes.c
@@ -0,0 +1,72 @@
+/*
+ * linux/arch/arm/kernel/opcodes.c
+ *
+ * A32 condition code lookup feature moved from nwfpe/fpopcode.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 <asm/opcodes.h>
+
+#define ARM_OPCODE_CONDITION_UNCOND 0xf
+
+/*
+ * 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 cc_map[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 */
+};
+
+/*
+ * Returns:
+ * ARM_OPCODE_CONDTEST_FAIL - if condition fails
+ * ARM_OPCODE_CONDTEST_PASS - if condition passes (including AL)
+ * ARM_OPCODE_CONDTEST_UNCOND - if NV condition, or separate unconditional
+ * opcode space from v5 onwards
+ *
+ * Code that tests whether a conditional instruction would pass its condition
+ * check should check that return value == ARM_OPCODE_CONDTEST_PASS.
+ *
+ * Code that tests if a condition means that the instruction would be executed
+ * (regardless of conditional or unconditional) should instead check that the
+ * return value != ARM_OPCODE_CONDTEST_FAIL.
+ */
+asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr)
+{
+ u32 cc_bits = opcode >> 28;
+ u32 psr_cond = psr >> 28;
+ unsigned int ret;
+
+ if (cc_bits != ARM_OPCODE_CONDITION_UNCOND) {
+ if ((cc_map[cc_bits] >> (psr_cond)) & 1)
+ ret = ARM_OPCODE_CONDTEST_PASS;
+ else
+ ret = ARM_OPCODE_CONDTEST_FAIL;
+ } else {
+ ret = ARM_OPCODE_CONDTEST_UNCOND;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(arm_check_condition);
diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
new file mode 100644
index 000000000..69bda1a57
--- /dev/null
+++ b/arch/arm/kernel/patch.c
@@ -0,0 +1,128 @@
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/kprobes.h>
+#include <linux/mm.h>
+#include <linux/stop_machine.h>
+
+#include <asm/cacheflush.h>
+#include <asm/fixmap.h>
+#include <asm/smp_plat.h>
+#include <asm/opcodes.h>
+#include <asm/patch.h>
+
+struct patch {
+ void *addr;
+ unsigned int insn;
+};
+
+static DEFINE_SPINLOCK(patch_lock);
+
+static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags)
+ __acquires(&patch_lock)
+{
+ unsigned int uintaddr = (uintptr_t) addr;
+ bool module = !core_kernel_text(uintaddr);
+ struct page *page;
+
+ if (module && IS_ENABLED(CONFIG_DEBUG_SET_MODULE_RONX))
+ page = vmalloc_to_page(addr);
+ else if (!module && IS_ENABLED(CONFIG_DEBUG_RODATA))
+ page = virt_to_page(addr);
+ else
+ return addr;
+
+ if (flags)
+ spin_lock_irqsave(&patch_lock, *flags);
+ else
+ __acquire(&patch_lock);
+
+ set_fixmap(fixmap, page_to_phys(page));
+
+ return (void *) (__fix_to_virt(fixmap) + (uintaddr & ~PAGE_MASK));
+}
+
+static void __kprobes patch_unmap(int fixmap, unsigned long *flags)
+ __releases(&patch_lock)
+{
+ clear_fixmap(fixmap);
+
+ if (flags)
+ spin_unlock_irqrestore(&patch_lock, *flags);
+ else
+ __release(&patch_lock);
+}
+
+void __kprobes __patch_text_real(void *addr, unsigned int insn, bool remap)
+{
+ bool thumb2 = IS_ENABLED(CONFIG_THUMB2_KERNEL);
+ unsigned int uintaddr = (uintptr_t) addr;
+ bool twopage = false;
+ unsigned long flags;
+ void *waddr = addr;
+ int size;
+
+ if (remap)
+ waddr = patch_map(addr, FIX_TEXT_POKE0, &flags);
+ else
+ __acquire(&patch_lock);
+
+ if (thumb2 && __opcode_is_thumb16(insn)) {
+ *(u16 *)waddr = __opcode_to_mem_thumb16(insn);
+ size = sizeof(u16);
+ } else if (thumb2 && (uintaddr & 2)) {
+ u16 first = __opcode_thumb32_first(insn);
+ u16 second = __opcode_thumb32_second(insn);
+ u16 *addrh0 = waddr;
+ u16 *addrh1 = waddr + 2;
+
+ twopage = (uintaddr & ~PAGE_MASK) == PAGE_SIZE - 2;
+ if (twopage && remap)
+ addrh1 = patch_map(addr + 2, FIX_TEXT_POKE1, NULL);
+
+ *addrh0 = __opcode_to_mem_thumb16(first);
+ *addrh1 = __opcode_to_mem_thumb16(second);
+
+ if (twopage && addrh1 != addr + 2) {
+ flush_kernel_vmap_range(addrh1, 2);
+ patch_unmap(FIX_TEXT_POKE1, NULL);
+ }
+
+ size = sizeof(u32);
+ } else {
+ if (thumb2)
+ insn = __opcode_to_mem_thumb32(insn);
+ else
+ insn = __opcode_to_mem_arm(insn);
+
+ *(u32 *)waddr = insn;
+ size = sizeof(u32);
+ }
+
+ if (waddr != addr) {
+ flush_kernel_vmap_range(waddr, twopage ? size / 2 : size);
+ patch_unmap(FIX_TEXT_POKE0, &flags);
+ } else
+ __release(&patch_lock);
+
+ flush_icache_range((uintptr_t)(addr),
+ (uintptr_t)(addr) + size);
+}
+
+static int __kprobes patch_text_stop_machine(void *data)
+{
+ struct patch *patch = data;
+
+ __patch_text(patch->addr, patch->insn);
+
+ return 0;
+}
+
+void __kprobes patch_text(void *addr, unsigned int insn)
+{
+ struct patch patch = {
+ .addr = addr,
+ .insn = insn,
+ };
+
+ stop_machine(patch_text_stop_machine, &patch, NULL);
+}
diff --git a/arch/arm/kernel/perf_callchain.c b/arch/arm/kernel/perf_callchain.c
new file mode 100644
index 000000000..4e02ae595
--- /dev/null
+++ b/arch/arm/kernel/perf_callchain.c
@@ -0,0 +1,136 @@
+/*
+ * ARM callchain 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 ARM OProfile backtrace code.
+ */
+#include <linux/perf_event.h>
+#include <linux/uaccess.h>
+
+#include <asm/stacktrace.h>
+
+/*
+ * 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;
+ unsigned long err;
+
+ if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
+ return NULL;
+
+ pagefault_disable();
+ err = __copy_from_user_inatomic(&buftail, tail, sizeof(buftail));
+ pagefault_enable();
+
+ if (err)
+ 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;
+
+ if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+ /* We don't support guest os callchain now */
+ return;
+ }
+
+ perf_callchain_store(entry, regs->ARM_pc);
+
+ if (!current->mm)
+ return;
+
+ 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;
+
+ if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+ /* We don't support guest os callchain now */
+ return;
+ }
+
+ arm_get_current_stackframe(regs, &fr);
+ walk_stackframe(&fr, callchain_trace, entry);
+}
+
+unsigned long perf_instruction_pointer(struct pt_regs *regs)
+{
+ if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
+ return perf_guest_cbs->get_guest_ip();
+
+ return instruction_pointer(regs);
+}
+
+unsigned long perf_misc_flags(struct pt_regs *regs)
+{
+ int misc = 0;
+
+ if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+ if (perf_guest_cbs->is_user_mode())
+ misc |= PERF_RECORD_MISC_GUEST_USER;
+ else
+ misc |= PERF_RECORD_MISC_GUEST_KERNEL;
+ } else {
+ if (user_mode(regs))
+ misc |= PERF_RECORD_MISC_USER;
+ else
+ misc |= PERF_RECORD_MISC_KERNEL;
+ }
+
+ return misc;
+}
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
new file mode 100644
index 000000000..4a86a0133
--- /dev/null
+++ b/arch/arm/kernel/perf_event.c
@@ -0,0 +1,553 @@
+#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.
+ */
+#define pr_fmt(fmt) "hw perfevents: " fmt
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
+
+#include <asm/irq_regs.h>
+#include <asm/pmu.h>
+
+static int
+armpmu_map_cache_event(const unsigned (*cache_map)
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX],
+ 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)(*cache_map)[cache_type][cache_op][cache_result];
+
+ if (ret == CACHE_OP_UNSUPPORTED)
+ return -ENOENT;
+
+ return ret;
+}
+
+static int
+armpmu_map_hw_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)
+{
+ int mapping;
+
+ if (config >= PERF_COUNT_HW_MAX)
+ return -EINVAL;
+
+ mapping = (*event_map)[config];
+ return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;
+}
+
+static int
+armpmu_map_raw_event(u32 raw_event_mask, u64 config)
+{
+ return (int)(config & raw_event_mask);
+}
+
+int
+armpmu_map_event(struct perf_event *event,
+ const unsigned (*event_map)[PERF_COUNT_HW_MAX],
+ const unsigned (*cache_map)
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX],
+ u32 raw_event_mask)
+{
+ u64 config = event->attr.config;
+ int type = event->attr.type;
+
+ if (type == event->pmu->type)
+ return armpmu_map_raw_event(raw_event_mask, config);
+
+ switch (type) {
+ case PERF_TYPE_HARDWARE:
+ return armpmu_map_hw_event(event_map, config);
+ case PERF_TYPE_HW_CACHE:
+ return armpmu_map_cache_event(cache_map, config);
+ case PERF_TYPE_RAW:
+ return armpmu_map_raw_event(raw_event_mask, config);
+ }
+
+ return -ENOENT;
+}
+
+int armpmu_event_set_period(struct perf_event *event)
+{
+ struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ 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;
+ }
+
+ /*
+ * Limit the maximum period to prevent the counter value
+ * from overtaking the one we are about to program. In
+ * effect we are reducing max_period to account for
+ * interrupt latency (and we are being very conservative).
+ */
+ if (left > (armpmu->max_period >> 1))
+ left = armpmu->max_period >> 1;
+
+ local64_set(&hwc->prev_count, (u64)-left);
+
+ armpmu->write_counter(event, (u64)(-left) & 0xffffffff);
+
+ perf_event_update_userpage(event);
+
+ return ret;
+}
+
+u64 armpmu_event_update(struct perf_event *event)
+{
+ struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ u64 delta, prev_raw_count, new_raw_count;
+
+again:
+ prev_raw_count = local64_read(&hwc->prev_count);
+ new_raw_count = armpmu->read_counter(event);
+
+ if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+ new_raw_count) != prev_raw_count)
+ goto again;
+
+ delta = (new_raw_count - prev_raw_count) & armpmu->max_period;
+
+ local64_add(delta, &event->count);
+ local64_sub(delta, &hwc->period_left);
+
+ return new_raw_count;
+}
+
+static void
+armpmu_read(struct perf_event *event)
+{
+ armpmu_event_update(event);
+}
+
+static void
+armpmu_stop(struct perf_event *event, int flags)
+{
+ struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+
+ /*
+ * 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(event);
+ armpmu_event_update(event);
+ hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
+ }
+}
+
+static void armpmu_start(struct perf_event *event, int flags)
+{
+ struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+
+ /*
+ * 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);
+ armpmu->enable(event);
+}
+
+static void
+armpmu_del(struct perf_event *event, int flags)
+{
+ struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
+ struct pmu_hw_events *hw_events = this_cpu_ptr(armpmu->hw_events);
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = hwc->idx;
+
+ armpmu_stop(event, PERF_EF_UPDATE);
+ hw_events->events[idx] = NULL;
+ clear_bit(idx, hw_events->used_mask);
+ if (armpmu->clear_event_idx)
+ armpmu->clear_event_idx(hw_events, event);
+
+ perf_event_update_userpage(event);
+}
+
+static int
+armpmu_add(struct perf_event *event, int flags)
+{
+ struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
+ struct pmu_hw_events *hw_events = this_cpu_ptr(armpmu->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(hw_events, event);
+ 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(event);
+ hw_events->events[idx] = event;
+
+ 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 int
+validate_event(struct pmu *pmu, struct pmu_hw_events *hw_events,
+ struct perf_event *event)
+{
+ struct arm_pmu *armpmu;
+
+ if (is_software_event(event))
+ return 1;
+
+ /*
+ * Reject groups spanning multiple HW PMUs (e.g. CPU + CCI). The
+ * core perf code won't check that the pmu->ctx == leader->ctx
+ * until after pmu->event_init(event).
+ */
+ if (event->pmu != pmu)
+ return 0;
+
+ if (event->state < PERF_EVENT_STATE_OFF)
+ return 1;
+
+ if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec)
+ return 1;
+
+ armpmu = to_arm_pmu(event->pmu);
+ return armpmu->get_event_idx(hw_events, event) >= 0;
+}
+
+static int
+validate_group(struct perf_event *event)
+{
+ struct perf_event *sibling, *leader = event->group_leader;
+ struct pmu_hw_events fake_pmu;
+
+ /*
+ * Initialise the fake PMU. We only need to populate the
+ * used_mask for the purposes of validation.
+ */
+ memset(&fake_pmu.used_mask, 0, sizeof(fake_pmu.used_mask));
+
+ if (!validate_event(event->pmu, &fake_pmu, leader))
+ return -EINVAL;
+
+ list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
+ if (!validate_event(event->pmu, &fake_pmu, sibling))
+ return -EINVAL;
+ }
+
+ if (!validate_event(event->pmu, &fake_pmu, event))
+ return -EINVAL;
+
+ return 0;
+}
+
+static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
+{
+ struct arm_pmu *armpmu;
+ struct platform_device *plat_device;
+ struct arm_pmu_platdata *plat;
+ int ret;
+ u64 start_clock, finish_clock;
+
+ /*
+ * we request the IRQ with a (possibly percpu) struct arm_pmu**, but
+ * the handlers expect a struct arm_pmu*. The percpu_irq framework will
+ * do any necessary shifting, we just need to perform the first
+ * dereference.
+ */
+ armpmu = *(void **)dev;
+ plat_device = armpmu->plat_device;
+ plat = dev_get_platdata(&plat_device->dev);
+
+ start_clock = sched_clock();
+ if (plat && plat->handle_irq)
+ ret = plat->handle_irq(irq, armpmu, armpmu->handle_irq);
+ else
+ ret = armpmu->handle_irq(irq, armpmu);
+ finish_clock = sched_clock();
+
+ perf_sample_event_took(finish_clock - start_clock);
+ return ret;
+}
+
+static void
+armpmu_release_hardware(struct arm_pmu *armpmu)
+{
+ armpmu->free_irq(armpmu);
+ pm_runtime_put_sync(&armpmu->plat_device->dev);
+}
+
+static int
+armpmu_reserve_hardware(struct arm_pmu *armpmu)
+{
+ int err;
+ struct platform_device *pmu_device = armpmu->plat_device;
+
+ if (!pmu_device)
+ return -ENODEV;
+
+ pm_runtime_get_sync(&pmu_device->dev);
+ err = armpmu->request_irq(armpmu, armpmu_dispatch_irq);
+ if (err) {
+ armpmu_release_hardware(armpmu);
+ return err;
+ }
+
+ return 0;
+}
+
+static void
+hw_perf_event_destroy(struct perf_event *event)
+{
+ struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
+ atomic_t *active_events = &armpmu->active_events;
+ struct mutex *pmu_reserve_mutex = &armpmu->reserve_mutex;
+
+ if (atomic_dec_and_mutex_lock(active_events, pmu_reserve_mutex)) {
+ armpmu_release_hardware(armpmu);
+ mutex_unlock(pmu_reserve_mutex);
+ }
+}
+
+static int
+event_requires_mode_exclusion(struct perf_event_attr *attr)
+{
+ return attr->exclude_idle || attr->exclude_user ||
+ attr->exclude_kernel || attr->exclude_hv;
+}
+
+static int
+__hw_perf_event_init(struct perf_event *event)
+{
+ struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ int mapping;
+
+ mapping = armpmu->map_event(event);
+
+ if (mapping < 0) {
+ pr_debug("event %x:%llx not supported\n", event->attr.type,
+ event->attr.config);
+ return mapping;
+ }
+
+ /*
+ * 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;
+ hwc->config_base = 0;
+ hwc->config = 0;
+ hwc->event_base = 0;
+
+ /*
+ * Check whether we need to exclude the counter from certain modes.
+ */
+ if ((!armpmu->set_event_filter ||
+ armpmu->set_event_filter(hwc, &event->attr)) &&
+ event_requires_mode_exclusion(&event->attr)) {
+ pr_debug("ARM performance counters do not support "
+ "mode exclusion\n");
+ return -EOPNOTSUPP;
+ }
+
+ /*
+ * Store the event encoding into the config_base field.
+ */
+ hwc->config_base |= (unsigned long)mapping;
+
+ if (!is_sampling_event(event)) {
+ /*
+ * For non-sampling runs, limit the sample_period to half
+ * of the counter width. That way, the new counter value
+ * is far less likely to overtake the previous one unless
+ * you have some serious IRQ latency issues.
+ */
+ hwc->sample_period = armpmu->max_period >> 1;
+ hwc->last_period = hwc->sample_period;
+ local64_set(&hwc->period_left, hwc->sample_period);
+ }
+
+ if (event->group_leader != event) {
+ if (validate_group(event) != 0)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int armpmu_event_init(struct perf_event *event)
+{
+ struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
+ int err = 0;
+ atomic_t *active_events = &armpmu->active_events;
+
+ /* does not support taken branch sampling */
+ if (has_branch_stack(event))
+ return -EOPNOTSUPP;
+
+ if (armpmu->map_event(event) == -ENOENT)
+ return -ENOENT;
+
+ event->destroy = hw_perf_event_destroy;
+
+ if (!atomic_inc_not_zero(active_events)) {
+ mutex_lock(&armpmu->reserve_mutex);
+ if (atomic_read(active_events) == 0)
+ err = armpmu_reserve_hardware(armpmu);
+
+ if (!err)
+ atomic_inc(active_events);
+ mutex_unlock(&armpmu->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)
+{
+ struct arm_pmu *armpmu = to_arm_pmu(pmu);
+ struct pmu_hw_events *hw_events = this_cpu_ptr(armpmu->hw_events);
+ int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events);
+
+ if (enabled)
+ armpmu->start(armpmu);
+}
+
+static void armpmu_disable(struct pmu *pmu)
+{
+ struct arm_pmu *armpmu = to_arm_pmu(pmu);
+ armpmu->stop(armpmu);
+}
+
+#ifdef CONFIG_PM
+static int armpmu_runtime_resume(struct device *dev)
+{
+ struct arm_pmu_platdata *plat = dev_get_platdata(dev);
+
+ if (plat && plat->runtime_resume)
+ return plat->runtime_resume(dev);
+
+ return 0;
+}
+
+static int armpmu_runtime_suspend(struct device *dev)
+{
+ struct arm_pmu_platdata *plat = dev_get_platdata(dev);
+
+ if (plat && plat->runtime_suspend)
+ return plat->runtime_suspend(dev);
+
+ return 0;
+}
+#endif
+
+const struct dev_pm_ops armpmu_dev_pm_ops = {
+ SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL)
+};
+
+static void armpmu_init(struct arm_pmu *armpmu)
+{
+ atomic_set(&armpmu->active_events, 0);
+ mutex_init(&armpmu->reserve_mutex);
+
+ armpmu->pmu = (struct 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,
+ };
+}
+
+int armpmu_register(struct arm_pmu *armpmu, int type)
+{
+ armpmu_init(armpmu);
+ pm_runtime_enable(&armpmu->plat_device->dev);
+ pr_info("enabled with %s PMU driver, %d counters available\n",
+ armpmu->name, armpmu->num_events);
+ return perf_pmu_register(&armpmu->pmu, armpmu->name, type);
+}
+
diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c
new file mode 100644
index 000000000..3b8c2833c
--- /dev/null
+++ b/arch/arm/kernel/perf_event_cpu.c
@@ -0,0 +1,421 @@
+/*
+ * This program is free software; you can 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) 2012 ARM Limited
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ */
+#define pr_fmt(fmt) "CPU PMU: " fmt
+
+#include <linux/bitmap.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
+
+#include <asm/cputype.h>
+#include <asm/irq_regs.h>
+#include <asm/pmu.h>
+
+/* Set at runtime when we know what CPU type we are. */
+static struct arm_pmu *cpu_pmu;
+
+/*
+ * Despite the names, these two functions are CPU-specific and are used
+ * by the OProfile/perf code.
+ */
+const char *perf_pmu_name(void)
+{
+ if (!cpu_pmu)
+ return NULL;
+
+ return cpu_pmu->name;
+}
+EXPORT_SYMBOL_GPL(perf_pmu_name);
+
+int perf_num_counters(void)
+{
+ int max_events = 0;
+
+ if (cpu_pmu != NULL)
+ max_events = cpu_pmu->num_events;
+
+ return max_events;
+}
+EXPORT_SYMBOL_GPL(perf_num_counters);
+
+/* Include the PMU-specific implementations. */
+#include "perf_event_xscale.c"
+#include "perf_event_v6.c"
+#include "perf_event_v7.c"
+
+static void cpu_pmu_enable_percpu_irq(void *data)
+{
+ int irq = *(int *)data;
+
+ enable_percpu_irq(irq, IRQ_TYPE_NONE);
+}
+
+static void cpu_pmu_disable_percpu_irq(void *data)
+{
+ int irq = *(int *)data;
+
+ disable_percpu_irq(irq);
+}
+
+static void cpu_pmu_free_irq(struct arm_pmu *cpu_pmu)
+{
+ int i, irq, irqs;
+ struct platform_device *pmu_device = cpu_pmu->plat_device;
+ struct pmu_hw_events __percpu *hw_events = cpu_pmu->hw_events;
+
+ irqs = min(pmu_device->num_resources, num_possible_cpus());
+
+ irq = platform_get_irq(pmu_device, 0);
+ if (irq >= 0 && irq_is_percpu(irq)) {
+ on_each_cpu(cpu_pmu_disable_percpu_irq, &irq, 1);
+ free_percpu_irq(irq, &hw_events->percpu_pmu);
+ } else {
+ for (i = 0; i < irqs; ++i) {
+ int cpu = i;
+
+ if (cpu_pmu->irq_affinity)
+ cpu = cpu_pmu->irq_affinity[i];
+
+ if (!cpumask_test_and_clear_cpu(cpu, &cpu_pmu->active_irqs))
+ continue;
+ irq = platform_get_irq(pmu_device, i);
+ if (irq >= 0)
+ free_irq(irq, per_cpu_ptr(&hw_events->percpu_pmu, cpu));
+ }
+ }
+}
+
+static int cpu_pmu_request_irq(struct arm_pmu *cpu_pmu, irq_handler_t handler)
+{
+ int i, err, irq, irqs;
+ struct platform_device *pmu_device = cpu_pmu->plat_device;
+ struct pmu_hw_events __percpu *hw_events = cpu_pmu->hw_events;
+
+ if (!pmu_device)
+ return -ENODEV;
+
+ irqs = min(pmu_device->num_resources, num_possible_cpus());
+ if (irqs < 1) {
+ pr_warn_once("perf/ARM: No irqs for PMU defined, sampling events not supported\n");
+ return 0;
+ }
+
+ irq = platform_get_irq(pmu_device, 0);
+ if (irq >= 0 && irq_is_percpu(irq)) {
+ err = request_percpu_irq(irq, handler, "arm-pmu",
+ &hw_events->percpu_pmu);
+ if (err) {
+ pr_err("unable to request IRQ%d for ARM PMU counters\n",
+ irq);
+ return err;
+ }
+ on_each_cpu(cpu_pmu_enable_percpu_irq, &irq, 1);
+ } else {
+ for (i = 0; i < irqs; ++i) {
+ int cpu = i;
+
+ err = 0;
+ irq = platform_get_irq(pmu_device, i);
+ if (irq < 0)
+ continue;
+
+ if (cpu_pmu->irq_affinity)
+ cpu = cpu_pmu->irq_affinity[i];
+
+ /*
+ * If we have a single PMU interrupt that we can't shift,
+ * assume that we're running on a uniprocessor machine and
+ * continue. Otherwise, continue without this interrupt.
+ */
+ if (irq_set_affinity(irq, cpumask_of(cpu)) && irqs > 1) {
+ pr_warn("unable to set irq affinity (irq=%d, cpu=%u)\n",
+ irq, cpu);
+ continue;
+ }
+
+ err = request_irq(irq, handler,
+ IRQF_NOBALANCING | IRQF_NO_THREAD, "arm-pmu",
+ per_cpu_ptr(&hw_events->percpu_pmu, cpu));
+ if (err) {
+ pr_err("unable to request IRQ%d for ARM PMU counters\n",
+ irq);
+ return err;
+ }
+
+ cpumask_set_cpu(cpu, &cpu_pmu->active_irqs);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * PMU hardware loses all context when a CPU goes offline.
+ * When a CPU is hotplugged back in, since some hardware registers are
+ * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading
+ * junk values out of them.
+ */
+static int cpu_pmu_notify(struct notifier_block *b, unsigned long action,
+ void *hcpu)
+{
+ struct arm_pmu *pmu = container_of(b, struct arm_pmu, hotplug_nb);
+
+ if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
+ return NOTIFY_DONE;
+
+ if (pmu->reset)
+ pmu->reset(pmu);
+ else
+ return NOTIFY_DONE;
+
+ return NOTIFY_OK;
+}
+
+static int cpu_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ int err;
+ int cpu;
+ struct pmu_hw_events __percpu *cpu_hw_events;
+
+ cpu_hw_events = alloc_percpu(struct pmu_hw_events);
+ if (!cpu_hw_events)
+ return -ENOMEM;
+
+ cpu_pmu->hotplug_nb.notifier_call = cpu_pmu_notify;
+ err = register_cpu_notifier(&cpu_pmu->hotplug_nb);
+ if (err)
+ goto out_hw_events;
+
+ for_each_possible_cpu(cpu) {
+ struct pmu_hw_events *events = per_cpu_ptr(cpu_hw_events, cpu);
+ raw_spin_lock_init(&events->pmu_lock);
+ events->percpu_pmu = cpu_pmu;
+ }
+
+ cpu_pmu->hw_events = cpu_hw_events;
+ cpu_pmu->request_irq = cpu_pmu_request_irq;
+ cpu_pmu->free_irq = cpu_pmu_free_irq;
+
+ /* Ensure the PMU has sane values out of reset. */
+ if (cpu_pmu->reset)
+ on_each_cpu(cpu_pmu->reset, cpu_pmu, 1);
+
+ /* If no interrupts available, set the corresponding capability flag */
+ if (!platform_get_irq(cpu_pmu->plat_device, 0))
+ cpu_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
+
+ return 0;
+
+out_hw_events:
+ free_percpu(cpu_hw_events);
+ return err;
+}
+
+static void cpu_pmu_destroy(struct arm_pmu *cpu_pmu)
+{
+ unregister_cpu_notifier(&cpu_pmu->hotplug_nb);
+ free_percpu(cpu_pmu->hw_events);
+}
+
+/*
+ * PMU platform driver and devicetree bindings.
+ */
+static const struct of_device_id cpu_pmu_of_device_ids[] = {
+ {.compatible = "arm,cortex-a17-pmu", .data = armv7_a17_pmu_init},
+ {.compatible = "arm,cortex-a15-pmu", .data = armv7_a15_pmu_init},
+ {.compatible = "arm,cortex-a12-pmu", .data = armv7_a12_pmu_init},
+ {.compatible = "arm,cortex-a9-pmu", .data = armv7_a9_pmu_init},
+ {.compatible = "arm,cortex-a8-pmu", .data = armv7_a8_pmu_init},
+ {.compatible = "arm,cortex-a7-pmu", .data = armv7_a7_pmu_init},
+ {.compatible = "arm,cortex-a5-pmu", .data = armv7_a5_pmu_init},
+ {.compatible = "arm,arm11mpcore-pmu", .data = armv6mpcore_pmu_init},
+ {.compatible = "arm,arm1176-pmu", .data = armv6_1176_pmu_init},
+ {.compatible = "arm,arm1136-pmu", .data = armv6_1136_pmu_init},
+ {.compatible = "qcom,krait-pmu", .data = krait_pmu_init},
+ {.compatible = "qcom,scorpion-pmu", .data = scorpion_pmu_init},
+ {.compatible = "qcom,scorpion-mp-pmu", .data = scorpion_mp_pmu_init},
+ {},
+};
+
+static struct platform_device_id cpu_pmu_plat_device_ids[] = {
+ {.name = "arm-pmu"},
+ {.name = "armv6-pmu"},
+ {.name = "armv7-pmu"},
+ {.name = "xscale-pmu"},
+ {},
+};
+
+static const struct pmu_probe_info pmu_probe_table[] = {
+ ARM_PMU_PROBE(ARM_CPU_PART_ARM1136, armv6_1136_pmu_init),
+ ARM_PMU_PROBE(ARM_CPU_PART_ARM1156, armv6_1156_pmu_init),
+ ARM_PMU_PROBE(ARM_CPU_PART_ARM1176, armv6_1176_pmu_init),
+ ARM_PMU_PROBE(ARM_CPU_PART_ARM11MPCORE, armv6mpcore_pmu_init),
+ ARM_PMU_PROBE(ARM_CPU_PART_CORTEX_A8, armv7_a8_pmu_init),
+ ARM_PMU_PROBE(ARM_CPU_PART_CORTEX_A9, armv7_a9_pmu_init),
+ XSCALE_PMU_PROBE(ARM_CPU_XSCALE_ARCH_V1, xscale1pmu_init),
+ XSCALE_PMU_PROBE(ARM_CPU_XSCALE_ARCH_V2, xscale2pmu_init),
+ { /* sentinel value */ }
+};
+
+/*
+ * CPU PMU identification and probing.
+ */
+static int probe_current_pmu(struct arm_pmu *pmu)
+{
+ int cpu = get_cpu();
+ unsigned int cpuid = read_cpuid_id();
+ int ret = -ENODEV;
+ const struct pmu_probe_info *info;
+
+ pr_info("probing PMU on CPU %d\n", cpu);
+
+ for (info = pmu_probe_table; info->init != NULL; info++) {
+ if ((cpuid & info->mask) != info->cpuid)
+ continue;
+ ret = info->init(pmu);
+ break;
+ }
+
+ put_cpu();
+ return ret;
+}
+
+static int of_pmu_irq_cfg(struct platform_device *pdev)
+{
+ int i, irq;
+ int *irqs;
+
+ /* Don't bother with PPIs; they're already affine */
+ irq = platform_get_irq(pdev, 0);
+ if (irq >= 0 && irq_is_percpu(irq))
+ return 0;
+
+ irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL);
+ if (!irqs)
+ return -ENOMEM;
+
+ for (i = 0; i < pdev->num_resources; ++i) {
+ struct device_node *dn;
+ int cpu;
+
+ dn = of_parse_phandle(pdev->dev.of_node, "interrupt-affinity",
+ i);
+ if (!dn) {
+ pr_warn("Failed to parse %s/interrupt-affinity[%d]\n",
+ of_node_full_name(pdev->dev.of_node), i);
+ break;
+ }
+
+ for_each_possible_cpu(cpu)
+ if (arch_find_n_match_cpu_physical_id(dn, cpu, NULL))
+ break;
+
+ of_node_put(dn);
+ if (cpu >= nr_cpu_ids) {
+ pr_warn("Failed to find logical CPU for %s\n",
+ dn->name);
+ break;
+ }
+
+ irqs[i] = cpu;
+ }
+
+ if (i == pdev->num_resources)
+ cpu_pmu->irq_affinity = irqs;
+ else
+ kfree(irqs);
+
+ return 0;
+}
+
+static int cpu_pmu_device_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *of_id;
+ const int (*init_fn)(struct arm_pmu *);
+ struct device_node *node = pdev->dev.of_node;
+ struct arm_pmu *pmu;
+ int ret = -ENODEV;
+
+ if (cpu_pmu) {
+ pr_info("attempt to register multiple PMU devices!\n");
+ return -ENOSPC;
+ }
+
+ pmu = kzalloc(sizeof(struct arm_pmu), GFP_KERNEL);
+ if (!pmu) {
+ pr_info("failed to allocate PMU device!\n");
+ return -ENOMEM;
+ }
+
+ cpu_pmu = pmu;
+ cpu_pmu->plat_device = pdev;
+
+ if (node && (of_id = of_match_node(cpu_pmu_of_device_ids, pdev->dev.of_node))) {
+ init_fn = of_id->data;
+
+ ret = of_pmu_irq_cfg(pdev);
+ if (!ret)
+ ret = init_fn(pmu);
+ } else {
+ ret = probe_current_pmu(pmu);
+ }
+
+ if (ret) {
+ pr_info("failed to probe PMU!\n");
+ goto out_free;
+ }
+
+ ret = cpu_pmu_init(cpu_pmu);
+ if (ret)
+ goto out_free;
+
+ ret = armpmu_register(cpu_pmu, -1);
+ if (ret)
+ goto out_destroy;
+
+ return 0;
+
+out_destroy:
+ cpu_pmu_destroy(cpu_pmu);
+out_free:
+ pr_info("failed to register PMU devices!\n");
+ kfree(pmu);
+ return ret;
+}
+
+static struct platform_driver cpu_pmu_driver = {
+ .driver = {
+ .name = "arm-pmu",
+ .pm = &armpmu_dev_pm_ops,
+ .of_match_table = cpu_pmu_of_device_ids,
+ },
+ .probe = cpu_pmu_device_probe,
+ .id_table = cpu_pmu_plat_device_ids,
+};
+
+static int __init register_pmu_driver(void)
+{
+ return platform_driver_register(&cpu_pmu_driver);
+}
+device_initcall(register_pmu_driver);
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c
new file mode 100644
index 000000000..f2ffd5c54
--- /dev/null
+++ b/arch/arm/kernel/perf_event_v6.c
@@ -0,0 +1,566 @@
+/*
+ * 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 = 0,
+ 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_MAP_ALL_UNSUPPORTED,
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV6_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6_PERFCTR_INSTR_EXEC,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6_PERFCTR_BR_MISPREDICT,
+ [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV6_PERFCTR_IBUF_STALL,
+ [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV6_PERFCTR_LSU_FULL_STALL,
+};
+
+static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ PERF_CACHE_MAP_ALL_UNSUPPORTED,
+
+ /*
+ * 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(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS,
+ [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS,
+
+ [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS,
+
+ /*
+ * 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(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS,
+ [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS,
+
+ [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS,
+ [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS,
+};
+
+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_MAP_ALL_UNSUPPORTED,
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV6MPCORE_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_INSTR_EXEC,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6MPCORE_PERFCTR_BR_MISPREDICT,
+ [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV6MPCORE_PERFCTR_IBUF_STALL,
+ [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV6MPCORE_PERFCTR_LSU_FULL_STALL,
+};
+
+static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ PERF_CACHE_MAP_ALL_UNSUPPORTED,
+
+ [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS,
+ [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DCACHE_RDMISS,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DCACHE_WRMISS,
+
+ [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
+
+ /*
+ * 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(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS,
+ [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS,
+
+ [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ITLB_MISS,
+ [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ITLB_MISS,
+};
+
+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(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ int counter = hwc->idx;
+ 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(struct perf_event *event, u32 value)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ int counter = hwc->idx;
+
+ 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 perf_event *event)
+{
+ unsigned long val, mask, evt, flags;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+ int idx = hwc->idx;
+
+ 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(&events->pmu_lock, flags);
+ val = armv6_pmcr_read();
+ val &= ~mask;
+ val |= evt;
+ armv6_pmcr_write(val);
+ raw_spin_unlock_irqrestore(&events->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 arm_pmu *cpu_pmu = (struct arm_pmu *)dev;
+ struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
+ 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);
+
+ for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
+ struct perf_event *event = cpuc->events[idx];
+ struct hw_perf_event *hwc;
+
+ /* Ignore if we don't have an event. */
+ if (!event)
+ 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);
+ perf_sample_data_init(&data, 0, hwc->last_period);
+ if (!armpmu_event_set_period(event))
+ continue;
+
+ if (perf_event_overflow(event, &data, regs))
+ cpu_pmu->disable(event);
+ }
+
+ /*
+ * 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(struct arm_pmu *cpu_pmu)
+{
+ unsigned long flags, val;
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+
+ raw_spin_lock_irqsave(&events->pmu_lock, flags);
+ val = armv6_pmcr_read();
+ val |= ARMV6_PMCR_ENABLE;
+ armv6_pmcr_write(val);
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static void armv6pmu_stop(struct arm_pmu *cpu_pmu)
+{
+ unsigned long flags, val;
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+
+ raw_spin_lock_irqsave(&events->pmu_lock, flags);
+ val = armv6_pmcr_read();
+ val &= ~ARMV6_PMCR_ENABLE;
+ armv6_pmcr_write(val);
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static int
+armv6pmu_get_event_idx(struct pmu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ /* Always place a cycle counter into the cycle counter. */
+ if (ARMV6_PERFCTR_CPU_CYCLES == hwc->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 perf_event *event)
+{
+ unsigned long val, mask, evt, flags;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+ int idx = hwc->idx;
+
+ 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(&events->pmu_lock, flags);
+ val = armv6_pmcr_read();
+ val &= ~mask;
+ val |= evt;
+ armv6_pmcr_write(val);
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static void armv6mpcore_pmu_disable_event(struct perf_event *event)
+{
+ unsigned long val, mask, flags, evt = 0;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+ int idx = hwc->idx;
+
+ 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(&events->pmu_lock, flags);
+ val = armv6_pmcr_read();
+ val &= ~mask;
+ val |= evt;
+ armv6_pmcr_write(val);
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static int armv6_map_event(struct perf_event *event)
+{
+ return armpmu_map_event(event, &armv6_perf_map,
+ &armv6_perf_cache_map, 0xFF);
+}
+
+static void armv6pmu_init(struct arm_pmu *cpu_pmu)
+{
+ cpu_pmu->handle_irq = armv6pmu_handle_irq;
+ cpu_pmu->enable = armv6pmu_enable_event;
+ cpu_pmu->disable = armv6pmu_disable_event;
+ cpu_pmu->read_counter = armv6pmu_read_counter;
+ cpu_pmu->write_counter = armv6pmu_write_counter;
+ cpu_pmu->get_event_idx = armv6pmu_get_event_idx;
+ cpu_pmu->start = armv6pmu_start;
+ cpu_pmu->stop = armv6pmu_stop;
+ cpu_pmu->map_event = armv6_map_event;
+ cpu_pmu->num_events = 3;
+ cpu_pmu->max_period = (1LLU << 32) - 1;
+}
+
+static int armv6_1136_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ armv6pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv6_1136";
+ return 0;
+}
+
+static int armv6_1156_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ armv6pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv6_1156";
+ return 0;
+}
+
+static int armv6_1176_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ armv6pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv6_1176";
+ return 0;
+}
+
+/*
+ * 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 int armv6mpcore_map_event(struct perf_event *event)
+{
+ return armpmu_map_event(event, &armv6mpcore_perf_map,
+ &armv6mpcore_perf_cache_map, 0xFF);
+}
+
+static int armv6mpcore_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ cpu_pmu->name = "armv6_11mpcore";
+ cpu_pmu->handle_irq = armv6pmu_handle_irq;
+ cpu_pmu->enable = armv6pmu_enable_event;
+ cpu_pmu->disable = armv6mpcore_pmu_disable_event;
+ cpu_pmu->read_counter = armv6pmu_read_counter;
+ cpu_pmu->write_counter = armv6pmu_write_counter;
+ cpu_pmu->get_event_idx = armv6pmu_get_event_idx;
+ cpu_pmu->start = armv6pmu_start;
+ cpu_pmu->stop = armv6pmu_stop;
+ cpu_pmu->map_event = armv6mpcore_map_event;
+ cpu_pmu->num_events = 3;
+ cpu_pmu->max_period = (1LLU << 32) - 1;
+
+ return 0;
+}
+#else
+static int armv6_1136_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ return -ENODEV;
+}
+
+static int armv6_1156_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ return -ENODEV;
+}
+
+static int armv6_1176_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ return -ENODEV;
+}
+
+static int armv6mpcore_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ return -ENODEV;
+}
+#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 000000000..f4207a4dc
--- /dev/null
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -0,0 +1,1908 @@
+/*
+ * 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
+
+#include <asm/cp15.h>
+#include <asm/vfp.h>
+#include "../vfp/vfpinstr.h"
+
+/*
+ * Common ARMv7 event types
+ *
+ * Note: An implementation may not be able to count all of these events
+ * but the encodings are considered to be `reserved' in the case that
+ * they are not available.
+ */
+enum armv7_perf_types {
+ ARMV7_PERFCTR_PMNC_SW_INCR = 0x00,
+ ARMV7_PERFCTR_L1_ICACHE_REFILL = 0x01,
+ ARMV7_PERFCTR_ITLB_REFILL = 0x02,
+ ARMV7_PERFCTR_L1_DCACHE_REFILL = 0x03,
+ ARMV7_PERFCTR_L1_DCACHE_ACCESS = 0x04,
+ ARMV7_PERFCTR_DTLB_REFILL = 0x05,
+ ARMV7_PERFCTR_MEM_READ = 0x06,
+ ARMV7_PERFCTR_MEM_WRITE = 0x07,
+ ARMV7_PERFCTR_INSTR_EXECUTED = 0x08,
+ 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 (taken) branch instructions,
+ * - instructions that explicitly write the PC,
+ * - exception generating instructions.
+ */
+ ARMV7_PERFCTR_PC_WRITE = 0x0C,
+ ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D,
+ ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E,
+ ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS = 0x0F,
+ ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
+ ARMV7_PERFCTR_CLOCK_CYCLES = 0x11,
+ ARMV7_PERFCTR_PC_BRANCH_PRED = 0x12,
+
+ /* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
+ ARMV7_PERFCTR_MEM_ACCESS = 0x13,
+ ARMV7_PERFCTR_L1_ICACHE_ACCESS = 0x14,
+ ARMV7_PERFCTR_L1_DCACHE_WB = 0x15,
+ ARMV7_PERFCTR_L2_CACHE_ACCESS = 0x16,
+ ARMV7_PERFCTR_L2_CACHE_REFILL = 0x17,
+ ARMV7_PERFCTR_L2_CACHE_WB = 0x18,
+ ARMV7_PERFCTR_BUS_ACCESS = 0x19,
+ ARMV7_PERFCTR_MEM_ERROR = 0x1A,
+ ARMV7_PERFCTR_INSTR_SPEC = 0x1B,
+ ARMV7_PERFCTR_TTBR_WRITE = 0x1C,
+ ARMV7_PERFCTR_BUS_CYCLES = 0x1D,
+
+ ARMV7_PERFCTR_CPU_CYCLES = 0xFF
+};
+
+/* ARMv7 Cortex-A8 specific event types */
+enum armv7_a8_perf_types {
+ ARMV7_A8_PERFCTR_L2_CACHE_ACCESS = 0x43,
+ ARMV7_A8_PERFCTR_L2_CACHE_REFILL = 0x44,
+ ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS = 0x50,
+ ARMV7_A8_PERFCTR_STALL_ISIDE = 0x56,
+};
+
+/* ARMv7 Cortex-A9 specific event types */
+enum armv7_a9_perf_types {
+ ARMV7_A9_PERFCTR_INSTR_CORE_RENAME = 0x68,
+ ARMV7_A9_PERFCTR_STALL_ICACHE = 0x60,
+ ARMV7_A9_PERFCTR_STALL_DISPATCH = 0x66,
+};
+
+/* ARMv7 Cortex-A5 specific event types */
+enum armv7_a5_perf_types {
+ ARMV7_A5_PERFCTR_PREFETCH_LINEFILL = 0xc2,
+ ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP = 0xc3,
+};
+
+/* ARMv7 Cortex-A15 specific event types */
+enum armv7_a15_perf_types {
+ ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ = 0x40,
+ ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE = 0x41,
+ ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ = 0x42,
+ ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE = 0x43,
+
+ ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ = 0x4C,
+ ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE = 0x4D,
+
+ ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ = 0x50,
+ ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE = 0x51,
+ ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ = 0x52,
+ ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE = 0x53,
+
+ ARMV7_A15_PERFCTR_PC_WRITE_SPEC = 0x76,
+};
+
+/* ARMv7 Cortex-A12 specific event types */
+enum armv7_a12_perf_types {
+ ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ = 0x40,
+ ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE = 0x41,
+
+ ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ = 0x50,
+ ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE = 0x51,
+
+ ARMV7_A12_PERFCTR_PC_WRITE_SPEC = 0x76,
+
+ ARMV7_A12_PERFCTR_PF_TLB_REFILL = 0xe7,
+};
+
+/* ARMv7 Krait specific event types */
+enum krait_perf_types {
+ KRAIT_PMRESR0_GROUP0 = 0xcc,
+ KRAIT_PMRESR1_GROUP0 = 0xd0,
+ KRAIT_PMRESR2_GROUP0 = 0xd4,
+ KRAIT_VPMRESR0_GROUP0 = 0xd8,
+
+ KRAIT_PERFCTR_L1_ICACHE_ACCESS = 0x10011,
+ KRAIT_PERFCTR_L1_ICACHE_MISS = 0x10010,
+
+ KRAIT_PERFCTR_L1_ITLB_ACCESS = 0x12222,
+ KRAIT_PERFCTR_L1_DTLB_ACCESS = 0x12210,
+};
+
+/* ARMv7 Scorpion specific event types */
+enum scorpion_perf_types {
+ SCORPION_LPM0_GROUP0 = 0x4c,
+ SCORPION_LPM1_GROUP0 = 0x50,
+ SCORPION_LPM2_GROUP0 = 0x54,
+ SCORPION_L2LPM_GROUP0 = 0x58,
+ SCORPION_VLPM_GROUP0 = 0x5c,
+
+ SCORPION_ICACHE_ACCESS = 0x10053,
+ SCORPION_ICACHE_MISS = 0x10052,
+
+ SCORPION_DTLB_ACCESS = 0x12013,
+ SCORPION_DTLB_MISS = 0x12012,
+
+ SCORPION_ITLB_MISS = 0x12021,
+};
+
+/*
+ * 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_MAP_ALL_UNSUPPORTED,
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_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_STALLED_CYCLES_FRONTEND] = ARMV7_A8_PERFCTR_STALL_ISIDE,
+};
+
+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] = {
+ PERF_CACHE_MAP_ALL_UNSUPPORTED,
+
+ /*
+ * 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(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+
+ [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS,
+ [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
+
+ [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS,
+ [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL,
+ [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS,
+ [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL,
+
+ [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+ [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+
+ [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
+ [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
+
+ [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+};
+
+/*
+ * Cortex-A9 HW events mapping
+ */
+static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
+ PERF_MAP_ALL_UNSUPPORTED,
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_A9_PERFCTR_INSTR_CORE_RENAME,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_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_STALLED_CYCLES_FRONTEND] = ARMV7_A9_PERFCTR_STALL_ICACHE,
+ [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV7_A9_PERFCTR_STALL_DISPATCH,
+};
+
+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] = {
+ PERF_CACHE_MAP_ALL_UNSUPPORTED,
+
+ /*
+ * 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(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+
+ [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
+
+ [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+ [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+
+ [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
+ [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
+
+ [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+};
+
+/*
+ * Cortex-A5 HW events mapping
+ */
+static const unsigned armv7_a5_perf_map[PERF_COUNT_HW_MAX] = {
+ PERF_MAP_ALL_UNSUPPORTED,
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+};
+
+static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ PERF_CACHE_MAP_ALL_UNSUPPORTED,
+
+ [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+ [C(L1D)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL,
+ [C(L1D)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP,
+
+ [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+ [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
+ /*
+ * The prefetch counters don't differentiate between the I side and the
+ * D side.
+ */
+ [C(L1I)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL,
+ [C(L1I)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP,
+
+ [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+ [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+
+ [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
+ [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
+
+ [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+};
+
+/*
+ * Cortex-A15 HW events mapping
+ */
+static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = {
+ PERF_MAP_ALL_UNSUPPORTED,
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A15_PERFCTR_PC_WRITE_SPEC,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
+};
+
+static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ PERF_CACHE_MAP_ALL_UNSUPPORTED,
+
+ [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ,
+ [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE,
+
+ /*
+ * Not all performance counters differentiate between read and write
+ * accesses/misses so we're not always strictly correct, but it's the
+ * best we can do. Writes and reads get combined in these cases.
+ */
+ [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+ [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
+
+ [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ,
+ [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ,
+ [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE,
+ [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE,
+
+ [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ,
+ [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE,
+
+ [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
+ [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
+
+ [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+};
+
+/*
+ * Cortex-A7 HW events mapping
+ */
+static const unsigned armv7_a7_perf_map[PERF_COUNT_HW_MAX] = {
+ PERF_MAP_ALL_UNSUPPORTED,
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_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_BUS_CYCLES,
+};
+
+static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ PERF_CACHE_MAP_ALL_UNSUPPORTED,
+
+ /*
+ * 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(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+
+ [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+ [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
+
+ [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS,
+ [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
+ [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS,
+ [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
+
+ [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+ [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+
+ [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
+ [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
+
+ [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+};
+
+/*
+ * Cortex-A12 HW events mapping
+ */
+static const unsigned armv7_a12_perf_map[PERF_COUNT_HW_MAX] = {
+ PERF_MAP_ALL_UNSUPPORTED,
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A12_PERFCTR_PC_WRITE_SPEC,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
+};
+
+static const unsigned armv7_a12_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ PERF_CACHE_MAP_ALL_UNSUPPORTED,
+
+ [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ,
+ [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+
+ /*
+ * Not all performance counters differentiate between read and write
+ * accesses/misses so we're not always strictly correct, but it's the
+ * best we can do. Writes and reads get combined in these cases.
+ */
+ [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+ [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
+
+ [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ,
+ [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
+ [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE,
+ [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
+
+ [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+ [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+ [C(DTLB)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV7_A12_PERFCTR_PF_TLB_REFILL,
+
+ [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
+ [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
+
+ [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+};
+
+/*
+ * Krait HW events mapping
+ */
+static const unsigned krait_perf_map[PERF_COUNT_HW_MAX] = {
+ PERF_MAP_ALL_UNSUPPORTED,
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
+ [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 krait_perf_map_no_branch[PERF_COUNT_HW_MAX] = {
+ PERF_MAP_ALL_UNSUPPORTED,
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
+};
+
+static const unsigned krait_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ PERF_CACHE_MAP_ALL_UNSUPPORTED,
+
+ /*
+ * 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(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+
+ [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ICACHE_ACCESS,
+ [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = KRAIT_PERFCTR_L1_ICACHE_MISS,
+
+ [C(DTLB)][C(OP_READ)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_DTLB_ACCESS,
+ [C(DTLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_DTLB_ACCESS,
+
+ [C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ITLB_ACCESS,
+ [C(ITLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ITLB_ACCESS,
+
+ [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+};
+
+/*
+ * Scorpion HW events mapping
+ */
+static const unsigned scorpion_perf_map[PERF_COUNT_HW_MAX] = {
+ PERF_MAP_ALL_UNSUPPORTED,
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
+ [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 scorpion_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ PERF_CACHE_MAP_ALL_UNSUPPORTED,
+ /*
+ * 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(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+ [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = SCORPION_ICACHE_ACCESS,
+ [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = SCORPION_ICACHE_MISS,
+ /*
+ * Only ITLB misses and DTLB refills are supported. If users want the
+ * DTLB refills misses a raw counter must be used.
+ */
+ [C(DTLB)][C(OP_READ)][C(RESULT_ACCESS)] = SCORPION_DTLB_ACCESS,
+ [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = SCORPION_DTLB_MISS,
+ [C(DTLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = SCORPION_DTLB_ACCESS,
+ [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = SCORPION_DTLB_MISS,
+ [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = SCORPION_ITLB_MISS,
+ [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = SCORPION_ITLB_MISS,
+ [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+};
+
+/*
+ * Perf Events' indices
+ */
+#define ARMV7_IDX_CYCLE_COUNTER 0
+#define ARMV7_IDX_COUNTER0 1
+#define ARMV7_IDX_COUNTER_LAST(cpu_pmu) \
+ (ARMV7_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1)
+
+#define ARMV7_MAX_COUNTERS 32
+#define ARMV7_COUNTER_MASK (ARMV7_MAX_COUNTERS - 1)
+
+/*
+ * ARMv7 low level PMNC access
+ */
+
+/*
+ * Perf Event to low level counters mapping
+ */
+#define ARMV7_IDX_TO_COUNTER(x) \
+ (((x) - ARMV7_IDX_COUNTER0) & ARMV7_COUNTER_MASK)
+
+/*
+ * 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 */
+
+/*
+ * FLAG: counters overflow flag status reg
+ */
+#define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */
+#define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK
+
+/*
+ * PMXEVTYPER: Event selection reg
+ */
+#define ARMV7_EVTYPE_MASK 0xc80000ff /* Mask for writable bits */
+#define ARMV7_EVTYPE_EVENT 0xff /* Mask for EVENT bits */
+
+/*
+ * Event filters for PMUv2
+ */
+#define ARMV7_EXCLUDE_PL1 (1 << 31)
+#define ARMV7_EXCLUDE_USER (1 << 30)
+#define ARMV7_INCLUDE_HYP (1 << 27)
+
+static inline u32 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(u32 val)
+{
+ val &= ARMV7_PMNC_MASK;
+ isb();
+ asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
+}
+
+static inline int armv7_pmnc_has_overflowed(u32 pmnc)
+{
+ return pmnc & ARMV7_OVERFLOWED_MASK;
+}
+
+static inline int armv7_pmnc_counter_valid(struct arm_pmu *cpu_pmu, int idx)
+{
+ return idx >= ARMV7_IDX_CYCLE_COUNTER &&
+ idx <= ARMV7_IDX_COUNTER_LAST(cpu_pmu);
+}
+
+static inline int armv7_pmnc_counter_has_overflowed(u32 pmnc, int idx)
+{
+ return pmnc & BIT(ARMV7_IDX_TO_COUNTER(idx));
+}
+
+static inline void armv7_pmnc_select_counter(int idx)
+{
+ u32 counter = ARMV7_IDX_TO_COUNTER(idx);
+ asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (counter));
+ isb();
+}
+
+static inline u32 armv7pmu_read_counter(struct perf_event *event)
+{
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = hwc->idx;
+ u32 value = 0;
+
+ if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
+ pr_err("CPU%u reading wrong counter %d\n",
+ smp_processor_id(), idx);
+ } else if (idx == ARMV7_IDX_CYCLE_COUNTER) {
+ asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
+ } else {
+ armv7_pmnc_select_counter(idx);
+ asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (value));
+ }
+
+ return value;
+}
+
+static inline void armv7pmu_write_counter(struct perf_event *event, u32 value)
+{
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = hwc->idx;
+
+ if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
+ pr_err("CPU%u writing wrong counter %d\n",
+ smp_processor_id(), idx);
+ } else if (idx == ARMV7_IDX_CYCLE_COUNTER) {
+ asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
+ } else {
+ armv7_pmnc_select_counter(idx);
+ asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (value));
+ }
+}
+
+static inline void armv7_pmnc_write_evtsel(int idx, u32 val)
+{
+ armv7_pmnc_select_counter(idx);
+ val &= ARMV7_EVTYPE_MASK;
+ asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
+}
+
+static inline void armv7_pmnc_enable_counter(int idx)
+{
+ u32 counter = ARMV7_IDX_TO_COUNTER(idx);
+ asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(counter)));
+}
+
+static inline void armv7_pmnc_disable_counter(int idx)
+{
+ u32 counter = ARMV7_IDX_TO_COUNTER(idx);
+ asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(counter)));
+}
+
+static inline void armv7_pmnc_enable_intens(int idx)
+{
+ u32 counter = ARMV7_IDX_TO_COUNTER(idx);
+ asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(counter)));
+}
+
+static inline void armv7_pmnc_disable_intens(int idx)
+{
+ u32 counter = ARMV7_IDX_TO_COUNTER(idx);
+ asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(counter)));
+ isb();
+ /* Clear the overflow flag in case an interrupt is pending. */
+ asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (BIT(counter)));
+ isb();
+}
+
+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(struct arm_pmu *cpu_pmu)
+{
+ u32 val;
+ unsigned int cnt;
+
+ pr_info("PMNC registers dump:\n");
+
+ asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
+ pr_info("PMNC =0x%08x\n", val);
+
+ asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
+ pr_info("CNTENS=0x%08x\n", val);
+
+ asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
+ pr_info("INTENS=0x%08x\n", val);
+
+ asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
+ pr_info("FLAGS =0x%08x\n", val);
+
+ asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
+ pr_info("SELECT=0x%08x\n", val);
+
+ asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
+ pr_info("CCNT =0x%08x\n", val);
+
+ for (cnt = ARMV7_IDX_COUNTER0;
+ cnt <= ARMV7_IDX_COUNTER_LAST(cpu_pmu); cnt++) {
+ armv7_pmnc_select_counter(cnt);
+ asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
+ pr_info("CNT[%d] count =0x%08x\n",
+ ARMV7_IDX_TO_COUNTER(cnt), val);
+ asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
+ pr_info("CNT[%d] evtsel=0x%08x\n",
+ ARMV7_IDX_TO_COUNTER(cnt), val);
+ }
+}
+#endif
+
+static void armv7pmu_enable_event(struct perf_event *event)
+{
+ unsigned long flags;
+ struct hw_perf_event *hwc = &event->hw;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+ int idx = hwc->idx;
+
+ if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
+ pr_err("CPU%u enabling wrong PMNC counter IRQ enable %d\n",
+ smp_processor_id(), idx);
+ return;
+ }
+
+ /*
+ * Enable counter and interrupt, and set the counter to count
+ * the event that we're interested in.
+ */
+ raw_spin_lock_irqsave(&events->pmu_lock, flags);
+
+ /*
+ * Disable counter
+ */
+ armv7_pmnc_disable_counter(idx);
+
+ /*
+ * Set event (if destined for PMNx counters)
+ * We only need to set the event for the cycle counter if we
+ * have the ability to perform event filtering.
+ */
+ if (cpu_pmu->set_event_filter || idx != ARMV7_IDX_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(&events->pmu_lock, flags);
+}
+
+static void armv7pmu_disable_event(struct perf_event *event)
+{
+ unsigned long flags;
+ struct hw_perf_event *hwc = &event->hw;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+ int idx = hwc->idx;
+
+ if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
+ pr_err("CPU%u disabling wrong PMNC counter IRQ enable %d\n",
+ smp_processor_id(), idx);
+ return;
+ }
+
+ /*
+ * Disable counter and interrupt
+ */
+ raw_spin_lock_irqsave(&events->pmu_lock, flags);
+
+ /*
+ * Disable counter
+ */
+ armv7_pmnc_disable_counter(idx);
+
+ /*
+ * Disable interrupt for this counter
+ */
+ armv7_pmnc_disable_intens(idx);
+
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
+{
+ u32 pmnc;
+ struct perf_sample_data data;
+ struct arm_pmu *cpu_pmu = (struct arm_pmu *)dev;
+ struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
+ 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();
+
+ for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
+ struct perf_event *event = cpuc->events[idx];
+ struct hw_perf_event *hwc;
+
+ /* Ignore if we don't have an event. */
+ if (!event)
+ 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);
+ perf_sample_data_init(&data, 0, hwc->last_period);
+ if (!armpmu_event_set_period(event))
+ continue;
+
+ if (perf_event_overflow(event, &data, regs))
+ cpu_pmu->disable(event);
+ }
+
+ /*
+ * 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(struct arm_pmu *cpu_pmu)
+{
+ unsigned long flags;
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+
+ raw_spin_lock_irqsave(&events->pmu_lock, flags);
+ /* Enable all counters */
+ armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static void armv7pmu_stop(struct arm_pmu *cpu_pmu)
+{
+ unsigned long flags;
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+
+ raw_spin_lock_irqsave(&events->pmu_lock, flags);
+ /* Disable all counters */
+ armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E);
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static int armv7pmu_get_event_idx(struct pmu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ int idx;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ unsigned long evtype = hwc->config_base & ARMV7_EVTYPE_EVENT;
+
+ /* Always place a cycle counter into the cycle counter. */
+ if (evtype == ARMV7_PERFCTR_CPU_CYCLES) {
+ if (test_and_set_bit(ARMV7_IDX_CYCLE_COUNTER, cpuc->used_mask))
+ return -EAGAIN;
+
+ return ARMV7_IDX_CYCLE_COUNTER;
+ }
+
+ /*
+ * For anything other than a cycle counter, try and use
+ * the events counters
+ */
+ for (idx = ARMV7_IDX_COUNTER0; idx < cpu_pmu->num_events; ++idx) {
+ if (!test_and_set_bit(idx, cpuc->used_mask))
+ return idx;
+ }
+
+ /* The counters are all in use. */
+ return -EAGAIN;
+}
+
+/*
+ * Add an event filter to a given event. This will only work for PMUv2 PMUs.
+ */
+static int armv7pmu_set_event_filter(struct hw_perf_event *event,
+ struct perf_event_attr *attr)
+{
+ unsigned long config_base = 0;
+
+ if (attr->exclude_idle)
+ return -EPERM;
+ if (attr->exclude_user)
+ config_base |= ARMV7_EXCLUDE_USER;
+ if (attr->exclude_kernel)
+ config_base |= ARMV7_EXCLUDE_PL1;
+ if (!attr->exclude_hv)
+ config_base |= ARMV7_INCLUDE_HYP;
+
+ /*
+ * Install the filter into config_base as this is used to
+ * construct the event type.
+ */
+ event->config_base = config_base;
+
+ return 0;
+}
+
+static void armv7pmu_reset(void *info)
+{
+ struct arm_pmu *cpu_pmu = (struct arm_pmu *)info;
+ u32 idx, nb_cnt = cpu_pmu->num_events;
+
+ /* The counter and interrupt enable registers are unknown at reset. */
+ for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) {
+ armv7_pmnc_disable_counter(idx);
+ armv7_pmnc_disable_intens(idx);
+ }
+
+ /* Initialize & Reset PMNC: C and P bits */
+ armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
+}
+
+static int armv7_a8_map_event(struct perf_event *event)
+{
+ return armpmu_map_event(event, &armv7_a8_perf_map,
+ &armv7_a8_perf_cache_map, 0xFF);
+}
+
+static int armv7_a9_map_event(struct perf_event *event)
+{
+ return armpmu_map_event(event, &armv7_a9_perf_map,
+ &armv7_a9_perf_cache_map, 0xFF);
+}
+
+static int armv7_a5_map_event(struct perf_event *event)
+{
+ return armpmu_map_event(event, &armv7_a5_perf_map,
+ &armv7_a5_perf_cache_map, 0xFF);
+}
+
+static int armv7_a15_map_event(struct perf_event *event)
+{
+ return armpmu_map_event(event, &armv7_a15_perf_map,
+ &armv7_a15_perf_cache_map, 0xFF);
+}
+
+static int armv7_a7_map_event(struct perf_event *event)
+{
+ return armpmu_map_event(event, &armv7_a7_perf_map,
+ &armv7_a7_perf_cache_map, 0xFF);
+}
+
+static int armv7_a12_map_event(struct perf_event *event)
+{
+ return armpmu_map_event(event, &armv7_a12_perf_map,
+ &armv7_a12_perf_cache_map, 0xFF);
+}
+
+static int krait_map_event(struct perf_event *event)
+{
+ return armpmu_map_event(event, &krait_perf_map,
+ &krait_perf_cache_map, 0xFFFFF);
+}
+
+static int krait_map_event_no_branch(struct perf_event *event)
+{
+ return armpmu_map_event(event, &krait_perf_map_no_branch,
+ &krait_perf_cache_map, 0xFFFFF);
+}
+
+static int scorpion_map_event(struct perf_event *event)
+{
+ return armpmu_map_event(event, &scorpion_perf_map,
+ &scorpion_perf_cache_map, 0xFFFFF);
+}
+
+static void armv7pmu_init(struct arm_pmu *cpu_pmu)
+{
+ cpu_pmu->handle_irq = armv7pmu_handle_irq;
+ cpu_pmu->enable = armv7pmu_enable_event;
+ cpu_pmu->disable = armv7pmu_disable_event;
+ cpu_pmu->read_counter = armv7pmu_read_counter;
+ cpu_pmu->write_counter = armv7pmu_write_counter;
+ cpu_pmu->get_event_idx = armv7pmu_get_event_idx;
+ cpu_pmu->start = armv7pmu_start;
+ cpu_pmu->stop = armv7pmu_stop;
+ cpu_pmu->reset = armv7pmu_reset;
+ cpu_pmu->max_period = (1LLU << 32) - 1;
+};
+
+static u32 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 int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ armv7pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv7_cortex_a8";
+ cpu_pmu->map_event = armv7_a8_map_event;
+ cpu_pmu->num_events = armv7_read_num_pmnc_events();
+ return 0;
+}
+
+static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ armv7pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv7_cortex_a9";
+ cpu_pmu->map_event = armv7_a9_map_event;
+ cpu_pmu->num_events = armv7_read_num_pmnc_events();
+ return 0;
+}
+
+static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ armv7pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv7_cortex_a5";
+ cpu_pmu->map_event = armv7_a5_map_event;
+ cpu_pmu->num_events = armv7_read_num_pmnc_events();
+ return 0;
+}
+
+static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ armv7pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv7_cortex_a15";
+ cpu_pmu->map_event = armv7_a15_map_event;
+ cpu_pmu->num_events = armv7_read_num_pmnc_events();
+ cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+ return 0;
+}
+
+static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ armv7pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv7_cortex_a7";
+ cpu_pmu->map_event = armv7_a7_map_event;
+ cpu_pmu->num_events = armv7_read_num_pmnc_events();
+ cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+ return 0;
+}
+
+static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ armv7pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv7_cortex_a12";
+ cpu_pmu->map_event = armv7_a12_map_event;
+ cpu_pmu->num_events = armv7_read_num_pmnc_events();
+ cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+ return 0;
+}
+
+static int armv7_a17_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ armv7_a12_pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv7_cortex_a17";
+ return 0;
+}
+
+/*
+ * Krait Performance Monitor Region Event Selection Register (PMRESRn)
+ *
+ * 31 30 24 16 8 0
+ * +--------------------------------+
+ * PMRESR0 | EN | CC | CC | CC | CC | N = 1, R = 0
+ * +--------------------------------+
+ * PMRESR1 | EN | CC | CC | CC | CC | N = 1, R = 1
+ * +--------------------------------+
+ * PMRESR2 | EN | CC | CC | CC | CC | N = 1, R = 2
+ * +--------------------------------+
+ * VPMRESR0 | EN | CC | CC | CC | CC | N = 2, R = ?
+ * +--------------------------------+
+ * EN | G=3 | G=2 | G=1 | G=0
+ *
+ * Event Encoding:
+ *
+ * hwc->config_base = 0xNRCCG
+ *
+ * N = prefix, 1 for Krait CPU (PMRESRn), 2 for Venum VFP (VPMRESR)
+ * R = region register
+ * CC = class of events the group G is choosing from
+ * G = group or particular event
+ *
+ * Example: 0x12021 is a Krait CPU event in PMRESR2's group 1 with code 2
+ *
+ * A region (R) corresponds to a piece of the CPU (execution unit, instruction
+ * unit, etc.) while the event code (CC) corresponds to a particular class of
+ * events (interrupts for example). An event code is broken down into
+ * groups (G) that can be mapped into the PMU (irq, fiqs, and irq+fiqs for
+ * example).
+ */
+
+#define KRAIT_EVENT (1 << 16)
+#define VENUM_EVENT (2 << 16)
+#define KRAIT_EVENT_MASK (KRAIT_EVENT | VENUM_EVENT)
+#define PMRESRn_EN BIT(31)
+
+#define EVENT_REGION(event) (((event) >> 12) & 0xf) /* R */
+#define EVENT_GROUP(event) ((event) & 0xf) /* G */
+#define EVENT_CODE(event) (((event) >> 4) & 0xff) /* CC */
+#define EVENT_VENUM(event) (!!(event & VENUM_EVENT)) /* N=2 */
+#define EVENT_CPU(event) (!!(event & KRAIT_EVENT)) /* N=1 */
+
+static u32 krait_read_pmresrn(int n)
+{
+ u32 val;
+
+ switch (n) {
+ case 0:
+ asm volatile("mrc p15, 1, %0, c9, c15, 0" : "=r" (val));
+ break;
+ case 1:
+ asm volatile("mrc p15, 1, %0, c9, c15, 1" : "=r" (val));
+ break;
+ case 2:
+ asm volatile("mrc p15, 1, %0, c9, c15, 2" : "=r" (val));
+ break;
+ default:
+ BUG(); /* Should be validated in krait_pmu_get_event_idx() */
+ }
+
+ return val;
+}
+
+static void krait_write_pmresrn(int n, u32 val)
+{
+ switch (n) {
+ case 0:
+ asm volatile("mcr p15, 1, %0, c9, c15, 0" : : "r" (val));
+ break;
+ case 1:
+ asm volatile("mcr p15, 1, %0, c9, c15, 1" : : "r" (val));
+ break;
+ case 2:
+ asm volatile("mcr p15, 1, %0, c9, c15, 2" : : "r" (val));
+ break;
+ default:
+ BUG(); /* Should be validated in krait_pmu_get_event_idx() */
+ }
+}
+
+static u32 venum_read_pmresr(void)
+{
+ u32 val;
+ asm volatile("mrc p10, 7, %0, c11, c0, 0" : "=r" (val));
+ return val;
+}
+
+static void venum_write_pmresr(u32 val)
+{
+ asm volatile("mcr p10, 7, %0, c11, c0, 0" : : "r" (val));
+}
+
+static void venum_pre_pmresr(u32 *venum_orig_val, u32 *fp_orig_val)
+{
+ u32 venum_new_val;
+ u32 fp_new_val;
+
+ BUG_ON(preemptible());
+ /* CPACR Enable CP10 and CP11 access */
+ *venum_orig_val = get_copro_access();
+ venum_new_val = *venum_orig_val | CPACC_SVC(10) | CPACC_SVC(11);
+ set_copro_access(venum_new_val);
+
+ /* Enable FPEXC */
+ *fp_orig_val = fmrx(FPEXC);
+ fp_new_val = *fp_orig_val | FPEXC_EN;
+ fmxr(FPEXC, fp_new_val);
+}
+
+static void venum_post_pmresr(u32 venum_orig_val, u32 fp_orig_val)
+{
+ BUG_ON(preemptible());
+ /* Restore FPEXC */
+ fmxr(FPEXC, fp_orig_val);
+ isb();
+ /* Restore CPACR */
+ set_copro_access(venum_orig_val);
+}
+
+static u32 krait_get_pmresrn_event(unsigned int region)
+{
+ static const u32 pmresrn_table[] = { KRAIT_PMRESR0_GROUP0,
+ KRAIT_PMRESR1_GROUP0,
+ KRAIT_PMRESR2_GROUP0 };
+ return pmresrn_table[region];
+}
+
+static void krait_evt_setup(int idx, u32 config_base)
+{
+ u32 val;
+ u32 mask;
+ u32 vval, fval;
+ unsigned int region = EVENT_REGION(config_base);
+ unsigned int group = EVENT_GROUP(config_base);
+ unsigned int code = EVENT_CODE(config_base);
+ unsigned int group_shift;
+ bool venum_event = EVENT_VENUM(config_base);
+
+ group_shift = group * 8;
+ mask = 0xff << group_shift;
+
+ /* Configure evtsel for the region and group */
+ if (venum_event)
+ val = KRAIT_VPMRESR0_GROUP0;
+ else
+ val = krait_get_pmresrn_event(region);
+ val += group;
+ /* Mix in mode-exclusion bits */
+ val |= config_base & (ARMV7_EXCLUDE_USER | ARMV7_EXCLUDE_PL1);
+ armv7_pmnc_write_evtsel(idx, val);
+
+ if (venum_event) {
+ venum_pre_pmresr(&vval, &fval);
+ val = venum_read_pmresr();
+ val &= ~mask;
+ val |= code << group_shift;
+ val |= PMRESRn_EN;
+ venum_write_pmresr(val);
+ venum_post_pmresr(vval, fval);
+ } else {
+ val = krait_read_pmresrn(region);
+ val &= ~mask;
+ val |= code << group_shift;
+ val |= PMRESRn_EN;
+ krait_write_pmresrn(region, val);
+ }
+}
+
+static u32 clear_pmresrn_group(u32 val, int group)
+{
+ u32 mask;
+ int group_shift;
+
+ group_shift = group * 8;
+ mask = 0xff << group_shift;
+ val &= ~mask;
+
+ /* Don't clear enable bit if entire region isn't disabled */
+ if (val & ~PMRESRn_EN)
+ return val |= PMRESRn_EN;
+
+ return 0;
+}
+
+static void krait_clearpmu(u32 config_base)
+{
+ u32 val;
+ u32 vval, fval;
+ unsigned int region = EVENT_REGION(config_base);
+ unsigned int group = EVENT_GROUP(config_base);
+ bool venum_event = EVENT_VENUM(config_base);
+
+ if (venum_event) {
+ venum_pre_pmresr(&vval, &fval);
+ val = venum_read_pmresr();
+ val = clear_pmresrn_group(val, group);
+ venum_write_pmresr(val);
+ venum_post_pmresr(vval, fval);
+ } else {
+ val = krait_read_pmresrn(region);
+ val = clear_pmresrn_group(val, group);
+ krait_write_pmresrn(region, val);
+ }
+}
+
+static void krait_pmu_disable_event(struct perf_event *event)
+{
+ unsigned long flags;
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = hwc->idx;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+
+ /* Disable counter and interrupt */
+ raw_spin_lock_irqsave(&events->pmu_lock, flags);
+
+ /* Disable counter */
+ armv7_pmnc_disable_counter(idx);
+
+ /*
+ * Clear pmresr code (if destined for PMNx counters)
+ */
+ if (hwc->config_base & KRAIT_EVENT_MASK)
+ krait_clearpmu(hwc->config_base);
+
+ /* Disable interrupt for this counter */
+ armv7_pmnc_disable_intens(idx);
+
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static void krait_pmu_enable_event(struct perf_event *event)
+{
+ unsigned long flags;
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = hwc->idx;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+
+ /*
+ * Enable counter and interrupt, and set the counter to count
+ * the event that we're interested in.
+ */
+ raw_spin_lock_irqsave(&events->pmu_lock, flags);
+
+ /* Disable counter */
+ armv7_pmnc_disable_counter(idx);
+
+ /*
+ * Set event (if destined for PMNx counters)
+ * We set the event for the cycle counter because we
+ * have the ability to perform event filtering.
+ */
+ if (hwc->config_base & KRAIT_EVENT_MASK)
+ krait_evt_setup(idx, hwc->config_base);
+ else
+ 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(&events->pmu_lock, flags);
+}
+
+static void krait_pmu_reset(void *info)
+{
+ u32 vval, fval;
+ struct arm_pmu *cpu_pmu = info;
+ u32 idx, nb_cnt = cpu_pmu->num_events;
+
+ armv7pmu_reset(info);
+
+ /* Clear all pmresrs */
+ krait_write_pmresrn(0, 0);
+ krait_write_pmresrn(1, 0);
+ krait_write_pmresrn(2, 0);
+
+ venum_pre_pmresr(&vval, &fval);
+ venum_write_pmresr(0);
+ venum_post_pmresr(vval, fval);
+
+ /* Reset PMxEVNCTCR to sane default */
+ for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) {
+ armv7_pmnc_select_counter(idx);
+ asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
+ }
+
+}
+
+static int krait_event_to_bit(struct perf_event *event, unsigned int region,
+ unsigned int group)
+{
+ int bit;
+ struct hw_perf_event *hwc = &event->hw;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+
+ if (hwc->config_base & VENUM_EVENT)
+ bit = KRAIT_VPMRESR0_GROUP0;
+ else
+ bit = krait_get_pmresrn_event(region);
+ bit -= krait_get_pmresrn_event(0);
+ bit += group;
+ /*
+ * Lower bits are reserved for use by the counters (see
+ * armv7pmu_get_event_idx() for more info)
+ */
+ bit += ARMV7_IDX_COUNTER_LAST(cpu_pmu) + 1;
+
+ return bit;
+}
+
+/*
+ * We check for column exclusion constraints here.
+ * Two events cant use the same group within a pmresr register.
+ */
+static int krait_pmu_get_event_idx(struct pmu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ int idx;
+ int bit = -1;
+ struct hw_perf_event *hwc = &event->hw;
+ unsigned int region = EVENT_REGION(hwc->config_base);
+ unsigned int code = EVENT_CODE(hwc->config_base);
+ unsigned int group = EVENT_GROUP(hwc->config_base);
+ bool venum_event = EVENT_VENUM(hwc->config_base);
+ bool krait_event = EVENT_CPU(hwc->config_base);
+
+ if (venum_event || krait_event) {
+ /* Ignore invalid events */
+ if (group > 3 || region > 2)
+ return -EINVAL;
+ if (venum_event && (code & 0xe0))
+ return -EINVAL;
+
+ bit = krait_event_to_bit(event, region, group);
+ if (test_and_set_bit(bit, cpuc->used_mask))
+ return -EAGAIN;
+ }
+
+ idx = armv7pmu_get_event_idx(cpuc, event);
+ if (idx < 0 && bit >= 0)
+ clear_bit(bit, cpuc->used_mask);
+
+ return idx;
+}
+
+static void krait_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ int bit;
+ struct hw_perf_event *hwc = &event->hw;
+ unsigned int region = EVENT_REGION(hwc->config_base);
+ unsigned int group = EVENT_GROUP(hwc->config_base);
+ bool venum_event = EVENT_VENUM(hwc->config_base);
+ bool krait_event = EVENT_CPU(hwc->config_base);
+
+ if (venum_event || krait_event) {
+ bit = krait_event_to_bit(event, region, group);
+ clear_bit(bit, cpuc->used_mask);
+ }
+}
+
+static int krait_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ armv7pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv7_krait";
+ /* Some early versions of Krait don't support PC write events */
+ if (of_property_read_bool(cpu_pmu->plat_device->dev.of_node,
+ "qcom,no-pc-write"))
+ cpu_pmu->map_event = krait_map_event_no_branch;
+ else
+ cpu_pmu->map_event = krait_map_event;
+ cpu_pmu->num_events = armv7_read_num_pmnc_events();
+ cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+ cpu_pmu->reset = krait_pmu_reset;
+ cpu_pmu->enable = krait_pmu_enable_event;
+ cpu_pmu->disable = krait_pmu_disable_event;
+ cpu_pmu->get_event_idx = krait_pmu_get_event_idx;
+ cpu_pmu->clear_event_idx = krait_pmu_clear_event_idx;
+ return 0;
+}
+
+/*
+ * Scorpion Local Performance Monitor Register (LPMn)
+ *
+ * 31 30 24 16 8 0
+ * +--------------------------------+
+ * LPM0 | EN | CC | CC | CC | CC | N = 1, R = 0
+ * +--------------------------------+
+ * LPM1 | EN | CC | CC | CC | CC | N = 1, R = 1
+ * +--------------------------------+
+ * LPM2 | EN | CC | CC | CC | CC | N = 1, R = 2
+ * +--------------------------------+
+ * L2LPM | EN | CC | CC | CC | CC | N = 1, R = 3
+ * +--------------------------------+
+ * VLPM | EN | CC | CC | CC | CC | N = 2, R = ?
+ * +--------------------------------+
+ * EN | G=3 | G=2 | G=1 | G=0
+ *
+ *
+ * Event Encoding:
+ *
+ * hwc->config_base = 0xNRCCG
+ *
+ * N = prefix, 1 for Scorpion CPU (LPMn/L2LPM), 2 for Venum VFP (VLPM)
+ * R = region register
+ * CC = class of events the group G is choosing from
+ * G = group or particular event
+ *
+ * Example: 0x12021 is a Scorpion CPU event in LPM2's group 1 with code 2
+ *
+ * A region (R) corresponds to a piece of the CPU (execution unit, instruction
+ * unit, etc.) while the event code (CC) corresponds to a particular class of
+ * events (interrupts for example). An event code is broken down into
+ * groups (G) that can be mapped into the PMU (irq, fiqs, and irq+fiqs for
+ * example).
+ */
+
+static u32 scorpion_read_pmresrn(int n)
+{
+ u32 val;
+
+ switch (n) {
+ case 0:
+ asm volatile("mrc p15, 0, %0, c15, c0, 0" : "=r" (val));
+ break;
+ case 1:
+ asm volatile("mrc p15, 1, %0, c15, c0, 0" : "=r" (val));
+ break;
+ case 2:
+ asm volatile("mrc p15, 2, %0, c15, c0, 0" : "=r" (val));
+ break;
+ case 3:
+ asm volatile("mrc p15, 3, %0, c15, c2, 0" : "=r" (val));
+ break;
+ default:
+ BUG(); /* Should be validated in scorpion_pmu_get_event_idx() */
+ }
+
+ return val;
+}
+
+static void scorpion_write_pmresrn(int n, u32 val)
+{
+ switch (n) {
+ case 0:
+ asm volatile("mcr p15, 0, %0, c15, c0, 0" : : "r" (val));
+ break;
+ case 1:
+ asm volatile("mcr p15, 1, %0, c15, c0, 0" : : "r" (val));
+ break;
+ case 2:
+ asm volatile("mcr p15, 2, %0, c15, c0, 0" : : "r" (val));
+ break;
+ case 3:
+ asm volatile("mcr p15, 3, %0, c15, c2, 0" : : "r" (val));
+ break;
+ default:
+ BUG(); /* Should be validated in scorpion_pmu_get_event_idx() */
+ }
+}
+
+static u32 scorpion_get_pmresrn_event(unsigned int region)
+{
+ static const u32 pmresrn_table[] = { SCORPION_LPM0_GROUP0,
+ SCORPION_LPM1_GROUP0,
+ SCORPION_LPM2_GROUP0,
+ SCORPION_L2LPM_GROUP0 };
+ return pmresrn_table[region];
+}
+
+static void scorpion_evt_setup(int idx, u32 config_base)
+{
+ u32 val;
+ u32 mask;
+ u32 vval, fval;
+ unsigned int region = EVENT_REGION(config_base);
+ unsigned int group = EVENT_GROUP(config_base);
+ unsigned int code = EVENT_CODE(config_base);
+ unsigned int group_shift;
+ bool venum_event = EVENT_VENUM(config_base);
+
+ group_shift = group * 8;
+ mask = 0xff << group_shift;
+
+ /* Configure evtsel for the region and group */
+ if (venum_event)
+ val = SCORPION_VLPM_GROUP0;
+ else
+ val = scorpion_get_pmresrn_event(region);
+ val += group;
+ /* Mix in mode-exclusion bits */
+ val |= config_base & (ARMV7_EXCLUDE_USER | ARMV7_EXCLUDE_PL1);
+ armv7_pmnc_write_evtsel(idx, val);
+
+ asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
+
+ if (venum_event) {
+ venum_pre_pmresr(&vval, &fval);
+ val = venum_read_pmresr();
+ val &= ~mask;
+ val |= code << group_shift;
+ val |= PMRESRn_EN;
+ venum_write_pmresr(val);
+ venum_post_pmresr(vval, fval);
+ } else {
+ val = scorpion_read_pmresrn(region);
+ val &= ~mask;
+ val |= code << group_shift;
+ val |= PMRESRn_EN;
+ scorpion_write_pmresrn(region, val);
+ }
+}
+
+static void scorpion_clearpmu(u32 config_base)
+{
+ u32 val;
+ u32 vval, fval;
+ unsigned int region = EVENT_REGION(config_base);
+ unsigned int group = EVENT_GROUP(config_base);
+ bool venum_event = EVENT_VENUM(config_base);
+
+ if (venum_event) {
+ venum_pre_pmresr(&vval, &fval);
+ val = venum_read_pmresr();
+ val = clear_pmresrn_group(val, group);
+ venum_write_pmresr(val);
+ venum_post_pmresr(vval, fval);
+ } else {
+ val = scorpion_read_pmresrn(region);
+ val = clear_pmresrn_group(val, group);
+ scorpion_write_pmresrn(region, val);
+ }
+}
+
+static void scorpion_pmu_disable_event(struct perf_event *event)
+{
+ unsigned long flags;
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = hwc->idx;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+
+ /* Disable counter and interrupt */
+ raw_spin_lock_irqsave(&events->pmu_lock, flags);
+
+ /* Disable counter */
+ armv7_pmnc_disable_counter(idx);
+
+ /*
+ * Clear pmresr code (if destined for PMNx counters)
+ */
+ if (hwc->config_base & KRAIT_EVENT_MASK)
+ scorpion_clearpmu(hwc->config_base);
+
+ /* Disable interrupt for this counter */
+ armv7_pmnc_disable_intens(idx);
+
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static void scorpion_pmu_enable_event(struct perf_event *event)
+{
+ unsigned long flags;
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = hwc->idx;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+
+ /*
+ * Enable counter and interrupt, and set the counter to count
+ * the event that we're interested in.
+ */
+ raw_spin_lock_irqsave(&events->pmu_lock, flags);
+
+ /* Disable counter */
+ armv7_pmnc_disable_counter(idx);
+
+ /*
+ * Set event (if destined for PMNx counters)
+ * We don't set the event for the cycle counter because we
+ * don't have the ability to perform event filtering.
+ */
+ if (hwc->config_base & KRAIT_EVENT_MASK)
+ scorpion_evt_setup(idx, hwc->config_base);
+ else if (idx != ARMV7_IDX_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(&events->pmu_lock, flags);
+}
+
+static void scorpion_pmu_reset(void *info)
+{
+ u32 vval, fval;
+ struct arm_pmu *cpu_pmu = info;
+ u32 idx, nb_cnt = cpu_pmu->num_events;
+
+ armv7pmu_reset(info);
+
+ /* Clear all pmresrs */
+ scorpion_write_pmresrn(0, 0);
+ scorpion_write_pmresrn(1, 0);
+ scorpion_write_pmresrn(2, 0);
+ scorpion_write_pmresrn(3, 0);
+
+ venum_pre_pmresr(&vval, &fval);
+ venum_write_pmresr(0);
+ venum_post_pmresr(vval, fval);
+
+ /* Reset PMxEVNCTCR to sane default */
+ for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) {
+ armv7_pmnc_select_counter(idx);
+ asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
+ }
+}
+
+static int scorpion_event_to_bit(struct perf_event *event, unsigned int region,
+ unsigned int group)
+{
+ int bit;
+ struct hw_perf_event *hwc = &event->hw;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+
+ if (hwc->config_base & VENUM_EVENT)
+ bit = SCORPION_VLPM_GROUP0;
+ else
+ bit = scorpion_get_pmresrn_event(region);
+ bit -= scorpion_get_pmresrn_event(0);
+ bit += group;
+ /*
+ * Lower bits are reserved for use by the counters (see
+ * armv7pmu_get_event_idx() for more info)
+ */
+ bit += ARMV7_IDX_COUNTER_LAST(cpu_pmu) + 1;
+
+ return bit;
+}
+
+/*
+ * We check for column exclusion constraints here.
+ * Two events cant use the same group within a pmresr register.
+ */
+static int scorpion_pmu_get_event_idx(struct pmu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ int idx;
+ int bit = -1;
+ struct hw_perf_event *hwc = &event->hw;
+ unsigned int region = EVENT_REGION(hwc->config_base);
+ unsigned int group = EVENT_GROUP(hwc->config_base);
+ bool venum_event = EVENT_VENUM(hwc->config_base);
+ bool scorpion_event = EVENT_CPU(hwc->config_base);
+
+ if (venum_event || scorpion_event) {
+ /* Ignore invalid events */
+ if (group > 3 || region > 3)
+ return -EINVAL;
+
+ bit = scorpion_event_to_bit(event, region, group);
+ if (test_and_set_bit(bit, cpuc->used_mask))
+ return -EAGAIN;
+ }
+
+ idx = armv7pmu_get_event_idx(cpuc, event);
+ if (idx < 0 && bit >= 0)
+ clear_bit(bit, cpuc->used_mask);
+
+ return idx;
+}
+
+static void scorpion_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ int bit;
+ struct hw_perf_event *hwc = &event->hw;
+ unsigned int region = EVENT_REGION(hwc->config_base);
+ unsigned int group = EVENT_GROUP(hwc->config_base);
+ bool venum_event = EVENT_VENUM(hwc->config_base);
+ bool scorpion_event = EVENT_CPU(hwc->config_base);
+
+ if (venum_event || scorpion_event) {
+ bit = scorpion_event_to_bit(event, region, group);
+ clear_bit(bit, cpuc->used_mask);
+ }
+}
+
+static int scorpion_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ armv7pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv7_scorpion";
+ cpu_pmu->map_event = scorpion_map_event;
+ cpu_pmu->num_events = armv7_read_num_pmnc_events();
+ cpu_pmu->reset = scorpion_pmu_reset;
+ cpu_pmu->enable = scorpion_pmu_enable_event;
+ cpu_pmu->disable = scorpion_pmu_disable_event;
+ cpu_pmu->get_event_idx = scorpion_pmu_get_event_idx;
+ cpu_pmu->clear_event_idx = scorpion_pmu_clear_event_idx;
+ return 0;
+}
+
+static int scorpion_mp_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ armv7pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv7_scorpion_mp";
+ cpu_pmu->map_event = scorpion_map_event;
+ cpu_pmu->num_events = armv7_read_num_pmnc_events();
+ cpu_pmu->reset = scorpion_pmu_reset;
+ cpu_pmu->enable = scorpion_pmu_enable_event;
+ cpu_pmu->disable = scorpion_pmu_disable_event;
+ cpu_pmu->get_event_idx = scorpion_pmu_get_event_idx;
+ cpu_pmu->clear_event_idx = scorpion_pmu_clear_event_idx;
+ return 0;
+}
+#else
+static inline int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ return -ENODEV;
+}
+
+static inline int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ return -ENODEV;
+}
+
+static inline int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ return -ENODEV;
+}
+
+static inline int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ return -ENODEV;
+}
+
+static inline int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ return -ENODEV;
+}
+
+static inline int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ return -ENODEV;
+}
+
+static inline int armv7_a17_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ return -ENODEV;
+}
+
+static inline int krait_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ return -ENODEV;
+}
+
+static inline int scorpion_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ return -ENODEV;
+}
+
+static inline int scorpion_mp_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ return -ENODEV;
+}
+#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 000000000..8af9f1f82
--- /dev/null
+++ b/arch/arm/kernel/perf_event_xscale.c
@@ -0,0 +1,753 @@
+/*
+ * 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 = 0,
+ XSCALE_COUNTER0,
+ XSCALE_COUNTER1,
+ XSCALE_COUNTER2,
+ XSCALE_COUNTER3,
+};
+
+static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = {
+ PERF_MAP_ALL_UNSUPPORTED,
+ [PERF_COUNT_HW_CPU_CYCLES] = XSCALE_PERFCTR_CCNT,
+ [PERF_COUNT_HW_INSTRUCTIONS] = XSCALE_PERFCTR_INSTRUCTION,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH,
+ [PERF_COUNT_HW_BRANCH_MISSES] = XSCALE_PERFCTR_BRANCH_MISS,
+ [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = XSCALE_PERFCTR_ICACHE_NO_DELIVER,
+};
+
+static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ PERF_CACHE_MAP_ALL_UNSUPPORTED,
+
+ [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS,
+ [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS,
+
+ [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS,
+
+ [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS,
+ [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS,
+
+ [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS,
+ [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS,
+};
+
+#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 arm_pmu *cpu_pmu = (struct arm_pmu *)dev;
+ struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
+ 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();
+
+ for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
+ struct perf_event *event = cpuc->events[idx];
+ struct hw_perf_event *hwc;
+
+ if (!event)
+ continue;
+
+ if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx))
+ continue;
+
+ hwc = &event->hw;
+ armpmu_event_update(event);
+ perf_sample_data_init(&data, 0, hwc->last_period);
+ if (!armpmu_event_set_period(event))
+ continue;
+
+ if (perf_event_overflow(event, &data, regs))
+ cpu_pmu->disable(event);
+ }
+
+ 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 perf_event *event)
+{
+ unsigned long val, mask, evt, flags;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+ int idx = hwc->idx;
+
+ 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(&events->pmu_lock, flags);
+ val = xscale1pmu_read_pmnc();
+ val &= ~mask;
+ val |= evt;
+ xscale1pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static void xscale1pmu_disable_event(struct perf_event *event)
+{
+ unsigned long val, mask, evt, flags;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+ int idx = hwc->idx;
+
+ 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(&events->pmu_lock, flags);
+ val = xscale1pmu_read_pmnc();
+ val &= ~mask;
+ val |= evt;
+ xscale1pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static int
+xscale1pmu_get_event_idx(struct pmu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ if (XSCALE_PERFCTR_CCNT == hwc->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(struct arm_pmu *cpu_pmu)
+{
+ unsigned long flags, val;
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+
+ raw_spin_lock_irqsave(&events->pmu_lock, flags);
+ val = xscale1pmu_read_pmnc();
+ val |= XSCALE_PMU_ENABLE;
+ xscale1pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static void xscale1pmu_stop(struct arm_pmu *cpu_pmu)
+{
+ unsigned long flags, val;
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+
+ raw_spin_lock_irqsave(&events->pmu_lock, flags);
+ val = xscale1pmu_read_pmnc();
+ val &= ~XSCALE_PMU_ENABLE;
+ xscale1pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static inline u32 xscale1pmu_read_counter(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ int counter = hwc->idx;
+ 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(struct perf_event *event, u32 val)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ int counter = hwc->idx;
+
+ 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 int xscale_map_event(struct perf_event *event)
+{
+ return armpmu_map_event(event, &xscale_perf_map,
+ &xscale_perf_cache_map, 0xFF);
+}
+
+static int xscale1pmu_init(struct arm_pmu *cpu_pmu)
+{
+ cpu_pmu->name = "armv5_xscale1";
+ cpu_pmu->handle_irq = xscale1pmu_handle_irq;
+ cpu_pmu->enable = xscale1pmu_enable_event;
+ cpu_pmu->disable = xscale1pmu_disable_event;
+ cpu_pmu->read_counter = xscale1pmu_read_counter;
+ cpu_pmu->write_counter = xscale1pmu_write_counter;
+ cpu_pmu->get_event_idx = xscale1pmu_get_event_idx;
+ cpu_pmu->start = xscale1pmu_start;
+ cpu_pmu->stop = xscale1pmu_stop;
+ cpu_pmu->map_event = xscale_map_event;
+ cpu_pmu->num_events = 3;
+ cpu_pmu->max_period = (1LLU << 32) - 1;
+
+ return 0;
+}
+
+#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 arm_pmu *cpu_pmu = (struct arm_pmu *)dev;
+ struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
+ 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();
+
+ for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
+ struct perf_event *event = cpuc->events[idx];
+ struct hw_perf_event *hwc;
+
+ if (!event)
+ continue;
+
+ if (!xscale2_pmnc_counter_has_overflowed(of_flags, idx))
+ continue;
+
+ hwc = &event->hw;
+ armpmu_event_update(event);
+ perf_sample_data_init(&data, 0, hwc->last_period);
+ if (!armpmu_event_set_period(event))
+ continue;
+
+ if (perf_event_overflow(event, &data, regs))
+ cpu_pmu->disable(event);
+ }
+
+ 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 perf_event *event)
+{
+ unsigned long flags, ien, evtsel;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+ int idx = hwc->idx;
+
+ 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(&events->pmu_lock, flags);
+ xscale2pmu_write_event_select(evtsel);
+ xscale2pmu_write_int_enable(ien);
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static void xscale2pmu_disable_event(struct perf_event *event)
+{
+ unsigned long flags, ien, evtsel, of_flags;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+ int idx = hwc->idx;
+
+ ien = xscale2pmu_read_int_enable();
+ evtsel = xscale2pmu_read_event_select();
+
+ switch (idx) {
+ case XSCALE_CYCLE_COUNTER:
+ ien &= ~XSCALE2_CCOUNT_INT_EN;
+ of_flags = XSCALE2_CCOUNT_OVERFLOW;
+ break;
+ case XSCALE_COUNTER0:
+ ien &= ~XSCALE2_COUNT0_INT_EN;
+ evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
+ evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT0_EVT_SHFT;
+ of_flags = XSCALE2_COUNT0_OVERFLOW;
+ break;
+ case XSCALE_COUNTER1:
+ ien &= ~XSCALE2_COUNT1_INT_EN;
+ evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
+ evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT1_EVT_SHFT;
+ of_flags = XSCALE2_COUNT1_OVERFLOW;
+ break;
+ case XSCALE_COUNTER2:
+ ien &= ~XSCALE2_COUNT2_INT_EN;
+ evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
+ evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT2_EVT_SHFT;
+ of_flags = XSCALE2_COUNT2_OVERFLOW;
+ break;
+ case XSCALE_COUNTER3:
+ ien &= ~XSCALE2_COUNT3_INT_EN;
+ evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
+ evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT3_EVT_SHFT;
+ of_flags = XSCALE2_COUNT3_OVERFLOW;
+ break;
+ default:
+ WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+ return;
+ }
+
+ raw_spin_lock_irqsave(&events->pmu_lock, flags);
+ xscale2pmu_write_event_select(evtsel);
+ xscale2pmu_write_int_enable(ien);
+ xscale2pmu_write_overflow_flags(of_flags);
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static int
+xscale2pmu_get_event_idx(struct pmu_hw_events *cpuc,
+ struct 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(struct arm_pmu *cpu_pmu)
+{
+ unsigned long flags, val;
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+
+ raw_spin_lock_irqsave(&events->pmu_lock, flags);
+ val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64;
+ val |= XSCALE_PMU_ENABLE;
+ xscale2pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static void xscale2pmu_stop(struct arm_pmu *cpu_pmu)
+{
+ unsigned long flags, val;
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
+
+ raw_spin_lock_irqsave(&events->pmu_lock, flags);
+ val = xscale2pmu_read_pmnc();
+ val &= ~XSCALE_PMU_ENABLE;
+ xscale2pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static inline u32 xscale2pmu_read_counter(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ int counter = hwc->idx;
+ 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(struct perf_event *event, u32 val)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ int counter = hwc->idx;
+
+ 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 int xscale2pmu_init(struct arm_pmu *cpu_pmu)
+{
+ cpu_pmu->name = "armv5_xscale2";
+ cpu_pmu->handle_irq = xscale2pmu_handle_irq;
+ cpu_pmu->enable = xscale2pmu_enable_event;
+ cpu_pmu->disable = xscale2pmu_disable_event;
+ cpu_pmu->read_counter = xscale2pmu_read_counter;
+ cpu_pmu->write_counter = xscale2pmu_write_counter;
+ cpu_pmu->get_event_idx = xscale2pmu_get_event_idx;
+ cpu_pmu->start = xscale2pmu_start;
+ cpu_pmu->stop = xscale2pmu_stop;
+ cpu_pmu->map_event = xscale_map_event;
+ cpu_pmu->num_events = 5;
+ cpu_pmu->max_period = (1LLU << 32) - 1;
+
+ return 0;
+}
+#else
+static inline int xscale1pmu_init(struct arm_pmu *cpu_pmu)
+{
+ return -ENODEV;
+}
+
+static inline int xscale2pmu_init(struct arm_pmu *cpu_pmu)
+{
+ return -ENODEV;
+}
+#endif /* CONFIG_CPU_XSCALE */
diff --git a/arch/arm/kernel/perf_regs.c b/arch/arm/kernel/perf_regs.c
new file mode 100644
index 000000000..592dda3f2
--- /dev/null
+++ b/arch/arm/kernel/perf_regs.c
@@ -0,0 +1,38 @@
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/perf_event.h>
+#include <linux/bug.h>
+#include <asm/perf_regs.h>
+#include <asm/ptrace.h>
+
+u64 perf_reg_value(struct pt_regs *regs, int idx)
+{
+ if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM_MAX))
+ return 0;
+
+ return regs->uregs[idx];
+}
+
+#define REG_RESERVED (~((1ULL << PERF_REG_ARM_MAX) - 1))
+
+int perf_reg_validate(u64 mask)
+{
+ if (!mask || mask & REG_RESERVED)
+ return -EINVAL;
+
+ return 0;
+}
+
+u64 perf_reg_abi(struct task_struct *task)
+{
+ return PERF_SAMPLE_REGS_ABI_32;
+}
+
+void perf_get_regs_user(struct perf_regs *regs_user,
+ struct pt_regs *regs,
+ struct pt_regs *regs_user_copy)
+{
+ regs_user->regs = task_pt_regs(current);
+ regs_user->abi = perf_reg_abi(current);
+}
diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c
new file mode 100644
index 000000000..8153e36b2
--- /dev/null
+++ b/arch/arm/kernel/pj4-cp0.c
@@ -0,0 +1,133 @@
+/*
+ * 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/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>
+#include <asm/cputype.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 __maybe_unused 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));
+}
+
+static int __init pj4_get_iwmmxt_version(void)
+{
+ u32 cp_access, wcid;
+
+ cp_access = pj4_cp_access_read();
+ pj4_cp_access_write(cp_access | 0xf);
+
+ /* check if coprocessor 0 and 1 are available */
+ if ((pj4_cp_access_read() & 0xf) != 0xf) {
+ pj4_cp_access_write(cp_access);
+ return -ENODEV;
+ }
+
+ /* read iWMMXt coprocessor id register p1, c0 */
+ __asm__ __volatile__ ("mrc p1, 0, %0, c0, c0, 0\n" : "=r" (wcid));
+
+ pj4_cp_access_write(cp_access);
+
+ /* iWMMXt v1 */
+ if ((wcid & 0xffffff00) == 0x56051000)
+ return 1;
+ /* iWMMXt v2 */
+ if ((wcid & 0xffffff00) == 0x56052000)
+ return 2;
+
+ return -EINVAL;
+}
+
+/*
+ * 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 __maybe_unused cp_access;
+ int vers;
+
+ if (!cpu_is_pj4())
+ return 0;
+
+ vers = pj4_get_iwmmxt_version();
+ if (vers < 0)
+ return 0;
+
+#ifndef CONFIG_IWMMXT
+ pr_info("PJ4 iWMMXt coprocessor detected, but kernel support is missing.\n");
+#else
+ cp_access = pj4_cp_access_read() & ~0xf;
+ pj4_cp_access_write(cp_access);
+
+ pr_info("PJ4 iWMMXt v%d coprocessor enabled.\n", vers);
+ elf_hwcap |= HWCAP_IWMMXT;
+ thread_register_notifier(&iwmmxt_notifier_block);
+#endif
+
+ return 0;
+}
+
+late_initcall(pj4_cp0_init);
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
new file mode 100644
index 000000000..f192a2a41
--- /dev/null
+++ b/arch/arm/kernel/process.c
@@ -0,0 +1,423 @@
+/*
+ * 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/export.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/interrupt.h>
+#include <linux/kallsyms.h>
+#include <linux/init.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/leds.h>
+
+#include <asm/processor.h>
+#include <asm/thread_notify.h>
+#include <asm/stacktrace.h>
+#include <asm/system_misc.h>
+#include <asm/mach/time.h>
+#include <asm/tls.h>
+#include <asm/vdso.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[] __maybe_unused = {
+ "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" , "MON_32" , "ABT_32" ,
+ "UK8_32" , "UK9_32" , "HYP_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
+};
+
+static const char *isa_modes[] __maybe_unused = {
+ "ARM" , "Thumb" , "Jazelle", "ThumbEE"
+};
+
+/*
+ * This is our default idle handler.
+ */
+
+void (*arm_pm_idle)(void);
+
+/*
+ * Called from the core idle loop.
+ */
+
+void arch_cpu_idle(void)
+{
+ if (arm_pm_idle)
+ arm_pm_idle();
+ else
+ cpu_do_idle();
+ local_irq_enable();
+}
+
+void arch_cpu_idle_prepare(void)
+{
+ local_fiq_enable();
+}
+
+void arch_cpu_idle_enter(void)
+{
+ ledtrig_cpu(CPU_LED_IDLE_START);
+#ifdef CONFIG_PL310_ERRATA_769419
+ wmb();
+#endif
+}
+
+void arch_cpu_idle_exit(void)
+{
+ ledtrig_cpu(CPU_LED_IDLE_END);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+void arch_cpu_idle_dead(void)
+{
+ cpu_die();
+}
+#endif
+
+void __show_regs(struct pt_regs *regs)
+{
+ unsigned long flags;
+ char buf[64];
+
+ show_regs_print_info(KERN_DEFAULT);
+
+ 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';
+
+#ifndef CONFIG_CPU_V7M
+ 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");
+#else
+ printk("xPSR: %08lx\n", regs->ARM_cpsr);
+#endif
+
+#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
+}
+
+void show_regs(struct pt_regs * regs)
+{
+ __show_regs(regs);
+ dump_stack();
+}
+
+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));
+
+ flush_tls();
+
+ 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 thread_info *thread = task_thread_info(p);
+ struct pt_regs *childregs = task_pt_regs(p);
+
+ memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
+
+ if (likely(!(p->flags & PF_KTHREAD))) {
+ *childregs = *current_pt_regs();
+ childregs->ARM_r0 = 0;
+ if (stack_start)
+ childregs->ARM_sp = stack_start;
+ } else {
+ memset(childregs, 0, sizeof(struct pt_regs));
+ thread->cpu_context.r4 = stk_sz;
+ thread->cpu_context.r5 = stack_start;
+ childregs->ARM_cpsr = SVC_MODE;
+ }
+ thread->cpu_context.pc = (unsigned long)ret_from_fork;
+ thread->cpu_context.sp = (unsigned long)childregs;
+
+ clear_ptrace_hw_breakpoint(p);
+
+ if (clone_flags & CLONE_SETTLS)
+ thread->tp_value[0] = childregs->ARM_r3;
+ thread->tp_value[1] = get_tpuser();
+
+ 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);
+
+unsigned long get_wchan(struct task_struct *p)
+{
+ struct stackframe frame;
+ unsigned long stack_page;
+ 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);
+ stack_page = (unsigned long)task_stack_page(p);
+ do {
+ if (frame.sp < stack_page ||
+ frame.sp >= stack_page + THREAD_SIZE ||
+ unwind_frame(&frame) < 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
+#ifdef CONFIG_KUSER_HELPERS
+/*
+ * The vectors page is always readable from user space for the
+ * atomic helpers. Insert it into the gate_vma so that it is visible
+ * through ptrace and /proc/<pid>/mem.
+ */
+static struct vm_area_struct gate_vma = {
+ .vm_start = 0xffff0000,
+ .vm_end = 0xffff0000 + PAGE_SIZE,
+ .vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC,
+};
+
+static int __init gate_vma_init(void)
+{
+ gate_vma.vm_page_prot = PAGE_READONLY_EXEC;
+ return 0;
+}
+arch_initcall(gate_vma_init);
+
+struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
+{
+ return &gate_vma;
+}
+
+int in_gate_area(struct mm_struct *mm, unsigned long addr)
+{
+ return (addr >= gate_vma.vm_start) && (addr < gate_vma.vm_end);
+}
+
+int in_gate_area_no_mm(unsigned long addr)
+{
+ return in_gate_area(NULL, addr);
+}
+#define is_gate_vma(vma) ((vma) == &gate_vma)
+#else
+#define is_gate_vma(vma) 0
+#endif
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+ return is_gate_vma(vma) ? "[vectors]" : NULL;
+}
+
+/* If possible, provide a placement hint at a random offset from the
+ * stack for the sigpage and vdso pages.
+ */
+static unsigned long sigpage_addr(const struct mm_struct *mm,
+ unsigned int npages)
+{
+ unsigned long offset;
+ unsigned long first;
+ unsigned long last;
+ unsigned long addr;
+ unsigned int slots;
+
+ first = PAGE_ALIGN(mm->start_stack);
+
+ last = TASK_SIZE - (npages << PAGE_SHIFT);
+
+ /* No room after stack? */
+ if (first > last)
+ return 0;
+
+ /* Just enough room? */
+ if (first == last)
+ return first;
+
+ slots = ((last - first) >> PAGE_SHIFT) + 1;
+
+ offset = get_random_int() % slots;
+
+ addr = first + (offset << PAGE_SHIFT);
+
+ return addr;
+}
+
+static struct page *signal_page;
+extern struct page *get_signal_page(void);
+
+static const struct vm_special_mapping sigpage_mapping = {
+ .name = "[sigpage]",
+ .pages = &signal_page,
+};
+
+int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+{
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ unsigned long npages;
+ unsigned long addr;
+ unsigned long hint;
+ int ret = 0;
+
+ if (!signal_page)
+ signal_page = get_signal_page();
+ if (!signal_page)
+ return -ENOMEM;
+
+ npages = 1; /* for sigpage */
+ npages += vdso_total_pages;
+
+ down_write(&mm->mmap_sem);
+ hint = sigpage_addr(mm, npages);
+ addr = get_unmapped_area(NULL, hint, npages << PAGE_SHIFT, 0, 0);
+ if (IS_ERR_VALUE(addr)) {
+ ret = addr;
+ goto up_fail;
+ }
+
+ vma = _install_special_mapping(mm, addr, PAGE_SIZE,
+ VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
+ &sigpage_mapping);
+
+ if (IS_ERR(vma)) {
+ ret = PTR_ERR(vma);
+ goto up_fail;
+ }
+
+ mm->context.sigpage = addr;
+
+ /* Unlike the sigpage, failure to install the vdso is unlikely
+ * to be fatal to the process, so no error check needed
+ * here.
+ */
+ arm_install_vdso(mm, addr + PAGE_SIZE);
+
+ up_fail:
+ up_write(&mm->mmap_sem);
+ return ret;
+}
+#endif
diff --git a/arch/arm/kernel/psci-call.S b/arch/arm/kernel/psci-call.S
new file mode 100644
index 000000000..a78e9e1e2
--- /dev/null
+++ b/arch/arm/kernel/psci-call.S
@@ -0,0 +1,31 @@
+/*
+ * This program is free software; you can 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.
+ *
+ * Copyright (C) 2015 ARM Limited
+ *
+ * Author: Mark Rutland <mark.rutland@arm.com>
+ */
+
+#include <linux/linkage.h>
+
+#include <asm/opcodes-sec.h>
+#include <asm/opcodes-virt.h>
+
+/* int __invoke_psci_fn_hvc(u32 function_id, u32 arg0, u32 arg1, u32 arg2) */
+ENTRY(__invoke_psci_fn_hvc)
+ __HVC(0)
+ bx lr
+ENDPROC(__invoke_psci_fn_hvc)
+
+/* int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1, u32 arg2) */
+ENTRY(__invoke_psci_fn_smc)
+ __SMC(0)
+ bx lr
+ENDPROC(__invoke_psci_fn_smc)
diff --git a/arch/arm/kernel/psci.c b/arch/arm/kernel/psci.c
new file mode 100644
index 000000000..f90fdf4ce
--- /dev/null
+++ b/arch/arm/kernel/psci.c
@@ -0,0 +1,299 @@
+/*
+ * This program is free software; you can 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.
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ */
+
+#define pr_fmt(fmt) "psci: " fmt
+
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/reboot.h>
+#include <linux/pm.h>
+#include <uapi/linux/psci.h>
+
+#include <asm/compiler.h>
+#include <asm/errno.h>
+#include <asm/psci.h>
+#include <asm/system_misc.h>
+
+struct psci_operations psci_ops;
+
+static int (*invoke_psci_fn)(u32, u32, u32, u32);
+typedef int (*psci_initcall_t)(const struct device_node *);
+
+asmlinkage int __invoke_psci_fn_hvc(u32, u32, u32, u32);
+asmlinkage int __invoke_psci_fn_smc(u32, u32, u32, u32);
+
+enum psci_function {
+ PSCI_FN_CPU_SUSPEND,
+ PSCI_FN_CPU_ON,
+ PSCI_FN_CPU_OFF,
+ PSCI_FN_MIGRATE,
+ PSCI_FN_AFFINITY_INFO,
+ PSCI_FN_MIGRATE_INFO_TYPE,
+ PSCI_FN_MAX,
+};
+
+static u32 psci_function_id[PSCI_FN_MAX];
+
+static int psci_to_linux_errno(int errno)
+{
+ switch (errno) {
+ case PSCI_RET_SUCCESS:
+ return 0;
+ case PSCI_RET_NOT_SUPPORTED:
+ return -EOPNOTSUPP;
+ case PSCI_RET_INVALID_PARAMS:
+ return -EINVAL;
+ case PSCI_RET_DENIED:
+ return -EPERM;
+ };
+
+ return -EINVAL;
+}
+
+static u32 psci_power_state_pack(struct psci_power_state state)
+{
+ return ((state.id << PSCI_0_2_POWER_STATE_ID_SHIFT)
+ & PSCI_0_2_POWER_STATE_ID_MASK) |
+ ((state.type << PSCI_0_2_POWER_STATE_TYPE_SHIFT)
+ & PSCI_0_2_POWER_STATE_TYPE_MASK) |
+ ((state.affinity_level << PSCI_0_2_POWER_STATE_AFFL_SHIFT)
+ & PSCI_0_2_POWER_STATE_AFFL_MASK);
+}
+
+static int psci_get_version(void)
+{
+ int err;
+
+ err = invoke_psci_fn(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0);
+ return err;
+}
+
+static int psci_cpu_suspend(struct psci_power_state state,
+ unsigned long entry_point)
+{
+ int err;
+ u32 fn, power_state;
+
+ fn = psci_function_id[PSCI_FN_CPU_SUSPEND];
+ power_state = psci_power_state_pack(state);
+ err = invoke_psci_fn(fn, power_state, entry_point, 0);
+ return psci_to_linux_errno(err);
+}
+
+static int psci_cpu_off(struct psci_power_state state)
+{
+ int err;
+ u32 fn, power_state;
+
+ fn = psci_function_id[PSCI_FN_CPU_OFF];
+ power_state = psci_power_state_pack(state);
+ err = invoke_psci_fn(fn, power_state, 0, 0);
+ return psci_to_linux_errno(err);
+}
+
+static int psci_cpu_on(unsigned long cpuid, unsigned long entry_point)
+{
+ int err;
+ u32 fn;
+
+ fn = psci_function_id[PSCI_FN_CPU_ON];
+ err = invoke_psci_fn(fn, cpuid, entry_point, 0);
+ return psci_to_linux_errno(err);
+}
+
+static int psci_migrate(unsigned long cpuid)
+{
+ int err;
+ u32 fn;
+
+ fn = psci_function_id[PSCI_FN_MIGRATE];
+ err = invoke_psci_fn(fn, cpuid, 0, 0);
+ return psci_to_linux_errno(err);
+}
+
+static int psci_affinity_info(unsigned long target_affinity,
+ unsigned long lowest_affinity_level)
+{
+ int err;
+ u32 fn;
+
+ fn = psci_function_id[PSCI_FN_AFFINITY_INFO];
+ err = invoke_psci_fn(fn, target_affinity, lowest_affinity_level, 0);
+ return err;
+}
+
+static int psci_migrate_info_type(void)
+{
+ int err;
+ u32 fn;
+
+ fn = psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE];
+ err = invoke_psci_fn(fn, 0, 0, 0);
+ return err;
+}
+
+static int get_set_conduit_method(struct device_node *np)
+{
+ const char *method;
+
+ pr_info("probing for conduit method from DT.\n");
+
+ if (of_property_read_string(np, "method", &method)) {
+ pr_warn("missing \"method\" property\n");
+ return -ENXIO;
+ }
+
+ if (!strcmp("hvc", method)) {
+ invoke_psci_fn = __invoke_psci_fn_hvc;
+ } else if (!strcmp("smc", method)) {
+ invoke_psci_fn = __invoke_psci_fn_smc;
+ } else {
+ pr_warn("invalid \"method\" property: %s\n", method);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void psci_sys_reset(enum reboot_mode reboot_mode, const char *cmd)
+{
+ invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
+}
+
+static void psci_sys_poweroff(void)
+{
+ invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
+}
+
+/*
+ * PSCI Function IDs for v0.2+ are well defined so use
+ * standard values.
+ */
+static int psci_0_2_init(struct device_node *np)
+{
+ int err, ver;
+
+ err = get_set_conduit_method(np);
+
+ if (err)
+ goto out_put_node;
+
+ ver = psci_get_version();
+
+ if (ver == PSCI_RET_NOT_SUPPORTED) {
+ /* PSCI v0.2 mandates implementation of PSCI_ID_VERSION. */
+ pr_err("PSCI firmware does not comply with the v0.2 spec.\n");
+ err = -EOPNOTSUPP;
+ goto out_put_node;
+ } else {
+ pr_info("PSCIv%d.%d detected in firmware.\n",
+ PSCI_VERSION_MAJOR(ver),
+ PSCI_VERSION_MINOR(ver));
+
+ if (PSCI_VERSION_MAJOR(ver) == 0 &&
+ PSCI_VERSION_MINOR(ver) < 2) {
+ err = -EINVAL;
+ pr_err("Conflicting PSCI version detected.\n");
+ goto out_put_node;
+ }
+ }
+
+ pr_info("Using standard PSCI v0.2 function IDs\n");
+ psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN_CPU_SUSPEND;
+ psci_ops.cpu_suspend = psci_cpu_suspend;
+
+ psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
+ psci_ops.cpu_off = psci_cpu_off;
+
+ psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN_CPU_ON;
+ psci_ops.cpu_on = psci_cpu_on;
+
+ psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN_MIGRATE;
+ psci_ops.migrate = psci_migrate;
+
+ psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN_AFFINITY_INFO;
+ psci_ops.affinity_info = psci_affinity_info;
+
+ psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
+ PSCI_0_2_FN_MIGRATE_INFO_TYPE;
+ psci_ops.migrate_info_type = psci_migrate_info_type;
+
+ arm_pm_restart = psci_sys_reset;
+
+ pm_power_off = psci_sys_poweroff;
+
+out_put_node:
+ of_node_put(np);
+ return err;
+}
+
+/*
+ * PSCI < v0.2 get PSCI Function IDs via DT.
+ */
+static int psci_0_1_init(struct device_node *np)
+{
+ u32 id;
+ int err;
+
+ err = get_set_conduit_method(np);
+
+ if (err)
+ goto out_put_node;
+
+ pr_info("Using PSCI v0.1 Function IDs from DT\n");
+
+ if (!of_property_read_u32(np, "cpu_suspend", &id)) {
+ psci_function_id[PSCI_FN_CPU_SUSPEND] = id;
+ psci_ops.cpu_suspend = psci_cpu_suspend;
+ }
+
+ if (!of_property_read_u32(np, "cpu_off", &id)) {
+ psci_function_id[PSCI_FN_CPU_OFF] = id;
+ psci_ops.cpu_off = psci_cpu_off;
+ }
+
+ if (!of_property_read_u32(np, "cpu_on", &id)) {
+ psci_function_id[PSCI_FN_CPU_ON] = id;
+ psci_ops.cpu_on = psci_cpu_on;
+ }
+
+ if (!of_property_read_u32(np, "migrate", &id)) {
+ psci_function_id[PSCI_FN_MIGRATE] = id;
+ psci_ops.migrate = psci_migrate;
+ }
+
+out_put_node:
+ of_node_put(np);
+ return err;
+}
+
+static const struct of_device_id psci_of_match[] __initconst = {
+ { .compatible = "arm,psci", .data = psci_0_1_init},
+ { .compatible = "arm,psci-0.2", .data = psci_0_2_init},
+ {},
+};
+
+int __init psci_init(void)
+{
+ struct device_node *np;
+ const struct of_device_id *matched_np;
+ psci_initcall_t init_fn;
+
+ np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
+ if (!np)
+ return -ENODEV;
+
+ init_fn = (psci_initcall_t)matched_np->data;
+ return init_fn(np);
+}
diff --git a/arch/arm/kernel/psci_smp.c b/arch/arm/kernel/psci_smp.c
new file mode 100644
index 000000000..28a1db4da
--- /dev/null
+++ b/arch/arm/kernel/psci_smp.c
@@ -0,0 +1,115 @@
+/*
+ * This program is free software; you can 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.
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ */
+
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/of.h>
+#include <linux/delay.h>
+#include <uapi/linux/psci.h>
+
+#include <asm/psci.h>
+#include <asm/smp_plat.h>
+
+/*
+ * psci_smp assumes that the following is true about PSCI:
+ *
+ * cpu_suspend Suspend the execution on a CPU
+ * @state we don't currently describe affinity levels, so just pass 0.
+ * @entry_point the first instruction to be executed on return
+ * returns 0 success, < 0 on failure
+ *
+ * cpu_off Power down a CPU
+ * @state we don't currently describe affinity levels, so just pass 0.
+ * no return on successful call
+ *
+ * cpu_on Power up a CPU
+ * @cpuid cpuid of target CPU, as from MPIDR
+ * @entry_point the first instruction to be executed on return
+ * returns 0 success, < 0 on failure
+ *
+ * migrate Migrate the context to a different CPU
+ * @cpuid cpuid of target CPU, as from MPIDR
+ * returns 0 success, < 0 on failure
+ *
+ */
+
+extern void secondary_startup(void);
+
+static int psci_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ if (psci_ops.cpu_on)
+ return psci_ops.cpu_on(cpu_logical_map(cpu),
+ __pa(secondary_startup));
+ return -ENODEV;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+void __ref psci_cpu_die(unsigned int cpu)
+{
+ const struct psci_power_state ps = {
+ .type = PSCI_POWER_STATE_TYPE_POWER_DOWN,
+ };
+
+ if (psci_ops.cpu_off)
+ psci_ops.cpu_off(ps);
+
+ /* We should never return */
+ panic("psci: cpu %d failed to shutdown\n", cpu);
+}
+
+int __ref psci_cpu_kill(unsigned int cpu)
+{
+ int err, i;
+
+ if (!psci_ops.affinity_info)
+ return 1;
+ /*
+ * cpu_kill could race with cpu_die and we can
+ * potentially end up declaring this cpu undead
+ * while it is dying. So, try again a few times.
+ */
+
+ for (i = 0; i < 10; i++) {
+ err = psci_ops.affinity_info(cpu_logical_map(cpu), 0);
+ if (err == PSCI_0_2_AFFINITY_LEVEL_OFF) {
+ pr_info("CPU%d killed.\n", cpu);
+ return 1;
+ }
+
+ msleep(10);
+ pr_info("Retrying again to check for CPU kill\n");
+ }
+
+ pr_warn("CPU%d may not have shut down cleanly (AFFINITY_INFO reports %d)\n",
+ cpu, err);
+ /* Make platform_cpu_kill() fail. */
+ return 0;
+}
+
+#endif
+
+bool __init psci_smp_available(void)
+{
+ /* is cpu_on available at least? */
+ return (psci_ops.cpu_on != NULL);
+}
+
+struct smp_operations __initdata psci_smp_ops = {
+ .smp_boot_secondary = psci_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = psci_cpu_die,
+ .cpu_kill = psci_cpu_kill,
+#endif
+};
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
new file mode 100644
index 000000000..ef9119f74
--- /dev/null
+++ b/arch/arm/kernel/ptrace.c
@@ -0,0 +1,977 @@
+/*
+ * 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/elf.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 <linux/audit.h>
+#include <linux/tracehook.h>
+#include <linux/unistd.h>
+
+#include <asm/pgtable.h>
+#include <asm/traps.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/syscalls.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 struct undef_hook thumb2_break_hook = {
+ .instr_mask = 0xffffffff,
+ .instr_val = 0xf7f0a000,
+ .cpsr_mask = PSR_T_BIT,
+ .cpsr_val = PSR_T_BIT,
+ .fn = 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)
+ 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);
+ else if (off >= sizeof(struct user))
+ return -EIO;
+
+ 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,
+ 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, NULL,
+ 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[0],
+ 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:
+ ret = ptrace_gethbpregs(child, addr,
+ (unsigned long __user *)data);
+ break;
+ case PTRACE_SETHBPREGS:
+ ret = ptrace_sethbpregs(child, addr,
+ (unsigned long __user *)data);
+ break;
+#endif
+
+ default:
+ ret = ptrace_request(child, request, addr, data);
+ break;
+ }
+
+ return ret;
+}
+
+enum ptrace_syscall_dir {
+ PTRACE_SYSCALL_ENTER = 0,
+ PTRACE_SYSCALL_EXIT,
+};
+
+static void tracehook_report_syscall(struct pt_regs *regs,
+ enum ptrace_syscall_dir dir)
+{
+ unsigned long ip;
+
+ /*
+ * IP is used to denote syscall entry/exit:
+ * IP = 0 -> entry, =1 -> exit
+ */
+ ip = regs->ARM_ip;
+ regs->ARM_ip = dir;
+
+ if (dir == PTRACE_SYSCALL_EXIT)
+ tracehook_report_syscall_exit(regs, 0);
+ else if (tracehook_report_syscall_entry(regs))
+ current_thread_info()->syscall = -1;
+
+ regs->ARM_ip = ip;
+}
+
+asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
+{
+ current_thread_info()->syscall = scno;
+
+ /* Do the secure computing check first; failures should be fast. */
+#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
+ if (secure_computing() == -1)
+ return -1;
+#else
+ /* XXX: remove this once OABI gets fixed */
+ secure_computing_strict(scno);
+#endif
+
+ if (test_thread_flag(TIF_SYSCALL_TRACE))
+ tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+
+ scno = current_thread_info()->syscall;
+
+ if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+ trace_sys_enter(regs, scno);
+
+ audit_syscall_entry(scno, regs->ARM_r0, regs->ARM_r1, regs->ARM_r2,
+ regs->ARM_r3);
+
+ return scno;
+}
+
+asmlinkage void syscall_trace_exit(struct pt_regs *regs)
+{
+ /*
+ * Audit the syscall before anything else, as a debugger may
+ * come in and change the current registers.
+ */
+ audit_syscall_exit(regs);
+
+ /*
+ * Note that we haven't updated the ->syscall field for the
+ * current thread. This isn't a problem because it will have
+ * been set on syscall entry and there hasn't been an opportunity
+ * for a PTRACE_SET_SYSCALL since then.
+ */
+ if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+ trace_sys_exit(regs, regs_return_value(regs));
+
+ if (test_thread_flag(TIF_SYSCALL_TRACE))
+ tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
+}
diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c
new file mode 100644
index 000000000..1a4d23279
--- /dev/null
+++ b/arch/arm/kernel/reboot.c
@@ -0,0 +1,155 @@
+/*
+ * 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 <linux/cpu.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+
+#include <asm/cacheflush.h>
+#include <asm/idmap.h>
+
+#include "reboot.h"
+
+typedef void (*phys_reset_t)(unsigned long);
+
+/*
+ * Function pointers to optional machine specific functions
+ */
+void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
+
+/*
+ * A temporary stack to use for CPU reset. This is static so that we
+ * don't clobber it with the identity mapping. When running with this
+ * stack, any references to the current task *will not work* so you
+ * should really do as little as possible before jumping to your reset
+ * code.
+ */
+static u64 soft_restart_stack[16];
+
+static void __soft_restart(void *addr)
+{
+ phys_reset_t phys_reset;
+
+ /* Take out a flat memory mapping. */
+ setup_mm_for_reboot();
+
+ /* 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();
+
+ /* Switch to the identity mapping. */
+ phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset);
+ phys_reset((unsigned long)addr);
+
+ /* Should never get here. */
+ BUG();
+}
+
+void _soft_restart(unsigned long addr, bool disable_l2)
+{
+ u64 *stack = soft_restart_stack + ARRAY_SIZE(soft_restart_stack);
+
+ /* Disable interrupts first */
+ raw_local_irq_disable();
+ local_fiq_disable();
+
+ /* Disable the L2 if we're the last man standing. */
+ if (disable_l2)
+ outer_disable();
+
+ /* Change to the new stack and continue with the reset. */
+ call_with_stack(__soft_restart, (void *)addr, (void *)stack);
+
+ /* Should never get here. */
+ BUG();
+}
+
+void soft_restart(unsigned long addr)
+{
+ _soft_restart(addr, num_online_cpus() == 1);
+}
+
+/*
+ * Called by kexec, immediately prior to machine_kexec().
+ *
+ * This must completely disable all secondary CPUs; simply causing those CPUs
+ * to execute e.g. a RAM-based pin loop is not sufficient. This allows the
+ * kexec'd kernel to use any and all RAM as it sees fit, without having to
+ * avoid any code or data used by any SW CPU pin loop. The CPU hotplug
+ * functionality embodied in disable_nonboot_cpus() to achieve this.
+ */
+void machine_shutdown(void)
+{
+ disable_nonboot_cpus();
+}
+
+/*
+ * Halting simply requires that the secondary CPUs stop performing any
+ * activity (executing tasks, handling interrupts). smp_send_stop()
+ * achieves this.
+ */
+void machine_halt(void)
+{
+ local_irq_disable();
+ smp_send_stop();
+
+ local_irq_disable();
+ while (1);
+}
+
+/*
+ * Power-off simply requires that the secondary CPUs stop performing any
+ * activity (executing tasks, handling interrupts). smp_send_stop()
+ * achieves this. When the system power is turned off, it will take all CPUs
+ * with it.
+ */
+void machine_power_off(void)
+{
+ local_irq_disable();
+ smp_send_stop();
+
+ if (pm_power_off)
+ pm_power_off();
+}
+
+/*
+ * Restart requires that the secondary CPUs stop performing any activity
+ * while the primary CPU resets the system. Systems with a single CPU can
+ * use soft_restart() as their machine descriptor's .restart hook, since that
+ * will cause the only available CPU to reset. Systems with multiple CPUs must
+ * provide a HW restart implementation, to ensure that all CPUs reset at once.
+ * This is required so that any code running after reset on the primary CPU
+ * doesn't have to co-ordinate with other CPUs to ensure they aren't still
+ * executing pre-reset code, and using RAM that the primary CPU's code wishes
+ * to use. Implementing such co-ordination would be essentially impossible.
+ */
+void machine_restart(char *cmd)
+{
+ local_irq_disable();
+ smp_send_stop();
+
+ if (arm_pm_restart)
+ arm_pm_restart(reboot_mode, cmd);
+ else
+ do_kernel_restart(cmd);
+
+ /* Give a grace period for failure to restart of 1s */
+ mdelay(1000);
+
+ /* Whoops - the platform was unable to reboot. Tell the user! */
+ printk("Reboot failed -- System halted\n");
+ local_irq_disable();
+ while (1);
+}
diff --git a/arch/arm/kernel/reboot.h b/arch/arm/kernel/reboot.h
new file mode 100644
index 000000000..bf7a0b1f0
--- /dev/null
+++ b/arch/arm/kernel/reboot.h
@@ -0,0 +1,7 @@
+#ifndef REBOOT_H
+#define REBOOT_H
+
+extern void call_with_stack(void (*fn)(void *), void *arg, void *sp);
+extern void _soft_restart(unsigned long addr, bool disable_l2);
+
+#endif
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
new file mode 100644
index 000000000..35e72585e
--- /dev/null
+++ b/arch/arm/kernel/relocate_kernel.S
@@ -0,0 +1,93 @@
+/*
+ * relocate_kernel.S - put the kernel image in place to boot
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/kexec.h>
+
+ .align 3 /* not needed for this code, but keeps fncpy() happy */
+
+ENTRY(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
+ ARM( ret lr )
+ THUMB( bx 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
+
+ENDPROC(relocate_new_kernel)
+
+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 000000000..36ed35073
--- /dev/null
+++ b/arch/arm/kernel/return_address.c
@@ -0,0 +1,61 @@
+/*
+ * 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/export.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->pc;
+
+ return 1;
+ } else {
+ --data->level;
+ return 0;
+ }
+}
+
+void *return_address(unsigned int level)
+{
+ struct return_address_data data;
+ struct stackframe frame;
+
+ data.level = level + 2;
+ data.addr = NULL;
+
+ frame.fp = (unsigned long)__builtin_frame_address(0);
+ frame.sp = current_stack_pointer;
+ 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;
+}
+
+#endif /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) */
+
+EXPORT_SYMBOL_GPL(return_address);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
new file mode 100644
index 000000000..6c777e908
--- /dev/null
+++ b/arch/arm/kernel/setup.c
@@ -0,0 +1,1138 @@
+/*
+ * 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/export.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/of_iommu.h>
+#include <linux/of_platform.h>
+#include <linux/init.h>
+#include <linux/kexec.h>
+#include <linux/of_fdt.h>
+#include <linux/cpu.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+#include <linux/proc_fs.h>
+#include <linux/memblock.h>
+#include <linux/bug.h>
+#include <linux/compiler.h>
+#include <linux/sort.h>
+
+#include <asm/unified.h>
+#include <asm/cp15.h>
+#include <asm/cpu.h>
+#include <asm/cputype.h>
+#include <asm/elf.h>
+#include <asm/procinfo.h>
+#include <asm/psci.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/system_info.h>
+#include <asm/system_misc.h>
+#include <asm/traps.h>
+#include <asm/unwind.h>
+#include <asm/memblock.h>
+#include <asm/virt.h>
+
+#include "atags.h"
+
+
+#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 init_default_cache_policy(unsigned long);
+extern void paging_init(const struct machine_desc *desc);
+extern void early_paging_init(const struct machine_desc *,
+ struct proc_info_list *);
+extern void sanity_check_meminfo(void);
+extern enum reboot_mode reboot_mode;
+extern void setup_dma_zone(const struct machine_desc *desc);
+
+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);
+
+unsigned int elf_hwcap2 __read_mostly;
+EXPORT_SYMBOL(elf_hwcap2);
+
+
+#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
+
+/*
+ * Cached cpu_architecture() result for use by assembler code.
+ * C code should use the cpu_architecture() function instead of accessing this
+ * variable directly.
+ */
+int __cpu_architecture __read_mostly = CPU_ARCH_UNKNOWN;
+
+struct stack {
+ u32 irq[3];
+ u32 abt[3];
+ u32 und[3];
+ u32 fiq[3];
+} ____cacheline_aligned;
+
+#ifndef CONFIG_CPU_V7M
+static struct stack stacks[NR_CPUS];
+#endif
+
+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];
+const struct machine_desc *machine_desc __initdata;
+
+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 code",
+ .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",
+ "7M",
+ "?(12)",
+ "?(13)",
+ "?(14)",
+ "?(15)",
+ "?(16)",
+ "?(17)",
+};
+
+#ifdef CONFIG_CPU_V7M
+static int __get_cpu_architecture(void)
+{
+ return CPU_ARCH_ARMv7M;
+}
+#else
+static int __get_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) {
+ /* Revised CPUID format. Read the Memory Model Feature
+ * Register 0 and check for VMSAv7 or PMSAv7 */
+ unsigned int mmfr0 = read_cpuid_ext(CPUID_EXT_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;
+}
+#endif
+
+int __pure cpu_architecture(void)
+{
+ BUG_ON(__cpu_architecture == CPU_ARCH_UNKNOWN);
+
+ return __cpu_architecture;
+}
+
+static int cpu_has_aliasing_icache(unsigned int arch)
+{
+ int aliasing_icache;
+ unsigned int id_reg, num_sets, line_size;
+
+ /* PIPT caches never alias. */
+ if (icache_is_pipt())
+ return 0;
+
+ /* 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 arch = cpu_architecture();
+
+ if (arch == CPU_ARCH_ARMv7M) {
+ cacheid = 0;
+ } else if (arch >= CPU_ARCH_ARMv6) {
+ unsigned int cachetype = read_cpuid_cachetype();
+ if ((cachetype & (7 << 29)) == 4 << 29) {
+ /* ARMv7 register format */
+ arch = CPU_ARCH_ARMv7;
+ cacheid = CACHEID_VIPT_NONALIASING;
+ switch (cachetype & (3 << 14)) {
+ case (1 << 14):
+ cacheid |= CACHEID_ASID_TAGGED;
+ break;
+ case (3 << 14):
+ cacheid |= CACHEID_PIPT;
+ break;
+ }
+ } else {
+ arch = CPU_ARCH_ARMv6;
+ if (cachetype & (1 << 23))
+ cacheid = CACHEID_VIPT_ALIASING;
+ else
+ cacheid = CACHEID_VIPT_NONALIASING;
+ }
+ if (cpu_has_aliasing_icache(arch))
+ cacheid |= CACHEID_VIPT_I_ALIASING;
+ } else {
+ cacheid = CACHEID_VIVT;
+ }
+
+ pr_info("CPU: %s data cache, %s instruction cache\n",
+ cache_is_vivt() ? "VIVT" :
+ cache_is_vipt_aliasing() ? "VIPT aliasing" :
+ cache_is_vipt_nonaliasing() ? "PIPT / VIPT nonaliasing" : "unknown",
+ cache_is_vivt() ? "VIVT" :
+ icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
+ icache_is_vipt_aliasing() ? "VIPT aliasing" :
+ icache_is_pipt() ? "PIPT" :
+ 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 cpuid_init_hwcaps(void)
+{
+ int block;
+ u32 isar5;
+
+ if (cpu_architecture() < CPU_ARCH_ARMv7)
+ return;
+
+ block = cpuid_feature_extract(CPUID_EXT_ISAR0, 24);
+ if (block >= 2)
+ elf_hwcap |= HWCAP_IDIVA;
+ if (block >= 1)
+ elf_hwcap |= HWCAP_IDIVT;
+
+ /* LPAE implies atomic ldrd/strd instructions */
+ block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0);
+ if (block >= 5)
+ elf_hwcap |= HWCAP_LPAE;
+
+ /* check for supported v8 Crypto instructions */
+ isar5 = read_cpuid_ext(CPUID_EXT_ISAR5);
+
+ block = cpuid_feature_extract_field(isar5, 4);
+ if (block >= 2)
+ elf_hwcap2 |= HWCAP2_PMULL;
+ if (block >= 1)
+ elf_hwcap2 |= HWCAP2_AES;
+
+ block = cpuid_feature_extract_field(isar5, 8);
+ if (block >= 1)
+ elf_hwcap2 |= HWCAP2_SHA1;
+
+ block = cpuid_feature_extract_field(isar5, 12);
+ if (block >= 1)
+ elf_hwcap2 |= HWCAP2_SHA2;
+
+ block = cpuid_feature_extract_field(isar5, 16);
+ if (block >= 1)
+ elf_hwcap2 |= HWCAP2_CRC32;
+}
+
+static void __init elf_hwcap_fixup(void)
+{
+ unsigned id = read_cpuid_id();
+
+ /*
+ * HWCAP_TLS is available only on 1136 r1p0 and later,
+ * see also kuser_get_tls_init.
+ */
+ if (read_cpuid_part() == ARM_CPU_PART_ARM1136 &&
+ ((id >> 20) & 3) == 0) {
+ elf_hwcap &= ~HWCAP_TLS;
+ return;
+ }
+
+ /* Verify if CPUID scheme is implemented */
+ if ((id & 0x000f0000) != 0x000f0000)
+ return;
+
+ /*
+ * If the CPU supports LDREX/STREX and LDREXB/STREXB,
+ * avoid advertising SWP; it may not be atomic with
+ * multiprocessing cores.
+ */
+ if (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) > 1 ||
+ (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) == 1 &&
+ cpuid_feature_extract(CPUID_EXT_ISAR3, 20) >= 3))
+ elf_hwcap &= ~HWCAP_SWP;
+}
+
+/*
+ * cpu_init - initialise one CPU.
+ *
+ * cpu_init sets up the per-CPU stacks.
+ */
+void notrace cpu_init(void)
+{
+#ifndef CONFIG_CPU_V7M
+ unsigned int cpu = smp_processor_id();
+ struct stack *stk = &stacks[cpu];
+
+ if (cpu >= NR_CPUS) {
+ pr_crit("CPU%u: bad primary CPU number\n", cpu);
+ BUG();
+ }
+
+ /*
+ * This only works on resume and secondary cores. For booting on the
+ * boot cpu, smp_prepare_boot_cpu is called after percpu area setup.
+ */
+ set_my_cpu_offset(per_cpu_offset(cpu));
+
+ cpu_proc_init();
+
+ /*
+ * 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\n\t"
+ "add r14, %0, %8\n\t"
+ "mov sp, r14\n\t"
+ "msr cpsr_c, %9"
+ :
+ : "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 | FIQ_MODE),
+ "I" (offsetof(struct stack, fiq[0])),
+ PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
+ : "r14");
+#endif
+}
+
+u32 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = MPIDR_INVALID };
+
+void __init smp_setup_processor_id(void)
+{
+ int i;
+ u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;
+ u32 cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+
+ cpu_logical_map(0) = cpu;
+ for (i = 1; i < nr_cpu_ids; ++i)
+ cpu_logical_map(i) = i == cpu ? 0 : i;
+
+ /*
+ * clear __my_cpu_offset on boot CPU to avoid hang caused by
+ * using percpu variable early, for example, lockdep will
+ * access percpu variable inside lock_release
+ */
+ set_my_cpu_offset(0);
+
+ pr_info("Booting Linux on physical CPU 0x%x\n", mpidr);
+}
+
+struct mpidr_hash mpidr_hash;
+#ifdef CONFIG_SMP
+/**
+ * smp_build_mpidr_hash - Pre-compute shifts required at each affinity
+ * level in order to build a linear index from an
+ * MPIDR value. Resulting algorithm is a collision
+ * free hash carried out through shifting and ORing
+ */
+static void __init smp_build_mpidr_hash(void)
+{
+ u32 i, affinity;
+ u32 fs[3], bits[3], ls, mask = 0;
+ /*
+ * Pre-scan the list of MPIDRS and filter out bits that do
+ * not contribute to affinity levels, ie they never toggle.
+ */
+ for_each_possible_cpu(i)
+ mask |= (cpu_logical_map(i) ^ cpu_logical_map(0));
+ pr_debug("mask of set bits 0x%x\n", mask);
+ /*
+ * Find and stash the last and first bit set at all affinity levels to
+ * check how many bits are required to represent them.
+ */
+ for (i = 0; i < 3; i++) {
+ affinity = MPIDR_AFFINITY_LEVEL(mask, i);
+ /*
+ * Find the MSB bit and LSB bits position
+ * to determine how many bits are required
+ * to express the affinity level.
+ */
+ ls = fls(affinity);
+ fs[i] = affinity ? ffs(affinity) - 1 : 0;
+ bits[i] = ls - fs[i];
+ }
+ /*
+ * An index can be created from the MPIDR by isolating the
+ * significant bits at each affinity level and by shifting
+ * them in order to compress the 24 bits values space to a
+ * compressed set of values. This is equivalent to hashing
+ * the MPIDR through shifting and ORing. It is a collision free
+ * hash though not minimal since some levels might contain a number
+ * of CPUs that is not an exact power of 2 and their bit
+ * representation might contain holes, eg MPIDR[7:0] = {0x2, 0x80}.
+ */
+ mpidr_hash.shift_aff[0] = fs[0];
+ mpidr_hash.shift_aff[1] = MPIDR_LEVEL_BITS + fs[1] - bits[0];
+ mpidr_hash.shift_aff[2] = 2*MPIDR_LEVEL_BITS + fs[2] -
+ (bits[1] + bits[0]);
+ mpidr_hash.mask = mask;
+ mpidr_hash.bits = bits[2] + bits[1] + bits[0];
+ pr_debug("MPIDR hash: aff0[%u] aff1[%u] aff2[%u] mask[0x%x] bits[%u]\n",
+ mpidr_hash.shift_aff[0],
+ mpidr_hash.shift_aff[1],
+ mpidr_hash.shift_aff[2],
+ mpidr_hash.mask,
+ mpidr_hash.bits);
+ /*
+ * 4x is an arbitrary value used to warn on a hash table much bigger
+ * than expected on most systems.
+ */
+ if (mpidr_hash_size() > 4 * num_possible_cpus())
+ pr_warn("Large number of MPIDR hash buckets detected\n");
+ sync_cache_w(&mpidr_hash);
+}
+#endif
+
+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) {
+ pr_err("CPU configuration botched (ID %08x), unable to continue.\n",
+ read_cpuid_id());
+ while (1);
+ }
+
+ cpu_name = list->cpu_name;
+ __cpu_architecture = __get_cpu_architecture();
+
+#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
+
+ pr_info("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n",
+ cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
+ proc_arch[cpu_architecture()], get_cr());
+
+ snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c",
+ list->arch_name, ENDIANNESS);
+ snprintf(elf_platform, ELF_PLATFORM_SIZE, "%s%c",
+ list->elf_name, ENDIANNESS);
+ elf_hwcap = list->elf_hwcap;
+
+ cpuid_init_hwcaps();
+
+#ifndef CONFIG_ARM_THUMB
+ elf_hwcap &= ~(HWCAP_THUMB | HWCAP_IDIVT);
+#endif
+#ifdef CONFIG_MMU
+ init_default_cache_policy(list->__cpu_mm_mmu_flags);
+#endif
+ erratum_a15_798181_init();
+
+ elf_hwcap_fixup();
+
+ cacheid_init();
+ cpu_init();
+}
+
+void __init dump_machine_table(void)
+{
+ const 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(u64 start, u64 size)
+{
+ u64 aligned_start;
+
+ /*
+ * Ensure that start/size are aligned to a page boundary.
+ * Size is rounded down, start is rounded up.
+ */
+ aligned_start = PAGE_ALIGN(start);
+ if (aligned_start > start + size)
+ size = 0;
+ else
+ size -= aligned_start - start;
+
+#ifndef CONFIG_ARCH_PHYS_ADDR_T_64BIT
+ if (aligned_start > ULONG_MAX) {
+ pr_crit("Ignoring memory at 0x%08llx outside 32-bit physical address space\n",
+ (long long)start);
+ return -EINVAL;
+ }
+
+ if (aligned_start + size > ULONG_MAX) {
+ pr_crit("Truncating memory at 0x%08llx to fit in 32-bit physical address space\n",
+ (long long)start);
+ /*
+ * To ensure bank->start + bank->size is representable in
+ * 32 bits, we use ULONG_MAX as the upper limit rather than 4GB.
+ * This means we lose a page after masking.
+ */
+ size = ULONG_MAX - aligned_start;
+ }
+#endif
+
+ if (aligned_start < PHYS_OFFSET) {
+ if (aligned_start + size <= PHYS_OFFSET) {
+ pr_info("Ignoring memory below PHYS_OFFSET: 0x%08llx-0x%08llx\n",
+ aligned_start, aligned_start + size);
+ return -EINVAL;
+ }
+
+ pr_info("Ignoring memory below PHYS_OFFSET: 0x%08llx-0x%08llx\n",
+ aligned_start, (u64)PHYS_OFFSET);
+
+ size -= PHYS_OFFSET - aligned_start;
+ aligned_start = PHYS_OFFSET;
+ }
+
+ start = aligned_start;
+ size = size & ~(phys_addr_t)(PAGE_SIZE - 1);
+
+ /*
+ * Check whether this memory region has non-zero size or
+ * invalid node number.
+ */
+ if (size == 0)
+ return -EINVAL;
+
+ memblock_add(start, size);
+ 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;
+ u64 size;
+ u64 start;
+ char *endp;
+
+ /*
+ * If the user specifies memory size, we
+ * blow away any automatically generated
+ * size.
+ */
+ if (usermem == 0) {
+ usermem = 1;
+ memblock_remove(memblock_start_of_DRAM(),
+ memblock_end_of_DRAM() - memblock_start_of_DRAM());
+ }
+
+ 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 request_standard_resources(const 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 = memblock_virt_alloc(sizeof(*res), 0);
+ 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);
+}
+
+#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
+};
+#endif
+
+static int __init customize_machine(void)
+{
+ /*
+ * customizes platform devices, or adds new ones
+ * On DT based machines, we fall back to populating the
+ * machine from the device tree, if no callback is provided,
+ * otherwise we would always need an init_machine callback.
+ */
+ of_iommu_init();
+ if (machine_desc->init_machine)
+ machine_desc->init_machine();
+#ifdef CONFIG_OF
+ else
+ of_platform_populate(NULL, of_default_bus_match_table,
+ NULL, NULL);
+#endif
+ return 0;
+}
+arch_initcall(customize_machine);
+
+static int __init init_machine_late(void)
+{
+ if (machine_desc->init_late)
+ machine_desc->init_late();
+ return 0;
+}
+late_initcall(init_machine_late);
+
+#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 = memblock_reserve(crash_base, crash_size);
+ if (ret < 0) {
+ pr_warn("crashkernel reservation failed - memory is in use (0x%lx)\n",
+ (unsigned long)crash_base);
+ return;
+ }
+
+ pr_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 */
+
+void __init hyp_mode_check(void)
+{
+#ifdef CONFIG_ARM_VIRT_EXT
+ sync_boot_mode();
+
+ if (is_hyp_mode_available()) {
+ pr_info("CPU: All CPU(s) started in HYP mode.\n");
+ pr_info("CPU: Virtualization extensions available.\n");
+ } else if (is_hyp_mode_mismatched()) {
+ pr_warn("CPU: WARNING: CPU(s) started in wrong/inconsistent modes (primary CPU mode 0x%x)\n",
+ __boot_cpu_mode & MODE_MASK);
+ pr_warn("CPU: This may indicate a broken bootloader or firmware.\n");
+ } else
+ pr_info("CPU: All CPU(s) started in SVC mode.\n");
+#endif
+}
+
+void __init setup_arch(char **cmdline_p)
+{
+ const struct machine_desc *mdesc;
+
+ setup_processor();
+ mdesc = setup_machine_fdt(__atags_pointer);
+ if (!mdesc)
+ mdesc = setup_machine_tags(__atags_pointer, __machine_arch_type);
+ machine_desc = mdesc;
+ machine_name = mdesc->name;
+ dump_stack_set_arch_desc("%s", mdesc->name);
+
+ if (mdesc->reboot_mode != REBOOT_HARD)
+ reboot_mode = mdesc->reboot_mode;
+
+ 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();
+
+ early_paging_init(mdesc, lookup_processor_type(read_cpuid_id()));
+ setup_dma_zone(mdesc);
+ sanity_check_meminfo();
+ arm_memblock_init(mdesc);
+
+ paging_init(mdesc);
+ request_standard_resources(mdesc);
+
+ if (mdesc->restart)
+ arm_pm_restart = mdesc->restart;
+
+ unflatten_device_tree();
+
+ arm_dt_init_cpu_maps();
+ psci_init();
+#ifdef CONFIG_SMP
+ if (is_smp()) {
+ if (!mdesc->smp_init || !mdesc->smp_init()) {
+ if (psci_smp_available())
+ smp_set_ops(&psci_smp_ops);
+ else if (mdesc->smp)
+ smp_set_ops(mdesc->smp);
+ }
+ smp_init_cpus();
+ smp_build_mpidr_hash();
+ }
+#endif
+
+ if (!is_smp())
+ hyp_mode_check();
+
+ reserve_crashkernel();
+
+#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
+
+ 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",
+ "tls",
+ "vfpv4",
+ "idiva",
+ "idivt",
+ "vfpd32",
+ "lpae",
+ "evtstrm",
+ NULL
+};
+
+static const char *hwcap2_str[] = {
+ "aes",
+ "pmull",
+ "sha1",
+ "sha2",
+ "crc32",
+ NULL
+};
+
+static int c_show(struct seq_file *m, void *v)
+{
+ int i, j;
+ u32 cpuid;
+
+ 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);
+ cpuid = is_smp() ? per_cpu(cpu_data, i).cpuid : read_cpuid_id();
+ seq_printf(m, "model name\t: %s rev %d (%s)\n",
+ cpu_name, cpuid & 15, elf_platform);
+
+#if defined(CONFIG_SMP)
+ seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
+ per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
+ (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
+#else
+ 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 (j = 0; hwcap_str[j]; j++)
+ if (elf_hwcap & (1 << j))
+ seq_printf(m, "%s ", hwcap_str[j]);
+
+ for (j = 0; hwcap2_str[j]; j++)
+ if (elf_hwcap2 & (1 << j))
+ seq_printf(m, "%s ", hwcap2_str[j]);
+
+ seq_printf(m, "\nCPU implementer\t: 0x%02x\n", cpuid >> 24);
+ seq_printf(m, "CPU architecture: %s\n",
+ proc_arch[cpu_architecture()]);
+
+ if ((cpuid & 0x0008f000) == 0x00000000) {
+ /* pre-ARM7 */
+ seq_printf(m, "CPU part\t: %07x\n", cpuid >> 4);
+ } else {
+ if ((cpuid & 0x0008f000) == 0x00007000) {
+ /* ARM7 */
+ seq_printf(m, "CPU variant\t: 0x%02x\n",
+ (cpuid >> 16) & 127);
+ } else {
+ /* post-ARM7 */
+ seq_printf(m, "CPU variant\t: 0x%x\n",
+ (cpuid >> 20) & 15);
+ }
+ seq_printf(m, "CPU part\t: 0x%03x\n",
+ (cpuid >> 4) & 0xfff);
+ }
+ seq_printf(m, "CPU revision\t: %d\n\n", cpuid & 15);
+ }
+
+ 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 000000000..423663e23
--- /dev/null
+++ b/arch/arm/kernel/signal.c
@@ -0,0 +1,624 @@
+/*
+ * 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/random.h>
+#include <linux/signal.h>
+#include <linux/personality.h>
+#include <linux/uaccess.h>
+#include <linux/tracehook.h>
+#include <linux/uprobes.h>
+
+#include <asm/elf.h>
+#include <asm/cacheflush.h>
+#include <asm/traps.h>
+#include <asm/ucontext.h>
+#include <asm/unistd.h>
+#include <asm/vfp.h>
+
+extern const unsigned long sigreturn_codes[7];
+
+static unsigned long signal_return_offset;
+
+#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)
+{
+ const unsigned long magic = VFP_MAGIC;
+ const unsigned long size = VFP_STORAGE_SIZE;
+ int err = 0;
+
+ __put_user_error(magic, &frame->magic, err);
+ __put_user_error(size, &frame->size, err);
+
+ if (err)
+ return -EFAULT;
+
+ return vfp_preserve_user_clear_hwstate(&frame->ufp, &frame->ufp_exc);
+}
+
+static int restore_vfp_context(struct vfp_sigframe __user *frame)
+{
+ unsigned long magic;
+ unsigned long size;
+ 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;
+
+ return vfp_restore_user_hwstate(&frame->ufp, &frame->ufp_exc);
+}
+
+#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)
+ set_current_blocked(&set);
+
+ __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->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->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 (restore_altstack(&frame->sig.uc.uc_stack))
+ 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 ksignal *ksig, struct pt_regs *regs, int framesize)
+{
+ unsigned long sp = sigsp(regs->ARM_sp, ksig);
+ void __user *frame;
+
+ /*
+ * 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 ksignal *ksig,
+ unsigned long __user *rc, void __user *frame)
+{
+ unsigned long handler = (unsigned long)ksig->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 (ksig->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 __LINUX_ARM_ARCH__ >= 7
+ /*
+ * Clear the If-Then Thumb-2 execution state
+ * ARM spec requires this to be all 000s in ARM mode
+ * Snapdragon S4/Krait misbehaves on a Thumb=>ARM
+ * signal transition without this.
+ */
+ cpsr &= ~PSR_IT_MASK;
+#endif
+
+ if (thumb) {
+ cpsr |= PSR_T_BIT;
+ } else
+ cpsr &= ~PSR_T_BIT;
+ }
+#endif
+
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+ retcode = (unsigned long)ksig->ka.sa.sa_restorer;
+ } else {
+ unsigned int idx = thumb << 1;
+
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+ idx += 3;
+
+ /*
+ * Put the sigreturn code on the stack no matter which return
+ * mechanism we use in order to remain ABI compliant
+ */
+ if (__put_user(sigreturn_codes[idx], rc) ||
+ __put_user(sigreturn_codes[idx+1], rc+1))
+ return 1;
+
+#ifdef CONFIG_MMU
+ if (cpsr & MODE32_BIT) {
+ struct mm_struct *mm = current->mm;
+
+ /*
+ * 32-bit code can use the signal return page
+ * except when the MPU has protected the vectors
+ * page from PL0
+ */
+ retcode = mm->context.sigpage + signal_return_offset +
+ (idx << 2) + thumb;
+ } else
+#endif
+ {
+ /*
+ * 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 = ksig->sig;
+ regs->ARM_sp = (unsigned long)frame;
+ regs->ARM_lr = retcode;
+ regs->ARM_pc = handler;
+ regs->ARM_cpsr = cpsr;
+
+ return 0;
+}
+
+static int
+setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
+{
+ struct sigframe __user *frame = get_sigframe(ksig, 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, ksig, frame->retcode, frame);
+
+ return err;
+}
+
+static int
+setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
+{
+ struct rt_sigframe __user *frame = get_sigframe(ksig, regs, sizeof(*frame));
+ int err = 0;
+
+ if (!frame)
+ return 1;
+
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
+
+ __put_user_error(0, &frame->sig.uc.uc_flags, err);
+ __put_user_error(NULL, &frame->sig.uc.uc_link, err);
+
+ err |= __save_altstack(&frame->sig.uc.uc_stack, regs->ARM_sp);
+ err |= setup_sigframe(&frame->sig, regs, set);
+ if (err == 0)
+ err = setup_return(regs, ksig, frame->sig.retcode, frame);
+
+ 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 void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
+{
+ sigset_t *oldset = sigmask_to_save();
+ int ret;
+
+ /*
+ * Set up the stack frame
+ */
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+ ret = setup_rt_frame(ksig, oldset, regs);
+ else
+ ret = setup_frame(ksig, oldset, regs);
+
+ /*
+ * Check that the resulting registers are actually sane.
+ */
+ ret |= !valid_user_regs(regs);
+
+ signal_setup_done(ret, ksig, 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 int do_signal(struct pt_regs *regs, int syscall)
+{
+ unsigned int retval = 0, continue_addr = 0, restart_addr = 0;
+ struct ksignal ksig;
+ int restart = 0;
+
+ /*
+ * 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 -ERESTART_RESTARTBLOCK:
+ restart -= 2;
+ case -ERESTARTNOHAND:
+ case -ERESTARTSYS:
+ case -ERESTARTNOINTR:
+ restart++;
+ regs->ARM_r0 = regs->ARM_ORIG_r0;
+ regs->ARM_pc = restart_addr;
+ break;
+ }
+ }
+
+ /*
+ * Get the signal to deliver. When running under ptrace, at this
+ * point the debugger may change all our registers ...
+ */
+ /*
+ * 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 (get_signal(&ksig)) {
+ /* handler */
+ if (unlikely(restart) && regs->ARM_pc == restart_addr) {
+ if (retval == -ERESTARTNOHAND ||
+ retval == -ERESTART_RESTARTBLOCK
+ || (retval == -ERESTARTSYS
+ && !(ksig.ka.sa.sa_flags & SA_RESTART))) {
+ regs->ARM_r0 = -EINTR;
+ regs->ARM_pc = continue_addr;
+ }
+ }
+ handle_signal(&ksig, regs);
+ } else {
+ /* no handler */
+ restore_saved_sigmask();
+ if (unlikely(restart) && regs->ARM_pc == restart_addr) {
+ regs->ARM_pc = continue_addr;
+ return restart;
+ }
+ }
+ return 0;
+}
+
+asmlinkage int
+do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
+{
+ do {
+ if (likely(thread_flags & _TIF_NEED_RESCHED)) {
+ schedule();
+ } else {
+ if (unlikely(!user_mode(regs)))
+ return 0;
+ local_irq_enable();
+ if (thread_flags & _TIF_SIGPENDING) {
+ int restart = do_signal(regs, syscall);
+ if (unlikely(restart)) {
+ /*
+ * Restart without handlers.
+ * Deal with it without leaving
+ * the kernel space.
+ */
+ return restart;
+ }
+ syscall = 0;
+ } else if (thread_flags & _TIF_UPROBE) {
+ uprobe_notify_resume(regs);
+ } else {
+ clear_thread_flag(TIF_NOTIFY_RESUME);
+ tracehook_notify_resume(regs);
+ }
+ }
+ local_irq_disable();
+ thread_flags = current_thread_info()->flags;
+ } while (thread_flags & _TIF_WORK_MASK);
+ return 0;
+}
+
+struct page *get_signal_page(void)
+{
+ unsigned long ptr;
+ unsigned offset;
+ struct page *page;
+ void *addr;
+
+ page = alloc_pages(GFP_KERNEL, 0);
+
+ if (!page)
+ return NULL;
+
+ addr = page_address(page);
+
+ /* Give the signal return code some randomness */
+ offset = 0x200 + (get_random_int() & 0x7fc);
+ signal_return_offset = offset;
+
+ /*
+ * Copy signal return handlers into the vector page, and
+ * set sigreturn to be a pointer to these.
+ */
+ memcpy(addr + offset, sigreturn_codes, sizeof(sigreturn_codes));
+
+ ptr = (unsigned long)addr + offset;
+ flush_icache_range(ptr, ptr + sizeof(sigreturn_codes));
+
+ return page;
+}
diff --git a/arch/arm/kernel/sigreturn_codes.S b/arch/arm/kernel/sigreturn_codes.S
new file mode 100644
index 000000000..b84d0cb13
--- /dev/null
+++ b/arch/arm/kernel/sigreturn_codes.S
@@ -0,0 +1,102 @@
+/*
+ * sigreturn_codes.S - code sinpets for sigreturn syscalls
+ *
+ * Created by: Victor Kamensky, 2013-08-13
+ * Copyright: (C) 2013 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.
+ */
+
+#include <asm/unistd.h>
+
+/*
+ * For ARM syscalls, we encode the syscall number into the instruction.
+ * With EABI, the syscall number has to be loaded into r7. As result
+ * ARM syscall sequence snippet will have move and svc in .arm encoding
+ *
+ * For Thumb syscalls, we pass the syscall number via r7. We therefore
+ * need two 16-bit instructions in .thumb encoding
+ *
+ * Please note sigreturn_codes code are not executed in place. Instead
+ * they just copied by kernel into appropriate places. Code inside of
+ * arch/arm/kernel/signal.c is very sensitive to layout of these code
+ * snippets.
+ */
+
+/*
+ * In CPU_THUMBONLY case kernel arm opcodes are not allowed.
+ * Note in this case codes skips those instructions but it uses .org
+ * directive to keep correct layout of sigreturn_codes array.
+ */
+#ifndef CONFIG_CPU_THUMBONLY
+#define ARM_OK(code...) code
+#else
+#define ARM_OK(code...)
+#endif
+
+ .macro arm_slot n
+ .org sigreturn_codes + 12 * (\n)
+ARM_OK( .arm )
+ .endm
+
+ .macro thumb_slot n
+ .org sigreturn_codes + 12 * (\n) + 8
+ .thumb
+ .endm
+
+#if __LINUX_ARM_ARCH__ <= 4
+ /*
+ * Note we manually set minimally required arch that supports
+ * required thumb opcodes for early arch versions. It is OK
+ * for this file to be used in combination with other
+ * lower arch variants, since these code snippets are only
+ * used as input data.
+ */
+ .arch armv4t
+#endif
+
+ .section .rodata
+ .global sigreturn_codes
+ .type sigreturn_codes, #object
+
+ .align
+
+sigreturn_codes:
+
+ /* ARM sigreturn syscall code snippet */
+ arm_slot 0
+ARM_OK( mov r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) )
+ARM_OK( swi #(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE) )
+
+ /* Thumb sigreturn syscall code snippet */
+ thumb_slot 0
+ movs r7, #(__NR_sigreturn - __NR_SYSCALL_BASE)
+ swi #0
+
+ /* ARM sigreturn_rt syscall code snippet */
+ arm_slot 1
+ARM_OK( mov r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) )
+ARM_OK( swi #(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE) )
+
+ /* Thumb sigreturn_rt syscall code snippet */
+ thumb_slot 1
+ movs r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE)
+ swi #0
+
+ /*
+ * Note on addtional space: setup_return in signal.c
+ * algorithm uses two words copy regardless whether
+ * it is thumb case or not, so we need additional
+ * word after real last entry.
+ */
+ arm_slot 2
+ .space 4
+
+ .size sigreturn_codes, . - sigreturn_codes
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
new file mode 100644
index 000000000..7d37bfc50
--- /dev/null
+++ b/arch/arm/kernel/sleep.S
@@ -0,0 +1,162 @@
+#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>
+ .text
+
+/*
+ * Implementation of MPIDR hash algorithm through shifting
+ * and OR'ing.
+ *
+ * @dst: register containing hash result
+ * @rs0: register containing affinity level 0 bit shift
+ * @rs1: register containing affinity level 1 bit shift
+ * @rs2: register containing affinity level 2 bit shift
+ * @mpidr: register containing MPIDR value
+ * @mask: register containing MPIDR mask
+ *
+ * Pseudo C-code:
+ *
+ *u32 dst;
+ *
+ *compute_mpidr_hash(u32 rs0, u32 rs1, u32 rs2, u32 mpidr, u32 mask) {
+ * u32 aff0, aff1, aff2;
+ * u32 mpidr_masked = mpidr & mask;
+ * aff0 = mpidr_masked & 0xff;
+ * aff1 = mpidr_masked & 0xff00;
+ * aff2 = mpidr_masked & 0xff0000;
+ * dst = (aff0 >> rs0 | aff1 >> rs1 | aff2 >> rs2);
+ *}
+ * Input registers: rs0, rs1, rs2, mpidr, mask
+ * Output register: dst
+ * Note: input and output registers must be disjoint register sets
+ (eg: a macro instance with mpidr = r1 and dst = r1 is invalid)
+ */
+ .macro compute_mpidr_hash dst, rs0, rs1, rs2, mpidr, mask
+ and \mpidr, \mpidr, \mask @ mask out MPIDR bits
+ and \dst, \mpidr, #0xff @ mask=aff0
+ ARM( mov \dst, \dst, lsr \rs0 ) @ dst=aff0>>rs0
+ THUMB( lsr \dst, \dst, \rs0 )
+ and \mask, \mpidr, #0xff00 @ mask = aff1
+ ARM( orr \dst, \dst, \mask, lsr \rs1 ) @ dst|=(aff1>>rs1)
+ THUMB( lsr \mask, \mask, \rs1 )
+ THUMB( orr \dst, \dst, \mask )
+ and \mask, \mpidr, #0xff0000 @ mask = aff2
+ ARM( orr \dst, \dst, \mask, lsr \rs2 ) @ dst|=(aff2>>rs2)
+ THUMB( lsr \mask, \mask, \rs2 )
+ THUMB( orr \dst, \dst, \mask )
+ .endm
+
+/*
+ * Save CPU state for a suspend. This saves the CPU general purpose
+ * registers, and allocates space on the kernel stack to save the CPU
+ * specific registers and some other data for resume.
+ * r0 = suspend function arg0
+ * r1 = suspend function
+ * r2 = MPIDR value the resuming CPU will use
+ */
+ENTRY(__cpu_suspend)
+ stmfd sp!, {r4 - r11, lr}
+#ifdef MULTI_CPU
+ ldr r10, =processor
+ ldr r4, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
+#else
+ ldr r4, =cpu_suspend_size
+#endif
+ mov r5, sp @ current virtual SP
+ add r4, r4, #12 @ Space for pgd, virt sp, phys resume fn
+ sub sp, sp, r4 @ allocate CPU state on stack
+ ldr r3, =sleep_save_sp
+ stmfd sp!, {r0, r1} @ save suspend func arg and pointer
+ ldr r3, [r3, #SLEEP_SAVE_SP_VIRT]
+ ALT_SMP(ldr r0, =mpidr_hash)
+ ALT_UP_B(1f)
+ /* This ldmia relies on the memory layout of the mpidr_hash struct */
+ ldmia r0, {r1, r6-r8} @ r1 = mpidr mask (r6,r7,r8) = l[0,1,2] shifts
+ compute_mpidr_hash r0, r6, r7, r8, r2, r1
+ add r3, r3, r0, lsl #2
+1: mov r2, r5 @ virtual SP
+ mov r1, r4 @ size of save block
+ add r0, sp, #8 @ pointer to save block
+ bl __cpu_suspend_save
+ adr lr, BSYM(cpu_suspend_abort)
+ ldmfd sp!, {r0, pc} @ call suspend fn
+ENDPROC(__cpu_suspend)
+ .ltorg
+
+cpu_suspend_abort:
+ ldmia sp!, {r1 - r3} @ pop phys pgd, virt SP, phys resume fn
+ teq r0, #0
+ moveq r0, #1 @ force non-zero value
+ mov sp, r2
+ ldmfd sp!, {r4 - r11, pc}
+ENDPROC(cpu_suspend_abort)
+
+/*
+ * r0 = control register value
+ */
+ .align 5
+ .pushsection .idmap.text,"ax"
+ENTRY(cpu_resume_mmu)
+ ldr r3, =cpu_resume_after_mmu
+ instr_sync
+ mcr p15, 0, r0, c1, c0, 0 @ turn on MMU, I-cache, etc
+ mrc p15, 0, r0, c0, c0, 0 @ read id reg
+ instr_sync
+ mov r0, r0
+ mov r0, r0
+ ret r3 @ jump to virtual address
+ENDPROC(cpu_resume_mmu)
+ .popsection
+cpu_resume_after_mmu:
+ bl cpu_init @ restore the und/abt/irq banked regs
+ mov r0, #0 @ return zero on success
+ ldmfd sp!, {r4 - r11, pc}
+ENDPROC(cpu_resume_after_mmu)
+
+ .text
+ .align
+ENTRY(cpu_resume)
+ARM_BE8(setend be) @ ensure we are in BE mode
+#ifdef CONFIG_ARM_VIRT_EXT
+ bl __hyp_stub_install_secondary
+#endif
+ safe_svcmode_maskall r1
+ mov r1, #0
+ ALT_SMP(mrc p15, 0, r0, c0, c0, 5)
+ ALT_UP_B(1f)
+ adr r2, mpidr_hash_ptr
+ ldr r3, [r2]
+ add r2, r2, r3 @ r2 = struct mpidr_hash phys address
+ /*
+ * This ldmia relies on the memory layout of the mpidr_hash
+ * struct mpidr_hash.
+ */
+ ldmia r2, { r3-r6 } @ r3 = mpidr mask (r4,r5,r6) = l[0,1,2] shifts
+ compute_mpidr_hash r1, r4, r5, r6, r0, r3
+1:
+ adr r0, _sleep_save_sp
+ ldr r2, [r0]
+ add r0, r0, r2
+ ldr r0, [r0, #SLEEP_SAVE_SP_PHYS]
+ ldr r0, [r0, r1, lsl #2]
+
+ @ load phys pgd, stack, resume fn
+ ARM( ldmia r0!, {r1, sp, pc} )
+THUMB( ldmia r0!, {r1, r2, r3} )
+THUMB( mov sp, r2 )
+THUMB( bx r3 )
+ENDPROC(cpu_resume)
+
+ .align 2
+_sleep_save_sp:
+ .long sleep_save_sp - .
+mpidr_hash_ptr:
+ .long mpidr_hash - . @ mpidr_hash struct offset
+
+ .data
+ .type sleep_save_sp, #object
+ENTRY(sleep_save_sp)
+ .space SLEEP_SAVE_SP_SZ @ struct sleep_save_sp
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
new file mode 100644
index 000000000..f11d82527
--- /dev/null
+++ b/arch/arm/kernel/smp.c
@@ -0,0 +1,724 @@
+/*
+ * 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/mm.h>
+#include <linux/err.h>
+#include <linux/cpu.h>
+#include <linux/seq_file.h>
+#include <linux/irq.h>
+#include <linux/percpu.h>
+#include <linux/clockchips.h>
+#include <linux/completion.h>
+#include <linux/cpufreq.h>
+#include <linux/irq_work.h>
+
+#include <linux/atomic.h>
+#include <asm/smp.h>
+#include <asm/cacheflush.h>
+#include <asm/cpu.h>
+#include <asm/cputype.h>
+#include <asm/exception.h>
+#include <asm/idmap.h>
+#include <asm/topology.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/smp_plat.h>
+#include <asm/virt.h>
+#include <asm/mach/arch.h>
+#include <asm/mpu.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/ipi.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;
+
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+volatile int pen_release = -1;
+
+enum ipi_msg_type {
+ IPI_WAKEUP,
+ IPI_TIMER,
+ IPI_RESCHEDULE,
+ IPI_CALL_FUNC,
+ IPI_CALL_FUNC_SINGLE,
+ IPI_CPU_STOP,
+ IPI_IRQ_WORK,
+ IPI_COMPLETION,
+};
+
+static DECLARE_COMPLETION(cpu_running);
+
+static struct smp_operations smp_ops;
+
+void __init smp_set_ops(struct smp_operations *ops)
+{
+ if (ops)
+ smp_ops = *ops;
+};
+
+static unsigned long get_arch_pgd(pgd_t *pgd)
+{
+ phys_addr_t pgdir = virt_to_idmap(pgd);
+ BUG_ON(pgdir & ARCH_PGD_MASK);
+ return pgdir >> ARCH_PGD_SHIFT;
+}
+
+int __cpu_up(unsigned int cpu, struct task_struct *idle)
+{
+ int ret;
+
+ if (!smp_ops.smp_boot_secondary)
+ return -ENOSYS;
+
+ /*
+ * 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;
+#ifdef CONFIG_ARM_MPU
+ secondary_data.mpu_rgn_szr = mpu_rgn_info.rgns[MPU_RAM_REGION].drsr;
+#endif
+
+#ifdef CONFIG_MMU
+ secondary_data.pgdir = get_arch_pgd(idmap_pgd);
+ secondary_data.swapper_pg_dir = get_arch_pgd(swapper_pg_dir);
+#endif
+ sync_cache_w(&secondary_data);
+
+ /*
+ * Now bring the CPU into our world.
+ */
+ ret = smp_ops.smp_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);
+ }
+
+
+ memset(&secondary_data, 0, sizeof(secondary_data));
+ return ret;
+}
+
+/* platform specific SMP operations */
+void __init smp_init_cpus(void)
+{
+ if (smp_ops.smp_init_cpus)
+ smp_ops.smp_init_cpus();
+}
+
+int platform_can_secondary_boot(void)
+{
+ return !!smp_ops.smp_boot_secondary;
+}
+
+int platform_can_cpu_hotplug(void)
+{
+#ifdef CONFIG_HOTPLUG_CPU
+ if (smp_ops.cpu_kill)
+ return 1;
+#endif
+
+ return 0;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static int platform_cpu_kill(unsigned int cpu)
+{
+ if (smp_ops.cpu_kill)
+ return smp_ops.cpu_kill(cpu);
+ return 1;
+}
+
+static int platform_cpu_disable(unsigned int cpu)
+{
+ if (smp_ops.cpu_disable)
+ return smp_ops.cpu_disable(cpu);
+
+ /*
+ * By default, allow disabling all CPUs except the first one,
+ * since this is special on a lot of platforms, e.g. because
+ * of clock tick interrupts.
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
+/*
+ * __cpu_disable runs on the processor to be shutdown.
+ */
+int __cpu_disable(void)
+{
+ unsigned int cpu = smp_processor_id();
+ 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();
+
+ /*
+ * Flush user cache and TLB mappings, and then remove this CPU
+ * from the vm mask set of all processes.
+ *
+ * Caches are flushed to the Level of Unification Inner Shareable
+ * to write-back dirty lines to unified caches shared by all CPUs.
+ */
+ flush_cache_louis();
+ local_flush_tlb_all();
+
+ clear_tasks_mm_cpumask(cpu);
+
+ 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;
+ }
+ pr_notice("CPU%u: shutdown\n", cpu);
+
+ /*
+ * platform_cpu_kill() is generally expected to do the powering off
+ * and/or cutting of clocks to the dying CPU. Optionally, this may
+ * be done by the CPU which is dying in preference to supporting
+ * this call, but that means there is _no_ synchronisation between
+ * the requesting CPU and the dying CPU actually losing power.
+ */
+ if (!platform_cpu_kill(cpu))
+ pr_err("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();
+
+ /*
+ * Flush the data out of the L1 cache for this CPU. This must be
+ * before the completion to ensure that data is safely written out
+ * before platform_cpu_kill() gets called - which may disable
+ * *this* CPU and power down its cache.
+ */
+ flush_cache_louis();
+
+ /*
+ * Tell __cpu_die() that this CPU is now safe to dispose of. Once
+ * this returns, power and/or clocks can be removed at any point
+ * from this CPU and its cache by platform_cpu_kill().
+ */
+ complete(&cpu_died);
+
+ /*
+ * Ensure that the cache lines associated with that completion are
+ * written out. This covers the case where _this_ CPU is doing the
+ * powering down, to ensure that the completion is visible to the
+ * CPU waiting for this one.
+ */
+ flush_cache_louis();
+
+ /*
+ * The actual CPU shutdown procedure is at least platform (if not
+ * CPU) specific. This may remove power, or it may simply spin.
+ *
+ * Platforms are generally expected *NOT* to return from this call,
+ * although there are some which do because they have no way to
+ * power down the CPU. These platforms are the _only_ reason we
+ * have a return path which uses the fragment of assembly below.
+ *
+ * The return path should not be used for platforms which can
+ * power off the CPU.
+ */
+ if (smp_ops.cpu_die)
+ smp_ops.cpu_die(cpu);
+
+ pr_warn("CPU%u: smp_ops.cpu_die() returned, trying to resuscitate\n",
+ 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 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;
+ cpu_info->cpuid = read_cpuid_id();
+
+ store_cpu_topology(cpuid);
+}
+
+/*
+ * This is the secondary CPU boot entry. We're using this CPUs
+ * idle thread stack, but a set of temporary page tables.
+ */
+asmlinkage void secondary_start_kernel(void)
+{
+ struct mm_struct *mm = &init_mm;
+ unsigned int cpu;
+
+ /*
+ * The identity mapping is uncached (strongly ordered), so
+ * switch away from it before attempting any exclusive accesses.
+ */
+ cpu_switch_mm(mm->pgd, mm);
+ local_flush_bp_all();
+ enter_lazy_tlb(mm, current);
+ local_flush_tlb_all();
+
+ /*
+ * All kernel threads share the same mm context; grab a
+ * reference and switch to it.
+ */
+ cpu = smp_processor_id();
+ atomic_inc(&mm->mm_count);
+ current->active_mm = mm;
+ cpumask_set_cpu(cpu, mm_cpumask(mm));
+
+ cpu_init();
+
+ pr_debug("CPU%u: Booted secondary processor\n", cpu);
+
+ preempt_disable();
+ trace_hardirqs_off();
+
+ /*
+ * Give the platform a chance to do its own initialisation.
+ */
+ if (smp_ops.smp_secondary_init)
+ smp_ops.smp_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);
+
+ local_irq_enable();
+ local_fiq_enable();
+
+ /*
+ * OK, it's off to the idle thread for us
+ */
+ cpu_startup_entry(CPUHP_ONLINE);
+}
+
+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);
+
+ hyp_mode_check();
+}
+
+void __init smp_prepare_boot_cpu(void)
+{
+ set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
+}
+
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+ unsigned int ncores = num_possible_cpus();
+
+ init_cpu_topology();
+
+ smp_store_cpu_info(smp_processor_id());
+
+ /*
+ * are we trying to boot more cores than exist?
+ */
+ if (max_cpus > ncores)
+ max_cpus = ncores;
+ if (ncores > 1 && max_cpus) {
+ /*
+ * Initialise the present map, which describes the set of CPUs
+ * actually populated at the present time. A platform should
+ * re-initialize the map in the platforms smp_prepare_cpus()
+ * if present != possible (e.g. physical hotplug).
+ */
+ init_cpu_present(cpu_possible_mask);
+
+ /*
+ * Initialise the SCU if there are more than one CPU
+ * and let them know where to start.
+ */
+ if (smp_ops.smp_prepare_cpus)
+ smp_ops.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))
+{
+ if (!__smp_cross_call)
+ __smp_cross_call = fn;
+}
+
+static const char *ipi_types[NR_IPI] __tracepoint_string = {
+#define S(x,s) [x] = s
+ S(IPI_WAKEUP, "CPU wakeup interrupts"),
+ 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_IRQ_WORK, "IRQ work interrupts"),
+ S(IPI_COMPLETION, "completion interrupts"),
+};
+
+static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
+{
+ trace_ipi_raise(target, ipi_types[ipinr]);
+ __smp_cross_call(target, ipinr);
+}
+
+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_online_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]);
+
+ return sum;
+}
+
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
+{
+ smp_cross_call(mask, IPI_CALL_FUNC);
+}
+
+void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
+{
+ smp_cross_call(mask, IPI_WAKEUP);
+}
+
+void arch_send_call_function_single_ipi(int cpu)
+{
+ smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+}
+
+#ifdef CONFIG_IRQ_WORK
+void arch_irq_work_raise(void)
+{
+ if (arch_irq_work_has_interrupt())
+ smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
+}
+#endif
+
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+void tick_broadcast(const struct cpumask *mask)
+{
+ smp_cross_call(mask, IPI_TIMER);
+}
+#endif
+
+static DEFINE_RAW_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) {
+ raw_spin_lock(&stop_lock);
+ pr_crit("CPU%u: stopping\n", cpu);
+ dump_stack();
+ raw_spin_unlock(&stop_lock);
+ }
+
+ set_cpu_online(cpu, false);
+
+ local_fiq_disable();
+ local_irq_disable();
+
+ while (1)
+ cpu_relax();
+}
+
+static DEFINE_PER_CPU(struct completion *, cpu_completion);
+
+int register_ipi_completion(struct completion *completion, int cpu)
+{
+ per_cpu(cpu_completion, cpu) = completion;
+ return IPI_COMPLETION;
+}
+
+static void ipi_complete(unsigned int cpu)
+{
+ complete(per_cpu(cpu_completion, cpu));
+}
+
+/*
+ * Main handler for inter-processor interrupts
+ */
+asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
+{
+ handle_IPI(ipinr, regs);
+}
+
+void handle_IPI(int ipinr, struct pt_regs *regs)
+{
+ unsigned int cpu = smp_processor_id();
+ struct pt_regs *old_regs = set_irq_regs(regs);
+
+ if ((unsigned)ipinr < NR_IPI) {
+ trace_ipi_entry_rcuidle(ipi_types[ipinr]);
+ __inc_irq_stat(cpu, ipi_irqs[ipinr]);
+ }
+
+ switch (ipinr) {
+ case IPI_WAKEUP:
+ break;
+
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+ case IPI_TIMER:
+ irq_enter();
+ tick_receive_broadcast();
+ irq_exit();
+ break;
+#endif
+
+ 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;
+
+#ifdef CONFIG_IRQ_WORK
+ case IPI_IRQ_WORK:
+ irq_enter();
+ irq_work_run();
+ irq_exit();
+ break;
+#endif
+
+ case IPI_COMPLETION:
+ irq_enter();
+ ipi_complete(cpu);
+ irq_exit();
+ break;
+
+ default:
+ pr_crit("CPU%u: Unknown IPI message 0x%x\n",
+ cpu, ipinr);
+ break;
+ }
+
+ if ((unsigned)ipinr < NR_IPI)
+ trace_ipi_exit_rcuidle(ipi_types[ipinr]);
+ 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;
+ struct cpumask mask;
+
+ cpumask_copy(&mask, cpu_online_mask);
+ cpumask_clear_cpu(smp_processor_id(), &mask);
+ if (!cpumask_empty(&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_warn("SMP: failed to stop secondary CPUs\n");
+}
+
+/*
+ * not supported here
+ */
+int setup_profiling_timer(unsigned int multiplier)
+{
+ return -EINVAL;
+}
+
+#ifdef CONFIG_CPU_FREQ
+
+static DEFINE_PER_CPU(unsigned long, l_p_j_ref);
+static DEFINE_PER_CPU(unsigned long, l_p_j_ref_freq);
+static unsigned long global_l_p_j_ref;
+static unsigned long global_l_p_j_ref_freq;
+
+static int cpufreq_callback(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ struct cpufreq_freqs *freq = data;
+ int cpu = freq->cpu;
+
+ if (freq->flags & CPUFREQ_CONST_LOOPS)
+ return NOTIFY_OK;
+
+ if (!per_cpu(l_p_j_ref, cpu)) {
+ per_cpu(l_p_j_ref, cpu) =
+ per_cpu(cpu_data, cpu).loops_per_jiffy;
+ per_cpu(l_p_j_ref_freq, cpu) = freq->old;
+ if (!global_l_p_j_ref) {
+ global_l_p_j_ref = loops_per_jiffy;
+ global_l_p_j_ref_freq = freq->old;
+ }
+ }
+
+ if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) ||
+ (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) {
+ loops_per_jiffy = cpufreq_scale(global_l_p_j_ref,
+ global_l_p_j_ref_freq,
+ freq->new);
+ per_cpu(cpu_data, cpu).loops_per_jiffy =
+ cpufreq_scale(per_cpu(l_p_j_ref, cpu),
+ per_cpu(l_p_j_ref_freq, cpu),
+ freq->new);
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block cpufreq_notifier = {
+ .notifier_call = cpufreq_callback,
+};
+
+static int __init register_cpufreq_notifier(void)
+{
+ return cpufreq_register_notifier(&cpufreq_notifier,
+ CPUFREQ_TRANSITION_NOTIFIER);
+}
+core_initcall(register_cpufreq_notifier);
+
+#endif
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
new file mode 100644
index 000000000..72f9241ad
--- /dev/null
+++ b/arch/arm/kernel/smp_scu.c
@@ -0,0 +1,96 @@
+/*
+ * 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_plat.h>
+#include <asm/smp_scu.h>
+#include <asm/cacheflush.h>
+#include <asm/cputype.h>
+
+#define SCU_CTRL 0x00
+#define SCU_ENABLE (1 << 0)
+#define SCU_STANDBY_ENABLE (1 << 5)
+#define SCU_CONFIG 0x04
+#define SCU_CPU_STATUS 0x08
+#define SCU_INVALIDATE 0x0c
+#define SCU_FPGA_REVISION 0x10
+
+#ifdef CONFIG_SMP
+/*
+ * Get the number of CPU cores from the SCU configuration
+ */
+unsigned int __init scu_get_core_count(void __iomem *scu_base)
+{
+ unsigned int ncores = readl_relaxed(scu_base + SCU_CONFIG);
+ return (ncores & 0x03) + 1;
+}
+
+/*
+ * Enable the SCU
+ */
+void scu_enable(void __iomem *scu_base)
+{
+ u32 scu_ctrl;
+
+#ifdef CONFIG_ARM_ERRATA_764369
+ /* Cortex-A9 only */
+ if ((read_cpuid_id() & 0xff0ffff0) == 0x410fc090) {
+ scu_ctrl = readl_relaxed(scu_base + 0x30);
+ if (!(scu_ctrl & 1))
+ writel_relaxed(scu_ctrl | 0x1, scu_base + 0x30);
+ }
+#endif
+
+ scu_ctrl = readl_relaxed(scu_base + SCU_CTRL);
+ /* already enabled? */
+ if (scu_ctrl & SCU_ENABLE)
+ return;
+
+ scu_ctrl |= SCU_ENABLE;
+
+ /* Cortex-A9 earlier than r2p0 has no standby bit in SCU */
+ if ((read_cpuid_id() & 0xff0ffff0) == 0x410fc090 &&
+ (read_cpuid_id() & 0x00f0000f) >= 0x00200000)
+ scu_ctrl |= SCU_STANDBY_ENABLE;
+
+ writel_relaxed(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();
+}
+#endif
+
+/*
+ * 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 = MPIDR_AFFINITY_LEVEL(cpu_logical_map(smp_processor_id()), 0);
+
+ if (mode > 3 || mode == 1 || cpu > 3)
+ return -EINVAL;
+
+ val = readb_relaxed(scu_base + SCU_CPU_STATUS + cpu) & ~0x03;
+ val |= mode;
+ writeb_relaxed(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 000000000..2e72be4f6
--- /dev/null
+++ b/arch/arm/kernel/smp_tlb.c
@@ -0,0 +1,213 @@
+/*
+ * 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>
+#include <asm/mmu_context.h>
+
+/**********************************************************************/
+
+/*
+ * 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);
+}
+
+static inline void ipi_flush_bp_all(void *ignored)
+{
+ local_flush_bp_all();
+}
+
+#ifdef CONFIG_ARM_ERRATA_798181
+bool (*erratum_a15_798181_handler)(void);
+
+static bool erratum_a15_798181_partial(void)
+{
+ asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (0));
+ dsb(ish);
+ return false;
+}
+
+static bool erratum_a15_798181_broadcast(void)
+{
+ asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (0));
+ dsb(ish);
+ return true;
+}
+
+void erratum_a15_798181_init(void)
+{
+ unsigned int midr = read_cpuid_id();
+ unsigned int revidr = read_cpuid(CPUID_REVIDR);
+
+ /* Brahma-B15 r0p0..r0p2 affected
+ * Cortex-A15 r0p0..r3p2 w/o ECO fix affected */
+ if ((midr & 0xff0ffff0) == 0x420f00f0 && midr <= 0x420f00f2)
+ erratum_a15_798181_handler = erratum_a15_798181_broadcast;
+ else if ((midr & 0xff0ffff0) == 0x410fc0f0 && midr <= 0x413fc0f2 &&
+ (revidr & 0x210) != 0x210) {
+ if (revidr & 0x10)
+ erratum_a15_798181_handler =
+ erratum_a15_798181_partial;
+ else
+ erratum_a15_798181_handler =
+ erratum_a15_798181_broadcast;
+ }
+}
+#endif
+
+static void ipi_flush_tlb_a15_erratum(void *arg)
+{
+ dmb();
+}
+
+static void broadcast_tlb_a15_erratum(void)
+{
+ if (!erratum_a15_798181())
+ return;
+
+ smp_call_function(ipi_flush_tlb_a15_erratum, NULL, 1);
+}
+
+static void broadcast_tlb_mm_a15_erratum(struct mm_struct *mm)
+{
+ int this_cpu;
+ cpumask_t mask = { CPU_BITS_NONE };
+
+ if (!erratum_a15_798181())
+ return;
+
+ this_cpu = get_cpu();
+ a15_erratum_get_cpumask(this_cpu, mm, &mask);
+ smp_call_function_many(&mask, ipi_flush_tlb_a15_erratum, NULL, 1);
+ put_cpu();
+}
+
+void flush_tlb_all(void)
+{
+ if (tlb_ops_need_broadcast())
+ on_each_cpu(ipi_flush_tlb_all, NULL, 1);
+ else
+ __flush_tlb_all();
+ broadcast_tlb_a15_erratum();
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+ if (tlb_ops_need_broadcast())
+ on_each_cpu_mask(mm_cpumask(mm), ipi_flush_tlb_mm, mm, 1);
+ else
+ __flush_tlb_mm(mm);
+ broadcast_tlb_mm_a15_erratum(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(mm_cpumask(vma->vm_mm), ipi_flush_tlb_page,
+ &ta, 1);
+ } else
+ __flush_tlb_page(vma, uaddr);
+ broadcast_tlb_mm_a15_erratum(vma->vm_mm);
+}
+
+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
+ __flush_tlb_kernel_page(kaddr);
+ broadcast_tlb_a15_erratum();
+}
+
+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(mm_cpumask(vma->vm_mm), ipi_flush_tlb_range,
+ &ta, 1);
+ } else
+ local_flush_tlb_range(vma, start, end);
+ broadcast_tlb_mm_a15_erratum(vma->vm_mm);
+}
+
+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);
+ broadcast_tlb_a15_erratum();
+}
+
+void flush_bp_all(void)
+{
+ if (tlb_ops_need_broadcast())
+ on_each_cpu(ipi_flush_bp_all, NULL, 1);
+ else
+ __flush_bp_all();
+}
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
new file mode 100644
index 000000000..172c6a05d
--- /dev/null
+++ b/arch/arm/kernel/smp_twd.c
@@ -0,0 +1,414 @@
+/*
+ * 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/clk.h>
+#include <linux/cpu.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/smp.h>
+#include <linux/jiffies.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+
+#include <asm/smp_plat.h>
+#include <asm/smp_twd.h>
+
+/* set up by the platform code */
+static void __iomem *twd_base;
+
+static struct clk *twd_clk;
+static unsigned long twd_timer_rate;
+static DEFINE_PER_CPU(bool, percpu_setup_called);
+
+static struct clock_event_device __percpu *twd_evt;
+static int twd_ppi;
+
+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:
+ ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE
+ | TWD_TIMER_CONTROL_PERIODIC;
+ writel_relaxed(DIV_ROUND_CLOSEST(twd_timer_rate, HZ),
+ twd_base + TWD_TIMER_LOAD);
+ 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;
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ default:
+ ctrl = 0;
+ }
+
+ writel_relaxed(ctrl, twd_base + TWD_TIMER_CONTROL);
+}
+
+static int twd_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ unsigned long ctrl = readl_relaxed(twd_base + TWD_TIMER_CONTROL);
+
+ ctrl |= TWD_TIMER_CONTROL_ENABLE;
+
+ writel_relaxed(evt, twd_base + TWD_TIMER_COUNTER);
+ writel_relaxed(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.
+ */
+static int twd_timer_ack(void)
+{
+ if (readl_relaxed(twd_base + TWD_TIMER_INTSTAT)) {
+ writel_relaxed(1, twd_base + TWD_TIMER_INTSTAT);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void twd_timer_stop(void)
+{
+ struct clock_event_device *clk = raw_cpu_ptr(twd_evt);
+
+ twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
+ disable_percpu_irq(clk->irq);
+}
+
+#ifdef CONFIG_COMMON_CLK
+
+/*
+ * 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 *new_rate)
+{
+ twd_timer_rate = *((unsigned long *) new_rate);
+
+ clockevents_update_freq(raw_cpu_ptr(twd_evt), twd_timer_rate);
+}
+
+static int twd_rate_change(struct notifier_block *nb,
+ unsigned long flags, void *data)
+{
+ struct clk_notifier_data *cnd = 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.
+ */
+ if (flags == POST_RATE_CHANGE)
+ on_each_cpu(twd_update_frequency,
+ (void *)&cnd->new_rate, 1);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block twd_clk_nb = {
+ .notifier_call = twd_rate_change,
+};
+
+static int twd_clk_init(void)
+{
+ if (twd_evt && raw_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
+ return clk_notifier_register(twd_clk, &twd_clk_nb);
+
+ return 0;
+}
+core_initcall(twd_clk_init);
+
+#elif defined (CONFIG_CPU_FREQ)
+
+#include <linux/cpufreq.h>
+
+/*
+ * 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(raw_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.
+ */
+ if (state == CPUFREQ_POSTCHANGE)
+ smp_call_function_single(freqs->cpu, twd_update_frequency,
+ NULL, 1);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block twd_cpufreq_nb = {
+ .notifier_call = twd_cpufreq_transition,
+};
+
+static int twd_cpufreq_init(void)
+{
+ if (twd_evt && raw_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 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) {
+ pr_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 */
+ writel_relaxed(0x1, twd_base + TWD_TIMER_CONTROL);
+
+ /* maximum value */
+ writel_relaxed(0xFFFFFFFFU, twd_base + TWD_TIMER_COUNTER);
+
+ while (get_jiffies_64() < waitjiffies)
+ udelay(10);
+
+ count = readl_relaxed(twd_base + TWD_TIMER_COUNTER);
+
+ twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
+
+ pr_cont("%lu.%02luMHz.\n", twd_timer_rate / 1000000,
+ (twd_timer_rate / 10000) % 100);
+ }
+}
+
+static irqreturn_t twd_handler(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ if (twd_timer_ack()) {
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static void twd_get_clock(struct device_node *np)
+{
+ int err;
+
+ if (np)
+ twd_clk = of_clk_get(np, 0);
+ else
+ twd_clk = clk_get_sys("smp_twd", NULL);
+
+ if (IS_ERR(twd_clk)) {
+ pr_err("smp_twd: clock not found %d\n", (int) PTR_ERR(twd_clk));
+ return;
+ }
+
+ err = clk_prepare_enable(twd_clk);
+ if (err) {
+ pr_err("smp_twd: clock failed to prepare+enable: %d\n", err);
+ clk_put(twd_clk);
+ return;
+ }
+
+ twd_timer_rate = clk_get_rate(twd_clk);
+}
+
+/*
+ * Setup the local clock events for a CPU.
+ */
+static void twd_timer_setup(void)
+{
+ struct clock_event_device *clk = raw_cpu_ptr(twd_evt);
+ int cpu = smp_processor_id();
+
+ /*
+ * If the basic setup for this CPU has been done before don't
+ * bother with the below.
+ */
+ if (per_cpu(percpu_setup_called, cpu)) {
+ writel_relaxed(0, twd_base + TWD_TIMER_CONTROL);
+ clockevents_register_device(clk);
+ enable_percpu_irq(clk->irq, 0);
+ return;
+ }
+ per_cpu(percpu_setup_called, cpu) = true;
+
+ twd_calibrate_rate();
+
+ /*
+ * The following is done once per CPU the first time .setup() is
+ * called.
+ */
+ writel_relaxed(0, twd_base + TWD_TIMER_CONTROL);
+
+ 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;
+ clk->irq = twd_ppi;
+ clk->cpumask = cpumask_of(cpu);
+
+ clockevents_config_and_register(clk, twd_timer_rate,
+ 0xf, 0xffffffff);
+ enable_percpu_irq(clk->irq, 0);
+}
+
+static int twd_timer_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_STARTING:
+ twd_timer_setup();
+ break;
+ case CPU_DYING:
+ twd_timer_stop();
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block twd_timer_cpu_nb = {
+ .notifier_call = twd_timer_cpu_notify,
+};
+
+static int __init twd_local_timer_common_register(struct device_node *np)
+{
+ int err;
+
+ twd_evt = alloc_percpu(struct clock_event_device);
+ if (!twd_evt) {
+ err = -ENOMEM;
+ goto out_free;
+ }
+
+ err = request_percpu_irq(twd_ppi, twd_handler, "twd", twd_evt);
+ if (err) {
+ pr_err("twd: can't register interrupt %d (%d)\n", twd_ppi, err);
+ goto out_free;
+ }
+
+ err = register_cpu_notifier(&twd_timer_cpu_nb);
+ if (err)
+ goto out_irq;
+
+ twd_get_clock(np);
+
+ /*
+ * Immediately configure the timer on the boot CPU, unless we need
+ * jiffies to be incrementing to calibrate the rate in which case
+ * setup the timer in late_time_init.
+ */
+ if (twd_timer_rate)
+ twd_timer_setup();
+ else
+ late_time_init = twd_timer_setup;
+
+ return 0;
+
+out_irq:
+ free_percpu_irq(twd_ppi, twd_evt);
+out_free:
+ iounmap(twd_base);
+ twd_base = NULL;
+ free_percpu(twd_evt);
+
+ return err;
+}
+
+int __init twd_local_timer_register(struct twd_local_timer *tlt)
+{
+ if (twd_base || twd_evt)
+ return -EBUSY;
+
+ twd_ppi = tlt->res[1].start;
+
+ twd_base = ioremap(tlt->res[0].start, resource_size(&tlt->res[0]));
+ if (!twd_base)
+ return -ENOMEM;
+
+ return twd_local_timer_common_register(NULL);
+}
+
+#ifdef CONFIG_OF
+static void __init twd_local_timer_of_register(struct device_node *np)
+{
+ int err;
+
+ if (!is_smp() || !setup_max_cpus)
+ return;
+
+ twd_ppi = irq_of_parse_and_map(np, 0);
+ if (!twd_ppi) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ twd_base = of_iomap(np, 0);
+ if (!twd_base) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ err = twd_local_timer_common_register(np);
+
+out:
+ WARN(err, "twd_local_timer_of_register failed (%d)\n", err);
+}
+CLOCKSOURCE_OF_DECLARE(arm_twd_a9, "arm,cortex-a9-twd-timer", twd_local_timer_of_register);
+CLOCKSOURCE_OF_DECLARE(arm_twd_a5, "arm,cortex-a5-twd-timer", twd_local_timer_of_register);
+CLOCKSOURCE_OF_DECLARE(arm_twd_11mp, "arm,arm11mp-twd-timer", twd_local_timer_of_register);
+#endif
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
new file mode 100644
index 000000000..92b72375c
--- /dev/null
+++ b/arch/arm/kernel/stacktrace.c
@@ -0,0 +1,179 @@
+#include <linux/export.h>
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+
+#include <asm/stacktrace.h>
+#include <asm/traps.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 > high - 4)
+ 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 long last_pc;
+ 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;
+ struct pt_regs *regs;
+ 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;
+
+ if (trace->nr_entries >= trace->max_entries)
+ return 1;
+
+ /*
+ * in_exception_text() is designed to test if the PC is one of
+ * the functions which has an exception stack above it, but
+ * unfortunately what is in frame->pc is the return LR value,
+ * not the saved PC value. So, we need to track the previous
+ * frame PC value when doing this.
+ */
+ addr = data->last_pc;
+ data->last_pc = frame->pc;
+ if (!in_exception_text(addr))
+ return 0;
+
+ regs = (struct pt_regs *)frame->sp;
+
+ trace->entries[trace->nr_entries++] = regs->ARM_pc;
+
+ return trace->nr_entries >= trace->max_entries;
+}
+
+/* This must be noinline to so that our skip calculation works correctly */
+static noinline void __save_stack_trace(struct task_struct *tsk,
+ struct stack_trace *trace, unsigned int nosched)
+{
+ struct stack_trace_data data;
+ struct stackframe frame;
+
+ data.trace = trace;
+ data.last_pc = ULONG_MAX;
+ data.skip = trace->skip;
+ data.no_sched_functions = nosched;
+
+ 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
+ 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 {
+ /* We don't want this function nor the caller */
+ data.skip += 2;
+ frame.fp = (unsigned long)__builtin_frame_address(0);
+ frame.sp = current_stack_pointer;
+ frame.lr = (unsigned long)__builtin_return_address(0);
+ frame.pc = (unsigned long)__save_stack_trace;
+ }
+
+ walk_stackframe(&frame, save_trace, &data);
+ if (trace->nr_entries < trace->max_entries)
+ trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+
+void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
+{
+ struct stack_trace_data data;
+ struct stackframe frame;
+
+ data.trace = trace;
+ data.skip = trace->skip;
+ data.no_sched_functions = 0;
+
+ frame.fp = regs->ARM_fp;
+ frame.sp = regs->ARM_sp;
+ frame.lr = regs->ARM_lr;
+ frame.pc = regs->ARM_pc;
+
+ walk_stackframe(&frame, save_trace, &data);
+ if (trace->nr_entries < trace->max_entries)
+ trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+
+void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
+{
+ __save_stack_trace(tsk, trace, 1);
+}
+
+void save_stack_trace(struct stack_trace *trace)
+{
+ __save_stack_trace(current, trace, 0);
+}
+EXPORT_SYMBOL_GPL(save_stack_trace);
+#endif
diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
new file mode 100644
index 000000000..9a2f882a0
--- /dev/null
+++ b/arch/arm/kernel/suspend.c
@@ -0,0 +1,102 @@
+#include <linux/init.h>
+#include <linux/slab.h>
+
+#include <asm/cacheflush.h>
+#include <asm/idmap.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/memory.h>
+#include <asm/smp_plat.h>
+#include <asm/suspend.h>
+#include <asm/tlbflush.h>
+
+extern int __cpu_suspend(unsigned long, int (*)(unsigned long), u32 cpuid);
+extern void cpu_resume_mmu(void);
+
+#ifdef CONFIG_MMU
+int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
+{
+ struct mm_struct *mm = current->active_mm;
+ u32 __mpidr = cpu_logical_map(smp_processor_id());
+ int ret;
+
+ if (!idmap_pgd)
+ return -EINVAL;
+
+ /*
+ * Provide a temporary page table with an identity mapping for
+ * the MMU-enable code, required for resuming. On successful
+ * resume (indicated by a zero return code), we need to switch
+ * back to the correct page tables.
+ */
+ ret = __cpu_suspend(arg, fn, __mpidr);
+ if (ret == 0) {
+ cpu_switch_mm(mm->pgd, mm);
+ local_flush_bp_all();
+ local_flush_tlb_all();
+ }
+
+ return ret;
+}
+#else
+int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
+{
+ u32 __mpidr = cpu_logical_map(smp_processor_id());
+ return __cpu_suspend(arg, fn, __mpidr);
+}
+#define idmap_pgd NULL
+#endif
+
+/*
+ * This is called by __cpu_suspend() to save the state, and do whatever
+ * flushing is required to ensure that when the CPU goes to sleep we have
+ * the necessary data available when the caches are not searched.
+ */
+void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
+{
+ u32 *ctx = ptr;
+
+ *save_ptr = virt_to_phys(ptr);
+
+ /* This must correspond to the LDM in cpu_resume() assembly */
+ *ptr++ = virt_to_phys(idmap_pgd);
+ *ptr++ = sp;
+ *ptr++ = virt_to_phys(cpu_do_resume);
+
+ cpu_do_suspend(ptr);
+
+ flush_cache_louis();
+
+ /*
+ * flush_cache_louis does not guarantee that
+ * save_ptr and ptr are cleaned to main memory,
+ * just up to the Level of Unification Inner Shareable.
+ * Since the context pointer and context itself
+ * are to be retrieved with the MMU off that
+ * data must be cleaned from all cache levels
+ * to main memory using "area" cache primitives.
+ */
+ __cpuc_flush_dcache_area(ctx, ptrsz);
+ __cpuc_flush_dcache_area(save_ptr, sizeof(*save_ptr));
+
+ outer_clean_range(*save_ptr, *save_ptr + ptrsz);
+ outer_clean_range(virt_to_phys(save_ptr),
+ virt_to_phys(save_ptr) + sizeof(*save_ptr));
+}
+
+extern struct sleep_save_sp sleep_save_sp;
+
+static int cpu_suspend_alloc_sp(void)
+{
+ void *ctx_ptr;
+ /* ctx_ptr is an array of physical addresses */
+ ctx_ptr = kcalloc(mpidr_hash_size(), sizeof(u32), GFP_KERNEL);
+
+ if (WARN_ON(!ctx_ptr))
+ return -ENOMEM;
+ sleep_save_sp.save_ptr_stash = ctx_ptr;
+ sleep_save_sp.save_ptr_stash_phys = virt_to_phys(ctx_ptr);
+ sync_cache_w(&sleep_save_sp);
+ return 0;
+}
+early_initcall(cpu_suspend_alloc_sp);
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c
new file mode 100644
index 000000000..136175678
--- /dev/null
+++ b/arch/arm/kernel/swp_emulate.c
@@ -0,0 +1,269 @@
+/*
+ * 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/seq_file.h>
+#include <linux/sched.h>
+#include <linux/syscalls.h>
+#include <linux/perf_event.h>
+
+#include <asm/opcodes.h>
+#include <asm/system_info.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 .text.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_status_show(struct seq_file *m, void *v)
+{
+ seq_printf(m, "Emulated SWP:\t\t%lu\n", swpcounter);
+ seq_printf(m, "Emulated SWPB:\t\t%lu\n", swpbcounter);
+ seq_printf(m, "Aborted SWP{B}:\t\t%lu\n", abtcounter);
+ if (previous_pid != 0)
+ seq_printf(m, "Last process:\t\t%d\n", previous_pid);
+ return 0;
+}
+
+static int proc_status_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_status_show, PDE_DATA(inode));
+}
+
+static const struct file_operations proc_status_fops = {
+ .open = proc_status_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+#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;
+
+ down_read(&current->mm->mmap_sem);
+ if (find_vma(current->mm, addr) == NULL)
+ info.si_code = SEGV_MAPERR;
+ else
+ info.si_code = SEGV_ACCERR;
+ up_read(&current->mm->mmap_sem);
+
+ 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;
+
+ 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) {
+ 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, regs, regs->ARM_pc);
+
+ res = arm_check_condition(instr, regs->ARM_cpsr);
+ switch (res) {
+ case ARM_OPCODE_CONDTEST_PASS:
+ break;
+ case ARM_OPCODE_CONDTEST_FAIL:
+ /* Condition failed - return to next instruction */
+ regs->ARM_pc += 4;
+ return 0;
+ case ARM_OPCODE_CONDTEST_UNCOND:
+ /* If unconditional encoding - not a SWP, undef */
+ return -EFAULT;
+ default:
+ return -EINVAL;
+ }
+
+ 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)
+{
+ if (cpu_architecture() < CPU_ARCH_ARMv7)
+ return 0;
+
+#ifdef CONFIG_PROC_FS
+ if (!proc_create("cpu/swp_emulation", S_IRUGO, NULL, &proc_status_fops))
+ return -ENOMEM;
+#endif /* CONFIG_PROC_FS */
+
+ pr_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 000000000..3151f5623
--- /dev/null
+++ b/arch/arm/kernel/sys_arm.c
@@ -0,0 +1,39 @@
+/*
+ * 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/export.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>
+
+/*
+ * 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 000000000..b83f3b773
--- /dev/null
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -0,0 +1,456 @@
+/*
+ * 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 = from_kuid_munged(current_user_ns(), stat->uid);
+ tmp.st_gid = from_kgid_munged(current_user_ns(), 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_OFD_GETLK:
+ case F_OFD_SETLK:
+ case F_OFD_SETLKW:
+ 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 user_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 user_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 000000000..7a3be1d4d
--- /dev/null
+++ b/arch/arm/kernel/tcm.c
@@ -0,0 +1,336 @@
+/*
+ * 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 <asm/system_info.h>
+
+static struct gen_pool *tcm_pool;
+static bool dtcm_present;
+static bool itcm_present;
+
+/* 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_RW_DTCM
+ }
+};
+
+static struct map_desc itcm_iomap[] __initdata = {
+ {
+ .virtual = ITCM_OFFSET,
+ .pfn = __phys_to_pfn(ITCM_OFFSET),
+ .length = 0,
+ .type = MT_MEMORY_RWX_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);
+
+bool tcm_dtcm_present(void)
+{
+ return dtcm_present;
+}
+EXPORT_SYMBOL(tcm_dtcm_present);
+
+bool tcm_itcm_present(void)
+{
+ return itcm_present;
+}
+EXPORT_SYMBOL(tcm_itcm_present);
+
+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 ");
+ }
+
+ /* Not much fun you can do with a size 0 bank */
+ if (tcm_size == 0)
+ return 0;
+
+ /* 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;
+ u8 dtcm_banks;
+ u8 itcm_banks;
+ size_t dtcm_code_sz = &__edtcm_data - &__sdtcm_data;
+ size_t itcm_code_sz = &__eitcm_text - &__sitcm_text;
+ char *start;
+ char *end;
+ char *ram;
+ int ret;
+ int i;
+
+ /*
+ * Prior to ARMv5 there is no TCM, and trying to read the status
+ * register will hang the processor.
+ */
+ if (cpu_architecture() < CPU_ARCH_ARMv5) {
+ if (dtcm_code_sz || itcm_code_sz)
+ pr_info("CPU TCM: %u bytes of DTCM and %u bytes of "
+ "ITCM code compiled in, but no TCM present "
+ "in pre-v5 CPU\n", dtcm_code_sz, itcm_code_sz);
+ return;
+ }
+
+ tcm_status = read_cpuid_tcmstatus();
+ dtcm_banks = (tcm_status >> 16) & 0x03;
+ itcm_banks = (tcm_status & 0x03);
+
+ /* Values greater than 2 for D/ITCM banks are "reserved" */
+ if (dtcm_banks > 2)
+ dtcm_banks = 0;
+ if (itcm_banks > 2)
+ itcm_banks = 0;
+
+ /* 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;
+ }
+ /* This means you compiled more code than fits into DTCM */
+ if (dtcm_code_sz > (dtcm_end - DTCM_OFFSET)) {
+ pr_info("CPU DTCM: %u bytes of code compiled to "
+ "DTCM but only %lu bytes of DTCM present\n",
+ dtcm_code_sz, (dtcm_end - DTCM_OFFSET));
+ goto no_dtcm;
+ }
+ 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;
+ memcpy(start, ram, dtcm_code_sz);
+ pr_debug("CPU DTCM: copied data from %p - %p\n",
+ start, end);
+ dtcm_present = true;
+ } else if (dtcm_code_sz) {
+ pr_info("CPU DTCM: %u bytes of code compiled to DTCM but no "
+ "DTCM banks present in CPU\n", dtcm_code_sz);
+ }
+
+no_dtcm:
+ /* 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;
+ }
+ /* This means you compiled more code than fits into ITCM */
+ if (itcm_code_sz > (itcm_end - ITCM_OFFSET)) {
+ pr_info("CPU ITCM: %u bytes of code compiled to "
+ "ITCM but only %lu bytes of ITCM present\n",
+ itcm_code_sz, (itcm_end - ITCM_OFFSET));
+ 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;
+ memcpy(start, ram, itcm_code_sz);
+ pr_debug("CPU ITCM: copied code from %p - %p\n",
+ start, end);
+ itcm_present = true;
+ } else if (itcm_code_sz) {
+ pr_info("CPU ITCM: %u bytes of code compiled to ITCM but no "
+ "ITCM banks present in CPU\n", itcm_code_sz);
+ }
+}
+
+/*
+ * 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 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 (dtcm_present) {
+ 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 (itcm_present) {
+ 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/thumbee.c b/arch/arm/kernel/thumbee.c
new file mode 100644
index 000000000..8ff8dbfbe
--- /dev/null
+++ b/arch/arm/kernel/thumbee.c
@@ -0,0 +1,82 @@
+/*
+ * 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/cputype.h>
+#include <asm/system_info.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:
+ teehbr_write(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;
+
+ pfr0 = read_cpuid_ext(CPUID_EXT_PFR0);
+ if ((pfr0 & 0x0000f000) != 0x00001000)
+ return 0;
+
+ pr_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 000000000..a66e37e21
--- /dev/null
+++ b/arch/arm/kernel/time.c
@@ -0,0 +1,125 @@
+/*
+ * 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/clk-provider.h>
+#include <linux/clocksource.h>
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/profile.h>
+#include <linux/sched.h>
+#include <linux/sched_clock.h>
+#include <linux/smp.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/timer.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/stacktrace.h>
+#include <asm/thread_info.h>
+
+#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || \
+ defined(CONFIG_NVRAM) || defined(CONFIG_NVRAM_MODULE)
+/* this needs a better home */
+DEFINE_SPINLOCK(rtc_lock);
+EXPORT_SYMBOL(rtc_lock);
+#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;
+
+ arm_get_current_stackframe(regs, &frame);
+ 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
+
+#ifndef CONFIG_GENERIC_CLOCKEVENTS
+/*
+ * Kernel system timer support.
+ */
+void timer_tick(void)
+{
+ profile_tick(CPU_PROFILING);
+ xtime_update(1);
+#ifndef CONFIG_SMP
+ update_process_times(user_mode(get_irq_regs()));
+#endif
+}
+#endif
+
+static void dummy_clock_access(struct timespec64 *ts)
+{
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;
+}
+
+static clock_access_fn __read_persistent_clock = dummy_clock_access;
+static clock_access_fn __read_boot_clock = dummy_clock_access;;
+
+void read_persistent_clock64(struct timespec64 *ts)
+{
+ __read_persistent_clock(ts);
+}
+
+void read_boot_clock64(struct timespec64 *ts)
+{
+ __read_boot_clock(ts);
+}
+
+int __init register_persistent_clock(clock_access_fn read_boot,
+ clock_access_fn read_persistent)
+{
+ /* Only allow the clockaccess functions to be registered once */
+ if (__read_persistent_clock == dummy_clock_access &&
+ __read_boot_clock == dummy_clock_access) {
+ if (read_boot)
+ __read_boot_clock = read_boot;
+ if (read_persistent)
+ __read_persistent_clock = read_persistent;
+
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+void __init time_init(void)
+{
+ if (machine_desc->init_time) {
+ machine_desc->init_time();
+ } else {
+#ifdef CONFIG_COMMON_CLK
+ of_clk_init(NULL);
+#endif
+ clocksource_of_init();
+ }
+}
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
new file mode 100644
index 000000000..08b7847bf
--- /dev/null
+++ b/arch/arm/kernel/topology.c
@@ -0,0 +1,318 @@
+/*
+ * arch/arm/kernel/topology.c
+ *
+ * Copyright (C) 2011 Linaro Limited.
+ * Written by: Vincent Guittot
+ *
+ * based on arch/sh/kernel/topology.c
+ *
+ * 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/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/percpu.h>
+#include <linux/node.h>
+#include <linux/nodemask.h>
+#include <linux/of.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include <asm/cputype.h>
+#include <asm/topology.h>
+
+/*
+ * cpu capacity scale management
+ */
+
+/*
+ * cpu capacity table
+ * This per cpu data structure describes the relative capacity of each core.
+ * On a heteregenous system, cores don't have the same computation capacity
+ * and we reflect that difference in the cpu_capacity field so the scheduler
+ * can take this difference into account during load balance. A per cpu
+ * structure is preferred because each CPU updates its own cpu_capacity field
+ * during the load balance except for idle cores. One idle core is selected
+ * to run the rebalance_domains for all idle cores and the cpu_capacity can be
+ * updated during this sequence.
+ */
+static DEFINE_PER_CPU(unsigned long, cpu_scale);
+
+unsigned long arch_scale_cpu_capacity(struct sched_domain *sd, int cpu)
+{
+ return per_cpu(cpu_scale, cpu);
+}
+
+static void set_capacity_scale(unsigned int cpu, unsigned long capacity)
+{
+ per_cpu(cpu_scale, cpu) = capacity;
+}
+
+#ifdef CONFIG_OF
+struct cpu_efficiency {
+ const char *compatible;
+ unsigned long efficiency;
+};
+
+/*
+ * Table of relative efficiency of each processors
+ * The efficiency value must fit in 20bit and the final
+ * cpu_scale value must be in the range
+ * 0 < cpu_scale < 3*SCHED_CAPACITY_SCALE/2
+ * in order to return at most 1 when DIV_ROUND_CLOSEST
+ * is used to compute the capacity of a CPU.
+ * Processors that are not defined in the table,
+ * use the default SCHED_CAPACITY_SCALE value for cpu_scale.
+ */
+static const struct cpu_efficiency table_efficiency[] = {
+ {"arm,cortex-a15", 3891},
+ {"arm,cortex-a7", 2048},
+ {NULL, },
+};
+
+static unsigned long *__cpu_capacity;
+#define cpu_capacity(cpu) __cpu_capacity[cpu]
+
+static unsigned long middle_capacity = 1;
+
+/*
+ * Iterate all CPUs' descriptor in DT and compute the efficiency
+ * (as per table_efficiency). Also calculate a middle efficiency
+ * as close as possible to (max{eff_i} - min{eff_i}) / 2
+ * This is later used to scale the cpu_capacity field such that an
+ * 'average' CPU is of middle capacity. Also see the comments near
+ * table_efficiency[] and update_cpu_capacity().
+ */
+static void __init parse_dt_topology(void)
+{
+ const struct cpu_efficiency *cpu_eff;
+ struct device_node *cn = NULL;
+ unsigned long min_capacity = ULONG_MAX;
+ unsigned long max_capacity = 0;
+ unsigned long capacity = 0;
+ int cpu = 0;
+
+ __cpu_capacity = kcalloc(nr_cpu_ids, sizeof(*__cpu_capacity),
+ GFP_NOWAIT);
+
+ for_each_possible_cpu(cpu) {
+ const u32 *rate;
+ int len;
+
+ /* too early to use cpu->of_node */
+ cn = of_get_cpu_node(cpu, NULL);
+ if (!cn) {
+ pr_err("missing device node for CPU %d\n", cpu);
+ continue;
+ }
+
+ for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++)
+ if (of_device_is_compatible(cn, cpu_eff->compatible))
+ break;
+
+ if (cpu_eff->compatible == NULL)
+ continue;
+
+ rate = of_get_property(cn, "clock-frequency", &len);
+ if (!rate || len != 4) {
+ pr_err("%s missing clock-frequency property\n",
+ cn->full_name);
+ continue;
+ }
+
+ capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency;
+
+ /* Save min capacity of the system */
+ if (capacity < min_capacity)
+ min_capacity = capacity;
+
+ /* Save max capacity of the system */
+ if (capacity > max_capacity)
+ max_capacity = capacity;
+
+ cpu_capacity(cpu) = capacity;
+ }
+
+ /* If min and max capacities are equals, we bypass the update of the
+ * cpu_scale because all CPUs have the same capacity. Otherwise, we
+ * compute a middle_capacity factor that will ensure that the capacity
+ * of an 'average' CPU of the system will be as close as possible to
+ * SCHED_CAPACITY_SCALE, which is the default value, but with the
+ * constraint explained near table_efficiency[].
+ */
+ if (4*max_capacity < (3*(max_capacity + min_capacity)))
+ middle_capacity = (min_capacity + max_capacity)
+ >> (SCHED_CAPACITY_SHIFT+1);
+ else
+ middle_capacity = ((max_capacity / 3)
+ >> (SCHED_CAPACITY_SHIFT-1)) + 1;
+
+}
+
+/*
+ * Look for a customed capacity of a CPU in the cpu_capacity table during the
+ * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the
+ * function returns directly for SMP system.
+ */
+static void update_cpu_capacity(unsigned int cpu)
+{
+ if (!cpu_capacity(cpu))
+ return;
+
+ set_capacity_scale(cpu, cpu_capacity(cpu) / middle_capacity);
+
+ pr_info("CPU%u: update cpu_capacity %lu\n",
+ cpu, arch_scale_cpu_capacity(NULL, cpu));
+}
+
+#else
+static inline void parse_dt_topology(void) {}
+static inline void update_cpu_capacity(unsigned int cpuid) {}
+#endif
+
+ /*
+ * cpu topology table
+ */
+struct cputopo_arm cpu_topology[NR_CPUS];
+EXPORT_SYMBOL_GPL(cpu_topology);
+
+const struct cpumask *cpu_coregroup_mask(int cpu)
+{
+ return &cpu_topology[cpu].core_sibling;
+}
+
+/*
+ * The current assumption is that we can power gate each core independently.
+ * This will be superseded by DT binding once available.
+ */
+const struct cpumask *cpu_corepower_mask(int cpu)
+{
+ return &cpu_topology[cpu].thread_sibling;
+}
+
+static void update_siblings_masks(unsigned int cpuid)
+{
+ struct cputopo_arm *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
+ int cpu;
+
+ /* update core and thread sibling masks */
+ for_each_possible_cpu(cpu) {
+ cpu_topo = &cpu_topology[cpu];
+
+ if (cpuid_topo->socket_id != cpu_topo->socket_id)
+ continue;
+
+ cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
+ if (cpu != cpuid)
+ cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
+
+ if (cpuid_topo->core_id != cpu_topo->core_id)
+ continue;
+
+ cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
+ if (cpu != cpuid)
+ cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
+ }
+ smp_wmb();
+}
+
+/*
+ * store_cpu_topology is called at boot when only one cpu is running
+ * and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
+ * which prevents simultaneous write access to cpu_topology array
+ */
+void store_cpu_topology(unsigned int cpuid)
+{
+ struct cputopo_arm *cpuid_topo = &cpu_topology[cpuid];
+ unsigned int mpidr;
+
+ /* If the cpu topology has been already set, just return */
+ if (cpuid_topo->core_id != -1)
+ return;
+
+ mpidr = read_cpuid_mpidr();
+
+ /* create cpu topology mapping */
+ if ((mpidr & MPIDR_SMP_BITMASK) == MPIDR_SMP_VALUE) {
+ /*
+ * This is a multiprocessor system
+ * multiprocessor format & multiprocessor mode field are set
+ */
+
+ if (mpidr & MPIDR_MT_BITMASK) {
+ /* core performance interdependency */
+ cpuid_topo->thread_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+ cpuid_topo->socket_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
+ } else {
+ /* largely independent cores */
+ cpuid_topo->thread_id = -1;
+ cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ cpuid_topo->socket_id = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+ }
+ } else {
+ /*
+ * This is an uniprocessor system
+ * we are in multiprocessor format but uniprocessor system
+ * or in the old uniprocessor format
+ */
+ cpuid_topo->thread_id = -1;
+ cpuid_topo->core_id = 0;
+ cpuid_topo->socket_id = -1;
+ }
+
+ update_siblings_masks(cpuid);
+
+ update_cpu_capacity(cpuid);
+
+ pr_info("CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n",
+ cpuid, cpu_topology[cpuid].thread_id,
+ cpu_topology[cpuid].core_id,
+ cpu_topology[cpuid].socket_id, mpidr);
+}
+
+static inline int cpu_corepower_flags(void)
+{
+ return SD_SHARE_PKG_RESOURCES | SD_SHARE_POWERDOMAIN;
+}
+
+static struct sched_domain_topology_level arm_topology[] = {
+#ifdef CONFIG_SCHED_MC
+ { cpu_corepower_mask, cpu_corepower_flags, SD_INIT_NAME(GMC) },
+ { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) },
+#endif
+ { cpu_cpu_mask, SD_INIT_NAME(DIE) },
+ { NULL, },
+};
+
+/*
+ * init_cpu_topology is called at boot when only one cpu is running
+ * which prevent simultaneous write access to cpu_topology array
+ */
+void __init init_cpu_topology(void)
+{
+ unsigned int cpu;
+
+ /* init core mask and capacity */
+ for_each_possible_cpu(cpu) {
+ struct cputopo_arm *cpu_topo = &(cpu_topology[cpu]);
+
+ cpu_topo->thread_id = -1;
+ cpu_topo->core_id = -1;
+ cpu_topo->socket_id = -1;
+ cpumask_clear(&cpu_topo->core_sibling);
+ cpumask_clear(&cpu_topo->thread_sibling);
+
+ set_capacity_scale(cpu, SCHED_CAPACITY_SCALE);
+ }
+ smp_wmb();
+
+ parse_dt_topology();
+
+ /* Set scheduler topology descriptor */
+ set_sched_topology(arm_topology);
+}
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
new file mode 100644
index 000000000..3dce1a342
--- /dev/null
+++ b/arch/arm/kernel/traps.c
@@ -0,0 +1,889 @@
+/*
+ * 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/bug.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/irq.h>
+
+#include <linux/atomic.h>
+#include <asm/cacheflush.h>
+#include <asm/exception.h>
+#include <asm/unistd.h>
+#include <asm/traps.h>
+#include <asm/ptrace.h>
+#include <asm/unwind.h>
+#include <asm/tls.h>
+#include <asm/system_misc.h>
+#include <asm/opcodes.h>
+
+
+static const char *handler[]= {
+ "prefetch abort",
+ "data abort",
+ "address exception",
+ "interrupt",
+ "undefined instruction",
+};
+
+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 = frame_pointer(regs);
+ 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) {
+ pr_cont("no frame pointer");
+ ok = 0;
+ } else if (verify_stack(fp)) {
+ pr_cont("invalid frame pointer 0x%08x", fp);
+ ok = 0;
+ } else if (fp < (unsigned long)end_of_stack(tsk))
+ pr_cont("frame pointer underflow");
+ pr_cont("\n");
+
+ if (ok)
+ c_backtrace(fp, mode);
+}
+#endif
+
+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
+#ifdef CONFIG_THUMB2_KERNEL
+#define S_ISA " THUMB2"
+#else
+#define S_ISA " ARM"
+#endif
+
+static int __die(const char *str, int err, struct pt_regs *regs)
+{
+ struct task_struct *tsk = current;
+ static int die_counter;
+ int ret;
+
+ pr_emerg("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP S_ISA "\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 1;
+
+ print_modules();
+ __show_regs(regs);
+ pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n",
+ TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk));
+
+ 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 0;
+}
+
+static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+static int die_owner = -1;
+static unsigned int die_nest_count;
+
+static unsigned long oops_begin(void)
+{
+ int cpu;
+ unsigned long flags;
+
+ oops_enter();
+
+ /* racy, but better than risking deadlock. */
+ raw_local_irq_save(flags);
+ cpu = smp_processor_id();
+ if (!arch_spin_trylock(&die_lock)) {
+ if (cpu == die_owner)
+ /* nested oops. should stop eventually */;
+ else
+ arch_spin_lock(&die_lock);
+ }
+ die_nest_count++;
+ die_owner = cpu;
+ console_verbose();
+ bust_spinlocks(1);
+ return flags;
+}
+
+static void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
+{
+ if (regs && kexec_should_crash(current))
+ crash_kexec(regs);
+
+ bust_spinlocks(0);
+ die_owner = -1;
+ add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
+ die_nest_count--;
+ if (!die_nest_count)
+ /* Nest count reaches zero, release the lock. */
+ arch_spin_unlock(&die_lock);
+ raw_local_irq_restore(flags);
+ oops_exit();
+
+ if (in_interrupt())
+ panic("Fatal exception in interrupt");
+ if (panic_on_oops)
+ panic("Fatal exception");
+ if (signr)
+ do_exit(signr);
+}
+
+/*
+ * This function is protected against re-entrancy.
+ */
+void die(const char *str, struct pt_regs *regs, int err)
+{
+ enum bug_trap_type bug_type = BUG_TRAP_TYPE_NONE;
+ unsigned long flags = oops_begin();
+ int sig = SIGSEGV;
+
+ if (!user_mode(regs))
+ bug_type = report_bug(regs->ARM_pc, regs);
+ if (bug_type != BUG_TRAP_TYPE_NONE)
+ str = "Oops - BUG";
+
+ if (__die(str, err, regs))
+ sig = 0;
+
+ oops_end(flags, regs, sig);
+}
+
+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);
+ }
+}
+
+#ifdef CONFIG_GENERIC_BUG
+
+int is_valid_bugaddr(unsigned long pc)
+{
+#ifdef CONFIG_THUMB2_KERNEL
+ u16 bkpt;
+ u16 insn = __opcode_to_mem_thumb16(BUG_INSTR_VALUE);
+#else
+ u32 bkpt;
+ u32 insn = __opcode_to_mem_arm(BUG_INSTR_VALUE);
+#endif
+
+ if (probe_kernel_address((unsigned *)pc, bkpt))
+ return 0;
+
+ return bkpt == insn;
+}
+
+#endif
+
+static LIST_HEAD(undef_hook);
+static DEFINE_RAW_SPINLOCK(undef_lock);
+
+void register_undef_hook(struct undef_hook *hook)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&undef_lock, flags);
+ list_add(&hook->node, &undef_hook);
+ raw_spin_unlock_irqrestore(&undef_lock, flags);
+}
+
+void unregister_undef_hook(struct undef_hook *hook)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&undef_lock, flags);
+ list_del(&hook->node);
+ raw_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;
+
+ raw_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;
+ raw_spin_unlock_irqrestore(&undef_lock, flags);
+
+ return fn ? fn(regs, instr) : 1;
+}
+
+asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
+{
+ unsigned int instr;
+ siginfo_t info;
+ void __user *pc;
+
+ pc = (void __user *)instruction_pointer(regs);
+
+ if (processor_mode(regs) == SVC_MODE) {
+#ifdef CONFIG_THUMB2_KERNEL
+ if (thumb_mode(regs)) {
+ instr = __mem_to_opcode_thumb16(((u16 *)pc)[0]);
+ if (is_wide_instruction(instr)) {
+ u16 inst2;
+ inst2 = __mem_to_opcode_thumb16(((u16 *)pc)[1]);
+ instr = __opcode_thumb32_compose(instr, inst2);
+ }
+ } else
+#endif
+ instr = __mem_to_opcode_arm(*(u32 *) pc);
+ } else if (thumb_mode(regs)) {
+ if (get_user(instr, (u16 __user *)pc))
+ goto die_sig;
+ instr = __mem_to_opcode_thumb16(instr);
+ if (is_wide_instruction(instr)) {
+ unsigned int instr2;
+ if (get_user(instr2, (u16 __user *)pc+1))
+ goto die_sig;
+ instr2 = __mem_to_opcode_thumb16(instr2);
+ instr = __opcode_thumb32_compose(instr, instr2);
+ }
+ } else {
+ if (get_user(instr, (u32 __user *)pc))
+ goto die_sig;
+ instr = __mem_to_opcode_arm(instr);
+ }
+
+ if (call_undef_hook(regs, instr) == 0)
+ return;
+
+die_sig:
+#ifdef CONFIG_DEBUG_USER
+ if (user_debug & UDBG_UNDEFINED) {
+ pr_info("%s (%d): undefined instruction: pc=%p\n",
+ current->comm, task_pid_nr(current), pc);
+ __show_regs(regs);
+ 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);
+}
+
+/*
+ * Handle FIQ similarly to NMI on x86 systems.
+ *
+ * The runtime environment for NMIs is extremely restrictive
+ * (NMIs can pre-empt critical sections meaning almost all locking is
+ * forbidden) meaning this default FIQ handling must only be used in
+ * circumstances where non-maskability improves robustness, such as
+ * watchdog or debug logic.
+ *
+ * This handler is not appropriate for general purpose use in drivers
+ * platform code and can be overrideen using set_fiq_handler.
+ */
+asmlinkage void __exception_irq_entry handle_fiq_as_nmi(struct pt_regs *regs)
+{
+ struct pt_regs *old_regs = set_irq_regs(regs);
+
+ nmi_enter();
+
+ /* nop. FIQ handlers for special arch/arm features can be added here. */
+
+ nmi_exit();
+
+ set_irq_regs(old_regs);
+}
+
+/*
+ * 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();
+
+ pr_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)
+{
+ siginfo_t info;
+
+ if ((current->personality & PER_MASK) != PER_LINUX) {
+ send_sig(SIGSEGV, current, 1);
+ return regs->ARM_r0;
+ }
+
+#ifdef CONFIG_DEBUG_USER
+ if (user_debug & UDBG_SYSCALL) {
+ pr_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 int
+__do_cache_op(unsigned long start, unsigned long end)
+{
+ int ret;
+
+ do {
+ unsigned long chunk = min(PAGE_SIZE, end - start);
+
+ if (fatal_signal_pending(current))
+ return 0;
+
+ ret = flush_cache_user_range(start, start + chunk);
+ if (ret)
+ return ret;
+
+ cond_resched();
+ start += chunk;
+ } while (start < end);
+
+ return 0;
+}
+
+static inline int
+do_cache_op(unsigned long start, unsigned long end, int flags)
+{
+ if (end < start || flags)
+ return -EINVAL;
+
+ if (!access_ok(VERIFY_READ, start, end - start))
+ return -EFAULT;
+
+ return __do_cache_op(start, end);
+}
+
+/*
+ * 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)
+{
+ 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):
+ return do_cache_op(regs->ARM_r0, regs->ARM_r1, regs->ARM_r2);
+
+ 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):
+ set_tls(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) {
+ pr_err("[%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(frame_pointer(regs), 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[0];
+ 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)
+{
+ pr_err("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) {
+ pr_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 __readwrite_bug(const char *fn)
+{
+ pr_err("%s called, but not implemented\n", fn);
+ BUG();
+}
+EXPORT_SYMBOL(__readwrite_bug);
+
+void __pte_error(const char *file, int line, pte_t pte)
+{
+ pr_err("%s:%d: bad pte %08llx.\n", file, line, (long long)pte_val(pte));
+}
+
+void __pmd_error(const char *file, int line, pmd_t pmd)
+{
+ pr_err("%s:%d: bad pmd %08llx.\n", file, line, (long long)pmd_val(pmd));
+}
+
+void __pgd_error(const char *file, int line, pgd_t pgd)
+{
+ pr_err("%s:%d: bad pgd %08llx.\n", file, line, (long long)pgd_val(pgd));
+}
+
+asmlinkage void __div0(void)
+{
+ pr_err("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;
+}
+
+#ifdef CONFIG_KUSER_HELPERS
+static void __init kuser_init(void *vectors)
+{
+ extern char __kuser_helper_start[], __kuser_helper_end[];
+ int kuser_sz = __kuser_helper_end - __kuser_helper_start;
+
+ memcpy(vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
+
+ /*
+ * vectors + 0xfe0 = __kuser_get_tls
+ * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8
+ */
+ if (tls_emu || has_tls_reg)
+ memcpy(vectors + 0xfe0, vectors + 0xfe8, 4);
+}
+#else
+static inline void __init kuser_init(void *vectors)
+{
+}
+#endif
+
+void __init early_trap_init(void *vectors_base)
+{
+#ifndef CONFIG_CPU_V7M
+ unsigned long vectors = (unsigned long)vectors_base;
+ extern char __stubs_start[], __stubs_end[];
+ extern char __vectors_start[], __vectors_end[];
+ unsigned i;
+
+ vectors_page = vectors_base;
+
+ /*
+ * Poison the vectors page with an undefined instruction. This
+ * instruction is chosen to be undefined for both ARM and Thumb
+ * ISAs. The Thumb version is an undefined instruction with a
+ * branch back to the undefined instruction.
+ */
+ for (i = 0; i < PAGE_SIZE / sizeof(u32); i++)
+ ((u32 *)vectors_base)[i] = 0xe7fddef1;
+
+ /*
+ * 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 + 0x1000, __stubs_start, __stubs_end - __stubs_start);
+
+ kuser_init(vectors_base);
+
+ flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
+ modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
+#else /* ifndef CONFIG_CPU_V7M */
+ /*
+ * on V7-M there is no need to copy the vector table to a dedicated
+ * memory area. The address is configurable and so a table in the kernel
+ * image can be used.
+ */
+#endif
+}
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
new file mode 100644
index 000000000..0bee233fe
--- /dev/null
+++ b/arch/arm/kernel/unwind.c
@@ -0,0 +1,551 @@
+/*
+ * 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) && !defined(__clang__)
+#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/export.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 */
+ const unsigned long *insn; /* pointer to the current instructions word */
+ unsigned long sp_high; /* highest value of sp allowed */
+ /*
+ * 1 : check for stack overflow for each register pop.
+ * 0 : save overhead if there is plenty of stack remaining.
+ */
+ int check_each_pop;
+ 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 const struct unwind_idx __start_unwind_idx[];
+static const struct unwind_idx *__origin_unwind_idx;
+extern const 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 are
+ * guaranteed to be sorted in ascending order by the linker.
+ *
+ * start = first entry
+ * origin = first entry with positive offset (or stop if there is no such entry)
+ * stop - 1 = last entry
+ */
+static const struct unwind_idx *search_index(unsigned long addr,
+ const struct unwind_idx *start,
+ const struct unwind_idx *origin,
+ const struct unwind_idx *stop)
+{
+ unsigned long addr_prel31;
+
+ pr_debug("%s(%08lx, %p, %p, %p)\n",
+ __func__, addr, start, origin, stop);
+
+ /*
+ * only search in the section with the matching sign. This way the
+ * prel31 numbers can be compared as unsigned longs.
+ */
+ if (addr < (unsigned long)start)
+ /* negative offsets: [start; origin) */
+ stop = origin;
+ else
+ /* positive offsets: [origin; stop) */
+ start = origin;
+
+ /* prel31 for address relavive to start */
+ addr_prel31 = (addr - (unsigned long)start) & 0x7fffffff;
+
+ while (start < stop - 1) {
+ const struct unwind_idx *mid = start + ((stop - start) >> 1);
+
+ /*
+ * As addr_prel31 is relative to start an offset is needed to
+ * make it relative to mid.
+ */
+ if (addr_prel31 - ((unsigned long)mid - (unsigned long)start) <
+ mid->addr_offset)
+ stop = mid;
+ else {
+ /* keep addr_prel31 relative to start */
+ addr_prel31 -= ((unsigned long)mid -
+ (unsigned long)start);
+ start = mid;
+ }
+ }
+
+ if (likely(start->addr_offset <= addr_prel31))
+ return start;
+ else {
+ pr_warn("unwind: Unknown symbol address %08lx\n", addr);
+ return NULL;
+ }
+}
+
+static const struct unwind_idx *unwind_find_origin(
+ const struct unwind_idx *start, const struct unwind_idx *stop)
+{
+ pr_debug("%s(%p, %p)\n", __func__, start, stop);
+ while (start < stop) {
+ const struct unwind_idx *mid = start + ((stop - start) >> 1);
+
+ if (mid->addr_offset >= 0x40000000)
+ /* negative offset */
+ start = mid + 1;
+ else
+ /* positive offset */
+ stop = mid;
+ }
+ pr_debug("%s -> %p\n", __func__, stop);
+ return stop;
+}
+
+static const struct unwind_idx *unwind_find_idx(unsigned long addr)
+{
+ const struct unwind_idx *idx = NULL;
+ unsigned long flags;
+
+ pr_debug("%s(%08lx)\n", __func__, addr);
+
+ if (core_kernel_text(addr)) {
+ if (unlikely(!__origin_unwind_idx))
+ __origin_unwind_idx =
+ unwind_find_origin(__start_unwind_idx,
+ __stop_unwind_idx);
+
+ /* main unwind table */
+ idx = search_index(addr, __start_unwind_idx,
+ __origin_unwind_idx,
+ __stop_unwind_idx);
+ } 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->origin,
+ table->stop);
+ /* 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_warn("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;
+}
+
+/* Before poping a register check whether it is feasible or not */
+static int unwind_pop_register(struct unwind_ctrl_block *ctrl,
+ unsigned long **vsp, unsigned int reg)
+{
+ if (unlikely(ctrl->check_each_pop))
+ if (*vsp >= (unsigned long *)ctrl->sp_high)
+ return -URC_FAILURE;
+
+ ctrl->vrs[reg] = *(*vsp)++;
+ return URC_OK;
+}
+
+/* Helper functions to execute the instructions */
+static int unwind_exec_pop_subset_r4_to_r13(struct unwind_ctrl_block *ctrl,
+ unsigned long mask)
+{
+ unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+ int load_sp, reg = 4;
+
+ load_sp = mask & (1 << (13 - 4));
+ while (mask) {
+ if (mask & 1)
+ if (unwind_pop_register(ctrl, &vsp, reg))
+ return -URC_FAILURE;
+ mask >>= 1;
+ reg++;
+ }
+ if (!load_sp)
+ ctrl->vrs[SP] = (unsigned long)vsp;
+
+ return URC_OK;
+}
+
+static int unwind_exec_pop_r4_to_rN(struct unwind_ctrl_block *ctrl,
+ unsigned long insn)
+{
+ unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+ int reg;
+
+ /* pop R4-R[4+bbb] */
+ for (reg = 4; reg <= 4 + (insn & 7); reg++)
+ if (unwind_pop_register(ctrl, &vsp, reg))
+ return -URC_FAILURE;
+
+ if (insn & 0x8)
+ if (unwind_pop_register(ctrl, &vsp, 14))
+ return -URC_FAILURE;
+
+ ctrl->vrs[SP] = (unsigned long)vsp;
+
+ return URC_OK;
+}
+
+static int unwind_exec_pop_subset_r0_to_r3(struct unwind_ctrl_block *ctrl,
+ unsigned long mask)
+{
+ unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+ int reg = 0;
+
+ /* pop R0-R3 according to mask */
+ while (mask) {
+ if (mask & 1)
+ if (unwind_pop_register(ctrl, &vsp, reg))
+ return -URC_FAILURE;
+ mask >>= 1;
+ reg++;
+ }
+ ctrl->vrs[SP] = (unsigned long)vsp;
+
+ return URC_OK;
+}
+
+/*
+ * Execute the current unwind instruction.
+ */
+static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
+{
+ unsigned long insn = unwind_get_byte(ctrl);
+ int ret = URC_OK;
+
+ 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;
+
+ insn = (insn << 8) | unwind_get_byte(ctrl);
+ mask = insn & 0x0fff;
+ if (mask == 0) {
+ pr_warn("unwind: 'Refuse to unwind' instruction %04lx\n",
+ insn);
+ return -URC_FAILURE;
+ }
+
+ ret = unwind_exec_pop_subset_r4_to_r13(ctrl, mask);
+ if (ret)
+ goto error;
+ } else if ((insn & 0xf0) == 0x90 &&
+ (insn & 0x0d) != 0x0d)
+ ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f];
+ else if ((insn & 0xf0) == 0xa0) {
+ ret = unwind_exec_pop_r4_to_rN(ctrl, insn);
+ if (ret)
+ goto error;
+ } 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);
+
+ if (mask == 0 || mask & 0xf0) {
+ pr_warn("unwind: Spare encoding %04lx\n",
+ (insn << 8) | mask);
+ return -URC_FAILURE;
+ }
+
+ ret = unwind_exec_pop_subset_r0_to_r3(ctrl, mask);
+ if (ret)
+ goto error;
+ } else if (insn == 0xb2) {
+ unsigned long uleb128 = unwind_get_byte(ctrl);
+
+ ctrl->vrs[SP] += 0x204 + (uleb128 << 2);
+ } else {
+ pr_warn("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]);
+
+error:
+ return ret;
+}
+
+/*
+ * 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 low;
+ const struct unwind_idx *idx;
+ struct unwind_ctrl_block ctrl;
+
+ /* store the highest address on the stack to avoid crossing it*/
+ low = frame->sp;
+ ctrl.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_warn("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_warn("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_warn("unwind: Unsupported personality routine %08lx at %p\n",
+ *ctrl.insn, ctrl.insn);
+ return -URC_FAILURE;
+ }
+
+ ctrl.check_each_pop = 0;
+
+ while (ctrl.entries > 0) {
+ int urc;
+ if ((ctrl.sp_high - ctrl.vrs[SP]) < sizeof(ctrl.vrs))
+ ctrl.check_each_pop = 1;
+ urc = unwind_exec_insn(&ctrl);
+ if (urc < 0)
+ return urc;
+ if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= ctrl.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;
+
+ pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
+
+ if (!tsk)
+ tsk = current;
+
+ if (regs) {
+ arm_get_current_stackframe(regs, &frame);
+ /* PC might be corrupted, use LR in that case. */
+ if (!kernel_text_address(regs->ARM_pc))
+ frame.pc = regs->ARM_lr;
+ } else if (tsk == current) {
+ frame.fp = (unsigned long)__builtin_frame_address(0);
+ frame.sp = current_stack_pointer;
+ 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_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 = (const struct unwind_idx *)start;
+ tab->stop = (const struct unwind_idx *)(start + size);
+ tab->origin = unwind_find_origin(tab->start, tab->stop);
+ tab->begin_addr = text_addr;
+ tab->end_addr = text_addr + text_size;
+
+ 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);
+}
diff --git a/arch/arm/kernel/v7m.c b/arch/arm/kernel/v7m.c
new file mode 100644
index 000000000..4d2cba94f
--- /dev/null
+++ b/arch/arm/kernel/v7m.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2013 Uwe Kleine-Koenig 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/io.h>
+#include <linux/reboot.h>
+#include <asm/barrier.h>
+#include <asm/v7m.h>
+
+void armv7m_restart(enum reboot_mode mode, const char *cmd)
+{
+ dsb();
+ __raw_writel(V7M_SCB_AIRCR_VECTKEY | V7M_SCB_AIRCR_SYSRESETREQ,
+ BASEADDR_V7M_SCB + V7M_SCB_AIRCR);
+ dsb();
+}
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
new file mode 100644
index 000000000..efe17dd9b
--- /dev/null
+++ b/arch/arm/kernel/vdso.c
@@ -0,0 +1,337 @@
+/*
+ * Adapted from arm64 version.
+ *
+ * Copyright (C) 2012 ARM Limited
+ * Copyright (C) 2015 Mentor Graphics 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/elf.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/of.h>
+#include <linux/printk.h>
+#include <linux/slab.h>
+#include <linux/timekeeper_internal.h>
+#include <linux/vmalloc.h>
+#include <asm/arch_timer.h>
+#include <asm/barrier.h>
+#include <asm/cacheflush.h>
+#include <asm/page.h>
+#include <asm/vdso.h>
+#include <asm/vdso_datapage.h>
+#include <clocksource/arm_arch_timer.h>
+
+#define MAX_SYMNAME 64
+
+static struct page **vdso_text_pagelist;
+
+/* Total number of pages needed for the data and text portions of the VDSO. */
+unsigned int vdso_total_pages __read_mostly;
+
+/*
+ * The VDSO data page.
+ */
+static union vdso_data_store vdso_data_store __page_aligned_data;
+static struct vdso_data *vdso_data = &vdso_data_store.data;
+
+static struct page *vdso_data_page;
+static struct vm_special_mapping vdso_data_mapping = {
+ .name = "[vvar]",
+ .pages = &vdso_data_page,
+};
+
+static struct vm_special_mapping vdso_text_mapping = {
+ .name = "[vdso]",
+};
+
+struct elfinfo {
+ Elf32_Ehdr *hdr; /* ptr to ELF */
+ Elf32_Sym *dynsym; /* ptr to .dynsym section */
+ unsigned long dynsymsize; /* size of .dynsym section */
+ char *dynstr; /* ptr to .dynstr section */
+};
+
+/* Cached result of boot-time check for whether the arch timer exists,
+ * and if so, whether the virtual counter is useable.
+ */
+static bool cntvct_ok __read_mostly;
+
+static bool __init cntvct_functional(void)
+{
+ struct device_node *np;
+ bool ret = false;
+
+ if (!IS_ENABLED(CONFIG_ARM_ARCH_TIMER))
+ goto out;
+
+ /* The arm_arch_timer core should export
+ * arch_timer_use_virtual or similar so we don't have to do
+ * this.
+ */
+ np = of_find_compatible_node(NULL, NULL, "arm,armv7-timer");
+ if (!np)
+ goto out_put;
+
+ if (of_property_read_bool(np, "arm,cpu-registers-not-fw-configured"))
+ goto out_put;
+
+ ret = true;
+
+out_put:
+ of_node_put(np);
+out:
+ return ret;
+}
+
+static void * __init find_section(Elf32_Ehdr *ehdr, const char *name,
+ unsigned long *size)
+{
+ Elf32_Shdr *sechdrs;
+ unsigned int i;
+ char *secnames;
+
+ /* Grab section headers and strings so we can tell who is who */
+ sechdrs = (void *)ehdr + ehdr->e_shoff;
+ secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset;
+
+ /* Find the section they want */
+ for (i = 1; i < ehdr->e_shnum; i++) {
+ if (strcmp(secnames + sechdrs[i].sh_name, name) == 0) {
+ if (size)
+ *size = sechdrs[i].sh_size;
+ return (void *)ehdr + sechdrs[i].sh_offset;
+ }
+ }
+
+ if (size)
+ *size = 0;
+ return NULL;
+}
+
+static Elf32_Sym * __init find_symbol(struct elfinfo *lib, const char *symname)
+{
+ unsigned int i;
+
+ for (i = 0; i < (lib->dynsymsize / sizeof(Elf32_Sym)); i++) {
+ char name[MAX_SYMNAME], *c;
+
+ if (lib->dynsym[i].st_name == 0)
+ continue;
+ strlcpy(name, lib->dynstr + lib->dynsym[i].st_name,
+ MAX_SYMNAME);
+ c = strchr(name, '@');
+ if (c)
+ *c = 0;
+ if (strcmp(symname, name) == 0)
+ return &lib->dynsym[i];
+ }
+ return NULL;
+}
+
+static void __init vdso_nullpatch_one(struct elfinfo *lib, const char *symname)
+{
+ Elf32_Sym *sym;
+
+ sym = find_symbol(lib, symname);
+ if (!sym)
+ return;
+
+ sym->st_name = 0;
+}
+
+static void __init patch_vdso(void *ehdr)
+{
+ struct elfinfo einfo;
+
+ einfo = (struct elfinfo) {
+ .hdr = ehdr,
+ };
+
+ einfo.dynsym = find_section(einfo.hdr, ".dynsym", &einfo.dynsymsize);
+ einfo.dynstr = find_section(einfo.hdr, ".dynstr", NULL);
+
+ /* If the virtual counter is absent or non-functional we don't
+ * want programs to incur the slight additional overhead of
+ * dispatching through the VDSO only to fall back to syscalls.
+ */
+ if (!cntvct_ok) {
+ vdso_nullpatch_one(&einfo, "__vdso_gettimeofday");
+ vdso_nullpatch_one(&einfo, "__vdso_clock_gettime");
+ }
+}
+
+static int __init vdso_init(void)
+{
+ unsigned int text_pages;
+ int i;
+
+ if (memcmp(&vdso_start, "\177ELF", 4)) {
+ pr_err("VDSO is not a valid ELF object!\n");
+ return -ENOEXEC;
+ }
+
+ text_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
+ pr_debug("vdso: %i text pages at base %p\n", text_pages, &vdso_start);
+
+ /* Allocate the VDSO text pagelist */
+ vdso_text_pagelist = kcalloc(text_pages, sizeof(struct page *),
+ GFP_KERNEL);
+ if (vdso_text_pagelist == NULL)
+ return -ENOMEM;
+
+ /* Grab the VDSO data page. */
+ vdso_data_page = virt_to_page(vdso_data);
+
+ /* Grab the VDSO text pages. */
+ for (i = 0; i < text_pages; i++) {
+ struct page *page;
+
+ page = virt_to_page(&vdso_start + i * PAGE_SIZE);
+ vdso_text_pagelist[i] = page;
+ }
+
+ vdso_text_mapping.pages = vdso_text_pagelist;
+
+ vdso_total_pages = 1; /* for the data/vvar page */
+ vdso_total_pages += text_pages;
+
+ cntvct_ok = cntvct_functional();
+
+ patch_vdso(&vdso_start);
+
+ return 0;
+}
+arch_initcall(vdso_init);
+
+static int install_vvar(struct mm_struct *mm, unsigned long addr)
+{
+ struct vm_area_struct *vma;
+
+ vma = _install_special_mapping(mm, addr, PAGE_SIZE,
+ VM_READ | VM_MAYREAD,
+ &vdso_data_mapping);
+
+ return IS_ERR(vma) ? PTR_ERR(vma) : 0;
+}
+
+/* assumes mmap_sem is write-locked */
+void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
+{
+ struct vm_area_struct *vma;
+ unsigned long len;
+
+ mm->context.vdso = 0;
+
+ if (vdso_text_pagelist == NULL)
+ return;
+
+ if (install_vvar(mm, addr))
+ return;
+
+ /* Account for vvar page. */
+ addr += PAGE_SIZE;
+ len = (vdso_total_pages - 1) << PAGE_SHIFT;
+
+ vma = _install_special_mapping(mm, addr, len,
+ VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
+ &vdso_text_mapping);
+
+ if (!IS_ERR(vma))
+ mm->context.vdso = addr;
+}
+
+static void vdso_write_begin(struct vdso_data *vdata)
+{
+ ++vdso_data->seq_count;
+ smp_wmb(); /* Pairs with smp_rmb in vdso_read_retry */
+}
+
+static void vdso_write_end(struct vdso_data *vdata)
+{
+ smp_wmb(); /* Pairs with smp_rmb in vdso_read_begin */
+ ++vdso_data->seq_count;
+}
+
+static bool tk_is_cntvct(const struct timekeeper *tk)
+{
+ if (!IS_ENABLED(CONFIG_ARM_ARCH_TIMER))
+ return false;
+
+ if (strcmp(tk->tkr_mono.clock->name, "arch_sys_counter") != 0)
+ return false;
+
+ return true;
+}
+
+/**
+ * update_vsyscall - update the vdso data page
+ *
+ * Increment the sequence counter, making it odd, indicating to
+ * userspace that an update is in progress. Update the fields used
+ * for coarse clocks and, if the architected system timer is in use,
+ * the fields used for high precision clocks. Increment the sequence
+ * counter again, making it even, indicating to userspace that the
+ * update is finished.
+ *
+ * Userspace is expected to sample seq_count before reading any other
+ * fields from the data page. If seq_count is odd, userspace is
+ * expected to wait until it becomes even. After copying data from
+ * the page, userspace must sample seq_count again; if it has changed
+ * from its previous value, userspace must retry the whole sequence.
+ *
+ * Calls to update_vsyscall are serialized by the timekeeping core.
+ */
+void update_vsyscall(struct timekeeper *tk)
+{
+ struct timespec xtime_coarse;
+ struct timespec64 *wtm = &tk->wall_to_monotonic;
+
+ if (!cntvct_ok) {
+ /* The entry points have been zeroed, so there is no
+ * point in updating the data page.
+ */
+ return;
+ }
+
+ vdso_write_begin(vdso_data);
+
+ xtime_coarse = __current_kernel_time();
+ vdso_data->tk_is_cntvct = tk_is_cntvct(tk);
+ vdso_data->xtime_coarse_sec = xtime_coarse.tv_sec;
+ vdso_data->xtime_coarse_nsec = xtime_coarse.tv_nsec;
+ vdso_data->wtm_clock_sec = wtm->tv_sec;
+ vdso_data->wtm_clock_nsec = wtm->tv_nsec;
+
+ if (vdso_data->tk_is_cntvct) {
+ vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last;
+ vdso_data->xtime_clock_sec = tk->xtime_sec;
+ vdso_data->xtime_clock_snsec = tk->tkr_mono.xtime_nsec;
+ vdso_data->cs_mult = tk->tkr_mono.mult;
+ vdso_data->cs_shift = tk->tkr_mono.shift;
+ vdso_data->cs_mask = tk->tkr_mono.mask;
+ }
+
+ vdso_write_end(vdso_data);
+
+ flush_dcache_page(virt_to_page(vdso_data));
+}
+
+void update_vsyscall_tz(void)
+{
+ vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
+ vdso_data->tz_dsttime = sys_tz.tz_dsttime;
+ flush_dcache_page(virt_to_page(vdso_data));
+}
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
new file mode 100644
index 000000000..8b60fde5c
--- /dev/null
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -0,0 +1,353 @@
+/* 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/cache.h>
+#include <asm/thread_info.h>
+#include <asm/memory.h>
+#include <asm/page.h>
+#ifdef CONFIG_ARM_KERNMEM_PERMS
+#include <asm/pgtable.h>
+#endif
+
+#define PROC_INFO \
+ . = ALIGN(4); \
+ VMLINUX_SYMBOL(__proc_info_begin) = .; \
+ *(.proc.info.init) \
+ VMLINUX_SYMBOL(__proc_info_end) = .;
+
+#define IDMAP_TEXT \
+ ALIGN_FUNCTION(); \
+ VMLINUX_SYMBOL(__idmap_text_start) = .; \
+ *(.idmap.text) \
+ VMLINUX_SYMBOL(__idmap_text_end) = .; \
+ . = ALIGN(PAGE_SIZE); \
+ VMLINUX_SYMBOL(__hyp_idmap_text_start) = .; \
+ *(.hyp.idmap.text) \
+ VMLINUX_SYMBOL(__hyp_idmap_text_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)) || \
+ defined(CONFIG_GENERIC_BUG)
+#define ARM_EXIT_KEEP(x) x
+#define ARM_EXIT_DISCARD(x)
+#else
+#define ARM_EXIT_KEEP(x)
+#define ARM_EXIT_DISCARD(x) x
+#endif
+
+OUTPUT_ARCH(arm)
+ENTRY(stext)
+
+#ifndef __ARMEB__
+jiffies = jiffies_64;
+#else
+jiffies = jiffies_64 + 4;
+#endif
+
+SECTIONS
+{
+ /*
+ * XXX: The linker does not define how output sections are
+ * assigned to input sections when there are multiple statements
+ * matching the same input section name. There is no documented
+ * order of matching.
+ *
+ * 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))
+ ARM_EXIT_DISCARD(EXIT_TEXT)
+ ARM_EXIT_DISCARD(EXIT_DATA)
+ EXIT_CALL
+#ifndef CONFIG_MMU
+ *(.text.fixup)
+ *(__ex_table)
+#endif
+#ifndef CONFIG_SMP_ON_UP
+ *(.alt.smp.init)
+#endif
+ *(.discard)
+ *(.discard.*)
+ }
+
+#ifdef CONFIG_XIP_KERNEL
+ . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
+#else
+ . = PAGE_OFFSET + TEXT_OFFSET;
+#endif
+ .head.text : {
+ _text = .;
+ HEAD_TEXT
+ }
+
+#ifdef CONFIG_ARM_KERNMEM_PERMS
+ . = ALIGN(1<<SECTION_SHIFT);
+#endif
+
+ .text : { /* Real text segment */
+ _stext = .; /* Text and read-only data */
+ IDMAP_TEXT
+ __exception_text_start = .;
+ *(.exception.text)
+ __exception_text_end = .;
+ IRQENTRY_TEXT
+ TEXT_TEXT
+ SCHED_TEXT
+ LOCK_TEXT
+ KPROBES_TEXT
+ *(.gnu.warning)
+ *(.glue_7)
+ *(.glue_7t)
+ . = ALIGN(4);
+ *(.got) /* Global offset table */
+ ARM_CPU_KEEP(PROC_INFO)
+ }
+
+#ifdef CONFIG_DEBUG_RODATA
+ . = ALIGN(1<<SECTION_SHIFT);
+#endif
+ RO_DATA(PAGE_SIZE)
+
+ . = ALIGN(4);
+ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
+ __start___ex_table = .;
+#ifdef CONFIG_MMU
+ *(__ex_table)
+#endif
+ __stop___ex_table = .;
+ }
+
+#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
+
+ NOTES
+
+ _etext = .; /* End of text and rodata section */
+
+#ifndef CONFIG_XIP_KERNEL
+# ifdef CONFIG_ARM_KERNMEM_PERMS
+ . = ALIGN(1<<SECTION_SHIFT);
+# else
+ . = ALIGN(PAGE_SIZE);
+# endif
+ __init_begin = .;
+#endif
+ /*
+ * The vectors and stubs are relocatable code, and the
+ * only thing that matters is their relative offsets
+ */
+ __vectors_start = .;
+ .vectors 0 : AT(__vectors_start) {
+ *(.vectors)
+ }
+ . = __vectors_start + SIZEOF(.vectors);
+ __vectors_end = .;
+
+ __stubs_start = .;
+ .stubs 0x1000 : AT(__stubs_start) {
+ *(.stubs)
+ }
+ . = __stubs_start + SIZEOF(.stubs);
+ __stubs_end = .;
+
+ INIT_TEXT_SECTION(8)
+ .exit.text : {
+ ARM_EXIT_KEEP(EXIT_TEXT)
+ }
+ .init.proc.info : {
+ ARM_CPU_DISCARD(PROC_INFO)
+ }
+ .init.arch.info : {
+ __arch_info_begin = .;
+ *(.arch.info.init)
+ __arch_info_end = .;
+ }
+ .init.tagtable : {
+ __tagtable_begin = .;
+ *(.taglist.init)
+ __tagtable_end = .;
+ }
+#ifdef CONFIG_SMP_ON_UP
+ .init.smpalt : {
+ __smpalt_begin = .;
+ *(.alt.smp.init)
+ __smpalt_end = .;
+ }
+#endif
+ .init.pv_table : {
+ __pv_table_begin = .;
+ *(.pv_table)
+ __pv_table_end = .;
+ }
+ .init.data : {
+#ifndef CONFIG_XIP_KERNEL
+ INIT_DATA
+#endif
+ INIT_SETUP(16)
+ INIT_CALLS
+ CON_INITCALL
+ SECURITY_INITCALL
+ INIT_RAM_FS
+ }
+#ifndef CONFIG_XIP_KERNEL
+ .exit.data : {
+ ARM_EXIT_KEEP(EXIT_DATA)
+ }
+#endif
+
+#ifdef CONFIG_SMP
+ PERCPU_SECTION(L1_CACHE_BYTES)
+#endif
+
+#ifdef CONFIG_XIP_KERNEL
+ __data_loc = ALIGN(4); /* location in binary */
+ . = PAGE_OFFSET + TEXT_OFFSET;
+#else
+#ifdef CONFIG_ARM_KERNMEM_PERMS
+ . = ALIGN(1<<SECTION_SHIFT);
+#else
+ . = ALIGN(THREAD_SIZE);
+#endif
+ __init_end = .;
+ __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(L1_CACHE_BYTES)
+ READ_MOSTLY_DATA(L1_CACHE_BYTES)
+
+ /*
+ * 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
+
+ BSS_SECTION(0, 0, 0)
+ _end = .;
+
+ STABS_DEBUG
+}
+
+/*
+ * 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")
+
+/*
+ * The HYP init code can't be more than a page long,
+ * and should not cross a page boundary.
+ * The above comment applies as well.
+ */
+ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & PAGE_MASK) <= PAGE_SIZE,
+ "HYP init code too big or misaligned")
diff --git a/arch/arm/kernel/xscale-cp0.c b/arch/arm/kernel/xscale-cp0.c
new file mode 100644
index 000000000..bdbb8853a
--- /dev/null
+++ b/arch/arm/kernel/xscale-cp0.c
@@ -0,0 +1,177 @@
+/*
+ * 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/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
+ pr_warn("CAUTION: XScale iWMMXt coprocessor detected, but kernel support is missing.\n");
+#else
+ pr_info("XScale iWMMXt coprocessor detected.\n");
+ elf_hwcap |= HWCAP_IWMMXT;
+ thread_register_notifier(&iwmmxt_notifier_block);
+#endif
+ } else {
+ pr_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/kvm/Kconfig b/arch/arm/kvm/Kconfig
new file mode 100644
index 000000000..f1f79d104
--- /dev/null
+++ b/arch/arm/kvm/Kconfig
@@ -0,0 +1,58 @@
+#
+# KVM configuration
+#
+
+source "virt/kvm/Kconfig"
+
+menuconfig VIRTUALIZATION
+ bool "Virtualization"
+ ---help---
+ Say Y here to get to see options for using your Linux host to run
+ other operating systems inside virtual machines (guests).
+ This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and
+ disabled.
+
+if VIRTUALIZATION
+
+config KVM
+ bool "Kernel-based Virtual Machine (KVM) support"
+ depends on MMU && OF
+ select PREEMPT_NOTIFIERS
+ select ANON_INODES
+ select HAVE_KVM_CPU_RELAX_INTERCEPT
+ select HAVE_KVM_ARCH_TLB_FLUSH_ALL
+ select KVM_MMIO
+ select KVM_ARM_HOST
+ select KVM_GENERIC_DIRTYLOG_READ_PROTECT
+ select SRCU
+ select MMU_NOTIFIER
+ select HAVE_KVM_EVENTFD
+ select HAVE_KVM_IRQFD
+ depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
+ ---help---
+ Support hosting virtualized guest machines.
+
+ This module provides access to the hardware capabilities through
+ a character device node named /dev/kvm.
+
+ If unsure, say N.
+
+config KVM_ARM_HOST
+ bool
+ ---help---
+ Provides host support for ARM processors.
+
+config KVM_ARM_MAX_VCPUS
+ int "Number maximum supported virtual CPUs per VM"
+ depends on KVM_ARM_HOST
+ default 4
+ help
+ Static number of max supported virtual CPUs per VM.
+
+ If you choose a high number, the vcpu structures will be quite
+ large, so only choose a reasonable number that you expect to
+ actually use.
+
+endif # VIRTUALIZATION
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
new file mode 100644
index 000000000..139e46c08
--- /dev/null
+++ b/arch/arm/kvm/Makefile
@@ -0,0 +1,26 @@
+#
+# Makefile for Kernel-based Virtual Machine module
+#
+
+plus_virt := $(call as-instr,.arch_extension virt,+virt)
+ifeq ($(plus_virt),+virt)
+ plus_virt_def := -DREQUIRES_VIRT=1
+endif
+
+ccflags-y += -Iarch/arm/kvm
+CFLAGS_arm.o := -I. $(plus_virt_def)
+CFLAGS_mmu.o := -I.
+
+AFLAGS_init.o := -Wa,-march=armv7-a$(plus_virt)
+AFLAGS_interrupts.o := -Wa,-march=armv7-a$(plus_virt)
+
+KVM := ../../../virt/kvm
+kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o
+
+obj-y += kvm-arm.o init.o interrupts.o
+obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o
+obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o
+obj-y += $(KVM)/arm/vgic.o
+obj-y += $(KVM)/arm/vgic-v2.o
+obj-y += $(KVM)/arm/vgic-v2-emul.o
+obj-y += $(KVM)/arm/arch_timer.o
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
new file mode 100644
index 000000000..d9631ecdd
--- /dev/null
+++ b/arch/arm/kvm/arm.c
@@ -0,0 +1,1154 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/cpu.h>
+#include <linux/cpu_pm.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/kvm_host.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/mman.h>
+#include <linux/sched.h>
+#include <linux/kvm.h>
+#include <trace/events/kvm.h>
+
+#define CREATE_TRACE_POINTS
+#include "trace.h"
+
+#include <asm/uaccess.h>
+#include <asm/ptrace.h>
+#include <asm/mman.h>
+#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
+#include <asm/virt.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_mmu.h>
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_coproc.h>
+#include <asm/kvm_psci.h>
+
+#ifdef REQUIRES_VIRT
+__asm__(".arch_extension virt");
+#endif
+
+static DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page);
+static kvm_cpu_context_t __percpu *kvm_host_cpu_state;
+static unsigned long hyp_default_vectors;
+
+/* Per-CPU variable containing the currently running vcpu. */
+static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_arm_running_vcpu);
+
+/* The VMID used in the VTTBR */
+static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1);
+static u8 kvm_next_vmid;
+static DEFINE_SPINLOCK(kvm_vmid_lock);
+
+static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu)
+{
+ BUG_ON(preemptible());
+ __this_cpu_write(kvm_arm_running_vcpu, vcpu);
+}
+
+/**
+ * kvm_arm_get_running_vcpu - get the vcpu running on the current CPU.
+ * Must be called from non-preemptible context
+ */
+struct kvm_vcpu *kvm_arm_get_running_vcpu(void)
+{
+ BUG_ON(preemptible());
+ return __this_cpu_read(kvm_arm_running_vcpu);
+}
+
+/**
+ * kvm_arm_get_running_vcpus - get the per-CPU array of currently running vcpus.
+ */
+struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void)
+{
+ return &kvm_arm_running_vcpu;
+}
+
+int kvm_arch_hardware_enable(void)
+{
+ return 0;
+}
+
+int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
+}
+
+int kvm_arch_hardware_setup(void)
+{
+ return 0;
+}
+
+void kvm_arch_check_processor_compat(void *rtn)
+{
+ *(int *)rtn = 0;
+}
+
+
+/**
+ * kvm_arch_init_vm - initializes a VM data structure
+ * @kvm: pointer to the KVM struct
+ */
+int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
+{
+ int ret = 0;
+
+ if (type)
+ return -EINVAL;
+
+ ret = kvm_alloc_stage2_pgd(kvm);
+ if (ret)
+ goto out_fail_alloc;
+
+ ret = create_hyp_mappings(kvm, kvm + 1);
+ if (ret)
+ goto out_free_stage2_pgd;
+
+ kvm_timer_init(kvm);
+
+ /* Mark the initial VMID generation invalid */
+ kvm->arch.vmid_gen = 0;
+
+ /* The maximum number of VCPUs is limited by the host's GIC model */
+ kvm->arch.max_vcpus = kvm_vgic_get_max_vcpus();
+
+ return ret;
+out_free_stage2_pgd:
+ kvm_free_stage2_pgd(kvm);
+out_fail_alloc:
+ return ret;
+}
+
+int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
+{
+ return VM_FAULT_SIGBUS;
+}
+
+
+/**
+ * kvm_arch_destroy_vm - destroy the VM data structure
+ * @kvm: pointer to the KVM struct
+ */
+void kvm_arch_destroy_vm(struct kvm *kvm)
+{
+ int i;
+
+ kvm_free_stage2_pgd(kvm);
+
+ for (i = 0; i < KVM_MAX_VCPUS; ++i) {
+ if (kvm->vcpus[i]) {
+ kvm_arch_vcpu_free(kvm->vcpus[i]);
+ kvm->vcpus[i] = NULL;
+ }
+ }
+
+ kvm_vgic_destroy(kvm);
+}
+
+int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
+{
+ int r;
+ switch (ext) {
+ case KVM_CAP_IRQCHIP:
+ case KVM_CAP_IRQFD:
+ case KVM_CAP_IOEVENTFD:
+ case KVM_CAP_DEVICE_CTRL:
+ case KVM_CAP_USER_MEMORY:
+ case KVM_CAP_SYNC_MMU:
+ case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
+ case KVM_CAP_ONE_REG:
+ case KVM_CAP_ARM_PSCI:
+ case KVM_CAP_ARM_PSCI_0_2:
+ case KVM_CAP_READONLY_MEM:
+ case KVM_CAP_MP_STATE:
+ r = 1;
+ break;
+ case KVM_CAP_COALESCED_MMIO:
+ r = KVM_COALESCED_MMIO_PAGE_OFFSET;
+ break;
+ case KVM_CAP_ARM_SET_DEVICE_ADDR:
+ r = 1;
+ break;
+ case KVM_CAP_NR_VCPUS:
+ r = num_online_cpus();
+ break;
+ case KVM_CAP_MAX_VCPUS:
+ r = KVM_MAX_VCPUS;
+ break;
+ default:
+ r = kvm_arch_dev_ioctl_check_extension(ext);
+ break;
+ }
+ return r;
+}
+
+long kvm_arch_dev_ioctl(struct file *filp,
+ unsigned int ioctl, unsigned long arg)
+{
+ return -EINVAL;
+}
+
+
+struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
+{
+ int err;
+ struct kvm_vcpu *vcpu;
+
+ if (irqchip_in_kernel(kvm) && vgic_initialized(kvm)) {
+ err = -EBUSY;
+ goto out;
+ }
+
+ if (id >= kvm->arch.max_vcpus) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
+ if (!vcpu) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ err = kvm_vcpu_init(vcpu, kvm, id);
+ if (err)
+ goto free_vcpu;
+
+ err = create_hyp_mappings(vcpu, vcpu + 1);
+ if (err)
+ goto vcpu_uninit;
+
+ return vcpu;
+vcpu_uninit:
+ kvm_vcpu_uninit(vcpu);
+free_vcpu:
+ kmem_cache_free(kvm_vcpu_cache, vcpu);
+out:
+ return ERR_PTR(err);
+}
+
+void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
+{
+}
+
+void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
+{
+ kvm_mmu_free_memory_caches(vcpu);
+ kvm_timer_vcpu_terminate(vcpu);
+ kvm_vgic_vcpu_destroy(vcpu);
+ kmem_cache_free(kvm_vcpu_cache, vcpu);
+}
+
+void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
+{
+ kvm_arch_vcpu_free(vcpu);
+}
+
+int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
+{
+ return kvm_timer_should_fire(vcpu);
+}
+
+int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
+{
+ /* Force users to call KVM_ARM_VCPU_INIT */
+ vcpu->arch.target = -1;
+ bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
+
+ /* Set up the timer */
+ kvm_timer_vcpu_init(vcpu);
+
+ return 0;
+}
+
+void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+{
+ vcpu->cpu = cpu;
+ vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state);
+
+ kvm_arm_set_running_vcpu(vcpu);
+}
+
+void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
+{
+ /*
+ * The arch-generic KVM code expects the cpu field of a vcpu to be -1
+ * if the vcpu is no longer assigned to a cpu. This is used for the
+ * optimized make_all_cpus_request path.
+ */
+ vcpu->cpu = -1;
+
+ kvm_arm_set_running_vcpu(NULL);
+}
+
+int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+ struct kvm_guest_debug *dbg)
+{
+ return -EINVAL;
+}
+
+
+int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
+ struct kvm_mp_state *mp_state)
+{
+ if (vcpu->arch.pause)
+ mp_state->mp_state = KVM_MP_STATE_STOPPED;
+ else
+ mp_state->mp_state = KVM_MP_STATE_RUNNABLE;
+
+ return 0;
+}
+
+int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
+ struct kvm_mp_state *mp_state)
+{
+ switch (mp_state->mp_state) {
+ case KVM_MP_STATE_RUNNABLE:
+ vcpu->arch.pause = false;
+ break;
+ case KVM_MP_STATE_STOPPED:
+ vcpu->arch.pause = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * kvm_arch_vcpu_runnable - determine if the vcpu can be scheduled
+ * @v: The VCPU pointer
+ *
+ * If the guest CPU is not waiting for interrupts or an interrupt line is
+ * asserted, the CPU is by definition runnable.
+ */
+int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
+{
+ return !!v->arch.irq_lines || kvm_vgic_vcpu_pending_irq(v);
+}
+
+/* Just ensure a guest exit from a particular CPU */
+static void exit_vm_noop(void *info)
+{
+}
+
+void force_vm_exit(const cpumask_t *mask)
+{
+ smp_call_function_many(mask, exit_vm_noop, NULL, true);
+}
+
+/**
+ * need_new_vmid_gen - check that the VMID is still valid
+ * @kvm: The VM's VMID to checkt
+ *
+ * return true if there is a new generation of VMIDs being used
+ *
+ * The hardware supports only 256 values with the value zero reserved for the
+ * host, so we check if an assigned value belongs to a previous generation,
+ * which which requires us to assign a new value. If we're the first to use a
+ * VMID for the new generation, we must flush necessary caches and TLBs on all
+ * CPUs.
+ */
+static bool need_new_vmid_gen(struct kvm *kvm)
+{
+ return unlikely(kvm->arch.vmid_gen != atomic64_read(&kvm_vmid_gen));
+}
+
+/**
+ * update_vttbr - Update the VTTBR with a valid VMID before the guest runs
+ * @kvm The guest that we are about to run
+ *
+ * Called from kvm_arch_vcpu_ioctl_run before entering the guest to ensure the
+ * VM has a valid VMID, otherwise assigns a new one and flushes corresponding
+ * caches and TLBs.
+ */
+static void update_vttbr(struct kvm *kvm)
+{
+ phys_addr_t pgd_phys;
+ u64 vmid;
+
+ if (!need_new_vmid_gen(kvm))
+ return;
+
+ spin_lock(&kvm_vmid_lock);
+
+ /*
+ * We need to re-check the vmid_gen here to ensure that if another vcpu
+ * already allocated a valid vmid for this vm, then this vcpu should
+ * use the same vmid.
+ */
+ if (!need_new_vmid_gen(kvm)) {
+ spin_unlock(&kvm_vmid_lock);
+ return;
+ }
+
+ /* First user of a new VMID generation? */
+ if (unlikely(kvm_next_vmid == 0)) {
+ atomic64_inc(&kvm_vmid_gen);
+ kvm_next_vmid = 1;
+
+ /*
+ * On SMP we know no other CPUs can use this CPU's or each
+ * other's VMID after force_vm_exit returns since the
+ * kvm_vmid_lock blocks them from reentry to the guest.
+ */
+ force_vm_exit(cpu_all_mask);
+ /*
+ * Now broadcast TLB + ICACHE invalidation over the inner
+ * shareable domain to make sure all data structures are
+ * clean.
+ */
+ kvm_call_hyp(__kvm_flush_vm_context);
+ }
+
+ kvm->arch.vmid_gen = atomic64_read(&kvm_vmid_gen);
+ kvm->arch.vmid = kvm_next_vmid;
+ kvm_next_vmid++;
+
+ /* update vttbr to be used with the new vmid */
+ pgd_phys = virt_to_phys(kvm_get_hwpgd(kvm));
+ BUG_ON(pgd_phys & ~VTTBR_BADDR_MASK);
+ vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK;
+ kvm->arch.vttbr = pgd_phys | vmid;
+
+ spin_unlock(&kvm_vmid_lock);
+}
+
+static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
+{
+ struct kvm *kvm = vcpu->kvm;
+ int ret;
+
+ if (likely(vcpu->arch.has_run_once))
+ return 0;
+
+ vcpu->arch.has_run_once = true;
+
+ /*
+ * Map the VGIC hardware resources before running a vcpu the first
+ * time on this VM.
+ */
+ if (unlikely(!vgic_ready(kvm))) {
+ ret = kvm_vgic_map_resources(kvm);
+ if (ret)
+ return ret;
+ }
+
+ /*
+ * Enable the arch timers only if we have an in-kernel VGIC
+ * and it has been properly initialized, since we cannot handle
+ * interrupts from the virtual timer with a userspace gic.
+ */
+ if (irqchip_in_kernel(kvm) && vgic_initialized(kvm))
+ kvm_timer_enable(kvm);
+
+ return 0;
+}
+
+bool kvm_arch_intc_initialized(struct kvm *kvm)
+{
+ return vgic_initialized(kvm);
+}
+
+static void vcpu_pause(struct kvm_vcpu *vcpu)
+{
+ wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu);
+
+ wait_event_interruptible(*wq, !vcpu->arch.pause);
+}
+
+static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.target >= 0;
+}
+
+/**
+ * kvm_arch_vcpu_ioctl_run - the main VCPU run function to execute guest code
+ * @vcpu: The VCPU pointer
+ * @run: The kvm_run structure pointer used for userspace state exchange
+ *
+ * This function is called through the VCPU_RUN ioctl called from user space. It
+ * will execute VM code in a loop until the time slice for the process is used
+ * or some emulation is needed from user space in which case the function will
+ * return with return value 0 and with the kvm_run structure filled in with the
+ * required data for the requested emulation.
+ */
+int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ int ret;
+ sigset_t sigsaved;
+
+ if (unlikely(!kvm_vcpu_initialized(vcpu)))
+ return -ENOEXEC;
+
+ ret = kvm_vcpu_first_run_init(vcpu);
+ if (ret)
+ return ret;
+
+ if (run->exit_reason == KVM_EXIT_MMIO) {
+ ret = kvm_handle_mmio_return(vcpu, vcpu->run);
+ if (ret)
+ return ret;
+ }
+
+ if (vcpu->sigset_active)
+ sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
+
+ ret = 1;
+ run->exit_reason = KVM_EXIT_UNKNOWN;
+ while (ret > 0) {
+ /*
+ * Check conditions before entering the guest
+ */
+ cond_resched();
+
+ update_vttbr(vcpu->kvm);
+
+ if (vcpu->arch.pause)
+ vcpu_pause(vcpu);
+
+ kvm_vgic_flush_hwstate(vcpu);
+ kvm_timer_flush_hwstate(vcpu);
+
+ local_irq_disable();
+
+ /*
+ * Re-check atomic conditions
+ */
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ run->exit_reason = KVM_EXIT_INTR;
+ }
+
+ if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
+ local_irq_enable();
+ kvm_timer_sync_hwstate(vcpu);
+ kvm_vgic_sync_hwstate(vcpu);
+ continue;
+ }
+
+ /**************************************************************
+ * Enter the guest
+ */
+ trace_kvm_entry(*vcpu_pc(vcpu));
+ kvm_guest_enter();
+ vcpu->mode = IN_GUEST_MODE;
+
+ ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
+
+ vcpu->mode = OUTSIDE_GUEST_MODE;
+ kvm_guest_exit();
+ trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
+ /*
+ * We may have taken a host interrupt in HYP mode (ie
+ * while executing the guest). This interrupt is still
+ * pending, as we haven't serviced it yet!
+ *
+ * We're now back in SVC mode, with interrupts
+ * disabled. Enabling the interrupts now will have
+ * the effect of taking the interrupt again, in SVC
+ * mode this time.
+ */
+ local_irq_enable();
+
+ /*
+ * Back from guest
+ *************************************************************/
+
+ kvm_timer_sync_hwstate(vcpu);
+ kvm_vgic_sync_hwstate(vcpu);
+
+ ret = handle_exit(vcpu, run, ret);
+ }
+
+ if (vcpu->sigset_active)
+ sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+ return ret;
+}
+
+static int vcpu_interrupt_line(struct kvm_vcpu *vcpu, int number, bool level)
+{
+ int bit_index;
+ bool set;
+ unsigned long *ptr;
+
+ if (number == KVM_ARM_IRQ_CPU_IRQ)
+ bit_index = __ffs(HCR_VI);
+ else /* KVM_ARM_IRQ_CPU_FIQ */
+ bit_index = __ffs(HCR_VF);
+
+ ptr = (unsigned long *)&vcpu->arch.irq_lines;
+ if (level)
+ set = test_and_set_bit(bit_index, ptr);
+ else
+ set = test_and_clear_bit(bit_index, ptr);
+
+ /*
+ * If we didn't change anything, no need to wake up or kick other CPUs
+ */
+ if (set == level)
+ return 0;
+
+ /*
+ * The vcpu irq_lines field was updated, wake up sleeping VCPUs and
+ * trigger a world-switch round on the running physical CPU to set the
+ * virtual IRQ/FIQ fields in the HCR appropriately.
+ */
+ kvm_vcpu_kick(vcpu);
+
+ return 0;
+}
+
+int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level,
+ bool line_status)
+{
+ u32 irq = irq_level->irq;
+ unsigned int irq_type, vcpu_idx, irq_num;
+ int nrcpus = atomic_read(&kvm->online_vcpus);
+ struct kvm_vcpu *vcpu = NULL;
+ bool level = irq_level->level;
+
+ irq_type = (irq >> KVM_ARM_IRQ_TYPE_SHIFT) & KVM_ARM_IRQ_TYPE_MASK;
+ vcpu_idx = (irq >> KVM_ARM_IRQ_VCPU_SHIFT) & KVM_ARM_IRQ_VCPU_MASK;
+ irq_num = (irq >> KVM_ARM_IRQ_NUM_SHIFT) & KVM_ARM_IRQ_NUM_MASK;
+
+ trace_kvm_irq_line(irq_type, vcpu_idx, irq_num, irq_level->level);
+
+ switch (irq_type) {
+ case KVM_ARM_IRQ_TYPE_CPU:
+ if (irqchip_in_kernel(kvm))
+ return -ENXIO;
+
+ if (vcpu_idx >= nrcpus)
+ return -EINVAL;
+
+ vcpu = kvm_get_vcpu(kvm, vcpu_idx);
+ if (!vcpu)
+ return -EINVAL;
+
+ if (irq_num > KVM_ARM_IRQ_CPU_FIQ)
+ return -EINVAL;
+
+ return vcpu_interrupt_line(vcpu, irq_num, level);
+ case KVM_ARM_IRQ_TYPE_PPI:
+ if (!irqchip_in_kernel(kvm))
+ return -ENXIO;
+
+ if (vcpu_idx >= nrcpus)
+ return -EINVAL;
+
+ vcpu = kvm_get_vcpu(kvm, vcpu_idx);
+ if (!vcpu)
+ return -EINVAL;
+
+ if (irq_num < VGIC_NR_SGIS || irq_num >= VGIC_NR_PRIVATE_IRQS)
+ return -EINVAL;
+
+ return kvm_vgic_inject_irq(kvm, vcpu->vcpu_id, irq_num, level);
+ case KVM_ARM_IRQ_TYPE_SPI:
+ if (!irqchip_in_kernel(kvm))
+ return -ENXIO;
+
+ if (irq_num < VGIC_NR_PRIVATE_IRQS)
+ return -EINVAL;
+
+ return kvm_vgic_inject_irq(kvm, 0, irq_num, level);
+ }
+
+ return -EINVAL;
+}
+
+static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
+ const struct kvm_vcpu_init *init)
+{
+ unsigned int i;
+ int phys_target = kvm_target_cpu();
+
+ if (init->target != phys_target)
+ return -EINVAL;
+
+ /*
+ * Secondary and subsequent calls to KVM_ARM_VCPU_INIT must
+ * use the same target.
+ */
+ if (vcpu->arch.target != -1 && vcpu->arch.target != init->target)
+ return -EINVAL;
+
+ /* -ENOENT for unknown features, -EINVAL for invalid combinations. */
+ for (i = 0; i < sizeof(init->features) * 8; i++) {
+ bool set = (init->features[i / 32] & (1 << (i % 32)));
+
+ if (set && i >= KVM_VCPU_MAX_FEATURES)
+ return -ENOENT;
+
+ /*
+ * Secondary and subsequent calls to KVM_ARM_VCPU_INIT must
+ * use the same feature set.
+ */
+ if (vcpu->arch.target != -1 && i < KVM_VCPU_MAX_FEATURES &&
+ test_bit(i, vcpu->arch.features) != set)
+ return -EINVAL;
+
+ if (set)
+ set_bit(i, vcpu->arch.features);
+ }
+
+ vcpu->arch.target = phys_target;
+
+ /* Now we know what it is, we can reset it. */
+ return kvm_reset_vcpu(vcpu);
+}
+
+
+static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
+ struct kvm_vcpu_init *init)
+{
+ int ret;
+
+ ret = kvm_vcpu_set_target(vcpu, init);
+ if (ret)
+ return ret;
+
+ /*
+ * Ensure a rebooted VM will fault in RAM pages and detect if the
+ * guest MMU is turned off and flush the caches as needed.
+ */
+ if (vcpu->arch.has_run_once)
+ stage2_unmap_vm(vcpu->kvm);
+
+ vcpu_reset_hcr(vcpu);
+
+ /*
+ * Handle the "start in power-off" case by marking the VCPU as paused.
+ */
+ if (test_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features))
+ vcpu->arch.pause = true;
+ else
+ vcpu->arch.pause = false;
+
+ return 0;
+}
+
+long kvm_arch_vcpu_ioctl(struct file *filp,
+ unsigned int ioctl, unsigned long arg)
+{
+ struct kvm_vcpu *vcpu = filp->private_data;
+ void __user *argp = (void __user *)arg;
+
+ switch (ioctl) {
+ case KVM_ARM_VCPU_INIT: {
+ struct kvm_vcpu_init init;
+
+ if (copy_from_user(&init, argp, sizeof(init)))
+ return -EFAULT;
+
+ return kvm_arch_vcpu_ioctl_vcpu_init(vcpu, &init);
+ }
+ case KVM_SET_ONE_REG:
+ case KVM_GET_ONE_REG: {
+ struct kvm_one_reg reg;
+
+ if (unlikely(!kvm_vcpu_initialized(vcpu)))
+ return -ENOEXEC;
+
+ if (copy_from_user(&reg, argp, sizeof(reg)))
+ return -EFAULT;
+ if (ioctl == KVM_SET_ONE_REG)
+ return kvm_arm_set_reg(vcpu, &reg);
+ else
+ return kvm_arm_get_reg(vcpu, &reg);
+ }
+ case KVM_GET_REG_LIST: {
+ struct kvm_reg_list __user *user_list = argp;
+ struct kvm_reg_list reg_list;
+ unsigned n;
+
+ if (unlikely(!kvm_vcpu_initialized(vcpu)))
+ return -ENOEXEC;
+
+ if (copy_from_user(&reg_list, user_list, sizeof(reg_list)))
+ return -EFAULT;
+ n = reg_list.n;
+ reg_list.n = kvm_arm_num_regs(vcpu);
+ if (copy_to_user(user_list, &reg_list, sizeof(reg_list)))
+ return -EFAULT;
+ if (n < reg_list.n)
+ return -E2BIG;
+ return kvm_arm_copy_reg_indices(vcpu, user_list->reg);
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+/**
+ * kvm_vm_ioctl_get_dirty_log - get and clear the log of dirty pages in a slot
+ * @kvm: kvm instance
+ * @log: slot id and address to which we copy the log
+ *
+ * Steps 1-4 below provide general overview of dirty page logging. See
+ * kvm_get_dirty_log_protect() function description for additional details.
+ *
+ * We call kvm_get_dirty_log_protect() to handle steps 1-3, upon return we
+ * always flush the TLB (step 4) even if previous step failed and the dirty
+ * bitmap may be corrupt. Regardless of previous outcome the KVM logging API
+ * does not preclude user space subsequent dirty log read. Flushing TLB ensures
+ * writes will be marked dirty for next log read.
+ *
+ * 1. Take a snapshot of the bit and clear it if needed.
+ * 2. Write protect the corresponding page.
+ * 3. Copy the snapshot to the userspace.
+ * 4. Flush TLB's if needed.
+ */
+int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+ bool is_dirty = false;
+ int r;
+
+ mutex_lock(&kvm->slots_lock);
+
+ r = kvm_get_dirty_log_protect(kvm, log, &is_dirty);
+
+ if (is_dirty)
+ kvm_flush_remote_tlbs(kvm);
+
+ mutex_unlock(&kvm->slots_lock);
+ return r;
+}
+
+static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
+ struct kvm_arm_device_addr *dev_addr)
+{
+ unsigned long dev_id, type;
+
+ dev_id = (dev_addr->id & KVM_ARM_DEVICE_ID_MASK) >>
+ KVM_ARM_DEVICE_ID_SHIFT;
+ type = (dev_addr->id & KVM_ARM_DEVICE_TYPE_MASK) >>
+ KVM_ARM_DEVICE_TYPE_SHIFT;
+
+ switch (dev_id) {
+ case KVM_ARM_DEVICE_VGIC_V2:
+ return kvm_vgic_addr(kvm, type, &dev_addr->addr, true);
+ default:
+ return -ENODEV;
+ }
+}
+
+long kvm_arch_vm_ioctl(struct file *filp,
+ unsigned int ioctl, unsigned long arg)
+{
+ struct kvm *kvm = filp->private_data;
+ void __user *argp = (void __user *)arg;
+
+ switch (ioctl) {
+ case KVM_CREATE_IRQCHIP: {
+ return kvm_vgic_create(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);
+ }
+ case KVM_ARM_SET_DEVICE_ADDR: {
+ struct kvm_arm_device_addr dev_addr;
+
+ if (copy_from_user(&dev_addr, argp, sizeof(dev_addr)))
+ return -EFAULT;
+ return kvm_vm_ioctl_set_device_addr(kvm, &dev_addr);
+ }
+ case KVM_ARM_PREFERRED_TARGET: {
+ int err;
+ struct kvm_vcpu_init init;
+
+ err = kvm_vcpu_preferred_target(&init);
+ if (err)
+ return err;
+
+ if (copy_to_user(argp, &init, sizeof(init)))
+ return -EFAULT;
+
+ return 0;
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+static void cpu_init_hyp_mode(void *dummy)
+{
+ phys_addr_t boot_pgd_ptr;
+ phys_addr_t pgd_ptr;
+ unsigned long hyp_stack_ptr;
+ unsigned long stack_page;
+ unsigned long vector_ptr;
+
+ /* Switch from the HYP stub to our own HYP init vector */
+ __hyp_set_vectors(kvm_get_idmap_vector());
+
+ boot_pgd_ptr = kvm_mmu_get_boot_httbr();
+ pgd_ptr = kvm_mmu_get_httbr();
+ stack_page = __this_cpu_read(kvm_arm_hyp_stack_page);
+ hyp_stack_ptr = stack_page + PAGE_SIZE;
+ vector_ptr = (unsigned long)__kvm_hyp_vector;
+
+ __cpu_init_hyp_mode(boot_pgd_ptr, pgd_ptr, hyp_stack_ptr, vector_ptr);
+}
+
+static int hyp_init_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *cpu)
+{
+ switch (action) {
+ case CPU_STARTING:
+ case CPU_STARTING_FROZEN:
+ if (__hyp_get_vectors() == hyp_default_vectors)
+ cpu_init_hyp_mode(NULL);
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block hyp_init_cpu_nb = {
+ .notifier_call = hyp_init_cpu_notify,
+};
+
+#ifdef CONFIG_CPU_PM
+static int hyp_init_cpu_pm_notifier(struct notifier_block *self,
+ unsigned long cmd,
+ void *v)
+{
+ if (cmd == CPU_PM_EXIT &&
+ __hyp_get_vectors() == hyp_default_vectors) {
+ cpu_init_hyp_mode(NULL);
+ return NOTIFY_OK;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block hyp_init_cpu_pm_nb = {
+ .notifier_call = hyp_init_cpu_pm_notifier,
+};
+
+static void __init hyp_cpu_pm_init(void)
+{
+ cpu_pm_register_notifier(&hyp_init_cpu_pm_nb);
+}
+#else
+static inline void hyp_cpu_pm_init(void)
+{
+}
+#endif
+
+/**
+ * Inits Hyp-mode on all online CPUs
+ */
+static int init_hyp_mode(void)
+{
+ int cpu;
+ int err = 0;
+
+ /*
+ * Allocate Hyp PGD and setup Hyp identity mapping
+ */
+ err = kvm_mmu_init();
+ if (err)
+ goto out_err;
+
+ /*
+ * It is probably enough to obtain the default on one
+ * CPU. It's unlikely to be different on the others.
+ */
+ hyp_default_vectors = __hyp_get_vectors();
+
+ /*
+ * Allocate stack pages for Hypervisor-mode
+ */
+ for_each_possible_cpu(cpu) {
+ unsigned long stack_page;
+
+ stack_page = __get_free_page(GFP_KERNEL);
+ if (!stack_page) {
+ err = -ENOMEM;
+ goto out_free_stack_pages;
+ }
+
+ per_cpu(kvm_arm_hyp_stack_page, cpu) = stack_page;
+ }
+
+ /*
+ * Map the Hyp-code called directly from the host
+ */
+ err = create_hyp_mappings(__kvm_hyp_code_start, __kvm_hyp_code_end);
+ if (err) {
+ kvm_err("Cannot map world-switch code\n");
+ goto out_free_mappings;
+ }
+
+ /*
+ * Map the Hyp stack pages
+ */
+ for_each_possible_cpu(cpu) {
+ char *stack_page = (char *)per_cpu(kvm_arm_hyp_stack_page, cpu);
+ err = create_hyp_mappings(stack_page, stack_page + PAGE_SIZE);
+
+ if (err) {
+ kvm_err("Cannot map hyp stack\n");
+ goto out_free_mappings;
+ }
+ }
+
+ /*
+ * Map the host CPU structures
+ */
+ kvm_host_cpu_state = alloc_percpu(kvm_cpu_context_t);
+ if (!kvm_host_cpu_state) {
+ err = -ENOMEM;
+ kvm_err("Cannot allocate host CPU state\n");
+ goto out_free_mappings;
+ }
+
+ for_each_possible_cpu(cpu) {
+ kvm_cpu_context_t *cpu_ctxt;
+
+ cpu_ctxt = per_cpu_ptr(kvm_host_cpu_state, cpu);
+ err = create_hyp_mappings(cpu_ctxt, cpu_ctxt + 1);
+
+ if (err) {
+ kvm_err("Cannot map host CPU state: %d\n", err);
+ goto out_free_context;
+ }
+ }
+
+ /*
+ * Execute the init code on each CPU.
+ */
+ on_each_cpu(cpu_init_hyp_mode, NULL, 1);
+
+ /*
+ * Init HYP view of VGIC
+ */
+ err = kvm_vgic_hyp_init();
+ if (err)
+ goto out_free_context;
+
+ /*
+ * Init HYP architected timer support
+ */
+ err = kvm_timer_hyp_init();
+ if (err)
+ goto out_free_mappings;
+
+#ifndef CONFIG_HOTPLUG_CPU
+ free_boot_hyp_pgd();
+#endif
+
+ kvm_perf_init();
+
+ kvm_info("Hyp mode initialized successfully\n");
+
+ return 0;
+out_free_context:
+ free_percpu(kvm_host_cpu_state);
+out_free_mappings:
+ free_hyp_pgds();
+out_free_stack_pages:
+ for_each_possible_cpu(cpu)
+ free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
+out_err:
+ kvm_err("error initializing Hyp mode: %d\n", err);
+ return err;
+}
+
+static void check_kvm_target_cpu(void *ret)
+{
+ *(int *)ret = kvm_target_cpu();
+}
+
+struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr)
+{
+ struct kvm_vcpu *vcpu;
+ int i;
+
+ mpidr &= MPIDR_HWID_BITMASK;
+ kvm_for_each_vcpu(i, vcpu, kvm) {
+ if (mpidr == kvm_vcpu_get_mpidr_aff(vcpu))
+ return vcpu;
+ }
+ return NULL;
+}
+
+/**
+ * Initialize Hyp-mode and memory mappings on all CPUs.
+ */
+int kvm_arch_init(void *opaque)
+{
+ int err;
+ int ret, cpu;
+
+ if (!is_hyp_mode_available()) {
+ kvm_err("HYP mode not available\n");
+ return -ENODEV;
+ }
+
+ for_each_online_cpu(cpu) {
+ smp_call_function_single(cpu, check_kvm_target_cpu, &ret, 1);
+ if (ret < 0) {
+ kvm_err("Error, CPU %d not supported!\n", cpu);
+ return -ENODEV;
+ }
+ }
+
+ cpu_notifier_register_begin();
+
+ err = init_hyp_mode();
+ if (err)
+ goto out_err;
+
+ err = __register_cpu_notifier(&hyp_init_cpu_nb);
+ if (err) {
+ kvm_err("Cannot register HYP init CPU notifier (%d)\n", err);
+ goto out_err;
+ }
+
+ cpu_notifier_register_done();
+
+ hyp_cpu_pm_init();
+
+ kvm_coproc_table_init();
+ return 0;
+out_err:
+ cpu_notifier_register_done();
+ return err;
+}
+
+/* NOP: Compiling as a module not supported */
+void kvm_arch_exit(void)
+{
+ kvm_perf_teardown();
+}
+
+static int arm_init(void)
+{
+ int rc = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
+ return rc;
+}
+
+module_init(arm_init);
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
new file mode 100644
index 000000000..f3d88dc38
--- /dev/null
+++ b/arch/arm/kvm/coproc.c
@@ -0,0 +1,1262 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Authors: Rusty Russell <rusty@rustcorp.com.au>
+ * Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <linux/mm.h>
+#include <linux/kvm_host.h>
+#include <linux/uaccess.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_host.h>
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_coproc.h>
+#include <asm/kvm_mmu.h>
+#include <asm/cacheflush.h>
+#include <asm/cputype.h>
+#include <trace/events/kvm.h>
+#include <asm/vfp.h>
+#include "../vfp/vfpinstr.h"
+
+#include "trace.h"
+#include "coproc.h"
+
+
+/******************************************************************************
+ * Co-processor emulation
+ *****************************************************************************/
+
+/* 3 bits per cache level, as per CLIDR, but non-existent caches always 0 */
+static u32 cache_levels;
+
+/* CSSELR values; used to index KVM_REG_ARM_DEMUX_ID_CCSIDR */
+#define CSSELR_MAX 12
+
+/*
+ * kvm_vcpu_arch.cp15 holds cp15 registers as an array of u32, but some
+ * of cp15 registers can be viewed either as couple of two u32 registers
+ * or one u64 register. Current u64 register encoding is that least
+ * significant u32 word is followed by most significant u32 word.
+ */
+static inline void vcpu_cp15_reg64_set(struct kvm_vcpu *vcpu,
+ const struct coproc_reg *r,
+ u64 val)
+{
+ vcpu->arch.cp15[r->reg] = val & 0xffffffff;
+ vcpu->arch.cp15[r->reg + 1] = val >> 32;
+}
+
+static inline u64 vcpu_cp15_reg64_get(struct kvm_vcpu *vcpu,
+ const struct coproc_reg *r)
+{
+ u64 val;
+
+ val = vcpu->arch.cp15[r->reg + 1];
+ val = val << 32;
+ val = val | vcpu->arch.cp15[r->reg];
+ return val;
+}
+
+int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ kvm_inject_undefined(vcpu);
+ return 1;
+}
+
+int kvm_handle_cp_0_13_access(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ /*
+ * We can get here, if the host has been built without VFPv3 support,
+ * but the guest attempted a floating point operation.
+ */
+ kvm_inject_undefined(vcpu);
+ return 1;
+}
+
+int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ kvm_inject_undefined(vcpu);
+ return 1;
+}
+
+int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ kvm_inject_undefined(vcpu);
+ return 1;
+}
+
+static void reset_mpidr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
+{
+ /*
+ * Compute guest MPIDR. We build a virtual cluster out of the
+ * vcpu_id, but we read the 'U' bit from the underlying
+ * hardware directly.
+ */
+ vcpu->arch.cp15[c0_MPIDR] = ((read_cpuid_mpidr() & MPIDR_SMP_BITMASK) |
+ ((vcpu->vcpu_id >> 2) << MPIDR_LEVEL_BITS) |
+ (vcpu->vcpu_id & 3));
+}
+
+/* TRM entries A7:4.3.31 A15:4.3.28 - RO WI */
+static bool access_actlr(struct kvm_vcpu *vcpu,
+ const struct coproc_params *p,
+ const struct coproc_reg *r)
+{
+ if (p->is_write)
+ return ignore_write(vcpu, p);
+
+ *vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp15[c1_ACTLR];
+ return true;
+}
+
+/* TRM entries A7:4.3.56, A15:4.3.60 - R/O. */
+static bool access_cbar(struct kvm_vcpu *vcpu,
+ const struct coproc_params *p,
+ const struct coproc_reg *r)
+{
+ if (p->is_write)
+ return write_to_read_only(vcpu, p);
+ return read_zero(vcpu, p);
+}
+
+/* TRM entries A7:4.3.49, A15:4.3.48 - R/O WI */
+static bool access_l2ctlr(struct kvm_vcpu *vcpu,
+ const struct coproc_params *p,
+ const struct coproc_reg *r)
+{
+ if (p->is_write)
+ return ignore_write(vcpu, p);
+
+ *vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp15[c9_L2CTLR];
+ return true;
+}
+
+static void reset_l2ctlr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
+{
+ u32 l2ctlr, ncores;
+
+ asm volatile("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr));
+ l2ctlr &= ~(3 << 24);
+ ncores = atomic_read(&vcpu->kvm->online_vcpus) - 1;
+ /* How many cores in the current cluster and the next ones */
+ ncores -= (vcpu->vcpu_id & ~3);
+ /* Cap it to the maximum number of cores in a single cluster */
+ ncores = min(ncores, 3U);
+ l2ctlr |= (ncores & 3) << 24;
+
+ vcpu->arch.cp15[c9_L2CTLR] = l2ctlr;
+}
+
+static void reset_actlr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
+{
+ u32 actlr;
+
+ /* ACTLR contains SMP bit: make sure you create all cpus first! */
+ asm volatile("mrc p15, 0, %0, c1, c0, 1\n" : "=r" (actlr));
+ /* Make the SMP bit consistent with the guest configuration */
+ if (atomic_read(&vcpu->kvm->online_vcpus) > 1)
+ actlr |= 1U << 6;
+ else
+ actlr &= ~(1U << 6);
+
+ vcpu->arch.cp15[c1_ACTLR] = actlr;
+}
+
+/*
+ * TRM entries: A7:4.3.50, A15:4.3.49
+ * R/O WI (even if NSACR.NS_L2ERR, a write of 1 is ignored).
+ */
+static bool access_l2ectlr(struct kvm_vcpu *vcpu,
+ const struct coproc_params *p,
+ const struct coproc_reg *r)
+{
+ if (p->is_write)
+ return ignore_write(vcpu, p);
+
+ *vcpu_reg(vcpu, p->Rt1) = 0;
+ return true;
+}
+
+/*
+ * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized).
+ */
+static bool access_dcsw(struct kvm_vcpu *vcpu,
+ const struct coproc_params *p,
+ const struct coproc_reg *r)
+{
+ if (!p->is_write)
+ return read_from_write_only(vcpu, p);
+
+ kvm_set_way_flush(vcpu);
+ return true;
+}
+
+/*
+ * Generic accessor for VM registers. Only called as long as HCR_TVM
+ * is set. If the guest enables the MMU, we stop trapping the VM
+ * sys_regs and leave it in complete control of the caches.
+ *
+ * Used by the cpu-specific code.
+ */
+bool access_vm_reg(struct kvm_vcpu *vcpu,
+ const struct coproc_params *p,
+ const struct coproc_reg *r)
+{
+ bool was_enabled = vcpu_has_cache_enabled(vcpu);
+
+ BUG_ON(!p->is_write);
+
+ vcpu->arch.cp15[r->reg] = *vcpu_reg(vcpu, p->Rt1);
+ if (p->is_64bit)
+ vcpu->arch.cp15[r->reg + 1] = *vcpu_reg(vcpu, p->Rt2);
+
+ kvm_toggle_cache(vcpu, was_enabled);
+ return true;
+}
+
+/*
+ * We could trap ID_DFR0 and tell the guest we don't support performance
+ * monitoring. Unfortunately the patch to make the kernel check ID_DFR0 was
+ * NAKed, so it will read the PMCR anyway.
+ *
+ * Therefore we tell the guest we have 0 counters. Unfortunately, we
+ * must always support PMCCNTR (the cycle counter): we just RAZ/WI for
+ * all PM registers, which doesn't crash the guest kernel at least.
+ */
+static bool pm_fake(struct kvm_vcpu *vcpu,
+ const struct coproc_params *p,
+ const struct coproc_reg *r)
+{
+ if (p->is_write)
+ return ignore_write(vcpu, p);
+ else
+ return read_zero(vcpu, p);
+}
+
+#define access_pmcr pm_fake
+#define access_pmcntenset pm_fake
+#define access_pmcntenclr pm_fake
+#define access_pmovsr pm_fake
+#define access_pmselr pm_fake
+#define access_pmceid0 pm_fake
+#define access_pmceid1 pm_fake
+#define access_pmccntr pm_fake
+#define access_pmxevtyper pm_fake
+#define access_pmxevcntr pm_fake
+#define access_pmuserenr pm_fake
+#define access_pmintenset pm_fake
+#define access_pmintenclr pm_fake
+
+/* Architected CP15 registers.
+ * CRn denotes the primary register number, but is copied to the CRm in the
+ * user space API for 64-bit register access in line with the terminology used
+ * in the ARM ARM.
+ * Important: Must be sorted ascending by CRn, CRM, Op1, Op2 and with 64-bit
+ * registers preceding 32-bit ones.
+ */
+static const struct coproc_reg cp15_regs[] = {
+ /* MPIDR: we use VMPIDR for guest access. */
+ { CRn( 0), CRm( 0), Op1( 0), Op2( 5), is32,
+ NULL, reset_mpidr, c0_MPIDR },
+
+ /* CSSELR: swapped by interrupt.S. */
+ { CRn( 0), CRm( 0), Op1( 2), Op2( 0), is32,
+ NULL, reset_unknown, c0_CSSELR },
+
+ /* ACTLR: trapped by HCR.TAC bit. */
+ { CRn( 1), CRm( 0), Op1( 0), Op2( 1), is32,
+ access_actlr, reset_actlr, c1_ACTLR },
+
+ /* CPACR: swapped by interrupt.S. */
+ { CRn( 1), CRm( 0), Op1( 0), Op2( 2), is32,
+ NULL, reset_val, c1_CPACR, 0x00000000 },
+
+ /* TTBR0/TTBR1/TTBCR: swapped by interrupt.S. */
+ { CRm64( 2), Op1( 0), is64, access_vm_reg, reset_unknown64, c2_TTBR0 },
+ { CRn(2), CRm( 0), Op1( 0), Op2( 0), is32,
+ access_vm_reg, reset_unknown, c2_TTBR0 },
+ { CRn(2), CRm( 0), Op1( 0), Op2( 1), is32,
+ access_vm_reg, reset_unknown, c2_TTBR1 },
+ { CRn( 2), CRm( 0), Op1( 0), Op2( 2), is32,
+ access_vm_reg, reset_val, c2_TTBCR, 0x00000000 },
+ { CRm64( 2), Op1( 1), is64, access_vm_reg, reset_unknown64, c2_TTBR1 },
+
+
+ /* DACR: swapped by interrupt.S. */
+ { CRn( 3), CRm( 0), Op1( 0), Op2( 0), is32,
+ access_vm_reg, reset_unknown, c3_DACR },
+
+ /* DFSR/IFSR/ADFSR/AIFSR: swapped by interrupt.S. */
+ { CRn( 5), CRm( 0), Op1( 0), Op2( 0), is32,
+ access_vm_reg, reset_unknown, c5_DFSR },
+ { CRn( 5), CRm( 0), Op1( 0), Op2( 1), is32,
+ access_vm_reg, reset_unknown, c5_IFSR },
+ { CRn( 5), CRm( 1), Op1( 0), Op2( 0), is32,
+ access_vm_reg, reset_unknown, c5_ADFSR },
+ { CRn( 5), CRm( 1), Op1( 0), Op2( 1), is32,
+ access_vm_reg, reset_unknown, c5_AIFSR },
+
+ /* DFAR/IFAR: swapped by interrupt.S. */
+ { CRn( 6), CRm( 0), Op1( 0), Op2( 0), is32,
+ access_vm_reg, reset_unknown, c6_DFAR },
+ { CRn( 6), CRm( 0), Op1( 0), Op2( 2), is32,
+ access_vm_reg, reset_unknown, c6_IFAR },
+
+ /* PAR swapped by interrupt.S */
+ { CRm64( 7), Op1( 0), is64, NULL, reset_unknown64, c7_PAR },
+
+ /*
+ * DC{C,I,CI}SW operations:
+ */
+ { CRn( 7), CRm( 6), Op1( 0), Op2( 2), is32, access_dcsw},
+ { CRn( 7), CRm(10), Op1( 0), Op2( 2), is32, access_dcsw},
+ { CRn( 7), CRm(14), Op1( 0), Op2( 2), is32, access_dcsw},
+ /*
+ * L2CTLR access (guest wants to know #CPUs).
+ */
+ { CRn( 9), CRm( 0), Op1( 1), Op2( 2), is32,
+ access_l2ctlr, reset_l2ctlr, c9_L2CTLR },
+ { CRn( 9), CRm( 0), Op1( 1), Op2( 3), is32, access_l2ectlr},
+
+ /*
+ * Dummy performance monitor implementation.
+ */
+ { CRn( 9), CRm(12), Op1( 0), Op2( 0), is32, access_pmcr},
+ { CRn( 9), CRm(12), Op1( 0), Op2( 1), is32, access_pmcntenset},
+ { CRn( 9), CRm(12), Op1( 0), Op2( 2), is32, access_pmcntenclr},
+ { CRn( 9), CRm(12), Op1( 0), Op2( 3), is32, access_pmovsr},
+ { CRn( 9), CRm(12), Op1( 0), Op2( 5), is32, access_pmselr},
+ { CRn( 9), CRm(12), Op1( 0), Op2( 6), is32, access_pmceid0},
+ { CRn( 9), CRm(12), Op1( 0), Op2( 7), is32, access_pmceid1},
+ { CRn( 9), CRm(13), Op1( 0), Op2( 0), is32, access_pmccntr},
+ { CRn( 9), CRm(13), Op1( 0), Op2( 1), is32, access_pmxevtyper},
+ { CRn( 9), CRm(13), Op1( 0), Op2( 2), is32, access_pmxevcntr},
+ { CRn( 9), CRm(14), Op1( 0), Op2( 0), is32, access_pmuserenr},
+ { CRn( 9), CRm(14), Op1( 0), Op2( 1), is32, access_pmintenset},
+ { CRn( 9), CRm(14), Op1( 0), Op2( 2), is32, access_pmintenclr},
+
+ /* PRRR/NMRR (aka MAIR0/MAIR1): swapped by interrupt.S. */
+ { CRn(10), CRm( 2), Op1( 0), Op2( 0), is32,
+ access_vm_reg, reset_unknown, c10_PRRR},
+ { CRn(10), CRm( 2), Op1( 0), Op2( 1), is32,
+ access_vm_reg, reset_unknown, c10_NMRR},
+
+ /* AMAIR0/AMAIR1: swapped by interrupt.S. */
+ { CRn(10), CRm( 3), Op1( 0), Op2( 0), is32,
+ access_vm_reg, reset_unknown, c10_AMAIR0},
+ { CRn(10), CRm( 3), Op1( 0), Op2( 1), is32,
+ access_vm_reg, reset_unknown, c10_AMAIR1},
+
+ /* VBAR: swapped by interrupt.S. */
+ { CRn(12), CRm( 0), Op1( 0), Op2( 0), is32,
+ NULL, reset_val, c12_VBAR, 0x00000000 },
+
+ /* CONTEXTIDR/TPIDRURW/TPIDRURO/TPIDRPRW: swapped by interrupt.S. */
+ { CRn(13), CRm( 0), Op1( 0), Op2( 1), is32,
+ access_vm_reg, reset_val, c13_CID, 0x00000000 },
+ { CRn(13), CRm( 0), Op1( 0), Op2( 2), is32,
+ NULL, reset_unknown, c13_TID_URW },
+ { CRn(13), CRm( 0), Op1( 0), Op2( 3), is32,
+ NULL, reset_unknown, c13_TID_URO },
+ { CRn(13), CRm( 0), Op1( 0), Op2( 4), is32,
+ NULL, reset_unknown, c13_TID_PRIV },
+
+ /* CNTKCTL: swapped by interrupt.S. */
+ { CRn(14), CRm( 1), Op1( 0), Op2( 0), is32,
+ NULL, reset_val, c14_CNTKCTL, 0x00000000 },
+
+ /* The Configuration Base Address Register. */
+ { CRn(15), CRm( 0), Op1( 4), Op2( 0), is32, access_cbar},
+};
+
+/* Target specific emulation tables */
+static struct kvm_coproc_target_table *target_tables[KVM_ARM_NUM_TARGETS];
+
+void kvm_register_target_coproc_table(struct kvm_coproc_target_table *table)
+{
+ unsigned int i;
+
+ for (i = 1; i < table->num; i++)
+ BUG_ON(cmp_reg(&table->table[i-1],
+ &table->table[i]) >= 0);
+
+ target_tables[table->target] = table;
+}
+
+/* Get specific register table for this target. */
+static const struct coproc_reg *get_target_table(unsigned target, size_t *num)
+{
+ struct kvm_coproc_target_table *table;
+
+ table = target_tables[target];
+ *num = table->num;
+ return table->table;
+}
+
+static const struct coproc_reg *find_reg(const struct coproc_params *params,
+ const struct coproc_reg table[],
+ unsigned int num)
+{
+ unsigned int i;
+
+ for (i = 0; i < num; i++) {
+ const struct coproc_reg *r = &table[i];
+
+ if (params->is_64bit != r->is_64)
+ continue;
+ if (params->CRn != r->CRn)
+ continue;
+ if (params->CRm != r->CRm)
+ continue;
+ if (params->Op1 != r->Op1)
+ continue;
+ if (params->Op2 != r->Op2)
+ continue;
+
+ return r;
+ }
+ return NULL;
+}
+
+static int emulate_cp15(struct kvm_vcpu *vcpu,
+ const struct coproc_params *params)
+{
+ size_t num;
+ const struct coproc_reg *table, *r;
+
+ trace_kvm_emulate_cp15_imp(params->Op1, params->Rt1, params->CRn,
+ params->CRm, params->Op2, params->is_write);
+
+ table = get_target_table(vcpu->arch.target, &num);
+
+ /* Search target-specific then generic table. */
+ r = find_reg(params, table, num);
+ if (!r)
+ r = find_reg(params, cp15_regs, ARRAY_SIZE(cp15_regs));
+
+ if (likely(r)) {
+ /* If we don't have an accessor, we should never get here! */
+ BUG_ON(!r->access);
+
+ if (likely(r->access(vcpu, params, r))) {
+ /* Skip instruction, since it was emulated */
+ kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+ return 1;
+ }
+ /* If access function fails, it should complain. */
+ } else {
+ kvm_err("Unsupported guest CP15 access at: %08lx\n",
+ *vcpu_pc(vcpu));
+ print_cp_instr(params);
+ }
+ kvm_inject_undefined(vcpu);
+ return 1;
+}
+
+/**
+ * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
+ * @vcpu: The VCPU pointer
+ * @run: The kvm_run struct
+ */
+int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ struct coproc_params params;
+
+ params.CRn = (kvm_vcpu_get_hsr(vcpu) >> 1) & 0xf;
+ params.Rt1 = (kvm_vcpu_get_hsr(vcpu) >> 5) & 0xf;
+ params.is_write = ((kvm_vcpu_get_hsr(vcpu) & 1) == 0);
+ params.is_64bit = true;
+
+ params.Op1 = (kvm_vcpu_get_hsr(vcpu) >> 16) & 0xf;
+ params.Op2 = 0;
+ params.Rt2 = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf;
+ params.CRm = 0;
+
+ return emulate_cp15(vcpu, &params);
+}
+
+static void reset_coproc_regs(struct kvm_vcpu *vcpu,
+ const struct coproc_reg *table, size_t num)
+{
+ unsigned long i;
+
+ for (i = 0; i < num; i++)
+ if (table[i].reset)
+ table[i].reset(vcpu, &table[i]);
+}
+
+/**
+ * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access
+ * @vcpu: The VCPU pointer
+ * @run: The kvm_run struct
+ */
+int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ struct coproc_params params;
+
+ params.CRm = (kvm_vcpu_get_hsr(vcpu) >> 1) & 0xf;
+ params.Rt1 = (kvm_vcpu_get_hsr(vcpu) >> 5) & 0xf;
+ params.is_write = ((kvm_vcpu_get_hsr(vcpu) & 1) == 0);
+ params.is_64bit = false;
+
+ params.CRn = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf;
+ params.Op1 = (kvm_vcpu_get_hsr(vcpu) >> 14) & 0x7;
+ params.Op2 = (kvm_vcpu_get_hsr(vcpu) >> 17) & 0x7;
+ params.Rt2 = 0;
+
+ return emulate_cp15(vcpu, &params);
+}
+
+/******************************************************************************
+ * Userspace API
+ *****************************************************************************/
+
+static bool index_to_params(u64 id, struct coproc_params *params)
+{
+ switch (id & KVM_REG_SIZE_MASK) {
+ case KVM_REG_SIZE_U32:
+ /* Any unused index bits means it's not valid. */
+ if (id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK
+ | KVM_REG_ARM_COPROC_MASK
+ | KVM_REG_ARM_32_CRN_MASK
+ | KVM_REG_ARM_CRM_MASK
+ | KVM_REG_ARM_OPC1_MASK
+ | KVM_REG_ARM_32_OPC2_MASK))
+ return false;
+
+ params->is_64bit = false;
+ params->CRn = ((id & KVM_REG_ARM_32_CRN_MASK)
+ >> KVM_REG_ARM_32_CRN_SHIFT);
+ params->CRm = ((id & KVM_REG_ARM_CRM_MASK)
+ >> KVM_REG_ARM_CRM_SHIFT);
+ params->Op1 = ((id & KVM_REG_ARM_OPC1_MASK)
+ >> KVM_REG_ARM_OPC1_SHIFT);
+ params->Op2 = ((id & KVM_REG_ARM_32_OPC2_MASK)
+ >> KVM_REG_ARM_32_OPC2_SHIFT);
+ return true;
+ case KVM_REG_SIZE_U64:
+ /* Any unused index bits means it's not valid. */
+ if (id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK
+ | KVM_REG_ARM_COPROC_MASK
+ | KVM_REG_ARM_CRM_MASK
+ | KVM_REG_ARM_OPC1_MASK))
+ return false;
+ params->is_64bit = true;
+ /* CRm to CRn: see cp15_to_index for details */
+ params->CRn = ((id & KVM_REG_ARM_CRM_MASK)
+ >> KVM_REG_ARM_CRM_SHIFT);
+ params->Op1 = ((id & KVM_REG_ARM_OPC1_MASK)
+ >> KVM_REG_ARM_OPC1_SHIFT);
+ params->Op2 = 0;
+ params->CRm = 0;
+ return true;
+ default:
+ return false;
+ }
+}
+
+/* Decode an index value, and find the cp15 coproc_reg entry. */
+static const struct coproc_reg *index_to_coproc_reg(struct kvm_vcpu *vcpu,
+ u64 id)
+{
+ size_t num;
+ const struct coproc_reg *table, *r;
+ struct coproc_params params;
+
+ /* We only do cp15 for now. */
+ if ((id & KVM_REG_ARM_COPROC_MASK) >> KVM_REG_ARM_COPROC_SHIFT != 15)
+ return NULL;
+
+ if (!index_to_params(id, &params))
+ return NULL;
+
+ table = get_target_table(vcpu->arch.target, &num);
+ r = find_reg(&params, table, num);
+ if (!r)
+ r = find_reg(&params, cp15_regs, ARRAY_SIZE(cp15_regs));
+
+ /* Not saved in the cp15 array? */
+ if (r && !r->reg)
+ r = NULL;
+
+ return r;
+}
+
+/*
+ * These are the invariant cp15 registers: we let the guest see the host
+ * versions of these, so they're part of the guest state.
+ *
+ * A future CPU may provide a mechanism to present different values to
+ * the guest, or a future kvm may trap them.
+ */
+/* Unfortunately, there's no register-argument for mrc, so generate. */
+#define FUNCTION_FOR32(crn, crm, op1, op2, name) \
+ static void get_##name(struct kvm_vcpu *v, \
+ const struct coproc_reg *r) \
+ { \
+ u32 val; \
+ \
+ asm volatile("mrc p15, " __stringify(op1) \
+ ", %0, c" __stringify(crn) \
+ ", c" __stringify(crm) \
+ ", " __stringify(op2) "\n" : "=r" (val)); \
+ ((struct coproc_reg *)r)->val = val; \
+ }
+
+FUNCTION_FOR32(0, 0, 0, 0, MIDR)
+FUNCTION_FOR32(0, 0, 0, 1, CTR)
+FUNCTION_FOR32(0, 0, 0, 2, TCMTR)
+FUNCTION_FOR32(0, 0, 0, 3, TLBTR)
+FUNCTION_FOR32(0, 0, 0, 6, REVIDR)
+FUNCTION_FOR32(0, 1, 0, 0, ID_PFR0)
+FUNCTION_FOR32(0, 1, 0, 1, ID_PFR1)
+FUNCTION_FOR32(0, 1, 0, 2, ID_DFR0)
+FUNCTION_FOR32(0, 1, 0, 3, ID_AFR0)
+FUNCTION_FOR32(0, 1, 0, 4, ID_MMFR0)
+FUNCTION_FOR32(0, 1, 0, 5, ID_MMFR1)
+FUNCTION_FOR32(0, 1, 0, 6, ID_MMFR2)
+FUNCTION_FOR32(0, 1, 0, 7, ID_MMFR3)
+FUNCTION_FOR32(0, 2, 0, 0, ID_ISAR0)
+FUNCTION_FOR32(0, 2, 0, 1, ID_ISAR1)
+FUNCTION_FOR32(0, 2, 0, 2, ID_ISAR2)
+FUNCTION_FOR32(0, 2, 0, 3, ID_ISAR3)
+FUNCTION_FOR32(0, 2, 0, 4, ID_ISAR4)
+FUNCTION_FOR32(0, 2, 0, 5, ID_ISAR5)
+FUNCTION_FOR32(0, 0, 1, 1, CLIDR)
+FUNCTION_FOR32(0, 0, 1, 7, AIDR)
+
+/* ->val is filled in by kvm_invariant_coproc_table_init() */
+static struct coproc_reg invariant_cp15[] = {
+ { CRn( 0), CRm( 0), Op1( 0), Op2( 0), is32, NULL, get_MIDR },
+ { CRn( 0), CRm( 0), Op1( 0), Op2( 1), is32, NULL, get_CTR },
+ { CRn( 0), CRm( 0), Op1( 0), Op2( 2), is32, NULL, get_TCMTR },
+ { CRn( 0), CRm( 0), Op1( 0), Op2( 3), is32, NULL, get_TLBTR },
+ { CRn( 0), CRm( 0), Op1( 0), Op2( 6), is32, NULL, get_REVIDR },
+
+ { CRn( 0), CRm( 1), Op1( 0), Op2( 0), is32, NULL, get_ID_PFR0 },
+ { CRn( 0), CRm( 1), Op1( 0), Op2( 1), is32, NULL, get_ID_PFR1 },
+ { CRn( 0), CRm( 1), Op1( 0), Op2( 2), is32, NULL, get_ID_DFR0 },
+ { CRn( 0), CRm( 1), Op1( 0), Op2( 3), is32, NULL, get_ID_AFR0 },
+ { CRn( 0), CRm( 1), Op1( 0), Op2( 4), is32, NULL, get_ID_MMFR0 },
+ { CRn( 0), CRm( 1), Op1( 0), Op2( 5), is32, NULL, get_ID_MMFR1 },
+ { CRn( 0), CRm( 1), Op1( 0), Op2( 6), is32, NULL, get_ID_MMFR2 },
+ { CRn( 0), CRm( 1), Op1( 0), Op2( 7), is32, NULL, get_ID_MMFR3 },
+
+ { CRn( 0), CRm( 2), Op1( 0), Op2( 0), is32, NULL, get_ID_ISAR0 },
+ { CRn( 0), CRm( 2), Op1( 0), Op2( 1), is32, NULL, get_ID_ISAR1 },
+ { CRn( 0), CRm( 2), Op1( 0), Op2( 2), is32, NULL, get_ID_ISAR2 },
+ { CRn( 0), CRm( 2), Op1( 0), Op2( 3), is32, NULL, get_ID_ISAR3 },
+ { CRn( 0), CRm( 2), Op1( 0), Op2( 4), is32, NULL, get_ID_ISAR4 },
+ { CRn( 0), CRm( 2), Op1( 0), Op2( 5), is32, NULL, get_ID_ISAR5 },
+
+ { CRn( 0), CRm( 0), Op1( 1), Op2( 1), is32, NULL, get_CLIDR },
+ { CRn( 0), CRm( 0), Op1( 1), Op2( 7), is32, NULL, get_AIDR },
+};
+
+/*
+ * Reads a register value from a userspace address to a kernel
+ * variable. Make sure that register size matches sizeof(*__val).
+ */
+static int reg_from_user(void *val, const void __user *uaddr, u64 id)
+{
+ if (copy_from_user(val, uaddr, KVM_REG_SIZE(id)) != 0)
+ return -EFAULT;
+ return 0;
+}
+
+/*
+ * Writes a register value to a userspace address from a kernel variable.
+ * Make sure that register size matches sizeof(*__val).
+ */
+static int reg_to_user(void __user *uaddr, const void *val, u64 id)
+{
+ if (copy_to_user(uaddr, val, KVM_REG_SIZE(id)) != 0)
+ return -EFAULT;
+ return 0;
+}
+
+static int get_invariant_cp15(u64 id, void __user *uaddr)
+{
+ struct coproc_params params;
+ const struct coproc_reg *r;
+ int ret;
+
+ if (!index_to_params(id, &params))
+ return -ENOENT;
+
+ r = find_reg(&params, invariant_cp15, ARRAY_SIZE(invariant_cp15));
+ if (!r)
+ return -ENOENT;
+
+ ret = -ENOENT;
+ if (KVM_REG_SIZE(id) == 4) {
+ u32 val = r->val;
+
+ ret = reg_to_user(uaddr, &val, id);
+ } else if (KVM_REG_SIZE(id) == 8) {
+ ret = reg_to_user(uaddr, &r->val, id);
+ }
+ return ret;
+}
+
+static int set_invariant_cp15(u64 id, void __user *uaddr)
+{
+ struct coproc_params params;
+ const struct coproc_reg *r;
+ int err;
+ u64 val;
+
+ if (!index_to_params(id, &params))
+ return -ENOENT;
+ r = find_reg(&params, invariant_cp15, ARRAY_SIZE(invariant_cp15));
+ if (!r)
+ return -ENOENT;
+
+ err = -ENOENT;
+ if (KVM_REG_SIZE(id) == 4) {
+ u32 val32;
+
+ err = reg_from_user(&val32, uaddr, id);
+ if (!err)
+ val = val32;
+ } else if (KVM_REG_SIZE(id) == 8) {
+ err = reg_from_user(&val, uaddr, id);
+ }
+ if (err)
+ return err;
+
+ /* This is what we mean by invariant: you can't change it. */
+ if (r->val != val)
+ return -EINVAL;
+
+ return 0;
+}
+
+static bool is_valid_cache(u32 val)
+{
+ u32 level, ctype;
+
+ if (val >= CSSELR_MAX)
+ return false;
+
+ /* Bottom bit is Instruction or Data bit. Next 3 bits are level. */
+ level = (val >> 1);
+ ctype = (cache_levels >> (level * 3)) & 7;
+
+ switch (ctype) {
+ case 0: /* No cache */
+ return false;
+ case 1: /* Instruction cache only */
+ return (val & 1);
+ case 2: /* Data cache only */
+ case 4: /* Unified cache */
+ return !(val & 1);
+ case 3: /* Separate instruction and data caches */
+ return true;
+ default: /* Reserved: we can't know instruction or data. */
+ return false;
+ }
+}
+
+/* Which cache CCSIDR represents depends on CSSELR value. */
+static u32 get_ccsidr(u32 csselr)
+{
+ u32 ccsidr;
+
+ /* Make sure noone else changes CSSELR during this! */
+ local_irq_disable();
+ /* Put value into CSSELR */
+ asm volatile("mcr p15, 2, %0, c0, c0, 0" : : "r" (csselr));
+ isb();
+ /* Read result out of CCSIDR */
+ asm volatile("mrc p15, 1, %0, c0, c0, 0" : "=r" (ccsidr));
+ local_irq_enable();
+
+ return ccsidr;
+}
+
+static int demux_c15_get(u64 id, void __user *uaddr)
+{
+ u32 val;
+ u32 __user *uval = uaddr;
+
+ /* Fail if we have unknown bits set. */
+ if (id & ~(KVM_REG_ARCH_MASK|KVM_REG_SIZE_MASK|KVM_REG_ARM_COPROC_MASK
+ | ((1 << KVM_REG_ARM_COPROC_SHIFT)-1)))
+ return -ENOENT;
+
+ switch (id & KVM_REG_ARM_DEMUX_ID_MASK) {
+ case KVM_REG_ARM_DEMUX_ID_CCSIDR:
+ if (KVM_REG_SIZE(id) != 4)
+ return -ENOENT;
+ val = (id & KVM_REG_ARM_DEMUX_VAL_MASK)
+ >> KVM_REG_ARM_DEMUX_VAL_SHIFT;
+ if (!is_valid_cache(val))
+ return -ENOENT;
+
+ return put_user(get_ccsidr(val), uval);
+ default:
+ return -ENOENT;
+ }
+}
+
+static int demux_c15_set(u64 id, void __user *uaddr)
+{
+ u32 val, newval;
+ u32 __user *uval = uaddr;
+
+ /* Fail if we have unknown bits set. */
+ if (id & ~(KVM_REG_ARCH_MASK|KVM_REG_SIZE_MASK|KVM_REG_ARM_COPROC_MASK
+ | ((1 << KVM_REG_ARM_COPROC_SHIFT)-1)))
+ return -ENOENT;
+
+ switch (id & KVM_REG_ARM_DEMUX_ID_MASK) {
+ case KVM_REG_ARM_DEMUX_ID_CCSIDR:
+ if (KVM_REG_SIZE(id) != 4)
+ return -ENOENT;
+ val = (id & KVM_REG_ARM_DEMUX_VAL_MASK)
+ >> KVM_REG_ARM_DEMUX_VAL_SHIFT;
+ if (!is_valid_cache(val))
+ return -ENOENT;
+
+ if (get_user(newval, uval))
+ return -EFAULT;
+
+ /* This is also invariant: you can't change it. */
+ if (newval != get_ccsidr(val))
+ return -EINVAL;
+ return 0;
+ default:
+ return -ENOENT;
+ }
+}
+
+#ifdef CONFIG_VFPv3
+static const int vfp_sysregs[] = { KVM_REG_ARM_VFP_FPEXC,
+ KVM_REG_ARM_VFP_FPSCR,
+ KVM_REG_ARM_VFP_FPINST,
+ KVM_REG_ARM_VFP_FPINST2,
+ KVM_REG_ARM_VFP_MVFR0,
+ KVM_REG_ARM_VFP_MVFR1,
+ KVM_REG_ARM_VFP_FPSID };
+
+static unsigned int num_fp_regs(void)
+{
+ if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK) >> MVFR0_A_SIMD_BIT) == 2)
+ return 32;
+ else
+ return 16;
+}
+
+static unsigned int num_vfp_regs(void)
+{
+ /* Normal FP regs + control regs. */
+ return num_fp_regs() + ARRAY_SIZE(vfp_sysregs);
+}
+
+static int copy_vfp_regids(u64 __user *uindices)
+{
+ unsigned int i;
+ const u64 u32reg = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP;
+ const u64 u64reg = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;
+
+ for (i = 0; i < num_fp_regs(); i++) {
+ if (put_user((u64reg | KVM_REG_ARM_VFP_BASE_REG) + i,
+ uindices))
+ return -EFAULT;
+ uindices++;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(vfp_sysregs); i++) {
+ if (put_user(u32reg | vfp_sysregs[i], uindices))
+ return -EFAULT;
+ uindices++;
+ }
+
+ return num_vfp_regs();
+}
+
+static int vfp_get_reg(const struct kvm_vcpu *vcpu, u64 id, void __user *uaddr)
+{
+ u32 vfpid = (id & KVM_REG_ARM_VFP_MASK);
+ u32 val;
+
+ /* Fail if we have unknown bits set. */
+ if (id & ~(KVM_REG_ARCH_MASK|KVM_REG_SIZE_MASK|KVM_REG_ARM_COPROC_MASK
+ | ((1 << KVM_REG_ARM_COPROC_SHIFT)-1)))
+ return -ENOENT;
+
+ if (vfpid < num_fp_regs()) {
+ if (KVM_REG_SIZE(id) != 8)
+ return -ENOENT;
+ return reg_to_user(uaddr, &vcpu->arch.vfp_guest.fpregs[vfpid],
+ id);
+ }
+
+ /* FP control registers are all 32 bit. */
+ if (KVM_REG_SIZE(id) != 4)
+ return -ENOENT;
+
+ switch (vfpid) {
+ case KVM_REG_ARM_VFP_FPEXC:
+ return reg_to_user(uaddr, &vcpu->arch.vfp_guest.fpexc, id);
+ case KVM_REG_ARM_VFP_FPSCR:
+ return reg_to_user(uaddr, &vcpu->arch.vfp_guest.fpscr, id);
+ case KVM_REG_ARM_VFP_FPINST:
+ return reg_to_user(uaddr, &vcpu->arch.vfp_guest.fpinst, id);
+ case KVM_REG_ARM_VFP_FPINST2:
+ return reg_to_user(uaddr, &vcpu->arch.vfp_guest.fpinst2, id);
+ case KVM_REG_ARM_VFP_MVFR0:
+ val = fmrx(MVFR0);
+ return reg_to_user(uaddr, &val, id);
+ case KVM_REG_ARM_VFP_MVFR1:
+ val = fmrx(MVFR1);
+ return reg_to_user(uaddr, &val, id);
+ case KVM_REG_ARM_VFP_FPSID:
+ val = fmrx(FPSID);
+ return reg_to_user(uaddr, &val, id);
+ default:
+ return -ENOENT;
+ }
+}
+
+static int vfp_set_reg(struct kvm_vcpu *vcpu, u64 id, const void __user *uaddr)
+{
+ u32 vfpid = (id & KVM_REG_ARM_VFP_MASK);
+ u32 val;
+
+ /* Fail if we have unknown bits set. */
+ if (id & ~(KVM_REG_ARCH_MASK|KVM_REG_SIZE_MASK|KVM_REG_ARM_COPROC_MASK
+ | ((1 << KVM_REG_ARM_COPROC_SHIFT)-1)))
+ return -ENOENT;
+
+ if (vfpid < num_fp_regs()) {
+ if (KVM_REG_SIZE(id) != 8)
+ return -ENOENT;
+ return reg_from_user(&vcpu->arch.vfp_guest.fpregs[vfpid],
+ uaddr, id);
+ }
+
+ /* FP control registers are all 32 bit. */
+ if (KVM_REG_SIZE(id) != 4)
+ return -ENOENT;
+
+ switch (vfpid) {
+ case KVM_REG_ARM_VFP_FPEXC:
+ return reg_from_user(&vcpu->arch.vfp_guest.fpexc, uaddr, id);
+ case KVM_REG_ARM_VFP_FPSCR:
+ return reg_from_user(&vcpu->arch.vfp_guest.fpscr, uaddr, id);
+ case KVM_REG_ARM_VFP_FPINST:
+ return reg_from_user(&vcpu->arch.vfp_guest.fpinst, uaddr, id);
+ case KVM_REG_ARM_VFP_FPINST2:
+ return reg_from_user(&vcpu->arch.vfp_guest.fpinst2, uaddr, id);
+ /* These are invariant. */
+ case KVM_REG_ARM_VFP_MVFR0:
+ if (reg_from_user(&val, uaddr, id))
+ return -EFAULT;
+ if (val != fmrx(MVFR0))
+ return -EINVAL;
+ return 0;
+ case KVM_REG_ARM_VFP_MVFR1:
+ if (reg_from_user(&val, uaddr, id))
+ return -EFAULT;
+ if (val != fmrx(MVFR1))
+ return -EINVAL;
+ return 0;
+ case KVM_REG_ARM_VFP_FPSID:
+ if (reg_from_user(&val, uaddr, id))
+ return -EFAULT;
+ if (val != fmrx(FPSID))
+ return -EINVAL;
+ return 0;
+ default:
+ return -ENOENT;
+ }
+}
+#else /* !CONFIG_VFPv3 */
+static unsigned int num_vfp_regs(void)
+{
+ return 0;
+}
+
+static int copy_vfp_regids(u64 __user *uindices)
+{
+ return 0;
+}
+
+static int vfp_get_reg(const struct kvm_vcpu *vcpu, u64 id, void __user *uaddr)
+{
+ return -ENOENT;
+}
+
+static int vfp_set_reg(struct kvm_vcpu *vcpu, u64 id, const void __user *uaddr)
+{
+ return -ENOENT;
+}
+#endif /* !CONFIG_VFPv3 */
+
+int kvm_arm_coproc_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+ const struct coproc_reg *r;
+ void __user *uaddr = (void __user *)(long)reg->addr;
+ int ret;
+
+ if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX)
+ return demux_c15_get(reg->id, uaddr);
+
+ if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_VFP)
+ return vfp_get_reg(vcpu, reg->id, uaddr);
+
+ r = index_to_coproc_reg(vcpu, reg->id);
+ if (!r)
+ return get_invariant_cp15(reg->id, uaddr);
+
+ ret = -ENOENT;
+ if (KVM_REG_SIZE(reg->id) == 8) {
+ u64 val;
+
+ val = vcpu_cp15_reg64_get(vcpu, r);
+ ret = reg_to_user(uaddr, &val, reg->id);
+ } else if (KVM_REG_SIZE(reg->id) == 4) {
+ ret = reg_to_user(uaddr, &vcpu->arch.cp15[r->reg], reg->id);
+ }
+
+ return ret;
+}
+
+int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+ const struct coproc_reg *r;
+ void __user *uaddr = (void __user *)(long)reg->addr;
+ int ret;
+
+ if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX)
+ return demux_c15_set(reg->id, uaddr);
+
+ if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_VFP)
+ return vfp_set_reg(vcpu, reg->id, uaddr);
+
+ r = index_to_coproc_reg(vcpu, reg->id);
+ if (!r)
+ return set_invariant_cp15(reg->id, uaddr);
+
+ ret = -ENOENT;
+ if (KVM_REG_SIZE(reg->id) == 8) {
+ u64 val;
+
+ ret = reg_from_user(&val, uaddr, reg->id);
+ if (!ret)
+ vcpu_cp15_reg64_set(vcpu, r, val);
+ } else if (KVM_REG_SIZE(reg->id) == 4) {
+ ret = reg_from_user(&vcpu->arch.cp15[r->reg], uaddr, reg->id);
+ }
+
+ return ret;
+}
+
+static unsigned int num_demux_regs(void)
+{
+ unsigned int i, count = 0;
+
+ for (i = 0; i < CSSELR_MAX; i++)
+ if (is_valid_cache(i))
+ count++;
+
+ return count;
+}
+
+static int write_demux_regids(u64 __user *uindices)
+{
+ u64 val = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_DEMUX;
+ unsigned int i;
+
+ val |= KVM_REG_ARM_DEMUX_ID_CCSIDR;
+ for (i = 0; i < CSSELR_MAX; i++) {
+ if (!is_valid_cache(i))
+ continue;
+ if (put_user(val | i, uindices))
+ return -EFAULT;
+ uindices++;
+ }
+ return 0;
+}
+
+static u64 cp15_to_index(const struct coproc_reg *reg)
+{
+ u64 val = KVM_REG_ARM | (15 << KVM_REG_ARM_COPROC_SHIFT);
+ if (reg->is_64) {
+ val |= KVM_REG_SIZE_U64;
+ val |= (reg->Op1 << KVM_REG_ARM_OPC1_SHIFT);
+ /*
+ * CRn always denotes the primary coproc. reg. nr. for the
+ * in-kernel representation, but the user space API uses the
+ * CRm for the encoding, because it is modelled after the
+ * MRRC/MCRR instructions: see the ARM ARM rev. c page
+ * B3-1445
+ */
+ val |= (reg->CRn << KVM_REG_ARM_CRM_SHIFT);
+ } else {
+ val |= KVM_REG_SIZE_U32;
+ val |= (reg->Op1 << KVM_REG_ARM_OPC1_SHIFT);
+ val |= (reg->Op2 << KVM_REG_ARM_32_OPC2_SHIFT);
+ val |= (reg->CRm << KVM_REG_ARM_CRM_SHIFT);
+ val |= (reg->CRn << KVM_REG_ARM_32_CRN_SHIFT);
+ }
+ return val;
+}
+
+static bool copy_reg_to_user(const struct coproc_reg *reg, u64 __user **uind)
+{
+ if (!*uind)
+ return true;
+
+ if (put_user(cp15_to_index(reg), *uind))
+ return false;
+
+ (*uind)++;
+ return true;
+}
+
+/* Assumed ordered tables, see kvm_coproc_table_init. */
+static int walk_cp15(struct kvm_vcpu *vcpu, u64 __user *uind)
+{
+ const struct coproc_reg *i1, *i2, *end1, *end2;
+ unsigned int total = 0;
+ size_t num;
+
+ /* We check for duplicates here, to allow arch-specific overrides. */
+ i1 = get_target_table(vcpu->arch.target, &num);
+ end1 = i1 + num;
+ i2 = cp15_regs;
+ end2 = cp15_regs + ARRAY_SIZE(cp15_regs);
+
+ BUG_ON(i1 == end1 || i2 == end2);
+
+ /* Walk carefully, as both tables may refer to the same register. */
+ while (i1 || i2) {
+ int cmp = cmp_reg(i1, i2);
+ /* target-specific overrides generic entry. */
+ if (cmp <= 0) {
+ /* Ignore registers we trap but don't save. */
+ if (i1->reg) {
+ if (!copy_reg_to_user(i1, &uind))
+ return -EFAULT;
+ total++;
+ }
+ } else {
+ /* Ignore registers we trap but don't save. */
+ if (i2->reg) {
+ if (!copy_reg_to_user(i2, &uind))
+ return -EFAULT;
+ total++;
+ }
+ }
+
+ if (cmp <= 0 && ++i1 == end1)
+ i1 = NULL;
+ if (cmp >= 0 && ++i2 == end2)
+ i2 = NULL;
+ }
+ return total;
+}
+
+unsigned long kvm_arm_num_coproc_regs(struct kvm_vcpu *vcpu)
+{
+ return ARRAY_SIZE(invariant_cp15)
+ + num_demux_regs()
+ + num_vfp_regs()
+ + walk_cp15(vcpu, (u64 __user *)NULL);
+}
+
+int kvm_arm_copy_coproc_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
+{
+ unsigned int i;
+ int err;
+
+ /* Then give them all the invariant registers' indices. */
+ for (i = 0; i < ARRAY_SIZE(invariant_cp15); i++) {
+ if (put_user(cp15_to_index(&invariant_cp15[i]), uindices))
+ return -EFAULT;
+ uindices++;
+ }
+
+ err = walk_cp15(vcpu, uindices);
+ if (err < 0)
+ return err;
+ uindices += err;
+
+ err = copy_vfp_regids(uindices);
+ if (err < 0)
+ return err;
+ uindices += err;
+
+ return write_demux_regids(uindices);
+}
+
+void kvm_coproc_table_init(void)
+{
+ unsigned int i;
+
+ /* Make sure tables are unique and in order. */
+ for (i = 1; i < ARRAY_SIZE(cp15_regs); i++)
+ BUG_ON(cmp_reg(&cp15_regs[i-1], &cp15_regs[i]) >= 0);
+
+ /* We abuse the reset function to overwrite the table itself. */
+ for (i = 0; i < ARRAY_SIZE(invariant_cp15); i++)
+ invariant_cp15[i].reset(NULL, &invariant_cp15[i]);
+
+ /*
+ * CLIDR format is awkward, so clean it up. See ARM B4.1.20:
+ *
+ * If software reads the Cache Type fields from Ctype1
+ * upwards, once it has seen a value of 0b000, no caches
+ * exist at further-out levels of the hierarchy. So, for
+ * example, if Ctype3 is the first Cache Type field with a
+ * value of 0b000, the values of Ctype4 to Ctype7 must be
+ * ignored.
+ */
+ asm volatile("mrc p15, 1, %0, c0, c0, 1" : "=r" (cache_levels));
+ for (i = 0; i < 7; i++)
+ if (((cache_levels >> (i*3)) & 7) == 0)
+ break;
+ /* Clear all higher bits. */
+ cache_levels &= (1 << (i*3))-1;
+}
+
+/**
+ * kvm_reset_coprocs - sets cp15 registers to reset value
+ * @vcpu: The VCPU pointer
+ *
+ * This function finds the right table above and sets the registers on the
+ * virtual CPU struct to their architecturally defined reset values.
+ */
+void kvm_reset_coprocs(struct kvm_vcpu *vcpu)
+{
+ size_t num;
+ const struct coproc_reg *table;
+
+ /* Catch someone adding a register without putting in reset entry. */
+ memset(vcpu->arch.cp15, 0x42, sizeof(vcpu->arch.cp15));
+
+ /* Generic chip reset first (so target could override). */
+ reset_coproc_regs(vcpu, cp15_regs, ARRAY_SIZE(cp15_regs));
+
+ table = get_target_table(vcpu->arch.target, &num);
+ reset_coproc_regs(vcpu, table, num);
+
+ for (num = 1; num < NR_CP15_REGS; num++)
+ if (vcpu->arch.cp15[num] == 0x42424242)
+ panic("Didn't reset vcpu->arch.cp15[%zi]", num);
+}
diff --git a/arch/arm/kvm/coproc.h b/arch/arm/kvm/coproc.h
new file mode 100644
index 000000000..88d24a3a9
--- /dev/null
+++ b/arch/arm/kvm/coproc.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Authors: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ARM_KVM_COPROC_LOCAL_H__
+#define __ARM_KVM_COPROC_LOCAL_H__
+
+struct coproc_params {
+ unsigned long CRn;
+ unsigned long CRm;
+ unsigned long Op1;
+ unsigned long Op2;
+ unsigned long Rt1;
+ unsigned long Rt2;
+ bool is_64bit;
+ bool is_write;
+};
+
+struct coproc_reg {
+ /* MRC/MCR/MRRC/MCRR instruction which accesses it. */
+ unsigned long CRn;
+ unsigned long CRm;
+ unsigned long Op1;
+ unsigned long Op2;
+
+ bool is_64;
+
+ /* Trapped access from guest, if non-NULL. */
+ bool (*access)(struct kvm_vcpu *,
+ const struct coproc_params *,
+ const struct coproc_reg *);
+
+ /* Initialization for vcpu. */
+ void (*reset)(struct kvm_vcpu *, const struct coproc_reg *);
+
+ /* Index into vcpu->arch.cp15[], or 0 if we don't need to save it. */
+ unsigned long reg;
+
+ /* Value (usually reset value) */
+ u64 val;
+};
+
+static inline void print_cp_instr(const struct coproc_params *p)
+{
+ /* Look, we even formatted it for you to paste into the table! */
+ if (p->is_64bit) {
+ kvm_pr_unimpl(" { CRm64(%2lu), Op1(%2lu), is64, func_%s },\n",
+ p->CRn, p->Op1, p->is_write ? "write" : "read");
+ } else {
+ kvm_pr_unimpl(" { CRn(%2lu), CRm(%2lu), Op1(%2lu), Op2(%2lu), is32,"
+ " func_%s },\n",
+ p->CRn, p->CRm, p->Op1, p->Op2,
+ p->is_write ? "write" : "read");
+ }
+}
+
+static inline bool ignore_write(struct kvm_vcpu *vcpu,
+ const struct coproc_params *p)
+{
+ return true;
+}
+
+static inline bool read_zero(struct kvm_vcpu *vcpu,
+ const struct coproc_params *p)
+{
+ *vcpu_reg(vcpu, p->Rt1) = 0;
+ return true;
+}
+
+static inline bool write_to_read_only(struct kvm_vcpu *vcpu,
+ const struct coproc_params *params)
+{
+ kvm_debug("CP15 write to read-only register at: %08lx\n",
+ *vcpu_pc(vcpu));
+ print_cp_instr(params);
+ return false;
+}
+
+static inline bool read_from_write_only(struct kvm_vcpu *vcpu,
+ const struct coproc_params *params)
+{
+ kvm_debug("CP15 read to write-only register at: %08lx\n",
+ *vcpu_pc(vcpu));
+ print_cp_instr(params);
+ return false;
+}
+
+/* Reset functions */
+static inline void reset_unknown(struct kvm_vcpu *vcpu,
+ const struct coproc_reg *r)
+{
+ BUG_ON(!r->reg);
+ BUG_ON(r->reg >= ARRAY_SIZE(vcpu->arch.cp15));
+ vcpu->arch.cp15[r->reg] = 0xdecafbad;
+}
+
+static inline void reset_val(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
+{
+ BUG_ON(!r->reg);
+ BUG_ON(r->reg >= ARRAY_SIZE(vcpu->arch.cp15));
+ vcpu->arch.cp15[r->reg] = r->val;
+}
+
+static inline void reset_unknown64(struct kvm_vcpu *vcpu,
+ const struct coproc_reg *r)
+{
+ BUG_ON(!r->reg);
+ BUG_ON(r->reg + 1 >= ARRAY_SIZE(vcpu->arch.cp15));
+
+ vcpu->arch.cp15[r->reg] = 0xdecafbad;
+ vcpu->arch.cp15[r->reg+1] = 0xd0c0ffee;
+}
+
+static inline int cmp_reg(const struct coproc_reg *i1,
+ const struct coproc_reg *i2)
+{
+ BUG_ON(i1 == i2);
+ if (!i1)
+ return 1;
+ else if (!i2)
+ return -1;
+ if (i1->CRn != i2->CRn)
+ return i1->CRn - i2->CRn;
+ if (i1->CRm != i2->CRm)
+ return i1->CRm - i2->CRm;
+ if (i1->Op1 != i2->Op1)
+ return i1->Op1 - i2->Op1;
+ if (i1->Op2 != i2->Op2)
+ return i1->Op2 - i2->Op2;
+ return i2->is_64 - i1->is_64;
+}
+
+
+#define CRn(_x) .CRn = _x
+#define CRm(_x) .CRm = _x
+#define CRm64(_x) .CRn = _x, .CRm = 0
+#define Op1(_x) .Op1 = _x
+#define Op2(_x) .Op2 = _x
+#define is64 .is_64 = true
+#define is32 .is_64 = false
+
+bool access_vm_reg(struct kvm_vcpu *vcpu,
+ const struct coproc_params *p,
+ const struct coproc_reg *r);
+
+#endif /* __ARM_KVM_COPROC_LOCAL_H__ */
diff --git a/arch/arm/kvm/coproc_a15.c b/arch/arm/kvm/coproc_a15.c
new file mode 100644
index 000000000..a7136757d
--- /dev/null
+++ b/arch/arm/kvm/coproc_a15.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Authors: Rusty Russell <rusty@rustcorp.au>
+ * Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <linux/kvm_host.h>
+#include <asm/kvm_coproc.h>
+#include <asm/kvm_emulate.h>
+#include <linux/init.h>
+
+#include "coproc.h"
+
+/*
+ * A15-specific CP15 registers.
+ * CRn denotes the primary register number, but is copied to the CRm in the
+ * user space API for 64-bit register access in line with the terminology used
+ * in the ARM ARM.
+ * Important: Must be sorted ascending by CRn, CRM, Op1, Op2 and with 64-bit
+ * registers preceding 32-bit ones.
+ */
+static const struct coproc_reg a15_regs[] = {
+ /* SCTLR: swapped by interrupt.S. */
+ { CRn( 1), CRm( 0), Op1( 0), Op2( 0), is32,
+ access_vm_reg, reset_val, c1_SCTLR, 0x00C50078 },
+};
+
+static struct kvm_coproc_target_table a15_target_table = {
+ .target = KVM_ARM_TARGET_CORTEX_A15,
+ .table = a15_regs,
+ .num = ARRAY_SIZE(a15_regs),
+};
+
+static int __init coproc_a15_init(void)
+{
+ kvm_register_target_coproc_table(&a15_target_table);
+ return 0;
+}
+late_initcall(coproc_a15_init);
diff --git a/arch/arm/kvm/coproc_a7.c b/arch/arm/kvm/coproc_a7.c
new file mode 100644
index 000000000..b19e46d1b
--- /dev/null
+++ b/arch/arm/kvm/coproc_a7.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Copyright (C) 2013 - ARM Ltd
+ *
+ * Authors: Rusty Russell <rusty@rustcorp.au>
+ * Christoffer Dall <c.dall@virtualopensystems.com>
+ * Jonathan Austin <jonathan.austin@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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <linux/kvm_host.h>
+#include <asm/kvm_coproc.h>
+#include <asm/kvm_emulate.h>
+#include <linux/init.h>
+
+#include "coproc.h"
+
+/*
+ * Cortex-A7 specific CP15 registers.
+ * CRn denotes the primary register number, but is copied to the CRm in the
+ * user space API for 64-bit register access in line with the terminology used
+ * in the ARM ARM.
+ * Important: Must be sorted ascending by CRn, CRM, Op1, Op2 and with 64-bit
+ * registers preceding 32-bit ones.
+ */
+static const struct coproc_reg a7_regs[] = {
+ /* SCTLR: swapped by interrupt.S. */
+ { CRn( 1), CRm( 0), Op1( 0), Op2( 0), is32,
+ access_vm_reg, reset_val, c1_SCTLR, 0x00C50878 },
+};
+
+static struct kvm_coproc_target_table a7_target_table = {
+ .target = KVM_ARM_TARGET_CORTEX_A7,
+ .table = a7_regs,
+ .num = ARRAY_SIZE(a7_regs),
+};
+
+static int __init coproc_a7_init(void)
+{
+ kvm_register_target_coproc_table(&a7_target_table);
+ return 0;
+}
+late_initcall(coproc_a7_init);
diff --git a/arch/arm/kvm/emulate.c b/arch/arm/kvm/emulate.c
new file mode 100644
index 000000000..d6c005283
--- /dev/null
+++ b/arch/arm/kvm/emulate.c
@@ -0,0 +1,402 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/mm.h>
+#include <linux/kvm_host.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_emulate.h>
+#include <asm/opcodes.h>
+#include <trace/events/kvm.h>
+
+#include "trace.h"
+
+#define VCPU_NR_MODES 6
+#define VCPU_REG_OFFSET_USR 0
+#define VCPU_REG_OFFSET_FIQ 1
+#define VCPU_REG_OFFSET_IRQ 2
+#define VCPU_REG_OFFSET_SVC 3
+#define VCPU_REG_OFFSET_ABT 4
+#define VCPU_REG_OFFSET_UND 5
+#define REG_OFFSET(_reg) \
+ (offsetof(struct kvm_regs, _reg) / sizeof(u32))
+
+#define USR_REG_OFFSET(_num) REG_OFFSET(usr_regs.uregs[_num])
+
+static const unsigned long vcpu_reg_offsets[VCPU_NR_MODES][15] = {
+ /* USR/SYS Registers */
+ [VCPU_REG_OFFSET_USR] = {
+ USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2),
+ USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5),
+ USR_REG_OFFSET(6), USR_REG_OFFSET(7), USR_REG_OFFSET(8),
+ USR_REG_OFFSET(9), USR_REG_OFFSET(10), USR_REG_OFFSET(11),
+ USR_REG_OFFSET(12), USR_REG_OFFSET(13), USR_REG_OFFSET(14),
+ },
+
+ /* FIQ Registers */
+ [VCPU_REG_OFFSET_FIQ] = {
+ USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2),
+ USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5),
+ USR_REG_OFFSET(6), USR_REG_OFFSET(7),
+ REG_OFFSET(fiq_regs[0]), /* r8 */
+ REG_OFFSET(fiq_regs[1]), /* r9 */
+ REG_OFFSET(fiq_regs[2]), /* r10 */
+ REG_OFFSET(fiq_regs[3]), /* r11 */
+ REG_OFFSET(fiq_regs[4]), /* r12 */
+ REG_OFFSET(fiq_regs[5]), /* r13 */
+ REG_OFFSET(fiq_regs[6]), /* r14 */
+ },
+
+ /* IRQ Registers */
+ [VCPU_REG_OFFSET_IRQ] = {
+ USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2),
+ USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5),
+ USR_REG_OFFSET(6), USR_REG_OFFSET(7), USR_REG_OFFSET(8),
+ USR_REG_OFFSET(9), USR_REG_OFFSET(10), USR_REG_OFFSET(11),
+ USR_REG_OFFSET(12),
+ REG_OFFSET(irq_regs[0]), /* r13 */
+ REG_OFFSET(irq_regs[1]), /* r14 */
+ },
+
+ /* SVC Registers */
+ [VCPU_REG_OFFSET_SVC] = {
+ USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2),
+ USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5),
+ USR_REG_OFFSET(6), USR_REG_OFFSET(7), USR_REG_OFFSET(8),
+ USR_REG_OFFSET(9), USR_REG_OFFSET(10), USR_REG_OFFSET(11),
+ USR_REG_OFFSET(12),
+ REG_OFFSET(svc_regs[0]), /* r13 */
+ REG_OFFSET(svc_regs[1]), /* r14 */
+ },
+
+ /* ABT Registers */
+ [VCPU_REG_OFFSET_ABT] = {
+ USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2),
+ USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5),
+ USR_REG_OFFSET(6), USR_REG_OFFSET(7), USR_REG_OFFSET(8),
+ USR_REG_OFFSET(9), USR_REG_OFFSET(10), USR_REG_OFFSET(11),
+ USR_REG_OFFSET(12),
+ REG_OFFSET(abt_regs[0]), /* r13 */
+ REG_OFFSET(abt_regs[1]), /* r14 */
+ },
+
+ /* UND Registers */
+ [VCPU_REG_OFFSET_UND] = {
+ USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2),
+ USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5),
+ USR_REG_OFFSET(6), USR_REG_OFFSET(7), USR_REG_OFFSET(8),
+ USR_REG_OFFSET(9), USR_REG_OFFSET(10), USR_REG_OFFSET(11),
+ USR_REG_OFFSET(12),
+ REG_OFFSET(und_regs[0]), /* r13 */
+ REG_OFFSET(und_regs[1]), /* r14 */
+ },
+};
+
+/*
+ * Return a pointer to the register number valid in the current mode of
+ * the virtual CPU.
+ */
+unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num)
+{
+ unsigned long *reg_array = (unsigned long *)&vcpu->arch.regs;
+ unsigned long mode = *vcpu_cpsr(vcpu) & MODE_MASK;
+
+ switch (mode) {
+ case USR_MODE...SVC_MODE:
+ mode &= ~MODE32_BIT; /* 0 ... 3 */
+ break;
+
+ case ABT_MODE:
+ mode = VCPU_REG_OFFSET_ABT;
+ break;
+
+ case UND_MODE:
+ mode = VCPU_REG_OFFSET_UND;
+ break;
+
+ case SYSTEM_MODE:
+ mode = VCPU_REG_OFFSET_USR;
+ break;
+
+ default:
+ BUG();
+ }
+
+ return reg_array + vcpu_reg_offsets[mode][reg_num];
+}
+
+/*
+ * Return the SPSR for the current mode of the virtual CPU.
+ */
+unsigned long *vcpu_spsr(struct kvm_vcpu *vcpu)
+{
+ unsigned long mode = *vcpu_cpsr(vcpu) & MODE_MASK;
+ switch (mode) {
+ case SVC_MODE:
+ return &vcpu->arch.regs.KVM_ARM_SVC_spsr;
+ case ABT_MODE:
+ return &vcpu->arch.regs.KVM_ARM_ABT_spsr;
+ case UND_MODE:
+ return &vcpu->arch.regs.KVM_ARM_UND_spsr;
+ case IRQ_MODE:
+ return &vcpu->arch.regs.KVM_ARM_IRQ_spsr;
+ case FIQ_MODE:
+ return &vcpu->arch.regs.KVM_ARM_FIQ_spsr;
+ default:
+ BUG();
+ }
+}
+
+/*
+ * A conditional instruction is allowed to trap, even though it
+ * wouldn't be executed. So let's re-implement the hardware, in
+ * software!
+ */
+bool kvm_condition_valid(struct kvm_vcpu *vcpu)
+{
+ unsigned long cpsr, cond, insn;
+
+ /*
+ * Exception Code 0 can only happen if we set HCR.TGE to 1, to
+ * catch undefined instructions, and then we won't get past
+ * the arm_exit_handlers test anyway.
+ */
+ BUG_ON(!kvm_vcpu_trap_get_class(vcpu));
+
+ /* Top two bits non-zero? Unconditional. */
+ if (kvm_vcpu_get_hsr(vcpu) >> 30)
+ return true;
+
+ cpsr = *vcpu_cpsr(vcpu);
+
+ /* Is condition field valid? */
+ if ((kvm_vcpu_get_hsr(vcpu) & HSR_CV) >> HSR_CV_SHIFT)
+ cond = (kvm_vcpu_get_hsr(vcpu) & HSR_COND) >> HSR_COND_SHIFT;
+ else {
+ /* This can happen in Thumb mode: examine IT state. */
+ unsigned long it;
+
+ it = ((cpsr >> 8) & 0xFC) | ((cpsr >> 25) & 0x3);
+
+ /* it == 0 => unconditional. */
+ if (it == 0)
+ return true;
+
+ /* The cond for this insn works out as the top 4 bits. */
+ cond = (it >> 4);
+ }
+
+ /* Shift makes it look like an ARM-mode instruction */
+ insn = cond << 28;
+ return arm_check_condition(insn, cpsr) != ARM_OPCODE_CONDTEST_FAIL;
+}
+
+/**
+ * adjust_itstate - adjust ITSTATE when emulating instructions in IT-block
+ * @vcpu: The VCPU pointer
+ *
+ * When exceptions occur while instructions are executed in Thumb IF-THEN
+ * blocks, the ITSTATE field of the CPSR is not advanved (updated), so we have
+ * to do this little bit of work manually. The fields map like this:
+ *
+ * IT[7:0] -> CPSR[26:25],CPSR[15:10]
+ */
+static void kvm_adjust_itstate(struct kvm_vcpu *vcpu)
+{
+ unsigned long itbits, cond;
+ unsigned long cpsr = *vcpu_cpsr(vcpu);
+ bool is_arm = !(cpsr & PSR_T_BIT);
+
+ BUG_ON(is_arm && (cpsr & PSR_IT_MASK));
+
+ if (!(cpsr & PSR_IT_MASK))
+ return;
+
+ cond = (cpsr & 0xe000) >> 13;
+ itbits = (cpsr & 0x1c00) >> (10 - 2);
+ itbits |= (cpsr & (0x3 << 25)) >> 25;
+
+ /* Perform ITAdvance (see page A-52 in ARM DDI 0406C) */
+ if ((itbits & 0x7) == 0)
+ itbits = cond = 0;
+ else
+ itbits = (itbits << 1) & 0x1f;
+
+ cpsr &= ~PSR_IT_MASK;
+ cpsr |= cond << 13;
+ cpsr |= (itbits & 0x1c) << (10 - 2);
+ cpsr |= (itbits & 0x3) << 25;
+ *vcpu_cpsr(vcpu) = cpsr;
+}
+
+/**
+ * kvm_skip_instr - skip a trapped instruction and proceed to the next
+ * @vcpu: The vcpu pointer
+ */
+void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr)
+{
+ bool is_thumb;
+
+ is_thumb = !!(*vcpu_cpsr(vcpu) & PSR_T_BIT);
+ if (is_thumb && !is_wide_instr)
+ *vcpu_pc(vcpu) += 2;
+ else
+ *vcpu_pc(vcpu) += 4;
+ kvm_adjust_itstate(vcpu);
+}
+
+
+/******************************************************************************
+ * Inject exceptions into the guest
+ */
+
+static u32 exc_vector_base(struct kvm_vcpu *vcpu)
+{
+ u32 sctlr = vcpu->arch.cp15[c1_SCTLR];
+ u32 vbar = vcpu->arch.cp15[c12_VBAR];
+
+ if (sctlr & SCTLR_V)
+ return 0xffff0000;
+ else /* always have security exceptions */
+ return vbar;
+}
+
+/**
+ * kvm_inject_undefined - inject an undefined exception into the guest
+ * @vcpu: The VCPU to receive the undefined exception
+ *
+ * It is assumed that this code is called from the VCPU thread and that the
+ * VCPU therefore is not currently executing guest code.
+ *
+ * Modelled after TakeUndefInstrException() pseudocode.
+ */
+void kvm_inject_undefined(struct kvm_vcpu *vcpu)
+{
+ unsigned long new_lr_value;
+ unsigned long new_spsr_value;
+ unsigned long cpsr = *vcpu_cpsr(vcpu);
+ u32 sctlr = vcpu->arch.cp15[c1_SCTLR];
+ bool is_thumb = (cpsr & PSR_T_BIT);
+ u32 vect_offset = 4;
+ u32 return_offset = (is_thumb) ? 2 : 4;
+
+ new_spsr_value = cpsr;
+ new_lr_value = *vcpu_pc(vcpu) - return_offset;
+
+ *vcpu_cpsr(vcpu) = (cpsr & ~MODE_MASK) | UND_MODE;
+ *vcpu_cpsr(vcpu) |= PSR_I_BIT;
+ *vcpu_cpsr(vcpu) &= ~(PSR_IT_MASK | PSR_J_BIT | PSR_E_BIT | PSR_T_BIT);
+
+ if (sctlr & SCTLR_TE)
+ *vcpu_cpsr(vcpu) |= PSR_T_BIT;
+ if (sctlr & SCTLR_EE)
+ *vcpu_cpsr(vcpu) |= PSR_E_BIT;
+
+ /* Note: These now point to UND banked copies */
+ *vcpu_spsr(vcpu) = cpsr;
+ *vcpu_reg(vcpu, 14) = new_lr_value;
+
+ /* Branch to exception vector */
+ *vcpu_pc(vcpu) = exc_vector_base(vcpu) + vect_offset;
+}
+
+/*
+ * Modelled after TakeDataAbortException() and TakePrefetchAbortException
+ * pseudocode.
+ */
+static void inject_abt(struct kvm_vcpu *vcpu, bool is_pabt, unsigned long addr)
+{
+ unsigned long new_lr_value;
+ unsigned long new_spsr_value;
+ unsigned long cpsr = *vcpu_cpsr(vcpu);
+ u32 sctlr = vcpu->arch.cp15[c1_SCTLR];
+ bool is_thumb = (cpsr & PSR_T_BIT);
+ u32 vect_offset;
+ u32 return_offset = (is_thumb) ? 4 : 0;
+ bool is_lpae;
+
+ new_spsr_value = cpsr;
+ new_lr_value = *vcpu_pc(vcpu) + return_offset;
+
+ *vcpu_cpsr(vcpu) = (cpsr & ~MODE_MASK) | ABT_MODE;
+ *vcpu_cpsr(vcpu) |= PSR_I_BIT | PSR_A_BIT;
+ *vcpu_cpsr(vcpu) &= ~(PSR_IT_MASK | PSR_J_BIT | PSR_E_BIT | PSR_T_BIT);
+
+ if (sctlr & SCTLR_TE)
+ *vcpu_cpsr(vcpu) |= PSR_T_BIT;
+ if (sctlr & SCTLR_EE)
+ *vcpu_cpsr(vcpu) |= PSR_E_BIT;
+
+ /* Note: These now point to ABT banked copies */
+ *vcpu_spsr(vcpu) = cpsr;
+ *vcpu_reg(vcpu, 14) = new_lr_value;
+
+ if (is_pabt)
+ vect_offset = 12;
+ else
+ vect_offset = 16;
+
+ /* Branch to exception vector */
+ *vcpu_pc(vcpu) = exc_vector_base(vcpu) + vect_offset;
+
+ if (is_pabt) {
+ /* Set IFAR and IFSR */
+ vcpu->arch.cp15[c6_IFAR] = addr;
+ is_lpae = (vcpu->arch.cp15[c2_TTBCR] >> 31);
+ /* Always give debug fault for now - should give guest a clue */
+ if (is_lpae)
+ vcpu->arch.cp15[c5_IFSR] = 1 << 9 | 0x22;
+ else
+ vcpu->arch.cp15[c5_IFSR] = 2;
+ } else { /* !iabt */
+ /* Set DFAR and DFSR */
+ vcpu->arch.cp15[c6_DFAR] = addr;
+ is_lpae = (vcpu->arch.cp15[c2_TTBCR] >> 31);
+ /* Always give debug fault for now - should give guest a clue */
+ if (is_lpae)
+ vcpu->arch.cp15[c5_DFSR] = 1 << 9 | 0x22;
+ else
+ vcpu->arch.cp15[c5_DFSR] = 2;
+ }
+
+}
+
+/**
+ * kvm_inject_dabt - inject a data abort into the guest
+ * @vcpu: The VCPU to receive the undefined exception
+ * @addr: The address to report in the DFAR
+ *
+ * It is assumed that this code is called from the VCPU thread and that the
+ * VCPU therefore is not currently executing guest code.
+ */
+void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr)
+{
+ inject_abt(vcpu, false, addr);
+}
+
+/**
+ * kvm_inject_pabt - inject a prefetch abort into the guest
+ * @vcpu: The VCPU to receive the undefined exception
+ * @addr: The address to report in the DFAR
+ *
+ * It is assumed that this code is called from the VCPU thread and that the
+ * VCPU therefore is not currently executing guest code.
+ */
+void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr)
+{
+ inject_abt(vcpu, true, addr);
+}
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
new file mode 100644
index 000000000..d503fbb78
--- /dev/null
+++ b/arch/arm/kvm/guest.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/kvm_host.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <asm/cputype.h>
+#include <asm/uaccess.h>
+#include <asm/kvm.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_coproc.h>
+
+#define VM_STAT(x) { #x, offsetof(struct kvm, stat.x), KVM_STAT_VM }
+#define VCPU_STAT(x) { #x, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU }
+
+struct kvm_stats_debugfs_item debugfs_entries[] = {
+ { NULL }
+};
+
+int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
+{
+ return 0;
+}
+
+static u64 core_reg_offset_from_id(u64 id)
+{
+ return id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_ARM_CORE);
+}
+
+static int get_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+ u32 __user *uaddr = (u32 __user *)(long)reg->addr;
+ struct kvm_regs *regs = &vcpu->arch.regs;
+ u64 off;
+
+ if (KVM_REG_SIZE(reg->id) != 4)
+ return -ENOENT;
+
+ /* Our ID is an index into the kvm_regs struct. */
+ off = core_reg_offset_from_id(reg->id);
+ if (off >= sizeof(*regs) / KVM_REG_SIZE(reg->id))
+ return -ENOENT;
+
+ return put_user(((u32 *)regs)[off], uaddr);
+}
+
+static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+ u32 __user *uaddr = (u32 __user *)(long)reg->addr;
+ struct kvm_regs *regs = &vcpu->arch.regs;
+ u64 off, val;
+
+ if (KVM_REG_SIZE(reg->id) != 4)
+ return -ENOENT;
+
+ /* Our ID is an index into the kvm_regs struct. */
+ off = core_reg_offset_from_id(reg->id);
+ if (off >= sizeof(*regs) / KVM_REG_SIZE(reg->id))
+ return -ENOENT;
+
+ if (get_user(val, uaddr) != 0)
+ return -EFAULT;
+
+ if (off == KVM_REG_ARM_CORE_REG(usr_regs.ARM_cpsr)) {
+ unsigned long mode = val & MODE_MASK;
+ switch (mode) {
+ case USR_MODE:
+ case FIQ_MODE:
+ case IRQ_MODE:
+ case SVC_MODE:
+ case ABT_MODE:
+ case UND_MODE:
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ ((u32 *)regs)[off] = val;
+ return 0;
+}
+
+int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
+{
+ return -EINVAL;
+}
+
+int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
+{
+ return -EINVAL;
+}
+
+#define NUM_TIMER_REGS 3
+
+static bool is_timer_reg(u64 index)
+{
+ switch (index) {
+ case KVM_REG_ARM_TIMER_CTL:
+ case KVM_REG_ARM_TIMER_CNT:
+ case KVM_REG_ARM_TIMER_CVAL:
+ return true;
+ }
+ return false;
+}
+
+static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
+{
+ if (put_user(KVM_REG_ARM_TIMER_CTL, uindices))
+ return -EFAULT;
+ uindices++;
+ if (put_user(KVM_REG_ARM_TIMER_CNT, uindices))
+ return -EFAULT;
+ uindices++;
+ if (put_user(KVM_REG_ARM_TIMER_CVAL, uindices))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int set_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+ void __user *uaddr = (void __user *)(long)reg->addr;
+ u64 val;
+ int ret;
+
+ ret = copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id));
+ if (ret != 0)
+ return -EFAULT;
+
+ return kvm_arm_timer_set_reg(vcpu, reg->id, val);
+}
+
+static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+ void __user *uaddr = (void __user *)(long)reg->addr;
+ u64 val;
+
+ val = kvm_arm_timer_get_reg(vcpu, reg->id);
+ return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id));
+}
+
+static unsigned long num_core_regs(void)
+{
+ return sizeof(struct kvm_regs) / sizeof(u32);
+}
+
+/**
+ * kvm_arm_num_regs - how many registers do we present via KVM_GET_ONE_REG
+ *
+ * This is for all registers.
+ */
+unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu)
+{
+ return num_core_regs() + kvm_arm_num_coproc_regs(vcpu)
+ + NUM_TIMER_REGS;
+}
+
+/**
+ * kvm_arm_copy_reg_indices - get indices of all registers.
+ *
+ * We do core registers right here, then we apppend coproc regs.
+ */
+int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
+{
+ unsigned int i;
+ const u64 core_reg = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_CORE;
+ int ret;
+
+ for (i = 0; i < sizeof(struct kvm_regs)/sizeof(u32); i++) {
+ if (put_user(core_reg | i, uindices))
+ return -EFAULT;
+ uindices++;
+ }
+
+ ret = copy_timer_indices(vcpu, uindices);
+ if (ret)
+ return ret;
+ uindices += NUM_TIMER_REGS;
+
+ return kvm_arm_copy_coproc_indices(vcpu, uindices);
+}
+
+int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+ /* We currently use nothing arch-specific in upper 32 bits */
+ if ((reg->id & ~KVM_REG_SIZE_MASK) >> 32 != KVM_REG_ARM >> 32)
+ return -EINVAL;
+
+ /* Register group 16 means we want a core register. */
+ if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
+ return get_core_reg(vcpu, reg);
+
+ if (is_timer_reg(reg->id))
+ return get_timer_reg(vcpu, reg);
+
+ return kvm_arm_coproc_get_reg(vcpu, reg);
+}
+
+int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+ /* We currently use nothing arch-specific in upper 32 bits */
+ if ((reg->id & ~KVM_REG_SIZE_MASK) >> 32 != KVM_REG_ARM >> 32)
+ return -EINVAL;
+
+ /* Register group 16 means we set a core register. */
+ if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
+ return set_core_reg(vcpu, reg);
+
+ if (is_timer_reg(reg->id))
+ return set_timer_reg(vcpu, reg);
+
+ return kvm_arm_coproc_set_reg(vcpu, reg);
+}
+
+int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
+ struct kvm_sregs *sregs)
+{
+ return -EINVAL;
+}
+
+int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
+ struct kvm_sregs *sregs)
+{
+ return -EINVAL;
+}
+
+int __attribute_const__ kvm_target_cpu(void)
+{
+ switch (read_cpuid_part()) {
+ case ARM_CPU_PART_CORTEX_A7:
+ return KVM_ARM_TARGET_CORTEX_A7;
+ case ARM_CPU_PART_CORTEX_A15:
+ return KVM_ARM_TARGET_CORTEX_A15;
+ default:
+ return -EINVAL;
+ }
+}
+
+int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init)
+{
+ int target = kvm_target_cpu();
+
+ if (target < 0)
+ return -ENODEV;
+
+ memset(init, 0, sizeof(*init));
+
+ /*
+ * For now, we don't return any features.
+ * In future, we might use features to return target
+ * specific features available for the preferred
+ * target type.
+ */
+ init->target = (__u32)target;
+
+ return 0;
+}
+
+int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
+{
+ return -EINVAL;
+}
+
+int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
+{
+ return -EINVAL;
+}
+
+int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
+ struct kvm_translation *tr)
+{
+ return -EINVAL;
+}
diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c
new file mode 100644
index 000000000..95f12b2cc
--- /dev/null
+++ b/arch/arm/kvm/handle_exit.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/kvm.h>
+#include <linux/kvm_host.h>
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_coproc.h>
+#include <asm/kvm_mmu.h>
+#include <asm/kvm_psci.h>
+#include <trace/events/kvm.h>
+
+#include "trace.h"
+
+typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *);
+
+static int handle_svc_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ /* SVC called from Hyp mode should never get here */
+ kvm_debug("SVC called from Hyp mode shouldn't go here\n");
+ BUG();
+ return -EINVAL; /* Squash warning */
+}
+
+static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ int ret;
+
+ trace_kvm_hvc(*vcpu_pc(vcpu), *vcpu_reg(vcpu, 0),
+ kvm_vcpu_hvc_get_imm(vcpu));
+
+ ret = kvm_psci_call(vcpu);
+ if (ret < 0) {
+ kvm_inject_undefined(vcpu);
+ return 1;
+ }
+
+ return ret;
+}
+
+static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ kvm_inject_undefined(vcpu);
+ return 1;
+}
+
+static int handle_pabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ /* The hypervisor should never cause aborts */
+ kvm_err("Prefetch Abort taken from Hyp mode at %#08lx (HSR: %#08x)\n",
+ kvm_vcpu_get_hfar(vcpu), kvm_vcpu_get_hsr(vcpu));
+ return -EFAULT;
+}
+
+static int handle_dabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ /* This is either an error in the ws. code or an external abort */
+ kvm_err("Data Abort taken from Hyp mode at %#08lx (HSR: %#08x)\n",
+ kvm_vcpu_get_hfar(vcpu), kvm_vcpu_get_hsr(vcpu));
+ return -EFAULT;
+}
+
+/**
+ * kvm_handle_wfx - handle a WFI or WFE instructions trapped in guests
+ * @vcpu: the vcpu pointer
+ * @run: the kvm_run structure pointer
+ *
+ * WFE: Yield the CPU and come back to this vcpu when the scheduler
+ * decides to.
+ * WFI: Simply call kvm_vcpu_block(), which will halt execution of
+ * world-switches and schedule other host processes until there is an
+ * incoming IRQ or FIQ to the VM.
+ */
+static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ if (kvm_vcpu_get_hsr(vcpu) & HSR_WFI_IS_WFE) {
+ trace_kvm_wfx(*vcpu_pc(vcpu), true);
+ kvm_vcpu_on_spin(vcpu);
+ } else {
+ trace_kvm_wfx(*vcpu_pc(vcpu), false);
+ kvm_vcpu_block(vcpu);
+ }
+
+ kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+
+ return 1;
+}
+
+static exit_handle_fn arm_exit_handlers[] = {
+ [HSR_EC_WFI] = kvm_handle_wfx,
+ [HSR_EC_CP15_32] = kvm_handle_cp15_32,
+ [HSR_EC_CP15_64] = kvm_handle_cp15_64,
+ [HSR_EC_CP14_MR] = kvm_handle_cp14_access,
+ [HSR_EC_CP14_LS] = kvm_handle_cp14_load_store,
+ [HSR_EC_CP14_64] = kvm_handle_cp14_access,
+ [HSR_EC_CP_0_13] = kvm_handle_cp_0_13_access,
+ [HSR_EC_CP10_ID] = kvm_handle_cp10_id,
+ [HSR_EC_SVC_HYP] = handle_svc_hyp,
+ [HSR_EC_HVC] = handle_hvc,
+ [HSR_EC_SMC] = handle_smc,
+ [HSR_EC_IABT] = kvm_handle_guest_abort,
+ [HSR_EC_IABT_HYP] = handle_pabt_hyp,
+ [HSR_EC_DABT] = kvm_handle_guest_abort,
+ [HSR_EC_DABT_HYP] = handle_dabt_hyp,
+};
+
+static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu)
+{
+ u8 hsr_ec = kvm_vcpu_trap_get_class(vcpu);
+
+ if (hsr_ec >= ARRAY_SIZE(arm_exit_handlers) ||
+ !arm_exit_handlers[hsr_ec]) {
+ kvm_err("Unknown exception class: hsr: %#08x\n",
+ (unsigned int)kvm_vcpu_get_hsr(vcpu));
+ BUG();
+ }
+
+ return arm_exit_handlers[hsr_ec];
+}
+
+/*
+ * Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on
+ * proper exit to userspace.
+ */
+int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
+ int exception_index)
+{
+ exit_handle_fn exit_handler;
+
+ switch (exception_index) {
+ case ARM_EXCEPTION_IRQ:
+ return 1;
+ case ARM_EXCEPTION_UNDEFINED:
+ kvm_err("Undefined exception in Hyp mode at: %#08lx\n",
+ kvm_vcpu_get_hyp_pc(vcpu));
+ BUG();
+ panic("KVM: Hypervisor undefined exception!\n");
+ case ARM_EXCEPTION_DATA_ABORT:
+ case ARM_EXCEPTION_PREF_ABORT:
+ case ARM_EXCEPTION_HVC:
+ /*
+ * See ARM ARM B1.14.1: "Hyp traps on instructions
+ * that fail their condition code check"
+ */
+ if (!kvm_condition_valid(vcpu)) {
+ kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+ return 1;
+ }
+
+ exit_handler = kvm_get_exit_handler(vcpu);
+
+ return exit_handler(vcpu, run);
+ default:
+ kvm_pr_unimpl("Unsupported exception type: %d",
+ exception_index);
+ run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
+ return 0;
+ }
+}
diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S
new file mode 100644
index 000000000..3988e72d1
--- /dev/null
+++ b/arch/arm/kvm/init.S
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/unified.h>
+#include <asm/asm-offsets.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_mmu.h>
+
+/********************************************************************
+ * Hypervisor initialization
+ * - should be called with:
+ * r0 = top of Hyp stack (kernel VA)
+ * r1 = pointer to hyp vectors
+ * r2,r3 = Hypervisor pgd pointer
+ *
+ * The init scenario is:
+ * - We jump in HYP with four parameters: boot HYP pgd, runtime HYP pgd,
+ * runtime stack, runtime vectors
+ * - Enable the MMU with the boot pgd
+ * - Jump to a target into the trampoline page (remember, this is the same
+ * physical page!)
+ * - Now switch to the runtime pgd (same VA, and still the same physical
+ * page!)
+ * - Invalidate TLBs
+ * - Set stack and vectors
+ * - Profit! (or eret, if you only care about the code).
+ *
+ * As we only have four registers available to pass parameters (and we
+ * need six), we split the init in two phases:
+ * - Phase 1: r0 = 0, r1 = 0, r2,r3 contain the boot PGD.
+ * Provides the basic HYP init, and enable the MMU.
+ * - Phase 2: r0 = ToS, r1 = vectors, r2,r3 contain the runtime PGD.
+ * Switches to the runtime PGD, set stack and vectors.
+ */
+
+ .text
+ .pushsection .hyp.idmap.text,"ax"
+ .align 5
+__kvm_hyp_init:
+ .globl __kvm_hyp_init
+
+ @ Hyp-mode exception vector
+ W(b) .
+ W(b) .
+ W(b) .
+ W(b) .
+ W(b) .
+ W(b) __do_hyp_init
+ W(b) .
+ W(b) .
+
+__do_hyp_init:
+ cmp r0, #0 @ We have a SP?
+ bne phase2 @ Yes, second stage init
+
+ @ Set the HTTBR to point to the hypervisor PGD pointer passed
+ mcrr p15, 4, rr_lo_hi(r2, r3), c2
+
+ @ Set the HTCR and VTCR to the same shareability and cacheability
+ @ settings as the non-secure TTBCR and with T0SZ == 0.
+ mrc p15, 4, r0, c2, c0, 2 @ HTCR
+ ldr r2, =HTCR_MASK
+ bic r0, r0, r2
+ mrc p15, 0, r1, c2, c0, 2 @ TTBCR
+ and r1, r1, #(HTCR_MASK & ~TTBCR_T0SZ)
+ orr r0, r0, r1
+ mcr p15, 4, r0, c2, c0, 2 @ HTCR
+
+ mrc p15, 4, r1, c2, c1, 2 @ VTCR
+ ldr r2, =VTCR_MASK
+ bic r1, r1, r2
+ bic r0, r0, #(~VTCR_HTCR_SH) @ clear non-reusable HTCR bits
+ orr r1, r0, r1
+ orr r1, r1, #(KVM_VTCR_SL0 | KVM_VTCR_T0SZ | KVM_VTCR_S)
+ mcr p15, 4, r1, c2, c1, 2 @ VTCR
+
+ @ Use the same memory attributes for hyp. accesses as the kernel
+ @ (copy MAIRx ro HMAIRx).
+ mrc p15, 0, r0, c10, c2, 0
+ mcr p15, 4, r0, c10, c2, 0
+ mrc p15, 0, r0, c10, c2, 1
+ mcr p15, 4, r0, c10, c2, 1
+
+ @ Invalidate the stale TLBs from Bootloader
+ mcr p15, 4, r0, c8, c7, 0 @ TLBIALLH
+ dsb ish
+
+ @ Set the HSCTLR to:
+ @ - ARM/THUMB exceptions: Kernel config (Thumb-2 kernel)
+ @ - Endianness: Kernel config
+ @ - Fast Interrupt Features: Kernel config
+ @ - Write permission implies XN: disabled
+ @ - Instruction cache: enabled
+ @ - Data/Unified cache: enabled
+ @ - Memory alignment checks: enabled
+ @ - MMU: enabled (this code must be run from an identity mapping)
+ mrc p15, 4, r0, c1, c0, 0 @ HSCR
+ ldr r2, =HSCTLR_MASK
+ bic r0, r0, r2
+ mrc p15, 0, r1, c1, c0, 0 @ SCTLR
+ ldr r2, =(HSCTLR_EE | HSCTLR_FI | HSCTLR_I | HSCTLR_C)
+ and r1, r1, r2
+ ARM( ldr r2, =(HSCTLR_M | HSCTLR_A) )
+ THUMB( ldr r2, =(HSCTLR_M | HSCTLR_A | HSCTLR_TE) )
+ orr r1, r1, r2
+ orr r0, r0, r1
+ isb
+ mcr p15, 4, r0, c1, c0, 0 @ HSCR
+
+ @ End of init phase-1
+ eret
+
+phase2:
+ @ Set stack pointer
+ mov sp, r0
+
+ @ Set HVBAR to point to the HYP vectors
+ mcr p15, 4, r1, c12, c0, 0 @ HVBAR
+
+ @ Jump to the trampoline page
+ ldr r0, =TRAMPOLINE_VA
+ adr r1, target
+ bfi r0, r1, #0, #PAGE_SHIFT
+ ret r0
+
+target: @ We're now in the trampoline code, switch page tables
+ mcrr p15, 4, rr_lo_hi(r2, r3), c2
+ isb
+
+ @ Invalidate the old TLBs
+ mcr p15, 4, r0, c8, c7, 0 @ TLBIALLH
+ dsb ish
+
+ eret
+
+ .ltorg
+
+ .globl __kvm_hyp_init_end
+__kvm_hyp_init_end:
+
+ .popsection
diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
new file mode 100644
index 000000000..f7db3a5d8
--- /dev/null
+++ b/arch/arm/kvm/interrupts.S
@@ -0,0 +1,524 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/linkage.h>
+#include <linux/const.h>
+#include <asm/unified.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include <asm/asm-offsets.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_arm.h>
+#include <asm/vfpmacros.h>
+#include "interrupts_head.S"
+
+ .text
+
+__kvm_hyp_code_start:
+ .globl __kvm_hyp_code_start
+
+/********************************************************************
+ * Flush per-VMID TLBs
+ *
+ * void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
+ *
+ * We rely on the hardware to broadcast the TLB invalidation to all CPUs
+ * inside the inner-shareable domain (which is the case for all v7
+ * implementations). If we come across a non-IS SMP implementation, we'll
+ * have to use an IPI based mechanism. Until then, we stick to the simple
+ * hardware assisted version.
+ *
+ * As v7 does not support flushing per IPA, just nuke the whole TLB
+ * instead, ignoring the ipa value.
+ */
+ENTRY(__kvm_tlb_flush_vmid_ipa)
+ push {r2, r3}
+
+ dsb ishst
+ add r0, r0, #KVM_VTTBR
+ ldrd r2, r3, [r0]
+ mcrr p15, 6, rr_lo_hi(r2, r3), c2 @ Write VTTBR
+ isb
+ mcr p15, 0, r0, c8, c3, 0 @ TLBIALLIS (rt ignored)
+ dsb ish
+ isb
+ mov r2, #0
+ mov r3, #0
+ mcrr p15, 6, r2, r3, c2 @ Back to VMID #0
+ isb @ Not necessary if followed by eret
+
+ pop {r2, r3}
+ bx lr
+ENDPROC(__kvm_tlb_flush_vmid_ipa)
+
+/**
+ * void __kvm_tlb_flush_vmid(struct kvm *kvm) - Flush per-VMID TLBs
+ *
+ * Reuses __kvm_tlb_flush_vmid_ipa() for ARMv7, without passing address
+ * parameter
+ */
+
+ENTRY(__kvm_tlb_flush_vmid)
+ b __kvm_tlb_flush_vmid_ipa
+ENDPROC(__kvm_tlb_flush_vmid)
+
+/********************************************************************
+ * Flush TLBs and instruction caches of all CPUs inside the inner-shareable
+ * domain, for all VMIDs
+ *
+ * void __kvm_flush_vm_context(void);
+ */
+ENTRY(__kvm_flush_vm_context)
+ mov r0, #0 @ rn parameter for c15 flushes is SBZ
+
+ /* Invalidate NS Non-Hyp TLB Inner Shareable (TLBIALLNSNHIS) */
+ mcr p15, 4, r0, c8, c3, 4
+ /* Invalidate instruction caches Inner Shareable (ICIALLUIS) */
+ mcr p15, 0, r0, c7, c1, 0
+ dsb ish
+ isb @ Not necessary if followed by eret
+
+ bx lr
+ENDPROC(__kvm_flush_vm_context)
+
+
+/********************************************************************
+ * Hypervisor world-switch code
+ *
+ *
+ * int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
+ */
+ENTRY(__kvm_vcpu_run)
+ @ Save the vcpu pointer
+ mcr p15, 4, vcpu, c13, c0, 2 @ HTPIDR
+
+ save_host_regs
+
+ restore_vgic_state
+ restore_timer_state
+
+ @ Store hardware CP15 state and load guest state
+ read_cp15_state store_to_vcpu = 0
+ write_cp15_state read_from_vcpu = 1
+
+ @ If the host kernel has not been configured with VFPv3 support,
+ @ then it is safer if we deny guests from using it as well.
+#ifdef CONFIG_VFPv3
+ @ Set FPEXC_EN so the guest doesn't trap floating point instructions
+ VFPFMRX r2, FPEXC @ VMRS
+ push {r2}
+ orr r2, r2, #FPEXC_EN
+ VFPFMXR FPEXC, r2 @ VMSR
+#endif
+
+ @ Configure Hyp-role
+ configure_hyp_role vmentry
+
+ @ Trap coprocessor CRx accesses
+ set_hstr vmentry
+ set_hcptr vmentry, (HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11))
+ set_hdcr vmentry
+
+ @ Write configured ID register into MIDR alias
+ ldr r1, [vcpu, #VCPU_MIDR]
+ mcr p15, 4, r1, c0, c0, 0
+
+ @ Write guest view of MPIDR into VMPIDR
+ ldr r1, [vcpu, #CP15_OFFSET(c0_MPIDR)]
+ mcr p15, 4, r1, c0, c0, 5
+
+ @ Set up guest memory translation
+ ldr r1, [vcpu, #VCPU_KVM]
+ add r1, r1, #KVM_VTTBR
+ ldrd r2, r3, [r1]
+ mcrr p15, 6, rr_lo_hi(r2, r3), c2 @ Write VTTBR
+
+ @ We're all done, just restore the GPRs and go to the guest
+ restore_guest_regs
+ clrex @ Clear exclusive monitor
+ eret
+
+__kvm_vcpu_return:
+ /*
+ * return convention:
+ * guest r0, r1, r2 saved on the stack
+ * r0: vcpu pointer
+ * r1: exception code
+ */
+ save_guest_regs
+
+ @ Set VMID == 0
+ mov r2, #0
+ mov r3, #0
+ mcrr p15, 6, r2, r3, c2 @ Write VTTBR
+
+ @ Don't trap coprocessor accesses for host kernel
+ set_hstr vmexit
+ set_hdcr vmexit
+ set_hcptr vmexit, (HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11)), after_vfp_restore
+
+#ifdef CONFIG_VFPv3
+ @ Switch VFP/NEON hardware state to the host's
+ add r7, vcpu, #VCPU_VFP_GUEST
+ store_vfp_state r7
+ add r7, vcpu, #VCPU_VFP_HOST
+ ldr r7, [r7]
+ restore_vfp_state r7
+
+after_vfp_restore:
+ @ Restore FPEXC_EN which we clobbered on entry
+ pop {r2}
+ VFPFMXR FPEXC, r2
+#else
+after_vfp_restore:
+#endif
+
+ @ Reset Hyp-role
+ configure_hyp_role vmexit
+
+ @ Let host read hardware MIDR
+ mrc p15, 0, r2, c0, c0, 0
+ mcr p15, 4, r2, c0, c0, 0
+
+ @ Back to hardware MPIDR
+ mrc p15, 0, r2, c0, c0, 5
+ mcr p15, 4, r2, c0, c0, 5
+
+ @ Store guest CP15 state and restore host state
+ read_cp15_state store_to_vcpu = 1
+ write_cp15_state read_from_vcpu = 0
+
+ save_timer_state
+ save_vgic_state
+
+ restore_host_regs
+ clrex @ Clear exclusive monitor
+#ifndef CONFIG_CPU_ENDIAN_BE8
+ mov r0, r1 @ Return the return code
+ mov r1, #0 @ Clear upper bits in return value
+#else
+ @ r1 already has return code
+ mov r0, #0 @ Clear upper bits in return value
+#endif /* CONFIG_CPU_ENDIAN_BE8 */
+ bx lr @ return to IOCTL
+
+/********************************************************************
+ * Call function in Hyp mode
+ *
+ *
+ * u64 kvm_call_hyp(void *hypfn, ...);
+ *
+ * This is not really a variadic function in the classic C-way and care must
+ * be taken when calling this to ensure parameters are passed in registers
+ * only, since the stack will change between the caller and the callee.
+ *
+ * Call the function with the first argument containing a pointer to the
+ * function you wish to call in Hyp mode, and subsequent arguments will be
+ * passed as r0, r1, and r2 (a maximum of 3 arguments in addition to the
+ * function pointer can be passed). The function being called must be mapped
+ * in Hyp mode (see init_hyp_mode in arch/arm/kvm/arm.c). Return values are
+ * passed in r0 and r1.
+ *
+ * A function pointer with a value of 0xffffffff has a special meaning,
+ * and is used to implement __hyp_get_vectors in the same way as in
+ * arch/arm/kernel/hyp_stub.S.
+ *
+ * The calling convention follows the standard AAPCS:
+ * r0 - r3: caller save
+ * r12: caller save
+ * rest: callee save
+ */
+ENTRY(kvm_call_hyp)
+ hvc #0
+ bx lr
+
+/********************************************************************
+ * Hypervisor exception vector and handlers
+ *
+ *
+ * The KVM/ARM Hypervisor ABI is defined as follows:
+ *
+ * Entry to Hyp mode from the host kernel will happen _only_ when an HVC
+ * instruction is issued since all traps are disabled when running the host
+ * kernel as per the Hyp-mode initialization at boot time.
+ *
+ * HVC instructions cause a trap to the vector page + offset 0x14 (see hyp_hvc
+ * below) when the HVC instruction is called from SVC mode (i.e. a guest or the
+ * host kernel) and they cause a trap to the vector page + offset 0x8 when HVC
+ * instructions are called from within Hyp-mode.
+ *
+ * Hyp-ABI: Calling HYP-mode functions from host (in SVC mode):
+ * Switching to Hyp mode is done through a simple HVC #0 instruction. The
+ * exception vector code will check that the HVC comes from VMID==0 and if
+ * so will push the necessary state (SPSR, lr_usr) on the Hyp stack.
+ * - r0 contains a pointer to a HYP function
+ * - r1, r2, and r3 contain arguments to the above function.
+ * - The HYP function will be called with its arguments in r0, r1 and r2.
+ * On HYP function return, we return directly to SVC.
+ *
+ * Note that the above is used to execute code in Hyp-mode from a host-kernel
+ * point of view, and is a different concept from performing a world-switch and
+ * executing guest code SVC mode (with a VMID != 0).
+ */
+
+/* Handle undef, svc, pabt, or dabt by crashing with a user notice */
+.macro bad_exception exception_code, panic_str
+ push {r0-r2}
+ mrrc p15, 6, r0, r1, c2 @ Read VTTBR
+ lsr r1, r1, #16
+ ands r1, r1, #0xff
+ beq 99f
+
+ load_vcpu @ Load VCPU pointer
+ .if \exception_code == ARM_EXCEPTION_DATA_ABORT
+ mrc p15, 4, r2, c5, c2, 0 @ HSR
+ mrc p15, 4, r1, c6, c0, 0 @ HDFAR
+ str r2, [vcpu, #VCPU_HSR]
+ str r1, [vcpu, #VCPU_HxFAR]
+ .endif
+ .if \exception_code == ARM_EXCEPTION_PREF_ABORT
+ mrc p15, 4, r2, c5, c2, 0 @ HSR
+ mrc p15, 4, r1, c6, c0, 2 @ HIFAR
+ str r2, [vcpu, #VCPU_HSR]
+ str r1, [vcpu, #VCPU_HxFAR]
+ .endif
+ mov r1, #\exception_code
+ b __kvm_vcpu_return
+
+ @ We were in the host already. Let's craft a panic-ing return to SVC.
+99: mrs r2, cpsr
+ bic r2, r2, #MODE_MASK
+ orr r2, r2, #SVC_MODE
+THUMB( orr r2, r2, #PSR_T_BIT )
+ msr spsr_cxsf, r2
+ mrs r1, ELR_hyp
+ ldr r2, =BSYM(panic)
+ msr ELR_hyp, r2
+ ldr r0, =\panic_str
+ clrex @ Clear exclusive monitor
+ eret
+.endm
+
+ .text
+
+ .align 5
+__kvm_hyp_vector:
+ .globl __kvm_hyp_vector
+
+ @ Hyp-mode exception vector
+ W(b) hyp_reset
+ W(b) hyp_undef
+ W(b) hyp_svc
+ W(b) hyp_pabt
+ W(b) hyp_dabt
+ W(b) hyp_hvc
+ W(b) hyp_irq
+ W(b) hyp_fiq
+
+ .align
+hyp_reset:
+ b hyp_reset
+
+ .align
+hyp_undef:
+ bad_exception ARM_EXCEPTION_UNDEFINED, und_die_str
+
+ .align
+hyp_svc:
+ bad_exception ARM_EXCEPTION_HVC, svc_die_str
+
+ .align
+hyp_pabt:
+ bad_exception ARM_EXCEPTION_PREF_ABORT, pabt_die_str
+
+ .align
+hyp_dabt:
+ bad_exception ARM_EXCEPTION_DATA_ABORT, dabt_die_str
+
+ .align
+hyp_hvc:
+ /*
+ * Getting here is either becuase of a trap from a guest or from calling
+ * HVC from the host kernel, which means "switch to Hyp mode".
+ */
+ push {r0, r1, r2}
+
+ @ Check syndrome register
+ mrc p15, 4, r1, c5, c2, 0 @ HSR
+ lsr r0, r1, #HSR_EC_SHIFT
+#ifdef CONFIG_VFPv3
+ cmp r0, #HSR_EC_CP_0_13
+ beq switch_to_guest_vfp
+#endif
+ cmp r0, #HSR_EC_HVC
+ bne guest_trap @ Not HVC instr.
+
+ /*
+ * Let's check if the HVC came from VMID 0 and allow simple
+ * switch to Hyp mode
+ */
+ mrrc p15, 6, r0, r2, c2
+ lsr r2, r2, #16
+ and r2, r2, #0xff
+ cmp r2, #0
+ bne guest_trap @ Guest called HVC
+
+host_switch_to_hyp:
+ pop {r0, r1, r2}
+
+ /* Check for __hyp_get_vectors */
+ cmp r0, #-1
+ mrceq p15, 4, r0, c12, c0, 0 @ get HVBAR
+ beq 1f
+
+ push {lr}
+ mrs lr, SPSR
+ push {lr}
+
+ mov lr, r0
+ mov r0, r1
+ mov r1, r2
+ mov r2, r3
+
+THUMB( orr lr, #1)
+ blx lr @ Call the HYP function
+
+ pop {lr}
+ msr SPSR_csxf, lr
+ pop {lr}
+1: eret
+
+guest_trap:
+ load_vcpu @ Load VCPU pointer to r0
+ str r1, [vcpu, #VCPU_HSR]
+
+ @ Check if we need the fault information
+ lsr r1, r1, #HSR_EC_SHIFT
+ cmp r1, #HSR_EC_IABT
+ mrceq p15, 4, r2, c6, c0, 2 @ HIFAR
+ beq 2f
+ cmp r1, #HSR_EC_DABT
+ bne 1f
+ mrc p15, 4, r2, c6, c0, 0 @ HDFAR
+
+2: str r2, [vcpu, #VCPU_HxFAR]
+
+ /*
+ * B3.13.5 Reporting exceptions taken to the Non-secure PL2 mode:
+ *
+ * Abort on the stage 2 translation for a memory access from a
+ * Non-secure PL1 or PL0 mode:
+ *
+ * For any Access flag fault or Translation fault, and also for any
+ * Permission fault on the stage 2 translation of a memory access
+ * made as part of a translation table walk for a stage 1 translation,
+ * the HPFAR holds the IPA that caused the fault. Otherwise, the HPFAR
+ * is UNKNOWN.
+ */
+
+ /* Check for permission fault, and S1PTW */
+ mrc p15, 4, r1, c5, c2, 0 @ HSR
+ and r0, r1, #HSR_FSC_TYPE
+ cmp r0, #FSC_PERM
+ tsteq r1, #(1 << 7) @ S1PTW
+ mrcne p15, 4, r2, c6, c0, 4 @ HPFAR
+ bne 3f
+
+ /* Preserve PAR */
+ mrrc p15, 0, r0, r1, c7 @ PAR
+ push {r0, r1}
+
+ /* Resolve IPA using the xFAR */
+ mcr p15, 0, r2, c7, c8, 0 @ ATS1CPR
+ isb
+ mrrc p15, 0, r0, r1, c7 @ PAR
+ tst r0, #1
+ bne 4f @ Failed translation
+ ubfx r2, r0, #12, #20
+ lsl r2, r2, #4
+ orr r2, r2, r1, lsl #24
+
+ /* Restore PAR */
+ pop {r0, r1}
+ mcrr p15, 0, r0, r1, c7 @ PAR
+
+3: load_vcpu @ Load VCPU pointer to r0
+ str r2, [r0, #VCPU_HPFAR]
+
+1: mov r1, #ARM_EXCEPTION_HVC
+ b __kvm_vcpu_return
+
+4: pop {r0, r1} @ Failed translation, return to guest
+ mcrr p15, 0, r0, r1, c7 @ PAR
+ clrex
+ pop {r0, r1, r2}
+ eret
+
+/*
+ * If VFPv3 support is not available, then we will not switch the VFP
+ * registers; however cp10 and cp11 accesses will still trap and fallback
+ * to the regular coprocessor emulation code, which currently will
+ * inject an undefined exception to the guest.
+ */
+#ifdef CONFIG_VFPv3
+switch_to_guest_vfp:
+ load_vcpu @ Load VCPU pointer to r0
+ push {r3-r7}
+
+ @ NEON/VFP used. Turn on VFP access.
+ set_hcptr vmtrap, (HCPTR_TCP(10) | HCPTR_TCP(11))
+
+ @ Switch VFP/NEON hardware state to the guest's
+ add r7, r0, #VCPU_VFP_HOST
+ ldr r7, [r7]
+ store_vfp_state r7
+ add r7, r0, #VCPU_VFP_GUEST
+ restore_vfp_state r7
+
+ pop {r3-r7}
+ pop {r0-r2}
+ clrex
+ eret
+#endif
+
+ .align
+hyp_irq:
+ push {r0, r1, r2}
+ mov r1, #ARM_EXCEPTION_IRQ
+ load_vcpu @ Load VCPU pointer to r0
+ b __kvm_vcpu_return
+
+ .align
+hyp_fiq:
+ b hyp_fiq
+
+ .ltorg
+
+__kvm_hyp_code_end:
+ .globl __kvm_hyp_code_end
+
+ .section ".rodata"
+
+und_die_str:
+ .ascii "unexpected undefined exception in Hyp mode at: %#08x\n"
+pabt_die_str:
+ .ascii "unexpected prefetch abort in Hyp mode at: %#08x\n"
+dabt_die_str:
+ .ascii "unexpected data abort in Hyp mode at: %#08x\n"
+svc_die_str:
+ .ascii "unexpected HVC/SVC trap in Hyp mode at: %#08x\n"
diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
new file mode 100644
index 000000000..48efe2ee4
--- /dev/null
+++ b/arch/arm/kvm/interrupts_head.S
@@ -0,0 +1,649 @@
+#include <linux/irqchip/arm-gic.h>
+#include <asm/assembler.h>
+
+#define VCPU_USR_REG(_reg_nr) (VCPU_USR_REGS + (_reg_nr * 4))
+#define VCPU_USR_SP (VCPU_USR_REG(13))
+#define VCPU_USR_LR (VCPU_USR_REG(14))
+#define CP15_OFFSET(_cp15_reg_idx) (VCPU_CP15 + (_cp15_reg_idx * 4))
+
+/*
+ * Many of these macros need to access the VCPU structure, which is always
+ * held in r0. These macros should never clobber r1, as it is used to hold the
+ * exception code on the return path (except of course the macro that switches
+ * all the registers before the final jump to the VM).
+ */
+vcpu .req r0 @ vcpu pointer always in r0
+
+/* Clobbers {r2-r6} */
+.macro store_vfp_state vfp_base
+ @ The VFPFMRX and VFPFMXR macros are the VMRS and VMSR instructions
+ VFPFMRX r2, FPEXC
+ @ Make sure VFP is enabled so we can touch the registers.
+ orr r6, r2, #FPEXC_EN
+ VFPFMXR FPEXC, r6
+
+ VFPFMRX r3, FPSCR
+ tst r2, #FPEXC_EX @ Check for VFP Subarchitecture
+ beq 1f
+ @ If FPEXC_EX is 0, then FPINST/FPINST2 reads are upredictable, so
+ @ we only need to save them if FPEXC_EX is set.
+ VFPFMRX r4, FPINST
+ tst r2, #FPEXC_FP2V
+ VFPFMRX r5, FPINST2, ne @ vmrsne
+ bic r6, r2, #FPEXC_EX @ FPEXC_EX disable
+ VFPFMXR FPEXC, r6
+1:
+ VFPFSTMIA \vfp_base, r6 @ Save VFP registers
+ stm \vfp_base, {r2-r5} @ Save FPEXC, FPSCR, FPINST, FPINST2
+.endm
+
+/* Assume FPEXC_EN is on and FPEXC_EX is off, clobbers {r2-r6} */
+.macro restore_vfp_state vfp_base
+ VFPFLDMIA \vfp_base, r6 @ Load VFP registers
+ ldm \vfp_base, {r2-r5} @ Load FPEXC, FPSCR, FPINST, FPINST2
+
+ VFPFMXR FPSCR, r3
+ tst r2, #FPEXC_EX @ Check for VFP Subarchitecture
+ beq 1f
+ VFPFMXR FPINST, r4
+ tst r2, #FPEXC_FP2V
+ VFPFMXR FPINST2, r5, ne
+1:
+ VFPFMXR FPEXC, r2 @ FPEXC (last, in case !EN)
+.endm
+
+/* These are simply for the macros to work - value don't have meaning */
+.equ usr, 0
+.equ svc, 1
+.equ abt, 2
+.equ und, 3
+.equ irq, 4
+.equ fiq, 5
+
+.macro push_host_regs_mode mode
+ mrs r2, SP_\mode
+ mrs r3, LR_\mode
+ mrs r4, SPSR_\mode
+ push {r2, r3, r4}
+.endm
+
+/*
+ * Store all host persistent registers on the stack.
+ * Clobbers all registers, in all modes, except r0 and r1.
+ */
+.macro save_host_regs
+ /* Hyp regs. Only ELR_hyp (SPSR_hyp already saved) */
+ mrs r2, ELR_hyp
+ push {r2}
+
+ /* usr regs */
+ push {r4-r12} @ r0-r3 are always clobbered
+ mrs r2, SP_usr
+ mov r3, lr
+ push {r2, r3}
+
+ push_host_regs_mode svc
+ push_host_regs_mode abt
+ push_host_regs_mode und
+ push_host_regs_mode irq
+
+ /* fiq regs */
+ mrs r2, r8_fiq
+ mrs r3, r9_fiq
+ mrs r4, r10_fiq
+ mrs r5, r11_fiq
+ mrs r6, r12_fiq
+ mrs r7, SP_fiq
+ mrs r8, LR_fiq
+ mrs r9, SPSR_fiq
+ push {r2-r9}
+.endm
+
+.macro pop_host_regs_mode mode
+ pop {r2, r3, r4}
+ msr SP_\mode, r2
+ msr LR_\mode, r3
+ msr SPSR_\mode, r4
+.endm
+
+/*
+ * Restore all host registers from the stack.
+ * Clobbers all registers, in all modes, except r0 and r1.
+ */
+.macro restore_host_regs
+ pop {r2-r9}
+ msr r8_fiq, r2
+ msr r9_fiq, r3
+ msr r10_fiq, r4
+ msr r11_fiq, r5
+ msr r12_fiq, r6
+ msr SP_fiq, r7
+ msr LR_fiq, r8
+ msr SPSR_fiq, r9
+
+ pop_host_regs_mode irq
+ pop_host_regs_mode und
+ pop_host_regs_mode abt
+ pop_host_regs_mode svc
+
+ pop {r2, r3}
+ msr SP_usr, r2
+ mov lr, r3
+ pop {r4-r12}
+
+ pop {r2}
+ msr ELR_hyp, r2
+.endm
+
+/*
+ * Restore SP, LR and SPSR for a given mode. offset is the offset of
+ * this mode's registers from the VCPU base.
+ *
+ * Assumes vcpu pointer in vcpu reg
+ *
+ * Clobbers r1, r2, r3, r4.
+ */
+.macro restore_guest_regs_mode mode, offset
+ add r1, vcpu, \offset
+ ldm r1, {r2, r3, r4}
+ msr SP_\mode, r2
+ msr LR_\mode, r3
+ msr SPSR_\mode, r4
+.endm
+
+/*
+ * Restore all guest registers from the vcpu struct.
+ *
+ * Assumes vcpu pointer in vcpu reg
+ *
+ * Clobbers *all* registers.
+ */
+.macro restore_guest_regs
+ restore_guest_regs_mode svc, #VCPU_SVC_REGS
+ restore_guest_regs_mode abt, #VCPU_ABT_REGS
+ restore_guest_regs_mode und, #VCPU_UND_REGS
+ restore_guest_regs_mode irq, #VCPU_IRQ_REGS
+
+ add r1, vcpu, #VCPU_FIQ_REGS
+ ldm r1, {r2-r9}
+ msr r8_fiq, r2
+ msr r9_fiq, r3
+ msr r10_fiq, r4
+ msr r11_fiq, r5
+ msr r12_fiq, r6
+ msr SP_fiq, r7
+ msr LR_fiq, r8
+ msr SPSR_fiq, r9
+
+ @ Load return state
+ ldr r2, [vcpu, #VCPU_PC]
+ ldr r3, [vcpu, #VCPU_CPSR]
+ msr ELR_hyp, r2
+ msr SPSR_cxsf, r3
+
+ @ Load user registers
+ ldr r2, [vcpu, #VCPU_USR_SP]
+ ldr r3, [vcpu, #VCPU_USR_LR]
+ msr SP_usr, r2
+ mov lr, r3
+ add vcpu, vcpu, #(VCPU_USR_REGS)
+ ldm vcpu, {r0-r12}
+.endm
+
+/*
+ * Save SP, LR and SPSR for a given mode. offset is the offset of
+ * this mode's registers from the VCPU base.
+ *
+ * Assumes vcpu pointer in vcpu reg
+ *
+ * Clobbers r2, r3, r4, r5.
+ */
+.macro save_guest_regs_mode mode, offset
+ add r2, vcpu, \offset
+ mrs r3, SP_\mode
+ mrs r4, LR_\mode
+ mrs r5, SPSR_\mode
+ stm r2, {r3, r4, r5}
+.endm
+
+/*
+ * Save all guest registers to the vcpu struct
+ * Expects guest's r0, r1, r2 on the stack.
+ *
+ * Assumes vcpu pointer in vcpu reg
+ *
+ * Clobbers r2, r3, r4, r5.
+ */
+.macro save_guest_regs
+ @ Store usr registers
+ add r2, vcpu, #VCPU_USR_REG(3)
+ stm r2, {r3-r12}
+ add r2, vcpu, #VCPU_USR_REG(0)
+ pop {r3, r4, r5} @ r0, r1, r2
+ stm r2, {r3, r4, r5}
+ mrs r2, SP_usr
+ mov r3, lr
+ str r2, [vcpu, #VCPU_USR_SP]
+ str r3, [vcpu, #VCPU_USR_LR]
+
+ @ Store return state
+ mrs r2, ELR_hyp
+ mrs r3, spsr
+ str r2, [vcpu, #VCPU_PC]
+ str r3, [vcpu, #VCPU_CPSR]
+
+ @ Store other guest registers
+ save_guest_regs_mode svc, #VCPU_SVC_REGS
+ save_guest_regs_mode abt, #VCPU_ABT_REGS
+ save_guest_regs_mode und, #VCPU_UND_REGS
+ save_guest_regs_mode irq, #VCPU_IRQ_REGS
+.endm
+
+/* Reads cp15 registers from hardware and stores them in memory
+ * @store_to_vcpu: If 0, registers are written in-order to the stack,
+ * otherwise to the VCPU struct pointed to by vcpup
+ *
+ * Assumes vcpu pointer in vcpu reg
+ *
+ * Clobbers r2 - r12
+ */
+.macro read_cp15_state store_to_vcpu
+ mrc p15, 0, r2, c1, c0, 0 @ SCTLR
+ mrc p15, 0, r3, c1, c0, 2 @ CPACR
+ mrc p15, 0, r4, c2, c0, 2 @ TTBCR
+ mrc p15, 0, r5, c3, c0, 0 @ DACR
+ mrrc p15, 0, r6, r7, c2 @ TTBR 0
+ mrrc p15, 1, r8, r9, c2 @ TTBR 1
+ mrc p15, 0, r10, c10, c2, 0 @ PRRR
+ mrc p15, 0, r11, c10, c2, 1 @ NMRR
+ mrc p15, 2, r12, c0, c0, 0 @ CSSELR
+
+ .if \store_to_vcpu == 0
+ push {r2-r12} @ Push CP15 registers
+ .else
+ str r2, [vcpu, #CP15_OFFSET(c1_SCTLR)]
+ str r3, [vcpu, #CP15_OFFSET(c1_CPACR)]
+ str r4, [vcpu, #CP15_OFFSET(c2_TTBCR)]
+ str r5, [vcpu, #CP15_OFFSET(c3_DACR)]
+ add r2, vcpu, #CP15_OFFSET(c2_TTBR0)
+ strd r6, r7, [r2]
+ add r2, vcpu, #CP15_OFFSET(c2_TTBR1)
+ strd r8, r9, [r2]
+ str r10, [vcpu, #CP15_OFFSET(c10_PRRR)]
+ str r11, [vcpu, #CP15_OFFSET(c10_NMRR)]
+ str r12, [vcpu, #CP15_OFFSET(c0_CSSELR)]
+ .endif
+
+ mrc p15, 0, r2, c13, c0, 1 @ CID
+ mrc p15, 0, r3, c13, c0, 2 @ TID_URW
+ mrc p15, 0, r4, c13, c0, 3 @ TID_URO
+ mrc p15, 0, r5, c13, c0, 4 @ TID_PRIV
+ mrc p15, 0, r6, c5, c0, 0 @ DFSR
+ mrc p15, 0, r7, c5, c0, 1 @ IFSR
+ mrc p15, 0, r8, c5, c1, 0 @ ADFSR
+ mrc p15, 0, r9, c5, c1, 1 @ AIFSR
+ mrc p15, 0, r10, c6, c0, 0 @ DFAR
+ mrc p15, 0, r11, c6, c0, 2 @ IFAR
+ mrc p15, 0, r12, c12, c0, 0 @ VBAR
+
+ .if \store_to_vcpu == 0
+ push {r2-r12} @ Push CP15 registers
+ .else
+ str r2, [vcpu, #CP15_OFFSET(c13_CID)]
+ str r3, [vcpu, #CP15_OFFSET(c13_TID_URW)]
+ str r4, [vcpu, #CP15_OFFSET(c13_TID_URO)]
+ str r5, [vcpu, #CP15_OFFSET(c13_TID_PRIV)]
+ str r6, [vcpu, #CP15_OFFSET(c5_DFSR)]
+ str r7, [vcpu, #CP15_OFFSET(c5_IFSR)]
+ str r8, [vcpu, #CP15_OFFSET(c5_ADFSR)]
+ str r9, [vcpu, #CP15_OFFSET(c5_AIFSR)]
+ str r10, [vcpu, #CP15_OFFSET(c6_DFAR)]
+ str r11, [vcpu, #CP15_OFFSET(c6_IFAR)]
+ str r12, [vcpu, #CP15_OFFSET(c12_VBAR)]
+ .endif
+
+ mrc p15, 0, r2, c14, c1, 0 @ CNTKCTL
+ mrrc p15, 0, r4, r5, c7 @ PAR
+ mrc p15, 0, r6, c10, c3, 0 @ AMAIR0
+ mrc p15, 0, r7, c10, c3, 1 @ AMAIR1
+
+ .if \store_to_vcpu == 0
+ push {r2,r4-r7}
+ .else
+ str r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)]
+ add r12, vcpu, #CP15_OFFSET(c7_PAR)
+ strd r4, r5, [r12]
+ str r6, [vcpu, #CP15_OFFSET(c10_AMAIR0)]
+ str r7, [vcpu, #CP15_OFFSET(c10_AMAIR1)]
+ .endif
+.endm
+
+/*
+ * Reads cp15 registers from memory and writes them to hardware
+ * @read_from_vcpu: If 0, registers are read in-order from the stack,
+ * otherwise from the VCPU struct pointed to by vcpup
+ *
+ * Assumes vcpu pointer in vcpu reg
+ */
+.macro write_cp15_state read_from_vcpu
+ .if \read_from_vcpu == 0
+ pop {r2,r4-r7}
+ .else
+ ldr r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)]
+ add r12, vcpu, #CP15_OFFSET(c7_PAR)
+ ldrd r4, r5, [r12]
+ ldr r6, [vcpu, #CP15_OFFSET(c10_AMAIR0)]
+ ldr r7, [vcpu, #CP15_OFFSET(c10_AMAIR1)]
+ .endif
+
+ mcr p15, 0, r2, c14, c1, 0 @ CNTKCTL
+ mcrr p15, 0, r4, r5, c7 @ PAR
+ mcr p15, 0, r6, c10, c3, 0 @ AMAIR0
+ mcr p15, 0, r7, c10, c3, 1 @ AMAIR1
+
+ .if \read_from_vcpu == 0
+ pop {r2-r12}
+ .else
+ ldr r2, [vcpu, #CP15_OFFSET(c13_CID)]
+ ldr r3, [vcpu, #CP15_OFFSET(c13_TID_URW)]
+ ldr r4, [vcpu, #CP15_OFFSET(c13_TID_URO)]
+ ldr r5, [vcpu, #CP15_OFFSET(c13_TID_PRIV)]
+ ldr r6, [vcpu, #CP15_OFFSET(c5_DFSR)]
+ ldr r7, [vcpu, #CP15_OFFSET(c5_IFSR)]
+ ldr r8, [vcpu, #CP15_OFFSET(c5_ADFSR)]
+ ldr r9, [vcpu, #CP15_OFFSET(c5_AIFSR)]
+ ldr r10, [vcpu, #CP15_OFFSET(c6_DFAR)]
+ ldr r11, [vcpu, #CP15_OFFSET(c6_IFAR)]
+ ldr r12, [vcpu, #CP15_OFFSET(c12_VBAR)]
+ .endif
+
+ mcr p15, 0, r2, c13, c0, 1 @ CID
+ mcr p15, 0, r3, c13, c0, 2 @ TID_URW
+ mcr p15, 0, r4, c13, c0, 3 @ TID_URO
+ mcr p15, 0, r5, c13, c0, 4 @ TID_PRIV
+ mcr p15, 0, r6, c5, c0, 0 @ DFSR
+ mcr p15, 0, r7, c5, c0, 1 @ IFSR
+ mcr p15, 0, r8, c5, c1, 0 @ ADFSR
+ mcr p15, 0, r9, c5, c1, 1 @ AIFSR
+ mcr p15, 0, r10, c6, c0, 0 @ DFAR
+ mcr p15, 0, r11, c6, c0, 2 @ IFAR
+ mcr p15, 0, r12, c12, c0, 0 @ VBAR
+
+ .if \read_from_vcpu == 0
+ pop {r2-r12}
+ .else
+ ldr r2, [vcpu, #CP15_OFFSET(c1_SCTLR)]
+ ldr r3, [vcpu, #CP15_OFFSET(c1_CPACR)]
+ ldr r4, [vcpu, #CP15_OFFSET(c2_TTBCR)]
+ ldr r5, [vcpu, #CP15_OFFSET(c3_DACR)]
+ add r12, vcpu, #CP15_OFFSET(c2_TTBR0)
+ ldrd r6, r7, [r12]
+ add r12, vcpu, #CP15_OFFSET(c2_TTBR1)
+ ldrd r8, r9, [r12]
+ ldr r10, [vcpu, #CP15_OFFSET(c10_PRRR)]
+ ldr r11, [vcpu, #CP15_OFFSET(c10_NMRR)]
+ ldr r12, [vcpu, #CP15_OFFSET(c0_CSSELR)]
+ .endif
+
+ mcr p15, 0, r2, c1, c0, 0 @ SCTLR
+ mcr p15, 0, r3, c1, c0, 2 @ CPACR
+ mcr p15, 0, r4, c2, c0, 2 @ TTBCR
+ mcr p15, 0, r5, c3, c0, 0 @ DACR
+ mcrr p15, 0, r6, r7, c2 @ TTBR 0
+ mcrr p15, 1, r8, r9, c2 @ TTBR 1
+ mcr p15, 0, r10, c10, c2, 0 @ PRRR
+ mcr p15, 0, r11, c10, c2, 1 @ NMRR
+ mcr p15, 2, r12, c0, c0, 0 @ CSSELR
+.endm
+
+/*
+ * Save the VGIC CPU state into memory
+ *
+ * Assumes vcpu pointer in vcpu reg
+ */
+.macro save_vgic_state
+ /* Get VGIC VCTRL base into r2 */
+ ldr r2, [vcpu, #VCPU_KVM]
+ ldr r2, [r2, #KVM_VGIC_VCTRL]
+ cmp r2, #0
+ beq 2f
+
+ /* Compute the address of struct vgic_cpu */
+ add r11, vcpu, #VCPU_VGIC_CPU
+
+ /* Save all interesting registers */
+ ldr r3, [r2, #GICH_HCR]
+ ldr r4, [r2, #GICH_VMCR]
+ ldr r5, [r2, #GICH_MISR]
+ ldr r6, [r2, #GICH_EISR0]
+ ldr r7, [r2, #GICH_EISR1]
+ ldr r8, [r2, #GICH_ELRSR0]
+ ldr r9, [r2, #GICH_ELRSR1]
+ ldr r10, [r2, #GICH_APR]
+ARM_BE8(rev r3, r3 )
+ARM_BE8(rev r4, r4 )
+ARM_BE8(rev r5, r5 )
+ARM_BE8(rev r6, r6 )
+ARM_BE8(rev r7, r7 )
+ARM_BE8(rev r8, r8 )
+ARM_BE8(rev r9, r9 )
+ARM_BE8(rev r10, r10 )
+
+ str r3, [r11, #VGIC_V2_CPU_HCR]
+ str r4, [r11, #VGIC_V2_CPU_VMCR]
+ str r5, [r11, #VGIC_V2_CPU_MISR]
+#ifdef CONFIG_CPU_ENDIAN_BE8
+ str r6, [r11, #(VGIC_V2_CPU_EISR + 4)]
+ str r7, [r11, #VGIC_V2_CPU_EISR]
+ str r8, [r11, #(VGIC_V2_CPU_ELRSR + 4)]
+ str r9, [r11, #VGIC_V2_CPU_ELRSR]
+#else
+ str r6, [r11, #VGIC_V2_CPU_EISR]
+ str r7, [r11, #(VGIC_V2_CPU_EISR + 4)]
+ str r8, [r11, #VGIC_V2_CPU_ELRSR]
+ str r9, [r11, #(VGIC_V2_CPU_ELRSR + 4)]
+#endif
+ str r10, [r11, #VGIC_V2_CPU_APR]
+
+ /* Clear GICH_HCR */
+ mov r5, #0
+ str r5, [r2, #GICH_HCR]
+
+ /* Save list registers */
+ add r2, r2, #GICH_LR0
+ add r3, r11, #VGIC_V2_CPU_LR
+ ldr r4, [r11, #VGIC_CPU_NR_LR]
+1: ldr r6, [r2], #4
+ARM_BE8(rev r6, r6 )
+ str r6, [r3], #4
+ subs r4, r4, #1
+ bne 1b
+2:
+.endm
+
+/*
+ * Restore the VGIC CPU state from memory
+ *
+ * Assumes vcpu pointer in vcpu reg
+ */
+.macro restore_vgic_state
+ /* Get VGIC VCTRL base into r2 */
+ ldr r2, [vcpu, #VCPU_KVM]
+ ldr r2, [r2, #KVM_VGIC_VCTRL]
+ cmp r2, #0
+ beq 2f
+
+ /* Compute the address of struct vgic_cpu */
+ add r11, vcpu, #VCPU_VGIC_CPU
+
+ /* We only restore a minimal set of registers */
+ ldr r3, [r11, #VGIC_V2_CPU_HCR]
+ ldr r4, [r11, #VGIC_V2_CPU_VMCR]
+ ldr r8, [r11, #VGIC_V2_CPU_APR]
+ARM_BE8(rev r3, r3 )
+ARM_BE8(rev r4, r4 )
+ARM_BE8(rev r8, r8 )
+
+ str r3, [r2, #GICH_HCR]
+ str r4, [r2, #GICH_VMCR]
+ str r8, [r2, #GICH_APR]
+
+ /* Restore list registers */
+ add r2, r2, #GICH_LR0
+ add r3, r11, #VGIC_V2_CPU_LR
+ ldr r4, [r11, #VGIC_CPU_NR_LR]
+1: ldr r6, [r3], #4
+ARM_BE8(rev r6, r6 )
+ str r6, [r2], #4
+ subs r4, r4, #1
+ bne 1b
+2:
+.endm
+
+#define CNTHCTL_PL1PCTEN (1 << 0)
+#define CNTHCTL_PL1PCEN (1 << 1)
+
+/*
+ * Save the timer state onto the VCPU and allow physical timer/counter access
+ * for the host.
+ *
+ * Assumes vcpu pointer in vcpu reg
+ * Clobbers r2-r5
+ */
+.macro save_timer_state
+ ldr r4, [vcpu, #VCPU_KVM]
+ ldr r2, [r4, #KVM_TIMER_ENABLED]
+ cmp r2, #0
+ beq 1f
+
+ mrc p15, 0, r2, c14, c3, 1 @ CNTV_CTL
+ str r2, [vcpu, #VCPU_TIMER_CNTV_CTL]
+ bic r2, #1 @ Clear ENABLE
+ mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL
+ isb
+
+ mrrc p15, 3, rr_lo_hi(r2, r3), c14 @ CNTV_CVAL
+ ldr r4, =VCPU_TIMER_CNTV_CVAL
+ add r5, vcpu, r4
+ strd r2, r3, [r5]
+
+ @ Ensure host CNTVCT == CNTPCT
+ mov r2, #0
+ mcrr p15, 4, r2, r2, c14 @ CNTVOFF
+
+1:
+ @ Allow physical timer/counter access for the host
+ mrc p15, 4, r2, c14, c1, 0 @ CNTHCTL
+ orr r2, r2, #(CNTHCTL_PL1PCEN | CNTHCTL_PL1PCTEN)
+ mcr p15, 4, r2, c14, c1, 0 @ CNTHCTL
+.endm
+
+/*
+ * Load the timer state from the VCPU and deny physical timer/counter access
+ * for the host.
+ *
+ * Assumes vcpu pointer in vcpu reg
+ * Clobbers r2-r5
+ */
+.macro restore_timer_state
+ @ Disallow physical timer access for the guest
+ @ Physical counter access is allowed
+ mrc p15, 4, r2, c14, c1, 0 @ CNTHCTL
+ orr r2, r2, #CNTHCTL_PL1PCTEN
+ bic r2, r2, #CNTHCTL_PL1PCEN
+ mcr p15, 4, r2, c14, c1, 0 @ CNTHCTL
+
+ ldr r4, [vcpu, #VCPU_KVM]
+ ldr r2, [r4, #KVM_TIMER_ENABLED]
+ cmp r2, #0
+ beq 1f
+
+ ldr r2, [r4, #KVM_TIMER_CNTVOFF]
+ ldr r3, [r4, #(KVM_TIMER_CNTVOFF + 4)]
+ mcrr p15, 4, rr_lo_hi(r2, r3), c14 @ CNTVOFF
+
+ ldr r4, =VCPU_TIMER_CNTV_CVAL
+ add r5, vcpu, r4
+ ldrd r2, r3, [r5]
+ mcrr p15, 3, rr_lo_hi(r2, r3), c14 @ CNTV_CVAL
+ isb
+
+ ldr r2, [vcpu, #VCPU_TIMER_CNTV_CTL]
+ and r2, r2, #3
+ mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL
+1:
+.endm
+
+.equ vmentry, 0
+.equ vmexit, 1
+
+/* Configures the HSTR (Hyp System Trap Register) on entry/return
+ * (hardware reset value is 0) */
+.macro set_hstr operation
+ mrc p15, 4, r2, c1, c1, 3
+ ldr r3, =HSTR_T(15)
+ .if \operation == vmentry
+ orr r2, r2, r3 @ Trap CR{15}
+ .else
+ bic r2, r2, r3 @ Don't trap any CRx accesses
+ .endif
+ mcr p15, 4, r2, c1, c1, 3
+.endm
+
+/* Configures the HCPTR (Hyp Coprocessor Trap Register) on entry/return
+ * (hardware reset value is 0). Keep previous value in r2.
+ * An ISB is emited on vmexit/vmtrap, but executed on vmexit only if
+ * VFP wasn't already enabled (always executed on vmtrap).
+ * If a label is specified with vmexit, it is branched to if VFP wasn't
+ * enabled.
+ */
+.macro set_hcptr operation, mask, label = none
+ mrc p15, 4, r2, c1, c1, 2
+ ldr r3, =\mask
+ .if \operation == vmentry
+ orr r3, r2, r3 @ Trap coproc-accesses defined in mask
+ .else
+ bic r3, r2, r3 @ Don't trap defined coproc-accesses
+ .endif
+ mcr p15, 4, r3, c1, c1, 2
+ .if \operation != vmentry
+ .if \operation == vmexit
+ tst r2, #(HCPTR_TCP(10) | HCPTR_TCP(11))
+ beq 1f
+ .endif
+ isb
+ .if \label != none
+ b \label
+ .endif
+1:
+ .endif
+.endm
+
+/* Configures the HDCR (Hyp Debug Configuration Register) on entry/return
+ * (hardware reset value is 0) */
+.macro set_hdcr operation
+ mrc p15, 4, r2, c1, c1, 1
+ ldr r3, =(HDCR_TPM|HDCR_TPMCR)
+ .if \operation == vmentry
+ orr r2, r2, r3 @ Trap some perfmon accesses
+ .else
+ bic r2, r2, r3 @ Don't trap any perfmon accesses
+ .endif
+ mcr p15, 4, r2, c1, c1, 1
+.endm
+
+/* Enable/Disable: stage-2 trans., trap interrupts, trap wfi, trap smc */
+.macro configure_hyp_role operation
+ .if \operation == vmentry
+ ldr r2, [vcpu, #VCPU_HCR]
+ ldr r3, [vcpu, #VCPU_IRQ_LINES]
+ orr r2, r2, r3
+ .else
+ mov r2, #0
+ .endif
+ mcr p15, 4, r2, c1, c1, 0 @ HCR
+.endm
+
+.macro load_vcpu
+ mrc p15, 4, vcpu, c13, c0, 2 @ HTPIDR
+.endm
diff --git a/arch/arm/kvm/mmio.c b/arch/arm/kvm/mmio.c
new file mode 100644
index 000000000..974b1c606
--- /dev/null
+++ b/arch/arm/kvm/mmio.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/kvm_host.h>
+#include <asm/kvm_mmio.h>
+#include <asm/kvm_emulate.h>
+#include <trace/events/kvm.h>
+
+#include "trace.h"
+
+static void mmio_write_buf(char *buf, unsigned int len, unsigned long data)
+{
+ void *datap = NULL;
+ union {
+ u8 byte;
+ u16 hword;
+ u32 word;
+ u64 dword;
+ } tmp;
+
+ switch (len) {
+ case 1:
+ tmp.byte = data;
+ datap = &tmp.byte;
+ break;
+ case 2:
+ tmp.hword = data;
+ datap = &tmp.hword;
+ break;
+ case 4:
+ tmp.word = data;
+ datap = &tmp.word;
+ break;
+ case 8:
+ tmp.dword = data;
+ datap = &tmp.dword;
+ break;
+ }
+
+ memcpy(buf, datap, len);
+}
+
+static unsigned long mmio_read_buf(char *buf, unsigned int len)
+{
+ unsigned long data = 0;
+ union {
+ u16 hword;
+ u32 word;
+ u64 dword;
+ } tmp;
+
+ switch (len) {
+ case 1:
+ data = buf[0];
+ break;
+ case 2:
+ memcpy(&tmp.hword, buf, len);
+ data = tmp.hword;
+ break;
+ case 4:
+ memcpy(&tmp.word, buf, len);
+ data = tmp.word;
+ break;
+ case 8:
+ memcpy(&tmp.dword, buf, len);
+ data = tmp.dword;
+ break;
+ }
+
+ return data;
+}
+
+/**
+ * kvm_handle_mmio_return -- Handle MMIO loads after user space emulation
+ * @vcpu: The VCPU pointer
+ * @run: The VCPU run struct containing the mmio data
+ *
+ * This should only be called after returning from userspace for MMIO load
+ * emulation.
+ */
+int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ unsigned long data;
+ unsigned int len;
+ int mask;
+
+ if (!run->mmio.is_write) {
+ len = run->mmio.len;
+ if (len > sizeof(unsigned long))
+ return -EINVAL;
+
+ data = mmio_read_buf(run->mmio.data, len);
+
+ if (vcpu->arch.mmio_decode.sign_extend &&
+ len < sizeof(unsigned long)) {
+ mask = 1U << ((len * 8) - 1);
+ data = (data ^ mask) - mask;
+ }
+
+ trace_kvm_mmio(KVM_TRACE_MMIO_READ, len, run->mmio.phys_addr,
+ data);
+ data = vcpu_data_host_to_guest(vcpu, data, len);
+ *vcpu_reg(vcpu, vcpu->arch.mmio_decode.rt) = data;
+ }
+
+ return 0;
+}
+
+static int decode_hsr(struct kvm_vcpu *vcpu, bool *is_write, int *len)
+{
+ unsigned long rt;
+ int access_size;
+ bool sign_extend;
+
+ if (kvm_vcpu_dabt_isextabt(vcpu)) {
+ /* cache operation on I/O addr, tell guest unsupported */
+ kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
+ return 1;
+ }
+
+ if (kvm_vcpu_dabt_iss1tw(vcpu)) {
+ /* page table accesses IO mem: tell guest to fix its TTBR */
+ kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
+ return 1;
+ }
+
+ access_size = kvm_vcpu_dabt_get_as(vcpu);
+ if (unlikely(access_size < 0))
+ return access_size;
+
+ *is_write = kvm_vcpu_dabt_iswrite(vcpu);
+ sign_extend = kvm_vcpu_dabt_issext(vcpu);
+ rt = kvm_vcpu_dabt_get_rd(vcpu);
+
+ *len = access_size;
+ vcpu->arch.mmio_decode.sign_extend = sign_extend;
+ vcpu->arch.mmio_decode.rt = rt;
+
+ /*
+ * The MMIO instruction is emulated and should not be re-executed
+ * in the guest.
+ */
+ kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+ return 0;
+}
+
+int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
+ phys_addr_t fault_ipa)
+{
+ unsigned long data;
+ unsigned long rt;
+ int ret;
+ bool is_write;
+ int len;
+ u8 data_buf[8];
+
+ /*
+ * Prepare MMIO operation. First decode the syndrome data we get
+ * from the CPU. Then try if some in-kernel emulation feels
+ * responsible, otherwise let user space do its magic.
+ */
+ if (kvm_vcpu_dabt_isvalid(vcpu)) {
+ ret = decode_hsr(vcpu, &is_write, &len);
+ if (ret)
+ return ret;
+ } else {
+ kvm_err("load/store instruction decoding not implemented\n");
+ return -ENOSYS;
+ }
+
+ rt = vcpu->arch.mmio_decode.rt;
+
+ if (is_write) {
+ data = vcpu_data_guest_to_host(vcpu, *vcpu_reg(vcpu, rt), len);
+
+ trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, len, fault_ipa, data);
+ mmio_write_buf(data_buf, len, data);
+
+ ret = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, fault_ipa, len,
+ data_buf);
+ } else {
+ trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, len,
+ fault_ipa, 0);
+
+ ret = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, fault_ipa, len,
+ data_buf);
+ }
+
+ /* Now prepare kvm_run for the potential return to userland. */
+ run->mmio.is_write = is_write;
+ run->mmio.phys_addr = fault_ipa;
+ run->mmio.len = len;
+ memcpy(run->mmio.data, data_buf, len);
+
+ if (!ret) {
+ /* We handled the access successfully in the kernel. */
+ kvm_handle_mmio_return(vcpu, run);
+ return 1;
+ }
+
+ run->exit_reason = KVM_EXIT_MMIO;
+ return 0;
+}
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
new file mode 100644
index 000000000..1d5accbd3
--- /dev/null
+++ b/arch/arm/kvm/mmu.c
@@ -0,0 +1,1926 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/mman.h>
+#include <linux/kvm_host.h>
+#include <linux/io.h>
+#include <linux/hugetlb.h>
+#include <trace/events/kvm.h>
+#include <asm/pgalloc.h>
+#include <asm/cacheflush.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_mmu.h>
+#include <asm/kvm_mmio.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_emulate.h>
+
+#include "trace.h"
+
+extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[];
+
+static pgd_t *boot_hyp_pgd;
+static pgd_t *hyp_pgd;
+static pgd_t *merged_hyp_pgd;
+static DEFINE_MUTEX(kvm_hyp_pgd_mutex);
+
+static unsigned long hyp_idmap_start;
+static unsigned long hyp_idmap_end;
+static phys_addr_t hyp_idmap_vector;
+
+#define hyp_pgd_order get_order(PTRS_PER_PGD * sizeof(pgd_t))
+
+#define kvm_pmd_huge(_x) (pmd_huge(_x) || pmd_trans_huge(_x))
+#define kvm_pud_huge(_x) pud_huge(_x)
+
+#define KVM_S2PTE_FLAG_IS_IOMAP (1UL << 0)
+#define KVM_S2_FLAG_LOGGING_ACTIVE (1UL << 1)
+
+static bool memslot_is_logging(struct kvm_memory_slot *memslot)
+{
+ return memslot->dirty_bitmap && !(memslot->flags & KVM_MEM_READONLY);
+}
+
+/**
+ * kvm_flush_remote_tlbs() - flush all VM TLB entries for v7/8
+ * @kvm: pointer to kvm structure.
+ *
+ * Interface to HYP function to flush all VM TLB entries
+ */
+void kvm_flush_remote_tlbs(struct kvm *kvm)
+{
+ kvm_call_hyp(__kvm_tlb_flush_vmid, kvm);
+}
+
+static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
+{
+ /*
+ * This function also gets called when dealing with HYP page
+ * tables. As HYP doesn't have an associated struct kvm (and
+ * the HYP page tables are fairly static), we don't do
+ * anything there.
+ */
+ if (kvm)
+ kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, kvm, ipa);
+}
+
+/*
+ * D-Cache management functions. They take the page table entries by
+ * value, as they are flushing the cache using the kernel mapping (or
+ * kmap on 32bit).
+ */
+static void kvm_flush_dcache_pte(pte_t pte)
+{
+ __kvm_flush_dcache_pte(pte);
+}
+
+static void kvm_flush_dcache_pmd(pmd_t pmd)
+{
+ __kvm_flush_dcache_pmd(pmd);
+}
+
+static void kvm_flush_dcache_pud(pud_t pud)
+{
+ __kvm_flush_dcache_pud(pud);
+}
+
+/**
+ * stage2_dissolve_pmd() - clear and flush huge PMD entry
+ * @kvm: pointer to kvm structure.
+ * @addr: IPA
+ * @pmd: pmd pointer for IPA
+ *
+ * Function clears a PMD entry, flushes addr 1st and 2nd stage TLBs. Marks all
+ * pages in the range dirty.
+ */
+static void stage2_dissolve_pmd(struct kvm *kvm, phys_addr_t addr, pmd_t *pmd)
+{
+ if (!kvm_pmd_huge(*pmd))
+ return;
+
+ pmd_clear(pmd);
+ kvm_tlb_flush_vmid_ipa(kvm, addr);
+ put_page(virt_to_page(pmd));
+}
+
+static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
+ int min, int max)
+{
+ void *page;
+
+ BUG_ON(max > KVM_NR_MEM_OBJS);
+ if (cache->nobjs >= min)
+ return 0;
+ while (cache->nobjs < max) {
+ page = (void *)__get_free_page(PGALLOC_GFP);
+ if (!page)
+ return -ENOMEM;
+ cache->objects[cache->nobjs++] = page;
+ }
+ return 0;
+}
+
+static void mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc)
+{
+ while (mc->nobjs)
+ free_page((unsigned long)mc->objects[--mc->nobjs]);
+}
+
+static void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc)
+{
+ void *p;
+
+ BUG_ON(!mc || !mc->nobjs);
+ p = mc->objects[--mc->nobjs];
+ return p;
+}
+
+static void clear_pgd_entry(struct kvm *kvm, pgd_t *pgd, phys_addr_t addr)
+{
+ pud_t *pud_table __maybe_unused = pud_offset(pgd, 0);
+ pgd_clear(pgd);
+ kvm_tlb_flush_vmid_ipa(kvm, addr);
+ pud_free(NULL, pud_table);
+ put_page(virt_to_page(pgd));
+}
+
+static void clear_pud_entry(struct kvm *kvm, pud_t *pud, phys_addr_t addr)
+{
+ pmd_t *pmd_table = pmd_offset(pud, 0);
+ VM_BUG_ON(pud_huge(*pud));
+ pud_clear(pud);
+ kvm_tlb_flush_vmid_ipa(kvm, addr);
+ pmd_free(NULL, pmd_table);
+ put_page(virt_to_page(pud));
+}
+
+static void clear_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr)
+{
+ pte_t *pte_table = pte_offset_kernel(pmd, 0);
+ VM_BUG_ON(kvm_pmd_huge(*pmd));
+ pmd_clear(pmd);
+ kvm_tlb_flush_vmid_ipa(kvm, addr);
+ pte_free_kernel(NULL, pte_table);
+ put_page(virt_to_page(pmd));
+}
+
+/*
+ * Unmapping vs dcache management:
+ *
+ * If a guest maps certain memory pages as uncached, all writes will
+ * bypass the data cache and go directly to RAM. However, the CPUs
+ * can still speculate reads (not writes) and fill cache lines with
+ * data.
+ *
+ * Those cache lines will be *clean* cache lines though, so a
+ * clean+invalidate operation is equivalent to an invalidate
+ * operation, because no cache lines are marked dirty.
+ *
+ * Those clean cache lines could be filled prior to an uncached write
+ * by the guest, and the cache coherent IO subsystem would therefore
+ * end up writing old data to disk.
+ *
+ * This is why right after unmapping a page/section and invalidating
+ * the corresponding TLBs, we call kvm_flush_dcache_p*() to make sure
+ * the IO subsystem will never hit in the cache.
+ */
+static void unmap_ptes(struct kvm *kvm, pmd_t *pmd,
+ phys_addr_t addr, phys_addr_t end)
+{
+ phys_addr_t start_addr = addr;
+ pte_t *pte, *start_pte;
+
+ start_pte = pte = pte_offset_kernel(pmd, addr);
+ do {
+ if (!pte_none(*pte)) {
+ pte_t old_pte = *pte;
+
+ kvm_set_pte(pte, __pte(0));
+ kvm_tlb_flush_vmid_ipa(kvm, addr);
+
+ /* No need to invalidate the cache for device mappings */
+ if ((pte_val(old_pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE)
+ kvm_flush_dcache_pte(old_pte);
+
+ put_page(virt_to_page(pte));
+ }
+ } while (pte++, addr += PAGE_SIZE, addr != end);
+
+ if (kvm_pte_table_empty(kvm, start_pte))
+ clear_pmd_entry(kvm, pmd, start_addr);
+}
+
+static void unmap_pmds(struct kvm *kvm, pud_t *pud,
+ phys_addr_t addr, phys_addr_t end)
+{
+ phys_addr_t next, start_addr = addr;
+ pmd_t *pmd, *start_pmd;
+
+ start_pmd = pmd = pmd_offset(pud, addr);
+ do {
+ next = kvm_pmd_addr_end(addr, end);
+ if (!pmd_none(*pmd)) {
+ if (kvm_pmd_huge(*pmd)) {
+ pmd_t old_pmd = *pmd;
+
+ pmd_clear(pmd);
+ kvm_tlb_flush_vmid_ipa(kvm, addr);
+
+ kvm_flush_dcache_pmd(old_pmd);
+
+ put_page(virt_to_page(pmd));
+ } else {
+ unmap_ptes(kvm, pmd, addr, next);
+ }
+ }
+ } while (pmd++, addr = next, addr != end);
+
+ if (kvm_pmd_table_empty(kvm, start_pmd))
+ clear_pud_entry(kvm, pud, start_addr);
+}
+
+static void unmap_puds(struct kvm *kvm, pgd_t *pgd,
+ phys_addr_t addr, phys_addr_t end)
+{
+ phys_addr_t next, start_addr = addr;
+ pud_t *pud, *start_pud;
+
+ start_pud = pud = pud_offset(pgd, addr);
+ do {
+ next = kvm_pud_addr_end(addr, end);
+ if (!pud_none(*pud)) {
+ if (pud_huge(*pud)) {
+ pud_t old_pud = *pud;
+
+ pud_clear(pud);
+ kvm_tlb_flush_vmid_ipa(kvm, addr);
+
+ kvm_flush_dcache_pud(old_pud);
+
+ put_page(virt_to_page(pud));
+ } else {
+ unmap_pmds(kvm, pud, addr, next);
+ }
+ }
+ } while (pud++, addr = next, addr != end);
+
+ if (kvm_pud_table_empty(kvm, start_pud))
+ clear_pgd_entry(kvm, pgd, start_addr);
+}
+
+
+static void unmap_range(struct kvm *kvm, pgd_t *pgdp,
+ phys_addr_t start, u64 size)
+{
+ pgd_t *pgd;
+ phys_addr_t addr = start, end = start + size;
+ phys_addr_t next;
+
+ pgd = pgdp + kvm_pgd_index(addr);
+ do {
+ next = kvm_pgd_addr_end(addr, end);
+ if (!pgd_none(*pgd))
+ unmap_puds(kvm, pgd, addr, next);
+ } while (pgd++, addr = next, addr != end);
+}
+
+static void stage2_flush_ptes(struct kvm *kvm, pmd_t *pmd,
+ phys_addr_t addr, phys_addr_t end)
+{
+ pte_t *pte;
+
+ pte = pte_offset_kernel(pmd, addr);
+ do {
+ if (!pte_none(*pte) &&
+ (pte_val(*pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE)
+ kvm_flush_dcache_pte(*pte);
+ } while (pte++, addr += PAGE_SIZE, addr != end);
+}
+
+static void stage2_flush_pmds(struct kvm *kvm, pud_t *pud,
+ phys_addr_t addr, phys_addr_t end)
+{
+ pmd_t *pmd;
+ phys_addr_t next;
+
+ pmd = pmd_offset(pud, addr);
+ do {
+ next = kvm_pmd_addr_end(addr, end);
+ if (!pmd_none(*pmd)) {
+ if (kvm_pmd_huge(*pmd))
+ kvm_flush_dcache_pmd(*pmd);
+ else
+ stage2_flush_ptes(kvm, pmd, addr, next);
+ }
+ } while (pmd++, addr = next, addr != end);
+}
+
+static void stage2_flush_puds(struct kvm *kvm, pgd_t *pgd,
+ phys_addr_t addr, phys_addr_t end)
+{
+ pud_t *pud;
+ phys_addr_t next;
+
+ pud = pud_offset(pgd, addr);
+ do {
+ next = kvm_pud_addr_end(addr, end);
+ if (!pud_none(*pud)) {
+ if (pud_huge(*pud))
+ kvm_flush_dcache_pud(*pud);
+ else
+ stage2_flush_pmds(kvm, pud, addr, next);
+ }
+ } while (pud++, addr = next, addr != end);
+}
+
+static void stage2_flush_memslot(struct kvm *kvm,
+ struct kvm_memory_slot *memslot)
+{
+ phys_addr_t addr = memslot->base_gfn << PAGE_SHIFT;
+ phys_addr_t end = addr + PAGE_SIZE * memslot->npages;
+ phys_addr_t next;
+ pgd_t *pgd;
+
+ pgd = kvm->arch.pgd + kvm_pgd_index(addr);
+ do {
+ next = kvm_pgd_addr_end(addr, end);
+ stage2_flush_puds(kvm, pgd, addr, next);
+ } while (pgd++, addr = next, addr != end);
+}
+
+/**
+ * stage2_flush_vm - Invalidate cache for pages mapped in stage 2
+ * @kvm: The struct kvm pointer
+ *
+ * Go through the stage 2 page tables and invalidate any cache lines
+ * backing memory already mapped to the VM.
+ */
+static void stage2_flush_vm(struct kvm *kvm)
+{
+ struct kvm_memslots *slots;
+ struct kvm_memory_slot *memslot;
+ int idx;
+
+ idx = srcu_read_lock(&kvm->srcu);
+ spin_lock(&kvm->mmu_lock);
+
+ slots = kvm_memslots(kvm);
+ kvm_for_each_memslot(memslot, slots)
+ stage2_flush_memslot(kvm, memslot);
+
+ spin_unlock(&kvm->mmu_lock);
+ srcu_read_unlock(&kvm->srcu, idx);
+}
+
+/**
+ * free_boot_hyp_pgd - free HYP boot page tables
+ *
+ * Free the HYP boot page tables. The bounce page is also freed.
+ */
+void free_boot_hyp_pgd(void)
+{
+ mutex_lock(&kvm_hyp_pgd_mutex);
+
+ if (boot_hyp_pgd) {
+ unmap_range(NULL, boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE);
+ unmap_range(NULL, boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE);
+ free_pages((unsigned long)boot_hyp_pgd, hyp_pgd_order);
+ boot_hyp_pgd = NULL;
+ }
+
+ if (hyp_pgd)
+ unmap_range(NULL, hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE);
+
+ mutex_unlock(&kvm_hyp_pgd_mutex);
+}
+
+/**
+ * free_hyp_pgds - free Hyp-mode page tables
+ *
+ * Assumes hyp_pgd is a page table used strictly in Hyp-mode and
+ * therefore contains either mappings in the kernel memory area (above
+ * PAGE_OFFSET), or device mappings in the vmalloc range (from
+ * VMALLOC_START to VMALLOC_END).
+ *
+ * boot_hyp_pgd should only map two pages for the init code.
+ */
+void free_hyp_pgds(void)
+{
+ unsigned long addr;
+
+ free_boot_hyp_pgd();
+
+ mutex_lock(&kvm_hyp_pgd_mutex);
+
+ if (hyp_pgd) {
+ for (addr = PAGE_OFFSET; virt_addr_valid(addr); addr += PGDIR_SIZE)
+ unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE);
+ for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE)
+ unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE);
+
+ free_pages((unsigned long)hyp_pgd, hyp_pgd_order);
+ hyp_pgd = NULL;
+ }
+ if (merged_hyp_pgd) {
+ clear_page(merged_hyp_pgd);
+ free_page((unsigned long)merged_hyp_pgd);
+ merged_hyp_pgd = NULL;
+ }
+
+ mutex_unlock(&kvm_hyp_pgd_mutex);
+}
+
+static void create_hyp_pte_mappings(pmd_t *pmd, unsigned long start,
+ unsigned long end, unsigned long pfn,
+ pgprot_t prot)
+{
+ pte_t *pte;
+ unsigned long addr;
+
+ addr = start;
+ do {
+ pte = pte_offset_kernel(pmd, addr);
+ kvm_set_pte(pte, pfn_pte(pfn, prot));
+ get_page(virt_to_page(pte));
+ kvm_flush_dcache_to_poc(pte, sizeof(*pte));
+ pfn++;
+ } while (addr += PAGE_SIZE, addr != end);
+}
+
+static int create_hyp_pmd_mappings(pud_t *pud, unsigned long start,
+ unsigned long end, unsigned long pfn,
+ pgprot_t prot)
+{
+ pmd_t *pmd;
+ pte_t *pte;
+ unsigned long addr, next;
+
+ addr = start;
+ do {
+ pmd = pmd_offset(pud, addr);
+
+ BUG_ON(pmd_sect(*pmd));
+
+ if (pmd_none(*pmd)) {
+ pte = pte_alloc_one_kernel(NULL, addr);
+ if (!pte) {
+ kvm_err("Cannot allocate Hyp pte\n");
+ return -ENOMEM;
+ }
+ pmd_populate_kernel(NULL, pmd, pte);
+ get_page(virt_to_page(pmd));
+ kvm_flush_dcache_to_poc(pmd, sizeof(*pmd));
+ }
+
+ next = pmd_addr_end(addr, end);
+
+ create_hyp_pte_mappings(pmd, addr, next, pfn, prot);
+ pfn += (next - addr) >> PAGE_SHIFT;
+ } while (addr = next, addr != end);
+
+ return 0;
+}
+
+static int create_hyp_pud_mappings(pgd_t *pgd, unsigned long start,
+ unsigned long end, unsigned long pfn,
+ pgprot_t prot)
+{
+ pud_t *pud;
+ pmd_t *pmd;
+ unsigned long addr, next;
+ int ret;
+
+ addr = start;
+ do {
+ pud = pud_offset(pgd, addr);
+
+ if (pud_none_or_clear_bad(pud)) {
+ pmd = pmd_alloc_one(NULL, addr);
+ if (!pmd) {
+ kvm_err("Cannot allocate Hyp pmd\n");
+ return -ENOMEM;
+ }
+ pud_populate(NULL, pud, pmd);
+ get_page(virt_to_page(pud));
+ kvm_flush_dcache_to_poc(pud, sizeof(*pud));
+ }
+
+ next = pud_addr_end(addr, end);
+ ret = create_hyp_pmd_mappings(pud, addr, next, pfn, prot);
+ if (ret)
+ return ret;
+ pfn += (next - addr) >> PAGE_SHIFT;
+ } while (addr = next, addr != end);
+
+ return 0;
+}
+
+static int __create_hyp_mappings(pgd_t *pgdp,
+ unsigned long start, unsigned long end,
+ unsigned long pfn, pgprot_t prot)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ unsigned long addr, next;
+ int err = 0;
+
+ mutex_lock(&kvm_hyp_pgd_mutex);
+ addr = start & PAGE_MASK;
+ end = PAGE_ALIGN(end);
+ do {
+ pgd = pgdp + pgd_index(addr);
+
+ if (pgd_none(*pgd)) {
+ pud = pud_alloc_one(NULL, addr);
+ if (!pud) {
+ kvm_err("Cannot allocate Hyp pud\n");
+ err = -ENOMEM;
+ goto out;
+ }
+ pgd_populate(NULL, pgd, pud);
+ get_page(virt_to_page(pgd));
+ kvm_flush_dcache_to_poc(pgd, sizeof(*pgd));
+ }
+
+ next = pgd_addr_end(addr, end);
+ err = create_hyp_pud_mappings(pgd, addr, next, pfn, prot);
+ if (err)
+ goto out;
+ pfn += (next - addr) >> PAGE_SHIFT;
+ } while (addr = next, addr != end);
+out:
+ mutex_unlock(&kvm_hyp_pgd_mutex);
+ return err;
+}
+
+static phys_addr_t kvm_kaddr_to_phys(void *kaddr)
+{
+ if (!is_vmalloc_addr(kaddr)) {
+ BUG_ON(!virt_addr_valid(kaddr));
+ return __pa(kaddr);
+ } else {
+ return page_to_phys(vmalloc_to_page(kaddr)) +
+ offset_in_page(kaddr);
+ }
+}
+
+/**
+ * create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode
+ * @from: The virtual kernel start address of the range
+ * @to: The virtual kernel end address of the range (exclusive)
+ *
+ * The same virtual address as the kernel virtual address is also used
+ * in Hyp-mode mapping (modulo HYP_PAGE_OFFSET) to the same underlying
+ * physical pages.
+ */
+int create_hyp_mappings(void *from, void *to)
+{
+ phys_addr_t phys_addr;
+ unsigned long virt_addr;
+ unsigned long start = KERN_TO_HYP((unsigned long)from);
+ unsigned long end = KERN_TO_HYP((unsigned long)to);
+
+ start = start & PAGE_MASK;
+ end = PAGE_ALIGN(end);
+
+ for (virt_addr = start; virt_addr < end; virt_addr += PAGE_SIZE) {
+ int err;
+
+ phys_addr = kvm_kaddr_to_phys(from + virt_addr - start);
+ err = __create_hyp_mappings(hyp_pgd, virt_addr,
+ virt_addr + PAGE_SIZE,
+ __phys_to_pfn(phys_addr),
+ PAGE_HYP);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+/**
+ * create_hyp_io_mappings - duplicate a kernel IO mapping into Hyp mode
+ * @from: The kernel start VA of the range
+ * @to: The kernel end VA of the range (exclusive)
+ * @phys_addr: The physical start address which gets mapped
+ *
+ * The resulting HYP VA is the same as the kernel VA, modulo
+ * HYP_PAGE_OFFSET.
+ */
+int create_hyp_io_mappings(void *from, void *to, phys_addr_t phys_addr)
+{
+ unsigned long start = KERN_TO_HYP((unsigned long)from);
+ unsigned long end = KERN_TO_HYP((unsigned long)to);
+
+ /* Check for a valid kernel IO mapping */
+ if (!is_vmalloc_addr(from) || !is_vmalloc_addr(to - 1))
+ return -EINVAL;
+
+ return __create_hyp_mappings(hyp_pgd, start, end,
+ __phys_to_pfn(phys_addr), PAGE_HYP_DEVICE);
+}
+
+/* Free the HW pgd, one page at a time */
+static void kvm_free_hwpgd(void *hwpgd)
+{
+ free_pages_exact(hwpgd, kvm_get_hwpgd_size());
+}
+
+/* Allocate the HW PGD, making sure that each page gets its own refcount */
+static void *kvm_alloc_hwpgd(void)
+{
+ unsigned int size = kvm_get_hwpgd_size();
+
+ return alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
+}
+
+/**
+ * kvm_alloc_stage2_pgd - allocate level-1 table for stage-2 translation.
+ * @kvm: The KVM struct pointer for the VM.
+ *
+ * Allocates the 1st level table only of size defined by S2_PGD_ORDER (can
+ * support either full 40-bit input addresses or limited to 32-bit input
+ * addresses). Clears the allocated pages.
+ *
+ * Note we don't need locking here as this is only called when the VM is
+ * created, which can only be done once.
+ */
+int kvm_alloc_stage2_pgd(struct kvm *kvm)
+{
+ pgd_t *pgd;
+ void *hwpgd;
+
+ if (kvm->arch.pgd != NULL) {
+ kvm_err("kvm_arch already initialized?\n");
+ return -EINVAL;
+ }
+
+ hwpgd = kvm_alloc_hwpgd();
+ if (!hwpgd)
+ return -ENOMEM;
+
+ /* When the kernel uses more levels of page tables than the
+ * guest, we allocate a fake PGD and pre-populate it to point
+ * to the next-level page table, which will be the real
+ * initial page table pointed to by the VTTBR.
+ *
+ * When KVM_PREALLOC_LEVEL==2, we allocate a single page for
+ * the PMD and the kernel will use folded pud.
+ * When KVM_PREALLOC_LEVEL==1, we allocate 2 consecutive PUD
+ * pages.
+ */
+ if (KVM_PREALLOC_LEVEL > 0) {
+ int i;
+
+ /*
+ * Allocate fake pgd for the page table manipulation macros to
+ * work. This is not used by the hardware and we have no
+ * alignment requirement for this allocation.
+ */
+ pgd = (pgd_t *)kmalloc(PTRS_PER_S2_PGD * sizeof(pgd_t),
+ GFP_KERNEL | __GFP_ZERO);
+
+ if (!pgd) {
+ kvm_free_hwpgd(hwpgd);
+ return -ENOMEM;
+ }
+
+ /* Plug the HW PGD into the fake one. */
+ for (i = 0; i < PTRS_PER_S2_PGD; i++) {
+ if (KVM_PREALLOC_LEVEL == 1)
+ pgd_populate(NULL, pgd + i,
+ (pud_t *)hwpgd + i * PTRS_PER_PUD);
+ else if (KVM_PREALLOC_LEVEL == 2)
+ pud_populate(NULL, pud_offset(pgd, 0) + i,
+ (pmd_t *)hwpgd + i * PTRS_PER_PMD);
+ }
+ } else {
+ /*
+ * Allocate actual first-level Stage-2 page table used by the
+ * hardware for Stage-2 page table walks.
+ */
+ pgd = (pgd_t *)hwpgd;
+ }
+
+ kvm_clean_pgd(pgd);
+ kvm->arch.pgd = pgd;
+ return 0;
+}
+
+/**
+ * unmap_stage2_range -- Clear stage2 page table entries to unmap a range
+ * @kvm: The VM pointer
+ * @start: The intermediate physical base address of the range to unmap
+ * @size: The size of the area to unmap
+ *
+ * Clear a range of stage-2 mappings, lowering the various ref-counts. Must
+ * be called while holding mmu_lock (unless for freeing the stage2 pgd before
+ * destroying the VM), otherwise another faulting VCPU may come in and mess
+ * with things behind our backs.
+ */
+static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size)
+{
+ unmap_range(kvm, kvm->arch.pgd, start, size);
+}
+
+static void stage2_unmap_memslot(struct kvm *kvm,
+ struct kvm_memory_slot *memslot)
+{
+ hva_t hva = memslot->userspace_addr;
+ phys_addr_t addr = memslot->base_gfn << PAGE_SHIFT;
+ phys_addr_t size = PAGE_SIZE * memslot->npages;
+ hva_t reg_end = hva + size;
+
+ /*
+ * A memory region could potentially cover multiple VMAs, and any holes
+ * between them, so iterate over all of them to find out if we should
+ * unmap any of them.
+ *
+ * +--------------------------------------------+
+ * +---------------+----------------+ +----------------+
+ * | : VMA 1 | VMA 2 | | VMA 3 : |
+ * +---------------+----------------+ +----------------+
+ * | memory region |
+ * +--------------------------------------------+
+ */
+ do {
+ struct vm_area_struct *vma = find_vma(current->mm, hva);
+ hva_t vm_start, vm_end;
+
+ if (!vma || vma->vm_start >= reg_end)
+ break;
+
+ /*
+ * Take the intersection of this VMA with the memory region
+ */
+ vm_start = max(hva, vma->vm_start);
+ vm_end = min(reg_end, vma->vm_end);
+
+ if (!(vma->vm_flags & VM_PFNMAP)) {
+ gpa_t gpa = addr + (vm_start - memslot->userspace_addr);
+ unmap_stage2_range(kvm, gpa, vm_end - vm_start);
+ }
+ hva = vm_end;
+ } while (hva < reg_end);
+}
+
+/**
+ * stage2_unmap_vm - Unmap Stage-2 RAM mappings
+ * @kvm: The struct kvm pointer
+ *
+ * Go through the memregions and unmap any reguler RAM
+ * backing memory already mapped to the VM.
+ */
+void stage2_unmap_vm(struct kvm *kvm)
+{
+ struct kvm_memslots *slots;
+ struct kvm_memory_slot *memslot;
+ int idx;
+
+ idx = srcu_read_lock(&kvm->srcu);
+ spin_lock(&kvm->mmu_lock);
+
+ slots = kvm_memslots(kvm);
+ kvm_for_each_memslot(memslot, slots)
+ stage2_unmap_memslot(kvm, memslot);
+
+ spin_unlock(&kvm->mmu_lock);
+ srcu_read_unlock(&kvm->srcu, idx);
+}
+
+/**
+ * kvm_free_stage2_pgd - free all stage-2 tables
+ * @kvm: The KVM struct pointer for the VM.
+ *
+ * Walks the level-1 page table pointed to by kvm->arch.pgd and frees all
+ * underlying level-2 and level-3 tables before freeing the actual level-1 table
+ * and setting the struct pointer to NULL.
+ *
+ * Note we don't need locking here as this is only called when the VM is
+ * destroyed, which can only be done once.
+ */
+void kvm_free_stage2_pgd(struct kvm *kvm)
+{
+ if (kvm->arch.pgd == NULL)
+ return;
+
+ unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE);
+ kvm_free_hwpgd(kvm_get_hwpgd(kvm));
+ if (KVM_PREALLOC_LEVEL > 0)
+ kfree(kvm->arch.pgd);
+
+ kvm->arch.pgd = NULL;
+}
+
+static pud_t *stage2_get_pud(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
+ phys_addr_t addr)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+
+ pgd = kvm->arch.pgd + kvm_pgd_index(addr);
+ if (WARN_ON(pgd_none(*pgd))) {
+ if (!cache)
+ return NULL;
+ pud = mmu_memory_cache_alloc(cache);
+ pgd_populate(NULL, pgd, pud);
+ get_page(virt_to_page(pgd));
+ }
+
+ return pud_offset(pgd, addr);
+}
+
+static pmd_t *stage2_get_pmd(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
+ phys_addr_t addr)
+{
+ pud_t *pud;
+ pmd_t *pmd;
+
+ pud = stage2_get_pud(kvm, cache, addr);
+ if (pud_none(*pud)) {
+ if (!cache)
+ return NULL;
+ pmd = mmu_memory_cache_alloc(cache);
+ pud_populate(NULL, pud, pmd);
+ get_page(virt_to_page(pud));
+ }
+
+ return pmd_offset(pud, addr);
+}
+
+static int stage2_set_pmd_huge(struct kvm *kvm, struct kvm_mmu_memory_cache
+ *cache, phys_addr_t addr, const pmd_t *new_pmd)
+{
+ pmd_t *pmd, old_pmd;
+
+ pmd = stage2_get_pmd(kvm, cache, addr);
+ VM_BUG_ON(!pmd);
+
+ /*
+ * Mapping in huge pages should only happen through a fault. If a
+ * page is merged into a transparent huge page, the individual
+ * subpages of that huge page should be unmapped through MMU
+ * notifiers before we get here.
+ *
+ * Merging of CompoundPages is not supported; they should become
+ * splitting first, unmapped, merged, and mapped back in on-demand.
+ */
+ VM_BUG_ON(pmd_present(*pmd) && pmd_pfn(*pmd) != pmd_pfn(*new_pmd));
+
+ old_pmd = *pmd;
+ kvm_set_pmd(pmd, *new_pmd);
+ if (pmd_present(old_pmd))
+ kvm_tlb_flush_vmid_ipa(kvm, addr);
+ else
+ get_page(virt_to_page(pmd));
+ return 0;
+}
+
+static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
+ phys_addr_t addr, const pte_t *new_pte,
+ unsigned long flags)
+{
+ pmd_t *pmd;
+ pte_t *pte, old_pte;
+ bool iomap = flags & KVM_S2PTE_FLAG_IS_IOMAP;
+ bool logging_active = flags & KVM_S2_FLAG_LOGGING_ACTIVE;
+
+ VM_BUG_ON(logging_active && !cache);
+
+ /* Create stage-2 page table mapping - Levels 0 and 1 */
+ pmd = stage2_get_pmd(kvm, cache, addr);
+ if (!pmd) {
+ /*
+ * Ignore calls from kvm_set_spte_hva for unallocated
+ * address ranges.
+ */
+ return 0;
+ }
+
+ /*
+ * While dirty page logging - dissolve huge PMD, then continue on to
+ * allocate page.
+ */
+ if (logging_active)
+ stage2_dissolve_pmd(kvm, addr, pmd);
+
+ /* Create stage-2 page mappings - Level 2 */
+ if (pmd_none(*pmd)) {
+ if (!cache)
+ return 0; /* ignore calls from kvm_set_spte_hva */
+ pte = mmu_memory_cache_alloc(cache);
+ kvm_clean_pte(pte);
+ pmd_populate_kernel(NULL, pmd, pte);
+ get_page(virt_to_page(pmd));
+ }
+
+ pte = pte_offset_kernel(pmd, addr);
+
+ if (iomap && pte_present(*pte))
+ return -EFAULT;
+
+ /* Create 2nd stage page table mapping - Level 3 */
+ old_pte = *pte;
+ kvm_set_pte(pte, *new_pte);
+ if (pte_present(old_pte))
+ kvm_tlb_flush_vmid_ipa(kvm, addr);
+ else
+ get_page(virt_to_page(pte));
+
+ return 0;
+}
+
+/**
+ * kvm_phys_addr_ioremap - map a device range to guest IPA
+ *
+ * @kvm: The KVM pointer
+ * @guest_ipa: The IPA at which to insert the mapping
+ * @pa: The physical address of the device
+ * @size: The size of the mapping
+ */
+int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
+ phys_addr_t pa, unsigned long size, bool writable)
+{
+ phys_addr_t addr, end;
+ int ret = 0;
+ unsigned long pfn;
+ struct kvm_mmu_memory_cache cache = { 0, };
+
+ end = (guest_ipa + size + PAGE_SIZE - 1) & PAGE_MASK;
+ pfn = __phys_to_pfn(pa);
+
+ for (addr = guest_ipa; addr < end; addr += PAGE_SIZE) {
+ pte_t pte = pfn_pte(pfn, PAGE_S2_DEVICE);
+
+ if (writable)
+ kvm_set_s2pte_writable(&pte);
+
+ ret = mmu_topup_memory_cache(&cache, KVM_MMU_CACHE_MIN_PAGES,
+ KVM_NR_MEM_OBJS);
+ if (ret)
+ goto out;
+ spin_lock(&kvm->mmu_lock);
+ ret = stage2_set_pte(kvm, &cache, addr, &pte,
+ KVM_S2PTE_FLAG_IS_IOMAP);
+ spin_unlock(&kvm->mmu_lock);
+ if (ret)
+ goto out;
+
+ pfn++;
+ }
+
+out:
+ mmu_free_memory_cache(&cache);
+ return ret;
+}
+
+static bool transparent_hugepage_adjust(pfn_t *pfnp, phys_addr_t *ipap)
+{
+ pfn_t pfn = *pfnp;
+ gfn_t gfn = *ipap >> PAGE_SHIFT;
+
+ if (PageTransCompound(pfn_to_page(pfn))) {
+ unsigned long mask;
+ /*
+ * The address we faulted on is backed by a transparent huge
+ * page. However, because we map the compound huge page and
+ * not the individual tail page, we need to transfer the
+ * refcount to the head page. We have to be careful that the
+ * THP doesn't start to split while we are adjusting the
+ * refcounts.
+ *
+ * We are sure this doesn't happen, because mmu_notifier_retry
+ * was successful and we are holding the mmu_lock, so if this
+ * THP is trying to split, it will be blocked in the mmu
+ * notifier before touching any of the pages, specifically
+ * before being able to call __split_huge_page_refcount().
+ *
+ * We can therefore safely transfer the refcount from PG_tail
+ * to PG_head and switch the pfn from a tail page to the head
+ * page accordingly.
+ */
+ mask = PTRS_PER_PMD - 1;
+ VM_BUG_ON((gfn & mask) != (pfn & mask));
+ if (pfn & mask) {
+ *ipap &= PMD_MASK;
+ kvm_release_pfn_clean(pfn);
+ pfn &= ~mask;
+ kvm_get_pfn(pfn);
+ *pfnp = pfn;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+static bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
+{
+ if (kvm_vcpu_trap_is_iabt(vcpu))
+ return false;
+
+ return kvm_vcpu_dabt_iswrite(vcpu);
+}
+
+static bool kvm_is_device_pfn(unsigned long pfn)
+{
+ return !pfn_valid(pfn);
+}
+
+/**
+ * stage2_wp_ptes - write protect PMD range
+ * @pmd: pointer to pmd entry
+ * @addr: range start address
+ * @end: range end address
+ */
+static void stage2_wp_ptes(pmd_t *pmd, phys_addr_t addr, phys_addr_t end)
+{
+ pte_t *pte;
+
+ pte = pte_offset_kernel(pmd, addr);
+ do {
+ if (!pte_none(*pte)) {
+ if (!kvm_s2pte_readonly(pte))
+ kvm_set_s2pte_readonly(pte);
+ }
+ } while (pte++, addr += PAGE_SIZE, addr != end);
+}
+
+/**
+ * stage2_wp_pmds - write protect PUD range
+ * @pud: pointer to pud entry
+ * @addr: range start address
+ * @end: range end address
+ */
+static void stage2_wp_pmds(pud_t *pud, phys_addr_t addr, phys_addr_t end)
+{
+ pmd_t *pmd;
+ phys_addr_t next;
+
+ pmd = pmd_offset(pud, addr);
+
+ do {
+ next = kvm_pmd_addr_end(addr, end);
+ if (!pmd_none(*pmd)) {
+ if (kvm_pmd_huge(*pmd)) {
+ if (!kvm_s2pmd_readonly(pmd))
+ kvm_set_s2pmd_readonly(pmd);
+ } else {
+ stage2_wp_ptes(pmd, addr, next);
+ }
+ }
+ } while (pmd++, addr = next, addr != end);
+}
+
+/**
+ * stage2_wp_puds - write protect PGD range
+ * @pgd: pointer to pgd entry
+ * @addr: range start address
+ * @end: range end address
+ *
+ * Process PUD entries, for a huge PUD we cause a panic.
+ */
+static void stage2_wp_puds(pgd_t *pgd, phys_addr_t addr, phys_addr_t end)
+{
+ pud_t *pud;
+ phys_addr_t next;
+
+ pud = pud_offset(pgd, addr);
+ do {
+ next = kvm_pud_addr_end(addr, end);
+ if (!pud_none(*pud)) {
+ /* TODO:PUD not supported, revisit later if supported */
+ BUG_ON(kvm_pud_huge(*pud));
+ stage2_wp_pmds(pud, addr, next);
+ }
+ } while (pud++, addr = next, addr != end);
+}
+
+/**
+ * stage2_wp_range() - write protect stage2 memory region range
+ * @kvm: The KVM pointer
+ * @addr: Start address of range
+ * @end: End address of range
+ */
+static void stage2_wp_range(struct kvm *kvm, phys_addr_t addr, phys_addr_t end)
+{
+ pgd_t *pgd;
+ phys_addr_t next;
+
+ pgd = kvm->arch.pgd + kvm_pgd_index(addr);
+ do {
+ /*
+ * Release kvm_mmu_lock periodically if the memory region is
+ * large. Otherwise, we may see kernel panics with
+ * CONFIG_DETECT_HUNG_TASK, CONFIG_LOCKUP_DETECTOR,
+ * CONFIG_LOCKDEP. Additionally, holding the lock too long
+ * will also starve other vCPUs.
+ */
+ if (need_resched() || spin_needbreak(&kvm->mmu_lock))
+ cond_resched_lock(&kvm->mmu_lock);
+
+ next = kvm_pgd_addr_end(addr, end);
+ if (pgd_present(*pgd))
+ stage2_wp_puds(pgd, addr, next);
+ } while (pgd++, addr = next, addr != end);
+}
+
+/**
+ * kvm_mmu_wp_memory_region() - write protect stage 2 entries for memory slot
+ * @kvm: The KVM pointer
+ * @slot: The memory slot to write protect
+ *
+ * Called to start logging dirty pages after memory region
+ * KVM_MEM_LOG_DIRTY_PAGES operation is called. After this function returns
+ * all present PMD and PTEs are write protected in the memory region.
+ * Afterwards read of dirty page log can be called.
+ *
+ * Acquires kvm_mmu_lock. Called with kvm->slots_lock mutex acquired,
+ * serializing operations for VM memory regions.
+ */
+void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot)
+{
+ struct kvm_memory_slot *memslot = id_to_memslot(kvm->memslots, slot);
+ phys_addr_t start = memslot->base_gfn << PAGE_SHIFT;
+ phys_addr_t end = (memslot->base_gfn + memslot->npages) << PAGE_SHIFT;
+
+ spin_lock(&kvm->mmu_lock);
+ stage2_wp_range(kvm, start, end);
+ spin_unlock(&kvm->mmu_lock);
+ kvm_flush_remote_tlbs(kvm);
+}
+
+/**
+ * kvm_mmu_write_protect_pt_masked() - write protect dirty pages
+ * @kvm: The KVM pointer
+ * @slot: The memory slot associated with mask
+ * @gfn_offset: The gfn offset in memory slot
+ * @mask: The mask of dirty pages at offset 'gfn_offset' in this memory
+ * slot to be write protected
+ *
+ * Walks bits set in mask write protects the associated pte's. Caller must
+ * acquire kvm_mmu_lock.
+ */
+static void kvm_mmu_write_protect_pt_masked(struct kvm *kvm,
+ struct kvm_memory_slot *slot,
+ gfn_t gfn_offset, unsigned long mask)
+{
+ phys_addr_t base_gfn = slot->base_gfn + gfn_offset;
+ phys_addr_t start = (base_gfn + __ffs(mask)) << PAGE_SHIFT;
+ phys_addr_t end = (base_gfn + __fls(mask) + 1) << PAGE_SHIFT;
+
+ stage2_wp_range(kvm, start, end);
+}
+
+/*
+ * kvm_arch_mmu_enable_log_dirty_pt_masked - enable dirty logging for selected
+ * dirty pages.
+ *
+ * It calls kvm_mmu_write_protect_pt_masked to write protect selected pages to
+ * enable dirty logging for them.
+ */
+void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm *kvm,
+ struct kvm_memory_slot *slot,
+ gfn_t gfn_offset, unsigned long mask)
+{
+ kvm_mmu_write_protect_pt_masked(kvm, slot, gfn_offset, mask);
+}
+
+static void coherent_cache_guest_page(struct kvm_vcpu *vcpu, pfn_t pfn,
+ unsigned long size, bool uncached)
+{
+ __coherent_cache_guest_page(vcpu, pfn, size, uncached);
+}
+
+static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
+ struct kvm_memory_slot *memslot, unsigned long hva,
+ unsigned long fault_status)
+{
+ int ret;
+ bool write_fault, writable, hugetlb = false, force_pte = false;
+ unsigned long mmu_seq;
+ gfn_t gfn = fault_ipa >> PAGE_SHIFT;
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
+ struct vm_area_struct *vma;
+ pfn_t pfn;
+ pgprot_t mem_type = PAGE_S2;
+ bool fault_ipa_uncached;
+ bool logging_active = memslot_is_logging(memslot);
+ unsigned long flags = 0;
+
+ write_fault = kvm_is_write_fault(vcpu);
+ if (fault_status == FSC_PERM && !write_fault) {
+ kvm_err("Unexpected L2 read permission error\n");
+ return -EFAULT;
+ }
+
+ /* Let's check if we will get back a huge page backed by hugetlbfs */
+ down_read(&current->mm->mmap_sem);
+ vma = find_vma_intersection(current->mm, hva, hva + 1);
+ if (unlikely(!vma)) {
+ kvm_err("Failed to find VMA for hva 0x%lx\n", hva);
+ up_read(&current->mm->mmap_sem);
+ return -EFAULT;
+ }
+
+ if (is_vm_hugetlb_page(vma) && !logging_active) {
+ hugetlb = true;
+ gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT;
+ } else {
+ /*
+ * Pages belonging to memslots that don't have the same
+ * alignment for userspace and IPA cannot be mapped using
+ * block descriptors even if the pages belong to a THP for
+ * the process, because the stage-2 block descriptor will
+ * cover more than a single THP and we loose atomicity for
+ * unmapping, updates, and splits of the THP or other pages
+ * in the stage-2 block range.
+ */
+ if ((memslot->userspace_addr & ~PMD_MASK) !=
+ ((memslot->base_gfn << PAGE_SHIFT) & ~PMD_MASK))
+ force_pte = true;
+ }
+ up_read(&current->mm->mmap_sem);
+
+ /* We need minimum second+third level pages */
+ ret = mmu_topup_memory_cache(memcache, KVM_MMU_CACHE_MIN_PAGES,
+ KVM_NR_MEM_OBJS);
+ if (ret)
+ return ret;
+
+ mmu_seq = vcpu->kvm->mmu_notifier_seq;
+ /*
+ * Ensure the read of mmu_notifier_seq happens before we call
+ * gfn_to_pfn_prot (which calls get_user_pages), so that we don't risk
+ * the page we just got a reference to gets unmapped before we have a
+ * chance to grab the mmu_lock, which ensure that if the page gets
+ * unmapped afterwards, the call to kvm_unmap_hva will take it away
+ * from us again properly. This smp_rmb() interacts with the smp_wmb()
+ * in kvm_mmu_notifier_invalidate_<page|range_end>.
+ */
+ smp_rmb();
+
+ pfn = gfn_to_pfn_prot(kvm, gfn, write_fault, &writable);
+ if (is_error_pfn(pfn))
+ return -EFAULT;
+
+ if (kvm_is_device_pfn(pfn)) {
+ mem_type = PAGE_S2_DEVICE;
+ flags |= KVM_S2PTE_FLAG_IS_IOMAP;
+ } else if (logging_active) {
+ /*
+ * Faults on pages in a memslot with logging enabled
+ * should not be mapped with huge pages (it introduces churn
+ * and performance degradation), so force a pte mapping.
+ */
+ force_pte = true;
+ flags |= KVM_S2_FLAG_LOGGING_ACTIVE;
+
+ /*
+ * Only actually map the page as writable if this was a write
+ * fault.
+ */
+ if (!write_fault)
+ writable = false;
+ }
+
+ spin_lock(&kvm->mmu_lock);
+ if (mmu_notifier_retry(kvm, mmu_seq))
+ goto out_unlock;
+
+ if (!hugetlb && !force_pte)
+ hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa);
+
+ fault_ipa_uncached = memslot->flags & KVM_MEMSLOT_INCOHERENT;
+
+ if (hugetlb) {
+ pmd_t new_pmd = pfn_pmd(pfn, mem_type);
+ new_pmd = pmd_mkhuge(new_pmd);
+ if (writable) {
+ kvm_set_s2pmd_writable(&new_pmd);
+ kvm_set_pfn_dirty(pfn);
+ }
+ coherent_cache_guest_page(vcpu, pfn, PMD_SIZE, fault_ipa_uncached);
+ ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd);
+ } else {
+ pte_t new_pte = pfn_pte(pfn, mem_type);
+
+ if (writable) {
+ kvm_set_s2pte_writable(&new_pte);
+ kvm_set_pfn_dirty(pfn);
+ mark_page_dirty(kvm, gfn);
+ }
+ coherent_cache_guest_page(vcpu, pfn, PAGE_SIZE, fault_ipa_uncached);
+ ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, flags);
+ }
+
+out_unlock:
+ spin_unlock(&kvm->mmu_lock);
+ kvm_set_pfn_accessed(pfn);
+ kvm_release_pfn_clean(pfn);
+ return ret;
+}
+
+/*
+ * Resolve the access fault by making the page young again.
+ * Note that because the faulting entry is guaranteed not to be
+ * cached in the TLB, we don't need to invalidate anything.
+ */
+static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
+{
+ pmd_t *pmd;
+ pte_t *pte;
+ pfn_t pfn;
+ bool pfn_valid = false;
+
+ trace_kvm_access_fault(fault_ipa);
+
+ spin_lock(&vcpu->kvm->mmu_lock);
+
+ pmd = stage2_get_pmd(vcpu->kvm, NULL, fault_ipa);
+ if (!pmd || pmd_none(*pmd)) /* Nothing there */
+ goto out;
+
+ if (kvm_pmd_huge(*pmd)) { /* THP, HugeTLB */
+ *pmd = pmd_mkyoung(*pmd);
+ pfn = pmd_pfn(*pmd);
+ pfn_valid = true;
+ goto out;
+ }
+
+ pte = pte_offset_kernel(pmd, fault_ipa);
+ if (pte_none(*pte)) /* Nothing there either */
+ goto out;
+
+ *pte = pte_mkyoung(*pte); /* Just a page... */
+ pfn = pte_pfn(*pte);
+ pfn_valid = true;
+out:
+ spin_unlock(&vcpu->kvm->mmu_lock);
+ if (pfn_valid)
+ kvm_set_pfn_accessed(pfn);
+}
+
+/**
+ * kvm_handle_guest_abort - handles all 2nd stage aborts
+ * @vcpu: the VCPU pointer
+ * @run: the kvm_run structure
+ *
+ * Any abort that gets to the host is almost guaranteed to be caused by a
+ * missing second stage translation table entry, which can mean that either the
+ * guest simply needs more memory and we must allocate an appropriate page or it
+ * can mean that the guest tried to access I/O memory, which is emulated by user
+ * space. The distinction is based on the IPA causing the fault and whether this
+ * memory region has been registered as standard RAM by user space.
+ */
+int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ unsigned long fault_status;
+ phys_addr_t fault_ipa;
+ struct kvm_memory_slot *memslot;
+ unsigned long hva;
+ bool is_iabt, write_fault, writable;
+ gfn_t gfn;
+ int ret, idx;
+
+ is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
+ fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
+
+ trace_kvm_guest_fault(*vcpu_pc(vcpu), kvm_vcpu_get_hsr(vcpu),
+ kvm_vcpu_get_hfar(vcpu), fault_ipa);
+
+ /* Check the stage-2 fault is trans. fault or write fault */
+ fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
+ if (fault_status != FSC_FAULT && fault_status != FSC_PERM &&
+ fault_status != FSC_ACCESS) {
+ kvm_err("Unsupported FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n",
+ kvm_vcpu_trap_get_class(vcpu),
+ (unsigned long)kvm_vcpu_trap_get_fault(vcpu),
+ (unsigned long)kvm_vcpu_get_hsr(vcpu));
+ return -EFAULT;
+ }
+
+ idx = srcu_read_lock(&vcpu->kvm->srcu);
+
+ gfn = fault_ipa >> PAGE_SHIFT;
+ memslot = gfn_to_memslot(vcpu->kvm, gfn);
+ hva = gfn_to_hva_memslot_prot(memslot, gfn, &writable);
+ write_fault = kvm_is_write_fault(vcpu);
+ if (kvm_is_error_hva(hva) || (write_fault && !writable)) {
+ if (is_iabt) {
+ /* Prefetch Abort on I/O address */
+ kvm_inject_pabt(vcpu, kvm_vcpu_get_hfar(vcpu));
+ ret = 1;
+ goto out_unlock;
+ }
+
+ /*
+ * The IPA is reported as [MAX:12], so we need to
+ * complement it with the bottom 12 bits from the
+ * faulting VA. This is always 12 bits, irrespective
+ * of the page size.
+ */
+ fault_ipa |= kvm_vcpu_get_hfar(vcpu) & ((1 << 12) - 1);
+ ret = io_mem_abort(vcpu, run, fault_ipa);
+ goto out_unlock;
+ }
+
+ /* Userspace should not be able to register out-of-bounds IPAs */
+ VM_BUG_ON(fault_ipa >= KVM_PHYS_SIZE);
+
+ if (fault_status == FSC_ACCESS) {
+ handle_access_fault(vcpu, fault_ipa);
+ ret = 1;
+ goto out_unlock;
+ }
+
+ ret = user_mem_abort(vcpu, fault_ipa, memslot, hva, fault_status);
+ if (ret == 0)
+ ret = 1;
+out_unlock:
+ srcu_read_unlock(&vcpu->kvm->srcu, idx);
+ return ret;
+}
+
+static int handle_hva_to_gpa(struct kvm *kvm,
+ unsigned long start,
+ unsigned long end,
+ int (*handler)(struct kvm *kvm,
+ gpa_t gpa, void *data),
+ void *data)
+{
+ struct kvm_memslots *slots;
+ struct kvm_memory_slot *memslot;
+ int ret = 0;
+
+ slots = kvm_memslots(kvm);
+
+ /* we only care about the pages that the guest sees */
+ kvm_for_each_memslot(memslot, slots) {
+ unsigned long hva_start, hva_end;
+ gfn_t gfn, gfn_end;
+
+ hva_start = max(start, memslot->userspace_addr);
+ hva_end = min(end, memslot->userspace_addr +
+ (memslot->npages << PAGE_SHIFT));
+ if (hva_start >= hva_end)
+ continue;
+
+ /*
+ * {gfn(page) | page intersects with [hva_start, hva_end)} =
+ * {gfn_start, gfn_start+1, ..., gfn_end-1}.
+ */
+ gfn = hva_to_gfn_memslot(hva_start, memslot);
+ gfn_end = hva_to_gfn_memslot(hva_end + PAGE_SIZE - 1, memslot);
+
+ for (; gfn < gfn_end; ++gfn) {
+ gpa_t gpa = gfn << PAGE_SHIFT;
+ ret |= handler(kvm, gpa, data);
+ }
+ }
+
+ return ret;
+}
+
+static int kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, void *data)
+{
+ unmap_stage2_range(kvm, gpa, PAGE_SIZE);
+ return 0;
+}
+
+int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
+{
+ unsigned long end = hva + PAGE_SIZE;
+
+ if (!kvm->arch.pgd)
+ return 0;
+
+ trace_kvm_unmap_hva(hva);
+ handle_hva_to_gpa(kvm, hva, end, &kvm_unmap_hva_handler, NULL);
+ return 0;
+}
+
+int kvm_unmap_hva_range(struct kvm *kvm,
+ unsigned long start, unsigned long end)
+{
+ if (!kvm->arch.pgd)
+ return 0;
+
+ trace_kvm_unmap_hva_range(start, end);
+ handle_hva_to_gpa(kvm, start, end, &kvm_unmap_hva_handler, NULL);
+ return 0;
+}
+
+static int kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, void *data)
+{
+ pte_t *pte = (pte_t *)data;
+
+ /*
+ * We can always call stage2_set_pte with KVM_S2PTE_FLAG_LOGGING_ACTIVE
+ * flag clear because MMU notifiers will have unmapped a huge PMD before
+ * calling ->change_pte() (which in turn calls kvm_set_spte_hva()) and
+ * therefore stage2_set_pte() never needs to clear out a huge PMD
+ * through this calling path.
+ */
+ stage2_set_pte(kvm, NULL, gpa, pte, 0);
+ return 0;
+}
+
+
+void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte)
+{
+ unsigned long end = hva + PAGE_SIZE;
+ pte_t stage2_pte;
+
+ if (!kvm->arch.pgd)
+ return;
+
+ trace_kvm_set_spte_hva(hva);
+ stage2_pte = pfn_pte(pte_pfn(pte), PAGE_S2);
+ handle_hva_to_gpa(kvm, hva, end, &kvm_set_spte_handler, &stage2_pte);
+}
+
+static int kvm_age_hva_handler(struct kvm *kvm, gpa_t gpa, void *data)
+{
+ pmd_t *pmd;
+ pte_t *pte;
+
+ pmd = stage2_get_pmd(kvm, NULL, gpa);
+ if (!pmd || pmd_none(*pmd)) /* Nothing there */
+ return 0;
+
+ if (kvm_pmd_huge(*pmd)) { /* THP, HugeTLB */
+ if (pmd_young(*pmd)) {
+ *pmd = pmd_mkold(*pmd);
+ return 1;
+ }
+
+ return 0;
+ }
+
+ pte = pte_offset_kernel(pmd, gpa);
+ if (pte_none(*pte))
+ return 0;
+
+ if (pte_young(*pte)) {
+ *pte = pte_mkold(*pte); /* Just a page... */
+ return 1;
+ }
+
+ return 0;
+}
+
+static int kvm_test_age_hva_handler(struct kvm *kvm, gpa_t gpa, void *data)
+{
+ pmd_t *pmd;
+ pte_t *pte;
+
+ pmd = stage2_get_pmd(kvm, NULL, gpa);
+ if (!pmd || pmd_none(*pmd)) /* Nothing there */
+ return 0;
+
+ if (kvm_pmd_huge(*pmd)) /* THP, HugeTLB */
+ return pmd_young(*pmd);
+
+ pte = pte_offset_kernel(pmd, gpa);
+ if (!pte_none(*pte)) /* Just a page... */
+ return pte_young(*pte);
+
+ return 0;
+}
+
+int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end)
+{
+ trace_kvm_age_hva(start, end);
+ return handle_hva_to_gpa(kvm, start, end, kvm_age_hva_handler, NULL);
+}
+
+int kvm_test_age_hva(struct kvm *kvm, unsigned long hva)
+{
+ trace_kvm_test_age_hva(hva);
+ return handle_hva_to_gpa(kvm, hva, hva, kvm_test_age_hva_handler, NULL);
+}
+
+void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu)
+{
+ mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
+}
+
+phys_addr_t kvm_mmu_get_httbr(void)
+{
+ if (__kvm_cpu_uses_extended_idmap())
+ return virt_to_phys(merged_hyp_pgd);
+ else
+ return virt_to_phys(hyp_pgd);
+}
+
+phys_addr_t kvm_mmu_get_boot_httbr(void)
+{
+ if (__kvm_cpu_uses_extended_idmap())
+ return virt_to_phys(merged_hyp_pgd);
+ else
+ return virt_to_phys(boot_hyp_pgd);
+}
+
+phys_addr_t kvm_get_idmap_vector(void)
+{
+ return hyp_idmap_vector;
+}
+
+int kvm_mmu_init(void)
+{
+ int err;
+
+ hyp_idmap_start = kvm_virt_to_phys(__hyp_idmap_text_start);
+ hyp_idmap_end = kvm_virt_to_phys(__hyp_idmap_text_end);
+ hyp_idmap_vector = kvm_virt_to_phys(__kvm_hyp_init);
+
+ /*
+ * We rely on the linker script to ensure at build time that the HYP
+ * init code does not cross a page boundary.
+ */
+ BUG_ON((hyp_idmap_start ^ (hyp_idmap_end - 1)) & PAGE_MASK);
+
+ hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, hyp_pgd_order);
+ boot_hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, hyp_pgd_order);
+
+ if (!hyp_pgd || !boot_hyp_pgd) {
+ kvm_err("Hyp mode PGD not allocated\n");
+ err = -ENOMEM;
+ goto out;
+ }
+
+ /* Create the idmap in the boot page tables */
+ err = __create_hyp_mappings(boot_hyp_pgd,
+ hyp_idmap_start, hyp_idmap_end,
+ __phys_to_pfn(hyp_idmap_start),
+ PAGE_HYP);
+
+ if (err) {
+ kvm_err("Failed to idmap %lx-%lx\n",
+ hyp_idmap_start, hyp_idmap_end);
+ goto out;
+ }
+
+ if (__kvm_cpu_uses_extended_idmap()) {
+ merged_hyp_pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
+ if (!merged_hyp_pgd) {
+ kvm_err("Failed to allocate extra HYP pgd\n");
+ goto out;
+ }
+ __kvm_extend_hypmap(boot_hyp_pgd, hyp_pgd, merged_hyp_pgd,
+ hyp_idmap_start);
+ return 0;
+ }
+
+ /* Map the very same page at the trampoline VA */
+ err = __create_hyp_mappings(boot_hyp_pgd,
+ TRAMPOLINE_VA, TRAMPOLINE_VA + PAGE_SIZE,
+ __phys_to_pfn(hyp_idmap_start),
+ PAGE_HYP);
+ if (err) {
+ kvm_err("Failed to map trampoline @%lx into boot HYP pgd\n",
+ TRAMPOLINE_VA);
+ goto out;
+ }
+
+ /* Map the same page again into the runtime page tables */
+ err = __create_hyp_mappings(hyp_pgd,
+ TRAMPOLINE_VA, TRAMPOLINE_VA + PAGE_SIZE,
+ __phys_to_pfn(hyp_idmap_start),
+ PAGE_HYP);
+ if (err) {
+ kvm_err("Failed to map trampoline @%lx into runtime HYP pgd\n",
+ TRAMPOLINE_VA);
+ goto out;
+ }
+
+ return 0;
+out:
+ free_hyp_pgds();
+ return err;
+}
+
+void kvm_arch_commit_memory_region(struct kvm *kvm,
+ struct kvm_userspace_memory_region *mem,
+ const struct kvm_memory_slot *old,
+ enum kvm_mr_change change)
+{
+ /*
+ * At this point memslot has been committed and there is an
+ * allocated dirty_bitmap[], dirty pages will be be tracked while the
+ * memory slot is write protected.
+ */
+ if (change != KVM_MR_DELETE && mem->flags & KVM_MEM_LOG_DIRTY_PAGES)
+ kvm_mmu_wp_memory_region(kvm, mem->slot);
+}
+
+int kvm_arch_prepare_memory_region(struct kvm *kvm,
+ struct kvm_memory_slot *memslot,
+ struct kvm_userspace_memory_region *mem,
+ enum kvm_mr_change change)
+{
+ hva_t hva = mem->userspace_addr;
+ hva_t reg_end = hva + mem->memory_size;
+ bool writable = !(mem->flags & KVM_MEM_READONLY);
+ int ret = 0;
+
+ if (change != KVM_MR_CREATE && change != KVM_MR_MOVE &&
+ change != KVM_MR_FLAGS_ONLY)
+ return 0;
+
+ /*
+ * Prevent userspace from creating a memory region outside of the IPA
+ * space addressable by the KVM guest IPA space.
+ */
+ if (memslot->base_gfn + memslot->npages >=
+ (KVM_PHYS_SIZE >> PAGE_SHIFT))
+ return -EFAULT;
+
+ /*
+ * A memory region could potentially cover multiple VMAs, and any holes
+ * between them, so iterate over all of them to find out if we can map
+ * any of them right now.
+ *
+ * +--------------------------------------------+
+ * +---------------+----------------+ +----------------+
+ * | : VMA 1 | VMA 2 | | VMA 3 : |
+ * +---------------+----------------+ +----------------+
+ * | memory region |
+ * +--------------------------------------------+
+ */
+ do {
+ struct vm_area_struct *vma = find_vma(current->mm, hva);
+ hva_t vm_start, vm_end;
+
+ if (!vma || vma->vm_start >= reg_end)
+ break;
+
+ /*
+ * Mapping a read-only VMA is only allowed if the
+ * memory region is configured as read-only.
+ */
+ if (writable && !(vma->vm_flags & VM_WRITE)) {
+ ret = -EPERM;
+ break;
+ }
+
+ /*
+ * Take the intersection of this VMA with the memory region
+ */
+ vm_start = max(hva, vma->vm_start);
+ vm_end = min(reg_end, vma->vm_end);
+
+ if (vma->vm_flags & VM_PFNMAP) {
+ gpa_t gpa = mem->guest_phys_addr +
+ (vm_start - mem->userspace_addr);
+ phys_addr_t pa = (vma->vm_pgoff << PAGE_SHIFT) +
+ vm_start - vma->vm_start;
+
+ /* IO region dirty page logging not allowed */
+ if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES)
+ return -EINVAL;
+
+ ret = kvm_phys_addr_ioremap(kvm, gpa, pa,
+ vm_end - vm_start,
+ writable);
+ if (ret)
+ break;
+ }
+ hva = vm_end;
+ } while (hva < reg_end);
+
+ if (change == KVM_MR_FLAGS_ONLY)
+ return ret;
+
+ spin_lock(&kvm->mmu_lock);
+ if (ret)
+ unmap_stage2_range(kvm, mem->guest_phys_addr, mem->memory_size);
+ else
+ stage2_flush_memslot(kvm, memslot);
+ spin_unlock(&kvm->mmu_lock);
+ return ret;
+}
+
+void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free,
+ struct kvm_memory_slot *dont)
+{
+}
+
+int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
+ unsigned long npages)
+{
+ /*
+ * Readonly memslots are not incoherent with the caches by definition,
+ * but in practice, they are used mostly to emulate ROMs or NOR flashes
+ * that the guest may consider devices and hence map as uncached.
+ * To prevent incoherency issues in these cases, tag all readonly
+ * regions as incoherent.
+ */
+ if (slot->flags & KVM_MEM_READONLY)
+ slot->flags |= KVM_MEMSLOT_INCOHERENT;
+ return 0;
+}
+
+void kvm_arch_memslots_updated(struct kvm *kvm)
+{
+}
+
+void kvm_arch_flush_shadow_all(struct kvm *kvm)
+{
+}
+
+void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
+ struct kvm_memory_slot *slot)
+{
+ gpa_t gpa = slot->base_gfn << PAGE_SHIFT;
+ phys_addr_t size = slot->npages << PAGE_SHIFT;
+
+ spin_lock(&kvm->mmu_lock);
+ unmap_stage2_range(kvm, gpa, size);
+ spin_unlock(&kvm->mmu_lock);
+}
+
+/*
+ * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized).
+ *
+ * Main problems:
+ * - S/W ops are local to a CPU (not broadcast)
+ * - We have line migration behind our back (speculation)
+ * - System caches don't support S/W at all (damn!)
+ *
+ * In the face of the above, the best we can do is to try and convert
+ * S/W ops to VA ops. Because the guest is not allowed to infer the
+ * S/W to PA mapping, it can only use S/W to nuke the whole cache,
+ * which is a rather good thing for us.
+ *
+ * Also, it is only used when turning caches on/off ("The expected
+ * usage of the cache maintenance instructions that operate by set/way
+ * is associated with the cache maintenance instructions associated
+ * with the powerdown and powerup of caches, if this is required by
+ * the implementation.").
+ *
+ * We use the following policy:
+ *
+ * - If we trap a S/W operation, we enable VM trapping to detect
+ * caches being turned on/off, and do a full clean.
+ *
+ * - We flush the caches on both caches being turned on and off.
+ *
+ * - Once the caches are enabled, we stop trapping VM ops.
+ */
+void kvm_set_way_flush(struct kvm_vcpu *vcpu)
+{
+ unsigned long hcr = vcpu_get_hcr(vcpu);
+
+ /*
+ * If this is the first time we do a S/W operation
+ * (i.e. HCR_TVM not set) flush the whole memory, and set the
+ * VM trapping.
+ *
+ * Otherwise, rely on the VM trapping to wait for the MMU +
+ * Caches to be turned off. At that point, we'll be able to
+ * clean the caches again.
+ */
+ if (!(hcr & HCR_TVM)) {
+ trace_kvm_set_way_flush(*vcpu_pc(vcpu),
+ vcpu_has_cache_enabled(vcpu));
+ stage2_flush_vm(vcpu->kvm);
+ vcpu_set_hcr(vcpu, hcr | HCR_TVM);
+ }
+}
+
+void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled)
+{
+ bool now_enabled = vcpu_has_cache_enabled(vcpu);
+
+ /*
+ * If switching the MMU+caches on, need to invalidate the caches.
+ * If switching it off, need to clean the caches.
+ * Clean + invalidate does the trick always.
+ */
+ if (now_enabled != was_enabled)
+ stage2_flush_vm(vcpu->kvm);
+
+ /* Caches are now on, stop trapping VM ops (until a S/W op) */
+ if (now_enabled)
+ vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) & ~HCR_TVM);
+
+ trace_kvm_toggle_cache(*vcpu_pc(vcpu), was_enabled, now_enabled);
+}
diff --git a/arch/arm/kvm/perf.c b/arch/arm/kvm/perf.c
new file mode 100644
index 000000000..1a3849da0
--- /dev/null
+++ b/arch/arm/kvm/perf.c
@@ -0,0 +1,68 @@
+/*
+ * Based on the x86 implementation.
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ * Author: Marc Zyngier <marc.zyngier@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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/perf_event.h>
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_emulate.h>
+
+static int kvm_is_in_guest(void)
+{
+ return kvm_arm_get_running_vcpu() != NULL;
+}
+
+static int kvm_is_user_mode(void)
+{
+ struct kvm_vcpu *vcpu;
+
+ vcpu = kvm_arm_get_running_vcpu();
+
+ if (vcpu)
+ return !vcpu_mode_priv(vcpu);
+
+ return 0;
+}
+
+static unsigned long kvm_get_guest_ip(void)
+{
+ struct kvm_vcpu *vcpu;
+
+ vcpu = kvm_arm_get_running_vcpu();
+
+ if (vcpu)
+ return *vcpu_pc(vcpu);
+
+ return 0;
+}
+
+static struct perf_guest_info_callbacks kvm_guest_cbs = {
+ .is_in_guest = kvm_is_in_guest,
+ .is_user_mode = kvm_is_user_mode,
+ .get_guest_ip = kvm_get_guest_ip,
+};
+
+int kvm_perf_init(void)
+{
+ return perf_register_guest_info_callbacks(&kvm_guest_cbs);
+}
+
+int kvm_perf_teardown(void)
+{
+ return perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
+}
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
new file mode 100644
index 000000000..531e92248
--- /dev/null
+++ b/arch/arm/kvm/psci.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2012 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/preempt.h>
+#include <linux/kvm_host.h>
+#include <linux/wait.h>
+
+#include <asm/cputype.h>
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_psci.h>
+#include <asm/kvm_host.h>
+
+/*
+ * This is an implementation of the Power State Coordination Interface
+ * as described in ARM document number ARM DEN 0022A.
+ */
+
+#define AFFINITY_MASK(level) ~((0x1UL << ((level) * MPIDR_LEVEL_BITS)) - 1)
+
+static unsigned long psci_affinity_mask(unsigned long affinity_level)
+{
+ if (affinity_level <= 3)
+ return MPIDR_HWID_BITMASK & AFFINITY_MASK(affinity_level);
+
+ return 0;
+}
+
+static unsigned long kvm_psci_vcpu_suspend(struct kvm_vcpu *vcpu)
+{
+ /*
+ * NOTE: For simplicity, we make VCPU suspend emulation to be
+ * same-as WFI (Wait-for-interrupt) emulation.
+ *
+ * This means for KVM the wakeup events are interrupts and
+ * this is consistent with intended use of StateID as described
+ * in section 5.4.1 of PSCI v0.2 specification (ARM DEN 0022A).
+ *
+ * Further, we also treat power-down request to be same as
+ * stand-by request as-per section 5.4.2 clause 3 of PSCI v0.2
+ * specification (ARM DEN 0022A). This means all suspend states
+ * for KVM will preserve the register state.
+ */
+ kvm_vcpu_block(vcpu);
+
+ return PSCI_RET_SUCCESS;
+}
+
+static void kvm_psci_vcpu_off(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.pause = true;
+}
+
+static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
+{
+ struct kvm *kvm = source_vcpu->kvm;
+ struct kvm_vcpu *vcpu = NULL;
+ wait_queue_head_t *wq;
+ unsigned long cpu_id;
+ unsigned long context_id;
+ phys_addr_t target_pc;
+
+ cpu_id = *vcpu_reg(source_vcpu, 1) & MPIDR_HWID_BITMASK;
+ if (vcpu_mode_is_32bit(source_vcpu))
+ cpu_id &= ~((u32) 0);
+
+ vcpu = kvm_mpidr_to_vcpu(kvm, cpu_id);
+
+ /*
+ * Make sure the caller requested a valid CPU and that the CPU is
+ * turned off.
+ */
+ if (!vcpu)
+ return PSCI_RET_INVALID_PARAMS;
+ if (!vcpu->arch.pause) {
+ if (kvm_psci_version(source_vcpu) != KVM_ARM_PSCI_0_1)
+ return PSCI_RET_ALREADY_ON;
+ else
+ return PSCI_RET_INVALID_PARAMS;
+ }
+
+ target_pc = *vcpu_reg(source_vcpu, 2);
+ context_id = *vcpu_reg(source_vcpu, 3);
+
+ kvm_reset_vcpu(vcpu);
+
+ /* Gracefully handle Thumb2 entry point */
+ if (vcpu_mode_is_32bit(vcpu) && (target_pc & 1)) {
+ target_pc &= ~((phys_addr_t) 1);
+ vcpu_set_thumb(vcpu);
+ }
+
+ /* Propagate caller endianness */
+ if (kvm_vcpu_is_be(source_vcpu))
+ kvm_vcpu_set_be(vcpu);
+
+ *vcpu_pc(vcpu) = target_pc;
+ /*
+ * NOTE: We always update r0 (or x0) because for PSCI v0.1
+ * the general puspose registers are undefined upon CPU_ON.
+ */
+ *vcpu_reg(vcpu, 0) = context_id;
+ vcpu->arch.pause = false;
+ smp_mb(); /* Make sure the above is visible */
+
+ wq = kvm_arch_vcpu_wq(vcpu);
+ wake_up_interruptible(wq);
+
+ return PSCI_RET_SUCCESS;
+}
+
+static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
+{
+ int i;
+ unsigned long mpidr;
+ unsigned long target_affinity;
+ unsigned long target_affinity_mask;
+ unsigned long lowest_affinity_level;
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_vcpu *tmp;
+
+ target_affinity = *vcpu_reg(vcpu, 1);
+ lowest_affinity_level = *vcpu_reg(vcpu, 2);
+
+ /* Determine target affinity mask */
+ target_affinity_mask = psci_affinity_mask(lowest_affinity_level);
+ if (!target_affinity_mask)
+ return PSCI_RET_INVALID_PARAMS;
+
+ /* Ignore other bits of target affinity */
+ target_affinity &= target_affinity_mask;
+
+ /*
+ * If one or more VCPU matching target affinity are running
+ * then ON else OFF
+ */
+ kvm_for_each_vcpu(i, tmp, kvm) {
+ mpidr = kvm_vcpu_get_mpidr_aff(tmp);
+ if (((mpidr & target_affinity_mask) == target_affinity) &&
+ !tmp->arch.pause) {
+ return PSCI_0_2_AFFINITY_LEVEL_ON;
+ }
+ }
+
+ return PSCI_0_2_AFFINITY_LEVEL_OFF;
+}
+
+static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type)
+{
+ int i;
+ struct kvm_vcpu *tmp;
+
+ /*
+ * The KVM ABI specifies that a system event exit may call KVM_RUN
+ * again and may perform shutdown/reboot at a later time that when the
+ * actual request is made. Since we are implementing PSCI and a
+ * caller of PSCI reboot and shutdown expects that the system shuts
+ * down or reboots immediately, let's make sure that VCPUs are not run
+ * after this call is handled and before the VCPUs have been
+ * re-initialized.
+ */
+ kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
+ tmp->arch.pause = true;
+ kvm_vcpu_kick(tmp);
+ }
+
+ memset(&vcpu->run->system_event, 0, sizeof(vcpu->run->system_event));
+ vcpu->run->system_event.type = type;
+ vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
+}
+
+static void kvm_psci_system_off(struct kvm_vcpu *vcpu)
+{
+ kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_SHUTDOWN);
+}
+
+static void kvm_psci_system_reset(struct kvm_vcpu *vcpu)
+{
+ kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_RESET);
+}
+
+int kvm_psci_version(struct kvm_vcpu *vcpu)
+{
+ if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
+ return KVM_ARM_PSCI_0_2;
+
+ return KVM_ARM_PSCI_0_1;
+}
+
+static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
+{
+ int ret = 1;
+ unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
+ unsigned long val;
+
+ switch (psci_fn) {
+ case PSCI_0_2_FN_PSCI_VERSION:
+ /*
+ * Bits[31:16] = Major Version = 0
+ * Bits[15:0] = Minor Version = 2
+ */
+ val = 2;
+ break;
+ case PSCI_0_2_FN_CPU_SUSPEND:
+ case PSCI_0_2_FN64_CPU_SUSPEND:
+ val = kvm_psci_vcpu_suspend(vcpu);
+ break;
+ case PSCI_0_2_FN_CPU_OFF:
+ kvm_psci_vcpu_off(vcpu);
+ val = PSCI_RET_SUCCESS;
+ break;
+ case PSCI_0_2_FN_CPU_ON:
+ case PSCI_0_2_FN64_CPU_ON:
+ val = kvm_psci_vcpu_on(vcpu);
+ break;
+ case PSCI_0_2_FN_AFFINITY_INFO:
+ case PSCI_0_2_FN64_AFFINITY_INFO:
+ val = kvm_psci_vcpu_affinity_info(vcpu);
+ break;
+ case PSCI_0_2_FN_MIGRATE_INFO_TYPE:
+ /*
+ * Trusted OS is MP hence does not require migration
+ * or
+ * Trusted OS is not present
+ */
+ val = PSCI_0_2_TOS_MP;
+ break;
+ case PSCI_0_2_FN_SYSTEM_OFF:
+ kvm_psci_system_off(vcpu);
+ /*
+ * We should'nt be going back to guest VCPU after
+ * receiving SYSTEM_OFF request.
+ *
+ * If user space accidently/deliberately resumes
+ * guest VCPU after SYSTEM_OFF request then guest
+ * VCPU should see internal failure from PSCI return
+ * value. To achieve this, we preload r0 (or x0) with
+ * PSCI return value INTERNAL_FAILURE.
+ */
+ val = PSCI_RET_INTERNAL_FAILURE;
+ ret = 0;
+ break;
+ case PSCI_0_2_FN_SYSTEM_RESET:
+ kvm_psci_system_reset(vcpu);
+ /*
+ * Same reason as SYSTEM_OFF for preloading r0 (or x0)
+ * with PSCI return value INTERNAL_FAILURE.
+ */
+ val = PSCI_RET_INTERNAL_FAILURE;
+ ret = 0;
+ break;
+ default:
+ val = PSCI_RET_NOT_SUPPORTED;
+ break;
+ }
+
+ *vcpu_reg(vcpu, 0) = val;
+ return ret;
+}
+
+static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
+{
+ unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
+ unsigned long val;
+
+ switch (psci_fn) {
+ case KVM_PSCI_FN_CPU_OFF:
+ kvm_psci_vcpu_off(vcpu);
+ val = PSCI_RET_SUCCESS;
+ break;
+ case KVM_PSCI_FN_CPU_ON:
+ val = kvm_psci_vcpu_on(vcpu);
+ break;
+ default:
+ val = PSCI_RET_NOT_SUPPORTED;
+ break;
+ }
+
+ *vcpu_reg(vcpu, 0) = val;
+ return 1;
+}
+
+/**
+ * kvm_psci_call - handle PSCI call if r0 value is in range
+ * @vcpu: Pointer to the VCPU struct
+ *
+ * Handle PSCI calls from guests through traps from HVC instructions.
+ * The calling convention is similar to SMC calls to the secure world
+ * where the function number is placed in r0.
+ *
+ * This function returns: > 0 (success), 0 (success but exit to user
+ * space), and < 0 (errors)
+ *
+ * Errors:
+ * -EINVAL: Unrecognized PSCI function
+ */
+int kvm_psci_call(struct kvm_vcpu *vcpu)
+{
+ switch (kvm_psci_version(vcpu)) {
+ case KVM_ARM_PSCI_0_2:
+ return kvm_psci_0_2_call(vcpu);
+ case KVM_ARM_PSCI_0_1:
+ return kvm_psci_0_1_call(vcpu);
+ default:
+ return -EINVAL;
+ };
+}
diff --git a/arch/arm/kvm/reset.c b/arch/arm/kvm/reset.c
new file mode 100644
index 000000000..f558c073c
--- /dev/null
+++ b/arch/arm/kvm/reset.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <linux/compiler.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kvm_host.h>
+#include <linux/kvm.h>
+
+#include <asm/unified.h>
+#include <asm/ptrace.h>
+#include <asm/cputype.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_coproc.h>
+
+#include <kvm/arm_arch_timer.h>
+
+/******************************************************************************
+ * Cortex-A15 and Cortex-A7 Reset Values
+ */
+
+static struct kvm_regs cortexa_regs_reset = {
+ .usr_regs.ARM_cpsr = SVC_MODE | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT,
+};
+
+static const struct kvm_irq_level cortexa_vtimer_irq = {
+ { .irq = 27 },
+ .level = 1,
+};
+
+
+/*******************************************************************************
+ * Exported reset function
+ */
+
+/**
+ * kvm_reset_vcpu - sets core registers and cp15 registers to reset value
+ * @vcpu: The VCPU pointer
+ *
+ * This function finds the right table above and sets the registers on the
+ * virtual CPU struct to their architectually defined reset values.
+ */
+int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
+{
+ struct kvm_regs *reset_regs;
+ const struct kvm_irq_level *cpu_vtimer_irq;
+
+ switch (vcpu->arch.target) {
+ case KVM_ARM_TARGET_CORTEX_A7:
+ case KVM_ARM_TARGET_CORTEX_A15:
+ reset_regs = &cortexa_regs_reset;
+ vcpu->arch.midr = read_cpuid_id();
+ cpu_vtimer_irq = &cortexa_vtimer_irq;
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ /* Reset core registers */
+ memcpy(&vcpu->arch.regs, reset_regs, sizeof(vcpu->arch.regs));
+
+ /* Reset CP15 registers */
+ kvm_reset_coprocs(vcpu);
+
+ /* Reset arch_timer context */
+ kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
+
+ return 0;
+}
diff --git a/arch/arm/kvm/trace.h b/arch/arm/kvm/trace.h
new file mode 100644
index 000000000..0ec35392d
--- /dev/null
+++ b/arch/arm/kvm/trace.h
@@ -0,0 +1,328 @@
+#if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_KVM_H
+
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kvm
+
+/*
+ * Tracepoints for entry/exit to guest
+ */
+TRACE_EVENT(kvm_entry,
+ TP_PROTO(unsigned long vcpu_pc),
+ TP_ARGS(vcpu_pc),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, vcpu_pc )
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_pc = vcpu_pc;
+ ),
+
+ TP_printk("PC: 0x%08lx", __entry->vcpu_pc)
+);
+
+TRACE_EVENT(kvm_exit,
+ TP_PROTO(unsigned int exit_reason, unsigned long vcpu_pc),
+ TP_ARGS(exit_reason, vcpu_pc),
+
+ TP_STRUCT__entry(
+ __field( unsigned int, exit_reason )
+ __field( unsigned long, vcpu_pc )
+ ),
+
+ TP_fast_assign(
+ __entry->exit_reason = exit_reason;
+ __entry->vcpu_pc = vcpu_pc;
+ ),
+
+ TP_printk("HSR_EC: 0x%04x, PC: 0x%08lx",
+ __entry->exit_reason,
+ __entry->vcpu_pc)
+);
+
+TRACE_EVENT(kvm_guest_fault,
+ TP_PROTO(unsigned long vcpu_pc, unsigned long hsr,
+ unsigned long hxfar,
+ unsigned long long ipa),
+ TP_ARGS(vcpu_pc, hsr, hxfar, ipa),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, vcpu_pc )
+ __field( unsigned long, hsr )
+ __field( unsigned long, hxfar )
+ __field( unsigned long long, ipa )
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_pc = vcpu_pc;
+ __entry->hsr = hsr;
+ __entry->hxfar = hxfar;
+ __entry->ipa = ipa;
+ ),
+
+ TP_printk("ipa %#llx, hsr %#08lx, hxfar %#08lx, pc %#08lx",
+ __entry->ipa, __entry->hsr,
+ __entry->hxfar, __entry->vcpu_pc)
+);
+
+TRACE_EVENT(kvm_access_fault,
+ TP_PROTO(unsigned long ipa),
+ TP_ARGS(ipa),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, ipa )
+ ),
+
+ TP_fast_assign(
+ __entry->ipa = ipa;
+ ),
+
+ TP_printk("IPA: %lx", __entry->ipa)
+);
+
+TRACE_EVENT(kvm_irq_line,
+ TP_PROTO(unsigned int type, int vcpu_idx, int irq_num, int level),
+ TP_ARGS(type, vcpu_idx, irq_num, level),
+
+ TP_STRUCT__entry(
+ __field( unsigned int, type )
+ __field( int, vcpu_idx )
+ __field( int, irq_num )
+ __field( int, level )
+ ),
+
+ TP_fast_assign(
+ __entry->type = type;
+ __entry->vcpu_idx = vcpu_idx;
+ __entry->irq_num = irq_num;
+ __entry->level = level;
+ ),
+
+ TP_printk("Inject %s interrupt (%d), vcpu->idx: %d, num: %d, level: %d",
+ (__entry->type == KVM_ARM_IRQ_TYPE_CPU) ? "CPU" :
+ (__entry->type == KVM_ARM_IRQ_TYPE_PPI) ? "VGIC PPI" :
+ (__entry->type == KVM_ARM_IRQ_TYPE_SPI) ? "VGIC SPI" : "UNKNOWN",
+ __entry->type, __entry->vcpu_idx, __entry->irq_num, __entry->level)
+);
+
+TRACE_EVENT(kvm_mmio_emulate,
+ TP_PROTO(unsigned long vcpu_pc, unsigned long instr,
+ unsigned long cpsr),
+ TP_ARGS(vcpu_pc, instr, cpsr),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, vcpu_pc )
+ __field( unsigned long, instr )
+ __field( unsigned long, cpsr )
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_pc = vcpu_pc;
+ __entry->instr = instr;
+ __entry->cpsr = cpsr;
+ ),
+
+ TP_printk("Emulate MMIO at: 0x%08lx (instr: %08lx, cpsr: %08lx)",
+ __entry->vcpu_pc, __entry->instr, __entry->cpsr)
+);
+
+/* Architecturally implementation defined CP15 register access */
+TRACE_EVENT(kvm_emulate_cp15_imp,
+ TP_PROTO(unsigned long Op1, unsigned long Rt1, unsigned long CRn,
+ unsigned long CRm, unsigned long Op2, bool is_write),
+ TP_ARGS(Op1, Rt1, CRn, CRm, Op2, is_write),
+
+ TP_STRUCT__entry(
+ __field( unsigned int, Op1 )
+ __field( unsigned int, Rt1 )
+ __field( unsigned int, CRn )
+ __field( unsigned int, CRm )
+ __field( unsigned int, Op2 )
+ __field( bool, is_write )
+ ),
+
+ TP_fast_assign(
+ __entry->is_write = is_write;
+ __entry->Op1 = Op1;
+ __entry->Rt1 = Rt1;
+ __entry->CRn = CRn;
+ __entry->CRm = CRm;
+ __entry->Op2 = Op2;
+ ),
+
+ TP_printk("Implementation defined CP15: %s\tp15, %u, r%u, c%u, c%u, %u",
+ (__entry->is_write) ? "mcr" : "mrc",
+ __entry->Op1, __entry->Rt1, __entry->CRn,
+ __entry->CRm, __entry->Op2)
+);
+
+TRACE_EVENT(kvm_wfx,
+ TP_PROTO(unsigned long vcpu_pc, bool is_wfe),
+ TP_ARGS(vcpu_pc, is_wfe),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, vcpu_pc )
+ __field( bool, is_wfe )
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_pc = vcpu_pc;
+ __entry->is_wfe = is_wfe;
+ ),
+
+ TP_printk("guest executed wf%c at: 0x%08lx",
+ __entry->is_wfe ? 'e' : 'i', __entry->vcpu_pc)
+);
+
+TRACE_EVENT(kvm_unmap_hva,
+ TP_PROTO(unsigned long hva),
+ TP_ARGS(hva),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, hva )
+ ),
+
+ TP_fast_assign(
+ __entry->hva = hva;
+ ),
+
+ TP_printk("mmu notifier unmap hva: %#08lx", __entry->hva)
+);
+
+TRACE_EVENT(kvm_unmap_hva_range,
+ TP_PROTO(unsigned long start, unsigned long end),
+ TP_ARGS(start, end),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, start )
+ __field( unsigned long, end )
+ ),
+
+ TP_fast_assign(
+ __entry->start = start;
+ __entry->end = end;
+ ),
+
+ TP_printk("mmu notifier unmap range: %#08lx -- %#08lx",
+ __entry->start, __entry->end)
+);
+
+TRACE_EVENT(kvm_set_spte_hva,
+ TP_PROTO(unsigned long hva),
+ TP_ARGS(hva),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, hva )
+ ),
+
+ TP_fast_assign(
+ __entry->hva = hva;
+ ),
+
+ TP_printk("mmu notifier set pte hva: %#08lx", __entry->hva)
+);
+
+TRACE_EVENT(kvm_age_hva,
+ TP_PROTO(unsigned long start, unsigned long end),
+ TP_ARGS(start, end),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, start )
+ __field( unsigned long, end )
+ ),
+
+ TP_fast_assign(
+ __entry->start = start;
+ __entry->end = end;
+ ),
+
+ TP_printk("mmu notifier age hva: %#08lx -- %#08lx",
+ __entry->start, __entry->end)
+);
+
+TRACE_EVENT(kvm_test_age_hva,
+ TP_PROTO(unsigned long hva),
+ TP_ARGS(hva),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, hva )
+ ),
+
+ TP_fast_assign(
+ __entry->hva = hva;
+ ),
+
+ TP_printk("mmu notifier test age hva: %#08lx", __entry->hva)
+);
+
+TRACE_EVENT(kvm_hvc,
+ TP_PROTO(unsigned long vcpu_pc, unsigned long r0, unsigned long imm),
+ TP_ARGS(vcpu_pc, r0, imm),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, vcpu_pc )
+ __field( unsigned long, r0 )
+ __field( unsigned long, imm )
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_pc = vcpu_pc;
+ __entry->r0 = r0;
+ __entry->imm = imm;
+ ),
+
+ TP_printk("HVC at 0x%08lx (r0: 0x%08lx, imm: 0x%lx",
+ __entry->vcpu_pc, __entry->r0, __entry->imm)
+);
+
+TRACE_EVENT(kvm_set_way_flush,
+ TP_PROTO(unsigned long vcpu_pc, bool cache),
+ TP_ARGS(vcpu_pc, cache),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, vcpu_pc )
+ __field( bool, cache )
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_pc = vcpu_pc;
+ __entry->cache = cache;
+ ),
+
+ TP_printk("S/W flush at 0x%016lx (cache %s)",
+ __entry->vcpu_pc, __entry->cache ? "on" : "off")
+);
+
+TRACE_EVENT(kvm_toggle_cache,
+ TP_PROTO(unsigned long vcpu_pc, bool was, bool now),
+ TP_ARGS(vcpu_pc, was, now),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, vcpu_pc )
+ __field( bool, was )
+ __field( bool, now )
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_pc = vcpu_pc;
+ __entry->was = was;
+ __entry->now = now;
+ ),
+
+ TP_printk("VM op at 0x%016lx (cache was %s, now %s)",
+ __entry->vcpu_pc, __entry->was ? "on" : "off",
+ __entry->now ? "on" : "off")
+);
+
+#endif /* _TRACE_KVM_H */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH arch/arm/kvm
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE trace
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
new file mode 100644
index 000000000..d8a780799
--- /dev/null
+++ b/arch/arm/lib/Makefile
@@ -0,0 +1,41 @@
+#
+# 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 delay-loop.o findbit.o memchr.o memcpy.o \
+ memmove.o memset.o memzero.o setbit.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 \
+ io-readsb.o io-writesb.o io-readsl.o io-writesl.o \
+ call_with_stack.o bswapsdi2.o
+
+mmu-y := clear_user.o copy_page.o getuser.o putuser.o \
+ copy_from_user.o copy_to_user.o
+
+# 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
+
+$(obj)/csumpartialcopy.o: $(obj)/csumpartialcopygeneric.S
+$(obj)/csumpartialcopyuser.o: $(obj)/csumpartialcopygeneric.S
+
+ifeq ($(CONFIG_KERNEL_MODE_NEON),y)
+ NEON_FLAGS := -mfloat-abi=softfp -mfpu=neon
+ CFLAGS_xor-neon.o += $(NEON_FLAGS)
+ obj-$(CONFIG_XOR_BLOCKS) += xor-neon.o
+endif
diff --git a/arch/arm/lib/ashldi3.S b/arch/arm/lib/ashldi3.S
new file mode 100644
index 000000000..b05e95840
--- /dev/null
+++ b/arch/arm/lib/ashldi3.S
@@ -0,0 +1,54 @@
+/* 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>
+#include <asm/assembler.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
+ ret 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 000000000..275d7d234
--- /dev/null
+++ b/arch/arm/lib/ashrdi3.S
@@ -0,0 +1,54 @@
+/* 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>
+#include <asm/assembler.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
+ ret 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 000000000..fab5a5050
--- /dev/null
+++ b/arch/arm/lib/backtrace.S
@@ -0,0 +1,152 @@
+/*
+ * 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(c_backtrace)
+
+#if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
+ ret lr
+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 #11
+ 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 #11
+ 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(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, #0
+ adr r3, .Lcr
+ addne r3, r3, #1 @ skip newline
+ ldr r2, [stack], #-4
+ mov r1, 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 " r%d:%08x%s"
+.Lcr: .asciz "\n"
+.Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n"
+ .align
+.Ldsi: .word 0xe92dd800 >> 11 @ stmfd sp!, {... fp, ip, lr, pc}
+ .word 0xe92d0000 >> 11 @ stmfd sp!, {}
+
+#endif
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
new file mode 100644
index 000000000..7d807cfd8
--- /dev/null
+++ b/arch/arm/lib/bitops.h
@@ -0,0 +1,106 @@
+#include <asm/assembler.h>
+#include <asm/unwind.h>
+
+#if __LINUX_ARM_ARCH__ >= 6
+ .macro bitop, name, instr
+ENTRY( \name )
+UNWIND( .fnstart )
+ 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
+#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
+ .arch_extension mp
+ ALT_SMP(W(pldw) [r1])
+ ALT_UP(W(nop))
+#endif
+ mov r3, r2, lsl r3
+1: ldrex r2, [r1]
+ \instr r2, r2, r3
+ strex r0, r2, [r1]
+ cmp r0, #0
+ bne 1b
+ bx lr
+UNWIND( .fnend )
+ENDPROC(\name )
+ .endm
+
+ .macro testop, name, instr, store
+ENTRY( \name )
+UNWIND( .fnstart )
+ 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
+#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
+ .arch_extension mp
+ ALT_SMP(W(pldw) [r1])
+ ALT_UP(W(nop))
+#endif
+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
+UNWIND( .fnend )
+ENDPROC(\name )
+ .endm
+#else
+ .macro bitop, name, instr
+ENTRY( \name )
+UNWIND( .fnstart )
+ 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
+ ret lr
+UNWIND( .fnend )
+ENDPROC(\name )
+ .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, name, instr, store
+ENTRY( \name )
+UNWIND( .fnstart )
+ 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
+ ret lr
+UNWIND( .fnend )
+ENDPROC(\name )
+ .endm
+#endif
diff --git a/arch/arm/lib/bswapsdi2.S b/arch/arm/lib/bswapsdi2.S
new file mode 100644
index 000000000..07cda737b
--- /dev/null
+++ b/arch/arm/lib/bswapsdi2.S
@@ -0,0 +1,37 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+#if __LINUX_ARM_ARCH__ >= 6
+ENTRY(__bswapsi2)
+ rev r0, r0
+ bx lr
+ENDPROC(__bswapsi2)
+
+ENTRY(__bswapdi2)
+ rev r3, r0
+ rev r0, r1
+ mov r1, r3
+ bx lr
+ENDPROC(__bswapdi2)
+#else
+ENTRY(__bswapsi2)
+ eor r3, r0, r0, ror #16
+ mov r3, r3, lsr #8
+ bic r3, r3, #0xff00
+ eor r0, r3, r0, ror #8
+ ret lr
+ENDPROC(__bswapsi2)
+
+ENTRY(__bswapdi2)
+ mov ip, r1
+ eor r3, ip, ip, ror #16
+ eor r1, r0, r0, ror #16
+ mov r1, r1, lsr #8
+ mov r3, r3, lsr #8
+ bic r3, r3, #0xff00
+ bic r1, r1, #0xff00
+ eor r1, r1, r0, ror #8
+ eor r0, r3, ip, ror #8
+ ret lr
+ENDPROC(__bswapdi2)
+#endif
diff --git a/arch/arm/lib/call_with_stack.S b/arch/arm/lib/call_with_stack.S
new file mode 100644
index 000000000..ed1a42181
--- /dev/null
+++ b/arch/arm/lib/call_with_stack.S
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/lib/call_with_stack.S
+ *
+ * Copyright (C) 2011 ARM Ltd.
+ * Written by Will Deacon <will.deacon@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
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * void call_with_stack(void (*fn)(void *), void *arg, void *sp)
+ *
+ * Change the stack to that pointed at by sp, then invoke fn(arg) with
+ * the new stack.
+ */
+ENTRY(call_with_stack)
+ str sp, [r2, #-4]!
+ str lr, [r2, #-4]!
+
+ mov sp, r2
+ mov r2, r0
+ mov r0, r1
+
+ adr lr, BSYM(1f)
+ ret r2
+
+1: ldr lr, [sp]
+ ldr sp, [sp, #4]
+ ret lr
+ENDPROC(call_with_stack)
diff --git a/arch/arm/lib/changebit.S b/arch/arm/lib/changebit.S
new file mode 100644
index 000000000..f40278621
--- /dev/null
+++ b/arch/arm/lib/changebit.S
@@ -0,0 +1,15 @@
+/*
+ * 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
+
+bitop _change_bit, eor
diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
new file mode 100644
index 000000000..1710fd7db
--- /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 .text.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 000000000..f6b75fb64
--- /dev/null
+++ b/arch/arm/lib/clearbit.S
@@ -0,0 +1,15 @@
+/*
+ * 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
+
+bitop _clear_bit, bic
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
new file mode 100644
index 000000000..7a235b995
--- /dev/null
+++ b/arch/arm/lib/copy_from_user.S
@@ -0,0 +1,109 @@
+/*
+ * 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>
+#include <asm/unwind.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 usave reg1 reg2
+ UNWIND( .save {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 000000000..6ee2f6706
--- /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 000000000..652e4d98c
--- /dev/null
+++ b/arch/arm/lib/copy_template.S
@@ -0,0 +1,297 @@
+/*
+ * 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.
+ *
+ * usave reg1 reg2
+ *
+ * Unwind annotation macro is corresponding for 'enter' macro.
+ * It tell unwinder that preserved some provided registers on the stack
+ * and additional data by a prior 'enter' macro.
+ *
+ * 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)
+ */
+
+
+ UNWIND( .fnstart )
+ enter r4, lr
+ UNWIND( .fnend )
+
+ UNWIND( .fnstart )
+ usave r4, lr @ in first stmdb block
+
+ 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}
+ UNWIND( .fnend )
+
+ UNWIND( .fnstart )
+ usave r4, lr
+ UNWIND( .save {r5 - r8} ) @ in second stmfd block
+ 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}
+ UNWIND( .fnend ) @ end of second stmfd block
+
+ UNWIND( .fnstart )
+ usave r4, lr @ still in first stmdb block
+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
+ UNWIND( .fnend )
+
+
+ .macro forward_copy_shift pull push
+
+ UNWIND( .fnstart )
+ usave r4, lr @ still in first stmdb block
+ 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}
+ UNWIND( .fnend )
+
+ UNWIND( .fnstart )
+ usave r4, lr
+ UNWIND( .save {r5 - r9} ) @ in new second stmfd block
+ 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, lspull #\pull
+ subs r2, r2, #32
+ ldr4w r1, r8, r9, ip, lr, abort=19f
+ orr r3, r3, r4, lspush #\push
+ mov r4, r4, lspull #\pull
+ orr r4, r4, r5, lspush #\push
+ mov r5, r5, lspull #\pull
+ orr r5, r5, r6, lspush #\push
+ mov r6, r6, lspull #\pull
+ orr r6, r6, r7, lspush #\push
+ mov r7, r7, lspull #\pull
+ orr r7, r7, r8, lspush #\push
+ mov r8, r8, lspull #\pull
+ orr r8, r8, r9, lspush #\push
+ mov r9, r9, lspull #\pull
+ orr r9, r9, ip, lspush #\push
+ mov ip, ip, lspull #\pull
+ orr ip, ip, lr, lspush #\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}
+ UNWIND( .fnend ) @ end of the second stmfd block
+
+ UNWIND( .fnstart )
+ usave r4, lr @ still in first stmdb block
+14: ands ip, r2, #28
+ beq 16f
+
+15: mov r3, lr, lspull #\pull
+ ldr1w r1, lr, abort=21f
+ subs ip, ip, #4
+ orr r3, r3, lr, lspush #\push
+ str1w r0, r3, abort=21f
+ bgt 15b
+ CALGN( cmp r2, #0 )
+ CALGN( bge 11b )
+
+16: sub r1, r1, #(\push / 8)
+ b 8b
+ UNWIND( .fnend )
+
+ .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 000000000..9648b0675
--- /dev/null
+++ b/arch/arm/lib/copy_to_user.S
@@ -0,0 +1,111 @@
+/*
+ * 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>
+#include <asm/unwind.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 usave reg1 reg2
+ UNWIND( .save {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 .text.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 000000000..3ac6ef01b
--- /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 000000000..984e0f29d
--- /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
+ ret 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 000000000..d03fc71fc
--- /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 000000000..10b459096
--- /dev/null
+++ b/arch/arm/lib/csumpartialcopygeneric.S
@@ -0,0 +1,333 @@
+/*
+ * 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.
+ */
+#include <asm/assembler.h>
+
+/*
+ * 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
+ reteq 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
+ ret 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, lspush #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, lspull #8 @ C = 0
+ bics ip, len, #15
+ beq 2f
+1: load4l r5, r6, r7, r8
+ orr r4, r4, r5, lspush #24
+ mov r5, r5, lspull #8
+ orr r5, r5, r6, lspush #24
+ mov r6, r6, lspull #8
+ orr r6, r6, r7, lspush #24
+ mov r7, r7, lspull #8
+ orr r7, r7, r8, lspush #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, lspull #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, lspush #24
+ mov r5, r5, lspull #8
+ orr r5, r5, r6, lspush #24
+ stmia dst!, {r4, r5}
+ adcs sum, sum, r4
+ adcs sum, sum, r5
+ mov r4, r6, lspull #8
+ tst ip, #4
+ beq 4f
+3: load1l r5
+ orr r4, r4, r5, lspush #24
+ str r4, [dst], #4
+ adcs sum, sum, r4
+ mov r4, r5, lspull #8
+4: ands len, len, #3
+ beq .Ldone
+ mov r5, r4, get_byte_0
+ tst len, #2
+ beq .Lexit
+ adcs sum, sum, r4, lspush #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, lspull #16
+ adds sum, sum, #0
+ bics ip, len, #15
+ beq 2f
+1: load4l r5, r6, r7, r8
+ orr r4, r4, r5, lspush #16
+ mov r5, r5, lspull #16
+ orr r5, r5, r6, lspush #16
+ mov r6, r6, lspull #16
+ orr r6, r6, r7, lspush #16
+ mov r7, r7, lspull #16
+ orr r7, r7, r8, lspush #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, lspull #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, lspush #16
+ mov r5, r5, lspull #16
+ orr r5, r5, r6, lspush #16
+ stmia dst!, {r4, r5}
+ adcs sum, sum, r4
+ adcs sum, sum, r5
+ mov r4, r6, lspull #16
+ tst ip, #4
+ beq 4f
+3: load1l r5
+ orr r4, r4, r5, lspush #16
+ str r4, [dst], #4
+ adcs sum, sum, r4
+ mov r4, r5, lspull #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, lspull #24
+ adds sum, sum, #0
+ bics ip, len, #15
+ beq 2f
+1: load4l r5, r6, r7, r8
+ orr r4, r4, r5, lspush #8
+ mov r5, r5, lspull #24
+ orr r5, r5, r6, lspush #8
+ mov r6, r6, lspull #24
+ orr r6, r6, r7, lspush #8
+ mov r7, r7, lspull #24
+ orr r7, r7, r8, lspush #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, lspull #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, lspush #8
+ mov r5, r5, lspull #24
+ orr r5, r5, r6, lspush #8
+ stmia dst!, {r4, r5}
+ adcs sum, sum, r4
+ adcs sum, sum, r5
+ mov r4, r6, lspull #24
+ tst ip, #4
+ beq 4f
+3: load1l r5
+ orr r4, r4, r5, lspush #8
+ str r4, [dst], #4
+ adcs sum, sum, r4
+ mov r4, r5, lspull #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, lspush #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 000000000..1d0957e61
--- /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 .text.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-loop.S b/arch/arm/lib/delay-loop.S
new file mode 100644
index 000000000..518bf6e93
--- /dev/null
+++ b/arch/arm/lib/delay-loop.S
@@ -0,0 +1,68 @@
+/*
+ * 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/delay.h>
+ .text
+
+.LC0: .word loops_per_jiffy
+.LC1: .word UDELAY_MULT
+
+/*
+ * r0 <= 2000
+ * lpj <= 0x01ffffff (max. 3355 bogomips)
+ * HZ <= 1000
+ */
+
+ENTRY(__loop_udelay)
+ ldr r2, .LC1
+ mul r0, r2, r0
+ENTRY(__loop_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
+ reteq lr
+
+/*
+ * loops = r0 * HZ * loops_per_jiffy / 1000000
+ */
+ .align 3
+
+@ Delay routine
+ENTRY(__loop_delay)
+ subs r0, r0, #1
+#if 0
+ retls lr
+ subs r0, r0, #1
+ retls lr
+ subs r0, r0, #1
+ retls lr
+ subs r0, r0, #1
+ retls lr
+ subs r0, r0, #1
+ retls lr
+ subs r0, r0, #1
+ retls lr
+ subs r0, r0, #1
+ retls lr
+ subs r0, r0, #1
+#endif
+ bhi __loop_delay
+ ret lr
+ENDPROC(__loop_udelay)
+ENDPROC(__loop_const_udelay)
+ENDPROC(__loop_delay)
diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c
new file mode 100644
index 000000000..8044591dc
--- /dev/null
+++ b/arch/arm/lib/delay.c
@@ -0,0 +1,117 @@
+/*
+ * Delay loops based on the OpenRISC implementation.
+ *
+ * Copyright (C) 2012 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
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ */
+
+#include <linux/clocksource.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/timex.h>
+
+/*
+ * Default to the loop-based delay implementation.
+ */
+struct arm_delay_ops arm_delay_ops = {
+ .delay = __loop_delay,
+ .const_udelay = __loop_const_udelay,
+ .udelay = __loop_udelay,
+};
+
+static const struct delay_timer *delay_timer;
+static bool delay_calibrated;
+static u64 delay_res;
+
+int read_current_timer(unsigned long *timer_val)
+{
+ if (!delay_timer)
+ return -ENXIO;
+
+ *timer_val = delay_timer->read_current_timer();
+ return 0;
+}
+EXPORT_SYMBOL_GPL(read_current_timer);
+
+static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift)
+{
+ return (cyc * mult) >> shift;
+}
+
+static void __timer_delay(unsigned long cycles)
+{
+ cycles_t start = get_cycles();
+
+ while ((get_cycles() - start) < cycles)
+ cpu_relax();
+}
+
+static void __timer_const_udelay(unsigned long xloops)
+{
+ unsigned long long loops = xloops;
+ loops *= arm_delay_ops.ticks_per_jiffy;
+ __timer_delay(loops >> UDELAY_SHIFT);
+}
+
+static void __timer_udelay(unsigned long usecs)
+{
+ __timer_const_udelay(usecs * UDELAY_MULT);
+}
+
+void __init register_current_timer_delay(const struct delay_timer *timer)
+{
+ u32 new_mult, new_shift;
+ u64 res;
+
+ clocks_calc_mult_shift(&new_mult, &new_shift, timer->freq,
+ NSEC_PER_SEC, 3600);
+ res = cyc_to_ns(1ULL, new_mult, new_shift);
+
+ if (res > 1000) {
+ pr_err("Ignoring delay timer %ps, which has insufficient resolution of %lluns\n",
+ timer, res);
+ return;
+ }
+
+ if (!delay_calibrated && (!delay_res || (res < delay_res))) {
+ pr_info("Switching to timer-based delay loop, resolution %lluns\n", res);
+ delay_timer = timer;
+ lpj_fine = timer->freq / HZ;
+ delay_res = res;
+
+ /* cpufreq may scale loops_per_jiffy, so keep a private copy */
+ arm_delay_ops.ticks_per_jiffy = lpj_fine;
+ arm_delay_ops.delay = __timer_delay;
+ arm_delay_ops.const_udelay = __timer_const_udelay;
+ arm_delay_ops.udelay = __timer_udelay;
+ } else {
+ pr_info("Ignoring duplicate/late registration of read_current_timer delay\n");
+ }
+}
+
+unsigned long calibrate_delay_is_known(void)
+{
+ delay_calibrated = true;
+ return lpj_fine;
+}
+
+void calibration_delay_done(void)
+{
+ delay_calibrated = true;
+}
diff --git a/arch/arm/lib/div64.S b/arch/arm/lib/div64.S
new file mode 100644
index 000000000..a9eafe498
--- /dev/null
+++ b/arch/arm/lib/div64.S
@@ -0,0 +1,212 @@
+/*
+ * 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>
+#include <asm/assembler.h>
+#include <asm/unwind.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)
+UNWIND(.fnstart)
+
+ @ 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
+ retlo 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
+ ret 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
+ reteq 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
+ ret 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
+ ret lr
+
+ @ eq -> division by 1: obvious enough...
+9: moveq yl, xl
+ moveq yh, xh
+ moveq xh, #0
+ reteq lr
+UNWIND(.fnend)
+
+UNWIND(.fnstart)
+UNWIND(.pad #4)
+UNWIND(.save {lr})
+Ldiv0_64:
+ @ 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
+
+UNWIND(.fnend)
+ENDPROC(__do_div64)
diff --git a/arch/arm/lib/ecard.S b/arch/arm/lib/ecard.S
new file mode 100644
index 000000000..e6057fa85
--- /dev/null
+++ b/arch/arm/lib/ecard.S
@@ -0,0 +1,44 @@
+/*
+ * 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>
+
+#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 000000000..7848780e8
--- /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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret lr
+
diff --git a/arch/arm/lib/floppydma.S b/arch/arm/lib/floppydma.S
new file mode 100644
index 000000000..617150b1b
--- /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 000000000..8ecfd15c3
--- /dev/null
+++ b/arch/arm/lib/getuser.S
@@ -0,0 +1,149 @@
+/*
+ * 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
+ * r1 contains the address limit, which must be preserved
+ * 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/assembler.h>
+#include <asm/errno.h>
+#include <asm/domain.h>
+
+ENTRY(__get_user_1)
+ check_uaccess r0, 1, r1, r2, __get_user_bad
+1: TUSER(ldrb) r2, [r0]
+ mov r0, #0
+ ret lr
+ENDPROC(__get_user_1)
+
+ENTRY(__get_user_2)
+ check_uaccess r0, 2, r1, r2, __get_user_bad
+#ifdef CONFIG_CPU_USE_DOMAINS
+rb .req ip
+2: ldrbt r2, [r0], #1
+3: ldrbt rb, [r0], #0
+#else
+rb .req r0
+2: ldrb r2, [r0]
+3: ldrb rb, [r0, #1]
+#endif
+#ifndef __ARMEB__
+ orr r2, r2, rb, lsl #8
+#else
+ orr r2, rb, r2, lsl #8
+#endif
+ mov r0, #0
+ ret lr
+ENDPROC(__get_user_2)
+
+ENTRY(__get_user_4)
+ check_uaccess r0, 4, r1, r2, __get_user_bad
+4: TUSER(ldr) r2, [r0]
+ mov r0, #0
+ ret lr
+ENDPROC(__get_user_4)
+
+ENTRY(__get_user_8)
+ check_uaccess r0, 8, r1, r2, __get_user_bad
+#ifdef CONFIG_THUMB2_KERNEL
+5: TUSER(ldr) r2, [r0]
+6: TUSER(ldr) r3, [r0, #4]
+#else
+5: TUSER(ldr) r2, [r0], #4
+6: TUSER(ldr) r3, [r0]
+#endif
+ mov r0, #0
+ ret lr
+ENDPROC(__get_user_8)
+
+#ifdef __ARMEB__
+ENTRY(__get_user_32t_8)
+ check_uaccess r0, 8, r1, r2, __get_user_bad
+#ifdef CONFIG_CPU_USE_DOMAINS
+ add r0, r0, #4
+7: ldrt r2, [r0]
+#else
+7: ldr r2, [r0, #4]
+#endif
+ mov r0, #0
+ ret lr
+ENDPROC(__get_user_32t_8)
+
+ENTRY(__get_user_64t_1)
+ check_uaccess r0, 1, r1, r2, __get_user_bad8
+8: TUSER(ldrb) r3, [r0]
+ mov r0, #0
+ ret lr
+ENDPROC(__get_user_64t_1)
+
+ENTRY(__get_user_64t_2)
+ check_uaccess r0, 2, r1, r2, __get_user_bad8
+#ifdef CONFIG_CPU_USE_DOMAINS
+rb .req ip
+9: ldrbt r3, [r0], #1
+10: ldrbt rb, [r0], #0
+#else
+rb .req r0
+9: ldrb r3, [r0]
+10: ldrb rb, [r0, #1]
+#endif
+ orr r3, rb, r3, lsl #8
+ mov r0, #0
+ ret lr
+ENDPROC(__get_user_64t_2)
+
+ENTRY(__get_user_64t_4)
+ check_uaccess r0, 4, r1, r2, __get_user_bad8
+11: TUSER(ldr) r3, [r0]
+ mov r0, #0
+ ret lr
+ENDPROC(__get_user_64t_4)
+#endif
+
+__get_user_bad8:
+ mov r3, #0
+__get_user_bad:
+ mov r2, #0
+ mov r0, #-EFAULT
+ ret lr
+ENDPROC(__get_user_bad)
+ENDPROC(__get_user_bad8)
+
+.pushsection __ex_table, "a"
+ .long 1b, __get_user_bad
+ .long 2b, __get_user_bad
+ .long 3b, __get_user_bad
+ .long 4b, __get_user_bad
+ .long 5b, __get_user_bad8
+ .long 6b, __get_user_bad8
+#ifdef __ARMEB__
+ .long 7b, __get_user_bad
+ .long 8b, __get_user_bad8
+ .long 9b, __get_user_bad8
+ .long 10b, __get_user_bad8
+ .long 11b, __get_user_bad8
+#endif
+.popsection
diff --git a/arch/arm/lib/io-acorn.S b/arch/arm/lib/io-acorn.S
new file mode 100644
index 000000000..69719bad6
--- /dev/null
+++ b/arch/arm/lib/io-acorn.S
@@ -0,0 +1,32 @@
+/*
+ * 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 <linux/kern_levels.h>
+#include <asm/assembler.h>
+
+ .text
+ .align
+
+.Liosl_warning:
+ .ascii KERN_WARNING "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 000000000..c31b2f315
--- /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?
+ reteq 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 000000000..2ed86fa54
--- /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?
+ reteq 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]
+ ret 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, lspull #24
+ ldrne r3, [r0]
+ orrne ip, ip, r3, lspush #8
+ strne ip, [r1], #4
+ bne 4b
+ b 8f
+
+5: subs r2, r2, #1
+ mov ip, r3, lspull #16
+ ldrne r3, [r0]
+ orrne ip, ip, r3, lspush #16
+ strne ip, [r1], #4
+ bne 5b
+ b 7f
+
+6: subs r2, r2, #1
+ mov ip, r3, lspull #8
+ ldrne r3, [r0]
+ orrne ip, ip, r3, lspush #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]
+ ret 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 000000000..413da9914
--- /dev/null
+++ b/arch/arm/lib/io-readsw-armv3.S
@@ -0,0 +1,106 @@
+/*
+ * 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>
+
+.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
+ reteq lr
+
+ENTRY(__raw_readsw)
+ teq r2, #0 @ do we have to check for the zero len?
+ reteq 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 000000000..d9a45e969
--- /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
+ reteq 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-writesb.S b/arch/arm/lib/io-writesb.S
new file mode 100644
index 000000000..a46bbc9b1
--- /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?
+ reteq 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 000000000..4ea243598
--- /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?
+ reteq 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]
+ ret lr
+
+3: bic r1, r1, #3
+ ldr r3, [r1], #4
+ cmp ip, #2
+ blt 5f
+ bgt 6f
+
+4: mov ip, r3, lspull #16
+ ldr r3, [r1], #4
+ subs r2, r2, #1
+ orr ip, ip, r3, lspush #16
+ str ip, [r0]
+ bne 4b
+ ret lr
+
+5: mov ip, r3, lspull #8
+ ldr r3, [r1], #4
+ subs r2, r2, #1
+ orr ip, ip, r3, lspush #24
+ str ip, [r0]
+ bne 5b
+ ret lr
+
+6: mov ip, r3, lspull #24
+ ldr r3, [r1], #4
+ subs r2, r2, #1
+ orr ip, ip, r3, lspush #8
+ str ip, [r0]
+ bne 6b
+ ret 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 000000000..121789eb6
--- /dev/null
+++ b/arch/arm/lib/io-writesw-armv3.S
@@ -0,0 +1,126 @@
+/*
+ * 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>
+
+.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
+ reteq lr
+
+ENTRY(__raw_writesw)
+ teq r2, #0 @ do we have to check for the zero len?
+ reteq 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 000000000..269f90c51
--- /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
+ reteq 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]
+ ret lr
+ENDPROC(__raw_writesw)
diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S
new file mode 100644
index 000000000..947567ff6
--- /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
+ reteq lr
+ bcc Ldiv0
+ cmp r0, r1
+ bls 11f
+ tst r1, r2
+ beq 12f
+
+ ARM_DIV_BODY r0, r1, r2, r3
+
+ mov r0, r2
+ ret lr
+
+11: moveq r0, #1
+ movne r0, #0
+ ret lr
+
+12: ARM_DIV2_ORDER r1, r2
+
+ mov r0, r0, lsr r2
+ ret 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
+ retls lr
+
+ ARM_MOD_BODY r0, r1, r2, r3
+
+ ret 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
+ ret lr
+
+10: teq ip, r0 @ same sign ?
+ rsbmi r0, r0, #0
+ ret lr
+
+11: movlo r0, #0
+ moveq r0, ip, asr #31
+ orreq r0, r0, #1
+ ret lr
+
+12: ARM_DIV2_ORDER r1, r2
+
+ cmp ip, #0
+ mov r0, r3, lsr r2
+ rsbmi r0, r0, #0
+ ret 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
+ ret 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
+ ret 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
+ ret 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 000000000..922dcd88b
--- /dev/null
+++ b/arch/arm/lib/lshrdi3.S
@@ -0,0 +1,54 @@
+/* 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>
+#include <asm/assembler.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
+ ret 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 000000000..74a5bed6d
--- /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
+ ret lr
+ENDPROC(memchr)
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
new file mode 100644
index 000000000..7797e81e4
--- /dev/null
+++ b/arch/arm/lib/memcpy.S
@@ -0,0 +1,68 @@
+/*
+ * 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>
+#include <asm/unwind.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 usave reg1 reg2
+ UNWIND( .save {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 000000000..69a9d47fc
--- /dev/null
+++ b/arch/arm/lib/memmove.S
@@ -0,0 +1,227 @@
+/*
+ * 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>
+#include <asm/unwind.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)
+ UNWIND( .fnstart )
+
+ subs ip, r0, r1
+ cmphi r2, ip
+ bls memcpy
+
+ stmfd sp!, {r0, r4, lr}
+ UNWIND( .fnend )
+
+ UNWIND( .fnstart )
+ UNWIND( .save {r0, r4, lr} ) @ in first stmfd block
+ 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}
+ UNWIND( .fnend )
+
+ UNWIND( .fnstart )
+ UNWIND( .save {r0, r4, lr} )
+ UNWIND( .save {r5 - r8} ) @ in second stmfd block
+ 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}
+ UNWIND( .fnend ) @ end of second stmfd block
+
+ UNWIND( .fnstart )
+ UNWIND( .save {r0, r4, lr} ) @ still in first stmfd block
+
+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
+ UNWIND( .fnend )
+
+
+ .macro backward_copy_shift push pull
+
+ UNWIND( .fnstart )
+ UNWIND( .save {r0, r4, lr} ) @ still in first stmfd block
+ 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}
+ UNWIND( .fnend )
+
+ UNWIND( .fnstart )
+ UNWIND( .save {r0, r4, lr} )
+ UNWIND( .save {r5 - r9} ) @ in new second stmfd block
+
+ 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, lspush #\push
+ subs r2, r2, #32
+ ldmdb r1!, {r3, r4, r5, r6}
+ orr lr, lr, ip, lspull #\pull
+ mov ip, ip, lspush #\push
+ orr ip, ip, r9, lspull #\pull
+ mov r9, r9, lspush #\push
+ orr r9, r9, r8, lspull #\pull
+ mov r8, r8, lspush #\push
+ orr r8, r8, r7, lspull #\pull
+ mov r7, r7, lspush #\push
+ orr r7, r7, r6, lspull #\pull
+ mov r6, r6, lspush #\push
+ orr r6, r6, r5, lspull #\pull
+ mov r5, r5, lspush #\push
+ orr r5, r5, r4, lspull #\pull
+ mov r4, r4, lspush #\push
+ orr r4, r4, r3, lspull #\pull
+ stmdb r0!, {r4 - r9, ip, lr}
+ bge 12b
+ PLD( cmn r2, #96 )
+ PLD( bge 13b )
+
+ ldmfd sp!, {r5 - r9}
+ UNWIND( .fnend ) @ end of the second stmfd block
+
+ UNWIND( .fnstart )
+ UNWIND( .save {r0, r4, lr} ) @ still in first stmfd block
+
+14: ands ip, r2, #28
+ beq 16f
+
+15: mov lr, r3, lspush #\push
+ ldr r3, [r1, #-4]!
+ subs ip, ip, #4
+ orr lr, lr, r3, lspull #\pull
+ str lr, [r0, #-4]!
+ bgt 15b
+ CALGN( cmp r2, #0 )
+ CALGN( bge 11b )
+
+16: add r1, r1, #(\pull / 8)
+ b 8b
+ UNWIND( .fnend )
+
+ .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 000000000..a4ee97b5a
--- /dev/null
+++ b/arch/arm/lib/memset.S
@@ -0,0 +1,135 @@
+/*
+ * 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>
+#include <asm/unwind.h>
+
+ .text
+ .align 5
+
+ENTRY(memset)
+UNWIND( .fnstart )
+ ands r3, r0, #3 @ 1 unaligned?
+ mov ip, r0 @ preserve r0 as return value
+ bne 6f @ 1
+/*
+ * we know that the pointer in ip is aligned to a word boundary.
+ */
+1: 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 2 extra registers for this loop - use r8 and the LR
+ */
+ stmfd sp!, {r8, lr}
+UNWIND( .fnend )
+UNWIND( .fnstart )
+UNWIND( .save {r8, lr} )
+ mov r8, r1
+ mov lr, r1
+
+2: subs r2, r2, #64
+ stmgeia ip!, {r1, r3, r8, lr} @ 64 bytes at a time.
+ stmgeia ip!, {r1, r3, r8, lr}
+ stmgeia ip!, {r1, r3, r8, lr}
+ stmgeia ip!, {r1, r3, r8, lr}
+ bgt 2b
+ ldmeqfd sp!, {r8, pc} @ Now <64 bytes to go.
+/*
+ * No need to correct the count; we're only testing bits from now on
+ */
+ tst r2, #32
+ stmneia ip!, {r1, r3, r8, lr}
+ stmneia ip!, {r1, r3, r8, lr}
+ tst r2, #16
+ stmneia ip!, {r1, r3, r8, lr}
+ ldmfd sp!, {r8, lr}
+UNWIND( .fnend )
+
+#else
+
+/*
+ * This version aligns the destination pointer in order to write
+ * whole cache lines at once.
+ */
+
+ stmfd sp!, {r4-r8, lr}
+UNWIND( .fnend )
+UNWIND( .fnstart )
+UNWIND( .save {r4-r8, lr} )
+ mov r4, r1
+ mov r5, r1
+ mov r6, r1
+ mov r7, r1
+ mov r8, r1
+ mov lr, r1
+
+ cmp r2, #96
+ tstgt ip, #31
+ ble 3f
+
+ and r8, ip, #31
+ rsb r8, r8, #32
+ sub r2, r2, r8
+ movs r8, r8, lsl #(32 - 4)
+ stmcsia ip!, {r4, r5, r6, r7}
+ stmmiia ip!, {r4, r5}
+ tst r8, #(1 << 30)
+ mov r8, r1
+ strne r1, [ip], #4
+
+3: subs r2, r2, #64
+ stmgeia ip!, {r1, r3-r8, lr}
+ stmgeia ip!, {r1, r3-r8, lr}
+ bgt 3b
+ ldmeqfd sp!, {r4-r8, pc}
+
+ tst r2, #32
+ stmneia ip!, {r1, r3-r8, lr}
+ tst r2, #16
+ stmneia ip!, {r4-r7}
+ ldmfd sp!, {r4-r8, lr}
+UNWIND( .fnend )
+
+#endif
+
+UNWIND( .fnstart )
+4: tst r2, #8
+ stmneia ip!, {r1, r3}
+ tst r2, #4
+ strne r1, [ip], #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, [ip], #1
+ strneb r1, [ip], #1
+ tst r2, #1
+ strneb r1, [ip], #1
+ ret lr
+
+6: subs r2, r2, #4 @ 1 do we have enough
+ blt 5b @ 1 bytes to align with?
+ cmp r3, #2 @ 1
+ strltb r1, [ip], #1 @ 1
+ strleb r1, [ip], #1 @ 1
+ strb r1, [ip], #1 @ 1
+ add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
+ b 1b
+UNWIND( .fnend )
+ENDPROC(memset)
diff --git a/arch/arm/lib/memzero.S b/arch/arm/lib/memzero.S
new file mode 100644
index 000000000..0eded952e
--- /dev/null
+++ b/arch/arm/lib/memzero.S
@@ -0,0 +1,137 @@
+/*
+ * 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>
+#include <asm/unwind.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.
+ */
+UNWIND( .fnstart )
+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
+UNWIND( .fnend )
+UNWIND( .fnstart )
+UNWIND( .save {lr} )
+ 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
+UNWIND( .fnend )
+
+#else
+
+/*
+ * This version aligns the destination pointer in order to write
+ * whole cache lines at once.
+ */
+
+ stmfd sp!, {r4-r7, lr}
+UNWIND( .fnend )
+UNWIND( .fnstart )
+UNWIND( .save {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}
+UNWIND( .fnend )
+
+#endif
+
+UNWIND( .fnstart )
+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
+ ret lr @ 1
+UNWIND( .fnend )
+ENDPROC(__memzero)
diff --git a/arch/arm/lib/muldi3.S b/arch/arm/lib/muldi3.S
new file mode 100644
index 000000000..204305956
--- /dev/null
+++ b/arch/arm/lib/muldi3.S
@@ -0,0 +1,48 @@
+/*
+ * 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>
+#include <asm/assembler.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
+ ret 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 000000000..38d660d37
--- /dev/null
+++ b/arch/arm/lib/putuser.S
@@ -0,0 +1,98 @@
+/*
+ * 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
+ * r1 contains the address limit, which must be preserved
+ * 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/assembler.h>
+#include <asm/errno.h>
+#include <asm/domain.h>
+
+ENTRY(__put_user_1)
+ check_uaccess r0, 1, r1, ip, __put_user_bad
+1: TUSER(strb) r2, [r0]
+ mov r0, #0
+ ret lr
+ENDPROC(__put_user_1)
+
+ENTRY(__put_user_2)
+ check_uaccess r0, 2, r1, ip, __put_user_bad
+ 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
+ ret lr
+ENDPROC(__put_user_2)
+
+ENTRY(__put_user_4)
+ check_uaccess r0, 4, r1, ip, __put_user_bad
+4: TUSER(str) r2, [r0]
+ mov r0, #0
+ ret lr
+ENDPROC(__put_user_4)
+
+ENTRY(__put_user_8)
+ check_uaccess r0, 8, r1, ip, __put_user_bad
+#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
+ ret lr
+ENDPROC(__put_user_8)
+
+__put_user_bad:
+ mov r0, #-EFAULT
+ ret 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 000000000..618fedae4
--- /dev/null
+++ b/arch/arm/lib/setbit.S
@@ -0,0 +1,15 @@
+/*
+ * 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
+
+bitop _set_bit, orr
diff --git a/arch/arm/lib/strchr.S b/arch/arm/lib/strchr.S
new file mode 100644
index 000000000..013d64c71
--- /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
+ ret lr
+ENDPROC(strchr)
diff --git a/arch/arm/lib/strrchr.S b/arch/arm/lib/strrchr.S
new file mode 100644
index 000000000..3cec1c748
--- /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
+ ret lr
+ENDPROC(strrchr)
diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S
new file mode 100644
index 000000000..4becdc3a5
--- /dev/null
+++ b/arch/arm/lib/testchangebit.S
@@ -0,0 +1,15 @@
+/*
+ * 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
+
+testop _test_and_change_bit, eor, str
diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S
new file mode 100644
index 000000000..918841dcc
--- /dev/null
+++ b/arch/arm/lib/testclearbit.S
@@ -0,0 +1,15 @@
+/*
+ * 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
+
+testop _test_and_clear_bit, bicne, strne
diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S
new file mode 100644
index 000000000..8d1b2fe9e
--- /dev/null
+++ b/arch/arm/lib/testsetbit.S
@@ -0,0 +1,15 @@
+/*
+ * 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
+
+testop _test_and_set_bit, orreq, streq
diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c
new file mode 100644
index 000000000..3e58d7100
--- /dev/null
+++ b/arch/arm/lib/uaccess_with_memcpy.c
@@ -0,0 +1,270 @@
+/*
+ * 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 <linux/highmem.h>
+#include <linux/hugetlb.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)))
+ return 0;
+
+ /*
+ * A pmd can be bad if it refers to a HugeTLB or THP page.
+ *
+ * Both THP and HugeTLB pages have the same pmd layout
+ * and should not be manipulated by the pte functions.
+ *
+ * Lock the page table for the destination and check
+ * to see that it's still huge and whether or not we will
+ * need to fault on write, or if we have a splitting THP.
+ */
+ if (unlikely(pmd_thp_or_huge(*pmd))) {
+ ptl = &current->mm->page_table_lock;
+ spin_lock(ptl);
+ if (unlikely(!pmd_thp_or_huge(*pmd)
+ || pmd_hugewillfault(*pmd)
+ || pmd_trans_splitting(*pmd))) {
+ spin_unlock(ptl);
+ return 0;
+ }
+
+ *ptep = NULL;
+ *ptlp = ptl;
+ return 1;
+ }
+
+ if (unlikely(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;
+
+ if (pte)
+ pte_unmap_unlock(pte, ptl);
+ else
+ spin_unlock(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;
+
+ if (pte)
+ pte_unmap_unlock(pte, ptl);
+ else
+ spin_unlock(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 000000000..ad4a63091
--- /dev/null
+++ b/arch/arm/lib/ucmpdi2.S
@@ -0,0 +1,53 @@
+/*
+ * 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>
+#include <asm/assembler.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
+ ret lr
+
+ENDPROC(__ucmpdi2)
+
+#ifdef CONFIG_AEABI
+
+ENTRY(__aeabi_ulcmp)
+
+ cmp xh, yh
+ cmpeq xl, yl
+ movlo r0, #-1
+ moveq r0, #0
+ movhi r0, #1
+ ret lr
+
+ENDPROC(__aeabi_ulcmp)
+
+#endif
+
diff --git a/arch/arm/lib/xor-neon.c b/arch/arm/lib/xor-neon.c
new file mode 100644
index 000000000..2c40aeab3
--- /dev/null
+++ b/arch/arm/lib/xor-neon.c
@@ -0,0 +1,46 @@
+/*
+ * linux/arch/arm/lib/xor-neon.c
+ *
+ * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@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 <linux/raid/xor.h>
+#include <linux/module.h>
+
+MODULE_LICENSE("GPL");
+
+#ifndef __ARM_NEON__
+#error You should compile this file with '-mfloat-abi=softfp -mfpu=neon'
+#endif
+
+/*
+ * Pull in the reference implementations while instructing GCC (through
+ * -ftree-vectorize) to attempt to exploit implicit parallelism and emit
+ * NEON instructions.
+ */
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+#pragma GCC optimize "tree-vectorize"
+#else
+/*
+ * While older versions of GCC do not generate incorrect code, they fail to
+ * recognize the parallel nature of these functions, and emit plain ARM code,
+ * which is known to be slower than the optimized ARM code in asm-arm/xor.h.
+ */
+#warning This code requires at least version 4.6 of GCC
+#endif
+
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include <asm-generic/xor.h>
+
+struct xor_block_template const xor_block_neon_inner = {
+ .name = "__inner_neon__",
+ .do_2 = xor_8regs_2,
+ .do_3 = xor_8regs_3,
+ .do_4 = xor_8regs_4,
+ .do_5 = xor_8regs_5,
+};
+EXPORT_SYMBOL(xor_block_neon_inner);
diff --git a/arch/arm/mach-alpine/Kconfig b/arch/arm/mach-alpine/Kconfig
new file mode 100644
index 000000000..2c44b9305
--- /dev/null
+++ b/arch/arm/mach-alpine/Kconfig
@@ -0,0 +1,12 @@
+config ARCH_ALPINE
+ bool "Annapurna Labs Alpine platform" if ARCH_MULTI_V7
+ select ARM_AMBA
+ select ARM_GIC
+ select GENERIC_IRQ_CHIP
+ select HAVE_ARM_ARCH_TIMER
+ select HAVE_SMP
+ select MFD_SYSCON
+ select PCI
+ select PCI_HOST_GENERIC
+ help
+ This enables support for the Annapurna Labs Alpine V1 boards.
diff --git a/arch/arm/mach-alpine/Makefile b/arch/arm/mach-alpine/Makefile
new file mode 100644
index 000000000..b6674890b
--- /dev/null
+++ b/arch/arm/mach-alpine/Makefile
@@ -0,0 +1,2 @@
+obj-y += alpine_machine.o
+obj-$(CONFIG_SMP) += platsmp.o alpine_cpu_pm.o
diff --git a/arch/arm/mach-alpine/alpine_cpu_pm.c b/arch/arm/mach-alpine/alpine_cpu_pm.c
new file mode 100644
index 000000000..121c77c4b
--- /dev/null
+++ b/arch/arm/mach-alpine/alpine_cpu_pm.c
@@ -0,0 +1,70 @@
+/*
+ * Low-level power-management support for Alpine platform.
+ *
+ * Copyright (C) 2015 Annapurna Labs 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.
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+#include "alpine_cpu_pm.h"
+#include "alpine_cpu_resume.h"
+
+/* NB registers */
+#define AL_SYSFAB_POWER_CONTROL(cpu) (0x2000 + (cpu)*0x100 + 0x20)
+
+static struct regmap *al_sysfabric;
+static struct al_cpu_resume_regs __iomem *al_cpu_resume_regs;
+static int wakeup_supported;
+
+int alpine_cpu_wakeup(unsigned int phys_cpu, uint32_t phys_resume_addr)
+{
+ if (!wakeup_supported)
+ return -ENOSYS;
+
+ /*
+ * Set CPU resume address -
+ * secure firmware running on boot will jump to this address
+ * after setting proper CPU mode, and initialiing e.g. secure
+ * regs (the same mode all CPUs are booted to - usually HYP)
+ */
+ writel(phys_resume_addr,
+ &al_cpu_resume_regs->per_cpu[phys_cpu].resume_addr);
+
+ /* Power-up the CPU */
+ regmap_write(al_sysfabric, AL_SYSFAB_POWER_CONTROL(phys_cpu), 0);
+
+ return 0;
+}
+
+void __init alpine_cpu_pm_init(void)
+{
+ struct device_node *np;
+ uint32_t watermark;
+
+ al_sysfabric = syscon_regmap_lookup_by_compatible("al,alpine-sysfabric-service");
+
+ np = of_find_compatible_node(NULL, NULL, "al,alpine-cpu-resume");
+ al_cpu_resume_regs = of_iomap(np, 0);
+
+ wakeup_supported = !IS_ERR(al_sysfabric) && al_cpu_resume_regs;
+
+ if (wakeup_supported) {
+ watermark = readl(&al_cpu_resume_regs->watermark);
+ wakeup_supported = (watermark & AL_CPU_RESUME_MAGIC_NUM_MASK)
+ == AL_CPU_RESUME_MAGIC_NUM;
+ }
+}
diff --git a/arch/arm/mach-alpine/alpine_cpu_pm.h b/arch/arm/mach-alpine/alpine_cpu_pm.h
new file mode 100644
index 000000000..5179e697c
--- /dev/null
+++ b/arch/arm/mach-alpine/alpine_cpu_pm.h
@@ -0,0 +1,26 @@
+/*
+ * Low-level power-management support for Alpine platform.
+ *
+ * Copyright (C) 2015 Annapurna Labs 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.
+ */
+
+#ifndef __ALPINE_CPU_PM_H__
+#define __ALPINE_CPU_PM_H__
+
+/* Alpine CPU Power Management Services Initialization */
+void alpine_cpu_pm_init(void);
+
+/* Wake-up a CPU */
+int alpine_cpu_wakeup(unsigned int phys_cpu, uint32_t phys_resume_addr);
+
+#endif /* __ALPINE_CPU_PM_H__ */
diff --git a/arch/arm/mach-alpine/alpine_cpu_resume.h b/arch/arm/mach-alpine/alpine_cpu_resume.h
new file mode 100644
index 000000000..c80150c0d
--- /dev/null
+++ b/arch/arm/mach-alpine/alpine_cpu_resume.h
@@ -0,0 +1,38 @@
+/*
+ * Annapurna labs cpu-resume register structure.
+ *
+ * Copyright (C) 2015 Annapurna Labs 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.
+ */
+
+#ifndef ALPINE_CPU_RESUME_H_
+#define ALPINE_CPU_RESUME_H_
+
+/* Per-cpu regs */
+struct al_cpu_resume_regs_per_cpu {
+ uint32_t flags;
+ uint32_t resume_addr;
+};
+
+/* general regs */
+struct al_cpu_resume_regs {
+ /* Watermark for validating the CPU resume struct */
+ uint32_t watermark;
+ uint32_t flags;
+ struct al_cpu_resume_regs_per_cpu per_cpu[];
+};
+
+/* The expected magic number for validating the resume addresses */
+#define AL_CPU_RESUME_MAGIC_NUM 0xf0e1d200
+#define AL_CPU_RESUME_MAGIC_NUM_MASK 0xffffff00
+
+#endif /* ALPINE_CPU_RESUME_H_ */
diff --git a/arch/arm/mach-alpine/alpine_machine.c b/arch/arm/mach-alpine/alpine_machine.c
new file mode 100644
index 000000000..b8e2145e9
--- /dev/null
+++ b/arch/arm/mach-alpine/alpine_machine.c
@@ -0,0 +1,28 @@
+/*
+ * Machine declaration for Alpine platforms.
+ *
+ * Copyright (C) 2015 Annapurna Labs 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.
+ */
+
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+
+static const char * const al_match[] __initconst = {
+ "al,alpine",
+ NULL,
+};
+
+DT_MACHINE_START(AL_DT, "Annapurna Labs Alpine")
+ .dt_compat = al_match,
+MACHINE_END
diff --git a/arch/arm/mach-alpine/platsmp.c b/arch/arm/mach-alpine/platsmp.c
new file mode 100644
index 000000000..f78429f48
--- /dev/null
+++ b/arch/arm/mach-alpine/platsmp.c
@@ -0,0 +1,49 @@
+/*
+ * SMP operations for Alpine platform.
+ *
+ * Copyright (C) 2015 Annapurna Labs 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.
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include <asm/smp_plat.h>
+
+#include "alpine_cpu_pm.h"
+
+static int alpine_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ phys_addr_t addr;
+
+ addr = virt_to_phys(secondary_startup);
+
+ if (addr > (phys_addr_t)(uint32_t)(-1)) {
+ pr_err("FAIL: resume address over 32bit (%pa)", &addr);
+ return -EINVAL;
+ }
+
+ return alpine_cpu_wakeup(cpu_logical_map(cpu), (uint32_t)addr);
+}
+
+static void __init alpine_smp_prepare_cpus(unsigned int max_cpus)
+{
+ alpine_cpu_pm_init();
+}
+
+static struct smp_operations alpine_smp_ops __initdata = {
+ .smp_prepare_cpus = alpine_smp_prepare_cpus,
+ .smp_boot_secondary = alpine_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(alpine_smp, "al,alpine-smp", &alpine_smp_ops);
diff --git a/arch/arm/mach-asm9260/Kconfig b/arch/arm/mach-asm9260/Kconfig
new file mode 100644
index 000000000..52241207a
--- /dev/null
+++ b/arch/arm/mach-asm9260/Kconfig
@@ -0,0 +1,8 @@
+config MACH_ASM9260
+ bool "Alphascale ASM9260"
+ depends on ARCH_MULTI_V5
+ select CPU_ARM926T
+ select ASM9260_TIMER
+ select GENERIC_CLOCKEVENTS
+ help
+ Support for Alphascale ASM9260 based platform.
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
new file mode 100644
index 000000000..fd95f3494
--- /dev/null
+++ b/arch/arm/mach-at91/Kconfig
@@ -0,0 +1,107 @@
+menuconfig ARCH_AT91
+ bool "Atmel SoCs"
+ depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V7
+ select ARCH_REQUIRE_GPIOLIB
+ select COMMON_CLK_AT91
+ select PINCTRL
+ select PINCTRL_AT91
+ select SOC_BUS
+
+if ARCH_AT91
+config SOC_SAMA5D3
+ bool "SAMA5D3 family" if ARCH_MULTI_V7
+ select SOC_SAMA5
+ select HAVE_FB_ATMEL
+ select HAVE_AT91_UTMI
+ select HAVE_AT91_SMD
+ select HAVE_AT91_USB_CLK
+ help
+ Select this if you are using one of Atmel's SAMA5D3 family SoC.
+ This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35, SAMA5D36.
+
+config SOC_SAMA5D4
+ bool "SAMA5D4 family" if ARCH_MULTI_V7
+ select SOC_SAMA5
+ select CACHE_L2X0
+ select HAVE_FB_ATMEL
+ select HAVE_AT91_UTMI
+ select HAVE_AT91_SMD
+ select HAVE_AT91_USB_CLK
+ select HAVE_AT91_H32MX
+ help
+ Select this if you are using one of Atmel's SAMA5D4 family SoC.
+
+config SOC_AT91RM9200
+ bool "AT91RM9200" if ARCH_MULTI_V4T
+ select ATMEL_AIC_IRQ
+ select ATMEL_ST
+ select CPU_ARM920T
+ select HAVE_AT91_USB_CLK
+ select MIGHT_HAVE_PCI
+ select SOC_SAM_V4_V5
+ select SRAM if PM
+ help
+ Select this if you are using Atmel's AT91RM9200 SoC.
+
+config SOC_AT91SAM9
+ bool "AT91SAM9" if ARCH_MULTI_V5
+ select ATMEL_AIC_IRQ
+ select ATMEL_SDRAMC
+ select CPU_ARM926T
+ select HAVE_AT91_SMD
+ select HAVE_AT91_USB_CLK
+ select HAVE_AT91_UTMI
+ select HAVE_FB_ATMEL
+ select MEMORY
+ select SOC_SAM_V4_V5
+ select SRAM if PM
+ help
+ Select this if you are using one of those Atmel SoC:
+ AT91SAM9260
+ AT91SAM9261
+ AT91SAM9263
+ AT91SAM9G15
+ AT91SAM9G20
+ AT91SAM9G25
+ AT91SAM9G35
+ AT91SAM9G45
+ AT91SAM9G46
+ AT91SAM9M10
+ AT91SAM9M11
+ AT91SAM9N12
+ AT91SAM9RL
+ AT91SAM9X25
+ AT91SAM9X35
+ AT91SAM9XE
+
+config HAVE_AT91_UTMI
+ bool
+
+config HAVE_AT91_USB_CLK
+ bool
+
+config COMMON_CLK_AT91
+ bool
+ select COMMON_CLK
+
+config HAVE_AT91_SMD
+ bool
+
+config HAVE_AT91_H32MX
+ bool
+
+config SOC_SAM_V4_V5
+ bool
+
+config SOC_SAM_V7
+ bool
+
+config SOC_SAMA5
+ bool
+ select ATMEL_AIC5_IRQ
+ select ATMEL_SDRAMC
+ select MEMORY
+ select SOC_SAM_V7
+ select SRAM if PM
+
+endif
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
new file mode 100644
index 000000000..4fa8b4541
--- /dev/null
+++ b/arch/arm/mach-at91/Makefile
@@ -0,0 +1,25 @@
+#
+# Makefile for the linux kernel.
+#
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
+asflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
+
+obj-y := soc.o
+
+obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o
+
+# CPU-specific support
+obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o
+obj-$(CONFIG_SOC_AT91SAM9) += at91sam9.o
+obj-$(CONFIG_SOC_SAMA5) += sama5.o
+
+# Power Management
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM) += pm_suspend.o
+
+ifeq ($(CONFIG_CPU_V7),y)
+AFLAGS_pm_suspend.o := -march=armv7-a
+endif
+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 000000000..29ed0fa37
--- /dev/null
+++ b/arch/arm/mach-at91/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 += 0x20008000
+params_phys-y := 0x20000100
+initrd_phys-y := 0x20410000
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
new file mode 100644
index 000000000..eaf58f88e
--- /dev/null
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -0,0 +1,49 @@
+/*
+ * Setup code for AT91RM9200
+ *
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
+ * 2012 Joachim Eastwood <manabian@gmail.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/system_misc.h>
+
+#include "generic.h"
+#include "soc.h"
+
+static const struct at91_soc rm9200_socs[] = {
+ AT91_SOC(AT91RM9200_CIDR_MATCH, 0, "at91rm9200 BGA", "at91rm9200"),
+ { /* sentinel */ },
+};
+
+static void __init at91rm9200_dt_device_init(void)
+{
+ struct soc_device *soc;
+ struct device *soc_dev = NULL;
+
+ soc = at91_soc_init(rm9200_socs);
+ if (soc != NULL)
+ soc_dev = soc_device_to_device(soc);
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev);
+
+ arm_pm_idle = at91rm9200_idle;
+ at91rm9200_pm_init();
+}
+
+static const char *at91rm9200_dt_board_compat[] __initconst = {
+ "atmel,at91rm9200",
+ NULL
+};
+
+DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200")
+ .init_machine = at91rm9200_dt_device_init,
+ .dt_compat = at91rm9200_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-at91/at91sam9.c b/arch/arm/mach-at91/at91sam9.c
new file mode 100644
index 000000000..e47a2093a
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9.c
@@ -0,0 +1,119 @@
+/*
+ * Setup code for AT91SAM9
+ *
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/of.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/system_misc.h>
+
+#include "generic.h"
+#include "soc.h"
+
+static const struct at91_soc at91sam9_socs[] = {
+ AT91_SOC(AT91SAM9260_CIDR_MATCH, 0, "at91sam9260", NULL),
+ AT91_SOC(AT91SAM9261_CIDR_MATCH, 0, "at91sam9261", NULL),
+ AT91_SOC(AT91SAM9263_CIDR_MATCH, 0, "at91sam9263", NULL),
+ AT91_SOC(AT91SAM9G20_CIDR_MATCH, 0, "at91sam9g20", NULL),
+ AT91_SOC(AT91SAM9RL64_CIDR_MATCH, 0, "at91sam9rl64", NULL),
+ AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9M11_EXID_MATCH,
+ "at91sam9m11", "at91sam9g45"),
+ AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9M10_EXID_MATCH,
+ "at91sam9m10", "at91sam9g45"),
+ AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9G46_EXID_MATCH,
+ "at91sam9g46", "at91sam9g45"),
+ AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9G45_EXID_MATCH,
+ "at91sam9g45", "at91sam9g45"),
+ AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G15_EXID_MATCH,
+ "at91sam9g15", "at91sam9x5"),
+ AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G35_EXID_MATCH,
+ "at91sam9g35", "at91sam9x5"),
+ AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9X35_EXID_MATCH,
+ "at91sam9x35", "at91sam9x5"),
+ AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G25_EXID_MATCH,
+ "at91sam9g25", "at91sam9x5"),
+ AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9X25_EXID_MATCH,
+ "at91sam9x25", "at91sam9x5"),
+ AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9CN12_EXID_MATCH,
+ "at91sam9cn12", "at91sam9n12"),
+ AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9N12_EXID_MATCH,
+ "at91sam9n12", "at91sam9n12"),
+ AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9CN11_EXID_MATCH,
+ "at91sam9cn11", "at91sam9n12"),
+ AT91_SOC(AT91SAM9XE128_CIDR_MATCH, 0, "at91sam9xe128", "at91sam9xe128"),
+ AT91_SOC(AT91SAM9XE256_CIDR_MATCH, 0, "at91sam9xe256", "at91sam9xe256"),
+ AT91_SOC(AT91SAM9XE512_CIDR_MATCH, 0, "at91sam9xe512", "at91sam9xe512"),
+ { /* sentinel */ },
+};
+
+static void __init at91sam9_common_init(void)
+{
+ struct soc_device *soc;
+ struct device *soc_dev = NULL;
+
+ soc = at91_soc_init(at91sam9_socs);
+ if (soc != NULL)
+ soc_dev = soc_device_to_device(soc);
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev);
+
+ arm_pm_idle = at91sam9_idle;
+}
+
+static void __init at91sam9_dt_device_init(void)
+{
+ at91sam9_common_init();
+ at91sam9260_pm_init();
+}
+
+static const char *at91_dt_board_compat[] __initconst = {
+ "atmel,at91sam9",
+ NULL
+};
+
+DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM9")
+ /* Maintainer: Atmel */
+ .init_machine = at91sam9_dt_device_init,
+ .dt_compat = at91_dt_board_compat,
+MACHINE_END
+
+static void __init at91sam9g45_dt_device_init(void)
+{
+ at91sam9_common_init();
+ at91sam9g45_pm_init();
+}
+
+static const char *at91sam9g45_board_compat[] __initconst = {
+ "atmel,at91sam9g45",
+ NULL
+};
+
+DT_MACHINE_START(at91sam9g45_dt, "Atmel AT91SAM9G45")
+ /* Maintainer: Atmel */
+ .init_machine = at91sam9g45_dt_device_init,
+ .dt_compat = at91sam9g45_board_compat,
+MACHINE_END
+
+static void __init at91sam9x5_dt_device_init(void)
+{
+ at91sam9_common_init();
+ at91sam9x5_pm_init();
+}
+
+static const char *at91sam9x5_board_compat[] __initconst = {
+ "atmel,at91sam9x5",
+ "atmel,at91sam9n12",
+ NULL
+};
+
+DT_MACHINE_START(at91sam9x5_dt, "Atmel AT91SAM9")
+ /* Maintainer: Atmel */
+ .init_machine = at91sam9x5_dt_device_init,
+ .dt_compat = at91sam9x5_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
new file mode 100644
index 000000000..b0fa7dc72
--- /dev/null
+++ b/arch/arm/mach-at91/generic.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#ifndef _AT91_GENERIC_H
+#define _AT91_GENERIC_H
+
+#include <linux/of.h>
+#include <linux/reboot.h>
+
+ /* Map io */
+extern void __init at91_map_io(void);
+extern void __init at91_alt_map_io(void);
+
+/* idle */
+extern void at91rm9200_idle(void);
+extern void at91sam9_idle(void);
+
+#ifdef CONFIG_PM
+extern void __init at91rm9200_pm_init(void);
+extern void __init at91sam9260_pm_init(void);
+extern void __init at91sam9g45_pm_init(void);
+extern void __init at91sam9x5_pm_init(void);
+#else
+static inline void __init at91rm9200_pm_init(void) { }
+static inline void __init at91sam9260_pm_init(void) { }
+static inline void __init at91sam9g45_pm_init(void) { }
+static inline void __init at91sam9x5_pm_init(void) { }
+#endif
+
+#endif /* _AT91_GENERIC_H */
diff --git a/arch/arm/mach-at91/include/mach/at91_ramc.h b/arch/arm/mach-at91/include/mach/at91_ramc.h
new file mode 100644
index 000000000..493bc486e
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_ramc.h
@@ -0,0 +1,28 @@
+/*
+ * Header file for the Atmel RAM Controller
+ *
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ */
+
+#ifndef __AT91_RAMC_H__
+#define __AT91_RAMC_H__
+
+#ifndef __ASSEMBLY__
+extern void __iomem *at91_ramc_base[];
+
+#define at91_ramc_read(id, field) \
+ __raw_readl(at91_ramc_base[id] + field)
+
+#define at91_ramc_write(id, field, value) \
+ __raw_writel(value, at91_ramc_base[id] + field)
+#else
+.extern at91_ramc_base
+#endif
+
+#include <soc/at91/at91rm9200_sdramc.h>
+#include <soc/at91/at91sam9_ddrsdr.h>
+#include <soc/at91/at91sam9_sdramc.h>
+
+#endif /* __AT91_RAMC_H__ */
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 000000000..aeaadfb45
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91rm9200_mc.h
@@ -0,0 +1,116 @@
+/*
+ * 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 0x00 /* MC Remap Control Register */
+#define AT91_MC_RCB (1 << 0) /* Remap Command Bit */
+
+#define AT91_MC_ASR 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 0x08 /* MC Abort Address Status Register */
+
+#define AT91_MC_MPR 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 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) (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)
+
+/* Burst Flash Controller register */
+#define AT91_BFC_MR 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/at91sam9_smc.h b/arch/arm/mach-at91/include/mach/at91sam9_smc.h
new file mode 100644
index 000000000..ff54a0ce9
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9_smc.h
@@ -0,0 +1,98 @@
+/*
+ * 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
+
+#ifndef __ASSEMBLY__
+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 sam9_smc_configure(int id, int cs, struct sam9_smc_config *config);
+extern void sam9_smc_read(int id, int cs, struct sam9_smc_config *config);
+extern void sam9_smc_read_mode(int id, int cs, struct sam9_smc_config *config);
+extern void sam9_smc_write_mode(int id, int cs, struct sam9_smc_config *config);
+#endif
+
+#define AT91_SMC_SETUP 0x00 /* 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 0x04 /* 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 0x08 /* 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 0x0c /* 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)
+
+#endif
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
new file mode 100644
index 000000000..5062699cb
--- /dev/null
+++ b/arch/arm/mach-at91/pm.c
@@ -0,0 +1,447 @@
+/*
+ * 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/gpio.h>
+#include <linux/suspend.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/genalloc.h>
+#include <linux/interrupt.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk/at91_pmc.h>
+
+#include <asm/irq.h>
+#include <linux/atomic.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+#include <asm/fncpy.h>
+#include <asm/cacheflush.h>
+
+#include "generic.h"
+#include "pm.h"
+
+/*
+ * FIXME: this is needed to communicate between the pinctrl driver and
+ * the PM implementation in the machine. Possibly part of the PM
+ * implementation should be moved down into the pinctrl driver and get
+ * called as part of the generic suspend/resume path.
+ */
+extern void at91_pinctrl_gpio_suspend(void);
+extern void at91_pinctrl_gpio_resume(void);
+
+static struct {
+ unsigned long uhp_udp_mask;
+ int memctrl;
+} at91_pm_data;
+
+void __iomem *at91_ramc_base[2];
+
+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_pmc_read(AT91_PMC_SCSR);
+
+ /* USB must not be using PLLB */
+ if ((scsr & at91_pm_data.uhp_udp_mask) != 0) {
+ pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
+ return 0;
+ }
+
+ /* 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_pmc_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;
+ }
+ }
+
+ 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 (*at91_suspend_sram_fn)(void __iomem *pmc, void __iomem *ramc0,
+ void __iomem *ramc1, int memctrl);
+
+extern void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *ramc0,
+ void __iomem *ramc1, int memctrl);
+extern u32 at91_pm_suspend_in_sram_sz;
+
+static void at91_pm_suspend(suspend_state_t state)
+{
+ unsigned int pm_data = at91_pm_data.memctrl;
+
+ pm_data |= (state == PM_SUSPEND_MEM) ?
+ AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
+
+ flush_cache_all();
+ outer_disable();
+
+ at91_suspend_sram_fn(at91_pmc_base, at91_ramc_base[0],
+ at91_ramc_base[1], pm_data);
+
+ outer_resume();
+}
+
+static int at91_pm_enter(suspend_state_t state)
+{
+ at91_pinctrl_gpio_suspend();
+
+ switch (state) {
+ /*
+ * Suspend-to-RAM is like STANDBY plus slow clock mode, so
+ * drivers must suspend more deeply, the master clock switches
+ * to the clk32k and turns off the main oscillator
+ */
+ case PM_SUSPEND_MEM:
+ /*
+ * Ensure that clocks are in a valid state.
+ */
+ if (!at91_pm_verify_clocks())
+ goto error;
+
+ at91_pm_suspend(state);
+
+ break;
+
+ /*
+ * 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:
+ at91_pm_suspend(state);
+ break;
+
+ case PM_SUSPEND_ON:
+ cpu_do_idle();
+ break;
+
+ default:
+ pr_debug("AT91: PM - bogus suspend state %d\n", state);
+ goto error;
+ }
+
+error:
+ target_state = PM_SUSPEND_ON;
+
+ at91_pinctrl_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 struct platform_device at91_cpuidle_device = {
+ .name = "cpuidle-at91",
+};
+
+static void at91_pm_set_standby(void (*at91_standby)(void))
+{
+ if (at91_standby)
+ at91_cpuidle_device.dev.platform_data = at91_standby;
+}
+
+/*
+ * 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 void at91rm9200_standby(void)
+{
+ u32 lpr = at91_ramc_read(0, AT91RM9200_SDRAMC_LPR);
+
+ asm volatile(
+ "b 1f\n\t"
+ ".align 5\n\t"
+ "1: mcr p15, 0, %0, c7, c10, 4\n\t"
+ " str %0, [%1, %2]\n\t"
+ " str %3, [%1, %4]\n\t"
+ " mcr p15, 0, %0, c7, c0, 4\n\t"
+ " str %5, [%1, %2]"
+ :
+ : "r" (0), "r" (at91_ramc_base[0]), "r" (AT91RM9200_SDRAMC_LPR),
+ "r" (1), "r" (AT91RM9200_SDRAMC_SRR),
+ "r" (lpr));
+}
+
+/* We manage both DDRAM/SDRAM controllers, we need more than one value to
+ * remember.
+ */
+static void at91_ddr_standby(void)
+{
+ /* Those two values allow us to delay self-refresh activation
+ * to the maximum. */
+ u32 lpr0, lpr1 = 0;
+ u32 saved_lpr0, saved_lpr1 = 0;
+
+ if (at91_ramc_base[1]) {
+ 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);
+ if (at91_ramc_base[1])
+ at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
+
+ cpu_do_idle();
+
+ at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
+ if (at91_ramc_base[1])
+ at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
+}
+
+/* We manage both DDRAM/SDRAM controllers, we need more than one value to
+ * remember.
+ */
+static void at91sam9_sdram_standby(void)
+{
+ u32 lpr0, lpr1 = 0;
+ u32 saved_lpr0, saved_lpr1 = 0;
+
+ if (at91_ramc_base[1]) {
+ saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
+ lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
+ lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH;
+ }
+
+ saved_lpr0 = at91_ramc_read(0, AT91_SDRAMC_LPR);
+ lpr0 = saved_lpr0 & ~AT91_SDRAMC_LPCB;
+ lpr0 |= AT91_SDRAMC_LPCB_SELF_REFRESH;
+
+ /* self-refresh mode now */
+ at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
+ if (at91_ramc_base[1])
+ at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);
+
+ cpu_do_idle();
+
+ at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
+ if (at91_ramc_base[1])
+ at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
+}
+
+static const struct of_device_id ramc_ids[] __initconst = {
+ { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby },
+ { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby },
+ { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
+ { .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby },
+ { /*sentinel*/ }
+};
+
+static __init void at91_dt_ramc(void)
+{
+ struct device_node *np;
+ const struct of_device_id *of_id;
+ int idx = 0;
+ const void *standby = NULL;
+
+ for_each_matching_node_and_match(np, ramc_ids, &of_id) {
+ at91_ramc_base[idx] = of_iomap(np, 0);
+ if (!at91_ramc_base[idx])
+ panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
+
+ if (!standby)
+ standby = of_id->data;
+
+ idx++;
+ }
+
+ if (!idx)
+ panic(pr_fmt("unable to find compatible ram controller node in dtb\n"));
+
+ if (!standby) {
+ pr_warn("ramc no standby function available\n");
+ return;
+ }
+
+ at91_pm_set_standby(standby);
+}
+
+static void __init at91_pm_sram_init(void)
+{
+ struct gen_pool *sram_pool;
+ phys_addr_t sram_pbase;
+ unsigned long sram_base;
+ struct device_node *node;
+ struct platform_device *pdev = NULL;
+
+ for_each_compatible_node(node, NULL, "mmio-sram") {
+ pdev = of_find_device_by_node(node);
+ if (pdev) {
+ of_node_put(node);
+ break;
+ }
+ }
+
+ if (!pdev) {
+ pr_warn("%s: failed to find sram device!\n", __func__);
+ return;
+ }
+
+ sram_pool = dev_get_gen_pool(&pdev->dev);
+ if (!sram_pool) {
+ pr_warn("%s: sram pool unavailable!\n", __func__);
+ return;
+ }
+
+ sram_base = gen_pool_alloc(sram_pool, at91_pm_suspend_in_sram_sz);
+ if (!sram_base) {
+ pr_warn("%s: unable to alloc sram!\n", __func__);
+ return;
+ }
+
+ sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base);
+ at91_suspend_sram_fn = __arm_ioremap_exec(sram_pbase,
+ at91_pm_suspend_in_sram_sz, false);
+ if (!at91_suspend_sram_fn) {
+ pr_warn("SRAM: Could not map\n");
+ return;
+ }
+
+ /* Copy the pm suspend handler to SRAM */
+ at91_suspend_sram_fn = fncpy(at91_suspend_sram_fn,
+ &at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz);
+}
+
+static void __init at91_pm_init(void)
+{
+ at91_pm_sram_init();
+
+ if (at91_cpuidle_device.dev.platform_data)
+ platform_device_register(&at91_cpuidle_device);
+
+ if (at91_suspend_sram_fn)
+ suspend_set_ops(&at91_pm_ops);
+ else
+ pr_info("AT91: PM not supported, due to no SRAM allocated\n");
+}
+
+void __init at91rm9200_pm_init(void)
+{
+ at91_dt_ramc();
+
+ /*
+ * AT91RM9200 SDRAM low-power mode cannot be used with self-refresh.
+ */
+ at91_ramc_write(0, AT91RM9200_SDRAMC_LPR, 0);
+
+ at91_pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP;
+ at91_pm_data.memctrl = AT91_MEMCTRL_MC;
+
+ at91_pm_init();
+}
+
+void __init at91sam9260_pm_init(void)
+{
+ at91_dt_ramc();
+ at91_pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
+ at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+ return at91_pm_init();
+}
+
+void __init at91sam9g45_pm_init(void)
+{
+ at91_dt_ramc();
+ at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
+ at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+ return at91_pm_init();
+}
+
+void __init at91sam9x5_pm_init(void)
+{
+ at91_dt_ramc();
+ at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+ at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+ return at91_pm_init();
+}
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
new file mode 100644
index 000000000..ecd875a91
--- /dev/null
+++ b/arch/arm/mach-at91/pm.h
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+#ifndef __ARCH_ARM_MACH_AT91_PM
+#define __ARCH_ARM_MACH_AT91_PM
+
+#include <asm/proc-fns.h>
+
+#include <mach/at91_ramc.h>
+
+#define AT91_MEMCTRL_MC 0
+#define AT91_MEMCTRL_SDRAMC 1
+#define AT91_MEMCTRL_DDRSDR 2
+
+#define AT91_PM_MEMTYPE_MASK 0x0f
+
+#define AT91_PM_MODE_OFFSET 4
+#define AT91_PM_MODE_MASK 0x01
+#define AT91_PM_MODE(x) (((x) & AT91_PM_MODE_MASK) << AT91_PM_MODE_OFFSET)
+
+#define AT91_PM_SLOW_CLOCK 0x01
+
+#endif
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
new file mode 100644
index 000000000..bd22b2c8a
--- /dev/null
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -0,0 +1,337 @@
+/*
+ * 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 <linux/clk/at91_pmc.h>
+#include <mach/at91_ramc.h>
+#include "pm.h"
+
+#define SRAMC_SELF_FRESH_ACTIVE 0x01
+#define SRAMC_SELF_FRESH_EXIT 0x00
+
+pmc .req r0
+tmp1 .req r4
+tmp2 .req r5
+
+/*
+ * Wait until master clock is ready (after switching master clock source)
+ */
+ .macro wait_mckrdy
+1: ldr tmp1, [pmc, #AT91_PMC_SR]
+ tst tmp1, #AT91_PMC_MCKRDY
+ beq 1b
+ .endm
+
+/*
+ * Wait until master oscillator has stabilized.
+ */
+ .macro wait_moscrdy
+1: ldr tmp1, [pmc, #AT91_PMC_SR]
+ tst tmp1, #AT91_PMC_MOSCS
+ beq 1b
+ .endm
+
+/*
+ * Wait until PLLA has locked.
+ */
+ .macro wait_pllalock
+1: ldr tmp1, [pmc, #AT91_PMC_SR]
+ tst tmp1, #AT91_PMC_LOCKA
+ beq 1b
+ .endm
+
+/*
+ * Put the processor to enter the idle state
+ */
+ .macro at91_cpu_idle
+
+#if defined(CONFIG_CPU_V7)
+ mov tmp1, #AT91_PMC_PCK
+ str tmp1, [pmc, #AT91_PMC_SCDR]
+
+ dsb
+
+ wfi @ Wait For Interrupt
+#else
+ mcr p15, 0, tmp1, c7, c0, 4
+#endif
+
+ .endm
+
+ .text
+
+ .arm
+
+/*
+ * void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *sdramc,
+ * void __iomem *ramc1, int memctrl)
+ * @input param:
+ * @r0: base address of AT91_PMC
+ * @r1: base address of SDRAM Controller (SDRAM, DDRSDR, or AT91_SYS)
+ * @r2: base address of second SDRAM Controller or 0 if not present
+ * @r3: pm information
+ */
+ENTRY(at91_pm_suspend_in_sram)
+ /* Save registers on stack */
+ stmfd sp!, {r4 - r12, lr}
+
+ /* Drain write buffer */
+ mov tmp1, #0
+ mcr p15, 0, tmp1, c7, c10, 4
+
+ str r0, .pmc_base
+ str r1, .sramc_base
+ str r2, .sramc1_base
+
+ and r0, r3, #AT91_PM_MEMTYPE_MASK
+ str r0, .memtype
+
+ lsr r0, r3, #AT91_PM_MODE_OFFSET
+ and r0, r0, #AT91_PM_MODE_MASK
+ str r0, .pm_mode
+
+ /* Active the self-refresh mode */
+ mov r0, #SRAMC_SELF_FRESH_ACTIVE
+ bl at91_sramc_self_refresh
+
+ ldr r0, .pm_mode
+ tst r0, #AT91_PM_SLOW_CLOCK
+ beq skip_disable_main_clock
+
+ ldr pmc, .pmc_base
+
+ /* Save Master clock setting */
+ ldr tmp1, [pmc, #AT91_PMC_MCKR]
+ str tmp1, .saved_mckr
+
+ /*
+ * Set the Master clock source to slow clock
+ */
+ bic tmp1, tmp1, #AT91_PMC_CSS
+ str tmp1, [pmc, #AT91_PMC_MCKR]
+
+ wait_mckrdy
+
+ /* Save PLLA setting and disable it */
+ ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
+ str tmp1, .saved_pllar
+
+ mov tmp1, #AT91_PMC_PLLCOUNT
+ orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
+ str tmp1, [pmc, #AT91_CKGR_PLLAR]
+
+ /* Turn off the main oscillator */
+ ldr tmp1, [pmc, #AT91_CKGR_MOR]
+ bic tmp1, tmp1, #AT91_PMC_MOSCEN
+ orr tmp1, tmp1, #AT91_PMC_KEY
+ str tmp1, [pmc, #AT91_CKGR_MOR]
+
+skip_disable_main_clock:
+ ldr pmc, .pmc_base
+
+ /* Wait for interrupt */
+ at91_cpu_idle
+
+ ldr r0, .pm_mode
+ tst r0, #AT91_PM_SLOW_CLOCK
+ beq skip_enable_main_clock
+
+ ldr pmc, .pmc_base
+
+ /* Turn on the main oscillator */
+ ldr tmp1, [pmc, #AT91_CKGR_MOR]
+ orr tmp1, tmp1, #AT91_PMC_MOSCEN
+ orr tmp1, tmp1, #AT91_PMC_KEY
+ str tmp1, [pmc, #AT91_CKGR_MOR]
+
+ wait_moscrdy
+
+ /* Restore PLLA setting */
+ ldr tmp1, .saved_pllar
+ str tmp1, [pmc, #AT91_CKGR_PLLAR]
+
+ tst tmp1, #(AT91_PMC_MUL & 0xff0000)
+ bne 3f
+ tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
+ beq 4f
+3:
+ wait_pllalock
+4:
+
+ /*
+ * Restore master clock setting
+ */
+ ldr tmp1, .saved_mckr
+ str tmp1, [pmc, #AT91_PMC_MCKR]
+
+ wait_mckrdy
+
+skip_enable_main_clock:
+ /* Exit the self-refresh mode */
+ mov r0, #SRAMC_SELF_FRESH_EXIT
+ bl at91_sramc_self_refresh
+
+ /* Restore registers, and return */
+ ldmfd sp!, {r4 - r12, pc}
+ENDPROC(at91_pm_suspend_in_sram)
+
+/*
+ * void at91_sramc_self_refresh(unsigned int is_active)
+ *
+ * @input param:
+ * @r0: 1 - active self-refresh mode
+ * 0 - exit self-refresh mode
+ * register usage:
+ * @r1: memory type
+ * @r2: base address of the sram controller
+ */
+
+ENTRY(at91_sramc_self_refresh)
+ ldr r1, .memtype
+ ldr r2, .sramc_base
+
+ cmp r1, #AT91_MEMCTRL_MC
+ bne ddrc_sf
+
+ /*
+ * at91rm9200 Memory controller
+ */
+
+ /*
+ * For exiting the self-refresh mode, do nothing,
+ * automatically exit the self-refresh mode.
+ */
+ tst r0, #SRAMC_SELF_FRESH_ACTIVE
+ beq exit_sramc_sf
+
+ /* Active SDRAM self-refresh mode */
+ mov r3, #1
+ str r3, [r2, #AT91RM9200_SDRAMC_SRR]
+ b exit_sramc_sf
+
+ddrc_sf:
+ cmp r1, #AT91_MEMCTRL_DDRSDR
+ bne sdramc_sf
+
+ /*
+ * DDR Memory controller
+ */
+ tst r0, #SRAMC_SELF_FRESH_ACTIVE
+ beq ddrc_exit_sf
+
+ /* LPDDR1 --> force DDR2 mode during self-refresh */
+ ldr r3, [r2, #AT91_DDRSDRC_MDR]
+ str r3, .saved_sam9_mdr
+ bic r3, r3, #~AT91_DDRSDRC_MD
+ cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
+ ldreq r3, [r2, #AT91_DDRSDRC_MDR]
+ biceq r3, r3, #AT91_DDRSDRC_MD
+ orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
+ streq r3, [r2, #AT91_DDRSDRC_MDR]
+
+ /* Active DDRC self-refresh mode */
+ ldr r3, [r2, #AT91_DDRSDRC_LPR]
+ str r3, .saved_sam9_lpr
+ bic r3, r3, #AT91_DDRSDRC_LPCB
+ orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
+ str r3, [r2, #AT91_DDRSDRC_LPR]
+
+ /* If using the 2nd ddr controller */
+ ldr r2, .sramc1_base
+ cmp r2, #0
+ beq no_2nd_ddrc
+
+ ldr r3, [r2, #AT91_DDRSDRC_MDR]
+ str r3, .saved_sam9_mdr1
+ bic r3, r3, #~AT91_DDRSDRC_MD
+ cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
+ ldreq r3, [r2, #AT91_DDRSDRC_MDR]
+ biceq r3, r3, #AT91_DDRSDRC_MD
+ orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
+ streq r3, [r2, #AT91_DDRSDRC_MDR]
+
+ /* Active DDRC self-refresh mode */
+ ldr r3, [r2, #AT91_DDRSDRC_LPR]
+ str r3, .saved_sam9_lpr1
+ bic r3, r3, #AT91_DDRSDRC_LPCB
+ orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
+ str r3, [r2, #AT91_DDRSDRC_LPR]
+
+no_2nd_ddrc:
+ b exit_sramc_sf
+
+ddrc_exit_sf:
+ /* Restore MDR in case of LPDDR1 */
+ ldr r3, .saved_sam9_mdr
+ str r3, [r2, #AT91_DDRSDRC_MDR]
+ /* Restore LPR on AT91 with DDRAM */
+ ldr r3, .saved_sam9_lpr
+ str r3, [r2, #AT91_DDRSDRC_LPR]
+
+ /* If using the 2nd ddr controller */
+ ldr r2, .sramc1_base
+ cmp r2, #0
+ ldrne r3, .saved_sam9_mdr1
+ strne r3, [r2, #AT91_DDRSDRC_MDR]
+ ldrne r3, .saved_sam9_lpr1
+ strne r3, [r2, #AT91_DDRSDRC_LPR]
+
+ b exit_sramc_sf
+
+ /*
+ * SDRAMC Memory controller
+ */
+sdramc_sf:
+ tst r0, #SRAMC_SELF_FRESH_ACTIVE
+ beq sdramc_exit_sf
+
+ /* Active SDRAMC self-refresh mode */
+ ldr r3, [r2, #AT91_SDRAMC_LPR]
+ str r3, .saved_sam9_lpr
+ bic r3, r3, #AT91_SDRAMC_LPCB
+ orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
+ str r3, [r2, #AT91_SDRAMC_LPR]
+
+sdramc_exit_sf:
+ ldr r3, .saved_sam9_lpr
+ str r3, [r2, #AT91_SDRAMC_LPR]
+
+exit_sramc_sf:
+ mov pc, lr
+ENDPROC(at91_sramc_self_refresh)
+
+.pmc_base:
+ .word 0
+.sramc_base:
+ .word 0
+.sramc1_base:
+ .word 0
+.memtype:
+ .word 0
+.pm_mode:
+ .word 0
+.saved_mckr:
+ .word 0
+.saved_pllar:
+ .word 0
+.saved_sam9_lpr:
+ .word 0
+.saved_sam9_lpr1:
+ .word 0
+.saved_sam9_mdr:
+ .word 0
+.saved_sam9_mdr1:
+ .word 0
+
+ENTRY(at91_pm_suspend_in_sram_sz)
+ .word .-at91_pm_suspend_in_sram
diff --git a/arch/arm/mach-at91/sam9_smc.c b/arch/arm/mach-at91/sam9_smc.c
new file mode 100644
index 000000000..826315af6
--- /dev/null
+++ b/arch/arm/mach-at91/sam9_smc.c
@@ -0,0 +1,136 @@
+/*
+ * linux/arch/arm/mach-at91/sam9_smc.c
+ *
+ * Copyright (C) 2008 Andrew Victor
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.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/of.h>
+#include <linux/of_address.h>
+
+#include <mach/at91sam9_smc.h>
+
+#include "sam9_smc.h"
+
+
+#define AT91_SMC_CS(id, n) (smc_base_addr[id] + ((n) * 0x10))
+
+static void __iomem *smc_base_addr[2];
+
+static void sam9_smc_cs_write_mode(void __iomem *base,
+ struct sam9_smc_config *config)
+{
+ __raw_writel(config->mode
+ | AT91_SMC_TDF_(config->tdf_cycles),
+ base + AT91_SMC_MODE);
+}
+
+void sam9_smc_write_mode(int id, int cs,
+ struct sam9_smc_config *config)
+{
+ sam9_smc_cs_write_mode(AT91_SMC_CS(id, cs), config);
+}
+EXPORT_SYMBOL_GPL(sam9_smc_write_mode);
+
+static void sam9_smc_cs_configure(void __iomem *base,
+ struct sam9_smc_config *config)
+{
+
+ /* Setup register */
+ __raw_writel(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),
+ base + AT91_SMC_SETUP);
+
+ /* Pulse register */
+ __raw_writel(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),
+ base + AT91_SMC_PULSE);
+
+ /* Cycle register */
+ __raw_writel(AT91_SMC_NWECYCLE_(config->write_cycle)
+ | AT91_SMC_NRDCYCLE_(config->read_cycle),
+ base + AT91_SMC_CYCLE);
+
+ /* Mode register */
+ sam9_smc_cs_write_mode(base, config);
+}
+
+void sam9_smc_configure(int id, int cs,
+ struct sam9_smc_config *config)
+{
+ sam9_smc_cs_configure(AT91_SMC_CS(id, cs), config);
+}
+EXPORT_SYMBOL_GPL(sam9_smc_configure);
+
+static void sam9_smc_cs_read_mode(void __iomem *base,
+ struct sam9_smc_config *config)
+{
+ u32 val = __raw_readl(base + AT91_SMC_MODE);
+
+ config->mode = (val & ~AT91_SMC_NWECYCLE);
+ config->tdf_cycles = (val & AT91_SMC_NWECYCLE) >> 16 ;
+}
+
+void sam9_smc_read_mode(int id, int cs,
+ struct sam9_smc_config *config)
+{
+ sam9_smc_cs_read_mode(AT91_SMC_CS(id, cs), config);
+}
+EXPORT_SYMBOL_GPL(sam9_smc_read_mode);
+
+static void sam9_smc_cs_read(void __iomem *base,
+ struct sam9_smc_config *config)
+{
+ u32 val;
+
+ /* Setup register */
+ val = __raw_readl(base + AT91_SMC_SETUP);
+
+ config->nwe_setup = val & AT91_SMC_NWESETUP;
+ config->ncs_write_setup = (val & AT91_SMC_NCS_WRSETUP) >> 8;
+ config->nrd_setup = (val & AT91_SMC_NRDSETUP) >> 16;
+ config->ncs_read_setup = (val & AT91_SMC_NCS_RDSETUP) >> 24;
+
+ /* Pulse register */
+ val = __raw_readl(base + AT91_SMC_PULSE);
+
+ config->nwe_pulse = val & AT91_SMC_NWEPULSE;
+ config->ncs_write_pulse = (val & AT91_SMC_NCS_WRPULSE) >> 8;
+ config->nrd_pulse = (val & AT91_SMC_NRDPULSE) >> 16;
+ config->ncs_read_pulse = (val & AT91_SMC_NCS_RDPULSE) >> 24;
+
+ /* Cycle register */
+ val = __raw_readl(base + AT91_SMC_CYCLE);
+
+ config->write_cycle = val & AT91_SMC_NWECYCLE;
+ config->read_cycle = (val & AT91_SMC_NRDCYCLE) >> 16;
+
+ /* Mode register */
+ sam9_smc_cs_read_mode(base, config);
+}
+
+void sam9_smc_read(int id, int cs, struct sam9_smc_config *config)
+{
+ sam9_smc_cs_read(AT91_SMC_CS(id, cs), config);
+}
+
+void __init at91sam9_ioremap_smc(int id, u32 addr)
+{
+ if (id > 1) {
+ pr_warn("%s: id > 2\n", __func__);
+ return;
+ }
+ smc_base_addr[id] = ioremap(addr, 512);
+ if (!smc_base_addr[id])
+ pr_warn("Impossible to ioremap smc.%d 0x%x\n", id, addr);
+}
diff --git a/arch/arm/mach-at91/sam9_smc.h b/arch/arm/mach-at91/sam9_smc.h
new file mode 100644
index 000000000..3e52dcd4a
--- /dev/null
+++ b/arch/arm/mach-at91/sam9_smc.h
@@ -0,0 +1,11 @@
+/*
+ * 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.
+ */
+
+extern void __init at91sam9_ioremap_smc(int id, u32 addr);
diff --git a/arch/arm/mach-at91/sama5.c b/arch/arm/mach-at91/sama5.c
new file mode 100644
index 000000000..41d829d8e
--- /dev/null
+++ b/arch/arm/mach-at91/sama5.c
@@ -0,0 +1,76 @@
+/*
+ * Setup code for SAMA5
+ *
+ * Copyright (C) 2013 Atmel,
+ * 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/of.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/system_misc.h>
+
+#include "generic.h"
+#include "soc.h"
+
+static const struct at91_soc sama5_socs[] = {
+ AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D31_EXID_MATCH,
+ "sama5d31", "sama5d3"),
+ AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D33_EXID_MATCH,
+ "sama5d33", "sama5d3"),
+ AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D34_EXID_MATCH,
+ "sama5d34", "sama5d3"),
+ AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D35_EXID_MATCH,
+ "sama5d35", "sama5d3"),
+ AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D36_EXID_MATCH,
+ "sama5d36", "sama5d3"),
+ AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D41_EXID_MATCH,
+ "sama5d41", "sama5d4"),
+ AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D42_EXID_MATCH,
+ "sama5d42", "sama5d4"),
+ AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D43_EXID_MATCH,
+ "sama5d43", "sama5d4"),
+ AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D44_EXID_MATCH,
+ "sama5d44", "sama5d4"),
+ { /* sentinel */ },
+};
+
+static void __init sama5_dt_device_init(void)
+{
+ struct soc_device *soc;
+ struct device *soc_dev = NULL;
+
+ soc = at91_soc_init(sama5_socs);
+ if (soc != NULL)
+ soc_dev = soc_device_to_device(soc);
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev);
+ at91sam9x5_pm_init();
+}
+
+static const char *sama5_dt_board_compat[] __initconst = {
+ "atmel,sama5",
+ NULL
+};
+
+DT_MACHINE_START(sama5_dt, "Atmel SAMA5")
+ /* Maintainer: Atmel */
+ .init_machine = sama5_dt_device_init,
+ .dt_compat = sama5_dt_board_compat,
+MACHINE_END
+
+static const char *sama5_alt_dt_board_compat[] __initconst = {
+ "atmel,sama5d4",
+ NULL
+};
+
+DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5")
+ /* Maintainer: Atmel */
+ .init_machine = sama5_dt_device_init,
+ .dt_compat = sama5_alt_dt_board_compat,
+ .l2c_aux_mask = ~0UL,
+MACHINE_END
diff --git a/arch/arm/mach-at91/soc.c b/arch/arm/mach-at91/soc.c
new file mode 100644
index 000000000..54343ffa3
--- /dev/null
+++ b/arch/arm/mach-at91/soc.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2015 Atmel
+ *
+ * Alexandre Belloni <alexandre.belloni@free-electrons.com
+ * Boris Brezillon <boris.brezillon@free-electrons.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 pr_fmt(fmt) "AT91: " fmt
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+
+#include "soc.h"
+
+#define AT91_DBGU_CIDR 0x40
+#define AT91_DBGU_CIDR_VERSION(x) ((x) & 0x1f)
+#define AT91_DBGU_CIDR_EXT BIT(31)
+#define AT91_DBGU_CIDR_MATCH_MASK 0x7fffffe0
+#define AT91_DBGU_EXID 0x44
+
+struct soc_device * __init at91_soc_init(const struct at91_soc *socs)
+{
+ struct soc_device_attribute *soc_dev_attr;
+ const struct at91_soc *soc;
+ struct soc_device *soc_dev;
+ struct device_node *np;
+ void __iomem *regs;
+ u32 cidr, exid;
+
+ np = of_find_compatible_node(NULL, NULL, "atmel,at91rm9200-dbgu");
+ if (!np)
+ np = of_find_compatible_node(NULL, NULL,
+ "atmel,at91sam9260-dbgu");
+
+ if (!np) {
+ pr_warn("Could not find DBGU node");
+ return NULL;
+ }
+
+ regs = of_iomap(np, 0);
+ of_node_put(np);
+
+ if (!regs) {
+ pr_warn("Could not map DBGU iomem range");
+ return NULL;
+ }
+
+ cidr = readl(regs + AT91_DBGU_CIDR);
+ exid = readl(regs + AT91_DBGU_EXID);
+
+ iounmap(regs);
+
+ for (soc = socs; soc->name; soc++) {
+ if (soc->cidr_match != (cidr & AT91_DBGU_CIDR_MATCH_MASK))
+ continue;
+
+ if (!(cidr & AT91_DBGU_CIDR_EXT) || soc->exid_match == exid)
+ break;
+ }
+
+ if (!soc->name) {
+ pr_warn("Could not find matching SoC description\n");
+ return NULL;
+ }
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ return NULL;
+
+ soc_dev_attr->family = soc->family;
+ soc_dev_attr->soc_id = soc->name;
+ soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%X",
+ AT91_DBGU_CIDR_VERSION(cidr));
+ soc_dev = soc_device_register(soc_dev_attr);
+ if (IS_ERR(soc_dev)) {
+ kfree(soc_dev_attr->revision);
+ kfree(soc_dev_attr);
+ pr_warn("Could not register SoC device\n");
+ return NULL;
+ }
+
+ if (soc->family)
+ pr_info("Detected SoC family: %s\n", soc->family);
+ pr_info("Detected SoC: %s, revision %X\n", soc->name,
+ AT91_DBGU_CIDR_VERSION(cidr));
+
+ return soc_dev;
+}
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h
new file mode 100644
index 000000000..be23c4005
--- /dev/null
+++ b/arch/arm/mach-at91/soc.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 Atmel
+ *
+ * Boris Brezillon <boris.brezillon@free-electrons.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 __AT91_SOC_H
+#define __AT91_SOC_H
+
+#include <linux/sys_soc.h>
+
+struct at91_soc {
+ u32 cidr_match;
+ u32 exid_match;
+ const char *name;
+ const char *family;
+};
+
+#define AT91_SOC(__cidr, __exid, __name, __family) \
+ { \
+ .cidr_match = (__cidr), \
+ .exid_match = (__exid), \
+ .name = (__name), \
+ .family = (__family), \
+ }
+
+struct soc_device * __init
+at91_soc_init(const struct at91_soc *socs);
+
+#define AT91RM9200_CIDR_MATCH 0x09290780
+
+#define AT91SAM9260_CIDR_MATCH 0x019803a0
+#define AT91SAM9261_CIDR_MATCH 0x019703a0
+#define AT91SAM9263_CIDR_MATCH 0x019607a0
+#define AT91SAM9G20_CIDR_MATCH 0x019905a0
+#define AT91SAM9RL64_CIDR_MATCH 0x019b03a0
+#define AT91SAM9G45_CIDR_MATCH 0x019b05a0
+#define AT91SAM9X5_CIDR_MATCH 0x019a05a0
+#define AT91SAM9N12_CIDR_MATCH 0x019a07a0
+
+#define AT91SAM9M11_EXID_MATCH 0x00000001
+#define AT91SAM9M10_EXID_MATCH 0x00000002
+#define AT91SAM9G46_EXID_MATCH 0x00000003
+#define AT91SAM9G45_EXID_MATCH 0x00000004
+
+#define AT91SAM9G15_EXID_MATCH 0x00000000
+#define AT91SAM9G35_EXID_MATCH 0x00000001
+#define AT91SAM9X35_EXID_MATCH 0x00000002
+#define AT91SAM9G25_EXID_MATCH 0x00000003
+#define AT91SAM9X25_EXID_MATCH 0x00000004
+
+#define AT91SAM9CN12_EXID_MATCH 0x00000005
+#define AT91SAM9N12_EXID_MATCH 0x00000006
+#define AT91SAM9CN11_EXID_MATCH 0x00000009
+
+#define AT91SAM9XE128_CIDR_MATCH 0x329973a0
+#define AT91SAM9XE256_CIDR_MATCH 0x329a93a0
+#define AT91SAM9XE512_CIDR_MATCH 0x329aa3a0
+
+#define SAMA5D3_CIDR_MATCH 0x0a5c07c0
+#define SAMA5D31_EXID_MATCH 0x00444300
+#define SAMA5D33_EXID_MATCH 0x00414300
+#define SAMA5D34_EXID_MATCH 0x00414301
+#define SAMA5D35_EXID_MATCH 0x00584300
+#define SAMA5D36_EXID_MATCH 0x00004301
+
+#define SAMA5D4_CIDR_MATCH 0x0a5c07c0
+#define SAMA5D41_EXID_MATCH 0x00000001
+#define SAMA5D42_EXID_MATCH 0x00000002
+#define SAMA5D43_EXID_MATCH 0x00000003
+#define SAMA5D44_EXID_MATCH 0x00000004
+
+#endif /* __AT91_SOC_H */
diff --git a/arch/arm/mach-axxia/Kconfig b/arch/arm/mach-axxia/Kconfig
new file mode 100644
index 000000000..8be7e0ae1
--- /dev/null
+++ b/arch/arm/mach-axxia/Kconfig
@@ -0,0 +1,16 @@
+config ARCH_AXXIA
+ bool "LSI Axxia platforms" if (ARCH_MULTI_V7 && ARM_LPAE)
+ select ARCH_DMA_ADDR_T_64BIT
+ select ARM_AMBA
+ select ARM_GIC
+ select ARM_TIMER_SP804
+ select HAVE_ARM_ARCH_TIMER
+ select MFD_SYSCON
+ select MIGHT_HAVE_PCI
+ select PCI_DOMAINS if PCI
+ select ZONE_DMA
+ help
+ This enables support for the LSI Axxia devices.
+
+ The LSI Axxia platforms require a Flattened Device Tree to be passed
+ to the kernel.
diff --git a/arch/arm/mach-axxia/Makefile b/arch/arm/mach-axxia/Makefile
new file mode 100644
index 000000000..ec4f68b46
--- /dev/null
+++ b/arch/arm/mach-axxia/Makefile
@@ -0,0 +1,2 @@
+obj-y += axxia.o
+obj-$(CONFIG_SMP) += platsmp.o
diff --git a/arch/arm/mach-axxia/axxia.c b/arch/arm/mach-axxia/axxia.c
new file mode 100644
index 000000000..4db76a493
--- /dev/null
+++ b/arch/arm/mach-axxia/axxia.c
@@ -0,0 +1,28 @@
+/*
+ * Support for the LSI Axxia SoC devices based on ARM cores.
+ *
+ * Copyright (C) 2012 LSI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <asm/mach/arch.h>
+
+static const char *const axxia_dt_match[] __initconst = {
+ "lsi,axm5516",
+ "lsi,axm5516-sim",
+ "lsi,axm5516-emu",
+ NULL
+};
+
+DT_MACHINE_START(AXXIA_DT, "LSI Axxia AXM55XX")
+ .dt_compat = axxia_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-axxia/platsmp.c b/arch/arm/mach-axxia/platsmp.c
new file mode 100644
index 000000000..959d4df3d
--- /dev/null
+++ b/arch/arm/mach-axxia/platsmp.c
@@ -0,0 +1,89 @@
+/*
+ * linux/arch/arm/mach-axxia/platsmp.c
+ *
+ * Copyright (C) 2012 LSI 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/init.h>
+#include <linux/io.h>
+#include <linux/smp.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <asm/cacheflush.h>
+
+/* Syscon register offsets for releasing cores from reset */
+#define SC_CRIT_WRITE_KEY 0x1000
+#define SC_RST_CPU_HOLD 0x1010
+
+/*
+ * Write the kernel entry point for secondary CPUs to the specified address
+ */
+static void write_release_addr(u32 release_phys)
+{
+ u32 *virt = (u32 *) phys_to_virt(release_phys);
+ writel_relaxed(virt_to_phys(secondary_startup), virt);
+ /* Make sure this store is visible to other CPUs */
+ smp_wmb();
+ __cpuc_flush_dcache_area(virt, sizeof(u32));
+}
+
+static int axxia_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ struct device_node *syscon_np;
+ void __iomem *syscon;
+ u32 tmp;
+
+ syscon_np = of_find_compatible_node(NULL, NULL, "lsi,axxia-syscon");
+ if (!syscon_np)
+ return -ENOENT;
+
+ syscon = of_iomap(syscon_np, 0);
+ if (!syscon)
+ return -ENOMEM;
+
+ tmp = readl(syscon + SC_RST_CPU_HOLD);
+ writel(0xab, syscon + SC_CRIT_WRITE_KEY);
+ tmp &= ~(1 << cpu);
+ writel(tmp, syscon + SC_RST_CPU_HOLD);
+
+ return 0;
+}
+
+static void __init axxia_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int cpu_count = 0;
+ int cpu;
+
+ /*
+ * Initialise the present map, which describes the set of CPUs actually
+ * populated at the present time.
+ */
+ for_each_possible_cpu(cpu) {
+ struct device_node *np;
+ u32 release_phys;
+
+ np = of_get_cpu_node(cpu, NULL);
+ if (!np)
+ continue;
+ if (of_property_read_u32(np, "cpu-release-addr", &release_phys))
+ continue;
+
+ if (cpu_count < max_cpus) {
+ set_cpu_present(cpu, true);
+ cpu_count++;
+ }
+
+ if (release_phys != 0)
+ write_release_addr(release_phys);
+ }
+}
+
+static struct smp_operations axxia_smp_ops __initdata = {
+ .smp_prepare_cpus = axxia_smp_prepare_cpus,
+ .smp_boot_secondary = axxia_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(axxia_smp, "lsi,syscon-release", &axxia_smp_ops);
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
new file mode 100644
index 000000000..8b11f44bb
--- /dev/null
+++ b/arch/arm/mach-bcm/Kconfig
@@ -0,0 +1,154 @@
+menuconfig ARCH_BCM
+ bool "Broadcom SoC Support" if ARCH_MULTI_V6_V7
+ help
+ This enables support for Broadcom ARM based SoC chips
+
+if ARCH_BCM
+
+comment "IPROC architected SoCs"
+
+config ARCH_BCM_IPROC
+ bool
+ select ARM_GIC
+ select CACHE_L2X0
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select ARM_GLOBAL_TIMER
+
+ select CLKSRC_MMIO
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_AMBA
+ select PINCTRL
+ help
+ This enables support for systems based on Broadcom IPROC architected SoCs.
+ The IPROC complex contains one or more ARM CPUs along with common
+ core periperals. Application specific SoCs are created by adding a
+ uArchitecture containing peripherals outside of the IPROC complex.
+ Currently supported SoCs are Cygnus.
+
+config ARCH_BCM_CYGNUS
+ bool "Broadcom Cygnus Support" if ARCH_MULTI_V7
+ select ARCH_BCM_IPROC
+ help
+ Enable support for the Cygnus family,
+ which includes the following variants:
+ BCM11300, BCM11320, BCM11350, BCM11360,
+ BCM58300, BCM58302, BCM58303, BCM58305.
+
+config ARCH_BCM_5301X
+ bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
+ select ARCH_BCM_IPROC
+ help
+ Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
+
+ This is a network SoC line mostly used in home routers and
+ wifi access points, it's internal name is Northstar.
+ This inclused the following SoC: BCM53010, BCM53011, BCM53012,
+ BCM53014, BCM53015, BCM53016, BCM53017, BCM53018, BCM4707,
+ BCM4708 and BCM4709.
+
+ Do not confuse this with the BCM4760 which is a totally
+ different SoC or with the older BCM47XX and BCM53XX based
+ network SoC using a MIPS CPU, they are supported by arch/mips/bcm47xx
+
+comment "KONA architected SoCs"
+
+config ARCH_BCM_MOBILE
+ bool
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_775420
+ select ARM_GIC
+ select GPIO_BCM_KONA
+ select TICK_ONESHOT
+ select HAVE_ARM_ARCH_TIMER
+ select PINCTRL
+ select ARCH_BCM_MOBILE_SMP if SMP
+ help
+ This enables support for systems based on Broadcom mobile SoCs.
+
+config ARCH_BCM_281XX
+ bool "Broadcom BCM281XX SoC family" if ARCH_MULTI_V7
+ select ARCH_BCM_MOBILE
+ select HAVE_SMP
+ help
+ Enable support for the BCM281XX family, which includes
+ BCM11130, BCM11140, BCM11351, BCM28145 and BCM28155
+ variants.
+
+config ARCH_BCM_21664
+ bool "Broadcom BCM21664 SoC family" if ARCH_MULTI_V7
+ select ARCH_BCM_MOBILE
+ select HAVE_SMP
+ help
+ Enable support for the BCM21664 family, which includes
+ BCM21663 and BCM21664 variants.
+
+config ARCH_BCM_MOBILE_L2_CACHE
+ bool "Broadcom mobile SoC level 2 cache support"
+ depends on ARCH_BCM_MOBILE
+ default y
+ select CACHE_L2X0
+ select ARCH_BCM_MOBILE_SMC
+
+config ARCH_BCM_MOBILE_SMC
+ bool
+ depends on ARCH_BCM_MOBILE
+
+config ARCH_BCM_MOBILE_SMP
+ bool
+ depends on ARCH_BCM_MOBILE
+ select HAVE_ARM_SCU
+ select ARM_ERRATA_764369
+ help
+ SMP support for the BCM281XX and BCM21664 SoC families.
+ Provided as an option so SMP support for SoCs of this type
+ can be disabled for an SMP-enabled kernel.
+
+comment "Other Architectures"
+
+config ARCH_BCM2835
+ bool "Broadcom BCM2835 family" if ARCH_MULTI_V6
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_AMBA
+ select ARM_ERRATA_411920
+ select ARM_TIMER_SP804
+ select CLKSRC_OF
+ select PINCTRL
+ select PINCTRL_BCM2835
+ help
+ This enables support for the Broadcom BCM2835 SoC. This SoC is
+ used in the Raspberry Pi and Roku 2 devices.
+
+config ARCH_BCM_63XX
+ bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7
+ depends on MMU
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_764369 if SMP
+ select ARM_GIC
+ select ARM_GLOBAL_TIMER
+ select CACHE_L2X0
+ select HAVE_ARM_ARCH_TIMER
+ select HAVE_ARM_TWD if SMP
+ select HAVE_ARM_SCU if SMP
+ select HAVE_SMP
+ help
+ This enables support for systems based on Broadcom DSL SoCs.
+ It currently supports the 'BCM63XX' ARM-based family, which includes
+ the BCM63138 variant.
+
+config ARCH_BRCMSTB
+ bool "Broadcom BCM7XXX based boards" if ARCH_MULTI_V7
+ select ARM_GIC
+ select HAVE_ARM_ARCH_TIMER
+ select BRCMSTB_GISB_ARB
+ select BRCMSTB_L2_IRQ
+ select BCM7120_L2_IRQ
+ help
+ Say Y if you intend to run the kernel on a Broadcom ARM-based STB
+ chipset.
+
+ This enables support for Broadcom ARM-based set-top box chipsets,
+ including the 7445 family of chips.
+
+endif
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
new file mode 100644
index 000000000..4c38674c7
--- /dev/null
+++ b/arch/arm/mach-bcm/Makefile
@@ -0,0 +1,47 @@
+#
+# Copyright (C) 2012-2014 Broadcom Corporation
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation version 2.
+#
+# 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.
+
+# Cygnus
+obj-$(CONFIG_ARCH_BCM_CYGNUS) += bcm_cygnus.o
+
+# BCM281XX
+obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o
+
+# BCM21664
+obj-$(CONFIG_ARCH_BCM_21664) += board_bcm21664.o
+
+# BCM281XX and BCM21664 SMP support
+obj-$(CONFIG_ARCH_BCM_MOBILE_SMP) += kona_smp.o
+
+# BCM281XX and BCM21664 L2 cache control
+obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona_l2_cache.o
+
+# Support for secure monitor traps
+obj-$(CONFIG_ARCH_BCM_MOBILE_SMC) += bcm_kona_smc.o
+ifeq ($(call as-instr,.arch_extension sec,as_has_sec),as_has_sec)
+CFLAGS_bcm_kona_smc.o += -Wa,-march=armv7-a+sec -DREQUIRES_SEC
+endif
+
+# BCM2835
+obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o
+
+# BCM5301X
+obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o
+
+# BCM63XXx
+obj-$(CONFIG_ARCH_BCM_63XX) := bcm63xx.o
+
+ifeq ($(CONFIG_ARCH_BRCMSTB),y)
+CFLAGS_platsmp-brcmstb.o += -march=armv7-a
+obj-y += brcmstb.o
+obj-$(CONFIG_SMP) += headsmp-brcmstb.o platsmp-brcmstb.o
+endif
diff --git a/arch/arm/mach-bcm/bcm63xx.c b/arch/arm/mach-bcm/bcm63xx.c
new file mode 100644
index 000000000..c4c66ae51
--- /dev/null
+++ b/arch/arm/mach-bcm/bcm63xx.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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/of_platform.h>
+
+#include <asm/mach/arch.h>
+
+static const char * const bcm63xx_dt_compat[] = {
+ "brcm,bcm63138",
+ NULL
+};
+
+DT_MACHINE_START(BCM63XXX_DT, "BCM63xx DSL SoC")
+ .dt_compat = bcm63xx_dt_compat,
+ .l2c_aux_val = 0,
+ .l2c_aux_mask = ~0,
+MACHINE_END
diff --git a/arch/arm/mach-bcm/bcm_5301x.c b/arch/arm/mach-bcm/bcm_5301x.c
new file mode 100644
index 000000000..e9bcbdbce
--- /dev/null
+++ b/arch/arm/mach-bcm/bcm_5301x.c
@@ -0,0 +1,56 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ *
+ * Copyright 2013 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+#include <linux/of_platform.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include <asm/mach/arch.h>
+#include <asm/siginfo.h>
+#include <asm/signal.h>
+
+
+static bool first_fault = true;
+
+static int bcm5301x_abort_handler(unsigned long addr, unsigned int fsr,
+ struct pt_regs *regs)
+{
+ if (fsr == 0x1c06 && first_fault) {
+ first_fault = false;
+
+ /*
+ * These faults with code 0x1c06 happens for no good reason,
+ * possibly left over from the CFE boot loader.
+ */
+ pr_warn("External imprecise Data abort at addr=%#lx, fsr=%#x ignored.\n",
+ addr, fsr);
+
+ /* Returning non-zero causes fault display and panic */
+ return 0;
+ }
+
+ /* Others should cause a fault */
+ return 1;
+}
+
+static void __init bcm5301x_init_early(void)
+{
+ /* Install our hook */
+ hook_fault_code(16 + 6, bcm5301x_abort_handler, SIGBUS, BUS_OBJERR,
+ "imprecise external abort");
+}
+
+static const char __initconst *bcm5301x_dt_compat[] = {
+ "brcm,bcm4708",
+ NULL,
+};
+
+DT_MACHINE_START(BCM5301X, "BCM5301X")
+ .l2c_aux_val = 0,
+ .l2c_aux_mask = ~0,
+ .init_early = bcm5301x_init_early,
+ .dt_compat = bcm5301x_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-bcm/bcm_cygnus.c b/arch/arm/mach-bcm/bcm_cygnus.c
new file mode 100644
index 000000000..7ae894c78
--- /dev/null
+++ b/arch/arm/mach-bcm/bcm_cygnus.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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 <asm/mach/arch.h>
+
+static const char * const bcm_cygnus_dt_compat[] __initconst = {
+ "brcm,cygnus",
+ NULL,
+};
+
+DT_MACHINE_START(BCM_CYGNUS_DT, "Broadcom Cygnus SoC")
+ .l2c_aux_val = 0,
+ .l2c_aux_mask = ~0,
+ .dt_compat = bcm_cygnus_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-bcm/bcm_kona_smc.c b/arch/arm/mach-bcm/bcm_kona_smc.c
new file mode 100644
index 000000000..a55a7ecf1
--- /dev/null
+++ b/arch/arm/mach-bcm/bcm_kona_smc.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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 <stdarg.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+
+#include <asm/cacheflush.h>
+#include <linux/of_address.h>
+
+#include "bcm_kona_smc.h"
+
+static u32 bcm_smc_buffer_phys; /* physical address */
+static void __iomem *bcm_smc_buffer; /* virtual address */
+
+struct bcm_kona_smc_data {
+ unsigned service_id;
+ unsigned arg0;
+ unsigned arg1;
+ unsigned arg2;
+ unsigned arg3;
+ unsigned result;
+};
+
+static const struct of_device_id bcm_kona_smc_ids[] __initconst = {
+ {.compatible = "brcm,kona-smc"},
+ {.compatible = "bcm,kona-smc"}, /* deprecated name */
+ {},
+};
+
+/* Map in the args buffer area */
+int __init bcm_kona_smc_init(void)
+{
+ struct device_node *node;
+ const __be32 *prop_val;
+ u64 prop_size = 0;
+ unsigned long buffer_size;
+ u32 buffer_phys;
+
+ /* Read buffer addr and size from the device tree node */
+ node = of_find_matching_node(NULL, bcm_kona_smc_ids);
+ if (!node)
+ return -ENODEV;
+
+ prop_val = of_get_address(node, 0, &prop_size, NULL);
+ if (!prop_val)
+ return -EINVAL;
+
+ /* We assume space for four 32-bit arguments */
+ if (prop_size < 4 * sizeof(u32) || prop_size > (u64)ULONG_MAX)
+ return -EINVAL;
+ buffer_size = (unsigned long)prop_size;
+
+ buffer_phys = be32_to_cpup(prop_val);
+ if (!buffer_phys)
+ return -EINVAL;
+
+ bcm_smc_buffer = ioremap(buffer_phys, buffer_size);
+ if (!bcm_smc_buffer)
+ return -ENOMEM;
+ bcm_smc_buffer_phys = buffer_phys;
+
+ pr_info("Kona Secure API initialized\n");
+
+ return 0;
+}
+
+/*
+ * int bcm_kona_do_smc(u32 service_id, u32 buffer_addr)
+ *
+ * Only core 0 can run the secure monitor code. If an "smc" request
+ * is initiated on a different core it must be redirected to core 0
+ * for execution. We rely on the caller to handle this.
+ *
+ * Each "smc" request supplies a service id and the address of a
+ * buffer containing parameters related to the service to be
+ * performed. A flags value defines the behavior of the level 2
+ * cache and interrupt handling while the secure monitor executes.
+ *
+ * Parameters to the "smc" request are passed in r4-r6 as follows:
+ * r4 service id
+ * r5 flags (SEC_ROM_*)
+ * r6 physical address of buffer with other parameters
+ *
+ * Execution of an "smc" request produces two distinct results.
+ *
+ * First, the secure monitor call itself (regardless of the specific
+ * service request) can succeed, or can produce an error. When an
+ * "smc" request completes this value is found in r12; it should
+ * always be SEC_EXIT_NORMAL.
+ *
+ * In addition, the particular service performed produces a result.
+ * The values that should be expected depend on the service. We
+ * therefore return this value to the caller, so it can handle the
+ * request result appropriately. This result value is found in r0
+ * when the "smc" request completes.
+ */
+static int bcm_kona_do_smc(u32 service_id, u32 buffer_phys)
+{
+ register u32 ip asm("ip"); /* Also called r12 */
+ register u32 r0 asm("r0");
+ register u32 r4 asm("r4");
+ register u32 r5 asm("r5");
+ register u32 r6 asm("r6");
+
+ r4 = service_id;
+ r5 = 0x3; /* Keep IRQ and FIQ off in SM */
+ r6 = buffer_phys;
+
+ asm volatile (
+ /* Make sure we got the registers we want */
+ __asmeq("%0", "ip")
+ __asmeq("%1", "r0")
+ __asmeq("%2", "r4")
+ __asmeq("%3", "r5")
+ __asmeq("%4", "r6")
+#ifdef REQUIRES_SEC
+ ".arch_extension sec\n"
+#endif
+ " smc #0\n"
+ : "=r" (ip), "=r" (r0)
+ : "r" (r4), "r" (r5), "r" (r6)
+ : "r1", "r2", "r3", "r7", "lr");
+
+ BUG_ON(ip != SEC_EXIT_NORMAL);
+
+ return r0;
+}
+
+/* __bcm_kona_smc() should only run on CPU 0, with pre-emption disabled */
+static void __bcm_kona_smc(void *info)
+{
+ struct bcm_kona_smc_data *data = info;
+ u32 *args = bcm_smc_buffer;
+
+ BUG_ON(smp_processor_id() != 0);
+ BUG_ON(!args);
+
+ /* Copy the four 32 bit argument values into the bounce area */
+ writel_relaxed(data->arg0, args++);
+ writel_relaxed(data->arg1, args++);
+ writel_relaxed(data->arg2, args++);
+ writel(data->arg3, args);
+
+ /* Flush caches for input data passed to Secure Monitor */
+ flush_cache_all();
+
+ /* Trap into Secure Monitor and record the request result */
+ data->result = bcm_kona_do_smc(data->service_id, bcm_smc_buffer_phys);
+}
+
+unsigned bcm_kona_smc(unsigned service_id, unsigned arg0, unsigned arg1,
+ unsigned arg2, unsigned arg3)
+{
+ struct bcm_kona_smc_data data;
+
+ data.service_id = service_id;
+ data.arg0 = arg0;
+ data.arg1 = arg1;
+ data.arg2 = arg2;
+ data.arg3 = arg3;
+ data.result = 0;
+
+ /*
+ * Due to a limitation of the secure monitor, we must use the SMP
+ * infrastructure to forward all secure monitor calls to Core 0.
+ */
+ smp_call_function_single(0, __bcm_kona_smc, &data, 1);
+
+ return data.result;
+}
diff --git a/arch/arm/mach-bcm/bcm_kona_smc.h b/arch/arm/mach-bcm/bcm_kona_smc.h
new file mode 100644
index 000000000..2e29ec67e
--- /dev/null
+++ b/arch/arm/mach-bcm/bcm_kona_smc.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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 BCM_KONA_SMC_H
+#define BCM_KONA_SMC_H
+
+#include <linux/types.h>
+
+/* Broadcom Secure Service API service IDs, return codes, and exit codes */
+#define SSAPI_ENABLE_L2_CACHE 0x01000002
+#define SEC_ROM_RET_OK 0x00000001
+#define SEC_EXIT_NORMAL 0x1
+
+extern int __init bcm_kona_smc_init(void);
+
+extern unsigned bcm_kona_smc(unsigned service_id,
+ unsigned arg0,
+ unsigned arg1,
+ unsigned arg2,
+ unsigned arg3);
+
+#endif /* BCM_KONA_SMC_H */
diff --git a/arch/arm/mach-bcm/board_bcm21664.c b/arch/arm/mach-bcm/board_bcm21664.c
new file mode 100644
index 000000000..82ad56877
--- /dev/null
+++ b/arch/arm/mach-bcm/board_bcm21664.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+
+#include "kona_l2_cache.h"
+
+#define RSTMGR_DT_STRING "brcm,bcm21664-resetmgr"
+
+#define RSTMGR_REG_WR_ACCESS_OFFSET 0
+#define RSTMGR_REG_CHIP_SOFT_RST_OFFSET 4
+
+#define RSTMGR_WR_PASSWORD 0xa5a5
+#define RSTMGR_WR_PASSWORD_SHIFT 8
+#define RSTMGR_WR_ACCESS_ENABLE 1
+
+static void bcm21664_restart(enum reboot_mode mode, const char *cmd)
+{
+ void __iomem *base;
+ struct device_node *resetmgr;
+
+ resetmgr = of_find_compatible_node(NULL, NULL, RSTMGR_DT_STRING);
+ if (!resetmgr) {
+ pr_emerg("Couldn't find " RSTMGR_DT_STRING "\n");
+ return;
+ }
+ base = of_iomap(resetmgr, 0);
+ if (!base) {
+ pr_emerg("Couldn't map " RSTMGR_DT_STRING "\n");
+ return;
+ }
+
+ /*
+ * A soft reset is triggered by writing a 0 to bit 0 of the soft reset
+ * register. To write to that register we must first write the password
+ * and the enable bit in the write access enable register.
+ */
+ writel((RSTMGR_WR_PASSWORD << RSTMGR_WR_PASSWORD_SHIFT) |
+ RSTMGR_WR_ACCESS_ENABLE,
+ base + RSTMGR_REG_WR_ACCESS_OFFSET);
+ writel(0, base + RSTMGR_REG_CHIP_SOFT_RST_OFFSET);
+
+ /* Wait for reset */
+ while (1);
+}
+
+static void __init bcm21664_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ kona_l2_cache_init();
+}
+
+static const char * const bcm21664_dt_compat[] = {
+ "brcm,bcm21664",
+ NULL,
+};
+
+DT_MACHINE_START(BCM21664_DT, "BCM21664 Broadcom Application Processor")
+ .init_machine = bcm21664_init,
+ .restart = bcm21664_restart,
+ .dt_compat = bcm21664_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-bcm/board_bcm281xx.c b/arch/arm/mach-bcm/board_bcm281xx.c
new file mode 100644
index 000000000..2e367bd7c
--- /dev/null
+++ b/arch/arm/mach-bcm/board_bcm281xx.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2012-2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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/clocksource.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+
+#include "kona_l2_cache.h"
+
+#define SECWDOG_OFFSET 0x00000000
+#define SECWDOG_RESERVED_MASK 0xe2000000
+#define SECWDOG_WD_LOAD_FLAG_MASK 0x10000000
+#define SECWDOG_EN_MASK 0x08000000
+#define SECWDOG_SRSTEN_MASK 0x04000000
+#define SECWDOG_CLKS_SHIFT 20
+#define SECWDOG_COUNT_SHIFT 0
+
+static void bcm281xx_restart(enum reboot_mode mode, const char *cmd)
+{
+ uint32_t val;
+ void __iomem *base;
+ struct device_node *np_wdog;
+
+ np_wdog = of_find_compatible_node(NULL, NULL, "brcm,kona-wdt");
+ if (!np_wdog) {
+ pr_emerg("Couldn't find brcm,kona-wdt\n");
+ return;
+ }
+ base = of_iomap(np_wdog, 0);
+ if (!base) {
+ pr_emerg("Couldn't map brcm,kona-wdt\n");
+ return;
+ }
+
+ /* Enable watchdog with short timeout (244us). */
+ val = readl(base + SECWDOG_OFFSET);
+ val &= SECWDOG_RESERVED_MASK | SECWDOG_WD_LOAD_FLAG_MASK;
+ val |= SECWDOG_EN_MASK | SECWDOG_SRSTEN_MASK |
+ (0x15 << SECWDOG_CLKS_SHIFT) |
+ (0x8 << SECWDOG_COUNT_SHIFT);
+ writel(val, base + SECWDOG_OFFSET);
+
+ /* Wait for reset */
+ while (1);
+}
+
+static void __init bcm281xx_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ kona_l2_cache_init();
+}
+
+static const char * const bcm281xx_dt_compat[] = {
+ "brcm,bcm11351", /* Have to use the first number upstreamed */
+ NULL,
+};
+
+DT_MACHINE_START(BCM281XX_DT, "BCM281xx Broadcom Application Processor")
+ .init_machine = bcm281xx_init,
+ .restart = bcm281xx_restart,
+ .dt_compat = bcm281xx_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c
new file mode 100644
index 000000000..70f2f3925
--- /dev/null
+++ b/arch/arm/mach-bcm/board_bcm2835.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2010 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+#include <linux/irqchip.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/clk/bcm2835.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#define PM_RSTC 0x1c
+#define PM_RSTS 0x20
+#define PM_WDOG 0x24
+
+#define PM_PASSWORD 0x5a000000
+#define PM_RSTC_WRCFG_MASK 0x00000030
+#define PM_RSTC_WRCFG_FULL_RESET 0x00000020
+#define PM_RSTS_HADWRH_SET 0x00000040
+
+#define BCM2835_PERIPH_PHYS 0x20000000
+#define BCM2835_PERIPH_VIRT 0xf0000000
+#define BCM2835_PERIPH_SIZE SZ_16M
+
+static void __iomem *wdt_regs;
+
+/*
+ * The machine restart method can be called from an atomic context so we won't
+ * be able to ioremap the regs then.
+ */
+static void bcm2835_setup_restart(void)
+{
+ struct device_node *np = of_find_compatible_node(NULL, NULL,
+ "brcm,bcm2835-pm-wdt");
+ if (WARN(!np, "unable to setup watchdog restart"))
+ return;
+
+ wdt_regs = of_iomap(np, 0);
+ WARN(!wdt_regs, "failed to remap watchdog regs");
+}
+
+static void bcm2835_restart(enum reboot_mode mode, const char *cmd)
+{
+ u32 val;
+
+ if (!wdt_regs)
+ return;
+
+ /* use a timeout of 10 ticks (~150us) */
+ writel_relaxed(10 | PM_PASSWORD, wdt_regs + PM_WDOG);
+ val = readl_relaxed(wdt_regs + PM_RSTC);
+ val &= ~PM_RSTC_WRCFG_MASK;
+ val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET;
+ writel_relaxed(val, wdt_regs + PM_RSTC);
+
+ /* No sleeping, possibly atomic. */
+ mdelay(1);
+}
+
+/*
+ * We can't really power off, but if we do the normal reset scheme, and
+ * indicate to bootcode.bin not to reboot, then most of the chip will be
+ * powered off.
+ */
+static void bcm2835_power_off(void)
+{
+ u32 val;
+
+ /*
+ * We set the watchdog hard reset bit here to distinguish this reset
+ * from the normal (full) reset. bootcode.bin will not reboot after a
+ * hard reset.
+ */
+ val = readl_relaxed(wdt_regs + PM_RSTS);
+ val &= ~PM_RSTC_WRCFG_MASK;
+ val |= PM_PASSWORD | PM_RSTS_HADWRH_SET;
+ writel_relaxed(val, wdt_regs + PM_RSTS);
+
+ /* Continue with normal reset mechanism */
+ bcm2835_restart(REBOOT_HARD, "");
+}
+
+static struct map_desc io_map __initdata = {
+ .virtual = BCM2835_PERIPH_VIRT,
+ .pfn = __phys_to_pfn(BCM2835_PERIPH_PHYS),
+ .length = BCM2835_PERIPH_SIZE,
+ .type = MT_DEVICE
+};
+
+static void __init bcm2835_map_io(void)
+{
+ iotable_init(&io_map, 1);
+}
+
+static void __init bcm2835_init(void)
+{
+ int ret;
+
+ bcm2835_setup_restart();
+ if (wdt_regs)
+ pm_power_off = bcm2835_power_off;
+
+ bcm2835_init_clocks();
+
+ ret = of_platform_populate(NULL, of_default_bus_match_table, NULL,
+ NULL);
+ if (ret) {
+ pr_err("of_platform_populate failed: %d\n", ret);
+ BUG();
+ }
+}
+
+static const char * const bcm2835_compat[] = {
+ "brcm,bcm2835",
+ NULL
+};
+
+DT_MACHINE_START(BCM2835, "BCM2835")
+ .map_io = bcm2835_map_io,
+ .init_irq = irqchip_init,
+ .init_machine = bcm2835_init,
+ .restart = bcm2835_restart,
+ .dt_compat = bcm2835_compat
+MACHINE_END
diff --git a/arch/arm/mach-bcm/brcmstb.c b/arch/arm/mach-bcm/brcmstb.c
new file mode 100644
index 000000000..3a60f7ee3
--- /dev/null
+++ b/arch/arm/mach-bcm/brcmstb.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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/of_platform.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static const char *const brcmstb_match[] __initconst = {
+ "brcm,bcm7445",
+ "brcm,brcmstb",
+ NULL
+};
+
+DT_MACHINE_START(BRCMSTB, "Broadcom STB (Flattened Device Tree)")
+ .dt_compat = brcmstb_match,
+MACHINE_END
diff --git a/arch/arm/mach-bcm/brcmstb.h b/arch/arm/mach-bcm/brcmstb.h
new file mode 100644
index 000000000..ec0c3d112
--- /dev/null
+++ b/arch/arm/mach-bcm/brcmstb.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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 __BRCMSTB_H__
+#define __BRCMSTB_H__
+
+void brcmstb_secondary_startup(void);
+
+#endif /* __BRCMSTB_H__ */
diff --git a/arch/arm/mach-bcm/headsmp-brcmstb.S b/arch/arm/mach-bcm/headsmp-brcmstb.S
new file mode 100644
index 000000000..199c1ea58
--- /dev/null
+++ b/arch/arm/mach-bcm/headsmp-brcmstb.S
@@ -0,0 +1,33 @@
+/*
+ * SMP boot code for secondary CPUs
+ * Based on arch/arm/mach-tegra/headsmp.S
+ *
+ * Copyright (C) 2010 NVIDIA, Inc.
+ * Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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 <asm/assembler.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+ .section ".text.head", "ax"
+
+ENTRY(brcmstb_secondary_startup)
+ /*
+ * Ensure CPU is in a sane state by disabling all IRQs and switching
+ * into SVC mode.
+ */
+ setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r0
+
+ bl v7_invalidate_l1
+ b secondary_startup
+ENDPROC(brcmstb_secondary_startup)
diff --git a/arch/arm/mach-bcm/kona_l2_cache.c b/arch/arm/mach-bcm/kona_l2_cache.c
new file mode 100644
index 000000000..b31970377
--- /dev/null
+++ b/arch/arm/mach-bcm/kona_l2_cache.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012-2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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/printk.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "bcm_kona_smc.h"
+
+void __init kona_l2_cache_init(void)
+{
+ unsigned int result;
+ int ret;
+
+ ret = bcm_kona_smc_init();
+ if (ret) {
+ pr_info("Secure API not available (%d). Skipping L2 init.\n",
+ ret);
+ return;
+ }
+
+ result = bcm_kona_smc(SSAPI_ENABLE_L2_CACHE, 0, 0, 0, 0);
+ if (result != SEC_ROM_RET_OK) {
+ pr_err("Secure Monitor call failed (%u)! Skipping L2 init.\n",
+ result);
+ return;
+ }
+
+ /*
+ * The aux_val and aux_mask have no effect since L2 cache is already
+ * enabled. Pass 0s for aux_val and 1s for aux_mask for default value.
+ */
+ ret = l2x0_of_init(0, ~0);
+ if (ret)
+ pr_err("Couldn't enable L2 cache: %d\n", ret);
+}
diff --git a/arch/arm/mach-bcm/kona_l2_cache.h b/arch/arm/mach-bcm/kona_l2_cache.h
new file mode 100644
index 000000000..46f84a95a
--- /dev/null
+++ b/arch/arm/mach-bcm/kona_l2_cache.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2012-2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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.
+ */
+
+#ifdef CONFIG_ARCH_BCM_MOBILE_L2_CACHE
+void kona_l2_cache_init(void);
+#else
+#define kona_l2_cache_init() ((void)0)
+#endif
diff --git a/arch/arm/mach-bcm/kona_smp.c b/arch/arm/mach-bcm/kona_smp.c
new file mode 100644
index 000000000..66a046552
--- /dev/null
+++ b/arch/arm/mach-bcm/kona_smp.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2014 Broadcom Corporation
+ * Copyright 2014 Linaro 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 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/errno.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/sched.h>
+
+#include <asm/smp.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+/* Size of mapped Cortex A9 SCU address space */
+#define CORTEX_A9_SCU_SIZE 0x58
+
+#define SECONDARY_TIMEOUT_NS NSEC_PER_MSEC /* 1 msec (in nanoseconds) */
+#define BOOT_ADDR_CPUID_MASK 0x3
+
+/* Name of device node property defining secondary boot register location */
+#define OF_SECONDARY_BOOT "secondary-boot-reg"
+
+/* I/O address of register used to coordinate secondary core startup */
+static u32 secondary_boot;
+
+/*
+ * Enable the Cortex A9 Snoop Control Unit
+ *
+ * By the time this is called we already know there are multiple
+ * cores present. We assume we're running on a Cortex A9 processor,
+ * so any trouble getting the base address register or getting the
+ * SCU base is a problem.
+ *
+ * Return 0 if successful or an error code otherwise.
+ */
+static int __init scu_a9_enable(void)
+{
+ unsigned long config_base;
+ void __iomem *scu_base;
+
+ if (!scu_a9_has_base()) {
+ pr_err("no configuration base address register!\n");
+ return -ENXIO;
+ }
+
+ /* Config base address register value is zero for uniprocessor */
+ config_base = scu_a9_get_base();
+ if (!config_base) {
+ pr_err("hardware reports only one core\n");
+ return -ENOENT;
+ }
+
+ scu_base = ioremap((phys_addr_t)config_base, CORTEX_A9_SCU_SIZE);
+ if (!scu_base) {
+ pr_err("failed to remap config base (%lu/%u) for SCU\n",
+ config_base, CORTEX_A9_SCU_SIZE);
+ return -ENOMEM;
+ }
+
+ scu_enable(scu_base);
+
+ iounmap(scu_base); /* That's the last we'll need of this */
+
+ return 0;
+}
+
+static void __init bcm_smp_prepare_cpus(unsigned int max_cpus)
+{
+ static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
+ struct device_node *node;
+ int ret;
+
+ BUG_ON(secondary_boot); /* We're called only once */
+
+ /*
+ * This function is only called via smp_ops->smp_prepare_cpu().
+ * That only happens if a "/cpus" device tree node exists
+ * and has an "enable-method" property that selects the SMP
+ * operations defined herein.
+ */
+ node = of_find_node_by_path("/cpus");
+ BUG_ON(!node);
+
+ /*
+ * Our secondary enable method requires a "secondary-boot-reg"
+ * property to specify a register address used to request the
+ * ROM code boot a secondary code. If we have any trouble
+ * getting this we fall back to uniprocessor mode.
+ */
+ if (of_property_read_u32(node, OF_SECONDARY_BOOT, &secondary_boot)) {
+ pr_err("%s: missing/invalid " OF_SECONDARY_BOOT " property\n",
+ node->name);
+ ret = -ENOENT; /* Arrange to disable SMP */
+ goto out;
+ }
+
+ /*
+ * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is
+ * returned, the SoC reported a uniprocessor configuration.
+ * We bail on any other error.
+ */
+ ret = scu_a9_enable();
+out:
+ of_node_put(node);
+ if (ret) {
+ /* Update the CPU present map to reflect uniprocessor mode */
+ BUG_ON(ret != -ENOENT);
+ pr_warn("disabling SMP\n");
+ init_cpu_present(&only_cpu_0);
+ }
+}
+
+/*
+ * The ROM code has the secondary cores looping, waiting for an event.
+ * When an event occurs each core examines the bottom two bits of the
+ * secondary boot register. When a core finds those bits contain its
+ * own core id, it performs initialization, including computing its boot
+ * address by clearing the boot register value's bottom two bits. The
+ * core signals that it is beginning its execution by writing its boot
+ * address back to the secondary boot register, and finally jumps to
+ * that address.
+ *
+ * So to start a core executing we need to:
+ * - Encode the (hardware) CPU id with the bottom bits of the secondary
+ * start address.
+ * - Write that value into the secondary boot register.
+ * - Generate an event to wake up the secondary CPU(s).
+ * - Wait for the secondary boot register to be re-written, which
+ * indicates the secondary core has started.
+ */
+static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ void __iomem *boot_reg;
+ phys_addr_t boot_func;
+ u64 start_clock;
+ u32 cpu_id;
+ u32 boot_val;
+ bool timeout = false;
+
+ cpu_id = cpu_logical_map(cpu);
+ if (cpu_id & ~BOOT_ADDR_CPUID_MASK) {
+ pr_err("bad cpu id (%u > %u)\n", cpu_id, BOOT_ADDR_CPUID_MASK);
+ return -EINVAL;
+ }
+
+ if (!secondary_boot) {
+ pr_err("required secondary boot register not specified\n");
+ return -EINVAL;
+ }
+
+ boot_reg = ioremap_nocache((phys_addr_t)secondary_boot, sizeof(u32));
+ if (!boot_reg) {
+ pr_err("unable to map boot register for cpu %u\n", cpu_id);
+ return -ENOSYS;
+ }
+
+ /*
+ * Secondary cores will start in secondary_startup(),
+ * defined in "arch/arm/kernel/head.S"
+ */
+ boot_func = virt_to_phys(secondary_startup);
+ BUG_ON(boot_func & BOOT_ADDR_CPUID_MASK);
+ BUG_ON(boot_func > (phys_addr_t)U32_MAX);
+
+ /* The core to start is encoded in the low bits */
+ boot_val = (u32)boot_func | cpu_id;
+ writel_relaxed(boot_val, boot_reg);
+
+ sev();
+
+ /* The low bits will be cleared once the core has started */
+ start_clock = local_clock();
+ while (!timeout && readl_relaxed(boot_reg) == boot_val)
+ timeout = local_clock() - start_clock > SECONDARY_TIMEOUT_NS;
+
+ iounmap(boot_reg);
+
+ if (!timeout)
+ return 0;
+
+ pr_err("timeout waiting for cpu %u to start\n", cpu_id);
+
+ return -ENOSYS;
+}
+
+static struct smp_operations bcm_smp_ops __initdata = {
+ .smp_prepare_cpus = bcm_smp_prepare_cpus,
+ .smp_boot_secondary = bcm_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method",
+ &bcm_smp_ops);
diff --git a/arch/arm/mach-bcm/platsmp-brcmstb.c b/arch/arm/mach-bcm/platsmp-brcmstb.c
new file mode 100644
index 000000000..e209e6fc7
--- /dev/null
+++ b/arch/arm/mach-bcm/platsmp-brcmstb.c
@@ -0,0 +1,370 @@
+/*
+ * Broadcom STB CPU SMP and hotplug support for ARM
+ *
+ * Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/printk.h>
+#include <linux/regmap.h>
+#include <linux/smp.h>
+#include <linux/mfd/syscon.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+#include <asm/mach-types.h>
+#include <asm/smp_plat.h>
+
+#include "brcmstb.h"
+
+enum {
+ ZONE_MAN_CLKEN_MASK = BIT(0),
+ ZONE_MAN_RESET_CNTL_MASK = BIT(1),
+ ZONE_MAN_MEM_PWR_MASK = BIT(4),
+ ZONE_RESERVED_1_MASK = BIT(5),
+ ZONE_MAN_ISO_CNTL_MASK = BIT(6),
+ ZONE_MANUAL_CONTROL_MASK = BIT(7),
+ ZONE_PWR_DN_REQ_MASK = BIT(9),
+ ZONE_PWR_UP_REQ_MASK = BIT(10),
+ ZONE_BLK_RST_ASSERT_MASK = BIT(12),
+ ZONE_PWR_OFF_STATE_MASK = BIT(25),
+ ZONE_PWR_ON_STATE_MASK = BIT(26),
+ ZONE_DPG_PWR_STATE_MASK = BIT(28),
+ ZONE_MEM_PWR_STATE_MASK = BIT(29),
+ ZONE_RESET_STATE_MASK = BIT(31),
+ CPU0_PWR_ZONE_CTRL_REG = 1,
+ CPU_RESET_CONFIG_REG = 2,
+};
+
+static void __iomem *cpubiuctrl_block;
+static void __iomem *hif_cont_block;
+static u32 cpu0_pwr_zone_ctrl_reg;
+static u32 cpu_rst_cfg_reg;
+static u32 hif_cont_reg;
+
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * We must quiesce a dying CPU before it can be killed by the boot CPU. Because
+ * one or more cache may be disabled, we must flush to ensure coherency. We
+ * cannot use traditionl completion structures or spinlocks as they rely on
+ * coherency.
+ */
+static DEFINE_PER_CPU_ALIGNED(int, per_cpu_sw_state);
+
+static int per_cpu_sw_state_rd(u32 cpu)
+{
+ sync_cache_r(SHIFT_PERCPU_PTR(&per_cpu_sw_state, per_cpu_offset(cpu)));
+ return per_cpu(per_cpu_sw_state, cpu);
+}
+
+static void per_cpu_sw_state_wr(u32 cpu, int val)
+{
+ dmb();
+ per_cpu(per_cpu_sw_state, cpu) = val;
+ sync_cache_w(SHIFT_PERCPU_PTR(&per_cpu_sw_state, per_cpu_offset(cpu)));
+}
+#else
+static inline void per_cpu_sw_state_wr(u32 cpu, int val) { }
+#endif
+
+static void __iomem *pwr_ctrl_get_base(u32 cpu)
+{
+ void __iomem *base = cpubiuctrl_block + cpu0_pwr_zone_ctrl_reg;
+ base += (cpu_logical_map(cpu) * 4);
+ return base;
+}
+
+static u32 pwr_ctrl_rd(u32 cpu)
+{
+ void __iomem *base = pwr_ctrl_get_base(cpu);
+ return readl_relaxed(base);
+}
+
+static void pwr_ctrl_set(unsigned int cpu, u32 val, u32 mask)
+{
+ void __iomem *base = pwr_ctrl_get_base(cpu);
+ writel((readl(base) & mask) | val, base);
+}
+
+static void pwr_ctrl_clr(unsigned int cpu, u32 val, u32 mask)
+{
+ void __iomem *base = pwr_ctrl_get_base(cpu);
+ writel((readl(base) & mask) & ~val, base);
+}
+
+#define POLL_TMOUT_MS 500
+static int pwr_ctrl_wait_tmout(unsigned int cpu, u32 set, u32 mask)
+{
+ const unsigned long timeo = jiffies + msecs_to_jiffies(POLL_TMOUT_MS);
+ u32 tmp;
+
+ do {
+ tmp = pwr_ctrl_rd(cpu) & mask;
+ if (!set == !tmp)
+ return 0;
+ } while (time_before(jiffies, timeo));
+
+ tmp = pwr_ctrl_rd(cpu) & mask;
+ if (!set == !tmp)
+ return 0;
+
+ return -ETIMEDOUT;
+}
+
+static void cpu_rst_cfg_set(u32 cpu, int set)
+{
+ u32 val;
+ val = readl_relaxed(cpubiuctrl_block + cpu_rst_cfg_reg);
+ if (set)
+ val |= BIT(cpu_logical_map(cpu));
+ else
+ val &= ~BIT(cpu_logical_map(cpu));
+ writel_relaxed(val, cpubiuctrl_block + cpu_rst_cfg_reg);
+}
+
+static void cpu_set_boot_addr(u32 cpu, unsigned long boot_addr)
+{
+ const int reg_ofs = cpu_logical_map(cpu) * 8;
+ writel_relaxed(0, hif_cont_block + hif_cont_reg + reg_ofs);
+ writel_relaxed(boot_addr, hif_cont_block + hif_cont_reg + 4 + reg_ofs);
+}
+
+static void brcmstb_cpu_boot(u32 cpu)
+{
+ /* Mark this CPU as "up" */
+ per_cpu_sw_state_wr(cpu, 1);
+
+ /*
+ * Set the reset vector to point to the secondary_startup
+ * routine
+ */
+ cpu_set_boot_addr(cpu, virt_to_phys(brcmstb_secondary_startup));
+
+ /* Unhalt the cpu */
+ cpu_rst_cfg_set(cpu, 0);
+}
+
+static void brcmstb_cpu_power_on(u32 cpu)
+{
+ /*
+ * The secondary cores power was cut, so we must go through
+ * power-on initialization.
+ */
+ pwr_ctrl_set(cpu, ZONE_MAN_ISO_CNTL_MASK, 0xffffff00);
+ pwr_ctrl_set(cpu, ZONE_MANUAL_CONTROL_MASK, -1);
+ pwr_ctrl_set(cpu, ZONE_RESERVED_1_MASK, -1);
+
+ pwr_ctrl_set(cpu, ZONE_MAN_MEM_PWR_MASK, -1);
+
+ if (pwr_ctrl_wait_tmout(cpu, 1, ZONE_MEM_PWR_STATE_MASK))
+ panic("ZONE_MEM_PWR_STATE_MASK set timeout");
+
+ pwr_ctrl_set(cpu, ZONE_MAN_CLKEN_MASK, -1);
+
+ if (pwr_ctrl_wait_tmout(cpu, 1, ZONE_DPG_PWR_STATE_MASK))
+ panic("ZONE_DPG_PWR_STATE_MASK set timeout");
+
+ pwr_ctrl_clr(cpu, ZONE_MAN_ISO_CNTL_MASK, -1);
+ pwr_ctrl_set(cpu, ZONE_MAN_RESET_CNTL_MASK, -1);
+}
+
+static int brcmstb_cpu_get_power_state(u32 cpu)
+{
+ int tmp = pwr_ctrl_rd(cpu);
+ return (tmp & ZONE_RESET_STATE_MASK) ? 0 : 1;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+static void brcmstb_cpu_die(u32 cpu)
+{
+ v7_exit_coherency_flush(all);
+
+ per_cpu_sw_state_wr(cpu, 0);
+
+ /* Sit and wait to die */
+ wfi();
+
+ /* We should never get here... */
+ while (1)
+ ;
+}
+
+static int brcmstb_cpu_kill(u32 cpu)
+{
+ /*
+ * Ordinarily, the hardware forbids power-down of CPU0 (which is good
+ * because it is the boot CPU), but this is not true when using BPCM
+ * manual mode. Consequently, we must avoid turning off CPU0 here to
+ * ensure that TI2C master reset will work.
+ */
+ if (cpu == 0) {
+ pr_warn("SMP: refusing to power off CPU0\n");
+ return 1;
+ }
+
+ while (per_cpu_sw_state_rd(cpu))
+ ;
+
+ pwr_ctrl_set(cpu, ZONE_MANUAL_CONTROL_MASK, -1);
+ pwr_ctrl_clr(cpu, ZONE_MAN_RESET_CNTL_MASK, -1);
+ pwr_ctrl_clr(cpu, ZONE_MAN_CLKEN_MASK, -1);
+ pwr_ctrl_set(cpu, ZONE_MAN_ISO_CNTL_MASK, -1);
+ pwr_ctrl_clr(cpu, ZONE_MAN_MEM_PWR_MASK, -1);
+
+ if (pwr_ctrl_wait_tmout(cpu, 0, ZONE_MEM_PWR_STATE_MASK))
+ panic("ZONE_MEM_PWR_STATE_MASK clear timeout");
+
+ pwr_ctrl_clr(cpu, ZONE_RESERVED_1_MASK, -1);
+
+ if (pwr_ctrl_wait_tmout(cpu, 0, ZONE_DPG_PWR_STATE_MASK))
+ panic("ZONE_DPG_PWR_STATE_MASK clear timeout");
+
+ /* Flush pipeline before resetting CPU */
+ mb();
+
+ /* Assert reset on the CPU */
+ cpu_rst_cfg_set(cpu, 1);
+
+ return 1;
+}
+
+#endif /* CONFIG_HOTPLUG_CPU */
+
+static int __init setup_hifcpubiuctrl_regs(struct device_node *np)
+{
+ int rc = 0;
+ char *name;
+ struct device_node *syscon_np = NULL;
+
+ name = "syscon-cpu";
+
+ syscon_np = of_parse_phandle(np, name, 0);
+ if (!syscon_np) {
+ pr_err("can't find phandle %s\n", name);
+ rc = -EINVAL;
+ goto cleanup;
+ }
+
+ cpubiuctrl_block = of_iomap(syscon_np, 0);
+ if (!cpubiuctrl_block) {
+ pr_err("iomap failed for cpubiuctrl_block\n");
+ rc = -EINVAL;
+ goto cleanup;
+ }
+
+ rc = of_property_read_u32_index(np, name, CPU0_PWR_ZONE_CTRL_REG,
+ &cpu0_pwr_zone_ctrl_reg);
+ if (rc) {
+ pr_err("failed to read 1st entry from %s property (%d)\n", name,
+ rc);
+ rc = -EINVAL;
+ goto cleanup;
+ }
+
+ rc = of_property_read_u32_index(np, name, CPU_RESET_CONFIG_REG,
+ &cpu_rst_cfg_reg);
+ if (rc) {
+ pr_err("failed to read 2nd entry from %s property (%d)\n", name,
+ rc);
+ rc = -EINVAL;
+ goto cleanup;
+ }
+
+cleanup:
+ of_node_put(syscon_np);
+ return rc;
+}
+
+static int __init setup_hifcont_regs(struct device_node *np)
+{
+ int rc = 0;
+ char *name;
+ struct device_node *syscon_np = NULL;
+
+ name = "syscon-cont";
+
+ syscon_np = of_parse_phandle(np, name, 0);
+ if (!syscon_np) {
+ pr_err("can't find phandle %s\n", name);
+ rc = -EINVAL;
+ goto cleanup;
+ }
+
+ hif_cont_block = of_iomap(syscon_np, 0);
+ if (!hif_cont_block) {
+ pr_err("iomap failed for hif_cont_block\n");
+ rc = -EINVAL;
+ goto cleanup;
+ }
+
+ /* Offset is at top of hif_cont_block */
+ hif_cont_reg = 0;
+
+cleanup:
+ of_node_put(syscon_np);
+ return rc;
+}
+
+static void __init brcmstb_cpu_ctrl_setup(unsigned int max_cpus)
+{
+ int rc;
+ struct device_node *np;
+ char *name;
+
+ name = "brcm,brcmstb-smpboot";
+ np = of_find_compatible_node(NULL, NULL, name);
+ if (!np) {
+ pr_err("can't find compatible node %s\n", name);
+ return;
+ }
+
+ rc = setup_hifcpubiuctrl_regs(np);
+ if (rc)
+ return;
+
+ rc = setup_hifcont_regs(np);
+ if (rc)
+ return;
+}
+
+static int brcmstb_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ /* Missing the brcm,brcmstb-smpboot DT node? */
+ if (!cpubiuctrl_block || !hif_cont_block)
+ return -ENODEV;
+
+ /* Bring up power to the core if necessary */
+ if (brcmstb_cpu_get_power_state(cpu) == 0)
+ brcmstb_cpu_power_on(cpu);
+
+ brcmstb_cpu_boot(cpu);
+
+ return 0;
+}
+
+static struct smp_operations brcmstb_smp_ops __initdata = {
+ .smp_prepare_cpus = brcmstb_cpu_ctrl_setup,
+ .smp_boot_secondary = brcmstb_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_kill = brcmstb_cpu_kill,
+ .cpu_die = brcmstb_cpu_die,
+#endif
+};
+
+CPU_METHOD_OF_DECLARE(brcmstb_smp, "brcm,brahma-b15", &brcmstb_smp_ops);
diff --git a/arch/arm/mach-berlin/Kconfig b/arch/arm/mach-berlin/Kconfig
new file mode 100644
index 000000000..3e40a947f
--- /dev/null
+++ b/arch/arm/mach-berlin/Kconfig
@@ -0,0 +1,35 @@
+menuconfig ARCH_BERLIN
+ bool "Marvell Berlin SoCs" if ARCH_MULTI_V7
+ select ARCH_HAS_RESET_CONTROLLER
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_GIC
+ select DW_APB_ICTL
+ select DW_APB_TIMER_OF
+ select GENERIC_IRQ_CHIP
+ select PINCTRL
+
+if ARCH_BERLIN
+
+config MACH_BERLIN_BG2
+ bool "Marvell Armada 1500 (BG2)"
+ select CACHE_L2X0
+ select CPU_PJ4B
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select HAVE_SMP
+ select PINCTRL_BERLIN_BG2
+
+config MACH_BERLIN_BG2CD
+ bool "Marvell Armada 1500-mini (BG2CD)"
+ select CACHE_L2X0
+ select HAVE_ARM_TWD if SMP
+ select PINCTRL_BERLIN_BG2CD
+
+config MACH_BERLIN_BG2Q
+ bool "Marvell Armada 1500 Pro (BG2-Q)"
+ select CACHE_L2X0
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select PINCTRL_BERLIN_BG2Q
+
+endif
diff --git a/arch/arm/mach-berlin/Makefile b/arch/arm/mach-berlin/Makefile
new file mode 100644
index 000000000..c0719ecd1
--- /dev/null
+++ b/arch/arm/mach-berlin/Makefile
@@ -0,0 +1,2 @@
+obj-y += berlin.o
+obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/mach-berlin/berlin.c b/arch/arm/mach-berlin/berlin.c
new file mode 100644
index 000000000..ac181c679
--- /dev/null
+++ b/arch/arm/mach-berlin/berlin.c
@@ -0,0 +1,34 @@
+/*
+ * Device Tree support for Marvell Berlin SoCs.
+ *
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * based on GPL'ed 2.6 kernel sources
+ * (c) Marvell International 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.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of_platform.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/arch.h>
+
+static const char * const berlin_dt_compat[] = {
+ "marvell,berlin",
+ NULL,
+};
+
+DT_MACHINE_START(BERLIN_DT, "Marvell Berlin")
+ .dt_compat = berlin_dt_compat,
+ /*
+ * with DT probing for L2CCs, berlin_init_machine can be removed.
+ * Note: 88DE3005 (Armada 1500-mini) uses pl310 l2cc
+ */
+ .l2c_aux_val = 0x30c00000,
+ .l2c_aux_mask = 0xfeffffff,
+MACHINE_END
diff --git a/arch/arm/mach-berlin/headsmp.S b/arch/arm/mach-berlin/headsmp.S
new file mode 100644
index 000000000..4a4c56a58
--- /dev/null
+++ b/arch/arm/mach-berlin/headsmp.S
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2014 Marvell Technology Group Ltd.
+ *
+ * Antoine TĂ©nart <antoine.tenart@free-electrons.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>
+
+ENTRY(berlin_secondary_startup)
+ ARM_BE8(setend be)
+ bl v7_invalidate_l1
+ b secondary_startup
+ENDPROC(berlin_secondary_startup)
+
+/*
+ * If the following instruction is set in the reset exception vector, CPUs
+ * will fetch the value of the software reset address vector when being
+ * reset.
+ */
+.global boot_inst
+boot_inst:
+ ldr pc, [pc, #140]
+
+ .align
diff --git a/arch/arm/mach-berlin/platsmp.c b/arch/arm/mach-berlin/platsmp.c
new file mode 100644
index 000000000..702e79820
--- /dev/null
+++ b/arch/arm/mach-berlin/platsmp.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2014 Marvell Technology Group Ltd.
+ *
+ * Antoine TĂ©nart <antoine.tenart@free-electrons.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/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+#define CPU_RESET 0x00
+
+#define RESET_VECT 0x00
+#define SW_RESET_ADDR 0x94
+
+extern void berlin_secondary_startup(void);
+extern u32 boot_inst;
+
+static void __iomem *cpu_ctrl;
+
+static inline void berlin_perform_reset_cpu(unsigned int cpu)
+{
+ u32 val;
+
+ val = readl(cpu_ctrl + CPU_RESET);
+ val |= BIT(cpu_logical_map(cpu));
+ writel(val, cpu_ctrl + CPU_RESET);
+}
+
+static int berlin_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ if (!cpu_ctrl)
+ return -EFAULT;
+
+ /*
+ * Reset the CPU, making it to execute the instruction in the reset
+ * exception vector.
+ */
+ berlin_perform_reset_cpu(cpu);
+
+ return 0;
+}
+
+static void __init berlin_smp_prepare_cpus(unsigned int max_cpus)
+{
+ struct device_node *np;
+ void __iomem *scu_base;
+ void __iomem *vectors_base;
+
+ np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+ scu_base = of_iomap(np, 0);
+ of_node_put(np);
+ if (!scu_base)
+ return;
+
+ np = of_find_compatible_node(NULL, NULL, "marvell,berlin-cpu-ctrl");
+ cpu_ctrl = of_iomap(np, 0);
+ of_node_put(np);
+ if (!cpu_ctrl)
+ goto unmap_scu;
+
+ vectors_base = ioremap(CONFIG_VECTORS_BASE, SZ_32K);
+ if (!vectors_base)
+ goto unmap_scu;
+
+ scu_enable(scu_base);
+ flush_cache_all();
+
+ /*
+ * Write the first instruction the CPU will execute after being reset
+ * in the reset exception vector.
+ */
+ writel(boot_inst, vectors_base + RESET_VECT);
+
+ /*
+ * Write the secondary startup address into the SW reset address
+ * vector. This is used by boot_inst.
+ */
+ writel(virt_to_phys(berlin_secondary_startup), vectors_base + SW_RESET_ADDR);
+
+ iounmap(vectors_base);
+unmap_scu:
+ iounmap(scu_base);
+}
+
+static struct smp_operations berlin_smp_ops __initdata = {
+ .smp_prepare_cpus = berlin_smp_prepare_cpus,
+ .smp_boot_secondary = berlin_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(berlin_smp, "marvell,berlin-smp", &berlin_smp_ops);
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig
new file mode 100644
index 000000000..f711498c1
--- /dev/null
+++ b/arch/arm/mach-clps711x/Kconfig
@@ -0,0 +1,38 @@
+if ARCH_CLPS711X
+
+menu "CLPS711X/EP721X/EP731X 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"
+ 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_CLEP7312
+ bool "CLEP7312"
+ help
+ Boards based on the Cirrus Logic 7212/7312 chips.
+
+config ARCH_EDB7211
+ bool "EDB7211"
+ select ARCH_HAS_HOLES_MEMORYMODEL
+ 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.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-clps711x/Makefile b/arch/arm/mach-clps711x/Makefile
new file mode 100644
index 000000000..f04151efd
--- /dev/null
+++ b/arch/arm/mach-clps711x/Makefile
@@ -0,0 +1,13 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := common.o devices.o
+
+obj-$(CONFIG_ARCH_AUTCPU12) += board-autcpu12.o
+obj-$(CONFIG_ARCH_CDB89712) += board-cdb89712.o
+obj-$(CONFIG_ARCH_CLEP7312) += board-clep7312.o
+obj-$(CONFIG_ARCH_EDB7211) += board-edb7211.o
+obj-$(CONFIG_ARCH_P720T) += board-p720t.o
diff --git a/arch/arm/mach-clps711x/Makefile.boot b/arch/arm/mach-clps711x/Makefile.boot
new file mode 100644
index 000000000..eba77d35a
--- /dev/null
+++ b/arch/arm/mach-clps711x/Makefile.boot
@@ -0,0 +1,5 @@
+# The standard locations for stuff on CLPS711x type processors
+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/board-autcpu12.c b/arch/arm/mach-clps711x/board-autcpu12.c
new file mode 100644
index 000000000..45abf6bd5
--- /dev/null
+++ b/arch/arm/mach-clps711x/board-autcpu12.c
@@ -0,0 +1,275 @@
+/*
+ * 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 <linux/gpio.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand-gpio.h>
+#include <linux/platform_device.h>
+#include <linux/basic_mmio_gpio.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 "common.h"
+#include "devices.h"
+
+/* NOR flash */
+#define AUTCPU12_FLASH_BASE (CS0_PHYS_BASE)
+
+/* Board specific hardware definitions */
+#define AUTCPU12_CHAR_LCD_BASE (CS1_PHYS_BASE + 0x00000000)
+#define AUTCPU12_CSAUX1_BASE (CS1_PHYS_BASE + 0x04000000)
+#define AUTCPU12_CAN_BASE (CS1_PHYS_BASE + 0x08000000)
+#define AUTCPU12_TOUCH_BASE (CS1_PHYS_BASE + 0x0a000000)
+#define AUTCPU12_IO_BASE (CS1_PHYS_BASE + 0x0c000000)
+#define AUTCPU12_LPT_BASE (CS1_PHYS_BASE + 0x0e000000)
+
+/* NVRAM */
+#define AUTCPU12_NVRAM_BASE (CS1_PHYS_BASE + 0x02000000)
+
+/* SmartMedia flash */
+#define AUTCPU12_SMC_BASE (CS1_PHYS_BASE + 0x06000000)
+#define AUTCPU12_SMC_SEL_BASE (AUTCPU12_SMC_BASE + 0x10)
+
+/* Ethernet */
+#define AUTCPU12_CS8900_BASE (CS2_PHYS_BASE + 0x300)
+#define AUTCPU12_CS8900_IRQ (IRQ_EINT3)
+
+/* NAND flash */
+#define AUTCPU12_MMGPIO_BASE (CLPS711X_NR_GPIO)
+#define AUTCPU12_SMC_NCE (AUTCPU12_MMGPIO_BASE + 0) /* Bit 0 */
+#define AUTCPU12_SMC_RDY CLPS711X_GPIO(1, 2)
+#define AUTCPU12_SMC_ALE CLPS711X_GPIO(1, 3)
+#define AUTCPU12_SMC_CLE CLPS711X_GPIO(1, 4)
+
+/* LCD contrast digital potentiometer */
+#define AUTCPU12_DPOT_CS CLPS711X_GPIO(4, 0)
+#define AUTCPU12_DPOT_CLK CLPS711X_GPIO(4, 1)
+#define AUTCPU12_DPOT_UD CLPS711X_GPIO(4, 2)
+
+static struct resource autcpu12_cs8900_resource[] __initdata = {
+ DEFINE_RES_MEM(AUTCPU12_CS8900_BASE, SZ_1K),
+ DEFINE_RES_IRQ(AUTCPU12_CS8900_IRQ),
+};
+
+static struct resource autcpu12_nand_resource[] __initdata = {
+ DEFINE_RES_MEM(AUTCPU12_SMC_BASE, SZ_16),
+};
+
+static struct mtd_partition autcpu12_nand_parts[] __initdata = {
+ {
+ .name = "Flash partition 1",
+ .offset = 0,
+ .size = SZ_8M,
+ },
+ {
+ .name = "Flash partition 2",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static void __init autcpu12_adjust_parts(struct gpio_nand_platdata *pdata,
+ size_t sz)
+{
+ switch (sz) {
+ case SZ_16M:
+ case SZ_32M:
+ break;
+ case SZ_64M:
+ case SZ_128M:
+ pdata->parts[0].size = SZ_16M;
+ break;
+ default:
+ pr_warn("Unsupported SmartMedia device size %u\n", sz);
+ break;
+ }
+}
+
+static struct gpio_nand_platdata autcpu12_nand_pdata __initdata = {
+ .gpio_rdy = AUTCPU12_SMC_RDY,
+ .gpio_nce = AUTCPU12_SMC_NCE,
+ .gpio_ale = AUTCPU12_SMC_ALE,
+ .gpio_cle = AUTCPU12_SMC_CLE,
+ .gpio_nwp = -1,
+ .chip_delay = 20,
+ .parts = autcpu12_nand_parts,
+ .num_parts = ARRAY_SIZE(autcpu12_nand_parts),
+ .adjust_parts = autcpu12_adjust_parts,
+};
+
+static struct platform_device autcpu12_nand_pdev __initdata = {
+ .name = "gpio-nand",
+ .id = -1,
+ .resource = autcpu12_nand_resource,
+ .num_resources = ARRAY_SIZE(autcpu12_nand_resource),
+ .dev = {
+ .platform_data = &autcpu12_nand_pdata,
+ },
+};
+
+static struct resource autcpu12_mmgpio_resource[] __initdata = {
+ DEFINE_RES_MEM_NAMED(AUTCPU12_SMC_SEL_BASE, SZ_1, "dat"),
+};
+
+static struct bgpio_pdata autcpu12_mmgpio_pdata __initdata = {
+ .base = AUTCPU12_MMGPIO_BASE,
+ .ngpio = 8,
+};
+
+static struct platform_device autcpu12_mmgpio_pdev __initdata = {
+ .name = "basic-mmio-gpio",
+ .id = -1,
+ .resource = autcpu12_mmgpio_resource,
+ .num_resources = ARRAY_SIZE(autcpu12_mmgpio_resource),
+ .dev = {
+ .platform_data = &autcpu12_mmgpio_pdata,
+ },
+};
+
+static const struct gpio autcpu12_gpios[] __initconst = {
+ { AUTCPU12_DPOT_CS, GPIOF_OUT_INIT_HIGH, "DPOT CS" },
+ { AUTCPU12_DPOT_CLK, GPIOF_OUT_INIT_LOW, "DPOT CLK" },
+ { AUTCPU12_DPOT_UD, GPIOF_OUT_INIT_LOW, "DPOT UD" },
+};
+
+static struct mtd_partition autcpu12_flash_partitions[] = {
+ {
+ .name = "NOR.0",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data autcpu12_flash_pdata = {
+ .width = 4,
+ .parts = autcpu12_flash_partitions,
+ .nr_parts = ARRAY_SIZE(autcpu12_flash_partitions),
+};
+
+static struct resource autcpu12_flash_resources[] __initdata = {
+ DEFINE_RES_MEM(AUTCPU12_FLASH_BASE, SZ_8M),
+};
+
+static struct platform_device autcpu12_flash_pdev __initdata = {
+ .name = "physmap-flash",
+ .id = 0,
+ .resource = autcpu12_flash_resources,
+ .num_resources = ARRAY_SIZE(autcpu12_flash_resources),
+ .dev = {
+ .platform_data = &autcpu12_flash_pdata,
+ },
+};
+
+static struct resource autcpu12_nvram_resource[] __initdata = {
+ DEFINE_RES_MEM(AUTCPU12_NVRAM_BASE, 0),
+};
+
+static struct platdata_mtd_ram autcpu12_nvram_pdata = {
+ .bankwidth = 4,
+};
+
+static struct platform_device autcpu12_nvram_pdev __initdata = {
+ .name = "mtd-ram",
+ .id = 0,
+ .resource = autcpu12_nvram_resource,
+ .num_resources = ARRAY_SIZE(autcpu12_nvram_resource),
+ .dev = {
+ .platform_data = &autcpu12_nvram_pdata,
+ },
+};
+
+static void __init autcpu12_nvram_init(void)
+{
+ void __iomem *nvram;
+ unsigned int save[2];
+ resource_size_t nvram_size = SZ_128K;
+
+ /*
+ * Check for 32K/128K
+ * Read ofs 0K
+ * Read ofs 64K
+ * Write complement to ofs 64K
+ * Read and check result on ofs 0K
+ * Restore contents
+ */
+ nvram = ioremap(autcpu12_nvram_resource[0].start, SZ_128K);
+ if (nvram) {
+ save[0] = readl(nvram + 0);
+ save[1] = readl(nvram + SZ_64K);
+ writel(~save[0], nvram + SZ_64K);
+ if (readl(nvram + 0) != save[0]) {
+ writel(save[0], nvram + 0);
+ nvram_size = SZ_32K;
+ } else
+ writel(save[1], nvram + SZ_64K);
+ iounmap(nvram);
+
+ autcpu12_nvram_resource[0].end =
+ autcpu12_nvram_resource[0].start + nvram_size - 1;
+ platform_device_register(&autcpu12_nvram_pdev);
+ } else
+ pr_err("Failed to remap NVRAM resource\n");
+}
+
+static void __init autcpu12_init(void)
+{
+ clps711x_devices_init();
+ platform_device_register(&autcpu12_flash_pdev);
+ platform_device_register_simple("video-clps711x", 0, NULL, 0);
+ platform_device_register_simple("cs89x0", 0, autcpu12_cs8900_resource,
+ ARRAY_SIZE(autcpu12_cs8900_resource));
+ platform_device_register(&autcpu12_mmgpio_pdev);
+ autcpu12_nvram_init();
+}
+
+static void __init autcpu12_init_late(void)
+{
+ gpio_request_array(autcpu12_gpios, ARRAY_SIZE(autcpu12_gpios));
+ platform_device_register(&autcpu12_nand_pdev);
+}
+
+MACHINE_START(AUTCPU12, "autronix autcpu12")
+ /* Maintainer: Thomas Gleixner */
+ .atag_offset = 0x20000,
+ .map_io = clps711x_map_io,
+ .init_irq = clps711x_init_irq,
+ .init_time = clps711x_timer_init,
+ .init_machine = autcpu12_init,
+ .init_late = autcpu12_init_late,
+ .restart = clps711x_restart,
+MACHINE_END
+
diff --git a/arch/arm/mach-clps711x/board-cdb89712.c b/arch/arm/mach-clps711x/board-cdb89712.c
new file mode 100644
index 000000000..1ec378c33
--- /dev/null
+++ b/arch/arm/mach-clps711x/board-cdb89712.c
@@ -0,0 +1,147 @@
+/*
+ * 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 <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/mtd/partitions.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"
+#include "devices.h"
+
+#define CDB89712_CS8900_BASE (CS2_PHYS_BASE + 0x300)
+#define CDB89712_CS8900_IRQ (IRQ_EINT3)
+
+static struct resource cdb89712_cs8900_resource[] __initdata = {
+ DEFINE_RES_MEM(CDB89712_CS8900_BASE, SZ_1K),
+ DEFINE_RES_IRQ(CDB89712_CS8900_IRQ),
+};
+
+static struct mtd_partition cdb89712_flash_partitions[] __initdata = {
+ {
+ .name = "Flash",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data cdb89712_flash_pdata __initdata = {
+ .width = 4,
+ .probe_type = "map_rom",
+ .parts = cdb89712_flash_partitions,
+ .nr_parts = ARRAY_SIZE(cdb89712_flash_partitions),
+};
+
+static struct resource cdb89712_flash_resources[] __initdata = {
+ DEFINE_RES_MEM(CS0_PHYS_BASE, SZ_8M),
+};
+
+static struct platform_device cdb89712_flash_pdev __initdata = {
+ .name = "physmap-flash",
+ .id = 0,
+ .resource = cdb89712_flash_resources,
+ .num_resources = ARRAY_SIZE(cdb89712_flash_resources),
+ .dev = {
+ .platform_data = &cdb89712_flash_pdata,
+ },
+};
+
+static struct mtd_partition cdb89712_bootrom_partitions[] __initdata = {
+ {
+ .name = "BootROM",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data cdb89712_bootrom_pdata __initdata = {
+ .width = 4,
+ .probe_type = "map_rom",
+ .parts = cdb89712_bootrom_partitions,
+ .nr_parts = ARRAY_SIZE(cdb89712_bootrom_partitions),
+};
+
+static struct resource cdb89712_bootrom_resources[] __initdata = {
+ DEFINE_RES_NAMED(CS7_PHYS_BASE, SZ_128, "BOOTROM", IORESOURCE_MEM |
+ IORESOURCE_CACHEABLE | IORESOURCE_READONLY),
+};
+
+static struct platform_device cdb89712_bootrom_pdev __initdata = {
+ .name = "physmap-flash",
+ .id = 1,
+ .resource = cdb89712_bootrom_resources,
+ .num_resources = ARRAY_SIZE(cdb89712_bootrom_resources),
+ .dev = {
+ .platform_data = &cdb89712_bootrom_pdata,
+ },
+};
+
+static struct platdata_mtd_ram cdb89712_sram_pdata __initdata = {
+ .bankwidth = 4,
+};
+
+static struct resource cdb89712_sram_resources[] __initdata = {
+ DEFINE_RES_MEM(CLPS711X_SRAM_BASE, CLPS711X_SRAM_SIZE),
+};
+
+static struct platform_device cdb89712_sram_pdev __initdata = {
+ .name = "mtd-ram",
+ .id = 0,
+ .resource = cdb89712_sram_resources,
+ .num_resources = ARRAY_SIZE(cdb89712_sram_resources),
+ .dev = {
+ .platform_data = &cdb89712_sram_pdata,
+ },
+};
+
+static void __init cdb89712_init(void)
+{
+ clps711x_devices_init();
+ platform_device_register(&cdb89712_flash_pdev);
+ platform_device_register(&cdb89712_bootrom_pdev);
+ platform_device_register(&cdb89712_sram_pdev);
+ platform_device_register_simple("cs89x0", 0, cdb89712_cs8900_resource,
+ ARRAY_SIZE(cdb89712_cs8900_resource));
+}
+
+MACHINE_START(CDB89712, "Cirrus-CDB89712")
+ /* Maintainer: Ray Lehtiniemi */
+ .atag_offset = 0x100,
+ .map_io = clps711x_map_io,
+ .init_irq = clps711x_init_irq,
+ .init_time = clps711x_timer_init,
+ .init_machine = cdb89712_init,
+ .restart = clps711x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-clps711x/board-clep7312.c b/arch/arm/mach-clps711x/board-clep7312.c
new file mode 100644
index 000000000..f9ca22b64
--- /dev/null
+++ b/arch/arm/mach-clps711x/board-clep7312.c
@@ -0,0 +1,45 @@
+/*
+ * 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 <linux/memblock.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "common.h"
+#include "devices.h"
+
+static void __init
+fixup_clep7312(struct tag *tags, char **cmdline)
+{
+ memblock_add(0xc0000000, 0x01000000);
+}
+
+MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312")
+ /* Maintainer: Nobody */
+ .atag_offset = 0x0100,
+ .fixup = fixup_clep7312,
+ .map_io = clps711x_map_io,
+ .init_irq = clps711x_init_irq,
+ .init_time = clps711x_timer_init,
+ .init_machine = clps711x_devices_init,
+ .restart = clps711x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-clps711x/board-edb7211.c b/arch/arm/mach-clps711x/board-edb7211.c
new file mode 100644
index 000000000..f33979784
--- /dev/null
+++ b/arch/arm/mach-clps711x/board-edb7211.c
@@ -0,0 +1,188 @@
+/*
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/memblock.h>
+#include <linux/types.h>
+#include <linux/i2c-gpio.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/pwm_backlight.h>
+#include <linux/memblock.h>
+
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/setup.h>
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <video/platform_lcd.h>
+
+#include <mach/hardware.h>
+
+#include "common.h"
+#include "devices.h"
+
+#define VIDEORAM_SIZE SZ_128K
+
+#define EDB7211_LCD_DC_DC_EN CLPS711X_GPIO(3, 1)
+#define EDB7211_LCDEN CLPS711X_GPIO(3, 2)
+#define EDB7211_LCDBL CLPS711X_GPIO(3, 3)
+
+#define EDB7211_I2C_SDA CLPS711X_GPIO(3, 4)
+#define EDB7211_I2C_SCL CLPS711X_GPIO(3, 5)
+
+#define EDB7211_FLASH0_BASE (CS0_PHYS_BASE)
+#define EDB7211_FLASH1_BASE (CS1_PHYS_BASE)
+
+#define EDB7211_CS8900_BASE (CS2_PHYS_BASE + 0x300)
+#define EDB7211_CS8900_IRQ (IRQ_EINT3)
+
+/* The extra 8 lines of the keyboard matrix */
+#define EDB7211_EXTKBD_BASE (CS3_PHYS_BASE)
+
+static struct i2c_gpio_platform_data edb7211_i2c_pdata __initdata = {
+ .sda_pin = EDB7211_I2C_SDA,
+ .scl_pin = EDB7211_I2C_SCL,
+ .scl_is_output_only = 1,
+};
+
+static struct resource edb7211_cs8900_resource[] __initdata = {
+ DEFINE_RES_MEM(EDB7211_CS8900_BASE, SZ_1K),
+ DEFINE_RES_IRQ(EDB7211_CS8900_IRQ),
+};
+
+static struct mtd_partition edb7211_flash_partitions[] __initdata = {
+ {
+ .name = "Flash",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data edb7211_flash_pdata __initdata = {
+ .width = 4,
+ .parts = edb7211_flash_partitions,
+ .nr_parts = ARRAY_SIZE(edb7211_flash_partitions),
+};
+
+static struct resource edb7211_flash_resources[] __initdata = {
+ DEFINE_RES_MEM(EDB7211_FLASH0_BASE, SZ_8M),
+ DEFINE_RES_MEM(EDB7211_FLASH1_BASE, SZ_8M),
+};
+
+static struct platform_device edb7211_flash_pdev __initdata = {
+ .name = "physmap-flash",
+ .id = 0,
+ .resource = edb7211_flash_resources,
+ .num_resources = ARRAY_SIZE(edb7211_flash_resources),
+ .dev = {
+ .platform_data = &edb7211_flash_pdata,
+ },
+};
+
+static void edb7211_lcd_power_set(struct plat_lcd_data *pd, unsigned int power)
+{
+ if (power) {
+ gpio_set_value(EDB7211_LCDEN, 1);
+ udelay(100);
+ gpio_set_value(EDB7211_LCD_DC_DC_EN, 1);
+ } else {
+ gpio_set_value(EDB7211_LCD_DC_DC_EN, 0);
+ udelay(100);
+ gpio_set_value(EDB7211_LCDEN, 0);
+ }
+}
+
+static struct plat_lcd_data edb7211_lcd_power_pdata = {
+ .set_power = edb7211_lcd_power_set,
+};
+
+static struct pwm_lookup edb7211_pwm_lookup[] = {
+ PWM_LOOKUP("clps711x-pwm", 0, "pwm-backlight.0", NULL,
+ 0, PWM_POLARITY_NORMAL),
+};
+
+static struct platform_pwm_backlight_data pwm_bl_pdata = {
+ .dft_brightness = 0x01,
+ .max_brightness = 0x0f,
+ .enable_gpio = EDB7211_LCDBL,
+};
+
+static struct resource clps711x_pwm_res =
+ DEFINE_RES_MEM(CLPS711X_PHYS_BASE + PMPCON, SZ_4);
+
+static struct gpio edb7211_gpios[] __initconst = {
+ { EDB7211_LCD_DC_DC_EN, GPIOF_OUT_INIT_LOW, "LCD DC-DC" },
+ { EDB7211_LCDEN, GPIOF_OUT_INIT_LOW, "LCD POWER" },
+};
+
+/* Reserve screen memory region at the start of main system memory. */
+static void __init edb7211_reserve(void)
+{
+ memblock_reserve(PHYS_OFFSET, VIDEORAM_SIZE);
+}
+
+static void __init
+fixup_edb7211(struct tag *tags, char **cmdline)
+{
+ /*
+ * 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.
+ */
+ memblock_add(0xc0000000, SZ_8M);
+ memblock_add(0xc1000000, SZ_8M);
+}
+
+static void __init edb7211_init_late(void)
+{
+ gpio_request_array(edb7211_gpios, ARRAY_SIZE(edb7211_gpios));
+
+ platform_device_register(&edb7211_flash_pdev);
+
+ platform_device_register_data(NULL, "platform-lcd", 0,
+ &edb7211_lcd_power_pdata,
+ sizeof(edb7211_lcd_power_pdata));
+
+ platform_device_register_simple("clps711x-pwm", PLATFORM_DEVID_NONE,
+ &clps711x_pwm_res, 1);
+ pwm_add_table(edb7211_pwm_lookup, ARRAY_SIZE(edb7211_pwm_lookup));
+
+ platform_device_register_data(&platform_bus, "pwm-backlight", 0,
+ &pwm_bl_pdata, sizeof(pwm_bl_pdata));
+
+ platform_device_register_simple("video-clps711x", 0, NULL, 0);
+ platform_device_register_simple("cs89x0", 0, edb7211_cs8900_resource,
+ ARRAY_SIZE(edb7211_cs8900_resource));
+ platform_device_register_data(NULL, "i2c-gpio", 0,
+ &edb7211_i2c_pdata,
+ sizeof(edb7211_i2c_pdata));
+}
+
+MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
+ /* Maintainer: Jon McClintock */
+ .atag_offset = VIDEORAM_SIZE + 0x100,
+ .fixup = fixup_edb7211,
+ .reserve = edb7211_reserve,
+ .map_io = clps711x_map_io,
+ .init_irq = clps711x_init_irq,
+ .init_time = clps711x_timer_init,
+ .init_machine = clps711x_devices_init,
+ .init_late = edb7211_init_late,
+ .restart = clps711x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-clps711x/board-p720t.c b/arch/arm/mach-clps711x/board-p720t.c
new file mode 100644
index 000000000..e68dd629b
--- /dev/null
+++ b/arch/arm/mach-clps711x/board-p720t.c
@@ -0,0 +1,373 @@
+/*
+ * 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 <linux/gpio.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
+#include <linux/sizes.h>
+#include <linux/backlight.h>
+#include <linux/basic_mmio_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand-gpio.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 <video/platform_lcd.h>
+
+#include "common.h"
+#include "devices.h"
+
+#define P720T_USERLED CLPS711X_GPIO(3, 0)
+#define P720T_NAND_CLE CLPS711X_GPIO(4, 0)
+#define P720T_NAND_ALE CLPS711X_GPIO(4, 1)
+#define P720T_NAND_NCE CLPS711X_GPIO(4, 2)
+
+#define P720T_NAND_BASE (CLPS711X_SDRAM1_BASE)
+
+#define P720T_MMGPIO_BASE (CLPS711X_NR_GPIO)
+
+#define SYSPLD_PHYS_BASE IOMEM(CS1_PHYS_BASE)
+
+#define PLD_INT (SYSPLD_PHYS_BASE + 0x000000)
+#define PLD_INT_MMGPIO_BASE (P720T_MMGPIO_BASE + 0)
+#define PLD_INT_PENIRQ (PLD_INT_MMGPIO_BASE + 5)
+#define PLD_INT_UCB_IRQ (PLD_INT_MMGPIO_BASE + 1)
+#define PLD_INT_KBD_ATN (PLD_INT_MMGPIO_BASE + 0) /* EINT1 */
+
+#define PLD_PWR (SYSPLD_PHYS_BASE + 0x000004)
+#define PLD_PWR_MMGPIO_BASE (P720T_MMGPIO_BASE + 8)
+#define PLD_PWR_EXT (PLD_PWR_MMGPIO_BASE + 5)
+#define PLD_PWR_MODE (PLD_PWR_MMGPIO_BASE + 4) /* 1 = PWM, 0 = PFM */
+#define PLD_S4_ON (PLD_PWR_MMGPIO_BASE + 3) /* LCD bias voltage enable */
+#define PLD_S3_ON (PLD_PWR_MMGPIO_BASE + 2) /* LCD backlight enable */
+#define PLD_S2_ON (PLD_PWR_MMGPIO_BASE + 1) /* LCD 3V3 supply enable */
+#define PLD_S1_ON (PLD_PWR_MMGPIO_BASE + 0) /* LCD 3V supply enable */
+
+#define PLD_KBD (SYSPLD_PHYS_BASE + 0x000008)
+#define PLD_KBD_MMGPIO_BASE (P720T_MMGPIO_BASE + 16)
+#define PLD_KBD_WAKE (PLD_KBD_MMGPIO_BASE + 1)
+#define PLD_KBD_EN (PLD_KBD_MMGPIO_BASE + 0)
+
+#define PLD_SPI (SYSPLD_PHYS_BASE + 0x00000c)
+#define PLD_SPI_MMGPIO_BASE (P720T_MMGPIO_BASE + 24)
+#define PLD_SPI_EN (PLD_SPI_MMGPIO_BASE + 0)
+
+#define PLD_IO (SYSPLD_PHYS_BASE + 0x000010)
+#define PLD_IO_MMGPIO_BASE (P720T_MMGPIO_BASE + 32)
+#define PLD_IO_BOOTSEL (PLD_IO_MMGPIO_BASE + 6) /* Boot sel switch */
+#define PLD_IO_USER (PLD_IO_MMGPIO_BASE + 5) /* User defined switch */
+#define PLD_IO_LED3 (PLD_IO_MMGPIO_BASE + 4)
+#define PLD_IO_LED2 (PLD_IO_MMGPIO_BASE + 3)
+#define PLD_IO_LED1 (PLD_IO_MMGPIO_BASE + 2)
+#define PLD_IO_LED0 (PLD_IO_MMGPIO_BASE + 1)
+#define PLD_IO_LEDEN (PLD_IO_MMGPIO_BASE + 0)
+
+#define PLD_IRDA (SYSPLD_PHYS_BASE + 0x000014)
+#define PLD_IRDA_MMGPIO_BASE (P720T_MMGPIO_BASE + 40)
+#define PLD_IRDA_EN (PLD_IRDA_MMGPIO_BASE + 0)
+
+#define PLD_COM2 (SYSPLD_PHYS_BASE + 0x000018)
+#define PLD_COM2_MMGPIO_BASE (P720T_MMGPIO_BASE + 48)
+#define PLD_COM2_EN (PLD_COM2_MMGPIO_BASE + 0)
+
+#define PLD_COM1 (SYSPLD_PHYS_BASE + 0x00001c)
+#define PLD_COM1_MMGPIO_BASE (P720T_MMGPIO_BASE + 56)
+#define PLD_COM1_EN (PLD_COM1_MMGPIO_BASE + 0)
+
+#define PLD_AUD (SYSPLD_PHYS_BASE + 0x000020)
+#define PLD_AUD_MMGPIO_BASE (P720T_MMGPIO_BASE + 64)
+#define PLD_AUD_DIV1 (PLD_AUD_MMGPIO_BASE + 6)
+#define PLD_AUD_DIV0 (PLD_AUD_MMGPIO_BASE + 5)
+#define PLD_AUD_CLK_SEL1 (PLD_AUD_MMGPIO_BASE + 4)
+#define PLD_AUD_CLK_SEL0 (PLD_AUD_MMGPIO_BASE + 3)
+#define PLD_AUD_MIC_PWR (PLD_AUD_MMGPIO_BASE + 2)
+#define PLD_AUD_MIC_GAIN (PLD_AUD_MMGPIO_BASE + 1)
+#define PLD_AUD_CODEC_EN (PLD_AUD_MMGPIO_BASE + 0)
+
+#define PLD_CF (SYSPLD_PHYS_BASE + 0x000024)
+#define PLD_CF_MMGPIO_BASE (P720T_MMGPIO_BASE + 72)
+#define PLD_CF2_SLEEP (PLD_CF_MMGPIO_BASE + 5)
+#define PLD_CF1_SLEEP (PLD_CF_MMGPIO_BASE + 4)
+#define PLD_CF2_nPDREQ (PLD_CF_MMGPIO_BASE + 3)
+#define PLD_CF1_nPDREQ (PLD_CF_MMGPIO_BASE + 2)
+#define PLD_CF2_nIRQ (PLD_CF_MMGPIO_BASE + 1)
+#define PLD_CF1_nIRQ (PLD_CF_MMGPIO_BASE + 0)
+
+#define PLD_SDC (SYSPLD_PHYS_BASE + 0x000028)
+#define PLD_SDC_MMGPIO_BASE (P720T_MMGPIO_BASE + 80)
+#define PLD_SDC_INT_EN (PLD_SDC_MMGPIO_BASE + 2)
+#define PLD_SDC_WP (PLD_SDC_MMGPIO_BASE + 1)
+#define PLD_SDC_CD (PLD_SDC_MMGPIO_BASE + 0)
+
+#define PLD_CODEC (SYSPLD_PHYS_BASE + 0x400000)
+#define PLD_CODEC_MMGPIO_BASE (P720T_MMGPIO_BASE + 88)
+#define PLD_CODEC_IRQ3 (PLD_CODEC_MMGPIO_BASE + 4)
+#define PLD_CODEC_IRQ2 (PLD_CODEC_MMGPIO_BASE + 3)
+#define PLD_CODEC_IRQ1 (PLD_CODEC_MMGPIO_BASE + 2)
+#define PLD_CODEC_EN (PLD_CODEC_MMGPIO_BASE + 0)
+
+#define PLD_BRITE (SYSPLD_PHYS_BASE + 0x400004)
+#define PLD_BRITE_MMGPIO_BASE (P720T_MMGPIO_BASE + 96)
+#define PLD_BRITE_UP (PLD_BRITE_MMGPIO_BASE + 1)
+#define PLD_BRITE_DN (PLD_BRITE_MMGPIO_BASE + 0)
+
+#define PLD_LCDEN (SYSPLD_PHYS_BASE + 0x400008)
+#define PLD_LCDEN_MMGPIO_BASE (P720T_MMGPIO_BASE + 104)
+#define PLD_LCDEN_EN (PLD_LCDEN_MMGPIO_BASE + 0)
+
+#define PLD_TCH (SYSPLD_PHYS_BASE + 0x400010)
+#define PLD_TCH_MMGPIO_BASE (P720T_MMGPIO_BASE + 112)
+#define PLD_TCH_PENIRQ (PLD_TCH_MMGPIO_BASE + 1)
+#define PLD_TCH_EN (PLD_TCH_MMGPIO_BASE + 0)
+
+#define PLD_GPIO (SYSPLD_PHYS_BASE + 0x400014)
+#define PLD_GPIO_MMGPIO_BASE (P720T_MMGPIO_BASE + 120)
+#define PLD_GPIO2 (PLD_GPIO_MMGPIO_BASE + 2)
+#define PLD_GPIO1 (PLD_GPIO_MMGPIO_BASE + 1)
+#define PLD_GPIO0 (PLD_GPIO_MMGPIO_BASE + 0)
+
+static struct gpio p720t_gpios[] __initconst = {
+ { PLD_S1_ON, GPIOF_OUT_INIT_LOW, "PLD_S1_ON" },
+ { PLD_S2_ON, GPIOF_OUT_INIT_LOW, "PLD_S2_ON" },
+ { PLD_S3_ON, GPIOF_OUT_INIT_LOW, "PLD_S3_ON" },
+ { PLD_S4_ON, GPIOF_OUT_INIT_LOW, "PLD_S4_ON" },
+ { PLD_KBD_EN, GPIOF_OUT_INIT_LOW, "PLD_KBD_EN" },
+ { PLD_SPI_EN, GPIOF_OUT_INIT_LOW, "PLD_SPI_EN" },
+ { PLD_IO_USER, GPIOF_OUT_INIT_LOW, "PLD_IO_USER" },
+ { PLD_IO_LED0, GPIOF_OUT_INIT_LOW, "PLD_IO_LED0" },
+ { PLD_IO_LED1, GPIOF_OUT_INIT_LOW, "PLD_IO_LED1" },
+ { PLD_IO_LED2, GPIOF_OUT_INIT_LOW, "PLD_IO_LED2" },
+ { PLD_IO_LED3, GPIOF_OUT_INIT_LOW, "PLD_IO_LED3" },
+ { PLD_IO_LEDEN, GPIOF_OUT_INIT_LOW, "PLD_IO_LEDEN" },
+ { PLD_IRDA_EN, GPIOF_OUT_INIT_LOW, "PLD_IRDA_EN" },
+ { PLD_COM1_EN, GPIOF_OUT_INIT_HIGH, "PLD_COM1_EN" },
+ { PLD_COM2_EN, GPIOF_OUT_INIT_HIGH, "PLD_COM2_EN" },
+ { PLD_CODEC_EN, GPIOF_OUT_INIT_LOW, "PLD_CODEC_EN" },
+ { PLD_LCDEN_EN, GPIOF_OUT_INIT_LOW, "PLD_LCDEN_EN" },
+ { PLD_TCH_EN, GPIOF_OUT_INIT_LOW, "PLD_TCH_EN" },
+ { P720T_USERLED,GPIOF_OUT_INIT_LOW, "USER_LED" },
+};
+
+static struct resource p720t_mmgpio_resource[] __initdata = {
+ DEFINE_RES_MEM_NAMED(0, 4, "dat"),
+};
+
+static struct bgpio_pdata p720t_mmgpio_pdata = {
+ .ngpio = 8,
+};
+
+static struct platform_device p720t_mmgpio __initdata = {
+ .name = "basic-mmio-gpio",
+ .id = -1,
+ .resource = p720t_mmgpio_resource,
+ .num_resources = ARRAY_SIZE(p720t_mmgpio_resource),
+ .dev = {
+ .platform_data = &p720t_mmgpio_pdata,
+ },
+};
+
+static void __init p720t_mmgpio_init(void __iomem *addrbase, int gpiobase)
+{
+ p720t_mmgpio_resource[0].start = (unsigned long)addrbase;
+ p720t_mmgpio_pdata.base = gpiobase;
+
+ platform_device_register(&p720t_mmgpio);
+}
+
+static struct {
+ void __iomem *addrbase;
+ int gpiobase;
+} mmgpios[] __initconst = {
+ { PLD_INT, PLD_INT_MMGPIO_BASE },
+ { PLD_PWR, PLD_PWR_MMGPIO_BASE },
+ { PLD_KBD, PLD_KBD_MMGPIO_BASE },
+ { PLD_SPI, PLD_SPI_MMGPIO_BASE },
+ { PLD_IO, PLD_IO_MMGPIO_BASE },
+ { PLD_IRDA, PLD_IRDA_MMGPIO_BASE },
+ { PLD_COM2, PLD_COM2_MMGPIO_BASE },
+ { PLD_COM1, PLD_COM1_MMGPIO_BASE },
+ { PLD_AUD, PLD_AUD_MMGPIO_BASE },
+ { PLD_CF, PLD_CF_MMGPIO_BASE },
+ { PLD_SDC, PLD_SDC_MMGPIO_BASE },
+ { PLD_CODEC, PLD_CODEC_MMGPIO_BASE },
+ { PLD_BRITE, PLD_BRITE_MMGPIO_BASE },
+ { PLD_LCDEN, PLD_LCDEN_MMGPIO_BASE },
+ { PLD_TCH, PLD_TCH_MMGPIO_BASE },
+ { PLD_GPIO, PLD_GPIO_MMGPIO_BASE },
+};
+
+static struct resource p720t_nand_resource[] __initdata = {
+ DEFINE_RES_MEM(P720T_NAND_BASE, SZ_4),
+};
+
+static struct mtd_partition p720t_nand_parts[] __initdata = {
+ {
+ .name = "Flash partition 1",
+ .offset = 0,
+ .size = SZ_2M,
+ },
+ {
+ .name = "Flash partition 2",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct gpio_nand_platdata p720t_nand_pdata __initdata = {
+ .gpio_rdy = -1,
+ .gpio_nce = P720T_NAND_NCE,
+ .gpio_ale = P720T_NAND_ALE,
+ .gpio_cle = P720T_NAND_CLE,
+ .gpio_nwp = -1,
+ .chip_delay = 15,
+ .parts = p720t_nand_parts,
+ .num_parts = ARRAY_SIZE(p720t_nand_parts),
+};
+
+static struct platform_device p720t_nand_pdev __initdata = {
+ .name = "gpio-nand",
+ .id = -1,
+ .resource = p720t_nand_resource,
+ .num_resources = ARRAY_SIZE(p720t_nand_resource),
+ .dev = {
+ .platform_data = &p720t_nand_pdata,
+ },
+};
+
+static void p720t_lcd_power_set(struct plat_lcd_data *pd, unsigned int power)
+{
+ if (power) {
+ gpio_set_value(PLD_LCDEN_EN, 1);
+ gpio_set_value(PLD_S1_ON, 1);
+ gpio_set_value(PLD_S2_ON, 1);
+ gpio_set_value(PLD_S4_ON, 1);
+ } else {
+ gpio_set_value(PLD_S1_ON, 0);
+ gpio_set_value(PLD_S2_ON, 0);
+ gpio_set_value(PLD_S4_ON, 0);
+ gpio_set_value(PLD_LCDEN_EN, 0);
+ }
+}
+
+static struct plat_lcd_data p720t_lcd_power_pdata = {
+ .set_power = p720t_lcd_power_set,
+};
+
+static void p720t_lcd_backlight_set_intensity(int intensity)
+{
+ gpio_set_value(PLD_S3_ON, intensity);
+}
+
+static struct generic_bl_info p720t_lcd_backlight_pdata = {
+ .name = "lcd-backlight.0",
+ .default_intensity = 0x01,
+ .max_intensity = 0x01,
+ .set_bl_intensity = p720t_lcd_backlight_set_intensity,
+};
+
+static void __init
+fixup_p720t(struct tag *tag, char **cmdline)
+{
+ /*
+ * 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 struct gpio_led p720t_gpio_leds[] = {
+ {
+ .name = "User LED",
+ .default_trigger = "heartbeat",
+ .gpio = P720T_USERLED,
+ },
+};
+
+static struct gpio_led_platform_data p720t_gpio_led_pdata __initdata = {
+ .leds = p720t_gpio_leds,
+ .num_leds = ARRAY_SIZE(p720t_gpio_leds),
+};
+
+static void __init p720t_init(void)
+{
+ int i;
+
+ clps711x_devices_init();
+
+ for (i = 0; i < ARRAY_SIZE(mmgpios); i++)
+ p720t_mmgpio_init(mmgpios[i].addrbase, mmgpios[i].gpiobase);
+
+ platform_device_register(&p720t_nand_pdev);
+}
+
+static void __init p720t_init_late(void)
+{
+ WARN_ON(gpio_request_array(p720t_gpios, ARRAY_SIZE(p720t_gpios)));
+
+ platform_device_register_data(NULL, "platform-lcd", 0,
+ &p720t_lcd_power_pdata,
+ sizeof(p720t_lcd_power_pdata));
+ platform_device_register_data(NULL, "generic-bl", 0,
+ &p720t_lcd_backlight_pdata,
+ sizeof(p720t_lcd_backlight_pdata));
+ platform_device_register_simple("video-clps711x", 0, NULL, 0);
+ platform_device_register_data(NULL, "leds-gpio", 0,
+ &p720t_gpio_led_pdata,
+ sizeof(p720t_gpio_led_pdata));
+}
+
+MACHINE_START(P720T, "ARM-Prospector720T")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .atag_offset = 0x100,
+ .fixup = fixup_p720t,
+ .map_io = clps711x_map_io,
+ .init_irq = clps711x_init_irq,
+ .init_time = clps711x_timer_init,
+ .init_machine = p720t_init,
+ .init_late = p720t_init_late,
+ .restart = clps711x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c
new file mode 100644
index 000000000..671acc5a3
--- /dev/null
+++ b/arch/arm/mach-clps711x/common.c
@@ -0,0 +1,65 @@
+/*
+ * linux/arch/arm/mach-clps711x/core.c
+ *
+ * Core support for the CLPS711x-based machines.
+ *
+ * Copyright (C) 2001,2011 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/sizes.h>
+
+#include <asm/mach/map.h>
+#include <asm/system_misc.h>
+
+#include <mach/hardware.h>
+
+#include "common.h"
+
+/*
+ * This maps the generic CLPS711x registers
+ */
+static struct map_desc clps711x_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long)CLPS711X_VIRT_BASE,
+ .pfn = __phys_to_pfn(CLPS711X_PHYS_BASE),
+ .length = SZ_64K,
+ .type = MT_DEVICE
+ }
+};
+
+void __init clps711x_map_io(void)
+{
+ iotable_init(clps711x_io_desc, ARRAY_SIZE(clps711x_io_desc));
+}
+
+void __init clps711x_init_irq(void)
+{
+ clps711x_intc_init(CLPS711X_PHYS_BASE, SZ_16K);
+}
+
+void __init clps711x_timer_init(void)
+{
+ clps711x_clk_init(CLPS711X_VIRT_BASE);
+ clps711x_clksrc_init(CLPS711X_VIRT_BASE + TC1D,
+ CLPS711X_VIRT_BASE + TC2D, IRQ_TC2OI);
+}
+
+void clps711x_restart(enum reboot_mode mode, const char *cmd)
+{
+ soft_restart(0);
+}
diff --git a/arch/arm/mach-clps711x/common.h b/arch/arm/mach-clps711x/common.h
new file mode 100644
index 000000000..370200b26
--- /dev/null
+++ b/arch/arm/mach-clps711x/common.h
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-clps711x/common.h
+ *
+ * Common bits.
+ */
+
+#include <linux/reboot.h>
+
+#define CLPS711X_NR_GPIO (4 * 8 + 3)
+#define CLPS711X_GPIO(prt, bit) ((prt) * 8 + (bit))
+
+extern void clps711x_map_io(void);
+extern void clps711x_init_irq(void);
+extern void clps711x_timer_init(void);
+extern void clps711x_restart(enum reboot_mode mode, const char *cmd);
+
+/* drivers/irqchip/irq-clps711x.c */
+void clps711x_intc_init(phys_addr_t, resource_size_t);
+/* drivers/clk/clk-clps711x.c */
+void clps711x_clk_init(void __iomem *base);
+/* drivers/clocksource/clps711x-timer.c */
+void clps711x_clksrc_init(void __iomem *tc1_base, void __iomem *tc2_base,
+ unsigned int irq);
diff --git a/arch/arm/mach-clps711x/devices.c b/arch/arm/mach-clps711x/devices.c
new file mode 100644
index 000000000..77a9617c2
--- /dev/null
+++ b/arch/arm/mach-clps711x/devices.c
@@ -0,0 +1,149 @@
+/*
+ * CLPS711X common devices definitions
+ *
+ * Author: Alexander Shiyan <shc_work@mail.ru>, 2013-2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 <linux/of_fdt.h>
+#include <linux/platform_device.h>
+#include <linux/random.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+
+#include <asm/system_info.h>
+
+#include <mach/hardware.h>
+
+static const struct resource clps711x_cpuidle_res __initconst =
+ DEFINE_RES_MEM(CLPS711X_PHYS_BASE + HALT, SZ_128);
+
+static void __init clps711x_add_cpuidle(void)
+{
+ platform_device_register_simple("clps711x-cpuidle", PLATFORM_DEVID_NONE,
+ &clps711x_cpuidle_res, 1);
+}
+
+static const phys_addr_t clps711x_gpios[][2] __initconst = {
+ { PADR, PADDR },
+ { PBDR, PBDDR },
+ { PCDR, PCDDR },
+ { PDDR, PDDDR },
+ { PEDR, PEDDR },
+};
+
+static void __init clps711x_add_gpio(void)
+{
+ unsigned i;
+ struct resource gpio_res[2];
+
+ memset(gpio_res, 0, sizeof(gpio_res));
+
+ gpio_res[0].flags = IORESOURCE_MEM;
+ gpio_res[1].flags = IORESOURCE_MEM;
+
+ for (i = 0; i < ARRAY_SIZE(clps711x_gpios); i++) {
+ gpio_res[0].start = CLPS711X_PHYS_BASE + clps711x_gpios[i][0];
+ gpio_res[0].end = gpio_res[0].start;
+ gpio_res[1].start = CLPS711X_PHYS_BASE + clps711x_gpios[i][1];
+ gpio_res[1].end = gpio_res[1].start;
+
+ platform_device_register_simple("clps711x-gpio", i,
+ gpio_res, ARRAY_SIZE(gpio_res));
+ }
+}
+
+const struct resource clps711x_syscon_res[] __initconst = {
+ /* SYSCON1, SYSFLG1 */
+ DEFINE_RES_MEM(CLPS711X_PHYS_BASE + SYSCON1, SZ_128),
+ /* SYSCON2, SYSFLG2 */
+ DEFINE_RES_MEM(CLPS711X_PHYS_BASE + SYSCON2, SZ_128),
+ /* SYSCON3 */
+ DEFINE_RES_MEM(CLPS711X_PHYS_BASE + SYSCON3, SZ_64),
+};
+
+static void __init clps711x_add_syscon(void)
+{
+ unsigned i;
+
+ for (i = 0; i < ARRAY_SIZE(clps711x_syscon_res); i++)
+ platform_device_register_simple("syscon", i + 1,
+ &clps711x_syscon_res[i], 1);
+}
+
+static const struct resource clps711x_uart1_res[] __initconst = {
+ DEFINE_RES_MEM(CLPS711X_PHYS_BASE + UARTDR1, SZ_128),
+ DEFINE_RES_IRQ(IRQ_UTXINT1),
+ DEFINE_RES_IRQ(IRQ_URXINT1),
+};
+
+static const struct resource clps711x_uart2_res[] __initconst = {
+ DEFINE_RES_MEM(CLPS711X_PHYS_BASE + UARTDR2, SZ_128),
+ DEFINE_RES_IRQ(IRQ_UTXINT2),
+ DEFINE_RES_IRQ(IRQ_URXINT2),
+};
+
+static void __init clps711x_add_uart(void)
+{
+ platform_device_register_simple("clps711x-uart", 0, clps711x_uart1_res,
+ ARRAY_SIZE(clps711x_uart1_res));
+ platform_device_register_simple("clps711x-uart", 1, clps711x_uart2_res,
+ ARRAY_SIZE(clps711x_uart2_res));
+};
+
+static void __init clps711x_soc_init(void)
+{
+ struct soc_device_attribute *soc_dev_attr;
+ struct soc_device *soc_dev;
+ void __iomem *base;
+ u32 id[5];
+
+ base = ioremap(CLPS711X_PHYS_BASE, SZ_32K);
+ if (!base)
+ return;
+
+ id[0] = readl(base + UNIQID);
+ id[1] = readl(base + RANDID0);
+ id[2] = readl(base + RANDID1);
+ id[3] = readl(base + RANDID2);
+ id[4] = readl(base + RANDID3);
+ system_rev = SYSFLG1_VERID(readl(base + SYSFLG1));
+
+ add_device_randomness(id, sizeof(id));
+
+ system_serial_low = id[0];
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ goto out_unmap;
+
+ soc_dev_attr->machine = of_flat_dt_get_machine_name();
+ soc_dev_attr->family = "Cirrus Logic CLPS711X";
+ soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%u", system_rev);
+ soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%08x", id[0]);
+
+ soc_dev = soc_device_register(soc_dev_attr);
+ if (IS_ERR(soc_dev)) {
+ kfree(soc_dev_attr->revision);
+ kfree(soc_dev_attr->soc_id);
+ kfree(soc_dev_attr);
+ }
+
+out_unmap:
+ iounmap(base);
+}
+
+void __init clps711x_devices_init(void)
+{
+ clps711x_add_cpuidle();
+ clps711x_add_gpio();
+ clps711x_add_syscon();
+ clps711x_add_uart();
+ clps711x_soc_init();
+}
diff --git a/arch/arm/mach-clps711x/devices.h b/arch/arm/mach-clps711x/devices.h
new file mode 100644
index 000000000..a5efc1744
--- /dev/null
+++ b/arch/arm/mach-clps711x/devices.h
@@ -0,0 +1,12 @@
+/*
+ * CLPS711X common devices definitions
+ *
+ * Copyright (C) 2013 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+void clps711x_devices_init(void);
diff --git a/arch/arm/mach-clps711x/include/mach/clps711x.h b/arch/arm/mach-clps711x/include/mach/clps711x.h
new file mode 100644
index 000000000..eb052a11a
--- /dev/null
+++ b/arch/arm/mach-clps711x/include/mach/clps711x.h
@@ -0,0 +1,204 @@
+/*
+ * This file contains the hardware definitions of the Cirrus Logic
+ * ARM7 CLPS711X 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 __MACH_CLPS711X_H
+#define __MACH_CLPS711X_H
+
+#include <linux/mfd/syscon/clps711x.h>
+
+#define CLPS711X_PHYS_BASE (0x80000000)
+
+#define PADR (0x0000)
+#define PBDR (0x0001)
+#define PCDR (0x0002)
+#define PDDR (0x0003)
+#define PADDR (0x0040)
+#define PBDDR (0x0041)
+#define PCDDR (0x0042)
+#define PDDDR (0x0043)
+#define PEDR (0x0083)
+#define PEDDR (0x00c3)
+#define SYSCON1 (0x0100)
+#define SYSFLG1 (0x0140)
+#define MEMCFG1 (0x0180)
+#define MEMCFG2 (0x01c0)
+#define DRFPR (0x0200)
+#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 HALT (0x0800)
+#define STDBY (0x0840)
+
+#define FBADDR (0x1000)
+#define SYSCON2 (0x1100)
+#define SYSFLG2 (0x1140)
+#define UARTDR2 (0x1480)
+#define UBRLCR2 (0x14c0)
+#define SS2DR (0x1500)
+#define SS2POP (0x16c0)
+
+#define DAIR (0x2000)
+#define DAIDR0 (0x2040)
+#define DAIDR1 (0x2080)
+#define DAIDR2 (0x20c0)
+#define DAISR (0x2100)
+#define SYSCON3 (0x2200)
+#define LEDFLSH (0x22c0)
+#define SDCONF (0x2300)
+#define SDRFPR (0x2340)
+#define UNIQID (0x2440)
+#define DAI64FS (0x2600)
+#define PLLW (0x2610)
+#define PLLR (0xa5a8)
+#define RANDID0 (0x2700)
+#define RANDID1 (0x2704)
+#define RANDID2 (0x2708)
+#define RANDID3 (0x270c)
+
+#define LCDCON_GSEN (1 << 30)
+#define LCDCON_GSMD (1 << 31)
+
+/* 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_FRMLEN(x) (((x) & 0x1f) << 8)
+#define SYNCIO_SMCKEN (1 << 13)
+#define SYNCIO_TXFRMEN (1 << 14)
+
+#define DAIR_RESERVED (0x0404)
+#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 DAI64FS_I2SF64 (1 << 0)
+#define DAI64FS_AUDIOCLKEN (1 << 1)
+#define DAI64FS_AUDIOCLKSRC (1 << 2)
+#define DAI64FS_MCLK256EN (1 << 3)
+#define DAI64FS_LOOPBACK (1 << 5)
+
+#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)
+
+#define MEMCFG_BUS_WIDTH_32 (1)
+#define MEMCFG_BUS_WIDTH_16 (0)
+#define MEMCFG_BUS_WIDTH_8 (3)
+
+#define MEMCFG_SQAEN (1 << 6)
+#define MEMCFG_CLKENB (1 << 7)
+
+#define MEMCFG_WAITSTATE_8_3 (0 << 2)
+#define MEMCFG_WAITSTATE_7_3 (1 << 2)
+#define MEMCFG_WAITSTATE_6_3 (2 << 2)
+#define MEMCFG_WAITSTATE_5_3 (3 << 2)
+#define MEMCFG_WAITSTATE_4_2 (4 << 2)
+#define MEMCFG_WAITSTATE_3_2 (5 << 2)
+#define MEMCFG_WAITSTATE_2_2 (6 << 2)
+#define MEMCFG_WAITSTATE_1_2 (7 << 2)
+#define MEMCFG_WAITSTATE_8_1 (8 << 2)
+#define MEMCFG_WAITSTATE_7_1 (9 << 2)
+#define MEMCFG_WAITSTATE_6_1 (10 << 2)
+#define MEMCFG_WAITSTATE_5_1 (11 << 2)
+#define MEMCFG_WAITSTATE_4_0 (12 << 2)
+#define MEMCFG_WAITSTATE_3_0 (13 << 2)
+#define MEMCFG_WAITSTATE_2_0 (14 << 2)
+#define MEMCFG_WAITSTATE_1_0 (15 << 2)
+
+/* INTSR1 Interrupts */
+#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)
+
+/* INTSR2 Interrupts */
+#define IRQ_KBDINT (16 + 0)
+#define IRQ_SS2RX (16 + 1)
+#define IRQ_SS2TX (16 + 2)
+#define IRQ_UTXINT2 (16 + 12)
+#define IRQ_URXINT2 (16 + 13)
+
+/* INTSR3 Interrupts */
+#define IRQ_DAIINT (32 + 0)
+
+#endif /* __MACH_CLPS711X_H */
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 000000000..833129c9f
--- /dev/null
+++ b/arch/arm/mach-clps711x/include/mach/hardware.h
@@ -0,0 +1,53 @@
+/*
+ * 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 __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+#include <mach/clps711x.h>
+
+#define CLPS711X_VIRT_BASE IOMEM(0xfeff0000)
+
+#ifndef __ASSEMBLY__
+#define clps_readb(off) readb(CLPS711X_VIRT_BASE + (off))
+#define clps_readw(off) readw(CLPS711X_VIRT_BASE + (off))
+#define clps_readl(off) readl(CLPS711X_VIRT_BASE + (off))
+#define clps_writeb(val,off) writeb(val, CLPS711X_VIRT_BASE + (off))
+#define clps_writew(val,off) writew(val, CLPS711X_VIRT_BASE + (off))
+#define clps_writel(val,off) writel(val, CLPS711X_VIRT_BASE + (off))
+#endif
+
+#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)
+
+#define CLPS711X_SRAM_BASE CS6_PHYS_BASE
+#define CLPS711X_SRAM_SIZE (48 * 1024)
+
+#define CLPS711X_SDRAM0_BASE (0xc0000000)
+#define CLPS711X_SDRAM1_BASE (0xd0000000)
+
+#endif
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 000000000..5f02d06dc
--- /dev/null
+++ b/arch/arm/mach-clps711x/include/mach/uncompress.h
@@ -0,0 +1,55 @@
+/*
+ * 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/clps711x.h>
+
+#ifdef CONFIG_DEBUG_CLPS711X_UART2
+#define SYSFLGx SYSFLG2
+#define UARTDRx UARTDR2
+#else
+#define SYSFLGx SYSFLG1
+#define UARTDRx UARTDR1
+#endif
+
+#define phys_reg(x) (*(volatile u32 *)(CLPS711X_PHYS_BASE + (x)))
+
+/*
+ * 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 inline void putc(int c)
+{
+ while (phys_reg(SYSFLGx) & SYSFLG_UTXFF)
+ barrier();
+ phys_reg(UARTDRx) = c;
+}
+
+static inline void flush(void)
+{
+ while (phys_reg(SYSFLGx) & SYSFLG_UBUSY)
+ barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
diff --git a/arch/arm/mach-cns3xxx/Kconfig b/arch/arm/mach-cns3xxx/Kconfig
new file mode 100644
index 000000000..3c22a1990
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/Kconfig
@@ -0,0 +1,19 @@
+menuconfig ARCH_CNS3XXX
+ bool "Cavium Networks CNS3XXX family" if ARCH_MULTI_V6
+ select ARM_GIC
+ select PCI_DOMAINS if PCI
+ help
+ Support for Cavium Networks CNS3XXX platform.
+
+if ARCH_CNS3XXX
+
+config MACH_CNS3420VB
+ bool "Support for CNS3420 Validation Board"
+ depends on ATAGS
+ 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.
+
+endif
diff --git a/arch/arm/mach-cns3xxx/Makefile b/arch/arm/mach-cns3xxx/Makefile
new file mode 100644
index 000000000..a1ff10848
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_ARCH_CNS3XXX) += cns3xxx.o
+cns3xxx-y += core.o pm.o
+cns3xxx-$(CONFIG_ATAGS) += devices.o
+cns3xxx-$(CONFIG_PCI) += pcie.o
+cns3xxx-$(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 000000000..d079de0b6
--- /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 000000000..6428bcc77
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/cns3420vb.c
@@ -0,0 +1,255 @@
+/*
+ * 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 <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.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 "cns3xxx.h"
+#include "pm.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 int csn3xxx_usb_power_on(struct platform_device *pdev)
+{
+ /*
+ * EHCI and OHCI share the same clock and power,
+ * resetting twice would cause the 1st controller been reset.
+ * Therefore only do power up at the first up device, and
+ * power down at the last down device.
+ *
+ * Set USB AHB INCR length to 16
+ */
+ if (atomic_inc_return(&usb_pwr_ref) == 1) {
+ cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
+ cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
+ cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
+ __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
+ MISC_CHIP_CONFIG_REG);
+ }
+
+ return 0;
+}
+
+static void csn3xxx_usb_power_off(struct platform_device *pdev)
+{
+ /*
+ * EHCI and OHCI share the same clock and power,
+ * resetting twice would cause the 1st controller been reset.
+ * Therefore only do power up at the first up device, and
+ * power down at the last down device.
+ */
+ if (atomic_dec_return(&usb_pwr_ref) == 0)
+ cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
+}
+
+static struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = {
+ .power_on = csn3xxx_usb_power_on,
+ .power_off = csn3xxx_usb_power_off,
+};
+
+static struct platform_device cns3xxx_usb_ehci_device = {
+ .name = "ehci-platform",
+ .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),
+ .platform_data = &cns3xxx_usb_ehci_pdata,
+ },
+};
+
+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 usb_ohci_pdata cns3xxx_usb_ohci_pdata = {
+ .num_ports = 1,
+ .power_on = csn3xxx_usb_power_on,
+ .power_off = csn3xxx_usb_power_off,
+};
+
+static struct platform_device cns3xxx_usb_ohci_device = {
+ .name = "ohci-platform",
+ .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),
+ .platform_data = &cns3xxx_usb_ohci_pdata,
+ },
+};
+
+/*
+ * 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)
+{
+ cns3xxx_l2x0_init();
+
+ 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")
+ .atag_offset = 0x100,
+ .map_io = cns3420_map_io,
+ .init_irq = cns3xxx_init_irq,
+ .init_time = cns3xxx_timer_init,
+ .init_machine = cns3420_init,
+ .init_late = cns3xxx_pcie_init_late,
+ .restart = cns3xxx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-cns3xxx/cns3xxx.h b/arch/arm/mach-cns3xxx/cns3xxx.h
new file mode 100644
index 000000000..a0f5b6066
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/cns3xxx.h
@@ -0,0 +1,602 @@
+/*
+ * 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_PPE_BASE 0x70001000 /* HANT */
+
+#define CNS3XXX_EMBEDDED_SRAM_BASE 0x70002000 /* HANT Embedded SRAM */
+
+#define CNS3XXX_SSP_BASE 0x71000000 /* Synchronous Serial Port - SPI/PCM/I2C */
+
+#define CNS3XXX_DMC_BASE 0x72000000 /* DMC Control (DDR2 SDRAM) */
+
+#define CNS3XXX_SMC_BASE 0x73000000 /* SMC Control */
+
+#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_GPIOB_BASE 0x74800000 /* GPIO port B */
+
+#define CNS3XXX_RTC_BASE 0x75000000 /* Real Time Clock */
+
+#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 0xFB000000 /* Misc Control */
+
+#define CNS3XXX_PM_BASE 0x77000000 /* Power Management Control */
+#define CNS3XXX_PM_BASE_VIRT 0xFB001000
+
+#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 0xFB002000
+
+#define CNS3XXX_UART1_BASE 0x78400000 /* UART 1 */
+
+#define CNS3XXX_UART2_BASE 0x78800000 /* UART 2 */
+
+#define CNS3XXX_DMAC_BASE 0x79000000 /* Generic DMA Control */
+
+#define CNS3XXX_CORESIGHT_BASE 0x7A000000 /* CoreSight */
+
+#define CNS3XXX_CRYPTO_BASE 0x7B000000 /* Crypto */
+
+#define CNS3XXX_I2S_BASE 0x7C000000 /* I2S */
+
+#define CNS3XXX_TIMER1_2_3_BASE 0x7C800000 /* Timer */
+#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFB003000
+
+#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_RAID_BASE 0x7E000000 /* RAID Control */
+
+#define CNS3XXX_AXI_IXC_BASE 0x7F000000 /* AXI IXC */
+
+#define CNS3XXX_CLCD_BASE 0x80000000 /* LCD Control */
+
+#define CNS3XXX_USBOTG_BASE 0x81000000 /* USB OTG Control */
+
+#define CNS3XXX_USB_BASE 0x82000000 /* USB Host Control */
+
+#define CNS3XXX_SATA2_BASE 0x83000000 /* SATA */
+#define CNS3XXX_SATA2_SIZE SZ_16M
+
+#define CNS3XXX_CAMERA_BASE 0x84000000 /* Camera Interface */
+
+#define CNS3XXX_SDIO_BASE 0x85000000 /* SDIO */
+
+#define CNS3XXX_I2S_TDM_BASE 0x86000000 /* I2S TDM */
+
+#define CNS3XXX_2DG_BASE 0x87000000 /* 2D Graphic Control */
+
+#define CNS3XXX_USB_OHCI_BASE 0x88000000 /* USB OHCI */
+
+#define CNS3XXX_L2C_BASE 0x92000000 /* L2 Cache Control */
+
+#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 0xFB004000
+
+#define CNS3XXX_TC11MP_GIC_CPU_BASE 0x90000100 /* Test chip interrupt controller CPU interface */
+#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x100)
+
+#define CNS3XXX_TC11MP_TWD_BASE 0x90000600
+#define CNS3XXX_TC11MP_TWD_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x600)
+
+#define CNS3XXX_TC11MP_GIC_DIST_BASE 0x90001000 /* Test chip interrupt controller distributor */
+#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x1000)
+
+#define CNS3XXX_TC11MP_L220_BASE 0x92002000 /* L220 registers */
+
+/*
+ * 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_TC11MP_GIC_START 32
+
+#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)
+
+#endif /* __MACH_BOARD_CNS3XXX_H */
diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c
new file mode 100644
index 000000000..4e9837ded
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/core.c
@@ -0,0 +1,409 @@
+/*
+ * 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 <linux/irqchip/arm-gic.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+#include <asm/hardware/cache-l2x0.h>
+#include "cns3xxx.h"
+#include "core.h"
+#include "pm.h"
+
+static struct map_desc cns3xxx_io_desc[] __initdata = {
+ {
+ .virtual = CNS3XXX_TC11MP_SCU_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_TC11MP_SCU_BASE),
+ .length = SZ_8K,
+ .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_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,
+#ifdef CONFIG_PCI
+ }, {
+ .virtual = CNS3XXX_PCIE0_HOST_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE0_HOST_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_PCIE0_CFG0_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE0_CFG0_BASE),
+ .length = SZ_64K, /* really 4 KiB at offset 32 KiB */
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_PCIE0_CFG1_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE0_CFG1_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_PCIE1_HOST_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE1_HOST_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_PCIE1_CFG0_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE1_CFG0_BASE),
+ .length = SZ_64K, /* really 4 KiB at offset 32 KiB */
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_PCIE1_CFG1_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE1_CFG1_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+#endif
+ },
+};
+
+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, IOMEM(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT),
+ IOMEM(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT));
+}
+
+void cns3xxx_power_off(void)
+{
+ u32 __iomem *pm_base = IOMEM(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",
+ .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;
+ clockevents_config_and_register(&cns3xxx_tmr1_clockevent,
+ (cns3xxx_cpu_clock() >> 3) * 1000000,
+ 0xf, 0xffffffff);
+}
+
+/*
+ * 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_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);
+}
+
+void __init cns3xxx_timer_init(void)
+{
+ cns3xxx_tmr1 = IOMEM(CNS3XXX_TIMER1_2_3_BASE_VIRT);
+
+ __cns3xxx_timer_init(IRQ_CNS3XXX_TIMER0);
+}
+
+#ifdef CONFIG_CACHE_L2X0
+
+void __init cns3xxx_l2x0_init(void)
+{
+ void __iomem *base = ioremap(CNS3XXX_L2C_BASE, SZ_4K);
+ u32 val;
+
+ if (WARN_ON(!base))
+ return;
+
+ /*
+ * Tag RAM Control register
+ *
+ * bit[10:8] - 1 cycle of write accesses latency
+ * bit[6:4] - 1 cycle of read accesses latency
+ * bit[3:0] - 1 cycle of setup latency
+ *
+ * 1 cycle of latency for setup, read and write accesses
+ */
+ val = readl(base + L310_TAG_LATENCY_CTRL);
+ val &= 0xfffff888;
+ writel(val, base + L310_TAG_LATENCY_CTRL);
+
+ /*
+ * Data RAM Control register
+ *
+ * bit[10:8] - 1 cycles of write accesses latency
+ * bit[6:4] - 1 cycles of read accesses latency
+ * bit[3:0] - 1 cycle of setup latency
+ *
+ * 1 cycle of latency for setup, read and write accesses
+ */
+ val = readl(base + L310_DATA_LATENCY_CTRL);
+ val &= 0xfffff888;
+ writel(val, base + L310_DATA_LATENCY_CTRL);
+
+ /* 32 KiB, 8-way, parity disable */
+ l2x0_init(base, 0x00500000, 0xfe0f0fff);
+}
+
+#endif /* CONFIG_CACHE_L2X0 */
+
+static int csn3xxx_usb_power_on(struct platform_device *pdev)
+{
+ /*
+ * EHCI and OHCI share the same clock and power,
+ * resetting twice would cause the 1st controller been reset.
+ * Therefore only do power up at the first up device, and
+ * power down at the last down device.
+ *
+ * Set USB AHB INCR length to 16
+ */
+ if (atomic_inc_return(&usb_pwr_ref) == 1) {
+ cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
+ cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
+ cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
+ __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
+ MISC_CHIP_CONFIG_REG);
+ }
+
+ return 0;
+}
+
+static void csn3xxx_usb_power_off(struct platform_device *pdev)
+{
+ /*
+ * EHCI and OHCI share the same clock and power,
+ * resetting twice would cause the 1st controller been reset.
+ * Therefore only do power up at the first up device, and
+ * power down at the last down device.
+ */
+ if (atomic_dec_return(&usb_pwr_ref) == 0)
+ cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
+}
+
+static struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = {
+ .power_on = csn3xxx_usb_power_on,
+ .power_off = csn3xxx_usb_power_off,
+};
+
+static struct usb_ohci_pdata cns3xxx_usb_ohci_pdata = {
+ .num_ports = 1,
+ .power_on = csn3xxx_usb_power_on,
+ .power_off = csn3xxx_usb_power_off,
+};
+
+static struct of_dev_auxdata cns3xxx_auxdata[] __initconst = {
+ { "intel,usb-ehci", CNS3XXX_USB_BASE, "ehci-platform", &cns3xxx_usb_ehci_pdata },
+ { "intel,usb-ohci", CNS3XXX_USB_OHCI_BASE, "ohci-platform", &cns3xxx_usb_ohci_pdata },
+ { "cavium,cns3420-ahci", CNS3XXX_SATA2_BASE, "ahci", NULL },
+ { "cavium,cns3420-sdhci", CNS3XXX_SDIO_BASE, "ahci", NULL },
+ {},
+};
+
+static void __init cns3xxx_init(void)
+{
+ struct device_node *dn;
+
+ cns3xxx_l2x0_init();
+
+ dn = of_find_compatible_node(NULL, NULL, "cavium,cns3420-ahci");
+ if (of_device_is_available(dn)) {
+ 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));
+ }
+
+ dn = of_find_compatible_node(NULL, NULL, "cavium,cns3420-sdhci");
+ if (of_device_is_available(dn)) {
+ u32 __iomem *gpioa = IOMEM(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));
+ }
+
+ pm_power_off = cns3xxx_power_off;
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ cns3xxx_auxdata, NULL);
+}
+
+static const char *cns3xxx_dt_compat[] __initdata = {
+ "cavium,cns3410",
+ "cavium,cns3420",
+ NULL,
+};
+
+DT_MACHINE_START(CNS3XXX_DT, "Cavium Networks CNS3xxx")
+ .dt_compat = cns3xxx_dt_compat,
+ .map_io = cns3xxx_map_io,
+ .init_irq = cns3xxx_init_irq,
+ .init_time = cns3xxx_timer_init,
+ .init_machine = cns3xxx_init,
+ .init_late = cns3xxx_pcie_init_late,
+ .restart = cns3xxx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-cns3xxx/core.h b/arch/arm/mach-cns3xxx/core.h
new file mode 100644
index 000000000..dc5df7f1e
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/core.h
@@ -0,0 +1,35 @@
+/*
+ * 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
+
+#include <linux/reboot.h>
+
+extern void cns3xxx_timer_init(void);
+
+#ifdef CONFIG_CACHE_L2X0
+void __init cns3xxx_l2x0_init(void);
+#else
+static inline void cns3xxx_l2x0_init(void) {}
+#endif /* CONFIG_CACHE_L2X0 */
+
+#ifdef CONFIG_PCI
+extern void __init cns3xxx_pcie_init_late(void);
+#else
+static inline void __init cns3xxx_pcie_init_late(void) {}
+#endif
+
+void __init cns3xxx_map_io(void);
+void __init cns3xxx_init_irq(void);
+void cns3xxx_power_off(void);
+void cns3xxx_restart(enum reboot_mode, const char *);
+
+#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 000000000..7da78a245
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/devices.c
@@ -0,0 +1,111 @@
+/*
+ * 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 "cns3xxx.h"
+#include "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 = IOMEM(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 000000000..27e15a10a
--- /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/pcie.c b/arch/arm/mach-cns3xxx/pcie.c
new file mode 100644
index 000000000..c622c306c
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/pcie.c
@@ -0,0 +1,304 @@
+/*
+ * 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 "cns3xxx.h"
+#include "core.h"
+
+struct cns3xxx_pcie {
+ void __iomem *host_regs; /* PCI config registers for host bridge */
+ void __iomem *cfg0_regs; /* PCI Type 0 config registers */
+ void __iomem *cfg1_regs; /* PCI Type 1 config registers */
+ unsigned int irqs[2];
+ struct resource res_io;
+ struct resource res_mem;
+ int port;
+ bool linked;
+};
+
+static struct cns3xxx_pcie *sysdata_to_cnspci(void *sysdata)
+{
+ struct pci_sys_data *root = sysdata;
+
+ return root->private_data;
+}
+
+static struct cns3xxx_pcie *pdev_to_cnspci(const 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_map_bus(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);
+ void __iomem *base;
+
+ /* If there is no link, just show the CNS PCI bridge. */
+ if (!cnspci->linked && busno > 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) { /* internal PCIe bus, host bridge device */
+ if (devfn == 0) /* device# and function# are ignored by hw */
+ base = cnspci->host_regs;
+ else
+ return NULL; /* no such device */
+
+ } else if (busno == 1) { /* directly connected PCIe device */
+ if (slot == 0) /* device# is ignored by hw */
+ base = cnspci->cfg0_regs;
+ else
+ return NULL; /* no such device */
+ } else /* remote PCI bus */
+ base = cnspci->cfg1_regs + ((busno & 0xf) << 20);
+
+ return base + (where & 0xffc) + (devfn << 12);
+}
+
+static int cns3xxx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ int ret;
+ u32 mask = (0x1ull << (size * 8)) - 1;
+ int shift = (where % 4) * 8;
+
+ ret = pci_generic_config_read32(bus, devfn, where, size, val);
+
+ if (ret == PCIBIOS_SUCCESSFUL && !bus->number && !devfn &&
+ (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.
+ */
+ *val = ((((*val << shift) & 0xff) | (0x604 << 16)) >> shift) & mask;
+
+ return ret;
+}
+
+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;
+
+ BUG_ON(request_resource(&iomem_resource, res_io) ||
+ request_resource(&iomem_resource, res_mem));
+
+ pci_add_resource_offset(&sys->resources, res_io, sys->io_offset);
+ pci_add_resource_offset(&sys->resources, res_mem, sys->mem_offset);
+
+ return 1;
+}
+
+static struct pci_ops cns3xxx_pcie_ops = {
+ .map_bus = cns3xxx_pci_map_bus,
+ .read = cns3xxx_pci_read_config,
+ .write = pci_generic_config_write,
+};
+
+static int cns3xxx_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ struct cns3xxx_pcie *cnspci = pdev_to_cnspci(dev);
+ int irq = cnspci->irqs[!!dev->bus->number];
+
+ 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] = {
+ .host_regs = (void __iomem *)CNS3XXX_PCIE0_HOST_BASE_VIRT,
+ .cfg0_regs = (void __iomem *)CNS3XXX_PCIE0_CFG0_BASE_VIRT,
+ .cfg1_regs = (void __iomem *)CNS3XXX_PCIE0_CFG1_BASE_VIRT,
+ .res_io = {
+ .name = "PCIe0 I/O space",
+ .start = CNS3XXX_PCIE0_IO_BASE,
+ .end = CNS3XXX_PCIE0_CFG0_BASE - 1, /* 16 MiB */
+ .flags = IORESOURCE_IO,
+ },
+ .res_mem = {
+ .name = "PCIe0 non-prefetchable",
+ .start = CNS3XXX_PCIE0_MEM_BASE,
+ .end = CNS3XXX_PCIE0_HOST_BASE - 1, /* 176 MiB */
+ .flags = IORESOURCE_MEM,
+ },
+ .irqs = { IRQ_CNS3XXX_PCIE0_RC, IRQ_CNS3XXX_PCIE0_DEVICE, },
+ .port = 0,
+ },
+ [1] = {
+ .host_regs = (void __iomem *)CNS3XXX_PCIE1_HOST_BASE_VIRT,
+ .cfg0_regs = (void __iomem *)CNS3XXX_PCIE1_CFG0_BASE_VIRT,
+ .cfg1_regs = (void __iomem *)CNS3XXX_PCIE1_CFG1_BASE_VIRT,
+ .res_io = {
+ .name = "PCIe1 I/O space",
+ .start = CNS3XXX_PCIE1_IO_BASE,
+ .end = CNS3XXX_PCIE1_CFG0_BASE - 1, /* 16 MiB */
+ .flags = IORESOURCE_IO,
+ },
+ .res_mem = {
+ .name = "PCIe1 non-prefetchable",
+ .start = CNS3XXX_PCIE1_MEM_BASE,
+ .end = CNS3XXX_PCIE1_HOST_BASE - 1, /* 176 MiB */
+ .flags = IORESOURCE_MEM,
+ },
+ .irqs = { IRQ_CNS3XXX_PCIE1_RC, IRQ_CNS3XXX_PCIE1_DEVICE, },
+ .port = 1,
+ },
+};
+
+static void __init cns3xxx_pcie_check_link(struct cns3xxx_pcie *cnspci)
+{
+ int port = cnspci->port;
+ 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->port;
+ struct pci_sys_data sd = {
+ .private_data = cnspci,
+ };
+ struct pci_bus bus = {
+ .number = 0,
+ .ops = &cns3xxx_pcie_ops,
+ .sysdata = &sd,
+ };
+ u16 mem_base = cnspci->res_mem.start >> 16;
+ u16 mem_limit = cnspci->res_mem.end >> 16;
+ u16 io_base = cnspci->res_io.start >> 16;
+ u16 io_limit = cnspci->res_io.end >> 16;
+ u32 devfn = 0;
+ u8 tmp8;
+ u16 pos;
+ u16 dc;
+
+ 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, mem_limit);
+ pci_bus_write_config_word(&bus, devfn, PCI_IO_BASE_UPPER16, io_base);
+ pci_bus_write_config_word(&bus, devfn, PCI_IO_LIMIT_UPPER16, io_limit);
+
+ if (!cnspci->linked)
+ return;
+
+ /* Set Device Max_Read_Request_Size to 128 byte */
+ bus.number = 1; /* directly connected PCIe device */
+ devfn = PCI_DEVFN(0, 0);
+ pos = pci_bus_find_capability(&bus, devfn, PCI_CAP_ID_EXP);
+ pci_bus_read_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, &dc);
+ if (dc & PCI_EXP_DEVCTL_READRQ) {
+ dc &= ~PCI_EXP_DEVCTL_READRQ;
+ 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 & PCI_EXP_DEVCTL_READRQ)
+ pr_warn("PCIe: Unable to set device Max_Read_Request_Size\n");
+ else
+ pr_info("PCIe: Max_Read_Request_Size set to 128 bytes\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;
+}
+
+void __init cns3xxx_pcie_init_late(void)
+{
+ int i;
+ void *private_data;
+ struct hw_pci hw_pci = {
+ .nr_controllers = 1,
+ .ops = &cns3xxx_pcie_ops,
+ .setup = cns3xxx_pci_setup,
+ .map_irq = cns3xxx_pcie_map_irq,
+ .private_data = &private_data,
+ };
+
+ pcibios_min_io = 0;
+ pcibios_min_mem = 0;
+
+ hook_fault_code(16 + 6, cns3xxx_pcie_abort_handler, SIGBUS, 0,
+ "imprecise external abort");
+
+ for (i = 0; i < ARRAY_SIZE(cns3xxx_pcie); i++) {
+ 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]);
+ private_data = &cns3xxx_pcie[i];
+ pci_common_init(&hw_pci);
+ }
+
+ pci_assign_unassigned_resources();
+}
diff --git a/arch/arm/mach-cns3xxx/pm.c b/arch/arm/mach-cns3xxx/pm.c
new file mode 100644
index 000000000..f46b78dd6
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/pm.c
@@ -0,0 +1,123 @@
+/*
+ * 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 <linux/atomic.h>
+#include "cns3xxx.h"
+#include "pm.h"
+#include "core.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);
+}
+
+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 cns3xxx_restart(enum reboot_mode 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-cns3xxx/pm.h b/arch/arm/mach-cns3xxx/pm.h
new file mode 100644
index 000000000..c2588cc99
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/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 <linux/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-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
new file mode 100644
index 000000000..dd8f5312b
--- /dev/null
+++ b/arch/arm/mach-davinci/Kconfig
@@ -0,0 +1,260 @@
+if ARCH_DAVINCI
+
+config AINTC
+ bool
+
+config CP_INTC
+ bool
+ select IRQ_DOMAIN
+
+config ARCH_DAVINCI_DMx
+ bool
+ select CPU_ARM926T
+
+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"
+ depends on !ARCH_DAVINCI_DMx || AUTO_ZRELADDR
+ select ARCH_DAVINCI_DA8XX
+ select CPU_DCACHE_WRITETHROUGH # needed on silicon revs 1.0, 1.1
+ select CP_INTC
+
+config ARCH_DAVINCI_DA850
+ bool "DA850/OMAP-L138/AM18x based system"
+ depends on !ARCH_DAVINCI_DMx || AUTO_ZRELADDR
+ select ARCH_DAVINCI_DA8XX
+ select CP_INTC
+
+config ARCH_DAVINCI_DA8XX
+ bool
+ select CPU_ARM926T
+
+config ARCH_DAVINCI_DM365
+ bool "DaVinci 365 based system"
+ select AINTC
+ select ARCH_DAVINCI_DMx
+
+comment "DaVinci Board Type"
+
+config MACH_DA8XX_DT
+ bool "Support DA8XX platforms using device tree"
+ default y
+ depends on ARCH_DAVINCI_DA8XX
+ select PINCTRL
+ help
+ Say y here to include support for TI DaVinci DA850 based using
+ Flattened Device Tree. More information at Documentation/devicetree
+
+config MACH_DAVINCI_EVM
+ bool "TI DM644x EVM"
+ default ARCH_DAVINCI_DM644x
+ depends on ARCH_DAVINCI_DM644x
+ 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 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 EEPROM_AT24
+ select I2C
+ select MACH_DAVINCI_DM6467TEVM
+ 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 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 EEPROM_AT24
+ select GPIO_PCF857X
+ 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.
+
+config DA850_UI_SD_VIDEO_PORT
+ bool "Video Port Interface"
+ help
+ Say Y if you want to use Video Port Interface (VPIF) on the
+ DA850/OMAP-L138 EVM. The Video decoders/encoders are found on the
+ UI daughter card that is supplied with the EVM.
+
+endchoice
+
+config MACH_MITYOMAPL138
+ bool "Critical Link MityDSP-L138/MityARM-1808 SoM"
+ depends on ARCH_DAVINCI_DA850
+ 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 000000000..2e3464b8b
--- /dev/null
+++ b/arch/arm/mach-davinci/Makefile
@@ -0,0 +1,40 @@
+#
+# Makefile for the linux kernel.
+#
+#
+
+# Common objects
+obj-y := time.o clock.o serial.o psc.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_AINTC) += irq.o
+obj-$(CONFIG_CP_INTC) += cp_intc.o
+
+# Board specific
+obj-$(CONFIG_MACH_DA8XX_DT) += da8xx-dt.o
+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
+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_MITYOMAPL138) += board-mityomapl138.o
+obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o
+
+# Power Management
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
+obj-$(CONFIG_SUSPEND) += pm.o sleep.o
+obj-$(CONFIG_HAVE_CLK) += pm_domain.o
diff --git a/arch/arm/mach-davinci/Makefile.boot b/arch/arm/mach-davinci/Makefile.boot
new file mode 100644
index 000000000..4b8160175
--- /dev/null
+++ b/arch/arm/mach-davinci/Makefile.boot
@@ -0,0 +1,7 @@
+zreladdr-$(CONFIG_ARCH_DAVINCI_DA8XX) += 0xc0008000
+params_phys-$(CONFIG_ARCH_DAVINCI_DA8XX) := 0xc0000100
+initrd_phys-$(CONFIG_ARCH_DAVINCI_DA8XX) := 0xc0800000
+
+zreladdr-$(CONFIG_ARCH_DAVINCI_DMx) += 0x80008000
+params_phys-$(CONFIG_ARCH_DAVINCI_DMx) := 0x80000100
+initrd_phys-$(CONFIG_ARCH_DAVINCI_DMx) := 0x80800000
diff --git a/arch/arm/mach-davinci/aemif.c b/arch/arm/mach-davinci/aemif.c
new file mode 100644
index 000000000..ff8b7e76b
--- /dev/null
+++ b/arch/arm/mach-davinci/aemif.c
@@ -0,0 +1,218 @@
+/*
+ * 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 <linux/platform_data/mtd-davinci-aemif.h>
+#include <linux/platform_data/mtd-davinci.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))
+
+static inline unsigned int davinci_aemif_readl(void __iomem *base, int offset)
+{
+ return readl_relaxed(base + offset);
+}
+
+static inline void davinci_aemif_writel(void __iomem *base,
+ int offset, unsigned long value)
+{
+ writel_relaxed(value, base + offset);
+}
+
+/*
+ * 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
+ * @clkrate: the AEMIF clkrate
+ *
+ * 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.
+ */
+static int davinci_aemif_setup_timing(struct davinci_aemif_timing *t,
+ void __iomem *base, unsigned cs,
+ unsigned long clkrate)
+{
+ unsigned set, val;
+ int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup;
+ unsigned offset = A1CR_OFFSET + cs * 4;
+
+ if (!t)
+ return 0; /* Nothing to do */
+
+ 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;
+}
+
+/**
+ * davinci_aemif_setup - setup AEMIF interface by davinci_nand_pdata
+ * @pdev - link to platform device to setup settings for
+ *
+ * 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(struct platform_device *pdev)
+{
+ struct davinci_nand_pdata *pdata = dev_get_platdata(&pdev->dev);
+ uint32_t val;
+ unsigned long clkrate;
+ struct resource *res;
+ void __iomem *base;
+ struct clk *clk;
+ int ret = 0;
+
+ clk = clk_get(&pdev->dev, "aemif");
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ dev_dbg(&pdev->dev, "unable to get AEMIF clock, err %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(clk);
+ if (ret < 0) {
+ dev_dbg(&pdev->dev, "unable to enable AEMIF clock, err %d\n",
+ ret);
+ goto err_put;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ base = ioremap(res->start, resource_size(res));
+ if (!base) {
+ dev_err(&pdev->dev, "ioremap failed for resource %pR\n", res);
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /*
+ * Setup Async configuration register in case we did not boot
+ * from NAND and so bootloader did not bother to set it up.
+ */
+ val = davinci_aemif_readl(base, A1CR_OFFSET + pdev->id * 4);
+ /*
+ * Extended Wait is not valid and Select Strobe mode is not
+ * used
+ */
+ val &= ~(ACR_ASIZE_MASK | ACR_EW_MASK | ACR_SS_MASK);
+ if (pdata->options & NAND_BUSWIDTH_16)
+ val |= 0x1;
+
+ davinci_aemif_writel(base, A1CR_OFFSET + pdev->id * 4, val);
+
+ clkrate = clk_get_rate(clk);
+
+ if (pdata->timing)
+ ret = davinci_aemif_setup_timing(pdata->timing, base, pdev->id,
+ clkrate);
+
+ if (ret < 0)
+ dev_dbg(&pdev->dev, "NAND timing values setup fail\n");
+
+ iounmap(base);
+err:
+ clk_disable_unprepare(clk);
+err_put:
+ clk_put(clk);
+ return ret;
+}
diff --git a/arch/arm/mach-davinci/asp.h b/arch/arm/mach-davinci/asp.h
new file mode 100644
index 000000000..1128e1d8e
--- /dev/null
+++ b/arch/arm/mach-davinci/asp.h
@@ -0,0 +1,56 @@
+/*
+ * TI DaVinci Audio definitions
+ */
+#ifndef __ASM_ARCH_DAVINCI_ASP_H
+#define __ASM_ARCH_DAVINCI_ASP_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
+
+/* Bases of da830 McASP2 register banks */
+#define DAVINCI_DA830_MCASP2_REG_BASE 0x01D08000
+
+/* 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
+
+/* EDMA channels of da830 McASP2 */
+#define DAVINCI_DA830_DMA_MCASP2_AREVT 4
+#define DAVINCI_DA830_DMA_MCASP2_AXEVT 5
+
+/* 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
+
+#endif /* __ASM_ARCH_DAVINCI_ASP_H */
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 000000000..f8f62fbaa
--- /dev/null
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -0,0 +1,677 @@
+/*
+ * 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/platform_data/at24.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_data/mtd-davinci.h>
+#include <linux/platform_data/mtd-davinci-aemif.h>
+#include <linux/platform_data/spi-davinci.h>
+#include <linux/platform_data/usb-davinci.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/common.h>
+#include <mach/cp_intc.h>
+#include <mach/mux.h>
+#include <mach/da8xx.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_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 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_warn("%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_warn("%s: USB 2.0 registration failed: %d\n",
+ __func__, ret);
+ }
+
+ ret = davinci_cfg_reg_list(da830_evm_usb11_pins);
+ if (ret) {
+ pr_warn("%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) {
+ pr_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) {
+ pr_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_warn("%s: USB 1.1 registration failed: %d\n", __func__, ret);
+}
+
+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,
+};
+
+static inline void da830_evm_init_mmc(void)
+{
+ int ret;
+
+ ret = davinci_cfg_reg_list(da830_evm_mmc_sd_pins);
+ if (ret) {
+ pr_warn("%s: mmc/sd mux setup failed: %d\n", __func__, ret);
+ return;
+ }
+
+ ret = gpio_request(DA830_MMCSD_WP_PIN, "MMC WP");
+ if (ret) {
+ pr_warn("%s: can not open GPIO %d\n",
+ __func__, 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_warn("%s: can not open GPIO %d\n",
+ __func__, DA830_MMCSD_CD_PIN);
+ return;
+ }
+ gpio_direction_input(DA830_MMCSD_CD_PIN);
+
+ ret = da8xx_register_mmcsd0(&da830_evm_mmc_config);
+ if (ret) {
+ pr_warn("%s: mmc/sd registration failed: %d\n", __func__, 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
+};
+
+#define HAS_MMC IS_ENABLED(CONFIG_MMC_DAVINCI)
+
+#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,
+ .bbt_options = NAND_BBT_USE_FLASH,
+ .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_warn("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_warn("%s: emif25 mux setup failed: %d\n", __func__, ret);
+
+ ret = platform_device_register(&da830_evm_nand_device);
+ if (ret)
+ pr_warn("%s: NAND device not registered\n", __func__);
+
+ if (davinci_aemif_setup(&da830_evm_nand_device))
+ pr_warn("%s: Cannot configure AEMIF\n", __func__);
+
+ 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_warn("%s: lcdcntl mux setup failed: %d\n", __func__, ret);
+
+ ret = da8xx_register_lcdc(&sharp_lcd035q3dg01_pdata);
+ if (ret)
+ pr_warn("%s: lcd setup failed: %d\n", __func__, 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_gpio();
+ if (ret)
+ pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
+
+ ret = da830_register_edma(da830_edma_rsv);
+ if (ret)
+ pr_warn("%s: edma registration failed: %d\n", __func__, ret);
+
+ ret = davinci_cfg_reg_list(da830_i2c0_pins);
+ if (ret)
+ pr_warn("%s: i2c0 mux setup failed: %d\n", __func__, ret);
+
+ ret = da8xx_register_i2c(0, &da830_evm_i2c_0_pdata);
+ if (ret)
+ pr_warn("%s: i2c0 registration failed: %d\n", __func__, 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_warn("%s: cpgmac mux setup failed: %d\n", __func__, ret);
+
+ ret = da8xx_register_emac();
+ if (ret)
+ pr_warn("%s: emac registration failed: %d\n", __func__, ret);
+
+ ret = da8xx_register_watchdog();
+ if (ret)
+ pr_warn("%s: watchdog registration failed: %d\n",
+ __func__, ret);
+
+ davinci_serial_init(da8xx_serial_device);
+ 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_warn("%s: mcasp1 mux setup failed: %d\n", __func__, ret);
+
+ da8xx_register_mcasp(1, &da830_evm_snd_data);
+
+ da830_evm_init_mmc();
+
+ ret = da8xx_register_rtc();
+ if (ret)
+ pr_warn("%s: rtc setup failed: %d\n", __func__, ret);
+
+ ret = spi_register_board_info(da830evm_spi_info,
+ ARRAY_SIZE(da830evm_spi_info));
+ if (ret)
+ pr_warn("%s: spi info registration failed: %d\n",
+ __func__, ret);
+
+ ret = da8xx_register_spi_bus(0, ARRAY_SIZE(da830evm_spi_info));
+ if (ret)
+ pr_warn("%s: spi 0 registration failed: %d\n", __func__, 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")
+ .atag_offset = 0x100,
+ .map_io = da830_evm_map_io,
+ .init_irq = cp_intc_init,
+ .init_time = davinci_timer_init,
+ .init_machine = da830_evm_init,
+ .init_late = davinci_init_late,
+ .dma_zone_size = SZ_128M,
+ .restart = da8xx_restart,
+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 000000000..1ed545cc2
--- /dev/null
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -0,0 +1,1510 @@
+/*
+ * 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/console.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/platform_data/at24.h>
+#include <linux/platform_data/pca953x.h>
+#include <linux/input.h>
+#include <linux/input/tps6507x-ts.h>
+#include <linux/mfd/tps6507x.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_data/mtd-davinci.h>
+#include <linux/platform_data/mtd-davinci-aemif.h>
+#include <linux/platform_data/spi-davinci.h>
+#include <linux/platform_data/uio_pruss.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/tps6507x.h>
+#include <linux/regulator/fixed.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <mach/common.h>
+#include <mach/cp_intc.h>
+#include <mach/da8xx.h>
+#include <mach/mux.h>
+#include <mach/sram.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/system_info.h>
+
+#include <media/tvp514x.h>
+#include <media/adv7343.h>
+
+#define DA850_EVM_PHY_ID "davinci_mdio-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,
+ .bbt_options = NAND_BBT_USE_FLASH,
+ .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[] = {
+ &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
+};
+
+#define HAS_MMC IS_ENABLED(CONFIG_MMC_DAVINCI)
+
+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_warn("%s: NAND mux setup failed: %d\n",
+ __func__, ret);
+
+ ret = davinci_cfg_reg_list(da850_evm_nor_pins);
+ if (ret)
+ pr_warn("%s: NOR mux setup failed: %d\n",
+ __func__, ret);
+
+ da850_evm_init_nor();
+
+ platform_add_devices(da850_evm_devices,
+ ARRAY_SIZE(da850_evm_devices));
+
+ if (davinci_aemif_setup(&da850_evm_nandflash_device))
+ pr_warn("%s: Cannot configure AEMIF.\n", __func__);
+ }
+}
+
+#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 = da850_evm_ui_exp[DA850_EVM_UI_EXP_PB8 + i];
+ button->gpio = gpio + DA850_EVM_UI_EXP_PB8 + i;
+ }
+}
+
+#ifdef CONFIG_DA850_UI_SD_VIDEO_PORT
+static inline void da850_evm_setup_video_port(int video_sel)
+{
+ gpio_set_value_cansleep(video_sel, 0);
+}
+#else
+static inline void da850_evm_setup_video_port(int video_sel) { }
+#endif
+
+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_warn("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_warn("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_warn("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_warn("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);
+
+ da850_evm_setup_video_port(sel_c);
+
+ 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 = 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 = 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_warn("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_warn("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 */
+};
+
+/* 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,
+ .ram_chan_q = EVENTQ_1,
+ .version = MCASP_VERSION_2,
+ .txnumevt = 1,
+ .rxnumevt = 1,
+ .sram_size_playback = SZ_8K,
+ .sram_size_capture = SZ_8K,
+};
+
+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,
+};
+
+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;
+}
+
+/* Fixed regulator support */
+static struct regulator_consumer_supply fixed_supplies[] = {
+ /* Baseboard 3.3V: 5V -> TPS73701DCQ -> 3.3V */
+ REGULATOR_SUPPLY("AVDD", "1-0018"),
+ REGULATOR_SUPPLY("DRVDD", "1-0018"),
+
+ /* Baseboard 1.8V: 5V -> TPS73701DCQ -> 1.8V */
+ REGULATOR_SUPPLY("DVDD", "1-0018"),
+};
+
+/* 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",
+ },
+ REGULATOR_SUPPLY("IOVDD", "1-0018"),
+};
+
+/* 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,
+ .always_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 */
+ .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_warn("%s: CPGMAC/RMII mux setup failed: %d\n",
+ __func__, 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_warn("%s:GPIO(2,6) mux setup failed\n", __func__);
+
+ ret = gpio_request(DA850_MII_MDIO_CLKEN_PIN, "mdio_clk_en");
+ if (ret) {
+ pr_warn("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_warn("%s: EMAC registration failed: %d\n", __func__, 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
+
+#if defined(CONFIG_DA850_UI_SD_VIDEO_PORT)
+
+#define TVP5147_CH0 "tvp514x-0"
+#define TVP5147_CH1 "tvp514x-1"
+
+/* VPIF capture configuration */
+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 const struct vpif_input da850_ch0_inputs[] = {
+ {
+ .input = {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .capabilities = V4L2_IN_CAP_STD,
+ .std = TVP514X_STD_ALL,
+ },
+ .input_route = INPUT_CVBS_VI2B,
+ .output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ .subdev_name = TVP5147_CH0,
+ },
+};
+
+static const struct vpif_input da850_ch1_inputs[] = {
+ {
+ .input = {
+ .index = 0,
+ .name = "S-Video",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .capabilities = V4L2_IN_CAP_STD,
+ .std = TVP514X_STD_ALL,
+ },
+ .input_route = INPUT_SVIDEO_VI2C_VI1C,
+ .output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ .subdev_name = TVP5147_CH1,
+ },
+};
+
+static struct vpif_subdev_info da850_vpif_capture_sdev_info[] = {
+ {
+ .name = TVP5147_CH0,
+ .board_info = {
+ I2C_BOARD_INFO("tvp5146", 0x5d),
+ .platform_data = &tvp5146_pdata,
+ },
+ },
+ {
+ .name = TVP5147_CH1,
+ .board_info = {
+ I2C_BOARD_INFO("tvp5146", 0x5c),
+ .platform_data = &tvp5146_pdata,
+ },
+ },
+};
+
+static struct vpif_capture_config da850_vpif_capture_config = {
+ .subdev_info = da850_vpif_capture_sdev_info,
+ .subdev_count = ARRAY_SIZE(da850_vpif_capture_sdev_info),
+ .chan_config[0] = {
+ .inputs = da850_ch0_inputs,
+ .input_count = ARRAY_SIZE(da850_ch0_inputs),
+ .vpif_if = {
+ .if_type = VPIF_IF_BT656,
+ .hd_pol = 1,
+ .vd_pol = 1,
+ .fid_pol = 0,
+ },
+ },
+ .chan_config[1] = {
+ .inputs = da850_ch1_inputs,
+ .input_count = ARRAY_SIZE(da850_ch1_inputs),
+ .vpif_if = {
+ .if_type = VPIF_IF_BT656,
+ .hd_pol = 1,
+ .vd_pol = 1,
+ .fid_pol = 0,
+ },
+ },
+ .card_name = "DA850/OMAP-L138 Video Capture",
+};
+
+/* VPIF display configuration */
+
+static struct adv7343_platform_data adv7343_pdata = {
+ .mode_config = {
+ .dac = { 1, 1, 1 },
+ },
+ .sd_config = {
+ .sd_dac_out = { 1 },
+ },
+};
+
+static struct vpif_subdev_info da850_vpif_subdev[] = {
+ {
+ .name = "adv7343",
+ .board_info = {
+ I2C_BOARD_INFO("adv7343", 0x2a),
+ .platform_data = &adv7343_pdata,
+ },
+ },
+};
+
+static const struct vpif_output da850_ch0_outputs[] = {
+ {
+ .output = {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .capabilities = V4L2_OUT_CAP_STD,
+ .std = V4L2_STD_ALL,
+ },
+ .subdev_name = "adv7343",
+ .output_route = ADV7343_COMPOSITE_ID,
+ },
+ {
+ .output = {
+ .index = 1,
+ .name = "S-Video",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .capabilities = V4L2_OUT_CAP_STD,
+ .std = V4L2_STD_ALL,
+ },
+ .subdev_name = "adv7343",
+ .output_route = ADV7343_SVIDEO_ID,
+ },
+};
+
+static struct vpif_display_config da850_vpif_display_config = {
+ .subdevinfo = da850_vpif_subdev,
+ .subdev_count = ARRAY_SIZE(da850_vpif_subdev),
+ .chan_config[0] = {
+ .outputs = da850_ch0_outputs,
+ .output_count = ARRAY_SIZE(da850_ch0_outputs),
+ },
+ .card_name = "DA850/OMAP-L138 Video Display",
+};
+
+static __init void da850_vpif_init(void)
+{
+ int ret;
+
+ ret = da850_register_vpif();
+ if (ret)
+ pr_warn("da850_evm_init: VPIF setup failed: %d\n", ret);
+
+ ret = davinci_cfg_reg_list(da850_vpif_capture_pins);
+ if (ret)
+ pr_warn("da850_evm_init: VPIF capture mux setup failed: %d\n",
+ ret);
+
+ ret = da850_register_vpif_capture(&da850_vpif_capture_config);
+ if (ret)
+ pr_warn("da850_evm_init: VPIF capture setup failed: %d\n", ret);
+
+ ret = davinci_cfg_reg_list(da850_vpif_display_pins);
+ if (ret)
+ pr_warn("da850_evm_init: VPIF display mux setup failed: %d\n",
+ ret);
+
+ ret = da850_register_vpif_display(&da850_vpif_display_config);
+ if (ret)
+ pr_warn("da850_evm_init: VPIF display setup failed: %d\n", ret);
+}
+
+#else
+static __init void da850_vpif_init(void) {}
+#endif
+
+#define DA850EVM_SATA_REFCLKPN_RATE (100 * 1000 * 1000)
+
+static __init void da850_evm_init(void)
+{
+ int ret;
+
+ ret = da850_register_gpio();
+ if (ret)
+ pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
+
+ regulator_register_fixed(0, fixed_supplies, ARRAY_SIZE(fixed_supplies));
+
+ ret = pmic_tps65070_init();
+ if (ret)
+ pr_warn("%s: TPS65070 PMIC init failed: %d\n", __func__, ret);
+
+ ret = da850_register_edma(da850_edma_rsv);
+ if (ret)
+ pr_warn("%s: EDMA registration failed: %d\n", __func__, ret);
+
+ ret = davinci_cfg_reg_list(da850_i2c0_pins);
+ if (ret)
+ pr_warn("%s: I2C0 mux setup failed: %d\n", __func__, ret);
+
+ ret = da8xx_register_i2c(0, &da850_evm_i2c_0_pdata);
+ if (ret)
+ pr_warn("%s: I2C0 registration failed: %d\n", __func__, ret);
+
+
+ ret = da8xx_register_watchdog();
+ if (ret)
+ pr_warn("%s: watchdog registration failed: %d\n",
+ __func__, ret);
+
+ if (HAS_MMC) {
+ ret = davinci_cfg_reg_list(da850_evm_mmcsd0_pins);
+ if (ret)
+ pr_warn("%s: MMCSD0 mux setup failed: %d\n",
+ __func__, ret);
+
+ ret = gpio_request(DA850_MMCSD_CD_PIN, "MMC CD\n");
+ if (ret)
+ pr_warn("%s: can not open GPIO %d\n",
+ __func__, DA850_MMCSD_CD_PIN);
+ gpio_direction_input(DA850_MMCSD_CD_PIN);
+
+ ret = gpio_request(DA850_MMCSD_WP_PIN, "MMC WP\n");
+ if (ret)
+ pr_warn("%s: can not open GPIO %d\n",
+ __func__, DA850_MMCSD_WP_PIN);
+ gpio_direction_input(DA850_MMCSD_WP_PIN);
+
+ ret = da8xx_register_mmcsd0(&da850_mmc_config);
+ if (ret)
+ pr_warn("%s: MMCSD0 registration failed: %d\n",
+ __func__, ret);
+ }
+
+ davinci_serial_init(da8xx_serial_device);
+
+ 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_warn("%s: McASP mux setup failed: %d\n", __func__, ret);
+
+ da850_evm_snd_data.sram_pool = sram_get_gen_pool();
+ da8xx_register_mcasp(0, &da850_evm_snd_data);
+
+ ret = davinci_cfg_reg_list(da850_lcdcntl_pins);
+ if (ret)
+ pr_warn("%s: LCDC mux setup failed: %d\n", __func__, ret);
+
+ ret = da8xx_register_uio_pruss();
+ if (ret)
+ pr_warn("da850_evm_init: pruss initialization failed: %d\n",
+ ret);
+
+ /* Handle board specific muxing for LCD here */
+ ret = davinci_cfg_reg_list(da850_evm_lcdc_pins);
+ if (ret)
+ pr_warn("%s: EVM specific LCD mux setup failed: %d\n",
+ __func__, ret);
+
+ ret = da850_lcd_hw_init();
+ if (ret)
+ pr_warn("%s: LCD initialization failed: %d\n", __func__, ret);
+
+ sharp_lk043t1dg01_pdata.panel_power_ctrl = da850_panel_power_ctrl,
+ ret = da8xx_register_lcdc(&sharp_lk043t1dg01_pdata);
+ if (ret)
+ pr_warn("%s: LCDC registration failed: %d\n", __func__, ret);
+
+ ret = da8xx_register_rtc();
+ if (ret)
+ pr_warn("%s: RTC setup failed: %d\n", __func__, ret);
+
+ ret = da850_evm_init_cpufreq();
+ if (ret)
+ pr_warn("%s: cpufreq registration failed: %d\n", __func__, ret);
+
+ ret = da8xx_register_cpuidle();
+ if (ret)
+ pr_warn("%s: cpuidle registration failed: %d\n", __func__, ret);
+
+ ret = da850_register_pm(&da850_pm_device);
+ if (ret)
+ pr_warn("%s: suspend registration failed: %d\n", __func__, ret);
+
+ da850_vpif_init();
+
+ ret = spi_register_board_info(da850evm_spi_info,
+ ARRAY_SIZE(da850evm_spi_info));
+ if (ret)
+ pr_warn("%s: spi info registration failed: %d\n", __func__,
+ ret);
+
+ ret = da8xx_register_spi_bus(1, ARRAY_SIZE(da850evm_spi_info));
+ if (ret)
+ pr_warn("%s: SPI 1 registration failed: %d\n", __func__, ret);
+
+ ret = da850_register_sata(DA850EVM_SATA_REFCLKPN_RATE);
+ if (ret)
+ pr_warn("%s: SATA registration failed: %d\n", __func__, ret);
+
+ da850_evm_setup_mac_addr();
+
+ ret = da8xx_register_rproc();
+ if (ret)
+ pr_warn("%s: dsp/rproc registration failed: %d\n",
+ __func__, ret);
+}
+
+#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")
+ .atag_offset = 0x100,
+ .map_io = da850_evm_map_io,
+ .init_irq = cp_intc_init,
+ .init_time = davinci_timer_init,
+ .init_machine = da850_evm_init,
+ .init_late = davinci_init_late,
+ .dma_zone_size = SZ_128M,
+ .restart = da8xx_restart,
+ .reserve = da8xx_rproc_reserve_cma,
+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 000000000..b46b4d25f
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -0,0 +1,428 @@
+/*
+ * 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 <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_data/i2c-davinci.h>
+#include <linux/platform_data/mtd-davinci.h>
+#include <linux/platform_data/mmc-davinci.h>
+#include <linux/platform_data/usb-davinci.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/serial.h>
+#include <mach/common.h>
+
+#include "davinci.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,
+ .bbt_options = NAND_BBT_USE_FLASH,
+ .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",
+};
+
+/* venc standards timings */
+static struct vpbe_enc_mode_info dm355evm_enc_preset_timing[] = {
+ {
+ .name = "ntsc",
+ .timings_type = VPBE_ENC_STD,
+ .std_id = V4L2_STD_NTSC,
+ .interlaced = 1,
+ .xres = 720,
+ .yres = 480,
+ .aspect = {11, 10},
+ .fps = {30000, 1001},
+ .left_margin = 0x79,
+ .upper_margin = 0x10,
+ },
+ {
+ .name = "pal",
+ .timings_type = VPBE_ENC_STD,
+ .std_id = V4L2_STD_PAL,
+ .interlaced = 1,
+ .xres = 720,
+ .yres = 576,
+ .aspect = {54, 59},
+ .fps = {25, 1},
+ .left_margin = 0x7E,
+ .upper_margin = 0x16
+ },
+};
+
+#define VENC_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
+
+/*
+ * The outputs available from VPBE + ecnoders. Keep the
+ * the order same as that of encoders. First those from venc followed by that
+ * from encoders. Index in the output refers to index on a particular encoder.
+ * Driver uses this index to pass it to encoder when it supports more than
+ * one output. Application uses index of the array to set an output.
+ */
+static struct vpbe_output dm355evm_vpbe_outputs[] = {
+ {
+ .output = {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .std = VENC_STD_ALL,
+ .capabilities = V4L2_OUT_CAP_STD,
+ },
+ .subdev_name = DM355_VPBE_VENC_SUBDEV_NAME,
+ .default_mode = "ntsc",
+ .num_modes = ARRAY_SIZE(dm355evm_enc_preset_timing),
+ .modes = dm355evm_enc_preset_timing,
+ .if_params = MEDIA_BUS_FMT_FIXED,
+ },
+};
+
+static struct vpbe_config dm355evm_display_cfg = {
+ .module_name = "dm355-vpbe-display",
+ .i2c_adapter_id = 1,
+ .osd = {
+ .module_name = DM355_VPBE_OSD_SUBDEV_NAME,
+ },
+ .venc = {
+ .module_name = DM355_VPBE_VENC_SUBDEV_NAME,
+ },
+ .num_outputs = ARRAY_SIZE(dm355evm_vpbe_outputs),
+ .outputs = dm355evm_vpbe_outputs,
+};
+
+static struct platform_device *davinci_evm_devices[] __initdata = {
+ &dm355evm_dm9000,
+ &davinci_nand_device,
+};
+
+static void __init dm355_evm_map_io(void)
+{
+ 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,
+};
+
+/* 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.
+ */
+#define USB_ID_VALUE 1 /* ID pulled low */
+
+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;
+ int ret;
+
+ ret = dm355_gpio_register();
+ if (ret)
+ pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
+
+ 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_prepare_enable(aemif);
+
+ platform_add_devices(davinci_evm_devices,
+ ARRAY_SIZE(davinci_evm_devices));
+ evm_init_i2c();
+ davinci_serial_init(dm355_serial_device);
+
+ /* 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_video(&vpfe_cfg, &dm355evm_display_cfg);
+
+ 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")
+ .atag_offset = 0x100,
+ .map_io = dm355_evm_map_io,
+ .init_irq = davinci_irq_init,
+ .init_time = davinci_timer_init,
+ .init_machine = dm355_evm_init,
+ .init_late = davinci_init_late,
+ .dma_zone_size = SZ_128M,
+ .restart = davinci_restart,
+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 000000000..680a7a2d9
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -0,0 +1,281 @@
+/*
+ * 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 <linux/platform_data/i2c-davinci.h>
+#include <linux/platform_data/mmc-davinci.h>
+#include <linux/platform_data/mtd-davinci.h>
+#include <linux/platform_data/usb-davinci.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/common.h>
+#include <mach/serial.h>
+
+#include "davinci.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,
+ .ecc_bits = 4,
+ .bbt_options = NAND_BBT_USE_FLASH,
+};
+
+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 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.
+ */
+#define USB_ID_VALUE 1 /* ID pulled low */
+
+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;
+ int ret;
+
+ ret = dm355_gpio_register();
+ if (ret)
+ pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
+
+ 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_prepare_enable(aemif);
+
+ platform_add_devices(davinci_leopard_devices,
+ ARRAY_SIZE(davinci_leopard_devices));
+ leopard_init_i2c();
+ davinci_serial_init(dm355_serial_device);
+
+ /* 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")
+ .atag_offset = 0x100,
+ .map_io = dm355_leopard_map_io,
+ .init_irq = davinci_irq_init,
+ .init_time = davinci_timer_init,
+ .init_machine = dm355_leopard_init,
+ .init_late = davinci_init_late,
+ .dma_zone_size = SZ_128M,
+ .restart = davinci_restart,
+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 000000000..a75600359
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -0,0 +1,787 @@
+/*
+ * 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/platform_data/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 <linux/v4l2-dv-timings.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/mux.h>
+#include <mach/common.h>
+#include <linux/platform_data/i2c-davinci.h>
+#include <mach/serial.h>
+#include <linux/platform_data/mmc-davinci.h>
+#include <linux/platform_data/mtd-davinci.h>
+#include <linux/platform_data/keyscan-davinci.h>
+
+#include <media/ths7303.h>
+#include <media/tvp514x.h>
+
+#include "davinci.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 "davinci_mdio-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 = 30 * 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,
+ .bbt_options = NAND_BBT_USE_FLASH,
+ .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 __maybe_unused = {
+ .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,
+};
+
+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",
+};
+
+/* venc standards timings */
+static struct vpbe_enc_mode_info dm365evm_enc_std_timing[] = {
+ {
+ .name = "ntsc",
+ .timings_type = VPBE_ENC_STD,
+ .std_id = V4L2_STD_NTSC,
+ .interlaced = 1,
+ .xres = 720,
+ .yres = 480,
+ .aspect = {11, 10},
+ .fps = {30000, 1001},
+ .left_margin = 0x79,
+ .upper_margin = 0x10,
+ },
+ {
+ .name = "pal",
+ .timings_type = VPBE_ENC_STD,
+ .std_id = V4L2_STD_PAL,
+ .interlaced = 1,
+ .xres = 720,
+ .yres = 576,
+ .aspect = {54, 59},
+ .fps = {25, 1},
+ .left_margin = 0x7E,
+ .upper_margin = 0x16,
+ },
+};
+
+/* venc dv timings */
+static struct vpbe_enc_mode_info dm365evm_enc_preset_timing[] = {
+ {
+ .name = "480p59_94",
+ .timings_type = VPBE_ENC_DV_TIMINGS,
+ .dv_timings = V4L2_DV_BT_CEA_720X480P59_94,
+ .interlaced = 0,
+ .xres = 720,
+ .yres = 480,
+ .aspect = {1, 1},
+ .fps = {5994, 100},
+ .left_margin = 0x8F,
+ .upper_margin = 0x2D,
+ },
+ {
+ .name = "576p50",
+ .timings_type = VPBE_ENC_DV_TIMINGS,
+ .dv_timings = V4L2_DV_BT_CEA_720X576P50,
+ .interlaced = 0,
+ .xres = 720,
+ .yres = 576,
+ .aspect = {1, 1},
+ .fps = {50, 1},
+ .left_margin = 0x8C,
+ .upper_margin = 0x36,
+ },
+ {
+ .name = "720p60",
+ .timings_type = VPBE_ENC_DV_TIMINGS,
+ .dv_timings = V4L2_DV_BT_CEA_1280X720P60,
+ .interlaced = 0,
+ .xres = 1280,
+ .yres = 720,
+ .aspect = {1, 1},
+ .fps = {60, 1},
+ .left_margin = 0x117,
+ .right_margin = 70,
+ .upper_margin = 38,
+ .lower_margin = 3,
+ .hsync_len = 80,
+ .vsync_len = 5,
+ },
+ {
+ .name = "1080i60",
+ .timings_type = VPBE_ENC_DV_TIMINGS,
+ .dv_timings = V4L2_DV_BT_CEA_1920X1080I60,
+ .interlaced = 1,
+ .xres = 1920,
+ .yres = 1080,
+ .aspect = {1, 1},
+ .fps = {30, 1},
+ .left_margin = 0xc9,
+ .right_margin = 80,
+ .upper_margin = 30,
+ .lower_margin = 3,
+ .hsync_len = 88,
+ .vsync_len = 5,
+ },
+};
+
+#define VENC_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
+
+/*
+ * The outputs available from VPBE + ecnoders. Keep the
+ * the order same as that of encoders. First those from venc followed by that
+ * from encoders. Index in the output refers to index on a particular
+ * encoder.Driver uses this index to pass it to encoder when it supports more
+ * than one output. Application uses index of the array to set an output.
+ */
+static struct vpbe_output dm365evm_vpbe_outputs[] = {
+ {
+ .output = {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .std = VENC_STD_ALL,
+ .capabilities = V4L2_OUT_CAP_STD,
+ },
+ .subdev_name = DM365_VPBE_VENC_SUBDEV_NAME,
+ .default_mode = "ntsc",
+ .num_modes = ARRAY_SIZE(dm365evm_enc_std_timing),
+ .modes = dm365evm_enc_std_timing,
+ .if_params = MEDIA_BUS_FMT_FIXED,
+ },
+ {
+ .output = {
+ .index = 1,
+ .name = "Component",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .capabilities = V4L2_OUT_CAP_DV_TIMINGS,
+ },
+ .subdev_name = DM365_VPBE_VENC_SUBDEV_NAME,
+ .default_mode = "480p59_94",
+ .num_modes = ARRAY_SIZE(dm365evm_enc_preset_timing),
+ .modes = dm365evm_enc_preset_timing,
+ .if_params = MEDIA_BUS_FMT_FIXED,
+ },
+};
+
+/*
+ * Amplifiers on the board
+ */
+static struct ths7303_platform_data ths7303_pdata = {
+ .ch_1 = 3,
+ .ch_2 = 3,
+ .ch_3 = 3,
+};
+
+static struct amp_config_info vpbe_amp = {
+ .module_name = "ths7303",
+ .is_i2c = 1,
+ .board_info = {
+ I2C_BOARD_INFO("ths7303", 0x2c),
+ .platform_data = &ths7303_pdata,
+ }
+};
+
+static struct vpbe_config dm365evm_display_cfg = {
+ .module_name = "dm365-vpbe-display",
+ .i2c_adapter_id = 1,
+ .amp = &vpbe_amp,
+ .osd = {
+ .module_name = DM365_VPBE_OSD_SUBDEV_NAME,
+ },
+ .venc = {
+ .module_name = DM365_VPBE_VENC_SUBDEV_NAME,
+ },
+ .num_outputs = ARRAY_SIZE(dm365evm_vpbe_outputs),
+ .outputs = dm365evm_vpbe_outputs,
+};
+
+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_prepare_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_unprepare(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 void __init dm365_evm_map_io(void)
+{
+ 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)
+{
+ int ret;
+
+ ret = dm365_gpio_register();
+ if (ret)
+ pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
+
+ evm_init_i2c();
+ davinci_serial_init(dm365_serial_device);
+
+ dm365evm_emac_configure();
+ dm365evm_mmc_configure();
+
+ davinci_setup_mmc(0, &dm365evm_mmc_config);
+
+ dm365_init_video(&vpfe_cfg, &dm365evm_display_cfg);
+
+ /* 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")
+ .atag_offset = 0x100,
+ .map_io = dm365_evm_map_io,
+ .init_irq = davinci_irq_init,
+ .init_time = davinci_timer_init,
+ .init_machine = dm365_evm_init,
+ .init_late = davinci_init_late,
+ .dma_zone_size = SZ_128M,
+ .restart = davinci_restart,
+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 000000000..1a0898c1c
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -0,0 +1,823 @@
+/*
+ * 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/platform_data/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 <linux/v4l2-dv-timings.h>
+#include <linux/export.h>
+
+#include <media/tvp514x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/common.h>
+#include <linux/platform_data/i2c-davinci.h>
+#include <mach/serial.h>
+#include <mach/mux.h>
+#include <linux/platform_data/mtd-davinci.h>
+#include <linux/platform_data/mmc-davinci.h>
+#include <linux/platform_data/usb-davinci.h>
+#include <linux/platform_data/mtd-davinci-aemif.h>
+
+#include "davinci.h"
+
+#define DM644X_EVM_PHY_ID "davinci_mdio-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,
+ .ecc_bits = 1,
+ .bbt_options = NAND_BBT_USE_FLASH,
+ .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 dm644xevm_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 dm644xevm_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 dm644xevm_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 dm644xevm_vpfe_sub_devs[] = {
+ {
+ .name = "tvp5146",
+ .grp_id = 0,
+ .num_inputs = ARRAY_SIZE(dm644xevm_tvp5146_inputs),
+ .inputs = dm644xevm_tvp5146_inputs,
+ .routes = dm644xevm_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 = &dm644xevm_tvp5146_pdata,
+ },
+ },
+};
+
+static struct vpfe_config dm644xevm_capture_cfg = {
+ .num_subdevs = ARRAY_SIZE(dm644xevm_vpfe_sub_devs),
+ .i2c_adapter_id = 1,
+ .sub_devs = dm644xevm_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] = {
+ {
+ .flags = 0,
+ .len = 2,
+ .buf = (void __force *)txbuf,
+ },
+ {
+ .flags = I2C_M_RD,
+ .len = 4,
+ .buf = buf,
+ },
+ };
+ int status;
+
+ if (!dm6446evm_msp)
+ return -ENXIO;
+
+ msg[0].addr = dm6446evm_msp->addr;
+ msg[1].addr = dm6446evm_msp->addr;
+
+ /* 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,
+};
+
+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));
+}
+
+#define VENC_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
+
+/* venc standard timings */
+static struct vpbe_enc_mode_info dm644xevm_enc_std_timing[] = {
+ {
+ .name = "ntsc",
+ .timings_type = VPBE_ENC_STD,
+ .std_id = V4L2_STD_NTSC,
+ .interlaced = 1,
+ .xres = 720,
+ .yres = 480,
+ .aspect = {11, 10},
+ .fps = {30000, 1001},
+ .left_margin = 0x79,
+ .upper_margin = 0x10,
+ },
+ {
+ .name = "pal",
+ .timings_type = VPBE_ENC_STD,
+ .std_id = V4L2_STD_PAL,
+ .interlaced = 1,
+ .xres = 720,
+ .yres = 576,
+ .aspect = {54, 59},
+ .fps = {25, 1},
+ .left_margin = 0x7e,
+ .upper_margin = 0x16,
+ },
+};
+
+/* venc dv preset timings */
+static struct vpbe_enc_mode_info dm644xevm_enc_preset_timing[] = {
+ {
+ .name = "480p59_94",
+ .timings_type = VPBE_ENC_DV_TIMINGS,
+ .dv_timings = V4L2_DV_BT_CEA_720X480P59_94,
+ .interlaced = 0,
+ .xres = 720,
+ .yres = 480,
+ .aspect = {1, 1},
+ .fps = {5994, 100},
+ .left_margin = 0x80,
+ .upper_margin = 0x20,
+ },
+ {
+ .name = "576p50",
+ .timings_type = VPBE_ENC_DV_TIMINGS,
+ .dv_timings = V4L2_DV_BT_CEA_720X576P50,
+ .interlaced = 0,
+ .xres = 720,
+ .yres = 576,
+ .aspect = {1, 1},
+ .fps = {50, 1},
+ .left_margin = 0x7e,
+ .upper_margin = 0x30,
+ },
+};
+
+/*
+ * The outputs available from VPBE + encoders. Keep the order same
+ * as that of encoders. First those from venc followed by that from
+ * encoders. Index in the output refers to index on a particular encoder.
+ * Driver uses this index to pass it to encoder when it supports more
+ * than one output. Userspace applications use index of the array to
+ * set an output.
+ */
+static struct vpbe_output dm644xevm_vpbe_outputs[] = {
+ {
+ .output = {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .std = VENC_STD_ALL,
+ .capabilities = V4L2_OUT_CAP_STD,
+ },
+ .subdev_name = DM644X_VPBE_VENC_SUBDEV_NAME,
+ .default_mode = "ntsc",
+ .num_modes = ARRAY_SIZE(dm644xevm_enc_std_timing),
+ .modes = dm644xevm_enc_std_timing,
+ },
+ {
+ .output = {
+ .index = 1,
+ .name = "Component",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .capabilities = V4L2_OUT_CAP_DV_TIMINGS,
+ },
+ .subdev_name = DM644X_VPBE_VENC_SUBDEV_NAME,
+ .default_mode = "480p59_94",
+ .num_modes = ARRAY_SIZE(dm644xevm_enc_preset_timing),
+ .modes = dm644xevm_enc_preset_timing,
+ },
+};
+
+static struct vpbe_config dm644xevm_display_cfg = {
+ .module_name = "dm644x-vpbe-display",
+ .i2c_adapter_id = 1,
+ .osd = {
+ .module_name = DM644X_VPBE_OSD_SUBDEV_NAME,
+ },
+ .venc = {
+ .module_name = DM644X_VPBE_VENC_SUBDEV_NAME,
+ },
+ .num_outputs = ARRAY_SIZE(dm644xevm_vpbe_outputs),
+ .outputs = dm644xevm_vpbe_outputs,
+};
+
+static struct platform_device *davinci_evm_devices[] __initdata = {
+ &davinci_fb_device,
+ &rtc_dev,
+};
+
+static void __init
+davinci_evm_map_io(void)
+{
+ 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;
+}
+
+#define HAS_ATA IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710)
+
+#define HAS_NOR IS_ENABLED(CONFIG_MTD_PHYSMAP)
+
+#define HAS_NAND IS_ENABLED(CONFIG_MTD_NAND_DAVINCI)
+
+static __init void davinci_evm_init(void)
+{
+ int ret;
+ struct clk *aemif_clk;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ ret = dm644x_gpio_register();
+ if (ret)
+ pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
+
+ aemif_clk = clk_get(NULL, "aemif");
+ clk_prepare_enable(aemif_clk);
+
+ if (HAS_ATA) {
+ if (HAS_NAND || HAS_NOR)
+ pr_warn("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);
+
+ if (davinci_aemif_setup(&davinci_evm_nandflash_device))
+ pr_warn("%s: Cannot configure AEMIF\n",
+ __func__);
+
+ evm_leds[7].default_trigger = "nand-disk";
+ if (HAS_NOR)
+ pr_warn("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);
+ dm644x_init_video(&dm644xevm_capture_cfg, &dm644xevm_display_cfg);
+
+ davinci_serial_init(dm644x_serial_device);
+ dm644x_init_asp(&dm644x_evm_snd_data);
+
+ /* irlml6401 switches over 1A, in under 8 msec */
+ davinci_setup_usb(1000, 8);
+
+ if (IS_BUILTIN(CONFIG_PHYLIB)) {
+ 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> */
+ .atag_offset = 0x100,
+ .map_io = davinci_evm_map_io,
+ .init_irq = davinci_irq_init,
+ .init_time = davinci_timer_init,
+ .init_machine = davinci_evm_init,
+ .init_late = davinci_init_late,
+ .dma_zone_size = SZ_128M,
+ .restart = davinci_restart,
+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 000000000..846a84ddc
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -0,0 +1,809 @@
+/*
+ * 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/platform_data/at24.h>
+#include <linux/i2c/pcf857x.h>
+
+#include <media/tvp514x.h>
+#include <media/adv7343.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/clk.h>
+#include <linux/export.h>
+#include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_data/i2c-davinci.h>
+#include <linux/platform_data/mtd-davinci.h>
+#include <linux/platform_data/mtd-davinci-aemif.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/common.h>
+#include <mach/irqs.h>
+#include <mach/serial.h>
+#include <mach/clock.h>
+
+#include "davinci.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,
+ .ecc_bits = 1,
+ .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,
+ },
+};
+
+#define HAS_ATA IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710)
+
+/* 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 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),
+ },
+};
+
+static struct davinci_i2c_platform_data i2c_pdata = {
+ .bus_freq = 100 /* kHz */,
+ .bus_delay = 0 /* usec */,
+};
+
+#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"
+
+/* 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 (!cpld_client)
+ return -ENXIO;
+
+ /* disable the clock */
+ spin_lock_irqsave(&vpif_reg_lock, flags);
+ value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
+ value |= (VIDCH3CLK | VIDCH2CLK);
+ __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
+ 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(DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL));
+ value &= ~(VCH2CLK_MASK);
+ value &= ~(VCH3CLK_MASK);
+
+ if (hd >= 1)
+ value |= (VCH2CLK_SYSCLK8 | VCH3CLK_SYSCLK8);
+ else
+ value |= (VCH2CLK_AUXCLK | VCH3CLK_AUXCLK);
+
+ __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL));
+
+ spin_lock_irqsave(&vpif_reg_lock, flags);
+ value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
+ /* enable the clock */
+ value &= ~(VIDCH3CLK | VIDCH2CLK);
+ __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
+ 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 struct vpif_output dm6467_ch0_outputs[] = {
+ {
+ .output = {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .capabilities = V4L2_OUT_CAP_STD,
+ .std = V4L2_STD_ALL,
+ },
+ .subdev_name = "adv7343",
+ .output_route = ADV7343_COMPOSITE_ID,
+ },
+ {
+ .output = {
+ .index = 1,
+ .name = "Component",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .capabilities = V4L2_OUT_CAP_DV_TIMINGS,
+ },
+ .subdev_name = "adv7343",
+ .output_route = ADV7343_COMPONENT_ID,
+ },
+ {
+ .output = {
+ .index = 2,
+ .name = "S-Video",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .capabilities = V4L2_OUT_CAP_STD,
+ .std = V4L2_STD_ALL,
+ },
+ .subdev_name = "adv7343",
+ .output_route = ADV7343_SVIDEO_ID,
+ },
+};
+
+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),
+ .chan_config[0] = {
+ .outputs = dm6467_ch0_outputs,
+ .output_count = ARRAY_SIZE(dm6467_ch0_outputs),
+ },
+ .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 (!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(DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL));
+ if (mux_mode) {
+ val &= VPIF_INPUT_TWO_CHANNEL;
+ value |= VIDCH1CLK;
+ } else {
+ val |= VPIF_INPUT_ONE_CHANNEL;
+ value &= ~VIDCH1CLK;
+ }
+ __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL));
+ 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,
+ },
+ },
+ {
+ .name = TVP5147_CH1,
+ .board_info = {
+ I2C_BOARD_INFO("tvp5146", 0x5c),
+ .platform_data = &tvp5146_pdata,
+ },
+ },
+};
+
+static const struct vpif_input dm6467_ch0_inputs[] = {
+ {
+ .input = {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .capabilities = V4L2_IN_CAP_STD,
+ .std = TVP514X_STD_ALL,
+ },
+ .subdev_name = TVP5147_CH0,
+ .input_route = INPUT_CVBS_VI2B,
+ .output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ },
+};
+
+static const struct vpif_input dm6467_ch1_inputs[] = {
+ {
+ .input = {
+ .index = 0,
+ .name = "S-Video",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .capabilities = V4L2_IN_CAP_STD,
+ .std = TVP514X_STD_ALL,
+ },
+ .subdev_name = TVP5147_CH1,
+ .input_route = INPUT_SVIDEO_VI2C_VI1C,
+ .output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ },
+};
+
+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),
+ .vpif_if = {
+ .if_type = VPIF_IF_BT656,
+ .hd_pol = 1,
+ .vd_pol = 1,
+ .fid_pol = 0,
+ },
+ },
+ .chan_config[1] = {
+ .inputs = dm6467_ch1_inputs,
+ .input_count = ARRAY_SIZE(dm6467_ch1_inputs),
+ .vpif_if = {
+ .if_type = VPIF_IF_BT656,
+ .hd_pol = 1,
+ .vd_pol = 1,
+ .fid_pol = 0,
+ },
+ },
+};
+
+static void __init evm_init_video(void)
+{
+ 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 DM6467T_EVM_REF_FREQ 33000000
+
+static void __init davinci_map_io(void)
+{
+ dm646x_init();
+
+ if (machine_is_davinci_dm6467tevm())
+ davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
+}
+
+#define DM646X_EVM_PHY_ID "davinci_mdio-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)
+{
+ int ret;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ ret = dm646x_gpio_register();
+ if (ret)
+ pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
+
+ evm_init_i2c();
+ davinci_serial_init(dm646x_serial_device);
+ 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);
+
+ if (davinci_aemif_setup(&davinci_nand_device))
+ pr_warn("%s: Cannot configure AEMIF.\n", __func__);
+
+ dm646x_init_edma(dm646x_edma_rsv);
+
+ if (HAS_ATA)
+ davinci_init_ide();
+
+ soc_info->emac_pdata->phy_id = DM646X_EVM_PHY_ID;
+}
+
+MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
+ .atag_offset = 0x100,
+ .map_io = davinci_map_io,
+ .init_irq = davinci_irq_init,
+ .init_time = davinci_timer_init,
+ .init_machine = evm_init,
+ .init_late = davinci_init_late,
+ .dma_zone_size = SZ_128M,
+ .restart = davinci_restart,
+MACHINE_END
+
+MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
+ .atag_offset = 0x100,
+ .map_io = davinci_map_io,
+ .init_irq = davinci_irq_init,
+ .init_time = davinci_timer_init,
+ .init_machine = evm_init,
+ .init_late = davinci_init_late,
+ .dma_zone_size = SZ_128M,
+ .restart = davinci_restart,
+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 000000000..8cfbfe084
--- /dev/null
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -0,0 +1,582 @@
+/*
+ * 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.
+ */
+
+#define pr_fmt(fmt) "MityOMAPL138: " fmt
+
+#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/platform_data/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 <linux/platform_data/mtd-davinci.h>
+#include <linux/platform_data/mtd-davinci-aemif.h>
+#include <mach/mux.h>
+#include <linux/platform_data/spi-davinci.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_warn("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_warn("Read Factory Config Failed: %d\n", ret);
+ goto bad_config;
+ }
+
+ if (factory_config.magic != FACTORY_CONFIG_MAGIC) {
+ pr_warn("Factory Config Magic Wrong (%X)\n",
+ factory_config.magic);
+ goto bad_config;
+ }
+
+ if (factory_config.version != FACTORY_CONFIG_VERSION) {
+ pr_warn("Factory Config Version Wrong (%X)\n",
+ factory_config.version);
+ goto bad_config;
+ }
+
+ pr_info("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_warn("Invalid MAC found in factory config block\n");
+
+ partnum = factory_config.partnum;
+ pr_info("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,
+ .bbt_options = NAND_BBT_USE_FLASH,
+ .options = 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));
+
+ if (davinci_aemif_setup(&mityomapl138_nandflash_device))
+ pr_warn("%s: Cannot configure AEMIF\n", __func__);
+}
+
+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_warn("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_warn("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_warn("edma registration failed: %d\n", ret);
+
+ ret = da8xx_register_watchdog();
+ if (ret)
+ pr_warn("watchdog registration failed: %d\n", ret);
+
+ davinci_serial_init(da8xx_serial_device);
+
+ ret = da8xx_register_i2c(0, &mityomap_i2c_0_pdata);
+ if (ret)
+ pr_warn("i2c0 registration failed: %d\n", ret);
+
+ ret = pmic_tps65023_init();
+ if (ret)
+ pr_warn("TPS65023 PMIC init failed: %d\n", ret);
+
+ mityomapl138_setup_nand();
+
+ ret = spi_register_board_info(mityomapl138_spi_flash_info,
+ ARRAY_SIZE(mityomapl138_spi_flash_info));
+ if (ret)
+ pr_warn("spi info registration failed: %d\n", ret);
+
+ ret = da8xx_register_spi_bus(1,
+ ARRAY_SIZE(mityomapl138_spi_flash_info));
+ if (ret)
+ pr_warn("spi 1 registration failed: %d\n", ret);
+
+ mityomapl138_config_emac();
+
+ ret = da8xx_register_rtc();
+ if (ret)
+ pr_warn("rtc setup failed: %d\n", ret);
+
+ ret = da8xx_register_cpuidle();
+ if (ret)
+ pr_warn("cpuidle registration failed: %d\n", ret);
+
+ ret = da850_register_pm(&da850_pm_device);
+ if (ret)
+ pr_warn("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")
+ .atag_offset = 0x100,
+ .map_io = mityomapl138_map_io,
+ .init_irq = cp_intc_init,
+ .init_time = davinci_timer_init,
+ .init_machine = mityomapl138_init,
+ .init_late = davinci_init_late,
+ .dma_zone_size = SZ_128M,
+ .restart = da8xx_restart,
+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 000000000..8fcdcf87c
--- /dev/null
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -0,0 +1,235 @@
+/*
+ * 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 <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_data/i2c-davinci.h>
+#include <linux/platform_data/mmc-davinci.h>
+#include <linux/platform_data/mtd-davinci.h>
+#include <linux/platform_data/usb-davinci.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/common.h>
+#include <mach/serial.h>
+#include <mach/mux.h>
+
+#include "davinci.h"
+
+#define NEUROS_OSD2_PHY_ID "davinci_mdio-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,
+ .ecc_bits = 1,
+ .bbt_options = NAND_BBT_USE_FLASH,
+};
+
+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 void __init davinci_ntosd2_map_io(void)
+{
+ dm644x_init();
+}
+
+static struct davinci_mmc_config davinci_ntosd2_mmc_config = {
+ .wires = 4,
+};
+
+#define HAS_ATA IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710)
+
+#define HAS_NAND IS_ENABLED(CONFIG_MTD_NAND_DAVINCI)
+
+static __init void davinci_ntosd2_init(void)
+{
+ int ret;
+ struct clk *aemif_clk;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ ret = dm644x_gpio_register();
+ if (ret)
+ pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
+
+ aemif_clk = clk_get(NULL, "aemif");
+ clk_prepare_enable(aemif_clk);
+
+ if (HAS_ATA) {
+ if (HAS_NAND)
+ pr_warn("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));
+
+ davinci_serial_init(dm644x_serial_device);
+ 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> */
+ .atag_offset = 0x100,
+ .map_io = davinci_ntosd2_map_io,
+ .init_irq = davinci_irq_init,
+ .init_time = davinci_timer_init,
+ .init_machine = davinci_ntosd2_init,
+ .init_late = davinci_init_late,
+ .dma_zone_size = SZ_128M,
+ .restart = davinci_restart,
+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 000000000..2aac51d0e
--- /dev/null
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -0,0 +1,348 @@
+/*
+ * 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 <linux/platform_data/gpio-davinci.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/mux.h>
+
+#define HAWKBOARD_PHY_ID "davinci_mdio-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_warn("%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_warn("%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,
+};
+
+static __init void omapl138_hawk_mmc_init(void)
+{
+ int ret;
+
+ ret = davinci_cfg_reg_list(hawk_mmcsd0_pins);
+ if (ret) {
+ pr_warn("%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_warn("%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_warn("%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_warn("%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_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_warn("%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_warn("%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 __init void omapl138_hawk_init(void)
+{
+ int ret;
+
+ ret = da850_register_gpio();
+ if (ret)
+ pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
+
+ davinci_serial_init(da8xx_serial_device);
+
+ omapl138_hawk_config_emac();
+
+ ret = da850_register_edma(da850_edma_rsv);
+ if (ret)
+ pr_warn("%s: EDMA registration failed: %d\n", __func__, ret);
+
+ omapl138_hawk_mmc_init();
+
+ omapl138_hawk_usb_init();
+
+ ret = da8xx_register_watchdog();
+ if (ret)
+ pr_warn("%s: watchdog registration failed: %d\n",
+ __func__, ret);
+
+ ret = da8xx_register_rproc();
+ if (ret)
+ pr_warn("%s: dsp/rproc registration failed: %d\n",
+ __func__, 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")
+ .atag_offset = 0x100,
+ .map_io = omapl138_hawk_map_io,
+ .init_irq = cp_intc_init,
+ .init_time = davinci_timer_init,
+ .init_machine = omapl138_hawk_init,
+ .init_late = davinci_init_late,
+ .dma_zone_size = SZ_128M,
+ .restart = da8xx_restart,
+ .reserve = da8xx_rproc_reserve_cma,
+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 000000000..41c7c9615
--- /dev/null
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -0,0 +1,158 @@
+/*
+ * 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/platform_data/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/common.h>
+#include <linux/platform_data/i2c-davinci.h>
+#include <mach/serial.h>
+#include <mach/mux.h>
+#include <linux/platform_data/usb-davinci.h>
+
+#include "davinci.h"
+
+#define SFFSDR_PHY_ID "davinci_mdio-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 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(dm644x_serial_device);
+ 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")
+ .atag_offset = 0x100,
+ .map_io = davinci_sffsdr_map_io,
+ .init_irq = davinci_irq_init,
+ .init_time = davinci_timer_init,
+ .init_machine = davinci_sffsdr_init,
+ .init_late = davinci_init_late,
+ .dma_zone_size = SZ_128M,
+ .restart = davinci_restart,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
new file mode 100644
index 000000000..c70bb0a4d
--- /dev/null
+++ b/arch/arm/mach-davinci/clock.c
@@ -0,0 +1,713 @@
+/*
+ * 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 void __clk_enable(struct clk *clk)
+{
+ if (clk->parent)
+ __clk_enable(clk->parent);
+ if (clk->usecount++ == 0) {
+ if (clk->flags & CLK_PSC)
+ davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
+ true, clk->flags);
+ else if (clk->clk_enable)
+ clk->clk_enable(clk);
+ }
+}
+
+static void __clk_disable(struct clk *clk)
+{
+ if (WARN_ON(clk->usecount == 0))
+ return;
+ if (--clk->usecount == 0) {
+ if (!(clk->flags & CLK_PLL) && (clk->flags & CLK_PSC))
+ davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
+ false, clk->flags);
+ else if (clk->clk_disable)
+ clk->clk_disable(clk);
+ }
+ if (clk->parent)
+ __clk_disable(clk->parent);
+}
+
+int davinci_clk_reset(struct clk *clk, bool reset)
+{
+ unsigned long flags;
+
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ if (clk->flags & CLK_PSC)
+ davinci_psc_reset(clk->gpsc, clk->lpsc, reset);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(davinci_clk_reset);
+
+int davinci_clk_reset_assert(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk) || !clk->reset)
+ return -EINVAL;
+
+ return clk->reset(clk, true);
+}
+EXPORT_SYMBOL(davinci_clk_reset_assert);
+
+int davinci_clk_reset_deassert(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk) || !clk->reset)
+ return -EINVAL;
+
+ return clk->reset(clk, false);
+}
+EXPORT_SYMBOL(davinci_clk_reset_deassert);
+
+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 0;
+
+ 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
+ */
+int __init davinci_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(ck->domain, ck->gpsc, ck->lpsc,
+ false, ck->flags);
+ }
+ spin_unlock_irq(&clockfw_lock);
+
+ return 0;
+}
+#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;
+}
+
+int davinci_simple_set_rate(struct clk *clk, unsigned long rate)
+{
+ clk->rate = rate;
+ return 0;
+}
+
+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);
+
+/**
+ * davinci_set_refclk_rate() - Set the reference clock rate
+ * @rate: The new rate.
+ *
+ * Sets the reference clock rate to a given value. This will most likely
+ * result in the entire clock tree getting updated.
+ *
+ * This is used to support boards which use a reference clock different
+ * than that used by default in <soc>.c file. The reference clock rate
+ * should be updated early in the boot process; ideally soon after the
+ * clock tree has been initialized once with the default reference clock
+ * rate (davinci_common_init()).
+ *
+ * Returns 0 on success, error otherwise.
+ */
+int davinci_set_refclk_rate(unsigned long rate)
+{
+ struct clk *refclk;
+
+ refclk = clk_get(NULL, "ref");
+ if (IS_ERR(refclk)) {
+ pr_err("%s: failed to get reference clock\n", __func__);
+ return PTR_ERR(refclk);
+ }
+
+ clk_set_rate(refclk, rate);
+
+ clk_put(refclk);
+
+ return 0;
+}
+
+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;
+
+ if (clk->flags & PSC_LRST)
+ clk->reset = davinci_clk_reset;
+
+ 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 000000000..1e4e83617
--- /dev/null
+++ b/arch/arm/mach-davinci/clock.h
@@ -0,0 +1,140 @@
+/*
+ * 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;
+ u8 domain;
+ 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);
+ int (*reset) (struct clk *clk, bool reset);
+ void (*clk_enable) (struct clk *clk);
+ void (*clk_disable) (struct clk *clk);
+};
+
+/* Clock flags: SoC-specific flags start at BIT(16) */
+#define ALWAYS_ENABLED BIT(1)
+#define CLK_PSC BIT(2)
+#define CLK_PLL BIT(3) /* PLL-derived clock */
+#define PRE_PLL BIT(4) /* source is before PLL mult/div */
+#define PSC_SWRSTDISABLE BIT(5) /* Disable state is SwRstDisable */
+#define PSC_FORCE BIT(6) /* Force module state transtition */
+#define PSC_LRST BIT(8) /* Use local reset on enable/disable */
+
+#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);
+int davinci_set_refclk_rate(unsigned long rate);
+int davinci_simple_set_rate(struct clk *clk, unsigned long rate);
+int davinci_clk_reset(struct clk *clk, bool reset);
+
+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 000000000..a794f6d9d
--- /dev/null
+++ b/arch/arm/mach-davinci/common.c
@@ -0,0 +1,124 @@
+/*
+ * 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 <linux/dma-mapping.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();
+
+ /*
+ * 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");
+}
+
+void __init davinci_init_late(void)
+{
+ davinci_cpufreq_init();
+ davinci_pm_init();
+ davinci_clk_disable_unused();
+}
diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c
new file mode 100644
index 000000000..006dae8df
--- /dev/null
+++ b/arch/arm/mach-davinci/cp_intc.c
@@ -0,0 +1,222 @@
+/*
+ * 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/export.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.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->hwirq, 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->hwirq, 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->hwirq, 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->hwirq);
+ unsigned mask = BIT_MASK(d->hwirq);
+ 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,
+};
+
+static struct irq_domain *cp_intc_domain;
+
+static int cp_intc_host_map(struct irq_domain *h, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ pr_debug("cp_intc_host_map(%d, 0x%lx)\n", virq, hw);
+
+ irq_set_chip(virq, &cp_intc_irq_chip);
+ set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
+ irq_set_handler(virq, handle_edge_irq);
+ return 0;
+}
+
+static const struct irq_domain_ops cp_intc_host_ops = {
+ .map = cp_intc_host_map,
+ .xlate = irq_domain_xlate_onetwocell,
+};
+
+int __init cp_intc_of_init(struct device_node *node, struct device_node *parent)
+{
+ u32 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, irq_base;
+
+ davinci_intc_type = DAVINCI_INTC_TYPE_CP_INTC;
+ if (node) {
+ davinci_intc_base = of_iomap(node, 0);
+ if (of_property_read_u32(node, "ti,intc-size", &num_irq))
+ pr_warn("unable to get intc-size, default to %d\n",
+ num_irq);
+ } else {
+ davinci_intc_base = ioremap(davinci_soc_info.intc_base, SZ_8K);
+ }
+ if (WARN_ON(!davinci_intc_base))
+ return -EINVAL;
+
+ 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));
+
+ irq_base = irq_alloc_descs(-1, 0, num_irq, 0);
+ if (irq_base < 0) {
+ pr_warn("Couldn't allocate IRQ numbers\n");
+ irq_base = 0;
+ }
+
+ /* create a legacy host */
+ cp_intc_domain = irq_domain_add_legacy(node, num_irq,
+ irq_base, 0, &cp_intc_host_ops, NULL);
+
+ if (!cp_intc_domain) {
+ pr_err("cp_intc: failed to allocate irq host!\n");
+ return -EINVAL;
+ }
+
+ /* Enable global interrupt */
+ cp_intc_write(1, CP_INTC_GLOBAL_ENABLE);
+
+ return 0;
+}
+
+void __init cp_intc_init(void)
+{
+ cp_intc_of_init(NULL, NULL);
+}
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
new file mode 100644
index 000000000..306ebc515
--- /dev/null
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -0,0 +1,102 @@
+/*
+ * 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 <linux/export.h>
+#include <asm/cpuidle.h>
+
+#include <mach/cpuidle.h>
+#include <mach/ddr2.h>
+
+#define DAVINCI_CPUIDLE_MAX_STATES 2
+
+static void __iomem *ddr2_reg_base;
+static bool ddr2_pdown;
+
+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);
+}
+
+/* Actual code that puts the SoC in different idle states */
+static int davinci_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ davinci_save_ddr_power(1, ddr2_pdown);
+ cpu_do_idle();
+ davinci_save_ddr_power(0, ddr2_pdown);
+
+ return index;
+}
+
+static struct cpuidle_driver davinci_idle_driver = {
+ .name = "cpuidle-davinci",
+ .owner = THIS_MODULE,
+ .states[0] = ARM_CPUIDLE_WFI_STATE,
+ .states[1] = {
+ .enter = davinci_enter_idle,
+ .exit_latency = 10,
+ .target_residency = 10000,
+ .name = "DDR SR",
+ .desc = "WFI and DDR Self Refresh",
+ },
+ .state_count = DAVINCI_CPUIDLE_MAX_STATES,
+};
+
+static int __init davinci_cpuidle_probe(struct platform_device *pdev)
+{
+ struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "cannot get platform data\n");
+ return -ENOENT;
+ }
+
+ ddr2_reg_base = pdata->ddr2_ctlr_base;
+
+ ddr2_pdown = pdata->ddr2_pdown;
+
+ return cpuidle_register(&davinci_idle_driver, NULL);
+}
+
+static struct platform_driver davinci_cpuidle_driver = {
+ .driver = {
+ .name = "cpuidle-davinci",
+ },
+};
+
+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 000000000..115d5736d
--- /dev/null
+++ b/arch/arm/mach-davinci/da830.c
@@ -0,0 +1,1217 @@
+/*
+ * 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/gpio.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_data/gpio-davinci.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 "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("davinci-wdt", 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("da830-mmc.0", NULL, &mmcsd_clk),
+ CLK("serial8250.0", NULL, &uart0_clk),
+ CLK("serial8250.1", NULL, &uart1_clk),
+ CLK("serial8250.2", NULL, &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", "fck", &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("davinci_mdio.0", "fck", &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[] __initconst = {
+ 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[] __initconst = {
+ DA830_SPI0_SOMI_0, DA830_SPI0_SIMO_0, DA830_SPI0_CLK, DA830_NSPI0_ENA,
+ DA830_NSPI0_SCS_0,
+ -1
+};
+
+const short da830_spi1_pins[] __initconst = {
+ 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[] __initconst = {
+ 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[] __initconst = {
+ DA830_NUART0_CTS, DA830_NUART0_RTS, DA830_UART0_RXD, DA830_UART0_TXD,
+ -1
+};
+
+const short da830_uart1_pins[] __initconst = {
+ DA830_UART1_RXD, DA830_UART1_TXD,
+ -1
+};
+
+const short da830_uart2_pins[] __initconst = {
+ DA830_UART2_RXD, DA830_UART2_TXD,
+ -1
+};
+
+const short da830_usb20_pins[] __initconst = {
+ DA830_USB0_DRVVBUS, DA830_USB_REFCLKIN,
+ -1
+};
+
+const short da830_usb11_pins[] __initconst = {
+ DA830_USB_REFCLKIN,
+ -1
+};
+
+const short da830_uhpi_pins[] __initconst = {
+ 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[] __initconst = {
+ 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[] __initconst = {
+ 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[] __initconst = {
+ 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[] __initconst = {
+ 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[] __initconst = {
+ 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[] __initconst = {
+ DA830_I2C0_SDA, DA830_I2C0_SCL,
+ -1
+};
+
+const short da830_i2c1_pins[] __initconst = {
+ DA830_I2C1_SCL, DA830_I2C1_SDA,
+ -1
+};
+
+const short da830_lcdcntl_pins[] __initconst = {
+ 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[] __initconst = {
+ 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[] __initconst = {
+ DA830_ECAP0_APWM0,
+ -1
+};
+
+const short da830_ecap1_pins[] __initconst = {
+ DA830_ECAP1_APWM1,
+ -1
+};
+
+const short da830_ecap2_pins[] __initconst = {
+ DA830_ECAP2_APWM2,
+ -1
+};
+
+const short da830_eqep0_pins[] __initconst = {
+ DA830_EQEP0I, DA830_EQEP0S, DA830_EQEP0A, DA830_EQEP0B,
+ -1
+};
+
+const short da830_eqep1_pins[] __initconst = {
+ 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_gpio_platform_data da830_gpio_platform_data = {
+ .ngpio = 128,
+};
+
+int __init da830_register_gpio(void)
+{
+ return da8xx_register_gpio(&da830_gpio_platform_data);
+}
+
+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,
+ .emac_pdata = &da8xx_emac_pdata,
+};
+
+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 000000000..45ce065e7
--- /dev/null
+++ b/arch/arm/mach-davinci/da850.c
@@ -0,0 +1,1348 @@
+/*
+ * 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/gpio.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/cpufreq.h>
+#include <linux/regulator/consumer.h>
+#include <linux/platform_data/gpio-davinci.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 "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,
+ .set_rate = davinci_simple_set_rate,
+};
+
+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_sysclk1 = {
+ .name = "pll0_sysclk1",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+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 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 pruss_clk = {
+ .name = "pruss",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_PRUSS,
+};
+
+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 vpif_clk = {
+ .name = "vpif",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA850_LPSC1_VPIF,
+ .gpsc = 1,
+};
+
+static struct clk sata_clk = {
+ .name = "sata",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA850_LPSC1_SATA,
+ .gpsc = 1,
+ .flags = PSC_FORCE,
+};
+
+static struct clk dsp_clk = {
+ .name = "dsp",
+ .parent = &pll0_sysclk1,
+ .domain = DAVINCI_GPSC_DSPDOMAIN,
+ .lpsc = DA8XX_LPSC0_GEM,
+ .flags = PSC_LRST | PSC_FORCE,
+};
+
+static struct clk ehrpwm_clk = {
+ .name = "ehrpwm",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_PWM,
+ .gpsc = 1,
+ .flags = DA850_CLK_ASYNC3,
+};
+
+#define DA8XX_EHRPWM_TBCLKSYNC BIT(12)
+
+static void ehrpwm_tblck_enable(struct clk *clk)
+{
+ u32 val;
+
+ val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
+ val |= DA8XX_EHRPWM_TBCLKSYNC;
+ writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
+}
+
+static void ehrpwm_tblck_disable(struct clk *clk)
+{
+ u32 val;
+
+ val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
+ val &= ~DA8XX_EHRPWM_TBCLKSYNC;
+ writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
+}
+
+static struct clk ehrpwm_tbclk = {
+ .name = "ehrpwm_tbclk",
+ .parent = &ehrpwm_clk,
+ .clk_enable = ehrpwm_tblck_enable,
+ .clk_disable = ehrpwm_tblck_disable,
+};
+
+static struct clk ecap_clk = {
+ .name = "ecap",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_ECAP,
+ .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_sysclk1", &pll0_sysclk1),
+ 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("i2c_davinci.1", NULL, &i2c0_clk),
+ CLK(NULL, "timer0", &timerp64_0_clk),
+ CLK("davinci-wdt", 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("pruss_uio", "pruss", &pruss_clk),
+ CLK("serial8250.0", NULL, &uart0_clk),
+ CLK("serial8250.1", NULL, &uart1_clk),
+ CLK("serial8250.2", NULL, &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_mdio.0", "fck", &emac_clk),
+ CLK("davinci-mcasp.0", NULL, &mcasp_clk),
+ CLK("da8xx_lcdc.0", "fck", &lcdc_clk),
+ CLK("da830-mmc.0", NULL, &mmcsd0_clk),
+ CLK("da830-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("vpif", NULL, &vpif_clk),
+ CLK("ahci_da850", NULL, &sata_clk),
+ CLK("davinci-rproc.0", NULL, &dsp_clk),
+ CLK("ehrpwm", "fck", &ehrpwm_clk),
+ CLK("ehrpwm", "tbclk", &ehrpwm_tbclk),
+ CLK("ecap", "fck", &ecap_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)
+ /* MMC/SD1 function */
+ MUX_CFG(DA850, MMCSD1_DAT_0, 18, 8, 15, 2, false)
+ MUX_CFG(DA850, MMCSD1_DAT_1, 19, 16, 15, 2, false)
+ MUX_CFG(DA850, MMCSD1_DAT_2, 19, 12, 15, 2, false)
+ MUX_CFG(DA850, MMCSD1_DAT_3, 19, 8, 15, 2, false)
+ MUX_CFG(DA850, MMCSD1_CLK, 18, 12, 15, 2, false)
+ MUX_CFG(DA850, MMCSD1_CMD, 18, 16, 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_9, 13, 24, 15, 8, false)
+ MUX_CFG(DA850, GPIO6_10, 13, 20, 15, 8, false)
+ MUX_CFG(DA850, GPIO6_13, 13, 8, 15, 8, false)
+ MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false)
+ /* VPIF Capture */
+ MUX_CFG(DA850, VPIF_DIN0, 15, 4, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN1, 15, 0, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN2, 14, 28, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN3, 14, 24, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN4, 14, 20, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN5, 14, 16, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN6, 14, 12, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN7, 14, 8, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN8, 16, 4, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN9, 16, 0, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN10, 15, 28, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN11, 15, 24, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN12, 15, 20, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN13, 15, 16, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN14, 15, 12, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN15, 15, 8, 15, 1, false)
+ MUX_CFG(DA850, VPIF_CLKIN0, 14, 0, 15, 1, false)
+ MUX_CFG(DA850, VPIF_CLKIN1, 14, 4, 15, 1, false)
+ MUX_CFG(DA850, VPIF_CLKIN2, 19, 8, 15, 1, false)
+ MUX_CFG(DA850, VPIF_CLKIN3, 19, 16, 15, 1, false)
+ /* VPIF Display */
+ MUX_CFG(DA850, VPIF_DOUT0, 17, 4, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT1, 17, 0, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT2, 16, 28, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT3, 16, 24, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT4, 16, 20, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT5, 16, 16, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT6, 16, 12, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT7, 16, 8, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT8, 18, 4, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT9, 18, 0, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT10, 17, 28, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT11, 17, 24, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT12, 17, 20, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT13, 17, 16, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT14, 17, 12, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT15, 17, 8, 15, 1, false)
+ MUX_CFG(DA850, VPIF_CLKO2, 19, 12, 15, 1, false)
+ MUX_CFG(DA850, VPIF_CLKO3, 19, 20, 15, 1, false)
+#endif
+};
+
+const short da850_i2c0_pins[] __initconst = {
+ DA850_I2C0_SDA, DA850_I2C0_SCL,
+ -1
+};
+
+const short da850_i2c1_pins[] __initconst = {
+ DA850_I2C1_SCL, DA850_I2C1_SDA,
+ -1
+};
+
+const short da850_lcdcntl_pins[] __initconst = {
+ 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
+};
+
+const short da850_vpif_capture_pins[] __initdata = {
+ DA850_VPIF_DIN0, DA850_VPIF_DIN1, DA850_VPIF_DIN2, DA850_VPIF_DIN3,
+ DA850_VPIF_DIN4, DA850_VPIF_DIN5, DA850_VPIF_DIN6, DA850_VPIF_DIN7,
+ DA850_VPIF_DIN8, DA850_VPIF_DIN9, DA850_VPIF_DIN10, DA850_VPIF_DIN11,
+ DA850_VPIF_DIN12, DA850_VPIF_DIN13, DA850_VPIF_DIN14, DA850_VPIF_DIN15,
+ DA850_VPIF_CLKIN0, DA850_VPIF_CLKIN1, DA850_VPIF_CLKIN2,
+ DA850_VPIF_CLKIN3,
+ -1
+};
+
+const short da850_vpif_display_pins[] __initdata = {
+ DA850_VPIF_DOUT0, DA850_VPIF_DOUT1, DA850_VPIF_DOUT2, DA850_VPIF_DOUT3,
+ DA850_VPIF_DOUT4, DA850_VPIF_DOUT5, DA850_VPIF_DOUT6, DA850_VPIF_DOUT7,
+ DA850_VPIF_DOUT8, DA850_VPIF_DOUT9, DA850_VPIF_DOUT10,
+ DA850_VPIF_DOUT11, DA850_VPIF_DOUT12, DA850_VPIF_DOUT13,
+ DA850_VPIF_DOUT14, DA850_VPIF_DOUT15, DA850_VPIF_CLKO2,
+ DA850_VPIF_CLKO3,
+ -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
+ },
+};
+
+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) \
+ { \
+ .driver_data = (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),
+ {
+ .driver_data = 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].driver_data;
+
+ 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 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 ret = 0, diff;
+ unsigned int best = (unsigned int) -1;
+ struct cpufreq_frequency_table *table = cpufreq_info.freq_table;
+ struct cpufreq_frequency_table *pos;
+
+ rate /= 1000; /* convert to kHz */
+
+ cpufreq_for_each_entry(pos, table) {
+ diff = pos->frequency - rate;
+ if (diff < 0)
+ diff = -diff;
+
+ if (diff < best) {
+ best = diff;
+ ret = pos->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].driver_data;
+ 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 __init 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;
+}
+
+/* VPIF resource, platform data */
+static u64 da850_vpif_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource da850_vpif_resource[] = {
+ {
+ .start = DA8XX_VPIF_BASE,
+ .end = DA8XX_VPIF_BASE + 0xfff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device da850_vpif_dev = {
+ .name = "vpif",
+ .id = -1,
+ .dev = {
+ .dma_mask = &da850_vpif_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = da850_vpif_resource,
+ .num_resources = ARRAY_SIZE(da850_vpif_resource),
+};
+
+static struct resource da850_vpif_display_resource[] = {
+ {
+ .start = IRQ_DA850_VPIFINT,
+ .end = IRQ_DA850_VPIFINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da850_vpif_display_dev = {
+ .name = "vpif_display",
+ .id = -1,
+ .dev = {
+ .dma_mask = &da850_vpif_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = da850_vpif_display_resource,
+ .num_resources = ARRAY_SIZE(da850_vpif_display_resource),
+};
+
+static struct resource da850_vpif_capture_resource[] = {
+ {
+ .start = IRQ_DA850_VPIFINT,
+ .end = IRQ_DA850_VPIFINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DA850_VPIFINT,
+ .end = IRQ_DA850_VPIFINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da850_vpif_capture_dev = {
+ .name = "vpif_capture",
+ .id = -1,
+ .dev = {
+ .dma_mask = &da850_vpif_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = da850_vpif_capture_resource,
+ .num_resources = ARRAY_SIZE(da850_vpif_capture_resource),
+};
+
+int __init da850_register_vpif(void)
+{
+ return platform_device_register(&da850_vpif_dev);
+}
+
+int __init da850_register_vpif_display(struct vpif_display_config
+ *display_config)
+{
+ da850_vpif_display_dev.dev.platform_data = display_config;
+ return platform_device_register(&da850_vpif_display_dev);
+}
+
+int __init da850_register_vpif_capture(struct vpif_capture_config
+ *capture_config)
+{
+ da850_vpif_capture_dev.dev.platform_data = capture_config;
+ return platform_device_register(&da850_vpif_capture_dev);
+}
+
+static struct davinci_gpio_platform_data da850_gpio_platform_data = {
+ .ngpio = 144,
+};
+
+int __init da850_register_gpio(void)
+{
+ return da8xx_register_gpio(&da850_gpio_platform_data);
+}
+
+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,
+ .emac_pdata = &da8xx_emac_pdata,
+ .sram_dma = DA8XX_SHARED_RAM_BASE,
+ .sram_len = SZ_128K,
+};
+
+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/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
new file mode 100644
index 000000000..438f68547
--- /dev/null
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Modified from mach-omap/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/io.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/irqdomain.h>
+
+#include <asm/mach/arch.h>
+
+#include <mach/common.h>
+#include <mach/cp_intc.h>
+#include <mach/da8xx.h>
+
+#define DA8XX_NUM_UARTS 3
+
+static const struct of_device_id da8xx_irq_match[] __initconst = {
+ { .compatible = "ti,cp-intc", .data = cp_intc_of_init, },
+ { }
+};
+
+static void __init da8xx_init_irq(void)
+{
+ of_irq_init(da8xx_irq_match);
+}
+
+static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("ti,davinci-i2c", 0x01c22000, "i2c_davinci.1", NULL),
+ OF_DEV_AUXDATA("ti,davinci-wdt", 0x01c21000, "davinci-wdt", NULL),
+ OF_DEV_AUXDATA("ti,da830-mmc", 0x01c40000, "da830-mmc.0", NULL),
+ OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f00000, "ehrpwm", NULL),
+ OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f02000, "ehrpwm", NULL),
+ OF_DEV_AUXDATA("ti,da850-ecap", 0x01f06000, "ecap", NULL),
+ OF_DEV_AUXDATA("ti,da850-ecap", 0x01f07000, "ecap", NULL),
+ OF_DEV_AUXDATA("ti,da850-ecap", 0x01f08000, "ecap", NULL),
+ OF_DEV_AUXDATA("ti,da830-spi", 0x01f0e000, "spi_davinci.1", NULL),
+ OF_DEV_AUXDATA("ns16550a", 0x01c42000, "serial8250.0", NULL),
+ OF_DEV_AUXDATA("ns16550a", 0x01d0c000, "serial8250.1", NULL),
+ OF_DEV_AUXDATA("ns16550a", 0x01d0d000, "serial8250.2", NULL),
+ OF_DEV_AUXDATA("ti,davinci_mdio", 0x01e24000, "davinci_mdio.0", NULL),
+ OF_DEV_AUXDATA("ti,davinci-dm6467-emac", 0x01e20000, "davinci_emac.1",
+ NULL),
+ OF_DEV_AUXDATA("ti,da830-mcasp-audio", 0x01d00000, "davinci-mcasp.0", NULL),
+ {}
+};
+
+#ifdef CONFIG_ARCH_DAVINCI_DA850
+
+static void __init da850_init_machine(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table,
+ da850_auxdata_lookup, NULL);
+
+}
+
+static const char *da850_boards_compat[] __initdata = {
+ "enbw,cmc",
+ "ti,da850-evm",
+ "ti,da850",
+ NULL,
+};
+
+DT_MACHINE_START(DA850_DT, "Generic DA850/OMAP-L138/AM18x")
+ .map_io = da850_init,
+ .init_irq = da8xx_init_irq,
+ .init_time = davinci_timer_init,
+ .init_machine = da850_init_machine,
+ .dt_compat = da850_boards_compat,
+ .init_late = davinci_init_late,
+ .restart = da8xx_restart,
+MACHINE_END
+
+#endif
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
new file mode 100644
index 000000000..4ffc37acc
--- /dev/null
+++ b/arch/arm/mach-davinci/davinci.h
@@ -0,0 +1,123 @@
+/*
+ * This file contains the processor specific definitions
+ * of the TI DM644x, DM355, DM365, and DM646x.
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated
+ * Copyright (c) 2007 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 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 __DAVINCI_H
+#define __DAVINCI_H
+
+#include <linux/clk.h>
+#include <linux/videodev2.h>
+#include <linux/davinci_emac.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/platform_data/davinci_asp.h>
+#include <linux/platform_data/edma.h>
+#include <linux/platform_data/keyscan-davinci.h>
+#include <mach/hardware.h>
+
+#include <media/davinci/vpfe_capture.h>
+#include <media/davinci/vpif_types.h>
+#include <media/davinci/vpss.h>
+#include <media/davinci/vpbe_types.h>
+#include <media/davinci/vpbe_venc.h>
+#include <media/davinci/vpbe.h>
+#include <media/davinci/vpbe_osd.h>
+
+#define DAVINCI_SYSTEM_MODULE_BASE 0x01c40000
+#define SYSMOD_VDAC_CONFIG 0x2c
+#define SYSMOD_VIDCLKCTL 0x38
+#define SYSMOD_VPSS_CLKCTL 0x44
+#define SYSMOD_VDD3P3VPWDN 0x48
+#define SYSMOD_VSCLKDIS 0x6c
+#define SYSMOD_PUPDCTL1 0x7c
+
+/* VPSS CLKCTL bit definitions */
+#define VPSS_MUXSEL_EXTCLK_ENABLE BIT(1)
+#define VPSS_VENCCLKEN_ENABLE BIT(3)
+#define VPSS_DACCLKEN_ENABLE BIT(4)
+#define VPSS_PLLC2SYSCLK5_ENABLE BIT(5)
+
+extern void __iomem *davinci_sysmod_base;
+#define DAVINCI_SYSMOD_VIRT(x) (davinci_sysmod_base + (x))
+void davinci_map_sysmod(void);
+
+#define DAVINCI_GPIO_BASE 0x01C67000
+int davinci_gpio_register(struct resource *res, int size, void *pdata);
+
+/* DM355 base addresses */
+#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
+
+/* DM365 base addresses */
+#define DM365_ASYNC_EMIF_CONTROL_BASE 0x01d10000
+#define DM365_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+#define DM365_ASYNC_EMIF_DATA_CE1_BASE 0x04000000
+
+/* DM644x base addresses */
+#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
+
+/* DM646x base addresses */
+#define DM646X_ASYNC_EMIF_CONTROL_BASE 0x20008000
+#define DM646X_ASYNC_EMIF_CS2_SPACE_BASE 0x42000000
+
+int davinci_init_wdt(void);
+
+/* DM355 function declarations */
+void dm355_init(void);
+void dm355_init_spi0(unsigned chipselect_mask,
+ const struct spi_board_info *info, unsigned len);
+void dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata);
+int dm355_init_video(struct vpfe_config *, struct vpbe_config *);
+int dm355_gpio_register(void);
+
+/* DM365 function declarations */
+void dm365_init(void);
+void dm365_init_asp(struct snd_platform_data *pdata);
+void dm365_init_vc(struct snd_platform_data *pdata);
+void dm365_init_ks(struct davinci_ks_platform_data *pdata);
+void dm365_init_rtc(void);
+void dm365_init_spi0(unsigned chipselect_mask,
+ const struct spi_board_info *info, unsigned len);
+int dm365_init_video(struct vpfe_config *, struct vpbe_config *);
+int dm365_gpio_register(void);
+
+/* DM644x function declarations */
+void dm644x_init(void);
+void dm644x_init_asp(struct snd_platform_data *pdata);
+int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
+int dm644x_gpio_register(void);
+
+/* DM646x function declarations */
+void dm646x_init(void);
+void dm646x_init_mcasp0(struct snd_platform_data *pdata);
+void dm646x_init_mcasp1(struct snd_platform_data *pdata);
+int dm646x_init_edma(struct edma_rsv_info *rsv);
+void dm646x_video_init(void);
+void dm646x_setup_vpif(struct vpif_display_config *,
+ struct vpif_capture_config *);
+int dm646x_gpio_register(void);
+
+extern struct platform_device dm365_serial_device[];
+extern struct platform_device dm355_serial_device[];
+extern struct platform_device dm644x_serial_device[];
+extern struct platform_device dm646x_serial_device[];
+#endif /*__DAVINCI_H */
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
new file mode 100644
index 000000000..ddfdd820e
--- /dev/null
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -0,0 +1,1095 @@
+/*
+ * 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-contiguous.h>
+#include <linux/serial_8250.h>
+#include <linux/ahci_platform.h>
+#include <linux/clk.h>
+#include <linux/reboot.h>
+
+#include <mach/cputype.h>
+#include <mach/common.h>
+#include <mach/time.h>
+#include <mach/da8xx.h>
+#include <mach/cpuidle.h>
+#include <mach/sram.h>
+
+#include "clock.h"
+#include "asp.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_PRUSS_MEM_BASE 0x01c30000
+#define DA8XX_MMCSD0_BASE 0x01c40000
+#define DA8XX_SPI0_BASE 0x01c41000
+#define DA830_SPI1_BASE 0x01e12000
+#define DA8XX_LCD_CNTRL_BASE 0x01e13000
+#define DA850_SATA_BASE 0x01e18000
+#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_serial0_pdata[] = {
+ {
+ .mapbase = DA8XX_UART0_BASE,
+ .irq = IRQ_DA8XX_UARTINT0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ }
+};
+static struct plat_serial8250_port da8xx_serial1_pdata[] = {
+ {
+ .mapbase = DA8XX_UART1_BASE,
+ .irq = IRQ_DA8XX_UARTINT1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ }
+};
+static struct plat_serial8250_port da8xx_serial2_pdata[] = {
+ {
+ .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_serial0_pdata,
+ }
+ },
+ {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM1,
+ .dev = {
+ .platform_data = da8xx_serial1_pdata,
+ }
+ },
+ {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM2,
+ .dev = {
+ .platform_data = da8xx_serial2_pdata,
+ }
+ },
+ {
+ }
+};
+
+static s8 da8xx_queue_priority_mapping[][2] = {
+ /* {event queue no, Priority} */
+ {0, 3},
+ {1, 7},
+ {-1, -1}
+};
+
+static s8 da850_queue_priority_mapping[][2] = {
+ /* {event queue no, Priority} */
+ {0, 3},
+ {-1, -1}
+};
+
+static struct edma_soc_info da830_edma_cc0_info = {
+ .queue_priority_mapping = da8xx_queue_priority_mapping,
+ .default_queue = EVENTQ_1,
+};
+
+static struct edma_soc_info *da830_edma_info[EDMA_MAX_CC] = {
+ &da830_edma_cc0_info,
+};
+
+static struct edma_soc_info da850_edma_cc_info[] = {
+ {
+ .queue_priority_mapping = da8xx_queue_priority_mapping,
+ .default_queue = EVENTQ_1,
+ },
+ {
+ .queue_priority_mapping = da850_queue_priority_mapping,
+ .default_queue = EVENTQ_0,
+ },
+};
+
+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,
+ },
+};
+
+static struct platform_device da8xx_wdt_device = {
+ .name = "davinci-wdt",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(da8xx_watchdog_resources),
+ .resource = da8xx_watchdog_resources,
+};
+
+void da8xx_restart(enum reboot_mode mode, const char *cmd)
+{
+ struct device *dev;
+
+ dev = bus_find_device_by_name(&platform_bus_type, NULL, "davinci-wdt");
+ if (!dev) {
+ pr_err("%s: failed to find watchdog device\n", __func__);
+ return;
+ }
+
+ davinci_watchdog_reset(to_platform_device(dev));
+}
+
+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;
+
+ return platform_device_register(&da8xx_emac_device);
+}
+
+static struct resource da830_mcasp1_resources[] = {
+ {
+ .name = "mpu",
+ .start = DAVINCI_DA830_MCASP1_REG_BASE,
+ .end = DAVINCI_DA830_MCASP1_REG_BASE + (SZ_1K * 12) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /* TX event */
+ {
+ .name = "tx",
+ .start = DAVINCI_DA830_DMA_MCASP1_AXEVT,
+ .end = DAVINCI_DA830_DMA_MCASP1_AXEVT,
+ .flags = IORESOURCE_DMA,
+ },
+ /* RX event */
+ {
+ .name = "rx",
+ .start = DAVINCI_DA830_DMA_MCASP1_AREVT,
+ .end = DAVINCI_DA830_DMA_MCASP1_AREVT,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "common",
+ .start = IRQ_DA8XX_MCASPINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+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 da830_mcasp2_resources[] = {
+ {
+ .name = "mpu",
+ .start = DAVINCI_DA830_MCASP2_REG_BASE,
+ .end = DAVINCI_DA830_MCASP2_REG_BASE + (SZ_1K * 12) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /* TX event */
+ {
+ .name = "tx",
+ .start = DAVINCI_DA830_DMA_MCASP2_AXEVT,
+ .end = DAVINCI_DA830_DMA_MCASP2_AXEVT,
+ .flags = IORESOURCE_DMA,
+ },
+ /* RX event */
+ {
+ .name = "rx",
+ .start = DAVINCI_DA830_DMA_MCASP2_AREVT,
+ .end = DAVINCI_DA830_DMA_MCASP2_AREVT,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "common",
+ .start = IRQ_DA8XX_MCASPINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da830_mcasp2_device = {
+ .name = "davinci-mcasp",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(da830_mcasp2_resources),
+ .resource = da830_mcasp2_resources,
+};
+
+static struct resource da850_mcasp_resources[] = {
+ {
+ .name = "mpu",
+ .start = DAVINCI_DA8XX_MCASP0_REG_BASE,
+ .end = DAVINCI_DA8XX_MCASP0_REG_BASE + (SZ_1K * 12) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /* TX event */
+ {
+ .name = "tx",
+ .start = DAVINCI_DA8XX_DMA_MCASP0_AXEVT,
+ .end = DAVINCI_DA8XX_DMA_MCASP0_AXEVT,
+ .flags = IORESOURCE_DMA,
+ },
+ /* RX event */
+ {
+ .name = "rx",
+ .start = DAVINCI_DA8XX_DMA_MCASP0_AREVT,
+ .end = DAVINCI_DA8XX_DMA_MCASP0_AREVT,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "common",
+ .start = IRQ_DA8XX_MCASPINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da850_mcasp_device = {
+ .name = "davinci-mcasp",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(da850_mcasp_resources),
+ .resource = da850_mcasp_resources,
+};
+
+void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata)
+{
+ struct platform_device *pdev;
+
+ switch (id) {
+ case 0:
+ /* Valid for DA830/OMAP-L137 or DA850/OMAP-L138 */
+ pdev = &da850_mcasp_device;
+ break;
+ case 1:
+ /* Valid for DA830/OMAP-L137 only */
+ if (!cpu_is_davinci_da830())
+ return;
+ pdev = &da830_mcasp1_device;
+ break;
+ case 2:
+ /* Valid for DA830/OMAP-L137 only */
+ if (!cpu_is_davinci_da830())
+ return;
+ pdev = &da830_mcasp2_device;
+ break;
+ default:
+ return;
+ }
+
+ pdev->dev.platform_data = pdata;
+ platform_device_register(pdev);
+}
+
+static struct resource da8xx_pruss_resources[] = {
+ {
+ .start = DA8XX_PRUSS_MEM_BASE,
+ .end = DA8XX_PRUSS_MEM_BASE + 0xFFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DA8XX_EVTOUT0,
+ .end = IRQ_DA8XX_EVTOUT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DA8XX_EVTOUT1,
+ .end = IRQ_DA8XX_EVTOUT1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DA8XX_EVTOUT2,
+ .end = IRQ_DA8XX_EVTOUT2,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DA8XX_EVTOUT3,
+ .end = IRQ_DA8XX_EVTOUT3,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DA8XX_EVTOUT4,
+ .end = IRQ_DA8XX_EVTOUT4,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DA8XX_EVTOUT5,
+ .end = IRQ_DA8XX_EVTOUT5,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DA8XX_EVTOUT6,
+ .end = IRQ_DA8XX_EVTOUT6,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DA8XX_EVTOUT7,
+ .end = IRQ_DA8XX_EVTOUT7,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct uio_pruss_pdata da8xx_uio_pruss_pdata = {
+ .pintc_base = 0x4000,
+};
+
+static struct platform_device da8xx_uio_pruss_dev = {
+ .name = "pruss_uio",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(da8xx_pruss_resources),
+ .resource = da8xx_pruss_resources,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &da8xx_uio_pruss_pdata,
+ }
+};
+
+int __init da8xx_register_uio_pruss(void)
+{
+ da8xx_uio_pruss_pdata.sram_pool = sram_get_gen_pool();
+ return platform_device_register(&da8xx_uio_pruss_dev);
+}
+
+static struct lcd_ctrl_config lcd_cfg = {
+ .panel_shade = COLOR_ACTIVE,
+ .bpp = 16,
+};
+
+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_gpio_resources[] = {
+ { /* registers */
+ .start = DA8XX_GPIO_BASE,
+ .end = DA8XX_GPIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ { /* interrupt */
+ .start = IRQ_DA8XX_GPIO0,
+ .end = IRQ_DA8XX_GPIO8,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da8xx_gpio_device = {
+ .name = "davinci_gpio",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(da8xx_gpio_resources),
+ .resource = da8xx_gpio_resources,
+};
+
+int __init da8xx_register_gpio(void *pdata)
+{
+ da8xx_gpio_device.dev.platform_data = pdata;
+ return platform_device_register(&da8xx_gpio_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 = "da830-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 = "da830-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_rproc_resources[] = {
+ { /* DSP boot address */
+ .start = DA8XX_SYSCFG0_BASE + DA8XX_HOST1CFG_REG,
+ .end = DA8XX_SYSCFG0_BASE + DA8XX_HOST1CFG_REG + 3,
+ .flags = IORESOURCE_MEM,
+ },
+ { /* DSP interrupt registers */
+ .start = DA8XX_SYSCFG0_BASE + DA8XX_CHIPSIG_REG,
+ .end = DA8XX_SYSCFG0_BASE + DA8XX_CHIPSIG_REG + 7,
+ .flags = IORESOURCE_MEM,
+ },
+ { /* dsp irq */
+ .start = IRQ_DA8XX_CHIPINT0,
+ .end = IRQ_DA8XX_CHIPINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da8xx_dsp = {
+ .name = "davinci-rproc",
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(da8xx_rproc_resources),
+ .resource = da8xx_rproc_resources,
+};
+
+#if IS_ENABLED(CONFIG_DA8XX_REMOTEPROC)
+
+static phys_addr_t rproc_base __initdata;
+static unsigned long rproc_size __initdata;
+
+static int __init early_rproc_mem(char *p)
+{
+ char *endp;
+
+ if (p == NULL)
+ return 0;
+
+ rproc_size = memparse(p, &endp);
+ if (*endp == '@')
+ rproc_base = memparse(endp + 1, NULL);
+
+ return 0;
+}
+early_param("rproc_mem", early_rproc_mem);
+
+void __init da8xx_rproc_reserve_cma(void)
+{
+ int ret;
+
+ if (!rproc_base || !rproc_size) {
+ pr_err("%s: 'rproc_mem=nn@address' badly specified\n"
+ " 'nn' and 'address' must both be non-zero\n",
+ __func__);
+
+ return;
+ }
+
+ pr_info("%s: reserving 0x%lx @ 0x%lx...\n",
+ __func__, rproc_size, (unsigned long)rproc_base);
+
+ ret = dma_declare_contiguous(&da8xx_dsp.dev, rproc_size, rproc_base, 0);
+ if (ret)
+ pr_err("%s: dma_declare_contiguous failed %d\n", __func__, ret);
+}
+
+#else
+
+void __init da8xx_rproc_reserve_cma(void)
+{
+}
+
+#endif
+
+int __init da8xx_register_rproc(void)
+{
+ int ret;
+
+ ret = platform_device_register(&da8xx_dsp);
+ if (ret)
+ pr_err("%s: can't register DSP device: %d\n", __func__, ret);
+
+ return ret;
+};
+
+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 = "da830-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(da8xx_rtc_resources),
+ .resource = da8xx_rtc_resources,
+};
+
+int da8xx_register_rtc(void)
+{
+ return platform_device_register(&da8xx_rtc_device);
+}
+
+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_warn("%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,
+ },
+};
+
+static 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_bus(int instance, unsigned num_chipselect)
+{
+ if (instance < 0 || instance > 1)
+ return -EINVAL;
+
+ da8xx_spi_pdata[instance].num_chipselect = num_chipselect;
+
+ 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]);
+}
+
+#ifdef CONFIG_ARCH_DAVINCI_DA850
+static struct resource da850_sata_resources[] = {
+ {
+ .start = DA850_SATA_BASE,
+ .end = DA850_SATA_BASE + 0x1fff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = DA8XX_SYSCFG1_BASE + DA8XX_PWRDN_REG,
+ .end = DA8XX_SYSCFG1_BASE + DA8XX_PWRDN_REG + 0x3,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DA850_SATAINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 da850_sata_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device da850_sata_device = {
+ .name = "ahci_da850",
+ .id = -1,
+ .dev = {
+ .dma_mask = &da850_sata_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(da850_sata_resources),
+ .resource = da850_sata_resources,
+};
+
+int __init da850_register_sata(unsigned long refclkpn)
+{
+ /* please see comment in drivers/ata/ahci_da850.c */
+ BUG_ON(refclkpn != 100 * 1000 * 1000);
+
+ return platform_device_register(&da850_sata_device);
+}
+#endif
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
new file mode 100644
index 000000000..6257aa452
--- /dev/null
+++ b/arch/arm/mach-davinci/devices.c
@@ -0,0 +1,350 @@
+/*
+ * 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 <linux/reboot.h>
+
+#include <mach/hardware.h>
+#include <linux/platform_data/i2c-davinci.h>
+#include <mach/irqs.h>
+#include <mach/cputype.h>
+#include <mach/mux.h>
+#include <linux/platform_data/mmc-davinci.h>
+#include <mach/time.h>
+#include <linux/platform_data/edma.h>
+
+
+#include "davinci.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
+
+#define DAVINCI_DMA_MMCRXEVT 26
+#define DAVINCI_DMA_MMCTXEVT 27
+
+void __iomem *davinci_sysmod_base;
+
+void davinci_map_sysmod(void)
+{
+ davinci_sysmod_base = ioremap_nocache(DAVINCI_SYSTEM_MODULE_BASE,
+ 0x800);
+ /*
+ * Throw a bug since a lot of board initialization code depends
+ * on system module availability. ioremap() failing this early
+ * need careful looking into anyway.
+ */
+ BUG_ON(!davinci_sysmod_base);
+}
+
+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 IS_ENABLED(CONFIG_MMC_DAVINCI)
+
+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 = "dm6441-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 = "dm6441-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()) {
+ /* Configure pull down control */
+ unsigned v;
+
+ v = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_PUPDCTL1));
+ __raw_writel(v & ~0xfc0,
+ DAVINCI_SYSMOD_VIRT(SYSMOD_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;
+ davinci_mmcsd1_device.name = "da830-mmc";
+ } 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;
+ davinci_mmcsd0_device.name = "da830-mmc";
+ } else if (cpu_is_davinci_dm644x()) {
+ /* REVISIT: should this be in board-init code? */
+ /* Power-on 3.3V IO cells */
+ __raw_writel(0,
+ DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN));
+ /*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 = "davinci-wdt",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+void davinci_restart(enum reboot_mode mode, const char *cmd)
+{
+ davinci_watchdog_reset(&davinci_wdt_device);
+}
+
+int davinci_init_wdt(void)
+{
+ return platform_device_register(&davinci_wdt_device);
+}
+
+static struct platform_device davinci_gpio_device = {
+ .name = "davinci_gpio",
+ .id = -1,
+};
+
+int davinci_gpio_register(struct resource *res, int size, void *pdata)
+{
+ davinci_gpio_device.resource = res;
+ davinci_gpio_device.num_resources = size;
+ davinci_gpio_device.dev.platform_data = pdata;
+ return platform_device_register(&davinci_gpio_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,
+ },
+};
+
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
new file mode 100644
index 000000000..9cbeda798
--- /dev/null
+++ b/arch/arm/mach-davinci/dm355.c
@@ -0,0 +1,1078 @@
+/*
+ * 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/spi/spi.h>
+#include <linux/platform_data/edma.h>
+#include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_data/spi-davinci.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/cputype.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 "davinci.h"
+#include "clock.h"
+#include "mux.h"
+#include "asp.h"
+
+#define DM355_UART2_BASE (IO_PHYS + 0x206000)
+#define DM355_OSD_BASE (IO_PHYS + 0x70200)
+#define DM355_VENC_BASE (IO_PHYS + 0x70400)
+
+/*
+ * 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("vpss", "master", &vpss_master_clk),
+ CLK("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("serial8250.0", NULL, &uart0_clk),
+ CLK("serial8250.1", NULL, &uart1_clk),
+ CLK("serial8250.2", NULL, &uart2_clk),
+ CLK("i2c_davinci.1", NULL, &i2c_clk),
+ CLK("davinci-mcbsp.0", NULL, &asp0_clk),
+ CLK("davinci-mcbsp.1", NULL, &asp1_clk),
+ CLK("dm6441-mmc.0", NULL, &mmcsd0_clk),
+ CLK("dm6441-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("davinci-wdt", 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,
+ const 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 s8
+queue_priority_mapping[][2] = {
+ /* {event queue no, Priority} */
+ {0, 3},
+ {1, 7},
+ {-1, -1},
+};
+
+static struct edma_soc_info edma_cc0_info = {
+ .queue_priority_mapping = queue_priority_mapping,
+ .default_queue = EVENTQ_1,
+};
+
+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[] = {
+ {
+ .name = "mpu",
+ .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),
+ },
+};
+
+static struct resource dm355_osd_resources[] = {
+ {
+ .start = DM355_OSD_BASE,
+ .end = DM355_OSD_BASE + 0x17f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm355_osd_dev = {
+ .name = DM355_VPBE_OSD_SUBDEV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm355_osd_resources),
+ .resource = dm355_osd_resources,
+ .dev = {
+ .dma_mask = &vpfe_capture_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource dm355_venc_resources[] = {
+ {
+ .start = IRQ_VENCINT,
+ .end = IRQ_VENCINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* venc registers io space */
+ {
+ .start = DM355_VENC_BASE,
+ .end = DM355_VENC_BASE + 0x17f,
+ .flags = IORESOURCE_MEM,
+ },
+ /* VDAC config register io space */
+ {
+ .start = DAVINCI_SYSTEM_MODULE_BASE + SYSMOD_VDAC_CONFIG,
+ .end = DAVINCI_SYSTEM_MODULE_BASE + SYSMOD_VDAC_CONFIG + 3,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource dm355_v4l2_disp_resources[] = {
+ {
+ .start = IRQ_VENCINT,
+ .end = IRQ_VENCINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* venc registers io space */
+ {
+ .start = DM355_VENC_BASE,
+ .end = DM355_VENC_BASE + 0x17f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static int dm355_vpbe_setup_pinmux(u32 if_type, int field)
+{
+ switch (if_type) {
+ case MEDIA_BUS_FMT_SGRBG8_1X8:
+ davinci_cfg_reg(DM355_VOUT_FIELD_G70);
+ break;
+ case MEDIA_BUS_FMT_YUYV10_1X20:
+ if (field)
+ davinci_cfg_reg(DM355_VOUT_FIELD);
+ else
+ davinci_cfg_reg(DM355_VOUT_FIELD_G70);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ davinci_cfg_reg(DM355_VOUT_COUTL_EN);
+ davinci_cfg_reg(DM355_VOUT_COUTH_EN);
+
+ return 0;
+}
+
+static int dm355_venc_setup_clock(enum vpbe_enc_timings_type type,
+ unsigned int pclock)
+{
+ void __iomem *vpss_clk_ctrl_reg;
+
+ vpss_clk_ctrl_reg = DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL);
+
+ switch (type) {
+ case VPBE_ENC_STD:
+ writel(VPSS_DACCLKEN_ENABLE | VPSS_VENCCLKEN_ENABLE,
+ vpss_clk_ctrl_reg);
+ break;
+ case VPBE_ENC_DV_TIMINGS:
+ if (pclock > 27000000)
+ /*
+ * For HD, use external clock source since we cannot
+ * support HD mode with internal clocks.
+ */
+ writel(VPSS_MUXSEL_EXTCLK_ENABLE, vpss_clk_ctrl_reg);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct platform_device dm355_vpbe_display = {
+ .name = "vpbe-v4l2",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm355_v4l2_disp_resources),
+ .resource = dm355_v4l2_disp_resources,
+ .dev = {
+ .dma_mask = &vpfe_capture_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct venc_platform_data dm355_venc_pdata = {
+ .setup_pinmux = dm355_vpbe_setup_pinmux,
+ .setup_clock = dm355_venc_setup_clock,
+};
+
+static struct platform_device dm355_venc_dev = {
+ .name = DM355_VPBE_VENC_SUBDEV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm355_venc_resources),
+ .resource = dm355_venc_resources,
+ .dev = {
+ .dma_mask = &vpfe_capture_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = (void *)&dm355_venc_pdata,
+ },
+};
+
+static struct platform_device dm355_vpbe_dev = {
+ .name = "vpbe_controller",
+ .id = -1,
+ .dev = {
+ .dma_mask = &vpfe_capture_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource dm355_gpio_resources[] = {
+ { /* registers */
+ .start = DAVINCI_GPIO_BASE,
+ .end = DAVINCI_GPIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ { /* interrupt */
+ .start = IRQ_DM355_GPIOBNK0,
+ .end = IRQ_DM355_GPIOBNK6,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct davinci_gpio_platform_data dm355_gpio_platform_data = {
+ .ngpio = 104,
+};
+
+int __init dm355_gpio_register(void)
+{
+ return davinci_gpio_register(dm355_gpio_resources,
+ ARRAY_SIZE(dm355_gpio_resources),
+ &dm355_gpio_platform_data);
+}
+/*----------------------------------------------------------------------*/
+
+static struct map_desc dm355_io_desc[] = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+};
+
+/* 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_serial0_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART0_BASE,
+ .irq = IRQ_UARTINT0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ }
+};
+static struct plat_serial8250_port dm355_serial1_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART1_BASE,
+ .irq = IRQ_UARTINT1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ }
+};
+static struct plat_serial8250_port dm355_serial2_platform_data[] = {
+ {
+ .mapbase = DM355_UART2_BASE,
+ .irq = IRQ_DM355_UARTINT2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ }
+};
+
+struct platform_device dm355_serial_device[] = {
+ {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = dm355_serial0_platform_data,
+ }
+ },
+ {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM1,
+ .dev = {
+ .platform_data = dm355_serial1_platform_data,
+ }
+ },
+ {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM2,
+ .dev = {
+ .platform_data = dm355_serial2_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,
+ .sram_dma = 0x00010000,
+ .sram_len = SZ_32K,
+};
+
+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);
+ davinci_map_sysmod();
+}
+
+int __init dm355_init_video(struct vpfe_config *vpfe_cfg,
+ struct vpbe_config *vpbe_cfg)
+{
+ if (vpfe_cfg || vpbe_cfg)
+ platform_device_register(&dm355_vpss_device);
+
+ if (vpfe_cfg) {
+ vpfe_capture_dev.dev.platform_data = vpfe_cfg;
+ platform_device_register(&dm355_ccdc_dev);
+ platform_device_register(&vpfe_capture_dev);
+ }
+
+ if (vpbe_cfg) {
+ dm355_vpbe_dev.dev.platform_data = vpbe_cfg;
+ platform_device_register(&dm355_osd_dev);
+ platform_device_register(&dm355_venc_dev);
+ platform_device_register(&dm355_vpbe_dev);
+ platform_device_register(&dm355_vpbe_display);
+ }
+
+ return 0;
+}
+
+static int __init dm355_init_devices(void)
+{
+ int ret = 0;
+
+ if (!cpu_is_davinci_dm355())
+ return 0;
+
+ davinci_cfg_reg(DM355_INT_EDMA_CC);
+ platform_device_register(&dm355_edma_device);
+
+ ret = davinci_init_wdt();
+ if (ret)
+ pr_warn("%s: watchdog init failed: %d\n", __func__, ret);
+
+ return ret;
+}
+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 000000000..e3a3c54b6
--- /dev/null
+++ b/arch/arm/mach-davinci/dm365.c
@@ -0,0 +1,1439 @@
+/*
+ * 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/spi/spi.h>
+#include <linux/platform_data/edma.h>
+#include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_data/keyscan-davinci.h>
+#include <linux/platform_data/spi-davinci.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/cputype.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 "davinci.h"
+#include "clock.h"
+#include "mux.h"
+#include "asp.h"
+
+#define DM365_REF_FREQ 24000000 /* 24 MHz on the DM365 EVM */
+#define DM365_RTC_BASE 0x01c69000
+#define DM365_KEYSCAN_BASE 0x01c69400
+#define DM365_OSD_BASE 0x01c71c00
+#define DM365_VENC_BASE 0x01c71e00
+#define DAVINCI_DM365_VC_BASE 0x01d0c000
+#define DAVINCI_DMA_VC_TX 2
+#define DAVINCI_DMA_VC_RX 3
+#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
+
+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 vpss_slave_clk = {
+ .name = "vpss_slave",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_VPSSSLV,
+};
+
+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("vpss", "master", &vpss_master_clk),
+ CLK("vpss", "slave", &vpss_slave_clk),
+ CLK(NULL, "arm", &arm_clk),
+ CLK("serial8250.0", NULL, &uart0_clk),
+ CLK("serial8250.1", NULL, &uart1_clk),
+ CLK("i2c_davinci.1", NULL, &i2c_clk),
+ CLK("da830-mmc.0", NULL, &mmcsd0_clk),
+ CLK("da830-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("davinci-wdt", NULL, &timer2_clk),
+ CLK(NULL, "timer3", &timer3_clk),
+ CLK(NULL, "usb", &usb_clk),
+ CLK("davinci_emac.1", NULL, &emac_clk),
+ CLK("davinci_mdio.0", "fck", &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,
+ const 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 resource dm365_gpio_resources[] = {
+ { /* registers */
+ .start = DAVINCI_GPIO_BASE,
+ .end = DAVINCI_GPIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ { /* interrupt */
+ .start = IRQ_DM365_GPIO0,
+ .end = IRQ_DM365_GPIO7,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct davinci_gpio_platform_data dm365_gpio_platform_data = {
+ .ngpio = 104,
+ .gpio_unbanked = 8,
+};
+
+int __init dm365_gpio_register(void)
+{
+ return davinci_gpio_register(dm365_gpio_resources,
+ ARRAY_SIZE(dm365_gpio_resources),
+ &dm365_gpio_platform_data);
+}
+
+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 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 = {
+ .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[] = {
+ {
+ .name = "mpu",
+ .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
+ },
+};
+
+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_serial0_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART0_BASE,
+ .irq = IRQ_UARTINT0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ }
+};
+static struct plat_serial8250_port dm365_serial1_platform_data[] = {
+ {
+ .mapbase = DM365_UART1_BASE,
+ .irq = IRQ_UARTINT1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ }
+};
+
+struct platform_device dm365_serial_device[] = {
+ {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = dm365_serial0_platform_data,
+ }
+ },
+ {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM1,
+ .dev = {
+ .platform_data = dm365_serial1_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,
+ .emac_pdata = &dm365_emac_pdata,
+ .sram_dma = 0x00010000,
+ .sram_len = SZ_32K,
+};
+
+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);
+ davinci_map_sysmod();
+}
+
+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 struct resource dm365_osd_resources[] = {
+ {
+ .start = DM365_OSD_BASE,
+ .end = DM365_OSD_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static u64 dm365_video_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device dm365_osd_dev = {
+ .name = DM365_VPBE_OSD_SUBDEV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm365_osd_resources),
+ .resource = dm365_osd_resources,
+ .dev = {
+ .dma_mask = &dm365_video_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource dm365_venc_resources[] = {
+ {
+ .start = IRQ_VENCINT,
+ .end = IRQ_VENCINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* venc registers io space */
+ {
+ .start = DM365_VENC_BASE,
+ .end = DM365_VENC_BASE + 0x177,
+ .flags = IORESOURCE_MEM,
+ },
+ /* vdaccfg registers io space */
+ {
+ .start = DAVINCI_SYSTEM_MODULE_BASE + SYSMOD_VDAC_CONFIG,
+ .end = DAVINCI_SYSTEM_MODULE_BASE + SYSMOD_VDAC_CONFIG + 3,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource dm365_v4l2_disp_resources[] = {
+ {
+ .start = IRQ_VENCINT,
+ .end = IRQ_VENCINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* venc registers io space */
+ {
+ .start = DM365_VENC_BASE,
+ .end = DM365_VENC_BASE + 0x177,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static int dm365_vpbe_setup_pinmux(u32 if_type, int field)
+{
+ switch (if_type) {
+ case MEDIA_BUS_FMT_SGRBG8_1X8:
+ davinci_cfg_reg(DM365_VOUT_FIELD_G81);
+ davinci_cfg_reg(DM365_VOUT_COUTL_EN);
+ davinci_cfg_reg(DM365_VOUT_COUTH_EN);
+ break;
+ case MEDIA_BUS_FMT_YUYV10_1X20:
+ if (field)
+ davinci_cfg_reg(DM365_VOUT_FIELD);
+ else
+ davinci_cfg_reg(DM365_VOUT_FIELD_G81);
+ davinci_cfg_reg(DM365_VOUT_COUTL_EN);
+ davinci_cfg_reg(DM365_VOUT_COUTH_EN);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int dm365_venc_setup_clock(enum vpbe_enc_timings_type type,
+ unsigned int pclock)
+{
+ void __iomem *vpss_clkctl_reg;
+ u32 val;
+
+ vpss_clkctl_reg = DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL);
+
+ switch (type) {
+ case VPBE_ENC_STD:
+ val = VPSS_VENCCLKEN_ENABLE | VPSS_DACCLKEN_ENABLE;
+ break;
+ case VPBE_ENC_DV_TIMINGS:
+ if (pclock <= 27000000) {
+ val = VPSS_VENCCLKEN_ENABLE | VPSS_DACCLKEN_ENABLE;
+ } else {
+ /* set sysclk4 to output 74.25 MHz from pll1 */
+ val = VPSS_PLLC2SYSCLK5_ENABLE | VPSS_DACCLKEN_ENABLE |
+ VPSS_VENCCLKEN_ENABLE;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ writel(val, vpss_clkctl_reg);
+
+ return 0;
+}
+
+static struct platform_device dm365_vpbe_display = {
+ .name = "vpbe-v4l2",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm365_v4l2_disp_resources),
+ .resource = dm365_v4l2_disp_resources,
+ .dev = {
+ .dma_mask = &dm365_video_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct venc_platform_data dm365_venc_pdata = {
+ .setup_pinmux = dm365_vpbe_setup_pinmux,
+ .setup_clock = dm365_venc_setup_clock,
+};
+
+static struct platform_device dm365_venc_dev = {
+ .name = DM365_VPBE_VENC_SUBDEV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm365_venc_resources),
+ .resource = dm365_venc_resources,
+ .dev = {
+ .dma_mask = &dm365_video_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = (void *)&dm365_venc_pdata,
+ },
+};
+
+static struct platform_device dm365_vpbe_dev = {
+ .name = "vpbe_controller",
+ .id = -1,
+ .dev = {
+ .dma_mask = &dm365_video_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+int __init dm365_init_video(struct vpfe_config *vpfe_cfg,
+ struct vpbe_config *vpbe_cfg)
+{
+ if (vpfe_cfg || vpbe_cfg)
+ platform_device_register(&dm365_vpss_device);
+
+ if (vpfe_cfg) {
+ vpfe_capture_dev.dev.platform_data = vpfe_cfg;
+ platform_device_register(&dm365_isif_dev);
+ platform_device_register(&vpfe_capture_dev);
+ }
+ if (vpbe_cfg) {
+ dm365_vpbe_dev.dev.platform_data = vpbe_cfg;
+ platform_device_register(&dm365_osd_dev);
+ platform_device_register(&dm365_venc_dev);
+ platform_device_register(&dm365_vpbe_dev);
+ platform_device_register(&dm365_vpbe_display);
+ }
+
+ return 0;
+}
+
+static int __init dm365_init_devices(void)
+{
+ int ret = 0;
+
+ 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);
+
+ ret = davinci_init_wdt();
+ if (ret)
+ pr_warn("%s: watchdog init failed: %d\n", __func__, ret);
+
+ return ret;
+}
+postcore_initcall(dm365_init_devices);
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
new file mode 100644
index 000000000..dc5265790
--- /dev/null
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -0,0 +1,969 @@
+/*
+ * 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/platform_data/edma.h>
+#include <linux/platform_data/gpio-davinci.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/cputype.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 "davinci.h"
+#include "clock.h"
+#include "mux.h"
+#include "asp.h"
+
+/*
+ * Device specific clocks
+ */
+#define DM644X_REF_FREQ 27000000
+
+#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
+
+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,
+ .domain = DAVINCI_GPSC_DSPDOMAIN,
+ .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,
+ .domain = DAVINCI_GPSC_DSPDOMAIN,
+ .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("vpss", "master", &vpss_master_clk),
+ CLK("vpss", "slave", &vpss_slave_clk),
+ CLK(NULL, "arm", &arm_clk),
+ CLK("serial8250.0", NULL, &uart0_clk),
+ CLK("serial8250.1", NULL, &uart1_clk),
+ CLK("serial8250.2", NULL, &uart2_clk),
+ CLK("davinci_emac.1", NULL, &emac_clk),
+ CLK("davinci_mdio.0", "fck", &emac_clk),
+ CLK("i2c_davinci.1", NULL, &i2c_clk),
+ CLK("palm_bk3710", NULL, &ide_clk),
+ CLK("davinci-mcbsp", NULL, &asp_clk),
+ CLK("dm6441-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("davinci-wdt", 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 s8
+queue_priority_mapping[][2] = {
+ /* {event queue no, Priority} */
+ {0, 3},
+ {1, 7},
+ {-1, -1},
+};
+
+static struct edma_soc_info edma_cc0_info = {
+ .queue_priority_mapping = queue_priority_mapping,
+ .default_queue = EVENTQ_1,
+};
+
+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[] = {
+ {
+ .name = "mpu",
+ .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,
+};
+
+#define DM644X_VPSS_BASE 0x01c73400
+
+static struct resource dm644x_vpss_resources[] = {
+ {
+ /* VPSS Base address */
+ .name = "vpss",
+ .start = DM644X_VPSS_BASE,
+ .end = DM644X_VPSS_BASE + 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 dm644x_vpfe_resources[] = {
+ {
+ .start = IRQ_VDINT0,
+ .end = IRQ_VDINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_VDINT1,
+ .end = IRQ_VDINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 dm644x_video_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 = &dm644x_video_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct platform_device dm644x_vpfe_dev = {
+ .name = CAPTURE_DRV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm644x_vpfe_resources),
+ .resource = dm644x_vpfe_resources,
+ .dev = {
+ .dma_mask = &dm644x_video_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+#define DM644X_OSD_BASE 0x01c72600
+
+static struct resource dm644x_osd_resources[] = {
+ {
+ .start = DM644X_OSD_BASE,
+ .end = DM644X_OSD_BASE + 0x1ff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm644x_osd_dev = {
+ .name = DM644X_VPBE_OSD_SUBDEV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm644x_osd_resources),
+ .resource = dm644x_osd_resources,
+ .dev = {
+ .dma_mask = &dm644x_video_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+#define DM644X_VENC_BASE 0x01c72400
+
+static struct resource dm644x_venc_resources[] = {
+ {
+ .start = DM644X_VENC_BASE,
+ .end = DM644X_VENC_BASE + 0x17f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+#define DM644X_VPSS_MUXSEL_PLL2_MODE BIT(0)
+#define DM644X_VPSS_MUXSEL_VPBECLK_MODE BIT(1)
+#define DM644X_VPSS_VENCLKEN BIT(3)
+#define DM644X_VPSS_DACCLKEN BIT(4)
+
+static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type,
+ unsigned int pclock)
+{
+ int ret = 0;
+ u32 v = DM644X_VPSS_VENCLKEN;
+
+ switch (type) {
+ case VPBE_ENC_STD:
+ v |= DM644X_VPSS_DACCLKEN;
+ writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
+ break;
+ case VPBE_ENC_DV_TIMINGS:
+ if (pclock <= 27000000) {
+ v |= DM644X_VPSS_DACCLKEN;
+ writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
+ } else {
+ /*
+ * For HD, use external clock source since
+ * HD requires higher clock rate
+ */
+ v |= DM644X_VPSS_MUXSEL_VPBECLK_MODE;
+ writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static struct resource dm644x_v4l2_disp_resources[] = {
+ {
+ .start = IRQ_VENCINT,
+ .end = IRQ_VENCINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dm644x_vpbe_display = {
+ .name = "vpbe-v4l2",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm644x_v4l2_disp_resources),
+ .resource = dm644x_v4l2_disp_resources,
+ .dev = {
+ .dma_mask = &dm644x_video_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct venc_platform_data dm644x_venc_pdata = {
+ .setup_clock = dm644x_venc_setup_clock,
+};
+
+static struct platform_device dm644x_venc_dev = {
+ .name = DM644X_VPBE_VENC_SUBDEV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm644x_venc_resources),
+ .resource = dm644x_venc_resources,
+ .dev = {
+ .dma_mask = &dm644x_video_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &dm644x_venc_pdata,
+ },
+};
+
+static struct platform_device dm644x_vpbe_dev = {
+ .name = "vpbe_controller",
+ .id = -1,
+ .dev = {
+ .dma_mask = &dm644x_video_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource dm644_gpio_resources[] = {
+ { /* registers */
+ .start = DAVINCI_GPIO_BASE,
+ .end = DAVINCI_GPIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ { /* interrupt */
+ .start = IRQ_GPIOBNK0,
+ .end = IRQ_GPIOBNK4,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct davinci_gpio_platform_data dm644_gpio_platform_data = {
+ .ngpio = 71,
+};
+
+int __init dm644x_gpio_register(void)
+{
+ return davinci_gpio_register(dm644_gpio_resources,
+ ARRAY_SIZE(dm644_gpio_resources),
+ &dm644_gpio_platform_data);
+}
+/*----------------------------------------------------------------------*/
+
+static struct map_desc dm644x_io_desc[] = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+};
+
+/* 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_serial0_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART0_BASE,
+ .irq = IRQ_UARTINT0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ }
+};
+static struct plat_serial8250_port dm644x_serial1_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART1_BASE,
+ .irq = IRQ_UARTINT1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ }
+};
+static struct plat_serial8250_port dm644x_serial2_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART2_BASE,
+ .irq = IRQ_UARTINT2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ }
+};
+
+struct platform_device dm644x_serial_device[] = {
+ {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = dm644x_serial0_platform_data,
+ }
+ },
+ {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM1,
+ .dev = {
+ .platform_data = dm644x_serial1_platform_data,
+ }
+ },
+ {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM2,
+ .dev = {
+ .platform_data = dm644x_serial2_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,
+ .emac_pdata = &dm644x_emac_pdata,
+ .sram_dma = 0x00008000,
+ .sram_len = SZ_16K,
+};
+
+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);
+ davinci_map_sysmod();
+}
+
+int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
+ struct vpbe_config *vpbe_cfg)
+{
+ if (vpfe_cfg || vpbe_cfg)
+ platform_device_register(&dm644x_vpss_device);
+
+ if (vpfe_cfg) {
+ dm644x_vpfe_dev.dev.platform_data = vpfe_cfg;
+ platform_device_register(&dm644x_ccdc_dev);
+ platform_device_register(&dm644x_vpfe_dev);
+ }
+
+ if (vpbe_cfg) {
+ dm644x_vpbe_dev.dev.platform_data = vpbe_cfg;
+ platform_device_register(&dm644x_osd_dev);
+ platform_device_register(&dm644x_venc_dev);
+ platform_device_register(&dm644x_vpbe_dev);
+ platform_device_register(&dm644x_vpbe_display);
+ }
+
+ return 0;
+}
+
+static int __init dm644x_init_devices(void)
+{
+ int ret = 0;
+
+ if (!cpu_is_davinci_dm644x())
+ return 0;
+
+ platform_device_register(&dm644x_edma_device);
+
+ platform_device_register(&dm644x_mdio_device);
+ platform_device_register(&dm644x_emac_device);
+
+ ret = davinci_init_wdt();
+ if (ret)
+ pr_warn("%s: watchdog init failed: %d\n", __func__, ret);
+
+ return ret;
+}
+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 000000000..3f842bb26
--- /dev/null
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -0,0 +1,966 @@
+/*
+ * 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/platform_data/edma.h>
+#include <linux/platform_data/gpio-davinci.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/cputype.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 "davinci.h"
+#include "clock.h"
+#include "mux.h"
+#include "asp.h"
+
+#define DAVINCI_VPIF_BASE (0x01C12000)
+
+#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_REF_FREQ 27000000
+#define DM646X_AUX_FREQ 24000000
+
+#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
+
+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 = DM646X_REF_FREQ,
+ .set_rate = davinci_simple_set_rate,
+};
+
+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,
+ .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("serial8250.0", NULL, &uart0_clk),
+ CLK("serial8250.1", NULL, &uart1_clk),
+ CLK("serial8250.2", NULL, &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("davinci_mdio.0", "fck", &emac_clk),
+ CLK(NULL, "pwm0", &pwm0_clk),
+ CLK(NULL, "pwm1", &pwm1_clk),
+ CLK(NULL, "timer0", &timer0_clk),
+ CLK(NULL, "timer1", &timer1_clk),
+ CLK("davinci-wdt", 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_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 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 = {
+ .queue_priority_mapping = dm646x_queue_priority_mapping,
+ .default_queue = EVENTQ_1,
+};
+
+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 = "mpu",
+ .start = DAVINCI_DM646X_MCASP0_REG_BASE,
+ .end = DAVINCI_DM646X_MCASP0_REG_BASE + (SZ_1K << 1) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "tx",
+ .start = DAVINCI_DM646X_DMA_MCASP0_AXEVT0,
+ .end = DAVINCI_DM646X_DMA_MCASP0_AXEVT0,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "rx",
+ .start = DAVINCI_DM646X_DMA_MCASP0_AREVT0,
+ .end = DAVINCI_DM646X_DMA_MCASP0_AREVT0,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = IRQ_DM646X_MCASP0TXINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "rx",
+ .start = IRQ_DM646X_MCASP0RXINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* DIT mode only, rx is not supported */
+static struct resource dm646x_mcasp1_resources[] = {
+ {
+ .name = "mpu",
+ .start = DAVINCI_DM646X_MCASP1_REG_BASE,
+ .end = DAVINCI_DM646X_MCASP1_REG_BASE + (SZ_1K << 1) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "tx",
+ .start = DAVINCI_DM646X_DMA_MCASP1_AXEVT1,
+ .end = DAVINCI_DM646X_DMA_MCASP1_AXEVT1,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = IRQ_DM646X_MCASP1TXINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+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 resource dm646x_gpio_resources[] = {
+ { /* registers */
+ .start = DAVINCI_GPIO_BASE,
+ .end = DAVINCI_GPIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ { /* interrupt */
+ .start = IRQ_DM646X_GPIOBNK0,
+ .end = IRQ_DM646X_GPIOBNK2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct davinci_gpio_platform_data dm646x_gpio_platform_data = {
+ .ngpio = 43,
+};
+
+int __init dm646x_gpio_register(void)
+{
+ return davinci_gpio_register(dm646x_gpio_resources,
+ ARRAY_SIZE(dm646x_gpio_resources),
+ &dm646x_gpio_platform_data);
+}
+/*----------------------------------------------------------------------*/
+
+static struct map_desc dm646x_io_desc[] = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+};
+
+/* 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_serial0_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART0_BASE,
+ .irq = IRQ_UARTINT0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ }
+};
+static struct plat_serial8250_port dm646x_serial1_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART1_BASE,
+ .irq = IRQ_UARTINT1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ }
+};
+static struct plat_serial8250_port dm646x_serial2_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART2_BASE,
+ .irq = IRQ_DM646X_UARTINT2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ }
+};
+
+struct platform_device dm646x_serial_device[] = {
+ {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = dm646x_serial0_platform_data,
+ }
+ },
+ {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM1,
+ .dev = {
+ .platform_data = dm646x_serial1_platform_data,
+ }
+ },
+ {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM2,
+ .dev = {
+ .platform_data = dm646x_serial2_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,
+ .emac_pdata = &dm646x_emac_pdata,
+ .sram_dma = 0x10010000,
+ .sram_len = SZ_32K,
+};
+
+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;
+
+ value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
+ value &= ~VSCLKDIS_MASK;
+ __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
+
+ value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN));
+ value &= ~VDD3P3V_VID_MASK;
+ __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN));
+
+ 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)
+{
+ davinci_common_init(&davinci_soc_info_dm646x);
+ davinci_map_sysmod();
+}
+
+static int __init dm646x_init_devices(void)
+{
+ int ret = 0;
+
+ if (!cpu_is_davinci_dm646x())
+ return 0;
+
+ platform_device_register(&dm646x_mdio_device);
+ platform_device_register(&dm646x_emac_device);
+
+ ret = davinci_init_wdt();
+ if (ret)
+ pr_warn("%s: watchdog init failed: %d\n", __func__, ret);
+
+ return ret;
+}
+postcore_initcall(dm646x_init_devices);
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 000000000..3e8af6a0b
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/clock.h
@@ -0,0 +1,24 @@
+/*
+ * 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);
+
+int davinci_clk_reset_assert(struct clk *c);
+int davinci_clk_reset_deassert(struct clk *c);
+
+#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 000000000..0b3c16975
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -0,0 +1,107 @@
+/*
+ * 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>
+#include <linux/reboot.h>
+
+extern void davinci_timer_init(void);
+
+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 emac_platform_data *emac_pdata;
+ dma_addr_t sram_dma;
+ unsigned sram_len;
+};
+
+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);
+void davinci_restart(enum reboot_mode mode, const char *cmd);
+void davinci_init_late(void);
+
+#ifdef CONFIG_DAVINCI_RESET_CLOCKS
+int davinci_clk_disable_unused(void);
+#else
+static inline int davinci_clk_disable_unused(void) { return 0; }
+#endif
+
+#ifdef CONFIG_CPU_FREQ
+int davinci_cpufreq_init(void);
+#else
+static inline int davinci_cpufreq_init(void) { return 0; }
+#endif
+
+#ifdef CONFIG_SUSPEND
+int davinci_pm_init(void);
+#else
+static inline int davinci_pm_init(void) { return 0; }
+#endif
+
+#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 000000000..827bbe9ba
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/cp_intc.h
@@ -0,0 +1,57 @@
+/*
+ * 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 cp_intc_init(void);
+int cp_intc_of_init(struct device_node *, struct device_node *);
+
+#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 000000000..3c089cfb6
--- /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 000000000..74f088b0e
--- /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 000000000..1fc84e216
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/cputype.h
@@ -0,0 +1,86 @@
+/*
+ * 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 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)
+
+#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
+
+#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 000000000..39e58b48e
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -0,0 +1,154 @@
+/*
+ * 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 <linux/platform_data/davinci_asp.h>
+#include <linux/reboot.h>
+#include <linux/videodev2.h>
+
+#include <mach/serial.h>
+#include <mach/pm.h>
+#include <linux/platform_data/edma.h>
+#include <linux/platform_data/i2c-davinci.h>
+#include <linux/platform_data/mmc-davinci.h>
+#include <linux/platform_data/usb-davinci.h>
+#include <linux/platform_data/spi-davinci.h>
+#include <linux/platform_data/uio_pruss.h>
+
+#include <media/davinci/vpif_types.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_HOST1CFG_REG 0x44
+#define DA8XX_CHIPSIG_REG 0x174
+#define DA8XX_CFGCHIP0_REG 0x17c
+#define DA8XX_CFGCHIP1_REG 0x180
+#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_PWRDN_REG 0x18
+
+#define DA8XX_PSC0_BASE 0x01c10000
+#define DA8XX_PLL0_BASE 0x01c11000
+#define DA8XX_TIMER64P0_BASE 0x01c20000
+#define DA8XX_TIMER64P1_BASE 0x01c21000
+#define DA8XX_VPIF_BASE 0x01e17000
+#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_SHARED_RAM_BASE 0x80000000
+#define DA8XX_ARM_RAM_BASE 0xffff0000
+
+void da830_init(void);
+void 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_bus(int instance, unsigned num_chipselect);
+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_uio_pruss(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 da8xx_register_mcasp(int id, struct snd_platform_data *pdata);
+int da8xx_register_rtc(void);
+int da8xx_register_gpio(void *pdata);
+int da850_register_cpufreq(char *async_clk);
+int da8xx_register_cpuidle(void);
+void __iomem *da8xx_get_mem_ctlr(void);
+int da850_register_pm(struct platform_device *pdev);
+int da850_register_sata(unsigned long refclkpn);
+int da850_register_vpif(void);
+int da850_register_vpif_display
+ (struct vpif_display_config *display_config);
+int da850_register_vpif_capture
+ (struct vpif_capture_config *capture_config);
+void da8xx_restart(enum reboot_mode mode, const char *cmd);
+void da8xx_rproc_reserve_cma(void);
+int da8xx_register_rproc(void);
+int da850_register_gpio(void);
+int da830_register_gpio(void);
+
+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 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_vpif_capture_pins[];
+extern const short da850_vpif_display_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/ddr2.h b/arch/arm/mach-davinci/include/mach/ddr2.h
new file mode 100644
index 000000000..c19e047d0
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/ddr2.h
@@ -0,0 +1,4 @@
+#define DDR2_SDRCR_OFFSET 0xc
+#define DDR2_SRPD_BIT (1 << 23)
+#define DDR2_MCLKSTOPEN_BIT (1 << 30)
+#define DDR2_LPMODEN_BIT (1 << 31)
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 000000000..cf5f573eb
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/entry-macro.S
@@ -0,0 +1,39 @@
+/*
+ * 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/irqs.h>
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =davinci_intc_base
+ ldr \base, [\base]
+ .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 */
+ mov \tmp, \irqnr, lsr #31
+ and \irqnr, \irqnr, #0xff /* irq is in bits 0-9 */
+ and \tmp, \tmp, #0x1
+ cmp \tmp, #0x1
+#endif
+1002:
+ .endm
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 000000000..16bb42291
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/hardware.h
@@ -0,0 +1,33 @@
+/*
+ * 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
+ */
+/*
+ * I/O mapping
+ */
+#define IO_PHYS UL(0x01c00000)
+#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))
+
+#endif /* __ASM_ARCH_HARDWARE_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 000000000..edb2ca623
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/irqs.h
@@ -0,0 +1,409 @@
+/*
+ * 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_MCASP1TXINT 30
+#define IRQ_DM646X_RESERVED_3 31
+#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
+
+/* 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/mux.h b/arch/arm/mach-davinci/include/mach/mux.h
new file mode 100644
index 000000000..631655e68
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/mux.h
@@ -0,0 +1,990 @@
+/*
+ * 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,
+
+ /* MMC/SD1 function */
+ DA850_MMCSD1_DAT_0,
+ DA850_MMCSD1_DAT_1,
+ DA850_MMCSD1_DAT_2,
+ DA850_MMCSD1_DAT_3,
+ DA850_MMCSD1_CLK,
+ DA850_MMCSD1_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_9,
+ DA850_GPIO6_10,
+ DA850_GPIO6_13,
+ DA850_RTC_ALARM,
+
+ /* VPIF Capture */
+ DA850_VPIF_DIN0,
+ DA850_VPIF_DIN1,
+ DA850_VPIF_DIN2,
+ DA850_VPIF_DIN3,
+ DA850_VPIF_DIN4,
+ DA850_VPIF_DIN5,
+ DA850_VPIF_DIN6,
+ DA850_VPIF_DIN7,
+ DA850_VPIF_DIN8,
+ DA850_VPIF_DIN9,
+ DA850_VPIF_DIN10,
+ DA850_VPIF_DIN11,
+ DA850_VPIF_DIN12,
+ DA850_VPIF_DIN13,
+ DA850_VPIF_DIN14,
+ DA850_VPIF_DIN15,
+ DA850_VPIF_CLKIN0,
+ DA850_VPIF_CLKIN1,
+ DA850_VPIF_CLKIN2,
+ DA850_VPIF_CLKIN3,
+
+ /* VPIF Display */
+ DA850_VPIF_DOUT0,
+ DA850_VPIF_DOUT1,
+ DA850_VPIF_DOUT2,
+ DA850_VPIF_DOUT3,
+ DA850_VPIF_DOUT4,
+ DA850_VPIF_DOUT5,
+ DA850_VPIF_DOUT6,
+ DA850_VPIF_DOUT7,
+ DA850_VPIF_DOUT8,
+ DA850_VPIF_DOUT9,
+ DA850_VPIF_DOUT10,
+ DA850_VPIF_DOUT11,
+ DA850_VPIF_DOUT12,
+ DA850_VPIF_DOUT13,
+ DA850_VPIF_DOUT14,
+ DA850_VPIF_DOUT15,
+ DA850_VPIF_CLKO2,
+ DA850_VPIF_CLKO3,
+};
+
+#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/pm.h b/arch/arm/mach-davinci/include/mach/pm.h
new file mode 100644
index 000000000..37b19bf35
--- /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 000000000..99d47cfa3
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/psc.h
@@ -0,0 +1,217 @@
+/*
+ * 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 DA850_LPSC1_VPIF 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
+
+/* PSC register offsets */
+#define EPCPR 0x070
+#define PTCMD 0x120
+#define PTSTAT 0x128
+#define PDSTAT 0x200
+#define PDCTL 0x300
+#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 0x3f
+#define PDSTAT_STATE_MASK 0x1f
+#define MDCTL_LRST BIT(8)
+#define MDCTL_FORCE BIT(31)
+#define PDCTL_NEXT BIT(0)
+#define PDCTL_EPCGOOD BIT(8)
+
+#ifndef __ASSEMBLER__
+
+extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
+extern void davinci_psc_reset(unsigned int ctlr, unsigned int id,
+ bool reset);
+extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
+ unsigned int id, bool enable, u32 flags);
+
+#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 000000000..d4b4aa879
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/serial.h
@@ -0,0 +1,37 @@
+/*
+ * 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>
+
+#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)
+
+/* DaVinci UART register offsets */
+#define UART_DAVINCI_PWREMU 0x0c
+#define UART_DM646X_SCR 0x10
+#define UART_DM646X_SCR_TX_WATERMARK 0x08
+
+#ifndef __ASSEMBLY__
+#include <linux/platform_device.h>
+
+extern int davinci_serial_init(struct platform_device *);
+#endif
+
+#endif /* __ASM_ARCH_SERIAL_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 000000000..4e5db5621
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/sram.h
@@ -0,0 +1,30 @@
+/*
+ * 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);
+
+/* Get the struct gen_pool * for use in platform data */
+extern struct gen_pool *sram_get_gen_pool(void);
+
+#endif /* __MACH_SRAM_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 000000000..1c971d8d8
--- /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/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h
new file mode 100644
index 000000000..8fb97b93b
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/uncompress.h
@@ -0,0 +1,97 @@
+/*
+ * 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>
+
+#define IOMEM(x) ((void __force __iomem *)(x))
+
+u32 *uart;
+
+/* PORT_16C550A, in polled non-fifo mode */
+static void putc(char c)
+{
+ if (!uart)
+ return;
+
+ while (!(uart[UART_LSR] & UART_LSR_THRE))
+ barrier();
+ uart[UART_TX] = c;
+}
+
+static inline void flush(void)
+{
+ if (!uart)
+ return;
+
+ while (!(uart[UART_LSR] & UART_LSR_THRE))
+ barrier();
+}
+
+static inline void set_uart_info(u32 phys)
+{
+ uart = (u32 *)phys;
+}
+
+#define _DEBUG_LL_ENTRY(machine, phys) \
+ { \
+ if (machine_is_##machine()) { \
+ set_uart_info(phys); \
+ break; \
+ } \
+ }
+
+#define DEBUG_LL_DAVINCI(machine, port) \
+ _DEBUG_LL_ENTRY(machine, DAVINCI_UART##port##_BASE)
+
+#define DEBUG_LL_DA8XX(machine, port) \
+ _DEBUG_LL_ENTRY(machine, DA8XX_UART##port##_BASE)
+
+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);
+ } while (0);
+}
+
+#define arch_decomp_setup() __arch_decomp_setup(arch_id)
diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c
new file mode 100644
index 000000000..952dc126c
--- /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 000000000..6a2ff0a65
--- /dev/null
+++ b/arch/arm/mach-davinci/mux.c
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#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 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) {
+ pr_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) {
+ pr_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
+ pr_warn("initialized %s\n", cfg->name);
+#endif
+ }
+
+#ifdef CONFIG_DAVINCI_MUX_DEBUG
+ if (cfg->debug || warn) {
+ pr_warn("Setting register %s\n", cfg->name);
+ pr_warn(" %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 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 000000000..5aad1e7dd
--- /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 000000000..07e23ba61
--- /dev/null
+++ b/arch/arm/mach-davinci/pm.c
@@ -0,0 +1,158 @@
+/*
+ * 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/common.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",
+ },
+ .remove = __exit_p(davinci_pm_remove),
+};
+
+int __init davinci_pm_init(void)
+{
+ return platform_driver_probe(&davinci_pm_driver, davinci_pm_probe);
+}
diff --git a/arch/arm/mach-davinci/pm_domain.c b/arch/arm/mach-davinci/pm_domain.c
new file mode 100644
index 000000000..641edc313
--- /dev/null
+++ b/arch/arm/mach-davinci/pm_domain.c
@@ -0,0 +1,65 @@
+/*
+ * Runtime PM support code for DaVinci
+ *
+ * Author: Kevin Hilman
+ *
+ * Copyright (C) 2012 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/pm_runtime.h>
+#include <linux/pm_clock.h>
+#include <linux/platform_device.h>
+
+#ifdef CONFIG_PM
+static int davinci_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_clk_suspend(dev);
+ if (ret) {
+ pm_generic_runtime_resume(dev);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int davinci_pm_runtime_resume(struct device *dev)
+{
+ dev_dbg(dev, "%s\n", __func__);
+
+ pm_clk_resume(dev);
+ return pm_generic_runtime_resume(dev);
+}
+#endif
+
+static struct dev_pm_domain davinci_pm_domain = {
+ .ops = {
+ SET_RUNTIME_PM_OPS(davinci_pm_runtime_suspend,
+ davinci_pm_runtime_resume, NULL)
+ USE_PLATFORM_PM_SLEEP_OPS
+ },
+};
+
+static struct pm_clk_notifier_block platform_bus_notifier = {
+ .pm_domain = &davinci_pm_domain,
+ .con_ids = { "fck", "master", "slave", NULL },
+};
+
+static int __init davinci_pm_runtime_init(void)
+{
+ pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
+
+ return 0;
+}
+core_initcall(davinci_pm_runtime_init);
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c
new file mode 100644
index 000000000..82fdc69d5
--- /dev/null
+++ b/arch/arm/mach-davinci/psc.c
@@ -0,0 +1,137 @@
+/*
+ * 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>
+
+#include "clock.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_warn("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);
+}
+
+/* Control "reset" line associated with PSC domain */
+void davinci_psc_reset(unsigned int ctlr, unsigned int id, bool reset)
+{
+ u32 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_warn("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 = readl(psc_base + MDCTL + 4 * id);
+ if (reset)
+ mdctl &= ~MDCTL_LRST;
+ else
+ mdctl |= MDCTL_LRST;
+ writel(mdctl, psc_base + MDCTL + 4 * id);
+
+ iounmap(psc_base);
+}
+
+/* Enable or disable a PSC domain */
+void davinci_psc_config(unsigned int domain, unsigned int ctlr,
+ unsigned int id, bool enable, u32 flags)
+{
+ u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl;
+ void __iomem *psc_base;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ u32 next_state = PSC_STATE_ENABLE;
+
+ if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
+ pr_warn("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);
+
+ if (!enable) {
+ if (flags & PSC_SWRSTDISABLE)
+ next_state = PSC_STATE_SWRSTDISABLE;
+ else
+ next_state = PSC_STATE_DISABLE;
+ }
+
+ mdctl = __raw_readl(psc_base + MDCTL + 4 * id);
+ mdctl &= ~MDSTAT_STATE_MASK;
+ mdctl |= next_state;
+ if (flags & PSC_FORCE)
+ mdctl |= MDCTL_FORCE;
+ __raw_writel(mdctl, psc_base + MDCTL + 4 * id);
+
+ pdstat = __raw_readl(psc_base + PDSTAT + 4 * domain);
+ if ((pdstat & PDSTAT_STATE_MASK) == 0) {
+ pdctl = __raw_readl(psc_base + PDCTL + 4 * domain);
+ pdctl |= PDCTL_NEXT;
+ __raw_writel(pdctl, psc_base + PDCTL + 4 * domain);
+
+ ptcmd = 1 << domain;
+ __raw_writel(ptcmd, psc_base + PTCMD);
+
+ do {
+ epcpr = __raw_readl(psc_base + EPCPR);
+ } while ((((epcpr >> domain) & 1) == 0));
+
+ pdctl = __raw_readl(psc_base + PDCTL + 4 * domain);
+ pdctl |= PDCTL_EPCGOOD;
+ __raw_writel(pdctl, psc_base + PDCTL + 4 * domain);
+ } 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 000000000..951b620bf
--- /dev/null
+++ b/arch/arm/mach-davinci/serial.c
@@ -0,0 +1,106 @@
+/*
+ * 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 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 platform_device *serial_dev)
+{
+ int i, ret = 0;
+ struct device *dev;
+ struct plat_serial8250_port *p;
+ struct clk *clk;
+
+ /*
+ * 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; serial_dev[i].dev.platform_data != NULL; i++) {
+ dev = &serial_dev[i].dev;
+ p = dev->platform_data;
+
+ ret = platform_device_register(&serial_dev[i]);
+ if (ret)
+ continue;
+
+ clk = clk_get(dev, NULL);
+ if (IS_ERR(clk)) {
+ pr_err("%s:%d: failed to get UART%d clock\n",
+ __func__, __LINE__, i);
+ continue;
+ }
+
+ clk_prepare_enable(clk);
+
+ p->uartclk = clk_get_rate(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 ret;
+}
diff --git a/arch/arm/mach-davinci/sleep.S b/arch/arm/mach-davinci/sleep.S
new file mode 100644
index 000000000..a5336a5e2
--- /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/ddr2.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
+
+ ret 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 000000000..8540dddf1
--- /dev/null
+++ b/arch/arm/mach-davinci/sram.c
@@ -0,0 +1,81 @@
+/*
+ * 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/io.h>
+#include <linux/genalloc.h>
+
+#include <mach/common.h>
+#include <mach/sram.h>
+
+static struct gen_pool *sram_pool;
+
+struct gen_pool *sram_get_gen_pool(void)
+{
+ return sram_pool;
+}
+
+void *sram_alloc(size_t len, dma_addr_t *dma)
+{
+ dma_addr_t dma_base = davinci_soc_info.sram_dma;
+
+ if (dma)
+ *dma = 0;
+ if (!sram_pool || (dma && !dma_base))
+ return NULL;
+
+ return gen_pool_dma_alloc(sram_pool, len, dma);
+
+}
+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)
+{
+ phys_addr_t phys = davinci_soc_info.sram_dma;
+ unsigned len = davinci_soc_info.sram_len;
+ int status = 0;
+ void __iomem *addr;
+
+ 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) {
+ addr = ioremap(phys, len);
+ if (!addr)
+ return -ENOMEM;
+ status = gen_pool_add_virt(sram_pool, (unsigned long) addr,
+ phys, len, -1);
+ if (status < 0)
+ iounmap(addr);
+ }
+
+ 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 000000000..160c9602f
--- /dev/null
+++ b/arch/arm/mach-davinci/time.c
@@ -0,0 +1,455 @@
+/*
+ * 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 <linux/sched_clock.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+#include <mach/cputype.h>
+#include <mach/hardware.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_TIMER,
+ .handler = timer_interrupt,
+ }
+ },
+ [TID_CLOCKSOURCE] = {
+ .name = "free-run counter",
+ .period = ~0,
+ .opts = TIMER_OPTS_PERIODIC,
+ .irqaction = {
+ .flags = 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);
+}
+
+static struct clocksource clocksource_davinci = {
+ .rating = 300,
+ .read = read_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/*
+ * Overwrite weak default sched_clock with something more precise
+ */
+static u64 notrace davinci_read_sched_clock(void)
+{
+ return timer32_read(&timers[TID_CLOCKSOURCE]);
+}
+
+/*
+ * 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,
+ .set_next_event = davinci_set_next_event,
+ .set_mode = davinci_set_mode,
+};
+
+
+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;
+ 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_warn("%s: Invalid use of system timers. Results unpredictable.\n",
+ __func__);
+ else if ((dtip[event_timer].cmp_off == 0)
+ || (dtip[event_timer].cmp_irq == 0))
+ pr_warn("%s: Invalid timer instance setup. Results unpredictable.\n",
+ __func__);
+ 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_prepare_enable(timer_clk);
+
+ /* init timer hw */
+ timer_init();
+
+ davinci_clock_tick_rate = clk_get_rate(timer_clk);
+
+ /* setup clocksource */
+ clocksource_davinci.name = id_to_name[clocksource_id];
+ if (clocksource_register_hz(&clocksource_davinci,
+ davinci_clock_tick_rate))
+ pr_err("%s: can't register clocksource!\n",
+ clocksource_davinci.name);
+
+ sched_clock_register(davinci_read_sched_clock, 32,
+ davinci_clock_tick_rate);
+
+ /* setup clockevent */
+ clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id];
+
+ clockevent_davinci.cpumask = cpumask_of(0);
+ clockevents_config_and_register(&clockevent_davinci,
+ davinci_clock_tick_rate, 1, 0xfffffffe);
+
+ for (i=0; i< ARRAY_SIZE(timers); i++)
+ timer32_config(&timers[i]);
+}
+
+/* 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_prepare_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/usb.c b/arch/arm/mach-davinci/usb.c
new file mode 100644
index 000000000..b0a6b5225
--- /dev/null
+++ b/arch/arm/mach-davinci/usb.c
@@ -0,0 +1,175 @@
+/*
+ * 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/da8xx.h>
+#include <linux/platform_data/usb-davinci.h>
+
+#define DAVINCI_USB_OTG_BASE 0x01c64000
+
+#define DA8XX_USB0_BASE 0x01e00000
+#define DA8XX_USB1_BASE 0x01e25000
+
+#if IS_ENABLED(CONFIG_USB_MUSB_HDRC)
+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 = {
+ /* OTG requires a Mini-AB connector */
+ .mode = MUSB_OTG,
+ .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-digicolor/Kconfig b/arch/arm/mach-digicolor/Kconfig
new file mode 100644
index 000000000..4f36d8d2b
--- /dev/null
+++ b/arch/arm/mach-digicolor/Kconfig
@@ -0,0 +1,7 @@
+config ARCH_DIGICOLOR
+ bool "Conexant Digicolor SoC Support"
+ depends on ARCH_MULTI_V7
+ select CLKSRC_MMIO
+ select DIGICOLOR_TIMER
+ select GENERIC_IRQ_CHIP
+ select MFD_SYSCON
diff --git a/arch/arm/mach-digicolor/Makefile b/arch/arm/mach-digicolor/Makefile
new file mode 100644
index 000000000..3d8a1d228
--- /dev/null
+++ b/arch/arm/mach-digicolor/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_DIGICOLOR) += digicolor.o
diff --git a/arch/arm/mach-digicolor/digicolor.c b/arch/arm/mach-digicolor/digicolor.c
new file mode 100644
index 000000000..cfc88d1ca
--- /dev/null
+++ b/arch/arm/mach-digicolor/digicolor.c
@@ -0,0 +1,18 @@
+/*
+ * Support for Conexant Digicolor 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 <asm/mach/arch.h>
+
+static const char *digicolor_dt_compat[] __initconst = {
+ "cnxt,cx92755",
+ NULL,
+};
+
+DT_MACHINE_START(DIGICOLOR, "Conexant Digicolor (Flattened Device Tree)")
+ .dt_compat = digicolor_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-dove/Kconfig b/arch/arm/mach-dove/Kconfig
new file mode 100644
index 000000000..d8c439c89
--- /dev/null
+++ b/arch/arm/mach-dove/Kconfig
@@ -0,0 +1,25 @@
+if ARCH_DOVE
+
+menu "Marvell Dove Implementations"
+
+config DOVE_LEGACY
+ bool
+
+config MACH_DOVE_DB
+ bool "Marvell DB-MV88AP510 Development Board"
+ select DOVE_LEGACY
+ 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"
+ select DOVE_LEGACY
+ 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 000000000..b608a2191
--- /dev/null
+++ b/arch/arm/mach-dove/Makefile
@@ -0,0 +1,5 @@
+obj-y += common.o
+obj-$(CONFIG_DOVE_LEGACY) += irq.o mpp.o
+obj-$(CONFIG_PCI) += pcie.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 000000000..760a0efe7
--- /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/cm-a510.c b/arch/arm/mach-dove/cm-a510.c
new file mode 100644
index 000000000..0dc39cf30
--- /dev/null
+++ b/arch/arm/mach-dove/cm-a510.c
@@ -0,0 +1,97 @@
+/*
+ * 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")
+ .atag_offset = 0x100,
+ .init_machine = cm_a510_init,
+ .map_io = dove_map_io,
+ .init_early = dove_init_early,
+ .init_irq = dove_init_irq,
+ .init_time = dove_timer_init,
+ .restart = dove_restart,
+MACHINE_END
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c
new file mode 100644
index 000000000..0d1a89298
--- /dev/null
+++ b/arch/arm/mach-dove/common.c
@@ -0,0 +1,411 @@
+/*
+ * 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/clk-provider.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_data/dma-mv_xor.h>
+#include <linux/platform_data/usb-ehci-orion.h>
+#include <linux/platform_device.h>
+#include <asm/hardware/cache-tauros2.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <mach/bridge-regs.h>
+#include <mach/pm.h>
+#include <plat/common.h>
+#include <plat/irq.h>
+#include <plat/time.h>
+#include "common.h"
+
+/* These can go away once Dove uses the mvebu-mbus DT binding */
+#define DOVE_MBUS_PCIE0_MEM_TARGET 0x4
+#define DOVE_MBUS_PCIE0_MEM_ATTR 0xe8
+#define DOVE_MBUS_PCIE0_IO_TARGET 0x4
+#define DOVE_MBUS_PCIE0_IO_ATTR 0xe0
+#define DOVE_MBUS_PCIE1_MEM_TARGET 0x8
+#define DOVE_MBUS_PCIE1_MEM_ATTR 0xe8
+#define DOVE_MBUS_PCIE1_IO_TARGET 0x8
+#define DOVE_MBUS_PCIE1_IO_ATTR 0xe0
+#define DOVE_MBUS_CESA_TARGET 0x3
+#define DOVE_MBUS_CESA_ATTR 0x1
+#define DOVE_MBUS_BOOTROM_TARGET 0x1
+#define DOVE_MBUS_BOOTROM_ATTR 0xfd
+#define DOVE_MBUS_SCRATCHPAD_TARGET 0xd
+#define DOVE_MBUS_SCRATCHPAD_ATTR 0x0
+
+/*****************************************************************************
+ * I/O Address Mapping
+ ****************************************************************************/
+static struct map_desc dove_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long) DOVE_SB_REGS_VIRT_BASE,
+ .pfn = __phys_to_pfn(DOVE_SB_REGS_PHYS_BASE),
+ .length = DOVE_SB_REGS_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long) DOVE_NB_REGS_VIRT_BASE,
+ .pfn = __phys_to_pfn(DOVE_NB_REGS_PHYS_BASE),
+ .length = DOVE_NB_REGS_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init dove_map_io(void)
+{
+ iotable_init(dove_io_desc, ARRAY_SIZE(dove_io_desc));
+}
+
+/*****************************************************************************
+ * CLK tree
+ ****************************************************************************/
+static int dove_tclk;
+
+static DEFINE_SPINLOCK(gating_lock);
+static struct clk *tclk;
+
+static struct clk __init *dove_register_gate(const char *name,
+ const char *parent, u8 bit_idx)
+{
+ return clk_register_gate(NULL, name, parent, 0,
+ (void __iomem *)CLOCK_GATING_CONTROL,
+ bit_idx, 0, &gating_lock);
+}
+
+static void __init dove_clk_init(void)
+{
+ struct clk *usb0, *usb1, *sata, *pex0, *pex1, *sdio0, *sdio1;
+ struct clk *nand, *camera, *i2s0, *i2s1, *crypto, *ac97, *pdma;
+ struct clk *xor0, *xor1, *ge, *gephy;
+
+ tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT,
+ dove_tclk);
+
+ usb0 = dove_register_gate("usb0", "tclk", CLOCK_GATING_BIT_USB0);
+ usb1 = dove_register_gate("usb1", "tclk", CLOCK_GATING_BIT_USB1);
+ sata = dove_register_gate("sata", "tclk", CLOCK_GATING_BIT_SATA);
+ pex0 = dove_register_gate("pex0", "tclk", CLOCK_GATING_BIT_PCIE0);
+ pex1 = dove_register_gate("pex1", "tclk", CLOCK_GATING_BIT_PCIE1);
+ sdio0 = dove_register_gate("sdio0", "tclk", CLOCK_GATING_BIT_SDIO0);
+ sdio1 = dove_register_gate("sdio1", "tclk", CLOCK_GATING_BIT_SDIO1);
+ nand = dove_register_gate("nand", "tclk", CLOCK_GATING_BIT_NAND);
+ camera = dove_register_gate("camera", "tclk", CLOCK_GATING_BIT_CAMERA);
+ i2s0 = dove_register_gate("i2s0", "tclk", CLOCK_GATING_BIT_I2S0);
+ i2s1 = dove_register_gate("i2s1", "tclk", CLOCK_GATING_BIT_I2S1);
+ crypto = dove_register_gate("crypto", "tclk", CLOCK_GATING_BIT_CRYPTO);
+ ac97 = dove_register_gate("ac97", "tclk", CLOCK_GATING_BIT_AC97);
+ pdma = dove_register_gate("pdma", "tclk", CLOCK_GATING_BIT_PDMA);
+ xor0 = dove_register_gate("xor0", "tclk", CLOCK_GATING_BIT_XOR0);
+ xor1 = dove_register_gate("xor1", "tclk", CLOCK_GATING_BIT_XOR1);
+ gephy = dove_register_gate("gephy", "tclk", CLOCK_GATING_BIT_GIGA_PHY);
+ ge = dove_register_gate("ge", "gephy", CLOCK_GATING_BIT_GBE);
+
+ orion_clkdev_add(NULL, "orion_spi.0", tclk);
+ orion_clkdev_add(NULL, "orion_spi.1", tclk);
+ orion_clkdev_add(NULL, "orion_wdt", tclk);
+ orion_clkdev_add(NULL, "mv64xxx_i2c.0", tclk);
+
+ orion_clkdev_add(NULL, "orion-ehci.0", usb0);
+ orion_clkdev_add(NULL, "orion-ehci.1", usb1);
+ orion_clkdev_add(NULL, "mv643xx_eth_port.0", ge);
+ orion_clkdev_add(NULL, "sata_mv.0", sata);
+ orion_clkdev_add("0", "pcie", pex0);
+ orion_clkdev_add("1", "pcie", pex1);
+ orion_clkdev_add(NULL, "sdhci-dove.0", sdio0);
+ orion_clkdev_add(NULL, "sdhci-dove.1", sdio1);
+ orion_clkdev_add(NULL, "orion_nand", nand);
+ orion_clkdev_add(NULL, "cafe1000-ccic.0", camera);
+ orion_clkdev_add(NULL, "mvebu-audio.0", i2s0);
+ orion_clkdev_add(NULL, "mvebu-audio.1", i2s1);
+ orion_clkdev_add(NULL, "mv_crypto", crypto);
+ orion_clkdev_add(NULL, "dove-ac97", ac97);
+ orion_clkdev_add(NULL, "dove-pdma", pdma);
+ orion_clkdev_add(NULL, MV_XOR_NAME ".0", xor0);
+ orion_clkdev_add(NULL, MV_XOR_NAME ".1", xor1);
+}
+
+/*****************************************************************************
+ * EHCI0
+ ****************************************************************************/
+void __init dove_ehci0_init(void)
+{
+ orion_ehci_init(DOVE_USB0_PHYS_BASE, IRQ_DOVE_USB0, EHCI_PHY_NA);
+}
+
+/*****************************************************************************
+ * EHCI1
+ ****************************************************************************/
+void __init dove_ehci1_init(void)
+{
+ orion_ehci_1_init(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_GE00_PHYS_BASE,
+ IRQ_DOVE_GE00_SUM, IRQ_DOVE_GE00_ERR,
+ 1600);
+}
+
+/*****************************************************************************
+ * SoC RTC
+ ****************************************************************************/
+static 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_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, tclk);
+}
+
+/*****************************************************************************
+ * UART1
+ ****************************************************************************/
+void __init dove_uart1_init(void)
+{
+ orion_uart1_init(DOVE_UART1_VIRT_BASE, DOVE_UART1_PHYS_BASE,
+ IRQ_DOVE_UART_1, tclk);
+}
+
+/*****************************************************************************
+ * UART2
+ ****************************************************************************/
+void __init dove_uart2_init(void)
+{
+ orion_uart2_init(DOVE_UART2_VIRT_BASE, DOVE_UART2_PHYS_BASE,
+ IRQ_DOVE_UART_2, tclk);
+}
+
+/*****************************************************************************
+ * UART3
+ ****************************************************************************/
+void __init dove_uart3_init(void)
+{
+ orion_uart3_init(DOVE_UART3_VIRT_BASE, DOVE_UART3_PHYS_BASE,
+ IRQ_DOVE_UART_3, tclk);
+}
+
+/*****************************************************************************
+ * SPI
+ ****************************************************************************/
+void __init dove_spi0_init(void)
+{
+ orion_spi_init(DOVE_SPI0_PHYS_BASE);
+}
+
+void __init dove_spi1_init(void)
+{
+ orion_spi_1_init(DOVE_SPI1_PHYS_BASE);
+}
+
+/*****************************************************************************
+ * 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);
+ mvebu_mbus_init("marvell,dove-mbus",
+ BRIDGE_WINS_BASE, BRIDGE_WINS_SZ,
+ DOVE_MC_WINS_BASE, DOVE_MC_WINS_SZ);
+}
+
+static int __init dove_find_tclk(void)
+{
+ return 166666667;
+}
+
+void __init dove_timer_init(void)
+{
+ dove_tclk = dove_find_tclk();
+ orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
+ IRQ_DOVE_BRIDGE, dove_tclk);
+}
+
+/*****************************************************************************
+ * XOR 0
+ ****************************************************************************/
+static void __init dove_xor0_init(void)
+{
+ orion_xor0_init(DOVE_XOR0_PHYS_BASE, DOVE_XOR0_HIGH_PHYS_BASE,
+ IRQ_DOVE_XOR_00, IRQ_DOVE_XOR_01);
+}
+
+/*****************************************************************************
+ * XOR 1
+ ****************************************************************************/
+static 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_setup_cpu_wins(void)
+{
+ /*
+ * The PCIe windows will no longer be statically allocated
+ * here once Dove is migrated to the pci-mvebu driver. The
+ * non-PCIe windows will no longer be created here once Dove
+ * fully moves to DT.
+ */
+ mvebu_mbus_add_window_remap_by_id(DOVE_MBUS_PCIE0_IO_TARGET,
+ DOVE_MBUS_PCIE0_IO_ATTR,
+ DOVE_PCIE0_IO_PHYS_BASE,
+ DOVE_PCIE0_IO_SIZE,
+ DOVE_PCIE0_IO_BUS_BASE);
+ mvebu_mbus_add_window_remap_by_id(DOVE_MBUS_PCIE1_IO_TARGET,
+ DOVE_MBUS_PCIE1_IO_ATTR,
+ DOVE_PCIE1_IO_PHYS_BASE,
+ DOVE_PCIE1_IO_SIZE,
+ DOVE_PCIE1_IO_BUS_BASE);
+ mvebu_mbus_add_window_by_id(DOVE_MBUS_PCIE0_MEM_TARGET,
+ DOVE_MBUS_PCIE0_MEM_ATTR,
+ DOVE_PCIE0_MEM_PHYS_BASE,
+ DOVE_PCIE0_MEM_SIZE);
+ mvebu_mbus_add_window_by_id(DOVE_MBUS_PCIE1_MEM_TARGET,
+ DOVE_MBUS_PCIE1_MEM_ATTR,
+ DOVE_PCIE1_MEM_PHYS_BASE,
+ DOVE_PCIE1_MEM_SIZE);
+ mvebu_mbus_add_window_by_id(DOVE_MBUS_CESA_TARGET,
+ DOVE_MBUS_CESA_ATTR,
+ DOVE_CESA_PHYS_BASE,
+ DOVE_CESA_SIZE);
+ mvebu_mbus_add_window_by_id(DOVE_MBUS_BOOTROM_TARGET,
+ DOVE_MBUS_BOOTROM_ATTR,
+ DOVE_BOOTROM_PHYS_BASE,
+ DOVE_BOOTROM_SIZE);
+ mvebu_mbus_add_window_by_id(DOVE_MBUS_SCRATCHPAD_TARGET,
+ DOVE_MBUS_SCRATCHPAD_ATTR,
+ DOVE_SCRATCHPAD_PHYS_BASE,
+ DOVE_SCRATCHPAD_SIZE);
+}
+
+void __init dove_init(void)
+{
+ pr_info("Dove 88AP510 SoC, TCLK = %d MHz.\n",
+ (dove_tclk + 499999) / 1000000);
+
+#ifdef CONFIG_CACHE_TAUROS2
+ tauros2_init(0);
+#endif
+ dove_setup_cpu_wins();
+
+ /* Setup root of clk tree */
+ dove_clk_init();
+
+ /* internal devices that every board has */
+ dove_rtc_init();
+ dove_xor0_init();
+ dove_xor1_init();
+}
+
+void dove_restart(enum reboot_mode 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)
+ ;
+}
diff --git a/arch/arm/mach-dove/common.h b/arch/arm/mach-dove/common.h
new file mode 100644
index 000000000..1d725224d
--- /dev/null
+++ b/arch/arm/mach-dove/common.h
@@ -0,0 +1,49 @@
+/*
+ * 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
+
+#include <linux/reboot.h>
+
+struct mv643xx_eth_platform_data;
+struct mv_sata_platform_data;
+
+extern void dove_timer_init(void);
+
+/*
+ * 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_wins(void);
+void dove_ge00_init(struct mv643xx_eth_platform_data *eth_data);
+void dove_sata_init(struct mv_sata_platform_data *sata_data);
+#ifdef CONFIG_PCI
+void dove_pcie_init(int init_port0, int init_port1);
+#else
+static inline void dove_pcie_init(int init_port0, int init_port1) { }
+#endif
+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);
+void dove_restart(enum reboot_mode, const char *);
+
+#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 000000000..76e26f949
--- /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/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")
+ .atag_offset = 0x100,
+ .init_machine = dove_db_init,
+ .map_io = dove_map_io,
+ .init_early = dove_init_early,
+ .init_irq = dove_init_irq,
+ .init_time = dove_timer_init,
+ .restart = dove_restart,
+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 000000000..f4a5b3448
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/bridge-regs.h
@@ -0,0 +1,57 @@
+/*
+ * 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 RSTOUTn_MASK_PHYS (BRIDGE_PHYS_BASE + 0x0108)
+#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 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)
+#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE + 0x0300)
+
+#endif
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 000000000..0c4b35f4e
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/dove.h
@@ -0,0 +1,190 @@
+/*
+ * 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
+
+/*
+ * 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 IOMEM(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 IOMEM(0xfdd00000)
+#define DOVE_SCRATCHPAD_SIZE SZ_1M
+
+#define DOVE_SB_REGS_PHYS_BASE 0xf1000000
+#define DOVE_SB_REGS_VIRT_BASE IOMEM(0xfde00000)
+#define DOVE_SB_REGS_SIZE SZ_8M
+
+#define DOVE_NB_REGS_PHYS_BASE 0xf1800000
+#define DOVE_NB_REGS_VIRT_BASE IOMEM(0xfe600000)
+#define DOVE_NB_REGS_SIZE SZ_8M
+
+#define DOVE_PCIE0_IO_PHYS_BASE 0xf2000000
+#define DOVE_PCIE0_IO_BUS_BASE 0x00000000
+#define DOVE_PCIE0_IO_SIZE SZ_64K
+
+#define DOVE_PCIE1_IO_PHYS_BASE 0xf2100000
+#define DOVE_PCIE1_IO_BUS_BASE 0x00010000
+#define DOVE_PCIE1_IO_SIZE SZ_64K
+
+/*
+ * 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)
+#define BRIDGE_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x20000)
+#define BRIDGE_WINS_BASE (BRIDGE_PHYS_BASE)
+#define BRIDGE_WINS_SZ (0x80)
+
+/* 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_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE + 0x00000)
+#define DOVE_MC_WINS_BASE (DOVE_MC_PHYS_BASE + 0x100)
+#define DOVE_MC_WINS_SZ (0x8)
+#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 000000000..72d622baa
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/entry-macro.S
@@ -0,0 +1,33 @@
+/*
+ * 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 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/hardware.h b/arch/arm/mach-dove/include/mach/hardware.h
new file mode 100644
index 000000000..f1368b9a8
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/hardware.h
@@ -0,0 +1,19 @@
+/*
+ * 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"
+
+/* 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/irqs.h b/arch/arm/mach-dove/include/mach/irqs.h
new file mode 100644
index 000000000..3f29e6bca
--- /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 (1 + 0)
+#define IRQ_DOVE_H2C (1 + 1)
+#define IRQ_DOVE_C2H (1 + 2)
+#define IRQ_DOVE_NAND (1 + 3)
+#define IRQ_DOVE_PDMA (1 + 4)
+#define IRQ_DOVE_SPI1 (1 + 5)
+#define IRQ_DOVE_SPI0 (1 + 6)
+#define IRQ_DOVE_UART_0 (1 + 7)
+#define IRQ_DOVE_UART_1 (1 + 8)
+#define IRQ_DOVE_UART_2 (1 + 9)
+#define IRQ_DOVE_UART_3 (1 + 10)
+#define IRQ_DOVE_I2C (1 + 11)
+#define IRQ_DOVE_GPIO_0_7 (1 + 12)
+#define IRQ_DOVE_GPIO_8_15 (1 + 13)
+#define IRQ_DOVE_GPIO_16_23 (1 + 14)
+#define IRQ_DOVE_PCIE0_ERR (1 + 15)
+#define IRQ_DOVE_PCIE0 (1 + 16)
+#define IRQ_DOVE_PCIE1_ERR (1 + 17)
+#define IRQ_DOVE_PCIE1 (1 + 18)
+#define IRQ_DOVE_I2S0 (1 + 19)
+#define IRQ_DOVE_I2S0_ERR (1 + 20)
+#define IRQ_DOVE_I2S1 (1 + 21)
+#define IRQ_DOVE_I2S1_ERR (1 + 22)
+#define IRQ_DOVE_USB_ERR (1 + 23)
+#define IRQ_DOVE_USB0 (1 + 24)
+#define IRQ_DOVE_USB1 (1 + 25)
+#define IRQ_DOVE_GE00_RX (1 + 26)
+#define IRQ_DOVE_GE00_TX (1 + 27)
+#define IRQ_DOVE_GE00_MISC (1 + 28)
+#define IRQ_DOVE_GE00_SUM (1 + 29)
+#define IRQ_DOVE_GE00_ERR (1 + 30)
+#define IRQ_DOVE_CRYPTO (1 + 31)
+
+/*
+ * Dove High Interrupt Controller
+ */
+#define IRQ_DOVE_AC97 (1 + 32)
+#define IRQ_DOVE_PMU (1 + 33)
+#define IRQ_DOVE_CAM (1 + 34)
+#define IRQ_DOVE_SDIO0 (1 + 35)
+#define IRQ_DOVE_SDIO1 (1 + 36)
+#define IRQ_DOVE_SDIO0_WAKEUP (1 + 37)
+#define IRQ_DOVE_SDIO1_WAKEUP (1 + 38)
+#define IRQ_DOVE_XOR_00 (1 + 39)
+#define IRQ_DOVE_XOR_01 (1 + 40)
+#define IRQ_DOVE_XOR0_ERR (1 + 41)
+#define IRQ_DOVE_XOR_10 (1 + 42)
+#define IRQ_DOVE_XOR_11 (1 + 43)
+#define IRQ_DOVE_XOR1_ERR (1 + 44)
+#define IRQ_DOVE_LCD_DCON (1 + 45)
+#define IRQ_DOVE_LCD1 (1 + 46)
+#define IRQ_DOVE_LCD0 (1 + 47)
+#define IRQ_DOVE_GPU (1 + 48)
+#define IRQ_DOVE_PERFORM_MNTR (1 + 49)
+#define IRQ_DOVE_VPRO_DMA1 (1 + 51)
+#define IRQ_DOVE_SSP_TIMER (1 + 54)
+#define IRQ_DOVE_SSP (1 + 55)
+#define IRQ_DOVE_MC_L2_ERR (1 + 56)
+#define IRQ_DOVE_CRYPTO_ERR (1 + 59)
+#define IRQ_DOVE_GPIO_24_31 (1 + 60)
+#define IRQ_DOVE_HIGH_GPIO (1 + 61)
+#define IRQ_DOVE_SATA (1 + 62)
+
+/*
+ * DOVE General Purpose Pins
+ */
+#define IRQ_DOVE_GPIO_START 65
+#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/pm.h b/arch/arm/mach-dove/include/mach/pm.h
new file mode 100644
index 000000000..b47f75038
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/pm.h
@@ -0,0 +1,72 @@
+/*
+ * 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_BIT_USB0 0
+#define CLOCK_GATING_BIT_USB1 1
+#define CLOCK_GATING_BIT_GBE 2
+#define CLOCK_GATING_BIT_SATA 3
+#define CLOCK_GATING_BIT_PCIE0 4
+#define CLOCK_GATING_BIT_PCIE1 5
+#define CLOCK_GATING_BIT_SDIO0 8
+#define CLOCK_GATING_BIT_SDIO1 9
+#define CLOCK_GATING_BIT_NAND 10
+#define CLOCK_GATING_BIT_CAMERA 11
+#define CLOCK_GATING_BIT_I2S0 12
+#define CLOCK_GATING_BIT_I2S1 13
+#define CLOCK_GATING_BIT_CRYPTO 15
+#define CLOCK_GATING_BIT_AC97 21
+#define CLOCK_GATING_BIT_PDMA 22
+#define CLOCK_GATING_BIT_XOR0 23
+#define CLOCK_GATING_BIT_XOR1 24
+#define CLOCK_GATING_BIT_GIGA_PHY 30
+#define CLOCK_GATING_USB0_MASK (1 << CLOCK_GATING_BIT_USB0)
+#define CLOCK_GATING_USB1_MASK (1 << CLOCK_GATING_BIT_USB1)
+#define CLOCK_GATING_GBE_MASK (1 << CLOCK_GATING_BIT_GBE)
+#define CLOCK_GATING_SATA_MASK (1 << CLOCK_GATING_BIT_SATA)
+#define CLOCK_GATING_PCIE0_MASK (1 << CLOCK_GATING_BIT_PCIE0)
+#define CLOCK_GATING_PCIE1_MASK (1 << CLOCK_GATING_BIT_PCIE1)
+#define CLOCK_GATING_SDIO0_MASK (1 << CLOCK_GATING_BIT_SDIO0)
+#define CLOCK_GATING_SDIO1_MASK (1 << CLOCK_GATING_BIT_SDIO1)
+#define CLOCK_GATING_NAND_MASK (1 << CLOCK_GATING_BIT_NAND)
+#define CLOCK_GATING_CAMERA_MASK (1 << CLOCK_GATING_BIT_CAMERA)
+#define CLOCK_GATING_I2S0_MASK (1 << CLOCK_GATING_BIT_I2S0)
+#define CLOCK_GATING_I2S1_MASK (1 << CLOCK_GATING_BIT_I2S1)
+#define CLOCK_GATING_CRYPTO_MASK (1 << CLOCK_GATING_BIT_CRYPTO)
+#define CLOCK_GATING_AC97_MASK (1 << CLOCK_GATING_BIT_AC97)
+#define CLOCK_GATING_PDMA_MASK (1 << CLOCK_GATING_BIT_PDMA)
+#define CLOCK_GATING_XOR0_MASK (1 << CLOCK_GATING_BIT_XOR0)
+#define CLOCK_GATING_XOR1_MASK (1 << CLOCK_GATING_BIT_XOR1)
+#define CLOCK_GATING_GIGA_PHY_MASK (1 << CLOCK_GATING_BIT_GIGA_PHY)
+
+#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/uncompress.h b/arch/arm/mach-dove/include/mach/uncompress.h
new file mode 100644
index 000000000..5c8ae9b9d
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/uncompress.h
@@ -0,0 +1,36 @@
+/*
+ * 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()
diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c
new file mode 100644
index 000000000..df0223f76
--- /dev/null
+++ b/arch/arm/mach-dove/irq.c
@@ -0,0 +1,178 @@
+/*
+ * 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 <plat/orion-gpio.h>
+#include "common.h"
+
+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;
+
+ /*
+ * The PMU mask register is not RW0C: it is RW. This means that
+ * the bits take whatever value is written to them; if you write
+ * a '1', you will set the interrupt.
+ *
+ * Unfortunately this means there is NO race free way to clear
+ * these interrupts.
+ *
+ * So, let's structure the code so that the window is as small as
+ * possible.
+ */
+ u = ~(1 << (pin & 31));
+ u &= readl_relaxed(PMU_INTERRUPT_CAUSE);
+ writel_relaxed(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);
+ }
+}
+
+static int __initdata gpio0_irqs[4] = {
+ IRQ_DOVE_GPIO_0_7,
+ IRQ_DOVE_GPIO_8_15,
+ IRQ_DOVE_GPIO_16_23,
+ IRQ_DOVE_GPIO_24_31,
+};
+
+static int __initdata gpio1_irqs[4] = {
+ IRQ_DOVE_HIGH_GPIO,
+ 0,
+ 0,
+ 0,
+};
+
+static int __initdata gpio2_irqs[4] = {
+ 0,
+ 0,
+ 0,
+ 0,
+};
+
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+/*
+ * Compiling with both non-DT and DT support enabled, will
+ * break asm irq handler used by non-DT boards. Therefore,
+ * we provide a C-style irq handler even for non-DT boards,
+ * if MULTI_IRQ_HANDLER is set.
+ */
+
+static void __iomem *dove_irq_base = IRQ_VIRT_BASE;
+
+static asmlinkage void
+__exception_irq_entry dove_legacy_handle_irq(struct pt_regs *regs)
+{
+ u32 stat;
+
+ stat = readl_relaxed(dove_irq_base + IRQ_CAUSE_LOW_OFF);
+ stat &= readl_relaxed(dove_irq_base + IRQ_MASK_LOW_OFF);
+ if (stat) {
+ unsigned int hwirq = 1 + __fls(stat);
+ handle_IRQ(hwirq, regs);
+ return;
+ }
+ stat = readl_relaxed(dove_irq_base + IRQ_CAUSE_HIGH_OFF);
+ stat &= readl_relaxed(dove_irq_base + IRQ_MASK_HIGH_OFF);
+ if (stat) {
+ unsigned int hwirq = 33 + __fls(stat);
+ handle_IRQ(hwirq, regs);
+ return;
+ }
+}
+#endif
+
+void __init dove_init_irq(void)
+{
+ int i;
+
+ orion_irq_init(1, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF);
+ orion_irq_init(33, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF);
+
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+ set_handle_irq(dove_legacy_handle_irq);
+#endif
+
+ /*
+ * Initialize gpiolib for GPIOs 0-71.
+ */
+ orion_gpio_init(NULL, 0, 32, DOVE_GPIO_LO_VIRT_BASE, 0,
+ IRQ_DOVE_GPIO_START, gpio0_irqs);
+
+ orion_gpio_init(NULL, 32, 32, DOVE_GPIO_HI_VIRT_BASE, 0,
+ IRQ_DOVE_GPIO_START + 32, gpio1_irqs);
+
+ orion_gpio_init(NULL, 64, 8, DOVE_GPIO2_VIRT_BASE, 0,
+ IRQ_DOVE_GPIO_START + 64, gpio2_irqs);
+
+ /*
+ * 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 000000000..8a433a512
--- /dev/null
+++ b/arch/arm/mach-dove/mpp.c
@@ -0,0 +1,162 @@
+/*
+ * 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 <plat/orion-gpio.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 __init 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 __init 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 __init 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 __init 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 __init 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 000000000..fbec7c52b
--- /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 000000000..91fe97144
--- /dev/null
+++ b/arch/arm/mach-dove/pcie.c
@@ -0,0 +1,216 @@
+/*
+ * 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/clk.h>
+#include <video/vga.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 <plat/addr-map.h>
+#include "common.h"
+
+struct pcie_port {
+ u8 index;
+ u8 root_bus_nr;
+ void __iomem *base;
+ spinlock_t conf_lock;
+ char mem_space_name[16];
+ struct resource res;
+};
+
+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];
+ sys->private_data = pp;
+ 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);
+
+ if (pp->index == 0)
+ pci_ioremap_io(sys->busnr * SZ_64K, DOVE_PCIE0_IO_PHYS_BASE);
+ else
+ pci_ioremap_io(sys->busnr * SZ_64K, DOVE_PCIE1_IO_PHYS_BASE);
+
+ /*
+ * 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.name = pp->mem_space_name;
+ if (pp->index == 0) {
+ pp->res.start = DOVE_PCIE0_MEM_PHYS_BASE;
+ pp->res.end = pp->res.start + DOVE_PCIE0_MEM_SIZE - 1;
+ } else {
+ pp->res.start = DOVE_PCIE1_MEM_PHYS_BASE;
+ pp->res.end = pp->res.start + DOVE_PCIE1_MEM_SIZE - 1;
+ }
+ pp->res.flags = IORESOURCE_MEM;
+ if (request_resource(&iomem_resource, &pp->res))
+ panic("Request PCIe Memory resource failed\n");
+ pci_add_resource_offset(&sys->resources, &pp->res, sys->mem_offset);
+
+ return 1;
+}
+
+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 pci_sys_data *sys = bus->sysdata;
+ struct pcie_port *pp = sys->private_data;
+ 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 pci_sys_data *sys = bus->sysdata;
+ struct pcie_port *pp = sys->private_data;
+ 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 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)
+{
+ if (nr >= num_pcie_ports) {
+ BUG();
+ return NULL;
+ }
+
+ return pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys,
+ &sys->resources);
+}
+
+static int __init dove_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ struct pci_sys_data *sys = dev->sysdata;
+ struct pcie_port *pp = sys->private_data;
+
+ return pp->index ? IRQ_DOVE_PCIE1 : IRQ_DOVE_PCIE0;
+}
+
+static struct hw_pci dove_pci __initdata = {
+ .nr_controllers = 2,
+ .setup = dove_pcie_setup,
+ .scan = dove_pcie_scan_bus,
+ .map_irq = dove_pcie_map_irq,
+};
+
+static void __init add_pcie_port(int index, void __iomem *base)
+{
+ printk(KERN_INFO "Dove PCIe port %d: ", index);
+
+ if (orion_pcie_link_up(base)) {
+ struct pcie_port *pp = &pcie_port[num_pcie_ports++];
+ struct clk *clk = clk_get_sys("pcie", (index ? "1" : "0"));
+
+ if (!IS_ERR(clk))
+ clk_prepare_enable(clk);
+
+ printk(KERN_INFO "link up\n");
+
+ pp->index = index;
+ pp->root_bus_nr = -1;
+ pp->base = 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)
+{
+ vga_base = DOVE_PCIE0_MEM_PHYS_BASE;
+
+ 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 000000000..a7d68c13c
--- /dev/null
+++ b/arch/arm/mach-ebsa110/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := core.o io.o leds.o
diff --git a/arch/arm/mach-ebsa110/Makefile.boot b/arch/arm/mach-ebsa110/Makefile.boot
new file mode 100644
index 000000000..83cf07c38
--- /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 000000000..8254e716b
--- /dev/null
+++ b/arch/arm/mach-ebsa110/core.c
@@ -0,0 +1,329 @@
+/*
+ * 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_misc.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+
+#include <asm/mach/time.h>
+
+#include "core.h"
+
+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 = (unsigned long)IRQ_STAT,
+ .pfn = __phys_to_pfn(TRICK4_PHYS),
+ .length = TRICK4_SIZE,
+ .type = MT_DEVICE
+ }, { /* IRQ_MASK/IRQ_MSET */
+ .virtual = (unsigned long)IRQ_MASK,
+ .pfn = __phys_to_pfn(TRICK3_PHYS),
+ .length = TRICK3_SIZE,
+ .type = MT_DEVICE
+ }, { /* SOFT_BASE */
+ .virtual = (unsigned long)SOFT_BASE,
+ .pfn = __phys_to_pfn(TRICK1_PHYS),
+ .length = TRICK1_SIZE,
+ .type = MT_DEVICE
+ }, { /* PIT_BASE */
+ .virtual = (unsigned long)PIT_BASE,
+ .pfn = __phys_to_pfn(TRICK0_PHYS),
+ .length = TRICK0_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));
+}
+
+static void __iomem *ebsa110_ioremap_caller(phys_addr_t cookie, size_t size,
+ unsigned int flags, void *caller)
+{
+ return (void __iomem *)cookie;
+}
+
+static void ebsa110_iounmap(volatile void __iomem *io_addr)
+{}
+
+static void __init ebsa110_init_early(void)
+{
+ arch_ioremap_caller = ebsa110_ioremap_caller;
+ arch_iounmap = ebsa110_iounmap;
+}
+
+#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 u32 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 * 1000;
+}
+
+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_TIMER | IRQF_IRQPOLL,
+ .handler = ebsa110_timer_interrupt,
+};
+
+/*
+ * Set up timer interrupt.
+ */
+void __init ebsa110_timer_init(void)
+{
+ arch_gettimeoffset = ebsa110_gettimeoffset;
+
+ /*
+ * 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 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,
+};
+
+/*
+ * 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 void ebsa110_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");
+}
+
+static int __init ebsa110_init(void)
+{
+ arm_pm_idle = ebsa110_idle;
+ return platform_add_devices(ebsa110_devices, ARRAY_SIZE(ebsa110_devices));
+}
+
+arch_initcall(ebsa110_init);
+
+static void ebsa110_restart(enum reboot_mode mode, const char *cmd)
+{
+ soft_restart(0x80000000);
+}
+
+MACHINE_START(EBSA110, "EBSA110")
+ /* Maintainer: Russell King */
+ .atag_offset = 0x400,
+ .reserve_lp0 = 1,
+ .reserve_lp2 = 1,
+ .map_io = ebsa110_map_io,
+ .init_early = ebsa110_init_early,
+ .init_irq = ebsa110_init_irq,
+ .init_time = ebsa110_timer_init,
+ .restart = ebsa110_restart,
+MACHINE_END
diff --git a/arch/arm/mach-ebsa110/core.h b/arch/arm/mach-ebsa110/core.h
new file mode 100644
index 000000000..afe137ee1
--- /dev/null
+++ b/arch/arm/mach-ebsa110/core.h
@@ -0,0 +1,41 @@
+/*
+ * 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 core hardware definitions of the EBSA-110.
+ */
+#ifndef CORE_H
+#define CORE_H
+
+/* Physical addresses/sizes */
+#define ISAMEM_PHYS 0xe0000000
+#define ISAMEM_SIZE 0x10000000
+
+#define ISAIO_PHYS 0xf0000000
+#define ISAIO_SIZE PGDIR_SIZE
+
+#define TRICK0_PHYS 0xf2000000
+#define TRICK0_SIZE PGDIR_SIZE
+#define TRICK1_PHYS 0xf2400000
+#define TRICK1_SIZE PGDIR_SIZE
+#define TRICK2_PHYS 0xf2800000
+#define TRICK3_PHYS 0xf2c00000
+#define TRICK3_SIZE PGDIR_SIZE
+#define TRICK4_PHYS 0xf3000000
+#define TRICK4_SIZE PGDIR_SIZE
+#define TRICK5_PHYS 0xf3400000
+#define TRICK6_PHYS 0xf3800000
+#define TRICK7_PHYS 0xf3c00000
+
+/* Virtual addresses */
+#define PIT_BASE IOMEM(0xfc000000) /* trick 0 */
+#define SOFT_BASE IOMEM(0xfd000000) /* trick 1 */
+#define IRQ_MASK IOMEM(0xfe000000) /* trick 3 - read */
+#define IRQ_MSET IOMEM(0xfe000000) /* trick 3 - write */
+#define IRQ_STAT IOMEM(0xff000000) /* trick 4 - read */
+#define IRQ_MCLR IOMEM(0xff000000) /* trick 4 - write */
+
+#endif
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 000000000..14b110de7
--- /dev/null
+++ b/arch/arm/mach-ebsa110/include/mach/entry-macro.S
@@ -0,0 +1,33 @@
+/*
+ * 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 get_irqnr_preamble, base, tmp
+ mov \base, #IRQ_STAT
+ .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 000000000..f4e5407bd
--- /dev/null
+++ b/arch/arm/mach-ebsa110/include/mach/hardware.h
@@ -0,0 +1,24 @@
+/*
+ * 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
+
+#define ISAMEM_BASE 0xe0000000
+#define ISAIO_BASE 0xf0000000
+
+/*
+ * 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 000000000..69975784a
--- /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
+
+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, volatile void __iomem *addr);
+void __writew(u16 val, volatile void __iomem *addr);
+void __writel(u32 val, volatile 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)
+
+#define insb insb
+extern void insb(unsigned int port, void *buf, int sz);
+#define insw insw
+extern void insw(unsigned int port, void *buf, int sz);
+#define insl insl
+extern void insl(unsigned int port, void *buf, int sz);
+
+#define outsb outsb
+extern void outsb(unsigned int port, const void *buf, int sz);
+#define outsw outsw
+extern void outsw(unsigned int port, const void *buf, int sz);
+#define outsl outsl
+extern void outsl(unsigned int port, const void *buf, int sz);
+
+/* can't support writesb atm */
+#define writesw writesw
+extern void writesw(volatile void __iomem *addr, const void *data, int wordlen);
+#define writesl writesl
+extern void writesl(volatile void __iomem *addr, const void *data, int longlen);
+
+/* can't support readsb atm */
+#define readsw readsw
+extern void readsw(const volatile void __iomem *addr, void *data, int wordlen);
+
+#define readsl readsl
+extern void readsl(const volatile 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 000000000..a8f3771bc
--- /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 000000000..866f8a1c6
--- /dev/null
+++ b/arch/arm/mach-ebsa110/include/mach/memory.h
@@ -0,0 +1,25 @@
+/*
+ * 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
+
+/*
+ * Cache flushing area - SRAM
+ */
+#define FLUSH_BASE_PHYS 0x40000000
+#define FLUSH_BASE 0xdf000000
+
+#endif
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 000000000..ab64bea69
--- /dev/null
+++ b/arch/arm/mach-ebsa110/include/mach/uncompress.h
@@ -0,0 +1,44 @@
+/*
+ * 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()
diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c
new file mode 100644
index 000000000..b57980b43
--- /dev/null
+++ b/arch/arm/mach-ebsa110/io.c
@@ -0,0 +1,439 @@
+/*
+ * 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 volatile 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 volatile 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, volatile 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, volatile void __iomem *addr)
+{
+ void __iomem *a = __isamem_convert_addr(addr);
+
+ if ((unsigned long)addr & 1)
+ BUG();
+
+ __raw_writew(val, a);
+}
+
+void __writel(u32 val, volatile 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(volatile 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(volatile 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);
+
+/*
+ * 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 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 000000000..0398258c2
--- /dev/null
+++ b/arch/arm/mach-ebsa110/leds.c
@@ -0,0 +1,71 @@
+/*
+ * Driver for the LED found on the EBSA110 machine
+ * Based on Versatile and RealView machine LED code
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ * Author: Bryan Wu <bryan.wu@canonical.com>
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
+
+#include <asm/mach-types.h>
+
+#include "core.h"
+
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+static void ebsa110_led_set(struct led_classdev *cdev,
+ enum led_brightness b)
+{
+ u8 reg = __raw_readb(SOFT_BASE);
+
+ if (b != LED_OFF)
+ reg |= 0x80;
+ else
+ reg &= ~0x80;
+
+ __raw_writeb(reg, SOFT_BASE);
+}
+
+static enum led_brightness ebsa110_led_get(struct led_classdev *cdev)
+{
+ u8 reg = __raw_readb(SOFT_BASE);
+
+ return (reg & 0x80) ? LED_FULL : LED_OFF;
+}
+
+static int __init ebsa110_leds_init(void)
+{
+
+ struct led_classdev *cdev;
+ int ret;
+
+ if (!machine_is_ebsa110())
+ return -ENODEV;
+
+ cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
+ if (!cdev)
+ return -ENOMEM;
+
+ cdev->name = "ebsa110:0";
+ cdev->brightness_set = ebsa110_led_set;
+ cdev->brightness_get = ebsa110_led_get;
+ cdev->default_trigger = "heartbeat";
+
+ ret = led_classdev_register(NULL, cdev);
+ if (ret < 0) {
+ kfree(cdev);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * Since we may have triggers on any subsystem, defer registration
+ * until after subsystem_init.
+ */
+fs_initcall(ebsa110_leds_init);
+#endif
diff --git a/arch/arm/mach-efm32/Makefile b/arch/arm/mach-efm32/Makefile
new file mode 100644
index 000000000..3a74af741
--- /dev/null
+++ b/arch/arm/mach-efm32/Makefile
@@ -0,0 +1 @@
+obj-y += dtmachine.o
diff --git a/arch/arm/mach-efm32/Makefile.boot b/arch/arm/mach-efm32/Makefile.boot
new file mode 100644
index 000000000..eacfc3f5c
--- /dev/null
+++ b/arch/arm/mach-efm32/Makefile.boot
@@ -0,0 +1,3 @@
+# Empty file waiting for deletion once Makefile.boot isn't needed any more.
+# Patch waits for application at
+# http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7889/1 .
diff --git a/arch/arm/mach-efm32/dtmachine.c b/arch/arm/mach-efm32/dtmachine.c
new file mode 100644
index 000000000..236749519
--- /dev/null
+++ b/arch/arm/mach-efm32/dtmachine.c
@@ -0,0 +1,15 @@
+#include <linux/kernel.h>
+
+#include <asm/v7m.h>
+
+#include <asm/mach/arch.h>
+
+static const char *const efm32gg_compat[] __initconst = {
+ "efm32,dk3750",
+ NULL
+};
+
+DT_MACHINE_START(EFM32DT, "EFM32 (Device Tree Support)")
+ .dt_compat = efm32gg_compat,
+ .restart = armv7m_restart,
+MACHINE_END
diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig
new file mode 100644
index 000000000..bec570ae6
--- /dev/null
+++ b/arch/arm/mach-ep93xx/Kconfig
@@ -0,0 +1,200 @@
+if ARCH_EP93XX
+
+menu "Cirrus EP93xx Implementation Options"
+
+config EP93XX_SOC_COMMON
+ bool
+ default y
+ select SOC_BUS
+ select LEDS_GPIO_REGISTER
+
+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.
+
+config MACH_VISION_EP9307
+ bool "Support Vision Engraving Systems EP9307 SoM"
+ depends on EP93XX_SDCE0_PHYS_OFFSET
+ help
+ Say 'Y' here if you want your kernel to support the
+ Vision Engraving Systems EP9307 SoM.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile
new file mode 100644
index 000000000..78d427b34
--- /dev/null
+++ b/arch/arm/mach-ep93xx/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for the linux kernel.
+#
+obj-y := core.o clock.o
+
+obj-$(CONFIG_EP93XX_DMA) += dma.o
+
+obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
+AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
+
+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
+obj-$(CONFIG_MACH_VISION_EP9307)+= vision_ep9307.o
diff --git a/arch/arm/mach-ep93xx/Makefile.boot b/arch/arm/mach-ep93xx/Makefile.boot
new file mode 100644
index 000000000..d3113a71c
--- /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 000000000..bda6c3a5c
--- /dev/null
+++ b/arch/arm/mach-ep93xx/adssphere.c
@@ -0,0 +1,45 @@
+/*
+ * 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 <linux/sizes.h>
+
+#include <mach/hardware.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "soc.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> */
+ .atag_offset = 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = adssphere_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
new file mode 100644
index 000000000..39ef3b613
--- /dev/null
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -0,0 +1,563 @@
+/*
+ * 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>
+
+#include "soc.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("ohci-platform", 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 000000000..0e571f174
--- /dev/null
+++ b/arch/arm/mach-ep93xx/core.c
@@ -0,0 +1,1076 @@
+/*
+ * 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/sys_soc.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 <linux/export.h>
+#include <linux/irqchip/arm-vic.h>
+#include <linux/reboot.h>
+#include <linux/usb/ohci_pdriver.h>
+
+#include <mach/hardware.h>
+#include <linux/platform_data/video-ep93xx.h>
+#include <linux/platform_data/keypad-ep93xx.h>
+#include <linux/platform_data/spi-ep93xx.h>
+#include <mach/gpio-ep93xx.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include "soc.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(EP93XX_TIMER4_CLOCK, 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_TIMER | IRQF_IRQPOLL,
+ .handler = ep93xx_timer_interrupt,
+};
+
+static u32 ep93xx_gettimeoffset(void)
+{
+ int offset;
+
+ offset = __raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time;
+
+ /*
+ * Timer 4 is based on a 983.04 kHz reference clock,
+ * so dividing by 983040 gives the fraction of a second,
+ * so dividing by 0.983040 converts to uS.
+ * Refactor the calculation to avoid overflow.
+ * Finally, multiply by 1000 to give nS.
+ */
+ return (offset + (53 * offset / 3072)) * 1000;
+}
+
+void __init ep93xx_timer_init(void)
+{
+ u32 tmode = EP93XX_TIMER123_CONTROL_MODE |
+ EP93XX_TIMER123_CONTROL_CLKSEL;
+
+ arch_gettimeoffset = ep93xx_gettimeoffset;
+
+ /* 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);
+}
+
+
+/*************************************************************************
+ * EP93xx IRQ handling
+ *************************************************************************/
+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 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);
+}
+
+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);
+}
+
+/**
+ * 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;
+}
+EXPORT_SYMBOL_GPL(ep93xx_chip_revision);
+
+/*************************************************************************
+ * EP93xx GPIO
+ *************************************************************************/
+static struct resource ep93xx_gpio_resource[] = {
+ DEFINE_RES_MEM(EP93XX_GPIO_PHYS_BASE, 0xcc),
+};
+
+static struct platform_device ep93xx_gpio_device = {
+ .name = "gpio-ep93xx",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ep93xx_gpio_resource),
+ .resource = ep93xx_gpio_resource,
+};
+
+/*************************************************************************
+ * 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 AMBA_APB_DEVICE(uart1, "apb:uart1", 0x00041010, EP93XX_UART1_PHYS_BASE,
+ { IRQ_EP93XX_UART1 }, &ep93xx_uart_data);
+
+static AMBA_APB_DEVICE(uart2, "apb:uart2", 0x00041010, EP93XX_UART2_PHYS_BASE,
+ { IRQ_EP93XX_UART2 }, NULL);
+
+static AMBA_APB_DEVICE(uart3, "apb:uart3", 0x00041010, EP93XX_UART3_PHYS_BASE,
+ { IRQ_EP93XX_UART3 }, &ep93xx_uart_data);
+
+static struct resource ep93xx_rtc_resource[] = {
+ DEFINE_RES_MEM(EP93XX_RTC_PHYS_BASE, 0x10c),
+};
+
+static struct platform_device ep93xx_rtc_device = {
+ .name = "ep93xx-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ep93xx_rtc_resource),
+ .resource = ep93xx_rtc_resource,
+};
+
+/*************************************************************************
+ * EP93xx OHCI USB Host
+ *************************************************************************/
+
+static struct clk *ep93xx_ohci_host_clock;
+
+static int ep93xx_ohci_power_on(struct platform_device *pdev)
+{
+ if (!ep93xx_ohci_host_clock) {
+ ep93xx_ohci_host_clock = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(ep93xx_ohci_host_clock))
+ return PTR_ERR(ep93xx_ohci_host_clock);
+ }
+
+ return clk_enable(ep93xx_ohci_host_clock);
+}
+
+static void ep93xx_ohci_power_off(struct platform_device *pdev)
+{
+ clk_disable(ep93xx_ohci_host_clock);
+}
+
+static struct usb_ohci_pdata ep93xx_ohci_pdata = {
+ .power_on = ep93xx_ohci_power_on,
+ .power_off = ep93xx_ohci_power_off,
+ .power_suspend = ep93xx_ohci_power_off,
+};
+
+static struct resource ep93xx_ohci_resources[] = {
+ DEFINE_RES_MEM(EP93XX_USB_PHYS_BASE, 0x1000),
+ DEFINE_RES_IRQ(IRQ_EP93XX_USB),
+};
+
+static u64 ep93xx_ohci_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device ep93xx_ohci_device = {
+ .name = "ohci-platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ep93xx_ohci_resources),
+ .resource = ep93xx_ohci_resources,
+ .dev = {
+ .dma_mask = &ep93xx_ohci_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &ep93xx_ohci_pdata,
+ },
+};
+
+/*************************************************************************
+ * 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[] = {
+ DEFINE_RES_MEM(EP93XX_ETHERNET_PHYS_BASE, 0x10000),
+ DEFINE_RES_IRQ(IRQ_EP93XX_ETHERNET),
+};
+
+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[] = {
+ DEFINE_RES_MEM(EP93XX_SPI_PHYS_BASE, 0x18),
+ DEFINE_RES_IRQ(IRQ_EP93XX_SSP),
+};
+
+static u64 ep93xx_spi_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device ep93xx_spi_device = {
+ .name = "ep93xx-spi",
+ .id = 0,
+ .dev = {
+ .platform_data = &ep93xx_spi_master_data,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .dma_mask = &ep93xx_spi_dma_mask,
+ },
+ .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 const struct gpio_led ep93xx_led_pins[] __initconst = {
+ {
+ .name = "platform:grled",
+ .gpio = EP93XX_GPIO_LINE_GRLED,
+ }, {
+ .name = "platform:rdled",
+ .gpio = EP93XX_GPIO_LINE_RDLED,
+ },
+};
+
+static const struct gpio_led_platform_data ep93xx_led_data __initconst = {
+ .num_leds = ARRAY_SIZE(ep93xx_led_pins),
+ .leds = ep93xx_led_pins,
+};
+
+/*************************************************************************
+ * EP93xx pwm peripheral handling
+ *************************************************************************/
+static struct resource ep93xx_pwm0_resource[] = {
+ DEFINE_RES_MEM(EP93XX_PWM_PHYS_BASE, 0x10),
+};
+
+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[] = {
+ DEFINE_RES_MEM(EP93XX_PWM_PHYS_BASE + 0x20, 0x10),
+};
+
+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[] = {
+ DEFINE_RES_MEM(EP93XX_RASTER_PHYS_BASE, 0x800),
+};
+
+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,
+};
+
+/* The backlight use a single register in the framebuffer's register space */
+#define EP93XX_RASTER_REG_BRIGHTNESS 0x20
+
+static struct resource ep93xx_bl_resources[] = {
+ DEFINE_RES_MEM(EP93XX_RASTER_PHYS_BASE +
+ EP93XX_RASTER_REG_BRIGHTNESS, 0x04),
+};
+
+static struct platform_device ep93xx_bl_device = {
+ .name = "ep93xx-bl",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ep93xx_bl_resources),
+ .resource = ep93xx_bl_resources,
+};
+
+/**
+ * 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[] = {
+ DEFINE_RES_MEM(EP93XX_KEY_MATRIX_PHYS_BASE, 0x0c),
+ DEFINE_RES_IRQ(IRQ_EP93XX_KEY),
+};
+
+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; 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[] = {
+ DEFINE_RES_MEM(EP93XX_I2S_PHYS_BASE, 0x100),
+};
+
+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(void)
+{
+ unsigned val;
+
+ ep93xx_devcfg_set_clear(EP93XX_SYSCON_DEVCFG_I2SONAC97,
+ EP93XX_SYSCON_DEVCFG_I2S_MASK);
+
+ /*
+ * 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 |= EP93XX_SYSCON_I2SCLKDIV_ORIDE | EP93XX_SYSCON_I2SCLKDIV_SPOL;
+ 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[] = {
+ DEFINE_RES_MEM(EP93XX_AAC_PHYS_BASE, 0xac),
+ DEFINE_RES_IRQ(IRQ_EP93XX_AACINTR),
+};
+
+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);
+}
+
+/*************************************************************************
+ * EP93xx Watchdog
+ *************************************************************************/
+static struct resource ep93xx_wdt_resources[] = {
+ DEFINE_RES_MEM(EP93XX_WATCHDOG_PHYS_BASE, 0x08),
+};
+
+static struct platform_device ep93xx_wdt_device = {
+ .name = "ep93xx-wdt",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ep93xx_wdt_resources),
+ .resource = ep93xx_wdt_resources,
+};
+
+/*************************************************************************
+ * EP93xx IDE
+ *************************************************************************/
+static struct resource ep93xx_ide_resources[] = {
+ DEFINE_RES_MEM(EP93XX_IDE_PHYS_BASE, 0x38),
+ DEFINE_RES_IRQ(IRQ_EP93XX_EXT3),
+};
+
+static struct platform_device ep93xx_ide_device = {
+ .name = "ep93xx-ide",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ep93xx_ide_device.dev.coherent_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(ep93xx_ide_resources),
+ .resource = ep93xx_ide_resources,
+};
+
+void __init ep93xx_register_ide(void)
+{
+ platform_device_register(&ep93xx_ide_device);
+}
+
+int ep93xx_ide_acquire_gpio(struct platform_device *pdev)
+{
+ int err;
+ int i;
+
+ err = gpio_request(EP93XX_GPIO_LINE_EGPIO2, dev_name(&pdev->dev));
+ if (err)
+ return err;
+ err = gpio_request(EP93XX_GPIO_LINE_EGPIO15, dev_name(&pdev->dev));
+ if (err)
+ goto fail_egpio15;
+ for (i = 2; i < 8; i++) {
+ err = gpio_request(EP93XX_GPIO_LINE_E(i), dev_name(&pdev->dev));
+ if (err)
+ goto fail_gpio_e;
+ }
+ for (i = 4; i < 8; i++) {
+ err = gpio_request(EP93XX_GPIO_LINE_G(i), dev_name(&pdev->dev));
+ if (err)
+ goto fail_gpio_g;
+ }
+ for (i = 0; i < 8; i++) {
+ err = gpio_request(EP93XX_GPIO_LINE_H(i), dev_name(&pdev->dev));
+ if (err)
+ goto fail_gpio_h;
+ }
+
+ /* GPIO ports E[7:2], G[7:4] and H used by IDE */
+ ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_EONIDE |
+ EP93XX_SYSCON_DEVCFG_GONIDE |
+ EP93XX_SYSCON_DEVCFG_HONIDE);
+ return 0;
+
+fail_gpio_h:
+ for (--i; i >= 0; --i)
+ gpio_free(EP93XX_GPIO_LINE_H(i));
+ i = 8;
+fail_gpio_g:
+ for (--i; i >= 4; --i)
+ gpio_free(EP93XX_GPIO_LINE_G(i));
+ i = 8;
+fail_gpio_e:
+ for (--i; i >= 2; --i)
+ gpio_free(EP93XX_GPIO_LINE_E(i));
+ gpio_free(EP93XX_GPIO_LINE_EGPIO15);
+fail_egpio15:
+ gpio_free(EP93XX_GPIO_LINE_EGPIO2);
+ return err;
+}
+EXPORT_SYMBOL(ep93xx_ide_acquire_gpio);
+
+void ep93xx_ide_release_gpio(struct platform_device *pdev)
+{
+ int i;
+
+ for (i = 2; i < 8; i++)
+ gpio_free(EP93XX_GPIO_LINE_E(i));
+ for (i = 4; i < 8; i++)
+ gpio_free(EP93XX_GPIO_LINE_G(i));
+ for (i = 0; i < 8; i++)
+ gpio_free(EP93XX_GPIO_LINE_H(i));
+ gpio_free(EP93XX_GPIO_LINE_EGPIO15);
+ gpio_free(EP93XX_GPIO_LINE_EGPIO2);
+
+
+ /* GPIO ports E[7:2], G[7:4] and H used by GPIO */
+ ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_EONIDE |
+ EP93XX_SYSCON_DEVCFG_GONIDE |
+ EP93XX_SYSCON_DEVCFG_HONIDE);
+}
+EXPORT_SYMBOL(ep93xx_ide_release_gpio);
+
+/*************************************************************************
+ * EP93xx Security peripheral
+ *************************************************************************/
+
+/*
+ * The Maverick Key is 256 bits of micro fuses blown at the factory during
+ * manufacturing to uniquely identify a part.
+ *
+ * See: http://arm.cirrus.com/forum/viewtopic.php?t=486&highlight=maverick+key
+ */
+#define EP93XX_SECURITY_REG(x) (EP93XX_SECURITY_BASE + (x))
+#define EP93XX_SECURITY_SECFLG EP93XX_SECURITY_REG(0x2400)
+#define EP93XX_SECURITY_FUSEFLG EP93XX_SECURITY_REG(0x2410)
+#define EP93XX_SECURITY_UNIQID EP93XX_SECURITY_REG(0x2440)
+#define EP93XX_SECURITY_UNIQCHK EP93XX_SECURITY_REG(0x2450)
+#define EP93XX_SECURITY_UNIQVAL EP93XX_SECURITY_REG(0x2460)
+#define EP93XX_SECURITY_SECID1 EP93XX_SECURITY_REG(0x2500)
+#define EP93XX_SECURITY_SECID2 EP93XX_SECURITY_REG(0x2504)
+#define EP93XX_SECURITY_SECCHK1 EP93XX_SECURITY_REG(0x2520)
+#define EP93XX_SECURITY_SECCHK2 EP93XX_SECURITY_REG(0x2524)
+#define EP93XX_SECURITY_UNIQID2 EP93XX_SECURITY_REG(0x2700)
+#define EP93XX_SECURITY_UNIQID3 EP93XX_SECURITY_REG(0x2704)
+#define EP93XX_SECURITY_UNIQID4 EP93XX_SECURITY_REG(0x2708)
+#define EP93XX_SECURITY_UNIQID5 EP93XX_SECURITY_REG(0x270c)
+
+static char ep93xx_soc_id[33];
+
+static const char __init *ep93xx_get_soc_id(void)
+{
+ unsigned int id, id2, id3, id4, id5;
+
+ if (__raw_readl(EP93XX_SECURITY_UNIQVAL) != 1)
+ return "bad Hamming code";
+
+ id = __raw_readl(EP93XX_SECURITY_UNIQID);
+ id2 = __raw_readl(EP93XX_SECURITY_UNIQID2);
+ id3 = __raw_readl(EP93XX_SECURITY_UNIQID3);
+ id4 = __raw_readl(EP93XX_SECURITY_UNIQID4);
+ id5 = __raw_readl(EP93XX_SECURITY_UNIQID5);
+
+ if (id != id2)
+ return "invalid";
+
+ snprintf(ep93xx_soc_id, sizeof(ep93xx_soc_id),
+ "%08x%08x%08x%08x", id2, id3, id4, id5);
+
+ return ep93xx_soc_id;
+}
+
+static const char __init *ep93xx_get_soc_rev(void)
+{
+ int rev = ep93xx_chip_revision();
+
+ switch (rev) {
+ case EP93XX_CHIP_REV_D0:
+ return "D0";
+ case EP93XX_CHIP_REV_D1:
+ return "D1";
+ case EP93XX_CHIP_REV_E0:
+ return "E0";
+ case EP93XX_CHIP_REV_E1:
+ return "E1";
+ case EP93XX_CHIP_REV_E2:
+ return "E2";
+ default:
+ return "unknown";
+ }
+}
+
+static const char __init *ep93xx_get_machine_name(void)
+{
+ return kasprintf(GFP_KERNEL,"%s", machine_desc->name);
+}
+
+static struct device __init *ep93xx_init_soc(void)
+{
+ struct soc_device_attribute *soc_dev_attr;
+ struct soc_device *soc_dev;
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ return NULL;
+
+ soc_dev_attr->machine = ep93xx_get_machine_name();
+ soc_dev_attr->family = "Cirrus Logic EP93xx";
+ soc_dev_attr->revision = ep93xx_get_soc_rev();
+ soc_dev_attr->soc_id = ep93xx_get_soc_id();
+
+ soc_dev = soc_device_register(soc_dev_attr);
+ if (IS_ERR(soc_dev)) {
+ kfree(soc_dev_attr->machine);
+ kfree(soc_dev_attr);
+ return NULL;
+ }
+
+ return soc_device_to_device(soc_dev);
+}
+
+struct device __init *ep93xx_init_devices(void)
+{
+ struct device *parent;
+
+ /* Disallow access to MaverickCrunch initially */
+ ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA);
+
+ /* Default all ports to GPIO */
+ ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS |
+ EP93XX_SYSCON_DEVCFG_GONK |
+ EP93XX_SYSCON_DEVCFG_EONIDE |
+ EP93XX_SYSCON_DEVCFG_GONIDE |
+ EP93XX_SYSCON_DEVCFG_HONIDE);
+
+ parent = ep93xx_init_soc();
+
+ /* Get the GPIO working early, other devices need it */
+ platform_device_register(&ep93xx_gpio_device);
+
+ 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_wdt_device);
+
+ gpio_led_register_device(-1, &ep93xx_led_data);
+
+ return parent;
+}
+
+void ep93xx_restart(enum reboot_mode mode, const char *cmd)
+{
+ /*
+ * 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)
+ ;
+}
+
+void __init ep93xx_init_late(void)
+{
+ crunch_init();
+}
diff --git a/arch/arm/mach-ep93xx/crunch-bits.S b/arch/arm/mach-ep93xx/crunch-bits.S
new file mode 100644
index 000000000..ee0be2af5
--- /dev/null
+++ b/arch/arm/mach-ep93xx/crunch-bits.S
@@ -0,0 +1,313 @@
+/*
+ * 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 <asm/assembler.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 enabled
+ */
+ENTRY(crunch_task_enable)
+ inc_preempt_count r10, r3
+
+ ldr r8, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr
+
+ ldr r1, [r8, #0x80]
+ tst r1, #0x00800000 @ access to crunch enabled?
+ bne 2f @ 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
+ beq 1f
+
+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]
+
+1:
+#ifdef CONFIG_PREEMPT_COUNT
+ get_thread_info r10
+#endif
+2: dec_preempt_count r10, r3
+ ret 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
+ ret 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
+ ret r3
diff --git a/arch/arm/mach-ep93xx/crunch.c b/arch/arm/mach-ep93xx/crunch.c
new file mode 100644
index 000000000..a4a2ab964
--- /dev/null
+++ b/arch/arm/mach-ep93xx/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 <asm/thread_notify.h>
+
+#include "soc.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,
+};
+
+int __init crunch_init(void)
+{
+ thread_register_notifier(&crunch_notifier_block);
+ elf_hwcap |= HWCAP_CRUNCH;
+
+ return 0;
+}
diff --git a/arch/arm/mach-ep93xx/dma.c b/arch/arm/mach-ep93xx/dma.c
new file mode 100644
index 000000000..88a4c9b08
--- /dev/null
+++ b/arch/arm/mach-ep93xx/dma.c
@@ -0,0 +1,118 @@
+/*
+ * arch/arm/mach-ep93xx/dma.c
+ *
+ * Platform support code for the EP93xx dmaengine driver.
+ *
+ * Copyright (C) 2011 Mika Westerberg
+ *
+ * This work is based on the original dma-m2p implementation with
+ * following copyrights:
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Copyright (C) 2006 Applied Data Systems
+ * Copyright (C) 2009 Ryan Mallon <rmallon@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/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <linux/platform_data/dma-ep93xx.h>
+#include <mach/hardware.h>
+
+#include "soc.h"
+
+#define DMA_CHANNEL(_name, _base, _irq) \
+ { .name = (_name), .base = (_base), .irq = (_irq) }
+
+/*
+ * DMA M2P channels.
+ *
+ * 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
+ *
+ * Registers are mapped statically in ep93xx_map_io().
+ */
+static struct ep93xx_dma_chan_data ep93xx_dma_m2p_channels[] = {
+ DMA_CHANNEL("m2p0", EP93XX_DMA_BASE + 0x0000, IRQ_EP93XX_DMAM2P0),
+ DMA_CHANNEL("m2p1", EP93XX_DMA_BASE + 0x0040, IRQ_EP93XX_DMAM2P1),
+ DMA_CHANNEL("m2p2", EP93XX_DMA_BASE + 0x0080, IRQ_EP93XX_DMAM2P2),
+ DMA_CHANNEL("m2p3", EP93XX_DMA_BASE + 0x00c0, IRQ_EP93XX_DMAM2P3),
+ DMA_CHANNEL("m2p4", EP93XX_DMA_BASE + 0x0240, IRQ_EP93XX_DMAM2P4),
+ DMA_CHANNEL("m2p5", EP93XX_DMA_BASE + 0x0200, IRQ_EP93XX_DMAM2P5),
+ DMA_CHANNEL("m2p6", EP93XX_DMA_BASE + 0x02c0, IRQ_EP93XX_DMAM2P6),
+ DMA_CHANNEL("m2p7", EP93XX_DMA_BASE + 0x0280, IRQ_EP93XX_DMAM2P7),
+ DMA_CHANNEL("m2p8", EP93XX_DMA_BASE + 0x0340, IRQ_EP93XX_DMAM2P8),
+ DMA_CHANNEL("m2p9", EP93XX_DMA_BASE + 0x0300, IRQ_EP93XX_DMAM2P9),
+};
+
+static struct ep93xx_dma_platform_data ep93xx_dma_m2p_data = {
+ .channels = ep93xx_dma_m2p_channels,
+ .num_channels = ARRAY_SIZE(ep93xx_dma_m2p_channels),
+};
+
+static u64 ep93xx_dma_m2p_mask = DMA_BIT_MASK(32);
+
+static struct platform_device ep93xx_dma_m2p_device = {
+ .name = "ep93xx-dma-m2p",
+ .id = -1,
+ .dev = {
+ .platform_data = &ep93xx_dma_m2p_data,
+ .dma_mask = &ep93xx_dma_m2p_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+/*
+ * DMA M2M channels.
+ *
+ * There are 2 M2M channels which support memcpy/memset and in addition simple
+ * hardware requests from/to SSP and IDE. We do not implement an external
+ * hardware requests.
+ *
+ * Registers are mapped statically in ep93xx_map_io().
+ */
+static struct ep93xx_dma_chan_data ep93xx_dma_m2m_channels[] = {
+ DMA_CHANNEL("m2m0", EP93XX_DMA_BASE + 0x0100, IRQ_EP93XX_DMAM2M0),
+ DMA_CHANNEL("m2m1", EP93XX_DMA_BASE + 0x0140, IRQ_EP93XX_DMAM2M1),
+};
+
+static struct ep93xx_dma_platform_data ep93xx_dma_m2m_data = {
+ .channels = ep93xx_dma_m2m_channels,
+ .num_channels = ARRAY_SIZE(ep93xx_dma_m2m_channels),
+};
+
+static u64 ep93xx_dma_m2m_mask = DMA_BIT_MASK(32);
+
+static struct platform_device ep93xx_dma_m2m_device = {
+ .name = "ep93xx-dma-m2m",
+ .id = -1,
+ .dev = {
+ .platform_data = &ep93xx_dma_m2m_data,
+ .dma_mask = &ep93xx_dma_m2m_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static int __init ep93xx_dma_init(void)
+{
+ platform_device_register(&ep93xx_dma_m2p_device);
+ platform_device_register(&ep93xx_dma_m2m_device);
+ return 0;
+}
+arch_initcall(ep93xx_dma_init);
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
new file mode 100644
index 000000000..27b14ae92
--- /dev/null
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -0,0 +1,374 @@
+/*
+ * 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 <linux/platform_data/video-ep93xx.h>
+#include <linux/platform_data/spi-ep93xx.h>
+#include <mach/gpio-ep93xx.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "soc.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_edb9302() || 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 struct platform_device edb93xx_audio_device = {
+ .name = "edb93xx-audio",
+ .id = -1,
+};
+
+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();
+ platform_device_register(&edb93xx_audio_device);
+ }
+}
+
+
+/*************************************************************************
+ * 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);
+}
+
+
+/*************************************************************************
+ * EDB93xx IDE
+ *************************************************************************/
+static int __init edb93xx_has_ide(void)
+{
+ /*
+ * Although EDB9312 and EDB9315 do have IDE capability, they have
+ * INTRQ line wired as pull-up, which makes using IDE interface
+ * problematic.
+ */
+ return machine_is_edb9312() || machine_is_edb9315() ||
+ machine_is_edb9315a();
+}
+
+static void __init edb93xx_register_ide(void)
+{
+ if (!edb93xx_has_ide())
+ return;
+
+ ep93xx_register_ide();
+}
+
+
+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();
+ edb93xx_register_ide();
+}
+
+
+#ifdef CONFIG_MACH_EDB9301
+MACHINE_START(EDB9301, "Cirrus Logic EDB9301 Evaluation Board")
+ /* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */
+ .atag_offset = 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = edb93xx_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EDB9302
+MACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board")
+ /* Maintainer: George Kashperko <george@chas.com.ua> */
+ .atag_offset = 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = edb93xx_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EDB9302A
+MACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board")
+ /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+ .atag_offset = 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = edb93xx_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EDB9307
+MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board")
+ /* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */
+ .atag_offset = 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = edb93xx_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EDB9307A
+MACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board")
+ /* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */
+ .atag_offset = 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = edb93xx_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EDB9312
+MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board")
+ /* Maintainer: Toufeeq Hussain <toufeeq_hussain@infosys.com> */
+ .atag_offset = 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = edb93xx_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EDB9315
+MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board")
+ /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+ .atag_offset = 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = edb93xx_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EDB9315A
+MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board")
+ /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+ .atag_offset = 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = edb93xx_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c
new file mode 100644
index 000000000..0cca5b183
--- /dev/null
+++ b/arch/arm/mach-ep93xx/gesbc9312.c
@@ -0,0 +1,45 @@
+/*
+ * 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 <linux/sizes.h>
+
+#include <mach/hardware.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "soc.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> */
+ .atag_offset = 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = gesbc9312_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
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 000000000..c64d74246
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
+ */
+
+#ifndef __ASM_ARCH_EP93XX_REGS_H
+#define __ASM_ARCH_EP93XX_REGS_H
+
+/*
+ * 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))
+
+/* APB UARTs */
+#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)
+
+#endif
diff --git a/arch/arm/mach-ep93xx/include/mach/gpio-ep93xx.h b/arch/arm/mach-ep93xx/include/mach/gpio-ep93xx.h
new file mode 100644
index 000000000..6d7c571a5
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/gpio-ep93xx.h
@@ -0,0 +1,110 @@
+/* Include file for the EP93XX GPIO controller machine specifics */
+
+#ifndef __GPIO_EP93XX_H
+#define __GPIO_EP93XX_H
+
+#include <mach/ep93xx-regs.h>
+
+#define EP93XX_GPIO_PHYS_BASE EP93XX_APB_PHYS(0x00040000)
+#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)
+
+/* 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)
+
+#endif /* __GPIO_EP93XX_H */
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 000000000..efcd47815
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/hardware.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/hardware.h
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <mach/platform.h>
+
+/*
+ * 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/irqs.h b/arch/arm/mach-ep93xx/include/mach/irqs.h
new file mode 100644
index 000000000..ff98390bb
--- /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/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
new file mode 100644
index 000000000..4c0bbd97f
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -0,0 +1,70 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/platform.h
+ */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/reboot.h>
+
+struct device;
+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);
+
+#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(void);
+void ep93xx_i2s_release(void);
+void ep93xx_register_ac97(void);
+void ep93xx_register_ide(void);
+int ep93xx_ide_acquire_gpio(struct platform_device *pdev);
+void ep93xx_ide_release_gpio(struct platform_device *pdev);
+
+struct device *ep93xx_init_devices(void);
+extern void ep93xx_timer_init(void);
+
+void ep93xx_restart(enum reboot_mode, const char *);
+void ep93xx_init_late(void);
+
+#ifdef CONFIG_CRUNCH
+int crunch_init(void);
+#else
+static inline int crunch_init(void) { return 0; }
+#endif
+
+#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 000000000..03c42e540
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/uncompress.h
@@ -0,0 +1,82 @@
+/*
+ * 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;
+}
+
+#define PHYS_UART_DATA (CONFIG_DEBUG_UART_PHYS + 0x00)
+#define PHYS_UART_FLAG (CONFIG_DEBUG_UART_PHYS + 0x18)
+#define UART_FLAG_TXFF 0x20
+
+static inline void putc(int c)
+{
+ int i;
+
+ for (i = 0; i < 10000; 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();
+}
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
new file mode 100644
index 000000000..373583c29
--- /dev/null
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -0,0 +1,128 @@
+/*
+ * 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>
+
+#include "soc.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> */
+ .atag_offset = 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = micro9_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_MICRO9M
+MACHINE_START(MICRO9M, "Contec Micro9-Mid")
+ /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
+ .atag_offset = 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = micro9_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_MICRO9L
+MACHINE_START(MICRO9L, "Contec Micro9-Lite")
+ /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
+ .atag_offset = 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = micro9_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_MICRO9S
+MACHINE_START(MICRO9S, "Contec Micro9-Slim")
+ /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
+ .atag_offset = 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = micro9_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c
new file mode 100644
index 000000000..36f22c1a3
--- /dev/null
+++ b/arch/arm/mach-ep93xx/simone.c
@@ -0,0 +1,89 @@
+/*
+ * arch/arm/mach-ep93xx/simone.c
+ * Simplemachines Sim.One support.
+ *
+ * Copyright (C) 2010 Ryan Mallon
+ *
+ * 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/i2c.h>
+#include <linux/i2c-gpio.h>
+
+#include <mach/hardware.h>
+#include <linux/platform_data/video-ep93xx.h>
+#include <mach/gpio-ep93xx.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "soc.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 struct platform_device simone_audio_device = {
+ .name = "simone-audio",
+ .id = -1,
+};
+
+static void __init simone_register_audio(void)
+{
+ ep93xx_register_ac97();
+ platform_device_register(&simone_audio_device);
+}
+
+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));
+ simone_register_audio();
+}
+
+MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board")
+ /* Maintainer: Ryan Mallon */
+ .atag_offset = 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = simone_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c
new file mode 100644
index 000000000..aa86f8663
--- /dev/null
+++ b/arch/arm/mach-ep93xx/snappercl15.c
@@ -0,0 +1,182 @@
+/*
+ * arch/arm/mach-ep93xx/snappercl15.c
+ * Bluewater Systems Snapper CL15 system module
+ *
+ * Copyright (C) 2009 Bluewater Systems Ltd
+ * Author: Ryan Mallon
+ *
+ * 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/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 <linux/platform_data/video-ep93xx.h>
+#include <mach/gpio-ep93xx.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "soc.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 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,
+ .partitions = snappercl15_nand_parts,
+ .nr_partitions = ARRAY_SIZE(snappercl15_nand_parts),
+ .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 struct platform_device snappercl15_audio_device = {
+ .name = "snappercl15-audio",
+ .id = -1,
+};
+
+static void __init snappercl15_register_audio(void)
+{
+ ep93xx_register_i2s();
+ platform_device_register(&snappercl15_audio_device);
+}
+
+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);
+ snappercl15_register_audio();
+ platform_device_register(&snappercl15_nand_device);
+}
+
+MACHINE_START(SNAPPER_CL15, "Bluewater Systems Snapper CL15")
+ /* Maintainer: Ryan Mallon */
+ .atag_offset = 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = snappercl15_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-ep93xx/soc.h b/arch/arm/mach-ep93xx/soc.h
new file mode 100644
index 000000000..7bf7ff8be
--- /dev/null
+++ b/arch/arm/mach-ep93xx/soc.h
@@ -0,0 +1,214 @@
+/*
+ * arch/arm/mach-ep93xx/soc.h
+ *
+ * Copyright (C) 2012 Open Kernel Labs <www.ok-labs.com>
+ * Copyright (C) 2012 Ryan Mallon <rmallon@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 _EP93XX_SOC_H
+#define _EP93XX_SOC_H
+
+#include <mach/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 */
+
+/* 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_PHYS_BASE EP93XX_AHB_PHYS(0x000a0000)
+#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_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_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_WATCHDOG_PHYS_BASE EP93XX_APB_PHYS(0x00140000)
+#define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000)
+
+/* System controller */
+#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)
+
+/* 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);
+}
+
+#endif /* _EP93XX_SOC_H */
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
new file mode 100644
index 000000000..61f4b5dc4
--- /dev/null
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -0,0 +1,252 @@
+/*
+ * 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 <asm/mach-types.h>
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+
+#include "soc.h"
+#include "ts72xx.h"
+
+static struct map_desc ts72xx_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long)TS72XX_MODEL_VIRT_BASE,
+ .pfn = __phys_to_pfn(TS72XX_MODEL_PHYS_BASE),
+ .length = TS72XX_MODEL_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)TS72XX_OPTIONS_VIRT_BASE,
+ .pfn = __phys_to_pfn(TS72XX_OPTIONS_PHYS_BASE),
+ .length = TS72XX_OPTIONS_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)TS72XX_OPTIONS2_VIRT_BASE,
+ .pfn = __phys_to_pfn(TS72XX_OPTIONS2_PHYS_BASE),
+ .length = TS72XX_OPTIONS2_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)TS72XX_RTC_INDEX_VIRT_BASE,
+ .pfn = __phys_to_pfn(TS72XX_RTC_INDEX_PHYS_BASE),
+ .length = TS72XX_RTC_INDEX_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)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);
+}
+
+#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_RETAIN,
+ .size = TS72XX_REDBOOT_PART_SIZE,
+ /* leave so much for last partition */
+ }, {
+ .name = "RedBoot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+};
+
+static struct platform_nand_data ts72xx_nand_data = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_offset = 0,
+ .chip_delay = 15,
+ .partitions = ts72xx_nand_parts,
+ .nr_partitions = ARRAY_SIZE(ts72xx_nand_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> */
+ .atag_offset = 0x100,
+ .map_io = ts72xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = ts72xx_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-ep93xx/ts72xx.h b/arch/arm/mach-ep93xx/ts72xx.h
new file mode 100644
index 000000000..071feaa30
--- /dev/null
+++ b/arch/arm/mach-ep93xx/ts72xx.h
@@ -0,0 +1,98 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/ts72xx.h
+ */
+
+/*
+ * TS72xx memory map:
+ *
+ * virt phys size
+ * febff000 22000000 4K model number register (bits 0-2)
+ * 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 IOMEM(0xfebff000)
+#define TS72XX_MODEL_SIZE 0x00001000
+
+#define TS72XX_MODEL_TS7200 0x00
+#define TS72XX_MODEL_TS7250 0x01
+#define TS72XX_MODEL_TS7260 0x02
+#define TS72XX_MODEL_TS7300 0x03
+#define TS72XX_MODEL_TS7400 0x04
+#define TS72XX_MODEL_MASK 0x07
+
+
+#define TS72XX_OPTIONS_PHYS_BASE 0x22400000
+#define TS72XX_OPTIONS_VIRT_BASE IOMEM(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 IOMEM(0xfebfd000)
+#define TS72XX_OPTIONS2_SIZE 0x00001000
+
+#define TS72XX_OPTIONS2_TS9420 0x04
+#define TS72XX_OPTIONS2_TS9420_BOOT 0x02
+
+
+#define TS72XX_RTC_INDEX_VIRT_BASE IOMEM(0xfebf9000)
+#define TS72XX_RTC_INDEX_PHYS_BASE 0x10800000
+#define TS72XX_RTC_INDEX_SIZE 0x00001000
+
+#define TS72XX_RTC_DATA_VIRT_BASE IOMEM(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 ts72xx_model(void)
+{
+ return __raw_readb(TS72XX_MODEL_VIRT_BASE) & TS72XX_MODEL_MASK;
+}
+
+static inline int board_is_ts7200(void)
+{
+ return ts72xx_model() == TS72XX_MODEL_TS7200;
+}
+
+static inline int board_is_ts7250(void)
+{
+ return ts72xx_model() == TS72XX_MODEL_TS7250;
+}
+
+static inline int board_is_ts7260(void)
+{
+ return ts72xx_model() == TS72XX_MODEL_TS7260;
+}
+
+static inline int board_is_ts7300(void)
+{
+ return ts72xx_model() == TS72XX_MODEL_TS7300;
+}
+
+static inline int board_is_ts7400(void)
+{
+ return ts72xx_model() == TS72XX_MODEL_TS7400;
+}
+
+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/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c
new file mode 100644
index 000000000..6bc1c1815
--- /dev/null
+++ b/arch/arm/mach-ep93xx/vision_ep9307.c
@@ -0,0 +1,323 @@
+/*
+ * arch/arm/mach-ep93xx/vision_ep9307.c
+ * Vision Engraving Systems EP9307 SoM support.
+ *
+ * Copyright (C) 2008-2011 Vision Engraving Systems
+ * H Hartley Sweeten <hsweeten@visionengravers.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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+#include <linux/mtd/partitions.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/platform_data/pca953x.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/mmc_spi.h>
+#include <linux/mmc/host.h>
+
+#include <mach/hardware.h>
+#include <linux/platform_data/video-ep93xx.h>
+#include <linux/platform_data/spi-ep93xx.h>
+#include <mach/gpio-ep93xx.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+
+#include "soc.h"
+
+/*************************************************************************
+ * Static I/O mappings for the FPGA
+ *************************************************************************/
+#define VISION_PHYS_BASE EP93XX_CS7_PHYS_BASE
+#define VISION_VIRT_BASE 0xfebff000
+
+static struct map_desc vision_io_desc[] __initdata = {
+ {
+ .virtual = VISION_VIRT_BASE,
+ .pfn = __phys_to_pfn(VISION_PHYS_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init vision_map_io(void)
+{
+ ep93xx_map_io();
+
+ iotable_init(vision_io_desc, ARRAY_SIZE(vision_io_desc));
+}
+
+/*************************************************************************
+ * Ethernet
+ *************************************************************************/
+static struct ep93xx_eth_data vision_eth_data __initdata = {
+ .phy_id = 1,
+};
+
+/*************************************************************************
+ * Framebuffer
+ *************************************************************************/
+#define VISION_LCD_ENABLE EP93XX_GPIO_LINE_EGPIO1
+
+static int vision_lcd_setup(struct platform_device *pdev)
+{
+ int err;
+
+ err = gpio_request_one(VISION_LCD_ENABLE, GPIOF_INIT_HIGH,
+ dev_name(&pdev->dev));
+ if (err)
+ return err;
+
+ ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_RAS |
+ EP93XX_SYSCON_DEVCFG_RASONP3 |
+ EP93XX_SYSCON_DEVCFG_EXVC);
+
+ return 0;
+}
+
+static void vision_lcd_teardown(struct platform_device *pdev)
+{
+ gpio_free(VISION_LCD_ENABLE);
+}
+
+static void vision_lcd_blank(int blank_mode, struct fb_info *info)
+{
+ if (blank_mode)
+ gpio_set_value(VISION_LCD_ENABLE, 0);
+ else
+ gpio_set_value(VISION_LCD_ENABLE, 1);
+}
+
+static struct ep93xxfb_mach_info ep93xxfb_info __initdata = {
+ .num_modes = EP93XXFB_USE_MODEDB,
+ .bpp = 16,
+ .flags = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
+ .setup = vision_lcd_setup,
+ .teardown = vision_lcd_teardown,
+ .blank = vision_lcd_blank,
+};
+
+
+/*************************************************************************
+ * GPIO Expanders
+ *************************************************************************/
+#define PCA9539_74_GPIO_BASE (EP93XX_GPIO_LINE_MAX + 1)
+#define PCA9539_75_GPIO_BASE (PCA9539_74_GPIO_BASE + 16)
+#define PCA9539_76_GPIO_BASE (PCA9539_75_GPIO_BASE + 16)
+#define PCA9539_77_GPIO_BASE (PCA9539_76_GPIO_BASE + 16)
+
+static struct pca953x_platform_data pca953x_74_gpio_data = {
+ .gpio_base = PCA9539_74_GPIO_BASE,
+ .irq_base = EP93XX_BOARD_IRQ(0),
+};
+
+static struct pca953x_platform_data pca953x_75_gpio_data = {
+ .gpio_base = PCA9539_75_GPIO_BASE,
+ .irq_base = -1,
+};
+
+static struct pca953x_platform_data pca953x_76_gpio_data = {
+ .gpio_base = PCA9539_76_GPIO_BASE,
+ .irq_base = -1,
+};
+
+static struct pca953x_platform_data pca953x_77_gpio_data = {
+ .gpio_base = PCA9539_77_GPIO_BASE,
+ .irq_base = -1,
+};
+
+/*************************************************************************
+ * I2C Bus
+ *************************************************************************/
+static struct i2c_gpio_platform_data vision_i2c_gpio_data __initdata = {
+ .sda_pin = EP93XX_GPIO_LINE_EEDAT,
+ .scl_pin = EP93XX_GPIO_LINE_EECLK,
+};
+
+static struct i2c_board_info vision_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("isl1208", 0x6f),
+ .irq = IRQ_EP93XX_EXT1,
+ }, {
+ I2C_BOARD_INFO("pca9539", 0x74),
+ .platform_data = &pca953x_74_gpio_data,
+ }, {
+ I2C_BOARD_INFO("pca9539", 0x75),
+ .platform_data = &pca953x_75_gpio_data,
+ }, {
+ I2C_BOARD_INFO("pca9539", 0x76),
+ .platform_data = &pca953x_76_gpio_data,
+ }, {
+ I2C_BOARD_INFO("pca9539", 0x77),
+ .platform_data = &pca953x_77_gpio_data,
+ },
+};
+
+/*************************************************************************
+ * SPI Flash
+ *************************************************************************/
+#define VISION_SPI_FLASH_CS EP93XX_GPIO_LINE_EGPIO7
+
+static struct mtd_partition vision_spi_flash_partitions[] = {
+ {
+ .name = "SPI bootstrap",
+ .offset = 0,
+ .size = SZ_4K,
+ }, {
+ .name = "Bootstrap config",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4K,
+ }, {
+ .name = "System config",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data vision_spi_flash_data = {
+ .name = "SPI Flash",
+ .parts = vision_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(vision_spi_flash_partitions),
+};
+
+static int vision_spi_flash_hw_setup(struct spi_device *spi)
+{
+ return gpio_request_one(VISION_SPI_FLASH_CS, GPIOF_INIT_HIGH,
+ spi->modalias);
+}
+
+static void vision_spi_flash_hw_cleanup(struct spi_device *spi)
+{
+ gpio_free(VISION_SPI_FLASH_CS);
+}
+
+static void vision_spi_flash_hw_cs_control(struct spi_device *spi, int value)
+{
+ gpio_set_value(VISION_SPI_FLASH_CS, value);
+}
+
+static struct ep93xx_spi_chip_ops vision_spi_flash_hw = {
+ .setup = vision_spi_flash_hw_setup,
+ .cleanup = vision_spi_flash_hw_cleanup,
+ .cs_control = vision_spi_flash_hw_cs_control,
+};
+
+/*************************************************************************
+ * SPI SD/MMC host
+ *************************************************************************/
+#define VISION_SPI_MMC_CS EP93XX_GPIO_LINE_G(2)
+#define VISION_SPI_MMC_WP EP93XX_GPIO_LINE_F(0)
+#define VISION_SPI_MMC_CD EP93XX_GPIO_LINE_EGPIO15
+
+static struct mmc_spi_platform_data vision_spi_mmc_data = {
+ .detect_delay = 100,
+ .powerup_msecs = 100,
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .flags = MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO,
+ .cd_gpio = VISION_SPI_MMC_CD,
+ .cd_debounce = 1,
+ .ro_gpio = VISION_SPI_MMC_WP,
+ .caps2 = MMC_CAP2_RO_ACTIVE_HIGH,
+};
+
+static int vision_spi_mmc_hw_setup(struct spi_device *spi)
+{
+ return gpio_request_one(VISION_SPI_MMC_CS, GPIOF_INIT_HIGH,
+ spi->modalias);
+}
+
+static void vision_spi_mmc_hw_cleanup(struct spi_device *spi)
+{
+ gpio_free(VISION_SPI_MMC_CS);
+}
+
+static void vision_spi_mmc_hw_cs_control(struct spi_device *spi, int value)
+{
+ gpio_set_value(VISION_SPI_MMC_CS, value);
+}
+
+static struct ep93xx_spi_chip_ops vision_spi_mmc_hw = {
+ .setup = vision_spi_mmc_hw_setup,
+ .cleanup = vision_spi_mmc_hw_cleanup,
+ .cs_control = vision_spi_mmc_hw_cs_control,
+};
+
+/*************************************************************************
+ * SPI Bus
+ *************************************************************************/
+static struct spi_board_info vision_spi_board_info[] __initdata = {
+ {
+ .modalias = "sst25l",
+ .platform_data = &vision_spi_flash_data,
+ .controller_data = &vision_spi_flash_hw,
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ }, {
+ .modalias = "mmc_spi",
+ .platform_data = &vision_spi_mmc_data,
+ .controller_data = &vision_spi_mmc_hw,
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = SPI_MODE_3,
+ },
+};
+
+static struct ep93xx_spi_info vision_spi_master __initdata = {
+ .num_chipselect = ARRAY_SIZE(vision_spi_board_info),
+};
+
+/*************************************************************************
+ * Machine Initialization
+ *************************************************************************/
+static void __init vision_init_machine(void)
+{
+ ep93xx_init_devices();
+ ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_64M);
+ ep93xx_register_eth(&vision_eth_data, 1);
+ ep93xx_register_fb(&ep93xxfb_info);
+ ep93xx_register_pwm(1, 0);
+
+ /*
+ * Request the gpio expander's interrupt gpio line now to prevent
+ * the kernel from doing a WARN in gpiolib:gpio_ensure_requested().
+ */
+ if (gpio_request_one(EP93XX_GPIO_LINE_F(7), GPIOF_DIR_IN,
+ "pca9539:74"))
+ pr_warn("cannot request interrupt gpio for pca9539:74\n");
+
+ vision_i2c_info[1].irq = gpio_to_irq(EP93XX_GPIO_LINE_F(7));
+
+ ep93xx_register_i2c(&vision_i2c_gpio_data, vision_i2c_info,
+ ARRAY_SIZE(vision_i2c_info));
+ ep93xx_register_spi(&vision_spi_master, vision_spi_board_info,
+ ARRAY_SIZE(vision_spi_board_info));
+}
+
+MACHINE_START(VISION_EP9307, "Vision Engraving Systems EP9307")
+ /* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */
+ .atag_offset = 0x100,
+ .map_io = vision_map_io,
+ .init_irq = ep93xx_init_irq,
+ .init_time = ep93xx_timer_init,
+ .init_machine = vision_init_machine,
+ .init_late = ep93xx_init_late,
+ .restart = ep93xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
new file mode 100644
index 000000000..81064cd61
--- /dev/null
+++ b/arch/arm/mach-exynos/Kconfig
@@ -0,0 +1,137 @@
+# arch/arm/mach-exynos/Kconfig
+#
+# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+# Configuration options for the EXYNOS4
+
+menuconfig ARCH_EXYNOS
+ bool "Samsung EXYNOS" if ARCH_MULTI_V7
+ select ARCH_HAS_BANDGAP
+ select ARCH_HAS_HOLES_MEMORYMODEL
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_AMBA
+ select ARM_GIC
+ select COMMON_CLK_SAMSUNG
+ select HAVE_ARM_SCU if SMP
+ select HAVE_S3C2410_I2C if I2C
+ select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select HAVE_S3C_RTC if RTC_CLASS
+ select PINCTRL
+ select PINCTRL_EXYNOS
+ select PM_GENERIC_DOMAINS if PM
+ select S5P_DEV_MFC
+ select SRAM
+ select MFD_SYSCON
+ help
+ Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5)
+
+if ARCH_EXYNOS
+
+config ARCH_EXYNOS3
+ bool "SAMSUNG EXYNOS3"
+ select ARM_CPU_SUSPEND if PM
+ help
+ Samsung EXYNOS3 (Cortex-A7) SoC based systems
+
+config ARCH_EXYNOS4
+ bool "SAMSUNG EXYNOS4"
+ default y
+ select ARM_CPU_SUSPEND if PM_SLEEP
+ select CLKSRC_SAMSUNG_PWM if CPU_EXYNOS4210
+ select CPU_EXYNOS4210
+ select GIC_NON_BANKED
+ select KEYBOARD_SAMSUNG if INPUT_KEYBOARD
+ select MIGHT_HAVE_CACHE_L2X0
+ help
+ Samsung EXYNOS4 (Cortex-A9) SoC based systems
+
+config ARCH_EXYNOS5
+ bool "SAMSUNG EXYNOS5"
+ default y
+ help
+ Samsung EXYNOS5 (Cortex-A15/A7) SoC based systems
+
+comment "EXYNOS SoCs"
+
+config SOC_EXYNOS3250
+ bool "SAMSUNG EXYNOS3250"
+ default y
+ depends on ARCH_EXYNOS3
+
+config CPU_EXYNOS4210
+ bool "SAMSUNG EXYNOS4210"
+ default y
+ depends on ARCH_EXYNOS4
+
+config SOC_EXYNOS4212
+ bool "SAMSUNG EXYNOS4212"
+ default y
+ depends on ARCH_EXYNOS4
+
+config SOC_EXYNOS4412
+ bool "SAMSUNG EXYNOS4412"
+ default y
+ depends on ARCH_EXYNOS4
+
+config SOC_EXYNOS4415
+ bool "SAMSUNG EXYNOS4415"
+ default y
+ depends on ARCH_EXYNOS4
+
+config SOC_EXYNOS5250
+ bool "SAMSUNG EXYNOS5250"
+ default y
+ depends on ARCH_EXYNOS5
+
+config SOC_EXYNOS5260
+ bool "SAMSUNG EXYNOS5260"
+ default y
+ depends on ARCH_EXYNOS5
+
+config SOC_EXYNOS5410
+ bool "SAMSUNG EXYNOS5410"
+ default y
+ depends on ARCH_EXYNOS5
+
+config SOC_EXYNOS5420
+ bool "SAMSUNG EXYNOS5420"
+ default y
+ depends on ARCH_EXYNOS5
+
+config SOC_EXYNOS5440
+ bool "SAMSUNG EXYNOS5440"
+ default y
+ depends on ARCH_EXYNOS5
+ select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
+ select HAVE_ARM_ARCH_TIMER
+ select AUTO_ZRELADDR
+ select MIGHT_HAVE_PCI
+ select PCI_DOMAINS if PCI
+ select PINCTRL_EXYNOS5440
+ select PM_OPP
+ help
+ Enable EXYNOS5440 SoC support
+
+config SOC_EXYNOS5800
+ bool "SAMSUNG EXYNOS5800"
+ default y
+ depends on SOC_EXYNOS5420
+
+config EXYNOS5420_MCPM
+ bool "Exynos5420 Multi-Cluster PM support"
+ depends on MCPM && SOC_EXYNOS5420
+ select ARM_CCI400_PORT_CTRL
+ select ARM_CPU_SUSPEND
+ help
+ This is needed to provide CPU and cluster power management
+ on Exynos5420 implementing big.LITTLE.
+
+config EXYNOS_CPU_SUSPEND
+ bool
+ select ARM_CPU_SUSPEND
+ default PM_SLEEP || ARM_EXYNOS_CPUIDLE
+
+endif
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
new file mode 100644
index 000000000..bcefb5473
--- /dev/null
+++ b/arch/arm/mach-exynos/Makefile
@@ -0,0 +1,25 @@
+# arch/arm/mach-exynos/Makefile
+#
+# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/$(src)/include -I$(srctree)/arch/arm/plat-samsung/include
+
+# Core
+
+obj-$(CONFIG_ARCH_EXYNOS) += exynos.o pmu.o exynos-smc.o firmware.o
+
+obj-$(CONFIG_EXYNOS_CPU_SUSPEND) += pm.o sleep.o
+obj-$(CONFIG_PM_SLEEP) += suspend.o
+obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
+
+obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+
+plus_sec := $(call as-instr,.arch_extension sec,+sec)
+AFLAGS_exynos-smc.o :=-Wa,-march=armv7-a$(plus_sec)
+AFLAGS_sleep.o :=-Wa,-march=armv7-a$(plus_sec)
+
+obj-$(CONFIG_EXYNOS5420_MCPM) += mcpm-exynos.o
+CFLAGS_mcpm-exynos.o += -march=armv7-a
diff --git a/arch/arm/mach-exynos/Makefile.boot b/arch/arm/mach-exynos/Makefile.boot
new file mode 100644
index 000000000..b9862e22b
--- /dev/null
+++ b/arch/arm/mach-exynos/Makefile.boot
@@ -0,0 +1,2 @@
+ zreladdr-y += 0x40008000
+params_phys-y := 0x40000100
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
new file mode 100644
index 000000000..5f5cd562c
--- /dev/null
+++ b/arch/arm/mach-exynos/common.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Common Header for EXYNOS 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_EXYNOS_COMMON_H
+#define __ARCH_ARM_MACH_EXYNOS_COMMON_H
+
+#include <linux/of.h>
+#include <linux/platform_data/cpuidle-exynos.h>
+
+#define EXYNOS3250_SOC_ID 0xE3472000
+#define EXYNOS3_SOC_MASK 0xFFFFF000
+
+#define EXYNOS4210_CPU_ID 0x43210000
+#define EXYNOS4212_CPU_ID 0x43220000
+#define EXYNOS4412_CPU_ID 0xE4412200
+#define EXYNOS4_CPU_MASK 0xFFFE0000
+
+#define EXYNOS5250_SOC_ID 0x43520000
+#define EXYNOS5410_SOC_ID 0xE5410000
+#define EXYNOS5420_SOC_ID 0xE5420000
+#define EXYNOS5440_SOC_ID 0xE5440000
+#define EXYNOS5800_SOC_ID 0xE5422000
+#define EXYNOS5_SOC_MASK 0xFFFFF000
+
+extern unsigned long samsung_cpu_id;
+
+#define IS_SAMSUNG_CPU(name, id, mask) \
+static inline int is_samsung_##name(void) \
+{ \
+ return ((samsung_cpu_id & mask) == (id & mask)); \
+}
+
+IS_SAMSUNG_CPU(exynos3250, EXYNOS3250_SOC_ID, EXYNOS3_SOC_MASK)
+IS_SAMSUNG_CPU(exynos4210, EXYNOS4210_CPU_ID, EXYNOS4_CPU_MASK)
+IS_SAMSUNG_CPU(exynos4212, EXYNOS4212_CPU_ID, EXYNOS4_CPU_MASK)
+IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK)
+IS_SAMSUNG_CPU(exynos5250, EXYNOS5250_SOC_ID, EXYNOS5_SOC_MASK)
+IS_SAMSUNG_CPU(exynos5410, EXYNOS5410_SOC_ID, EXYNOS5_SOC_MASK)
+IS_SAMSUNG_CPU(exynos5420, EXYNOS5420_SOC_ID, EXYNOS5_SOC_MASK)
+IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK)
+IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
+
+#if defined(CONFIG_SOC_EXYNOS3250)
+# define soc_is_exynos3250() is_samsung_exynos3250()
+#else
+# define soc_is_exynos3250() 0
+#endif
+
+#if defined(CONFIG_CPU_EXYNOS4210)
+# define soc_is_exynos4210() is_samsung_exynos4210()
+#else
+# define soc_is_exynos4210() 0
+#endif
+
+#if defined(CONFIG_SOC_EXYNOS4212)
+# define soc_is_exynos4212() is_samsung_exynos4212()
+#else
+# define soc_is_exynos4212() 0
+#endif
+
+#if defined(CONFIG_SOC_EXYNOS4412)
+# define soc_is_exynos4412() is_samsung_exynos4412()
+#else
+# define soc_is_exynos4412() 0
+#endif
+
+#define EXYNOS4210_REV_0 (0x0)
+#define EXYNOS4210_REV_1_0 (0x10)
+#define EXYNOS4210_REV_1_1 (0x11)
+
+#if defined(CONFIG_SOC_EXYNOS5250)
+# define soc_is_exynos5250() is_samsung_exynos5250()
+#else
+# define soc_is_exynos5250() 0
+#endif
+
+#if defined(CONFIG_SOC_EXYNOS5410)
+# define soc_is_exynos5410() is_samsung_exynos5410()
+#else
+# define soc_is_exynos5410() 0
+#endif
+
+#if defined(CONFIG_SOC_EXYNOS5420)
+# define soc_is_exynos5420() is_samsung_exynos5420()
+#else
+# define soc_is_exynos5420() 0
+#endif
+
+#if defined(CONFIG_SOC_EXYNOS5440)
+# define soc_is_exynos5440() is_samsung_exynos5440()
+#else
+# define soc_is_exynos5440() 0
+#endif
+
+#if defined(CONFIG_SOC_EXYNOS5800)
+# define soc_is_exynos5800() is_samsung_exynos5800()
+#else
+# define soc_is_exynos5800() 0
+#endif
+
+#define soc_is_exynos4() (soc_is_exynos4210() || soc_is_exynos4212() || \
+ soc_is_exynos4412())
+#define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5410() || \
+ soc_is_exynos5420() || soc_is_exynos5800())
+
+extern u32 cp15_save_diag;
+extern u32 cp15_save_power;
+
+extern void __iomem *sysram_ns_base_addr;
+extern void __iomem *sysram_base_addr;
+extern void __iomem *pmu_base_addr;
+void exynos_sysram_init(void);
+
+enum {
+ FW_DO_IDLE_SLEEP,
+ FW_DO_IDLE_AFTR,
+};
+
+void exynos_firmware_init(void);
+
+/* CPU BOOT mode flag for Exynos3250 SoC bootloader */
+#define C2_STATE (1 << 3)
+
+void exynos_set_boot_flag(unsigned int cpu, unsigned int mode);
+void exynos_clear_boot_flag(unsigned int cpu, unsigned int mode);
+
+extern u32 exynos_get_eint_wake_mask(void);
+
+#ifdef CONFIG_PM_SLEEP
+extern void __init exynos_pm_init(void);
+#else
+static inline void exynos_pm_init(void) {}
+#endif
+
+extern void exynos_cpu_resume(void);
+extern void exynos_cpu_resume_ns(void);
+
+extern struct smp_operations exynos_smp_ops;
+
+extern void exynos_cpu_power_down(int cpu);
+extern void exynos_cpu_power_up(int cpu);
+extern int exynos_cpu_power_state(int cpu);
+extern void exynos_cluster_power_down(int cluster);
+extern void exynos_cluster_power_up(int cluster);
+extern int exynos_cluster_power_state(int cluster);
+extern void exynos_cpu_save_register(void);
+extern void exynos_cpu_restore_register(void);
+extern void exynos_pm_central_suspend(void);
+extern int exynos_pm_central_resume(void);
+extern void exynos_enter_aftr(void);
+
+extern struct cpuidle_exynos_data cpuidle_coupled_exynos_data;
+
+extern void exynos_set_delayed_reset_assertion(bool enable);
+
+extern void s5p_init_cpu(void __iomem *cpuid_addr);
+extern unsigned int samsung_rev(void);
+extern void __iomem *cpu_boot_reg_base(void);
+
+static inline void pmu_raw_writel(u32 val, u32 offset)
+{
+ __raw_writel(val, pmu_base_addr + offset);
+}
+
+static inline u32 pmu_raw_readl(u32 offset)
+{
+ return __raw_readl(pmu_base_addr + offset);
+}
+
+#endif /* __ARCH_ARM_MACH_EXYNOS_COMMON_H */
diff --git a/arch/arm/mach-exynos/exynos-pmu.h b/arch/arm/mach-exynos/exynos-pmu.h
new file mode 100644
index 000000000..a2ab0d52b
--- /dev/null
+++ b/arch/arm/mach-exynos/exynos-pmu.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Header for EXYNOS PMU Driver 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 __EXYNOS_PMU_H
+#define __EXYNOS_PMU_H
+
+enum sys_powerdown {
+ SYS_AFTR,
+ SYS_LPA,
+ SYS_SLEEP,
+ NUM_SYS_POWERDOWN,
+};
+
+extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
+
+#endif /* __EXYNOS_PMU_H */
diff --git a/arch/arm/mach-exynos/exynos-smc.S b/arch/arm/mach-exynos/exynos-smc.S
new file mode 100644
index 000000000..2e27aa381
--- /dev/null
+++ b/arch/arm/mach-exynos/exynos-smc.S
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics.
+ *
+ * Copied from omap-smc.S Copyright (C) 2010 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/linkage.h>
+
+/*
+ * Function signature: void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3)
+ */
+
+ENTRY(exynos_smc)
+ stmfd sp!, {r4-r11, lr}
+ dsb
+ smc #0
+ ldmfd sp!, {r4-r11, pc}
+ENDPROC(exynos_smc)
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
new file mode 100644
index 000000000..5917a30ee
--- /dev/null
+++ b/arch/arm/mach-exynos/exynos.c
@@ -0,0 +1,309 @@
+/*
+ * SAMSUNG EXYNOS Flattened Device Tree enabled machine
+ *
+ * Copyright (c) 2010-2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/serial_s3c.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/irqchip.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/memory.h>
+
+#include <mach/map.h>
+
+#include "common.h"
+#include "mfc.h"
+#include "regs-pmu.h"
+
+void __iomem *pmu_base_addr;
+
+static struct map_desc exynos4_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_SROMC,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC),
+ .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_COREPERI_BASE,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_DMC0,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_DMC1,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_DMC1),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct map_desc exynos5_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_SROMC,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_SROMC),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_CMU,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_CMU),
+ .length = 144 * SZ_1K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct platform_device exynos_cpuidle = {
+ .name = "exynos_cpuidle",
+#ifdef CONFIG_ARM_EXYNOS_CPUIDLE
+ .dev.platform_data = exynos_enter_aftr,
+#endif
+ .id = -1,
+};
+
+void __iomem *sysram_base_addr;
+void __iomem *sysram_ns_base_addr;
+
+void __init exynos_sysram_init(void)
+{
+ struct device_node *node;
+
+ for_each_compatible_node(node, NULL, "samsung,exynos4210-sysram") {
+ if (!of_device_is_available(node))
+ continue;
+ sysram_base_addr = of_iomap(node, 0);
+ break;
+ }
+
+ for_each_compatible_node(node, NULL, "samsung,exynos4210-sysram-ns") {
+ if (!of_device_is_available(node))
+ continue;
+ sysram_ns_base_addr = of_iomap(node, 0);
+ break;
+ }
+}
+
+static void __init exynos_init_late(void)
+{
+ if (of_machine_is_compatible("samsung,exynos5440"))
+ /* to be supported later */
+ return;
+
+ exynos_pm_init();
+}
+
+static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
+ int depth, void *data)
+{
+ struct map_desc iodesc;
+ const __be32 *reg;
+ int len;
+
+ if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") &&
+ !of_flat_dt_is_compatible(node, "samsung,exynos5440-clock"))
+ return 0;
+
+ reg = of_get_flat_dt_prop(node, "reg", &len);
+ if (reg == NULL || len != (sizeof(unsigned long) * 2))
+ return 0;
+
+ iodesc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
+ iodesc.length = be32_to_cpu(reg[1]) - 1;
+ iodesc.virtual = (unsigned long)S5P_VA_CHIPID;
+ iodesc.type = MT_DEVICE;
+ iotable_init(&iodesc, 1);
+ return 1;
+}
+
+/*
+ * exynos_map_io
+ *
+ * register the standard cpu IO areas
+ */
+static void __init exynos_map_io(void)
+{
+ if (soc_is_exynos4())
+ iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
+
+ if (soc_is_exynos5())
+ iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
+}
+
+static void __init exynos_init_io(void)
+{
+ debug_ll_io_init();
+
+ of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
+
+ /* detect cpu id and rev. */
+ s5p_init_cpu(S5P_VA_CHIPID);
+
+ exynos_map_io();
+}
+
+/*
+ * Set or clear the USE_DELAYED_RESET_ASSERTION option. Used by smp code
+ * and suspend.
+ *
+ * This is necessary only on Exynos4 SoCs. When system is running
+ * USE_DELAYED_RESET_ASSERTION should be set so the ARM CLK clock down
+ * feature could properly detect global idle state when secondary CPU is
+ * powered down.
+ *
+ * However this should not be set when such system is going into suspend.
+ */
+void exynos_set_delayed_reset_assertion(bool enable)
+{
+ if (of_machine_is_compatible("samsung,exynos4")) {
+ unsigned int tmp, core_id;
+
+ for (core_id = 0; core_id < num_possible_cpus(); core_id++) {
+ tmp = pmu_raw_readl(EXYNOS_ARM_CORE_OPTION(core_id));
+ if (enable)
+ tmp |= S5P_USE_DELAYED_RESET_ASSERTION;
+ else
+ tmp &= ~(S5P_USE_DELAYED_RESET_ASSERTION);
+ pmu_raw_writel(tmp, EXYNOS_ARM_CORE_OPTION(core_id));
+ }
+ }
+}
+
+/*
+ * Apparently, these SoCs are not able to wake-up from suspend using
+ * the PMU. Too bad. Should they suddenly become capable of such a
+ * feat, the matches below should be moved to suspend.c.
+ */
+static const struct of_device_id exynos_dt_pmu_match[] = {
+ { .compatible = "samsung,exynos5260-pmu" },
+ { .compatible = "samsung,exynos5410-pmu" },
+ { /*sentinel*/ },
+};
+
+static void exynos_map_pmu(void)
+{
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, exynos_dt_pmu_match);
+ if (np)
+ pmu_base_addr = of_iomap(np, 0);
+}
+
+static void __init exynos_init_irq(void)
+{
+ irqchip_init();
+ /*
+ * Since platsmp.c needs pmu base address by the time
+ * DT is not unflatten so we can't use DT APIs before
+ * init_irq
+ */
+ exynos_map_pmu();
+}
+
+static void __init exynos_dt_machine_init(void)
+{
+ /*
+ * This is called from smp_prepare_cpus if we've built for SMP, but
+ * we still need to set it up for PM and firmware ops if not.
+ */
+ if (!IS_ENABLED(CONFIG_SMP))
+ exynos_sysram_init();
+
+#if defined(CONFIG_SMP) && defined(CONFIG_ARM_EXYNOS_CPUIDLE)
+ if (of_machine_is_compatible("samsung,exynos4210"))
+ exynos_cpuidle.dev.platform_data = &cpuidle_coupled_exynos_data;
+#endif
+ if (of_machine_is_compatible("samsung,exynos4210") ||
+ of_machine_is_compatible("samsung,exynos4212") ||
+ (of_machine_is_compatible("samsung,exynos4412") &&
+ of_machine_is_compatible("samsung,trats2")) ||
+ of_machine_is_compatible("samsung,exynos3250") ||
+ of_machine_is_compatible("samsung,exynos5250"))
+ platform_device_register(&exynos_cpuidle);
+
+ platform_device_register_simple("exynos-cpufreq", -1, NULL, 0);
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static char const *const exynos_dt_compat[] __initconst = {
+ "samsung,exynos3",
+ "samsung,exynos3250",
+ "samsung,exynos4",
+ "samsung,exynos4210",
+ "samsung,exynos4212",
+ "samsung,exynos4412",
+ "samsung,exynos4415",
+ "samsung,exynos5",
+ "samsung,exynos5250",
+ "samsung,exynos5260",
+ "samsung,exynos5420",
+ "samsung,exynos5440",
+ NULL
+};
+
+static void __init exynos_reserve(void)
+{
+#ifdef CONFIG_S5P_DEV_MFC
+ int i;
+ char *mfc_mem[] = {
+ "samsung,mfc-v5",
+ "samsung,mfc-v6",
+ "samsung,mfc-v7",
+ "samsung,mfc-v8",
+ };
+
+ for (i = 0; i < ARRAY_SIZE(mfc_mem); i++)
+ if (of_scan_flat_dt(s5p_fdt_alloc_mfc_mem, mfc_mem[i]))
+ break;
+#endif
+}
+
+static void __init exynos_dt_fixup(void)
+{
+ /*
+ * Some versions of uboot pass garbage entries in the memory node,
+ * use the old CONFIG_ARM_NR_BANKS
+ */
+ of_fdt_limit_memory(8);
+}
+
+DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
+ /* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
+ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+ .l2c_aux_val = 0x3c400001,
+ .l2c_aux_mask = 0xc20fffff,
+ .smp = smp_ops(exynos_smp_ops),
+ .map_io = exynos_init_io,
+ .init_early = exynos_firmware_init,
+ .init_irq = exynos_init_irq,
+ .init_machine = exynos_dt_machine_init,
+ .init_late = exynos_init_late,
+ .dt_compat = exynos_dt_compat,
+ .reserve = exynos_reserve,
+ .dt_fixup = exynos_dt_fixup,
+MACHINE_END
diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
new file mode 100644
index 000000000..1bd35763f
--- /dev/null
+++ b/arch/arm/mach-exynos/firmware.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics.
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ * Tomasz Figa <t.figa@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/io.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cputype.h>
+#include <asm/firmware.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/suspend.h>
+
+#include <mach/map.h>
+
+#include "common.h"
+#include "smc.h"
+
+#define EXYNOS_SLEEP_MAGIC 0x00000bad
+#define EXYNOS_AFTR_MAGIC 0xfcba0d10
+#define EXYNOS_BOOT_ADDR 0x8
+#define EXYNOS_BOOT_FLAG 0xc
+
+static void exynos_save_cp15(void)
+{
+ /* Save Power control and Diagnostic registers */
+ asm ("mrc p15, 0, %0, c15, c0, 0\n"
+ "mrc p15, 0, %1, c15, c0, 1\n"
+ : "=r" (cp15_save_power), "=r" (cp15_save_diag)
+ : : "cc");
+}
+
+static int exynos_do_idle(unsigned long mode)
+{
+ switch (mode) {
+ case FW_DO_IDLE_AFTR:
+ if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
+ exynos_save_cp15();
+ __raw_writel(virt_to_phys(exynos_cpu_resume_ns),
+ sysram_ns_base_addr + 0x24);
+ __raw_writel(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
+ if (soc_is_exynos3250()) {
+ exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
+ SMC_POWERSTATE_IDLE, 0);
+ exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
+ SMC_POWERSTATE_IDLE, 0);
+ } else
+ exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0);
+ break;
+ case FW_DO_IDLE_SLEEP:
+ exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
+ }
+ return 0;
+}
+
+static int exynos_cpu_boot(int cpu)
+{
+ /*
+ * Exynos3250 doesn't need to send smc command for secondary CPU boot
+ * because Exynos3250 removes WFE in secure mode.
+ */
+ if (soc_is_exynos3250())
+ return 0;
+
+ /*
+ * The second parameter of SMC_CMD_CPU1BOOT command means CPU id.
+ * But, Exynos4212 has only one secondary CPU so second parameter
+ * isn't used for informing secure firmware about CPU id.
+ */
+ if (soc_is_exynos4212())
+ cpu = 0;
+
+ exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0);
+ return 0;
+}
+
+static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
+{
+ void __iomem *boot_reg;
+
+ if (!sysram_ns_base_addr)
+ return -ENODEV;
+
+ boot_reg = sysram_ns_base_addr + 0x1c;
+
+ /*
+ * Almost all Exynos-series of SoCs that run in secure mode don't need
+ * additional offset for every CPU, with Exynos4412 being the only
+ * exception.
+ */
+ if (soc_is_exynos4412())
+ boot_reg += 4 * cpu;
+
+ __raw_writel(boot_addr, boot_reg);
+ return 0;
+}
+
+static int exynos_cpu_suspend(unsigned long arg)
+{
+ flush_cache_all();
+ outer_flush_all();
+
+ exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
+
+ pr_info("Failed to suspend the system\n");
+ writel(0, sysram_ns_base_addr + EXYNOS_BOOT_FLAG);
+ return 1;
+}
+
+static int exynos_suspend(void)
+{
+ if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
+ exynos_save_cp15();
+
+ writel(EXYNOS_SLEEP_MAGIC, sysram_ns_base_addr + EXYNOS_BOOT_FLAG);
+ writel(virt_to_phys(exynos_cpu_resume_ns),
+ sysram_ns_base_addr + EXYNOS_BOOT_ADDR);
+
+ return cpu_suspend(0, exynos_cpu_suspend);
+}
+
+static int exynos_resume(void)
+{
+ writel(0, sysram_ns_base_addr + EXYNOS_BOOT_FLAG);
+
+ return 0;
+}
+
+static const struct firmware_ops exynos_firmware_ops = {
+ .do_idle = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_do_idle : NULL,
+ .set_cpu_boot_addr = exynos_set_cpu_boot_addr,
+ .cpu_boot = exynos_cpu_boot,
+ .suspend = IS_ENABLED(CONFIG_PM_SLEEP) ? exynos_suspend : NULL,
+ .resume = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL,
+};
+
+static void exynos_l2_write_sec(unsigned long val, unsigned reg)
+{
+ static int l2cache_enabled;
+
+ switch (reg) {
+ case L2X0_CTRL:
+ if (val & L2X0_CTRL_EN) {
+ /*
+ * Before the cache can be enabled, due to firmware
+ * design, SMC_CMD_L2X0INVALL must be called.
+ */
+ if (!l2cache_enabled) {
+ exynos_smc(SMC_CMD_L2X0INVALL, 0, 0, 0);
+ l2cache_enabled = 1;
+ }
+ } else {
+ l2cache_enabled = 0;
+ }
+ exynos_smc(SMC_CMD_L2X0CTRL, val, 0, 0);
+ break;
+
+ case L2X0_DEBUG_CTRL:
+ exynos_smc(SMC_CMD_L2X0DEBUG, val, 0, 0);
+ break;
+
+ default:
+ WARN_ONCE(1, "%s: ignoring write to reg 0x%x\n", __func__, reg);
+ }
+}
+
+static void exynos_l2_configure(const struct l2x0_regs *regs)
+{
+ exynos_smc(SMC_CMD_L2X0SETUP1, regs->tag_latency, regs->data_latency,
+ regs->prefetch_ctrl);
+ exynos_smc(SMC_CMD_L2X0SETUP2, regs->pwr_ctrl, regs->aux_ctrl, 0);
+}
+
+void __init exynos_firmware_init(void)
+{
+ struct device_node *nd;
+ const __be32 *addr;
+
+ nd = of_find_compatible_node(NULL, NULL,
+ "samsung,secure-firmware");
+ if (!nd)
+ return;
+
+ addr = of_get_address(nd, 0, NULL, NULL);
+ if (!addr) {
+ pr_err("%s: No address specified.\n", __func__);
+ return;
+ }
+
+ pr_info("Running under secure firmware.\n");
+
+ register_firmware_ops(&exynos_firmware_ops);
+
+ /*
+ * Exynos 4 SoCs (based on Cortex A9 and equipped with L2C-310),
+ * running under secure firmware, require certain registers of L2
+ * cache controller to be written in secure mode. Here .write_sec
+ * callback is provided to perform necessary SMC calls.
+ */
+ if (IS_ENABLED(CONFIG_CACHE_L2X0) &&
+ read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
+ outer_cache.write_sec = exynos_l2_write_sec;
+ outer_cache.configure = exynos_l2_configure;
+ }
+}
+
+#define REG_CPU_STATE_ADDR (sysram_ns_base_addr + 0x28)
+#define BOOT_MODE_MASK 0x1f
+
+void exynos_set_boot_flag(unsigned int cpu, unsigned int mode)
+{
+ unsigned int tmp;
+
+ tmp = __raw_readl(REG_CPU_STATE_ADDR + cpu * 4);
+
+ if (mode & BOOT_MODE_MASK)
+ tmp &= ~BOOT_MODE_MASK;
+
+ tmp |= mode;
+ __raw_writel(tmp, REG_CPU_STATE_ADDR + cpu * 4);
+}
+
+void exynos_clear_boot_flag(unsigned int cpu, unsigned int mode)
+{
+ unsigned int tmp;
+
+ tmp = __raw_readl(REG_CPU_STATE_ADDR + cpu * 4);
+ tmp &= ~mode;
+ __raw_writel(tmp, REG_CPU_STATE_ADDR + cpu * 4);
+}
diff --git a/arch/arm/mach-exynos/headsmp.S b/arch/arm/mach-exynos/headsmp.S
new file mode 100644
index 000000000..b54f9701e
--- /dev/null
+++ b/arch/arm/mach-exynos/headsmp.S
@@ -0,0 +1,40 @@
+/*
+ *
+ * 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>
+
+/*
+ * 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
+ENDPROC(exynos4_secondary_startup)
+
+ .align 2
+1: .long .
+ .long pen_release
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
new file mode 100644
index 000000000..de3ae59e1
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -0,0 +1,43 @@
+/*
+ * 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 EXYNOS_PA_CHIPID 0x10000000
+
+#define EXYNOS4_PA_CMU 0x10030000
+#define EXYNOS5_PA_CMU 0x10010000
+
+#define EXYNOS4_PA_DMC0 0x10400000
+#define EXYNOS4_PA_DMC1 0x10410000
+
+#define EXYNOS4_PA_COREPERI 0x10500000
+#define EXYNOS4_PA_L2CC 0x10502000
+
+#define EXYNOS4_PA_SROMC 0x12570000
+#define EXYNOS5_PA_SROMC 0x12250000
+
+/* Compatibility UART */
+
+#define EXYNOS5440_PA_UART0 0x000B0000
+
+#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
new file mode 100644
index 000000000..9bdf54795
--- /dev/null
+++ b/arch/arm/mach-exynos/mcpm-exynos.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * arch/arm/mach-exynos/mcpm-exynos.c
+ *
+ * Based on arch/arm/mach-vexpress/dcscb.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/arm-cci.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
+
+#include <asm/cputype.h>
+#include <asm/cp15.h>
+#include <asm/mcpm.h>
+
+#include "regs-pmu.h"
+#include "common.h"
+
+#define EXYNOS5420_CPUS_PER_CLUSTER 4
+#define EXYNOS5420_NR_CLUSTERS 2
+
+#define EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN BIT(9)
+#define EXYNOS5420_USE_ARM_CORE_DOWN_STATE BIT(29)
+#define EXYNOS5420_USE_L2_COMMON_UP_STATE BIT(30)
+
+static void __iomem *ns_sram_base_addr;
+
+/*
+ * The common v7_exit_coherency_flush API could not be used because of the
+ * Erratum 799270 workaround. This macro is the same as the common one (in
+ * arch/arm/include/asm/cacheflush.h) except for the erratum handling.
+ */
+#define exynos_v7_exit_coherency_flush(level) \
+ asm volatile( \
+ "stmfd sp!, {fp, ip}\n\t"\
+ "mrc p15, 0, r0, c1, c0, 0 @ get SCTLR\n\t" \
+ "bic r0, r0, #"__stringify(CR_C)"\n\t" \
+ "mcr p15, 0, r0, c1, c0, 0 @ set SCTLR\n\t" \
+ "isb\n\t"\
+ "bl v7_flush_dcache_"__stringify(level)"\n\t" \
+ "mrc p15, 0, r0, c1, c0, 1 @ get ACTLR\n\t" \
+ "bic r0, r0, #(1 << 6) @ disable local coherency\n\t" \
+ /* Dummy Load of a device register to avoid Erratum 799270 */ \
+ "ldr r4, [%0]\n\t" \
+ "and r4, r4, #0\n\t" \
+ "orr r0, r0, r4\n\t" \
+ "mcr p15, 0, r0, c1, c0, 1 @ set ACTLR\n\t" \
+ "isb\n\t" \
+ "dsb\n\t" \
+ "ldmfd sp!, {fp, ip}" \
+ : \
+ : "Ir" (pmu_base_addr + S5P_INFORM0) \
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ "r9", "r10", "lr", "memory")
+
+static int exynos_cpu_powerup(unsigned int cpu, unsigned int cluster)
+{
+ unsigned int cpunr = cpu + (cluster * EXYNOS5420_CPUS_PER_CLUSTER);
+
+ pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+ if (cpu >= EXYNOS5420_CPUS_PER_CLUSTER ||
+ cluster >= EXYNOS5420_NR_CLUSTERS)
+ return -EINVAL;
+
+ exynos_cpu_power_up(cpunr);
+ return 0;
+}
+
+static int exynos_cluster_powerup(unsigned int cluster)
+{
+ pr_debug("%s: cluster %u\n", __func__, cluster);
+ if (cluster >= EXYNOS5420_NR_CLUSTERS)
+ return -EINVAL;
+
+ exynos_cluster_power_up(cluster);
+ return 0;
+}
+
+static void exynos_cpu_powerdown_prepare(unsigned int cpu, unsigned int cluster)
+{
+ unsigned int cpunr = cpu + (cluster * EXYNOS5420_CPUS_PER_CLUSTER);
+
+ pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+ BUG_ON(cpu >= EXYNOS5420_CPUS_PER_CLUSTER ||
+ cluster >= EXYNOS5420_NR_CLUSTERS);
+ exynos_cpu_power_down(cpunr);
+}
+
+static void exynos_cluster_powerdown_prepare(unsigned int cluster)
+{
+ pr_debug("%s: cluster %u\n", __func__, cluster);
+ BUG_ON(cluster >= EXYNOS5420_NR_CLUSTERS);
+ exynos_cluster_power_down(cluster);
+}
+
+static void exynos_cpu_cache_disable(void)
+{
+ /* Disable and flush the local CPU cache. */
+ exynos_v7_exit_coherency_flush(louis);
+}
+
+static void exynos_cluster_cache_disable(void)
+{
+ if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A15) {
+ /*
+ * On the Cortex-A15 we need to disable
+ * L2 prefetching before flushing the cache.
+ */
+ asm volatile(
+ "mcr p15, 1, %0, c15, c0, 3\n\t"
+ "isb\n\t"
+ "dsb"
+ : : "r" (0x400));
+ }
+
+ /* Flush all cache levels for this cluster. */
+ exynos_v7_exit_coherency_flush(all);
+
+ /*
+ * Disable cluster-level coherency by masking
+ * incoming snoops and DVM messages:
+ */
+ cci_disable_port_by_cpu(read_cpuid_mpidr());
+}
+
+static int exynos_wait_for_powerdown(unsigned int cpu, unsigned int cluster)
+{
+ unsigned int tries = 100;
+ unsigned int cpunr = cpu + (cluster * EXYNOS5420_CPUS_PER_CLUSTER);
+
+ pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+ BUG_ON(cpu >= EXYNOS5420_CPUS_PER_CLUSTER ||
+ cluster >= EXYNOS5420_NR_CLUSTERS);
+
+ /* Wait for the core state to be OFF */
+ while (tries--) {
+ if ((exynos_cpu_power_state(cpunr) == 0))
+ return 0; /* success: the CPU is halted */
+
+ /* Otherwise, wait and retry: */
+ msleep(1);
+ }
+
+ return -ETIMEDOUT; /* timeout */
+}
+
+static void exynos_cpu_is_up(unsigned int cpu, unsigned int cluster)
+{
+ /* especially when resuming: make sure power control is set */
+ exynos_cpu_powerup(cpu, cluster);
+}
+
+static const struct mcpm_platform_ops exynos_power_ops = {
+ .cpu_powerup = exynos_cpu_powerup,
+ .cluster_powerup = exynos_cluster_powerup,
+ .cpu_powerdown_prepare = exynos_cpu_powerdown_prepare,
+ .cluster_powerdown_prepare = exynos_cluster_powerdown_prepare,
+ .cpu_cache_disable = exynos_cpu_cache_disable,
+ .cluster_cache_disable = exynos_cluster_cache_disable,
+ .wait_for_powerdown = exynos_wait_for_powerdown,
+ .cpu_is_up = exynos_cpu_is_up,
+};
+
+/*
+ * Enable cluster-level coherency, in preparation for turning on the MMU.
+ */
+static void __naked exynos_pm_power_up_setup(unsigned int affinity_level)
+{
+ asm volatile ("\n"
+ "cmp r0, #1\n"
+ "bxne lr\n"
+ "b cci_enable_port_for_self");
+}
+
+static const struct of_device_id exynos_dt_mcpm_match[] = {
+ { .compatible = "samsung,exynos5420" },
+ { .compatible = "samsung,exynos5800" },
+ {},
+};
+
+static void exynos_mcpm_setup_entry_point(void)
+{
+ /*
+ * U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr
+ * as part of secondary_cpu_start(). Let's redirect it to the
+ * mcpm_entry_point(). This is done during both secondary boot-up as
+ * well as system resume.
+ */
+ __raw_writel(0xe59f0000, ns_sram_base_addr); /* ldr r0, [pc, #0] */
+ __raw_writel(0xe12fff10, ns_sram_base_addr + 4); /* bx r0 */
+ __raw_writel(virt_to_phys(mcpm_entry_point), ns_sram_base_addr + 8);
+}
+
+static struct syscore_ops exynos_mcpm_syscore_ops = {
+ .resume = exynos_mcpm_setup_entry_point,
+};
+
+static int __init exynos_mcpm_init(void)
+{
+ struct device_node *node;
+ unsigned int value, i;
+ int ret;
+
+ node = of_find_matching_node(NULL, exynos_dt_mcpm_match);
+ if (!node)
+ return -ENODEV;
+ of_node_put(node);
+
+ if (!cci_probed())
+ return -ENODEV;
+
+ node = of_find_compatible_node(NULL, NULL,
+ "samsung,exynos4210-sysram-ns");
+ if (!node)
+ return -ENODEV;
+
+ ns_sram_base_addr = of_iomap(node, 0);
+ of_node_put(node);
+ if (!ns_sram_base_addr) {
+ pr_err("failed to map non-secure iRAM base address\n");
+ return -ENOMEM;
+ }
+
+ /*
+ * To increase the stability of KFC reset we need to program
+ * the PMU SPARE3 register
+ */
+ pmu_raw_writel(EXYNOS5420_SWRESET_KFC_SEL, S5P_PMU_SPARE3);
+
+ ret = mcpm_platform_register(&exynos_power_ops);
+ if (!ret)
+ ret = mcpm_sync_init(exynos_pm_power_up_setup);
+ if (!ret)
+ ret = mcpm_loopback(exynos_cluster_cache_disable); /* turn on the CCI */
+ if (ret) {
+ iounmap(ns_sram_base_addr);
+ return ret;
+ }
+
+ mcpm_smp_set_ops();
+
+ pr_info("Exynos MCPM support installed\n");
+
+ /*
+ * On Exynos5420/5800 for the A15 and A7 clusters:
+ *
+ * EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN ensures that all the cores
+ * in a cluster are turned off before turning off the cluster L2.
+ *
+ * EXYNOS5420_USE_ARM_CORE_DOWN_STATE ensures that a cores is powered
+ * off before waking it up.
+ *
+ * EXYNOS5420_USE_L2_COMMON_UP_STATE ensures that cluster L2 will be
+ * turned on before the first man is powered up.
+ */
+ for (i = 0; i < EXYNOS5420_NR_CLUSTERS; i++) {
+ value = pmu_raw_readl(EXYNOS_COMMON_OPTION(i));
+ value |= EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN |
+ EXYNOS5420_USE_ARM_CORE_DOWN_STATE |
+ EXYNOS5420_USE_L2_COMMON_UP_STATE;
+ pmu_raw_writel(value, EXYNOS_COMMON_OPTION(i));
+ }
+
+ exynos_mcpm_setup_entry_point();
+
+ register_syscore_ops(&exynos_mcpm_syscore_ops);
+
+ return ret;
+}
+
+early_initcall(exynos_mcpm_init);
diff --git a/arch/arm/mach-exynos/mfc.h b/arch/arm/mach-exynos/mfc.h
new file mode 100644
index 000000000..dec93cd5b
--- /dev/null
+++ b/arch/arm/mach-exynos/mfc.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Co.Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __MACH_EXYNOS_MFC_H
+#define __MACH_EXYNOS_MFC_H __FILE__
+
+int __init s5p_fdt_alloc_mfc_mem(unsigned long node, const char *uname,
+ int depth, void *data);
+
+#endif /* __MACH_EXYNOS_MFC_H */
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
new file mode 100644
index 000000000..a825bca2a
--- /dev/null
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -0,0 +1,458 @@
+ /*
+ * 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 <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+#include <asm/firmware.h>
+
+#include <mach/map.h>
+
+#include "common.h"
+#include "regs-pmu.h"
+
+extern void exynos4_secondary_startup(void);
+
+#ifdef CONFIG_HOTPLUG_CPU
+static inline void cpu_leave_lowpower(u32 core_id)
+{
+ 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)
+{
+ u32 mpidr = cpu_logical_map(cpu);
+ u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+
+ for (;;) {
+
+ /* Turn the CPU off on next WFI instruction. */
+ exynos_cpu_power_down(core_id);
+
+ wfi();
+
+ if (pen_release == core_id) {
+ /*
+ * 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)++;
+ }
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
+/**
+ * exynos_core_power_down : power down the specified cpu
+ * @cpu : the cpu to power down
+ *
+ * Power down the specified cpu. The sequence must be finished by a
+ * call to cpu_do_idle()
+ *
+ */
+void exynos_cpu_power_down(int cpu)
+{
+ u32 core_conf;
+
+ if (cpu == 0 && (soc_is_exynos5420() || soc_is_exynos5800())) {
+ /*
+ * Bypass power down for CPU0 during suspend. Check for
+ * the SYS_PWR_REG value to decide if we are suspending
+ * the system.
+ */
+ int val = pmu_raw_readl(EXYNOS5_ARM_CORE0_SYS_PWR_REG);
+
+ if (!(val & S5P_CORE_LOCAL_PWR_EN))
+ return;
+ }
+
+ core_conf = pmu_raw_readl(EXYNOS_ARM_CORE_CONFIGURATION(cpu));
+ core_conf &= ~S5P_CORE_LOCAL_PWR_EN;
+ pmu_raw_writel(core_conf, EXYNOS_ARM_CORE_CONFIGURATION(cpu));
+}
+
+/**
+ * exynos_cpu_power_up : power up the specified cpu
+ * @cpu : the cpu to power up
+ *
+ * Power up the specified cpu
+ */
+void exynos_cpu_power_up(int cpu)
+{
+ u32 core_conf = S5P_CORE_LOCAL_PWR_EN;
+
+ if (soc_is_exynos3250())
+ core_conf |= S5P_CORE_AUTOWAKEUP_EN;
+
+ pmu_raw_writel(core_conf,
+ EXYNOS_ARM_CORE_CONFIGURATION(cpu));
+}
+
+/**
+ * exynos_cpu_power_state : returns the power state of the cpu
+ * @cpu : the cpu to retrieve the power state from
+ *
+ */
+int exynos_cpu_power_state(int cpu)
+{
+ return (pmu_raw_readl(EXYNOS_ARM_CORE_STATUS(cpu)) &
+ S5P_CORE_LOCAL_PWR_EN);
+}
+
+/**
+ * exynos_cluster_power_down : power down the specified cluster
+ * @cluster : the cluster to power down
+ */
+void exynos_cluster_power_down(int cluster)
+{
+ pmu_raw_writel(0, EXYNOS_COMMON_CONFIGURATION(cluster));
+}
+
+/**
+ * exynos_cluster_power_up : power up the specified cluster
+ * @cluster : the cluster to power up
+ */
+void exynos_cluster_power_up(int cluster)
+{
+ pmu_raw_writel(S5P_CORE_LOCAL_PWR_EN,
+ EXYNOS_COMMON_CONFIGURATION(cluster));
+}
+
+/**
+ * exynos_cluster_power_state : returns the power state of the cluster
+ * @cluster : the cluster to retrieve the power state from
+ *
+ */
+int exynos_cluster_power_state(int cluster)
+{
+ return (pmu_raw_readl(EXYNOS_COMMON_STATUS(cluster)) &
+ S5P_CORE_LOCAL_PWR_EN);
+}
+
+void __iomem *cpu_boot_reg_base(void)
+{
+ if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
+ return pmu_base_addr + S5P_INFORM5;
+ return sysram_base_addr;
+}
+
+static inline void __iomem *cpu_boot_reg(int cpu)
+{
+ void __iomem *boot_reg;
+
+ boot_reg = cpu_boot_reg_base();
+ if (!boot_reg)
+ return ERR_PTR(-ENODEV);
+ if (soc_is_exynos4412())
+ boot_reg += 4*cpu;
+ else if (soc_is_exynos5420() || soc_is_exynos5800())
+ boot_reg += 4;
+ return boot_reg;
+}
+
+/*
+ * Set wake up by local power mode and execute software reset for given core.
+ *
+ * Currently this is needed only when booting secondary CPU on Exynos3250.
+ */
+static void exynos_core_restart(u32 core_id)
+{
+ u32 val;
+
+ if (!of_machine_is_compatible("samsung,exynos3250"))
+ return;
+
+ while (!pmu_raw_readl(S5P_PMU_SPARE2))
+ udelay(10);
+ udelay(10);
+
+ val = pmu_raw_readl(EXYNOS_ARM_CORE_STATUS(core_id));
+ val |= S5P_CORE_WAKEUP_FROM_LOCAL_CFG;
+ pmu_raw_writel(val, EXYNOS_ARM_CORE_STATUS(core_id));
+
+ pr_info("CPU%u: Software reset\n", core_id);
+ pmu_raw_writel(EXYNOS_CORE_PO_RESET(core_id), EXYNOS_SWRESET);
+}
+
+/*
+ * 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();
+ sync_cache_w(&pen_release);
+}
+
+static void __iomem *scu_base_addr(void)
+{
+ return (void __iomem *)(S5P_VA_SCU);
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+static void exynos_secondary_init(unsigned int cpu)
+{
+ /*
+ * 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);
+}
+
+static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ unsigned long timeout;
+ u32 mpidr = cpu_logical_map(cpu);
+ u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ int ret = -ENOSYS;
+
+ /*
+ * 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 core ID, whereas
+ * "cpu" is Linux's internal ID.
+ */
+ write_pen_release(core_id);
+
+ if (!exynos_cpu_power_state(core_id)) {
+ exynos_cpu_power_up(core_id);
+ timeout = 10;
+
+ /* wait max 10 ms until cpu1 is on */
+ while (exynos_cpu_power_state(core_id)
+ != S5P_CORE_LOCAL_PWR_EN) {
+ if (timeout-- == 0)
+ break;
+
+ mdelay(1);
+ }
+
+ if (timeout == 0) {
+ printk(KERN_ERR "cpu1 power enable failed");
+ spin_unlock(&boot_lock);
+ return -ETIMEDOUT;
+ }
+ }
+
+ exynos_core_restart(core_id);
+
+ /*
+ * 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.
+ */
+
+ timeout = jiffies + (1 * HZ);
+ while (time_before(jiffies, timeout)) {
+ unsigned long boot_addr;
+
+ smp_rmb();
+
+ boot_addr = virt_to_phys(exynos4_secondary_startup);
+
+ /*
+ * Try to set boot address using firmware first
+ * and fall back to boot register if it fails.
+ */
+ ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr);
+ if (ret && ret != -ENOSYS)
+ goto fail;
+ if (ret == -ENOSYS) {
+ void __iomem *boot_reg = cpu_boot_reg(core_id);
+
+ if (IS_ERR(boot_reg)) {
+ ret = PTR_ERR(boot_reg);
+ goto fail;
+ }
+ __raw_writel(boot_addr, boot_reg);
+ }
+
+ call_firmware_op(cpu_boot, core_id);
+
+ if (soc_is_exynos3250())
+ dsb_sev();
+ else
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+ 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
+ */
+fail:
+ spin_unlock(&boot_lock);
+
+ return pen_release != -1 ? ret : 0;
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+
+static void __init exynos_smp_init_cpus(void)
+{
+ void __iomem *scu_base = scu_base_addr();
+ unsigned int i, ncores;
+
+ if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
+ ncores = scu_base ? scu_get_core_count(scu_base) : 1;
+ else
+ /*
+ * CPU Nodes are passed thru DT and set_cpu_possible
+ * is set by "arm_dt_init_cpu_maps".
+ */
+ return;
+
+ /* sanity check */
+ if (ncores > nr_cpu_ids) {
+ pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
+ ncores, nr_cpu_ids);
+ ncores = nr_cpu_ids;
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+}
+
+static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int i;
+
+ exynos_sysram_init();
+
+ exynos_set_delayed_reset_assertion(true);
+
+ if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
+ 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.
+ *
+ * Try using firmware operation first and fall back to
+ * boot register if it fails.
+ */
+ for (i = 1; i < max_cpus; ++i) {
+ unsigned long boot_addr;
+ u32 mpidr;
+ u32 core_id;
+ int ret;
+
+ mpidr = cpu_logical_map(i);
+ core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ boot_addr = virt_to_phys(exynos4_secondary_startup);
+
+ ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr);
+ if (ret && ret != -ENOSYS)
+ break;
+ if (ret == -ENOSYS) {
+ void __iomem *boot_reg = cpu_boot_reg(core_id);
+
+ if (IS_ERR(boot_reg))
+ break;
+ __raw_writel(boot_addr, boot_reg);
+ }
+ }
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+static void exynos_cpu_die(unsigned int cpu)
+{
+ int spurious = 0;
+ u32 mpidr = cpu_logical_map(cpu);
+ u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+
+ v7_exit_coherency_flush(louis);
+
+ platform_do_lowpower(cpu, &spurious);
+
+ /*
+ * bring this CPU back into the world of cache
+ * coherency, and then restore interrupts
+ */
+ cpu_leave_lowpower(core_id);
+
+ if (spurious)
+ pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
+struct smp_operations exynos_smp_ops __initdata = {
+ .smp_init_cpus = exynos_smp_init_cpus,
+ .smp_prepare_cpus = exynos_smp_prepare_cpus,
+ .smp_secondary_init = exynos_secondary_init,
+ .smp_boot_secondary = exynos_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = exynos_cpu_die,
+#endif
+};
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
new file mode 100644
index 000000000..cc75ab448
--- /dev/null
+++ b/arch/arm/mach-exynos/pm.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - 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/cpu_pm.h>
+#include <linux/io.h>
+#include <linux/err.h>
+
+#include <asm/firmware.h>
+#include <asm/smp_scu.h>
+#include <asm/suspend.h>
+
+#include <mach/map.h>
+
+#include <plat/pm-common.h>
+
+#include "common.h"
+#include "exynos-pmu.h"
+#include "regs-pmu.h"
+
+static inline void __iomem *exynos_boot_vector_addr(void)
+{
+ if (samsung_rev() == EXYNOS4210_REV_1_1)
+ return pmu_base_addr + S5P_INFORM7;
+ else if (samsung_rev() == EXYNOS4210_REV_1_0)
+ return sysram_base_addr + 0x24;
+ return pmu_base_addr + S5P_INFORM0;
+}
+
+static inline void __iomem *exynos_boot_vector_flag(void)
+{
+ if (samsung_rev() == EXYNOS4210_REV_1_1)
+ return pmu_base_addr + S5P_INFORM6;
+ else if (samsung_rev() == EXYNOS4210_REV_1_0)
+ return sysram_base_addr + 0x20;
+ return pmu_base_addr + S5P_INFORM1;
+}
+
+#define S5P_CHECK_AFTR 0xFCBA0D10
+
+/* For Cortex-A9 Diagnostic and Power control register */
+static unsigned int save_arm_register[2];
+
+void exynos_cpu_save_register(void)
+{
+ unsigned long tmp;
+
+ /* Save Power control register */
+ asm ("mrc p15, 0, %0, c15, c0, 0"
+ : "=r" (tmp) : : "cc");
+
+ save_arm_register[0] = tmp;
+
+ /* Save Diagnostic register */
+ asm ("mrc p15, 0, %0, c15, c0, 1"
+ : "=r" (tmp) : : "cc");
+
+ save_arm_register[1] = tmp;
+}
+
+void exynos_cpu_restore_register(void)
+{
+ unsigned long tmp;
+
+ /* Restore Power control register */
+ tmp = save_arm_register[0];
+
+ asm volatile ("mcr p15, 0, %0, c15, c0, 0"
+ : : "r" (tmp)
+ : "cc");
+
+ /* Restore Diagnostic register */
+ tmp = save_arm_register[1];
+
+ asm volatile ("mcr p15, 0, %0, c15, c0, 1"
+ : : "r" (tmp)
+ : "cc");
+}
+
+void exynos_pm_central_suspend(void)
+{
+ unsigned long tmp;
+
+ /* Setting Central Sequence Register for power down mode */
+ tmp = pmu_raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
+ tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
+ pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
+}
+
+int exynos_pm_central_resume(void)
+{
+ unsigned long tmp;
+
+ /*
+ * If PMU failed while entering sleep mode, WFI will be
+ * ignored by PMU and then exiting cpu_do_idle().
+ * S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically
+ * in this situation.
+ */
+ tmp = pmu_raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
+ if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) {
+ tmp |= S5P_CENTRAL_LOWPWR_CFG;
+ pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
+ /* clear the wakeup state register */
+ pmu_raw_writel(0x0, S5P_WAKEUP_STAT);
+ /* No need to perform below restore code */
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
+static void exynos_set_wakeupmask(long mask)
+{
+ pmu_raw_writel(mask, S5P_WAKEUP_MASK);
+ if (soc_is_exynos3250())
+ pmu_raw_writel(0x0, S5P_WAKEUP_MASK2);
+}
+
+static void exynos_cpu_set_boot_vector(long flags)
+{
+ __raw_writel(virt_to_phys(exynos_cpu_resume),
+ exynos_boot_vector_addr());
+ __raw_writel(flags, exynos_boot_vector_flag());
+}
+
+static int exynos_aftr_finisher(unsigned long flags)
+{
+ int ret;
+
+ exynos_set_wakeupmask(soc_is_exynos3250() ? 0x40003ffe : 0x0000ff3e);
+ /* Set value of power down register for aftr mode */
+ exynos_sys_powerdown_conf(SYS_AFTR);
+
+ ret = call_firmware_op(do_idle, FW_DO_IDLE_AFTR);
+ if (ret == -ENOSYS) {
+ if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
+ exynos_cpu_save_register();
+ exynos_cpu_set_boot_vector(S5P_CHECK_AFTR);
+ cpu_do_idle();
+ }
+
+ return 1;
+}
+
+void exynos_enter_aftr(void)
+{
+ unsigned int cpuid = smp_processor_id();
+
+ cpu_pm_enter();
+
+ if (soc_is_exynos3250())
+ exynos_set_boot_flag(cpuid, C2_STATE);
+
+ exynos_pm_central_suspend();
+
+ if (of_machine_is_compatible("samsung,exynos4212") ||
+ of_machine_is_compatible("samsung,exynos4412")) {
+ /* Setting SEQ_OPTION register */
+ pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0,
+ S5P_CENTRAL_SEQ_OPTION);
+ }
+
+ cpu_suspend(0, exynos_aftr_finisher);
+
+ if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
+ scu_enable(S5P_VA_SCU);
+ if (call_firmware_op(resume) == -ENOSYS)
+ exynos_cpu_restore_register();
+ }
+
+ exynos_pm_central_resume();
+
+ if (soc_is_exynos3250())
+ exynos_clear_boot_flag(cpuid, C2_STATE);
+
+ cpu_pm_exit();
+}
+
+#if defined(CONFIG_SMP) && defined(CONFIG_ARM_EXYNOS_CPUIDLE)
+static atomic_t cpu1_wakeup = ATOMIC_INIT(0);
+
+static int exynos_cpu0_enter_aftr(void)
+{
+ int ret = -1;
+
+ /*
+ * If the other cpu is powered on, we have to power it off, because
+ * the AFTR state won't work otherwise
+ */
+ if (cpu_online(1)) {
+ /*
+ * We reach a sync point with the coupled idle state, we know
+ * the other cpu will power down itself or will abort the
+ * sequence, let's wait for one of these to happen
+ */
+ while (exynos_cpu_power_state(1)) {
+ /*
+ * The other cpu may skip idle and boot back
+ * up again
+ */
+ if (atomic_read(&cpu1_wakeup))
+ goto abort;
+
+ /*
+ * The other cpu may bounce through idle and
+ * boot back up again, getting stuck in the
+ * boot rom code
+ */
+ if (__raw_readl(cpu_boot_reg_base()) == 0)
+ goto abort;
+
+ cpu_relax();
+ }
+ }
+
+ exynos_enter_aftr();
+ ret = 0;
+
+abort:
+ if (cpu_online(1)) {
+ /*
+ * Set the boot vector to something non-zero
+ */
+ __raw_writel(virt_to_phys(exynos_cpu_resume),
+ cpu_boot_reg_base());
+ dsb();
+
+ /*
+ * Turn on cpu1 and wait for it to be on
+ */
+ exynos_cpu_power_up(1);
+ while (exynos_cpu_power_state(1) != S5P_CORE_LOCAL_PWR_EN)
+ cpu_relax();
+
+ while (!atomic_read(&cpu1_wakeup)) {
+ /*
+ * Poke cpu1 out of the boot rom
+ */
+ __raw_writel(virt_to_phys(exynos_cpu_resume),
+ cpu_boot_reg_base());
+
+ arch_send_wakeup_ipi_mask(cpumask_of(1));
+ }
+ }
+
+ return ret;
+}
+
+static int exynos_wfi_finisher(unsigned long flags)
+{
+ cpu_do_idle();
+
+ return -1;
+}
+
+static int exynos_cpu1_powerdown(void)
+{
+ int ret = -1;
+
+ /*
+ * Idle sequence for cpu1
+ */
+ if (cpu_pm_enter())
+ goto cpu1_aborted;
+
+ /*
+ * Turn off cpu 1
+ */
+ exynos_cpu_power_down(1);
+
+ ret = cpu_suspend(0, exynos_wfi_finisher);
+
+ cpu_pm_exit();
+
+cpu1_aborted:
+ dsb();
+ /*
+ * Notify cpu 0 that cpu 1 is awake
+ */
+ atomic_set(&cpu1_wakeup, 1);
+
+ return ret;
+}
+
+static void exynos_pre_enter_aftr(void)
+{
+ __raw_writel(virt_to_phys(exynos_cpu_resume), cpu_boot_reg_base());
+}
+
+static void exynos_post_enter_aftr(void)
+{
+ atomic_set(&cpu1_wakeup, 0);
+}
+
+struct cpuidle_exynos_data cpuidle_coupled_exynos_data = {
+ .cpu0_enter_aftr = exynos_cpu0_enter_aftr,
+ .cpu1_powerdown = exynos_cpu1_powerdown,
+ .pre_enter_aftr = exynos_pre_enter_aftr,
+ .post_enter_aftr = exynos_post_enter_aftr,
+};
+#endif /* CONFIG_SMP && CONFIG_ARM_EXYNOS_CPUIDLE */
diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
new file mode 100644
index 000000000..a9686535f
--- /dev/null
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -0,0 +1,213 @@
+/*
+ * Exynos Generic power domain support.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Implementation of Exynos specific power domain control which is used in
+ * conjunction with runtime-pm. Support for both device-tree and non-device-tree
+ * based power domain support is included.
+ *
+ * This program is free software; you can redistribute it 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/slab.h>
+#include <linux/pm_domain.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/sched.h>
+
+#define INT_LOCAL_PWR_EN 0x7
+#define MAX_CLK_PER_DOMAIN 4
+
+/*
+ * Exynos specific wrapper around the generic power domain
+ */
+struct exynos_pm_domain {
+ void __iomem *base;
+ char const *name;
+ bool is_off;
+ struct generic_pm_domain pd;
+ struct clk *oscclk;
+ struct clk *clk[MAX_CLK_PER_DOMAIN];
+ struct clk *pclk[MAX_CLK_PER_DOMAIN];
+ struct clk *asb_clk[MAX_CLK_PER_DOMAIN];
+};
+
+static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
+{
+ struct exynos_pm_domain *pd;
+ void __iomem *base;
+ u32 timeout, pwr;
+ char *op;
+ int i;
+
+ pd = container_of(domain, struct exynos_pm_domain, pd);
+ base = pd->base;
+
+ for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
+ if (IS_ERR(pd->asb_clk[i]))
+ break;
+ clk_prepare_enable(pd->asb_clk[i]);
+ }
+
+ /* Set oscclk before powering off a domain*/
+ if (!power_on) {
+ for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
+ if (IS_ERR(pd->clk[i]))
+ break;
+ if (clk_set_parent(pd->clk[i], pd->oscclk))
+ pr_err("%s: error setting oscclk as parent to clock %d\n",
+ pd->name, i);
+ }
+ }
+
+ pwr = power_on ? INT_LOCAL_PWR_EN : 0;
+ __raw_writel(pwr, base);
+
+ /* Wait max 1ms */
+ timeout = 10;
+
+ while ((__raw_readl(base + 0x4) & INT_LOCAL_PWR_EN) != pwr) {
+ if (!timeout) {
+ op = (power_on) ? "enable" : "disable";
+ pr_err("Power domain %s %s failed\n", domain->name, op);
+ return -ETIMEDOUT;
+ }
+ timeout--;
+ cpu_relax();
+ usleep_range(80, 100);
+ }
+
+ /* Restore clocks after powering on a domain*/
+ if (power_on) {
+ for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
+ if (IS_ERR(pd->clk[i]))
+ break;
+ if (clk_set_parent(pd->clk[i], pd->pclk[i]))
+ pr_err("%s: error setting parent to clock%d\n",
+ pd->name, i);
+ }
+ }
+
+ for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
+ if (IS_ERR(pd->asb_clk[i]))
+ break;
+ clk_disable_unprepare(pd->asb_clk[i]);
+ }
+
+ return 0;
+}
+
+static int exynos_pd_power_on(struct generic_pm_domain *domain)
+{
+ return exynos_pd_power(domain, true);
+}
+
+static int exynos_pd_power_off(struct generic_pm_domain *domain)
+{
+ return exynos_pd_power(domain, false);
+}
+
+static __init int exynos4_pm_init_power_domain(void)
+{
+ struct platform_device *pdev;
+ struct device_node *np;
+
+ for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
+ struct exynos_pm_domain *pd;
+ int on, i;
+ struct device *dev;
+
+ pdev = of_find_device_by_node(np);
+ dev = &pdev->dev;
+
+ pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+ if (!pd) {
+ pr_err("%s: failed to allocate memory for domain\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ pd->pd.name = kstrdup(dev_name(dev), GFP_KERNEL);
+ pd->name = pd->pd.name;
+ pd->base = of_iomap(np, 0);
+ pd->pd.power_off = exynos_pd_power_off;
+ pd->pd.power_on = exynos_pd_power_on;
+
+ for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
+ char clk_name[8];
+
+ snprintf(clk_name, sizeof(clk_name), "asb%d", i);
+ pd->asb_clk[i] = clk_get(dev, clk_name);
+ if (IS_ERR(pd->asb_clk[i]))
+ break;
+ }
+
+ pd->oscclk = clk_get(dev, "oscclk");
+ if (IS_ERR(pd->oscclk))
+ goto no_clk;
+
+ for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
+ char clk_name[8];
+
+ snprintf(clk_name, sizeof(clk_name), "clk%d", i);
+ pd->clk[i] = clk_get(dev, clk_name);
+ if (IS_ERR(pd->clk[i]))
+ break;
+ snprintf(clk_name, sizeof(clk_name), "pclk%d", i);
+ pd->pclk[i] = clk_get(dev, clk_name);
+ if (IS_ERR(pd->pclk[i])) {
+ clk_put(pd->clk[i]);
+ pd->clk[i] = ERR_PTR(-EINVAL);
+ break;
+ }
+ }
+
+ if (IS_ERR(pd->clk[0]))
+ clk_put(pd->oscclk);
+
+no_clk:
+ on = __raw_readl(pd->base + 0x4) & INT_LOCAL_PWR_EN;
+
+ pm_genpd_init(&pd->pd, NULL, !on);
+ of_genpd_add_provider_simple(np, &pd->pd);
+ }
+
+ /* Assign the child power domains to their parents */
+ for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
+ struct generic_pm_domain *child_domain, *parent_domain;
+ struct of_phandle_args args;
+
+ args.np = np;
+ args.args_count = 0;
+ child_domain = of_genpd_get_from_provider(&args);
+ if (IS_ERR(child_domain))
+ continue;
+
+ if (of_parse_phandle_with_args(np, "power-domains",
+ "#power-domain-cells", 0, &args) != 0)
+ continue;
+
+ parent_domain = of_genpd_get_from_provider(&args);
+ if (IS_ERR(parent_domain))
+ continue;
+
+ if (pm_genpd_add_subdomain(parent_domain, child_domain))
+ pr_warn("%s failed to add subdomain: %s\n",
+ parent_domain->name, child_domain->name);
+ else
+ pr_info("%s has as child subdomain: %s.\n",
+ parent_domain->name, child_domain->name);
+ of_node_put(np);
+ }
+
+ return 0;
+}
+arch_initcall(exynos4_pm_init_power_domain);
diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c
new file mode 100644
index 000000000..c15761ca2
--- /dev/null
+++ b/arch/arm/mach-exynos/pmu.c
@@ -0,0 +1,1005 @@
+/*
+ * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS - CPU PMU(Power Management Unit) support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+
+
+#include "exynos-pmu.h"
+#include "regs-pmu.h"
+
+#define PMU_TABLE_END (-1U)
+
+struct exynos_pmu_conf {
+ unsigned int offset;
+ u8 val[NUM_SYS_POWERDOWN];
+};
+
+struct exynos_pmu_data {
+ const struct exynos_pmu_conf *pmu_config;
+ const struct exynos_pmu_conf *pmu_config_extra;
+
+ void (*pmu_init)(void);
+ void (*powerdown_conf)(enum sys_powerdown);
+ void (*powerdown_conf_extra)(enum sys_powerdown);
+};
+
+struct exynos_pmu_context {
+ struct device *dev;
+ const struct exynos_pmu_data *pmu_data;
+};
+
+static void __iomem *pmu_base_addr;
+static struct exynos_pmu_context *pmu_context;
+
+static inline void pmu_raw_writel(u32 val, u32 offset)
+{
+ writel_relaxed(val, pmu_base_addr + offset);
+}
+
+static inline u32 pmu_raw_readl(u32 offset)
+{
+ return readl_relaxed(pmu_base_addr + offset);
+}
+
+static struct exynos_pmu_conf exynos3250_pmu_config[] = {
+ /* { .offset = offset, .val = { AFTR, W-AFTR, SLEEP } */
+ { EXYNOS3_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
+ { EXYNOS3_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS3_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS3_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
+ { EXYNOS3_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS3_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS3_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS3_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS3_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
+ { EXYNOS3_ARM_L2_SYS_PWR_REG, { 0x0, 0x0, 0x3} },
+ { EXYNOS3_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS3_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS3_LPDDR_PHY_DLL_LOCK_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS3_CMU_ACLKSTOP_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_CMU_SCLKSTOP_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_CMU_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_UPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS3_EPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_CMU_CLKSTOP_CAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_CMU_CLKSTOP_LCD0_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_CMU_CLKSTOP_MAUDIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_CMU_RESET_CAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_CMU_RESET_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_CMU_RESET_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_CMU_RESET_LCD0_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_CMU_RESET_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_CMU_RESET_MAUDIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS3_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS3_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS3_TOP_PWR_SYS_PWR_REG, { 0x3, 0x3, 0x3} },
+ { EXYNOS3_TOP_BUS_COREBLK_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS3_TOP_RETENTION_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS3_TOP_PWR_COREBLK_SYS_PWR_REG, { 0x3, 0x3, 0x3} },
+ { EXYNOS3_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS3_LOGIC_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_OSCCLK_GATE_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS3_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_PAD_RETENTION_MAUDIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_PAD_RETENTION_GPIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_PAD_RETENTION_MMC0_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_PAD_RETENTION_MMC1_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_PAD_RETENTION_MMC2_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_PAD_RETENTION_JTAG_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_EXT_REGULATOR_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_GPIO_MODE_MAUDIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_TOP_ASB_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_TOP_ASB_ISOLATION_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS3_CAM_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS3_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS3_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS3_LCD0_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS3_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS3_MAUDIO_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS3_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { PMU_TABLE_END,},
+};
+
+static const struct exynos_pmu_conf exynos4210_pmu_config[] = {
+ /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */
+ { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } },
+ { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } },
+ { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } },
+ { S5P_ARM_CORE1_LOWPWR, { 0x0, 0x0, 0x2 } },
+ { S5P_DIS_IRQ_CORE1, { 0x0, 0x0, 0x0 } },
+ { S5P_DIS_IRQ_CENTRAL1, { 0x0, 0x0, 0x0 } },
+ { S5P_ARM_COMMON_LOWPWR, { 0x0, 0x0, 0x2 } },
+ { S5P_L2_0_LOWPWR, { 0x2, 0x2, 0x3 } },
+ { S5P_L2_1_LOWPWR, { 0x2, 0x2, 0x3 } },
+ { S5P_CMU_ACLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_SCLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_RESET_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_APLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_MPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_VPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_EPLL_SYSCLK_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_RESET_GPSALIVE_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_CLKSTOP_CAM_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_CLKSTOP_TV_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_CLKSTOP_MFC_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_CLKSTOP_G3D_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_CLKSTOP_LCD0_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_CLKSTOP_LCD1_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_CLKSTOP_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_CLKSTOP_GPS_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_RESET_CAM_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_RESET_TV_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_RESET_MFC_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_RESET_G3D_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_RESET_LCD0_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_RESET_LCD1_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_RESET_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_RESET_GPS_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_TOP_BUS_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_TOP_RETENTION_LOWPWR, { 0x1, 0x0, 0x1 } },
+ { S5P_TOP_PWR_LOWPWR, { 0x3, 0x0, 0x3 } },
+ { S5P_LOGIC_RESET_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_ONENAND_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_MODIMIF_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_G2D_ACP_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_USBOTG_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_HSMMC_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_CSSYS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_SECSS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_PCIE_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_SATA_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_DRAM_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_PAD_RETENTION_GPIO_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_UART_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_MMCA_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_MMCB_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_EBIA_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_EBIB_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_ISOLATION_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_ALV_SEL_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_XUSBXTI_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_XXTI_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_EXT_REGULATOR_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_GPIO_MODE_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_GPIO_MODE_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CAM_LOWPWR, { 0x7, 0x0, 0x0 } },
+ { S5P_TV_LOWPWR, { 0x7, 0x0, 0x0 } },
+ { S5P_MFC_LOWPWR, { 0x7, 0x0, 0x0 } },
+ { S5P_G3D_LOWPWR, { 0x7, 0x0, 0x0 } },
+ { S5P_LCD0_LOWPWR, { 0x7, 0x0, 0x0 } },
+ { S5P_LCD1_LOWPWR, { 0x7, 0x0, 0x0 } },
+ { S5P_MAUDIO_LOWPWR, { 0x7, 0x7, 0x0 } },
+ { S5P_GPS_LOWPWR, { 0x7, 0x0, 0x0 } },
+ { S5P_GPS_ALIVE_LOWPWR, { 0x7, 0x0, 0x0 } },
+ { PMU_TABLE_END,},
+};
+
+static const struct exynos_pmu_conf exynos4x12_pmu_config[] = {
+ { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } },
+ { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } },
+ { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } },
+ { S5P_ARM_CORE1_LOWPWR, { 0x0, 0x0, 0x2 } },
+ { S5P_DIS_IRQ_CORE1, { 0x0, 0x0, 0x0 } },
+ { S5P_DIS_IRQ_CENTRAL1, { 0x0, 0x0, 0x0 } },
+ { S5P_ISP_ARM_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_DIS_IRQ_ISP_ARM_LOCAL_LOWPWR, { 0x0, 0x0, 0x0 } },
+ { S5P_DIS_IRQ_ISP_ARM_CENTRAL_LOWPWR, { 0x0, 0x0, 0x0 } },
+ { S5P_ARM_COMMON_LOWPWR, { 0x0, 0x0, 0x2 } },
+ { S5P_L2_0_LOWPWR, { 0x0, 0x0, 0x3 } },
+ /* XXX_OPTION register should be set other field */
+ { S5P_ARM_L2_0_OPTION, { 0x10, 0x10, 0x0 } },
+ { S5P_L2_1_LOWPWR, { 0x0, 0x0, 0x3 } },
+ { S5P_ARM_L2_1_OPTION, { 0x10, 0x10, 0x0 } },
+ { S5P_CMU_ACLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_SCLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_RESET_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_DRAM_FREQ_DOWN_LOWPWR, { 0x1, 0x1, 0x1 } },
+ { S5P_DDRPHY_DLLOFF_LOWPWR, { 0x1, 0x1, 0x1 } },
+ { S5P_LPDDR_PHY_DLL_LOCK_LOWPWR, { 0x1, 0x1, 0x1 } },
+ { S5P_CMU_ACLKSTOP_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_SCLKSTOP_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_RESET_COREBLK_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_APLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_MPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_VPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_EPLL_SYSCLK_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_MPLLUSER_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_RESET_GPSALIVE_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_CLKSTOP_CAM_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_CLKSTOP_TV_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_CLKSTOP_MFC_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_CLKSTOP_G3D_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_CLKSTOP_LCD0_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_CLKSTOP_ISP_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_CLKSTOP_MAUDIO_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_CLKSTOP_GPS_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_RESET_CAM_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_RESET_TV_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_RESET_MFC_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_RESET_G3D_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_RESET_LCD0_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_RESET_ISP_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_RESET_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_CMU_RESET_GPS_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_TOP_BUS_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_TOP_RETENTION_LOWPWR, { 0x1, 0x0, 0x1 } },
+ { S5P_TOP_PWR_LOWPWR, { 0x3, 0x0, 0x3 } },
+ { S5P_TOP_BUS_COREBLK_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_TOP_RETENTION_COREBLK_LOWPWR, { 0x1, 0x0, 0x1 } },
+ { S5P_TOP_PWR_COREBLK_LOWPWR, { 0x3, 0x0, 0x3 } },
+ { S5P_LOGIC_RESET_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_OSCCLK_GATE_LOWPWR, { 0x1, 0x0, 0x1 } },
+ { S5P_LOGIC_RESET_COREBLK_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_OSCCLK_GATE_COREBLK_LOWPWR, { 0x1, 0x0, 0x1 } },
+ { S5P_ONENAND_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_ONENAND_MEM_OPTION, { 0x10, 0x10, 0x0 } },
+ { S5P_HSI_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_HSI_MEM_OPTION, { 0x10, 0x10, 0x0 } },
+ { S5P_G2D_ACP_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_G2D_ACP_MEM_OPTION, { 0x10, 0x10, 0x0 } },
+ { S5P_USBOTG_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_USBOTG_MEM_OPTION, { 0x10, 0x10, 0x0 } },
+ { S5P_HSMMC_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_HSMMC_MEM_OPTION, { 0x10, 0x10, 0x0 } },
+ { S5P_CSSYS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_CSSYS_MEM_OPTION, { 0x10, 0x10, 0x0 } },
+ { S5P_SECSS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_SECSS_MEM_OPTION, { 0x10, 0x10, 0x0 } },
+ { S5P_ROTATOR_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
+ { S5P_ROTATOR_MEM_OPTION, { 0x10, 0x10, 0x0 } },
+ { S5P_PAD_RETENTION_DRAM_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_PAD_RETENTION_GPIO_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_UART_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_MMCA_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_MMCB_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_EBIA_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_EBIB_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_GPIO_COREBLK_LOWPWR,{ 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_ISOLATION_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_ISOLATION_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_PAD_RETENTION_ALV_SEL_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_XUSBXTI_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_XXTI_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_EXT_REGULATOR_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_GPIO_MODE_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_GPIO_MODE_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_GPIO_MODE_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
+ { S5P_TOP_ASB_RESET_LOWPWR, { 0x1, 0x1, 0x1 } },
+ { S5P_TOP_ASB_ISOLATION_LOWPWR, { 0x1, 0x0, 0x1 } },
+ { S5P_CAM_LOWPWR, { 0x7, 0x0, 0x0 } },
+ { S5P_TV_LOWPWR, { 0x7, 0x0, 0x0 } },
+ { S5P_MFC_LOWPWR, { 0x7, 0x0, 0x0 } },
+ { S5P_G3D_LOWPWR, { 0x7, 0x0, 0x0 } },
+ { S5P_LCD0_LOWPWR, { 0x7, 0x0, 0x0 } },
+ { S5P_ISP_LOWPWR, { 0x7, 0x0, 0x0 } },
+ { S5P_MAUDIO_LOWPWR, { 0x7, 0x7, 0x0 } },
+ { S5P_GPS_LOWPWR, { 0x7, 0x0, 0x0 } },
+ { S5P_GPS_ALIVE_LOWPWR, { 0x7, 0x0, 0x0 } },
+ { S5P_CMU_SYSCLK_ISP_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { S5P_CMU_SYSCLK_GPS_LOWPWR, { 0x1, 0x0, 0x0 } },
+ { PMU_TABLE_END,},
+};
+
+static const struct exynos_pmu_conf exynos4412_pmu_config[] = {
+ { S5P_ARM_CORE2_LOWPWR, { 0x0, 0x0, 0x2 } },
+ { S5P_DIS_IRQ_CORE2, { 0x0, 0x0, 0x0 } },
+ { S5P_DIS_IRQ_CENTRAL2, { 0x0, 0x0, 0x0 } },
+ { S5P_ARM_CORE3_LOWPWR, { 0x0, 0x0, 0x2 } },
+ { S5P_DIS_IRQ_CORE3, { 0x0, 0x0, 0x0 } },
+ { S5P_DIS_IRQ_CENTRAL3, { 0x0, 0x0, 0x0 } },
+ { PMU_TABLE_END,},
+};
+
+static const struct exynos_pmu_conf exynos5250_pmu_config[] = {
+ /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */
+ { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
+ { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
+ { EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_FSYS_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_DIS_IRQ_FSYS_ARM_CENTRAL_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS5_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
+ { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x3, 0x3, 0x3} },
+ { EXYNOS5_ARM_L2_OPTION, { 0x10, 0x10, 0x0 } },
+ { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS5_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_TOP_PWR_SYS_PWR_REG, { 0x3, 0x0, 0x3} },
+ { EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} },
+ { EXYNOS5_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_USBOTG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_G2D_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_USBDRD_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_SDMMC_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_CSSYS_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_SECSS_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_ROTATOR_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_JPEG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_JPEG_MEM_OPTION, { 0x10, 0x10, 0x0} },
+ { EXYNOS5_HSI_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_MCUIOP_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_SATA_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_PAD_RETENTION_GPIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_MMCA_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_MMCB_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS5_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_GSCL_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5_DISP1_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5_MAU_SYS_PWR_REG, { 0x7, 0x7, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { PMU_TABLE_END,},
+};
+
+static struct exynos_pmu_conf exynos5420_pmu_config[] = {
+ /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */
+ { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_ARM_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_ARM_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_DIS_IRQ_ARM_CORE3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_DIS_IRQ_ARM_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_KFC_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_DIS_IRQ_KFC_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_KFC_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_DIS_IRQ_KFC_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_KFC_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_DIS_IRQ_KFC_CORE2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_KFC_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_DIS_IRQ_KFC_CORE3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5420_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_KFC_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_KFC_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5420_DPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5420_IPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5420_KPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5420_RPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5420_SPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS5_TOP_PWR_SYS_PWR_REG, { 0x3, 0x3, 0x0} },
+ { EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5420_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} },
+ { EXYNOS5420_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} },
+ { EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5420_PAD_RETENTION_JTAG_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5420_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5420_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5420_PAD_RETENTION_MMC0_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5420_PAD_RETENTION_MMC1_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5420_PAD_RETENTION_MMC2_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5420_PAD_RETENTION_HSI_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5420_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5420_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5420_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5420_PAD_RETENTION_DRAM_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_GSCL_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5420_DISP1_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5420_MAU_SYS_PWR_REG, { 0x7, 0x7, 0x0} },
+ { EXYNOS5420_G2D_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5420_MSC_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5420_FSYS_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5420_FSYS2_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5420_PSGEN_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5420_PERIC_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5420_WCORE_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { PMU_TABLE_END,},
+};
+
+static unsigned int const exynos3250_list_feed[] = {
+ EXYNOS3_ARM_CORE_OPTION(0),
+ EXYNOS3_ARM_CORE_OPTION(1),
+ EXYNOS3_ARM_CORE_OPTION(2),
+ EXYNOS3_ARM_CORE_OPTION(3),
+ EXYNOS3_ARM_COMMON_OPTION,
+ EXYNOS3_TOP_PWR_OPTION,
+ EXYNOS3_CORE_TOP_PWR_OPTION,
+ S5P_CAM_OPTION,
+ S5P_MFC_OPTION,
+ S5P_G3D_OPTION,
+ S5P_LCD0_OPTION,
+ S5P_ISP_OPTION,
+};
+
+static void exynos3250_powerdown_conf_extra(enum sys_powerdown mode)
+{
+ unsigned int i;
+ unsigned int tmp;
+
+ /* Enable only SC_FEEDBACK */
+ for (i = 0; i < ARRAY_SIZE(exynos3250_list_feed); i++) {
+ tmp = pmu_raw_readl(exynos3250_list_feed[i]);
+ tmp &= ~(EXYNOS3_OPTION_USE_SC_COUNTER);
+ tmp |= EXYNOS3_OPTION_USE_SC_FEEDBACK;
+ pmu_raw_writel(tmp, exynos3250_list_feed[i]);
+ }
+
+ if (mode != SYS_SLEEP)
+ return;
+
+ pmu_raw_writel(XUSBXTI_DURATION, EXYNOS3_XUSBXTI_DURATION);
+ pmu_raw_writel(XXTI_DURATION, EXYNOS3_XXTI_DURATION);
+ pmu_raw_writel(EXT_REGULATOR_DURATION, EXYNOS3_EXT_REGULATOR_DURATION);
+ pmu_raw_writel(EXT_REGULATOR_COREBLK_DURATION,
+ EXYNOS3_EXT_REGULATOR_COREBLK_DURATION);
+}
+
+static unsigned int const exynos5_list_both_cnt_feed[] = {
+ EXYNOS5_ARM_CORE0_OPTION,
+ EXYNOS5_ARM_CORE1_OPTION,
+ EXYNOS5_ARM_COMMON_OPTION,
+ EXYNOS5_GSCL_OPTION,
+ EXYNOS5_ISP_OPTION,
+ EXYNOS5_MFC_OPTION,
+ EXYNOS5_G3D_OPTION,
+ EXYNOS5_DISP1_OPTION,
+ EXYNOS5_MAU_OPTION,
+ EXYNOS5_TOP_PWR_OPTION,
+ EXYNOS5_TOP_PWR_SYSMEM_OPTION,
+};
+
+static unsigned int const exynos5_list_disable_wfi_wfe[] = {
+ EXYNOS5_ARM_CORE1_OPTION,
+ EXYNOS5_FSYS_ARM_OPTION,
+ EXYNOS5_ISP_ARM_OPTION,
+};
+
+static unsigned int const exynos5420_list_disable_pmu_reg[] = {
+ EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG,
+ EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG,
+ EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG,
+ EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG,
+ EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG,
+ EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG,
+ EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG,
+ EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG,
+ EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG,
+ EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG,
+ EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG,
+ EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG,
+ EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG,
+ EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG,
+ EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG,
+ EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG,
+ EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG,
+ EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG,
+ EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG,
+ EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG,
+ EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG,
+ EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG,
+ EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG,
+ EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG,
+ EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG,
+ EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG,
+ EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG,
+ EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG,
+ EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG,
+ EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG,
+ EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG,
+ EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG,
+ EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG,
+ EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG,
+ EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG,
+};
+
+static void exynos5_power_off(void)
+{
+ unsigned int tmp;
+
+ pr_info("Power down.\n");
+ tmp = pmu_raw_readl(EXYNOS_PS_HOLD_CONTROL);
+ tmp ^= (1 << 8);
+ pmu_raw_writel(tmp, EXYNOS_PS_HOLD_CONTROL);
+
+ /* Wait a little so we don't give a false warning below */
+ mdelay(100);
+
+ pr_err("Power down failed, please power off system manually.\n");
+ while (1)
+ ;
+}
+
+void exynos5420_powerdown_conf(enum sys_powerdown mode)
+{
+ u32 this_cluster;
+
+ this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1);
+
+ /*
+ * set the cluster id to IROM register to ensure that we wake
+ * up with the current cluster.
+ */
+ pmu_raw_writel(this_cluster, EXYNOS_IROM_DATA2);
+}
+
+
+static void exynos5_powerdown_conf(enum sys_powerdown mode)
+{
+ unsigned int i;
+ unsigned int tmp;
+
+ /*
+ * Enable both SC_FEEDBACK and SC_COUNTER
+ */
+ for (i = 0; i < ARRAY_SIZE(exynos5_list_both_cnt_feed); i++) {
+ tmp = pmu_raw_readl(exynos5_list_both_cnt_feed[i]);
+ tmp |= (EXYNOS5_USE_SC_FEEDBACK |
+ EXYNOS5_USE_SC_COUNTER);
+ pmu_raw_writel(tmp, exynos5_list_both_cnt_feed[i]);
+ }
+
+ /*
+ * SKIP_DEACTIVATE_ACEACP_IN_PWDN_BITFIELD Enable
+ */
+ tmp = pmu_raw_readl(EXYNOS5_ARM_COMMON_OPTION);
+ tmp |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN;
+ pmu_raw_writel(tmp, EXYNOS5_ARM_COMMON_OPTION);
+
+ /*
+ * Disable WFI/WFE on XXX_OPTION
+ */
+ for (i = 0; i < ARRAY_SIZE(exynos5_list_disable_wfi_wfe); i++) {
+ tmp = pmu_raw_readl(exynos5_list_disable_wfi_wfe[i]);
+ tmp &= ~(EXYNOS5_OPTION_USE_STANDBYWFE |
+ EXYNOS5_OPTION_USE_STANDBYWFI);
+ pmu_raw_writel(tmp, exynos5_list_disable_wfi_wfe[i]);
+ }
+}
+
+void exynos_sys_powerdown_conf(enum sys_powerdown mode)
+{
+ unsigned int i;
+
+ const struct exynos_pmu_data *pmu_data = pmu_context->pmu_data;
+
+ if (pmu_data->powerdown_conf)
+ pmu_data->powerdown_conf(mode);
+
+ if (pmu_data->pmu_config) {
+ for (i = 0; (pmu_data->pmu_config[i].offset != PMU_TABLE_END); i++)
+ pmu_raw_writel(pmu_data->pmu_config[i].val[mode],
+ pmu_data->pmu_config[i].offset);
+ }
+
+ if (pmu_data->powerdown_conf_extra)
+ pmu_data->powerdown_conf_extra(mode);
+
+ if (pmu_data->pmu_config_extra) {
+ for (i = 0; pmu_data->pmu_config_extra[i].offset != PMU_TABLE_END; i++)
+ pmu_raw_writel(pmu_data->pmu_config_extra[i].val[mode],
+ pmu_data->pmu_config_extra[i].offset);
+ }
+}
+
+static void exynos3250_pmu_init(void)
+{
+ unsigned int value;
+
+ /*
+ * To prevent from issuing new bus request form L2 memory system
+ * If core status is power down, should be set '1' to L2 power down
+ */
+ value = pmu_raw_readl(EXYNOS3_ARM_COMMON_OPTION);
+ value |= EXYNOS3_OPTION_SKIP_DEACTIVATE_ACEACP_IN_PWDN;
+ pmu_raw_writel(value, EXYNOS3_ARM_COMMON_OPTION);
+
+ /* Enable USE_STANDBY_WFI for all CORE */
+ pmu_raw_writel(S5P_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION);
+
+ /*
+ * Set PSHOLD port for output high
+ */
+ value = pmu_raw_readl(S5P_PS_HOLD_CONTROL);
+ value |= S5P_PS_HOLD_OUTPUT_HIGH;
+ pmu_raw_writel(value, S5P_PS_HOLD_CONTROL);
+
+ /*
+ * Enable signal for PSHOLD port
+ */
+ value = pmu_raw_readl(S5P_PS_HOLD_CONTROL);
+ value |= S5P_PS_HOLD_EN;
+ pmu_raw_writel(value, S5P_PS_HOLD_CONTROL);
+}
+
+static void exynos5250_pmu_init(void)
+{
+ unsigned int value;
+ /*
+ * When SYS_WDTRESET is set, watchdog timer reset request
+ * is ignored by power management unit.
+ */
+ value = pmu_raw_readl(EXYNOS5_AUTO_WDTRESET_DISABLE);
+ value &= ~EXYNOS5_SYS_WDTRESET;
+ pmu_raw_writel(value, EXYNOS5_AUTO_WDTRESET_DISABLE);
+
+ value = pmu_raw_readl(EXYNOS5_MASK_WDTRESET_REQUEST);
+ value &= ~EXYNOS5_SYS_WDTRESET;
+ pmu_raw_writel(value, EXYNOS5_MASK_WDTRESET_REQUEST);
+}
+
+static void exynos5420_pmu_init(void)
+{
+ unsigned int value;
+ int i;
+
+ /*
+ * Set the CMU_RESET, CMU_SYSCLK and CMU_CLKSTOP registers
+ * for local power blocks to Low initially as per Table 8-4:
+ * "System-Level Power-Down Configuration Registers".
+ */
+ for (i = 0; i < ARRAY_SIZE(exynos5420_list_disable_pmu_reg); i++)
+ pmu_raw_writel(0, exynos5420_list_disable_pmu_reg[i]);
+
+ /* Enable USE_STANDBY_WFI for all CORE */
+ pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION);
+
+ value = pmu_raw_readl(EXYNOS_L2_OPTION(0));
+ value &= ~EXYNOS5_USE_RETENTION;
+ pmu_raw_writel(value, EXYNOS_L2_OPTION(0));
+
+ value = pmu_raw_readl(EXYNOS_L2_OPTION(1));
+ value &= ~EXYNOS5_USE_RETENTION;
+ pmu_raw_writel(value, EXYNOS_L2_OPTION(1));
+
+ /*
+ * If L2_COMMON is turned off, clocks related to ATB async
+ * bridge are gated. Thus, when ISP power is gated, LPI
+ * may get stuck.
+ */
+ value = pmu_raw_readl(EXYNOS5420_LPI_MASK);
+ value |= EXYNOS5420_ATB_ISP_ARM;
+ pmu_raw_writel(value, EXYNOS5420_LPI_MASK);
+
+ value = pmu_raw_readl(EXYNOS5420_LPI_MASK1);
+ value |= EXYNOS5420_ATB_KFC;
+ pmu_raw_writel(value, EXYNOS5420_LPI_MASK1);
+
+ /* Prevent issue of new bus request from L2 memory */
+ value = pmu_raw_readl(EXYNOS5420_ARM_COMMON_OPTION);
+ value |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN;
+ pmu_raw_writel(value, EXYNOS5420_ARM_COMMON_OPTION);
+
+ value = pmu_raw_readl(EXYNOS5420_KFC_COMMON_OPTION);
+ value |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN;
+ pmu_raw_writel(value, EXYNOS5420_KFC_COMMON_OPTION);
+
+ /* This setting is to reduce suspend/resume time */
+ pmu_raw_writel(DUR_WAIT_RESET, EXYNOS5420_LOGIC_RESET_DURATION3);
+
+ /* Serialized CPU wakeup of Eagle */
+ pmu_raw_writel(SPREAD_ENABLE, EXYNOS5420_ARM_INTR_SPREAD_ENABLE);
+
+ pmu_raw_writel(SPREAD_USE_STANDWFI,
+ EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI);
+
+ pmu_raw_writel(0x1, EXYNOS5420_UP_SCHEDULER);
+
+ pm_power_off = exynos5_power_off;
+ pr_info("EXYNOS5420 PMU initialized\n");
+}
+
+static int pmu_restart_notify(struct notifier_block *this,
+ unsigned long code, void *unused)
+{
+ pmu_raw_writel(0x1, EXYNOS_SWRESET);
+
+ return NOTIFY_DONE;
+}
+
+static const struct exynos_pmu_data exynos3250_pmu_data = {
+ .pmu_config = exynos3250_pmu_config,
+ .pmu_init = exynos3250_pmu_init,
+ .powerdown_conf_extra = exynos3250_powerdown_conf_extra,
+};
+
+static const struct exynos_pmu_data exynos4210_pmu_data = {
+ .pmu_config = exynos4210_pmu_config,
+};
+
+static const struct exynos_pmu_data exynos4212_pmu_data = {
+ .pmu_config = exynos4x12_pmu_config,
+};
+
+static const struct exynos_pmu_data exynos4412_pmu_data = {
+ .pmu_config = exynos4x12_pmu_config,
+ .pmu_config_extra = exynos4412_pmu_config,
+};
+
+static const struct exynos_pmu_data exynos5250_pmu_data = {
+ .pmu_config = exynos5250_pmu_config,
+ .pmu_init = exynos5250_pmu_init,
+ .powerdown_conf = exynos5_powerdown_conf,
+};
+
+static struct exynos_pmu_data exynos5420_pmu_data = {
+ .pmu_config = exynos5420_pmu_config,
+ .pmu_init = exynos5420_pmu_init,
+ .powerdown_conf = exynos5420_powerdown_conf,
+};
+
+/*
+ * PMU platform driver and devicetree bindings.
+ */
+static const struct of_device_id exynos_pmu_of_device_ids[] = {
+ {
+ .compatible = "samsung,exynos3250-pmu",
+ .data = &exynos3250_pmu_data,
+ }, {
+ .compatible = "samsung,exynos4210-pmu",
+ .data = &exynos4210_pmu_data,
+ }, {
+ .compatible = "samsung,exynos4212-pmu",
+ .data = &exynos4212_pmu_data,
+ }, {
+ .compatible = "samsung,exynos4412-pmu",
+ .data = &exynos4412_pmu_data,
+ }, {
+ .compatible = "samsung,exynos5250-pmu",
+ .data = &exynos5250_pmu_data,
+ }, {
+ .compatible = "samsung,exynos5420-pmu",
+ .data = &exynos5420_pmu_data,
+ },
+ { /*sentinel*/ },
+};
+
+/*
+ * Exynos PMU restart notifier, handles restart functionality
+ */
+static struct notifier_block pmu_restart_handler = {
+ .notifier_call = pmu_restart_notify,
+ .priority = 128,
+};
+
+static int exynos_pmu_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pmu_base_addr = devm_ioremap_resource(dev, res);
+ if (IS_ERR(pmu_base_addr))
+ return PTR_ERR(pmu_base_addr);
+
+ pmu_context = devm_kzalloc(&pdev->dev,
+ sizeof(struct exynos_pmu_context),
+ GFP_KERNEL);
+ if (!pmu_context) {
+ dev_err(dev, "Cannot allocate memory.\n");
+ return -ENOMEM;
+ }
+ pmu_context->dev = dev;
+
+ match = of_match_node(exynos_pmu_of_device_ids, dev->of_node);
+
+ pmu_context->pmu_data = match->data;
+
+ if (pmu_context->pmu_data->pmu_init)
+ pmu_context->pmu_data->pmu_init();
+
+ platform_set_drvdata(pdev, pmu_context);
+
+ ret = register_restart_handler(&pmu_restart_handler);
+ if (ret)
+ dev_warn(dev, "can't register restart handler err=%d\n", ret);
+
+ dev_dbg(dev, "Exynos PMU Driver probe done\n");
+ return 0;
+}
+
+static struct platform_driver exynos_pmu_driver = {
+ .driver = {
+ .name = "exynos-pmu",
+ .owner = THIS_MODULE,
+ .of_match_table = exynos_pmu_of_device_ids,
+ },
+ .probe = exynos_pmu_probe,
+};
+
+static int __init exynos_pmu_init(void)
+{
+ return platform_driver_register(&exynos_pmu_driver);
+
+}
+postcore_initcall(exynos_pmu_init);
diff --git a/arch/arm/mach-exynos/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h
new file mode 100644
index 000000000..b7614333d
--- /dev/null
+++ b/arch/arm/mach-exynos/regs-pmu.h
@@ -0,0 +1,696 @@
+/*
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - 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__
+
+#define S5P_CENTRAL_SEQ_CONFIGURATION 0x0200
+
+#define S5P_CENTRAL_LOWPWR_CFG (1 << 16)
+
+#define S5P_CENTRAL_SEQ_OPTION 0x0208
+
+#define S5P_USE_STANDBY_WFI0 (1 << 16)
+#define S5P_USE_STANDBY_WFI1 (1 << 17)
+#define S5P_USE_STANDBY_WFI2 (1 << 19)
+#define S5P_USE_STANDBY_WFI3 (1 << 20)
+#define S5P_USE_STANDBY_WFE0 (1 << 24)
+#define S5P_USE_STANDBY_WFE1 (1 << 25)
+#define S5P_USE_STANDBY_WFE2 (1 << 27)
+#define S5P_USE_STANDBY_WFE3 (1 << 28)
+
+#define S5P_USE_STANDBY_WFI_ALL \
+ (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFI1 | \
+ S5P_USE_STANDBY_WFI2 | S5P_USE_STANDBY_WFI3 | \
+ S5P_USE_STANDBY_WFE0 | S5P_USE_STANDBY_WFE1 | \
+ S5P_USE_STANDBY_WFE2 | S5P_USE_STANDBY_WFE3)
+
+#define S5P_USE_DELAYED_RESET_ASSERTION BIT(12)
+
+#define EXYNOS_CORE_PO_RESET(n) ((1 << 4) << n)
+#define EXYNOS_WAKEUP_FROM_LOWPWR (1 << 28)
+#define EXYNOS_SWRESET 0x0400
+#define EXYNOS5440_SWRESET 0x00C4
+
+#define S5P_WAKEUP_STAT 0x0600
+#define S5P_EINT_WAKEUP_MASK 0x0604
+#define S5P_WAKEUP_MASK 0x0608
+#define S5P_WAKEUP_MASK2 0x0614
+
+#define S5P_INFORM0 0x0800
+#define S5P_INFORM1 0x0804
+#define S5P_INFORM5 0x0814
+#define S5P_INFORM6 0x0818
+#define S5P_INFORM7 0x081C
+#define S5P_PMU_SPARE2 0x0908
+#define S5P_PMU_SPARE3 0x090C
+
+#define EXYNOS_IROM_DATA2 0x0988
+#define S5P_ARM_CORE0_LOWPWR 0x1000
+#define S5P_DIS_IRQ_CORE0 0x1004
+#define S5P_DIS_IRQ_CENTRAL0 0x1008
+#define S5P_ARM_CORE1_LOWPWR 0x1010
+#define S5P_DIS_IRQ_CORE1 0x1014
+#define S5P_DIS_IRQ_CENTRAL1 0x1018
+#define S5P_ARM_COMMON_LOWPWR 0x1080
+#define S5P_L2_0_LOWPWR 0x10C0
+#define S5P_L2_1_LOWPWR 0x10C4
+#define S5P_CMU_ACLKSTOP_LOWPWR 0x1100
+#define S5P_CMU_SCLKSTOP_LOWPWR 0x1104
+#define S5P_CMU_RESET_LOWPWR 0x110C
+#define S5P_APLL_SYSCLK_LOWPWR 0x1120
+#define S5P_MPLL_SYSCLK_LOWPWR 0x1124
+#define S5P_VPLL_SYSCLK_LOWPWR 0x1128
+#define S5P_EPLL_SYSCLK_LOWPWR 0x112C
+#define S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR 0x1138
+#define S5P_CMU_RESET_GPSALIVE_LOWPWR 0x113C
+#define S5P_CMU_CLKSTOP_CAM_LOWPWR 0x1140
+#define S5P_CMU_CLKSTOP_TV_LOWPWR 0x1144
+#define S5P_CMU_CLKSTOP_MFC_LOWPWR 0x1148
+#define S5P_CMU_CLKSTOP_G3D_LOWPWR 0x114C
+#define S5P_CMU_CLKSTOP_LCD0_LOWPWR 0x1150
+#define S5P_CMU_CLKSTOP_MAUDIO_LOWPWR 0x1158
+#define S5P_CMU_CLKSTOP_GPS_LOWPWR 0x115C
+#define S5P_CMU_RESET_CAM_LOWPWR 0x1160
+#define S5P_CMU_RESET_TV_LOWPWR 0x1164
+#define S5P_CMU_RESET_MFC_LOWPWR 0x1168
+#define S5P_CMU_RESET_G3D_LOWPWR 0x116C
+#define S5P_CMU_RESET_LCD0_LOWPWR 0x1170
+#define S5P_CMU_RESET_MAUDIO_LOWPWR 0x1178
+#define S5P_CMU_RESET_GPS_LOWPWR 0x117C
+#define S5P_TOP_BUS_LOWPWR 0x1180
+#define S5P_TOP_RETENTION_LOWPWR 0x1184
+#define S5P_TOP_PWR_LOWPWR 0x1188
+#define S5P_LOGIC_RESET_LOWPWR 0x11A0
+#define S5P_ONENAND_MEM_LOWPWR 0x11C0
+#define S5P_G2D_ACP_MEM_LOWPWR 0x11C8
+#define S5P_USBOTG_MEM_LOWPWR 0x11CC
+#define S5P_HSMMC_MEM_LOWPWR 0x11D0
+#define S5P_CSSYS_MEM_LOWPWR 0x11D4
+#define S5P_SECSS_MEM_LOWPWR 0x11D8
+#define S5P_PAD_RETENTION_DRAM_LOWPWR 0x1200
+#define S5P_PAD_RETENTION_MAUDIO_LOWPWR 0x1204
+#define S5P_PAD_RETENTION_GPIO_LOWPWR 0x1220
+#define S5P_PAD_RETENTION_UART_LOWPWR 0x1224
+#define S5P_PAD_RETENTION_MMCA_LOWPWR 0x1228
+#define S5P_PAD_RETENTION_MMCB_LOWPWR 0x122C
+#define S5P_PAD_RETENTION_EBIA_LOWPWR 0x1230
+#define S5P_PAD_RETENTION_EBIB_LOWPWR 0x1234
+#define S5P_PAD_RETENTION_ISOLATION_LOWPWR 0x1240
+#define S5P_PAD_RETENTION_ALV_SEL_LOWPWR 0x1260
+#define S5P_XUSBXTI_LOWPWR 0x1280
+#define S5P_XXTI_LOWPWR 0x1284
+#define S5P_EXT_REGULATOR_LOWPWR 0x12C0
+#define S5P_GPIO_MODE_LOWPWR 0x1300
+#define S5P_GPIO_MODE_MAUDIO_LOWPWR 0x1340
+#define S5P_CAM_LOWPWR 0x1380
+#define S5P_TV_LOWPWR 0x1384
+#define S5P_MFC_LOWPWR 0x1388
+#define S5P_G3D_LOWPWR 0x138C
+#define S5P_LCD0_LOWPWR 0x1390
+#define S5P_MAUDIO_LOWPWR 0x1398
+#define S5P_GPS_LOWPWR 0x139C
+#define S5P_GPS_ALIVE_LOWPWR 0x13A0
+
+#define EXYNOS_ARM_CORE0_CONFIGURATION 0x2000
+#define EXYNOS_ARM_CORE_CONFIGURATION(_nr) \
+ (EXYNOS_ARM_CORE0_CONFIGURATION + (0x80 * (_nr)))
+#define EXYNOS_ARM_CORE_STATUS(_nr) \
+ (EXYNOS_ARM_CORE_CONFIGURATION(_nr) + 0x4)
+#define EXYNOS_ARM_CORE_OPTION(_nr) \
+ (EXYNOS_ARM_CORE_CONFIGURATION(_nr) + 0x8)
+
+#define EXYNOS_ARM_COMMON_CONFIGURATION 0x2500
+#define EXYNOS_COMMON_CONFIGURATION(_nr) \
+ (EXYNOS_ARM_COMMON_CONFIGURATION + (0x80 * (_nr)))
+#define EXYNOS_COMMON_STATUS(_nr) \
+ (EXYNOS_COMMON_CONFIGURATION(_nr) + 0x4)
+#define EXYNOS_COMMON_OPTION(_nr) \
+ (EXYNOS_COMMON_CONFIGURATION(_nr) + 0x8)
+
+#define EXYNOS_CORE_LOCAL_PWR_EN 0x3
+
+#define EXYNOS_ARM_COMMON_STATUS 0x2504
+#define EXYNOS_COMMON_OPTION(_nr) \
+ (EXYNOS_COMMON_CONFIGURATION(_nr) + 0x8)
+
+#define EXYNOS_ARM_L2_CONFIGURATION 0x2600
+#define EXYNOS_L2_CONFIGURATION(_nr) \
+ (EXYNOS_ARM_L2_CONFIGURATION + ((_nr) * 0x80))
+#define EXYNOS_L2_STATUS(_nr) \
+ (EXYNOS_L2_CONFIGURATION(_nr) + 0x4)
+#define EXYNOS_L2_OPTION(_nr) \
+ (EXYNOS_L2_CONFIGURATION(_nr) + 0x8)
+#define EXYNOS_L2_COMMON_PWR_EN 0x3
+
+#define EXYNOS_ARM_CORE_X_STATUS_OFFSET 0x4
+
+#define EXYNOS5_APLL_SYSCLK_CONFIGURATION 0x2A00
+#define EXYNOS5_APLL_SYSCLK_STATUS 0x2A04
+
+#define EXYNOS5_ARM_L2_OPTION 0x2608
+#define EXYNOS5_USE_RETENTION BIT(4)
+
+#define EXYNOS5_L2RSTDISABLE_VALUE BIT(3)
+
+#define S5P_PAD_RET_MAUDIO_OPTION 0x3028
+#define S5P_PAD_RET_MMC2_OPTION 0x30c8
+#define S5P_PAD_RET_GPIO_OPTION 0x3108
+#define S5P_PAD_RET_UART_OPTION 0x3128
+#define S5P_PAD_RET_MMCA_OPTION 0x3148
+#define S5P_PAD_RET_MMCB_OPTION 0x3168
+#define S5P_PAD_RET_EBIA_OPTION 0x3188
+#define S5P_PAD_RET_EBIB_OPTION 0x31A8
+#define S5P_PAD_RET_SPI_OPTION 0x31c8
+
+#define S5P_PS_HOLD_CONTROL 0x330C
+#define S5P_PS_HOLD_EN (1 << 31)
+#define S5P_PS_HOLD_OUTPUT_HIGH (3 << 8)
+
+#define S5P_CAM_OPTION 0x3C08
+#define S5P_MFC_OPTION 0x3C48
+#define S5P_G3D_OPTION 0x3C68
+#define S5P_LCD0_OPTION 0x3C88
+#define S5P_LCD1_OPTION 0x3CA8
+#define S5P_ISP_OPTION S5P_LCD1_OPTION
+
+#define S5P_CORE_LOCAL_PWR_EN 0x3
+#define S5P_CORE_WAKEUP_FROM_LOCAL_CFG (0x3 << 8)
+#define S5P_CORE_AUTOWAKEUP_EN (1 << 31)
+
+/* Only for EXYNOS4210 */
+#define S5P_CMU_CLKSTOP_LCD1_LOWPWR 0x1154
+#define S5P_CMU_RESET_LCD1_LOWPWR 0x1174
+#define S5P_MODIMIF_MEM_LOWPWR 0x11C4
+#define S5P_PCIE_MEM_LOWPWR 0x11E0
+#define S5P_SATA_MEM_LOWPWR 0x11E4
+#define S5P_LCD1_LOWPWR 0x1394
+
+/* Only for EXYNOS4x12 */
+#define S5P_ISP_ARM_LOWPWR 0x1050
+#define S5P_DIS_IRQ_ISP_ARM_LOCAL_LOWPWR 0x1054
+#define S5P_DIS_IRQ_ISP_ARM_CENTRAL_LOWPWR 0x1058
+#define S5P_CMU_ACLKSTOP_COREBLK_LOWPWR 0x1110
+#define S5P_CMU_SCLKSTOP_COREBLK_LOWPWR 0x1114
+#define S5P_CMU_RESET_COREBLK_LOWPWR 0x111C
+#define S5P_MPLLUSER_SYSCLK_LOWPWR 0x1130
+#define S5P_CMU_CLKSTOP_ISP_LOWPWR 0x1154
+#define S5P_CMU_RESET_ISP_LOWPWR 0x1174
+#define S5P_TOP_BUS_COREBLK_LOWPWR 0x1190
+#define S5P_TOP_RETENTION_COREBLK_LOWPWR 0x1194
+#define S5P_TOP_PWR_COREBLK_LOWPWR 0x1198
+#define S5P_OSCCLK_GATE_LOWPWR 0x11A4
+#define S5P_LOGIC_RESET_COREBLK_LOWPWR 0x11B0
+#define S5P_OSCCLK_GATE_COREBLK_LOWPWR 0x11B4
+#define S5P_HSI_MEM_LOWPWR 0x11C4
+#define S5P_ROTATOR_MEM_LOWPWR 0x11DC
+#define S5P_PAD_RETENTION_GPIO_COREBLK_LOWPWR 0x123C
+#define S5P_PAD_ISOLATION_COREBLK_LOWPWR 0x1250
+#define S5P_GPIO_MODE_COREBLK_LOWPWR 0x1320
+#define S5P_TOP_ASB_RESET_LOWPWR 0x1344
+#define S5P_TOP_ASB_ISOLATION_LOWPWR 0x1348
+#define S5P_ISP_LOWPWR 0x1394
+#define S5P_DRAM_FREQ_DOWN_LOWPWR 0x13B0
+#define S5P_DDRPHY_DLLOFF_LOWPWR 0x13B4
+#define S5P_CMU_SYSCLK_ISP_LOWPWR 0x13B8
+#define S5P_CMU_SYSCLK_GPS_LOWPWR 0x13BC
+#define S5P_LPDDR_PHY_DLL_LOCK_LOWPWR 0x13C0
+
+#define S5P_ARM_L2_0_OPTION 0x2608
+#define S5P_ARM_L2_1_OPTION 0x2628
+#define S5P_ONENAND_MEM_OPTION 0x2E08
+#define S5P_HSI_MEM_OPTION 0x2E28
+#define S5P_G2D_ACP_MEM_OPTION 0x2E48
+#define S5P_USBOTG_MEM_OPTION 0x2E68
+#define S5P_HSMMC_MEM_OPTION 0x2E88
+#define S5P_CSSYS_MEM_OPTION 0x2EA8
+#define S5P_SECSS_MEM_OPTION 0x2EC8
+#define S5P_ROTATOR_MEM_OPTION 0x2F48
+
+/* Only for EXYNOS4412 */
+#define S5P_ARM_CORE2_LOWPWR 0x1020
+#define S5P_DIS_IRQ_CORE2 0x1024
+#define S5P_DIS_IRQ_CENTRAL2 0x1028
+#define S5P_ARM_CORE3_LOWPWR 0x1030
+#define S5P_DIS_IRQ_CORE3 0x1034
+#define S5P_DIS_IRQ_CENTRAL3 0x1038
+
+/* Only for EXYNOS3XXX */
+#define EXYNOS3_ARM_CORE0_SYS_PWR_REG 0x1000
+#define EXYNOS3_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG 0x1004
+#define EXYNOS3_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG 0x1008
+#define EXYNOS3_ARM_CORE1_SYS_PWR_REG 0x1010
+#define EXYNOS3_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG 0x1014
+#define EXYNOS3_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG 0x1018
+#define EXYNOS3_ISP_ARM_SYS_PWR_REG 0x1050
+#define EXYNOS3_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG 0x1054
+#define EXYNOS3_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG 0x1058
+#define EXYNOS3_ARM_COMMON_SYS_PWR_REG 0x1080
+#define EXYNOS3_ARM_L2_SYS_PWR_REG 0x10C0
+#define EXYNOS3_CMU_ACLKSTOP_SYS_PWR_REG 0x1100
+#define EXYNOS3_CMU_SCLKSTOP_SYS_PWR_REG 0x1104
+#define EXYNOS3_CMU_RESET_SYS_PWR_REG 0x110C
+#define EXYNOS3_CMU_ACLKSTOP_COREBLK_SYS_PWR_REG 0x1110
+#define EXYNOS3_CMU_SCLKSTOP_COREBLK_SYS_PWR_REG 0x1114
+#define EXYNOS3_CMU_RESET_COREBLK_SYS_PWR_REG 0x111C
+#define EXYNOS3_APLL_SYSCLK_SYS_PWR_REG 0x1120
+#define EXYNOS3_MPLL_SYSCLK_SYS_PWR_REG 0x1124
+#define EXYNOS3_VPLL_SYSCLK_SYS_PWR_REG 0x1128
+#define EXYNOS3_EPLL_SYSCLK_SYS_PWR_REG 0x112C
+#define EXYNOS3_MPLLUSER_SYSCLK_SYS_PWR_REG 0x1130
+#define EXYNOS3_BPLLUSER_SYSCLK_SYS_PWR_REG 0x1134
+#define EXYNOS3_EPLLUSER_SYSCLK_SYS_PWR_REG 0x1138
+#define EXYNOS3_CMU_CLKSTOP_CAM_SYS_PWR_REG 0x1140
+#define EXYNOS3_CMU_CLKSTOP_MFC_SYS_PWR_REG 0x1148
+#define EXYNOS3_CMU_CLKSTOP_G3D_SYS_PWR_REG 0x114C
+#define EXYNOS3_CMU_CLKSTOP_LCD0_SYS_PWR_REG 0x1150
+#define EXYNOS3_CMU_CLKSTOP_ISP_SYS_PWR_REG 0x1154
+#define EXYNOS3_CMU_CLKSTOP_MAUDIO_SYS_PWR_REG 0x1158
+#define EXYNOS3_CMU_RESET_CAM_SYS_PWR_REG 0x1160
+#define EXYNOS3_CMU_RESET_MFC_SYS_PWR_REG 0x1168
+#define EXYNOS3_CMU_RESET_G3D_SYS_PWR_REG 0x116C
+#define EXYNOS3_CMU_RESET_LCD0_SYS_PWR_REG 0x1170
+#define EXYNOS3_CMU_RESET_ISP_SYS_PWR_REG 0x1174
+#define EXYNOS3_CMU_RESET_MAUDIO_SYS_PWR_REG 0x1178
+#define EXYNOS3_TOP_BUS_SYS_PWR_REG 0x1180
+#define EXYNOS3_TOP_RETENTION_SYS_PWR_REG 0x1184
+#define EXYNOS3_TOP_PWR_SYS_PWR_REG 0x1188
+#define EXYNOS3_TOP_BUS_COREBLK_SYS_PWR_REG 0x1190
+#define EXYNOS3_TOP_RETENTION_COREBLK_SYS_PWR_REG 0x1194
+#define EXYNOS3_TOP_PWR_COREBLK_SYS_PWR_REG 0x1198
+#define EXYNOS3_LOGIC_RESET_SYS_PWR_REG 0x11A0
+#define EXYNOS3_OSCCLK_GATE_SYS_PWR_REG 0x11A4
+#define EXYNOS3_LOGIC_RESET_COREBLK_SYS_PWR_REG 0x11B0
+#define EXYNOS3_OSCCLK_GATE_COREBLK_SYS_PWR_REG 0x11B4
+#define EXYNOS3_PAD_RETENTION_DRAM_SYS_PWR_REG 0x1200
+#define EXYNOS3_PAD_RETENTION_MAUDIO_SYS_PWR_REG 0x1204
+#define EXYNOS3_PAD_RETENTION_SPI_SYS_PWR_REG 0x1208
+#define EXYNOS3_PAD_RETENTION_MMC2_SYS_PWR_REG 0x1218
+#define EXYNOS3_PAD_RETENTION_GPIO_SYS_PWR_REG 0x1220
+#define EXYNOS3_PAD_RETENTION_UART_SYS_PWR_REG 0x1224
+#define EXYNOS3_PAD_RETENTION_MMC0_SYS_PWR_REG 0x1228
+#define EXYNOS3_PAD_RETENTION_MMC1_SYS_PWR_REG 0x122C
+#define EXYNOS3_PAD_RETENTION_EBIA_SYS_PWR_REG 0x1230
+#define EXYNOS3_PAD_RETENTION_EBIB_SYS_PWR_REG 0x1234
+#define EXYNOS3_PAD_RETENTION_JTAG_SYS_PWR_REG 0x1238
+#define EXYNOS3_PAD_ISOLATION_SYS_PWR_REG 0x1240
+#define EXYNOS3_PAD_ALV_SEL_SYS_PWR_REG 0x1260
+#define EXYNOS3_XUSBXTI_SYS_PWR_REG 0x1280
+#define EXYNOS3_XXTI_SYS_PWR_REG 0x1284
+#define EXYNOS3_EXT_REGULATOR_SYS_PWR_REG 0x12C0
+#define EXYNOS3_EXT_REGULATOR_COREBLK_SYS_PWR_REG 0x12C4
+#define EXYNOS3_GPIO_MODE_SYS_PWR_REG 0x1300
+#define EXYNOS3_GPIO_MODE_MAUDIO_SYS_PWR_REG 0x1340
+#define EXYNOS3_TOP_ASB_RESET_SYS_PWR_REG 0x1344
+#define EXYNOS3_TOP_ASB_ISOLATION_SYS_PWR_REG 0x1348
+#define EXYNOS3_TOP_ASB_RESET_COREBLK_SYS_PWR_REG 0x1350
+#define EXYNOS3_TOP_ASB_ISOLATION_COREBLK_SYS_PWR_REG 0x1354
+#define EXYNOS3_CAM_SYS_PWR_REG 0x1380
+#define EXYNOS3_MFC_SYS_PWR_REG 0x1388
+#define EXYNOS3_G3D_SYS_PWR_REG 0x138C
+#define EXYNOS3_LCD0_SYS_PWR_REG 0x1390
+#define EXYNOS3_ISP_SYS_PWR_REG 0x1394
+#define EXYNOS3_MAUDIO_SYS_PWR_REG 0x1398
+#define EXYNOS3_DRAM_FREQ_DOWN_SYS_PWR_REG 0x13B0
+#define EXYNOS3_DDRPHY_DLLOFF_SYS_PWR_REG 0x13B4
+#define EXYNOS3_CMU_SYSCLK_ISP_SYS_PWR_REG 0x13B8
+#define EXYNOS3_LPDDR_PHY_DLL_LOCK_SYS_PWR_REG 0x13C0
+#define EXYNOS3_BPLL_SYSCLK_SYS_PWR_REG 0x13C4
+#define EXYNOS3_UPLL_SYSCLK_SYS_PWR_REG 0x13C8
+
+#define EXYNOS3_ARM_CORE0_OPTION 0x2008
+#define EXYNOS3_ARM_CORE_OPTION(_nr) \
+ (EXYNOS3_ARM_CORE0_OPTION + ((_nr) * 0x80))
+
+#define EXYNOS3_ARM_COMMON_OPTION 0x2408
+#define EXYNOS3_ARM_L2_OPTION 0x2608
+#define EXYNOS3_TOP_PWR_OPTION 0x2C48
+#define EXYNOS3_CORE_TOP_PWR_OPTION 0x2CA8
+#define EXYNOS3_XUSBXTI_DURATION 0x341C
+#define EXYNOS3_XXTI_DURATION 0x343C
+#define EXYNOS3_EXT_REGULATOR_DURATION 0x361C
+#define EXYNOS3_EXT_REGULATOR_COREBLK_DURATION 0x363C
+#define XUSBXTI_DURATION 0x00000BB8
+#define XXTI_DURATION XUSBXTI_DURATION
+#define EXT_REGULATOR_DURATION 0x00001D4C
+#define EXT_REGULATOR_COREBLK_DURATION EXT_REGULATOR_DURATION
+
+/* for XXX_OPTION */
+#define EXYNOS3_OPTION_USE_SC_COUNTER (1 << 0)
+#define EXYNOS3_OPTION_USE_SC_FEEDBACK (1 << 1)
+#define EXYNOS3_OPTION_SKIP_DEACTIVATE_ACEACP_IN_PWDN (1 << 7)
+
+/* For EXYNOS5 */
+
+#define EXYNOS5_AUTO_WDTRESET_DISABLE 0x0408
+#define EXYNOS5_MASK_WDTRESET_REQUEST 0x040C
+
+#define EXYNOS5_USE_RETENTION BIT(4)
+#define EXYNOS5_SYS_WDTRESET (1 << 20)
+
+#define EXYNOS5_ARM_CORE0_SYS_PWR_REG 0x1000
+#define EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG 0x1004
+#define EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG 0x1008
+#define EXYNOS5_ARM_CORE1_SYS_PWR_REG 0x1010
+#define EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG 0x1014
+#define EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG 0x1018
+#define EXYNOS5_FSYS_ARM_SYS_PWR_REG 0x1040
+#define EXYNOS5_DIS_IRQ_FSYS_ARM_CENTRAL_SYS_PWR_REG 0x1048
+#define EXYNOS5_ISP_ARM_SYS_PWR_REG 0x1050
+#define EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG 0x1054
+#define EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG 0x1058
+#define EXYNOS5_ARM_COMMON_SYS_PWR_REG 0x1080
+#define EXYNOS5_ARM_L2_SYS_PWR_REG 0x10C0
+#define EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG 0x1100
+#define EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG 0x1104
+#define EXYNOS5_CMU_RESET_SYS_PWR_REG 0x110C
+#define EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG 0x1120
+#define EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG 0x1124
+#define EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG 0x112C
+#define EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG 0x1130
+#define EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG 0x1134
+#define EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG 0x1138
+#define EXYNOS5_APLL_SYSCLK_SYS_PWR_REG 0x1140
+#define EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG 0x1144
+#define EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG 0x1148
+#define EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG 0x114C
+#define EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG 0x1150
+#define EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG 0x1154
+#define EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG 0x1164
+#define EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG 0x1170
+#define EXYNOS5_TOP_BUS_SYS_PWR_REG 0x1180
+#define EXYNOS5_TOP_RETENTION_SYS_PWR_REG 0x1184
+#define EXYNOS5_TOP_PWR_SYS_PWR_REG 0x1188
+#define EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG 0x1190
+#define EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG 0x1194
+#define EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG 0x1198
+#define EXYNOS5_LOGIC_RESET_SYS_PWR_REG 0x11A0
+#define EXYNOS5_OSCCLK_GATE_SYS_PWR_REG 0x11A4
+#define EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG 0x11B0
+#define EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG 0x11B4
+#define EXYNOS5_USBOTG_MEM_SYS_PWR_REG 0x11C0
+#define EXYNOS5_G2D_MEM_SYS_PWR_REG 0x11C8
+#define EXYNOS5_USBDRD_MEM_SYS_PWR_REG 0x11CC
+#define EXYNOS5_SDMMC_MEM_SYS_PWR_REG 0x11D0
+#define EXYNOS5_CSSYS_MEM_SYS_PWR_REG 0x11D4
+#define EXYNOS5_SECSS_MEM_SYS_PWR_REG 0x11D8
+#define EXYNOS5_ROTATOR_MEM_SYS_PWR_REG 0x11DC
+#define EXYNOS5_INTRAM_MEM_SYS_PWR_REG 0x11E0
+#define EXYNOS5_INTROM_MEM_SYS_PWR_REG 0x11E4
+#define EXYNOS5_JPEG_MEM_SYS_PWR_REG 0x11E8
+#define EXYNOS5_HSI_MEM_SYS_PWR_REG 0x11EC
+#define EXYNOS5_MCUIOP_MEM_SYS_PWR_REG 0x11F4
+#define EXYNOS5_SATA_MEM_SYS_PWR_REG 0x11FC
+#define EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG 0x1200
+#define EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG 0x1204
+#define EXYNOS5_PAD_RETENTION_EFNAND_SYS_PWR_REG 0x1208
+#define EXYNOS5_PAD_RETENTION_GPIO_SYS_PWR_REG 0x1220
+#define EXYNOS5_PAD_RETENTION_UART_SYS_PWR_REG 0x1224
+#define EXYNOS5_PAD_RETENTION_MMCA_SYS_PWR_REG 0x1228
+#define EXYNOS5_PAD_RETENTION_MMCB_SYS_PWR_REG 0x122C
+#define EXYNOS5_PAD_RETENTION_EBIA_SYS_PWR_REG 0x1230
+#define EXYNOS5_PAD_RETENTION_EBIB_SYS_PWR_REG 0x1234
+#define EXYNOS5_PAD_RETENTION_SPI_SYS_PWR_REG 0x1238
+#define EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_SYS_PWR_REG 0x123C
+#define EXYNOS5_PAD_ISOLATION_SYS_PWR_REG 0x1240
+#define EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG 0x1250
+#define EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG 0x1260
+#define EXYNOS5_XUSBXTI_SYS_PWR_REG 0x1280
+#define EXYNOS5_XXTI_SYS_PWR_REG 0x1284
+#define EXYNOS5_EXT_REGULATOR_SYS_PWR_REG 0x12C0
+#define EXYNOS5_GPIO_MODE_SYS_PWR_REG 0x1300
+#define EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG 0x1320
+#define EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG 0x1340
+#define EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG 0x1344
+#define EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG 0x1348
+#define EXYNOS5_GSCL_SYS_PWR_REG 0x1400
+#define EXYNOS5_ISP_SYS_PWR_REG 0x1404
+#define EXYNOS5_MFC_SYS_PWR_REG 0x1408
+#define EXYNOS5_G3D_SYS_PWR_REG 0x140C
+#define EXYNOS5_DISP1_SYS_PWR_REG 0x1414
+#define EXYNOS5_MAU_SYS_PWR_REG 0x1418
+#define EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG 0x1480
+#define EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG 0x1484
+#define EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG 0x1488
+#define EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG 0x148C
+#define EXYNOS5_CMU_CLKSTOP_DISP1_SYS_PWR_REG 0x1494
+#define EXYNOS5_CMU_CLKSTOP_MAU_SYS_PWR_REG 0x1498
+#define EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG 0x14C0
+#define EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG 0x14C4
+#define EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG 0x14C8
+#define EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG 0x14CC
+#define EXYNOS5_CMU_SYSCLK_DISP1_SYS_PWR_REG 0x14D4
+#define EXYNOS5_CMU_SYSCLK_MAU_SYS_PWR_REG 0x14D8
+#define EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG 0x1580
+#define EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG 0x1584
+#define EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG 0x1588
+#define EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG 0x158C
+#define EXYNOS5_CMU_RESET_DISP1_SYS_PWR_REG 0x1594
+#define EXYNOS5_CMU_RESET_MAU_SYS_PWR_REG 0x1598
+
+#define EXYNOS5_ARM_CORE0_OPTION 0x2008
+#define EXYNOS5_ARM_CORE1_OPTION 0x2088
+#define EXYNOS5_FSYS_ARM_OPTION 0x2208
+#define EXYNOS5_ISP_ARM_OPTION 0x2288
+#define EXYNOS5_ARM_COMMON_OPTION 0x2408
+#define EXYNOS5_ARM_L2_OPTION 0x2608
+#define EXYNOS5_TOP_PWR_OPTION 0x2C48
+#define EXYNOS5_TOP_PWR_SYSMEM_OPTION 0x2CC8
+#define EXYNOS5_JPEG_MEM_OPTION 0x2F48
+#define EXYNOS5_GSCL_OPTION 0x4008
+#define EXYNOS5_ISP_OPTION 0x4028
+#define EXYNOS5_MFC_OPTION 0x4048
+#define EXYNOS5_G3D_OPTION 0x4068
+#define EXYNOS5_DISP1_OPTION 0x40A8
+#define EXYNOS5_MAU_OPTION 0x40C8
+
+#define EXYNOS5_USE_SC_FEEDBACK (1 << 1)
+#define EXYNOS5_USE_SC_COUNTER (1 << 0)
+
+#define EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN (1 << 7)
+
+#define EXYNOS5_OPTION_USE_STANDBYWFE (1 << 24)
+#define EXYNOS5_OPTION_USE_STANDBYWFI (1 << 16)
+
+#define EXYNOS5_OPTION_USE_RETENTION (1 << 4)
+
+#define EXYNOS5420_SWRESET_KFC_SEL 0x3
+
+#include <asm/cputype.h>
+#define MAX_CPUS_IN_CLUSTER 4
+
+static inline unsigned int exynos_pmu_cpunr(unsigned int mpidr)
+{
+ return ((MPIDR_AFFINITY_LEVEL(mpidr, 1) * MAX_CPUS_IN_CLUSTER)
+ + MPIDR_AFFINITY_LEVEL(mpidr, 0));
+}
+
+/* Only for EXYNOS5420 */
+#define EXYNOS5420_ISP_ARM_OPTION 0x2488
+#define EXYNOS5420_L2RSTDISABLE_VALUE BIT(3)
+
+#define EXYNOS5420_LPI_MASK 0x0004
+#define EXYNOS5420_LPI_MASK1 0x0008
+#define EXYNOS5420_UFS BIT(8)
+#define EXYNOS5420_ATB_KFC BIT(13)
+#define EXYNOS5420_ATB_ISP_ARM BIT(19)
+#define EXYNOS5420_EMULATION BIT(31)
+#define ATB_ISP_ARM BIT(12)
+#define ATB_KFC BIT(13)
+#define ATB_NOC BIT(14)
+
+#define EXYNOS5420_ARM_INTR_SPREAD_ENABLE 0x0100
+#define EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI 0x0104
+#define EXYNOS5420_UP_SCHEDULER 0x0120
+#define SPREAD_ENABLE 0xF
+#define SPREAD_USE_STANDWFI 0xF
+
+#define EXYNOS5420_BB_CON1 0x0784
+#define EXYNOS5420_BB_SEL_EN BIT(31)
+#define EXYNOS5420_BB_PMOS_EN BIT(7)
+#define EXYNOS5420_BB_1300X 0XF
+
+#define EXYNOS5420_ARM_CORE2_SYS_PWR_REG 0x1020
+#define EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG 0x1024
+#define EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG 0x1028
+#define EXYNOS5420_ARM_CORE3_SYS_PWR_REG 0x1030
+#define EXYNOS5420_DIS_IRQ_ARM_CORE3_LOCAL_SYS_PWR_REG 0x1034
+#define EXYNOS5420_DIS_IRQ_ARM_CORE3_CENTRAL_SYS_PWR_REG 0x1038
+#define EXYNOS5420_KFC_CORE0_SYS_PWR_REG 0x1040
+#define EXYNOS5420_DIS_IRQ_KFC_CORE0_LOCAL_SYS_PWR_REG 0x1044
+#define EXYNOS5420_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG 0x1048
+#define EXYNOS5420_KFC_CORE1_SYS_PWR_REG 0x1050
+#define EXYNOS5420_DIS_IRQ_KFC_CORE1_LOCAL_SYS_PWR_REG 0x1054
+#define EXYNOS5420_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG 0x1058
+#define EXYNOS5420_KFC_CORE2_SYS_PWR_REG 0x1060
+#define EXYNOS5420_DIS_IRQ_KFC_CORE2_LOCAL_SYS_PWR_REG 0x1064
+#define EXYNOS5420_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG 0x1068
+#define EXYNOS5420_KFC_CORE3_SYS_PWR_REG 0x1070
+#define EXYNOS5420_DIS_IRQ_KFC_CORE3_LOCAL_SYS_PWR_REG 0x1074
+#define EXYNOS5420_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG 0x1078
+#define EXYNOS5420_ISP_ARM_SYS_PWR_REG 0x1090
+#define EXYNOS5420_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG 0x1094
+#define EXYNOS5420_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG 0x1098
+#define EXYNOS5420_ARM_COMMON_SYS_PWR_REG 0x10A0
+#define EXYNOS5420_KFC_COMMON_SYS_PWR_REG 0x10B0
+#define EXYNOS5420_KFC_L2_SYS_PWR_REG 0x10D0
+#define EXYNOS5420_DPLL_SYSCLK_SYS_PWR_REG 0x1158
+#define EXYNOS5420_IPLL_SYSCLK_SYS_PWR_REG 0x115C
+#define EXYNOS5420_KPLL_SYSCLK_SYS_PWR_REG 0x1160
+#define EXYNOS5420_RPLL_SYSCLK_SYS_PWR_REG 0x1174
+#define EXYNOS5420_SPLL_SYSCLK_SYS_PWR_REG 0x1178
+#define EXYNOS5420_INTRAM_MEM_SYS_PWR_REG 0x11B8
+#define EXYNOS5420_INTROM_MEM_SYS_PWR_REG 0x11BC
+#define EXYNOS5420_ONENANDXL_MEM_SYS_PWR 0x11C0
+#define EXYNOS5420_USBDEV_MEM_SYS_PWR 0x11CC
+#define EXYNOS5420_USBDEV1_MEM_SYS_PWR 0x11D0
+#define EXYNOS5420_SDMMC_MEM_SYS_PWR 0x11D4
+#define EXYNOS5420_CSSYS_MEM_SYS_PWR 0x11D8
+#define EXYNOS5420_SECSS_MEM_SYS_PWR 0x11DC
+#define EXYNOS5420_ROTATOR_MEM_SYS_PWR 0x11E0
+#define EXYNOS5420_INTRAM_MEM_SYS_PWR 0x11E4
+#define EXYNOS5420_INTROM_MEM_SYS_PWR 0x11E8
+#define EXYNOS5420_PAD_RETENTION_JTAG_SYS_PWR_REG 0x1208
+#define EXYNOS5420_PAD_RETENTION_DRAM_SYS_PWR_REG 0x1210
+#define EXYNOS5420_PAD_RETENTION_UART_SYS_PWR_REG 0x1214
+#define EXYNOS5420_PAD_RETENTION_MMC0_SYS_PWR_REG 0x1218
+#define EXYNOS5420_PAD_RETENTION_MMC1_SYS_PWR_REG 0x121C
+#define EXYNOS5420_PAD_RETENTION_MMC2_SYS_PWR_REG 0x1220
+#define EXYNOS5420_PAD_RETENTION_HSI_SYS_PWR_REG 0x1224
+#define EXYNOS5420_PAD_RETENTION_EBIA_SYS_PWR_REG 0x1228
+#define EXYNOS5420_PAD_RETENTION_EBIB_SYS_PWR_REG 0x122C
+#define EXYNOS5420_PAD_RETENTION_SPI_SYS_PWR_REG 0x1230
+#define EXYNOS5420_PAD_RETENTION_DRAM_COREBLK_SYS_PWR_REG 0x1234
+#define EXYNOS5420_DISP1_SYS_PWR_REG 0x1410
+#define EXYNOS5420_MAU_SYS_PWR_REG 0x1414
+#define EXYNOS5420_G2D_SYS_PWR_REG 0x1418
+#define EXYNOS5420_MSC_SYS_PWR_REG 0x141C
+#define EXYNOS5420_FSYS_SYS_PWR_REG 0x1420
+#define EXYNOS5420_FSYS2_SYS_PWR_REG 0x1424
+#define EXYNOS5420_PSGEN_SYS_PWR_REG 0x1428
+#define EXYNOS5420_PERIC_SYS_PWR_REG 0x142C
+#define EXYNOS5420_WCORE_SYS_PWR_REG 0x1430
+#define EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG 0x1490
+#define EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG 0x1494
+#define EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG 0x1498
+#define EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG 0x149C
+#define EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG 0x14A0
+#define EXYNOS5420_CMU_CLKSTOP_FSYS2_SYS_PWR_REG 0x14A4
+#define EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG 0x14A8
+#define EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG 0x14AC
+#define EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG 0x14B0
+#define EXYNOS5420_CMU_SYSCLK_TOPPWR_SYS_PWR_REG 0x14BC
+#define EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG 0x14D0
+#define EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG 0x14D4
+#define EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG 0x14D8
+#define EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG 0x14DC
+#define EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG 0x14E0
+#define EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG 0x14E4
+#define EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG 0x14E8
+#define EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG 0x14EC
+#define EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG 0x14F0
+#define EXYNOS5420_CMU_SYSCLK_SYSMEM_TOPPWR_SYS_PWR_REG 0x14F4
+#define EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG 0x1570
+#define EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG 0x1574
+#define EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG 0x1578
+#define EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG 0x157C
+#define EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG 0x1590
+#define EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG 0x1594
+#define EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG 0x1598
+#define EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG 0x159C
+#define EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG 0x15A0
+#define EXYNOS5420_SFR_AXI_CGDIS1 0x15E4
+#define EXYNOS_ARM_CORE2_CONFIGURATION 0x2100
+#define EXYNOS5420_ARM_CORE2_OPTION 0x2108
+#define EXYNOS_ARM_CORE3_CONFIGURATION 0x2180
+#define EXYNOS5420_ARM_CORE3_OPTION 0x2188
+#define EXYNOS5420_ARM_COMMON_STATUS 0x2504
+#define EXYNOS5420_ARM_COMMON_OPTION 0x2508
+#define EXYNOS5420_KFC_COMMON_STATUS 0x2584
+#define EXYNOS5420_KFC_COMMON_OPTION 0x2588
+#define EXYNOS5420_LOGIC_RESET_DURATION3 0x2D1C
+
+#define EXYNOS5420_PAD_RET_GPIO_OPTION 0x30C8
+#define EXYNOS5420_PAD_RET_UART_OPTION 0x30E8
+#define EXYNOS5420_PAD_RET_MMCA_OPTION 0x3108
+#define EXYNOS5420_PAD_RET_MMCB_OPTION 0x3128
+#define EXYNOS5420_PAD_RET_MMCC_OPTION 0x3148
+#define EXYNOS5420_PAD_RET_HSI_OPTION 0x3168
+#define EXYNOS5420_PAD_RET_SPI_OPTION 0x31C8
+#define EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION 0x31E8
+#define EXYNOS_PAD_RET_DRAM_OPTION 0x3008
+#define EXYNOS_PAD_RET_MAUDIO_OPTION 0x3028
+#define EXYNOS_PAD_RET_JTAG_OPTION 0x3048
+#define EXYNOS_PAD_RET_GPIO_OPTION 0x3108
+#define EXYNOS_PAD_RET_UART_OPTION 0x3128
+#define EXYNOS_PAD_RET_MMCA_OPTION 0x3148
+#define EXYNOS_PAD_RET_MMCB_OPTION 0x3168
+#define EXYNOS_PAD_RET_EBIA_OPTION 0x3188
+#define EXYNOS_PAD_RET_EBIB_OPTION 0x31A8
+
+#define EXYNOS_PS_HOLD_CONTROL 0x330C
+
+/* For SYS_PWR_REG */
+#define EXYNOS_SYS_PWR_CFG BIT(0)
+
+#define EXYNOS5420_MFC_CONFIGURATION 0x4060
+#define EXYNOS5420_MFC_STATUS 0x4064
+#define EXYNOS5420_MFC_OPTION 0x4068
+#define EXYNOS5420_G3D_CONFIGURATION 0x4080
+#define EXYNOS5420_G3D_STATUS 0x4084
+#define EXYNOS5420_G3D_OPTION 0x4088
+#define EXYNOS5420_DISP0_CONFIGURATION 0x40A0
+#define EXYNOS5420_DISP0_STATUS 0x40A4
+#define EXYNOS5420_DISP0_OPTION 0x40A8
+#define EXYNOS5420_DISP1_CONFIGURATION 0x40C0
+#define EXYNOS5420_DISP1_STATUS 0x40C4
+#define EXYNOS5420_DISP1_OPTION 0x40C8
+#define EXYNOS5420_MAU_CONFIGURATION 0x40E0
+#define EXYNOS5420_MAU_STATUS 0x40E4
+#define EXYNOS5420_MAU_OPTION 0x40E8
+#define EXYNOS5420_FSYS2_OPTION 0x4168
+#define EXYNOS5420_PSGEN_OPTION 0x4188
+
+/* For EXYNOS_CENTRAL_SEQ_OPTION */
+#define EXYNOS5_USE_STANDBYWFI_ARM_CORE0 BIT(16)
+#define EXYNOS5_USE_STANDBYWFI_ARM_CORE1 BUT(17)
+#define EXYNOS5_USE_STANDBYWFE_ARM_CORE0 BIT(24)
+#define EXYNOS5_USE_STANDBYWFE_ARM_CORE1 BIT(25)
+
+#define EXYNOS5420_ARM_USE_STANDBY_WFI0 BIT(4)
+#define EXYNOS5420_ARM_USE_STANDBY_WFI1 BIT(5)
+#define EXYNOS5420_ARM_USE_STANDBY_WFI2 BIT(6)
+#define EXYNOS5420_ARM_USE_STANDBY_WFI3 BIT(7)
+#define EXYNOS5420_KFC_USE_STANDBY_WFI0 BIT(8)
+#define EXYNOS5420_KFC_USE_STANDBY_WFI1 BIT(9)
+#define EXYNOS5420_KFC_USE_STANDBY_WFI2 BIT(10)
+#define EXYNOS5420_KFC_USE_STANDBY_WFI3 BIT(11)
+#define EXYNOS5420_ARM_USE_STANDBY_WFE0 BIT(16)
+#define EXYNOS5420_ARM_USE_STANDBY_WFE1 BIT(17)
+#define EXYNOS5420_ARM_USE_STANDBY_WFE2 BIT(18)
+#define EXYNOS5420_ARM_USE_STANDBY_WFE3 BIT(19)
+#define EXYNOS5420_KFC_USE_STANDBY_WFE0 BIT(20)
+#define EXYNOS5420_KFC_USE_STANDBY_WFE1 BIT(21)
+#define EXYNOS5420_KFC_USE_STANDBY_WFE2 BIT(22)
+#define EXYNOS5420_KFC_USE_STANDBY_WFE3 BIT(23)
+
+#define DUR_WAIT_RESET 0xF
+
+#define EXYNOS5420_USE_STANDBY_WFI_ALL (EXYNOS5420_ARM_USE_STANDBY_WFI0 \
+ | EXYNOS5420_ARM_USE_STANDBY_WFI1 \
+ | EXYNOS5420_ARM_USE_STANDBY_WFI2 \
+ | EXYNOS5420_ARM_USE_STANDBY_WFI3 \
+ | EXYNOS5420_KFC_USE_STANDBY_WFI0 \
+ | EXYNOS5420_KFC_USE_STANDBY_WFI1 \
+ | EXYNOS5420_KFC_USE_STANDBY_WFI2 \
+ | EXYNOS5420_KFC_USE_STANDBY_WFI3)
+
+#endif /* __ASM_ARCH_REGS_PMU_H */
diff --git a/arch/arm/mach-exynos/sleep.S b/arch/arm/mach-exynos/sleep.S
new file mode 100644
index 000000000..cf950790f
--- /dev/null
+++ b/arch/arm/mach-exynos/sleep.S
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Exynos low-level resume 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/asm-offsets.h>
+#include <asm/hardware/cache-l2x0.h>
+#include "smc.h"
+
+#define CPU_MASK 0xff0ffff0
+#define CPU_CORTEX_A9 0x410fc090
+
+ .text
+ .align
+
+ /*
+ * sleep magic, to allow the bootloader to check for an valid
+ * image to resume to. Must be the first word before the
+ * exynos_cpu_resume entry.
+ */
+
+ .word 0x2bedf00d
+
+ /*
+ * exynos_cpu_resume
+ *
+ * resume code entry for bootloader to call
+ */
+
+ENTRY(exynos_cpu_resume)
+#ifdef CONFIG_CACHE_L2X0
+ mrc p15, 0, r0, c0, c0, 0
+ ldr r1, =CPU_MASK
+ and r0, r0, r1
+ ldr r1, =CPU_CORTEX_A9
+ cmp r0, r1
+ bleq l2c310_early_resume
+#endif
+ b cpu_resume
+ENDPROC(exynos_cpu_resume)
+
+ .align
+
+ENTRY(exynos_cpu_resume_ns)
+ mrc p15, 0, r0, c0, c0, 0
+ ldr r1, =CPU_MASK
+ and r0, r0, r1
+ ldr r1, =CPU_CORTEX_A9
+ cmp r0, r1
+ bne skip_cp15
+
+ adr r0, _cp15_save_power
+ ldr r1, [r0]
+ ldr r1, [r0, r1]
+ adr r0, _cp15_save_diag
+ ldr r2, [r0]
+ ldr r2, [r0, r2]
+ mov r0, #SMC_CMD_C15RESUME
+ dsb
+ smc #0
+#ifdef CONFIG_CACHE_L2X0
+ adr r0, 1f
+ ldr r2, [r0]
+ add r0, r2, r0
+
+ /* Check that the address has been initialised. */
+ ldr r1, [r0, #L2X0_R_PHY_BASE]
+ teq r1, #0
+ beq skip_l2x0
+
+ /* Check if controller has been enabled. */
+ ldr r2, [r1, #L2X0_CTRL]
+ tst r2, #0x1
+ bne skip_l2x0
+
+ ldr r1, [r0, #L2X0_R_TAG_LATENCY]
+ ldr r2, [r0, #L2X0_R_DATA_LATENCY]
+ ldr r3, [r0, #L2X0_R_PREFETCH_CTRL]
+ mov r0, #SMC_CMD_L2X0SETUP1
+ smc #0
+
+ /* Reload saved regs pointer because smc corrupts registers. */
+ adr r0, 1f
+ ldr r2, [r0]
+ add r0, r2, r0
+
+ ldr r1, [r0, #L2X0_R_PWR_CTRL]
+ ldr r2, [r0, #L2X0_R_AUX_CTRL]
+ mov r0, #SMC_CMD_L2X0SETUP2
+ smc #0
+
+ mov r0, #SMC_CMD_L2X0INVALL
+ smc #0
+
+ mov r1, #1
+ mov r0, #SMC_CMD_L2X0CTRL
+ smc #0
+skip_l2x0:
+#endif /* CONFIG_CACHE_L2X0 */
+skip_cp15:
+ b cpu_resume
+ENDPROC(exynos_cpu_resume_ns)
+
+ .align
+_cp15_save_power:
+ .long cp15_save_power - .
+_cp15_save_diag:
+ .long cp15_save_diag - .
+#ifdef CONFIG_CACHE_L2X0
+1: .long l2x0_saved_regs - .
+#endif /* CONFIG_CACHE_L2X0 */
+
+ .data
+ .globl cp15_save_diag
+cp15_save_diag:
+ .long 0 @ cp15 diagnostic
+ .globl cp15_save_power
+cp15_save_power:
+ .long 0 @ cp15 power control
diff --git a/arch/arm/mach-exynos/smc.h b/arch/arm/mach-exynos/smc.h
new file mode 100644
index 000000000..c2845717b
--- /dev/null
+++ b/arch/arm/mach-exynos/smc.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics.
+ *
+ * EXYNOS - SMC Call
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_EXYNOS_SMC_H
+#define __ASM_ARCH_EXYNOS_SMC_H
+
+#define SMC_CMD_INIT (-1)
+#define SMC_CMD_INFO (-2)
+/* For Power Management */
+#define SMC_CMD_SLEEP (-3)
+#define SMC_CMD_CPU1BOOT (-4)
+#define SMC_CMD_CPU0AFTR (-5)
+#define SMC_CMD_SAVE (-6)
+#define SMC_CMD_SHUTDOWN (-7)
+/* For CP15 Access */
+#define SMC_CMD_C15RESUME (-11)
+/* For L2 Cache Access */
+#define SMC_CMD_L2X0CTRL (-21)
+#define SMC_CMD_L2X0SETUP1 (-22)
+#define SMC_CMD_L2X0SETUP2 (-23)
+#define SMC_CMD_L2X0INVALL (-24)
+#define SMC_CMD_L2X0DEBUG (-25)
+
+#ifndef __ASSEMBLY__
+
+extern void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3);
+
+#endif /* __ASSEMBLY__ */
+
+/* op type for SMC_CMD_SAVE and SMC_CMD_SHUTDOWN */
+#define OP_TYPE_CORE 0x0
+#define OP_TYPE_CLUSTER 0x1
+
+/* Power State required for SMC_CMD_SAVE and SMC_CMD_SHUTDOWN */
+#define SMC_POWERSTATE_IDLE 0x1
+
+#endif
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
new file mode 100644
index 000000000..7d23ce04c
--- /dev/null
+++ b/arch/arm/mach-exynos/suspend.c
@@ -0,0 +1,746 @@
+/*
+ * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - Suspend 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/cpu_pm.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/err.h>
+#include <linux/regulator/machine.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/firmware.h>
+#include <asm/mcpm.h>
+#include <asm/smp_scu.h>
+#include <asm/suspend.h>
+
+#include <plat/pm-common.h>
+#include <plat/regs-srom.h>
+
+#include "common.h"
+#include "regs-pmu.h"
+#include "exynos-pmu.h"
+
+#define S5P_CHECK_SLEEP 0x00000BAD
+
+#define REG_TABLE_END (-1U)
+
+#define EXYNOS5420_CPU_STATE 0x28
+
+/**
+ * struct exynos_wkup_irq - PMU IRQ to mask mapping
+ * @hwirq: Hardware IRQ signal of the PMU
+ * @mask: Mask in PMU wake-up mask register
+ */
+struct exynos_wkup_irq {
+ unsigned int hwirq;
+ u32 mask;
+};
+
+static struct sleep_save exynos_core_save[] = {
+ /* SROM side */
+ SAVE_ITEM(S5P_SROM_BW),
+ SAVE_ITEM(S5P_SROM_BC0),
+ SAVE_ITEM(S5P_SROM_BC1),
+ SAVE_ITEM(S5P_SROM_BC2),
+ SAVE_ITEM(S5P_SROM_BC3),
+};
+
+struct exynos_pm_data {
+ const struct exynos_wkup_irq *wkup_irq;
+ unsigned int wake_disable_mask;
+ unsigned int *release_ret_regs;
+
+ void (*pm_prepare)(void);
+ void (*pm_resume_prepare)(void);
+ void (*pm_resume)(void);
+ int (*pm_suspend)(void);
+ int (*cpu_suspend)(unsigned long);
+};
+
+static const struct exynos_pm_data *pm_data;
+
+static int exynos5420_cpu_state;
+static unsigned int exynos_pmu_spare3;
+
+/*
+ * GIC wake-up support
+ */
+
+static u32 exynos_irqwake_intmask = 0xffffffff;
+
+static const struct exynos_wkup_irq exynos3250_wkup_irq[] = {
+ { 73, BIT(1) }, /* RTC alarm */
+ { 74, BIT(2) }, /* RTC tick */
+ { /* sentinel */ },
+};
+
+static const struct exynos_wkup_irq exynos4_wkup_irq[] = {
+ { 44, BIT(1) }, /* RTC alarm */
+ { 45, BIT(2) }, /* RTC tick */
+ { /* sentinel */ },
+};
+
+static const struct exynos_wkup_irq exynos5250_wkup_irq[] = {
+ { 43, BIT(1) }, /* RTC alarm */
+ { 44, BIT(2) }, /* RTC tick */
+ { /* sentinel */ },
+};
+
+static unsigned int exynos_release_ret_regs[] = {
+ S5P_PAD_RET_MAUDIO_OPTION,
+ S5P_PAD_RET_GPIO_OPTION,
+ S5P_PAD_RET_UART_OPTION,
+ S5P_PAD_RET_MMCA_OPTION,
+ S5P_PAD_RET_MMCB_OPTION,
+ S5P_PAD_RET_EBIA_OPTION,
+ S5P_PAD_RET_EBIB_OPTION,
+ REG_TABLE_END,
+};
+
+static unsigned int exynos3250_release_ret_regs[] = {
+ S5P_PAD_RET_MAUDIO_OPTION,
+ S5P_PAD_RET_GPIO_OPTION,
+ S5P_PAD_RET_UART_OPTION,
+ S5P_PAD_RET_MMCA_OPTION,
+ S5P_PAD_RET_MMCB_OPTION,
+ S5P_PAD_RET_EBIA_OPTION,
+ S5P_PAD_RET_EBIB_OPTION,
+ S5P_PAD_RET_MMC2_OPTION,
+ S5P_PAD_RET_SPI_OPTION,
+ REG_TABLE_END,
+};
+
+static unsigned int exynos5420_release_ret_regs[] = {
+ EXYNOS_PAD_RET_DRAM_OPTION,
+ EXYNOS_PAD_RET_MAUDIO_OPTION,
+ EXYNOS_PAD_RET_JTAG_OPTION,
+ EXYNOS5420_PAD_RET_GPIO_OPTION,
+ EXYNOS5420_PAD_RET_UART_OPTION,
+ EXYNOS5420_PAD_RET_MMCA_OPTION,
+ EXYNOS5420_PAD_RET_MMCB_OPTION,
+ EXYNOS5420_PAD_RET_MMCC_OPTION,
+ EXYNOS5420_PAD_RET_HSI_OPTION,
+ EXYNOS_PAD_RET_EBIA_OPTION,
+ EXYNOS_PAD_RET_EBIB_OPTION,
+ EXYNOS5420_PAD_RET_SPI_OPTION,
+ EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION,
+ REG_TABLE_END,
+};
+
+static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
+{
+ const struct exynos_wkup_irq *wkup_irq;
+
+ if (!pm_data->wkup_irq)
+ return -ENOENT;
+ wkup_irq = pm_data->wkup_irq;
+
+ while (wkup_irq->mask) {
+ if (wkup_irq->hwirq == data->hwirq) {
+ if (!state)
+ exynos_irqwake_intmask |= wkup_irq->mask;
+ else
+ exynos_irqwake_intmask &= ~wkup_irq->mask;
+ return 0;
+ }
+ ++wkup_irq;
+ }
+
+ return -ENOENT;
+}
+
+static struct irq_chip exynos_pmu_chip = {
+ .name = "PMU",
+ .irq_eoi = irq_chip_eoi_parent,
+ .irq_mask = irq_chip_mask_parent,
+ .irq_unmask = irq_chip_unmask_parent,
+ .irq_retrigger = irq_chip_retrigger_hierarchy,
+ .irq_set_wake = exynos_irq_set_wake,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = irq_chip_set_affinity_parent,
+#endif
+};
+
+static int exynos_pmu_domain_xlate(struct irq_domain *domain,
+ struct device_node *controller,
+ const u32 *intspec,
+ unsigned int intsize,
+ unsigned long *out_hwirq,
+ unsigned int *out_type)
+{
+ if (domain->of_node != controller)
+ return -EINVAL; /* Shouldn't happen, really... */
+ if (intsize != 3)
+ return -EINVAL; /* Not GIC compliant */
+ if (intspec[0] != 0)
+ return -EINVAL; /* No PPI should point to this domain */
+
+ *out_hwirq = intspec[1];
+ *out_type = intspec[2];
+ return 0;
+}
+
+static int exynos_pmu_domain_alloc(struct irq_domain *domain,
+ unsigned int virq,
+ unsigned int nr_irqs, void *data)
+{
+ struct of_phandle_args *args = data;
+ struct of_phandle_args parent_args;
+ irq_hw_number_t hwirq;
+ int i;
+
+ if (args->args_count != 3)
+ return -EINVAL; /* Not GIC compliant */
+ if (args->args[0] != 0)
+ return -EINVAL; /* No PPI should point to this domain */
+
+ hwirq = args->args[1];
+
+ for (i = 0; i < nr_irqs; i++)
+ irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
+ &exynos_pmu_chip, NULL);
+
+ parent_args = *args;
+ parent_args.np = domain->parent->of_node;
+ return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args);
+}
+
+static struct irq_domain_ops exynos_pmu_domain_ops = {
+ .xlate = exynos_pmu_domain_xlate,
+ .alloc = exynos_pmu_domain_alloc,
+ .free = irq_domain_free_irqs_common,
+};
+
+static int __init exynos_pmu_irq_init(struct device_node *node,
+ struct device_node *parent)
+{
+ struct irq_domain *parent_domain, *domain;
+
+ if (!parent) {
+ pr_err("%s: no parent, giving up\n", node->full_name);
+ return -ENODEV;
+ }
+
+ parent_domain = irq_find_host(parent);
+ if (!parent_domain) {
+ pr_err("%s: unable to obtain parent domain\n", node->full_name);
+ return -ENXIO;
+ }
+
+ pmu_base_addr = of_iomap(node, 0);
+
+ if (!pmu_base_addr) {
+ pr_err("%s: failed to find exynos pmu register\n",
+ node->full_name);
+ return -ENOMEM;
+ }
+
+ domain = irq_domain_add_hierarchy(parent_domain, 0, 0,
+ node, &exynos_pmu_domain_ops,
+ NULL);
+ if (!domain) {
+ iounmap(pmu_base_addr);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+#define EXYNOS_PMU_IRQ(symbol, name) OF_DECLARE_2(irqchip, symbol, name, exynos_pmu_irq_init)
+
+EXYNOS_PMU_IRQ(exynos3250_pmu_irq, "samsung,exynos3250-pmu");
+EXYNOS_PMU_IRQ(exynos4210_pmu_irq, "samsung,exynos4210-pmu");
+EXYNOS_PMU_IRQ(exynos4212_pmu_irq, "samsung,exynos4212-pmu");
+EXYNOS_PMU_IRQ(exynos4412_pmu_irq, "samsung,exynos4412-pmu");
+EXYNOS_PMU_IRQ(exynos4415_pmu_irq, "samsung,exynos4415-pmu");
+EXYNOS_PMU_IRQ(exynos5250_pmu_irq, "samsung,exynos5250-pmu");
+EXYNOS_PMU_IRQ(exynos5420_pmu_irq, "samsung,exynos5420-pmu");
+
+static int exynos_cpu_do_idle(void)
+{
+ /* issue the standby signal into the pm unit. */
+ cpu_do_idle();
+
+ pr_info("Failed to suspend the system\n");
+ return 1; /* Aborting suspend */
+}
+static void exynos_flush_cache_all(void)
+{
+ flush_cache_all();
+ outer_flush_all();
+}
+
+static int exynos_cpu_suspend(unsigned long arg)
+{
+ exynos_flush_cache_all();
+ return exynos_cpu_do_idle();
+}
+
+static int exynos3250_cpu_suspend(unsigned long arg)
+{
+ flush_cache_all();
+ return exynos_cpu_do_idle();
+}
+
+static int exynos5420_cpu_suspend(unsigned long arg)
+{
+ /* MCPM works with HW CPU identifiers */
+ unsigned int mpidr = read_cpuid_mpidr();
+ unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+ unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+
+ __raw_writel(0x0, sysram_base_addr + EXYNOS5420_CPU_STATE);
+
+ if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) {
+ mcpm_set_entry_vector(cpu, cluster, exynos_cpu_resume);
+
+ /*
+ * Residency value passed to mcpm_cpu_suspend back-end
+ * has to be given clear semantics. Set to 0 as a
+ * temporary value.
+ */
+ mcpm_cpu_suspend(0);
+ }
+
+ pr_info("Failed to suspend the system\n");
+
+ /* return value != 0 means failure */
+ return 1;
+}
+
+static void exynos_pm_set_wakeup_mask(void)
+{
+ /* Set wake-up mask registers */
+ pmu_raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
+ pmu_raw_writel(exynos_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
+}
+
+static void exynos_pm_enter_sleep_mode(void)
+{
+ /* Set value of power down register for sleep mode */
+ exynos_sys_powerdown_conf(SYS_SLEEP);
+ pmu_raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1);
+}
+
+static void exynos_pm_prepare(void)
+{
+ exynos_set_delayed_reset_assertion(false);
+
+ /* Set wake-up mask registers */
+ exynos_pm_set_wakeup_mask();
+
+ s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
+
+ exynos_pm_enter_sleep_mode();
+
+ /* ensure at least INFORM0 has the resume address */
+ pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
+}
+
+static void exynos3250_pm_prepare(void)
+{
+ unsigned int tmp;
+
+ /* Set wake-up mask registers */
+ exynos_pm_set_wakeup_mask();
+
+ tmp = pmu_raw_readl(EXYNOS3_ARM_L2_OPTION);
+ tmp &= ~EXYNOS5_OPTION_USE_RETENTION;
+ pmu_raw_writel(tmp, EXYNOS3_ARM_L2_OPTION);
+
+ exynos_pm_enter_sleep_mode();
+
+ /* ensure at least INFORM0 has the resume address */
+ pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
+}
+
+static void exynos5420_pm_prepare(void)
+{
+ unsigned int tmp;
+
+ /* Set wake-up mask registers */
+ exynos_pm_set_wakeup_mask();
+
+ s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
+
+ exynos_pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3);
+ /*
+ * The cpu state needs to be saved and restored so that the
+ * secondary CPUs will enter low power start. Though the U-Boot
+ * is setting the cpu state with low power flag, the kernel
+ * needs to restore it back in case, the primary cpu fails to
+ * suspend for any reason.
+ */
+ exynos5420_cpu_state = __raw_readl(sysram_base_addr +
+ EXYNOS5420_CPU_STATE);
+
+ exynos_pm_enter_sleep_mode();
+
+ /* ensure at least INFORM0 has the resume address */
+ if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM))
+ pmu_raw_writel(virt_to_phys(mcpm_entry_point), S5P_INFORM0);
+
+ tmp = pmu_raw_readl(EXYNOS5_ARM_L2_OPTION);
+ tmp &= ~EXYNOS5_USE_RETENTION;
+ pmu_raw_writel(tmp, EXYNOS5_ARM_L2_OPTION);
+
+ tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
+ tmp |= EXYNOS5420_UFS;
+ pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1);
+
+ tmp = pmu_raw_readl(EXYNOS5420_ARM_COMMON_OPTION);
+ tmp &= ~EXYNOS5420_L2RSTDISABLE_VALUE;
+ pmu_raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION);
+
+ tmp = pmu_raw_readl(EXYNOS5420_FSYS2_OPTION);
+ tmp |= EXYNOS5420_EMULATION;
+ pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION);
+
+ tmp = pmu_raw_readl(EXYNOS5420_PSGEN_OPTION);
+ tmp |= EXYNOS5420_EMULATION;
+ pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION);
+}
+
+
+static int exynos_pm_suspend(void)
+{
+ exynos_pm_central_suspend();
+
+ /* Setting SEQ_OPTION register */
+ pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0,
+ S5P_CENTRAL_SEQ_OPTION);
+
+ if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
+ exynos_cpu_save_register();
+
+ return 0;
+}
+
+static int exynos5420_pm_suspend(void)
+{
+ u32 this_cluster;
+
+ exynos_pm_central_suspend();
+
+ /* Setting SEQ_OPTION register */
+
+ this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1);
+ if (!this_cluster)
+ pmu_raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0,
+ S5P_CENTRAL_SEQ_OPTION);
+ else
+ pmu_raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0,
+ S5P_CENTRAL_SEQ_OPTION);
+ return 0;
+}
+
+static void exynos_pm_release_retention(void)
+{
+ unsigned int i;
+
+ for (i = 0; (pm_data->release_ret_regs[i] != REG_TABLE_END); i++)
+ pmu_raw_writel(EXYNOS_WAKEUP_FROM_LOWPWR,
+ pm_data->release_ret_regs[i]);
+}
+
+static void exynos_pm_resume(void)
+{
+ u32 cpuid = read_cpuid_part();
+
+ if (exynos_pm_central_resume())
+ goto early_wakeup;
+
+ /* For release retention */
+ exynos_pm_release_retention();
+
+ s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
+
+ if (cpuid == ARM_CPU_PART_CORTEX_A9)
+ scu_enable(S5P_VA_SCU);
+
+ if (call_firmware_op(resume) == -ENOSYS
+ && cpuid == ARM_CPU_PART_CORTEX_A9)
+ exynos_cpu_restore_register();
+
+early_wakeup:
+
+ /* Clear SLEEP mode set in INFORM1 */
+ pmu_raw_writel(0x0, S5P_INFORM1);
+ exynos_set_delayed_reset_assertion(true);
+}
+
+static void exynos3250_pm_resume(void)
+{
+ u32 cpuid = read_cpuid_part();
+
+ if (exynos_pm_central_resume())
+ goto early_wakeup;
+
+ /* For release retention */
+ exynos_pm_release_retention();
+
+ pmu_raw_writel(S5P_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION);
+
+ if (call_firmware_op(resume) == -ENOSYS
+ && cpuid == ARM_CPU_PART_CORTEX_A9)
+ exynos_cpu_restore_register();
+
+early_wakeup:
+
+ /* Clear SLEEP mode set in INFORM1 */
+ pmu_raw_writel(0x0, S5P_INFORM1);
+}
+
+static void exynos5420_prepare_pm_resume(void)
+{
+ if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM))
+ WARN_ON(mcpm_cpu_powered_up());
+}
+
+static void exynos5420_pm_resume(void)
+{
+ unsigned long tmp;
+
+ /* Restore the CPU0 low power state register */
+ tmp = pmu_raw_readl(EXYNOS5_ARM_CORE0_SYS_PWR_REG);
+ pmu_raw_writel(tmp | S5P_CORE_LOCAL_PWR_EN,
+ EXYNOS5_ARM_CORE0_SYS_PWR_REG);
+
+ /* Restore the sysram cpu state register */
+ __raw_writel(exynos5420_cpu_state,
+ sysram_base_addr + EXYNOS5420_CPU_STATE);
+
+ pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL,
+ S5P_CENTRAL_SEQ_OPTION);
+
+ if (exynos_pm_central_resume())
+ goto early_wakeup;
+
+ /* For release retention */
+ exynos_pm_release_retention();
+
+ pmu_raw_writel(exynos_pmu_spare3, S5P_PMU_SPARE3);
+
+ s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
+
+early_wakeup:
+
+ tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
+ tmp &= ~EXYNOS5420_UFS;
+ pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1);
+
+ tmp = pmu_raw_readl(EXYNOS5420_FSYS2_OPTION);
+ tmp &= ~EXYNOS5420_EMULATION;
+ pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION);
+
+ tmp = pmu_raw_readl(EXYNOS5420_PSGEN_OPTION);
+ tmp &= ~EXYNOS5420_EMULATION;
+ pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION);
+
+ /* Clear SLEEP mode set in INFORM1 */
+ pmu_raw_writel(0x0, S5P_INFORM1);
+}
+
+/*
+ * Suspend Ops
+ */
+
+static int exynos_suspend_enter(suspend_state_t state)
+{
+ int ret;
+
+ s3c_pm_debug_init();
+
+ S3C_PMDBG("%s: suspending the system...\n", __func__);
+
+ S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__,
+ exynos_irqwake_intmask, exynos_get_eint_wake_mask());
+
+ if (exynos_irqwake_intmask == -1U
+ && exynos_get_eint_wake_mask() == -1U) {
+ pr_err("%s: No wake-up sources!\n", __func__);
+ pr_err("%s: Aborting sleep\n", __func__);
+ return -EINVAL;
+ }
+
+ s3c_pm_save_uarts();
+ if (pm_data->pm_prepare)
+ pm_data->pm_prepare();
+ flush_cache_all();
+ s3c_pm_check_store();
+
+ ret = call_firmware_op(suspend);
+ if (ret == -ENOSYS)
+ ret = cpu_suspend(0, pm_data->cpu_suspend);
+ if (ret)
+ return ret;
+
+ if (pm_data->pm_resume_prepare)
+ pm_data->pm_resume_prepare();
+ s3c_pm_restore_uarts();
+
+ S3C_PMDBG("%s: wakeup stat: %08x\n", __func__,
+ pmu_raw_readl(S5P_WAKEUP_STAT));
+
+ s3c_pm_check_restore();
+
+ S3C_PMDBG("%s: resuming the system...\n", __func__);
+
+ return 0;
+}
+
+static int exynos_suspend_prepare(void)
+{
+ int ret;
+
+ /*
+ * REVISIT: It would be better if struct platform_suspend_ops
+ * .prepare handler get the suspend_state_t as a parameter to
+ * avoid hard-coding the suspend to mem state. It's safe to do
+ * it now only because the suspend_valid_only_mem function is
+ * used as the .valid callback used to check if a given state
+ * is supported by the platform anyways.
+ */
+ ret = regulator_suspend_prepare(PM_SUSPEND_MEM);
+ if (ret) {
+ pr_err("Failed to prepare regulators for suspend (%d)\n", ret);
+ return ret;
+ }
+
+ s3c_pm_check_prepare();
+
+ return 0;
+}
+
+static void exynos_suspend_finish(void)
+{
+ int ret;
+
+ s3c_pm_check_cleanup();
+
+ ret = regulator_suspend_finish();
+ if (ret)
+ pr_warn("Failed to resume regulators from suspend (%d)\n", ret);
+}
+
+static const struct platform_suspend_ops exynos_suspend_ops = {
+ .enter = exynos_suspend_enter,
+ .prepare = exynos_suspend_prepare,
+ .finish = exynos_suspend_finish,
+ .valid = suspend_valid_only_mem,
+};
+
+static const struct exynos_pm_data exynos3250_pm_data = {
+ .wkup_irq = exynos3250_wkup_irq,
+ .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
+ .release_ret_regs = exynos3250_release_ret_regs,
+ .pm_suspend = exynos_pm_suspend,
+ .pm_resume = exynos3250_pm_resume,
+ .pm_prepare = exynos3250_pm_prepare,
+ .cpu_suspend = exynos3250_cpu_suspend,
+};
+
+static const struct exynos_pm_data exynos4_pm_data = {
+ .wkup_irq = exynos4_wkup_irq,
+ .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
+ .release_ret_regs = exynos_release_ret_regs,
+ .pm_suspend = exynos_pm_suspend,
+ .pm_resume = exynos_pm_resume,
+ .pm_prepare = exynos_pm_prepare,
+ .cpu_suspend = exynos_cpu_suspend,
+};
+
+static const struct exynos_pm_data exynos5250_pm_data = {
+ .wkup_irq = exynos5250_wkup_irq,
+ .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
+ .release_ret_regs = exynos_release_ret_regs,
+ .pm_suspend = exynos_pm_suspend,
+ .pm_resume = exynos_pm_resume,
+ .pm_prepare = exynos_pm_prepare,
+ .cpu_suspend = exynos_cpu_suspend,
+};
+
+static const struct exynos_pm_data exynos5420_pm_data = {
+ .wkup_irq = exynos5250_wkup_irq,
+ .wake_disable_mask = (0x7F << 7) | (0x1F << 1),
+ .release_ret_regs = exynos5420_release_ret_regs,
+ .pm_resume_prepare = exynos5420_prepare_pm_resume,
+ .pm_resume = exynos5420_pm_resume,
+ .pm_suspend = exynos5420_pm_suspend,
+ .pm_prepare = exynos5420_pm_prepare,
+ .cpu_suspend = exynos5420_cpu_suspend,
+};
+
+static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = {
+ {
+ .compatible = "samsung,exynos3250-pmu",
+ .data = &exynos3250_pm_data,
+ }, {
+ .compatible = "samsung,exynos4210-pmu",
+ .data = &exynos4_pm_data,
+ }, {
+ .compatible = "samsung,exynos4212-pmu",
+ .data = &exynos4_pm_data,
+ }, {
+ .compatible = "samsung,exynos4412-pmu",
+ .data = &exynos4_pm_data,
+ }, {
+ .compatible = "samsung,exynos5250-pmu",
+ .data = &exynos5250_pm_data,
+ }, {
+ .compatible = "samsung,exynos5420-pmu",
+ .data = &exynos5420_pm_data,
+ },
+ { /*sentinel*/ },
+};
+
+static struct syscore_ops exynos_pm_syscore_ops;
+
+void __init exynos_pm_init(void)
+{
+ const struct of_device_id *match;
+ struct device_node *np;
+ u32 tmp;
+
+ np = of_find_matching_node_and_match(NULL, exynos_pmu_of_device_ids, &match);
+ if (!np) {
+ pr_err("Failed to find PMU node\n");
+ return;
+ }
+
+ if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL))) {
+ pr_warn("Outdated DT detected, suspend/resume will NOT work\n");
+ return;
+ }
+
+ pm_data = (const struct exynos_pm_data *) match->data;
+
+ /* All wakeup disable */
+ tmp = pmu_raw_readl(S5P_WAKEUP_MASK);
+ tmp |= pm_data->wake_disable_mask;
+ pmu_raw_writel(tmp, S5P_WAKEUP_MASK);
+
+ exynos_pm_syscore_ops.suspend = pm_data->pm_suspend;
+ exynos_pm_syscore_ops.resume = pm_data->pm_resume;
+
+ register_syscore_ops(&exynos_pm_syscore_ops);
+ suspend_set_ops(&exynos_suspend_ops);
+}
diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig
new file mode 100644
index 000000000..07152d00f
--- /dev/null
+++ b/arch/arm/mach-footbridge/Kconfig
@@ -0,0 +1,99 @@
+if ARCH_FOOTBRIDGE
+
+menu "Footbridge Implementations"
+
+config ARCH_CATS
+ bool "CATS"
+ select CLKEVT_I8253
+ 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 ARCH_MAY_HAVE_PC_FDC
+ 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 CLKEVT_I8253
+ select CLKSRC_I8253
+ select FOOTBRIDGE_HOST
+ select ISA
+ select ISA_DMA
+ select PCI
+ select VIRT_TO_BUS
+ 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
+ select ARCH_MIGHT_HAVE_PC_SERIO
+
+# Footbridge in addin mode
+config FOOTBRIDGE_ADDIN
+ bool
+
+# EBSA285 board in either host or addin mode
+config ARCH_EBSA285
+ bool
+
+endif
diff --git a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile
new file mode 100644
index 000000000..e83d5c839
--- /dev/null
+++ b/arch/arm/mach-footbridge/Makefile
@@ -0,0 +1,22 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := common.o dma.o isa-irq.o
+
+pci-y += dc21285.o
+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
+
+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_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 000000000..ff0a4b5b0
--- /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 000000000..8f0548967
--- /dev/null
+++ b/arch/arm/mach-footbridge/cats-hw.c
@@ -0,0 +1,97 @@
+/*
+ * 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 tag *tags, char **cmdline)
+{
+#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
+ screen_info.orig_video_lines = 25;
+ screen_info.orig_video_points = 16;
+ screen_info.orig_y = 24;
+#endif
+}
+
+MACHINE_START(CATS, "Chalice-CATS")
+ /* Maintainer: Philip Blundell */
+ .atag_offset = 0x100,
+ .reboot_mode = REBOOT_SOFT,
+ .fixup = fixup_cats,
+ .map_io = footbridge_map_io,
+ .init_irq = footbridge_init_irq,
+ .init_time = isa_timer_init,
+ .restart = footbridge_restart,
+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 000000000..5cec2567c
--- /dev/null
+++ b/arch/arm/mach-footbridge/cats-pci.c
@@ -0,0 +1,63 @@
+/*
+ * 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 u8 cats_no_swizzle(struct pci_dev *dev, u8 *pin)
+{
+ return 0;
+}
+
+static int __init cats_map_irq(const 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 = cats_no_swizzle,
+ .map_irq = cats_map_irq,
+ .nr_controllers = 1,
+ .ops = &dc21285_ops,
+ .setup = dc21285_setup,
+ .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 000000000..9e8220e38
--- /dev/null
+++ b/arch/arm/mach-footbridge/common.c
@@ -0,0 +1,268 @@
+/*
+ * 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 <video/vga.h>
+
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+#include <asm/system_misc.h>
+#include <asm/hardware/dec21285.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+#include <asm/mach/pci.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,
+ }
+};
+
+/*
+ * 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,
+ },
+#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));
+ pci_map_io_early(__phys_to_pfn(DC21285_PCI_IO));
+ }
+
+ vga_base = PCIMEM_BASE;
+}
+
+void footbridge_restart(enum reboot_mode mode, const char *cmd)
+{
+ if (mode == REBOOT_SOFT) {
+ /* Jump into the ROM */
+ soft_restart(0x41000000);
+ } 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);
+ }
+}
+
+#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 000000000..b911e5587
--- /dev/null
+++ b/arch/arm/mach-footbridge/common.h
@@ -0,0 +1,14 @@
+#include <linux/reboot.h>
+
+extern void footbridge_timer_init(void);
+extern void isa_timer_init(void);
+
+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);
+extern void footbridge_restart(enum reboot_mode, const char *);
+
+extern void footbridge_sched_clock(void);
diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c
new file mode 100644
index 000000000..bf7aa7d29
--- /dev/null
+++ b/arch/arm/mach-footbridge/dc21285-timer.c
@@ -0,0 +1,142 @@
+/*
+ * 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 <linux/sched_clock.h>
+
+#include <asm/irq.h>
+
+#include <asm/hardware/dec21285.h>
+#include <asm/mach/time.h>
+#include <asm/system_info.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 int ckevt_dc21285_set_next_event(unsigned long delta,
+ struct clock_event_device *c)
+{
+ *CSR_TIMER1_CLR = 0;
+ *CSR_TIMER1_LOAD = delta;
+ *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
+
+ return 0;
+}
+
+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;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ *CSR_TIMER1_CNTL = 0;
+ break;
+ }
+}
+
+static struct clock_event_device ckevt_dc21285 = {
+ .name = "dc21285_timer1",
+ .features = CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 200,
+ .irq = IRQ_TIMER1,
+ .set_next_event = ckevt_dc21285_set_next_event,
+ .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;
+
+ /* Stop the timer if in one-shot mode */
+ if (ce->mode == CLOCK_EVT_MODE_ONESHOT)
+ *CSR_TIMER1_CNTL = 0;
+
+ ce->event_handler(ce);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction footbridge_timer_irq = {
+ .name = "dc21285_timer1",
+ .handler = timer1_interrupt,
+ .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ .dev_id = &ckevt_dc21285,
+};
+
+/*
+ * Set up timer interrupt.
+ */
+void __init footbridge_timer_init(void)
+{
+ struct clock_event_device *ce = &ckevt_dc21285;
+ unsigned rate = DIV_ROUND_CLOSEST(mem_fclk_21285, 16);
+
+ clocksource_register_hz(&cksrc_dc21285, rate);
+
+ setup_irq(ce->irq, &footbridge_timer_irq);
+
+ ce->cpumask = cpumask_of(smp_processor_id());
+ clockevents_config_and_register(ce, rate, 0x4, 0xffffff);
+}
+
+static u64 notrace footbridge_read_sched_clock(void)
+{
+ return ~*CSR_TIMER3_VALUE;
+}
+
+void __init footbridge_sched_clock(void)
+{
+ unsigned rate = DIV_ROUND_CLOSEST(mem_fclk_21285, 16);
+
+ *CSR_TIMER3_LOAD = 0;
+ *CSR_TIMER3_CLR = 0;
+ *CSR_TIMER3_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
+
+ sched_clock_register(footbridge_read_sched_clock, 24, rate);
+}
diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c
new file mode 100644
index 000000000..96a3d73ef
--- /dev/null
+++ b/arch/arm/mach-footbridge/dc21285.c
@@ -0,0 +1,376 @@
+/*
+ * 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/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;
+}
+
+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->mem_offset = DC21285_PCI_MEM;
+
+ pci_add_resource_offset(&sys->resources, &res[0], sys->mem_offset);
+ pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
+
+ return 1;
+}
+
+#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;
+
+ pcibios_min_mem = 0x81000000;
+
+ 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, 0,
+ "PCI system error", &serr_timer);
+ dc21285_request_irq(IRQ_PCI_PERR, dc21285_parity_irq, 0,
+ "PCI parity error", &perr_timer);
+ dc21285_request_irq(IRQ_PCI_ABORT, dc21285_abort_irq, 0,
+ "PCI abort", NULL);
+ dc21285_request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, 0,
+ "Discard timer", NULL);
+ dc21285_request_irq(IRQ_PCI_DPERR, dc21285_dparity_irq, 0,
+ "PCI data parity", NULL);
+
+ if (cfn_mode) {
+ /*
+ * 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 = 0;
+ *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 000000000..e2e0df8bc
--- /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-pci.c b/arch/arm/mach-footbridge/ebsa285-pci.c
new file mode 100644
index 000000000..fd12d8a36
--- /dev/null
+++ b/arch/arm/mach-footbridge/ebsa285-pci.c
@@ -0,0 +1,47 @@
+/*
+ * 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(const 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 = {
+ .map_irq = ebsa285_map_irq,
+ .nr_controllers = 1,
+ .ops = &dc21285_ops,
+ .setup = dc21285_setup,
+ .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 000000000..aee8300f3
--- /dev/null
+++ b/arch/arm/mach-footbridge/ebsa285.c
@@ -0,0 +1,123 @@
+/*
+ * linux/arch/arm/mach-footbridge/ebsa285.c
+ *
+ * EBSA285 machine fixup
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
+
+#include <asm/hardware/dec21285.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+#include "common.h"
+
+/* LEDs */
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+#define XBUS_AMBER_L BIT(0)
+#define XBUS_GREEN_L BIT(1)
+#define XBUS_RED_L BIT(2)
+#define XBUS_TOGGLE BIT(7)
+
+struct ebsa285_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;
+} ebsa285_leds[] = {
+ { "ebsa285:amber", "cpu0", },
+ { "ebsa285:green", "heartbeat", },
+ { "ebsa285:red",},
+};
+
+static unsigned char hw_led_state;
+static void __iomem *xbus;
+
+static void ebsa285_led_set(struct led_classdev *cdev,
+ enum led_brightness b)
+{
+ struct ebsa285_led *led = container_of(cdev,
+ struct ebsa285_led, cdev);
+
+ if (b == LED_OFF)
+ hw_led_state |= led->mask;
+ else
+ hw_led_state &= ~led->mask;
+ writeb(hw_led_state, xbus);
+}
+
+static enum led_brightness ebsa285_led_get(struct led_classdev *cdev)
+{
+ struct ebsa285_led *led = container_of(cdev,
+ struct ebsa285_led, cdev);
+
+ return hw_led_state & led->mask ? LED_OFF : LED_FULL;
+}
+
+static int __init ebsa285_leds_init(void)
+{
+ int i;
+
+ if (!machine_is_ebsa285())
+ return -ENODEV;
+
+ xbus = ioremap(XBUS_CS2, SZ_4K);
+ if (!xbus)
+ return -ENOMEM;
+
+ /* 3 LEDS all off */
+ hw_led_state = XBUS_AMBER_L | XBUS_GREEN_L | XBUS_RED_L;
+ writeb(hw_led_state, xbus);
+
+ for (i = 0; i < ARRAY_SIZE(ebsa285_leds); i++) {
+ struct ebsa285_led *led;
+
+ led = kzalloc(sizeof(*led), GFP_KERNEL);
+ if (!led)
+ break;
+
+ led->cdev.name = ebsa285_leds[i].name;
+ led->cdev.brightness_set = ebsa285_led_set;
+ led->cdev.brightness_get = ebsa285_led_get;
+ led->cdev.default_trigger = ebsa285_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(ebsa285_leds_init);
+#endif
+
+MACHINE_START(EBSA285, "EBSA285")
+ /* Maintainer: Russell King */
+ .atag_offset = 0x100,
+ .video_start = 0x000a0000,
+ .video_end = 0x000bffff,
+ .map_io = footbridge_map_io,
+ .init_early = footbridge_sched_clock,
+ .init_irq = footbridge_init_irq,
+ .init_time = footbridge_timer_init,
+ .restart = footbridge_restart,
+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 000000000..02247f313
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/debug-macro.S
@@ -0,0 +1,42 @@
+/* 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>
+
+#include <mach/hardware.h>
+ /* For EBSA285 debugging */
+ .equ dc21285_high, ARMCSR_BASE & 0xff000000
+ .equ dc21285_low, ARMCSR_BASE & 0x00ffffff
+
+ .macro addruart, rp, rv, tmp
+ .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
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 000000000..dabbd5c54
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/entry-macro.S
@@ -0,0 +1,107 @@
+/*
+ * 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 get_irqnr_preamble, base, tmp
+ mov \base, #dc21285_high
+ .if dc21285_low
+ orr \base, \base, #dc21285_low
+ .endif
+ .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 000000000..02f6d7a70
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/hardware.h
@@ -0,0 +1,99 @@
+/*
+ * 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_CS2 0x40012000
+
+#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 raw_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
+
+#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 000000000..aba46388c
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/io.h
@@ -0,0 +1,23 @@
+/*
+ * 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
+
+/*
+ * Translation of various i/o addresses to host addresses for !CONFIG_MMU
+ */
+#define PCIO_BASE 0x7c000000
+#define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
+
+#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 000000000..61c714c49
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/irqs.h
@@ -0,0 +1,96 @@
+/*
+ * 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)
+
+#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 000000000..5bd4a0d33
--- /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 000000000..6f2ecccdf
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/memory.h
@@ -0,0 +1,64 @@
+/*
+ * 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
+
+#define FLUSH_BASE_PHYS 0x50000000
+
+#endif
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 000000000..a69398c05
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/uncompress.h
@@ -0,0 +1,37 @@
+/*
+ * 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()
diff --git a/arch/arm/mach-footbridge/isa-irq.c b/arch/arm/mach-footbridge/isa-irq.c
new file mode 100644
index 000000000..c3a0abbc9
--- /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 000000000..07fde4051
--- /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 000000000..b73f52e19
--- /dev/null
+++ b/arch/arm/mach-footbridge/isa-timer.c
@@ -0,0 +1,40 @@
+/*
+ * linux/arch/arm/mach-footbridge/isa-timer.c
+ *
+ * Copyright (C) 1998 Russell King.
+ * Copyright (C) 1998 Phil Blundell
+ */
+#include <linux/clockchips.h>
+#include <linux/i8253.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <linux/timex.h>
+
+#include <asm/irq.h>
+#include <asm/mach/time.h>
+
+#include "common.h"
+
+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_TIMER | IRQF_IRQPOLL,
+ .dev_id = &i8253_clockevent,
+};
+
+void __init isa_timer_init(void)
+{
+ clocksource_i8253_init();
+
+ setup_irq(i8253_clockevent.irq, &pit_timer_irq);
+ clockevent_i8253_init(false);
+}
diff --git a/arch/arm/mach-footbridge/isa.c b/arch/arm/mach-footbridge/isa.c
new file mode 100644
index 000000000..4d9276c27
--- /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 000000000..cdee08c6d
--- /dev/null
+++ b/arch/arm/mach-footbridge/netwinder-hw.c
@@ -0,0 +1,771 @@
+/*
+ * 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 <linux/slab.h>
+#include <linux/leds.h>
+
+#include <asm/hardware/dec21285.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+#include <asm/system_misc.h>
+
+#include <asm/mach/arch.h>
+
+#include "common.h"
+
+#define IRDA_IO_BASE 0x180
+#define GP1_IO_BASE 0x338
+#define GP2_IO_BASE 0x33a
+
+/*
+ * 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_RAW_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
+ */
+ raw_spin_lock_irqsave(&nw_gpio_lock, flags);
+ nw_gpio_modify_op(-1, GPIO_RED_LED | GPIO_FAN);
+ raw_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;
+
+ raw_spin_lock_irqsave(&nw_gpio_lock, flags);
+ nw_cpld_modify(-1, CPLD_UNMUTE | CPLD_7111_DISABLE);
+ raw_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()) {
+ wb977_init();
+ cpld_init();
+ rwa010_init();
+ }
+ 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 tag *tags, char **cmdline)
+{
+#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
+}
+
+static void netwinder_restart(enum reboot_mode mode, const char *cmd)
+{
+ if (mode == REBOOT_SOFT) {
+ /* Jump into the ROM */
+ soft_restart(0x41000000);
+ } else {
+ local_irq_disable();
+ local_fiq_disable();
+
+ /* 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);
+ }
+}
+
+/* LEDs */
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+struct netwinder_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;
+} netwinder_leds[] = {
+ { "netwinder:green", "heartbeat", },
+ { "netwinder:red", "cpu0", },
+};
+
+/*
+ * The LED control in Netwinder is reversed:
+ * - setting bit means turn off LED
+ * - clearing bit means turn on LED
+ */
+static void netwinder_led_set(struct led_classdev *cdev,
+ enum led_brightness b)
+{
+ struct netwinder_led *led = container_of(cdev,
+ struct netwinder_led, cdev);
+ unsigned long flags;
+ u32 reg;
+
+ raw_spin_lock_irqsave(&nw_gpio_lock, flags);
+ reg = nw_gpio_read();
+ if (b != LED_OFF)
+ reg &= ~led->mask;
+ else
+ reg |= led->mask;
+ nw_gpio_modify_op(led->mask, reg);
+ raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
+}
+
+static enum led_brightness netwinder_led_get(struct led_classdev *cdev)
+{
+ struct netwinder_led *led = container_of(cdev,
+ struct netwinder_led, cdev);
+ unsigned long flags;
+ u32 reg;
+
+ raw_spin_lock_irqsave(&nw_gpio_lock, flags);
+ reg = nw_gpio_read();
+ raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
+
+ return (reg & led->mask) ? LED_OFF : LED_FULL;
+}
+
+static int __init netwinder_leds_init(void)
+{
+ int i;
+
+ if (!machine_is_netwinder())
+ return -ENODEV;
+
+ for (i = 0; i < ARRAY_SIZE(netwinder_leds); i++) {
+ struct netwinder_led *led;
+
+ led = kzalloc(sizeof(*led), GFP_KERNEL);
+ if (!led)
+ break;
+
+ led->cdev.name = netwinder_leds[i].name;
+ led->cdev.brightness_set = netwinder_led_set;
+ led->cdev.brightness_get = netwinder_led_get;
+ led->cdev.default_trigger = netwinder_leds[i].trigger;
+
+ if (i == 0)
+ led->mask = GPIO_GREEN_LED;
+ else
+ led->mask = GPIO_RED_LED;
+
+ 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(netwinder_leds_init);
+#endif
+
+MACHINE_START(NETWINDER, "Rebel-NetWinder")
+ /* Maintainer: Russell King/Rebel.com */
+ .atag_offset = 0x100,
+ .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,
+ .init_time = isa_timer_init,
+ .restart = netwinder_restart,
+MACHINE_END
diff --git a/arch/arm/mach-footbridge/netwinder-pci.c b/arch/arm/mach-footbridge/netwinder-pci.c
new file mode 100644
index 000000000..0fba5134e
--- /dev/null
+++ b/arch/arm/mach-footbridge/netwinder-pci.c
@@ -0,0 +1,61 @@
+/*
+ * 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(const 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 = {
+ .map_irq = netwinder_map_irq,
+ .nr_controllers = 1,
+ .ops = &dc21285_ops,
+ .setup = dc21285_setup,
+ .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 000000000..5c9ee5461
--- /dev/null
+++ b/arch/arm/mach-footbridge/personal-pci.c
@@ -0,0 +1,57 @@
+/*
+ * 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(const 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,
+ .ops = &dc21285_ops,
+ .setup = dc21285_setup,
+ .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 000000000..7bdeabdcd
--- /dev/null
+++ b/arch/arm/mach-footbridge/personal.c
@@ -0,0 +1,24 @@
+/*
+ * 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 */
+ .atag_offset = 0x100,
+ .map_io = footbridge_map_io,
+ .init_irq = footbridge_init_irq,
+ .init_time = footbridge_timer_init,
+ .restart = footbridge_restart,
+MACHINE_END
+
diff --git a/arch/arm/mach-gemini/Kconfig b/arch/arm/mach-gemini/Kconfig
new file mode 100644
index 000000000..6f066ee4b
--- /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 000000000..7963a77be
--- /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 idle.o reset.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 000000000..683f52b20
--- /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 000000000..ca8a25bb3
--- /dev/null
+++ b/arch/arm/mach-gemini/board-nas4220b.c
@@ -0,0 +1,107 @@
+/*
+ * 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 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")
+ .atag_offset = 0x100,
+ .map_io = gemini_map_io,
+ .init_irq = gemini_init_irq,
+ .init_time = gemini_timer_init,
+ .init_machine = ib4220b_init,
+ .restart = gemini_restart,
+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 000000000..7a675f88f
--- /dev/null
+++ b/arch/arm/mach-gemini/board-rut1xx.c
@@ -0,0 +1,92 @@
+/*
+ * 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 <linux/sizes.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 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")
+ .atag_offset = 0x100,
+ .map_io = gemini_map_io,
+ .init_irq = gemini_init_irq,
+ .init_time = gemini_timer_init,
+ .init_machine = rut1xx_init,
+ .restart = gemini_restart,
+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 000000000..418188cd1
--- /dev/null
+++ b/arch/arm/mach-gemini/board-wbd111.c
@@ -0,0 +1,134 @@
+/*
+ * 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 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")
+ .atag_offset = 0x100,
+ .map_io = gemini_map_io,
+ .init_irq = gemini_init_irq,
+ .init_time = gemini_timer_init,
+ .init_machine = wbd111_init,
+ .restart = gemini_restart,
+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 000000000..266b26509
--- /dev/null
+++ b/arch/arm/mach-gemini/board-wbd222.c
@@ -0,0 +1,134 @@
+/*
+ * 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 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")
+ .atag_offset = 0x100,
+ .map_io = gemini_map_io,
+ .init_irq = gemini_init_irq,
+ .init_time = gemini_timer_init,
+ .init_machine = wbd222_init,
+ .restart = gemini_restart,
+MACHINE_END
diff --git a/arch/arm/mach-gemini/common.h b/arch/arm/mach-gemini/common.h
new file mode 100644
index 000000000..dd883698f
--- /dev/null
+++ b/arch/arm/mach-gemini/common.h
@@ -0,0 +1,33 @@
+/*
+ * 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__
+
+#include <linux/reboot.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);
+
+extern void gemini_restart(enum reboot_mode mode, const char *cmd);
+
+#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 000000000..5cff29818
--- /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 000000000..f8cb5710d
--- /dev/null
+++ b/arch/arm/mach-gemini/gpio.c
@@ -0,0 +1,231 @@
+/*
+ * 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))
+#define irq_to_gpio(x) ((x) - GPIO_IRQ_BASE)
+
+/* 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(void __iomem *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);
+ void __iomem *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);
+ void __iomem *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);
+ void __iomem *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);
+ void __iomem *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);
+
+ 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)
+{
+ void __iomem *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)
+{
+ void __iomem *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)
+{
+ void __iomem *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/idle.c b/arch/arm/mach-gemini/idle.c
new file mode 100644
index 000000000..ddf8ec9d2
--- /dev/null
+++ b/arch/arm/mach-gemini/idle.c
@@ -0,0 +1,31 @@
+/*
+ * arch/arm/mach-gemini/idle.c
+ */
+
+#include <linux/init.h>
+#include <asm/system_misc.h>
+#include <asm/proc-fns.h>
+
+static void gemini_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 first since scheduler can miss a tick, but there is
+ * no other way around this. Platforms that needs it for power saving
+ * should enable it in init code, since by default it is
+ * disabled.
+ */
+
+ /* FIXME: Enabling interrupts here is racy! */
+ local_irq_enable();
+ cpu_do_idle();
+}
+
+static int __init gemini_idle_init(void)
+{
+ arm_pm_idle = gemini_idle;
+ return 0;
+}
+
+arch_initcall(gemini_idle_init);
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 000000000..f044e430b
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/entry-macro.S
@@ -0,0 +1,33 @@
+/*
+ * 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 get_irqnr_preamble, base, tmp
+ .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 000000000..de7ff7e84
--- /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/hardware.h b/arch/arm/mach-gemini/include/mach/hardware.h
new file mode 100644
index 000000000..98e7b0f28
--- /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) IOMEM((((x) & 0xFFF00000) >> 4) | ((x) & 0x000FFFFF) | 0xF0000000)
+
+#endif
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 000000000..06bc47e77
--- /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/uncompress.h b/arch/arm/mach-gemini/include/mach/uncompress.h
new file mode 100644
index 000000000..02e225673
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/uncompress.h
@@ -0,0 +1,42 @@
+/*
+ * 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()
+
+#endif /* __MACH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c
new file mode 100644
index 000000000..44f50dcb6
--- /dev/null
+++ b/arch/arm/mach-gemini/irq.c
@@ -0,0 +1,105 @@
+/*
+ * 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 <linux/cpu.h>
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/system_misc.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 = GEMINI_INTERRUPT_BASE,
+ .end = FIQ_STATUS(GEMINI_INTERRUPT_BASE) + 4,
+};
+
+void __init gemini_init_irq(void)
+{
+ unsigned int i, mode = 0, level = 0;
+
+ /*
+ * Disable the idle handler by default since it is buggy
+ * For more info see arch/arm/mach-gemini/idle.c
+ */
+ cpu_idle_poll_ctrl(true);
+
+ 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 000000000..2c2cd284b
--- /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 = (unsigned long)IO_ADDRESS(GEMINI_GLOBAL_BASE),
+ .pfn =__phys_to_pfn(GEMINI_GLOBAL_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)IO_ADDRESS(GEMINI_UART_BASE),
+ .pfn = __phys_to_pfn(GEMINI_UART_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)IO_ADDRESS(GEMINI_TIMER_BASE),
+ .pfn = __phys_to_pfn(GEMINI_TIMER_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)IO_ADDRESS(GEMINI_INTERRUPT_BASE),
+ .pfn = __phys_to_pfn(GEMINI_INTERRUPT_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)IO_ADDRESS(GEMINI_POWER_CTRL_BASE),
+ .pfn = __phys_to_pfn(GEMINI_POWER_CTRL_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)IO_ADDRESS(GEMINI_GPIO_BASE(0)),
+ .pfn = __phys_to_pfn(GEMINI_GPIO_BASE(0)),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)IO_ADDRESS(GEMINI_GPIO_BASE(1)),
+ .pfn = __phys_to_pfn(GEMINI_GPIO_BASE(1)),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)IO_ADDRESS(GEMINI_GPIO_BASE(2)),
+ .pfn = __phys_to_pfn(GEMINI_GPIO_BASE(2)),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)IO_ADDRESS(GEMINI_FLASH_CTRL_BASE),
+ .pfn = __phys_to_pfn(GEMINI_FLASH_CTRL_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)IO_ADDRESS(GEMINI_DRAM_CTRL_BASE),
+ .pfn = __phys_to_pfn(GEMINI_DRAM_CTRL_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)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/reset.c b/arch/arm/mach-gemini/reset.c
new file mode 100644
index 000000000..21a6d6d4f
--- /dev/null
+++ b/arch/arm/mach-gemini/reset.c
@@ -0,0 +1,25 @@
+/*
+ * 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>
+
+#include "common.h"
+
+void gemini_restart(enum reboot_mode 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/time.c b/arch/arm/mach-gemini/time.c
new file mode 100644
index 000000000..0a63c4d25
--- /dev/null
+++ b/arch/arm/mach-gemini/time.c
@@ -0,0 +1,170 @@
+/*
+ * 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>
+#include <linux/clockchips.h>
+#include <linux/clocksource.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)
+
+static unsigned int tick_rate;
+
+static int gemini_timer_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ u32 cr;
+
+ cr = readl(TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+
+ /* This may be overdoing it, feel free to test without this */
+ cr &= ~TIMER_2_CR_ENABLE;
+ cr &= ~TIMER_2_CR_INT;
+ writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+
+ /* Set next event */
+ writel(cycles, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE)));
+ writel(cycles, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE)));
+ cr |= TIMER_2_CR_ENABLE;
+ cr |= TIMER_2_CR_INT;
+ writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+
+ return 0;
+}
+
+static void gemini_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ u32 period = DIV_ROUND_CLOSEST(tick_rate, HZ);
+ u32 cr;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ /* Start the timer */
+ writel(period,
+ TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE)));
+ writel(period,
+ TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE)));
+ cr = readl(TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+ cr |= TIMER_2_CR_ENABLE;
+ cr |= TIMER_2_CR_INT;
+ writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_RESUME:
+ /*
+ * Disable also for oneshot: the set_next() call will
+ * arm the timer instead.
+ */
+ cr = readl(TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+ cr &= ~TIMER_2_CR_ENABLE;
+ cr &= ~TIMER_2_CR_INT;
+ writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+ break;
+ default:
+ break;
+ }
+}
+
+/* Use TIMER2 as clock event */
+static struct clock_event_device gemini_clockevent = {
+ .name = "TIMER2",
+ .rating = 300, /* Reasonably fast and accurate clock event */
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_next_event = gemini_timer_set_next_event,
+ .set_mode = gemini_timer_set_mode,
+};
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t gemini_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &gemini_clockevent;
+
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction gemini_timer_irq = {
+ .name = "Gemini Timer Tick",
+ .flags = IRQF_TIMER,
+ .handler = gemini_timer_interrupt,
+};
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+void __init gemini_timer_init(void)
+{
+ u32 reg_v;
+
+ reg_v = 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);
+
+ /* Enable and use TIMER1 as clock source */
+ writel(0xffffffff, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER1_BASE)));
+ writel(0xffffffff, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER1_BASE)));
+ writel(TIMER_1_CR_ENABLE, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+ if (clocksource_mmio_init(TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER1_BASE)),
+ "TIMER1", tick_rate, 300, 32,
+ clocksource_mmio_readl_up))
+ pr_err("timer: failed to initialize gemini clock source\n");
+
+ /* Configure and register the clockevent */
+ clockevents_config_and_register(&gemini_clockevent, tick_rate,
+ 1, 0xffffffff);
+}
diff --git a/arch/arm/mach-highbank/Kconfig b/arch/arm/mach-highbank/Kconfig
new file mode 100644
index 000000000..31aa866c3
--- /dev/null
+++ b/arch/arm/mach-highbank/Kconfig
@@ -0,0 +1,18 @@
+config ARCH_HIGHBANK
+ bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7
+ select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
+ select ARCH_HAS_HOLES_MEMORYMODEL
+ select ARCH_SUPPORTS_BIG_ENDIAN
+ select ARM_AMBA
+ select ARM_ERRATA_764369 if SMP
+ select ARM_ERRATA_775420
+ select ARM_ERRATA_798181 if SMP
+ select ARM_GIC
+ select ARM_PSCI
+ select ARM_TIMER_SP804
+ select CACHE_L2X0
+ select HAVE_ARM_SCU
+ select HAVE_ARM_TWD if SMP
+ select MAILBOX
+ select PL320_MBOX
+ select ZONE_DMA if ARM_LPAE
diff --git a/arch/arm/mach-highbank/Makefile b/arch/arm/mach-highbank/Makefile
new file mode 100644
index 000000000..55840f414
--- /dev/null
+++ b/arch/arm/mach-highbank/Makefile
@@ -0,0 +1,6 @@
+obj-y := highbank.o system.o smc.o
+
+plus_sec := $(call as-instr,.arch_extension sec,+sec)
+AFLAGS_smc.o :=-Wa,-march=armv7-a$(plus_sec)
+
+obj-$(CONFIG_PM_SLEEP) += pm.o
diff --git a/arch/arm/mach-highbank/core.h b/arch/arm/mach-highbank/core.h
new file mode 100644
index 000000000..7ec5edcd1
--- /dev/null
+++ b/arch/arm/mach-highbank/core.h
@@ -0,0 +1,17 @@
+#ifndef __HIGHBANK_CORE_H
+#define __HIGHBANK_CORE_H
+
+#include <linux/reboot.h>
+
+extern void highbank_restart(enum reboot_mode, const char *);
+extern void __iomem *scu_base_addr;
+
+#ifdef CONFIG_PM_SLEEP
+extern void highbank_pm_init(void);
+#else
+static inline void highbank_pm_init(void) {}
+#endif
+
+extern void highbank_smc1(int fn, int arg);
+
+#endif
diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
new file mode 100644
index 000000000..231fba0d0
--- /dev/null
+++ b/arch/arm/mach-highbank/highbank.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2010-2011 Calxeda, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clocksource.h>
+#include <linux/dma-mapping.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/pl320-ipc.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/reboot.h>
+#include <linux/amba/bus.h>
+#include <linux/platform_device.h>
+
+#include <asm/psci.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "core.h"
+#include "sysregs.h"
+
+void __iomem *sregs_base;
+void __iomem *scu_base_addr;
+
+static void __init highbank_scu_map_io(void)
+{
+ unsigned long base;
+
+ /* Get SCU base */
+ asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
+
+ scu_base_addr = ioremap(base, SZ_4K);
+}
+
+
+static void highbank_l2c310_write_sec(unsigned long val, unsigned reg)
+{
+ if (reg == L2X0_CTRL)
+ highbank_smc1(0x102, val);
+ else
+ WARN_ONCE(1, "Highbank L2C310: ignoring write to reg 0x%x\n",
+ reg);
+}
+
+static void __init highbank_init_irq(void)
+{
+ irqchip_init();
+
+ if (of_find_compatible_node(NULL, NULL, "arm,cortex-a9"))
+ highbank_scu_map_io();
+}
+
+static void highbank_power_off(void)
+{
+ highbank_set_pwr_shutdown();
+
+ while (1)
+ cpu_do_idle();
+}
+
+static int highbank_platform_notifier(struct notifier_block *nb,
+ unsigned long event, void *__dev)
+{
+ struct resource *res;
+ int reg = -1;
+ u32 val;
+ struct device *dev = __dev;
+
+ if (event != BUS_NOTIFY_ADD_DEVICE)
+ return NOTIFY_DONE;
+
+ if (of_device_is_compatible(dev->of_node, "calxeda,hb-ahci"))
+ reg = 0xc;
+ else if (of_device_is_compatible(dev->of_node, "calxeda,hb-sdhci"))
+ reg = 0x18;
+ else if (of_device_is_compatible(dev->of_node, "arm,pl330"))
+ reg = 0x20;
+ else if (of_device_is_compatible(dev->of_node, "calxeda,hb-xgmac")) {
+ res = platform_get_resource(to_platform_device(dev),
+ IORESOURCE_MEM, 0);
+ if (res) {
+ if (res->start == 0xfff50000)
+ reg = 0;
+ else if (res->start == 0xfff51000)
+ reg = 4;
+ }
+ }
+
+ if (reg < 0)
+ return NOTIFY_DONE;
+
+ if (of_property_read_bool(dev->of_node, "dma-coherent")) {
+ val = readl(sregs_base + reg);
+ writel(val | 0xff01, sregs_base + reg);
+ set_dma_ops(dev, &arm_coherent_dma_ops);
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block highbank_amba_nb = {
+ .notifier_call = highbank_platform_notifier,
+};
+
+static struct notifier_block highbank_platform_nb = {
+ .notifier_call = highbank_platform_notifier,
+};
+
+static struct platform_device highbank_cpuidle_device = {
+ .name = "cpuidle-calxeda",
+};
+
+static int hb_keys_notifier(struct notifier_block *nb, unsigned long event, void *data)
+{
+ u32 key = *(u32 *)data;
+
+ if (event != 0x1000)
+ return 0;
+
+ if (key == KEY_POWER)
+ orderly_poweroff(false);
+ else if (key == 0xffff)
+ ctrl_alt_del();
+
+ return 0;
+}
+static struct notifier_block hb_keys_nb = {
+ .notifier_call = hb_keys_notifier,
+};
+
+static void __init highbank_init(void)
+{
+ struct device_node *np;
+
+ /* Map system registers */
+ np = of_find_compatible_node(NULL, NULL, "calxeda,hb-sregs");
+ sregs_base = of_iomap(np, 0);
+ WARN_ON(!sregs_base);
+
+ pm_power_off = highbank_power_off;
+ highbank_pm_init();
+
+ bus_register_notifier(&platform_bus_type, &highbank_platform_nb);
+ bus_register_notifier(&amba_bustype, &highbank_amba_nb);
+
+ pl320_ipc_register_notifier(&hb_keys_nb);
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+ if (psci_ops.cpu_suspend)
+ platform_device_register(&highbank_cpuidle_device);
+}
+
+static const char *const highbank_match[] __initconst = {
+ "calxeda,highbank",
+ "calxeda,ecx-2000",
+ NULL,
+};
+
+DT_MACHINE_START(HIGHBANK, "Highbank")
+#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE)
+ .dma_zone_size = (4ULL * SZ_1G),
+#endif
+ .l2c_aux_val = 0,
+ .l2c_aux_mask = ~0,
+ .l2c_write_sec = highbank_l2c310_write_sec,
+ .init_irq = highbank_init_irq,
+ .init_machine = highbank_init,
+ .dt_compat = highbank_match,
+ .restart = highbank_restart,
+MACHINE_END
diff --git a/arch/arm/mach-highbank/pm.c b/arch/arm/mach-highbank/pm.c
new file mode 100644
index 000000000..7f2bd85eb
--- /dev/null
+++ b/arch/arm/mach-highbank/pm.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2011 Calxeda, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/cpu_pm.h>
+#include <linux/init.h>
+#include <linux/suspend.h>
+
+#include <asm/suspend.h>
+#include <asm/psci.h>
+
+static int highbank_suspend_finish(unsigned long val)
+{
+ const struct psci_power_state ps = {
+ .type = PSCI_POWER_STATE_TYPE_POWER_DOWN,
+ .affinity_level = 1,
+ };
+
+ return psci_ops.cpu_suspend(ps, __pa(cpu_resume));
+}
+
+static int highbank_pm_enter(suspend_state_t state)
+{
+ cpu_pm_enter();
+ cpu_cluster_pm_enter();
+
+ cpu_suspend(0, highbank_suspend_finish);
+
+ cpu_cluster_pm_exit();
+ cpu_pm_exit();
+
+ return 0;
+}
+
+static const struct platform_suspend_ops highbank_pm_ops = {
+ .enter = highbank_pm_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+void __init highbank_pm_init(void)
+{
+ if (!psci_ops.cpu_suspend)
+ return;
+
+ suspend_set_ops(&highbank_pm_ops);
+}
diff --git a/arch/arm/mach-highbank/smc.S b/arch/arm/mach-highbank/smc.S
new file mode 100644
index 000000000..407d17baa
--- /dev/null
+++ b/arch/arm/mach-highbank/smc.S
@@ -0,0 +1,27 @@
+/*
+ * Copied from omap44xx-smc.S Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright 2012 Calxeda, 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>
+
+/*
+ * 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.
+ * Function signature : void highbank_smc1(u32 fn, u32 arg)
+ */
+
+ENTRY(highbank_smc1)
+ stmfd sp!, {r4-r11, lr}
+ mov r12, r0
+ mov r0, r1
+ dsb
+ smc #0
+ ldmfd sp!, {r4-r11, pc}
+ENDPROC(highbank_smc1)
diff --git a/arch/arm/mach-highbank/sysregs.h b/arch/arm/mach-highbank/sysregs.h
new file mode 100644
index 000000000..5995df7f2
--- /dev/null
+++ b/arch/arm/mach-highbank/sysregs.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2011 Calxeda, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _MACH_HIGHBANK__SYSREGS_H_
+#define _MACH_HIGHBANK__SYSREGS_H_
+
+#include <linux/io.h>
+#include <linux/smp.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+#include "core.h"
+
+extern void __iomem *sregs_base;
+
+#define HB_SREG_A9_PWR_REQ 0xf00
+#define HB_SREG_A9_BOOT_STAT 0xf04
+#define HB_SREG_A9_BOOT_DATA 0xf08
+
+#define HB_PWR_SUSPEND 0
+#define HB_PWR_SOFT_RESET 1
+#define HB_PWR_HARD_RESET 2
+#define HB_PWR_SHUTDOWN 3
+
+#define SREG_CPU_PWR_CTRL(c) (0x200 + ((c) * 4))
+
+static inline void highbank_set_core_pwr(void)
+{
+ int cpu = MPIDR_AFFINITY_LEVEL(cpu_logical_map(smp_processor_id()), 0);
+ if (scu_base_addr)
+ scu_power_mode(scu_base_addr, SCU_PM_POWEROFF);
+ else
+ writel_relaxed(1, sregs_base + SREG_CPU_PWR_CTRL(cpu));
+}
+
+static inline void highbank_clear_core_pwr(void)
+{
+ int cpu = MPIDR_AFFINITY_LEVEL(cpu_logical_map(smp_processor_id()), 0);
+ if (scu_base_addr)
+ scu_power_mode(scu_base_addr, SCU_PM_NORMAL);
+ else
+ writel_relaxed(0, sregs_base + SREG_CPU_PWR_CTRL(cpu));
+}
+
+static inline void highbank_set_pwr_suspend(void)
+{
+ writel(HB_PWR_SUSPEND, sregs_base + HB_SREG_A9_PWR_REQ);
+ highbank_set_core_pwr();
+}
+
+static inline void highbank_set_pwr_shutdown(void)
+{
+ writel(HB_PWR_SHUTDOWN, sregs_base + HB_SREG_A9_PWR_REQ);
+ highbank_set_core_pwr();
+}
+
+static inline void highbank_set_pwr_soft_reset(void)
+{
+ writel(HB_PWR_SOFT_RESET, sregs_base + HB_SREG_A9_PWR_REQ);
+ highbank_set_core_pwr();
+}
+
+static inline void highbank_set_pwr_hard_reset(void)
+{
+ writel(HB_PWR_HARD_RESET, sregs_base + HB_SREG_A9_PWR_REQ);
+ highbank_set_core_pwr();
+}
+
+static inline void highbank_clear_pwr_request(void)
+{
+ writel(~0UL, sregs_base + HB_SREG_A9_PWR_REQ);
+ highbank_clear_core_pwr();
+}
+
+#endif
diff --git a/arch/arm/mach-highbank/system.c b/arch/arm/mach-highbank/system.c
new file mode 100644
index 000000000..2df5870b7
--- /dev/null
+++ b/arch/arm/mach-highbank/system.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2011 Calxeda, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/io.h>
+#include <asm/proc-fns.h>
+#include <linux/reboot.h>
+
+#include "core.h"
+#include "sysregs.h"
+
+void highbank_restart(enum reboot_mode mode, const char *cmd)
+{
+ if (mode == REBOOT_HARD)
+ highbank_set_pwr_hard_reset();
+ else
+ highbank_set_pwr_soft_reset();
+
+ while (1)
+ cpu_do_idle();
+}
+
diff --git a/arch/arm/mach-hisi/Kconfig b/arch/arm/mach-hisi/Kconfig
new file mode 100644
index 000000000..83061ad0e
--- /dev/null
+++ b/arch/arm/mach-hisi/Kconfig
@@ -0,0 +1,53 @@
+config ARCH_HISI
+ bool "Hisilicon SoC Support"
+ depends on ARCH_MULTI_V7
+ select ARM_AMBA
+ select ARM_GIC
+ select ARM_TIMER_SP804
+ select POWER_RESET
+ select POWER_RESET_HISI
+ select POWER_SUPPLY
+
+if ARCH_HISI
+
+menu "Hisilicon platform type"
+
+config ARCH_HI3xxx
+ bool "Hisilicon Hi36xx family" if ARCH_MULTI_V7
+ select CACHE_L2X0
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select PINCTRL
+ select PINCTRL_SINGLE
+ help
+ Support for Hisilicon Hi36xx SoC family
+
+config ARCH_HIP01
+ bool "Hisilicon HIP01 family" if ARCH_MULTI_V7
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select ARM_GLOBAL_TIMER
+ help
+ Support for Hisilicon HIP01 SoC family
+
+config ARCH_HIP04
+ bool "Hisilicon HiP04 Cortex A15 family" if ARCH_MULTI_V7
+ select ARM_ERRATA_798181 if SMP
+ select HAVE_ARM_ARCH_TIMER
+ select MCPM if SMP
+ select MCPM_QUAD_CLUSTER if SMP
+ help
+ Support for Hisilicon HiP04 SoC family
+
+config ARCH_HIX5HD2
+ bool "Hisilicon X5HD2 family" if ARCH_MULTI_V7
+ select CACHE_L2X0
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select PINCTRL
+ select PINCTRL_SINGLE
+ help
+ Support for Hisilicon HIX5HD2 SoC family
+endmenu
+
+endif
diff --git a/arch/arm/mach-hisi/Makefile b/arch/arm/mach-hisi/Makefile
new file mode 100644
index 000000000..6b7b3033d
--- /dev/null
+++ b/arch/arm/mach-hisi/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for Hisilicon processors family
+#
+
+CFLAGS_platmcpm.o := -march=armv7-a
+
+obj-y += hisilicon.o
+obj-$(CONFIG_MCPM) += platmcpm.o
+obj-$(CONFIG_SMP) += platsmp.o hotplug.o headsmp.o
diff --git a/arch/arm/mach-hisi/core.h b/arch/arm/mach-hisi/core.h
new file mode 100644
index 000000000..92a682d8e
--- /dev/null
+++ b/arch/arm/mach-hisi/core.h
@@ -0,0 +1,23 @@
+#ifndef __HISILICON_CORE_H
+#define __HISILICON_CORE_H
+
+#include <linux/reboot.h>
+
+extern void hi3xxx_set_cpu_jump(int cpu, void *jump_addr);
+extern int hi3xxx_get_cpu_jump(int cpu);
+extern void secondary_startup(void);
+extern struct smp_operations hi3xxx_smp_ops;
+
+extern void hi3xxx_cpu_die(unsigned int cpu);
+extern int hi3xxx_cpu_kill(unsigned int cpu);
+extern void hi3xxx_set_cpu(int cpu, bool enable);
+
+extern void hisi_secondary_startup(void);
+extern struct smp_operations hix5hd2_smp_ops;
+extern void hix5hd2_set_cpu(int cpu, bool enable);
+extern void hix5hd2_cpu_die(unsigned int cpu);
+
+extern struct smp_operations hip01_smp_ops;
+extern void hip01_set_cpu(int cpu, bool enable);
+extern void hip01_cpu_die(unsigned int cpu);
+#endif
diff --git a/arch/arm/mach-hisi/headsmp.S b/arch/arm/mach-hisi/headsmp.S
new file mode 100644
index 000000000..81e35b159
--- /dev/null
+++ b/arch/arm/mach-hisi/headsmp.S
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2014 Hisilicon Limited.
+ * Copyright (c) 2014 Linaro 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/linkage.h>
+#include <linux/init.h>
+
+ __CPUINIT
+
+ENTRY(hisi_secondary_startup)
+ bl v7_invalidate_l1
+ b secondary_startup
diff --git a/arch/arm/mach-hisi/hisilicon.c b/arch/arm/mach-hisi/hisilicon.c
new file mode 100644
index 000000000..c6bd7c7bd
--- /dev/null
+++ b/arch/arm/mach-hisi/hisilicon.c
@@ -0,0 +1,84 @@
+/*
+ * (Hisilicon's SoC based) flattened device tree enabled machine
+ *
+ * Copyright (c) 2012-2013 Hisilicon Ltd.
+ * Copyright (c) 2012-2013 Linaro Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@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 <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <linux/irqchip.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#define HI3620_SYSCTRL_PHYS_BASE 0xfc802000
+#define HI3620_SYSCTRL_VIRT_BASE 0xfe802000
+
+/*
+ * This table is only for optimization. Since ioremap() could always share
+ * the same mapping if it's defined as static IO mapping.
+ *
+ * Without this table, system could also work. The cost is some virtual address
+ * spaces wasted since ioremap() may be called multi times for the same
+ * IO space.
+ */
+static struct map_desc hi3620_io_desc[] __initdata = {
+ {
+ /* sysctrl */
+ .pfn = __phys_to_pfn(HI3620_SYSCTRL_PHYS_BASE),
+ .virtual = HI3620_SYSCTRL_VIRT_BASE,
+ .length = 0x1000,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init hi3620_map_io(void)
+{
+ debug_ll_io_init();
+ iotable_init(hi3620_io_desc, ARRAY_SIZE(hi3620_io_desc));
+}
+
+static const char *const hi3xxx_compat[] __initconst = {
+ "hisilicon,hi3620-hi4511",
+ NULL,
+};
+
+DT_MACHINE_START(HI3620, "Hisilicon Hi3620 (Flattened Device Tree)")
+ .map_io = hi3620_map_io,
+ .dt_compat = hi3xxx_compat,
+MACHINE_END
+
+static const char *const hix5hd2_compat[] __initconst = {
+ "hisilicon,hix5hd2",
+ NULL,
+};
+
+DT_MACHINE_START(HIX5HD2_DT, "Hisilicon HIX5HD2 (Flattened Device Tree)")
+ .dt_compat = hix5hd2_compat,
+MACHINE_END
+
+static const char *const hip04_compat[] __initconst = {
+ "hisilicon,hip04-d01",
+ NULL,
+};
+
+DT_MACHINE_START(HIP04, "Hisilicon HiP04 (Flattened Device Tree)")
+ .dt_compat = hip04_compat,
+MACHINE_END
+
+static const char *const hip01_compat[] __initconst = {
+ "hisilicon,hip01",
+ "hisilicon,hip01-ca9x2",
+ NULL,
+};
+
+DT_MACHINE_START(HIP01, "Hisilicon HIP01 (Flattened Device Tree)")
+ .dt_compat = hip01_compat,
+MACHINE_END
diff --git a/arch/arm/mach-hisi/hotplug.c b/arch/arm/mach-hisi/hotplug.c
new file mode 100644
index 000000000..a129aae72
--- /dev/null
+++ b/arch/arm/mach-hisi/hotplug.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2013 Linaro Ltd.
+ * Copyright (c) 2013 Hisilicon Limited.
+ *
+ * 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.
+ */
+
+#include <linux/cpu.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include "core.h"
+
+/* Sysctrl registers in Hi3620 SoC */
+#define SCISOEN 0xc0
+#define SCISODIS 0xc4
+#define SCPERPWREN 0xd0
+#define SCPERPWRDIS 0xd4
+#define SCCPUCOREEN 0xf4
+#define SCCPUCOREDIS 0xf8
+#define SCPERCTRL0 0x200
+#define SCCPURSTEN 0x410
+#define SCCPURSTDIS 0x414
+
+/*
+ * bit definition in SCISOEN/SCPERPWREN/...
+ *
+ * CPU2_ISO_CTRL (1 << 5)
+ * CPU3_ISO_CTRL (1 << 6)
+ * ...
+ */
+#define CPU2_ISO_CTRL (1 << 5)
+
+/*
+ * bit definition in SCPERCTRL0
+ *
+ * CPU0_WFI_MASK_CFG (1 << 28)
+ * CPU1_WFI_MASK_CFG (1 << 29)
+ * ...
+ */
+#define CPU0_WFI_MASK_CFG (1 << 28)
+
+/*
+ * bit definition in SCCPURSTEN/...
+ *
+ * CPU0_SRST_REQ_EN (1 << 0)
+ * CPU1_SRST_REQ_EN (1 << 1)
+ * ...
+ */
+#define CPU0_HPM_SRST_REQ_EN (1 << 22)
+#define CPU0_DBG_SRST_REQ_EN (1 << 12)
+#define CPU0_NEON_SRST_REQ_EN (1 << 4)
+#define CPU0_SRST_REQ_EN (1 << 0)
+
+#define HIX5HD2_PERI_CRG20 0x50
+#define CRG20_CPU1_RESET (1 << 17)
+
+#define HIX5HD2_PERI_PMC0 0x1000
+#define PMC0_CPU1_WAIT_MTCOMS_ACK (1 << 8)
+#define PMC0_CPU1_PMC_ENABLE (1 << 7)
+#define PMC0_CPU1_POWERDOWN (1 << 3)
+
+#define HIP01_PERI9 0x50
+#define PERI9_CPU1_RESET (1 << 1)
+
+enum {
+ HI3620_CTRL,
+ ERROR_CTRL,
+};
+
+static void __iomem *ctrl_base;
+static int id;
+
+static void set_cpu_hi3620(int cpu, bool enable)
+{
+ u32 val = 0;
+
+ if (enable) {
+ /* MTCMOS set */
+ if ((cpu == 2) || (cpu == 3))
+ writel_relaxed(CPU2_ISO_CTRL << (cpu - 2),
+ ctrl_base + SCPERPWREN);
+ udelay(100);
+
+ /* Enable core */
+ writel_relaxed(0x01 << cpu, ctrl_base + SCCPUCOREEN);
+
+ /* unreset */
+ val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN
+ | CPU0_SRST_REQ_EN;
+ writel_relaxed(val << cpu, ctrl_base + SCCPURSTDIS);
+ /* reset */
+ val |= CPU0_HPM_SRST_REQ_EN;
+ writel_relaxed(val << cpu, ctrl_base + SCCPURSTEN);
+
+ /* ISO disable */
+ if ((cpu == 2) || (cpu == 3))
+ writel_relaxed(CPU2_ISO_CTRL << (cpu - 2),
+ ctrl_base + SCISODIS);
+ udelay(1);
+
+ /* WFI Mask */
+ val = readl_relaxed(ctrl_base + SCPERCTRL0);
+ val &= ~(CPU0_WFI_MASK_CFG << cpu);
+ writel_relaxed(val, ctrl_base + SCPERCTRL0);
+
+ /* Unreset */
+ val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN
+ | CPU0_SRST_REQ_EN | CPU0_HPM_SRST_REQ_EN;
+ writel_relaxed(val << cpu, ctrl_base + SCCPURSTDIS);
+ } else {
+ /* wfi mask */
+ val = readl_relaxed(ctrl_base + SCPERCTRL0);
+ val |= (CPU0_WFI_MASK_CFG << cpu);
+ writel_relaxed(val, ctrl_base + SCPERCTRL0);
+
+ /* disable core*/
+ writel_relaxed(0x01 << cpu, ctrl_base + SCCPUCOREDIS);
+
+ if ((cpu == 2) || (cpu == 3)) {
+ /* iso enable */
+ writel_relaxed(CPU2_ISO_CTRL << (cpu - 2),
+ ctrl_base + SCISOEN);
+ udelay(1);
+ }
+
+ /* reset */
+ val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN
+ | CPU0_SRST_REQ_EN | CPU0_HPM_SRST_REQ_EN;
+ writel_relaxed(val << cpu, ctrl_base + SCCPURSTEN);
+
+ if ((cpu == 2) || (cpu == 3)) {
+ /* MTCMOS unset */
+ writel_relaxed(CPU2_ISO_CTRL << (cpu - 2),
+ ctrl_base + SCPERPWRDIS);
+ udelay(100);
+ }
+ }
+}
+
+static int hi3xxx_hotplug_init(void)
+{
+ struct device_node *node;
+
+ node = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
+ if (node) {
+ ctrl_base = of_iomap(node, 0);
+ id = HI3620_CTRL;
+ return 0;
+ }
+ id = ERROR_CTRL;
+ return -ENOENT;
+}
+
+void hi3xxx_set_cpu(int cpu, bool enable)
+{
+ if (!ctrl_base) {
+ if (hi3xxx_hotplug_init() < 0)
+ return;
+ }
+
+ if (id == HI3620_CTRL)
+ set_cpu_hi3620(cpu, enable);
+}
+
+static bool hix5hd2_hotplug_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "hisilicon,cpuctrl");
+ if (np) {
+ ctrl_base = of_iomap(np, 0);
+ return true;
+ }
+ return false;
+}
+
+void hix5hd2_set_cpu(int cpu, bool enable)
+{
+ u32 val = 0;
+
+ if (!ctrl_base)
+ if (!hix5hd2_hotplug_init())
+ BUG();
+
+ if (enable) {
+ /* power on cpu1 */
+ val = readl_relaxed(ctrl_base + HIX5HD2_PERI_PMC0);
+ val &= ~(PMC0_CPU1_WAIT_MTCOMS_ACK | PMC0_CPU1_POWERDOWN);
+ val |= PMC0_CPU1_PMC_ENABLE;
+ writel_relaxed(val, ctrl_base + HIX5HD2_PERI_PMC0);
+ /* unreset */
+ val = readl_relaxed(ctrl_base + HIX5HD2_PERI_CRG20);
+ val &= ~CRG20_CPU1_RESET;
+ writel_relaxed(val, ctrl_base + HIX5HD2_PERI_CRG20);
+ } else {
+ /* power down cpu1 */
+ val = readl_relaxed(ctrl_base + HIX5HD2_PERI_PMC0);
+ val |= PMC0_CPU1_PMC_ENABLE | PMC0_CPU1_POWERDOWN;
+ val &= ~PMC0_CPU1_WAIT_MTCOMS_ACK;
+ writel_relaxed(val, ctrl_base + HIX5HD2_PERI_PMC0);
+
+ /* reset */
+ val = readl_relaxed(ctrl_base + HIX5HD2_PERI_CRG20);
+ val |= CRG20_CPU1_RESET;
+ writel_relaxed(val, ctrl_base + HIX5HD2_PERI_CRG20);
+ }
+}
+
+void hip01_set_cpu(int cpu, bool enable)
+{
+ unsigned int temp;
+ struct device_node *np;
+
+ if (!ctrl_base) {
+ np = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl");
+ if (np)
+ ctrl_base = of_iomap(np, 0);
+ else
+ BUG();
+ }
+
+ if (enable) {
+ /* reset on CPU1 */
+ temp = readl_relaxed(ctrl_base + HIP01_PERI9);
+ temp |= PERI9_CPU1_RESET;
+ writel_relaxed(temp, ctrl_base + HIP01_PERI9);
+
+ udelay(50);
+
+ /* unreset on CPU1 */
+ temp = readl_relaxed(ctrl_base + HIP01_PERI9);
+ temp &= ~PERI9_CPU1_RESET;
+ writel_relaxed(temp, ctrl_base + HIP01_PERI9);
+ }
+}
+
+static inline void cpu_enter_lowpower(void)
+{
+ unsigned int v;
+
+ flush_cache_all();
+
+ /*
+ * Turn off coherency and L1 D-cache
+ */
+ asm volatile(
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " bic %0, %0, #0x40\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ " mrc p15, 0, %0, c1, c0, 0\n"
+ " bic %0, %0, #0x04\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ : "=&r" (v)
+ : "r" (0)
+ : "cc");
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+void hi3xxx_cpu_die(unsigned int cpu)
+{
+ cpu_enter_lowpower();
+ hi3xxx_set_cpu_jump(cpu, phys_to_virt(0));
+ cpu_do_idle();
+
+ /* We should have never returned from idle */
+ panic("cpu %d unexpectedly exit from shutdown\n", cpu);
+}
+
+int hi3xxx_cpu_kill(unsigned int cpu)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(50);
+
+ while (hi3xxx_get_cpu_jump(cpu))
+ if (time_after(jiffies, timeout))
+ return 0;
+ hi3xxx_set_cpu(cpu, false);
+ return 1;
+}
+
+void hix5hd2_cpu_die(unsigned int cpu)
+{
+ flush_cache_all();
+ hix5hd2_set_cpu(cpu, false);
+}
+#endif
diff --git a/arch/arm/mach-hisi/platmcpm.c b/arch/arm/mach-hisi/platmcpm.c
new file mode 100644
index 000000000..280f3f14f
--- /dev/null
+++ b/arch/arm/mach-hisi/platmcpm.c
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2013-2014 Linaro Ltd.
+ * Copyright (c) 2013-2014 Hisilicon Limited.
+ *
+ * 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.
+ */
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/memblock.h>
+#include <linux/of_address.h>
+
+#include <asm/cputype.h>
+#include <asm/cp15.h>
+#include <asm/mcpm.h>
+
+#include "core.h"
+
+/* bits definition in SC_CPU_RESET_REQ[x]/SC_CPU_RESET_DREQ[x]
+ * 1 -- unreset; 0 -- reset
+ */
+#define CORE_RESET_BIT(x) (1 << x)
+#define NEON_RESET_BIT(x) (1 << (x + 4))
+#define CORE_DEBUG_RESET_BIT(x) (1 << (x + 9))
+#define CLUSTER_L2_RESET_BIT (1 << 8)
+#define CLUSTER_DEBUG_RESET_BIT (1 << 13)
+
+/*
+ * bits definition in SC_CPU_RESET_STATUS[x]
+ * 1 -- reset status; 0 -- unreset status
+ */
+#define CORE_RESET_STATUS(x) (1 << x)
+#define NEON_RESET_STATUS(x) (1 << (x + 4))
+#define CORE_DEBUG_RESET_STATUS(x) (1 << (x + 9))
+#define CLUSTER_L2_RESET_STATUS (1 << 8)
+#define CLUSTER_DEBUG_RESET_STATUS (1 << 13)
+#define CORE_WFI_STATUS(x) (1 << (x + 16))
+#define CORE_WFE_STATUS(x) (1 << (x + 20))
+#define CORE_DEBUG_ACK(x) (1 << (x + 24))
+
+#define SC_CPU_RESET_REQ(x) (0x520 + (x << 3)) /* reset */
+#define SC_CPU_RESET_DREQ(x) (0x524 + (x << 3)) /* unreset */
+#define SC_CPU_RESET_STATUS(x) (0x1520 + (x << 3))
+
+#define FAB_SF_MODE 0x0c
+#define FAB_SF_INVLD 0x10
+
+/* bits definition in FB_SF_INVLD */
+#define FB_SF_INVLD_START (1 << 8)
+
+#define HIP04_MAX_CLUSTERS 4
+#define HIP04_MAX_CPUS_PER_CLUSTER 4
+
+#define POLL_MSEC 10
+#define TIMEOUT_MSEC 1000
+
+static void __iomem *sysctrl, *fabric;
+static int hip04_cpu_table[HIP04_MAX_CLUSTERS][HIP04_MAX_CPUS_PER_CLUSTER];
+static DEFINE_SPINLOCK(boot_lock);
+static u32 fabric_phys_addr;
+/*
+ * [0]: bootwrapper physical address
+ * [1]: bootwrapper size
+ * [2]: relocation address
+ * [3]: relocation size
+ */
+static u32 hip04_boot_method[4];
+
+static bool hip04_cluster_is_down(unsigned int cluster)
+{
+ int i;
+
+ for (i = 0; i < HIP04_MAX_CPUS_PER_CLUSTER; i++)
+ if (hip04_cpu_table[cluster][i])
+ return false;
+ return true;
+}
+
+static void hip04_set_snoop_filter(unsigned int cluster, unsigned int on)
+{
+ unsigned long data;
+
+ if (!fabric)
+ BUG();
+ data = readl_relaxed(fabric + FAB_SF_MODE);
+ if (on)
+ data |= 1 << cluster;
+ else
+ data &= ~(1 << cluster);
+ writel_relaxed(data, fabric + FAB_SF_MODE);
+ do {
+ cpu_relax();
+ } while (data != readl_relaxed(fabric + FAB_SF_MODE));
+}
+
+static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster)
+{
+ unsigned long data;
+ void __iomem *sys_dreq, *sys_status;
+
+ if (!sysctrl)
+ return -ENODEV;
+ if (cluster >= HIP04_MAX_CLUSTERS || cpu >= HIP04_MAX_CPUS_PER_CLUSTER)
+ return -EINVAL;
+
+ spin_lock_irq(&boot_lock);
+
+ if (hip04_cpu_table[cluster][cpu])
+ goto out;
+
+ sys_dreq = sysctrl + SC_CPU_RESET_DREQ(cluster);
+ sys_status = sysctrl + SC_CPU_RESET_STATUS(cluster);
+ if (hip04_cluster_is_down(cluster)) {
+ data = CLUSTER_DEBUG_RESET_BIT;
+ writel_relaxed(data, sys_dreq);
+ do {
+ cpu_relax();
+ data = readl_relaxed(sys_status);
+ } while (data & CLUSTER_DEBUG_RESET_STATUS);
+ }
+
+ data = CORE_RESET_BIT(cpu) | NEON_RESET_BIT(cpu) | \
+ CORE_DEBUG_RESET_BIT(cpu);
+ writel_relaxed(data, sys_dreq);
+ do {
+ cpu_relax();
+ } while (data == readl_relaxed(sys_status));
+ /*
+ * We may fail to power up core again without this delay.
+ * It's not mentioned in document. It's found by test.
+ */
+ udelay(20);
+out:
+ hip04_cpu_table[cluster][cpu]++;
+ spin_unlock_irq(&boot_lock);
+
+ return 0;
+}
+
+static void hip04_mcpm_power_down(void)
+{
+ unsigned int mpidr, cpu, cluster;
+ bool skip_wfi = false, last_man = false;
+
+ mpidr = read_cpuid_mpidr();
+ cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+
+ __mcpm_cpu_going_down(cpu, cluster);
+
+ spin_lock(&boot_lock);
+ BUG_ON(__mcpm_cluster_state(cluster) != CLUSTER_UP);
+ hip04_cpu_table[cluster][cpu]--;
+ if (hip04_cpu_table[cluster][cpu] == 1) {
+ /* A power_up request went ahead of us. */
+ skip_wfi = true;
+ } else if (hip04_cpu_table[cluster][cpu] > 1) {
+ pr_err("Cluster %d CPU%d boots multiple times\n", cluster, cpu);
+ BUG();
+ }
+
+ last_man = hip04_cluster_is_down(cluster);
+ if (last_man && __mcpm_outbound_enter_critical(cpu, cluster)) {
+ spin_unlock(&boot_lock);
+ /* Since it's Cortex A15, disable L2 prefetching. */
+ asm volatile(
+ "mcr p15, 1, %0, c15, c0, 3 \n\t"
+ "isb \n\t"
+ "dsb "
+ : : "r" (0x400) );
+ v7_exit_coherency_flush(all);
+ hip04_set_snoop_filter(cluster, 0);
+ __mcpm_outbound_leave_critical(cluster, CLUSTER_DOWN);
+ } else {
+ spin_unlock(&boot_lock);
+ v7_exit_coherency_flush(louis);
+ }
+
+ __mcpm_cpu_down(cpu, cluster);
+
+ if (!skip_wfi)
+ wfi();
+}
+
+static int hip04_mcpm_wait_for_powerdown(unsigned int cpu, unsigned int cluster)
+{
+ unsigned int data, tries, count;
+ int ret = -ETIMEDOUT;
+
+ BUG_ON(cluster >= HIP04_MAX_CLUSTERS ||
+ cpu >= HIP04_MAX_CPUS_PER_CLUSTER);
+
+ count = TIMEOUT_MSEC / POLL_MSEC;
+ spin_lock_irq(&boot_lock);
+ for (tries = 0; tries < count; tries++) {
+ if (hip04_cpu_table[cluster][cpu]) {
+ ret = -EBUSY;
+ goto err;
+ }
+ cpu_relax();
+ data = readl_relaxed(sysctrl + SC_CPU_RESET_STATUS(cluster));
+ if (data & CORE_WFI_STATUS(cpu))
+ break;
+ spin_unlock_irq(&boot_lock);
+ /* Wait for clean L2 when the whole cluster is down. */
+ msleep(POLL_MSEC);
+ spin_lock_irq(&boot_lock);
+ }
+ if (tries >= count)
+ goto err;
+ data = CORE_RESET_BIT(cpu) | NEON_RESET_BIT(cpu) | \
+ CORE_DEBUG_RESET_BIT(cpu);
+ writel_relaxed(data, sysctrl + SC_CPU_RESET_REQ(cluster));
+ for (tries = 0; tries < count; tries++) {
+ cpu_relax();
+ data = readl_relaxed(sysctrl + SC_CPU_RESET_STATUS(cluster));
+ if (data & CORE_RESET_STATUS(cpu))
+ break;
+ }
+ if (tries >= count)
+ goto err;
+ spin_unlock_irq(&boot_lock);
+ return 0;
+err:
+ spin_unlock_irq(&boot_lock);
+ return ret;
+}
+
+static void hip04_mcpm_powered_up(void)
+{
+ unsigned int mpidr, cpu, cluster;
+
+ mpidr = read_cpuid_mpidr();
+ cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+
+ spin_lock(&boot_lock);
+ if (!hip04_cpu_table[cluster][cpu])
+ hip04_cpu_table[cluster][cpu] = 1;
+ spin_unlock(&boot_lock);
+}
+
+static void __naked hip04_mcpm_power_up_setup(unsigned int affinity_level)
+{
+ asm volatile (" \n"
+" cmp r0, #0 \n"
+" bxeq lr \n"
+ /* calculate fabric phys address */
+" adr r2, 2f \n"
+" ldmia r2, {r1, r3} \n"
+" sub r0, r2, r1 \n"
+" ldr r2, [r0, r3] \n"
+ /* get cluster id from MPIDR */
+" mrc p15, 0, r0, c0, c0, 5 \n"
+" ubfx r1, r0, #8, #8 \n"
+ /* 1 << cluster id */
+" mov r0, #1 \n"
+" mov r3, r0, lsl r1 \n"
+" ldr r0, [r2, #"__stringify(FAB_SF_MODE)"] \n"
+" tst r0, r3 \n"
+" bxne lr \n"
+" orr r1, r0, r3 \n"
+" str r1, [r2, #"__stringify(FAB_SF_MODE)"] \n"
+"1: ldr r0, [r2, #"__stringify(FAB_SF_MODE)"] \n"
+" tst r0, r3 \n"
+" beq 1b \n"
+" bx lr \n"
+
+" .align 2 \n"
+"2: .word . \n"
+" .word fabric_phys_addr \n"
+ );
+}
+
+static const struct mcpm_platform_ops hip04_mcpm_ops = {
+ .power_up = hip04_mcpm_power_up,
+ .power_down = hip04_mcpm_power_down,
+ .wait_for_powerdown = hip04_mcpm_wait_for_powerdown,
+ .powered_up = hip04_mcpm_powered_up,
+};
+
+static bool __init hip04_cpu_table_init(void)
+{
+ unsigned int mpidr, cpu, cluster;
+
+ mpidr = read_cpuid_mpidr();
+ cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+
+ if (cluster >= HIP04_MAX_CLUSTERS ||
+ cpu >= HIP04_MAX_CPUS_PER_CLUSTER) {
+ pr_err("%s: boot CPU is out of bound!\n", __func__);
+ return false;
+ }
+ hip04_set_snoop_filter(cluster, 1);
+ hip04_cpu_table[cluster][cpu] = 1;
+ return true;
+}
+
+static int __init hip04_mcpm_init(void)
+{
+ struct device_node *np, *np_sctl, *np_fab;
+ struct resource fab_res;
+ void __iomem *relocation;
+ int ret = -ENODEV;
+
+ np = of_find_compatible_node(NULL, NULL, "hisilicon,hip04-bootwrapper");
+ if (!np)
+ goto err;
+ ret = of_property_read_u32_array(np, "boot-method",
+ &hip04_boot_method[0], 4);
+ if (ret)
+ goto err;
+ np_sctl = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
+ if (!np_sctl)
+ goto err;
+ np_fab = of_find_compatible_node(NULL, NULL, "hisilicon,hip04-fabric");
+ if (!np_fab)
+ goto err;
+
+ ret = memblock_reserve(hip04_boot_method[0], hip04_boot_method[1]);
+ if (ret)
+ goto err;
+
+ relocation = ioremap(hip04_boot_method[2], hip04_boot_method[3]);
+ if (!relocation) {
+ pr_err("failed to map relocation space\n");
+ ret = -ENOMEM;
+ goto err_reloc;
+ }
+ sysctrl = of_iomap(np_sctl, 0);
+ if (!sysctrl) {
+ pr_err("failed to get sysctrl base\n");
+ ret = -ENOMEM;
+ goto err_sysctrl;
+ }
+ ret = of_address_to_resource(np_fab, 0, &fab_res);
+ if (ret) {
+ pr_err("failed to get fabric base phys\n");
+ goto err_fabric;
+ }
+ fabric_phys_addr = fab_res.start;
+ sync_cache_w(&fabric_phys_addr);
+ fabric = of_iomap(np_fab, 0);
+ if (!fabric) {
+ pr_err("failed to get fabric base\n");
+ ret = -ENOMEM;
+ goto err_fabric;
+ }
+
+ if (!hip04_cpu_table_init()) {
+ ret = -EINVAL;
+ goto err_table;
+ }
+ ret = mcpm_platform_register(&hip04_mcpm_ops);
+ if (ret) {
+ goto err_table;
+ }
+
+ /*
+ * Fill the instruction address that is used after secondary core
+ * out of reset.
+ */
+ writel_relaxed(hip04_boot_method[0], relocation);
+ writel_relaxed(0xa5a5a5a5, relocation + 4); /* magic number */
+ writel_relaxed(virt_to_phys(mcpm_entry_point), relocation + 8);
+ writel_relaxed(0, relocation + 12);
+ iounmap(relocation);
+
+ mcpm_sync_init(hip04_mcpm_power_up_setup);
+ mcpm_smp_set_ops();
+ pr_info("HiP04 MCPM initialized\n");
+ return ret;
+err_table:
+ iounmap(fabric);
+err_fabric:
+ iounmap(sysctrl);
+err_sysctrl:
+ iounmap(relocation);
+err_reloc:
+ memblock_free(hip04_boot_method[0], hip04_boot_method[1]);
+err:
+ return ret;
+}
+early_initcall(hip04_mcpm_init);
diff --git a/arch/arm/mach-hisi/platsmp.c b/arch/arm/mach-hisi/platsmp.c
new file mode 100644
index 000000000..8880c8e8b
--- /dev/null
+++ b/arch/arm/mach-hisi/platsmp.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2013 Linaro Ltd.
+ * Copyright (c) 2013 Hisilicon Limited.
+ * Based on arch/arm/mach-vexpress/platsmp.c, Copyright (C) 2002 ARM Ltd.
+ *
+ * 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.
+ */
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/delay.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+#include <asm/mach/map.h>
+
+#include "core.h"
+
+#define HIX5HD2_BOOT_ADDRESS 0xffff0000
+
+static void __iomem *ctrl_base;
+
+void hi3xxx_set_cpu_jump(int cpu, void *jump_addr)
+{
+ cpu = cpu_logical_map(cpu);
+ if (!cpu || !ctrl_base)
+ return;
+ writel_relaxed(virt_to_phys(jump_addr), ctrl_base + ((cpu - 1) << 2));
+}
+
+int hi3xxx_get_cpu_jump(int cpu)
+{
+ cpu = cpu_logical_map(cpu);
+ if (!cpu || !ctrl_base)
+ return 0;
+ return readl_relaxed(ctrl_base + ((cpu - 1) << 2));
+}
+
+static void __init hisi_enable_scu_a9(void)
+{
+ unsigned long base = 0;
+ void __iomem *scu_base = NULL;
+
+ if (scu_a9_has_base()) {
+ base = scu_a9_get_base();
+ scu_base = ioremap(base, SZ_4K);
+ if (!scu_base) {
+ pr_err("ioremap(scu_base) failed\n");
+ return;
+ }
+ scu_enable(scu_base);
+ iounmap(scu_base);
+ }
+}
+
+static void __init hi3xxx_smp_prepare_cpus(unsigned int max_cpus)
+{
+ struct device_node *np = NULL;
+ u32 offset = 0;
+
+ hisi_enable_scu_a9();
+ if (!ctrl_base) {
+ np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
+ if (!np) {
+ pr_err("failed to find hisilicon,sysctrl node\n");
+ return;
+ }
+ ctrl_base = of_iomap(np, 0);
+ if (!ctrl_base) {
+ pr_err("failed to map address\n");
+ return;
+ }
+ if (of_property_read_u32(np, "smp-offset", &offset) < 0) {
+ pr_err("failed to find smp-offset property\n");
+ return;
+ }
+ ctrl_base += offset;
+ }
+}
+
+static int hi3xxx_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ hi3xxx_set_cpu(cpu, true);
+ hi3xxx_set_cpu_jump(cpu, secondary_startup);
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+ return 0;
+}
+
+struct smp_operations hi3xxx_smp_ops __initdata = {
+ .smp_prepare_cpus = hi3xxx_smp_prepare_cpus,
+ .smp_boot_secondary = hi3xxx_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = hi3xxx_cpu_die,
+ .cpu_kill = hi3xxx_cpu_kill,
+#endif
+};
+
+static void __init hisi_common_smp_prepare_cpus(unsigned int max_cpus)
+{
+ hisi_enable_scu_a9();
+}
+
+void hix5hd2_set_scu_boot_addr(phys_addr_t start_addr, phys_addr_t jump_addr)
+{
+ void __iomem *virt;
+
+ virt = ioremap(start_addr, PAGE_SIZE);
+
+ writel_relaxed(0xe51ff004, virt); /* ldr pc, [rc, #-4] */
+ writel_relaxed(jump_addr, virt + 4); /* pc jump phy address */
+ iounmap(virt);
+}
+
+static int hix5hd2_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ phys_addr_t jumpaddr;
+
+ jumpaddr = virt_to_phys(hisi_secondary_startup);
+ hix5hd2_set_scu_boot_addr(HIX5HD2_BOOT_ADDRESS, jumpaddr);
+ hix5hd2_set_cpu(cpu, true);
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+ return 0;
+}
+
+
+struct smp_operations hix5hd2_smp_ops __initdata = {
+ .smp_prepare_cpus = hisi_common_smp_prepare_cpus,
+ .smp_boot_secondary = hix5hd2_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = hix5hd2_cpu_die,
+#endif
+};
+
+
+#define SC_SCTL_REMAP_CLR 0x00000100
+#define HIP01_BOOT_ADDRESS 0x80000000
+#define REG_SC_CTRL 0x000
+
+void hip01_set_boot_addr(phys_addr_t start_addr, phys_addr_t jump_addr)
+{
+ void __iomem *virt;
+
+ virt = phys_to_virt(start_addr);
+
+ writel_relaxed(0xe51ff004, virt);
+ writel_relaxed(jump_addr, virt + 4);
+}
+
+static int hip01_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ phys_addr_t jumpaddr;
+ unsigned int remap_reg_value = 0;
+ struct device_node *node;
+
+
+ jumpaddr = virt_to_phys(hisi_secondary_startup);
+ hip01_set_boot_addr(HIP01_BOOT_ADDRESS, jumpaddr);
+
+ node = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl");
+ if (WARN_ON(!node))
+ return -1;
+ ctrl_base = of_iomap(node, 0);
+
+ /* set the secondary core boot from DDR */
+ remap_reg_value = readl_relaxed(ctrl_base + REG_SC_CTRL);
+ barrier();
+ remap_reg_value |= SC_SCTL_REMAP_CLR;
+ barrier();
+ writel_relaxed(remap_reg_value, ctrl_base + REG_SC_CTRL);
+
+ hip01_set_cpu(cpu, true);
+
+ return 0;
+}
+
+struct smp_operations hip01_smp_ops __initdata = {
+ .smp_prepare_cpus = hisi_common_smp_prepare_cpus,
+ .smp_boot_secondary = hip01_boot_secondary,
+};
+
+CPU_METHOD_OF_DECLARE(hi3xxx_smp, "hisilicon,hi3620-smp", &hi3xxx_smp_ops);
+CPU_METHOD_OF_DECLARE(hix5hd2_smp, "hisilicon,hix5hd2-smp", &hix5hd2_smp_ops);
+CPU_METHOD_OF_DECLARE(hip01_smp, "hisilicon,hip01-smp", &hip01_smp_ops);
diff --git a/arch/arm/mach-imx/3ds_debugboard.c b/arch/arm/mach-imx/3ds_debugboard.c
new file mode 100644
index 000000000..134377352
--- /dev/null
+++ b/arch/arm/mach-imx/3ds_debugboard.c
@@ -0,0 +1,213 @@
+/*
+ * 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/irqdomain.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/smsc911x.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+
+#include "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_MAX_EXP_IO_LINES 16
+
+/* interrupts like external uart , external ethernet etc*/
+#define EXPIO_INT_ENET 0
+#define EXPIO_INT_XUART_A 1
+#define EXPIO_INT_XUART_B 2
+#define EXPIO_INT_BUTTON_A 3
+#define EXPIO_INT_BUTTON_B 4
+
+static void __iomem *brd_io;
+static struct irq_domain *domain;
+
+static struct resource smsc911x_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ } , {
+ .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 = -1,
+ .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 = 0;
+ for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
+ if ((int_valid & 1) == 0)
+ continue;
+ generic_handle_irq(irq_find_mapping(domain, 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 = d->hwirq;
+
+ 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 = d->hwirq;
+
+ __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 = d->hwirq;
+
+ 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,
+};
+
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+};
+
+int __init mxc_expio_init(u32 base, u32 intr_gpio)
+{
+ u32 p_irq = gpio_to_irq(intr_gpio);
+ int irq_base;
+ 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(intr_gpio, "expio_pirq");
+ gpio_direction_input(intr_gpio);
+
+ /* 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);
+
+ irq_base = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, numa_node_id());
+ WARN_ON(irq_base < 0);
+
+ domain = irq_domain_add_legacy(NULL, MXC_MAX_EXP_IO_LINES, irq_base, 0,
+ &irq_domain_simple_ops, NULL);
+ WARN_ON(!domain);
+
+ for (i = irq_base; i < irq_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 */
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
+ smsc911x_resources[0].start = LAN9217_BASE_ADDR(base);
+ smsc911x_resources[0].end = LAN9217_BASE_ADDR(base) + 0x100 - 1;
+ smsc911x_resources[1].start = irq_find_mapping(domain, EXPIO_INT_ENET);
+ smsc911x_resources[1].end = irq_find_mapping(domain, EXPIO_INT_ENET);
+ platform_device_register(&smsc_lan9217_device);
+
+ return 0;
+}
diff --git a/arch/arm/mach-imx/3ds_debugboard.h b/arch/arm/mach-imx/3ds_debugboard.h
new file mode 100644
index 000000000..9fd6cb3f8
--- /dev/null
+++ b/arch/arm/mach-imx/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 intr_gpio);
+
+#endif /* __ASM_ARCH_MXC_3DS_DB_H__ */
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
new file mode 100644
index 000000000..3a3d3e9d7
--- /dev/null
+++ b/arch/arm/mach-imx/Kconfig
@@ -0,0 +1,630 @@
+menuconfig ARCH_MXC
+ bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_CPU_SUSPEND if PM
+ select CLKSRC_MMIO
+ select GENERIC_IRQ_CHIP
+ select PINCTRL
+ select PM_OPP if PM
+ select SOC_BUS
+ select SRAM
+ help
+ Support for Freescale MXC/iMX-based family of processors
+
+if ARCH_MXC
+
+config MXC_TZIC
+ bool
+
+config MXC_AVIC
+ bool
+
+config MXC_DEBUG_BOARD
+ bool "Enable MXC debug board(for 3-stack)"
+ depends on MACH_MX27_3DS || MACH_MX31_3DS || MACH_MX35_3DS
+ 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_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 ARCH_HAS_RNGA
+ bool
+
+config HAVE_IMX_ANATOP
+ bool
+
+config HAVE_IMX_GPC
+ bool
+ select PM_GENERIC_DOMAINS if PM
+
+config HAVE_IMX_MMDC
+ bool
+
+config HAVE_IMX_SRC
+ def_bool y if SMP
+ select ARCH_HAS_RESET_CONTROLLER
+
+config IMX_HAVE_IOMUX_V1
+ bool
+
+config ARCH_MXC_IOMUX_V3
+ bool
+
+config SOC_IMX1
+ bool
+ select CPU_ARM920T
+ select IMX_HAVE_IOMUX_V1
+ select MXC_AVIC
+ select PINCTRL_IMX1
+
+config SOC_IMX21
+ bool
+ select CPU_ARM926T
+ select IMX_HAVE_IOMUX_V1
+ select MXC_AVIC
+
+config SOC_IMX27
+ bool
+ select CPU_ARM926T
+ select IMX_HAVE_IOMUX_V1
+ select MXC_AVIC
+ select PINCTRL_IMX27
+
+config SOC_IMX31
+ bool
+ select CPU_V6
+ select IMX_HAVE_PLATFORM_MXC_RNGA
+ select MXC_AVIC
+ select SMP_ON_UP if SMP
+
+config SOC_IMX35
+ bool
+ select ARCH_MXC_IOMUX_V3
+ select HAVE_EPIT
+ select MXC_AVIC
+ select PINCTRL_IMX35
+ select SMP_ON_UP if SMP
+
+if ARCH_MULTI_V4T
+
+comment "MX1 platforms:"
+
+config MACH_SCB9328
+ bool "Synertronixx scb9328"
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select SOC_IMX1
+ help
+ Say Y here if you are using a Synertronixx scb9328 board
+
+config MACH_APF9328
+ bool "APF9328"
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select SOC_IMX1
+ help
+ Say Yes here if you are using the Armadeus APF9328 development board
+
+config MACH_IMX1_DT
+ bool "Support i.MX1 platforms from device tree"
+ select SOC_IMX1
+ help
+ Include support for Freescale i.MX1 based platforms
+ using the device tree for discovery.
+
+endif
+
+if ARCH_MULTI_V5
+
+comment "MX21 platforms:"
+
+config MACH_MX21ADS
+ bool "MX21ADS platform"
+ select IMX_HAVE_PLATFORM_IMX_FB
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select SOC_IMX21
+ help
+ Include support for MX21ADS platform. This includes specific
+ configurations for the board and its peripherals.
+
+comment "MX27 platforms:"
+
+config MACH_MX27ADS
+ bool "MX27ADS platform"
+ 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
+ select SOC_IMX27
+ help
+ Include support for MX27ADS platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX27_3DS
+ bool "MX27PDK platform"
+ 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_KEYPAD
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MX2_CAMERA
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select MXC_DEBUG_BOARD
+ select USB_ULPI_VIEWPORT if USB_ULPI
+ select SOC_IMX27
+ 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 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_MX2_CAMERA
+ select IMX_HAVE_PLATFORM_MX2_EMMA
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select LEDS_GPIO_REGISTER
+ select SOC_IMX27
+ help
+ Include support for Visstrim_m10 platform and its different variants.
+ This includes specific configurations for the board and its
+ peripherals.
+
+config MACH_PCA100
+ bool "Phytec phyCARD-s (pca100)"
+ 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 USB_ULPI_VIEWPORT if USB_ULPI
+ select SOC_IMX27
+ help
+ Include support for phyCARD-s (aka pca100) platform. This
+ includes specific configurations for the module and its peripherals.
+
+config MACH_IMX27_DT
+ bool "Support i.MX27 platforms from device tree"
+ select SOC_IMX27
+ help
+ Include support for Freescale i.MX27 based platforms
+ using the device tree for discovery
+
+endif
+
+if ARCH_MULTI_V6
+
+comment "MX31 platforms:"
+
+config MACH_MX31ADS
+ bool "Support MX31ADS platforms"
+ default y
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select SOC_IMX31
+ 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 = y
+ 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 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 USB_ULPI_VIEWPORT if USB_ULPI
+ select SOC_IMX31
+ 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 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
+ select LEDS_GPIO_REGISTER
+ select USB_ULPI_VIEWPORT if USB_ULPI
+ select SOC_IMX31
+ 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 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 USB_ULPI_VIEWPORT if USB_ULPI
+ select SOC_IMX31
+ 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 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_SSI
+ 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_SPI_IMX
+ select MXC_DEBUG_BOARD
+ select USB_ULPI_VIEWPORT if USB_ULPI
+ select SOC_IMX31
+ 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 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_MMC
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select LEDS_GPIO_REGISTER
+ select USB_ULPI_VIEWPORT if USB_ULPI
+ select SOC_IMX31
+ 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 IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select SOC_IMX31
+ 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 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 USB_ULPI_VIEWPORT if USB_ULPI
+ select SOC_IMX31
+ 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 IMX_HAVE_PLATFORM_IMX_UART
+ select SOC_IMX31
+ 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"
+ default y
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select SOC_IMX31
+ help
+ Include support for BUGBase 1.3 platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_IMX31_DT
+ bool "Support i.MX31 platforms from device tree"
+ select SOC_IMX31
+ help
+ Include support for Freescale i.MX31 based platforms
+ using the device tree for discovery.
+
+comment "MX35 platforms:"
+
+config MACH_IMX35_DT
+ bool "Support i.MX35 platforms from device tree"
+ select SOC_IMX35
+ help
+ Include support for Freescale i.MX35 based platforms
+ using the device tree for discovery.
+
+config MACH_PCM043
+ bool "Support Phytec pcm043 (i.MX35) platforms"
+ 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 USB_ULPI_VIEWPORT if USB_ULPI
+ select SOC_IMX35
+ 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 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_UART
+ select IMX_HAVE_PLATFORM_IPU_CORE
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_MXC_RTC
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select MXC_DEBUG_BOARD
+ select SOC_IMX35
+ help
+ Include support for MX35PDK platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_EUKREA_CPUIMX35SD
+ bool "Support Eukrea CPUIMX35 Platform"
+ 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 USB_ULPI_VIEWPORT if USB_ULPI
+ select SOC_IMX35
+ help
+ Include support for Eukrea CPUIMX35 platform. This includes
+ specific configurations for the board and its peripherals.
+
+choice
+ prompt "Baseboard"
+ depends on MACH_EUKREA_CPUIMX35SD
+ 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
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select LEDS_GPIO_REGISTER
+ 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 IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_GPIO_KEYS
+ 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_NAND
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select SOC_IMX35
+ help
+ Include support for VPR200 platform. This includes specific
+ configurations for the board and its peripherals.
+
+endif
+
+if ARCH_MULTI_V5
+
+comment "Device tree only"
+
+config SOC_IMX25
+ bool "i.MX25 support"
+ select ARCH_MXC_IOMUX_V3
+ select CPU_ARM926T
+ select MXC_AVIC
+ select PINCTRL_IMX25
+ help
+ This enables support for Freescale i.MX25 processor
+endif
+
+if ARCH_MULTI_V7
+
+comment "Device tree only"
+
+config SOC_IMX5
+ bool
+ select HAVE_IMX_SRC
+ select MXC_TZIC
+
+config SOC_IMX50
+ bool "i.MX50 support"
+ select PINCTRL_IMX50
+ select SOC_IMX5
+
+ help
+ This enables support for Freescale i.MX50 processor.
+
+config SOC_IMX51
+ bool "i.MX51 support"
+ select PINCTRL_IMX51
+ select SOC_IMX5
+ help
+ This enables support for Freescale i.MX51 processor
+
+config SOC_IMX53
+ bool "i.MX53 support"
+ select PINCTRL_IMX53
+ select SOC_IMX5
+
+ help
+ This enables support for Freescale i.MX53 processor.
+
+config SOC_IMX6
+ bool
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_775420
+ select ARM_GIC
+ select HAVE_IMX_ANATOP
+ select HAVE_IMX_GPC
+ select HAVE_IMX_MMDC
+ select HAVE_IMX_SRC
+ select MFD_SYSCON
+ select PL310_ERRATA_769419 if CACHE_L2X0
+
+config SOC_IMX6Q
+ bool "i.MX6 Quad/DualLite support"
+ select ARM_ERRATA_764369 if SMP
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select PCI_DOMAINS if PCI
+ select PINCTRL_IMX6Q
+ select SOC_IMX6
+
+ help
+ This enables support for Freescale i.MX6 Quad processor.
+
+config SOC_IMX6SL
+ bool "i.MX6 SoloLite support"
+ select PINCTRL_IMX6SL
+ select SOC_IMX6
+
+ help
+ This enables support for Freescale i.MX6 SoloLite processor.
+
+config SOC_IMX6SX
+ bool "i.MX6 SoloX support"
+ select PINCTRL_IMX6SX
+ select SOC_IMX6
+
+ help
+ This enables support for Freescale i.MX6 SoloX processor.
+
+config SOC_VF610
+ bool "Vybrid Family VF610 support"
+ select IRQ_DOMAIN_HIERARCHY
+ select ARM_GIC
+ select PINCTRL_VF610
+ select PL310_ERRATA_769419 if CACHE_L2X0
+ select SMP_ON_UP if SMP
+
+ help
+ This enables support for Freescale Vybrid VF610 processor.
+
+choice
+ prompt "Clocksource for scheduler clock"
+ depends on SOC_VF610
+ default VF_USE_ARM_GLOBAL_TIMER
+
+ config VF_USE_ARM_GLOBAL_TIMER
+ bool "Use ARM Global Timer"
+ select ARM_GLOBAL_TIMER
+ select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+ help
+ Use the ARM Global Timer as clocksource
+
+ config VF_USE_PIT_TIMER
+ bool "Use PIT timer"
+ select VF_PIT_TIMER
+ help
+ Use SoC Periodic Interrupt Timer (PIT) as clocksource
+
+endchoice
+
+config SOC_LS1021A
+ bool "Freescale LS1021A support"
+ select ARM_GIC
+ select HAVE_ARM_ARCH_TIMER
+ select PCI_DOMAINS if PCI
+ select ZONE_DMA if ARM_LPAE
+
+ help
+ This enables support for Freescale LS1021A processor.
+
+endif
+
+source "arch/arm/mach-imx/devices/Kconfig"
+
+endif
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
new file mode 100644
index 000000000..3244cf1d2
--- /dev/null
+++ b/arch/arm/mach-imx/Makefile
@@ -0,0 +1,108 @@
+obj-y := time.o cpu.o system.o irq-common.o
+
+obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o
+obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o
+
+obj-$(CONFIG_SOC_IMX25) += clk-imx25.o cpu-imx25.o mach-imx25.o
+
+obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o
+obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o
+
+obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
+obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o
+
+imx5-pm-$(CONFIG_PM) += pm-imx5.o
+obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o clk-imx51-imx53.o clk-cpu.o $(imx5-pm-y)
+
+obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \
+ clk-pfd.o clk-busy.o clk.o \
+ clk-fixup-div.o clk-fixup-mux.o \
+ clk-gate-exclusive.o
+
+obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
+obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
+
+obj-$(CONFIG_MXC_TZIC) += tzic.o
+obj-$(CONFIG_MXC_AVIC) += avic.o
+
+obj-$(CONFIG_MXC_USE_EPIT) += epit.o
+obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
+
+ifeq ($(CONFIG_CPU_IDLE),y)
+obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o
+obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
+obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o
+obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o
+endif
+
+ifdef CONFIG_SND_IMX_SOC
+obj-y += ssi-fiq.o
+obj-y += ssi-fiq-ksym.o
+endif
+
+# i.MX1 based machines
+obj-$(CONFIG_MACH_SCB9328) += mach-scb9328.o
+obj-$(CONFIG_MACH_APF9328) += mach-apf9328.o
+obj-$(CONFIG_MACH_IMX1_DT) += imx1-dt.o
+
+# i.MX21 based machines
+obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o
+
+# i.MX27 based machines
+obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o
+obj-$(CONFIG_MACH_MX27_3DS) += mach-mx27_3ds.o
+obj-$(CONFIG_MACH_IMX27_VISSTRIM_M10) += mach-imx27_visstrim_m10.o
+obj-$(CONFIG_MACH_PCA100) += mach-pca100.o
+obj-$(CONFIG_MACH_IMX27_DT) += imx27-dt.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
+obj-$(CONFIG_MACH_IMX31_DT) += imx31-dt.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_CPUIMX35SD) += mach-cpuimx35.o
+obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o
+obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
+obj-$(CONFIG_MACH_IMX35_DT) += imx35-dt.o
+
+obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o
+obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
+obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
+obj-$(CONFIG_HAVE_IMX_SRC) += src.o
+ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_LS1021A),)
+AFLAGS_headsmp.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SMP) += headsmp.o platsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+endif
+obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o
+obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o
+obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o mach-imx6sx.o
+
+ifeq ($(CONFIG_SUSPEND),y)
+AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o
+endif
+obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
+
+obj-$(CONFIG_SOC_IMX50) += mach-imx50.o
+obj-$(CONFIG_SOC_IMX51) += mach-imx51.o
+obj-$(CONFIG_SOC_IMX53) += mach-imx53.o
+
+obj-$(CONFIG_SOC_VF610) += clk-vf610.o mach-vf610.o
+
+obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o
+
+obj-y += devices/
diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c
new file mode 100644
index 000000000..7f262fe4b
--- /dev/null
+++ b/arch/arm/mach-imx/anatop.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2013 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/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include "common.h"
+#include "hardware.h"
+
+#define REG_SET 0x4
+#define REG_CLR 0x8
+
+#define ANADIG_REG_2P5 0x130
+#define ANADIG_REG_CORE 0x140
+#define ANADIG_ANA_MISC0 0x150
+#define ANADIG_USB1_CHRG_DETECT 0x1b0
+#define ANADIG_USB2_CHRG_DETECT 0x210
+#define ANADIG_DIGPROG 0x260
+#define ANADIG_DIGPROG_IMX6SL 0x280
+
+#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000
+#define BM_ANADIG_REG_2P5_ENABLE_PULLDOWN 0x8
+#define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000
+#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG 0x1000
+/* Below MISC0_DISCON_HIGH_SNVS is only for i.MX6SL */
+#define BM_ANADIG_ANA_MISC0_DISCON_HIGH_SNVS 0x2000
+#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000
+#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000
+
+static struct regmap *anatop;
+
+static void imx_anatop_enable_weak2p5(bool enable)
+{
+ u32 reg, val;
+
+ regmap_read(anatop, ANADIG_ANA_MISC0, &val);
+
+ /* can only be enabled when stop_mode_config is clear. */
+ reg = ANADIG_REG_2P5;
+ reg += (enable && (val & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) == 0) ?
+ REG_SET : REG_CLR;
+ regmap_write(anatop, reg, BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG);
+}
+
+static void imx_anatop_enable_fet_odrive(bool enable)
+{
+ regmap_write(anatop, ANADIG_REG_CORE + (enable ? REG_SET : REG_CLR),
+ BM_ANADIG_REG_CORE_FET_ODRIVE);
+}
+
+static inline void imx_anatop_enable_2p5_pulldown(bool enable)
+{
+ regmap_write(anatop, ANADIG_REG_2P5 + (enable ? REG_SET : REG_CLR),
+ BM_ANADIG_REG_2P5_ENABLE_PULLDOWN);
+}
+
+static inline void imx_anatop_disconnect_high_snvs(bool enable)
+{
+ regmap_write(anatop, ANADIG_ANA_MISC0 + (enable ? REG_SET : REG_CLR),
+ BM_ANADIG_ANA_MISC0_DISCON_HIGH_SNVS);
+}
+
+void imx_anatop_pre_suspend(void)
+{
+ if (imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2)
+ imx_anatop_enable_2p5_pulldown(true);
+ else
+ imx_anatop_enable_weak2p5(true);
+
+ imx_anatop_enable_fet_odrive(true);
+
+ if (cpu_is_imx6sl())
+ imx_anatop_disconnect_high_snvs(true);
+}
+
+void imx_anatop_post_resume(void)
+{
+ if (imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2)
+ imx_anatop_enable_2p5_pulldown(false);
+ else
+ imx_anatop_enable_weak2p5(false);
+
+ imx_anatop_enable_fet_odrive(false);
+
+ if (cpu_is_imx6sl())
+ imx_anatop_disconnect_high_snvs(false);
+
+}
+
+static void imx_anatop_usb_chrg_detect_disable(void)
+{
+ regmap_write(anatop, ANADIG_USB1_CHRG_DETECT,
+ BM_ANADIG_USB_CHRG_DETECT_EN_B
+ | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
+ regmap_write(anatop, ANADIG_USB2_CHRG_DETECT,
+ BM_ANADIG_USB_CHRG_DETECT_EN_B |
+ BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
+}
+
+void __init imx_init_revision_from_anatop(void)
+{
+ struct device_node *np;
+ void __iomem *anatop_base;
+ unsigned int revision;
+ u32 digprog;
+ u16 offset = ANADIG_DIGPROG;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
+ anatop_base = of_iomap(np, 0);
+ WARN_ON(!anatop_base);
+ if (of_device_is_compatible(np, "fsl,imx6sl-anatop"))
+ offset = ANADIG_DIGPROG_IMX6SL;
+ digprog = readl_relaxed(anatop_base + offset);
+ iounmap(anatop_base);
+
+ switch (digprog & 0xff) {
+ case 0:
+ revision = IMX_CHIP_REVISION_1_0;
+ break;
+ case 1:
+ revision = IMX_CHIP_REVISION_1_1;
+ break;
+ case 2:
+ revision = IMX_CHIP_REVISION_1_2;
+ break;
+ case 3:
+ revision = IMX_CHIP_REVISION_1_3;
+ break;
+ case 4:
+ revision = IMX_CHIP_REVISION_1_4;
+ break;
+ case 5:
+ /*
+ * i.MX6DQ TO1.5 is defined as Rev 1.3 in Data Sheet, marked
+ * as 'D' in Part Number last character.
+ */
+ revision = IMX_CHIP_REVISION_1_5;
+ break;
+ default:
+ revision = IMX_CHIP_REVISION_UNKNOWN;
+ }
+
+ mxc_set_cpu_type(digprog >> 16 & 0xff);
+ imx_set_soc_revision(revision);
+}
+
+void __init imx_anatop_init(void)
+{
+ anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop");
+ if (IS_ERR(anatop)) {
+ pr_err("%s: failed to find imx6q-anatop regmap!\n", __func__);
+ return;
+ }
+
+ imx_anatop_usb_chrg_detect_disable();
+}
diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c
new file mode 100644
index 000000000..1a8932335
--- /dev/null
+++ b/arch/arm/mach-imx/avic.c
@@ -0,0 +1,201 @@
+/*
+ * 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/irqdomain.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <asm/mach/irq.h>
+#include <asm/exception.h>
+
+#include "common.h"
+#include "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 */
+
+#define AVIC_NUM_IRQS 64
+
+static void __iomem *avic_base;
+static struct irq_domain *domain;
+
+#ifdef CONFIG_FIQ
+static int avic_set_irq_fiq(unsigned int irq, unsigned int type)
+{
+ struct irq_data *d = irq_get_irq_data(irq);
+ unsigned int irqt;
+
+ irq = d->hwirq;
+
+ if (irq >= AVIC_NUM_IRQS)
+ return -EINVAL;
+
+ if (irq < AVIC_NUM_IRQS / 2) {
+ irqt = __raw_readl(avic_base + AVIC_INTTYPEL) & ~(1 << irq);
+ __raw_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEL);
+ } else {
+ irq -= AVIC_NUM_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 */
+
+
+static struct mxc_extra_irq avic_extra_irq = {
+#ifdef CONFIG_FIQ
+ .set_irq_fiq = avic_set_irq_fiq,
+#endif
+};
+
+#ifdef CONFIG_PM
+static u32 avic_saved_mask_reg[2];
+
+static void avic_irq_suspend(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct irq_chip_type *ct = gc->chip_types;
+ int idx = d->hwirq >> 5;
+
+ avic_saved_mask_reg[idx] = __raw_readl(avic_base + ct->regs.mask);
+ __raw_writel(gc->wake_active, avic_base + ct->regs.mask);
+}
+
+static void avic_irq_resume(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct irq_chip_type *ct = gc->chip_types;
+ int idx = d->hwirq >> 5;
+
+ __raw_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask);
+}
+
+#else
+#define avic_irq_suspend NULL
+#define avic_irq_resume NULL
+#endif
+
+static __init void avic_init_gc(int idx, unsigned int irq_start)
+{
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+
+ gc = irq_alloc_generic_chip("mxc-avic", 1, irq_start, avic_base,
+ handle_level_irq);
+ gc->private = &avic_extra_irq;
+ gc->wake_enabled = IRQ_MSK(32);
+
+ ct = gc->chip_types;
+ ct->chip.irq_mask = irq_gc_mask_clr_bit;
+ ct->chip.irq_unmask = irq_gc_mask_set_bit;
+ ct->chip.irq_ack = irq_gc_mask_clr_bit;
+ ct->chip.irq_set_wake = irq_gc_set_wake;
+ ct->chip.irq_suspend = avic_irq_suspend;
+ ct->chip.irq_resume = avic_irq_resume;
+ ct->regs.mask = !idx ? AVIC_INTENABLEL : AVIC_INTENABLEH;
+ ct->regs.ack = ct->regs.mask;
+
+ irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0);
+}
+
+static void __exception_irq_entry avic_handle_irq(struct pt_regs *regs)
+{
+ u32 nivector;
+
+ do {
+ nivector = __raw_readl(avic_base + AVIC_NIVECSR) >> 16;
+ if (nivector == 0xffff)
+ break;
+
+ handle_domain_irq(domain, nivector, regs);
+ } while (1);
+}
+
+/*
+ * 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)
+{
+ struct device_node *np;
+ int irq_base;
+ 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);
+
+ irq_base = irq_alloc_descs(-1, 0, AVIC_NUM_IRQS, numa_node_id());
+ WARN_ON(irq_base < 0);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,avic");
+ domain = irq_domain_add_legacy(np, AVIC_NUM_IRQS, irq_base, 0,
+ &irq_domain_simple_ops, NULL);
+ WARN_ON(!domain);
+
+ for (i = 0; i < AVIC_NUM_IRQS / 32; i++, irq_base += 32)
+ avic_init_gc(i, irq_base);
+
+ /* Set default priority value (0) for all IRQ's */
+ for (i = 0; i < 8; i++)
+ __raw_writel(0, avic_base + AVIC_NIPRIORITY(i));
+
+ set_handle_irq(avic_handle_irq);
+
+#ifdef CONFIG_FIQ
+ /* Initialize FIQ */
+ init_FIQ(FIQ_START);
+#endif
+
+ printk(KERN_INFO "MXC IRQ initialized\n");
+}
diff --git a/arch/arm/mach-imx/board-mx31lilly.h b/arch/arm/mach-imx/board-mx31lilly.h
new file mode 100644
index 000000000..0df71bfef
--- /dev/null
+++ b/arch/arm/mach-imx/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/mach-imx/board-mx31lite.h b/arch/arm/mach-imx/board-mx31lite.h
new file mode 100644
index 000000000..c1ad0ae80
--- /dev/null
+++ b/arch/arm/mach-imx/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/mach-imx/board-mx31moboard.h b/arch/arm/mach-imx/board-mx31moboard.h
new file mode 100644
index 000000000..de1454389
--- /dev/null
+++ b/arch/arm/mach-imx/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/mach-imx/clk-busy.c b/arch/arm/mach-imx/clk-busy.c
new file mode 100644
index 000000000..4bb1bc419
--- /dev/null
+++ b/arch/arm/mach-imx/clk-busy.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * 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/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/err.h>
+#include "clk.h"
+
+static int clk_busy_wait(void __iomem *reg, u8 shift)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(10);
+
+ while (readl_relaxed(reg) & (1 << shift))
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+struct clk_busy_divider {
+ struct clk_divider div;
+ const struct clk_ops *div_ops;
+ void __iomem *reg;
+ u8 shift;
+};
+
+static inline struct clk_busy_divider *to_clk_busy_divider(struct clk_hw *hw)
+{
+ struct clk_divider *div = container_of(hw, struct clk_divider, hw);
+
+ return container_of(div, struct clk_busy_divider, div);
+}
+
+static unsigned long clk_busy_divider_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_busy_divider *busy = to_clk_busy_divider(hw);
+
+ return busy->div_ops->recalc_rate(&busy->div.hw, parent_rate);
+}
+
+static long clk_busy_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct clk_busy_divider *busy = to_clk_busy_divider(hw);
+
+ return busy->div_ops->round_rate(&busy->div.hw, rate, prate);
+}
+
+static int clk_busy_divider_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_busy_divider *busy = to_clk_busy_divider(hw);
+ int ret;
+
+ ret = busy->div_ops->set_rate(&busy->div.hw, rate, parent_rate);
+ if (!ret)
+ ret = clk_busy_wait(busy->reg, busy->shift);
+
+ return ret;
+}
+
+static struct clk_ops clk_busy_divider_ops = {
+ .recalc_rate = clk_busy_divider_recalc_rate,
+ .round_rate = clk_busy_divider_round_rate,
+ .set_rate = clk_busy_divider_set_rate,
+};
+
+struct clk *imx_clk_busy_divider(const char *name, const char *parent_name,
+ void __iomem *reg, u8 shift, u8 width,
+ void __iomem *busy_reg, u8 busy_shift)
+{
+ struct clk_busy_divider *busy;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ busy = kzalloc(sizeof(*busy), GFP_KERNEL);
+ if (!busy)
+ return ERR_PTR(-ENOMEM);
+
+ busy->reg = busy_reg;
+ busy->shift = busy_shift;
+
+ busy->div.reg = reg;
+ busy->div.shift = shift;
+ busy->div.width = width;
+ busy->div.lock = &imx_ccm_lock;
+ busy->div_ops = &clk_divider_ops;
+
+ init.name = name;
+ init.ops = &clk_busy_divider_ops;
+ init.flags = CLK_SET_RATE_PARENT;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ busy->div.hw.init = &init;
+
+ clk = clk_register(NULL, &busy->div.hw);
+ if (IS_ERR(clk))
+ kfree(busy);
+
+ return clk;
+}
+
+struct clk_busy_mux {
+ struct clk_mux mux;
+ const struct clk_ops *mux_ops;
+ void __iomem *reg;
+ u8 shift;
+};
+
+static inline struct clk_busy_mux *to_clk_busy_mux(struct clk_hw *hw)
+{
+ struct clk_mux *mux = container_of(hw, struct clk_mux, hw);
+
+ return container_of(mux, struct clk_busy_mux, mux);
+}
+
+static u8 clk_busy_mux_get_parent(struct clk_hw *hw)
+{
+ struct clk_busy_mux *busy = to_clk_busy_mux(hw);
+
+ return busy->mux_ops->get_parent(&busy->mux.hw);
+}
+
+static int clk_busy_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_busy_mux *busy = to_clk_busy_mux(hw);
+ int ret;
+
+ ret = busy->mux_ops->set_parent(&busy->mux.hw, index);
+ if (!ret)
+ ret = clk_busy_wait(busy->reg, busy->shift);
+
+ return ret;
+}
+
+static struct clk_ops clk_busy_mux_ops = {
+ .get_parent = clk_busy_mux_get_parent,
+ .set_parent = clk_busy_mux_set_parent,
+};
+
+struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
+ u8 width, void __iomem *busy_reg, u8 busy_shift,
+ const char **parent_names, int num_parents)
+{
+ struct clk_busy_mux *busy;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ busy = kzalloc(sizeof(*busy), GFP_KERNEL);
+ if (!busy)
+ return ERR_PTR(-ENOMEM);
+
+ busy->reg = busy_reg;
+ busy->shift = busy_shift;
+
+ busy->mux.reg = reg;
+ busy->mux.shift = shift;
+ busy->mux.mask = BIT(width) - 1;
+ busy->mux.lock = &imx_ccm_lock;
+ busy->mux_ops = &clk_mux_ops;
+
+ init.name = name;
+ init.ops = &clk_busy_mux_ops;
+ init.flags = 0;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+
+ busy->mux.hw.init = &init;
+
+ clk = clk_register(NULL, &busy->mux.hw);
+ if (IS_ERR(clk))
+ kfree(busy);
+
+ return clk;
+}
diff --git a/arch/arm/mach-imx/clk-cpu.c b/arch/arm/mach-imx/clk-cpu.c
new file mode 100644
index 000000000..aa1c345e2
--- /dev/null
+++ b/arch/arm/mach-imx/clk-cpu.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2014 Lucas Stach <l.stach@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.
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+
+struct clk_cpu {
+ struct clk_hw hw;
+ struct clk *div;
+ struct clk *mux;
+ struct clk *pll;
+ struct clk *step;
+};
+
+static inline struct clk_cpu *to_clk_cpu(struct clk_hw *hw)
+{
+ return container_of(hw, struct clk_cpu, hw);
+}
+
+static unsigned long clk_cpu_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_cpu *cpu = to_clk_cpu(hw);
+
+ return clk_get_rate(cpu->div);
+}
+
+static long clk_cpu_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct clk_cpu *cpu = to_clk_cpu(hw);
+
+ return clk_round_rate(cpu->pll, rate);
+}
+
+static int clk_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_cpu *cpu = to_clk_cpu(hw);
+ int ret;
+
+ /* switch to PLL bypass clock */
+ ret = clk_set_parent(cpu->mux, cpu->step);
+ if (ret)
+ return ret;
+
+ /* reprogram PLL */
+ ret = clk_set_rate(cpu->pll, rate);
+ if (ret) {
+ clk_set_parent(cpu->mux, cpu->pll);
+ return ret;
+ }
+ /* switch back to PLL clock */
+ clk_set_parent(cpu->mux, cpu->pll);
+
+ /* Ensure the divider is what we expect */
+ clk_set_rate(cpu->div, rate);
+
+ return 0;
+}
+
+static const struct clk_ops clk_cpu_ops = {
+ .recalc_rate = clk_cpu_recalc_rate,
+ .round_rate = clk_cpu_round_rate,
+ .set_rate = clk_cpu_set_rate,
+};
+
+struct clk *imx_clk_cpu(const char *name, const char *parent_name,
+ struct clk *div, struct clk *mux, struct clk *pll,
+ struct clk *step)
+{
+ struct clk_cpu *cpu;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ cpu = kzalloc(sizeof(*cpu), GFP_KERNEL);
+ if (!cpu)
+ return ERR_PTR(-ENOMEM);
+
+ cpu->div = div;
+ cpu->mux = mux;
+ cpu->pll = pll;
+ cpu->step = step;
+
+ init.name = name;
+ init.ops = &clk_cpu_ops;
+ init.flags = 0;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ cpu->hw.init = &init;
+
+ clk = clk_register(NULL, &cpu->hw);
+ if (IS_ERR(clk))
+ kfree(cpu);
+
+ return clk;
+}
diff --git a/arch/arm/mach-imx/clk-fixup-div.c b/arch/arm/mach-imx/clk-fixup-div.c
new file mode 100644
index 000000000..21db020b1
--- /dev/null
+++ b/arch/arm/mach-imx/clk-fixup-div.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2013 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/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include "clk.h"
+
+#define to_clk_div(_hw) container_of(_hw, struct clk_divider, hw)
+#define div_mask(d) ((1 << (d->width)) - 1)
+
+/**
+ * struct clk_fixup_div - imx integer fixup divider clock
+ * @divider: the parent class
+ * @ops: pointer to clk_ops of parent class
+ * @fixup: a hook to fixup the write value
+ *
+ * The imx fixup divider clock is a subclass of basic clk_divider
+ * with an addtional fixup hook.
+ */
+struct clk_fixup_div {
+ struct clk_divider divider;
+ const struct clk_ops *ops;
+ void (*fixup)(u32 *val);
+};
+
+static inline struct clk_fixup_div *to_clk_fixup_div(struct clk_hw *hw)
+{
+ struct clk_divider *divider = to_clk_div(hw);
+
+ return container_of(divider, struct clk_fixup_div, divider);
+}
+
+static unsigned long clk_fixup_div_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw);
+
+ return fixup_div->ops->recalc_rate(&fixup_div->divider.hw, parent_rate);
+}
+
+static long clk_fixup_div_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw);
+
+ return fixup_div->ops->round_rate(&fixup_div->divider.hw, rate, prate);
+}
+
+static int clk_fixup_div_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw);
+ struct clk_divider *div = to_clk_div(hw);
+ unsigned int divider, value;
+ unsigned long flags = 0;
+ u32 val;
+
+ divider = parent_rate / rate;
+
+ /* Zero based divider */
+ value = divider - 1;
+
+ if (value > div_mask(div))
+ value = div_mask(div);
+
+ spin_lock_irqsave(div->lock, flags);
+
+ val = readl(div->reg);
+ val &= ~(div_mask(div) << div->shift);
+ val |= value << div->shift;
+ fixup_div->fixup(&val);
+ writel(val, div->reg);
+
+ spin_unlock_irqrestore(div->lock, flags);
+
+ return 0;
+}
+
+static const struct clk_ops clk_fixup_div_ops = {
+ .recalc_rate = clk_fixup_div_recalc_rate,
+ .round_rate = clk_fixup_div_round_rate,
+ .set_rate = clk_fixup_div_set_rate,
+};
+
+struct clk *imx_clk_fixup_divider(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, u8 width,
+ void (*fixup)(u32 *val))
+{
+ struct clk_fixup_div *fixup_div;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ if (!fixup)
+ return ERR_PTR(-EINVAL);
+
+ fixup_div = kzalloc(sizeof(*fixup_div), GFP_KERNEL);
+ if (!fixup_div)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &clk_fixup_div_ops;
+ init.flags = CLK_SET_RATE_PARENT;
+ init.parent_names = parent ? &parent : NULL;
+ init.num_parents = parent ? 1 : 0;
+
+ fixup_div->divider.reg = reg;
+ fixup_div->divider.shift = shift;
+ fixup_div->divider.width = width;
+ fixup_div->divider.lock = &imx_ccm_lock;
+ fixup_div->divider.hw.init = &init;
+ fixup_div->ops = &clk_divider_ops;
+ fixup_div->fixup = fixup;
+
+ clk = clk_register(NULL, &fixup_div->divider.hw);
+ if (IS_ERR(clk))
+ kfree(fixup_div);
+
+ return clk;
+}
diff --git a/arch/arm/mach-imx/clk-fixup-mux.c b/arch/arm/mach-imx/clk-fixup-mux.c
new file mode 100644
index 000000000..0d40b35c5
--- /dev/null
+++ b/arch/arm/mach-imx/clk-fixup-mux.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013 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/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include "clk.h"
+
+#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
+
+/**
+ * struct clk_fixup_mux - imx integer fixup multiplexer clock
+ * @mux: the parent class
+ * @ops: pointer to clk_ops of parent class
+ * @fixup: a hook to fixup the write value
+ *
+ * The imx fixup multiplexer clock is a subclass of basic clk_mux
+ * with an addtional fixup hook.
+ */
+struct clk_fixup_mux {
+ struct clk_mux mux;
+ const struct clk_ops *ops;
+ void (*fixup)(u32 *val);
+};
+
+static inline struct clk_fixup_mux *to_clk_fixup_mux(struct clk_hw *hw)
+{
+ struct clk_mux *mux = to_clk_mux(hw);
+
+ return container_of(mux, struct clk_fixup_mux, mux);
+}
+
+static u8 clk_fixup_mux_get_parent(struct clk_hw *hw)
+{
+ struct clk_fixup_mux *fixup_mux = to_clk_fixup_mux(hw);
+
+ return fixup_mux->ops->get_parent(&fixup_mux->mux.hw);
+}
+
+static int clk_fixup_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_fixup_mux *fixup_mux = to_clk_fixup_mux(hw);
+ struct clk_mux *mux = to_clk_mux(hw);
+ unsigned long flags = 0;
+ u32 val;
+
+ spin_lock_irqsave(mux->lock, flags);
+
+ val = readl(mux->reg);
+ val &= ~(mux->mask << mux->shift);
+ val |= index << mux->shift;
+ fixup_mux->fixup(&val);
+ writel(val, mux->reg);
+
+ spin_unlock_irqrestore(mux->lock, flags);
+
+ return 0;
+}
+
+static const struct clk_ops clk_fixup_mux_ops = {
+ .get_parent = clk_fixup_mux_get_parent,
+ .set_parent = clk_fixup_mux_set_parent,
+};
+
+struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg,
+ u8 shift, u8 width, const char **parents,
+ int num_parents, void (*fixup)(u32 *val))
+{
+ struct clk_fixup_mux *fixup_mux;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ if (!fixup)
+ return ERR_PTR(-EINVAL);
+
+ fixup_mux = kzalloc(sizeof(*fixup_mux), GFP_KERNEL);
+ if (!fixup_mux)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &clk_fixup_mux_ops;
+ init.parent_names = parents;
+ init.num_parents = num_parents;
+ init.flags = 0;
+
+ fixup_mux->mux.reg = reg;
+ fixup_mux->mux.shift = shift;
+ fixup_mux->mux.mask = BIT(width) - 1;
+ fixup_mux->mux.lock = &imx_ccm_lock;
+ fixup_mux->mux.hw.init = &init;
+ fixup_mux->ops = &clk_mux_ops;
+ fixup_mux->fixup = fixup;
+
+ clk = clk_register(NULL, &fixup_mux->mux.hw);
+ if (IS_ERR(clk))
+ kfree(fixup_mux);
+
+ return clk;
+}
diff --git a/arch/arm/mach-imx/clk-gate-exclusive.c b/arch/arm/mach-imx/clk-gate-exclusive.c
new file mode 100644
index 000000000..c12f5f2e0
--- /dev/null
+++ b/arch/arm/mach-imx/clk-gate-exclusive.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2014 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 <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include "clk.h"
+
+/**
+ * struct clk_gate_exclusive - i.MX specific gate clock which is mutually
+ * exclusive with other gate clocks
+ *
+ * @gate: the parent class
+ * @exclusive_mask: mask of gate bits which are mutually exclusive to this
+ * gate clock
+ *
+ * The imx exclusive gate clock is a subclass of basic clk_gate
+ * with an addtional mask to indicate which other gate bits in the same
+ * register is mutually exclusive to this gate clock.
+ */
+struct clk_gate_exclusive {
+ struct clk_gate gate;
+ u32 exclusive_mask;
+};
+
+static int clk_gate_exclusive_enable(struct clk_hw *hw)
+{
+ struct clk_gate *gate = container_of(hw, struct clk_gate, hw);
+ struct clk_gate_exclusive *exgate = container_of(gate,
+ struct clk_gate_exclusive, gate);
+ u32 val = readl(gate->reg);
+
+ if (val & exgate->exclusive_mask)
+ return -EBUSY;
+
+ return clk_gate_ops.enable(hw);
+}
+
+static void clk_gate_exclusive_disable(struct clk_hw *hw)
+{
+ clk_gate_ops.disable(hw);
+}
+
+static int clk_gate_exclusive_is_enabled(struct clk_hw *hw)
+{
+ return clk_gate_ops.is_enabled(hw);
+}
+
+static const struct clk_ops clk_gate_exclusive_ops = {
+ .enable = clk_gate_exclusive_enable,
+ .disable = clk_gate_exclusive_disable,
+ .is_enabled = clk_gate_exclusive_is_enabled,
+};
+
+struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, u32 exclusive_mask)
+{
+ struct clk_gate_exclusive *exgate;
+ struct clk_gate *gate;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ if (exclusive_mask == 0)
+ return ERR_PTR(-EINVAL);
+
+ exgate = kzalloc(sizeof(*exgate), GFP_KERNEL);
+ if (!exgate)
+ return ERR_PTR(-ENOMEM);
+ gate = &exgate->gate;
+
+ init.name = name;
+ init.ops = &clk_gate_exclusive_ops;
+ init.flags = CLK_SET_RATE_PARENT;
+ init.parent_names = parent ? &parent : NULL;
+ init.num_parents = parent ? 1 : 0;
+
+ gate->reg = reg;
+ gate->bit_idx = shift;
+ gate->lock = &imx_ccm_lock;
+ gate->hw.init = &init;
+ exgate->exclusive_mask = exclusive_mask;
+
+ clk = clk_register(NULL, &gate->hw);
+ if (IS_ERR(clk))
+ kfree(exgate);
+
+ return clk;
+}
diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
new file mode 100644
index 000000000..8935bff99
--- /dev/null
+++ b/arch/arm/mach-imx/clk-gate2.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@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.
+ *
+ * Gated clock implementation
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include "clk.h"
+
+/**
+ * DOC: basic gatable clock which can gate and ungate it's ouput
+ *
+ * Traits of this clock:
+ * prepare - clk_(un)prepare only ensures parent is (un)prepared
+ * enable - clk_enable and clk_disable are functional & control gating
+ * rate - inherits rate from parent. No clk_set_rate support
+ * parent - fixed parent. No clk_set_parent support
+ */
+
+struct clk_gate2 {
+ struct clk_hw hw;
+ void __iomem *reg;
+ u8 bit_idx;
+ u8 flags;
+ spinlock_t *lock;
+ unsigned int *share_count;
+};
+
+#define to_clk_gate2(_hw) container_of(_hw, struct clk_gate2, hw)
+
+static int clk_gate2_enable(struct clk_hw *hw)
+{
+ struct clk_gate2 *gate = to_clk_gate2(hw);
+ u32 reg;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(gate->lock, flags);
+
+ if (gate->share_count && (*gate->share_count)++ > 0)
+ goto out;
+
+ reg = readl(gate->reg);
+ reg |= 3 << gate->bit_idx;
+ writel(reg, gate->reg);
+
+out:
+ spin_unlock_irqrestore(gate->lock, flags);
+
+ return 0;
+}
+
+static void clk_gate2_disable(struct clk_hw *hw)
+{
+ struct clk_gate2 *gate = to_clk_gate2(hw);
+ u32 reg;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(gate->lock, flags);
+
+ if (gate->share_count) {
+ if (WARN_ON(*gate->share_count == 0))
+ goto out;
+ else if (--(*gate->share_count) > 0)
+ goto out;
+ }
+
+ reg = readl(gate->reg);
+ reg &= ~(3 << gate->bit_idx);
+ writel(reg, gate->reg);
+
+out:
+ spin_unlock_irqrestore(gate->lock, flags);
+}
+
+static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx)
+{
+ u32 val = readl(reg);
+
+ if (((val >> bit_idx) & 1) == 1)
+ return 1;
+
+ return 0;
+}
+
+static int clk_gate2_is_enabled(struct clk_hw *hw)
+{
+ struct clk_gate2 *gate = to_clk_gate2(hw);
+
+ return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx);
+}
+
+static void clk_gate2_disable_unused(struct clk_hw *hw)
+{
+ struct clk_gate2 *gate = to_clk_gate2(hw);
+ unsigned long flags = 0;
+ u32 reg;
+
+ spin_lock_irqsave(gate->lock, flags);
+
+ if (!gate->share_count || *gate->share_count == 0) {
+ reg = readl(gate->reg);
+ reg &= ~(3 << gate->bit_idx);
+ writel(reg, gate->reg);
+ }
+
+ spin_unlock_irqrestore(gate->lock, flags);
+}
+
+static struct clk_ops clk_gate2_ops = {
+ .enable = clk_gate2_enable,
+ .disable = clk_gate2_disable,
+ .disable_unused = clk_gate2_disable_unused,
+ .is_enabled = clk_gate2_is_enabled,
+};
+
+struct clk *clk_register_gate2(struct device *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ void __iomem *reg, u8 bit_idx,
+ u8 clk_gate2_flags, spinlock_t *lock,
+ unsigned int *share_count)
+{
+ struct clk_gate2 *gate;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ gate = kzalloc(sizeof(struct clk_gate2), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ /* struct clk_gate2 assignments */
+ gate->reg = reg;
+ gate->bit_idx = bit_idx;
+ gate->flags = clk_gate2_flags;
+ gate->lock = lock;
+ gate->share_count = share_count;
+
+ init.name = name;
+ init.ops = &clk_gate2_ops;
+ init.flags = flags;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.num_parents = parent_name ? 1 : 0;
+
+ gate->hw.init = &init;
+
+ clk = clk_register(dev, &gate->hw);
+ if (IS_ERR(clk))
+ kfree(gate);
+
+ return clk;
+}
diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c
new file mode 100644
index 000000000..37c307a8d
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx1.c
@@ -0,0 +1,117 @@
+/*
+ * 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/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <dt-bindings/clock/imx1-clock.h>
+
+#include "clk.h"
+#include "common.h"
+#include "hardware.h"
+
+static const char *prem_sel_clks[] = { "clk32_premult", "clk16m", };
+static const char *clko_sel_clks[] = { "per1", "hclk", "clk48m", "clk16m",
+ "prem", "fclk", };
+
+static struct clk *clk[IMX1_CLK_MAX];
+static struct clk_onecell_data clk_data;
+
+static void __iomem *ccm __initdata;
+#define CCM_CSCR (ccm + 0x0000)
+#define CCM_MPCTL0 (ccm + 0x0004)
+#define CCM_SPCTL0 (ccm + 0x000c)
+#define CCM_PCDR (ccm + 0x0020)
+#define SCM_GCCR (ccm + 0x0810)
+
+static void __init _mx1_clocks_init(unsigned long fref)
+{
+ clk[IMX1_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+ clk[IMX1_CLK_CLK32] = imx_obtain_fixed_clock("clk32", fref);
+ clk[IMX1_CLK_CLK16M_EXT] = imx_clk_fixed("clk16m_ext", 16000000);
+ clk[IMX1_CLK_CLK16M] = imx_clk_gate("clk16m", "clk16m_ext", CCM_CSCR, 17);
+ clk[IMX1_CLK_CLK32_PREMULT] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1);
+ clk[IMX1_CLK_PREM] = imx_clk_mux("prem", CCM_CSCR, 16, 1, prem_sel_clks, ARRAY_SIZE(prem_sel_clks));
+ clk[IMX1_CLK_MPLL] = imx_clk_pllv1("mpll", "clk32_premult", CCM_MPCTL0);
+ clk[IMX1_CLK_MPLL_GATE] = imx_clk_gate("mpll_gate", "mpll", CCM_CSCR, 0);
+ clk[IMX1_CLK_SPLL] = imx_clk_pllv1("spll", "prem", CCM_SPCTL0);
+ clk[IMX1_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1);
+ clk[IMX1_CLK_MCU] = imx_clk_divider("mcu", "clk32_premult", CCM_CSCR, 15, 1);
+ clk[IMX1_CLK_FCLK] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 15, 1);
+ clk[IMX1_CLK_HCLK] = imx_clk_divider("hclk", "spll_gate", CCM_CSCR, 10, 4);
+ clk[IMX1_CLK_CLK48M] = imx_clk_divider("clk48m", "spll_gate", CCM_CSCR, 26, 3);
+ clk[IMX1_CLK_PER1] = imx_clk_divider("per1", "spll_gate", CCM_PCDR, 0, 4);
+ clk[IMX1_CLK_PER2] = imx_clk_divider("per2", "spll_gate", CCM_PCDR, 4, 4);
+ clk[IMX1_CLK_PER3] = imx_clk_divider("per3", "spll_gate", CCM_PCDR, 16, 7);
+ clk[IMX1_CLK_CLKO] = imx_clk_mux("clko", CCM_CSCR, 29, 3, clko_sel_clks, ARRAY_SIZE(clko_sel_clks));
+ clk[IMX1_CLK_UART3_GATE] = imx_clk_gate("uart3_gate", "hclk", SCM_GCCR, 6);
+ clk[IMX1_CLK_SSI2_GATE] = imx_clk_gate("ssi2_gate", "hclk", SCM_GCCR, 5);
+ clk[IMX1_CLK_BROM_GATE] = imx_clk_gate("brom_gate", "hclk", SCM_GCCR, 4);
+ clk[IMX1_CLK_DMA_GATE] = imx_clk_gate("dma_gate", "hclk", SCM_GCCR, 3);
+ clk[IMX1_CLK_CSI_GATE] = imx_clk_gate("csi_gate", "hclk", SCM_GCCR, 2);
+ clk[IMX1_CLK_MMA_GATE] = imx_clk_gate("mma_gate", "hclk", SCM_GCCR, 1);
+ clk[IMX1_CLK_USBD_GATE] = imx_clk_gate("usbd_gate", "clk48m", SCM_GCCR, 0);
+
+ imx_check_clocks(clk, ARRAY_SIZE(clk));
+}
+
+int __init mx1_clocks_init(unsigned long fref)
+{
+ ccm = MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR);
+
+ _mx1_clocks_init(fref);
+
+ clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx-gpt.0");
+ clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx-gpt.0");
+ clk_register_clkdev(clk[IMX1_CLK_DMA_GATE], "ahb", "imx1-dma");
+ clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx1-dma");
+ clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx1-uart.0");
+ clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx1-uart.0");
+ clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx1-uart.1");
+ clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx1-uart.1");
+ clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx1-uart.2");
+ clk_register_clkdev(clk[IMX1_CLK_UART3_GATE], "ipg", "imx1-uart.2");
+ clk_register_clkdev(clk[IMX1_CLK_HCLK], NULL, "imx1-i2c.0");
+ clk_register_clkdev(clk[IMX1_CLK_PER2], "per", "imx1-cspi.0");
+ clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-cspi.0");
+ clk_register_clkdev(clk[IMX1_CLK_PER2], "per", "imx1-cspi.1");
+ clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-cspi.1");
+ clk_register_clkdev(clk[IMX1_CLK_PER2], "per", "imx1-fb.0");
+ clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-fb.0");
+ clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ahb", "imx1-fb.0");
+
+ mxc_timer_init(MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), MX1_TIM1_INT);
+
+ return 0;
+}
+
+static void __init mx1_clocks_init_dt(struct device_node *np)
+{
+ ccm = of_iomap(np, 0);
+ BUG_ON(!ccm);
+
+ _mx1_clocks_init(32768);
+
+ clk_data.clks = clk;
+ clk_data.clk_num = ARRAY_SIZE(clk);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+CLK_OF_DECLARE(imx1_ccm, "fsl,imx1-ccm", mx1_clocks_init_dt);
diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c
new file mode 100644
index 000000000..4b4c75339
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx21.c
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <dt-bindings/clock/imx21-clock.h>
+
+#include "clk.h"
+#include "common.h"
+#include "hardware.h"
+
+static void __iomem *ccm __initdata;
+
+/* Register offsets */
+#define CCM_CSCR (ccm + 0x00)
+#define CCM_MPCTL0 (ccm + 0x04)
+#define CCM_SPCTL0 (ccm + 0x0c)
+#define CCM_PCDR0 (ccm + 0x18)
+#define CCM_PCDR1 (ccm + 0x1c)
+#define CCM_PCCR0 (ccm + 0x20)
+#define CCM_PCCR1 (ccm + 0x24)
+
+static const char *mpll_osc_sel_clks[] = { "ckih_gate", "ckih_div1p5", };
+static const char *mpll_sel_clks[] = { "fpm_gate", "mpll_osc_sel", };
+static const char *spll_sel_clks[] = { "fpm_gate", "mpll_osc_sel", };
+static const char *ssi_sel_clks[] = { "spll_gate", "mpll_gate", };
+
+static struct clk *clk[IMX21_CLK_MAX];
+static struct clk_onecell_data clk_data;
+
+static void __init _mx21_clocks_init(unsigned long lref, unsigned long href)
+{
+ BUG_ON(!ccm);
+
+ clk[IMX21_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+ clk[IMX21_CLK_CKIL] = imx_obtain_fixed_clock("ckil", lref);
+ clk[IMX21_CLK_CKIH] = imx_obtain_fixed_clock("ckih", href);
+ clk[IMX21_CLK_FPM] = imx_clk_fixed_factor("fpm", "ckil", 512, 1);
+ clk[IMX21_CLK_CKIH_DIV1P5] = imx_clk_fixed_factor("ckih_div1p5", "ckih_gate", 2, 3);
+
+ clk[IMX21_CLK_MPLL_GATE] = imx_clk_gate("mpll_gate", "mpll", CCM_CSCR, 0);
+ clk[IMX21_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1);
+ clk[IMX21_CLK_FPM_GATE] = imx_clk_gate("fpm_gate", "fpm", CCM_CSCR, 2);
+ clk[IMX21_CLK_CKIH_GATE] = imx_clk_gate_dis("ckih_gate", "ckih", CCM_CSCR, 3);
+ clk[IMX21_CLK_MPLL_OSC_SEL] = imx_clk_mux("mpll_osc_sel", CCM_CSCR, 4, 1, mpll_osc_sel_clks, ARRAY_SIZE(mpll_osc_sel_clks));
+ clk[IMX21_CLK_IPG] = imx_clk_divider("ipg", "hclk", CCM_CSCR, 9, 1);
+ clk[IMX21_CLK_HCLK] = imx_clk_divider("hclk", "fclk", CCM_CSCR, 10, 4);
+ clk[IMX21_CLK_MPLL_SEL] = imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks, ARRAY_SIZE(mpll_sel_clks));
+ clk[IMX21_CLK_SPLL_SEL] = imx_clk_mux("spll_sel", CCM_CSCR, 17, 1, spll_sel_clks, ARRAY_SIZE(spll_sel_clks));
+ clk[IMX21_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", CCM_CSCR, 19, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
+ clk[IMX21_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", CCM_CSCR, 20, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
+ clk[IMX21_CLK_USB_DIV] = imx_clk_divider("usb_div", "spll_gate", CCM_CSCR, 26, 3);
+ clk[IMX21_CLK_FCLK] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 29, 3);
+
+ clk[IMX21_CLK_MPLL] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0);
+
+ clk[IMX21_CLK_SPLL] = imx_clk_pllv1("spll", "spll_sel", CCM_SPCTL0);
+
+ clk[IMX21_CLK_NFC_DIV] = imx_clk_divider("nfc_div", "fclk", CCM_PCDR0, 12, 4);
+ clk[IMX21_CLK_SSI1_DIV] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6);
+ clk[IMX21_CLK_SSI2_DIV] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 6);
+
+ clk[IMX21_CLK_PER1] = imx_clk_divider("per1", "mpll_gate", CCM_PCDR1, 0, 6);
+ clk[IMX21_CLK_PER2] = imx_clk_divider("per2", "mpll_gate", CCM_PCDR1, 8, 6);
+ clk[IMX21_CLK_PER3] = imx_clk_divider("per3", "mpll_gate", CCM_PCDR1, 16, 6);
+ clk[IMX21_CLK_PER4] = imx_clk_divider("per4", "mpll_gate", CCM_PCDR1, 24, 6);
+
+ clk[IMX21_CLK_UART1_IPG_GATE] = imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR0, 0);
+ clk[IMX21_CLK_UART2_IPG_GATE] = imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR0, 1);
+ clk[IMX21_CLK_UART3_IPG_GATE] = imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR0, 2);
+ clk[IMX21_CLK_UART4_IPG_GATE] = imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR0, 3);
+ clk[IMX21_CLK_CSPI1_IPG_GATE] = imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 4);
+ clk[IMX21_CLK_CSPI2_IPG_GATE] = imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 5);
+ clk[IMX21_CLK_SSI1_GATE] = imx_clk_gate("ssi1_gate", "ipg", CCM_PCCR0, 6);
+ clk[IMX21_CLK_SSI2_GATE] = imx_clk_gate("ssi2_gate", "ipg", CCM_PCCR0, 7);
+ clk[IMX21_CLK_SDHC1_IPG_GATE] = imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 9);
+ clk[IMX21_CLK_SDHC2_IPG_GATE] = imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 10);
+ clk[IMX21_CLK_GPIO_GATE] = imx_clk_gate("gpio_gate", "ipg", CCM_PCCR0, 11);
+ clk[IMX21_CLK_I2C_GATE] = imx_clk_gate("i2c_gate", "ipg", CCM_PCCR0, 12);
+ clk[IMX21_CLK_DMA_GATE] = imx_clk_gate("dma_gate", "ipg", CCM_PCCR0, 13);
+ clk[IMX21_CLK_USB_GATE] = imx_clk_gate("usb_gate", "usb_div", CCM_PCCR0, 14);
+ clk[IMX21_CLK_EMMA_GATE] = imx_clk_gate("emma_gate", "ipg", CCM_PCCR0, 15);
+ clk[IMX21_CLK_SSI2_BAUD_GATE] = imx_clk_gate("ssi2_baud_gate", "ipg", CCM_PCCR0, 16);
+ clk[IMX21_CLK_SSI1_BAUD_GATE] = imx_clk_gate("ssi1_baud_gate", "ipg", CCM_PCCR0, 17);
+ clk[IMX21_CLK_LCDC_IPG_GATE] = imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 18);
+ clk[IMX21_CLK_NFC_GATE] = imx_clk_gate("nfc_gate", "nfc_div", CCM_PCCR0, 19);
+ clk[IMX21_CLK_SLCDC_HCLK_GATE] = imx_clk_gate("slcdc_hclk_gate", "hclk", CCM_PCCR0, 21);
+ clk[IMX21_CLK_PER4_GATE] = imx_clk_gate("per4_gate", "per4", CCM_PCCR0, 22);
+ clk[IMX21_CLK_BMI_GATE] = imx_clk_gate("bmi_gate", "hclk", CCM_PCCR0, 23);
+ clk[IMX21_CLK_USB_HCLK_GATE] = imx_clk_gate("usb_hclk_gate", "hclk", CCM_PCCR0, 24);
+ clk[IMX21_CLK_SLCDC_GATE] = imx_clk_gate("slcdc_gate", "hclk", CCM_PCCR0, 25);
+ clk[IMX21_CLK_LCDC_HCLK_GATE] = imx_clk_gate("lcdc_hclk_gate", "hclk", CCM_PCCR0, 26);
+ clk[IMX21_CLK_EMMA_HCLK_GATE] = imx_clk_gate("emma_hclk_gate", "hclk", CCM_PCCR0, 27);
+ clk[IMX21_CLK_BROM_GATE] = imx_clk_gate("brom_gate", "hclk", CCM_PCCR0, 28);
+ clk[IMX21_CLK_DMA_HCLK_GATE] = imx_clk_gate("dma_hclk_gate", "hclk", CCM_PCCR0, 30);
+ clk[IMX21_CLK_CSI_HCLK_GATE] = imx_clk_gate("csi_hclk_gate", "hclk", CCM_PCCR0, 31);
+
+ clk[IMX21_CLK_CSPI3_IPG_GATE] = imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR1, 23);
+ clk[IMX21_CLK_WDOG_GATE] = imx_clk_gate("wdog_gate", "ipg", CCM_PCCR1, 24);
+ clk[IMX21_CLK_GPT1_IPG_GATE] = imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR1, 25);
+ clk[IMX21_CLK_GPT2_IPG_GATE] = imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR1, 26);
+ clk[IMX21_CLK_GPT3_IPG_GATE] = imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR1, 27);
+ clk[IMX21_CLK_PWM_IPG_GATE] = imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR1, 28);
+ clk[IMX21_CLK_RTC_GATE] = imx_clk_gate("rtc_gate", "ipg", CCM_PCCR1, 29);
+ clk[IMX21_CLK_KPP_GATE] = imx_clk_gate("kpp_gate", "ipg", CCM_PCCR1, 30);
+ clk[IMX21_CLK_OWIRE_GATE] = imx_clk_gate("owire_gate", "ipg", CCM_PCCR1, 31);
+
+ imx_check_clocks(clk, ARRAY_SIZE(clk));
+}
+
+int __init mx21_clocks_init(unsigned long lref, unsigned long href)
+{
+ ccm = ioremap(MX21_CCM_BASE_ADDR, SZ_2K);
+
+ _mx21_clocks_init(lref, href);
+
+ clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.0");
+ clk_register_clkdev(clk[IMX21_CLK_UART1_IPG_GATE], "ipg", "imx21-uart.0");
+ clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.1");
+ clk_register_clkdev(clk[IMX21_CLK_UART2_IPG_GATE], "ipg", "imx21-uart.1");
+ clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.2");
+ clk_register_clkdev(clk[IMX21_CLK_UART3_IPG_GATE], "ipg", "imx21-uart.2");
+ clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.3");
+ clk_register_clkdev(clk[IMX21_CLK_UART4_IPG_GATE], "ipg", "imx21-uart.3");
+ clk_register_clkdev(clk[IMX21_CLK_GPT1_IPG_GATE], "ipg", "imx-gpt.0");
+ clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx-gpt.0");
+ clk_register_clkdev(clk[IMX21_CLK_PER2], "per", "imx21-cspi.0");
+ clk_register_clkdev(clk[IMX21_CLK_CSPI1_IPG_GATE], "ipg", "imx21-cspi.0");
+ clk_register_clkdev(clk[IMX21_CLK_PER2], "per", "imx21-cspi.1");
+ clk_register_clkdev(clk[IMX21_CLK_CSPI2_IPG_GATE], "ipg", "imx21-cspi.1");
+ clk_register_clkdev(clk[IMX21_CLK_PER2], "per", "imx21-cspi.2");
+ clk_register_clkdev(clk[IMX21_CLK_CSPI3_IPG_GATE], "ipg", "imx21-cspi.2");
+ clk_register_clkdev(clk[IMX21_CLK_PER3], "per", "imx21-fb.0");
+ clk_register_clkdev(clk[IMX21_CLK_LCDC_IPG_GATE], "ipg", "imx21-fb.0");
+ clk_register_clkdev(clk[IMX21_CLK_LCDC_HCLK_GATE], "ahb", "imx21-fb.0");
+ clk_register_clkdev(clk[IMX21_CLK_USB_GATE], "per", "imx21-hcd.0");
+ clk_register_clkdev(clk[IMX21_CLK_USB_HCLK_GATE], "ahb", "imx21-hcd.0");
+ clk_register_clkdev(clk[IMX21_CLK_NFC_GATE], NULL, "imx21-nand.0");
+ clk_register_clkdev(clk[IMX21_CLK_DMA_HCLK_GATE], "ahb", "imx21-dma");
+ clk_register_clkdev(clk[IMX21_CLK_DMA_GATE], "ipg", "imx21-dma");
+ clk_register_clkdev(clk[IMX21_CLK_WDOG_GATE], NULL, "imx2-wdt.0");
+ clk_register_clkdev(clk[IMX21_CLK_I2C_GATE], NULL, "imx21-i2c.0");
+ clk_register_clkdev(clk[IMX21_CLK_OWIRE_GATE], NULL, "mxc_w1.0");
+
+ mxc_timer_init(MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), MX21_INT_GPT1);
+
+ return 0;
+}
+
+static void __init mx21_clocks_init_dt(struct device_node *np)
+{
+ ccm = of_iomap(np, 0);
+
+ _mx21_clocks_init(32768, 26000000);
+
+ clk_data.clks = clk;
+ clk_data.clk_num = ARRAY_SIZE(clk);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+CLK_OF_DECLARE(imx27_ccm, "fsl,imx21-ccm", mx21_clocks_init_dt);
diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c
new file mode 100644
index 000000000..9c2633a9d
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx25.c
@@ -0,0 +1,264 @@
+/*
+ * 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 <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#include "clk.h"
+#include "common.h"
+#include "hardware.h"
+
+#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
+#define CCM_MCR 0x64
+
+#define ccm(x) (ccm_base + (x))
+
+static struct clk_onecell_data clk_data;
+
+static const char *cpu_sel_clks[] = { "mpll", "mpll_cpu_3_4", };
+static const char *per_sel_clks[] = { "ahb", "upll", };
+static const char *cko_sel_clks[] = { "dummy", "osc", "cpu", "ahb",
+ "ipg", "dummy", "dummy", "dummy",
+ "dummy", "dummy", "per0", "per2",
+ "per13", "per14", "usbotg_ahb", "dummy",};
+
+enum mx25_clks {
+ dummy, osc, mpll, upll, mpll_cpu_3_4, cpu_sel, cpu, ahb, usb_div, ipg,
+ per0_sel, per1_sel, per2_sel, per3_sel, per4_sel, per5_sel, per6_sel,
+ per7_sel, per8_sel, per9_sel, per10_sel, per11_sel, per12_sel,
+ per13_sel, per14_sel, per15_sel, per0, per1, per2, per3, per4, per5,
+ per6, per7, per8, per9, per10, per11, per12, per13, per14, per15,
+ csi_ipg_per, epit_ipg_per, esai_ipg_per, esdhc1_ipg_per, esdhc2_ipg_per,
+ gpt_ipg_per, i2c_ipg_per, lcdc_ipg_per, nfc_ipg_per, owire_ipg_per,
+ pwm_ipg_per, sim1_ipg_per, sim2_ipg_per, ssi1_ipg_per, ssi2_ipg_per,
+ uart_ipg_per, ata_ahb, reserved1, csi_ahb, emi_ahb, esai_ahb, esdhc1_ahb,
+ esdhc2_ahb, fec_ahb, lcdc_ahb, rtic_ahb, sdma_ahb, slcdc_ahb, usbotg_ahb,
+ reserved2, reserved3, reserved4, reserved5, can1_ipg, can2_ipg, csi_ipg,
+ cspi1_ipg, cspi2_ipg, cspi3_ipg, dryice_ipg, ect_ipg, epit1_ipg, epit2_ipg,
+ reserved6, esdhc1_ipg, esdhc2_ipg, fec_ipg, reserved7, reserved8, reserved9,
+ gpt1_ipg, gpt2_ipg, gpt3_ipg, gpt4_ipg, reserved10, reserved11, reserved12,
+ iim_ipg, reserved13, reserved14, kpp_ipg, lcdc_ipg, reserved15, pwm1_ipg,
+ pwm2_ipg, pwm3_ipg, pwm4_ipg, rngb_ipg, reserved16, scc_ipg, sdma_ipg,
+ sim1_ipg, sim2_ipg, slcdc_ipg, spba_ipg, ssi1_ipg, ssi2_ipg, tsc_ipg,
+ uart1_ipg, uart2_ipg, uart3_ipg, uart4_ipg, uart5_ipg, reserved17,
+ wdt_ipg, cko_div, cko_sel, cko, clk_max
+};
+
+static struct clk *clk[clk_max];
+
+static int __init __mx25_clocks_init(unsigned long osc_rate,
+ void __iomem *ccm_base)
+{
+ BUG_ON(!ccm_base);
+
+ clk[dummy] = imx_clk_fixed("dummy", 0);
+ clk[osc] = imx_clk_fixed("osc", osc_rate);
+ clk[mpll] = imx_clk_pllv1("mpll", "osc", ccm(CCM_MPCTL));
+ clk[upll] = imx_clk_pllv1("upll", "osc", ccm(CCM_UPCTL));
+ clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4);
+ clk[cpu_sel] = imx_clk_mux("cpu_sel", ccm(CCM_CCTL), 14, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
+ clk[cpu] = imx_clk_divider("cpu", "cpu_sel", ccm(CCM_CCTL), 30, 2);
+ clk[ahb] = imx_clk_divider("ahb", "cpu", ccm(CCM_CCTL), 28, 2);
+ clk[usb_div] = imx_clk_divider("usb_div", "upll", ccm(CCM_CCTL), 16, 6);
+ clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
+ clk[per0_sel] = imx_clk_mux("per0_sel", ccm(CCM_MCR), 0, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per1_sel] = imx_clk_mux("per1_sel", ccm(CCM_MCR), 1, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per2_sel] = imx_clk_mux("per2_sel", ccm(CCM_MCR), 2, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per3_sel] = imx_clk_mux("per3_sel", ccm(CCM_MCR), 3, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per4_sel] = imx_clk_mux("per4_sel", ccm(CCM_MCR), 4, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per5_sel] = imx_clk_mux("per5_sel", ccm(CCM_MCR), 5, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per6_sel] = imx_clk_mux("per6_sel", ccm(CCM_MCR), 6, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per7_sel] = imx_clk_mux("per7_sel", ccm(CCM_MCR), 7, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per8_sel] = imx_clk_mux("per8_sel", ccm(CCM_MCR), 8, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per9_sel] = imx_clk_mux("per9_sel", ccm(CCM_MCR), 9, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per10_sel] = imx_clk_mux("per10_sel", ccm(CCM_MCR), 10, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per11_sel] = imx_clk_mux("per11_sel", ccm(CCM_MCR), 11, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per12_sel] = imx_clk_mux("per12_sel", ccm(CCM_MCR), 12, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per13_sel] = imx_clk_mux("per13_sel", ccm(CCM_MCR), 13, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per14_sel] = imx_clk_mux("per14_sel", ccm(CCM_MCR), 14, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per15_sel] = imx_clk_mux("per15_sel", ccm(CCM_MCR), 15, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[cko_div] = imx_clk_divider("cko_div", "cko_sel", ccm(CCM_MCR), 24, 6);
+ clk[cko_sel] = imx_clk_mux("cko_sel", ccm(CCM_MCR), 20, 4, cko_sel_clks, ARRAY_SIZE(cko_sel_clks));
+ clk[cko] = imx_clk_gate("cko", "cko_div", ccm(CCM_MCR), 30);
+ clk[per0] = imx_clk_divider("per0", "per0_sel", ccm(CCM_PCDR0), 0, 6);
+ clk[per1] = imx_clk_divider("per1", "per1_sel", ccm(CCM_PCDR0), 8, 6);
+ clk[per2] = imx_clk_divider("per2", "per2_sel", ccm(CCM_PCDR0), 16, 6);
+ clk[per3] = imx_clk_divider("per3", "per3_sel", ccm(CCM_PCDR0), 24, 6);
+ clk[per4] = imx_clk_divider("per4", "per4_sel", ccm(CCM_PCDR1), 0, 6);
+ clk[per5] = imx_clk_divider("per5", "per5_sel", ccm(CCM_PCDR1), 8, 6);
+ clk[per6] = imx_clk_divider("per6", "per6_sel", ccm(CCM_PCDR1), 16, 6);
+ clk[per7] = imx_clk_divider("per7", "per7_sel", ccm(CCM_PCDR1), 24, 6);
+ clk[per8] = imx_clk_divider("per8", "per8_sel", ccm(CCM_PCDR2), 0, 6);
+ clk[per9] = imx_clk_divider("per9", "per9_sel", ccm(CCM_PCDR2), 8, 6);
+ clk[per10] = imx_clk_divider("per10", "per10_sel", ccm(CCM_PCDR2), 16, 6);
+ clk[per11] = imx_clk_divider("per11", "per11_sel", ccm(CCM_PCDR2), 24, 6);
+ clk[per12] = imx_clk_divider("per12", "per12_sel", ccm(CCM_PCDR3), 0, 6);
+ clk[per13] = imx_clk_divider("per13", "per13_sel", ccm(CCM_PCDR3), 8, 6);
+ clk[per14] = imx_clk_divider("per14", "per14_sel", ccm(CCM_PCDR3), 16, 6);
+ clk[per15] = imx_clk_divider("per15", "per15_sel", ccm(CCM_PCDR3), 24, 6);
+ clk[csi_ipg_per] = imx_clk_gate("csi_ipg_per", "per0", ccm(CCM_CGCR0), 0);
+ clk[epit_ipg_per] = imx_clk_gate("epit_ipg_per", "per1", ccm(CCM_CGCR0), 1);
+ clk[esai_ipg_per] = imx_clk_gate("esai_ipg_per", "per2", ccm(CCM_CGCR0), 2);
+ clk[esdhc1_ipg_per] = imx_clk_gate("esdhc1_ipg_per", "per3", ccm(CCM_CGCR0), 3);
+ clk[esdhc2_ipg_per] = imx_clk_gate("esdhc2_ipg_per", "per4", ccm(CCM_CGCR0), 4);
+ clk[gpt_ipg_per] = imx_clk_gate("gpt_ipg_per", "per5", ccm(CCM_CGCR0), 5);
+ clk[i2c_ipg_per] = imx_clk_gate("i2c_ipg_per", "per6", ccm(CCM_CGCR0), 6);
+ clk[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per7", ccm(CCM_CGCR0), 7);
+ clk[nfc_ipg_per] = imx_clk_gate("nfc_ipg_per", "per8", ccm(CCM_CGCR0), 8);
+ clk[owire_ipg_per] = imx_clk_gate("owire_ipg_per", "per9", ccm(CCM_CGCR0), 9);
+ clk[pwm_ipg_per] = imx_clk_gate("pwm_ipg_per", "per10", ccm(CCM_CGCR0), 10);
+ clk[sim1_ipg_per] = imx_clk_gate("sim1_ipg_per", "per11", ccm(CCM_CGCR0), 11);
+ clk[sim2_ipg_per] = imx_clk_gate("sim2_ipg_per", "per12", ccm(CCM_CGCR0), 12);
+ clk[ssi1_ipg_per] = imx_clk_gate("ssi1_ipg_per", "per13", ccm(CCM_CGCR0), 13);
+ clk[ssi2_ipg_per] = imx_clk_gate("ssi2_ipg_per", "per14", ccm(CCM_CGCR0), 14);
+ clk[uart_ipg_per] = imx_clk_gate("uart_ipg_per", "per15", ccm(CCM_CGCR0), 15);
+ clk[ata_ahb] = imx_clk_gate("ata_ahb", "ahb", ccm(CCM_CGCR0), 16);
+ /* CCM_CGCR0(17): reserved */
+ clk[csi_ahb] = imx_clk_gate("csi_ahb", "ahb", ccm(CCM_CGCR0), 18);
+ clk[emi_ahb] = imx_clk_gate("emi_ahb", "ahb", ccm(CCM_CGCR0), 19);
+ clk[esai_ahb] = imx_clk_gate("esai_ahb", "ahb", ccm(CCM_CGCR0), 20);
+ clk[esdhc1_ahb] = imx_clk_gate("esdhc1_ahb", "ahb", ccm(CCM_CGCR0), 21);
+ clk[esdhc2_ahb] = imx_clk_gate("esdhc2_ahb", "ahb", ccm(CCM_CGCR0), 22);
+ clk[fec_ahb] = imx_clk_gate("fec_ahb", "ahb", ccm(CCM_CGCR0), 23);
+ clk[lcdc_ahb] = imx_clk_gate("lcdc_ahb", "ahb", ccm(CCM_CGCR0), 24);
+ clk[rtic_ahb] = imx_clk_gate("rtic_ahb", "ahb", ccm(CCM_CGCR0), 25);
+ clk[sdma_ahb] = imx_clk_gate("sdma_ahb", "ahb", ccm(CCM_CGCR0), 26);
+ clk[slcdc_ahb] = imx_clk_gate("slcdc_ahb", "ahb", ccm(CCM_CGCR0), 27);
+ clk[usbotg_ahb] = imx_clk_gate("usbotg_ahb", "ahb", ccm(CCM_CGCR0), 28);
+ /* CCM_CGCR0(29-31): reserved */
+ /* CCM_CGCR1(0): reserved in datasheet, used as audmux in FSL kernel */
+ clk[can1_ipg] = imx_clk_gate("can1_ipg", "ipg", ccm(CCM_CGCR1), 2);
+ clk[can2_ipg] = imx_clk_gate("can2_ipg", "ipg", ccm(CCM_CGCR1), 3);
+ clk[csi_ipg] = imx_clk_gate("csi_ipg", "ipg", ccm(CCM_CGCR1), 4);
+ clk[cspi1_ipg] = imx_clk_gate("cspi1_ipg", "ipg", ccm(CCM_CGCR1), 5);
+ clk[cspi2_ipg] = imx_clk_gate("cspi2_ipg", "ipg", ccm(CCM_CGCR1), 6);
+ clk[cspi3_ipg] = imx_clk_gate("cspi3_ipg", "ipg", ccm(CCM_CGCR1), 7);
+ clk[dryice_ipg] = imx_clk_gate("dryice_ipg", "ipg", ccm(CCM_CGCR1), 8);
+ clk[ect_ipg] = imx_clk_gate("ect_ipg", "ipg", ccm(CCM_CGCR1), 9);
+ clk[epit1_ipg] = imx_clk_gate("epit1_ipg", "ipg", ccm(CCM_CGCR1), 10);
+ clk[epit2_ipg] = imx_clk_gate("epit2_ipg", "ipg", ccm(CCM_CGCR1), 11);
+ /* CCM_CGCR1(12): reserved in datasheet, used as esai in FSL kernel */
+ clk[esdhc1_ipg] = imx_clk_gate("esdhc1_ipg", "ipg", ccm(CCM_CGCR1), 13);
+ clk[esdhc2_ipg] = imx_clk_gate("esdhc2_ipg", "ipg", ccm(CCM_CGCR1), 14);
+ clk[fec_ipg] = imx_clk_gate("fec_ipg", "ipg", ccm(CCM_CGCR1), 15);
+ /* CCM_CGCR1(16): reserved in datasheet, used as gpio1 in FSL kernel */
+ /* CCM_CGCR1(17): reserved in datasheet, used as gpio2 in FSL kernel */
+ /* CCM_CGCR1(18): reserved in datasheet, used as gpio3 in FSL kernel */
+ clk[gpt1_ipg] = imx_clk_gate("gpt1_ipg", "ipg", ccm(CCM_CGCR1), 19);
+ clk[gpt2_ipg] = imx_clk_gate("gpt2_ipg", "ipg", ccm(CCM_CGCR1), 20);
+ clk[gpt3_ipg] = imx_clk_gate("gpt3_ipg", "ipg", ccm(CCM_CGCR1), 21);
+ clk[gpt4_ipg] = imx_clk_gate("gpt4_ipg", "ipg", ccm(CCM_CGCR1), 22);
+ /* CCM_CGCR1(23): reserved in datasheet, used as i2c1 in FSL kernel */
+ /* CCM_CGCR1(24): reserved in datasheet, used as i2c2 in FSL kernel */
+ /* CCM_CGCR1(25): reserved in datasheet, used as i2c3 in FSL kernel */
+ clk[iim_ipg] = imx_clk_gate("iim_ipg", "ipg", ccm(CCM_CGCR1), 26);
+ /* CCM_CGCR1(27): reserved in datasheet, used as iomuxc in FSL kernel */
+ /* CCM_CGCR1(28): reserved in datasheet, used as kpp in FSL kernel */
+ clk[kpp_ipg] = imx_clk_gate("kpp_ipg", "ipg", ccm(CCM_CGCR1), 28);
+ clk[lcdc_ipg] = imx_clk_gate("lcdc_ipg", "ipg", ccm(CCM_CGCR1), 29);
+ /* CCM_CGCR1(30): reserved in datasheet, used as owire in FSL kernel */
+ clk[pwm1_ipg] = imx_clk_gate("pwm1_ipg", "ipg", ccm(CCM_CGCR1), 31);
+ clk[pwm2_ipg] = imx_clk_gate("pwm2_ipg", "ipg", ccm(CCM_CGCR2), 0);
+ clk[pwm3_ipg] = imx_clk_gate("pwm3_ipg", "ipg", ccm(CCM_CGCR2), 1);
+ clk[pwm4_ipg] = imx_clk_gate("pwm4_ipg", "ipg", ccm(CCM_CGCR2), 2);
+ clk[rngb_ipg] = imx_clk_gate("rngb_ipg", "ipg", ccm(CCM_CGCR2), 3);
+ /* CCM_CGCR2(4): reserved in datasheet, used as rtic in FSL kernel */
+ clk[scc_ipg] = imx_clk_gate("scc_ipg", "ipg", ccm(CCM_CGCR2), 5);
+ clk[sdma_ipg] = imx_clk_gate("sdma_ipg", "ipg", ccm(CCM_CGCR2), 6);
+ clk[sim1_ipg] = imx_clk_gate("sim1_ipg", "ipg", ccm(CCM_CGCR2), 7);
+ clk[sim2_ipg] = imx_clk_gate("sim2_ipg", "ipg", ccm(CCM_CGCR2), 8);
+ clk[slcdc_ipg] = imx_clk_gate("slcdc_ipg", "ipg", ccm(CCM_CGCR2), 9);
+ clk[spba_ipg] = imx_clk_gate("spba_ipg", "ipg", ccm(CCM_CGCR2), 10);
+ clk[ssi1_ipg] = imx_clk_gate("ssi1_ipg", "ipg", ccm(CCM_CGCR2), 11);
+ clk[ssi2_ipg] = imx_clk_gate("ssi2_ipg", "ipg", ccm(CCM_CGCR2), 12);
+ clk[tsc_ipg] = imx_clk_gate("tsc_ipg", "ipg", ccm(CCM_CGCR2), 13);
+ clk[uart1_ipg] = imx_clk_gate("uart1_ipg", "ipg", ccm(CCM_CGCR2), 14);
+ clk[uart2_ipg] = imx_clk_gate("uart2_ipg", "ipg", ccm(CCM_CGCR2), 15);
+ clk[uart3_ipg] = imx_clk_gate("uart3_ipg", "ipg", ccm(CCM_CGCR2), 16);
+ clk[uart4_ipg] = imx_clk_gate("uart4_ipg", "ipg", ccm(CCM_CGCR2), 17);
+ clk[uart5_ipg] = imx_clk_gate("uart5_ipg", "ipg", ccm(CCM_CGCR2), 18);
+ /* CCM_CGCR2(19): reserved in datasheet, but used as wdt in FSL kernel */
+ clk[wdt_ipg] = imx_clk_gate("wdt_ipg", "ipg", ccm(CCM_CGCR2), 19);
+
+ imx_check_clocks(clk, ARRAY_SIZE(clk));
+
+ clk_prepare_enable(clk[emi_ahb]);
+
+ /* Clock source for gpt must be derived from AHB */
+ clk_set_parent(clk[per5_sel], clk[ahb]);
+
+ /*
+ * Let's initially set up CLKO parent as ipg, since this configuration
+ * is used on some imx25 board designs to clock the audio codec.
+ */
+ clk_set_parent(clk[cko_sel], clk[ipg]);
+
+ return 0;
+}
+
+static void __init mx25_clocks_init_dt(struct device_node *np)
+{
+ struct device_node *refnp;
+ unsigned long osc_rate = 24000000;
+ void __iomem *ccm;
+
+ /* retrieve the freqency of fixed clocks from device tree */
+ for_each_compatible_node(refnp, NULL, "fixed-clock") {
+ u32 rate;
+ if (of_property_read_u32(refnp, "clock-frequency", &rate))
+ continue;
+
+ if (of_device_is_compatible(refnp, "fsl,imx-osc"))
+ osc_rate = rate;
+ }
+
+ ccm = of_iomap(np, 0);
+ __mx25_clocks_init(osc_rate, ccm);
+
+ clk_data.clks = clk;
+ clk_data.clk_num = ARRAY_SIZE(clk);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+CLK_OF_DECLARE(imx25_ccm, "fsl,imx25-ccm", mx25_clocks_init_dt);
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
new file mode 100644
index 000000000..ab6349ec2
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx27.c
@@ -0,0 +1,258 @@
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <dt-bindings/clock/imx27-clock.h>
+
+#include "clk.h"
+#include "common.h"
+#include "hardware.h"
+
+static void __iomem *ccm __initdata;
+
+/* Register offsets */
+#define CCM_CSCR (ccm + 0x00)
+#define CCM_MPCTL0 (ccm + 0x04)
+#define CCM_MPCTL1 (ccm + 0x08)
+#define CCM_SPCTL0 (ccm + 0x0c)
+#define CCM_SPCTL1 (ccm + 0x10)
+#define CCM_PCDR0 (ccm + 0x18)
+#define CCM_PCDR1 (ccm + 0x1c)
+#define CCM_PCCR0 (ccm + 0x20)
+#define CCM_PCCR1 (ccm + 0x24)
+#define CCM_CCSR (ccm + 0x28)
+
+static const char *vpu_sel_clks[] = { "spll", "mpll_main2", };
+static const char *cpu_sel_clks[] = { "mpll_main2", "mpll", };
+static const char *mpll_sel_clks[] = { "fpm", "mpll_osc_sel", };
+static const char *mpll_osc_sel_clks[] = { "ckih_gate", "ckih_div1p5", };
+static const char *clko_sel_clks[] = {
+ "ckil", "fpm", "ckih_gate", "ckih_gate",
+ "ckih_gate", "mpll", "spll", "cpu_div",
+ "ahb", "ipg", "per1_div", "per2_div",
+ "per3_div", "per4_div", "ssi1_div", "ssi2_div",
+ "nfc_div", "mshc_div", "vpu_div", "60m",
+ "32k", "usb_div", "dptc",
+};
+
+static const char *ssi_sel_clks[] = { "spll_gate", "mpll", };
+
+static struct clk *clk[IMX27_CLK_MAX];
+static struct clk_onecell_data clk_data;
+
+static void __init _mx27_clocks_init(unsigned long fref)
+{
+ BUG_ON(!ccm);
+
+ clk[IMX27_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+ clk[IMX27_CLK_CKIH] = imx_clk_fixed("ckih", fref);
+ clk[IMX27_CLK_CKIL] = imx_clk_fixed("ckil", 32768);
+ clk[IMX27_CLK_FPM] = imx_clk_fixed_factor("fpm", "ckil", 1024, 1);
+ clk[IMX27_CLK_CKIH_DIV1P5] = imx_clk_fixed_factor("ckih_div1p5", "ckih_gate", 2, 3);
+ clk[IMX27_CLK_CKIH_GATE] = imx_clk_gate_dis("ckih_gate", "ckih", CCM_CSCR, 3);
+ clk[IMX27_CLK_MPLL_OSC_SEL] = imx_clk_mux("mpll_osc_sel", CCM_CSCR, 4, 1, mpll_osc_sel_clks, ARRAY_SIZE(mpll_osc_sel_clks));
+ clk[IMX27_CLK_MPLL_SEL] = imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks, ARRAY_SIZE(mpll_sel_clks));
+ clk[IMX27_CLK_MPLL] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0);
+ clk[IMX27_CLK_SPLL] = imx_clk_pllv1("spll", "ckih_gate", CCM_SPCTL0);
+ clk[IMX27_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1);
+ clk[IMX27_CLK_MPLL_MAIN2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3);
+
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
+ clk[IMX27_CLK_AHB] = imx_clk_divider("ahb", "mpll_main2", CCM_CSCR, 8, 2);
+ clk[IMX27_CLK_IPG] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
+ } else {
+ clk[IMX27_CLK_AHB] = imx_clk_divider("ahb", "mpll_main2", CCM_CSCR, 9, 4);
+ clk[IMX27_CLK_IPG] = imx_clk_divider("ipg", "ahb", CCM_CSCR, 8, 1);
+ }
+
+ clk[IMX27_CLK_MSHC_DIV] = imx_clk_divider("mshc_div", "ahb", CCM_PCDR0, 0, 6);
+ clk[IMX27_CLK_NFC_DIV] = imx_clk_divider("nfc_div", "ahb", CCM_PCDR0, 6, 4);
+ clk[IMX27_CLK_PER1_DIV] = imx_clk_divider("per1_div", "mpll_main2", CCM_PCDR1, 0, 6);
+ clk[IMX27_CLK_PER2_DIV] = imx_clk_divider("per2_div", "mpll_main2", CCM_PCDR1, 8, 6);
+ clk[IMX27_CLK_PER3_DIV] = imx_clk_divider("per3_div", "mpll_main2", CCM_PCDR1, 16, 6);
+ clk[IMX27_CLK_PER4_DIV] = imx_clk_divider("per4_div", "mpll_main2", CCM_PCDR1, 24, 6);
+ clk[IMX27_CLK_VPU_SEL] = imx_clk_mux("vpu_sel", CCM_CSCR, 21, 1, vpu_sel_clks, ARRAY_SIZE(vpu_sel_clks));
+ clk[IMX27_CLK_VPU_DIV] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 6);
+ clk[IMX27_CLK_USB_DIV] = imx_clk_divider("usb_div", "spll_gate", CCM_CSCR, 28, 3);
+ clk[IMX27_CLK_CPU_SEL] = imx_clk_mux("cpu_sel", CCM_CSCR, 15, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
+ clk[IMX27_CLK_CLKO_SEL] = imx_clk_mux("clko_sel", CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks));
+
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
+ clk[IMX27_CLK_CPU_DIV] = imx_clk_divider("cpu_div", "cpu_sel", CCM_CSCR, 12, 2);
+ else
+ clk[IMX27_CLK_CPU_DIV] = imx_clk_divider("cpu_div", "cpu_sel", CCM_CSCR, 13, 3);
+
+ clk[IMX27_CLK_CLKO_DIV] = imx_clk_divider("clko_div", "clko_sel", CCM_PCDR0, 22, 3);
+ clk[IMX27_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", CCM_CSCR, 22, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
+ clk[IMX27_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", CCM_CSCR, 23, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
+ clk[IMX27_CLK_SSI1_DIV] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6);
+ clk[IMX27_CLK_SSI2_DIV] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 6);
+ clk[IMX27_CLK_CLKO_EN] = imx_clk_gate("clko_en", "clko_div", CCM_PCCR0, 0);
+ clk[IMX27_CLK_SSI2_IPG_GATE] = imx_clk_gate("ssi2_ipg_gate", "ipg", CCM_PCCR0, 0);
+ clk[IMX27_CLK_SSI1_IPG_GATE] = imx_clk_gate("ssi1_ipg_gate", "ipg", CCM_PCCR0, 1);
+ clk[IMX27_CLK_SLCDC_IPG_GATE] = imx_clk_gate("slcdc_ipg_gate", "ipg", CCM_PCCR0, 2);
+ clk[IMX27_CLK_SDHC3_IPG_GATE] = imx_clk_gate("sdhc3_ipg_gate", "ipg", CCM_PCCR0, 3);
+ clk[IMX27_CLK_SDHC2_IPG_GATE] = imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 4);
+ clk[IMX27_CLK_SDHC1_IPG_GATE] = imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 5);
+ clk[IMX27_CLK_SCC_IPG_GATE] = imx_clk_gate("scc_ipg_gate", "ipg", CCM_PCCR0, 6);
+ clk[IMX27_CLK_SAHARA_IPG_GATE] = imx_clk_gate("sahara_ipg_gate", "ipg", CCM_PCCR0, 7);
+ clk[IMX27_CLK_RTIC_IPG_GATE] = imx_clk_gate("rtic_ipg_gate", "ipg", CCM_PCCR0, 8);
+ clk[IMX27_CLK_RTC_IPG_GATE] = imx_clk_gate("rtc_ipg_gate", "ipg", CCM_PCCR0, 9);
+ clk[IMX27_CLK_PWM_IPG_GATE] = imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR0, 11);
+ clk[IMX27_CLK_OWIRE_IPG_GATE] = imx_clk_gate("owire_ipg_gate", "ipg", CCM_PCCR0, 12);
+ clk[IMX27_CLK_MSHC_IPG_GATE] = imx_clk_gate("mshc_ipg_gate", "ipg", CCM_PCCR0, 13);
+ clk[IMX27_CLK_LCDC_IPG_GATE] = imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 14);
+ clk[IMX27_CLK_KPP_IPG_GATE] = imx_clk_gate("kpp_ipg_gate", "ipg", CCM_PCCR0, 15);
+ clk[IMX27_CLK_IIM_IPG_GATE] = imx_clk_gate("iim_ipg_gate", "ipg", CCM_PCCR0, 16);
+ clk[IMX27_CLK_I2C2_IPG_GATE] = imx_clk_gate("i2c2_ipg_gate", "ipg", CCM_PCCR0, 17);
+ clk[IMX27_CLK_I2C1_IPG_GATE] = imx_clk_gate("i2c1_ipg_gate", "ipg", CCM_PCCR0, 18);
+ clk[IMX27_CLK_GPT6_IPG_GATE] = imx_clk_gate("gpt6_ipg_gate", "ipg", CCM_PCCR0, 19);
+ clk[IMX27_CLK_GPT5_IPG_GATE] = imx_clk_gate("gpt5_ipg_gate", "ipg", CCM_PCCR0, 20);
+ clk[IMX27_CLK_GPT4_IPG_GATE] = imx_clk_gate("gpt4_ipg_gate", "ipg", CCM_PCCR0, 21);
+ clk[IMX27_CLK_GPT3_IPG_GATE] = imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR0, 22);
+ clk[IMX27_CLK_GPT2_IPG_GATE] = imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR0, 23);
+ clk[IMX27_CLK_GPT1_IPG_GATE] = imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR0, 24);
+ clk[IMX27_CLK_GPIO_IPG_GATE] = imx_clk_gate("gpio_ipg_gate", "ipg", CCM_PCCR0, 25);
+ clk[IMX27_CLK_FEC_IPG_GATE] = imx_clk_gate("fec_ipg_gate", "ipg", CCM_PCCR0, 26);
+ clk[IMX27_CLK_EMMA_IPG_GATE] = imx_clk_gate("emma_ipg_gate", "ipg", CCM_PCCR0, 27);
+ clk[IMX27_CLK_DMA_IPG_GATE] = imx_clk_gate("dma_ipg_gate", "ipg", CCM_PCCR0, 28);
+ clk[IMX27_CLK_CSPI3_IPG_GATE] = imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR0, 29);
+ clk[IMX27_CLK_CSPI2_IPG_GATE] = imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 30);
+ clk[IMX27_CLK_CSPI1_IPG_GATE] = imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 31);
+ clk[IMX27_CLK_MSHC_BAUD_GATE] = imx_clk_gate("mshc_baud_gate", "mshc_div", CCM_PCCR1, 2);
+ clk[IMX27_CLK_NFC_BAUD_GATE] = imx_clk_gate("nfc_baud_gate", "nfc_div", CCM_PCCR1, 3);
+ clk[IMX27_CLK_SSI2_BAUD_GATE] = imx_clk_gate("ssi2_baud_gate", "ssi2_div", CCM_PCCR1, 4);
+ clk[IMX27_CLK_SSI1_BAUD_GATE] = imx_clk_gate("ssi1_baud_gate", "ssi1_div", CCM_PCCR1, 5);
+ clk[IMX27_CLK_VPU_BAUD_GATE] = imx_clk_gate("vpu_baud_gate", "vpu_div", CCM_PCCR1, 6);
+ clk[IMX27_CLK_PER4_GATE] = imx_clk_gate("per4_gate", "per4_div", CCM_PCCR1, 7);
+ clk[IMX27_CLK_PER3_GATE] = imx_clk_gate("per3_gate", "per3_div", CCM_PCCR1, 8);
+ clk[IMX27_CLK_PER2_GATE] = imx_clk_gate("per2_gate", "per2_div", CCM_PCCR1, 9);
+ clk[IMX27_CLK_PER1_GATE] = imx_clk_gate("per1_gate", "per1_div", CCM_PCCR1, 10);
+ clk[IMX27_CLK_USB_AHB_GATE] = imx_clk_gate("usb_ahb_gate", "ahb", CCM_PCCR1, 11);
+ clk[IMX27_CLK_SLCDC_AHB_GATE] = imx_clk_gate("slcdc_ahb_gate", "ahb", CCM_PCCR1, 12);
+ clk[IMX27_CLK_SAHARA_AHB_GATE] = imx_clk_gate("sahara_ahb_gate", "ahb", CCM_PCCR1, 13);
+ clk[IMX27_CLK_RTIC_AHB_GATE] = imx_clk_gate("rtic_ahb_gate", "ahb", CCM_PCCR1, 14);
+ clk[IMX27_CLK_LCDC_AHB_GATE] = imx_clk_gate("lcdc_ahb_gate", "ahb", CCM_PCCR1, 15);
+ clk[IMX27_CLK_VPU_AHB_GATE] = imx_clk_gate("vpu_ahb_gate", "ahb", CCM_PCCR1, 16);
+ clk[IMX27_CLK_FEC_AHB_GATE] = imx_clk_gate("fec_ahb_gate", "ahb", CCM_PCCR1, 17);
+ clk[IMX27_CLK_EMMA_AHB_GATE] = imx_clk_gate("emma_ahb_gate", "ahb", CCM_PCCR1, 18);
+ clk[IMX27_CLK_EMI_AHB_GATE] = imx_clk_gate("emi_ahb_gate", "ahb", CCM_PCCR1, 19);
+ clk[IMX27_CLK_DMA_AHB_GATE] = imx_clk_gate("dma_ahb_gate", "ahb", CCM_PCCR1, 20);
+ clk[IMX27_CLK_CSI_AHB_GATE] = imx_clk_gate("csi_ahb_gate", "ahb", CCM_PCCR1, 21);
+ clk[IMX27_CLK_BROM_AHB_GATE] = imx_clk_gate("brom_ahb_gate", "ahb", CCM_PCCR1, 22);
+ clk[IMX27_CLK_ATA_AHB_GATE] = imx_clk_gate("ata_ahb_gate", "ahb", CCM_PCCR1, 23);
+ clk[IMX27_CLK_WDOG_IPG_GATE] = imx_clk_gate("wdog_ipg_gate", "ipg", CCM_PCCR1, 24);
+ clk[IMX27_CLK_USB_IPG_GATE] = imx_clk_gate("usb_ipg_gate", "ipg", CCM_PCCR1, 25);
+ clk[IMX27_CLK_UART6_IPG_GATE] = imx_clk_gate("uart6_ipg_gate", "ipg", CCM_PCCR1, 26);
+ clk[IMX27_CLK_UART5_IPG_GATE] = imx_clk_gate("uart5_ipg_gate", "ipg", CCM_PCCR1, 27);
+ clk[IMX27_CLK_UART4_IPG_GATE] = imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR1, 28);
+ clk[IMX27_CLK_UART3_IPG_GATE] = imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR1, 29);
+ clk[IMX27_CLK_UART2_IPG_GATE] = imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR1, 30);
+ clk[IMX27_CLK_UART1_IPG_GATE] = imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR1, 31);
+
+ imx_check_clocks(clk, ARRAY_SIZE(clk));
+
+ clk_register_clkdev(clk[IMX27_CLK_CPU_DIV], NULL, "cpu0");
+
+ clk_prepare_enable(clk[IMX27_CLK_EMI_AHB_GATE]);
+
+ imx_print_silicon_rev("i.MX27", mx27_revision());
+}
+
+int __init mx27_clocks_init(unsigned long fref)
+{
+ ccm = ioremap(MX27_CCM_BASE_ADDR, SZ_4K);
+
+ _mx27_clocks_init(fref);
+
+ clk_register_clkdev(clk[IMX27_CLK_UART1_IPG_GATE], "ipg", "imx21-uart.0");
+ clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.0");
+ clk_register_clkdev(clk[IMX27_CLK_UART2_IPG_GATE], "ipg", "imx21-uart.1");
+ clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.1");
+ clk_register_clkdev(clk[IMX27_CLK_UART3_IPG_GATE], "ipg", "imx21-uart.2");
+ clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.2");
+ clk_register_clkdev(clk[IMX27_CLK_UART4_IPG_GATE], "ipg", "imx21-uart.3");
+ clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.3");
+ clk_register_clkdev(clk[IMX27_CLK_UART5_IPG_GATE], "ipg", "imx21-uart.4");
+ clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.4");
+ clk_register_clkdev(clk[IMX27_CLK_UART6_IPG_GATE], "ipg", "imx21-uart.5");
+ clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.5");
+ clk_register_clkdev(clk[IMX27_CLK_GPT1_IPG_GATE], "ipg", "imx-gpt.0");
+ clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx-gpt.0");
+ clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx21-mmc.0");
+ clk_register_clkdev(clk[IMX27_CLK_SDHC1_IPG_GATE], "ipg", "imx21-mmc.0");
+ clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx21-mmc.1");
+ clk_register_clkdev(clk[IMX27_CLK_SDHC2_IPG_GATE], "ipg", "imx21-mmc.1");
+ clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx21-mmc.2");
+ clk_register_clkdev(clk[IMX27_CLK_SDHC2_IPG_GATE], "ipg", "imx21-mmc.2");
+ clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx27-cspi.0");
+ clk_register_clkdev(clk[IMX27_CLK_CSPI1_IPG_GATE], "ipg", "imx27-cspi.0");
+ clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx27-cspi.1");
+ clk_register_clkdev(clk[IMX27_CLK_CSPI2_IPG_GATE], "ipg", "imx27-cspi.1");
+ clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx27-cspi.2");
+ clk_register_clkdev(clk[IMX27_CLK_CSPI3_IPG_GATE], "ipg", "imx27-cspi.2");
+ clk_register_clkdev(clk[IMX27_CLK_PER3_GATE], "per", "imx21-fb.0");
+ clk_register_clkdev(clk[IMX27_CLK_LCDC_IPG_GATE], "ipg", "imx21-fb.0");
+ clk_register_clkdev(clk[IMX27_CLK_LCDC_AHB_GATE], "ahb", "imx21-fb.0");
+ clk_register_clkdev(clk[IMX27_CLK_CSI_AHB_GATE], "ahb", "imx27-camera.0");
+ clk_register_clkdev(clk[IMX27_CLK_PER4_GATE], "per", "imx27-camera.0");
+ clk_register_clkdev(clk[IMX27_CLK_USB_DIV], "per", "imx-udc-mx27");
+ clk_register_clkdev(clk[IMX27_CLK_USB_IPG_GATE], "ipg", "imx-udc-mx27");
+ clk_register_clkdev(clk[IMX27_CLK_USB_AHB_GATE], "ahb", "imx-udc-mx27");
+ clk_register_clkdev(clk[IMX27_CLK_USB_DIV], "per", "mxc-ehci.0");
+ clk_register_clkdev(clk[IMX27_CLK_USB_IPG_GATE], "ipg", "mxc-ehci.0");
+ clk_register_clkdev(clk[IMX27_CLK_USB_AHB_GATE], "ahb", "mxc-ehci.0");
+ clk_register_clkdev(clk[IMX27_CLK_USB_DIV], "per", "mxc-ehci.1");
+ clk_register_clkdev(clk[IMX27_CLK_USB_IPG_GATE], "ipg", "mxc-ehci.1");
+ clk_register_clkdev(clk[IMX27_CLK_USB_AHB_GATE], "ahb", "mxc-ehci.1");
+ clk_register_clkdev(clk[IMX27_CLK_USB_DIV], "per", "mxc-ehci.2");
+ clk_register_clkdev(clk[IMX27_CLK_USB_IPG_GATE], "ipg", "mxc-ehci.2");
+ clk_register_clkdev(clk[IMX27_CLK_USB_AHB_GATE], "ahb", "mxc-ehci.2");
+ clk_register_clkdev(clk[IMX27_CLK_SSI1_IPG_GATE], NULL, "imx-ssi.0");
+ clk_register_clkdev(clk[IMX27_CLK_SSI2_IPG_GATE], NULL, "imx-ssi.1");
+ clk_register_clkdev(clk[IMX27_CLK_NFC_BAUD_GATE], NULL, "imx27-nand.0");
+ clk_register_clkdev(clk[IMX27_CLK_VPU_BAUD_GATE], "per", "coda-imx27.0");
+ clk_register_clkdev(clk[IMX27_CLK_VPU_AHB_GATE], "ahb", "coda-imx27.0");
+ clk_register_clkdev(clk[IMX27_CLK_DMA_AHB_GATE], "ahb", "imx27-dma");
+ clk_register_clkdev(clk[IMX27_CLK_DMA_IPG_GATE], "ipg", "imx27-dma");
+ clk_register_clkdev(clk[IMX27_CLK_FEC_IPG_GATE], "ipg", "imx27-fec.0");
+ clk_register_clkdev(clk[IMX27_CLK_FEC_AHB_GATE], "ahb", "imx27-fec.0");
+ clk_register_clkdev(clk[IMX27_CLK_WDOG_IPG_GATE], NULL, "imx2-wdt.0");
+ clk_register_clkdev(clk[IMX27_CLK_I2C1_IPG_GATE], NULL, "imx21-i2c.0");
+ clk_register_clkdev(clk[IMX27_CLK_I2C2_IPG_GATE], NULL, "imx21-i2c.1");
+ clk_register_clkdev(clk[IMX27_CLK_OWIRE_IPG_GATE], NULL, "mxc_w1.0");
+ clk_register_clkdev(clk[IMX27_CLK_KPP_IPG_GATE], NULL, "imx-keypad");
+ clk_register_clkdev(clk[IMX27_CLK_EMMA_AHB_GATE], "emma-ahb", "imx27-camera.0");
+ clk_register_clkdev(clk[IMX27_CLK_EMMA_IPG_GATE], "emma-ipg", "imx27-camera.0");
+ clk_register_clkdev(clk[IMX27_CLK_EMMA_AHB_GATE], "ahb", "m2m-emmaprp.0");
+ clk_register_clkdev(clk[IMX27_CLK_EMMA_IPG_GATE], "ipg", "m2m-emmaprp.0");
+
+ mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1);
+
+ return 0;
+}
+
+static void __init mx27_clocks_init_dt(struct device_node *np)
+{
+ struct device_node *refnp;
+ u32 fref = 26000000; /* default */
+
+ for_each_compatible_node(refnp, NULL, "fixed-clock") {
+ if (!of_device_is_compatible(refnp, "fsl,imx-osc26m"))
+ continue;
+
+ if (!of_property_read_u32(refnp, "clock-frequency", &fref))
+ break;
+ }
+
+ ccm = of_iomap(np, 0);
+
+ _mx27_clocks_init(fref);
+
+ clk_data.clks = clk;
+ clk_data.clk_num = ARRAY_SIZE(clk);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+CLK_OF_DECLARE(imx27_ccm, "fsl,imx27-ccm", mx27_clocks_init_dt);
diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c
new file mode 100644
index 000000000..286ef422c
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx31.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/of.h>
+
+#include "clk.h"
+#include "common.h"
+#include "crmregs-imx3.h"
+#include "hardware.h"
+#include "mx31.h"
+
+static const char *mcu_main_sel[] = { "spll", "mpll", };
+static const char *per_sel[] = { "per_div", "ipg", };
+static const char *csi_sel[] = { "upll", "spll", };
+static const char *fir_sel[] = { "mcu_main", "upll", "spll" };
+
+enum mx31_clks {
+ dummy, ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg,
+ per_div, per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre,
+ fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate,
+ iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate,
+ uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate,
+ mstick1_gate, mstick2_gate, csi_gate, rtc_gate, wdog_gate, pwm_gate,
+ sim_gate, ect_gate, usb_gate, kpp_gate, ipu_gate, uart3_gate,
+ uart4_gate, uart5_gate, owire_gate, ssi2_gate, cspi1_gate, cspi2_gate,
+ gacc_gate, emi_gate, rtic_gate, firi_gate, clk_max
+};
+
+static struct clk *clk[clk_max];
+static struct clk_onecell_data clk_data;
+
+int __init mx31_clocks_init(unsigned long fref)
+{
+ void __iomem *base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR);
+ struct device_node *np;
+
+ clk[dummy] = imx_clk_fixed("dummy", 0);
+ clk[ckih] = imx_clk_fixed("ckih", fref);
+ clk[ckil] = imx_clk_fixed("ckil", 32768);
+ clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MXC_CCM_MPCTL);
+ clk[spll] = imx_clk_pllv1("spll", "ckih", base + MXC_CCM_SRPCTL);
+ clk[upll] = imx_clk_pllv1("upll", "ckih", base + MXC_CCM_UPCTL);
+ clk[mcu_main] = imx_clk_mux("mcu_main", base + MXC_CCM_PMCR0, 31, 1, mcu_main_sel, ARRAY_SIZE(mcu_main_sel));
+ clk[hsp] = imx_clk_divider("hsp", "mcu_main", base + MXC_CCM_PDR0, 11, 3);
+ clk[ahb] = imx_clk_divider("ahb", "mcu_main", base + MXC_CCM_PDR0, 3, 3);
+ clk[nfc] = imx_clk_divider("nfc", "ahb", base + MXC_CCM_PDR0, 8, 3);
+ clk[ipg] = imx_clk_divider("ipg", "ahb", base + MXC_CCM_PDR0, 6, 2);
+ clk[per_div] = imx_clk_divider("per_div", "upll", base + MXC_CCM_PDR0, 16, 5);
+ clk[per] = imx_clk_mux("per", base + MXC_CCM_CCMR, 24, 1, per_sel, ARRAY_SIZE(per_sel));
+ clk[csi] = imx_clk_mux("csi_sel", base + MXC_CCM_CCMR, 25, 1, csi_sel, ARRAY_SIZE(csi_sel));
+ clk[fir] = imx_clk_mux("fir_sel", base + MXC_CCM_CCMR, 11, 2, fir_sel, ARRAY_SIZE(fir_sel));
+ clk[csi_div] = imx_clk_divider("csi_div", "csi_sel", base + MXC_CCM_PDR0, 23, 9);
+ clk[usb_div_pre] = imx_clk_divider("usb_div_pre", "upll", base + MXC_CCM_PDR1, 30, 2);
+ clk[usb_div_post] = imx_clk_divider("usb_div_post", "usb_div_pre", base + MXC_CCM_PDR1, 27, 3);
+ clk[fir_div_pre] = imx_clk_divider("fir_div_pre", "fir_sel", base + MXC_CCM_PDR1, 24, 3);
+ clk[fir_div_post] = imx_clk_divider("fir_div_post", "fir_div_pre", base + MXC_CCM_PDR1, 23, 6);
+ clk[sdhc1_gate] = imx_clk_gate2("sdhc1_gate", "per", base + MXC_CCM_CGR0, 0);
+ clk[sdhc2_gate] = imx_clk_gate2("sdhc2_gate", "per", base + MXC_CCM_CGR0, 2);
+ clk[gpt_gate] = imx_clk_gate2("gpt_gate", "per", base + MXC_CCM_CGR0, 4);
+ clk[epit1_gate] = imx_clk_gate2("epit1_gate", "per", base + MXC_CCM_CGR0, 6);
+ clk[epit2_gate] = imx_clk_gate2("epit2_gate", "per", base + MXC_CCM_CGR0, 8);
+ clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MXC_CCM_CGR0, 10);
+ clk[ata_gate] = imx_clk_gate2("ata_gate", "ipg", base + MXC_CCM_CGR0, 12);
+ clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ahb", base + MXC_CCM_CGR0, 14);
+ clk[cspi3_gate] = imx_clk_gate2("cspi3_gate", "ipg", base + MXC_CCM_CGR0, 16);
+ clk[rng_gate] = imx_clk_gate2("rng_gate", "ipg", base + MXC_CCM_CGR0, 18);
+ clk[uart1_gate] = imx_clk_gate2("uart1_gate", "per", base + MXC_CCM_CGR0, 20);
+ clk[uart2_gate] = imx_clk_gate2("uart2_gate", "per", base + MXC_CCM_CGR0, 22);
+ clk[ssi1_gate] = imx_clk_gate2("ssi1_gate", "spll", base + MXC_CCM_CGR0, 24);
+ clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "per", base + MXC_CCM_CGR0, 26);
+ clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "per", base + MXC_CCM_CGR0, 28);
+ clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per", base + MXC_CCM_CGR0, 30);
+ clk[hantro_gate] = imx_clk_gate2("hantro_gate", "per", base + MXC_CCM_CGR1, 0);
+ clk[mstick1_gate] = imx_clk_gate2("mstick1_gate", "per", base + MXC_CCM_CGR1, 2);
+ clk[mstick2_gate] = imx_clk_gate2("mstick2_gate", "per", base + MXC_CCM_CGR1, 4);
+ clk[csi_gate] = imx_clk_gate2("csi_gate", "csi_div", base + MXC_CCM_CGR1, 6);
+ clk[rtc_gate] = imx_clk_gate2("rtc_gate", "ipg", base + MXC_CCM_CGR1, 8);
+ clk[wdog_gate] = imx_clk_gate2("wdog_gate", "ipg", base + MXC_CCM_CGR1, 10);
+ clk[pwm_gate] = imx_clk_gate2("pwm_gate", "per", base + MXC_CCM_CGR1, 12);
+ clk[sim_gate] = imx_clk_gate2("sim_gate", "per", base + MXC_CCM_CGR1, 14);
+ clk[ect_gate] = imx_clk_gate2("ect_gate", "per", base + MXC_CCM_CGR1, 16);
+ clk[usb_gate] = imx_clk_gate2("usb_gate", "ahb", base + MXC_CCM_CGR1, 18);
+ clk[kpp_gate] = imx_clk_gate2("kpp_gate", "ipg", base + MXC_CCM_CGR1, 20);
+ clk[ipu_gate] = imx_clk_gate2("ipu_gate", "hsp", base + MXC_CCM_CGR1, 22);
+ clk[uart3_gate] = imx_clk_gate2("uart3_gate", "per", base + MXC_CCM_CGR1, 24);
+ clk[uart4_gate] = imx_clk_gate2("uart4_gate", "per", base + MXC_CCM_CGR1, 26);
+ clk[uart5_gate] = imx_clk_gate2("uart5_gate", "per", base + MXC_CCM_CGR1, 28);
+ clk[owire_gate] = imx_clk_gate2("owire_gate", "per", base + MXC_CCM_CGR1, 30);
+ clk[ssi2_gate] = imx_clk_gate2("ssi2_gate", "spll", base + MXC_CCM_CGR2, 0);
+ clk[cspi1_gate] = imx_clk_gate2("cspi1_gate", "ipg", base + MXC_CCM_CGR2, 2);
+ clk[cspi2_gate] = imx_clk_gate2("cspi2_gate", "ipg", base + MXC_CCM_CGR2, 4);
+ clk[gacc_gate] = imx_clk_gate2("gacc_gate", "per", base + MXC_CCM_CGR2, 6);
+ clk[emi_gate] = imx_clk_gate2("emi_gate", "ahb", base + MXC_CCM_CGR2, 8);
+ clk[rtic_gate] = imx_clk_gate2("rtic_gate", "ahb", base + MXC_CCM_CGR2, 10);
+ clk[firi_gate] = imx_clk_gate2("firi_gate", "upll", base+MXC_CCM_CGR2, 12);
+
+ imx_check_clocks(clk, ARRAY_SIZE(clk));
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm");
+
+ if (np) {
+ clk_data.clks = clk;
+ clk_data.clk_num = ARRAY_SIZE(clk);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+ }
+
+ clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
+ clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
+ clk_register_clkdev(clk[cspi1_gate], NULL, "imx31-cspi.0");
+ clk_register_clkdev(clk[cspi2_gate], NULL, "imx31-cspi.1");
+ clk_register_clkdev(clk[cspi3_gate], NULL, "imx31-cspi.2");
+ clk_register_clkdev(clk[pwm_gate], "pwm", NULL);
+ clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
+ clk_register_clkdev(clk[rtc_gate], NULL, "imx21-rtc");
+ clk_register_clkdev(clk[epit1_gate], "epit", NULL);
+ clk_register_clkdev(clk[epit2_gate], "epit", NULL);
+ clk_register_clkdev(clk[nfc], NULL, "imx27-nand.0");
+ clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core");
+ clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");
+ clk_register_clkdev(clk[kpp_gate], NULL, "imx-keypad");
+ clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.0");
+ clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.0");
+ clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
+ clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.1");
+ clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.1");
+ clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1");
+ clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.2");
+ clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.2");
+ clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
+ clk_register_clkdev(clk[usb_div_post], "per", "imx-udc-mx27");
+ clk_register_clkdev(clk[usb_gate], "ahb", "imx-udc-mx27");
+ clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx27");
+ clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
+ /* i.mx31 has the i.mx21 type uart */
+ clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");
+ clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0");
+ clk_register_clkdev(clk[uart2_gate], "per", "imx21-uart.1");
+ clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.1");
+ clk_register_clkdev(clk[uart3_gate], "per", "imx21-uart.2");
+ clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.2");
+ clk_register_clkdev(clk[uart4_gate], "per", "imx21-uart.3");
+ clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.3");
+ clk_register_clkdev(clk[uart5_gate], "per", "imx21-uart.4");
+ clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.4");
+ clk_register_clkdev(clk[i2c1_gate], NULL, "imx21-i2c.0");
+ clk_register_clkdev(clk[i2c2_gate], NULL, "imx21-i2c.1");
+ clk_register_clkdev(clk[i2c3_gate], NULL, "imx21-i2c.2");
+ clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1.0");
+ clk_register_clkdev(clk[sdhc1_gate], NULL, "imx31-mmc.0");
+ clk_register_clkdev(clk[sdhc2_gate], NULL, "imx31-mmc.1");
+ clk_register_clkdev(clk[ssi1_gate], NULL, "imx-ssi.0");
+ clk_register_clkdev(clk[ssi2_gate], NULL, "imx-ssi.1");
+ clk_register_clkdev(clk[firi_gate], "firi", NULL);
+ clk_register_clkdev(clk[ata_gate], NULL, "pata_imx");
+ clk_register_clkdev(clk[rtic_gate], "rtic", NULL);
+ clk_register_clkdev(clk[rng_gate], NULL, "mxc_rnga");
+ clk_register_clkdev(clk[sdma_gate], NULL, "imx31-sdma");
+ clk_register_clkdev(clk[iim_gate], "iim", NULL);
+
+ clk_set_parent(clk[csi], clk[upll]);
+ clk_prepare_enable(clk[emi_gate]);
+ clk_prepare_enable(clk[iim_gate]);
+ mx31_revision();
+ clk_disable_unprepare(clk[iim_gate]);
+
+ mxc_timer_init(MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), MX31_INT_GPT);
+
+ return 0;
+}
+
+int __init mx31_clocks_init_dt(void)
+{
+ struct device_node *np;
+ u32 fref = 26000000; /* default */
+
+ for_each_compatible_node(np, NULL, "fixed-clock") {
+ if (!of_device_is_compatible(np, "fsl,imx-osc26m"))
+ continue;
+
+ if (!of_property_read_u32(np, "clock-frequency", &fref))
+ break;
+ }
+
+ return mx31_clocks_init(fref);
+}
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c
new file mode 100644
index 000000000..a0d2b57fd
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx35.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2012 Sascha Hauer, Pengutronix <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/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/err.h>
+
+#include "crmregs-imx3.h"
+#include "clk.h"
+#include "common.h"
+#include "hardware.h"
+
+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 char hsp_div_532[] = { 4, 8, 3, 0 };
+static char hsp_div_400[] = { 3, 6, 3, 0 };
+
+static struct clk_onecell_data clk_data;
+
+static const char *std_sel[] = {"ppll", "arm"};
+static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"};
+
+enum mx35_clks {
+ ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
+ arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel,
+ esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre,
+ spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre,
+ ssi2_div_post, usb_sel, usb_div, nfc_div, asrc_gate, pata_gate,
+ audmux_gate, can1_gate, can2_gate, cspi1_gate, cspi2_gate, ect_gate,
+ edio_gate, emi_gate, epit1_gate, epit2_gate, esai_gate, esdhc1_gate,
+ esdhc2_gate, esdhc3_gate, fec_gate, gpio1_gate, gpio2_gate, gpio3_gate,
+ gpt_gate, i2c1_gate, i2c2_gate, i2c3_gate, iomuxc_gate, ipu_gate,
+ kpp_gate, mlb_gate, mshc_gate, owire_gate, pwm_gate, rngc_gate,
+ rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate,
+ ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate,
+ wdog_gate, max_gate, admux_gate, csi_gate, csi_div, csi_sel, iim_gate,
+ gpu2d_gate, clk_max
+};
+
+static struct clk *clk[clk_max];
+
+int __init mx35_clocks_init(void)
+{
+ void __iomem *base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR);
+ u32 pdr0, consumer_sel, hsp_sel;
+ struct arm_ahb_div *aad;
+ unsigned char *hsp_div;
+
+ pdr0 = __raw_readl(base + MXC_CCM_PDR0);
+ consumer_sel = (pdr0 >> 16) & 0xf;
+ aad = &clk_consumer[consumer_sel];
+ if (!aad->arm) {
+ pr_err("i.MX35 clk: illegal consumer mux selection 0x%x\n", consumer_sel);
+ /*
+ * We are basically stuck. Continue with a default entry and hope we
+ * get far enough to actually show the above message
+ */
+ aad = &clk_consumer[0];
+ }
+
+ clk[ckih] = imx_clk_fixed("ckih", 24000000);
+ clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MX35_CCM_MPCTL);
+ clk[ppll] = imx_clk_pllv1("ppll", "ckih", base + MX35_CCM_PPCTL);
+
+ clk[mpll] = imx_clk_fixed_factor("mpll_075", "mpll", 3, 4);
+
+ if (aad->sel)
+ clk[arm] = imx_clk_fixed_factor("arm", "mpll_075", 1, aad->arm);
+ else
+ clk[arm] = imx_clk_fixed_factor("arm", "mpll", 1, aad->arm);
+
+ if (clk_get_rate(clk[arm]) > 400000000)
+ hsp_div = hsp_div_532;
+ else
+ hsp_div = hsp_div_400;
+
+ hsp_sel = (pdr0 >> 20) & 0x3;
+ if (!hsp_div[hsp_sel]) {
+ pr_err("i.MX35 clk: illegal hsp clk selection 0x%x\n", hsp_sel);
+ hsp_sel = 0;
+ }
+
+ clk[hsp] = imx_clk_fixed_factor("hsp", "arm", 1, hsp_div[hsp_sel]);
+
+ clk[ahb] = imx_clk_fixed_factor("ahb", "arm", 1, aad->ahb);
+ clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
+
+ clk[arm_per_div] = imx_clk_divider("arm_per_div", "arm", base + MX35_CCM_PDR4, 16, 6);
+ clk[ahb_per_div] = imx_clk_divider("ahb_per_div", "ahb", base + MXC_CCM_PDR0, 12, 3);
+ clk[ipg_per] = imx_clk_mux("ipg_per", base + MXC_CCM_PDR0, 26, 1, ipg_per_sel, ARRAY_SIZE(ipg_per_sel));
+
+ clk[uart_sel] = imx_clk_mux("uart_sel", base + MX35_CCM_PDR3, 14, 1, std_sel, ARRAY_SIZE(std_sel));
+ clk[uart_div] = imx_clk_divider("uart_div", "uart_sel", base + MX35_CCM_PDR4, 10, 6);
+
+ clk[esdhc_sel] = imx_clk_mux("esdhc_sel", base + MX35_CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
+ clk[esdhc1_div] = imx_clk_divider("esdhc1_div", "esdhc_sel", base + MX35_CCM_PDR3, 0, 6);
+ clk[esdhc2_div] = imx_clk_divider("esdhc2_div", "esdhc_sel", base + MX35_CCM_PDR3, 8, 6);
+ clk[esdhc3_div] = imx_clk_divider("esdhc3_div", "esdhc_sel", base + MX35_CCM_PDR3, 16, 6);
+
+ clk[spdif_sel] = imx_clk_mux("spdif_sel", base + MX35_CCM_PDR3, 22, 1, std_sel, ARRAY_SIZE(std_sel));
+ clk[spdif_div_pre] = imx_clk_divider("spdif_div_pre", "spdif_sel", base + MX35_CCM_PDR3, 29, 3); /* divide by 1 not allowed */
+ clk[spdif_div_post] = imx_clk_divider("spdif_div_post", "spdif_div_pre", base + MX35_CCM_PDR3, 23, 6);
+
+ clk[ssi_sel] = imx_clk_mux("ssi_sel", base + MX35_CCM_PDR2, 6, 1, std_sel, ARRAY_SIZE(std_sel));
+ clk[ssi1_div_pre] = imx_clk_divider("ssi1_div_pre", "ssi_sel", base + MX35_CCM_PDR2, 24, 3);
+ clk[ssi1_div_post] = imx_clk_divider("ssi1_div_post", "ssi1_div_pre", base + MX35_CCM_PDR2, 0, 6);
+ clk[ssi2_div_pre] = imx_clk_divider("ssi2_div_pre", "ssi_sel", base + MX35_CCM_PDR2, 27, 3);
+ clk[ssi2_div_post] = imx_clk_divider("ssi2_div_post", "ssi2_div_pre", base + MX35_CCM_PDR2, 8, 6);
+
+ clk[usb_sel] = imx_clk_mux("usb_sel", base + MX35_CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
+ clk[usb_div] = imx_clk_divider("usb_div", "usb_sel", base + MX35_CCM_PDR4, 22, 6);
+
+ clk[nfc_div] = imx_clk_divider("nfc_div", "ahb", base + MX35_CCM_PDR4, 28, 4);
+
+ clk[csi_sel] = imx_clk_mux("csi_sel", base + MX35_CCM_PDR2, 7, 1, std_sel, ARRAY_SIZE(std_sel));
+ clk[csi_div] = imx_clk_divider("csi_div", "csi_sel", base + MX35_CCM_PDR2, 16, 6);
+
+ clk[asrc_gate] = imx_clk_gate2("asrc_gate", "ipg", base + MX35_CCM_CGR0, 0);
+ clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", base + MX35_CCM_CGR0, 2);
+ clk[audmux_gate] = imx_clk_gate2("audmux_gate", "ipg", base + MX35_CCM_CGR0, 4);
+ clk[can1_gate] = imx_clk_gate2("can1_gate", "ipg", base + MX35_CCM_CGR0, 6);
+ clk[can2_gate] = imx_clk_gate2("can2_gate", "ipg", base + MX35_CCM_CGR0, 8);
+ clk[cspi1_gate] = imx_clk_gate2("cspi1_gate", "ipg", base + MX35_CCM_CGR0, 10);
+ clk[cspi2_gate] = imx_clk_gate2("cspi2_gate", "ipg", base + MX35_CCM_CGR0, 12);
+ clk[ect_gate] = imx_clk_gate2("ect_gate", "ipg", base + MX35_CCM_CGR0, 14);
+ clk[edio_gate] = imx_clk_gate2("edio_gate", "ipg", base + MX35_CCM_CGR0, 16);
+ clk[emi_gate] = imx_clk_gate2("emi_gate", "ipg", base + MX35_CCM_CGR0, 18);
+ clk[epit1_gate] = imx_clk_gate2("epit1_gate", "ipg", base + MX35_CCM_CGR0, 20);
+ clk[epit2_gate] = imx_clk_gate2("epit2_gate", "ipg", base + MX35_CCM_CGR0, 22);
+ clk[esai_gate] = imx_clk_gate2("esai_gate", "ipg", base + MX35_CCM_CGR0, 24);
+ clk[esdhc1_gate] = imx_clk_gate2("esdhc1_gate", "esdhc1_div", base + MX35_CCM_CGR0, 26);
+ clk[esdhc2_gate] = imx_clk_gate2("esdhc2_gate", "esdhc2_div", base + MX35_CCM_CGR0, 28);
+ clk[esdhc3_gate] = imx_clk_gate2("esdhc3_gate", "esdhc3_div", base + MX35_CCM_CGR0, 30);
+
+ clk[fec_gate] = imx_clk_gate2("fec_gate", "ipg", base + MX35_CCM_CGR1, 0);
+ clk[gpio1_gate] = imx_clk_gate2("gpio1_gate", "ipg", base + MX35_CCM_CGR1, 2);
+ clk[gpio2_gate] = imx_clk_gate2("gpio2_gate", "ipg", base + MX35_CCM_CGR1, 4);
+ clk[gpio3_gate] = imx_clk_gate2("gpio3_gate", "ipg", base + MX35_CCM_CGR1, 6);
+ clk[gpt_gate] = imx_clk_gate2("gpt_gate", "ipg", base + MX35_CCM_CGR1, 8);
+ clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "ipg_per", base + MX35_CCM_CGR1, 10);
+ clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "ipg_per", base + MX35_CCM_CGR1, 12);
+ clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "ipg_per", base + MX35_CCM_CGR1, 14);
+ clk[iomuxc_gate] = imx_clk_gate2("iomuxc_gate", "ipg", base + MX35_CCM_CGR1, 16);
+ clk[ipu_gate] = imx_clk_gate2("ipu_gate", "hsp", base + MX35_CCM_CGR1, 18);
+ clk[kpp_gate] = imx_clk_gate2("kpp_gate", "ipg", base + MX35_CCM_CGR1, 20);
+ clk[mlb_gate] = imx_clk_gate2("mlb_gate", "ahb", base + MX35_CCM_CGR1, 22);
+ clk[mshc_gate] = imx_clk_gate2("mshc_gate", "dummy", base + MX35_CCM_CGR1, 24);
+ clk[owire_gate] = imx_clk_gate2("owire_gate", "ipg_per", base + MX35_CCM_CGR1, 26);
+ clk[pwm_gate] = imx_clk_gate2("pwm_gate", "ipg_per", base + MX35_CCM_CGR1, 28);
+ clk[rngc_gate] = imx_clk_gate2("rngc_gate", "ipg", base + MX35_CCM_CGR1, 30);
+
+ clk[rtc_gate] = imx_clk_gate2("rtc_gate", "ipg", base + MX35_CCM_CGR2, 0);
+ clk[rtic_gate] = imx_clk_gate2("rtic_gate", "ahb", base + MX35_CCM_CGR2, 2);
+ clk[scc_gate] = imx_clk_gate2("scc_gate", "ipg", base + MX35_CCM_CGR2, 4);
+ clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ahb", base + MX35_CCM_CGR2, 6);
+ clk[spba_gate] = imx_clk_gate2("spba_gate", "ipg", base + MX35_CCM_CGR2, 8);
+ clk[spdif_gate] = imx_clk_gate2("spdif_gate", "spdif_div_post", base + MX35_CCM_CGR2, 10);
+ clk[ssi1_gate] = imx_clk_gate2("ssi1_gate", "ssi1_div_post", base + MX35_CCM_CGR2, 12);
+ clk[ssi2_gate] = imx_clk_gate2("ssi2_gate", "ssi2_div_post", base + MX35_CCM_CGR2, 14);
+ clk[uart1_gate] = imx_clk_gate2("uart1_gate", "uart_div", base + MX35_CCM_CGR2, 16);
+ clk[uart2_gate] = imx_clk_gate2("uart2_gate", "uart_div", base + MX35_CCM_CGR2, 18);
+ clk[uart3_gate] = imx_clk_gate2("uart3_gate", "uart_div", base + MX35_CCM_CGR2, 20);
+ clk[usbotg_gate] = imx_clk_gate2("usbotg_gate", "ahb", base + MX35_CCM_CGR2, 22);
+ clk[wdog_gate] = imx_clk_gate2("wdog_gate", "ipg", base + MX35_CCM_CGR2, 24);
+ clk[max_gate] = imx_clk_gate2("max_gate", "dummy", base + MX35_CCM_CGR2, 26);
+ clk[admux_gate] = imx_clk_gate2("admux_gate", "ipg", base + MX35_CCM_CGR2, 30);
+
+ clk[csi_gate] = imx_clk_gate2("csi_gate", "csi_div", base + MX35_CCM_CGR3, 0);
+ clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MX35_CCM_CGR3, 2);
+ clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "ahb", base + MX35_CCM_CGR3, 4);
+
+ imx_check_clocks(clk, ARRAY_SIZE(clk));
+
+ clk_register_clkdev(clk[pata_gate], NULL, "pata_imx");
+ clk_register_clkdev(clk[can1_gate], NULL, "flexcan.0");
+ clk_register_clkdev(clk[can2_gate], NULL, "flexcan.1");
+ clk_register_clkdev(clk[cspi1_gate], "per", "imx35-cspi.0");
+ clk_register_clkdev(clk[cspi1_gate], "ipg", "imx35-cspi.0");
+ clk_register_clkdev(clk[cspi2_gate], "per", "imx35-cspi.1");
+ clk_register_clkdev(clk[cspi2_gate], "ipg", "imx35-cspi.1");
+ clk_register_clkdev(clk[epit1_gate], NULL, "imx-epit.0");
+ clk_register_clkdev(clk[epit2_gate], NULL, "imx-epit.1");
+ clk_register_clkdev(clk[esdhc1_gate], "per", "sdhci-esdhc-imx35.0");
+ clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.0");
+ clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.0");
+ clk_register_clkdev(clk[esdhc2_gate], "per", "sdhci-esdhc-imx35.1");
+ clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.1");
+ clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.1");
+ clk_register_clkdev(clk[esdhc3_gate], "per", "sdhci-esdhc-imx35.2");
+ clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.2");
+ clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.2");
+ /* i.mx35 has the i.mx27 type fec */
+ clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0");
+ clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
+ clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
+ clk_register_clkdev(clk[i2c1_gate], NULL, "imx21-i2c.0");
+ clk_register_clkdev(clk[i2c2_gate], NULL, "imx21-i2c.1");
+ clk_register_clkdev(clk[i2c3_gate], NULL, "imx21-i2c.2");
+ clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core");
+ clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");
+ clk_register_clkdev(clk[kpp_gate], NULL, "imx-keypad");
+ clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1");
+ clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma");
+ clk_register_clkdev(clk[ssi1_gate], NULL, "imx-ssi.0");
+ clk_register_clkdev(clk[ssi2_gate], NULL, "imx-ssi.1");
+ /* i.mx35 has the i.mx21 type uart */
+ clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");
+ clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0");
+ clk_register_clkdev(clk[uart2_gate], "per", "imx21-uart.1");
+ clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.1");
+ clk_register_clkdev(clk[uart3_gate], "per", "imx21-uart.2");
+ clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.2");
+ clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
+ clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
+ clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.0");
+ clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.1");
+ clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1");
+ clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.1");
+ clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
+ clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
+ clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.2");
+ clk_register_clkdev(clk[usb_div], "per", "imx-udc-mx27");
+ clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx27");
+ clk_register_clkdev(clk[usbotg_gate], "ahb", "imx-udc-mx27");
+ clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
+ clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0");
+ clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
+ clk_register_clkdev(clk[admux_gate], "audmux", NULL);
+
+ clk_prepare_enable(clk[spba_gate]);
+ clk_prepare_enable(clk[gpio1_gate]);
+ clk_prepare_enable(clk[gpio2_gate]);
+ clk_prepare_enable(clk[gpio3_gate]);
+ clk_prepare_enable(clk[iim_gate]);
+ clk_prepare_enable(clk[emi_gate]);
+ clk_prepare_enable(clk[max_gate]);
+ clk_prepare_enable(clk[iomuxc_gate]);
+
+ /*
+ * SCC is needed to boot via mmc after a watchdog reset. The clock code
+ * before conversion to common clk also enabled UART1 (which isn't
+ * handled here and not needed for mmc) and IIM (which is enabled
+ * unconditionally above).
+ */
+ clk_prepare_enable(clk[scc_gate]);
+
+ imx_print_silicon_rev("i.MX35", mx35_revision());
+
+#ifdef CONFIG_MXC_USE_EPIT
+ epit_timer_init(MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
+#else
+ mxc_timer_init(MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT);
+#endif
+
+ return 0;
+}
+
+static void __init mx35_clocks_init_dt(struct device_node *ccm_node)
+{
+ clk_data.clks = clk;
+ clk_data.clk_num = ARRAY_SIZE(clk);
+ of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data);
+
+ mx35_clocks_init();
+}
+CLK_OF_DECLARE(imx35, "fsl,imx35-ccm", mx35_clocks_init_dt);
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
new file mode 100644
index 000000000..0f7e53614
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -0,0 +1,573 @@
+/*
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <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/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <dt-bindings/clock/imx5-clock.h>
+
+#include "clk.h"
+#include "common.h"
+#include "hardware.h"
+
+#define MX51_DPLL1_BASE 0x83f80000
+#define MX51_DPLL2_BASE 0x83f84000
+#define MX51_DPLL3_BASE 0x83f88000
+
+#define MX53_DPLL1_BASE 0x63f80000
+#define MX53_DPLL2_BASE 0x63f84000
+#define MX53_DPLL3_BASE 0x63f88000
+#define MX53_DPLL4_BASE 0x63f8c000
+
+#define MXC_CCM_CCR (ccm_base + 0x00)
+#define MXC_CCM_CCDR (ccm_base + 0x04)
+#define MXC_CCM_CSR (ccm_base + 0x08)
+#define MXC_CCM_CCSR (ccm_base + 0x0c)
+#define MXC_CCM_CACRR (ccm_base + 0x10)
+#define MXC_CCM_CBCDR (ccm_base + 0x14)
+#define MXC_CCM_CBCMR (ccm_base + 0x18)
+#define MXC_CCM_CSCMR1 (ccm_base + 0x1c)
+#define MXC_CCM_CSCMR2 (ccm_base + 0x20)
+#define MXC_CCM_CSCDR1 (ccm_base + 0x24)
+#define MXC_CCM_CS1CDR (ccm_base + 0x28)
+#define MXC_CCM_CS2CDR (ccm_base + 0x2c)
+#define MXC_CCM_CDCDR (ccm_base + 0x30)
+#define MXC_CCM_CHSCDR (ccm_base + 0x34)
+#define MXC_CCM_CSCDR2 (ccm_base + 0x38)
+#define MXC_CCM_CSCDR3 (ccm_base + 0x3c)
+#define MXC_CCM_CSCDR4 (ccm_base + 0x40)
+#define MXC_CCM_CWDR (ccm_base + 0x44)
+#define MXC_CCM_CDHIPR (ccm_base + 0x48)
+#define MXC_CCM_CDCR (ccm_base + 0x4c)
+#define MXC_CCM_CTOR (ccm_base + 0x50)
+#define MXC_CCM_CLPCR (ccm_base + 0x54)
+#define MXC_CCM_CISR (ccm_base + 0x58)
+#define MXC_CCM_CIMR (ccm_base + 0x5c)
+#define MXC_CCM_CCOSR (ccm_base + 0x60)
+#define MXC_CCM_CGPR (ccm_base + 0x64)
+#define MXC_CCM_CCGR0 (ccm_base + 0x68)
+#define MXC_CCM_CCGR1 (ccm_base + 0x6c)
+#define MXC_CCM_CCGR2 (ccm_base + 0x70)
+#define MXC_CCM_CCGR3 (ccm_base + 0x74)
+#define MXC_CCM_CCGR4 (ccm_base + 0x78)
+#define MXC_CCM_CCGR5 (ccm_base + 0x7c)
+#define MXC_CCM_CCGR6 (ccm_base + 0x80)
+#define MXC_CCM_CCGR7 (ccm_base + 0x84)
+
+/* Low-power Audio Playback Mode clock */
+static const char *lp_apm_sel[] = { "osc", };
+
+/* This is used multiple times */
+static const char *standard_pll_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "lp_apm", };
+static const char *periph_apm_sel[] = { "pll1_sw", "pll3_sw", "lp_apm", };
+static const char *main_bus_sel[] = { "pll2_sw", "periph_apm", };
+static const char *per_lp_apm_sel[] = { "main_bus", "lp_apm", };
+static const char *per_root_sel[] = { "per_podf", "ipg", };
+static const char *esdhc_c_sel[] = { "esdhc_a_podf", "esdhc_b_podf", };
+static const char *esdhc_d_sel[] = { "esdhc_a_podf", "esdhc_b_podf", };
+static const char *ssi_apm_sels[] = { "ckih1", "lp_amp", "ckih2", };
+static const char *ssi_clk_sels[] = { "pll1_sw", "pll2_sw", "pll3_sw", "ssi_apm", };
+static const char *ssi3_clk_sels[] = { "ssi1_root_gate", "ssi2_root_gate", };
+static const char *ssi_ext1_com_sels[] = { "ssi_ext1_podf", "ssi1_root_gate", };
+static const char *ssi_ext2_com_sels[] = { "ssi_ext2_podf", "ssi2_root_gate", };
+static const char *emi_slow_sel[] = { "main_bus", "ahb", };
+static const char *usb_phy_sel_str[] = { "osc", "usb_phy_podf", };
+static const char *mx51_ipu_di0_sel[] = { "di_pred", "osc", "ckih1", "tve_di", };
+static const char *mx53_ipu_di0_sel[] = { "di_pred", "osc", "ckih1", "di_pll4_podf", "dummy", "ldb_di0_gate", };
+static const char *mx53_ldb_di0_sel[] = { "pll3_sw", "pll4_sw", };
+static const char *mx51_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "ipp_di1", };
+static const char *mx53_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "ipp_di1", "ldb_di1_gate", };
+static const char *mx53_ldb_di1_sel[] = { "pll3_sw", "pll4_sw", };
+static const char *mx51_tve_ext_sel[] = { "osc", "ckih1", };
+static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", };
+static const char *mx51_tve_sel[] = { "tve_pred", "tve_ext_sel", };
+static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
+static const char *gpu3d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" };
+static const char *gpu2d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" };
+static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
+static const char *mx53_can_sel[] = { "ipg", "ckih1", "ckih2", "lp_apm", };
+static const char *mx53_cko1_sel[] = {
+ "cpu_podf", "pll1_sw", "pll2_sw", "pll3_sw",
+ "emi_slow_podf", "pll4_sw", "nfc_podf", "dummy",
+ "di_pred", "dummy", "dummy", "ahb",
+ "ipg", "per_root", "ckil", "dummy",};
+static const char *mx53_cko2_sel[] = {
+ "dummy"/* dptc_core */, "dummy"/* dptc_perich */,
+ "dummy", "esdhc_a_podf",
+ "usboh3_podf", "dummy"/* wrck_clk_root */,
+ "ecspi_podf", "dummy"/* pll1_ref_clk */,
+ "esdhc_b_podf", "dummy"/* ddr_clk_root */,
+ "dummy"/* arm_axi_clk_root */, "dummy"/* usb_phy_out */,
+ "vpu_sel", "ipu_sel",
+ "osc", "ckih1",
+ "dummy", "esdhc_c_sel",
+ "ssi1_root_podf", "ssi2_root_podf",
+ "dummy", "dummy",
+ "dummy"/* lpsr_clk_root */, "dummy"/* pgc_clk_root */,
+ "dummy"/* tve_out */, "usb_phy_sel",
+ "tve_sel", "lp_apm",
+ "uart_root", "dummy"/* spdif0_clk_root */,
+ "dummy", "dummy", };
+static const char *mx51_spdif_xtal_sel[] = { "osc", "ckih", "ckih2", };
+static const char *mx53_spdif_xtal_sel[] = { "osc", "ckih", "ckih2", "pll4_sw", };
+static const char *spdif_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "spdif_xtal_sel", };
+static const char *spdif0_com_sel[] = { "spdif0_podf", "ssi1_root_gate", };
+static const char *mx51_spdif1_com_sel[] = { "spdif1_podf", "ssi2_root_gate", };
+static const char *step_sels[] = { "lp_apm", };
+static const char *cpu_podf_sels[] = { "pll1_sw", "step_sel" };
+
+static struct clk *clk[IMX5_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static void __init mx5_clocks_common_init(void __iomem *ccm_base)
+{
+ imx5_pm_set_ccm_base(ccm_base);
+
+ clk[IMX5_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+ clk[IMX5_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
+ clk[IMX5_CLK_OSC] = imx_obtain_fixed_clock("osc", 0);
+ clk[IMX5_CLK_CKIH1] = imx_obtain_fixed_clock("ckih1", 0);
+ clk[IMX5_CLK_CKIH2] = imx_obtain_fixed_clock("ckih2", 0);
+
+ clk[IMX5_CLK_PERIPH_APM] = imx_clk_mux("periph_apm", MXC_CCM_CBCMR, 12, 2,
+ periph_apm_sel, ARRAY_SIZE(periph_apm_sel));
+ clk[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1,
+ main_bus_sel, ARRAY_SIZE(main_bus_sel));
+ clk[IMX5_CLK_PER_LP_APM] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCMR, 1, 1,
+ per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel));
+ clk[IMX5_CLK_PER_PRED1] = imx_clk_divider("per_pred1", "per_lp_apm", MXC_CCM_CBCDR, 6, 2);
+ clk[IMX5_CLK_PER_PRED2] = imx_clk_divider("per_pred2", "per_pred1", MXC_CCM_CBCDR, 3, 3);
+ clk[IMX5_CLK_PER_PODF] = imx_clk_divider("per_podf", "per_pred2", MXC_CCM_CBCDR, 0, 3);
+ clk[IMX5_CLK_PER_ROOT] = imx_clk_mux("per_root", MXC_CCM_CBCMR, 0, 1,
+ per_root_sel, ARRAY_SIZE(per_root_sel));
+ clk[IMX5_CLK_AHB] = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3);
+ clk[IMX5_CLK_AHB_MAX] = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28);
+ clk[IMX5_CLK_AIPS_TZ1] = imx_clk_gate2("aips_tz1", "ahb", MXC_CCM_CCGR0, 24);
+ clk[IMX5_CLK_AIPS_TZ2] = imx_clk_gate2("aips_tz2", "ahb", MXC_CCM_CCGR0, 26);
+ clk[IMX5_CLK_TMAX1] = imx_clk_gate2("tmax1", "ahb", MXC_CCM_CCGR1, 0);
+ clk[IMX5_CLK_TMAX2] = imx_clk_gate2("tmax2", "ahb", MXC_CCM_CCGR1, 2);
+ clk[IMX5_CLK_TMAX3] = imx_clk_gate2("tmax3", "ahb", MXC_CCM_CCGR1, 4);
+ clk[IMX5_CLK_SPBA] = imx_clk_gate2("spba", "ipg", MXC_CCM_CCGR5, 0);
+ clk[IMX5_CLK_IPG] = imx_clk_divider("ipg", "ahb", MXC_CCM_CBCDR, 8, 2);
+ clk[IMX5_CLK_AXI_A] = imx_clk_divider("axi_a", "main_bus", MXC_CCM_CBCDR, 16, 3);
+ clk[IMX5_CLK_AXI_B] = imx_clk_divider("axi_b", "main_bus", MXC_CCM_CBCDR, 19, 3);
+ clk[IMX5_CLK_UART_SEL] = imx_clk_mux("uart_sel", MXC_CCM_CSCMR1, 24, 2,
+ standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clk[IMX5_CLK_UART_PRED] = imx_clk_divider("uart_pred", "uart_sel", MXC_CCM_CSCDR1, 3, 3);
+ clk[IMX5_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_pred", MXC_CCM_CSCDR1, 0, 3);
+
+ clk[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", MXC_CCM_CSCMR1, 20, 2,
+ standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clk[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", MXC_CCM_CSCMR1, 16, 2,
+ standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clk[IMX5_CLK_ESDHC_A_PRED] = imx_clk_divider("esdhc_a_pred", "esdhc_a_sel", MXC_CCM_CSCDR1, 16, 3);
+ clk[IMX5_CLK_ESDHC_A_PODF] = imx_clk_divider("esdhc_a_podf", "esdhc_a_pred", MXC_CCM_CSCDR1, 11, 3);
+ clk[IMX5_CLK_ESDHC_B_PRED] = imx_clk_divider("esdhc_b_pred", "esdhc_b_sel", MXC_CCM_CSCDR1, 22, 3);
+ clk[IMX5_CLK_ESDHC_B_PODF] = imx_clk_divider("esdhc_b_podf", "esdhc_b_pred", MXC_CCM_CSCDR1, 19, 3);
+ clk[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", MXC_CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
+ clk[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", MXC_CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
+
+ clk[IMX5_CLK_EMI_SEL] = imx_clk_mux("emi_sel", MXC_CCM_CBCDR, 26, 1,
+ emi_slow_sel, ARRAY_SIZE(emi_slow_sel));
+ clk[IMX5_CLK_EMI_SLOW_PODF] = imx_clk_divider("emi_slow_podf", "emi_sel", MXC_CCM_CBCDR, 22, 3);
+ clk[IMX5_CLK_NFC_PODF] = imx_clk_divider("nfc_podf", "emi_slow_podf", MXC_CCM_CBCDR, 13, 3);
+ clk[IMX5_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", MXC_CCM_CSCMR1, 4, 2,
+ standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clk[IMX5_CLK_ECSPI_PRED] = imx_clk_divider("ecspi_pred", "ecspi_sel", MXC_CCM_CSCDR2, 25, 3);
+ clk[IMX5_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_pred", MXC_CCM_CSCDR2, 19, 6);
+ clk[IMX5_CLK_USBOH3_SEL] = imx_clk_mux("usboh3_sel", MXC_CCM_CSCMR1, 22, 2,
+ standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clk[IMX5_CLK_USBOH3_PRED] = imx_clk_divider("usboh3_pred", "usboh3_sel", MXC_CCM_CSCDR1, 8, 3);
+ clk[IMX5_CLK_USBOH3_PODF] = imx_clk_divider("usboh3_podf", "usboh3_pred", MXC_CCM_CSCDR1, 6, 2);
+ clk[IMX5_CLK_USB_PHY_PRED] = imx_clk_divider("usb_phy_pred", "pll3_sw", MXC_CCM_CDCDR, 3, 3);
+ clk[IMX5_CLK_USB_PHY_PODF] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3);
+ clk[IMX5_CLK_USB_PHY_SEL] = imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1,
+ usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str));
+ clk[IMX5_CLK_STEP_SEL] = imx_clk_mux("step_sel", MXC_CCM_CCSR, 7, 2, step_sels, ARRAY_SIZE(step_sels));
+ clk[IMX5_CLK_CPU_PODF_SEL] = imx_clk_mux("cpu_podf_sel", MXC_CCM_CCSR, 2, 1, cpu_podf_sels, ARRAY_SIZE(cpu_podf_sels));
+ clk[IMX5_CLK_CPU_PODF] = imx_clk_divider("cpu_podf", "cpu_podf_sel", MXC_CCM_CACRR, 0, 3);
+ clk[IMX5_CLK_DI_PRED] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3);
+ clk[IMX5_CLK_IIM_GATE] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30);
+ clk[IMX5_CLK_UART1_IPG_GATE] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6);
+ clk[IMX5_CLK_UART1_PER_GATE] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8);
+ clk[IMX5_CLK_UART2_IPG_GATE] = imx_clk_gate2("uart2_ipg_gate", "ipg", MXC_CCM_CCGR1, 10);
+ clk[IMX5_CLK_UART2_PER_GATE] = imx_clk_gate2("uart2_per_gate", "uart_root", MXC_CCM_CCGR1, 12);
+ clk[IMX5_CLK_UART3_IPG_GATE] = imx_clk_gate2("uart3_ipg_gate", "ipg", MXC_CCM_CCGR1, 14);
+ clk[IMX5_CLK_UART3_PER_GATE] = imx_clk_gate2("uart3_per_gate", "uart_root", MXC_CCM_CCGR1, 16);
+ clk[IMX5_CLK_I2C1_GATE] = imx_clk_gate2("i2c1_gate", "per_root", MXC_CCM_CCGR1, 18);
+ clk[IMX5_CLK_I2C2_GATE] = imx_clk_gate2("i2c2_gate", "per_root", MXC_CCM_CCGR1, 20);
+ clk[IMX5_CLK_PWM1_IPG_GATE] = imx_clk_gate2("pwm1_ipg_gate", "ipg", MXC_CCM_CCGR2, 10);
+ clk[IMX5_CLK_PWM1_HF_GATE] = imx_clk_gate2("pwm1_hf_gate", "per_root", MXC_CCM_CCGR2, 12);
+ clk[IMX5_CLK_PWM2_IPG_GATE] = imx_clk_gate2("pwm2_ipg_gate", "ipg", MXC_CCM_CCGR2, 14);
+ clk[IMX5_CLK_PWM2_HF_GATE] = imx_clk_gate2("pwm2_hf_gate", "per_root", MXC_CCM_CCGR2, 16);
+ clk[IMX5_CLK_GPT_IPG_GATE] = imx_clk_gate2("gpt_ipg_gate", "ipg", MXC_CCM_CCGR2, 18);
+ clk[IMX5_CLK_GPT_HF_GATE] = imx_clk_gate2("gpt_hf_gate", "per_root", MXC_CCM_CCGR2, 20);
+ clk[IMX5_CLK_FEC_GATE] = imx_clk_gate2("fec_gate", "ipg", MXC_CCM_CCGR2, 24);
+ clk[IMX5_CLK_USBOH3_GATE] = imx_clk_gate2("usboh3_gate", "ipg", MXC_CCM_CCGR2, 26);
+ clk[IMX5_CLK_USBOH3_PER_GATE] = imx_clk_gate2("usboh3_per_gate", "usboh3_podf", MXC_CCM_CCGR2, 28);
+ clk[IMX5_CLK_ESDHC1_IPG_GATE] = imx_clk_gate2("esdhc1_ipg_gate", "ipg", MXC_CCM_CCGR3, 0);
+ clk[IMX5_CLK_ESDHC2_IPG_GATE] = imx_clk_gate2("esdhc2_ipg_gate", "ipg", MXC_CCM_CCGR3, 4);
+ clk[IMX5_CLK_ESDHC3_IPG_GATE] = imx_clk_gate2("esdhc3_ipg_gate", "ipg", MXC_CCM_CCGR3, 8);
+ clk[IMX5_CLK_ESDHC4_IPG_GATE] = imx_clk_gate2("esdhc4_ipg_gate", "ipg", MXC_CCM_CCGR3, 12);
+ clk[IMX5_CLK_SSI1_IPG_GATE] = imx_clk_gate2("ssi1_ipg_gate", "ipg", MXC_CCM_CCGR3, 16);
+ clk[IMX5_CLK_SSI2_IPG_GATE] = imx_clk_gate2("ssi2_ipg_gate", "ipg", MXC_CCM_CCGR3, 20);
+ clk[IMX5_CLK_SSI3_IPG_GATE] = imx_clk_gate2("ssi3_ipg_gate", "ipg", MXC_CCM_CCGR3, 24);
+ clk[IMX5_CLK_ECSPI1_IPG_GATE] = imx_clk_gate2("ecspi1_ipg_gate", "ipg", MXC_CCM_CCGR4, 18);
+ clk[IMX5_CLK_ECSPI1_PER_GATE] = imx_clk_gate2("ecspi1_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 20);
+ clk[IMX5_CLK_ECSPI2_IPG_GATE] = imx_clk_gate2("ecspi2_ipg_gate", "ipg", MXC_CCM_CCGR4, 22);
+ clk[IMX5_CLK_ECSPI2_PER_GATE] = imx_clk_gate2("ecspi2_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 24);
+ clk[IMX5_CLK_CSPI_IPG_GATE] = imx_clk_gate2("cspi_ipg_gate", "ipg", MXC_CCM_CCGR4, 26);
+ clk[IMX5_CLK_SDMA_GATE] = imx_clk_gate2("sdma_gate", "ipg", MXC_CCM_CCGR4, 30);
+ clk[IMX5_CLK_EMI_FAST_GATE] = imx_clk_gate2("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14);
+ clk[IMX5_CLK_EMI_SLOW_GATE] = imx_clk_gate2("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16);
+ clk[IMX5_CLK_IPU_SEL] = imx_clk_mux("ipu_sel", MXC_CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel));
+ clk[IMX5_CLK_IPU_GATE] = imx_clk_gate2("ipu_gate", "ipu_sel", MXC_CCM_CCGR5, 10);
+ clk[IMX5_CLK_NFC_GATE] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20);
+ clk[IMX5_CLK_IPU_DI0_GATE] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10);
+ clk[IMX5_CLK_IPU_DI1_GATE] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12);
+ clk[IMX5_CLK_GPU3D_SEL] = imx_clk_mux("gpu3d_sel", MXC_CCM_CBCMR, 4, 2, gpu3d_sel, ARRAY_SIZE(gpu3d_sel));
+ clk[IMX5_CLK_GPU2D_SEL] = imx_clk_mux("gpu2d_sel", MXC_CCM_CBCMR, 16, 2, gpu2d_sel, ARRAY_SIZE(gpu2d_sel));
+ clk[IMX5_CLK_GPU3D_GATE] = imx_clk_gate2("gpu3d_gate", "gpu3d_sel", MXC_CCM_CCGR5, 2);
+ clk[IMX5_CLK_GARB_GATE] = imx_clk_gate2("garb_gate", "axi_a", MXC_CCM_CCGR5, 4);
+ clk[IMX5_CLK_GPU2D_GATE] = imx_clk_gate2("gpu2d_gate", "gpu2d_sel", MXC_CCM_CCGR6, 14);
+ clk[IMX5_CLK_VPU_SEL] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel));
+ clk[IMX5_CLK_VPU_GATE] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6);
+ clk[IMX5_CLK_VPU_REFERENCE_GATE] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8);
+ clk[IMX5_CLK_UART4_IPG_GATE] = imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8);
+ clk[IMX5_CLK_UART4_PER_GATE] = imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10);
+ clk[IMX5_CLK_UART5_IPG_GATE] = imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12);
+ clk[IMX5_CLK_UART5_PER_GATE] = imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14);
+ clk[IMX5_CLK_GPC_DVFS] = imx_clk_gate2("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24);
+
+ clk[IMX5_CLK_SSI_APM] = imx_clk_mux("ssi_apm", MXC_CCM_CSCMR1, 8, 2, ssi_apm_sels, ARRAY_SIZE(ssi_apm_sels));
+ clk[IMX5_CLK_SSI1_ROOT_SEL] = imx_clk_mux("ssi1_root_sel", MXC_CCM_CSCMR1, 14, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
+ clk[IMX5_CLK_SSI2_ROOT_SEL] = imx_clk_mux("ssi2_root_sel", MXC_CCM_CSCMR1, 12, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
+ clk[IMX5_CLK_SSI3_ROOT_SEL] = imx_clk_mux("ssi3_root_sel", MXC_CCM_CSCMR1, 11, 1, ssi3_clk_sels, ARRAY_SIZE(ssi3_clk_sels));
+ clk[IMX5_CLK_SSI_EXT1_SEL] = imx_clk_mux("ssi_ext1_sel", MXC_CCM_CSCMR1, 28, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
+ clk[IMX5_CLK_SSI_EXT2_SEL] = imx_clk_mux("ssi_ext2_sel", MXC_CCM_CSCMR1, 30, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
+ clk[IMX5_CLK_SSI_EXT1_COM_SEL] = imx_clk_mux("ssi_ext1_com_sel", MXC_CCM_CSCMR1, 0, 1, ssi_ext1_com_sels, ARRAY_SIZE(ssi_ext1_com_sels));
+ clk[IMX5_CLK_SSI_EXT2_COM_SEL] = imx_clk_mux("ssi_ext2_com_sel", MXC_CCM_CSCMR1, 1, 1, ssi_ext2_com_sels, ARRAY_SIZE(ssi_ext2_com_sels));
+ clk[IMX5_CLK_SSI1_ROOT_PRED] = imx_clk_divider("ssi1_root_pred", "ssi1_root_sel", MXC_CCM_CS1CDR, 6, 3);
+ clk[IMX5_CLK_SSI1_ROOT_PODF] = imx_clk_divider("ssi1_root_podf", "ssi1_root_pred", MXC_CCM_CS1CDR, 0, 6);
+ clk[IMX5_CLK_SSI2_ROOT_PRED] = imx_clk_divider("ssi2_root_pred", "ssi2_root_sel", MXC_CCM_CS2CDR, 6, 3);
+ clk[IMX5_CLK_SSI2_ROOT_PODF] = imx_clk_divider("ssi2_root_podf", "ssi2_root_pred", MXC_CCM_CS2CDR, 0, 6);
+ clk[IMX5_CLK_SSI_EXT1_PRED] = imx_clk_divider("ssi_ext1_pred", "ssi_ext1_sel", MXC_CCM_CS1CDR, 22, 3);
+ clk[IMX5_CLK_SSI_EXT1_PODF] = imx_clk_divider("ssi_ext1_podf", "ssi_ext1_pred", MXC_CCM_CS1CDR, 16, 6);
+ clk[IMX5_CLK_SSI_EXT2_PRED] = imx_clk_divider("ssi_ext2_pred", "ssi_ext2_sel", MXC_CCM_CS2CDR, 22, 3);
+ clk[IMX5_CLK_SSI_EXT2_PODF] = imx_clk_divider("ssi_ext2_podf", "ssi_ext2_pred", MXC_CCM_CS2CDR, 16, 6);
+ clk[IMX5_CLK_SSI1_ROOT_GATE] = imx_clk_gate2("ssi1_root_gate", "ssi1_root_podf", MXC_CCM_CCGR3, 18);
+ clk[IMX5_CLK_SSI2_ROOT_GATE] = imx_clk_gate2("ssi2_root_gate", "ssi2_root_podf", MXC_CCM_CCGR3, 22);
+ clk[IMX5_CLK_SSI3_ROOT_GATE] = imx_clk_gate2("ssi3_root_gate", "ssi3_root_sel", MXC_CCM_CCGR3, 26);
+ clk[IMX5_CLK_SSI_EXT1_GATE] = imx_clk_gate2("ssi_ext1_gate", "ssi_ext1_com_sel", MXC_CCM_CCGR3, 28);
+ clk[IMX5_CLK_SSI_EXT2_GATE] = imx_clk_gate2("ssi_ext2_gate", "ssi_ext2_com_sel", MXC_CCM_CCGR3, 30);
+ clk[IMX5_CLK_EPIT1_IPG_GATE] = imx_clk_gate2("epit1_ipg_gate", "ipg", MXC_CCM_CCGR2, 2);
+ clk[IMX5_CLK_EPIT1_HF_GATE] = imx_clk_gate2("epit1_hf_gate", "per_root", MXC_CCM_CCGR2, 4);
+ clk[IMX5_CLK_EPIT2_IPG_GATE] = imx_clk_gate2("epit2_ipg_gate", "ipg", MXC_CCM_CCGR2, 6);
+ clk[IMX5_CLK_EPIT2_HF_GATE] = imx_clk_gate2("epit2_hf_gate", "per_root", MXC_CCM_CCGR2, 8);
+ clk[IMX5_CLK_OWIRE_GATE] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22);
+ clk[IMX5_CLK_SRTC_GATE] = imx_clk_gate2("srtc_gate", "per_root", MXC_CCM_CCGR4, 28);
+ clk[IMX5_CLK_PATA_GATE] = imx_clk_gate2("pata_gate", "ipg", MXC_CCM_CCGR4, 0);
+ clk[IMX5_CLK_SPDIF0_SEL] = imx_clk_mux("spdif0_sel", MXC_CCM_CSCMR2, 0, 2, spdif_sel, ARRAY_SIZE(spdif_sel));
+ clk[IMX5_CLK_SPDIF0_PRED] = imx_clk_divider("spdif0_pred", "spdif0_sel", MXC_CCM_CDCDR, 25, 3);
+ clk[IMX5_CLK_SPDIF0_PODF] = imx_clk_divider("spdif0_podf", "spdif0_pred", MXC_CCM_CDCDR, 19, 6);
+ clk[IMX5_CLK_SPDIF0_COM_SEL] = imx_clk_mux_flags("spdif0_com_sel", MXC_CCM_CSCMR2, 4, 1,
+ spdif0_com_sel, ARRAY_SIZE(spdif0_com_sel), CLK_SET_RATE_PARENT);
+ clk[IMX5_CLK_SPDIF0_GATE] = imx_clk_gate2("spdif0_gate", "spdif0_com_sel", MXC_CCM_CCGR5, 26);
+ clk[IMX5_CLK_SPDIF_IPG_GATE] = imx_clk_gate2("spdif_ipg_gate", "ipg", MXC_CCM_CCGR5, 30);
+ clk[IMX5_CLK_SAHARA_IPG_GATE] = imx_clk_gate2("sahara_ipg_gate", "ipg", MXC_CCM_CCGR4, 14);
+ clk[IMX5_CLK_SATA_REF] = imx_clk_fixed_factor("sata_ref", "usb_phy1_gate", 1, 1);
+
+ clk_register_clkdev(clk[IMX5_CLK_CPU_PODF], NULL, "cpu0");
+ clk_register_clkdev(clk[IMX5_CLK_GPC_DVFS], "gpc_dvfs", NULL);
+
+ /* Set SDHC parents to be PLL2 */
+ clk_set_parent(clk[IMX5_CLK_ESDHC_A_SEL], clk[IMX5_CLK_PLL2_SW]);
+ clk_set_parent(clk[IMX5_CLK_ESDHC_B_SEL], clk[IMX5_CLK_PLL2_SW]);
+
+ /* move usb phy clk to 24MHz */
+ clk_set_parent(clk[IMX5_CLK_USB_PHY_SEL], clk[IMX5_CLK_OSC]);
+
+ clk_prepare_enable(clk[IMX5_CLK_GPC_DVFS]);
+ clk_prepare_enable(clk[IMX5_CLK_AHB_MAX]); /* esdhc3 */
+ clk_prepare_enable(clk[IMX5_CLK_AIPS_TZ1]);
+ clk_prepare_enable(clk[IMX5_CLK_AIPS_TZ2]); /* fec */
+ clk_prepare_enable(clk[IMX5_CLK_SPBA]);
+ clk_prepare_enable(clk[IMX5_CLK_EMI_FAST_GATE]); /* fec */
+ clk_prepare_enable(clk[IMX5_CLK_EMI_SLOW_GATE]); /* eim */
+ clk_prepare_enable(clk[IMX5_CLK_MIPI_HSC1_GATE]);
+ clk_prepare_enable(clk[IMX5_CLK_MIPI_HSC2_GATE]);
+ clk_prepare_enable(clk[IMX5_CLK_MIPI_ESC_GATE]);
+ clk_prepare_enable(clk[IMX5_CLK_MIPI_HSP_GATE]);
+ clk_prepare_enable(clk[IMX5_CLK_TMAX1]);
+ clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */
+ clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */
+}
+
+static void __init mx50_clocks_init(struct device_node *np)
+{
+ void __iomem *ccm_base;
+ void __iomem *pll_base;
+ unsigned long r;
+
+ pll_base = ioremap(MX53_DPLL1_BASE, SZ_16K);
+ WARN_ON(!pll_base);
+ clk[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", pll_base);
+
+ pll_base = ioremap(MX53_DPLL2_BASE, SZ_16K);
+ WARN_ON(!pll_base);
+ clk[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", pll_base);
+
+ pll_base = ioremap(MX53_DPLL3_BASE, SZ_16K);
+ WARN_ON(!pll_base);
+ clk[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", pll_base);
+
+ ccm_base = of_iomap(np, 0);
+ WARN_ON(!ccm_base);
+
+ mx5_clocks_common_init(ccm_base);
+
+ clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 10, 1,
+ lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
+ clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
+ clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6);
+ clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10);
+ clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
+ clk[IMX5_CLK_USB_PHY1_GATE] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10);
+ clk[IMX5_CLK_USB_PHY2_GATE] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12);
+ clk[IMX5_CLK_I2C3_GATE] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
+
+ clk[IMX5_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
+ mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
+ clk[IMX5_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3);
+ clk[IMX5_CLK_CKO1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7);
+
+ clk[IMX5_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5,
+ mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel));
+ clk[IMX5_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3);
+ clk[IMX5_CLK_CKO2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24);
+
+ imx_check_clocks(clk, ARRAY_SIZE(clk));
+
+ clk_data.clks = clk;
+ clk_data.clk_num = ARRAY_SIZE(clk);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+ /* set SDHC root clock to 200MHZ*/
+ clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 200000000);
+ clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 200000000);
+
+ clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]);
+ imx_print_silicon_rev("i.MX50", IMX_CHIP_REVISION_1_1);
+ clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]);
+
+ r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000);
+ clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r);
+}
+CLK_OF_DECLARE(imx50_ccm, "fsl,imx50-ccm", mx50_clocks_init);
+
+static void __init mx51_clocks_init(struct device_node *np)
+{
+ void __iomem *ccm_base;
+ void __iomem *pll_base;
+ u32 val;
+
+ pll_base = ioremap(MX51_DPLL1_BASE, SZ_16K);
+ WARN_ON(!pll_base);
+ clk[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", pll_base);
+
+ pll_base = ioremap(MX51_DPLL2_BASE, SZ_16K);
+ WARN_ON(!pll_base);
+ clk[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", pll_base);
+
+ pll_base = ioremap(MX51_DPLL3_BASE, SZ_16K);
+ WARN_ON(!pll_base);
+ clk[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", pll_base);
+
+ ccm_base = of_iomap(np, 0);
+ WARN_ON(!ccm_base);
+
+ mx5_clocks_common_init(ccm_base);
+
+ clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1,
+ lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
+ clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
+ mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel));
+ clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
+ mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel));
+ clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
+ mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT);
+ clk[IMX5_CLK_TVE_SEL] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1,
+ mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel));
+ clk[IMX5_CLK_TVE_GATE] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30);
+ clk[IMX5_CLK_TVE_PRED] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3);
+ clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
+ clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 6);
+ clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 10);
+ clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
+ clk[IMX5_CLK_USB_PHY_GATE] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0);
+ clk[IMX5_CLK_HSI2C_GATE] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22);
+ clk[IMX5_CLK_MIPI_HSC1_GATE] = imx_clk_gate2("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6);
+ clk[IMX5_CLK_MIPI_HSC2_GATE] = imx_clk_gate2("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8);
+ clk[IMX5_CLK_MIPI_ESC_GATE] = imx_clk_gate2("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10);
+ clk[IMX5_CLK_MIPI_HSP_GATE] = imx_clk_gate2("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12);
+ clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2,
+ mx51_spdif_xtal_sel, ARRAY_SIZE(mx51_spdif_xtal_sel));
+ clk[IMX5_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", MXC_CCM_CSCMR2, 2, 2,
+ spdif_sel, ARRAY_SIZE(spdif_sel));
+ clk[IMX5_CLK_SPDIF1_PRED] = imx_clk_divider("spdif1_pred", "spdif1_sel", MXC_CCM_CDCDR, 16, 3);
+ clk[IMX5_CLK_SPDIF1_PODF] = imx_clk_divider("spdif1_podf", "spdif1_pred", MXC_CCM_CDCDR, 9, 6);
+ clk[IMX5_CLK_SPDIF1_COM_SEL] = imx_clk_mux("spdif1_com_sel", MXC_CCM_CSCMR2, 5, 1,
+ mx51_spdif1_com_sel, ARRAY_SIZE(mx51_spdif1_com_sel));
+ clk[IMX5_CLK_SPDIF1_GATE] = imx_clk_gate2("spdif1_gate", "spdif1_com_sel", MXC_CCM_CCGR5, 28);
+
+ imx_check_clocks(clk, ARRAY_SIZE(clk));
+
+ clk_data.clks = clk;
+ clk_data.clk_num = ARRAY_SIZE(clk);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+ /* set the usboh3 parent to pll2_sw */
+ clk_set_parent(clk[IMX5_CLK_USBOH3_SEL], clk[IMX5_CLK_PLL2_SW]);
+
+ /* set SDHC root clock to 166.25MHZ*/
+ clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 166250000);
+ clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 166250000);
+
+ clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]);
+ imx_print_silicon_rev("i.MX51", mx51_revision());
+ clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]);
+
+ /*
+ * Reference Manual says: Functionality of CCDR[18] and CLPCR[23] is no
+ * longer supported. Set to one for better power saving.
+ *
+ * The effect of not setting these bits is that MIPI clocks can't be
+ * enabled without the IPU clock being enabled aswell.
+ */
+ val = readl(MXC_CCM_CCDR);
+ val |= 1 << 18;
+ writel(val, MXC_CCM_CCDR);
+
+ val = readl(MXC_CCM_CLPCR);
+ val |= 1 << 23;
+ writel(val, MXC_CCM_CLPCR);
+}
+CLK_OF_DECLARE(imx51_ccm, "fsl,imx51-ccm", mx51_clocks_init);
+
+static void __init mx53_clocks_init(struct device_node *np)
+{
+ void __iomem *ccm_base;
+ void __iomem *pll_base;
+ unsigned long r;
+
+ pll_base = ioremap(MX53_DPLL1_BASE, SZ_16K);
+ WARN_ON(!pll_base);
+ clk[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", pll_base);
+
+ pll_base = ioremap(MX53_DPLL2_BASE, SZ_16K);
+ WARN_ON(!pll_base);
+ clk[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", pll_base);
+
+ pll_base = ioremap(MX53_DPLL3_BASE, SZ_16K);
+ WARN_ON(!pll_base);
+ clk[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", pll_base);
+
+ pll_base = ioremap(MX53_DPLL4_BASE, SZ_16K);
+ WARN_ON(!pll_base);
+ clk[IMX5_CLK_PLL4_SW] = imx_clk_pllv2("pll4_sw", "osc", pll_base);
+
+ ccm_base = of_iomap(np, 0);
+ WARN_ON(!ccm_base);
+
+ mx5_clocks_common_init(ccm_base);
+
+ clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 10, 1,
+ lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
+ clk[IMX5_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+ clk[IMX5_CLK_LDB_DI1_DIV] = imx_clk_divider_flags("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1, 0);
+ clk[IMX5_CLK_LDB_DI1_SEL] = imx_clk_mux_flags("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1,
+ mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel), CLK_SET_RATE_PARENT);
+ clk[IMX5_CLK_DI_PLL4_PODF] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3);
+ clk[IMX5_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+ clk[IMX5_CLK_LDB_DI0_DIV] = imx_clk_divider_flags("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1, 0);
+ clk[IMX5_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1,
+ mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT);
+ clk[IMX5_CLK_LDB_DI0_GATE] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28);
+ clk[IMX5_CLK_LDB_DI1_GATE] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30);
+ clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
+ mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel));
+ clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
+ mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel));
+ clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
+ mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT);
+ clk[IMX5_CLK_TVE_GATE] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30);
+ clk[IMX5_CLK_TVE_PRED] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3);
+ clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
+ clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6);
+ clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10);
+ clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
+ clk[IMX5_CLK_USB_PHY1_GATE] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10);
+ clk[IMX5_CLK_USB_PHY2_GATE] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12);
+ clk[IMX5_CLK_CAN_SEL] = imx_clk_mux("can_sel", MXC_CCM_CSCMR2, 6, 2,
+ mx53_can_sel, ARRAY_SIZE(mx53_can_sel));
+ clk[IMX5_CLK_CAN1_SERIAL_GATE] = imx_clk_gate2("can1_serial_gate", "can_sel", MXC_CCM_CCGR6, 22);
+ clk[IMX5_CLK_CAN1_IPG_GATE] = imx_clk_gate2("can1_ipg_gate", "ipg", MXC_CCM_CCGR6, 20);
+ clk[IMX5_CLK_OCRAM] = imx_clk_gate2("ocram", "ahb", MXC_CCM_CCGR6, 2);
+ clk[IMX5_CLK_CAN2_SERIAL_GATE] = imx_clk_gate2("can2_serial_gate", "can_sel", MXC_CCM_CCGR4, 8);
+ clk[IMX5_CLK_CAN2_IPG_GATE] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6);
+ clk[IMX5_CLK_I2C3_GATE] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
+ clk[IMX5_CLK_SATA_GATE] = imx_clk_gate2("sata_gate", "ipg", MXC_CCM_CCGR4, 2);
+
+ clk[IMX5_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
+ mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
+ clk[IMX5_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3);
+ clk[IMX5_CLK_CKO1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7);
+
+ clk[IMX5_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5,
+ mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel));
+ clk[IMX5_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3);
+ clk[IMX5_CLK_CKO2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24);
+ clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2,
+ mx53_spdif_xtal_sel, ARRAY_SIZE(mx53_spdif_xtal_sel));
+ clk[IMX5_CLK_ARM] = imx_clk_cpu("arm", "cpu_podf",
+ clk[IMX5_CLK_CPU_PODF],
+ clk[IMX5_CLK_CPU_PODF_SEL],
+ clk[IMX5_CLK_PLL1_SW],
+ clk[IMX5_CLK_STEP_SEL]);
+
+ imx_check_clocks(clk, ARRAY_SIZE(clk));
+
+ clk_data.clks = clk;
+ clk_data.clk_num = ARRAY_SIZE(clk);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+ /* set SDHC root clock to 200MHZ*/
+ clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 200000000);
+ clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 200000000);
+
+ /* move can bus clk to 24MHz */
+ clk_set_parent(clk[IMX5_CLK_CAN_SEL], clk[IMX5_CLK_LP_APM]);
+
+ /* make sure step clock is running from 24MHz */
+ clk_set_parent(clk[IMX5_CLK_STEP_SEL], clk[IMX5_CLK_LP_APM]);
+
+ clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]);
+ imx_print_silicon_rev("i.MX53", mx53_revision());
+ clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]);
+
+ r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000);
+ clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r);
+}
+CLK_OF_DECLARE(imx53_ccm, "fsl,imx53-ccm", mx53_clocks_init);
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
new file mode 100644
index 000000000..a2e8ef3c0
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -0,0 +1,534 @@
+/*
+ * Copyright 2011-2013 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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/types.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <dt-bindings/clock/imx6qdl-clock.h>
+
+#include "clk.h"
+#include "common.h"
+#include "hardware.h"
+
+static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
+static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
+static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
+static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", "dummy", };
+static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
+static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
+static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
+static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", };
+static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
+static const char *gpu_axi_sels[] = { "axi", "ahb", };
+static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", };
+static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
+static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll3_pfd0_720m", };
+static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
+static const char *ldb_di_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", };
+static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
+static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
+static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
+static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
+static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
+static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", };
+static const char *pcie_axi_sels[] = { "axi", "ahb", };
+static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio_div", };
+static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", };
+static const char *eim_sels[] = { "pll2_pfd2_396m", "pll3_usb_otg", "axi", "pll2_pfd0_352m", };
+static const char *eim_slow_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *vdo_axi_sels[] = { "axi", "ahb", };
+static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
+ "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0",
+ "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio_div", };
+static const char *cko2_sels[] = {
+ "mmdc_ch0_axi", "mmdc_ch1_axi", "usdhc4", "usdhc1",
+ "gpu2d_axi", "dummy", "ecspi_root", "gpu3d_axi",
+ "usdhc3", "dummy", "arm", "ipu1",
+ "ipu2", "vdo_axi", "osc", "gpu2d_core",
+ "gpu3d_core", "usdhc2", "ssi1", "ssi2",
+ "ssi3", "gpu3d_shader", "vpu_axi", "can_root",
+ "ldb_di0", "ldb_di1", "esai_extal", "eim_slow",
+ "uart_serial", "spdif", "asrc", "hsi_tx",
+};
+static const char *cko_sels[] = { "cko1", "cko2", };
+static const char *lvds_sels[] = {
+ "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
+ "pll4_audio", "pll5_video", "pll8_mlb", "enet_ref",
+ "pcie_ref_125m", "sata_ref_100m",
+};
+static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", "lvds2_in", "dummy", };
+static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
+static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
+static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
+static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
+static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
+static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
+static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
+
+static struct clk *clk[IMX6QDL_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static unsigned int const clks_init_on[] __initconst = {
+ IMX6QDL_CLK_MMDC_CH0_AXI,
+ IMX6QDL_CLK_ROM,
+ IMX6QDL_CLK_ARM,
+};
+
+static struct clk_div_table clk_enet_ref_table[] = {
+ { .val = 0, .div = 20, },
+ { .val = 1, .div = 10, },
+ { .val = 2, .div = 5, },
+ { .val = 3, .div = 4, },
+ { /* sentinel */ }
+};
+
+static struct clk_div_table post_div_table[] = {
+ { .val = 2, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 0, .div = 4, },
+ { /* sentinel */ }
+};
+
+static struct clk_div_table video_div_table[] = {
+ { .val = 0, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 2, .div = 1, },
+ { .val = 3, .div = 4, },
+ { /* sentinel */ }
+};
+
+static unsigned int share_count_esai;
+static unsigned int share_count_asrc;
+static unsigned int share_count_ssi1;
+static unsigned int share_count_ssi2;
+static unsigned int share_count_ssi3;
+static unsigned int share_count_mipi_core_cfg;
+
+static void __init imx6q_clocks_init(struct device_node *ccm_node)
+{
+ struct device_node *np;
+ void __iomem *base;
+ int i;
+ int ret;
+
+ clk[IMX6QDL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+ clk[IMX6QDL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
+ clk[IMX6QDL_CLK_CKIH] = imx_obtain_fixed_clock("ckih1", 0);
+ clk[IMX6QDL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0);
+ /* Clock source from external clock via CLK1/2 PADs */
+ clk[IMX6QDL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0);
+ clk[IMX6QDL_CLK_ANACLK2] = imx_obtain_fixed_clock("anaclk2", 0);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */
+ if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) {
+ post_div_table[1].div = 1;
+ post_div_table[2].div = 1;
+ video_div_table[1].div = 1;
+ video_div_table[3].div = 1;
+ }
+
+ clk[IMX6QDL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[IMX6QDL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[IMX6QDL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[IMX6QDL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[IMX6QDL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[IMX6QDL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[IMX6QDL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+
+ /* type name parent_name base div_mask */
+ clk[IMX6QDL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
+ clk[IMX6QDL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
+ clk[IMX6QDL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3);
+ clk[IMX6QDL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
+ clk[IMX6QDL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
+ clk[IMX6QDL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
+ clk[IMX6QDL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3);
+
+ clk[IMX6QDL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
+
+ /* Do not bypass PLLs initially */
+ clk_set_parent(clk[IMX6QDL_PLL1_BYPASS], clk[IMX6QDL_CLK_PLL1]);
+ clk_set_parent(clk[IMX6QDL_PLL2_BYPASS], clk[IMX6QDL_CLK_PLL2]);
+ clk_set_parent(clk[IMX6QDL_PLL3_BYPASS], clk[IMX6QDL_CLK_PLL3]);
+ clk_set_parent(clk[IMX6QDL_PLL4_BYPASS], clk[IMX6QDL_CLK_PLL4]);
+ clk_set_parent(clk[IMX6QDL_PLL5_BYPASS], clk[IMX6QDL_CLK_PLL5]);
+ clk_set_parent(clk[IMX6QDL_PLL6_BYPASS], clk[IMX6QDL_CLK_PLL6]);
+ clk_set_parent(clk[IMX6QDL_PLL7_BYPASS], clk[IMX6QDL_CLK_PLL7]);
+
+ clk[IMX6QDL_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13);
+ clk[IMX6QDL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
+ clk[IMX6QDL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
+ clk[IMX6QDL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
+ clk[IMX6QDL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
+ clk[IMX6QDL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
+ clk[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
+
+ /*
+ * Bit 20 is the reserved and read-only bit, we do this only for:
+ * - Do nothing for usbphy clk_enable/disable
+ * - Keep refcount when do usbphy clk_enable/disable, in that case,
+ * the clk framework may need to enable/disable usbphy's parent
+ */
+ clk[IMX6QDL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20);
+ clk[IMX6QDL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20);
+
+ /*
+ * usbphy*_gate needs to be on after system boots up, and software
+ * never needs to control it anymore.
+ */
+ clk[IMX6QDL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
+ clk[IMX6QDL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
+
+ clk[IMX6QDL_CLK_SATA_REF] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5);
+ clk[IMX6QDL_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4);
+
+ clk[IMX6QDL_CLK_SATA_REF_100M] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20);
+ clk[IMX6QDL_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
+
+ clk[IMX6QDL_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0,
+ base + 0xe0, 0, 2, 0, clk_enet_ref_table,
+ &imx_ccm_lock);
+
+ clk[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
+ clk[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
+
+ /*
+ * lvds1_gate and lvds2_gate are pseudo-gates. Both can be
+ * independently configured as clock inputs or outputs. We treat
+ * the "output_enable" bit as a gate, even though it's really just
+ * enabling clock output.
+ */
+ clk[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate_exclusive("lvds1_gate", "lvds1_sel", base + 0x160, 10, BIT(12));
+ clk[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate_exclusive("lvds2_gate", "lvds2_sel", base + 0x160, 11, BIT(13));
+
+ clk[IMX6QDL_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10));
+ clk[IMX6QDL_CLK_LVDS2_IN] = imx_clk_gate_exclusive("lvds2_in", "anaclk2", base + 0x160, 13, BIT(11));
+
+ /* name parent_name reg idx */
+ clk[IMX6QDL_CLK_PLL2_PFD0_352M] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
+ clk[IMX6QDL_CLK_PLL2_PFD1_594M] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
+ clk[IMX6QDL_CLK_PLL2_PFD2_396M] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2);
+ clk[IMX6QDL_CLK_PLL3_PFD0_720M] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0);
+ clk[IMX6QDL_CLK_PLL3_PFD1_540M] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1);
+ clk[IMX6QDL_CLK_PLL3_PFD2_508M] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2);
+ clk[IMX6QDL_CLK_PLL3_PFD3_454M] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3);
+
+ /* name parent_name mult div */
+ clk[IMX6QDL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
+ clk[IMX6QDL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
+ clk[IMX6QDL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
+ clk[IMX6QDL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
+ clk[IMX6QDL_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2);
+ clk[IMX6QDL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
+ clk[IMX6QDL_CLK_VIDEO_27M] = imx_clk_fixed_factor("video_27m", "pll3_pfd1_540m", 1, 20);
+ if (cpu_is_imx6dl()) {
+ clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_fixed_factor("gpu2d_axi", "mmdc_ch0_axi_podf", 1, 1);
+ clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_fixed_factor("gpu3d_axi", "mmdc_ch0_axi_podf", 1, 1);
+ }
+
+ clk[IMX6QDL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
+ clk[IMX6QDL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock);
+ clk[IMX6QDL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
+ clk[IMX6QDL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
+
+ np = ccm_node;
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ imx6q_pm_set_ccm_base(base);
+
+ /* name reg shift width parent_names num_parents */
+ clk[IMX6QDL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
+ clk[IMX6QDL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
+ clk[IMX6QDL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
+ clk[IMX6QDL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
+ clk[IMX6QDL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
+ clk[IMX6QDL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
+ clk[IMX6QDL_CLK_AXI_SEL] = imx_clk_mux("axi_sel", base + 0x14, 6, 2, axi_sels, ARRAY_SIZE(axi_sels));
+ clk[IMX6QDL_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
+ clk[IMX6QDL_CLK_ASRC_SEL] = imx_clk_mux("asrc_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
+ clk[IMX6QDL_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
+ if (cpu_is_imx6q()) {
+ clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_mux("gpu2d_axi", base + 0x18, 0, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels));
+ clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_mux("gpu3d_axi", base + 0x18, 1, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels));
+ }
+ clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels));
+ clk[IMX6QDL_CLK_GPU3D_CORE_SEL] = imx_clk_mux("gpu3d_core_sel", base + 0x18, 4, 2, gpu3d_core_sels, ARRAY_SIZE(gpu3d_core_sels));
+ clk[IMX6QDL_CLK_GPU3D_SHADER_SEL] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels));
+ clk[IMX6QDL_CLK_IPU1_SEL] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
+ clk[IMX6QDL_CLK_IPU2_SEL] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
+ clk[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_CLK_LDB_DI1_SEL] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_CLK_IPU1_DI0_PRE_SEL] = imx_clk_mux_flags("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_mux_flags("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_mux_flags("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_CLK_IPU2_DI1_PRE_SEL] = imx_clk_mux_flags("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels), CLK_SET_RATE_PARENT);
+ clk[IMX6QDL_CLK_HSI_TX_SEL] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels));
+ clk[IMX6QDL_CLK_PCIE_AXI_SEL] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels));
+ clk[IMX6QDL_CLK_SSI1_SEL] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
+ clk[IMX6QDL_CLK_SSI2_SEL] = imx_clk_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
+ clk[IMX6QDL_CLK_SSI3_SEL] = imx_clk_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
+ clk[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
+ clk[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
+ clk[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
+ clk[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
+ clk[IMX6QDL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 16, 2, enfc_sels, ARRAY_SIZE(enfc_sels));
+ clk[IMX6QDL_CLK_EIM_SEL] = imx_clk_fixup_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels), imx_cscmr1_fixup);
+ clk[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_fixup_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels), imx_cscmr1_fixup);
+ clk[IMX6QDL_CLK_VDO_AXI_SEL] = imx_clk_mux("vdo_axi_sel", base + 0x18, 11, 1, vdo_axi_sels, ARRAY_SIZE(vdo_axi_sels));
+ clk[IMX6QDL_CLK_VPU_AXI_SEL] = imx_clk_mux("vpu_axi_sel", base + 0x18, 14, 2, vpu_axi_sels, ARRAY_SIZE(vpu_axi_sels));
+ clk[IMX6QDL_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels));
+ clk[IMX6QDL_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels));
+ clk[IMX6QDL_CLK_CKO] = imx_clk_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels));
+
+ /* name reg shift width busy: reg, shift parent_names num_parents */
+ clk[IMX6QDL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
+ clk[IMX6QDL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
+
+ /* name parent_name reg shift width */
+ clk[IMX6QDL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
+ clk[IMX6QDL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
+ clk[IMX6QDL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
+ clk[IMX6QDL_CLK_IPG_PER] = imx_clk_fixup_divider("ipg_per", "ipg", base + 0x1c, 0, 6, imx_cscmr1_fixup);
+ clk[IMX6QDL_CLK_ESAI_PRED] = imx_clk_divider("esai_pred", "esai_sel", base + 0x28, 9, 3);
+ clk[IMX6QDL_CLK_ESAI_PODF] = imx_clk_divider("esai_podf", "esai_pred", base + 0x28, 25, 3);
+ clk[IMX6QDL_CLK_ASRC_PRED] = imx_clk_divider("asrc_pred", "asrc_sel", base + 0x30, 12, 3);
+ clk[IMX6QDL_CLK_ASRC_PODF] = imx_clk_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3);
+ clk[IMX6QDL_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3);
+ clk[IMX6QDL_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3);
+ clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60m", base + 0x20, 2, 6);
+ clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6);
+ clk[IMX6QDL_CLK_GPU2D_CORE_PODF] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3);
+ clk[IMX6QDL_CLK_GPU3D_CORE_PODF] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3);
+ clk[IMX6QDL_CLK_GPU3D_SHADER] = imx_clk_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3);
+ clk[IMX6QDL_CLK_IPU1_PODF] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3);
+ clk[IMX6QDL_CLK_IPU2_PODF] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3);
+ clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+ clk[IMX6QDL_CLK_LDB_DI0_PODF] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0);
+ clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+ clk[IMX6QDL_CLK_LDB_DI1_PODF] = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0);
+ clk[IMX6QDL_CLK_IPU1_DI0_PRE] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3);
+ clk[IMX6QDL_CLK_IPU1_DI1_PRE] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3);
+ clk[IMX6QDL_CLK_IPU2_DI0_PRE] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3);
+ clk[IMX6QDL_CLK_IPU2_DI1_PRE] = imx_clk_divider("ipu2_di1_pre", "ipu2_di1_pre_sel", base + 0x38, 12, 3);
+ clk[IMX6QDL_CLK_HSI_TX_PODF] = imx_clk_divider("hsi_tx_podf", "hsi_tx_sel", base + 0x30, 29, 3);
+ clk[IMX6QDL_CLK_SSI1_PRED] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3);
+ clk[IMX6QDL_CLK_SSI1_PODF] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6);
+ clk[IMX6QDL_CLK_SSI2_PRED] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3);
+ clk[IMX6QDL_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6);
+ clk[IMX6QDL_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3);
+ clk[IMX6QDL_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6);
+ clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6);
+ clk[IMX6QDL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
+ clk[IMX6QDL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
+ clk[IMX6QDL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
+ clk[IMX6QDL_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3);
+ clk[IMX6QDL_CLK_ENFC_PRED] = imx_clk_divider("enfc_pred", "enfc_sel", base + 0x2c, 18, 3);
+ clk[IMX6QDL_CLK_ENFC_PODF] = imx_clk_divider("enfc_podf", "enfc_pred", base + 0x2c, 21, 6);
+ clk[IMX6QDL_CLK_EIM_PODF] = imx_clk_fixup_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3, imx_cscmr1_fixup);
+ clk[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_fixup_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3, imx_cscmr1_fixup);
+ clk[IMX6QDL_CLK_VPU_AXI_PODF] = imx_clk_divider("vpu_axi_podf", "vpu_axi_sel", base + 0x24, 25, 3);
+ clk[IMX6QDL_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3);
+ clk[IMX6QDL_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3);
+
+ /* name parent_name reg shift width busy: reg, shift */
+ clk[IMX6QDL_CLK_AXI] = imx_clk_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0);
+ clk[IMX6QDL_CLK_MMDC_CH0_AXI_PODF] = imx_clk_busy_divider("mmdc_ch0_axi_podf", "periph", base + 0x14, 19, 3, base + 0x48, 4);
+ clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
+ clk[IMX6QDL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
+ clk[IMX6QDL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
+
+ /* name parent_name reg shift */
+ clk[IMX6QDL_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4);
+ clk[IMX6QDL_CLK_ASRC] = imx_clk_gate2_shared("asrc", "asrc_podf", base + 0x68, 6, &share_count_asrc);
+ clk[IMX6QDL_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc);
+ clk[IMX6QDL_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc);
+ clk[IMX6QDL_CLK_CAN1_IPG] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14);
+ clk[IMX6QDL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_root", base + 0x68, 16);
+ clk[IMX6QDL_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18);
+ clk[IMX6QDL_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_root", base + 0x68, 20);
+ clk[IMX6QDL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0);
+ clk[IMX6QDL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2);
+ clk[IMX6QDL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4);
+ clk[IMX6QDL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6);
+ if (cpu_is_imx6dl())
+ clk[IMX6DL_CLK_I2C4] = imx_clk_gate2("i2c4", "ipg_per", base + 0x6c, 8);
+ else
+ clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8);
+ clk[IMX6QDL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10);
+ clk[IMX6QDL_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai);
+ clk[IMX6QDL_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai);
+ clk[IMX6QDL_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai);
+ clk[IMX6QDL_CLK_GPT_IPG] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20);
+ clk[IMX6QDL_CLK_GPT_IPG_PER] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22);
+ if (cpu_is_imx6dl())
+ /*
+ * The multiplexer and divider of imx6q clock gpu3d_shader get
+ * redefined/reused as gpu2d_core_sel and gpu2d_core_podf on imx6dl.
+ */
+ clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu3d_shader", base + 0x6c, 24);
+ else
+ clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24);
+ clk[IMX6QDL_CLK_GPU3D_CORE] = imx_clk_gate2("gpu3d_core", "gpu3d_core_podf", base + 0x6c, 26);
+ clk[IMX6QDL_CLK_HDMI_IAHB] = imx_clk_gate2("hdmi_iahb", "ahb", base + 0x70, 0);
+ clk[IMX6QDL_CLK_HDMI_ISFR] = imx_clk_gate2("hdmi_isfr", "video_27m", base + 0x70, 4);
+ clk[IMX6QDL_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_per", base + 0x70, 6);
+ clk[IMX6QDL_CLK_I2C2] = imx_clk_gate2("i2c2", "ipg_per", base + 0x70, 8);
+ clk[IMX6QDL_CLK_I2C3] = imx_clk_gate2("i2c3", "ipg_per", base + 0x70, 10);
+ clk[IMX6QDL_CLK_IIM] = imx_clk_gate2("iim", "ipg", base + 0x70, 12);
+ clk[IMX6QDL_CLK_ENFC] = imx_clk_gate2("enfc", "enfc_podf", base + 0x70, 14);
+ clk[IMX6QDL_CLK_VDOA] = imx_clk_gate2("vdoa", "vdo_axi", base + 0x70, 26);
+ clk[IMX6QDL_CLK_IPU1] = imx_clk_gate2("ipu1", "ipu1_podf", base + 0x74, 0);
+ clk[IMX6QDL_CLK_IPU1_DI0] = imx_clk_gate2("ipu1_di0", "ipu1_di0_sel", base + 0x74, 2);
+ clk[IMX6QDL_CLK_IPU1_DI1] = imx_clk_gate2("ipu1_di1", "ipu1_di1_sel", base + 0x74, 4);
+ clk[IMX6QDL_CLK_IPU2] = imx_clk_gate2("ipu2", "ipu2_podf", base + 0x74, 6);
+ clk[IMX6QDL_CLK_IPU2_DI0] = imx_clk_gate2("ipu2_di0", "ipu2_di0_sel", base + 0x74, 8);
+ clk[IMX6QDL_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12);
+ clk[IMX6QDL_CLK_LDB_DI1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14);
+ clk[IMX6QDL_CLK_IPU2_DI1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10);
+ clk[IMX6QDL_CLK_HSI_TX] = imx_clk_gate2_shared("hsi_tx", "hsi_tx_podf", base + 0x74, 16, &share_count_mipi_core_cfg);
+ clk[IMX6QDL_CLK_MIPI_CORE_CFG] = imx_clk_gate2_shared("mipi_core_cfg", "video_27m", base + 0x74, 16, &share_count_mipi_core_cfg);
+ clk[IMX6QDL_CLK_MIPI_IPG] = imx_clk_gate2_shared("mipi_ipg", "ipg", base + 0x74, 16, &share_count_mipi_core_cfg);
+ if (cpu_is_imx6dl())
+ /*
+ * The multiplexer and divider of the imx6q clock gpu2d get
+ * redefined/reused as mlb_sys_sel and mlb_sys_clk_podf on imx6dl.
+ */
+ clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "gpu2d_core_podf", base + 0x74, 18);
+ else
+ clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "axi", base + 0x74, 18);
+ clk[IMX6QDL_CLK_MMDC_CH0_AXI] = imx_clk_gate2("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20);
+ clk[IMX6QDL_CLK_MMDC_CH1_AXI] = imx_clk_gate2("mmdc_ch1_axi", "mmdc_ch1_axi_podf", base + 0x74, 22);
+ clk[IMX6QDL_CLK_OCRAM] = imx_clk_gate2("ocram", "ahb", base + 0x74, 28);
+ clk[IMX6QDL_CLK_OPENVG_AXI] = imx_clk_gate2("openvg_axi", "axi", base + 0x74, 30);
+ clk[IMX6QDL_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "pcie_axi_sel", base + 0x78, 0);
+ clk[IMX6QDL_CLK_PER1_BCH] = imx_clk_gate2("per1_bch", "usdhc3", base + 0x78, 12);
+ clk[IMX6QDL_CLK_PWM1] = imx_clk_gate2("pwm1", "ipg_per", base + 0x78, 16);
+ clk[IMX6QDL_CLK_PWM2] = imx_clk_gate2("pwm2", "ipg_per", base + 0x78, 18);
+ clk[IMX6QDL_CLK_PWM3] = imx_clk_gate2("pwm3", "ipg_per", base + 0x78, 20);
+ clk[IMX6QDL_CLK_PWM4] = imx_clk_gate2("pwm4", "ipg_per", base + 0x78, 22);
+ clk[IMX6QDL_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24);
+ clk[IMX6QDL_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26);
+ clk[IMX6QDL_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28);
+ clk[IMX6QDL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30);
+ clk[IMX6QDL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0);
+ clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ahb", base + 0x7c, 4);
+ clk[IMX6QDL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6);
+ clk[IMX6QDL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
+ clk[IMX6QDL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif_podf", base + 0x7c, 14);
+ clk[IMX6QDL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1);
+ clk[IMX6QDL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2);
+ clk[IMX6QDL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3);
+ clk[IMX6QDL_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1);
+ clk[IMX6QDL_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2);
+ clk[IMX6QDL_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3);
+ clk[IMX6QDL_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24);
+ clk[IMX6QDL_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_serial_podf", base + 0x7c, 26);
+ clk[IMX6QDL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
+ clk[IMX6QDL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
+ clk[IMX6QDL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
+ clk[IMX6QDL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
+ clk[IMX6QDL_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
+ clk[IMX6QDL_CLK_EIM_SLOW] = imx_clk_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10);
+ clk[IMX6QDL_CLK_VDO_AXI] = imx_clk_gate2("vdo_axi", "vdo_axi_sel", base + 0x80, 12);
+ clk[IMX6QDL_CLK_VPU_AXI] = imx_clk_gate2("vpu_axi", "vpu_axi_podf", base + 0x80, 14);
+ clk[IMX6QDL_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7);
+ clk[IMX6QDL_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24);
+
+ /*
+ * The gpt_3m clock is not available on i.MX6Q TO1.0. Let's point it
+ * to clock gpt_ipg_per to ease the gpt driver code.
+ */
+ if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0)
+ clk[IMX6QDL_CLK_GPT_3M] = clk[IMX6QDL_CLK_GPT_IPG_PER];
+
+ imx_check_clocks(clk, ARRAY_SIZE(clk));
+
+ clk_data.clks = clk;
+ clk_data.clk_num = ARRAY_SIZE(clk);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+ clk_register_clkdev(clk[IMX6QDL_CLK_ENET_REF], "enet_ref", NULL);
+
+ if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
+ cpu_is_imx6dl()) {
+ clk_set_parent(clk[IMX6QDL_CLK_LDB_DI0_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+ clk_set_parent(clk[IMX6QDL_CLK_LDB_DI1_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+ }
+
+ clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI0_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+ clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI1_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+ clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI0_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+ clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI1_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+ clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI0_SEL], clk[IMX6QDL_CLK_IPU1_DI0_PRE]);
+ clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI1_SEL], clk[IMX6QDL_CLK_IPU1_DI1_PRE]);
+ clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI0_SEL], clk[IMX6QDL_CLK_IPU2_DI0_PRE]);
+ clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI1_SEL], clk[IMX6QDL_CLK_IPU2_DI1_PRE]);
+
+ /*
+ * The gpmi needs 100MHz frequency in the EDO/Sync mode,
+ * We can not get the 100MHz from the pll2_pfd0_352m.
+ * So choose pll2_pfd2_396m as enfc_sel's parent.
+ */
+ clk_set_parent(clk[IMX6QDL_CLK_ENFC_SEL], clk[IMX6QDL_CLK_PLL2_PFD2_396M]);
+
+ for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+ clk_prepare_enable(clk[clks_init_on[i]]);
+
+ if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
+ clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY1_GATE]);
+ clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY2_GATE]);
+ }
+
+ /*
+ * Let's initially set up CLKO with OSC24M, since this configuration
+ * is widely used by imx6q board designs to clock audio codec.
+ */
+ ret = clk_set_parent(clk[IMX6QDL_CLK_CKO2_SEL], clk[IMX6QDL_CLK_OSC]);
+ if (!ret)
+ ret = clk_set_parent(clk[IMX6QDL_CLK_CKO], clk[IMX6QDL_CLK_CKO2]);
+ if (ret)
+ pr_warn("failed to set up CLKO: %d\n", ret);
+
+ /* Audio-related clocks configuration */
+ clk_set_parent(clk[IMX6QDL_CLK_SPDIF_SEL], clk[IMX6QDL_CLK_PLL3_PFD3_454M]);
+
+ /* All existing boards with PCIe use LVDS1 */
+ if (IS_ENABLED(CONFIG_PCI_IMX6))
+ clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]);
+
+ /* Set initial power mode */
+ imx6q_set_lpm(WAIT_CLOCKED);
+}
+CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);
diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c
new file mode 100644
index 000000000..e982ebe10
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx6sl.c
@@ -0,0 +1,450 @@
+/*
+ * Copyright 2013-2014 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 <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <dt-bindings/clock/imx6sl-clock.h>
+
+#include "clk.h"
+#include "common.h"
+
+#define CCSR 0xc
+#define BM_CCSR_PLL1_SW_CLK_SEL (1 << 2)
+#define CACRR 0x10
+#define CDHIPR 0x48
+#define BM_CDHIPR_ARM_PODF_BUSY (1 << 16)
+#define ARM_WAIT_DIV_396M 2
+#define ARM_WAIT_DIV_792M 4
+#define ARM_WAIT_DIV_996M 6
+
+#define PLL_ARM 0x0
+#define BM_PLL_ARM_DIV_SELECT (0x7f << 0)
+#define BM_PLL_ARM_POWERDOWN (1 << 12)
+#define BM_PLL_ARM_ENABLE (1 << 13)
+#define BM_PLL_ARM_LOCK (1 << 31)
+#define PLL_ARM_DIV_792M 66
+
+static const char *step_sels[] = { "osc", "pll2_pfd2", };
+static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
+static const char *ocram_alt_sels[] = { "pll2_pfd2", "pll3_pfd1", };
+static const char *ocram_sels[] = { "periph", "ocram_alt_sels", };
+static const char *pre_periph_sels[] = { "pll2_bus", "pll2_pfd2", "pll2_pfd0", "pll2_198m", };
+static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", "dummy", };
+static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
+static const char *periph_sels[] = { "pre_periph_sel", "periph_clk2_podf", };
+static const char *periph2_sels[] = { "pre_periph2_sel", "periph2_clk2_podf", };
+static const char *csi_sels[] = { "osc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", };
+static const char *lcdif_axi_sels[] = { "pll2_bus", "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", };
+static const char *usdhc_sels[] = { "pll2_pfd2", "pll2_pfd0", };
+static const char *ssi_sels[] = { "pll3_pfd2", "pll3_pfd3", "pll4_audio_div", "dummy", };
+static const char *perclk_sels[] = { "ipg", "osc", };
+static const char *pxp_axi_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd2", "pll3_pfd3", };
+static const char *epdc_axi_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd2", "pll3_pfd2", };
+static const char *gpu2d_ovg_sels[] = { "pll3_pfd1", "pll3_usb_otg", "pll2_bus", "pll2_pfd2", };
+static const char *gpu2d_sels[] = { "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", "pll2_bus", };
+static const char *lcdif_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll3_pfd0", "pll3_pfd1", };
+static const char *epdc_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd1", "pll3_pfd1", };
+static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", };
+static const char *ecspi_sels[] = { "pll3_60m", "osc", };
+static const char *uart_sels[] = { "pll3_80m", "osc", };
+static const char *lvds_sels[] = {
+ "pll1_sys", "pll2_bus", "pll2_pfd0", "pll2_pfd1", "pll2_pfd2", "dummy", "pll4_audio", "pll5_video",
+ "dummy", "enet_ref", "dummy", "dummy", "pll3_usb_otg", "pll7_usb_host", "pll3_pfd0", "pll3_pfd1",
+ "pll3_pfd2", "pll3_pfd3", "osc", "dummy", "dummy", "dummy", "dummy", "dummy",
+ "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
+};
+static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", };
+static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
+static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
+static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
+static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
+static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
+static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
+static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
+
+static struct clk_div_table clk_enet_ref_table[] = {
+ { .val = 0, .div = 20, },
+ { .val = 1, .div = 10, },
+ { .val = 2, .div = 5, },
+ { .val = 3, .div = 4, },
+ { }
+};
+
+static struct clk_div_table post_div_table[] = {
+ { .val = 2, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 0, .div = 4, },
+ { }
+};
+
+static struct clk_div_table video_div_table[] = {
+ { .val = 0, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 2, .div = 1, },
+ { .val = 3, .div = 4, },
+ { }
+};
+
+static unsigned int share_count_ssi1;
+static unsigned int share_count_ssi2;
+static unsigned int share_count_ssi3;
+
+static struct clk *clks[IMX6SL_CLK_END];
+static struct clk_onecell_data clk_data;
+static void __iomem *ccm_base;
+static void __iomem *anatop_base;
+
+static const u32 clks_init_on[] __initconst = {
+ IMX6SL_CLK_IPG, IMX6SL_CLK_ARM, IMX6SL_CLK_MMDC_ROOT,
+};
+
+/*
+ * ERR005311 CCM: After exit from WAIT mode, unwanted interrupt(s) taken
+ * during WAIT mode entry process could cause cache memory
+ * corruption.
+ *
+ * Software workaround:
+ * To prevent this issue from occurring, software should ensure that the
+ * ARM to IPG clock ratio is less than 12:5 (that is < 2.4x), before
+ * entering WAIT mode.
+ *
+ * This function will set the ARM clk to max value within the 12:5 limit.
+ * As IPG clock is fixed at 66MHz(so ARM freq must not exceed 158.4MHz),
+ * ARM freq are one of below setpoints: 396MHz, 792MHz and 996MHz, since
+ * the clk APIs can NOT be called in idle thread(may cause kernel schedule
+ * as there is sleep function in PLL wait function), so here we just slow
+ * down ARM to below freq according to previous freq:
+ *
+ * run mode wait mode
+ * 396MHz -> 132MHz;
+ * 792MHz -> 158.4MHz;
+ * 996MHz -> 142.3MHz;
+ */
+static int imx6sl_get_arm_divider_for_wait(void)
+{
+ if (readl_relaxed(ccm_base + CCSR) & BM_CCSR_PLL1_SW_CLK_SEL) {
+ return ARM_WAIT_DIV_396M;
+ } else {
+ if ((readl_relaxed(anatop_base + PLL_ARM) &
+ BM_PLL_ARM_DIV_SELECT) == PLL_ARM_DIV_792M)
+ return ARM_WAIT_DIV_792M;
+ else
+ return ARM_WAIT_DIV_996M;
+ }
+}
+
+static void imx6sl_enable_pll_arm(bool enable)
+{
+ static u32 saved_pll_arm;
+ u32 val;
+
+ if (enable) {
+ saved_pll_arm = val = readl_relaxed(anatop_base + PLL_ARM);
+ val |= BM_PLL_ARM_ENABLE;
+ val &= ~BM_PLL_ARM_POWERDOWN;
+ writel_relaxed(val, anatop_base + PLL_ARM);
+ while (!(__raw_readl(anatop_base + PLL_ARM) & BM_PLL_ARM_LOCK))
+ ;
+ } else {
+ writel_relaxed(saved_pll_arm, anatop_base + PLL_ARM);
+ }
+}
+
+void imx6sl_set_wait_clk(bool enter)
+{
+ static unsigned long saved_arm_div;
+ int arm_div_for_wait = imx6sl_get_arm_divider_for_wait();
+
+ /*
+ * According to hardware design, arm podf change need
+ * PLL1 clock enabled.
+ */
+ if (arm_div_for_wait == ARM_WAIT_DIV_396M)
+ imx6sl_enable_pll_arm(true);
+
+ if (enter) {
+ saved_arm_div = readl_relaxed(ccm_base + CACRR);
+ writel_relaxed(arm_div_for_wait, ccm_base + CACRR);
+ } else {
+ writel_relaxed(saved_arm_div, ccm_base + CACRR);
+ }
+ while (__raw_readl(ccm_base + CDHIPR) & BM_CDHIPR_ARM_PODF_BUSY)
+ ;
+
+ if (arm_div_for_wait == ARM_WAIT_DIV_396M)
+ imx6sl_enable_pll_arm(false);
+}
+
+static void __init imx6sl_clocks_init(struct device_node *ccm_node)
+{
+ struct device_node *np;
+ void __iomem *base;
+ int i;
+ int ret;
+
+ clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+ clks[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
+ clks[IMX6SL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0);
+ /* Clock source from external clock via CLK1 PAD */
+ clks[IMX6SL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop");
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+ anatop_base = base;
+
+ clks[IMX6SL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+
+ /* type name parent_name base div_mask */
+ clks[IMX6SL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
+ clks[IMX6SL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
+ clks[IMX6SL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3);
+ clks[IMX6SL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
+ clks[IMX6SL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
+ clks[IMX6SL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
+ clks[IMX6SL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3);
+
+ clks[IMX6SL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
+
+ /* Do not bypass PLLs initially */
+ clk_set_parent(clks[IMX6SL_PLL1_BYPASS], clks[IMX6SL_CLK_PLL1]);
+ clk_set_parent(clks[IMX6SL_PLL2_BYPASS], clks[IMX6SL_CLK_PLL2]);
+ clk_set_parent(clks[IMX6SL_PLL3_BYPASS], clks[IMX6SL_CLK_PLL3]);
+ clk_set_parent(clks[IMX6SL_PLL4_BYPASS], clks[IMX6SL_CLK_PLL4]);
+ clk_set_parent(clks[IMX6SL_PLL5_BYPASS], clks[IMX6SL_CLK_PLL5]);
+ clk_set_parent(clks[IMX6SL_PLL6_BYPASS], clks[IMX6SL_CLK_PLL6]);
+ clk_set_parent(clks[IMX6SL_PLL7_BYPASS], clks[IMX6SL_CLK_PLL7]);
+
+ clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13);
+ clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
+ clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
+ clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
+ clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
+ clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
+ clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
+
+ clks[IMX6SL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
+ clks[IMX6SL_CLK_LVDS1_OUT] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12));
+ clks[IMX6SL_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10));
+
+ /*
+ * usbphy1 and usbphy2 are implemented as dummy gates using reserve
+ * bit 20. They are used by phy driver to keep the refcount of
+ * parent PLL correct. usbphy1_gate and usbphy2_gate only needs to be
+ * turned on during boot, and software will not need to control it
+ * anymore after that.
+ */
+ clks[IMX6SL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20);
+ clks[IMX6SL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20);
+ clks[IMX6SL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
+ clks[IMX6SL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
+
+ /* dev name parent_name flags reg shift width div: flags, div_table lock */
+ clks[IMX6SL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
+ clks[IMX6SL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock);
+ clks[IMX6SL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
+ clks[IMX6SL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
+ clks[IMX6SL_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, base + 0xe0, 0, 2, 0, clk_enet_ref_table, &imx_ccm_lock);
+
+ /* name parent_name reg idx */
+ clks[IMX6SL_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0", "pll2_bus", base + 0x100, 0);
+ clks[IMX6SL_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1", "pll2_bus", base + 0x100, 1);
+ clks[IMX6SL_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2", "pll2_bus", base + 0x100, 2);
+ clks[IMX6SL_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0", "pll3_usb_otg", base + 0xf0, 0);
+ clks[IMX6SL_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1", "pll3_usb_otg", base + 0xf0, 1);
+ clks[IMX6SL_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_usb_otg", base + 0xf0, 2);
+ clks[IMX6SL_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_usb_otg", base + 0xf0, 3);
+
+ /* name parent_name mult div */
+ clks[IMX6SL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2", 1, 2);
+ clks[IMX6SL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
+ clks[IMX6SL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
+ clks[IMX6SL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
+
+ np = ccm_node;
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+ ccm_base = base;
+
+ /* Reuse imx6q pm code */
+ imx6q_pm_set_ccm_base(base);
+
+ /* name reg shift width parent_names num_parents */
+ clks[IMX6SL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
+ clks[IMX6SL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
+ clks[IMX6SL_CLK_OCRAM_ALT_SEL] = imx_clk_mux("ocram_alt_sel", base + 0x14, 7, 1, ocram_alt_sels, ARRAY_SIZE(ocram_alt_sels));
+ clks[IMX6SL_CLK_OCRAM_SEL] = imx_clk_mux("ocram_sel", base + 0x14, 6, 1, ocram_sels, ARRAY_SIZE(ocram_sels));
+ clks[IMX6SL_CLK_PRE_PERIPH2_SEL] = imx_clk_mux("pre_periph2_sel", base + 0x18, 21, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
+ clks[IMX6SL_CLK_PRE_PERIPH_SEL] = imx_clk_mux("pre_periph_sel", base + 0x18, 18, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
+ clks[IMX6SL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
+ clks[IMX6SL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
+ clks[IMX6SL_CLK_CSI_SEL] = imx_clk_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels));
+ clks[IMX6SL_CLK_LCDIF_AXI_SEL] = imx_clk_mux("lcdif_axi_sel", base + 0x3c, 14, 2, lcdif_axi_sels, ARRAY_SIZE(lcdif_axi_sels));
+ clks[IMX6SL_CLK_USDHC1_SEL] = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
+ clks[IMX6SL_CLK_USDHC2_SEL] = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
+ clks[IMX6SL_CLK_USDHC3_SEL] = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
+ clks[IMX6SL_CLK_USDHC4_SEL] = imx_clk_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
+ clks[IMX6SL_CLK_SSI1_SEL] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
+ clks[IMX6SL_CLK_SSI2_SEL] = imx_clk_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
+ clks[IMX6SL_CLK_SSI3_SEL] = imx_clk_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
+ clks[IMX6SL_CLK_PERCLK_SEL] = imx_clk_fixup_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels), imx_cscmr1_fixup);
+ clks[IMX6SL_CLK_PXP_AXI_SEL] = imx_clk_mux("pxp_axi_sel", base + 0x34, 6, 3, pxp_axi_sels, ARRAY_SIZE(pxp_axi_sels));
+ clks[IMX6SL_CLK_EPDC_AXI_SEL] = imx_clk_mux("epdc_axi_sel", base + 0x34, 15, 3, epdc_axi_sels, ARRAY_SIZE(epdc_axi_sels));
+ clks[IMX6SL_CLK_GPU2D_OVG_SEL] = imx_clk_mux("gpu2d_ovg_sel", base + 0x18, 4, 2, gpu2d_ovg_sels, ARRAY_SIZE(gpu2d_ovg_sels));
+ clks[IMX6SL_CLK_GPU2D_SEL] = imx_clk_mux("gpu2d_sel", base + 0x18, 8, 2, gpu2d_sels, ARRAY_SIZE(gpu2d_sels));
+ clks[IMX6SL_CLK_LCDIF_PIX_SEL] = imx_clk_mux("lcdif_pix_sel", base + 0x38, 6, 3, lcdif_pix_sels, ARRAY_SIZE(lcdif_pix_sels));
+ clks[IMX6SL_CLK_EPDC_PIX_SEL] = imx_clk_mux("epdc_pix_sel", base + 0x38, 15, 3, epdc_pix_sels, ARRAY_SIZE(epdc_pix_sels));
+ clks[IMX6SL_CLK_SPDIF0_SEL] = imx_clk_mux("spdif0_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
+ clks[IMX6SL_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
+ clks[IMX6SL_CLK_EXTERN_AUDIO_SEL] = imx_clk_mux("extern_audio_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
+ clks[IMX6SL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
+ clks[IMX6SL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
+
+ /* name reg shift width busy: reg, shift parent_names num_parents */
+ clks[IMX6SL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
+ clks[IMX6SL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
+
+ /* name parent_name reg shift width */
+ clks[IMX6SL_CLK_OCRAM_PODF] = imx_clk_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3);
+ clks[IMX6SL_CLK_PERIPH_CLK2_PODF] = imx_clk_divider("periph_clk2_podf", "periph_clk2_sel", base + 0x14, 27, 3);
+ clks[IMX6SL_CLK_PERIPH2_CLK2_PODF] = imx_clk_divider("periph2_clk2_podf", "periph2_clk2_sel", base + 0x14, 0, 3);
+ clks[IMX6SL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
+ clks[IMX6SL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3);
+ clks[IMX6SL_CLK_LCDIF_AXI_PODF] = imx_clk_divider("lcdif_axi_podf", "lcdif_axi_sel", base + 0x3c, 16, 3);
+ clks[IMX6SL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
+ clks[IMX6SL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
+ clks[IMX6SL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
+ clks[IMX6SL_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3);
+ clks[IMX6SL_CLK_SSI1_PRED] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3);
+ clks[IMX6SL_CLK_SSI1_PODF] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6);
+ clks[IMX6SL_CLK_SSI2_PRED] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3);
+ clks[IMX6SL_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6);
+ clks[IMX6SL_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3);
+ clks[IMX6SL_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6);
+ clks[IMX6SL_CLK_PERCLK] = imx_clk_fixup_divider("perclk", "perclk_sel", base + 0x1c, 0, 6, imx_cscmr1_fixup);
+ clks[IMX6SL_CLK_PXP_AXI_PODF] = imx_clk_divider("pxp_axi_podf", "pxp_axi_sel", base + 0x34, 3, 3);
+ clks[IMX6SL_CLK_EPDC_AXI_PODF] = imx_clk_divider("epdc_axi_podf", "epdc_axi_sel", base + 0x34, 12, 3);
+ clks[IMX6SL_CLK_GPU2D_OVG_PODF] = imx_clk_divider("gpu2d_ovg_podf", "gpu2d_ovg_sel", base + 0x18, 26, 3);
+ clks[IMX6SL_CLK_GPU2D_PODF] = imx_clk_divider("gpu2d_podf", "gpu2d_sel", base + 0x18, 29, 3);
+ clks[IMX6SL_CLK_LCDIF_PIX_PRED] = imx_clk_divider("lcdif_pix_pred", "lcdif_pix_sel", base + 0x38, 3, 3);
+ clks[IMX6SL_CLK_EPDC_PIX_PRED] = imx_clk_divider("epdc_pix_pred", "epdc_pix_sel", base + 0x38, 12, 3);
+ clks[IMX6SL_CLK_LCDIF_PIX_PODF] = imx_clk_fixup_divider("lcdif_pix_podf", "lcdif_pix_pred", base + 0x1c, 20, 3, imx_cscmr1_fixup);
+ clks[IMX6SL_CLK_EPDC_PIX_PODF] = imx_clk_divider("epdc_pix_podf", "epdc_pix_pred", base + 0x18, 23, 3);
+ clks[IMX6SL_CLK_SPDIF0_PRED] = imx_clk_divider("spdif0_pred", "spdif0_sel", base + 0x30, 25, 3);
+ clks[IMX6SL_CLK_SPDIF0_PODF] = imx_clk_divider("spdif0_podf", "spdif0_pred", base + 0x30, 22, 3);
+ clks[IMX6SL_CLK_SPDIF1_PRED] = imx_clk_divider("spdif1_pred", "spdif1_sel", base + 0x30, 12, 3);
+ clks[IMX6SL_CLK_SPDIF1_PODF] = imx_clk_divider("spdif1_podf", "spdif1_pred", base + 0x30, 9, 3);
+ clks[IMX6SL_CLK_EXTERN_AUDIO_PRED] = imx_clk_divider("extern_audio_pred", "extern_audio_sel", base + 0x28, 9, 3);
+ clks[IMX6SL_CLK_EXTERN_AUDIO_PODF] = imx_clk_divider("extern_audio_podf", "extern_audio_pred", base + 0x28, 25, 3);
+ clks[IMX6SL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "ecspi_sel", base + 0x38, 19, 6);
+ clks[IMX6SL_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_sel", base + 0x24, 0, 6);
+
+ /* name parent_name reg shift width busy: reg, shift */
+ clks[IMX6SL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
+ clks[IMX6SL_CLK_MMDC_ROOT] = imx_clk_busy_divider("mmdc", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
+ clks[IMX6SL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
+
+ /* name parent_name reg shift */
+ clks[IMX6SL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0);
+ clks[IMX6SL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2);
+ clks[IMX6SL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4);
+ clks[IMX6SL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6);
+ clks[IMX6SL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10);
+ clks[IMX6SL_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12);
+ clks[IMX6SL_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14);
+ clks[IMX6SL_CLK_EXTERN_AUDIO] = imx_clk_gate2("extern_audio", "extern_audio_podf", base + 0x6c, 16);
+ clks[IMX6SL_CLK_GPT] = imx_clk_gate2("gpt", "perclk", base + 0x6c, 20);
+ clks[IMX6SL_CLK_GPT_SERIAL] = imx_clk_gate2("gpt_serial", "perclk", base + 0x6c, 22);
+ clks[IMX6SL_CLK_GPU2D_OVG] = imx_clk_gate2("gpu2d_ovg", "gpu2d_ovg_podf", base + 0x6c, 26);
+ clks[IMX6SL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6);
+ clks[IMX6SL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8);
+ clks[IMX6SL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10);
+ clks[IMX6SL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12);
+ clks[IMX6SL_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x74, 0);
+ clks[IMX6SL_CLK_PXP_AXI] = imx_clk_gate2("pxp_axi", "pxp_axi_podf", base + 0x74, 2);
+ clks[IMX6SL_CLK_EPDC_AXI] = imx_clk_gate2("epdc_axi", "epdc_axi_podf", base + 0x74, 4);
+ clks[IMX6SL_CLK_LCDIF_AXI] = imx_clk_gate2("lcdif_axi", "lcdif_axi_podf", base + 0x74, 6);
+ clks[IMX6SL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_pix_podf", base + 0x74, 8);
+ clks[IMX6SL_CLK_EPDC_PIX] = imx_clk_gate2("epdc_pix", "epdc_pix_podf", base + 0x74, 10);
+ clks[IMX6SL_CLK_OCRAM] = imx_clk_gate2("ocram", "ocram_podf", base + 0x74, 28);
+ clks[IMX6SL_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16);
+ clks[IMX6SL_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18);
+ clks[IMX6SL_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20);
+ clks[IMX6SL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22);
+ clks[IMX6SL_CLK_SDMA] = imx_clk_gate2("sdma", "ipg", base + 0x7c, 6);
+ clks[IMX6SL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
+ clks[IMX6SL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif0_podf", base + 0x7c, 14);
+ clks[IMX6SL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1);
+ clks[IMX6SL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2);
+ clks[IMX6SL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3);
+ clks[IMX6SL_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1);
+ clks[IMX6SL_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2);
+ clks[IMX6SL_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3);
+ clks[IMX6SL_CLK_UART] = imx_clk_gate2("uart", "ipg", base + 0x7c, 24);
+ clks[IMX6SL_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_root", base + 0x7c, 26);
+ clks[IMX6SL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
+ clks[IMX6SL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
+ clks[IMX6SL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
+ clks[IMX6SL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
+ clks[IMX6SL_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
+
+ imx_check_clocks(clks, ARRAY_SIZE(clks));
+
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+ /* Ensure the AHB clk is at 132MHz. */
+ ret = clk_set_rate(clks[IMX6SL_CLK_AHB], 132000000);
+ if (ret)
+ pr_warn("%s: failed to set AHB clock rate %d!\n",
+ __func__, ret);
+
+ /*
+ * Make sure those always on clocks are enabled to maintain the correct
+ * usecount and enabling/disabling of parent PLLs.
+ */
+ for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+ clk_prepare_enable(clks[clks_init_on[i]]);
+
+ if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
+ clk_prepare_enable(clks[IMX6SL_CLK_USBPHY1_GATE]);
+ clk_prepare_enable(clks[IMX6SL_CLK_USBPHY2_GATE]);
+ }
+
+ /* Audio-related clocks configuration */
+ clk_set_parent(clks[IMX6SL_CLK_SPDIF0_SEL], clks[IMX6SL_CLK_PLL3_PFD3]);
+
+ /* set PLL5 video as lcdif pix parent clock */
+ clk_set_parent(clks[IMX6SL_CLK_LCDIF_PIX_SEL],
+ clks[IMX6SL_CLK_PLL5_VIDEO_DIV]);
+
+ clk_set_parent(clks[IMX6SL_CLK_LCDIF_AXI_SEL],
+ clks[IMX6SL_CLK_PLL2_PFD2]);
+
+ /* Set initial power mode */
+ imx6q_set_lpm(WAIT_CLOCKED);
+}
+CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init);
diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/arch/arm/mach-imx/clk-imx6sx.c
new file mode 100644
index 000000000..5a3e5a159
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx6sx.c
@@ -0,0 +1,567 @@
+/*
+ * Copyright (C) 2014 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 <dt-bindings/clock/imx6sx-clock.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/types.h>
+
+#include "clk.h"
+#include "common.h"
+
+#define CCDR 0x4
+#define BM_CCM_CCDR_MMDC_CH0_MASK (0x2 << 16)
+
+static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
+static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
+static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
+static const char *periph2_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll4_audio_div", };
+static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", };
+static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "osc", };
+static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
+static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
+static const char *ocram_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", };
+static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll5_video_div", "pll3_usb_otg", };
+static const char *gpu_axi_sels[] = { "pll2_pfd2_396m", "pll3_pfd0_720m", "pll3_pfd1_540m", "pll2_bus", };
+static const char *gpu_core_sels[] = { "pll3_pfd1_540m", "pll3_pfd0_720m", "pll2_bus", "pll2_pfd2_396m", };
+static const char *ldb_di0_div_sels[] = { "ldb_di0_div_3_5", "ldb_di0_div_7", };
+static const char *ldb_di1_div_sels[] = { "ldb_di1_div_3_5", "ldb_di1_div_7", };
+static const char *ldb_di0_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_pfd3_594m", "pll2_pfd1_594m", "pll3_pfd3_454m", };
+static const char *ldb_di1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
+static const char *pcie_axi_sels[] = { "axi", "ahb", };
+static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll5_video_div", "pll4_audio_div", };
+static const char *qspi1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
+static const char *perclk_sels[] = { "ipg", "osc", };
+static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *vid_sels[] = { "pll3_pfd1_540m", "pll3_usb_otg", "pll3_pfd3_454m", "pll4_audio_div", "pll5_video_div", };
+static const char *can_sels[] = { "pll3_60m", "osc", "pll3_80m", "dummy", };
+static const char *uart_sels[] = { "pll3_80m", "osc", };
+static const char *qspi2_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", "pll3_pfd3_454m", "dummy", "dummy", "dummy", };
+static const char *enet_pre_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd2_508m", };
+static const char *enet_sels[] = { "enet_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *m4_pre_sels[] = { "pll2_bus", "pll3_usb_otg", "osc", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd3_454m", };
+static const char *m4_sels[] = { "m4_pre_sel", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *eim_slow_sels[] = { "ocram", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *ecspi_sels[] = { "pll3_60m", "osc", };
+static const char *lcdif1_pre_sels[] = { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd1_594m", "pll3_pfd1_540m", };
+static const char *lcdif1_sels[] = { "lcdif1_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *lcdif2_pre_sels[] = { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd3_594m", "pll3_pfd1_540m", };
+static const char *lcdif2_sels[] = { "lcdif2_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *display_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll3_usb_otg", "pll3_pfd1_540m", };
+static const char *csi_sels[] = { "osc", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
+static const char *cko1_sels[] = {
+ "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
+ "dummy", "ocram", "dummy", "pxp_axi", "epdc_axi", "lcdif_pix",
+ "epdc_pix", "ahb", "ipg", "perclk", "ckil", "pll4_audio_div",
+};
+static const char *cko2_sels[] = {
+ "dummy", "mmdc_p0_fast", "usdhc4", "usdhc1", "dummy", "wrck",
+ "ecspi_root", "dummy", "usdhc3", "pcie", "arm", "csi_core",
+ "lcdif_axi", "dummy", "osc", "dummy", "gpu2d_ovg_core",
+ "usdhc2", "ssi1", "ssi2", "ssi3", "gpu2d_core", "dummy",
+ "dummy", "dummy", "dummy", "esai_extal", "eim_slow", "uart_serial",
+ "spdif", "asrc", "dummy",
+};
+static const char *cko_sels[] = { "cko1", "cko2", };
+static const char *lvds_sels[] = {
+ "arm", "pll1_sys", "dummy", "dummy", "dummy", "dummy", "dummy", "pll5_video_div",
+ "dummy", "dummy", "pcie_ref_125m", "dummy", "usbphy1", "usbphy2",
+};
+static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", };
+static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
+static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
+static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
+static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
+static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
+static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
+static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
+
+static struct clk *clks[IMX6SX_CLK_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static int const clks_init_on[] __initconst = {
+ IMX6SX_CLK_AIPS_TZ1, IMX6SX_CLK_AIPS_TZ2, IMX6SX_CLK_AIPS_TZ3,
+ IMX6SX_CLK_IPMUX1, IMX6SX_CLK_IPMUX2, IMX6SX_CLK_IPMUX3,
+ IMX6SX_CLK_WAKEUP, IMX6SX_CLK_MMDC_P0_FAST, IMX6SX_CLK_MMDC_P0_IPG,
+ IMX6SX_CLK_ROM, IMX6SX_CLK_ARM, IMX6SX_CLK_IPG, IMX6SX_CLK_OCRAM,
+ IMX6SX_CLK_PER2_MAIN, IMX6SX_CLK_PERCLK, IMX6SX_CLK_M4,
+ IMX6SX_CLK_QSPI1, IMX6SX_CLK_QSPI2, IMX6SX_CLK_UART_IPG,
+ IMX6SX_CLK_UART_SERIAL, IMX6SX_CLK_I2C3, IMX6SX_CLK_ECSPI5,
+ IMX6SX_CLK_CAN1_IPG, IMX6SX_CLK_CAN1_SERIAL, IMX6SX_CLK_CAN2_IPG,
+ IMX6SX_CLK_CAN2_SERIAL, IMX6SX_CLK_CANFD, IMX6SX_CLK_EPIT1,
+ IMX6SX_CLK_EPIT2,
+};
+
+static struct clk_div_table clk_enet_ref_table[] = {
+ { .val = 0, .div = 20, },
+ { .val = 1, .div = 10, },
+ { .val = 2, .div = 5, },
+ { .val = 3, .div = 4, },
+ { }
+};
+
+static struct clk_div_table post_div_table[] = {
+ { .val = 2, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 0, .div = 4, },
+ { }
+};
+
+static struct clk_div_table video_div_table[] = {
+ { .val = 0, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 2, .div = 1, },
+ { .val = 3, .div = 4, },
+ { }
+};
+
+static u32 share_count_asrc;
+static u32 share_count_audio;
+static u32 share_count_esai;
+static u32 share_count_ssi1;
+static u32 share_count_ssi2;
+static u32 share_count_ssi3;
+
+static void __init imx6sx_clocks_init(struct device_node *ccm_node)
+{
+ struct device_node *np;
+ void __iomem *base;
+ int i;
+
+ clks[IMX6SX_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+
+ clks[IMX6SX_CLK_CKIL] = of_clk_get_by_name(ccm_node, "ckil");
+ clks[IMX6SX_CLK_OSC] = of_clk_get_by_name(ccm_node, "osc");
+
+ /* ipp_di clock is external input */
+ clks[IMX6SX_CLK_IPP_DI0] = of_clk_get_by_name(ccm_node, "ipp_di0");
+ clks[IMX6SX_CLK_IPP_DI1] = of_clk_get_by_name(ccm_node, "ipp_di1");
+
+ /* Clock source from external clock via CLK1 PAD */
+ clks[IMX6SX_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-anatop");
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ clks[IMX6SX_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SX_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SX_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SX_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SX_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SX_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SX_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+
+ /* type name parent_name base div_mask */
+ clks[IMX6SX_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
+ clks[IMX6SX_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
+ clks[IMX6SX_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3);
+ clks[IMX6SX_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
+ clks[IMX6SX_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
+ clks[IMX6SX_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
+ clks[IMX6SX_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3);
+
+ clks[IMX6SX_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SX_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SX_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SX_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SX_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SX_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SX_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
+
+ /* Do not bypass PLLs initially */
+ clk_set_parent(clks[IMX6SX_PLL1_BYPASS], clks[IMX6SX_CLK_PLL1]);
+ clk_set_parent(clks[IMX6SX_PLL2_BYPASS], clks[IMX6SX_CLK_PLL2]);
+ clk_set_parent(clks[IMX6SX_PLL3_BYPASS], clks[IMX6SX_CLK_PLL3]);
+ clk_set_parent(clks[IMX6SX_PLL4_BYPASS], clks[IMX6SX_CLK_PLL4]);
+ clk_set_parent(clks[IMX6SX_PLL5_BYPASS], clks[IMX6SX_CLK_PLL5]);
+ clk_set_parent(clks[IMX6SX_PLL6_BYPASS], clks[IMX6SX_CLK_PLL6]);
+ clk_set_parent(clks[IMX6SX_PLL7_BYPASS], clks[IMX6SX_CLK_PLL7]);
+
+ clks[IMX6SX_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13);
+ clks[IMX6SX_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
+ clks[IMX6SX_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
+ clks[IMX6SX_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
+ clks[IMX6SX_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
+ clks[IMX6SX_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
+ clks[IMX6SX_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
+
+ /*
+ * Bit 20 is the reserved and read-only bit, we do this only for:
+ * - Do nothing for usbphy clk_enable/disable
+ * - Keep refcount when do usbphy clk_enable/disable, in that case,
+ * the clk framework may need to enable/disable usbphy's parent
+ */
+ clks[IMX6SX_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20);
+ clks[IMX6SX_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20);
+
+ /*
+ * usbphy*_gate needs to be on after system boots up, and software
+ * never needs to control it anymore.
+ */
+ clks[IMX6SX_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
+ clks[IMX6SX_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
+
+ /* FIXME 100Mhz is used for pcie ref for all imx6 pcie, excepted imx6q */
+ clks[IMX6SX_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 5);
+ clks[IMX6SX_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
+
+ clks[IMX6SX_CLK_LVDS1_OUT] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12));
+ clks[IMX6SX_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10));
+
+ clks[IMX6SX_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0,
+ base + 0xe0, 0, 2, 0, clk_enet_ref_table,
+ &imx_ccm_lock);
+ clks[IMX6SX_CLK_ENET2_REF] = clk_register_divider_table(NULL, "enet2_ref", "pll6_enet", 0,
+ base + 0xe0, 2, 2, 0, clk_enet_ref_table,
+ &imx_ccm_lock);
+ clks[IMX6SX_CLK_ENET2_REF_125M] = imx_clk_gate("enet2_ref_125m", "enet2_ref", base + 0xe0, 20);
+
+ clks[IMX6SX_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20);
+ clks[IMX6SX_CLK_ENET_PTP] = imx_clk_gate("enet_ptp_25m", "enet_ptp_ref", base + 0xe0, 21);
+
+ /* name parent_name reg idx */
+ clks[IMX6SX_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
+ clks[IMX6SX_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
+ clks[IMX6SX_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2);
+ clks[IMX6SX_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3_594m", "pll2_bus", base + 0x100, 3);
+ clks[IMX6SX_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0);
+ clks[IMX6SX_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1);
+ clks[IMX6SX_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2);
+ clks[IMX6SX_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3);
+
+ /* name parent_name mult div */
+ clks[IMX6SX_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
+ clks[IMX6SX_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
+ clks[IMX6SX_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
+ clks[IMX6SX_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
+ clks[IMX6SX_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2);
+ clks[IMX6SX_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
+
+ clks[IMX6SX_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio",
+ CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
+ clks[IMX6SX_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div",
+ CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock);
+ clks[IMX6SX_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video",
+ CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
+ clks[IMX6SX_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div",
+ CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
+
+ /* name reg shift width parent_names num_parents */
+ clks[IMX6SX_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
+
+ np = ccm_node;
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ imx6q_pm_set_ccm_base(base);
+
+ /* name reg shift width parent_names num_parents */
+ clks[IMX6SX_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
+ clks[IMX6SX_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
+ clks[IMX6SX_CLK_OCRAM_SEL] = imx_clk_mux("ocram_sel", base + 0x14, 6, 2, ocram_sels, ARRAY_SIZE(ocram_sels));
+ clks[IMX6SX_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
+ clks[IMX6SX_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels));
+ clks[IMX6SX_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
+ clks[IMX6SX_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
+ clks[IMX6SX_CLK_PCIE_AXI_SEL] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels));
+ clks[IMX6SX_CLK_GPU_AXI_SEL] = imx_clk_mux("gpu_axi_sel", base + 0x18, 8, 2, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels));
+ clks[IMX6SX_CLK_GPU_CORE_SEL] = imx_clk_mux("gpu_core_sel", base + 0x18, 4, 2, gpu_core_sels, ARRAY_SIZE(gpu_core_sels));
+ clks[IMX6SX_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels));
+ clks[IMX6SX_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6SX_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6SX_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6SX_CLK_USDHC4_SEL] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6SX_CLK_SSI3_SEL] = imx_clk_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+ clks[IMX6SX_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+ clks[IMX6SX_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+ clks[IMX6SX_CLK_QSPI1_SEL] = imx_clk_mux_flags("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SX_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels));
+ clks[IMX6SX_CLK_VID_SEL] = imx_clk_mux("vid_sel", base + 0x20, 21, 3, vid_sels, ARRAY_SIZE(vid_sels));
+ clks[IMX6SX_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
+ clks[IMX6SX_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels));
+ clks[IMX6SX_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
+ clks[IMX6SX_CLK_QSPI2_SEL] = imx_clk_mux_flags("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SX_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
+ clks[IMX6SX_CLK_AUDIO_SEL] = imx_clk_mux("audio_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
+ clks[IMX6SX_CLK_ENET_PRE_SEL] = imx_clk_mux("enet_pre_sel", base + 0x34, 15, 3, enet_pre_sels, ARRAY_SIZE(enet_pre_sels));
+ clks[IMX6SX_CLK_ENET_SEL] = imx_clk_mux("enet_sel", base + 0x34, 9, 3, enet_sels, ARRAY_SIZE(enet_sels));
+ clks[IMX6SX_CLK_M4_PRE_SEL] = imx_clk_mux("m4_pre_sel", base + 0x34, 6, 3, m4_pre_sels, ARRAY_SIZE(m4_pre_sels));
+ clks[IMX6SX_CLK_M4_SEL] = imx_clk_mux("m4_sel", base + 0x34, 0, 3, m4_sels, ARRAY_SIZE(m4_sels));
+ clks[IMX6SX_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
+ clks[IMX6SX_CLK_LCDIF2_PRE_SEL] = imx_clk_mux("lcdif2_pre_sel", base + 0x38, 6, 3, lcdif2_pre_sels, ARRAY_SIZE(lcdif2_pre_sels));
+ clks[IMX6SX_CLK_LCDIF2_SEL] = imx_clk_mux("lcdif2_sel", base + 0x38, 0, 3, lcdif2_sels, ARRAY_SIZE(lcdif2_sels));
+ clks[IMX6SX_CLK_DISPLAY_SEL] = imx_clk_mux("display_sel", base + 0x3c, 14, 2, display_sels, ARRAY_SIZE(display_sels));
+ clks[IMX6SX_CLK_CSI_SEL] = imx_clk_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels));
+ clks[IMX6SX_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels));
+ clks[IMX6SX_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels));
+ clks[IMX6SX_CLK_CKO] = imx_clk_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels));
+
+ clks[IMX6SX_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux_flags("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SX_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux_flags("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SX_CLK_LDB_DI1_SEL] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SX_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SX_CLK_LCDIF1_PRE_SEL] = imx_clk_mux_flags("lcdif1_pre_sel", base + 0x38, 15, 3, lcdif1_pre_sels, ARRAY_SIZE(lcdif1_pre_sels), CLK_SET_RATE_PARENT);
+ clks[IMX6SX_CLK_LCDIF1_SEL] = imx_clk_mux_flags("lcdif1_sel", base + 0x38, 9, 3, lcdif1_sels, ARRAY_SIZE(lcdif1_sels), CLK_SET_RATE_PARENT);
+
+ /* name parent_name reg shift width */
+ clks[IMX6SX_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
+ clks[IMX6SX_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
+ clks[IMX6SX_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
+ clks[IMX6SX_CLK_GPU_CORE_PODF] = imx_clk_divider("gpu_core_podf", "gpu_core_sel", base + 0x18, 29, 3);
+ clks[IMX6SX_CLK_GPU_AXI_PODF] = imx_clk_divider("gpu_axi_podf", "gpu_axi_sel", base + 0x18, 26, 3);
+ clks[IMX6SX_CLK_LCDIF1_PODF] = imx_clk_divider("lcdif1_podf", "lcdif1_pred", base + 0x18, 23, 3);
+ clks[IMX6SX_CLK_QSPI1_PODF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3);
+ clks[IMX6SX_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3);
+ clks[IMX6SX_CLK_LCDIF2_PODF] = imx_clk_divider("lcdif2_podf", "lcdif2_pred", base + 0x1c, 20, 3);
+ clks[IMX6SX_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6);
+ clks[IMX6SX_CLK_VID_PODF] = imx_clk_divider("vid_podf", "vid_sel", base + 0x20, 24, 2);
+ clks[IMX6SX_CLK_CAN_PODF] = imx_clk_divider("can_podf", "can_sel", base + 0x20, 2, 6);
+ clks[IMX6SX_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3);
+ clks[IMX6SX_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
+ clks[IMX6SX_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
+ clks[IMX6SX_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
+ clks[IMX6SX_CLK_UART_PODF] = imx_clk_divider("uart_podf", "uart_sel", base + 0x24, 0, 6);
+ clks[IMX6SX_CLK_ESAI_PRED] = imx_clk_divider("esai_pred", "esai_sel", base + 0x28, 9, 3);
+ clks[IMX6SX_CLK_ESAI_PODF] = imx_clk_divider("esai_podf", "esai_pred", base + 0x28, 25, 3);
+ clks[IMX6SX_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3);
+ clks[IMX6SX_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6);
+ clks[IMX6SX_CLK_SSI1_PRED] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3);
+ clks[IMX6SX_CLK_SSI1_PODF] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6);
+ clks[IMX6SX_CLK_QSPI2_PRED] = imx_clk_divider("qspi2_pred", "qspi2_sel", base + 0x2c, 18, 3);
+ clks[IMX6SX_CLK_QSPI2_PODF] = imx_clk_divider("qspi2_podf", "qspi2_pred", base + 0x2c, 21, 6);
+ clks[IMX6SX_CLK_SSI2_PRED] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3);
+ clks[IMX6SX_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6);
+ clks[IMX6SX_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3);
+ clks[IMX6SX_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3);
+ clks[IMX6SX_CLK_AUDIO_PRED] = imx_clk_divider("audio_pred", "audio_sel", base + 0x30, 12, 3);
+ clks[IMX6SX_CLK_AUDIO_PODF] = imx_clk_divider("audio_podf", "audio_pred", base + 0x30, 9, 3);
+ clks[IMX6SX_CLK_ENET_PODF] = imx_clk_divider("enet_podf", "enet_pre_sel", base + 0x34, 12, 3);
+ clks[IMX6SX_CLK_M4_PODF] = imx_clk_divider("m4_podf", "m4_sel", base + 0x34, 3, 3);
+ clks[IMX6SX_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_sel", base + 0x38, 19, 6);
+ clks[IMX6SX_CLK_LCDIF1_PRED] = imx_clk_divider("lcdif1_pred", "lcdif1_pre_sel", base + 0x38, 12, 3);
+ clks[IMX6SX_CLK_LCDIF2_PRED] = imx_clk_divider("lcdif2_pred", "lcdif2_pre_sel", base + 0x38, 3, 3);
+ clks[IMX6SX_CLK_DISPLAY_PODF] = imx_clk_divider("display_podf", "display_sel", base + 0x3c, 16, 3);
+ clks[IMX6SX_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3);
+ clks[IMX6SX_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3);
+ clks[IMX6SX_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3);
+
+ clks[IMX6SX_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+ clks[IMX6SX_CLK_LDB_DI0_DIV_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7);
+ clks[IMX6SX_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+ clks[IMX6SX_CLK_LDB_DI1_DIV_7] = imx_clk_fixed_factor("ldb_di1_div_7", "ldb_di1_sel", 1, 7);
+
+ /* name reg shift width busy: reg, shift parent_names num_parents */
+ clks[IMX6SX_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
+ clks[IMX6SX_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
+ /* name parent_name reg shift width busy: reg, shift */
+ clks[IMX6SX_CLK_OCRAM_PODF] = imx_clk_busy_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3, base + 0x48, 0);
+ clks[IMX6SX_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
+ clks[IMX6SX_CLK_MMDC_PODF] = imx_clk_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
+ clks[IMX6SX_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
+
+ /* name parent_name reg shift */
+ /* CCGR0 */
+ clks[IMX6SX_CLK_AIPS_TZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0);
+ clks[IMX6SX_CLK_AIPS_TZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2);
+ clks[IMX6SX_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4);
+ clks[IMX6SX_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc);
+ clks[IMX6SX_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc);
+ clks[IMX6SX_CLK_CAAM_MEM] = imx_clk_gate2("caam_mem", "ahb", base + 0x68, 8);
+ clks[IMX6SX_CLK_CAAM_ACLK] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10);
+ clks[IMX6SX_CLK_CAAM_IPG] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12);
+ clks[IMX6SX_CLK_CAN1_IPG] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14);
+ clks[IMX6SX_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_podf", base + 0x68, 16);
+ clks[IMX6SX_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18);
+ clks[IMX6SX_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_podf", base + 0x68, 20);
+ clks[IMX6SX_CLK_DCIC1] = imx_clk_gate2("dcic1", "display_podf", base + 0x68, 24);
+ clks[IMX6SX_CLK_DCIC2] = imx_clk_gate2("dcic2", "display_podf", base + 0x68, 26);
+ clks[IMX6SX_CLK_AIPS_TZ3] = imx_clk_gate2("aips_tz3", "ahb", base + 0x68, 30);
+
+ /* CCGR1 */
+ clks[IMX6SX_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0);
+ clks[IMX6SX_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_podf", base + 0x6c, 2);
+ clks[IMX6SX_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_podf", base + 0x6c, 4);
+ clks[IMX6SX_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_podf", base + 0x6c, 6);
+ clks[IMX6SX_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_podf", base + 0x6c, 8);
+ clks[IMX6SX_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12);
+ clks[IMX6SX_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14);
+ clks[IMX6SX_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai);
+ clks[IMX6SX_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai);
+ clks[IMX6SX_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai);
+ clks[IMX6SX_CLK_WAKEUP] = imx_clk_gate2("wakeup", "ipg", base + 0x6c, 18);
+ clks[IMX6SX_CLK_GPT_BUS] = imx_clk_gate2("gpt_bus", "perclk", base + 0x6c, 20);
+ clks[IMX6SX_CLK_GPT_SERIAL] = imx_clk_gate2("gpt_serial", "perclk", base + 0x6c, 22);
+ clks[IMX6SX_CLK_GPU] = imx_clk_gate2("gpu", "gpu_core_podf", base + 0x6c, 26);
+ clks[IMX6SX_CLK_CANFD] = imx_clk_gate2("canfd", "can_podf", base + 0x6c, 30);
+
+ /* CCGR2 */
+ clks[IMX6SX_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x70, 2);
+ clks[IMX6SX_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6);
+ clks[IMX6SX_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8);
+ clks[IMX6SX_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10);
+ clks[IMX6SX_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12);
+ clks[IMX6SX_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif1_podf", base + 0x70, 14);
+ clks[IMX6SX_CLK_IPMUX1] = imx_clk_gate2("ipmux1", "ahb", base + 0x70, 16);
+ clks[IMX6SX_CLK_IPMUX2] = imx_clk_gate2("ipmux2", "ahb", base + 0x70, 18);
+ clks[IMX6SX_CLK_IPMUX3] = imx_clk_gate2("ipmux3", "ahb", base + 0x70, 20);
+ clks[IMX6SX_CLK_TZASC1] = imx_clk_gate2("tzasc1", "mmdc_podf", base + 0x70, 22);
+ clks[IMX6SX_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "display_podf", base + 0x70, 28);
+ clks[IMX6SX_CLK_PXP_AXI] = imx_clk_gate2("pxp_axi", "display_podf", base + 0x70, 30);
+
+ /* CCGR3 */
+ clks[IMX6SX_CLK_M4] = imx_clk_gate2("m4", "m4_podf", base + 0x74, 2);
+ clks[IMX6SX_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x74, 4);
+ clks[IMX6SX_CLK_ENET_AHB] = imx_clk_gate2("enet_ahb", "enet_sel", base + 0x74, 4);
+ clks[IMX6SX_CLK_DISPLAY_AXI] = imx_clk_gate2("display_axi", "display_podf", base + 0x74, 6);
+ clks[IMX6SX_CLK_LCDIF2_PIX] = imx_clk_gate2("lcdif2_pix", "lcdif2_sel", base + 0x74, 8);
+ clks[IMX6SX_CLK_LCDIF1_PIX] = imx_clk_gate2("lcdif1_pix", "lcdif1_sel", base + 0x74, 10);
+ clks[IMX6SX_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_div_sel", base + 0x74, 12);
+ clks[IMX6SX_CLK_QSPI1] = imx_clk_gate2("qspi1", "qspi1_podf", base + 0x74, 14);
+ clks[IMX6SX_CLK_MLB] = imx_clk_gate2("mlb", "ahb", base + 0x74, 18);
+ clks[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_gate2("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20);
+ clks[IMX6SX_CLK_MMDC_P0_IPG] = imx_clk_gate2("mmdc_p0_ipg", "ipg", base + 0x74, 24);
+ clks[IMX6SX_CLK_OCRAM] = imx_clk_gate2("ocram", "ocram_podf", base + 0x74, 28);
+
+ /* CCGR4 */
+ clks[IMX6SX_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "display_podf", base + 0x78, 0);
+ clks[IMX6SX_CLK_QSPI2] = imx_clk_gate2("qspi2", "qspi2_podf", base + 0x78, 10);
+ clks[IMX6SX_CLK_PER1_BCH] = imx_clk_gate2("per1_bch", "usdhc3", base + 0x78, 12);
+ clks[IMX6SX_CLK_PER2_MAIN] = imx_clk_gate2("per2_main", "ahb", base + 0x78, 14);
+ clks[IMX6SX_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16);
+ clks[IMX6SX_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18);
+ clks[IMX6SX_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20);
+ clks[IMX6SX_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22);
+ clks[IMX6SX_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24);
+ clks[IMX6SX_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26);
+ clks[IMX6SX_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "qspi2_podf", base + 0x78, 28);
+ clks[IMX6SX_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30);
+
+ /* CCGR5 */
+ clks[IMX6SX_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0);
+ clks[IMX6SX_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6);
+ clks[IMX6SX_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
+ clks[IMX6SX_CLK_AUDIO] = imx_clk_gate2_shared("audio", "audio_podf", base + 0x7c, 14, &share_count_audio);
+ clks[IMX6SX_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio);
+ clks[IMX6SX_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1);
+ clks[IMX6SX_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2);
+ clks[IMX6SX_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3);
+ clks[IMX6SX_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1);
+ clks[IMX6SX_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2);
+ clks[IMX6SX_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3);
+ clks[IMX6SX_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24);
+ clks[IMX6SX_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_podf", base + 0x7c, 26);
+ clks[IMX6SX_CLK_SAI1_IPG] = imx_clk_gate2("sai1_ipg", "ipg", base + 0x7c, 28);
+ clks[IMX6SX_CLK_SAI2_IPG] = imx_clk_gate2("sai2_ipg", "ipg", base + 0x7c, 30);
+ clks[IMX6SX_CLK_SAI1] = imx_clk_gate2("sai1", "ssi1_podf", base + 0x7c, 28);
+ clks[IMX6SX_CLK_SAI2] = imx_clk_gate2("sai2", "ssi2_podf", base + 0x7c, 30);
+
+ /* CCGR6 */
+ clks[IMX6SX_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
+ clks[IMX6SX_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
+ clks[IMX6SX_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
+ clks[IMX6SX_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
+ clks[IMX6SX_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
+ clks[IMX6SX_CLK_EIM_SLOW] = imx_clk_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10);
+ clks[IMX6SX_CLK_PWM8] = imx_clk_gate2("pwm8", "perclk", base + 0x80, 16);
+ clks[IMX6SX_CLK_VADC] = imx_clk_gate2("vadc", "vid_podf", base + 0x80, 20);
+ clks[IMX6SX_CLK_GIS] = imx_clk_gate2("gis", "display_podf", base + 0x80, 22);
+ clks[IMX6SX_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24);
+ clks[IMX6SX_CLK_PWM5] = imx_clk_gate2("pwm5", "perclk", base + 0x80, 26);
+ clks[IMX6SX_CLK_PWM6] = imx_clk_gate2("pwm6", "perclk", base + 0x80, 28);
+ clks[IMX6SX_CLK_PWM7] = imx_clk_gate2("pwm7", "perclk", base + 0x80, 30);
+
+ clks[IMX6SX_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7);
+ clks[IMX6SX_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24);
+
+ /* mask handshake of mmdc */
+ writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
+
+ imx_check_clocks(clks, ARRAY_SIZE(clks));
+
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+ for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+ clk_prepare_enable(clks[clks_init_on[i]]);
+
+ if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
+ clk_prepare_enable(clks[IMX6SX_CLK_USBPHY1_GATE]);
+ clk_prepare_enable(clks[IMX6SX_CLK_USBPHY2_GATE]);
+ }
+
+ /* Set the default 132MHz for EIM module */
+ clk_set_parent(clks[IMX6SX_CLK_EIM_SLOW_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
+ clk_set_rate(clks[IMX6SX_CLK_EIM_SLOW], 132000000);
+
+ /* set parent clock for LCDIF1 pixel clock */
+ clk_set_parent(clks[IMX6SX_CLK_LCDIF1_PRE_SEL], clks[IMX6SX_CLK_PLL5_VIDEO_DIV]);
+ clk_set_parent(clks[IMX6SX_CLK_LCDIF1_SEL], clks[IMX6SX_CLK_LCDIF1_PODF]);
+
+ /* Set the parent clks of PCIe lvds1 and pcie_axi to be pcie ref, axi */
+ if (clk_set_parent(clks[IMX6SX_CLK_LVDS1_SEL], clks[IMX6SX_CLK_PCIE_REF_125M]))
+ pr_err("Failed to set pcie bus parent clk.\n");
+ if (clk_set_parent(clks[IMX6SX_CLK_PCIE_AXI_SEL], clks[IMX6SX_CLK_AXI]))
+ pr_err("Failed to set pcie parent clk.\n");
+
+ /*
+ * Init enet system AHB clock, set to 200Mhz
+ * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB
+ */
+ clk_set_parent(clks[IMX6SX_CLK_ENET_PRE_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
+ clk_set_parent(clks[IMX6SX_CLK_ENET_SEL], clks[IMX6SX_CLK_ENET_PODF]);
+ clk_set_rate(clks[IMX6SX_CLK_ENET_PODF], 200000000);
+ clk_set_rate(clks[IMX6SX_CLK_ENET_REF], 125000000);
+ clk_set_rate(clks[IMX6SX_CLK_ENET2_REF], 125000000);
+
+ /* Audio clocks */
+ clk_set_rate(clks[IMX6SX_CLK_PLL4_AUDIO_DIV], 393216000);
+
+ clk_set_parent(clks[IMX6SX_CLK_SPDIF_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
+ clk_set_rate(clks[IMX6SX_CLK_SPDIF_PODF], 98304000);
+
+ clk_set_parent(clks[IMX6SX_CLK_AUDIO_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]);
+ clk_set_rate(clks[IMX6SX_CLK_AUDIO_PODF], 24000000);
+
+ clk_set_parent(clks[IMX6SX_CLK_SSI1_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
+ clk_set_parent(clks[IMX6SX_CLK_SSI2_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
+ clk_set_parent(clks[IMX6SX_CLK_SSI3_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
+ clk_set_rate(clks[IMX6SX_CLK_SSI1_PODF], 24576000);
+ clk_set_rate(clks[IMX6SX_CLK_SSI2_PODF], 24576000);
+ clk_set_rate(clks[IMX6SX_CLK_SSI3_PODF], 24576000);
+
+ clk_set_parent(clks[IMX6SX_CLK_ESAI_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
+ clk_set_rate(clks[IMX6SX_CLK_ESAI_PODF], 24576000);
+
+ /* Set parent clock for vadc */
+ clk_set_parent(clks[IMX6SX_CLK_VID_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]);
+
+ /* default parent of can_sel clock is invalid, manually set it here */
+ clk_set_parent(clks[IMX6SX_CLK_CAN_SEL], clks[IMX6SX_CLK_PLL3_60M]);
+
+ /* Update gpu clock from default 528M to 720M */
+ clk_set_parent(clks[IMX6SX_CLK_GPU_CORE_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
+ clk_set_parent(clks[IMX6SX_CLK_GPU_AXI_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
+
+ clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
+ clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
+
+ /* Set initial power mode */
+ imx6q_set_lpm(WAIT_CLOCKED);
+}
+CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init);
diff --git a/arch/arm/mach-imx/clk-pfd.c b/arch/arm/mach-imx/clk-pfd.c
new file mode 100644
index 000000000..0b0f6f66e
--- /dev/null
+++ b/arch/arm/mach-imx/clk-pfd.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * 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/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include "clk.h"
+
+/**
+ * struct clk_pfd - IMX PFD clock
+ * @clk_hw: clock source
+ * @reg: PFD register address
+ * @idx: the index of PFD encoded in the register
+ *
+ * PFD clock found on i.MX6 series. Each register for PFD has 4 clk_pfd
+ * data encoded, and member idx is used to specify the one. And each
+ * register has SET, CLR and TOG registers at offset 0x4 0x8 and 0xc.
+ */
+struct clk_pfd {
+ struct clk_hw hw;
+ void __iomem *reg;
+ u8 idx;
+};
+
+#define to_clk_pfd(_hw) container_of(_hw, struct clk_pfd, hw)
+
+#define SET 0x4
+#define CLR 0x8
+#define OTG 0xc
+
+static int clk_pfd_enable(struct clk_hw *hw)
+{
+ struct clk_pfd *pfd = to_clk_pfd(hw);
+
+ writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + CLR);
+
+ return 0;
+}
+
+static void clk_pfd_disable(struct clk_hw *hw)
+{
+ struct clk_pfd *pfd = to_clk_pfd(hw);
+
+ writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + SET);
+}
+
+static unsigned long clk_pfd_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pfd *pfd = to_clk_pfd(hw);
+ u64 tmp = parent_rate;
+ u8 frac = (readl_relaxed(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
+
+ tmp *= 18;
+ do_div(tmp, frac);
+
+ return tmp;
+}
+
+static long clk_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ u64 tmp = *prate;
+ u8 frac;
+
+ tmp = tmp * 18 + rate / 2;
+ do_div(tmp, rate);
+ frac = tmp;
+ if (frac < 12)
+ frac = 12;
+ else if (frac > 35)
+ frac = 35;
+ tmp = *prate;
+ tmp *= 18;
+ do_div(tmp, frac);
+
+ return tmp;
+}
+
+static int clk_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pfd *pfd = to_clk_pfd(hw);
+ u64 tmp = parent_rate;
+ u8 frac;
+
+ tmp = tmp * 18 + rate / 2;
+ do_div(tmp, rate);
+ frac = tmp;
+ if (frac < 12)
+ frac = 12;
+ else if (frac > 35)
+ frac = 35;
+
+ writel_relaxed(0x3f << (pfd->idx * 8), pfd->reg + CLR);
+ writel_relaxed(frac << (pfd->idx * 8), pfd->reg + SET);
+
+ return 0;
+}
+
+static int clk_pfd_is_enabled(struct clk_hw *hw)
+{
+ struct clk_pfd *pfd = to_clk_pfd(hw);
+
+ if (readl_relaxed(pfd->reg) & (1 << ((pfd->idx + 1) * 8 - 1)))
+ return 0;
+
+ return 1;
+}
+
+static const struct clk_ops clk_pfd_ops = {
+ .enable = clk_pfd_enable,
+ .disable = clk_pfd_disable,
+ .recalc_rate = clk_pfd_recalc_rate,
+ .round_rate = clk_pfd_round_rate,
+ .set_rate = clk_pfd_set_rate,
+ .is_enabled = clk_pfd_is_enabled,
+};
+
+struct clk *imx_clk_pfd(const char *name, const char *parent_name,
+ void __iomem *reg, u8 idx)
+{
+ struct clk_pfd *pfd;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pfd = kzalloc(sizeof(*pfd), GFP_KERNEL);
+ if (!pfd)
+ return ERR_PTR(-ENOMEM);
+
+ pfd->reg = reg;
+ pfd->idx = idx;
+
+ init.name = name;
+ init.ops = &clk_pfd_ops;
+ init.flags = 0;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ pfd->hw.init = &init;
+
+ clk = clk_register(NULL, &pfd->hw);
+ if (IS_ERR(clk))
+ kfree(pfd);
+
+ return clk;
+}
diff --git a/arch/arm/mach-imx/clk-pllv1.c b/arch/arm/mach-imx/clk-pllv1.c
new file mode 100644
index 000000000..d21d14ca4
--- /dev/null
+++ b/arch/arm/mach-imx/clk-pllv1.c
@@ -0,0 +1,126 @@
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+
+#include "clk.h"
+#include "common.h"
+#include "hardware.h"
+
+/**
+ * pll v1
+ *
+ * @clk_hw clock source
+ * @parent the parent clock name
+ * @base base address of pll registers
+ *
+ * PLL clock version 1, found on i.MX1/21/25/27/31/35
+ */
+
+#define MFN_BITS (10)
+#define MFN_SIGN (BIT(MFN_BITS - 1))
+#define MFN_MASK (MFN_SIGN - 1)
+
+struct clk_pllv1 {
+ struct clk_hw hw;
+ void __iomem *base;
+};
+
+#define to_clk_pllv1(clk) (container_of(clk, struct clk_pllv1, clk))
+
+static inline bool mfn_is_negative(unsigned int mfn)
+{
+ return !cpu_is_mx1() && !cpu_is_mx21() && (mfn & MFN_SIGN);
+}
+
+static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pllv1 *pll = to_clk_pllv1(hw);
+ long long ll;
+ int mfn_abs;
+ unsigned int mfi, mfn, mfd, pd;
+ u32 reg;
+ unsigned long rate;
+
+ reg = readl(pll->base);
+
+ /*
+ * Get the resulting clock rate from a PLL register value and the input
+ * frequency. PLLs with this register layout can be found on i.MX1,
+ * i.MX21, i.MX27 and i,MX31
+ *
+ * mfi + mfn / (mfd + 1)
+ * f = 2 * f_ref * --------------------
+ * pd + 1
+ */
+
+ mfi = (reg >> 10) & 0xf;
+ mfn = reg & 0x3ff;
+ mfd = (reg >> 16) & 0x3ff;
+ pd = (reg >> 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.
+ * On i.MX27 the bit 9 is the sign bit.
+ */
+ if (mfn_is_negative(mfn)) {
+ if (cpu_is_mx27())
+ mfn_abs = mfn & MFN_MASK;
+ else
+ mfn_abs = BIT(MFN_BITS) - mfn;
+ }
+
+ rate = parent_rate * 2;
+ rate /= pd + 1;
+
+ ll = (unsigned long long)rate * mfn_abs;
+
+ do_div(ll, mfd + 1);
+
+ if (mfn_is_negative(mfn))
+ ll = -ll;
+
+ ll = (rate * mfi) + ll;
+
+ return ll;
+}
+
+static struct clk_ops clk_pllv1_ops = {
+ .recalc_rate = clk_pllv1_recalc_rate,
+};
+
+struct clk *imx_clk_pllv1(const char *name, const char *parent,
+ void __iomem *base)
+{
+ struct clk_pllv1 *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kmalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->base = base;
+
+ init.name = name;
+ init.ops = &clk_pllv1_ops;
+ init.flags = 0;
+ init.parent_names = &parent;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
diff --git a/arch/arm/mach-imx/clk-pllv2.c b/arch/arm/mach-imx/clk-pllv2.c
new file mode 100644
index 000000000..20889d59b
--- /dev/null
+++ b/arch/arm/mach-imx/clk-pllv2.c
@@ -0,0 +1,266 @@
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+
+#include <asm/div64.h>
+
+#include "clk.h"
+
+#define to_clk_pllv2(clk) (container_of(clk, struct clk_pllv2, clk))
+
+/* 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
+
+#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
+
+struct clk_pllv2 {
+ struct clk_hw hw;
+ void __iomem *base;
+};
+
+static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate,
+ u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn)
+{
+ long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+ unsigned long dbl;
+ s64 temp;
+
+ dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
+
+ 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 unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ u32 dp_op, dp_mfd, dp_mfn, dp_ctl;
+ void __iomem *pllbase;
+ struct clk_pllv2 *pll = to_clk_pllv2(hw);
+
+ pllbase = pll->base;
+
+ dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ 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);
+
+ return __clk_pllv2_recalc_rate(parent_rate, dp_ctl, dp_op, dp_mfd, dp_mfn);
+}
+
+static int __clk_pllv2_set_rate(unsigned long rate, unsigned long parent_rate,
+ u32 *dp_op, u32 *dp_mfd, u32 *dp_mfn)
+{
+ u32 reg;
+ long mfi, pdf, mfn, mfd = 999999;
+ s64 temp64;
+ unsigned long quad_parent_rate;
+
+ 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;
+
+ reg = mfi << 4 | pdf;
+
+ *dp_op = reg;
+ *dp_mfd = mfd;
+ *dp_mfn = mfn;
+
+ return 0;
+}
+
+static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pllv2 *pll = to_clk_pllv2(hw);
+ void __iomem *pllbase;
+ u32 dp_ctl, dp_op, dp_mfd, dp_mfn;
+ int ret;
+
+ pllbase = pll->base;
+
+
+ ret = __clk_pllv2_set_rate(rate, parent_rate, &dp_op, &dp_mfd, &dp_mfn);
+ if (ret)
+ return ret;
+
+ dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ /* use dpdck0_2 */
+ __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
+
+ __raw_writel(dp_op, pllbase + MXC_PLL_DP_OP);
+ __raw_writel(dp_mfd, pllbase + MXC_PLL_DP_MFD);
+ __raw_writel(dp_mfn, pllbase + MXC_PLL_DP_MFN);
+
+ return 0;
+}
+
+static long clk_pllv2_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ u32 dp_op, dp_mfd, dp_mfn;
+
+ __clk_pllv2_set_rate(rate, *prate, &dp_op, &dp_mfd, &dp_mfn);
+ return __clk_pllv2_recalc_rate(*prate, MXC_PLL_DP_CTL_DPDCK0_2_EN,
+ dp_op, dp_mfd, dp_mfn);
+}
+
+static int clk_pllv2_prepare(struct clk_hw *hw)
+{
+ struct clk_pllv2 *pll = to_clk_pllv2(hw);
+ u32 reg;
+ void __iomem *pllbase;
+ int i = 0;
+
+ pllbase = pll->base;
+ 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_pllv2_unprepare(struct clk_hw *hw)
+{
+ struct clk_pllv2 *pll = to_clk_pllv2(hw);
+ u32 reg;
+ void __iomem *pllbase;
+
+ pllbase = pll->base;
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+}
+
+static struct clk_ops clk_pllv2_ops = {
+ .prepare = clk_pllv2_prepare,
+ .unprepare = clk_pllv2_unprepare,
+ .recalc_rate = clk_pllv2_recalc_rate,
+ .round_rate = clk_pllv2_round_rate,
+ .set_rate = clk_pllv2_set_rate,
+};
+
+struct clk *imx_clk_pllv2(const char *name, const char *parent,
+ void __iomem *base)
+{
+ struct clk_pllv2 *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->base = base;
+
+ init.name = name;
+ init.ops = &clk_pllv2_ops;
+ init.flags = 0;
+ init.parent_names = &parent;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c
new file mode 100644
index 000000000..641ebc508
--- /dev/null
+++ b/arch/arm/mach-imx/clk-pllv3.c
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * 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/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/err.h>
+#include "clk.h"
+
+#define PLL_NUM_OFFSET 0x10
+#define PLL_DENOM_OFFSET 0x20
+
+#define BM_PLL_POWER (0x1 << 12)
+#define BM_PLL_LOCK (0x1 << 31)
+
+/**
+ * struct clk_pllv3 - IMX PLL clock version 3
+ * @clk_hw: clock source
+ * @base: base address of PLL registers
+ * @powerup_set: set POWER bit to power up the PLL
+ * @div_mask: mask of divider bits
+ * @div_shift: shift of divider bits
+ *
+ * IMX PLL clock version 3, found on i.MX6 series. Divider for pllv3
+ * is actually a multiplier, and always sits at bit 0.
+ */
+struct clk_pllv3 {
+ struct clk_hw hw;
+ void __iomem *base;
+ bool powerup_set;
+ u32 div_mask;
+ u32 div_shift;
+};
+
+#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
+
+static int clk_pllv3_wait_lock(struct clk_pllv3 *pll)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(10);
+ u32 val = readl_relaxed(pll->base) & BM_PLL_POWER;
+
+ /* No need to wait for lock when pll is not powered up */
+ if ((pll->powerup_set && !val) || (!pll->powerup_set && val))
+ return 0;
+
+ /* Wait for PLL to lock */
+ do {
+ if (readl_relaxed(pll->base) & BM_PLL_LOCK)
+ break;
+ if (time_after(jiffies, timeout))
+ break;
+ usleep_range(50, 500);
+ } while (1);
+
+ return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT;
+}
+
+static int clk_pllv3_prepare(struct clk_hw *hw)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ u32 val;
+
+ val = readl_relaxed(pll->base);
+ if (pll->powerup_set)
+ val |= BM_PLL_POWER;
+ else
+ val &= ~BM_PLL_POWER;
+ writel_relaxed(val, pll->base);
+
+ return clk_pllv3_wait_lock(pll);
+}
+
+static void clk_pllv3_unprepare(struct clk_hw *hw)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ u32 val;
+
+ val = readl_relaxed(pll->base);
+ if (pll->powerup_set)
+ val &= ~BM_PLL_POWER;
+ else
+ val |= BM_PLL_POWER;
+ writel_relaxed(val, pll->base);
+}
+
+static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ u32 div = (readl_relaxed(pll->base) >> pll->div_shift) & pll->div_mask;
+
+ return (div == 1) ? parent_rate * 22 : parent_rate * 20;
+}
+
+static long clk_pllv3_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ unsigned long parent_rate = *prate;
+
+ return (rate >= parent_rate * 22) ? parent_rate * 22 :
+ parent_rate * 20;
+}
+
+static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ u32 val, div;
+
+ if (rate == parent_rate * 22)
+ div = 1;
+ else if (rate == parent_rate * 20)
+ div = 0;
+ else
+ return -EINVAL;
+
+ val = readl_relaxed(pll->base);
+ val &= ~(pll->div_mask << pll->div_shift);
+ val |= (div << pll->div_shift);
+ writel_relaxed(val, pll->base);
+
+ return clk_pllv3_wait_lock(pll);
+}
+
+static const struct clk_ops clk_pllv3_ops = {
+ .prepare = clk_pllv3_prepare,
+ .unprepare = clk_pllv3_unprepare,
+ .recalc_rate = clk_pllv3_recalc_rate,
+ .round_rate = clk_pllv3_round_rate,
+ .set_rate = clk_pllv3_set_rate,
+};
+
+static unsigned long clk_pllv3_sys_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ u32 div = readl_relaxed(pll->base) & pll->div_mask;
+
+ return parent_rate * div / 2;
+}
+
+static long clk_pllv3_sys_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ unsigned long parent_rate = *prate;
+ unsigned long min_rate = parent_rate * 54 / 2;
+ unsigned long max_rate = parent_rate * 108 / 2;
+ u32 div;
+
+ if (rate > max_rate)
+ rate = max_rate;
+ else if (rate < min_rate)
+ rate = min_rate;
+ div = rate * 2 / parent_rate;
+
+ return parent_rate * div / 2;
+}
+
+static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ unsigned long min_rate = parent_rate * 54 / 2;
+ unsigned long max_rate = parent_rate * 108 / 2;
+ u32 val, div;
+
+ if (rate < min_rate || rate > max_rate)
+ return -EINVAL;
+
+ div = rate * 2 / parent_rate;
+ val = readl_relaxed(pll->base);
+ val &= ~pll->div_mask;
+ val |= div;
+ writel_relaxed(val, pll->base);
+
+ return clk_pllv3_wait_lock(pll);
+}
+
+static const struct clk_ops clk_pllv3_sys_ops = {
+ .prepare = clk_pllv3_prepare,
+ .unprepare = clk_pllv3_unprepare,
+ .recalc_rate = clk_pllv3_sys_recalc_rate,
+ .round_rate = clk_pllv3_sys_round_rate,
+ .set_rate = clk_pllv3_sys_set_rate,
+};
+
+static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
+ u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
+ u32 div = readl_relaxed(pll->base) & pll->div_mask;
+
+ return (parent_rate * div) + ((parent_rate / mfd) * mfn);
+}
+
+static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ unsigned long parent_rate = *prate;
+ unsigned long min_rate = parent_rate * 27;
+ unsigned long max_rate = parent_rate * 54;
+ u32 div;
+ u32 mfn, mfd = 1000000;
+ s64 temp64;
+
+ if (rate > max_rate)
+ rate = max_rate;
+ else if (rate < min_rate)
+ rate = min_rate;
+
+ div = rate / parent_rate;
+ temp64 = (u64) (rate - div * parent_rate);
+ temp64 *= mfd;
+ do_div(temp64, parent_rate);
+ mfn = temp64;
+
+ return parent_rate * div + parent_rate / mfd * mfn;
+}
+
+static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ unsigned long min_rate = parent_rate * 27;
+ unsigned long max_rate = parent_rate * 54;
+ u32 val, div;
+ u32 mfn, mfd = 1000000;
+ s64 temp64;
+
+ if (rate < min_rate || rate > max_rate)
+ return -EINVAL;
+
+ div = rate / parent_rate;
+ temp64 = (u64) (rate - div * parent_rate);
+ temp64 *= mfd;
+ do_div(temp64, parent_rate);
+ mfn = temp64;
+
+ val = readl_relaxed(pll->base);
+ val &= ~pll->div_mask;
+ val |= div;
+ writel_relaxed(val, pll->base);
+ writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
+ writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
+
+ return clk_pllv3_wait_lock(pll);
+}
+
+static const struct clk_ops clk_pllv3_av_ops = {
+ .prepare = clk_pllv3_prepare,
+ .unprepare = clk_pllv3_unprepare,
+ .recalc_rate = clk_pllv3_av_recalc_rate,
+ .round_rate = clk_pllv3_av_round_rate,
+ .set_rate = clk_pllv3_av_set_rate,
+};
+
+static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ return 500000000;
+}
+
+static const struct clk_ops clk_pllv3_enet_ops = {
+ .prepare = clk_pllv3_prepare,
+ .unprepare = clk_pllv3_unprepare,
+ .recalc_rate = clk_pllv3_enet_recalc_rate,
+};
+
+struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
+ const char *parent_name, void __iomem *base,
+ u32 div_mask)
+{
+ struct clk_pllv3 *pll;
+ const struct clk_ops *ops;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ switch (type) {
+ case IMX_PLLV3_SYS:
+ ops = &clk_pllv3_sys_ops;
+ break;
+ case IMX_PLLV3_USB_VF610:
+ pll->div_shift = 1;
+ case IMX_PLLV3_USB:
+ ops = &clk_pllv3_ops;
+ pll->powerup_set = true;
+ break;
+ case IMX_PLLV3_AV:
+ ops = &clk_pllv3_av_ops;
+ break;
+ case IMX_PLLV3_ENET:
+ ops = &clk_pllv3_enet_ops;
+ break;
+ default:
+ ops = &clk_pllv3_ops;
+ }
+ pll->base = base;
+ pll->div_mask = div_mask;
+
+ init.name = name;
+ init.ops = ops;
+ init.flags = 0;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c
new file mode 100644
index 000000000..61876ed6e
--- /dev/null
+++ b/arch/arm/mach-imx/clk-vf610.c
@@ -0,0 +1,412 @@
+/*
+ * Copyright 2012-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.
+ *
+ */
+
+#include <linux/of_address.h>
+#include <linux/clk.h>
+#include <dt-bindings/clock/vf610-clock.h>
+
+#include "clk.h"
+
+#define CCM_CCR (ccm_base + 0x00)
+#define CCM_CSR (ccm_base + 0x04)
+#define CCM_CCSR (ccm_base + 0x08)
+#define CCM_CACRR (ccm_base + 0x0c)
+#define CCM_CSCMR1 (ccm_base + 0x10)
+#define CCM_CSCDR1 (ccm_base + 0x14)
+#define CCM_CSCDR2 (ccm_base + 0x18)
+#define CCM_CSCDR3 (ccm_base + 0x1c)
+#define CCM_CSCMR2 (ccm_base + 0x20)
+#define CCM_CSCDR4 (ccm_base + 0x24)
+#define CCM_CLPCR (ccm_base + 0x2c)
+#define CCM_CISR (ccm_base + 0x30)
+#define CCM_CIMR (ccm_base + 0x34)
+#define CCM_CGPR (ccm_base + 0x3c)
+#define CCM_CCGR0 (ccm_base + 0x40)
+#define CCM_CCGR1 (ccm_base + 0x44)
+#define CCM_CCGR2 (ccm_base + 0x48)
+#define CCM_CCGR3 (ccm_base + 0x4c)
+#define CCM_CCGR4 (ccm_base + 0x50)
+#define CCM_CCGR5 (ccm_base + 0x54)
+#define CCM_CCGR6 (ccm_base + 0x58)
+#define CCM_CCGR7 (ccm_base + 0x5c)
+#define CCM_CCGR8 (ccm_base + 0x60)
+#define CCM_CCGR9 (ccm_base + 0x64)
+#define CCM_CCGR10 (ccm_base + 0x68)
+#define CCM_CCGR11 (ccm_base + 0x6c)
+#define CCM_CMEOR0 (ccm_base + 0x70)
+#define CCM_CMEOR1 (ccm_base + 0x74)
+#define CCM_CMEOR2 (ccm_base + 0x78)
+#define CCM_CMEOR3 (ccm_base + 0x7c)
+#define CCM_CMEOR4 (ccm_base + 0x80)
+#define CCM_CMEOR5 (ccm_base + 0x84)
+#define CCM_CPPDSR (ccm_base + 0x88)
+#define CCM_CCOWR (ccm_base + 0x8c)
+#define CCM_CCPGR0 (ccm_base + 0x90)
+#define CCM_CCPGR1 (ccm_base + 0x94)
+#define CCM_CCPGR2 (ccm_base + 0x98)
+#define CCM_CCPGR3 (ccm_base + 0x9c)
+
+#define CCM_CCGRx_CGn(n) ((n) * 2)
+
+#define PFD_PLL1_BASE (anatop_base + 0x2b0)
+#define PFD_PLL2_BASE (anatop_base + 0x100)
+#define PFD_PLL3_BASE (anatop_base + 0xf0)
+#define PLL1_CTRL (anatop_base + 0x270)
+#define PLL2_CTRL (anatop_base + 0x30)
+#define PLL3_CTRL (anatop_base + 0x10)
+#define PLL4_CTRL (anatop_base + 0x70)
+#define PLL5_CTRL (anatop_base + 0xe0)
+#define PLL6_CTRL (anatop_base + 0xa0)
+#define PLL7_CTRL (anatop_base + 0x20)
+#define ANA_MISC1 (anatop_base + 0x160)
+
+static void __iomem *anatop_base;
+static void __iomem *ccm_base;
+
+/* sources for multiplexer clocks, this is used multiple times */
+static const char *fast_sels[] = { "firc", "fxosc", };
+static const char *slow_sels[] = { "sirc_32k", "sxosc", };
+static const char *pll1_sels[] = { "pll1_sys", "pll1_pfd1", "pll1_pfd2", "pll1_pfd3", "pll1_pfd4", };
+static const char *pll2_sels[] = { "pll2_bus", "pll2_pfd1", "pll2_pfd2", "pll2_pfd3", "pll2_pfd4", };
+static const char *pll_bypass_src_sels[] = { "fast_clk_sel", "lvds1_in", };
+static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
+static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
+static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
+static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
+static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
+static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
+static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
+static const char *sys_sels[] = { "fast_clk_sel", "slow_clk_sel", "pll2_pfd_sel", "pll2_bus", "pll1_pfd_sel", "pll3_usb_otg", };
+static const char *ddr_sels[] = { "pll2_pfd2", "sys_sel", };
+static const char *rmii_sels[] = { "enet_ext", "audio_ext", "enet_50m", "enet_25m", };
+static const char *enet_ts_sels[] = { "enet_ext", "fxosc", "audio_ext", "usb", "enet_ts", "enet_25m", "enet_50m", };
+static const char *esai_sels[] = { "audio_ext", "mlb", "spdif_rx", "pll4_audio_div", };
+static const char *sai_sels[] = { "audio_ext", "mlb", "spdif_rx", "pll4_audio_div", };
+static const char *nfc_sels[] = { "platform_bus", "pll1_pfd1", "pll3_pfd1", "pll3_pfd3", };
+static const char *qspi_sels[] = { "pll3_usb_otg", "pll3_pfd4", "pll2_pfd4", "pll1_pfd4", };
+static const char *esdhc_sels[] = { "pll3_usb_otg", "pll3_pfd3", "pll1_pfd3", "platform_bus", };
+static const char *dcu_sels[] = { "pll1_pfd2", "pll3_usb_otg", };
+static const char *gpu_sels[] = { "pll2_pfd2", "pll3_pfd2", };
+static const char *vadc_sels[] = { "pll6_video_div", "pll3_usb_otg_div", "pll3_usb_otg", };
+/* FTM counter clock source, not module clock */
+static const char *ftm_ext_sels[] = {"sirc_128k", "sxosc", "fxosc_half", "audio_ext", };
+static const char *ftm_fix_sels[] = { "sxosc", "ipg_bus", };
+
+
+static struct clk_div_table pll4_audio_div_table[] = {
+ { .val = 0, .div = 1 },
+ { .val = 1, .div = 2 },
+ { .val = 2, .div = 6 },
+ { .val = 3, .div = 8 },
+ { .val = 4, .div = 10 },
+ { .val = 5, .div = 12 },
+ { .val = 6, .div = 14 },
+ { .val = 7, .div = 16 },
+ { }
+};
+
+static struct clk *clk[VF610_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static unsigned int const clks_init_on[] __initconst = {
+ VF610_CLK_SYS_BUS,
+ VF610_CLK_DDR_SEL,
+};
+
+static struct clk * __init vf610_get_fixed_clock(
+ struct device_node *ccm_node, const char *name)
+{
+ struct clk *clk = of_clk_get_by_name(ccm_node, name);
+
+ /* Backward compatibility if device tree is missing clks assignments */
+ if (IS_ERR(clk))
+ clk = imx_obtain_fixed_clock(name, 0);
+ return clk;
+};
+
+static void __init vf610_clocks_init(struct device_node *ccm_node)
+{
+ struct device_node *np;
+ int i;
+
+ clk[VF610_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+ clk[VF610_CLK_SIRC_128K] = imx_clk_fixed("sirc_128k", 128000);
+ clk[VF610_CLK_SIRC_32K] = imx_clk_fixed("sirc_32k", 32000);
+ clk[VF610_CLK_FIRC] = imx_clk_fixed("firc", 24000000);
+
+ clk[VF610_CLK_SXOSC] = vf610_get_fixed_clock(ccm_node, "sxosc");
+ clk[VF610_CLK_FXOSC] = vf610_get_fixed_clock(ccm_node, "fxosc");
+ clk[VF610_CLK_AUDIO_EXT] = vf610_get_fixed_clock(ccm_node, "audio_ext");
+ clk[VF610_CLK_ENET_EXT] = vf610_get_fixed_clock(ccm_node, "enet_ext");
+
+ /* Clock source from external clock via LVDs PAD */
+ clk[VF610_CLK_ANACLK1] = vf610_get_fixed_clock(ccm_node, "anaclk1");
+
+ clk[VF610_CLK_FXOSC_HALF] = imx_clk_fixed_factor("fxosc_half", "fxosc", 1, 2);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,vf610-anatop");
+ anatop_base = of_iomap(np, 0);
+ BUG_ON(!anatop_base);
+
+ np = ccm_node;
+ ccm_base = of_iomap(np, 0);
+ BUG_ON(!ccm_base);
+
+ clk[VF610_CLK_SLOW_CLK_SEL] = imx_clk_mux("slow_clk_sel", CCM_CCSR, 4, 1, slow_sels, ARRAY_SIZE(slow_sels));
+ clk[VF610_CLK_FASK_CLK_SEL] = imx_clk_mux("fast_clk_sel", CCM_CCSR, 5, 1, fast_sels, ARRAY_SIZE(fast_sels));
+
+ clk[VF610_CLK_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", PLL1_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[VF610_CLK_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", PLL2_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[VF610_CLK_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", PLL3_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[VF610_CLK_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", PLL4_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[VF610_CLK_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", PLL5_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[VF610_CLK_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", PLL6_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[VF610_CLK_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", PLL7_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+
+ clk[VF610_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll1", "pll1_bypass_src", PLL1_CTRL, 0x1);
+ clk[VF610_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", PLL2_CTRL, 0x1);
+ clk[VF610_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB_VF610, "pll3", "pll3_bypass_src", PLL3_CTRL, 0x2);
+ clk[VF610_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", PLL4_CTRL, 0x7f);
+ clk[VF610_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll5", "pll5_bypass_src", PLL5_CTRL, 0x3);
+ clk[VF610_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_AV, "pll6", "pll6_bypass_src", PLL6_CTRL, 0x7f);
+ clk[VF610_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB_VF610, "pll7", "pll7_bypass_src", PLL7_CTRL, 0x2);
+
+ clk[VF610_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", PLL1_CTRL, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[VF610_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", PLL2_CTRL, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[VF610_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", PLL3_CTRL, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[VF610_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", PLL4_CTRL, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[VF610_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", PLL5_CTRL, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[VF610_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", PLL6_CTRL, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[VF610_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", PLL7_CTRL, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
+
+ /* Do not bypass PLLs initially */
+ clk_set_parent(clk[VF610_PLL1_BYPASS], clk[VF610_CLK_PLL1]);
+ clk_set_parent(clk[VF610_PLL2_BYPASS], clk[VF610_CLK_PLL2]);
+ clk_set_parent(clk[VF610_PLL3_BYPASS], clk[VF610_CLK_PLL3]);
+ clk_set_parent(clk[VF610_PLL4_BYPASS], clk[VF610_CLK_PLL4]);
+ clk_set_parent(clk[VF610_PLL5_BYPASS], clk[VF610_CLK_PLL5]);
+ clk_set_parent(clk[VF610_PLL6_BYPASS], clk[VF610_CLK_PLL6]);
+ clk_set_parent(clk[VF610_PLL7_BYPASS], clk[VF610_CLK_PLL7]);
+
+ clk[VF610_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", PLL1_CTRL, 13);
+ clk[VF610_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", PLL2_CTRL, 13);
+ clk[VF610_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", PLL3_CTRL, 13);
+ clk[VF610_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", PLL4_CTRL, 13);
+ clk[VF610_CLK_PLL5_ENET] = imx_clk_gate("pll5_enet", "pll5_bypass", PLL5_CTRL, 13);
+ clk[VF610_CLK_PLL6_VIDEO] = imx_clk_gate("pll6_video", "pll6_bypass", PLL6_CTRL, 13);
+ clk[VF610_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", PLL7_CTRL, 13);
+
+ clk[VF610_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", ANA_MISC1, 12, BIT(10));
+
+ clk[VF610_CLK_PLL1_PFD1] = imx_clk_pfd("pll1_pfd1", "pll1_sys", PFD_PLL1_BASE, 0);
+ clk[VF610_CLK_PLL1_PFD2] = imx_clk_pfd("pll1_pfd2", "pll1_sys", PFD_PLL1_BASE, 1);
+ clk[VF610_CLK_PLL1_PFD3] = imx_clk_pfd("pll1_pfd3", "pll1_sys", PFD_PLL1_BASE, 2);
+ clk[VF610_CLK_PLL1_PFD4] = imx_clk_pfd("pll1_pfd4", "pll1_sys", PFD_PLL1_BASE, 3);
+
+ clk[VF610_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1", "pll2_bus", PFD_PLL2_BASE, 0);
+ clk[VF610_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2", "pll2_bus", PFD_PLL2_BASE, 1);
+ clk[VF610_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3", "pll2_bus", PFD_PLL2_BASE, 2);
+ clk[VF610_CLK_PLL2_PFD4] = imx_clk_pfd("pll2_pfd4", "pll2_bus", PFD_PLL2_BASE, 3);
+
+ clk[VF610_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1", "pll3_usb_otg", PFD_PLL3_BASE, 0);
+ clk[VF610_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_usb_otg", PFD_PLL3_BASE, 1);
+ clk[VF610_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_usb_otg", PFD_PLL3_BASE, 2);
+ clk[VF610_CLK_PLL3_PFD4] = imx_clk_pfd("pll3_pfd4", "pll3_usb_otg", PFD_PLL3_BASE, 3);
+
+ clk[VF610_CLK_PLL1_PFD_SEL] = imx_clk_mux("pll1_pfd_sel", CCM_CCSR, 16, 3, pll1_sels, 5);
+ clk[VF610_CLK_PLL2_PFD_SEL] = imx_clk_mux("pll2_pfd_sel", CCM_CCSR, 19, 3, pll2_sels, 5);
+ clk[VF610_CLK_SYS_SEL] = imx_clk_mux("sys_sel", CCM_CCSR, 0, 3, sys_sels, ARRAY_SIZE(sys_sels));
+ clk[VF610_CLK_DDR_SEL] = imx_clk_mux("ddr_sel", CCM_CCSR, 6, 1, ddr_sels, ARRAY_SIZE(ddr_sels));
+ clk[VF610_CLK_SYS_BUS] = imx_clk_divider("sys_bus", "sys_sel", CCM_CACRR, 0, 3);
+ clk[VF610_CLK_PLATFORM_BUS] = imx_clk_divider("platform_bus", "sys_bus", CCM_CACRR, 3, 3);
+ clk[VF610_CLK_IPG_BUS] = imx_clk_divider("ipg_bus", "platform_bus", CCM_CACRR, 11, 2);
+
+ clk[VF610_CLK_PLL3_MAIN_DIV] = imx_clk_divider("pll3_usb_otg_div", "pll3_usb_otg", CCM_CACRR, 20, 1);
+ clk[VF610_CLK_PLL4_MAIN_DIV] = clk_register_divider_table(NULL, "pll4_audio_div", "pll4_audio", 0, CCM_CACRR, 6, 3, 0, pll4_audio_div_table, &imx_ccm_lock);
+ clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_video_div", "pll6_video", CCM_CACRR, 21, 1);
+
+ clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_usb_otg", PLL3_CTRL, 6);
+ clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_usb_host", PLL7_CTRL, 6);
+
+ clk[VF610_CLK_USBC0] = imx_clk_gate2("usbc0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(4));
+ clk[VF610_CLK_USBC1] = imx_clk_gate2("usbc1", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(4));
+
+ clk[VF610_CLK_QSPI0_SEL] = imx_clk_mux("qspi0_sel", CCM_CSCMR1, 22, 2, qspi_sels, 4);
+ clk[VF610_CLK_QSPI0_EN] = imx_clk_gate("qspi0_en", "qspi0_sel", CCM_CSCDR3, 4);
+ clk[VF610_CLK_QSPI0_X4_DIV] = imx_clk_divider("qspi0_x4", "qspi0_en", CCM_CSCDR3, 0, 2);
+ clk[VF610_CLK_QSPI0_X2_DIV] = imx_clk_divider("qspi0_x2", "qspi0_x4", CCM_CSCDR3, 2, 1);
+ clk[VF610_CLK_QSPI0_X1_DIV] = imx_clk_divider("qspi0_x1", "qspi0_x2", CCM_CSCDR3, 3, 1);
+ clk[VF610_CLK_QSPI0] = imx_clk_gate2("qspi0", "qspi0_x1", CCM_CCGR2, CCM_CCGRx_CGn(4));
+
+ clk[VF610_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", CCM_CSCMR1, 24, 2, qspi_sels, 4);
+ clk[VF610_CLK_QSPI1_EN] = imx_clk_gate("qspi1_en", "qspi1_sel", CCM_CSCDR3, 12);
+ clk[VF610_CLK_QSPI1_X4_DIV] = imx_clk_divider("qspi1_x4", "qspi1_en", CCM_CSCDR3, 8, 2);
+ clk[VF610_CLK_QSPI1_X2_DIV] = imx_clk_divider("qspi1_x2", "qspi1_x4", CCM_CSCDR3, 10, 1);
+ clk[VF610_CLK_QSPI1_X1_DIV] = imx_clk_divider("qspi1_x1", "qspi1_x2", CCM_CSCDR3, 11, 1);
+ clk[VF610_CLK_QSPI1] = imx_clk_gate2("qspi1", "qspi1_x1", CCM_CCGR8, CCM_CCGRx_CGn(4));
+
+ clk[VF610_CLK_ENET_50M] = imx_clk_fixed_factor("enet_50m", "pll5_enet", 1, 10);
+ clk[VF610_CLK_ENET_25M] = imx_clk_fixed_factor("enet_25m", "pll5_enet", 1, 20);
+ clk[VF610_CLK_ENET_SEL] = imx_clk_mux("enet_sel", CCM_CSCMR2, 4, 2, rmii_sels, 4);
+ clk[VF610_CLK_ENET_TS_SEL] = imx_clk_mux("enet_ts_sel", CCM_CSCMR2, 0, 3, enet_ts_sels, 7);
+ clk[VF610_CLK_ENET] = imx_clk_gate("enet", "enet_sel", CCM_CSCDR1, 24);
+ clk[VF610_CLK_ENET_TS] = imx_clk_gate("enet_ts", "enet_ts_sel", CCM_CSCDR1, 23);
+ clk[VF610_CLK_ENET0] = imx_clk_gate2("enet0", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(0));
+ clk[VF610_CLK_ENET1] = imx_clk_gate2("enet1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(1));
+
+ clk[VF610_CLK_PIT] = imx_clk_gate2("pit", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(7));
+
+ clk[VF610_CLK_UART0] = imx_clk_gate2("uart0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(7));
+ clk[VF610_CLK_UART1] = imx_clk_gate2("uart1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(8));
+ clk[VF610_CLK_UART2] = imx_clk_gate2("uart2", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(9));
+ clk[VF610_CLK_UART3] = imx_clk_gate2("uart3", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(10));
+ clk[VF610_CLK_UART4] = imx_clk_gate2("uart4", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(9));
+ clk[VF610_CLK_UART5] = imx_clk_gate2("uart5", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(10));
+
+ clk[VF610_CLK_I2C0] = imx_clk_gate2("i2c0", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(6));
+ clk[VF610_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(7));
+
+ clk[VF610_CLK_DSPI0] = imx_clk_gate2("dspi0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(12));
+ clk[VF610_CLK_DSPI1] = imx_clk_gate2("dspi1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(13));
+ clk[VF610_CLK_DSPI2] = imx_clk_gate2("dspi2", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(12));
+ clk[VF610_CLK_DSPI3] = imx_clk_gate2("dspi3", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(13));
+
+ clk[VF610_CLK_WDT] = imx_clk_gate2("wdt", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(14));
+
+ clk[VF610_CLK_ESDHC0_SEL] = imx_clk_mux("esdhc0_sel", CCM_CSCMR1, 16, 2, esdhc_sels, 4);
+ clk[VF610_CLK_ESDHC0_EN] = imx_clk_gate("esdhc0_en", "esdhc0_sel", CCM_CSCDR2, 28);
+ clk[VF610_CLK_ESDHC0_DIV] = imx_clk_divider("esdhc0_div", "esdhc0_en", CCM_CSCDR2, 16, 4);
+ clk[VF610_CLK_ESDHC0] = imx_clk_gate2("eshc0", "esdhc0_div", CCM_CCGR7, CCM_CCGRx_CGn(1));
+
+ clk[VF610_CLK_ESDHC1_SEL] = imx_clk_mux("esdhc1_sel", CCM_CSCMR1, 18, 2, esdhc_sels, 4);
+ clk[VF610_CLK_ESDHC1_EN] = imx_clk_gate("esdhc1_en", "esdhc1_sel", CCM_CSCDR2, 29);
+ clk[VF610_CLK_ESDHC1_DIV] = imx_clk_divider("esdhc1_div", "esdhc1_en", CCM_CSCDR2, 20, 4);
+ clk[VF610_CLK_ESDHC1] = imx_clk_gate2("eshc1", "esdhc1_div", CCM_CCGR7, CCM_CCGRx_CGn(2));
+
+ /*
+ * ftm_ext_clk and ftm_fix_clk are FTM timer counter's
+ * selectable clock sources, both use a common enable bit
+ * in CCM_CSCDR1, selecting "dummy" clock as parent of
+ * "ftm0_ext_fix" make it serve only for enable/disable.
+ */
+ clk[VF610_CLK_FTM0_EXT_SEL] = imx_clk_mux("ftm0_ext_sel", CCM_CSCMR2, 6, 2, ftm_ext_sels, 4);
+ clk[VF610_CLK_FTM0_FIX_SEL] = imx_clk_mux("ftm0_fix_sel", CCM_CSCMR2, 14, 1, ftm_fix_sels, 2);
+ clk[VF610_CLK_FTM0_EXT_FIX_EN] = imx_clk_gate("ftm0_ext_fix_en", "dummy", CCM_CSCDR1, 25);
+ clk[VF610_CLK_FTM1_EXT_SEL] = imx_clk_mux("ftm1_ext_sel", CCM_CSCMR2, 8, 2, ftm_ext_sels, 4);
+ clk[VF610_CLK_FTM1_FIX_SEL] = imx_clk_mux("ftm1_fix_sel", CCM_CSCMR2, 15, 1, ftm_fix_sels, 2);
+ clk[VF610_CLK_FTM1_EXT_FIX_EN] = imx_clk_gate("ftm1_ext_fix_en", "dummy", CCM_CSCDR1, 26);
+ clk[VF610_CLK_FTM2_EXT_SEL] = imx_clk_mux("ftm2_ext_sel", CCM_CSCMR2, 10, 2, ftm_ext_sels, 4);
+ clk[VF610_CLK_FTM2_FIX_SEL] = imx_clk_mux("ftm2_fix_sel", CCM_CSCMR2, 16, 1, ftm_fix_sels, 2);
+ clk[VF610_CLK_FTM2_EXT_FIX_EN] = imx_clk_gate("ftm2_ext_fix_en", "dummy", CCM_CSCDR1, 27);
+ clk[VF610_CLK_FTM3_EXT_SEL] = imx_clk_mux("ftm3_ext_sel", CCM_CSCMR2, 12, 2, ftm_ext_sels, 4);
+ clk[VF610_CLK_FTM3_FIX_SEL] = imx_clk_mux("ftm3_fix_sel", CCM_CSCMR2, 17, 1, ftm_fix_sels, 2);
+ clk[VF610_CLK_FTM3_EXT_FIX_EN] = imx_clk_gate("ftm3_ext_fix_en", "dummy", CCM_CSCDR1, 28);
+
+ /* ftm(n)_clk are FTM module operation clock */
+ clk[VF610_CLK_FTM0] = imx_clk_gate2("ftm0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(8));
+ clk[VF610_CLK_FTM1] = imx_clk_gate2("ftm1", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(9));
+ clk[VF610_CLK_FTM2] = imx_clk_gate2("ftm2", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(8));
+ clk[VF610_CLK_FTM3] = imx_clk_gate2("ftm3", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(9));
+
+ clk[VF610_CLK_DCU0_SEL] = imx_clk_mux("dcu0_sel", CCM_CSCMR1, 28, 1, dcu_sels, 2);
+ clk[VF610_CLK_DCU0_EN] = imx_clk_gate("dcu0_en", "dcu0_sel", CCM_CSCDR3, 19);
+ clk[VF610_CLK_DCU0_DIV] = imx_clk_divider("dcu0_div", "dcu0_en", CCM_CSCDR3, 16, 3);
+ clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "dcu0_div", CCM_CCGR3, CCM_CCGRx_CGn(8));
+ clk[VF610_CLK_DCU1_SEL] = imx_clk_mux("dcu1_sel", CCM_CSCMR1, 29, 1, dcu_sels, 2);
+ clk[VF610_CLK_DCU1_EN] = imx_clk_gate("dcu1_en", "dcu1_sel", CCM_CSCDR3, 23);
+ clk[VF610_CLK_DCU1_DIV] = imx_clk_divider("dcu1_div", "dcu1_en", CCM_CSCDR3, 20, 3);
+ clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "dcu1_div", CCM_CCGR9, CCM_CCGRx_CGn(8));
+
+ clk[VF610_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", CCM_CSCMR1, 20, 2, esai_sels, 4);
+ clk[VF610_CLK_ESAI_EN] = imx_clk_gate("esai_en", "esai_sel", CCM_CSCDR2, 30);
+ clk[VF610_CLK_ESAI_DIV] = imx_clk_divider("esai_div", "esai_en", CCM_CSCDR2, 24, 4);
+ clk[VF610_CLK_ESAI] = imx_clk_gate2("esai", "esai_div", CCM_CCGR4, CCM_CCGRx_CGn(2));
+
+ clk[VF610_CLK_SAI0_SEL] = imx_clk_mux("sai0_sel", CCM_CSCMR1, 0, 2, sai_sels, 4);
+ clk[VF610_CLK_SAI0_EN] = imx_clk_gate("sai0_en", "sai0_sel", CCM_CSCDR1, 16);
+ clk[VF610_CLK_SAI0_DIV] = imx_clk_divider("sai0_div", "sai0_en", CCM_CSCDR1, 0, 4);
+ clk[VF610_CLK_SAI0] = imx_clk_gate2("sai0", "sai0_div", CCM_CCGR0, CCM_CCGRx_CGn(15));
+
+ clk[VF610_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", CCM_CSCMR1, 2, 2, sai_sels, 4);
+ clk[VF610_CLK_SAI1_EN] = imx_clk_gate("sai1_en", "sai1_sel", CCM_CSCDR1, 17);
+ clk[VF610_CLK_SAI1_DIV] = imx_clk_divider("sai1_div", "sai1_en", CCM_CSCDR1, 4, 4);
+ clk[VF610_CLK_SAI1] = imx_clk_gate2("sai1", "sai1_div", CCM_CCGR1, CCM_CCGRx_CGn(0));
+
+ clk[VF610_CLK_SAI2_SEL] = imx_clk_mux("sai2_sel", CCM_CSCMR1, 4, 2, sai_sels, 4);
+ clk[VF610_CLK_SAI2_EN] = imx_clk_gate("sai2_en", "sai2_sel", CCM_CSCDR1, 18);
+ clk[VF610_CLK_SAI2_DIV] = imx_clk_divider("sai2_div", "sai2_en", CCM_CSCDR1, 8, 4);
+ clk[VF610_CLK_SAI2] = imx_clk_gate2("sai2", "sai2_div", CCM_CCGR1, CCM_CCGRx_CGn(1));
+
+ clk[VF610_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", CCM_CSCMR1, 6, 2, sai_sels, 4);
+ clk[VF610_CLK_SAI3_EN] = imx_clk_gate("sai3_en", "sai3_sel", CCM_CSCDR1, 19);
+ clk[VF610_CLK_SAI3_DIV] = imx_clk_divider("sai3_div", "sai3_en", CCM_CSCDR1, 12, 4);
+ clk[VF610_CLK_SAI3] = imx_clk_gate2("sai3", "sai3_div", CCM_CCGR1, CCM_CCGRx_CGn(2));
+
+ clk[VF610_CLK_NFC_SEL] = imx_clk_mux("nfc_sel", CCM_CSCMR1, 12, 2, nfc_sels, 4);
+ clk[VF610_CLK_NFC_EN] = imx_clk_gate("nfc_en", "nfc_sel", CCM_CSCDR2, 9);
+ clk[VF610_CLK_NFC_PRE_DIV] = imx_clk_divider("nfc_pre_div", "nfc_en", CCM_CSCDR3, 13, 3);
+ clk[VF610_CLK_NFC_FRAC_DIV] = imx_clk_divider("nfc_frac_div", "nfc_pre_div", CCM_CSCDR2, 4, 4);
+ clk[VF610_CLK_NFC] = imx_clk_gate2("nfc", "nfc_frac_div", CCM_CCGR10, CCM_CCGRx_CGn(0));
+
+ clk[VF610_CLK_GPU_SEL] = imx_clk_mux("gpu_sel", CCM_CSCMR1, 14, 1, gpu_sels, 2);
+ clk[VF610_CLK_GPU_EN] = imx_clk_gate("gpu_en", "gpu_sel", CCM_CSCDR2, 10);
+ clk[VF610_CLK_GPU2D] = imx_clk_gate2("gpu", "gpu_en", CCM_CCGR8, CCM_CCGRx_CGn(15));
+
+ clk[VF610_CLK_VADC_SEL] = imx_clk_mux("vadc_sel", CCM_CSCMR1, 8, 2, vadc_sels, 3);
+ clk[VF610_CLK_VADC_EN] = imx_clk_gate("vadc_en", "vadc_sel", CCM_CSCDR1, 22);
+ clk[VF610_CLK_VADC_DIV] = imx_clk_divider("vadc_div", "vadc_en", CCM_CSCDR1, 20, 2);
+ clk[VF610_CLK_VADC_DIV_HALF] = imx_clk_fixed_factor("vadc_div_half", "vadc_div", 1, 2);
+ clk[VF610_CLK_VADC] = imx_clk_gate2("vadc", "vadc_div", CCM_CCGR8, CCM_CCGRx_CGn(7));
+
+ clk[VF610_CLK_ADC0] = imx_clk_gate2("adc0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(11));
+ clk[VF610_CLK_ADC1] = imx_clk_gate2("adc1", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(11));
+ clk[VF610_CLK_DAC0] = imx_clk_gate2("dac0", "ipg_bus", CCM_CCGR8, CCM_CCGRx_CGn(12));
+ clk[VF610_CLK_DAC1] = imx_clk_gate2("dac1", "ipg_bus", CCM_CCGR8, CCM_CCGRx_CGn(13));
+
+ clk[VF610_CLK_ASRC] = imx_clk_gate2("asrc", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(1));
+
+ clk[VF610_CLK_FLEXCAN0_EN] = imx_clk_gate("flexcan0_en", "ipg_bus", CCM_CSCDR2, 11);
+ clk[VF610_CLK_FLEXCAN0] = imx_clk_gate2("flexcan0", "flexcan0_en", CCM_CCGR0, CCM_CCGRx_CGn(0));
+ clk[VF610_CLK_FLEXCAN1_EN] = imx_clk_gate("flexcan1_en", "ipg_bus", CCM_CSCDR2, 12);
+ clk[VF610_CLK_FLEXCAN1] = imx_clk_gate2("flexcan1", "flexcan1_en", CCM_CCGR9, CCM_CCGRx_CGn(4));
+
+ clk[VF610_CLK_DMAMUX0] = imx_clk_gate2("dmamux0", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(4));
+ clk[VF610_CLK_DMAMUX1] = imx_clk_gate2("dmamux1", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(5));
+ clk[VF610_CLK_DMAMUX2] = imx_clk_gate2("dmamux2", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(1));
+ clk[VF610_CLK_DMAMUX3] = imx_clk_gate2("dmamux3", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(2));
+
+ clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7));
+
+ imx_check_clocks(clk, ARRAY_SIZE(clk));
+
+ clk_set_parent(clk[VF610_CLK_QSPI0_SEL], clk[VF610_CLK_PLL1_PFD4]);
+ clk_set_rate(clk[VF610_CLK_QSPI0_X4_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_SEL]) / 2);
+ clk_set_rate(clk[VF610_CLK_QSPI0_X2_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_X4_DIV]) / 2);
+ clk_set_rate(clk[VF610_CLK_QSPI0_X1_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_X2_DIV]) / 2);
+
+ clk_set_parent(clk[VF610_CLK_QSPI1_SEL], clk[VF610_CLK_PLL1_PFD4]);
+ clk_set_rate(clk[VF610_CLK_QSPI1_X4_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_SEL]) / 2);
+ clk_set_rate(clk[VF610_CLK_QSPI1_X2_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_X4_DIV]) / 2);
+ clk_set_rate(clk[VF610_CLK_QSPI1_X1_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_X2_DIV]) / 2);
+
+ clk_set_parent(clk[VF610_CLK_SAI0_SEL], clk[VF610_CLK_AUDIO_EXT]);
+ clk_set_parent(clk[VF610_CLK_SAI1_SEL], clk[VF610_CLK_AUDIO_EXT]);
+ clk_set_parent(clk[VF610_CLK_SAI2_SEL], clk[VF610_CLK_AUDIO_EXT]);
+ clk_set_parent(clk[VF610_CLK_SAI3_SEL], clk[VF610_CLK_AUDIO_EXT]);
+
+ for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+ clk_prepare_enable(clk[clks_init_on[i]]);
+
+ /* Add the clocks to provider list */
+ clk_data.clks = clk;
+ clk_data.clk_num = ARRAY_SIZE(clk);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+CLK_OF_DECLARE(vf610, "fsl,vf610-ccm", vf610_clocks_init);
diff --git a/arch/arm/mach-imx/clk.c b/arch/arm/mach-imx/clk.c
new file mode 100644
index 000000000..df12b5307
--- /dev/null
+++ b/arch/arm/mach-imx/clk.c
@@ -0,0 +1,75 @@
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include "clk.h"
+
+DEFINE_SPINLOCK(imx_ccm_lock);
+
+void __init imx_check_clocks(struct clk *clks[], unsigned int count)
+{
+ unsigned i;
+
+ for (i = 0; i < count; i++)
+ if (IS_ERR(clks[i]))
+ pr_err("i.MX clk %u: register failed with %ld\n",
+ i, PTR_ERR(clks[i]));
+}
+
+static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name)
+{
+ struct of_phandle_args phandle;
+ struct clk *clk = ERR_PTR(-ENODEV);
+ char *path;
+
+ path = kasprintf(GFP_KERNEL, "/clocks/%s", name);
+ if (!path)
+ return ERR_PTR(-ENOMEM);
+
+ phandle.np = of_find_node_by_path(path);
+ kfree(path);
+
+ if (phandle.np) {
+ clk = of_clk_get_from_provider(&phandle);
+ of_node_put(phandle.np);
+ }
+ return clk;
+}
+
+struct clk * __init imx_obtain_fixed_clock(
+ const char *name, unsigned long rate)
+{
+ struct clk *clk;
+
+ clk = imx_obtain_fixed_clock_from_dt(name);
+ if (IS_ERR(clk))
+ clk = imx_clk_fixed(name, rate);
+ return clk;
+}
+
+/*
+ * This fixups the register CCM_CSCMR1 write value.
+ * The write/read/divider values of the aclk_podf field
+ * of that register have the relationship described by
+ * the following table:
+ *
+ * write value read value divider
+ * 3b'000 3b'110 7
+ * 3b'001 3b'111 8
+ * 3b'010 3b'100 5
+ * 3b'011 3b'101 6
+ * 3b'100 3b'010 3
+ * 3b'101 3b'011 4
+ * 3b'110 3b'000 1
+ * 3b'111 3b'001 2(default)
+ *
+ * That's why we do the xor operation below.
+ */
+#define CSCMR1_FIXUP 0x00600000
+
+void imx_cscmr1_fixup(u32 *val)
+{
+ *val ^= CSCMR1_FIXUP;
+ return;
+}
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
new file mode 100644
index 000000000..6a07903a2
--- /dev/null
+++ b/arch/arm/mach-imx/clk.h
@@ -0,0 +1,139 @@
+#ifndef __MACH_IMX_CLK_H
+#define __MACH_IMX_CLK_H
+
+#include <linux/spinlock.h>
+#include <linux/clk-provider.h>
+
+extern spinlock_t imx_ccm_lock;
+
+void imx_check_clocks(struct clk *clks[], unsigned int count);
+
+extern void imx_cscmr1_fixup(u32 *val);
+
+struct clk *imx_clk_pllv1(const char *name, const char *parent,
+ void __iomem *base);
+
+struct clk *imx_clk_pllv2(const char *name, const char *parent,
+ void __iomem *base);
+
+enum imx_pllv3_type {
+ IMX_PLLV3_GENERIC,
+ IMX_PLLV3_SYS,
+ IMX_PLLV3_USB,
+ IMX_PLLV3_USB_VF610,
+ IMX_PLLV3_AV,
+ IMX_PLLV3_ENET,
+};
+
+struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
+ const char *parent_name, void __iomem *base, u32 div_mask);
+
+struct clk *clk_register_gate2(struct device *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ void __iomem *reg, u8 bit_idx,
+ u8 clk_gate_flags, spinlock_t *lock,
+ unsigned int *share_count);
+
+struct clk * imx_obtain_fixed_clock(
+ const char *name, unsigned long rate);
+
+struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, u32 exclusive_mask);
+
+static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
+ void __iomem *reg, u8 shift)
+{
+ return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+ shift, 0, &imx_ccm_lock, NULL);
+}
+
+static inline struct clk *imx_clk_gate2_shared(const char *name,
+ const char *parent, void __iomem *reg, u8 shift,
+ unsigned int *share_count)
+{
+ return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+ shift, 0, &imx_ccm_lock, share_count);
+}
+
+struct clk *imx_clk_pfd(const char *name, const char *parent_name,
+ void __iomem *reg, u8 idx);
+
+struct clk *imx_clk_busy_divider(const char *name, const char *parent_name,
+ void __iomem *reg, u8 shift, u8 width,
+ void __iomem *busy_reg, u8 busy_shift);
+
+struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
+ u8 width, void __iomem *busy_reg, u8 busy_shift,
+ const char **parent_names, int num_parents);
+
+struct clk *imx_clk_fixup_divider(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, u8 width,
+ void (*fixup)(u32 *val));
+
+struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg,
+ u8 shift, u8 width, const char **parents,
+ int num_parents, void (*fixup)(u32 *val));
+
+static inline struct clk *imx_clk_fixed(const char *name, int rate)
+{
+ return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
+}
+
+static inline struct clk *imx_clk_divider(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, u8 width)
+{
+ return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
+ reg, shift, width, 0, &imx_ccm_lock);
+}
+
+static inline struct clk *imx_clk_divider_flags(const char *name,
+ const char *parent, void __iomem *reg, u8 shift, u8 width,
+ unsigned long flags)
+{
+ return clk_register_divider(NULL, name, parent, flags,
+ reg, shift, width, 0, &imx_ccm_lock);
+}
+
+static inline struct clk *imx_clk_gate(const char *name, const char *parent,
+ void __iomem *reg, u8 shift)
+{
+ return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+ shift, 0, &imx_ccm_lock);
+}
+
+static inline struct clk *imx_clk_gate_dis(const char *name, const char *parent,
+ void __iomem *reg, u8 shift)
+{
+ return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+ shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock);
+}
+
+static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
+ u8 shift, u8 width, const char **parents, int num_parents)
+{
+ return clk_register_mux(NULL, name, parents, num_parents,
+ CLK_SET_RATE_NO_REPARENT, reg, shift,
+ width, 0, &imx_ccm_lock);
+}
+
+static inline struct clk *imx_clk_mux_flags(const char *name,
+ void __iomem *reg, u8 shift, u8 width, const char **parents,
+ int num_parents, unsigned long flags)
+{
+ return clk_register_mux(NULL, name, parents, num_parents,
+ flags | CLK_SET_RATE_NO_REPARENT, reg, shift, width, 0,
+ &imx_ccm_lock);
+}
+
+static inline struct clk *imx_clk_fixed_factor(const char *name,
+ const char *parent, unsigned int mult, unsigned int div)
+{
+ return clk_register_fixed_factor(NULL, name, parent,
+ CLK_SET_RATE_PARENT, mult, div);
+}
+
+struct clk *imx_clk_cpu(const char *name, const char *parent_name,
+ struct clk *div, struct clk *mux, struct clk *pll,
+ struct clk *step);
+
+#endif
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
new file mode 100644
index 000000000..0f04e30b7
--- /dev/null
+++ b/arch/arm/mach-imx/common.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2004-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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_COMMON_H__
+#define __ASM_ARCH_MXC_COMMON_H__
+
+#include <linux/reboot.h>
+
+struct irq_data;
+struct platform_device;
+struct pt_regs;
+struct clk;
+struct device_node;
+enum mxc_cpu_pwr_mode;
+struct of_device_id;
+
+void mx1_map_io(void);
+void mx21_map_io(void);
+void mx27_map_io(void);
+void mx31_map_io(void);
+void mx35_map_io(void);
+void imx1_init_early(void);
+void imx21_init_early(void);
+void imx27_init_early(void);
+void imx31_init_early(void);
+void imx35_init_early(void);
+void mxc_init_irq(void __iomem *);
+void tzic_init_irq(void);
+void mx1_init_irq(void);
+void mx21_init_irq(void);
+void mx27_init_irq(void);
+void mx31_init_irq(void);
+void mx35_init_irq(void);
+void imx1_soc_init(void);
+void imx21_soc_init(void);
+void imx27_soc_init(void);
+void imx31_soc_init(void);
+void imx35_soc_init(void);
+void epit_timer_init(void __iomem *base, int irq);
+void mxc_timer_init(void __iomem *, int);
+int mx1_clocks_init(unsigned long fref);
+int mx21_clocks_init(unsigned long lref, unsigned long fref);
+int mx27_clocks_init(unsigned long fref);
+int mx31_clocks_init(unsigned long fref);
+int mx35_clocks_init(void);
+int mx31_clocks_init_dt(void);
+struct platform_device *mxc_register_gpio(char *name, int id,
+ resource_size_t iobase, resource_size_t iosize, int irq, int irq_high);
+void mxc_set_cpu_type(unsigned int type);
+void mxc_restart(enum reboot_mode, const char *);
+void mxc_arch_reset_init(void __iomem *);
+int mx51_revision(void);
+int mx53_revision(void);
+void imx_set_aips(void __iomem *);
+void imx_aips_allow_unprivileged_access(const char *compat);
+int mxc_device_init(void);
+void imx_set_soc_revision(unsigned int rev);
+unsigned int imx_get_soc_revision(void);
+void imx_init_revision_from_anatop(void);
+struct device *imx_soc_device_init(void);
+void imx6_enable_rbc(bool enable);
+void imx_gpc_check_dt(void);
+void imx_gpc_set_arm_power_in_lpm(bool power_off);
+void imx_gpc_set_arm_power_up_timing(u32 sw2iso, u32 sw);
+void imx_gpc_set_arm_power_down_timing(u32 sw2iso, u32 sw);
+
+enum mxc_cpu_pwr_mode {
+ WAIT_CLOCKED, /* wfi only */
+ WAIT_UNCLOCKED, /* WAIT */
+ WAIT_UNCLOCKED_POWER_OFF, /* WAIT + SRPG */
+ STOP_POWER_ON, /* just STOP */
+ STOP_POWER_OFF, /* STOP + SRPG */
+};
+
+enum mx3_cpu_pwr_mode {
+ MX3_RUN,
+ MX3_WAIT,
+ MX3_DOZE,
+ MX3_SLEEP,
+};
+
+void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode);
+void imx_print_silicon_rev(const char *cpu, int srev);
+
+void imx_enable_cpu(int cpu, bool enable);
+void imx_set_cpu_jump(int cpu, void *jump_addr);
+u32 imx_get_cpu_arg(int cpu);
+void imx_set_cpu_arg(int cpu, u32 arg);
+#ifdef CONFIG_SMP
+void v7_secondary_startup(void);
+void imx_scu_map_io(void);
+void imx_smp_prepare(void);
+#else
+static inline void imx_scu_map_io(void) {}
+static inline void imx_smp_prepare(void) {}
+#endif
+void imx_src_init(void);
+void imx_gpc_pre_suspend(bool arm_power_off);
+void imx_gpc_post_resume(void);
+void imx_gpc_mask_all(void);
+void imx_gpc_restore_all(void);
+void imx_gpc_hwirq_mask(unsigned int hwirq);
+void imx_gpc_hwirq_unmask(unsigned int hwirq);
+void imx_anatop_init(void);
+void imx_anatop_pre_suspend(void);
+void imx_anatop_post_resume(void);
+int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
+void imx6q_set_int_mem_clk_lpm(bool enable);
+void imx6sl_set_wait_clk(bool enter);
+int imx_mmdc_get_ddr_type(void);
+
+void imx_cpu_die(unsigned int cpu);
+int imx_cpu_kill(unsigned int cpu);
+
+#ifdef CONFIG_SUSPEND
+void v7_cpu_resume(void);
+void imx6_suspend(void __iomem *ocram_vbase);
+#else
+static inline void v7_cpu_resume(void) {}
+static inline void imx6_suspend(void __iomem *ocram_vbase) {}
+#endif
+
+void imx6q_pm_init(void);
+void imx6dl_pm_init(void);
+void imx6sl_pm_init(void);
+void imx6sx_pm_init(void);
+void imx6q_pm_set_ccm_base(void __iomem *base);
+
+#ifdef CONFIG_PM
+void imx51_pm_init(void);
+void imx53_pm_init(void);
+void imx5_pm_set_ccm_base(void __iomem *base);
+#else
+static inline void imx51_pm_init(void) {}
+static inline void imx53_pm_init(void) {}
+static inline void imx5_pm_set_ccm_base(void __iomem *base) {}
+#endif
+
+#ifdef CONFIG_NEON
+int mx51_neon_fixup(void);
+#else
+static inline int mx51_neon_fixup(void) { return 0; }
+#endif
+
+#ifdef CONFIG_CACHE_L2X0
+void imx_init_l2cache(void);
+#else
+static inline void imx_init_l2cache(void) {}
+#endif
+
+extern struct smp_operations imx_smp_ops;
+extern struct smp_operations ls1021a_smp_ops;
+
+#endif
diff --git a/arch/arm/mach-imx/cpu-imx25.c b/arch/arm/mach-imx/cpu-imx25.c
new file mode 100644
index 000000000..d0ad67e80
--- /dev/null
+++ b/arch/arm/mach-imx/cpu-imx25.c
@@ -0,0 +1,51 @@
+/*
+ * MX25 CPU type detection
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ * 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.
+ */
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include "iim.h"
+#include "hardware.h"
+
+static int mx25_cpu_rev = -1;
+
+static int mx25_read_cpu_rev(void)
+{
+ u32 rev;
+ void __iomem *iim_base;
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx25-iim");
+ iim_base = of_iomap(np, 0);
+ BUG_ON(!iim_base);
+ rev = readl(iim_base + MXC_IIMSREV);
+ iounmap(iim_base);
+
+ switch (rev) {
+ case 0x00:
+ return IMX_CHIP_REVISION_1_0;
+ case 0x01:
+ return IMX_CHIP_REVISION_1_1;
+ default:
+ return IMX_CHIP_REVISION_UNKNOWN;
+ }
+}
+
+int mx25_revision(void)
+{
+ if (mx25_cpu_rev == -1)
+ mx25_cpu_rev = mx25_read_cpu_rev();
+
+ return mx25_cpu_rev;
+}
+EXPORT_SYMBOL(mx25_revision);
diff --git a/arch/arm/mach-imx/cpu-imx27.c b/arch/arm/mach-imx/cpu-imx27.c
new file mode 100644
index 000000000..fe8d36f7e
--- /dev/null
+++ b/arch/arm/mach-imx/cpu-imx27.c
@@ -0,0 +1,74 @@
+/*
+ * 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 "hardware.h"
+
+static int mx27_cpu_rev = -1;
+static int mx27_cpu_partnumber;
+
+#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */
+
+static int mx27_read_cpu_rev(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));
+
+ mx27_cpu_partnumber = (int)((val >> 12) & 0xFFFF);
+
+ switch (val >> 28) {
+ case 0:
+ return IMX_CHIP_REVISION_1_0;
+ case 1:
+ return IMX_CHIP_REVISION_2_0;
+ case 2:
+ return IMX_CHIP_REVISION_2_1;
+ default:
+ return IMX_CHIP_REVISION_UNKNOWN;
+ }
+}
+
+/*
+ * Returns:
+ * the silicon revision of the cpu
+ * -EINVAL - not a mx27
+ */
+int mx27_revision(void)
+{
+ if (mx27_cpu_rev == -1)
+ mx27_cpu_rev = mx27_read_cpu_rev();
+
+ if (mx27_cpu_partnumber != 0x8821)
+ return -EINVAL;
+
+ return mx27_cpu_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 000000000..fde1860a2
--- /dev/null
+++ b/arch/arm/mach-imx/cpu-imx31.c
@@ -0,0 +1,63 @@
+/*
+ * 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 "common.h"
+#include "hardware.h"
+#include "iim.h"
+
+static int mx31_cpu_rev = -1;
+
+static struct {
+ u8 srev;
+ const char *name;
+ unsigned int rev;
+} mx31_cpu_type[] = {
+ { .srev = 0x00, .name = "i.MX31(L)", .rev = IMX_CHIP_REVISION_1_0 },
+ { .srev = 0x10, .name = "i.MX31", .rev = IMX_CHIP_REVISION_1_1 },
+ { .srev = 0x11, .name = "i.MX31L", .rev = IMX_CHIP_REVISION_1_1 },
+ { .srev = 0x12, .name = "i.MX31", .rev = IMX_CHIP_REVISION_1_1 },
+ { .srev = 0x13, .name = "i.MX31L", .rev = IMX_CHIP_REVISION_1_1 },
+ { .srev = 0x14, .name = "i.MX31", .rev = IMX_CHIP_REVISION_1_2 },
+ { .srev = 0x15, .name = "i.MX31L", .rev = IMX_CHIP_REVISION_1_2 },
+ { .srev = 0x28, .name = "i.MX31", .rev = IMX_CHIP_REVISION_2_0 },
+ { .srev = 0x29, .name = "i.MX31L", .rev = IMX_CHIP_REVISION_2_0 },
+};
+
+static int 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));
+ srev &= 0xff;
+
+ for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++)
+ if (srev == mx31_cpu_type[i].srev) {
+ imx_print_silicon_rev(mx31_cpu_type[i].name,
+ mx31_cpu_type[i].rev);
+ return mx31_cpu_type[i].rev;
+ }
+
+ imx_print_silicon_rev("i.MX31", IMX_CHIP_REVISION_UNKNOWN);
+ return IMX_CHIP_REVISION_UNKNOWN;
+}
+
+int mx31_revision(void)
+{
+ if (mx31_cpu_rev == -1)
+ mx31_cpu_rev = mx31_read_cpu_rev();
+
+ return mx31_cpu_rev;
+}
+EXPORT_SYMBOL(mx31_revision);
diff --git a/arch/arm/mach-imx/cpu-imx35.c b/arch/arm/mach-imx/cpu-imx35.c
new file mode 100644
index 000000000..ec3aaa098
--- /dev/null
+++ b/arch/arm/mach-imx/cpu-imx35.c
@@ -0,0 +1,43 @@
+/*
+ * 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 "hardware.h"
+#include "iim.h"
+
+static int mx35_cpu_rev = -1;
+
+static int mx35_read_cpu_rev(void)
+{
+ u32 rev;
+
+ rev = __raw_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV));
+ switch (rev) {
+ case 0x00:
+ return IMX_CHIP_REVISION_1_0;
+ case 0x10:
+ return IMX_CHIP_REVISION_2_0;
+ case 0x11:
+ return IMX_CHIP_REVISION_2_1;
+ default:
+ return IMX_CHIP_REVISION_UNKNOWN;
+ }
+}
+
+int mx35_revision(void)
+{
+ if (mx35_cpu_rev == -1)
+ mx35_cpu_rev = mx35_read_cpu_rev();
+
+ return mx35_cpu_rev;
+}
+EXPORT_SYMBOL(mx35_revision);
diff --git a/arch/arm/mach-imx/cpu-imx5.c b/arch/arm/mach-imx/cpu-imx5.c
new file mode 100644
index 000000000..3403bac94
--- /dev/null
+++ b/arch/arm/mach-imx/cpu-imx5.c
@@ -0,0 +1,127 @@
+/*
+ * 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
+ *
+ * This file contains the CPU initialization code.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include "hardware.h"
+#include "common.h"
+
+static int mx5_cpu_rev = -1;
+
+#define IIM_SREV 0x24
+
+static u32 imx5_read_srev_reg(const char *compat)
+{
+ void __iomem *iim_base;
+ struct device_node *np;
+ u32 srev;
+
+ np = of_find_compatible_node(NULL, NULL, compat);
+ iim_base = of_iomap(np, 0);
+ WARN_ON(!iim_base);
+
+ srev = readl(iim_base + IIM_SREV) & 0xff;
+
+ iounmap(iim_base);
+
+ return srev;
+}
+
+static int get_mx51_srev(void)
+{
+ u32 rev = imx5_read_srev_reg("fsl,imx51-iim");
+
+ switch (rev) {
+ case 0x0:
+ return IMX_CHIP_REVISION_2_0;
+ case 0x10:
+ return IMX_CHIP_REVISION_3_0;
+ default:
+ return IMX_CHIP_REVISION_UNKNOWN;
+ }
+}
+
+/*
+ * Returns:
+ * the silicon revision of the cpu
+ * -EINVAL - not a mx51
+ */
+int mx51_revision(void)
+{
+ if (!cpu_is_mx51())
+ return -EINVAL;
+
+ if (mx5_cpu_rev == -1)
+ mx5_cpu_rev = get_mx51_srev();
+
+ return mx5_cpu_rev;
+}
+EXPORT_SYMBOL(mx51_revision);
+
+#ifdef CONFIG_NEON
+
+/*
+ * All versions of the silicon before Rev. 3 have broken NEON implementations.
+ * Dependent on link order - so the assumption is that vfp_init is called
+ * before us.
+ */
+int __init mx51_neon_fixup(void)
+{
+ 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;
+}
+
+#endif
+
+static int get_mx53_srev(void)
+{
+ u32 rev = imx5_read_srev_reg("fsl,imx53-iim");
+
+ 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 (mx5_cpu_rev == -1)
+ mx5_cpu_rev = get_mx53_srev();
+
+ return mx5_cpu_rev;
+}
+EXPORT_SYMBOL(mx53_revision);
diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c
new file mode 100644
index 000000000..df42c14ff
--- /dev/null
+++ b/arch/arm/mach-imx/cpu.c
@@ -0,0 +1,155 @@
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+
+#include "hardware.h"
+#include "common.h"
+
+unsigned int __mxc_cpu_type;
+EXPORT_SYMBOL(__mxc_cpu_type);
+
+static unsigned int imx_soc_revision;
+
+void mxc_set_cpu_type(unsigned int type)
+{
+ __mxc_cpu_type = type;
+}
+
+void imx_set_soc_revision(unsigned int rev)
+{
+ imx_soc_revision = rev;
+}
+
+unsigned int imx_get_soc_revision(void)
+{
+ return imx_soc_revision;
+}
+
+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);
+}
+
+void __init imx_set_aips(void __iomem *base)
+{
+ unsigned int reg;
+/*
+ * Set all MPROTx to be non-bufferable, trusted for R/W,
+ * not forced to user-mode.
+ */
+ __raw_writel(0x77777777, base + 0x0);
+ __raw_writel(0x77777777, base + 0x4);
+
+/*
+ * Set all OPACRx to be non-bufferable, to not require
+ * supervisor privilege level for access, allow for
+ * write access and untrusted master access.
+ */
+ __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);
+}
+
+void __init imx_aips_allow_unprivileged_access(
+ const char *compat)
+{
+ void __iomem *aips_base_addr;
+ struct device_node *np;
+
+ for_each_compatible_node(np, NULL, compat) {
+ aips_base_addr = of_iomap(np, 0);
+ imx_set_aips(aips_base_addr);
+ }
+}
+
+struct device * __init imx_soc_device_init(void)
+{
+ struct soc_device_attribute *soc_dev_attr;
+ struct soc_device *soc_dev;
+ struct device_node *root;
+ const char *soc_id;
+ int ret;
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ return NULL;
+
+ soc_dev_attr->family = "Freescale i.MX";
+
+ root = of_find_node_by_path("/");
+ ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
+ of_node_put(root);
+ if (ret)
+ goto free_soc;
+
+ switch (__mxc_cpu_type) {
+ case MXC_CPU_MX1:
+ soc_id = "i.MX1";
+ break;
+ case MXC_CPU_MX21:
+ soc_id = "i.MX21";
+ break;
+ case MXC_CPU_MX25:
+ soc_id = "i.MX25";
+ break;
+ case MXC_CPU_MX27:
+ soc_id = "i.MX27";
+ break;
+ case MXC_CPU_MX31:
+ soc_id = "i.MX31";
+ break;
+ case MXC_CPU_MX35:
+ soc_id = "i.MX35";
+ break;
+ case MXC_CPU_MX51:
+ soc_id = "i.MX51";
+ break;
+ case MXC_CPU_MX53:
+ soc_id = "i.MX53";
+ break;
+ case MXC_CPU_IMX6SL:
+ soc_id = "i.MX6SL";
+ break;
+ case MXC_CPU_IMX6DL:
+ soc_id = "i.MX6DL";
+ break;
+ case MXC_CPU_IMX6SX:
+ soc_id = "i.MX6SX";
+ break;
+ case MXC_CPU_IMX6Q:
+ soc_id = "i.MX6Q";
+ break;
+ default:
+ soc_id = "Unknown";
+ }
+ soc_dev_attr->soc_id = soc_id;
+
+ soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d.%d",
+ (imx_soc_revision >> 4) & 0xf,
+ imx_soc_revision & 0xf);
+ if (!soc_dev_attr->revision)
+ goto free_soc;
+
+ soc_dev = soc_device_register(soc_dev_attr);
+ if (IS_ERR(soc_dev))
+ goto free_rev;
+
+ return soc_device_to_device(soc_dev);
+
+free_rev:
+ kfree(soc_dev_attr->revision);
+free_soc:
+ kfree(soc_dev_attr);
+ return NULL;
+}
diff --git a/arch/arm/mach-imx/cpuidle-imx5.c b/arch/arm/mach-imx/cpuidle-imx5.c
new file mode 100644
index 000000000..3feca526d
--- /dev/null
+++ b/arch/arm/mach-imx/cpuidle-imx5.c
@@ -0,0 +1,36 @@
+/*
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/cpuidle.h>
+#include <linux/module.h>
+#include <asm/system_misc.h>
+
+static int imx5_cpuidle_enter(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ arm_pm_idle();
+ return index;
+}
+
+static struct cpuidle_driver imx5_cpuidle_driver = {
+ .name = "imx5_cpuidle",
+ .owner = THIS_MODULE,
+ .states[0] = {
+ .enter = imx5_cpuidle_enter,
+ .exit_latency = 2,
+ .target_residency = 1,
+ .name = "IMX5 SRPG",
+ .desc = "CPU state retained,powered off",
+ },
+ .state_count = 1,
+};
+
+int __init imx5_cpuidle_init(void)
+{
+ return cpuidle_register(&imx5_cpuidle_driver, NULL);
+}
diff --git a/arch/arm/mach-imx/cpuidle-imx6q.c b/arch/arm/mach-imx/cpuidle-imx6q.c
new file mode 100644
index 000000000..8e21ccc1e
--- /dev/null
+++ b/arch/arm/mach-imx/cpuidle-imx6q.c
@@ -0,0 +1,71 @@
+/*
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/cpuidle.h>
+#include <linux/module.h>
+#include <asm/cpuidle.h>
+
+#include "common.h"
+#include "cpuidle.h"
+#include "hardware.h"
+
+static atomic_t master = ATOMIC_INIT(0);
+static DEFINE_SPINLOCK(master_lock);
+
+static int imx6q_enter_wait(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ if (atomic_inc_return(&master) == num_online_cpus()) {
+ /*
+ * With this lock, we prevent other cpu to exit and enter
+ * this function again and become the master.
+ */
+ if (!spin_trylock(&master_lock))
+ goto idle;
+ imx6q_set_lpm(WAIT_UNCLOCKED);
+ cpu_do_idle();
+ imx6q_set_lpm(WAIT_CLOCKED);
+ spin_unlock(&master_lock);
+ goto done;
+ }
+
+idle:
+ cpu_do_idle();
+done:
+ atomic_dec(&master);
+
+ return index;
+}
+
+static struct cpuidle_driver imx6q_cpuidle_driver = {
+ .name = "imx6q_cpuidle",
+ .owner = THIS_MODULE,
+ .states = {
+ /* WFI */
+ ARM_CPUIDLE_WFI_STATE,
+ /* WAIT */
+ {
+ .exit_latency = 50,
+ .target_residency = 75,
+ .flags = CPUIDLE_FLAG_TIMER_STOP,
+ .enter = imx6q_enter_wait,
+ .name = "WAIT",
+ .desc = "Clock off",
+ },
+ },
+ .state_count = 2,
+ .safe_state_index = 0,
+};
+
+int __init imx6q_cpuidle_init(void)
+{
+ /* Set INT_MEM_CLK_LPM bit to get a reliable WAIT mode support */
+ imx6q_set_int_mem_clk_lpm(true);
+
+ return cpuidle_register(&imx6q_cpuidle_driver, NULL);
+}
diff --git a/arch/arm/mach-imx/cpuidle-imx6sl.c b/arch/arm/mach-imx/cpuidle-imx6sl.c
new file mode 100644
index 000000000..5742a9fd1
--- /dev/null
+++ b/arch/arm/mach-imx/cpuidle-imx6sl.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 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 <linux/cpuidle.h>
+#include <linux/module.h>
+#include <asm/cpuidle.h>
+
+#include "common.h"
+#include "cpuidle.h"
+
+static int imx6sl_enter_wait(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ imx6q_set_lpm(WAIT_UNCLOCKED);
+ /*
+ * Software workaround for ERR005311, see function
+ * description for details.
+ */
+ imx6sl_set_wait_clk(true);
+ cpu_do_idle();
+ imx6sl_set_wait_clk(false);
+ imx6q_set_lpm(WAIT_CLOCKED);
+
+ return index;
+}
+
+static struct cpuidle_driver imx6sl_cpuidle_driver = {
+ .name = "imx6sl_cpuidle",
+ .owner = THIS_MODULE,
+ .states = {
+ /* WFI */
+ ARM_CPUIDLE_WFI_STATE,
+ /* WAIT */
+ {
+ .exit_latency = 50,
+ .target_residency = 75,
+ .flags = CPUIDLE_FLAG_TIMER_STOP,
+ .enter = imx6sl_enter_wait,
+ .name = "WAIT",
+ .desc = "Clock off",
+ },
+ },
+ .state_count = 2,
+ .safe_state_index = 0,
+};
+
+int __init imx6sl_cpuidle_init(void)
+{
+ return cpuidle_register(&imx6sl_cpuidle_driver, NULL);
+}
diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c
new file mode 100644
index 000000000..2c9f1a8bf
--- /dev/null
+++ b/arch/arm/mach-imx/cpuidle-imx6sx.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2014 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 <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
+#include <linux/module.h>
+#include <asm/cpuidle.h>
+#include <asm/suspend.h>
+
+#include "common.h"
+#include "cpuidle.h"
+
+static int imx6sx_idle_finish(unsigned long val)
+{
+ cpu_do_idle();
+
+ return 0;
+}
+
+static int imx6sx_enter_wait(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ imx6q_set_lpm(WAIT_UNCLOCKED);
+
+ switch (index) {
+ case 1:
+ cpu_do_idle();
+ break;
+ case 2:
+ imx6_enable_rbc(true);
+ imx_gpc_set_arm_power_in_lpm(true);
+ imx_set_cpu_jump(0, v7_cpu_resume);
+ /* Need to notify there is a cpu pm operation. */
+ cpu_pm_enter();
+ cpu_cluster_pm_enter();
+
+ cpu_suspend(0, imx6sx_idle_finish);
+
+ cpu_cluster_pm_exit();
+ cpu_pm_exit();
+ imx_gpc_set_arm_power_in_lpm(false);
+ imx6_enable_rbc(false);
+ break;
+ default:
+ break;
+ }
+
+ imx6q_set_lpm(WAIT_CLOCKED);
+
+ return index;
+}
+
+static struct cpuidle_driver imx6sx_cpuidle_driver = {
+ .name = "imx6sx_cpuidle",
+ .owner = THIS_MODULE,
+ .states = {
+ /* WFI */
+ ARM_CPUIDLE_WFI_STATE,
+ /* WAIT */
+ {
+ .exit_latency = 50,
+ .target_residency = 75,
+ .flags = CPUIDLE_FLAG_TIMER_STOP,
+ .enter = imx6sx_enter_wait,
+ .name = "WAIT",
+ .desc = "Clock off",
+ },
+ /* WAIT + ARM power off */
+ {
+ /*
+ * ARM gating 31us * 5 + RBC clear 65us
+ * and some margin for SW execution, here set it
+ * to 300us.
+ */
+ .exit_latency = 300,
+ .target_residency = 500,
+ .enter = imx6sx_enter_wait,
+ .name = "LOW-POWER-IDLE",
+ .desc = "ARM power off",
+ },
+ },
+ .state_count = 3,
+ .safe_state_index = 0,
+};
+
+int __init imx6sx_cpuidle_init(void)
+{
+ imx6_enable_rbc(false);
+ /*
+ * set ARM power up/down timing to the fastest,
+ * sw2iso and sw can be set to one 32K cycle = 31us
+ * except for power up sw2iso which need to be
+ * larger than LDO ramp up time.
+ */
+ imx_gpc_set_arm_power_up_timing(2, 1);
+ imx_gpc_set_arm_power_down_timing(1, 1);
+
+ return cpuidle_register(&imx6sx_cpuidle_driver, NULL);
+}
diff --git a/arch/arm/mach-imx/cpuidle.h b/arch/arm/mach-imx/cpuidle.h
new file mode 100644
index 000000000..f9140128b
--- /dev/null
+++ b/arch/arm/mach-imx/cpuidle.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * 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
+ */
+
+#ifdef CONFIG_CPU_IDLE
+extern int imx5_cpuidle_init(void);
+extern int imx6q_cpuidle_init(void);
+extern int imx6sl_cpuidle_init(void);
+extern int imx6sx_cpuidle_init(void);
+#else
+static inline int imx5_cpuidle_init(void)
+{
+ return 0;
+}
+static inline int imx6q_cpuidle_init(void)
+{
+ return 0;
+}
+static inline int imx6sl_cpuidle_init(void)
+{
+ return 0;
+}
+static inline int imx6sx_cpuidle_init(void)
+{
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-imx/crmregs-imx3.h b/arch/arm/mach-imx/crmregs-imx3.h
new file mode 100644
index 000000000..a1dfde53e
--- /dev/null
+++ b/arch/arm/mach-imx/crmregs-imx3.h
@@ -0,0 +1,261 @@
+/*
+ * 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
+
+extern void __iomem *mx3_ccm_base;
+
+/* Register addresses */
+#define MXC_CCM_CCMR 0x00
+#define MXC_CCM_PDR0 0x04
+#define MXC_CCM_PDR1 0x08
+#define MX35_CCM_PDR2 0x0C
+#define MXC_CCM_RCSR 0x0C
+#define MX35_CCM_PDR3 0x10
+#define MXC_CCM_MPCTL 0x10
+#define MX35_CCM_PDR4 0x14
+#define MXC_CCM_UPCTL 0x14
+#define MX35_CCM_RCSR 0x18
+#define MXC_CCM_SRPCTL 0x18
+#define MX35_CCM_MPCTL 0x1C
+#define MXC_CCM_COSR 0x1C
+#define MX35_CCM_PPCTL 0x20
+#define MXC_CCM_CGR0 0x20
+#define MX35_CCM_ACMR 0x24
+#define MXC_CCM_CGR1 0x24
+#define MX35_CCM_COSR 0x28
+#define MXC_CCM_CGR2 0x28
+#define MX35_CCM_CGR0 0x2C
+#define MXC_CCM_WIMR 0x2C
+#define MX35_CCM_CGR1 0x30
+#define MXC_CCM_LDC 0x30
+#define MX35_CCM_CGR2 0x34
+#define MXC_CCM_DCVR0 0x34
+#define MX35_CCM_CGR3 0x38
+#define MXC_CCM_DCVR1 0x38
+#define MXC_CCM_DCVR2 0x3C
+#define MXC_CCM_DCVR3 0x40
+#define MXC_CCM_LTR0 0x44
+#define MXC_CCM_LTR1 0x48
+#define MXC_CCM_LTR2 0x4C
+#define MXC_CCM_LTR3 0x50
+#define MXC_CCM_LTBR0 0x54
+#define MXC_CCM_LTBR1 0x58
+#define MXC_CCM_PMCR0 0x5C
+#define MXC_CCM_PMCR1 0x60
+#define MXC_CCM_PDR2 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_LPM_WAIT_MX35 (0x1 << 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 000000000..f9b5afc6b
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx1.h
@@ -0,0 +1,30 @@
+/*
+ * 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 "devices/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 000000000..bd9393280
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx21.h
@@ -0,0 +1,59 @@
+/*
+ * 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 "devices/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() \
+ 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() \
+ 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-imx27.h b/arch/arm/mach-imx/devices-imx27.h
new file mode 100644
index 000000000..130962519
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx27.h
@@ -0,0 +1,89 @@
+/*
+ * 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 "devices/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_imx27_coda_data imx27_coda_data;
+#define imx27_add_coda() \
+ imx_add_imx27_coda(&imx27_coda_data)
+
+extern const struct imx_imx2_wdt_data imx27_imx2_wdt_data;
+#define imx27_add_imx2_wdt() \
+ 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_mx2_emma_data imx27_mx2_emmaprp_data;
+#define imx27_add_mx2_emmaprp() \
+ imx_add_mx2_emmaprp(&imx27_mx2_emmaprp_data)
+
+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() \
+ 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)
+
+extern const struct imx_pata_imx_data imx27_pata_imx_data;
+#define imx27_add_pata_imx() \
+ imx_add_pata_imx(&imx27_pata_imx_data)
diff --git a/arch/arm/mach-imx/devices-imx31.h b/arch/arm/mach-imx/devices-imx31.h
new file mode 100644
index 000000000..e8d1611bb
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx31.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 "devices/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() \
+ 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() \
+ imx_add_ipu_core(&imx31_ipu_core_data)
+#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() \
+ imx_add_mxc_rtc(&imx31_mxc_rtc_data)
+
+extern const struct imx_mxc_w1_data imx31_mxc_w1_data;
+#define imx31_add_mxc_w1() \
+ 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)
+
+extern const struct imx_pata_imx_data imx31_pata_imx_data;
+#define imx31_add_pata_imx() \
+ imx_add_pata_imx(&imx31_pata_imx_data)
diff --git a/arch/arm/mach-imx/devices-imx35.h b/arch/arm/mach-imx/devices-imx35.h
new file mode 100644
index 000000000..780d82402
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx35.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 "devices/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) \
+ imx_add_flexcan(&imx35_flexcan_data[id])
+#define imx35_add_flexcan0() imx35_add_flexcan(0)
+#define imx35_add_flexcan1() imx35_add_flexcan(1)
+
+extern const struct imx_imx2_wdt_data imx35_imx2_wdt_data;
+#define imx35_add_imx2_wdt() \
+ 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() \
+ imx_add_ipu_core(&imx35_ipu_core_data)
+#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_rtc_data imx35_mxc_rtc_data;
+#define imx35_add_mxc_rtc() \
+ imx_add_mxc_rtc(&imx35_mxc_rtc_data)
+
+extern const struct imx_mxc_w1_data imx35_mxc_w1_data;
+#define imx35_add_mxc_w1() \
+ 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)
+
+extern const struct imx_pata_imx_data imx35_pata_imx_data;
+#define imx35_add_pata_imx() \
+ imx_add_pata_imx(&imx35_pata_imx_data)
diff --git a/arch/arm/mach-imx/devices/Kconfig b/arch/arm/mach-imx/devices/Kconfig
new file mode 100644
index 000000000..3a5529892
--- /dev/null
+++ b/arch/arm/mach-imx/devices/Kconfig
@@ -0,0 +1,74 @@
+config IMX_HAVE_PLATFORM_FEC
+ bool
+ default y if SOC_IMX25 || SOC_IMX27 || SOC_IMX35
+
+config IMX_HAVE_PLATFORM_FLEXCAN
+ bool
+
+config IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ bool
+
+config IMX_HAVE_PLATFORM_GPIO_KEYS
+ bool
+
+config IMX_HAVE_PLATFORM_IMX21_HCD
+ bool
+
+config IMX_HAVE_PLATFORM_IMX27_CODA
+ bool
+ default y if SOC_IMX27
+
+config IMX_HAVE_PLATFORM_IMX2_WDT
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_FB
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_I2C
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_KEYPAD
+ bool
+
+config IMX_HAVE_PLATFORM_PATA_IMX
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_SSI
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_UART
+ bool
+
+config IMX_HAVE_PLATFORM_IPU_CORE
+ bool
+
+config IMX_HAVE_PLATFORM_MX2_CAMERA
+ bool
+
+config IMX_HAVE_PLATFORM_MX2_EMMA
+ 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_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
diff --git a/arch/arm/mach-imx/devices/Makefile b/arch/arm/mach-imx/devices/Makefile
new file mode 100644
index 000000000..e5cf587bc
--- /dev/null
+++ b/arch/arm/mach-imx/devices/Makefile
@@ -0,0 +1,28 @@
+obj-y := devices.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-y += platform-gpio-mxc.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX27_CODA) += platform-imx27-coda.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.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_PATA_IMX) += platform-pata_imx.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SSI) += platform-imx-ssi.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_UART) += platform-imx-uart.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IPU_CORE) += platform-ipu-core.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_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_MX2_EMMA) += platform-mx2-emma.o
diff --git a/arch/arm/mach-imx/devices/devices-common.h b/arch/arm/mach-imx/devices/devices-common.h
new file mode 100644
index 000000000..67f7fb130
--- /dev/null
+++ b/arch/arm/mach-imx/devices/devices-common.h
@@ -0,0 +1,309 @@
+/*
+ * 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/platform_data/dma-imx-sdma.h>
+
+extern struct device mxc_aips_bus;
+extern struct device mxc_ahb_bus;
+
+static inline 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)
+{
+ struct platform_device_info pdevinfo = {
+ .name = name,
+ .id = id,
+ .res = res,
+ .num_res = num_resources,
+ .data = data,
+ .size_data = size_data,
+ .dma_mask = dmamask,
+ };
+ return platform_device_register_full(&pdevinfo);
+}
+
+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);
+}
+
+#include <linux/fec.h>
+struct imx_fec_data {
+ const char *devid;
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_fec(
+ const struct imx_fec_data *data,
+ const struct fec_platform_data *pdata);
+
+struct imx_flexcan_data {
+ 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);
+
+#include <linux/fsl_devices.h>
+struct imx_fsl_usb2_udc_data {
+ const char *devid;
+ 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 <linux/platform_data/usb-mx2.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_imx27_coda_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx27_coda(
+ const struct imx_imx27_coda_data *data);
+
+struct imx_imx2_wdt_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+};
+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);
+
+#include <linux/platform_data/video-imxfb.h>
+struct imx_imx_fb_data {
+ const char *devid;
+ 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 <linux/platform_data/i2c-imx.h>
+struct imx_imx_i2c_data {
+ const char *devid;
+ 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 <linux/platform_data/asoc-imx-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 <linux/platform_data/serial-imx.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 <linux/platform_data/video-mx3fb.h>
+#include <linux/platform_data/camera-mx3.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);
+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);
+
+#include <linux/platform_data/camera-mx2.h>
+struct imx_mx2_camera_data {
+ const char *devid;
+ 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);
+
+
+struct imx_mx2_emma_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_mx2_emmaprp(
+ const struct imx_mx2_emma_data *data);
+
+#include <linux/platform_data/usb-ehci-mxc.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);
+
+#include <linux/platform_data/mmc-mxcmmc.h>
+struct imx_mxc_mmc_data {
+ const char *devid;
+ 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 <linux/platform_data/mtd-mxc_nand.h>
+struct imx_mxc_nand_data {
+ const char *devid;
+ /*
+ * 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_pata_imx_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_pata_imx(
+ const struct imx_pata_imx_data *data);
+
+/* mxc_rtc */
+struct imx_mxc_rtc_data {
+ const char *devid;
+ 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 <linux/platform_data/mmc-esdhc-imx.h>
+struct imx_sdhci_esdhc_imx_data {
+ const char *devid;
+ 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 <linux/platform_data/spi-imx.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);
+
+struct platform_device *imx_add_imx_dma(char *name, resource_size_t iobase,
+ int irq, int irq_err);
+struct platform_device *imx_add_imx_sdma(char *name,
+ resource_size_t iobase, int irq, struct sdma_platform_data *pdata);
diff --git a/arch/arm/mach-imx/devices/devices.c b/arch/arm/mach-imx/devices/devices.c
new file mode 100644
index 000000000..8eab5440d
--- /dev/null
+++ b/arch/arm/mach-imx/devices/devices.c
@@ -0,0 +1,45 @@
+/*
+ * 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>
+
+struct device mxc_aips_bus = {
+ .init_name = "mxc_aips",
+};
+
+struct device mxc_ahb_bus = {
+ .init_name = "mxc_ahb",
+};
+
+int __init mxc_device_init(void)
+{
+ int ret;
+
+ ret = device_register(&mxc_aips_bus);
+ if (ret < 0)
+ goto done;
+
+ ret = device_register(&mxc_ahb_bus);
+
+done:
+ return ret;
+}
diff --git a/arch/arm/mach-imx/devices/platform-fec.c b/arch/arm/mach-imx/devices/platform-fec.c
new file mode 100644
index 000000000..b403a4fe2
--- /dev/null
+++ b/arch/arm/mach-imx/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 "../hardware.h"
+#include "devices-common.h"
+
+#define imx_fec_data_entry_single(soc, _devid) \
+ { \
+ .devid = _devid, \
+ .iobase = soc ## _FEC_BASE_ADDR, \
+ .irq = soc ## _INT_FEC, \
+ }
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_fec_data imx27_fec_data __initconst =
+ imx_fec_data_entry_single(MX27, "imx27-fec");
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX35
+/* i.mx35 has the i.mx27 type fec */
+const struct imx_fec_data imx35_fec_data __initconst =
+ imx_fec_data_entry_single(MX35, "imx27-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,
+ },
+ };
+
+ 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/mach-imx/devices/platform-flexcan.c b/arch/arm/mach-imx/devices/platform-flexcan.c
new file mode 100644
index 000000000..55d61eaf6
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-flexcan.c
@@ -0,0 +1,57 @@
+/*
+ * 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 "../hardware.h"
+#include "devices-common.h"
+
+#define imx_flexcan_data_entry_single(soc, _id, _hwid, _size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _CAN ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_CAN ## _hwid, \
+ }
+
+#define imx_flexcan_data_entry(soc, _id, _hwid, _size) \
+ [_id] = imx_flexcan_data_entry_single(soc, _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, _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, _id, _hwid, SZ_16K)
+ imx35_flexcan_data_entry(0, 1),
+ imx35_flexcan_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+struct platform_device *__init imx_add_flexcan(
+ const struct imx_flexcan_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("flexcan", data->id,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c b/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c
new file mode 100644
index 000000000..25e1de6f3
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c
@@ -0,0 +1,54 @@
+/*
+ * 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 "../hardware.h"
+#include "devices-common.h"
+
+#define imx_fsl_usb2_udc_data_entry_single(soc, _devid) \
+ { \
+ .devid = _devid, \
+ .iobase = soc ## _USB_OTG_BASE_ADDR, \
+ .irq = soc ## _INT_USB_OTG, \
+ }
+
+#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, "imx-udc-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, "imx-udc-mx27");
+#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, "imx-udc-mx27");
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+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,
+ },
+ };
+ return imx_add_platform_device_dmamask(data->devid, -1,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/mach-imx/devices/platform-gpio-mxc.c b/arch/arm/mach-imx/devices/platform-gpio-mxc.c
new file mode 100644
index 000000000..26483fa94
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-gpio-mxc.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 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.
+ */
+#include "devices-common.h"
+
+struct platform_device *__init mxc_register_gpio(char *name, int id,
+ resource_size_t iobase, resource_size_t iosize, int irq, int irq_high)
+{
+ struct resource res[] = {
+ {
+ .start = iobase,
+ .end = iobase + iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = irq,
+ .end = irq,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = irq_high,
+ .end = irq_high,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return platform_device_register_resndata(&mxc_aips_bus,
+ name, id, res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/mach-imx/devices/platform-gpio_keys.c b/arch/arm/mach-imx/devices/platform-gpio_keys.c
new file mode 100644
index 000000000..486282539
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-gpio_keys.c
@@ -0,0 +1,28 @@
+/*
+ * 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 "../hardware.h"
+#include "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/mach-imx/devices/platform-imx-dma.c b/arch/arm/mach-imx/devices/platform-imx-dma.c
new file mode 100644
index 000000000..ccdb5dc4d
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-imx-dma.c
@@ -0,0 +1,51 @@
+/*
+ * 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 "devices-common.h"
+
+struct platform_device __init __maybe_unused *imx_add_imx_dma(char *name,
+ resource_size_t iobase, int irq, int irq_err)
+{
+ struct resource res[] = {
+ {
+ .start = iobase,
+ .end = iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = irq,
+ .end = irq,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = irq_err,
+ .end = irq_err,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return platform_device_register_resndata(&mxc_ahb_bus,
+ name, -1, res, ARRAY_SIZE(res), NULL, 0);
+}
+
+struct platform_device __init __maybe_unused *imx_add_imx_sdma(char *name,
+ resource_size_t iobase, int irq, struct sdma_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = iobase,
+ .end = iobase + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = irq,
+ .end = irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return platform_device_register_resndata(&mxc_ahb_bus, name,
+ -1, res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-imx/devices/platform-imx-fb.c b/arch/arm/mach-imx/devices/platform-imx-fb.c
new file mode 100644
index 000000000..7df632830
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-imx-fb.c
@@ -0,0 +1,55 @@
+/*
+ * 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 "../hardware.h"
+#include "devices-common.h"
+
+#define imx_imx_fb_data_entry_single(soc, _devid, _size) \
+ { \
+ .devid = _devid, \
+ .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, "imx1-fb", 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, "imx21-fb", SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx_fb_data imx27_imx_fb_data __initconst =
+ imx_imx_fb_data_entry_single(MX27, "imx21-fb", 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(data->devid, 0,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/mach-imx/devices/platform-imx-i2c.c b/arch/arm/mach-imx/devices/platform-imx-i2c.c
new file mode 100644
index 000000000..ae9791522
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-imx-i2c.c
@@ -0,0 +1,82 @@
+/*
+ * 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 "../hardware.h"
+#include "devices-common.h"
+
+#define imx_imx_i2c_data_entry_single(soc, _devid, _id, _hwid, _size) \
+ { \
+ .devid = _devid, \
+ .id = _id, \
+ .iobase = soc ## _I2C ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_I2C ## _hwid, \
+ }
+
+#define imx_imx_i2c_data_entry(soc, _devid, _id, _hwid, _size) \
+ [_id] = imx_imx_i2c_data_entry_single(soc, _devid, _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, "imx1-i2c", 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, "imx21-i2c", 0, , SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#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, "imx21-i2c", _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, "imx21-i2c", _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, "imx21-i2c", _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 */
+
+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(data->devid, data->id,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-imx/devices/platform-imx-keypad.c b/arch/arm/mach-imx/devices/platform-imx-keypad.c
new file mode 100644
index 000000000..479e4d70d
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-imx-keypad.c
@@ -0,0 +1,57 @@
+/*
+ * 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 "../hardware.h"
+#include "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_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 */
+
+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/mach-imx/devices/platform-imx-ssi.c b/arch/arm/mach-imx/devices/platform-imx-ssi.c
new file mode 100644
index 000000000..6f0e94eb2
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-imx-ssi.c
@@ -0,0 +1,89 @@
+/*
+ * 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 "../hardware.h"
+#include "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_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 */
+
+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/mach-imx/devices/platform-imx-uart.c b/arch/arm/mach-imx/devices/platform-imx-uart.c
new file mode 100644
index 000000000..6962cff4a
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-imx-uart.c
@@ -0,0 +1,132 @@
+/*
+ * 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 "../hardware.h"
+#include "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_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(MX35, _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 */
+
+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("imx1-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,
+ },
+ };
+
+ /* i.mx21 type uart runs on all i.mx except i.mx1 */
+ return imx_add_platform_device("imx21-uart", data->id,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-imx/devices/platform-imx2-wdt.c b/arch/arm/mach-imx/devices/platform-imx2-wdt.c
new file mode 100644
index 000000000..8c134c8d7
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-imx2-wdt.c
@@ -0,0 +1,55 @@
+/*
+ * 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 "../hardware.h"
+#include "devices-common.h"
+
+#define imx_imx2_wdt_data_entry_single(soc, _id, _hwid, _size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _WDOG ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ }
+#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_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 */
+
+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,
+ },
+ };
+ return imx_add_platform_device("imx2-wdt", data->id,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/mach-imx/devices/platform-imx21-hcd.c b/arch/arm/mach-imx/devices/platform-imx21-hcd.c
new file mode 100644
index 000000000..30c81616a
--- /dev/null
+++ b/arch/arm/mach-imx/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 "../hardware.h"
+#include "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/mach-imx/devices/platform-imx27-coda.c b/arch/arm/mach-imx/devices/platform-imx27-coda.c
new file mode 100644
index 000000000..25bebc29e
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-imx27-coda.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 Vista Silicon
+ * Javier Martin <javier.martin@vista-silicon.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 "../hardware.h"
+#include "devices-common.h"
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx27_coda_data imx27_coda_data __initconst = {
+ .iobase = MX27_VPU_BASE_ADDR,
+ .iosize = SZ_512,
+ .irq = MX27_INT_VPU,
+};
+#endif
+
+struct platform_device *__init imx_add_imx27_coda(
+ const struct imx_imx27_coda_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_dmamask("coda-imx27", 0, res, 2, NULL,
+ 0, DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/mach-imx/devices/platform-ipu-core.c b/arch/arm/mach-imx/devices/platform-ipu-core.c
new file mode 100644
index 000000000..6bd7c3f37
--- /dev/null
+++ b/arch/arm/mach-imx/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 "../hardware.h"
+#include "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)
+{
+ /* 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), NULL, 0);
+}
+
+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)
+ return ERR_PTR(-ENOMEM);
+
+ 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/mach-imx/devices/platform-mx2-camera.c b/arch/arm/mach-imx/devices/platform-mx2-camera.c
new file mode 100644
index 000000000..4c377c332
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-mx2-camera.c
@@ -0,0 +1,62 @@
+/*
+ * 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 "../hardware.h"
+#include "devices-common.h"
+
+#define imx_mx2_camera_data_entry_single(soc, _devid) \
+ { \
+ .devid = _devid, \
+ .iobasecsi = soc ## _CSI_BASE_ADDR, \
+ .iosizecsi = SZ_4K, \
+ .irqcsi = soc ## _INT_CSI, \
+ }
+#define imx_mx2_camera_data_entry_single_emma(soc, _devid) \
+ { \
+ .devid = _devid, \
+ .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_IMX27
+const struct imx_mx2_camera_data imx27_mx2_camera_data __initconst =
+ imx_mx2_camera_data_entry_single_emma(MX27, "imx27-camera");
+#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(data->devid, 0,
+ res, data->iobaseemmaprp ? 4 : 2,
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
+
diff --git a/arch/arm/mach-imx/devices/platform-mx2-emma.c b/arch/arm/mach-imx/devices/platform-mx2-emma.c
new file mode 100644
index 000000000..0dc065182
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-mx2-emma.c
@@ -0,0 +1,40 @@
+/*
+ * 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 "../hardware.h"
+#include "devices-common.h"
+
+#define imx_mx2_emmaprp_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _EMMAPRP_BASE_ADDR, \
+ .iosize = SZ_256, \
+ .irq = soc ## _INT_EMMAPRP, \
+ }
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_mx2_emma_data imx27_mx2_emmaprp_data __initconst =
+ imx_mx2_emmaprp_data_entry_single(MX27);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+struct platform_device *__init imx_add_mx2_emmaprp(
+ const struct imx_mx2_emma_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_dmamask("m2m-emmaprp", 0,
+ res, 2, NULL, 0, DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/mach-imx/devices/platform-mxc-ehci.c b/arch/arm/mach-imx/devices/platform-mxc-ehci.c
new file mode 100644
index 000000000..4537abd2a
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-mxc-ehci.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 <linux/dma-mapping.h>
+
+#include "../hardware.h"
+#include "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_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 */
+
+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));
+}
diff --git a/arch/arm/mach-imx/devices/platform-mxc-mmc.c b/arch/arm/mach-imx/devices/platform-mxc-mmc.c
new file mode 100644
index 000000000..b8203c760
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-mxc-mmc.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 <linux/dma-mapping.h>
+
+#include "../hardware.h"
+#include "devices-common.h"
+
+#define imx_mxc_mmc_data_entry_single(soc, _devid, _id, _hwid, _size) \
+ { \
+ .devid = _devid, \
+ .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, _devid, _id, _hwid, _size) \
+ [_id] = imx_mxc_mmc_data_entry_single(soc, _devid, _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, "imx21-mmc", _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, "imx21-mmc", _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, "imx31-mmc", _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 + data->iosize - 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(data->devid, data->id,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/mach-imx/devices/platform-mxc_nand.c b/arch/arm/mach-imx/devices/platform-mxc_nand.c
new file mode 100644
index 000000000..676df4920
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-mxc_nand.c
@@ -0,0 +1,75 @@
+/*
+ * 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 "../hardware.h"
+#include "devices-common.h"
+
+#define imx_mxc_nand_data_entry_single(soc, _devid, _size) \
+ { \
+ .devid = _devid, \
+ .iobase = soc ## _NFC_BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_NFC \
+ }
+
+#define imx_mxc_nandv3_data_entry_single(soc, _devid, _size) \
+ { \
+ .devid = _devid, \
+ .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, "imx21-nand", SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_mxc_nand_data imx27_mxc_nand_data __initconst =
+ imx_mxc_nand_data_entry_single(MX27, "imx27-nand", 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, "imx27-nand", 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, "imx25-nand", SZ_8K);
+#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->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->axibase,
+ .end = data->axibase + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+ return imx_add_platform_device(data->devid, data->id,
+ res, ARRAY_SIZE(res) - !data->axibase,
+ pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-imx/devices/platform-mxc_rnga.c b/arch/arm/mach-imx/devices/platform-mxc_rnga.c
new file mode 100644
index 000000000..851fbc8af
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-mxc_rnga.c
@@ -0,0 +1,53 @@
+/*
+ * 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 "../hardware.h"
+#include "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);
+
+ return PTR_ERR_OR_ZERO(ret);
+}
+arch_initcall(imxXX_add_mxc_rnga);
diff --git a/arch/arm/mach-imx/devices/platform-mxc_rtc.c b/arch/arm/mach-imx/devices/platform-mxc_rtc.c
new file mode 100644
index 000000000..c7fffaadf
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-mxc_rtc.c
@@ -0,0 +1,46 @@
+/*
+ * 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 "../hardware.h"
+#include "devices-common.h"
+
+#define imx_mxc_rtc_data_entry_single(soc, _devid) \
+ { \
+ .devid = _devid, \
+ .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, "imx21-rtc");
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_mxc_rtc_data imx35_mxc_rtc_data __initconst =
+ imx_mxc_rtc_data_entry_single(MX35, "imx21-rtc");
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+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(data->devid, -1,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/mach-imx/devices/platform-mxc_w1.c b/arch/arm/mach-imx/devices/platform-mxc_w1.c
new file mode 100644
index 000000000..88c18b720
--- /dev/null
+++ b/arch/arm/mach-imx/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 "../hardware.h"
+#include "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/mach-imx/devices/platform-pata_imx.c b/arch/arm/mach-imx/devices/platform-pata_imx.c
new file mode 100644
index 000000000..1c7f895a6
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-pata_imx.c
@@ -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 version 2 as published by the
+ * Free Software Foundation.
+ */
+#include "../hardware.h"
+#include "devices-common.h"
+
+#define imx_pata_imx_data_entry_single(soc, _size) \
+ { \
+ .iobase = soc ## _ATA_BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_ATA, \
+ }
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_pata_imx_data imx27_pata_imx_data __initconst =
+ imx_pata_imx_data_entry_single(MX27, SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_pata_imx_data imx31_pata_imx_data __initconst =
+ imx_pata_imx_data_entry_single(MX31, SZ_16K);
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_pata_imx_data imx35_pata_imx_data __initconst =
+ imx_pata_imx_data_entry_single(MX35, SZ_16K);
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+struct platform_device *__init imx_add_pata_imx(
+ const struct imx_pata_imx_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("pata_imx", -1,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
+
diff --git a/arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c b/arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c
new file mode 100644
index 000000000..a5edd7d60
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2010 Pengutronix, Wolfram Sang <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 <linux/platform_data/mmc-esdhc-imx.h>
+
+#include "../hardware.h"
+#include "devices-common.h"
+
+#define imx_sdhci_esdhc_imx_data_entry_single(soc, _devid, _id, hwid) \
+ { \
+ .devid = _devid, \
+ .id = _id, \
+ .iobase = soc ## _ESDHC ## hwid ## _BASE_ADDR, \
+ .irq = soc ## _INT_ESDHC ## hwid, \
+ }
+
+#define imx_sdhci_esdhc_imx_data_entry(soc, devid, id, hwid) \
+ [id] = imx_sdhci_esdhc_imx_data_entry_single(soc, devid, 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, "sdhci-esdhc-imx25", _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, "sdhci-esdhc-imx35", _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 */
+
+static const struct esdhc_platform_data default_esdhc_pdata __initconst = {
+ .wp_type = ESDHC_WP_NONE,
+ .cd_type = ESDHC_CD_NONE,
+};
+
+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,
+ },
+ };
+
+ /*
+ * If machine does not provide pdata, use the default one
+ * which means no WP/CD support
+ */
+ if (!pdata)
+ pdata = &default_esdhc_pdata;
+
+ return imx_add_platform_device(data->devid, data->id, res,
+ ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-imx/devices/platform-spi_imx.c b/arch/arm/mach-imx/devices/platform-spi_imx.c
new file mode 100644
index 000000000..5e9707b47
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-spi_imx.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 "../hardware.h"
+#include "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_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 */
+
+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/mach-imx/ehci-imx27.c b/arch/arm/mach-imx/ehci-imx27.c
new file mode 100644
index 000000000..c56974346
--- /dev/null
+++ b/arch/arm/mach-imx/ehci-imx27.c
@@ -0,0 +1,83 @@
+/*
+ * 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 <linux/platform_data/usb-ehci-mxc.h>
+
+#include "ehci.h"
+#include "hardware.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 000000000..bede21d9b
--- /dev/null
+++ b/arch/arm/mach-imx/ehci-imx31.c
@@ -0,0 +1,83 @@
+/*
+ * 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 <linux/platform_data/usb-ehci-mxc.h>
+
+#include "ehci.h"
+#include "hardware.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 000000000..f424a5437
--- /dev/null
+++ b/arch/arm/mach-imx/ehci-imx35.c
@@ -0,0 +1,98 @@
+/*
+ * 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 <linux/platform_data/usb-ehci-mxc.h>
+
+#include "ehci.h"
+#include "hardware.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_OTG_PP_BIT (1 << 11)
+#define MX35_OTG_OCPOL_BIT (1 << 3)
+
+#define MX35_H1_SIC_SHIFT 21
+#define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT)
+#define MX35_H1_PP_BIT (1 << 18)
+#define MX35_H1_PM_BIT (1 << 16)
+#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)
+#define MX35_H1_OCPOL_BIT (1 << 2)
+
+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 | MX35_OTG_PP_BIT |
+ MX35_OTG_OCPOL_BIT);
+ v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_OTG_SIC_SHIFT;
+
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+ v |= MX35_OTG_PM_BIT;
+
+ if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
+ v |= MX35_OTG_PP_BIT;
+
+ if (!(flags & MXC_EHCI_OC_PIN_ACTIVE_LOW))
+ v |= MX35_OTG_OCPOL_BIT;
+
+ break;
+ case 1: /* H1 port */
+ v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_PP_BIT |
+ MX35_H1_OCPOL_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_PWR_PIN_ACTIVE_HIGH)
+ v |= MX35_H1_PP_BIT;
+
+ if (!(flags & MXC_EHCI_OC_PIN_ACTIVE_LOW))
+ v |= MX35_H1_OCPOL_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/ehci.h b/arch/arm/mach-imx/ehci.h
new file mode 100644
index 000000000..0e060023d
--- /dev/null
+++ b/arch/arm/mach-imx/ehci.h
@@ -0,0 +1,43 @@
+#ifndef __MACH_IMX_EHCI_H
+#define __MACH_IMX_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_PWR_PIN_ACTIVE_HIGH (1 << 6)
+#define MXC_EHCI_OC_PIN_ACTIVE_LOW (1 << 7)
+#define MXC_EHCI_TTL_ENABLED (1 << 8)
+
+#define MXC_EHCI_INTERNAL_PHY (1 << 9)
+#define MXC_EHCI_IPPUE_DOWN (1 << 10)
+#define MXC_EHCI_IPPUE_UP (1 << 11)
+#define MXC_EHCI_WAKEUP_ENABLED (1 << 12)
+#define MXC_EHCI_ITC_NO_THRESHOLD (1 << 13)
+
+#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
+
+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 /* __MACH_IMX_EHCI_H */
diff --git a/arch/arm/mach-imx/epit.c b/arch/arm/mach-imx/epit.c
new file mode 100644
index 000000000..074b1a81b
--- /dev/null
+++ b/arch/arm/mach-imx/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 <linux/err.h>
+#include <asm/mach/time.h>
+
+#include "common.h"
+#include "hardware.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_TIMER | IRQF_IRQPOLL,
+ .handler = epit_timer_interrupt,
+};
+
+static struct clock_event_device clockevent_epit = {
+ .name = "epit",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .set_mode = epit_set_mode,
+ .set_next_event = epit_set_next_event,
+ .rating = 200,
+};
+
+static int __init epit_clockevent_init(struct clk *timer_clk)
+{
+ clockevent_epit.cpumask = cpumask_of(0);
+ clockevents_config_and_register(&clockevent_epit,
+ clk_get_rate(timer_clk),
+ 0x800, 0xfffffffe);
+
+ return 0;
+}
+
+void __init epit_timer_init(void __iomem *base, int irq)
+{
+ struct clk *timer_clk;
+
+ timer_clk = clk_get_sys("imx-epit.0", NULL);
+ if (IS_ERR(timer_clk)) {
+ pr_err("i.MX epit: unable to get clk\n");
+ return;
+ }
+
+ clk_prepare_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/mach-imx/eukrea-baseboards.h b/arch/arm/mach-imx/eukrea-baseboards.h
new file mode 100644
index 000000000..bb2c90d65
--- /dev/null
+++ b/arch/arm/mach-imx/eukrea-baseboards.h
@@ -0,0 +1,42 @@
+/*
+ * 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() or eukrea_cpuimx35_init()
+ *
+ * This example here is for the development board. Refer
+ * mach-mx25/eukrea_mbimxsd-baseboard.c for cpuimx25
+ * mach-mx3/eukrea_mbimxsd-baseboard.c for cpuimx35
+ */
+
+extern void eukrea_mbimxsd25_baseboard_init(void);
+extern void eukrea_mbimxsd35_baseboard_init(void);
+
+#endif
+
+#endif /* __MACH_EUKREA_BASEBOARDS_H__ */
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 000000000..6edc940e0
--- /dev/null
+++ b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
@@ -0,0 +1,318 @@
+/*
+ * 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 <linux/spi/spi.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 "common.h"
+#include "devices-imx35.h"
+#include "hardware.h"
+#include "iomux-mx35.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 struct mx3fb_platform_data mx3fb_pdata __initdata = {
+ .name = "CMO-QVGA",
+ .mode = fb_modedb,
+ .num_modes = ARRAY_SIZE(fb_modedb),
+};
+
+static const iomux_v3_cfg_t eukrea_mbimxsd_pads[] __initconst = {
+ /* 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,
+ /* SPI */
+ MX35_PAD_CSPI1_MOSI__CSPI1_MOSI,
+ MX35_PAD_CSPI1_MISO__CSPI1_MISO,
+ MX35_PAD_CSPI1_SS0__GPIO1_18,
+ MX35_PAD_CSPI1_SS1__GPIO1_19,
+ MX35_PAD_CSPI1_SCLK__CSPI1_SCLK,
+ MX35_PAD_CSPI1_SPI_RDY__GPIO3_5,
+};
+
+#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)
+#define GPIO_SPI1_SS0 IMX_GPIO_NR(1, 18)
+#define GPIO_SPI1_SS1 IMX_GPIO_NR(1, 19)
+#define GPIO_SPI1_IRQ IMX_GPIO_NR(3, 5)
+
+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 const struct gpio_led_platform_data
+ eukrea_mbimxsd_led_info __initconst = {
+ .leds = eukrea_mbimxsd_leds,
+ .num_leds = ARRAY_SIZE(eukrea_mbimxsd_leds),
+};
+
+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_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,
+ .cd_type = ESDHC_CD_GPIO,
+ .wp_type = ESDHC_WP_NONE,
+};
+
+static struct spi_board_info eukrea_mbimxsd35_spi_board_info[] __initdata = {
+ {
+ .modalias = "spidev",
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ },
+ {
+ .modalias = "spidev",
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ },
+};
+
+static int eukrea_mbimxsd35_spi_cs[] = {GPIO_SPI1_SS0, GPIO_SPI1_SS1};
+
+static const struct spi_imx_master eukrea_mbimxsd35_spi0_data __initconst = {
+ .chipselect = eukrea_mbimxsd35_spi_cs,
+ .num_chipselect = ARRAY_SIZE(eukrea_mbimxsd35_spi_cs),
+};
+
+/*
+ * 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");
+
+ imx35_add_imx_uart1(&uart_pdata);
+ imx35_add_ipu_core();
+ imx35_add_mx3_sdc_fb(&mx3fb_pdata);
+
+ imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
+
+ imx35_add_flexcan1();
+ 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));
+
+ gpio_request(GPIO_SPI1_IRQ, "SPI1_IRQ");
+ gpio_direction_input(GPIO_SPI1_IRQ);
+ gpio_free(GPIO_SPI1_IRQ);
+ imx35_add_spi_imx0(&eukrea_mbimxsd35_spi0_data);
+ spi_register_board_info(eukrea_mbimxsd35_spi_board_info,
+ ARRAY_SIZE(eukrea_mbimxsd35_spi_board_info));
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ gpio_led_register_device(-1, &eukrea_mbimxsd_led_info);
+ imx_add_gpio_keys(&eukrea_mbimxsd_button_data);
+ imx_add_platform_device("eukrea_tlv320", 0, NULL, 0, NULL, 0);
+}
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
new file mode 100644
index 000000000..6d0893a38
--- /dev/null
+++ b/arch/arm/mach-imx/gpc.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright 2011-2013 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/regulator/consumer.h>
+#include <linux/irqchip/arm-gic.h>
+#include "common.h"
+#include "hardware.h"
+
+#define GPC_CNTR 0x000
+#define GPC_IMR1 0x008
+#define GPC_PGC_GPU_PDN 0x260
+#define GPC_PGC_GPU_PUPSCR 0x264
+#define GPC_PGC_GPU_PDNSCR 0x268
+#define GPC_PGC_CPU_PDN 0x2a0
+#define GPC_PGC_CPU_PUPSCR 0x2a4
+#define GPC_PGC_CPU_PDNSCR 0x2a8
+#define GPC_PGC_SW2ISO_SHIFT 0x8
+#define GPC_PGC_SW_SHIFT 0x0
+
+#define IMR_NUM 4
+#define GPC_MAX_IRQS (IMR_NUM * 32)
+
+#define GPU_VPU_PUP_REQ BIT(1)
+#define GPU_VPU_PDN_REQ BIT(0)
+
+#define GPC_CLK_MAX 6
+
+struct pu_domain {
+ struct generic_pm_domain base;
+ struct regulator *reg;
+ struct clk *clk[GPC_CLK_MAX];
+ int num_clks;
+};
+
+static void __iomem *gpc_base;
+static u32 gpc_wake_irqs[IMR_NUM];
+static u32 gpc_saved_imrs[IMR_NUM];
+
+void imx_gpc_set_arm_power_up_timing(u32 sw2iso, u32 sw)
+{
+ writel_relaxed((sw2iso << GPC_PGC_SW2ISO_SHIFT) |
+ (sw << GPC_PGC_SW_SHIFT), gpc_base + GPC_PGC_CPU_PUPSCR);
+}
+
+void imx_gpc_set_arm_power_down_timing(u32 sw2iso, u32 sw)
+{
+ writel_relaxed((sw2iso << GPC_PGC_SW2ISO_SHIFT) |
+ (sw << GPC_PGC_SW_SHIFT), gpc_base + GPC_PGC_CPU_PDNSCR);
+}
+
+void imx_gpc_set_arm_power_in_lpm(bool power_off)
+{
+ writel_relaxed(power_off, gpc_base + GPC_PGC_CPU_PDN);
+}
+
+void imx_gpc_pre_suspend(bool arm_power_off)
+{
+ void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
+ int i;
+
+ /* Tell GPC to power off ARM core when suspend */
+ if (arm_power_off)
+ imx_gpc_set_arm_power_in_lpm(arm_power_off);
+
+ for (i = 0; i < IMR_NUM; i++) {
+ gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
+ writel_relaxed(~gpc_wake_irqs[i], reg_imr1 + i * 4);
+ }
+}
+
+void imx_gpc_post_resume(void)
+{
+ void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
+ int i;
+
+ /* Keep ARM core powered on for other low-power modes */
+ imx_gpc_set_arm_power_in_lpm(false);
+
+ for (i = 0; i < IMR_NUM; i++)
+ writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
+}
+
+static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+ unsigned int idx = d->hwirq / 32;
+ u32 mask;
+
+ mask = 1 << d->hwirq % 32;
+ gpc_wake_irqs[idx] = on ? gpc_wake_irqs[idx] | mask :
+ gpc_wake_irqs[idx] & ~mask;
+
+ /*
+ * Do *not* call into the parent, as the GIC doesn't have any
+ * wake-up facility...
+ */
+ return 0;
+}
+
+void imx_gpc_mask_all(void)
+{
+ void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
+ int i;
+
+ for (i = 0; i < IMR_NUM; i++) {
+ gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
+ writel_relaxed(~0, reg_imr1 + i * 4);
+ }
+
+}
+
+void imx_gpc_restore_all(void)
+{
+ void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
+ int i;
+
+ for (i = 0; i < IMR_NUM; i++)
+ writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
+}
+
+void imx_gpc_hwirq_unmask(unsigned int hwirq)
+{
+ void __iomem *reg;
+ u32 val;
+
+ reg = gpc_base + GPC_IMR1 + hwirq / 32 * 4;
+ val = readl_relaxed(reg);
+ val &= ~(1 << hwirq % 32);
+ writel_relaxed(val, reg);
+}
+
+void imx_gpc_hwirq_mask(unsigned int hwirq)
+{
+ void __iomem *reg;
+ u32 val;
+
+ reg = gpc_base + GPC_IMR1 + hwirq / 32 * 4;
+ val = readl_relaxed(reg);
+ val |= 1 << (hwirq % 32);
+ writel_relaxed(val, reg);
+}
+
+static void imx_gpc_irq_unmask(struct irq_data *d)
+{
+ imx_gpc_hwirq_unmask(d->hwirq);
+ irq_chip_unmask_parent(d);
+}
+
+static void imx_gpc_irq_mask(struct irq_data *d)
+{
+ imx_gpc_hwirq_mask(d->hwirq);
+ irq_chip_mask_parent(d);
+}
+
+static struct irq_chip imx_gpc_chip = {
+ .name = "GPC",
+ .irq_eoi = irq_chip_eoi_parent,
+ .irq_mask = imx_gpc_irq_mask,
+ .irq_unmask = imx_gpc_irq_unmask,
+ .irq_retrigger = irq_chip_retrigger_hierarchy,
+ .irq_set_wake = imx_gpc_irq_set_wake,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = irq_chip_set_affinity_parent,
+#endif
+};
+
+static int imx_gpc_domain_xlate(struct irq_domain *domain,
+ struct device_node *controller,
+ const u32 *intspec,
+ unsigned int intsize,
+ unsigned long *out_hwirq,
+ unsigned int *out_type)
+{
+ if (domain->of_node != controller)
+ return -EINVAL; /* Shouldn't happen, really... */
+ if (intsize != 3)
+ return -EINVAL; /* Not GIC compliant */
+ if (intspec[0] != 0)
+ return -EINVAL; /* No PPI should point to this domain */
+
+ *out_hwirq = intspec[1];
+ *out_type = intspec[2];
+ return 0;
+}
+
+static int imx_gpc_domain_alloc(struct irq_domain *domain,
+ unsigned int irq,
+ unsigned int nr_irqs, void *data)
+{
+ struct of_phandle_args *args = data;
+ struct of_phandle_args parent_args;
+ irq_hw_number_t hwirq;
+ int i;
+
+ if (args->args_count != 3)
+ return -EINVAL; /* Not GIC compliant */
+ if (args->args[0] != 0)
+ return -EINVAL; /* No PPI should point to this domain */
+
+ hwirq = args->args[1];
+ if (hwirq >= GPC_MAX_IRQS)
+ return -EINVAL; /* Can't deal with this */
+
+ for (i = 0; i < nr_irqs; i++)
+ irq_domain_set_hwirq_and_chip(domain, irq + i, hwirq + i,
+ &imx_gpc_chip, NULL);
+
+ parent_args = *args;
+ parent_args.np = domain->parent->of_node;
+ return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, &parent_args);
+}
+
+static struct irq_domain_ops imx_gpc_domain_ops = {
+ .xlate = imx_gpc_domain_xlate,
+ .alloc = imx_gpc_domain_alloc,
+ .free = irq_domain_free_irqs_common,
+};
+
+static int __init imx_gpc_init(struct device_node *node,
+ struct device_node *parent)
+{
+ struct irq_domain *parent_domain, *domain;
+ int i;
+
+ if (!parent) {
+ pr_err("%s: no parent, giving up\n", node->full_name);
+ return -ENODEV;
+ }
+
+ parent_domain = irq_find_host(parent);
+ if (!parent_domain) {
+ pr_err("%s: unable to obtain parent domain\n", node->full_name);
+ return -ENXIO;
+ }
+
+ gpc_base = of_iomap(node, 0);
+ if (WARN_ON(!gpc_base))
+ return -ENOMEM;
+
+ domain = irq_domain_add_hierarchy(parent_domain, 0, GPC_MAX_IRQS,
+ node, &imx_gpc_domain_ops,
+ NULL);
+ if (!domain) {
+ iounmap(gpc_base);
+ return -ENOMEM;
+ }
+
+ /* Initially mask all interrupts */
+ for (i = 0; i < IMR_NUM; i++)
+ writel_relaxed(~0, gpc_base + GPC_IMR1 + i * 4);
+
+ return 0;
+}
+
+/*
+ * We cannot use the IRQCHIP_DECLARE macro that lives in
+ * drivers/irqchip, so we're forced to roll our own. Not very nice.
+ */
+OF_DECLARE_2(irqchip, imx_gpc, "fsl,imx6q-gpc", imx_gpc_init);
+
+void __init imx_gpc_check_dt(void)
+{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
+ if (WARN_ON(!np))
+ return;
+
+ if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL))) {
+ pr_warn("Outdated DT detected, suspend/resume will NOT work\n");
+
+ /* map GPC, so that at least CPUidle and WARs keep working */
+ gpc_base = of_iomap(np, 0);
+ }
+}
+
+#ifdef CONFIG_PM_GENERIC_DOMAINS
+
+static void _imx6q_pm_pu_power_off(struct generic_pm_domain *genpd)
+{
+ int iso, iso2sw;
+ u32 val;
+
+ /* Read ISO and ISO2SW power down delays */
+ val = readl_relaxed(gpc_base + GPC_PGC_GPU_PDNSCR);
+ iso = val & 0x3f;
+ iso2sw = (val >> 8) & 0x3f;
+
+ /* Gate off PU domain when GPU/VPU when powered down */
+ writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN);
+
+ /* Request GPC to power down GPU/VPU */
+ val = readl_relaxed(gpc_base + GPC_CNTR);
+ val |= GPU_VPU_PDN_REQ;
+ writel_relaxed(val, gpc_base + GPC_CNTR);
+
+ /* Wait ISO + ISO2SW IPG clock cycles */
+ ndelay((iso + iso2sw) * 1000 / 66);
+}
+
+static int imx6q_pm_pu_power_off(struct generic_pm_domain *genpd)
+{
+ struct pu_domain *pu = container_of(genpd, struct pu_domain, base);
+
+ _imx6q_pm_pu_power_off(genpd);
+
+ if (pu->reg)
+ regulator_disable(pu->reg);
+
+ return 0;
+}
+
+static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd)
+{
+ struct pu_domain *pu = container_of(genpd, struct pu_domain, base);
+ int i, ret, sw, sw2iso;
+ u32 val;
+
+ if (pu->reg)
+ ret = regulator_enable(pu->reg);
+ if (pu->reg && ret) {
+ pr_err("%s: failed to enable regulator: %d\n", __func__, ret);
+ return ret;
+ }
+
+ /* Enable reset clocks for all devices in the PU domain */
+ for (i = 0; i < pu->num_clks; i++)
+ clk_prepare_enable(pu->clk[i]);
+
+ /* Gate off PU domain when GPU/VPU when powered down */
+ writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN);
+
+ /* Read ISO and ISO2SW power down delays */
+ val = readl_relaxed(gpc_base + GPC_PGC_GPU_PUPSCR);
+ sw = val & 0x3f;
+ sw2iso = (val >> 8) & 0x3f;
+
+ /* Request GPC to power up GPU/VPU */
+ val = readl_relaxed(gpc_base + GPC_CNTR);
+ val |= GPU_VPU_PUP_REQ;
+ writel_relaxed(val, gpc_base + GPC_CNTR);
+
+ /* Wait ISO + ISO2SW IPG clock cycles */
+ ndelay((sw + sw2iso) * 1000 / 66);
+
+ /* Disable reset clocks for all devices in the PU domain */
+ for (i = 0; i < pu->num_clks; i++)
+ clk_disable_unprepare(pu->clk[i]);
+
+ return 0;
+}
+
+static struct generic_pm_domain imx6q_arm_domain = {
+ .name = "ARM",
+};
+
+static struct pu_domain imx6q_pu_domain = {
+ .base = {
+ .name = "PU",
+ .power_off = imx6q_pm_pu_power_off,
+ .power_on = imx6q_pm_pu_power_on,
+ .power_off_latency_ns = 25000,
+ .power_on_latency_ns = 2000000,
+ },
+};
+
+static struct generic_pm_domain imx6sl_display_domain = {
+ .name = "DISPLAY",
+};
+
+static struct generic_pm_domain *imx_gpc_domains[] = {
+ &imx6q_arm_domain,
+ &imx6q_pu_domain.base,
+ &imx6sl_display_domain,
+};
+
+static struct genpd_onecell_data imx_gpc_onecell_data = {
+ .domains = imx_gpc_domains,
+ .num_domains = ARRAY_SIZE(imx_gpc_domains),
+};
+
+static int imx_gpc_genpd_init(struct device *dev, struct regulator *pu_reg)
+{
+ struct clk *clk;
+ bool is_off;
+ int i;
+
+ imx6q_pu_domain.reg = pu_reg;
+
+ for (i = 0; ; i++) {
+ clk = of_clk_get(dev->of_node, i);
+ if (IS_ERR(clk))
+ break;
+ if (i >= GPC_CLK_MAX) {
+ dev_err(dev, "more than %d clocks\n", GPC_CLK_MAX);
+ goto clk_err;
+ }
+ imx6q_pu_domain.clk[i] = clk;
+ }
+ imx6q_pu_domain.num_clks = i;
+
+ is_off = IS_ENABLED(CONFIG_PM);
+ if (is_off) {
+ _imx6q_pm_pu_power_off(&imx6q_pu_domain.base);
+ } else {
+ /*
+ * Enable power if compiled without CONFIG_PM in case the
+ * bootloader disabled it.
+ */
+ imx6q_pm_pu_power_on(&imx6q_pu_domain.base);
+ }
+
+ pm_genpd_init(&imx6q_pu_domain.base, NULL, is_off);
+ return of_genpd_add_provider_onecell(dev->of_node,
+ &imx_gpc_onecell_data);
+
+clk_err:
+ while (i--)
+ clk_put(imx6q_pu_domain.clk[i]);
+ return -EINVAL;
+}
+
+#else
+static inline int imx_gpc_genpd_init(struct device *dev, struct regulator *reg)
+{
+ return 0;
+}
+#endif /* CONFIG_PM_GENERIC_DOMAINS */
+
+static int imx_gpc_probe(struct platform_device *pdev)
+{
+ struct regulator *pu_reg;
+ int ret;
+
+ /* bail out if DT too old and doesn't provide the necessary info */
+ if (!of_property_read_bool(pdev->dev.of_node, "#power-domain-cells"))
+ return 0;
+
+ pu_reg = devm_regulator_get_optional(&pdev->dev, "pu");
+ if (PTR_ERR(pu_reg) == -ENODEV)
+ pu_reg = NULL;
+ if (IS_ERR(pu_reg)) {
+ ret = PTR_ERR(pu_reg);
+ dev_err(&pdev->dev, "failed to get pu regulator: %d\n", ret);
+ return ret;
+ }
+
+ return imx_gpc_genpd_init(&pdev->dev, pu_reg);
+}
+
+static const struct of_device_id imx_gpc_dt_ids[] = {
+ { .compatible = "fsl,imx6q-gpc" },
+ { .compatible = "fsl,imx6sl-gpc" },
+ { }
+};
+
+static struct platform_driver imx_gpc_driver = {
+ .driver = {
+ .name = "imx-gpc",
+ .owner = THIS_MODULE,
+ .of_match_table = imx_gpc_dt_ids,
+ },
+ .probe = imx_gpc_probe,
+};
+
+static int __init imx_pgc_init(void)
+{
+ return platform_driver_register(&imx_gpc_driver);
+}
+subsys_initcall(imx_pgc_init);
diff --git a/arch/arm/mach-imx/hardware.h b/arch/arm/mach-imx/hardware.h
new file mode 100644
index 000000000..76af2c03c
--- /dev/null
+++ b/arch/arm/mach-imx/hardware.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2004-2007, 2014 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_HARDWARE_H__
+#define __ASM_ARCH_MXC_HARDWARE_H__
+
+#ifndef __ASSEMBLY__
+#include <asm/io.h>
+#endif
+#include <asm/sizes.h>
+
+#define addr_in_module(addr, mod) \
+ ((unsigned long)(addr) - mod ## _BASE_ADDR < mod ## _SIZE)
+
+#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 -> 0xf5000000+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 -> 0xf5000000+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 -> 0xf5c00000+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 -> 0xf5c00000+0x010000
+ * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000
+ * mx51:
+ * TZIC 0x0fffc000+0x004000 -> 0xf4bfc000+0x004000
+ * IRAM 0x1ffe0000+0x020000 -> 0xf4fe0000+0x020000
+ * DEBUG 0x60000000+0x100000 -> 0xf5000000+0x100000
+ * SPBA0 0x70000000+0x100000 -> 0xf5400000+0x100000
+ * AIPS1 0x73f00000+0x100000 -> 0xf5700000+0x100000
+ * AIPS2 0x83f00000+0x100000 -> 0xf5300000+0x100000
+ * mx53:
+ * TZIC 0x0fffc000+0x004000 -> 0xf4bfc000+0x004000
+ * DEBUG 0x40000000+0x100000 -> 0xf5000000+0x100000
+ * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000
+ * AIPS1 0x53f00000+0x100000 -> 0xf5700000+0x100000
+ * AIPS2 0x63f00000+0x100000 -> 0xf5300000+0x100000
+ * mx6q:
+ * SCU 0x00a00000+0x004000 -> 0xf4000000+0x004000
+ * CCM 0x020c4000+0x004000 -> 0xf42c4000+0x004000
+ * ANATOP 0x020c8000+0x004000 -> 0xf42c8000+0x004000
+ * UART4 0x021f0000+0x004000 -> 0xf42f0000+0x004000
+ */
+#define IMX_IO_P2V(x) ( \
+ (((x) & 0x80000000) >> 7) | \
+ (0xf4000000 + \
+ (((x) & 0x50000000) >> 6) + \
+ (((x) & 0x0b000000) >> 4) + \
+ (((x) & 0x000fffff))))
+
+#define IMX_IO_ADDRESS(x) IOMEM(IMX_IO_P2V(x))
+
+#include "mxc.h"
+
+#include "mx3x.h"
+#include "mx31.h"
+#include "mx35.h"
+#include "mx2x.h"
+#include "mx21.h"
+#include "mx27.h"
+#include "mx1.h"
+
+#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, \
+}
+
+/* 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))
+
+#endif /* __ASM_ARCH_MXC_HARDWARE_H__ */
diff --git a/arch/arm/mach-imx/headsmp.S b/arch/arm/mach-imx/headsmp.S
new file mode 100644
index 000000000..de5047c8a
--- /dev/null
+++ b/arch/arm/mach-imx/headsmp.S
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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>
+#include <linux/init.h>
+
+diag_reg_offset:
+ .word g_diag_reg - .
+
+ .macro set_diag_reg
+ adr r0, diag_reg_offset
+ ldr r1, [r0]
+ add r1, r1, r0 @ r1 = physical &g_diag_reg
+ ldr r0, [r1]
+ mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
+ .endm
+
+ENTRY(v7_secondary_startup)
+ bl v7_invalidate_l1
+ set_diag_reg
+ b secondary_startup
+ENDPROC(v7_secondary_startup)
diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c
new file mode 100644
index 000000000..b35e99cc5
--- /dev/null
+++ b/arch/arm/mach-imx/hotplug.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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/errno.h>
+#include <linux/jiffies.h>
+#include <asm/cp15.h>
+#include <asm/proc-fns.h>
+
+#include "common.h"
+
+static inline void cpu_enter_lowpower(void)
+{
+ unsigned int v;
+
+ 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");
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void imx_cpu_die(unsigned int cpu)
+{
+ cpu_enter_lowpower();
+ /*
+ * We use the cpu jumping argument register to sync with
+ * imx_cpu_kill() which is running on cpu0 and waiting for
+ * the register being cleared to kill the cpu.
+ */
+ imx_set_cpu_arg(cpu, ~0);
+
+ while (1)
+ cpu_do_idle();
+}
+
+int imx_cpu_kill(unsigned int cpu)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(50);
+
+ while (imx_get_cpu_arg(cpu) == 0)
+ if (time_after(jiffies, timeout))
+ return 0;
+ imx_enable_cpu(cpu, false);
+ imx_set_cpu_arg(cpu, 0);
+ return 1;
+}
diff --git a/arch/arm/mach-imx/iim.h b/arch/arm/mach-imx/iim.h
new file mode 100644
index 000000000..315bffada
--- /dev/null
+++ b/arch/arm/mach-imx/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/mach-imx/imx1-dt.c b/arch/arm/mach-imx/imx1-dt.c
new file mode 100644
index 000000000..6f915b096
--- /dev/null
+++ b/arch/arm/mach-imx/imx1-dt.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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/of_platform.h>
+#include <asm/mach/arch.h>
+
+#include "common.h"
+
+static const char * const imx1_dt_board_compat[] __initconst = {
+ "fsl,imx1",
+ NULL
+};
+
+DT_MACHINE_START(IMX1_DT, "Freescale i.MX1 (Device Tree Support)")
+ .map_io = mx1_map_io,
+ .init_early = imx1_init_early,
+ .init_irq = mx1_init_irq,
+ .dt_compat = imx1_dt_board_compat,
+ .restart = mxc_restart,
+MACHINE_END
diff --git a/arch/arm/mach-imx/imx27-dt.c b/arch/arm/mach-imx/imx27-dt.c
new file mode 100644
index 000000000..bd42d1bd1
--- /dev/null
+++ b/arch/arm/mach-imx/imx27-dt.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2012 Sascha Hauer, Pengutronix
+ *
+ * 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/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "common.h"
+#include "mx27.h"
+
+static void __init imx27_dt_init(void)
+{
+ struct platform_device_info devinfo = { .name = "cpufreq-dt", };
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+ platform_device_register_full(&devinfo);
+}
+
+static const char * const imx27_dt_board_compat[] __initconst = {
+ "fsl,imx27",
+ NULL
+};
+
+DT_MACHINE_START(IMX27_DT, "Freescale i.MX27 (Device Tree Support)")
+ .map_io = mx27_map_io,
+ .init_early = imx27_init_early,
+ .init_irq = mx27_init_irq,
+ .init_machine = imx27_dt_init,
+ .dt_compat = imx27_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-imx/imx31-dt.c b/arch/arm/mach-imx/imx31-dt.c
new file mode 100644
index 000000000..32100222a
--- /dev/null
+++ b/arch/arm/mach-imx/imx31-dt.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2012 Sascha Hauer, Pengutronix
+ *
+ * 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/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "common.h"
+#include "mx31.h"
+
+static const char * const imx31_dt_board_compat[] __initconst = {
+ "fsl,imx31",
+ NULL
+};
+
+static void __init imx31_dt_timer_init(void)
+{
+ mx31_clocks_init_dt();
+}
+
+DT_MACHINE_START(IMX31_DT, "Freescale i.MX31 (Device Tree Support)")
+ .map_io = mx31_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .init_time = imx31_dt_timer_init,
+ .dt_compat = imx31_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-imx/imx35-dt.c b/arch/arm/mach-imx/imx35-dt.c
new file mode 100644
index 000000000..e93960372
--- /dev/null
+++ b/arch/arm/mach-imx/imx35-dt.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2012 Steffen Trumtrar, Pengutronix
+ *
+ * based on imx27-dt.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/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/cache-l2x0.h>
+#include "common.h"
+#include "mx35.h"
+
+static void __init imx35_irq_init(void)
+{
+ imx_init_l2cache();
+ mx35_init_irq();
+}
+
+static const char * const imx35_dt_board_compat[] __initconst = {
+ "fsl,imx35",
+ NULL
+};
+
+DT_MACHINE_START(IMX35_DT, "Freescale i.MX35 (Device Tree Support)")
+ .map_io = mx35_map_io,
+ .init_early = imx35_init_early,
+ .init_irq = imx35_irq_init,
+ .dt_compat = imx35_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-imx/iomux-imx31.c b/arch/arm/mach-imx/iomux-imx31.c
new file mode 100644
index 000000000..d6a30753c
--- /dev/null
+++ b/arch/arm/mach-imx/iomux-imx31.c
@@ -0,0 +1,174 @@
+/*
+ * 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/gpio.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+
+#include "hardware.h"
+#include "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)
+
+static unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG];
+/*
+ * set the mode for a IOMUX pin.
+ */
+void mxc_iomux_mode(unsigned int pin_mode)
+{
+ u32 field;
+ u32 l;
+ u32 mode;
+ 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);
+}
+
+/*
+ * 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);
+}
+
+/*
+ * 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;
+}
+
+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;
+}
+
+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);
+}
+
+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++;
+ }
+}
+
+/*
+ * 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);
+}
diff --git a/arch/arm/mach-imx/iomux-mx1.h b/arch/arm/mach-imx/iomux-mx1.h
new file mode 100644
index 000000000..95f4681d8
--- /dev/null
+++ b/arch/arm/mach-imx/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 "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/mach-imx/iomux-mx21.h b/arch/arm/mach-imx/iomux-mx21.h
new file mode 100644
index 000000000..a70cffceb
--- /dev/null
+++ b/arch/arm/mach-imx/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 "iomux-mx2x.h"
+#include "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/mach-imx/iomux-mx27.h b/arch/arm/mach-imx/iomux-mx27.h
new file mode 100644
index 000000000..218e99e89
--- /dev/null
+++ b/arch/arm/mach-imx/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 "iomux-mx2x.h"
+#include "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/mach-imx/iomux-mx2x.h b/arch/arm/mach-imx/iomux-mx2x.h
new file mode 100644
index 000000000..7a9b20abd
--- /dev/null
+++ b/arch/arm/mach-imx/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/mach-imx/iomux-mx3.h b/arch/arm/mach-imx/iomux-mx3.h
new file mode 100644
index 000000000..2e4a0ddca
--- /dev/null
+++ b/arch/arm/mach-imx/iomux-mx3.h
@@ -0,0 +1,753 @@
+/*
+ * 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 multiple 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
+ */
+void 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)
+
+/*
+ * 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_RTS1__SFS IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_ALT2)
+#define MX31_PIN_TXD1__TXD1 IOMUX_MODE(MX31_PIN_TXD1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_TXD1__SCK IOMUX_MODE(MX31_PIN_TXD1, IOMUX_CONFIG_ALT2)
+#define MX31_PIN_RXD1__RXD1 IOMUX_MODE(MX31_PIN_RXD1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_RXD1__STXDA IOMUX_MODE(MX31_PIN_RXD1, IOMUX_CONFIG_ALT2)
+#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_DTR_DCE1__SRXDA IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_ALT2)
+#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_ROW4_GPIO IOMUX_MODE(MX31_PIN_KEY_ROW4, IOMUX_CONFIG_GPIO)
+#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)
+#define MX31_PIN_WATCHDOG_RST__WATCHDOG_RST IOMUX_MODE(MX31_PIN_WATCHDOG_RST, 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/mach-imx/iomux-mx35.h b/arch/arm/mach-imx/iomux-mx35.h
new file mode 100644
index 000000000..90bfa6b5b
--- /dev/null
+++ b/arch/arm/mach-imx/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 "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/mach-imx/iomux-v1.c b/arch/arm/mach-imx/iomux-v1.c
new file mode 100644
index 000000000..ecd543664
--- /dev/null
+++ b/arch/arm/mach-imx/iomux-v1.c
@@ -0,0 +1,187 @@
+/*
+ * 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 <asm/mach/map.h>
+
+#include "hardware.h"
+#include "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;
+}
+
+static int imx_iomuxv1_setup_multiple(const int *list, unsigned count)
+{
+ size_t i;
+ int ret = 0;
+
+ 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)
+{
+ int ret;
+
+ ret = imx_iomuxv1_setup_multiple(pin_list, count);
+ return ret;
+}
+
+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/mach-imx/iomux-v1.h b/arch/arm/mach-imx/iomux-v1.h
new file mode 100644
index 000000000..02651a40f
--- /dev/null
+++ b/arch/arm/mach-imx/iomux-v1.h
@@ -0,0 +1,94 @@
+/*
+ * 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)
+
+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 int imx_iomuxv1_init(void __iomem *base, int numports);
+
+#endif /* __MACH_IOMUX_V1_H__ */
diff --git a/arch/arm/mach-imx/iomux-v3.c b/arch/arm/mach-imx/iomux-v3.c
new file mode 100644
index 000000000..a53b2e64f
--- /dev/null
+++ b/arch/arm/mach-imx/iomux-v3.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2004-2006 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 "hardware.h"
+#include "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;
+}
+
+int mxc_iomux_v3_setup_multiple_pads(const iomux_v3_cfg_t *pad_list,
+ unsigned count)
+{
+ const 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;
+}
+
+void mxc_iomux_v3_init(void __iomem *iomux_v3_base)
+{
+ base = iomux_v3_base;
+}
diff --git a/arch/arm/mach-imx/iomux-v3.h b/arch/arm/mach-imx/iomux-v3.h
new file mode 100644
index 000000000..f79e165a3
--- /dev/null
+++ b/arch/arm/mach-imx/iomux-v3.h
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+#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..57 (17)
+ * SEL_INP: 58..61 (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)0x1ffff << MUX_PAD_CTRL_SHIFT)
+#define MUX_SEL_INPUT_SHIFT 58
+#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 << 16)
+#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)
+
+#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)
+
+/*
+ * setups a single pad in the iomuxer
+ */
+int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad);
+
+/*
+ * setups multiple pads
+ * convenient way to call the above function with tables
+ */
+int mxc_iomux_v3_setup_multiple_pads(const iomux_v3_cfg_t *pad_list,
+ unsigned count);
+
+/*
+ * Initialise the iomux controller
+ */
+void mxc_iomux_v3_init(void __iomem *iomux_v3_base);
+
+#endif /* __MACH_IOMUX_V3_H__*/
+
diff --git a/arch/arm/mach-imx/irq-common.c b/arch/arm/mach-imx/irq-common.c
new file mode 100644
index 000000000..0a920d184
--- /dev/null
+++ b/arch/arm/mach-imx/irq-common.c
@@ -0,0 +1,42 @@
+/*
+ * 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 <linux/platform_data/asoc-imx-ssi.h>
+
+#include "irq-common.h"
+
+int mxc_set_irq_fiq(unsigned int irq, unsigned int type)
+{
+ struct irq_chip_generic *gc;
+ struct mxc_extra_irq *exirq;
+ int ret;
+
+ ret = -ENOSYS;
+
+ gc = irq_get_chip_data(irq);
+ if (gc && gc->private) {
+ exirq = gc->private;
+ if (exirq->set_irq_fiq)
+ ret = exirq->set_irq_fiq(irq, type);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(mxc_set_irq_fiq);
diff --git a/arch/arm/mach-imx/irq-common.h b/arch/arm/mach-imx/irq-common.h
new file mode 100644
index 000000000..6e3175dc0
--- /dev/null
+++ b/arch/arm/mach-imx/irq-common.h
@@ -0,0 +1,30 @@
+/*
+ * 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__
+
+/* all normal IRQs can be FIQs */
+#define FIQ_START 0
+
+struct mxc_extra_irq
+{
+ int (*set_irq_fiq)(unsigned int irq, unsigned int type);
+};
+
+#endif
diff --git a/arch/arm/mach-imx/mach-apf9328.c b/arch/arm/mach-imx/mach-apf9328.c
new file mode 100644
index 000000000..ebbb5ab63
--- /dev/null
+++ b/arch/arm/mach-imx/mach-apf9328.c
@@ -0,0 +1,148 @@
+/*
+ * 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 <linux/gpio.h>
+#include <linux/i2c.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "common.h"
+#include "devices-imx1.h"
+#include "hardware.h"
+#include "iomux-mx1.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,
+ /* I2C */
+ PA15_PF_I2C_SDA,
+ PA16_PF_I2C_SCL,
+};
+
+/*
+ * 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,
+ }, {
+ /* irq number is run-time assigned */
+ .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,
+ }
+};
+
+static const struct imxuart_platform_data uart1_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct imxi2c_platform_data apf9328_i2c_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &apf9328_flash_device,
+ &dm9000x_device,
+};
+
+static void __init apf9328_init(void)
+{
+ imx1_soc_init();
+
+ mxc_gpio_setup_multiple_pins(apf9328_pins,
+ ARRAY_SIZE(apf9328_pins),
+ "APF9328");
+
+ imx1_add_imx_uart0(NULL);
+ imx1_add_imx_uart1(&uart1_pdata);
+
+ imx1_add_imx_i2c(&apf9328_i2c_data);
+
+ dm9000_resources[2].start = gpio_to_irq(IMX_GPIO_NR(2, 14));
+ dm9000_resources[2].end = gpio_to_irq(IMX_GPIO_NR(2, 14));
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init apf9328_timer_init(void)
+{
+ mx1_clocks_init(32768);
+}
+
+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,
+ .init_time = apf9328_timer_init,
+ .init_machine = apf9328_init,
+ .restart = mxc_restart,
+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 000000000..f2060523b
--- /dev/null
+++ b/arch/arm/mach-imx/mach-armadillo5x0.c
@@ -0,0 +1,569 @@
+/*
+ * 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 <linux/regulator/machine.h>
+#include <linux/regulator/fixed.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 "common.h"
+#include "devices-imx31.h"
+#include "crmregs-imx3.h"
+#include "ehci.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "ulpi.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 const struct physmap_flash_data
+ armadillo5x0_nor_flash_pdata __initconst = {
+ .width = 2,
+ .parts = armadillo5x0_nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(armadillo5x0_nor_flash_partitions),
+};
+
+static const struct resource armadillo5x0_nor_flash_resource __initconst = {
+ .flags = IORESOURCE_MEM,
+ .start = MX31_CS0_BASE_ADDR,
+ .end = MX31_CS0_BASE_ADDR + SZ_64M - 1,
+};
+
+/*
+ * 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 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(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK)),
+ detect_irq, 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(gpio_to_irq(IOMUX_TO_GPIO(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,
+ }, {
+ /* irq number is run-time assigned */
+ .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,
+};
+
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+};
+
+/*
+ * Perform board specific initializations
+ */
+static void __init armadillo5x0_init(void)
+{
+ imx31_soc_init();
+
+ mxc_iomux_setup_multiple_pins(armadillo5x0_pins,
+ ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0");
+
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
+ armadillo5x0_smc911x_resources[1].start =
+ gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_0));
+ armadillo5x0_smc911x_resources[1].end =
+ gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_0));
+ 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();
+ imx31_add_mx3_sdc_fb(&mx3fb_pdata);
+
+ /* Register NOR Flash */
+ platform_device_register_resndata(NULL, "physmap-flash", -1,
+ &armadillo5x0_nor_flash_resource, 1,
+ &armadillo5x0_nor_flash_pdata,
+ sizeof(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(mx3_ccm_base + MXC_CCM_RCSR) |
+ (1 << 30), mx3_ccm_base + 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_warn("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);
+}
+
+MACHINE_START(ARMADILLO5X0, "Armadillo-500")
+ /* Maintainer: Alberto Panizzo */
+ .atag_offset = 0x100,
+ .map_io = mx31_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .init_time = armadillo5x0_timer_init,
+ .init_machine = armadillo5x0_init,
+ .restart = mxc_restart,
+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 000000000..c97d7cb39
--- /dev/null
+++ b/arch/arm/mach-imx/mach-bug.c
@@ -0,0 +1,63 @@
+/*
+ * 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 <asm/mach/time.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include "common.h"
+#include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.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)
+{
+ imx31_soc_init();
+
+ 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);
+}
+
+MACHINE_START(BUG, "BugLabs BUGBase")
+ .map_io = mx31_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .init_time = bug_timer_init,
+ .init_machine = bug_board_init,
+ .restart = mxc_restart,
+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 000000000..922ffd6ca
--- /dev/null
+++ b/arch/arm/mach-imx/mach-cpuimx35.c
@@ -0,0 +1,206 @@
+/*
+ * 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 "common.h"
+#include "devices-imx35.h"
+#include "ehci.h"
+#include "eukrea-baseboards.h"
+#include "hardware.h"
+#include "iomux-mx35.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,
+};
+
+#define TSC2007_IRQGPIO IMX_GPIO_NR(3, 2)
+static int tsc2007_get_pendown_state(struct device *dev)
+{
+ return !gpio_get_value(TSC2007_IRQGPIO);
+}
+
+static struct tsc2007_platform_data tsc2007_info = {
+ .model = 2007,
+ .x_plate_ohms = 180,
+ .get_pendown_state = tsc2007_get_pendown_state,
+};
+
+static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ }, {
+ I2C_BOARD_INFO("tsc2007", 0x48),
+ .platform_data = &tsc2007_info,
+ /* irq number is run-time assigned */
+ },
+};
+
+static const iomux_v3_cfg_t eukrea_cpuimx35_pads[] __initconst = {
+ /* 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 bool otg_mode_host __initdata;
+
+static int __init eukrea_cpuimx35_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = true;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = false;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 1;
+}
+__setup("otg_mode=", eukrea_cpuimx35_otg_mode);
+
+/*
+ * Board specific initialization.
+ */
+static void __init eukrea_cpuimx35_init(void)
+{
+ imx35_soc_init();
+
+ mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads,
+ ARRAY_SIZE(eukrea_cpuimx35_pads));
+
+ imx35_add_fec(NULL);
+ imx35_add_imx2_wdt();
+
+ imx35_add_imx_uart0(&uart_pdata);
+ imx35_add_mxc_nand(&eukrea_cpuimx35_nand_board_info);
+
+ eukrea_cpuimx35_i2c_devices[1].irq = gpio_to_irq(TSC2007_IRQGPIO);
+ 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();
+}
+
+MACHINE_START(EUKREA_CPUIMX35SD, "Eukrea CPUIMX35")
+ /* Maintainer: Eukrea Electromatique */
+ .atag_offset = 0x100,
+ .map_io = mx35_map_io,
+ .init_early = imx35_init_early,
+ .init_irq = mx35_init_irq,
+ .init_time = eukrea_cpuimx35_timer_init,
+ .init_machine = eukrea_cpuimx35_init,
+ .restart = mxc_restart,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx25.c b/arch/arm/mach-imx/mach-imx25.c
new file mode 100644
index 000000000..9379fd0a7
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx25.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012 Sascha Hauer, Pengutronix
+ *
+ * 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/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include "common.h"
+#include "hardware.h"
+
+static void __init imx25_init_early(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX25);
+}
+
+static void __init mx25_init_irq(void)
+{
+ struct device_node *np;
+ void __iomem *avic_base;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,avic");
+ avic_base = of_iomap(np, 0);
+ BUG_ON(!avic_base);
+ mxc_init_irq(avic_base);
+}
+
+static const char * const imx25_dt_board_compat[] __initconst = {
+ "fsl,imx25",
+ NULL
+};
+
+DT_MACHINE_START(IMX25_DT, "Freescale i.MX25 (Device Tree Support)")
+ .init_early = imx25_init_early,
+ .init_irq = mx25_init_irq,
+ .dt_compat = imx25_dt_board_compat,
+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 000000000..ede2bdbb5
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
@@ -0,0 +1,611 @@
+/*
+ * 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/platform_data/pca953x.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/leds.h>
+#include <linux/platform_data/asoc-mx27vis.h>
+#include <media/soc_camera.h>
+#include <sound/tlv320aic32x4.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/system_info.h>
+#include <asm/memblock.h>
+
+#include "common.h"
+#include "devices-imx27.h"
+#include "ehci.h"
+#include "hardware.h"
+#include "iomux-mx27.h"
+
+#define TVP5150_RSTN (GPIO_PORTC + 18)
+#define TVP5150_PWDN (GPIO_PORTC + 19)
+#define OTG_PHY_CS_GPIO (GPIO_PORTF + 17)
+#define SDHC1_IRQ_GPIO IMX_GPIO_NR(2, 25)
+
+#define VERSION_MASK 0x7
+#define MOTHERBOARD_SHIFT 4
+#define EXPBOARD_SHIFT 0
+
+#define MOTHERBOARD_BIT2 (GPIO_PORTD + 31)
+#define MOTHERBOARD_BIT1 (GPIO_PORTD + 30)
+#define MOTHERBOARD_BIT0 (GPIO_PORTD + 29)
+
+#define EXPBOARD_BIT2 (GPIO_PORTD + 25)
+#define EXPBOARD_BIT1 (GPIO_PORTD + 27)
+#define EXPBOARD_BIT0 (GPIO_PORTD + 28)
+
+#define AMP_GAIN_0 (GPIO_PORTF + 9)
+#define AMP_GAIN_1 (GPIO_PORTF + 8)
+#define AMP_MUTE_SDL (GPIO_PORTE + 5)
+#define AMP_MUTE_SDR (GPIO_PORTF + 7)
+
+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,
+ /* CSI */
+ TVP5150_RSTN | GPIO_GPIO | GPIO_OUT,
+ TVP5150_PWDN | GPIO_GPIO | GPIO_OUT,
+ 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,
+ /* mother board version */
+ MOTHERBOARD_BIT2 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
+ MOTHERBOARD_BIT1 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
+ MOTHERBOARD_BIT0 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
+ /* expansion board version */
+ EXPBOARD_BIT2 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
+ EXPBOARD_BIT1 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
+ EXPBOARD_BIT0 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
+ /* Audio AMP control */
+ AMP_GAIN_0 | GPIO_GPIO | GPIO_OUT,
+ AMP_GAIN_1 | GPIO_GPIO | GPIO_OUT,
+ AMP_MUTE_SDL | GPIO_GPIO | GPIO_OUT,
+ AMP_MUTE_SDR | GPIO_GPIO | GPIO_OUT,
+};
+
+static struct gpio visstrim_m10_version_gpios[] = {
+ { EXPBOARD_BIT0, GPIOF_IN, "exp-version-0" },
+ { EXPBOARD_BIT1, GPIOF_IN, "exp-version-1" },
+ { EXPBOARD_BIT2, GPIOF_IN, "exp-version-2" },
+ { MOTHERBOARD_BIT0, GPIOF_IN, "mother-version-0" },
+ { MOTHERBOARD_BIT1, GPIOF_IN, "mother-version-1" },
+ { MOTHERBOARD_BIT2, GPIOF_IN, "mother-version-2" },
+};
+
+static const struct gpio visstrim_m10_gpios[] __initconst = {
+ {
+ .gpio = TVP5150_RSTN,
+ .flags = GPIOF_DIR_OUT | GPIOF_INIT_HIGH,
+ .label = "tvp5150_rstn",
+ },
+ {
+ .gpio = TVP5150_PWDN,
+ .flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW,
+ .label = "tvp5150_pwdn",
+ },
+ {
+ .gpio = OTG_PHY_CS_GPIO,
+ .flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW,
+ .label = "usbotg_cs",
+ },
+ {
+ .gpio = AMP_GAIN_0,
+ .flags = GPIOF_DIR_OUT,
+ .label = "amp-gain-0",
+ },
+ {
+ .gpio = AMP_GAIN_1,
+ .flags = GPIOF_DIR_OUT,
+ .label = "amp-gain-1",
+ },
+ {
+ .gpio = AMP_MUTE_SDL,
+ .flags = GPIOF_DIR_OUT,
+ .label = "amp-mute-sdl",
+ },
+ {
+ .gpio = AMP_MUTE_SDR,
+ .flags = GPIOF_DIR_OUT,
+ .label = "amp-mute-sdr",
+ },
+};
+
+/* Camera */
+static int visstrim_camera_power(struct device *dev, int on)
+{
+ gpio_set_value(TVP5150_PWDN, on);
+
+ return 0;
+};
+
+static int visstrim_camera_reset(struct device *dev)
+{
+ gpio_set_value(TVP5150_RSTN, 0);
+ ndelay(500);
+ gpio_set_value(TVP5150_RSTN, 1);
+
+ return 0;
+};
+
+static struct i2c_board_info visstrim_i2c_camera = {
+ I2C_BOARD_INFO("tvp5150", 0x5d),
+};
+
+static struct soc_camera_link iclink_tvp5150 = {
+ .bus_id = 0,
+ .board_info = &visstrim_i2c_camera,
+ .i2c_adapter_id = 0,
+ .power = visstrim_camera_power,
+ .reset = visstrim_camera_reset,
+};
+
+static struct mx2_camera_platform_data visstrim_camera = {
+ .flags = MX2_CAMERA_CCIR | MX2_CAMERA_CCIR_INTERLACE |
+ MX2_CAMERA_PCLK_SAMPLE_RISING,
+ .clk = 100000,
+};
+
+static phys_addr_t mx2_camera_base __initdata;
+#define MX2_CAMERA_BUF_SIZE SZ_8M
+
+static void __init visstrim_analog_camera_init(void)
+{
+ struct platform_device *pdev;
+ int dma;
+
+ gpio_set_value(TVP5150_PWDN, 1);
+ ndelay(1);
+ gpio_set_value(TVP5150_RSTN, 0);
+ ndelay(500);
+ gpio_set_value(TVP5150_RSTN, 1);
+ ndelay(200000);
+
+ pdev = imx27_add_mx2_camera(&visstrim_camera);
+ if (IS_ERR(pdev))
+ return;
+
+ dma = dma_declare_coherent_memory(&pdev->dev,
+ mx2_camera_base, mx2_camera_base,
+ MX2_CAMERA_BUF_SIZE,
+ DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+ if (!(dma & DMA_MEMORY_MAP))
+ return;
+}
+
+static void __init visstrim_reserve(void)
+{
+ /* reserve 4 MiB for mx2-camera */
+ mx2_camera_base = arm_memblock_steal(3 * MX2_CAMERA_BUF_SIZE,
+ MX2_CAMERA_BUF_SIZE);
+}
+
+/* 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),
+};
+
+/* led */
+static const struct gpio_led visstrim_m10_leds[] __initconst = {
+ {
+ .name = "visstrim:ld0",
+ .default_trigger = "nand-disk",
+ .gpio = (GPIO_PORTC + 29),
+ },
+ {
+ .name = "visstrim:ld1",
+ .default_trigger = "nand-disk",
+ .gpio = (GPIO_PORTC + 24),
+ },
+ {
+ .name = "visstrim:ld2",
+ .default_trigger = "nand-disk",
+ .gpio = (GPIO_PORTC + 28),
+ },
+ {
+ .name = "visstrim:ld3",
+ .default_trigger = "nand-disk",
+ .gpio = (GPIO_PORTC + 25),
+ },
+};
+
+static const struct gpio_led_platform_data visstrim_m10_led_data __initconst = {
+ .leds = visstrim_m10_leds,
+ .num_leds = ARRAY_SIZE(visstrim_m10_leds),
+};
+
+/* 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(gpio_to_irq(SDHC1_IRQ_GPIO), detect_irq,
+ IRQF_TRIGGER_FALLING, "mmc-detect", data);
+ return ret;
+}
+
+static void visstrim_m10_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(gpio_to_irq(SDHC1_IRQ_GPIO), 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 aic32x4_pdata visstrim_m10_aic32x4_pdata = {
+ .power_cfg = AIC32X4_PWR_MICBIAS_2075_LDOIN |
+ AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE |
+ AIC32X4_PWR_AIC32X4_LDO_ENABLE |
+ AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36 |
+ AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED,
+ .micpga_routing = AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K |
+ AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K,
+ .swapdacs = false,
+};
+
+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),
+ .platform_data = &visstrim_m10_aic32x4_pdata,
+ },
+ {
+ I2C_BOARD_INFO("m41t00", 0x68),
+ }
+};
+
+/* USB OTG */
+static int otg_phy_init(struct platform_device *pdev)
+{
+ 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,
+};
+
+/* coda */
+
+static void __init visstrim_coda_init(void)
+{
+ struct platform_device *pdev;
+ int dma;
+
+ pdev = imx27_add_coda();
+ dma = dma_declare_coherent_memory(&pdev->dev,
+ mx2_camera_base + MX2_CAMERA_BUF_SIZE,
+ mx2_camera_base + MX2_CAMERA_BUF_SIZE,
+ MX2_CAMERA_BUF_SIZE,
+ DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+ if (!(dma & DMA_MEMORY_MAP))
+ return;
+}
+
+/* DMA deinterlace */
+static struct platform_device visstrim_deinterlace = {
+ .name = "m2m-deinterlace",
+ .id = 0,
+};
+
+static void __init visstrim_deinterlace_init(void)
+{
+ int ret = -ENOMEM;
+ struct platform_device *pdev = &visstrim_deinterlace;
+ int dma;
+
+ ret = platform_device_register(pdev);
+
+ dma = dma_declare_coherent_memory(&pdev->dev,
+ mx2_camera_base + 2 * MX2_CAMERA_BUF_SIZE,
+ mx2_camera_base + 2 * MX2_CAMERA_BUF_SIZE,
+ MX2_CAMERA_BUF_SIZE,
+ DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+ if (!(dma & DMA_MEMORY_MAP))
+ return;
+}
+
+/* Emma-PrP for format conversion */
+static void __init visstrim_emmaprp_init(void)
+{
+ struct platform_device *pdev;
+ int dma;
+
+ pdev = imx27_add_mx2_emmaprp();
+ if (IS_ERR(pdev))
+ return;
+
+ /*
+ * Use the same memory area as the analog camera since both
+ * devices are, by nature, exclusive.
+ */
+ dma = dma_declare_coherent_memory(&pdev->dev,
+ mx2_camera_base, mx2_camera_base,
+ MX2_CAMERA_BUF_SIZE,
+ DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+ if (!(dma & DMA_MEMORY_MAP))
+ pr_err("Failed to declare memory for emmaprp\n");
+}
+
+/* Audio */
+static const struct snd_mx27vis_platform_data snd_mx27vis_pdata __initconst = {
+ .amp_gain0_gpio = AMP_GAIN_0,
+ .amp_gain1_gpio = AMP_GAIN_1,
+ .amp_mutel_gpio = AMP_MUTE_SDL,
+ .amp_muter_gpio = AMP_MUTE_SDR,
+};
+
+static void __init visstrim_m10_revision(void)
+{
+ int exp_version = 0;
+ int mo_version = 0;
+ int ret;
+
+ ret = gpio_request_array(visstrim_m10_version_gpios,
+ ARRAY_SIZE(visstrim_m10_version_gpios));
+ if (ret) {
+ pr_err("Failed to request version gpios");
+ return;
+ }
+
+ /* Get expansion board version (negative logic) */
+ exp_version |= !gpio_get_value(EXPBOARD_BIT2) << 2;
+ exp_version |= !gpio_get_value(EXPBOARD_BIT1) << 1;
+ exp_version |= !gpio_get_value(EXPBOARD_BIT0);
+
+ /* Get mother board version (negative logic) */
+ mo_version |= !gpio_get_value(MOTHERBOARD_BIT2) << 2;
+ mo_version |= !gpio_get_value(MOTHERBOARD_BIT1) << 1;
+ mo_version |= !gpio_get_value(MOTHERBOARD_BIT0);
+
+ system_rev = 0x27000;
+ system_rev |= (mo_version << MOTHERBOARD_SHIFT);
+ system_rev |= (exp_version << EXPBOARD_SHIFT);
+}
+
+static void __init visstrim_m10_board_init(void)
+{
+ int ret;
+ int mo_version;
+
+ imx27_soc_init();
+ visstrim_m10_revision();
+
+ 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);
+
+ ret = gpio_request_array(visstrim_m10_gpios,
+ ARRAY_SIZE(visstrim_m10_gpios));
+ if (ret)
+ pr_err("Failed to request gpios (%d)\n", ret);
+
+ imx27_add_imx_ssi(0, &visstrim_m10_ssi_pdata);
+ imx27_add_imx_uart0(&uart_pdata);
+
+ imx27_add_imx_i2c(0, &visstrim_m10_i2c_data);
+ imx27_add_imx_i2c(1, &visstrim_m10_i2c_data);
+ i2c_register_board_info(0, visstrim_m10_i2c_devices,
+ ARRAY_SIZE(visstrim_m10_i2c_devices));
+
+ 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));
+ imx_add_platform_device("mx27vis", 0, NULL, 0, &snd_mx27vis_pdata,
+ sizeof(snd_mx27vis_pdata));
+ platform_device_register_resndata(NULL, "soc-camera-pdrv", 0, NULL, 0,
+ &iclink_tvp5150, sizeof(iclink_tvp5150));
+ gpio_led_register_device(0, &visstrim_m10_led_data);
+
+ /* Use mother board version to decide what video devices we shall use */
+ mo_version = (system_rev >> MOTHERBOARD_SHIFT) & VERSION_MASK;
+ if (mo_version & 0x1) {
+ visstrim_emmaprp_init();
+
+ /*
+ * Despite not being used, tvp5150 must be
+ * powered on to avoid I2C problems. To minimize
+ * power consupmtion keep reset enabled.
+ */
+ gpio_set_value(TVP5150_PWDN, 1);
+ ndelay(1);
+ gpio_set_value(TVP5150_RSTN, 0);
+ } else {
+ visstrim_deinterlace_init();
+ visstrim_analog_camera_init();
+ }
+ visstrim_coda_init();
+}
+
+static void __init visstrim_m10_timer_init(void)
+{
+ mx27_clocks_init((unsigned long)25000000);
+}
+
+MACHINE_START(IMX27_VISSTRIM_M10, "Vista Silicon Visstrim_M10")
+ .atag_offset = 0x100,
+ .reserve = visstrim_reserve,
+ .map_io = mx27_map_io,
+ .init_early = imx27_init_early,
+ .init_irq = mx27_init_irq,
+ .init_time = visstrim_m10_timer_init,
+ .init_machine = visstrim_m10_board_init,
+ .restart = mxc_restart,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx50.c b/arch/arm/mach-imx/mach-imx50.c
new file mode 100644
index 000000000..ecf58b9e9
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx50.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2013 Greg Ungerer <gerg@uclinux.org>
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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/of_platform.h>
+#include <asm/mach/arch.h>
+
+#include "common.h"
+
+static const char * const imx50_dt_board_compat[] __initconst = {
+ "fsl,imx50",
+ NULL
+};
+
+DT_MACHINE_START(IMX50_DT, "Freescale i.MX50 (Device Tree Support)")
+ .init_irq = tzic_init_irq,
+ .dt_compat = imx50_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx51.c b/arch/arm/mach-imx/mach-imx51.c
new file mode 100644
index 000000000..b015129e4
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx51.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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/io.h>
+#include <linux/irq.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "common.h"
+#include "hardware.h"
+
+static void __init imx51_init_early(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX51);
+}
+
+/*
+ * 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 for proper
+ * IPU support.
+ */
+#define MX51_MIPI_HSC_BASE 0x83fdc000
+static void __init imx51_ipu_mipi_setup(void)
+{
+ void __iomem *hsc_addr;
+
+ hsc_addr = ioremap(MX51_MIPI_HSC_BASE, SZ_16K);
+ WARN_ON(!hsc_addr);
+
+ /* setup MIPI module to legacy mode */
+ __raw_writel(0xf00, hsc_addr);
+
+ /* CSI mode: reserved; DI control mode: legacy (from Freescale BSP) */
+ __raw_writel(__raw_readl(hsc_addr + 0x800) | 0x30ff,
+ hsc_addr + 0x800);
+
+ iounmap(hsc_addr);
+}
+
+static void __init imx51_dt_init(void)
+{
+ struct platform_device_info devinfo = { .name = "cpufreq-dt", };
+
+ imx51_ipu_mipi_setup();
+ imx_src_init();
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ platform_device_register_full(&devinfo);
+}
+
+static void __init imx51_init_late(void)
+{
+ mx51_neon_fixup();
+ imx51_pm_init();
+}
+
+static const char * const imx51_dt_board_compat[] __initconst = {
+ "fsl,imx51",
+ NULL
+};
+
+DT_MACHINE_START(IMX51_DT, "Freescale i.MX51 (Device Tree Support)")
+ .init_early = imx51_init_early,
+ .init_irq = tzic_init_irq,
+ .init_machine = imx51_dt_init,
+ .init_late = imx51_init_late,
+ .dt_compat = imx51_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx53.c b/arch/arm/mach-imx/mach-imx53.c
new file mode 100644
index 000000000..86316a979
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx53.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "common.h"
+#include "hardware.h"
+
+static void __init imx53_init_early(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX53);
+}
+
+static void __init imx53_dt_init(void)
+{
+ imx_src_init();
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+ imx_aips_allow_unprivileged_access("fsl,imx53-aipstz");
+}
+
+static void __init imx53_init_late(void)
+{
+ imx53_pm_init();
+
+ platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+}
+
+static const char * const imx53_dt_board_compat[] __initconst = {
+ "fsl,imx53",
+ NULL
+};
+
+DT_MACHINE_START(IMX53_DT, "Freescale i.MX53 (Device Tree Support)")
+ .init_early = imx53_init_early,
+ .init_irq = tzic_init_irq,
+ .init_machine = imx53_dt_init,
+ .init_late = imx53_init_late,
+ .dt_compat = imx53_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
new file mode 100644
index 000000000..3ab61549c
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -0,0 +1,411 @@
+/*
+ * Copyright 2011-2013 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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/clk.h>
+#include <linux/clkdev.h>
+#include <linux/cpu.h>
+#include <linux/delay.h>
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/pm_opp.h>
+#include <linux/pci.h>
+#include <linux/phy.h>
+#include <linux/reboot.h>
+#include <linux/regmap.h>
+#include <linux/micrel_phy.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/system_misc.h>
+
+#include "common.h"
+#include "cpuidle.h"
+#include "hardware.h"
+
+/* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */
+static int ksz9021rn_phy_fixup(struct phy_device *phydev)
+{
+ if (IS_BUILTIN(CONFIG_PHYLIB)) {
+ /* min rx data delay */
+ phy_write(phydev, MICREL_KSZ9021_EXTREG_CTRL,
+ 0x8000 | MICREL_KSZ9021_RGMII_RX_DATA_PAD_SCEW);
+ phy_write(phydev, MICREL_KSZ9021_EXTREG_DATA_WRITE, 0x0000);
+
+ /* max rx/tx clock delay, min rx/tx control delay */
+ phy_write(phydev, MICREL_KSZ9021_EXTREG_CTRL,
+ 0x8000 | MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW);
+ phy_write(phydev, MICREL_KSZ9021_EXTREG_DATA_WRITE, 0xf0f0);
+ phy_write(phydev, MICREL_KSZ9021_EXTREG_CTRL,
+ MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW);
+ }
+
+ return 0;
+}
+
+static void mmd_write_reg(struct phy_device *dev, int device, int reg, int val)
+{
+ phy_write(dev, 0x0d, device);
+ phy_write(dev, 0x0e, reg);
+ phy_write(dev, 0x0d, (1 << 14) | device);
+ phy_write(dev, 0x0e, val);
+}
+
+static int ksz9031rn_phy_fixup(struct phy_device *dev)
+{
+ /*
+ * min rx data delay, max rx/tx clock delay,
+ * min rx/tx control delay
+ */
+ mmd_write_reg(dev, 2, 4, 0);
+ mmd_write_reg(dev, 2, 5, 0);
+ mmd_write_reg(dev, 2, 8, 0x003ff);
+
+ return 0;
+}
+
+/*
+ * fixup for PLX PEX8909 bridge to configure GPIO1-7 as output High
+ * as they are used for slots1-7 PERST#
+ */
+static void ventana_pciesw_early_fixup(struct pci_dev *dev)
+{
+ u32 dw;
+
+ if (!of_machine_is_compatible("gw,ventana"))
+ return;
+
+ if (dev->devfn != 0)
+ return;
+
+ pci_read_config_dword(dev, 0x62c, &dw);
+ dw |= 0xaaa8; // GPIO1-7 outputs
+ pci_write_config_dword(dev, 0x62c, dw);
+
+ pci_read_config_dword(dev, 0x644, &dw);
+ dw |= 0xfe; // GPIO1-7 output high
+ pci_write_config_dword(dev, 0x644, dw);
+
+ msleep(100);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8609, ventana_pciesw_early_fixup);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8606, ventana_pciesw_early_fixup);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8604, ventana_pciesw_early_fixup);
+
+static int ar8031_phy_fixup(struct phy_device *dev)
+{
+ u16 val;
+
+ /* To enable AR8031 output a 125MHz clk from CLK_25M */
+ phy_write(dev, 0xd, 0x7);
+ phy_write(dev, 0xe, 0x8016);
+ phy_write(dev, 0xd, 0x4007);
+
+ val = phy_read(dev, 0xe);
+ val &= 0xffe3;
+ val |= 0x18;
+ phy_write(dev, 0xe, val);
+
+ /* introduce tx clock delay */
+ phy_write(dev, 0x1d, 0x5);
+ val = phy_read(dev, 0x1e);
+ val |= 0x0100;
+ phy_write(dev, 0x1e, val);
+
+ return 0;
+}
+
+#define PHY_ID_AR8031 0x004dd074
+
+static int ar8035_phy_fixup(struct phy_device *dev)
+{
+ u16 val;
+
+ /* Ar803x phy SmartEEE feature cause link status generates glitch,
+ * which cause ethernet link down/up issue, so disable SmartEEE
+ */
+ phy_write(dev, 0xd, 0x3);
+ phy_write(dev, 0xe, 0x805d);
+ phy_write(dev, 0xd, 0x4003);
+
+ val = phy_read(dev, 0xe);
+ phy_write(dev, 0xe, val & ~(1 << 8));
+
+ /*
+ * Enable 125MHz clock from CLK_25M on the AR8031. This
+ * is fed in to the IMX6 on the ENET_REF_CLK (V22) pad.
+ * Also, introduce a tx clock delay.
+ *
+ * This is the same as is the AR8031 fixup.
+ */
+ ar8031_phy_fixup(dev);
+
+ /*check phy power*/
+ val = phy_read(dev, 0x0);
+ if (val & BMCR_PDOWN)
+ phy_write(dev, 0x0, val & ~BMCR_PDOWN);
+
+ return 0;
+}
+
+#define PHY_ID_AR8035 0x004dd072
+
+static void __init imx6q_enet_phy_init(void)
+{
+ if (IS_BUILTIN(CONFIG_PHYLIB)) {
+ phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
+ ksz9021rn_phy_fixup);
+ phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK,
+ ksz9031rn_phy_fixup);
+ phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
+ ar8031_phy_fixup);
+ phy_register_fixup_for_uid(PHY_ID_AR8035, 0xffffffef,
+ ar8035_phy_fixup);
+ }
+}
+
+static void __init imx6q_1588_init(void)
+{
+ struct device_node *np;
+ struct clk *ptp_clk;
+ struct clk *enet_ref;
+ struct regmap *gpr;
+ u32 clksel;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-fec");
+ if (!np) {
+ pr_warn("%s: failed to find fec node\n", __func__);
+ return;
+ }
+
+ ptp_clk = of_clk_get(np, 2);
+ if (IS_ERR(ptp_clk)) {
+ pr_warn("%s: failed to get ptp clock\n", __func__);
+ goto put_node;
+ }
+
+ enet_ref = clk_get_sys(NULL, "enet_ref");
+ if (IS_ERR(enet_ref)) {
+ pr_warn("%s: failed to get enet clock\n", __func__);
+ goto put_ptp_clk;
+ }
+
+ /*
+ * If enet_ref from ANATOP/CCM is the PTP clock source, we need to
+ * set bit IOMUXC_GPR1[21]. Or the PTP clock must be from pad
+ * (external OSC), and we need to clear the bit.
+ */
+ clksel = clk_is_match(ptp_clk, enet_ref) ?
+ IMX6Q_GPR1_ENET_CLK_SEL_ANATOP :
+ IMX6Q_GPR1_ENET_CLK_SEL_PAD;
+ gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+ if (!IS_ERR(gpr))
+ regmap_update_bits(gpr, IOMUXC_GPR1,
+ IMX6Q_GPR1_ENET_CLK_SEL_MASK,
+ clksel);
+ else
+ pr_err("failed to find fsl,imx6q-iomux-gpr regmap\n");
+
+ clk_put(enet_ref);
+put_ptp_clk:
+ clk_put(ptp_clk);
+put_node:
+ of_node_put(np);
+}
+
+static void __init imx6q_axi_init(void)
+{
+ struct regmap *gpr;
+ unsigned int mask;
+
+ gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+ if (!IS_ERR(gpr)) {
+ /*
+ * Enable the cacheable attribute of VPU and IPU
+ * AXI transactions.
+ */
+ mask = IMX6Q_GPR4_VPU_WR_CACHE_SEL |
+ IMX6Q_GPR4_VPU_RD_CACHE_SEL |
+ IMX6Q_GPR4_VPU_P_WR_CACHE_VAL |
+ IMX6Q_GPR4_VPU_P_RD_CACHE_VAL_MASK |
+ IMX6Q_GPR4_IPU_WR_CACHE_CTL |
+ IMX6Q_GPR4_IPU_RD_CACHE_CTL;
+ regmap_update_bits(gpr, IOMUXC_GPR4, mask, mask);
+
+ /* Increase IPU read QoS priority */
+ regmap_update_bits(gpr, IOMUXC_GPR6,
+ IMX6Q_GPR6_IPU1_ID00_RD_QOS_MASK |
+ IMX6Q_GPR6_IPU1_ID01_RD_QOS_MASK,
+ (0xf << 16) | (0x7 << 20));
+ regmap_update_bits(gpr, IOMUXC_GPR7,
+ IMX6Q_GPR7_IPU2_ID00_RD_QOS_MASK |
+ IMX6Q_GPR7_IPU2_ID01_RD_QOS_MASK,
+ (0xf << 16) | (0x7 << 20));
+ } else {
+ pr_warn("failed to find fsl,imx6q-iomuxc-gpr regmap\n");
+ }
+}
+
+static void __init imx6q_init_machine(void)
+{
+ struct device *parent;
+
+ imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q",
+ imx_get_soc_revision());
+
+ parent = imx_soc_device_init();
+ if (parent == NULL)
+ pr_warn("failed to initialize soc device\n");
+
+ imx6q_enet_phy_init();
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
+
+ imx_anatop_init();
+ cpu_is_imx6q() ? imx6q_pm_init() : imx6dl_pm_init();
+ imx6q_1588_init();
+ imx6q_axi_init();
+}
+
+#define OCOTP_CFG3 0x440
+#define OCOTP_CFG3_SPEED_SHIFT 16
+#define OCOTP_CFG3_SPEED_1P2GHZ 0x3
+#define OCOTP_CFG3_SPEED_996MHZ 0x2
+#define OCOTP_CFG3_SPEED_852MHZ 0x1
+
+static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
+{
+ struct device_node *np;
+ void __iomem *base;
+ u32 val;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
+ if (!np) {
+ pr_warn("failed to find ocotp node\n");
+ return;
+ }
+
+ base = of_iomap(np, 0);
+ if (!base) {
+ pr_warn("failed to map ocotp\n");
+ goto put_node;
+ }
+
+ /*
+ * SPEED_GRADING[1:0] defines the max speed of ARM:
+ * 2b'11: 1200000000Hz;
+ * 2b'10: 996000000Hz;
+ * 2b'01: 852000000Hz; -- i.MX6Q Only, exclusive with 996MHz.
+ * 2b'00: 792000000Hz;
+ * We need to set the max speed of ARM according to fuse map.
+ */
+ val = readl_relaxed(base + OCOTP_CFG3);
+ val >>= OCOTP_CFG3_SPEED_SHIFT;
+ val &= 0x3;
+
+ if ((val != OCOTP_CFG3_SPEED_1P2GHZ) && cpu_is_imx6q())
+ if (dev_pm_opp_disable(cpu_dev, 1200000000))
+ pr_warn("failed to disable 1.2 GHz OPP\n");
+ if (val < OCOTP_CFG3_SPEED_996MHZ)
+ if (dev_pm_opp_disable(cpu_dev, 996000000))
+ pr_warn("failed to disable 996 MHz OPP\n");
+ if (cpu_is_imx6q()) {
+ if (val != OCOTP_CFG3_SPEED_852MHZ)
+ if (dev_pm_opp_disable(cpu_dev, 852000000))
+ pr_warn("failed to disable 852 MHz OPP\n");
+ }
+ iounmap(base);
+put_node:
+ of_node_put(np);
+}
+
+static void __init imx6q_opp_init(void)
+{
+ struct device_node *np;
+ struct device *cpu_dev = get_cpu_device(0);
+
+ if (!cpu_dev) {
+ pr_warn("failed to get cpu0 device\n");
+ return;
+ }
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ pr_warn("failed to find cpu0 node\n");
+ return;
+ }
+
+ if (of_init_opp_table(cpu_dev)) {
+ pr_warn("failed to init OPP table\n");
+ goto put_node;
+ }
+
+ imx6q_opp_check_speed_grading(cpu_dev);
+
+put_node:
+ of_node_put(np);
+}
+
+static struct platform_device imx6q_cpufreq_pdev = {
+ .name = "imx6q-cpufreq",
+};
+
+static void __init imx6q_init_late(void)
+{
+ /*
+ * WAIT mode is broken on TO 1.0 and 1.1, so there is no point
+ * to run cpuidle on them.
+ */
+ if (imx_get_soc_revision() > IMX_CHIP_REVISION_1_1)
+ imx6q_cpuidle_init();
+
+ if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
+ imx6q_opp_init();
+ platform_device_register(&imx6q_cpufreq_pdev);
+ }
+}
+
+static void __init imx6q_map_io(void)
+{
+ debug_ll_io_init();
+ imx_scu_map_io();
+}
+
+static void __init imx6q_init_irq(void)
+{
+ imx_gpc_check_dt();
+ imx_init_revision_from_anatop();
+ imx_init_l2cache();
+ imx_src_init();
+ irqchip_init();
+}
+
+static const char * const imx6q_dt_compat[] __initconst = {
+ "fsl,imx6dl",
+ "fsl,imx6q",
+ NULL,
+};
+
+DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)")
+ .smp = smp_ops(imx_smp_ops),
+ .map_io = imx6q_map_io,
+ .init_irq = imx6q_init_irq,
+ .init_machine = imx6q_init_machine,
+ .init_late = imx6q_init_late,
+ .dt_compat = imx6q_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c
new file mode 100644
index 000000000..12a1b098f
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx6sl.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/irqchip.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/regmap.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+#include "cpuidle.h"
+
+static void __init imx6sl_fec_init(void)
+{
+ struct regmap *gpr;
+
+ /* set FEC clock from internal PLL clock source */
+ gpr = syscon_regmap_lookup_by_compatible("fsl,imx6sl-iomuxc-gpr");
+ if (!IS_ERR(gpr)) {
+ regmap_update_bits(gpr, IOMUXC_GPR1,
+ IMX6SL_GPR1_FEC_CLOCK_MUX2_SEL_MASK, 0);
+ regmap_update_bits(gpr, IOMUXC_GPR1,
+ IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK, 0);
+ } else {
+ pr_err("failed to find fsl,imx6sl-iomux-gpr regmap\n");
+ }
+}
+
+static void __init imx6sl_init_late(void)
+{
+ /* imx6sl reuses imx6q cpufreq driver */
+ if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
+ platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
+
+ imx6sl_cpuidle_init();
+}
+
+static void __init imx6sl_init_machine(void)
+{
+ struct device *parent;
+
+ parent = imx_soc_device_init();
+ if (parent == NULL)
+ pr_warn("failed to initialize soc device\n");
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
+
+ imx6sl_fec_init();
+ imx_anatop_init();
+ imx6sl_pm_init();
+}
+
+static void __init imx6sl_init_irq(void)
+{
+ imx_gpc_check_dt();
+ imx_init_revision_from_anatop();
+ imx_init_l2cache();
+ imx_src_init();
+ irqchip_init();
+}
+
+static const char * const imx6sl_dt_compat[] __initconst = {
+ "fsl,imx6sl",
+ NULL,
+};
+
+DT_MACHINE_START(IMX6SL, "Freescale i.MX6 SoloLite (Device Tree)")
+ .init_irq = imx6sl_init_irq,
+ .init_machine = imx6sl_init_machine,
+ .init_late = imx6sl_init_late,
+ .dt_compat = imx6sl_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx6sx.c b/arch/arm/mach-imx/mach-imx6sx.c
new file mode 100644
index 000000000..f17b7004c
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx6sx.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2014 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 <linux/irqchip.h>
+#include <linux/of_platform.h>
+#include <linux/phy.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+#include "cpuidle.h"
+
+static int ar8031_phy_fixup(struct phy_device *dev)
+{
+ u16 val;
+
+ /* Set RGMII IO voltage to 1.8V */
+ phy_write(dev, 0x1d, 0x1f);
+ phy_write(dev, 0x1e, 0x8);
+
+ /* introduce tx clock delay */
+ phy_write(dev, 0x1d, 0x5);
+ val = phy_read(dev, 0x1e);
+ val |= 0x0100;
+ phy_write(dev, 0x1e, val);
+
+ return 0;
+}
+
+#define PHY_ID_AR8031 0x004dd074
+static void __init imx6sx_enet_phy_init(void)
+{
+ if (IS_BUILTIN(CONFIG_PHYLIB))
+ phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
+ ar8031_phy_fixup);
+}
+
+static void __init imx6sx_enet_clk_sel(void)
+{
+ struct regmap *gpr;
+
+ gpr = syscon_regmap_lookup_by_compatible("fsl,imx6sx-iomuxc-gpr");
+ if (!IS_ERR(gpr)) {
+ regmap_update_bits(gpr, IOMUXC_GPR1,
+ IMX6SX_GPR1_FEC_CLOCK_MUX_SEL_MASK, 0);
+ regmap_update_bits(gpr, IOMUXC_GPR1,
+ IMX6SX_GPR1_FEC_CLOCK_PAD_DIR_MASK, 0);
+ } else {
+ pr_err("failed to find fsl,imx6sx-iomux-gpr regmap\n");
+ }
+}
+
+static inline void imx6sx_enet_init(void)
+{
+ imx6sx_enet_phy_init();
+ imx6sx_enet_clk_sel();
+}
+
+static void __init imx6sx_init_machine(void)
+{
+ struct device *parent;
+
+ parent = imx_soc_device_init();
+ if (parent == NULL)
+ pr_warn("failed to initialize soc device\n");
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
+
+ imx6sx_enet_init();
+ imx_anatop_init();
+ imx6sx_pm_init();
+}
+
+static void __init imx6sx_init_irq(void)
+{
+ imx_gpc_check_dt();
+ imx_init_revision_from_anatop();
+ imx_init_l2cache();
+ imx_src_init();
+ irqchip_init();
+}
+
+static void __init imx6sx_init_late(void)
+{
+ imx6sx_cpuidle_init();
+
+ if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
+ platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
+}
+
+static const char * const imx6sx_dt_compat[] __initconst = {
+ "fsl,imx6sx",
+ NULL,
+};
+
+DT_MACHINE_START(IMX6SX, "Freescale i.MX6 SoloX (Device Tree)")
+ .init_irq = imx6sx_init_irq,
+ .init_machine = imx6sx_init_machine,
+ .dt_compat = imx6sx_dt_compat,
+ .init_late = imx6sx_init_late,
+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 000000000..31df43619
--- /dev/null
+++ b/arch/arm/mach-imx/mach-kzm_arm11_01.c
@@ -0,0 +1,295 @@
+/*
+ * 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 <linux/regulator/machine.h>
+#include <linux/regulator/fixed.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 "common.h"
+#include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.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 number is run-time assigned */
+ .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,
+ },
+ {
+ /* irq number is run-time assigned */
+ .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));
+
+ serial_platform_data[0].irq =
+ gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1));
+ serial8250_resources[1].start =
+ gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1));
+ serial8250_resources[1].end =
+ gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1));
+
+ 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,
+ },
+ {
+ /* irq number is run-time assigned */
+ .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 struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+};
+
+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));
+
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
+ kzm_smsc9118_resources[1].start =
+ gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2));
+ kzm_smsc9118_resources[1].end =
+ gpio_to_irq(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)
+{
+ imx31_soc_init();
+
+ 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 = (unsigned long)MX31_CS4_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR),
+ .length = MX31_CS4_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = (unsigned long)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);
+}
+
+MACHINE_START(KZM_ARM11_01, "Kyoto Microcomputer Co., Ltd. KZM-ARM11-01")
+ .atag_offset = 0x100,
+ .map_io = kzm_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .init_time = kzm_timer_init,
+ .init_machine = kzm_board_init,
+ .restart = mxc_restart,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-ls1021a.c b/arch/arm/mach-imx/mach-ls1021a.c
new file mode 100644
index 000000000..b89c858eb
--- /dev/null
+++ b/arch/arm/mach-imx/mach-ls1021a.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2013-2014 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <asm/mach/arch.h>
+
+#include "common.h"
+
+static const char * const ls1021a_dt_compat[] __initconst = {
+ "fsl,ls1021a",
+ NULL,
+};
+
+DT_MACHINE_START(LS1021A, "Freescale LS1021A")
+ .smp = smp_ops(ls1021a_smp_ops),
+ .dt_compat = ls1021a_dt_compat,
+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 000000000..703ce31d7
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx21ads.c
@@ -0,0 +1,333 @@
+/*
+ * 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/basic_mmio_gpio.h>
+#include <linux/gpio.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "common.h"
+#include "devices-imx21.h"
+#include "hardware.h"
+#include "iomux-mx21.h"
+
+#define MX21ADS_CS8900A_REG (MX21_CS1_BASE_ADDR + 0x000000)
+#define MX21ADS_ST16C255_IOBASE_REG (MX21_CS1_BASE_ADDR + 0x200000)
+#define MX21ADS_VERSION_REG (MX21_CS1_BASE_ADDR + 0x400000)
+#define MX21ADS_IO_REG (MX21_CS1_BASE_ADDR + 0x800000)
+
+#define MX21ADS_MMC_CD IMX_GPIO_NR(4, 25)
+#define MX21ADS_CS8900A_IRQ_GPIO IMX_GPIO_NR(5, 11)
+#define MX21ADS_MMGPIO_BASE (6 * 32)
+
+/* MX21ADS_IO_REG bit definitions */
+#define MX21ADS_IO_SD_WP (MX21ADS_MMGPIO_BASE + 0)
+#define MX21ADS_IO_TP6 (MX21ADS_IO_SD_WP)
+#define MX21ADS_IO_SW_SEL (MX21ADS_MMGPIO_BASE + 1)
+#define MX21ADS_IO_TP7 (MX21ADS_IO_SW_SEL)
+#define MX21ADS_IO_RESET_E_UART (MX21ADS_MMGPIO_BASE + 2)
+#define MX21ADS_IO_RESET_BASE (MX21ADS_MMGPIO_BASE + 3)
+#define MX21ADS_IO_CSI_CTL2 (MX21ADS_MMGPIO_BASE + 4)
+#define MX21ADS_IO_CSI_CTL1 (MX21ADS_MMGPIO_BASE + 5)
+#define MX21ADS_IO_CSI_CTL0 (MX21ADS_MMGPIO_BASE + 6)
+#define MX21ADS_IO_UART1_EN (MX21ADS_MMGPIO_BASE + 7)
+#define MX21ADS_IO_UART4_EN (MX21ADS_MMGPIO_BASE + 8)
+#define MX21ADS_IO_LCDON (MX21ADS_MMGPIO_BASE + 9)
+#define MX21ADS_IO_IRDA_EN (MX21ADS_MMGPIO_BASE + 10)
+#define MX21ADS_IO_IRDA_FIR_SEL (MX21ADS_MMGPIO_BASE + 11)
+#define MX21ADS_IO_IRDA_MD0_B (MX21ADS_MMGPIO_BASE + 12)
+#define MX21ADS_IO_IRDA_MD1 (MX21ADS_MMGPIO_BASE + 13)
+#define MX21ADS_IO_LED4_ON (MX21ADS_MMGPIO_BASE + 14)
+#define MX21ADS_IO_LED3_ON (MX21ADS_MMGPIO_BASE + 15)
+
+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 =
+ DEFINE_RES_MEM(MX21_CS0_BASE_ADDR, SZ_32M);
+
+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 struct resource mx21ads_cs8900_resources[] __initdata = {
+ DEFINE_RES_MEM(MX21ADS_CS8900A_REG, SZ_1K),
+ /* irq number is run-time assigned */
+ DEFINE_RES_IRQ(-1),
+};
+
+static const struct platform_device_info mx21ads_cs8900_devinfo __initconst = {
+ .name = "cs89x0",
+ .id = 0,
+ .res = mx21ads_cs8900_resources,
+ .num_res = ARRAY_SIZE(mx21ads_cs8900_resources),
+};
+
+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 struct resource mx21ads_mmgpio_resource =
+ DEFINE_RES_MEM_NAMED(MX21ADS_IO_REG, SZ_2, "dat");
+
+static struct bgpio_pdata mx21ads_mmgpio_pdata = {
+ .base = MX21ADS_MMGPIO_BASE,
+ .ngpio = 16,
+};
+
+static struct platform_device mx21ads_mmgpio = {
+ .name = "basic-mmio-gpio",
+ .id = PLATFORM_DEVID_AUTO,
+ .resource = &mx21ads_mmgpio_resource,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &mx21ads_mmgpio_pdata,
+ },
+};
+
+static struct regulator_consumer_supply mx21ads_lcd_regulator_consumer =
+ REGULATOR_SUPPLY("lcd", "imx-fb.0");
+
+static struct regulator_init_data mx21ads_lcd_regulator_init_data = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .consumer_supplies = &mx21ads_lcd_regulator_consumer,
+ .num_consumer_supplies = 1,
+};
+
+static struct fixed_voltage_config mx21ads_lcd_regulator_pdata = {
+ .supply_name = "LCD",
+ .microvolts = 3300000,
+ .gpio = MX21ADS_IO_LCDON,
+ .enable_high = 1,
+ .init_data = &mx21ads_lcd_regulator_init_data,
+};
+
+static struct platform_device mx21ads_lcd_regulator = {
+ .name = "reg-fixed-voltage",
+ .id = PLATFORM_DEVID_AUTO,
+ .dev = {
+ .platform_data = &mx21ads_lcd_regulator_pdata,
+ },
+};
+
+/*
+ * 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,
+};
+
+static int mx21ads_sdhc_get_ro(struct device *dev)
+{
+ return gpio_get_value(MX21ADS_IO_SD_WP);
+}
+
+static int mx21ads_sdhc_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ int ret;
+
+ ret = gpio_request(MX21ADS_IO_SD_WP, "mmc-ro");
+ if (ret)
+ return ret;
+
+ return request_irq(gpio_to_irq(MX21ADS_MMC_CD), detect_irq,
+ IRQF_TRIGGER_FALLING, "mmc-detect", data);
+}
+
+static void mx21ads_sdhc_exit(struct device *dev, void *data)
+{
+ free_irq(gpio_to_irq(MX21ADS_MMC_CD), data);
+ gpio_free(MX21ADS_IO_SD_WP);
+}
+
+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 platform_device *platform_devices[] __initdata = {
+ &mx21ads_mmgpio,
+ &mx21ads_lcd_regulator,
+ &mx21ads_nor_mtd_device,
+};
+
+static void __init mx21ads_board_init(void)
+{
+ imx21_soc_init();
+
+ 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_mxc_mmc(0, &mx21ads_sdhc_pdata);
+ imx21_add_mxc_nand(&mx21ads_nand_board_info);
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+ imx21_add_imx_fb(&mx21ads_fb_data);
+
+ mx21ads_cs8900_resources[1].start =
+ gpio_to_irq(MX21ADS_CS8900A_IRQ_GPIO);
+ mx21ads_cs8900_resources[1].end =
+ gpio_to_irq(MX21ADS_CS8900A_IRQ_GPIO);
+ platform_device_register_full(&mx21ads_cs8900_devinfo);
+}
+
+static void __init mx21ads_timer_init(void)
+{
+ mx21_clocks_init(32768, 26000000);
+}
+
+MACHINE_START(MX21ADS, "Freescale i.MX21ADS")
+ /* maintainer: Freescale Semiconductor, Inc. */
+ .atag_offset = 0x100,
+ .map_io = mx21_map_io,
+ .init_early = imx21_init_early,
+ .init_irq = mx21_init_irq,
+ .init_time = mx21ads_timer_init,
+ .init_machine = mx21ads_board_init,
+ .restart = mxc_restart,
+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 000000000..9ef4640f3
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx27_3ds.c
@@ -0,0 +1,551 @@
+/*
+ * 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 <linux/spi/l4f00242t03.h>
+
+#include <media/soc_camera.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "3ds_debugboard.h"
+#include "common.h"
+#include "devices-imx27.h"
+#include "ehci.h"
+#include "hardware.h"
+#include "iomux-mx27.h"
+#include "ulpi.h"
+
+#define SD1_EN_GPIO IMX_GPIO_NR(2, 25)
+#define OTG_PHY_RESET_GPIO IMX_GPIO_NR(2, 23)
+#define SPI2_SS0 IMX_GPIO_NR(4, 21)
+#define PMIC_INT IMX_GPIO_NR(3, 14)
+#define SPI1_SS0 IMX_GPIO_NR(4, 28)
+#define SD1_CD IMX_GPIO_NR(2, 26)
+#define LCD_RESET IMX_GPIO_NR(1, 3)
+#define LCD_ENABLE IMX_GPIO_NR(1, 31)
+#define CSI_PWRDWN IMX_GPIO_NR(4, 19)
+#define CSI_RESET IMX_GPIO_NR(3, 6)
+
+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,
+ /* CSPI1 */
+ PD31_PF_CSPI1_MOSI,
+ PD30_PF_CSPI1_MISO,
+ PD29_PF_CSPI1_SCLK,
+ PD25_PF_CSPI1_RDY,
+ SPI1_SS0 | GPIO_GPIO | GPIO_OUT,
+ /* CSPI2 */
+ PD22_PF_CSPI2_SCLK,
+ PD23_PF_CSPI2_MISO,
+ PD24_PF_CSPI2_MOSI,
+ SPI2_SS0 | GPIO_GPIO | GPIO_OUT,
+ /* I2C1 */
+ PD17_PF_I2C_DATA,
+ PD18_PF_I2C_CLK,
+ /* PMIC INT */
+ PMIC_INT | GPIO_GPIO | GPIO_IN,
+ /* LCD */
+ 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,
+ LCD_ENABLE | GPIO_GPIO | GPIO_OUT,
+ LCD_RESET | GPIO_GPIO | GPIO_OUT,
+ /* CSI */
+ 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,
+ CSI_PWRDWN | GPIO_GPIO | GPIO_OUT,
+ CSI_RESET | GPIO_GPIO | GPIO_OUT,
+ /* SSI4 */
+ PC16_PF_SSI4_FS,
+ PC17_PF_SSI4_RXD,
+ PC18_PF_SSI4_TXD,
+ PC19_PF_SSI4_CLK,
+};
+
+static struct gpio mx27_3ds_camera_gpios[] = {
+ { CSI_PWRDWN, GPIOF_OUT_INIT_HIGH, "camera-power" },
+ { CSI_RESET, GPIOF_OUT_INIT_HIGH, "camera-reset" },
+};
+
+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(gpio_to_irq(SD1_CD), 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(gpio_to_irq(SD1_CD), 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 bool otg_mode_host __initdata;
+
+static int __init mx27_3ds_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = true;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = false;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 1;
+}
+__setup("otg_mode=", mx27_3ds_otg_mode);
+
+/* Regulators */
+static struct regulator_init_data gpo_init = {
+ .constraints = {
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_consumer_supply vmmc1_consumers[] = {
+ REGULATOR_SUPPLY("vcore", "spi0.0"),
+ 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", "spi0.0"),
+};
+
+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 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 mx27_3ds_regulators[] = {
+ {
+ .id = MC13783_REG_VMMC1,
+ .init_data = &vmmc1_init,
+ }, {
+ .id = MC13783_REG_VGEN,
+ .init_data = &vgen_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_VVIB, /* Power OV2640 */
+ .init_data = &vvib_init,
+ },
+};
+
+/* MC13783 */
+static struct mc13xxx_codec_platform_data mx27_3ds_codec = {
+ .dac_ssi_port = MC13783_SSI1_PORT,
+ .adc_ssi_port = MC13783_SSI1_PORT,
+};
+
+static struct mc13xxx_platform_data mc13783_pdata = {
+ .regulators = {
+ .regulators = mx27_3ds_regulators,
+ .num_regulators = ARRAY_SIZE(mx27_3ds_regulators),
+
+ },
+ .flags = MC13XXX_USE_TOUCHSCREEN | MC13XXX_USE_RTC |
+ MC13XXX_USE_CODEC,
+ .codec = &mx27_3ds_codec,
+};
+
+static struct imx_ssi_platform_data mx27_3ds_ssi_pdata = {
+ .flags = IMX_SSI_DMA | IMX_SSI_NET,
+};
+
+/* SPI */
+static int spi1_chipselect[] = {SPI1_SS0};
+
+static const struct spi_imx_master spi1_pdata __initconst = {
+ .chipselect = spi1_chipselect,
+ .num_chipselect = ARRAY_SIZE(spi1_chipselect),
+};
+
+static int spi2_chipselect[] = {SPI2_SS0};
+
+static const struct spi_imx_master spi2_pdata __initconst = {
+ .chipselect = spi2_chipselect,
+ .num_chipselect = ARRAY_SIZE(spi2_chipselect),
+};
+
+static int mx27_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(CSI_PWRDWN, on ? 0 : 1);
+
+ if (!on)
+ goto out;
+
+ /* If enabled, give a reset impulse */
+ gpio_set_value(CSI_RESET, 0);
+ msleep(20);
+ gpio_set_value(CSI_RESET, 1);
+ msleep(100);
+
+out:
+ return 0;
+}
+
+static struct i2c_board_info mx27_3ds_i2c_camera = {
+ I2C_BOARD_INFO("ov2640", 0x30),
+};
+
+static struct regulator_bulk_data mx27_3ds_camera_regs[] = {
+ { .supply = "cmos_vcore" },
+ { .supply = "cmos_2v8" },
+};
+
+static struct soc_camera_link iclink_ov2640 = {
+ .bus_id = 0,
+ .board_info = &mx27_3ds_i2c_camera,
+ .i2c_adapter_id = 0,
+ .power = mx27_3ds_camera_power,
+ .regulators = mx27_3ds_camera_regs,
+ .num_regulators = ARRAY_SIZE(mx27_3ds_camera_regs),
+};
+
+static struct platform_device mx27_3ds_ov2640 = {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &iclink_ov2640,
+ },
+};
+
+static struct imx_fb_videomode mx27_3ds_modes[] = {
+ { /* 480x640 @ 60 Hz */
+ .mode = {
+ .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,
+ },
+ .bpp = 16,
+ .pcr = 0xFAC08B82,
+ },
+};
+
+static const struct imx_fb_platform_data mx27_3ds_fb_data __initconst = {
+ .mode = mx27_3ds_modes,
+ .num_modes = ARRAY_SIZE(mx27_3ds_modes),
+ .pwmr = 0x00A903FF,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00020010,
+};
+
+/* LCD */
+static struct l4f00242t03_pdata mx27_3ds_lcd_pdata = {
+ .reset_gpio = LCD_RESET,
+ .data_enable_gpio = LCD_ENABLE,
+};
+
+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 number is run-time assigned */
+ .mode = SPI_CS_HIGH,
+ }, {
+ .modalias = "l4f00242t03",
+ .max_speed_hz = 5000000,
+ .bus_num = 0,
+ .chip_select = 0, /* SS0 */
+ .platform_data = &mx27_3ds_lcd_pdata,
+ },
+};
+
+static struct platform_device *devices[] __initdata = {
+ &mx27_3ds_ov2640,
+};
+
+static const struct mx2_camera_platform_data mx27_3ds_cam_pdata __initconst = {
+ .clk = 26000000,
+};
+
+static const struct imxi2c_platform_data mx27_3ds_i2c0_data __initconst = {
+ .bitrate = 100000,
+};
+
+static void __init mx27pdk_init(void)
+{
+ int ret;
+ imx27_soc_init();
+
+ 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();
+ 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);
+ imx27_add_spi_imx0(&spi1_pdata);
+ mx27_3ds_spi_devs[0].irq = gpio_to_irq(PMIC_INT);
+ spi_register_board_info(mx27_3ds_spi_devs,
+ ARRAY_SIZE(mx27_3ds_spi_devs));
+
+ if (mxc_expio_init(MX27_CS5_BASE_ADDR, IMX_GPIO_NR(3, 28)))
+ pr_warn("Init of the debugboard failed, all devices on the debugboard are unusable.\n");
+ imx27_add_imx_i2c(0, &mx27_3ds_i2c0_data);
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ imx27_add_imx_fb(&mx27_3ds_fb_data);
+
+ ret = gpio_request_array(mx27_3ds_camera_gpios,
+ ARRAY_SIZE(mx27_3ds_camera_gpios));
+ if (ret) {
+ pr_err("Failed to request camera gpios");
+ iclink_ov2640.power = NULL;
+ }
+
+ imx27_add_mx2_camera(&mx27_3ds_cam_pdata);
+ imx27_add_imx_ssi(0, &mx27_3ds_ssi_pdata);
+
+ imx_add_platform_device("imx_mc13783", 0, NULL, 0, NULL, 0);
+}
+
+static void __init mx27pdk_timer_init(void)
+{
+ mx27_clocks_init(26000000);
+}
+
+MACHINE_START(MX27_3DS, "Freescale MX27PDK")
+ /* maintainer: Freescale Semiconductor, Inc. */
+ .atag_offset = 0x100,
+ .map_io = mx27_map_io,
+ .init_early = imx27_init_early,
+ .init_irq = mx27_init_irq,
+ .init_time = mx27pdk_timer_init,
+ .init_machine = mx27pdk_init,
+ .restart = mxc_restart,
+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 000000000..eb1c3477c
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx27ads.c
@@ -0,0 +1,397 @@
+/*
+ * 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/gpio.h>
+#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 <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+#include "devices-imx27.h"
+#include "hardware.h"
+#include "iomux-mx27.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[] = {
+};
+
+static void vgpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ if (value)
+ __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG);
+ else
+ __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG);
+}
+
+static int vgpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
+{
+ return 0;
+}
+
+#define MX27ADS_LCD_GPIO (6 * 32)
+
+static struct regulator_consumer_supply mx27ads_lcd_regulator_consumer =
+ REGULATOR_SUPPLY("lcd", "imx-fb.0");
+
+static struct regulator_init_data mx27ads_lcd_regulator_init_data = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+},
+ .consumer_supplies = &mx27ads_lcd_regulator_consumer,
+ .num_consumer_supplies = 1,
+};
+
+static struct fixed_voltage_config mx27ads_lcd_regulator_pdata = {
+ .supply_name = "LCD",
+ .microvolts = 3300000,
+ .gpio = MX27ADS_LCD_GPIO,
+ .init_data = &mx27ads_lcd_regulator_init_data,
+};
+
+static void __init mx27ads_regulator_init(void)
+{
+ struct gpio_chip *vchip;
+
+ vchip = kzalloc(sizeof(*vchip), GFP_KERNEL);
+ vchip->owner = THIS_MODULE;
+ vchip->label = "LCD";
+ vchip->base = MX27ADS_LCD_GPIO;
+ vchip->ngpio = 1;
+ vchip->direction_output = vgpio_dir_out;
+ vchip->set = vgpio_set;
+ gpiochip_add(vchip);
+
+ platform_device_register_data(NULL, "reg-fixed-voltage",
+ PLATFORM_DEVID_AUTO,
+ &mx27ads_lcd_regulator_pdata,
+ sizeof(mx27ads_lcd_regulator_pdata));
+}
+
+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,
+};
+
+static int mx27ads_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ return request_irq(gpio_to_irq(IMX_GPIO_NR(5, 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(gpio_to_irq(IMX_GPIO_NR(2, 7)), detect_irq,
+ IRQF_TRIGGER_RISING, "sdhc2-card-detect", data);
+}
+
+static void mx27ads_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(gpio_to_irq(IMX_GPIO_NR(5, 21)), data);
+}
+
+static void mx27ads_sdhc2_exit(struct device *dev, void *data)
+{
+ free_irq(gpio_to_irq(IMX_GPIO_NR(2, 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)
+{
+ imx27_soc_init();
+
+ 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);
+ mx27ads_regulator_init();
+ 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();
+}
+
+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 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. */
+ .atag_offset = 0x100,
+ .map_io = mx27ads_map_io,
+ .init_early = imx27_init_early,
+ .init_irq = mx27_init_irq,
+ .init_time = mx27ads_timer_init,
+ .init_machine = mx27ads_board_init,
+ .restart = mxc_restart,
+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 000000000..65a0dc06a
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx31_3ds.c
@@ -0,0 +1,783 @@
+/*
+ * 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 <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/memory.h>
+#include <asm/mach/map.h>
+#include <asm/memblock.h>
+
+#include "3ds_debugboard.h"
+#include "common.h"
+#include "devices-imx31.h"
+#include "ehci.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "ulpi.h"
+
+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*/
+ IOMUX_MODE(MX31_PIN_DSR_DCE1, IOMUX_CONFIG_ALT1),
+ IOMUX_MODE(MX31_PIN_RI_DCE1, IOMUX_CONFIG_ALT1),
+ /* 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 */
+ /* SSI */
+ MX31_PIN_STXD4__STXD4,
+ MX31_PIN_SRXD4__SRXD4,
+ MX31_PIN_SCK4__SCK4,
+ MX31_PIN_SFS4__SFS4,
+};
+
+/*
+ * 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 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),
+};
+
+/*
+ * 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_warn("Unable to request the SD/MMC GPIOs.\n");
+ return ret;
+ }
+
+ ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)),
+ detect_irq,
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ "sdhc1-detect", data);
+ if (ret) {
+ pr_warn("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(gpio_to_irq(IOMUX_TO_GPIO(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", "imx31-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("vcore", "spi0.0"),
+ 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", "spi0.0"),
+};
+
+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_codec_platform_data mx31_3ds_codec = {
+ .dac_ssi_port = MC13783_SSI1_PORT,
+ .adc_ssi_port = MC13783_SSI1_PORT,
+};
+
+static struct mc13xxx_platform_data mc13783_pdata = {
+ .regulators = {
+ .regulators = mx31_3ds_regulators,
+ .num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
+ },
+ .codec = &mx31_3ds_codec,
+ .flags = MC13XXX_USE_TOUCHSCREEN | MC13XXX_USE_RTC | MC13XXX_USE_CODEC,
+
+};
+
+static struct imx_ssi_platform_data mx31_3ds_ssi_pdata = {
+ .flags = IMX_SSI_DMA | IMX_SSI_NET,
+};
+
+/* 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 number is run-time assigned */
+ .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 CONFIG_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 bool otg_mode_host __initdata;
+
+static int __init mx31_3ds_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = true;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = false;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 1;
+}
+__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;
+
+ imx31_soc_init();
+
+ /* Configure SPI1 IOMUX */
+ mxc_iomux_set_gpr(MUX_PGP_CSPI_BB, true);
+
+ 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);
+ mx31_3ds_spi_devs[0].irq = gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3));
+ 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, IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)))
+ printk(KERN_WARNING "Init of the debug board failed, all "
+ "devices on the debug board are unusable.\n");
+ imx31_add_imx2_wdt();
+ 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();
+ 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();
+
+ imx31_add_imx_ssi(0, &mx31_3ds_ssi_pdata);
+
+ imx_add_platform_device("imx_mc13783", 0, NULL, 0, NULL, 0);
+}
+
+static void __init mx31_3ds_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static void __init mx31_3ds_reserve(void)
+{
+ /* reserve MX31_3DS_CAMERA_BUF_SIZE bytes for mx3-camera */
+ mx3_camera_base = arm_memblock_steal(MX31_3DS_CAMERA_BUF_SIZE,
+ MX31_3DS_CAMERA_BUF_SIZE);
+}
+
+MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .atag_offset = 0x100,
+ .map_io = mx31_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .init_time = mx31_3ds_timer_init,
+ .init_machine = mx31_3ds_init,
+ .reserve = mx31_3ds_reserve,
+ .restart = mxc_restart,
+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 000000000..d08c37c69
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx31ads.c
@@ -0,0 +1,588 @@
+/*
+ * 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 <linux/irqdomain.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>
+
+#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 "common.h"
+#include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+
+/* Base address of PBC controller */
+#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT
+
+/* 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_INT_XUART_INTA 10
+#define EXPIO_INT_XUART_INTB 11
+
+#define MXC_MAX_EXP_IO_LINES 16
+
+/* CS8900 */
+#define EXPIO_INT_ENET_INT 8
+#define CS4_CS8900_MMIO_START 0x20000
+
+static struct irq_domain *domain;
+
+/*
+ * 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),
+ .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),
+ .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 struct resource mx31ads_cs8900_resources[] __initdata = {
+ DEFINE_RES_MEM(MX31_CS4_BASE_ADDR + CS4_CS8900_MMIO_START, SZ_64K),
+ DEFINE_RES_IRQ(-1),
+};
+
+static const struct platform_device_info mx31ads_cs8900_devinfo __initconst = {
+ .name = "cs89x0",
+ .id = 0,
+ .res = mx31ads_cs8900_resources,
+ .num_res = ARRAY_SIZE(mx31ads_cs8900_resources),
+};
+
+static int __init mxc_init_extuart(void)
+{
+ serial_platform_data[0].irq = irq_find_mapping(domain,
+ EXPIO_INT_XUART_INTA);
+ serial_platform_data[1].irq = irq_find_mapping(domain,
+ EXPIO_INT_XUART_INTB);
+ return platform_device_register(&serial_device);
+}
+
+static void __init mxc_init_ext_ethernet(void)
+{
+ mx31ads_cs8900_resources[1].start =
+ irq_find_mapping(domain, EXPIO_INT_ENET_INT);
+ mx31ads_cs8900_resources[1].end =
+ irq_find_mapping(domain, EXPIO_INT_ENET_INT);
+ platform_device_register_full(
+ (struct platform_device_info *)&mx31ads_cs8900_devinfo);
+}
+
+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 = 0;
+ for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
+ if ((int_valid & 1) == 0)
+ continue;
+
+ generic_handle_irq(irq_find_mapping(domain, 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 = d->hwirq;
+ /* 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 = d->hwirq;
+ /* 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 = d->hwirq;
+ /* 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 irq_base;
+ int i, irq;
+
+ 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);
+
+ irq_base = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, numa_node_id());
+ WARN_ON(irq_base < 0);
+
+ domain = irq_domain_add_legacy(NULL, MXC_MAX_EXP_IO_LINES, irq_base, 0,
+ &irq_domain_simple_ops, NULL);
+ WARN_ON(!domain);
+
+ for (i = irq_base; i < irq_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 = gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_4));
+ irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
+ irq_set_chained_handler(irq, 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,
+};
+#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 number is run-time assigned */
+ },
+#endif
+};
+
+static void __init mxc_init_i2c(void)
+{
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+ mx31ads_i2c1_devices[0].irq =
+ gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3));
+#endif
+ 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 __init mxc_init_audio(void)
+{
+ imx31_add_imx_ssi(0, NULL);
+ mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi");
+}
+
+/*
+ * Static mappings, starting from the CS4 start address up to the start address
+ * of the CS8900.
+ */
+static struct map_desc mx31ads_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long)MX31_CS4_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR),
+ .length = CS4_CS8900_MMIO_START,
+ .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)
+{
+ imx31_soc_init();
+
+ mxc_init_extuart();
+ mxc_init_imx_uart();
+ mxc_init_i2c();
+ mxc_init_audio();
+ mxc_init_ext_ethernet();
+}
+
+static void __init mx31ads_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+MACHINE_START(MX31ADS, "Freescale MX31ADS")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .atag_offset = 0x100,
+ .map_io = mx31ads_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31ads_init_irq,
+ .init_time = mx31ads_timer_init,
+ .init_machine = mx31ads_init,
+ .restart = mxc_restart,
+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 000000000..e9549a3c0
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx31lilly.c
@@ -0,0 +1,315 @@
+/*
+ * 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/moduleparam.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 <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include "board-mx31lilly.h"
+#include "common.h"
+#include "devices-imx31.h"
+#include "ehci.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "ulpi.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,
+ },
+ {
+ /* irq number is run-time assigned */
+ .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 __init 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 number is run-time assigned */
+};
+
+static struct platform_device *devices[] __initdata = {
+ &smsc91x_device,
+ &physmap_flash_device,
+};
+
+static int mx31lilly_baseboard;
+core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444);
+
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+};
+
+static void __init mx31lilly_board_init(void)
+{
+ imx31_soc_init();
+
+ 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);
+ mc13783_dev.irq = gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3));
+ spi_register_board_info(&mc13783_dev, 1);
+
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
+ smsc91x_resources[1].start =
+ gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_0));
+ smsc91x_resources[1].end =
+ gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_0));
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ /* USB */
+ lilly1131_usb_init();
+}
+
+static void __init mx31lilly_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+MACHINE_START(LILLY1131, "INCO startec LILLY-1131")
+ .atag_offset = 0x100,
+ .map_io = mx31_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .init_time = mx31lilly_timer_init,
+ .init_machine = mx31lilly_board_init,
+ .restart = mxc_restart,
+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 000000000..4822a1738
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx31lite.c
@@ -0,0 +1,298 @@
+/*
+ * 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/moduleparam.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 <linux/regulator/machine.h>
+#include <linux/regulator/fixed.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 "board-mx31lite.h"
+#include "common.h"
+#include "devices-imx31.h"
+#include "ehci.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "ulpi.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,
+ }, {
+ /* irq number is run-time assigned */
+ .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,
+};
+
+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 number is run-time assigned */
+};
+
+/*
+ * 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 = (unsigned long)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 struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+};
+
+static void __init mx31lite_init(void)
+{
+ int ret;
+
+ imx31_soc_init();
+
+ 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);
+ mc13783_spi_dev.irq = gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3));
+ 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);
+
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
+ /* SMSC9117 IRQ pin */
+ ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_SFS6), "sms9117-irq");
+ if (ret)
+ pr_warn("could not get LAN irq gpio\n");
+ else {
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_SFS6));
+ smsc911x_resources[1].start =
+ gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_SFS6));
+ smsc911x_resources[1].end =
+ gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_SFS6));
+ platform_device_register(&smsc911x_device);
+ }
+}
+
+static void __init mx31lite_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+MACHINE_START(MX31LITE, "LogicPD i.MX31 SOM")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .atag_offset = 0x100,
+ .map_io = mx31lite_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .init_time = mx31lite_timer_init,
+ .init_machine = mx31lite_init,
+ .restart = mxc_restart,
+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 000000000..bb6f8a52a
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx31moboard.c
@@ -0,0 +1,605 @@
+/*
+ * 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/moduleparam.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/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/input.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 <asm/memblock.h>
+#include <linux/platform_data/asoc-imx-ssi.h>
+
+#include "board-mx31moboard.h"
+#include "common.h"
+#include "devices-imx31.h"
+#include "ehci.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "ulpi.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,
+ /* SSI */
+ MX31_PIN_STXD4__STXD4, MX31_PIN_SRXD4__SRXD4,
+ MX31_PIN_SCK4__SCK4, MX31_PIN_SFS4__SFS4,
+};
+
+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 void __init moboard_uart0_init(void)
+{
+ if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), "uart0-cts-hack")) {
+ gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CTS1), 0);
+ gpio_free(IOMUX_TO_GPIO(MX31_PIN_CTS1));
+ }
+}
+
+static const struct imxuart_platform_data uart0_pdata __initconst = {
+};
+
+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 = "imx31-mmc.0",
+ .supply = "sdhc0_vcc",
+ },
+ {
+ .dev_name = "imx31-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 mc13xxx_led_platform_data moboard_led[] = {
+ {
+ .id = MC13783_LED_R1,
+ .name = "coreboard-led-4:red",
+ },
+ {
+ .id = MC13783_LED_G1,
+ .name = "coreboard-led-4:green",
+ },
+ {
+ .id = MC13783_LED_B1,
+ .name = "coreboard-led-4:blue",
+ },
+ {
+ .id = MC13783_LED_R2,
+ .name = "coreboard-led-5:red",
+ },
+ {
+ .id = MC13783_LED_G2,
+ .name = "coreboard-led-5:green",
+ },
+ {
+ .id = MC13783_LED_B2,
+ .name = "coreboard-led-5:blue",
+ },
+};
+
+static struct mc13xxx_leds_platform_data moboard_leds = {
+ .num_leds = ARRAY_SIZE(moboard_led),
+ .led = moboard_led,
+ .led_control[0] = MC13783_LED_C0_ENABLE | MC13783_LED_C0_ABMODE(0),
+ .led_control[1] = MC13783_LED_C1_SLEWLIM,
+ .led_control[2] = MC13783_LED_C2_SLEWLIM,
+ .led_control[3] = MC13783_LED_C3_PERIOD(0) |
+ MC13783_LED_C3_CURRENT_R1(2) |
+ MC13783_LED_C3_CURRENT_G1(2) |
+ MC13783_LED_C3_CURRENT_B1(2),
+ .led_control[4] = MC13783_LED_C4_PERIOD(0) |
+ MC13783_LED_C4_CURRENT_R2(3) |
+ MC13783_LED_C4_CURRENT_G2(3) |
+ MC13783_LED_C4_CURRENT_B2(3),
+};
+
+static struct mc13xxx_buttons_platform_data moboard_buttons = {
+ .b1on_flags = MC13783_BUTTON_DBNC_750MS | MC13783_BUTTON_ENABLE |
+ MC13783_BUTTON_POL_INVERT,
+ .b1on_key = KEY_POWER,
+};
+
+static struct mc13xxx_codec_platform_data moboard_codec = {
+ .dac_ssi_port = MC13783_SSI1_PORT,
+ .adc_ssi_port = MC13783_SSI1_PORT,
+};
+
+static struct mc13xxx_platform_data moboard_pmic = {
+ .regulators = {
+ .regulators = moboard_regulators,
+ .num_regulators = ARRAY_SIZE(moboard_regulators),
+ },
+ .leds = &moboard_leds,
+ .buttons = &moboard_buttons,
+ .codec = &moboard_codec,
+ .flags = MC13XXX_USE_RTC | MC13XXX_USE_ADC | MC13XXX_USE_CODEC,
+};
+
+static struct imx_ssi_platform_data moboard_ssi_pdata = {
+ .flags = IMX_SSI_DMA | IMX_SSI_NET,
+};
+
+static struct spi_board_info moboard_spi_board_info[] __initdata = {
+ {
+ .modalias = "mc13783",
+ /* irq number is run-time assigned */
+ .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);
+
+ return PTR_ERR_OR_ZERO(pdev);
+}
+
+static const struct gpio_led mx31moboard_leds[] __initconst = {
+ {
+ .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 const struct gpio_led_platform_data mx31moboard_led_pdata __initconst = {
+ .num_leds = ARRAY_SIZE(mx31moboard_leds),
+ .leds = mx31moboard_leds,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &mx31moboard_flash,
+};
+
+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();
+
+ 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 void mx31moboard_poweroff(void)
+{
+ struct clk *clk = clk_get_sys("imx2-wdt.0", NULL);
+
+ if (!IS_ERR(clk))
+ clk_prepare_enable(clk);
+
+ mxc_iomux_mode(MX31_PIN_WATCHDOG_RST__WATCHDOG_RST);
+
+ __raw_writew(1 << 6 | 1 << 2, MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
+}
+
+static int mx31moboard_baseboard;
+core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444);
+
+/*
+ * Board specific initialization.
+ */
+static void __init mx31moboard_init(void)
+{
+ imx31_soc_init();
+
+ mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins),
+ "moboard");
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ gpio_led_register_device(-1, &mx31moboard_led_pdata);
+
+ imx31_add_imx2_wdt();
+
+ moboard_uart0_init();
+ 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));
+ moboard_spi_board_info[0].irq =
+ gpio_to_irq(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();
+
+ imx31_add_imx_ssi(0, &moboard_ssi_pdata);
+
+ imx_add_platform_device("imx_mc13783", 0, NULL, 0, NULL, 0);
+
+ pm_power_off = mx31moboard_poweroff;
+
+ 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);
+}
+
+static void __init mx31moboard_reserve(void)
+{
+ /* reserve 4 MiB for mx3-camera */
+ mx3_camera_base = arm_memblock_steal(MX3_CAMERA_BUF_SIZE,
+ MX3_CAMERA_BUF_SIZE);
+}
+
+MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")
+ /* Maintainer: Philippe Retornaz, EPFL Mobots group */
+ .atag_offset = 0x100,
+ .reserve = mx31moboard_reserve,
+ .map_io = mx31_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .init_time = mx31moboard_timer_init,
+ .init_machine = mx31moboard_init,
+ .restart = mxc_restart,
+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 000000000..7e315f006
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx35_3ds.c
@@ -0,0 +1,623 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Marc Kleine-Budde, Pengutronix
+ *
+ * Author: Fabio Estevam <fabio.estevam@freescale.com>
+ *
+ * Copyright (C) 2011 Meprolight, Ltd.
+ * Alex Gershgorin <alexg@meprolight.com>
+ *
+ * Modified from i.MX31 3-Stack Development System
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <linux/mfd/mc13892.h>
+#include <linux/regulator/machine.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <asm/memblock.h>
+
+#include <video/platform_lcd.h>
+
+#include <media/soc_camera.h>
+
+#include "3ds_debugboard.h"
+#include "common.h"
+#include "devices-imx35.h"
+#include "ehci.h"
+#include "hardware.h"
+#include "iomux-mx35.h"
+
+#define GPIO_MC9S08DZ60_GPS_ENABLE 0
+#define GPIO_MC9S08DZ60_HDD_ENABLE 4
+#define GPIO_MC9S08DZ60_WIFI_ENABLE 5
+#define GPIO_MC9S08DZ60_LCD_ENABLE 6
+#define GPIO_MC9S08DZ60_SPEAKER_ENABLE 8
+
+static const struct fb_videomode fb_modedb[] = {
+ {
+ /* 800x480 @ 55 Hz */
+ .name = "Ceramate-CLAA070VC01",
+ .refresh = 55,
+ .xres = 800,
+ .yres = 480,
+ .pixclock = 40000,
+ .left_margin = 40,
+ .right_margin = 40,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 20,
+ .vsync_len = 10,
+ .sync = FB_SYNC_OE_ACT_HIGH,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+};
+
+static struct mx3fb_platform_data mx3fb_pdata __initdata = {
+ .name = "Ceramate-CLAA070VC01",
+ .mode = fb_modedb,
+ .num_modes = ARRAY_SIZE(fb_modedb),
+};
+
+static struct i2c_board_info __initdata i2c_devices_3ds[] = {
+ {
+ I2C_BOARD_INFO("mc9s08dz60", 0x69),
+ },
+};
+
+static int lcd_power_gpio = -ENXIO;
+
+static int mc9s08dz60_gpiochip_match(struct gpio_chip *chip, void *data)
+{
+ return !strcmp(chip->label, data);
+}
+
+static void mx35_3ds_lcd_set_power(
+ struct plat_lcd_data *pd, unsigned int power)
+{
+ struct gpio_chip *chip;
+
+ if (!gpio_is_valid(lcd_power_gpio)) {
+ chip = gpiochip_find(
+ "mc9s08dz60", mc9s08dz60_gpiochip_match);
+ if (chip) {
+ lcd_power_gpio =
+ chip->base + GPIO_MC9S08DZ60_LCD_ENABLE;
+ if (gpio_request(lcd_power_gpio, "lcd_power") < 0) {
+ pr_err("error: gpio already requested!\n");
+ lcd_power_gpio = -ENXIO;
+ }
+ } else {
+ pr_err("error: didn't find mc9s08dz60 gpio chip\n");
+ }
+ }
+
+ if (gpio_is_valid(lcd_power_gpio))
+ gpio_set_value_cansleep(lcd_power_gpio, power);
+}
+
+static struct plat_lcd_data mx35_3ds_lcd_data = {
+ .set_power = mx35_3ds_lcd_set_power,
+};
+
+static struct platform_device mx35_3ds_lcd = {
+ .name = "platform-lcd",
+ .dev.platform_data = &mx35_3ds_lcd_data,
+};
+
+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 const iomux_v3_cfg_t mx35pdk_pads[] __initconst = {
+ /* 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,
+ /* 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,
+ /* CSI */
+ MX35_PAD_TX1__IPU_CSI_D_6,
+ MX35_PAD_TX0__IPU_CSI_D_7,
+ MX35_PAD_CSI_D8__IPU_CSI_D_8,
+ MX35_PAD_CSI_D9__IPU_CSI_D_9,
+ MX35_PAD_CSI_D10__IPU_CSI_D_10,
+ MX35_PAD_CSI_D11__IPU_CSI_D_11,
+ MX35_PAD_CSI_D12__IPU_CSI_D_12,
+ MX35_PAD_CSI_D13__IPU_CSI_D_13,
+ MX35_PAD_CSI_D14__IPU_CSI_D_14,
+ MX35_PAD_CSI_D15__IPU_CSI_D_15,
+ MX35_PAD_CSI_HSYNC__IPU_CSI_HSYNC,
+ MX35_PAD_CSI_MCLK__IPU_CSI_MCLK,
+ MX35_PAD_CSI_PIXCLK__IPU_CSI_PIXCLK,
+ MX35_PAD_CSI_VSYNC__IPU_CSI_VSYNC,
+ /*PMIC IRQ*/
+ MX35_PAD_GPIO2_0__GPIO2_0,
+};
+
+/*
+ * Camera support
+*/
+static phys_addr_t mx3_camera_base __initdata;
+#define MX35_3DS_CAMERA_BUF_SIZE SZ_8M
+
+static const struct mx3_camera_pdata mx35_3ds_camera_pdata __initconst = {
+ .flags = MX3_CAMERA_DATAWIDTH_8,
+ .mclk_10khz = 2000,
+};
+
+static int __init imx35_3ds_init_camera(void)
+{
+ int dma, ret = -ENOMEM;
+ struct platform_device *pdev =
+ imx35_alloc_mx3_camera(&mx35_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,
+ MX35_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 struct i2c_board_info mx35_3ds_i2c_camera = {
+ I2C_BOARD_INFO("ov2640", 0x30),
+};
+
+static struct soc_camera_link iclink_ov2640 = {
+ .bus_id = 0,
+ .board_info = &mx35_3ds_i2c_camera,
+ .i2c_adapter_id = 0,
+ .power = NULL,
+};
+
+static struct platform_device mx35_3ds_ov2640 = {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &iclink_ov2640,
+ },
+};
+
+static struct regulator_consumer_supply sw1_consumers[] = {
+ {
+ .supply = "cpu_vcc",
+ }
+};
+
+static struct regulator_consumer_supply vcam_consumers[] = {
+ /* sgtl5000 */
+ REGULATOR_SUPPLY("VDDA", "0-000a"),
+};
+
+static struct regulator_consumer_supply vaudio_consumers[] = {
+ REGULATOR_SUPPLY("cmos_vio", "soc-camera-pdrv.0"),
+};
+
+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,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw1_consumers),
+ .consumer_supplies = sw1_consumers,
+};
+
+static struct regulator_init_data sw2_init = {
+ .constraints = {
+ .name = "SW2",
+ .always_on = 1,
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data sw3_init = {
+ .constraints = {
+ .name = "SW3",
+ .always_on = 1,
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data sw4_init = {
+ .constraints = {
+ .name = "SW4",
+ .always_on = 1,
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data viohi_init = {
+ .constraints = {
+ .name = "VIOHI",
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data vusb_init = {
+ .constraints = {
+ .name = "VUSB",
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data vdig_init = {
+ .constraints = {
+ .name = "VDIG",
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data vpll_init = {
+ .constraints = {
+ .name = "VPLL",
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data vusb2_init = {
+ .constraints = {
+ .name = "VUSB2",
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data vvideo_init = {
+ .constraints = {
+ .name = "VVIDEO",
+ .boot_on = 1
+ }
+};
+
+static struct regulator_init_data vaudio_init = {
+ .constraints = {
+ .name = "VAUDIO",
+ .min_uV = 2300000,
+ .max_uV = 3000000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .boot_on = 1
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vaudio_consumers),
+ .consumer_supplies = vaudio_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,
+ .valid_modes_mask = REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL,
+ .boot_on = 1
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vcam_consumers),
+ .consumer_supplies = vcam_consumers,
+};
+
+static struct regulator_init_data vgen1_init = {
+ .constraints = {
+ .name = "VGEN1",
+ }
+};
+
+static struct regulator_init_data vgen2_init = {
+ .constraints = {
+ .name = "VGEN2",
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data vgen3_init = {
+ .constraints = {
+ .name = "VGEN3",
+ }
+};
+
+static struct mc13xxx_regulator_init_data mx35_3ds_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_VIOHI, .init_data = &viohi_init },
+ { .id = MC13892_VPLL, .init_data = &vpll_init },
+ { .id = MC13892_VDIG, .init_data = &vdig_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 },
+};
+
+static struct mc13xxx_platform_data mx35_3ds_mc13892_data = {
+ .flags = MC13XXX_USE_RTC | MC13XXX_USE_TOUCHSCREEN,
+ .regulators = {
+ .num_regulators = ARRAY_SIZE(mx35_3ds_regulators),
+ .regulators = mx35_3ds_regulators,
+ },
+};
+
+#define GPIO_PMIC_INT IMX_GPIO_NR(2, 0)
+
+static struct i2c_board_info mx35_3ds_i2c_mc13892 = {
+
+ I2C_BOARD_INFO("mc13892", 0x08),
+ .platform_data = &mx35_3ds_mc13892_data,
+ /* irq number is run-time assigned */
+};
+
+static void __init imx35_3ds_init_mc13892(void)
+{
+ int ret = gpio_request_one(GPIO_PMIC_INT, GPIOF_DIR_IN, "pmic irq");
+
+ if (ret) {
+ pr_err("failed to get pmic irq: %d\n", ret);
+ return;
+ }
+
+ mx35_3ds_i2c_mc13892.irq = gpio_to_irq(GPIO_PMIC_INT);
+ i2c_register_board_info(0, &mx35_3ds_i2c_mc13892, 1);
+}
+
+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 bool otg_mode_host __initdata;
+
+static int __init mx35_3ds_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = true;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = false;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 1;
+}
+__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)
+{
+ struct platform_device *imx35_fb_pdev;
+
+ imx35_soc_init();
+
+ mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads));
+
+ imx35_add_fec(NULL);
+ imx35_add_imx2_wdt();
+ imx35_add_mxc_rtc();
+ 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, IMX_GPIO_NR(1, 1)))
+ pr_warn("Init of the debugboard failed, all "
+ "devices on the debugboard are unusable.\n");
+ imx35_add_imx_i2c0(&mx35_3ds_i2c0_data);
+
+ i2c_register_board_info(
+ 0, i2c_devices_3ds, ARRAY_SIZE(i2c_devices_3ds));
+
+ imx35_add_ipu_core();
+ platform_device_register(&mx35_3ds_ov2640);
+ imx35_3ds_init_camera();
+
+ imx35_fb_pdev = imx35_add_mx3_sdc_fb(&mx3fb_pdata);
+ mx35_3ds_lcd.dev.parent = &imx35_fb_pdev->dev;
+ platform_device_register(&mx35_3ds_lcd);
+
+ imx35_3ds_init_mc13892();
+}
+
+static void __init mx35pdk_timer_init(void)
+{
+ mx35_clocks_init();
+}
+
+static void __init mx35_3ds_reserve(void)
+{
+ /* reserve MX35_3DS_CAMERA_BUF_SIZE bytes for mx3-camera */
+ mx3_camera_base = arm_memblock_steal(MX35_3DS_CAMERA_BUF_SIZE,
+ MX35_3DS_CAMERA_BUF_SIZE);
+}
+
+MACHINE_START(MX35_3DS, "Freescale MX35PDK")
+ /* Maintainer: Freescale Semiconductor, Inc */
+ .atag_offset = 0x100,
+ .map_io = mx35_map_io,
+ .init_early = imx35_init_early,
+ .init_irq = mx35_init_irq,
+ .init_time = mx35pdk_timer_init,
+ .init_machine = mx35_3ds_init,
+ .reserve = mx35_3ds_reserve,
+ .restart = mxc_restart,
+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 000000000..2d1c50bd8
--- /dev/null
+++ b/arch/arm/mach-imx/mach-pca100.c
@@ -0,0 +1,427 @@
+/*
+ * 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/platform_data/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 <asm/mach/time.h>
+
+#include "common.h"
+#include "devices-imx27.h"
+#include "ehci.h"
+#include "hardware.h"
+#include "iomux-mx27.h"
+#include "ulpi.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(gpio_to_irq(IMX_GPIO_NR(3, 29)), detect_irq,
+ IRQF_TRIGGER_FALLING, "imx-mmc-detect", data);
+ if (ret)
+ printk(KERN_ERR
+ "pca100: Failed to request irq for sd/mmc detection\n");
+
+ return ret;
+}
+
+static void pca100_sdhc2_exit(struct device *dev, void *data)
+{
+ free_irq(gpio_to_irq(IMX_GPIO_NR(3, 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 bool otg_mode_host __initdata;
+
+static int __init pca100_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = true;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = false;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 1;
+}
+__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;
+
+ imx27_soc_init();
+
+ 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 = imx_otg_ulpi_create(
+ 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();
+ imx27_add_mxc_w1();
+}
+
+static void __init pca100_timer_init(void)
+{
+ mx27_clocks_init(26000000);
+}
+
+MACHINE_START(PCA100, "phyCARD-i.MX27")
+ .atag_offset = 0x100,
+ .map_io = mx27_map_io,
+ .init_early = imx27_init_early,
+ .init_irq = mx27_init_irq,
+ .init_machine = pca100_init,
+ .init_time = pca100_timer_init,
+ .restart = mxc_restart,
+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 000000000..6d879417d
--- /dev/null
+++ b/arch/arm/mach-imx/mach-pcm037.c
@@ -0,0 +1,711 @@
+/*
+ * 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/platform_data/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 <linux/regulator/machine.h>
+#include <linux/regulator/fixed.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 <asm/memblock.h>
+
+#include "common.h"
+#include "devices-imx31.h"
+#include "ehci.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "pcm037.h"
+#include "ulpi.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_warn("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,
+ }, {
+ /* irq number is run-time assigned */
+ .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(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_SCK6)), detect_irq,
+ 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(gpio_to_irq(IOMUX_TO_GPIO(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 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,
+ }, {
+ /* irq number is run-time assigned */
+ .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 bool otg_mode_host __initdata;
+
+static int __init pcm037_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = true;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = false;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 1;
+}
+__setup("otg_mode=", pcm037_otg_mode);
+
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init pcm037_init(void)
+{
+ int ret;
+
+ imx31_soc_init();
+
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
+ 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();
+ 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();
+
+ /* LAN9217 IRQ pin */
+ ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1), "lan9217-irq");
+ if (ret)
+ pr_warn("could not get LAN irq gpio\n");
+ else {
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1));
+ smsc911x_resources[1].start =
+ gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1));
+ smsc911x_resources[1].end =
+ gpio_to_irq(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();
+ 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();
+
+ pcm970_sja1000_resources[1].start =
+ gpio_to_irq(IOMUX_TO_GPIO(IOMUX_PIN(48, 105)));
+ pcm970_sja1000_resources[1].end =
+ gpio_to_irq(IOMUX_TO_GPIO(IOMUX_PIN(48, 105)));
+ 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);
+}
+
+static void __init pcm037_reserve(void)
+{
+ /* reserve 4 MiB for mx3-camera */
+ mx3_camera_base = arm_memblock_steal(MX3_CAMERA_BUF_SIZE,
+ MX3_CAMERA_BUF_SIZE);
+}
+
+static void __init pcm037_init_late(void)
+{
+ pcm037_eet_init_devices();
+}
+
+MACHINE_START(PCM037, "Phytec Phycore pcm037")
+ /* Maintainer: Pengutronix */
+ .atag_offset = 0x100,
+ .reserve = pcm037_reserve,
+ .map_io = mx31_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .init_time = pcm037_timer_init,
+ .init_machine = pcm037_init,
+ .init_late = pcm037_init_late,
+ .restart = mxc_restart,
+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 000000000..8fd825506
--- /dev/null
+++ b/arch/arm/mach-imx/mach-pcm037_eet.c
@@ -0,0 +1,177 @@
+/*
+ * 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 <asm/mach-types.h>
+
+#include "pcm037.h"
+#include "common.h"
+#include "devices-imx31.h"
+#include "iomux-mx3.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 */
+};
+
+int __init pcm037_eet_init_devices(void)
+{
+ if (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;
+}
diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c
new file mode 100644
index 000000000..e447e59c0
--- /dev/null
+++ b/arch/arm/mach-imx/mach-pcm043.c
@@ -0,0 +1,407 @@
+/*
+ * 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/platform_data/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 "common.h"
+#include "devices-imx35.h"
+#include "ehci.h"
+#include "hardware.h"
+#include "iomux-mx35.h"
+#include "ulpi.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 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 const iomux_v3_cfg_t pcm043_pads[] __initconst = {
+ /* 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 bool otg_mode_host __initdata;
+
+static int __init pcm043_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = true;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = false;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 1;
+}
+__setup("otg_mode=", pcm043_otg_mode);
+
+static struct esdhc_platform_data sd1_pdata = {
+ .wp_gpio = SD1_GPIO_WP,
+ .cd_gpio = SD1_GPIO_CD,
+ .wp_type = ESDHC_WP_GPIO,
+ .cd_type = ESDHC_CD_GPIO,
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init pcm043_init(void)
+{
+ imx35_soc_init();
+
+ mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads));
+
+ imx35_add_fec(NULL);
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ imx35_add_imx2_wdt();
+
+ 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();
+ 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();
+ imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);
+}
+
+static void __init pcm043_timer_init(void)
+{
+ mx35_clocks_init();
+}
+
+MACHINE_START(PCM043, "Phytec Phycore pcm043")
+ /* Maintainer: Pengutronix */
+ .atag_offset = 0x100,
+ .map_io = mx35_map_io,
+ .init_early = imx35_init_early,
+ .init_irq = mx35_init_irq,
+ .init_time = pcm043_timer_init,
+ .init_machine = pcm043_init,
+ .restart = mxc_restart,
+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 000000000..a213e7b9c
--- /dev/null
+++ b/arch/arm/mach-imx/mach-qong.c
@@ -0,0 +1,272 @@
+/*
+ * 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 <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 "common.h"
+#include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.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
+
+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,
+ }, {
+ /* irq number is run-time assigned */
+ .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;
+
+ dnet_resources[1].start =
+ gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1));
+ dnet_resources[1].end =
+ gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1));
+ 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 */
+ __raw_writel(0x00004f00, MX31_IO_ADDRESS(MX31_WEIM_CSCRxU(3)));
+ __raw_writel(0x20013b31, MX31_IO_ADDRESS(MX31_WEIM_CSCRxL(3)));
+ __raw_writel(0x00020800, MX31_IO_ADDRESS(MX31_WEIM_CSCRxA(3)));
+
+ 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)
+{
+ imx31_soc_init();
+
+ mxc_init_imx_uart();
+ qong_init_nor_mtd();
+ qong_init_fpga();
+ imx31_add_imx2_wdt();
+}
+
+static void __init qong_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+MACHINE_START(QONG, "Dave/DENX QongEVB-LITE")
+ /* Maintainer: DENX Software Engineering GmbH */
+ .atag_offset = 0x100,
+ .map_io = mx31_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .init_time = qong_timer_init,
+ .init_machine = qong_init,
+ .restart = mxc_restart,
+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 000000000..1f6bc3f7a
--- /dev/null
+++ b/arch/arm/mach-imx/mach-scb9328.c
@@ -0,0 +1,143 @@
+/*
+ * 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 <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "common.h"
+#include "devices-imx1.h"
+#include "hardware.h"
+#include "iomux-mx1.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 */
+ }, {
+ /* irq number is run-time assigned */
+ .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 const struct imxuart_platform_data uart_pdata __initconst = {
+ .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_soc_init();
+
+ mxc_gpio_setup_multiple_pins(mxc_uart1_pins,
+ ARRAY_SIZE(mxc_uart1_pins), "UART1");
+
+ imx1_add_imx_uart0(&uart_pdata);
+
+ printk(KERN_INFO"Scb9328: Adding devices\n");
+ dm9000x_resources[2].start = gpio_to_irq(IMX_GPIO_NR(3, 3));
+ dm9000x_resources[2].end = gpio_to_irq(IMX_GPIO_NR(3, 3));
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init scb9328_timer_init(void)
+{
+ mx1_clocks_init(32000);
+}
+
+MACHINE_START(SCB9328, "Synertronixx scb9328")
+ /* Sascha Hauer */
+ .atag_offset = 100,
+ .map_io = mx1_map_io,
+ .init_early = imx1_init_early,
+ .init_irq = mx1_init_irq,
+ .init_time = scb9328_timer_init,
+ .init_machine = scb9328_init,
+ .restart = mxc_restart,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-vf610.c b/arch/arm/mach-imx/mach-vf610.c
new file mode 100644
index 000000000..2e7c75b66
--- /dev/null
+++ b/arch/arm/mach-imx/mach-vf610.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2012-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.
+ */
+
+#include <linux/of_platform.h>
+#include <linux/irqchip.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware/cache-l2x0.h>
+
+static const char * const vf610_dt_compat[] __initconst = {
+ "fsl,vf500",
+ "fsl,vf510",
+ "fsl,vf600",
+ "fsl,vf610",
+ NULL,
+};
+
+DT_MACHINE_START(VYBRID_VF610, "Freescale Vybrid VF5xx/VF6xx (Device Tree)")
+ .l2c_aux_val = 0,
+ .l2c_aux_mask = ~0,
+ .dt_compat = vf610_dt_compat,
+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 000000000..27a8f7e3e
--- /dev/null
+++ b/arch/arm/mach-imx/mach-vpr200.c
@@ -0,0 +1,317 @@
+/*
+ * 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 <linux/i2c.h>
+#include <linux/platform_data/at24.h>
+#include <linux/mfd/mc13xxx.h>
+
+#include "common.h"
+#include "devices-imx35.h"
+#include "ehci.h"
+#include "hardware.h"
+#include "iomux-mx35.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 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 number is run-time assigned */
+ }
+};
+
+static const iomux_v3_cfg_t vpr200_pads[] __initconst = {
+ /* 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)
+{
+ imx35_soc_init();
+
+ mxc_iomux_v3_setup_multiple_pads(vpr200_pads, ARRAY_SIZE(vpr200_pads));
+
+ imx35_add_fec(NULL);
+ imx35_add_imx2_wdt();
+ 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();
+ 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);
+
+ vpr200_i2c_devices[1].irq = gpio_to_irq(GPIO_PMIC_INT);
+ 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();
+}
+
+MACHINE_START(VPR200, "VPR200")
+ /* Maintainer: Creative Product Design */
+ .map_io = mx35_map_io,
+ .init_early = imx35_init_early,
+ .init_irq = mx35_init_irq,
+ .init_time = vpr200_timer_init,
+ .init_machine = vpr200_board_init,
+ .restart = mxc_restart,
+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 000000000..e065fedb3
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx1.c
@@ -0,0 +1,67 @@
+/*
+ * 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 <linux/pinctrl/machine.h>
+
+#include <asm/mach/map.h>
+
+#include "common.h"
+#include "devices/devices-common.h"
+#include "hardware.h"
+#include "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);
+ imx_iomuxv1_init(MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR),
+ MX1_NUM_GPIO_PORT);
+}
+
+void __init mx1_init_irq(void)
+{
+ mxc_init_irq(MX1_IO_ADDRESS(MX1_AVIC_BASE_ADDR));
+}
+
+void __init imx1_soc_init(void)
+{
+ mxc_arch_reset_init(MX1_IO_ADDRESS(MX1_WDT_BASE_ADDR));
+ mxc_device_init();
+
+ mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256,
+ MX1_GPIO_INT_PORTA, 0);
+ mxc_register_gpio("imx1-gpio", 1, MX1_GPIO2_BASE_ADDR, SZ_256,
+ MX1_GPIO_INT_PORTB, 0);
+ mxc_register_gpio("imx1-gpio", 2, MX1_GPIO3_BASE_ADDR, SZ_256,
+ MX1_GPIO_INT_PORTC, 0);
+ mxc_register_gpio("imx1-gpio", 3, MX1_GPIO4_BASE_ADDR, SZ_256,
+ MX1_GPIO_INT_PORTD, 0);
+ imx_add_imx_dma("imx1-dma", MX1_DMA_BASE_ADDR,
+ MX1_DMA_INT, MX1_DMA_ERR);
+ pinctrl_provide_dummies();
+}
diff --git a/arch/arm/mach-imx/mm-imx21.c b/arch/arm/mach-imx/mm-imx21.c
new file mode 100644
index 000000000..2e91ab2ca
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx21.c
@@ -0,0 +1,99 @@
+/*
+ * 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 <linux/pinctrl/machine.h>
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+#include "devices/devices-common.h"
+#include "hardware.h"
+#include "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);
+ imx_iomuxv1_init(MX21_IO_ADDRESS(MX21_GPIO_BASE_ADDR),
+ MX21_NUM_GPIO_PORT);
+}
+
+void __init mx21_init_irq(void)
+{
+ mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR));
+}
+
+static const struct resource imx21_audmux_res[] __initconst = {
+ DEFINE_RES_MEM(MX21_AUDMUX_BASE_ADDR, SZ_4K),
+};
+
+void __init imx21_soc_init(void)
+{
+ mxc_arch_reset_init(MX21_IO_ADDRESS(MX21_WDOG_BASE_ADDR));
+ mxc_device_init();
+
+ mxc_register_gpio("imx21-gpio", 0, MX21_GPIO1_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
+ mxc_register_gpio("imx21-gpio", 1, MX21_GPIO2_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
+ mxc_register_gpio("imx21-gpio", 2, MX21_GPIO3_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
+ mxc_register_gpio("imx21-gpio", 3, MX21_GPIO4_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
+ mxc_register_gpio("imx21-gpio", 4, MX21_GPIO5_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
+ mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
+
+ pinctrl_provide_dummies();
+ imx_add_imx_dma("imx21-dma", MX21_DMA_BASE_ADDR,
+ MX21_INT_DMACH0, 0); /* No ERR irq */
+ platform_device_register_simple("imx21-audmux", 0, imx21_audmux_res,
+ ARRAY_SIZE(imx21_audmux_res));
+}
diff --git a/arch/arm/mach-imx/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c
new file mode 100644
index 000000000..7d82a5a5b
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx27.c
@@ -0,0 +1,101 @@
+/*
+ * 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 <linux/pinctrl/machine.h>
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+#include "devices/devices-common.h"
+#include "hardware.h"
+#include "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);
+ imx_iomuxv1_init(MX27_IO_ADDRESS(MX27_GPIO_BASE_ADDR),
+ MX27_NUM_GPIO_PORT);
+}
+
+void __init mx27_init_irq(void)
+{
+ mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR));
+}
+
+static const struct resource imx27_audmux_res[] __initconst = {
+ DEFINE_RES_MEM(MX27_AUDMUX_BASE_ADDR, SZ_4K),
+};
+
+void __init imx27_soc_init(void)
+{
+ mxc_arch_reset_init(MX27_IO_ADDRESS(MX27_WDOG_BASE_ADDR));
+ mxc_device_init();
+
+ /* i.mx27 has the i.mx21 type gpio */
+ mxc_register_gpio("imx21-gpio", 0, MX27_GPIO1_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
+ mxc_register_gpio("imx21-gpio", 1, MX27_GPIO2_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
+ mxc_register_gpio("imx21-gpio", 2, MX27_GPIO3_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
+ mxc_register_gpio("imx21-gpio", 3, MX27_GPIO4_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
+ mxc_register_gpio("imx21-gpio", 4, MX27_GPIO5_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
+ mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
+
+ pinctrl_provide_dummies();
+ imx_add_imx_dma("imx27-dma", MX27_DMA_BASE_ADDR,
+ MX27_INT_DMACH0, 0); /* No ERR irq */
+ /* imx27 has the imx21 type audmux */
+ platform_device_register_simple("imx21-audmux", 0, imx27_audmux_res,
+ ARRAY_SIZE(imx27_audmux_res));
+}
diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c
new file mode 100644
index 000000000..0256e17d2
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx3.c
@@ -0,0 +1,298 @@
+/*
+ * 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 <linux/pinctrl/machine.h>
+
+#include <asm/pgtable.h>
+#include <asm/system_misc.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+#include "crmregs-imx3.h"
+#include "devices/devices-common.h"
+#include "hardware.h"
+#include "iomux-v3.h"
+
+void __iomem *mx3_ccm_base;
+
+static void imx3_idle(void)
+{
+ unsigned long reg = 0;
+
+ mx3_cpu_lp_set(MX3_WAIT);
+
+ __asm__ __volatile__(
+ /* disable I and D cache */
+ "mrc p15, 0, %0, c1, c0, 0\n"
+ "bic %0, %0, #0x00001000\n"
+ "bic %0, %0, #0x00000004\n"
+ "mcr p15, 0, %0, c1, c0, 0\n"
+ /* invalidate I cache */
+ "mov %0, #0\n"
+ "mcr p15, 0, %0, c7, c5, 0\n"
+ /* clear and invalidate D cache */
+ "mov %0, #0\n"
+ "mcr p15, 0, %0, c7, c14, 0\n"
+ /* WFI */
+ "mov %0, #0\n"
+ "mcr p15, 0, %0, c7, c0, 4\n"
+ "nop\n" "nop\n" "nop\n" "nop\n"
+ "nop\n" "nop\n" "nop\n"
+ /* enable I and D cache */
+ "mrc p15, 0, %0, c1, c0, 0\n"
+ "orr %0, %0, #0x00001000\n"
+ "orr %0, %0, #0x00000004\n"
+ "mcr p15, 0, %0, c1, c0, 0\n"
+ : "=r" (reg));
+}
+
+static void __iomem *imx3_ioremap_caller(phys_addr_t phys_addr, size_t size,
+ unsigned int mtype, void *caller)
+{
+ if (mtype == MT_DEVICE) {
+ /*
+ * 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_caller(phys_addr, size, mtype, caller);
+}
+
+static void __init imx3_init_l2x0(void)
+{
+#ifdef CONFIG_CACHE_L2X0
+ void __iomem *l2x0_base;
+ void __iomem *clkctl_base;
+
+/*
+ * First of all, we must repair broken chip settings. There are some
+ * i.MX35 CPUs in the wild, comming with bogus L2 cache settings. These
+ * misconfigured CPUs will run amok immediately when the L2 cache gets enabled.
+ * Workaraound is to setup the correct register setting prior enabling the
+ * L2 cache. This should not hurt already working CPUs, as they are using the
+ * same value.
+ */
+#define L2_MEM_VAL 0x10
+
+ clkctl_base = ioremap(MX35_CLKCTL_BASE_ADDR, 4096);
+ if (clkctl_base != NULL) {
+ writel(0x00000515, clkctl_base + L2_MEM_VAL);
+ iounmap(clkctl_base);
+ } else {
+ pr_err("L2 cache: Cannot fix timing. Trying to continue without\n");
+ }
+
+ l2x0_base = ioremap(MX3x_L2CC_BASE_ADDR, 4096);
+ if (!l2x0_base) {
+ printk(KERN_ERR "remapping L2 cache area failed\n");
+ return;
+ }
+
+ l2x0_init(l2x0_base, 0x00030024, 0x00000000);
+#endif
+}
+
+#ifdef CONFIG_SOC_IMX31
+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);
+ arch_ioremap_caller = imx3_ioremap_caller;
+ arm_pm_idle = imx3_idle;
+ mx3_ccm_base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR);
+}
+
+void __init mx31_init_irq(void)
+{
+ mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR));
+}
+
+static struct sdma_script_start_addrs imx31_to1_sdma_script __initdata = {
+ .per_2_per_addr = 1677,
+};
+
+static struct sdma_script_start_addrs imx31_to2_sdma_script __initdata = {
+ .ap_2_ap_addr = 423,
+ .ap_2_bp_addr = 829,
+ .bp_2_ap_addr = 1029,
+};
+
+static struct sdma_platform_data imx31_sdma_pdata __initdata = {
+ .fw_name = "/*(DEBLOBBED)*/",
+ .script_addrs = &imx31_to2_sdma_script,
+};
+
+static const struct resource imx31_audmux_res[] __initconst = {
+ DEFINE_RES_MEM(MX31_AUDMUX_BASE_ADDR, SZ_16K),
+};
+
+void __init imx31_soc_init(void)
+{
+ int to_version = mx31_revision() >> 4;
+
+ imx3_init_l2x0();
+
+ mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
+ mxc_device_init();
+
+ mxc_register_gpio("imx31-gpio", 0, MX31_GPIO1_BASE_ADDR, SZ_16K, MX31_INT_GPIO1, 0);
+ mxc_register_gpio("imx31-gpio", 1, MX31_GPIO2_BASE_ADDR, SZ_16K, MX31_INT_GPIO2, 0);
+ mxc_register_gpio("imx31-gpio", 2, MX31_GPIO3_BASE_ADDR, SZ_16K, MX31_INT_GPIO3, 0);
+
+ pinctrl_provide_dummies();
+
+ if (to_version == 1) {
+ strncpy(imx31_sdma_pdata.fw_name, "/*(DEBLOBBED)*/",
+ strlen(imx31_sdma_pdata.fw_name));
+ imx31_sdma_pdata.script_addrs = &imx31_to1_sdma_script;
+ }
+
+ imx_add_imx_sdma("imx31-sdma", MX31_SDMA_BASE_ADDR, MX31_INT_SDMA, &imx31_sdma_pdata);
+
+ imx_set_aips(MX31_IO_ADDRESS(MX31_AIPS1_BASE_ADDR));
+ imx_set_aips(MX31_IO_ADDRESS(MX31_AIPS2_BASE_ADDR));
+
+ platform_device_register_simple("imx31-audmux", 0, imx31_audmux_res,
+ ARRAY_SIZE(imx31_audmux_res));
+}
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+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));
+ arm_pm_idle = imx3_idle;
+ arch_ioremap_caller = imx3_ioremap_caller;
+ mx3_ccm_base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR);
+}
+
+void __init mx35_init_irq(void)
+{
+ mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR));
+}
+
+static struct sdma_script_start_addrs imx35_to1_sdma_script __initdata = {
+ .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 imx35_to2_sdma_script __initdata = {
+ .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,
+};
+
+static struct sdma_platform_data imx35_sdma_pdata __initdata = {
+ .fw_name = "/*(DEBLOBBED)*/",
+ .script_addrs = &imx35_to2_sdma_script,
+};
+
+static const struct resource imx35_audmux_res[] __initconst = {
+ DEFINE_RES_MEM(MX35_AUDMUX_BASE_ADDR, SZ_16K),
+};
+
+void __init imx35_soc_init(void)
+{
+ int to_version = mx35_revision() >> 4;
+
+ imx3_init_l2x0();
+
+ mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
+ mxc_device_init();
+
+ mxc_register_gpio("imx35-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
+ mxc_register_gpio("imx35-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
+ mxc_register_gpio("imx35-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
+
+ pinctrl_provide_dummies();
+ if (to_version == 1) {
+ strncpy(imx35_sdma_pdata.fw_name, "/*(DEBLOBBED)*/",
+ strlen(imx35_sdma_pdata.fw_name));
+ imx35_sdma_pdata.script_addrs = &imx35_to1_sdma_script;
+ }
+
+ imx_add_imx_sdma("imx35-sdma", MX35_SDMA_BASE_ADDR, MX35_INT_SDMA, &imx35_sdma_pdata);
+
+ /* Setup AIPS registers */
+ imx_set_aips(MX35_IO_ADDRESS(MX35_AIPS1_BASE_ADDR));
+ imx_set_aips(MX35_IO_ADDRESS(MX35_AIPS2_BASE_ADDR));
+
+ /* i.mx35 has the i.mx31 type audmux */
+ platform_device_register_simple("imx31-audmux", 0, imx35_audmux_res,
+ ARRAY_SIZE(imx35_audmux_res));
+}
+#endif /* ifdef CONFIG_SOC_IMX35 */
diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
new file mode 100644
index 000000000..0411f0664
--- /dev/null
+++ b/arch/arm/mach-imx/mmdc.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+
+#define MMDC_MAPSR 0x404
+#define BP_MMDC_MAPSR_PSD 0
+#define BP_MMDC_MAPSR_PSS 4
+
+#define MMDC_MDMISC 0x18
+#define BM_MMDC_MDMISC_DDR_TYPE 0x18
+#define BP_MMDC_MDMISC_DDR_TYPE 0x3
+
+static int ddr_type;
+
+static int imx_mmdc_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ void __iomem *mmdc_base, *reg;
+ u32 val;
+ int timeout = 0x400;
+
+ mmdc_base = of_iomap(np, 0);
+ WARN_ON(!mmdc_base);
+
+ reg = mmdc_base + MMDC_MDMISC;
+ /* Get ddr type */
+ val = readl_relaxed(reg);
+ ddr_type = (val & BM_MMDC_MDMISC_DDR_TYPE) >>
+ BP_MMDC_MDMISC_DDR_TYPE;
+
+ reg = mmdc_base + MMDC_MAPSR;
+
+ /* Enable automatic power saving */
+ val = readl_relaxed(reg);
+ val &= ~(1 << BP_MMDC_MAPSR_PSD);
+ writel_relaxed(val, reg);
+
+ /* Ensure it's successfully enabled */
+ while (!(readl_relaxed(reg) & 1 << BP_MMDC_MAPSR_PSS) && --timeout)
+ cpu_relax();
+
+ if (unlikely(!timeout)) {
+ pr_warn("%s: failed to enable automatic power saving\n",
+ __func__);
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+int imx_mmdc_get_ddr_type(void)
+{
+ return ddr_type;
+}
+
+static const struct of_device_id imx_mmdc_dt_ids[] = {
+ { .compatible = "fsl,imx6q-mmdc", },
+ { /* sentinel */ }
+};
+
+static struct platform_driver imx_mmdc_driver = {
+ .driver = {
+ .name = "imx-mmdc",
+ .of_match_table = imx_mmdc_dt_ids,
+ },
+ .probe = imx_mmdc_probe,
+};
+
+static int __init imx_mmdc_init(void)
+{
+ return platform_driver_register(&imx_mmdc_driver);
+}
+postcore_initcall(imx_mmdc_init);
diff --git a/arch/arm/mach-imx/mx1.h b/arch/arm/mach-imx/mx1.h
new file mode 100644
index 000000000..45bd31cc3
--- /dev/null
+++ b/arch/arm/mach-imx/mx1.h
@@ -0,0 +1,172 @@
+/*
+ * 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__
+
+/*
+ * 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 */
+#include <asm/irq.h>
+#define MX1_INT_SOFTINT (NR_IRQS_LEGACY + 0)
+#define MX1_INT_CSI (NR_IRQS_LEGACY + 6)
+#define MX1_DSPA_MAC_INT (NR_IRQS_LEGACY + 7)
+#define MX1_DSPA_INT (NR_IRQS_LEGACY + 8)
+#define MX1_COMP_INT (NR_IRQS_LEGACY + 9)
+#define MX1_MSHC_XINT (NR_IRQS_LEGACY + 10)
+#define MX1_GPIO_INT_PORTA (NR_IRQS_LEGACY + 11)
+#define MX1_GPIO_INT_PORTB (NR_IRQS_LEGACY + 12)
+#define MX1_GPIO_INT_PORTC (NR_IRQS_LEGACY + 13)
+#define MX1_INT_LCDC (NR_IRQS_LEGACY + 14)
+#define MX1_SIM_INT (NR_IRQS_LEGACY + 15)
+#define MX1_SIM_DATA_INT (NR_IRQS_LEGACY + 16)
+#define MX1_RTC_INT (NR_IRQS_LEGACY + 17)
+#define MX1_RTC_SAMINT (NR_IRQS_LEGACY + 18)
+#define MX1_INT_UART2PFERR (NR_IRQS_LEGACY + 19)
+#define MX1_INT_UART2RTS (NR_IRQS_LEGACY + 20)
+#define MX1_INT_UART2DTR (NR_IRQS_LEGACY + 21)
+#define MX1_INT_UART2UARTC (NR_IRQS_LEGACY + 22)
+#define MX1_INT_UART2TX (NR_IRQS_LEGACY + 23)
+#define MX1_INT_UART2RX (NR_IRQS_LEGACY + 24)
+#define MX1_INT_UART1PFERR (NR_IRQS_LEGACY + 25)
+#define MX1_INT_UART1RTS (NR_IRQS_LEGACY + 26)
+#define MX1_INT_UART1DTR (NR_IRQS_LEGACY + 27)
+#define MX1_INT_UART1UARTC (NR_IRQS_LEGACY + 28)
+#define MX1_INT_UART1TX (NR_IRQS_LEGACY + 29)
+#define MX1_INT_UART1RX (NR_IRQS_LEGACY + 30)
+#define MX1_VOICE_DAC_INT (NR_IRQS_LEGACY + 31)
+#define MX1_VOICE_ADC_INT (NR_IRQS_LEGACY + 32)
+#define MX1_PEN_DATA_INT (NR_IRQS_LEGACY + 33)
+#define MX1_PWM_INT (NR_IRQS_LEGACY + 34)
+#define MX1_SDHC_INT (NR_IRQS_LEGACY + 35)
+#define MX1_INT_I2C (NR_IRQS_LEGACY + 39)
+#define MX1_INT_CSPI2 (NR_IRQS_LEGACY + 40)
+#define MX1_INT_CSPI1 (NR_IRQS_LEGACY + 41)
+#define MX1_SSI_TX_INT (NR_IRQS_LEGACY + 42)
+#define MX1_SSI_TX_ERR_INT (NR_IRQS_LEGACY + 43)
+#define MX1_SSI_RX_INT (NR_IRQS_LEGACY + 44)
+#define MX1_SSI_RX_ERR_INT (NR_IRQS_LEGACY + 45)
+#define MX1_TOUCH_INT (NR_IRQS_LEGACY + 46)
+#define MX1_INT_USBD0 (NR_IRQS_LEGACY + 47)
+#define MX1_INT_USBD1 (NR_IRQS_LEGACY + 48)
+#define MX1_INT_USBD2 (NR_IRQS_LEGACY + 49)
+#define MX1_INT_USBD3 (NR_IRQS_LEGACY + 50)
+#define MX1_INT_USBD4 (NR_IRQS_LEGACY + 51)
+#define MX1_INT_USBD5 (NR_IRQS_LEGACY + 52)
+#define MX1_INT_USBD6 (NR_IRQS_LEGACY + 53)
+#define MX1_BTSYS_INT (NR_IRQS_LEGACY + 55)
+#define MX1_BTTIM_INT (NR_IRQS_LEGACY + 56)
+#define MX1_BTWUI_INT (NR_IRQS_LEGACY + 57)
+#define MX1_TIM2_INT (NR_IRQS_LEGACY + 58)
+#define MX1_TIM1_INT (NR_IRQS_LEGACY + 59)
+#define MX1_DMA_ERR (NR_IRQS_LEGACY + 60)
+#define MX1_DMA_INT (NR_IRQS_LEGACY + 61)
+#define MX1_GPIO_INT_PORTD (NR_IRQS_LEGACY + 62)
+#define MX1_WDT_INT (NR_IRQS_LEGACY + 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/mach-imx/mx21.h b/arch/arm/mach-imx/mx21.h
new file mode 100644
index 000000000..468738aa9
--- /dev/null
+++ b/arch/arm/mach-imx/mx21.h
@@ -0,0 +1,189 @@
+/*
+ * 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 */
+#include <asm/irq.h>
+#define MX21_INT_CSPI3 (NR_IRQS_LEGACY + 6)
+#define MX21_INT_GPIO (NR_IRQS_LEGACY + 8)
+#define MX21_INT_FIRI (NR_IRQS_LEGACY + 9)
+#define MX21_INT_SDHC2 (NR_IRQS_LEGACY + 10)
+#define MX21_INT_SDHC1 (NR_IRQS_LEGACY + 11)
+#define MX21_INT_I2C (NR_IRQS_LEGACY + 12)
+#define MX21_INT_SSI2 (NR_IRQS_LEGACY + 13)
+#define MX21_INT_SSI1 (NR_IRQS_LEGACY + 14)
+#define MX21_INT_CSPI2 (NR_IRQS_LEGACY + 15)
+#define MX21_INT_CSPI1 (NR_IRQS_LEGACY + 16)
+#define MX21_INT_UART4 (NR_IRQS_LEGACY + 17)
+#define MX21_INT_UART3 (NR_IRQS_LEGACY + 18)
+#define MX21_INT_UART2 (NR_IRQS_LEGACY + 19)
+#define MX21_INT_UART1 (NR_IRQS_LEGACY + 20)
+#define MX21_INT_KPP (NR_IRQS_LEGACY + 21)
+#define MX21_INT_RTC (NR_IRQS_LEGACY + 22)
+#define MX21_INT_PWM (NR_IRQS_LEGACY + 23)
+#define MX21_INT_GPT3 (NR_IRQS_LEGACY + 24)
+#define MX21_INT_GPT2 (NR_IRQS_LEGACY + 25)
+#define MX21_INT_GPT1 (NR_IRQS_LEGACY + 26)
+#define MX21_INT_WDOG (NR_IRQS_LEGACY + 27)
+#define MX21_INT_PCMCIA (NR_IRQS_LEGACY + 28)
+#define MX21_INT_NFC (NR_IRQS_LEGACY + 29)
+#define MX21_INT_BMI (NR_IRQS_LEGACY + 30)
+#define MX21_INT_CSI (NR_IRQS_LEGACY + 31)
+#define MX21_INT_DMACH0 (NR_IRQS_LEGACY + 32)
+#define MX21_INT_DMACH1 (NR_IRQS_LEGACY + 33)
+#define MX21_INT_DMACH2 (NR_IRQS_LEGACY + 34)
+#define MX21_INT_DMACH3 (NR_IRQS_LEGACY + 35)
+#define MX21_INT_DMACH4 (NR_IRQS_LEGACY + 36)
+#define MX21_INT_DMACH5 (NR_IRQS_LEGACY + 37)
+#define MX21_INT_DMACH6 (NR_IRQS_LEGACY + 38)
+#define MX21_INT_DMACH7 (NR_IRQS_LEGACY + 39)
+#define MX21_INT_DMACH8 (NR_IRQS_LEGACY + 40)
+#define MX21_INT_DMACH9 (NR_IRQS_LEGACY + 41)
+#define MX21_INT_DMACH10 (NR_IRQS_LEGACY + 42)
+#define MX21_INT_DMACH11 (NR_IRQS_LEGACY + 43)
+#define MX21_INT_DMACH12 (NR_IRQS_LEGACY + 44)
+#define MX21_INT_DMACH13 (NR_IRQS_LEGACY + 45)
+#define MX21_INT_DMACH14 (NR_IRQS_LEGACY + 46)
+#define MX21_INT_DMACH15 (NR_IRQS_LEGACY + 47)
+#define MX21_INT_EMMAENC (NR_IRQS_LEGACY + 49)
+#define MX21_INT_EMMADEC (NR_IRQS_LEGACY + 50)
+#define MX21_INT_EMMAPRP (NR_IRQS_LEGACY + 51)
+#define MX21_INT_EMMAPP (NR_IRQS_LEGACY + 52)
+#define MX21_INT_USBWKUP (NR_IRQS_LEGACY + 53)
+#define MX21_INT_USBDMA (NR_IRQS_LEGACY + 54)
+#define MX21_INT_USBHOST (NR_IRQS_LEGACY + 55)
+#define MX21_INT_USBFUNC (NR_IRQS_LEGACY + 56)
+#define MX21_INT_USBMNP (NR_IRQS_LEGACY + 57)
+#define MX21_INT_USBCTRL (NR_IRQS_LEGACY + 58)
+#define MX21_INT_SLCDC (NR_IRQS_LEGACY + 60)
+#define MX21_INT_LCDC (NR_IRQS_LEGACY + 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/mach-imx/mx27.h b/arch/arm/mach-imx/mx27.h
new file mode 100644
index 000000000..8a65f192e
--- /dev/null
+++ b/arch/arm/mach-imx/mx27.h
@@ -0,0 +1,238 @@
+/*
+ * 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__
+
+#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))
+
+/* fixed interrupt numbers */
+#include <asm/irq.h>
+#define MX27_INT_I2C2 (NR_IRQS_LEGACY + 1)
+#define MX27_INT_GPT6 (NR_IRQS_LEGACY + 2)
+#define MX27_INT_GPT5 (NR_IRQS_LEGACY + 3)
+#define MX27_INT_GPT4 (NR_IRQS_LEGACY + 4)
+#define MX27_INT_RTIC (NR_IRQS_LEGACY + 5)
+#define MX27_INT_CSPI3 (NR_IRQS_LEGACY + 6)
+#define MX27_INT_MSHC (NR_IRQS_LEGACY + 7)
+#define MX27_INT_GPIO (NR_IRQS_LEGACY + 8)
+#define MX27_INT_SDHC3 (NR_IRQS_LEGACY + 9)
+#define MX27_INT_SDHC2 (NR_IRQS_LEGACY + 10)
+#define MX27_INT_SDHC1 (NR_IRQS_LEGACY + 11)
+#define MX27_INT_I2C1 (NR_IRQS_LEGACY + 12)
+#define MX27_INT_SSI2 (NR_IRQS_LEGACY + 13)
+#define MX27_INT_SSI1 (NR_IRQS_LEGACY + 14)
+#define MX27_INT_CSPI2 (NR_IRQS_LEGACY + 15)
+#define MX27_INT_CSPI1 (NR_IRQS_LEGACY + 16)
+#define MX27_INT_UART4 (NR_IRQS_LEGACY + 17)
+#define MX27_INT_UART3 (NR_IRQS_LEGACY + 18)
+#define MX27_INT_UART2 (NR_IRQS_LEGACY + 19)
+#define MX27_INT_UART1 (NR_IRQS_LEGACY + 20)
+#define MX27_INT_KPP (NR_IRQS_LEGACY + 21)
+#define MX27_INT_RTC (NR_IRQS_LEGACY + 22)
+#define MX27_INT_PWM (NR_IRQS_LEGACY + 23)
+#define MX27_INT_GPT3 (NR_IRQS_LEGACY + 24)
+#define MX27_INT_GPT2 (NR_IRQS_LEGACY + 25)
+#define MX27_INT_GPT1 (NR_IRQS_LEGACY + 26)
+#define MX27_INT_WDOG (NR_IRQS_LEGACY + 27)
+#define MX27_INT_PCMCIA (NR_IRQS_LEGACY + 28)
+#define MX27_INT_NFC (NR_IRQS_LEGACY + 29)
+#define MX27_INT_ATA (NR_IRQS_LEGACY + 30)
+#define MX27_INT_CSI (NR_IRQS_LEGACY + 31)
+#define MX27_INT_DMACH0 (NR_IRQS_LEGACY + 32)
+#define MX27_INT_DMACH1 (NR_IRQS_LEGACY + 33)
+#define MX27_INT_DMACH2 (NR_IRQS_LEGACY + 34)
+#define MX27_INT_DMACH3 (NR_IRQS_LEGACY + 35)
+#define MX27_INT_DMACH4 (NR_IRQS_LEGACY + 36)
+#define MX27_INT_DMACH5 (NR_IRQS_LEGACY + 37)
+#define MX27_INT_DMACH6 (NR_IRQS_LEGACY + 38)
+#define MX27_INT_DMACH7 (NR_IRQS_LEGACY + 39)
+#define MX27_INT_DMACH8 (NR_IRQS_LEGACY + 40)
+#define MX27_INT_DMACH9 (NR_IRQS_LEGACY + 41)
+#define MX27_INT_DMACH10 (NR_IRQS_LEGACY + 42)
+#define MX27_INT_DMACH11 (NR_IRQS_LEGACY + 43)
+#define MX27_INT_DMACH12 (NR_IRQS_LEGACY + 44)
+#define MX27_INT_DMACH13 (NR_IRQS_LEGACY + 45)
+#define MX27_INT_DMACH14 (NR_IRQS_LEGACY + 46)
+#define MX27_INT_DMACH15 (NR_IRQS_LEGACY + 47)
+#define MX27_INT_UART6 (NR_IRQS_LEGACY + 48)
+#define MX27_INT_UART5 (NR_IRQS_LEGACY + 49)
+#define MX27_INT_FEC (NR_IRQS_LEGACY + 50)
+#define MX27_INT_EMMAPRP (NR_IRQS_LEGACY + 51)
+#define MX27_INT_EMMAPP (NR_IRQS_LEGACY + 52)
+#define MX27_INT_VPU (NR_IRQS_LEGACY + 53)
+#define MX27_INT_USB_HS1 (NR_IRQS_LEGACY + 54)
+#define MX27_INT_USB_HS2 (NR_IRQS_LEGACY + 55)
+#define MX27_INT_USB_OTG (NR_IRQS_LEGACY + 56)
+#define MX27_INT_SCC_SMN (NR_IRQS_LEGACY + 57)
+#define MX27_INT_SCC_SCM (NR_IRQS_LEGACY + 58)
+#define MX27_INT_SAHARA (NR_IRQS_LEGACY + 59)
+#define MX27_INT_SLCDC (NR_IRQS_LEGACY + 60)
+#define MX27_INT_LCDC (NR_IRQS_LEGACY + 61)
+#define MX27_INT_IIM (NR_IRQS_LEGACY + 62)
+#define MX27_INT_CCM (NR_IRQS_LEGACY + 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/mach-imx/mx2x.h b/arch/arm/mach-imx/mx2x.h
new file mode 100644
index 000000000..11642f5b2
--- /dev/null
+++ b/arch/arm/mach-imx/mx2x.h
@@ -0,0 +1,145 @@
+/*
+ * 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 */
+#include <asm/irq.h>
+#define MX2x_INT_CSPI3 (NR_IRQS_LEGACY + 6)
+#define MX2x_INT_GPIO (NR_IRQS_LEGACY + 8)
+#define MX2x_INT_SDHC2 (NR_IRQS_LEGACY + 10)
+#define MX2x_INT_SDHC1 (NR_IRQS_LEGACY + 11)
+#define MX2x_INT_I2C (NR_IRQS_LEGACY + 12)
+#define MX2x_INT_SSI2 (NR_IRQS_LEGACY + 13)
+#define MX2x_INT_SSI1 (NR_IRQS_LEGACY + 14)
+#define MX2x_INT_CSPI2 (NR_IRQS_LEGACY + 15)
+#define MX2x_INT_CSPI1 (NR_IRQS_LEGACY + 16)
+#define MX2x_INT_UART4 (NR_IRQS_LEGACY + 17)
+#define MX2x_INT_UART3 (NR_IRQS_LEGACY + 18)
+#define MX2x_INT_UART2 (NR_IRQS_LEGACY + 19)
+#define MX2x_INT_UART1 (NR_IRQS_LEGACY + 20)
+#define MX2x_INT_KPP (NR_IRQS_LEGACY + 21)
+#define MX2x_INT_RTC (NR_IRQS_LEGACY + 22)
+#define MX2x_INT_PWM (NR_IRQS_LEGACY + 23)
+#define MX2x_INT_GPT3 (NR_IRQS_LEGACY + 24)
+#define MX2x_INT_GPT2 (NR_IRQS_LEGACY + 25)
+#define MX2x_INT_GPT1 (NR_IRQS_LEGACY + 26)
+#define MX2x_INT_WDOG (NR_IRQS_LEGACY + 27)
+#define MX2x_INT_PCMCIA (NR_IRQS_LEGACY + 28)
+#define MX2x_INT_NANDFC (NR_IRQS_LEGACY + 29)
+#define MX2x_INT_CSI (NR_IRQS_LEGACY + 31)
+#define MX2x_INT_DMACH0 (NR_IRQS_LEGACY + 32)
+#define MX2x_INT_DMACH1 (NR_IRQS_LEGACY + 33)
+#define MX2x_INT_DMACH2 (NR_IRQS_LEGACY + 34)
+#define MX2x_INT_DMACH3 (NR_IRQS_LEGACY + 35)
+#define MX2x_INT_DMACH4 (NR_IRQS_LEGACY + 36)
+#define MX2x_INT_DMACH5 (NR_IRQS_LEGACY + 37)
+#define MX2x_INT_DMACH6 (NR_IRQS_LEGACY + 38)
+#define MX2x_INT_DMACH7 (NR_IRQS_LEGACY + 39)
+#define MX2x_INT_DMACH8 (NR_IRQS_LEGACY + 40)
+#define MX2x_INT_DMACH9 (NR_IRQS_LEGACY + 41)
+#define MX2x_INT_DMACH10 (NR_IRQS_LEGACY + 42)
+#define MX2x_INT_DMACH11 (NR_IRQS_LEGACY + 43)
+#define MX2x_INT_DMACH12 (NR_IRQS_LEGACY + 44)
+#define MX2x_INT_DMACH13 (NR_IRQS_LEGACY + 45)
+#define MX2x_INT_DMACH14 (NR_IRQS_LEGACY + 46)
+#define MX2x_INT_DMACH15 (NR_IRQS_LEGACY + 47)
+#define MX2x_INT_EMMAPRP (NR_IRQS_LEGACY + 51)
+#define MX2x_INT_EMMAPP (NR_IRQS_LEGACY + 52)
+#define MX2x_INT_SLCDC (NR_IRQS_LEGACY + 60)
+#define MX2x_INT_LCDC (NR_IRQS_LEGACY + 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/mach-imx/mx31.h b/arch/arm/mach-imx/mx31.h
new file mode 100644
index 000000000..ee9b1f921
--- /dev/null
+++ b/arch/arm/mach-imx/mx31.h
@@ -0,0 +1,196 @@
+#ifndef __MACH_MX31_H__
+#define __MACH_MX31_H__
+
+/*
+ * 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 IOMEM(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 IOMEM(0xf6000000)
+#define MX31_CS4_SIZE SZ_32M
+
+#define MX31_CS5_BASE_ADDR 0xb6000000
+#define MX31_CS5_BASE_ADDR_VIRT IOMEM(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))
+
+/*
+ * Interrupt numbers
+ */
+#include <asm/irq.h>
+#define MX31_INT_I2C3 (NR_IRQS_LEGACY + 3)
+#define MX31_INT_I2C2 (NR_IRQS_LEGACY + 4)
+#define MX31_INT_MPEG4_ENCODER (NR_IRQS_LEGACY + 5)
+#define MX31_INT_RTIC (NR_IRQS_LEGACY + 6)
+#define MX31_INT_FIRI (NR_IRQS_LEGACY + 7)
+#define MX31_INT_SDHC2 (NR_IRQS_LEGACY + 8)
+#define MX31_INT_SDHC1 (NR_IRQS_LEGACY + 9)
+#define MX31_INT_I2C1 (NR_IRQS_LEGACY + 10)
+#define MX31_INT_SSI2 (NR_IRQS_LEGACY + 11)
+#define MX31_INT_SSI1 (NR_IRQS_LEGACY + 12)
+#define MX31_INT_CSPI2 (NR_IRQS_LEGACY + 13)
+#define MX31_INT_CSPI1 (NR_IRQS_LEGACY + 14)
+#define MX31_INT_ATA (NR_IRQS_LEGACY + 15)
+#define MX31_INT_MBX (NR_IRQS_LEGACY + 16)
+#define MX31_INT_CSPI3 (NR_IRQS_LEGACY + 17)
+#define MX31_INT_UART3 (NR_IRQS_LEGACY + 18)
+#define MX31_INT_IIM (NR_IRQS_LEGACY + 19)
+#define MX31_INT_SIM2 (NR_IRQS_LEGACY + 20)
+#define MX31_INT_SIM1 (NR_IRQS_LEGACY + 21)
+#define MX31_INT_RNGA (NR_IRQS_LEGACY + 22)
+#define MX31_INT_EVTMON (NR_IRQS_LEGACY + 23)
+#define MX31_INT_KPP (NR_IRQS_LEGACY + 24)
+#define MX31_INT_RTC (NR_IRQS_LEGACY + 25)
+#define MX31_INT_PWM (NR_IRQS_LEGACY + 26)
+#define MX31_INT_EPIT2 (NR_IRQS_LEGACY + 27)
+#define MX31_INT_EPIT1 (NR_IRQS_LEGACY + 28)
+#define MX31_INT_GPT (NR_IRQS_LEGACY + 29)
+#define MX31_INT_POWER_FAIL (NR_IRQS_LEGACY + 30)
+#define MX31_INT_CCM_DVFS (NR_IRQS_LEGACY + 31)
+#define MX31_INT_UART2 (NR_IRQS_LEGACY + 32)
+#define MX31_INT_NFC (NR_IRQS_LEGACY + 33)
+#define MX31_INT_SDMA (NR_IRQS_LEGACY + 34)
+#define MX31_INT_USB_HS1 (NR_IRQS_LEGACY + 35)
+#define MX31_INT_USB_HS2 (NR_IRQS_LEGACY + 36)
+#define MX31_INT_USB_OTG (NR_IRQS_LEGACY + 37)
+#define MX31_INT_MSHC1 (NR_IRQS_LEGACY + 39)
+#define MX31_INT_MSHC2 (NR_IRQS_LEGACY + 40)
+#define MX31_INT_IPU_ERR (NR_IRQS_LEGACY + 41)
+#define MX31_INT_IPU_SYN (NR_IRQS_LEGACY + 42)
+#define MX31_INT_UART1 (NR_IRQS_LEGACY + 45)
+#define MX31_INT_UART4 (NR_IRQS_LEGACY + 46)
+#define MX31_INT_UART5 (NR_IRQS_LEGACY + 47)
+#define MX31_INT_ECT (NR_IRQS_LEGACY + 48)
+#define MX31_INT_SCC_SCM (NR_IRQS_LEGACY + 49)
+#define MX31_INT_SCC_SMN (NR_IRQS_LEGACY + 50)
+#define MX31_INT_GPIO2 (NR_IRQS_LEGACY + 51)
+#define MX31_INT_GPIO1 (NR_IRQS_LEGACY + 52)
+#define MX31_INT_CCM (NR_IRQS_LEGACY + 53)
+#define MX31_INT_PCMCIA (NR_IRQS_LEGACY + 54)
+#define MX31_INT_WDOG (NR_IRQS_LEGACY + 55)
+#define MX31_INT_GPIO3 (NR_IRQS_LEGACY + 56)
+#define MX31_INT_EXT_POWER (NR_IRQS_LEGACY + 58)
+#define MX31_INT_EXT_TEMPER (NR_IRQS_LEGACY + 59)
+#define MX31_INT_EXT_SENSOR60 (NR_IRQS_LEGACY + 60)
+#define MX31_INT_EXT_SENSOR61 (NR_IRQS_LEGACY + 61)
+#define MX31_INT_EXT_WDOG (NR_IRQS_LEGACY + 62)
+#define MX31_INT_EXT_TV (NR_IRQS_LEGACY + 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/mach-imx/mx31lilly-db.c b/arch/arm/mach-imx/mx31lilly-db.c
new file mode 100644
index 000000000..649fe49ce
--- /dev/null
+++ b/arch/arm/mach-imx/mx31lilly-db.c
@@ -0,0 +1,211 @@
+/*
+ * 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 "board-mx31lilly.h"
+#include "common.h"
+#include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.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(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)),
+ detect_irq, 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(gpio_to_irq(IOMUX_TO_GPIO(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 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();
+ 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 000000000..5a160b7e4
--- /dev/null
+++ b/arch/arm/mach-imx/mx31lite-db.c
@@ -0,0 +1,196 @@
+/*
+ * 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 "board-mx31lite.h"
+#include "common.h"
+#include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.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(gpio_to_irq(IOMUX_TO_GPIO(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(gpio_to_irq(IOMUX_TO_GPIO(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 const struct gpio_led litekit_leds[] __initconst = {
+ {
+ .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 const struct gpio_led_platform_data
+ litekit_led_platform_data __initconst = {
+ .leds = litekit_leds,
+ .num_leds = ARRAY_SIZE(litekit_leds),
+};
+
+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);
+ gpio_led_register_device(-1, &litekit_led_platform_data);
+ imx31_add_imx2_wdt();
+ imx31_add_mxc_rtc();
+}
diff --git a/arch/arm/mach-imx/mx31moboard-devboard.c b/arch/arm/mach-imx/mx31moboard-devboard.c
new file mode 100644
index 000000000..1e91a0918
--- /dev/null
+++ b/arch/arm/mach-imx/mx31moboard-devboard.c
@@ -0,0 +1,246 @@
+/*
+ * 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 "common.h"
+#include "devices-imx31.h"
+#include "ehci.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "ulpi.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 usb_phy *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 usb_otg *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 usb_phy *phy;
+ struct platform_device *pdev;
+
+ phy = kzalloc(sizeof(*phy), GFP_KERNEL);
+ if (!phy)
+ return -ENOMEM;
+
+ phy->otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL);
+ if (!phy->otg) {
+ kfree(phy);
+ return -ENOMEM;
+ }
+
+ phy->label = "ISP1105";
+ phy->init = devboard_isp1105_init;
+ phy->otg->set_vbus = devboard_isp1105_set_vbus;
+
+ usbh1_pdata.otg = phy;
+
+ pdev = imx31_add_mxc_ehci_hs(1, &usbh1_pdata);
+
+ return PTR_ERR_OR_ZERO(pdev);
+}
+
+
+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 000000000..2e895a82a
--- /dev/null
+++ b/arch/arm/mach-imx/mx31moboard-marxbot.c
@@ -0,0 +1,370 @@
+/*
+ * 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 <media/soc_camera.h>
+
+#include "common.h"
+#include "devices-imx31.h"
+#include "ehci.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "ulpi.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 usb_phy *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 usb_otg *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 usb_phy *phy;
+ struct platform_device *pdev;
+
+ phy = kzalloc(sizeof(*phy), GFP_KERNEL);
+ if (!phy)
+ return -ENOMEM;
+
+ phy->otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL);
+ if (!phy->otg) {
+ kfree(phy);
+ return -ENOMEM;
+ }
+
+ phy->label = "ISP1105";
+ phy->init = marxbot_isp1105_init;
+ phy->otg->set_vbus = marxbot_isp1105_set_vbus;
+
+ usbh1_pdata.otg = phy;
+
+ pdev = imx31_add_mxc_ehci_hs(1, &usbh1_pdata);
+
+ return PTR_ERR_OR_ZERO(pdev);
+}
+
+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 000000000..89fc35a64
--- /dev/null
+++ b/arch/arm/mach-imx/mx31moboard-smartbot.c
@@ -0,0 +1,207 @@
+/*
+ * 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 <media/soc_camera.h>
+
+#include "board-mx31moboard.h"
+#include "common.h"
+#include "devices-imx31.h"
+#include "ehci.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "ulpi.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);
+
+ return PTR_ERR_OR_ZERO(pdev);
+}
+#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/mx35.h b/arch/arm/mach-imx/mx35.h
new file mode 100644
index 000000000..2af5d3a69
--- /dev/null
+++ b/arch/arm/mach-imx/mx35.h
@@ -0,0 +1,190 @@
+#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_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
+ */
+#include <asm/irq.h>
+#define MX35_INT_OWIRE (NR_IRQS_LEGACY + 2)
+#define MX35_INT_I2C3 (NR_IRQS_LEGACY + 3)
+#define MX35_INT_I2C2 (NR_IRQS_LEGACY + 4)
+#define MX35_INT_RTIC (NR_IRQS_LEGACY + 6)
+#define MX35_INT_ESDHC1 (NR_IRQS_LEGACY + 7)
+#define MX35_INT_ESDHC2 (NR_IRQS_LEGACY + 8)
+#define MX35_INT_ESDHC3 (NR_IRQS_LEGACY + 9)
+#define MX35_INT_I2C1 (NR_IRQS_LEGACY + 10)
+#define MX35_INT_SSI1 (NR_IRQS_LEGACY + 11)
+#define MX35_INT_SSI2 (NR_IRQS_LEGACY + 12)
+#define MX35_INT_CSPI2 (NR_IRQS_LEGACY + 13)
+#define MX35_INT_CSPI1 (NR_IRQS_LEGACY + 14)
+#define MX35_INT_ATA (NR_IRQS_LEGACY + 15)
+#define MX35_INT_GPU2D (NR_IRQS_LEGACY + 16)
+#define MX35_INT_ASRC (NR_IRQS_LEGACY + 17)
+#define MX35_INT_UART3 (NR_IRQS_LEGACY + 18)
+#define MX35_INT_IIM (NR_IRQS_LEGACY + 19)
+#define MX35_INT_RNGA (NR_IRQS_LEGACY + 22)
+#define MX35_INT_EVTMON (NR_IRQS_LEGACY + 23)
+#define MX35_INT_KPP (NR_IRQS_LEGACY + 24)
+#define MX35_INT_RTC (NR_IRQS_LEGACY + 25)
+#define MX35_INT_PWM (NR_IRQS_LEGACY + 26)
+#define MX35_INT_EPIT2 (NR_IRQS_LEGACY + 27)
+#define MX35_INT_EPIT1 (NR_IRQS_LEGACY + 28)
+#define MX35_INT_GPT (NR_IRQS_LEGACY + 29)
+#define MX35_INT_POWER_FAIL (NR_IRQS_LEGACY + 30)
+#define MX35_INT_UART2 (NR_IRQS_LEGACY + 32)
+#define MX35_INT_NFC (NR_IRQS_LEGACY + 33)
+#define MX35_INT_SDMA (NR_IRQS_LEGACY + 34)
+#define MX35_INT_USB_HS (NR_IRQS_LEGACY + 35)
+#define MX35_INT_USB_OTG (NR_IRQS_LEGACY + 37)
+#define MX35_INT_MSHC1 (NR_IRQS_LEGACY + 39)
+#define MX35_INT_ESAI (NR_IRQS_LEGACY + 40)
+#define MX35_INT_IPU_ERR (NR_IRQS_LEGACY + 41)
+#define MX35_INT_IPU_SYN (NR_IRQS_LEGACY + 42)
+#define MX35_INT_CAN1 (NR_IRQS_LEGACY + 43)
+#define MX35_INT_CAN2 (NR_IRQS_LEGACY + 44)
+#define MX35_INT_UART1 (NR_IRQS_LEGACY + 45)
+#define MX35_INT_MLB (NR_IRQS_LEGACY + 46)
+#define MX35_INT_SPDIF (NR_IRQS_LEGACY + 47)
+#define MX35_INT_ECT (NR_IRQS_LEGACY + 48)
+#define MX35_INT_SCC_SCM (NR_IRQS_LEGACY + 49)
+#define MX35_INT_SCC_SMN (NR_IRQS_LEGACY + 50)
+#define MX35_INT_GPIO2 (NR_IRQS_LEGACY + 51)
+#define MX35_INT_GPIO1 (NR_IRQS_LEGACY + 52)
+#define MX35_INT_WDOG (NR_IRQS_LEGACY + 55)
+#define MX35_INT_GPIO3 (NR_IRQS_LEGACY + 56)
+#define MX35_INT_FEC (NR_IRQS_LEGACY + 57)
+#define MX35_INT_EXT_POWER (NR_IRQS_LEGACY + 58)
+#define MX35_INT_EXT_TEMPER (NR_IRQS_LEGACY + 59)
+#define MX35_INT_EXT_SENSOR60 (NR_IRQS_LEGACY + 60)
+#define MX35_INT_EXT_SENSOR61 (NR_IRQS_LEGACY + 61)
+#define MX35_INT_EXT_WDOG (NR_IRQS_LEGACY + 62)
+#define MX35_INT_EXT_TV (NR_IRQS_LEGACY + 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/mach-imx/mx3x.h b/arch/arm/mach-imx/mx3x.h
new file mode 100644
index 000000000..96fb4fbc8
--- /dev/null
+++ b/arch/arm/mach-imx/mx3x.h
@@ -0,0 +1,195 @@
+/*
+ * 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
+ */
+#include <asm/irq.h>
+#define MX3x_INT_I2C3 (NR_IRQS_LEGACY + 3)
+#define MX3x_INT_I2C2 (NR_IRQS_LEGACY + 4)
+#define MX3x_INT_RTIC (NR_IRQS_LEGACY + 6)
+#define MX3x_INT_I2C (NR_IRQS_LEGACY + 10)
+#define MX3x_INT_CSPI2 (NR_IRQS_LEGACY + 13)
+#define MX3x_INT_CSPI1 (NR_IRQS_LEGACY + 14)
+#define MX3x_INT_ATA (NR_IRQS_LEGACY + 15)
+#define MX3x_INT_UART3 (NR_IRQS_LEGACY + 18)
+#define MX3x_INT_IIM (NR_IRQS_LEGACY + 19)
+#define MX3x_INT_RNGA (NR_IRQS_LEGACY + 22)
+#define MX3x_INT_EVTMON (NR_IRQS_LEGACY + 23)
+#define MX3x_INT_KPP (NR_IRQS_LEGACY + 24)
+#define MX3x_INT_RTC (NR_IRQS_LEGACY + 25)
+#define MX3x_INT_PWM (NR_IRQS_LEGACY + 26)
+#define MX3x_INT_EPIT2 (NR_IRQS_LEGACY + 27)
+#define MX3x_INT_EPIT1 (NR_IRQS_LEGACY + 28)
+#define MX3x_INT_GPT (NR_IRQS_LEGACY + 29)
+#define MX3x_INT_POWER_FAIL (NR_IRQS_LEGACY + 30)
+#define MX3x_INT_UART2 (NR_IRQS_LEGACY + 32)
+#define MX3x_INT_NANDFC (NR_IRQS_LEGACY + 33)
+#define MX3x_INT_SDMA (NR_IRQS_LEGACY + 34)
+#define MX3x_INT_MSHC1 (NR_IRQS_LEGACY + 39)
+#define MX3x_INT_IPU_ERR (NR_IRQS_LEGACY + 41)
+#define MX3x_INT_IPU_SYN (NR_IRQS_LEGACY + 42)
+#define MX3x_INT_UART1 (NR_IRQS_LEGACY + 45)
+#define MX3x_INT_ECT (NR_IRQS_LEGACY + 48)
+#define MX3x_INT_SCC_SCM (NR_IRQS_LEGACY + 49)
+#define MX3x_INT_SCC_SMN (NR_IRQS_LEGACY + 50)
+#define MX3x_INT_GPIO2 (NR_IRQS_LEGACY + 51)
+#define MX3x_INT_GPIO1 (NR_IRQS_LEGACY + 52)
+#define MX3x_INT_WDOG (NR_IRQS_LEGACY + 55)
+#define MX3x_INT_GPIO3 (NR_IRQS_LEGACY + 56)
+#define MX3x_INT_EXT_POWER (NR_IRQS_LEGACY + 58)
+#define MX3x_INT_EXT_TEMPER (NR_IRQS_LEGACY + 59)
+#define MX3x_INT_EXT_SENSOR60 (NR_IRQS_LEGACY + 60)
+#define MX3x_INT_EXT_SENSOR61 (NR_IRQS_LEGACY + 61)
+#define MX3x_INT_EXT_WDOG (NR_IRQS_LEGACY + 62)
+#define MX3x_INT_EXT_TV (NR_IRQS_LEGACY + 63)
+
+#define MX3x_PROD_SIGNATURE 0x1 /* For MX31 */
+
+/* Mandatory defines used globally */
+
+#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
+extern int mx35_revision(void);
+extern int mx31_revision(void);
+#endif
+
+#endif /* ifndef __MACH_MX3x_H__ */
diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h
new file mode 100644
index 000000000..4c1343df2
--- /dev/null
+++ b/arch/arm/mach-imx/mxc.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2004-2007, 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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_MX51 51
+#define MXC_CPU_MX53 53
+#define MXC_CPU_IMX6SL 0x60
+#define MXC_CPU_IMX6DL 0x61
+#define MXC_CPU_IMX6SX 0x62
+#define MXC_CPU_IMX6Q 0x63
+
+#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_1_4 0x14
+#define IMX_CHIP_REVISION_1_5 0x15
+#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_DDR_TYPE_LPDDR2 1
+
+#ifndef __ASSEMBLY__
+extern unsigned int __mxc_cpu_type;
+#endif
+
+#ifdef CONFIG_SOC_IMX1
+# 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_SOC_IMX21
+# 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_SOC_IMX25
+# 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_SOC_IMX27
+# 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
+
+#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_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
+
+#ifndef __ASSEMBLY__
+#ifdef CONFIG_SOC_IMX6SL
+static inline bool cpu_is_imx6sl(void)
+{
+ return __mxc_cpu_type == MXC_CPU_IMX6SL;
+}
+#else
+static inline bool cpu_is_imx6sl(void)
+{
+ return false;
+}
+#endif
+
+static inline bool cpu_is_imx6dl(void)
+{
+ return __mxc_cpu_type == MXC_CPU_IMX6DL;
+}
+
+static inline bool cpu_is_imx6sx(void)
+{
+ return __mxc_cpu_type == MXC_CPU_IMX6SX;
+}
+
+static inline bool cpu_is_imx6q(void)
+{
+ return __mxc_cpu_type == MXC_CPU_IMX6Q;
+}
+
+struct cpu_op {
+ u32 cpu_rate;
+};
+
+int tzic_enable_wake(void);
+
+extern struct cpu_op *(*get_cpu_op)(int *op);
+#endif
+
+#define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35())
+#define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27())
+
+#endif /* __ASM_ARCH_MXC_H__ */
diff --git a/arch/arm/mach-imx/pcm037.h b/arch/arm/mach-imx/pcm037.h
new file mode 100644
index 000000000..7d167690e
--- /dev/null
+++ b/arch/arm/mach-imx/pcm037.h
@@ -0,0 +1,17 @@
+#ifndef __PCM037_H__
+#define __PCM037_H__
+
+enum pcm037_board_variant {
+ PCM037_PCM970,
+ PCM037_EET,
+};
+
+extern enum pcm037_board_variant pcm037_variant(void);
+
+#ifdef CONFIG_MACH_PCM037_EET
+int pcm037_eet_init_devices(void);
+#else
+static inline int pcm037_eet_init_devices(void) { return 0; }
+#endif
+
+#endif
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c
new file mode 100644
index 000000000..7f270015f
--- /dev/null
+++ b/arch/arm/mach-imx/platsmp.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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/of_address.h>
+#include <linux/of.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <asm/page.h>
+#include <asm/smp_scu.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+#include "hardware.h"
+
+u32 g_diag_reg;
+static void __iomem *scu_base;
+
+static struct map_desc scu_io_desc __initdata = {
+ /* .virtual and .pfn are run-time assigned */
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+};
+
+void __init imx_scu_map_io(void)
+{
+ unsigned long base;
+
+ /* Get SCU base */
+ asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
+
+ scu_io_desc.virtual = IMX_IO_P2V(base);
+ scu_io_desc.pfn = __phys_to_pfn(base);
+ iotable_init(&scu_io_desc, 1);
+
+ scu_base = IMX_IO_ADDRESS(base);
+}
+
+static int imx_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ imx_set_cpu_jump(cpu, v7_secondary_startup);
+ imx_enable_cpu(cpu, true);
+ return 0;
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+static void __init imx_smp_init_cpus(void)
+{
+ int i, ncores;
+
+ ncores = scu_get_core_count(scu_base);
+
+ for (i = ncores; i < NR_CPUS; i++)
+ set_cpu_possible(i, false);
+}
+
+void imx_smp_prepare(void)
+{
+ scu_enable(scu_base);
+}
+
+static void __init imx_smp_prepare_cpus(unsigned int max_cpus)
+{
+ imx_smp_prepare();
+
+ /*
+ * The diagnostic register holds the errata bits. Mostly bootloader
+ * does not bring up secondary cores, so that when errata bits are set
+ * in bootloader, they are set only for boot cpu. But on a SMP
+ * configuration, it should be equally done on every single core.
+ * Read the register from boot cpu here, and will replicate it into
+ * secondary cores when booting them.
+ */
+ asm("mrc p15, 0, %0, c15, c0, 1" : "=r" (g_diag_reg) : : "cc");
+ sync_cache_w(&g_diag_reg);
+}
+
+struct smp_operations imx_smp_ops __initdata = {
+ .smp_init_cpus = imx_smp_init_cpus,
+ .smp_prepare_cpus = imx_smp_prepare_cpus,
+ .smp_boot_secondary = imx_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = imx_cpu_die,
+ .cpu_kill = imx_cpu_kill,
+#endif
+};
+
+#define DCFG_CCSR_SCRATCHRW1 0x200
+
+static int ls1021a_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+ return 0;
+}
+
+static void __init ls1021a_smp_prepare_cpus(unsigned int max_cpus)
+{
+ struct device_node *np;
+ void __iomem *dcfg_base;
+ unsigned long paddr;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcfg");
+ dcfg_base = of_iomap(np, 0);
+ BUG_ON(!dcfg_base);
+
+ paddr = virt_to_phys(secondary_startup);
+ writel_relaxed(cpu_to_be32(paddr), dcfg_base + DCFG_CCSR_SCRATCHRW1);
+
+ iounmap(dcfg_base);
+}
+
+struct smp_operations ls1021a_smp_ops __initdata = {
+ .smp_prepare_cpus = ls1021a_smp_prepare_cpus,
+ .smp_boot_secondary = ls1021a_boot_secondary,
+};
diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c
new file mode 100644
index 000000000..56d02d064
--- /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 "hardware.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 */
+ cpu_do_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-imx/pm-imx3.c b/arch/arm/mach-imx/pm-imx3.c
new file mode 100644
index 000000000..6a07006ff
--- /dev/null
+++ b/arch/arm/mach-imx/pm-imx3.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 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/io.h>
+
+#include "common.h"
+#include "crmregs-imx3.h"
+#include "devices/devices-common.h"
+#include "hardware.h"
+
+/*
+ * Set cpu low power mode before WFI instruction. This function is called
+ * mx3 because it can be used for mx31 and mx35.
+ * Currently only WAIT_MODE is supported.
+ */
+void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode)
+{
+ int reg = __raw_readl(mx3_ccm_base + MXC_CCM_CCMR);
+ reg &= ~MXC_CCM_CCMR_LPM_MASK;
+
+ switch (mode) {
+ case MX3_WAIT:
+ if (cpu_is_mx35())
+ reg |= MXC_CCM_CCMR_LPM_WAIT_MX35;
+ __raw_writel(reg, mx3_ccm_base + MXC_CCM_CCMR);
+ break;
+ default:
+ pr_err("Unknown cpu power mode: %d\n", mode);
+ return;
+ }
+}
diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c
new file mode 100644
index 000000000..f1f80ab73
--- /dev/null
+++ b/arch/arm/mach-imx/pm-imx5.c
@@ -0,0 +1,235 @@
+/*
+ * 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/suspend.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <asm/cacheflush.h>
+#include <asm/system_misc.h>
+#include <asm/tlbflush.h>
+
+#include "common.h"
+#include "cpuidle.h"
+#include "hardware.h"
+
+#define MXC_CCM_CLPCR 0x54
+#define MXC_CCM_CLPCR_LPM_OFFSET 0
+#define MXC_CCM_CLPCR_LPM_MASK 0x3
+#define MXC_CCM_CLPCR_STBY_COUNT_OFFSET 9
+#define MXC_CCM_CLPCR_VSTBY (0x1 << 8)
+#define MXC_CCM_CLPCR_SBYOS (0x1 << 6)
+
+#define MXC_CORTEXA8_PLAT_LPC 0xc
+#define MXC_CORTEXA8_PLAT_LPC_DSM (1 << 0)
+#define MXC_CORTEXA8_PLAT_LPC_DBG_DSM (1 << 1)
+
+#define MXC_SRPG_NEON_SRPGCR 0x280
+#define MXC_SRPG_ARM_SRPGCR 0x2a0
+#define MXC_SRPG_EMPGC0_SRPGCR 0x2c0
+#define MXC_SRPG_EMPGC1_SRPGCR 0x2d0
+
+#define MXC_SRPGCR_PCR 1
+
+/*
+ * The WAIT_UNCLOCKED_POWER_OFF state only requires <= 500ns to exit.
+ * This is also the lowest power state possible without affecting
+ * non-cpu parts of the system. For these reasons, imx5 should default
+ * to always using this state for cpu idling. The PM_SUSPEND_STANDBY also
+ * uses this state and needs to take no action when registers remain confgiured
+ * for this state.
+ */
+#define IMX5_DEFAULT_CPU_IDLE_STATE WAIT_UNCLOCKED_POWER_OFF
+
+struct imx5_pm_data {
+ phys_addr_t cortex_addr;
+ phys_addr_t gpc_addr;
+};
+
+static const struct imx5_pm_data imx51_pm_data __initconst = {
+ .cortex_addr = 0x83fa0000,
+ .gpc_addr = 0x73fd8000,
+};
+
+static const struct imx5_pm_data imx53_pm_data __initconst = {
+ .cortex_addr = 0x63fa0000,
+ .gpc_addr = 0x53fd8000,
+};
+
+static void __iomem *ccm_base;
+static void __iomem *cortex_base;
+static void __iomem *gpc_base;
+
+void __init imx5_pm_set_ccm_base(void __iomem *base)
+{
+ ccm_base = base;
+}
+
+/*
+ * set cpu low power mode before WFI instruction. This function is called
+ * mx5 because it can be used for mx51, and mx53.
+ */
+static void mx5_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(cortex_base + MXC_CORTEXA8_PLAT_LPC) &
+ ~(MXC_CORTEXA8_PLAT_LPC_DSM);
+ ccm_clpcr = __raw_readl(ccm_base + MXC_CCM_CLPCR) &
+ ~(MXC_CCM_CLPCR_LPM_MASK);
+ arm_srpgcr = __raw_readl(gpc_base + MXC_SRPG_ARM_SRPGCR) &
+ ~(MXC_SRPGCR_PCR);
+ empgc0 = __raw_readl(gpc_base + MXC_SRPG_EMPGC0_SRPGCR) &
+ ~(MXC_SRPGCR_PCR);
+ empgc1 = __raw_readl(gpc_base + 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;
+ 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, cortex_base + MXC_CORTEXA8_PLAT_LPC);
+ __raw_writel(ccm_clpcr, ccm_base + MXC_CCM_CLPCR);
+ __raw_writel(arm_srpgcr, gpc_base + MXC_SRPG_ARM_SRPGCR);
+ __raw_writel(arm_srpgcr, gpc_base + MXC_SRPG_NEON_SRPGCR);
+
+ if (stop_mode) {
+ empgc0 |= MXC_SRPGCR_PCR;
+ empgc1 |= MXC_SRPGCR_PCR;
+
+ __raw_writel(empgc0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR);
+ __raw_writel(empgc1, gpc_base + MXC_SRPG_EMPGC1_SRPGCR);
+ }
+}
+
+static int mx5_suspend_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ mx5_cpu_lp_set(STOP_POWER_OFF);
+ break;
+ case PM_SUSPEND_STANDBY:
+ /* DEFAULT_IDLE_STATE already configured */
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (state == PM_SUSPEND_MEM) {
+ local_flush_tlb_all();
+ flush_cache_all();
+
+ /*clear the EMPGC0/1 bits */
+ __raw_writel(0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR);
+ __raw_writel(0, gpc_base + MXC_SRPG_EMPGC1_SRPGCR);
+ }
+ cpu_do_idle();
+
+ /* return registers to default idle state */
+ mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE);
+ return 0;
+}
+
+static int mx5_pm_valid(suspend_state_t state)
+{
+ return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX);
+}
+
+static const struct platform_suspend_ops mx5_suspend_ops = {
+ .valid = mx5_pm_valid,
+ .enter = mx5_suspend_enter,
+};
+
+static inline int imx5_cpu_do_idle(void)
+{
+ int ret = tzic_enable_wake();
+
+ if (likely(!ret))
+ cpu_do_idle();
+
+ return ret;
+}
+
+static void imx5_pm_idle(void)
+{
+ imx5_cpu_do_idle();
+}
+
+static int __init imx5_pm_common_init(const struct imx5_pm_data *data)
+{
+ int ret;
+ struct clk *gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
+
+ if (IS_ERR(gpc_dvfs_clk))
+ return PTR_ERR(gpc_dvfs_clk);
+
+ ret = clk_prepare_enable(gpc_dvfs_clk);
+ if (ret)
+ return ret;
+
+ arm_pm_idle = imx5_pm_idle;
+
+ cortex_base = ioremap(data->cortex_addr, SZ_16K);
+ gpc_base = ioremap(data->gpc_addr, SZ_16K);
+ WARN_ON(!ccm_base || !cortex_base || !gpc_base);
+
+ /* Set the registers to the default cpu idle state. */
+ mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE);
+
+ ret = imx5_cpuidle_init();
+ if (ret)
+ pr_warn("%s: cpuidle init failed %d\n", __func__, ret);
+
+ suspend_set_ops(&mx5_suspend_ops);
+
+ return 0;
+}
+
+void __init imx51_pm_init(void)
+{
+ imx5_pm_common_init(&imx51_pm_data);
+}
+
+void __init imx53_pm_init(void)
+{
+ imx5_pm_common_init(&imx53_pm_data);
+}
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
new file mode 100644
index 000000000..6a7c6fc78
--- /dev/null
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -0,0 +1,600 @@
+/*
+ * Copyright 2011-2014 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/genalloc.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/suspend.h>
+#include <asm/cacheflush.h>
+#include <asm/fncpy.h>
+#include <asm/proc-fns.h>
+#include <asm/suspend.h>
+#include <asm/tlb.h>
+
+#include "common.h"
+#include "hardware.h"
+
+#define CCR 0x0
+#define BM_CCR_WB_COUNT (0x7 << 16)
+#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21)
+#define BM_CCR_RBC_EN (0x1 << 27)
+
+#define CLPCR 0x54
+#define BP_CLPCR_LPM 0
+#define BM_CLPCR_LPM (0x3 << 0)
+#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
+#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
+#define BM_CLPCR_SBYOS (0x1 << 6)
+#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
+#define BM_CLPCR_VSTBY (0x1 << 8)
+#define BP_CLPCR_STBY_COUNT 9
+#define BM_CLPCR_STBY_COUNT (0x3 << 9)
+#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
+#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
+#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
+#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
+#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
+#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
+#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
+#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
+#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
+#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
+#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
+
+#define CGPR 0x64
+#define BM_CGPR_INT_MEM_CLK_LPM (0x1 << 17)
+
+#define MX6Q_SUSPEND_OCRAM_SIZE 0x1000
+#define MX6_MAX_MMDC_IO_NUM 33
+
+static void __iomem *ccm_base;
+static void __iomem *suspend_ocram_base;
+static void (*imx6_suspend_in_ocram_fn)(void __iomem *ocram_vbase);
+
+/*
+ * suspend ocram space layout:
+ * ======================== high address ======================
+ * .
+ * .
+ * .
+ * ^
+ * ^
+ * ^
+ * imx6_suspend code
+ * PM_INFO structure(imx6_cpu_pm_info)
+ * ======================== low address =======================
+ */
+
+struct imx6_pm_base {
+ phys_addr_t pbase;
+ void __iomem *vbase;
+};
+
+struct imx6_pm_socdata {
+ u32 ddr_type;
+ const char *mmdc_compat;
+ const char *src_compat;
+ const char *iomuxc_compat;
+ const char *gpc_compat;
+ const u32 mmdc_io_num;
+ const u32 *mmdc_io_offset;
+};
+
+static const u32 imx6q_mmdc_io_offset[] __initconst = {
+ 0x5ac, 0x5b4, 0x528, 0x520, /* DQM0 ~ DQM3 */
+ 0x514, 0x510, 0x5bc, 0x5c4, /* DQM4 ~ DQM7 */
+ 0x56c, 0x578, 0x588, 0x594, /* CAS, RAS, SDCLK_0, SDCLK_1 */
+ 0x5a8, 0x5b0, 0x524, 0x51c, /* SDQS0 ~ SDQS3 */
+ 0x518, 0x50c, 0x5b8, 0x5c0, /* SDQS4 ~ SDQS7 */
+ 0x784, 0x788, 0x794, 0x79c, /* GPR_B0DS ~ GPR_B3DS */
+ 0x7a0, 0x7a4, 0x7a8, 0x748, /* GPR_B4DS ~ GPR_B7DS */
+ 0x59c, 0x5a0, 0x750, 0x774, /* SODT0, SODT1, MODE_CTL, MODE */
+ 0x74c, /* GPR_ADDS */
+};
+
+static const u32 imx6dl_mmdc_io_offset[] __initconst = {
+ 0x470, 0x474, 0x478, 0x47c, /* DQM0 ~ DQM3 */
+ 0x480, 0x484, 0x488, 0x48c, /* DQM4 ~ DQM7 */
+ 0x464, 0x490, 0x4ac, 0x4b0, /* CAS, RAS, SDCLK_0, SDCLK_1 */
+ 0x4bc, 0x4c0, 0x4c4, 0x4c8, /* DRAM_SDQS0 ~ DRAM_SDQS3 */
+ 0x4cc, 0x4d0, 0x4d4, 0x4d8, /* DRAM_SDQS4 ~ DRAM_SDQS7 */
+ 0x764, 0x770, 0x778, 0x77c, /* GPR_B0DS ~ GPR_B3DS */
+ 0x780, 0x784, 0x78c, 0x748, /* GPR_B4DS ~ GPR_B7DS */
+ 0x4b4, 0x4b8, 0x750, 0x760, /* SODT0, SODT1, MODE_CTL, MODE */
+ 0x74c, /* GPR_ADDS */
+};
+
+static const u32 imx6sl_mmdc_io_offset[] __initconst = {
+ 0x30c, 0x310, 0x314, 0x318, /* DQM0 ~ DQM3 */
+ 0x5c4, 0x5cc, 0x5d4, 0x5d8, /* GPR_B0DS ~ GPR_B3DS */
+ 0x300, 0x31c, 0x338, 0x5ac, /* CAS, RAS, SDCLK_0, GPR_ADDS */
+ 0x33c, 0x340, 0x5b0, 0x5c0, /* SODT0, SODT1, MODE_CTL, MODE */
+ 0x330, 0x334, 0x320, /* SDCKE0, SDCKE1, RESET */
+};
+
+static const u32 imx6sx_mmdc_io_offset[] __initconst = {
+ 0x2ec, 0x2f0, 0x2f4, 0x2f8, /* DQM0 ~ DQM3 */
+ 0x60c, 0x610, 0x61c, 0x620, /* GPR_B0DS ~ GPR_B3DS */
+ 0x300, 0x2fc, 0x32c, 0x5f4, /* CAS, RAS, SDCLK_0, GPR_ADDS */
+ 0x310, 0x314, 0x5f8, 0x608, /* SODT0, SODT1, MODE_CTL, MODE */
+ 0x330, 0x334, 0x338, 0x33c, /* SDQS0 ~ SDQS3 */
+};
+
+static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
+ .mmdc_compat = "fsl,imx6q-mmdc",
+ .src_compat = "fsl,imx6q-src",
+ .iomuxc_compat = "fsl,imx6q-iomuxc",
+ .gpc_compat = "fsl,imx6q-gpc",
+ .mmdc_io_num = ARRAY_SIZE(imx6q_mmdc_io_offset),
+ .mmdc_io_offset = imx6q_mmdc_io_offset,
+};
+
+static const struct imx6_pm_socdata imx6dl_pm_data __initconst = {
+ .mmdc_compat = "fsl,imx6q-mmdc",
+ .src_compat = "fsl,imx6q-src",
+ .iomuxc_compat = "fsl,imx6dl-iomuxc",
+ .gpc_compat = "fsl,imx6q-gpc",
+ .mmdc_io_num = ARRAY_SIZE(imx6dl_mmdc_io_offset),
+ .mmdc_io_offset = imx6dl_mmdc_io_offset,
+};
+
+static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
+ .mmdc_compat = "fsl,imx6sl-mmdc",
+ .src_compat = "fsl,imx6sl-src",
+ .iomuxc_compat = "fsl,imx6sl-iomuxc",
+ .gpc_compat = "fsl,imx6sl-gpc",
+ .mmdc_io_num = ARRAY_SIZE(imx6sl_mmdc_io_offset),
+ .mmdc_io_offset = imx6sl_mmdc_io_offset,
+};
+
+static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
+ .mmdc_compat = "fsl,imx6sx-mmdc",
+ .src_compat = "fsl,imx6sx-src",
+ .iomuxc_compat = "fsl,imx6sx-iomuxc",
+ .gpc_compat = "fsl,imx6sx-gpc",
+ .mmdc_io_num = ARRAY_SIZE(imx6sx_mmdc_io_offset),
+ .mmdc_io_offset = imx6sx_mmdc_io_offset,
+};
+
+/*
+ * This structure is for passing necessary data for low level ocram
+ * suspend code(arch/arm/mach-imx/suspend-imx6.S), if this struct
+ * definition is changed, the offset definition in
+ * arch/arm/mach-imx/suspend-imx6.S must be also changed accordingly,
+ * otherwise, the suspend to ocram function will be broken!
+ */
+struct imx6_cpu_pm_info {
+ phys_addr_t pbase; /* The physical address of pm_info. */
+ phys_addr_t resume_addr; /* The physical resume address for asm code */
+ u32 ddr_type;
+ u32 pm_info_size; /* Size of pm_info. */
+ struct imx6_pm_base mmdc_base;
+ struct imx6_pm_base src_base;
+ struct imx6_pm_base iomuxc_base;
+ struct imx6_pm_base ccm_base;
+ struct imx6_pm_base gpc_base;
+ struct imx6_pm_base l2_base;
+ u32 mmdc_io_num; /* Number of MMDC IOs which need saved/restored. */
+ u32 mmdc_io_val[MX6_MAX_MMDC_IO_NUM][2]; /* To save offset and value */
+} __aligned(8);
+
+void imx6q_set_int_mem_clk_lpm(bool enable)
+{
+ u32 val = readl_relaxed(ccm_base + CGPR);
+
+ val &= ~BM_CGPR_INT_MEM_CLK_LPM;
+ if (enable)
+ val |= BM_CGPR_INT_MEM_CLK_LPM;
+ writel_relaxed(val, ccm_base + CGPR);
+}
+
+void imx6_enable_rbc(bool enable)
+{
+ u32 val;
+
+ /*
+ * need to mask all interrupts in GPC before
+ * operating RBC configurations
+ */
+ imx_gpc_mask_all();
+
+ /* configure RBC enable bit */
+ val = readl_relaxed(ccm_base + CCR);
+ val &= ~BM_CCR_RBC_EN;
+ val |= enable ? BM_CCR_RBC_EN : 0;
+ writel_relaxed(val, ccm_base + CCR);
+
+ /* configure RBC count */
+ val = readl_relaxed(ccm_base + CCR);
+ val &= ~BM_CCR_RBC_BYPASS_COUNT;
+ val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
+ writel(val, ccm_base + CCR);
+
+ /*
+ * need to delay at least 2 cycles of CKIL(32K)
+ * due to hardware design requirement, which is
+ * ~61us, here we use 65us for safe
+ */
+ udelay(65);
+
+ /* restore GPC interrupt mask settings */
+ imx_gpc_restore_all();
+}
+
+static void imx6q_enable_wb(bool enable)
+{
+ u32 val;
+
+ /* configure well bias enable bit */
+ val = readl_relaxed(ccm_base + CLPCR);
+ val &= ~BM_CLPCR_WB_PER_AT_LPM;
+ val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
+ writel_relaxed(val, ccm_base + CLPCR);
+
+ /* configure well bias count */
+ val = readl_relaxed(ccm_base + CCR);
+ val &= ~BM_CCR_WB_COUNT;
+ val |= enable ? BM_CCR_WB_COUNT : 0;
+ writel_relaxed(val, ccm_base + CCR);
+}
+
+int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
+{
+ u32 val = readl_relaxed(ccm_base + CLPCR);
+
+ val &= ~BM_CLPCR_LPM;
+ switch (mode) {
+ case WAIT_CLOCKED:
+ break;
+ case WAIT_UNCLOCKED:
+ val |= 0x1 << BP_CLPCR_LPM;
+ val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
+ break;
+ case STOP_POWER_ON:
+ val |= 0x2 << BP_CLPCR_LPM;
+ val &= ~BM_CLPCR_VSTBY;
+ val &= ~BM_CLPCR_SBYOS;
+ if (cpu_is_imx6sl())
+ val |= BM_CLPCR_BYPASS_PMIC_READY;
+ if (cpu_is_imx6sl() || cpu_is_imx6sx())
+ val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
+ else
+ val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
+ break;
+ case WAIT_UNCLOCKED_POWER_OFF:
+ val |= 0x1 << BP_CLPCR_LPM;
+ val &= ~BM_CLPCR_VSTBY;
+ val &= ~BM_CLPCR_SBYOS;
+ break;
+ case STOP_POWER_OFF:
+ val |= 0x2 << BP_CLPCR_LPM;
+ val |= 0x3 << BP_CLPCR_STBY_COUNT;
+ val |= BM_CLPCR_VSTBY;
+ val |= BM_CLPCR_SBYOS;
+ if (cpu_is_imx6sl())
+ val |= BM_CLPCR_BYPASS_PMIC_READY;
+ if (cpu_is_imx6sl() || cpu_is_imx6sx())
+ val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
+ else
+ val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /*
+ * ERR007265: CCM: When improper low-power sequence is used,
+ * the SoC enters low power mode before the ARM core executes WFI.
+ *
+ * Software workaround:
+ * 1) Software should trigger IRQ #32 (IOMUX) to be always pending
+ * by setting IOMUX_GPR1_GINT.
+ * 2) Software should then unmask IRQ #32 in GPC before setting CCM
+ * Low-Power mode.
+ * 3) Software should mask IRQ #32 right after CCM Low-Power mode
+ * is set (set bits 0-1 of CCM_CLPCR).
+ *
+ * Note that IRQ #32 is GIC SPI #0.
+ */
+ imx_gpc_hwirq_unmask(0);
+ writel_relaxed(val, ccm_base + CLPCR);
+ imx_gpc_hwirq_mask(0);
+
+ return 0;
+}
+
+static int imx6q_suspend_finish(unsigned long val)
+{
+ if (!imx6_suspend_in_ocram_fn) {
+ cpu_do_idle();
+ } else {
+ /*
+ * call low level suspend function in ocram,
+ * as we need to float DDR IO.
+ */
+ local_flush_tlb_all();
+ imx6_suspend_in_ocram_fn(suspend_ocram_base);
+ }
+
+ return 0;
+}
+
+static int imx6q_pm_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ imx6q_set_lpm(STOP_POWER_ON);
+ imx6q_set_int_mem_clk_lpm(true);
+ imx_gpc_pre_suspend(false);
+ if (cpu_is_imx6sl())
+ imx6sl_set_wait_clk(true);
+ /* Zzz ... */
+ cpu_do_idle();
+ if (cpu_is_imx6sl())
+ imx6sl_set_wait_clk(false);
+ imx_gpc_post_resume();
+ imx6q_set_lpm(WAIT_CLOCKED);
+ break;
+ case PM_SUSPEND_MEM:
+ imx6q_set_lpm(STOP_POWER_OFF);
+ imx6q_set_int_mem_clk_lpm(false);
+ imx6q_enable_wb(true);
+ /*
+ * For suspend into ocram, asm code already take care of
+ * RBC setting, so we do NOT need to do that here.
+ */
+ if (!imx6_suspend_in_ocram_fn)
+ imx6_enable_rbc(true);
+ imx_gpc_pre_suspend(true);
+ imx_anatop_pre_suspend();
+ /* Zzz ... */
+ cpu_suspend(0, imx6q_suspend_finish);
+ if (cpu_is_imx6q() || cpu_is_imx6dl())
+ imx_smp_prepare();
+ imx_anatop_post_resume();
+ imx_gpc_post_resume();
+ imx6_enable_rbc(false);
+ imx6q_enable_wb(false);
+ imx6q_set_int_mem_clk_lpm(true);
+ imx6q_set_lpm(WAIT_CLOCKED);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int imx6q_pm_valid(suspend_state_t state)
+{
+ return (state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM);
+}
+
+static const struct platform_suspend_ops imx6q_pm_ops = {
+ .enter = imx6q_pm_enter,
+ .valid = imx6q_pm_valid,
+};
+
+void __init imx6q_pm_set_ccm_base(void __iomem *base)
+{
+ ccm_base = base;
+}
+
+static int __init imx6_pm_get_base(struct imx6_pm_base *base,
+ const char *compat)
+{
+ struct device_node *node;
+ struct resource res;
+ int ret = 0;
+
+ node = of_find_compatible_node(NULL, NULL, compat);
+ if (!node) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ ret = of_address_to_resource(node, 0, &res);
+ if (ret)
+ goto put_node;
+
+ base->pbase = res.start;
+ base->vbase = ioremap(res.start, resource_size(&res));
+ if (!base->vbase)
+ ret = -ENOMEM;
+
+put_node:
+ of_node_put(node);
+out:
+ return ret;
+}
+
+static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
+{
+ phys_addr_t ocram_pbase;
+ struct device_node *node;
+ struct platform_device *pdev;
+ struct imx6_cpu_pm_info *pm_info;
+ struct gen_pool *ocram_pool;
+ unsigned long ocram_base;
+ int i, ret = 0;
+ const u32 *mmdc_offset_array;
+
+ suspend_set_ops(&imx6q_pm_ops);
+
+ if (!socdata) {
+ pr_warn("%s: invalid argument!\n", __func__);
+ return -EINVAL;
+ }
+
+ node = of_find_compatible_node(NULL, NULL, "mmio-sram");
+ if (!node) {
+ pr_warn("%s: failed to find ocram node!\n", __func__);
+ return -ENODEV;
+ }
+
+ pdev = of_find_device_by_node(node);
+ if (!pdev) {
+ pr_warn("%s: failed to find ocram device!\n", __func__);
+ ret = -ENODEV;
+ goto put_node;
+ }
+
+ ocram_pool = dev_get_gen_pool(&pdev->dev);
+ if (!ocram_pool) {
+ pr_warn("%s: ocram pool unavailable!\n", __func__);
+ ret = -ENODEV;
+ goto put_node;
+ }
+
+ ocram_base = gen_pool_alloc(ocram_pool, MX6Q_SUSPEND_OCRAM_SIZE);
+ if (!ocram_base) {
+ pr_warn("%s: unable to alloc ocram!\n", __func__);
+ ret = -ENOMEM;
+ goto put_node;
+ }
+
+ ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base);
+
+ suspend_ocram_base = __arm_ioremap_exec(ocram_pbase,
+ MX6Q_SUSPEND_OCRAM_SIZE, false);
+
+ pm_info = suspend_ocram_base;
+ pm_info->pbase = ocram_pbase;
+ pm_info->resume_addr = virt_to_phys(v7_cpu_resume);
+ pm_info->pm_info_size = sizeof(*pm_info);
+
+ /*
+ * ccm physical address is not used by asm code currently,
+ * so get ccm virtual address directly, as we already have
+ * it from ccm driver.
+ */
+ pm_info->ccm_base.vbase = ccm_base;
+
+ ret = imx6_pm_get_base(&pm_info->mmdc_base, socdata->mmdc_compat);
+ if (ret) {
+ pr_warn("%s: failed to get mmdc base %d!\n", __func__, ret);
+ goto put_node;
+ }
+
+ ret = imx6_pm_get_base(&pm_info->src_base, socdata->src_compat);
+ if (ret) {
+ pr_warn("%s: failed to get src base %d!\n", __func__, ret);
+ goto src_map_failed;
+ }
+
+ ret = imx6_pm_get_base(&pm_info->iomuxc_base, socdata->iomuxc_compat);
+ if (ret) {
+ pr_warn("%s: failed to get iomuxc base %d!\n", __func__, ret);
+ goto iomuxc_map_failed;
+ }
+
+ ret = imx6_pm_get_base(&pm_info->gpc_base, socdata->gpc_compat);
+ if (ret) {
+ pr_warn("%s: failed to get gpc base %d!\n", __func__, ret);
+ goto gpc_map_failed;
+ }
+
+ ret = imx6_pm_get_base(&pm_info->l2_base, "arm,pl310-cache");
+ if (ret) {
+ pr_warn("%s: failed to get pl310-cache base %d!\n",
+ __func__, ret);
+ goto pl310_cache_map_failed;
+ }
+
+ pm_info->ddr_type = imx_mmdc_get_ddr_type();
+ pm_info->mmdc_io_num = socdata->mmdc_io_num;
+ mmdc_offset_array = socdata->mmdc_io_offset;
+
+ for (i = 0; i < pm_info->mmdc_io_num; i++) {
+ pm_info->mmdc_io_val[i][0] =
+ mmdc_offset_array[i];
+ pm_info->mmdc_io_val[i][1] =
+ readl_relaxed(pm_info->iomuxc_base.vbase +
+ mmdc_offset_array[i]);
+ }
+
+ imx6_suspend_in_ocram_fn = fncpy(
+ suspend_ocram_base + sizeof(*pm_info),
+ &imx6_suspend,
+ MX6Q_SUSPEND_OCRAM_SIZE - sizeof(*pm_info));
+
+ goto put_node;
+
+pl310_cache_map_failed:
+ iounmap(&pm_info->gpc_base.vbase);
+gpc_map_failed:
+ iounmap(&pm_info->iomuxc_base.vbase);
+iomuxc_map_failed:
+ iounmap(&pm_info->src_base.vbase);
+src_map_failed:
+ iounmap(&pm_info->mmdc_base.vbase);
+put_node:
+ of_node_put(node);
+
+ return ret;
+}
+
+static void __init imx6_pm_common_init(const struct imx6_pm_socdata
+ *socdata)
+{
+ struct regmap *gpr;
+ int ret;
+
+ WARN_ON(!ccm_base);
+
+ if (IS_ENABLED(CONFIG_SUSPEND)) {
+ ret = imx6q_suspend_init(socdata);
+ if (ret)
+ pr_warn("%s: No DDR LPM support with suspend %d!\n",
+ __func__, ret);
+ }
+
+ /*
+ * This is for SW workaround step #1 of ERR007265, see comments
+ * in imx6q_set_lpm for details of this errata.
+ * Force IOMUXC irq pending, so that the interrupt to GPC can be
+ * used to deassert dsm_request signal when the signal gets
+ * asserted unexpectedly.
+ */
+ gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+ if (!IS_ERR(gpr))
+ regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT,
+ IMX6Q_GPR1_GINT);
+}
+
+void __init imx6q_pm_init(void)
+{
+ imx6_pm_common_init(&imx6q_pm_data);
+}
+
+void __init imx6dl_pm_init(void)
+{
+ imx6_pm_common_init(&imx6dl_pm_data);
+}
+
+void __init imx6sl_pm_init(void)
+{
+ imx6_pm_common_init(&imx6sl_pm_data);
+}
+
+void __init imx6sx_pm_init(void)
+{
+ imx6_pm_common_init(&imx6sx_pm_data);
+}
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c
new file mode 100644
index 000000000..45f7f4e0a
--- /dev/null
+++ b/arch/arm/mach-imx/src.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/reset-controller.h>
+#include <linux/smp.h>
+#include <asm/smp_plat.h>
+#include "common.h"
+
+#define SRC_SCR 0x000
+#define SRC_GPR1 0x020
+#define BP_SRC_SCR_WARM_RESET_ENABLE 0
+#define BP_SRC_SCR_SW_GPU_RST 1
+#define BP_SRC_SCR_SW_VPU_RST 2
+#define BP_SRC_SCR_SW_IPU1_RST 3
+#define BP_SRC_SCR_SW_OPEN_VG_RST 4
+#define BP_SRC_SCR_SW_IPU2_RST 12
+#define BP_SRC_SCR_CORE1_RST 14
+#define BP_SRC_SCR_CORE1_ENABLE 22
+
+static void __iomem *src_base;
+static DEFINE_SPINLOCK(scr_lock);
+
+static const int sw_reset_bits[5] = {
+ BP_SRC_SCR_SW_GPU_RST,
+ BP_SRC_SCR_SW_VPU_RST,
+ BP_SRC_SCR_SW_IPU1_RST,
+ BP_SRC_SCR_SW_OPEN_VG_RST,
+ BP_SRC_SCR_SW_IPU2_RST
+};
+
+static int imx_src_reset_module(struct reset_controller_dev *rcdev,
+ unsigned long sw_reset_idx)
+{
+ unsigned long timeout;
+ unsigned long flags;
+ int bit;
+ u32 val;
+
+ if (!src_base)
+ return -ENODEV;
+
+ if (sw_reset_idx >= ARRAY_SIZE(sw_reset_bits))
+ return -EINVAL;
+
+ bit = 1 << sw_reset_bits[sw_reset_idx];
+
+ spin_lock_irqsave(&scr_lock, flags);
+ val = readl_relaxed(src_base + SRC_SCR);
+ val |= bit;
+ writel_relaxed(val, src_base + SRC_SCR);
+ spin_unlock_irqrestore(&scr_lock, flags);
+
+ timeout = jiffies + msecs_to_jiffies(1000);
+ while (readl(src_base + SRC_SCR) & bit) {
+ if (time_after(jiffies, timeout))
+ return -ETIME;
+ cpu_relax();
+ }
+
+ return 0;
+}
+
+static struct reset_control_ops imx_src_ops = {
+ .reset = imx_src_reset_module,
+};
+
+static struct reset_controller_dev imx_reset_controller = {
+ .ops = &imx_src_ops,
+ .nr_resets = ARRAY_SIZE(sw_reset_bits),
+};
+
+void imx_enable_cpu(int cpu, bool enable)
+{
+ u32 mask, val;
+
+ cpu = cpu_logical_map(cpu);
+ mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
+ spin_lock(&scr_lock);
+ val = readl_relaxed(src_base + SRC_SCR);
+ val = enable ? val | mask : val & ~mask;
+ val |= 1 << (BP_SRC_SCR_CORE1_RST + cpu - 1);
+ writel_relaxed(val, src_base + SRC_SCR);
+ spin_unlock(&scr_lock);
+}
+
+void imx_set_cpu_jump(int cpu, void *jump_addr)
+{
+ cpu = cpu_logical_map(cpu);
+ writel_relaxed(virt_to_phys(jump_addr),
+ src_base + SRC_GPR1 + cpu * 8);
+}
+
+u32 imx_get_cpu_arg(int cpu)
+{
+ cpu = cpu_logical_map(cpu);
+ return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4);
+}
+
+void imx_set_cpu_arg(int cpu, u32 arg)
+{
+ cpu = cpu_logical_map(cpu);
+ writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4);
+}
+
+void __init imx_src_init(void)
+{
+ struct device_node *np;
+ u32 val;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx51-src");
+ if (!np)
+ return;
+ src_base = of_iomap(np, 0);
+ WARN_ON(!src_base);
+
+ imx_reset_controller.of_node = np;
+ if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
+ reset_controller_register(&imx_reset_controller);
+
+ /*
+ * force warm reset sources to generate cold reset
+ * for a more reliable restart
+ */
+ spin_lock(&scr_lock);
+ val = readl_relaxed(src_base + SRC_SCR);
+ val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE);
+ writel_relaxed(val, src_base + SRC_SCR);
+ spin_unlock(&scr_lock);
+}
diff --git a/arch/arm/mach-imx/ssi-fiq-ksym.c b/arch/arm/mach-imx/ssi-fiq-ksym.c
new file mode 100644
index 000000000..792090f9a
--- /dev/null
+++ b/arch/arm/mach-imx/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 <linux/platform_data/asoc-imx-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/mach-imx/ssi-fiq.S b/arch/arm/mach-imx/ssi-fiq.S
new file mode 100644
index 000000000..a8b93c5f2
--- /dev/null
+++ b/arch/arm/mach-imx/ssi-fiq.S
@@ -0,0 +1,147 @@
+/*
+ * 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 is _intentionally_ not marked as a function symbol
+ * using ENDPROC(). imx_ssi_fiq_start and imx_ssi_fiq_end are used to
+ * mark the function body so that it can be copied to the FIQ vector in
+ * the vectors page. imx_ssi_fiq_start should only be called as the result
+ * of an FIQ: calling it directly will not work.
+ */
+imx_ssi_fiq_start:
+ ldr r12, .L_imx_ssi_fiq_base
+
+ /* TX */
+ ldr r13, .L_imx_ssi_fiq_tx_buffer
+
+ /* shall we send? */
+ ldr r11, [r12, #SSI_SIER]
+ tst r11, #SSI_SIER_TFE0_EN
+ beq 1f
+
+ /* TX FIFO empty? */
+ ldr r11, [r12, #SSI_SISR]
+ tst r11, #SSI_SISR_TFE0
+ beq 1f
+
+ mov r10, #0x10000
+ sub r10, #1
+ and r10, r10, r8 /* r10: current buffer offset */
+
+ add r13, r13, r10
+
+ ldrh r11, [r13]
+ strh r11, [r12, #SSI_STX0]
+
+ ldrh r11, [r13, #2]
+ strh r11, [r12, #SSI_STX0]
+
+ ldrh r11, [r13, #4]
+ strh r11, [r12, #SSI_STX0]
+
+ ldrh r11, [r13, #6]
+ strh r11, [r12, #SSI_STX0]
+
+ add r10, #8
+ lsr r11, r8, #16 /* r11: buffer size */
+ cmp r10, r11
+ lslgt r8, r11, #16
+ addle r8, #8
+1:
+ /* RX */
+
+ /* shall we receive? */
+ ldr r11, [r12, #SSI_SIER]
+ tst r11, #SSI_SIER_RFF0_EN
+ beq 1f
+
+ /* RX FIFO full? */
+ ldr r11, [r12, #SSI_SISR]
+ tst r11, #SSI_SISR_RFF0
+ beq 1f
+
+ ldr r13, .L_imx_ssi_fiq_rx_buffer
+
+ mov r10, #0x10000
+ sub r10, #1
+ and r10, r10, r9 /* r10: current buffer offset */
+
+ add r13, r13, r10
+
+ ldr r11, [r12, #SSI_SACNT]
+ tst r11, #SSI_SACNT_AC97EN
+
+ ldr r11, [r12, #SSI_SRX0]
+ strh r11, [r13]
+
+ ldr r11, [r12, #SSI_SRX0]
+ strh r11, [r13, #2]
+
+ /* dummy read to skip slot 12 */
+ ldrne r11, [r12, #SSI_SRX0]
+
+ ldr r11, [r12, #SSI_SRX0]
+ strh r11, [r13, #4]
+
+ ldr r11, [r12, #SSI_SRX0]
+ strh r11, [r13, #6]
+
+ /* dummy read to skip slot 12 */
+ ldrne r11, [r12, #SSI_SRX0]
+
+ add r10, #8
+ lsr r11, r9, #16 /* r11: buffer size */
+ cmp r10, r11
+ lslgt r9, r11, #16
+ addle r9, #8
+
+1:
+ @ return from FIQ
+ subs pc, lr, #4
+
+ .align
+.L_imx_ssi_fiq_base:
+imx_ssi_fiq_base:
+ .word 0x0
+.L_imx_ssi_fiq_rx_buffer:
+imx_ssi_fiq_rx_buffer:
+ .word 0x0
+.L_imx_ssi_fiq_tx_buffer:
+imx_ssi_fiq_tx_buffer:
+ .word 0x0
+.L_imx_ssi_fiq_end:
+imx_ssi_fiq_end:
+
diff --git a/arch/arm/mach-imx/suspend-imx6.S b/arch/arm/mach-imx/suspend-imx6.S
new file mode 100644
index 000000000..b99987b02
--- /dev/null
+++ b/arch/arm/mach-imx/suspend-imx6.S
@@ -0,0 +1,346 @@
+/*
+ * Copyright 2014 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/linkage.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hardware/cache-l2x0.h>
+#include "hardware.h"
+
+/*
+ * ==================== low level suspend ====================
+ *
+ * Better to follow below rules to use ARM registers:
+ * r0: pm_info structure address;
+ * r1 ~ r4: for saving pm_info members;
+ * r5 ~ r10: free registers;
+ * r11: io base address.
+ *
+ * suspend ocram space layout:
+ * ======================== high address ======================
+ * .
+ * .
+ * .
+ * ^
+ * ^
+ * ^
+ * imx6_suspend code
+ * PM_INFO structure(imx6_cpu_pm_info)
+ * ======================== low address =======================
+ */
+
+/*
+ * Below offsets are based on struct imx6_cpu_pm_info
+ * which defined in arch/arm/mach-imx/pm-imx6q.c, this
+ * structure contains necessary pm info for low level
+ * suspend related code.
+ */
+#define PM_INFO_PBASE_OFFSET 0x0
+#define PM_INFO_RESUME_ADDR_OFFSET 0x4
+#define PM_INFO_DDR_TYPE_OFFSET 0x8
+#define PM_INFO_PM_INFO_SIZE_OFFSET 0xC
+#define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10
+#define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14
+#define PM_INFO_MX6Q_SRC_P_OFFSET 0x18
+#define PM_INFO_MX6Q_SRC_V_OFFSET 0x1C
+#define PM_INFO_MX6Q_IOMUXC_P_OFFSET 0x20
+#define PM_INFO_MX6Q_IOMUXC_V_OFFSET 0x24
+#define PM_INFO_MX6Q_CCM_P_OFFSET 0x28
+#define PM_INFO_MX6Q_CCM_V_OFFSET 0x2C
+#define PM_INFO_MX6Q_GPC_P_OFFSET 0x30
+#define PM_INFO_MX6Q_GPC_V_OFFSET 0x34
+#define PM_INFO_MX6Q_L2_P_OFFSET 0x38
+#define PM_INFO_MX6Q_L2_V_OFFSET 0x3C
+#define PM_INFO_MMDC_IO_NUM_OFFSET 0x40
+#define PM_INFO_MMDC_IO_VAL_OFFSET 0x44
+
+#define MX6Q_SRC_GPR1 0x20
+#define MX6Q_SRC_GPR2 0x24
+#define MX6Q_MMDC_MAPSR 0x404
+#define MX6Q_MMDC_MPDGCTRL0 0x83c
+#define MX6Q_GPC_IMR1 0x08
+#define MX6Q_GPC_IMR2 0x0c
+#define MX6Q_GPC_IMR3 0x10
+#define MX6Q_GPC_IMR4 0x14
+#define MX6Q_CCM_CCR 0x0
+
+ .align 3
+
+ .macro sync_l2_cache
+
+ /* sync L2 cache to drain L2's buffers to DRAM. */
+#ifdef CONFIG_CACHE_L2X0
+ ldr r11, [r0, #PM_INFO_MX6Q_L2_V_OFFSET]
+ mov r6, #0x0
+ str r6, [r11, #L2X0_CACHE_SYNC]
+1:
+ ldr r6, [r11, #L2X0_CACHE_SYNC]
+ ands r6, r6, #0x1
+ bne 1b
+#endif
+
+ .endm
+
+ .macro resume_mmdc
+
+ /* restore MMDC IO */
+ cmp r5, #0x0
+ ldreq r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
+ ldrne r11, [r0, #PM_INFO_MX6Q_IOMUXC_P_OFFSET]
+
+ ldr r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r7, =PM_INFO_MMDC_IO_VAL_OFFSET
+ add r7, r7, r0
+1:
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x4
+ str r9, [r11, r8]
+ subs r6, r6, #0x1
+ bne 1b
+
+ cmp r5, #0x0
+ ldreq r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
+ ldrne r11, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET]
+
+ cmp r3, #IMX_DDR_TYPE_LPDDR2
+ bne 4f
+
+ /* reset read FIFO, RST_RD_FIFO */
+ ldr r7, =MX6Q_MMDC_MPDGCTRL0
+ ldr r6, [r11, r7]
+ orr r6, r6, #(1 << 31)
+ str r6, [r11, r7]
+2:
+ ldr r6, [r11, r7]
+ ands r6, r6, #(1 << 31)
+ bne 2b
+
+ /* reset FIFO a second time */
+ ldr r6, [r11, r7]
+ orr r6, r6, #(1 << 31)
+ str r6, [r11, r7]
+3:
+ ldr r6, [r11, r7]
+ ands r6, r6, #(1 << 31)
+ bne 3b
+4:
+ /* let DDR out of self-refresh */
+ ldr r7, [r11, #MX6Q_MMDC_MAPSR]
+ bic r7, r7, #(1 << 21)
+ str r7, [r11, #MX6Q_MMDC_MAPSR]
+5:
+ ldr r7, [r11, #MX6Q_MMDC_MAPSR]
+ ands r7, r7, #(1 << 25)
+ bne 5b
+
+ /* enable DDR auto power saving */
+ ldr r7, [r11, #MX6Q_MMDC_MAPSR]
+ bic r7, r7, #0x1
+ str r7, [r11, #MX6Q_MMDC_MAPSR]
+
+ .endm
+
+ENTRY(imx6_suspend)
+ ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
+ ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
+ ldr r3, [r0, #PM_INFO_DDR_TYPE_OFFSET]
+ ldr r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
+
+ /*
+ * counting the resume address in iram
+ * to set it in SRC register.
+ */
+ ldr r6, =imx6_suspend
+ ldr r7, =resume
+ sub r7, r7, r6
+ add r8, r1, r4
+ add r9, r8, r7
+
+ /*
+ * make sure TLB contain the addr we want,
+ * as we will access them after MMDC IO floated.
+ */
+
+ ldr r11, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+ ldr r6, [r11, #0x0]
+ ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ ldr r6, [r11, #0x0]
+ ldr r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
+ ldr r6, [r11, #0x0]
+
+ /* use r11 to store the IO address */
+ ldr r11, [r0, #PM_INFO_MX6Q_SRC_V_OFFSET]
+ /* store physical resume addr and pm_info address. */
+ str r9, [r11, #MX6Q_SRC_GPR1]
+ str r1, [r11, #MX6Q_SRC_GPR2]
+
+ /* need to sync L2 cache before DSM. */
+ sync_l2_cache
+
+ ldr r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
+ /*
+ * put DDR explicitly into self-refresh and
+ * disable automatic power savings.
+ */
+ ldr r7, [r11, #MX6Q_MMDC_MAPSR]
+ orr r7, r7, #0x1
+ str r7, [r11, #MX6Q_MMDC_MAPSR]
+
+ /* make the DDR explicitly enter self-refresh. */
+ ldr r7, [r11, #MX6Q_MMDC_MAPSR]
+ orr r7, r7, #(1 << 21)
+ str r7, [r11, #MX6Q_MMDC_MAPSR]
+
+poll_dvfs_set:
+ ldr r7, [r11, #MX6Q_MMDC_MAPSR]
+ ands r7, r7, #(1 << 25)
+ beq poll_dvfs_set
+
+ ldr r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
+ ldr r6, =0x0
+ ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+ ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET
+ add r8, r8, r0
+ /* LPDDR2's last 3 IOs need special setting */
+ cmp r3, #IMX_DDR_TYPE_LPDDR2
+ subeq r7, r7, #0x3
+set_mmdc_io_lpm:
+ ldr r9, [r8], #0x8
+ str r6, [r11, r9]
+ subs r7, r7, #0x1
+ bne set_mmdc_io_lpm
+
+ cmp r3, #IMX_DDR_TYPE_LPDDR2
+ bne set_mmdc_io_lpm_done
+ ldr r6, =0x1000
+ ldr r9, [r8], #0x8
+ str r6, [r11, r9]
+ ldr r9, [r8], #0x8
+ str r6, [r11, r9]
+ ldr r6, =0x80000
+ ldr r9, [r8]
+ str r6, [r11, r9]
+set_mmdc_io_lpm_done:
+
+ /*
+ * mask all GPC interrupts before
+ * enabling the RBC counters to
+ * avoid the counter starting too
+ * early if an interupt is already
+ * pending.
+ */
+ ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ ldr r6, [r11, #MX6Q_GPC_IMR1]
+ ldr r7, [r11, #MX6Q_GPC_IMR2]
+ ldr r8, [r11, #MX6Q_GPC_IMR3]
+ ldr r9, [r11, #MX6Q_GPC_IMR4]
+
+ ldr r10, =0xffffffff
+ str r10, [r11, #MX6Q_GPC_IMR1]
+ str r10, [r11, #MX6Q_GPC_IMR2]
+ str r10, [r11, #MX6Q_GPC_IMR3]
+ str r10, [r11, #MX6Q_GPC_IMR4]
+
+ /*
+ * 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 r11, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+ ldr r10, [r11, #MX6Q_CCM_CCR]
+ bic r10, r10, #(0x3f << 21)
+ orr r10, r10, #(0x20 << 21)
+ str r10, [r11, #MX6Q_CCM_CCR]
+
+ /* enable the counter. */
+ ldr r10, [r11, #MX6Q_CCM_CCR]
+ orr r10, r10, #(0x1 << 27)
+ str r10, [r11, #MX6Q_CCM_CCR]
+
+ /* unmask all the GPC interrupts. */
+ ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+ str r6, [r11, #MX6Q_GPC_IMR1]
+ str r7, [r11, #MX6Q_GPC_IMR2]
+ str r8, [r11, #MX6Q_GPC_IMR3]
+ str r9, [r11, #MX6Q_GPC_IMR4]
+
+ /*
+ * 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 r6, =2000
+rbc_loop:
+ subs r6, r6, #0x1
+ bne rbc_loop
+
+ /* Zzz, enter stop mode */
+ wfi
+ nop
+ nop
+ nop
+ nop
+
+ /*
+ * run to here means there is pending
+ * wakeup source, system should auto
+ * resume, we need to restore MMDC IO first
+ */
+ mov r5, #0x0
+ resume_mmdc
+
+ /* return to suspend finish */
+ ret lr
+
+resume:
+ /* invalidate L1 I-cache first */
+ mov r6, #0x0
+ mcr p15, 0, r6, c7, c5, 0
+ mcr p15, 0, r6, c7, c5, 6
+ /* enable the Icache and branch prediction */
+ mov r6, #0x1800
+ mcr p15, 0, r6, c1, c0, 0
+ isb
+
+ /* get physical resume address from pm_info. */
+ ldr lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
+ /* clear core0's entry and parameter */
+ ldr r11, [r0, #PM_INFO_MX6Q_SRC_P_OFFSET]
+ mov r7, #0x0
+ str r7, [r11, #MX6Q_SRC_GPR1]
+ str r7, [r11, #MX6Q_SRC_GPR2]
+
+ ldr r3, [r0, #PM_INFO_DDR_TYPE_OFFSET]
+ mov r5, #0x1
+ resume_mmdc
+
+ ret lr
+ENDPROC(imx6_suspend)
+
+/*
+ * The following code must assume it is running from physical address
+ * where absolute virtual addresses to the data section have to be
+ * turned into relative ones.
+ */
+
+ENTRY(v7_cpu_resume)
+ bl v7_invalidate_l1
+#ifdef CONFIG_CACHE_L2X0
+ bl l2c310_early_resume
+#endif
+ b cpu_resume
+ENDPROC(v7_cpu_resume)
diff --git a/arch/arm/mach-imx/system.c b/arch/arm/mach-imx/system.c
new file mode 100644
index 000000000..51c35013b
--- /dev/null
+++ b/arch/arm/mach-imx/system.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2006-2007 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/of.h>
+#include <linux/of_address.h>
+
+#include <asm/system_misc.h>
+#include <asm/proc-fns.h>
+#include <asm/mach-types.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "common.h"
+#include "hardware.h"
+
+static void __iomem *wdog_base;
+static struct clk *wdog_clk;
+
+/*
+ * Reset the system. It is called by machine_restart().
+ */
+void mxc_restart(enum reboot_mode mode, const char *cmd)
+{
+ unsigned int wcr_enable;
+
+ if (!wdog_base)
+ goto reset_fallback;
+
+ if (!IS_ERR(wdog_clk))
+ clk_enable(wdog_clk);
+
+ if (cpu_is_mx1())
+ wcr_enable = (1 << 0);
+ else
+ wcr_enable = (1 << 2);
+
+ /* Assert SRS signal */
+ __raw_writew(wcr_enable, wdog_base);
+ /*
+ * Due to imx6q errata ERR004346 (WDOG: WDOG SRS bit requires to be
+ * written twice), we add another two writes to ensure there must be at
+ * least two writes happen in the same one 32kHz clock period. We save
+ * the target check here, since the writes shouldn't be a huge burden
+ * for other platforms.
+ */
+ __raw_writew(wcr_enable, wdog_base);
+ __raw_writew(wcr_enable, wdog_base);
+
+ /* wait for reset to assert... */
+ mdelay(500);
+
+ pr_err("%s: Watchdog reset failed to assert reset\n", __func__);
+
+ /* delay to allow the serial port to show the message */
+ mdelay(50);
+
+reset_fallback:
+ /* we'll take a jump through zero as a poor second */
+ soft_restart(0);
+}
+
+void __init mxc_arch_reset_init(void __iomem *base)
+{
+ wdog_base = base;
+
+ wdog_clk = clk_get_sys("imx2-wdt.0", NULL);
+ if (IS_ERR(wdog_clk))
+ pr_warn("%s: failed to get wdog clock\n", __func__);
+ else
+ clk_prepare(wdog_clk);
+}
+
+#ifdef CONFIG_CACHE_L2X0
+void __init imx_init_l2cache(void)
+{
+ void __iomem *l2x0_base;
+ struct device_node *np;
+ unsigned int val;
+
+ np = of_find_compatible_node(NULL, NULL, "arm,pl310-cache");
+ if (!np)
+ goto out;
+
+ l2x0_base = of_iomap(np, 0);
+ if (!l2x0_base) {
+ of_node_put(np);
+ goto out;
+ }
+
+ /* Configure the L2 PREFETCH and POWER registers */
+ val = readl_relaxed(l2x0_base + L310_PREFETCH_CTRL);
+ val |= 0x70800000;
+ /*
+ * 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_imx6q())
+ val &= ~(1 << 30 | 1 << 23);
+ writel_relaxed(val, l2x0_base + L310_PREFETCH_CTRL);
+
+ iounmap(l2x0_base);
+ of_node_put(np);
+
+out:
+ l2x0_of_init(0, ~0);
+}
+#endif
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
new file mode 100644
index 000000000..15d18e198
--- /dev/null
+++ b/arch/arm/mach-imx/time.c
@@ -0,0 +1,385 @@
+/*
+ * 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 <linux/delay.h>
+#include <linux/err.h>
+#include <linux/sched_clock.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#include <asm/mach/time.h>
+
+#include "common.h"
+#include "hardware.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, MX6 */
+#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_FRR (1 << 9)
+#define V2_TCTL_24MEN (1 << 10)
+#define V2_TPRER_PRE24M 12
+#define V2_IR 0x0c
+#define V2_TSTAT 0x08
+#define V2_TSTAT_OF1 (1 << 0)
+#define V2_TCN 0x24
+#define V2_TCMP 0x10
+
+#define V2_TIMER_RATE_OSC_DIV8 3000000
+
+#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 u64 notrace mxc_read_sched_clock(void)
+{
+ return sched_clock_reg ? __raw_readl(sched_clock_reg) : 0;
+}
+
+static struct delay_timer imx_delay_timer;
+
+static unsigned long imx_read_current_timer(void)
+{
+ return __raw_readl(sched_clock_reg);
+}
+
+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);
+
+ imx_delay_timer.read_current_timer = &imx_read_current_timer;
+ imx_delay_timer.freq = c;
+ register_current_timer_delay(&imx_delay_timer);
+
+ sched_clock_reg = reg;
+
+ sched_clock_register(mxc_read_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",
+ [CLOCK_EVT_MODE_RESUME] = "CLOCK_EVT_MODE_RESUME",
+};
+#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_TIMER | IRQF_IRQPOLL,
+ .handler = mxc_timer_interrupt,
+};
+
+static struct clock_event_device clockevent_mxc = {
+ .name = "mxc_timer1",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .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)
+{
+ if (timer_is_v2())
+ clockevent_mxc.set_next_event = v2_set_next_event;
+
+ clockevent_mxc.cpumask = cpumask_of(0);
+ clockevents_config_and_register(&clockevent_mxc,
+ clk_get_rate(timer_clk),
+ 0xff, 0xfffffffe);
+
+ return 0;
+}
+
+static void __init _mxc_timer_init(int irq,
+ struct clk *clk_per, struct clk *clk_ipg)
+{
+ uint32_t tctl_val;
+
+ if (IS_ERR(clk_per)) {
+ pr_err("i.MX timer: unable to get clk\n");
+ return;
+ }
+
+ if (!IS_ERR(clk_ipg))
+ clk_prepare_enable(clk_ipg);
+
+ clk_prepare_enable(clk_per);
+
+ /*
+ * 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()) {
+ tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
+ if (clk_get_rate(clk_per) == V2_TIMER_RATE_OSC_DIV8) {
+ tctl_val |= V2_TCTL_CLK_OSC_DIV8;
+ if (cpu_is_imx6dl() || cpu_is_imx6sx()) {
+ /* 24 / 8 = 3 MHz */
+ __raw_writel(7 << V2_TPRER_PRE24M,
+ timer_base + MXC_TPRER);
+ tctl_val |= V2_TCTL_24MEN;
+ }
+ } else {
+ tctl_val |= V2_TCTL_CLK_PER;
+ }
+ } 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(clk_per);
+ mxc_clockevent_init(clk_per);
+
+ /* Make irqs happen */
+ setup_irq(irq, &mxc_timer_irq);
+}
+
+void __init mxc_timer_init(void __iomem *base, int irq)
+{
+ struct clk *clk_per = clk_get_sys("imx-gpt.0", "per");
+ struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
+
+ timer_base = base;
+
+ _mxc_timer_init(irq, clk_per, clk_ipg);
+}
+
+static void __init mxc_timer_init_dt(struct device_node *np)
+{
+ struct clk *clk_per, *clk_ipg;
+ int irq;
+
+ if (timer_base)
+ return;
+
+ timer_base = of_iomap(np, 0);
+ WARN_ON(!timer_base);
+ irq = irq_of_parse_and_map(np, 0);
+
+ clk_ipg = of_clk_get_by_name(np, "ipg");
+
+ /* Try osc_per first, and fall back to per otherwise */
+ clk_per = of_clk_get_by_name(np, "osc_per");
+ if (IS_ERR(clk_per))
+ clk_per = of_clk_get_by_name(np, "per");
+
+ _mxc_timer_init(irq, clk_per, clk_ipg);
+}
+CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(mx25_timer, "fsl,imx25-gpt", mxc_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(mx50_timer, "fsl,imx50-gpt", mxc_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(mx51_timer, "fsl,imx51-gpt", mxc_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(mx53_timer, "fsl,imx53-gpt", mxc_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(mx6q_timer, "fsl,imx6q-gpt", mxc_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(mx6sl_timer, "fsl,imx6sl-gpt", mxc_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(mx6sx_timer, "fsl,imx6sx-gpt", mxc_timer_init_dt);
diff --git a/arch/arm/mach-imx/tzic.c b/arch/arm/mach-imx/tzic.c
new file mode 100644
index 000000000..4de65eeda
--- /dev/null
+++ b/arch/arm/mach-imx/tzic.c
@@ -0,0 +1,226 @@
+/*
+ * 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 <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/mach/irq.h>
+#include <asm/exception.h>
+
+#include "common.h"
+#include "hardware.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_HIPND(i) (0x0D80+ ((i) << 2)) /* 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 */
+
+static void __iomem *tzic_base;
+static struct irq_domain *domain;
+
+#define TZIC_NUM_IRQS 128
+
+#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;
+}
+#else
+#define tzic_set_irq_fiq NULL
+#endif
+
+#ifdef CONFIG_PM
+static void tzic_irq_suspend(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ int idx = d->hwirq >> 5;
+
+ __raw_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx));
+}
+
+static void tzic_irq_resume(struct irq_data *d)
+{
+ int idx = d->hwirq >> 5;
+
+ __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(idx)),
+ tzic_base + TZIC_WAKEUP0(idx));
+}
+
+#else
+#define tzic_irq_suspend NULL
+#define tzic_irq_resume NULL
+#endif
+
+static struct mxc_extra_irq tzic_extra_irq = {
+#ifdef CONFIG_FIQ
+ .set_irq_fiq = tzic_set_irq_fiq,
+#endif
+};
+
+static __init void tzic_init_gc(int idx, unsigned int irq_start)
+{
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+
+ gc = irq_alloc_generic_chip("tzic", 1, irq_start, tzic_base,
+ handle_level_irq);
+ gc->private = &tzic_extra_irq;
+ gc->wake_enabled = IRQ_MSK(32);
+
+ ct = gc->chip_types;
+ ct->chip.irq_mask = irq_gc_mask_disable_reg;
+ ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
+ ct->chip.irq_set_wake = irq_gc_set_wake;
+ ct->chip.irq_suspend = tzic_irq_suspend;
+ ct->chip.irq_resume = tzic_irq_resume;
+ ct->regs.disable = TZIC_ENCLEAR0(idx);
+ ct->regs.enable = TZIC_ENSET0(idx);
+
+ irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0);
+}
+
+static void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs)
+{
+ u32 stat;
+ int i, irqofs, handled;
+
+ do {
+ handled = 0;
+
+ for (i = 0; i < 4; i++) {
+ stat = __raw_readl(tzic_base + TZIC_HIPND(i)) &
+ __raw_readl(tzic_base + TZIC_INTSEC0(i));
+
+ while (stat) {
+ handled = 1;
+ irqofs = fls(stat) - 1;
+ handle_domain_irq(domain, irqofs + i * 32, regs);
+ stat &= ~(1 << irqofs);
+ }
+ }
+ } while (handled);
+}
+
+/*
+ * 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)
+{
+ struct device_node *np;
+ int irq_base;
+ int i;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,tzic");
+ tzic_base = of_iomap(np, 0);
+ WARN_ON(!tzic_base);
+
+ /* 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 */
+
+ irq_base = irq_alloc_descs(-1, 0, TZIC_NUM_IRQS, numa_node_id());
+ WARN_ON(irq_base < 0);
+
+ domain = irq_domain_add_legacy(np, TZIC_NUM_IRQS, irq_base, 0,
+ &irq_domain_simple_ops, NULL);
+ WARN_ON(!domain);
+
+ for (i = 0; i < 4; i++, irq_base += 32)
+ tzic_init_gc(i, irq_base);
+
+ set_handle_irq(tzic_handle_irq);
+
+#ifdef CONFIG_FIQ
+ /* Initialize FIQ */
+ init_FIQ(FIQ_START);
+#endif
+
+ pr_info("TrustZone Interrupt Controller (TZIC) initialized\n");
+}
+
+/**
+ * tzic_enable_wake() - enable wakeup interrupt
+ *
+ * @return 0 if successful; non-zero otherwise
+ *
+ * This function provides an interrupt synchronization point that is required
+ * by tzic enabled platforms before entering imx specific low power modes (ie,
+ * those low power modes beyond the WAIT_CLOCKED basic ARM WFI only mode).
+ */
+int tzic_enable_wake(void)
+{
+ unsigned int i;
+
+ __raw_writel(1, tzic_base + TZIC_DSMINT);
+ if (unlikely(__raw_readl(tzic_base + TZIC_DSMINT) == 0))
+ return -EAGAIN;
+
+ for (i = 0; i < 4; i++)
+ __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(i)),
+ tzic_base + TZIC_WAKEUP0(i));
+
+ return 0;
+}
diff --git a/arch/arm/mach-imx/ulpi.h b/arch/arm/mach-imx/ulpi.h
new file mode 100644
index 000000000..23f5c0349
--- /dev/null
+++ b/arch/arm/mach-imx/ulpi.h
@@ -0,0 +1,19 @@
+#ifndef __MACH_ULPI_H
+#define __MACH_ULPI_H
+
+#include <linux/usb/ulpi.h>
+
+#ifdef CONFIG_USB_ULPI_VIEWPORT
+static inline struct usb_phy *imx_otg_ulpi_create(unsigned int flags)
+{
+ return otg_ulpi_create(&ulpi_viewport_access_ops, flags);
+}
+#else
+static inline struct usb_phy *imx_otg_ulpi_create(unsigned int flags)
+{
+ return NULL;
+}
+#endif
+
+#endif /* __MACH_ULPI_H */
+
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
new file mode 100644
index 000000000..02d083489
--- /dev/null
+++ b/arch/arm/mach-integrator/Kconfig
@@ -0,0 +1,68 @@
+config ARCH_INTEGRATOR
+ bool "ARM Ltd. Integrator family" if (ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V6)
+ select ARM_AMBA
+ select ARM_PATCH_PHYS_VIRT if MMU
+ select AUTO_ZRELADDR
+ select COMMON_CLK
+ select COMMON_CLK_VERSATILE
+ select GENERIC_CLOCKEVENTS
+ select HAVE_TCM
+ select ICST
+ select MFD_SYSCON
+ select MULTI_IRQ_HANDLER
+ select PLAT_VERSATILE
+ select POWER_RESET
+ select POWER_RESET_VERSATILE
+ select POWER_SUPPLY
+ select SOC_INTEGRATOR_CM
+ select SPARSE_IRQ
+ select USE_OF
+ select VERSATILE_FPGA_IRQ
+ help
+ Support for ARM's Integrator platform.
+
+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
+ select SERIAL_AMBA_PL010 if TTY
+ select SERIAL_AMBA_PL010_CONSOLE if TTY
+ select SOC_BUS
+ 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 SERIAL_AMBA_PL011 if TTY
+ select SERIAL_AMBA_PL011_CONSOLE if TTY
+ select SOC_BUS
+ help
+ Include support for the ARM(R) Integrator CP platform.
+
+config ARCH_CINTEGRATOR
+ bool
+
+config INTEGRATOR_IMPD1
+ bool "Include support for Integrator/IM-PD1"
+ depends on ARCH_INTEGRATOR_AP
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_VIC
+ select GPIO_PL061 if GPIOLIB
+ 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 000000000..1ebe45356
--- /dev/null
+++ b/arch/arm/mach-integrator/Makefile
@@ -0,0 +1,12 @@
+#
+# 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_PCI) += pci_v3.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 000000000..ff0a4b5b0
--- /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/cm.h b/arch/arm/mach-integrator/cm.h
new file mode 100644
index 000000000..5b8ba8247
--- /dev/null
+++ b/arch/arm/mach-integrator/cm.h
@@ -0,0 +1,40 @@
+/*
+ * access the core module control register.
+ */
+u32 cm_get(void);
+void cm_control(u32, u32);
+
+struct device_node;
+void cm_init(void);
+void cm_clear_irqs(void);
+
+#define CM_CTRL_LED (1 << 0)
+#define CM_CTRL_nMBDET (1 << 1)
+#define CM_CTRL_REMAP (1 << 2)
+
+/*
+ * 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/common.h b/arch/arm/mach-integrator/common.h
new file mode 100644
index 000000000..96c9dc56c
--- /dev/null
+++ b/arch/arm/mach-integrator/common.h
@@ -0,0 +1,6 @@
+#include <linux/reboot.h>
+#include <linux/amba/serial.h>
+extern struct amba_pl010_data ap_uart_data;
+void integrator_init_early(void);
+int integrator_init(bool is_cp);
+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 000000000..948872a41
--- /dev/null
+++ b/arch/arm/mach-integrator/core.c
@@ -0,0 +1,99 @@
+/*
+ * 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/export.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/amba/bus.h>
+#include <linux/amba/serial.h>
+#include <linux/io.h>
+#include <linux/stat.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/time.h>
+#include <asm/pgtable.h>
+
+#include "hardware.h"
+#include "cm.h"
+#include "common.h"
+
+static DEFINE_RAW_SPINLOCK(cm_lock);
+static void __iomem *cm_base;
+
+/**
+ * cm_get - get the value from the CM_CTRL register
+ */
+u32 cm_get(void)
+{
+ return readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET);
+}
+
+/**
+ * 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;
+
+ raw_spin_lock_irqsave(&cm_lock, flags);
+ val = readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET) & ~mask;
+ writel(val | set, cm_base + INTEGRATOR_HDR_CTRL_OFFSET);
+ raw_spin_unlock_irqrestore(&cm_lock, flags);
+}
+
+void cm_clear_irqs(void)
+{
+ /* disable core module IRQs */
+ writel(0xffffffffU, cm_base + INTEGRATOR_HDR_IC_OFFSET +
+ IRQ_ENABLE_CLEAR);
+}
+
+static const struct of_device_id cm_match[] = {
+ { .compatible = "arm,core-module-integrator"},
+ { },
+};
+
+void cm_init(void)
+{
+ struct device_node *cm = of_find_matching_node(NULL, cm_match);
+
+ if (!cm) {
+ pr_crit("no core module node found in device tree\n");
+ return;
+ }
+ cm_base = of_iomap(cm, 0);
+ if (!cm_base) {
+ pr_crit("could not remap core module\n");
+ return;
+ }
+ cm_clear_irqs();
+}
+
+/*
+ * 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/hardware.h b/arch/arm/mach-integrator/hardware.h
new file mode 100644
index 000000000..857ca5f8b
--- /dev/null
+++ b/arch/arm/mach-integrator/hardware.h
@@ -0,0 +1,354 @@
+/*
+ * This file contains the hardware definitions of the Integrator.
+ *
+ * Copyright (C) 1998-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 INTEGRATOR_HARDWARE_H
+#define INTEGRATOR_HARDWARE_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
+
+/* 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))
+
+/*
+ * 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_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 */
+
+/* PS2 Keyboard interface */
+#define KMI0_BASE INTEGRATOR_KBD_BASE
+
+/* PS2 Mouse interface */
+#define KMI1_BASE INTEGRATOR_MOUSE_BASE
+
+/*
+ * 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
+
+
+/*
+ * 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 INTEGRATOR_CSR_BASE 0x10000000
+#define INTEGRATOR_CSR_SIZE 0x10000000
+
+#endif /* INTEGRATOR_HARDWARE_H */
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
new file mode 100644
index 000000000..38b0da300
--- /dev/null
+++ b/arch/arm/mach-integrator/impd1.c
@@ -0,0 +1,478 @@
+/*
+ * 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/amba/mmci.h>
+#include <linux/amba/pl061.h>
+#include <linux/io.h>
+#include <linux/platform_data/clk-integrator.h>
+#include <linux/slab.h>
+#include <linux/irqchip/arm-vic.h>
+#include <linux/gpio/machine.h>
+
+#include <asm/sizes.h>
+#include "lm.h"
+#include "impd1.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;
+ void __iomem *vic_base;
+};
+
+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);
+
+/*
+ * MMC support
+ */
+static struct mmci_platform_data mmc_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+};
+
+/*
+ * 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 = 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,
+ .platform_data = &mmc_data,
+ }, {
+ .offset = 0x00800000,
+ .irq = { 9 },
+ .id = 0x00041041,
+ }, {
+ .offset = 0x01000000,
+ .irq = { 11 },
+ .id = 0x00041110,
+ .platform_data = &impd1_clcd_data,
+ }
+};
+
+/*
+ * Valid IRQs: 0 thru 9 and 11, 10 unused.
+ */
+#define IMPD1_VALID_IRQS 0x00000bffU
+
+/*
+ * As this module is bool, it is OK to have this as __init_refok() - no
+ * probe calls will be done after the initial system bootup, as devices
+ * are discovered as part of the machine startup.
+ */
+static int __init_refok impd1_probe(struct lm_device *dev)
+{
+ struct impd1_module *impd1;
+ int irq_base;
+ int i;
+
+ if (dev->id != module_id)
+ return -EINVAL;
+
+ if (!devm_request_mem_region(&dev->dev, dev->resource.start,
+ SZ_4K, "LM registers"))
+ return -EBUSY;
+
+ impd1 = devm_kzalloc(&dev->dev, sizeof(struct impd1_module),
+ GFP_KERNEL);
+ if (!impd1)
+ return -ENOMEM;
+
+ impd1->base = devm_ioremap(&dev->dev, dev->resource.start, SZ_4K);
+ if (!impd1->base)
+ return -ENOMEM;
+
+ integrator_impd1_clk_init(impd1->base, dev->id);
+
+ if (!devm_request_mem_region(&dev->dev,
+ dev->resource.start + 0x03000000,
+ SZ_4K, "VIC"))
+ return -EBUSY;
+
+ impd1->vic_base = devm_ioremap(&dev->dev,
+ dev->resource.start + 0x03000000,
+ SZ_4K);
+ if (!impd1->vic_base)
+ return -ENOMEM;
+
+ irq_base = vic_init_cascaded(impd1->vic_base, dev->irq,
+ IMPD1_VALID_IRQS, 0);
+
+ lm_set_drvdata(dev, impd1);
+
+ dev_info(&dev->dev, "IM-PD1 found at 0x%08lx\n",
+ (unsigned long)dev->resource.start);
+
+ for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) {
+ struct impd1_device *idev = impd1_devs + i;
+ struct amba_device *d;
+ unsigned long pc_base;
+ char devname[32];
+ int irq1 = idev->irq[0];
+ int irq2 = idev->irq[1];
+
+ /* Translate IRQs to IM-PD1 local numberspace */
+ if (irq1)
+ irq1 += irq_base;
+ if (irq2)
+ irq2 += irq_base;
+
+ pc_base = dev->resource.start + idev->offset;
+ snprintf(devname, 32, "lm%x:%5.5lx", dev->id, idev->offset >> 12);
+
+ /* Add GPIO descriptor lookup table for the PL061 block */
+ if (idev->offset == 0x00400000) {
+ struct gpiod_lookup_table *lookup;
+ char *chipname;
+ char *mmciname;
+
+ lookup = devm_kzalloc(&dev->dev,
+ sizeof(*lookup) + 3 * sizeof(struct gpiod_lookup),
+ GFP_KERNEL);
+ chipname = devm_kstrdup(&dev->dev, devname, GFP_KERNEL);
+ mmciname = kasprintf(GFP_KERNEL, "lm%x:00700", dev->id);
+ lookup->dev_id = mmciname;
+ /*
+ * Offsets on GPIO block 1:
+ * 3 = MMC WP (write protect)
+ * 4 = MMC CD (card detect)
+ *
+ * Offsets on GPIO block 2:
+ * 0 = Up key
+ * 1 = Down key
+ * 2 = Left key
+ * 3 = Right key
+ * 4 = Key lower left
+ * 5 = Key lower right
+ */
+ /* We need the two MMCI GPIO entries */
+ lookup->table[0].chip_label = chipname;
+ lookup->table[0].chip_hwnum = 3;
+ lookup->table[0].con_id = "wp";
+ lookup->table[1].chip_label = chipname;
+ lookup->table[1].chip_hwnum = 4;
+ lookup->table[1].con_id = "cd";
+ lookup->table[1].flags = GPIO_ACTIVE_LOW;
+ gpiod_add_lookup_table(lookup);
+ }
+
+ d = amba_ahb_device_add_res(&dev->dev, devname, pc_base, SZ_4K,
+ irq1, irq2,
+ idev->platform_data, idev->id,
+ &dev->resource);
+ if (IS_ERR(d)) {
+ dev_err(&dev->dev, "unable to register device: %ld\n", PTR_ERR(d));
+ continue;
+ }
+ }
+
+ return 0;
+}
+
+static int impd1_remove_one(struct device *dev, void *data)
+{
+ device_unregister(dev);
+ return 0;
+}
+
+static void impd1_remove(struct lm_device *dev)
+{
+ device_for_each_child(&dev->dev, NULL, impd1_remove_one);
+ integrator_impd1_clk_exit(dev->id);
+
+ lm_set_drvdata(dev, NULL);
+}
+
+static struct lm_driver impd1_driver = {
+ .drv = {
+ .name = "impd1",
+ /*
+ * As we're dropping the probe() function, suppress driver
+ * binding from sysfs.
+ */
+ .suppress_bind_attrs = true,
+ },
+ .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/impd1.h b/arch/arm/mach-integrator/impd1.h
new file mode 100644
index 000000000..76de4dc9b
--- /dev/null
+++ b/arch/arm/mach-integrator/impd1.h
@@ -0,0 +1,14 @@
+#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/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
new file mode 100644
index 000000000..30003ba44
--- /dev/null
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -0,0 +1,342 @@
+/*
+ * 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/io.h>
+#include <linux/irqchip.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_data/clk-integrator.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/stat.h>
+#include <linux/termios.h>
+
+#include <asm/hardware/arm_timer.h>
+#include <asm/setup.h>
+#include <asm/param.h> /* HZ */
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include "hardware.h"
+#include "cm.h"
+#include "common.h"
+#include "pci_v3.h"
+#include "lm.h"
+
+/* Base address to the AP system controller */
+void __iomem *ap_syscon_base;
+/* Base address to the external bus interface */
+static void __iomem *ebi_base;
+
+
+/*
+ * 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)
+
+/*
+ * Logical Physical
+ * ef000000 Cache flush
+ * f1100000 11000000 System controller 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 __maybe_unused = {
+ {
+ .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_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
+ }
+};
+
+static void __init ap_map_io(void)
+{
+ iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc));
+ pci_v3_early_init();
+}
+
+#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 */
+ cm_clear_irqs();
+ 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.
+ */
+static int ap_flash_init(struct platform_device *dev)
+{
+ u32 tmp;
+
+ writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP,
+ ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
+
+ tmp = readl(ebi_base + INTEGRATOR_EBI_CSR1_OFFSET) |
+ INTEGRATOR_EBI_WRITE_ENABLE;
+ writel(tmp, ebi_base + INTEGRATOR_EBI_CSR1_OFFSET);
+
+ if (!(readl(ebi_base + INTEGRATOR_EBI_CSR1_OFFSET)
+ & INTEGRATOR_EBI_WRITE_ENABLE)) {
+ writel(0xa05f, ebi_base + INTEGRATOR_EBI_LOCK_OFFSET);
+ writel(tmp, ebi_base + INTEGRATOR_EBI_CSR1_OFFSET);
+ writel(0, ebi_base + INTEGRATOR_EBI_LOCK_OFFSET);
+ }
+ return 0;
+}
+
+static void ap_flash_exit(struct platform_device *dev)
+{
+ u32 tmp;
+
+ writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP,
+ ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
+
+ tmp = readl(ebi_base + INTEGRATOR_EBI_CSR1_OFFSET) &
+ ~INTEGRATOR_EBI_WRITE_ENABLE;
+ writel(tmp, ebi_base + INTEGRATOR_EBI_CSR1_OFFSET);
+
+ if (readl(ebi_base + INTEGRATOR_EBI_CSR1_OFFSET) &
+ INTEGRATOR_EBI_WRITE_ENABLE) {
+ writel(0xa05f, ebi_base + INTEGRATOR_EBI_LOCK_OFFSET);
+ writel(tmp, ebi_base + INTEGRATOR_EBI_CSR1_OFFSET);
+ writel(0, ebi_base + INTEGRATOR_EBI_LOCK_OFFSET);
+ }
+}
+
+static void ap_flash_set_vpp(struct platform_device *pdev, int on)
+{
+ if (on)
+ writel(INTEGRATOR_SC_CTRL_nFLVPPEN,
+ ap_syscon_base + INTEGRATOR_SC_CTRLS_OFFSET);
+ else
+ writel(INTEGRATOR_SC_CTRL_nFLVPPEN,
+ ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
+}
+
+static struct physmap_flash_data ap_flash_data = {
+ .width = 4,
+ .init = ap_flash_init,
+ .exit = ap_flash_exit,
+ .set_vpp = ap_flash_set_vpp,
+};
+
+/*
+ * For the PL010 found in the Integrator/AP some of the UART control is
+ * implemented in the system controller and accessed using a callback
+ * from the driver.
+ */
+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;
+ u32 phybase = dev->res.start;
+
+ if (phybase == INTEGRATOR_UART0_BASE) {
+ /* UART0 */
+ rts_mask = 1 << 4;
+ dtr_mask = 1 << 5;
+ } else {
+ /* UART1 */
+ 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, ap_syscon_base + INTEGRATOR_SC_CTRLS_OFFSET);
+ __raw_writel(ctrlc, ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
+}
+
+struct amba_pl010_data ap_uart_data = {
+ .set_mctrl = integrator_uart_set_mctrl,
+};
+
+void __init ap_init_early(void)
+{
+}
+
+static void __init ap_init_irq_of(void)
+{
+ cm_init();
+ irqchip_init();
+}
+
+/* For the Device Tree, add in the UART callbacks as AUXDATA */
+static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE,
+ "rtc", NULL),
+ OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE,
+ "uart0", &ap_uart_data),
+ OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE,
+ "uart1", &ap_uart_data),
+ OF_DEV_AUXDATA("arm,primecell", KMI0_BASE,
+ "kmi0", NULL),
+ OF_DEV_AUXDATA("arm,primecell", KMI1_BASE,
+ "kmi1", NULL),
+ OF_DEV_AUXDATA("cfi-flash", INTEGRATOR_FLASH_BASE,
+ "physmap-flash", &ap_flash_data),
+ { /* sentinel */ },
+};
+
+static const struct of_device_id ap_syscon_match[] = {
+ { .compatible = "arm,integrator-ap-syscon"},
+ { },
+};
+
+static const struct of_device_id ebi_match[] = {
+ { .compatible = "arm,external-bus-interface"},
+ { },
+};
+
+static void __init ap_init_of(void)
+{
+ unsigned long sc_dec;
+ struct device_node *syscon;
+ struct device_node *ebi;
+ int i;
+
+ syscon = of_find_matching_node(NULL, ap_syscon_match);
+ if (!syscon)
+ return;
+ ebi = of_find_matching_node(NULL, ebi_match);
+ if (!ebi)
+ return;
+
+ ap_syscon_base = of_iomap(syscon, 0);
+ if (!ap_syscon_base)
+ return;
+ ebi_base = of_iomap(ebi, 0);
+ if (!ebi_base)
+ return;
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ ap_auxdata_lookup, NULL);
+
+ sc_dec = readl(ap_syscon_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_of_parse_and_map(syscon, i);
+ lmdev->id = i;
+
+ lm_device_register(lmdev);
+ }
+}
+
+static const char * ap_dt_board_compat[] = {
+ "arm,integrator-ap",
+ NULL,
+};
+
+DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)")
+ .reserve = integrator_reserve,
+ .map_io = ap_map_io,
+ .init_early = ap_init_early,
+ .init_irq = ap_init_irq_of,
+ .init_machine = ap_init_of,
+ .dt_compat = ap_dt_board_compat,
+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 000000000..b5fb71a36
--- /dev/null
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -0,0 +1,301 @@
+/*
+ * 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/device.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/kmi.h>
+#include <linux/amba/clcd.h>
+#include <linux/platform_data/video-clcd-versatile.h>
+#include <linux/amba/mmci.h>
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/gfp.h>
+#include <linux/mtd/physmap.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/sched_clock.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include "hardware.h"
+#include "cm.h"
+#include "common.h"
+
+/* Base address to the CP controller */
+static void __iomem *intcp_con_base;
+
+#define INTCP_PA_FLASH_BASE 0x24000000
+
+#define INTCP_PA_CLCD_BASE 0xc0000000
+
+#define INTCP_FLASHPROG 0x04
+#define CINTEGRATOR_FLASHPROG_FLVPPEN (1 << 0)
+#define CINTEGRATOR_FLASHPROG_FLWREN (1 << 1)
+
+/*
+ * Logical Physical
+ * f1000000 10000000 Core module 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
+ */
+
+static struct map_desc intcp_io_desc[] __initdata __maybe_unused = {
+ {
+ .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_HDR_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_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
+ }
+};
+
+static void __init intcp_map_io(void)
+{
+ iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));
+}
+
+/*
+ * Flash handling.
+ */
+static int intcp_flash_init(struct platform_device *dev)
+{
+ u32 val;
+
+ val = readl(intcp_con_base + INTCP_FLASHPROG);
+ val |= CINTEGRATOR_FLASHPROG_FLWREN;
+ writel(val, intcp_con_base + INTCP_FLASHPROG);
+
+ return 0;
+}
+
+static void intcp_flash_exit(struct platform_device *dev)
+{
+ u32 val;
+
+ val = readl(intcp_con_base + INTCP_FLASHPROG);
+ val &= ~(CINTEGRATOR_FLASHPROG_FLVPPEN|CINTEGRATOR_FLASHPROG_FLWREN);
+ writel(val, intcp_con_base + INTCP_FLASHPROG);
+}
+
+static void intcp_flash_set_vpp(struct platform_device *pdev, int on)
+{
+ u32 val;
+
+ val = readl(intcp_con_base + INTCP_FLASHPROG);
+ if (on)
+ val |= CINTEGRATOR_FLASHPROG_FLVPPEN;
+ else
+ val &= ~CINTEGRATOR_FLASHPROG_FLVPPEN;
+ writel(val, intcp_con_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,
+};
+
+/*
+ * 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, intcp_con_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,
+};
+
+/*
+ * 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
+ | CM_CTRL_LCDEN0 | CM_CTRL_LCDEN1;
+
+ 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,
+};
+
+#define REFCOUNTER (__io_address(INTEGRATOR_HDR_BASE) + 0x28)
+
+static u64 notrace intcp_read_sched_clock(void)
+{
+ return readl(REFCOUNTER);
+}
+
+static void __init intcp_init_early(void)
+{
+ sched_clock_register(intcp_read_sched_clock, 32, 24000000);
+}
+
+static void __init intcp_init_irq_of(void)
+{
+ cm_init();
+ irqchip_init();
+}
+
+/*
+ * For the Device Tree, add in the UART, MMC and CLCD specifics as AUXDATA
+ * and enforce the bus names since these are used for clock lookups.
+ */
+static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE,
+ "rtc", NULL),
+ OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE,
+ "uart0", NULL),
+ OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE,
+ "uart1", NULL),
+ OF_DEV_AUXDATA("arm,primecell", KMI0_BASE,
+ "kmi0", NULL),
+ OF_DEV_AUXDATA("arm,primecell", KMI1_BASE,
+ "kmi1", NULL),
+ OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_CP_MMC_BASE,
+ "mmci", &mmc_data),
+ OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_CP_AACI_BASE,
+ "aaci", &mmc_data),
+ OF_DEV_AUXDATA("arm,primecell", INTCP_PA_CLCD_BASE,
+ "clcd", &clcd_data),
+ OF_DEV_AUXDATA("cfi-flash", INTCP_PA_FLASH_BASE,
+ "physmap-flash", &intcp_flash_data),
+ { /* sentinel */ },
+};
+
+static const struct of_device_id intcp_syscon_match[] = {
+ { .compatible = "arm,integrator-cp-syscon"},
+ { },
+};
+
+static void __init intcp_init_of(void)
+{
+ struct device_node *cpcon;
+
+ cpcon = of_find_matching_node(NULL, intcp_syscon_match);
+ if (!cpcon)
+ return;
+
+ intcp_con_base = of_iomap(cpcon, 0);
+ if (!intcp_con_base)
+ return;
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ intcp_auxdata_lookup, NULL);
+}
+
+static const char * intcp_dt_board_compat[] = {
+ "arm,integrator-cp",
+ NULL,
+};
+
+DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)")
+ .reserve = integrator_reserve,
+ .map_io = intcp_map_io,
+ .init_early = intcp_init_early,
+ .init_irq = intcp_init_irq_of,
+ .init_machine = intcp_init_of,
+ .dt_compat = intcp_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-integrator/lm.c b/arch/arm/mach-integrator/lm.c
new file mode 100644
index 000000000..3f9e9f043
--- /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 "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/lm.h b/arch/arm/mach-integrator/lm.h
new file mode 100644
index 000000000..28186b6f2
--- /dev/null
+++ b/arch/arm/mach-integrator/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/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
new file mode 100644
index 000000000..2565f0e7b
--- /dev/null
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -0,0 +1,900 @@
+/*
+ * 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 <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <video/vga.h>
+
+#include <asm/mach/map.h>
+#include <asm/signal.h>
+#include <asm/mach/pci.h>
+#include <asm/irq_regs.h>
+
+#include "pci_v3.h"
+#include "hardware.h"
+
+/*
+ * 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 /* 256M */
+#define PHYS_PCI_PRE_BASE 0x50000000 /* 256M */
+#define PHYS_PCI_IO_BASE 0x60000000 /* 16M */
+#define PHYS_PCI_CONFIG_BASE 0x61000000 /* 16M */
+#define PHYS_PCI_V3_BASE 0x62000000 /* 64K */
+
+#define PCI_MEMORY_VADDR IOMEM(0xe8000000)
+#define PCI_CONFIG_VADDR IOMEM(0xec000000)
+
+/*
+ * 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)
+
+/*
+ * 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.
+ */
+
+/* Filled in by probe */
+static void __iomem *pci_v3_base;
+/* CPU side memory ranges */
+static struct resource conf_mem; /* FIXME: remap this instead of static map */
+static struct resource io_mem;
+static struct resource non_mem;
+static struct resource pre_mem;
+/* PCI side memory ranges */
+static u64 non_mem_pci;
+static u64 non_mem_pci_sz;
+static u64 pre_mem_pci;
+static u64 pre_mem_pci_sz;
+
+// V3 access routines
+#define v3_writeb(o,v) __raw_writeb(v, pci_v3_base + (unsigned int)(o))
+#define v3_readb(o) (__raw_readb(pci_v3_base + (unsigned int)(o)))
+
+#define v3_writew(o,v) __raw_writew(v, pci_v3_base + (unsigned int)(o))
+#define v3_readw(o) (__raw_readw(pci_v3_base + (unsigned int)(o)))
+
+#define v3_writel(o,v) __raw_writel(v, pci_v3_base + (unsigned int)(o))
+#define v3_readl(o) (__raw_readl(pci_v3_base + (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
+ *
+ */
+
+#undef V3_LB_BASE_PREFETCH
+#define V3_LB_BASE_PREFETCH 0
+
+static void __iomem *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
+ */
+ BUG_ON(offset > 255);
+ BUG_ON(busnr > 255);
+ BUG_ON(devfn > 255);
+
+ 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(non_mem.start) |
+ 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(conf_mem.start) |
+ 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(pre_mem.start) |
+ V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
+ V3_LB_BASE_ENABLE);
+ v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(pre_mem_pci) |
+ 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(non_mem.start) |
+ 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)
+{
+ int ret = pci_generic_config_read(bus, devfn, where, size, val);
+ v3_close_config_window();
+ return ret;
+}
+
+static int v3_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 val)
+{
+ int ret = pci_generic_config_write(bus, devfn, where, size, val);
+ v3_close_config_window();
+ return ret;
+}
+
+static struct pci_ops pci_v3_ops = {
+ .map_bus = v3_open_config_window,
+ .read = v3_read_config,
+ .write = v3_write_config,
+};
+
+static int __init pci_v3_setup_resources(struct pci_sys_data *sys)
+{
+ 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;
+ }
+
+ /*
+ * the mem resource for this bus
+ * the prefetch mem resource for this bus
+ */
+ pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset);
+ pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset);
+
+ 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. ;)
+ */
+static void __iomem *ap_syscon_base;
+#define INTEGRATOR_SC_PCIENABLE_OFFSET 0x18
+#define INTEGRATOR_SC_LBFADDR_OFFSET 0x20
+#define INTEGRATOR_SC_LBFCODE_OFFSET 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(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET), __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255,
+ v3_readb(V3_LB_ISTAT));
+ printk(KERN_DEBUG "%s", buf);
+#endif
+
+ v3_writeb(V3_LB_ISTAT, 0);
+ __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
+
+ /*
+ * 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 irq, 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, pc, instr,
+ __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET),
+ __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255,
+ v3_readb(V3_LB_ISTAT));
+ printascii(buf);
+#endif
+
+ v3_writew(V3_PCI_STAT, 0xf000);
+ v3_writeb(V3_LB_ISTAT, 0);
+ __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
+
+#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;
+}
+
+static int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
+{
+ int ret = 0;
+
+ if (!ap_syscon_base)
+ return -EINVAL;
+
+ if (nr == 0) {
+ sys->mem_offset = non_mem.start;
+ ret = pci_v3_setup_resources(sys);
+ }
+
+ return ret;
+}
+
+/*
+ * V3_LB_BASE? - local bus address
+ * V3_LB_MAP? - pci bus address
+ */
+static void __init pci_v3_preinit(void)
+{
+ unsigned int temp;
+ phys_addr_t io_address = pci_pio_to_address(io_mem.start);
+
+ pcibios_min_mem = 0x00100000;
+
+ /*
+ * 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");
+
+ /*
+ * 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(non_mem.start) |
+ V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
+ v3_writew(V3_LB_MAP0, v3_addr_to_lb_map(non_mem_pci) |
+ 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(pre_mem.start) |
+ V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
+ V3_LB_BASE_ENABLE);
+ v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(pre_mem_pci) |
+ V3_LB_MAP_TYPE_MEM_MULTIPLE);
+
+ /*
+ * Setup window 2 - PCI IO
+ */
+ v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_address) |
+ 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, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
+}
+
+static void __init pci_v3_postinit(void)
+{
+ unsigned int pci_cmd;
+ phys_addr_t io_address = pci_pio_to_address(io_mem.start);
+
+ 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(non_mem.start, io_address, 0);
+}
+
+/*
+ * 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 pci_v3_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+ if (*pinp == 0)
+ *pinp = 1;
+
+ return pci_common_swizzle(dev, pinp);
+}
+
+static struct hw_pci pci_v3 __initdata = {
+ .swizzle = pci_v3_swizzle,
+ .setup = pci_v3_setup,
+ .nr_controllers = 1,
+ .ops = &pci_v3_ops,
+ .preinit = pci_v3_preinit,
+ .postinit = pci_v3_postinit,
+};
+
+static int __init pci_v3_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct of_pci_range_parser parser;
+ struct of_pci_range range;
+ struct resource *res;
+ int irq, ret;
+
+ /* Remap the Integrator system controller */
+ ap_syscon_base = devm_ioremap(&pdev->dev, INTEGRATOR_SC_BASE, 0x100);
+ if (!ap_syscon_base) {
+ dev_err(&pdev->dev, "unable to remap the AP syscon for PCIv3\n");
+ return -ENODEV;
+ }
+
+ /* Device tree probe path */
+ if (!np) {
+ dev_err(&pdev->dev, "no device tree node for PCIv3\n");
+ return -ENODEV;
+ }
+
+ if (of_pci_range_parser_init(&parser, np))
+ return -EINVAL;
+
+ /* Get base for bridge registers */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "unable to obtain PCIv3 base\n");
+ return -ENODEV;
+ }
+ pci_v3_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!pci_v3_base) {
+ dev_err(&pdev->dev, "unable to remap PCIv3 base\n");
+ return -ENODEV;
+ }
+
+ /* Get and request error IRQ resource */
+ irq = platform_get_irq(pdev, 0);
+ if (irq <= 0) {
+ dev_err(&pdev->dev, "unable to obtain PCIv3 error IRQ\n");
+ return -ENODEV;
+ }
+ ret = devm_request_irq(&pdev->dev, irq, v3_irq, 0,
+ "PCIv3 error", NULL);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "unable to request PCIv3 error IRQ %d (%d)\n", irq, ret);
+ return ret;
+ }
+
+ for_each_of_pci_range(&parser, &range) {
+ if (!range.flags) {
+ ret = of_pci_range_to_resource(&range, np, &conf_mem);
+ conf_mem.name = "PCIv3 config";
+ }
+ if (range.flags & IORESOURCE_IO) {
+ ret = of_pci_range_to_resource(&range, np, &io_mem);
+ io_mem.name = "PCIv3 I/O";
+ }
+ if ((range.flags & IORESOURCE_MEM) &&
+ !(range.flags & IORESOURCE_PREFETCH)) {
+ non_mem_pci = range.pci_addr;
+ non_mem_pci_sz = range.size;
+ ret = of_pci_range_to_resource(&range, np, &non_mem);
+ non_mem.name = "PCIv3 non-prefetched mem";
+ }
+ if ((range.flags & IORESOURCE_MEM) &&
+ (range.flags & IORESOURCE_PREFETCH)) {
+ pre_mem_pci = range.pci_addr;
+ pre_mem_pci_sz = range.size;
+ ret = of_pci_range_to_resource(&range, np, &pre_mem);
+ pre_mem.name = "PCIv3 prefetched mem";
+ }
+
+ if (ret < 0) {
+ dev_err(&pdev->dev, "missing ranges in device node\n");
+ return ret;
+ }
+ }
+
+ pci_v3.map_irq = of_irq_parse_and_map_pci;
+ pci_common_init_dev(&pdev->dev, &pci_v3);
+
+ return 0;
+}
+
+static const struct of_device_id pci_ids[] = {
+ { .compatible = "v3,v360epc-pci", },
+ {},
+};
+
+static struct platform_driver pci_v3_driver = {
+ .driver = {
+ .name = "pci-v3",
+ .of_match_table = pci_ids,
+ },
+};
+
+static int __init pci_v3_init(void)
+{
+ return platform_driver_probe(&pci_v3_driver, pci_v3_probe);
+}
+
+subsys_initcall(pci_v3_init);
+
+/*
+ * Static mappings for the PCIv3 bridge
+ *
+ * e8000000 40000000 PCI memory PHYS_PCI_MEM_BASE (max 512M)
+ * ec000000 61000000 PCI config space PHYS_PCI_CONFIG_BASE (max 16M)
+ * fee00000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M)
+ */
+static struct map_desc pci_v3_io_desc[] __initdata __maybe_unused = {
+ {
+ .virtual = (unsigned long)PCI_MEMORY_VADDR,
+ .pfn = __phys_to_pfn(PHYS_PCI_MEM_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = (unsigned long)PCI_CONFIG_VADDR,
+ .pfn = __phys_to_pfn(PHYS_PCI_CONFIG_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }
+};
+
+int __init pci_v3_early_init(void)
+{
+ iotable_init(pci_v3_io_desc, ARRAY_SIZE(pci_v3_io_desc));
+ vga_base = (unsigned long)PCI_MEMORY_VADDR;
+ pci_map_io_early(__phys_to_pfn(PHYS_PCI_IO_BASE));
+ return 0;
+}
diff --git a/arch/arm/mach-integrator/pci_v3.h b/arch/arm/mach-integrator/pci_v3.h
new file mode 100644
index 000000000..06a9e2e7d
--- /dev/null
+++ b/arch/arm/mach-integrator/pci_v3.h
@@ -0,0 +1,9 @@
+/* Simple oneliner include to the PCIv3 early init */
+#ifdef CONFIG_PCI
+extern int pci_v3_early_init(void);
+#else
+static inline int pci_v3_early_init(void)
+{
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-iop13xx/Kconfig b/arch/arm/mach-iop13xx/Kconfig
new file mode 100644
index 000000000..40c2d689f
--- /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 000000000..a3d9260e3
--- /dev/null
+++ b/arch/arm/mach-iop13xx/Makefile
@@ -0,0 +1,8 @@
+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 000000000..3a8c38c31
--- /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 000000000..a86fd0ed7
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/adma.h
@@ -0,0 +1,621 @@
+/*
+ * 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_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 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/entry-macro.S b/arch/arm/mach-iop13xx/include/mach/entry-macro.S
new file mode 100644
index 000000000..1a2d60348
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/entry-macro.S
@@ -0,0 +1,42 @@
+/*
+ * 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 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 000000000..786fa266f
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/hardware.h
@@ -0,0 +1,21 @@
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+#include <asm/types.h>
+
+#ifndef __ASSEMBLY__
+extern u16 iop13xx_dev_id(void);
+extern void iop13xx_set_atu_mmr_bases(void);
+#endif
+
+/*
+ * 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/iop13xx.h b/arch/arm/mach-iop13xx/include/mach/iop13xx.h
new file mode 100644
index 000000000..9311ee212
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/iop13xx.h
@@ -0,0 +1,507 @@
+#ifndef _IOP13XX_HW_H_
+#define _IOP13XX_HW_H_
+
+#ifndef __ASSEMBLY__
+
+enum reboot_mode;
+
+/* The ATU offsets can change based on the strapping */
+extern u32 iop13xx_atux_pmmr_offset;
+extern u32 iop13xx_atue_pmmr_offset;
+void iop13xx_init_early(void);
+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);
+void iop13xx_restart(enum reboot_mode, const char *);
+
+/* 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
+ * 0x00000 + 64K 0x0.fffb.0000 0xfee0.0000 PCIX outbound i/o window
+ * 0x10000 + 64K 0x0.fffd.0000 0xfee1.0000 PCIE outbound i/o window
+ */
+#define IOP13XX_PCIX_LOWER_IO_PA 0xfffb0000UL
+#define IOP13XX_PCIX_LOWER_IO_BA 0x0UL /* OIOTVR */
+
+#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_LOWER_IO_PA 0xfffd0000UL
+#define IOP13XX_PCIE_LOWER_IO_BA 0x10000UL /* OIOTVR */
+
+#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 (void __iomem *)(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) (((addr) - IOP13XX_PMMR_VIRT_MEM_BASE)\
+ + IOP13XX_PMMR_PHYS_MEM_BASE)
+#define IOP13XX_PMMR_PHYS_TO_VIRT(addr) (((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 000000000..ba2cf931e
--- /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 000000000..e8d24d321
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/irqs.h
@@ -0,0 +1,194 @@
+#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
+
+#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 000000000..59307e787
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/memory.h
@@ -0,0 +1,67 @@
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <mach/hardware.h>
+
+#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(void __iomem *x)
+{
+ return x + IOP13XX_PMMR_PHYS_MEM_BASE - IOP13XX_PMMR_VIRT_MEM_BASE;
+}
+
+static inline void __iomem *__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) \
+ ({ \
+ void * __virt; \
+ dma_addr_t __dma = addr; \
+ if (is_lbus_device(dev) && __is_lbus_dma(__dma)) \
+ __virt = __lbus_to_virt(__dma); \
+ else \
+ __virt = (void *)__phys_to_virt(__dma); \
+ __virt; \
+ })
+
+#define __arch_virt_to_dma(dev, addr) \
+ ({ \
+ void * __virt = addr; \
+ dma_addr_t __dma; \
+ if (is_lbus_device(dev) && __is_lbus_virt(__virt)) \
+ __dma = __virt_to_lbus(__virt); \
+ else \
+ __dma = __virt_to_phys((unsigned long)__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 000000000..b80c5ae17
--- /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 000000000..59f42b535
--- /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/time.h b/arch/arm/mach-iop13xx/include/mach/time.h
new file mode 100644
index 000000000..15bc9bb78
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/time.h
@@ -0,0 +1,126 @@
+#ifndef _IOP13XX_TIME_H_
+#define _IOP13XX_TIME_H_
+
+#include <mach/irqs.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/uncompress.h b/arch/arm/mach-iop13xx/include/mach/uncompress.h
new file mode 100644
index 000000000..d3791ece2
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/uncompress.h
@@ -0,0 +1,22 @@
+#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()
diff --git a/arch/arm/mach-iop13xx/io.c b/arch/arm/mach-iop13xx/io.c
new file mode 100644
index 000000000..faaf7d448
--- /dev/null
+++ b/arch/arm/mach-iop13xx/io.c
@@ -0,0 +1,90 @@
+/*
+ * 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>
+
+#include "pci.h"
+
+static void __iomem *__iop13xx_ioremap_caller(phys_addr_t cookie,
+ size_t size, unsigned int mtype, void *caller)
+{
+ 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 = (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 = (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_PMMR_PHYS_MEM_BASE ... IOP13XX_PMMR_UPPER_MEM_PA:
+ retval = IOP13XX_PMMR_PHYS_TO_VIRT(cookie);
+ break;
+ default:
+ retval = __arm_ioremap_caller(cookie, size, mtype,
+ caller);
+ }
+
+ return retval;
+}
+
+static void __iop13xx_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 (u32)IOP13XX_PMMR_VIRT_MEM_BASE ... (u32)IOP13XX_PMMR_UPPER_MEM_VA:
+ goto skip;
+ }
+ __iounmap(addr);
+
+skip:
+ return;
+}
+
+void __init iop13xx_init_early(void)
+{
+ arch_ioremap_caller = __iop13xx_ioremap_caller;
+ arch_iounmap = __iop13xx_iounmap;
+}
diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c
new file mode 100644
index 000000000..9cd07d396
--- /dev/null
+++ b/arch/arm/mach-iop13xx/iq81340mc.c
@@ -0,0 +1,97 @@
+/*
+ * 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(const 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 = {
+ .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);
+}
+
+MACHINE_START(IQ81340MC, "Intel IQ81340MC")
+ /* Maintainer: Dan Williams <dan.j.williams@intel.com> */
+ .atag_offset = 0x100,
+ .init_early = iop13xx_init_early,
+ .map_io = iop13xx_map_io,
+ .init_irq = iop13xx_init_irq,
+ .init_time = iq81340mc_timer_init,
+ .init_machine = iq81340mc_init,
+ .restart = iop13xx_restart,
+ .nr_irqs = NR_IOP13XX_IRQS,
+MACHINE_END
diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c
new file mode 100644
index 000000000..b3ec11cb7
--- /dev/null
+++ b/arch/arm/mach-iop13xx/iq81340sc.c
@@ -0,0 +1,99 @@
+/*
+ * 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(const 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 = {
+ .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);
+}
+
+MACHINE_START(IQ81340SC, "Intel IQ81340SC")
+ /* Maintainer: Dan Williams <dan.j.williams@intel.com> */
+ .atag_offset = 0x100,
+ .init_early = iop13xx_init_early,
+ .map_io = iop13xx_map_io,
+ .init_irq = iop13xx_init_irq,
+ .init_time = iq81340sc_timer_init,
+ .init_machine = iq81340sc_init,
+ .restart = iop13xx_restart,
+ .nr_irqs = NR_IOP13XX_IRQS,
+MACHINE_END
diff --git a/arch/arm/mach-iop13xx/irq.c b/arch/arm/mach-iop13xx/irq.c
new file mode 100644
index 000000000..bc739701c
--- /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 000000000..9f89e76df
--- /dev/null
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -0,0 +1,165 @@
+/*
+ * 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>
+#include <mach/irqs.h>
+
+/* 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);
+}
+
+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 = pci_msi_unmask_irq,
+ .irq_disable = pci_msi_mask_irq,
+ .irq_mask = pci_msi_mask_irq,
+ .irq_unmask = pci_msi_unmask_irq,
+};
+
+int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+{
+ int id, irq = irq_alloc_desc_from(IRQ_IOP13XX_MSI_0, -1);
+ struct msi_msg msg;
+
+ if (irq < 0)
+ return irq;
+
+ if (irq >= NR_IOP13XX_IRQS) {
+ irq_free_desc(irq);
+ return -ENOSPC;
+ }
+
+ 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);
+
+ pci_write_msi_msg(irq, &msg);
+ irq_set_chip_and_handler(irq, &iop13xx_msi_chip, handle_simple_irq);
+
+ return 0;
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+ irq_free_desc(irq);
+}
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
new file mode 100644
index 000000000..9082b84ae
--- /dev/null
+++ b/arch/arm/mach-iop13xx/pci.c
@@ -0,0 +1,1119 @@
+/*
+ * 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 <linux/export.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;
+void __iomem *iop13xx_atue_mem_base;
+void __iomem *iop13xx_atux_mem_base;
+size_t iop13xx_atue_mem_size;
+size_t iop13xx_atux_mem_size;
+
+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 = __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: %p\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 = __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: %p\n",
+ __func__, atu, iop13xx_atue_mem_size,
+ iop13xx_atue_mem_base);
+ break;
+ }
+
+ printk("%s: Initialized (%uM @ resource/virtual: %08lx/%p)\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(const 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_root_bus(NULL, sys->busnr,
+ &iop13xx_atux_ops,
+ sys, &sys->resources);
+ break;
+ case IOP13XX_INIT_ATU_ATUE:
+ bus = pci_bus_atue = pci_scan_root_bus(NULL, sys->busnr,
+ &iop13xx_atue_ops,
+ sys, &sys->resources);
+ 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... */
+ 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 = kzalloc(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);
+
+ pci_ioremap_io(0, IOP13XX_PCIX_LOWER_IO_PA);
+
+ res->start = IOP13XX_PCIX_LOWER_MEM_RA;
+ res->end = IOP13XX_PCIX_UPPER_MEM_RA;
+ res->name = "IQ81340 ATUX PCI Memory Space";
+ res->flags = IORESOURCE_MEM;
+ sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET;
+ 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);
+
+ pci_ioremap_io(SZ_64K, IOP13XX_PCIE_LOWER_IO_PA);
+
+ res->start = IOP13XX_PCIE_LOWER_MEM_RA;
+ res->end = IOP13XX_PCIE_UPPER_MEM_RA;
+ res->name = "IQ81340 ATUE PCI Memory Space";
+ res->flags = IORESOURCE_MEM;
+ sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET;
+ sys->map_irq = iop13xx_pcie_map_irq;
+ break;
+ default:
+ kfree(res);
+ return 0;
+ }
+
+ request_resource(&iomem_resource, res);
+
+ pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
+
+ 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/pci.h b/arch/arm/mach-iop13xx/pci.h
new file mode 100644
index 000000000..d45a80b30
--- /dev/null
+++ b/arch/arm/mach-iop13xx/pci.h
@@ -0,0 +1,6 @@
+#include <linux/types.h>
+
+extern void __iomem *iop13xx_atue_mem_base;
+extern void __iomem *iop13xx_atux_mem_base;
+extern size_t iop13xx_atue_mem_size;
+extern size_t iop13xx_atux_mem_size;
diff --git a/arch/arm/mach-iop13xx/setup.c b/arch/arm/mach-iop13xx/setup.c
new file mode 100644
index 000000000..53c316f73
--- /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>
+#include <linux/reboot.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>
+#include <mach/irqs.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 = (unsigned long)IOP13XX_PMMR_VIRT_MEM_BASE,
+ .pfn = __phys_to_pfn(IOP13XX_PMMR_PHYS_MEM_BASE),
+ .length = IOP13XX_PMMR_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 = 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 = 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_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_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_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);
+
+void iop13xx_restart(enum reboot_mode 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);
+}
diff --git a/arch/arm/mach-iop13xx/tpmi.c b/arch/arm/mach-iop13xx/tpmi.c
new file mode 100644
index 000000000..db511ec2b
--- /dev/null
+++ b/arch/arm/mach-iop13xx/tpmi.c
@@ -0,0 +1,257 @@
+/*
+ * 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>
+#include <mach/irqs.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 000000000..5e8c6f7df
--- /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 000000000..2d4010abb
--- /dev/null
+++ b/arch/arm/mach-iop32x/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := irq.o
+
+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 000000000..0a833b11e
--- /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 000000000..77e1ff057
--- /dev/null
+++ b/arch/arm/mach-iop32x/em7210.c
@@ -0,0 +1,231 @@
+/*
+ * 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 <linux/gpio.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>
+#include "gpio-iop32x.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);
+}
+
+/*
+ * 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(const 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 = {
+ .nr_controllers = 1,
+ .ops = &iop3xx_ops,
+ .setup = iop3xx_pci_setup,
+ .preinit = iop3xx_pci_preinit,
+ .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,
+};
+
+#define EM7210_HARDWARE_POWER 0
+
+void em7210_power_off(void)
+{
+ int ret;
+
+ ret = gpio_direction_output(EM7210_HARDWARE_POWER, 1);
+ if (ret)
+ pr_crit("could not drive power off GPIO high\n");
+}
+
+static int __init em7210_request_gpios(void)
+{
+ int ret;
+
+ if (!machine_is_em7210())
+ return 0;
+
+ ret = gpio_request(EM7210_HARDWARE_POWER, "power");
+ if (ret) {
+ pr_err("could not request power off GPIO\n");
+ return 0;
+ }
+
+ pm_power_off = em7210_power_off;
+
+ return 0;
+}
+device_initcall(em7210_request_gpios);
+
+static void __init em7210_init_machine(void)
+{
+ register_iop32x_gpio();
+ 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));
+}
+
+MACHINE_START(EM7210, "Lanner EM7210")
+ .atag_offset = 0x100,
+ .map_io = em7210_map_io,
+ .init_irq = iop32x_init_irq,
+ .init_time = em7210_timer_init,
+ .init_machine = em7210_init_machine,
+ .restart = iop3xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c
new file mode 100644
index 000000000..547b2342d
--- /dev/null
+++ b/arch/arm/mach-iop32x/glantank.c
@@ -0,0 +1,213 @@
+/*
+ * 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>
+#include "gpio-iop32x.h"
+
+/*
+ * GLAN Tank timer tick configuration.
+ */
+static void __init glantank_timer_init(void)
+{
+ /* 33.333 MHz crystal. */
+ iop_init_time(200000000);
+}
+
+
+/*
+ * 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(const 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 = {
+ .nr_controllers = 1,
+ .ops = &iop3xx_ops,
+ .setup = iop3xx_pci_setup,
+ .preinit = iop3xx_pci_preinit,
+ .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, IOMEM(0xfe8d0004));
+
+ while (1)
+ ;
+}
+
+static void __init glantank_init_machine(void)
+{
+ register_iop32x_gpio();
+ 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> */
+ .atag_offset = 0x100,
+ .map_io = glantank_map_io,
+ .init_irq = iop32x_init_irq,
+ .init_time = glantank_timer_init,
+ .init_machine = glantank_init_machine,
+ .restart = iop3xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-iop32x/gpio-iop32x.h b/arch/arm/mach-iop32x/gpio-iop32x.h
new file mode 100644
index 000000000..3c7309c02
--- /dev/null
+++ b/arch/arm/mach-iop32x/gpio-iop32x.h
@@ -0,0 +1,10 @@
+static struct resource iop32x_gpio_res[] = {
+ DEFINE_RES_MEM((IOP3XX_PERIPHERAL_PHYS_BASE + 0x07c4), 0x10),
+};
+
+static inline void register_iop32x_gpio(void)
+{
+ platform_device_register_simple("gpio-iop", 0,
+ iop32x_gpio_res,
+ ARRAY_SIZE(iop32x_gpio_res));
+}
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 000000000..5ed92037d
--- /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/entry-macro.S b/arch/arm/mach-iop32x/include/mach/entry-macro.S
new file mode 100644
index 000000000..ea13ae02d
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/entry-macro.S
@@ -0,0 +1,33 @@
+/*
+ * 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 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 000000000..958eb91c0
--- /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/hardware.h b/arch/arm/mach-iop32x/include/mach/hardware.h
new file mode 100644
index 000000000..48cb1b20b
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/hardware.h
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#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/iop32x.h b/arch/arm/mach-iop32x/include/mach/iop32x.h
new file mode 100644
index 000000000..56ec864ec
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/iop32x.h
@@ -0,0 +1,34 @@
+/*
+ * 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_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 000000000..6b6b369e7
--- /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 000000000..498819b73
--- /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 000000000..33573e099
--- /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/n2100.h b/arch/arm/mach-iop32x/include/mach/n2100.h
new file mode 100644
index 000000000..40b8a532b
--- /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/time.h b/arch/arm/mach-iop32x/include/mach/time.h
new file mode 100644
index 000000000..0f28c9949
--- /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/uncompress.h b/arch/arm/mach-iop32x/include/mach/uncompress.h
new file mode 100644
index 000000000..b3d45fd36
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/uncompress.h
@@ -0,0 +1,38 @@
+/*
+ * 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)
diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c
new file mode 100644
index 000000000..0e1392b20
--- /dev/null
+++ b/arch/arm/mach-iop32x/iq31244.c
@@ -0,0 +1,333 @@
+/*
+ * 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>
+#include "gpio-iop32x.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);
+ }
+}
+
+
+/*
+ * 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(const 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 = {
+ .nr_controllers = 1,
+ .ops = &iop3xx_ops,
+ .setup = iop3xx_pci_setup,
+ .preinit = iop3xx_pci_preinit,
+ .map_irq = ep80219_pci_map_irq,
+};
+
+static int __init
+iq31244_pci_map_irq(const 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 = {
+ .nr_controllers = 1,
+ .ops = &iop3xx_ops,
+ .setup = iop3xx_pci_setup,
+ .preinit = iop3xx_pci_preinit,
+ .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)
+{
+ register_iop32x_gpio();
+ 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. */
+ .atag_offset = 0x100,
+ .map_io = iq31244_map_io,
+ .init_irq = iop32x_init_irq,
+ .init_time = iq31244_timer_init,
+ .init_machine = iq31244_init_machine,
+ .restart = iop3xx_restart,
+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. */
+ .atag_offset = 0x100,
+ .map_io = iq31244_map_io,
+ .init_irq = iop32x_init_irq,
+ .init_time = iq31244_timer_init,
+ .init_machine = iq31244_init_machine,
+ .restart = iop3xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c
new file mode 100644
index 000000000..66782ff1f
--- /dev/null
+++ b/arch/arm/mach-iop32x/iq80321.c
@@ -0,0 +1,192 @@
+/*
+ * 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>
+#include "gpio-iop32x.h"
+
+/*
+ * IQ80321 timer tick configuration.
+ */
+static void __init iq80321_timer_init(void)
+{
+ /* 33.333 MHz crystal. */
+ iop_init_time(200000000);
+}
+
+
+/*
+ * 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(const 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 = {
+ .nr_controllers = 1,
+ .ops = &iop3xx_ops,
+ .setup = iop3xx_pci_setup,
+ .preinit = iop3xx_pci_preinit_cond,
+ .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)
+{
+ register_iop32x_gpio();
+ 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. */
+ .atag_offset = 0x100,
+ .map_io = iq80321_map_io,
+ .init_irq = iop32x_init_irq,
+ .init_time = iq80321_timer_init,
+ .init_machine = iq80321_init_machine,
+ .restart = iop3xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
new file mode 100644
index 000000000..d7ee2789d
--- /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 000000000..c1cd80ecc
--- /dev/null
+++ b/arch/arm/mach-iop32x/n2100.c
@@ -0,0 +1,370 @@
+/*
+ * 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 <linux/gpio.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>
+#include "gpio-iop32x.h"
+
+/*
+ * N2100 timer tick configuration.
+ */
+static void __init n2100_timer_init(void)
+{
+ /* 33.000 MHz crystal. */
+ iop_init_time(198000000);
+}
+
+
+/*
+ * 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(const 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 = {
+ .nr_controllers = 1,
+ .ops = &iop3xx_ops,
+ .setup = iop3xx_pci_setup,
+ .preinit = iop3xx_pci_preinit,
+ .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 void n2100_restart(enum reboot_mode mode, const char *cmd)
+{
+ int ret;
+
+ ret = gpio_direction_output(N2100_HARDWARE_RESET, 0);
+ if (ret) {
+ pr_crit("could not drive reset GPIO low\n");
+ return;
+ }
+ /* Wait for reset to happen */
+ while (1)
+ ;
+}
+
+
+static struct timer_list power_button_poll_timer;
+
+static void power_button_poll(unsigned long dummy)
+{
+ if (gpio_get_value(N2100_POWER_BUTTON) == 0) {
+ ctrl_alt_del();
+ return;
+ }
+
+ power_button_poll_timer.expires = jiffies + (HZ / 10);
+ add_timer(&power_button_poll_timer);
+}
+
+static int __init n2100_request_gpios(void)
+{
+ int ret;
+
+ if (!machine_is_n2100())
+ return 0;
+
+ ret = gpio_request(N2100_HARDWARE_RESET, "reset");
+ if (ret)
+ pr_err("could not request reset GPIO\n");
+
+ ret = gpio_request(N2100_POWER_BUTTON, "power");
+ if (ret)
+ pr_err("could not request power GPIO\n");
+ else {
+ ret = gpio_direction_input(N2100_POWER_BUTTON);
+ if (ret)
+ pr_err("could not set power GPIO as input\n");
+ }
+ /* Set up power button poll timer */
+ 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);
+ return 0;
+}
+device_initcall(n2100_request_gpios);
+
+static void __init n2100_init_machine(void)
+{
+ register_iop32x_gpio();
+ 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;
+}
+
+MACHINE_START(N2100, "Thecus N2100")
+ /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+ .atag_offset = 0x100,
+ .map_io = n2100_map_io,
+ .init_irq = iop32x_init_irq,
+ .init_time = n2100_timer_init,
+ .init_machine = n2100_init_machine,
+ .restart = n2100_restart,
+MACHINE_END
diff --git a/arch/arm/mach-iop33x/Kconfig b/arch/arm/mach-iop33x/Kconfig
new file mode 100644
index 000000000..9aa016bb1
--- /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 000000000..e95db30d8
--- /dev/null
+++ b/arch/arm/mach-iop33x/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := irq.o uart.o
+
+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 000000000..760a0efe7
--- /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 000000000..4b92f795f
--- /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/entry-macro.S b/arch/arm/mach-iop33x/include/mach/entry-macro.S
new file mode 100644
index 000000000..0a398fe1f
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/entry-macro.S
@@ -0,0 +1,34 @@
+/*
+ * 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 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/hardware.h b/arch/arm/mach-iop33x/include/mach/hardware.h
new file mode 100644
index 000000000..839285315
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/hardware.h
@@ -0,0 +1,43 @@
+/*
+ * 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
+ */
+
+#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/iop33x.h b/arch/arm/mach-iop33x/include/mach/iop33x.h
new file mode 100644
index 000000000..c95122653
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/iop33x.h
@@ -0,0 +1,40 @@
+/*
+ * 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_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 000000000..fe406b012
--- /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 000000000..8325d71f2
--- /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 000000000..707628a60
--- /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/time.h b/arch/arm/mach-iop33x/include/mach/time.h
new file mode 100644
index 000000000..4ac4d7664
--- /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/uncompress.h b/arch/arm/mach-iop33x/include/mach/uncompress.h
new file mode 100644
index 000000000..ed282e141
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/uncompress.h
@@ -0,0 +1,36 @@
+/*
+ * 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)
diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c
new file mode 100644
index 000000000..e2cb65cfb
--- /dev/null
+++ b/arch/arm/mach-iop33x/iq80331.c
@@ -0,0 +1,152 @@
+/*
+ * 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);
+}
+
+
+/*
+ * IQ80331 PCI.
+ */
+static int __init
+iq80331_pci_map_irq(const 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 = {
+ .nr_controllers = 1,
+ .ops = &iop3xx_ops,
+ .setup = iop3xx_pci_setup,
+ .preinit = iop3xx_pci_preinit_cond,
+ .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 struct resource iq80331_gpio_res[] = {
+ DEFINE_RES_MEM((IOP3XX_PERIPHERAL_PHYS_BASE + 0x1780), 0x10),
+};
+
+static void __init iq80331_init_machine(void)
+{
+ platform_device_register_simple("gpio-iop", 0,
+ iq80331_gpio_res,
+ ARRAY_SIZE(iq80331_gpio_res));
+ 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. */
+ .atag_offset = 0x100,
+ .map_io = iop3xx_map_io,
+ .init_irq = iop33x_init_irq,
+ .init_time = iq80331_timer_init,
+ .init_machine = iq80331_init_machine,
+ .restart = iop3xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c
new file mode 100644
index 000000000..0b6269d94
--- /dev/null
+++ b/arch/arm/mach-iop33x/iq80332.c
@@ -0,0 +1,152 @@
+/*
+ * 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);
+}
+
+
+/*
+ * IQ80332 PCI.
+ */
+static int __init
+iq80332_pci_map_irq(const 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 = {
+ .nr_controllers = 1,
+ .ops = &iop3xx_ops,
+ .setup = iop3xx_pci_setup,
+ .preinit = iop3xx_pci_preinit_cond,
+ .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 struct resource iq80332_gpio_res[] = {
+ DEFINE_RES_MEM((IOP3XX_PERIPHERAL_PHYS_BASE + 0x1780), 0x10),
+};
+
+static void __init iq80332_init_machine(void)
+{
+ platform_device_register_simple("gpio-iop", 0,
+ iq80332_gpio_res,
+ ARRAY_SIZE(iq80332_gpio_res));
+ 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. */
+ .atag_offset = 0x100,
+ .map_io = iop3xx_map_io,
+ .init_irq = iop33x_init_irq,
+ .init_time = iq80332_timer_init,
+ .init_machine = iq80332_init_machine,
+ .restart = iop3xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-iop33x/irq.c b/arch/arm/mach-iop33x/irq.c
new file mode 100644
index 000000000..f7f5d3e45
--- /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 000000000..bbf54d794
--- /dev/null
+++ b/arch/arm/mach-iop33x/uart.c
@@ -0,0 +1,103 @@
+/*
+ * 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/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-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
new file mode 100644
index 000000000..c342dc4e8
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -0,0 +1,240 @@
+if ARCH_IXP4XX
+
+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
+
+config MACH_DEVIXP
+ bool "Omicron DEVIXP"
+ help
+ Say 'Y' here if you want your kernel to support the DEVIXP
+ board from OMICRON electronics GmbH.
+
+config MACH_MICCPT
+ bool "Omicron MICCPT"
+ select PCI
+ help
+ Say 'Y' here if you want your kernel to support the MICCPT
+ board from OMICRON electronics GmbH.
+
+config MACH_MIC256
+ bool "Omicron MIC256"
+ help
+ Say 'Y' here if you want your kernel to support the MIC256
+ board from OMICRON electronics GmbH.
+
+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 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 000000000..eded94c96
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -0,0 +1,43 @@
+#
+# 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_MICCPT) += miccpt-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_DEVIXP) += omixp-setup.o
+obj-$(CONFIG_MACH_MICCPT) += omixp-setup.o
+obj-$(CONFIG_MACH_MIC256) += omixp-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 000000000..9c7af91d9
--- /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 000000000..548c7d43a
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/avila-pci.c
@@ -0,0 +1,81 @@
+/*
+ * 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(const 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,
+ .ops = &ixp4xx_ops,
+ .preinit = avila_pci_preinit,
+ .setup = ixp4xx_setup,
+ .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 000000000..6beec150c
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
@@ -0,0 +1,199 @@
+/*
+ * 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_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .atag_offset = 0x100,
+ .init_machine = avila_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+ .restart = ixp4xx_restart,
+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_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .atag_offset = 0x100,
+ .init_machine = avila_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+ .restart = ixp4xx_restart,
+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 000000000..4977296f0
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -0,0 +1,455 @@
+/*
+ * 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 <linux/export.h>
+#include <asm/dma-mapping.h>
+
+#include <asm/cputype.h>
+#include <asm/irq.h>
+#include <asm/sizes.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_RAW_SPINLOCK(ixp4xx_pci_lock);
+
+/*
+ * Read from PCI config space
+ */
+static void crp_read(u32 ad_cbe, u32 *data)
+{
+ unsigned long flags;
+ raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
+ *PCI_CRP_AD_CBE = ad_cbe;
+ *data = *PCI_CRP_RDATA;
+ raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
+}
+
+/*
+ * Write to PCI config space
+ */
+static void crp_write(u32 ad_cbe, u32 data)
+{
+ unsigned long flags;
+ raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
+ *PCI_CRP_AD_CBE = CRP_AD_CBE_WRITE | ad_cbe;
+ *PCI_CRP_WDATA = data;
+ raw_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;
+
+ raw_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;
+
+ raw_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;
+
+ raw_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;
+
+ raw_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;
+
+ raw_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;
+
+ raw_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;
+}
+
+void __init ixp4xx_pci_preinit(void)
+{
+ unsigned long cpuid = read_cpuid_id();
+
+#ifdef CONFIG_IXP4XX_INDIRECT_PCI
+ pcibios_min_mem = 0x10000000; /* 1 GB of indirect PCI MMIO space */
+#else
+ pcibios_min_mem = 0x48000000; /* 64 MB of PCI MMIO space */
+#endif
+ /*
+ * 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_32M + SZ_16M);
+
+ /*
+ * 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);
+ local_write_config(0x40, 4, 0x000080FF); /* No TRDY time limit */
+ } 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]);
+
+ pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
+ pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
+
+ return 1;
+}
+
+EXPORT_SYMBOL(ixp4xx_pci_read);
+EXPORT_SYMBOL(ixp4xx_pci_write);
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
new file mode 100644
index 000000000..8537d4c41
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -0,0 +1,672 @@
+/*
+ * 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/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/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+#include <linux/export.h>
+#include <linux/gpio.h>
+#include <linux/cpu.h>
+#include <linux/pci.h>
+#include <linux/sched_clock.h>
+#include <mach/udc.h>
+#include <mach/hardware.h>
+#include <mach/io.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/irq.h>
+#include <asm/system_misc.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+#define IXP4XX_TIMER_FREQ 66666000
+
+/*
+ * The timer register doesn't allow to specify the two least significant bits of
+ * the timeout value and assumes them being zero. So make sure IXP4XX_LATCH is
+ * the best value with the two least significant bits unset.
+ */
+#define IXP4XX_LATCH DIV_ROUND_CLOSEST(IXP4XX_TIMER_FREQ, \
+ (IXP4XX_OST_RELOAD_MASK + 1) * HZ) * \
+ (IXP4XX_OST_RELOAD_MASK + 1)
+
+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 = (unsigned long)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 = (unsigned long)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 = (unsigned long)IXP4XX_PCI_CFG_BASE_VIRT,
+ .pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
+ .length = IXP4XX_PCI_CFG_REGION_SIZE,
+ .type = MT_DEVICE
+ }, { /* Queue Manager */
+ .virtual = (unsigned long)IXP4XX_QMGR_BASE_VIRT,
+ .pfn = __phys_to_pfn(IXP4XX_QMGR_BASE_PHYS),
+ .length = IXP4XX_QMGR_REGION_SIZE,
+ .type = MT_DEVICE
+ },
+};
+
+void __init ixp4xx_map_io(void)
+{
+ iotable_init(ixp4xx_io_desc, ARRAY_SIZE(ixp4xx_io_desc));
+}
+
+/*
+ * 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 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 void gpio_line_get(u8 line, int *value)
+{
+ *value = (*IXP4XX_GPIO_GPINR >> line) & 0x1;
+}
+
+static 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);
+}
+
+/*************************************************************************
+ * 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,
+};
+
+static int ixp4xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
+{
+ int irq;
+
+ for (irq = 0; irq < 32; irq++) {
+ if (irq2gpio[irq] == gpio)
+ return irq;
+ }
+ return -EINVAL;
+}
+
+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;
+
+ /*
+ * ixp4xx does not implement the XScale PWRMODE register
+ * so it must not call cpu_do_idle().
+ */
+ cpu_idle_poll_ctrl(true);
+
+ /* 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_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();
+}
+
+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);
+
+static int ixp4xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+ gpio_line_config(gpio, IXP4XX_GPIO_IN);
+
+ return 0;
+}
+
+static int ixp4xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
+ int level)
+{
+ gpio_line_set(gpio, level);
+ gpio_line_config(gpio, IXP4XX_GPIO_OUT);
+
+ return 0;
+}
+
+static int ixp4xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+ int value;
+
+ gpio_line_get(gpio, &value);
+
+ return value;
+}
+
+static void ixp4xx_gpio_set_value(struct gpio_chip *chip, unsigned gpio,
+ int value)
+{
+ gpio_line_set(gpio, value);
+}
+
+static struct gpio_chip ixp4xx_gpio_chip = {
+ .label = "IXP4XX_GPIO_CHIP",
+ .direction_input = ixp4xx_gpio_direction_input,
+ .direction_output = ixp4xx_gpio_direction_output,
+ .get = ixp4xx_gpio_get_value,
+ .set = ixp4xx_gpio_set_value,
+ .to_irq = ixp4xx_gpio_to_irq,
+ .base = 0,
+ .ngpio = 16,
+};
+
+void __init ixp4xx_sys_init(void)
+{
+ ixp4xx_exp_bus_size = SZ_16M;
+
+ platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices));
+
+ gpiochip_add(&ixp4xx_gpio_chip);
+
+ 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 u64 notrace ixp4xx_read_sched_clock(void)
+{
+ return *IXP4XX_OSTS;
+}
+
+/*
+ * 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)
+{
+ sched_clock_register(ixp4xx_read_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 = IXP4XX_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,
+ .set_mode = ixp4xx_set_mode,
+ .set_next_event = ixp4xx_set_next_event,
+};
+
+static void __init ixp4xx_clockevent_init(void)
+{
+ clockevent_ixp4xx.cpumask = cpumask_of(0);
+ clockevents_config_and_register(&clockevent_ixp4xx, IXP4XX_TIMER_FREQ,
+ 0xf, 0xfffffffe);
+}
+
+void ixp4xx_restart(enum reboot_mode mode, const char *cmd)
+{
+ if (mode == REBOOT_SOFT) {
+ /* Jump into ROM at address 0 */
+ soft_restart(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;
+ }
+}
+
+#ifdef CONFIG_PCI
+static int ixp4xx_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
+{
+ return (dma_addr + size) > SZ_64M;
+}
+
+static int ixp4xx_platform_notify_remove(struct device *dev)
+{
+ if (dev_is_pci(dev))
+ dmabounce_unregister_dev(dev);
+
+ return 0;
+}
+#endif
+
+/*
+ * Setup DMA mask to 64MB on PCI devices and 4 GB on all other things.
+ */
+static int ixp4xx_platform_notify(struct device *dev)
+{
+ dev->dma_mask = &dev->coherent_dma_mask;
+
+#ifdef CONFIG_PCI
+ if (dev_is_pci(dev)) {
+ dev->coherent_dma_mask = DMA_BIT_MASK(28); /* 64 MB */
+ dmabounce_register_dev(dev, 2048, 4096, ixp4xx_needs_bounce);
+ return 0;
+ }
+#endif
+
+ dev->coherent_dma_mask = DMA_BIT_MASK(32);
+ return 0;
+}
+
+int dma_set_coherent_mask(struct device *dev, u64 mask)
+{
+ if (dev_is_pci(dev))
+ mask &= DMA_BIT_MASK(28); /* 64 MB */
+
+ if ((mask & DMA_BIT_MASK(28)) == DMA_BIT_MASK(28)) {
+ dev->coherent_dma_mask = mask;
+ return 0;
+ }
+
+ return -EIO; /* device wanted sub-64MB mask */
+}
+EXPORT_SYMBOL(dma_set_coherent_mask);
+
+#ifdef CONFIG_IXP4XX_INDIRECT_PCI
+/*
+ * 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 void __iomem *ixp4xx_ioremap_caller(phys_addr_t addr, size_t size,
+ unsigned int mtype, void *caller)
+{
+ if (!is_pci_memory(addr))
+ return __arm_ioremap_caller(addr, size, mtype, caller);
+
+ return (void __iomem *)addr;
+}
+
+static void ixp4xx_iounmap(volatile void __iomem *addr)
+{
+ if (!is_pci_memory((__force u32)addr))
+ __iounmap(addr);
+}
+#endif
+
+void __init ixp4xx_init_early(void)
+{
+ platform_notify = ixp4xx_platform_notify;
+#ifdef CONFIG_PCI
+ platform_notify_remove = ixp4xx_platform_notify_remove;
+#endif
+#ifdef CONFIG_IXP4XX_INDIRECT_PCI
+ arch_ioremap_caller = ixp4xx_ioremap_caller;
+ arch_iounmap = ixp4xx_iounmap;
+#endif
+}
diff --git a/arch/arm/mach-ixp4xx/coyote-pci.c b/arch/arm/mach-ixp4xx/coyote-pci.c
new file mode 100644
index 000000000..5d14ce2ae
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/coyote-pci.c
@@ -0,0 +1,64 @@
+/*
+ * 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(const 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,
+ .ops = &ixp4xx_ops,
+ .preinit = coyote_pci_preinit,
+ .setup = ixp4xx_setup,
+ .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 000000000..820cae860
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/coyote-setup.c
@@ -0,0 +1,141 @@
+/*
+ * 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_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .atag_offset = 0x100,
+ .init_machine = coyote_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+ .restart = ixp4xx_restart,
+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_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .atag_offset = 0x100,
+ .init_machine = coyote_init,
+ .restart = ixp4xx_restart,
+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 000000000..8dca76937
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/dsmg600-pci.c
@@ -0,0 +1,79 @@
+/*
+ * 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(const 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,
+ .ops = &ixp4xx_ops,
+ .preinit = dsmg600_pci_preinit,
+ .setup = ixp4xx_setup,
+ .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 000000000..43ee06d3a
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c
@@ -0,0 +1,299 @@
+/*
+ * 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/gpio.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/gpio.h>
+
+#include <mach/hardware.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/time.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 and drive it high */
+ gpio_direction_output(DSMG600_PO_GPIO, 1);
+}
+
+/* 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_set_value(DSMG600_LED_PWR_GPIO, 0);
+ } 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 int __init dsmg600_gpio_init(void)
+{
+ if (!machine_is_dsmg600())
+ return 0;
+
+ gpio_request(DSMG600_RB_GPIO, "reset button");
+ if (request_irq(gpio_to_irq(DSMG600_RB_GPIO), &dsmg600_reset_handler,
+ 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_request(DSMG600_PB_GPIO, "power button");
+ gpio_direction_input(DSMG600_PB_GPIO);
+ /* Request poweroff GPIO line */
+ gpio_request(DSMG600_PO_GPIO, "power off button");
+
+ /* 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));
+ return 0;
+}
+device_initcall(dsmg600_gpio_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;
+}
+
+MACHINE_START(DSMG600, "D-Link DSM-G600 RevA")
+ /* Maintainer: www.nslu2-linux.org */
+ .atag_offset = 0x100,
+ .map_io = ixp4xx_map_io,
+ .init_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = dsmg600_timer_init,
+ .init_machine = dsmg600_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+ .restart = ixp4xx_restart,
+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 000000000..fd4a8625b
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/fsg-pci.c
@@ -0,0 +1,75 @@
+/*
+ * 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(const 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,
+ .ops = &ixp4xx_ops,
+ .preinit = fsg_pci_preinit,
+ .setup = ixp4xx_setup,
+ .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 000000000..5c4b0c4a1
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/fsg-setup.c
@@ -0,0 +1,281 @@
+/*
+ * 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/gpio.h>
+#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>
+
+#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_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_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_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .atag_offset = 0x100,
+ .init_machine = fsg_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+ .restart = ixp4xx_restart,
+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 000000000..d9d6cc089
--- /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(const 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,
+ .ops = &ixp4xx_ops,
+ .preinit = gateway7001_pci_preinit,
+ .setup = ixp4xx_setup,
+ .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 000000000..3d24b3fce
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/gateway7001-setup.c
@@ -0,0 +1,110 @@
+/*
+ * 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_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .atag_offset = 0x100,
+ .init_machine = gateway7001_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+ .restart = ixp4xx_restart,
+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 000000000..80bd9d6d0
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/goramo_mlr.c
@@ -0,0 +1,517 @@
+/*
+ * Goramo MultiLink router platform code
+ * Copyright (C) 2006-2009 Krzysztof Halasa <khc@pm.waw.pl>
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.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/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/pci.h>
+#include <asm/system_info.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_set_value(GPIO_SCL, !!value);
+ udelay(3);
+}
+
+static void set_sda(u8 value)
+{
+ gpio_set_value(GPIO_SDA, !!value);
+ udelay(3);
+}
+
+static void set_str(u8 value)
+{
+ gpio_set_value(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_direction_output(GPIO_SCL, 1);
+ gpio_direction_output(GPIO_SDA, 1);
+
+ 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 port = (irq == IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N));
+ int i = gpio_get_value(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N);
+ 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);
+
+ i = gpio_get_value(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N);
+ 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_set_value(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_set_value(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[7] __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_request(GPIO_SCL, "SCL/clock");
+ gpio_request(GPIO_SDA, "SDA/data");
+ gpio_request(GPIO_STR, "strobe");
+ gpio_request(GPIO_HSS0_RTS_N, "HSS0 RTS");
+ gpio_request(GPIO_HSS1_RTS_N, "HSS1 RTS");
+ gpio_request(GPIO_HSS0_DCD_N, "HSS0 DCD");
+ gpio_request(GPIO_HSS1_DCD_N, "HSS1 DCD");
+
+ gpio_direction_output(GPIO_SCL, 1);
+ gpio_direction_output(GPIO_SDA, 1);
+ gpio_direction_output(GPIO_STR, 0);
+ gpio_direction_output(GPIO_HSS0_RTS_N, 1);
+ gpio_direction_output(GPIO_HSS1_RTS_N, 1);
+ gpio_direction_input(GPIO_HSS0_DCD_N);
+ gpio_direction_input(GPIO_HSS1_DCD_N);
+ 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(const 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,
+ .ops = &ixp4xx_ops,
+ .preinit = gmlr_pci_preinit,
+ .postinit = gmlr_pci_postinit,
+ .setup = ixp4xx_setup,
+ .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_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .atag_offset = 0x100,
+ .init_machine = gmlr_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+ .restart = ixp4xx_restart,
+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 000000000..551d114c9
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/gtwx5715-pci.c
@@ -0,0 +1,84 @@
+/*
+ * 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(const 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,
+ .ops = &ixp4xx_ops,
+ .preinit = gtwx5715_pci_preinit,
+ .setup = ixp4xx_setup,
+ .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 000000000..16a12994f
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
@@ -0,0 +1,179 @@
+/*
+ * 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_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .atag_offset = 0x100,
+ .init_machine = gtwx5715_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+ .restart = ixp4xx_restart,
+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 000000000..ebc0ba31c
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/cpu.h
@@ -0,0 +1,58 @@
+/*
+ * 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 <linux/io.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 = ~__raw_readl(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)
+{
+ __raw_writel(~value, IXP4XX_EXP_CFG2);
+}
+
+#endif /* _ASM_ARCH_CPU_H */
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 000000000..79adf83e2
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/entry-macro.S
@@ -0,0 +1,41 @@
+/*
+ * 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 get_irqnr_preamble, base, tmp
+ .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/hardware.h b/arch/arm/mach-ixp4xx/include/mach/hardware.h
new file mode 100644
index 000000000..034bb2a1b
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/hardware.h
@@ -0,0 +1,36 @@
+/*
+ * 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__
+
+#ifdef CONFIG_IXP4XX_INDIRECT_PCI
+#define PCIBIOS_MAX_MEM 0x4FFFFFFF
+#else
+#define PCIBIOS_MAX_MEM 0x4BFFFFFF
+#endif
+
+/* 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 000000000..b02439019
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/io.h
@@ -0,0 +1,530 @@
+/*
+ * 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>
+
+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.
+ */
+#ifdef CONFIG_IXP4XX_INDIRECT_PCI
+
+/*
+ * 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.
+ */
+
+extern unsigned long pcibios_min_mem;
+static inline int is_pci_memory(u32 addr)
+{
+ return (addr >= pcibios_min_mem) && (addr <= 0x4FFFFFFF);
+}
+
+#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 writeb_relaxed(v, p) __indirect_writeb(v, p)
+#define writew_relaxed(v, p) __indirect_writew(v, p)
+#define writel_relaxed(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 readb_relaxed(p) __indirect_readb(p)
+#define readw_relaxed(p) __indirect_readw(p)
+#define readl_relaxed(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, p);
+ 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, p);
+ 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(p);
+
+ 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(p);
+
+ 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.
+ */
+
+#define outb outb
+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);
+}
+
+#define outsb outsb
+static inline void outsb(u32 io_addr, const void *p, u32 count)
+{
+ const u8 *vaddr = p;
+
+ while (count--)
+ outb(*vaddr++, io_addr);
+}
+
+#define outw outw
+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);
+}
+
+#define outsw outsw
+static inline void outsw(u32 io_addr, const void *p, u32 count)
+{
+ const u16 *vaddr = p;
+ while (count--)
+ outw(cpu_to_le16(*vaddr++), io_addr);
+}
+
+#define outl outl
+static inline void outl(u32 value, u32 addr)
+{
+ ixp4xx_pci_write(addr, NP_CMD_IOWRITE, value);
+}
+
+#define outsl outsl
+static inline void outsl(u32 io_addr, const void *p, u32 count)
+{
+ const u32 *vaddr = p;
+ while (count--)
+ outl(cpu_to_le32(*vaddr++), io_addr);
+}
+
+#define inb inb
+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);
+}
+
+#define insb insb
+static inline void insb(u32 io_addr, void *p, u32 count)
+{
+ u8 *vaddr = p;
+ while (count--)
+ *vaddr++ = inb(io_addr);
+}
+
+#define inw inw
+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);
+}
+
+#define insw insw
+static inline void insw(u32 io_addr, void *p, u32 count)
+{
+ u16 *vaddr = p;
+ while (count--)
+ *vaddr++ = le16_to_cpu(inw(io_addr));
+}
+
+#define inl inl
+static inline u32 inl(u32 addr)
+{
+ u32 data;
+ if (ixp4xx_pci_read(addr, NP_CMD_IOREAD, &data))
+ return 0xffffffff;
+
+ return data;
+}
+
+#define insl insl
+static inline void insl(u32 io_addr, void *p, u32 count)
+{
+ u32 *vaddr = p;
+ 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 000000000..7e6d4cce7
--- /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 000000000..cf03614d2
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/ixp46x_ts.h
@@ -0,0 +1,81 @@
+/*
+ * 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)
+
+/* The ptp_ixp46x module will set this variable */
+extern int ixp46x_phc_index;
+
+#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 000000000..c5bae9c03
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
@@ -0,0 +1,652 @@
+/*
+ * 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
+ *
+ * 0xC8000000 0x00013000 0xFEF00000 On-Chip Peripherals
+ *
+ * 0xC0000000 0x00001000 0xFEF13000 PCI CFG
+ *
+ * 0xC4000000 0x00001000 0xFEF14000 EXP CFG
+ *
+ * 0x60000000 0x00004000 0xFEF15000 QMgr
+ */
+
+/*
+ * Queue Manager
+ */
+#define IXP4XX_QMGR_BASE_PHYS 0x60000000
+#define IXP4XX_QMGR_BASE_VIRT IOMEM(0xFEF15000)
+#define IXP4XX_QMGR_REGION_SIZE 0x00004000
+
+/*
+ * Peripheral space, including debug UART. Must be section-aligned so that
+ * it can be used with the low-level debug code.
+ */
+#define IXP4XX_PERIPHERAL_BASE_PHYS 0xC8000000
+#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFEF00000)
+#define IXP4XX_PERIPHERAL_REGION_SIZE 0x00013000
+
+/*
+ * PCI Config registers
+ */
+#define IXP4XX_PCI_CFG_BASE_PHYS 0xC0000000
+#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFEF13000)
+#define IXP4XX_PCI_CFG_REGION_SIZE 0x00001000
+
+/*
+ * Expansion BUS Configuration registers
+ */
+#define IXP4XX_EXP_CFG_BASE_PHYS 0xC4000000
+#define IXP4XX_EXP_CFG_BASE_VIRT 0xFEF14000
+#define IXP4XX_EXP_CFG_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 __iomem *)(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/npe.h b/arch/arm/mach-ixp4xx/include/mach/npe.h
new file mode 100644
index 000000000..e320db245
--- /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 000000000..75c4c6572
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/platform.h
@@ -0,0 +1,135 @@
+/*
+ * 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 <linux/reboot.h>
+
+#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;
+};
+
+#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_early(void);
+extern void ixp4xx_init_irq(void);
+extern void ixp4xx_sys_init(void);
+extern void ixp4xx_timer_init(void);
+extern void ixp4xx_restart(enum reboot_mode, const char *);
+extern void ixp4xx_pci_preinit(void);
+struct pci_sys_data;
+extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
+extern struct pci_ops ixp4xx_ops;
+
+#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 000000000..4de8da536
--- /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)
+{
+ struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
+#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;
+ const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
+ 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)
+{
+ const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
+ return (__raw_readl(&qmgr_regs->stat1[queue >> 3])
+ >> ((queue & 7) << 2)) & 0xF;
+}
+
+static inline int __qmgr_get_stat2(unsigned int queue)
+{
+ const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
+ 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)
+{
+ const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
+ 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)
+{
+ const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
+ 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/udc.h b/arch/arm/mach-ixp4xx/include/mach/udc.h
new file mode 100644
index 000000000..7bd8b96c8
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/udc.h
@@ -0,0 +1,8 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/udc.h
+ *
+ */
+#include <linux/platform_data/pxa2xx_udc.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 000000000..7b25c0225
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/uncompress.h
@@ -0,0 +1,56 @@
+/*
+ * 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() ||
+ machine_is_devixp() || machine_is_miccpt() || machine_is_mic256())
+ 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)
+
+#endif
diff --git a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c
new file mode 100644
index 000000000..318424dd3
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c
@@ -0,0 +1,77 @@
+/*
+ * 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(const 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,
+ .ops = &ixp4xx_ops,
+ .preinit = ixdp425_pci_preinit,
+ .setup = ixp4xx_setup,
+ .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 000000000..e7b8befa8
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -0,0 +1,310 @@
+/*
+ * 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 <linux/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 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)
+
+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_set_value(IXDP425_NAND_NCE_PIN, 0);
+ udelay(5);
+ } else
+ gpio_set_value(IXDP425_NAND_NCE_PIN, 1);
+
+ 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,
+ .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_request(IXDP425_NAND_NCE_PIN, "NAND NCE pin");
+ gpio_direction_output(IXDP425_NAND_NCE_PIN, 0);
+
+ /* 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_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .atag_offset = 0x100,
+ .init_machine = ixdp425_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+ .restart = ixp4xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_IXDP465
+MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
+ /* Maintainer: MontaVista Software, Inc. */
+ .map_io = ixp4xx_map_io,
+ .init_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .atag_offset = 0x100,
+ .init_machine = ixdp425_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_PRPMC1100
+MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
+ /* Maintainer: MontaVista Software, Inc. */
+ .map_io = ixp4xx_map_io,
+ .init_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .atag_offset = 0x100,
+ .init_machine = ixdp425_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_KIXRP435
+MACHINE_START(KIXRP435, "Intel KIXRP435 Reference Platform")
+ /* Maintainer: MontaVista Software, Inc. */
+ .map_io = ixp4xx_map_io,
+ .init_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .atag_offset = 0x100,
+ .init_machine = ixdp425_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+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 000000000..1f8717ba1
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
@@ -0,0 +1,58 @@
+/*
+ * 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(const 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,
+ .ops = &ixp4xx_ops,
+ .preinit = ixdpg425_pci_preinit,
+ .setup = ixp4xx_setup,
+ .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 000000000..2f74114f9
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/ixp4xx_npe.c
@@ -0,0 +1,740 @@
+/*
+ * 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
+
+#define NPE_A_FIRMWARE "NPE-A"
+#define NPE_B_FIRMWARE "NPE-B"
+#define NPE_C_FIRMWARE "NPE-C"
+
+const char *npe_names[] = { NPE_A_FIRMWARE, NPE_B_FIRMWARE, NPE_C_FIRMWARE };
+
+#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 = reject_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");
+/*(DEBLOBBED)*/
+
+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 000000000..9d1b6b7c3
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
@@ -0,0 +1,372 @@
+/*
+ * 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>
+
+static struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
+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;
+
+ /* 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:
+ 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);
+ 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_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/miccpt-pci.c b/arch/arm/mach-ixp4xx/miccpt-pci.c
new file mode 100644
index 000000000..d114ccd20
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/miccpt-pci.c
@@ -0,0 +1,77 @@
+/*
+ * arch/arm/mach-ixp4xx/miccpt-pci.c
+ *
+ * MICCPT board-level PCI initialization
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ * Copyright (C) 2006 OMICRON electronics GmbH
+ *
+ * Author: Michael Jochum <michael.jochum@omicron.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/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.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 1
+#define INTB 2
+#define INTC 3
+#define INTD 4
+
+
+void __init miccpt_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 miccpt_map_irq(const 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 miccpt_pci __initdata = {
+ .nr_controllers = 1,
+ .ops = &ixp4xx_ops,
+ .preinit = miccpt_pci_preinit,
+ .setup = ixp4xx_setup,
+ .map_irq = miccpt_map_irq,
+};
+
+int __init miccpt_pci_init(void)
+{
+ if (machine_is_miccpt())
+ pci_common_init(&miccpt_pci);
+ return 0;
+}
+
+subsys_initcall(miccpt_pci_init);
diff --git a/arch/arm/mach-ixp4xx/nas100d-pci.c b/arch/arm/mach-ixp4xx/nas100d-pci.c
new file mode 100644
index 000000000..8f0eba0a6
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nas100d-pci.c
@@ -0,0 +1,75 @@
+/*
+ * 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(const 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,
+ .ops = &ixp4xx_ops,
+ .preinit = nas100d_pci_preinit,
+ .setup = ixp4xx_setup,
+ .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 000000000..4e0f762bc
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nas100d-setup.c
@@ -0,0 +1,336 @@
+/*
+ * 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/gpio.h>
+#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>
+
+#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 and assert power off */
+ gpio_direction_output(NAS100D_PO_GPIO, 1);
+}
+
+/* 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_set_value(NAS100D_LED_PWR_GPIO, 0);
+ } 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 int __init nas100d_gpio_init(void)
+{
+ if (!machine_is_nas100d())
+ return 0;
+
+ /*
+ * 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.
+ */
+
+ /* Request the power off GPIO */
+ gpio_request(NAS100D_PO_GPIO, "power off");
+
+ /* Make sure that the power button GPIO is set up as an input */
+ gpio_request(NAS100D_PB_GPIO, "power button");
+ gpio_direction_input(NAS100D_PB_GPIO);
+
+ /* 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));
+
+ return 0;
+}
+device_initcall(nas100d_gpio_init);
+
+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_TRIGGER_LOW, "NAS100D reset button", NULL) < 0) {
+
+ printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
+ gpio_to_irq(NAS100D_RB_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), 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 */
+ .atag_offset = 0x100,
+ .map_io = ixp4xx_map_io,
+ .init_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .init_machine = nas100d_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+ .restart = ixp4xx_restart,
+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 000000000..032defe11
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nslu2-pci.c
@@ -0,0 +1,71 @@
+/*
+ * 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(const 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,
+ .ops = &ixp4xx_ops,
+ .preinit = nslu2_pci_preinit,
+ .setup = ixp4xx_setup,
+ .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 000000000..88c025f52
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nslu2-setup.c
@@ -0,0 +1,313 @@
+/*
+ * 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/gpio.h>
+#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>
+
+#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 and assert power off */
+ gpio_direction_output(NSLU2_PO_GPIO, 1);
+}
+
+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 int __init nslu2_gpio_init(void)
+{
+ if (!machine_is_nslu2())
+ return 0;
+
+ /* Request the power off GPIO */
+ return gpio_request(NSLU2_PO_GPIO, "power off");
+}
+device_initcall(nslu2_gpio_init);
+
+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 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_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_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 */
+ .atag_offset = 0x100,
+ .map_io = ixp4xx_map_io,
+ .init_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = nslu2_timer_init,
+ .init_machine = nslu2_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+ .restart = ixp4xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-ixp4xx/omixp-setup.c b/arch/arm/mach-ixp4xx/omixp-setup.c
new file mode 100644
index 000000000..2d494b454
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/omixp-setup.c
@@ -0,0 +1,279 @@
+/*
+ * arch/arm/mach-ixp4xx/omixp-setup.c
+ *
+ * omicron ixp4xx board setup
+ * Copyright (C) 2009 OMICRON electronics GmbH
+ *
+ * based nslu2-setup.c, ixdp425-setup.c:
+ * 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/kernel.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/leds.h>
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+#include <mach/hardware.h>
+
+static struct resource omixp_flash_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ }, {
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct mtd_partition omixp_partitions[] = {
+ {
+ .name = "Recovery Bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ }, {
+ .name = "Calibration Data",
+ .size = 0x00020000,
+ .offset = 0x00020000,
+ }, {
+ .name = "Recovery FPGA",
+ .size = 0x00020000,
+ .offset = 0x00040000,
+ }, {
+ .name = "Release Bootloader",
+ .size = 0x00020000,
+ .offset = 0x00060000,
+ }, {
+ .name = "Release FPGA",
+ .size = 0x00020000,
+ .offset = 0x00080000,
+ }, {
+ .name = "Kernel",
+ .size = 0x00160000,
+ .offset = 0x000a0000,
+ }, {
+ .name = "Filesystem",
+ .size = 0x00C00000,
+ .offset = 0x00200000,
+ }, {
+ .name = "Persistent Storage",
+ .size = 0x00200000,
+ .offset = 0x00E00000,
+ },
+};
+
+static struct flash_platform_data omixp_flash_data[] = {
+ {
+ .map_name = "cfi_probe",
+ .parts = omixp_partitions,
+ .nr_parts = ARRAY_SIZE(omixp_partitions),
+ }, {
+ .map_name = "cfi_probe",
+ .parts = NULL,
+ .nr_parts = 0,
+ },
+};
+
+static struct platform_device omixp_flash_device[] = {
+ {
+ .name = "IXP4XX-Flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &omixp_flash_data[0],
+ },
+ .resource = &omixp_flash_resources[0],
+ .num_resources = 1,
+ }, {
+ .name = "IXP4XX-Flash",
+ .id = 1,
+ .dev = {
+ .platform_data = &omixp_flash_data[1],
+ },
+ .resource = &omixp_flash_resources[1],
+ .num_resources = 1,
+ },
+};
+
+/* Swap UART's - These boards have the console on UART2. The following
+ * configuration is used:
+ * ttyS0 .. UART2
+ * ttyS1 .. UART1
+ * This way standard images can be used with the kernel that expect
+ * the console on ttyS0.
+ */
+static struct resource omixp_uart_resources[] = {
+ {
+ .start = IXP4XX_UART2_BASE_PHYS,
+ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IXP4XX_UART1_BASE_PHYS,
+ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct plat_serial8250_port omixp_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,
+ }, {
+ .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,
+ }, {
+ /* list termination */
+ }
+};
+
+static struct platform_device omixp_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev.platform_data = omixp_uart_data,
+ .num_resources = 2,
+ .resource = omixp_uart_resources,
+};
+
+static struct gpio_led mic256_led_pins[] = {
+ {
+ .name = "LED-A",
+ .gpio = 7,
+ },
+};
+
+static struct gpio_led_platform_data mic256_led_data = {
+ .num_leds = ARRAY_SIZE(mic256_led_pins),
+ .leds = mic256_led_pins,
+};
+
+static struct platform_device mic256_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = &mic256_led_data,
+};
+
+/* 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 *devixp_pldev[] __initdata = {
+ &omixp_uart,
+ &omixp_flash_device[0],
+ &ixdp425_eth[0],
+ &ixdp425_eth[1],
+};
+
+static struct platform_device *mic256_pldev[] __initdata = {
+ &omixp_uart,
+ &omixp_flash_device[0],
+ &mic256_leds,
+ &ixdp425_eth[0],
+ &ixdp425_eth[1],
+};
+
+static struct platform_device *miccpt_pldev[] __initdata = {
+ &omixp_uart,
+ &omixp_flash_device[0],
+ &omixp_flash_device[1],
+ &ixdp425_eth[0],
+ &ixdp425_eth[1],
+};
+
+static void __init omixp_init(void)
+{
+ ixp4xx_sys_init();
+
+ /* 16MiB Boot Flash */
+ omixp_flash_resources[0].start = IXP4XX_EXP_BUS_BASE(0);
+ omixp_flash_resources[0].end = IXP4XX_EXP_BUS_END(0);
+
+ /* 32 MiB Data Flash */
+ omixp_flash_resources[1].start = IXP4XX_EXP_BUS_BASE(2);
+ omixp_flash_resources[1].end = IXP4XX_EXP_BUS_END(2);
+
+ if (machine_is_devixp())
+ platform_add_devices(devixp_pldev, ARRAY_SIZE(devixp_pldev));
+ else if (machine_is_miccpt())
+ platform_add_devices(miccpt_pldev, ARRAY_SIZE(miccpt_pldev));
+ else if (machine_is_mic256())
+ platform_add_devices(mic256_pldev, ARRAY_SIZE(mic256_pldev));
+}
+
+#ifdef CONFIG_MACH_DEVIXP
+MACHINE_START(DEVIXP, "Omicron DEVIXP")
+ .atag_offset = 0x100,
+ .map_io = ixp4xx_map_io,
+ .init_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .init_machine = omixp_init,
+ .restart = ixp4xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_MICCPT
+MACHINE_START(MICCPT, "Omicron MICCPT")
+ .atag_offset = 0x100,
+ .map_io = ixp4xx_map_io,
+ .init_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .init_machine = omixp_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+ .restart = ixp4xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_MIC256
+MACHINE_START(MIC256, "Omicron MIC256")
+ .atag_offset = 0x100,
+ .map_io = ixp4xx_map_io,
+ .init_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .init_machine = omixp_init,
+ .restart = ixp4xx_restart,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-ixp4xx/vulcan-pci.c b/arch/arm/mach-ixp4xx/vulcan-pci.c
new file mode 100644
index 000000000..a4220fa5e
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/vulcan-pci.c
@@ -0,0 +1,72 @@
+/*
+ * 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(const 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,
+ .ops = &ixp4xx_ops,
+ .preinit = vulcan_pci_preinit,
+ .setup = ixp4xx_setup,
+ .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 000000000..d599e354c
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/vulcan-setup.c
@@ -0,0 +1,250 @@
+/*
+ * 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,
+ .ext_pullup_enable_pin = -EINVAL,
+};
+
+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_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .atag_offset = 0x100,
+ .init_machine = vulcan_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+ .restart = ixp4xx_restart,
+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 000000000..c92e5b82a
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/wg302v2-pci.c
@@ -0,0 +1,62 @@
+/*
+ * 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(const 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,
+ .ops = &ixp4xx_ops,
+ .preinit = wg302v2_pci_preinit,
+ .setup = ixp4xx_setup,
+ .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 000000000..8f9ea2f3a
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/wg302v2-setup.c
@@ -0,0 +1,111 @@
+/*
+ * 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_early = ixp4xx_init_early,
+ .init_irq = ixp4xx_init_irq,
+ .init_time = ixp4xx_timer_init,
+ .atag_offset = 0x100,
+ .init_machine = wg302v2_init,
+#if defined(CONFIG_PCI)
+ .dma_zone_size = SZ_64M,
+#endif
+ .restart = ixp4xx_restart,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-keystone/Kconfig b/arch/arm/mach-keystone/Kconfig
new file mode 100644
index 000000000..ea955f6db
--- /dev/null
+++ b/arch/arm/mach-keystone/Kconfig
@@ -0,0 +1,16 @@
+config ARCH_KEYSTONE
+ bool "Texas Instruments Keystone Devices"
+ depends on ARCH_MULTI_V7
+ depends on ARM_PATCH_PHYS_VIRT
+ select ARM_GIC
+ select HAVE_ARM_ARCH_TIMER
+ select CLKSRC_MMIO
+ select ARM_ERRATA_798181 if SMP
+ select COMMON_CLK_KEYSTONE
+ select ARCH_SUPPORTS_BIG_ENDIAN
+ select ZONE_DMA if ARM_LPAE
+ select MIGHT_HAVE_PCI
+ select PCI_DOMAINS if PCI
+ help
+ Support for boards based on the Texas Instruments Keystone family of
+ SoCs.
diff --git a/arch/arm/mach-keystone/Makefile b/arch/arm/mach-keystone/Makefile
new file mode 100644
index 000000000..25d92396f
--- /dev/null
+++ b/arch/arm/mach-keystone/Makefile
@@ -0,0 +1,9 @@
+obj-y := keystone.o smc.o
+
+plus_sec := $(call as-instr,.arch_extension sec,+sec)
+AFLAGS_smc.o :=-Wa,-march=armv7-a$(plus_sec)
+
+obj-$(CONFIG_SMP) += platsmp.o
+
+# PM domain driver for Keystone SOCs
+obj-$(CONFIG_ARCH_KEYSTONE) += pm_domain.o
diff --git a/arch/arm/mach-keystone/Makefile.boot b/arch/arm/mach-keystone/Makefile.boot
new file mode 100644
index 000000000..f3835c43a
--- /dev/null
+++ b/arch/arm/mach-keystone/Makefile.boot
@@ -0,0 +1 @@
+zreladdr-y := 0x80008000
diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c
new file mode 100644
index 000000000..066208758
--- /dev/null
+++ b/arch/arm/mach-keystone/keystone.c
@@ -0,0 +1,119 @@
+/*
+ * Keystone2 based boards and SOC related code.
+ *
+ * Copyright 2013 Texas Instruments, Inc.
+ * Cyril Chemparathy <cyril@ti.com>
+ * Santosh Shilimkar <santosh.shillimkar@ti.com>
+ *
+ * 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.
+ */
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/memblock.h>
+
+#include <asm/setup.h>
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/smp_plat.h>
+#include <asm/memory.h>
+
+#include "memory.h"
+
+#include "keystone.h"
+
+static struct notifier_block platform_nb;
+static unsigned long keystone_dma_pfn_offset __read_mostly;
+
+static int keystone_platform_notifier(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct device *dev = data;
+
+ if (event != BUS_NOTIFY_ADD_DEVICE)
+ return NOTIFY_DONE;
+
+ if (!dev)
+ return NOTIFY_BAD;
+
+ if (!dev->of_node) {
+ dev->dma_pfn_offset = keystone_dma_pfn_offset;
+ dev_err(dev, "set dma_pfn_offset%08lx\n",
+ dev->dma_pfn_offset);
+ }
+ return NOTIFY_OK;
+}
+
+static void __init keystone_init(void)
+{
+ keystone_pm_runtime_init();
+ if (platform_nb.notifier_call)
+ bus_register_notifier(&platform_bus_type, &platform_nb);
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static phys_addr_t keystone_virt_to_idmap(unsigned long x)
+{
+ return (phys_addr_t)(x) - CONFIG_PAGE_OFFSET + KEYSTONE_LOW_PHYS_START;
+}
+
+static void __init keystone_init_meminfo(void)
+{
+ bool lpae = IS_ENABLED(CONFIG_ARM_LPAE);
+ bool pvpatch = IS_ENABLED(CONFIG_ARM_PATCH_PHYS_VIRT);
+ phys_addr_t offset = PHYS_OFFSET - KEYSTONE_LOW_PHYS_START;
+ phys_addr_t mem_start, mem_end;
+
+ mem_start = memblock_start_of_DRAM();
+ mem_end = memblock_end_of_DRAM();
+
+ /* nothing to do if we are running out of the <32-bit space */
+ if (mem_start >= KEYSTONE_LOW_PHYS_START &&
+ mem_end <= KEYSTONE_LOW_PHYS_END)
+ return;
+
+ if (!lpae || !pvpatch) {
+ pr_crit("Enable %s%s%s to run outside 32-bit space\n",
+ !lpae ? __stringify(CONFIG_ARM_LPAE) : "",
+ (!lpae && !pvpatch) ? " and " : "",
+ !pvpatch ? __stringify(CONFIG_ARM_PATCH_PHYS_VIRT) : "");
+ }
+
+ if (mem_start < KEYSTONE_HIGH_PHYS_START ||
+ mem_end > KEYSTONE_HIGH_PHYS_END) {
+ pr_crit("Invalid address space for memory (%08llx-%08llx)\n",
+ (u64)mem_start, (u64)mem_end);
+ }
+
+ offset += KEYSTONE_HIGH_PHYS_START;
+ __pv_phys_pfn_offset = PFN_DOWN(offset);
+ __pv_offset = (offset - PAGE_OFFSET);
+
+ /* Populate the arch idmap hook */
+ arch_virt_to_idmap = keystone_virt_to_idmap;
+ platform_nb.notifier_call = keystone_platform_notifier;
+ keystone_dma_pfn_offset = PFN_DOWN(KEYSTONE_HIGH_PHYS_START -
+ KEYSTONE_LOW_PHYS_START);
+
+ pr_info("Switching to high address space at 0x%llx\n", (u64)offset);
+}
+
+static const char *const keystone_match[] __initconst = {
+ "ti,keystone",
+ NULL,
+};
+
+DT_MACHINE_START(KEYSTONE, "Keystone")
+#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE)
+ .dma_zone_size = SZ_2G,
+#endif
+ .smp = smp_ops(keystone_smp_ops),
+ .init_machine = keystone_init,
+ .dt_compat = keystone_match,
+ .init_meminfo = keystone_init_meminfo,
+MACHINE_END
diff --git a/arch/arm/mach-keystone/keystone.h b/arch/arm/mach-keystone/keystone.h
new file mode 100644
index 000000000..cd04a1c14
--- /dev/null
+++ b/arch/arm/mach-keystone/keystone.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2013 Texas Instruments, Inc.
+ * Cyril Chemparathy <cyril@ti.com>
+ * Santosh Shilimkar <santosh.shillimkar@ti.com>
+ *
+ * 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.
+ */
+
+#ifndef __KEYSTONE_H__
+#define __KEYSTONE_H__
+
+#define KEYSTONE_MON_CPU_UP_IDX 0x00
+
+#ifndef __ASSEMBLER__
+
+extern struct smp_operations keystone_smp_ops;
+extern void secondary_startup(void);
+extern u32 keystone_cpu_smc(u32 command, u32 cpu, u32 addr);
+extern int keystone_pm_runtime_init(void);
+
+#endif /* __ASSEMBLER__ */
+#endif /* __KEYSTONE_H__ */
diff --git a/arch/arm/mach-keystone/memory.h b/arch/arm/mach-keystone/memory.h
new file mode 100644
index 000000000..b854fb18e
--- /dev/null
+++ b/arch/arm/mach-keystone/memory.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2014 Texas Instruments, Inc.
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * 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.
+ */
+#ifndef __MEMORY_H
+#define __MEMORY_H
+
+#define MAX_PHYSMEM_BITS 36
+#define SECTION_SIZE_BITS 34
+
+#define KEYSTONE_LOW_PHYS_START 0x80000000ULL
+#define KEYSTONE_LOW_PHYS_SIZE 0x80000000ULL /* 2G */
+#define KEYSTONE_LOW_PHYS_END (KEYSTONE_LOW_PHYS_START + \
+ KEYSTONE_LOW_PHYS_SIZE - 1)
+
+#define KEYSTONE_HIGH_PHYS_START 0x800000000ULL
+#define KEYSTONE_HIGH_PHYS_SIZE 0x400000000ULL /* 16G */
+#define KEYSTONE_HIGH_PHYS_END (KEYSTONE_HIGH_PHYS_START + \
+ KEYSTONE_HIGH_PHYS_SIZE - 1)
+#endif /* __MEMORY_H */
diff --git a/arch/arm/mach-keystone/platsmp.c b/arch/arm/mach-keystone/platsmp.c
new file mode 100644
index 000000000..5f46a7cf9
--- /dev/null
+++ b/arch/arm/mach-keystone/platsmp.c
@@ -0,0 +1,57 @@
+/*
+ * Keystone SOC SMP platform code
+ *
+ * Copyright 2013 Texas Instruments, Inc.
+ * Cyril Chemparathy <cyril@ti.com>
+ * Santosh Shilimkar <santosh.shillimkar@ti.com>
+ *
+ * Based on platsmp.c, Copyright (C) 2002 ARM Ltd.
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/smp_plat.h>
+#include <asm/prom.h>
+#include <asm/tlbflush.h>
+#include <asm/pgtable.h>
+
+#include "keystone.h"
+
+static int keystone_smp_boot_secondary(unsigned int cpu,
+ struct task_struct *idle)
+{
+ unsigned long start = virt_to_idmap(&secondary_startup);
+ int error;
+
+ pr_debug("keystone-smp: booting cpu %d, vector %08lx\n",
+ cpu, start);
+
+ error = keystone_cpu_smc(KEYSTONE_MON_CPU_UP_IDX, cpu, start);
+ if (error)
+ pr_err("CPU %d bringup failed with %d\n", cpu, error);
+
+ return error;
+}
+
+#ifdef CONFIG_ARM_LPAE
+static void __cpuinit keystone_smp_secondary_initmem(unsigned int cpu)
+{
+ pgd_t *pgd0 = pgd_offset_k(0);
+ cpu_set_ttbr(1, __pa(pgd0) + TTBR1_OFFSET);
+ local_flush_tlb_all();
+}
+#else
+static inline void __cpuinit keystone_smp_secondary_initmem(unsigned int cpu)
+{}
+#endif
+
+struct smp_operations keystone_smp_ops __initdata = {
+ .smp_boot_secondary = keystone_smp_boot_secondary,
+ .smp_secondary_init = keystone_smp_secondary_initmem,
+};
diff --git a/arch/arm/mach-keystone/pm_domain.c b/arch/arm/mach-keystone/pm_domain.c
new file mode 100644
index 000000000..41bebfd29
--- /dev/null
+++ b/arch/arm/mach-keystone/pm_domain.c
@@ -0,0 +1,80 @@
+/*
+ * PM domain driver for Keystone2 devices
+ *
+ * Copyright 2013 Texas Instruments, Inc.
+ * Santosh Shilimkar <santosh.shillimkar@ti.com>
+ *
+ * Based on Kevins work on DAVINCI SOCs
+ * Kevin Hilman <khilman@linaro.org>
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/pm_runtime.h>
+#include <linux/pm_clock.h>
+#include <linux/platform_device.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+
+#ifdef CONFIG_PM
+static int keystone_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_clk_suspend(dev);
+ if (ret) {
+ pm_generic_runtime_resume(dev);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int keystone_pm_runtime_resume(struct device *dev)
+{
+ dev_dbg(dev, "%s\n", __func__);
+
+ pm_clk_resume(dev);
+
+ return pm_generic_runtime_resume(dev);
+}
+#endif
+
+static struct dev_pm_domain keystone_pm_domain = {
+ .ops = {
+ SET_RUNTIME_PM_OPS(keystone_pm_runtime_suspend,
+ keystone_pm_runtime_resume, NULL)
+ USE_PLATFORM_PM_SLEEP_OPS
+ },
+};
+
+static struct pm_clk_notifier_block platform_domain_notifier = {
+ .pm_domain = &keystone_pm_domain,
+};
+
+static const struct of_device_id of_keystone_table[] = {
+ {.compatible = "ti,keystone"},
+ { /* end of list */ },
+};
+
+int __init keystone_pm_runtime_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, of_keystone_table);
+ if (!np)
+ return 0;
+
+ pm_clk_add_notifier(&platform_bus_type, &platform_domain_notifier);
+
+ return 0;
+}
diff --git a/arch/arm/mach-keystone/smc.S b/arch/arm/mach-keystone/smc.S
new file mode 100644
index 000000000..d15de8179
--- /dev/null
+++ b/arch/arm/mach-keystone/smc.S
@@ -0,0 +1,28 @@
+/*
+ * Keystone Secure APIs
+ *
+ * Copyright (C) 2013 Texas Instruments, Inc.
+ * 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>
+
+/**
+ * u32 keystone_cpu_smc(u32 command, u32 cpu, u32 addr)
+ *
+ * Low level CPU monitor API
+ * @command: Monitor command.
+ * @cpu: CPU Number
+ * @addr: Kernel jump address for boot CPU
+ *
+ * Return: Non zero value on failure
+ */
+ENTRY(keystone_cpu_smc)
+ stmfd sp!, {r4-r11, lr}
+ smc #0
+ ldmfd sp!, {r4-r11, pc}
+ENDPROC(keystone_cpu_smc)
diff --git a/arch/arm/mach-ks8695/Kconfig b/arch/arm/mach-ks8695/Kconfig
new file mode 100644
index 000000000..a545976bd
--- /dev/null
+++ b/arch/arm/mach-ks8695/Kconfig
@@ -0,0 +1,87 @@
+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.
+
+config MACH_LITE300
+ bool "SecureComputing SG300"
+ help
+ Say 'Y' here if you want your kernel to support the
+ SecureComputing / SnapGear SG300 VPN Internet Router.
+ See http://www.securecomputing.com for more details.
+
+config MACH_SG310
+ bool "McAfee SG310"
+ help
+ Say 'Y' here if you want your kernel to support the
+ McAfee / SnapGear SG310 VPN Internet Router.
+ See http://www.mcafee.com for more details.
+
+config MACH_SE4200
+ bool "SecureComputing SE4200"
+ help
+ Say 'Y' here if you want your kernel to support the
+ SecureComputing / SnapGear SE4200 Secure Wireless VPN
+ Internet Router.
+ See http://www.securecomputing.com for more details.
+
+config MACH_CM4002
+ bool "OpenGear CM4002"
+ help
+ Say 'Y' here if you want your kernel to support the OpenGear
+ CM4002 Secure Access Server. See http://www.opengear.com for
+ more details.
+
+config MACH_CM4008
+ bool "OpenGear CM4008"
+ select MIGHT_HAVE_PCI
+ help
+ Say 'Y' here if you want your kernel to support the OpenGear
+ CM4008 Console Server. See http://www.opengear.com for more
+ details.
+
+config MACH_CM41xx
+ bool "OpenGear CM41xx"
+ select MIGHT_HAVE_PCI
+ help
+ Say 'Y' here if you want your kernel to support the OpenGear
+ CM4016 or CM4048 Console Servers. See http://www.opengear.com for
+ more details.
+
+config MACH_IM4004
+ bool "OpenGear IM4004"
+ select MIGHT_HAVE_PCI
+ help
+ Say 'Y' here if you want your kernel to support the OpenGear
+ IM4004 Secure Access Server. See http://www.opengear.com for
+ more details.
+
+config MACH_IM42xx
+ bool "OpenGear IM42xx"
+ select MIGHT_HAVE_PCI
+ help
+ Say 'Y' here if you want your kernel to support the OpenGear
+ IM4216 or IM4248 Console Servers. See http://www.opengear.com for
+ more details.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-ks8695/Makefile b/arch/arm/mach-ks8695/Makefile
new file mode 100644
index 000000000..8ecb7973a
--- /dev/null
+++ b/arch/arm/mach-ks8695/Makefile
@@ -0,0 +1,22 @@
+# arch/arm/mach-ks8695/Makefile
+#
+# Makefile for KS8695 architecture support
+#
+
+obj-y := cpu.o irq.o time.o devices.o
+
+# PCI support is optional
+obj-$(CONFIG_PCI) += pci.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
+obj-$(CONFIG_MACH_LITE300) += board-sg.o
+obj-$(CONFIG_MACH_SG310) += board-sg.o
+obj-$(CONFIG_MACH_SE4200) += board-sg.o
+obj-$(CONFIG_MACH_CM4002) += board-og.o
+obj-$(CONFIG_MACH_CM4008) += board-og.o
+obj-$(CONFIG_MACH_CM41xx) += board-og.o
+obj-$(CONFIG_MACH_IM4004) += board-og.o
+obj-$(CONFIG_MACH_IM42xx) += board-og.o
diff --git a/arch/arm/mach-ks8695/Makefile.boot b/arch/arm/mach-ks8695/Makefile.boot
new file mode 100644
index 000000000..c9b0bebcf
--- /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 000000000..9f9c0441a
--- /dev/null
+++ b/arch/arm/mach-ks8695/board-acs5k.c
@@ -0,0 +1,232 @@
+/*
+ * 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/gpio.h>
+#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/platform_data/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-ks8695.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 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. */
+ .atag_offset = 0x100,
+ .map_io = ks8695_map_io,
+ .init_irq = ks8695_init_irq,
+ .init_machine = acs5k_init,
+ .init_time = ks8695_timer_init,
+ .restart = ks8695_restart,
+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 000000000..d37c218c3
--- /dev/null
+++ b/arch/arm/mach-ks8695/board-dsm320.c
@@ -0,0 +1,130 @@
+/*
+ * 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/gpio.h>
+#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-ks8695.h>
+
+#include "generic.h"
+
+#ifdef CONFIG_PCI
+static int dsm320_pci_map_irq(const 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. */
+ .atag_offset = 0x100,
+ .map_io = ks8695_map_io,
+ .init_irq = ks8695_init_irq,
+ .init_machine = dsm320_init,
+ .init_time = ks8695_timer_init,
+ .restart = ks8695_restart,
+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 000000000..3acbdfd31
--- /dev/null
+++ b/arch/arm/mach-ks8695/board-micrel.c
@@ -0,0 +1,62 @@
+/*
+ * 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/gpio.h>
+#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-ks8695.h>
+#include <mach/devices.h>
+
+#include "generic.h"
+
+#ifdef CONFIG_PCI
+static int micrel_pci_map_irq(const 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. */
+ .atag_offset = 0x100,
+ .map_io = ks8695_map_io,
+ .init_irq = ks8695_init_irq,
+ .init_machine = micrel_init,
+ .init_time = ks8695_timer_init,
+ .restart = ks8695_restart,
+MACHINE_END
diff --git a/arch/arm/mach-ks8695/board-og.c b/arch/arm/mach-ks8695/board-og.c
new file mode 100644
index 000000000..f2658168e
--- /dev/null
+++ b/arch/arm/mach-ks8695/board-og.c
@@ -0,0 +1,200 @@
+/*
+ * board-og.c -- support for the OpenGear KS8695 based boards.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/devices.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-ks8695.h>
+#include "generic.h"
+
+static int og_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (machine_is_im4004() && (slot == 8))
+ return KS8695_IRQ_EXTERN1;
+ return KS8695_IRQ_EXTERN0;
+}
+
+static struct ks8695_pci_cfg __initdata og_pci = {
+ .mode = KS8695_MODE_PCI,
+ .map_irq = og_pci_map_irq,
+};
+
+static void __init og_register_pci(void)
+{
+ /* Initialize the GPIO lines for interrupt mode */
+ ks8695_gpio_interrupt(KS8695_GPIO_0, IRQ_TYPE_LEVEL_LOW);
+
+ /* Cardbus Slot */
+ if (machine_is_im4004())
+ ks8695_gpio_interrupt(KS8695_GPIO_1, IRQ_TYPE_LEVEL_LOW);
+
+ if (IS_ENABLED(CONFIG_PCI))
+ ks8695_init_pci(&og_pci);
+}
+
+/*
+ * The PCI bus reset is driven by a dedicated GPIO line. Toggle it here
+ * and bring the PCI bus out of reset.
+ */
+static void __init og_pci_bus_reset(void)
+{
+ unsigned int rstline = 1;
+
+ /* Some boards use a different GPIO as the PCI reset line */
+ if (machine_is_im4004())
+ rstline = 2;
+ else if (machine_is_im42xx())
+ rstline = 0;
+
+ gpio_request(rstline, "PCI reset");
+ gpio_direction_output(rstline, 0);
+
+ /* Drive a reset on the PCI reset line */
+ gpio_set_value(rstline, 1);
+ gpio_set_value(rstline, 0);
+ mdelay(100);
+ gpio_set_value(rstline, 1);
+ mdelay(100);
+}
+
+/*
+ * Direct connect serial ports (non-PCI that is).
+ */
+#define S8250_PHYS 0x03800000
+#define S8250_VIRT 0xf4000000
+#define S8250_SIZE 0x00100000
+
+static struct __initdata map_desc og_io_desc[] = {
+ {
+ .virtual = S8250_VIRT,
+ .pfn = __phys_to_pfn(S8250_PHYS),
+ .length = S8250_SIZE,
+ .type = MT_DEVICE,
+ }
+};
+
+static struct resource og_uart_resources[] = {
+ {
+ .start = S8250_VIRT,
+ .end = S8250_VIRT + S8250_SIZE,
+ .flags = IORESOURCE_MEM
+ },
+};
+
+static struct plat_serial8250_port og_uart_data[] = {
+ {
+ .mapbase = S8250_VIRT,
+ .membase = (char *) S8250_VIRT,
+ .irq = 3,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = 115200 * 16,
+ },
+ { },
+};
+
+static struct platform_device og_uart = {
+ .name = "serial8250",
+ .id = 0,
+ .dev.platform_data = og_uart_data,
+ .num_resources = 1,
+ .resource = og_uart_resources
+};
+
+static struct platform_device *og_devices[] __initdata = {
+ &og_uart
+};
+
+static void __init og_init(void)
+{
+ ks8695_register_gpios();
+
+ if (machine_is_cm4002()) {
+ ks8695_gpio_interrupt(KS8695_GPIO_1, IRQ_TYPE_LEVEL_HIGH);
+ iotable_init(og_io_desc, ARRAY_SIZE(og_io_desc));
+ platform_add_devices(og_devices, ARRAY_SIZE(og_devices));
+ } else {
+ og_pci_bus_reset();
+ og_register_pci();
+ }
+
+ ks8695_add_device_lan();
+ ks8695_add_device_wan();
+}
+
+#ifdef CONFIG_MACH_CM4002
+MACHINE_START(CM4002, "OpenGear/CM4002")
+ /* OpenGear Inc. */
+ .atag_offset = 0x100,
+ .map_io = ks8695_map_io,
+ .init_irq = ks8695_init_irq,
+ .init_machine = og_init,
+ .init_time = ks8695_timer_init,
+ .restart = ks8695_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_CM4008
+MACHINE_START(CM4008, "OpenGear/CM4008")
+ /* OpenGear Inc. */
+ .atag_offset = 0x100,
+ .map_io = ks8695_map_io,
+ .init_irq = ks8695_init_irq,
+ .init_machine = og_init,
+ .init_time = ks8695_timer_init,
+ .restart = ks8695_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_CM41xx
+MACHINE_START(CM41XX, "OpenGear/CM41xx")
+ /* OpenGear Inc. */
+ .atag_offset = 0x100,
+ .map_io = ks8695_map_io,
+ .init_irq = ks8695_init_irq,
+ .init_machine = og_init,
+ .init_time = ks8695_timer_init,
+ .restart = ks8695_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_IM4004
+MACHINE_START(IM4004, "OpenGear/IM4004")
+ /* OpenGear Inc. */
+ .atag_offset = 0x100,
+ .map_io = ks8695_map_io,
+ .init_irq = ks8695_init_irq,
+ .init_machine = og_init,
+ .init_time = ks8695_timer_init,
+ .restart = ks8695_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_IM42xx
+MACHINE_START(IM42XX, "OpenGear/IM42xx")
+ /* OpenGear Inc. */
+ .atag_offset = 0x100,
+ .map_io = ks8695_map_io,
+ .init_irq = ks8695_init_irq,
+ .init_machine = og_init,
+ .init_time = ks8695_timer_init,
+ .restart = ks8695_restart,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-ks8695/board-sg.c b/arch/arm/mach-ks8695/board-sg.c
new file mode 100644
index 000000000..fdf2352d2
--- /dev/null
+++ b/arch/arm/mach-ks8695/board-sg.c
@@ -0,0 +1,121 @@
+/*
+ * board-sg.c -- support for the SnapGear KS8695 based boards
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.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 <mach/devices.h>
+#include "generic.h"
+
+/*
+ * The SG310 machine type is fitted with a conventional 8MB Strataflash
+ * device. Define its partitioning.
+ */
+#define FL_BASE 0x02000000
+#define FL_SIZE SZ_8M
+
+static struct mtd_partition sg_mtd_partitions[] = {
+ [0] = {
+ .name = "SnapGear Boot Loader",
+ .size = SZ_128K,
+ },
+ [1] = {
+ .name = "SnapGear non-volatile configuration",
+ .size = SZ_512K,
+ .offset = SZ_256K,
+ },
+ [2] = {
+ .name = "SnapGear image",
+ .offset = SZ_512K + SZ_256K,
+ },
+ [3] = {
+ .name = "SnapGear StrataFlash",
+ },
+ [4] = {
+ .name = "SnapGear Boot Tags",
+ .size = SZ_128K,
+ .offset = SZ_128K,
+ },
+};
+
+static struct physmap_flash_data sg_mtd_pdata = {
+ .width = 1,
+ .nr_parts = ARRAY_SIZE(sg_mtd_partitions),
+ .parts = sg_mtd_partitions,
+};
+
+
+static struct resource sg_mtd_resource[] = {
+ [0] = {
+ .start = FL_BASE,
+ .end = FL_BASE + FL_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device sg_mtd_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(sg_mtd_resource),
+ .resource = sg_mtd_resource,
+ .dev = {
+ .platform_data = &sg_mtd_pdata,
+ },
+};
+
+static void __init sg_init(void)
+{
+ ks8695_add_device_lan();
+ ks8695_add_device_wan();
+
+ if (machine_is_sg310())
+ platform_device_register(&sg_mtd_device);
+}
+
+#ifdef CONFIG_MACH_LITE300
+MACHINE_START(LITE300, "SecureComputing/SG300")
+ /* SnapGear */
+ .atag_offset = 0x100,
+ .map_io = ks8695_map_io,
+ .init_irq = ks8695_init_irq,
+ .init_machine = sg_init,
+ .init_time = ks8695_timer_init,
+ .restart = ks8695_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_SG310
+MACHINE_START(SG310, "McAfee/SG310")
+ /* SnapGear */
+ .atag_offset = 0x100,
+ .map_io = ks8695_map_io,
+ .init_irq = ks8695_init_irq,
+ .init_machine = sg_init,
+ .init_time = ks8695_timer_init,
+ .restart = ks8695_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_SE4200
+MACHINE_START(SE4200, "SecureComputing/SE4200")
+ /* SnapGear */
+ .atag_offset = 0x100,
+ .map_io = ks8695_map_io,
+ .init_irq = ks8695_init_irq,
+ .init_machine = sg_init,
+ .init_time = ks8695_timer_init,
+ .restart = ks8695_restart,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-ks8695/cpu.c b/arch/arm/mach-ks8695/cpu.c
new file mode 100644
index 000000000..ddb242229
--- /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 = (unsigned long)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 000000000..47399bc3c
--- /dev/null
+++ b/arch/arm/mach-ks8695/devices.c
@@ -0,0 +1,197 @@
+/*
+ * 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/gpio.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);
+}
+
+
+/* -------------------------------------------------------------------- */
+
+/*
+ * 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 000000000..43253f8e6
--- /dev/null
+++ b/arch/arm/mach-ks8695/generic.h
@@ -0,0 +1,16 @@
+/*
+ * 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 void ks8695_restart(enum reboot_mode, const char *);
+extern void ks8695_timer_init(void);
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 000000000..1e6594a0f
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/devices.h
@@ -0,0 +1,32 @@
+/*
+ * 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);
+
+ /* 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)(const 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 000000000..8315b34f3
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/entry-macro.S
@@ -0,0 +1,47 @@
+/*
+ * 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 get_irqnr_preamble, base, tmp
+ ldr \base, =KS8695_IRQ_VA @ Base address of interrupt controller
+ .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-ks8695.h b/arch/arm/mach-ks8695/include/mach/gpio-ks8695.h
new file mode 100644
index 000000000..6eb034d60
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/gpio-ks8695.h
@@ -0,0 +1,39 @@
+/*
+ * 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 __MACH_KS8659_GPIO_H
+#define __MACH_KS8659_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);
+
+/* Register the GPIOs */
+extern void ks8695_register_gpios(void);
+
+#endif /* __MACH_KS8659_GPIO_H */
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 000000000..5090338c0
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/hardware.h
@@ -0,0 +1,45 @@
+/*
+ * 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 IOMEM(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
+
+#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 000000000..86fc9e6ce
--- /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 000000000..ab0d27fa8
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/memory.h
@@ -0,0 +1,51 @@
+/*
+ * 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>
+
+#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((unsigned long)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 000000000..90614a7d0
--- /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 000000000..815ce5c2e
--- /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 000000000..352b7e870
--- /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 000000000..82c5f3791
--- /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 000000000..55806bc68
--- /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 000000000..2740c5249
--- /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 000000000..75a9db6ed
--- /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 000000000..97e8acb1c
--- /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 000000000..57c20be0c
--- /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-uart.h b/arch/arm/mach-ks8695/include/mach/regs-uart.h
new file mode 100644
index 000000000..8581fbc62
--- /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 000000000..c475bed22
--- /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/uncompress.h b/arch/arm/mach-ks8695/include/mach/uncompress.h
new file mode 100644
index 000000000..c089a1aea
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/uncompress.h
@@ -0,0 +1,36 @@
+/*
+ * 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((void __iomem*)KS8695_UART_PA + KS8695_URLS) & URLS_URTHRE))
+ barrier();
+
+ __raw_writel(c, (void __iomem*)KS8695_UART_PA + KS8695_URTH);
+}
+
+static inline void flush(void)
+{
+ while (!(__raw_readl((void __iomem*)KS8695_UART_PA + KS8695_URLS) & URLS_URTE))
+ barrier();
+}
+
+#define arch_decomp_setup()
+
+#endif
diff --git a/arch/arm/mach-ks8695/irq.c b/arch/arm/mach-ks8695/irq.c
new file mode 100644
index 000000000..76802aac0
--- /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/device.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/pci.c b/arch/arm/mach-ks8695/pci.c
new file mode 100644
index 000000000..c1bc4c371
--- /dev/null
+++ b/arch/arm/mach-ks8695/pci.c
@@ -0,0 +1,260 @@
+/*
+ * 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 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);
+ }
+}
+
+static void __iomem *ks8695_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
+ int where)
+{
+ ks8695_pci_setupconfig(bus->number, devfn, where);
+ return KS8695_PCI_VA + KS8695_PBCD;
+}
+
+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 = {
+ .map_bus = ks8695_pci_map_bus,
+ .read = pci_generic_config_read32,
+ .write = pci_generic_config_write32,
+};
+
+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);
+
+ pci_add_resource_offset(&sys->resources, &pci_io, sys->io_offset);
+ pci_add_resource_offset(&sys->resources, &pci_mem, sys->mem_offset);
+
+ /* 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,
+ .ops = &ks8695_pci_ops,
+ .preinit = ks8695_pci_preinit,
+ .setup = ks8695_pci_setup,
+ .postinit = NULL,
+ .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;
+ }
+
+ pcibios_min_io = 0;
+ pcibios_min_mem = 0;
+
+ 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 000000000..a197874bf
--- /dev/null
+++ b/arch/arm/mach-ks8695/time.c
@@ -0,0 +1,173 @@
+/*
+ * 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 <linux/clockchips.h>
+
+#include <asm/mach/time.h>
+#include <asm/system_misc.h>
+
+#include <mach/regs-irq.h>
+
+#include "generic.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 */
+
+static void ks8695_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ u32 tmcon;
+
+ if (mode == CLOCK_EVT_FEAT_PERIODIC) {
+ u32 rate = DIV_ROUND_CLOSEST(KS8695_CLOCK_RATE, HZ);
+ u32 half = DIV_ROUND_CLOSEST(rate, 2);
+
+ /* Disable timer 1 */
+ tmcon = readl_relaxed(KS8695_TMR_VA + KS8695_TMCON);
+ tmcon &= ~TMCON_T1EN;
+ writel_relaxed(tmcon, KS8695_TMR_VA + KS8695_TMCON);
+
+ /* Both registers need to count down */
+ writel_relaxed(half, KS8695_TMR_VA + KS8695_T1TC);
+ writel_relaxed(half, KS8695_TMR_VA + KS8695_T1PD);
+
+ /* Re-enable timer1 */
+ tmcon |= TMCON_T1EN;
+ writel_relaxed(tmcon, KS8695_TMR_VA + KS8695_TMCON);
+ }
+}
+
+static int ks8695_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+
+{
+ u32 half = DIV_ROUND_CLOSEST(cycles, 2);
+ u32 tmcon;
+
+ /* Disable timer 1 */
+ tmcon = readl_relaxed(KS8695_TMR_VA + KS8695_TMCON);
+ tmcon &= ~TMCON_T1EN;
+ writel_relaxed(tmcon, KS8695_TMR_VA + KS8695_TMCON);
+
+ /* Both registers need to count down */
+ writel_relaxed(half, KS8695_TMR_VA + KS8695_T1TC);
+ writel_relaxed(half, KS8695_TMR_VA + KS8695_T1PD);
+
+ /* Re-enable timer1 */
+ tmcon |= TMCON_T1EN;
+ writel_relaxed(tmcon, KS8695_TMR_VA + KS8695_TMCON);
+
+ return 0;
+}
+
+static struct clock_event_device clockevent_ks8695 = {
+ .name = "ks8695_t1tc",
+ .rating = 300, /* Reasonably fast and accurate clock event */
+ .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
+ .set_next_event = ks8695_set_next_event,
+ .set_mode = ks8695_set_mode,
+};
+
+/*
+ * IRQ handler for the timer.
+ */
+static irqreturn_t ks8695_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_ks8695;
+
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction ks8695_timer_irq = {
+ .name = "ks8695_tick",
+ .flags = IRQF_TIMER,
+ .handler = ks8695_timer_interrupt,
+};
+
+static void ks8695_timer_setup(void)
+{
+ unsigned long tmcon;
+
+ /* Disable timer 0 and 1 */
+ tmcon = readl_relaxed(KS8695_TMR_VA + KS8695_TMCON);
+ tmcon &= ~TMCON_T0EN;
+ tmcon &= ~TMCON_T1EN;
+ writel_relaxed(tmcon, KS8695_TMR_VA + KS8695_TMCON);
+
+ /*
+ * Use timer 1 to fire IRQs on the timeline, minimum 2 cycles
+ * (one on each counter) maximum 2*2^32, but the API will only
+ * accept up to a 32bit full word (0xFFFFFFFFU).
+ */
+ clockevents_config_and_register(&clockevent_ks8695,
+ KS8695_CLOCK_RATE, 2,
+ 0xFFFFFFFFU);
+}
+
+void __init ks8695_timer_init(void)
+{
+ ks8695_timer_setup();
+
+ /* Enable timer interrupts */
+ setup_irq(KS8695_IRQ_TIMER1, &ks8695_timer_irq);
+}
+
+void ks8695_restart(enum reboot_mode reboot_mode, const char *cmd)
+{
+ unsigned int reg;
+
+ if (reboot_mode == REBOOT_SOFT)
+ soft_restart(0);
+
+ /* disable timer0 */
+ reg = readl_relaxed(KS8695_TMR_VA + KS8695_TMCON);
+ writel_relaxed(reg & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
+
+ /* enable watchdog mode */
+ writel_relaxed((10 << 8) | T0TC_WATCHDOG, KS8695_TMR_VA + KS8695_T0TC);
+
+ /* re-enable timer0 */
+ writel_relaxed(reg | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
+}
diff --git a/arch/arm/mach-lpc32xx/Makefile b/arch/arm/mach-lpc32xx/Makefile
new file mode 100644
index 000000000..f5db805ab
--- /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 += 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 000000000..d7392a475
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/Makefile.boot
@@ -0,0 +1,3 @@
+ 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 000000000..dd5d6f532
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/clock.c
@@ -0,0 +1,1287 @@
+/*
+ * 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/export.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/delay.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 DEFINE_SPINLOCK(global_clkregs_lock);
+
+static int usb_pll_enable, usb_pll_valid;
+
+static struct clk clk_armpll;
+static struct clk clk_usbpll;
+
+/*
+ * 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 = jiffies + 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) &&
+ time_before(jiffies, timeout))
+ 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 = jiffies + 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) &&
+ time_before(jiffies, timeout))
+ 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 = 0;
+ unsigned long timeout = jiffies + msecs_to_jiffies(20);
+
+ reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
+
+ __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN2 |
+ LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP),
+ LPC32XX_CLKPWR_USB_CTRL);
+ __raw_writel(reg & ~LPC32XX_CLKPWR_USBCTRL_CLK_EN1,
+ LPC32XX_CLKPWR_USB_CTRL);
+
+ if (enable && usb_pll_valid && usb_pll_enable) {
+ ret = -ENODEV;
+ /*
+ * If the PLL rate has been previously set, then the rate
+ * in the PLL register is valid and can be enabled here.
+ * Otherwise, it needs to be enabled as part of setrate.
+ */
+
+ /*
+ * Gate clock into PLL
+ */
+ reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1;
+ __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
+
+ /*
+ * Enable PLL
+ */
+ reg |= LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP;
+ __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
+
+ /*
+ * Wait for PLL to lock
+ */
+ while (time_before(jiffies, timeout) && (ret == -ENODEV)) {
+ reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
+ if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS)
+ ret = 0;
+ else
+ udelay(10);
+ }
+
+ /*
+ * Gate clock from PLL if PLL is locked
+ */
+ if (ret == 0) {
+ __raw_writel(reg | LPC32XX_CLKPWR_USBCTRL_CLK_EN2,
+ LPC32XX_CLKPWR_USB_CTRL);
+ } else {
+ __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 |
+ LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP),
+ LPC32XX_CLKPWR_USB_CTRL);
+ }
+ } else if ((enable == 0) && usb_pll_valid && usb_pll_enable) {
+ usb_pll_valid = 0;
+ usb_pll_enable = 0;
+ }
+
+ 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->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 0;
+
+ return clk_check_pll_setup(clkin, &pllsetup);
+}
+
+static int local_usbpll_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -ENODEV;
+ 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->get_rate(clk->parent);
+ 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;
+
+ /*
+ * Disable PLL clocks during PLL change
+ */
+ local_usbpll_enable(clk, 0);
+ pllsetup.analog_on = 0;
+ local_clk_usbpll_setup(&pllsetup);
+
+ /*
+ * Start USB PLL and check PLL status
+ */
+
+ usb_pll_valid = 1;
+ usb_pll_enable = 1;
+
+ ret = local_usbpll_enable(clk, 1);
+ if (ret >= 0)
+ clk->rate = clk_check_pll_setup(clkin, &pllsetup);
+
+ return ret;
+}
+
+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_mpwm = {
+ .parent = &clk_pclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1,
+ .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_MPWM_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_pwm = {
+ .parent = &clk_pclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_PWM_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_PWMCLK_PWM1CLK_EN |
+ LPC32XX_CLKPWR_PWMCLK_PWM1SEL_PCLK |
+ LPC32XX_CLKPWR_PWMCLK_PWM1_DIV(1) |
+ LPC32XX_CLKPWR_PWMCLK_PWM2CLK_EN |
+ LPC32XX_CLKPWR_PWMCLK_PWM2SEL_PCLK |
+ LPC32XX_CLKPWR_PWMCLK_PWM2_DIV(1),
+ .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 |
+ LPC32XX_CLKPWR_NANDCLK_SEL_SLC,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_nand_mlc = {
+ .parent = &clk_hclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_NAND_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_NANDCLK_MLCCLK_EN |
+ LPC32XX_CLKPWR_NANDCLK_DMA_INT |
+ LPC32XX_CLKPWR_NANDCLK_INTSEL_MLC,
+ .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 |
+ LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA,
+ .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 int local_usb_enable(struct clk *clk, int enable)
+{
+ u32 tmp;
+
+ if (enable) {
+ /* Set up I2C pull levels */
+ tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL);
+ tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE;
+ __raw_writel(tmp, LPC32XX_CLKPWR_I2C_CLK_CTRL);
+ }
+
+ return local_onoff_enable(clk, enable);
+}
+
+static struct clk clk_usbd = {
+ .parent = &clk_usbpll,
+ .enable = local_usb_enable,
+ .enable_reg = LPC32XX_CLKPWR_USB_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_USBCTRL_HCLK_EN,
+ .get_rate = local_return_parent_rate,
+};
+
+#define OTG_ALWAYS_MASK (LPC32XX_USB_OTG_OTG_CLOCK_ON | \
+ LPC32XX_USB_OTG_I2C_CLOCK_ON)
+
+static int local_usb_otg_enable(struct clk *clk, int enable)
+{
+ int to = 1000;
+
+ if (enable) {
+ __raw_writel(clk->enable_mask, clk->enable_reg);
+
+ while (((__raw_readl(LPC32XX_USB_OTG_CLK_STAT) &
+ clk->enable_mask) != clk->enable_mask) && (to > 0))
+ to--;
+ } else {
+ __raw_writel(OTG_ALWAYS_MASK, clk->enable_reg);
+
+ while (((__raw_readl(LPC32XX_USB_OTG_CLK_STAT) &
+ OTG_ALWAYS_MASK) != OTG_ALWAYS_MASK) && (to > 0))
+ to--;
+ }
+
+ if (to)
+ return 0;
+ else
+ return -1;
+}
+
+static struct clk clk_usb_otg_dev = {
+ .parent = &clk_usbpll,
+ .enable = local_usb_otg_enable,
+ .enable_reg = LPC32XX_USB_OTG_CLK_CTRL,
+ .enable_mask = LPC32XX_USB_OTG_AHB_M_CLOCK_ON |
+ LPC32XX_USB_OTG_OTG_CLOCK_ON |
+ LPC32XX_USB_OTG_DEV_CLOCK_ON |
+ LPC32XX_USB_OTG_I2C_CLOCK_ON,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_usb_otg_host = {
+ .parent = &clk_usbpll,
+ .enable = local_usb_otg_enable,
+ .enable_reg = LPC32XX_USB_OTG_CLK_CTRL,
+ .enable_mask = LPC32XX_USB_OTG_AHB_M_CLOCK_ON |
+ LPC32XX_USB_OTG_OTG_CLOCK_ON |
+ LPC32XX_USB_OTG_HOST_CLOCK_ON |
+ LPC32XX_USB_OTG_I2C_CLOCK_ON,
+ .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 adc_onoff_enable(struct clk *clk, int enable)
+{
+ u32 tmp;
+ u32 divider;
+
+ /* Use PERIPH_CLOCK */
+ tmp = __raw_readl(LPC32XX_CLKPWR_ADC_CLK_CTRL_1);
+ tmp |= LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL;
+ /*
+ * Set clock divider so that we have equal to or less than
+ * 4.5MHz clock at ADC
+ */
+ divider = clk->get_rate(clk) / 4500000 + 1;
+ tmp |= divider;
+ __raw_writel(tmp, LPC32XX_CLKPWR_ADC_CLK_CTRL_1);
+
+ /* synchronize rate of this clock w/ actual HW setting */
+ clk->rate = clk->get_rate(clk->parent) / divider;
+
+ if (enable == 0)
+ __raw_writel(0, clk->enable_reg);
+ else
+ __raw_writel(clk->enable_mask, clk->enable_reg);
+
+ return 0;
+}
+
+static struct clk clk_adc = {
+ .parent = &clk_pclk,
+ .enable = adc_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 |
+ LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN |
+ LPC32XX_CLKPWR_MSCARD_MSDIO_PIN_DIS |
+ LPC32XX_CLKPWR_MSCARD_MSDIO0_DIS |
+ LPC32XX_CLKPWR_MSCARD_MSDIO1_DIS |
+ LPC32XX_CLKPWR_MSCARD_MSDIO23_DIS);
+
+ /* If rate is 0, disable clock */
+ if (enable != 0)
+ tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_EN |
+ LPC32XX_CLKPWR_MSCARD_MSDIO_PU_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 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 */
+ tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL) &
+ ~LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xf);
+ tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(div) |
+ LPC32XX_CLKPWR_MSCARD_SDCARD_EN;
+ __raw_writel(tmp, 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 void local_clk_disable(struct clk *clk)
+{
+ /* 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;
+ unsigned long flags;
+
+ spin_lock_irqsave(&global_clkregs_lock, flags);
+ ret = local_clk_enable(clk);
+ spin_unlock_irqrestore(&global_clkregs_lock, flags);
+
+ 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)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&global_clkregs_lock, flags);
+ local_clk_disable(clk);
+ spin_unlock_irqrestore(&global_clkregs_lock, flags);
+}
+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)
+{
+ return clk->get_rate(clk);
+}
+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)
+ ret = clk->set_rate(clk, rate);
+
+ 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)
+{
+ if (clk->round_rate)
+ rate = clk->round_rate(clk, rate);
+ else
+ rate = clk->get_rate(clk);
+
+ 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);
+
+static struct clk_lookup lookups[] = {
+ CLKDEV_INIT(NULL, "osc_32KHz", &osc_32KHz),
+ CLKDEV_INIT(NULL, "osc_pll397", &osc_pll397),
+ CLKDEV_INIT(NULL, "osc_main", &osc_main),
+ CLKDEV_INIT(NULL, "sys_ck", &clk_sys),
+ CLKDEV_INIT(NULL, "arm_pll_ck", &clk_armpll),
+ CLKDEV_INIT(NULL, "ck_pll5", &clk_usbpll),
+ CLKDEV_INIT(NULL, "hclk_ck", &clk_hclk),
+ CLKDEV_INIT(NULL, "pclk_ck", &clk_pclk),
+ CLKDEV_INIT(NULL, "timer0_ck", &clk_timer0),
+ CLKDEV_INIT(NULL, "timer1_ck", &clk_timer1),
+ CLKDEV_INIT(NULL, "timer2_ck", &clk_timer2),
+ CLKDEV_INIT(NULL, "timer3_ck", &clk_timer3),
+ CLKDEV_INIT(NULL, "vfp9_ck", &clk_vfp9),
+ CLKDEV_INIT("pl08xdmac", NULL, &clk_dma),
+ CLKDEV_INIT("4003c000.watchdog", NULL, &clk_wdt),
+ CLKDEV_INIT("4005c000.pwm", NULL, &clk_pwm),
+ CLKDEV_INIT("400e8000.mpwm", NULL, &clk_mpwm),
+ CLKDEV_INIT(NULL, "uart3_ck", &clk_uart3),
+ CLKDEV_INIT(NULL, "uart4_ck", &clk_uart4),
+ CLKDEV_INIT(NULL, "uart5_ck", &clk_uart5),
+ CLKDEV_INIT(NULL, "uart6_ck", &clk_uart6),
+ CLKDEV_INIT("400a0000.i2c", NULL, &clk_i2c0),
+ CLKDEV_INIT("400a8000.i2c", NULL, &clk_i2c1),
+ CLKDEV_INIT("31020300.i2c", NULL, &clk_i2c2),
+ CLKDEV_INIT("dev:ssp0", NULL, &clk_ssp0),
+ CLKDEV_INIT("dev:ssp1", NULL, &clk_ssp1),
+ CLKDEV_INIT("40050000.key", NULL, &clk_kscan),
+ CLKDEV_INIT("20020000.flash", NULL, &clk_nand),
+ CLKDEV_INIT("200a8000.flash", NULL, &clk_nand_mlc),
+ CLKDEV_INIT("40048000.adc", NULL, &clk_adc),
+ CLKDEV_INIT(NULL, "i2s0_ck", &clk_i2s0),
+ CLKDEV_INIT(NULL, "i2s1_ck", &clk_i2s1),
+ CLKDEV_INIT("40048000.tsc", NULL, &clk_tsc),
+ CLKDEV_INIT("20098000.sd", NULL, &clk_mmc),
+ CLKDEV_INIT("31060000.ethernet", NULL, &clk_net),
+ CLKDEV_INIT("dev:clcd", NULL, &clk_lcd),
+ CLKDEV_INIT("31020000.usbd", "ck_usbd", &clk_usbd),
+ CLKDEV_INIT("31020000.ohci", "ck_usbd", &clk_usbd),
+ CLKDEV_INIT("31020000.usbd", "ck_usb_otg", &clk_usb_otg_dev),
+ CLKDEV_INIT("31020000.ohci", "ck_usb_otg", &clk_usb_otg_host),
+ CLKDEV_INIT("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 000000000..c0a843430
--- /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 000000000..716e83eb1
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/common.c
@@ -0,0 +1,228 @@
+/*
+ * 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 <asm/system_info.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include "common.h"
+
+/*
+ * 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;
+}
+
+/*
+ * 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;
+}
+EXPORT_SYMBOL_GPL(lpc32xx_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 = (unsigned long)IO_ADDRESS(LPC32XX_AHB0_START),
+ .pfn = __phys_to_pfn(LPC32XX_AHB0_START),
+ .length = LPC32XX_AHB0_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = (unsigned long)IO_ADDRESS(LPC32XX_AHB1_START),
+ .pfn = __phys_to_pfn(LPC32XX_AHB1_START),
+ .length = LPC32XX_AHB1_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = (unsigned long)IO_ADDRESS(LPC32XX_FABAPB_START),
+ .pfn = __phys_to_pfn(LPC32XX_FABAPB_START),
+ .length = LPC32XX_FABAPB_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = (unsigned long)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));
+}
+
+void lpc23xx_restart(enum reboot_mode mode, const char *cmd)
+{
+ /* 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));
+
+ /* Wait for watchdog to reset system */
+ while (1)
+ ;
+}
+
+static int __init lpc32xx_check_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]);
+
+ if (!system_serial_low && !system_serial_high) {
+ system_serial_low = uid[0];
+ system_serial_high = uid[1];
+ }
+
+ return 1;
+}
+arch_initcall(lpc32xx_check_uid);
diff --git a/arch/arm/mach-lpc32xx/common.h b/arch/arm/mach-lpc32xx/common.h
new file mode 100644
index 000000000..1cd8853b2
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/common.h
@@ -0,0 +1,66 @@
+/*
+ * 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 <mach/board.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+
+/*
+ * Other arch specific structures and functions
+ */
+extern void lpc32xx_timer_init(void);
+extern void __init lpc32xx_init_irq(void);
+extern void __init lpc32xx_map_io(void);
+extern void __init lpc32xx_serial_init(void);
+extern void lpc23xx_restart(enum reboot_mode, const char *);
+
+
+/*
+ * 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 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/include/mach/board.h b/arch/arm/mach-lpc32xx/include/mach/board.h
new file mode 100644
index 000000000..52531ca7b
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/board.h
@@ -0,0 +1,24 @@
+/*
+ * arm/arch/mach-lpc32xx/include/mach/board.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_BOARD_H
+#define __ASM_ARCH_BOARD_H
+
+extern u32 lpc32xx_return_iram_size(void);
+
+#endif /* __ASM_ARCH_BOARD_H */
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 000000000..24ca11b37
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/entry-macro.S
@@ -0,0 +1,37 @@
+/*
+ * 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 get_irqnr_preamble, base, tmp
+ ldr \base, =IO_ADDRESS(LPC32XX_MIC_BASE)
+ .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
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 000000000..69065de97
--- /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) IOMEM(((((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/irqs.h b/arch/arm/mach-lpc32xx/include/mach/irqs.h
new file mode 100644
index 000000000..9e3b90df3
--- /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/platform.h b/arch/arm/mach-lpc32xx/include/mach/platform.h
new file mode 100644
index 000000000..b5612a1d1
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/platform.h
@@ -0,0 +1,712 @@
+/*
+ * 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_MPWM_EN 0x40
+#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 LPC32XX_TIMER_IR(x) io_p2v((x) + 0x00)
+#define LPC32XX_TIMER_TCR(x) io_p2v((x) + 0x04)
+#define LPC32XX_TIMER_TC(x) io_p2v((x) + 0x08)
+#define LPC32XX_TIMER_PR(x) io_p2v((x) + 0x0C)
+#define LPC32XX_TIMER_PC(x) io_p2v((x) + 0x10)
+#define LPC32XX_TIMER_MCR(x) io_p2v((x) + 0x14)
+#define LPC32XX_TIMER_MR0(x) io_p2v((x) + 0x18)
+#define LPC32XX_TIMER_MR1(x) io_p2v((x) + 0x1C)
+#define LPC32XX_TIMER_MR2(x) io_p2v((x) + 0x20)
+#define LPC32XX_TIMER_MR3(x) io_p2v((x) + 0x24)
+#define LPC32XX_TIMER_CCR(x) io_p2v((x) + 0x28)
+#define LPC32XX_TIMER_CR0(x) io_p2v((x) + 0x2C)
+#define LPC32XX_TIMER_CR1(x) io_p2v((x) + 0x30)
+#define LPC32XX_TIMER_CR2(x) io_p2v((x) + 0x34)
+#define LPC32XX_TIMER_CR3(x) io_p2v((x) + 0x38)
+#define LPC32XX_TIMER_EMR(x) io_p2v((x) + 0x3C)
+#define LPC32XX_TIMER_CTCR(x) io_p2v((x) + 0x70)
+
+/*
+ * ir register definitions
+ */
+#define LPC32XX_TIMER_CNTR_MTCH_BIT(n) (1 << ((n) & 0x3))
+#define LPC32XX_TIMER_CNTR_CAPT_BIT(n) (1 << (4 + ((n) & 0x3)))
+
+/*
+ * tcr register definitions
+ */
+#define LPC32XX_TIMER_CNTR_TCR_EN 0x1
+#define LPC32XX_TIMER_CNTR_TCR_RESET 0x2
+
+/*
+ * mcr register definitions
+ */
+#define LPC32XX_TIMER_CNTR_MCR_MTCH(n) (0x1 << ((n) * 3))
+#define LPC32XX_TIMER_CNTR_MCR_RESET(n) (0x1 << (((n) * 3) + 1))
+#define LPC32XX_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)
+#define LPC32XX_GPIO_P2_MUX_SET _GPREG(0x028)
+#define LPC32XX_GPIO_P2_MUX_CLR _GPREG(0x02C)
+#define LPC32XX_GPIO_P2_MUX_STATE _GPREG(0x030)
+
+/*
+ * USB Otg Registers
+ */
+#define _OTGREG(x) io_p2v(LPC32XX_USB_OTG_BASE + (x))
+#define LPC32XX_USB_OTG_CLK_CTRL _OTGREG(0xFF4)
+#define LPC32XX_USB_OTG_CLK_STAT _OTGREG(0xFF8)
+
+/* USB OTG CLK CTRL bit defines */
+#define LPC32XX_USB_OTG_AHB_M_CLOCK_ON _BIT(4)
+#define LPC32XX_USB_OTG_OTG_CLOCK_ON _BIT(3)
+#define LPC32XX_USB_OTG_I2C_CLOCK_ON _BIT(2)
+#define LPC32XX_USB_OTG_DEV_CLOCK_ON _BIT(1)
+#define LPC32XX_USB_OTG_HOST_CLOCK_ON _BIT(0)
+
+#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 000000000..1198a8918
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/uncompress.h
@@ -0,0 +1,59 @@
+/*
+ * 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()
+
+#endif
diff --git a/arch/arm/mach-lpc32xx/irq.c b/arch/arm/mach-lpc32xx/irq.c
new file mode 100644
index 000000000..9ecb8f9c4
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/irq.c
@@ -0,0 +1,477 @@
+/*
+ * 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 <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/module.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
+
+static struct irq_domain *lpc32xx_mic_domain;
+static struct device_node *lpc32xx_mic_np;
+
+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_ETHERNET] = {
+ .event_group = &lpc32xx_event_int_regs,
+ .mask = LPC32XX_CLKPWR_INTSRC_MAC_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->hwirq, &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->hwirq, &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->hwirq, &ctrl, &mask);
+
+ __raw_writel(mask, LPC32XX_INTC_RAW_STAT(ctrl));
+
+ /* Also need to clear pending wake event */
+ if (lpc32xx_events[d->hwirq].mask != 0)
+ __raw_writel(lpc32xx_events[d->hwirq].mask,
+ lpc32xx_events[d->hwirq].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->hwirq, 1, 1);
+ __irq_set_handler_locked(d->hwirq, handle_edge_irq);
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ /* Falling edge sensitive */
+ __lpc32xx_set_irq_type(d->hwirq, 0, 1);
+ __irq_set_handler_locked(d->hwirq, handle_edge_irq);
+ break;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ /* Low level sensitive */
+ __lpc32xx_set_irq_type(d->hwirq, 0, 0);
+ __irq_set_handler_locked(d->hwirq, handle_level_irq);
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ /* High level sensitive */
+ __lpc32xx_set_irq_type(d->hwirq, 1, 0);
+ __irq_set_handler_locked(d->hwirq, handle_level_irq);
+ break;
+
+ /* Other modes are not supported */
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int lpc32xx_irq_wake(struct irq_data *d, unsigned int state)
+{
+ unsigned long eventreg;
+
+ if (lpc32xx_events[d->hwirq].mask != 0) {
+ eventreg = __raw_readl(lpc32xx_events[d->hwirq].
+ event_group->enab_reg);
+
+ if (state)
+ eventreg |= lpc32xx_events[d->hwirq].mask;
+ else {
+ eventreg &= ~lpc32xx_events[d->hwirq].mask;
+
+ /*
+ * When disabling the wakeup, clear the latched
+ * event
+ */
+ __raw_writel(lpc32xx_events[d->hwirq].mask,
+ lpc32xx_events[d->hwirq].
+ event_group->rawstat_reg);
+ }
+
+ __raw_writel(eventreg,
+ lpc32xx_events[d->hwirq].event_group->enab_reg);
+
+ return 0;
+ }
+
+ /* Clear event */
+ __raw_writel(lpc32xx_events[d->hwirq].mask,
+ lpc32xx_events[d->hwirq].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 = {
+ .name = "MIC",
+ .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));
+ }
+}
+
+static int __init __lpc32xx_mic_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ lpc32xx_mic_np = node;
+
+ return 0;
+}
+
+static const struct of_device_id mic_of_match[] __initconst = {
+ { .compatible = "nxp,lpc3220-mic", .data = __lpc32xx_mic_of_init },
+ { }
+};
+
+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);
+
+ /* 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);
+
+ of_irq_init(mic_of_match);
+
+ lpc32xx_mic_domain = irq_domain_add_legacy(lpc32xx_mic_np, NR_IRQS,
+ 0, 0, &irq_domain_simple_ops,
+ NULL);
+ if (!lpc32xx_mic_domain)
+ panic("Unable to add MIC irq domain\n");
+
+ /* 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);
+}
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c
new file mode 100644
index 000000000..7858d5b6f
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/phy3250.c
@@ -0,0 +1,267 @@
+/*
+ * Platform support for LPC32xx SoC
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2012 Roland Stigge <stigge@antcom.de>
+ * 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/device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/dma-mapping.h>
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/amba/pl08x.h>
+#include <linux/amba/mmci.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>
+#include <linux/mtd/lpc32xx_slc.h>
+#include <linux/mtd/lpc32xx_mlc.h>
+#include <linux/platform_data/gpio-lpc32xx.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <mach/board.h>
+#include "common.h"
+
+/*
+ * Mapped GPIOLIB GPIOs
+ */
+#define LCD_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 0)
+#define BKL_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 4)
+#define MMC_PWR_ENABLE_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 5)
+
+/*
+ * 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 pl08x_channel_data pl08x_slave_channels[] = {
+ {
+ .bus_id = "nand-slc",
+ .min_signal = 1, /* SLC NAND Flash */
+ .max_signal = 1,
+ .periph_buses = PL08X_AHB1,
+ },
+ {
+ .bus_id = "nand-mlc",
+ .min_signal = 12, /* MLC NAND Flash */
+ .max_signal = 12,
+ .periph_buses = PL08X_AHB1,
+ },
+};
+
+static int pl08x_get_signal(const struct pl08x_channel_data *cd)
+{
+ return cd->min_signal;
+}
+
+static void pl08x_put_signal(const struct pl08x_channel_data *cd, int ch)
+{
+}
+
+static struct pl08x_platform_data pl08x_pd = {
+ .slave_channels = &pl08x_slave_channels[0],
+ .num_slave_channels = ARRAY_SIZE(pl08x_slave_channels),
+ .get_xfer_signal = pl08x_get_signal,
+ .put_xfer_signal = pl08x_put_signal,
+ .lli_buses = PL08X_AHB1,
+ .mem_buses = PL08X_AHB1,
+};
+
+static int mmc_handle_ios(struct device *dev, struct mmc_ios *ios)
+{
+ /* Only on and off are supported */
+ if (ios->power_mode == MMC_POWER_OFF)
+ gpio_set_value(MMC_PWR_ENABLE_GPIO, 0);
+ else
+ gpio_set_value(MMC_PWR_ENABLE_GPIO, 1);
+ return 0;
+}
+
+static struct mmci_platform_data lpc32xx_mmci_data = {
+ .ocr_mask = MMC_VDD_30_31 | MMC_VDD_31_32 |
+ MMC_VDD_32_33 | MMC_VDD_33_34,
+ .ios_handler = mmc_handle_ios,
+};
+
+static struct lpc32xx_slc_platform_data lpc32xx_slc_data = {
+ .dma_filter = pl08x_filter_id,
+};
+
+static struct lpc32xx_mlc_platform_data lpc32xx_mlc_data = {
+ .dma_filter = pl08x_filter_id,
+};
+
+static const struct of_dev_auxdata lpc32xx_auxdata_lookup[] __initconst = {
+ OF_DEV_AUXDATA("arm,pl022", 0x20084000, "dev:ssp0", NULL),
+ OF_DEV_AUXDATA("arm,pl022", 0x2008C000, "dev:ssp1", NULL),
+ OF_DEV_AUXDATA("arm,pl110", 0x31040000, "dev:clcd", &lpc32xx_clcd_data),
+ OF_DEV_AUXDATA("arm,pl080", 0x31000000, "pl08xdmac", &pl08x_pd),
+ OF_DEV_AUXDATA("arm,pl18x", 0x20098000, "20098000.sd",
+ &lpc32xx_mmci_data),
+ OF_DEV_AUXDATA("nxp,lpc3220-slc", 0x20020000, "20020000.flash",
+ &lpc32xx_slc_data),
+ OF_DEV_AUXDATA("nxp,lpc3220-mlc", 0x200a8000, "200a8000.flash",
+ &lpc32xx_mlc_data),
+ { }
+};
+
+static void __init lpc3250_machine_init(void)
+{
+ u32 tmp;
+
+ /* 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);
+
+ lpc32xx_serial_init();
+
+ /* Test clock needed for UDA1380 initial init */
+ __raw_writel(LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC |
+ LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN,
+ LPC32XX_CLKPWR_TEST_CLK_SEL);
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ lpc32xx_auxdata_lookup, NULL);
+}
+
+static char const *lpc32xx_dt_compat[] __initdata = {
+ "nxp,lpc3220",
+ "nxp,lpc3230",
+ "nxp,lpc3240",
+ "nxp,lpc3250",
+ NULL
+};
+
+DT_MACHINE_START(LPC32XX_DT, "LPC32XX SoC (Flattened Device Tree)")
+ .atag_offset = 0x100,
+ .map_io = lpc32xx_map_io,
+ .init_irq = lpc32xx_init_irq,
+ .init_time = lpc32xx_timer_init,
+ .init_machine = lpc3250_machine_init,
+ .dt_compat = lpc32xx_dt_compat,
+ .restart = lpc23xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-lpc32xx/pm.c b/arch/arm/mach-lpc32xx/pm.c
new file mode 100644
index 000000000..207e81275
--- /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 LPC32XX 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 000000000..05621a29f
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/serial.c
@@ -0,0 +1,130 @@
+/*
+ * 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
+
+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 = {
+ {
+ .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,
+ },
+ {
+ .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,
+ },
+ {
+ .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,
+ },
+ {
+ .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,
+ },
+};
+
+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);
+ }
+
+ /* 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 = 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));
+ }
+
+ /* Disable IrDA pulsing support on UART6 */
+ tmp = __raw_readl(LPC32XX_UARTCTL_CTRL);
+ tmp |= LPC32XX_UART_UART6_IRDAMOD_BYPASS;
+ __raw_writel(tmp, LPC32XX_UARTCTL_CTRL);
+
+ /* 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);
+}
diff --git a/arch/arm/mach-lpc32xx/suspend.S b/arch/arm/mach-lpc32xx/suspend.S
new file mode 100644
index 000000000..374f9f07f
--- /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 000000000..4e5837299
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/timer.c
@@ -0,0 +1,156 @@
+/*
+ * 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(LPC32XX_TIMER_CNTR_TCR_RESET,
+ LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
+ __raw_writel(delta, LPC32XX_TIMER_PR(LPC32XX_TIMER0_BASE));
+ __raw_writel(LPC32XX_TIMER_CNTR_TCR_EN,
+ LPC32XX_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, LPC32XX_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,
+ .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(LPC32XX_TIMER_CNTR_MTCH_BIT(0),
+ LPC32XX_TIMER_IR(LPC32XX_TIMER0_BASE));
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction lpc32xx_timer_irq = {
+ .name = "LPC32XX Timer Tick",
+ .flags = 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
+ */
+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, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
+ __raw_writel(LPC32XX_TIMER_CNTR_MTCH_BIT(0),
+ LPC32XX_TIMER_IR(LPC32XX_TIMER0_BASE));
+ __raw_writel(1, LPC32XX_TIMER_MR0(LPC32XX_TIMER0_BASE));
+ __raw_writel(LPC32XX_TIMER_CNTR_MCR_MTCH(0) |
+ LPC32XX_TIMER_CNTR_MCR_STOP(0) |
+ LPC32XX_TIMER_CNTR_MCR_RESET(0),
+ LPC32XX_TIMER_MCR(LPC32XX_TIMER0_BASE));
+
+ /* Setup tick interrupt */
+ setup_irq(IRQ_LPC32XX_TIMER0, &lpc32xx_timer_irq);
+
+ /* Setup the clockevent structure. */
+ lpc32xx_clkevt.cpumask = cpumask_of(0);
+ clockevents_config_and_register(&lpc32xx_clkevt, clkrate, 1, -1);
+
+ /* Use timer1 as clock source. */
+ __raw_writel(LPC32XX_TIMER_CNTR_TCR_RESET,
+ LPC32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));
+ __raw_writel(0, LPC32XX_TIMER_PR(LPC32XX_TIMER1_BASE));
+ __raw_writel(0, LPC32XX_TIMER_MCR(LPC32XX_TIMER1_BASE));
+ __raw_writel(LPC32XX_TIMER_CNTR_TCR_EN,
+ LPC32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));
+
+ clocksource_mmio_init(LPC32XX_TIMER_TC(LPC32XX_TIMER1_BASE),
+ "lpc32xx_clksrc", clkrate, 300, 32, clocksource_mmio_readl_up);
+}
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
new file mode 100644
index 000000000..9f59e58da
--- /dev/null
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -0,0 +1,27 @@
+menuconfig ARCH_MEDIATEK
+ bool "Mediatek MT65xx & MT81xx SoC" if ARCH_MULTI_V7
+ select ARM_GIC
+ select PINCTRL
+ select MTK_TIMER
+ help
+ Support for Mediatek MT65xx & MT81xx SoCs
+
+if ARCH_MEDIATEK
+
+config MACH_MT6589
+ bool "MediaTek MT6589 SoCs support"
+ default ARCH_MEDIATEK
+
+config MACH_MT6592
+ bool "MediaTek MT6592 SoCs support"
+ default ARCH_MEDIATEK
+
+config MACH_MT8127
+ bool "MediaTek MT8127 SoCs support"
+ default ARCH_MEDIATEK
+
+config MACH_MT8135
+ bool "MediaTek MT8135 SoCs support"
+ default ARCH_MEDIATEK
+
+endif
diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
new file mode 100644
index 000000000..43e619f56
--- /dev/null
+++ b/arch/arm/mach-mediatek/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c
new file mode 100644
index 000000000..a95490050
--- /dev/null
+++ b/arch/arm/mach-mediatek/mediatek.c
@@ -0,0 +1,30 @@
+/*
+ * Device Tree support for Mediatek SoCs
+ *
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Matthias Brugger <matthias.bgg@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.
+ */
+#include <linux/init.h>
+#include <asm/mach/arch.h>
+
+static const char * const mediatek_board_dt_compat[] = {
+ "mediatek,mt6589",
+ "mediatek,mt6592",
+ "mediatek,mt8127",
+ "mediatek,mt8135",
+ NULL,
+};
+
+DT_MACHINE_START(MEDIATEK_DT, "Mediatek Cortex-A7 (Device Tree)")
+ .dt_compat = mediatek_board_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig
new file mode 100644
index 000000000..0743e2059
--- /dev/null
+++ b/arch/arm/mach-meson/Kconfig
@@ -0,0 +1,22 @@
+menuconfig ARCH_MESON
+ bool "Amlogic Meson SoCs" if ARCH_MULTI_V7
+ select ARCH_REQUIRE_GPIOLIB
+ select GENERIC_IRQ_CHIP
+ select ARM_GIC
+ select CACHE_L2X0
+ select PINCTRL
+ select PINCTRL_MESON
+
+if ARCH_MESON
+
+config MACH_MESON6
+ bool "Amlogic Meson6 (8726MX) SoCs support"
+ default ARCH_MESON
+ select MESON6_TIMER
+
+config MACH_MESON8
+ bool "Amlogic Meson8 SoCs support"
+ default ARCH_MESON
+ select MESON6_TIMER
+
+endif
diff --git a/arch/arm/mach-meson/Makefile b/arch/arm/mach-meson/Makefile
new file mode 100644
index 000000000..9d7380eee
--- /dev/null
+++ b/arch/arm/mach-meson/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_MESON) += meson.o
diff --git a/arch/arm/mach-meson/meson.c b/arch/arm/mach-meson/meson.c
new file mode 100644
index 000000000..5d6affe6a
--- /dev/null
+++ b/arch/arm/mach-meson/meson.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 Carlo Caione <carlo@caione.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/of_platform.h>
+#include <asm/mach/arch.h>
+
+static const char * const meson_common_board_compat[] = {
+ "amlogic,meson6",
+ "amlogic,meson8",
+ NULL,
+};
+
+DT_MACHINE_START(MESON, "Amlogic Meson platform")
+ .dt_compat = meson_common_board_compat,
+ .l2c_aux_val = 0,
+ .l2c_aux_mask = ~0,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
new file mode 100644
index 000000000..fdbfadf00
--- /dev/null
+++ b/arch/arm/mach-mmp/Kconfig
@@ -0,0 +1,142 @@
+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.
+
+config MACH_GPLUGD
+ bool "Marvell's PXA168 GuruPlug Display (gplugD) Board"
+ select CPU_PXA168
+ help
+ Say 'Y' here if you want to support the Marvell PXA168-based
+ GuruPlug Display (gplugD) Board
+
+config MACH_MMP_DT
+ bool "Support MMP (ARMv5) platforms from device tree"
+ select USE_OF
+ select PINCTRL
+ select PINCTRL_SINGLE
+ select COMMON_CLK
+ select ARCH_HAS_RESET_CONTROLLER
+ select CPU_MOHAWK
+ help
+ Include support for Marvell MMP2 based platforms using
+ the device tree. Needn't select any other machine while
+ MACH_MMP_DT is enabled.
+
+config MACH_MMP2_DT
+ bool "Support MMP2 (ARMv7) platforms from device tree"
+ depends on !CPU_MOHAWK
+ select USE_OF
+ select PINCTRL
+ select PINCTRL_SINGLE
+ select COMMON_CLK
+ select ARCH_HAS_RESET_CONTROLLER
+ select CPU_PJ4
+ help
+ Include support for Marvell MMP2 based platforms using
+ the device tree.
+
+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.
+
+config USB_EHCI_MV_U2O
+ bool "EHCI support for PXA USB OTG controller"
+ depends on USB_EHCI_MV
+ help
+ Enables support for OTG controller which can be switched to host mode.
+
+config MMP_SRAM
+ bool
+
+endif
diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
new file mode 100644
index 000000000..98f0f6388
--- /dev/null
+++ b/arch/arm/mach-mmp/Makefile
@@ -0,0 +1,36 @@
+#
+# Makefile for Marvell's PXA168 processors line
+#
+
+obj-y += common.o devices.o time.o
+
+# SoC support
+obj-$(CONFIG_CPU_PXA168) += pxa168.o
+obj-$(CONFIG_CPU_PXA910) += pxa910.o
+obj-$(CONFIG_CPU_MMP2) += mmp2.o
+obj-$(CONFIG_MMP_SRAM) += sram.o
+
+ifeq ($(CONFIG_COMMON_CLK), )
+obj-y += clock.o
+obj-$(CONFIG_CPU_PXA168) += clock-pxa168.o
+obj-$(CONFIG_CPU_PXA910) += clock-pxa910.o
+obj-$(CONFIG_CPU_MMP2) += clock-mmp2.o
+endif
+ifeq ($(CONFIG_PM),y)
+obj-$(CONFIG_CPU_PXA910) += pm-pxa910.o
+obj-$(CONFIG_CPU_MMP2) += pm-mmp2.o
+endif
+
+# 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_MMP_DT) += mmp-dt.o
+obj-$(CONFIG_MACH_MMP2_DT) += mmp2-dt.o
+obj-$(CONFIG_MACH_TETON_BGA) += teton_bga.o
+obj-$(CONFIG_MACH_GPLUGD) += gplugd.o
diff --git a/arch/arm/mach-mmp/Makefile.boot b/arch/arm/mach-mmp/Makefile.boot
new file mode 100644
index 000000000..5edf03e2b
--- /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 000000000..7e0248582
--- /dev/null
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -0,0 +1,282 @@
+/*
+ * 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/gpio.h>
+#include <linux/gpio-pxa.h>
+#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 <linux/platform_data/mv_usb.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 <video/pxa168fb.h>
+#include <linux/input.h>
+#include <linux/platform_data/keypad-pxa27x.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 pxa_gpio_platform_data pxa168_gpio_pdata = {
+ .irq_base = MMP_GPIO_TO_IRQ(0),
+};
+
+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 = MMP_GPIO_TO_IRQ(27),
+ .end = MMP_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_32M + SZ_16M,
+ .mask_flags = 0,
+ }
+};
+
+static struct pxa3xx_nand_platform_data aspenite_nand_info = {
+ .enable_arbiter = 1,
+ .num_cs = 1,
+ .parts[0] = aspenite_nand_partitions,
+ .nr_parts[0] = 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 const 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 matrix_keymap_data aspenite_matrix_keymap_data = {
+ .keymap = aspenite_matrix_key_map,
+ .keymap_size = ARRAY_SIZE(aspenite_matrix_key_map),
+};
+
+static struct pxa27x_keypad_platform_data aspenite_keypad_info __initdata = {
+ .matrix_key_rows = 5,
+ .matrix_key_cols = 8,
+ .matrix_keymap_data = &aspenite_matrix_keymap_data,
+ .debounce_interval = 30,
+};
+
+#if IS_ENABLED(CONFIG_USB_EHCI_MV)
+static struct mv_usb_platform_data pxa168_sph_pdata = {
+ .mode = MV_USB_MODE_HOST,
+ .phy_init = pxa_usb_phy_init,
+ .phy_deinit = pxa_usb_phy_deinit,
+ .set_vbus = NULL,
+};
+#endif
+
+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);
+ platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
+ platform_device_register(&pxa168_device_gpio);
+
+ /* off-chip devices */
+ platform_device_register(&smc91x_device);
+
+#if IS_ENABLED(CONFIG_USB_EHCI_MV)
+ pxa168_add_usb_host(&pxa168_sph_pdata);
+#endif
+}
+
+MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform")
+ .map_io = mmp_map_io,
+ .nr_irqs = MMP_NR_IRQS,
+ .init_irq = pxa168_init_irq,
+ .init_time = pxa168_timer_init,
+ .init_machine = common_init,
+ .restart = pxa168_restart,
+MACHINE_END
+
+MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform")
+ .map_io = mmp_map_io,
+ .nr_irqs = MMP_NR_IRQS,
+ .init_irq = pxa168_init_irq,
+ .init_time = pxa168_timer_init,
+ .init_machine = common_init,
+ .restart = pxa168_restart,
+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 000000000..a451a0f4d
--- /dev/null
+++ b/arch/arm/mach-mmp/avengers_lite.c
@@ -0,0 +1,58 @@
+/*
+ * 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/gpio-pxa.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 struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+ .irq_base = MMP_GPIO_TO_IRQ(0),
+};
+
+static void __init avengers_lite_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(avengers_lite_pin_config_V16F));
+
+ /* on-chip devices */
+ pxa168_add_uart(2);
+ platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
+ platform_device_register(&pxa168_device_gpio);
+}
+
+MACHINE_START(AVENGERS_LITE, "PXA168 Avengers lite Development Platform")
+ .map_io = mmp_map_io,
+ .nr_irqs = MMP_NR_IRQS,
+ .init_irq = pxa168_init_irq,
+ .init_time = pxa168_timer_init,
+ .init_machine = avengers_lite_init,
+ .restart = pxa168_restart,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
new file mode 100644
index 000000000..ac25544b8
--- /dev/null
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -0,0 +1,231 @@
+/*
+ * 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-pxa.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 (MMP_NR_IRQS + 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 pxa_gpio_platform_data mmp2_gpio_pdata = {
+ .irq_base = MMP_GPIO_TO_IRQ(0),
+};
+
+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 = MMP_NR_IRQS,
+};
+
+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 = {
+ .clk_delay_cycles = 0x1f,
+};
+
+static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = {
+ .clk_delay_cycles = 0x1f,
+ .flags = PXA_FLAG_CARD_PERMANENT
+ | PXA_FLAG_SD_8_BIT_CAPABLE_SLOT,
+};
+
+static struct sram_platdata mmp2_asram_platdata = {
+ .pool_name = "asram",
+ .granularity = SRAM_GRANULARITY,
+};
+
+static struct sram_platdata mmp2_isram_platdata = {
+ .pool_name = "isram",
+ .granularity = SRAM_GRANULARITY,
+};
+
+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);
+ platform_device_add_data(&mmp2_device_gpio, &mmp2_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
+ platform_device_register(&mmp2_device_gpio);
+ mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info));
+ mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */
+ mmp2_add_sdhost(2, &mmp2_sdh_platdata_mmc2); /* eMMC */
+ mmp2_add_asram(&mmp2_asram_platdata);
+ mmp2_add_isram(&mmp2_isram_platdata);
+
+ /* 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,
+ .init_time = mmp2_timer_init,
+ .init_machine = brownstone_init,
+ .restart = mmp_restart,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/clock-mmp2.c b/arch/arm/mach-mmp/clock-mmp2.c
new file mode 100644
index 000000000..53d77cbd6
--- /dev/null
+++ b/arch/arm/mach-mmp/clock-mmp2.c
@@ -0,0 +1,111 @@
+#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 <mach/addr-map.h>
+
+#include "common.h"
+#include "clock.h"
+
+/*
+ * APB Clock register offsets for MMP2
+ */
+#define APBC_RTC APBC_REG(0x000)
+#define APBC_TWSI1 APBC_REG(0x004)
+#define APBC_TWSI2 APBC_REG(0x008)
+#define APBC_TWSI3 APBC_REG(0x00c)
+#define APBC_TWSI4 APBC_REG(0x010)
+#define APBC_KPC APBC_REG(0x018)
+#define APBC_UART1 APBC_REG(0x02c)
+#define APBC_UART2 APBC_REG(0x030)
+#define APBC_UART3 APBC_REG(0x034)
+#define APBC_GPIO APBC_REG(0x038)
+#define APBC_PWM0 APBC_REG(0x03c)
+#define APBC_PWM1 APBC_REG(0x040)
+#define APBC_PWM2 APBC_REG(0x044)
+#define APBC_PWM3 APBC_REG(0x048)
+#define APBC_SSP0 APBC_REG(0x04c)
+#define APBC_SSP1 APBC_REG(0x050)
+#define APBC_SSP2 APBC_REG(0x054)
+#define APBC_SSP3 APBC_REG(0x058)
+#define APBC_SSP4 APBC_REG(0x05c)
+#define APBC_SSP5 APBC_REG(0x060)
+#define APBC_TWSI5 APBC_REG(0x07c)
+#define APBC_TWSI6 APBC_REG(0x080)
+#define APBC_UART4 APBC_REG(0x088)
+
+#define APMU_USB APMU_REG(0x05c)
+#define APMU_NAND APMU_REG(0x060)
+#define APMU_SDH0 APMU_REG(0x054)
+#define APMU_SDH1 APMU_REG(0x058)
+#define APMU_SDH2 APMU_REG(0x0e8)
+#define APMU_SDH3 APMU_REG(0x0ec)
+
+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, UART1, 1, 26000000);
+static APBC_CLK(uart2, UART2, 1, 26000000);
+static APBC_CLK(uart3, UART3, 1, 26000000);
+static APBC_CLK(uart4, UART4, 1, 26000000);
+static APBC_CLK(twsi1, TWSI1, 0, 26000000);
+static APBC_CLK(twsi2, TWSI2, 0, 26000000);
+static APBC_CLK(twsi3, TWSI3, 0, 26000000);
+static APBC_CLK(twsi4, TWSI4, 0, 26000000);
+static APBC_CLK(twsi5, TWSI5, 0, 26000000);
+static APBC_CLK(twsi6, TWSI6, 0, 26000000);
+static APBC_CLK(gpio, GPIO, 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_gpio, "mmp2-gpio", NULL),
+ INIT_CLKREG(&clk_sdh0, "sdhci-pxav3.0", "PXA-SDHCLK"),
+ INIT_CLKREG(&clk_sdh1, "sdhci-pxav3.1", "PXA-SDHCLK"),
+ INIT_CLKREG(&clk_sdh2, "sdhci-pxav3.2", "PXA-SDHCLK"),
+ INIT_CLKREG(&clk_sdh3, "sdhci-pxav3.3", "PXA-SDHCLK"),
+};
+
+void __init mmp2_clk_init(void)
+{
+ clkdev_add_table(ARRAY_AND_SIZE(mmp2_clkregs));
+}
diff --git a/arch/arm/mach-mmp/clock-pxa168.c b/arch/arm/mach-mmp/clock-pxa168.c
new file mode 100644
index 000000000..c572f219a
--- /dev/null
+++ b/arch/arm/mach-mmp/clock-pxa168.c
@@ -0,0 +1,91 @@
+#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 <mach/addr-map.h>
+
+#include "common.h"
+#include "clock.h"
+
+/*
+ * APB clock register offsets for PXA168
+ */
+#define APBC_UART1 APBC_REG(0x000)
+#define APBC_UART2 APBC_REG(0x004)
+#define APBC_GPIO APBC_REG(0x008)
+#define APBC_PWM1 APBC_REG(0x00c)
+#define APBC_PWM2 APBC_REG(0x010)
+#define APBC_PWM3 APBC_REG(0x014)
+#define APBC_PWM4 APBC_REG(0x018)
+#define APBC_RTC APBC_REG(0x028)
+#define APBC_TWSI0 APBC_REG(0x02c)
+#define APBC_KPC APBC_REG(0x030)
+#define APBC_TWSI1 APBC_REG(0x06c)
+#define APBC_UART3 APBC_REG(0x070)
+#define APBC_SSP1 APBC_REG(0x81c)
+#define APBC_SSP2 APBC_REG(0x820)
+#define APBC_SSP3 APBC_REG(0x84c)
+#define APBC_SSP4 APBC_REG(0x858)
+#define APBC_SSP5 APBC_REG(0x85c)
+
+#define APMU_NAND APMU_REG(0x060)
+#define APMU_LCD APMU_REG(0x04c)
+#define APMU_ETH APMU_REG(0x0fc)
+#define APMU_USB APMU_REG(0x05c)
+
+/* APB peripheral clocks */
+static APBC_CLK(uart1, UART1, 1, 14745600);
+static APBC_CLK(uart2, UART2, 1, 14745600);
+static APBC_CLK(uart3, UART3, 1, 14745600);
+static APBC_CLK(twsi0, TWSI0, 1, 33000000);
+static APBC_CLK(twsi1, TWSI1, 1, 33000000);
+static APBC_CLK(pwm1, PWM1, 1, 13000000);
+static APBC_CLK(pwm2, PWM2, 1, 13000000);
+static APBC_CLK(pwm3, PWM3, 1, 13000000);
+static APBC_CLK(pwm4, PWM4, 1, 13000000);
+static APBC_CLK(ssp1, SSP1, 4, 0);
+static APBC_CLK(ssp2, SSP2, 4, 0);
+static APBC_CLK(ssp3, SSP3, 4, 0);
+static APBC_CLK(ssp4, SSP4, 4, 0);
+static APBC_CLK(ssp5, SSP5, 4, 0);
+static APBC_CLK(gpio, GPIO, 0, 13000000);
+static APBC_CLK(keypad, KPC, 0, 32000);
+static APBC_CLK(rtc, RTC, 8, 32768);
+
+static APMU_CLK(nand, NAND, 0x19b, 156000000);
+static APMU_CLK(lcd, LCD, 0x7f, 312000000);
+static APMU_CLK(eth, ETH, 0x09, 0);
+static APMU_CLK(usb, USB, 0x12, 0);
+
+/* 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_uart3, "pxa2xx-uart.2", 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_gpio, "mmp-gpio", NULL),
+ INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL),
+ INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"),
+ INIT_CLKREG(&clk_usb, NULL, "PXA168-USBCLK"),
+ INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
+};
+
+void __init pxa168_clk_init(void)
+{
+ clkdev_add_table(ARRAY_AND_SIZE(pxa168_clkregs));
+}
diff --git a/arch/arm/mach-mmp/clock-pxa910.c b/arch/arm/mach-mmp/clock-pxa910.c
new file mode 100644
index 000000000..379e1df61
--- /dev/null
+++ b/arch/arm/mach-mmp/clock-pxa910.c
@@ -0,0 +1,67 @@
+#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 <mach/addr-map.h>
+
+#include "common.h"
+#include "clock.h"
+
+/*
+ * APB Clock register offsets for PXA910
+ */
+#define APBC_UART0 APBC_REG(0x000)
+#define APBC_UART1 APBC_REG(0x004)
+#define APBC_GPIO APBC_REG(0x008)
+#define APBC_PWM1 APBC_REG(0x00c)
+#define APBC_PWM2 APBC_REG(0x010)
+#define APBC_PWM3 APBC_REG(0x014)
+#define APBC_PWM4 APBC_REG(0x018)
+#define APBC_SSP1 APBC_REG(0x01c)
+#define APBC_SSP2 APBC_REG(0x020)
+#define APBC_RTC APBC_REG(0x028)
+#define APBC_TWSI0 APBC_REG(0x02c)
+#define APBC_KPC APBC_REG(0x030)
+#define APBC_SSP3 APBC_REG(0x04c)
+#define APBC_TWSI1 APBC_REG(0x06c)
+
+#define APMU_NAND APMU_REG(0x060)
+#define APMU_USB APMU_REG(0x05c)
+
+static APBC_CLK(uart1, UART0, 1, 14745600);
+static APBC_CLK(uart2, UART1, 1, 14745600);
+static APBC_CLK(twsi0, TWSI0, 1, 33000000);
+static APBC_CLK(twsi1, TWSI1, 1, 33000000);
+static APBC_CLK(pwm1, PWM1, 1, 13000000);
+static APBC_CLK(pwm2, PWM2, 1, 13000000);
+static APBC_CLK(pwm3, PWM3, 1, 13000000);
+static APBC_CLK(pwm4, PWM4, 1, 13000000);
+static APBC_CLK(gpio, GPIO, 0, 13000000);
+static APBC_CLK(rtc, RTC, 8, 32768);
+
+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_gpio, "mmp-gpio", NULL),
+ INIT_CLKREG(&clk_u2o, NULL, "U2OCLK"),
+ INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
+};
+
+void __init pxa910_clk_init(void)
+{
+ clkdev_add_table(ARRAY_AND_SIZE(pxa910_clkregs));
+}
diff --git a/arch/arm/mach-mmp/clock.c b/arch/arm/mach-mmp/clock.c
new file mode 100644
index 000000000..7c6f95f29
--- /dev/null
+++ b/arch/arm/mach-mmp/clock.c
@@ -0,0 +1,105 @@
+/*
+ * 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);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ if (clk->ops->setrate) {
+ spin_lock_irqsave(&clocks_lock, flags);
+ ret = clk->ops->setrate(clk, rate);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
diff --git a/arch/arm/mach-mmp/clock.h b/arch/arm/mach-mmp/clock.h
new file mode 100644
index 000000000..149b30cd1
--- /dev/null
+++ b/arch/arm/mach-mmp/clock.h
@@ -0,0 +1,71 @@
+/*
+ * 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 *);
+ int (*setrate)(struct clk *, unsigned long);
+};
+
+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 = 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 = APBC_##_reg, \
+ .fnclksel = _fnclksel, \
+ .rate = _rate, \
+ .ops = _ops, \
+}
+
+#define APMU_CLK(_name, _reg, _eval, _rate) \
+struct clk clk_##_name = { \
+ .clk_rst = 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 = 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 000000000..c03b4ab58
--- /dev/null
+++ b/arch/arm/mach-mmp/common.c
@@ -0,0 +1,53 @@
+/*
+ * 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 <asm/system_misc.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 = (unsigned long)APB_VIRT_BASE,
+ .length = APB_PHYS_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .pfn = __phys_to_pfn(AXI_PHYS_BASE),
+ .virtual = (unsigned long)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);
+}
+
+void mmp_restart(enum reboot_mode mode, const char *cmd)
+{
+ soft_restart(0);
+}
diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h
new file mode 100644
index 000000000..cf445bae6
--- /dev/null
+++ b/arch/arm/mach-mmp/common.h
@@ -0,0 +1,10 @@
+#include <linux/reboot.h>
+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
+
+extern void timer_init(int irq);
+
+extern void __init mmp_map_io(void);
+extern void mmp_restart(enum reboot_mode, const char *);
+extern void __init pxa168_clk_init(void);
+extern void __init pxa910_clk_init(void);
+extern void __init mmp2_clk_init(void);
diff --git a/arch/arm/mach-mmp/devices.c b/arch/arm/mach-mmp/devices.c
new file mode 100644
index 000000000..2bcb766af
--- /dev/null
+++ b/arch/arm/mach-mmp/devices.c
@@ -0,0 +1,351 @@
+/*
+ * 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 <linux/delay.h>
+
+#include <asm/irq.h>
+#include <mach/irqs.h>
+#include <mach/devices.h>
+#include <mach/cputype.h>
+#include <mach/regs-usb.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);
+}
+
+#if IS_ENABLED(CONFIG_USB) || IS_ENABLED(CONFIG_USB_GADGET)
+
+/*****************************************************************************
+ * The registers read/write routines
+ *****************************************************************************/
+
+static unsigned int u2o_get(void __iomem *base, unsigned int offset)
+{
+ return readl_relaxed(base + offset);
+}
+
+static void u2o_set(void __iomem *base, unsigned int offset,
+ unsigned int value)
+{
+ u32 reg;
+
+ reg = readl_relaxed(base + offset);
+ reg |= value;
+ writel_relaxed(reg, base + offset);
+ readl_relaxed(base + offset);
+}
+
+static void u2o_clear(void __iomem *base, unsigned int offset,
+ unsigned int value)
+{
+ u32 reg;
+
+ reg = readl_relaxed(base + offset);
+ reg &= ~value;
+ writel_relaxed(reg, base + offset);
+ readl_relaxed(base + offset);
+}
+
+static void u2o_write(void __iomem *base, unsigned int offset,
+ unsigned int value)
+{
+ writel_relaxed(value, base + offset);
+ readl_relaxed(base + offset);
+}
+
+#if IS_ENABLED(CONFIG_USB_MV_UDC) || IS_ENABLED(CONFIG_USB_EHCI_MV)
+
+#if IS_ENABLED(CONFIG_CPU_PXA910) || IS_ENABLED(CONFIG_CPU_PXA168)
+
+static DEFINE_MUTEX(phy_lock);
+static int phy_init_cnt;
+
+static int usb_phy_init_internal(void __iomem *base)
+{
+ int loops;
+
+ pr_info("Init usb phy!!!\n");
+
+ /* Initialize the USB PHY power */
+ if (cpu_is_pxa910()) {
+ u2o_set(base, UTMI_CTRL, (1<<UTMI_CTRL_INPKT_DELAY_SOF_SHIFT)
+ | (1<<UTMI_CTRL_PU_REF_SHIFT));
+ }
+
+ u2o_set(base, UTMI_CTRL, 1<<UTMI_CTRL_PLL_PWR_UP_SHIFT);
+ u2o_set(base, UTMI_CTRL, 1<<UTMI_CTRL_PWR_UP_SHIFT);
+
+ /* UTMI_PLL settings */
+ u2o_clear(base, UTMI_PLL, UTMI_PLL_PLLVDD18_MASK
+ | UTMI_PLL_PLLVDD12_MASK | UTMI_PLL_PLLCALI12_MASK
+ | UTMI_PLL_FBDIV_MASK | UTMI_PLL_REFDIV_MASK
+ | UTMI_PLL_ICP_MASK | UTMI_PLL_KVCO_MASK);
+
+ u2o_set(base, UTMI_PLL, 0xee<<UTMI_PLL_FBDIV_SHIFT
+ | 0xb<<UTMI_PLL_REFDIV_SHIFT | 3<<UTMI_PLL_PLLVDD18_SHIFT
+ | 3<<UTMI_PLL_PLLVDD12_SHIFT | 3<<UTMI_PLL_PLLCALI12_SHIFT
+ | 1<<UTMI_PLL_ICP_SHIFT | 3<<UTMI_PLL_KVCO_SHIFT);
+
+ /* UTMI_TX */
+ u2o_clear(base, UTMI_TX, UTMI_TX_REG_EXT_FS_RCAL_EN_MASK
+ | UTMI_TX_TXVDD12_MASK | UTMI_TX_CK60_PHSEL_MASK
+ | UTMI_TX_IMPCAL_VTH_MASK | UTMI_TX_REG_EXT_FS_RCAL_MASK
+ | UTMI_TX_AMP_MASK);
+ u2o_set(base, UTMI_TX, 3<<UTMI_TX_TXVDD12_SHIFT
+ | 4<<UTMI_TX_CK60_PHSEL_SHIFT | 4<<UTMI_TX_IMPCAL_VTH_SHIFT
+ | 8<<UTMI_TX_REG_EXT_FS_RCAL_SHIFT | 3<<UTMI_TX_AMP_SHIFT);
+
+ /* UTMI_RX */
+ u2o_clear(base, UTMI_RX, UTMI_RX_SQ_THRESH_MASK
+ | UTMI_REG_SQ_LENGTH_MASK);
+ u2o_set(base, UTMI_RX, 7<<UTMI_RX_SQ_THRESH_SHIFT
+ | 2<<UTMI_REG_SQ_LENGTH_SHIFT);
+
+ /* UTMI_IVREF */
+ if (cpu_is_pxa168())
+ /* fixing Microsoft Altair board interface with NEC hub issue -
+ * Set UTMI_IVREF from 0x4a3 to 0x4bf */
+ u2o_write(base, UTMI_IVREF, 0x4bf);
+
+ /* toggle VCOCAL_START bit of UTMI_PLL */
+ udelay(200);
+ u2o_set(base, UTMI_PLL, VCOCAL_START);
+ udelay(40);
+ u2o_clear(base, UTMI_PLL, VCOCAL_START);
+
+ /* toggle REG_RCAL_START bit of UTMI_TX */
+ udelay(400);
+ u2o_set(base, UTMI_TX, REG_RCAL_START);
+ udelay(40);
+ u2o_clear(base, UTMI_TX, REG_RCAL_START);
+ udelay(400);
+
+ /* Make sure PHY PLL is ready */
+ loops = 0;
+ while ((u2o_get(base, UTMI_PLL) & PLL_READY) == 0) {
+ mdelay(1);
+ loops++;
+ if (loops > 100) {
+ printk(KERN_WARNING "calibrate timeout, UTMI_PLL %x\n",
+ u2o_get(base, UTMI_PLL));
+ break;
+ }
+ }
+
+ if (cpu_is_pxa168()) {
+ u2o_set(base, UTMI_RESERVE, 1 << 5);
+ /* Turn on UTMI PHY OTG extension */
+ u2o_write(base, UTMI_OTG_ADDON, 1);
+ }
+
+ return 0;
+}
+
+static int usb_phy_deinit_internal(void __iomem *base)
+{
+ pr_info("Deinit usb phy!!!\n");
+
+ if (cpu_is_pxa168())
+ u2o_clear(base, UTMI_OTG_ADDON, UTMI_OTG_ADDON_OTG_ON);
+
+ u2o_clear(base, UTMI_CTRL, UTMI_CTRL_RXBUF_PDWN);
+ u2o_clear(base, UTMI_CTRL, UTMI_CTRL_TXBUF_PDWN);
+ u2o_clear(base, UTMI_CTRL, UTMI_CTRL_USB_CLK_EN);
+ u2o_clear(base, UTMI_CTRL, 1<<UTMI_CTRL_PWR_UP_SHIFT);
+ u2o_clear(base, UTMI_CTRL, 1<<UTMI_CTRL_PLL_PWR_UP_SHIFT);
+
+ return 0;
+}
+
+int pxa_usb_phy_init(void __iomem *phy_reg)
+{
+ mutex_lock(&phy_lock);
+ if (phy_init_cnt++ == 0)
+ usb_phy_init_internal(phy_reg);
+ mutex_unlock(&phy_lock);
+ return 0;
+}
+
+void pxa_usb_phy_deinit(void __iomem *phy_reg)
+{
+ WARN_ON(phy_init_cnt == 0);
+
+ mutex_lock(&phy_lock);
+ if (--phy_init_cnt == 0)
+ usb_phy_deinit_internal(phy_reg);
+ mutex_unlock(&phy_lock);
+}
+#endif
+#endif
+#endif
+
+#if IS_ENABLED(CONFIG_USB_SUPPORT)
+static u64 usb_dma_mask = ~(u32)0;
+
+#if IS_ENABLED(CONFIG_USB_MV_UDC)
+struct resource pxa168_u2o_resources[] = {
+ /* regbase */
+ [0] = {
+ .start = PXA168_U2O_REGBASE + U2x_CAPREGS_OFFSET,
+ .end = PXA168_U2O_REGBASE + USB_REG_RANGE,
+ .flags = IORESOURCE_MEM,
+ .name = "capregs",
+ },
+ /* phybase */
+ [1] = {
+ .start = PXA168_U2O_PHYBASE,
+ .end = PXA168_U2O_PHYBASE + USB_PHY_RANGE,
+ .flags = IORESOURCE_MEM,
+ .name = "phyregs",
+ },
+ [2] = {
+ .start = IRQ_PXA168_USB1,
+ .end = IRQ_PXA168_USB1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa168_device_u2o = {
+ .name = "mv-udc",
+ .id = -1,
+ .resource = pxa168_u2o_resources,
+ .num_resources = ARRAY_SIZE(pxa168_u2o_resources),
+ .dev = {
+ .dma_mask = &usb_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ }
+};
+#endif /* CONFIG_USB_MV_UDC */
+
+#if IS_ENABLED(CONFIG_USB_EHCI_MV_U2O)
+struct resource pxa168_u2oehci_resources[] = {
+ /* regbase */
+ [0] = {
+ .start = PXA168_U2O_REGBASE + U2x_CAPREGS_OFFSET,
+ .end = PXA168_U2O_REGBASE + USB_REG_RANGE,
+ .flags = IORESOURCE_MEM,
+ .name = "capregs",
+ },
+ /* phybase */
+ [1] = {
+ .start = PXA168_U2O_PHYBASE,
+ .end = PXA168_U2O_PHYBASE + USB_PHY_RANGE,
+ .flags = IORESOURCE_MEM,
+ .name = "phyregs",
+ },
+ [2] = {
+ .start = IRQ_PXA168_USB1,
+ .end = IRQ_PXA168_USB1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa168_device_u2oehci = {
+ .name = "pxa-u2oehci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &usb_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+
+ .num_resources = ARRAY_SIZE(pxa168_u2oehci_resources),
+ .resource = pxa168_u2oehci_resources,
+};
+#endif
+
+#if IS_ENABLED(CONFIG_USB_MV_OTG)
+struct resource pxa168_u2ootg_resources[] = {
+ /* regbase */
+ [0] = {
+ .start = PXA168_U2O_REGBASE + U2x_CAPREGS_OFFSET,
+ .end = PXA168_U2O_REGBASE + USB_REG_RANGE,
+ .flags = IORESOURCE_MEM,
+ .name = "capregs",
+ },
+ /* phybase */
+ [1] = {
+ .start = PXA168_U2O_PHYBASE,
+ .end = PXA168_U2O_PHYBASE + USB_PHY_RANGE,
+ .flags = IORESOURCE_MEM,
+ .name = "phyregs",
+ },
+ [2] = {
+ .start = IRQ_PXA168_USB1,
+ .end = IRQ_PXA168_USB1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa168_device_u2ootg = {
+ .name = "mv-otg",
+ .id = -1,
+ .dev = {
+ .dma_mask = &usb_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+
+ .num_resources = ARRAY_SIZE(pxa168_u2ootg_resources),
+ .resource = pxa168_u2ootg_resources,
+};
+#endif /* CONFIG_USB_MV_OTG */
+
+#endif
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
new file mode 100644
index 000000000..6291c33d8
--- /dev/null
+++ b/arch/arm/mach-mmp/flint.c
@@ -0,0 +1,134 @@
+/*
+ * 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/gpio-pxa.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-mmp2.h>
+#include <mach/mmp2.h>
+#include <mach/irqs.h>
+
+#include "common.h"
+
+#define FLINT_NR_IRQS (MMP_NR_IRQS + 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 pxa_gpio_platform_data mmp2_gpio_pdata = {
+ .irq_base = MMP_GPIO_TO_IRQ(0),
+};
+
+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 = MMP_GPIO_TO_IRQ(155),
+ .end = MMP_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);
+ platform_device_add_data(&mmp2_device_gpio, &mmp2_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
+ platform_device_register(&mmp2_device_gpio);
+
+ /* 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,
+ .init_time = mmp2_timer_init,
+ .init_machine = flint_init,
+ .restart = mmp_restart,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
new file mode 100644
index 000000000..22762a1f9
--- /dev/null
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -0,0 +1,209 @@
+/*
+ * linux/arch/arm/mach-mmp/gplugd.c
+ *
+ * Support for the Marvell PXA168-based GuruPlug Display (gplugD) 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/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/irqs.h>
+#include <mach/pxa168.h>
+#include <mach/mfp-pxa168.h>
+
+#include "common.h"
+
+static unsigned long gplugd_pin_config[] __initdata = {
+ /* UART3 */
+ GPIO8_UART3_TXD,
+ GPIO9_UART3_RXD,
+ GPIO1O_UART3_CTS,
+ GPIO11_UART3_RTS,
+
+ /* USB OTG PEN */
+ GPIO18_GPIO,
+
+ /* MMC2 */
+ GPIO28_MMC2_CMD,
+ GPIO29_MMC2_CLK,
+ GPIO30_MMC2_DAT0,
+ GPIO31_MMC2_DAT1,
+ GPIO32_MMC2_DAT2,
+ GPIO33_MMC2_DAT3,
+
+ /* LCD & HDMI clock selection GPIO: 0: 74.176MHz, 1: 74.25 MHz */
+ GPIO35_GPIO,
+ GPIO36_GPIO, /* CEC Interrupt */
+
+ /* MMC1 */
+ GPIO43_MMC1_CLK,
+ GPIO49_MMC1_CMD,
+ GPIO41_MMC1_DAT0,
+ GPIO40_MMC1_DAT1,
+ GPIO52_MMC1_DAT2,
+ GPIO51_MMC1_DAT3,
+ GPIO53_MMC1_CD,
+
+ /* 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,
+
+ /* GPIO */
+ GPIO84_GPIO,
+ GPIO85_GPIO,
+
+ /* Fast-Ethernet*/
+ GPIO86_TX_CLK,
+ GPIO87_TX_EN,
+ GPIO88_TX_DQ3,
+ GPIO89_TX_DQ2,
+ GPIO90_TX_DQ1,
+ GPIO91_TX_DQ0,
+ GPIO92_MII_CRS,
+ GPIO93_MII_COL,
+ GPIO94_RX_CLK,
+ GPIO95_RX_ER,
+ GPIO96_RX_DQ3,
+ GPIO97_RX_DQ2,
+ GPIO98_RX_DQ1,
+ GPIO99_RX_DQ0,
+ GPIO100_MII_MDC,
+ GPIO101_MII_MDIO,
+ GPIO103_RX_DV,
+ GPIO104_GPIO, /* Reset PHY */
+
+ /* RTC interrupt */
+ GPIO102_GPIO,
+
+ /* I2C */
+ GPIO105_CI2C_SDA,
+ GPIO106_CI2C_SCL,
+
+ /* SPI NOR Flash on SSP2 */
+ GPIO107_SSP2_RXD,
+ GPIO108_SSP2_TXD,
+ GPIO110_GPIO, /* SPI_CSn */
+ GPIO111_SSP2_CLK,
+
+ /* Select JTAG */
+ GPIO109_GPIO,
+
+ /* I2S */
+ GPIO114_I2S_FRM,
+ GPIO115_I2S_BCLK,
+ GPIO116_I2S_TXD
+};
+
+static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+ .irq_base = MMP_GPIO_TO_IRQ(0),
+};
+
+static struct i2c_board_info gplugd_i2c_board_info[] = {
+ {
+ .type = "isl1208",
+ .addr = 0x6F,
+ }
+};
+
+/* Bring PHY out of reset by setting GPIO 104 */
+static int gplugd_eth_init(void)
+{
+ if (unlikely(gpio_request(104, "ETH_RESET_N"))) {
+ printk(KERN_ERR "Can't get hold of GPIO 104 to bring Ethernet "
+ "PHY out of reset\n");
+ return -EIO;
+ }
+
+ gpio_direction_output(104, 1);
+ gpio_free(104);
+ return 0;
+}
+
+struct pxa168_eth_platform_data gplugd_eth_platform_data = {
+ .port_number = 0,
+ .phy_addr = 0,
+ .speed = 0, /* Autonagotiation */
+ .intf = PHY_INTERFACE_MODE_RMII,
+ .init = gplugd_eth_init,
+};
+
+static void __init select_disp_freq(void)
+{
+ /* set GPIO 35 & clear GPIO 85 to set LCD External Clock to 74.25 MHz */
+ if (unlikely(gpio_request(35, "DISP_FREQ_SEL"))) {
+ printk(KERN_ERR "Can't get hold of GPIO 35 to select display "
+ "frequency\n");
+ } else {
+ gpio_direction_output(35, 1);
+ gpio_free(35);
+ }
+
+ if (unlikely(gpio_request(85, "DISP_FREQ_SEL_2"))) {
+ printk(KERN_ERR "Can't get hold of GPIO 85 to select display "
+ "frequency\n");
+ } else {
+ gpio_direction_output(85, 0);
+ gpio_free(85);
+ }
+}
+
+static void __init gplugd_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(gplugd_pin_config));
+
+ select_disp_freq();
+
+ /* on-chip devices */
+ pxa168_add_uart(3);
+ pxa168_add_ssp(1);
+ pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info));
+ platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
+ platform_device_register(&pxa168_device_gpio);
+
+ pxa168_add_eth(&gplugd_eth_platform_data);
+}
+
+MACHINE_START(GPLUGD, "PXA168-based GuruPlug Display (gplugD) Platform")
+ .map_io = mmp_map_io,
+ .nr_irqs = MMP_NR_IRQS,
+ .init_irq = pxa168_init_irq,
+ .init_time = pxa168_timer_init,
+ .init_machine = gplugd_init,
+ .restart = pxa168_restart,
+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 000000000..f88a44c0e
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/addr-map.h
@@ -0,0 +1,46 @@
+/*
+ * 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 IOMEM(0xfe000000)
+#define APB_PHYS_SIZE 0x00200000
+
+#define AXI_PHYS_BASE 0xd4200000
+#define AXI_VIRT_BASE IOMEM(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
+
+#define APMU_VIRT_BASE (AXI_VIRT_BASE + 0x82800)
+#define APMU_REG(x) (APMU_VIRT_BASE + (x))
+
+#define APBC_VIRT_BASE (APB_VIRT_BASE + 0x015000)
+#define APBC_REG(x) (APBC_VIRT_BASE + (x))
+
+#define MPMU_VIRT_BASE (APB_VIRT_BASE + 0x50000)
+#define MPMU_REG(x) (MPMU_VIRT_BASE + (x))
+
+#define CIU_VIRT_BASE (AXI_VIRT_BASE + 0x82c00)
+#define CIU_REG(x) (CIU_VIRT_BASE + (x))
+
+#endif /* __ASM_MACH_ADDR_MAP_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 000000000..8a3b56dfd
--- /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/devices.h b/arch/arm/mach-mmp/include/mach/devices.h
new file mode 100644
index 000000000..21217ef11
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/devices.h
@@ -0,0 +1,56 @@
+#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);
+extern int pxa_usb_phy_init(void __iomem *phy_reg);
+extern void pxa_usb_phy_deinit(void __iomem *phy_reg);
+
+#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 000000000..1d6914544
--- /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/hardware.h b/arch/arm/mach-mmp/include/mach/hardware.h
new file mode 100644
index 000000000..99264a5ce
--- /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/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h
new file mode 100644
index 000000000..fb492a50a
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/irqs.h
@@ -0,0 +1,239 @@
+#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_MUX 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_MIPI_HSI1_MUX 51
+#define IRQ_MMP2_MMC2 52
+#define IRQ_MMP2_MMC3 53
+#define IRQ_MMP2_MMC4 54
+#define IRQ_MMP2_MIPI_HSI0_MUX 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 #9 */
+#define IRQ_MMP2_KEYPAD_BASE (IRQ_MMP2_RTC_BASE + 2)
+#define IRQ_MMP2_KPC (IRQ_MMP2_KEYPAD_BASE + 0)
+#define IRQ_MMP2_ROTORY (IRQ_MMP2_KEYPAD_BASE + 1)
+#define IRQ_MMP2_TBALL (IRQ_MMP2_KEYPAD_BASE + 2)
+
+/* secondary interrupt of INT #17 */
+#define IRQ_MMP2_TWSI_BASE (IRQ_MMP2_KEYPAD_BASE + 3)
+#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_MIPI_HSI1_BASE (IRQ_MMP2_MISC_BASE + 15)
+#define IRQ_MMP2_HSI1_CAWAKE (IRQ_MMP2_MIPI_HSI1_BASE + 0)
+#define IRQ_MMP2_MIPI_HSI_INT1 (IRQ_MMP2_MIPI_HSI1_BASE + 1)
+
+/* secondary interrupt of INT #55 */
+#define IRQ_MMP2_MIPI_HSI0_BASE (IRQ_MMP2_MIPI_HSI1_BASE + 2)
+#define IRQ_MMP2_HSI0_CAWAKE (IRQ_MMP2_MIPI_HSI0_BASE + 0)
+#define IRQ_MMP2_MIPI_HSI_INT0 (IRQ_MMP2_MIPI_HSI0_BASE + 1)
+
+#define IRQ_MMP2_MUX_END (IRQ_MMP2_MIPI_HSI0_BASE + 2)
+
+#define IRQ_GPIO_START 128
+#define MMP_NR_BUILTIN_GPIO 192
+#define MMP_GPIO_TO_IRQ(gpio) (IRQ_GPIO_START + (gpio))
+
+#define IRQ_BOARD_START (IRQ_GPIO_START + MMP_NR_BUILTIN_GPIO)
+#define MMP_NR_IRQS IRQ_BOARD_START
+
+#endif /* __ASM_MACH_IRQS_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 000000000..4ad38629c
--- /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 000000000..92aaa3c19
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
@@ -0,0 +1,354 @@
+#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 GPIO8_UART3_TXD MFP_CFG(GPIO8, AF2)
+#define GPIO9_UART3_RXD MFP_CFG(GPIO9, AF2)
+#define GPIO1O_UART3_CTS MFP_CFG(GPIO10, AF2)
+#define GPIO11_UART3_RTS MFP_CFG(GPIO11, AF2)
+#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)
+
+/* MMC2 */
+#define GPIO28_MMC2_CMD MFP_CFG_DRV(GPIO28, AF6, FAST)
+#define GPIO29_MMC2_CLK MFP_CFG_DRV(GPIO29, AF6, FAST)
+#define GPIO30_MMC2_DAT0 MFP_CFG_DRV(GPIO30, AF6, FAST)
+#define GPIO31_MMC2_DAT1 MFP_CFG_DRV(GPIO31, AF6, FAST)
+#define GPIO32_MMC2_DAT2 MFP_CFG_DRV(GPIO32, AF6, FAST)
+#define GPIO33_MMC2_DAT3 MFP_CFG_DRV(GPIO33, AF6, FAST)
+
+/* MMC4 */
+#define GPIO125_MMC4_DAT3 MFP_CFG_DRV(GPIO125, AF7, FAST)
+#define GPIO126_MMC4_DAT2 MFP_CFG_DRV(GPIO126, AF7, FAST)
+#define GPIO127_MMC4_DAT1 MFP_CFG_DRV(GPIO127, AF7, FAST)
+#define GPIO0_2_MMC4_DAT0 MFP_CFG_DRV(GPIO0_2, AF7, FAST)
+#define GPIO1_2_MMC4_CMD MFP_CFG_DRV(GPIO1_2, AF7, FAST)
+#define GPIO2_2_MMC4_CLK MFP_CFG_DRV(GPIO2_2, AF7, FAST)
+
+/* 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 GPIO116_I2S_TXD MFP_CFG(GPIO116, AF1)
+#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)
+
+/* Fast Ethernet */
+#define GPIO86_TX_CLK MFP_CFG(GPIO86, AF5)
+#define GPIO87_TX_EN MFP_CFG(GPIO87, AF5)
+#define GPIO88_TX_DQ3 MFP_CFG(GPIO88, AF5)
+#define GPIO89_TX_DQ2 MFP_CFG(GPIO89, AF5)
+#define GPIO90_TX_DQ1 MFP_CFG(GPIO90, AF5)
+#define GPIO91_TX_DQ0 MFP_CFG(GPIO91, AF5)
+#define GPIO92_MII_CRS MFP_CFG(GPIO92, AF5)
+#define GPIO93_MII_COL MFP_CFG(GPIO93, AF5)
+#define GPIO94_RX_CLK MFP_CFG(GPIO94, AF5)
+#define GPIO95_RX_ER MFP_CFG(GPIO95, AF5)
+#define GPIO96_RX_DQ3 MFP_CFG(GPIO96, AF5)
+#define GPIO97_RX_DQ2 MFP_CFG(GPIO97, AF5)
+#define GPIO98_RX_DQ1 MFP_CFG(GPIO98, AF5)
+#define GPIO99_RX_DQ0 MFP_CFG(GPIO99, AF5)
+#define GPIO100_MII_MDC MFP_CFG(GPIO100, AF5)
+#define GPIO101_MII_MDIO MFP_CFG(GPIO101, AF5)
+#define GPIO103_RX_DV MFP_CFG(GPIO103, AF5)
+
+/* SSP2 */
+#define GPIO107_SSP2_RXD MFP_CFG(GPIO107, AF4)
+#define GPIO108_SSP2_TXD MFP_CFG(GPIO108, AF4)
+#define GPIO111_SSP2_CLK MFP_CFG(GPIO111, AF4)
+#define GPIO112_SSP2_FRM MFP_CFG(GPIO112, AF4)
+
+#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 000000000..8c78f2b16
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
@@ -0,0 +1,169 @@
+#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_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 000000000..62e510e80
--- /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 000000000..0764f4ece
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/mmp2.h
@@ -0,0 +1,102 @@
+#ifndef __ASM_MACH_MMP2_H
+#define __ASM_MACH_MMP2_H
+
+#include <linux/platform_data/pxa_sdhci.h>
+
+extern void mmp2_timer_init(void);
+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>
+#include <linux/platform_data/dma-mmp_tdma.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;
+extern struct pxa_device_desc mmp2_device_asram;
+extern struct pxa_device_desc mmp2_device_isram;
+
+extern struct platform_device mmp2_device_gpio;
+
+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));
+}
+
+static inline int mmp2_add_asram(struct sram_platdata *data)
+{
+ return pxa_register_device(&mmp2_device_asram, data, sizeof(*data));
+}
+
+static inline int mmp2_add_isram(struct sram_platdata *data)
+{
+ return pxa_register_device(&mmp2_device_isram, data, sizeof(*data));
+}
+
+#endif /* __ASM_MACH_MMP2_H */
+
diff --git a/arch/arm/mach-mmp/include/mach/pm-mmp2.h b/arch/arm/mach-mmp/include/mach/pm-mmp2.h
new file mode 100644
index 000000000..98bd66ce8
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/pm-mmp2.h
@@ -0,0 +1,61 @@
+/*
+ * MMP2 Power Management Routines
+ *
+ * This software program is licensed subject to the GNU General Public License
+ * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * (C) Copyright 2010 Marvell International Ltd.
+ * All Rights Reserved
+ */
+
+#ifndef __MMP2_PM_H__
+#define __MMP2_PM_H__
+
+#include <mach/addr-map.h>
+
+#define APMU_PJ_IDLE_CFG APMU_REG(0x018)
+#define APMU_PJ_IDLE_CFG_PJ_IDLE (1 << 1)
+#define APMU_PJ_IDLE_CFG_PJ_PWRDWN (1 << 5)
+#define APMU_PJ_IDLE_CFG_PWR_SW(x) ((x) << 16)
+#define APMU_PJ_IDLE_CFG_L2_PWR_SW (1 << 19)
+#define APMU_PJ_IDLE_CFG_ISO_MODE_CNTRL_MASK (3 << 28)
+
+#define APMU_SRAM_PWR_DWN APMU_REG(0x08c)
+
+#define MPMU_SCCR MPMU_REG(0x038)
+#define MPMU_PCR_PJ MPMU_REG(0x1000)
+#define MPMU_PCR_PJ_AXISD (1 << 31)
+#define MPMU_PCR_PJ_SLPEN (1 << 29)
+#define MPMU_PCR_PJ_SPSD (1 << 28)
+#define MPMU_PCR_PJ_DDRCORSD (1 << 27)
+#define MPMU_PCR_PJ_APBSD (1 << 26)
+#define MPMU_PCR_PJ_INTCLR (1 << 24)
+#define MPMU_PCR_PJ_SLPWP0 (1 << 23)
+#define MPMU_PCR_PJ_SLPWP1 (1 << 22)
+#define MPMU_PCR_PJ_SLPWP2 (1 << 21)
+#define MPMU_PCR_PJ_SLPWP3 (1 << 20)
+#define MPMU_PCR_PJ_VCTCXOSD (1 << 19)
+#define MPMU_PCR_PJ_SLPWP4 (1 << 18)
+#define MPMU_PCR_PJ_SLPWP5 (1 << 17)
+#define MPMU_PCR_PJ_SLPWP6 (1 << 16)
+#define MPMU_PCR_PJ_SLPWP7 (1 << 15)
+
+#define MPMU_PLL2_CTRL1 MPMU_REG(0x0414)
+#define MPMU_CGR_PJ MPMU_REG(0x1024)
+#define MPMU_WUCRM_PJ MPMU_REG(0x104c)
+#define MPMU_WUCRM_PJ_WAKEUP(x) (1 << (x))
+#define MPMU_WUCRM_PJ_RTC_ALARM (1 << 17)
+
+enum {
+ POWER_MODE_ACTIVE = 0,
+ POWER_MODE_CORE_INTIDLE,
+ POWER_MODE_CORE_EXTIDLE,
+ POWER_MODE_APPS_IDLE,
+ POWER_MODE_APPS_SLEEP,
+ POWER_MODE_CHIP_SLEEP,
+ POWER_MODE_SYS_SLEEP,
+};
+
+extern void mmp2_pm_enter_lowpower_mode(int state);
+extern int mmp2_set_wake(struct irq_data *d, unsigned int on);
+#endif
diff --git a/arch/arm/mach-mmp/include/mach/pm-pxa910.h b/arch/arm/mach-mmp/include/mach/pm-pxa910.h
new file mode 100644
index 000000000..8cac8ab52
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/pm-pxa910.h
@@ -0,0 +1,77 @@
+/*
+ * PXA910 Power Management Routines
+ *
+ * This software program is licensed subject to the GNU General Public License
+ * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * (C) Copyright 2009 Marvell International Ltd.
+ * All Rights Reserved
+ */
+
+#ifndef __PXA910_PM_H__
+#define __PXA910_PM_H__
+
+#define APMU_MOH_IDLE_CFG APMU_REG(0x0018)
+#define APMU_MOH_IDLE_CFG_MOH_IDLE (1 << 1)
+#define APMU_MOH_IDLE_CFG_MOH_PWRDWN (1 << 5)
+#define APMU_MOH_IDLE_CFG_MOH_SRAM_PWRDWN (1 << 6)
+#define APMU_MOH_IDLE_CFG_MOH_PWR_SW(x) (((x) & 0x3) << 16)
+#define APMU_MOH_IDLE_CFG_MOH_L2_PWR_SW(x) (((x) & 0x3) << 18)
+#define APMU_MOH_IDLE_CFG_MOH_DIS_MC_SW_REQ (1 << 21)
+#define APMU_MOH_IDLE_CFG_MOH_MC_WAKE_EN (1 << 20)
+
+#define APMU_SQU_CLK_GATE_CTRL APMU_REG(0x001c)
+#define APMU_MC_HW_SLP_TYPE APMU_REG(0x00b0)
+
+#define MPMU_FCCR MPMU_REG(0x0008)
+#define MPMU_APCR MPMU_REG(0x1000)
+#define MPMU_APCR_AXISD (1 << 31)
+#define MPMU_APCR_DSPSD (1 << 30)
+#define MPMU_APCR_SLPEN (1 << 29)
+#define MPMU_APCR_DTCMSD (1 << 28)
+#define MPMU_APCR_DDRCORSD (1 << 27)
+#define MPMU_APCR_APBSD (1 << 26)
+#define MPMU_APCR_BBSD (1 << 25)
+#define MPMU_APCR_SLPWP0 (1 << 23)
+#define MPMU_APCR_SLPWP1 (1 << 22)
+#define MPMU_APCR_SLPWP2 (1 << 21)
+#define MPMU_APCR_SLPWP3 (1 << 20)
+#define MPMU_APCR_VCTCXOSD (1 << 19)
+#define MPMU_APCR_SLPWP4 (1 << 18)
+#define MPMU_APCR_SLPWP5 (1 << 17)
+#define MPMU_APCR_SLPWP6 (1 << 16)
+#define MPMU_APCR_SLPWP7 (1 << 15)
+#define MPMU_APCR_MSASLPEN (1 << 14)
+#define MPMU_APCR_STBYEN (1 << 13)
+
+#define MPMU_AWUCRM MPMU_REG(0x104c)
+#define MPMU_AWUCRM_AP_ASYNC_INT (1 << 25)
+#define MPMU_AWUCRM_AP_FULL_IDLE (1 << 24)
+#define MPMU_AWUCRM_SDH1 (1 << 23)
+#define MPMU_AWUCRM_SDH2 (1 << 22)
+#define MPMU_AWUCRM_KEYPRESS (1 << 21)
+#define MPMU_AWUCRM_TRACKBALL (1 << 20)
+#define MPMU_AWUCRM_NEWROTARY (1 << 19)
+#define MPMU_AWUCRM_RTC_ALARM (1 << 17)
+#define MPMU_AWUCRM_AP2_TIMER_3 (1 << 13)
+#define MPMU_AWUCRM_AP2_TIMER_2 (1 << 12)
+#define MPMU_AWUCRM_AP2_TIMER_1 (1 << 11)
+#define MPMU_AWUCRM_AP1_TIMER_3 (1 << 10)
+#define MPMU_AWUCRM_AP1_TIMER_2 (1 << 9)
+#define MPMU_AWUCRM_AP1_TIMER_1 (1 << 8)
+#define MPMU_AWUCRM_WAKEUP(x) (1 << ((x) & 0x7))
+
+enum {
+ POWER_MODE_ACTIVE = 0,
+ POWER_MODE_CORE_INTIDLE,
+ POWER_MODE_CORE_EXTIDLE,
+ POWER_MODE_APPS_IDLE,
+ POWER_MODE_APPS_SLEEP,
+ POWER_MODE_SYS_SLEEP,
+ POWER_MODE_HIBERNATE,
+ POWER_MODE_UDR,
+};
+
+extern int pxa910_set_wake(struct irq_data *data, unsigned int on);
+
+#endif
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 000000000..a83ba7cb5
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -0,0 +1,137 @@
+#ifndef __ASM_MACH_PXA168_H
+#define __ASM_MACH_PXA168_H
+
+#include <linux/reboot.h>
+
+extern void pxa168_timer_init(void);
+extern void __init icu_init_irq(void);
+extern void __init pxa168_init_irq(void);
+extern void pxa168_restart(enum reboot_mode, const char *);
+extern void pxa168_clear_keypad_wakeup(void);
+
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <mach/devices.h>
+#include <linux/platform_data/mtd-nand-pxa3xx.h>
+#include <video/pxa168fb.h>
+#include <linux/platform_data/keypad-pxa27x.h>
+#include <mach/cputype.h>
+#include <linux/pxa168_eth.h>
+#include <linux/platform_data/mv_usb.h>
+
+extern struct pxa_device_desc pxa168_device_uart1;
+extern struct pxa_device_desc pxa168_device_uart2;
+extern struct pxa_device_desc pxa168_device_uart3;
+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;
+extern struct pxa_device_desc pxa168_device_eth;
+
+/* pdata can be NULL */
+extern int __init pxa168_add_usb_host(struct mv_usb_platform_data *pdata);
+
+
+extern struct platform_device pxa168_device_gpio;
+
+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;
+ case 3: d = &pxa168_device_uart3; 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));
+}
+
+static inline int pxa168_add_eth(struct pxa168_eth_platform_data *data)
+{
+ return pxa_register_device(&pxa168_device_eth, 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 000000000..92253203f
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/pxa910.h
@@ -0,0 +1,87 @@
+#ifndef __ASM_MACH_PXA910_H
+#define __ASM_MACH_PXA910_H
+
+extern void pxa910_timer_init(void);
+extern void __init icu_init_irq(void);
+extern void __init pxa910_init_irq(void);
+
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <mach/devices.h>
+#include <linux/platform_data/mtd-nand-pxa3xx.h>
+#include <video/mmp_disp.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;
+extern struct platform_device pxa168_device_u2o;
+extern struct platform_device pxa168_device_u2ootg;
+extern struct platform_device pxa168_device_u2oehci;
+extern struct pxa_device_desc pxa910_device_disp;
+extern struct pxa_device_desc pxa910_device_fb;
+extern struct pxa_device_desc pxa910_device_panel;
+extern struct platform_device pxa910_device_gpio;
+extern struct platform_device pxa910_device_rtc;
+
+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 000000000..ddc812f40
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/regs-apbc.h
@@ -0,0 +1,24 @@
+/*
+ * 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>
+
+/* 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 000000000..93c8d0e29
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/regs-apmu.h
@@ -0,0 +1,33 @@
+/*
+ * 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_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 000000000..f882d9189
--- /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-rtc.h b/arch/arm/mach-mmp/include/mach/regs-rtc.h
new file mode 100644
index 000000000..5bff886a3
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/regs-rtc.h
@@ -0,0 +1,23 @@
+#ifndef __ASM_MACH_REGS_RTC_H
+#define __ASM_MACH_REGS_RTC_H
+
+#include <mach/addr-map.h>
+
+#define RTC_VIRT_BASE (APB_VIRT_BASE + 0x10000)
+#define RTC_REG(x) (*((volatile u32 __iomem *)(RTC_VIRT_BASE + (x))))
+
+/*
+ * Real Time Clock
+ */
+
+#define RCNR RTC_REG(0x00) /* RTC Count Register */
+#define RTAR RTC_REG(0x04) /* RTC Alarm Register */
+#define RTSR RTC_REG(0x08) /* RTC Status Register */
+#define RTTR RTC_REG(0x0C) /* RTC Timer Trim Register */
+
+#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-mmp/include/mach/regs-smc.h b/arch/arm/mach-mmp/include/mach/regs-smc.h
new file mode 100644
index 000000000..e484d40d7
--- /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 000000000..45589fec9
--- /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/regs-usb.h b/arch/arm/mach-mmp/include/mach/regs-usb.h
new file mode 100644
index 000000000..b047bf487
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/regs-usb.h
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __ASM_ARCH_REGS_USB_H
+#define __ASM_ARCH_REGS_USB_H
+
+#define PXA168_U2O_REGBASE (0xd4208000)
+#define PXA168_U2O_PHYBASE (0xd4207000)
+
+#define PXA168_U2H_REGBASE (0xd4209000)
+#define PXA168_U2H_PHYBASE (0xd4206000)
+
+#define MMP3_HSIC1_REGBASE (0xf0001000)
+#define MMP3_HSIC1_PHYBASE (0xf0001800)
+
+#define MMP3_HSIC2_REGBASE (0xf0002000)
+#define MMP3_HSIC2_PHYBASE (0xf0002800)
+
+#define MMP3_FSIC_REGBASE (0xf0003000)
+#define MMP3_FSIC_PHYBASE (0xf0003800)
+
+
+#define USB_REG_RANGE (0x1ff)
+#define USB_PHY_RANGE (0xff)
+
+/* registers */
+#define U2x_CAPREGS_OFFSET 0x100
+
+/* phy regs */
+#define UTMI_REVISION 0x0
+#define UTMI_CTRL 0x4
+#define UTMI_PLL 0x8
+#define UTMI_TX 0xc
+#define UTMI_RX 0x10
+#define UTMI_IVREF 0x14
+#define UTMI_T0 0x18
+#define UTMI_T1 0x1c
+#define UTMI_T2 0x20
+#define UTMI_T3 0x24
+#define UTMI_T4 0x28
+#define UTMI_T5 0x2c
+#define UTMI_RESERVE 0x30
+#define UTMI_USB_INT 0x34
+#define UTMI_DBG_CTL 0x38
+#define UTMI_OTG_ADDON 0x3c
+
+/* For UTMICTRL Register */
+#define UTMI_CTRL_USB_CLK_EN (1 << 31)
+/* pxa168 */
+#define UTMI_CTRL_SUSPEND_SET1 (1 << 30)
+#define UTMI_CTRL_SUSPEND_SET2 (1 << 29)
+#define UTMI_CTRL_RXBUF_PDWN (1 << 24)
+#define UTMI_CTRL_TXBUF_PDWN (1 << 11)
+
+#define UTMI_CTRL_INPKT_DELAY_SHIFT 30
+#define UTMI_CTRL_INPKT_DELAY_SOF_SHIFT 28
+#define UTMI_CTRL_PU_REF_SHIFT 20
+#define UTMI_CTRL_ARC_PULLDN_SHIFT 12
+#define UTMI_CTRL_PLL_PWR_UP_SHIFT 1
+#define UTMI_CTRL_PWR_UP_SHIFT 0
+
+/* For UTMI_PLL Register */
+#define UTMI_PLL_PLLCALI12_SHIFT 29
+#define UTMI_PLL_PLLCALI12_MASK (0x3 << 29)
+
+#define UTMI_PLL_PLLVDD18_SHIFT 27
+#define UTMI_PLL_PLLVDD18_MASK (0x3 << 27)
+
+#define UTMI_PLL_PLLVDD12_SHIFT 25
+#define UTMI_PLL_PLLVDD12_MASK (0x3 << 25)
+
+#define UTMI_PLL_CLK_BLK_EN_SHIFT 24
+#define CLK_BLK_EN (0x1 << 24)
+#define PLL_READY (0x1 << 23)
+#define KVCO_EXT (0x1 << 22)
+#define VCOCAL_START (0x1 << 21)
+
+#define UTMI_PLL_KVCO_SHIFT 15
+#define UTMI_PLL_KVCO_MASK (0x7 << 15)
+
+#define UTMI_PLL_ICP_SHIFT 12
+#define UTMI_PLL_ICP_MASK (0x7 << 12)
+
+#define UTMI_PLL_FBDIV_SHIFT 4
+#define UTMI_PLL_FBDIV_MASK (0xFF << 4)
+
+#define UTMI_PLL_REFDIV_SHIFT 0
+#define UTMI_PLL_REFDIV_MASK (0xF << 0)
+
+/* For UTMI_TX Register */
+#define UTMI_TX_REG_EXT_FS_RCAL_SHIFT 27
+#define UTMI_TX_REG_EXT_FS_RCAL_MASK (0xf << 27)
+
+#define UTMI_TX_REG_EXT_FS_RCAL_EN_SHIFT 26
+#define UTMI_TX_REG_EXT_FS_RCAL_EN_MASK (0x1 << 26)
+
+#define UTMI_TX_TXVDD12_SHIFT 22
+#define UTMI_TX_TXVDD12_MASK (0x3 << 22)
+
+#define UTMI_TX_CK60_PHSEL_SHIFT 17
+#define UTMI_TX_CK60_PHSEL_MASK (0xf << 17)
+
+#define UTMI_TX_IMPCAL_VTH_SHIFT 14
+#define UTMI_TX_IMPCAL_VTH_MASK (0x7 << 14)
+
+#define REG_RCAL_START (0x1 << 12)
+
+#define UTMI_TX_LOW_VDD_EN_SHIFT 11
+
+#define UTMI_TX_AMP_SHIFT 0
+#define UTMI_TX_AMP_MASK (0x7 << 0)
+
+/* For UTMI_RX Register */
+#define UTMI_REG_SQ_LENGTH_SHIFT 15
+#define UTMI_REG_SQ_LENGTH_MASK (0x3 << 15)
+
+#define UTMI_RX_SQ_THRESH_SHIFT 4
+#define UTMI_RX_SQ_THRESH_MASK (0xf << 4)
+
+#define UTMI_OTG_ADDON_OTG_ON (1 << 0)
+
+/* For MMP3 USB Phy */
+#define USB2_PLL_REG0 0x4
+#define USB2_PLL_REG1 0x8
+#define USB2_TX_REG0 0x10
+#define USB2_TX_REG1 0x14
+#define USB2_TX_REG2 0x18
+#define USB2_RX_REG0 0x20
+#define USB2_RX_REG1 0x24
+#define USB2_RX_REG2 0x28
+#define USB2_ANA_REG0 0x30
+#define USB2_ANA_REG1 0x34
+#define USB2_ANA_REG2 0x38
+#define USB2_DIG_REG0 0x3C
+#define USB2_DIG_REG1 0x40
+#define USB2_DIG_REG2 0x44
+#define USB2_DIG_REG3 0x48
+#define USB2_TEST_REG0 0x4C
+#define USB2_TEST_REG1 0x50
+#define USB2_TEST_REG2 0x54
+#define USB2_CHARGER_REG0 0x58
+#define USB2_OTG_REG0 0x5C
+#define USB2_PHY_MON0 0x60
+#define USB2_RESETVE_REG0 0x64
+#define USB2_ICID_REG0 0x78
+#define USB2_ICID_REG1 0x7C
+
+/* USB2_PLL_REG0 */
+/* This is for Ax stepping */
+#define USB2_PLL_FBDIV_SHIFT_MMP3 0
+#define USB2_PLL_FBDIV_MASK_MMP3 (0xFF << 0)
+
+#define USB2_PLL_REFDIV_SHIFT_MMP3 8
+#define USB2_PLL_REFDIV_MASK_MMP3 (0xF << 8)
+
+#define USB2_PLL_VDD12_SHIFT_MMP3 12
+#define USB2_PLL_VDD18_SHIFT_MMP3 14
+
+/* This is for B0 stepping */
+#define USB2_PLL_FBDIV_SHIFT_MMP3_B0 0
+#define USB2_PLL_REFDIV_SHIFT_MMP3_B0 9
+#define USB2_PLL_VDD18_SHIFT_MMP3_B0 14
+#define USB2_PLL_FBDIV_MASK_MMP3_B0 0x01FF
+#define USB2_PLL_REFDIV_MASK_MMP3_B0 0x3E00
+
+#define USB2_PLL_CAL12_SHIFT_MMP3 0
+#define USB2_PLL_CALI12_MASK_MMP3 (0x3 << 0)
+
+#define USB2_PLL_VCOCAL_START_SHIFT_MMP3 2
+
+#define USB2_PLL_KVCO_SHIFT_MMP3 4
+#define USB2_PLL_KVCO_MASK_MMP3 (0x7<<4)
+
+#define USB2_PLL_ICP_SHIFT_MMP3 8
+#define USB2_PLL_ICP_MASK_MMP3 (0x7<<8)
+
+#define USB2_PLL_LOCK_BYPASS_SHIFT_MMP3 12
+
+#define USB2_PLL_PU_PLL_SHIFT_MMP3 13
+#define USB2_PLL_PU_PLL_MASK (0x1 << 13)
+
+#define USB2_PLL_READY_MASK_MMP3 (0x1 << 15)
+
+/* USB2_TX_REG0 */
+#define USB2_TX_IMPCAL_VTH_SHIFT_MMP3 8
+#define USB2_TX_IMPCAL_VTH_MASK_MMP3 (0x7 << 8)
+
+#define USB2_TX_RCAL_START_SHIFT_MMP3 13
+
+/* USB2_TX_REG1 */
+#define USB2_TX_CK60_PHSEL_SHIFT_MMP3 0
+#define USB2_TX_CK60_PHSEL_MASK_MMP3 (0xf << 0)
+
+#define USB2_TX_AMP_SHIFT_MMP3 4
+#define USB2_TX_AMP_MASK_MMP3 (0x7 << 4)
+
+#define USB2_TX_VDD12_SHIFT_MMP3 8
+#define USB2_TX_VDD12_MASK_MMP3 (0x3 << 8)
+
+/* USB2_TX_REG2 */
+#define USB2_TX_DRV_SLEWRATE_SHIFT 10
+
+/* USB2_RX_REG0 */
+#define USB2_RX_SQ_THRESH_SHIFT_MMP3 4
+#define USB2_RX_SQ_THRESH_MASK_MMP3 (0xf << 4)
+
+#define USB2_RX_SQ_LENGTH_SHIFT_MMP3 10
+#define USB2_RX_SQ_LENGTH_MASK_MMP3 (0x3 << 10)
+
+/* USB2_ANA_REG1*/
+#define USB2_ANA_PU_ANA_SHIFT_MMP3 14
+
+/* USB2_OTG_REG0 */
+#define USB2_OTG_PU_OTG_SHIFT_MMP3 3
+
+/* fsic registers */
+#define FSIC_MISC 0x4
+#define FSIC_INT 0x28
+#define FSIC_CTRL 0x30
+
+/* HSIC registers */
+#define HSIC_PAD_CTRL 0x4
+
+#define HSIC_CTRL 0x8
+#define HSIC_CTRL_HSIC_ENABLE (1<<7)
+#define HSIC_CTRL_PLL_BYPASS (1<<4)
+
+#define TEST_GRP_0 0xc
+#define TEST_GRP_1 0x10
+
+#define HSIC_INT 0x14
+#define HSIC_INT_READY_INT_EN (1<<10)
+#define HSIC_INT_CONNECT_INT_EN (1<<9)
+#define HSIC_INT_CORE_INT_EN (1<<8)
+#define HSIC_INT_HS_READY (1<<2)
+#define HSIC_INT_CONNECT (1<<1)
+#define HSIC_INT_CORE (1<<0)
+
+#define HSIC_CONFIG 0x18
+#define USBHSIC_CTRL 0x20
+
+#define HSIC_USB_CTRL 0x28
+#define HSIC_USB_CTRL_CLKEN 1
+#define HSIC_USB_CLK_PHY 0x0
+#define HSIC_USB_CLK_PMU 0x1
+
+#endif /* __ASM_ARCH_PXA_U2O_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 000000000..61a539b2c
--- /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/uncompress.h b/arch/arm/mach-mmp/include/mach/uncompress.h
new file mode 100644
index 000000000..8890fa8fa
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/uncompress.h
@@ -0,0 +1,45 @@
+/*
+ * 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;
+}
diff --git a/arch/arm/mach-mmp/jasper.c b/arch/arm/mach-mmp/jasper.c
new file mode 100644
index 000000000..0e9e5c05b
--- /dev/null
+++ b/arch/arm/mach-mmp/jasper.c
@@ -0,0 +1,188 @@
+/*
+ * 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/gpio-pxa.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/max8649.h>
+#include <linux/mfd/max8925.h>
+#include <linux/interrupt.h>
+
+#include <mach/irqs.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 (MMP_NR_IRQS + 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 pxa_gpio_platform_data mmp2_gpio_pdata = {
+ .irq_base = MMP_GPIO_TO_IRQ(0),
+};
+
+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 = MMP_NR_IRQS,
+};
+
+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 = {
+ .clk_delay_cycles = 0x1f,
+};
+
+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));
+ platform_device_add_data(&mmp2_device_gpio, &mmp2_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
+ platform_device_register(&mmp2_device_gpio);
+ 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,
+ .init_time = mmp2_timer_init,
+ .init_machine = jasper_init,
+ .restart = mmp_restart,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/mmp-dt.c b/arch/arm/mach-mmp/mmp-dt.c
new file mode 100644
index 000000000..b2296c930
--- /dev/null
+++ b/arch/arm/mach-mmp/mmp-dt.c
@@ -0,0 +1,52 @@
+/*
+ * linux/arch/arm/mach-mmp/mmp-dt.c
+ *
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@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/irqchip.h>
+#include <linux/of_platform.h>
+#include <linux/clk-provider.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/cache-tauros2.h>
+
+#include "common.h"
+
+extern void __init mmp_dt_init_timer(void);
+
+static const char *pxa168_dt_board_compat[] __initdata = {
+ "mrvl,pxa168-aspenite",
+ NULL,
+};
+
+static const char *pxa910_dt_board_compat[] __initdata = {
+ "mrvl,pxa910-dkb",
+ NULL,
+};
+
+static void __init mmp_init_time(void)
+{
+#ifdef CONFIG_CACHE_TAUROS2
+ tauros2_init(0);
+#endif
+ mmp_dt_init_timer();
+ of_clk_init(NULL);
+}
+
+DT_MACHINE_START(PXA168_DT, "Marvell PXA168 (Device Tree Support)")
+ .map_io = mmp_map_io,
+ .init_time = mmp_init_time,
+ .dt_compat = pxa168_dt_board_compat,
+MACHINE_END
+
+DT_MACHINE_START(PXA910_DT, "Marvell PXA910 (Device Tree Support)")
+ .map_io = mmp_map_io,
+ .init_time = mmp_init_time,
+ .dt_compat = pxa910_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/mmp2-dt.c b/arch/arm/mach-mmp/mmp2-dt.c
new file mode 100644
index 000000000..998c0f533
--- /dev/null
+++ b/arch/arm/mach-mmp/mmp2-dt.c
@@ -0,0 +1,42 @@
+/*
+ * linux/arch/arm/mach-mmp/mmp2-dt.c
+ *
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@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/io.h>
+#include <linux/irqchip.h>
+#include <linux/of_platform.h>
+#include <linux/clk-provider.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/cache-tauros2.h>
+
+#include "common.h"
+
+extern void __init mmp_dt_init_timer(void);
+
+static void __init mmp_init_time(void)
+{
+#ifdef CONFIG_CACHE_TAUROS2
+ tauros2_init(0);
+#endif
+ mmp_dt_init_timer();
+ of_clk_init(NULL);
+}
+
+static const char *mmp2_dt_board_compat[] __initdata = {
+ "mrvl,mmp2-brownstone",
+ NULL,
+};
+
+DT_MACHINE_START(MMP2_DT, "Marvell MMP2 (Device Tree Support)")
+ .map_io = mmp_map_io,
+ .init_time = mmp_init_time,
+ .dt_compat = mmp2_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
new file mode 100644
index 000000000..a70b5530b
--- /dev/null
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -0,0 +1,177 @@
+/*
+ * 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 <linux/irq.h>
+#include <linux/irqchip/mmp.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware/cache-tauros2.h>
+
+#include <asm/mach/time.h>
+#include <mach/addr-map.h>
+#include <mach/regs-apbc.h>
+#include <mach/cputype.h>
+#include <mach/irqs.h>
+#include <mach/dma.h>
+#include <mach/mfp.h>
+#include <mach/devices.h>
+#include <mach/mmp2.h>
+#include <mach/pm-mmp2.h>
+
+#include "common.h"
+
+#define MFPR_VIRT_BASE (APB_VIRT_BASE + 0x1e000)
+
+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)
+{
+ void __iomem *mfpr_pmic;
+ unsigned long 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);
+}
+
+void __init mmp2_init_irq(void)
+{
+ mmp2_init_icu();
+#ifdef CONFIG_PM
+ icu_irq_chip.irq_set_wake = mmp2_set_wake;
+#endif
+}
+
+static int __init mmp2_init(void)
+{
+ if (cpu_is_mmp2()) {
+#ifdef CONFIG_CACHE_TAUROS2
+ tauros2_init(0);
+#endif
+ mfp_init_base(MFPR_VIRT_BASE);
+ mfp_init_addr(mmp2_addr_map);
+ pxa_init_dma(IRQ_MMP2_DMA_RIQ, 16);
+ mmp2_clk_init();
+ }
+
+ return 0;
+}
+postcore_initcall(mmp2_init);
+
+#define APBC_TIMERS APBC_REG(0x024)
+
+void __init mmp2_timer_init(void)
+{
+ unsigned long clk_rst;
+
+ __raw_writel(APBC_APBCLK | APBC_RST, APBC_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_TIMERS);
+
+ timer_init(IRQ_MMP2_TIMER1);
+}
+
+/* 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-pxav3", 0, MMC, 0xd4280000, 0x120);
+MMP2_DEVICE(sdh1, "sdhci-pxav3", 1, MMC2, 0xd4280800, 0x120);
+MMP2_DEVICE(sdh2, "sdhci-pxav3", 2, MMC3, 0xd4281000, 0x120);
+MMP2_DEVICE(sdh3, "sdhci-pxav3", 3, MMC4, 0xd4281800, 0x120);
+MMP2_DEVICE(asram, "asram", -1, NONE, 0xe0000000, 0x4000);
+/* 0xd1000000 ~ 0xd101ffff is reserved for secure processor */
+MMP2_DEVICE(isram, "isram", -1, NONE, 0xd1020000, 0x18000);
+
+struct resource mmp2_resource_gpio[] = {
+ {
+ .start = 0xd4019000,
+ .end = 0xd4019fff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_MMP2_GPIO,
+ .end = IRQ_MMP2_GPIO,
+ .name = "gpio_mux",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mmp2_device_gpio = {
+ .name = "mmp2-gpio",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(mmp2_resource_gpio),
+ .resource = mmp2_resource_gpio,
+};
diff --git a/arch/arm/mach-mmp/pm-mmp2.c b/arch/arm/mach-mmp/pm-mmp2.c
new file mode 100644
index 000000000..43b1a5169
--- /dev/null
+++ b/arch/arm/mach-mmp/pm-mmp2.c
@@ -0,0 +1,250 @@
+/*
+ * MMP2 Power Management Routines
+ *
+ * This software program is licensed subject to the GNU General Public License
+ * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * (C) Copyright 2012 Marvell International Ltd.
+ * All Rights Reserved
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/suspend.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/cputype.h>
+#include <mach/addr-map.h>
+#include <mach/pm-mmp2.h>
+#include <mach/regs-icu.h>
+#include <mach/irqs.h>
+
+int mmp2_set_wake(struct irq_data *d, unsigned int on)
+{
+ unsigned long data = 0;
+ int irq = d->irq;
+
+ /* enable wakeup sources */
+ switch (irq) {
+ case IRQ_MMP2_RTC:
+ case IRQ_MMP2_RTC_ALARM:
+ data = MPMU_WUCRM_PJ_WAKEUP(4) | MPMU_WUCRM_PJ_RTC_ALARM;
+ break;
+ case IRQ_MMP2_PMIC:
+ data = MPMU_WUCRM_PJ_WAKEUP(7);
+ break;
+ case IRQ_MMP2_MMC2:
+ /* mmc use WAKEUP2, same as GPIO wakeup source */
+ data = MPMU_WUCRM_PJ_WAKEUP(2);
+ break;
+ }
+ if (on) {
+ if (data) {
+ data |= __raw_readl(MPMU_WUCRM_PJ);
+ __raw_writel(data, MPMU_WUCRM_PJ);
+ }
+ } else {
+ if (data) {
+ data = ~data & __raw_readl(MPMU_WUCRM_PJ);
+ __raw_writel(data, MPMU_WUCRM_PJ);
+ }
+ }
+ return 0;
+}
+
+static void pm_scu_clk_disable(void)
+{
+ unsigned int val;
+
+ /* close AXI fabric clock gate */
+ __raw_writel(0x0, CIU_REG(0x64));
+ __raw_writel(0x0, CIU_REG(0x68));
+
+ /* close MCB master clock gate */
+ val = __raw_readl(CIU_REG(0x1c));
+ val |= 0xf0;
+ __raw_writel(val, CIU_REG(0x1c));
+
+ return ;
+}
+
+static void pm_scu_clk_enable(void)
+{
+ unsigned int val;
+
+ /* open AXI fabric clock gate */
+ __raw_writel(0x03003003, CIU_REG(0x64));
+ __raw_writel(0x00303030, CIU_REG(0x68));
+
+ /* open MCB master clock gate */
+ val = __raw_readl(CIU_REG(0x1c));
+ val &= ~(0xf0);
+ __raw_writel(val, CIU_REG(0x1c));
+
+ return ;
+}
+
+static void pm_mpmu_clk_disable(void)
+{
+ /*
+ * disable clocks in MPMU_CGR_PJ register
+ * except clock for APMU_PLL1, APMU_PLL1_2 and AP_26M
+ */
+ __raw_writel(0x0000a010, MPMU_CGR_PJ);
+}
+
+static void pm_mpmu_clk_enable(void)
+{
+ unsigned int val;
+
+ __raw_writel(0xdffefffe, MPMU_CGR_PJ);
+ val = __raw_readl(MPMU_PLL2_CTRL1);
+ val |= (1 << 29);
+ __raw_writel(val, MPMU_PLL2_CTRL1);
+
+ return ;
+}
+
+void mmp2_pm_enter_lowpower_mode(int state)
+{
+ uint32_t idle_cfg, apcr;
+
+ idle_cfg = __raw_readl(APMU_PJ_IDLE_CFG);
+ apcr = __raw_readl(MPMU_PCR_PJ);
+ apcr &= ~(MPMU_PCR_PJ_SLPEN | MPMU_PCR_PJ_DDRCORSD | MPMU_PCR_PJ_APBSD
+ | MPMU_PCR_PJ_AXISD | MPMU_PCR_PJ_VCTCXOSD | (1 << 13));
+ idle_cfg &= ~APMU_PJ_IDLE_CFG_PJ_IDLE;
+
+ switch (state) {
+ case POWER_MODE_SYS_SLEEP:
+ apcr |= MPMU_PCR_PJ_SLPEN; /* set the SLPEN bit */
+ apcr |= MPMU_PCR_PJ_VCTCXOSD; /* set VCTCXOSD */
+ /* fall through */
+ case POWER_MODE_CHIP_SLEEP:
+ apcr |= MPMU_PCR_PJ_SLPEN;
+ /* fall through */
+ case POWER_MODE_APPS_SLEEP:
+ apcr |= MPMU_PCR_PJ_APBSD; /* set APBSD */
+ /* fall through */
+ case POWER_MODE_APPS_IDLE:
+ apcr |= MPMU_PCR_PJ_AXISD; /* set AXISDD bit */
+ apcr |= MPMU_PCR_PJ_DDRCORSD; /* set DDRCORSD bit */
+ idle_cfg |= APMU_PJ_IDLE_CFG_PJ_PWRDWN; /* PJ power down */
+ apcr |= MPMU_PCR_PJ_SPSD;
+ /* fall through */
+ case POWER_MODE_CORE_EXTIDLE:
+ idle_cfg |= APMU_PJ_IDLE_CFG_PJ_IDLE; /* set the IDLE bit */
+ idle_cfg &= ~APMU_PJ_IDLE_CFG_ISO_MODE_CNTRL_MASK;
+ idle_cfg |= APMU_PJ_IDLE_CFG_PWR_SW(3)
+ | APMU_PJ_IDLE_CFG_L2_PWR_SW;
+ break;
+ case POWER_MODE_CORE_INTIDLE:
+ apcr &= ~MPMU_PCR_PJ_SPSD;
+ break;
+ }
+
+ /* set reserve bits */
+ apcr |= (1 << 30) | (1 << 25);
+
+ /* finally write the registers back */
+ __raw_writel(idle_cfg, APMU_PJ_IDLE_CFG);
+ __raw_writel(apcr, MPMU_PCR_PJ); /* 0xfe086000 */
+}
+
+static int mmp2_pm_enter(suspend_state_t state)
+{
+ int temp;
+
+ temp = __raw_readl(MMP2_ICU_INT4_MASK);
+ if (temp & (1 << 1)) {
+ printk(KERN_ERR "%s: PMIC interrupt is handling\n", __func__);
+ return -EAGAIN;
+ }
+
+ temp = __raw_readl(APMU_SRAM_PWR_DWN);
+ temp |= ((1 << 19) | (1 << 18));
+ __raw_writel(temp, APMU_SRAM_PWR_DWN);
+ pm_mpmu_clk_disable();
+ pm_scu_clk_disable();
+
+ printk(KERN_INFO "%s: before suspend\n", __func__);
+ cpu_do_idle();
+ printk(KERN_INFO "%s: after suspend\n", __func__);
+
+ pm_mpmu_clk_enable(); /* enable clocks in MPMU */
+ pm_scu_clk_enable(); /* enable clocks in SCU */
+
+ return 0;
+}
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int mmp2_pm_prepare(void)
+{
+ mmp2_pm_enter_lowpower_mode(POWER_MODE_SYS_SLEEP);
+
+ return 0;
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+static void mmp2_pm_finish(void)
+{
+ mmp2_pm_enter_lowpower_mode(POWER_MODE_CORE_INTIDLE);
+}
+
+static int mmp2_pm_valid(suspend_state_t state)
+{
+ return ((state == PM_SUSPEND_STANDBY) || (state == PM_SUSPEND_MEM));
+}
+
+/*
+ * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
+ */
+static const struct platform_suspend_ops mmp2_pm_ops = {
+ .valid = mmp2_pm_valid,
+ .prepare = mmp2_pm_prepare,
+ .enter = mmp2_pm_enter,
+ .finish = mmp2_pm_finish,
+};
+
+static int __init mmp2_pm_init(void)
+{
+ uint32_t apcr;
+
+ if (!cpu_is_mmp2())
+ return -EIO;
+
+ suspend_set_ops(&mmp2_pm_ops);
+
+ /*
+ * Set bit 0, Slow clock Select 32K clock input instead of VCXO
+ * VCXO is chosen by default, which would be disabled in suspend
+ */
+ __raw_writel(0x5, MPMU_SCCR);
+
+ /*
+ * Clear bit 23 of CIU_CPU_CONF
+ * direct PJ4 to DDR access through Memory Controller slow queue
+ * fast queue has issue and cause lcd will flick
+ */
+ __raw_writel(__raw_readl(CIU_REG(0x8)) & ~(0x1 << 23), CIU_REG(0x8));
+
+ /* Clear default low power control bit */
+ apcr = __raw_readl(MPMU_PCR_PJ);
+ apcr &= ~(MPMU_PCR_PJ_SLPEN | MPMU_PCR_PJ_DDRCORSD
+ | MPMU_PCR_PJ_APBSD | MPMU_PCR_PJ_AXISD | 1 << 13);
+ __raw_writel(apcr, MPMU_PCR_PJ);
+
+ return 0;
+}
+
+late_initcall(mmp2_pm_init);
diff --git a/arch/arm/mach-mmp/pm-pxa910.c b/arch/arm/mach-mmp/pm-pxa910.c
new file mode 100644
index 000000000..04c9daf9f
--- /dev/null
+++ b/arch/arm/mach-mmp/pm-pxa910.c
@@ -0,0 +1,273 @@
+/*
+ * PXA910 Power Management Routines
+ *
+ * This software program is licensed subject to the GNU General Public License
+ * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * (C) Copyright 2009 Marvell International Ltd.
+ * All Rights Reserved
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/suspend.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/cputype.h>
+#include <mach/addr-map.h>
+#include <mach/pm-pxa910.h>
+#include <mach/regs-icu.h>
+#include <mach/irqs.h>
+
+int pxa910_set_wake(struct irq_data *data, unsigned int on)
+{
+ uint32_t awucrm = 0, apcr = 0;
+ int irq = data->irq;
+
+ /* setting wakeup sources */
+ switch (irq) {
+ /* wakeup line 2 */
+ case IRQ_PXA910_AP_GPIO:
+ awucrm = MPMU_AWUCRM_WAKEUP(2);
+ apcr |= MPMU_APCR_SLPWP2;
+ break;
+ /* wakeup line 3 */
+ case IRQ_PXA910_KEYPAD:
+ awucrm = MPMU_AWUCRM_WAKEUP(3) | MPMU_AWUCRM_KEYPRESS;
+ apcr |= MPMU_APCR_SLPWP3;
+ break;
+ case IRQ_PXA910_ROTARY:
+ awucrm = MPMU_AWUCRM_WAKEUP(3) | MPMU_AWUCRM_NEWROTARY;
+ apcr |= MPMU_APCR_SLPWP3;
+ break;
+ case IRQ_PXA910_TRACKBALL:
+ awucrm = MPMU_AWUCRM_WAKEUP(3) | MPMU_AWUCRM_TRACKBALL;
+ apcr |= MPMU_APCR_SLPWP3;
+ break;
+ /* wakeup line 4 */
+ case IRQ_PXA910_AP1_TIMER1:
+ awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP1_TIMER_1;
+ apcr |= MPMU_APCR_SLPWP4;
+ break;
+ case IRQ_PXA910_AP1_TIMER2:
+ awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP1_TIMER_2;
+ apcr |= MPMU_APCR_SLPWP4;
+ break;
+ case IRQ_PXA910_AP1_TIMER3:
+ awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP1_TIMER_3;
+ apcr |= MPMU_APCR_SLPWP4;
+ break;
+ case IRQ_PXA910_AP2_TIMER1:
+ awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP2_TIMER_1;
+ apcr |= MPMU_APCR_SLPWP4;
+ break;
+ case IRQ_PXA910_AP2_TIMER2:
+ awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP2_TIMER_2;
+ apcr |= MPMU_APCR_SLPWP4;
+ break;
+ case IRQ_PXA910_AP2_TIMER3:
+ awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP2_TIMER_3;
+ apcr |= MPMU_APCR_SLPWP4;
+ break;
+ case IRQ_PXA910_RTC_ALARM:
+ awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_RTC_ALARM;
+ apcr |= MPMU_APCR_SLPWP4;
+ break;
+ /* wakeup line 5 */
+ case IRQ_PXA910_USB1:
+ case IRQ_PXA910_USB2:
+ awucrm = MPMU_AWUCRM_WAKEUP(5);
+ apcr |= MPMU_APCR_SLPWP5;
+ break;
+ /* wakeup line 6 */
+ case IRQ_PXA910_MMC:
+ awucrm = MPMU_AWUCRM_WAKEUP(6)
+ | MPMU_AWUCRM_SDH1
+ | MPMU_AWUCRM_SDH2;
+ apcr |= MPMU_APCR_SLPWP6;
+ break;
+ /* wakeup line 7 */
+ case IRQ_PXA910_PMIC_INT:
+ awucrm = MPMU_AWUCRM_WAKEUP(7);
+ apcr |= MPMU_APCR_SLPWP7;
+ break;
+ default:
+ if (irq >= IRQ_GPIO_START && irq < IRQ_BOARD_START) {
+ awucrm = MPMU_AWUCRM_WAKEUP(2);
+ apcr |= MPMU_APCR_SLPWP2;
+ } else {
+ /* FIXME: This should return a proper error code ! */
+ printk(KERN_ERR "Error: no defined wake up source irq: %d\n",
+ irq);
+ }
+ }
+
+ if (on) {
+ if (awucrm) {
+ awucrm |= __raw_readl(MPMU_AWUCRM);
+ __raw_writel(awucrm, MPMU_AWUCRM);
+ }
+ if (apcr) {
+ apcr = ~apcr & __raw_readl(MPMU_APCR);
+ __raw_writel(apcr, MPMU_APCR);
+ }
+ } else {
+ if (awucrm) {
+ awucrm = ~awucrm & __raw_readl(MPMU_AWUCRM);
+ __raw_writel(awucrm, MPMU_AWUCRM);
+ }
+ if (apcr) {
+ apcr |= __raw_readl(MPMU_APCR);
+ __raw_writel(apcr, MPMU_APCR);
+ }
+ }
+ return 0;
+}
+
+void pxa910_pm_enter_lowpower_mode(int state)
+{
+ uint32_t idle_cfg, apcr;
+
+ idle_cfg = __raw_readl(APMU_MOH_IDLE_CFG);
+ apcr = __raw_readl(MPMU_APCR);
+
+ apcr &= ~(MPMU_APCR_DDRCORSD | MPMU_APCR_APBSD | MPMU_APCR_AXISD
+ | MPMU_APCR_VCTCXOSD | MPMU_APCR_STBYEN);
+ idle_cfg &= ~(APMU_MOH_IDLE_CFG_MOH_IDLE
+ | APMU_MOH_IDLE_CFG_MOH_PWRDWN);
+
+ switch (state) {
+ case POWER_MODE_UDR:
+ /* only shutdown APB in UDR */
+ apcr |= MPMU_APCR_STBYEN | MPMU_APCR_APBSD;
+ /* fall through */
+ case POWER_MODE_SYS_SLEEP:
+ apcr |= MPMU_APCR_SLPEN; /* set the SLPEN bit */
+ apcr |= MPMU_APCR_VCTCXOSD; /* set VCTCXOSD */
+ /* fall through */
+ case POWER_MODE_APPS_SLEEP:
+ apcr |= MPMU_APCR_DDRCORSD; /* set DDRCORSD */
+ /* fall through */
+ case POWER_MODE_APPS_IDLE:
+ apcr |= MPMU_APCR_AXISD; /* set AXISDD bit */
+ /* fall through */
+ case POWER_MODE_CORE_EXTIDLE:
+ idle_cfg |= APMU_MOH_IDLE_CFG_MOH_IDLE;
+ idle_cfg |= APMU_MOH_IDLE_CFG_MOH_PWRDWN;
+ idle_cfg |= APMU_MOH_IDLE_CFG_MOH_PWR_SW(3)
+ | APMU_MOH_IDLE_CFG_MOH_L2_PWR_SW(3);
+ /* fall through */
+ case POWER_MODE_CORE_INTIDLE:
+ break;
+ }
+
+ /* program the memory controller hardware sleep type and auto wakeup */
+ idle_cfg |= APMU_MOH_IDLE_CFG_MOH_DIS_MC_SW_REQ;
+ idle_cfg |= APMU_MOH_IDLE_CFG_MOH_MC_WAKE_EN;
+ __raw_writel(0x0, APMU_MC_HW_SLP_TYPE); /* auto refresh */
+
+ /* set DSPSD, DTCMSD, BBSD, MSASLPEN */
+ apcr |= MPMU_APCR_DSPSD | MPMU_APCR_DTCMSD | MPMU_APCR_BBSD
+ | MPMU_APCR_MSASLPEN;
+
+ /*always set SLEPEN bit mainly for MSA*/
+ apcr |= MPMU_APCR_SLPEN;
+
+ /* finally write the registers back */
+ __raw_writel(idle_cfg, APMU_MOH_IDLE_CFG);
+ __raw_writel(apcr, MPMU_APCR);
+
+}
+
+static int pxa910_pm_enter(suspend_state_t state)
+{
+ unsigned int idle_cfg, reg = 0;
+
+ /*pmic thread not completed,exit;otherwise system can't be waked up*/
+ reg = __raw_readl(ICU_INT_CONF(IRQ_PXA910_PMIC_INT));
+ if ((reg & 0x3) == 0)
+ return -EAGAIN;
+
+ idle_cfg = __raw_readl(APMU_MOH_IDLE_CFG);
+ idle_cfg |= APMU_MOH_IDLE_CFG_MOH_PWRDWN
+ | APMU_MOH_IDLE_CFG_MOH_SRAM_PWRDWN;
+ __raw_writel(idle_cfg, APMU_MOH_IDLE_CFG);
+
+ /* disable L2 */
+ outer_disable();
+ /* wait for l2 idle */
+ while (!(readl(CIU_REG(0x8)) & (1 << 16)))
+ udelay(1);
+
+ cpu_do_idle();
+
+ /* enable L2 */
+ outer_resume();
+ /* wait for l2 idle */
+ while (!(readl(CIU_REG(0x8)) & (1 << 16)))
+ udelay(1);
+
+ idle_cfg = __raw_readl(APMU_MOH_IDLE_CFG);
+ idle_cfg &= ~(APMU_MOH_IDLE_CFG_MOH_PWRDWN
+ | APMU_MOH_IDLE_CFG_MOH_SRAM_PWRDWN);
+ __raw_writel(idle_cfg, APMU_MOH_IDLE_CFG);
+
+ return 0;
+}
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int pxa910_pm_prepare(void)
+{
+ pxa910_pm_enter_lowpower_mode(POWER_MODE_UDR);
+ return 0;
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+static void pxa910_pm_finish(void)
+{
+ pxa910_pm_enter_lowpower_mode(POWER_MODE_CORE_INTIDLE);
+}
+
+static int pxa910_pm_valid(suspend_state_t state)
+{
+ return ((state == PM_SUSPEND_STANDBY) || (state == PM_SUSPEND_MEM));
+}
+
+static const struct platform_suspend_ops pxa910_pm_ops = {
+ .valid = pxa910_pm_valid,
+ .prepare = pxa910_pm_prepare,
+ .enter = pxa910_pm_enter,
+ .finish = pxa910_pm_finish,
+};
+
+static int __init pxa910_pm_init(void)
+{
+ uint32_t awucrm = 0;
+
+ if (!cpu_is_pxa910())
+ return -EIO;
+
+ suspend_set_ops(&pxa910_pm_ops);
+
+ /* Set the following bits for MMP3 playback with VCTXO on */
+ __raw_writel(__raw_readl(APMU_SQU_CLK_GATE_CTRL) | (1 << 30),
+ APMU_SQU_CLK_GATE_CTRL);
+ __raw_writel(__raw_readl(MPMU_FCCR) | (1 << 28), MPMU_FCCR);
+
+ awucrm |= MPMU_AWUCRM_AP_ASYNC_INT | MPMU_AWUCRM_AP_FULL_IDLE;
+ __raw_writel(awucrm, MPMU_AWUCRM);
+
+ return 0;
+}
+
+late_initcall(pxa910_pm_init);
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
new file mode 100644
index 000000000..144e99762
--- /dev/null
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -0,0 +1,178 @@
+/*
+ * 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 <linux/platform_device.h>
+#include <linux/platform_data/mv_usb.h>
+
+#include <asm/mach/time.h>
+#include <asm/system_misc.h>
+#include <mach/cputype.h>
+#include <mach/addr-map.h>
+#include <mach/regs-apbc.h>
+#include <mach/regs-apmu.h>
+#include <mach/irqs.h>
+#include <mach/dma.h>
+#include <mach/devices.h>
+#include <mach/mfp.h>
+#include <linux/dma-mapping.h>
+#include <mach/pxa168.h>
+#include <mach/regs-usb.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,
+};
+
+void __init pxa168_init_irq(void)
+{
+ icu_init_irq();
+}
+
+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);
+ pxa168_clk_init();
+ }
+
+ return 0;
+}
+postcore_initcall(pxa168_init);
+
+/* system timer - clock enabled, 3.25MHz */
+#define TIMER_CLK_RST (APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(3))
+#define APBC_TIMERS APBC_REG(0x34)
+
+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_TIMERS);
+
+ /* 3.25MHz, bus/functional clock enabled, release reset */
+ __raw_writel(TIMER_CLK_RST, APBC_TIMERS);
+
+ timer_init(IRQ_PXA168_TIMER1);
+}
+
+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(uart3, "pxa2xx-uart", 2, UART3, 0xd4026000, 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);
+PXA168_DEVICE(eth, "pxa168-eth", -1, MFU, 0xc0800000, 0x0fff);
+
+struct resource pxa168_resource_gpio[] = {
+ {
+ .start = 0xd4019000,
+ .end = 0xd4019fff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_PXA168_GPIOX,
+ .end = IRQ_PXA168_GPIOX,
+ .name = "gpio_mux",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa168_device_gpio = {
+ .name = "mmp-gpio",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pxa168_resource_gpio),
+ .resource = pxa168_resource_gpio,
+};
+
+struct resource pxa168_usb_host_resources[] = {
+ /* USB Host conroller register base */
+ [0] = {
+ .start = PXA168_U2H_REGBASE + U2x_CAPREGS_OFFSET,
+ .end = PXA168_U2H_REGBASE + USB_REG_RANGE,
+ .flags = IORESOURCE_MEM,
+ .name = "capregs",
+ },
+ /* USB PHY register base */
+ [1] = {
+ .start = PXA168_U2H_PHYBASE,
+ .end = PXA168_U2H_PHYBASE + USB_PHY_RANGE,
+ .flags = IORESOURCE_MEM,
+ .name = "phyregs",
+ },
+ [2] = {
+ .start = IRQ_PXA168_USB2,
+ .end = IRQ_PXA168_USB2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 pxa168_usb_host_dmamask = DMA_BIT_MASK(32);
+struct platform_device pxa168_device_usb_host = {
+ .name = "pxa-sph",
+ .id = -1,
+ .dev = {
+ .dma_mask = &pxa168_usb_host_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+
+ .num_resources = ARRAY_SIZE(pxa168_usb_host_resources),
+ .resource = pxa168_usb_host_resources,
+};
+
+int __init pxa168_add_usb_host(struct mv_usb_platform_data *pdata)
+{
+ pxa168_device_usb_host.dev.platform_data = pdata;
+ return platform_device_register(&pxa168_device_usb_host);
+}
+
+void pxa168_restart(enum reboot_mode mode, const char *cmd)
+{
+ soft_restart(0xffff0000);
+}
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
new file mode 100644
index 000000000..eb57ee196
--- /dev/null
+++ b/arch/arm/mach-mmp/pxa910.c
@@ -0,0 +1,191 @@
+/*
+ * 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 <linux/irq.h>
+#include <linux/irqchip/mmp.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware/cache-tauros2.h>
+#include <asm/mach/time.h>
+#include <mach/addr-map.h>
+#include <mach/regs-apbc.h>
+#include <mach/cputype.h>
+#include <mach/irqs.h>
+#include <mach/dma.h>
+#include <mach/mfp.h>
+#include <mach/devices.h>
+#include <mach/pm-pxa910.h>
+#include <mach/pxa910.h>
+
+#include "common.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,
+};
+
+void __init pxa910_init_irq(void)
+{
+ icu_init_irq();
+#ifdef CONFIG_PM
+ icu_irq_chip.irq_set_wake = pxa910_set_wake;
+#endif
+}
+
+static int __init pxa910_init(void)
+{
+ if (cpu_is_pxa910()) {
+#ifdef CONFIG_CACHE_TAUROS2
+ tauros2_init(0);
+#endif
+ mfp_init_base(MFPR_VIRT_BASE);
+ mfp_init_addr(pxa910_mfp_addr_map);
+ pxa_init_dma(IRQ_PXA910_DMA_INT0, 32);
+ pxa910_clk_init();
+ }
+
+ return 0;
+}
+postcore_initcall(pxa910_init);
+
+/* system timer - clock enabled, 3.25MHz */
+#define TIMER_CLK_RST (APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(3))
+#define APBC_TIMERS APBC_REG(0x34)
+
+void __init pxa910_timer_init(void)
+{
+ /* reset and configure */
+ __raw_writel(APBC_APBCLK | APBC_RST, APBC_TIMERS);
+ __raw_writel(TIMER_CLK_RST, APBC_TIMERS);
+
+ timer_init(IRQ_PXA910_AP1_TIMER1);
+}
+
+/* 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);
+PXA910_DEVICE(disp, "mmp-disp", 0, LCD, 0xd420b000, 0x1ec);
+PXA910_DEVICE(fb, "mmp-fb", -1, NONE, 0, 0);
+PXA910_DEVICE(panel, "tpo-hvga", -1, NONE, 0, 0);
+
+struct resource pxa910_resource_gpio[] = {
+ {
+ .start = 0xd4019000,
+ .end = 0xd4019fff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_PXA910_AP_GPIO,
+ .end = IRQ_PXA910_AP_GPIO,
+ .name = "gpio_mux",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa910_device_gpio = {
+ .name = "mmp-gpio",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pxa910_resource_gpio),
+ .resource = pxa910_resource_gpio,
+};
+
+static struct resource pxa910_resource_rtc[] = {
+ {
+ .start = 0xd4010000,
+ .end = 0xd401003f,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_PXA910_RTC_INT,
+ .end = IRQ_PXA910_RTC_INT,
+ .name = "rtc 1Hz",
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = IRQ_PXA910_RTC_ALARM,
+ .end = IRQ_PXA910_RTC_ALARM,
+ .name = "rtc alarm",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa910_device_rtc = {
+ .name = "sa1100-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pxa910_resource_rtc),
+ .resource = pxa910_resource_rtc,
+};
diff --git a/arch/arm/mach-mmp/sram.c b/arch/arm/mach-mmp/sram.c
new file mode 100644
index 000000000..bf5e64906
--- /dev/null
+++ b/arch/arm/mach-mmp/sram.c
@@ -0,0 +1,168 @@
+/*
+ * linux/arch/arm/mach-mmp/sram.c
+ *
+ * based on mach-davinci/sram.c - DaVinci simple SRAM allocator
+ *
+ * Copyright (c) 2011 Marvell Semiconductors Inc.
+ * All Rights Reserved
+ *
+ * Add for mmp sram support - Leo Yan <leoy@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
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/genalloc.h>
+
+#include <linux/platform_data/dma-mmp_tdma.h>
+
+struct sram_bank_info {
+ char *pool_name;
+ struct gen_pool *gpool;
+ int granularity;
+
+ phys_addr_t sram_phys;
+ void __iomem *sram_virt;
+ u32 sram_size;
+
+ struct list_head node;
+};
+
+static DEFINE_MUTEX(sram_lock);
+static LIST_HEAD(sram_bank_list);
+
+struct gen_pool *sram_get_gpool(char *pool_name)
+{
+ struct sram_bank_info *info = NULL;
+
+ if (!pool_name)
+ return NULL;
+
+ mutex_lock(&sram_lock);
+
+ list_for_each_entry(info, &sram_bank_list, node)
+ if (!strcmp(pool_name, info->pool_name))
+ break;
+
+ mutex_unlock(&sram_lock);
+
+ if (&info->node == &sram_bank_list)
+ return NULL;
+
+ return info->gpool;
+}
+EXPORT_SYMBOL(sram_get_gpool);
+
+static int sram_probe(struct platform_device *pdev)
+{
+ struct sram_platdata *pdata = pdev->dev.platform_data;
+ struct sram_bank_info *info;
+ struct resource *res;
+ int ret = 0;
+
+ if (!pdata || !pdata->pool_name)
+ return -ENODEV;
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no memory resource defined\n");
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (!resource_size(res))
+ return 0;
+
+ info->sram_phys = (phys_addr_t)res->start;
+ info->sram_size = resource_size(res);
+ info->sram_virt = ioremap(info->sram_phys, info->sram_size);
+ info->pool_name = kstrdup(pdata->pool_name, GFP_KERNEL);
+ info->granularity = pdata->granularity;
+
+ info->gpool = gen_pool_create(ilog2(info->granularity), -1);
+ if (!info->gpool) {
+ dev_err(&pdev->dev, "create pool failed\n");
+ ret = -ENOMEM;
+ goto create_pool_err;
+ }
+
+ ret = gen_pool_add_virt(info->gpool, (unsigned long)info->sram_virt,
+ info->sram_phys, info->sram_size, -1);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "add new chunk failed\n");
+ ret = -ENOMEM;
+ goto add_chunk_err;
+ }
+
+ mutex_lock(&sram_lock);
+ list_add(&info->node, &sram_bank_list);
+ mutex_unlock(&sram_lock);
+
+ platform_set_drvdata(pdev, info);
+
+ dev_info(&pdev->dev, "initialized\n");
+ return 0;
+
+add_chunk_err:
+ gen_pool_destroy(info->gpool);
+create_pool_err:
+ iounmap(info->sram_virt);
+ kfree(info->pool_name);
+out:
+ kfree(info);
+ return ret;
+}
+
+static int sram_remove(struct platform_device *pdev)
+{
+ struct sram_bank_info *info;
+
+ info = platform_get_drvdata(pdev);
+ if (info == NULL)
+ return -ENODEV;
+
+ mutex_lock(&sram_lock);
+ list_del(&info->node);
+ mutex_unlock(&sram_lock);
+
+ gen_pool_destroy(info->gpool);
+ iounmap(info->sram_virt);
+ kfree(info->pool_name);
+ kfree(info);
+ return 0;
+}
+
+static const struct platform_device_id sram_id_table[] = {
+ { "asram", MMP_ASRAM },
+ { "isram", MMP_ISRAM },
+ { }
+};
+
+static struct platform_driver sram_driver = {
+ .probe = sram_probe,
+ .remove = sram_remove,
+ .driver = {
+ .name = "mmp-sram",
+ },
+ .id_table = sram_id_table,
+};
+
+static int __init sram_init(void)
+{
+ return platform_driver_register(&sram_driver);
+}
+core_initcall(sram_init);
+
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
new file mode 100644
index 000000000..cdfc9bfee
--- /dev/null
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -0,0 +1,116 @@
+/*
+ * 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/gpio.h>
+#include <linux/gpio-pxa.h>
+#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/irqs.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 pxa_gpio_platform_data pxa910_gpio_pdata = {
+ .irq_base = MMP_GPIO_TO_IRQ(0),
+};
+
+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 = MMP_GPIO_TO_IRQ(80),
+ .end = MMP_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);
+ platform_device_add_data(&pxa910_device_gpio, &pxa910_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
+ platform_device_register(&pxa910_device_gpio);
+
+ /* off-chip devices */
+ platform_device_register(&smc91x_device);
+}
+
+MACHINE_START(TAVOREVB, "PXA910 Evaluation Board (aka TavorEVB)")
+ .map_io = mmp_map_io,
+ .nr_irqs = MMP_NR_IRQS,
+ .init_irq = pxa910_init_irq,
+ .init_time = pxa910_timer_init,
+ .init_machine = tavorevb_init,
+ .restart = mmp_restart,
+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 000000000..6aa53fb29
--- /dev/null
+++ b/arch/arm/mach-mmp/teton_bga.c
@@ -0,0 +1,103 @@
+/*
+ * 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/gpio-pxa.h>
+#include <linux/input.h>
+#include <linux/platform_data/keypad-pxa27x.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 <mach/irqs.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 struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+ .irq_base = MMP_GPIO_TO_IRQ(0),
+};
+
+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 matrix_keymap_data teton_bga_matrix_keymap_data = {
+ .keymap = teton_bga_matrix_key_map,
+ .keymap_size = ARRAY_SIZE(teton_bga_matrix_key_map),
+};
+
+static struct pxa27x_keypad_platform_data teton_bga_keypad_info __initdata = {
+ .matrix_key_rows = 2,
+ .matrix_key_cols = 8,
+ .matrix_keymap_data = &teton_bga_matrix_keymap_data,
+ .debounce_interval = 30,
+};
+
+static struct i2c_board_info teton_bga_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("ds1337", 0x68),
+ .irq = MMP_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));
+ platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
+ platform_device_register(&pxa168_device_gpio);
+}
+
+MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform")
+ .map_io = mmp_map_io,
+ .nr_irqs = MMP_NR_IRQS,
+ .init_irq = pxa168_init_irq,
+ .init_time = pxa168_timer_init,
+ .init_machine = teton_bga_init,
+ .restart = pxa168_restart,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
new file mode 100644
index 000000000..10bfa03e5
--- /dev/null
+++ b/arch/arm/mach-mmp/time.c
@@ -0,0 +1,247 @@
+/*
+ * 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/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/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"
+
+#ifdef CONFIG_CPU_MMP2
+#define MMP_CLOCK_FREQ 6500000
+#else
+#define MMP_CLOCK_FREQ 3250000
+#endif
+
+#define TIMERS_VIRT_BASE TIMERS1_VIRT_BASE
+
+#define MAX_DELTA (0xfffffffe)
+#define MIN_DELTA (16)
+
+static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE;
+
+/*
+ * FIXME: the timer needs some delay to stablize the counter capture
+ */
+static inline uint32_t timer_read(void)
+{
+ int delay = 100;
+
+ __raw_writel(1, mmp_timer_base + TMR_CVWR(1));
+
+ while (delay--)
+ cpu_relax();
+
+ return __raw_readl(mmp_timer_base + TMR_CVWR(1));
+}
+
+static u64 notrace mmp_read_sched_clock(void)
+{
+ return timer_read();
+}
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *c = dev_id;
+
+ /*
+ * Clear pending interrupt status.
+ */
+ __raw_writel(0x01, mmp_timer_base + TMR_ICR(0));
+
+ /*
+ * Disable timer 0.
+ */
+ __raw_writel(0x02, mmp_timer_base + TMR_CER);
+
+ c->event_handler(c);
+
+ return IRQ_HANDLED;
+}
+
+static int timer_set_next_event(unsigned long delta,
+ struct clock_event_device *dev)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ /*
+ * Disable timer 0.
+ */
+ __raw_writel(0x02, mmp_timer_base + TMR_CER);
+
+ /*
+ * Clear and enable timer match 0 interrupt.
+ */
+ __raw_writel(0x01, mmp_timer_base + TMR_ICR(0));
+ __raw_writel(0x01, mmp_timer_base + TMR_IER(0));
+
+ /*
+ * Setup new clockevent timer value.
+ */
+ __raw_writel(delta - 1, mmp_timer_base + TMR_TN_MM(0, 0));
+
+ /*
+ * Enable timer 0.
+ */
+ __raw_writel(0x03, mmp_timer_base + TMR_CER);
+
+ 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, mmp_timer_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,
+ .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(mmp_timer_base + TMR_CCR);
+
+ __raw_writel(0x0, mmp_timer_base + TMR_CER); /* disable */
+
+ ccr &= (cpu_is_mmp2()) ? (TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) :
+ (TMR_CCR_CS_0(3) | TMR_CCR_CS_1(3));
+ __raw_writel(ccr, mmp_timer_base + TMR_CCR);
+
+ /* set timer 0 to periodic mode, and timer 1 to free-running mode */
+ __raw_writel(0x2, mmp_timer_base + TMR_CMR);
+
+ __raw_writel(0x1, mmp_timer_base + TMR_PLCR(0)); /* periodic */
+ __raw_writel(0x7, mmp_timer_base + TMR_ICR(0)); /* clear status */
+ __raw_writel(0x0, mmp_timer_base + TMR_IER(0));
+
+ __raw_writel(0x0, mmp_timer_base + TMR_PLCR(1)); /* free-running */
+ __raw_writel(0x7, mmp_timer_base + TMR_ICR(1)); /* clear status */
+ __raw_writel(0x0, mmp_timer_base + TMR_IER(1));
+
+ /* enable timer 1 counter */
+ __raw_writel(0x2, mmp_timer_base + TMR_CER);
+}
+
+static struct irqaction timer_irq = {
+ .name = "timer",
+ .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = timer_interrupt,
+ .dev_id = &ckevt,
+};
+
+void __init timer_init(int irq)
+{
+ timer_config();
+
+ sched_clock_register(mmp_read_sched_clock, 32, MMP_CLOCK_FREQ);
+
+ ckevt.cpumask = cpumask_of(0);
+
+ setup_irq(irq, &timer_irq);
+
+ clocksource_register_hz(&cksrc, MMP_CLOCK_FREQ);
+ clockevents_config_and_register(&ckevt, MMP_CLOCK_FREQ,
+ MIN_DELTA, MAX_DELTA);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id mmp_timer_dt_ids[] = {
+ { .compatible = "mrvl,mmp-timer", },
+ {}
+};
+
+void __init mmp_dt_init_timer(void)
+{
+ struct device_node *np;
+ int irq, ret;
+
+ np = of_find_matching_node(NULL, mmp_timer_dt_ids);
+ if (!np) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq) {
+ ret = -EINVAL;
+ goto out;
+ }
+ mmp_timer_base = of_iomap(np, 0);
+ if (!mmp_timer_base) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ timer_init(irq);
+ return;
+out:
+ pr_err("Failed to get timer from device tree with error:%d\n", ret);
+}
+#endif
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
new file mode 100644
index 000000000..ac4af81de
--- /dev/null
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -0,0 +1,315 @@
+/*
+ * 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 <linux/platform_data/pca953x.h>
+#include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
+#include <linux/mfd/88pm860x.h>
+#include <linux/platform_data/mv_usb.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.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 <mach/irqs.h>
+#include <mach/regs-usb.h>
+
+#include "common.h"
+
+#define TTCDKB_GPIO_EXT0(x) (MMP_NR_BUILTIN_GPIO + ((x < 0) ? 0 : \
+ ((x < 16) ? x : 15)))
+#define TTCDKB_GPIO_EXT1(x) (MMP_NR_BUILTIN_GPIO + 16 + ((x < 0) ? 0 : \
+ ((x < 16) ? x : 15)))
+
+/*
+ * 16 board interrupts -- MAX7312 GPIO expander
+ * 16 board interrupts -- PCA9575 GPIO expander
+ * 24 board interrupts -- 88PM860x PMIC
+ */
+#define TTCDKB_NR_IRQS (MMP_NR_IRQS + 16 + 16 + 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 pxa_gpio_platform_data pxa910_gpio_pdata = {
+ .irq_base = MMP_GPIO_TO_IRQ(0),
+};
+
+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_32M + SZ_16M,
+ .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[] = {
+ &pxa910_device_gpio,
+ &pxa910_device_rtc,
+ &ttc_dkb_device_onenand,
+};
+
+static struct pca953x_platform_data max7312_data[] = {
+ {
+ .gpio_base = TTCDKB_GPIO_EXT0(0),
+ .irq_base = MMP_NR_IRQS,
+ },
+};
+
+static struct pm860x_platform_data ttc_dkb_pm8607_info = {
+ .irq_base = IRQ_BOARD_START,
+};
+
+static struct i2c_board_info ttc_dkb_i2c_info[] = {
+ {
+ .type = "88PM860x",
+ .addr = 0x34,
+ .platform_data = &ttc_dkb_pm8607_info,
+ .irq = IRQ_PXA910_PMIC_INT,
+ },
+ {
+ .type = "max7312",
+ .addr = 0x23,
+ .irq = MMP_GPIO_TO_IRQ(80),
+ .platform_data = &max7312_data,
+ },
+};
+
+#if IS_ENABLED(CONFIG_USB_SUPPORT)
+#if IS_ENABLED(CONFIG_USB_MV_UDC) || IS_ENABLED(CONFIG_USB_EHCI_MV_U2O)
+
+static struct mv_usb_platform_data ttc_usb_pdata = {
+ .vbus = NULL,
+ .mode = MV_USB_MODE_OTG,
+ .otg_force_a_bus_req = 1,
+ .phy_init = pxa_usb_phy_init,
+ .phy_deinit = pxa_usb_phy_deinit,
+ .set_vbus = NULL,
+};
+#endif
+#endif
+
+#if IS_ENABLED(CONFIG_MTD_NAND_PXA3xx)
+static struct pxa3xx_nand_platform_data dkb_nand_info = {
+ .enable_arbiter = 1,
+ .num_cs = 1,
+};
+#endif
+
+#if IS_ENABLED(CONFIG_MMP_DISP)
+/* path config */
+#define CFG_IOPADMODE(iopad) (iopad) /* 0x0 ~ 0xd */
+#define SCLK_SOURCE_SELECT(x) (x << 30) /* 0x0 ~ 0x3 */
+/* link config */
+#define CFG_DUMBMODE(mode) (mode << 28) /* 0x0 ~ 0x6*/
+static struct mmp_mach_path_config dkb_disp_config[] = {
+ [0] = {
+ .name = "mmp-parallel",
+ .overlay_num = 2,
+ .output_type = PATH_OUT_PARALLEL,
+ .path_config = CFG_IOPADMODE(0x1)
+ | SCLK_SOURCE_SELECT(0x1),
+ .link_config = CFG_DUMBMODE(0x2),
+ },
+};
+
+static struct mmp_mach_plat_info dkb_disp_info = {
+ .name = "mmp-disp",
+ .clk_name = "disp0",
+ .path_num = 1,
+ .paths = dkb_disp_config,
+};
+
+static struct mmp_buffer_driver_mach_info dkb_fb_info = {
+ .name = "mmp-fb",
+ .path_name = "mmp-parallel",
+ .overlay_id = 0,
+ .dmafetch_id = 1,
+ .default_pixfmt = PIXFMT_RGB565,
+};
+
+static void dkb_tpo_panel_power(int on)
+{
+ int err;
+ u32 spi_reset = mfp_to_gpio(MFP_PIN_GPIO106);
+
+ if (on) {
+ err = gpio_request(spi_reset, "TPO_LCD_SPI_RESET");
+ if (err) {
+ pr_err("failed to request GPIO for TPO LCD RESET\n");
+ return;
+ }
+ gpio_direction_output(spi_reset, 0);
+ udelay(100);
+ gpio_set_value(spi_reset, 1);
+ gpio_free(spi_reset);
+ } else {
+ err = gpio_request(spi_reset, "TPO_LCD_SPI_RESET");
+ if (err) {
+ pr_err("failed to request LCD RESET gpio\n");
+ return;
+ }
+ gpio_set_value(spi_reset, 0);
+ gpio_free(spi_reset);
+ }
+}
+
+static struct mmp_mach_panel_info dkb_tpo_panel_info = {
+ .name = "tpo-hvga",
+ .plat_path_name = "mmp-parallel",
+ .plat_set_onoff = dkb_tpo_panel_power,
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "tpo-hvga",
+ .platform_data = &dkb_tpo_panel_info,
+ .bus_num = 5,
+ }
+};
+
+static void __init add_disp(void)
+{
+ pxa_register_device(&pxa910_device_disp,
+ &dkb_disp_info, sizeof(dkb_disp_info));
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+ pxa_register_device(&pxa910_device_fb,
+ &dkb_fb_info, sizeof(dkb_fb_info));
+ pxa_register_device(&pxa910_device_panel,
+ &dkb_tpo_panel_info, sizeof(dkb_tpo_panel_info));
+}
+#endif
+
+static void __init ttc_dkb_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(ttc_dkb_pin_config));
+
+ /* on-chip devices */
+ pxa910_add_uart(1);
+#if IS_ENABLED(CONFIG_MTD_NAND_PXA3xx)
+ pxa910_add_nand(&dkb_nand_info);
+#endif
+
+ /* off-chip devices */
+ pxa910_add_twsi(0, NULL, ARRAY_AND_SIZE(ttc_dkb_i2c_info));
+ platform_device_add_data(&pxa910_device_gpio, &pxa910_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
+ platform_add_devices(ARRAY_AND_SIZE(ttc_dkb_devices));
+
+#if IS_ENABLED(CONFIG_USB_MV_UDC)
+ pxa168_device_u2o.dev.platform_data = &ttc_usb_pdata;
+ platform_device_register(&pxa168_device_u2o);
+#endif
+
+#if IS_ENABLED(CONFIG_USB_EHCI_MV_U2O)
+ pxa168_device_u2oehci.dev.platform_data = &ttc_usb_pdata;
+ platform_device_register(&pxa168_device_u2oehci);
+#endif
+
+#if IS_ENABLED(CONFIG_USB_MV_OTG)
+ pxa168_device_u2ootg.dev.platform_data = &ttc_usb_pdata;
+ platform_device_register(&pxa168_device_u2ootg);
+#endif
+
+#if IS_ENABLED(CONFIG_MMP_DISP)
+ add_disp();
+#endif
+}
+
+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,
+ .init_time = pxa910_timer_init,
+ .init_machine = ttc_dkb_init,
+ .restart = mmp_restart,
+MACHINE_END
diff --git a/arch/arm/mach-moxart/Kconfig b/arch/arm/mach-moxart/Kconfig
new file mode 100644
index 000000000..f49328c39
--- /dev/null
+++ b/arch/arm/mach-moxart/Kconfig
@@ -0,0 +1,25 @@
+menuconfig ARCH_MOXART
+ bool "MOXA ART SoC" if ARCH_MULTI_V4
+ select CPU_FA526
+ select ARM_DMA_MEM_BUFFERABLE
+ select CLKSRC_MMIO
+ select GENERIC_IRQ_CHIP
+ select ARCH_REQUIRE_GPIOLIB
+ select PHYLIB if NETDEVICES
+ help
+ Say Y here if you want to run your kernel on hardware with a
+ MOXA ART SoC.
+ The MOXA ART SoC is based on a Faraday FA526 ARMv4 32-bit
+ 192 MHz CPU with MMU and 16KB/8KB D/I-cache (UC-7112-LX).
+ Used on models UC-7101, UC-7112/UC-7110, IA240/IA241, IA3341.
+
+if ARCH_MOXART
+
+config MACH_UC7112LX
+ bool "MOXA UC-7112-LX"
+ depends on ARCH_MOXART
+ help
+ Say Y here if you intend to run this kernel on a MOXA
+ UC-7112-LX embedded computer.
+
+endif
diff --git a/arch/arm/mach-moxart/Makefile b/arch/arm/mach-moxart/Makefile
new file mode 100644
index 000000000..fa022eb10
--- /dev/null
+++ b/arch/arm/mach-moxart/Makefile
@@ -0,0 +1,3 @@
+# Object file lists.
+
+obj-$(CONFIG_MACH_UC7112LX) += moxart.o
diff --git a/arch/arm/mach-moxart/moxart.c b/arch/arm/mach-moxart/moxart.c
new file mode 100644
index 000000000..86b6d9b57
--- /dev/null
+++ b/arch/arm/mach-moxart/moxart.c
@@ -0,0 +1,15 @@
+/*
+ * arch/arm/mach-moxart/moxart.c
+ *
+ * (C) Copyright 2013, Jonas Jensen <jonas.jensen@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.
+ */
diff --git a/arch/arm/mach-mv78xx0/Kconfig b/arch/arm/mach-mv78xx0/Kconfig
new file mode 100644
index 000000000..f2d309d06
--- /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 000000000..7cd04634d
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/Makefile
@@ -0,0 +1,4 @@
+obj-y += common.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 000000000..760a0efe7
--- /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/buffalo-wxl-setup.c b/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
new file mode 100644
index 000000000..1f2ef98b3
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
@@ -0,0 +1,155 @@
+/*
+ * 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> */
+ .atag_offset = 0x100,
+ .init_machine = wxl_init,
+ .map_io = mv78xx0_map_io,
+ .init_early = mv78xx0_init_early,
+ .init_irq = mv78xx0_init_irq,
+ .init_time = mv78xx0_timer_init,
+ .restart = mv78xx0_restart,
+MACHINE_END
diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c
new file mode 100644
index 000000000..e6ac679be
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/common.c
@@ -0,0 +1,430 @@
+/*
+ * 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/ata_platform.h>
+#include <linux/clk-provider.h>
+#include <linux/ethtool.h>
+#include <asm/hardware/cache-feroceon-l2.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <mach/mv78xx0.h>
+#include <mach/bridge-regs.h>
+#include <linux/platform_data/usb-ehci-orion.h>
+#include <linux/platform_data/mtd-orion_nand.h>
+#include <plat/time.h>
+#include <plat/common.h>
+#include <plat/addr-map.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_freq;
+
+ /*
+ * TCLK tick rate is configured by DEV_A[2:0] strap pins.
+ */
+ switch ((readl(SAMPLE_AT_RESET_HIGH) >> 6) & 7) {
+ case 1:
+ tclk_freq = 166666667;
+ break;
+ case 3:
+ tclk_freq = 200000000;
+ break;
+ default:
+ panic("unknown TCLK PLL setting: %.8x\n",
+ readl(SAMPLE_AT_RESET_HIGH));
+ }
+
+ return tclk_freq;
+}
+
+
+/*****************************************************************************
+ * I/O Address Mapping
+ ****************************************************************************/
+static struct map_desc mv78xx0_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long) MV78XX0_CORE_REGS_VIRT_BASE,
+ .pfn = 0,
+ .length = MV78XX0_CORE_REGS_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long) 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));
+}
+
+
+/*****************************************************************************
+ * CLK tree
+ ****************************************************************************/
+static struct clk *tclk;
+
+static void __init clk_init(void)
+{
+ tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT,
+ get_tclk());
+
+ orion_clkdev_init(tclk);
+}
+
+/*****************************************************************************
+ * EHCI
+ ****************************************************************************/
+void __init mv78xx0_ehci0_init(void)
+{
+ orion_ehci_init(USB0_PHYS_BASE, IRQ_MV78XX0_USB_0, EHCI_PHY_NA);
+}
+
+
+/*****************************************************************************
+ * EHCI1
+ ****************************************************************************/
+void __init mv78xx0_ehci1_init(void)
+{
+ orion_ehci_1_init(USB1_PHYS_BASE, IRQ_MV78XX0_USB_1);
+}
+
+
+/*****************************************************************************
+ * EHCI2
+ ****************************************************************************/
+void __init mv78xx0_ehci2_init(void)
+{
+ orion_ehci_2_init(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,
+ GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM,
+ IRQ_MV78XX0_GE_ERR,
+ MV643XX_TX_CSUM_DEFAULT_LIMIT);
+}
+
+
+/*****************************************************************************
+ * GE01
+ ****************************************************************************/
+void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
+{
+ orion_ge01_init(eth_data,
+ GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM,
+ NO_IRQ,
+ MV643XX_TX_CSUM_DEFAULT_LIMIT);
+}
+
+
+/*****************************************************************************
+ * 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,
+ GE10_PHYS_BASE, IRQ_MV78XX0_GE10_SUM,
+ NO_IRQ);
+}
+
+
+/*****************************************************************************
+ * 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,
+ GE11_PHYS_BASE, IRQ_MV78XX0_GE11_SUM,
+ NO_IRQ);
+}
+
+/*****************************************************************************
+ * 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, 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, tclk);
+}
+
+
+/*****************************************************************************
+ * UART1
+ ****************************************************************************/
+void __init mv78xx0_uart1_init(void)
+{
+ orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
+ IRQ_MV78XX0_UART_1, tclk);
+}
+
+
+/*****************************************************************************
+ * UART2
+ ****************************************************************************/
+void __init mv78xx0_uart2_init(void)
+{
+ orion_uart2_init(UART2_VIRT_BASE, UART2_PHYS_BASE,
+ IRQ_MV78XX0_UART_2, tclk);
+}
+
+/*****************************************************************************
+ * UART3
+ ****************************************************************************/
+void __init mv78xx0_uart3_init(void)
+{
+ orion_uart3_init(UART3_VIRT_BASE, UART3_PHYS_BASE,
+ IRQ_MV78XX0_UART_3, tclk);
+}
+
+/*****************************************************************************
+ * Time handling
+ ****************************************************************************/
+void __init mv78xx0_init_early(void)
+{
+ orion_time_set_base(TIMER_VIRT_BASE);
+ if (mv78xx0_core_index() == 0)
+ mvebu_mbus_init("marvell,mv78xx0-mbus",
+ BRIDGE_WINS_CPU0_BASE, BRIDGE_WINS_SZ,
+ DDR_WINDOW_CPU0_BASE, DDR_WINDOW_CPU_SZ);
+ else
+ mvebu_mbus_init("marvell,mv78xx0-mbus",
+ BRIDGE_WINS_CPU1_BASE, BRIDGE_WINS_SZ,
+ DDR_WINDOW_CPU1_BASE, DDR_WINDOW_CPU_SZ);
+}
+
+void __init_refok mv78xx0_timer_init(void)
+{
+ orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
+ IRQ_MV78XX0_TIMER_1, get_tclk());
+}
+
+
+/*****************************************************************************
+ * 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;
+
+ core_index = mv78xx0_core_index();
+ hclk = get_hclk();
+ get_pclk_l2clk(hclk, core_index, &pclk, &l2clk);
+
+ 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", (get_tclk() + 499999) / 1000000);
+
+#ifdef CONFIG_CACHE_FEROCEON_L2
+ feroceon_l2_init(is_l2_writethrough());
+#endif
+
+ /* Setup root of clk tree */
+ clk_init();
+}
+
+void mv78xx0_restart(enum reboot_mode 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)
+ ;
+}
diff --git a/arch/arm/mach-mv78xx0/common.h b/arch/arm/mach-mv78xx0/common.h
new file mode 100644
index 000000000..6889af260
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/common.h
@@ -0,0 +1,55 @@
+/*
+ * 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
+
+#include <linux/reboot.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);
+
+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);
+void mv78xx0_restart(enum reboot_mode, const char *);
+
+extern void mv78xx0_timer_init(void);
+
+
+#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 000000000..4e0f22b30
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c
@@ -0,0 +1,103 @@
+/*
+ * 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> */
+ .atag_offset = 0x100,
+ .init_machine = db78x00_init,
+ .map_io = mv78xx0_map_io,
+ .init_early = mv78xx0_init_early,
+ .init_irq = mv78xx0_init_irq,
+ .init_time = mv78xx0_timer_init,
+ .restart = mv78xx0_restart,
+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 000000000..e20d6da23
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h
@@ -0,0 +1,37 @@
+/*
+ * 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 RSTOUTn_MASK_PHYS (BRIDGE_PHYS_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)
+#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE + 0x0300)
+
+#endif
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 000000000..6b1f088e0
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/entry-macro.S
@@ -0,0 +1,41 @@
+/*
+ * 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 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/hardware.h b/arch/arm/mach-mv78xx0/include/mach/hardware.h
new file mode 100644
index 000000000..67cab0a08
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/hardware.h
@@ -0,0 +1,14 @@
+/*
+ * 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"
+
+#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 000000000..fa1d42219
--- /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/mv78xx0.h b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
new file mode 100644
index 000000000..723748d8b
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
@@ -0,0 +1,127 @@
+/*
+ * 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
+ * fee00000 f0800000 64K PCIe #0 I/O space
+ * fee10000 f0900000 64K PCIe #1 I/O space
+ * fee20000 f0a00000 64K PCIe #2 I/O space
+ * fee30000 f0b00000 64K PCIe #3 I/O space
+ * fee40000 f0c00000 64K PCIe #4 I/O space
+ * fee50000 f0d00000 64K PCIe #5 I/O space
+ * fee60000 f0e00000 64K PCIe #6 I/O space
+ * fee70000 f0f00000 64K PCIe #7 I/O space
+ * fd000000 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 IOMEM(0xfe400000)
+#define MV78XX0_CORE_REGS_PHYS_BASE 0xfe400000
+#define MV78XX0_CORE_REGS_SIZE SZ_16K
+
+#define MV78XX0_PCIE_IO_PHYS_BASE(i) (0xf0800000 + ((i) << 20))
+#define MV78XX0_PCIE_IO_SIZE SZ_1M
+
+#define MV78XX0_REGS_PHYS_BASE 0xf1000000
+#define MV78XX0_REGS_VIRT_BASE IOMEM(0xfd000000)
+#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)
+#define BRIDGE_PHYS_BASE (MV78XX0_CORE_REGS_PHYS_BASE)
+#define BRIDGE_WINS_CPU0_BASE (MV78XX0_CORE0_REGS_PHYS_BASE)
+#define BRIDGE_WINS_CPU1_BASE (MV78XX0_CORE1_REGS_PHYS_BASE)
+#define BRIDGE_WINS_SZ (0xA000)
+
+/*
+ * Register Map
+ */
+#define DDR_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x00000)
+#define DDR_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x00000)
+#define DDR_WINDOW_CPU0_BASE (DDR_PHYS_BASE + 0x1500)
+#define DDR_WINDOW_CPU1_BASE (DDR_PHYS_BASE + 0x1570)
+#define DDR_WINDOW_CPU_SZ (0x20)
+
+#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/uncompress.h b/arch/arm/mach-mv78xx0/include/mach/uncompress.h
new file mode 100644
index 000000000..6a761c44a
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/uncompress.h
@@ -0,0 +1,46 @@
+/*
+ * 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()
diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c
new file mode 100644
index 000000000..320734440
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/irq.c
@@ -0,0 +1,40 @@
+/*
+ * 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/gpio.h>
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/bridge-regs.h>
+#include <plat/orion-gpio.h>
+#include <plat/irq.h>
+#include "common.h"
+
+static int __initdata gpio0_irqs[4] = {
+ IRQ_MV78XX0_GPIO_0_7,
+ IRQ_MV78XX0_GPIO_8_15,
+ IRQ_MV78XX0_GPIO_16_23,
+ IRQ_MV78XX0_GPIO_24_31,
+};
+
+void __init mv78xx0_init_irq(void)
+{
+ orion_irq_init(0, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF);
+ orion_irq_init(32, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF);
+ orion_irq_init(64, 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(NULL, 0, 32, GPIO_VIRT_BASE,
+ mv78xx0_core_index() ? 0x18 : 0,
+ IRQ_MV78XX0_GPIO_START, gpio0_irqs);
+}
diff --git a/arch/arm/mach-mv78xx0/mpp.c b/arch/arm/mach-mv78xx0/mpp.c
new file mode 100644
index 000000000..df5034217
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/mpp.c
@@ -0,0 +1,37 @@
+/*
+ * 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/gpio.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <plat/mpp.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 000000000..3752302ae
--- /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 000000000..097ea4cb1
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/pcie.c
@@ -0,0 +1,269 @@
+/*
+ * 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 <video/vga.h>
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <plat/pcie.h>
+#include <mach/mv78xx0.h>
+#include "common.h"
+
+#define MV78XX0_MBUS_PCIE_MEM_TARGET(port, lane) ((port) ? 8 : 4)
+#define MV78XX0_MBUS_PCIE_MEM_ATTR(port, lane) (0xf8 & ~(0x10 << (lane)))
+#define MV78XX0_MBUS_PCIE_IO_TARGET(port, lane) ((port) ? 8 : 4)
+#define MV78XX0_MBUS_PCIE_IO_ATTR(port, lane) (0xf0 & ~(0x10 << (lane)))
+
+struct pcie_port {
+ u8 maj;
+ u8 min;
+ u8 root_bus_nr;
+ void __iomem *base;
+ spinlock_t conf_lock;
+ char mem_space_name[16];
+ struct resource res;
+};
+
+static struct pcie_port pcie_port[8];
+static int num_pcie_ports;
+static struct resource pcie_io_space;
+
+void __init mv78xx0_pcie_id(u32 *dev, u32 *rev)
+{
+ *dev = orion_pcie_dev_id(PCIE00_VIRT_BASE);
+ *rev = orion_pcie_rev(PCIE00_VIRT_BASE);
+}
+
+u32 pcie_port_size[8] = {
+ 0,
+ 0x30000000,
+ 0x10000000,
+ 0x10000000,
+ 0x08000000,
+ 0x08000000,
+ 0x08000000,
+ 0x04000000,
+};
+
+static void __init mv78xx0_pcie_preinit(void)
+{
+ int i;
+ u32 size_each;
+ u32 start;
+
+ 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_MEM;
+ if (request_resource(&iomem_resource, &pcie_io_space))
+ panic("can't allocate PCIe I/O space");
+
+ if (num_pcie_ports > 7)
+ panic("invalid number of PCIe ports");
+
+ size_each = pcie_port_size[num_pcie_ports];
+
+ start = MV78XX0_PCIE_MEM_PHYS_BASE;
+ for (i = 0; i < num_pcie_ports; i++) {
+ struct pcie_port *pp = pcie_port + i;
+
+ 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.name = pp->mem_space_name;
+ pp->res.flags = IORESOURCE_MEM;
+ pp->res.start = start;
+ pp->res.end = start + size_each - 1;
+ start += size_each;
+
+ if (request_resource(&iomem_resource, &pp->res))
+ panic("can't allocate PCIe MEM sub-space");
+
+ mvebu_mbus_add_window_by_id(MV78XX0_MBUS_PCIE_MEM_TARGET(pp->maj, pp->min),
+ MV78XX0_MBUS_PCIE_MEM_ATTR(pp->maj, pp->min),
+ pp->res.start, resource_size(&pp->res));
+ mvebu_mbus_add_window_remap_by_id(MV78XX0_MBUS_PCIE_IO_TARGET(pp->maj, pp->min),
+ MV78XX0_MBUS_PCIE_IO_ATTR(pp->maj, pp->min),
+ i * SZ_64K, SZ_64K, 0);
+ }
+}
+
+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];
+ sys->private_data = pp;
+ 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);
+
+ pci_ioremap_io(nr * SZ_64K, MV78XX0_PCIE_IO_PHYS_BASE(nr));
+
+ pci_add_resource_offset(&sys->resources, &pp->res, sys->mem_offset);
+
+ return 1;
+}
+
+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 pci_sys_data *sys = bus->sysdata;
+ struct pcie_port *pp = sys->private_data;
+ 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 pci_sys_data *sys = bus->sysdata;
+ struct pcie_port *pp = sys->private_data;
+ 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 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)
+{
+ if (nr >= num_pcie_ports) {
+ BUG();
+ return NULL;
+ }
+
+ return pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys,
+ &sys->resources);
+}
+
+static int __init mv78xx0_pcie_map_irq(const struct pci_dev *dev, u8 slot,
+ u8 pin)
+{
+ struct pci_sys_data *sys = dev->bus->sysdata;
+ struct pcie_port *pp = sys->private_data;
+
+ return IRQ_MV78XX0_PCIE_00 + (pp->maj << 2) + pp->min;
+}
+
+static struct hw_pci mv78xx0_pci __initdata = {
+ .nr_controllers = 8,
+ .preinit = mv78xx0_pcie_preinit,
+ .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, void __iomem *base)
+{
+ printk(KERN_INFO "MV78xx0 PCIe port %d.%d: ", maj, min);
+
+ if (orion_pcie_link_up(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 = 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)
+{
+ vga_base = MV78XX0_PCIE_MEM_PHYS_BASE;
+
+ if (init_port0) {
+ add_pcie_port(0, 0, PCIE00_VIRT_BASE);
+ if (!orion_pcie_x4_mode(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 000000000..d2d06f395
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c
@@ -0,0 +1,88 @@
+/*
+ * 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> */
+ .atag_offset = 0x100,
+ .init_machine = rd78x00_masa_init,
+ .map_io = mv78xx0_map_io,
+ .init_early = mv78xx0_init_early,
+ .init_irq = mv78xx0_init_irq,
+ .init_time = mv78xx0_timer_init,
+ .restart = mv78xx0_restart,
+MACHINE_END
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
new file mode 100644
index 000000000..97473168d
--- /dev/null
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -0,0 +1,126 @@
+menuconfig ARCH_MVEBU
+ bool "Marvell Engineering Business Unit (MVEBU) SoCs" if (ARCH_MULTI_V7 || ARCH_MULTI_V5)
+ select ARCH_SUPPORTS_BIG_ENDIAN
+ select CLKSRC_MMIO
+ select GENERIC_IRQ_CHIP
+ select PINCTRL
+ select PLAT_ORION
+ select SOC_BUS
+ select MVEBU_MBUS
+ select ZONE_DMA if ARM_LPAE
+ select ARCH_REQUIRE_GPIOLIB
+ select PCI_QUIRKS if PCI
+ select OF_ADDRESS_PCI
+
+if ARCH_MVEBU
+
+config MACH_MVEBU_ANY
+ bool
+
+config MACH_MVEBU_V7
+ bool
+ select ARMADA_370_XP_TIMER
+ select CACHE_L2X0
+ select ARM_CPU_SUSPEND
+ select MACH_MVEBU_ANY
+
+config MACH_ARMADA_370
+ bool "Marvell Armada 370 boards" if ARCH_MULTI_V7
+ select ARMADA_370_CLK
+ select CPU_PJ4B
+ select MACH_MVEBU_V7
+ select PINCTRL_ARMADA_370
+ help
+ Say 'Y' here if you want your kernel to support boards based
+ on the Marvell Armada 370 SoC with device tree.
+
+config MACH_ARMADA_375
+ bool "Marvell Armada 375 boards" if ARCH_MULTI_V7
+ select ARM_ERRATA_720789
+ select ARM_ERRATA_753970
+ select ARM_GIC
+ select ARMADA_375_CLK
+ select HAVE_ARM_SCU
+ select HAVE_ARM_TWD if SMP
+ select HAVE_SMP
+ select MACH_MVEBU_V7
+ select PINCTRL_ARMADA_375
+ help
+ Say 'Y' here if you want your kernel to support boards based
+ on the Marvell Armada 375 SoC with device tree.
+
+config MACH_ARMADA_38X
+ bool "Marvell Armada 380/385 boards" if ARCH_MULTI_V7
+ select ARM_ERRATA_720789
+ select ARM_ERRATA_753970
+ select ARM_GIC
+ select ARMADA_38X_CLK
+ select HAVE_ARM_SCU
+ select HAVE_ARM_TWD if SMP
+ select HAVE_SMP
+ select MACH_MVEBU_V7
+ select PINCTRL_ARMADA_38X
+ help
+ Say 'Y' here if you want your kernel to support boards based
+ on the Marvell Armada 380/385 SoC with device tree.
+
+config MACH_ARMADA_39X
+ bool "Marvell Armada 39x boards" if ARCH_MULTI_V7
+ select ARM_GIC
+ select ARMADA_39X_CLK
+ select CACHE_L2X0
+ select HAVE_ARM_SCU
+ select HAVE_ARM_TWD if SMP
+ select HAVE_SMP
+ select MACH_MVEBU_V7
+ select PINCTRL_ARMADA_39X
+ help
+ Say 'Y' here if you want your kernel to support boards based
+ on the Marvell Armada 39x SoC with device tree.
+
+config MACH_ARMADA_XP
+ bool "Marvell Armada XP boards" if ARCH_MULTI_V7
+ select ARMADA_XP_CLK
+ select CPU_PJ4B
+ select MACH_MVEBU_V7
+ select PINCTRL_ARMADA_XP
+ help
+ Say 'Y' here if you want your kernel to support boards based
+ on the Marvell Armada XP SoC with device tree.
+
+config MACH_DOVE
+ bool "Marvell Dove boards" if ARCH_MULTI_V7
+ select CACHE_L2X0
+ select CPU_PJ4
+ select DOVE_CLK
+ select MACH_MVEBU_ANY
+ select ORION_IRQCHIP
+ select ORION_TIMER
+ select PINCTRL_DOVE
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell Dove using flattened device tree.
+
+config MACH_KIRKWOOD
+ bool "Marvell Kirkwood boards" if ARCH_MULTI_V5
+ select ARCH_REQUIRE_GPIOLIB
+ select CPU_FEROCEON
+ select KIRKWOOD_CLK
+ select MACH_MVEBU_ANY
+ select ORION_IRQCHIP
+ select ORION_TIMER
+ select PCI
+ select PCI_QUIRKS
+ select PINCTRL_KIRKWOOD
+ help
+ Say 'Y' here if you want your kernel to support boards based
+ on the Marvell Kirkwood device tree.
+
+config MACH_NETXBIG
+ bool "LaCie 2Big and 5Big Network v2"
+ depends on MACH_KIRKWOOD
+ help
+ Say 'Y' here if you want your kernel to support the
+ LaCie 2Big and 5Big Network v2
+
+endif
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
new file mode 100644
index 000000000..b4f01497c
--- /dev/null
+++ b/arch/arm/mach-mvebu/Makefile
@@ -0,0 +1,16 @@
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
+ -I$(srctree)/arch/arm/plat-orion/include
+
+AFLAGS_coherency_ll.o := -Wa,-march=armv7-a
+CFLAGS_pmsu.o := -march=armv7-a
+
+obj-$(CONFIG_MACH_MVEBU_ANY) += system-controller.o mvebu-soc-id.o
+
+ifeq ($(CONFIG_MACH_MVEBU_V7),y)
+obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o pmsu_ll.o pm.o pm-board.o
+obj-$(CONFIG_SMP) += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o
+endif
+
+obj-$(CONFIG_MACH_DOVE) += dove.o
+obj-$(CONFIG_MACH_KIRKWOOD) += kirkwood.o kirkwood-pm.o
+obj-$(CONFIG_MACH_NETXBIG) += netxbig.o
diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h
new file mode 100644
index 000000000..c55bbf81d
--- /dev/null
+++ b/arch/arm/mach-mvebu/armada-370-xp.h
@@ -0,0 +1,23 @@
+/*
+ * Generic definitions for Marvell Armada_370_XP SoCs
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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_ARMADA_370_XP_H
+#define __MACH_ARMADA_370_XP_H
+
+#ifdef CONFIG_SMP
+void armada_xp_secondary_startup(void);
+extern struct smp_operations armada_xp_smp_ops;
+#endif
+
+#endif /* __MACH_ARMADA_370_XP_H */
diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c
new file mode 100644
index 000000000..afee9083a
--- /dev/null
+++ b/arch/arm/mach-mvebu/board-v7.c
@@ -0,0 +1,248 @@
+/*
+ * Device Tree support for Armada 370 and XP platforms.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <linux/clocksource.h>
+#include <linux/dma-mapping.h>
+#include <linux/memblock.h>
+#include <linux/mbus.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/irqchip.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/smp_scu.h>
+#include "armada-370-xp.h"
+#include "common.h"
+#include "coherency.h"
+#include "mvebu-soc-id.h"
+
+static void __iomem *scu_base;
+
+/*
+ * Enables the SCU when available. Obviously, this is only useful on
+ * Cortex-A based SOCs, not on PJ4B based ones.
+ */
+static void __init mvebu_scu_enable(void)
+{
+ struct device_node *np =
+ of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+ if (np) {
+ scu_base = of_iomap(np, 0);
+ scu_enable(scu_base);
+ of_node_put(np);
+ }
+}
+
+void __iomem *mvebu_get_scu_base(void)
+{
+ return scu_base;
+}
+
+/*
+ * When returning from suspend, the platform goes through the
+ * bootloader, which executes its DDR3 training code. This code has
+ * the unfortunate idea of using the first 10 KB of each DRAM bank to
+ * exercise the RAM and calculate the optimal timings. Therefore, this
+ * area of RAM is overwritten, and shouldn't be used by the kernel if
+ * suspend/resume is supported.
+ */
+
+#ifdef CONFIG_SUSPEND
+#define MVEBU_DDR_TRAINING_AREA_SZ (10 * SZ_1K)
+static int __init mvebu_scan_mem(unsigned long node, const char *uname,
+ int depth, void *data)
+{
+ const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+ const __be32 *reg, *endp;
+ int l;
+
+ if (type == NULL || strcmp(type, "memory"))
+ return 0;
+
+ reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
+ if (reg == NULL)
+ reg = of_get_flat_dt_prop(node, "reg", &l);
+ if (reg == NULL)
+ return 0;
+
+ endp = reg + (l / sizeof(__be32));
+ while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+ u64 base, size;
+
+ base = dt_mem_next_cell(dt_root_addr_cells, &reg);
+ size = dt_mem_next_cell(dt_root_size_cells, &reg);
+
+ memblock_reserve(base, MVEBU_DDR_TRAINING_AREA_SZ);
+ }
+
+ return 0;
+}
+
+static void __init mvebu_memblock_reserve(void)
+{
+ of_scan_flat_dt(mvebu_scan_mem, NULL);
+}
+#else
+static void __init mvebu_memblock_reserve(void) {}
+#endif
+
+/*
+ * Early versions of Armada 375 SoC have a bug where the BootROM
+ * leaves an external data abort pending. The kernel is hit by this
+ * data abort as soon as it enters userspace, because it unmasks the
+ * data aborts at this moment. We register a custom abort handler
+ * below to ignore the first data abort to work around this
+ * problem.
+ */
+static int armada_375_external_abort_wa(unsigned long addr, unsigned int fsr,
+ struct pt_regs *regs)
+{
+ static int ignore_first;
+
+ if (!ignore_first && fsr == 0x1406) {
+ ignore_first = 1;
+ return 0;
+ }
+
+ return 1;
+}
+
+static void __init mvebu_init_irq(void)
+{
+ irqchip_init();
+ mvebu_scu_enable();
+ coherency_init();
+ BUG_ON(mvebu_mbus_dt_init(coherency_available()));
+}
+
+static void __init external_abort_quirk(void)
+{
+ u32 dev, rev;
+
+ if (mvebu_get_soc_id(&dev, &rev) == 0 && rev > ARMADA_375_Z1_REV)
+ return;
+
+ hook_fault_code(16 + 6, armada_375_external_abort_wa, SIGBUS, 0,
+ "imprecise external abort");
+}
+
+static void __init i2c_quirk(void)
+{
+ struct device_node *np;
+ u32 dev, rev;
+
+ /*
+ * Only revisons more recent than A0 support the offload
+ * mechanism. We can exit only if we are sure that we can
+ * get the SoC revision and it is more recent than A0.
+ */
+ if (mvebu_get_soc_id(&dev, &rev) == 0 && rev > MV78XX0_A0_REV)
+ return;
+
+ for_each_compatible_node(np, NULL, "marvell,mv78230-i2c") {
+ struct property *new_compat;
+
+ new_compat = kzalloc(sizeof(*new_compat), GFP_KERNEL);
+
+ new_compat->name = kstrdup("compatible", GFP_KERNEL);
+ new_compat->length = sizeof("marvell,mv78230-a0-i2c");
+ new_compat->value = kstrdup("marvell,mv78230-a0-i2c",
+ GFP_KERNEL);
+
+ of_update_property(np, new_compat);
+ }
+ return;
+}
+
+static void __init mvebu_dt_init(void)
+{
+ if (of_machine_is_compatible("marvell,armadaxp"))
+ i2c_quirk();
+ if (of_machine_is_compatible("marvell,a375-db"))
+ external_abort_quirk();
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char * const armada_370_xp_dt_compat[] __initconst = {
+ "marvell,armada-370-xp",
+ NULL,
+};
+
+DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)")
+ .l2c_aux_val = 0,
+ .l2c_aux_mask = ~0,
+/*
+ * The following field (.smp) is still needed to ensure backward
+ * compatibility with old Device Trees that were not specifying the
+ * cpus enable-method property.
+ */
+ .smp = smp_ops(armada_xp_smp_ops),
+ .init_machine = mvebu_dt_init,
+ .init_irq = mvebu_init_irq,
+ .restart = mvebu_restart,
+ .reserve = mvebu_memblock_reserve,
+ .dt_compat = armada_370_xp_dt_compat,
+MACHINE_END
+
+static const char * const armada_375_dt_compat[] __initconst = {
+ "marvell,armada375",
+ NULL,
+};
+
+DT_MACHINE_START(ARMADA_375_DT, "Marvell Armada 375 (Device Tree)")
+ .l2c_aux_val = 0,
+ .l2c_aux_mask = ~0,
+ .init_irq = mvebu_init_irq,
+ .init_machine = mvebu_dt_init,
+ .restart = mvebu_restart,
+ .dt_compat = armada_375_dt_compat,
+MACHINE_END
+
+static const char * const armada_38x_dt_compat[] __initconst = {
+ "marvell,armada380",
+ "marvell,armada385",
+ NULL,
+};
+
+DT_MACHINE_START(ARMADA_38X_DT, "Marvell Armada 380/385 (Device Tree)")
+ .l2c_aux_val = 0,
+ .l2c_aux_mask = ~0,
+ .init_irq = mvebu_init_irq,
+ .restart = mvebu_restart,
+ .dt_compat = armada_38x_dt_compat,
+MACHINE_END
+
+static const char * const armada_39x_dt_compat[] __initconst = {
+ "marvell,armada390",
+ "marvell,armada398",
+ NULL,
+};
+
+DT_MACHINE_START(ARMADA_39X_DT, "Marvell Armada 39x (Device Tree)")
+ .l2c_aux_val = 0,
+ .l2c_aux_mask = ~0,
+ .init_irq = mvebu_init_irq,
+ .restart = mvebu_restart,
+ .dt_compat = armada_39x_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-mvebu/board.h b/arch/arm/mach-mvebu/board.h
new file mode 100644
index 000000000..98e32cc2e
--- /dev/null
+++ b/arch/arm/mach-mvebu/board.h
@@ -0,0 +1,21 @@
+/*
+ * Board functions for Marvell System On Chip
+ *
+ * Copyright (C) 2014
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms 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_MVEBU_BOARD_H
+#define __ARCH_MVEBU_BOARD_H
+
+#ifdef CONFIG_MACH_NETXBIG
+void netxbig_init(void);
+#else
+static inline void netxbig_init(void) {};
+#endif
+#endif
diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
new file mode 100644
index 000000000..e46e9ea1e
--- /dev/null
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -0,0 +1,252 @@
+/*
+ * Coherency fabric (Aurora) support for Armada 370, 375, 38x and XP
+ * platforms.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Yehuda Yitschak <yehuday@marvell.com>
+ * Gregory Clement <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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.
+ *
+ * The Armada 370, 375, 38x and XP SOCs have a coherency fabric which is
+ * responsible for ensuring hardware coherency between all CPUs and between
+ * CPUs and I/O masters. This file initializes the coherency fabric and
+ * supplies basic routines for configuring and controlling hardware coherency
+ */
+
+#define pr_fmt(fmt) "mvebu-coherency: " fmt
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/smp.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/mbus.h>
+#include <linux/pci.h>
+#include <asm/smp_plat.h>
+#include <asm/cacheflush.h>
+#include <asm/mach/map.h>
+#include <asm/dma-mapping.h>
+#include "coherency.h"
+#include "mvebu-soc-id.h"
+
+unsigned long coherency_phys_base;
+void __iomem *coherency_base;
+static void __iomem *coherency_cpu_base;
+
+/* Coherency fabric registers */
+#define IO_SYNC_BARRIER_CTL_OFFSET 0x0
+
+enum {
+ COHERENCY_FABRIC_TYPE_NONE,
+ COHERENCY_FABRIC_TYPE_ARMADA_370_XP,
+ COHERENCY_FABRIC_TYPE_ARMADA_375,
+ COHERENCY_FABRIC_TYPE_ARMADA_380,
+};
+
+static const struct of_device_id of_coherency_table[] = {
+ {.compatible = "marvell,coherency-fabric",
+ .data = (void *) COHERENCY_FABRIC_TYPE_ARMADA_370_XP },
+ {.compatible = "marvell,armada-375-coherency-fabric",
+ .data = (void *) COHERENCY_FABRIC_TYPE_ARMADA_375 },
+ {.compatible = "marvell,armada-380-coherency-fabric",
+ .data = (void *) COHERENCY_FABRIC_TYPE_ARMADA_380 },
+ { /* end of list */ },
+};
+
+/* Functions defined in coherency_ll.S */
+int ll_enable_coherency(void);
+void ll_add_cpu_to_smp_group(void);
+
+int set_cpu_coherent(void)
+{
+ if (!coherency_base) {
+ pr_warn("Can't make current CPU cache coherent.\n");
+ pr_warn("Coherency fabric is not initialized\n");
+ return 1;
+ }
+
+ ll_add_cpu_to_smp_group();
+ return ll_enable_coherency();
+}
+
+static int mvebu_hwcc_notifier(struct notifier_block *nb,
+ unsigned long event, void *__dev)
+{
+ struct device *dev = __dev;
+
+ if (event != BUS_NOTIFY_ADD_DEVICE)
+ return NOTIFY_DONE;
+ set_dma_ops(dev, &arm_coherent_dma_ops);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block mvebu_hwcc_nb = {
+ .notifier_call = mvebu_hwcc_notifier,
+};
+
+static struct notifier_block mvebu_hwcc_pci_nb = {
+ .notifier_call = mvebu_hwcc_notifier,
+};
+
+static void __init armada_370_coherency_init(struct device_node *np)
+{
+ struct resource res;
+
+ of_address_to_resource(np, 0, &res);
+ coherency_phys_base = res.start;
+ /*
+ * Ensure secondary CPUs will see the updated value,
+ * which they read before they join the coherency
+ * fabric, and therefore before they are coherent with
+ * the boot CPU cache.
+ */
+ sync_cache_w(&coherency_phys_base);
+ coherency_base = of_iomap(np, 0);
+ coherency_cpu_base = of_iomap(np, 1);
+ set_cpu_coherent();
+}
+
+/*
+ * This ioremap hook is used on Armada 375/38x to ensure that PCIe
+ * memory areas are mapped as MT_UNCACHED instead of MT_DEVICE. This
+ * is needed as a workaround for a deadlock issue between the PCIe
+ * interface and the cache controller.
+ */
+static void __iomem *
+armada_pcie_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
+ unsigned int mtype, void *caller)
+{
+ struct resource pcie_mem;
+
+ mvebu_mbus_get_pcie_mem_aperture(&pcie_mem);
+
+ if (pcie_mem.start <= phys_addr && (phys_addr + size) <= pcie_mem.end)
+ mtype = MT_UNCACHED;
+
+ return __arm_ioremap_caller(phys_addr, size, mtype, caller);
+}
+
+static void __init armada_375_380_coherency_init(struct device_node *np)
+{
+ struct device_node *cache_dn;
+
+ coherency_cpu_base = of_iomap(np, 0);
+ arch_ioremap_caller = armada_pcie_wa_ioremap_caller;
+
+ /*
+ * We should switch the PL310 to I/O coherency mode only if
+ * I/O coherency is actually enabled.
+ */
+ if (!coherency_available())
+ return;
+
+ /*
+ * Add the PL310 property "arm,io-coherent". This makes sure the
+ * outer sync operation is not used, which allows to
+ * workaround the system erratum that causes deadlocks when
+ * doing PCIe in an SMP situation on Armada 375 and Armada
+ * 38x.
+ */
+ for_each_compatible_node(cache_dn, NULL, "arm,pl310-cache") {
+ struct property *p;
+
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
+ p->name = kstrdup("arm,io-coherent", GFP_KERNEL);
+ of_add_property(cache_dn, p);
+ }
+}
+
+static int coherency_type(void)
+{
+ struct device_node *np;
+ const struct of_device_id *match;
+ int type;
+
+ /*
+ * The coherency fabric is needed:
+ * - For coherency between processors on Armada XP, so only
+ * when SMP is enabled.
+ * - For coherency between the processor and I/O devices, but
+ * this coherency requires many pre-requisites (write
+ * allocate cache policy, shareable pages, SMP bit set) that
+ * are only meant in SMP situations.
+ *
+ * Note that this means that on Armada 370, there is currently
+ * no way to use hardware I/O coherency, because even when
+ * CONFIG_SMP is enabled, is_smp() returns false due to the
+ * Armada 370 being a single-core processor. To lift this
+ * limitation, we would have to find a way to make the cache
+ * policy set to write-allocate (on all Armada SoCs), and to
+ * set the shareable attribute in page tables (on all Armada
+ * SoCs except the Armada 370). Unfortunately, such decisions
+ * are taken very early in the kernel boot process, at a point
+ * where we don't know yet on which SoC we are running.
+
+ */
+ if (!is_smp())
+ return COHERENCY_FABRIC_TYPE_NONE;
+
+ np = of_find_matching_node_and_match(NULL, of_coherency_table, &match);
+ if (!np)
+ return COHERENCY_FABRIC_TYPE_NONE;
+
+ type = (int) match->data;
+
+ of_node_put(np);
+
+ return type;
+}
+
+int coherency_available(void)
+{
+ return coherency_type() != COHERENCY_FABRIC_TYPE_NONE;
+}
+
+int __init coherency_init(void)
+{
+ int type = coherency_type();
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, of_coherency_table);
+
+ if (type == COHERENCY_FABRIC_TYPE_ARMADA_370_XP)
+ armada_370_coherency_init(np);
+ else if (type == COHERENCY_FABRIC_TYPE_ARMADA_375 ||
+ type == COHERENCY_FABRIC_TYPE_ARMADA_380)
+ armada_375_380_coherency_init(np);
+
+ of_node_put(np);
+
+ return 0;
+}
+
+static int __init coherency_late_init(void)
+{
+ if (coherency_available())
+ bus_register_notifier(&platform_bus_type,
+ &mvebu_hwcc_nb);
+ return 0;
+}
+
+postcore_initcall(coherency_late_init);
+
+#if IS_ENABLED(CONFIG_PCI)
+static int __init coherency_pci_init(void)
+{
+ if (coherency_available())
+ bus_register_notifier(&pci_bus_type,
+ &mvebu_hwcc_pci_nb);
+ return 0;
+}
+
+arch_initcall(coherency_pci_init);
+#endif
diff --git a/arch/arm/mach-mvebu/coherency.h b/arch/arm/mach-mvebu/coherency.h
new file mode 100644
index 000000000..54cb7607b
--- /dev/null
+++ b/arch/arm/mach-mvebu/coherency.h
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-mvebu/include/mach/coherency.h
+ *
+ *
+ * Coherency fabric (Aurora) support for Armada 370 and XP platforms.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * This file is licensed under the terms 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_370_XP_COHERENCY_H
+#define __MACH_370_XP_COHERENCY_H
+
+extern unsigned long coherency_phys_base;
+int set_cpu_coherent(void);
+
+int coherency_init(void);
+int coherency_available(void);
+
+#endif /* __MACH_370_XP_COHERENCY_H */
diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S
new file mode 100644
index 000000000..8b2fbc8b6
--- /dev/null
+++ b/arch/arm/mach-mvebu/coherency_ll.S
@@ -0,0 +1,166 @@
+/*
+ * Coherency fabric: low level functions
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.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.
+ *
+ * This file implements the assembly function to add a CPU to the
+ * coherency fabric. This function is called by each of the secondary
+ * CPUs during their early boot in an SMP kernel, this why this
+ * function have to callable from assembly. It can also be called by a
+ * primary CPU from C code during its boot.
+ */
+
+#include <linux/linkage.h>
+#define ARMADA_XP_CFB_CTL_REG_OFFSET 0x0
+#define ARMADA_XP_CFB_CFG_REG_OFFSET 0x4
+
+#include <asm/assembler.h>
+#include <asm/cp15.h>
+
+ .text
+/*
+ * Returns the coherency base address in r1 (r0 is untouched), or 0 if
+ * the coherency fabric is not enabled.
+ */
+ENTRY(ll_get_coherency_base)
+ mrc p15, 0, r1, c1, c0, 0
+ tst r1, #CR_M @ Check MMU bit enabled
+ bne 1f
+
+ /*
+ * MMU is disabled, use the physical address of the coherency
+ * base address. However, if the coherency fabric isn't mapped
+ * (i.e its virtual address is zero), it means coherency is
+ * not enabled, so we return 0.
+ */
+ ldr r1, =coherency_base
+ cmp r1, #0
+ beq 2f
+ adr r1, 3f
+ ldr r3, [r1]
+ ldr r1, [r1, r3]
+ b 2f
+1:
+ /*
+ * MMU is enabled, use the virtual address of the coherency
+ * base address.
+ */
+ ldr r1, =coherency_base
+ ldr r1, [r1]
+2:
+ ret lr
+ENDPROC(ll_get_coherency_base)
+
+/*
+ * Returns the coherency CPU mask in r3 (r0 is untouched). This
+ * coherency CPU mask can be used with the coherency fabric
+ * configuration and control registers. Note that the mask is already
+ * endian-swapped as appropriate so that the calling functions do not
+ * have to care about endianness issues while accessing the coherency
+ * fabric registers
+ */
+ENTRY(ll_get_coherency_cpumask)
+ mrc 15, 0, r3, cr0, cr0, 5
+ and r3, r3, #15
+ mov r2, #(1 << 24)
+ lsl r3, r2, r3
+ARM_BE8(rev r3, r3)
+ ret lr
+ENDPROC(ll_get_coherency_cpumask)
+
+/*
+ * ll_add_cpu_to_smp_group(), ll_enable_coherency() and
+ * ll_disable_coherency() use the strex/ldrex instructions while the
+ * MMU can be disabled. The Armada XP SoC has an exclusive monitor
+ * that tracks transactions to Device and/or SO memory and thanks to
+ * that, exclusive transactions are functional even when the MMU is
+ * disabled.
+ */
+
+ENTRY(ll_add_cpu_to_smp_group)
+ /*
+ * As r0 is not modified by ll_get_coherency_base() and
+ * ll_get_coherency_cpumask(), we use it to temporarly save lr
+ * and avoid it being modified by the branch and link
+ * calls. This function is used very early in the secondary
+ * CPU boot, and no stack is available at this point.
+ */
+ mov r0, lr
+ bl ll_get_coherency_base
+ /* Bail out if the coherency is not enabled */
+ cmp r1, #0
+ reteq r0
+ bl ll_get_coherency_cpumask
+ mov lr, r0
+ add r0, r1, #ARMADA_XP_CFB_CFG_REG_OFFSET
+1:
+ ldrex r2, [r0]
+ orr r2, r2, r3
+ strex r1, r2, [r0]
+ cmp r1, #0
+ bne 1b
+ ret lr
+ENDPROC(ll_add_cpu_to_smp_group)
+
+ENTRY(ll_enable_coherency)
+ /*
+ * As r0 is not modified by ll_get_coherency_base() and
+ * ll_get_coherency_cpumask(), we use it to temporarly save lr
+ * and avoid it being modified by the branch and link
+ * calls. This function is used very early in the secondary
+ * CPU boot, and no stack is available at this point.
+ */
+ mov r0, lr
+ bl ll_get_coherency_base
+ /* Bail out if the coherency is not enabled */
+ cmp r1, #0
+ reteq r0
+ bl ll_get_coherency_cpumask
+ mov lr, r0
+ add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET
+1:
+ ldrex r2, [r0]
+ orr r2, r2, r3
+ strex r1, r2, [r0]
+ cmp r1, #0
+ bne 1b
+ dsb
+ mov r0, #0
+ ret lr
+ENDPROC(ll_enable_coherency)
+
+ENTRY(ll_disable_coherency)
+ /*
+ * As r0 is not modified by ll_get_coherency_base() and
+ * ll_get_coherency_cpumask(), we use it to temporarly save lr
+ * and avoid it being modified by the branch and link
+ * calls. This function is used very early in the secondary
+ * CPU boot, and no stack is available at this point.
+ */
+ mov r0, lr
+ bl ll_get_coherency_base
+ /* Bail out if the coherency is not enabled */
+ cmp r1, #0
+ reteq r0
+ bl ll_get_coherency_cpumask
+ mov lr, r0
+ add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET
+1:
+ ldrex r2, [r0]
+ bic r2, r2, r3
+ strex r1, r2, [r0]
+ cmp r1, #0
+ bne 1b
+ dsb
+ ret lr
+ENDPROC(ll_disable_coherency)
+
+ .align 2
+3:
+ .long coherency_phys_base - .
diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
new file mode 100644
index 000000000..3e0aca1f2
--- /dev/null
+++ b/arch/arm/mach-mvebu/common.h
@@ -0,0 +1,30 @@
+/*
+ * Core functions for Marvell System On Chip
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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 __ARCH_MVEBU_COMMON_H
+#define __ARCH_MVEBU_COMMON_H
+
+#include <linux/reboot.h>
+
+void mvebu_restart(enum reboot_mode mode, const char *cmd);
+int mvebu_cpu_reset_deassert(int cpu);
+void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr);
+void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr);
+int mvebu_system_controller_get_soc_id(u32 *dev, u32 *rev);
+
+void __iomem *mvebu_get_scu_base(void);
+
+int mvebu_pm_init(void (*board_pm_enter)(void __iomem *sdram_reg, u32 srcmd));
+
+#endif
diff --git a/arch/arm/mach-mvebu/cpu-reset.c b/arch/arm/mach-mvebu/cpu-reset.c
new file mode 100644
index 000000000..4a2cadd6b
--- /dev/null
+++ b/arch/arm/mach-mvebu/cpu-reset.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2014 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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 pr_fmt(fmt) "mvebu-cpureset: " fmt
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/resource.h>
+
+static void __iomem *cpu_reset_base;
+static size_t cpu_reset_size;
+
+#define CPU_RESET_OFFSET(cpu) (cpu * 0x8)
+#define CPU_RESET_ASSERT BIT(0)
+
+int mvebu_cpu_reset_deassert(int cpu)
+{
+ u32 reg;
+
+ if (!cpu_reset_base)
+ return -ENODEV;
+
+ if (CPU_RESET_OFFSET(cpu) >= cpu_reset_size)
+ return -EINVAL;
+
+ reg = readl(cpu_reset_base + CPU_RESET_OFFSET(cpu));
+ reg &= ~CPU_RESET_ASSERT;
+ writel(reg, cpu_reset_base + CPU_RESET_OFFSET(cpu));
+
+ return 0;
+}
+
+static int mvebu_cpu_reset_map(struct device_node *np, int res_idx)
+{
+ struct resource res;
+
+ if (of_address_to_resource(np, res_idx, &res)) {
+ pr_err("unable to get resource\n");
+ return -ENOENT;
+ }
+
+ if (!request_mem_region(res.start, resource_size(&res),
+ np->full_name)) {
+ pr_err("unable to request region\n");
+ return -EBUSY;
+ }
+
+ cpu_reset_base = ioremap(res.start, resource_size(&res));
+ if (!cpu_reset_base) {
+ pr_err("unable to map registers\n");
+ release_mem_region(res.start, resource_size(&res));
+ return -ENOMEM;
+ }
+
+ cpu_reset_size = resource_size(&res);
+
+ return 0;
+}
+
+static int __init mvebu_cpu_reset_init(void)
+{
+ struct device_node *np;
+ int res_idx;
+ int ret;
+
+ np = of_find_compatible_node(NULL, NULL,
+ "marvell,armada-370-cpu-reset");
+ if (np) {
+ res_idx = 0;
+ } else {
+ /*
+ * This code is kept for backward compatibility with
+ * old Device Trees.
+ */
+ np = of_find_compatible_node(NULL, NULL,
+ "marvell,armada-370-xp-pmsu");
+ if (np) {
+ pr_warn(FW_WARN "deprecated pmsu binding\n");
+ res_idx = 1;
+ }
+ }
+
+ /* No reset node found */
+ if (!np)
+ return -ENODEV;
+
+ ret = mvebu_cpu_reset_map(np, res_idx);
+ of_node_put(np);
+
+ return ret;
+}
+
+early_initcall(mvebu_cpu_reset_init);
diff --git a/arch/arm/mach-mvebu/dove.c b/arch/arm/mach-mvebu/dove.c
new file mode 100644
index 000000000..5a1741500
--- /dev/null
+++ b/arch/arm/mach-mvebu/dove.c
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-mvebu/dove.c
+ *
+ * Marvell Dove 88AP510 System On Chip FDT Board
+ *
+ * This file is licensed under the terms 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/mbus.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <asm/hardware/cache-tauros2.h>
+#include <asm/mach/arch.h>
+#include "common.h"
+
+static void __init dove_init(void)
+{
+ pr_info("Dove 88AP510 SoC\n");
+
+#ifdef CONFIG_CACHE_TAUROS2
+ tauros2_init(0);
+#endif
+ BUG_ON(mvebu_mbus_dt_init(false));
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char * const dove_dt_compat[] __initconst = {
+ "marvell,dove",
+ NULL
+};
+
+DT_MACHINE_START(DOVE_DT, "Marvell Dove")
+ .init_machine = dove_init,
+ .restart = mvebu_restart,
+ .dt_compat = dove_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-mvebu/headsmp-a9.S b/arch/arm/mach-mvebu/headsmp-a9.S
new file mode 100644
index 000000000..08d5ed46b
--- /dev/null
+++ b/arch/arm/mach-mvebu/headsmp-a9.S
@@ -0,0 +1,27 @@
+/*
+ * SMP support: Entry point for secondary CPUs of Marvell EBU
+ * Cortex-A9 based SOCs (Armada 375 and Armada 38x).
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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/linkage.h>
+#include <linux/init.h>
+
+#include <asm/assembler.h>
+
+ __CPUINIT
+
+ENTRY(mvebu_cortex_a9_secondary_startup)
+ARM_BE8(setend be)
+ bl v7_invalidate_l1
+ bl armada_38x_scu_power_up
+ b secondary_startup
+ENDPROC(mvebu_cortex_a9_secondary_startup)
diff --git a/arch/arm/mach-mvebu/headsmp.S b/arch/arm/mach-mvebu/headsmp.S
new file mode 100644
index 000000000..2c4032e36
--- /dev/null
+++ b/arch/arm/mach-mvebu/headsmp.S
@@ -0,0 +1,40 @@
+/*
+ * SMP support: Entry point for secondary CPUs
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Yehuda Yitschak <yehuday@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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.
+ *
+ * This file implements the assembly entry point for secondary CPUs in
+ * an SMP kernel. The only thing we need to do is to add the CPU to
+ * the coherency fabric by writing to 2 registers. Currently the base
+ * register addresses are hard coded due to the early initialisation
+ * problems.
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+#include <asm/assembler.h>
+
+/*
+ * Armada XP specific entry point for secondary CPUs.
+ * We add the CPU to the coherency fabric and then jump to secondary
+ * startup
+ */
+ENTRY(armada_xp_secondary_startup)
+ ARM_BE8(setend be ) @ go BE8 if entered LE
+
+ bl ll_add_cpu_to_smp_group
+
+ bl ll_enable_coherency
+
+ b secondary_startup
+
+ENDPROC(armada_xp_secondary_startup)
diff --git a/arch/arm/mach-mvebu/include/mach/gpio.h b/arch/arm/mach-mvebu/include/mach/gpio.h
new file mode 100644
index 000000000..40a8c178f
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/gpio.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/arm/mach-mvebu/kirkwood-pm.c b/arch/arm/mach-mvebu/kirkwood-pm.c
new file mode 100644
index 000000000..cbb816f21
--- /dev/null
+++ b/arch/arm/mach-mvebu/kirkwood-pm.c
@@ -0,0 +1,76 @@
+/*
+ * Power Management driver for Marvell Kirkwood SoCs
+ *
+ * Copyright (C) 2013 Ezequiel Garcia <ezequiel@free-electrons.com>
+ * 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,
+ * 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/kernel.h>
+#include <linux/suspend.h>
+#include <linux/io.h>
+#include "kirkwood.h"
+
+static void __iomem *ddr_operation_base;
+static void __iomem *memory_pm_ctrl;
+
+static void kirkwood_low_power(void)
+{
+ u32 mem_pm_ctrl;
+
+ mem_pm_ctrl = readl(memory_pm_ctrl);
+
+ /* Set peripherals to low-power mode */
+ writel_relaxed(~0, memory_pm_ctrl);
+
+ /* Set DDR in self-refresh */
+ writel_relaxed(0x7, ddr_operation_base);
+
+ /*
+ * Set CPU in wait-for-interrupt state.
+ * This disables the CPU core clocks,
+ * the array clocks, and also the L2 controller.
+ */
+ cpu_do_idle();
+
+ writel_relaxed(mem_pm_ctrl, memory_pm_ctrl);
+}
+
+static int kirkwood_suspend_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ kirkwood_low_power();
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int kirkwood_pm_valid_standby(suspend_state_t state)
+{
+ return state == PM_SUSPEND_STANDBY;
+}
+
+static const struct platform_suspend_ops kirkwood_suspend_ops = {
+ .enter = kirkwood_suspend_enter,
+ .valid = kirkwood_pm_valid_standby,
+};
+
+int __init kirkwood_pm_init(void)
+{
+ ddr_operation_base = ioremap(DDR_OPERATION_BASE, 4);
+ memory_pm_ctrl = ioremap(MEMORY_PM_CTRL_PHYS, 4);
+
+ suspend_set_ops(&kirkwood_suspend_ops);
+ return 0;
+}
diff --git a/arch/arm/mach-mvebu/kirkwood-pm.h b/arch/arm/mach-mvebu/kirkwood-pm.h
new file mode 100644
index 000000000..21e7530f3
--- /dev/null
+++ b/arch/arm/mach-mvebu/kirkwood-pm.h
@@ -0,0 +1,26 @@
+/*
+ * Power Management driver for Marvell Kirkwood SoCs
+ *
+ * Copyright (C) 2013 Ezequiel Garcia <ezequiel@free-electrons.com>
+ * 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,
+ * 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.
+ */
+
+#ifndef __ARCH_KIRKWOOD_PM_H
+#define __ARCH_KIRKWOOD_PM_H
+
+#ifdef CONFIG_PM
+void kirkwood_pm_init(void);
+#else
+static inline void kirkwood_pm_init(void) {};
+#endif
+
+#endif
diff --git a/arch/arm/mach-mvebu/kirkwood.c b/arch/arm/mach-mvebu/kirkwood.c
new file mode 100644
index 000000000..925f75f54
--- /dev/null
+++ b/arch/arm/mach-mvebu/kirkwood.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2012 (C), Jason Cooper <jason@lakedaemon.net>
+ *
+ * arch/arm/mach-mvebu/kirkwood.c
+ *
+ * Flattened Device Tree board initialization
+ *
+ * This file is licensed under the terms 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/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_net.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <asm/hardware/cache-feroceon-l2.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include "kirkwood.h"
+#include "kirkwood-pm.h"
+#include "common.h"
+#include "board.h"
+
+static struct resource kirkwood_cpufreq_resources[] = {
+ [0] = {
+ .start = CPU_CONTROL_PHYS,
+ .end = CPU_CONTROL_PHYS + 3,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device kirkwood_cpufreq_device = {
+ .name = "kirkwood-cpufreq",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(kirkwood_cpufreq_resources),
+ .resource = kirkwood_cpufreq_resources,
+};
+
+static void __init kirkwood_cpufreq_init(void)
+{
+ platform_device_register(&kirkwood_cpufreq_device);
+}
+
+static struct resource kirkwood_cpuidle_resource[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ .start = DDR_OPERATION_BASE,
+ .end = DDR_OPERATION_BASE + 3,
+ },
+};
+
+static struct platform_device kirkwood_cpuidle = {
+ .name = "kirkwood_cpuidle",
+ .id = -1,
+ .resource = kirkwood_cpuidle_resource,
+ .num_resources = 1,
+};
+
+static void __init kirkwood_cpuidle_init(void)
+{
+ platform_device_register(&kirkwood_cpuidle);
+}
+
+#define MV643XX_ETH_MAC_ADDR_LOW 0x0414
+#define MV643XX_ETH_MAC_ADDR_HIGH 0x0418
+
+static void __init kirkwood_dt_eth_fixup(void)
+{
+ struct device_node *np;
+
+ /*
+ * The ethernet interfaces forget the MAC address assigned by u-boot
+ * if the clocks are turned off. Usually, u-boot on kirkwood boards
+ * has no DT support to properly set local-mac-address property.
+ * As a workaround, we get the MAC address from mv643xx_eth registers
+ * and update the port device node if no valid MAC address is set.
+ */
+ for_each_compatible_node(np, NULL, "marvell,kirkwood-eth-port") {
+ struct device_node *pnp = of_get_parent(np);
+ struct clk *clk;
+ struct property *pmac;
+ void __iomem *io;
+ u8 *macaddr;
+ u32 reg;
+
+ if (!pnp)
+ continue;
+
+ /* skip disabled nodes or nodes with valid MAC address*/
+ if (!of_device_is_available(pnp) || of_get_mac_address(np))
+ goto eth_fixup_skip;
+
+ clk = of_clk_get(pnp, 0);
+ if (IS_ERR(clk))
+ goto eth_fixup_skip;
+
+ io = of_iomap(pnp, 0);
+ if (!io)
+ goto eth_fixup_no_map;
+
+ /* ensure port clock is not gated to not hang CPU */
+ clk_prepare_enable(clk);
+
+ /* store MAC address register contents in local-mac-address */
+ pr_err(FW_INFO "%s: local-mac-address is not set\n",
+ np->full_name);
+
+ pmac = kzalloc(sizeof(*pmac) + 6, GFP_KERNEL);
+ if (!pmac)
+ goto eth_fixup_no_mem;
+
+ pmac->value = pmac + 1;
+ pmac->length = 6;
+ pmac->name = kstrdup("local-mac-address", GFP_KERNEL);
+ if (!pmac->name) {
+ kfree(pmac);
+ goto eth_fixup_no_mem;
+ }
+
+ macaddr = pmac->value;
+ reg = readl(io + MV643XX_ETH_MAC_ADDR_HIGH);
+ macaddr[0] = (reg >> 24) & 0xff;
+ macaddr[1] = (reg >> 16) & 0xff;
+ macaddr[2] = (reg >> 8) & 0xff;
+ macaddr[3] = reg & 0xff;
+
+ reg = readl(io + MV643XX_ETH_MAC_ADDR_LOW);
+ macaddr[4] = (reg >> 8) & 0xff;
+ macaddr[5] = reg & 0xff;
+
+ of_update_property(np, pmac);
+
+eth_fixup_no_mem:
+ iounmap(io);
+ clk_disable_unprepare(clk);
+eth_fixup_no_map:
+ clk_put(clk);
+eth_fixup_skip:
+ of_node_put(pnp);
+ }
+}
+
+/*
+ * 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.
+ */
+void kirkwood_disable_mbus_error_propagation(void)
+{
+ void __iomem *cpu_config;
+
+ cpu_config = ioremap(CPU_CONFIG_PHYS, 4);
+ writel(readl(cpu_config) & ~CPU_CONFIG_ERROR_PROP, cpu_config);
+}
+
+static struct of_dev_auxdata auxdata[] __initdata = {
+ OF_DEV_AUXDATA("marvell,kirkwood-audio", 0xf10a0000,
+ "mvebu-audio", NULL),
+ { /* sentinel */ }
+};
+
+static void __init kirkwood_dt_init(void)
+{
+ kirkwood_disable_mbus_error_propagation();
+
+ BUG_ON(mvebu_mbus_dt_init(false));
+
+#ifdef CONFIG_CACHE_FEROCEON_L2
+ feroceon_of_init();
+#endif
+ kirkwood_cpufreq_init();
+ kirkwood_cpuidle_init();
+
+ kirkwood_pm_init();
+ kirkwood_dt_eth_fixup();
+
+ if (of_machine_is_compatible("lacie,netxbig"))
+ netxbig_init();
+
+ of_platform_populate(NULL, of_default_bus_match_table, auxdata, NULL);
+}
+
+static const char * const kirkwood_dt_board_compat[] __initconst = {
+ "marvell,kirkwood",
+ NULL
+};
+
+DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)")
+ /* Maintainer: Jason Cooper <jason@lakedaemon.net> */
+ .init_machine = kirkwood_dt_init,
+ .restart = mvebu_restart,
+ .dt_compat = kirkwood_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-mvebu/kirkwood.h b/arch/arm/mach-mvebu/kirkwood.h
new file mode 100644
index 000000000..89f3d1f51
--- /dev/null
+++ b/arch/arm/mach-mvebu/kirkwood.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-mvebu/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.
+ */
+
+#define KIRKWOOD_REGS_PHYS_BASE 0xf1000000
+#define DDR_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x00000)
+#define BRIDGE_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x20000)
+
+#define DDR_OPERATION_BASE (DDR_PHYS_BASE + 0x1418)
+
+#define CPU_CONFIG_PHYS (BRIDGE_PHYS_BASE + 0x0100)
+#define CPU_CONFIG_ERROR_PROP 0x00000004
+
+#define CPU_CONTROL_PHYS (BRIDGE_PHYS_BASE + 0x0104)
+#define MEMORY_PM_CTRL_PHYS (BRIDGE_PHYS_BASE + 0x0118)
diff --git a/arch/arm/mach-mvebu/mvebu-soc-id.c b/arch/arm/mach-mvebu/mvebu-soc-id.c
new file mode 100644
index 000000000..a99434bce
--- /dev/null
+++ b/arch/arm/mach-mvebu/mvebu-soc-id.c
@@ -0,0 +1,178 @@
+/*
+ * ID and revision information for mvebu SoCs
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.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.
+ *
+ * All the mvebu SoCs have information related to their variant and
+ * revision that can be read from the PCI control register. This is
+ * done before the PCI initialization to avoid any conflict. Once the
+ * ID and revision are retrieved, the mapping is freed.
+ */
+
+#define pr_fmt(fmt) "mvebu-soc-id: " fmt
+
+#include <linux/clk.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+#include "common.h"
+#include "mvebu-soc-id.h"
+
+#define PCIE_DEV_ID_OFF 0x0
+#define PCIE_DEV_REV_OFF 0x8
+
+#define SOC_ID_MASK 0xFFFF0000
+#define SOC_REV_MASK 0xFF
+
+static u32 soc_dev_id;
+static u32 soc_rev;
+static bool is_id_valid;
+
+static const struct of_device_id mvebu_pcie_of_match_table[] = {
+ { .compatible = "marvell,armada-xp-pcie", },
+ { .compatible = "marvell,armada-370-pcie", },
+ { .compatible = "marvell,kirkwood-pcie" },
+ {},
+};
+
+int mvebu_get_soc_id(u32 *dev, u32 *rev)
+{
+ if (is_id_valid) {
+ *dev = soc_dev_id;
+ *rev = soc_rev;
+ return 0;
+ } else
+ return -ENODEV;
+}
+
+static int __init get_soc_id_by_pci(void)
+{
+ struct device_node *np;
+ int ret = 0;
+ void __iomem *pci_base;
+ struct clk *clk;
+ struct device_node *child;
+
+ np = of_find_matching_node(NULL, mvebu_pcie_of_match_table);
+ if (!np)
+ return ret;
+
+ /*
+ * ID and revision are available from any port, so we
+ * just pick the first one
+ */
+ child = of_get_next_child(np, NULL);
+ if (child == NULL) {
+ pr_err("cannot get pci node\n");
+ ret = -ENOMEM;
+ goto clk_err;
+ }
+
+ clk = of_clk_get_by_name(child, NULL);
+ if (IS_ERR(clk)) {
+ pr_err("cannot get clock\n");
+ ret = -ENOMEM;
+ goto clk_err;
+ }
+
+ ret = clk_prepare_enable(clk);
+ if (ret) {
+ pr_err("cannot enable clock\n");
+ goto clk_err;
+ }
+
+ pci_base = of_iomap(child, 0);
+ if (pci_base == NULL) {
+ pr_err("cannot map registers\n");
+ ret = -ENOMEM;
+ goto res_ioremap;
+ }
+
+ /* SoC ID */
+ soc_dev_id = readl(pci_base + PCIE_DEV_ID_OFF) >> 16;
+
+ /* SoC revision */
+ soc_rev = readl(pci_base + PCIE_DEV_REV_OFF) & SOC_REV_MASK;
+
+ is_id_valid = true;
+
+ pr_info("MVEBU SoC ID=0x%X, Rev=0x%X\n", soc_dev_id, soc_rev);
+
+ iounmap(pci_base);
+
+res_ioremap:
+ /*
+ * If the PCIe unit is actually enabled and we have PCI
+ * support in the kernel, we intentionally do not release the
+ * reference to the clock. We want to keep it running since
+ * the bootloader does some PCIe link configuration that the
+ * kernel is for now unable to do, and gating the clock would
+ * make us loose this precious configuration.
+ */
+ if (!of_device_is_available(child) || !IS_ENABLED(CONFIG_PCI_MVEBU)) {
+ clk_disable_unprepare(clk);
+ clk_put(clk);
+ }
+
+clk_err:
+ of_node_put(child);
+ of_node_put(np);
+
+ return ret;
+}
+
+static int __init mvebu_soc_id_init(void)
+{
+
+ /*
+ * First try to get the ID and the revision by the system
+ * register and use PCI registers only if it is not possible
+ */
+ if (!mvebu_system_controller_get_soc_id(&soc_dev_id, &soc_rev)) {
+ is_id_valid = true;
+ pr_info("MVEBU SoC ID=0x%X, Rev=0x%X\n", soc_dev_id, soc_rev);
+ return 0;
+ }
+
+ return get_soc_id_by_pci();
+}
+early_initcall(mvebu_soc_id_init);
+
+static int __init mvebu_soc_device(void)
+{
+ struct soc_device_attribute *soc_dev_attr;
+ struct soc_device *soc_dev;
+
+ /* Also protects against running on non-mvebu systems */
+ if (!is_id_valid)
+ return 0;
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ return -ENOMEM;
+
+ soc_dev_attr->family = kasprintf(GFP_KERNEL, "Marvell");
+ soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%X", soc_rev);
+ soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%X", soc_dev_id);
+
+ soc_dev = soc_device_register(soc_dev_attr);
+ if (IS_ERR(soc_dev)) {
+ kfree(soc_dev_attr->family);
+ kfree(soc_dev_attr->revision);
+ kfree(soc_dev_attr->soc_id);
+ kfree(soc_dev_attr);
+ }
+
+ return 0;
+}
+postcore_initcall(mvebu_soc_device);
diff --git a/arch/arm/mach-mvebu/mvebu-soc-id.h b/arch/arm/mach-mvebu/mvebu-soc-id.h
new file mode 100644
index 000000000..e124a0b82
--- /dev/null
+++ b/arch/arm/mach-mvebu/mvebu-soc-id.h
@@ -0,0 +1,54 @@
+/*
+ * Marvell EBU SoC ID and revision definitions.
+ *
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef __LINUX_MVEBU_SOC_ID_H
+#define __LINUX_MVEBU_SOC_ID_H
+
+/* Armada XP ID */
+#define MV78230_DEV_ID 0x7823
+#define MV78260_DEV_ID 0x7826
+#define MV78460_DEV_ID 0x7846
+
+/* Armada XP Revision */
+#define MV78XX0_A0_REV 0x1
+#define MV78XX0_B0_REV 0x2
+
+/* Amada 370 ID */
+#define ARMADA_370_DEV_ID 0x6710
+
+/* Amada 370 Revision */
+#define ARMADA_370_A1_REV 0x1
+
+/* Armada 375 ID */
+#define ARMADA_375_DEV_ID 0x6720
+
+/* Armada 375 */
+#define ARMADA_375_Z1_REV 0x0
+#define ARMADA_375_A0_REV 0x3
+
+/* Armada 38x ID */
+#define ARMADA_380_DEV_ID 0x6810
+#define ARMADA_385_DEV_ID 0x6820
+#define ARMADA_388_DEV_ID 0x6828
+
+/* Armada 38x Revision */
+#define ARMADA_38x_Z1_REV 0x0
+#define ARMADA_38x_A0_REV 0x4
+
+#ifdef CONFIG_ARCH_MVEBU
+int mvebu_get_soc_id(u32 *dev, u32 *rev);
+#else
+static inline int mvebu_get_soc_id(u32 *dev, u32 *rev)
+{
+ return -1;
+}
+#endif
+
+#endif /* __LINUX_MVEBU_SOC_ID_H */
diff --git a/arch/arm/mach-mvebu/netxbig.c b/arch/arm/mach-mvebu/netxbig.c
new file mode 100644
index 000000000..94b11b658
--- /dev/null
+++ b/arch/arm/mach-mvebu/netxbig.c
@@ -0,0 +1,191 @@
+/*
+ * arch/arm/mach-mvbu/board-netxbig.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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/leds-kirkwood-netxbig.h>
+#include "common.h"
+
+/*****************************************************************************
+ * 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:sata4", 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,
+ },
+};
+
+void __init netxbig_init(void)
+{
+
+ if (of_machine_is_compatible("lacie,net5big_v2"))
+ netxbig_v2_leds.dev.platform_data = &net5big_v2_leds_data;
+ platform_device_register(&netxbig_v2_leds);
+}
diff --git a/arch/arm/mach-mvebu/platsmp-a9.c b/arch/arm/mach-mvebu/platsmp-a9.c
new file mode 100644
index 000000000..df0a9cc5d
--- /dev/null
+++ b/arch/arm/mach-mvebu/platsmp-a9.c
@@ -0,0 +1,114 @@
+/*
+ * Symmetric Multi Processing (SMP) support for Marvell EBU Cortex-A9
+ * based SOCs (Armada 375/38x).
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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/io.h>
+#include <linux/of.h>
+#include <linux/smp.h>
+#include <linux/mbus.h>
+#include <asm/smp_scu.h>
+#include <asm/smp_plat.h>
+#include "common.h"
+#include "pmsu.h"
+
+extern void mvebu_cortex_a9_secondary_startup(void);
+
+static int __cpuinit mvebu_cortex_a9_boot_secondary(unsigned int cpu,
+ struct task_struct *idle)
+{
+ int ret, hw_cpu;
+
+ pr_info("Booting CPU %d\n", cpu);
+
+ /*
+ * 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.
+ */
+ hw_cpu = cpu_logical_map(cpu);
+ if (of_machine_is_compatible("marvell,armada375"))
+ mvebu_system_controller_set_cpu_boot_addr(mvebu_cortex_a9_secondary_startup);
+ else
+ mvebu_pmsu_set_cpu_boot_addr(hw_cpu, mvebu_cortex_a9_secondary_startup);
+ smp_wmb();
+
+ /*
+ * Doing this before deasserting the CPUs is needed to wake up CPUs
+ * in the offline state after using CPU hotplug.
+ */
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+ ret = mvebu_cpu_reset_deassert(hw_cpu);
+ if (ret) {
+ pr_err("Could not start the secondary CPU: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+/*
+ * When a CPU is brought back online, either through CPU hotplug, or
+ * because of the boot of a kexec'ed kernel, the PMSU configuration
+ * for this CPU might be in the deep idle state, preventing this CPU
+ * from receiving interrupts. Here, we therefore take out the current
+ * CPU from this state, which was entered by armada_38x_cpu_die()
+ * below.
+ */
+static void armada_38x_secondary_init(unsigned int cpu)
+{
+ mvebu_v7_pmsu_idle_exit();
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void armada_38x_cpu_die(unsigned int cpu)
+{
+ /*
+ * CPU hotplug is implemented by putting offline CPUs into the
+ * deep idle sleep state.
+ */
+ armada_38x_do_cpu_suspend(true);
+}
+
+/*
+ * We need a dummy function, so that platform_can_cpu_hotplug() knows
+ * we support CPU hotplug. However, the function does not need to do
+ * anything, because CPUs going offline can enter the deep idle state
+ * by themselves, without any help from a still alive CPU.
+ */
+static int armada_38x_cpu_kill(unsigned int cpu)
+{
+ return 1;
+}
+#endif
+
+static struct smp_operations mvebu_cortex_a9_smp_ops __initdata = {
+ .smp_boot_secondary = mvebu_cortex_a9_boot_secondary,
+};
+
+static struct smp_operations armada_38x_smp_ops __initdata = {
+ .smp_boot_secondary = mvebu_cortex_a9_boot_secondary,
+ .smp_secondary_init = armada_38x_secondary_init,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = armada_38x_cpu_die,
+ .cpu_kill = armada_38x_cpu_kill,
+#endif
+};
+
+CPU_METHOD_OF_DECLARE(mvebu_armada_375_smp, "marvell,armada-375-smp",
+ &mvebu_cortex_a9_smp_ops);
+CPU_METHOD_OF_DECLARE(mvebu_armada_380_smp, "marvell,armada-380-smp",
+ &armada_38x_smp_ops);
+CPU_METHOD_OF_DECLARE(mvebu_armada_390_smp, "marvell,armada-390-smp",
+ &armada_38x_smp_ops);
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
new file mode 100644
index 000000000..58cc8c157
--- /dev/null
+++ b/arch/arm/mach-mvebu/platsmp.c
@@ -0,0 +1,185 @@
+/*
+ * Symmetric Multi Processing (SMP) support for Armada XP
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Yehuda Yitschak <yehuday@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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.
+ *
+ * The Armada XP SoC has 4 ARMv7 PJ4B CPUs running in full HW coherency
+ * This file implements the routines for preparing the SMP infrastructure
+ * and waking up the secondary CPUs
+ */
+
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/mbus.h>
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include "common.h"
+#include "armada-370-xp.h"
+#include "pmsu.h"
+#include "coherency.h"
+
+#define ARMADA_XP_MAX_CPUS 4
+
+#define AXP_BOOTROM_BASE 0xfff00000
+#define AXP_BOOTROM_SIZE 0x100000
+
+static struct clk *get_cpu_clk(int cpu)
+{
+ struct clk *cpu_clk;
+ struct device_node *np = of_get_cpu_node(cpu, NULL);
+
+ if (WARN(!np, "missing cpu node\n"))
+ return NULL;
+ cpu_clk = of_clk_get(np, 0);
+ if (WARN_ON(IS_ERR(cpu_clk)))
+ return NULL;
+ return cpu_clk;
+}
+
+static void set_secondary_cpu_clock(unsigned int cpu)
+{
+ int thiscpu;
+ unsigned long rate;
+ struct clk *cpu_clk;
+
+ thiscpu = get_cpu();
+
+ cpu_clk = get_cpu_clk(thiscpu);
+ if (!cpu_clk)
+ goto out;
+ clk_prepare_enable(cpu_clk);
+ rate = clk_get_rate(cpu_clk);
+
+ cpu_clk = get_cpu_clk(cpu);
+ if (!cpu_clk)
+ goto out;
+ clk_set_rate(cpu_clk, rate);
+ clk_prepare_enable(cpu_clk);
+
+out:
+ put_cpu();
+}
+
+static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ int ret, hw_cpu;
+
+ pr_info("Booting CPU %d\n", cpu);
+
+ hw_cpu = cpu_logical_map(cpu);
+ set_secondary_cpu_clock(hw_cpu);
+ mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_xp_secondary_startup);
+
+ /*
+ * This is needed to wake up CPUs in the offline state after
+ * using CPU hotplug.
+ */
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+ /*
+ * This is needed to take secondary CPUs out of reset on the
+ * initial boot.
+ */
+ ret = mvebu_cpu_reset_deassert(hw_cpu);
+ if (ret) {
+ pr_warn("unable to boot CPU: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * When a CPU is brought back online, either through CPU hotplug, or
+ * because of the boot of a kexec'ed kernel, the PMSU configuration
+ * for this CPU might be in the deep idle state, preventing this CPU
+ * from receiving interrupts. Here, we therefore take out the current
+ * CPU from this state, which was entered by armada_xp_cpu_die()
+ * below.
+ */
+static void armada_xp_secondary_init(unsigned int cpu)
+{
+ mvebu_v7_pmsu_idle_exit();
+}
+
+static void __init armada_xp_smp_init_cpus(void)
+{
+ unsigned int ncores = num_possible_cpus();
+
+ if (ncores == 0 || ncores > ARMADA_XP_MAX_CPUS)
+ panic("Invalid number of CPUs in DT\n");
+}
+
+static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
+{
+ struct device_node *node;
+ struct resource res;
+ int err;
+
+ flush_cache_all();
+ set_cpu_coherent();
+
+ /*
+ * In order to boot the secondary CPUs we need to ensure
+ * the bootROM is mapped at the correct address.
+ */
+ node = of_find_compatible_node(NULL, NULL, "marvell,bootrom");
+ if (!node)
+ panic("Cannot find 'marvell,bootrom' compatible node");
+
+ err = of_address_to_resource(node, 0, &res);
+ if (err < 0)
+ panic("Cannot get 'bootrom' node address");
+
+ if (res.start != AXP_BOOTROM_BASE ||
+ resource_size(&res) != AXP_BOOTROM_SIZE)
+ panic("The address for the BootROM is incorrect");
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void armada_xp_cpu_die(unsigned int cpu)
+{
+ /*
+ * CPU hotplug is implemented by putting offline CPUs into the
+ * deep idle sleep state.
+ */
+ armada_370_xp_pmsu_idle_enter(true);
+}
+
+/*
+ * We need a dummy function, so that platform_can_cpu_hotplug() knows
+ * we support CPU hotplug. However, the function does not need to do
+ * anything, because CPUs going offline can enter the deep idle state
+ * by themselves, without any help from a still alive CPU.
+ */
+static int armada_xp_cpu_kill(unsigned int cpu)
+{
+ return 1;
+}
+#endif
+
+struct smp_operations armada_xp_smp_ops __initdata = {
+ .smp_init_cpus = armada_xp_smp_init_cpus,
+ .smp_prepare_cpus = armada_xp_smp_prepare_cpus,
+ .smp_boot_secondary = armada_xp_boot_secondary,
+ .smp_secondary_init = armada_xp_secondary_init,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = armada_xp_cpu_die,
+ .cpu_kill = armada_xp_cpu_kill,
+#endif
+};
+
+CPU_METHOD_OF_DECLARE(armada_xp_smp, "marvell,armada-xp-smp",
+ &armada_xp_smp_ops);
diff --git a/arch/arm/mach-mvebu/pm-board.c b/arch/arm/mach-mvebu/pm-board.c
new file mode 100644
index 000000000..301ab38d3
--- /dev/null
+++ b/arch/arm/mach-mvebu/pm-board.c
@@ -0,0 +1,144 @@
+/*
+ * Board-level suspend/resume support.
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include "common.h"
+
+#define ARMADA_XP_GP_PIC_NR_GPIOS 3
+
+static void __iomem *gpio_ctrl;
+static int pic_gpios[ARMADA_XP_GP_PIC_NR_GPIOS];
+static int pic_raw_gpios[ARMADA_XP_GP_PIC_NR_GPIOS];
+
+static void mvebu_armada_xp_gp_pm_enter(void __iomem *sdram_reg, u32 srcmd)
+{
+ u32 reg, ackcmd;
+ int i;
+
+ /* Put 001 as value on the GPIOs */
+ reg = readl(gpio_ctrl);
+ for (i = 0; i < ARMADA_XP_GP_PIC_NR_GPIOS; i++)
+ reg &= ~BIT(pic_raw_gpios[i]);
+ reg |= BIT(pic_raw_gpios[0]);
+ writel(reg, gpio_ctrl);
+
+ /* Prepare writing 111 to the GPIOs */
+ ackcmd = readl(gpio_ctrl);
+ for (i = 0; i < ARMADA_XP_GP_PIC_NR_GPIOS; i++)
+ ackcmd |= BIT(pic_raw_gpios[i]);
+
+ srcmd = cpu_to_le32(srcmd);
+ ackcmd = cpu_to_le32(ackcmd);
+
+ /*
+ * Wait a while, the PIC needs quite a bit of time between the
+ * two GPIO commands.
+ */
+ mdelay(3000);
+
+ asm volatile (
+ /* Align to a cache line */
+ ".balign 32\n\t"
+
+ /* Enter self refresh */
+ "str %[srcmd], [%[sdram_reg]]\n\t"
+
+ /*
+ * Wait 100 cycles for DDR to enter self refresh, by
+ * doing 50 times two instructions.
+ */
+ "mov r1, #50\n\t"
+ "1: subs r1, r1, #1\n\t"
+ "bne 1b\n\t"
+
+ /* Issue the command ACK */
+ "str %[ackcmd], [%[gpio_ctrl]]\n\t"
+
+ /* Trap the processor */
+ "b .\n\t"
+ : : [srcmd] "r" (srcmd), [sdram_reg] "r" (sdram_reg),
+ [ackcmd] "r" (ackcmd), [gpio_ctrl] "r" (gpio_ctrl) : "r1");
+}
+
+static int mvebu_armada_xp_gp_pm_init(void)
+{
+ struct device_node *np;
+ struct device_node *gpio_ctrl_np;
+ int ret = 0, i;
+
+ if (!of_machine_is_compatible("marvell,axp-gp"))
+ return -ENODEV;
+
+ np = of_find_node_by_name(NULL, "pm_pic");
+ if (!np)
+ return -ENODEV;
+
+ for (i = 0; i < ARMADA_XP_GP_PIC_NR_GPIOS; i++) {
+ char *name;
+ struct of_phandle_args args;
+
+ pic_gpios[i] = of_get_named_gpio(np, "ctrl-gpios", i);
+ if (pic_gpios[i] < 0) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ name = kasprintf(GFP_KERNEL, "pic-pin%d", i);
+ if (!name) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = gpio_request(pic_gpios[i], name);
+ if (ret < 0) {
+ kfree(name);
+ goto out;
+ }
+
+ ret = gpio_direction_output(pic_gpios[i], 0);
+ if (ret < 0) {
+ gpio_free(pic_gpios[i]);
+ kfree(name);
+ goto out;
+ }
+
+ ret = of_parse_phandle_with_fixed_args(np, "ctrl-gpios", 2,
+ i, &args);
+ if (ret < 0) {
+ gpio_free(pic_gpios[i]);
+ kfree(name);
+ goto out;
+ }
+
+ gpio_ctrl_np = args.np;
+ pic_raw_gpios[i] = args.args[0];
+ }
+
+ gpio_ctrl = of_iomap(gpio_ctrl_np, 0);
+ if (!gpio_ctrl)
+ return -ENOMEM;
+
+ mvebu_pm_init(mvebu_armada_xp_gp_pm_enter);
+
+out:
+ of_node_put(np);
+ return ret;
+}
+
+late_initcall(mvebu_armada_xp_gp_pm_init);
diff --git a/arch/arm/mach-mvebu/pm.c b/arch/arm/mach-mvebu/pm.c
new file mode 100644
index 000000000..6573a8f11
--- /dev/null
+++ b/arch/arm/mach-mvebu/pm.c
@@ -0,0 +1,218 @@
+/*
+ * Suspend/resume support. Currently supporting Armada XP only.
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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/cpu_pm.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mbus.h>
+#include <linux/of_address.h>
+#include <linux/suspend.h>
+#include <asm/cacheflush.h>
+#include <asm/outercache.h>
+#include <asm/suspend.h>
+
+#include "coherency.h"
+#include "pmsu.h"
+
+#define SDRAM_CONFIG_OFFS 0x0
+#define SDRAM_CONFIG_SR_MODE_BIT BIT(24)
+#define SDRAM_OPERATION_OFFS 0x18
+#define SDRAM_OPERATION_SELF_REFRESH 0x7
+#define SDRAM_DLB_EVICTION_OFFS 0x30c
+#define SDRAM_DLB_EVICTION_THRESHOLD_MASK 0xff
+
+static void (*mvebu_board_pm_enter)(void __iomem *sdram_reg, u32 srcmd);
+static void __iomem *sdram_ctrl;
+
+static int mvebu_pm_powerdown(unsigned long data)
+{
+ u32 reg, srcmd;
+
+ flush_cache_all();
+ outer_flush_all();
+
+ /*
+ * Issue a Data Synchronization Barrier instruction to ensure
+ * that all state saving has been completed.
+ */
+ dsb();
+
+ /* Flush the DLB and wait ~7 usec */
+ reg = readl(sdram_ctrl + SDRAM_DLB_EVICTION_OFFS);
+ reg &= ~SDRAM_DLB_EVICTION_THRESHOLD_MASK;
+ writel(reg, sdram_ctrl + SDRAM_DLB_EVICTION_OFFS);
+
+ udelay(7);
+
+ /* Set DRAM in battery backup mode */
+ reg = readl(sdram_ctrl + SDRAM_CONFIG_OFFS);
+ reg &= ~SDRAM_CONFIG_SR_MODE_BIT;
+ writel(reg, sdram_ctrl + SDRAM_CONFIG_OFFS);
+
+ /* Prepare to go to self-refresh */
+
+ srcmd = readl(sdram_ctrl + SDRAM_OPERATION_OFFS);
+ srcmd &= ~0x1F;
+ srcmd |= SDRAM_OPERATION_SELF_REFRESH;
+
+ mvebu_board_pm_enter(sdram_ctrl + SDRAM_OPERATION_OFFS, srcmd);
+
+ return 0;
+}
+
+#define BOOT_INFO_ADDR 0x3000
+#define BOOT_MAGIC_WORD 0xdeadb002
+#define BOOT_MAGIC_LIST_END 0xffffffff
+
+/*
+ * Those registers are accessed before switching the internal register
+ * base, which is why we hardcode the 0xd0000000 base address, the one
+ * used by the SoC out of reset.
+ */
+#define MBUS_WINDOW_12_CTRL 0xd00200b0
+#define MBUS_INTERNAL_REG_ADDRESS 0xd0020080
+
+#define SDRAM_WIN_BASE_REG(x) (0x20180 + (0x8*x))
+#define SDRAM_WIN_CTRL_REG(x) (0x20184 + (0x8*x))
+
+static phys_addr_t mvebu_internal_reg_base(void)
+{
+ struct device_node *np;
+ __be32 in_addr[2];
+
+ np = of_find_node_by_name(NULL, "internal-regs");
+ BUG_ON(!np);
+
+ /*
+ * Ask the DT what is the internal register address on this
+ * platform. In the mvebu-mbus DT binding, 0xf0010000
+ * corresponds to the internal register window.
+ */
+ in_addr[0] = cpu_to_be32(0xf0010000);
+ in_addr[1] = 0x0;
+
+ return of_translate_address(np, in_addr);
+}
+
+static void mvebu_pm_store_bootinfo(void)
+{
+ u32 *store_addr;
+ phys_addr_t resume_pc;
+
+ store_addr = phys_to_virt(BOOT_INFO_ADDR);
+ resume_pc = virt_to_phys(armada_370_xp_cpu_resume);
+
+ /*
+ * The bootloader expects the first two words to be a magic
+ * value (BOOT_MAGIC_WORD), followed by the address of the
+ * resume code to jump to. Then, it expects a sequence of
+ * (address, value) pairs, which can be used to restore the
+ * value of certain registers. This sequence must end with the
+ * BOOT_MAGIC_LIST_END magic value.
+ */
+
+ writel(BOOT_MAGIC_WORD, store_addr++);
+ writel(resume_pc, store_addr++);
+
+ /*
+ * Some platforms remap their internal register base address
+ * to 0xf1000000. However, out of reset, window 12 starts at
+ * 0xf0000000 and ends at 0xf7ffffff, which would overlap with
+ * the internal registers. Therefore, disable window 12.
+ */
+ writel(MBUS_WINDOW_12_CTRL, store_addr++);
+ writel(0x0, store_addr++);
+
+ /*
+ * Set the internal register base address to the value
+ * expected by Linux, as read from the Device Tree.
+ */
+ writel(MBUS_INTERNAL_REG_ADDRESS, store_addr++);
+ writel(mvebu_internal_reg_base(), store_addr++);
+
+ /*
+ * Ask the mvebu-mbus driver to store the SDRAM window
+ * configuration, which has to be restored by the bootloader
+ * before re-entering the kernel on resume.
+ */
+ store_addr += mvebu_mbus_save_cpu_target(store_addr);
+
+ writel(BOOT_MAGIC_LIST_END, store_addr);
+}
+
+static int mvebu_pm_enter(suspend_state_t state)
+{
+ if (state != PM_SUSPEND_MEM)
+ return -EINVAL;
+
+ cpu_pm_enter();
+
+ mvebu_pm_store_bootinfo();
+ cpu_suspend(0, mvebu_pm_powerdown);
+
+ outer_resume();
+
+ mvebu_v7_pmsu_idle_exit();
+
+ set_cpu_coherent();
+
+ cpu_pm_exit();
+
+ return 0;
+}
+
+static const struct platform_suspend_ops mvebu_pm_ops = {
+ .enter = mvebu_pm_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+int mvebu_pm_init(void (*board_pm_enter)(void __iomem *sdram_reg, u32 srcmd))
+{
+ struct device_node *np;
+ struct resource res;
+
+ if (!of_machine_is_compatible("marvell,armadaxp"))
+ return -ENODEV;
+
+ np = of_find_compatible_node(NULL, NULL,
+ "marvell,armada-xp-sdram-controller");
+ if (!np)
+ return -ENODEV;
+
+ if (of_address_to_resource(np, 0, &res)) {
+ of_node_put(np);
+ return -ENODEV;
+ }
+
+ if (!request_mem_region(res.start, resource_size(&res),
+ np->full_name)) {
+ of_node_put(np);
+ return -EBUSY;
+ }
+
+ sdram_ctrl = ioremap(res.start, resource_size(&res));
+ if (!sdram_ctrl) {
+ release_mem_region(res.start, resource_size(&res));
+ of_node_put(np);
+ return -ENOMEM;
+ }
+
+ of_node_put(np);
+
+ mvebu_board_pm_enter = board_pm_enter;
+
+ suspend_set_ops(&mvebu_pm_ops);
+
+ return 0;
+}
diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
new file mode 100644
index 000000000..4f4e22206
--- /dev/null
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -0,0 +1,670 @@
+/*
+ * Power Management Service Unit(PMSU) support for Armada 370/XP platforms.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Yehuda Yitschak <yehuday@marvell.com>
+ * Gregory Clement <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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.
+ *
+ * The Armada 370 and Armada XP SOCs have a power management service
+ * unit which is responsible for powering down and waking up CPUs and
+ * other SOC units
+ */
+
+#define pr_fmt(fmt) "mvebu-pmsu: " fmt
+
+#include <linux/clk.h>
+#include <linux/cpu_pm.h>
+#include <linux/cpufreq-dt.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mbus.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/resource.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+#include <asm/smp_scu.h>
+#include <asm/smp_plat.h>
+#include <asm/suspend.h>
+#include <asm/tlbflush.h>
+#include "common.h"
+
+
+#define PMSU_BASE_OFFSET 0x100
+#define PMSU_REG_SIZE 0x1000
+
+/* PMSU MP registers */
+#define PMSU_CONTROL_AND_CONFIG(cpu) ((cpu * 0x100) + 0x104)
+#define PMSU_CONTROL_AND_CONFIG_DFS_REQ BIT(18)
+#define PMSU_CONTROL_AND_CONFIG_PWDDN_REQ BIT(16)
+#define PMSU_CONTROL_AND_CONFIG_L2_PWDDN BIT(20)
+
+#define PMSU_CPU_POWER_DOWN_CONTROL(cpu) ((cpu * 0x100) + 0x108)
+
+#define PMSU_CPU_POWER_DOWN_DIS_SNP_Q_SKIP BIT(0)
+
+#define PMSU_STATUS_AND_MASK(cpu) ((cpu * 0x100) + 0x10c)
+#define PMSU_STATUS_AND_MASK_CPU_IDLE_WAIT BIT(16)
+#define PMSU_STATUS_AND_MASK_SNP_Q_EMPTY_WAIT BIT(17)
+#define PMSU_STATUS_AND_MASK_IRQ_WAKEUP BIT(20)
+#define PMSU_STATUS_AND_MASK_FIQ_WAKEUP BIT(21)
+#define PMSU_STATUS_AND_MASK_DBG_WAKEUP BIT(22)
+#define PMSU_STATUS_AND_MASK_IRQ_MASK BIT(24)
+#define PMSU_STATUS_AND_MASK_FIQ_MASK BIT(25)
+
+#define PMSU_EVENT_STATUS_AND_MASK(cpu) ((cpu * 0x100) + 0x120)
+#define PMSU_EVENT_STATUS_AND_MASK_DFS_DONE BIT(1)
+#define PMSU_EVENT_STATUS_AND_MASK_DFS_DONE_MASK BIT(17)
+
+#define PMSU_BOOT_ADDR_REDIRECT_OFFSET(cpu) ((cpu * 0x100) + 0x124)
+
+/* PMSU fabric registers */
+#define L2C_NFABRIC_PM_CTL 0x4
+#define L2C_NFABRIC_PM_CTL_PWR_DOWN BIT(20)
+
+/* PMSU delay registers */
+#define PMSU_POWERDOWN_DELAY 0xF04
+#define PMSU_POWERDOWN_DELAY_PMU BIT(1)
+#define PMSU_POWERDOWN_DELAY_MASK 0xFFFE
+#define PMSU_DFLT_ARMADA38X_DELAY 0x64
+
+/* CA9 MPcore SoC Control registers */
+
+#define MPCORE_RESET_CTL 0x64
+#define MPCORE_RESET_CTL_L2 BIT(0)
+#define MPCORE_RESET_CTL_DEBUG BIT(16)
+
+#define SRAM_PHYS_BASE 0xFFFF0000
+#define BOOTROM_BASE 0xFFF00000
+#define BOOTROM_SIZE 0x100000
+
+#define ARMADA_370_CRYPT0_ENG_TARGET 0x9
+#define ARMADA_370_CRYPT0_ENG_ATTR 0x1
+
+extern void ll_disable_coherency(void);
+extern void ll_enable_coherency(void);
+
+extern void armada_370_xp_cpu_resume(void);
+extern void armada_38x_cpu_resume(void);
+
+static phys_addr_t pmsu_mp_phys_base;
+static void __iomem *pmsu_mp_base;
+
+static void *mvebu_cpu_resume;
+
+static const struct of_device_id of_pmsu_table[] = {
+ { .compatible = "marvell,armada-370-pmsu", },
+ { .compatible = "marvell,armada-370-xp-pmsu", },
+ { .compatible = "marvell,armada-380-pmsu", },
+ { /* end of list */ },
+};
+
+void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr)
+{
+ writel(virt_to_phys(boot_addr), pmsu_mp_base +
+ PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
+}
+
+extern unsigned char mvebu_boot_wa_start;
+extern unsigned char mvebu_boot_wa_end;
+
+/*
+ * This function sets up the boot address workaround needed for SMP
+ * boot on Armada 375 Z1 and cpuidle on Armada 370. It unmaps the
+ * BootROM Mbus window, and instead remaps a crypto SRAM into which a
+ * custom piece of code is copied to replace the problematic BootROM.
+ */
+int mvebu_setup_boot_addr_wa(unsigned int crypto_eng_target,
+ unsigned int crypto_eng_attribute,
+ phys_addr_t resume_addr_reg)
+{
+ void __iomem *sram_virt_base;
+ u32 code_len = &mvebu_boot_wa_end - &mvebu_boot_wa_start;
+
+ mvebu_mbus_del_window(BOOTROM_BASE, BOOTROM_SIZE);
+ mvebu_mbus_add_window_by_id(crypto_eng_target, crypto_eng_attribute,
+ SRAM_PHYS_BASE, SZ_64K);
+
+ sram_virt_base = ioremap(SRAM_PHYS_BASE, SZ_64K);
+ if (!sram_virt_base) {
+ pr_err("Unable to map SRAM to setup the boot address WA\n");
+ return -ENOMEM;
+ }
+
+ memcpy(sram_virt_base, &mvebu_boot_wa_start, code_len);
+
+ /*
+ * The last word of the code copied in SRAM must contain the
+ * physical base address of the PMSU register. We
+ * intentionally store this address in the native endianness
+ * of the system.
+ */
+ __raw_writel((unsigned long)resume_addr_reg,
+ sram_virt_base + code_len - 4);
+
+ iounmap(sram_virt_base);
+
+ return 0;
+}
+
+static int __init mvebu_v7_pmsu_init(void)
+{
+ struct device_node *np;
+ struct resource res;
+ int ret = 0;
+
+ np = of_find_matching_node(NULL, of_pmsu_table);
+ if (!np)
+ return 0;
+
+ pr_info("Initializing Power Management Service Unit\n");
+
+ if (of_address_to_resource(np, 0, &res)) {
+ pr_err("unable to get resource\n");
+ ret = -ENOENT;
+ goto out;
+ }
+
+ if (of_device_is_compatible(np, "marvell,armada-370-xp-pmsu")) {
+ pr_warn(FW_WARN "deprecated pmsu binding\n");
+ res.start = res.start - PMSU_BASE_OFFSET;
+ res.end = res.start + PMSU_REG_SIZE - 1;
+ }
+
+ if (!request_mem_region(res.start, resource_size(&res),
+ np->full_name)) {
+ pr_err("unable to request region\n");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ pmsu_mp_phys_base = res.start;
+
+ pmsu_mp_base = ioremap(res.start, resource_size(&res));
+ if (!pmsu_mp_base) {
+ pr_err("unable to map registers\n");
+ release_mem_region(res.start, resource_size(&res));
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ out:
+ of_node_put(np);
+ return ret;
+}
+
+static void mvebu_v7_pmsu_enable_l2_powerdown_onidle(void)
+{
+ u32 reg;
+
+ if (pmsu_mp_base == NULL)
+ return;
+
+ /* Enable L2 & Fabric powerdown in Deep-Idle mode - Fabric */
+ reg = readl(pmsu_mp_base + L2C_NFABRIC_PM_CTL);
+ reg |= L2C_NFABRIC_PM_CTL_PWR_DOWN;
+ writel(reg, pmsu_mp_base + L2C_NFABRIC_PM_CTL);
+}
+
+enum pmsu_idle_prepare_flags {
+ PMSU_PREPARE_NORMAL = 0,
+ PMSU_PREPARE_DEEP_IDLE = BIT(0),
+ PMSU_PREPARE_SNOOP_DISABLE = BIT(1),
+};
+
+/* No locking is needed because we only access per-CPU registers */
+static int mvebu_v7_pmsu_idle_prepare(unsigned long flags)
+{
+ unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
+ u32 reg;
+
+ if (pmsu_mp_base == NULL)
+ return -EINVAL;
+
+ /*
+ * Adjust the PMSU configuration to wait for WFI signal, enable
+ * IRQ and FIQ as wakeup events, set wait for snoop queue empty
+ * indication and mask IRQ and FIQ from CPU
+ */
+ reg = readl(pmsu_mp_base + PMSU_STATUS_AND_MASK(hw_cpu));
+ reg |= PMSU_STATUS_AND_MASK_CPU_IDLE_WAIT |
+ PMSU_STATUS_AND_MASK_IRQ_WAKEUP |
+ PMSU_STATUS_AND_MASK_FIQ_WAKEUP |
+ PMSU_STATUS_AND_MASK_SNP_Q_EMPTY_WAIT |
+ PMSU_STATUS_AND_MASK_IRQ_MASK |
+ PMSU_STATUS_AND_MASK_FIQ_MASK;
+ writel(reg, pmsu_mp_base + PMSU_STATUS_AND_MASK(hw_cpu));
+
+ reg = readl(pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(hw_cpu));
+ /* ask HW to power down the L2 Cache if needed */
+ if (flags & PMSU_PREPARE_DEEP_IDLE)
+ reg |= PMSU_CONTROL_AND_CONFIG_L2_PWDDN;
+
+ /* request power down */
+ reg |= PMSU_CONTROL_AND_CONFIG_PWDDN_REQ;
+ writel(reg, pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(hw_cpu));
+
+ if (flags & PMSU_PREPARE_SNOOP_DISABLE) {
+ /* Disable snoop disable by HW - SW is taking care of it */
+ reg = readl(pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
+ reg |= PMSU_CPU_POWER_DOWN_DIS_SNP_Q_SKIP;
+ writel(reg, pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
+ }
+
+ return 0;
+}
+
+int armada_370_xp_pmsu_idle_enter(unsigned long deepidle)
+{
+ unsigned long flags = PMSU_PREPARE_SNOOP_DISABLE;
+ int ret;
+
+ if (deepidle)
+ flags |= PMSU_PREPARE_DEEP_IDLE;
+
+ ret = mvebu_v7_pmsu_idle_prepare(flags);
+ if (ret)
+ return ret;
+
+ v7_exit_coherency_flush(all);
+
+ ll_disable_coherency();
+
+ dsb();
+
+ wfi();
+
+ /* If we are here, wfi failed. As processors run out of
+ * coherency for some time, tlbs might be stale, so flush them
+ */
+ local_flush_tlb_all();
+
+ ll_enable_coherency();
+
+ /* Test the CR_C bit and set it if it was cleared */
+ asm volatile(
+ "mrc p15, 0, r0, c1, c0, 0 \n\t"
+ "tst r0, #(1 << 2) \n\t"
+ "orreq r0, r0, #(1 << 2) \n\t"
+ "mcreq p15, 0, r0, c1, c0, 0 \n\t"
+ "isb "
+ : : : "r0");
+
+ pr_debug("Failed to suspend the system\n");
+
+ return 0;
+}
+
+static int armada_370_xp_cpu_suspend(unsigned long deepidle)
+{
+ return cpu_suspend(deepidle, armada_370_xp_pmsu_idle_enter);
+}
+
+int armada_38x_do_cpu_suspend(unsigned long deepidle)
+{
+ unsigned long flags = 0;
+
+ if (deepidle)
+ flags |= PMSU_PREPARE_DEEP_IDLE;
+
+ mvebu_v7_pmsu_idle_prepare(flags);
+ /*
+ * Already flushed cache, but do it again as the outer cache
+ * functions dirty the cache with spinlocks
+ */
+ v7_exit_coherency_flush(louis);
+
+ scu_power_mode(mvebu_get_scu_base(), SCU_PM_POWEROFF);
+
+ cpu_do_idle();
+
+ return 1;
+}
+
+static int armada_38x_cpu_suspend(unsigned long deepidle)
+{
+ return cpu_suspend(false, armada_38x_do_cpu_suspend);
+}
+
+/* No locking is needed because we only access per-CPU registers */
+void mvebu_v7_pmsu_idle_exit(void)
+{
+ unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
+ u32 reg;
+
+ if (pmsu_mp_base == NULL)
+ return;
+ /* cancel ask HW to power down the L2 Cache if possible */
+ reg = readl(pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(hw_cpu));
+ reg &= ~PMSU_CONTROL_AND_CONFIG_L2_PWDDN;
+ writel(reg, pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(hw_cpu));
+
+ /* cancel Enable wakeup events and mask interrupts */
+ reg = readl(pmsu_mp_base + PMSU_STATUS_AND_MASK(hw_cpu));
+ reg &= ~(PMSU_STATUS_AND_MASK_IRQ_WAKEUP | PMSU_STATUS_AND_MASK_FIQ_WAKEUP);
+ reg &= ~PMSU_STATUS_AND_MASK_CPU_IDLE_WAIT;
+ reg &= ~PMSU_STATUS_AND_MASK_SNP_Q_EMPTY_WAIT;
+ reg &= ~(PMSU_STATUS_AND_MASK_IRQ_MASK | PMSU_STATUS_AND_MASK_FIQ_MASK);
+ writel(reg, pmsu_mp_base + PMSU_STATUS_AND_MASK(hw_cpu));
+}
+
+static int mvebu_v7_cpu_pm_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ if (action == CPU_PM_ENTER) {
+ unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
+ mvebu_pmsu_set_cpu_boot_addr(hw_cpu, mvebu_cpu_resume);
+ } else if (action == CPU_PM_EXIT) {
+ mvebu_v7_pmsu_idle_exit();
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block mvebu_v7_cpu_pm_notifier = {
+ .notifier_call = mvebu_v7_cpu_pm_notify,
+};
+
+static struct platform_device mvebu_v7_cpuidle_device;
+
+static __init int armada_370_cpuidle_init(void)
+{
+ struct device_node *np;
+ phys_addr_t redirect_reg;
+
+ np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
+ if (!np)
+ return -ENODEV;
+ of_node_put(np);
+
+ /*
+ * On Armada 370, there is "a slow exit process from the deep
+ * idle state due to heavy L1/L2 cache cleanup operations
+ * performed by the BootROM software". To avoid this, we
+ * replace the restart code of the bootrom by a a simple jump
+ * to the boot address. Then the code located at this boot
+ * address will take care of the initialization.
+ */
+ redirect_reg = pmsu_mp_phys_base + PMSU_BOOT_ADDR_REDIRECT_OFFSET(0);
+ mvebu_setup_boot_addr_wa(ARMADA_370_CRYPT0_ENG_TARGET,
+ ARMADA_370_CRYPT0_ENG_ATTR,
+ redirect_reg);
+
+ mvebu_cpu_resume = armada_370_xp_cpu_resume;
+ mvebu_v7_cpuidle_device.dev.platform_data = armada_370_xp_cpu_suspend;
+ mvebu_v7_cpuidle_device.name = "cpuidle-armada-370";
+
+ return 0;
+}
+
+static __init int armada_38x_cpuidle_init(void)
+{
+ struct device_node *np;
+ void __iomem *mpsoc_base;
+ u32 reg;
+
+ pr_warn("CPU idle is currently broken on Armada 38x: disabling");
+ return 0;
+
+ np = of_find_compatible_node(NULL, NULL,
+ "marvell,armada-380-coherency-fabric");
+ if (!np)
+ return -ENODEV;
+ of_node_put(np);
+
+ np = of_find_compatible_node(NULL, NULL,
+ "marvell,armada-380-mpcore-soc-ctrl");
+ if (!np)
+ return -ENODEV;
+ mpsoc_base = of_iomap(np, 0);
+ BUG_ON(!mpsoc_base);
+ of_node_put(np);
+
+ /* Set up reset mask when powering down the cpus */
+ reg = readl(mpsoc_base + MPCORE_RESET_CTL);
+ reg |= MPCORE_RESET_CTL_L2;
+ reg |= MPCORE_RESET_CTL_DEBUG;
+ writel(reg, mpsoc_base + MPCORE_RESET_CTL);
+ iounmap(mpsoc_base);
+
+ /* Set up delay */
+ reg = readl(pmsu_mp_base + PMSU_POWERDOWN_DELAY);
+ reg &= ~PMSU_POWERDOWN_DELAY_MASK;
+ reg |= PMSU_DFLT_ARMADA38X_DELAY;
+ reg |= PMSU_POWERDOWN_DELAY_PMU;
+ writel(reg, pmsu_mp_base + PMSU_POWERDOWN_DELAY);
+
+ mvebu_cpu_resume = armada_38x_cpu_resume;
+ mvebu_v7_cpuidle_device.dev.platform_data = armada_38x_cpu_suspend;
+ mvebu_v7_cpuidle_device.name = "cpuidle-armada-38x";
+
+ return 0;
+}
+
+static __init int armada_xp_cpuidle_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
+ if (!np)
+ return -ENODEV;
+ of_node_put(np);
+
+ mvebu_cpu_resume = armada_370_xp_cpu_resume;
+ mvebu_v7_cpuidle_device.dev.platform_data = armada_370_xp_cpu_suspend;
+ mvebu_v7_cpuidle_device.name = "cpuidle-armada-xp";
+
+ return 0;
+}
+
+static int __init mvebu_v7_cpu_pm_init(void)
+{
+ struct device_node *np;
+ int ret;
+
+ np = of_find_matching_node(NULL, of_pmsu_table);
+ if (!np)
+ return 0;
+ of_node_put(np);
+
+ /*
+ * Currently the CPU idle support for Armada 38x is broken, as
+ * the CPU hotplug uses some of the CPU idle functions it is
+ * broken too, so let's disable it
+ */
+ if (of_machine_is_compatible("marvell,armada380")) {
+ cpu_hotplug_disable();
+ pr_warn("CPU hotplug support is currently broken on Armada 38x: disabling");
+ }
+
+ if (of_machine_is_compatible("marvell,armadaxp"))
+ ret = armada_xp_cpuidle_init();
+ else if (of_machine_is_compatible("marvell,armada370"))
+ ret = armada_370_cpuidle_init();
+ else if (of_machine_is_compatible("marvell,armada380"))
+ ret = armada_38x_cpuidle_init();
+ else
+ return 0;
+
+ if (ret)
+ return ret;
+
+ mvebu_v7_pmsu_enable_l2_powerdown_onidle();
+ if (mvebu_v7_cpuidle_device.name)
+ platform_device_register(&mvebu_v7_cpuidle_device);
+ cpu_pm_register_notifier(&mvebu_v7_cpu_pm_notifier);
+
+ return 0;
+}
+
+arch_initcall(mvebu_v7_cpu_pm_init);
+early_initcall(mvebu_v7_pmsu_init);
+
+static void mvebu_pmsu_dfs_request_local(void *data)
+{
+ u32 reg;
+ u32 cpu = smp_processor_id();
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ /* Prepare to enter idle */
+ reg = readl(pmsu_mp_base + PMSU_STATUS_AND_MASK(cpu));
+ reg |= PMSU_STATUS_AND_MASK_CPU_IDLE_WAIT |
+ PMSU_STATUS_AND_MASK_IRQ_MASK |
+ PMSU_STATUS_AND_MASK_FIQ_MASK;
+ writel(reg, pmsu_mp_base + PMSU_STATUS_AND_MASK(cpu));
+
+ /* Request the DFS transition */
+ reg = readl(pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(cpu));
+ reg |= PMSU_CONTROL_AND_CONFIG_DFS_REQ;
+ writel(reg, pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(cpu));
+
+ /* The fact of entering idle will trigger the DFS transition */
+ wfi();
+
+ /*
+ * We're back from idle, the DFS transition has completed,
+ * clear the idle wait indication.
+ */
+ reg = readl(pmsu_mp_base + PMSU_STATUS_AND_MASK(cpu));
+ reg &= ~PMSU_STATUS_AND_MASK_CPU_IDLE_WAIT;
+ writel(reg, pmsu_mp_base + PMSU_STATUS_AND_MASK(cpu));
+
+ local_irq_restore(flags);
+}
+
+int mvebu_pmsu_dfs_request(int cpu)
+{
+ unsigned long timeout;
+ int hwcpu = cpu_logical_map(cpu);
+ u32 reg;
+
+ /* Clear any previous DFS DONE event */
+ reg = readl(pmsu_mp_base + PMSU_EVENT_STATUS_AND_MASK(hwcpu));
+ reg &= ~PMSU_EVENT_STATUS_AND_MASK_DFS_DONE;
+ writel(reg, pmsu_mp_base + PMSU_EVENT_STATUS_AND_MASK(hwcpu));
+
+ /* Mask the DFS done interrupt, since we are going to poll */
+ reg = readl(pmsu_mp_base + PMSU_EVENT_STATUS_AND_MASK(hwcpu));
+ reg |= PMSU_EVENT_STATUS_AND_MASK_DFS_DONE_MASK;
+ writel(reg, pmsu_mp_base + PMSU_EVENT_STATUS_AND_MASK(hwcpu));
+
+ /* Trigger the DFS on the appropriate CPU */
+ smp_call_function_single(cpu, mvebu_pmsu_dfs_request_local,
+ NULL, false);
+
+ /* Poll until the DFS done event is generated */
+ timeout = jiffies + HZ;
+ while (time_before(jiffies, timeout)) {
+ reg = readl(pmsu_mp_base + PMSU_EVENT_STATUS_AND_MASK(hwcpu));
+ if (reg & PMSU_EVENT_STATUS_AND_MASK_DFS_DONE)
+ break;
+ udelay(10);
+ }
+
+ if (time_after(jiffies, timeout))
+ return -ETIME;
+
+ /* Restore the DFS mask to its original state */
+ reg = readl(pmsu_mp_base + PMSU_EVENT_STATUS_AND_MASK(hwcpu));
+ reg &= ~PMSU_EVENT_STATUS_AND_MASK_DFS_DONE_MASK;
+ writel(reg, pmsu_mp_base + PMSU_EVENT_STATUS_AND_MASK(hwcpu));
+
+ return 0;
+}
+
+struct cpufreq_dt_platform_data cpufreq_dt_pd = {
+ .independent_clocks = true,
+};
+
+static int __init armada_xp_pmsu_cpufreq_init(void)
+{
+ struct device_node *np;
+ struct resource res;
+ int ret, cpu;
+
+ if (!of_machine_is_compatible("marvell,armadaxp"))
+ return 0;
+
+ /*
+ * In order to have proper cpufreq handling, we need to ensure
+ * that the Device Tree description of the CPU clock includes
+ * the definition of the PMU DFS registers. If not, we do not
+ * register the clock notifier and the cpufreq driver. This
+ * piece of code is only for compatibility with old Device
+ * Trees.
+ */
+ np = of_find_compatible_node(NULL, NULL, "marvell,armada-xp-cpu-clock");
+ if (!np)
+ return 0;
+
+ ret = of_address_to_resource(np, 1, &res);
+ if (ret) {
+ pr_warn(FW_WARN "not enabling cpufreq, deprecated armada-xp-cpu-clock binding\n");
+ of_node_put(np);
+ return 0;
+ }
+
+ of_node_put(np);
+
+ /*
+ * For each CPU, this loop registers the operating points
+ * supported (which are the nominal CPU frequency and half of
+ * it), and registers the clock notifier that will take care
+ * of doing the PMSU part of a frequency transition.
+ */
+ for_each_possible_cpu(cpu) {
+ struct device *cpu_dev;
+ struct clk *clk;
+ int ret;
+
+ cpu_dev = get_cpu_device(cpu);
+ if (!cpu_dev) {
+ pr_err("Cannot get CPU %d\n", cpu);
+ continue;
+ }
+
+ clk = clk_get(cpu_dev, 0);
+ if (IS_ERR(clk)) {
+ pr_err("Cannot get clock for CPU %d\n", cpu);
+ return PTR_ERR(clk);
+ }
+
+ /*
+ * In case of a failure of dev_pm_opp_add(), we don't
+ * bother with cleaning up the registered OPP (there's
+ * no function to do so), and simply cancel the
+ * registration of the cpufreq device.
+ */
+ ret = dev_pm_opp_add(cpu_dev, clk_get_rate(clk), 0);
+ if (ret) {
+ clk_put(clk);
+ return ret;
+ }
+
+ ret = dev_pm_opp_add(cpu_dev, clk_get_rate(clk) / 2, 0);
+ if (ret) {
+ clk_put(clk);
+ return ret;
+ }
+ }
+
+ platform_device_register_data(NULL, "cpufreq-dt", -1,
+ &cpufreq_dt_pd, sizeof(cpufreq_dt_pd));
+ return 0;
+}
+
+device_initcall(armada_xp_pmsu_cpufreq_init);
diff --git a/arch/arm/mach-mvebu/pmsu.h b/arch/arm/mach-mvebu/pmsu.h
new file mode 100644
index 000000000..ea79269c2
--- /dev/null
+++ b/arch/arm/mach-mvebu/pmsu.h
@@ -0,0 +1,24 @@
+/*
+ * Power Management Service Unit (PMSU) support for Armada 370/XP platforms.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * This file is licensed under the terms 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_MVEBU_PMSU_H
+#define __MACH_MVEBU_PMSU_H
+
+int armada_xp_boot_cpu(unsigned int cpu_id, void *phys_addr);
+int mvebu_setup_boot_addr_wa(unsigned int crypto_eng_target,
+ unsigned int crypto_eng_attribute,
+ phys_addr_t resume_addr_reg);
+
+void mvebu_v7_pmsu_idle_exit(void);
+void armada_370_xp_cpu_resume(void);
+
+int armada_370_xp_pmsu_idle_enter(unsigned long deepidle);
+int armada_38x_do_cpu_suspend(unsigned long deepidle);
+#endif /* __MACH_370_XP_PMSU_H */
diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S
new file mode 100644
index 000000000..88651221d
--- /dev/null
+++ b/arch/arm/mach-mvebu/pmsu_ll.S
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2014 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ * Gregory Clement <gregory.clement@free-electrons.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/linkage.h>
+#include <asm/assembler.h>
+
+
+ENTRY(armada_38x_scu_power_up)
+ mrc p15, 4, r1, c15, c0 @ get SCU base address
+ orr r1, r1, #0x8 @ SCU CPU Power Status Register
+ mrc 15, 0, r0, cr0, cr0, 5 @ get the CPU ID
+ and r0, r0, #15
+ add r1, r1, r0
+ mov r0, #0x0
+ strb r0, [r1] @ switch SCU power state to Normal mode
+ ret lr
+ENDPROC(armada_38x_scu_power_up)
+
+/*
+ * This is the entry point through which CPUs exiting cpuidle deep
+ * idle state are going.
+ */
+ENTRY(armada_370_xp_cpu_resume)
+ARM_BE8(setend be ) @ go BE8 if entered LE
+ /*
+ * Disable the MMU that might have been enabled in BootROM if
+ * this code is used in the resume path of a suspend/resume
+ * cycle.
+ */
+ mrc p15, 0, r1, c1, c0, 0
+ bic r1, #1
+ mcr p15, 0, r1, c1, c0, 0
+ bl ll_add_cpu_to_smp_group
+ bl ll_enable_coherency
+ b cpu_resume
+ENDPROC(armada_370_xp_cpu_resume)
+
+ENTRY(armada_38x_cpu_resume)
+ /* do we need it for Armada 38x*/
+ARM_BE8(setend be ) @ go BE8 if entered LE
+ bl v7_invalidate_l1
+ bl armada_38x_scu_power_up
+ b cpu_resume
+ENDPROC(armada_38x_cpu_resume)
+
+.global mvebu_boot_wa_start
+.global mvebu_boot_wa_end
+
+/* The following code will be executed from SRAM */
+ENTRY(mvebu_boot_wa_start)
+mvebu_boot_wa_start:
+ARM_BE8(setend be)
+ adr r0, 1f
+ ldr r0, [r0] @ load the address of the
+ @ resume register
+ ldr r0, [r0] @ load the value in the
+ @ resume register
+ARM_BE8(rev r0, r0) @ the value is stored LE
+ mov pc, r0 @ jump to this value
+/*
+ * the last word of this piece of code will be filled by the physical
+ * address of the boot address register just after being copied in SRAM
+ */
+1:
+ .long .
+mvebu_boot_wa_end:
+ENDPROC(mvebu_boot_wa_end)
diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c
new file mode 100644
index 000000000..c6c132acd
--- /dev/null
+++ b/arch/arm/mach-mvebu/system-controller.c
@@ -0,0 +1,180 @@
+/*
+ * System controller support for Armada 370, 375 and XP platforms.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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.
+ *
+ * The Armada 370, 375 and Armada XP SoCs have a range of
+ * miscellaneous registers, that do not belong to a particular device,
+ * but rather provide system-level features. This basic
+ * system-controller driver provides a device tree binding for those
+ * registers, and implements utility functions offering various
+ * features related to those registers.
+ *
+ * For now, the feature set is limited to restarting the platform by a
+ * soft-reset, but it might be extended in the future.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/reboot.h>
+#include "common.h"
+#include "mvebu-soc-id.h"
+#include "pmsu.h"
+
+#define ARMADA_375_CRYPT0_ENG_TARGET 41
+#define ARMADA_375_CRYPT0_ENG_ATTR 1
+
+static void __iomem *system_controller_base;
+static phys_addr_t system_controller_phys_base;
+
+struct mvebu_system_controller {
+ u32 rstoutn_mask_offset;
+ u32 system_soft_reset_offset;
+
+ u32 rstoutn_mask_reset_out_en;
+ u32 system_soft_reset;
+
+ u32 resume_boot_addr;
+
+ u32 dev_id;
+ u32 rev_id;
+};
+static struct mvebu_system_controller *mvebu_sc;
+
+static const struct mvebu_system_controller armada_370_xp_system_controller = {
+ .rstoutn_mask_offset = 0x60,
+ .system_soft_reset_offset = 0x64,
+ .rstoutn_mask_reset_out_en = 0x1,
+ .system_soft_reset = 0x1,
+ .dev_id = 0x38,
+ .rev_id = 0x3c,
+};
+
+static const struct mvebu_system_controller armada_375_system_controller = {
+ .rstoutn_mask_offset = 0x54,
+ .system_soft_reset_offset = 0x58,
+ .rstoutn_mask_reset_out_en = 0x1,
+ .system_soft_reset = 0x1,
+ .resume_boot_addr = 0xd4,
+ .dev_id = 0x38,
+ .rev_id = 0x3c,
+};
+
+static const struct mvebu_system_controller orion_system_controller = {
+ .rstoutn_mask_offset = 0x108,
+ .system_soft_reset_offset = 0x10c,
+ .rstoutn_mask_reset_out_en = 0x4,
+ .system_soft_reset = 0x1,
+};
+
+static const struct of_device_id of_system_controller_table[] = {
+ {
+ .compatible = "marvell,orion-system-controller",
+ .data = (void *) &orion_system_controller,
+ }, {
+ .compatible = "marvell,armada-370-xp-system-controller",
+ .data = (void *) &armada_370_xp_system_controller,
+ }, {
+ .compatible = "marvell,armada-375-system-controller",
+ .data = (void *) &armada_375_system_controller,
+ },
+ { /* end of list */ },
+};
+
+void mvebu_restart(enum reboot_mode mode, const char *cmd)
+{
+ if (!system_controller_base) {
+ pr_err("Cannot restart, system-controller not available: check the device tree\n");
+ } else {
+ /*
+ * Enable soft reset to assert RSTOUTn.
+ */
+ writel(mvebu_sc->rstoutn_mask_reset_out_en,
+ system_controller_base +
+ mvebu_sc->rstoutn_mask_offset);
+ /*
+ * Assert soft reset.
+ */
+ writel(mvebu_sc->system_soft_reset,
+ system_controller_base +
+ mvebu_sc->system_soft_reset_offset);
+ }
+
+ while (1)
+ ;
+}
+
+int mvebu_system_controller_get_soc_id(u32 *dev, u32 *rev)
+{
+ if (of_machine_is_compatible("marvell,armada380") &&
+ system_controller_base) {
+ *dev = readl(system_controller_base + mvebu_sc->dev_id) >> 16;
+ *rev = (readl(system_controller_base + mvebu_sc->rev_id) >> 8)
+ & 0xF;
+ return 0;
+ } else
+ return -ENODEV;
+}
+
+#if defined(CONFIG_SMP) && defined(CONFIG_MACH_MVEBU_V7)
+void mvebu_armada375_smp_wa_init(void)
+{
+ u32 dev, rev;
+ phys_addr_t resume_addr_reg;
+
+ if (mvebu_get_soc_id(&dev, &rev) != 0)
+ return;
+
+ if (rev != ARMADA_375_Z1_REV)
+ return;
+
+ resume_addr_reg = system_controller_phys_base +
+ mvebu_sc->resume_boot_addr;
+ mvebu_setup_boot_addr_wa(ARMADA_375_CRYPT0_ENG_TARGET,
+ ARMADA_375_CRYPT0_ENG_ATTR,
+ resume_addr_reg);
+}
+
+void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr)
+{
+ BUG_ON(system_controller_base == NULL);
+ BUG_ON(mvebu_sc->resume_boot_addr == 0);
+
+ if (of_machine_is_compatible("marvell,armada375"))
+ mvebu_armada375_smp_wa_init();
+
+ writel(virt_to_phys(boot_addr), system_controller_base +
+ mvebu_sc->resume_boot_addr);
+}
+#endif
+
+static int __init mvebu_system_controller_init(void)
+{
+ const struct of_device_id *match;
+ struct device_node *np;
+
+ np = of_find_matching_node_and_match(NULL, of_system_controller_table,
+ &match);
+ if (np) {
+ struct resource res;
+ system_controller_base = of_iomap(np, 0);
+ of_address_to_resource(np, 0, &res);
+ system_controller_phys_base = res.start;
+ mvebu_sc = (struct mvebu_system_controller *)match->data;
+ of_node_put(np);
+ }
+
+ return 0;
+}
+
+early_initcall(mvebu_system_controller_init);
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
new file mode 100644
index 000000000..84794137b
--- /dev/null
+++ b/arch/arm/mach-mxs/Kconfig
@@ -0,0 +1,26 @@
+config SOC_IMX23
+ bool
+ select ARM_AMBA
+ select ARM_CPU_SUSPEND if PM
+ select CPU_ARM926T
+ select PINCTRL_IMX23
+
+config SOC_IMX28
+ bool
+ select ARM_AMBA
+ select ARM_CPU_SUSPEND if PM
+ select CPU_ARM926T
+ select PINCTRL_IMX28
+
+config ARCH_MXS
+ bool "Freescale MXS (i.MX23, i.MX28) support"
+ depends on ARCH_MULTI_V5
+ select ARCH_REQUIRE_GPIOLIB
+ select CLKSRC_MMIO
+ select PINCTRL
+ select SOC_BUS
+ select SOC_IMX23
+ select SOC_IMX28
+ select STMP_DEVICE
+ help
+ Support for Freescale MXS-based family of processors
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
new file mode 100644
index 000000000..cc2bf6748
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_ARCH_MXS) += mach-mxs.o
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
new file mode 100644
index 000000000..2e7cec86e
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mxs.c
@@ -0,0 +1,543 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * 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/clk.h>
+#include <linux/clk/mxs.h>
+#include <linux/clkdev.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/irqchip/mxs.h>
+#include <linux/reboot.h>
+#include <linux/micrel_phy.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/phy.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/sys_soc.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/system_misc.h>
+
+#include "pm.h"
+
+/* MXS DIGCTL SAIF CLKMUX */
+#define MXS_DIGCTL_SAIF_CLKMUX_DIRECT 0x0
+#define MXS_DIGCTL_SAIF_CLKMUX_CROSSINPUT 0x1
+#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0 0x2
+#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR1 0x3
+
+#define HW_DIGCTL_CHIPID 0x310
+#define HW_DIGCTL_CHIPID_MASK (0xffff << 16)
+#define HW_DIGCTL_REV_MASK 0xff
+#define HW_DIGCTL_CHIPID_MX23 (0x3780 << 16)
+#define HW_DIGCTL_CHIPID_MX28 (0x2800 << 16)
+
+#define MXS_CHIP_REVISION_1_0 0x10
+#define MXS_CHIP_REVISION_1_1 0x11
+#define MXS_CHIP_REVISION_1_2 0x12
+#define MXS_CHIP_REVISION_1_3 0x13
+#define MXS_CHIP_REVISION_1_4 0x14
+#define MXS_CHIP_REV_UNKNOWN 0xff
+
+#define MXS_GPIO_NR(bank, nr) ((bank) * 32 + (nr))
+
+#define MXS_SET_ADDR 0x4
+#define MXS_CLR_ADDR 0x8
+#define MXS_TOG_ADDR 0xc
+
+static u32 chipid;
+static u32 socid;
+
+static void __iomem *reset_addr;
+
+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);
+}
+
+#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];
+
+static const u32 *mxs_get_ocotp(void)
+{
+ struct device_node *np;
+ void __iomem *ocotp_base;
+ int timeout = 0x400;
+ size_t i;
+ static int once;
+
+ if (once)
+ return ocotp_words;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,ocotp");
+ ocotp_base = of_iomap(np, 0);
+ WARN_ON(!ocotp_base);
+
+ 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;
+}
+
+enum mac_oui {
+ OUI_FSL,
+ OUI_DENX,
+ OUI_CRYSTALFONTZ,
+ OUI_I2SE,
+ OUI_ARMADEUS,
+};
+
+static void __init update_fec_mac_prop(enum mac_oui oui)
+{
+ struct device_node *np, *from = NULL;
+ struct property *newmac;
+ const u32 *ocotp = mxs_get_ocotp();
+ u8 *macaddr;
+ u32 val;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ np = of_find_compatible_node(from, NULL, "fsl,imx28-fec");
+ if (!np)
+ return;
+
+ from = np;
+
+ if (of_get_property(np, "local-mac-address", NULL))
+ continue;
+
+ newmac = kzalloc(sizeof(*newmac) + 6, GFP_KERNEL);
+ if (!newmac)
+ return;
+ newmac->value = newmac + 1;
+ newmac->length = 6;
+
+ newmac->name = kstrdup("local-mac-address", GFP_KERNEL);
+ if (!newmac->name) {
+ kfree(newmac);
+ return;
+ }
+
+ /*
+ * OCOTP only stores the last 4 octets for each mac address,
+ * so hard-code OUI here.
+ */
+ macaddr = newmac->value;
+ switch (oui) {
+ case OUI_FSL:
+ macaddr[0] = 0x00;
+ macaddr[1] = 0x04;
+ macaddr[2] = 0x9f;
+ break;
+ case OUI_DENX:
+ macaddr[0] = 0xc0;
+ macaddr[1] = 0xe5;
+ macaddr[2] = 0x4e;
+ break;
+ case OUI_CRYSTALFONTZ:
+ macaddr[0] = 0x58;
+ macaddr[1] = 0xb9;
+ macaddr[2] = 0xe1;
+ break;
+ case OUI_I2SE:
+ macaddr[0] = 0x00;
+ macaddr[1] = 0x01;
+ macaddr[2] = 0x87;
+ break;
+ case OUI_ARMADEUS:
+ macaddr[0] = 0x00;
+ macaddr[1] = 0x1e;
+ macaddr[2] = 0xac;
+ break;
+ }
+ val = ocotp[i];
+ macaddr[3] = (val >> 16) & 0xff;
+ macaddr[4] = (val >> 8) & 0xff;
+ macaddr[5] = (val >> 0) & 0xff;
+
+ of_update_property(np, newmac);
+ }
+}
+
+static inline void enable_clk_enet_out(void)
+{
+ struct clk *clk = clk_get_sys("enet_out", NULL);
+
+ if (!IS_ERR(clk))
+ clk_prepare_enable(clk);
+}
+
+static void __init imx28_evk_init(void)
+{
+ update_fec_mac_prop(OUI_FSL);
+
+ mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);
+}
+
+static void __init imx28_apf28_init(void)
+{
+ update_fec_mac_prop(OUI_ARMADEUS);
+}
+
+static int apx4devkit_phy_fixup(struct phy_device *phy)
+{
+ phy->dev_flags |= MICREL_PHY_50MHZ_CLK;
+ return 0;
+}
+
+static void __init apx4devkit_init(void)
+{
+ enable_clk_enet_out();
+
+ if (IS_BUILTIN(CONFIG_PHYLIB))
+ phy_register_fixup_for_uid(PHY_ID_KSZ8051, MICREL_PHY_ID_MASK,
+ apx4devkit_phy_fixup);
+}
+
+#define ENET0_MDC__GPIO_4_0 MXS_GPIO_NR(4, 0)
+#define ENET0_MDIO__GPIO_4_1 MXS_GPIO_NR(4, 1)
+#define ENET0_RX_EN__GPIO_4_2 MXS_GPIO_NR(4, 2)
+#define ENET0_RXD0__GPIO_4_3 MXS_GPIO_NR(4, 3)
+#define ENET0_RXD1__GPIO_4_4 MXS_GPIO_NR(4, 4)
+#define ENET0_TX_EN__GPIO_4_6 MXS_GPIO_NR(4, 6)
+#define ENET0_TXD0__GPIO_4_7 MXS_GPIO_NR(4, 7)
+#define ENET0_TXD1__GPIO_4_8 MXS_GPIO_NR(4, 8)
+#define ENET_CLK__GPIO_4_16 MXS_GPIO_NR(4, 16)
+
+#define TX28_FEC_PHY_POWER MXS_GPIO_NR(3, 29)
+#define TX28_FEC_PHY_RESET MXS_GPIO_NR(4, 13)
+#define TX28_FEC_nINT MXS_GPIO_NR(4, 5)
+
+static const struct gpio tx28_gpios[] __initconst = {
+ { ENET0_MDC__GPIO_4_0, GPIOF_OUT_INIT_LOW, "GPIO_4_0" },
+ { ENET0_MDIO__GPIO_4_1, GPIOF_OUT_INIT_LOW, "GPIO_4_1" },
+ { ENET0_RX_EN__GPIO_4_2, GPIOF_OUT_INIT_LOW, "GPIO_4_2" },
+ { ENET0_RXD0__GPIO_4_3, GPIOF_OUT_INIT_LOW, "GPIO_4_3" },
+ { ENET0_RXD1__GPIO_4_4, GPIOF_OUT_INIT_LOW, "GPIO_4_4" },
+ { ENET0_TX_EN__GPIO_4_6, GPIOF_OUT_INIT_LOW, "GPIO_4_6" },
+ { ENET0_TXD0__GPIO_4_7, GPIOF_OUT_INIT_LOW, "GPIO_4_7" },
+ { ENET0_TXD1__GPIO_4_8, GPIOF_OUT_INIT_LOW, "GPIO_4_8" },
+ { ENET_CLK__GPIO_4_16, GPIOF_OUT_INIT_LOW, "GPIO_4_16" },
+ { TX28_FEC_PHY_POWER, GPIOF_OUT_INIT_LOW, "fec-phy-power" },
+ { TX28_FEC_PHY_RESET, GPIOF_OUT_INIT_LOW, "fec-phy-reset" },
+ { TX28_FEC_nINT, GPIOF_DIR_IN, "fec-int" },
+};
+
+static void __init tx28_post_init(void)
+{
+ struct device_node *np;
+ struct platform_device *pdev;
+ struct pinctrl *pctl;
+ int ret;
+
+ enable_clk_enet_out();
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx28-fec");
+ pdev = of_find_device_by_node(np);
+ if (!pdev) {
+ pr_err("%s: failed to find fec device\n", __func__);
+ return;
+ }
+
+ pctl = pinctrl_get_select(&pdev->dev, "gpio_mode");
+ if (IS_ERR(pctl)) {
+ pr_err("%s: failed to get pinctrl state\n", __func__);
+ return;
+ }
+
+ ret = gpio_request_array(tx28_gpios, ARRAY_SIZE(tx28_gpios));
+ if (ret) {
+ pr_err("%s: failed to request gpios: %d\n", __func__, ret);
+ return;
+ }
+
+ /* Power up fec phy */
+ gpio_set_value(TX28_FEC_PHY_POWER, 1);
+ msleep(26); /* 25ms according to data sheet */
+
+ /* Mode strap pins */
+ gpio_set_value(ENET0_RX_EN__GPIO_4_2, 1);
+ gpio_set_value(ENET0_RXD0__GPIO_4_3, 1);
+ gpio_set_value(ENET0_RXD1__GPIO_4_4, 1);
+
+ udelay(100); /* minimum assertion time for nRST */
+
+ /* Deasserting FEC PHY RESET */
+ gpio_set_value(TX28_FEC_PHY_RESET, 1);
+
+ pinctrl_put(pctl);
+}
+
+static void __init crystalfontz_init(void)
+{
+ update_fec_mac_prop(OUI_CRYSTALFONTZ);
+}
+
+static void __init duckbill_init(void)
+{
+ update_fec_mac_prop(OUI_I2SE);
+}
+
+static void __init m28cu3_init(void)
+{
+ update_fec_mac_prop(OUI_DENX);
+}
+
+static const char __init *mxs_get_soc_id(void)
+{
+ struct device_node *np;
+ void __iomem *digctl_base;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx23-digctl");
+ digctl_base = of_iomap(np, 0);
+ WARN_ON(!digctl_base);
+
+ chipid = readl(digctl_base + HW_DIGCTL_CHIPID);
+ socid = chipid & HW_DIGCTL_CHIPID_MASK;
+
+ iounmap(digctl_base);
+ of_node_put(np);
+
+ switch (socid) {
+ case HW_DIGCTL_CHIPID_MX23:
+ return "i.MX23";
+ case HW_DIGCTL_CHIPID_MX28:
+ return "i.MX28";
+ default:
+ return "Unknown";
+ }
+}
+
+static u32 __init mxs_get_cpu_rev(void)
+{
+ u32 rev = chipid & HW_DIGCTL_REV_MASK;
+
+ switch (socid) {
+ case HW_DIGCTL_CHIPID_MX23:
+ switch (rev) {
+ case 0x0:
+ return MXS_CHIP_REVISION_1_0;
+ case 0x1:
+ return MXS_CHIP_REVISION_1_1;
+ case 0x2:
+ return MXS_CHIP_REVISION_1_2;
+ case 0x3:
+ return MXS_CHIP_REVISION_1_3;
+ case 0x4:
+ return MXS_CHIP_REVISION_1_4;
+ default:
+ return MXS_CHIP_REV_UNKNOWN;
+ }
+ case HW_DIGCTL_CHIPID_MX28:
+ switch (rev) {
+ case 0x0:
+ return MXS_CHIP_REVISION_1_1;
+ case 0x1:
+ return MXS_CHIP_REVISION_1_2;
+ default:
+ return MXS_CHIP_REV_UNKNOWN;
+ }
+ default:
+ return MXS_CHIP_REV_UNKNOWN;
+ }
+}
+
+static const char __init *mxs_get_revision(void)
+{
+ u32 rev = mxs_get_cpu_rev();
+
+ if (rev != MXS_CHIP_REV_UNKNOWN)
+ return kasprintf(GFP_KERNEL, "%d.%d", (rev >> 4) & 0xf,
+ rev & 0xf);
+ else
+ return kasprintf(GFP_KERNEL, "%s", "Unknown");
+}
+
+#define MX23_CLKCTRL_RESET_OFFSET 0x120
+#define MX28_CLKCTRL_RESET_OFFSET 0x1e0
+
+static int __init mxs_restart_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,clkctrl");
+ reset_addr = of_iomap(np, 0);
+ if (!reset_addr)
+ return -ENODEV;
+
+ if (of_device_is_compatible(np, "fsl,imx23-clkctrl"))
+ reset_addr += MX23_CLKCTRL_RESET_OFFSET;
+ else
+ reset_addr += MX28_CLKCTRL_RESET_OFFSET;
+ of_node_put(np);
+
+ return 0;
+}
+
+static void __init eukrea_mbmx283lc_init(void)
+{
+ mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);
+}
+
+static void __init mxs_machine_init(void)
+{
+ struct device_node *root;
+ struct device *parent;
+ struct soc_device *soc_dev;
+ struct soc_device_attribute *soc_dev_attr;
+ int ret;
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ return;
+
+ root = of_find_node_by_path("/");
+ ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
+ if (ret)
+ return;
+
+ soc_dev_attr->family = "Freescale MXS Family";
+ soc_dev_attr->soc_id = mxs_get_soc_id();
+ soc_dev_attr->revision = mxs_get_revision();
+
+ soc_dev = soc_device_register(soc_dev_attr);
+ if (IS_ERR(soc_dev)) {
+ kfree(soc_dev_attr->revision);
+ kfree(soc_dev_attr);
+ return;
+ }
+
+ parent = soc_device_to_device(soc_dev);
+
+ if (of_machine_is_compatible("fsl,imx28-evk"))
+ imx28_evk_init();
+ if (of_machine_is_compatible("armadeus,imx28-apf28"))
+ imx28_apf28_init();
+ else if (of_machine_is_compatible("bluegiga,apx4devkit"))
+ apx4devkit_init();
+ else if (of_machine_is_compatible("crystalfontz,cfa10036"))
+ crystalfontz_init();
+ else if (of_machine_is_compatible("eukrea,mbmx283lc"))
+ eukrea_mbmx283lc_init();
+ else if (of_machine_is_compatible("i2se,duckbill"))
+ duckbill_init();
+ else if (of_machine_is_compatible("msr,m28cu3"))
+ m28cu3_init();
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ NULL, parent);
+
+ mxs_restart_init();
+
+ if (of_machine_is_compatible("karo,tx28"))
+ tx28_post_init();
+}
+
+#define MXS_CLKCTRL_RESET_CHIP (1 << 1)
+
+/*
+ * Reset the system. It is called by machine_restart().
+ */
+static void mxs_restart(enum reboot_mode mode, const char *cmd)
+{
+ if (reset_addr) {
+ /* reset the chip */
+ __mxs_setl(MXS_CLKCTRL_RESET_CHIP, 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 */
+ soft_restart(0);
+}
+
+static const char *mxs_dt_compat[] __initdata = {
+ "fsl,imx28",
+ "fsl,imx23",
+ NULL,
+};
+
+DT_MACHINE_START(MXS, "Freescale MXS (Device Tree)")
+ .handle_irq = icoll_handle_irq,
+ .init_machine = mxs_machine_init,
+ .init_late = mxs_pm_init,
+ .dt_compat = mxs_dt_compat,
+ .restart = mxs_restart,
+MACHINE_END
diff --git a/arch/arm/mach-mxs/pm.c b/arch/arm/mach-mxs/pm.c
new file mode 100644
index 000000000..0170e99fd
--- /dev/null
+++ b/arch/arm/mach-mxs/pm.c
@@ -0,0 +1,41 @@
+/*
+ * 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 "pm.h"
+
+static int mxs_suspend_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ cpu_do_idle();
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static struct platform_suspend_ops mxs_suspend_ops = {
+ .enter = mxs_suspend_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+void __init mxs_pm_init(void)
+{
+ suspend_set_ops(&mxs_suspend_ops);
+}
diff --git a/arch/arm/mach-mxs/pm.h b/arch/arm/mach-mxs/pm.h
new file mode 100644
index 000000000..09d77b00a
--- /dev/null
+++ b/arch/arm/mach-mxs/pm.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_MXS_PM_H
+#define __ARCH_MXS_PM_H
+
+#ifdef CONFIG_PM
+void mxs_pm_init(void);
+#else
+#define mxs_pm_init NULL
+#endif
+
+#endif
diff --git a/arch/arm/mach-netx/Kconfig b/arch/arm/mach-netx/Kconfig
new file mode 100644
index 000000000..3d90ef19b
--- /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 000000000..7ce4ba9eb
--- /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 000000000..534a4d270
--- /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 000000000..d122ee6ab
--- /dev/null
+++ b/arch/arm/mach-netx/fb.c
@@ -0,0 +1,79 @@
+/*
+ * 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);
+}
+
+static AMBA_AHB_DEVICE(fb, "fb", 0, 0x00104000, { NETX_IRQ_LCD }, NULL);
+
+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 000000000..4919cf33a
--- /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 000000000..db25b0cef
--- /dev/null
+++ b/arch/arm/mach-netx/generic.c
@@ -0,0 +1,195 @@
+/*
+ * 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 <linux/irqchip/arm-vic.h>
+#include <linux/reboot.h>
+#include <mach/hardware.h>
+#include <asm/mach/map.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_p2v(NETX_PA_VIC), NETX_IRQ_VIC_START, ~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);
+
+void netx_restart(enum reboot_mode mode, const char *cmd)
+{
+ writel(NETX_SYSTEM_RES_CR_FIRMW_RES_EN | NETX_SYSTEM_RES_CR_FIRMW_RES,
+ NETX_SYSTEM_RES_CR);
+}
diff --git a/arch/arm/mach-netx/generic.h b/arch/arm/mach-netx/generic.h
new file mode 100644
index 000000000..bb2ce471c
--- /dev/null
+++ b/arch/arm/mach-netx/generic.h
@@ -0,0 +1,26 @@
+/*
+ * 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
+ */
+
+#include <linux/reboot.h>
+
+extern void __init netx_map_io(void);
+extern void __init netx_init_irq(void);
+extern void netx_restart(enum reboot_mode, const char *);
+
+extern void netx_timer_init(void);
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 000000000..b661af2f2
--- /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) IOMEM((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/irqs.h b/arch/arm/mach-netx/include/mach/irqs.h
new file mode 100644
index 000000000..8f74a844a
--- /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 64
+#define NETX_IRQ_SOFTINT (NETX_IRQ_VIC_START + 0)
+#define NETX_IRQ_TIMER0 (NETX_IRQ_VIC_START + 1)
+#define NETX_IRQ_TIMER1 (NETX_IRQ_VIC_START + 2)
+#define NETX_IRQ_TIMER2 (NETX_IRQ_VIC_START + 3)
+#define NETX_IRQ_SYSTIME_NS (NETX_IRQ_VIC_START + 4)
+#define NETX_IRQ_SYSTIME_S (NETX_IRQ_VIC_START + 5)
+#define NETX_IRQ_GPIO_15 (NETX_IRQ_VIC_START + 6)
+#define NETX_IRQ_WATCHDOG (NETX_IRQ_VIC_START + 7)
+#define NETX_IRQ_UART0 (NETX_IRQ_VIC_START + 8)
+#define NETX_IRQ_UART1 (NETX_IRQ_VIC_START + 9)
+#define NETX_IRQ_UART2 (NETX_IRQ_VIC_START + 10)
+#define NETX_IRQ_USB (NETX_IRQ_VIC_START + 11)
+#define NETX_IRQ_SPI (NETX_IRQ_VIC_START + 12)
+#define NETX_IRQ_I2C (NETX_IRQ_VIC_START + 13)
+#define NETX_IRQ_LCD (NETX_IRQ_VIC_START + 14)
+#define NETX_IRQ_HIF (NETX_IRQ_VIC_START + 15)
+#define NETX_IRQ_GPIO_0_14 (NETX_IRQ_VIC_START + 16)
+#define NETX_IRQ_XPEC0 (NETX_IRQ_VIC_START + 17)
+#define NETX_IRQ_XPEC1 (NETX_IRQ_VIC_START + 18)
+#define NETX_IRQ_XPEC2 (NETX_IRQ_VIC_START + 19)
+#define NETX_IRQ_XPEC3 (NETX_IRQ_VIC_START + 20)
+#define NETX_IRQ_XPEC(no) (NETX_IRQ_VIC_START + 17 + (no))
+#define NETX_IRQ_MSYNC0 (NETX_IRQ_VIC_START + 21)
+#define NETX_IRQ_MSYNC1 (NETX_IRQ_VIC_START + 22)
+#define NETX_IRQ_MSYNC2 (NETX_IRQ_VIC_START + 23)
+#define NETX_IRQ_MSYNC3 (NETX_IRQ_VIC_START + 24)
+#define NETX_IRQ_IRQ_PHY (NETX_IRQ_VIC_START + 25)
+#define NETX_IRQ_ISO_AREA (NETX_IRQ_VIC_START + 26)
+/* int 27 is reserved */
+/* int 28 is reserved */
+#define NETX_IRQ_TIMER3 (NETX_IRQ_VIC_START + 29)
+#define NETX_IRQ_TIMER4 (NETX_IRQ_VIC_START + 30)
+/* int 31 is reserved */
+
+#define NETX_IRQS (NETX_IRQ_VIC_START + 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/netx-regs.h b/arch/arm/mach-netx/include/mach/netx-regs.h
new file mode 100644
index 000000000..fdde22b58
--- /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) IOMEM(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) IOMEM(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) IOMEM(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 IOMEM(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) IOMEM(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) IOMEM(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) IOMEM(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) IOMEM(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 000000000..a77145920
--- /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 000000000..42c59068f
--- /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/uncompress.h b/arch/arm/mach-netx/include/mach/uncompress.h
new file mode 100644
index 000000000..5cb1051b5
--- /dev/null
+++ b/arch/arm/mach-netx/include/mach/uncompress.h
@@ -0,0 +1,75 @@
+/*
+ * 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()
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 000000000..0c0011d4f
--- /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 000000000..9b558eb30
--- /dev/null
+++ b/arch/arm/mach-netx/nxdb500.c
@@ -0,0 +1,209 @@
+/*
+ * 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 <linux/platform_data/eth-netx.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")
+ .atag_offset = 0x100,
+ .map_io = netx_map_io,
+ .init_irq = netx_init_irq,
+ .init_time = netx_timer_init,
+ .init_machine = nxdb500_init,
+ .restart = netx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-netx/nxdkn.c b/arch/arm/mach-netx/nxdkn.c
new file mode 100644
index 000000000..a5e86cd36
--- /dev/null
+++ b/arch/arm/mach-netx/nxdkn.c
@@ -0,0 +1,102 @@
+/*
+ * 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 <linux/platform_data/eth-netx.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")
+ .atag_offset = 0x100,
+ .map_io = netx_map_io,
+ .init_irq = netx_init_irq,
+ .init_time = netx_timer_init,
+ .init_machine = nxdkn_init,
+ .restart = netx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-netx/nxeb500hmi.c b/arch/arm/mach-netx/nxeb500hmi.c
new file mode 100644
index 000000000..ad17885d0
--- /dev/null
+++ b/arch/arm/mach-netx/nxeb500hmi.c
@@ -0,0 +1,186 @@
+/*
+ * 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 <linux/platform_data/eth-netx.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")
+ .atag_offset = 0x100,
+ .map_io = netx_map_io,
+ .init_irq = netx_init_irq,
+ .init_time = netx_timer_init,
+ .init_machine = nxeb500hmi_init,
+ .restart = netx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-netx/pfifo.c b/arch/arm/mach-netx/pfifo.c
new file mode 100644
index 000000000..03984943e
--- /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 000000000..5fb2a590e
--- /dev/null
+++ b/arch/arm/mach-netx/time.c
@@ -0,0 +1,150 @@
+/*
+ * 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 NETX_CLOCK_FREQ 100000000
+#define NETX_LATCH DIV_ROUND_CLOSEST(NETX_CLOCK_FREQ, HZ)
+
+#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(NETX_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),
+ .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_TIMER | IRQF_IRQPOLL,
+ .handler = netx_timer_interrupt,
+};
+
+/*
+ * Set up timer interrupt
+ */
+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(NETX_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", NETX_CLOCK_FREQ, 200, 32, clocksource_mmio_readl_up);
+
+ /* with max_delta_ns >= delta2ns(0x800) the system currently runs fine.
+ * Adding some safety ... */
+ netx_clockevent.cpumask = cpumask_of(0);
+ clockevents_config_and_register(&netx_clockevent, NETX_CLOCK_FREQ,
+ 0xa00, 0xfffffffe);
+}
diff --git a/arch/arm/mach-netx/xc.c b/arch/arm/mach-netx/xc.c
new file mode 100644
index 000000000..95f9389d5
--- /dev/null
+++ b/arch/arm/mach-netx/xc.c
@@ -0,0 +1,258 @@
+/*
+ * 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 <linux/export.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, "/*(DEBLOBBED)*/", x->no);
+
+ ret = reject_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'. Endianness 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 000000000..3c61096c8
--- /dev/null
+++ b/arch/arm/mach-nomadik/Kconfig
@@ -0,0 +1,30 @@
+menuconfig ARCH_NOMADIK
+ bool "ST-Ericsson Nomadik"
+ depends on ARCH_MULTI_V5
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_AMBA
+ select ARM_VIC
+ select CLKSRC_NOMADIK_MTU
+ select CLKSRC_NOMADIK_MTU_SCHED_CLOCK
+ select CPU_ARM926T
+ select MIGHT_HAVE_CACHE_L2X0
+ select PINCTRL
+ select PINCTRL_NOMADIK
+ select PINCTRL_STN8815
+ help
+ Support for the Nomadik platform by ST-Ericsson
+
+if ARCH_NOMADIK
+
+config MACH_NOMADIK_8815NHK
+ bool "ST 8815 Nomadik Hardware Kit (evaluation board)"
+ select NOMADIK_8815
+ select I2C
+ select I2C_ALGOBIT
+ select I2C_NOMADIK
+
+endif
+
+config NOMADIK_8815
+ depends on ARCH_NOMADIK
+ bool
diff --git a/arch/arm/mach-nomadik/Makefile b/arch/arm/mach-nomadik/Makefile
new file mode 100644
index 000000000..1071c3b04
--- /dev/null
+++ b/arch/arm/mach-nomadik/Makefile
@@ -0,0 +1,11 @@
+#
+# 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.
+
+# Cpu revision
+obj-$(CONFIG_NOMADIK_8815) += cpu-8815.o
diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c
new file mode 100644
index 000000000..9bda46f1f
--- /dev/null
+++ b/arch/arm/mach-nomadik/cpu-8815.c
@@ -0,0 +1,159 @@
+/*
+ * 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/io.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-l2x0.h>
+
+/*
+ * These are the only hard-coded address offsets we still have to use.
+ */
+#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 */
+#define NOMADIK_UART1_VBASE 0xF01FB000
+
+/* This is needed for LL-debug/earlyprintk/debug-macro.S */
+static struct map_desc cpu8815_io_desc[] __initdata = {
+ {
+ .virtual = NOMADIK_UART1_VBASE,
+ .pfn = __phys_to_pfn(NOMADIK_UART1_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init cpu8815_map_io(void)
+{
+ iotable_init(cpu8815_io_desc, ARRAY_SIZE(cpu8815_io_desc));
+}
+
+static void cpu8815_restart(enum reboot_mode mode, const char *cmd)
+{
+ void __iomem *srcbase = ioremap(NOMADIK_SRC_BASE, SZ_4K);
+
+ /* FIXME: use egpio when implemented */
+
+ /* Write anything to Reset status register */
+ writel(1, srcbase + 0x18);
+}
+
+/*
+ * This GPIO pin turns on a line that is used to detect card insertion
+ * on this board.
+ */
+static int __init cpu8815_mmcsd_init(void)
+{
+ struct device_node *cdbias;
+ int gpio, err;
+
+ cdbias = of_find_node_by_path("/usb-s8815/mmcsd-gpio");
+ if (!cdbias) {
+ pr_info("could not find MMC/SD card detect bias node\n");
+ return 0;
+ }
+ gpio = of_get_gpio(cdbias, 0);
+ if (gpio < 0) {
+ pr_info("could not obtain MMC/SD card detect bias GPIO\n");
+ return 0;
+ }
+ err = gpio_request(gpio, "card detect bias");
+ if (err) {
+ pr_info("failed to request card detect bias GPIO %d\n", gpio);
+ return -ENODEV;
+ }
+ err = gpio_direction_output(gpio, 0);
+ if (err){
+ pr_info("failed to set GPIO %d as output, low\n", gpio);
+ return err;
+ }
+ pr_info("enabled USB-S8815 CD bias GPIO %d, low\n", gpio);
+ return 0;
+}
+device_initcall(cpu8815_mmcsd_init);
+
+static const char * cpu8815_board_compat[] = {
+ "st,nomadik-nhk-15",
+ "calaosystems,usb-s8815",
+ NULL,
+};
+
+DT_MACHINE_START(NOMADIK_DT, "Nomadik STn8815")
+ /* At full speed latency must be >=2, so 0x249 in low bits */
+ .l2c_aux_val = 0x00700249,
+ .l2c_aux_mask = 0xfe0fefff,
+ .map_io = cpu8815_map_io,
+ .restart = cpu8815_restart,
+ .dt_compat = cpu8815_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-nspire/Kconfig b/arch/arm/mach-nspire/Kconfig
new file mode 100644
index 000000000..bc41f26c1
--- /dev/null
+++ b/arch/arm/mach-nspire/Kconfig
@@ -0,0 +1,11 @@
+config ARCH_NSPIRE
+ bool "TI-NSPIRE based"
+ depends on ARCH_MULTI_V4_V5
+ depends on MMU
+ select CPU_ARM926T
+ select GENERIC_IRQ_CHIP
+ select ARM_AMBA
+ select ARM_VIC
+ select ARM_TIMER_SP804
+ help
+ This enables support for systems using the TI-NSPIRE CPU
diff --git a/arch/arm/mach-nspire/Makefile b/arch/arm/mach-nspire/Makefile
new file mode 100644
index 000000000..1bec256eb
--- /dev/null
+++ b/arch/arm/mach-nspire/Makefile
@@ -0,0 +1,2 @@
+obj-y += nspire.o
+obj-y += clcd.o
diff --git a/arch/arm/mach-nspire/Makefile.boot b/arch/arm/mach-nspire/Makefile.boot
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/arch/arm/mach-nspire/Makefile.boot
diff --git a/arch/arm/mach-nspire/clcd.c b/arch/arm/mach-nspire/clcd.c
new file mode 100644
index 000000000..abea12617
--- /dev/null
+++ b/arch/arm/mach-nspire/clcd.c
@@ -0,0 +1,119 @@
+/*
+ * linux/arch/arm/mach-nspire/clcd.c
+ *
+ * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it 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/of.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/dma-mapping.h>
+
+static struct clcd_panel nspire_cx_lcd_panel = {
+ .mode = {
+ .name = "Color LCD",
+ .refresh = 60,
+ .xres = 320,
+ .yres = 240,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .pixclock = 1,
+ .hsync_len = 6,
+ .vsync_len = 1,
+ .right_margin = 50,
+ .left_margin = 38,
+ .lower_margin = 3,
+ .upper_margin = 17,
+ },
+ .width = 65, /* ~6.50 cm */
+ .height = 49, /* ~4.87 cm */
+ .tim2 = TIM2_IPC,
+ .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+ .bpp = 16,
+ .caps = CLCD_CAP_565,
+};
+
+static struct clcd_panel nspire_classic_lcd_panel = {
+ .mode = {
+ .name = "Grayscale LCD",
+ .refresh = 60,
+ .xres = 320,
+ .yres = 240,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .pixclock = 1,
+ .hsync_len = 6,
+ .vsync_len = 1,
+ .right_margin = 6,
+ .left_margin = 6,
+ },
+ .width = 71, /* 7.11cm */
+ .height = 53, /* 5.33cm */
+ .tim2 = 0x80007d0,
+ .cntl = CNTL_LCDMONO8,
+ .bpp = 8,
+ .grayscale = 1,
+ .caps = CLCD_CAP_5551,
+};
+
+int nspire_clcd_setup(struct clcd_fb *fb)
+{
+ struct clcd_panel *panel;
+ size_t panel_size;
+ const char *type;
+ dma_addr_t dma;
+ int err;
+
+ BUG_ON(!fb->dev->dev.of_node);
+
+ err = of_property_read_string(fb->dev->dev.of_node, "lcd-type", &type);
+ if (err) {
+ pr_err("CLCD: Could not find lcd-type property\n");
+ return err;
+ }
+
+ if (!strcmp(type, "cx")) {
+ panel = &nspire_cx_lcd_panel;
+ } else if (!strcmp(type, "classic")) {
+ panel = &nspire_classic_lcd_panel;
+ } else {
+ pr_err("CLCD: Unknown lcd-type %s\n", type);
+ return -EINVAL;
+ }
+
+ panel_size = ((panel->mode.xres * panel->mode.yres) * panel->bpp) / 8;
+ panel_size = ALIGN(panel_size, PAGE_SIZE);
+
+ fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev,
+ panel_size, &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 = panel_size;
+ fb->panel = panel;
+
+ return 0;
+}
+
+int nspire_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 nspire_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);
+}
diff --git a/arch/arm/mach-nspire/clcd.h b/arch/arm/mach-nspire/clcd.h
new file mode 100644
index 000000000..8c33d2c18
--- /dev/null
+++ b/arch/arm/mach-nspire/clcd.h
@@ -0,0 +1,14 @@
+/*
+ * linux/arch/arm/mach-nspire/clcd.h
+ *
+ * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can 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 nspire_clcd_setup(struct clcd_fb *fb);
+int nspire_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma);
+void nspire_clcd_remove(struct clcd_fb *fb);
diff --git a/arch/arm/mach-nspire/mmio.h b/arch/arm/mach-nspire/mmio.h
new file mode 100644
index 000000000..8813471af
--- /dev/null
+++ b/arch/arm/mach-nspire/mmio.h
@@ -0,0 +1,20 @@
+/*
+ * linux/arch/arm/mach-nspire/mmio.h
+ *
+ * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can 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 NSPIRE_MISC_PHYS_BASE 0x900A0000
+#define NSPIRE_MISC_HWRESET 0x08
+
+#define NSPIRE_PWR_PHYS_BASE 0x900B0000
+#define NSPIRE_PWR_VIRT_BASE 0xFEEB0000
+#define NSPIRE_PWR_BUS_DISABLE1 0x18
+#define NSPIRE_PWR_BUS_DISABLE2 0x20
+
+#define NSPIRE_LCD_PHYS_BASE 0xC0000000
diff --git a/arch/arm/mach-nspire/nspire.c b/arch/arm/mach-nspire/nspire.c
new file mode 100644
index 000000000..3445a5686
--- /dev/null
+++ b/arch/arm/mach-nspire/nspire.c
@@ -0,0 +1,80 @@
+/*
+ * linux/arch/arm/mach-nspire/nspire.c
+ *
+ * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it 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/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/arm-vic.h>
+#include <linux/clkdev.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <asm/hardware/timer-sp.h>
+
+#include "mmio.h"
+#include "clcd.h"
+
+static const char *const nspire_dt_match[] __initconst = {
+ "ti,nspire",
+ "ti,nspire-cx",
+ "ti,nspire-tp",
+ "ti,nspire-clp",
+ NULL,
+};
+
+static void __init nspire_map_io(void)
+{
+ debug_ll_io_init();
+}
+
+static struct clcd_board nspire_clcd_data = {
+ .name = "LCD",
+ .caps = CLCD_CAP_5551 | CLCD_CAP_565,
+ .check = clcdfb_check,
+ .decode = clcdfb_decode,
+ .setup = nspire_clcd_setup,
+ .mmap = nspire_clcd_mmap,
+ .remove = nspire_clcd_remove,
+};
+
+
+static struct of_dev_auxdata nspire_auxdata[] __initdata = {
+ OF_DEV_AUXDATA("arm,pl111", NSPIRE_LCD_PHYS_BASE,
+ NULL, &nspire_clcd_data),
+ { }
+};
+
+static void __init nspire_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table,
+ nspire_auxdata, NULL);
+}
+
+static void nspire_restart(enum reboot_mode mode, const char *cmd)
+{
+ void __iomem *base = ioremap(NSPIRE_MISC_PHYS_BASE, SZ_4K);
+ if (!base)
+ return;
+
+ writel(2, base + NSPIRE_MISC_HWRESET);
+}
+
+DT_MACHINE_START(NSPIRE, "TI-NSPIRE")
+ .dt_compat = nspire_dt_match,
+ .map_io = nspire_map_io,
+ .init_machine = nspire_init,
+ .restart = nspire_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
new file mode 100644
index 000000000..cdd05f2e6
--- /dev/null
+++ b/arch/arm/mach-omap1/Kconfig
@@ -0,0 +1,169 @@
+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 ARCH_OMAP_OTG
+ select CPU_ARM926T
+ select OMAP_MPU_TIMER
+
+config ARCH_OMAP850
+ depends on ARCH_OMAP1
+ bool "OMAP850 Based System"
+ select ARCH_OMAP_OTG
+ select CPU_ARM926T
+
+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 ARCH_OMAP_OTG
+ select CPU_ARM926T
+
+comment "OMAP Board Type"
+ depends on ARCH_OMAP1
+
+config MACH_OMAP_INNOVATOR
+ bool "TI Innovator"
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
+ 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
+ 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_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
+ 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
+ select I2C
+ 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
+ select GPIO_GENERIC_PLATFORM
+ select LEDS_GPIO_REGISTER
+ select REGULATOR
+ select REGULATOR_FIXED_VOLTAGE
+ 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.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
new file mode 100644
index 000000000..3889b6cd2
--- /dev/null
+++ b/arch/arm/mach-omap1/Makefile
@@ -0,0 +1,63 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := io.o id.o sram-init.o sram.o time.o irq.o mux.o flash.o \
+ serial.o devices.o dma.o fb.o
+obj-y += clock.o clock_data.o opp_data.o reset.o pm_bus.o timer.o
+
+ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),)
+obj-y += mcbsp.o
+endif
+
+obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o
+
+# OCPI interconnect support for 1710, 1610 and 5912
+obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
+
+# Power Management
+obj-$(CONFIG_PM) += pm.o sleep.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 \
+ board-nand.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 board-nand.o
+obj-$(CONFIG_MACH_OMAP_FSAMPLE) += board-fsample.o board-nand.o
+obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o
+obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o board-h3-mmc.o \
+ board-nand.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
+
+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 000000000..13bda8dbd
--- /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 000000000..3d1e1c250
--- /dev/null
+++ b/arch/arm/mach-omap1/ams-delta-fiq-handler.S
@@ -0,0 +1,281 @@
+/*
+ * 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 <asm/assembler.h>
+
+#include <mach/board-ams-delta.h>
+
+#include <mach/irqs.h>
+#include <mach/ams-delta-fiq.h>
+
+#include "iomap.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 000000000..d1f12095f
--- /dev/null
+++ b/arch/arm/mach-omap1/ams-delta-fiq.c
@@ -0,0 +1,155 @@
+/*
+ * 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 <mach/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)
+{
+ int gpio, irq_num, fiq_count;
+ struct irq_chip *irq_chip;
+
+ irq_chip = irq_get_chip(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK));
+
+ /*
+ * 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", NULL);
+ 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 000000000..2aab761ee
--- /dev/null
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -0,0 +1,633 @@
+/*
+ * 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/basic_mmio_gpio.h>
+#include <linux/gpio.h>
+#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/regulator/consumer.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/serial_8250.h>
+#include <linux/export.h>
+#include <linux/omapfb.h>
+#include <linux/io.h>
+#include <linux/platform_data/gpio-omap.h>
+
+#include <media/soc_camera.h>
+
+#include <asm/serial.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/board-ams-delta.h>
+#include <linux/platform_data/keypad-omap.h>
+#include <mach/mux.h>
+
+#include <mach/hardware.h>
+#include <mach/ams-delta-fiq.h>
+#include <mach/camera.h>
+#include <mach/usb.h>
+
+#include "iomap.h"
+#include "common.h"
+
+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 */
+};
+
+#define LATCH1_PHYS 0x01000000
+#define LATCH1_VIRT 0xEA000000
+#define MODEM_PHYS 0x04000000
+#define MODEM_VIRT 0xEB000000
+#define LATCH2_PHYS 0x08000000
+#define LATCH2_VIRT 0xEC000000
+
+static struct map_desc ams_delta_io_desc[] __initdata = {
+ /* AMS_DELTA_LATCH1 */
+ {
+ .virtual = LATCH1_VIRT,
+ .pfn = __phys_to_pfn(LATCH1_PHYS),
+ .length = 0x01000000,
+ .type = MT_DEVICE
+ },
+ /* AMS_DELTA_LATCH2 */
+ {
+ .virtual = LATCH2_VIRT,
+ .pfn = __phys_to_pfn(LATCH2_PHYS),
+ .length = 0x01000000,
+ .type = MT_DEVICE
+ },
+ /* AMS_DELTA_MODEM */
+ {
+ .virtual = MODEM_VIRT,
+ .pfn = __phys_to_pfn(MODEM_PHYS),
+ .length = 0x01000000,
+ .type = MT_DEVICE
+ }
+};
+
+static struct omap_lcd_config ams_delta_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_usb_config ams_delta_usb_config __initdata = {
+ .register_host = 1,
+ .hmc_mode = 16,
+ .pins[0] = 2,
+};
+
+#define LATCH1_GPIO_BASE 232
+#define LATCH1_NGPIO 8
+
+static struct resource latch1_resources[] = {
+ [0] = {
+ .name = "dat",
+ .start = LATCH1_PHYS,
+ .end = LATCH1_PHYS + (LATCH1_NGPIO - 1) / 8,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct bgpio_pdata latch1_pdata = {
+ .base = LATCH1_GPIO_BASE,
+ .ngpio = LATCH1_NGPIO,
+};
+
+static struct platform_device latch1_gpio_device = {
+ .name = "basic-mmio-gpio",
+ .id = 0,
+ .resource = latch1_resources,
+ .num_resources = ARRAY_SIZE(latch1_resources),
+ .dev = {
+ .platform_data = &latch1_pdata,
+ },
+};
+
+static struct resource latch2_resources[] = {
+ [0] = {
+ .name = "dat",
+ .start = LATCH2_PHYS,
+ .end = LATCH2_PHYS + (AMS_DELTA_LATCH2_NGPIO - 1) / 8,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct bgpio_pdata latch2_pdata = {
+ .base = AMS_DELTA_LATCH2_GPIO_BASE,
+ .ngpio = AMS_DELTA_LATCH2_NGPIO,
+};
+
+static struct platform_device latch2_gpio_device = {
+ .name = "basic-mmio-gpio",
+ .id = 1,
+ .resource = latch2_resources,
+ .num_resources = ARRAY_SIZE(latch2_resources),
+ .dev = {
+ .platform_data = &latch2_pdata,
+ },
+};
+
+static const struct gpio latch_gpios[] __initconst = {
+ {
+ .gpio = LATCH1_GPIO_BASE + 6,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "dockit1",
+ },
+ {
+ .gpio = LATCH1_GPIO_BASE + 7,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "dockit2",
+ },
+ {
+ .gpio = AMS_DELTA_GPIO_PIN_SCARD_RSTIN,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "scard_rstin",
+ },
+ {
+ .gpio = AMS_DELTA_GPIO_PIN_SCARD_CMDVCC,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "scard_cmdvcc",
+ },
+ {
+ .gpio = AMS_DELTA_GPIO_PIN_MODEM_CODEC,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "modem_codec",
+ },
+ {
+ .gpio = AMS_DELTA_LATCH2_GPIO_BASE + 14,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "hookflash1",
+ },
+ {
+ .gpio = AMS_DELTA_LATCH2_GPIO_BASE + 15,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "hookflash2",
+ },
+};
+
+static struct regulator_consumer_supply modem_nreset_consumers[] = {
+ REGULATOR_SUPPLY("RESET#", "serial8250.1"),
+ REGULATOR_SUPPLY("POR", "cx20442-codec"),
+};
+
+static struct regulator_init_data modem_nreset_data = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(modem_nreset_consumers),
+ .consumer_supplies = modem_nreset_consumers,
+};
+
+static struct fixed_voltage_config modem_nreset_config = {
+ .supply_name = "modem_nreset",
+ .microvolts = 3300000,
+ .gpio = AMS_DELTA_GPIO_PIN_MODEM_NRESET,
+ .startup_delay = 25000,
+ .enable_high = 1,
+ .enabled_at_boot = 1,
+ .init_data = &modem_nreset_data,
+};
+
+static struct platform_device modem_nreset_device = {
+ .name = "reg-fixed-voltage",
+ .id = -1,
+ .dev = {
+ .platform_data = &modem_nreset_config,
+ },
+};
+
+struct modem_private_data {
+ struct regulator *regulator;
+};
+
+static struct modem_private_data modem_priv;
+
+void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value)
+{
+ int bit = 0;
+ u16 bitpos = 1 << bit;
+
+ for (; bit < ngpio; bit++, bitpos = bitpos << 1) {
+ if (!(mask & bitpos))
+ continue;
+ else
+ gpio_set_value(base + bit, (value & bitpos) != 0);
+ }
+}
+EXPORT_SYMBOL(ams_delta_latch_write);
+
+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 = {
+ .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 const struct gpio_led gpio_leds[] __initconst = {
+ {
+ .name = "camera",
+ .gpio = LATCH1_GPIO_BASE + 0,
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+#ifdef CONFIG_LEDS_TRIGGERS
+ .default_trigger = "ams_delta_camera",
+#endif
+ },
+ {
+ .name = "advert",
+ .gpio = LATCH1_GPIO_BASE + 1,
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "email",
+ .gpio = LATCH1_GPIO_BASE + 2,
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "handsfree",
+ .gpio = LATCH1_GPIO_BASE + 3,
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "voicemail",
+ .gpio = LATCH1_GPIO_BASE + 4,
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "voice",
+ .gpio = LATCH1_GPIO_BASE + 5,
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+};
+
+static const struct gpio_led_platform_data leds_pdata __initconst = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+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_audio_device = {
+ .name = "ams-delta-audio",
+ .id = -1,
+};
+
+static struct platform_device cx20442_codec_device = {
+ .name = "cx20442-codec",
+ .id = -1,
+};
+
+static struct platform_device *ams_delta_devices[] __initdata = {
+ &latch1_gpio_device,
+ &latch2_gpio_device,
+ &ams_delta_kp_device,
+ &ams_delta_camera_device,
+ &ams_delta_audio_device,
+};
+
+static struct platform_device *late_devices[] __initdata = {
+ &ams_delta_nand_device,
+ &ams_delta_lcd_device,
+ &cx20442_codec_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);
+
+ omap_serial_init();
+ omap_register_i2c_bus(1, 100, NULL, 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
+ gpio_led_register_device(-1, &leds_pdata);
+ platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
+
+ ams_delta_init_fiq();
+
+ omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1);
+
+ omapfb_set_lcd_config(&ams_delta_lcd_config);
+}
+
+static void modem_pm(struct uart_port *port, unsigned int state, unsigned old)
+{
+ struct modem_private_data *priv = port->private_data;
+
+ if (IS_ERR(priv->regulator))
+ return;
+
+ if (state == old)
+ return;
+
+ if (state == 0)
+ regulator_enable(priv->regulator);
+ else if (old == 0)
+ regulator_disable(priv->regulator);
+}
+
+static struct plat_serial8250_port ams_delta_modem_ports[] = {
+ {
+ .membase = IOMEM(MODEM_VIRT),
+ .mapbase = MODEM_PHYS,
+ .irq = -EINVAL, /* changed later */
+ .flags = UPF_BOOT_AUTOCONF,
+ .irqflags = IRQF_TRIGGER_RISING,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = BASE_BAUD * 16,
+ .pm = modem_pm,
+ .private_data = &modem_priv,
+ },
+ { },
+};
+
+static struct platform_device ams_delta_modem_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM1,
+ .dev = {
+ .platform_data = ams_delta_modem_ports,
+ },
+};
+
+static int __init late_init(void)
+{
+ int err;
+
+ if (!machine_is_ams_delta())
+ return -ENODEV;
+
+ err = gpio_request_array(latch_gpios, ARRAY_SIZE(latch_gpios));
+ if (err) {
+ pr_err("Couldn't take over latch1/latch2 GPIO pins\n");
+ return err;
+ }
+
+ platform_add_devices(late_devices, ARRAY_SIZE(late_devices));
+
+ err = platform_device_register(&modem_nreset_device);
+ if (err) {
+ pr_err("Couldn't register the modem regulator device\n");
+ return err;
+ }
+
+ 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);
+
+ /* Initialize the modem_nreset regulator consumer before use */
+ modem_priv.regulator = ERR_PTR(-ENODEV);
+
+ ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC,
+ AMS_DELTA_LATCH2_MODEM_CODEC);
+
+ err = platform_device_register(&ams_delta_modem_device);
+ if (err)
+ goto gpio_free;
+
+ /*
+ * Once the modem device is registered, the modem_nreset
+ * regulator can be requested on behalf of that device.
+ */
+ modem_priv.regulator = regulator_get(&ams_delta_modem_device.dev,
+ "RESET#");
+ if (IS_ERR(modem_priv.regulator)) {
+ err = PTR_ERR(modem_priv.regulator);
+ goto unregister;
+ }
+ return 0;
+
+unregister:
+ platform_device_unregister(&ams_delta_modem_device);
+gpio_free:
+ gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
+ return err;
+}
+
+static void __init ams_delta_init_late(void)
+{
+ omap1_init_late();
+ late_init();
+}
+
+static void __init ams_delta_map_io(void)
+{
+ omap15xx_map_io();
+ iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));
+}
+
+MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
+ /* Maintainer: Jonathan McDowell <noodles@earth.li> */
+ .atag_offset = 0x100,
+ .map_io = ams_delta_map_io,
+ .init_early = omap1_init_early,
+ .init_irq = omap1_init_irq,
+ .init_machine = ams_delta_init,
+ .init_late = ams_delta_init_late,
+ .init_time = omap1_timer_init,
+ .restart = omap1_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
new file mode 100644
index 000000000..702d58039
--- /dev/null
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -0,0 +1,369 @@
+/*
+ * 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/gpio.h>
+#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 <linux/omapfb.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/tc.h>
+#include <mach/mux.h>
+#include <mach/flash.h>
+#include <linux/platform_data/keypad-omap.h>
+
+#include <mach/hardware.h>
+
+#include "iomap.h"
+#include "common.h"
+#include "fpga.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)
+{
+ __raw_writeb(1, H2P2_DBG_FPGA_LAN_RESET);
+ mdelay(50);
+ __raw_writeb(__raw_readb(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,
+};
+
+#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 struct platform_nand_data nand_data = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_offset = 0,
+ .options = NAND_SAMSUNG_LP_OPTIONS,
+ },
+ .ctrl = {
+ .cmd_ctrl = omap1_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 *devices[] __initdata = {
+ &nor_device,
+ &nand_device,
+ &smc91x_device,
+ &kp_device,
+};
+
+static struct omap_lcd_config fsample_lcd_config = {
+ .ctrl_name = "internal",
+};
+
+static void __init omap_fsample_init(void)
+{
+ /* 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);
+
+ fsample_init_smc91x();
+
+ BUG_ON(gpio_request(FSAMPLE_NAND_RB_GPIO_PIN, "NAND ready") < 0);
+ 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_serial_init();
+ omap_register_i2c_bus(1, 100, NULL, 0);
+
+ omapfb_set_lcd_config(&fsample_lcd_config);
+}
+
+/* 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)
+{
+ omap15xx_map_io();
+ iotable_init(omap_fsample_io_desc,
+ ARRAY_SIZE(omap_fsample_io_desc));
+}
+
+MACHINE_START(OMAP_FSAMPLE, "OMAP730 F-Sample")
+/* Maintainer: Brian Swetland <swetland@google.com> */
+ .atag_offset = 0x100,
+ .map_io = omap_fsample_map_io,
+ .init_early = omap1_init_early,
+ .init_irq = omap1_init_irq,
+ .init_machine = omap_fsample_init,
+ .init_late = omap1_init_late,
+ .init_time = omap1_timer_init,
+ .restart = omap1_restart,
+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 000000000..e1d917177
--- /dev/null
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -0,0 +1,89 @@
+/*
+ * 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/gpio.h>
+#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/mux.h>
+
+#include <mach/usb.h>
+
+#include "common.h"
+
+/* 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 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_serial_init();
+ omap_register_i2c_bus(1, 100, NULL, 0);
+}
+
+MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
+ /* Maintainer: Tony Lindgren <tony@atomide.com> */
+ .atag_offset = 0x100,
+ .map_io = omap16xx_map_io,
+ .init_early = omap1_init_early,
+ .init_irq = omap1_init_irq,
+ .init_machine = omap_generic_init,
+ .init_late = omap1_init_late,
+ .init_time = omap1_timer_init,
+ .restart = omap1_restart,
+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 000000000..7119ef28e
--- /dev/null
+++ b/arch/arm/mach-omap1/board-h2-mmc.c
@@ -0,0 +1,77 @@
+/*
+ * 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/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/gpio-omap.h>
+#include <linux/i2c/tps65010.h>
+
+#include "board-h2.h"
+#include "mmc.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,
+ .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 000000000..5b45d266d
--- /dev/null
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -0,0 +1,433 @@
+/*
+ * 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/gpio.h>
+#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 <linux/omapfb.h>
+#include <linux/platform_data/gpio-omap.h>
+#include <linux/leds.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/mux.h>
+#include <linux/omap-dma.h>
+#include <mach/tc.h>
+#include <linux/platform_data/keypad-omap.h>
+#include <mach/flash.h>
+
+#include <mach/hardware.h>
+#include <mach/usb.h>
+
+#include "common.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,
+ },
+};
+
+#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 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,
+ },
+ .ctrl = {
+ .cmd_ctrl = omap1_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] = {
+ .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,
+};
+
+static struct gpio_led h2_gpio_led_pins[] = {
+ {
+ .name = "h2:red",
+ .default_trigger = "heartbeat",
+ .gpio = 3,
+ },
+ {
+ .name = "h2:green",
+ .default_trigger = "cpu0",
+ .gpio = OMAP_MPUIO(4),
+ },
+};
+
+static struct gpio_led_platform_data h2_gpio_led_data = {
+ .leds = h2_gpio_led_pins,
+ .num_leds = ARRAY_SIZE(h2_gpio_led_pins),
+};
+
+static struct platform_device h2_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &h2_gpio_led_data,
+ },
+};
+
+static struct platform_device *h2_devices[] __initdata = {
+ &h2_nor_device,
+ &h2_nand_device,
+ &h2_smc91x_device,
+ &h2_kp_device,
+ &h2_gpio_leds,
+};
+
+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)
+{
+ if (!IS_BUILTIN(CONFIG_TPS65010))
+ return -ENOSYS;
+
+ 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),
+ .platform_data = &tps_board,
+ }, {
+ I2C_BOARD_INFO("isp1301_omap", 0x2d),
+ },
+};
+
+static struct omap_usb_config h2_usb_config __initdata = {
+ /* usb1 has a Mini-AB port and external isp1301 transceiver */
+ .otg = 2,
+
+#if IS_ENABLED(CONFIG_USB_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 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;
+ BUG_ON(gpio_request(H2_NAND_RB_GPIO_PIN, "NAND ready") < 0);
+ 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);
+
+ /* GPIO based LEDs */
+ omap_cfg_reg(P18_1610_GPIO3);
+ omap_cfg_reg(MPUIO4);
+
+ h2_smc91x_resources[1].start = gpio_to_irq(0);
+ h2_smc91x_resources[1].end = gpio_to_irq(0);
+ platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
+ omap_serial_init();
+ h2_i2c_board_info[0].irq = gpio_to_irq(58);
+ h2_i2c_board_info[1].irq = gpio_to_irq(2);
+ 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();
+
+ omapfb_set_lcd_config(&h2_lcd_config);
+}
+
+MACHINE_START(OMAP_H2, "TI-H2")
+ /* Maintainer: Imre Deak <imre.deak@nokia.com> */
+ .atag_offset = 0x100,
+ .map_io = omap16xx_map_io,
+ .init_early = omap1_init_early,
+ .init_irq = omap1_init_irq,
+ .init_machine = h2_init,
+ .init_late = omap1_init_late,
+ .init_time = omap1_timer_init,
+ .restart = omap1_restart,
+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 000000000..315e26625
--- /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 000000000..17d77914d
--- /dev/null
+++ b/arch/arm/mach-omap1/board-h3-mmc.c
@@ -0,0 +1,66 @@
+/*
+ * 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/gpio.h>
+#include <linux/platform_device.h>
+
+#include <linux/i2c/tps65010.h>
+
+#include "board-h3.h"
+#include "mmc.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,
+ .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 000000000..bfed4f928
--- /dev/null
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -0,0 +1,459 @@
+/*
+ * 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/gpio.h>
+#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 <linux/omapfb.h>
+#include <linux/platform_data/gpio-omap.h>
+#include <linux/leds.h>
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/mux.h>
+#include <mach/tc.h>
+#include <linux/platform_data/keypad-omap.h>
+#include <linux/omap-dma.h>
+#include <mach/flash.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/usb.h>
+
+#include "common.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,
+ },
+};
+
+#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 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,
+ },
+ .ctrl = {
+ .cmd_ctrl = omap1_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] = {
+ .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,
+ .max_speed_hz = 16000000,
+ /* .platform_data = &tsc_platform_data, */
+ },
+};
+
+static struct gpio_led h3_gpio_led_pins[] = {
+ {
+ .name = "h3:red",
+ .default_trigger = "heartbeat",
+ .gpio = 3,
+ },
+ {
+ .name = "h3:green",
+ .default_trigger = "cpu0",
+ .gpio = OMAP_MPUIO(4),
+ },
+};
+
+static struct gpio_led_platform_data h3_gpio_led_data = {
+ .leds = h3_gpio_led_pins,
+ .num_leds = ARRAY_SIZE(h3_gpio_led_pins),
+};
+
+static struct platform_device h3_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &h3_gpio_led_data,
+ },
+};
+
+static struct platform_device *devices[] __initdata = {
+ &nor_device,
+ &nand_device,
+ &smc91x_device,
+ &intlat_device,
+ &h3_kp_device,
+ &h3_lcd_device,
+ &h3_gpio_leds,
+};
+
+static struct omap_usb_config h3_usb_config __initdata = {
+ /* usb1 has a Mini-AB port and external isp1301 transceiver */
+ .otg = 2,
+
+#if IS_ENABLED(CONFIG_USB_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 i2c_board_info __initdata h3_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("tps65013", 0x48),
+ },
+ {
+ I2C_BOARD_INFO("isp1301_omap", 0x2d),
+ },
+};
+
+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;
+ BUG_ON(gpio_request(H3_NAND_RB_GPIO_PIN, "NAND ready") < 0);
+ 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);
+
+ /* GPIO based LEDs */
+ omap_cfg_reg(P18_1610_GPIO3);
+ omap_cfg_reg(MPUIO4);
+
+ smc91x_resources[1].start = gpio_to_irq(40);
+ smc91x_resources[1].end = gpio_to_irq(40);
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ h3_spi_board_info[0].irq = gpio_to_irq(H3_TS_GPIO);
+ spi_register_board_info(h3_spi_board_info,
+ ARRAY_SIZE(h3_spi_board_info));
+ omap_serial_init();
+ h3_i2c_board_info[1].irq = gpio_to_irq(14);
+ 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();
+
+ omapfb_set_lcd_config(&h3_lcd_config);
+}
+
+MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
+ /* Maintainer: Texas Instruments, Inc. */
+ .atag_offset = 0x100,
+ .map_io = omap16xx_map_io,
+ .init_early = omap1_init_early,
+ .init_irq = omap1_init_irq,
+ .init_machine = h3_init,
+ .init_late = omap1_init_late,
+ .init_time = omap1_timer_init,
+ .restart = omap1_restart,
+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 000000000..78de535be
--- /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 000000000..35a2379b9
--- /dev/null
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -0,0 +1,608 @@
+/*
+ * 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/delay.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 <linux/omapfb.h>
+#include <linux/platform_data/keypad-omap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/omap7xx.h>
+#include "mmc.h"
+
+#include <mach/irqs.h>
+#include <mach/usb.h>
+
+#include "common.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] = {
+ .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 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,
+ .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)
+ pr_err("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)
+{
+ omap7xx_map_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 */
+ htcpld_resources[0].start = gpio_to_irq(HTCHERALD_GIRQ_BTNS);
+ htcpld_resources[0].end = gpio_to_irq(HTCHERALD_GIRQ_BTNS);
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ htcherald_disable_watchdog();
+
+ htcherald_usb_enable();
+ omap1_usb_init(&htcherald_usb_config);
+
+ htcherald_spi_board_info[0].irq = gpio_to_irq(HTCHERALD_GPIO_TS);
+ 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
+
+ omapfb_set_lcd_config(&htcherald_lcd_config);
+}
+
+MACHINE_START(HERALD, "HTC Herald")
+ /* Maintainer: Cory Maccarrone <darkstar6262@gmail.com> */
+ /* Maintainer: wing-linux.sourceforge.net */
+ .atag_offset = 0x100,
+ .map_io = htcherald_map_io,
+ .init_early = omap1_init_early,
+ .init_irq = omap1_init_irq,
+ .init_machine = htcherald_init,
+ .init_late = omap1_init_late,
+ .init_time = omap1_timer_init,
+ .restart = omap1_restart,
+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 000000000..c49ce83cc
--- /dev/null
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -0,0 +1,463 @@
+/*
+ * 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/gpio.h>
+#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 <linux/omapfb.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/mux.h>
+#include <mach/flash.h>
+#include <mach/tc.h>
+#include <linux/platform_data/keypad-omap.h>
+
+#include <mach/hardware.h>
+#include <mach/usb.h>
+
+#include "iomap.h"
+#include "common.h"
+#include "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 !(__raw_readb(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] = {
+ .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()) {
+ __raw_writeb(__raw_readb(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;
+ }
+ }
+}
+
+#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,
+
+#if IS_ENABLED(CONFIG_USB_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)
+ __raw_writeb(__raw_readb(OMAP1510_FPGA_POWER) | (1 << 3),
+ OMAP1510_FPGA_POWER);
+ else
+ __raw_writeb(__raw_readb(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 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 = __raw_readb(OMAP1510_FPGA_POWER);
+ reg |= OMAP1510_FPGA_PCR_COM1_EN;
+ __raw_writeb(reg, OMAP1510_FPGA_POWER);
+ udelay(10);
+
+ reg = __raw_readb(OMAP1510_FPGA_POWER);
+ reg |= OMAP1510_FPGA_PCR_COM2_EN;
+ __raw_writeb(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()) {
+ innovator1610_smc91x_resources[1].start = gpio_to_irq(0);
+ innovator1610_smc91x_resources[1].end = gpio_to_irq(0);
+ platform_add_devices(innovator1610_devices, ARRAY_SIZE(innovator1610_devices));
+ }
+#endif
+
+#ifdef CONFIG_ARCH_OMAP15XX
+ if (cpu_is_omap1510()) {
+ omap1_usb_init(&innovator1510_usb_config);
+ omapfb_set_lcd_config(&innovator1510_lcd_config);
+ }
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+ if (cpu_is_omap1610()) {
+ omap1_usb_init(&h2_usb_config);
+ omapfb_set_lcd_config(&innovator1610_lcd_config);
+ }
+#endif
+ omap_serial_init();
+ omap_register_i2c_bus(1, 100, NULL, 0);
+ innovator_mmc_init();
+}
+
+/*
+ * REVISIT: Assume 15xx for now, we don't want to do revision check
+ * until later on. The right way to fix this is to set up a different
+ * machine_id for 16xx Innovator, or use device tree.
+ */
+static void __init innovator_map_io(void)
+{
+#ifdef CONFIG_ARCH_OMAP15XX
+ omap15xx_map_io();
+
+ 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. */
+ pr_debug("Innovator FPGA Rev %d.%d Board Rev %d\n",
+ __raw_readb(OMAP1510_FPGA_REV_HIGH),
+ __raw_readb(OMAP1510_FPGA_REV_LOW),
+ __raw_readb(OMAP1510_FPGA_BOARD_REV));
+#endif
+}
+
+MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
+ /* Maintainer: MontaVista Software, Inc. */
+ .atag_offset = 0x100,
+ .map_io = innovator_map_io,
+ .init_early = omap1_init_early,
+ .init_irq = omap1_init_irq,
+ .init_machine = innovator_init,
+ .init_late = omap1_init_late,
+ .init_time = omap1_timer_init,
+ .restart = omap1_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-nand.c b/arch/arm/mach-omap1/board-nand.c
new file mode 100644
index 000000000..4d0835327
--- /dev/null
+++ b/arch/arm/mach-omap1/board-nand.c
@@ -0,0 +1,37 @@
+/*
+ * linux/arch/arm/mach-omap1/board-nand.c
+ *
+ * Common OMAP1 board NAND code
+ *
+ * Copyright (C) 2004, 2012 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/kernel.h>
+#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+
+#include "common.h"
+
+void omap1_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, this->IO_ADDR_W + mask);
+}
+
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
new file mode 100644
index 000000000..85089d821
--- /dev/null
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -0,0 +1,301 @@
+/*
+ * 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/irq.h>
+#include <linux/gpio.h>
+#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 <linux/platform_data/keypad-omap.h>
+#include <linux/platform_data/lcd-mipid.h>
+#include <linux/platform_data/gpio-omap.h>
+#include <linux/platform_data/i2c-cbus-gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/mux.h>
+
+#include <mach/hardware.h>
+#include <mach/usb.h>
+
+#include "common.h"
+#include "clock.h"
+#include "mmc.h"
+
+#define ADS7846_PENDOWN_GPIO 15
+
+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 struct omap_lcd_config nokia770_lcd_config __initdata = {
+ .ctrl_name = "hwa742",
+};
+
+static void __init mipid_dev_init(void)
+{
+ nokia770_mipid_platform_data.nreset_gpio = 13;
+ nokia770_mipid_platform_data.data_lines = 16;
+
+ omapfb_set_lcd_config(&nokia770_lcd_config);
+}
+
+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,
+ .gpio_pendown = ADS7846_PENDOWN_GPIO,
+};
+
+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,
+ .platform_data = &nokia770_ads7846_platform_data,
+ },
+};
+
+static void __init hwa742_dev_init(void)
+{
+ clk_add_alias("hwa_sys_ck", NULL, "bclk", NULL);
+}
+
+/* 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,
+ .extcon = "tahvo-usb",
+};
+
+#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,
+ .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
+
+#if defined(CONFIG_I2C_CBUS_GPIO) || defined(CONFIG_I2C_CBUS_GPIO_MODULE)
+static struct i2c_cbus_platform_data nokia770_cbus_data = {
+ .clk_gpio = OMAP_MPUIO(9),
+ .dat_gpio = OMAP_MPUIO(10),
+ .sel_gpio = OMAP_MPUIO(11),
+};
+
+static struct platform_device nokia770_cbus_device = {
+ .name = "i2c-cbus-gpio",
+ .id = 2,
+ .dev = {
+ .platform_data = &nokia770_cbus_data,
+ },
+};
+
+static struct i2c_board_info nokia770_i2c_board_info_2[] __initdata = {
+ {
+ I2C_BOARD_INFO("retu-mfd", 0x01),
+ },
+ {
+ I2C_BOARD_INFO("tahvo-mfd", 0x02),
+ },
+};
+
+static void __init nokia770_cbus_init(void)
+{
+ const int retu_irq_gpio = 62;
+ const int tahvo_irq_gpio = 40;
+
+ if (gpio_request_one(retu_irq_gpio, GPIOF_IN, "Retu IRQ"))
+ return;
+ if (gpio_request_one(tahvo_irq_gpio, GPIOF_IN, "Tahvo IRQ")) {
+ gpio_free(retu_irq_gpio);
+ return;
+ }
+ irq_set_irq_type(gpio_to_irq(retu_irq_gpio), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(tahvo_irq_gpio), IRQ_TYPE_EDGE_RISING);
+ nokia770_i2c_board_info_2[0].irq = gpio_to_irq(retu_irq_gpio);
+ nokia770_i2c_board_info_2[1].irq = gpio_to_irq(tahvo_irq_gpio);
+ i2c_register_board_info(2, nokia770_i2c_board_info_2,
+ ARRAY_SIZE(nokia770_i2c_board_info_2));
+ platform_device_register(&nokia770_cbus_device);
+}
+#else /* CONFIG_I2C_CBUS_GPIO */
+static void __init nokia770_cbus_init(void)
+{
+}
+#endif /* CONFIG_I2C_CBUS_GPIO */
+
+static void __init omap_nokia770_init(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);
+
+ platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices));
+ nokia770_spi_board_info[1].irq = gpio_to_irq(15);
+ 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();
+ mipid_dev_init();
+ omap1_usb_init(&nokia770_usb_config);
+ nokia770_mmc_init();
+ nokia770_cbus_init();
+}
+
+MACHINE_START(NOKIA770, "Nokia 770")
+ .atag_offset = 0x100,
+ .map_io = omap16xx_map_io,
+ .init_early = omap1_init_early,
+ .init_irq = omap1_init_irq,
+ .init_machine = omap_nokia770_init,
+ .init_late = omap1_init_late,
+ .init_time = omap1_timer_init,
+ .restart = omap1_restart,
+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 000000000..7436d4cf6
--- /dev/null
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -0,0 +1,617 @@
+/*
+ * 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/gpio.h>
+#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/omapfb.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c/tps65010.h>
+#include <linux/platform_data/gpio-omap.h>
+#include <linux/platform_data/omap1_bl.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/flash.h>
+#include <mach/mux.h>
+#include <mach/tc.h>
+
+#include <mach/hardware.h>
+#include <mach/usb.h>
+
+#include "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] = {
+ .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] = {
+ .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)
+{
+ if (!IS_BUILTIN(CONFIG_TPS65010))
+ return -ENOSYS;
+
+ /* 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),
+ .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 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.
+ */
+#if IS_ENABLED(CONFIG_USB_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
+
+#ifdef CONFIG_OMAP_OSK_MISTRAL
+
+#include <linux/input.h>
+#include <linux/platform_data/at24.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+#include <linux/platform_data/keypad-omap.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 gpio_led mistral_gpio_led_pins[] = {
+ {
+ .name = "mistral:red",
+ .default_trigger = "heartbeat",
+ .gpio = 3,
+ },
+ {
+ .name = "mistral:green",
+ .default_trigger = "cpu0",
+ .gpio = OMAP_MPUIO(4),
+ },
+};
+
+static struct gpio_led_platform_data mistral_gpio_led_data = {
+ .leds = mistral_gpio_led_pins,
+ .num_leds = ARRAY_SIZE(mistral_gpio_led_pins),
+};
+
+static struct platform_device mistral_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &mistral_gpio_led_data,
+ },
+};
+
+static struct platform_device *mistral_devices[] __initdata = {
+ &osk5912_kp_device,
+ &mistral_bl_device,
+ &osk5912_lcd_device,
+ &mistral_gpio_leds,
+};
+
+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,
+ .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);
+
+ mistral_boardinfo[0].irq = gpio_to_irq(4);
+ 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);
+
+ /*
+ * GPIO based LEDs
+ */
+ omap_cfg_reg(P18_1610_GPIO3);
+ omap_cfg_reg(MPUIO4);
+
+ 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;
+ osk5912_smc91x_resources[1].start = gpio_to_irq(0);
+ osk5912_smc91x_resources[1].end = gpio_to_irq(0);
+ osk5912_cf_resources[0].start = gpio_to_irq(62);
+ osk5912_cf_resources[0].end = gpio_to_irq(62);
+ platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
+
+ 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();
+ osk_i2c_board_info[0].irq = gpio_to_irq(OMAP_MPUIO(1));
+ omap_register_i2c_bus(1, 400, osk_i2c_board_info,
+ ARRAY_SIZE(osk_i2c_board_info));
+ osk_mistral_init();
+
+#ifdef CONFIG_OMAP_OSK_MISTRAL
+ omapfb_set_lcd_config(&osk_lcd_config);
+#endif
+
+}
+
+MACHINE_START(OMAP_OSK, "TI-OSK")
+ /* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */
+ .atag_offset = 0x100,
+ .map_io = omap16xx_map_io,
+ .init_early = omap1_init_early,
+ .init_irq = omap1_init_irq,
+ .init_machine = osk_init,
+ .init_late = omap1_init_late,
+ .init_time = omap1_timer_init,
+ .restart = omap1_restart,
+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 000000000..3b8e98f43
--- /dev/null
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -0,0 +1,242 @@
+/*
+ * 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/gpio.h>
+#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 <linux/omapfb.h>
+#include <linux/platform_data/omap1_bl.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/flash.h>
+#include <mach/mux.h>
+#include <mach/tc.h>
+#include <linux/omap-dma.h>
+#include <linux/platform_data/keypad-omap.h>
+
+#include <mach/hardware.h>
+#include <mach/usb.h>
+
+#include "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 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 platform_device *palmte_devices[] __initdata = {
+ &palmte_rom_device,
+ &palmte_kp_device,
+ &palmte_lcd_device,
+ &palmte_backlight_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 spi_board_info palmte_spi_info[] __initdata = {
+ {
+ .modalias = "tsc2102",
+ .bus_num = 2, /* uWire (officially) */
+ .chip_select = 0, /* As opposed to 3 */
+ .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);
+
+ platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices));
+
+ palmte_spi_info[0].irq = gpio_to_irq(PALMTE_PINTDAV_GPIO);
+ 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);
+
+ omapfb_set_lcd_config(&palmte_lcd_config);
+}
+
+MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
+ .atag_offset = 0x100,
+ .map_io = omap15xx_map_io,
+ .init_early = omap1_init_early,
+ .init_irq = omap1_init_irq,
+ .init_machine = omap_palmte_init,
+ .init_late = omap1_init_late,
+ .init_time = omap1_timer_init,
+ .restart = omap1_restart,
+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 000000000..ca5012088
--- /dev/null
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -0,0 +1,289 @@
+/*
+ * 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/gpio.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 <linux/omapfb.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/platform_data/omap1_bl.h>
+#include <linux/platform_data/leds-omap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/flash.h>
+#include <mach/mux.h>
+#include <linux/omap-dma.h>
+#include <mach/tc.h>
+#include <linux/platform_data/keypad-omap.h>
+
+#include <mach/hardware.h>
+#include <mach/usb.h>
+
+#include "common.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 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_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,
+ .max_speed_hz = 120000 /* max sample rate at 3V */
+ * 26 /* command + data + overhead */,
+ .bus_num = 2,
+ .chip_select = 0,
+ }
+};
+
+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 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);
+
+ platform_add_devices(palmtt_devices, ARRAY_SIZE(palmtt_devices));
+
+ palmtt_boardinfo[0].irq = gpio_to_irq(6);
+ 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);
+
+ omapfb_set_lcd_config(&palmtt_lcd_config);
+}
+
+MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T")
+ .atag_offset = 0x100,
+ .map_io = omap15xx_map_io,
+ .init_early = omap1_init_early,
+ .init_irq = omap1_init_irq,
+ .init_machine = omap_palmtt_init,
+ .init_late = omap1_init_late,
+ .init_time = omap1_timer_init,
+ .restart = omap1_restart,
+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 000000000..470e12d67
--- /dev/null
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -0,0 +1,304 @@
+/*
+ * 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/gpio.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 <linux/omapfb.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/platform_data/omap1_bl.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/flash.h>
+#include <mach/mux.h>
+#include <linux/omap-dma.h>
+#include <mach/tc.h>
+#include <linux/platform_data/keypad-omap.h>
+
+#include <mach/hardware.h>
+#include <mach/usb.h>
+
+#include "common.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 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 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_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,
+ .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 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, 0, "palmz71-cable", NULL))
+ printk(KERN_ERR
+ "IRQ request for power cable failed!\n");
+ palmz71_powercable(gpio_to_irq(PALMZ71_USBDETECT_GPIO), NULL);
+ }
+}
+
+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);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ palmz71_boardinfo[0].irq = gpio_to_irq(PALMZ71_PENIRQ_GPIO);
+ 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);
+
+ omapfb_set_lcd_config(&palmz71_lcd_config);
+}
+
+MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71")
+ .atag_offset = 0x100,
+ .map_io = omap15xx_map_io,
+ .init_early = omap1_init_early,
+ .init_irq = omap1_init_irq,
+ .init_machine = omap_palmz71_init,
+ .init_late = omap1_init_late,
+ .init_time = omap1_timer_init,
+ .restart = omap1_restart,
+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 000000000..8b2f7127f
--- /dev/null
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -0,0 +1,331 @@
+/*
+ * 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/gpio.h>
+#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 <linux/omapfb.h>
+#include <linux/platform_data/keypad-omap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/tc.h>
+#include <mach/mux.h>
+#include <mach/flash.h>
+
+#include <mach/hardware.h>
+
+#include "iomap.h"
+#include "common.h"
+#include "fpga.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,
+};
+
+#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 struct platform_nand_data nand_data = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_offset = 0,
+ .options = NAND_SAMSUNG_LP_OPTIONS,
+ },
+ .ctrl = {
+ .cmd_ctrl = omap1_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 *devices[] __initdata = {
+ &nor_device,
+ &nand_device,
+ &smc91x_device,
+ &kp_device,
+};
+
+static struct omap_lcd_config perseus2_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static void __init perseus2_init_smc91x(void)
+{
+ __raw_writeb(1, H2P2_DBG_FPGA_LAN_RESET);
+ mdelay(50);
+ __raw_writeb(__raw_readb(H2P2_DBG_FPGA_LAN_RESET) & ~1,
+ H2P2_DBG_FPGA_LAN_RESET);
+ mdelay(50);
+}
+
+static void __init omap_perseus2_init(void)
+{
+ /* 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);
+
+ perseus2_init_smc91x();
+
+ BUG_ON(gpio_request(P2_NAND_RB_GPIO_PIN, "NAND ready") < 0);
+ 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_serial_init();
+ omap_register_i2c_bus(1, 100, NULL, 0);
+
+ omapfb_set_lcd_config(&perseus2_lcd_config);
+}
+
+/* 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)
+{
+ omap7xx_map_io();
+ iotable_init(omap_perseus2_io_desc,
+ ARRAY_SIZE(omap_perseus2_io_desc));
+}
+
+MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
+ /* Maintainer: Kevin Hilman <kjh@hilman.org> */
+ .atag_offset = 0x100,
+ .map_io = omap_perseus2_map_io,
+ .init_early = omap1_init_early,
+ .init_irq = omap1_init_irq,
+ .init_machine = omap_perseus2_init,
+ .init_late = omap1_init_late,
+ .init_time = omap1_timer_init,
+ .restart = omap1_restart,
+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 000000000..4fcf19c78
--- /dev/null
+++ b/arch/arm/mach-omap1/board-sx1-mmc.c
@@ -0,0 +1,67 @@
+/*
+ * 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/gpio.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <mach/board-sx1.h>
+
+#include "mmc.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 000000000..29e526235
--- /dev/null
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -0,0 +1,350 @@
+/*
+* 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/gpio.h>
+#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 <linux/export.h>
+#include <linux/omapfb.h>
+#include <linux/platform_data/keypad-omap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/flash.h>
+#include <mach/mux.h>
+#include <linux/omap-dma.h>
+#include <mach/tc.h>
+#include <mach/board-sx1.h>
+
+#include <mach/hardware.h>
+#include <mach/usb.h>
+
+#include "common.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,
+};
+
+/*----------- 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),
+};
+
+/* 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,
+};
+
+/*----------- 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 omap_lcd_config sx1_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+/*-----------------------------------------*/
+static struct platform_device *sx1_devices[] __initdata = {
+ &sx1_flash_device,
+ &sx1_kp_device,
+};
+
+/*-----------------------------------------*/
+
+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_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 */
+
+ omapfb_set_lcd_config(&sx1_lcd_config);
+}
+
+MACHINE_START(SX1, "OMAP310 based Siemens SX1")
+ .atag_offset = 0x100,
+ .map_io = omap15xx_map_io,
+ .init_early = omap1_init_early,
+ .init_irq = omap1_init_irq,
+ .init_machine = omap_sx1_init,
+ .init_late = omap1_init_late,
+ .init_time = omap1_timer_init,
+ .restart = omap1_restart,
+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 000000000..4677a9ccb
--- /dev/null
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -0,0 +1,295 @@
+/*
+ * 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/gpio.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 <linux/export.h>
+#include <linux/reboot.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/board-voiceblue.h>
+#include <mach/flash.h>
+#include <mach/mux.h>
+#include <mach/tc.h>
+
+#include <mach/hardware.h>
+#include <mach/usb.h>
+
+#include "common.h"
+
+static struct plat_serial8250_port voiceblue_ports[] = {
+ {
+ .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x40000),
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = 3686400,
+ },
+ {
+ .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x50000),
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = 3686400,
+ },
+ {
+ .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x60000),
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = 3686400,
+ },
+ {
+ .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x70000),
+ .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,
+};
+
+static int __init ext_uart_init(void)
+{
+ if (!machine_is_voiceblue())
+ return -ENODEV;
+
+ voiceblue_ports[0].irq = gpio_to_irq(12);
+ voiceblue_ports[1].irq = gpio_to_irq(13);
+ voiceblue_ports[2].irq = gpio_to_irq(14);
+ voiceblue_ports[3].irq = gpio_to_irq(15);
+ serial_device.dev.platform_data = voiceblue_ports;
+ 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] = {
+ .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,
+};
+
+#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_restart(enum reboot_mode 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);
+
+ voiceblue_smc91x_resources[1].start = gpio_to_irq(8);
+ voiceblue_smc91x_resources[1].end = gpio_to_irq(8);
+ platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices));
+ 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 */
+}
+
+MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")
+ /* Maintainer: Ladislav Michl <michl@2n.cz> */
+ .atag_offset = 0x100,
+ .map_io = omap15xx_map_io,
+ .init_early = omap1_init_early,
+ .init_irq = omap1_init_irq,
+ .init_machine = voiceblue_init,
+ .init_late = omap1_init_late,
+ .init_time = omap1_timer_init,
+ .restart = voiceblue_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
new file mode 100644
index 000000000..4f5fd4a08
--- /dev/null
+++ b/arch/arm/mach-omap1/clock.c
@@ -0,0 +1,1104 @@
+/*
+ * 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/export.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/hardware.h>
+
+#include "soc.h"
+#include "iomap.h"
+#include "clock.h"
+#include "opp.h"
+#include "sram.h"
+
+__u32 arm_idlect1_mask;
+struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+static DEFINE_SPINLOCK(clockfw_lock);
+
+/*
+ * 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 ref_rate;
+
+ ref_rate = ck_ref_p->rate;
+
+ for (ptr = omap1_rate_table; ptr->rate; ptr++) {
+ if (!(ptr->flags & cpu_mask))
+ continue;
+
+ if (ptr->xtal != ref_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.
+ */
+ 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->flags & cpu_mask))
+ continue;
+
+ 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) {
+ pr_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
+
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+ int ret;
+
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ ret = omap1_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;
+
+ 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;
+ }
+
+ omap1_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;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ ret = omap1_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;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ ret = omap1_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)
+{
+ WARN_ONCE(1, "clk_set_parent() not implemented for OMAP1\n");
+
+ return -EINVAL;
+}
+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_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;
+
+ pr_info("clock: disabling unused clocks to save power\n");
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ list_for_each_entry(ck, &clocks, node) {
+ if (ck->ops == &clkops_null)
+ continue;
+
+ if (ck->usecount > 0 || !ck->enable_reg)
+ continue;
+
+ omap1_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
+
+#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
+/*
+ * debugfs support to trace clock tree hierarchy and attributes
+ */
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static struct dentry *clk_debugfs_root;
+
+static int clk_dbg_show_summary(struct seq_file *s, void *unused)
+{
+ struct clk *c;
+ struct clk *pa;
+
+ mutex_lock(&clocks_mutex);
+ seq_printf(s, "%-30s %-30s %-10s %s\n",
+ "clock-name", "parent-name", "rate", "use-count");
+
+ list_for_each_entry(c, &clocks, node) {
+ pa = c->parent;
+ seq_printf(s, "%-30s %-30s %-10lu %d\n",
+ c->name, pa ? pa->name : "none", c->rate,
+ c->usecount);
+ }
+ mutex_unlock(&clocks_mutex);
+
+ return 0;
+}
+
+static int clk_dbg_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, clk_dbg_show_summary, inode->i_private);
+}
+
+static const struct file_operations debug_clock_fops = {
+ .open = clk_dbg_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int clk_debugfs_register_one(struct clk *c)
+{
+ int err;
+ struct dentry *d;
+ struct clk *pa = c->parent;
+
+ d = debugfs_create_dir(c->name, 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:
+ debugfs_remove_recursive(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;
+ }
+
+ d = debugfs_create_file("summary", S_IRUGO,
+ d, NULL, &debug_clock_fops);
+ if (!d)
+ return -ENOMEM;
+
+ 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/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
new file mode 100644
index 000000000..1e4918a3a
--- /dev/null
+++ b/arch/arm/mach-omap1/clock.h
@@ -0,0 +1,293 @@
+/*
+ * 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 <linux/list.h>
+
+#include <linux/clkdev.h>
+
+struct module;
+struct clk;
+
+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_1710 (1 << 4) /* 1710 extra for rate selection */
+
+
+/* Temporary, needed during the common clock framework conversion */
+#define __clk_get_name(clk) (clk->name)
+#define __clk_get_parent(clk) (clk->parent)
+#define __clk_get_rate(clk) (clk->rate)
+
+/**
+ * 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 *);
+};
+
+/*
+ * 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
+ * @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;
+ u8 rate_offset;
+ u8 src_offset;
+#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
+ struct dentry *dent; /* For visible tree hierarchy */
+#endif
+};
+
+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);
+};
+
+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);
+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;
+
+int omap1_clk_init(void);
+void omap1_clk_late_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;
+
+/* used for passing SoC type to omap1_{select,round_to}_table_rate() */
+extern u32 cpu_mask;
+
+#endif
diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c
new file mode 100644
index 000000000..6c4f76636
--- /dev/null
+++ b/arch/arm/mach-omap1/clock_data.c
@@ -0,0 +1,924 @@
+/*
+ * 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/io.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+
+#include <asm/mach-types.h> /* for machine_is_* */
+
+#include "soc.h"
+
+#include <mach/hardware.h>
+#include <mach/usb.h> /* for OTG_BASE */
+
+#include "iomap.h"
+#include "clock.h"
+#include "sram.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 = 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 | 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 void __init omap1_show_rates(void)
+{
+ pr_notice("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);
+}
+
+u32 cpu_mask;
+
+int __init omap1_clk_init(void)
+{
+ struct omap_clk *c;
+ int crystal_type = 0; /* Default 12 MHz */
+ u32 reg;
+
+#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);
+
+ /* 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_omap1710())
+ cpu_mask |= CK_1710;
+ 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");
+
+ 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);
+
+
+ /*
+ * Initially use the values set by bootloader. Determine PLL rate and
+ * recalculate dependent clocks as if kernel had changed PLL or
+ * divisors. See also omap1_clk_late_init() that can reprogram dpll1
+ * after the SRAM is initialized.
+ */
+ {
+ 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;
+ }
+ }
+ }
+ propagate_rate(&ck_dpll1);
+ /* Cache rates for clocks connected to ck_ref (not dpll1) */
+ propagate_rate(&ck_ref);
+ omap1_show_rates();
+ 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;
+}
+
+#define OMAP1_DPLL1_SANE_VALUE 60000000
+
+void __init omap1_clk_late_init(void)
+{
+ unsigned long rate = ck_dpll1.rate;
+
+ /* Find the highest supported frequency and enable it */
+ if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
+ pr_err("System frequencies not set, using default. Check your config.\n");
+ /*
+ * Reprogramming the DPLL is tricky, it must be done from SRAM.
+ */
+ omap_sram_reprogram_clock(0x2290, 0x0005);
+ ck_dpll1.rate = OMAP1_DPLL1_SANE_VALUE;
+ }
+ propagate_rate(&ck_dpll1);
+ omap1_show_rates();
+ loops_per_jiffy = cpufreq_scale(loops_per_jiffy, rate, ck_dpll1.rate);
+}
diff --git a/arch/arm/mach-omap1/common.h b/arch/arm/mach-omap1/common.h
new file mode 100644
index 000000000..732f8ee2f
--- /dev/null
+++ b/arch/arm/mach-omap1/common.h
@@ -0,0 +1,104 @@
+/*
+ *
+ * Header for code common to all OMAP1 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_OMAP1_COMMON_H
+#define __ARCH_ARM_MACH_OMAP1_COMMON_H
+
+#include <linux/mtd/mtd.h>
+#include <linux/i2c-omap.h>
+#include <linux/reboot.h>
+
+#include <plat/i2c.h>
+
+#include <mach/irqs.h>
+
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+void omap7xx_map_io(void);
+#else
+static inline void omap7xx_map_io(void)
+{
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP15XX
+void omap1510_fpga_init_irq(void);
+void omap15xx_map_io(void);
+#else
+static inline void omap1510_fpga_init_irq(void)
+{
+}
+static inline void omap15xx_map_io(void)
+{
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP16XX
+void omap16xx_map_io(void);
+#else
+static inline void omap16xx_map_io(void)
+{
+}
+#endif
+
+#ifdef CONFIG_OMAP_SERIAL_WAKE
+int omap_serial_wakeup_init(void);
+#else
+static inline int omap_serial_wakeup_init(void)
+{
+ return 0;
+}
+#endif
+
+void omap1_init_early(void);
+void omap1_init_irq(void);
+void omap1_init_late(void);
+void omap1_restart(enum reboot_mode, const char *);
+
+extern void __init omap_check_revision(void);
+
+extern void omap1_nand_cmd_ctl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl);
+
+extern void omap1_timer_init(void);
+#ifdef CONFIG_OMAP_32K_TIMER
+extern int omap_32k_timer_init(void);
+#else
+static inline int __init omap_32k_timer_init(void)
+{
+ return -ENODEV;
+}
+#endif
+
+extern u32 omap_irq_flags;
+
+#ifdef CONFIG_ARCH_OMAP16XX
+extern int ocpi_enable(void);
+#else
+static inline int ocpi_enable(void) { return 0; }
+#endif
+
+extern u32 omap1_get_reset_sources(void);
+
+#endif /* __ARCH_ARM_MACH_OMAP1_COMMON_H */
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
new file mode 100644
index 000000000..325e60300
--- /dev/null
+++ b/arch/arm/mach-omap1/devices.c
@@ -0,0 +1,478 @@
+/*
+ * 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/gpio.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+
+#include <linux/platform_data/omap-wd-timer.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/tc.h>
+#include <mach/mux.h>
+
+#include <mach/omap7xx.h>
+#include <mach/camera.h>
+#include <mach/hardware.h>
+
+#include "common.h"
+#include "clock.h"
+#include "mmc.h"
+#include "sram.h"
+
+#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
+
+static struct platform_device omap_pcm = {
+ .name = "omap-pcm-audio",
+ .id = -1,
+};
+
+static void omap_init_audio(void)
+{
+ platform_device_register(&omap_pcm);
+}
+
+#else
+static inline void omap_init_audio(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#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);
+ }
+}
+
+#define OMAP_MMC_NR_RES 4
+
+/*
+ * Register MMC devices.
+ */
+static int __init omap_mmc_add(const char *name, int id, unsigned long base,
+ unsigned long size, unsigned int irq,
+ unsigned rx_req, unsigned tx_req,
+ 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;
+ res[2].start = rx_req;
+ res[2].name = "rx";
+ res[2].flags = IORESOURCE_DMA;
+ res[3].start = tx_req;
+ res[3].name = "tx";
+ res[3].flags = IORESOURCE_DMA;
+
+ if (cpu_is_omap7xx())
+ data->slots[0].features = MMC_OMAP7XX;
+ if (cpu_is_omap15xx())
+ data->slots[0].features = MMC_OMAP15XX;
+ if (cpu_is_omap16xx())
+ data->slots[0].features = MMC_OMAP16XX;
+
+ 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;
+}
+
+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 rx_req, tx_req;
+ 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;
+ rx_req = 22;
+ tx_req = 21;
+ break;
+ case 1:
+ if (!cpu_is_omap16xx())
+ return;
+ base = OMAP1_MMC2_BASE;
+ irq = INT_1610_MMC2;
+ rx_req = 55;
+ tx_req = 54;
+ break;
+ default:
+ continue;
+ }
+ size = OMAP1_MMC_SIZE;
+
+ omap_mmc_add("mmci-omap", i, base, size, irq,
+ rx_req, tx_req, 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) {}
+
+/* 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
+
+
+#define OMAP1_RNG_BASE 0xfffe5000
+
+static struct resource omap1_rng_resources[] = {
+ {
+ .start = OMAP1_RNG_BASE,
+ .end = OMAP1_RNG_BASE + 0x4f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device omap1_rng_device = {
+ .name = "omap_rng",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(omap1_rng_resources),
+ .resource = omap1_rng_resources,
+};
+
+static void omap1_init_rng(void)
+{
+ if (!cpu_is_omap16xx())
+ return;
+
+ (void) platform_device_register(&omap1_rng_device);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * 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;
+
+ omap_sram_init();
+ omap1_clk_late_init();
+
+ /* please keep these calls, and their implementations above,
+ * in alphabetical order so they're easier to sort through.
+ */
+
+ omap_init_audio();
+ omap_init_mbox();
+ omap_init_rtc();
+ omap_init_spi100k();
+ omap_init_sti();
+ omap_init_uwire();
+ omap1_init_rng();
+
+ 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)
+{
+ struct omap_wd_timer_platform_data pdata;
+ int ret;
+
+ if (!cpu_is_omap16xx())
+ return -ENODEV;
+
+ pdata.read_reset_sources = omap1_get_reset_sources;
+
+ ret = platform_device_register(&omap_wdt_device);
+ if (!ret) {
+ ret = platform_device_add_data(&omap_wdt_device, &pdata,
+ sizeof(pdata));
+ if (ret)
+ platform_device_del(&omap_wdt_device);
+ }
+
+ return ret;
+}
+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 000000000..4be601b63
--- /dev/null
+++ b/arch/arm/mach-omap1/dma.c
@@ -0,0 +1,378 @@
+/*
+ * 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/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/omap-dma.h>
+#include <mach/tc.h>
+
+#include <mach/irqs.h>
+
+#define OMAP1_DMA_BASE (0xfffed800)
+#define OMAP1_LOGICAL_DMA_CH_COUNT 17
+
+static u32 enable_1510_mode;
+
+static const struct omap_dma_reg reg_map[] = {
+ [GCR] = { 0x0400, 0x00, OMAP_DMA_REG_16BIT },
+ [GSCR] = { 0x0404, 0x00, OMAP_DMA_REG_16BIT },
+ [GRST1] = { 0x0408, 0x00, OMAP_DMA_REG_16BIT },
+ [HW_ID] = { 0x0442, 0x00, OMAP_DMA_REG_16BIT },
+ [PCH2_ID] = { 0x0444, 0x00, OMAP_DMA_REG_16BIT },
+ [PCH0_ID] = { 0x0446, 0x00, OMAP_DMA_REG_16BIT },
+ [PCH1_ID] = { 0x0448, 0x00, OMAP_DMA_REG_16BIT },
+ [PCHG_ID] = { 0x044a, 0x00, OMAP_DMA_REG_16BIT },
+ [PCHD_ID] = { 0x044c, 0x00, OMAP_DMA_REG_16BIT },
+ [CAPS_0] = { 0x044e, 0x00, OMAP_DMA_REG_2X16BIT },
+ [CAPS_1] = { 0x0452, 0x00, OMAP_DMA_REG_2X16BIT },
+ [CAPS_2] = { 0x0456, 0x00, OMAP_DMA_REG_16BIT },
+ [CAPS_3] = { 0x0458, 0x00, OMAP_DMA_REG_16BIT },
+ [CAPS_4] = { 0x045a, 0x00, OMAP_DMA_REG_16BIT },
+ [PCH2_SR] = { 0x0460, 0x00, OMAP_DMA_REG_16BIT },
+ [PCH0_SR] = { 0x0480, 0x00, OMAP_DMA_REG_16BIT },
+ [PCH1_SR] = { 0x0482, 0x00, OMAP_DMA_REG_16BIT },
+ [PCHD_SR] = { 0x04c0, 0x00, OMAP_DMA_REG_16BIT },
+
+ /* Common Registers */
+ [CSDP] = { 0x0000, 0x40, OMAP_DMA_REG_16BIT },
+ [CCR] = { 0x0002, 0x40, OMAP_DMA_REG_16BIT },
+ [CICR] = { 0x0004, 0x40, OMAP_DMA_REG_16BIT },
+ [CSR] = { 0x0006, 0x40, OMAP_DMA_REG_16BIT },
+ [CEN] = { 0x0010, 0x40, OMAP_DMA_REG_16BIT },
+ [CFN] = { 0x0012, 0x40, OMAP_DMA_REG_16BIT },
+ [CSFI] = { 0x0014, 0x40, OMAP_DMA_REG_16BIT },
+ [CSEI] = { 0x0016, 0x40, OMAP_DMA_REG_16BIT },
+ [CPC] = { 0x0018, 0x40, OMAP_DMA_REG_16BIT }, /* 15xx only */
+ [CSAC] = { 0x0018, 0x40, OMAP_DMA_REG_16BIT },
+ [CDAC] = { 0x001a, 0x40, OMAP_DMA_REG_16BIT },
+ [CDEI] = { 0x001c, 0x40, OMAP_DMA_REG_16BIT },
+ [CDFI] = { 0x001e, 0x40, OMAP_DMA_REG_16BIT },
+ [CLNK_CTRL] = { 0x0028, 0x40, OMAP_DMA_REG_16BIT },
+
+ /* Channel specific register offsets */
+ [CSSA] = { 0x0008, 0x40, OMAP_DMA_REG_2X16BIT },
+ [CDSA] = { 0x000c, 0x40, OMAP_DMA_REG_2X16BIT },
+ [COLOR] = { 0x0020, 0x40, OMAP_DMA_REG_2X16BIT },
+ [CCR2] = { 0x0024, 0x40, OMAP_DMA_REG_16BIT },
+ [LCH_CTRL] = { 0x002a, 0x40, OMAP_DMA_REG_16BIT },
+};
+
+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)
+{
+ void __iomem *addr = dma_base;
+
+ addr += reg_map[reg].offset;
+ addr += reg_map[reg].stride * lch;
+
+ __raw_writew(val, addr);
+ if (reg_map[reg].type == OMAP_DMA_REG_2X16BIT)
+ __raw_writew(val >> 16, addr + 2);
+}
+
+static inline u32 dma_read(int reg, int lch)
+{
+ void __iomem *addr = dma_base;
+ uint32_t val;
+
+ addr += reg_map[reg].offset;
+ addr += reg_map[reg].stride * lch;
+
+ val = __raw_readw(addr);
+ if (reg_map[reg].type == OMAP_DMA_REG_2X16BIT)
+ val |= __raw_readw(addr + 2) << 16;
+
+ return val;
+}
+
+static void omap1_clear_lch_regs(int lch)
+{
+ int i;
+
+ for (i = CPC; i <= COLOR; 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 unsigned configure_dma_errata(void)
+{
+ unsigned errata = 0;
+
+ /*
+ * 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 const struct platform_device_info omap_dma_dev_info = {
+ .name = "omap-dma-engine",
+ .id = -1,
+ .dma_mask = DMA_BIT_MASK(32),
+ .res = res,
+ .num_res = 1,
+};
+
+static struct omap_system_dma_plat_info dma_plat_info __initdata = {
+ .reg_map = reg_map,
+ .channel_stride = 0x40,
+ .show_dma_caps = omap1_show_dma_caps,
+ .clear_lch_regs = omap1_clear_lch_regs,
+ .clear_dma = omap1_clear_dma,
+ .dma_write = dma_write,
+ .dma_read = dma_read,
+};
+
+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, *dma_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_iounmap;
+ }
+
+ 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_iounmap;
+ }
+
+ 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;
+
+ if (cpu_is_omap16xx())
+ d->dev_caps = ENABLE_16XX_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;
+
+ 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_plat_info;
+ p.dma_attr = d;
+ 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_d;
+ }
+
+ 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_d;
+ }
+
+ dma_pdev = platform_device_register_full(&omap_dma_dev_info);
+ if (IS_ERR(dma_pdev)) {
+ ret = PTR_ERR(dma_pdev);
+ goto exit_release_pdev;
+ }
+
+ return ret;
+
+exit_release_pdev:
+ platform_device_del(pdev);
+exit_release_d:
+ kfree(d);
+exit_iounmap:
+ iounmap(dma_base);
+exit_device_put:
+ platform_device_put(pdev);
+
+ return ret;
+}
+arch_initcall(omap1_system_dma_init);
diff --git a/arch/arm/mach-omap1/fb.c b/arch/arm/mach-omap1/fb.c
new file mode 100644
index 000000000..c770d45c7
--- /dev/null
+++ b/arch/arm/mach-omap1/fb.c
@@ -0,0 +1,80 @@
+/*
+ * 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 <linux/dma-mapping.h>
+
+#include <asm/mach/map.h>
+
+#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
+
+static bool omapfb_lcd_configured;
+static struct omapfb_platform_data omapfb_config;
+
+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 = DMA_BIT_MASK(32),
+ .platform_data = &omapfb_config,
+ },
+ .num_resources = 0,
+};
+
+void __init omapfb_set_lcd_config(const struct omap_lcd_config *config)
+{
+ omapfb_config.lcd = *config;
+ omapfb_lcd_configured = true;
+}
+
+static int __init omap_init_fb(void)
+{
+ /*
+ * If the board file has not set the lcd config with
+ * omapfb_set_lcd_config(), don't bother registering the omapfb device
+ */
+ if (!omapfb_lcd_configured)
+ return 0;
+
+ return platform_device_register(&omap_fb_device);
+}
+
+arch_initcall(omap_init_fb);
+
+#else
+
+void __init omapfb_set_lcd_config(const struct omap_lcd_config *config)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-omap1/flash.c b/arch/arm/mach-omap1/flash.c
new file mode 100644
index 000000000..b3fb531af
--- /dev/null
+++ b/arch/arm/mach-omap1/flash.c
@@ -0,0 +1,28 @@
+/*
+ * 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/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+
+#include <mach/tc.h>
+#include <mach/flash.h>
+
+#include <mach/hardware.h>
+
+void omap1_set_vpp(struct platform_device *pdev, int enable)
+{
+ u32 l;
+
+ l = omap_readl(EMIFS_CONFIG);
+ if (enable)
+ l |= OMAP_EMIFS_CONFIG_WP;
+ else
+ 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 000000000..3c0e42219
--- /dev/null
+++ b/arch/arm/mach-omap1/fpga.c
@@ -0,0 +1,190 @@
+/*
+ * 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/gpio.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+
+#include "iomap.h"
+#include "common.h"
+#include "fpga.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);
+}
+
+static 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 run with all interrupts masked.
+ *
+ * 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/fpga.h b/arch/arm/mach-omap1/fpga.h
new file mode 100644
index 000000000..4b4307a80
--- /dev/null
+++ b/arch/arm/mach-omap1/fpga.h
@@ -0,0 +1,52 @@
+/*
+ * 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
+
+/*
+ * ---------------------------------------------------------------------------
+ * 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 */
+
+/* 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)
+
+#endif
diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
new file mode 100644
index 000000000..312a0924d
--- /dev/null
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -0,0 +1,123 @@
+/*
+ * 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>
+#include <linux/platform_data/gpio-omap.h>
+
+#include <mach/irqs.h>
+
+#define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE
+#define OMAP1510_GPIO_BASE 0xFFFCE000
+
+/* gpio1 */
+static struct 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 omap_gpio_reg_offs omap15xx_mpuio_regs = {
+ .revision = USHRT_MAX,
+ .direction = OMAP_MPUIO_IO_CNTL,
+ .datain = OMAP_MPUIO_INPUT_LATCH,
+ .dataout = OMAP_MPUIO_OUTPUT,
+ .irqstatus = OMAP_MPUIO_GPIO_INT,
+ .irqenable = OMAP_MPUIO_GPIO_MASKIT,
+ .irqenable_inv = true,
+ .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE,
+};
+
+static struct omap_gpio_platform_data omap15xx_mpu_gpio_config = {
+ .is_mpuio = true,
+ .bank_width = 16,
+ .bank_stride = 1,
+ .regs = &omap15xx_mpuio_regs,
+};
+
+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 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 omap_gpio_reg_offs omap15xx_gpio_regs = {
+ .revision = USHRT_MAX,
+ .direction = OMAP1510_GPIO_DIR_CONTROL,
+ .datain = OMAP1510_GPIO_DATA_INPUT,
+ .dataout = OMAP1510_GPIO_DATA_OUTPUT,
+ .irqstatus = OMAP1510_GPIO_INT_STATUS,
+ .irqenable = OMAP1510_GPIO_INT_MASK,
+ .irqenable_inv = true,
+ .irqctrl = OMAP1510_GPIO_INT_CONTROL,
+ .pinctrl = OMAP1510_GPIO_PIN_CONTROL,
+};
+
+static struct omap_gpio_platform_data omap15xx_gpio_config = {
+ .bank_width = 16,
+ .regs = &omap15xx_gpio_regs,
+};
+
+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);
+
+ 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 000000000..6e6ec93dc
--- /dev/null
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -0,0 +1,257 @@
+/*
+ * 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>
+#include <linux/platform_data/gpio-omap.h>
+
+#include <mach/irqs.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
+
+/* smart idle, enable wakeup */
+#define SYSCONFIG_WORD 0x14
+
+/* mpu gpio */
+static struct 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 omap_gpio_reg_offs omap16xx_mpuio_regs = {
+ .revision = USHRT_MAX,
+ .direction = OMAP_MPUIO_IO_CNTL,
+ .datain = OMAP_MPUIO_INPUT_LATCH,
+ .dataout = OMAP_MPUIO_OUTPUT,
+ .irqstatus = OMAP_MPUIO_GPIO_INT,
+ .irqenable = OMAP_MPUIO_GPIO_MASKIT,
+ .irqenable_inv = true,
+ .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE,
+};
+
+static struct omap_gpio_platform_data omap16xx_mpu_gpio_config = {
+ .is_mpuio = true,
+ .bank_width = 16,
+ .bank_stride = 1,
+ .regs = &omap16xx_mpuio_regs,
+};
+
+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 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 omap_gpio_reg_offs omap16xx_gpio_regs = {
+ .revision = OMAP1610_GPIO_REVISION,
+ .direction = OMAP1610_GPIO_DIRECTION,
+ .set_dataout = OMAP1610_GPIO_SET_DATAOUT,
+ .clr_dataout = OMAP1610_GPIO_CLEAR_DATAOUT,
+ .datain = OMAP1610_GPIO_DATAIN,
+ .dataout = OMAP1610_GPIO_DATAOUT,
+ .irqstatus = OMAP1610_GPIO_IRQSTATUS1,
+ .irqenable = OMAP1610_GPIO_IRQENABLE1,
+ .set_irqenable = OMAP1610_GPIO_SET_IRQENABLE1,
+ .clr_irqenable = OMAP1610_GPIO_CLEAR_IRQENABLE1,
+ .wkup_en = OMAP1610_GPIO_WAKEUPENABLE,
+ .edgectrl1 = OMAP1610_GPIO_EDGE_CTRL1,
+ .edgectrl2 = OMAP1610_GPIO_EDGE_CTRL2,
+};
+
+static struct omap_gpio_platform_data omap16xx_gpio1_config = {
+ .bank_width = 16,
+ .regs = &omap16xx_gpio_regs,
+};
+
+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 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 omap_gpio_platform_data omap16xx_gpio2_config = {
+ .bank_width = 16,
+ .regs = &omap16xx_gpio_regs,
+};
+
+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 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 omap_gpio_platform_data omap16xx_gpio3_config = {
+ .bank_width = 16,
+ .regs = &omap16xx_gpio_regs,
+};
+
+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 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 omap_gpio_platform_data omap16xx_gpio4_config = {
+ .bank_width = 16,
+ .regs = &omap16xx_gpio_regs,
+};
+
+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 platform_device *omap16xx_gpio_dev[] __initdata = {
+ &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;
+ void __iomem *base;
+ struct resource *res;
+ struct platform_device *pdev;
+ struct omap_gpio_platform_data *pdata;
+
+ if (!cpu_is_omap16xx())
+ return -EINVAL;
+
+ /*
+ * Enable system clock for GPIO module.
+ * The CAM_CLK_CTRL *is* really the right place.
+ */
+ omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04,
+ ULPD_CAM_CLK_CTRL);
+
+ for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++) {
+ pdev = omap16xx_gpio_dev[i];
+ pdata = pdev->dev.platform_data;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (unlikely(!res)) {
+ dev_err(&pdev->dev, "Invalid mem resource.\n");
+ return -ENODEV;
+ }
+
+ base = ioremap(res->start, resource_size(res));
+ if (unlikely(!base)) {
+ dev_err(&pdev->dev, "ioremap failed.\n");
+ return -ENOMEM;
+ }
+
+ __raw_writel(SYSCONFIG_WORD, base + OMAP1610_GPIO_SYSCONFIG);
+ iounmap(base);
+
+ platform_device_register(omap16xx_gpio_dev[i]);
+ }
+
+ 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 000000000..4612d2506
--- /dev/null
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -0,0 +1,279 @@
+/*
+ * 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>
+#include <linux/platform_data/gpio-omap.h>
+
+#include <mach/irqs.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 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 omap_gpio_reg_offs omap7xx_mpuio_regs = {
+ .revision = USHRT_MAX,
+ .direction = OMAP_MPUIO_IO_CNTL / 2,
+ .datain = OMAP_MPUIO_INPUT_LATCH / 2,
+ .dataout = OMAP_MPUIO_OUTPUT / 2,
+ .irqstatus = OMAP_MPUIO_GPIO_INT / 2,
+ .irqenable = OMAP_MPUIO_GPIO_MASKIT / 2,
+ .irqenable_inv = true,
+ .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE >> 1,
+};
+
+static struct omap_gpio_platform_data omap7xx_mpu_gpio_config = {
+ .is_mpuio = true,
+ .bank_width = 16,
+ .bank_stride = 2,
+ .regs = &omap7xx_mpuio_regs,
+};
+
+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 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 omap_gpio_reg_offs omap7xx_gpio_regs = {
+ .revision = USHRT_MAX,
+ .direction = OMAP7XX_GPIO_DIR_CONTROL,
+ .datain = OMAP7XX_GPIO_DATA_INPUT,
+ .dataout = OMAP7XX_GPIO_DATA_OUTPUT,
+ .irqstatus = OMAP7XX_GPIO_INT_STATUS,
+ .irqenable = OMAP7XX_GPIO_INT_MASK,
+ .irqenable_inv = true,
+ .irqctrl = OMAP7XX_GPIO_INT_CONTROL,
+};
+
+static struct omap_gpio_platform_data omap7xx_gpio1_config = {
+ .bank_width = 32,
+ .regs = &omap7xx_gpio_regs,
+};
+
+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 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 omap_gpio_platform_data omap7xx_gpio2_config = {
+ .bank_width = 32,
+ .regs = &omap7xx_gpio_regs,
+};
+
+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 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 omap_gpio_platform_data omap7xx_gpio3_config = {
+ .bank_width = 32,
+ .regs = &omap7xx_gpio_regs,
+};
+
+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 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 omap_gpio_platform_data omap7xx_gpio4_config = {
+ .bank_width = 32,
+ .regs = &omap7xx_gpio_regs,
+};
+
+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 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 omap_gpio_platform_data omap7xx_gpio5_config = {
+ .bank_width = 32,
+ .regs = &omap7xx_gpio_regs,
+};
+
+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 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 omap_gpio_platform_data omap7xx_gpio6_config = {
+ .bank_width = 32,
+ .regs = &omap7xx_gpio_regs,
+};
+
+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 platform_device *omap7xx_gpio_dev[] __initdata = {
+ &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]);
+
+ 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 000000000..7f5761cff
--- /dev/null
+++ b/arch/arm/mach-omap1/i2c.c
@@ -0,0 +1,99 @@
+/*
+ * 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 <linux/i2c-omap.h>
+#include <mach/mux.h>
+#include "soc.h"
+
+#include <plat/i2c.h>
+
+#define OMAP_I2C_SIZE 0x3f
+#define OMAP1_I2C_BASE 0xfffb3800
+#define OMAP1_INT_I2C (32 + 4)
+
+static const char name[] = "omap_i2c";
+
+static struct resource i2c_resources[2] = {
+};
+
+static struct platform_device omap_i2c_devices[1] = {
+};
+
+static 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);
+ }
+}
+
+int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *pdata,
+ int bus_id)
+{
+ struct platform_device *pdev;
+ struct resource *res;
+
+ if (bus_id > 1)
+ return -EINVAL;
+
+ omap1_i2c_mux_pins(bus_id);
+
+ pdev = &omap_i2c_devices[bus_id - 1];
+ pdev->id = bus_id;
+ pdev->name = name;
+ pdev->num_resources = ARRAY_SIZE(i2c_resources);
+ res = i2c_resources;
+ res[0].start = OMAP1_I2C_BASE;
+ res[0].end = res[0].start + OMAP_I2C_SIZE;
+ res[0].flags = IORESOURCE_MEM;
+ res[1].start = OMAP1_INT_I2C;
+ res[1].flags = IORESOURCE_IRQ;
+ pdev->resource = res;
+
+ /* all OMAP1 have IP version 1 register set */
+ pdata->rev = OMAP_I2C_IP_VERSION_1;
+
+ /* all OMAP1 I2C are implemented like this */
+ pdata->flags = OMAP_I2C_FLAG_NO_FIFO |
+ OMAP_I2C_FLAG_SIMPLE_CLOCK |
+ OMAP_I2C_FLAG_16BIT_DATA_REG |
+ OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK;
+
+ /* how the cpu bus is wired up differs for 7xx only */
+
+ if (cpu_is_omap7xx())
+ pdata->flags |= OMAP_I2C_FLAG_BUS_SHIFT_1;
+ else
+ pdata->flags |= OMAP_I2C_FLAG_BUS_SHIFT_2;
+
+ pdev->dev.platform_data = pdata;
+
+ return platform_device_register(pdev);
+}
+
+static int __init omap_i2c_cmdline(void)
+{
+ return omap_register_i2c_bus_cmdline();
+}
+subsys_initcall(omap_i2c_cmdline);
diff --git a/arch/arm/mach-omap1/id.c b/arch/arm/mach-omap1/id.c
new file mode 100644
index 000000000..52de382fc
--- /dev/null
+++ b/arch/arm/mach-omap1/id.c
@@ -0,0 +1,210 @@
+/*
+ * 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 <asm/system_info.h>
+
+#include "soc.h"
+
+#include <mach/hardware.h>
+
+#include "common.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 000000000..adb5e7649
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h
@@ -0,0 +1,77 @@
+/*
+ * 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
+
+/*
+ * 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/board-ams-delta.h b/arch/arm/mach-omap1/include/mach/board-ams-delta.h
new file mode 100644
index 000000000..ad6f865d1
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/board-ams-delta.h
@@ -0,0 +1,71 @@
+/*
+ * 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 AMD_DELTA_LATCH2_SCARD_RSTIN 0x0400
+#define AMD_DELTA_LATCH2_SCARD_CMDVCC 0x0800
+#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
+
+#define AMS_DELTA_GPIO_PIN_LCD_VBLEN 240
+#define AMS_DELTA_GPIO_PIN_LCD_NDISP 241
+#define AMS_DELTA_GPIO_PIN_NAND_NCE 242
+#define AMS_DELTA_GPIO_PIN_NAND_NRE 243
+#define AMS_DELTA_GPIO_PIN_NAND_NWP 244
+#define AMS_DELTA_GPIO_PIN_NAND_NWE 245
+#define AMS_DELTA_GPIO_PIN_NAND_ALE 246
+#define AMS_DELTA_GPIO_PIN_NAND_CLE 247
+#define AMS_DELTA_GPIO_PIN_KEYBRD_PWR 248
+#define AMS_DELTA_GPIO_PIN_KEYBRD_DATAOUT 249
+#define AMS_DELTA_GPIO_PIN_SCARD_RSTIN 250
+#define AMS_DELTA_GPIO_PIN_SCARD_CMDVCC 251
+#define AMS_DELTA_GPIO_PIN_MODEM_NRESET 252
+#define AMS_DELTA_GPIO_PIN_MODEM_CODEC 253
+
+#define AMS_DELTA_LATCH2_GPIO_BASE AMS_DELTA_GPIO_PIN_LCD_VBLEN
+#define AMS_DELTA_LATCH2_NGPIO 16
+
+#ifndef __ASSEMBLY__
+void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value);
+#define ams_delta_latch2_write(mask, value) \
+ ams_delta_latch_write(AMS_DELTA_LATCH2_GPIO_BASE, \
+ AMS_DELTA_LATCH2_NGPIO, (mask), (value))
+#endif
+
+#endif /* CONFIG_MACH_AMS_DELTA */
+
+#endif /* __ASM_ARCH_OMAP_AMS_DELTA_H */
diff --git a/arch/arm/mach-omap1/include/mach/board-sx1.h b/arch/arm/mach-omap1/include/mach/board-sx1.h
new file mode 100644
index 000000000..355adbdaa
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/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/mach-omap1/include/mach/board-voiceblue.h b/arch/arm/mach-omap1/include/mach/board-voiceblue.h
new file mode 100644
index 000000000..27916b210
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/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/mach-omap1/include/mach/camera.h b/arch/arm/mach-omap1/include/mach/camera.h
new file mode 100644
index 000000000..847d00f0b
--- /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/entry-macro.S b/arch/arm/mach-omap1/include/mach/entry-macro.S
new file mode 100644
index 000000000..78a8c6c24
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/entry-macro.S
@@ -0,0 +1,39 @@
+/*
+ * 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/irqs.h>
+
+ .macro get_irqnr_preamble, base, tmp
+ .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/flash.h b/arch/arm/mach-omap1/include/mach/flash.h
new file mode 100644
index 000000000..0d88499b7
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/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/mach-omap1/include/mach/hardware.h b/arch/arm/mach-omap1/include/mach/hardware.h
new file mode 100644
index 000000000..5875a5098
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/hardware.h
@@ -0,0 +1,321 @@
+/*
+ * arch/arm/mach-omap1/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 <mach/soc.h>
+
+/*
+ * 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);
+
+#include <mach/tc.h>
+
+/* 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_cs0m_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 /* ifndef __ASSEMBLER__ */
+
+#define OMAP1_IO_OFFSET 0x01000000 /* Virtual IO = 0xfefb0000 */
+#define OMAP1_IO_ADDRESS(pa) IOMEM((pa) - OMAP1_IO_OFFSET)
+
+#include <mach/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 "omap7xx.h"
+#include "omap1510.h"
+#include "omap16xx.h"
+
+#endif /* __ASM_ARCH_OMAP_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 000000000..ce4f8005b
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/io.h
@@ -0,0 +1,45 @@
+/*
+ * arch/arm/mach-omap1/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
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU 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
+
+#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)
+
+#endif
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 000000000..729992d7d
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/irqs.h
@@ -0,0 +1,268 @@
+/*
+ * 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
+
+/*
+ * 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_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)
+
+/* 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)
+
+#define NR_IRQS OMAP_FPGA_IRQ_END
+
+#define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32))
+
+#include <mach/hardware.h>
+
+#ifdef CONFIG_FIQ
+#define FIQ_START 1024
+#endif
+
+#endif
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 000000000..d7a457bbc
--- /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 000000000..89bd703ad
--- /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 000000000..058a4f7d4
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/memory.h
@@ -0,0 +1,52 @@
+/*
+ * arch/arm/mach-omap1/include/mach/memory.h
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * 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().
+ */
+#if defined(CONFIG_ARCH_OMAP15XX) && !defined(__ASSEMBLER__)
+#include <mach/soc.h>
+
+/*
+ * 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 */
+
+#endif
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 000000000..f82a8dcaa
--- /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/mux.h b/arch/arm/mach-omap1/include/mach/mux.h
new file mode 100644
index 000000000..323948959
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/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 omap7xx.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/mach-omap1/include/mach/omap1510.h b/arch/arm/mach-omap1/include/mach/omap1510.h
new file mode 100644
index 000000000..3d235244b
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/omap1510.h
@@ -0,0 +1,162 @@
+/*
+ * 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)
+
+/*
+ * ---------------------------------------------------------------------------
+ * 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 INNOVATOR_FPGA_CAM_USB_CONTROL IOMEM(OMAP1510_FPGA_BASE + 0x20c)
+#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_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 /* __ASM_ARCH_OMAP15XX_H */
+
diff --git a/arch/arm/mach-omap1/include/mach/omap16xx.h b/arch/arm/mach-omap1/include/mach/omap16xx.h
new file mode 100644
index 000000000..cd1c72486
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/omap16xx.h
@@ -0,0 +1,201 @@
+/*
+ * 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/mach-omap1/include/mach/omap7xx.h b/arch/arm/mach-omap1/include/mach/omap7xx.h
new file mode 100644
index 000000000..63da994bc
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/omap7xx.h
@@ -0,0 +1,106 @@
+/*
+ * 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/mach-omap1/include/mach/serial.h b/arch/arm/mach-omap1/include/mach/serial.h
new file mode 100644
index 000000000..2ce6a2db4
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/serial.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009 Texas Instruments
+ * Added 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, relative to
+ * start of RAM. 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_OFS 0x3ffc
+
+/* OMAP1 serial ports */
+#define OMAP1_UART1_BASE 0xfffb0000
+#define OMAP1_UART2_BASE 0xfffb0800
+#define OMAP1_UART3_BASE 0xfffb9800
+
+#define OMAP_PORT_SHIFT 2
+#define OMAP7XX_PORT_SHIFT 0
+
+#define OMAP1510_BASE_BAUD (12000000/16)
+#define OMAP16XX_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
+
+#ifndef __ASSEMBLER__
+extern void omap_serial_init(void);
+#endif
+
+#endif
diff --git a/arch/arm/mach-omap1/include/mach/soc.h b/arch/arm/mach-omap1/include/mach/soc.h
new file mode 100644
index 000000000..612bd1cc2
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/soc.h
@@ -0,0 +1,230 @@
+/*
+ * 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/5 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
+
+#ifndef __ASSEMBLY__
+
+#include <linux/bitops.h>
+
+/*
+ * Test if multicore OMAP support is needed
+ */
+#undef MULTI_OMAP1
+#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
+
+/*
+ * 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);
+
+/*
+ * 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
+ */
+#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; \
+}
+
+IS_OMAP_CLASS(7xx, 0x07)
+IS_OMAP_CLASS(15xx, 0x15)
+IS_OMAP_CLASS(16xx, 0x16)
+
+#define cpu_is_omap7xx() 0
+#define cpu_is_omap15xx() 0
+#define cpu_is_omap16xx() 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
+
+/*
+ * Macros to detect individual cpu types.
+ * These are only rarely needed.
+ * cpu_is_omap310(): True for OMAP310
+ * 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
+ */
+#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(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)
+
+#define cpu_is_omap310() 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
+
+/* These are needed to compile common code */
+#ifdef CONFIG_ARCH_OMAP1
+#define cpu_is_omap242x() 0
+#define cpu_is_omap2430() 0
+#define cpu_is_omap243x() 0
+#define cpu_is_omap24xx() 0
+#define cpu_is_omap34xx() 0
+#define cpu_is_omap44xx() 0
+#define soc_is_omap54xx() 0
+#define soc_is_dra7xx() 0
+#define soc_is_am33xx() 0
+#define cpu_class_is_omap1() 1
+#define cpu_class_is_omap2() 0
+#endif
+
+/*
+ * Whether we have MULTI_OMAP1 or not, we still need to distinguish
+ * between 310 vs. 1510 and 1611B/5912 vs. 1710.
+ */
+
+#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
+
+#endif /* __ASSEMBLY__ */
+#endif
diff --git a/arch/arm/mach-omap1/include/mach/tc.h b/arch/arm/mach-omap1/include/mach/tc.h
new file mode 100644
index 000000000..1b4b2da86
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/tc.h
@@ -0,0 +1,89 @@
+/*
+ * 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)))
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __ASM_ARCH_TC_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 000000000..4869633de
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/uncompress.h
@@ -0,0 +1,117 @@
+/*
+ * 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 "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)
+{
+ /*
+ * Get address of some.bss variable and round it down
+ * a la CONFIG_AUTO_ZRELADDR.
+ */
+ u32 ram_start = (u32)&uart_shift & 0xf8000000;
+ u32 *uart_info = (u32 *)(ram_start + OMAP_UART_INFO_OFS);
+ *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)
+
+static inline void arch_decomp_setup(void)
+{
+ 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);
+ } while (0);
+}
diff --git a/arch/arm/mach-omap1/include/mach/usb.h b/arch/arm/mach-omap1/include/mach/usb.h
new file mode 100644
index 000000000..2c263051d
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/usb.h
@@ -0,0 +1,129 @@
+/*
+ * FIXME correct answer depends on hmc_mode,
+ * as does (on omap1) any nonzero value for config->otg port number
+ */
+#if IS_ENABLED(CONFIG_USB_OMAP)
+#define is_usb0_device(config) 1
+#else
+#define is_usb0_device(config) 0
+#endif
+
+#include <linux/platform_data/usb-omap1.h>
+
+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
+
+#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
+#define OTG_BASE OMAP1_OTG_BASE
+#define UDC_BASE OMAP1_UDC_BASE
+#define OMAP_OHCI_BASE OMAP1_OHCI_BASE
+
+/*
+ * 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)
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
new file mode 100644
index 000000000..499b8accb
--- /dev/null
+++ b/arch/arm/mach-omap1/io.c
@@ -0,0 +1,182 @@
+/*
+ * 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 <mach/mux.h>
+#include <mach/tc.h>
+#include <linux/omap-dma.h>
+
+#include "iomap.h"
+#include "common.h"
+#include "clock.h"
+
+/*
+ * 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
+ */
+static void __init omap1_map_common_io(void)
+{
+ iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc));
+}
+
+#if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850)
+void __init omap7xx_map_io(void)
+{
+ omap1_map_common_io();
+ iotable_init(omap7xx_io_desc, ARRAY_SIZE(omap7xx_io_desc));
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP15XX
+void __init omap15xx_map_io(void)
+{
+ omap1_map_common_io();
+ iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
+}
+#endif
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+void __init omap16xx_map_io(void)
+{
+ omap1_map_common_io();
+ iotable_init(omap16xx_io_desc, ARRAY_SIZE(omap16xx_io_desc));
+}
+#endif
+
+/*
+ * Common low-level hardware init for omap1.
+ */
+void __init omap1_init_early(void)
+{
+ omap_check_revision();
+
+ /* 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();
+}
+
+void __init omap1_init_late(void)
+{
+ omap_serial_wakeup_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/iomap.h b/arch/arm/mach-omap1/iomap.h
new file mode 100644
index 000000000..f4e2d7a21
--- /dev/null
+++ b/arch/arm/mach-omap1/iomap.h
@@ -0,0 +1,33 @@
+/*
+ * IO mappings for OMAP1
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU 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.
+ */
+
+/*
+ * ----------------------------------------------------------------------------
+ * Omap1 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+
+#define OMAP1_IO_PHYS 0xFFFB0000
+#define OMAP1_IO_SIZE 0x40000
+#define OMAP1_IO_VIRT (OMAP1_IO_PHYS - OMAP1_IO_OFFSET)
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
new file mode 100644
index 000000000..a8a533df2
--- /dev/null
+++ b/arch/arm/mach-omap1/irq.c
@@ -0,0 +1,245 @@
+/*
+ * 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/gpio.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include "soc.h"
+
+#include <mach/hardware.h>
+
+#include "common.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 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 omap1_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 000000000..26a2b01c7
--- /dev/null
+++ b/arch/arm/mach-omap1/lcd_dma.c
@@ -0,0 +1,445 @@
+/*
+ * 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 <linux/omap-dma.h>
+
+#include <mach/hardware.h>
+#include <mach/lcdc.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;
+ 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_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()) {
+ pr_err("DMA virtual resolution 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)
+ pr_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/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c
new file mode 100644
index 000000000..8ed67f8d1
--- /dev/null
+++ b/arch/arm/mach-omap1/mcbsp.c
@@ -0,0 +1,446 @@
+/*
+ * 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 <linux/omap-dma.h>
+#include <mach/mux.h>
+#include "soc.h"
+#include <linux/platform_data/asoc-ti-mcbsp.h>
+
+#include <mach/irqs.h>
+
+#include "iomap.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 struct platform_device **omap_mcbsp_devices;
+
+static void omap1_mcbsp_request(unsigned int id)
+{
+ /*
+ * On 1510, 1610 and 1710, McBSP1 and McBSP3
+ * are DSP public peripherals.
+ */
+ if (id == 0 || id == 2) {
+ 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 == 0 || id == 2) {
+ 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,
+};
+
+#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
+
+#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 = 9,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = 8,
+ .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 = 11,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = 10,
+ .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 = 9,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = 8,
+ .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 = 17,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = 16,
+ .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 = 11,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = 10,
+ .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 = 9,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = 8,
+ .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 = 17,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = 16,
+ .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 = 11,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = 10,
+ .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 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);
+ config[i].reg_size = 2;
+ config[i].reg_step = 2;
+ 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;
+ }
+}
+
+static int __init omap1_mcbsp_init(void)
+{
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
+ 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 0;
+}
+
+arch_initcall(omap1_mcbsp_init);
diff --git a/arch/arm/mach-omap1/mmc.h b/arch/arm/mach-omap1/mmc.h
new file mode 100644
index 000000000..39c2b13de
--- /dev/null
+++ b/arch/arm/mach-omap1/mmc.h
@@ -0,0 +1,18 @@
+#include <linux/mmc/host.h>
+#include <linux/platform_data/mmc-omap.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 */
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers);
+#else
+static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers)
+{
+}
+#endif
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c
new file mode 100644
index 000000000..667ce5027
--- /dev/null
+++ b/arch/arm/mach-omap1/mux.c
@@ -0,0 +1,525 @@
+/*
+ * 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 <mach/hardware.h>
+
+#include <mach/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
+}
+
+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 = &mux_cfg->pins[index];
+
+ if (!mux_cfg->cfg_reg)
+ return -ENODEV;
+
+ return mux_cfg->cfg_reg(reg);
+}
+EXPORT_SYMBOL(omap_cfg_reg);
+
+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);
+}
+
+#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/mach-omap1/ocpi.c b/arch/arm/mach-omap1/ocpi.c
new file mode 100644
index 000000000..44a3d19eb
--- /dev/null
+++ b/arch/arm/mach-omap1/ocpi.c
@@ -0,0 +1,111 @@
+/*
+ * linux/arch/arm/plat-omap/ocpi.c
+ *
+ * Minimal OCP bus support for omap16xx
+ *
+ * Copyright (C) 2003 - 2005 Nokia Corporation
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * 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>
+
+#include "common.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
+ */
+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();
+ pr_info("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/mach-omap1/opp.h b/arch/arm/mach-omap1/opp.h
new file mode 100644
index 000000000..79a683864
--- /dev/null
+++ b/arch/arm/mach-omap1/opp.h
@@ -0,0 +1,29 @@
+/*
+ * 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;
+ u32 flags;
+};
+
+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 000000000..8dcebe6d8
--- /dev/null
+++ b/arch/arm/mach-omap1/opp_data.c
@@ -0,0 +1,54 @@
+/*
+ * 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 "clock.h"
+#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
+ */
+ { 216000000, 12000000, 216000000, 0x050d, 0x2910, /* 1/1/2/2/2/8 */
+ CK_1710 },
+ { 195000000, 13000000, 195000000, 0x050e, 0x2790, /* 1/1/2/2/4/8 */
+ CK_7XX },
+ { 192000000, 19200000, 192000000, 0x050f, 0x2510, /* 1/1/2/2/8/8 */
+ CK_16XX },
+ { 192000000, 12000000, 192000000, 0x050f, 0x2810, /* 1/1/2/2/8/8 */
+ CK_16XX },
+ { 96000000, 12000000, 192000000, 0x055f, 0x2810, /* 2/2/2/2/8/8 */
+ CK_16XX },
+ { 48000000, 12000000, 192000000, 0x0baf, 0x2810, /* 4/4/4/8/8/8 */
+ CK_16XX },
+ { 24000000, 12000000, 192000000, 0x0fff, 0x2810, /* 8/8/8/8/8/8 */
+ CK_16XX },
+ { 182000000, 13000000, 182000000, 0x050e, 0x2710, /* 1/1/2/2/4/8 */
+ CK_7XX },
+ { 168000000, 12000000, 168000000, 0x010f, 0x2710, /* 1/1/1/2/8/8 */
+ CK_16XX|CK_7XX },
+ { 150000000, 12000000, 150000000, 0x010a, 0x2cb0, /* 1/1/1/2/4/4 */
+ CK_1510 },
+ { 120000000, 12000000, 120000000, 0x010a, 0x2510, /* 1/1/1/2/4/4 */
+ CK_16XX|CK_1510|CK_310|CK_7XX },
+ { 96000000, 12000000, 96000000, 0x0005, 0x2410, /* 1/1/1/1/2/2 */
+ CK_16XX|CK_1510|CK_310|CK_7XX },
+ { 60000000, 12000000, 60000000, 0x0005, 0x2290, /* 1/1/1/1/2/2 */
+ CK_16XX|CK_1510|CK_310|CK_7XX },
+ { 30000000, 12000000, 60000000, 0x0555, 0x2290, /* 2/2/2/2/2/2 */
+ CK_16XX|CK_1510|CK_310|CK_7XX },
+ { 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 000000000..dd94567c3
--- /dev/null
+++ b/arch/arm/mach-omap1/pm.c
@@ -0,0 +1,708 @@
+/*
+ * 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/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/interrupt.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/atomic.h>
+#include <linux/cpu.h>
+
+#include <asm/fncpy.h>
+#include <asm/system_misc.h>
+#include <asm/irq.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+
+#include <mach/tc.h>
+#include <mach/mux.h>
+#include <linux/omap-dma.h>
+#include <plat/dmtimer.h>
+
+#include <mach/irqs.h>
+
+#include "iomap.h"
+#include "clock.h"
+#include "pm.h"
+#include "sram.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];
+
+static unsigned short enable_dyn_sleep;
+
+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) ||
+ (value != 0 && !IS_ENABLED(CONFIG_OMAP_32K_TIMER))) {
+ pr_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);
+
+
+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;
+
+ local_fiq_disable();
+
+#if defined(CONFIG_OMAP_MPU_TIMER) && !defined(CONFIG_OMAP_DM_TIMER)
+ use_idlect1 = use_idlect1 & ~(1 << 9);
+#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) || !enable_dyn_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();
+ return;
+ }
+ omap_sram_suspend(omap_readl(ARM_IDLECT1),
+ omap_readl(ARM_IDLECT2));
+
+ local_fiq_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());
+}
+
+#ifdef CONFIG_DEBUG_FS
+/*
+ * Read system PM registers for debugging
+ */
+static int omap_pm_debug_show(struct seq_file *m, void *v)
+{
+ 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);
+ }
+
+ seq_printf(m,
+ "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()) {
+ seq_printf(m,
+ "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()) {
+ seq_printf(m,
+ "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()) {
+ seq_printf(m,
+ "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));
+ }
+
+ return 0;
+}
+
+static int omap_pm_debug_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, omap_pm_debug_show,
+ &inode->i_private);
+}
+
+static const struct file_operations omap_pm_debug_fops = {
+ .open = omap_pm_debug_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static void omap_pm_init_debugfs(void)
+{
+ struct dentry *d;
+
+ d = debugfs_create_dir("pm_debug", NULL);
+ if (!d)
+ return;
+
+ (void) debugfs_create_file("omap_pm", S_IWUSR | S_IRUGO,
+ d, NULL, &omap_pm_debug_fops);
+}
+
+#endif /* CONFIG_DEBUG_FS */
+
+/*
+ * omap_pm_prepare - Do preliminary suspend work.
+ *
+ */
+static int omap_pm_prepare(void)
+{
+ /* We cannot sleep in idle until we have resumed */
+ cpu_idle_poll_ctrl(true);
+ 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)
+{
+ cpu_idle_poll_ctrl(false);
+}
+
+
+static irqreturn_t omap_wakeup_interrupt(int irq, void *dev)
+{
+ return IRQ_HANDLED;
+}
+
+static struct irqaction omap_wakeup_irq = {
+ .name = "peripheral wakeup",
+ .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)
+{
+ int error = 0;
+
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
+ pr_info("Power Management for TI OMAP.\n");
+
+ if (!IS_ENABLED(CONFIG_OMAP_32K_TIMER))
+ pr_info("OMAP1 PM: sleep states in idle disabled due to no 32KiHz timer\n");
+
+ if (!IS_ENABLED(CONFIG_OMAP_DM_TIMER))
+ pr_info("OMAP1 PM: sleep states in idle disabled due to no DMTIMER support\n");
+
+ if (IS_ENABLED(CONFIG_OMAP_32K_TIMER) &&
+ IS_ENABLED(CONFIG_OMAP_DM_TIMER)) {
+ /* OMAP16xx only */
+ pr_info("OMAP1 PM: sleep states in idle enabled\n");
+ enable_dyn_sleep = 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_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;
+ }
+
+ arm_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);
+
+#ifdef CONFIG_DEBUG_FS
+ omap_pm_init_debugfs();
+#endif
+
+ error = sysfs_create_file(power_kobj, &sleep_while_idle_attr.attr);
+ if (error)
+ printk(KERN_ERR "sysfs_create_file failed: %d\n", error);
+
+ if (cpu_is_omap16xx()) {
+ /* configure LOW_PWR pin */
+ omap_cfg_reg(T20_1610_LOW_PWR);
+ }
+
+ return error;
+}
+__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 000000000..cd926dcb5
--- /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 000000000..c40e209de
--- /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/pm_clock.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include "soc.h"
+
+#ifdef CONFIG_PM
+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_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_clk_resume(dev);
+ return pm_generic_runtime_resume(dev);
+}
+
+static struct dev_pm_domain default_pm_domain = {
+ .ops = {
+ .runtime_suspend = omap1_pm_runtime_suspend,
+ .runtime_resume = omap1_pm_runtime_resume,
+ USE_PLATFORM_PM_SLEEP_OPS
+ },
+};
+#define OMAP1_PM_DOMAIN (&default_pm_domain)
+#else
+#define OMAP1_PM_DOMAIN NULL
+#endif /* CONFIG_PM */
+
+static struct pm_clk_notifier_block platform_bus_notifier = {
+ .pm_domain = OMAP1_PM_DOMAIN,
+ .con_ids = { "ick", "fck", NULL, },
+};
+
+static int __init omap1_pm_runtime_init(void)
+{
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
+ pm_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 000000000..72bf4bf4a
--- /dev/null
+++ b/arch/arm/mach-omap1/reset.c
@@ -0,0 +1,63 @@
+/*
+ * OMAP1 reset support
+ */
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/reboot.h>
+
+#include <mach/hardware.h>
+
+#include "iomap.h"
+#include "common.h"
+
+/* ARM_SYSST bit shifts related to SoC reset sources */
+#define ARM_SYSST_POR_SHIFT 5
+#define ARM_SYSST_EXT_RST_SHIFT 4
+#define ARM_SYSST_ARM_WDRST_SHIFT 2
+#define ARM_SYSST_GLOB_SWRST_SHIFT 1
+
+/* Standardized reset source bits (across all OMAP SoCs) */
+#define OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT 0
+#define OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT 1
+#define OMAP_MPU_WD_RST_SRC_ID_SHIFT 3
+#define OMAP_EXTWARM_RST_SRC_ID_SHIFT 5
+
+
+void omap1_restart(enum reboot_mode 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);
+}
+
+/**
+ * omap1_get_reset_sources - return the source of the SoC's last reset
+ *
+ * Returns bits that represent the last reset source for the SoC. The
+ * format is standardized across OMAPs for use by the OMAP watchdog.
+ */
+u32 omap1_get_reset_sources(void)
+{
+ u32 ret = 0;
+ u16 rs;
+
+ rs = __raw_readw(OMAP1_IO_ADDRESS(ARM_SYSST));
+
+ if (rs & (1 << ARM_SYSST_POR_SHIFT))
+ ret |= 1 << OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT;
+ if (rs & (1 << ARM_SYSST_EXT_RST_SHIFT))
+ ret |= 1 << OMAP_EXTWARM_RST_SRC_ID_SHIFT;
+ if (rs & (1 << ARM_SYSST_ARM_WDRST_SHIFT))
+ ret |= 1 << OMAP_MPU_WD_RST_SRC_ID_SHIFT;
+ if (rs & (1 << ARM_SYSST_GLOB_SWRST_SHIFT))
+ ret |= 1 << OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT;
+
+ return ret;
+}
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
new file mode 100644
index 000000000..d1ac08016
--- /dev/null
+++ b/arch/arm/mach-omap1/serial.c
@@ -0,0 +1,262 @@
+/*
+ * 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/gpio.h>
+#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 <mach/mux.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));
+}
+
+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;
+}
+
+#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 000000000..a908c5183
--- /dev/null
+++ b/arch/arm/mach-omap1/sleep.S
@@ -0,0 +1,370 @@
+/*
+ * 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/hardware.h>
+
+#include "iomap.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/soc.h b/arch/arm/mach-omap1/soc.h
new file mode 100644
index 000000000..69daf0187
--- /dev/null
+++ b/arch/arm/mach-omap1/soc.h
@@ -0,0 +1,4 @@
+/*
+ * We can move mach/soc.h here once the drivers are fixed
+ */
+#include <mach/soc.h>
diff --git a/arch/arm/mach-omap1/sram-init.c b/arch/arm/mach-omap1/sram-init.c
new file mode 100644
index 000000000..6431b0f86
--- /dev/null
+++ b/arch/arm/mach-omap1/sram-init.c
@@ -0,0 +1,76 @@
+/*
+ * OMAP SRAM detection and management
+ *
+ * Copyright (C) 2005 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 <asm/fncpy.h>
+#include <asm/tlb.h>
+#include <asm/cacheflush.h>
+
+#include <asm/mach/map.h>
+
+#include "soc.h"
+#include "sram.h"
+
+#define OMAP1_SRAM_PA 0x20000000
+#define SRAM_BOOTLOADER_SZ 0x80
+
+/*
+ * 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_and_map_sram(void)
+{
+ unsigned long omap_sram_skip = SRAM_BOOTLOADER_SZ;
+ unsigned long omap_sram_start = OMAP1_SRAM_PA;
+ unsigned long omap_sram_size;
+
+ 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_omap1611() ||
+ cpu_is_omap1621() || cpu_is_omap1710())
+ omap_sram_size = 0x4000; /* 16K */
+ else {
+ pr_err("Could not detect SRAM size\n");
+ omap_sram_size = 0x4000;
+ }
+
+ omap_map_sram(omap_sram_start, omap_sram_size,
+ omap_sram_skip, 1);
+}
+
+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);
+ /* On 730, bit 13 must always be 1 */
+ if (cpu_is_omap7xx())
+ ckctl |= 0x2000;
+ _omap_sram_reprogram_clock(dpllctl, ckctl);
+}
+
+int __init omap_sram_init(void)
+{
+ omap_detect_and_map_sram();
+ _omap_sram_reprogram_clock =
+ omap_sram_push(omap1_sram_reprogram_clock,
+ omap1_sram_reprogram_clock_sz);
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap1/sram.S b/arch/arm/mach-omap1/sram.S
new file mode 100644
index 000000000..00e9d9e9a
--- /dev/null
+++ b/arch/arm/mach-omap1/sram.S
@@ -0,0 +1,61 @@
+/*
+ * 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/hardware.h>
+
+#include "iomap.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/sram.h b/arch/arm/mach-omap1/sram.h
new file mode 100644
index 000000000..d5a6c8362
--- /dev/null
+++ b/arch/arm/mach-omap1/sram.h
@@ -0,0 +1,7 @@
+#include <plat/sram.h>
+
+extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
+
+/* Do not use these */
+extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
+extern unsigned long omap1_sram_reprogram_clock_sz;
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
new file mode 100644
index 000000000..a7588cfd0
--- /dev/null
+++ b/arch/arm/mach-omap1/time.c
@@ -0,0 +1,236 @@
+/*
+ * 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/spinlock.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+#include <linux/sched_clock.h>
+
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+#include "iomap.h"
+#include "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,
+ .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_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.cpumask = cpumask_of(0);
+ clockevents_config_and_register(&clockevent_mpu_timer1, rate,
+ 1, -1);
+}
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * MPU timer 2 ... free running 32-bit clock source and scheduler clock
+ * ---------------------------------------------------------------------------
+ */
+
+static u64 notrace omap_mpu_read_sched_clock(void)
+{
+ return ~omap_mpu_timer_read(1);
+}
+
+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);
+ sched_clock_register(omap_mpu_read_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 */
+
+/*
+ * ---------------------------------------------------------------------------
+ * Timer initialization
+ * ---------------------------------------------------------------------------
+ */
+void __init omap1_timer_init(void)
+{
+ if (omap_32k_timer_init() != 0)
+ omap_mpu_timer_init();
+}
diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c
new file mode 100644
index 000000000..bde7a35e5
--- /dev/null
+++ b/arch/arm/mach-omap1/timer.c
@@ -0,0 +1,174 @@
+/**
+ * OMAP1 Dual-Mode Timers - platform device registration
+ *
+ * Contains first level initialization routines which internally
+ * generates timer device information and registers with linux
+ * device model. It also has low level function to chnage the timer
+ * input clock source.
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Tarun Kanti DebBarma <tarun.kanti@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 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/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/dmtimer-omap.h>
+
+#include <mach/irqs.h>
+
+#include <plat/dmtimer.h>
+
+#define OMAP1610_GPTIMER1_BASE 0xfffb1400
+#define OMAP1610_GPTIMER2_BASE 0xfffb1c00
+#define OMAP1610_GPTIMER3_BASE 0xfffb2400
+#define OMAP1610_GPTIMER4_BASE 0xfffb2c00
+#define OMAP1610_GPTIMER5_BASE 0xfffb3400
+#define OMAP1610_GPTIMER6_BASE 0xfffb3c00
+#define OMAP1610_GPTIMER7_BASE 0xfffb7400
+#define OMAP1610_GPTIMER8_BASE 0xfffbd400
+
+#define OMAP1_DM_TIMER_COUNT 8
+
+static int omap1_dm_timer_set_src(struct platform_device *pdev,
+ int source)
+{
+ int n = (pdev->id - 1) << 1;
+ u32 l;
+
+ l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
+ l |= source << n;
+ omap_writel(l, MOD_CONF_CTRL_1);
+
+ return 0;
+}
+
+static int __init omap1_dm_timer_init(void)
+{
+ int i;
+ int ret;
+ struct dmtimer_platform_data *pdata;
+ struct platform_device *pdev;
+
+ if (!cpu_is_omap16xx())
+ return 0;
+
+ for (i = 1; i <= OMAP1_DM_TIMER_COUNT; i++) {
+ struct resource res[2];
+ u32 base, irq;
+
+ switch (i) {
+ case 1:
+ base = OMAP1610_GPTIMER1_BASE;
+ irq = INT_1610_GPTIMER1;
+ break;
+ case 2:
+ base = OMAP1610_GPTIMER2_BASE;
+ irq = INT_1610_GPTIMER2;
+ break;
+ case 3:
+ base = OMAP1610_GPTIMER3_BASE;
+ irq = INT_1610_GPTIMER3;
+ break;
+ case 4:
+ base = OMAP1610_GPTIMER4_BASE;
+ irq = INT_1610_GPTIMER4;
+ break;
+ case 5:
+ base = OMAP1610_GPTIMER5_BASE;
+ irq = INT_1610_GPTIMER5;
+ break;
+ case 6:
+ base = OMAP1610_GPTIMER6_BASE;
+ irq = INT_1610_GPTIMER6;
+ break;
+ case 7:
+ base = OMAP1610_GPTIMER7_BASE;
+ irq = INT_1610_GPTIMER7;
+ break;
+ case 8:
+ base = OMAP1610_GPTIMER8_BASE;
+ irq = INT_1610_GPTIMER8;
+ break;
+ default:
+ /*
+ * not supposed to reach here.
+ * this is to remove warning.
+ */
+ return -EINVAL;
+ }
+
+ pdev = platform_device_alloc("omap_timer", i);
+ if (!pdev) {
+ pr_err("%s: Failed to device alloc for dmtimer%d\n",
+ __func__, i);
+ return -ENOMEM;
+ }
+
+ memset(res, 0, 2 * sizeof(struct resource));
+ res[0].start = base;
+ res[0].end = base + 0x46;
+ res[0].flags = IORESOURCE_MEM;
+ res[1].start = irq;
+ res[1].end = irq;
+ res[1].flags = IORESOURCE_IRQ;
+ ret = platform_device_add_resources(pdev, res,
+ ARRAY_SIZE(res));
+ if (ret) {
+ dev_err(&pdev->dev, "%s: Failed to add resources.\n",
+ __func__);
+ goto err_free_pdev;
+ }
+
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(&pdev->dev, "%s: Failed to allocate pdata.\n",
+ __func__);
+ ret = -ENOMEM;
+ goto err_free_pdata;
+ }
+
+ pdata->set_timer_src = omap1_dm_timer_set_src;
+ pdata->timer_capability = OMAP_TIMER_ALWON |
+ OMAP_TIMER_NEEDS_RESET | OMAP_TIMER_HAS_DSP_IRQ;
+
+ ret = platform_device_add_data(pdev, pdata, sizeof(*pdata));
+ if (ret) {
+ dev_err(&pdev->dev, "%s: Failed to add platform data.\n",
+ __func__);
+ goto err_free_pdata;
+ }
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: Failed to add platform device.\n",
+ __func__);
+ goto err_free_pdata;
+ }
+
+ dev_dbg(&pdev->dev, " Registered.\n");
+ }
+
+ return 0;
+
+err_free_pdata:
+ kfree(pdata);
+
+err_free_pdev:
+ platform_device_unregister(pdev);
+
+ return ret;
+}
+arch_initcall(omap1_dm_timer_init);
diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c
new file mode 100644
index 000000000..36bf174b3
--- /dev/null
+++ b/arch/arm/mach-omap1/timer32k.c
@@ -0,0 +1,197 @@
+/*
+ * 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/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+#include <plat/counter-32k.h>
+
+#include <mach/hardware.h>
+
+#include "common.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_32KSYNC_TIMER_BASE 0xfffbc400
+#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 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,
+ .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_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.cpumask = cpumask_of(0);
+ clockevents_config_and_register(&clockevent_32k_timer,
+ OMAP_32K_TICKS_PER_SEC, 1, 0xfffffffe);
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * Timer initialization
+ * ---------------------------------------------------------------------------
+ */
+int __init omap_32k_timer_init(void)
+{
+ int ret = -ENODEV;
+
+ if (cpu_is_omap16xx()) {
+ void __iomem *base;
+ struct clk *sync32k_ick;
+
+ base = ioremap(OMAP1_32KSYNC_TIMER_BASE, SZ_1K);
+ if (!base) {
+ pr_err("32k_counter: failed to map base addr\n");
+ return -ENODEV;
+ }
+
+ sync32k_ick = clk_get(NULL, "omap_32ksync_ick");
+ if (!IS_ERR(sync32k_ick))
+ clk_enable(sync32k_ick);
+
+ ret = omap_init_clocksource_32k(base);
+ }
+
+ if (!ret)
+ omap_init_32k_timer();
+
+ return ret;
+}
diff --git a/arch/arm/mach-omap1/usb.c b/arch/arm/mach-omap1/usb.c
new file mode 100644
index 000000000..4118db50d
--- /dev/null
+++ b/arch/arm/mach-omap1/usb.c
@@ -0,0 +1,653 @@
+/*
+ * 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 <mach/mux.h>
+
+#include <mach/usb.h>
+
+#include "common.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_ARCH_OMAP_OTG
+
+void __init
+omap_otg_init(struct omap_usb_config *config)
+{
+ u32 syscon;
+ 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;
+
+#if IS_ENABLED(CONFIG_USB_OMAP)
+ if (config->otg || config->register_dev) {
+ struct platform_device *udc_device = config->udc_device;
+ int status;
+
+ 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;
+ int status;
+
+ 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;
+ int status;
+
+ 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);
+}
+
+#else
+void omap_otg_init(struct omap_usb_config *config) {}
+#endif
+
+#if IS_ENABLED(CONFIG_USB_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;
+ pdata->ocpi_enable = &ocpi_enable;
+}
+
+#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
+
+static 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;
+}
+
+static 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;
+}
+
+static 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();
+
+#if IS_ENABLED(CONFIG_USB_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)
+{
+ struct omap_usb_config *pdata;
+
+ pdata = kmemdup(_pdata, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return;
+
+ 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 000000000..6468f15f0
--- /dev/null
+++ b/arch/arm/mach-omap2/Kconfig
@@ -0,0 +1,269 @@
+menu "TI OMAP/AM/DM/DRA Family"
+ depends on ARCH_MULTI_V6 || ARCH_MULTI_V7
+
+config ARCH_OMAP2
+ bool "TI OMAP2"
+ depends on ARCH_MULTI_V6
+ select ARCH_OMAP2PLUS
+ select CPU_V6
+ select SOC_HAS_OMAP2_SDRC
+
+config ARCH_OMAP3
+ bool "TI OMAP3"
+ depends on ARCH_MULTI_V7
+ select ARCH_OMAP2PLUS
+ select ARM_CPU_SUSPEND if PM
+ select OMAP_INTERCONNECT
+ select PM_OPP if PM
+ select PM if CPU_IDLE
+ select SOC_HAS_OMAP2_SDRC
+
+config ARCH_OMAP4
+ bool "TI OMAP4"
+ depends on ARCH_MULTI_V7
+ select ARCH_OMAP2PLUS
+ select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
+ select ARM_CPU_SUSPEND if PM
+ select ARM_ERRATA_720789
+ select ARM_GIC
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select OMAP_INTERCONNECT
+ select PL310_ERRATA_588369 if CACHE_L2X0
+ select PL310_ERRATA_727915 if CACHE_L2X0
+ select PM_OPP if PM
+ select PM if CPU_IDLE
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_775420
+
+config SOC_OMAP5
+ bool "TI OMAP5"
+ depends on ARCH_MULTI_V7
+ select ARCH_OMAP2PLUS
+ select ARM_CPU_SUSPEND if PM
+ select ARM_GIC
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select HAVE_ARM_ARCH_TIMER
+ select ARM_ERRATA_798181 if SMP
+
+config SOC_AM33XX
+ bool "TI AM33XX"
+ depends on ARCH_MULTI_V7
+ select ARCH_OMAP2PLUS
+ select ARM_CPU_SUSPEND if PM
+
+config SOC_AM43XX
+ bool "TI AM43x"
+ depends on ARCH_MULTI_V7
+ select ARCH_OMAP2PLUS
+ select ARM_GIC
+ select MACH_OMAP_GENERIC
+ select MIGHT_HAVE_CACHE_L2X0
+
+config SOC_DRA7XX
+ bool "TI DRA7XX"
+ depends on ARCH_MULTI_V7
+ select ARCH_OMAP2PLUS
+ select ARM_CPU_SUSPEND if PM
+ select ARM_GIC
+ select HAVE_ARM_ARCH_TIMER
+ select IRQ_CROSSBAR
+ select ARM_ERRATA_798181 if SMP
+
+config ARCH_OMAP2PLUS
+ bool
+ select ARCH_HAS_BANDGAP
+ select ARCH_HAS_HOLES_MEMORYMODEL
+ select ARCH_OMAP
+ select ARCH_REQUIRE_GPIOLIB
+ select CLKSRC_MMIO
+ select GENERIC_IRQ_CHIP
+ select MACH_OMAP_GENERIC
+ select MEMORY
+ select MFD_SYSCON
+ select OMAP_DM_TIMER
+ select OMAP_GPMC
+ select PINCTRL
+ select SOC_BUS
+ select TI_PRIV_EDMA
+ select OMAP_IRQCHIP
+ help
+ Systems based on OMAP2, OMAP3, OMAP4 or OMAP5
+
+
+if ARCH_OMAP2PLUS
+
+menu "TI OMAP2/3/4 Specific Features"
+
+config ARCH_OMAP2PLUS_TYPICAL
+ bool "Typical OMAP configuration"
+ default y
+ select AEABI
+ select HIGHMEM
+ select I2C
+ select I2C_OMAP
+ select MENELAUS if ARCH_OMAP2
+ select NEON if CPU_V7
+ select PM
+ select REGULATOR
+ select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
+ select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4
+ select VFP
+ help
+ Compile a kernel suitable for booting most boards
+
+config SOC_HAS_OMAP2_SDRC
+ bool "OMAP2 SDRAM Controller support"
+
+config SOC_HAS_REALTIME_COUNTER
+ bool "Real time free running counter"
+ depends on SOC_OMAP5 || SOC_DRA7XX
+ default y
+
+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 SOC_HAS_OMAP2_SDRC
+
+config SOC_OMAP2430
+ bool "OMAP2430 support"
+ depends on ARCH_OMAP2
+ default y
+ select SOC_HAS_OMAP2_SDRC
+
+config SOC_OMAP3430
+ bool "OMAP3430 support"
+ depends on ARCH_OMAP3
+ default y
+ select SOC_HAS_OMAP2_SDRC
+
+config SOC_TI81XX
+ bool "TI81XX support"
+ depends on ARCH_OMAP3
+ default y
+
+config OMAP_PACKAGE_CBC
+ bool
+
+config OMAP_PACKAGE_CBB
+ bool
+
+config OMAP_PACKAGE_CUS
+ bool
+
+config OMAP_PACKAGE_CBP
+ bool
+
+comment "OMAP Legacy Platform Data Board Type"
+ depends on ARCH_OMAP2PLUS
+
+config MACH_OMAP_GENERIC
+ bool
+
+config MACH_OMAP2_TUSB6010
+ bool
+ depends on ARCH_OMAP2 && SOC_OMAP2420
+ default y if MACH_NOKIA_N8X0
+
+config MACH_OMAP3_BEAGLE
+ bool "OMAP3 BEAGLE board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+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
+ default y
+ select OMAP_PACKAGE_CBB
+ 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
+ default y
+ select OMAP_PACKAGE_CBB
+ 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_OMAP3517EVM
+ bool "OMAP3517/ AM3517 EVM board"
+ depends on ARCH_OMAP3
+ default y
+
+config MACH_OMAP3_PANDORA
+ bool "OMAP3 Pandora"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+
+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 MACH_NOKIA_N810
+ select MACH_NOKIA_N810_WIMAX
+
+config MACH_NOKIA_RX51
+ bool "Nokia N900 (RX-51) phone"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_CM_T35
+ bool "CompuLab CM-T35/CM-T3730 modules"
+ depends on ARCH_OMAP3
+ default y
+ select MACH_CM_T3730
+ select OMAP_PACKAGE_CUS
+
+config MACH_CM_T3730
+ bool
+
+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
+
+endmenu
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
new file mode 100644
index 000000000..ec002bd4a
--- /dev/null
+++ b/arch/arm/mach-omap2/Makefile
@@ -0,0 +1,284 @@
+#
+# Makefile for the linux kernel.
+#
+
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
+ -I$(srctree)/arch/arm/plat-omap/include
+
+# Common support
+obj-y := id.o io.o control.o mux.o devices.o fb.o serial.o timer.o pm.o \
+ common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \
+ omap_device.o sram.o drm.o
+
+hwmod-common = omap_hwmod.o omap_hwmod_reset.o \
+ omap_hwmod_common_data.o
+clock-common = clock.o clock_common_data.o \
+ clkt_dpll.o clkt_clksel.o
+secure-common = omap-smc.o omap-secure.o
+
+obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common)
+obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
+obj-$(CONFIG_ARCH_OMAP4) += $(hwmod-common) $(secure-common)
+obj-$(CONFIG_SOC_AM33XX) += $(hwmod-common)
+obj-$(CONFIG_SOC_OMAP5) += $(hwmod-common) $(secure-common)
+obj-$(CONFIG_SOC_AM43XX) += $(hwmod-common) $(secure-common)
+obj-$(CONFIG_SOC_DRA7XX) += $(hwmod-common) $(secure-common)
+
+ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),)
+obj-y += mcbsp.o
+endif
+
+obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
+obj-$(CONFIG_SOC_HAS_OMAP2_SDRC) += sdrc.o
+
+# SMP support ONLY available for OMAP4
+
+smp-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
+smp-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o
+omap-4-5-common = omap4-common.o omap-wakeupgen.o
+obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-common) $(smp-y) sleep44xx.o
+obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-common) $(smp-y) sleep44xx.o
+obj-$(CONFIG_SOC_AM43XX) += $(omap-4-5-common)
+obj-$(CONFIG_SOC_DRA7XX) += $(omap-4-5-common) $(smp-y) sleep44xx.o
+
+plus_sec := $(call as-instr,.arch_extension sec,+sec)
+AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec)
+AFLAGS_omap-smc.o :=-Wa,-march=armv7-a$(plus_sec)
+AFLAGS_sleep44xx.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
+
+# Restart code (OMAP4/5 currently in omap4-common.c)
+obj-$(CONFIG_SOC_OMAP2420) += omap2-restart.o
+obj-$(CONFIG_SOC_OMAP2430) += omap2-restart.o
+obj-$(CONFIG_SOC_TI81XX) += ti81xx-restart.o
+obj-$(CONFIG_SOC_AM33XX) += am33xx-restart.o
+obj-$(CONFIG_SOC_AM43XX) += omap4-restart.o
+obj-$(CONFIG_ARCH_OMAP3) += omap3-restart.o
+obj-$(CONFIG_ARCH_OMAP4) += omap4-restart.o
+obj-$(CONFIG_SOC_OMAP5) += omap4-restart.o
+obj-$(CONFIG_SOC_DRA7XX) += omap4-restart.o
+
+# Pin multiplexing
+obj-$(CONFIG_ARCH_OMAP3) += mux34xx.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
+obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
+
+ifeq ($(CONFIG_PM),y)
+obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
+obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o
+obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
+omap-4-5-pm-common = pm44xx.o omap-mpuss-lowpower.o
+obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-pm-common)
+obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-pm-common)
+obj-$(CONFIG_SOC_DRA7XX) += $(omap-4-5-pm-common)
+obj-$(CONFIG_PM_DEBUG) += pm-debug.o
+
+obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o
+obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o
+
+AFLAGS_sleep24xx.o :=-Wa,-march=armv6
+AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec)
+
+endif
+
+ifeq ($(CONFIG_CPU_IDLE),y)
+obj-$(CONFIG_ARCH_OMAP3) += cpuidle34xx.o
+omap-4-5-idle-common = cpuidle44xx.o
+obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-idle-common)
+obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-idle-common)
+obj-$(CONFIG_SOC_DRA7XX) += $(omap-4-5-idle-common)
+endif
+
+# PRCM
+obj-y += prm_common.o cm_common.o
+obj-$(CONFIG_ARCH_OMAP2) += prm2xxx_3xxx.o prm2xxx.o cm2xxx.o
+obj-$(CONFIG_ARCH_OMAP3) += prm2xxx_3xxx.o prm3xxx.o cm3xxx.o
+obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o
+omap-prcm-4-5-common = cminst44xx.o prm44xx.o \
+ prcm_mpu44xx.o prminst44xx.o \
+ vc44xx_data.o vp44xx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common)
+obj-$(CONFIG_SOC_OMAP5) += $(omap-prcm-4-5-common)
+obj-$(CONFIG_SOC_DRA7XX) += $(omap-prcm-4-5-common)
+am33xx-43xx-prcm-common += prm33xx.o cm33xx.o
+obj-$(CONFIG_SOC_TI81XX) += $(am33xx-43xx-prcm-common)
+obj-$(CONFIG_SOC_AM33XX) += $(am33xx-43xx-prcm-common)
+obj-$(CONFIG_SOC_AM43XX) += $(omap-prcm-4-5-common) \
+ $(am33xx-43xx-prcm-common)
+
+# OMAP voltage domains
+voltagedomain-common := voltage.o vc.o vp.o
+obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common)
+obj-$(CONFIG_ARCH_OMAP2) += voltagedomains2xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += $(voltagedomain-common)
+obj-$(CONFIG_ARCH_OMAP3) += voltagedomains3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += $(voltagedomain-common)
+obj-$(CONFIG_ARCH_OMAP4) += voltagedomains44xx_data.o
+obj-$(CONFIG_SOC_AM33XX) += $(voltagedomain-common)
+obj-$(CONFIG_SOC_AM43XX) += $(voltagedomain-common)
+obj-$(CONFIG_SOC_OMAP5) += $(voltagedomain-common)
+obj-$(CONFIG_SOC_OMAP5) += voltagedomains54xx_data.o
+obj-$(CONFIG_SOC_DRA7XX) += $(voltagedomain-common)
+
+# OMAP powerdomain framework
+powerdomain-common += powerdomain.o powerdomain-common.o
+obj-$(CONFIG_ARCH_OMAP2) += $(powerdomain-common)
+obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_data.o
+obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += $(powerdomain-common)
+obj-$(CONFIG_ARCH_OMAP3) += powerdomains3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += powerdomains2xxx_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common)
+obj-$(CONFIG_ARCH_OMAP4) += powerdomains44xx_data.o
+obj-$(CONFIG_SOC_AM33XX) += $(powerdomain-common)
+obj-$(CONFIG_SOC_AM33XX) += powerdomains33xx_data.o
+obj-$(CONFIG_SOC_AM43XX) += $(powerdomain-common)
+obj-$(CONFIG_SOC_AM43XX) += powerdomains43xx_data.o
+obj-$(CONFIG_SOC_OMAP5) += $(powerdomain-common)
+obj-$(CONFIG_SOC_OMAP5) += powerdomains54xx_data.o
+obj-$(CONFIG_SOC_DRA7XX) += $(powerdomain-common)
+obj-$(CONFIG_SOC_DRA7XX) += powerdomains7xx_data.o
+
+# PRCM clockdomain control
+clockdomain-common += clockdomain.o
+obj-$(CONFIG_ARCH_OMAP2) += $(clockdomain-common)
+obj-$(CONFIG_ARCH_OMAP2) += clockdomains2xxx_3xxx_data.o
+obj-$(CONFIG_SOC_OMAP2420) += clockdomains2420_data.o
+obj-$(CONFIG_SOC_OMAP2430) += clockdomains2430_data.o
+obj-$(CONFIG_ARCH_OMAP3) += $(clockdomain-common)
+obj-$(CONFIG_ARCH_OMAP3) += clockdomains2xxx_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += clockdomains3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += $(clockdomain-common)
+obj-$(CONFIG_ARCH_OMAP4) += clockdomains44xx_data.o
+obj-$(CONFIG_SOC_AM33XX) += $(clockdomain-common)
+obj-$(CONFIG_SOC_AM33XX) += clockdomains33xx_data.o
+obj-$(CONFIG_SOC_TI81XX) += $(clockdomain-common)
+obj-$(CONFIG_SOC_TI81XX) += clockdomains81xx_data.o
+obj-$(CONFIG_SOC_AM43XX) += $(clockdomain-common)
+obj-$(CONFIG_SOC_AM43XX) += clockdomains43xx_data.o
+obj-$(CONFIG_SOC_OMAP5) += $(clockdomain-common)
+obj-$(CONFIG_SOC_OMAP5) += clockdomains54xx_data.o
+obj-$(CONFIG_SOC_DRA7XX) += $(clockdomain-common)
+obj-$(CONFIG_SOC_DRA7XX) += clockdomains7xx_data.o
+
+# Clock framework
+obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o
+obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o
+obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_virt_prcm_set.o
+obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpll.o clkt_iclk.o
+obj-$(CONFIG_SOC_OMAP2430) += clock2430.o
+obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o
+obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o clkt34xx_dpll3m2.o
+obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o
+obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o
+obj-$(CONFIG_ARCH_OMAP3) += clkt_iclk.o
+obj-$(CONFIG_ARCH_OMAP4) += $(clock-common)
+obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o
+obj-$(CONFIG_SOC_AM33XX) += $(clock-common) dpll3xxx.o
+obj-$(CONFIG_SOC_OMAP5) += $(clock-common)
+obj-$(CONFIG_SOC_OMAP5) += dpll3xxx.o dpll44xx.o
+obj-$(CONFIG_SOC_DRA7XX) += $(clock-common)
+obj-$(CONFIG_SOC_DRA7XX) += dpll3xxx.o dpll44xx.o
+obj-$(CONFIG_SOC_AM43XX) += $(clock-common) dpll3xxx.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-y += omap_hwmod_common_ipblock_data.o
+obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_ipblock_data.o
+obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_3xxx_ipblock_data.o
+obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_interconnect_data.o
+obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_3xxx_interconnect_data.o
+obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2420_data.o
+obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_ipblock_data.o
+obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_3xxx_ipblock_data.o
+obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_interconnect_data.o
+obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_3xxx_interconnect_data.o
+obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2430_data.o
+obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_2xxx_3xxx_ipblock_data.o
+obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_2xxx_3xxx_interconnect_data.o
+obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_3xxx_data.o
+obj-$(CONFIG_SOC_AM33XX) += omap_hwmod_33xx_data.o
+obj-$(CONFIG_SOC_AM33XX) += omap_hwmod_33xx_43xx_interconnect_data.o
+obj-$(CONFIG_SOC_AM33XX) += omap_hwmod_33xx_43xx_ipblock_data.o
+obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_43xx_data.o
+obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_33xx_43xx_interconnect_data.o
+obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_33xx_43xx_ipblock_data.o
+obj-$(CONFIG_SOC_TI81XX) += omap_hwmod_81xx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o
+obj-$(CONFIG_SOC_OMAP5) += omap_hwmod_54xx_data.o
+obj-$(CONFIG_SOC_DRA7XX) += omap_hwmod_7xx_data.o
+
+# EMU peripherals
+obj-$(CONFIG_HW_PERF_EVENTS) += pmu.o
+
+iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o
+obj-y += $(iommu-m) $(iommu-y)
+
+# OMAP2420 MSDI controller integration support ("MMC")
+obj-$(CONFIG_SOC_OMAP2420) += msdi.o
+
+# Specific board support
+obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o pdata-quirks.o
+obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o
+obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o
+obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o
+obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o
+obj-$(CONFIG_MACH_OVERO) += board-overo.o
+obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o
+obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o
+obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o sdram-nokia.o
+obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-peripherals.o
+obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-video.o
+obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o
+
+# Platform specific device init code
+
+omap-flash-$(CONFIG_MTD_NAND_OMAP2) := board-flash.o
+omap-flash-$(CONFIG_MTD_ONENAND_OMAP2) := board-flash.o
+obj-y += $(omap-flash-y) $(omap-flash-m)
+
+omap-hsmmc-$(CONFIG_MMC_OMAP_HS) := hsmmc.o
+obj-y += $(omap-hsmmc-m) $(omap-hsmmc-y)
+
+obj-y += usb-musb.o
+obj-y += omap_phy_internal.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)
+
+smsc911x-$(CONFIG_SMSC911X) := gpmc-smsc911x.o
+obj-y += $(smsc911x-m) $(smsc911x-y)
+ifneq ($(CONFIG_HWSPINLOCK_OMAP),)
+obj-y += hwspinlock.o
+endif
+
+obj-y += common-board-devices.o twl-common.o dss-common.o
diff --git a/arch/arm/mach-omap2/Makefile.boot b/arch/arm/mach-omap2/Makefile.boot
new file mode 100644
index 000000000..b03e562ac
--- /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/am33xx-restart.c b/arch/arm/mach-omap2/am33xx-restart.c
new file mode 100644
index 000000000..5bace6a45
--- /dev/null
+++ b/arch/arm/mach-omap2/am33xx-restart.c
@@ -0,0 +1,27 @@
+/*
+ * am33xx-restart.c - Code common to all AM33xx 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/kernel.h>
+#include <linux/reboot.h>
+
+#include "common.h"
+#include "prm.h"
+
+/**
+ * am3xx_restart - trigger a software restart of the SoC
+ * @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c
+ * @cmd: passed from the userspace program rebooting the system (if provided)
+ *
+ * Resets the SoC. For @cmd, see the 'reboot' syscall in
+ * kernel/sys.c. No return value.
+ */
+void am33xx_restart(enum reboot_mode mode, const char *cmd)
+{
+ /* TODO: Handle mode and cmd if necessary */
+
+ omap_prm_reset_system();
+}
diff --git a/arch/arm/mach-omap2/am33xx.h b/arch/arm/mach-omap2/am33xx.h
new file mode 100644
index 000000000..5eef093e6
--- /dev/null
+++ b/arch/arm/mach-omap2/am33xx.h
@@ -0,0 +1,27 @@
+/*
+ * This file contains the address info for various AM33XX modules.
+ *
+ * Copyright (C) 2011 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_AM33XX_H
+#define __ASM_ARCH_AM33XX_H
+
+#define L4_SLOW_AM33XX_BASE 0x48000000
+
+#define AM33XX_SCM_BASE 0x44E10000
+#define AM33XX_CTRL_BASE AM33XX_SCM_BASE
+#define AM33XX_PRCM_BASE 0x44E00000
+#define AM43XX_PRCM_BASE 0x44DF0000
+#define AM33XX_TAP_BASE (AM33XX_CTRL_BASE + 0x3FC)
+
+#endif /* __ASM_ARCH_AM33XX_H */
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 000000000..b5dfbc1b1
--- /dev/null
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -0,0 +1,769 @@
+/*
+ * CompuLab CM-T35/CM-T3730 modules support
+ *
+ * Copyright (C) 2009-2011 CompuLab, Ltd.
+ * Authors: 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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-provider.h>
+#include <linux/clkdev.h>
+#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/omap-gpmc.h>
+#include <linux/platform_data/gpio-omap.h>
+
+#include <linux/platform_data/at24.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/mmc/host.h>
+#include <linux/usb/phy.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 <linux/platform_data/mtd-nand-omap2.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-data.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+
+#include "common.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 SB_T35_USB_HUB_RESET_GPIO 167
+
+#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 "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 struct regulator_consumer_supply cm_t35_smsc911x_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x.0"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x.0"),
+};
+
+static struct regulator_consumer_supply sb_t35_smsc911x_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x.1"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x.1"),
+};
+
+static void __init cm_t35_init_ethernet(void)
+{
+ regulator_register_fixed(0, cm_t35_smsc911x_supplies,
+ ARRAY_SIZE(cm_t35_smsc911x_supplies));
+ regulator_register_fixed(1, sb_t35_smsc911x_supplies,
+ ARRAY_SIZE(sb_t35_smsc911x_supplies));
+
+ 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 = 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_t35_nand_data = {
+ .parts = cm_t35_nand_partitions,
+ .nr_parts = ARRAY_SIZE(cm_t35_nand_partitions),
+ .cs = 0,
+};
+
+static void __init cm_t35_init_nand(void)
+{
+ if (gpmc_nand_init(&cm_t35_nand_data, NULL) < 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 const struct display_timing cm_t35_lcd_videomode = {
+ .pixelclock = { 0, 26000000, 0 },
+
+ .hactive = { 0, 480, 0 },
+ .hfront_porch = { 0, 104, 0 },
+ .hback_porch = { 0, 8, 0 },
+ .hsync_len = { 0, 8, 0 },
+
+ .vactive = { 0, 640, 0 },
+ .vfront_porch = { 0, 4, 0 },
+ .vback_porch = { 0, 2, 0 },
+ .vsync_len = { 0, 2, 0 },
+
+ .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
+ DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_NEGEDGE,
+};
+
+static struct panel_dpi_platform_data cm_t35_lcd_pdata = {
+ .name = "lcd",
+ .source = "dpi.0",
+
+ .data_lines = 18,
+
+ .display_timing = &cm_t35_lcd_videomode,
+
+ .enable_gpio = -1,
+ .backlight_gpio = CM_T35_LCD_BL_GPIO,
+};
+
+static struct platform_device cm_t35_lcd_device = {
+ .name = "panel-dpi",
+ .id = 0,
+ .dev.platform_data = &cm_t35_lcd_pdata,
+};
+
+static struct connector_dvi_platform_data cm_t35_dvi_connector_pdata = {
+ .name = "dvi",
+ .source = "tfp410.0",
+ .i2c_bus_num = -1,
+};
+
+static struct platform_device cm_t35_dvi_connector_device = {
+ .name = "connector-dvi",
+ .id = 0,
+ .dev.platform_data = &cm_t35_dvi_connector_pdata,
+};
+
+static struct encoder_tfp410_platform_data cm_t35_tfp410_pdata = {
+ .name = "tfp410.0",
+ .source = "dpi.0",
+ .data_lines = 24,
+ .power_down_gpio = CM_T35_DVI_EN_GPIO,
+};
+
+static struct platform_device cm_t35_tfp410_device = {
+ .name = "tfp410",
+ .id = 0,
+ .dev.platform_data = &cm_t35_tfp410_pdata,
+};
+
+static struct connector_atv_platform_data cm_t35_tv_pdata = {
+ .name = "tv",
+ .source = "venc.0",
+ .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO,
+ .invert_polarity = false,
+};
+
+static struct platform_device cm_t35_tv_connector_device = {
+ .name = "connector-analog-tv",
+ .id = 0,
+ .dev.platform_data = &cm_t35_tv_pdata,
+};
+
+static struct omap_dss_board_info cm_t35_dss_data = {
+ .default_display_name = "dvi",
+};
+
+static struct omap2_mcspi_device_config tdo24m_mcspi_config = {
+ .turbo_mode = 0,
+};
+
+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 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_one(CM_T35_LCD_EN_GPIO, GPIOF_OUT_INIT_LOW,
+ "lcd bl enable");
+ if (err) {
+ pr_err("CM-T35: failed to request LCD EN GPIO\n");
+ return;
+ }
+
+ 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(CM_T35_LCD_EN_GPIO);
+ }
+
+ platform_device_register(&cm_t35_tfp410_device);
+ platform_device_register(&cm_t35_dvi_connector_device);
+ platform_device_register(&cm_t35_lcd_device);
+ platform_device_register(&cm_t35_tv_connector_device);
+}
+
+static struct regulator_consumer_supply cm_t35_vmmc1_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply cm_t35_vsim_supply[] = {
+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply cm_t35_vio_supplies[] = {
+ REGULATOR_SUPPLY("vcc", "spi1.0"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dpi.0"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
+};
+
+/* 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 = ARRAY_SIZE(cm_t35_vmmc1_supply),
+ .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 = ARRAY_SIZE(cm_t35_vsim_supply),
+ .consumer_supplies = cm_t35_vsim_supply,
+};
+
+static struct regulator_init_data cm_t35_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,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(cm_t35_vio_supplies),
+ .consumer_supplies = cm_t35_vio_supplies,
+};
+
+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,
+ .deferred = true,
+ },
+ {
+ .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_phy_data phy_data[] __initdata = {
+ {
+ .port = 1,
+ .reset_gpio = OMAP_MAX_GPIO_LINES + 6,
+ .vcc_gpio = -EINVAL,
+ },
+ {
+ .port = 2,
+ .reset_gpio = OMAP_MAX_GPIO_LINES + 7,
+ .vcc_gpio = -EINVAL,
+ },
+};
+
+static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+};
+
+static void __init cm_t35_init_usbh(void)
+{
+ int err;
+
+ err = gpio_request_one(SB_T35_USB_HUB_RESET_GPIO,
+ GPIOF_OUT_INIT_LOW, "usb hub rst");
+ if (err) {
+ pr_err("SB-T35: usb hub rst gpio request failed: %d\n", err);
+ } else {
+ udelay(10);
+ gpio_set_value(SB_T35_USB_HUB_RESET_GPIO, 1);
+ msleep(1);
+ }
+
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
+ usbhs_init(&usbhs_bdata);
+}
+
+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_cansleep(wlan_rst, 0);
+ udelay(10);
+ gpio_set_value_cansleep(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;
+ omap_hsmmc_late_init(mmc);
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data cm_t35_gpio_data = {
+ .setup = cm_t35_twl_gpio_setup,
+};
+
+static struct twl4030_power_data cm_t35_power_data = {
+ .use_poweroff = true,
+};
+
+static struct twl4030_platform_data cm_t35_twldata = {
+ /* platform_data for children goes here */
+ .keypad = &cm_t35_kp_data,
+ .gpio = &cm_t35_gpio_data,
+ .vmmc1 = &cm_t35_vmmc1,
+ .vsim = &cm_t35_vsim,
+ .vio = &cm_t35_vio,
+ .power = &cm_t35_power_data,
+};
+
+#if defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
+#include <media/omap3isp.h>
+#include "devices.h"
+
+static struct isp_platform_subdev cm_t35_isp_subdevs[] = {
+ {
+ .board_info = &(struct i2c_board_info){
+ I2C_BOARD_INFO("mt9t001", 0x5d)
+ },
+ .i2c_adapter_id = 3,
+ .bus = &(struct isp_bus_cfg){
+ .interface = ISP_INTERFACE_PARALLEL,
+ .bus = {
+ .parallel = {
+ .clk_pol = 1,
+ },
+ },
+ },
+ },
+ {
+ .board_info = &(struct i2c_board_info){
+ I2C_BOARD_INFO("tvp5150", 0x5c),
+ },
+ .i2c_adapter_id = 3,
+ .bus = &(struct isp_bus_cfg){
+ .interface = ISP_INTERFACE_PARALLEL,
+ .bus = {
+ .parallel = {
+ .clk_pol = 0,
+ },
+ },
+ },
+ },
+ { 0 },
+};
+
+static struct isp_platform_data cm_t35_isp_pdata = {
+ .subdevs = cm_t35_isp_subdevs,
+};
+
+static struct regulator_consumer_supply cm_t35_camera_supplies[] = {
+ REGULATOR_SUPPLY("vaa", "3-005d"),
+ REGULATOR_SUPPLY("vdd", "3-005d"),
+};
+
+static void __init cm_t35_init_camera(void)
+{
+ struct clk *clk;
+
+ clk = clk_register_fixed_rate(NULL, "mt9t001-clkin", NULL, CLK_IS_ROOT,
+ 48000000);
+ clk_register_clkdev(clk, NULL, "3-005d");
+
+ regulator_register_fixed(2, cm_t35_camera_supplies,
+ ARRAY_SIZE(cm_t35_camera_supplies));
+
+ if (omap3_init_camera(&cm_t35_isp_pdata) < 0)
+ pr_warn("CM-T3x: Failed registering camera device!\n");
+}
+
+#else
+static inline void cm_t35_init_camera(void) {}
+#endif /* CONFIG_VIDEO_OMAP3 */
+
+static void __init cm_t35_init_i2c(void)
+{
+ omap3_pmic_get_config(&cm_t35_twldata, TWL_COMMON_PDATA_USB,
+ TWL_COMMON_REGULATOR_VDAC |
+ TWL_COMMON_PDATA_AUDIO);
+
+ omap3_pmic_init("tps65930", &cm_t35_twldata);
+
+ omap_register_i2c_bus(3, 400, NULL, 0);
+}
+
+#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),
+
+ /* common 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_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),
+
+ /* Camera */
+ OMAP3_MUX(CAM_HS, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(CAM_VS, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(CAM_XCLKA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(CAM_PCLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(CAM_FLD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(CAM_D0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(CAM_D1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(CAM_D2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(CAM_D3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(CAM_D4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(CAM_D5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(CAM_D6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(CAM_D7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(CAM_D8, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ OMAP3_MUX(CAM_D9, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ OMAP3_MUX(CAM_STROBE, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ OMAP3_MUX(CAM_D10, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLDOWN),
+ OMAP3_MUX(CAM_D11, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLDOWN),
+
+ /* 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 },
+};
+
+static void __init cm_t3x_common_dss_mux_init(int mux_mode)
+{
+ omap_mux_init_signal("dss_data18", mux_mode);
+ omap_mux_init_signal("dss_data19", mux_mode);
+ omap_mux_init_signal("dss_data20", mux_mode);
+ omap_mux_init_signal("dss_data21", mux_mode);
+ omap_mux_init_signal("dss_data22", mux_mode);
+ omap_mux_init_signal("dss_data23", mux_mode);
+}
+
+static void __init cm_t35_init_mux(void)
+{
+ int mux_mode = OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT;
+
+ omap_mux_init_signal("dss_data0.dss_data0", mux_mode);
+ omap_mux_init_signal("dss_data1.dss_data1", mux_mode);
+ omap_mux_init_signal("dss_data2.dss_data2", mux_mode);
+ omap_mux_init_signal("dss_data3.dss_data3", mux_mode);
+ omap_mux_init_signal("dss_data4.dss_data4", mux_mode);
+ omap_mux_init_signal("dss_data5.dss_data5", mux_mode);
+ cm_t3x_common_dss_mux_init(mux_mode);
+}
+
+static void __init cm_t3730_init_mux(void)
+{
+ int mux_mode = OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT;
+
+ omap_mux_init_signal("sys_boot0", mux_mode);
+ omap_mux_init_signal("sys_boot1", mux_mode);
+ omap_mux_init_signal("sys_boot3", mux_mode);
+ omap_mux_init_signal("sys_boot4", mux_mode);
+ omap_mux_init_signal("sys_boot5", mux_mode);
+ omap_mux_init_signal("sys_boot6", mux_mode);
+ cm_t3x_common_dss_mux_init(mux_mode);
+}
+#else
+static inline void cm_t35_init_mux(void) {}
+static inline void cm_t3730_init_mux(void) {}
+#endif
+
+static void __init cm_t3x_common_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
+ omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+ omap_hsmmc_init(mmc);
+ cm_t35_init_i2c();
+ omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
+ cm_t35_init_ethernet();
+ cm_t35_init_led();
+ cm_t35_init_display();
+ omap_twl4030_audio_init("cm-t3x", NULL);
+
+ usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
+ usb_musb_init(NULL);
+ cm_t35_init_usbh();
+ cm_t35_init_camera();
+}
+
+static void __init cm_t35_init(void)
+{
+ cm_t3x_common_init();
+ cm_t35_init_mux();
+ cm_t35_init_nand();
+}
+
+static void __init cm_t3730_init(void)
+{
+ cm_t3x_common_init();
+ cm_t3730_init_mux();
+}
+
+MACHINE_START(CM_T35, "Compulab CM-T35")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .init_machine = cm_t35_init,
+ .init_late = omap35xx_init_late,
+ .init_time = omap3_sync32k_timer_init,
+ .restart = omap3xxx_restart,
+MACHINE_END
+
+MACHINE_START(CM_T3730, "Compulab CM-T3730")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3630_init_early,
+ .init_irq = omap3_init_irq,
+ .init_machine = cm_t3730_init,
+ .init_late = omap3630_init_late,
+ .init_time = omap3_sync32k_timer_init,
+ .restart = omap3xxx_restart,
+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 000000000..70b21cc27
--- /dev/null
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -0,0 +1,244 @@
+/*
+ * 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/omap-gpmc.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+
+#include <linux/platform_data/mtd-nand-omap2.h>
+#include <linux/platform_data/mtd-onenand-omap2.h>
+
+#include "soc.h"
+#include "common.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 */
+};
+
+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);
+}
+#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 */
+struct gpmc_timings nand_default_timings[1] = {
+ {
+ .sync_clk = 0,
+
+ .cs_on = 0,
+ .cs_rd_off = 36,
+ .cs_wr_off = 36,
+
+ .we_on = 6,
+ .oe_on = 6,
+
+ .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;
+
+void
+__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
+ int nand_type, struct gpmc_timings *gpmc_t)
+{
+ 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_HAM1_CODE_SW;
+ gpmc_nand_init(&board_nand_data, gpmc_t);
+}
+#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 (!(readw_relaxed(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 = readw_relaxed(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 __init 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, nand_default_timings);
+}
diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h
new file mode 100644
index 000000000..ea9aaebe1
--- /dev/null
+++ b/arch/arm/mach-omap2/board-flash.h
@@ -0,0 +1,61 @@
+/*
+ * 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>
+
+#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;
+};
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || \
+ defined(CONFIG_MTD_NAND_OMAP2_MODULE) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+extern void board_flash_init(struct flash_partitions [],
+ char chip_sel[][GPMC_CS_NUM], int nand_type);
+#else
+static inline void board_flash_init(struct flash_partitions part[],
+ char chip_sel[][GPMC_CS_NUM], int nand_type)
+{
+}
+#endif
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || \
+ defined(CONFIG_MTD_NAND_OMAP2_MODULE)
+extern void board_nand_init(struct mtd_partition *nand_parts,
+ u8 nr_parts, u8 cs, int nand_type, struct gpmc_timings *gpmc_t);
+extern struct gpmc_timings nand_default_timings[];
+#else
+static inline void board_nand_init(struct mtd_partition *nand_parts,
+ u8 nr_parts, u8 cs, int nand_type, struct gpmc_timings *gpmc_t)
+{
+}
+#define nand_default_timings NULL
+#endif
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+extern void board_onenand_init(struct mtd_partition *nand_parts,
+ u8 nr_parts, u8 cs);
+#else
+static inline void board_onenand_init(struct mtd_partition *nand_parts,
+ u8 nr_parts, u8 cs)
+{
+}
+#endif
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
new file mode 100644
index 000000000..34ff14b7b
--- /dev/null
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Modified from the original mach-omap/omap2/board-generic.c did by Paul
+ * to support the OMAP2+ device tree boards with an unique board file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/io.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/irqdomain.h>
+
+#include <asm/mach/arch.h>
+
+#include "common.h"
+
+#if !(defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3))
+#define intc_of_init NULL
+#endif
+#ifndef CONFIG_ARCH_OMAP4
+#define gic_of_init NULL
+#endif
+
+static const struct of_device_id omap_dt_match_table[] __initconst = {
+ { .compatible = "simple-bus", },
+ { .compatible = "ti,omap-infra", },
+ { }
+};
+
+static void __init omap_generic_init(void)
+{
+ omapdss_early_init_of();
+
+ pdata_quirks_init(omap_dt_match_table);
+
+ omapdss_init_of();
+}
+
+#ifdef CONFIG_SOC_OMAP2420
+static const char *const omap242x_boards_compat[] __initconst = {
+ "ti,omap2420",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)")
+ .reserve = omap_reserve,
+ .map_io = omap242x_map_io,
+ .init_early = omap2420_init_early,
+ .init_machine = omap_generic_init,
+ .init_time = omap2_sync32k_timer_init,
+ .dt_compat = omap242x_boards_compat,
+ .restart = omap2xxx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_SOC_OMAP2430
+static const char *const omap243x_boards_compat[] __initconst = {
+ "ti,omap2430",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)")
+ .reserve = omap_reserve,
+ .map_io = omap243x_map_io,
+ .init_early = omap2430_init_early,
+ .init_machine = omap_generic_init,
+ .init_time = omap2_sync32k_timer_init,
+ .dt_compat = omap243x_boards_compat,
+ .restart = omap2xxx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+/* Some boards need board name for legacy userspace in /proc/cpuinfo */
+static const char *const n900_boards_compat[] __initconst = {
+ "nokia,omap3-n900",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP3_N900_DT, "Nokia RX-51 board")
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3430_init_early,
+ .init_machine = omap_generic_init,
+ .init_late = omap3_init_late,
+ .init_time = omap3_sync32k_timer_init,
+ .dt_compat = n900_boards_compat,
+ .restart = omap3xxx_restart,
+MACHINE_END
+
+/* Generic omap3 boards, most boards can use these */
+static const char *const omap3_boards_compat[] __initconst = {
+ "ti,omap3430",
+ "ti,omap3",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3430_init_early,
+ .init_machine = omap_generic_init,
+ .init_late = omap3_init_late,
+ .init_time = omap3_sync32k_timer_init,
+ .dt_compat = omap3_boards_compat,
+ .restart = omap3xxx_restart,
+MACHINE_END
+
+static const char *const omap36xx_boards_compat[] __initconst = {
+ "ti,omap36xx",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP36XX_DT, "Generic OMAP36xx (Flattened Device Tree)")
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3630_init_early,
+ .init_machine = omap_generic_init,
+ .init_late = omap3_init_late,
+ .init_time = omap3_sync32k_timer_init,
+ .dt_compat = omap36xx_boards_compat,
+ .restart = omap3xxx_restart,
+MACHINE_END
+
+static const char *const omap3_gp_boards_compat[] __initconst = {
+ "ti,omap3-beagle",
+ "timll,omap3-devkit8000",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP3_GP_DT, "Generic OMAP3-GP (Flattened Device Tree)")
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3430_init_early,
+ .init_machine = omap_generic_init,
+ .init_late = omap3_init_late,
+ .init_time = omap3_secure_sync32k_timer_init,
+ .dt_compat = omap3_gp_boards_compat,
+ .restart = omap3xxx_restart,
+MACHINE_END
+
+static const char *const am3517_boards_compat[] __initconst = {
+ "ti,am3517",
+ NULL,
+};
+
+DT_MACHINE_START(AM3517_DT, "Generic AM3517 (Flattened Device Tree)")
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = am35xx_init_early,
+ .init_machine = omap_generic_init,
+ .init_late = omap3_init_late,
+ .init_time = omap3_gptimer_timer_init,
+ .dt_compat = am3517_boards_compat,
+ .restart = omap3xxx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_SOC_TI81XX
+static const char *const ti814x_boards_compat[] __initconst = {
+ "ti,dm8148",
+ "ti,dm814",
+ NULL,
+};
+
+DT_MACHINE_START(TI81XX_DT, "Generic ti814x (Flattened Device Tree)")
+ .reserve = omap_reserve,
+ .map_io = ti81xx_map_io,
+ .init_early = ti814x_init_early,
+ .init_machine = omap_generic_init,
+ .init_late = ti81xx_init_late,
+ .init_time = omap3_gptimer_timer_init,
+ .dt_compat = ti814x_boards_compat,
+ .restart = ti81xx_restart,
+MACHINE_END
+
+static const char *const ti816x_boards_compat[] __initconst = {
+ "ti,dm8168",
+ "ti,dm816",
+ NULL,
+};
+
+DT_MACHINE_START(TI816X_DT, "Generic ti816x (Flattened Device Tree)")
+ .reserve = omap_reserve,
+ .map_io = ti81xx_map_io,
+ .init_early = ti816x_init_early,
+ .init_machine = omap_generic_init,
+ .init_late = ti81xx_init_late,
+ .init_time = omap3_gptimer_timer_init,
+ .dt_compat = ti816x_boards_compat,
+ .restart = ti81xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_SOC_AM33XX
+static const char *const am33xx_boards_compat[] __initconst = {
+ "ti,am33xx",
+ NULL,
+};
+
+DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)")
+ .reserve = omap_reserve,
+ .map_io = am33xx_map_io,
+ .init_early = am33xx_init_early,
+ .init_machine = omap_generic_init,
+ .init_late = am33xx_init_late,
+ .init_time = omap3_gptimer_timer_init,
+ .dt_compat = am33xx_boards_compat,
+ .restart = am33xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+static const char *const omap4_boards_compat[] __initconst = {
+ "ti,omap4460",
+ "ti,omap4430",
+ "ti,omap4",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")
+ .l2c_aux_val = OMAP_L2C_AUX_CTRL,
+ .l2c_aux_mask = 0xcf9fffff,
+ .l2c_write_sec = omap4_l2c310_write_sec,
+ .reserve = omap_reserve,
+ .smp = smp_ops(omap4_smp_ops),
+ .map_io = omap4_map_io,
+ .init_early = omap4430_init_early,
+ .init_irq = omap_gic_of_init,
+ .init_machine = omap_generic_init,
+ .init_late = omap4430_init_late,
+ .init_time = omap4_local_timer_init,
+ .dt_compat = omap4_boards_compat,
+ .restart = omap44xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_SOC_OMAP5
+static const char *const omap5_boards_compat[] __initconst = {
+ "ti,omap5432",
+ "ti,omap5430",
+ "ti,omap5",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")
+ .reserve = omap_reserve,
+ .smp = smp_ops(omap4_smp_ops),
+ .map_io = omap5_map_io,
+ .init_early = omap5_init_early,
+ .init_irq = omap_gic_of_init,
+ .init_machine = omap_generic_init,
+ .init_late = omap5_init_late,
+ .init_time = omap5_realtime_timer_init,
+ .dt_compat = omap5_boards_compat,
+ .restart = omap44xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_SOC_AM43XX
+static const char *const am43_boards_compat[] __initconst = {
+ "ti,am4372",
+ "ti,am43",
+ NULL,
+};
+
+DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)")
+ .l2c_aux_val = OMAP_L2C_AUX_CTRL,
+ .l2c_aux_mask = 0xcf9fffff,
+ .l2c_write_sec = omap4_l2c310_write_sec,
+ .map_io = am33xx_map_io,
+ .init_early = am43xx_init_early,
+ .init_late = am43xx_init_late,
+ .init_irq = omap_gic_of_init,
+ .init_machine = omap_generic_init,
+ .init_time = omap3_gptimer_timer_init,
+ .dt_compat = am43_boards_compat,
+ .restart = omap44xx_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_SOC_DRA7XX
+static const char *const dra74x_boards_compat[] __initconst = {
+ "ti,am5728",
+ "ti,am5726",
+ "ti,dra742",
+ "ti,dra7",
+ NULL,
+};
+
+DT_MACHINE_START(DRA74X_DT, "Generic DRA74X (Flattened Device Tree)")
+ .reserve = omap_reserve,
+ .smp = smp_ops(omap4_smp_ops),
+ .map_io = omap5_map_io,
+ .init_early = dra7xx_init_early,
+ .init_late = dra7xx_init_late,
+ .init_irq = omap_gic_of_init,
+ .init_machine = omap_generic_init,
+ .init_time = omap5_realtime_timer_init,
+ .dt_compat = dra74x_boards_compat,
+ .restart = omap44xx_restart,
+MACHINE_END
+
+static const char *const dra72x_boards_compat[] __initconst = {
+ "ti,am5718",
+ "ti,am5716",
+ "ti,dra722",
+ NULL,
+};
+
+DT_MACHINE_START(DRA72X_DT, "Generic DRA72X (Flattened Device Tree)")
+ .reserve = omap_reserve,
+ .map_io = omap5_map_io,
+ .init_early = dra7xx_init_early,
+ .init_late = dra7xx_init_late,
+ .init_irq = omap_gic_of_init,
+ .init_machine = omap_generic_init,
+ .init_time = omap5_realtime_timer_init,
+ .dt_compat = dra72x_boards_compat,
+ .restart = omap44xx_restart,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
new file mode 100644
index 000000000..c2975af4c
--- /dev/null
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -0,0 +1,429 @@
+/*
+ * 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/gpio.h>
+#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/fixed.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 <linux/usb/phy.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+#include "gpmc.h"
+#include "gpmc-smsc911x.h"
+
+#include <video/omapdss.h>
+#include <video/omap-panel-data.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);
+}
+
+/* LCD */
+
+#define LCD_PANEL_RESET_GPIO 55
+#define LCD_PANEL_QVGA_GPIO 56
+
+static const struct display_timing ldp_lcd_videomode = {
+ .pixelclock = { 0, 5400000, 0 },
+
+ .hactive = { 0, 240, 0 },
+ .hfront_porch = { 0, 3, 0 },
+ .hback_porch = { 0, 39, 0 },
+ .hsync_len = { 0, 3, 0 },
+
+ .vactive = { 0, 320, 0 },
+ .vfront_porch = { 0, 2, 0 },
+ .vback_porch = { 0, 7, 0 },
+ .vsync_len = { 0, 1, 0 },
+
+ .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
+ DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE,
+};
+
+static struct panel_dpi_platform_data ldp_lcd_pdata = {
+ .name = "lcd",
+ .source = "dpi.0",
+
+ .data_lines = 18,
+
+ .display_timing = &ldp_lcd_videomode,
+
+ .enable_gpio = -1, /* filled in code */
+ .backlight_gpio = -1, /* filled in code */
+};
+
+static struct platform_device ldp_lcd_device = {
+ .name = "panel-dpi",
+ .id = 0,
+ .dev.platform_data = &ldp_lcd_pdata,
+};
+
+static struct omap_dss_board_info ldp_dss_data = {
+ .default_display_name = "lcd",
+};
+
+static void __init ldp_display_init(void)
+{
+ int r;
+
+ static struct gpio gpios[] __initdata = {
+ {LCD_PANEL_RESET_GPIO, GPIOF_OUT_INIT_HIGH, "LCD RESET"},
+ {LCD_PANEL_QVGA_GPIO, GPIOF_OUT_INIT_HIGH, "LCD QVGA"},
+ };
+
+ r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
+ if (r) {
+ pr_err("Cannot request LCD GPIOs, error %d\n", r);
+ return;
+ }
+
+ omap_display_init(&ldp_dss_data);
+}
+
+static int ldp_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio)
+{
+ int res;
+
+ /* LCD enable GPIO */
+ ldp_lcd_pdata.enable_gpio = gpio + 7;
+
+ /* Backlight enable GPIO */
+ ldp_lcd_pdata.backlight_gpio = gpio + 15;
+
+ res = platform_device_register(&ldp_lcd_device);
+ if (res)
+ pr_err("Unable to register LCD: %d\n", res);
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data ldp_gpio_data = {
+ .setup = ldp_twl_gpio_setup,
+};
+
+static struct regulator_consumer_supply ldp_vmmc1_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+/* 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 = ARRAY_SIZE(ldp_vmmc1_supply),
+ .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 regulator_consumer_supply ldp_vpll2_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dpi.0"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
+};
+
+static struct regulator_init_data ldp_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(ldp_vpll2_supplies),
+ .consumer_supplies = ldp_vpll2_supplies,
+};
+
+static struct twl4030_platform_data ldp_twldata = {
+ /* platform_data for children goes here */
+ .vmmc1 = &ldp_vmmc1,
+ .vaux1 = &ldp_vaux1,
+ .vpll2 = &ldp_vpll2,
+ .gpio = &ldp_gpio_data,
+ .keypad = &ldp_kp_twl4030_data,
+};
+
+static int __init omap_i2c_init(void)
+{
+ omap3_pmic_get_config(&ldp_twldata,
+ TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC, 0);
+ 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_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 struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x.0"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x.0"),
+};
+
+static void __init omap_ldp_init(void)
+{
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ 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();
+ omap_sdrc_init(NULL, NULL);
+ usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
+ usb_musb_init(NULL);
+ board_nand_init(ldp_nand_partitions, ARRAY_SIZE(ldp_nand_partitions),
+ 0, 0, nand_default_timings);
+
+ omap_hsmmc_init(mmc);
+ ldp_display_init();
+}
+
+MACHINE_START(OMAP_LDP, "OMAP LDP board")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3430_init_early,
+ .init_irq = omap3_init_irq,
+ .init_machine = omap_ldp_init,
+ .init_late = omap3430_init_late,
+ .init_time = omap3_sync32k_timer_init,
+ .restart = omap3xxx_restart,
+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 000000000..b6443a4e0
--- /dev/null
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -0,0 +1,602 @@
+/*
+ * 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/irq.h>
+#include <linux/stddef.h>
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
+#include <linux/usb/musb.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+#include <linux/platform_data/mmc-omap.h>
+#include <linux/mfd/menelaus.h>
+#include <sound/tlv320aic3x.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include "common.h"
+#include "mmc.h"
+#include "soc.h"
+#include "common-board-devices.h"
+
+#define TUSB6010_ASYNC_CS 1
+#define TUSB6010_SYNC_CS 4
+#define TUSB6010_GPIO_INT 58
+#define TUSB6010_GPIO_ENABLE 0
+#define TUSB6010_DMACHAN 0x3f
+
+#define NOKIA_N810_WIMAX (1 << 2)
+#define NOKIA_N810 (1 << 1)
+#define NOKIA_N800 (1 << 0)
+
+static u32 board_caps;
+
+#define board_is_n800() (board_caps & NOKIA_N800)
+#define board_is_n810() (board_caps & NOKIA_N810)
+#define board_is_n810_wimax() (board_caps & NOKIA_N810_WIMAX)
+
+static void board_check_revision(void)
+{
+ if (of_have_populated_dt()) {
+ if (of_machine_is_compatible("nokia,n800"))
+ board_caps = NOKIA_N800;
+ else if (of_machine_is_compatible("nokia,n810"))
+ board_caps = NOKIA_N810;
+ else if (of_machine_is_compatible("nokia,n810-wimax"))
+ board_caps = NOKIA_N810_WIMAX;
+ }
+
+ if (!board_caps)
+ pr_err("Unknown board\n");
+}
+
+#if defined(CONFIG_USB_MUSB_TUSB6010) || defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
+/*
+ * 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 = {
+ .mode = MUSB_OTG,
+ .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,
+};
+
+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_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 slot1_cover_open;
+static int slot2_cover_open;
+static struct device *mmc_device;
+
+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 (board_is_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 (board_is_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;
+
+#ifdef CONFIG_MMC_OMAP
+ omap_mmc_notify_cover_event(mmc_device, index, *openp);
+#else
+ pr_warn("MMC: notify cover event not available\n");
+#endif
+}
+
+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 (board_is_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 (board_is_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 (board_is_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 (board_is_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 = 0,
+ .switch_slot = n8x0_mmc_switch_slot,
+ .init = n8x0_mmc_late_init,
+ .cleanup = n8x0_mmc_cleanup,
+ .shutdown = n8x0_mmc_shutdown,
+ .max_freq = 24000000,
+ .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 (board_is_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 (board_is_n810()) {
+ err = gpio_request_array(n810_emmc_gpios,
+ ARRAY_SIZE(n810_emmc_gpios));
+ if (err) {
+ gpio_free(N8X0_SLOT_SWITCH_GPIO);
+ return;
+ }
+ }
+
+ mmc1_data.nr_slots = 2;
+ mmc_data[0] = &mmc1_data;
+}
+#else
+static struct omap_mmc_platform_data mmc1_data;
+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) {
+ pr_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) {
+ pr_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
+
+struct menelaus_platform_data n8x0_menelaus_platform_data __initdata = {
+ .late_init = n8x0_menelaus_late_init,
+};
+
+struct aic3x_pdata n810_aic33_data __initdata = {
+ .gpio_reset = 118,
+};
+
+static int __init n8x0_late_initcall(void)
+{
+ if (!board_caps)
+ return -ENODEV;
+
+ n8x0_mmc_init();
+ n8x0_usb_init();
+
+ return 0;
+}
+omap_late_initcall(n8x0_late_initcall);
+
+/*
+ * Legacy init pdata init for n8x0. Note that we want to follow the
+ * I2C bus numbering starting at 0 for device tree like other omaps.
+ */
+void * __init n8x0_legacy_init(void)
+{
+ board_check_revision();
+ spi_register_board_info(n800_spi_board_info,
+ ARRAY_SIZE(n800_spi_board_info));
+ return &mmc1_data;
+}
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
new file mode 100644
index 000000000..81de1c68b
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -0,0 +1,595 @@
+/*
+ * 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/pwm.h>
+#include <linux/leds_pwm.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/pm_opp.h>
+#include <linux/cpu.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/mmc/host.h>
+#include <linux/usb/phy.h>
+
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <video/omapdss.h>
+#include <video/omap-panel-data.h>
+#include <linux/platform_data/mtd-nand-omap2.h>
+
+#include "common.h"
+#include "omap_device.h"
+#include "gpmc.h"
+#include "soc.h"
+#include "mux.h"
+#include "hsmmc.h"
+#include "pm.h"
+#include "board-flash.h"
+#include "common-board-devices.h"
+
+#define NAND_CS 0
+
+static struct pwm_lookup pwm_lookup[] = {
+ /* LEDB -> PMU_STAT */
+ PWM_LOOKUP("twl-pwmled", 1, "leds_pwm", "beagleboard::pmu_stat",
+ 7812500, PWM_POLARITY_NORMAL),
+};
+
+static struct led_pwm pwm_leds[] = {
+ {
+ .name = "beagleboard::pmu_stat",
+ .max_brightness = 127,
+ .pwm_period_ns = 7812500,
+ },
+};
+
+static struct led_pwm_platform_data pwm_data = {
+ .num_leds = ARRAY_SIZE(pwm_leds),
+ .leds = pwm_leds,
+};
+
+static struct platform_device leds_pwm = {
+ .name = "leds_pwm",
+ .id = -1,
+ .dev = {
+ .platform_data = &pwm_data,
+ },
+};
+
+/*
+ * 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
+ * XMA/XMB = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMC = GPIO173, GPIO172, GPIO171: 0 1 0
+ */
+enum {
+ OMAP3BEAGLE_BOARD_UNKN = 0,
+ OMAP3BEAGLE_BOARD_AXBX,
+ OMAP3BEAGLE_BOARD_C1_3,
+ OMAP3BEAGLE_BOARD_C4,
+ OMAP3BEAGLE_BOARD_XM,
+ OMAP3BEAGLE_BOARD_XMC,
+};
+
+static u8 omap3_beagle_version;
+
+/*
+ * Board-specific configuration
+ * Defaults to BeagleBoard-xMC
+ */
+static struct {
+ int mmc1_gpio_wp;
+ bool usb_pwr_level; /* 0 - Active Low, 1 - Active High */
+ int dvi_pd_gpio;
+ int usr_button_gpio;
+ int mmc_caps;
+} beagle_config = {
+ .mmc1_gpio_wp = -EINVAL,
+ .usb_pwr_level = 0,
+ .dvi_pd_gpio = -EINVAL,
+ .usr_button_gpio = 4,
+ .mmc_caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+};
+
+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;
+ beagle_config.mmc1_gpio_wp = 29;
+ beagle_config.dvi_pd_gpio = 170;
+ beagle_config.usr_button_gpio = 7;
+ break;
+ case 6:
+ printk(KERN_INFO "OMAP3 Beagle Rev: C1/C2/C3\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_C1_3;
+ beagle_config.mmc1_gpio_wp = 23;
+ beagle_config.dvi_pd_gpio = 170;
+ beagle_config.usr_button_gpio = 7;
+ break;
+ case 5:
+ printk(KERN_INFO "OMAP3 Beagle Rev: C4\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_C4;
+ beagle_config.mmc1_gpio_wp = 23;
+ beagle_config.dvi_pd_gpio = 170;
+ beagle_config.usr_button_gpio = 7;
+ break;
+ case 0:
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM Ax/Bx\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
+ beagle_config.usb_pwr_level = 1;
+ beagle_config.mmc_caps &= ~MMC_CAP_8_BIT_DATA;
+ break;
+ case 2:
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
+ beagle_config.mmc_caps &= ~MMC_CAP_8_BIT_DATA;
+ 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 struct connector_dvi_platform_data beagle_dvi_connector_pdata = {
+ .name = "dvi",
+ .source = "tfp410.0",
+ .i2c_bus_num = 3,
+};
+
+static struct platform_device beagle_dvi_connector_device = {
+ .name = "connector-dvi",
+ .id = 0,
+ .dev.platform_data = &beagle_dvi_connector_pdata,
+};
+
+static struct encoder_tfp410_platform_data beagle_tfp410_pdata = {
+ .name = "tfp410.0",
+ .source = "dpi.0",
+ .data_lines = 24,
+ .power_down_gpio = -1,
+};
+
+static struct platform_device beagle_tfp410_device = {
+ .name = "tfp410",
+ .id = 0,
+ .dev.platform_data = &beagle_tfp410_pdata,
+};
+
+static struct connector_atv_platform_data beagle_tv_pdata = {
+ .name = "tv",
+ .source = "venc.0",
+ .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO,
+ .invert_polarity = false,
+};
+
+static struct platform_device beagle_tv_connector_device = {
+ .name = "connector-analog-tv",
+ .id = 0,
+ .dev.platform_data = &beagle_tv_pdata,
+};
+
+static struct omap_dss_board_info beagle_dss_data = {
+ .default_display_name = "dvi",
+};
+
+#include "sdram-micron-mt46h32m32lf-6.h"
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_wp = -EINVAL,
+ .deferred = true,
+ },
+ {} /* Terminator */
+};
+
+static struct regulator_consumer_supply beagle_vmmc1_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply beagle_vsim_supply[] = {
+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
+};
+
+static struct gpio_led gpio_leds[];
+
+static struct usbhs_phy_data phy_data[] = {
+ {
+ .port = 2,
+ .reset_gpio = 147,
+ .vcc_gpio = -1, /* updated in beagle_twl_gpio_setup */
+ .vcc_polarity = 1, /* updated in beagle_twl_gpio_setup */
+ },
+};
+
+static int beagle_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ int r;
+
+ mmc[0].gpio_wp = beagle_config.mmc1_gpio_wp;
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ mmc[0].gpio_cd = gpio + 0;
+ omap_hsmmc_late_init(mmc);
+
+ /*
+ * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active
+ * high / others active low)
+ * DVI reset GPIO is different between beagle revisions
+ */
+ /* Valid for all -xM revisions */
+ if (cpu_is_omap3630()) {
+ /*
+ * 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__);
+
+ beagle_config.dvi_pd_gpio = gpio + 2;
+
+ } else {
+ /*
+ * 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__);
+ }
+ beagle_tfp410_pdata.power_down_gpio = beagle_config.dvi_pd_gpio;
+
+ platform_device_register(&beagle_tfp410_device);
+ platform_device_register(&beagle_dvi_connector_device);
+ platform_device_register(&beagle_tv_connector_device);
+
+ /* TWL4030_GPIO_MAX i.e. LED_GPO controls HS USB Port 2 power */
+ phy_data[0].vcc_gpio = gpio + TWL4030_GPIO_MAX;
+ phy_data[0].vcc_polarity = beagle_config.usb_pwr_level;
+
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data beagle_gpio_data = {
+ .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 = ARRAY_SIZE(beagle_vmmc1_supply),
+ .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 = ARRAY_SIZE(beagle_vsim_supply),
+ .consumer_supplies = beagle_vsim_supply,
+};
+
+static struct twl4030_platform_data beagle_twldata = {
+ /* platform_data for children goes here */
+ .gpio = &beagle_gpio_data,
+ .vmmc1 = &beagle_vmmc1,
+ .vsim = &beagle_vsim,
+};
+
+static struct i2c_board_info __initdata beagle_i2c_eeprom[] = {
+ {
+ I2C_BOARD_INFO("eeprom", 0x50),
+ },
+};
+
+static int __init omap3_beagle_i2c_init(void)
+{
+ omap3_pmic_get_config(&beagle_twldata,
+ TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC |
+ TWL_COMMON_PDATA_AUDIO,
+ TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
+
+ beagle_twldata.vpll2->constraints.name = "VDVI";
+
+ 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,
+ },
+};
+
+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,
+ /* Dynamically assigned depending on board */
+ .gpio = -EINVAL,
+ .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 platform_device madc_hwmon = {
+ .name = "twl4030_madc_hwmon",
+ .id = -1,
+};
+
+static struct platform_device *omap3_beagle_devices[] __initdata = {
+ &leds_gpio,
+ &keys_gpio,
+ &madc_hwmon,
+ &leds_pwm,
+};
+
+static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static int __init beagle_opp_init(void)
+{
+ int r = 0;
+
+ if (!machine_is_omap3_beagle())
+ return 0;
+
+ /* Initialize the omap3 opp table if not already created. */
+ r = omap3_opp_init();
+ if (r < 0 && (r != -EEXIST)) {
+ pr_err("%s: opp default init failed\n", __func__);
+ return r;
+ }
+
+ /* Custom OPP enabled for all xM versions */
+ if (cpu_is_omap3630()) {
+ struct device *mpu_dev, *iva_dev;
+
+ mpu_dev = get_cpu_device(0);
+ iva_dev = omap_device_get_by_hwmod_name("iva");
+
+ if (!mpu_dev || IS_ERR(iva_dev)) {
+ pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n",
+ __func__, mpu_dev, iva_dev);
+ return -ENODEV;
+ }
+ /* Enable MPU 1GHz and lower opps */
+ r = dev_pm_opp_enable(mpu_dev, 800000000);
+ /* TODO: MPU 1GHz needs SR and ABB */
+
+ /* Enable IVA 800MHz and lower opps */
+ r |= dev_pm_opp_enable(iva_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_pm_opp_disable(mpu_dev, 800000000);
+ dev_pm_opp_disable(iva_dev, 660000000);
+ }
+ }
+ return 0;
+}
+omap_device_initcall(beagle_opp_init);
+
+static void __init omap3_beagle_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap3_beagle_init_rev();
+
+ if (gpio_is_valid(beagle_config.mmc1_gpio_wp))
+ omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT);
+ mmc[0].caps = beagle_config.mmc_caps;
+ omap_hsmmc_init(mmc);
+
+ omap3_beagle_i2c_init();
+
+ gpio_buttons[0].gpio = beagle_config.usr_button_gpio;
+
+ platform_add_devices(omap3_beagle_devices,
+ ARRAY_SIZE(omap3_beagle_devices));
+ if (gpio_is_valid(beagle_config.dvi_pd_gpio))
+ omap_mux_init_gpio(beagle_config.dvi_pd_gpio, OMAP_PIN_OUTPUT);
+ omap_display_init(&beagle_dss_data);
+
+ omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+
+ usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
+ usb_musb_init(NULL);
+
+ usbhs_init(&usbhs_bdata);
+
+ board_nand_init(omap3beagle_nand_partitions,
+ ARRAY_SIZE(omap3beagle_nand_partitions), NAND_CS,
+ NAND_BUSWIDTH_16, NULL);
+ omap_twl4030_audio_init("omap3beagle", NULL);
+
+ /* 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);
+
+ pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
+}
+
+MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
+ /* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3_init_early,
+ .init_irq = omap3_init_irq,
+ .init_machine = omap3_beagle_init,
+ .init_late = omap3_init_late,
+ .init_time = omap3_secure_sync32k_timer_init,
+ .restart = omap3xxx_restart,
+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 000000000..6049f60a8
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -0,0 +1,249 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3logic.c
+ *
+ * Copyright (C) 2010 Li-Pro.Net
+ * Stephan Linz <linz@li-pro.net>
+ *
+ * Copyright (C) 2010-2012 Logic Product Development, Inc.
+ * Peter Barada <peter.barada@logicpd.com>
+ * Ashwin BIhari <ashwin.bihari@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/fixed.h>
+#include <linux/regulator/machine.h>
+
+#include <linux/i2c/twl.h>
+#include <linux/mmc/host.h>
+#include <linux/usb/phy.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+#include "mux.h"
+#include "hsmmc.h"
+#include "control.h"
+#include "common-board-devices.h"
+#include "gpmc.h"
+#include "gpmc-smsc911x.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[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+/* 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 = ARRAY_SIZE(omap3logic_vmmc1_supply),
+ .consumer_supplies = omap3logic_vmmc1_supply,
+};
+
+static struct twl4030_gpio_platform_data omap3logic_gpio_data = {
+ .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_usb_data omap3logic_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+
+static struct twl4030_platform_data omap3logic_twldata = {
+ /* platform_data for children goes here */
+ .gpio = &omap3logic_gpio_data,
+ .vmmc1 = &omap3logic_vmmc1,
+ .usb = &omap3logic_usb_data,
+};
+
+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;
+ }
+
+ omap_hsmmc_init(board_mmc_info);
+}
+
+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);
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ /* 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),
+
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x.0"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x.0"),
+};
+
+static void __init omap3logic_init(void)
+{
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap3torpedo_fix_pbias_voltage();
+ omap3logic_i2c_init();
+ omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
+ board_mmc_init();
+ board_smsc911x_init();
+
+ usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
+ usb_musb_init(NULL);
+
+ /* 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")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .init_machine = omap3logic_init,
+ .init_late = omap35xx_init_late,
+ .init_time = omap3_sync32k_timer_init,
+ .restart = omap3xxx_restart,
+MACHINE_END
+
+MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .init_machine = omap3logic_init,
+ .init_late = omap35xx_init_late,
+ .init_time = omap3_sync32k_timer_init,
+ .restart = omap3xxx_restart,
+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 000000000..969e1003d
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -0,0 +1,633 @@
+/*
+ * 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/omap-gpmc.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 <linux/usb/phy.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+#include <video/omapdss.h>
+#include <video/omap-panel-data.h>
+#include <linux/platform_data/mtd-nand-omap2.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,
+ },
+};
+
+static struct platform_device pandora_backlight = {
+ .name = "pandora-backlight",
+ .id = -1,
+};
+
+#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 connector_atv_platform_data pandora_tv_pdata = {
+ .name = "tv",
+ .source = "venc.0",
+ .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO,
+ .invert_polarity = false,
+};
+
+static struct platform_device pandora_tv_connector_device = {
+ .name = "connector-analog-tv",
+ .id = 0,
+ .dev.platform_data = &pandora_tv_pdata,
+};
+
+static struct omap_dss_board_info pandora_dss_data = {
+ .default_display_name = "lcd",
+};
+
+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.
+ */
+ if (card->type == MMC_TYPE_SDIO || card->type == MMC_TYPE_SD_COMBO) {
+ 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,
+ .deferred = true,
+ },
+ {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = 127,
+ .ext_clock = 1,
+ .transceiver = true,
+ .deferred = 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;
+ omap_hsmmc_late_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 = {
+ .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_vdds_supplies[] = {
+ REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dpi.0"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
+};
+
+static struct regulator_consumer_supply pandora_vcc_lcd_supply[] = {
+ REGULATOR_SUPPLY("vcc", "spi1.1"),
+};
+
+static struct regulator_consumer_supply pandora_usb_phy_supply[] = {
+ REGULATOR_SUPPLY("vcc", "usb_phy_gen_xceiv.2"), /* hsusb port 2 */
+};
+
+/* 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 = ARRAY_SIZE(pandora_vmmc1_supply),
+ .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 = ARRAY_SIZE(pandora_vmmc2_supply),
+ .consumer_supplies = pandora_vmmc2_supply,
+};
+
+/* 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 = ARRAY_SIZE(pandora_vcc_lcd_supply),
+ .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 = ARRAY_SIZE(pandora_usb_phy_supply),
+ .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 = ARRAY_SIZE(pandora_adac_supply),
+ .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 = ARRAY_SIZE(pandora_vmmc3_supply),
+ .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_bci_platform_data pandora_bci_data;
+
+static struct twl4030_power_data pandora_power_data = {
+ .use_poweroff = true,
+};
+
+static struct twl4030_platform_data omap3pandora_twldata = {
+ .gpio = &omap3pandora_gpio_data,
+ .vmmc1 = &pandora_vmmc1,
+ .vmmc2 = &pandora_vmmc2,
+ .vaux1 = &pandora_vaux1,
+ .vaux2 = &pandora_vaux2,
+ .vaux4 = &pandora_vaux4,
+ .vsim = &pandora_vsim,
+ .keypad = &pandora_kp_data,
+ .bci = &pandora_bci_data,
+ .power = &pandora_power_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_get_config(&omap3pandora_twldata,
+ TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO,
+ TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
+
+ omap3pandora_twldata.vdac->constraints.apply_uV = true;
+
+ omap3pandora_twldata.vpll2->constraints.apply_uV = true;
+ omap3pandora_twldata.vpll2->num_consumer_supplies =
+ ARRAY_SIZE(pandora_vdds_supplies);
+ omap3pandora_twldata.vpll2->consumer_supplies = pandora_vdds_supplies;
+
+ 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 panel_tpo_td043mtea1_platform_data pandora_lcd_pdata = {
+ .name = "lcd",
+ .source = "dpi.0",
+
+ .data_lines = 24,
+ .nreset_gpio = 157,
+};
+
+static struct spi_board_info omap3pandora_spi_board_info[] __initdata = {
+ {
+ .modalias = "panel-tpo-td043mtea1",
+ .bus_num = 1,
+ .chip_select = 1,
+ .max_speed_hz = 375000,
+ .platform_data = &pandora_lcd_pdata,
+ }
+};
+
+static void __init pandora_wl1251_init(void)
+{
+ struct wl1251_platform_data pandora_wl1251_pdata;
+ int ret;
+
+ memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
+
+ pandora_wl1251_pdata.power_gpio = -1;
+
+ 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 = wl1251_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 usbhs_phy_data phy_data[] __initdata = {
+ {
+ .port = 2,
+ .reset_gpio = 16,
+ .vcc_gpio = -EINVAL,
+ },
+};
+
+static struct platform_device *omap3pandora_devices[] __initdata = {
+ &pandora_leds_gpio,
+ &pandora_keys_gpio,
+ &pandora_vwlan_device,
+ &pandora_backlight,
+ &pandora_tv_connector_device,
+};
+
+static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+};
+
+#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);
+ omap_hsmmc_init(omap3pandora_mmc);
+ omap3pandora_i2c_init();
+ pandora_wl1251_init();
+ platform_add_devices(omap3pandora_devices,
+ ARRAY_SIZE(omap3pandora_devices));
+ omap_display_init(&pandora_dss_data);
+ omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+ 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_phys(phy_data, ARRAY_SIZE(phy_data));
+ usbhs_init(&usbhs_bdata);
+
+ usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
+ usb_musb_init(NULL);
+ gpmc_nand_init(&pandora_nand_data, NULL);
+
+ /* 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")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .init_machine = omap3pandora_init,
+ .init_late = omap35xx_init_late,
+ .init_time = omap3_sync32k_timer_init,
+ .restart = omap3xxx_restart,
+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 000000000..2dae6ccd3
--- /dev/null
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -0,0 +1,571 @@
+/*
+ * 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 <linux/usb/phy.h>
+
+#include <linux/platform_data/mtd-nand-omap2.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <video/omapdss.h>
+#include <video/omap-panel-data.h>
+
+#include "common.h"
+#include "mux.h"
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "gpmc.h"
+#include "hsmmc.h"
+#include "board-flash.h"
+#include "common-board-devices.h"
+
+#define NAND_CS 0
+
+#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_SMSC911X_NRESET 64
+#define OVERO_SMSC911X2_CS 4
+#define OVERO_SMSC911X2_GPIO 65
+
+/* whether to register LCD35 instead of LCD43 */
+static bool overo_use_lcd35;
+
+#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 = ARRAY_SIZE(ads7846_supply),
+ .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 "gpmc-smsc911x.h"
+
+static struct omap_smsc911x_platform_data smsc911x_cfg = {
+ .id = 0,
+ .cs = OVERO_SMSC911X_CS,
+ .gpio_irq = OVERO_SMSC911X_GPIO,
+ .gpio_reset = OVERO_SMSC911X_NRESET,
+ .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 */
+#define OVERO_GPIO_LCD_EN 144
+#define OVERO_GPIO_LCD_BL 145
+
+static struct connector_atv_platform_data overo_tv_pdata = {
+ .name = "tv",
+ .source = "venc.0",
+ .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO,
+ .invert_polarity = false,
+};
+
+static struct platform_device overo_tv_connector_device = {
+ .name = "connector-analog-tv",
+ .id = 0,
+ .dev.platform_data = &overo_tv_pdata,
+};
+
+static const struct display_timing overo_lcd43_videomode = {
+ .pixelclock = { 0, 9200000, 0 },
+
+ .hactive = { 0, 480, 0 },
+ .hfront_porch = { 0, 8, 0 },
+ .hback_porch = { 0, 4, 0 },
+ .hsync_len = { 0, 41, 0 },
+
+ .vactive = { 0, 272, 0 },
+ .vfront_porch = { 0, 4, 0 },
+ .vback_porch = { 0, 2, 0 },
+ .vsync_len = { 0, 10, 0 },
+
+ .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
+ DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE,
+};
+
+static struct panel_dpi_platform_data overo_lcd43_pdata = {
+ .name = "lcd43",
+ .source = "dpi.0",
+
+ .data_lines = 24,
+
+ .display_timing = &overo_lcd43_videomode,
+
+ .enable_gpio = OVERO_GPIO_LCD_EN,
+ .backlight_gpio = OVERO_GPIO_LCD_BL,
+};
+
+static struct platform_device overo_lcd43_device = {
+ .name = "panel-dpi",
+ .id = 0,
+ .dev.platform_data = &overo_lcd43_pdata,
+};
+
+static struct connector_dvi_platform_data overo_dvi_connector_pdata = {
+ .name = "dvi",
+ .source = "tfp410.0",
+ .i2c_bus_num = 3,
+};
+
+static struct platform_device overo_dvi_connector_device = {
+ .name = "connector-dvi",
+ .id = 0,
+ .dev.platform_data = &overo_dvi_connector_pdata,
+};
+
+static struct encoder_tfp410_platform_data overo_tfp410_pdata = {
+ .name = "tfp410.0",
+ .source = "dpi.0",
+ .data_lines = 24,
+ .power_down_gpio = -1,
+};
+
+static struct platform_device overo_tfp410_device = {
+ .name = "tfp410",
+ .id = 0,
+ .dev.platform_data = &overo_tfp410_pdata,
+};
+
+static struct omap_dss_board_info overo_dss_data = {
+ .default_display_name = "lcd43",
+};
+
+static void __init overo_display_init(void)
+{
+ omap_display_init(&overo_dss_data);
+
+ if (!overo_use_lcd35)
+ platform_device_register(&overo_lcd43_device);
+ platform_device_register(&overo_tfp410_device);
+ platform_device_register(&overo_dvi_connector_device);
+ platform_device_register(&overo_tv_connector_device);
+}
+
+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[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+#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)
+{
+#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 = {
+ .use_leds = true,
+ .setup = overo_twl_gpio_setup,
+};
+
+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 = ARRAY_SIZE(overo_vmmc1_supply),
+ .consumer_supplies = overo_vmmc1_supply,
+};
+
+static struct twl4030_platform_data overo_twldata = {
+ .gpio = &overo_gpio_data,
+ .vmmc1 = &overo_vmmc1,
+};
+
+static int __init overo_i2c_init(void)
+{
+ omap3_pmic_get_config(&overo_twldata,
+ TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO,
+ TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
+
+ overo_twldata.vpll2->constraints.name = "VDVI";
+
+ omap3_pmic_init("tps65950", &overo_twldata);
+ /* i2c2 pins are used for gpio */
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+static struct panel_lb035q02_platform_data overo_lcd35_pdata = {
+ .name = "lcd35",
+ .source = "dpi.0",
+
+ .data_lines = 24,
+
+ .enable_gpio = OVERO_GPIO_LCD_EN,
+ .backlight_gpio = OVERO_GPIO_LCD_BL,
+};
+
+/*
+ * NOTE: We need to add either the lgphilips panel, or the lcd43 panel. The
+ * selection is done based on the overo_use_lcd35 field. If new SPI
+ * devices are added here, extra work is needed to make only the lgphilips panel
+ * affected by the overo_use_lcd35 field.
+ */
+static struct spi_board_info overo_spi_board_info[] __initdata = {
+ {
+ .modalias = "panel_lgphilips_lb035q02",
+ .bus_num = 1,
+ .chip_select = 1,
+ .max_speed_hz = 500000,
+ .mode = SPI_MODE_3,
+ .platform_data = &overo_lcd35_pdata,
+ },
+};
+
+static int __init overo_spi_init(void)
+{
+ overo_ads7846_init();
+
+ if (overo_use_lcd35) {
+ spi_register_board_info(overo_spi_board_info,
+ ARRAY_SIZE(overo_spi_board_info));
+ }
+ return 0;
+}
+
+static struct usbhs_phy_data phy_data[] __initdata = {
+ {
+ .port = 2,
+ .reset_gpio = OVERO_GPIO_USBH_NRESET,
+ .vcc_gpio = -EINVAL,
+ },
+};
+
+static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+};
+
+#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 struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x.0"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x.0"),
+ REGULATOR_SUPPLY("vddvario", "smsc911x.1"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x.1"),
+};
+
+static void __init overo_init(void)
+{
+ int ret;
+
+ if (strstr(boot_command_line, "omapdss.def_disp=lcd35"))
+ overo_use_lcd35 = true;
+
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ overo_i2c_init();
+ omap_hsmmc_init(mmc);
+ omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+ board_nand_init(overo_nand_partitions,
+ ARRAY_SIZE(overo_nand_partitions), NAND_CS, 0, NULL);
+ usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
+ usb_musb_init(NULL);
+
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
+ usbhs_init(&usbhs_bdata);
+ overo_spi_init();
+ overo_init_smsc911x();
+ overo_init_led();
+ overo_init_keys();
+ omap_twl4030_audio_init("overo", NULL);
+
+ overo_display_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);
+
+ 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 {
+ pr_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
+ pr_err("could not obtain gpio for OVERO_GPIO_USBH_CPEN\n");
+}
+
+MACHINE_START(OVERO, "Gumstix Overo")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
+ .init_machine = overo_init,
+ .init_late = omap35xx_init_late,
+ .init_time = omap3_sync32k_timer_init,
+ .restart = omap3xxx_restart,
+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 000000000..14edcd7a2
--- /dev/null
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -0,0 +1,1286 @@
+/*
+ * 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/spi/tsc2005.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/gpio/machine.h>
+#include <linux/omap-gpmc.h>
+#include <linux/mmc/host.h>
+#include <linux/power/isp1704_charger.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+#include <linux/platform_data/mtd-onenand-omap2.h>
+
+#include <asm/system_info.h>
+
+#include "common.h"
+#include <linux/omap-dma.h>
+
+#include "board-rx51.h"
+
+#include <sound/tlv320aic3x.h>
+#include <sound/tpa6130a2-plat.h>
+#include <media/si4713.h>
+#include <linux/platform_data/leds-lp55xx.h>
+
+#include <linux/platform_data/tsl2563.h>
+#include <linux/lis3lv02d.h>
+
+#include <video/omap-panel-data.h>
+
+#if defined(CONFIG_IR_RX51) || defined(CONFIG_IR_RX51_MODULE)
+#include <media/ir-rx51.h>
+#endif
+
+#include "mux.h"
+#include "omap-pm.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+#include "soc.h"
+#include "omap-secure.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_LP5523_CHIP_EN_GPIO 41
+
+#define RX51_USB_TRANSCEIVER_RST_GPIO 67
+
+#define RX51_TSC2005_RESET_GPIO 104
+#define RX51_TSC2005_IRQ_GPIO 100
+
+#define LIS302_IRQ1_GPIO 181
+#define LIS302_IRQ2_GPIO 180 /* Not yet in use */
+
+/* List all SPI devices here. Note that the list/probe order seems to matter! */
+enum {
+ RX51_SPI_WL1251,
+ RX51_SPI_TSC2005, /* Touch Controller */
+ RX51_SPI_MIPID, /* LCD panel */
+};
+
+static struct wl1251_platform_data wl1251_pdata;
+static struct tsc2005_platform_data tsc2005_pdata;
+
+#if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE)
+static int lis302_setup(void)
+{
+ int err;
+ int irq1 = LIS302_IRQ1_GPIO;
+ int irq2 = LIS302_IRQ2_GPIO;
+
+ /* gpio for interrupt pin 1 */
+ err = gpio_request(irq1, "lis3lv02dl_irq1");
+ if (err) {
+ printk(KERN_ERR "lis3lv02dl: gpio request failed\n");
+ goto out;
+ }
+
+ /* gpio for interrupt pin 2 */
+ err = gpio_request(irq2, "lis3lv02dl_irq2");
+ if (err) {
+ gpio_free(irq1);
+ printk(KERN_ERR "lis3lv02dl: gpio request failed\n");
+ goto out;
+ }
+
+ gpio_direction_input(irq1);
+ gpio_direction_input(irq2);
+
+out:
+ return err;
+}
+
+static int lis302_release(void)
+{
+ gpio_free(LIS302_IRQ1_GPIO);
+ gpio_free(LIS302_IRQ2_GPIO);
+
+ return 0;
+}
+
+static struct lis3lv02d_platform_data rx51_lis3lv02d_data = {
+ .click_flags = LIS3_CLICK_SINGLE_X | LIS3_CLICK_SINGLE_Y |
+ LIS3_CLICK_SINGLE_Z,
+ /* Limits are 0.5g * value */
+ .click_thresh_x = 8,
+ .click_thresh_y = 8,
+ .click_thresh_z = 10,
+ /* Click must be longer than time limit */
+ .click_time_limit = 9,
+ /* Kind of debounce filter */
+ .click_latency = 50,
+
+ /* Limits for all axis. millig-value / 18 to get HW values */
+ .wakeup_flags = LIS3_WAKEUP_X_HI | LIS3_WAKEUP_Y_HI,
+ .wakeup_thresh = 800 / 18,
+ .wakeup_flags2 = LIS3_WAKEUP_Z_HI ,
+ .wakeup_thresh2 = 900 / 18,
+
+ .hipass_ctrl = LIS3_HIPASS1_DISABLE | LIS3_HIPASS2_DISABLE,
+
+ /* Interrupt line 2 for click detection, line 1 for thresholds */
+ .irq_cfg = LIS3_IRQ2_CLICK | LIS3_IRQ1_FF_WU_12,
+
+ .axis_x = LIS3_DEV_X,
+ .axis_y = LIS3_INV_DEV_Y,
+ .axis_z = LIS3_INV_DEV_Z,
+ .setup_resources = lis302_setup,
+ .release_resources = lis302_release,
+ .st_min_limits = {-32, 3, 3},
+ .st_max_limits = {-3, 32, 32},
+};
+#endif
+
+#if defined(CONFIG_SENSORS_TSL2563) || defined(CONFIG_SENSORS_TSL2563_MODULE)
+static struct tsl2563_platform_data rx51_tsl2563_platform_data = {
+ .cover_comp_gain = 16,
+};
+#endif
+
+#if defined(CONFIG_LEDS_LP5523) || defined(CONFIG_LEDS_LP5523_MODULE)
+static struct lp55xx_led_config rx51_lp5523_led_config[] = {
+ {
+ .name = "lp5523:kb1",
+ .chan_nr = 0,
+ .led_current = 50,
+ .max_current = 100,
+ }, {
+ .name = "lp5523:kb2",
+ .chan_nr = 1,
+ .led_current = 50,
+ .max_current = 100,
+ }, {
+ .name = "lp5523:kb3",
+ .chan_nr = 2,
+ .led_current = 50,
+ .max_current = 100,
+ }, {
+ .name = "lp5523:kb4",
+ .chan_nr = 3,
+ .led_current = 50,
+ .max_current = 100,
+ }, {
+ .name = "lp5523:b",
+ .chan_nr = 4,
+ .led_current = 50,
+ .max_current = 100,
+ }, {
+ .name = "lp5523:g",
+ .chan_nr = 5,
+ .led_current = 50,
+ .max_current = 100,
+ }, {
+ .name = "lp5523:r",
+ .chan_nr = 6,
+ .led_current = 50,
+ .max_current = 100,
+ }, {
+ .name = "lp5523:kb5",
+ .chan_nr = 7,
+ .led_current = 50,
+ .max_current = 100,
+ }, {
+ .name = "lp5523:kb6",
+ .chan_nr = 8,
+ .led_current = 50,
+ .max_current = 100,
+ }
+};
+
+static struct lp55xx_platform_data rx51_lp5523_platform_data = {
+ .led_config = rx51_lp5523_led_config,
+ .num_channels = ARRAY_SIZE(rx51_lp5523_led_config),
+ .clock_mode = LP55XX_CLOCK_AUTO,
+ .enable_gpio = RX51_LP5523_CHIP_EN_GPIO,
+};
+#endif
+
+#define RX51_LCD_RESET_GPIO 90
+
+static struct panel_acx565akm_platform_data acx_pdata = {
+ .name = "lcd",
+ .source = "sdi.0",
+ .reset_gpio = RX51_LCD_RESET_GPIO,
+ .datapairs = 2,
+};
+
+static struct omap2_mcspi_device_config wl1251_mcspi_config = {
+ .turbo_mode = 0,
+};
+
+static struct omap2_mcspi_device_config mipid_mcspi_config = {
+ .turbo_mode = 0,
+};
+
+static struct omap2_mcspi_device_config tsc2005_mcspi_config = {
+ .turbo_mode = 0,
+};
+
+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,
+ .platform_data = &acx_pdata,
+ },
+ [RX51_SPI_TSC2005] = {
+ .modalias = "tsc2005",
+ .bus_num = 1,
+ .chip_select = 0,
+ .max_speed_hz = 6000000,
+ .controller_data = &tsc2005_mcspi_config,
+ .platform_data = &tsc2005_pdata,
+ },
+};
+
+static struct platform_device rx51_battery_device = {
+ .name = "rx51-battery",
+ .id = -1,
+};
+
+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_battery_device);
+ 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,
+};
+
+/* 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 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,
+ },
+ {
+ .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,
+ .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_vaux2_supply[] = {
+ REGULATOR_SUPPLY("vdds_csib", "omap3isp"),
+};
+
+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"),
+ /* lis3lv02d */
+ REGULATOR_SUPPLY("Vdd_IO", "3-001d"),
+};
+
+static struct regulator_consumer_supply rx51_vaux1_consumers[] = {
+ REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_sdi", "omapdss_sdi.0"),
+ /* Si4713 supply */
+ REGULATOR_SUPPLY("vdd", "2-0063"),
+ /* lis3lv02d */
+ REGULATOR_SUPPLY("Vdd", "3-001d"),
+};
+
+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,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rx51_vaux2_supply),
+ .consumer_supplies = rx51_vaux2_supply,
+};
+
+/* 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 = ARRAY_SIZE(rx51_vaux3_supply),
+ .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 = ARRAY_SIZE(rx51_vmmc1_supply),
+ .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_vpll1 = {
+ .constraints = {
+ .name = "VPLL",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .always_on = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE,
+ },
+};
+
+static struct regulator_init_data rx51_vpll2 = {
+ .constraints = {
+ .name = "VSDI_CSI",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .always_on = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE,
+ },
+};
+
+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 = ARRAY_SIZE(rx51_vsim_supply),
+ .consumer_supplies = rx51_vsim_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 regulator_init_data rx51_vintana1 = {
+ .constraints = {
+ .name = "VINTANA1",
+ .min_uV = 1500000,
+ .max_uV = 1500000,
+ .always_on = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE,
+ },
+};
+
+static struct regulator_init_data rx51_vintana2 = {
+ .constraints = {
+ .name = "VINTANA2",
+ .min_uV = 2750000,
+ .max_uV = 2750000,
+ .apply_uV = true,
+ .always_on = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE,
+ },
+};
+
+static struct regulator_init_data rx51_vintdig = {
+ .constraints = {
+ .name = "VINTDIG",
+ .min_uV = 1500000,
+ .max_uV = 1500000,
+ .always_on = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE,
+ },
+};
+
+static struct gpiod_lookup_table rx51_fmtx_gpios_table = {
+ .dev_id = "2-0063",
+ .table = {
+ GPIO_LOOKUP("gpio.6", 3, "reset", GPIO_ACTIVE_HIGH), /* 163 */
+ { },
+ },
+};
+
+static __init void rx51_gpio_init(void)
+{
+ gpiod_add_lookup_table(&rx51_fmtx_gpios_table);
+}
+
+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 = {
+ .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_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,
+};
+
+static struct twl4030_vibra_data rx51_vibra_data __initdata = {
+ .coexist = 0,
+};
+
+static struct twl4030_audio_data rx51_audio_data __initdata = {
+ .audio_mclk = 26000000,
+ .vibra = &rx51_vibra_data,
+};
+
+static struct twl4030_platform_data rx51_twldata __initdata = {
+ /* platform_data for children goes here */
+ .gpio = &rx51_gpio_data,
+ .keypad = &rx51_kp_data,
+ .power = &rx51_t2scripts_data,
+ .audio = &rx51_audio_data,
+
+ .vaux1 = &rx51_vaux1,
+ .vaux2 = &rx51_vaux2,
+ .vaux4 = &rx51_vaux4,
+ .vmmc1 = &rx51_vmmc1,
+ .vpll1 = &rx51_vpll1,
+ .vpll2 = &rx51_vpll2,
+ .vsim = &rx51_vsim,
+ .vintana1 = &rx51_vintana1,
+ .vintana2 = &rx51_vintana2,
+ .vintdig = &rx51_vintdig,
+ .vio = &rx51_vio,
+};
+
+static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata_or_module = {
+ .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,
+};
+
+#if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713)
+static struct si4713_platform_data rx51_si4713_platform_data = {
+ .is_platform_device = true
+};
+#endif
+
+static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = {
+#if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713)
+ {
+ I2C_BOARD_INFO("si4713", 0x63),
+ .platform_data = &rx51_si4713_platform_data,
+ },
+#endif
+ {
+ 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
+#if defined(CONFIG_LEDS_LP5523) || defined(CONFIG_LEDS_LP5523_MODULE)
+ {
+ I2C_BOARD_INFO("lp5523", 0x32),
+ .platform_data = &rx51_lp5523_platform_data,
+ },
+#endif
+ {
+ I2C_BOARD_INFO("bq27200", 0x55),
+ },
+ {
+ I2C_BOARD_INFO("tpa6130a2", 0x60),
+ .platform_data = &rx51_tpa6130a2_data,
+ }
+};
+
+static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_3[] = {
+#if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE)
+ {
+ I2C_BOARD_INFO("lis3lv02d", 0x1d),
+ .platform_data = &rx51_lis3lv02d_data,
+ },
+#endif
+};
+
+static int __init rx51_i2c_init(void)
+{
+#if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713)
+ int err;
+#endif
+
+ 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;
+ omap3_pmic_get_config(&rx51_twldata,
+ TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC,
+ TWL_COMMON_REGULATOR_VDAC);
+
+ rx51_twldata.vdac->constraints.apply_uV = true;
+ rx51_twldata.vdac->constraints.name = "VDAC";
+
+ omap_pmic_init(1, 2200, "twl5030", 7 + OMAP_INTC_START, &rx51_twldata);
+#if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713)
+ 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 err;
+ }
+ rx51_peripherals_i2c_board_info_2[0].irq = gpio_to_irq(RX51_FMTX_IRQ);
+#endif
+ omap_register_i2c_bus(2, 100, rx51_peripherals_i2c_board_info_2,
+ ARRAY_SIZE(rx51_peripherals_i2c_board_info_2));
+#if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE)
+ rx51_lis3lv02d_data.irq2 = gpio_to_irq(LIS302_IRQ2_GPIO);
+ rx51_peripherals_i2c_board_info_3[0].irq = gpio_to_irq(LIS302_IRQ1_GPIO);
+#endif
+ omap_register_i2c_bus(3, 400, rx51_peripherals_i2c_board_info_3,
+ ARRAY_SIZE(rx51_peripherals_i2c_board_info_3));
+ 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
+
+static struct gpio rx51_wl1251_gpios[] __initdata = {
+ { 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.power_gpio = RX51_WL1251_POWER_GPIO;
+ rx51_peripherals_spi_board_info[RX51_SPI_WL1251].irq = irq;
+
+ return;
+
+err_irq:
+ gpio_free(RX51_WL1251_IRQ_GPIO);
+error:
+ printk(KERN_ERR "wl1251 board initialisation failed\n");
+ wl1251_pdata.power_gpio = -1;
+
+ /*
+ * Now rx51_peripherals_spi_board_info[1].irq is zero and
+ * set_power is null, and wl1251_probe() will fail.
+ */
+}
+
+static struct tsc2005_platform_data tsc2005_pdata = {
+ .ts_pressure_max = 2048,
+ .ts_pressure_fudge = 2,
+ .ts_x_max = 4096,
+ .ts_x_fudge = 4,
+ .ts_y_max = 4096,
+ .ts_y_fudge = 7,
+ .ts_x_plate_ohm = 280,
+ .esd_timeout_ms = 8000,
+};
+
+static struct gpio rx51_tsc2005_gpios[] __initdata = {
+ { RX51_TSC2005_IRQ_GPIO, GPIOF_IN, "tsc2005 IRQ" },
+ { RX51_TSC2005_RESET_GPIO, GPIOF_OUT_INIT_HIGH, "tsc2005 reset" },
+};
+
+static void rx51_tsc2005_set_reset(bool enable)
+{
+ gpio_set_value(RX51_TSC2005_RESET_GPIO, enable);
+}
+
+static void __init rx51_init_tsc2005(void)
+{
+ int r;
+
+ omap_mux_init_gpio(RX51_TSC2005_RESET_GPIO, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(RX51_TSC2005_IRQ_GPIO, OMAP_PIN_INPUT_PULLUP);
+
+ r = gpio_request_array(rx51_tsc2005_gpios,
+ ARRAY_SIZE(rx51_tsc2005_gpios));
+ if (r < 0) {
+ printk(KERN_ERR "tsc2005 board initialization failed\n");
+ tsc2005_pdata.esd_timeout_ms = 0;
+ return;
+ }
+
+ tsc2005_pdata.set_reset = rx51_tsc2005_set_reset;
+ rx51_peripherals_spi_board_info[RX51_SPI_TSC2005].irq =
+ gpio_to_irq(RX51_TSC2005_IRQ_GPIO);
+}
+
+#if defined(CONFIG_IR_RX51) || defined(CONFIG_IR_RX51_MODULE)
+static struct lirc_rx51_platform_data rx51_lirc_data = {
+ .set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat,
+ .pwm_timer = 9, /* Use GPT 9 for CIR */
+};
+
+static struct platform_device rx51_lirc_device = {
+ .name = "lirc_rx51",
+ .id = -1,
+ .dev = {
+ .platform_data = &rx51_lirc_data,
+ },
+};
+
+static void __init rx51_init_lirc(void)
+{
+ platform_device_register(&rx51_lirc_device);
+}
+#else
+static void __init rx51_init_lirc(void)
+{
+}
+#endif
+
+static struct platform_device madc_hwmon = {
+ .name = "twl4030_madc_hwmon",
+ .id = -1,
+};
+
+static void __init rx51_init_twl4030_hwmon(void)
+{
+ platform_device_register(&madc_hwmon);
+}
+
+static struct platform_device omap3_rom_rng_device = {
+ .name = "omap3-rom-rng",
+ .id = -1,
+ .dev = {
+ .platform_data = rx51_secure_rng_call,
+ },
+};
+
+static void __init rx51_init_omap3_rom_rng(void)
+{
+ if (omap_type() == OMAP2_DEVICE_TYPE_SEC) {
+ pr_info("RX-51: Registring OMAP3 HWRNG device\n");
+ platform_device_register(&omap3_rom_rng_device);
+ }
+}
+
+void __init rx51_peripherals_init(void)
+{
+ rx51_gpio_init();
+ rx51_i2c_init();
+ regulator_has_full_constraints();
+ gpmc_onenand_init(board_onenand_data);
+ rx51_add_gpio_keys();
+ rx51_init_wl1251();
+ rx51_init_tsc2005();
+ rx51_init_lirc();
+ spi_register_board_info(rx51_peripherals_spi_board_info,
+ ARRAY_SIZE(rx51_peripherals_spi_board_info));
+
+ partition = omap_mux_get("core");
+ if (partition)
+ omap_hsmmc_init(mmc);
+
+ rx51_charger_init();
+ rx51_init_twl4030_hwmon();
+ rx51_init_omap3_rom_rng();
+}
+
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 000000000..9cfebc5c7
--- /dev/null
+++ b/arch/arm/mach-omap2/board-rx51-video.c
@@ -0,0 +1,67 @@
+/*
+ * 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 <video/omap-panel-data.h>
+
+#include <linux/platform_data/spi-omap2-mcspi.h>
+
+#include "soc.h"
+#include "board-rx51.h"
+
+#include "mux.h"
+
+#define RX51_LCD_RESET_GPIO 90
+
+#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
+
+static struct connector_atv_platform_data rx51_tv_pdata = {
+ .name = "tv",
+ .source = "venc.0",
+ .connector_type = OMAP_DSS_VENC_TYPE_COMPOSITE,
+ .invert_polarity = false,
+};
+
+static struct platform_device rx51_tv_connector_device = {
+ .name = "connector-analog-tv",
+ .id = 0,
+ .dev.platform_data = &rx51_tv_pdata,
+};
+
+static struct omap_dss_board_info rx51_dss_board_info = {
+ .default_display_name = "lcd",
+};
+
+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;
+ }
+
+ omap_display_init(&rx51_dss_board_info);
+
+ platform_device_register(&rx51_tv_connector_device);
+
+ return 0;
+}
+
+omap_subsys_initcall(rx51_video_init);
+#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 000000000..2d1e5a6be
--- /dev/null
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -0,0 +1,141 @@
+/*
+ * Board support file for Nokia N900 (aka RX-51).
+ *
+ * Copyright (C) 2007, 2008 Nokia
+ * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg>
+ * Copyright (C) 2013 Pali RohĂ¡r <pali.rohar@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/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 <linux/usb/phy.h>
+#include <linux/usb/musb.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/omap-dma.h>
+
+#include "common.h"
+#include "mux.h"
+#include "gpmc.h"
+#include "pm.h"
+#include "soc.h"
+#include "sdram-nokia.h"
+#include "omap-secure.h"
+
+#define RX51_GPIO_SLEEP_IND 162
+
+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 for rx51.
+ *
+ * The 'exit_latency' field is the sum of sleep
+ * and wake-up latencies.
+
+ ---------------------------------------------
+ | state | exit_latency | target_residency |
+ ---------------------------------------------
+ | C1 | 110 + 162 | 5 |
+ | C2 | 106 + 180 | 309 |
+ | C3 | 107 + 410 | 46057 |
+ | C4 | 121 + 3374 | 46057 |
+ | C5 | 855 + 1146 | 46057 |
+ | C6 | 7580 + 4134 | 484329 |
+ | C7 | 7505 + 15274 | 484329 |
+ ---------------------------------------------
+
+*/
+
+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_OTG,
+ .power = 0,
+};
+
+static void __init rx51_init(void)
+{
+ struct omap_sdrc_params *sdrc_params;
+
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap_serial_init();
+
+ sdrc_params = nokia_get_sdram_timings();
+ omap_sdrc_init(sdrc_params, sdrc_params);
+
+ usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
+ usb_musb_init(&musb_board_data);
+ rx51_peripherals_init();
+
+ if (omap_type() == OMAP2_DEVICE_TYPE_SEC) {
+#ifdef CONFIG_ARM_ERRATA_430973
+ pr_info("RX-51: Enabling ARM errata 430973 workaround\n");
+ /* set IBE to 1 */
+ rx51_secure_update_aux_cr(BIT(6), 0);
+#endif
+ }
+
+ /* 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_reserve(void)
+{
+ omap_reserve();
+}
+
+MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
+ /* Maintainer: Lauri Leukkunen <lauri.leukkunen@nokia.com> */
+ .atag_offset = 0x100,
+ .reserve = rx51_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3430_init_early,
+ .init_irq = omap3_init_irq,
+ .init_machine = rx51_init,
+ .init_late = omap3430_init_late,
+ .init_time = omap3_sync32k_timer_init,
+ .restart = omap3xxx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-rx51.h b/arch/arm/mach-omap2/board-rx51.h
new file mode 100644
index 000000000..b76f49e7e
--- /dev/null
+++ b/arch/arm/mach-omap2/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/clkt2xxx_dpll.c b/arch/arm/mach-omap2/clkt2xxx_dpll.c
new file mode 100644
index 000000000..82572e277
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_dpll.c
@@ -0,0 +1,59 @@
+/*
+ * 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 "clock.h"
+#include "cm2xxx.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_hw_omap *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_hw_omap *clk)
+{
+ if (!clk || !clk->dpll_data)
+ return;
+
+ omap2xxx_cm_set_dpll_disable_autoidle();
+}
+
+
+/* Public data */
+const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll = {
+ .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 000000000..59cf310bc
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
@@ -0,0 +1,195 @@
+/*
+ * 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 "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "cm2xxx.h"
+#include "cm-regbits-24xx.h"
+#include "sdrc.h"
+#include "sram.h"
+
+/* #define DOWN_VARIABLE_DPLL 1 */ /* Experimental */
+
+/*
+ * dpll_core_ck: pointer to the combined dpll_ck + core_ck on OMAP2xxx
+ * (currently defined as "dpll_ck" in the OMAP2xxx clock tree). Set
+ * during dpll_ck init and used later by omap2xxx_clk_get_core_rate().
+ */
+static struct clk_hw_omap *dpll_core_ck;
+
+/**
+ * omap2xxx_clk_get_core_rate - return the CORE_CLK rate
+ *
+ * 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(void)
+{
+ long long core_clk;
+ u32 v;
+
+ WARN_ON(!dpll_core_ck);
+
+ core_clk = omap2_get_dpll_rate(dpll_core_ck);
+
+ v = omap2xxx_cm_get_core_clk_src();
+
+ 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 = omap2xxx_cm_get_core_clk_src();
+
+ 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_hw *hw,
+ unsigned long parent_rate)
+{
+ return omap2xxx_clk_get_core_rate();
+}
+
+int omap2_reprogram_dpllcore(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ 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();
+ mult = omap2xxx_cm_get_core_clk_src();
+
+ 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 = readl_relaxed(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 = omap2xxx_cm_get_core_pll_config();
+ 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;
+}
+
+/**
+ * omap2xxx_clkt_dpllcore_init - clk init function for dpll_ck
+ * @clk: struct clk *dpll_ck
+ *
+ * Store a local copy of @clk in dpll_core_ck so other code can query
+ * the core rate without having to clk_get(), which can sleep. Must
+ * only be called once. No return value. XXX If the clock
+ * registration process is ever changed such that dpll_ck is no longer
+ * statically defined, this code may need to change to increment some
+ * kind of use count on dpll_ck.
+ */
+void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw)
+{
+ WARN(dpll_core_ck, "dpll_core_ck already set - should never happen");
+ dpll_core_ck = to_clk_hw_omap(hw);
+}
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 000000000..85e0b0c06
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
@@ -0,0 +1,263 @@
+/*
+ * OMAP2xxx DVFS virtual clock functions
+ *
+ * Copyright (C) 2005-2008, 2012 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 "soc.h"
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "cm2xxx.h"
+#include "cm-regbits-24xx.h"
+#include "sdrc.h"
+#include "sram.h"
+
+const struct prcm_config *curr_prcm_set;
+const struct prcm_config *rate_table;
+
+/*
+ * sys_ck_rate: the rate of the external high-frequency clock
+ * oscillator on the board. Set by the SoC-specific clock init code.
+ * Once set during a boot, will not change.
+ */
+static unsigned long sys_ck_rate;
+
+/**
+ * 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_hw *clk,
+ unsigned long parent_rate)
+{
+ 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_hw *hw, unsigned long rate,
+ unsigned long *parent_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 != sys_ck_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_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ u32 cur_rate, done_rate, bypass = 0;
+ 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 != sys_ck_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();
+
+ 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;
+
+ omap2xxx_cm_set_mod_dividers(prcm->cm_clksel_mpu,
+ prcm->cm_clksel_dsp,
+ prcm->cm_clksel_gfx,
+ prcm->cm_clksel1_core,
+ prcm->cm_clksel_mdm);
+
+ /* 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;
+}
+
+/**
+ * omap2xxx_clkt_vps_check_bootloader_rate - determine which of the rate
+ * table sets matches the current CORE DPLL hardware rate
+ *
+ * Check the MPU rate set by bootloader. Sets the 'curr_prcm_set'
+ * global to point to the active rate set when found; otherwise, sets
+ * it to NULL. No return value;
+ */
+void omap2xxx_clkt_vps_check_bootloader_rates(void)
+{
+ const struct prcm_config *prcm = NULL;
+ unsigned long rate;
+
+ rate = omap2xxx_clk_get_core_rate();
+ 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 <= rate)
+ break;
+ }
+ curr_prcm_set = prcm;
+}
+
+/**
+ * omap2xxx_clkt_vps_late_init - store a copy of the sys_ck rate
+ *
+ * Store a copy of the sys_ck rate for later use by the OMAP2xxx DVFS
+ * code. (The sys_ck rate does not -- or rather, must not -- change
+ * during kernel runtime.) Must be called after we have a valid
+ * sys_ck rate, but before the virt_prcm_set clock rate is
+ * recalculated. No return value.
+ */
+void omap2xxx_clkt_vps_late_init(void)
+{
+ struct clk *c;
+
+ c = clk_get(NULL, "sys_ck");
+ if (IS_ERR(c)) {
+ WARN(1, "could not locate sys_ck\n");
+ } else {
+ sys_ck_rate = clk_get_rate(c);
+ clk_put(c);
+ }
+}
+
+#ifdef CONFIG_OF
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+
+static const struct clk_ops virt_prcm_set_ops = {
+ .recalc_rate = &omap2_table_mpu_recalc,
+ .set_rate = &omap2_select_table_rate,
+ .round_rate = &omap2_round_to_table_rate,
+};
+
+/**
+ * omap2xxx_clkt_vps_init - initialize virt_prcm_set clock
+ *
+ * Does a manual init for the virtual prcm DVFS clock for OMAP2. This
+ * function is called only from omap2 DT clock init, as the virtual
+ * node is not modelled in the DT clock data.
+ */
+void omap2xxx_clkt_vps_init(void)
+{
+ struct clk_init_data init = { NULL };
+ struct clk_hw_omap *hw = NULL;
+ struct clk *clk;
+ const char *parent_name = "mpu_ck";
+ struct clk_lookup *lookup = NULL;
+
+ omap2xxx_clkt_vps_late_init();
+ omap2xxx_clkt_vps_check_bootloader_rates();
+
+ hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+ lookup = kzalloc(sizeof(*lookup), GFP_KERNEL);
+ if (!hw || !lookup)
+ goto cleanup;
+ init.name = "virt_prcm_set";
+ init.ops = &virt_prcm_set_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ hw->hw.init = &init;
+
+ clk = clk_register(NULL, &hw->hw);
+
+ lookup->dev_id = NULL;
+ lookup->con_id = "cpufreq_ck";
+ lookup->clk = clk;
+
+ clkdev_add(lookup);
+ return;
+cleanup:
+ kfree(hw);
+ kfree(lookup);
+}
+#endif
diff --git a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
new file mode 100644
index 000000000..eb69acf21
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
@@ -0,0 +1,119 @@
+/*
+ * 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 "clock.h"
+#include "clock3xxx.h"
+#include "clock34xx.h"
+#include "sdrc.h"
+#include "sram.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_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ 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;
+ unsigned long clkrate;
+
+ if (!clk || !rate)
+ return -EINVAL;
+
+ validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
+ if (validrate != rate)
+ return -EINVAL;
+
+ sdrcrate = __clk_get_rate(sdrc_ick_p);
+ clkrate = __clk_get_rate(hw->clk);
+ if (rate > clkrate)
+ sdrcrate <<= ((rate / clkrate) >> 1);
+ else
+ sdrcrate >>= ((clkrate / 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 = __clk_get_rate(arm_fck_p) / 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",
+ clkrate, 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 > clkrate,
+ 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 > clkrate,
+ sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
+ sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
+ 0, 0, 0, 0);
+ 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 000000000..7ee26108a
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt_clksel.c
@@ -0,0 +1,466 @@
+/*
+ * 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-provider.h>
+#include <linux/io.h>
+#include <linux/bug.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_hw_omap *clk,
+ struct clk *src_clk)
+{
+ const struct clksel *clks;
+
+ if (!src_clk)
+ return NULL;
+
+ 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: %s: could not find parent clock %s in clksel array\n",
+ __clk_get_name(clk->hw.clk), __clk_get_name(src_clk));
+ return NULL;
+ }
+
+ return clks;
+}
+
+/**
+ * _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_hw_omap *clk, u32 field_val)
+{
+ u32 v;
+
+ v = omap2_clk_readl(clk, clk->clksel_reg);
+ v &= ~clk->clksel_mask;
+ v |= field_val << __ffs(clk->clksel_mask);
+ omap2_clk_writel(v, clk, clk->clksel_reg);
+
+ v = omap2_clk_readl(clk, 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_hw_omap *clk, u32 field_val)
+{
+ const struct clksel *clks;
+ const struct clksel_rate *clkr;
+ struct clk *parent;
+
+ parent = __clk_get_parent(clk->hw.clk);
+
+ clks = _get_clksel_by_parent(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: %s: could not find fieldval %d for parent %s\n",
+ __clk_get_name(clk->hw.clk), field_val,
+ __clk_get_name(parent));
+ 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_hw_omap *clk, u32 div)
+{
+ const struct clksel *clks;
+ const struct clksel_rate *clkr;
+ struct clk *parent;
+
+ /* should never happen */
+ WARN_ON(div == 0);
+
+ parent = __clk_get_parent(clk->hw.clk);
+ clks = _get_clksel_by_parent(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: %s: could not find divisor %d for parent %s\n",
+ __clk_get_name(clk->hw.clk), div,
+ __clk_get_name(parent));
+ 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_hw_omap *clk)
+{
+ u32 v;
+
+ if (!clk->clksel || !clk->clksel_mask)
+ return 0;
+
+ v = omap2_clk_readl(clk, 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_hw_omap *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;
+ struct clk *parent;
+ unsigned long parent_rate;
+ const char *clk_name;
+
+ parent = __clk_get_parent(clk->hw.clk);
+ clk_name = __clk_get_name(clk->hw.clk);
+ parent_rate = __clk_get_rate(parent);
+
+ 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, 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: %s: clksel_rate table not sorted\n",
+ clk_name);
+
+ last_div = clkr->div;
+
+ test_rate = parent_rate / clkr->div;
+
+ if (test_rate <= target_rate)
+ break; /* found it */
+ }
+
+ if (!clkr->div) {
+ pr_err("clock: %s: could not find divisor for target rate %ld for parent %s\n",
+ clk_name, target_rate, __clk_get_name(parent));
+ return ~0;
+ }
+
+ *new_div = clkr->div;
+
+ pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div,
+ (parent_rate / clkr->div));
+
+ return parent_rate / clkr->div;
+}
+
+/*
+ * Clocktype interface functions to the OMAP clock code
+ * (i.e., those used in struct clk field function pointers, etc.)
+ */
+
+/**
+ * omap2_clksel_find_parent_index() - return the array index of the current
+ * hardware parent of @hw
+ * @hw: struct clk_hw * to find the current hardware parent of
+ *
+ * Given a struct clk_hw pointer @hw to the 'hw' member of a struct
+ * clk_hw_omap record representing a source-selectable hardware clock,
+ * read the hardware register and determine what its parent is
+ * currently set to. Intended to be called only by the common clock
+ * framework struct clk_hw_ops.get_parent function pointer. Return
+ * the array index of this parent clock upon success -- there is no
+ * way to return an error, so if we encounter an error, just WARN()
+ * and pretend that we know that we're doing.
+ */
+u8 omap2_clksel_find_parent_index(struct clk_hw *hw)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ const struct clksel *clks;
+ const struct clksel_rate *clkr;
+ u32 r, found = 0;
+ struct clk *parent;
+ const char *clk_name;
+ int ret = 0, f = 0;
+
+ parent = __clk_get_parent(hw->clk);
+ clk_name = __clk_get_name(hw->clk);
+
+ /* XXX should be able to return an error */
+ WARN((!clk->clksel || !clk->clksel_mask),
+ "clock: %s: attempt to call on a non-clksel clock", clk_name);
+
+ r = omap2_clk_readl(clk, 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) {
+ found = 1;
+ ret = f;
+ }
+ }
+ f++;
+ }
+
+ /* This indicates a data error */
+ WARN(!found, "clock: %s: init parent: could not find regval %0x\n",
+ clk_name, r);
+
+ return ret;
+}
+
+
+/**
+ * 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_hw *hw, unsigned long parent_rate)
+{
+ unsigned long rate;
+ u32 div = 0;
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+
+ if (!parent_rate)
+ return 0;
+
+ div = _read_divisor(clk);
+ if (!div)
+ rate = parent_rate;
+ else
+ rate = parent_rate / div;
+
+ pr_debug("%s: recalc'd %s's rate to %lu (div %d)\n", __func__,
+ __clk_get_name(hw->clk), 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_hw *hw, unsigned long target_rate,
+ unsigned long *parent_rate)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ 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_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ 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);
+
+ pr_debug("clock: %s: set rate to %ld\n", __clk_get_name(hw->clk),
+ __clk_get_rate(hw->clk));
+
+ 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_hw *hw, u8 field_val)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+
+ if (!clk->clksel || !clk->clksel_mask)
+ return -EINVAL;
+
+ _write_clksel_reg(clk, field_val);
+ 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 000000000..f251a14cb
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt_dpll.c
@@ -0,0 +1,370 @@
+/*
+ * 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-provider.h>
+#include <linux/io.h>
+
+#include <asm/div64.h>
+
+#include "clock.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 range for OMAP36xx and OMAP4xxx.
+ * From device data manual section 4.3 "DPLL and DLL Specifications".
+ */
+#define OMAP3PLUS_DPLL_FINT_JTYPE_MIN 500000
+#define OMAP3PLUS_DPLL_FINT_JTYPE_MAX 2500000
+
+/* _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_hw_omap *clk, unsigned int n)
+{
+ struct dpll_data *dd;
+ long fint, fint_min, fint_max;
+ int ret = 0;
+
+ dd = clk->dpll_data;
+
+ /* DPLL divider must result in a valid jitter correction val */
+ fint = __clk_get_rate(__clk_get_parent(clk->hw.clk)) / n;
+
+ if (dd->flags & DPLL_J_TYPE) {
+ fint_min = OMAP3PLUS_DPLL_FINT_JTYPE_MIN;
+ fint_max = OMAP3PLUS_DPLL_FINT_JTYPE_MAX;
+ } else {
+ fint_min = ti_clk_features.fint_min;
+ fint_max = ti_clk_features.fint_max;
+ }
+
+ if (!fint_min || !fint_max) {
+ WARN(1, "No fint limits available!\n");
+ return DPLL_FINT_INVALID;
+ }
+
+ if (fint < ti_clk_features.fint_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 > ti_clk_features.fint_max) {
+ pr_debug("rejecting n=%d due to Fint failure, boosting min_divider\n",
+ n);
+ dd->min_divider = n;
+ ret = DPLL_FINT_INVALID;
+ } else if (fint > ti_clk_features.fint_band1_max &&
+ fint < ti_clk_features.fint_band2_min) {
+ pr_debug("rejecting n=%d due to Fint failure\n", 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;
+}
+
+/**
+ * _omap2_dpll_is_in_bypass - check if DPLL is in bypass mode or not
+ * @v: bitfield value of the DPLL enable
+ *
+ * Checks given DPLL enable bitfield to see whether the DPLL is in bypass
+ * mode or not. Returns 1 if the DPLL is in bypass, 0 otherwise.
+ */
+static int _omap2_dpll_is_in_bypass(u32 v)
+{
+ u8 mask, val;
+
+ mask = ti_clk_features.dpll_bypass_vals;
+
+ /*
+ * Each set bit in the mask corresponds to a bypass value equal
+ * to the bitshift. Go through each set-bit in the mask and
+ * compare against the given register value.
+ */
+ while (mask) {
+ val = __ffs(mask);
+ mask ^= (1 << val);
+ if (v == val)
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Public functions */
+u8 omap2_init_dpll_parent(struct clk_hw *hw)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ u32 v;
+ struct dpll_data *dd;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return -EINVAL;
+
+ v = omap2_clk_readl(clk, dd->control_reg);
+ v &= dd->enable_mask;
+ v >>= __ffs(dd->enable_mask);
+
+ /* Reparent the struct clk in case the dpll is in bypass */
+ if (_omap2_dpll_is_in_bypass(v))
+ return 1;
+
+ return 0;
+}
+
+/**
+ * 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.
+ */
+unsigned long omap2_get_dpll_rate(struct clk_hw_omap *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 = omap2_clk_readl(clk, dd->control_reg);
+ v &= dd->enable_mask;
+ v >>= __ffs(dd->enable_mask);
+
+ if (_omap2_dpll_is_in_bypass(v))
+ return __clk_get_rate(dd->clk_bypass);
+
+ v = omap2_clk_readl(clk, 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) __clk_get_rate(dd->clk_ref) * 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_hw *hw, unsigned long target_rate,
+ unsigned long *parent_rate)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ int m, n, r, scaled_max_m;
+ int min_delta_m = INT_MAX, min_delta_n = INT_MAX;
+ unsigned long scaled_rt_rp;
+ unsigned long new_rate = 0;
+ struct dpll_data *dd;
+ unsigned long ref_rate;
+ long delta;
+ long prev_min_delta = LONG_MAX;
+ const char *clk_name;
+
+ if (!clk || !clk->dpll_data)
+ return ~0;
+
+ dd = clk->dpll_data;
+
+ ref_rate = __clk_get_rate(dd->clk_ref);
+ clk_name = __clk_get_name(hw->clk);
+ pr_debug("clock: %s: starting DPLL round_rate, target rate %lu\n",
+ clk_name, target_rate);
+
+ scaled_rt_rp = target_rate / (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,
+ ref_rate);
+
+ /* m can't be set low enough for this n - try with a larger n */
+ if (r == DPLL_MULT_UNDERFLOW)
+ continue;
+
+ /* skip rates above our target rate */
+ delta = target_rate - new_rate;
+ if (delta < 0)
+ continue;
+
+ if (delta < prev_min_delta) {
+ prev_min_delta = delta;
+ min_delta_m = m;
+ min_delta_n = n;
+ }
+
+ pr_debug("clock: %s: m = %d: n = %d: new_rate = %lu\n",
+ clk_name, m, n, new_rate);
+
+ if (delta == 0)
+ break;
+ }
+
+ if (prev_min_delta == LONG_MAX) {
+ pr_debug("clock: %s: cannot round to rate %lu\n",
+ clk_name, target_rate);
+ return ~0;
+ }
+
+ dd->last_rounded_m = min_delta_m;
+ dd->last_rounded_n = min_delta_n;
+ dd->last_rounded_rate = target_rate - prev_min_delta;
+
+ return dd->last_rounded_rate;
+}
+
diff --git a/arch/arm/mach-omap2/clkt_iclk.c b/arch/arm/mach-omap2/clkt_iclk.c
new file mode 100644
index 000000000..55eb579ae
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt_iclk.c
@@ -0,0 +1,68 @@
+/*
+ * 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-provider.h>
+#include <linux/io.h>
+
+#include "clock.h"
+
+/* Register offsets */
+#define CM_AUTOIDLE 0x30
+#define CM_ICLKEN 0x10
+
+/* Private functions */
+
+/* XXX */
+void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk)
+{
+ u32 v;
+ void __iomem *r;
+
+ r = (__force void __iomem *)
+ ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN));
+
+ v = omap2_clk_readl(clk, r);
+ v |= (1 << clk->enable_bit);
+ omap2_clk_writel(v, clk, r);
+}
+
+/* XXX */
+void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk)
+{
+ u32 v;
+ void __iomem *r;
+
+ r = (__force void __iomem *)
+ ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN));
+
+ v = omap2_clk_readl(clk, r);
+ v &= ~(1 << clk->enable_bit);
+ omap2_clk_writel(v, clk, r);
+}
+
+/* Public data */
+
+const struct clk_hw_omap_ops clkhwops_iclk = {
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+};
+
+const struct clk_hw_omap_ops clkhwops_iclk_wait = {
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+ .find_idlest = omap2_clk_dflt_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+};
+
+
+
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
new file mode 100644
index 000000000..a699d7169
--- /dev/null
+++ b/arch/arm/mach-omap2/clock.c
@@ -0,0 +1,849 @@
+/*
+ * 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/export.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/regmap.h>
+#include <linux/of_address.h>
+#include <linux/bootmem.h>
+#include <asm/cpu.h>
+
+#include <trace/events/power.h>
+
+#include "soc.h"
+#include "clockdomain.h"
+#include "clock.h"
+#include "cm.h"
+#include "cm2xxx.h"
+#include "cm3xxx.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+#include "common.h"
+
+/*
+ * MAX_MODULE_ENABLE_WAIT: maximum of number of microseconds to wait
+ * for a module to indicate that it is no longer in idle
+ */
+#define MAX_MODULE_ENABLE_WAIT 100000
+
+u16 cpu_mask;
+
+/*
+ * Clock features setup. Used instead of CPU type checks.
+ */
+struct ti_clk_features ti_clk_features;
+
+/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
+#define OMAP3430_DPLL_FINT_BAND1_MIN 750000
+#define OMAP3430_DPLL_FINT_BAND1_MAX 2100000
+#define OMAP3430_DPLL_FINT_BAND2_MIN 7500000
+#define OMAP3430_DPLL_FINT_BAND2_MAX 21000000
+
+/*
+ * DPLL valid Fint frequency range for OMAP36xx and OMAP4xxx.
+ * From device data manual section 4.3 "DPLL and DLL Specifications".
+ */
+#define OMAP3PLUS_DPLL_FINT_MIN 32000
+#define OMAP3PLUS_DPLL_FINT_MAX 52000000
+
+/*
+ * clkdm_control: if true, then when a clock is enabled in the
+ * hardware, its clockdomain will first be enabled; and when a clock
+ * is disabled in the hardware, its clockdomain will be disabled
+ * afterwards.
+ */
+static bool clkdm_control = true;
+
+static LIST_HEAD(clk_hw_omap_clocks);
+
+struct clk_iomap {
+ struct regmap *regmap;
+ void __iomem *mem;
+};
+
+static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS];
+
+static void clk_memmap_writel(u32 val, void __iomem *reg)
+{
+ struct clk_omap_reg *r = (struct clk_omap_reg *)&reg;
+ struct clk_iomap *io = clk_memmaps[r->index];
+
+ if (io->regmap)
+ regmap_write(io->regmap, r->offset, val);
+ else
+ writel_relaxed(val, io->mem + r->offset);
+}
+
+static u32 clk_memmap_readl(void __iomem *reg)
+{
+ u32 val;
+ struct clk_omap_reg *r = (struct clk_omap_reg *)&reg;
+ struct clk_iomap *io = clk_memmaps[r->index];
+
+ if (io->regmap)
+ regmap_read(io->regmap, r->offset, &val);
+ else
+ val = readl_relaxed(io->mem + r->offset);
+
+ return val;
+}
+
+void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg)
+{
+ if (WARN_ON_ONCE(!(clk->flags & MEMMAP_ADDRESSING)))
+ writel_relaxed(val, reg);
+ else
+ clk_memmap_writel(val, reg);
+}
+
+u32 omap2_clk_readl(struct clk_hw_omap *clk, void __iomem *reg)
+{
+ if (WARN_ON_ONCE(!(clk->flags & MEMMAP_ADDRESSING)))
+ return readl_relaxed(reg);
+ else
+ return clk_memmap_readl(reg);
+}
+
+static struct ti_clk_ll_ops omap_clk_ll_ops = {
+ .clk_readl = clk_memmap_readl,
+ .clk_writel = clk_memmap_writel,
+};
+
+/**
+ * omap2_clk_provider_init - initialize a clock provider
+ * @match_table: DT device table to match for devices to init
+ * @np: device node pointer for the this clock provider
+ * @index: index for the clock provider
+ + @syscon: syscon regmap pointer
+ * @mem: iomem pointer for the clock provider memory area, only used if
+ * syscon is not provided
+ *
+ * Initializes a clock provider module (CM/PRM etc.), registering
+ * the memory mapping at specified index and initializing the
+ * low level driver infrastructure. Returns 0 in success.
+ */
+int __init omap2_clk_provider_init(struct device_node *np, int index,
+ struct regmap *syscon, void __iomem *mem)
+{
+ struct clk_iomap *io;
+
+ ti_clk_ll_ops = &omap_clk_ll_ops;
+
+ io = kzalloc(sizeof(*io), GFP_KERNEL);
+
+ io->regmap = syscon;
+ io->mem = mem;
+
+ clk_memmaps[index] = io;
+
+ ti_dt_clk_init_provider(np, index);
+
+ return 0;
+}
+
+/**
+ * omap2_clk_legacy_provider_init - initialize a legacy clock provider
+ * @index: index for the clock provider
+ * @mem: iomem pointer for the clock provider memory area
+ *
+ * Initializes a legacy clock provider memory mapping.
+ */
+void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem)
+{
+ struct clk_iomap *io;
+
+ ti_clk_ll_ops = &omap_clk_ll_ops;
+
+ io = memblock_virt_alloc(sizeof(*io), 0);
+
+ io->mem = mem;
+
+ clk_memmaps[index] = io;
+}
+
+/*
+ * OMAP2+ specific clock functions
+ */
+
+/* Private functions */
+
+
+/**
+ * _wait_idlest_generic - wait for a module to leave the idle state
+ * @clk: module clock to wait for (needed for register offsets)
+ * @reg: virtual 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)
+ *
+ * Wait for a module to leave idle, where its idle-status register is
+ * not inside the CM module. Returns 1 if the module left idle
+ * promptly, or 0 if the module did not leave idle before the timeout
+ * elapsed. XXX Deprecated - should be moved into drivers for the
+ * individual IP block that the IDLEST register exists in.
+ */
+static int _wait_idlest_generic(struct clk_hw_omap *clk, void __iomem *reg,
+ u32 mask, u8 idlest, const char *name)
+{
+ int i = 0, ena = 0;
+
+ ena = (idlest) ? 0 : mask;
+
+ omap_test_timeout(((omap2_clk_readl(clk, reg) & mask) == ena),
+ MAX_MODULE_ENABLE_WAIT, i);
+
+ if (i < MAX_MODULE_ENABLE_WAIT)
+ pr_debug("omap clock: module associated with clock %s ready after %d loops\n",
+ name, i);
+ else
+ pr_err("omap clock: 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;
+};
+
+/**
+ * _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_hw_omap *clk)
+{
+ void __iomem *companion_reg, *idlest_reg;
+ u8 other_bit, idlest_bit, idlest_val, idlest_reg_id;
+ s16 prcm_mod;
+ int r;
+
+ /* 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 (!(omap2_clk_readl(clk, companion_reg) & (1 << other_bit)))
+ return;
+ }
+
+ clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val);
+ r = cm_split_idlest_reg(idlest_reg, &prcm_mod, &idlest_reg_id);
+ if (r) {
+ /* IDLEST register not in the CM module */
+ _wait_idlest_generic(clk, idlest_reg, (1 << idlest_bit),
+ idlest_val, __clk_get_name(clk->hw.clk));
+ } else {
+ omap_cm_wait_module_ready(0, prcm_mod, idlest_reg_id,
+ idlest_bit);
+ };
+}
+
+/* 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_hw *hw)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ struct clockdomain *clkdm;
+ const char *clk_name;
+
+ if (!clk->clkdm_name)
+ return;
+
+ clk_name = __clk_get_name(hw->clk);
+
+ 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_disable_clkdm_control - disable clkdm control on clk enable/disable
+ *
+ * Prevent the OMAP clock code from calling into the clockdomain code
+ * when a hardware clock in that clockdomain is enabled or disabled.
+ * Intended to be called at init time from omap*_clk_init(). No
+ * return value.
+ */
+void __init omap2_clk_disable_clkdm_control(void)
+{
+ clkdm_control = false;
+}
+
+/**
+ * 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_hw_omap *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_hw_omap *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.
+ */
+ *idlest_val = ti_clk_features.cm_idlest_val;
+}
+
+/**
+ * omap2_dflt_clk_enable - enable a clock in the hardware
+ * @hw: struct clk_hw * of the clock to enable
+ *
+ * Enable the clock @hw in the hardware. We first call into the OMAP
+ * clockdomain code to "enable" the corresponding clockdomain if this
+ * is the first enabled user of the clockdomain. Then program the
+ * hardware to enable the clock. Then wait for the IP block that uses
+ * this clock to leave idle (if applicable). Returns the error value
+ * from clkdm_clk_enable() if it terminated with an error, or -EINVAL
+ * if @hw has a null clock enable_reg, or zero upon success.
+ */
+int omap2_dflt_clk_enable(struct clk_hw *hw)
+{
+ struct clk_hw_omap *clk;
+ u32 v;
+ int ret = 0;
+
+ clk = to_clk_hw_omap(hw);
+
+ if (clkdm_control && clk->clkdm) {
+ ret = clkdm_clk_enable(clk->clkdm, hw->clk);
+ if (ret) {
+ WARN(1, "%s: could not enable %s's clockdomain %s: %d\n",
+ __func__, __clk_get_name(hw->clk),
+ clk->clkdm->name, ret);
+ return ret;
+ }
+ }
+
+ if (unlikely(clk->enable_reg == NULL)) {
+ pr_err("%s: %s missing enable_reg\n", __func__,
+ __clk_get_name(hw->clk));
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /* FIXME should not have INVERT_ENABLE bit here */
+ v = omap2_clk_readl(clk, clk->enable_reg);
+ if (clk->flags & INVERT_ENABLE)
+ v &= ~(1 << clk->enable_bit);
+ else
+ v |= (1 << clk->enable_bit);
+ omap2_clk_writel(v, clk, clk->enable_reg);
+ v = omap2_clk_readl(clk, clk->enable_reg); /* OCP barrier */
+
+ if (clk->ops && clk->ops->find_idlest)
+ _omap2_module_wait_ready(clk);
+
+ return 0;
+
+err:
+ if (clkdm_control && clk->clkdm)
+ clkdm_clk_disable(clk->clkdm, hw->clk);
+ return ret;
+}
+
+/**
+ * omap2_dflt_clk_disable - disable a clock in the hardware
+ * @hw: struct clk_hw * of the clock to disable
+ *
+ * Disable the clock @hw in the hardware, and call into the OMAP
+ * clockdomain code to "disable" the corresponding clockdomain if all
+ * clocks/hwmods in that clockdomain are now disabled. No return
+ * value.
+ */
+void omap2_dflt_clk_disable(struct clk_hw *hw)
+{
+ struct clk_hw_omap *clk;
+ u32 v;
+
+ clk = to_clk_hw_omap(hw);
+ if (!clk->enable_reg) {
+ /*
+ * 'independent' here refers to a clock which is not
+ * controlled by its parent.
+ */
+ pr_err("%s: independent clock %s has no enable_reg\n",
+ __func__, __clk_get_name(hw->clk));
+ return;
+ }
+
+ v = omap2_clk_readl(clk, clk->enable_reg);
+ if (clk->flags & INVERT_ENABLE)
+ v |= (1 << clk->enable_bit);
+ else
+ v &= ~(1 << clk->enable_bit);
+ omap2_clk_writel(v, clk, clk->enable_reg);
+ /* No OCP barrier needed here since it is a disable operation */
+
+ if (clkdm_control && clk->clkdm)
+ clkdm_clk_disable(clk->clkdm, hw->clk);
+}
+
+/**
+ * omap2_clkops_enable_clkdm - increment usecount on clkdm of @hw
+ * @hw: struct clk_hw * of the clock being enabled
+ *
+ * Increment the usecount of the clockdomain of the clock pointed to
+ * by @hw; if the usecount is 1, the clockdomain will be "enabled."
+ * Only needed for clocks that don't use omap2_dflt_clk_enable() as
+ * their enable function pointer. Passes along the return value of
+ * clkdm_clk_enable(), -EINVAL if @hw is not associated with a
+ * clockdomain, or 0 if clock framework-based clockdomain control is
+ * not implemented.
+ */
+int omap2_clkops_enable_clkdm(struct clk_hw *hw)
+{
+ struct clk_hw_omap *clk;
+ int ret = 0;
+
+ clk = to_clk_hw_omap(hw);
+
+ if (unlikely(!clk->clkdm)) {
+ pr_err("%s: %s: no clkdm set ?!\n", __func__,
+ __clk_get_name(hw->clk));
+ return -EINVAL;
+ }
+
+ if (unlikely(clk->enable_reg))
+ pr_err("%s: %s: should use dflt_clk_enable ?!\n", __func__,
+ __clk_get_name(hw->clk));
+
+ if (!clkdm_control) {
+ pr_err("%s: %s: clkfw-based clockdomain control disabled ?!\n",
+ __func__, __clk_get_name(hw->clk));
+ return 0;
+ }
+
+ ret = clkdm_clk_enable(clk->clkdm, hw->clk);
+ WARN(ret, "%s: could not enable %s's clockdomain %s: %d\n",
+ __func__, __clk_get_name(hw->clk), clk->clkdm->name, ret);
+
+ return ret;
+}
+
+/**
+ * omap2_clkops_disable_clkdm - decrement usecount on clkdm of @hw
+ * @hw: struct clk_hw * of the clock being disabled
+ *
+ * Decrement the usecount of the clockdomain of the clock pointed to
+ * by @hw; if the usecount is 0, the clockdomain will be "disabled."
+ * Only needed for clocks that don't use omap2_dflt_clk_disable() as their
+ * disable function pointer. No return value.
+ */
+void omap2_clkops_disable_clkdm(struct clk_hw *hw)
+{
+ struct clk_hw_omap *clk;
+
+ clk = to_clk_hw_omap(hw);
+
+ if (unlikely(!clk->clkdm)) {
+ pr_err("%s: %s: no clkdm set ?!\n", __func__,
+ __clk_get_name(hw->clk));
+ return;
+ }
+
+ if (unlikely(clk->enable_reg))
+ pr_err("%s: %s: should use dflt_clk_disable ?!\n", __func__,
+ __clk_get_name(hw->clk));
+
+ if (!clkdm_control) {
+ pr_err("%s: %s: clkfw-based clockdomain control disabled ?!\n",
+ __func__, __clk_get_name(hw->clk));
+ return;
+ }
+
+ clkdm_clk_disable(clk->clkdm, hw->clk);
+}
+
+/**
+ * omap2_dflt_clk_is_enabled - is clock enabled in the hardware?
+ * @hw: struct clk_hw * to check
+ *
+ * Return 1 if the clock represented by @hw is enabled in the
+ * hardware, or 0 otherwise. Intended for use in the struct
+ * clk_ops.is_enabled function pointer.
+ */
+int omap2_dflt_clk_is_enabled(struct clk_hw *hw)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ u32 v;
+
+ v = omap2_clk_readl(clk, clk->enable_reg);
+
+ if (clk->flags & INVERT_ENABLE)
+ v ^= BIT(clk->enable_bit);
+
+ v &= BIT(clk->enable_bit);
+
+ return v ? 1 : 0;
+}
+
+static 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);
+
+/**
+ * omap2_init_clk_hw_omap_clocks - initialize an OMAP clock
+ * @clk: struct clk * to initialize
+ *
+ * Add an OMAP clock @clk to the internal list of OMAP clocks. Used
+ * temporarily for autoidle handling, until this support can be
+ * integrated into the common clock framework code in some way. No
+ * return value.
+ */
+void omap2_init_clk_hw_omap_clocks(struct clk *clk)
+{
+ struct clk_hw_omap *c;
+
+ if (__clk_get_flags(clk) & CLK_IS_BASIC)
+ return;
+
+ c = to_clk_hw_omap(__clk_get_hw(clk));
+ list_add(&c->node, &clk_hw_omap_clocks);
+}
+
+/**
+ * omap2_clk_enable_autoidle_all - enable autoidle on all OMAP clocks that
+ * support it
+ *
+ * Enable clock autoidle on all OMAP clocks that have allow_idle
+ * function pointers associated with them. This function is intended
+ * to be temporary until support for this is added to the common clock
+ * code. Returns 0.
+ */
+int omap2_clk_enable_autoidle_all(void)
+{
+ struct clk_hw_omap *c;
+
+ list_for_each_entry(c, &clk_hw_omap_clocks, node)
+ if (c->ops && c->ops->allow_idle)
+ c->ops->allow_idle(c);
+
+ of_ti_clk_allow_autoidle_all();
+
+ return 0;
+}
+
+/**
+ * omap2_clk_disable_autoidle_all - disable autoidle on all OMAP clocks that
+ * support it
+ *
+ * Disable clock autoidle on all OMAP clocks that have allow_idle
+ * function pointers associated with them. This function is intended
+ * to be temporary until support for this is added to the common clock
+ * code. Returns 0.
+ */
+int omap2_clk_disable_autoidle_all(void)
+{
+ struct clk_hw_omap *c;
+
+ list_for_each_entry(c, &clk_hw_omap_clocks, node)
+ if (c->ops && c->ops->deny_idle)
+ c->ops->deny_idle(c);
+
+ of_ti_clk_deny_autoidle_all();
+
+ return 0;
+}
+
+/**
+ * omap2_clk_deny_idle - disable autoidle on an OMAP clock
+ * @clk: struct clk * to disable autoidle for
+ *
+ * Disable autoidle on an OMAP clock.
+ */
+int omap2_clk_deny_idle(struct clk *clk)
+{
+ struct clk_hw_omap *c;
+
+ if (__clk_get_flags(clk) & CLK_IS_BASIC)
+ return -EINVAL;
+
+ c = to_clk_hw_omap(__clk_get_hw(clk));
+ if (c->ops && c->ops->deny_idle)
+ c->ops->deny_idle(c);
+ return 0;
+}
+
+/**
+ * omap2_clk_allow_idle - enable autoidle on an OMAP clock
+ * @clk: struct clk * to enable autoidle for
+ *
+ * Enable autoidle on an OMAP clock.
+ */
+int omap2_clk_allow_idle(struct clk *clk)
+{
+ struct clk_hw_omap *c;
+
+ if (__clk_get_flags(clk) & CLK_IS_BASIC)
+ return -EINVAL;
+
+ c = to_clk_hw_omap(__clk_get_hw(clk));
+ if (c->ops && c->ops->allow_idle)
+ c->ops->allow_idle(c);
+ return 0;
+}
+
+/**
+ * omap2_clk_enable_init_clocks - prepare & enable a list of clocks
+ * @clk_names: ptr to an array of strings of clock names to enable
+ * @num_clocks: number of clock names in @clk_names
+ *
+ * Prepare and enable a list of clocks, named by @clk_names. No
+ * return value. XXX Deprecated; only needed until these clocks are
+ * properly claimed and enabled by the drivers or core code that uses
+ * them. XXX What code disables & calls clk_put on these clocks?
+ */
+void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks)
+{
+ struct clk *init_clk;
+ int i;
+
+ for (i = 0; i < num_clocks; i++) {
+ init_clk = clk_get(NULL, clk_names[i]);
+ if (WARN(IS_ERR(init_clk), "could not find init clock %s\n",
+ clk_names[i]))
+ continue;
+ clk_prepare_enable(init_clk);
+ }
+}
+
+const struct clk_hw_omap_ops clkhwops_wait = {
+ .find_idlest = omap2_clk_dflt_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+};
+
+/**
+ * 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 (r < 0) {
+ WARN(1, "clock: %s: unable to set MPU rate to %d: %d\n",
+ mpurate_ck_name, mpurate, r);
+ clk_put(mpurate_ck);
+ return -EINVAL;
+ }
+
+ calibrate_delay();
+ 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));
+}
+
+/**
+ * ti_clk_init_features - init clock features struct for the SoC
+ *
+ * Initializes the clock features struct based on the SoC type.
+ */
+void __init ti_clk_init_features(void)
+{
+ /* Fint setup for DPLLs */
+ if (cpu_is_omap3430()) {
+ ti_clk_features.fint_min = OMAP3430_DPLL_FINT_BAND1_MIN;
+ ti_clk_features.fint_max = OMAP3430_DPLL_FINT_BAND2_MAX;
+ ti_clk_features.fint_band1_max = OMAP3430_DPLL_FINT_BAND1_MAX;
+ ti_clk_features.fint_band2_min = OMAP3430_DPLL_FINT_BAND2_MIN;
+ } else {
+ ti_clk_features.fint_min = OMAP3PLUS_DPLL_FINT_MIN;
+ ti_clk_features.fint_max = OMAP3PLUS_DPLL_FINT_MAX;
+ }
+
+ /* Bypass value setup for DPLLs */
+ if (cpu_is_omap24xx()) {
+ ti_clk_features.dpll_bypass_vals |=
+ (1 << OMAP2XXX_EN_DPLL_LPBYPASS) |
+ (1 << OMAP2XXX_EN_DPLL_FRBYPASS);
+ } else if (cpu_is_omap34xx()) {
+ ti_clk_features.dpll_bypass_vals |=
+ (1 << OMAP3XXX_EN_DPLL_LPBYPASS) |
+ (1 << OMAP3XXX_EN_DPLL_FRBYPASS);
+ } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx() ||
+ soc_is_omap54xx() || soc_is_dra7xx()) {
+ ti_clk_features.dpll_bypass_vals |=
+ (1 << OMAP4XXX_EN_DPLL_LPBYPASS) |
+ (1 << OMAP4XXX_EN_DPLL_FRBYPASS) |
+ (1 << OMAP4XXX_EN_DPLL_MNBYPASS);
+ }
+
+ /* Jitter correction only available on OMAP343X */
+ if (cpu_is_omap343x())
+ ti_clk_features.flags |= TI_CLK_DPLL_HAS_FREQSEL;
+
+ /* Idlest value for interface clocks.
+ * 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())
+ ti_clk_features.cm_idlest_val = OMAP24XX_CM_IDLEST_VAL;
+ else if (cpu_is_omap34xx())
+ ti_clk_features.cm_idlest_val = OMAP34XX_CM_IDLEST_VAL;
+
+ /* On OMAP3430 ES1.0, DPLL4 can't be re-programmed */
+ if (omap_rev() == OMAP3430_REV_ES1_0)
+ ti_clk_features.flags |= TI_CLK_DPLL4_DENY_REPROGRAM;
+}
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
new file mode 100644
index 000000000..652ed0ab8
--- /dev/null
+++ b/arch/arm/mach-omap2/clock.h
@@ -0,0 +1,284 @@
+/*
+ * 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 <linux/kernel.h>
+#include <linux/list.h>
+
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/ti.h>
+
+struct omap_clk {
+ u16 cpu;
+ struct clk_lookup lk;
+};
+
+#define CLK(dev, con, ck) \
+ { \
+ .lk = { \
+ .dev_id = dev, \
+ .con_id = con, \
+ .clk = ck, \
+ }, \
+ }
+
+struct clockdomain;
+
+#define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name) \
+ static struct clk_core _name##_core = { \
+ .name = #_name, \
+ .hw = &_name##_hw.hw, \
+ .parent_names = _parent_array_name, \
+ .num_parents = ARRAY_SIZE(_parent_array_name), \
+ .ops = &_clkops_name, \
+ }; \
+ static struct clk _name = { \
+ .core = &_name##_core, \
+ };
+
+#define DEFINE_STRUCT_CLK_FLAGS(_name, _parent_array_name, \
+ _clkops_name, _flags) \
+ static struct clk_core _name##_core = { \
+ .name = #_name, \
+ .hw = &_name##_hw.hw, \
+ .parent_names = _parent_array_name, \
+ .num_parents = ARRAY_SIZE(_parent_array_name), \
+ .ops = &_clkops_name, \
+ .flags = _flags, \
+ }; \
+ static struct clk _name = { \
+ .core = &_name##_core, \
+ };
+
+#define DEFINE_STRUCT_CLK_HW_OMAP(_name, _clkdm_name) \
+ static struct clk_hw_omap _name##_hw = { \
+ .hw = { \
+ .clk = &_name, \
+ }, \
+ .clkdm_name = _clkdm_name, \
+ };
+
+#define DEFINE_CLK_OMAP_MUX(_name, _clkdm_name, _clksel, \
+ _clksel_reg, _clksel_mask, \
+ _parent_names, _ops) \
+ static struct clk _name; \
+ static struct clk_hw_omap _name##_hw = { \
+ .hw = { \
+ .clk = &_name, \
+ }, \
+ .clksel = _clksel, \
+ .clksel_reg = _clksel_reg, \
+ .clksel_mask = _clksel_mask, \
+ .clkdm_name = _clkdm_name, \
+ }; \
+ DEFINE_STRUCT_CLK(_name, _parent_names, _ops);
+
+#define DEFINE_CLK_OMAP_MUX_GATE(_name, _clkdm_name, _clksel, \
+ _clksel_reg, _clksel_mask, \
+ _enable_reg, _enable_bit, \
+ _hwops, _parent_names, _ops) \
+ static struct clk _name; \
+ static struct clk_hw_omap _name##_hw = { \
+ .hw = { \
+ .clk = &_name, \
+ }, \
+ .ops = _hwops, \
+ .enable_reg = _enable_reg, \
+ .enable_bit = _enable_bit, \
+ .clksel = _clksel, \
+ .clksel_reg = _clksel_reg, \
+ .clksel_mask = _clksel_mask, \
+ .clkdm_name = _clkdm_name, \
+ }; \
+ DEFINE_STRUCT_CLK(_name, _parent_names, _ops);
+
+/* 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_4460 (1 << 7)
+#define RATE_IN_AM33XX (1 << 8)
+#define RATE_IN_TI814X (1 << 9)
+
+#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)
+#define RATE_IN_44XX (RATE_IN_4430 | RATE_IN_4460)
+
+/* 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.
+ */
+struct clksel_rate {
+ u32 val;
+ u8 div;
+ u16 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;
+};
+
+/* 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
+
+u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk);
+void omap3_dpll_allow_idle(struct clk_hw_omap *clk);
+void omap3_dpll_deny_idle(struct clk_hw_omap *clk);
+void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk);
+void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk);
+
+void __init omap2_clk_disable_clkdm_control(void);
+
+/* clkt_clksel.c public functions */
+u32 omap2_clksel_round_rate_div(struct clk_hw_omap *clk,
+ unsigned long target_rate,
+ u32 *new_div);
+u8 omap2_clksel_find_parent_index(struct clk_hw *hw);
+unsigned long omap2_clksel_recalc(struct clk_hw *hw, unsigned long parent_rate);
+long omap2_clksel_round_rate(struct clk_hw *hw, unsigned long target_rate,
+ unsigned long *parent_rate);
+int omap2_clksel_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate);
+int omap2_clksel_set_parent(struct clk_hw *hw, u8 field_val);
+
+/* clkt_iclk.c public functions */
+extern void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk);
+extern void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk);
+
+unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk);
+
+void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk,
+ void __iomem **other_reg,
+ u8 *other_bit);
+void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk,
+ void __iomem **idlest_reg,
+ u8 *idlest_bit, u8 *idlest_val);
+int omap2_clk_enable_autoidle_all(void);
+int omap2_clk_allow_idle(struct clk *clk);
+int omap2_clk_deny_idle(struct clk *clk);
+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);
+
+u32 omap2_clk_readl(struct clk_hw_omap *clk, void __iomem *reg);
+void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg);
+
+extern u16 cpu_mask;
+
+/*
+ * Clock features setup. Used instead of CPU type checks.
+ */
+struct ti_clk_features {
+ u32 flags;
+ long fint_min;
+ long fint_max;
+ long fint_band1_max;
+ long fint_band2_min;
+ u8 dpll_bypass_vals;
+ u8 cm_idlest_val;
+};
+
+#define TI_CLK_DPLL_HAS_FREQSEL (1 << 0)
+#define TI_CLK_DPLL4_DENY_REPROGRAM (1 << 1)
+
+extern struct ti_clk_features ti_clk_features;
+
+extern const struct clkops clkops_omap2_dflt_wait;
+extern const struct clkops clkops_omap2_dflt;
+
+extern struct clk_functions omap2_clk_functions;
+
+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[];
+
+extern const struct clk_hw_omap_ops clkhwops_iclk_wait;
+extern const struct clk_hw_omap_ops clkhwops_wait;
+extern const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait;
+extern const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait;
+extern const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait;
+extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait;
+extern const struct clk_hw_omap_ops clkhwops_apll54;
+extern const struct clk_hw_omap_ops clkhwops_apll96;
+
+/* clksel_rate blocks shared between OMAP44xx and AM33xx */
+extern const struct clksel_rate div_1_0_rates[];
+extern const struct clksel_rate div3_1to4_rates[];
+extern const struct clksel_rate div_1_1_rates[];
+extern const struct clksel_rate div_1_2_rates[];
+extern const struct clksel_rate div_1_3_rates[];
+extern const struct clksel_rate div_1_4_rates[];
+extern const struct clksel_rate div31_1to31_rates[];
+
+extern int omap2_clkops_enable_clkdm(struct clk_hw *hw);
+extern void omap2_clkops_disable_clkdm(struct clk_hw *hw);
+
+struct regmap;
+
+int __init omap2_clk_provider_init(struct device_node *np, int index,
+ struct regmap *syscon, void __iomem *mem);
+void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem);
+
+void __init ti_clk_init_features(void);
+#endif
diff --git a/arch/arm/mach-omap2/clock2430.c b/arch/arm/mach-omap2/clock2430.c
new file mode 100644
index 000000000..cef0c8d1d
--- /dev/null
+++ b/arch/arm/mach-omap2/clock2430.c
@@ -0,0 +1,57 @@
+/*
+ * 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 "soc.h"
+#include "iomap.h"
+#include "clock.h"
+#include "clock2xxx.h"
+#include "cm2xxx.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_hw_omap *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 clk_hw_omap_ops clkhwops_omap2430_i2chs_wait = {
+ .find_idlest = omap2430_clk_i2chs_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+};
diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c
new file mode 100644
index 000000000..b870f6a9e
--- /dev/null
+++ b/arch/arm/mach-omap2/clock2xxx.c
@@ -0,0 +1,57 @@
+/*
+ * 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 "soc.h"
+#include "clock.h"
+#include "clock2xxx.h"
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+
+struct clk_hw *dclk_hw;
+/*
+ * Omap24xx specific clock functions
+ */
+
+/*
+ * 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;
+}
+
+omap_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 000000000..125c37614
--- /dev/null
+++ b/arch/arm/mach-omap2/clock2xxx.h
@@ -0,0 +1,45 @@
+/*
+ * 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
+
+#include <linux/clk-provider.h>
+#include "clock.h"
+
+unsigned long omap2_table_mpu_recalc(struct clk_hw *clk,
+ unsigned long parent_rate);
+int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate);
+long omap2_round_to_table_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate);
+unsigned long omap2xxx_sys_clk_recalc(struct clk_hw *clk,
+ unsigned long parent_rate);
+unsigned long omap2_osc_clk_recalc(struct clk_hw *clk,
+ unsigned long parent_rate);
+void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw);
+unsigned long omap2xxx_clk_get_core_rate(void);
+u32 omap2xxx_get_sysclkdiv(void);
+void omap2xxx_clk_prepare_for_reboot(void);
+void omap2xxx_clkt_vps_check_bootloader_rates(void);
+void omap2xxx_clkt_vps_late_init(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 struct clk_hw *dclk_hw;
+
+#endif
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
new file mode 100644
index 000000000..4596468e5
--- /dev/null
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -0,0 +1,138 @@
+/*
+ * 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 "clock.h"
+#include "clock34xx.h"
+#include "cm3xxx.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_hw_omap *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 clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait = {
+ .find_idlest = omap3430es2_clk_ssi_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+};
+
+const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait = {
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+ .find_idlest = omap3430es2_clk_ssi_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+};
+
+/**
+ * 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_hw_omap *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 clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait = {
+ .find_idlest = omap3430es2_clk_dss_usbhost_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+};
+
+const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait = {
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+ .find_idlest = omap3430es2_clk_dss_usbhost_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+};
+
+/**
+ * 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_hw_omap *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 clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait = {
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+ .find_idlest = omap3430es2_clk_hsotgusb_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+};
+
+const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait = {
+ .find_idlest = omap3430es2_clk_hsotgusb_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+};
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
new file mode 100644
index 000000000..084ba71b2
--- /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 000000000..4d79ae2c0
--- /dev/null
+++ b/arch/arm/mach-omap2/clock3517.c
@@ -0,0 +1,118 @@
+/*
+ * 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 "clock.h"
+#include "clock3517.h"
+#include "cm3xxx.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_hw_omap *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_hw_omap *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 clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait = {
+ .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_hw_omap *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 clk_hw_omap_ops clkhwops_am35xx_ipss_wait = {
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+ .find_idlest = am35xx_clk_ipss_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+};
diff --git a/arch/arm/mach-omap2/clock3517.h b/arch/arm/mach-omap2/clock3517.h
new file mode 100644
index 000000000..ca5e5a64c
--- /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 000000000..91ccb962e
--- /dev/null
+++ b/arch/arm/mach-omap2/clock36xx.c
@@ -0,0 +1,69 @@
+/*
+ * 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/clk-provider.h>
+#include <linux/io.h>
+
+#include "clock.h"
+#include "clock36xx.h"
+#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
+
+/**
+ * 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.
+ */
+int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk_hw *clk)
+{
+ struct clk_divider *parent;
+ struct clk_hw *parent_hw;
+ u32 dummy_v, orig_v;
+ struct clk_hw_omap *omap_clk = to_clk_hw_omap(clk);
+ int ret;
+
+ /* Clear PWRDN bit of HSDIVIDER */
+ ret = omap2_dflt_clk_enable(clk);
+
+ parent_hw = __clk_get_hw(__clk_get_parent(clk->clk));
+ parent = to_clk_divider(parent_hw);
+
+ /* Restore the dividers */
+ if (!ret) {
+ orig_v = omap2_clk_readl(omap_clk, parent->reg);
+ dummy_v = orig_v;
+
+ /* Write any other value different from the Read value */
+ dummy_v ^= (1 << parent->shift);
+ omap2_clk_writel(dummy_v, omap_clk, parent->reg);
+
+ /* Write the original divider */
+ omap2_clk_writel(orig_v, omap_clk, parent->reg);
+ }
+
+ return ret;
+}
diff --git a/arch/arm/mach-omap2/clock36xx.h b/arch/arm/mach-omap2/clock36xx.h
new file mode 100644
index 000000000..945bb7f08
--- /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 int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk_hw *hw);
+
+#endif
diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c
new file mode 100644
index 000000000..a9e86db5d
--- /dev/null
+++ b/arch/arm/mach-omap2/clock3xxx.c
@@ -0,0 +1,135 @@
+/*
+ * 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 "soc.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;
+
+/**
+ * omap3_dpll4_set_rate - set rate for omap3 per-dpll
+ * @hw: clock to change
+ * @rate: target rate for clock
+ * @parent_rate: rate of the parent clock
+ *
+ * Check if the current SoC supports the per-dpll reprogram operation
+ * or not, and then do the rate change if supported. Returns -EINVAL
+ * if not supported, 0 for success, and potential error codes from the
+ * clock rate change.
+ */
+int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_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 (ti_clk_features.flags & TI_CLK_DPLL4_DENY_REPROGRAM) {
+ pr_err("clock: DPLL4 cannot change rate due to silicon 'Limitation 2.5' on 3430ES1.\n");
+ return -EINVAL;
+ }
+
+ return omap3_noncore_dpll_set_rate(hw, rate, parent_rate);
+}
+
+/**
+ * omap3_dpll4_set_rate_and_parent - set rate and parent for omap3 per-dpll
+ * @hw: clock to change
+ * @rate: target rate for clock
+ * @parent_rate: rate of the parent clock
+ * @index: parent index, 0 - reference clock, 1 - bypass clock
+ *
+ * Check if the current SoC support the per-dpll reprogram operation
+ * or not, and then do the rate + parent change if supported. Returns
+ * -EINVAL if not supported, 0 for success, and potential error codes
+ * from the clock rate change.
+ */
+int omap3_dpll4_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate, u8 index)
+{
+ if (ti_clk_features.flags & TI_CLK_DPLL4_DENY_REPROGRAM) {
+ pr_err("clock: DPLL4 cannot change rate due to silicon 'Limitation 2.5' on 3430ES1.\n");
+ return -EINVAL;
+ }
+
+ return omap3_noncore_dpll_set_rate_and_parent(hw, rate, parent_rate,
+ index);
+}
+
+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_prepare_enable(dpll5_clk);
+
+ /* Program dpll5_m2_clk divider for no division */
+ dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
+ clk_prepare_enable(dpll5_m2_clk);
+ clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
+
+ clk_disable_unprepare(dpll5_m2_clk);
+ clk_disable_unprepare(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;
+}
+
+omap_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 000000000..78d9f562e
--- /dev/null
+++ b/arch/arm/mach-omap2/clock3xxx.h
@@ -0,0 +1,20 @@
+/*
+ * 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_core_dpll_m2_set_rate(struct clk_hw *clk, unsigned long rate,
+ unsigned long parent_rate);
+
+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/clock44xx.h b/arch/arm/mach-omap2/clock44xx.h
new file mode 100644
index 000000000..287a46f78
--- /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
+
+/*
+ * OMAP4430_REGM4XEN_MULT: If the CM_CLKMODE_DPLL_ABE.DPLL_REGM4XEN bit is
+ * set, then the DPLL's lock frequency is multiplied by 4 (OMAP4430 TRM
+ * vV Section 3.6.3.3.1 "DPLLs Output Clocks Parameters")
+ */
+#define OMAP4430_REGM4XEN_MULT 4
+
+int omap4xxx_clk_init(void);
+
+#endif
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 000000000..61b60dfb1
--- /dev/null
+++ b/arch/arm/mach-omap2/clock_common_data.c
@@ -0,0 +1,115 @@
+/*
+ * 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 },
+};
+
+
+/* clksel_rate blocks shared between OMAP44xx and AM33xx */
+
+const struct clksel_rate div_1_0_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 0 },
+};
+
+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 },
+};
+
+const struct clksel_rate div_1_1_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 0 },
+};
+
+const struct clksel_rate div_1_2_rates[] = {
+ { .div = 1, .val = 2, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 0 },
+};
+
+const struct clksel_rate div_1_3_rates[] = {
+ { .div = 1, .val = 3, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 0 },
+};
+
+const struct clksel_rate div_1_4_rates[] = {
+ { .div = 1, .val = 4, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 0 },
+};
+
+const struct clksel_rate div31_1to31_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 3, .val = 3, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 5, .val = 5, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 6, .val = 6, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 7, .val = 7, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 8, .val = 8, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 9, .val = 9, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 10, .val = 10, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 11, .val = 11, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 12, .val = 12, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 13, .val = 13, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 14, .val = 14, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 15, .val = 15, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 16, .val = 16, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 17, .val = 17, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 18, .val = 18, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 19, .val = 19, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 20, .val = 20, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 21, .val = 21, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 22, .val = 22, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 23, .val = 23, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 24, .val = 24, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 25, .val = 25, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 26, .val = 26, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 27, .val = 27, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 28, .val = 28, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 29, .val = 29, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 30, .val = 30, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 31, .val = 31, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
+ { .div = 0 },
+};
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
new file mode 100644
index 000000000..2da3b5ec0
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -0,0 +1,1297 @@
+/*
+ * OMAP2/3/4 clockdomain framework functions
+ *
+ * Copyright (C) 2008-2011 Texas Instruments, Inc.
+ * Copyright (C) 2008-2011 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/string.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/limits.h>
+#include <linux/err.h>
+#include <linux/clk-provider.h>
+
+#include <linux/io.h>
+
+#include <linux/bitops.h>
+
+#include "soc.h"
+#include "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;
+
+ 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)
+ return ERR_PTR(-EINVAL);
+
+ for (cd = deps; cd->clkdm_name; cd++) {
+ 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;
+
+ 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;
+}
+
+/**
+ * _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 (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);
+ }
+}
+
+/**
+ * _clkdm_add_wkdep - add a wakeup dependency from clkdm2 to clkdm1 (lockless)
+ * @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.
+ */
+static 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;
+ }
+
+ cd->wkdep_usecount++;
+ if (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 dep from clkdm2 to clkdm1 (lockless)
+ * @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.
+ */
+static 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;
+ }
+
+ cd->wkdep_usecount--;
+ if (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_add_sleepdep - add a sleep dependency from clkdm2 to clkdm1 (lockless)
+ * @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.
+ */
+static 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;
+ }
+
+ cd->sleepdep_usecount++;
+ if (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 dep from clkdm2 to clkdm1 (lockless)
+ * @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.
+ */
+static 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;
+ }
+
+ cd->sleepdep_usecount--;
+ if (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;
+}
+
+/* Public functions */
+
+/**
+ * clkdm_register_platform_funcs - register clockdomain implementation fns
+ * @co: func pointers for arch specific implementations
+ *
+ * Register the list of function pointers used to implement the
+ * clockdomain functions on different OMAP SoCs. Should be called
+ * before any other clkdm_register*() function. Returns -EINVAL if
+ * @co is null, -EEXIST if platform functions have already been
+ * registered, or 0 upon success.
+ */
+int clkdm_register_platform_funcs(struct clkdm_ops *co)
+{
+ if (!co)
+ return -EINVAL;
+
+ if (arch_clkdm)
+ return -EEXIST;
+
+ arch_clkdm = co;
+
+ return 0;
+};
+
+/**
+ * clkdm_register_clkdms - register SoC clockdomains
+ * @cs: pointer to an array of struct clockdomain to register
+ *
+ * Register the clockdomains available on a particular OMAP SoC. Must
+ * be called after clkdm_register_platform_funcs(). May be called
+ * multiple times. Returns -EACCES if called before
+ * clkdm_register_platform_funcs(); -EINVAL if the argument @cs is
+ * null; or 0 upon success.
+ */
+int clkdm_register_clkdms(struct clockdomain **cs)
+{
+ struct clockdomain **c = NULL;
+
+ if (!arch_clkdm)
+ return -EACCES;
+
+ if (!cs)
+ return -EINVAL;
+
+ for (c = cs; *c; c++)
+ _clkdm_register(*c);
+
+ return 0;
+}
+
+/**
+ * clkdm_register_autodeps - register autodeps (if required)
+ * @ia: pointer to a static array of struct clkdm_autodep to register
+ *
+ * Register clockdomain "automatic dependencies." These are
+ * clockdomain wakeup and sleep dependencies that are automatically
+ * added whenever the first clock inside a clockdomain is enabled, and
+ * removed whenever the last clock inside a clockdomain is disabled.
+ * These are currently only used on OMAP3 devices, and are deprecated,
+ * since they waste energy. However, until the OMAP2/3 IP block
+ * enable/disable sequence can be converted to match the OMAP4
+ * sequence, they are needed.
+ *
+ * Must be called only after all of the SoC clockdomains are
+ * registered, since the function will resolve autodep clockdomain
+ * names into clockdomain pointers.
+ *
+ * The struct clkdm_autodep @ia array must be static, as this function
+ * does not copy the array elements.
+ *
+ * Returns -EACCES if called before any clockdomains have been
+ * registered, -EINVAL if called with a null @ia argument, -EEXIST if
+ * autodeps have already been registered, or 0 upon success.
+ */
+int clkdm_register_autodeps(struct clkdm_autodep *ia)
+{
+ struct clkdm_autodep *a = NULL;
+
+ if (list_empty(&clkdm_list))
+ return -EACCES;
+
+ if (!ia)
+ return -EINVAL;
+
+ if (autodeps)
+ return -EEXIST;
+
+ autodeps = ia;
+ for (a = autodeps; a->clkdm.ptr; a++)
+ _autodep_lookup(a);
+
+ return 0;
+}
+
+/**
+ * clkdm_complete_init - set up the clockdomain layer
+ *
+ * Put all clockdomains into software-supervised mode; PM code should
+ * later enable hardware-supervised mode as appropriate. Must be
+ * called after clkdm_register_clkdms(). Returns -EACCES if called
+ * before clkdm_register_clkdms(), or 0 upon success.
+ */
+int clkdm_complete_init(void)
+{
+ struct clockdomain *clkdm;
+
+ if (list_empty(&clkdm_list))
+ return -EACCES;
+
+ 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);
+ }
+
+ return 0;
+}
+
+/**
+ * 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;
+
+ if (!clkdm1 || !clkdm2)
+ return -EINVAL;
+
+ cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
+ if (IS_ERR(cd))
+ return PTR_ERR(cd);
+
+ pwrdm_lock(cd->clkdm->pwrdm.ptr);
+ ret = _clkdm_add_wkdep(clkdm1, clkdm2);
+ pwrdm_unlock(cd->clkdm->pwrdm.ptr);
+
+ 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;
+
+ if (!clkdm1 || !clkdm2)
+ return -EINVAL;
+
+ cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
+ if (IS_ERR(cd))
+ return PTR_ERR(cd);
+
+ pwrdm_lock(cd->clkdm->pwrdm.ptr);
+ ret = _clkdm_del_wkdep(clkdm1, clkdm2);
+ pwrdm_unlock(cd->clkdm->pwrdm.ptr);
+
+ 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 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;
+
+ if (!clkdm1 || !clkdm2)
+ return -EINVAL;
+
+ cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
+ if (IS_ERR(cd))
+ return PTR_ERR(cd);
+
+ pwrdm_lock(cd->clkdm->pwrdm.ptr);
+ ret = _clkdm_add_sleepdep(clkdm1, clkdm2);
+ pwrdm_unlock(cd->clkdm->pwrdm.ptr);
+
+ 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;
+
+ if (!clkdm1 || !clkdm2)
+ return -EINVAL;
+
+ cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
+ if (IS_ERR(cd))
+ return PTR_ERR(cd);
+
+ pwrdm_lock(cd->clkdm->pwrdm.ptr);
+ ret = _clkdm_del_sleepdep(clkdm1, clkdm2);
+ pwrdm_unlock(cd->clkdm->pwrdm.ptr);
+
+ 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 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_nolock - force clockdomain sleep transition (lockless)
+ * @clkdm: struct clockdomain *
+ *
+ * Instruct the CM to force a sleep transition on the specified
+ * clockdomain @clkdm. Only for use by the powerdomain code. Returns
+ * -EINVAL if @clkdm is NULL or if clockdomain does not support
+ * software-initiated sleep; 0 upon success.
+ */
+int clkdm_sleep_nolock(struct clockdomain *clkdm)
+{
+ int ret;
+
+ 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);
+
+ clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
+ ret = arch_clkdm->clkdm_sleep(clkdm);
+ ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
+
+ return ret;
+}
+
+/**
+ * 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)
+{
+ int ret;
+
+ pwrdm_lock(clkdm->pwrdm.ptr);
+ ret = clkdm_sleep_nolock(clkdm);
+ pwrdm_unlock(clkdm->pwrdm.ptr);
+
+ return ret;
+}
+
+/**
+ * clkdm_wakeup_nolock - force clockdomain wakeup transition (lockless)
+ * @clkdm: struct clockdomain *
+ *
+ * Instruct the CM to force a wakeup transition on the specified
+ * clockdomain @clkdm. Only for use by the powerdomain code. Returns
+ * -EINVAL if @clkdm is NULL or if the clockdomain does not support
+ * software-controlled wakeup; 0 upon success.
+ */
+int clkdm_wakeup_nolock(struct clockdomain *clkdm)
+{
+ int ret;
+
+ 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);
+
+ clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
+ ret = arch_clkdm->clkdm_wakeup(clkdm);
+ ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
+
+ return ret;
+}
+
+/**
+ * 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)
+{
+ int ret;
+
+ pwrdm_lock(clkdm->pwrdm.ptr);
+ ret = clkdm_wakeup_nolock(clkdm);
+ pwrdm_unlock(clkdm->pwrdm.ptr);
+
+ return ret;
+}
+
+/**
+ * clkdm_allow_idle_nolock - 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. Only for use by
+ * the powerdomain code. No return value.
+ */
+void clkdm_allow_idle_nolock(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return;
+
+ if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) {
+ pr_debug("clock: %s: automatic idle transitions cannot be enabled\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);
+
+ clkdm->_flags |= _CLKDM_FLAG_HWSUP_ENABLED;
+ arch_clkdm->clkdm_allow_idle(clkdm);
+ pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
+}
+
+/**
+ * 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)
+{
+ pwrdm_lock(clkdm->pwrdm.ptr);
+ clkdm_allow_idle_nolock(clkdm);
+ pwrdm_unlock(clkdm->pwrdm.ptr);
+}
+
+/**
+ * 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. Only for use by the powerdomain
+ * code. No return value.
+ */
+void clkdm_deny_idle_nolock(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return;
+
+ if (!(clkdm->flags & CLKDM_CAN_DISABLE_AUTO)) {
+ pr_debug("clockdomain: %s: automatic idle transitions cannot be disabled\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);
+
+ clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
+ arch_clkdm->clkdm_deny_idle(clkdm);
+ pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
+}
+
+/**
+ * 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)
+{
+ pwrdm_lock(clkdm->pwrdm.ptr);
+ clkdm_deny_idle_nolock(clkdm);
+ pwrdm_unlock(clkdm->pwrdm.ptr);
+}
+
+/**
+ * clkdm_in_hwsup - is clockdomain @clkdm have hardware-supervised idle enabled?
+ * @clkdm: struct clockdomain *
+ *
+ * Returns true if clockdomain @clkdm currently has
+ * hardware-supervised idle enabled, or false if it does not or if
+ * @clkdm is NULL. It is only valid to call this function after
+ * clkdm_init() has been called. This function does not actually read
+ * bits from the hardware; it instead tests an in-memory flag that is
+ * changed whenever the clockdomain code changes the auto-idle mode.
+ */
+bool clkdm_in_hwsup(struct clockdomain *clkdm)
+{
+ bool ret;
+
+ if (!clkdm)
+ return false;
+
+ ret = (clkdm->_flags & _CLKDM_FLAG_HWSUP_ENABLED) ? true : false;
+
+ return ret;
+}
+
+/**
+ * clkdm_missing_idle_reporting - can @clkdm enter autoidle even if in use?
+ * @clkdm: struct clockdomain *
+ *
+ * Returns true if clockdomain @clkdm has the
+ * CLKDM_MISSING_IDLE_REPORTING flag set, or false if not or @clkdm is
+ * null. More information is available in the documentation for the
+ * CLKDM_MISSING_IDLE_REPORTING macro.
+ */
+bool clkdm_missing_idle_reporting(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return false;
+
+ return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false;
+}
+
+/* Public autodep handling functions (deprecated) */
+
+/**
+ * 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;
+
+ pr_debug("clockdomain: %s: adding %s sleepdep/wkdep\n",
+ clkdm->name, autodep->clkdm.ptr->name);
+
+ _clkdm_add_sleepdep(clkdm, autodep->clkdm.ptr);
+ _clkdm_add_wkdep(clkdm, autodep->clkdm.ptr);
+ }
+}
+
+/**
+ * clkdm_del_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;
+
+ pr_debug("clockdomain: %s: removing %s sleepdep/wkdep\n",
+ clkdm->name, autodep->clkdm.ptr->name);
+
+ _clkdm_del_sleepdep(clkdm, autodep->clkdm.ptr);
+ _clkdm_del_wkdep(clkdm, autodep->clkdm.ptr);
+ }
+}
+
+/* Clockdomain-to-clock/hwmod framework interface code */
+
+static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
+{
+ if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable)
+ return -EINVAL;
+
+ pwrdm_lock(clkdm->pwrdm.ptr);
+
+ /*
+ * For arch's with no autodeps, clkcm_clk_enable
+ * should be called for every clock instance or hwmod that is
+ * enabled, so the clkdm can be force woken up.
+ */
+ clkdm->usecount++;
+ if (clkdm->usecount > 1 && autodeps) {
+ pwrdm_unlock(clkdm->pwrdm.ptr);
+ return 0;
+ }
+
+ arch_clkdm->clkdm_clk_enable(clkdm);
+ pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
+ pwrdm_unlock(clkdm->pwrdm.ptr);
+
+ pr_debug("clockdomain: %s: enabled\n", clkdm->name);
+
+ return 0;
+}
+
+/**
+ * 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 (!clk)
+ return -EINVAL;
+
+ return _clkdm_clk_hwmod_enable(clkdm);
+}
+
+/**
+ * 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; or returns 0
+ * upon success or if the clockdomain is in hwsup idle mode.
+ */
+int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
+{
+ if (!clkdm || !clk || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
+ return -EINVAL;
+
+ pwrdm_lock(clkdm->pwrdm.ptr);
+
+ /* corner case: disabling unused clocks */
+ if ((__clk_get_enable_count(clk) == 0) && clkdm->usecount == 0)
+ goto ccd_exit;
+
+ if (clkdm->usecount == 0) {
+ pwrdm_unlock(clkdm->pwrdm.ptr);
+ WARN_ON(1); /* underflow */
+ return -ERANGE;
+ }
+
+ clkdm->usecount--;
+ if (clkdm->usecount > 0) {
+ pwrdm_unlock(clkdm->pwrdm.ptr);
+ return 0;
+ }
+
+ arch_clkdm->clkdm_clk_disable(clkdm);
+ pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
+
+ pr_debug("clockdomain: %s: disabled\n", clkdm->name);
+
+ccd_exit:
+ pwrdm_unlock(clkdm->pwrdm.ptr);
+
+ return 0;
+}
+
+/**
+ * clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm
+ * @clkdm: struct clockdomain *
+ * @oh: struct omap_hwmod * of the enabled downstream hwmod
+ *
+ * Increment the usecount of the clockdomain @clkdm and ensure that it
+ * is awake before @oh is enabled. Intended to be called by
+ * module_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_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
+{
+ /* The clkdm attribute does not exist yet prior OMAP4 */
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ return 0;
+
+ /*
+ * XXX Rewrite this code to maintain a list of enabled
+ * downstream hwmods for debugging purposes?
+ */
+
+ if (!oh)
+ return -EINVAL;
+
+ return _clkdm_clk_hwmod_enable(clkdm);
+}
+
+/**
+ * clkdm_hwmod_disable - remove an enabled downstream hwmod from this clkdm
+ * @clkdm: struct clockdomain *
+ * @oh: struct omap_hwmod * of the disabled downstream hwmod
+ *
+ * Decrement the usecount of this clockdomain @clkdm when @oh is
+ * disabled. Intended to be called by module_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; or returns 0 upon success or if the clockdomain is in hwsup
+ * idle mode.
+ */
+int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
+{
+ /* The clkdm attribute does not exist yet prior OMAP4 */
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ return 0;
+
+ /*
+ * XXX Rewrite this code to maintain a list of enabled
+ * downstream hwmods for debugging purposes?
+ */
+
+ if (!clkdm || !oh || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
+ return -EINVAL;
+
+ pwrdm_lock(clkdm->pwrdm.ptr);
+
+ if (clkdm->usecount == 0) {
+ pwrdm_unlock(clkdm->pwrdm.ptr);
+ WARN_ON(1); /* underflow */
+ return -ERANGE;
+ }
+
+ clkdm->usecount--;
+ if (clkdm->usecount > 0) {
+ pwrdm_unlock(clkdm->pwrdm.ptr);
+ return 0;
+ }
+
+ arch_clkdm->clkdm_clk_disable(clkdm);
+ pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
+ pwrdm_unlock(clkdm->pwrdm.ptr);
+
+ pr_debug("clockdomain: %s: disabled\n", clkdm->name);
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
new file mode 100644
index 000000000..77bab5fb6
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -0,0 +1,238 @@
+/*
+ * OMAP2/3 clockdomain framework functions
+ *
+ * Copyright (C) 2008, 2012 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 "clock.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.)
+ * CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is
+ * active whenever the MPU is active. True for interconnects and
+ * the WKUP clockdomains.
+ * CLKDM_MISSING_IDLE_REPORTING: The idle status of the IP blocks and
+ * clocks inside this clockdomain are not taken into account by
+ * the PRCM when determining whether the clockdomain is idle.
+ * Without this flag, if the clockdomain is set to
+ * hardware-supervised idle mode, the PRCM may transition the
+ * enclosing powerdomain to a low power state, even when devices
+ * inside the clockdomain and powerdomain are in use. (An example
+ * of such a clockdomain is the EMU clockdomain on OMAP3/4.) If
+ * this flag is set, and the clockdomain does not support the
+ * force-sleep mode, then the HW_AUTO mode will be used to put the
+ * clockdomain to sleep. Similarly, if the clockdomain supports
+ * the force-wakeup mode, then it will be used whenever a clock or
+ * IP block inside the clockdomain is active, rather than the
+ * HW_AUTO mode.
+ */
+#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_ACTIVE_WITH_MPU (1 << 5)
+#define CLKDM_MISSING_IDLE_REPORTING (1 << 6)
+
+#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
+ *
+ * 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;
+};
+
+/**
+ * struct clkdm_dep - encode dependencies between clockdomains
+ * @clkdm_name: clockdomain name
+ * @clkdm: pointer to the struct clockdomain of @clkdm_name
+ * @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;
+ s16 wkdep_usecount;
+ s16 sleepdep_usecount;
+};
+
+/* Possible flags for struct clockdomain._flags */
+#define _CLKDM_FLAG_HWSUP_ENABLED BIT(0)
+
+struct omap_hwmod;
+
+/**
+ * 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
+ * @_flags: Flags for use only by internal clockdomain code
+ * @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
+ * @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;
+ u8 _flags;
+ const u8 dep_bit;
+ const u8 prcm_partition;
+ const u16 cm_inst;
+ const u16 clkdm_offs;
+ struct clkdm_dep *wkdep_srcs;
+ struct clkdm_dep *sleepdep_srcs;
+ int 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);
+};
+
+int clkdm_register_platform_funcs(struct clkdm_ops *co);
+int clkdm_register_autodeps(struct clkdm_autodep *ia);
+int clkdm_register_clkdms(struct clockdomain **c);
+int clkdm_complete_init(void);
+
+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_nolock(struct clockdomain *clkdm);
+void clkdm_allow_idle(struct clockdomain *clkdm);
+void clkdm_deny_idle_nolock(struct clockdomain *clkdm);
+void clkdm_deny_idle(struct clockdomain *clkdm);
+bool clkdm_in_hwsup(struct clockdomain *clkdm);
+bool clkdm_missing_idle_reporting(struct clockdomain *clkdm);
+
+int clkdm_wakeup_nolock(struct clockdomain *clkdm);
+int clkdm_wakeup(struct clockdomain *clkdm);
+int clkdm_sleep_nolock(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);
+int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh);
+int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh);
+
+extern void __init omap242x_clockdomains_init(void);
+extern void __init omap243x_clockdomains_init(void);
+extern void __init omap3xxx_clockdomains_init(void);
+extern void __init am33xx_clockdomains_init(void);
+extern void __init ti81xx_clockdomains_init(void);
+extern void __init omap44xx_clockdomains_init(void);
+extern void __init omap54xx_clockdomains_init(void);
+extern void __init dra7xx_clockdomains_init(void);
+void am43xx_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;
+extern struct clkdm_ops am33xx_clkdm_operations;
+extern struct clkdm_ops am43xx_clkdm_operations;
+
+extern struct clkdm_dep gfx_24xx_wkdeps[];
+extern struct clkdm_dep dsp_24xx_wkdeps[];
+extern struct clockdomain wkup_common_clkdm;
+
+#endif
diff --git a/arch/arm/mach-omap2/clockdomains2420_data.c b/arch/arm/mach-omap2/clockdomains2420_data.c
new file mode 100644
index 000000000..7e76becf3
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains2420_data.c
@@ -0,0 +1,153 @@
+/*
+ * OMAP2420 clockdomains
+ *
+ * Copyright (C) 2008-2011 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Paul Walmsley, Jouni Högander
+ *
+ * This file contains clockdomains and clockdomain wakeup dependencies
+ * for OMAP2420 chips. Some notes:
+ *
+ * A useful validation rule for struct clockdomain: Any clockdomain
+ * referenced by a wkdep_srcs must have a dep_bit assigned. So
+ * wkdep_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 "soc.h"
+#include "clockdomain.h"
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+#include "prm-regbits-24xx.h"
+
+/*
+ * Clockdomain dependencies for wkdeps
+ *
+ * XXX Hardware dependencies (e.g., dependencies that cannot be
+ * changed in software) are not included here yet, but should be.
+ */
+
+/* Wakeup dependency source arrays */
+
+/* 2420-specific possible wakeup dependencies */
+
+/* 2420 PM_WKDEP_MPU: CORE, DSP, WKUP */
+static struct clkdm_dep mpu_2420_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "dsp_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+/* 2420 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP */
+static struct clkdm_dep core_2420_wkdeps[] = {
+ { .clkdm_name = "dsp_clkdm" },
+ { .clkdm_name = "gfx_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+/*
+ * 2420-only clockdomains
+ */
+
+static struct clockdomain mpu_2420_clkdm = {
+ .name = "mpu_clkdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .wkdep_srcs = mpu_2420_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
+};
+
+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,
+};
+
+static struct clockdomain dsp_2420_clkdm = {
+ .name = "dsp_clkdm",
+ .pwrdm = { .name = "dsp_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
+};
+
+static struct clockdomain gfx_2420_clkdm = {
+ .name = "gfx_clkdm",
+ .pwrdm = { .name = "gfx_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = gfx_24xx_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
+};
+
+static struct clockdomain core_l3_2420_clkdm = {
+ .name = "core_l3_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .wkdep_srcs = core_2420_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
+};
+
+static struct clockdomain core_l4_2420_clkdm = {
+ .name = "core_l4_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .wkdep_srcs = core_2420_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
+};
+
+static struct clockdomain dss_2420_clkdm = {
+ .name = "dss_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
+};
+
+static struct clockdomain *clockdomains_omap242x[] __initdata = {
+ &wkup_common_clkdm,
+ &mpu_2420_clkdm,
+ &iva1_2420_clkdm,
+ &dsp_2420_clkdm,
+ &gfx_2420_clkdm,
+ &core_l3_2420_clkdm,
+ &core_l4_2420_clkdm,
+ &dss_2420_clkdm,
+ NULL,
+};
+
+void __init omap242x_clockdomains_init(void)
+{
+ if (!cpu_is_omap242x())
+ return;
+
+ clkdm_register_platform_funcs(&omap2_clkdm_operations);
+ clkdm_register_clkdms(clockdomains_omap242x);
+ clkdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/clockdomains2430_data.c b/arch/arm/mach-omap2/clockdomains2430_data.c
new file mode 100644
index 000000000..b923007e4
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains2430_data.c
@@ -0,0 +1,180 @@
+/*
+ * OMAP2xxx 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 dependencies
+ * for OMAP2xxx chips. Some notes:
+ *
+ * A useful validation rule for struct clockdomain: Any clockdomain
+ * referenced by a wkdep_srcs must have a dep_bit assigned. So
+ * wkdep_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 "soc.h"
+#include "clockdomain.h"
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+#include "prm-regbits-24xx.h"
+
+/*
+ * Clockdomain dependencies for wkdeps
+ *
+ * XXX Hardware dependencies (e.g., dependencies that cannot be
+ * changed in software) are not included here yet, but should be.
+ */
+
+/* Wakeup dependency source arrays */
+
+/* 2430-specific possible wakeup dependencies */
+
+/* 2430 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP, MDM */
+static struct clkdm_dep core_2430_wkdeps[] = {
+ { .clkdm_name = "dsp_clkdm" },
+ { .clkdm_name = "gfx_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { .clkdm_name = "mdm_clkdm" },
+ { NULL },
+};
+
+/* 2430 PM_WKDEP_MPU: CORE, DSP, WKUP, MDM */
+static struct clkdm_dep mpu_2430_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "dsp_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { .clkdm_name = "mdm_clkdm" },
+ { NULL },
+};
+
+/* 2430 PM_WKDEP_MDM: CORE, MPU, WKUP */
+static struct clkdm_dep mdm_2430_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+/*
+ * 2430-only clockdomains
+ */
+
+static struct clockdomain mpu_2430_clkdm = {
+ .name = "mpu_clkdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = mpu_2430_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
+};
+
+/* 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,
+};
+
+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,
+};
+
+static struct clockdomain gfx_2430_clkdm = {
+ .name = "gfx_clkdm",
+ .pwrdm = { .name = "gfx_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = gfx_24xx_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
+};
+
+/*
+ * 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_2430_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
+};
+
+/*
+ * 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_2430_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
+};
+
+static struct clockdomain dss_2430_clkdm = {
+ .name = "dss_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
+};
+
+static struct clockdomain *clockdomains_omap243x[] __initdata = {
+ &wkup_common_clkdm,
+ &mpu_2430_clkdm,
+ &mdm_clkdm,
+ &dsp_2430_clkdm,
+ &gfx_2430_clkdm,
+ &core_l3_2430_clkdm,
+ &core_l4_2430_clkdm,
+ &dss_2430_clkdm,
+ NULL,
+};
+
+void __init omap243x_clockdomains_init(void)
+{
+ if (!cpu_is_omap243x())
+ return;
+
+ clkdm_register_platform_funcs(&omap2_clkdm_operations);
+ clkdm_register_clkdms(clockdomains_omap243x);
+ clkdm_complete_init();
+}
+
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 000000000..497221965
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
@@ -0,0 +1,92 @@
+/*
+ * OMAP2/3 clockdomain common data
+ *
+ * Copyright (C) 2008-2011 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.
+ */
+
+/* Wakeup dependency source arrays */
+
+/* 2xxx-specific possible dependencies */
+
+/* 2xxx PM_WKDEP_GFX: CORE, MPU, WKUP */
+struct clkdm_dep gfx_24xx_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+/* 2xxx PM_WKDEP_DSP: CORE, MPU, WKUP */
+struct clkdm_dep dsp_24xx_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+
+/*
+ * 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 */
+struct clockdomain wkup_common_clkdm = {
+ .name = "wkup_clkdm",
+ .pwrdm = { .name = "wkup_pwrdm" },
+ .dep_bit = OMAP_EN_WKUP_SHIFT,
+ .flags = CLKDM_ACTIVE_WITH_MPU,
+};
diff --git a/arch/arm/mach-omap2/clockdomains33xx_data.c b/arch/arm/mach-omap2/clockdomains33xx_data.c
new file mode 100644
index 000000000..32c90fd9e
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains33xx_data.c
@@ -0,0 +1,196 @@
+/*
+ * AM33XX Clock Domain data.
+ *
+ * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.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 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/io.h>
+
+#include "clockdomain.h"
+#include "cm.h"
+#include "cm33xx.h"
+#include "cm-regbits-33xx.h"
+
+static struct clockdomain l4ls_am33xx_clkdm = {
+ .name = "l4ls_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .cm_inst = AM33XX_CM_PER_MOD,
+ .clkdm_offs = AM33XX_CM_PER_L4LS_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l3s_am33xx_clkdm = {
+ .name = "l3s_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .cm_inst = AM33XX_CM_PER_MOD,
+ .clkdm_offs = AM33XX_CM_PER_L3S_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l4fw_am33xx_clkdm = {
+ .name = "l4fw_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .cm_inst = AM33XX_CM_PER_MOD,
+ .clkdm_offs = AM33XX_CM_PER_L4FW_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l3_am33xx_clkdm = {
+ .name = "l3_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .cm_inst = AM33XX_CM_PER_MOD,
+ .clkdm_offs = AM33XX_CM_PER_L3_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l4hs_am33xx_clkdm = {
+ .name = "l4hs_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .cm_inst = AM33XX_CM_PER_MOD,
+ .clkdm_offs = AM33XX_CM_PER_L4HS_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain ocpwp_l3_am33xx_clkdm = {
+ .name = "ocpwp_l3_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .cm_inst = AM33XX_CM_PER_MOD,
+ .clkdm_offs = AM33XX_CM_PER_OCPWP_L3_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain pruss_ocp_am33xx_clkdm = {
+ .name = "pruss_ocp_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .cm_inst = AM33XX_CM_PER_MOD,
+ .clkdm_offs = AM33XX_CM_PER_PRUSS_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain cpsw_125mhz_am33xx_clkdm = {
+ .name = "cpsw_125mhz_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .cm_inst = AM33XX_CM_PER_MOD,
+ .clkdm_offs = AM33XX_CM_PER_CPSW_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain lcdc_am33xx_clkdm = {
+ .name = "lcdc_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .cm_inst = AM33XX_CM_PER_MOD,
+ .clkdm_offs = AM33XX_CM_PER_LCDC_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain clk_24mhz_am33xx_clkdm = {
+ .name = "clk_24mhz_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .cm_inst = AM33XX_CM_PER_MOD,
+ .clkdm_offs = AM33XX_CM_PER_CLK_24MHZ_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l4_wkup_am33xx_clkdm = {
+ .name = "l4_wkup_clkdm",
+ .pwrdm = { .name = "wkup_pwrdm" },
+ .cm_inst = AM33XX_CM_WKUP_MOD,
+ .clkdm_offs = AM33XX_CM_WKUP_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l3_aon_am33xx_clkdm = {
+ .name = "l3_aon_clkdm",
+ .pwrdm = { .name = "wkup_pwrdm" },
+ .cm_inst = AM33XX_CM_WKUP_MOD,
+ .clkdm_offs = AM33XX_CM_L3_AON_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l4_wkup_aon_am33xx_clkdm = {
+ .name = "l4_wkup_aon_clkdm",
+ .pwrdm = { .name = "wkup_pwrdm" },
+ .cm_inst = AM33XX_CM_WKUP_MOD,
+ .clkdm_offs = AM33XX_CM_L4_WKUP_AON_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain mpu_am33xx_clkdm = {
+ .name = "mpu_clkdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
+ .cm_inst = AM33XX_CM_MPU_MOD,
+ .clkdm_offs = AM33XX_CM_MPU_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l4_rtc_am33xx_clkdm = {
+ .name = "l4_rtc_clkdm",
+ .pwrdm = { .name = "rtc_pwrdm" },
+ .cm_inst = AM33XX_CM_RTC_MOD,
+ .clkdm_offs = AM33XX_CM_RTC_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain gfx_l3_am33xx_clkdm = {
+ .name = "gfx_l3_clkdm",
+ .pwrdm = { .name = "gfx_pwrdm" },
+ .cm_inst = AM33XX_CM_GFX_MOD,
+ .clkdm_offs = AM33XX_CM_GFX_L3_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain gfx_l4ls_gfx_am33xx_clkdm = {
+ .name = "gfx_l4ls_gfx_clkdm",
+ .pwrdm = { .name = "gfx_pwrdm" },
+ .cm_inst = AM33XX_CM_GFX_MOD,
+ .clkdm_offs = AM33XX_CM_GFX_L4LS_GFX_CLKSTCTRL__1_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l4_cefuse_am33xx_clkdm = {
+ .name = "l4_cefuse_clkdm",
+ .pwrdm = { .name = "cefuse_pwrdm" },
+ .cm_inst = AM33XX_CM_CEFUSE_MOD,
+ .clkdm_offs = AM33XX_CM_CEFUSE_CLKSTCTRL_OFFSET,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain *clockdomains_am33xx[] __initdata = {
+ &l4ls_am33xx_clkdm,
+ &l3s_am33xx_clkdm,
+ &l4fw_am33xx_clkdm,
+ &l3_am33xx_clkdm,
+ &l4hs_am33xx_clkdm,
+ &ocpwp_l3_am33xx_clkdm,
+ &pruss_ocp_am33xx_clkdm,
+ &cpsw_125mhz_am33xx_clkdm,
+ &lcdc_am33xx_clkdm,
+ &clk_24mhz_am33xx_clkdm,
+ &l4_wkup_am33xx_clkdm,
+ &l3_aon_am33xx_clkdm,
+ &l4_wkup_aon_am33xx_clkdm,
+ &mpu_am33xx_clkdm,
+ &l4_rtc_am33xx_clkdm,
+ &gfx_l3_am33xx_clkdm,
+ &gfx_l4ls_gfx_am33xx_clkdm,
+ &l4_cefuse_am33xx_clkdm,
+ NULL,
+};
+
+void __init am33xx_clockdomains_init(void)
+{
+ clkdm_register_platform_funcs(&am33xx_clkdm_operations);
+ clkdm_register_clkdms(clockdomains_am33xx);
+ clkdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
new file mode 100644
index 000000000..f03dc9792
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
@@ -0,0 +1,525 @@
+/*
+ * OMAP3xxx clockdomains
+ *
+ * Copyright (C) 2008-2011 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 OMAP3xxx 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).
+ *
+ * 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 "soc.h"
+#include "clockdomain.h"
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-34xx.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.
+ */
+
+/* OMAP3-specific possible dependencies */
+
+/*
+ * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
+ * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
+ */
+static struct clkdm_dep gfx_sgx_3xxx_wkdeps[] = {
+ { .clkdm_name = "iva2_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+/* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */
+static struct clkdm_dep per_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "iva2_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep per_am35x_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+/* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */
+static struct clkdm_dep usbhost_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "iva2_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep usbhost_am35x_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+/* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */
+static struct clkdm_dep mpu_3xxx_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "iva2_clkdm" },
+ { .clkdm_name = "dss_clkdm" },
+ { .clkdm_name = "per_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep mpu_am35x_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "dss_clkdm" },
+ { .clkdm_name = "per_clkdm" },
+ { NULL },
+};
+
+/* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */
+static struct clkdm_dep iva2_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { .clkdm_name = "dss_clkdm" },
+ { .clkdm_name = "per_clkdm" },
+ { NULL },
+};
+
+/* 3430 PM_WKDEP_CAM: IVA2, MPU, WKUP */
+static struct clkdm_dep cam_wkdeps[] = {
+ { .clkdm_name = "iva2_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+/* 3430 PM_WKDEP_DSS: IVA2, MPU, WKUP */
+static struct clkdm_dep dss_wkdeps[] = {
+ { .clkdm_name = "iva2_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep dss_am35x_wkdeps[] = {
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+/* 3430: PM_WKDEP_NEON: MPU */
+static struct clkdm_dep neon_wkdeps[] = {
+ { .clkdm_name = "mpu_clkdm" },
+ { 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" },
+ { .clkdm_name = "iva2_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep dss_am35x_sleepdeps[] = {
+ { .clkdm_name = "mpu_clkdm" },
+ { NULL },
+};
+
+/* 3430: CM_SLEEPDEP_PER: MPU, IVA */
+static struct clkdm_dep per_sleepdeps[] = {
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "iva2_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep per_am35x_sleepdeps[] = {
+ { .clkdm_name = "mpu_clkdm" },
+ { NULL },
+};
+
+/* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */
+static struct clkdm_dep usbhost_sleepdeps[] = {
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "iva2_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep usbhost_am35x_sleepdeps[] = {
+ { .clkdm_name = "mpu_clkdm" },
+ { NULL },
+};
+
+/* 3430: CM_SLEEPDEP_CAM: MPU */
+static struct clkdm_dep cam_sleepdeps[] = {
+ { .clkdm_name = "mpu_clkdm" },
+ { 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" },
+ { NULL },
+};
+
+/*
+ * OMAP3 clockdomains
+ */
+
+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,
+};
+
+static struct clockdomain mpu_am35x_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_am35x_wkdeps,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
+};
+
+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,
+};
+
+static struct clockdomain iva2_clkdm = {
+ .name = "iva2_clkdm",
+ .pwrdm = { .name = "iva2_pwrdm" },
+ .flags = CLKDM_CAN_SWSUP,
+ .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
+ .wkdep_srcs = iva2_wkdeps,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
+};
+
+static struct clockdomain gfx_3430es1_clkdm = {
+ .name = "gfx_clkdm",
+ .pwrdm = { .name = "gfx_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = gfx_sgx_3xxx_wkdeps,
+ .sleepdep_srcs = gfx_sgx_sleepdeps,
+ .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK,
+};
+
+static struct clockdomain sgx_clkdm = {
+ .name = "sgx_clkdm",
+ .pwrdm = { .name = "sgx_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = gfx_sgx_3xxx_wkdeps,
+ .sleepdep_srcs = gfx_sgx_sleepdeps,
+ .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
+};
+
+static struct clockdomain sgx_am35x_clkdm = {
+ .name = "sgx_clkdm",
+ .pwrdm = { .name = "sgx_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = gfx_sgx_am35x_wkdeps,
+ .sleepdep_srcs = gfx_sgx_sleepdeps,
+ .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
+};
+
+/*
+ * 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,
+};
+
+/*
+ * 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,
+};
+
+/*
+ * 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,
+};
+
+/* 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,
+};
+
+static struct clockdomain dss_am35x_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_am35x_wkdeps,
+ .sleepdep_srcs = dss_am35x_sleepdeps,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
+};
+
+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,
+};
+
+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,
+};
+
+static struct clockdomain usbhost_am35x_clkdm = {
+ .name = "usbhost_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = usbhost_am35x_wkdeps,
+ .sleepdep_srcs = usbhost_am35x_sleepdeps,
+ .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
+};
+
+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,
+};
+
+static struct clockdomain per_am35x_clkdm = {
+ .name = "per_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .dep_bit = OMAP3430_EN_PER_SHIFT,
+ .wkdep_srcs = per_am35x_wkdeps,
+ .sleepdep_srcs = per_am35x_sleepdeps,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
+};
+
+static struct clockdomain emu_clkdm = {
+ .name = "emu_clkdm",
+ .pwrdm = { .name = "emu_pwrdm" },
+ .flags = (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP |
+ CLKDM_MISSING_IDLE_REPORTING),
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
+};
+
+static struct clockdomain dpll1_clkdm = {
+ .name = "dpll1_clkdm",
+ .pwrdm = { .name = "dpll1_pwrdm" },
+};
+
+static struct clockdomain dpll2_clkdm = {
+ .name = "dpll2_clkdm",
+ .pwrdm = { .name = "dpll2_pwrdm" },
+};
+
+static struct clockdomain dpll3_clkdm = {
+ .name = "dpll3_clkdm",
+ .pwrdm = { .name = "dpll3_pwrdm" },
+};
+
+static struct clockdomain dpll4_clkdm = {
+ .name = "dpll4_clkdm",
+ .pwrdm = { .name = "dpll4_pwrdm" },
+};
+
+static struct clockdomain dpll5_clkdm = {
+ .name = "dpll5_clkdm",
+ .pwrdm = { .name = "dpll5_pwrdm" },
+};
+
+/*
+ * Clockdomain hwsup dependencies
+ */
+
+static struct clkdm_autodep clkdm_autodeps[] = {
+ {
+ .clkdm = { .name = "mpu_clkdm" },
+ },
+ {
+ .clkdm = { .name = "iva2_clkdm" },
+ },
+ {
+ .clkdm = { .name = NULL },
+ }
+};
+
+static struct clkdm_autodep clkdm_am35x_autodeps[] = {
+ {
+ .clkdm = { .name = "mpu_clkdm" },
+ },
+ {
+ .clkdm = { .name = NULL },
+ }
+};
+
+/*
+ *
+ */
+
+static struct clockdomain *clockdomains_common[] __initdata = {
+ &wkup_common_clkdm,
+ &neon_clkdm,
+ &core_l3_3xxx_clkdm,
+ &core_l4_3xxx_clkdm,
+ &emu_clkdm,
+ &dpll1_clkdm,
+ &dpll3_clkdm,
+ &dpll4_clkdm,
+ NULL
+};
+
+static struct clockdomain *clockdomains_omap3430[] __initdata = {
+ &mpu_3xxx_clkdm,
+ &iva2_clkdm,
+ &d2d_clkdm,
+ &dss_3xxx_clkdm,
+ &cam_clkdm,
+ &per_clkdm,
+ &dpll2_clkdm,
+ NULL
+};
+
+static struct clockdomain *clockdomains_omap3430es1[] __initdata = {
+ &gfx_3430es1_clkdm,
+ NULL,
+};
+
+static struct clockdomain *clockdomains_omap3430es2plus[] __initdata = {
+ &sgx_clkdm,
+ &dpll5_clkdm,
+ &usbhost_clkdm,
+ NULL,
+};
+
+static struct clockdomain *clockdomains_am35x[] __initdata = {
+ &mpu_am35x_clkdm,
+ &sgx_am35x_clkdm,
+ &dss_am35x_clkdm,
+ &per_am35x_clkdm,
+ &usbhost_am35x_clkdm,
+ &dpll5_clkdm,
+ NULL
+};
+
+void __init omap3xxx_clockdomains_init(void)
+{
+ struct clockdomain **sc;
+ unsigned int rev;
+
+ if (!cpu_is_omap34xx())
+ return;
+
+ clkdm_register_platform_funcs(&omap3_clkdm_operations);
+ clkdm_register_clkdms(clockdomains_common);
+
+ rev = omap_rev();
+
+ if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) {
+ clkdm_register_clkdms(clockdomains_am35x);
+ clkdm_register_autodeps(clkdm_am35x_autodeps);
+ } else {
+ clkdm_register_clkdms(clockdomains_omap3430);
+
+ sc = (rev == OMAP3430_REV_ES1_0) ?
+ clockdomains_omap3430es1 : clockdomains_omap3430es2plus;
+
+ clkdm_register_clkdms(sc);
+ clkdm_register_autodeps(clkdm_autodeps);
+ }
+
+ clkdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/clockdomains43xx_data.c b/arch/arm/mach-omap2/clockdomains43xx_data.c
new file mode 100644
index 000000000..6d71c6082
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains43xx_data.c
@@ -0,0 +1,196 @@
+/*
+ * AM43xx Clock domains framework
+ *
+ * Copyright (C) 2013 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/io.h>
+
+#include "clockdomain.h"
+#include "prcm44xx.h"
+#include "prcm43xx.h"
+
+static struct clockdomain l4_cefuse_43xx_clkdm = {
+ .name = "l4_cefuse_clkdm",
+ .pwrdm = { .name = "cefuse_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_CEFUSE_INST,
+ .clkdm_offs = AM43XX_CM_CEFUSE_CEFUSE_CDOFFS,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain mpu_43xx_clkdm = {
+ .name = "mpu_clkdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_MPU_INST,
+ .clkdm_offs = AM43XX_CM_MPU_MPU_CDOFFS,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain l4ls_43xx_clkdm = {
+ .name = "l4ls_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_PER_INST,
+ .clkdm_offs = AM43XX_CM_PER_L4LS_CDOFFS,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain tamper_43xx_clkdm = {
+ .name = "tamper_clkdm",
+ .pwrdm = { .name = "tamper_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_TAMPER_INST,
+ .clkdm_offs = AM43XX_CM_TAMPER_TAMPER_CDOFFS,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l4_rtc_43xx_clkdm = {
+ .name = "l4_rtc_clkdm",
+ .pwrdm = { .name = "rtc_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_RTC_INST,
+ .clkdm_offs = AM43XX_CM_RTC_RTC_CDOFFS,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain pruss_ocp_43xx_clkdm = {
+ .name = "pruss_ocp_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_PER_INST,
+ .clkdm_offs = AM43XX_CM_PER_ICSS_CDOFFS,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain ocpwp_l3_43xx_clkdm = {
+ .name = "ocpwp_l3_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_PER_INST,
+ .clkdm_offs = AM43XX_CM_PER_OCPWP_L3_CDOFFS,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l3s_tsc_43xx_clkdm = {
+ .name = "l3s_tsc_clkdm",
+ .pwrdm = { .name = "wkup_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_WKUP_INST,
+ .clkdm_offs = AM43XX_CM_WKUP_L3S_TSC_CDOFFS,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain dss_43xx_clkdm = {
+ .name = "dss_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_PER_INST,
+ .clkdm_offs = AM43XX_CM_PER_DSS_CDOFFS,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l3_aon_43xx_clkdm = {
+ .name = "l3_aon_clkdm",
+ .pwrdm = { .name = "wkup_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_WKUP_INST,
+ .clkdm_offs = AM43XX_CM_WKUP_L3_AON_CDOFFS,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain emif_43xx_clkdm = {
+ .name = "emif_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_PER_INST,
+ .clkdm_offs = AM43XX_CM_PER_EMIF_CDOFFS,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l4_wkup_aon_43xx_clkdm = {
+ .name = "l4_wkup_aon_clkdm",
+ .pwrdm = { .name = "wkup_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_WKUP_INST,
+ .clkdm_offs = AM43XX_CM_WKUP_L4_WKUP_AON_CDOFFS,
+};
+
+static struct clockdomain l3_43xx_clkdm = {
+ .name = "l3_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_PER_INST,
+ .clkdm_offs = AM43XX_CM_PER_L3_CDOFFS,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l4_wkup_43xx_clkdm = {
+ .name = "l4_wkup_clkdm",
+ .pwrdm = { .name = "wkup_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_WKUP_INST,
+ .clkdm_offs = AM43XX_CM_WKUP_WKUP_CDOFFS,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain cpsw_125mhz_43xx_clkdm = {
+ .name = "cpsw_125mhz_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_PER_INST,
+ .clkdm_offs = AM43XX_CM_PER_CPSW_CDOFFS,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain gfx_l3_43xx_clkdm = {
+ .name = "gfx_l3_clkdm",
+ .pwrdm = { .name = "gfx_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_GFX_INST,
+ .clkdm_offs = AM43XX_CM_GFX_GFX_L3_CDOFFS,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l3s_43xx_clkdm = {
+ .name = "l3s_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .prcm_partition = AM43XX_CM_PARTITION,
+ .cm_inst = AM43XX_CM_PER_INST,
+ .clkdm_offs = AM43XX_CM_PER_L3S_CDOFFS,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain *clockdomains_am43xx[] __initdata = {
+ &l4_cefuse_43xx_clkdm,
+ &mpu_43xx_clkdm,
+ &l4ls_43xx_clkdm,
+ &tamper_43xx_clkdm,
+ &l4_rtc_43xx_clkdm,
+ &pruss_ocp_43xx_clkdm,
+ &ocpwp_l3_43xx_clkdm,
+ &l3s_tsc_43xx_clkdm,
+ &dss_43xx_clkdm,
+ &l3_aon_43xx_clkdm,
+ &emif_43xx_clkdm,
+ &l4_wkup_aon_43xx_clkdm,
+ &l3_43xx_clkdm,
+ &l4_wkup_43xx_clkdm,
+ &cpsw_125mhz_43xx_clkdm,
+ &gfx_l3_43xx_clkdm,
+ &l3s_43xx_clkdm,
+ NULL
+};
+
+void __init am43xx_clockdomains_init(void)
+{
+ clkdm_register_platform_funcs(&am43xx_clkdm_operations);
+ clkdm_register_clkdms(clockdomains_am43xx);
+ clkdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
new file mode 100644
index 000000000..95192a062
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -0,0 +1,443 @@
+/*
+ * OMAP4 Clock domains framework
+ *
+ * Copyright (C) 2009-2011 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/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 d2d_wkup_sleep_deps[] = {
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_2_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { .clkdm_name = "l3_init_clkdm" },
+ { .clkdm_name = "l4_cfg_clkdm" },
+ { .clkdm_name = "l4_per_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep ducati_wkup_sleep_deps[] = {
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_2_clkdm" },
+ { .clkdm_name = "l3_dss_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { .clkdm_name = "l3_gfx_clkdm" },
+ { .clkdm_name = "l3_init_clkdm" },
+ { .clkdm_name = "l4_cfg_clkdm" },
+ { .clkdm_name = "l4_per_clkdm" },
+ { .clkdm_name = "l4_secure_clkdm" },
+ { .clkdm_name = "l4_wkup_clkdm" },
+ { .clkdm_name = "tesla_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep iss_wkup_sleep_deps[] = {
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep ivahd_wkup_sleep_deps[] = {
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep l3_dma_wkup_sleep_deps[] = {
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "ducati_clkdm" },
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_dss_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { .clkdm_name = "l3_init_clkdm" },
+ { .clkdm_name = "l4_cfg_clkdm" },
+ { .clkdm_name = "l4_per_clkdm" },
+ { .clkdm_name = "l4_secure_clkdm" },
+ { .clkdm_name = "l4_wkup_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep l3_dss_wkup_sleep_deps[] = {
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_2_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep l3_gfx_wkup_sleep_deps[] = {
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep l3_init_wkup_sleep_deps[] = {
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { .clkdm_name = "l4_cfg_clkdm" },
+ { .clkdm_name = "l4_per_clkdm" },
+ { .clkdm_name = "l4_secure_clkdm" },
+ { .clkdm_name = "l4_wkup_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep l4_secure_wkup_sleep_deps[] = {
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { .clkdm_name = "l4_per_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep mpu_wkup_sleep_deps[] = {
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "ducati_clkdm" },
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_2_clkdm" },
+ { .clkdm_name = "l3_dss_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { .clkdm_name = "l3_gfx_clkdm" },
+ { .clkdm_name = "l3_init_clkdm" },
+ { .clkdm_name = "l4_cfg_clkdm" },
+ { .clkdm_name = "l4_per_clkdm" },
+ { .clkdm_name = "l4_secure_clkdm" },
+ { .clkdm_name = "l4_wkup_clkdm" },
+ { .clkdm_name = "tesla_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep tesla_wkup_sleep_deps[] = {
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_2_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { .clkdm_name = "l3_init_clkdm" },
+ { .clkdm_name = "l4_cfg_clkdm" },
+ { .clkdm_name = "l4_per_clkdm" },
+ { .clkdm_name = "l4_wkup_clkdm" },
+ { 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,
+};
+
+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,
+};
+
+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,
+};
+
+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,
+};
+
+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,
+};
+
+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,
+};
+
+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,
+};
+
+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,
+};
+
+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,
+};
+
+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,
+};
+
+static struct clockdomain d2d_44xx_clkdm = {
+ .name = "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 = d2d_wkup_sleep_deps,
+ .sleepdep_srcs = d2d_wkup_sleep_deps,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+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,
+};
+
+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,
+};
+
+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,
+};
+
+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,
+};
+
+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,
+};
+
+static struct clockdomain mpu_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 = mpu_wkup_sleep_deps,
+ .sleepdep_srcs = mpu_wkup_sleep_deps,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+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,
+};
+
+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,
+};
+
+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_SWSUP,
+};
+
+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,
+};
+
+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 | CLKDM_ACTIVE_WITH_MPU,
+};
+
+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_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP |
+ CLKDM_MISSING_IDLE_REPORTING),
+};
+
+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,
+};
+
+/* As clockdomains are added or removed above, this list must also be changed */
+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,
+ &d2d_44xx_clkdm,
+ &mpu0_44xx_clkdm,
+ &mpu1_44xx_clkdm,
+ &l3_emif_44xx_clkdm,
+ &l4_ao_44xx_clkdm,
+ &ducati_44xx_clkdm,
+ &mpu_44xx_clkdm,
+ &l3_2_44xx_clkdm,
+ &l3_1_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_register_platform_funcs(&omap4_clkdm_operations);
+ clkdm_register_clkdms(clockdomains_omap44xx);
+ clkdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/clockdomains54xx_data.c b/arch/arm/mach-omap2/clockdomains54xx_data.c
new file mode 100644
index 000000000..1a3c69d2e
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains54xx_data.c
@@ -0,0 +1,464 @@
+/*
+ * OMAP54XX Clock domains framework
+ *
+ * Copyright (C) 2013 Texas Instruments, Inc.
+ *
+ * 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/io.h>
+
+#include "clockdomain.h"
+#include "cm1_54xx.h"
+#include "cm2_54xx.h"
+
+#include "cm-regbits-54xx.h"
+#include "prm54xx.h"
+#include "prcm44xx.h"
+#include "prcm_mpu54xx.h"
+
+/* Static Dependencies for OMAP4 Clock Domains */
+
+static struct clkdm_dep c2c_wkup_sleep_deps[] = {
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l3init_clkdm" },
+ { .clkdm_name = "l3main1_clkdm" },
+ { .clkdm_name = "l3main2_clkdm" },
+ { .clkdm_name = "l4cfg_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep cam_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l3main1_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep dma_wkup_sleep_deps[] = {
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "dss_clkdm" },
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "ipu_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l3init_clkdm" },
+ { .clkdm_name = "l3main1_clkdm" },
+ { .clkdm_name = "l4cfg_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { .clkdm_name = "l4sec_clkdm" },
+ { .clkdm_name = "wkupaon_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep dsp_wkup_sleep_deps[] = {
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l3init_clkdm" },
+ { .clkdm_name = "l3main1_clkdm" },
+ { .clkdm_name = "l3main2_clkdm" },
+ { .clkdm_name = "l4cfg_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { .clkdm_name = "wkupaon_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep dss_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l3main2_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep gpu_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l3main1_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep ipu_wkup_sleep_deps[] = {
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "dsp_clkdm" },
+ { .clkdm_name = "dss_clkdm" },
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "gpu_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l3init_clkdm" },
+ { .clkdm_name = "l3main1_clkdm" },
+ { .clkdm_name = "l3main2_clkdm" },
+ { .clkdm_name = "l4cfg_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { .clkdm_name = "l4sec_clkdm" },
+ { .clkdm_name = "wkupaon_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep iva_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "l3main1_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep l3init_wkup_sleep_deps[] = {
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l4cfg_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { .clkdm_name = "l4sec_clkdm" },
+ { .clkdm_name = "wkupaon_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep l4sec_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "l3main1_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep mipiext_wkup_sleep_deps[] = {
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l3init_clkdm" },
+ { .clkdm_name = "l3main1_clkdm" },
+ { .clkdm_name = "l3main2_clkdm" },
+ { .clkdm_name = "l4cfg_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep mpu_wkup_sleep_deps[] = {
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "dsp_clkdm" },
+ { .clkdm_name = "dss_clkdm" },
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "gpu_clkdm" },
+ { .clkdm_name = "ipu_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l3init_clkdm" },
+ { .clkdm_name = "l3main1_clkdm" },
+ { .clkdm_name = "l3main2_clkdm" },
+ { .clkdm_name = "l4cfg_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { .clkdm_name = "l4sec_clkdm" },
+ { .clkdm_name = "wkupaon_clkdm" },
+ { NULL },
+};
+
+static struct clockdomain l4sec_54xx_clkdm = {
+ .name = "l4sec_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_CORE_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_CORE_L4SEC_CDOFFS,
+ .dep_bit = OMAP54XX_L4SEC_STATDEP_SHIFT,
+ .wkdep_srcs = l4sec_wkup_sleep_deps,
+ .sleepdep_srcs = l4sec_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain iva_54xx_clkdm = {
+ .name = "iva_clkdm",
+ .pwrdm = { .name = "iva_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_IVA_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_IVA_IVA_CDOFFS,
+ .dep_bit = OMAP54XX_IVA_STATDEP_SHIFT,
+ .wkdep_srcs = iva_wkup_sleep_deps,
+ .sleepdep_srcs = iva_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain mipiext_54xx_clkdm = {
+ .name = "mipiext_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_CORE_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_CORE_MIPIEXT_CDOFFS,
+ .wkdep_srcs = mipiext_wkup_sleep_deps,
+ .sleepdep_srcs = mipiext_wkup_sleep_deps,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain l3main2_54xx_clkdm = {
+ .name = "l3main2_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_CORE_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_CORE_L3MAIN2_CDOFFS,
+ .dep_bit = OMAP54XX_L3MAIN2_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain l3main1_54xx_clkdm = {
+ .name = "l3main1_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_CORE_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_CORE_L3MAIN1_CDOFFS,
+ .dep_bit = OMAP54XX_L3MAIN1_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain custefuse_54xx_clkdm = {
+ .name = "custefuse_clkdm",
+ .pwrdm = { .name = "custefuse_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_CUSTEFUSE_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_CUSTEFUSE_CUSTEFUSE_CDOFFS,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain ipu_54xx_clkdm = {
+ .name = "ipu_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_CORE_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_CORE_IPU_CDOFFS,
+ .dep_bit = OMAP54XX_IPU_STATDEP_SHIFT,
+ .wkdep_srcs = ipu_wkup_sleep_deps,
+ .sleepdep_srcs = ipu_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain l4cfg_54xx_clkdm = {
+ .name = "l4cfg_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_CORE_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_CORE_L4CFG_CDOFFS,
+ .dep_bit = OMAP54XX_L4CFG_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain abe_54xx_clkdm = {
+ .name = "abe_clkdm",
+ .pwrdm = { .name = "abe_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_AON_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_AON_ABE_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_AON_ABE_ABE_CDOFFS,
+ .dep_bit = OMAP54XX_ABE_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain dss_54xx_clkdm = {
+ .name = "dss_clkdm",
+ .pwrdm = { .name = "dss_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_DSS_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_DSS_DSS_CDOFFS,
+ .dep_bit = OMAP54XX_DSS_STATDEP_SHIFT,
+ .wkdep_srcs = dss_wkup_sleep_deps,
+ .sleepdep_srcs = dss_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain dsp_54xx_clkdm = {
+ .name = "dsp_clkdm",
+ .pwrdm = { .name = "dsp_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_AON_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_AON_DSP_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_AON_DSP_DSP_CDOFFS,
+ .dep_bit = OMAP54XX_DSP_STATDEP_SHIFT,
+ .wkdep_srcs = dsp_wkup_sleep_deps,
+ .sleepdep_srcs = dsp_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain c2c_54xx_clkdm = {
+ .name = "c2c_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_CORE_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_CORE_C2C_CDOFFS,
+ .wkdep_srcs = c2c_wkup_sleep_deps,
+ .sleepdep_srcs = c2c_wkup_sleep_deps,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain l4per_54xx_clkdm = {
+ .name = "l4per_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_CORE_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_CORE_L4PER_CDOFFS,
+ .dep_bit = OMAP54XX_L4PER_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain gpu_54xx_clkdm = {
+ .name = "gpu_clkdm",
+ .pwrdm = { .name = "gpu_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_GPU_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_GPU_GPU_CDOFFS,
+ .dep_bit = OMAP54XX_GPU_STATDEP_SHIFT,
+ .wkdep_srcs = gpu_wkup_sleep_deps,
+ .sleepdep_srcs = gpu_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain wkupaon_54xx_clkdm = {
+ .name = "wkupaon_clkdm",
+ .pwrdm = { .name = "wkupaon_pwrdm" },
+ .prcm_partition = OMAP54XX_PRM_PARTITION,
+ .cm_inst = OMAP54XX_PRM_WKUPAON_CM_INST,
+ .clkdm_offs = OMAP54XX_PRM_WKUPAON_CM_WKUPAON_CDOFFS,
+ .dep_bit = OMAP54XX_WKUPAON_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain mpu0_54xx_clkdm = {
+ .name = "mpu0_clkdm",
+ .pwrdm = { .name = "cpu0_pwrdm" },
+ .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION,
+ .cm_inst = OMAP54XX_PRCM_MPU_CM_C0_INST,
+ .clkdm_offs = OMAP54XX_PRCM_MPU_CM_C0_CPU0_CDOFFS,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain mpu1_54xx_clkdm = {
+ .name = "mpu1_clkdm",
+ .pwrdm = { .name = "cpu1_pwrdm" },
+ .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION,
+ .cm_inst = OMAP54XX_PRCM_MPU_CM_C1_INST,
+ .clkdm_offs = OMAP54XX_PRCM_MPU_CM_C1_CPU1_CDOFFS,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain coreaon_54xx_clkdm = {
+ .name = "coreaon_clkdm",
+ .pwrdm = { .name = "coreaon_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_COREAON_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_COREAON_COREAON_CDOFFS,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain mpu_54xx_clkdm = {
+ .name = "mpu_clkdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_AON_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_AON_MPU_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_AON_MPU_MPU_CDOFFS,
+ .wkdep_srcs = mpu_wkup_sleep_deps,
+ .sleepdep_srcs = mpu_wkup_sleep_deps,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain l3init_54xx_clkdm = {
+ .name = "l3init_clkdm",
+ .pwrdm = { .name = "l3init_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_L3INIT_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_L3INIT_L3INIT_CDOFFS,
+ .dep_bit = OMAP54XX_L3INIT_STATDEP_SHIFT,
+ .wkdep_srcs = l3init_wkup_sleep_deps,
+ .sleepdep_srcs = l3init_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain dma_54xx_clkdm = {
+ .name = "dma_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_CORE_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_CORE_DMA_CDOFFS,
+ .wkdep_srcs = dma_wkup_sleep_deps,
+ .sleepdep_srcs = dma_wkup_sleep_deps,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain l3instr_54xx_clkdm = {
+ .name = "l3instr_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_CORE_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_CORE_L3INSTR_CDOFFS,
+};
+
+static struct clockdomain emif_54xx_clkdm = {
+ .name = "emif_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_CORE_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_CORE_EMIF_CDOFFS,
+ .dep_bit = OMAP54XX_EMIF_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain emu_54xx_clkdm = {
+ .name = "emu_clkdm",
+ .pwrdm = { .name = "emu_pwrdm" },
+ .prcm_partition = OMAP54XX_PRM_PARTITION,
+ .cm_inst = OMAP54XX_PRM_EMU_CM_INST,
+ .clkdm_offs = OMAP54XX_PRM_EMU_CM_EMU_CDOFFS,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain cam_54xx_clkdm = {
+ .name = "cam_clkdm",
+ .pwrdm = { .name = "cam_pwrdm" },
+ .prcm_partition = OMAP54XX_CM_CORE_PARTITION,
+ .cm_inst = OMAP54XX_CM_CORE_CAM_INST,
+ .clkdm_offs = OMAP54XX_CM_CORE_CAM_CAM_CDOFFS,
+ .wkdep_srcs = cam_wkup_sleep_deps,
+ .sleepdep_srcs = cam_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+/* As clockdomains are added or removed above, this list must also be changed */
+static struct clockdomain *clockdomains_omap54xx[] __initdata = {
+ &l4sec_54xx_clkdm,
+ &iva_54xx_clkdm,
+ &mipiext_54xx_clkdm,
+ &l3main2_54xx_clkdm,
+ &l3main1_54xx_clkdm,
+ &custefuse_54xx_clkdm,
+ &ipu_54xx_clkdm,
+ &l4cfg_54xx_clkdm,
+ &abe_54xx_clkdm,
+ &dss_54xx_clkdm,
+ &dsp_54xx_clkdm,
+ &c2c_54xx_clkdm,
+ &l4per_54xx_clkdm,
+ &gpu_54xx_clkdm,
+ &wkupaon_54xx_clkdm,
+ &mpu0_54xx_clkdm,
+ &mpu1_54xx_clkdm,
+ &coreaon_54xx_clkdm,
+ &mpu_54xx_clkdm,
+ &l3init_54xx_clkdm,
+ &dma_54xx_clkdm,
+ &l3instr_54xx_clkdm,
+ &emif_54xx_clkdm,
+ &emu_54xx_clkdm,
+ &cam_54xx_clkdm,
+ NULL
+};
+
+void __init omap54xx_clockdomains_init(void)
+{
+ clkdm_register_platform_funcs(&omap4_clkdm_operations);
+ clkdm_register_clkdms(clockdomains_omap54xx);
+ clkdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/clockdomains7xx_data.c b/arch/arm/mach-omap2/clockdomains7xx_data.c
new file mode 100644
index 000000000..57d5df0c1
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains7xx_data.c
@@ -0,0 +1,740 @@
+/*
+ * DRA7xx Clock domains framework
+ *
+ * Copyright (C) 2009-2013 Texas Instruments, Inc.
+ * Copyright (C) 2009-2011 Nokia Corporation
+ *
+ * Generated by code originally written by:
+ * 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/io.h>
+
+#include "clockdomain.h"
+#include "cm1_7xx.h"
+#include "cm2_7xx.h"
+
+#include "cm-regbits-7xx.h"
+#include "prm7xx.h"
+#include "prcm44xx.h"
+#include "prcm_mpu7xx.h"
+
+/* Static Dependencies for DRA7xx Clock Domains */
+
+static struct clkdm_dep cam_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep dma_wkup_sleep_deps[] = {
+ { .clkdm_name = "dss_clkdm" },
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "ipu_clkdm" },
+ { .clkdm_name = "ipu1_clkdm" },
+ { .clkdm_name = "ipu2_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l3init_clkdm" },
+ { .clkdm_name = "l4cfg_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { .clkdm_name = "l4per2_clkdm" },
+ { .clkdm_name = "l4per3_clkdm" },
+ { .clkdm_name = "l4sec_clkdm" },
+ { .clkdm_name = "pcie_clkdm" },
+ { .clkdm_name = "wkupaon_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep dsp1_wkup_sleep_deps[] = {
+ { .clkdm_name = "atl_clkdm" },
+ { .clkdm_name = "cam_clkdm" },
+ { .clkdm_name = "dsp2_clkdm" },
+ { .clkdm_name = "dss_clkdm" },
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "eve1_clkdm" },
+ { .clkdm_name = "eve2_clkdm" },
+ { .clkdm_name = "eve3_clkdm" },
+ { .clkdm_name = "eve4_clkdm" },
+ { .clkdm_name = "gmac_clkdm" },
+ { .clkdm_name = "gpu_clkdm" },
+ { .clkdm_name = "ipu_clkdm" },
+ { .clkdm_name = "ipu1_clkdm" },
+ { .clkdm_name = "ipu2_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l3init_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { .clkdm_name = "l4per2_clkdm" },
+ { .clkdm_name = "l4per3_clkdm" },
+ { .clkdm_name = "l4sec_clkdm" },
+ { .clkdm_name = "pcie_clkdm" },
+ { .clkdm_name = "vpe_clkdm" },
+ { .clkdm_name = "wkupaon_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep dsp2_wkup_sleep_deps[] = {
+ { .clkdm_name = "atl_clkdm" },
+ { .clkdm_name = "cam_clkdm" },
+ { .clkdm_name = "dsp1_clkdm" },
+ { .clkdm_name = "dss_clkdm" },
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "eve1_clkdm" },
+ { .clkdm_name = "eve2_clkdm" },
+ { .clkdm_name = "eve3_clkdm" },
+ { .clkdm_name = "eve4_clkdm" },
+ { .clkdm_name = "gmac_clkdm" },
+ { .clkdm_name = "gpu_clkdm" },
+ { .clkdm_name = "ipu_clkdm" },
+ { .clkdm_name = "ipu1_clkdm" },
+ { .clkdm_name = "ipu2_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l3init_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { .clkdm_name = "l4per2_clkdm" },
+ { .clkdm_name = "l4per3_clkdm" },
+ { .clkdm_name = "l4sec_clkdm" },
+ { .clkdm_name = "pcie_clkdm" },
+ { .clkdm_name = "vpe_clkdm" },
+ { .clkdm_name = "wkupaon_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep dss_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep eve1_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "eve2_clkdm" },
+ { .clkdm_name = "eve3_clkdm" },
+ { .clkdm_name = "eve4_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep eve2_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "eve1_clkdm" },
+ { .clkdm_name = "eve3_clkdm" },
+ { .clkdm_name = "eve4_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep eve3_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "eve1_clkdm" },
+ { .clkdm_name = "eve2_clkdm" },
+ { .clkdm_name = "eve4_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep eve4_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "eve1_clkdm" },
+ { .clkdm_name = "eve2_clkdm" },
+ { .clkdm_name = "eve3_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep gmac_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "l4per2_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep gpu_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep ipu1_wkup_sleep_deps[] = {
+ { .clkdm_name = "atl_clkdm" },
+ { .clkdm_name = "dsp1_clkdm" },
+ { .clkdm_name = "dsp2_clkdm" },
+ { .clkdm_name = "dss_clkdm" },
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "eve1_clkdm" },
+ { .clkdm_name = "eve2_clkdm" },
+ { .clkdm_name = "eve3_clkdm" },
+ { .clkdm_name = "eve4_clkdm" },
+ { .clkdm_name = "gmac_clkdm" },
+ { .clkdm_name = "gpu_clkdm" },
+ { .clkdm_name = "ipu_clkdm" },
+ { .clkdm_name = "ipu2_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l3init_clkdm" },
+ { .clkdm_name = "l3main1_clkdm" },
+ { .clkdm_name = "l4cfg_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { .clkdm_name = "l4per2_clkdm" },
+ { .clkdm_name = "l4per3_clkdm" },
+ { .clkdm_name = "l4sec_clkdm" },
+ { .clkdm_name = "pcie_clkdm" },
+ { .clkdm_name = "vpe_clkdm" },
+ { .clkdm_name = "wkupaon_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep ipu2_wkup_sleep_deps[] = {
+ { .clkdm_name = "atl_clkdm" },
+ { .clkdm_name = "dsp1_clkdm" },
+ { .clkdm_name = "dsp2_clkdm" },
+ { .clkdm_name = "dss_clkdm" },
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "eve1_clkdm" },
+ { .clkdm_name = "eve2_clkdm" },
+ { .clkdm_name = "eve3_clkdm" },
+ { .clkdm_name = "eve4_clkdm" },
+ { .clkdm_name = "gmac_clkdm" },
+ { .clkdm_name = "gpu_clkdm" },
+ { .clkdm_name = "ipu_clkdm" },
+ { .clkdm_name = "ipu1_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l3init_clkdm" },
+ { .clkdm_name = "l3main1_clkdm" },
+ { .clkdm_name = "l4cfg_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { .clkdm_name = "l4per2_clkdm" },
+ { .clkdm_name = "l4per3_clkdm" },
+ { .clkdm_name = "l4sec_clkdm" },
+ { .clkdm_name = "pcie_clkdm" },
+ { .clkdm_name = "vpe_clkdm" },
+ { .clkdm_name = "wkupaon_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep iva_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep l3init_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l4cfg_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { .clkdm_name = "l4per3_clkdm" },
+ { .clkdm_name = "l4sec_clkdm" },
+ { .clkdm_name = "wkupaon_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep l4per2_wkup_sleep_deps[] = {
+ { .clkdm_name = "dsp1_clkdm" },
+ { .clkdm_name = "dsp2_clkdm" },
+ { .clkdm_name = "ipu1_clkdm" },
+ { .clkdm_name = "ipu2_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep l4sec_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep mpu_wkup_sleep_deps[] = {
+ { .clkdm_name = "cam_clkdm" },
+ { .clkdm_name = "dsp1_clkdm" },
+ { .clkdm_name = "dsp2_clkdm" },
+ { .clkdm_name = "dss_clkdm" },
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "eve1_clkdm" },
+ { .clkdm_name = "eve2_clkdm" },
+ { .clkdm_name = "eve3_clkdm" },
+ { .clkdm_name = "eve4_clkdm" },
+ { .clkdm_name = "gmac_clkdm" },
+ { .clkdm_name = "gpu_clkdm" },
+ { .clkdm_name = "ipu_clkdm" },
+ { .clkdm_name = "ipu1_clkdm" },
+ { .clkdm_name = "ipu2_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l3init_clkdm" },
+ { .clkdm_name = "l3main1_clkdm" },
+ { .clkdm_name = "l4cfg_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { .clkdm_name = "l4per2_clkdm" },
+ { .clkdm_name = "l4per3_clkdm" },
+ { .clkdm_name = "l4sec_clkdm" },
+ { .clkdm_name = "pcie_clkdm" },
+ { .clkdm_name = "vpe_clkdm" },
+ { .clkdm_name = "wkupaon_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep pcie_wkup_sleep_deps[] = {
+ { .clkdm_name = "atl_clkdm" },
+ { .clkdm_name = "cam_clkdm" },
+ { .clkdm_name = "dsp1_clkdm" },
+ { .clkdm_name = "dsp2_clkdm" },
+ { .clkdm_name = "dss_clkdm" },
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "eve1_clkdm" },
+ { .clkdm_name = "eve2_clkdm" },
+ { .clkdm_name = "eve3_clkdm" },
+ { .clkdm_name = "eve4_clkdm" },
+ { .clkdm_name = "gmac_clkdm" },
+ { .clkdm_name = "gpu_clkdm" },
+ { .clkdm_name = "ipu_clkdm" },
+ { .clkdm_name = "ipu1_clkdm" },
+ { .clkdm_name = "iva_clkdm" },
+ { .clkdm_name = "l3init_clkdm" },
+ { .clkdm_name = "l4cfg_clkdm" },
+ { .clkdm_name = "l4per_clkdm" },
+ { .clkdm_name = "l4per2_clkdm" },
+ { .clkdm_name = "l4per3_clkdm" },
+ { .clkdm_name = "l4sec_clkdm" },
+ { .clkdm_name = "vpe_clkdm" },
+ { NULL },
+};
+
+static struct clkdm_dep vpe_wkup_sleep_deps[] = {
+ { .clkdm_name = "emif_clkdm" },
+ { .clkdm_name = "l4per3_clkdm" },
+ { NULL },
+};
+
+static struct clockdomain l4per3_7xx_clkdm = {
+ .name = "l4per3_clkdm",
+ .pwrdm = { .name = "l4per_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_L4PER_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_L4PER_L4PER3_CDOFFS,
+ .dep_bit = DRA7XX_L4PER3_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain l4per2_7xx_clkdm = {
+ .name = "l4per2_clkdm",
+ .pwrdm = { .name = "l4per_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_L4PER_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_L4PER_L4PER2_CDOFFS,
+ .dep_bit = DRA7XX_L4PER2_STATDEP_SHIFT,
+ .wkdep_srcs = l4per2_wkup_sleep_deps,
+ .sleepdep_srcs = l4per2_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain mpu0_7xx_clkdm = {
+ .name = "mpu0_clkdm",
+ .pwrdm = { .name = "cpu0_pwrdm" },
+ .prcm_partition = DRA7XX_MPU_PRCM_PARTITION,
+ .cm_inst = DRA7XX_MPU_PRCM_CM_C0_INST,
+ .clkdm_offs = DRA7XX_MPU_PRCM_CM_C0_CPU0_CDOFFS,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain iva_7xx_clkdm = {
+ .name = "iva_clkdm",
+ .pwrdm = { .name = "iva_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_IVA_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_IVA_IVA_CDOFFS,
+ .dep_bit = DRA7XX_IVA_STATDEP_SHIFT,
+ .wkdep_srcs = iva_wkup_sleep_deps,
+ .sleepdep_srcs = iva_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain coreaon_7xx_clkdm = {
+ .name = "coreaon_clkdm",
+ .pwrdm = { .name = "coreaon_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_COREAON_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_COREAON_COREAON_CDOFFS,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain ipu1_7xx_clkdm = {
+ .name = "ipu1_clkdm",
+ .pwrdm = { .name = "ipu_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_AON_IPU_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_AON_IPU_IPU1_CDOFFS,
+ .dep_bit = DRA7XX_IPU1_STATDEP_SHIFT,
+ .wkdep_srcs = ipu1_wkup_sleep_deps,
+ .sleepdep_srcs = ipu1_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain ipu2_7xx_clkdm = {
+ .name = "ipu2_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_CORE_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_CORE_IPU2_CDOFFS,
+ .dep_bit = DRA7XX_IPU2_STATDEP_SHIFT,
+ .wkdep_srcs = ipu2_wkup_sleep_deps,
+ .sleepdep_srcs = ipu2_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain l3init_7xx_clkdm = {
+ .name = "l3init_clkdm",
+ .pwrdm = { .name = "l3init_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_L3INIT_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_L3INIT_L3INIT_CDOFFS,
+ .dep_bit = DRA7XX_L3INIT_STATDEP_SHIFT,
+ .wkdep_srcs = l3init_wkup_sleep_deps,
+ .sleepdep_srcs = l3init_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain l4sec_7xx_clkdm = {
+ .name = "l4sec_clkdm",
+ .pwrdm = { .name = "l4per_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_L4PER_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_L4PER_L4SEC_CDOFFS,
+ .dep_bit = DRA7XX_L4SEC_STATDEP_SHIFT,
+ .wkdep_srcs = l4sec_wkup_sleep_deps,
+ .sleepdep_srcs = l4sec_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain l3main1_7xx_clkdm = {
+ .name = "l3main1_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_CORE_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_CORE_L3MAIN1_CDOFFS,
+ .dep_bit = DRA7XX_L3MAIN1_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain vpe_7xx_clkdm = {
+ .name = "vpe_clkdm",
+ .pwrdm = { .name = "vpe_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_AON_VPE_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_AON_VPE_VPE_CDOFFS,
+ .dep_bit = DRA7XX_VPE_STATDEP_SHIFT,
+ .wkdep_srcs = vpe_wkup_sleep_deps,
+ .sleepdep_srcs = vpe_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain mpu_7xx_clkdm = {
+ .name = "mpu_clkdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_AON_MPU_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_AON_MPU_MPU_CDOFFS,
+ .wkdep_srcs = mpu_wkup_sleep_deps,
+ .sleepdep_srcs = mpu_wkup_sleep_deps,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain custefuse_7xx_clkdm = {
+ .name = "custefuse_clkdm",
+ .pwrdm = { .name = "custefuse_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_CUSTEFUSE_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_CUSTEFUSE_CUSTEFUSE_CDOFFS,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain ipu_7xx_clkdm = {
+ .name = "ipu_clkdm",
+ .pwrdm = { .name = "ipu_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_AON_IPU_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_AON_IPU_IPU_CDOFFS,
+ .dep_bit = DRA7XX_IPU_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain mpu1_7xx_clkdm = {
+ .name = "mpu1_clkdm",
+ .pwrdm = { .name = "cpu1_pwrdm" },
+ .prcm_partition = DRA7XX_MPU_PRCM_PARTITION,
+ .cm_inst = DRA7XX_MPU_PRCM_CM_C1_INST,
+ .clkdm_offs = DRA7XX_MPU_PRCM_CM_C1_CPU1_CDOFFS,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain gmac_7xx_clkdm = {
+ .name = "gmac_clkdm",
+ .pwrdm = { .name = "l3init_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_L3INIT_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_L3INIT_GMAC_CDOFFS,
+ .dep_bit = DRA7XX_GMAC_STATDEP_SHIFT,
+ .wkdep_srcs = gmac_wkup_sleep_deps,
+ .sleepdep_srcs = gmac_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain l4cfg_7xx_clkdm = {
+ .name = "l4cfg_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_CORE_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_CORE_L4CFG_CDOFFS,
+ .dep_bit = DRA7XX_L4CFG_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain dma_7xx_clkdm = {
+ .name = "dma_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_CORE_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_CORE_DMA_CDOFFS,
+ .wkdep_srcs = dma_wkup_sleep_deps,
+ .sleepdep_srcs = dma_wkup_sleep_deps,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain rtc_7xx_clkdm = {
+ .name = "rtc_clkdm",
+ .pwrdm = { .name = "rtc_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_AON_RTC_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_AON_RTC_RTC_CDOFFS,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain pcie_7xx_clkdm = {
+ .name = "pcie_clkdm",
+ .pwrdm = { .name = "l3init_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_L3INIT_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_L3INIT_PCIE_CDOFFS,
+ .dep_bit = DRA7XX_PCIE_STATDEP_SHIFT,
+ .wkdep_srcs = pcie_wkup_sleep_deps,
+ .sleepdep_srcs = pcie_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain atl_7xx_clkdm = {
+ .name = "atl_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_CORE_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_CORE_ATL_CDOFFS,
+ .dep_bit = DRA7XX_ATL_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain l3instr_7xx_clkdm = {
+ .name = "l3instr_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_CORE_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_CORE_L3INSTR_CDOFFS,
+};
+
+static struct clockdomain dss_7xx_clkdm = {
+ .name = "dss_clkdm",
+ .pwrdm = { .name = "dss_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_DSS_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_DSS_DSS_CDOFFS,
+ .dep_bit = DRA7XX_DSS_STATDEP_SHIFT,
+ .wkdep_srcs = dss_wkup_sleep_deps,
+ .sleepdep_srcs = dss_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain emif_7xx_clkdm = {
+ .name = "emif_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_CORE_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_CORE_EMIF_CDOFFS,
+ .dep_bit = DRA7XX_EMIF_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain emu_7xx_clkdm = {
+ .name = "emu_clkdm",
+ .pwrdm = { .name = "emu_pwrdm" },
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .cm_inst = DRA7XX_PRM_EMU_CM_INST,
+ .clkdm_offs = DRA7XX_PRM_EMU_CM_EMU_CDOFFS,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain dsp2_7xx_clkdm = {
+ .name = "dsp2_clkdm",
+ .pwrdm = { .name = "dsp2_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_AON_DSP2_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_AON_DSP2_DSP2_CDOFFS,
+ .dep_bit = DRA7XX_DSP2_STATDEP_SHIFT,
+ .wkdep_srcs = dsp2_wkup_sleep_deps,
+ .sleepdep_srcs = dsp2_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain dsp1_7xx_clkdm = {
+ .name = "dsp1_clkdm",
+ .pwrdm = { .name = "dsp1_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_AON_DSP1_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_AON_DSP1_DSP1_CDOFFS,
+ .dep_bit = DRA7XX_DSP1_STATDEP_SHIFT,
+ .wkdep_srcs = dsp1_wkup_sleep_deps,
+ .sleepdep_srcs = dsp1_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain cam_7xx_clkdm = {
+ .name = "cam_clkdm",
+ .pwrdm = { .name = "cam_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_CAM_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_CAM_CAM_CDOFFS,
+ .dep_bit = DRA7XX_CAM_STATDEP_SHIFT,
+ .wkdep_srcs = cam_wkup_sleep_deps,
+ .sleepdep_srcs = cam_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain l4per_7xx_clkdm = {
+ .name = "l4per_clkdm",
+ .pwrdm = { .name = "l4per_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_L4PER_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_L4PER_L4PER_CDOFFS,
+ .dep_bit = DRA7XX_L4PER_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain gpu_7xx_clkdm = {
+ .name = "gpu_clkdm",
+ .pwrdm = { .name = "gpu_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_GPU_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_GPU_GPU_CDOFFS,
+ .dep_bit = DRA7XX_GPU_STATDEP_SHIFT,
+ .wkdep_srcs = gpu_wkup_sleep_deps,
+ .sleepdep_srcs = gpu_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain eve4_7xx_clkdm = {
+ .name = "eve4_clkdm",
+ .pwrdm = { .name = "eve4_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_AON_EVE4_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_AON_EVE4_EVE4_CDOFFS,
+ .dep_bit = DRA7XX_EVE4_STATDEP_SHIFT,
+ .wkdep_srcs = eve4_wkup_sleep_deps,
+ .sleepdep_srcs = eve4_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain eve2_7xx_clkdm = {
+ .name = "eve2_clkdm",
+ .pwrdm = { .name = "eve2_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_AON_EVE2_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_AON_EVE2_EVE2_CDOFFS,
+ .dep_bit = DRA7XX_EVE2_STATDEP_SHIFT,
+ .wkdep_srcs = eve2_wkup_sleep_deps,
+ .sleepdep_srcs = eve2_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain eve3_7xx_clkdm = {
+ .name = "eve3_clkdm",
+ .pwrdm = { .name = "eve3_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_AON_EVE3_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_AON_EVE3_EVE3_CDOFFS,
+ .dep_bit = DRA7XX_EVE3_STATDEP_SHIFT,
+ .wkdep_srcs = eve3_wkup_sleep_deps,
+ .sleepdep_srcs = eve3_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain wkupaon_7xx_clkdm = {
+ .name = "wkupaon_clkdm",
+ .pwrdm = { .name = "wkupaon_pwrdm" },
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .cm_inst = DRA7XX_PRM_WKUPAON_CM_INST,
+ .clkdm_offs = DRA7XX_PRM_WKUPAON_CM_WKUPAON_CDOFFS,
+ .dep_bit = DRA7XX_WKUPAON_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain eve1_7xx_clkdm = {
+ .name = "eve1_clkdm",
+ .pwrdm = { .name = "eve1_pwrdm" },
+ .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION,
+ .cm_inst = DRA7XX_CM_CORE_AON_EVE1_INST,
+ .clkdm_offs = DRA7XX_CM_CORE_AON_EVE1_EVE1_CDOFFS,
+ .dep_bit = DRA7XX_EVE1_STATDEP_SHIFT,
+ .wkdep_srcs = eve1_wkup_sleep_deps,
+ .sleepdep_srcs = eve1_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+/* As clockdomains are added or removed above, this list must also be changed */
+static struct clockdomain *clockdomains_dra7xx[] __initdata = {
+ &l4per3_7xx_clkdm,
+ &l4per2_7xx_clkdm,
+ &mpu0_7xx_clkdm,
+ &iva_7xx_clkdm,
+ &coreaon_7xx_clkdm,
+ &ipu1_7xx_clkdm,
+ &ipu2_7xx_clkdm,
+ &l3init_7xx_clkdm,
+ &l4sec_7xx_clkdm,
+ &l3main1_7xx_clkdm,
+ &vpe_7xx_clkdm,
+ &mpu_7xx_clkdm,
+ &custefuse_7xx_clkdm,
+ &ipu_7xx_clkdm,
+ &mpu1_7xx_clkdm,
+ &gmac_7xx_clkdm,
+ &l4cfg_7xx_clkdm,
+ &dma_7xx_clkdm,
+ &rtc_7xx_clkdm,
+ &pcie_7xx_clkdm,
+ &atl_7xx_clkdm,
+ &l3instr_7xx_clkdm,
+ &dss_7xx_clkdm,
+ &emif_7xx_clkdm,
+ &emu_7xx_clkdm,
+ &dsp2_7xx_clkdm,
+ &dsp1_7xx_clkdm,
+ &cam_7xx_clkdm,
+ &l4per_7xx_clkdm,
+ &gpu_7xx_clkdm,
+ &eve4_7xx_clkdm,
+ &eve2_7xx_clkdm,
+ &eve3_7xx_clkdm,
+ &wkupaon_7xx_clkdm,
+ &eve1_7xx_clkdm,
+ NULL
+};
+
+void __init dra7xx_clockdomains_init(void)
+{
+ clkdm_register_platform_funcs(&omap4_clkdm_operations);
+ clkdm_register_clkdms(clockdomains_dra7xx);
+ clkdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/clockdomains81xx_data.c b/arch/arm/mach-omap2/clockdomains81xx_data.c
new file mode 100644
index 000000000..ce2a82001
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains81xx_data.c
@@ -0,0 +1,194 @@
+/*
+ * TI81XX Clock Domain data.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/
+ * Copyright (C) 2013 SKTB SKiT, http://www.skitlab.ru/
+ *
+ * This program is free software; 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 __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_81XX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_81XX_H
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+#include "clockdomain.h"
+#include "cm81xx.h"
+
+/*
+ * Note that 814x seems to have HWSUP_SWSUP for many clockdomains
+ * while 816x does not. According to the TRM, 816x only has HWSUP
+ * for ALWON_L3_FAST. Also note that the TI tree clockdomains81xx.h
+ * seems to have the related ifdef the wrong way around claiming
+ * 816x supports HWSUP while 814x does not. For now, we only set
+ * HWSUP for ALWON_L3_FAST as that seems to be supported for both
+ * dm814x and dm816x.
+ */
+
+/* Common for 81xx */
+
+static struct clockdomain alwon_l3_slow_81xx_clkdm = {
+ .name = "alwon_l3s_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_ALWON_L3_SLOW_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain alwon_l3_med_81xx_clkdm = {
+ .name = "alwon_l3_med_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_ALWON_L3_MED_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain alwon_l3_fast_81xx_clkdm = {
+ .name = "alwon_l3_fast_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_ALWON_L3_FAST_CLKDM,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain alwon_ethernet_81xx_clkdm = {
+ .name = "alwon_ethernet_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_ETHERNET_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain mmu_81xx_clkdm = {
+ .name = "mmu_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_MMU_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain mmu_cfg_81xx_clkdm = {
+ .name = "mmu_cfg_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_MMUCFG_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+/* 816x only */
+
+static struct clockdomain alwon_mpu_816x_clkdm = {
+ .name = "alwon_mpu_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_ALWON_MPU_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain active_gem_816x_clkdm = {
+ .name = "active_gem_clkdm",
+ .pwrdm = { .name = "active_pwrdm" },
+ .cm_inst = TI816X_CM_ACTIVE_MOD,
+ .clkdm_offs = TI816X_CM_ACTIVE_GEM_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain ivahd0_816x_clkdm = {
+ .name = "ivahd0_clkdm",
+ .pwrdm = { .name = "ivahd0_pwrdm" },
+ .cm_inst = TI816X_CM_IVAHD0_MOD,
+ .clkdm_offs = TI816X_CM_IVAHD0_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain ivahd1_816x_clkdm = {
+ .name = "ivahd1_clkdm",
+ .pwrdm = { .name = "ivahd1_pwrdm" },
+ .cm_inst = TI816X_CM_IVAHD1_MOD,
+ .clkdm_offs = TI816X_CM_IVAHD1_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain ivahd2_816x_clkdm = {
+ .name = "ivahd2_clkdm",
+ .pwrdm = { .name = "ivahd2_pwrdm" },
+ .cm_inst = TI816X_CM_IVAHD2_MOD,
+ .clkdm_offs = TI816X_CM_IVAHD2_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain sgx_816x_clkdm = {
+ .name = "sgx_clkdm",
+ .pwrdm = { .name = "sgx_pwrdm" },
+ .cm_inst = TI816X_CM_SGX_MOD,
+ .clkdm_offs = TI816X_CM_SGX_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain default_l3_med_816x_clkdm = {
+ .name = "default_l3_med_clkdm",
+ .pwrdm = { .name = "default_pwrdm" },
+ .cm_inst = TI816X_CM_DEFAULT_MOD,
+ .clkdm_offs = TI816X_CM_DEFAULT_L3_MED_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain default_ducati_816x_clkdm = {
+ .name = "default_ducati_clkdm",
+ .pwrdm = { .name = "default_pwrdm" },
+ .cm_inst = TI816X_CM_DEFAULT_MOD,
+ .clkdm_offs = TI816X_CM_DEFAULT_DUCATI_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain default_pci_816x_clkdm = {
+ .name = "default_pci_clkdm",
+ .pwrdm = { .name = "default_pwrdm" },
+ .cm_inst = TI816X_CM_DEFAULT_MOD,
+ .clkdm_offs = TI816X_CM_DEFAULT_PCI_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain default_l3_slow_816x_clkdm = {
+ .name = "default_l3_slow_clkdm",
+ .pwrdm = { .name = "default_pwrdm" },
+ .cm_inst = TI816X_CM_DEFAULT_MOD,
+ .clkdm_offs = TI816X_CM_DEFAULT_L3_SLOW_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain *clockdomains_ti81xx[] __initdata = {
+ &alwon_mpu_816x_clkdm,
+ &alwon_l3_slow_81xx_clkdm,
+ &alwon_l3_med_81xx_clkdm,
+ &alwon_l3_fast_81xx_clkdm,
+ &alwon_ethernet_81xx_clkdm,
+ &mmu_81xx_clkdm,
+ &mmu_cfg_81xx_clkdm,
+ &active_gem_816x_clkdm,
+ &ivahd0_816x_clkdm,
+ &ivahd1_816x_clkdm,
+ &ivahd2_816x_clkdm,
+ &sgx_816x_clkdm,
+ &default_l3_med_816x_clkdm,
+ &default_ducati_816x_clkdm,
+ &default_pci_816x_clkdm,
+ &default_l3_slow_816x_clkdm,
+ NULL,
+};
+
+void __init ti81xx_clockdomains_init(void)
+{
+ clkdm_register_platform_funcs(&am33xx_clkdm_operations);
+ clkdm_register_clkdms(clockdomains_ti81xx);
+ clkdm_complete_init();
+}
+#endif
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 000000000..d7a5d11cb
--- /dev/null
+++ b/arch/arm/mach-omap2/cm-regbits-24xx.h
@@ -0,0 +1,135 @@
+#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.
+ */
+
+#define OMAP24XX_EN_CAM_SHIFT 31
+#define OMAP24XX_EN_WDT4_SHIFT 29
+#define OMAP2420_EN_WDT3_SHIFT 28
+#define OMAP24XX_EN_MSPRO_SHIFT 27
+#define OMAP24XX_EN_FAC_SHIFT 25
+#define OMAP2420_EN_EAC_SHIFT 24
+#define OMAP24XX_EN_HDQ_SHIFT 23
+#define OMAP2420_EN_I2C2_SHIFT 20
+#define OMAP2420_EN_I2C1_SHIFT 19
+#define OMAP2430_EN_MCBSP5_SHIFT 5
+#define OMAP2430_EN_MCBSP4_SHIFT 4
+#define OMAP2430_EN_MCBSP3_SHIFT 3
+#define OMAP24XX_EN_SSI_SHIFT 1
+#define OMAP24XX_EN_MPU_WDT_SHIFT 3
+#define OMAP24XX_CLKSEL_MPU_SHIFT 0
+#define OMAP24XX_CLKSEL_MPU_WIDTH 5
+#define OMAP24XX_AUTOSTATE_MPU_MASK (1 << 0)
+#define OMAP24XX_EN_TV_SHIFT 2
+#define OMAP24XX_EN_DSS2_SHIFT 1
+#define OMAP24XX_EN_DSS1_SHIFT 0
+#define OMAP24XX_EN_DSS1_MASK (1 << 0)
+#define OMAP2430_EN_I2CHS2_SHIFT 20
+#define OMAP2430_EN_I2CHS1_SHIFT 19
+#define OMAP2430_EN_MMCHSDB2_SHIFT 17
+#define OMAP2430_EN_MMCHSDB1_SHIFT 16
+#define OMAP24XX_EN_MAILBOXES_SHIFT 30
+#define OMAP2430_EN_SDRC_SHIFT 2
+#define OMAP24XX_EN_PKA_SHIFT 4
+#define OMAP24XX_EN_AES_SHIFT 3
+#define OMAP24XX_EN_RNG_SHIFT 2
+#define OMAP24XX_EN_SHA_SHIFT 1
+#define OMAP24XX_EN_DES_SHIFT 0
+#define OMAP24XX_ST_MAILBOXES_SHIFT 30
+#define OMAP24XX_ST_HDQ_SHIFT 23
+#define OMAP2420_ST_I2C2_SHIFT 20
+#define OMAP2430_ST_I2CHS1_SHIFT 19
+#define OMAP2420_ST_I2C1_SHIFT 19
+#define OMAP2430_ST_I2CHS2_SHIFT 20
+#define OMAP24XX_ST_MCBSP2_SHIFT 16
+#define OMAP24XX_ST_MCBSP1_SHIFT 15
+#define OMAP24XX_ST_DSS_SHIFT 0
+#define OMAP2430_ST_MCBSP5_SHIFT 5
+#define OMAP2430_ST_MCBSP4_SHIFT 4
+#define OMAP2430_ST_MCBSP3_SHIFT 3
+#define OMAP24XX_ST_AES_SHIFT 3
+#define OMAP24XX_ST_RNG_SHIFT 2
+#define OMAP24XX_ST_SHA_SHIFT 1
+#define OMAP24XX_AUTO_SDRC_SHIFT 2
+#define OMAP24XX_AUTO_GPMC_SHIFT 1
+#define OMAP24XX_AUTO_SDMA_SHIFT 0
+#define OMAP24XX_CLKSEL_USB_MASK (0x7 << 25)
+#define OMAP24XX_CLKSEL_SSI_MASK (0x1f << 20)
+#define OMAP2420_CLKSEL_VLYNQ_MASK (0x1f << 15)
+#define OMAP24XX_CLKSEL_DSS2_MASK (0x1 << 13)
+#define OMAP24XX_CLKSEL_DSS1_MASK (0x1f << 8)
+#define OMAP24XX_CLKSEL_L4_SHIFT 5
+#define OMAP24XX_CLKSEL_L4_WIDTH 2
+#define OMAP24XX_CLKSEL_L3_SHIFT 0
+#define OMAP24XX_CLKSEL_L3_WIDTH 5
+#define OMAP24XX_CLKSEL_GPT12_MASK (0x3 << 22)
+#define OMAP24XX_CLKSEL_GPT11_MASK (0x3 << 20)
+#define OMAP24XX_CLKSEL_GPT10_MASK (0x3 << 18)
+#define OMAP24XX_CLKSEL_GPT9_MASK (0x3 << 16)
+#define OMAP24XX_CLKSEL_GPT8_MASK (0x3 << 14)
+#define OMAP24XX_CLKSEL_GPT7_MASK (0x3 << 12)
+#define OMAP24XX_CLKSEL_GPT6_MASK (0x3 << 10)
+#define OMAP24XX_CLKSEL_GPT5_MASK (0x3 << 8)
+#define OMAP24XX_CLKSEL_GPT4_MASK (0x3 << 6)
+#define OMAP24XX_CLKSEL_GPT3_MASK (0x3 << 4)
+#define OMAP24XX_CLKSEL_GPT2_MASK (0x3 << 2)
+#define OMAP24XX_AUTOSTATE_DSS_MASK (1 << 2)
+#define OMAP24XX_AUTOSTATE_L4_MASK (1 << 1)
+#define OMAP24XX_AUTOSTATE_L3_MASK (1 << 0)
+#define OMAP24XX_EN_3D_SHIFT 2
+#define OMAP24XX_EN_2D_SHIFT 1
+#define OMAP24XX_AUTOSTATE_GFX_MASK (1 << 0)
+#define OMAP2430_EN_ICR_SHIFT 6
+#define OMAP24XX_EN_OMAPCTRL_SHIFT 5
+#define OMAP24XX_EN_WDT1_SHIFT 4
+#define OMAP24XX_EN_32KSYNC_SHIFT 1
+#define OMAP24XX_ST_MPU_WDT_SHIFT 3
+#define OMAP24XX_ST_32KSYNC_SHIFT 1
+#define OMAP24XX_CLKSEL_GPT1_MASK (0x3 << 0)
+#define OMAP24XX_EN_54M_PLL_SHIFT 6
+#define OMAP24XX_EN_96M_PLL_SHIFT 2
+#define OMAP24XX_EN_DPLL_MASK (0x3 << 0)
+#define OMAP24XX_ST_54M_APLL_SHIFT 9
+#define OMAP24XX_ST_96M_APLL_SHIFT 8
+#define OMAP24XX_AUTO_54M_MASK (0x3 << 6)
+#define OMAP24XX_AUTO_96M_MASK (0x3 << 2)
+#define OMAP24XX_AUTO_DPLL_SHIFT 0
+#define OMAP24XX_AUTO_DPLL_MASK (0x3 << 0)
+#define OMAP24XX_APLLS_CLKIN_SHIFT 23
+#define OMAP24XX_APLLS_CLKIN_WIDTH 3
+#define OMAP24XX_APLLS_CLKIN_MASK (0x7 << 23)
+#define OMAP24XX_DPLL_MULT_MASK (0x3ff << 12)
+#define OMAP24XX_DPLL_DIV_MASK (0xf << 8)
+#define OMAP24XX_54M_SOURCE_SHIFT 5
+#define OMAP24XX_54M_SOURCE_WIDTH 1
+#define OMAP2430_96M_SOURCE_SHIFT 4
+#define OMAP2430_96M_SOURCE_WIDTH 1
+#define OMAP24XX_48M_SOURCE_MASK (1 << 3)
+#define OMAP24XX_CORE_CLK_SRC_MASK (0x3 << 0)
+#define OMAP2420_EN_IVA_COP_SHIFT 10
+#define OMAP2420_EN_IVA_MPU_SHIFT 8
+#define OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT 0
+#define OMAP2420_EN_DSP_IPI_SHIFT 1
+#define OMAP2420_CLKSEL_IVA_MASK (0x1f << 8)
+#define OMAP24XX_CLKSEL_DSP_IF_MASK (0x3 << 5)
+#define OMAP24XX_CLKSEL_DSP_MASK (0x1f << 0)
+#define OMAP2420_AUTOSTATE_IVA_MASK (1 << 8)
+#define OMAP24XX_AUTOSTATE_DSP_MASK (1 << 0)
+#define OMAP2430_EN_OSC_SHIFT 1
+#define OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT 0
+#define OMAP2430_CLKSEL_MDM_MASK (0xf << 0)
+#define OMAP2430_AUTOSTATE_MDM_MASK (1 << 0)
+#define OMAP24XX_CLKSTCTRL_DISABLE_AUTO 0x0
+#define OMAP24XX_CLKSTCTRL_ENABLE_AUTO 0x1
+#endif
diff --git a/arch/arm/mach-omap2/cm-regbits-33xx.h b/arch/arm/mach-omap2/cm-regbits-33xx.h
new file mode 100644
index 000000000..c0823fd6d
--- /dev/null
+++ b/arch/arm/mach-omap2/cm-regbits-33xx.h
@@ -0,0 +1,68 @@
+/*
+ * AM33XX Power Management register bits
+ *
+ * This file is automatically generated from the AM33XX hardware databases.
+ * Vaibhav Hiremath <hvaibhav@ti.com>
+ *
+ * Copyright (C) 2011-2012 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 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 __ARCH_ARM_MACH_OMAP2_CM_REGBITS_33XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM_REGBITS_33XX_H
+
+#define AM33XX_CLKOUT2DIV_SHIFT 3
+#define AM33XX_CLKOUT2DIV_WIDTH 3
+#define AM33XX_CLKOUT2EN_SHIFT 7
+#define AM33XX_CLKOUT2SOURCE_MASK (0x7 << 0)
+#define AM33XX_CLKSEL_0_0_SHIFT 0
+#define AM33XX_CLKSEL_0_0_WIDTH 1
+#define AM33XX_CLKSEL_0_0_MASK (1 << 0)
+#define AM33XX_CLKSEL_0_1_MASK (3 << 0)
+#define AM33XX_CLKSEL_0_2_MASK (7 << 0)
+#define AM33XX_CLKSEL_GFX_FCLK_MASK (1 << 1)
+#define AM33XX_CLKTRCTRL_SHIFT 0
+#define AM33XX_CLKTRCTRL_MASK (0x3 << 0)
+#define AM33XX_DPLL_CLKOUT_DIV_SHIFT 0
+#define AM33XX_DPLL_CLKOUT_DIV_WIDTH 5
+#define AM33XX_DPLL_DIV_MASK (0x7f << 0)
+#define AM33XX_DPLL_PER_DIV_MASK (0xff << 0)
+#define AM33XX_DPLL_EN_MASK (0x7 << 0)
+#define AM33XX_DPLL_MULT_MASK (0x7ff << 8)
+#define AM33XX_DPLL_MULT_PERIPH_MASK (0xfff << 8)
+#define AM33XX_HSDIVIDER_CLKOUT1_DIV_SHIFT 0
+#define AM33XX_HSDIVIDER_CLKOUT1_DIV_WIDTH 5
+#define AM33XX_HSDIVIDER_CLKOUT2_DIV_SHIFT 0
+#define AM33XX_HSDIVIDER_CLKOUT2_DIV_WIDTH 5
+#define AM33XX_HSDIVIDER_CLKOUT3_DIV_SHIFT 0
+#define AM33XX_HSDIVIDER_CLKOUT3_DIV_WIDTH 5
+#define AM33XX_IDLEST_SHIFT 16
+#define AM33XX_IDLEST_MASK (0x3 << 16)
+#define AM33XX_MODULEMODE_SHIFT 0
+#define AM33XX_MODULEMODE_MASK (0x3 << 0)
+#define AM33XX_OPTCLK_DEBUG_CLKA_SHIFT 30
+#define AM33XX_OPTFCLKEN_DBGSYSCLK_SHIFT 19
+#define AM33XX_OPTFCLKEN_GPIO0_GDBCLK_SHIFT 18
+#define AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_SHIFT 18
+#define AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_SHIFT 18
+#define AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_SHIFT 18
+#define AM33XX_STM_PMD_CLKDIVSEL_SHIFT 27
+#define AM33XX_STM_PMD_CLKDIVSEL_WIDTH 3
+#define AM33XX_STM_PMD_CLKSEL_SHIFT 22
+#define AM33XX_STM_PMD_CLKSEL_WIDTH 2
+#define AM33XX_ST_DPLL_CLK_MASK (1 << 0)
+#define AM33XX_ST_DPLL_CLKDCOLDO_SHIFT 8
+#define AM33XX_TRC_PMD_CLKDIVSEL_SHIFT 24
+#define AM33XX_TRC_PMD_CLKDIVSEL_WIDTH 3
+#define AM33XX_TRC_PMD_CLKSEL_SHIFT 20
+#define AM33XX_TRC_PMD_CLKSEL_WIDTH 2
+#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 000000000..ee6c784cd
--- /dev/null
+++ b/arch/arm/mach-omap2/cm-regbits-34xx.h
@@ -0,0 +1,217 @@
+#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.
+ */
+
+#define OMAP3430ES2_EN_MMC3_SHIFT 30
+#define OMAP3430_EN_MSPRO_SHIFT 23
+#define OMAP3430_EN_HDQ_SHIFT 22
+#define OMAP3430ES1_EN_FSHOSTUSB_SHIFT 5
+#define OMAP3430ES1_EN_D2D_SHIFT 3
+#define OMAP3430_EN_SSI_SHIFT 0
+#define OMAP3430ES2_EN_USBTLL_SHIFT 2
+#define OMAP3430_EN_WDT2_SHIFT 5
+#define OMAP3430_EN_CAM_SHIFT 0
+#define OMAP3430_EN_WDT3_SHIFT 12
+#define OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_MASK (1 << 0)
+#define OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT 0
+#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_SHIFT 0
+#define OMAP3430_EN_IVA2_DPLL_MASK (0x7 << 0)
+#define OMAP3430_ST_IVA2_SHIFT 0
+#define OMAP3430_ST_IVA2_CLK_MASK (1 << 0)
+#define OMAP3430_AUTO_IVA2_DPLL_SHIFT 0
+#define OMAP3430_AUTO_IVA2_DPLL_MASK (0x7 << 0)
+#define OMAP3430_IVA2_CLK_SRC_SHIFT 19
+#define OMAP3430_IVA2_CLK_SRC_WIDTH 3
+#define OMAP3430_IVA2_DPLL_MULT_MASK (0x7ff << 8)
+#define OMAP3430_IVA2_DPLL_DIV_MASK (0x7f << 0)
+#define OMAP3430_IVA2_DPLL_CLKOUT_DIV_SHIFT 0
+#define OMAP3430_IVA2_DPLL_CLKOUT_DIV_WIDTH 5
+#define OMAP3430_CLKTRCTRL_IVA2_MASK (0x3 << 0)
+#define OMAP3430_CLKACTIVITY_IVA2_MASK (1 << 0)
+#define OMAP3430_MPU_DPLL_FREQSEL_MASK (0xf << 4)
+#define OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT 3
+#define OMAP3430_EN_MPU_DPLL_MASK (0x7 << 0)
+#define OMAP3430_ST_MPU_CLK_SHIFT 0
+#define OMAP3430_ST_MPU_CLK_MASK (1 << 0)
+#define OMAP3430_ST_MPU_CLK_WIDTH 1
+#define OMAP3430_AUTO_MPU_DPLL_MASK (0x7 << 0)
+#define OMAP3430_MPU_CLK_SRC_SHIFT 19
+#define OMAP3430_MPU_CLK_SRC_WIDTH 3
+#define OMAP3430_MPU_DPLL_MULT_MASK (0x7ff << 8)
+#define OMAP3430_MPU_DPLL_DIV_MASK (0x7f << 0)
+#define OMAP3430_MPU_DPLL_CLKOUT_DIV_SHIFT 0
+#define OMAP3430_MPU_DPLL_CLKOUT_DIV_WIDTH 5
+#define OMAP3430_CLKTRCTRL_MPU_MASK (0x3 << 0)
+#define OMAP3430_EN_MODEM_SHIFT 31
+#define OMAP3430_EN_ICR_SHIFT 29
+#define OMAP3430_EN_AES2_SHIFT 28
+#define OMAP3430_EN_SHA12_SHIFT 27
+#define OMAP3430_EN_DES2_SHIFT 26
+#define OMAP3430ES1_EN_FAC_SHIFT 8
+#define OMAP3430_EN_MAILBOXES_SHIFT 7
+#define OMAP3430_EN_OMAPCTRL_SHIFT 6
+#define OMAP3430_EN_SAD2D_SHIFT 3
+#define OMAP3430_EN_SDRC_SHIFT 1
+#define AM35XX_EN_IPSS_SHIFT 4
+#define OMAP3430_EN_PKA_SHIFT 4
+#define OMAP3430_EN_AES1_SHIFT 3
+#define OMAP3430_EN_RNG_SHIFT 2
+#define OMAP3430_EN_SHA11_SHIFT 1
+#define OMAP3430_EN_DES1_SHIFT 0
+#define OMAP3430_EN_MAD2D_SHIFT 3
+#define OMAP3430ES2_EN_TS_SHIFT 1
+#define OMAP3430ES2_EN_CPEFUSE_SHIFT 0
+#define OMAP3430_ST_AES2_SHIFT 28
+#define OMAP3430_ST_SHA12_SHIFT 27
+#define AM35XX_ST_UART4_SHIFT 23
+#define OMAP3430_ST_HDQ_SHIFT 22
+#define OMAP3430ES2_ST_SSI_IDLE_SHIFT 8
+#define OMAP3430_ST_MAILBOXES_SHIFT 7
+#define OMAP3430_ST_SAD2D_SHIFT 3
+#define OMAP3430_ST_SDMA_SHIFT 2
+#define AM35XX_ST_IPSS_SHIFT 5
+#define OMAP3430ES2_ST_USBTLL_SHIFT 2
+#define OMAP3430_CLKSEL_SSI_MASK (0xf << 8)
+#define OMAP3430_CLKSEL_GPT11_MASK (1 << 7)
+#define OMAP3430_CLKSEL_GPT10_MASK (1 << 6)
+#define OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK (0x3 << 4)
+#define OMAP3430_CLKSEL_L4_SHIFT 2
+#define OMAP3430_CLKSEL_L4_WIDTH 2
+#define OMAP3430_CLKSEL_L3_SHIFT 0
+#define OMAP3430_CLKSEL_L3_WIDTH 2
+#define OMAP3630_CLKSEL_96M_MASK (0x3 << 12)
+#define OMAP3430ES1_CLKTRCTRL_D2D_MASK (0x3 << 4)
+#define OMAP3430_CLKTRCTRL_L4_MASK (0x3 << 2)
+#define OMAP3430_CLKTRCTRL_L3_MASK (0x3 << 0)
+#define OMAP3430ES1_EN_3D_SHIFT 2
+#define OMAP3430ES1_EN_2D_SHIFT 1
+#define OMAP3430ES1_CLKTRCTRL_GFX_MASK (0x3 << 0)
+#define OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT 1
+#define OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT 0
+#define OMAP3430ES2_CLKSEL_SGX_MASK (0x7 << 0)
+#define OMAP3430ES2_CLKTRCTRL_SGX_MASK (0x3 << 0)
+#define OMAP3430ES2_EN_USIMOCP_SHIFT 9
+#define OMAP3430_EN_WDT1_SHIFT 4
+#define OMAP3430_EN_32KSYNC_SHIFT 2
+#define OMAP3430_ST_WDT2_SHIFT 5
+#define OMAP3430_ST_32KSYNC_SHIFT 2
+#define OMAP3430ES2_CLKSEL_USIMOCP_MASK (0xf << 3)
+#define OMAP3430_CLKSEL_RM_SHIFT 1
+#define OMAP3430_CLKSEL_RM_WIDTH 2
+#define OMAP3430_CLKSEL_GPT1_MASK (1 << 0)
+#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_FREQSEL_MASK (0xf << 20)
+#define OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT 19
+#define OMAP3430_EN_PERIPH_DPLL_MASK (0x7 << 16)
+#define OMAP3430_PWRDN_EMU_CORE_SHIFT 12
+#define OMAP3430_CORE_DPLL_FREQSEL_MASK (0xf << 4)
+#define OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT 3
+#define OMAP3430_EN_CORE_DPLL_MASK (0x7 << 0)
+#define OMAP3430ES2_PERIPH2_DPLL_FREQSEL_MASK (0xf << 4)
+#define OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT 3
+#define OMAP3430ES2_EN_PERIPH2_DPLL_MASK (0x7 << 0)
+#define OMAP3430_ST_PERIPH_CLK_MASK (1 << 1)
+#define OMAP3430_ST_CORE_CLK_MASK (1 << 0)
+#define OMAP3430ES2_ST_PERIPH2_CLK_MASK (1 << 0)
+#define OMAP3430_AUTO_PERIPH_DPLL_MASK (0x7 << 3)
+#define OMAP3430_AUTO_CORE_DPLL_MASK (0x7 << 0)
+#define OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK (0x7 << 0)
+#define OMAP3430_CORE_DPLL_CLKOUT_DIV_SHIFT 27
+#define OMAP3430_CORE_DPLL_CLKOUT_DIV_WIDTH 5
+#define OMAP3430_CORE_DPLL_MULT_MASK (0x7ff << 16)
+#define OMAP3430_CORE_DPLL_DIV_MASK (0x7f << 8)
+#define OMAP3430_SOURCE_96M_SHIFT 6
+#define OMAP3430_SOURCE_96M_WIDTH 1
+#define OMAP3430_SOURCE_54M_SHIFT 5
+#define OMAP3430_SOURCE_54M_WIDTH 1
+#define OMAP3430_SOURCE_48M_MASK (1 << 3)
+#define OMAP3430_PERIPH_DPLL_MULT_MASK (0x7ff << 8)
+#define OMAP3630_PERIPH_DPLL_MULT_MASK (0xfff << 8)
+#define OMAP3430_PERIPH_DPLL_DIV_MASK (0x7f << 0)
+#define OMAP3630_PERIPH_DPLL_DCO_SEL_MASK (0x7 << 21)
+#define OMAP3630_PERIPH_DPLL_SD_DIV_MASK (0xff << 24)
+#define OMAP3430_DIV_96M_SHIFT 0
+#define OMAP3630_DIV_96M_WIDTH 6
+#define OMAP3430ES2_PERIPH2_DPLL_MULT_MASK (0x7ff << 8)
+#define OMAP3430ES2_PERIPH2_DPLL_DIV_MASK (0x7f << 0)
+#define OMAP3430ES2_DIV_120M_SHIFT 0
+#define OMAP3430ES2_DIV_120M_WIDTH 5
+#define OMAP3430_CLKOUT2_EN_SHIFT 7
+#define OMAP3430_CLKOUT2_DIV_SHIFT 3
+#define OMAP3430_CLKOUT2_DIV_WIDTH 3
+#define OMAP3430_CLKOUT2SOURCE_MASK (0x3 << 0)
+#define OMAP3430_EN_TV_SHIFT 2
+#define OMAP3430_EN_DSS2_SHIFT 1
+#define OMAP3430_EN_DSS1_SHIFT 0
+#define OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT 0
+#define OMAP3430ES2_ST_DSS_IDLE_SHIFT 1
+#define OMAP3430ES2_ST_DSS_STDBY_SHIFT 0
+#define OMAP3430ES1_ST_DSS_SHIFT 0
+#define OMAP3430_CLKSEL_TV_SHIFT 8
+#define OMAP3630_CLKSEL_TV_WIDTH 6
+#define OMAP3430_CLKSEL_DSS1_SHIFT 0
+#define OMAP3630_CLKSEL_DSS1_WIDTH 6
+#define OMAP3430_CLKTRCTRL_DSS_MASK (0x3 << 0)
+#define OMAP3430_EN_CSI2_SHIFT 1
+#define OMAP3430_CLKSEL_CAM_SHIFT 0
+#define OMAP3630_CLKSEL_CAM_WIDTH 6
+#define OMAP3430_CLKTRCTRL_CAM_MASK (0x3 << 0)
+#define OMAP3430_ST_MCBSP4_SHIFT 2
+#define OMAP3430_ST_MCBSP3_SHIFT 1
+#define OMAP3430_ST_MCBSP2_SHIFT 0
+#define OMAP3430_CLKSEL_GPT9_MASK (1 << 7)
+#define OMAP3430_CLKSEL_GPT8_MASK (1 << 6)
+#define OMAP3430_CLKSEL_GPT7_MASK (1 << 5)
+#define OMAP3430_CLKSEL_GPT6_MASK (1 << 4)
+#define OMAP3430_CLKSEL_GPT5_MASK (1 << 3)
+#define OMAP3430_CLKSEL_GPT4_MASK (1 << 2)
+#define OMAP3430_CLKSEL_GPT3_MASK (1 << 1)
+#define OMAP3430_CLKSEL_GPT2_MASK (1 << 0)
+#define OMAP3430_CLKTRCTRL_PER_MASK (0x3 << 0)
+#define OMAP3430_DIV_DPLL4_SHIFT 24
+#define OMAP3630_DIV_DPLL4_WIDTH 6
+#define OMAP3430_DIV_DPLL3_SHIFT 16
+#define OMAP3430_DIV_DPLL3_WIDTH 5
+#define OMAP3430_CLKSEL_TRACECLK_SHIFT 11
+#define OMAP3430_CLKSEL_TRACECLK_WIDTH 3
+#define OMAP3430_CLKSEL_PCLK_SHIFT 8
+#define OMAP3430_CLKSEL_PCLK_WIDTH 3
+#define OMAP3430_CLKSEL_PCLKX2_SHIFT 6
+#define OMAP3430_CLKSEL_PCLKX2_WIDTH 2
+#define OMAP3430_CLKSEL_ATCLK_SHIFT 4
+#define OMAP3430_CLKSEL_ATCLK_WIDTH 2
+#define OMAP3430_TRACE_MUX_CTRL_SHIFT 2
+#define OMAP3430_TRACE_MUX_CTRL_WIDTH 2
+#define OMAP3430_MUX_CTRL_MASK (0x3 << 0)
+#define OMAP3430_CLKTRCTRL_EMU_MASK (0x3 << 0)
+#define OMAP3430_CLKTRCTRL_NEON_MASK (0x3 << 0)
+#define OMAP3430ES2_EN_USBHOST2_SHIFT 1
+#define OMAP3430ES2_EN_USBHOST1_SHIFT 0
+#define OMAP3430ES2_EN_USBHOST_SHIFT 0
+#define OMAP3430ES2_ST_USBHOST_IDLE_SHIFT 1
+#define OMAP3430ES2_ST_USBHOST_STDBY_SHIFT 0
+#define OMAP3430ES2_CLKTRCTRL_USBHOST_MASK (3 << 0)
+#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 000000000..4dbbd99b6
--- /dev/null
+++ b/arch/arm/mach-omap2/cm-regbits-44xx.h
@@ -0,0 +1,146 @@
+/*
+ * OMAP44xx Clock Management register bits
+ *
+ * Copyright (C) 2009-2012 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
+
+#define OMAP4430_ABE_STATDEP_SHIFT 3
+#define OMAP4430_AUTO_DPLL_MODE_MASK (0x7 << 0)
+#define OMAP4430_CLKSEL_SHIFT 24
+#define OMAP4430_CLKSEL_WIDTH 0x1
+#define OMAP4430_CLKSEL_MASK (1 << 24)
+#define OMAP4430_CLKSEL_0_0_SHIFT 0
+#define OMAP4430_CLKSEL_0_0_WIDTH 0x1
+#define OMAP4430_CLKSEL_0_1_SHIFT 0
+#define OMAP4430_CLKSEL_0_1_WIDTH 0x2
+#define OMAP4430_CLKSEL_24_25_SHIFT 24
+#define OMAP4430_CLKSEL_24_25_WIDTH 0x2
+#define OMAP4430_CLKSEL_60M_SHIFT 24
+#define OMAP4430_CLKSEL_60M_WIDTH 0x1
+#define OMAP4430_CLKSEL_AESS_FCLK_SHIFT 24
+#define OMAP4430_CLKSEL_AESS_FCLK_WIDTH 0x1
+#define OMAP4430_CLKSEL_CORE_SHIFT 0
+#define OMAP4430_CLKSEL_CORE_WIDTH 0x1
+#define OMAP4430_CLKSEL_DIV_SHIFT 24
+#define OMAP4430_CLKSEL_DIV_WIDTH 0x1
+#define OMAP4430_CLKSEL_FCLK_SHIFT 24
+#define OMAP4430_CLKSEL_FCLK_WIDTH 0x2
+#define OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT 25
+#define OMAP4430_CLKSEL_INTERNAL_SOURCE_WIDTH 0x1
+#define OMAP4430_CLKSEL_L3_SHIFT 4
+#define OMAP4430_CLKSEL_L3_WIDTH 0x1
+#define OMAP4430_CLKSEL_L4_SHIFT 8
+#define OMAP4430_CLKSEL_L4_WIDTH 0x1
+#define OMAP4430_CLKSEL_OPP_SHIFT 0
+#define OMAP4430_CLKSEL_OPP_WIDTH 0x2
+#define OMAP4430_CLKSEL_PMD_STM_CLK_SHIFT 27
+#define OMAP4430_CLKSEL_PMD_STM_CLK_WIDTH 0x3
+#define OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK (0x7 << 24)
+#define OMAP4430_CLKSEL_SGX_FCLK_MASK (1 << 24)
+#define OMAP4430_CLKSEL_SOURCE_MASK (0x3 << 24)
+#define OMAP4430_CLKSEL_SOURCE_24_24_MASK (1 << 24)
+#define OMAP4430_CLKSEL_UTMI_P1_SHIFT 24
+#define OMAP4430_CLKSEL_UTMI_P1_WIDTH 0x1
+#define OMAP4430_CLKSEL_UTMI_P2_SHIFT 25
+#define OMAP4430_CLKSEL_UTMI_P2_WIDTH 0x1
+#define OMAP4430_CLKTRCTRL_SHIFT 0
+#define OMAP4430_CLKTRCTRL_MASK (0x3 << 0)
+#define OMAP4430_DPLL_BYP_CLKSEL_SHIFT 23
+#define OMAP4430_DPLL_BYP_CLKSEL_WIDTH 0x1
+#define OMAP4430_DPLL_CLKOUTHIF_DIV_MASK (0x1f << 0)
+#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT 8
+#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK (1 << 10)
+#define OMAP4430_DPLL_CLKOUT_DIV_SHIFT 0
+#define OMAP4430_DPLL_CLKOUT_DIV_WIDTH 0x5
+#define OMAP4430_DPLL_CLKOUT_DIV_MASK (0x1f << 0)
+#define OMAP4430_DPLL_CLKOUT_DIV_0_6_MASK (0x7f << 0)
+#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK (1 << 8)
+#define OMAP4430_DPLL_DIV_MASK (0x7f << 0)
+#define OMAP4430_DPLL_DIV_0_7_MASK (0xff << 0)
+#define OMAP4430_DPLL_EN_MASK (0x7 << 0)
+#define OMAP4430_DPLL_LPMODE_EN_MASK (1 << 10)
+#define OMAP4430_DPLL_MULT_MASK (0x7ff << 8)
+#define OMAP4430_DPLL_MULT_USB_MASK (0xfff << 8)
+#define OMAP4430_DPLL_REGM4XEN_MASK (1 << 11)
+#define OMAP4430_DPLL_SD_DIV_MASK (0xff << 24)
+#define OMAP4430_DSS_STATDEP_SHIFT 8
+#define OMAP4430_DUCATI_STATDEP_SHIFT 0
+#define OMAP4430_GFX_STATDEP_SHIFT 10
+#define OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK (0x1f << 0)
+#define OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK (0x1f << 0)
+#define OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK (0x1f << 0)
+#define OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK (0x1f << 0)
+#define OMAP4430_IDLEST_SHIFT 16
+#define OMAP4430_IDLEST_MASK (0x3 << 16)
+#define OMAP4430_IVAHD_STATDEP_SHIFT 2
+#define OMAP4430_L3INIT_STATDEP_SHIFT 7
+#define OMAP4430_L3_1_STATDEP_SHIFT 5
+#define OMAP4430_L3_2_STATDEP_SHIFT 6
+#define OMAP4430_L4CFG_STATDEP_SHIFT 12
+#define OMAP4430_L4PER_STATDEP_SHIFT 13
+#define OMAP4430_L4SEC_STATDEP_SHIFT 14
+#define OMAP4430_L4WKUP_STATDEP_SHIFT 15
+#define OMAP4430_MEMIF_STATDEP_SHIFT 4
+#define OMAP4430_MODULEMODE_SHIFT 0
+#define OMAP4430_MODULEMODE_MASK (0x3 << 0)
+#define OMAP4430_OPTFCLKEN_48MHZ_CLK_SHIFT 9
+#define OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT 8
+#define OMAP4430_OPTFCLKEN_CLK32K_SHIFT 8
+#define OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_DBCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_DSSCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_FCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_FCLK0_SHIFT 8
+#define OMAP4430_OPTFCLKEN_FCLK1_SHIFT 9
+#define OMAP4430_OPTFCLKEN_FCLK2_SHIFT 10
+#define OMAP4430_OPTFCLKEN_FUNC48MCLK_SHIFT 15
+#define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT 13
+#define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT 14
+#define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT 11
+#define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT 12
+#define OMAP4430_OPTFCLKEN_PER24MC_GFCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT 9
+#define OMAP4430_OPTFCLKEN_PHY_48M_SHIFT 8
+#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT 10
+#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT 11
+#define OMAP4430_OPTFCLKEN_SYS_CLK_SHIFT 10
+#define OMAP4460_OPTFCLKEN_TS_FCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_TV_CLK_SHIFT 11
+#define OMAP4430_OPTFCLKEN_USB_CH0_CLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_USB_CH1_CLK_SHIFT 9
+#define OMAP4430_OPTFCLKEN_USB_CH2_CLK_SHIFT 10
+#define OMAP4430_OPTFCLKEN_UTMI_P1_CLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_UTMI_P2_CLK_SHIFT 9
+#define OMAP4430_OPTFCLKEN_UTMI_P3_CLK_SHIFT 10
+#define OMAP4430_OPTFCLKEN_XCLK_SHIFT 8
+#define OMAP4430_PAD_CLKS_GATE_SHIFT 8
+#define OMAP4430_PMD_STM_MUX_CTRL_SHIFT 20
+#define OMAP4430_PMD_STM_MUX_CTRL_WIDTH 0x2
+#define OMAP4430_PMD_TRACE_MUX_CTRL_SHIFT 22
+#define OMAP4430_PMD_TRACE_MUX_CTRL_WIDTH 0x2
+#define OMAP4430_SCALE_FCLK_SHIFT 0
+#define OMAP4430_SCALE_FCLK_WIDTH 0x1
+#define OMAP4430_SLIMBUS_CLK_GATE_SHIFT 10
+#define OMAP4430_ST_DPLL_CLK_MASK (1 << 0)
+#define OMAP4430_SYS_CLKSEL_SHIFT 0
+#define OMAP4430_SYS_CLKSEL_WIDTH 0x3
+#define OMAP4430_TESLA_STATDEP_SHIFT 1
+#endif
diff --git a/arch/arm/mach-omap2/cm-regbits-54xx.h b/arch/arm/mach-omap2/cm-regbits-54xx.h
new file mode 100644
index 000000000..896ae9fc4
--- /dev/null
+++ b/arch/arm/mach-omap2/cm-regbits-54xx.h
@@ -0,0 +1,104 @@
+/*
+ * OMAP54xx Clock Management register bits
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * 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_54XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM_REGBITS_54XX_H
+
+#define OMAP54XX_ABE_STATDEP_SHIFT 3
+#define OMAP54XX_AUTO_DPLL_MODE_MASK (0x7 << 0)
+#define OMAP54XX_CLKSEL_SHIFT 24
+#define OMAP54XX_CLKSEL_WIDTH 0x1
+#define OMAP54XX_CLKSEL_0_0_SHIFT 0
+#define OMAP54XX_CLKSEL_0_0_WIDTH 0x1
+#define OMAP54XX_CLKSEL_AESS_FCLK_SHIFT 24
+#define OMAP54XX_CLKSEL_AESS_FCLK_WIDTH 0x1
+#define OMAP54XX_CLKSEL_DIV_SHIFT 25
+#define OMAP54XX_CLKSEL_DIV_WIDTH 0x1
+#define OMAP54XX_CLKSEL_FCLK_SHIFT 24
+#define OMAP54XX_CLKSEL_FCLK_WIDTH 0x1
+#define OMAP54XX_CLKSEL_GPU_CORE_GCLK_SHIFT 24
+#define OMAP54XX_CLKSEL_GPU_CORE_GCLK_WIDTH 0x1
+#define OMAP54XX_CLKSEL_GPU_HYD_GCLK_SHIFT 25
+#define OMAP54XX_CLKSEL_GPU_HYD_GCLK_WIDTH 0x1
+#define OMAP54XX_CLKSEL_INTERNAL_SOURCE_SHIFT 26
+#define OMAP54XX_CLKSEL_INTERNAL_SOURCE_WIDTH 0x2
+#define OMAP54XX_CLKSEL_OPP_SHIFT 0
+#define OMAP54XX_CLKSEL_OPP_WIDTH 0x2
+#define OMAP54XX_CLKSEL_SOURCE_SHIFT 24
+#define OMAP54XX_CLKSEL_SOURCE_WIDTH 0x2
+#define OMAP54XX_CLKSEL_SOURCE_L3INIT_MMC1_SHIFT 24
+#define OMAP54XX_CLKSEL_SOURCE_L3INIT_MMC1_WIDTH 0x1
+#define OMAP54XX_CLKSEL_UTMI_P1_SHIFT 24
+#define OMAP54XX_CLKSEL_UTMI_P1_WIDTH 0x1
+#define OMAP54XX_CLKSEL_UTMI_P2_SHIFT 25
+#define OMAP54XX_CLKSEL_UTMI_P2_WIDTH 0x1
+#define OMAP54XX_DIVHS_MASK (0x3f << 0)
+#define OMAP54XX_DIVHS_0_4_MASK (0x1f << 0)
+#define OMAP54XX_DIVHS_0_6_MASK (0x7f << 0)
+#define OMAP54XX_DPLL_DIV_MASK (0x7f << 0)
+#define OMAP54XX_DPLL_EN_MASK (0x7 << 0)
+#define OMAP54XX_DPLL_LPMODE_EN_MASK (1 << 10)
+#define OMAP54XX_DPLL_MULT_MASK (0x7ff << 8)
+#define OMAP54XX_DPLL_REGM4XEN_MASK (1 << 11)
+#define OMAP54XX_DPLL_SD_DIV_MASK (0xff << 24)
+#define OMAP54XX_DSP_STATDEP_SHIFT 1
+#define OMAP54XX_DSS_STATDEP_SHIFT 8
+#define OMAP54XX_EMIF_STATDEP_SHIFT 4
+#define OMAP54XX_GPU_STATDEP_SHIFT 10
+#define OMAP54XX_IPU_STATDEP_SHIFT 0
+#define OMAP54XX_IVA_STATDEP_SHIFT 2
+#define OMAP54XX_L3INIT_STATDEP_SHIFT 7
+#define OMAP54XX_L3MAIN1_STATDEP_SHIFT 5
+#define OMAP54XX_L3MAIN2_STATDEP_SHIFT 6
+#define OMAP54XX_L4CFG_STATDEP_SHIFT 12
+#define OMAP54XX_L4PER_STATDEP_SHIFT 13
+#define OMAP54XX_L4SEC_STATDEP_SHIFT 14
+#define OMAP54XX_OPTFCLKEN_32KHZ_CLK_SHIFT 11
+#define OMAP54XX_OPTFCLKEN_32KHZ_CLK_8_8_SHIFT 8
+#define OMAP54XX_OPTFCLKEN_48MHZ_CLK_SHIFT 9
+#define OMAP54XX_OPTFCLKEN_CLK32K_SHIFT 8
+#define OMAP54XX_OPTFCLKEN_CTRLCLK_SHIFT 8
+#define OMAP54XX_OPTFCLKEN_DBCLK_SHIFT 8
+#define OMAP54XX_OPTFCLKEN_DSSCLK_SHIFT 8
+#define OMAP54XX_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT 13
+#define OMAP54XX_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT 14
+#define OMAP54XX_OPTFCLKEN_HSIC480M_P3_CLK_SHIFT 7
+#define OMAP54XX_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT 11
+#define OMAP54XX_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT 12
+#define OMAP54XX_OPTFCLKEN_HSIC60M_P3_CLK_SHIFT 6
+#define OMAP54XX_OPTFCLKEN_REFCLK960M_SHIFT 8
+#define OMAP54XX_OPTFCLKEN_REF_CLK_SHIFT 8
+#define OMAP54XX_OPTFCLKEN_SLIMBUS_CLK_SHIFT 11
+#define OMAP54XX_OPTFCLKEN_SYS_CLK_SHIFT 10
+#define OMAP54XX_OPTFCLKEN_TXPHY_CLK_SHIFT 8
+#define OMAP54XX_OPTFCLKEN_TXPHY_LS_CLK_SHIFT 9
+#define OMAP54XX_OPTFCLKEN_USB_CH0_CLK_SHIFT 8
+#define OMAP54XX_OPTFCLKEN_USB_CH1_CLK_SHIFT 9
+#define OMAP54XX_OPTFCLKEN_USB_CH2_CLK_SHIFT 10
+#define OMAP54XX_OPTFCLKEN_UTMI_P1_CLK_SHIFT 8
+#define OMAP54XX_OPTFCLKEN_UTMI_P2_CLK_SHIFT 9
+#define OMAP54XX_OPTFCLKEN_UTMI_P3_CLK_SHIFT 10
+#define OMAP54XX_PAD_CLKS_GATE_SHIFT 8
+#define OMAP54XX_SLIMBUS1_CLK_GATE_SHIFT 10
+#define OMAP54XX_ST_DPLL_CLK_MASK (1 << 0)
+#define OMAP54XX_SYS_CLKSEL_SHIFT 0
+#define OMAP54XX_SYS_CLKSEL_WIDTH 0x3
+#define OMAP54XX_WKUPAON_STATDEP_SHIFT 15
+#endif
diff --git a/arch/arm/mach-omap2/cm-regbits-7xx.h b/arch/arm/mach-omap2/cm-regbits-7xx.h
new file mode 100644
index 000000000..ad8f81ce9
--- /dev/null
+++ b/arch/arm/mach-omap2/cm-regbits-7xx.h
@@ -0,0 +1,51 @@
+/*
+ * DRA7xx Clock Management register bits
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Generated by code originally written by:
+ * 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_7XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM_REGBITS_7XX_H
+
+#define DRA7XX_ATL_STATDEP_SHIFT 30
+#define DRA7XX_CAM_STATDEP_SHIFT 9
+#define DRA7XX_DSP1_STATDEP_SHIFT 1
+#define DRA7XX_DSP2_STATDEP_SHIFT 18
+#define DRA7XX_DSS_STATDEP_SHIFT 8
+#define DRA7XX_EMIF_STATDEP_SHIFT 4
+#define DRA7XX_EVE1_STATDEP_SHIFT 19
+#define DRA7XX_EVE2_STATDEP_SHIFT 20
+#define DRA7XX_EVE3_STATDEP_SHIFT 21
+#define DRA7XX_EVE4_STATDEP_SHIFT 22
+#define DRA7XX_GMAC_STATDEP_SHIFT 25
+#define DRA7XX_GPU_STATDEP_SHIFT 10
+#define DRA7XX_IPU1_STATDEP_SHIFT 23
+#define DRA7XX_IPU2_STATDEP_SHIFT 0
+#define DRA7XX_IPU_STATDEP_SHIFT 24
+#define DRA7XX_IVA_STATDEP_SHIFT 2
+#define DRA7XX_L3INIT_STATDEP_SHIFT 7
+#define DRA7XX_L3MAIN1_STATDEP_SHIFT 5
+#define DRA7XX_L4CFG_STATDEP_SHIFT 12
+#define DRA7XX_L4PER2_STATDEP_SHIFT 26
+#define DRA7XX_L4PER3_STATDEP_SHIFT 27
+#define DRA7XX_L4PER_STATDEP_SHIFT 13
+#define DRA7XX_L4SEC_STATDEP_SHIFT 14
+#define DRA7XX_PCIE_STATDEP_SHIFT 29
+#define DRA7XX_VPE_STATDEP_SHIFT 28
+#define DRA7XX_WKUPAON_STATDEP_SHIFT 15
+#endif
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
new file mode 100644
index 000000000..1fe3e6b83
--- /dev/null
+++ b/arch/arm/mach-omap2/cm.h
@@ -0,0 +1,78 @@
+/*
+ * OMAP2+ Clock Management prototypes
+ *
+ * Copyright (C) 2007-2009, 2012 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
+
+# ifndef __ASSEMBLER__
+extern void __iomem *cm_base;
+extern void __iomem *cm2_base;
+extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2);
+# endif
+
+/*
+ * MAX_MODULE_DISABLE_TIME: max duration in microseconds to wait for
+ * the PRCM to request that a module enter 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 inactive state from
+ * a functional state.
+ * XXX FSUSB on OMAP4430 takes ~4ms to idle after reset during
+ * kernel init.
+ */
+#define MAX_MODULE_DISABLE_TIME 5000
+
+# ifndef __ASSEMBLER__
+
+/**
+ * struct cm_ll_data - fn ptrs to per-SoC CM function implementations
+ * @split_idlest_reg: ptr to the SoC CM-specific split_idlest_reg impl
+ * @wait_module_ready: ptr to the SoC CM-specific wait_module_ready impl
+ * @wait_module_idle: ptr to the SoC CM-specific wait_module_idle impl
+ * @module_enable: ptr to the SoC CM-specific module_enable impl
+ * @module_disable: ptr to the SoC CM-specific module_disable impl
+ */
+struct cm_ll_data {
+ int (*split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst,
+ u8 *idlest_reg_id);
+ int (*wait_module_ready)(u8 part, s16 prcm_mod, u16 idlest_reg,
+ u8 idlest_shift);
+ int (*wait_module_idle)(u8 part, s16 prcm_mod, u16 idlest_reg,
+ u8 idlest_shift);
+ void (*module_enable)(u8 mode, u8 part, u16 inst, u16 clkctrl_offs);
+ void (*module_disable)(u8 part, u16 inst, u16 clkctrl_offs);
+};
+
+extern int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
+ u8 *idlest_reg_id);
+int omap_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_reg,
+ u8 idlest_shift);
+int omap_cm_wait_module_idle(u8 part, s16 prcm_mod, u16 idlest_reg,
+ u8 idlest_shift);
+int omap_cm_module_enable(u8 mode, u8 part, u16 inst, u16 clkctrl_offs);
+int omap_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs);
+extern int cm_register(struct cm_ll_data *cld);
+extern int cm_unregister(struct cm_ll_data *cld);
+int omap_cm_init(void);
+int omap2_cm_base_init(void);
+
+# endif
+
+#endif
diff --git a/arch/arm/mach-omap2/cm1_44xx.h b/arch/arm/mach-omap2/cm1_44xx.h
new file mode 100644
index 000000000..a5949927b
--- /dev/null
+++ b/arch/arm/mach-omap2/cm1_44xx.h
@@ -0,0 +1,220 @@
+/*
+ * OMAP44xx CM1 instance offset macros
+ *
+ * Copyright (C) 2009-2011 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_MPU_MPU_CDOFFS 0x0000
+#define OMAP4430_CM1_TESLA_TESLA_CDOFFS 0x0000
+#define OMAP4430_CM1_ABE_ABE_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_MODFREQDIV_DPLL_CORE_OFFSET 0x004c
+#define OMAP4430_CM_SSC_MODFREQDIV_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_MODFREQDIV_DPLL_MPU_OFFSET 0x008c
+#define OMAP4430_CM_SSC_MODFREQDIV_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_MODFREQDIV_DPLL_IVA_OFFSET 0x00cc
+#define OMAP4430_CM_SSC_MODFREQDIV_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_MODFREQDIV_DPLL_ABE_OFFSET 0x010c
+#define OMAP4430_CM_SSC_MODFREQDIV_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_MODFREQDIV_DPLL_DDRPHY_OFFSET 0x014c
+#define OMAP4430_CM_SSC_MODFREQDIV_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)
+
+#endif
diff --git a/arch/arm/mach-omap2/cm1_54xx.h b/arch/arm/mach-omap2/cm1_54xx.h
new file mode 100644
index 000000000..fd245dfa7
--- /dev/null
+++ b/arch/arm/mach-omap2/cm1_54xx.h
@@ -0,0 +1,211 @@
+/*
+ * OMAP54xx CM1 instance offset macros
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * 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_CM1_54XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM1_54XX_H
+
+/* CM1 base address */
+#define OMAP54XX_CM_CORE_AON_BASE 0x4a004000
+
+#define OMAP54XX_CM_CORE_AON_REGADDR(inst, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_AON_BASE + (inst) + (reg))
+
+/* CM_CORE_AON instances */
+#define OMAP54XX_CM_CORE_AON_OCP_SOCKET_INST 0x0000
+#define OMAP54XX_CM_CORE_AON_CKGEN_INST 0x0100
+#define OMAP54XX_CM_CORE_AON_MPU_INST 0x0300
+#define OMAP54XX_CM_CORE_AON_DSP_INST 0x0400
+#define OMAP54XX_CM_CORE_AON_ABE_INST 0x0500
+#define OMAP54XX_CM_CORE_AON_RESTORE_INST 0x0e00
+#define OMAP54XX_CM_CORE_AON_INSTR_INST 0x0f00
+
+/* CM_CORE_AON clockdomain register offsets (from instance start) */
+#define OMAP54XX_CM_CORE_AON_MPU_MPU_CDOFFS 0x0000
+#define OMAP54XX_CM_CORE_AON_DSP_DSP_CDOFFS 0x0000
+#define OMAP54XX_CM_CORE_AON_ABE_ABE_CDOFFS 0x0000
+
+/* CM_CORE_AON */
+
+/* CM_CORE_AON.OCP_SOCKET_CM_CORE_AON register offsets */
+#define OMAP54XX_REVISION_CM_CORE_AON_OFFSET 0x0000
+#define OMAP54XX_CM_CM_CORE_AON_PROFILING_CLKCTRL_OFFSET 0x0040
+#define OMAP54XX_CM_CM_CORE_AON_PROFILING_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_OCP_SOCKET_INST, 0x0040)
+#define OMAP54XX_CM_CORE_AON_DEBUG_CFG_OFFSET 0x0080
+#define OMAP54XX_CM_CORE_AON_DEBUG_OUT_OFFSET 0x0084
+#define OMAP54XX_CM_CORE_AON_DEBUG_MPU_FD_TRANS_OFFSET 0x0090
+#define OMAP54XX_CM_CORE_AON_DEBUG_DSP_FD_TRANS_OFFSET 0x0094
+#define OMAP54XX_CM_CORE_AON_DEBUG_ABE_FD_TRANS_OFFSET 0x0098
+#define OMAP54XX_CM_CORE_AON_DEBUG_ABE_FD_TRANS2_OFFSET 0x009c
+#define OMAP54XX_CM_CORE_AON_DEBUG_CM_CORE_AON_FD_TRANS_OFFSET 0x00a0
+#define OMAP54XX_CM_CORE_AON_DEBUG_C2C_FD_TRANS_OFFSET 0x00a4
+#define OMAP54XX_CM_CORE_AON_DEBUG_CAM_FD_TRANS_OFFSET 0x00a8
+#define OMAP54XX_CM_CORE_AON_DEBUG_COREAON_FD_TRANS_OFFSET 0x00ac
+#define OMAP54XX_CM_CORE_AON_DEBUG_CUSTEFUSE_FD_TRANS_OFFSET 0x00b0
+#define OMAP54XX_CM_CORE_AON_DEBUG_DMA_FD_TRANS_OFFSET 0x00b4
+#define OMAP54XX_CM_CORE_AON_DEBUG_DSS_FD_TRANS_OFFSET 0x00b8
+#define OMAP54XX_CM_CORE_AON_DEBUG_EMIF_FD_TRANS_OFFSET 0x00bc
+#define OMAP54XX_CM_CORE_AON_DEBUG_GPU_FD_TRANS_OFFSET 0x00c0
+#define OMAP54XX_CM_CORE_AON_DEBUG_IPU_FD_TRANS_OFFSET 0x00c4
+#define OMAP54XX_CM_CORE_AON_DEBUG_IVA_FD_TRANS_OFFSET 0x00c8
+#define OMAP54XX_CM_CORE_AON_DEBUG_L3INIT_FD_TRANS_OFFSET 0x00cc
+#define OMAP54XX_CM_CORE_AON_DEBUG_L3INIT_FD_TRANS2_OFFSET 0x00d0
+#define OMAP54XX_CM_CORE_AON_DEBUG_L3INSTR_FD_TRANS_OFFSET 0x00d4
+#define OMAP54XX_CM_CORE_AON_DEBUG_L3MAIN1_FD_TRANS_OFFSET 0x00d8
+#define OMAP54XX_CM_CORE_AON_DEBUG_L3MAIN2_FD_TRANS_OFFSET 0x00dc
+#define OMAP54XX_CM_CORE_AON_DEBUG_L4CFG_FD_TRANS_OFFSET 0x00e0
+#define OMAP54XX_CM_CORE_AON_DEBUG_L4PER_FD_TRANS_OFFSET 0x00e4
+#define OMAP54XX_CM_CORE_AON_DEBUG_L4PER_FD_TRANS2_OFFSET 0x00e8
+#define OMAP54XX_CM_CORE_AON_DEBUG_L4SEC_FD_TRANS_OFFSET 0x00ec
+#define OMAP54XX_CM_CORE_AON_DEBUG_MIPIEXT_FD_TRANS_OFFSET 0x00f0
+
+/* CM_CORE_AON.CKGEN_CM_CORE_AON register offsets */
+#define OMAP54XX_CM_CLKSEL_CORE_OFFSET 0x0000
+#define OMAP54XX_CM_CLKSEL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0000)
+#define OMAP54XX_CM_CLKSEL_ABE_OFFSET 0x0008
+#define OMAP54XX_CM_CLKSEL_ABE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0008)
+#define OMAP54XX_CM_DLL_CTRL_OFFSET 0x0010
+#define OMAP54XX_CM_CLKMODE_DPLL_CORE_OFFSET 0x0020
+#define OMAP54XX_CM_CLKMODE_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0020)
+#define OMAP54XX_CM_IDLEST_DPLL_CORE_OFFSET 0x0024
+#define OMAP54XX_CM_IDLEST_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0024)
+#define OMAP54XX_CM_AUTOIDLE_DPLL_CORE_OFFSET 0x0028
+#define OMAP54XX_CM_AUTOIDLE_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0028)
+#define OMAP54XX_CM_CLKSEL_DPLL_CORE_OFFSET 0x002c
+#define OMAP54XX_CM_CLKSEL_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x002c)
+#define OMAP54XX_CM_DIV_M2_DPLL_CORE_OFFSET 0x0030
+#define OMAP54XX_CM_DIV_M2_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0030)
+#define OMAP54XX_CM_DIV_M3_DPLL_CORE_OFFSET 0x0034
+#define OMAP54XX_CM_DIV_M3_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0034)
+#define OMAP54XX_CM_DIV_H11_DPLL_CORE_OFFSET 0x0038
+#define OMAP54XX_CM_DIV_H11_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0038)
+#define OMAP54XX_CM_DIV_H12_DPLL_CORE_OFFSET 0x003c
+#define OMAP54XX_CM_DIV_H12_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x003c)
+#define OMAP54XX_CM_DIV_H13_DPLL_CORE_OFFSET 0x0040
+#define OMAP54XX_CM_DIV_H13_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0040)
+#define OMAP54XX_CM_DIV_H14_DPLL_CORE_OFFSET 0x0044
+#define OMAP54XX_CM_DIV_H14_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0044)
+#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_CORE_OFFSET 0x0048
+#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_CORE_OFFSET 0x004c
+#define OMAP54XX_CM_DIV_H21_DPLL_CORE_OFFSET 0x0050
+#define OMAP54XX_CM_DIV_H21_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0050)
+#define OMAP54XX_CM_DIV_H22_DPLL_CORE_OFFSET 0x0054
+#define OMAP54XX_CM_DIV_H22_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0054)
+#define OMAP54XX_CM_DIV_H23_DPLL_CORE_OFFSET 0x0058
+#define OMAP54XX_CM_DIV_H23_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0058)
+#define OMAP54XX_CM_DIV_H24_DPLL_CORE_OFFSET 0x005c
+#define OMAP54XX_CM_DIV_H24_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x005c)
+#define OMAP54XX_CM_CLKMODE_DPLL_MPU_OFFSET 0x0060
+#define OMAP54XX_CM_CLKMODE_DPLL_MPU OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0060)
+#define OMAP54XX_CM_IDLEST_DPLL_MPU_OFFSET 0x0064
+#define OMAP54XX_CM_IDLEST_DPLL_MPU OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0064)
+#define OMAP54XX_CM_AUTOIDLE_DPLL_MPU_OFFSET 0x0068
+#define OMAP54XX_CM_AUTOIDLE_DPLL_MPU OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0068)
+#define OMAP54XX_CM_CLKSEL_DPLL_MPU_OFFSET 0x006c
+#define OMAP54XX_CM_CLKSEL_DPLL_MPU OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x006c)
+#define OMAP54XX_CM_DIV_M2_DPLL_MPU_OFFSET 0x0070
+#define OMAP54XX_CM_DIV_M2_DPLL_MPU OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0070)
+#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_MPU_OFFSET 0x0088
+#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_MPU_OFFSET 0x008c
+#define OMAP54XX_CM_BYPCLK_DPLL_MPU_OFFSET 0x009c
+#define OMAP54XX_CM_BYPCLK_DPLL_MPU OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x009c)
+#define OMAP54XX_CM_CLKMODE_DPLL_IVA_OFFSET 0x00a0
+#define OMAP54XX_CM_CLKMODE_DPLL_IVA OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00a0)
+#define OMAP54XX_CM_IDLEST_DPLL_IVA_OFFSET 0x00a4
+#define OMAP54XX_CM_IDLEST_DPLL_IVA OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00a4)
+#define OMAP54XX_CM_AUTOIDLE_DPLL_IVA_OFFSET 0x00a8
+#define OMAP54XX_CM_AUTOIDLE_DPLL_IVA OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00a8)
+#define OMAP54XX_CM_CLKSEL_DPLL_IVA_OFFSET 0x00ac
+#define OMAP54XX_CM_CLKSEL_DPLL_IVA OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00ac)
+#define OMAP54XX_CM_DIV_H11_DPLL_IVA_OFFSET 0x00b8
+#define OMAP54XX_CM_DIV_H11_DPLL_IVA OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00b8)
+#define OMAP54XX_CM_DIV_H12_DPLL_IVA_OFFSET 0x00bc
+#define OMAP54XX_CM_DIV_H12_DPLL_IVA OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00bc)
+#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_IVA_OFFSET 0x00c8
+#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_IVA_OFFSET 0x00cc
+#define OMAP54XX_CM_BYPCLK_DPLL_IVA_OFFSET 0x00dc
+#define OMAP54XX_CM_BYPCLK_DPLL_IVA OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00dc)
+#define OMAP54XX_CM_CLKMODE_DPLL_ABE_OFFSET 0x00e0
+#define OMAP54XX_CM_CLKMODE_DPLL_ABE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00e0)
+#define OMAP54XX_CM_IDLEST_DPLL_ABE_OFFSET 0x00e4
+#define OMAP54XX_CM_IDLEST_DPLL_ABE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00e4)
+#define OMAP54XX_CM_AUTOIDLE_DPLL_ABE_OFFSET 0x00e8
+#define OMAP54XX_CM_AUTOIDLE_DPLL_ABE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00e8)
+#define OMAP54XX_CM_CLKSEL_DPLL_ABE_OFFSET 0x00ec
+#define OMAP54XX_CM_CLKSEL_DPLL_ABE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00ec)
+#define OMAP54XX_CM_DIV_M2_DPLL_ABE_OFFSET 0x00f0
+#define OMAP54XX_CM_DIV_M2_DPLL_ABE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00f0)
+#define OMAP54XX_CM_DIV_M3_DPLL_ABE_OFFSET 0x00f4
+#define OMAP54XX_CM_DIV_M3_DPLL_ABE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00f4)
+#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_ABE_OFFSET 0x0108
+#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_ABE_OFFSET 0x010c
+#define OMAP54XX_CM_SHADOW_FREQ_CONFIG1_OFFSET 0x0160
+#define OMAP54XX_CM_SHADOW_FREQ_CONFIG2_OFFSET 0x0164
+#define OMAP54XX_CM_DYN_DEP_PRESCAL_OFFSET 0x0170
+#define OMAP54XX_CM_RESTORE_ST_OFFSET 0x0180
+
+/* CM_CORE_AON.MPU_CM_CORE_AON register offsets */
+#define OMAP54XX_CM_MPU_CLKSTCTRL_OFFSET 0x0000
+#define OMAP54XX_CM_MPU_STATICDEP_OFFSET 0x0004
+#define OMAP54XX_CM_MPU_DYNAMICDEP_OFFSET 0x0008
+#define OMAP54XX_CM_MPU_MPU_CLKCTRL_OFFSET 0x0020
+#define OMAP54XX_CM_MPU_MPU_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_MPU_INST, 0x0020)
+#define OMAP54XX_CM_MPU_MPU_MPU_DBG_CLKCTRL_OFFSET 0x0028
+#define OMAP54XX_CM_MPU_MPU_MPU_DBG_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_MPU_INST, 0x0028)
+
+/* CM_CORE_AON.DSP_CM_CORE_AON register offsets */
+#define OMAP54XX_CM_DSP_CLKSTCTRL_OFFSET 0x0000
+#define OMAP54XX_CM_DSP_STATICDEP_OFFSET 0x0004
+#define OMAP54XX_CM_DSP_DYNAMICDEP_OFFSET 0x0008
+#define OMAP54XX_CM_DSP_DSP_CLKCTRL_OFFSET 0x0020
+#define OMAP54XX_CM_DSP_DSP_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_DSP_INST, 0x0020)
+
+/* CM_CORE_AON.ABE_CM_CORE_AON register offsets */
+#define OMAP54XX_CM_ABE_CLKSTCTRL_OFFSET 0x0000
+#define OMAP54XX_CM_ABE_L4_ABE_CLKCTRL_OFFSET 0x0020
+#define OMAP54XX_CM_ABE_L4_ABE_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0020)
+#define OMAP54XX_CM_ABE_AESS_CLKCTRL_OFFSET 0x0028
+#define OMAP54XX_CM_ABE_AESS_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0028)
+#define OMAP54XX_CM_ABE_MCPDM_CLKCTRL_OFFSET 0x0030
+#define OMAP54XX_CM_ABE_MCPDM_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0030)
+#define OMAP54XX_CM_ABE_DMIC_CLKCTRL_OFFSET 0x0038
+#define OMAP54XX_CM_ABE_DMIC_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0038)
+#define OMAP54XX_CM_ABE_MCASP_CLKCTRL_OFFSET 0x0040
+#define OMAP54XX_CM_ABE_MCASP_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0040)
+#define OMAP54XX_CM_ABE_MCBSP1_CLKCTRL_OFFSET 0x0048
+#define OMAP54XX_CM_ABE_MCBSP1_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0048)
+#define OMAP54XX_CM_ABE_MCBSP2_CLKCTRL_OFFSET 0x0050
+#define OMAP54XX_CM_ABE_MCBSP2_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0050)
+#define OMAP54XX_CM_ABE_MCBSP3_CLKCTRL_OFFSET 0x0058
+#define OMAP54XX_CM_ABE_MCBSP3_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0058)
+#define OMAP54XX_CM_ABE_SLIMBUS1_CLKCTRL_OFFSET 0x0060
+#define OMAP54XX_CM_ABE_SLIMBUS1_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0060)
+#define OMAP54XX_CM_ABE_TIMER5_CLKCTRL_OFFSET 0x0068
+#define OMAP54XX_CM_ABE_TIMER5_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0068)
+#define OMAP54XX_CM_ABE_TIMER6_CLKCTRL_OFFSET 0x0070
+#define OMAP54XX_CM_ABE_TIMER6_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0070)
+#define OMAP54XX_CM_ABE_TIMER7_CLKCTRL_OFFSET 0x0078
+#define OMAP54XX_CM_ABE_TIMER7_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0078)
+#define OMAP54XX_CM_ABE_TIMER8_CLKCTRL_OFFSET 0x0080
+#define OMAP54XX_CM_ABE_TIMER8_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0080)
+#define OMAP54XX_CM_ABE_WD_TIMER3_CLKCTRL_OFFSET 0x0088
+#define OMAP54XX_CM_ABE_WD_TIMER3_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0088)
+
+#endif
diff --git a/arch/arm/mach-omap2/cm1_7xx.h b/arch/arm/mach-omap2/cm1_7xx.h
new file mode 100644
index 000000000..2f1c09eea
--- /dev/null
+++ b/arch/arm/mach-omap2/cm1_7xx.h
@@ -0,0 +1,322 @@
+/*
+ * DRA7xx CM1 instance offset macros
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Generated by code originally written by:
+ * 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_CM1_7XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM1_7XX_H
+
+/* CM1 base address */
+#define DRA7XX_CM_CORE_AON_BASE 0x4a005000
+
+#define DRA7XX_CM_CORE_AON_REGADDR(inst, reg) \
+ OMAP2_L4_IO_ADDRESS(DRA7XX_CM_CORE_AON_BASE + (inst) + (reg))
+
+/* CM_CORE_AON instances */
+#define DRA7XX_CM_CORE_AON_OCP_SOCKET_INST 0x0000
+#define DRA7XX_CM_CORE_AON_CKGEN_INST 0x0100
+#define DRA7XX_CM_CORE_AON_MPU_INST 0x0300
+#define DRA7XX_CM_CORE_AON_DSP1_INST 0x0400
+#define DRA7XX_CM_CORE_AON_IPU_INST 0x0500
+#define DRA7XX_CM_CORE_AON_DSP2_INST 0x0600
+#define DRA7XX_CM_CORE_AON_EVE1_INST 0x0640
+#define DRA7XX_CM_CORE_AON_EVE2_INST 0x0680
+#define DRA7XX_CM_CORE_AON_EVE3_INST 0x06c0
+#define DRA7XX_CM_CORE_AON_EVE4_INST 0x0700
+#define DRA7XX_CM_CORE_AON_RTC_INST 0x0740
+#define DRA7XX_CM_CORE_AON_VPE_INST 0x0760
+#define DRA7XX_CM_CORE_AON_RESTORE_INST 0x0e00
+#define DRA7XX_CM_CORE_AON_INSTR_INST 0x0f00
+
+/* CM_CORE_AON clockdomain register offsets (from instance start) */
+#define DRA7XX_CM_CORE_AON_MPU_MPU_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_AON_DSP1_DSP1_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_AON_IPU_IPU1_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_AON_IPU_IPU_CDOFFS 0x0040
+#define DRA7XX_CM_CORE_AON_DSP2_DSP2_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_AON_EVE1_EVE1_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_AON_EVE2_EVE2_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_AON_EVE3_EVE3_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_AON_EVE4_EVE4_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_AON_RTC_RTC_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_AON_VPE_VPE_CDOFFS 0x0000
+
+/* CM_CORE_AON */
+
+/* CM_CORE_AON.OCP_SOCKET_CM_CORE_AON register offsets */
+#define DRA7XX_REVISION_CM_CORE_AON_OFFSET 0x0000
+#define DRA7XX_CM_CM_CORE_AON_PROFILING_CLKCTRL_OFFSET 0x0040
+#define DRA7XX_CM_CM_CORE_AON_PROFILING_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_OCP_SOCKET_INST, 0x0040)
+#define DRA7XX_CM_CORE_AON_DEBUG_OUT_OFFSET 0x00ec
+#define DRA7XX_CM_CORE_AON_DEBUG_CFG0_OFFSET 0x00f0
+#define DRA7XX_CM_CORE_AON_DEBUG_CFG1_OFFSET 0x00f4
+#define DRA7XX_CM_CORE_AON_DEBUG_CFG2_OFFSET 0x00f8
+#define DRA7XX_CM_CORE_AON_DEBUG_CFG3_OFFSET 0x00fc
+
+/* CM_CORE_AON.CKGEN_CM_CORE_AON register offsets */
+#define DRA7XX_CM_CLKSEL_CORE_OFFSET 0x0000
+#define DRA7XX_CM_CLKSEL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0000)
+#define DRA7XX_CM_CLKSEL_ABE_OFFSET 0x0008
+#define DRA7XX_CM_CLKSEL_ABE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0008)
+#define DRA7XX_CM_DLL_CTRL_OFFSET 0x0010
+#define DRA7XX_CM_CLKMODE_DPLL_CORE_OFFSET 0x0020
+#define DRA7XX_CM_CLKMODE_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0020)
+#define DRA7XX_CM_IDLEST_DPLL_CORE_OFFSET 0x0024
+#define DRA7XX_CM_IDLEST_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0024)
+#define DRA7XX_CM_AUTOIDLE_DPLL_CORE_OFFSET 0x0028
+#define DRA7XX_CM_AUTOIDLE_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0028)
+#define DRA7XX_CM_CLKSEL_DPLL_CORE_OFFSET 0x002c
+#define DRA7XX_CM_CLKSEL_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x002c)
+#define DRA7XX_CM_DIV_M2_DPLL_CORE_OFFSET 0x0030
+#define DRA7XX_CM_DIV_M2_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0030)
+#define DRA7XX_CM_DIV_M3_DPLL_CORE_OFFSET 0x0034
+#define DRA7XX_CM_DIV_M3_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0034)
+#define DRA7XX_CM_DIV_H11_DPLL_CORE_OFFSET 0x0038
+#define DRA7XX_CM_DIV_H11_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0038)
+#define DRA7XX_CM_DIV_H12_DPLL_CORE_OFFSET 0x003c
+#define DRA7XX_CM_DIV_H12_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x003c)
+#define DRA7XX_CM_DIV_H13_DPLL_CORE_OFFSET 0x0040
+#define DRA7XX_CM_DIV_H13_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0040)
+#define DRA7XX_CM_DIV_H14_DPLL_CORE_OFFSET 0x0044
+#define DRA7XX_CM_DIV_H14_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0044)
+#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_CORE_OFFSET 0x0048
+#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_CORE_OFFSET 0x004c
+#define DRA7XX_CM_DIV_H21_DPLL_CORE_OFFSET 0x0050
+#define DRA7XX_CM_DIV_H21_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0050)
+#define DRA7XX_CM_DIV_H22_DPLL_CORE_OFFSET 0x0054
+#define DRA7XX_CM_DIV_H22_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0054)
+#define DRA7XX_CM_DIV_H23_DPLL_CORE_OFFSET 0x0058
+#define DRA7XX_CM_DIV_H23_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0058)
+#define DRA7XX_CM_DIV_H24_DPLL_CORE_OFFSET 0x005c
+#define DRA7XX_CM_DIV_H24_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x005c)
+#define DRA7XX_CM_CLKMODE_DPLL_MPU_OFFSET 0x0060
+#define DRA7XX_CM_CLKMODE_DPLL_MPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0060)
+#define DRA7XX_CM_IDLEST_DPLL_MPU_OFFSET 0x0064
+#define DRA7XX_CM_IDLEST_DPLL_MPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0064)
+#define DRA7XX_CM_AUTOIDLE_DPLL_MPU_OFFSET 0x0068
+#define DRA7XX_CM_AUTOIDLE_DPLL_MPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0068)
+#define DRA7XX_CM_CLKSEL_DPLL_MPU_OFFSET 0x006c
+#define DRA7XX_CM_CLKSEL_DPLL_MPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x006c)
+#define DRA7XX_CM_DIV_M2_DPLL_MPU_OFFSET 0x0070
+#define DRA7XX_CM_DIV_M2_DPLL_MPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0070)
+#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_MPU_OFFSET 0x0088
+#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_MPU_OFFSET 0x008c
+#define DRA7XX_CM_BYPCLK_DPLL_MPU_OFFSET 0x009c
+#define DRA7XX_CM_BYPCLK_DPLL_MPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x009c)
+#define DRA7XX_CM_CLKMODE_DPLL_IVA_OFFSET 0x00a0
+#define DRA7XX_CM_CLKMODE_DPLL_IVA DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00a0)
+#define DRA7XX_CM_IDLEST_DPLL_IVA_OFFSET 0x00a4
+#define DRA7XX_CM_IDLEST_DPLL_IVA DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00a4)
+#define DRA7XX_CM_AUTOIDLE_DPLL_IVA_OFFSET 0x00a8
+#define DRA7XX_CM_AUTOIDLE_DPLL_IVA DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00a8)
+#define DRA7XX_CM_CLKSEL_DPLL_IVA_OFFSET 0x00ac
+#define DRA7XX_CM_CLKSEL_DPLL_IVA DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00ac)
+#define DRA7XX_CM_DIV_M2_DPLL_IVA_OFFSET 0x00b0
+#define DRA7XX_CM_DIV_M2_DPLL_IVA DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00b0)
+#define DRA7XX_CM_DIV_M3_DPLL_IVA_OFFSET 0x00b4
+#define DRA7XX_CM_DIV_M3_DPLL_IVA DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00b4)
+#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_IVA_OFFSET 0x00c8
+#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_IVA_OFFSET 0x00cc
+#define DRA7XX_CM_BYPCLK_DPLL_IVA_OFFSET 0x00dc
+#define DRA7XX_CM_BYPCLK_DPLL_IVA DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00dc)
+#define DRA7XX_CM_CLKMODE_DPLL_ABE_OFFSET 0x00e0
+#define DRA7XX_CM_CLKMODE_DPLL_ABE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00e0)
+#define DRA7XX_CM_IDLEST_DPLL_ABE_OFFSET 0x00e4
+#define DRA7XX_CM_IDLEST_DPLL_ABE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00e4)
+#define DRA7XX_CM_AUTOIDLE_DPLL_ABE_OFFSET 0x00e8
+#define DRA7XX_CM_AUTOIDLE_DPLL_ABE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00e8)
+#define DRA7XX_CM_CLKSEL_DPLL_ABE_OFFSET 0x00ec
+#define DRA7XX_CM_CLKSEL_DPLL_ABE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00ec)
+#define DRA7XX_CM_DIV_M2_DPLL_ABE_OFFSET 0x00f0
+#define DRA7XX_CM_DIV_M2_DPLL_ABE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00f0)
+#define DRA7XX_CM_DIV_M3_DPLL_ABE_OFFSET 0x00f4
+#define DRA7XX_CM_DIV_M3_DPLL_ABE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00f4)
+#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_ABE_OFFSET 0x0108
+#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_ABE_OFFSET 0x010c
+#define DRA7XX_CM_CLKMODE_DPLL_DDR_OFFSET 0x0110
+#define DRA7XX_CM_CLKMODE_DPLL_DDR DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0110)
+#define DRA7XX_CM_IDLEST_DPLL_DDR_OFFSET 0x0114
+#define DRA7XX_CM_IDLEST_DPLL_DDR DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0114)
+#define DRA7XX_CM_AUTOIDLE_DPLL_DDR_OFFSET 0x0118
+#define DRA7XX_CM_AUTOIDLE_DPLL_DDR DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0118)
+#define DRA7XX_CM_CLKSEL_DPLL_DDR_OFFSET 0x011c
+#define DRA7XX_CM_CLKSEL_DPLL_DDR DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x011c)
+#define DRA7XX_CM_DIV_M2_DPLL_DDR_OFFSET 0x0120
+#define DRA7XX_CM_DIV_M2_DPLL_DDR DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0120)
+#define DRA7XX_CM_DIV_M3_DPLL_DDR_OFFSET 0x0124
+#define DRA7XX_CM_DIV_M3_DPLL_DDR DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0124)
+#define DRA7XX_CM_DIV_H11_DPLL_DDR_OFFSET 0x0128
+#define DRA7XX_CM_DIV_H11_DPLL_DDR DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0128)
+#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_DDR_OFFSET 0x012c
+#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_DDR_OFFSET 0x0130
+#define DRA7XX_CM_CLKMODE_DPLL_DSP_OFFSET 0x0134
+#define DRA7XX_CM_CLKMODE_DPLL_DSP DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0134)
+#define DRA7XX_CM_IDLEST_DPLL_DSP_OFFSET 0x0138
+#define DRA7XX_CM_IDLEST_DPLL_DSP DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0138)
+#define DRA7XX_CM_AUTOIDLE_DPLL_DSP_OFFSET 0x013c
+#define DRA7XX_CM_AUTOIDLE_DPLL_DSP DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x013c)
+#define DRA7XX_CM_CLKSEL_DPLL_DSP_OFFSET 0x0140
+#define DRA7XX_CM_CLKSEL_DPLL_DSP DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0140)
+#define DRA7XX_CM_DIV_M2_DPLL_DSP_OFFSET 0x0144
+#define DRA7XX_CM_DIV_M2_DPLL_DSP DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0144)
+#define DRA7XX_CM_DIV_M3_DPLL_DSP_OFFSET 0x0148
+#define DRA7XX_CM_DIV_M3_DPLL_DSP DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0148)
+#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_DSP_OFFSET 0x014c
+#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_DSP_OFFSET 0x0150
+#define DRA7XX_CM_BYPCLK_DPLL_DSP_OFFSET 0x0154
+#define DRA7XX_CM_BYPCLK_DPLL_DSP DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0154)
+#define DRA7XX_CM_SHADOW_FREQ_CONFIG1_OFFSET 0x0160
+#define DRA7XX_CM_SHADOW_FREQ_CONFIG2_OFFSET 0x0164
+#define DRA7XX_CM_DYN_DEP_PRESCAL_OFFSET 0x0170
+#define DRA7XX_CM_RESTORE_ST_OFFSET 0x0180
+#define DRA7XX_CM_CLKMODE_DPLL_EVE_OFFSET 0x0184
+#define DRA7XX_CM_CLKMODE_DPLL_EVE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0184)
+#define DRA7XX_CM_IDLEST_DPLL_EVE_OFFSET 0x0188
+#define DRA7XX_CM_IDLEST_DPLL_EVE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0188)
+#define DRA7XX_CM_AUTOIDLE_DPLL_EVE_OFFSET 0x018c
+#define DRA7XX_CM_AUTOIDLE_DPLL_EVE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x018c)
+#define DRA7XX_CM_CLKSEL_DPLL_EVE_OFFSET 0x0190
+#define DRA7XX_CM_CLKSEL_DPLL_EVE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0190)
+#define DRA7XX_CM_DIV_M2_DPLL_EVE_OFFSET 0x0194
+#define DRA7XX_CM_DIV_M2_DPLL_EVE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0194)
+#define DRA7XX_CM_DIV_M3_DPLL_EVE_OFFSET 0x0198
+#define DRA7XX_CM_DIV_M3_DPLL_EVE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0198)
+#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_EVE_OFFSET 0x019c
+#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_EVE_OFFSET 0x01a0
+#define DRA7XX_CM_BYPCLK_DPLL_EVE_OFFSET 0x01a4
+#define DRA7XX_CM_BYPCLK_DPLL_EVE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01a4)
+#define DRA7XX_CM_CLKMODE_DPLL_GMAC_OFFSET 0x01a8
+#define DRA7XX_CM_CLKMODE_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01a8)
+#define DRA7XX_CM_IDLEST_DPLL_GMAC_OFFSET 0x01ac
+#define DRA7XX_CM_IDLEST_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01ac)
+#define DRA7XX_CM_AUTOIDLE_DPLL_GMAC_OFFSET 0x01b0
+#define DRA7XX_CM_AUTOIDLE_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01b0)
+#define DRA7XX_CM_CLKSEL_DPLL_GMAC_OFFSET 0x01b4
+#define DRA7XX_CM_CLKSEL_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01b4)
+#define DRA7XX_CM_DIV_M2_DPLL_GMAC_OFFSET 0x01b8
+#define DRA7XX_CM_DIV_M2_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01b8)
+#define DRA7XX_CM_DIV_M3_DPLL_GMAC_OFFSET 0x01bc
+#define DRA7XX_CM_DIV_M3_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01bc)
+#define DRA7XX_CM_DIV_H11_DPLL_GMAC_OFFSET 0x01c0
+#define DRA7XX_CM_DIV_H11_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01c0)
+#define DRA7XX_CM_DIV_H12_DPLL_GMAC_OFFSET 0x01c4
+#define DRA7XX_CM_DIV_H12_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01c4)
+#define DRA7XX_CM_DIV_H13_DPLL_GMAC_OFFSET 0x01c8
+#define DRA7XX_CM_DIV_H13_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01c8)
+#define DRA7XX_CM_DIV_H14_DPLL_GMAC_OFFSET 0x01cc
+#define DRA7XX_CM_DIV_H14_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01cc)
+#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_GMAC_OFFSET 0x01d0
+#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_GMAC_OFFSET 0x01d4
+#define DRA7XX_CM_CLKMODE_DPLL_GPU_OFFSET 0x01d8
+#define DRA7XX_CM_CLKMODE_DPLL_GPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01d8)
+#define DRA7XX_CM_IDLEST_DPLL_GPU_OFFSET 0x01dc
+#define DRA7XX_CM_IDLEST_DPLL_GPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01dc)
+#define DRA7XX_CM_AUTOIDLE_DPLL_GPU_OFFSET 0x01e0
+#define DRA7XX_CM_AUTOIDLE_DPLL_GPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01e0)
+#define DRA7XX_CM_CLKSEL_DPLL_GPU_OFFSET 0x01e4
+#define DRA7XX_CM_CLKSEL_DPLL_GPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01e4)
+#define DRA7XX_CM_DIV_M2_DPLL_GPU_OFFSET 0x01e8
+#define DRA7XX_CM_DIV_M2_DPLL_GPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01e8)
+#define DRA7XX_CM_DIV_M3_DPLL_GPU_OFFSET 0x01ec
+#define DRA7XX_CM_DIV_M3_DPLL_GPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01ec)
+#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_GPU_OFFSET 0x01f0
+#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_GPU_OFFSET 0x01f4
+
+/* CM_CORE_AON.MPU_CM_CORE_AON register offsets */
+#define DRA7XX_CM_MPU_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_MPU_STATICDEP_OFFSET 0x0004
+#define DRA7XX_CM_MPU_DYNAMICDEP_OFFSET 0x0008
+#define DRA7XX_CM_MPU_MPU_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_MPU_MPU_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_MPU_INST, 0x0020)
+#define DRA7XX_CM_MPU_MPU_MPU_DBG_CLKCTRL_OFFSET 0x0028
+#define DRA7XX_CM_MPU_MPU_MPU_DBG_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_MPU_INST, 0x0028)
+
+/* CM_CORE_AON.DSP1_CM_CORE_AON register offsets */
+#define DRA7XX_CM_DSP1_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_DSP1_STATICDEP_OFFSET 0x0004
+#define DRA7XX_CM_DSP1_DYNAMICDEP_OFFSET 0x0008
+#define DRA7XX_CM_DSP1_DSP1_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_DSP1_DSP1_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_DSP1_INST, 0x0020)
+
+/* CM_CORE_AON.IPU_CM_CORE_AON register offsets */
+#define DRA7XX_CM_IPU1_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_IPU1_STATICDEP_OFFSET 0x0004
+#define DRA7XX_CM_IPU1_DYNAMICDEP_OFFSET 0x0008
+#define DRA7XX_CM_IPU1_IPU1_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_IPU1_IPU1_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_IPU_INST, 0x0020)
+#define DRA7XX_CM_IPU_CLKSTCTRL_OFFSET 0x0040
+#define DRA7XX_CM_IPU_MCASP1_CLKCTRL_OFFSET 0x0050
+#define DRA7XX_CM_IPU_MCASP1_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_IPU_INST, 0x0050)
+#define DRA7XX_CM_IPU_TIMER5_CLKCTRL_OFFSET 0x0058
+#define DRA7XX_CM_IPU_TIMER5_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_IPU_INST, 0x0058)
+#define DRA7XX_CM_IPU_TIMER6_CLKCTRL_OFFSET 0x0060
+#define DRA7XX_CM_IPU_TIMER6_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_IPU_INST, 0x0060)
+#define DRA7XX_CM_IPU_TIMER7_CLKCTRL_OFFSET 0x0068
+#define DRA7XX_CM_IPU_TIMER7_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_IPU_INST, 0x0068)
+#define DRA7XX_CM_IPU_TIMER8_CLKCTRL_OFFSET 0x0070
+#define DRA7XX_CM_IPU_TIMER8_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_IPU_INST, 0x0070)
+#define DRA7XX_CM_IPU_I2C5_CLKCTRL_OFFSET 0x0078
+#define DRA7XX_CM_IPU_I2C5_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_IPU_INST, 0x0078)
+#define DRA7XX_CM_IPU_UART6_CLKCTRL_OFFSET 0x0080
+#define DRA7XX_CM_IPU_UART6_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_IPU_INST, 0x0080)
+
+/* CM_CORE_AON.DSP2_CM_CORE_AON register offsets */
+#define DRA7XX_CM_DSP2_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_DSP2_STATICDEP_OFFSET 0x0004
+#define DRA7XX_CM_DSP2_DYNAMICDEP_OFFSET 0x0008
+#define DRA7XX_CM_DSP2_DSP2_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_DSP2_DSP2_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_DSP2_INST, 0x0020)
+
+/* CM_CORE_AON.EVE1_CM_CORE_AON register offsets */
+#define DRA7XX_CM_EVE1_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_EVE1_STATICDEP_OFFSET 0x0004
+#define DRA7XX_CM_EVE1_EVE1_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_EVE1_EVE1_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_EVE1_INST, 0x0020)
+
+/* CM_CORE_AON.EVE2_CM_CORE_AON register offsets */
+#define DRA7XX_CM_EVE2_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_EVE2_STATICDEP_OFFSET 0x0004
+#define DRA7XX_CM_EVE2_EVE2_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_EVE2_EVE2_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_EVE2_INST, 0x0020)
+
+/* CM_CORE_AON.EVE3_CM_CORE_AON register offsets */
+#define DRA7XX_CM_EVE3_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_EVE3_STATICDEP_OFFSET 0x0004
+#define DRA7XX_CM_EVE3_EVE3_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_EVE3_EVE3_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_EVE3_INST, 0x0020)
+
+/* CM_CORE_AON.EVE4_CM_CORE_AON register offsets */
+#define DRA7XX_CM_EVE4_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_EVE4_STATICDEP_OFFSET 0x0004
+#define DRA7XX_CM_EVE4_EVE4_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_EVE4_EVE4_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_EVE4_INST, 0x0020)
+
+/* CM_CORE_AON.RTC_CM_CORE_AON register offsets */
+#define DRA7XX_CM_RTC_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_RTC_RTCSS_CLKCTRL_OFFSET 0x0004
+#define DRA7XX_CM_RTC_RTCSS_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_RTC_INST, 0x0004)
+
+/* CM_CORE_AON.VPE_CM_CORE_AON register offsets */
+#define DRA7XX_CM_VPE_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_VPE_VPE_CLKCTRL_OFFSET 0x0004
+#define DRA7XX_CM_VPE_VPE_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_VPE_INST, 0x0004)
+#define DRA7XX_CM_VPE_STATICDEP_OFFSET 0x0008
+
+#endif
diff --git a/arch/arm/mach-omap2/cm2_44xx.h b/arch/arm/mach-omap2/cm2_44xx.h
new file mode 100644
index 000000000..7521abf3d
--- /dev/null
+++ b/arch/arm/mach-omap2/cm2_44xx.h
@@ -0,0 +1,452 @@
+/*
+ * OMAP44xx CM2 instance offset macros
+ *
+ * Copyright (C) 2009-2011 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_MODFREQDIV_DPLL_PER_OFFSET 0x006c
+#define OMAP4430_CM_SSC_MODFREQDIV_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_MODFREQDIV_DPLL_USB_OFFSET 0x00ac
+#define OMAP4430_CM_SSC_MODFREQDIV_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_MODFREQDIV_DPLL_UNIPRO_OFFSET 0x00ec
+#define OMAP4430_CM_SSC_MODFREQDIV_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_MODEM_ICR_CLKCTRL_OFFSET 0x0528
+#define OMAP4430_CM_D2D_MODEM_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)
+
+#endif
diff --git a/arch/arm/mach-omap2/cm2_54xx.h b/arch/arm/mach-omap2/cm2_54xx.h
new file mode 100644
index 000000000..ff4040c19
--- /dev/null
+++ b/arch/arm/mach-omap2/cm2_54xx.h
@@ -0,0 +1,387 @@
+/*
+ * OMAP54xx CM2 instance offset macros
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * 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_CM2_54XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM2_54XX_H
+
+/* CM2 base address */
+#define OMAP54XX_CM_CORE_BASE 0x4a008000
+
+#define OMAP54XX_CM_CORE_REGADDR(inst, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_BASE + (inst) + (reg))
+
+/* CM_CORE instances */
+#define OMAP54XX_CM_CORE_OCP_SOCKET_INST 0x0000
+#define OMAP54XX_CM_CORE_CKGEN_INST 0x0100
+#define OMAP54XX_CM_CORE_COREAON_INST 0x0600
+#define OMAP54XX_CM_CORE_CORE_INST 0x0700
+#define OMAP54XX_CM_CORE_IVA_INST 0x1200
+#define OMAP54XX_CM_CORE_CAM_INST 0x1300
+#define OMAP54XX_CM_CORE_DSS_INST 0x1400
+#define OMAP54XX_CM_CORE_GPU_INST 0x1500
+#define OMAP54XX_CM_CORE_L3INIT_INST 0x1600
+#define OMAP54XX_CM_CORE_CUSTEFUSE_INST 0x1700
+#define OMAP54XX_CM_CORE_RESTORE_INST 0x1e00
+#define OMAP54XX_CM_CORE_INSTR_INST 0x1f00
+
+/* CM_CORE clockdomain register offsets (from instance start) */
+#define OMAP54XX_CM_CORE_COREAON_COREAON_CDOFFS 0x0000
+#define OMAP54XX_CM_CORE_CORE_L3MAIN1_CDOFFS 0x0000
+#define OMAP54XX_CM_CORE_CORE_L3MAIN2_CDOFFS 0x0100
+#define OMAP54XX_CM_CORE_CORE_IPU_CDOFFS 0x0200
+#define OMAP54XX_CM_CORE_CORE_DMA_CDOFFS 0x0300
+#define OMAP54XX_CM_CORE_CORE_EMIF_CDOFFS 0x0400
+#define OMAP54XX_CM_CORE_CORE_C2C_CDOFFS 0x0500
+#define OMAP54XX_CM_CORE_CORE_L4CFG_CDOFFS 0x0600
+#define OMAP54XX_CM_CORE_CORE_L3INSTR_CDOFFS 0x0700
+#define OMAP54XX_CM_CORE_CORE_MIPIEXT_CDOFFS 0x0800
+#define OMAP54XX_CM_CORE_CORE_L4PER_CDOFFS 0x0900
+#define OMAP54XX_CM_CORE_CORE_L4SEC_CDOFFS 0x0a80
+#define OMAP54XX_CM_CORE_IVA_IVA_CDOFFS 0x0000
+#define OMAP54XX_CM_CORE_CAM_CAM_CDOFFS 0x0000
+#define OMAP54XX_CM_CORE_DSS_DSS_CDOFFS 0x0000
+#define OMAP54XX_CM_CORE_GPU_GPU_CDOFFS 0x0000
+#define OMAP54XX_CM_CORE_L3INIT_L3INIT_CDOFFS 0x0000
+#define OMAP54XX_CM_CORE_CUSTEFUSE_CUSTEFUSE_CDOFFS 0x0000
+
+/* CM_CORE */
+
+/* CM_CORE.OCP_SOCKET_CM_CORE register offsets */
+#define OMAP54XX_REVISION_CM_CORE_OFFSET 0x0000
+#define OMAP54XX_CM_CM_CORE_PROFILING_CLKCTRL_OFFSET 0x0040
+#define OMAP54XX_CM_CM_CORE_PROFILING_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_OCP_SOCKET_INST, 0x0040)
+#define OMAP54XX_CM_CORE_DEBUG_CFG_OFFSET 0x0080
+#define OMAP54XX_CM_CORE_DEBUG_OUT_OFFSET 0x0084
+
+/* CM_CORE.CKGEN_CM_CORE register offsets */
+#define OMAP54XX_CM_CLKSEL_USB_60MHZ_OFFSET 0x0004
+#define OMAP54XX_CM_CLKSEL_USB_60MHZ OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0004)
+#define OMAP54XX_CM_CLKMODE_DPLL_PER_OFFSET 0x0040
+#define OMAP54XX_CM_CLKMODE_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0040)
+#define OMAP54XX_CM_IDLEST_DPLL_PER_OFFSET 0x0044
+#define OMAP54XX_CM_IDLEST_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0044)
+#define OMAP54XX_CM_AUTOIDLE_DPLL_PER_OFFSET 0x0048
+#define OMAP54XX_CM_AUTOIDLE_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0048)
+#define OMAP54XX_CM_CLKSEL_DPLL_PER_OFFSET 0x004c
+#define OMAP54XX_CM_CLKSEL_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x004c)
+#define OMAP54XX_CM_DIV_M2_DPLL_PER_OFFSET 0x0050
+#define OMAP54XX_CM_DIV_M2_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0050)
+#define OMAP54XX_CM_DIV_M3_DPLL_PER_OFFSET 0x0054
+#define OMAP54XX_CM_DIV_M3_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0054)
+#define OMAP54XX_CM_DIV_H11_DPLL_PER_OFFSET 0x0058
+#define OMAP54XX_CM_DIV_H11_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0058)
+#define OMAP54XX_CM_DIV_H12_DPLL_PER_OFFSET 0x005c
+#define OMAP54XX_CM_DIV_H12_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x005c)
+#define OMAP54XX_CM_DIV_H13_DPLL_PER_OFFSET 0x0060
+#define OMAP54XX_CM_DIV_H13_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0060)
+#define OMAP54XX_CM_DIV_H14_DPLL_PER_OFFSET 0x0064
+#define OMAP54XX_CM_DIV_H14_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0064)
+#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_PER_OFFSET 0x0068
+#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_PER_OFFSET 0x006c
+#define OMAP54XX_CM_CLKMODE_DPLL_USB_OFFSET 0x0080
+#define OMAP54XX_CM_CLKMODE_DPLL_USB OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0080)
+#define OMAP54XX_CM_IDLEST_DPLL_USB_OFFSET 0x0084
+#define OMAP54XX_CM_IDLEST_DPLL_USB OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0084)
+#define OMAP54XX_CM_AUTOIDLE_DPLL_USB_OFFSET 0x0088
+#define OMAP54XX_CM_AUTOIDLE_DPLL_USB OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0088)
+#define OMAP54XX_CM_CLKSEL_DPLL_USB_OFFSET 0x008c
+#define OMAP54XX_CM_CLKSEL_DPLL_USB OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x008c)
+#define OMAP54XX_CM_DIV_M2_DPLL_USB_OFFSET 0x0090
+#define OMAP54XX_CM_DIV_M2_DPLL_USB OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0090)
+#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_USB_OFFSET 0x00a8
+#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_USB_OFFSET 0x00ac
+#define OMAP54XX_CM_CLKDCOLDO_DPLL_USB_OFFSET 0x00b4
+#define OMAP54XX_CM_CLKDCOLDO_DPLL_USB OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00b4)
+#define OMAP54XX_CM_CLKMODE_DPLL_UNIPRO2_OFFSET 0x00c0
+#define OMAP54XX_CM_CLKMODE_DPLL_UNIPRO2 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00c0)
+#define OMAP54XX_CM_IDLEST_DPLL_UNIPRO2_OFFSET 0x00c4
+#define OMAP54XX_CM_IDLEST_DPLL_UNIPRO2 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00c4)
+#define OMAP54XX_CM_AUTOIDLE_DPLL_UNIPRO2_OFFSET 0x00c8
+#define OMAP54XX_CM_AUTOIDLE_DPLL_UNIPRO2 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00c8)
+#define OMAP54XX_CM_CLKSEL_DPLL_UNIPRO2_OFFSET 0x00cc
+#define OMAP54XX_CM_CLKSEL_DPLL_UNIPRO2 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00cc)
+#define OMAP54XX_CM_DIV_M2_DPLL_UNIPRO2_OFFSET 0x00d0
+#define OMAP54XX_CM_DIV_M2_DPLL_UNIPRO2 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00d0)
+#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_UNIPRO2_OFFSET 0x00e8
+#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_UNIPRO2_OFFSET 0x00ec
+#define OMAP54XX_CM_CLKDCOLDO_DPLL_UNIPRO2_OFFSET 0x00f4
+#define OMAP54XX_CM_CLKDCOLDO_DPLL_UNIPRO2 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00f4)
+#define OMAP54XX_CM_CLKMODE_DPLL_UNIPRO1_OFFSET 0x0100
+#define OMAP54XX_CM_CLKMODE_DPLL_UNIPRO1 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0100)
+#define OMAP54XX_CM_IDLEST_DPLL_UNIPRO1_OFFSET 0x0104
+#define OMAP54XX_CM_IDLEST_DPLL_UNIPRO1 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0104)
+#define OMAP54XX_CM_AUTOIDLE_DPLL_UNIPRO1_OFFSET 0x0108
+#define OMAP54XX_CM_AUTOIDLE_DPLL_UNIPRO1 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0108)
+#define OMAP54XX_CM_CLKSEL_DPLL_UNIPRO1_OFFSET 0x010c
+#define OMAP54XX_CM_CLKSEL_DPLL_UNIPRO1 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x010c)
+#define OMAP54XX_CM_DIV_M2_DPLL_UNIPRO1_OFFSET 0x0110
+#define OMAP54XX_CM_DIV_M2_DPLL_UNIPRO1 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0110)
+#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_UNIPRO1_OFFSET 0x0128
+#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_UNIPRO1_OFFSET 0x012c
+#define OMAP54XX_CM_CLKDCOLDO_DPLL_UNIPRO1_OFFSET 0x0134
+#define OMAP54XX_CM_CLKDCOLDO_DPLL_UNIPRO1 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0134)
+
+/* CM_CORE.COREAON_CM_CORE register offsets */
+#define OMAP54XX_CM_COREAON_CLKSTCTRL_OFFSET 0x0000
+#define OMAP54XX_CM_COREAON_SMARTREFLEX_MPU_CLKCTRL_OFFSET 0x0028
+#define OMAP54XX_CM_COREAON_SMARTREFLEX_MPU_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_COREAON_INST, 0x0028)
+#define OMAP54XX_CM_COREAON_SMARTREFLEX_MM_CLKCTRL_OFFSET 0x0030
+#define OMAP54XX_CM_COREAON_SMARTREFLEX_MM_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_COREAON_INST, 0x0030)
+#define OMAP54XX_CM_COREAON_SMARTREFLEX_CORE_CLKCTRL_OFFSET 0x0038
+#define OMAP54XX_CM_COREAON_SMARTREFLEX_CORE_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_COREAON_INST, 0x0038)
+#define OMAP54XX_CM_COREAON_USB_PHY_CORE_CLKCTRL_OFFSET 0x0040
+#define OMAP54XX_CM_COREAON_USB_PHY_CORE_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_COREAON_INST, 0x0040)
+#define OMAP54XX_CM_COREAON_IO_SRCOMP_CLKCTRL_OFFSET 0x0050
+#define OMAP54XX_CM_COREAON_IO_SRCOMP_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_COREAON_INST, 0x0050)
+
+/* CM_CORE.CORE_CM_CORE register offsets */
+#define OMAP54XX_CM_L3MAIN1_CLKSTCTRL_OFFSET 0x0000
+#define OMAP54XX_CM_L3MAIN1_DYNAMICDEP_OFFSET 0x0008
+#define OMAP54XX_CM_L3MAIN1_L3_MAIN_1_CLKCTRL_OFFSET 0x0020
+#define OMAP54XX_CM_L3MAIN1_L3_MAIN_1_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0020)
+#define OMAP54XX_CM_L3MAIN2_CLKSTCTRL_OFFSET 0x0100
+#define OMAP54XX_CM_L3MAIN2_DYNAMICDEP_OFFSET 0x0108
+#define OMAP54XX_CM_L3MAIN2_L3_MAIN_2_CLKCTRL_OFFSET 0x0120
+#define OMAP54XX_CM_L3MAIN2_L3_MAIN_2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0120)
+#define OMAP54XX_CM_L3MAIN2_GPMC_CLKCTRL_OFFSET 0x0128
+#define OMAP54XX_CM_L3MAIN2_GPMC_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0128)
+#define OMAP54XX_CM_L3MAIN2_OCMC_RAM_CLKCTRL_OFFSET 0x0130
+#define OMAP54XX_CM_L3MAIN2_OCMC_RAM_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0130)
+#define OMAP54XX_CM_IPU_CLKSTCTRL_OFFSET 0x0200
+#define OMAP54XX_CM_IPU_STATICDEP_OFFSET 0x0204
+#define OMAP54XX_CM_IPU_DYNAMICDEP_OFFSET 0x0208
+#define OMAP54XX_CM_IPU_IPU_CLKCTRL_OFFSET 0x0220
+#define OMAP54XX_CM_IPU_IPU_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0220)
+#define OMAP54XX_CM_DMA_CLKSTCTRL_OFFSET 0x0300
+#define OMAP54XX_CM_DMA_STATICDEP_OFFSET 0x0304
+#define OMAP54XX_CM_DMA_DYNAMICDEP_OFFSET 0x0308
+#define OMAP54XX_CM_DMA_DMA_SYSTEM_CLKCTRL_OFFSET 0x0320
+#define OMAP54XX_CM_DMA_DMA_SYSTEM_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0320)
+#define OMAP54XX_CM_EMIF_CLKSTCTRL_OFFSET 0x0400
+#define OMAP54XX_CM_EMIF_DMM_CLKCTRL_OFFSET 0x0420
+#define OMAP54XX_CM_EMIF_DMM_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0420)
+#define OMAP54XX_CM_EMIF_EMIF_OCP_FW_CLKCTRL_OFFSET 0x0428
+#define OMAP54XX_CM_EMIF_EMIF_OCP_FW_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0428)
+#define OMAP54XX_CM_EMIF_EMIF1_CLKCTRL_OFFSET 0x0430
+#define OMAP54XX_CM_EMIF_EMIF1_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0430)
+#define OMAP54XX_CM_EMIF_EMIF2_CLKCTRL_OFFSET 0x0438
+#define OMAP54XX_CM_EMIF_EMIF2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0438)
+#define OMAP54XX_CM_EMIF_EMIF_DLL_CLKCTRL_OFFSET 0x0440
+#define OMAP54XX_CM_EMIF_EMIF_DLL_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0440)
+#define OMAP54XX_CM_C2C_CLKSTCTRL_OFFSET 0x0500
+#define OMAP54XX_CM_C2C_STATICDEP_OFFSET 0x0504
+#define OMAP54XX_CM_C2C_DYNAMICDEP_OFFSET 0x0508
+#define OMAP54XX_CM_C2C_C2C_CLKCTRL_OFFSET 0x0520
+#define OMAP54XX_CM_C2C_C2C_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0520)
+#define OMAP54XX_CM_C2C_MODEM_ICR_CLKCTRL_OFFSET 0x0528
+#define OMAP54XX_CM_C2C_MODEM_ICR_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0528)
+#define OMAP54XX_CM_C2C_C2C_OCP_FW_CLKCTRL_OFFSET 0x0530
+#define OMAP54XX_CM_C2C_C2C_OCP_FW_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0530)
+#define OMAP54XX_CM_L4CFG_CLKSTCTRL_OFFSET 0x0600
+#define OMAP54XX_CM_L4CFG_DYNAMICDEP_OFFSET 0x0608
+#define OMAP54XX_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET 0x0620
+#define OMAP54XX_CM_L4CFG_L4_CFG_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0620)
+#define OMAP54XX_CM_L4CFG_SPINLOCK_CLKCTRL_OFFSET 0x0628
+#define OMAP54XX_CM_L4CFG_SPINLOCK_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0628)
+#define OMAP54XX_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET 0x0630
+#define OMAP54XX_CM_L4CFG_MAILBOX_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0630)
+#define OMAP54XX_CM_L4CFG_SAR_ROM_CLKCTRL_OFFSET 0x0638
+#define OMAP54XX_CM_L4CFG_SAR_ROM_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0638)
+#define OMAP54XX_CM_L4CFG_OCP2SCP2_CLKCTRL_OFFSET 0x0640
+#define OMAP54XX_CM_L4CFG_OCP2SCP2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0640)
+#define OMAP54XX_CM_L3INSTR_CLKSTCTRL_OFFSET 0x0700
+#define OMAP54XX_CM_L3INSTR_L3_MAIN_3_CLKCTRL_OFFSET 0x0720
+#define OMAP54XX_CM_L3INSTR_L3_MAIN_3_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0720)
+#define OMAP54XX_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET 0x0728
+#define OMAP54XX_CM_L3INSTR_L3_INSTR_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0728)
+#define OMAP54XX_CM_L3INSTR_OCP_WP_NOC_CLKCTRL_OFFSET 0x0740
+#define OMAP54XX_CM_L3INSTR_OCP_WP_NOC_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0740)
+#define OMAP54XX_CM_L3INSTR_DLL_AGING_CLKCTRL_OFFSET 0x0748
+#define OMAP54XX_CM_L3INSTR_DLL_AGING_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0748)
+#define OMAP54XX_CM_L3INSTR_CTRL_MODULE_BANDGAP_CLKCTRL_OFFSET 0x0750
+#define OMAP54XX_CM_L3INSTR_CTRL_MODULE_BANDGAP_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0750)
+#define OMAP54XX_CM_MIPIEXT_CLKSTCTRL_OFFSET 0x0800
+#define OMAP54XX_CM_MIPIEXT_STATICDEP_OFFSET 0x0804
+#define OMAP54XX_CM_MIPIEXT_DYNAMICDEP_OFFSET 0x0808
+#define OMAP54XX_CM_MIPIEXT_LLI_CLKCTRL_OFFSET 0x0820
+#define OMAP54XX_CM_MIPIEXT_LLI_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0820)
+#define OMAP54XX_CM_MIPIEXT_LLI_OCP_FW_CLKCTRL_OFFSET 0x0828
+#define OMAP54XX_CM_MIPIEXT_LLI_OCP_FW_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0828)
+#define OMAP54XX_CM_MIPIEXT_MPHY_CLKCTRL_OFFSET 0x0830
+#define OMAP54XX_CM_MIPIEXT_MPHY_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0830)
+#define OMAP54XX_CM_L4PER_CLKSTCTRL_OFFSET 0x0900
+#define OMAP54XX_CM_L4PER_DYNAMICDEP_OFFSET 0x0908
+#define OMAP54XX_CM_L4PER_TIMER10_CLKCTRL_OFFSET 0x0928
+#define OMAP54XX_CM_L4PER_TIMER10_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0928)
+#define OMAP54XX_CM_L4PER_TIMER11_CLKCTRL_OFFSET 0x0930
+#define OMAP54XX_CM_L4PER_TIMER11_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0930)
+#define OMAP54XX_CM_L4PER_TIMER2_CLKCTRL_OFFSET 0x0938
+#define OMAP54XX_CM_L4PER_TIMER2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0938)
+#define OMAP54XX_CM_L4PER_TIMER3_CLKCTRL_OFFSET 0x0940
+#define OMAP54XX_CM_L4PER_TIMER3_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0940)
+#define OMAP54XX_CM_L4PER_TIMER4_CLKCTRL_OFFSET 0x0948
+#define OMAP54XX_CM_L4PER_TIMER4_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0948)
+#define OMAP54XX_CM_L4PER_TIMER9_CLKCTRL_OFFSET 0x0950
+#define OMAP54XX_CM_L4PER_TIMER9_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0950)
+#define OMAP54XX_CM_L4PER_ELM_CLKCTRL_OFFSET 0x0958
+#define OMAP54XX_CM_L4PER_ELM_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0958)
+#define OMAP54XX_CM_L4PER_GPIO2_CLKCTRL_OFFSET 0x0960
+#define OMAP54XX_CM_L4PER_GPIO2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0960)
+#define OMAP54XX_CM_L4PER_GPIO3_CLKCTRL_OFFSET 0x0968
+#define OMAP54XX_CM_L4PER_GPIO3_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0968)
+#define OMAP54XX_CM_L4PER_GPIO4_CLKCTRL_OFFSET 0x0970
+#define OMAP54XX_CM_L4PER_GPIO4_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0970)
+#define OMAP54XX_CM_L4PER_GPIO5_CLKCTRL_OFFSET 0x0978
+#define OMAP54XX_CM_L4PER_GPIO5_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0978)
+#define OMAP54XX_CM_L4PER_GPIO6_CLKCTRL_OFFSET 0x0980
+#define OMAP54XX_CM_L4PER_GPIO6_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0980)
+#define OMAP54XX_CM_L4PER_HDQ1W_CLKCTRL_OFFSET 0x0988
+#define OMAP54XX_CM_L4PER_HDQ1W_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0988)
+#define OMAP54XX_CM_L4PER_I2C1_CLKCTRL_OFFSET 0x09a0
+#define OMAP54XX_CM_L4PER_I2C1_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09a0)
+#define OMAP54XX_CM_L4PER_I2C2_CLKCTRL_OFFSET 0x09a8
+#define OMAP54XX_CM_L4PER_I2C2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09a8)
+#define OMAP54XX_CM_L4PER_I2C3_CLKCTRL_OFFSET 0x09b0
+#define OMAP54XX_CM_L4PER_I2C3_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09b0)
+#define OMAP54XX_CM_L4PER_I2C4_CLKCTRL_OFFSET 0x09b8
+#define OMAP54XX_CM_L4PER_I2C4_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09b8)
+#define OMAP54XX_CM_L4PER_L4_PER_CLKCTRL_OFFSET 0x09c0
+#define OMAP54XX_CM_L4PER_L4_PER_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09c0)
+#define OMAP54XX_CM_L4PER_MCSPI1_CLKCTRL_OFFSET 0x09f0
+#define OMAP54XX_CM_L4PER_MCSPI1_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09f0)
+#define OMAP54XX_CM_L4PER_MCSPI2_CLKCTRL_OFFSET 0x09f8
+#define OMAP54XX_CM_L4PER_MCSPI2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09f8)
+#define OMAP54XX_CM_L4PER_MCSPI3_CLKCTRL_OFFSET 0x0a00
+#define OMAP54XX_CM_L4PER_MCSPI3_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a00)
+#define OMAP54XX_CM_L4PER_MCSPI4_CLKCTRL_OFFSET 0x0a08
+#define OMAP54XX_CM_L4PER_MCSPI4_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a08)
+#define OMAP54XX_CM_L4PER_GPIO7_CLKCTRL_OFFSET 0x0a10
+#define OMAP54XX_CM_L4PER_GPIO7_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a10)
+#define OMAP54XX_CM_L4PER_GPIO8_CLKCTRL_OFFSET 0x0a18
+#define OMAP54XX_CM_L4PER_GPIO8_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a18)
+#define OMAP54XX_CM_L4PER_MMC3_CLKCTRL_OFFSET 0x0a20
+#define OMAP54XX_CM_L4PER_MMC3_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a20)
+#define OMAP54XX_CM_L4PER_MMC4_CLKCTRL_OFFSET 0x0a28
+#define OMAP54XX_CM_L4PER_MMC4_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a28)
+#define OMAP54XX_CM_L4PER_UART1_CLKCTRL_OFFSET 0x0a40
+#define OMAP54XX_CM_L4PER_UART1_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a40)
+#define OMAP54XX_CM_L4PER_UART2_CLKCTRL_OFFSET 0x0a48
+#define OMAP54XX_CM_L4PER_UART2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a48)
+#define OMAP54XX_CM_L4PER_UART3_CLKCTRL_OFFSET 0x0a50
+#define OMAP54XX_CM_L4PER_UART3_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a50)
+#define OMAP54XX_CM_L4PER_UART4_CLKCTRL_OFFSET 0x0a58
+#define OMAP54XX_CM_L4PER_UART4_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a58)
+#define OMAP54XX_CM_L4PER_MMC5_CLKCTRL_OFFSET 0x0a60
+#define OMAP54XX_CM_L4PER_MMC5_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a60)
+#define OMAP54XX_CM_L4PER_I2C5_CLKCTRL_OFFSET 0x0a68
+#define OMAP54XX_CM_L4PER_I2C5_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a68)
+#define OMAP54XX_CM_L4PER_UART5_CLKCTRL_OFFSET 0x0a70
+#define OMAP54XX_CM_L4PER_UART5_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a70)
+#define OMAP54XX_CM_L4PER_UART6_CLKCTRL_OFFSET 0x0a78
+#define OMAP54XX_CM_L4PER_UART6_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a78)
+#define OMAP54XX_CM_L4SEC_CLKSTCTRL_OFFSET 0x0a80
+#define OMAP54XX_CM_L4SEC_STATICDEP_OFFSET 0x0a84
+#define OMAP54XX_CM_L4SEC_DYNAMICDEP_OFFSET 0x0a88
+#define OMAP54XX_CM_L4SEC_AES1_CLKCTRL_OFFSET 0x0aa0
+#define OMAP54XX_CM_L4SEC_AES1_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0aa0)
+#define OMAP54XX_CM_L4SEC_AES2_CLKCTRL_OFFSET 0x0aa8
+#define OMAP54XX_CM_L4SEC_AES2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0aa8)
+#define OMAP54XX_CM_L4SEC_DES3DES_CLKCTRL_OFFSET 0x0ab0
+#define OMAP54XX_CM_L4SEC_DES3DES_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0ab0)
+#define OMAP54XX_CM_L4SEC_FPKA_CLKCTRL_OFFSET 0x0ab8
+#define OMAP54XX_CM_L4SEC_FPKA_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0ab8)
+#define OMAP54XX_CM_L4SEC_RNG_CLKCTRL_OFFSET 0x0ac0
+#define OMAP54XX_CM_L4SEC_RNG_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0ac0)
+#define OMAP54XX_CM_L4SEC_SHA2MD5_CLKCTRL_OFFSET 0x0ac8
+#define OMAP54XX_CM_L4SEC_SHA2MD5_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0ac8)
+#define OMAP54XX_CM_L4SEC_DMA_CRYPTO_CLKCTRL_OFFSET 0x0ad8
+#define OMAP54XX_CM_L4SEC_DMA_CRYPTO_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0ad8)
+
+/* CM_CORE.IVA_CM_CORE register offsets */
+#define OMAP54XX_CM_IVA_CLKSTCTRL_OFFSET 0x0000
+#define OMAP54XX_CM_IVA_STATICDEP_OFFSET 0x0004
+#define OMAP54XX_CM_IVA_DYNAMICDEP_OFFSET 0x0008
+#define OMAP54XX_CM_IVA_IVA_CLKCTRL_OFFSET 0x0020
+#define OMAP54XX_CM_IVA_IVA_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_IVA_INST, 0x0020)
+#define OMAP54XX_CM_IVA_SL2_CLKCTRL_OFFSET 0x0028
+#define OMAP54XX_CM_IVA_SL2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_IVA_INST, 0x0028)
+
+/* CM_CORE.CAM_CM_CORE register offsets */
+#define OMAP54XX_CM_CAM_CLKSTCTRL_OFFSET 0x0000
+#define OMAP54XX_CM_CAM_STATICDEP_OFFSET 0x0004
+#define OMAP54XX_CM_CAM_DYNAMICDEP_OFFSET 0x0008
+#define OMAP54XX_CM_CAM_ISS_CLKCTRL_OFFSET 0x0020
+#define OMAP54XX_CM_CAM_ISS_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CAM_INST, 0x0020)
+#define OMAP54XX_CM_CAM_FDIF_CLKCTRL_OFFSET 0x0028
+#define OMAP54XX_CM_CAM_FDIF_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CAM_INST, 0x0028)
+#define OMAP54XX_CM_CAM_CAL_CLKCTRL_OFFSET 0x0030
+#define OMAP54XX_CM_CAM_CAL_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CAM_INST, 0x0030)
+
+/* CM_CORE.DSS_CM_CORE register offsets */
+#define OMAP54XX_CM_DSS_CLKSTCTRL_OFFSET 0x0000
+#define OMAP54XX_CM_DSS_STATICDEP_OFFSET 0x0004
+#define OMAP54XX_CM_DSS_DYNAMICDEP_OFFSET 0x0008
+#define OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET 0x0020
+#define OMAP54XX_CM_DSS_DSS_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_DSS_INST, 0x0020)
+#define OMAP54XX_CM_DSS_BB2D_CLKCTRL_OFFSET 0x0030
+#define OMAP54XX_CM_DSS_BB2D_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_DSS_INST, 0x0030)
+
+/* CM_CORE.GPU_CM_CORE register offsets */
+#define OMAP54XX_CM_GPU_CLKSTCTRL_OFFSET 0x0000
+#define OMAP54XX_CM_GPU_STATICDEP_OFFSET 0x0004
+#define OMAP54XX_CM_GPU_DYNAMICDEP_OFFSET 0x0008
+#define OMAP54XX_CM_GPU_GPU_CLKCTRL_OFFSET 0x0020
+#define OMAP54XX_CM_GPU_GPU_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_GPU_INST, 0x0020)
+
+/* CM_CORE.L3INIT_CM_CORE register offsets */
+#define OMAP54XX_CM_L3INIT_CLKSTCTRL_OFFSET 0x0000
+#define OMAP54XX_CM_L3INIT_STATICDEP_OFFSET 0x0004
+#define OMAP54XX_CM_L3INIT_DYNAMICDEP_OFFSET 0x0008
+#define OMAP54XX_CM_L3INIT_MMC1_CLKCTRL_OFFSET 0x0028
+#define OMAP54XX_CM_L3INIT_MMC1_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0028)
+#define OMAP54XX_CM_L3INIT_MMC2_CLKCTRL_OFFSET 0x0030
+#define OMAP54XX_CM_L3INIT_MMC2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0030)
+#define OMAP54XX_CM_L3INIT_HSI_CLKCTRL_OFFSET 0x0038
+#define OMAP54XX_CM_L3INIT_HSI_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0038)
+#define OMAP54XX_CM_L3INIT_UNIPRO2_CLKCTRL_OFFSET 0x0040
+#define OMAP54XX_CM_L3INIT_UNIPRO2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0040)
+#define OMAP54XX_CM_L3INIT_MPHY_UNIPRO2_CLKCTRL_OFFSET 0x0048
+#define OMAP54XX_CM_L3INIT_MPHY_UNIPRO2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0048)
+#define OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL_OFFSET 0x0058
+#define OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0058)
+#define OMAP54XX_CM_L3INIT_USB_TLL_HS_CLKCTRL_OFFSET 0x0068
+#define OMAP54XX_CM_L3INIT_USB_TLL_HS_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0068)
+#define OMAP54XX_CM_L3INIT_IEEE1500_2_OCP_CLKCTRL_OFFSET 0x0078
+#define OMAP54XX_CM_L3INIT_IEEE1500_2_OCP_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0078)
+#define OMAP54XX_CM_L3INIT_SATA_CLKCTRL_OFFSET 0x0088
+#define OMAP54XX_CM_L3INIT_SATA_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0088)
+#define OMAP54XX_CM_L3INIT_OCP2SCP1_CLKCTRL_OFFSET 0x00e0
+#define OMAP54XX_CM_L3INIT_OCP2SCP1_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x00e0)
+#define OMAP54XX_CM_L3INIT_OCP2SCP3_CLKCTRL_OFFSET 0x00e8
+#define OMAP54XX_CM_L3INIT_OCP2SCP3_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x00e8)
+#define OMAP54XX_CM_L3INIT_USB_OTG_SS_CLKCTRL_OFFSET 0x00f0
+#define OMAP54XX_CM_L3INIT_USB_OTG_SS_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x00f0)
+
+/* CM_CORE.CUSTEFUSE_CM_CORE register offsets */
+#define OMAP54XX_CM_CUSTEFUSE_CLKSTCTRL_OFFSET 0x0000
+#define OMAP54XX_CM_CUSTEFUSE_EFUSE_CTRL_CUST_CLKCTRL_OFFSET 0x0020
+#define OMAP54XX_CM_CUSTEFUSE_EFUSE_CTRL_CUST_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CUSTEFUSE_INST, 0x0020)
+
+#endif
diff --git a/arch/arm/mach-omap2/cm2_7xx.h b/arch/arm/mach-omap2/cm2_7xx.h
new file mode 100644
index 000000000..ce63fdb68
--- /dev/null
+++ b/arch/arm/mach-omap2/cm2_7xx.h
@@ -0,0 +1,515 @@
+/*
+ * DRA7xx CM2 instance offset macros
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Generated by code originally written by:
+ * 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_CM2_7XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM2_7XX_H
+
+/* CM2 base address */
+#define DRA7XX_CM_CORE_BASE 0x4a008000
+
+#define DRA7XX_CM_CORE_REGADDR(inst, reg) \
+ OMAP2_L4_IO_ADDRESS(DRA7XX_CM_CORE_BASE + (inst) + (reg))
+
+/* CM_CORE instances */
+#define DRA7XX_CM_CORE_OCP_SOCKET_INST 0x0000
+#define DRA7XX_CM_CORE_CKGEN_INST 0x0104
+#define DRA7XX_CM_CORE_COREAON_INST 0x0600
+#define DRA7XX_CM_CORE_CORE_INST 0x0700
+#define DRA7XX_CM_CORE_IVA_INST 0x0f00
+#define DRA7XX_CM_CORE_CAM_INST 0x1000
+#define DRA7XX_CM_CORE_DSS_INST 0x1100
+#define DRA7XX_CM_CORE_GPU_INST 0x1200
+#define DRA7XX_CM_CORE_L3INIT_INST 0x1300
+#define DRA7XX_CM_CORE_CUSTEFUSE_INST 0x1600
+#define DRA7XX_CM_CORE_L4PER_INST 0x1700
+#define DRA7XX_CM_CORE_RESTORE_INST 0x1e18
+
+/* CM_CORE clockdomain register offsets (from instance start) */
+#define DRA7XX_CM_CORE_COREAON_COREAON_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_CORE_L3MAIN1_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_CORE_IPU2_CDOFFS 0x0200
+#define DRA7XX_CM_CORE_CORE_DMA_CDOFFS 0x0300
+#define DRA7XX_CM_CORE_CORE_EMIF_CDOFFS 0x0400
+#define DRA7XX_CM_CORE_CORE_ATL_CDOFFS 0x0520
+#define DRA7XX_CM_CORE_CORE_L4CFG_CDOFFS 0x0600
+#define DRA7XX_CM_CORE_CORE_L3INSTR_CDOFFS 0x0700
+#define DRA7XX_CM_CORE_IVA_IVA_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_CAM_CAM_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_DSS_DSS_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_GPU_GPU_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_L3INIT_L3INIT_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_L3INIT_PCIE_CDOFFS 0x00a0
+#define DRA7XX_CM_CORE_L3INIT_GMAC_CDOFFS 0x00c0
+#define DRA7XX_CM_CORE_CUSTEFUSE_CUSTEFUSE_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_L4PER_L4PER_CDOFFS 0x0000
+#define DRA7XX_CM_CORE_L4PER_L4SEC_CDOFFS 0x0180
+#define DRA7XX_CM_CORE_L4PER_L4PER2_CDOFFS 0x01fc
+#define DRA7XX_CM_CORE_L4PER_L4PER3_CDOFFS 0x0210
+
+/* CM_CORE */
+
+/* CM_CORE.OCP_SOCKET_CM_CORE register offsets */
+#define DRA7XX_REVISION_CM_CORE_OFFSET 0x0000
+#define DRA7XX_CM_CM_CORE_PROFILING_CLKCTRL_OFFSET 0x0040
+#define DRA7XX_CM_CM_CORE_PROFILING_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_OCP_SOCKET_INST, 0x0040)
+#define DRA7XX_CM_CORE_DEBUG_CFG_OFFSET 0x00f0
+
+/* CM_CORE.CKGEN_CM_CORE register offsets */
+#define DRA7XX_CM_CLKSEL_USB_60MHZ_OFFSET 0x0000
+#define DRA7XX_CM_CLKSEL_USB_60MHZ DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0000)
+#define DRA7XX_CM_CLKMODE_DPLL_PER_OFFSET 0x003c
+#define DRA7XX_CM_CLKMODE_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x003c)
+#define DRA7XX_CM_IDLEST_DPLL_PER_OFFSET 0x0040
+#define DRA7XX_CM_IDLEST_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0040)
+#define DRA7XX_CM_AUTOIDLE_DPLL_PER_OFFSET 0x0044
+#define DRA7XX_CM_AUTOIDLE_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0044)
+#define DRA7XX_CM_CLKSEL_DPLL_PER_OFFSET 0x0048
+#define DRA7XX_CM_CLKSEL_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0048)
+#define DRA7XX_CM_DIV_M2_DPLL_PER_OFFSET 0x004c
+#define DRA7XX_CM_DIV_M2_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x004c)
+#define DRA7XX_CM_DIV_M3_DPLL_PER_OFFSET 0x0050
+#define DRA7XX_CM_DIV_M3_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0050)
+#define DRA7XX_CM_DIV_H11_DPLL_PER_OFFSET 0x0054
+#define DRA7XX_CM_DIV_H11_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0054)
+#define DRA7XX_CM_DIV_H12_DPLL_PER_OFFSET 0x0058
+#define DRA7XX_CM_DIV_H12_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0058)
+#define DRA7XX_CM_DIV_H13_DPLL_PER_OFFSET 0x005c
+#define DRA7XX_CM_DIV_H13_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x005c)
+#define DRA7XX_CM_DIV_H14_DPLL_PER_OFFSET 0x0060
+#define DRA7XX_CM_DIV_H14_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0060)
+#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_PER_OFFSET 0x0064
+#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_PER_OFFSET 0x0068
+#define DRA7XX_CM_CLKMODE_DPLL_USB_OFFSET 0x007c
+#define DRA7XX_CM_CLKMODE_DPLL_USB DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x007c)
+#define DRA7XX_CM_IDLEST_DPLL_USB_OFFSET 0x0080
+#define DRA7XX_CM_IDLEST_DPLL_USB DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0080)
+#define DRA7XX_CM_AUTOIDLE_DPLL_USB_OFFSET 0x0084
+#define DRA7XX_CM_AUTOIDLE_DPLL_USB DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0084)
+#define DRA7XX_CM_CLKSEL_DPLL_USB_OFFSET 0x0088
+#define DRA7XX_CM_CLKSEL_DPLL_USB DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0088)
+#define DRA7XX_CM_DIV_M2_DPLL_USB_OFFSET 0x008c
+#define DRA7XX_CM_DIV_M2_DPLL_USB DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x008c)
+#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_USB_OFFSET 0x00a4
+#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_USB_OFFSET 0x00a8
+#define DRA7XX_CM_CLKDCOLDO_DPLL_USB_OFFSET 0x00b0
+#define DRA7XX_CM_CLKDCOLDO_DPLL_USB DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x00b0)
+#define DRA7XX_CM_CLKMODE_DPLL_PCIE_REF_OFFSET 0x00fc
+#define DRA7XX_CM_CLKMODE_DPLL_PCIE_REF DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x00fc)
+#define DRA7XX_CM_IDLEST_DPLL_PCIE_REF_OFFSET 0x0100
+#define DRA7XX_CM_IDLEST_DPLL_PCIE_REF DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0100)
+#define DRA7XX_CM_AUTOIDLE_DPLL_PCIE_REF_OFFSET 0x0104
+#define DRA7XX_CM_AUTOIDLE_DPLL_PCIE_REF DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0104)
+#define DRA7XX_CM_CLKSEL_DPLL_PCIE_REF_OFFSET 0x0108
+#define DRA7XX_CM_CLKSEL_DPLL_PCIE_REF DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0108)
+#define DRA7XX_CM_DIV_M2_DPLL_PCIE_REF_OFFSET 0x010c
+#define DRA7XX_CM_DIV_M2_DPLL_PCIE_REF DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x010c)
+#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_PCIE_REF_OFFSET 0x0110
+#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_PCIE_REF_OFFSET 0x0114
+#define DRA7XX_CM_CLKMODE_APLL_PCIE_OFFSET 0x0118
+#define DRA7XX_CM_CLKMODE_APLL_PCIE DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0118)
+#define DRA7XX_CM_IDLEST_APLL_PCIE_OFFSET 0x011c
+#define DRA7XX_CM_IDLEST_APLL_PCIE DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x011c)
+#define DRA7XX_CM_DIV_M2_APLL_PCIE_OFFSET 0x0120
+#define DRA7XX_CM_DIV_M2_APLL_PCIE DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0120)
+#define DRA7XX_CM_CLKVCOLDO_APLL_PCIE_OFFSET 0x0124
+#define DRA7XX_CM_CLKVCOLDO_APLL_PCIE DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0124)
+
+/* CM_CORE.COREAON_CM_CORE register offsets */
+#define DRA7XX_CM_COREAON_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_COREAON_SMARTREFLEX_MPU_CLKCTRL_OFFSET 0x0028
+#define DRA7XX_CM_COREAON_SMARTREFLEX_MPU_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0028)
+#define DRA7XX_CM_COREAON_SMARTREFLEX_CORE_CLKCTRL_OFFSET 0x0038
+#define DRA7XX_CM_COREAON_SMARTREFLEX_CORE_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0038)
+#define DRA7XX_CM_COREAON_USB_PHY1_CORE_CLKCTRL_OFFSET 0x0040
+#define DRA7XX_CM_COREAON_USB_PHY1_CORE_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0040)
+#define DRA7XX_CM_COREAON_IO_SRCOMP_CLKCTRL_OFFSET 0x0050
+#define DRA7XX_CM_COREAON_IO_SRCOMP_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0050)
+#define DRA7XX_CM_COREAON_SMARTREFLEX_GPU_CLKCTRL_OFFSET 0x0058
+#define DRA7XX_CM_COREAON_SMARTREFLEX_GPU_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0058)
+#define DRA7XX_CM_COREAON_SMARTREFLEX_DSPEVE_CLKCTRL_OFFSET 0x0068
+#define DRA7XX_CM_COREAON_SMARTREFLEX_DSPEVE_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0068)
+#define DRA7XX_CM_COREAON_SMARTREFLEX_IVAHD_CLKCTRL_OFFSET 0x0078
+#define DRA7XX_CM_COREAON_SMARTREFLEX_IVAHD_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0078)
+#define DRA7XX_CM_COREAON_USB_PHY2_CORE_CLKCTRL_OFFSET 0x0088
+#define DRA7XX_CM_COREAON_USB_PHY2_CORE_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0088)
+#define DRA7XX_CM_COREAON_USB_PHY3_CORE_CLKCTRL_OFFSET 0x0098
+#define DRA7XX_CM_COREAON_USB_PHY3_CORE_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0098)
+#define DRA7XX_CM_COREAON_DUMMY_MODULE1_CLKCTRL_OFFSET 0x00a0
+#define DRA7XX_CM_COREAON_DUMMY_MODULE1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x00a0)
+#define DRA7XX_CM_COREAON_DUMMY_MODULE2_CLKCTRL_OFFSET 0x00b0
+#define DRA7XX_CM_COREAON_DUMMY_MODULE2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x00b0)
+#define DRA7XX_CM_COREAON_DUMMY_MODULE3_CLKCTRL_OFFSET 0x00c0
+#define DRA7XX_CM_COREAON_DUMMY_MODULE3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x00c0)
+#define DRA7XX_CM_COREAON_DUMMY_MODULE4_CLKCTRL_OFFSET 0x00d0
+#define DRA7XX_CM_COREAON_DUMMY_MODULE4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x00d0)
+
+/* CM_CORE.CORE_CM_CORE register offsets */
+#define DRA7XX_CM_L3MAIN1_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_L3MAIN1_DYNAMICDEP_OFFSET 0x0008
+#define DRA7XX_CM_L3MAIN1_L3_MAIN_1_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_L3MAIN1_L3_MAIN_1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0020)
+#define DRA7XX_CM_L3MAIN1_GPMC_CLKCTRL_OFFSET 0x0028
+#define DRA7XX_CM_L3MAIN1_GPMC_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0028)
+#define DRA7XX_CM_L3MAIN1_MMU_EDMA_CLKCTRL_OFFSET 0x0030
+#define DRA7XX_CM_L3MAIN1_MMU_EDMA_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0030)
+#define DRA7XX_CM_L3MAIN1_OCMC_RAM1_CLKCTRL_OFFSET 0x0050
+#define DRA7XX_CM_L3MAIN1_OCMC_RAM1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0050)
+#define DRA7XX_CM_L3MAIN1_OCMC_RAM2_CLKCTRL_OFFSET 0x0058
+#define DRA7XX_CM_L3MAIN1_OCMC_RAM2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0058)
+#define DRA7XX_CM_L3MAIN1_OCMC_RAM3_CLKCTRL_OFFSET 0x0060
+#define DRA7XX_CM_L3MAIN1_OCMC_RAM3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0060)
+#define DRA7XX_CM_L3MAIN1_OCMC_ROM_CLKCTRL_OFFSET 0x0068
+#define DRA7XX_CM_L3MAIN1_OCMC_ROM_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0068)
+#define DRA7XX_CM_L3MAIN1_TPCC_CLKCTRL_OFFSET 0x0070
+#define DRA7XX_CM_L3MAIN1_TPCC_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0070)
+#define DRA7XX_CM_L3MAIN1_TPTC1_CLKCTRL_OFFSET 0x0078
+#define DRA7XX_CM_L3MAIN1_TPTC1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0078)
+#define DRA7XX_CM_L3MAIN1_TPTC2_CLKCTRL_OFFSET 0x0080
+#define DRA7XX_CM_L3MAIN1_TPTC2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0080)
+#define DRA7XX_CM_L3MAIN1_VCP1_CLKCTRL_OFFSET 0x0088
+#define DRA7XX_CM_L3MAIN1_VCP1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0088)
+#define DRA7XX_CM_L3MAIN1_VCP2_CLKCTRL_OFFSET 0x0090
+#define DRA7XX_CM_L3MAIN1_VCP2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0090)
+#define DRA7XX_CM_L3MAIN1_SPARE_CME_CLKCTRL_OFFSET 0x0098
+#define DRA7XX_CM_L3MAIN1_SPARE_CME_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0098)
+#define DRA7XX_CM_L3MAIN1_SPARE_HDMI_CLKCTRL_OFFSET 0x00a0
+#define DRA7XX_CM_L3MAIN1_SPARE_HDMI_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00a0)
+#define DRA7XX_CM_L3MAIN1_SPARE_ICM_CLKCTRL_OFFSET 0x00a8
+#define DRA7XX_CM_L3MAIN1_SPARE_ICM_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00a8)
+#define DRA7XX_CM_L3MAIN1_SPARE_IVA2_CLKCTRL_OFFSET 0x00b0
+#define DRA7XX_CM_L3MAIN1_SPARE_IVA2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00b0)
+#define DRA7XX_CM_L3MAIN1_SPARE_SATA2_CLKCTRL_OFFSET 0x00b8
+#define DRA7XX_CM_L3MAIN1_SPARE_SATA2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00b8)
+#define DRA7XX_CM_L3MAIN1_SPARE_UNKNOWN4_CLKCTRL_OFFSET 0x00c0
+#define DRA7XX_CM_L3MAIN1_SPARE_UNKNOWN4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00c0)
+#define DRA7XX_CM_L3MAIN1_SPARE_UNKNOWN5_CLKCTRL_OFFSET 0x00c8
+#define DRA7XX_CM_L3MAIN1_SPARE_UNKNOWN5_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00c8)
+#define DRA7XX_CM_L3MAIN1_SPARE_UNKNOWN6_CLKCTRL_OFFSET 0x00d0
+#define DRA7XX_CM_L3MAIN1_SPARE_UNKNOWN6_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00d0)
+#define DRA7XX_CM_L3MAIN1_SPARE_VIDEOPLL1_CLKCTRL_OFFSET 0x00d8
+#define DRA7XX_CM_L3MAIN1_SPARE_VIDEOPLL1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00d8)
+#define DRA7XX_CM_L3MAIN1_SPARE_VIDEOPLL2_CLKCTRL_OFFSET 0x00f0
+#define DRA7XX_CM_L3MAIN1_SPARE_VIDEOPLL2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00f0)
+#define DRA7XX_CM_L3MAIN1_SPARE_VIDEOPLL3_CLKCTRL_OFFSET 0x00f8
+#define DRA7XX_CM_L3MAIN1_SPARE_VIDEOPLL3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00f8)
+#define DRA7XX_CM_IPU2_CLKSTCTRL_OFFSET 0x0200
+#define DRA7XX_CM_IPU2_STATICDEP_OFFSET 0x0204
+#define DRA7XX_CM_IPU2_DYNAMICDEP_OFFSET 0x0208
+#define DRA7XX_CM_IPU2_IPU2_CLKCTRL_OFFSET 0x0220
+#define DRA7XX_CM_IPU2_IPU2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0220)
+#define DRA7XX_CM_DMA_CLKSTCTRL_OFFSET 0x0300
+#define DRA7XX_CM_DMA_STATICDEP_OFFSET 0x0304
+#define DRA7XX_CM_DMA_DYNAMICDEP_OFFSET 0x0308
+#define DRA7XX_CM_DMA_DMA_SYSTEM_CLKCTRL_OFFSET 0x0320
+#define DRA7XX_CM_DMA_DMA_SYSTEM_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0320)
+#define DRA7XX_CM_EMIF_CLKSTCTRL_OFFSET 0x0400
+#define DRA7XX_CM_EMIF_DMM_CLKCTRL_OFFSET 0x0420
+#define DRA7XX_CM_EMIF_DMM_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0420)
+#define DRA7XX_CM_EMIF_EMIF_OCP_FW_CLKCTRL_OFFSET 0x0428
+#define DRA7XX_CM_EMIF_EMIF_OCP_FW_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0428)
+#define DRA7XX_CM_EMIF_EMIF1_CLKCTRL_OFFSET 0x0430
+#define DRA7XX_CM_EMIF_EMIF1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0430)
+#define DRA7XX_CM_EMIF_EMIF2_CLKCTRL_OFFSET 0x0438
+#define DRA7XX_CM_EMIF_EMIF2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0438)
+#define DRA7XX_CM_EMIF_EMIF_DLL_CLKCTRL_OFFSET 0x0440
+#define DRA7XX_CM_EMIF_EMIF_DLL_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0440)
+#define DRA7XX_CM_ATL_ATL_CLKCTRL_OFFSET 0x0500
+#define DRA7XX_CM_ATL_ATL_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0500)
+#define DRA7XX_CM_ATL_CLKSTCTRL_OFFSET 0x0520
+#define DRA7XX_CM_L4CFG_CLKSTCTRL_OFFSET 0x0600
+#define DRA7XX_CM_L4CFG_DYNAMICDEP_OFFSET 0x0608
+#define DRA7XX_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET 0x0620
+#define DRA7XX_CM_L4CFG_L4_CFG_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0620)
+#define DRA7XX_CM_L4CFG_SPINLOCK_CLKCTRL_OFFSET 0x0628
+#define DRA7XX_CM_L4CFG_SPINLOCK_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0628)
+#define DRA7XX_CM_L4CFG_MAILBOX1_CLKCTRL_OFFSET 0x0630
+#define DRA7XX_CM_L4CFG_MAILBOX1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0630)
+#define DRA7XX_CM_L4CFG_SAR_ROM_CLKCTRL_OFFSET 0x0638
+#define DRA7XX_CM_L4CFG_SAR_ROM_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0638)
+#define DRA7XX_CM_L4CFG_OCP2SCP2_CLKCTRL_OFFSET 0x0640
+#define DRA7XX_CM_L4CFG_OCP2SCP2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0640)
+#define DRA7XX_CM_L4CFG_MAILBOX2_CLKCTRL_OFFSET 0x0648
+#define DRA7XX_CM_L4CFG_MAILBOX2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0648)
+#define DRA7XX_CM_L4CFG_MAILBOX3_CLKCTRL_OFFSET 0x0650
+#define DRA7XX_CM_L4CFG_MAILBOX3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0650)
+#define DRA7XX_CM_L4CFG_MAILBOX4_CLKCTRL_OFFSET 0x0658
+#define DRA7XX_CM_L4CFG_MAILBOX4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0658)
+#define DRA7XX_CM_L4CFG_MAILBOX5_CLKCTRL_OFFSET 0x0660
+#define DRA7XX_CM_L4CFG_MAILBOX5_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0660)
+#define DRA7XX_CM_L4CFG_MAILBOX6_CLKCTRL_OFFSET 0x0668
+#define DRA7XX_CM_L4CFG_MAILBOX6_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0668)
+#define DRA7XX_CM_L4CFG_MAILBOX7_CLKCTRL_OFFSET 0x0670
+#define DRA7XX_CM_L4CFG_MAILBOX7_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0670)
+#define DRA7XX_CM_L4CFG_MAILBOX8_CLKCTRL_OFFSET 0x0678
+#define DRA7XX_CM_L4CFG_MAILBOX8_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0678)
+#define DRA7XX_CM_L4CFG_MAILBOX9_CLKCTRL_OFFSET 0x0680
+#define DRA7XX_CM_L4CFG_MAILBOX9_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0680)
+#define DRA7XX_CM_L4CFG_MAILBOX10_CLKCTRL_OFFSET 0x0688
+#define DRA7XX_CM_L4CFG_MAILBOX10_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0688)
+#define DRA7XX_CM_L4CFG_MAILBOX11_CLKCTRL_OFFSET 0x0690
+#define DRA7XX_CM_L4CFG_MAILBOX11_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0690)
+#define DRA7XX_CM_L4CFG_MAILBOX12_CLKCTRL_OFFSET 0x0698
+#define DRA7XX_CM_L4CFG_MAILBOX12_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0698)
+#define DRA7XX_CM_L4CFG_MAILBOX13_CLKCTRL_OFFSET 0x06a0
+#define DRA7XX_CM_L4CFG_MAILBOX13_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x06a0)
+#define DRA7XX_CM_L4CFG_SPARE_SMARTREFLEX_RTC_CLKCTRL_OFFSET 0x06a8
+#define DRA7XX_CM_L4CFG_SPARE_SMARTREFLEX_RTC_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x06a8)
+#define DRA7XX_CM_L4CFG_SPARE_SMARTREFLEX_SDRAM_CLKCTRL_OFFSET 0x06b0
+#define DRA7XX_CM_L4CFG_SPARE_SMARTREFLEX_SDRAM_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x06b0)
+#define DRA7XX_CM_L4CFG_SPARE_SMARTREFLEX_WKUP_CLKCTRL_OFFSET 0x06b8
+#define DRA7XX_CM_L4CFG_SPARE_SMARTREFLEX_WKUP_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x06b8)
+#define DRA7XX_CM_L4CFG_IO_DELAY_BLOCK_CLKCTRL_OFFSET 0x06c0
+#define DRA7XX_CM_L4CFG_IO_DELAY_BLOCK_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x06c0)
+#define DRA7XX_CM_L3INSTR_CLKSTCTRL_OFFSET 0x0700
+#define DRA7XX_CM_L3INSTR_L3_MAIN_2_CLKCTRL_OFFSET 0x0720
+#define DRA7XX_CM_L3INSTR_L3_MAIN_2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0720)
+#define DRA7XX_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET 0x0728
+#define DRA7XX_CM_L3INSTR_L3_INSTR_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0728)
+#define DRA7XX_CM_L3INSTR_OCP_WP_NOC_CLKCTRL_OFFSET 0x0740
+#define DRA7XX_CM_L3INSTR_OCP_WP_NOC_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0740)
+#define DRA7XX_CM_L3INSTR_DLL_AGING_CLKCTRL_OFFSET 0x0748
+#define DRA7XX_CM_L3INSTR_DLL_AGING_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0748)
+#define DRA7XX_CM_L3INSTR_CTRL_MODULE_BANDGAP_CLKCTRL_OFFSET 0x0750
+#define DRA7XX_CM_L3INSTR_CTRL_MODULE_BANDGAP_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0750)
+
+/* CM_CORE.IVA_CM_CORE register offsets */
+#define DRA7XX_CM_IVA_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_IVA_STATICDEP_OFFSET 0x0004
+#define DRA7XX_CM_IVA_DYNAMICDEP_OFFSET 0x0008
+#define DRA7XX_CM_IVA_IVA_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_IVA_IVA_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_IVA_INST, 0x0020)
+#define DRA7XX_CM_IVA_SL2_CLKCTRL_OFFSET 0x0028
+#define DRA7XX_CM_IVA_SL2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_IVA_INST, 0x0028)
+
+/* CM_CORE.CAM_CM_CORE register offsets */
+#define DRA7XX_CM_CAM_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_CAM_STATICDEP_OFFSET 0x0004
+#define DRA7XX_CM_CAM_VIP1_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_CAM_VIP1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CAM_INST, 0x0020)
+#define DRA7XX_CM_CAM_VIP2_CLKCTRL_OFFSET 0x0028
+#define DRA7XX_CM_CAM_VIP2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CAM_INST, 0x0028)
+#define DRA7XX_CM_CAM_VIP3_CLKCTRL_OFFSET 0x0030
+#define DRA7XX_CM_CAM_VIP3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CAM_INST, 0x0030)
+#define DRA7XX_CM_CAM_LVDSRX_CLKCTRL_OFFSET 0x0038
+#define DRA7XX_CM_CAM_LVDSRX_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CAM_INST, 0x0038)
+#define DRA7XX_CM_CAM_CSI1_CLKCTRL_OFFSET 0x0040
+#define DRA7XX_CM_CAM_CSI1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CAM_INST, 0x0040)
+#define DRA7XX_CM_CAM_CSI2_CLKCTRL_OFFSET 0x0048
+#define DRA7XX_CM_CAM_CSI2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CAM_INST, 0x0048)
+
+/* CM_CORE.DSS_CM_CORE register offsets */
+#define DRA7XX_CM_DSS_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_DSS_STATICDEP_OFFSET 0x0004
+#define DRA7XX_CM_DSS_DYNAMICDEP_OFFSET 0x0008
+#define DRA7XX_CM_DSS_DSS_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_DSS_DSS_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_DSS_INST, 0x0020)
+#define DRA7XX_CM_DSS_BB2D_CLKCTRL_OFFSET 0x0030
+#define DRA7XX_CM_DSS_BB2D_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_DSS_INST, 0x0030)
+#define DRA7XX_CM_DSS_SDVENC_CLKCTRL_OFFSET 0x003c
+#define DRA7XX_CM_DSS_SDVENC_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_DSS_INST, 0x003c)
+
+/* CM_CORE.GPU_CM_CORE register offsets */
+#define DRA7XX_CM_GPU_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_GPU_STATICDEP_OFFSET 0x0004
+#define DRA7XX_CM_GPU_DYNAMICDEP_OFFSET 0x0008
+#define DRA7XX_CM_GPU_GPU_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_GPU_GPU_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_GPU_INST, 0x0020)
+
+/* CM_CORE.L3INIT_CM_CORE register offsets */
+#define DRA7XX_CM_L3INIT_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_L3INIT_STATICDEP_OFFSET 0x0004
+#define DRA7XX_CM_L3INIT_DYNAMICDEP_OFFSET 0x0008
+#define DRA7XX_CM_L3INIT_MMC1_CLKCTRL_OFFSET 0x0028
+#define DRA7XX_CM_L3INIT_MMC1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x0028)
+#define DRA7XX_CM_L3INIT_MMC2_CLKCTRL_OFFSET 0x0030
+#define DRA7XX_CM_L3INIT_MMC2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x0030)
+#define DRA7XX_CM_L3INIT_USB_OTG_SS2_CLKCTRL_OFFSET 0x0040
+#define DRA7XX_CM_L3INIT_USB_OTG_SS2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x0040)
+#define DRA7XX_CM_L3INIT_USB_OTG_SS3_CLKCTRL_OFFSET 0x0048
+#define DRA7XX_CM_L3INIT_USB_OTG_SS3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x0048)
+#define DRA7XX_CM_L3INIT_USB_OTG_SS4_CLKCTRL_OFFSET 0x0050
+#define DRA7XX_CM_L3INIT_USB_OTG_SS4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x0050)
+#define DRA7XX_CM_L3INIT_MLB_SS_CLKCTRL_OFFSET 0x0058
+#define DRA7XX_CM_L3INIT_MLB_SS_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x0058)
+#define DRA7XX_CM_L3INIT_IEEE1500_2_OCP_CLKCTRL_OFFSET 0x0078
+#define DRA7XX_CM_L3INIT_IEEE1500_2_OCP_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x0078)
+#define DRA7XX_CM_L3INIT_SATA_CLKCTRL_OFFSET 0x0088
+#define DRA7XX_CM_L3INIT_SATA_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x0088)
+#define DRA7XX_CM_PCIE_CLKSTCTRL_OFFSET 0x00a0
+#define DRA7XX_CM_PCIE_STATICDEP_OFFSET 0x00a4
+#define DRA7XX_CM_L3INIT_PCIESS1_CLKCTRL_OFFSET 0x00b0
+#define DRA7XX_CM_L3INIT_PCIESS1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x00b0)
+#define DRA7XX_CM_L3INIT_PCIESS2_CLKCTRL_OFFSET 0x00b8
+#define DRA7XX_CM_L3INIT_PCIESS2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x00b8)
+#define DRA7XX_CM_GMAC_CLKSTCTRL_OFFSET 0x00c0
+#define DRA7XX_CM_GMAC_STATICDEP_OFFSET 0x00c4
+#define DRA7XX_CM_GMAC_DYNAMICDEP_OFFSET 0x00c8
+#define DRA7XX_CM_GMAC_GMAC_CLKCTRL_OFFSET 0x00d0
+#define DRA7XX_CM_GMAC_GMAC_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x00d0)
+#define DRA7XX_CM_L3INIT_OCP2SCP1_CLKCTRL_OFFSET 0x00e0
+#define DRA7XX_CM_L3INIT_OCP2SCP1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x00e0)
+#define DRA7XX_CM_L3INIT_OCP2SCP3_CLKCTRL_OFFSET 0x00e8
+#define DRA7XX_CM_L3INIT_OCP2SCP3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x00e8)
+#define DRA7XX_CM_L3INIT_USB_OTG_SS1_CLKCTRL_OFFSET 0x00f0
+#define DRA7XX_CM_L3INIT_USB_OTG_SS1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x00f0)
+
+/* CM_CORE.CUSTEFUSE_CM_CORE register offsets */
+#define DRA7XX_CM_CUSTEFUSE_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_CUSTEFUSE_EFUSE_CTRL_CUST_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_CUSTEFUSE_EFUSE_CTRL_CUST_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CUSTEFUSE_INST, 0x0020)
+
+/* CM_CORE.L4PER_CM_CORE register offsets */
+#define DRA7XX_CM_L4PER_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_L4PER_DYNAMICDEP_OFFSET 0x0008
+#define DRA7XX_CM_L4PER2_L4_PER2_CLKCTRL_OFFSET 0x000c
+#define DRA7XX_CM_L4PER2_L4_PER2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x000c)
+#define DRA7XX_CM_L4PER3_L4_PER3_CLKCTRL_OFFSET 0x0014
+#define DRA7XX_CM_L4PER3_L4_PER3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0014)
+#define DRA7XX_CM_L4PER2_PRUSS1_CLKCTRL_OFFSET 0x0018
+#define DRA7XX_CM_L4PER2_PRUSS1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0018)
+#define DRA7XX_CM_L4PER2_PRUSS2_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_L4PER2_PRUSS2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0020)
+#define DRA7XX_CM_L4PER_TIMER10_CLKCTRL_OFFSET 0x0028
+#define DRA7XX_CM_L4PER_TIMER10_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0028)
+#define DRA7XX_CM_L4PER_TIMER11_CLKCTRL_OFFSET 0x0030
+#define DRA7XX_CM_L4PER_TIMER11_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0030)
+#define DRA7XX_CM_L4PER_TIMER2_CLKCTRL_OFFSET 0x0038
+#define DRA7XX_CM_L4PER_TIMER2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0038)
+#define DRA7XX_CM_L4PER_TIMER3_CLKCTRL_OFFSET 0x0040
+#define DRA7XX_CM_L4PER_TIMER3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0040)
+#define DRA7XX_CM_L4PER_TIMER4_CLKCTRL_OFFSET 0x0048
+#define DRA7XX_CM_L4PER_TIMER4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0048)
+#define DRA7XX_CM_L4PER_TIMER9_CLKCTRL_OFFSET 0x0050
+#define DRA7XX_CM_L4PER_TIMER9_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0050)
+#define DRA7XX_CM_L4PER_ELM_CLKCTRL_OFFSET 0x0058
+#define DRA7XX_CM_L4PER_ELM_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0058)
+#define DRA7XX_CM_L4PER_GPIO2_CLKCTRL_OFFSET 0x0060
+#define DRA7XX_CM_L4PER_GPIO2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0060)
+#define DRA7XX_CM_L4PER_GPIO3_CLKCTRL_OFFSET 0x0068
+#define DRA7XX_CM_L4PER_GPIO3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0068)
+#define DRA7XX_CM_L4PER_GPIO4_CLKCTRL_OFFSET 0x0070
+#define DRA7XX_CM_L4PER_GPIO4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0070)
+#define DRA7XX_CM_L4PER_GPIO5_CLKCTRL_OFFSET 0x0078
+#define DRA7XX_CM_L4PER_GPIO5_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0078)
+#define DRA7XX_CM_L4PER_GPIO6_CLKCTRL_OFFSET 0x0080
+#define DRA7XX_CM_L4PER_GPIO6_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0080)
+#define DRA7XX_CM_L4PER_HDQ1W_CLKCTRL_OFFSET 0x0088
+#define DRA7XX_CM_L4PER_HDQ1W_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0088)
+#define DRA7XX_CM_L4PER2_PWMSS2_CLKCTRL_OFFSET 0x0090
+#define DRA7XX_CM_L4PER2_PWMSS2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0090)
+#define DRA7XX_CM_L4PER2_PWMSS3_CLKCTRL_OFFSET 0x0098
+#define DRA7XX_CM_L4PER2_PWMSS3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0098)
+#define DRA7XX_CM_L4PER_I2C1_CLKCTRL_OFFSET 0x00a0
+#define DRA7XX_CM_L4PER_I2C1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00a0)
+#define DRA7XX_CM_L4PER_I2C2_CLKCTRL_OFFSET 0x00a8
+#define DRA7XX_CM_L4PER_I2C2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00a8)
+#define DRA7XX_CM_L4PER_I2C3_CLKCTRL_OFFSET 0x00b0
+#define DRA7XX_CM_L4PER_I2C3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00b0)
+#define DRA7XX_CM_L4PER_I2C4_CLKCTRL_OFFSET 0x00b8
+#define DRA7XX_CM_L4PER_I2C4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00b8)
+#define DRA7XX_CM_L4PER_L4_PER1_CLKCTRL_OFFSET 0x00c0
+#define DRA7XX_CM_L4PER_L4_PER1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00c0)
+#define DRA7XX_CM_L4PER2_PWMSS1_CLKCTRL_OFFSET 0x00c4
+#define DRA7XX_CM_L4PER2_PWMSS1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00c4)
+#define DRA7XX_CM_L4PER3_TIMER13_CLKCTRL_OFFSET 0x00c8
+#define DRA7XX_CM_L4PER3_TIMER13_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00c8)
+#define DRA7XX_CM_L4PER3_TIMER14_CLKCTRL_OFFSET 0x00d0
+#define DRA7XX_CM_L4PER3_TIMER14_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00d0)
+#define DRA7XX_CM_L4PER3_TIMER15_CLKCTRL_OFFSET 0x00d8
+#define DRA7XX_CM_L4PER3_TIMER15_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00d8)
+#define DRA7XX_CM_L4PER_MCSPI1_CLKCTRL_OFFSET 0x00f0
+#define DRA7XX_CM_L4PER_MCSPI1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00f0)
+#define DRA7XX_CM_L4PER_MCSPI2_CLKCTRL_OFFSET 0x00f8
+#define DRA7XX_CM_L4PER_MCSPI2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00f8)
+#define DRA7XX_CM_L4PER_MCSPI3_CLKCTRL_OFFSET 0x0100
+#define DRA7XX_CM_L4PER_MCSPI3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0100)
+#define DRA7XX_CM_L4PER_MCSPI4_CLKCTRL_OFFSET 0x0108
+#define DRA7XX_CM_L4PER_MCSPI4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0108)
+#define DRA7XX_CM_L4PER_GPIO7_CLKCTRL_OFFSET 0x0110
+#define DRA7XX_CM_L4PER_GPIO7_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0110)
+#define DRA7XX_CM_L4PER_GPIO8_CLKCTRL_OFFSET 0x0118
+#define DRA7XX_CM_L4PER_GPIO8_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0118)
+#define DRA7XX_CM_L4PER_MMC3_CLKCTRL_OFFSET 0x0120
+#define DRA7XX_CM_L4PER_MMC3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0120)
+#define DRA7XX_CM_L4PER_MMC4_CLKCTRL_OFFSET 0x0128
+#define DRA7XX_CM_L4PER_MMC4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0128)
+#define DRA7XX_CM_L4PER3_TIMER16_CLKCTRL_OFFSET 0x0130
+#define DRA7XX_CM_L4PER3_TIMER16_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0130)
+#define DRA7XX_CM_L4PER2_QSPI_CLKCTRL_OFFSET 0x0138
+#define DRA7XX_CM_L4PER2_QSPI_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0138)
+#define DRA7XX_CM_L4PER_UART1_CLKCTRL_OFFSET 0x0140
+#define DRA7XX_CM_L4PER_UART1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0140)
+#define DRA7XX_CM_L4PER_UART2_CLKCTRL_OFFSET 0x0148
+#define DRA7XX_CM_L4PER_UART2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0148)
+#define DRA7XX_CM_L4PER_UART3_CLKCTRL_OFFSET 0x0150
+#define DRA7XX_CM_L4PER_UART3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0150)
+#define DRA7XX_CM_L4PER_UART4_CLKCTRL_OFFSET 0x0158
+#define DRA7XX_CM_L4PER_UART4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0158)
+#define DRA7XX_CM_L4PER2_MCASP2_CLKCTRL_OFFSET 0x0160
+#define DRA7XX_CM_L4PER2_MCASP2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0160)
+#define DRA7XX_CM_L4PER2_MCASP3_CLKCTRL_OFFSET 0x0168
+#define DRA7XX_CM_L4PER2_MCASP3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0168)
+#define DRA7XX_CM_L4PER_UART5_CLKCTRL_OFFSET 0x0170
+#define DRA7XX_CM_L4PER_UART5_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0170)
+#define DRA7XX_CM_L4PER2_MCASP5_CLKCTRL_OFFSET 0x0178
+#define DRA7XX_CM_L4PER2_MCASP5_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0178)
+#define DRA7XX_CM_L4SEC_CLKSTCTRL_OFFSET 0x0180
+#define DRA7XX_CM_L4SEC_STATICDEP_OFFSET 0x0184
+#define DRA7XX_CM_L4SEC_DYNAMICDEP_OFFSET 0x0188
+#define DRA7XX_CM_L4PER2_MCASP8_CLKCTRL_OFFSET 0x0190
+#define DRA7XX_CM_L4PER2_MCASP8_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0190)
+#define DRA7XX_CM_L4PER2_MCASP4_CLKCTRL_OFFSET 0x0198
+#define DRA7XX_CM_L4PER2_MCASP4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0198)
+#define DRA7XX_CM_L4SEC_AES1_CLKCTRL_OFFSET 0x01a0
+#define DRA7XX_CM_L4SEC_AES1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01a0)
+#define DRA7XX_CM_L4SEC_AES2_CLKCTRL_OFFSET 0x01a8
+#define DRA7XX_CM_L4SEC_AES2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01a8)
+#define DRA7XX_CM_L4SEC_DES3DES_CLKCTRL_OFFSET 0x01b0
+#define DRA7XX_CM_L4SEC_DES3DES_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01b0)
+#define DRA7XX_CM_L4SEC_FPKA_CLKCTRL_OFFSET 0x01b8
+#define DRA7XX_CM_L4SEC_FPKA_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01b8)
+#define DRA7XX_CM_L4SEC_RNG_CLKCTRL_OFFSET 0x01c0
+#define DRA7XX_CM_L4SEC_RNG_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01c0)
+#define DRA7XX_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET 0x01c8
+#define DRA7XX_CM_L4SEC_SHA2MD51_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01c8)
+#define DRA7XX_CM_L4PER2_UART7_CLKCTRL_OFFSET 0x01d0
+#define DRA7XX_CM_L4PER2_UART7_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01d0)
+#define DRA7XX_CM_L4SEC_DMA_CRYPTO_CLKCTRL_OFFSET 0x01d8
+#define DRA7XX_CM_L4SEC_DMA_CRYPTO_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01d8)
+#define DRA7XX_CM_L4PER2_UART8_CLKCTRL_OFFSET 0x01e0
+#define DRA7XX_CM_L4PER2_UART8_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01e0)
+#define DRA7XX_CM_L4PER2_UART9_CLKCTRL_OFFSET 0x01e8
+#define DRA7XX_CM_L4PER2_UART9_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01e8)
+#define DRA7XX_CM_L4PER2_DCAN2_CLKCTRL_OFFSET 0x01f0
+#define DRA7XX_CM_L4PER2_DCAN2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01f0)
+#define DRA7XX_CM_L4SEC_SHA2MD52_CLKCTRL_OFFSET 0x01f8
+#define DRA7XX_CM_L4SEC_SHA2MD52_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01f8)
+#define DRA7XX_CM_L4PER2_CLKSTCTRL_OFFSET 0x01fc
+#define DRA7XX_CM_L4PER2_DYNAMICDEP_OFFSET 0x0200
+#define DRA7XX_CM_L4PER2_MCASP6_CLKCTRL_OFFSET 0x0204
+#define DRA7XX_CM_L4PER2_MCASP6_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0204)
+#define DRA7XX_CM_L4PER2_MCASP7_CLKCTRL_OFFSET 0x0208
+#define DRA7XX_CM_L4PER2_MCASP7_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0208)
+#define DRA7XX_CM_L4PER2_STATICDEP_OFFSET 0x020c
+#define DRA7XX_CM_L4PER3_CLKSTCTRL_OFFSET 0x0210
+#define DRA7XX_CM_L4PER3_DYNAMICDEP_OFFSET 0x0214
+
+#endif
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c
new file mode 100644
index 000000000..3e5fd3587
--- /dev/null
+++ b/arch/arm/mach-omap2/cm2xxx.c
@@ -0,0 +1,405 @@
+/*
+ * OMAP2xxx CM module functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2008-2010, 2012 Texas Instruments, Inc.
+ * 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 <linux/types.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include "prm2xxx.h"
+#include "cm.h"
+#include "cm2xxx.h"
+#include "cm-regbits-24xx.h"
+#include "clockdomain.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
+
+/* CM_IDLEST_PLL bit value offset for APLLs (OMAP2xxx only) */
+#define EN_APLL_LOCKED 3
+
+static const u8 omap2xxx_cm_idlest_offs[] = {
+ CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3, OMAP24XX_CM_IDLEST4
+};
+
+/*
+ *
+ */
+
+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);
+}
+
+static bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
+{
+ u32 v;
+
+ v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
+ v &= mask;
+ v >>= __ffs(mask);
+
+ return (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
+}
+
+static void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
+}
+
+static void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, 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 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);
+}
+
+/* Enable an APLL if off */
+static int _omap2xxx_apll_enable(u8 enable_bit, u8 status_bit)
+{
+ u32 v, m;
+
+ m = EN_APLL_LOCKED << enable_bit;
+
+ v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+ if (v & m)
+ return 0; /* apll already enabled */
+
+ v |= m;
+ omap2_cm_write_mod_reg(v, PLL_MOD, CM_CLKEN);
+
+ omap2xxx_cm_wait_module_ready(0, PLL_MOD, 1, status_bit);
+
+ /*
+ * REVISIT: Should we return an error code if
+ * omap2xxx_cm_wait_module_ready() fails?
+ */
+ return 0;
+}
+
+/* Stop APLL */
+static void _omap2xxx_apll_disable(u8 enable_bit)
+{
+ u32 v;
+
+ v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+ v &= ~(EN_APLL_LOCKED << enable_bit);
+ omap2_cm_write_mod_reg(v, PLL_MOD, CM_CLKEN);
+}
+
+/* Enable an APLL if off */
+int omap2xxx_cm_apll54_enable(void)
+{
+ return _omap2xxx_apll_enable(OMAP24XX_EN_54M_PLL_SHIFT,
+ OMAP24XX_ST_54M_APLL_SHIFT);
+}
+
+/* Enable an APLL if off */
+int omap2xxx_cm_apll96_enable(void)
+{
+ return _omap2xxx_apll_enable(OMAP24XX_EN_96M_PLL_SHIFT,
+ OMAP24XX_ST_96M_APLL_SHIFT);
+}
+
+/* Stop APLL */
+void omap2xxx_cm_apll54_disable(void)
+{
+ _omap2xxx_apll_disable(OMAP24XX_EN_54M_PLL_SHIFT);
+}
+
+/* Stop APLL */
+void omap2xxx_cm_apll96_disable(void)
+{
+ _omap2xxx_apll_disable(OMAP24XX_EN_96M_PLL_SHIFT);
+}
+
+/**
+ * omap2xxx_cm_split_idlest_reg - split CM_IDLEST reg addr into its components
+ * @idlest_reg: CM_IDLEST* virtual address
+ * @prcm_inst: pointer to an s16 to return the PRCM instance offset
+ * @idlest_reg_id: pointer to a u8 to return the CM_IDLESTx register ID
+ *
+ * XXX This function is only needed until absolute register addresses are
+ * removed from the OMAP struct clk records.
+ */
+static int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg,
+ s16 *prcm_inst,
+ u8 *idlest_reg_id)
+{
+ unsigned long offs;
+ u8 idlest_offs;
+ int i;
+
+ if (idlest_reg < cm_base || idlest_reg > (cm_base + 0x0fff))
+ return -EINVAL;
+
+ idlest_offs = (unsigned long)idlest_reg & 0xff;
+ for (i = 0; i < ARRAY_SIZE(omap2xxx_cm_idlest_offs); i++) {
+ if (idlest_offs == omap2xxx_cm_idlest_offs[i]) {
+ *idlest_reg_id = i + 1;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(omap2xxx_cm_idlest_offs))
+ return -EINVAL;
+
+ offs = idlest_reg - cm_base;
+ offs &= 0xff00;
+ *prcm_inst = offs;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+/**
+ * omap2xxx_cm_wait_module_ready - wait for a module to leave idle or standby
+ * @part: PRCM partition, ignored for OMAP2
+ * @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
+ *
+ * Wait for the PRCM to indicate that the module identified by
+ * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon
+ * success or -EBUSY if the module doesn't enable in time.
+ */
+int omap2xxx_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_id,
+ u8 idlest_shift)
+{
+ int ena = 0, i = 0;
+ u8 cm_idlest_reg;
+ u32 mask;
+
+ if (!idlest_id || (idlest_id > ARRAY_SIZE(omap2xxx_cm_idlest_offs)))
+ return -EINVAL;
+
+ cm_idlest_reg = omap2xxx_cm_idlest_offs[idlest_id - 1];
+
+ mask = 1 << idlest_shift;
+ ena = mask;
+
+ 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;
+}
+
+/* Clockdomain low-level functions */
+
+static void omap2xxx_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+ omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+}
+
+static void omap2xxx_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+ omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+}
+
+static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ if (!clkdm->clktrctrl_mask)
+ return 0;
+
+ hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ if (!hwsup && clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+ omap2xxx_clkdm_wakeup(clkdm);
+
+ return 0;
+}
+
+static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ if (!clkdm->clktrctrl_mask)
+ return 0;
+
+ hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (!hwsup && clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
+ omap2xxx_clkdm_sleep(clkdm);
+
+ return 0;
+}
+
+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 = omap2xxx_clkdm_sleep,
+ .clkdm_wakeup = omap2xxx_clkdm_wakeup,
+ .clkdm_allow_idle = omap2xxx_clkdm_allow_idle,
+ .clkdm_deny_idle = omap2xxx_clkdm_deny_idle,
+ .clkdm_clk_enable = omap2xxx_clkdm_clk_enable,
+ .clkdm_clk_disable = omap2xxx_clkdm_clk_disable,
+};
+
+int omap2xxx_cm_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);
+
+ return (f1 | f2) ? 1 : 0;
+}
+
+int omap2xxx_cm_mpu_retention_allowed(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;
+
+ return 1;
+}
+
+u32 omap2xxx_cm_get_core_clk_src(void)
+{
+ u32 v;
+
+ v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ v &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+ return v;
+}
+
+u32 omap2xxx_cm_get_core_pll_config(void)
+{
+ return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+}
+
+void omap2xxx_cm_set_mod_dividers(u32 mpu, u32 dsp, u32 gfx, u32 core, u32 mdm)
+{
+ u32 tmp;
+
+ omap2_cm_write_mod_reg(mpu, MPU_MOD, CM_CLKSEL);
+ omap2_cm_write_mod_reg(dsp, OMAP24XX_DSP_MOD, CM_CLKSEL);
+ omap2_cm_write_mod_reg(gfx, GFX_MOD, CM_CLKSEL);
+ tmp = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) &
+ OMAP24XX_CLKSEL_DSS2_MASK;
+ omap2_cm_write_mod_reg(core | tmp, CORE_MOD, CM_CLKSEL1);
+ if (mdm)
+ omap2_cm_write_mod_reg(mdm, OMAP2430_MDM_MOD, CM_CLKSEL);
+}
+
+/*
+ *
+ */
+
+static struct cm_ll_data omap2xxx_cm_ll_data = {
+ .split_idlest_reg = &omap2xxx_cm_split_idlest_reg,
+ .wait_module_ready = &omap2xxx_cm_wait_module_ready,
+};
+
+int __init omap2xxx_cm_init(const struct omap_prcm_init_data *data)
+{
+ return cm_register(&omap2xxx_cm_ll_data);
+}
+
+static void __exit omap2xxx_cm_exit(void)
+{
+ cm_unregister(&omap2xxx_cm_ll_data);
+}
+__exitcall(omap2xxx_cm_exit);
diff --git a/arch/arm/mach-omap2/cm2xxx.h b/arch/arm/mach-omap2/cm2xxx.h
new file mode 100644
index 000000000..7b8c79c0c
--- /dev/null
+++ b/arch/arm/mach-omap2/cm2xxx.h
@@ -0,0 +1,70 @@
+/*
+ * OMAP2xxx Clock Management (CM) register definitions
+ *
+ * Copyright (C) 2007-2009, 2012 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_H
+#define __ARCH_ASM_MACH_OMAP2_CM2XXX_H
+
+#include "prcm-common.h"
+#include "cm2xxx_3xxx.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))
+
+/*
+ * 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.
+ */
+
+/* OMAP2-specific register offsets */
+
+#define OMAP24XX_CM_FCLKEN2 0x0004
+#define OMAP24XX_CM_ICLKEN4 0x001c
+#define OMAP24XX_CM_AUTOIDLE4 0x003c
+#define OMAP24XX_CM_IDLEST4 0x002c
+
+/* CM_IDLEST bit field values to indicate deasserted IdleReq */
+
+#define OMAP24XX_CM_IDLEST_VAL 0
+
+
+/* Clock management domain register get/set */
+
+#ifndef __ASSEMBLER__
+
+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);
+
+int omap2xxx_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_id,
+ u8 idlest_shift);
+extern int omap2xxx_cm_fclks_active(void);
+extern int omap2xxx_cm_mpu_retention_allowed(void);
+extern u32 omap2xxx_cm_get_core_clk_src(void);
+extern u32 omap2xxx_cm_get_core_pll_config(void);
+extern void omap2xxx_cm_set_mod_dividers(u32 mpu, u32 dsp, u32 gfx, u32 core,
+ u32 mdm);
+
+int __init omap2xxx_cm_init(const struct omap_prcm_init_data *data);
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h
new file mode 100644
index 000000000..72928a3ce
--- /dev/null
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h
@@ -0,0 +1,120 @@
+/*
+ * 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 "cm.h"
+
+/*
+ * 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 OMAP2430_CM_IDLEST3 0x0028
+#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
+
+#ifndef __ASSEMBLER__
+
+#include <linux/io.h>
+
+static inline u32 omap2_cm_read_mod_reg(s16 module, u16 idx)
+{
+ return readl_relaxed(cm_base + module + idx);
+}
+
+static inline void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx)
+{
+ writel_relaxed(val, cm_base + module + idx);
+}
+
+/* Read-modify-write a register in a CM module. Caller must lock */
+static inline 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;
+}
+
+/* Read a CM register, AND it, and shift the result down to bit 0 */
+static inline u32 omap2_cm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
+{
+ u32 v;
+
+ v = omap2_cm_read_mod_reg(domain, idx);
+ v &= mask;
+ v >>= __ffs(mask);
+
+ return v;
+}
+
+static inline u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx);
+}
+
+static inline u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ return omap2_cm_rmw_mod_reg_bits(bits, 0x0, module, idx);
+}
+
+extern int omap2xxx_cm_apll54_enable(void);
+extern void omap2xxx_cm_apll54_disable(void);
+extern int omap2xxx_cm_apll96_enable(void);
+extern void omap2xxx_cm_apll96_disable(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)
+#define OMAP_CLKSEL_GFX_WIDTH 3
+
+/* 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)
+
+#endif
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c
new file mode 100644
index 000000000..7b181f929
--- /dev/null
+++ b/arch/arm/mach-omap2/cm33xx.c
@@ -0,0 +1,364 @@
+/*
+ * AM33XX CM functions
+ *
+ * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Vaibhav Hiremath <hvaibhav@ti.com>
+ *
+ * Reference taken from from OMAP4 cminst44xx.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/types.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include "clockdomain.h"
+#include "cm.h"
+#include "cm33xx.h"
+#include "cm-regbits-34xx.h"
+#include "cm-regbits-33xx.h"
+#include "prm33xx.h"
+
+/*
+ * CLKCTRL_IDLEST_*: possible values for the CM_*_CLKCTRL.IDLEST bitfield:
+ *
+ * 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
+ *
+ */
+#define CLKCTRL_IDLEST_FUNCTIONAL 0x0
+#define CLKCTRL_IDLEST_INTRANSITION 0x1
+#define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2
+#define CLKCTRL_IDLEST_DISABLED 0x3
+
+/* Private functions */
+
+/* Read a register in a CM instance */
+static inline u32 am33xx_cm_read_reg(u16 inst, u16 idx)
+{
+ return readl_relaxed(cm_base + inst + idx);
+}
+
+/* Write into a register in a CM */
+static inline void am33xx_cm_write_reg(u32 val, u16 inst, u16 idx)
+{
+ writel_relaxed(val, cm_base + inst + idx);
+}
+
+/* Read-modify-write a register in CM */
+static inline u32 am33xx_cm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx)
+{
+ u32 v;
+
+ v = am33xx_cm_read_reg(inst, idx);
+ v &= ~mask;
+ v |= bits;
+ am33xx_cm_write_reg(v, inst, idx);
+
+ return v;
+}
+
+/**
+ * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield
+ * @inst: CM instance register offset (*_INST macro)
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
+ *
+ * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to
+ * bit 0.
+ */
+static u32 _clkctrl_idlest(u16 inst, u16 clkctrl_offs)
+{
+ u32 v = am33xx_cm_read_reg(inst, clkctrl_offs);
+ v &= AM33XX_IDLEST_MASK;
+ v >>= AM33XX_IDLEST_SHIFT;
+ return v;
+}
+
+/**
+ * _is_module_ready - can module registers be accessed without causing an abort?
+ * @inst: CM instance register offset (*_INST macro)
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
+ *
+ * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either
+ * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise.
+ */
+static bool _is_module_ready(u16 inst, u16 clkctrl_offs)
+{
+ u32 v;
+
+ v = _clkctrl_idlest(inst, clkctrl_offs);
+
+ return (v == CLKCTRL_IDLEST_FUNCTIONAL ||
+ v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false;
+}
+
+/**
+ * _clktrctrl_write - write @c to a CM_CLKSTCTRL.CLKTRCTRL register bitfield
+ * @c: CLKTRCTRL register bitfield (LSB = bit 0, i.e., unshifted)
+ * @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, u16 inst, u16 cdoffs)
+{
+ u32 v;
+
+ v = am33xx_cm_read_reg(inst, cdoffs);
+ v &= ~AM33XX_CLKTRCTRL_MASK;
+ v |= c << AM33XX_CLKTRCTRL_SHIFT;
+ am33xx_cm_write_reg(v, inst, cdoffs);
+}
+
+/* Public functions */
+
+/**
+ * am33xx_cm_is_clkdm_in_hwsup - is a clockdomain in hwsup idle mode?
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * Returns true if the clockdomain referred to by (@inst, @cdoffs)
+ * is in hardware-supervised idle mode, or 0 otherwise.
+ */
+static bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs)
+{
+ u32 v;
+
+ v = am33xx_cm_read_reg(inst, cdoffs);
+ v &= AM33XX_CLKTRCTRL_MASK;
+ v >>= AM33XX_CLKTRCTRL_SHIFT;
+
+ return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? true : false;
+}
+
+/**
+ * am33xx_cm_clkdm_enable_hwsup - put a clockdomain in hwsup-idle mode
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * Put a clockdomain referred to by (@inst, @cdoffs) into
+ * hardware-supervised idle mode. No return value.
+ */
+static void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs)
+{
+ _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, inst, cdoffs);
+}
+
+/**
+ * am33xx_cm_clkdm_disable_hwsup - put a clockdomain in swsup-idle mode
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * Put a clockdomain referred to by (@inst, @cdoffs) into
+ * software-supervised idle mode, i.e., controlled manually by the
+ * Linux OMAP clockdomain code. No return value.
+ */
+static void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs)
+{
+ _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, inst, cdoffs);
+}
+
+/**
+ * am33xx_cm_clkdm_force_sleep - try to put a clockdomain into idle
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * Put a clockdomain referred to by (@inst, @cdoffs) into idle
+ * No return value.
+ */
+static void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs)
+{
+ _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, inst, cdoffs);
+}
+
+/**
+ * am33xx_cm_clkdm_force_wakeup - try to take a clockdomain out of idle
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * Take a clockdomain referred to by (@inst, @cdoffs) out of idle,
+ * waking it up. No return value.
+ */
+static void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs)
+{
+ _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, inst, cdoffs);
+}
+
+/*
+ *
+ */
+
+/**
+ * am33xx_cm_wait_module_ready - wait for a module to be in 'func' state
+ * @part: PRCM partition, ignored for AM33xx
+ * @inst: CM instance register offset (*_INST macro)
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
+ * @bit_shift: bit shift for the register, ignored for AM33xx
+ *
+ * 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"
+ */
+static int am33xx_cm_wait_module_ready(u8 part, s16 inst, u16 clkctrl_offs,
+ u8 bit_shift)
+{
+ int i = 0;
+
+ omap_test_timeout(_is_module_ready(inst, clkctrl_offs),
+ MAX_MODULE_READY_TIME, i);
+
+ return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
+}
+
+/**
+ * am33xx_cm_wait_module_idle - wait for a module to be in 'disabled'
+ * state
+ * @part: CM partition, ignored for AM33xx
+ * @inst: CM instance register offset (*_INST macro)
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
+ * @bit_shift: bit shift for the register, ignored for AM33xx
+ *
+ * Wait for the module IDLEST to be disabled. Some PRCM transition,
+ * like reset assertion or parent clock de-activation must wait the
+ * module to be fully disabled.
+ */
+static int am33xx_cm_wait_module_idle(u8 part, s16 inst, u16 clkctrl_offs,
+ u8 bit_shift)
+{
+ int i = 0;
+
+ if (!clkctrl_offs)
+ return 0;
+
+ omap_test_timeout((_clkctrl_idlest(inst, clkctrl_offs) ==
+ CLKCTRL_IDLEST_DISABLED),
+ MAX_MODULE_READY_TIME, i);
+
+ return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
+}
+
+/**
+ * am33xx_cm_module_enable - Enable the modulemode inside CLKCTRL
+ * @mode: Module mode (SW or HW)
+ * @part: CM partition, ignored for AM33xx
+ * @inst: CM instance register offset (*_INST macro)
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
+ *
+ * No return value.
+ */
+static void am33xx_cm_module_enable(u8 mode, u8 part, u16 inst,
+ u16 clkctrl_offs)
+{
+ u32 v;
+
+ v = am33xx_cm_read_reg(inst, clkctrl_offs);
+ v &= ~AM33XX_MODULEMODE_MASK;
+ v |= mode << AM33XX_MODULEMODE_SHIFT;
+ am33xx_cm_write_reg(v, inst, clkctrl_offs);
+}
+
+/**
+ * am33xx_cm_module_disable - Disable the module inside CLKCTRL
+ * @part: CM partition, ignored for AM33xx
+ * @inst: CM instance register offset (*_INST macro)
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
+ *
+ * No return value.
+ */
+static void am33xx_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs)
+{
+ u32 v;
+
+ v = am33xx_cm_read_reg(inst, clkctrl_offs);
+ v &= ~AM33XX_MODULEMODE_MASK;
+ am33xx_cm_write_reg(v, inst, clkctrl_offs);
+}
+
+/*
+ * Clockdomain low-level functions
+ */
+
+static int am33xx_clkdm_sleep(struct clockdomain *clkdm)
+{
+ am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs);
+ return 0;
+}
+
+static int am33xx_clkdm_wakeup(struct clockdomain *clkdm)
+{
+ am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs);
+ return 0;
+}
+
+static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+ am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
+}
+
+static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+ am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
+}
+
+static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+ if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+ return am33xx_clkdm_wakeup(clkdm);
+
+ return 0;
+}
+
+static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
+
+ if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
+ am33xx_clkdm_sleep(clkdm);
+
+ return 0;
+}
+
+struct clkdm_ops am33xx_clkdm_operations = {
+ .clkdm_sleep = am33xx_clkdm_sleep,
+ .clkdm_wakeup = am33xx_clkdm_wakeup,
+ .clkdm_allow_idle = am33xx_clkdm_allow_idle,
+ .clkdm_deny_idle = am33xx_clkdm_deny_idle,
+ .clkdm_clk_enable = am33xx_clkdm_clk_enable,
+ .clkdm_clk_disable = am33xx_clkdm_clk_disable,
+};
+
+static struct cm_ll_data am33xx_cm_ll_data = {
+ .wait_module_ready = &am33xx_cm_wait_module_ready,
+ .wait_module_idle = &am33xx_cm_wait_module_idle,
+ .module_enable = &am33xx_cm_module_enable,
+ .module_disable = &am33xx_cm_module_disable,
+};
+
+int __init am33xx_cm_init(const struct omap_prcm_init_data *data)
+{
+ return cm_register(&am33xx_cm_ll_data);
+}
+
+static void __exit am33xx_cm_exit(void)
+{
+ cm_unregister(&am33xx_cm_ll_data);
+}
+__exitcall(am33xx_cm_exit);
diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h
new file mode 100644
index 000000000..a91f7d282
--- /dev/null
+++ b/arch/arm/mach-omap2/cm33xx.h
@@ -0,0 +1,380 @@
+/*
+ * AM33XX CM offset macros
+ *
+ * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.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 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 __ARCH_ARM_MACH_OMAP2_CM_33XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM_33XX_H
+
+#include "cm.h"
+#include "cm-regbits-33xx.h"
+#include "prcm-common.h"
+
+/* CM base address */
+#define AM33XX_CM_BASE 0x44e00000
+
+#define AM33XX_CM_REGADDR(inst, reg) \
+ AM33XX_L4_WK_IO_ADDRESS(AM33XX_CM_BASE + (inst) + (reg))
+
+/* CM instances */
+#define AM33XX_CM_PER_MOD 0x0000
+#define AM33XX_CM_WKUP_MOD 0x0400
+#define AM33XX_CM_DPLL_MOD 0x0500
+#define AM33XX_CM_MPU_MOD 0x0600
+#define AM33XX_CM_DEVICE_MOD 0x0700
+#define AM33XX_CM_RTC_MOD 0x0800
+#define AM33XX_CM_GFX_MOD 0x0900
+#define AM33XX_CM_CEFUSE_MOD 0x0A00
+
+/* CM */
+
+/* CM.PER_CM register offsets */
+#define AM33XX_CM_PER_L4LS_CLKSTCTRL_OFFSET 0x0000
+#define AM33XX_CM_PER_L4LS_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0000)
+#define AM33XX_CM_PER_L3S_CLKSTCTRL_OFFSET 0x0004
+#define AM33XX_CM_PER_L3S_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0004)
+#define AM33XX_CM_PER_L4FW_CLKSTCTRL_OFFSET 0x0008
+#define AM33XX_CM_PER_L4FW_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0008)
+#define AM33XX_CM_PER_L3_CLKSTCTRL_OFFSET 0x000c
+#define AM33XX_CM_PER_L3_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x000c)
+#define AM33XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET 0x0014
+#define AM33XX_CM_PER_CPGMAC0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0014)
+#define AM33XX_CM_PER_LCDC_CLKCTRL_OFFSET 0x0018
+#define AM33XX_CM_PER_LCDC_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0018)
+#define AM33XX_CM_PER_USB0_CLKCTRL_OFFSET 0x001c
+#define AM33XX_CM_PER_USB0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x001c)
+#define AM33XX_CM_PER_MLB_CLKCTRL_OFFSET 0x0020
+#define AM33XX_CM_PER_MLB_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0020)
+#define AM33XX_CM_PER_TPTC0_CLKCTRL_OFFSET 0x0024
+#define AM33XX_CM_PER_TPTC0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0024)
+#define AM33XX_CM_PER_EMIF_CLKCTRL_OFFSET 0x0028
+#define AM33XX_CM_PER_EMIF_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0028)
+#define AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET 0x002c
+#define AM33XX_CM_PER_OCMCRAM_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x002c)
+#define AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET 0x0030
+#define AM33XX_CM_PER_GPMC_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0030)
+#define AM33XX_CM_PER_MCASP0_CLKCTRL_OFFSET 0x0034
+#define AM33XX_CM_PER_MCASP0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0034)
+#define AM33XX_CM_PER_UART5_CLKCTRL_OFFSET 0x0038
+#define AM33XX_CM_PER_UART5_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0038)
+#define AM33XX_CM_PER_MMC0_CLKCTRL_OFFSET 0x003c
+#define AM33XX_CM_PER_MMC0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x003c)
+#define AM33XX_CM_PER_ELM_CLKCTRL_OFFSET 0x0040
+#define AM33XX_CM_PER_ELM_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0040)
+#define AM33XX_CM_PER_I2C2_CLKCTRL_OFFSET 0x0044
+#define AM33XX_CM_PER_I2C2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0044)
+#define AM33XX_CM_PER_I2C1_CLKCTRL_OFFSET 0x0048
+#define AM33XX_CM_PER_I2C1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0048)
+#define AM33XX_CM_PER_SPI0_CLKCTRL_OFFSET 0x004c
+#define AM33XX_CM_PER_SPI0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x004c)
+#define AM33XX_CM_PER_SPI1_CLKCTRL_OFFSET 0x0050
+#define AM33XX_CM_PER_SPI1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0050)
+#define AM33XX_CM_PER_SPI2_CLKCTRL_OFFSET 0x0054
+#define AM33XX_CM_PER_SPI2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0054)
+#define AM33XX_CM_PER_SPI3_CLKCTRL_OFFSET 0x0058
+#define AM33XX_CM_PER_SPI3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0058)
+#define AM33XX_CM_PER_L4LS_CLKCTRL_OFFSET 0x0060
+#define AM33XX_CM_PER_L4LS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0060)
+#define AM33XX_CM_PER_L4FW_CLKCTRL_OFFSET 0x0064
+#define AM33XX_CM_PER_L4FW_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0064)
+#define AM33XX_CM_PER_MCASP1_CLKCTRL_OFFSET 0x0068
+#define AM33XX_CM_PER_MCASP1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0068)
+#define AM33XX_CM_PER_UART1_CLKCTRL_OFFSET 0x006c
+#define AM33XX_CM_PER_UART1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x006c)
+#define AM33XX_CM_PER_UART2_CLKCTRL_OFFSET 0x0070
+#define AM33XX_CM_PER_UART2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0070)
+#define AM33XX_CM_PER_UART3_CLKCTRL_OFFSET 0x0074
+#define AM33XX_CM_PER_UART3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0074)
+#define AM33XX_CM_PER_UART4_CLKCTRL_OFFSET 0x0078
+#define AM33XX_CM_PER_UART4_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0078)
+#define AM33XX_CM_PER_TIMER7_CLKCTRL_OFFSET 0x007c
+#define AM33XX_CM_PER_TIMER7_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x007c)
+#define AM33XX_CM_PER_TIMER2_CLKCTRL_OFFSET 0x0080
+#define AM33XX_CM_PER_TIMER2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0080)
+#define AM33XX_CM_PER_TIMER3_CLKCTRL_OFFSET 0x0084
+#define AM33XX_CM_PER_TIMER3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0084)
+#define AM33XX_CM_PER_TIMER4_CLKCTRL_OFFSET 0x0088
+#define AM33XX_CM_PER_TIMER4_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0088)
+#define AM33XX_CM_PER_MCASP2_CLKCTRL_OFFSET 0x008c
+#define AM33XX_CM_PER_MCASP2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x008c)
+#define AM33XX_CM_PER_RNG_CLKCTRL_OFFSET 0x0090
+#define AM33XX_CM_PER_RNG_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0090)
+#define AM33XX_CM_PER_AES0_CLKCTRL_OFFSET 0x0094
+#define AM33XX_CM_PER_AES0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0094)
+#define AM33XX_CM_PER_AES1_CLKCTRL_OFFSET 0x0098
+#define AM33XX_CM_PER_AES1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0098)
+#define AM33XX_CM_PER_DES_CLKCTRL_OFFSET 0x009c
+#define AM33XX_CM_PER_DES_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x009c)
+#define AM33XX_CM_PER_SHA0_CLKCTRL_OFFSET 0x00a0
+#define AM33XX_CM_PER_SHA0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00a0)
+#define AM33XX_CM_PER_PKA_CLKCTRL_OFFSET 0x00a4
+#define AM33XX_CM_PER_PKA_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00a4)
+#define AM33XX_CM_PER_GPIO6_CLKCTRL_OFFSET 0x00a8
+#define AM33XX_CM_PER_GPIO6_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00a8)
+#define AM33XX_CM_PER_GPIO1_CLKCTRL_OFFSET 0x00ac
+#define AM33XX_CM_PER_GPIO1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00ac)
+#define AM33XX_CM_PER_GPIO2_CLKCTRL_OFFSET 0x00b0
+#define AM33XX_CM_PER_GPIO2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00b0)
+#define AM33XX_CM_PER_GPIO3_CLKCTRL_OFFSET 0x00b4
+#define AM33XX_CM_PER_GPIO3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00b4)
+#define AM33XX_CM_PER_GPIO4_CLKCTRL_OFFSET 0x00b8
+#define AM33XX_CM_PER_GPIO4_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00b8)
+#define AM33XX_CM_PER_TPCC_CLKCTRL_OFFSET 0x00bc
+#define AM33XX_CM_PER_TPCC_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00bc)
+#define AM33XX_CM_PER_DCAN0_CLKCTRL_OFFSET 0x00c0
+#define AM33XX_CM_PER_DCAN0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00c0)
+#define AM33XX_CM_PER_DCAN1_CLKCTRL_OFFSET 0x00c4
+#define AM33XX_CM_PER_DCAN1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00c4)
+#define AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET 0x00cc
+#define AM33XX_CM_PER_EPWMSS1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00cc)
+#define AM33XX_CM_PER_EMIF_FW_CLKCTRL_OFFSET 0x00d0
+#define AM33XX_CM_PER_EMIF_FW_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00d0)
+#define AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET 0x00d4
+#define AM33XX_CM_PER_EPWMSS0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00d4)
+#define AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET 0x00d8
+#define AM33XX_CM_PER_EPWMSS2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00d8)
+#define AM33XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET 0x00dc
+#define AM33XX_CM_PER_L3_INSTR_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00dc)
+#define AM33XX_CM_PER_L3_CLKCTRL_OFFSET 0x00e0
+#define AM33XX_CM_PER_L3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00e0)
+#define AM33XX_CM_PER_IEEE5000_CLKCTRL_OFFSET 0x00e4
+#define AM33XX_CM_PER_IEEE5000_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00e4)
+#define AM33XX_CM_PER_PRUSS_CLKCTRL_OFFSET 0x00e8
+#define AM33XX_CM_PER_PRUSS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00e8)
+#define AM33XX_CM_PER_TIMER5_CLKCTRL_OFFSET 0x00ec
+#define AM33XX_CM_PER_TIMER5_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00ec)
+#define AM33XX_CM_PER_TIMER6_CLKCTRL_OFFSET 0x00f0
+#define AM33XX_CM_PER_TIMER6_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00f0)
+#define AM33XX_CM_PER_MMC1_CLKCTRL_OFFSET 0x00f4
+#define AM33XX_CM_PER_MMC1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00f4)
+#define AM33XX_CM_PER_MMC2_CLKCTRL_OFFSET 0x00f8
+#define AM33XX_CM_PER_MMC2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00f8)
+#define AM33XX_CM_PER_TPTC1_CLKCTRL_OFFSET 0x00fc
+#define AM33XX_CM_PER_TPTC1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00fc)
+#define AM33XX_CM_PER_TPTC2_CLKCTRL_OFFSET 0x0100
+#define AM33XX_CM_PER_TPTC2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0100)
+#define AM33XX_CM_PER_GPIO5_CLKCTRL_OFFSET 0x0104
+#define AM33XX_CM_PER_GPIO5_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0104)
+#define AM33XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET 0x010c
+#define AM33XX_CM_PER_SPINLOCK_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x010c)
+#define AM33XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET 0x0110
+#define AM33XX_CM_PER_MAILBOX0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0110)
+#define AM33XX_CM_PER_L4HS_CLKSTCTRL_OFFSET 0x011c
+#define AM33XX_CM_PER_L4HS_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x011c)
+#define AM33XX_CM_PER_L4HS_CLKCTRL_OFFSET 0x0120
+#define AM33XX_CM_PER_L4HS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0120)
+#define AM33XX_CM_PER_MSTR_EXPS_CLKCTRL_OFFSET 0x0124
+#define AM33XX_CM_PER_MSTR_EXPS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0124)
+#define AM33XX_CM_PER_SLV_EXPS_CLKCTRL_OFFSET 0x0128
+#define AM33XX_CM_PER_SLV_EXPS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0128)
+#define AM33XX_CM_PER_OCPWP_L3_CLKSTCTRL_OFFSET 0x012c
+#define AM33XX_CM_PER_OCPWP_L3_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x012c)
+#define AM33XX_CM_PER_OCPWP_CLKCTRL_OFFSET 0x0130
+#define AM33XX_CM_PER_OCPWP_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0130)
+#define AM33XX_CM_PER_MAILBOX1_CLKCTRL_OFFSET 0x0134
+#define AM33XX_CM_PER_MAILBOX1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0134)
+#define AM33XX_CM_PER_PRUSS_CLKSTCTRL_OFFSET 0x0140
+#define AM33XX_CM_PER_PRUSS_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0140)
+#define AM33XX_CM_PER_CPSW_CLKSTCTRL_OFFSET 0x0144
+#define AM33XX_CM_PER_CPSW_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0144)
+#define AM33XX_CM_PER_LCDC_CLKSTCTRL_OFFSET 0x0148
+#define AM33XX_CM_PER_LCDC_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0148)
+#define AM33XX_CM_PER_CLKDIV32K_CLKCTRL_OFFSET 0x014c
+#define AM33XX_CM_PER_CLKDIV32K_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x014c)
+#define AM33XX_CM_PER_CLK_24MHZ_CLKSTCTRL_OFFSET 0x0150
+#define AM33XX_CM_PER_CLK_24MHZ_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0150)
+
+/* CM.WKUP_CM register offsets */
+#define AM33XX_CM_WKUP_CLKSTCTRL_OFFSET 0x0000
+#define AM33XX_CM_WKUP_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0000)
+#define AM33XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET 0x0004
+#define AM33XX_CM_WKUP_CONTROL_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0004)
+#define AM33XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET 0x0008
+#define AM33XX_CM_WKUP_GPIO0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0008)
+#define AM33XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET 0x000c
+#define AM33XX_CM_WKUP_L4WKUP_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x000c)
+#define AM33XX_CM_WKUP_TIMER0_CLKCTRL_OFFSET 0x0010
+#define AM33XX_CM_WKUP_TIMER0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0010)
+#define AM33XX_CM_WKUP_DEBUGSS_CLKCTRL_OFFSET 0x0014
+#define AM33XX_CM_WKUP_DEBUGSS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0014)
+#define AM33XX_CM_L3_AON_CLKSTCTRL_OFFSET 0x0018
+#define AM33XX_CM_L3_AON_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0018)
+#define AM33XX_CM_AUTOIDLE_DPLL_MPU_OFFSET 0x001c
+#define AM33XX_CM_AUTOIDLE_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x001c)
+#define AM33XX_CM_IDLEST_DPLL_MPU_OFFSET 0x0020
+#define AM33XX_CM_IDLEST_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0020)
+#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_MPU_OFFSET 0x0024
+#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0024)
+#define AM33XX_CM_SSC_MODFREQDIV_DPLL_MPU_OFFSET 0x0028
+#define AM33XX_CM_SSC_MODFREQDIV_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0028)
+#define AM33XX_CM_CLKSEL_DPLL_MPU_OFFSET 0x002c
+#define AM33XX_CM_CLKSEL_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x002c)
+#define AM33XX_CM_AUTOIDLE_DPLL_DDR_OFFSET 0x0030
+#define AM33XX_CM_AUTOIDLE_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0030)
+#define AM33XX_CM_IDLEST_DPLL_DDR_OFFSET 0x0034
+#define AM33XX_CM_IDLEST_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0034)
+#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_DDR_OFFSET 0x0038
+#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0038)
+#define AM33XX_CM_SSC_MODFREQDIV_DPLL_DDR_OFFSET 0x003c
+#define AM33XX_CM_SSC_MODFREQDIV_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x003c)
+#define AM33XX_CM_CLKSEL_DPLL_DDR_OFFSET 0x0040
+#define AM33XX_CM_CLKSEL_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0040)
+#define AM33XX_CM_AUTOIDLE_DPLL_DISP_OFFSET 0x0044
+#define AM33XX_CM_AUTOIDLE_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0044)
+#define AM33XX_CM_IDLEST_DPLL_DISP_OFFSET 0x0048
+#define AM33XX_CM_IDLEST_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0048)
+#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_DISP_OFFSET 0x004c
+#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x004c)
+#define AM33XX_CM_SSC_MODFREQDIV_DPLL_DISP_OFFSET 0x0050
+#define AM33XX_CM_SSC_MODFREQDIV_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0050)
+#define AM33XX_CM_CLKSEL_DPLL_DISP_OFFSET 0x0054
+#define AM33XX_CM_CLKSEL_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0054)
+#define AM33XX_CM_AUTOIDLE_DPLL_CORE_OFFSET 0x0058
+#define AM33XX_CM_AUTOIDLE_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0058)
+#define AM33XX_CM_IDLEST_DPLL_CORE_OFFSET 0x005c
+#define AM33XX_CM_IDLEST_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x005c)
+#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_CORE_OFFSET 0x0060
+#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0060)
+#define AM33XX_CM_SSC_MODFREQDIV_DPLL_CORE_OFFSET 0x0064
+#define AM33XX_CM_SSC_MODFREQDIV_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0064)
+#define AM33XX_CM_CLKSEL_DPLL_CORE_OFFSET 0x0068
+#define AM33XX_CM_CLKSEL_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0068)
+#define AM33XX_CM_AUTOIDLE_DPLL_PER_OFFSET 0x006c
+#define AM33XX_CM_AUTOIDLE_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x006c)
+#define AM33XX_CM_IDLEST_DPLL_PER_OFFSET 0x0070
+#define AM33XX_CM_IDLEST_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0070)
+#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_PER_OFFSET 0x0074
+#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0074)
+#define AM33XX_CM_SSC_MODFREQDIV_DPLL_PER_OFFSET 0x0078
+#define AM33XX_CM_SSC_MODFREQDIV_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0078)
+#define AM33XX_CM_CLKDCOLDO_DPLL_PER_OFFSET 0x007c
+#define AM33XX_CM_CLKDCOLDO_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x007c)
+#define AM33XX_CM_DIV_M4_DPLL_CORE_OFFSET 0x0080
+#define AM33XX_CM_DIV_M4_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0080)
+#define AM33XX_CM_DIV_M5_DPLL_CORE_OFFSET 0x0084
+#define AM33XX_CM_DIV_M5_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0084)
+#define AM33XX_CM_CLKMODE_DPLL_MPU_OFFSET 0x0088
+#define AM33XX_CM_CLKMODE_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0088)
+#define AM33XX_CM_CLKMODE_DPLL_PER_OFFSET 0x008c
+#define AM33XX_CM_CLKMODE_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x008c)
+#define AM33XX_CM_CLKMODE_DPLL_CORE_OFFSET 0x0090
+#define AM33XX_CM_CLKMODE_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0090)
+#define AM33XX_CM_CLKMODE_DPLL_DDR_OFFSET 0x0094
+#define AM33XX_CM_CLKMODE_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0094)
+#define AM33XX_CM_CLKMODE_DPLL_DISP_OFFSET 0x0098
+#define AM33XX_CM_CLKMODE_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0098)
+#define AM33XX_CM_CLKSEL_DPLL_PERIPH_OFFSET 0x009c
+#define AM33XX_CM_CLKSEL_DPLL_PERIPH AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x009c)
+#define AM33XX_CM_DIV_M2_DPLL_DDR_OFFSET 0x00a0
+#define AM33XX_CM_DIV_M2_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00a0)
+#define AM33XX_CM_DIV_M2_DPLL_DISP_OFFSET 0x00a4
+#define AM33XX_CM_DIV_M2_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00a4)
+#define AM33XX_CM_DIV_M2_DPLL_MPU_OFFSET 0x00a8
+#define AM33XX_CM_DIV_M2_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00a8)
+#define AM33XX_CM_DIV_M2_DPLL_PER_OFFSET 0x00ac
+#define AM33XX_CM_DIV_M2_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00ac)
+#define AM33XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET 0x00b0
+#define AM33XX_CM_WKUP_WKUP_M3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00b0)
+#define AM33XX_CM_WKUP_UART0_CLKCTRL_OFFSET 0x00b4
+#define AM33XX_CM_WKUP_UART0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00b4)
+#define AM33XX_CM_WKUP_I2C0_CLKCTRL_OFFSET 0x00b8
+#define AM33XX_CM_WKUP_I2C0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00b8)
+#define AM33XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET 0x00bc
+#define AM33XX_CM_WKUP_ADC_TSC_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00bc)
+#define AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET 0x00c0
+#define AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00c0)
+#define AM33XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET 0x00c4
+#define AM33XX_CM_WKUP_TIMER1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00c4)
+#define AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET 0x00c8
+#define AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00c8)
+#define AM33XX_CM_L4_WKUP_AON_CLKSTCTRL_OFFSET 0x00cc
+#define AM33XX_CM_L4_WKUP_AON_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00cc)
+#define AM33XX_CM_WKUP_WDT0_CLKCTRL_OFFSET 0x00d0
+#define AM33XX_CM_WKUP_WDT0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00d0)
+#define AM33XX_CM_WKUP_WDT1_CLKCTRL_OFFSET 0x00d4
+#define AM33XX_CM_WKUP_WDT1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00d4)
+#define AM33XX_CM_DIV_M6_DPLL_CORE_OFFSET 0x00d8
+#define AM33XX_CM_DIV_M6_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00d8)
+
+/* CM.DPLL_CM register offsets */
+#define AM33XX_CLKSEL_TIMER7_CLK_OFFSET 0x0004
+#define AM33XX_CLKSEL_TIMER7_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0004)
+#define AM33XX_CLKSEL_TIMER2_CLK_OFFSET 0x0008
+#define AM33XX_CLKSEL_TIMER2_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0008)
+#define AM33XX_CLKSEL_TIMER3_CLK_OFFSET 0x000c
+#define AM33XX_CLKSEL_TIMER3_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x000c)
+#define AM33XX_CLKSEL_TIMER4_CLK_OFFSET 0x0010
+#define AM33XX_CLKSEL_TIMER4_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0010)
+#define AM33XX_CM_MAC_CLKSEL_OFFSET 0x0014
+#define AM33XX_CM_MAC_CLKSEL AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0014)
+#define AM33XX_CLKSEL_TIMER5_CLK_OFFSET 0x0018
+#define AM33XX_CLKSEL_TIMER5_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0018)
+#define AM33XX_CLKSEL_TIMER6_CLK_OFFSET 0x001c
+#define AM33XX_CLKSEL_TIMER6_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x001c)
+#define AM33XX_CM_CPTS_RFT_CLKSEL_OFFSET 0x0020
+#define AM33XX_CM_CPTS_RFT_CLKSEL AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0020)
+#define AM33XX_CLKSEL_TIMER1MS_CLK_OFFSET 0x0028
+#define AM33XX_CLKSEL_TIMER1MS_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0028)
+#define AM33XX_CLKSEL_GFX_FCLK_OFFSET 0x002c
+#define AM33XX_CLKSEL_GFX_FCLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x002c)
+#define AM33XX_CLKSEL_PRUSS_OCP_CLK_OFFSET 0x0030
+#define AM33XX_CLKSEL_PRUSS_OCP_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0030)
+#define AM33XX_CLKSEL_LCDC_PIXEL_CLK_OFFSET 0x0034
+#define AM33XX_CLKSEL_LCDC_PIXEL_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0034)
+#define AM33XX_CLKSEL_WDT1_CLK_OFFSET 0x0038
+#define AM33XX_CLKSEL_WDT1_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0038)
+#define AM33XX_CLKSEL_GPIO0_DBCLK_OFFSET 0x003c
+#define AM33XX_CLKSEL_GPIO0_DBCLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x003c)
+
+/* CM.MPU_CM register offsets */
+#define AM33XX_CM_MPU_CLKSTCTRL_OFFSET 0x0000
+#define AM33XX_CM_MPU_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_MPU_MOD, 0x0000)
+#define AM33XX_CM_MPU_MPU_CLKCTRL_OFFSET 0x0004
+#define AM33XX_CM_MPU_MPU_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_MPU_MOD, 0x0004)
+
+/* CM.DEVICE_CM register offsets */
+#define AM33XX_CM_CLKOUT_CTRL_OFFSET 0x0000
+#define AM33XX_CM_CLKOUT_CTRL AM33XX_CM_REGADDR(AM33XX_CM_DEVICE_MOD, 0x0000)
+
+/* CM.RTC_CM register offsets */
+#define AM33XX_CM_RTC_RTC_CLKCTRL_OFFSET 0x0000
+#define AM33XX_CM_RTC_RTC_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_RTC_MOD, 0x0000)
+#define AM33XX_CM_RTC_CLKSTCTRL_OFFSET 0x0004
+#define AM33XX_CM_RTC_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_RTC_MOD, 0x0004)
+
+/* CM.GFX_CM register offsets */
+#define AM33XX_CM_GFX_L3_CLKSTCTRL_OFFSET 0x0000
+#define AM33XX_CM_GFX_L3_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x0000)
+#define AM33XX_CM_GFX_GFX_CLKCTRL_OFFSET 0x0004
+#define AM33XX_CM_GFX_GFX_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x0004)
+#define AM33XX_CM_GFX_BITBLT_CLKCTRL_OFFSET 0x0008
+#define AM33XX_CM_GFX_BITBLT_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x0008)
+#define AM33XX_CM_GFX_L4LS_GFX_CLKSTCTRL__1_OFFSET 0x000c
+#define AM33XX_CM_GFX_L4LS_GFX_CLKSTCTRL__1 AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x000c)
+#define AM33XX_CM_GFX_MMUCFG_CLKCTRL_OFFSET 0x0010
+#define AM33XX_CM_GFX_MMUCFG_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x0010)
+#define AM33XX_CM_GFX_MMUDATA_CLKCTRL_OFFSET 0x0014
+#define AM33XX_CM_GFX_MMUDATA_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x0014)
+
+/* CM.CEFUSE_CM register offsets */
+#define AM33XX_CM_CEFUSE_CLKSTCTRL_OFFSET 0x0000
+#define AM33XX_CM_CEFUSE_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_CEFUSE_MOD, 0x0000)
+#define AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET 0x0020
+#define AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_CEFUSE_MOD, 0x0020)
+
+
+#ifndef __ASSEMBLER__
+int am33xx_cm_init(const struct omap_prcm_init_data *data);
+#endif /* ASSEMBLER */
+#endif
diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c
new file mode 100644
index 000000000..187fa4386
--- /dev/null
+++ b/arch/arm/mach-omap2/cm3xxx.c
@@ -0,0 +1,684 @@
+/*
+ * OMAP3xxx CM module functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2008-2010, 2012 Texas Instruments, Inc.
+ * 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 <linux/types.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include "prm2xxx_3xxx.h"
+#include "cm.h"
+#include "cm3xxx.h"
+#include "cm-regbits-34xx.h"
+#include "clockdomain.h"
+
+static const u8 omap3xxx_cm_idlest_offs[] = {
+ CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
+};
+
+/*
+ *
+ */
+
+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);
+}
+
+static bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
+{
+ u32 v;
+
+ v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
+ v &= mask;
+ v >>= __ffs(mask);
+
+ return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
+}
+
+static void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
+}
+
+static void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
+}
+
+static void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, module, mask);
+}
+
+static void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask);
+}
+
+/*
+ *
+ */
+
+/**
+ * omap3xxx_cm_wait_module_ready - wait for a module to leave idle or standby
+ * @part: PRCM partition, ignored for OMAP3
+ * @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
+ *
+ * Wait for the PRCM to indicate that the module identified by
+ * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon
+ * success or -EBUSY if the module doesn't enable in time.
+ */
+static int omap3xxx_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_id,
+ u8 idlest_shift)
+{
+ int ena = 0, i = 0;
+ u8 cm_idlest_reg;
+ u32 mask;
+
+ if (!idlest_id || (idlest_id > ARRAY_SIZE(omap3xxx_cm_idlest_offs)))
+ return -EINVAL;
+
+ cm_idlest_reg = omap3xxx_cm_idlest_offs[idlest_id - 1];
+
+ mask = 1 << idlest_shift;
+ ena = 0;
+
+ 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;
+}
+
+/**
+ * omap3xxx_cm_split_idlest_reg - split CM_IDLEST reg addr into its components
+ * @idlest_reg: CM_IDLEST* virtual address
+ * @prcm_inst: pointer to an s16 to return the PRCM instance offset
+ * @idlest_reg_id: pointer to a u8 to return the CM_IDLESTx register ID
+ *
+ * XXX This function is only needed until absolute register addresses are
+ * removed from the OMAP struct clk records.
+ */
+static int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg,
+ s16 *prcm_inst,
+ u8 *idlest_reg_id)
+{
+ unsigned long offs;
+ u8 idlest_offs;
+ int i;
+
+ if (idlest_reg < (cm_base + OMAP3430_IVA2_MOD) ||
+ idlest_reg > (cm_base + 0x1ffff))
+ return -EINVAL;
+
+ idlest_offs = (unsigned long)idlest_reg & 0xff;
+ for (i = 0; i < ARRAY_SIZE(omap3xxx_cm_idlest_offs); i++) {
+ if (idlest_offs == omap3xxx_cm_idlest_offs[i]) {
+ *idlest_reg_id = i + 1;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(omap3xxx_cm_idlest_offs))
+ return -EINVAL;
+
+ offs = idlest_reg - cm_base;
+ offs &= 0xff00;
+ *prcm_inst = offs;
+
+ return 0;
+}
+
+/* Clockdomain low-level operations */
+
+static int omap3xxx_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 omap3xxx_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 omap3xxx_clkdm_read_sleepdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ return omap2_cm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
+ OMAP3430_CM_SLEEPDEP,
+ (1 << clkdm2->dep_bit));
+}
+
+static int omap3xxx_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 (!cd->clkdm)
+ continue; /* only happens if data is erroneous */
+
+ mask |= 1 << cd->clkdm->dep_bit;
+ cd->sleepdep_usecount = 0;
+ }
+ omap2_cm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
+ OMAP3430_CM_SLEEPDEP);
+ return 0;
+}
+
+static int omap3xxx_clkdm_sleep(struct clockdomain *clkdm)
+{
+ omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ return 0;
+}
+
+static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm)
+{
+ omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ return 0;
+}
+
+static void omap3xxx_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+ if (clkdm->usecount > 0)
+ clkdm_add_autodeps(clkdm);
+
+ omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+}
+
+static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+ omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (clkdm->usecount > 0)
+ clkdm_del_autodeps(clkdm);
+}
+
+static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ if (!clkdm->clktrctrl_mask)
+ return 0;
+
+ /*
+ * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+ * more details on the unpleasant problem this is working
+ * around
+ */
+ if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
+ (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
+ omap3xxx_clkdm_wakeup(clkdm);
+ return 0;
+ }
+
+ hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (hwsup) {
+ /* Disable HW transitions when we are changing deps */
+ omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ clkdm_add_autodeps(clkdm);
+ omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ } else {
+ if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+ omap3xxx_clkdm_wakeup(clkdm);
+ }
+
+ return 0;
+}
+
+static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ if (!clkdm->clktrctrl_mask)
+ return 0;
+
+ /*
+ * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+ * more details on the unpleasant problem this is working
+ * around
+ */
+ if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+ !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+ omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ return 0;
+ }
+
+ hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (hwsup) {
+ /* Disable HW transitions when we are changing deps */
+ omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ clkdm_del_autodeps(clkdm);
+ omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ } else {
+ if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
+ omap3xxx_clkdm_sleep(clkdm);
+ }
+
+ return 0;
+}
+
+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 = omap3xxx_clkdm_add_sleepdep,
+ .clkdm_del_sleepdep = omap3xxx_clkdm_del_sleepdep,
+ .clkdm_read_sleepdep = omap3xxx_clkdm_read_sleepdep,
+ .clkdm_clear_all_sleepdeps = omap3xxx_clkdm_clear_all_sleepdeps,
+ .clkdm_sleep = omap3xxx_clkdm_sleep,
+ .clkdm_wakeup = omap3xxx_clkdm_wakeup,
+ .clkdm_allow_idle = omap3xxx_clkdm_allow_idle,
+ .clkdm_deny_idle = omap3xxx_clkdm_deny_idle,
+ .clkdm_clk_enable = omap3xxx_clkdm_clk_enable,
+ .clkdm_clk_disable = omap3xxx_clkdm_clk_disable,
+};
+
+/*
+ * Context save/restore code - OMAP3 only
+ */
+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 =
+ omap2_cm_read_mod_reg(OCP_MOD, 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 =
+ omap2_cm_read_mod_reg(OCP_MOD, 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);
+ omap2_cm_write_mod_reg(cm_context.cm_sysconfig, OCP_MOD,
+ 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);
+ omap2_cm_write_mod_reg(cm_context.cm_polctrl, OCP_MOD,
+ 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);
+}
+
+void omap3_cm_save_scratchpad_contents(u32 *ptr)
+{
+ *ptr++ = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL);
+ *ptr++ = omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
+ *ptr++ = 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.
+ */
+ *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) &
+ ~OMAP3430_AUTO_PERIPH_DPLL_MASK;
+ *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL);
+ *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL);
+ *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3);
+ *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL);
+ *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL);
+ *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL);
+ *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL);
+}
+
+/*
+ *
+ */
+
+static struct cm_ll_data omap3xxx_cm_ll_data = {
+ .split_idlest_reg = &omap3xxx_cm_split_idlest_reg,
+ .wait_module_ready = &omap3xxx_cm_wait_module_ready,
+};
+
+int __init omap3xxx_cm_init(const struct omap_prcm_init_data *data)
+{
+ omap2_clk_legacy_provider_init(TI_CLKM_CM, cm_base + OMAP3430_IVA2_MOD);
+ return cm_register(&omap3xxx_cm_ll_data);
+}
+
+static void __exit omap3xxx_cm_exit(void)
+{
+ cm_unregister(&omap3xxx_cm_ll_data);
+}
+__exitcall(omap3xxx_cm_exit);
diff --git a/arch/arm/mach-omap2/cm3xxx.h b/arch/arm/mach-omap2/cm3xxx.h
new file mode 100644
index 000000000..bc444e208
--- /dev/null
+++ b/arch/arm/mach-omap2/cm3xxx.h
@@ -0,0 +1,79 @@
+/*
+ * 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_CM3XXX_H
+#define __ARCH_ASM_MACH_OMAP2_CM3XXX_H
+
+#include "prcm-common.h"
+#include "cm2xxx_3xxx.h"
+
+#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_SYSCONFIG 0x0010
+#define OMAP3430_CM_POLCTRL 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.
+ */
+
+/* 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 OMAP34XX_CM_IDLEST_VAL 1
+
+
+#ifndef __ASSEMBLER__
+
+extern void omap3_cm_save_context(void);
+extern void omap3_cm_restore_context(void);
+extern void omap3_cm_save_scratchpad_contents(u32 *ptr);
+
+int __init omap3xxx_cm_init(const struct omap_prcm_init_data *data);
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h
new file mode 100644
index 000000000..309a4c913
--- /dev/null
+++ b/arch/arm/mach-omap2/cm44xx.h
@@ -0,0 +1,28 @@
+/*
+ * OMAP4 Clock Management (CM) definitions
+ *
+ * Copyright (C) 2007-2011 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
+
+int omap4_cm_init(const struct omap_prcm_init_data *data);
+
+#endif
diff --git a/arch/arm/mach-omap2/cm81xx.h b/arch/arm/mach-omap2/cm81xx.h
new file mode 100644
index 000000000..45cb407da
--- /dev/null
+++ b/arch/arm/mach-omap2/cm81xx.h
@@ -0,0 +1,61 @@
+/*
+ * Clock domain register offsets for TI81XX.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/
+ * Copyright (C) 2013 SKTB SKiT, http://www.skitlab.ru/
+ *
+ * This program is free software; 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 __ARCH_ARM_MACH_OMAP2_CM_TI81XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM_TI81XX_H
+
+/* TI81XX common CM module offsets */
+#define TI81XX_CM_ALWON_MOD 0x1400 /* 1KB */
+
+/* TI816X CM module offsets */
+#define TI816X_CM_ACTIVE_MOD 0x0400 /* 256B */
+#define TI816X_CM_DEFAULT_MOD 0x0500 /* 256B */
+#define TI816X_CM_IVAHD0_MOD 0x0600 /* 256B */
+#define TI816X_CM_IVAHD1_MOD 0x0700 /* 256B */
+#define TI816X_CM_IVAHD2_MOD 0x0800 /* 256B */
+#define TI816X_CM_SGX_MOD 0x0900 /* 256B */
+
+/* ALWON */
+#define TI81XX_CM_ALWON_L3_SLOW_CLKDM 0x0000
+#define TI81XX_CM_ALWON_L3_MED_CLKDM 0x0004
+#define TI81XX_CM_ETHERNET_CLKDM 0x0004
+#define TI81XX_CM_MMU_CLKDM 0x000C
+#define TI81XX_CM_MMUCFG_CLKDM 0x0010
+#define TI81XX_CM_ALWON_MPU_CLKDM 0x001C
+#define TI81XX_CM_ALWON_L3_FAST_CLKDM 0x0030
+
+/* ACTIVE */
+#define TI816X_CM_ACTIVE_GEM_CLKDM 0x0000
+
+/* IVAHD0 */
+#define TI816X_CM_IVAHD0_CLKDM 0x0000
+
+/* IVAHD1 */
+#define TI816X_CM_IVAHD1_CLKDM 0x0000
+
+/* IVAHD2 */
+#define TI816X_CM_IVAHD2_CLKDM 0x0000
+
+/* SGX */
+#define TI816X_CM_SGX_CLKDM 0x0000
+
+/* DEFAULT */
+#define TI816X_CM_DEFAULT_L3_MED_CLKDM 0x0004
+#define TI816X_CM_DEFAULT_PCI_CLKDM 0x0010
+#define TI816X_CM_DEFAULT_L3_SLOW_CLKDM 0x0014
+#define TI816X_CM_DEFAULT_DUCATI_CLKDM 0x0018
+
+#endif
diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c
new file mode 100644
index 000000000..23e8bcec3
--- /dev/null
+++ b/arch/arm/mach-omap2/cm_common.c
@@ -0,0 +1,370 @@
+/*
+ * OMAP2+ common Clock Management (CM) IP block functions
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * 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 code should eventually be moved to a CM driver.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/bug.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include "cm2xxx.h"
+#include "cm3xxx.h"
+#include "cm33xx.h"
+#include "cm44xx.h"
+#include "clock.h"
+
+/*
+ * cm_ll_data: function pointers to SoC-specific implementations of
+ * common CM functions
+ */
+static struct cm_ll_data null_cm_ll_data;
+static struct cm_ll_data *cm_ll_data = &null_cm_ll_data;
+
+/* cm_base: base virtual address of the CM IP block */
+void __iomem *cm_base;
+
+/* cm2_base: base virtual address of the CM2 IP block (OMAP44xx only) */
+void __iomem *cm2_base;
+
+#define CM_NO_CLOCKS 0x1
+#define CM_SINGLE_INSTANCE 0x2
+
+/**
+ * omap2_set_globals_cm - set the CM/CM2 base addresses (for early use)
+ * @cm: CM base virtual address
+ * @cm2: CM2 base virtual address (if present on the booted SoC)
+ *
+ * XXX Will be replaced when the PRM/CM drivers are completed.
+ */
+void __init omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2)
+{
+ cm_base = cm;
+ cm2_base = cm2;
+}
+
+/**
+ * cm_split_idlest_reg - split CM_IDLEST reg addr into its components
+ * @idlest_reg: CM_IDLEST* virtual address
+ * @prcm_inst: pointer to an s16 to return the PRCM instance offset
+ * @idlest_reg_id: pointer to a u8 to return the CM_IDLESTx register ID
+ *
+ * Given an absolute CM_IDLEST register address @idlest_reg, passes
+ * the PRCM instance offset and IDLEST register ID back to the caller
+ * via the @prcm_inst and @idlest_reg_id. Returns -EINVAL upon error,
+ * or 0 upon success. XXX This function is only needed until absolute
+ * register addresses are removed from the OMAP struct clk records.
+ */
+int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
+ u8 *idlest_reg_id)
+{
+ if (!cm_ll_data->split_idlest_reg) {
+ WARN_ONCE(1, "cm: %s: no low-level function defined\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return cm_ll_data->split_idlest_reg(idlest_reg, prcm_inst,
+ idlest_reg_id);
+}
+
+/**
+ * omap_cm_wait_module_ready - wait for a module to leave idle or standby
+ * @part: PRCM partition
+ * @prcm_mod: PRCM module offset
+ * @idlest_reg: CM_IDLESTx register
+ * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
+ *
+ * Wait for the PRCM to indicate that the module identified by
+ * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon
+ * success, -EBUSY if the module doesn't enable in time, or -EINVAL if
+ * no per-SoC wait_module_ready() function pointer has been registered
+ * or if the idlest register is unknown on the SoC.
+ */
+int omap_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_reg,
+ u8 idlest_shift)
+{
+ if (!cm_ll_data->wait_module_ready) {
+ WARN_ONCE(1, "cm: %s: no low-level function defined\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return cm_ll_data->wait_module_ready(part, prcm_mod, idlest_reg,
+ idlest_shift);
+}
+
+/**
+ * omap_cm_wait_module_idle - wait for a module to enter idle or standby
+ * @part: PRCM partition
+ * @prcm_mod: PRCM module offset
+ * @idlest_reg: CM_IDLESTx register
+ * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
+ *
+ * Wait for the PRCM to indicate that the module identified by
+ * (@prcm_mod, @idlest_id, @idlest_shift) is no longer clocked. Return
+ * 0 upon success, -EBUSY if the module doesn't enable in time, or
+ * -EINVAL if no per-SoC wait_module_idle() function pointer has been
+ * registered or if the idlest register is unknown on the SoC.
+ */
+int omap_cm_wait_module_idle(u8 part, s16 prcm_mod, u16 idlest_reg,
+ u8 idlest_shift)
+{
+ if (!cm_ll_data->wait_module_idle) {
+ WARN_ONCE(1, "cm: %s: no low-level function defined\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return cm_ll_data->wait_module_idle(part, prcm_mod, idlest_reg,
+ idlest_shift);
+}
+
+/**
+ * omap_cm_module_enable - enable a module
+ * @mode: target mode for the module
+ * @part: PRCM partition
+ * @inst: PRCM instance
+ * @clkctrl_offs: CM_CLKCTRL register offset for the module
+ *
+ * Enables clocks for a module identified by (@part, @inst, @clkctrl_offs)
+ * making its IO space accessible. Return 0 upon success, -EINVAL if no
+ * per-SoC module_enable() function pointer has been registered.
+ */
+int omap_cm_module_enable(u8 mode, u8 part, u16 inst, u16 clkctrl_offs)
+{
+ if (!cm_ll_data->module_enable) {
+ WARN_ONCE(1, "cm: %s: no low-level function defined\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ cm_ll_data->module_enable(mode, part, inst, clkctrl_offs);
+ return 0;
+}
+
+/**
+ * omap_cm_module_disable - disable a module
+ * @part: PRCM partition
+ * @inst: PRCM instance
+ * @clkctrl_offs: CM_CLKCTRL register offset for the module
+ *
+ * Disables clocks for a module identified by (@part, @inst, @clkctrl_offs)
+ * makings its IO space inaccessible. Return 0 upon success, -EINVAL if
+ * no per-SoC module_disable() function pointer has been registered.
+ */
+int omap_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs)
+{
+ if (!cm_ll_data->module_disable) {
+ WARN_ONCE(1, "cm: %s: no low-level function defined\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ cm_ll_data->module_disable(part, inst, clkctrl_offs);
+ return 0;
+}
+
+/**
+ * cm_register - register per-SoC low-level data with the CM
+ * @cld: low-level per-SoC OMAP CM data & function pointers to register
+ *
+ * Register per-SoC low-level OMAP CM data and function pointers with
+ * the OMAP CM common interface. The caller must keep the data
+ * pointed to by @cld valid until it calls cm_unregister() and
+ * it returns successfully. Returns 0 upon success, -EINVAL if @cld
+ * is NULL, or -EEXIST if cm_register() has already been called
+ * without an intervening cm_unregister().
+ */
+int cm_register(struct cm_ll_data *cld)
+{
+ if (!cld)
+ return -EINVAL;
+
+ if (cm_ll_data != &null_cm_ll_data)
+ return -EEXIST;
+
+ cm_ll_data = cld;
+
+ return 0;
+}
+
+/**
+ * cm_unregister - unregister per-SoC low-level data & function pointers
+ * @cld: low-level per-SoC OMAP CM data & function pointers to unregister
+ *
+ * Unregister per-SoC low-level OMAP CM data and function pointers
+ * that were previously registered with cm_register(). The
+ * caller may not destroy any of the data pointed to by @cld until
+ * this function returns successfully. Returns 0 upon success, or
+ * -EINVAL if @cld is NULL or if @cld does not match the struct
+ * cm_ll_data * previously registered by cm_register().
+ */
+int cm_unregister(struct cm_ll_data *cld)
+{
+ if (!cld || cm_ll_data != cld)
+ return -EINVAL;
+
+ cm_ll_data = &null_cm_ll_data;
+
+ return 0;
+}
+
+#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
+ defined(CONFIG_SOC_DRA7XX)
+static struct omap_prcm_init_data cm_data __initdata = {
+ .index = TI_CLKM_CM,
+ .init = omap4_cm_init,
+};
+
+static struct omap_prcm_init_data cm2_data __initdata = {
+ .index = TI_CLKM_CM2,
+ .init = omap4_cm_init,
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2
+static struct omap_prcm_init_data omap2_prcm_data __initdata = {
+ .index = TI_CLKM_CM,
+ .init = omap2xxx_cm_init,
+ .flags = CM_NO_CLOCKS | CM_SINGLE_INSTANCE,
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+static struct omap_prcm_init_data omap3_cm_data __initdata = {
+ .index = TI_CLKM_CM,
+ .init = omap3xxx_cm_init,
+ .flags = CM_SINGLE_INSTANCE,
+
+ /*
+ * IVA2 offset is a negative value, must offset the cm_base address
+ * by this to get it to positive side on the iomap
+ */
+ .offset = -OMAP3430_IVA2_MOD,
+};
+#endif
+
+#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_TI81XX)
+static struct omap_prcm_init_data am3_prcm_data __initdata = {
+ .index = TI_CLKM_CM,
+ .flags = CM_NO_CLOCKS | CM_SINGLE_INSTANCE,
+ .init = am33xx_cm_init,
+};
+#endif
+
+#ifdef CONFIG_SOC_AM43XX
+static struct omap_prcm_init_data am4_prcm_data __initdata = {
+ .index = TI_CLKM_CM,
+ .flags = CM_NO_CLOCKS | CM_SINGLE_INSTANCE,
+ .init = omap4_cm_init,
+};
+#endif
+
+static const struct of_device_id omap_cm_dt_match_table[] __initconst = {
+#ifdef CONFIG_ARCH_OMAP2
+ { .compatible = "ti,omap2-prcm", .data = &omap2_prcm_data },
+#endif
+#ifdef CONFIG_ARCH_OMAP3
+ { .compatible = "ti,omap3-cm", .data = &omap3_cm_data },
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+ { .compatible = "ti,omap4-cm1", .data = &cm_data },
+ { .compatible = "ti,omap4-cm2", .data = &cm2_data },
+#endif
+#ifdef CONFIG_SOC_OMAP5
+ { .compatible = "ti,omap5-cm-core-aon", .data = &cm_data },
+ { .compatible = "ti,omap5-cm-core", .data = &cm2_data },
+#endif
+#ifdef CONFIG_SOC_DRA7XX
+ { .compatible = "ti,dra7-cm-core-aon", .data = &cm_data },
+ { .compatible = "ti,dra7-cm-core", .data = &cm2_data },
+#endif
+#ifdef CONFIG_SOC_AM33XX
+ { .compatible = "ti,am3-prcm", .data = &am3_prcm_data },
+#endif
+#ifdef CONFIG_SOC_AM43XX
+ { .compatible = "ti,am4-prcm", .data = &am4_prcm_data },
+#endif
+#ifdef CONFIG_SOC_TI81XX
+ { .compatible = "ti,dm814-prcm", .data = &am3_prcm_data },
+ { .compatible = "ti,dm816-prcm", .data = &am3_prcm_data },
+#endif
+ { }
+};
+
+/**
+ * omap2_cm_base_init - initialize iomappings for the CM drivers
+ *
+ * Detects and initializes the iomappings for the CM driver, based
+ * on the DT data. Returns 0 in success, negative error value
+ * otherwise.
+ */
+int __init omap2_cm_base_init(void)
+{
+ struct device_node *np;
+ const struct of_device_id *match;
+ struct omap_prcm_init_data *data;
+ void __iomem *mem;
+
+ for_each_matching_node_and_match(np, omap_cm_dt_match_table, &match) {
+ data = (struct omap_prcm_init_data *)match->data;
+
+ mem = of_iomap(np, 0);
+ if (!mem)
+ return -ENOMEM;
+
+ if (data->index == TI_CLKM_CM)
+ cm_base = mem + data->offset;
+
+ if (data->index == TI_CLKM_CM2)
+ cm2_base = mem + data->offset;
+
+ data->mem = mem;
+
+ data->np = np;
+
+ if (data->init && (data->flags & CM_SINGLE_INSTANCE ||
+ (cm_base && cm2_base)))
+ data->init(data);
+ }
+
+ return 0;
+}
+
+/**
+ * omap_cm_init - low level init for the CM drivers
+ *
+ * Initializes the low level clock infrastructure for CM drivers.
+ * Returns 0 in success, negative error value in failure.
+ */
+int __init omap_cm_init(void)
+{
+ struct device_node *np;
+ const struct of_device_id *match;
+ const struct omap_prcm_init_data *data;
+ int ret;
+
+ for_each_matching_node_and_match(np, omap_cm_dt_match_table, &match) {
+ data = match->data;
+
+ if (data->flags & CM_NO_CLOCKS)
+ continue;
+
+ ret = omap2_clk_provider_init(np, data->index, NULL, data->mem);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
new file mode 100644
index 000000000..2c0e07ed6
--- /dev/null
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -0,0 +1,528 @@
+/*
+ * OMAP4 CM instance functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2008-2011 Texas Instruments, Inc.
+ * 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.
+ *
+ * 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 "clockdomain.h"
+#include "cm.h"
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "cm44xx.h"
+#include "cm-regbits-34xx.h"
+#include "prcm44xx.h"
+#include "prm44xx.h"
+#include "prcm_mpu44xx.h"
+#include "prcm-common.h"
+
+#define OMAP4430_IDLEST_SHIFT 16
+#define OMAP4430_IDLEST_MASK (0x3 << 16)
+#define OMAP4430_CLKTRCTRL_SHIFT 0
+#define OMAP4430_CLKTRCTRL_MASK (0x3 << 0)
+#define OMAP4430_MODULEMODE_SHIFT 0
+#define OMAP4430_MODULEMODE_MASK (0x3 << 0)
+
+/*
+ * CLKCTRL_IDLEST_*: possible values for the CM_*_CLKCTRL.IDLEST bitfield:
+ *
+ * 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
+ *
+ */
+#define CLKCTRL_IDLEST_FUNCTIONAL 0x0
+#define CLKCTRL_IDLEST_INTRANSITION 0x1
+#define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2
+#define CLKCTRL_IDLEST_DISABLED 0x3
+
+static void __iomem *_cm_bases[OMAP4_MAX_PRCM_PARTITIONS];
+
+/**
+ * omap_cm_base_init - Populates the cm partitions
+ *
+ * Populates the base addresses of the _cm_bases
+ * array used for read/write of cm module registers.
+ */
+static void omap_cm_base_init(void)
+{
+ _cm_bases[OMAP4430_PRM_PARTITION] = prm_base;
+ _cm_bases[OMAP4430_CM1_PARTITION] = cm_base;
+ _cm_bases[OMAP4430_CM2_PARTITION] = cm2_base;
+ _cm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_base;
+}
+
+/* Private functions */
+
+static u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx);
+
+/**
+ * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield
+ * @part: PRCM partition ID that the CM_CLKCTRL register exists in
+ * @inst: CM instance register offset (*_INST macro)
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
+ *
+ * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to
+ * bit 0.
+ */
+static u32 _clkctrl_idlest(u8 part, u16 inst, u16 clkctrl_offs)
+{
+ u32 v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs);
+ v &= OMAP4430_IDLEST_MASK;
+ v >>= OMAP4430_IDLEST_SHIFT;
+ return v;
+}
+
+/**
+ * _is_module_ready - can module registers be accessed without causing an abort?
+ * @part: PRCM partition ID that the CM_CLKCTRL register exists in
+ * @inst: CM instance register offset (*_INST macro)
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
+ *
+ * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either
+ * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise.
+ */
+static bool _is_module_ready(u8 part, u16 inst, u16 clkctrl_offs)
+{
+ u32 v;
+
+ v = _clkctrl_idlest(part, inst, clkctrl_offs);
+
+ return (v == CLKCTRL_IDLEST_FUNCTIONAL ||
+ v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false;
+}
+
+/* Read a register in a CM instance */
+static u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx)
+{
+ BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
+ part == OMAP4430_INVALID_PRCM_PARTITION ||
+ !_cm_bases[part]);
+ return readl_relaxed(_cm_bases[part] + inst + idx);
+}
+
+/* Write into a register in a CM instance */
+static void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx)
+{
+ BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
+ part == OMAP4430_INVALID_PRCM_PARTITION ||
+ !_cm_bases[part]);
+ writel_relaxed(val, _cm_bases[part] + inst + idx);
+}
+
+/* Read-modify-write a register in CM1. Caller must lock */
+static u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, u16 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;
+}
+
+static u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, u16 inst, s16 idx)
+{
+ return omap4_cminst_rmw_inst_reg_bits(bits, bits, part, inst, idx);
+}
+
+static u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, u16 inst,
+ s16 idx)
+{
+ return omap4_cminst_rmw_inst_reg_bits(bits, 0x0, part, inst, idx);
+}
+
+static 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, u16 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.
+ */
+static bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 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.
+ */
+static void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 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.
+ */
+static void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs)
+{
+ _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, 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.
+ */
+static void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs)
+{
+ _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, part, inst, cdoffs);
+}
+
+/*
+ *
+ */
+
+static void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs)
+{
+ _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, part, inst, cdoffs);
+}
+
+/**
+ * omap4_cminst_wait_module_ready - wait for a module to be in 'func' state
+ * @part: PRCM partition ID that the CM_CLKCTRL register exists in
+ * @inst: CM instance register offset (*_INST macro)
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
+ * @bit_shift: bit shift for the register, ignored for OMAP4+
+ *
+ * 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"
+ */
+static int omap4_cminst_wait_module_ready(u8 part, s16 inst, u16 clkctrl_offs,
+ u8 bit_shift)
+{
+ int i = 0;
+
+ if (!clkctrl_offs)
+ return 0;
+
+ omap_test_timeout(_is_module_ready(part, inst, clkctrl_offs),
+ MAX_MODULE_READY_TIME, i);
+
+ return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
+}
+
+/**
+ * omap4_cminst_wait_module_idle - wait for a module to be in 'disabled'
+ * state
+ * @part: PRCM partition ID that the CM_CLKCTRL register exists in
+ * @inst: CM instance register offset (*_INST macro)
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
+ * @bit_shift: Bit shift for the register, ignored for OMAP4+
+ *
+ * Wait for the module IDLEST to be disabled. Some PRCM transition,
+ * like reset assertion or parent clock de-activation must wait the
+ * module to be fully disabled.
+ */
+static int omap4_cminst_wait_module_idle(u8 part, s16 inst, u16 clkctrl_offs,
+ u8 bit_shift)
+{
+ int i = 0;
+
+ if (!clkctrl_offs)
+ return 0;
+
+ omap_test_timeout((_clkctrl_idlest(part, inst, clkctrl_offs) ==
+ CLKCTRL_IDLEST_DISABLED),
+ MAX_MODULE_DISABLE_TIME, i);
+
+ return (i < MAX_MODULE_DISABLE_TIME) ? 0 : -EBUSY;
+}
+
+/**
+ * omap4_cminst_module_enable - Enable the modulemode inside CLKCTRL
+ * @mode: Module mode (SW or HW)
+ * @part: PRCM partition ID that the CM_CLKCTRL register exists in
+ * @inst: CM instance register offset (*_INST macro)
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
+ *
+ * No return value.
+ */
+static void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst,
+ u16 clkctrl_offs)
+{
+ u32 v;
+
+ v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs);
+ v &= ~OMAP4430_MODULEMODE_MASK;
+ v |= mode << OMAP4430_MODULEMODE_SHIFT;
+ omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs);
+}
+
+/**
+ * omap4_cminst_module_disable - Disable the module inside CLKCTRL
+ * @part: PRCM partition ID that the CM_CLKCTRL register exists in
+ * @inst: CM instance register offset (*_INST macro)
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
+ *
+ * No return value.
+ */
+static void omap4_cminst_module_disable(u8 part, u16 inst, u16 clkctrl_offs)
+{
+ u32 v;
+
+ v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs);
+ v &= ~OMAP4430_MODULEMODE_MASK;
+ omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs);
+}
+
+/*
+ * Clockdomain low-level functions
+ */
+
+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;
+
+ if (!clkdm->prcm_partition)
+ return 0;
+
+ for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
+ if (!cd->clkdm)
+ continue; /* only happens if data is erroneous */
+
+ mask |= 1 << cd->clkdm->dep_bit;
+ 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)
+{
+ if (clkdm->flags & CLKDM_CAN_HWSUP)
+ omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst,
+ clkdm->clkdm_offs);
+ else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
+ omap4_cminst_clkdm_force_sleep(clkdm->prcm_partition,
+ clkdm->cm_inst,
+ clkdm->clkdm_offs);
+ else
+ return -EINVAL;
+
+ 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)
+{
+ if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+ omap4_clkdm_wakeup(clkdm);
+ else
+ omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst,
+ clkdm->clkdm_offs);
+}
+
+static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+ if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+ return omap4_clkdm_wakeup(clkdm);
+
+ return 0;
+}
+
+static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ if (!clkdm->prcm_partition)
+ return 0;
+
+ /*
+ * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+ * more details on the unpleasant problem this is working
+ * around
+ */
+ if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+ !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+ omap4_clkdm_allow_idle(clkdm);
+ return 0;
+ }
+
+ hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+
+ if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
+ omap4_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,
+};
+
+struct clkdm_ops am43xx_clkdm_operations = {
+ .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,
+};
+
+static struct cm_ll_data omap4xxx_cm_ll_data = {
+ .wait_module_ready = &omap4_cminst_wait_module_ready,
+ .wait_module_idle = &omap4_cminst_wait_module_idle,
+ .module_enable = &omap4_cminst_module_enable,
+ .module_disable = &omap4_cminst_module_disable,
+};
+
+int __init omap4_cm_init(const struct omap_prcm_init_data *data)
+{
+ omap_cm_base_init();
+
+ return cm_register(&omap4xxx_cm_ll_data);
+}
+
+static void __exit omap4_cm_exit(void)
+{
+ cm_unregister(&omap4xxx_cm_ll_data);
+}
+__exitcall(omap4_cm_exit);
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 000000000..d246efd9f
--- /dev/null
+++ b/arch/arm/mach-omap2/common-board-devices.c
@@ -0,0 +1,103 @@
+/*
+ * 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/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+#include <linux/platform_data/spi-omap2-mcspi.h>
+
+#include "common.h"
+#include "common-board-devices.h"
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
+ defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+static struct omap2_mcspi_device_config ads7846_mcspi_config = {
+ .turbo_mode = 0,
+};
+
+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 a board defines get_pendown_state() function, request the pendown
+ * GPIO and set the GPIO debounce time.
+ * If a board does not define the get_pendown_state() function, then
+ * the ads7846 driver will setup the pendown GPIO itself.
+ */
+ 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;
+ }
+
+ if (gpio_debounce)
+ gpio_set_debounce(gpio_pendown, gpio_debounce);
+
+ gpio_export(gpio_pendown, 0);
+ }
+
+ spi_bi->bus_num = bus_num;
+ spi_bi->irq = gpio_to_irq(gpio_pendown);
+
+ ads7846_config.gpio_pendown = gpio_pendown;
+
+ if (board_pdata) {
+ board_pdata->gpio_pendown = gpio_pendown;
+ board_pdata->gpio_pendown_debounce = gpio_debounce;
+ 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
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 000000000..07c88ae08
--- /dev/null
+++ b/arch/arm/mach-omap2/common-board-devices.h
@@ -0,0 +1,20 @@
+#ifndef __OMAP_COMMON_BOARD_DEVICES__
+#define __OMAP_COMMON_BOARD_DEVICES__
+
+#include <sound/tlv320aic3x.h>
+#include <linux/mfd/menelaus.h>
+#include "twl-common.h"
+
+#define NAND_BLOCK_SIZE SZ_128K
+
+struct mtd_partition;
+struct ads7846_platform_data;
+
+void omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
+ struct ads7846_platform_data *board_pdata);
+void *n8x0_legacy_init(void);
+
+extern struct menelaus_platform_data n8x0_menelaus_platform_data;
+extern struct aic3x_pdata n810_aic33_data;
+
+#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 000000000..eae6a0e87
--- /dev/null
+++ b/arch/arm/mach-omap2/common.c
@@ -0,0 +1,33 @@
+/*
+ * 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 "common.h"
+#include "omap-secure.h"
+
+/*
+ * Stub function for OMAP2 so that common files
+ * continue to build when custom builds are used
+ */
+int __weak omap_secure_ram_reserve_memblock(void)
+{
+ return 0;
+}
+
+void __init omap_reserve(void)
+{
+ omap_secure_ram_reserve_memblock();
+}
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
new file mode 100644
index 000000000..cf3cf22ec
--- /dev/null
+++ b/arch/arm/mach-omap2/common.h
@@ -0,0 +1,325 @@
+/*
+ * Header for code common to all OMAP2+ 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_OMAP2PLUS_COMMON_H
+#define __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H
+#ifndef __ASSEMBLER__
+
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c/twl.h>
+#include <linux/i2c-omap.h>
+#include <linux/reboot.h>
+#include <linux/irqchip/irq-omap-intc.h>
+
+#include <asm/proc-fns.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "i2c.h"
+#include "serial.h"
+
+#include "usb.h"
+
+#define OMAP_INTC_START NR_IRQS
+
+#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP2)
+int omap2_pm_init(void);
+#else
+static inline int omap2_pm_init(void)
+{
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
+int omap3_pm_init(void);
+#else
+static inline int omap3_pm_init(void)
+{
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_PM) && (defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX))
+int omap4_pm_init(void);
+int omap4_pm_init_early(void);
+#else
+static inline int omap4_pm_init(void)
+{
+ return 0;
+}
+
+static inline int omap4_pm_init_early(void)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_OMAP_MUX
+int omap_mux_late_init(void);
+#else
+static inline int omap_mux_late_init(void)
+{
+ return 0;
+}
+#endif
+
+extern void omap2_init_common_infrastructure(void);
+
+extern void omap2_sync32k_timer_init(void);
+extern void omap3_sync32k_timer_init(void);
+extern void omap3_secure_sync32k_timer_init(void);
+extern void omap3_gptimer_timer_init(void);
+extern void omap4_local_timer_init(void);
+#ifdef CONFIG_CACHE_L2X0
+int omap_l2_cache_init(void);
+#define OMAP_L2C_AUX_CTRL (L2C_AUX_CTRL_SHARED_OVERRIDE | \
+ L310_AUX_CTRL_DATA_PREFETCH | \
+ L310_AUX_CTRL_INSTR_PREFETCH)
+void omap4_l2c310_write_sec(unsigned long val, unsigned reg);
+#else
+static inline int omap_l2_cache_init(void)
+{
+ return 0;
+}
+
+#define OMAP_L2C_AUX_CTRL 0
+#define omap4_l2c310_write_sec NULL
+#endif
+extern void omap5_realtime_timer_init(void);
+
+void omap2420_init_early(void);
+void omap2430_init_early(void);
+void omap3430_init_early(void);
+void omap35xx_init_early(void);
+void omap3630_init_early(void);
+void omap3_init_early(void); /* Do not use this one */
+void am33xx_init_early(void);
+void am35xx_init_early(void);
+void ti814x_init_early(void);
+void ti816x_init_early(void);
+void am33xx_init_early(void);
+void am43xx_init_early(void);
+void am43xx_init_late(void);
+void omap4430_init_early(void);
+void omap5_init_early(void);
+void omap3_init_late(void); /* Do not use this one */
+void omap4430_init_late(void);
+void omap2420_init_late(void);
+void omap2430_init_late(void);
+void omap3430_init_late(void);
+void omap35xx_init_late(void);
+void omap3630_init_late(void);
+void am35xx_init_late(void);
+void ti81xx_init_late(void);
+void am33xx_init_late(void);
+void omap5_init_late(void);
+int omap2_common_pm_late_init(void);
+void dra7xx_init_early(void);
+void dra7xx_init_late(void);
+
+#ifdef CONFIG_SOC_BUS
+void omap_soc_device_init(void);
+#else
+static inline void omap_soc_device_init(void)
+{
+}
+#endif
+
+#if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
+void omap2xxx_restart(enum reboot_mode mode, const char *cmd);
+#else
+static inline void omap2xxx_restart(enum reboot_mode mode, const char *cmd)
+{
+}
+#endif
+
+#ifdef CONFIG_SOC_AM33XX
+void am33xx_restart(enum reboot_mode mode, const char *cmd);
+#else
+static inline void am33xx_restart(enum reboot_mode mode, const char *cmd)
+{
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+void omap3xxx_restart(enum reboot_mode mode, const char *cmd);
+#else
+static inline void omap3xxx_restart(enum reboot_mode mode, const char *cmd)
+{
+}
+#endif
+
+#ifdef CONFIG_SOC_TI81XX
+void ti81xx_restart(enum reboot_mode mode, const char *cmd);
+#else
+static inline void ti81xx_restart(enum reboot_mode mode, const char *cmd)
+{
+}
+#endif
+
+#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
+ defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX)
+void omap44xx_restart(enum reboot_mode mode, const char *cmd);
+#else
+static inline void omap44xx_restart(enum reboot_mode mode, const char *cmd)
+{
+}
+#endif
+
+/* This gets called from mach-omap2/io.c, do not call this */
+void __init omap2_set_globals_tap(u32 class, void __iomem *tap);
+
+void __init omap242x_map_io(void);
+void __init omap243x_map_io(void);
+void __init omap3_map_io(void);
+void __init am33xx_map_io(void);
+void __init omap4_map_io(void);
+void __init omap5_map_io(void);
+void __init ti81xx_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);
+
+unsigned int omap4_xlate_irq(unsigned int hwirq);
+void omap_gic_of_init(void);
+
+#ifdef CONFIG_CACHE_L2X0
+extern void __iomem *omap4_get_l2cache_base(void);
+#endif
+
+struct device_node;
+
+#ifdef CONFIG_SMP
+extern void __iomem *omap4_get_scu_base(void);
+#else
+static inline void __iomem *omap4_get_scu_base(void)
+{
+ return NULL;
+}
+#endif
+
+extern void gic_dist_disable(void);
+extern void gic_dist_enable(void);
+extern bool gic_dist_disabled(void);
+extern void gic_timer_retrigger(void);
+extern void omap_smc1(u32 fn, u32 arg);
+extern void __iomem *omap4_get_sar_ram_base(void);
+extern void omap_do_wfi(void);
+
+#ifdef CONFIG_SMP
+/* Needed for secondary core boot */
+extern void omap4_secondary_startup(void);
+extern void omap4460_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);
+
+extern void omap4_cpu_die(unsigned int cpu);
+
+extern struct smp_operations omap4_smp_ops;
+
+extern void omap5_secondary_startup(void);
+extern void omap5_secondary_hyp_startup(void);
+#endif
+
+#if defined(CONFIG_SMP) && defined(CONFIG_PM)
+extern int omap4_mpuss_init(void);
+extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state);
+extern int omap4_finish_suspend(unsigned long cpu_state);
+extern void omap4_cpu_resume(void);
+extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state);
+#else
+static inline int omap4_enter_lowpower(unsigned int cpu,
+ unsigned int power_state)
+{
+ cpu_do_idle();
+ return 0;
+}
+
+static inline int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
+{
+ cpu_do_idle();
+ return 0;
+}
+
+static inline int omap4_mpuss_init(void)
+{
+ return 0;
+}
+
+static inline int omap4_finish_suspend(unsigned long cpu_state)
+{
+ return 0;
+}
+
+static inline void omap4_cpu_resume(void)
+{}
+
+#endif
+
+void pdata_quirks_init(const struct of_device_id *);
+void omap_auxdata_legacy_init(struct device *dev);
+void omap_pcs_legacy_init(int irq, void (*rearm)(void));
+
+struct omap_sdrc_params;
+extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
+ struct omap_sdrc_params *sdrc_cs1);
+struct omap2_hsmmc_info;
+extern void omap_reserve(void);
+
+struct omap_hwmod;
+extern int omap_dss_reset(struct omap_hwmod *);
+
+/* SoC specific clock initializer */
+int omap_clk_init(void);
+
+int __init omapdss_init_of(void);
+void __init omapdss_early_init_of(void);
+
+#endif /* __ASSEMBLER__ */
+#endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
new file mode 100644
index 000000000..af95a624f
--- /dev/null
+++ b/arch/arm/mach-omap2/control.c
@@ -0,0 +1,748 @@
+/*
+ * OMAP2/3 System Control Module register access
+ *
+ * Copyright (C) 2007, 2012 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 <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+#include "soc.h"
+#include "iomap.h"
+#include "common.h"
+#include "cm-regbits-34xx.h"
+#include "prm-regbits-34xx.h"
+#include "prm3xxx.h"
+#include "cm3xxx.h"
+#include "sdrc.h"
+#include "pm.h"
+#include "control.h"
+#include "clock.h"
+
+/* Used by omap3_ctrl_save_padconf() */
+#define START_PADCONF_SAVE 0x2
+#define PADCONF_SAVE_DONE 0x1
+
+static void __iomem *omap2_ctrl_base;
+static s16 omap2_ctrl_offset;
+static struct regmap *omap2_ctrl_syscon;
+
+#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_contents[2];
+ u32 cm_contents[11];
+ 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 */
+
+void __init omap2_set_globals_control(void __iomem *ctrl)
+{
+ omap2_ctrl_base = ctrl;
+}
+
+u8 omap_ctrl_readb(u16 offset)
+{
+ u32 val;
+ u8 byte_offset = offset & 0x3;
+
+ val = omap_ctrl_readl(offset);
+
+ return (val >> (byte_offset * 8)) & 0xff;
+}
+
+u16 omap_ctrl_readw(u16 offset)
+{
+ u32 val;
+ u16 byte_offset = offset & 0x2;
+
+ val = omap_ctrl_readl(offset);
+
+ return (val >> (byte_offset * 8)) & 0xffff;
+}
+
+u32 omap_ctrl_readl(u16 offset)
+{
+ u32 val;
+
+ offset &= 0xfffc;
+ if (!omap2_ctrl_syscon)
+ val = readl_relaxed(omap2_ctrl_base + offset);
+ else
+ regmap_read(omap2_ctrl_syscon, omap2_ctrl_offset + offset,
+ &val);
+
+ return val;
+}
+
+void omap_ctrl_writeb(u8 val, u16 offset)
+{
+ u32 tmp;
+ u8 byte_offset = offset & 0x3;
+
+ tmp = omap_ctrl_readl(offset);
+
+ tmp &= 0xffffffff ^ (0xff << (byte_offset * 8));
+ tmp |= val << (byte_offset * 8);
+
+ omap_ctrl_writel(tmp, offset);
+}
+
+void omap_ctrl_writew(u16 val, u16 offset)
+{
+ u32 tmp;
+ u8 byte_offset = offset & 0x2;
+
+ tmp = omap_ctrl_readl(offset);
+
+ tmp &= 0xffffffff ^ (0xffff << (byte_offset * 8));
+ tmp |= val << (byte_offset * 8);
+
+ omap_ctrl_writel(tmp, offset);
+}
+
+void omap_ctrl_writel(u32 val, u16 offset)
+{
+ offset &= 0xfffc;
+ if (!omap2_ctrl_syscon)
+ writel_relaxed(val, omap2_ctrl_base + offset);
+ else
+ regmap_write(omap2_ctrl_syscon, omap2_ctrl_offset + offset,
+ val);
+}
+
+#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
+ */
+ writel_relaxed(l, OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD + 4));
+}
+
+#endif
+
+/**
+ * omap_ctrl_write_dsp_boot_addr - set boot address for a remote processor
+ * @bootaddr: physical address of the boot loader
+ *
+ * Set boot address for the boot loader of a supported processor
+ * when a power ON sequence occurs.
+ */
+void omap_ctrl_write_dsp_boot_addr(u32 bootaddr)
+{
+ u32 offset = cpu_is_omap243x() ? OMAP243X_CONTROL_IVA2_BOOTADDR :
+ cpu_is_omap34xx() ? OMAP343X_CONTROL_IVA2_BOOTADDR :
+ cpu_is_omap44xx() ? OMAP4_CTRL_MODULE_CORE_DSP_BOOTADDR :
+ soc_is_omap54xx() ? OMAP4_CTRL_MODULE_CORE_DSP_BOOTADDR :
+ 0;
+
+ if (!offset) {
+ pr_err("%s: unsupported omap type\n", __func__);
+ return;
+ }
+
+ omap_ctrl_writel(bootaddr, offset);
+}
+
+/**
+ * omap_ctrl_write_dsp_boot_mode - set boot mode for a remote processor
+ * @bootmode: 8-bit value to pass to some boot code
+ *
+ * Sets boot mode for the boot loader of a supported processor
+ * when a power ON sequence occurs.
+ */
+void omap_ctrl_write_dsp_boot_mode(u8 bootmode)
+{
+ u32 offset = cpu_is_omap243x() ? OMAP243X_CONTROL_IVA2_BOOTMOD :
+ cpu_is_omap34xx() ? OMAP343X_CONTROL_IVA2_BOOTMOD :
+ 0;
+
+ if (!offset) {
+ pr_err("%s: unsupported omap type\n", __func__);
+ return;
+ }
+
+ omap_ctrl_writel(bootmode, offset);
+}
+
+#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 (omap3xxx_prm_clear_global_cold_reset()) {
+ for ( ; offset <= max_offset; offset += 0x4)
+ writel_relaxed(0x0, (v_addr + 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(omap3_restore_3630);
+ else if (omap_rev() != OMAP3430_REV_ES3_0 &&
+ omap_rev() != OMAP3430_REV_ES3_1 &&
+ omap_rev() != OMAP3430_REV_ES3_1_2)
+ scratchpad_contents.public_restore_ptr =
+ virt_to_phys(omap3_restore);
+ else
+ scratchpad_contents.public_restore_ptr =
+ virt_to_phys(omap3_restore_es3);
+
+ 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 */
+ omap3_prm_save_scratchpad_contents(prcm_block_contents.prm_contents);
+ omap3_cm_save_scratchpad_contents(prcm_block_contents.cm_contents);
+
+ 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);
+}
+
+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);
+}
+
+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;
+}
+
+/**
+ * omap3_ctrl_set_iva_bootmode_idle - sets the IVA2 bootmode to idle
+ *
+ * Sets the bootmode for IVA2 to idle. This is needed by the PM code to
+ * force disable IVA2 so that it does not prevent any low-power states.
+ */
+static void __init omap3_ctrl_set_iva_bootmode_idle(void)
+{
+ omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE,
+ OMAP343X_CONTROL_IVA2_BOOTMOD);
+}
+
+/**
+ * omap3_ctrl_setup_d2d_padconf - setup stacked modem pads for idle
+ *
+ * Sets up the pads controlling the stacked modem in such way that the
+ * device can enter idle.
+ */
+static void __init omap3_ctrl_setup_d2d_padconf(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);
+}
+
+/**
+ * omap3_ctrl_init - does static initializations for control module
+ *
+ * Initializes system control module. This sets up the sysconfig autoidle,
+ * and sets up modem and iva2 so that they can be idled properly.
+ */
+void __init omap3_ctrl_init(void)
+{
+ omap_ctrl_writel(OMAP3430_AUTOIDLE_MASK, OMAP2_CONTROL_SYSCONFIG);
+
+ omap3_ctrl_set_iva_bootmode_idle();
+
+ omap3_ctrl_setup_d2d_padconf();
+}
+#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
+
+struct control_init_data {
+ int index;
+ s16 offset;
+};
+
+static struct control_init_data ctrl_data = {
+ .index = TI_CLKM_CTRL,
+};
+
+static const struct control_init_data omap2_ctrl_data = {
+ .index = TI_CLKM_CTRL,
+ .offset = -OMAP2_CONTROL_GENERAL,
+};
+
+static const struct of_device_id omap_scrm_dt_match_table[] = {
+ { .compatible = "ti,am3-scm", .data = &ctrl_data },
+ { .compatible = "ti,am4-scm", .data = &ctrl_data },
+ { .compatible = "ti,omap2-scm", .data = &omap2_ctrl_data },
+ { .compatible = "ti,omap3-scm", .data = &omap2_ctrl_data },
+ { .compatible = "ti,dm816-scrm", .data = &ctrl_data },
+ { .compatible = "ti,omap4-scm-core", .data = &ctrl_data },
+ { .compatible = "ti,omap5-scm-core", .data = &ctrl_data },
+ { .compatible = "ti,dra7-scm-core", .data = &ctrl_data },
+ { }
+};
+
+/**
+ * omap2_control_base_init - initialize iomappings for the control driver
+ *
+ * Detects and initializes the iomappings for the control driver, based
+ * on the DT data. Returns 0 in success, negative error value
+ * otherwise.
+ */
+int __init omap2_control_base_init(void)
+{
+ struct device_node *np;
+ const struct of_device_id *match;
+ struct control_init_data *data;
+
+ for_each_matching_node_and_match(np, omap_scrm_dt_match_table, &match) {
+ data = (struct control_init_data *)match->data;
+
+ omap2_ctrl_base = of_iomap(np, 0);
+ if (!omap2_ctrl_base)
+ return -ENOMEM;
+
+ omap2_ctrl_offset = data->offset;
+ }
+
+ return 0;
+}
+
+/**
+ * omap_control_init - low level init for the control driver
+ *
+ * Initializes the low level clock infrastructure for control driver.
+ * Returns 0 in success, negative error value in failure.
+ */
+int __init omap_control_init(void)
+{
+ struct device_node *np, *scm_conf;
+ const struct of_device_id *match;
+ const struct omap_prcm_init_data *data;
+ int ret;
+ struct regmap *syscon;
+
+ for_each_matching_node_and_match(np, omap_scrm_dt_match_table, &match) {
+ data = match->data;
+
+ /*
+ * Check if we have scm_conf node, if yes, use this to
+ * access clock registers.
+ */
+ scm_conf = of_get_child_by_name(np, "scm_conf");
+
+ if (scm_conf) {
+ syscon = syscon_node_to_regmap(scm_conf);
+
+ if (IS_ERR(syscon))
+ return PTR_ERR(syscon);
+
+ omap2_ctrl_syscon = syscon;
+
+ if (of_get_child_by_name(scm_conf, "clocks")) {
+ ret = omap2_clk_provider_init(scm_conf,
+ data->index,
+ syscon, NULL);
+ if (ret)
+ return ret;
+ }
+
+ iounmap(omap2_ctrl_base);
+ omap2_ctrl_base = NULL;
+ } else {
+ /* No scm_conf found, direct access */
+ ret = omap2_clk_provider_init(np, data->index, NULL,
+ omap2_ctrl_base);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * omap3_control_legacy_iomap_init - legacy iomap init for clock providers
+ *
+ * Legacy iomap init for clock provider. Needed only by legacy boot mode,
+ * where the base addresses are not parsed from DT, but still required
+ * by the clock driver to be setup properly.
+ */
+void __init omap3_control_legacy_iomap_init(void)
+{
+ omap2_clk_legacy_provider_init(TI_CLKM_SCRM, omap2_ctrl_base);
+}
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
new file mode 100644
index 000000000..80d2b7d8e
--- /dev/null
+++ b/arch/arm/mach-omap2/control.h
@@ -0,0 +1,481 @@
+/*
+ * 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 "am33xx.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))
+#define AM33XX_CTRL_REGADDR(reg) \
+ AM33XX_L4_WK_IO_ADDRESS(AM33XX_SCM_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))
+#define AM33XX_CTRL_REGADDR(reg) \
+ AM33XX_L4_WK_IO_ADDRESS(AM33XX_SCM_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
+
+/* TI81XX spefic control submodules */
+#define TI81XX_CONTROL_DEVBOOT 0x040
+#define TI81XX_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)
+#define OMAP3630_CONTROL_CAMERA_PHY_CTRL (OMAP2_CONTROL_GENERAL + 0x02f0)
+
+/* 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
+#define OMAP44XX_CONTROL_FUSE_CORE_OPP100OV 0x25A
+
+/* 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 register 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
+
+/* TI81XX CONTROL_DEVBOOT register offsets */
+#define TI81XX_CONTROL_STATUS (TI81XX_CONTROL_DEVBOOT + 0x000)
+
+/* TI81XX CONTROL_DEVCONF register offsets */
+#define TI81XX_CONTROL_DEVICE_ID (TI81XX_CONTROL_DEVCONF + 0x000)
+
+/* OMAP4 CONTROL MODULE */
+#define OMAP4_CTRL_MODULE_PAD_WKUP 0x4a31e000
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_I2C_2 0x0604
+#define OMAP4_CTRL_MODULE_CORE_STATUS 0x02c4
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1 0x0218
+#define OMAP4_CTRL_MODULE_CORE_DSP_BOOTADDR 0x0304
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY 0x0618
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_CAMERA_RX 0x0608
+
+/* OMAP4 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)
+
+/* OMAP4 CONTROL_CAMERA_RX */
+#define OMAP4_CAMERARX_CSI21_LANEENABLE_SHIFT 24
+#define OMAP4_CAMERARX_CSI21_LANEENABLE_MASK (0x1f << 24)
+#define OMAP4_CAMERARX_CSI22_LANEENABLE_SHIFT 29
+#define OMAP4_CAMERARX_CSI22_LANEENABLE_MASK (0x3 << 29)
+#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)
+
+/* OMAP54XX CONTROL STATUS register */
+#define OMAP5XXX_CONTROL_STATUS 0x134
+#define OMAP5_DEVICETYPE_MASK (0x7 << 6)
+
+/* DRA7XX CONTROL CORE BOOTSTRAP */
+#define DRA7_CTRL_CORE_BOOTSTRAP 0x6c4
+#define DRA7_SPEEDSELECT_MASK (0x3 << 8)
+
+/*
+ * 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)
+
+/* AM33XX CONTROL_STATUS register */
+#define AM33XX_CONTROL_STATUS 0x040
+#define AM33XX_CONTROL_SEC_CLK_CTRL 0x1bc
+
+/* AM33XX CONTROL_STATUS bitfields (partial) */
+#define AM33XX_CONTROL_STATUS_SYSBOOT1_SHIFT 22
+#define AM33XX_CONTROL_STATUS_SYSBOOT1_WIDTH 0x2
+#define AM33XX_CONTROL_STATUS_SYSBOOT1_MASK (0x3 << 22)
+
+/* AM33XX PWMSS Control register */
+#define AM33XX_PWMSS_TBCLK_CLKCTRL 0x664
+
+/* AM33XX PWMSS Control bitfields */
+#define AM33XX_PWMSS0_TBCLKEN_SHIFT 0
+#define AM33XX_PWMSS1_TBCLKEN_SHIFT 1
+#define AM33XX_PWMSS2_TBCLKEN_SHIFT 2
+
+/* DEV Feature register to identify AM33XX features */
+#define AM33XX_DEV_FEATURE 0x604
+#define AM33XX_SGX_MASK BIT(29)
+
+/* 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 u8 omap_ctrl_readb(u16 offset);
+extern u16 omap_ctrl_readw(u16 offset);
+extern u32 omap_ctrl_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 omap3_save_scratchpad_contents(void);
+extern void omap3_clear_scratchpad_contents(void);
+extern void omap3_restore(void);
+extern void omap3_restore_es3(void);
+extern void omap3_restore_3630(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 omap_ctrl_write_dsp_boot_addr(u32 bootaddr);
+extern void omap_ctrl_write_dsp_boot_mode(u8 bootmode);
+extern void omap3630_ctrl_disable_rta(void);
+extern int omap3_ctrl_save_padconf(void);
+void omap3_ctrl_init(void);
+int omap2_control_base_init(void);
+int omap_control_init(void);
+void omap2_set_globals_control(void __iomem *ctrl);
+void __init omap3_control_legacy_iomap_init(void);
+#else
+#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 000000000..aa7b379e2
--- /dev/null
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -0,0 +1,337 @@
+/*
+ * 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 <linux/export.h>
+#include <linux/cpu_pm.h>
+#include <asm/cpuidle.h>
+
+#include "powerdomain.h"
+#include "clockdomain.h"
+
+#include "pm.h"
+#include "control.h"
+#include "common.h"
+
+/* Mach specific information to be recorded in the C-state driver_data */
+struct omap3_idle_statedata {
+ u8 mpu_state;
+ u8 core_state;
+ u8 per_min_state;
+ u8 flags;
+};
+
+static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd;
+
+/*
+ * Possible flag bits for struct omap3_idle_statedata.flags:
+ *
+ * OMAP_CPUIDLE_CX_NO_CLKDM_IDLE: don't allow the MPU clockdomain to go
+ * inactive. This in turn prevents the MPU DPLL from entering autoidle
+ * mode, so wakeup latency is greatly reduced, at the cost of additional
+ * energy consumption. This also prevents the CORE clockdomain from
+ * entering idle.
+ */
+#define OMAP_CPUIDLE_CX_NO_CLKDM_IDLE BIT(0)
+
+/*
+ * Prevent PER OFF if CORE is not in RETention or OFF as this would
+ * disable PER wakeups completely.
+ */
+static struct omap3_idle_statedata omap3_idle_data[] = {
+ {
+ .mpu_state = PWRDM_POWER_ON,
+ .core_state = PWRDM_POWER_ON,
+ /* In C1 do not allow PER state lower than CORE state */
+ .per_min_state = PWRDM_POWER_ON,
+ .flags = OMAP_CPUIDLE_CX_NO_CLKDM_IDLE,
+ },
+ {
+ .mpu_state = PWRDM_POWER_ON,
+ .core_state = PWRDM_POWER_ON,
+ .per_min_state = PWRDM_POWER_RET,
+ },
+ {
+ .mpu_state = PWRDM_POWER_RET,
+ .core_state = PWRDM_POWER_ON,
+ .per_min_state = PWRDM_POWER_RET,
+ },
+ {
+ .mpu_state = PWRDM_POWER_OFF,
+ .core_state = PWRDM_POWER_ON,
+ .per_min_state = PWRDM_POWER_RET,
+ },
+ {
+ .mpu_state = PWRDM_POWER_RET,
+ .core_state = PWRDM_POWER_RET,
+ .per_min_state = PWRDM_POWER_OFF,
+ },
+ {
+ .mpu_state = PWRDM_POWER_OFF,
+ .core_state = PWRDM_POWER_RET,
+ .per_min_state = PWRDM_POWER_OFF,
+ },
+ {
+ .mpu_state = PWRDM_POWER_OFF,
+ .core_state = PWRDM_POWER_OFF,
+ .per_min_state = PWRDM_POWER_OFF,
+ },
+};
+
+/**
+ * omap3_enter_idle - Programs OMAP3 to enter the specified state
+ * @dev: cpuidle device
+ * @drv: cpuidle driver
+ * @index: the index of state to be entered
+ */
+static int omap3_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ struct omap3_idle_statedata *cx = &omap3_idle_data[index];
+
+ if (omap_irq_pending() || need_resched())
+ goto return_sleep_time;
+
+ /* Deny idle for C1 */
+ if (cx->flags & OMAP_CPUIDLE_CX_NO_CLKDM_IDLE) {
+ clkdm_deny_idle(mpu_pd->pwrdm_clkdms[0]);
+ } else {
+ pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state);
+ pwrdm_set_next_pwrst(core_pd, cx->core_state);
+ }
+
+ /*
+ * Call idle CPU PM enter notifier chain so that
+ * VFP context is saved.
+ */
+ if (cx->mpu_state == PWRDM_POWER_OFF)
+ cpu_pm_enter();
+
+ /* Execute ARM wfi */
+ omap_sram_idle();
+
+ /*
+ * Call idle CPU PM enter notifier chain to restore
+ * VFP context.
+ */
+ if (cx->mpu_state == PWRDM_POWER_OFF &&
+ pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF)
+ cpu_pm_exit();
+
+ /* Re-allow idle for C1 */
+ if (cx->flags & OMAP_CPUIDLE_CX_NO_CLKDM_IDLE)
+ clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]);
+
+return_sleep_time:
+
+ return index;
+}
+
+/**
+ * next_valid_state - Find next valid C-state
+ * @dev: cpuidle device
+ * @drv: cpuidle driver
+ * @index: Index of currently selected c-state
+ *
+ * If the state corresponding to index is valid, index is returned back
+ * to the caller. Else, this function searches for a lower c-state which is
+ * still valid (as defined in omap3_power_states[]) and returns its index.
+ *
+ * A state is valid if the 'valid' field is enabled and
+ * if it satisfies the enable_off_mode condition.
+ */
+static int next_valid_state(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ struct omap3_idle_statedata *cx = &omap3_idle_data[index];
+ u32 mpu_deepest_state = PWRDM_POWER_RET;
+ u32 core_deepest_state = PWRDM_POWER_RET;
+ int idx;
+ int next_index = 0; /* C1 is the default value */
+
+ 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->mpu_state >= mpu_deepest_state) &&
+ (cx->core_state >= core_deepest_state))
+ return index;
+
+ /*
+ * Drop to next valid state.
+ * Start search from the next (lower) state.
+ */
+ for (idx = index - 1; idx >= 0; idx--) {
+ cx = &omap3_idle_data[idx];
+ if ((cx->mpu_state >= mpu_deepest_state) &&
+ (cx->core_state >= core_deepest_state)) {
+ next_index = idx;
+ break;
+ }
+ }
+
+ return next_index;
+}
+
+/**
+ * omap3_enter_idle_bm - Checks for any bus activity
+ * @dev: cpuidle device
+ * @drv: cpuidle driver
+ * @index: array index of 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_driver *drv,
+ int index)
+{
+ int new_state_idx, ret;
+ u8 per_next_state, per_saved_state;
+ struct omap3_idle_statedata *cx;
+
+ /*
+ * Use only C1 if CAM is active.
+ * CAM does not have wakeup capability in OMAP3.
+ */
+ if (pwrdm_read_pwrst(cam_pd) == PWRDM_POWER_ON)
+ new_state_idx = drv->safe_state_index;
+ else
+ new_state_idx = next_valid_state(dev, drv, index);
+
+ /*
+ * 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.
+ */
+
+ /* Program PER state */
+ cx = &omap3_idle_data[new_state_idx];
+
+ per_next_state = pwrdm_read_next_pwrst(per_pd);
+ per_saved_state = per_next_state;
+ if (per_next_state < cx->per_min_state) {
+ per_next_state = cx->per_min_state;
+ pwrdm_set_next_pwrst(per_pd, per_next_state);
+ }
+
+ ret = omap3_enter_idle(dev, drv, new_state_idx);
+
+ /* 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;
+}
+
+static struct cpuidle_driver omap3_idle_driver = {
+ .name = "omap3_idle",
+ .owner = THIS_MODULE,
+ .states = {
+ {
+ .enter = omap3_enter_idle_bm,
+ .exit_latency = 2 + 2,
+ .target_residency = 5,
+ .name = "C1",
+ .desc = "MPU ON + CORE ON",
+ },
+ {
+ .enter = omap3_enter_idle_bm,
+ .exit_latency = 10 + 10,
+ .target_residency = 30,
+ .name = "C2",
+ .desc = "MPU ON + CORE ON",
+ },
+ {
+ .enter = omap3_enter_idle_bm,
+ .exit_latency = 50 + 50,
+ .target_residency = 300,
+ .name = "C3",
+ .desc = "MPU RET + CORE ON",
+ },
+ {
+ .enter = omap3_enter_idle_bm,
+ .exit_latency = 1500 + 1800,
+ .target_residency = 4000,
+ .name = "C4",
+ .desc = "MPU OFF + CORE ON",
+ },
+ {
+ .enter = omap3_enter_idle_bm,
+ .exit_latency = 2500 + 7500,
+ .target_residency = 12000,
+ .name = "C5",
+ .desc = "MPU RET + CORE RET",
+ },
+ {
+ .enter = omap3_enter_idle_bm,
+ .exit_latency = 3000 + 8500,
+ .target_residency = 15000,
+ .name = "C6",
+ .desc = "MPU OFF + CORE RET",
+ },
+ {
+ .enter = omap3_enter_idle_bm,
+ .exit_latency = 10000 + 30000,
+ .target_residency = 30000,
+ .name = "C7",
+ .desc = "MPU OFF + CORE OFF",
+ },
+ },
+ .state_count = ARRAY_SIZE(omap3_idle_data),
+ .safe_state_index = 0,
+};
+
+/* Public functions */
+
+/**
+ * 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)
+{
+ mpu_pd = pwrdm_lookup("mpu_pwrdm");
+ core_pd = pwrdm_lookup("core_pwrdm");
+ per_pd = pwrdm_lookup("per_pwrdm");
+ cam_pd = pwrdm_lookup("cam_pwrdm");
+
+ if (!mpu_pd || !core_pd || !per_pd || !cam_pd)
+ return -ENODEV;
+
+ return cpuidle_register(&omap3_idle_driver, NULL);
+}
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
new file mode 100644
index 000000000..4b8e9f4d5
--- /dev/null
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -0,0 +1,248 @@
+/*
+ * OMAP4+ CPU idle Routines
+ *
+ * Copyright (C) 2011-2013 Texas Instruments, Inc.
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * 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/sched.h>
+#include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
+#include <linux/export.h>
+#include <linux/tick.h>
+
+#include <asm/cpuidle.h>
+
+#include "common.h"
+#include "pm.h"
+#include "prm.h"
+#include "clockdomain.h"
+
+#define MAX_CPUS 2
+
+/* Machine specific information */
+struct idle_statedata {
+ u32 cpu_state;
+ u32 mpu_logic_state;
+ u32 mpu_state;
+};
+
+static struct idle_statedata omap4_idle_data[] = {
+ {
+ .cpu_state = PWRDM_POWER_ON,
+ .mpu_state = PWRDM_POWER_ON,
+ .mpu_logic_state = PWRDM_POWER_RET,
+ },
+ {
+ .cpu_state = PWRDM_POWER_OFF,
+ .mpu_state = PWRDM_POWER_RET,
+ .mpu_logic_state = PWRDM_POWER_RET,
+ },
+ {
+ .cpu_state = PWRDM_POWER_OFF,
+ .mpu_state = PWRDM_POWER_RET,
+ .mpu_logic_state = PWRDM_POWER_OFF,
+ },
+};
+
+static struct powerdomain *mpu_pd, *cpu_pd[MAX_CPUS];
+static struct clockdomain *cpu_clkdm[MAX_CPUS];
+
+static atomic_t abort_barrier;
+static bool cpu_done[MAX_CPUS];
+static struct idle_statedata *state_ptr = &omap4_idle_data[0];
+
+/* Private functions */
+
+/**
+ * omap_enter_idle_[simple/coupled] - OMAP4PLUS cpuidle entry functions
+ * @dev: cpuidle device
+ * @drv: cpuidle driver
+ * @index: the index of state to be entered
+ *
+ * Called from the CPUidle framework to program the device to the
+ * specified low power state selected by the governor.
+ * Returns the amount of time spent in the low power state.
+ */
+static int omap_enter_idle_simple(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ omap_do_wfi();
+ return index;
+}
+
+static int omap_enter_idle_coupled(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ struct idle_statedata *cx = state_ptr + index;
+ u32 mpuss_can_lose_context = 0;
+
+ /*
+ * CPU0 has to wait and stay ON until CPU1 is OFF state.
+ * This is necessary to honour hardware recommondation
+ * of triggeing all the possible low power modes once CPU1 is
+ * out of coherency and in OFF mode.
+ */
+ if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
+ while (pwrdm_read_pwrst(cpu_pd[1]) != PWRDM_POWER_OFF) {
+ cpu_relax();
+
+ /*
+ * CPU1 could have already entered & exited idle
+ * without hitting off because of a wakeup
+ * or a failed attempt to hit off mode. Check for
+ * that here, otherwise we could spin forever
+ * waiting for CPU1 off.
+ */
+ if (cpu_done[1])
+ goto fail;
+
+ }
+ }
+
+ mpuss_can_lose_context = (cx->mpu_state == PWRDM_POWER_RET) &&
+ (cx->mpu_logic_state == PWRDM_POWER_OFF);
+
+ tick_broadcast_enter();
+
+ /*
+ * Call idle CPU PM enter notifier chain so that
+ * VFP and per CPU interrupt context is saved.
+ */
+ cpu_pm_enter();
+
+ if (dev->cpu == 0) {
+ pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
+ omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
+
+ /*
+ * Call idle CPU cluster PM enter notifier chain
+ * to save GIC and wakeupgen context.
+ */
+ if (mpuss_can_lose_context)
+ cpu_cluster_pm_enter();
+ }
+
+ omap4_enter_lowpower(dev->cpu, cx->cpu_state);
+ cpu_done[dev->cpu] = true;
+
+ /* Wakeup CPU1 only if it is not offlined */
+ if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
+
+ if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD) &&
+ mpuss_can_lose_context)
+ gic_dist_disable();
+
+ clkdm_wakeup(cpu_clkdm[1]);
+ omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
+ clkdm_allow_idle(cpu_clkdm[1]);
+
+ if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD) &&
+ mpuss_can_lose_context) {
+ while (gic_dist_disabled()) {
+ udelay(1);
+ cpu_relax();
+ }
+ gic_timer_retrigger();
+ }
+ }
+
+ /*
+ * Call idle CPU PM exit notifier chain to restore
+ * VFP and per CPU IRQ context.
+ */
+ cpu_pm_exit();
+
+ /*
+ * Call idle CPU cluster PM exit notifier chain
+ * to restore GIC and wakeupgen context.
+ */
+ if (dev->cpu == 0 && mpuss_can_lose_context)
+ cpu_cluster_pm_exit();
+
+ tick_broadcast_exit();
+
+fail:
+ cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
+ cpu_done[dev->cpu] = false;
+
+ return index;
+}
+
+/*
+ * For each cpu, setup the broadcast timer because local timers
+ * stops for the states above C1.
+ */
+static void omap_setup_broadcast_timer(void *arg)
+{
+ tick_broadcast_enable();
+}
+
+static struct cpuidle_driver omap4_idle_driver = {
+ .name = "omap4_idle",
+ .owner = THIS_MODULE,
+ .states = {
+ {
+ /* C1 - CPU0 ON + CPU1 ON + MPU ON */
+ .exit_latency = 2 + 2,
+ .target_residency = 5,
+ .enter = omap_enter_idle_simple,
+ .name = "C1",
+ .desc = "CPUx ON, MPUSS ON"
+ },
+ {
+ /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
+ .exit_latency = 328 + 440,
+ .target_residency = 960,
+ .flags = CPUIDLE_FLAG_COUPLED,
+ .enter = omap_enter_idle_coupled,
+ .name = "C2",
+ .desc = "CPUx OFF, MPUSS CSWR",
+ },
+ {
+ /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
+ .exit_latency = 460 + 518,
+ .target_residency = 1100,
+ .flags = CPUIDLE_FLAG_COUPLED,
+ .enter = omap_enter_idle_coupled,
+ .name = "C3",
+ .desc = "CPUx OFF, MPUSS OSWR",
+ },
+ },
+ .state_count = ARRAY_SIZE(omap4_idle_data),
+ .safe_state_index = 0,
+};
+
+/* Public functions */
+
+/**
+ * omap4_idle_init - Init routine for OMAP4+ idle
+ *
+ * Registers the OMAP4+ specific cpuidle driver to the cpuidle
+ * framework with the valid set of states.
+ */
+int __init omap4_idle_init(void)
+{
+ mpu_pd = pwrdm_lookup("mpu_pwrdm");
+ cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm");
+ cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm");
+ if ((!mpu_pd) || (!cpu_pd[0]) || (!cpu_pd[1]))
+ return -ENODEV;
+
+ cpu_clkdm[0] = clkdm_lookup("mpu0_clkdm");
+ cpu_clkdm[1] = clkdm_lookup("mpu1_clkdm");
+ if (!cpu_clkdm[0] || !cpu_clkdm[1])
+ return -ENODEV;
+
+ /* Configure the broadcast timer on each cpu */
+ on_each_cpu(omap_setup_broadcast_timer, NULL, 1);
+
+ return cpuidle_register(&omap4_idle_driver, cpu_online_mask);
+}
diff --git a/arch/arm/mach-omap2/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/ctrl_module_wkup_44xx.h
new file mode 100644
index 000000000..a0af9baec
--- /dev/null
+++ b/arch/arm/mach-omap2/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/devices.c b/arch/arm/mach-omap2/devices.c
new file mode 100644
index 000000000..990338fba
--- /dev/null
+++ b/arch/arm/mach-omap2/devices.c
@@ -0,0 +1,338 @@
+/*
+ * 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/gpio.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/platform_data/mailbox-omap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <linux/omap-dma.h>
+
+#include "iomap.h"
+#include "omap_hwmod.h"
+#include "omap_device.h"
+
+#include "soc.h"
+#include "common.h"
+#include "mux.h"
+#include "control.h"
+#include "devices.h"
+#include "display.h"
+
+#define L3_MODULES_MAX_LEN 12
+#define L3_MODULES 3
+
+static int __init omap3_l3_init(void)
+{
+ struct omap_hwmod *oh;
+ struct platform_device *pdev;
+ char oh_name[L3_MODULES_MAX_LEN];
+
+ /*
+ * To avoid code running on other OMAPs in
+ * multi-omap builds
+ */
+ if (!(cpu_is_omap34xx()) || of_have_populated_dt())
+ return -ENODEV;
+
+ 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);
+
+ pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0);
+
+ WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
+
+ return PTR_RET(pdev);
+}
+omap_postcore_initcall(omap3_l3_init);
+
+#if defined(CONFIG_IOMMU_API)
+
+#include <linux/platform_data/iommu-omap.h>
+
+static struct resource omap3isp_resources[] = {
+ {
+ .start = OMAP3430_ISP_BASE,
+ .end = OMAP3430_ISP_BASE + 0x12fc,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_BASE2,
+ .end = OMAP3430_ISP_BASE2 + 0x0600,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 24 + OMAP_INTC_START,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device omap3isp_device = {
+ .name = "omap3isp",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(omap3isp_resources),
+ .resource = omap3isp_resources,
+};
+
+static struct omap_iommu_arch_data omap3_isp_iommu = {
+ .name = "mmu_isp",
+};
+
+int omap3_init_camera(struct isp_platform_data *pdata)
+{
+ if (of_have_populated_dt())
+ omap3_isp_iommu.name = "480bd400.mmu";
+
+ omap3isp_device.dev.platform_data = pdata;
+ omap3isp_device.dev.archdata.iommu = &omap3_isp_iommu;
+
+ return platform_device_register(&omap3isp_device);
+}
+
+#else /* !CONFIG_IOMMU_API */
+
+int omap3_init_camera(struct isp_platform_data *pdata)
+{
+ return 0;
+}
+
+#endif
+
+#if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE)
+static inline void __init omap_init_mbox(void)
+{
+ struct omap_hwmod *oh;
+ struct platform_device *pdev;
+ struct omap_mbox_pdata *pdata;
+
+ oh = omap_hwmod_lookup("mailbox");
+ if (!oh) {
+ pr_err("%s: unable to find hwmod\n", __func__);
+ return;
+ }
+ if (!oh->dev_attr) {
+ pr_err("%s: hwmod doesn't have valid attrs\n", __func__);
+ return;
+ }
+
+ pdata = (struct omap_mbox_pdata *)oh->dev_attr;
+ pdev = omap_device_build("omap-mailbox", -1, oh, pdata, sizeof(*pdata));
+ WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n",
+ __func__, PTR_ERR(pdev));
+}
+#else
+static inline void omap_init_mbox(void) { }
+#endif /* CONFIG_OMAP2PLUS_MBOX */
+
+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,
+};
+
+static void omap_init_audio(void)
+{
+ 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 <linux/platform_data/spi-omap2-mcspi.h>
+
+static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused)
+{
+ struct platform_device *pdev;
+ 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");
+ kfree(pdata);
+ return -EINVAL;
+ }
+
+ spi_num++;
+ pdev = omap_device_build(name, spi_num, oh, pdata, sizeof(*pdata));
+ WARN(IS_ERR(pdev), "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
+
+/**
+ * omap_init_rng - bind the RNG hwmod to the RNG omap_device
+ *
+ * Bind the RNG hwmod to the RNG omap_device. No return value.
+ */
+static void omap_init_rng(void)
+{
+ struct omap_hwmod *oh;
+ struct platform_device *pdev;
+
+ oh = omap_hwmod_lookup("rng");
+ if (!oh)
+ return;
+
+ pdev = omap_device_build("omap_rng", -1, oh, NULL, 0);
+ WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n");
+}
+
+static void __init omap_init_sham(void)
+{
+ struct omap_hwmod *oh;
+ struct platform_device *pdev;
+
+ oh = omap_hwmod_lookup("sham");
+ if (!oh)
+ return;
+
+ pdev = omap_device_build("omap-sham", -1, oh, NULL, 0);
+ WARN(IS_ERR(pdev), "Can't build omap_device for omap-sham\n");
+}
+
+static void __init omap_init_aes(void)
+{
+ struct omap_hwmod *oh;
+ struct platform_device *pdev;
+
+ oh = omap_hwmod_lookup("aes");
+ if (!oh)
+ return;
+
+ pdev = omap_device_build("omap-aes", -1, oh, NULL, 0);
+ WARN(IS_ERR(pdev), "Can't build omap_device for omap-aes\n");
+}
+
+/*-------------------------------------------------------------------------*/
+
+#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,
+};
+
+int __init omap_init_vout(void)
+{
+ return platform_device_register(&omap_vout_device);
+}
+#else
+int __init omap_init_vout(void) { return 0; }
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+static int __init omap2_init_devices(void)
+{
+ /* Enable dummy states for those platforms without pinctrl support */
+ if (!of_have_populated_dt())
+ pinctrl_provide_dummies();
+
+ /*
+ * please keep these calls, and their implementations above,
+ * in alphabetical order so they're easier to sort through.
+ */
+ omap_init_audio();
+ /* If dtb is there, the devices will be created dynamically */
+ if (!of_have_populated_dt()) {
+ omap_init_mbox();
+ omap_init_mcspi();
+ omap_init_sham();
+ omap_init_aes();
+ omap_init_rng();
+ }
+ omap_init_sti();
+
+ return 0;
+}
+omap_arch_initcall(omap2_init_devices);
+
+static int __init omap_gpmc_init(void)
+{
+ struct omap_hwmod *oh;
+ struct platform_device *pdev;
+ char *oh_name = "gpmc";
+
+ /*
+ * if the board boots up with a populated DT, do not
+ * manually add the device from this initcall
+ */
+ if (of_have_populated_dt())
+ return -ENODEV;
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("Could not look up %s\n", oh_name);
+ return -ENODEV;
+ }
+
+ pdev = omap_device_build("omap-gpmc", -1, oh, NULL, 0);
+ WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
+
+ return PTR_RET(pdev);
+}
+omap_postcore_initcall(omap_gpmc_init);
diff --git a/arch/arm/mach-omap2/devices.h b/arch/arm/mach-omap2/devices.h
new file mode 100644
index 000000000..f61eb6e5d
--- /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 000000000..f492ae147
--- /dev/null
+++ b/arch/arm/mach-omap2/display.c
@@ -0,0 +1,680 @@
+/*
+ * 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/string.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+#include <video/omapdss.h>
+#include "omap_hwmod.h"
+#include "omap_device.h"
+#include "omap-pm.h"
+#include "common.h"
+
+#include "soc.h"
+#include "iomap.h"
+#include "control.h"
+#include "display.h"
+#include "prm.h"
+
+#define DISPC_CONTROL 0x0040
+#define DISPC_CONTROL2 0x0238
+#define DISPC_CONTROL3 0x0848
+#define DISPC_IRQSTATUS 0x0018
+
+#define DSS_SYSCONFIG 0x10
+#define DSS_SYSSTATUS 0x14
+#define DSS_CONTROL 0x40
+#define DSS_SDI_CONTROL 0x44
+#define DSS_PLL_CONTROL 0x48
+
+#define LCD_EN_MASK (0x1 << 0)
+#define DIGIT_EN_MASK (0x1 << 1)
+
+#define FRAMEDONE_IRQ_SHIFT 0
+#define EVSYNC_EVEN_IRQ_SHIFT 2
+#define EVSYNC_ODD_IRQ_SHIFT 3
+#define FRAMEDONE2_IRQ_SHIFT 22
+#define FRAMEDONE3_IRQ_SHIFT 30
+#define FRAMEDONETV_IRQ_SHIFT 24
+
+/*
+ * FRAMEDONE_IRQ_TIMEOUT: how long (in milliseconds) to wait during DISPC
+ * reset before deciding that something has gone wrong
+ */
+#define FRAMEDONE_IRQ_TIMEOUT 100
+
+static struct platform_device omap_display_device = {
+ .name = "omapdss",
+ .id = -1,
+ .dev = {
+ .platform_data = NULL,
+ },
+};
+
+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[] __initconst = {
+ { "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[] __initconst = {
+ { "dss_core", "omapdss_dss", -1 },
+ { "dss_dispc", "omapdss_dispc", -1 },
+ { "dss_rfbi", "omapdss_rfbi", -1 },
+ { "dss_venc", "omapdss_venc", -1 },
+ { "dss_dsi1", "omapdss_dsi", 0 },
+};
+
+static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initconst = {
+ { "dss_core", "omapdss_dss", -1 },
+ { "dss_dispc", "omapdss_dispc", -1 },
+ { "dss_rfbi", "omapdss_rfbi", -1 },
+ { "dss_dsi1", "omapdss_dsi", 0 },
+ { "dss_dsi2", "omapdss_dsi", 1 },
+ { "dss_hdmi", "omapdss_hdmi", -1 },
+};
+
+#define OMAP4_DSIPHY_SYSCON_OFFSET 0x78
+
+static struct regmap *omap4_dsi_mux_syscon;
+
+static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
+{
+ u32 enable_mask, enable_shift;
+ u32 pipd_mask, pipd_shift;
+ u32 reg;
+
+ if (dsi_id == 0) {
+ enable_mask = OMAP4_DSI1_LANEENABLE_MASK;
+ enable_shift = OMAP4_DSI1_LANEENABLE_SHIFT;
+ pipd_mask = OMAP4_DSI1_PIPD_MASK;
+ pipd_shift = OMAP4_DSI1_PIPD_SHIFT;
+ } else if (dsi_id == 1) {
+ enable_mask = OMAP4_DSI2_LANEENABLE_MASK;
+ enable_shift = OMAP4_DSI2_LANEENABLE_SHIFT;
+ pipd_mask = OMAP4_DSI2_PIPD_MASK;
+ pipd_shift = OMAP4_DSI2_PIPD_SHIFT;
+ } else {
+ return -ENODEV;
+ }
+
+ regmap_read(omap4_dsi_mux_syscon, OMAP4_DSIPHY_SYSCON_OFFSET, &reg);
+
+ reg &= ~enable_mask;
+ reg &= ~pipd_mask;
+
+ reg |= (lanes << enable_shift) & enable_mask;
+ reg |= (lanes << pipd_shift) & pipd_mask;
+
+ regmap_write(omap4_dsi_mux_syscon, OMAP4_DSIPHY_SYSCON_OFFSET, reg);
+
+ return 0;
+}
+
+static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
+{
+ if (cpu_is_omap44xx())
+ return omap4_dsi_mux_pads(dsi_id, lane_mask);
+
+ return 0;
+}
+
+static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
+{
+ if (cpu_is_omap44xx())
+ omap4_dsi_mux_pads(dsi_id, 0);
+}
+
+static int omap_dss_set_min_bus_tput(struct device *dev, unsigned long tput)
+{
+ return omap_pm_set_min_bus_tput(dev, OCP_INITIATOR_AGENT, tput);
+}
+
+static struct platform_device *create_dss_pdev(const char *pdev_name,
+ int pdev_id, const char *oh_name, void *pdata, int pdata_len,
+ struct platform_device *parent)
+{
+ struct platform_device *pdev;
+ struct omap_device *od;
+ struct omap_hwmod *ohs[1];
+ struct omap_hwmod *oh;
+ int r;
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("Could not look up %s\n", oh_name);
+ r = -ENODEV;
+ goto err;
+ }
+
+ pdev = platform_device_alloc(pdev_name, pdev_id);
+ if (!pdev) {
+ pr_err("Could not create pdev for %s\n", pdev_name);
+ r = -ENOMEM;
+ goto err;
+ }
+
+ if (parent != NULL)
+ pdev->dev.parent = &parent->dev;
+
+ if (pdev->id != -1)
+ dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
+ else
+ dev_set_name(&pdev->dev, "%s", pdev->name);
+
+ ohs[0] = oh;
+ od = omap_device_alloc(pdev, ohs, 1);
+ if (IS_ERR(od)) {
+ pr_err("Could not alloc omap_device for %s\n", pdev_name);
+ r = -ENOMEM;
+ goto err;
+ }
+
+ r = platform_device_add_data(pdev, pdata, pdata_len);
+ if (r) {
+ pr_err("Could not set pdata for %s\n", pdev_name);
+ goto err;
+ }
+
+ r = omap_device_register(pdev);
+ if (r) {
+ pr_err("Could not register omap_device for %s\n", pdev_name);
+ goto err;
+ }
+
+ return pdev;
+
+err:
+ return ERR_PTR(r);
+}
+
+static struct platform_device *create_simple_dss_pdev(const char *pdev_name,
+ int pdev_id, void *pdata, int pdata_len,
+ struct platform_device *parent)
+{
+ struct platform_device *pdev;
+ int r;
+
+ pdev = platform_device_alloc(pdev_name, pdev_id);
+ if (!pdev) {
+ pr_err("Could not create pdev for %s\n", pdev_name);
+ r = -ENOMEM;
+ goto err;
+ }
+
+ if (parent != NULL)
+ pdev->dev.parent = &parent->dev;
+
+ if (pdev->id != -1)
+ dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
+ else
+ dev_set_name(&pdev->dev, "%s", pdev->name);
+
+ r = platform_device_add_data(pdev, pdata, pdata_len);
+ if (r) {
+ pr_err("Could not set pdata for %s\n", pdev_name);
+ goto err;
+ }
+
+ r = platform_device_add(pdev);
+ if (r) {
+ pr_err("Could not register platform_device for %s\n", pdev_name);
+ goto err;
+ }
+
+ return pdev;
+
+err:
+ return ERR_PTR(r);
+}
+
+static enum omapdss_version __init omap_display_get_version(void)
+{
+ if (cpu_is_omap24xx())
+ return OMAPDSS_VER_OMAP24xx;
+ else if (cpu_is_omap3630())
+ return OMAPDSS_VER_OMAP3630;
+ else if (cpu_is_omap34xx()) {
+ if (soc_is_am35xx()) {
+ return OMAPDSS_VER_AM35xx;
+ } else {
+ if (omap_rev() < OMAP3430_REV_ES3_0)
+ return OMAPDSS_VER_OMAP34xx_ES1;
+ else
+ return OMAPDSS_VER_OMAP34xx_ES3;
+ }
+ } else if (omap_rev() == OMAP4430_REV_ES1_0)
+ return OMAPDSS_VER_OMAP4430_ES1;
+ else if (omap_rev() == OMAP4430_REV_ES2_0 ||
+ omap_rev() == OMAP4430_REV_ES2_1 ||
+ omap_rev() == OMAP4430_REV_ES2_2)
+ return OMAPDSS_VER_OMAP4430_ES2;
+ else if (cpu_is_omap44xx())
+ return OMAPDSS_VER_OMAP4;
+ else if (soc_is_omap54xx())
+ return OMAPDSS_VER_OMAP5;
+ else if (soc_is_am43xx())
+ return OMAPDSS_VER_AM43xx;
+ else
+ return OMAPDSS_VER_UNKNOWN;
+}
+
+int __init omap_display_init(struct omap_dss_board_info *board_data)
+{
+ int r = 0;
+ struct platform_device *pdev;
+ int i, oh_count;
+ const struct omap_dss_hwmod_data *curr_dss_hwmod;
+ struct platform_device *dss_pdev;
+ enum omapdss_version ver;
+
+ /* create omapdss device */
+
+ ver = omap_display_get_version();
+
+ if (ver == OMAPDSS_VER_UNKNOWN) {
+ pr_err("DSS not supported on this SoC\n");
+ return -ENODEV;
+ }
+
+ board_data->version = ver;
+ board_data->dsi_enable_pads = omap_dsi_enable_pads;
+ board_data->dsi_disable_pads = omap_dsi_disable_pads;
+ board_data->set_min_bus_tput = omap_dss_set_min_bus_tput;
+
+ omap_display_device.dev.platform_data = board_data;
+
+ r = platform_device_register(&omap_display_device);
+ if (r < 0) {
+ pr_err("Unable to register omapdss device\n");
+ return r;
+ }
+
+ /* create devices for dss hwmods */
+
+ 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);
+ }
+
+ /*
+ * First create the pdev for dss_core, which is used as a parent device
+ * by the other dss pdevs. Note: dss_core has to be the first item in
+ * the hwmod list.
+ */
+ dss_pdev = create_dss_pdev(curr_dss_hwmod[0].dev_name,
+ curr_dss_hwmod[0].id,
+ curr_dss_hwmod[0].oh_name,
+ board_data, sizeof(*board_data),
+ NULL);
+
+ if (IS_ERR(dss_pdev)) {
+ pr_err("Could not build omap_device for %s\n",
+ curr_dss_hwmod[0].oh_name);
+
+ return PTR_ERR(dss_pdev);
+ }
+
+ for (i = 1; i < oh_count; i++) {
+ pdev = create_dss_pdev(curr_dss_hwmod[i].dev_name,
+ curr_dss_hwmod[i].id,
+ curr_dss_hwmod[i].oh_name,
+ board_data, sizeof(*board_data),
+ dss_pdev);
+
+ if (IS_ERR(pdev)) {
+ pr_err("Could not build omap_device for %s\n",
+ curr_dss_hwmod[i].oh_name);
+
+ return PTR_ERR(pdev);
+ }
+ }
+
+ /* Create devices for DPI and SDI */
+
+ pdev = create_simple_dss_pdev("omapdss_dpi", 0,
+ board_data, sizeof(*board_data), dss_pdev);
+ if (IS_ERR(pdev)) {
+ pr_err("Could not build platform_device for omapdss_dpi\n");
+ return PTR_ERR(pdev);
+ }
+
+ if (cpu_is_omap34xx()) {
+ pdev = create_simple_dss_pdev("omapdss_sdi", 0,
+ board_data, sizeof(*board_data), dss_pdev);
+ if (IS_ERR(pdev)) {
+ pr_err("Could not build platform_device for omapdss_sdi\n");
+ return PTR_ERR(pdev);
+ }
+ }
+
+ /* create DRM device */
+ r = omap_init_drm();
+ if (r < 0) {
+ pr_err("Unable to register omapdrm device\n");
+ return r;
+ }
+
+ /* create vrfb device */
+ r = omap_init_vrfb();
+ if (r < 0) {
+ pr_err("Unable to register omapvrfb device\n");
+ return r;
+ }
+
+ /* create FB device */
+ r = omap_init_fb();
+ if (r < 0) {
+ pr_err("Unable to register omapfb device\n");
+ return r;
+ }
+
+ /* create V4L2 display device */
+ r = omap_init_vout();
+ if (r < 0) {
+ pr_err("Unable to register omap_vout device\n");
+ return r;
+ }
+
+ return 0;
+}
+
+static void dispc_disable_outputs(void)
+{
+ u32 v, irq_mask = 0;
+ bool lcd_en, digit_en, lcd2_en = false, lcd3_en = false;
+ int i;
+ struct omap_dss_dispc_dev_attr *da;
+ struct omap_hwmod *oh;
+
+ oh = omap_hwmod_lookup("dss_dispc");
+ if (!oh) {
+ WARN(1, "display: could not disable outputs during reset - could not find dss_dispc hwmod\n");
+ return;
+ }
+
+ if (!oh->dev_attr) {
+ pr_err("display: could not disable outputs during reset due to missing dev_attr\n");
+ return;
+ }
+
+ da = (struct omap_dss_dispc_dev_attr *)oh->dev_attr;
+
+ /* store value of LCDENABLE and DIGITENABLE bits */
+ v = omap_hwmod_read(oh, DISPC_CONTROL);
+ lcd_en = v & LCD_EN_MASK;
+ digit_en = v & DIGIT_EN_MASK;
+
+ /* store value of LCDENABLE for LCD2 */
+ if (da->manager_count > 2) {
+ v = omap_hwmod_read(oh, DISPC_CONTROL2);
+ lcd2_en = v & LCD_EN_MASK;
+ }
+
+ /* store value of LCDENABLE for LCD3 */
+ if (da->manager_count > 3) {
+ v = omap_hwmod_read(oh, DISPC_CONTROL3);
+ lcd3_en = v & LCD_EN_MASK;
+ }
+
+ if (!(lcd_en | digit_en | lcd2_en | lcd3_en))
+ return; /* no managers currently enabled */
+
+ /*
+ * If any manager was enabled, we need to disable it before
+ * DSS clocks are disabled or DISPC module is reset
+ */
+ if (lcd_en)
+ irq_mask |= 1 << FRAMEDONE_IRQ_SHIFT;
+
+ if (digit_en) {
+ if (da->has_framedonetv_irq) {
+ irq_mask |= 1 << FRAMEDONETV_IRQ_SHIFT;
+ } else {
+ irq_mask |= 1 << EVSYNC_EVEN_IRQ_SHIFT |
+ 1 << EVSYNC_ODD_IRQ_SHIFT;
+ }
+ }
+
+ if (lcd2_en)
+ irq_mask |= 1 << FRAMEDONE2_IRQ_SHIFT;
+ if (lcd3_en)
+ irq_mask |= 1 << FRAMEDONE3_IRQ_SHIFT;
+
+ /*
+ * clear any previous FRAMEDONE, FRAMEDONETV,
+ * EVSYNC_EVEN/ODD, FRAMEDONE2 or FRAMEDONE3 interrupts
+ */
+ omap_hwmod_write(irq_mask, oh, DISPC_IRQSTATUS);
+
+ /* disable LCD and TV managers */
+ v = omap_hwmod_read(oh, DISPC_CONTROL);
+ v &= ~(LCD_EN_MASK | DIGIT_EN_MASK);
+ omap_hwmod_write(v, oh, DISPC_CONTROL);
+
+ /* disable LCD2 manager */
+ if (da->manager_count > 2) {
+ v = omap_hwmod_read(oh, DISPC_CONTROL2);
+ v &= ~LCD_EN_MASK;
+ omap_hwmod_write(v, oh, DISPC_CONTROL2);
+ }
+
+ /* disable LCD3 manager */
+ if (da->manager_count > 3) {
+ v = omap_hwmod_read(oh, DISPC_CONTROL3);
+ v &= ~LCD_EN_MASK;
+ omap_hwmod_write(v, oh, DISPC_CONTROL3);
+ }
+
+ i = 0;
+ while ((omap_hwmod_read(oh, DISPC_IRQSTATUS) & irq_mask) !=
+ irq_mask) {
+ i++;
+ if (i > FRAMEDONE_IRQ_TIMEOUT) {
+ pr_err("didn't get FRAMEDONE1/2/3 or TV interrupt\n");
+ break;
+ }
+ mdelay(1);
+ }
+}
+
+int omap_dss_reset(struct omap_hwmod *oh)
+{
+ struct omap_hwmod_opt_clk *oc;
+ int c = 0;
+ int i, r;
+
+ if (!(oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)) {
+ pr_err("dss_core: hwmod data doesn't contain reset data\n");
+ return -EINVAL;
+ }
+
+ for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
+ if (oc->_clk)
+ clk_prepare_enable(oc->_clk);
+
+ dispc_disable_outputs();
+
+ /* clear SDI registers */
+ if (cpu_is_omap3430()) {
+ omap_hwmod_write(0x0, oh, DSS_SDI_CONTROL);
+ omap_hwmod_write(0x0, oh, DSS_PLL_CONTROL);
+ }
+
+ /*
+ * clear DSS_CONTROL register to switch DSS clock sources to
+ * PRCM clock, if any
+ */
+ omap_hwmod_write(0x0, oh, DSS_CONTROL);
+
+ omap_test_timeout((omap_hwmod_read(oh, oh->class->sysc->syss_offs)
+ & SYSS_RESETDONE_MASK),
+ MAX_MODULE_SOFTRESET_WAIT, c);
+
+ if (c == MAX_MODULE_SOFTRESET_WAIT)
+ pr_warn("dss_core: waiting for reset to finish failed\n");
+ else
+ pr_debug("dss_core: softreset done\n");
+
+ for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
+ if (oc->_clk)
+ clk_disable_unprepare(oc->_clk);
+
+ r = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
+
+ return r;
+}
+
+void __init omapdss_early_init_of(void)
+{
+
+}
+
+struct device_node * __init omapdss_find_dss_of_node(void)
+{
+ struct device_node *node;
+
+ node = of_find_compatible_node(NULL, NULL, "ti,omap2-dss");
+ if (node)
+ return node;
+
+ node = of_find_compatible_node(NULL, NULL, "ti,omap3-dss");
+ if (node)
+ return node;
+
+ node = of_find_compatible_node(NULL, NULL, "ti,omap4-dss");
+ if (node)
+ return node;
+
+ node = of_find_compatible_node(NULL, NULL, "ti,omap5-dss");
+ if (node)
+ return node;
+
+ return NULL;
+}
+
+int __init omapdss_init_of(void)
+{
+ int r;
+ enum omapdss_version ver;
+ struct device_node *node;
+ struct platform_device *pdev;
+
+ static struct omap_dss_board_info board_data = {
+ .dsi_enable_pads = omap_dsi_enable_pads,
+ .dsi_disable_pads = omap_dsi_disable_pads,
+ .set_min_bus_tput = omap_dss_set_min_bus_tput,
+ };
+
+ /* only create dss helper devices if dss is enabled in the .dts */
+
+ node = omapdss_find_dss_of_node();
+ if (!node)
+ return 0;
+
+ if (!of_device_is_available(node))
+ return 0;
+
+ ver = omap_display_get_version();
+
+ if (ver == OMAPDSS_VER_UNKNOWN) {
+ pr_err("DSS not supported on this SoC\n");
+ return -ENODEV;
+ }
+
+ pdev = of_find_device_by_node(node);
+
+ if (!pdev) {
+ pr_err("Unable to find DSS platform device\n");
+ return -ENODEV;
+ }
+
+ r = of_platform_populate(node, NULL, NULL, &pdev->dev);
+ if (r) {
+ pr_err("Unable to populate DSS submodule devices\n");
+ return r;
+ }
+
+ board_data.version = ver;
+
+ omap_display_device.dev.platform_data = &board_data;
+
+ r = platform_device_register(&omap_display_device);
+ if (r < 0) {
+ pr_err("Unable to register omapdss device\n");
+ return r;
+ }
+
+ /* create DRM device */
+ r = omap_init_drm();
+ if (r < 0) {
+ pr_err("Unable to register omapdrm device\n");
+ return r;
+ }
+
+ /* create vrfb device */
+ r = omap_init_vrfb();
+ if (r < 0) {
+ pr_err("Unable to register omapvrfb device\n");
+ return r;
+ }
+
+ /* create FB device */
+ r = omap_init_fb();
+ if (r < 0) {
+ pr_err("Unable to register omapfb device\n");
+ return r;
+ }
+
+ /* create V4L2 display device */
+ r = omap_init_vout();
+ if (r < 0) {
+ pr_err("Unable to register omap_vout device\n");
+ return r;
+ }
+
+ /* add DSI info for omap4 */
+ node = of_find_node_by_name(NULL, "omap4_padconf_global");
+ if (node)
+ omap4_dsi_mux_syscon = syscon_node_to_regmap(node);
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/display.h b/arch/arm/mach-omap2/display.h
new file mode 100644
index 000000000..7375854b1
--- /dev/null
+++ b/arch/arm/mach-omap2/display.h
@@ -0,0 +1,36 @@
+/*
+ * display.h - OMAP2+ integration-specific DSS header
+ *
+ * Copyright (C) 2011 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_DISPLAY_H
+#define __ARCH_ARM_MACH_OMAP2_DISPLAY_H
+
+#include <linux/kernel.h>
+
+struct omap_dss_dispc_dev_attr {
+ u8 manager_count;
+ bool has_framedonetv_irq;
+};
+
+int omap_init_drm(void);
+int omap_init_vrfb(void);
+int omap_init_fb(void);
+int omap_init_vout(void);
+
+struct device_node * __init omapdss_find_dss_of_node(void);
+
+#endif
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
new file mode 100644
index 000000000..e1a56d875
--- /dev/null
+++ b/arch/arm/mach-omap2/dma.c
@@ -0,0 +1,293 @@
+/*
+ * 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 <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/omap-dma.h>
+
+#include "soc.h"
+#include "omap_hwmod.h"
+#include "omap_device.h"
+
+static enum omap_reg_offsets dma_common_ch_end;
+
+static const struct omap_dma_reg reg_map[] = {
+ [REVISION] = { 0x0000, 0x00, OMAP_DMA_REG_32BIT },
+ [GCR] = { 0x0078, 0x00, OMAP_DMA_REG_32BIT },
+ [IRQSTATUS_L0] = { 0x0008, 0x00, OMAP_DMA_REG_32BIT },
+ [IRQSTATUS_L1] = { 0x000c, 0x00, OMAP_DMA_REG_32BIT },
+ [IRQSTATUS_L2] = { 0x0010, 0x00, OMAP_DMA_REG_32BIT },
+ [IRQSTATUS_L3] = { 0x0014, 0x00, OMAP_DMA_REG_32BIT },
+ [IRQENABLE_L0] = { 0x0018, 0x00, OMAP_DMA_REG_32BIT },
+ [IRQENABLE_L1] = { 0x001c, 0x00, OMAP_DMA_REG_32BIT },
+ [IRQENABLE_L2] = { 0x0020, 0x00, OMAP_DMA_REG_32BIT },
+ [IRQENABLE_L3] = { 0x0024, 0x00, OMAP_DMA_REG_32BIT },
+ [SYSSTATUS] = { 0x0028, 0x00, OMAP_DMA_REG_32BIT },
+ [OCP_SYSCONFIG] = { 0x002c, 0x00, OMAP_DMA_REG_32BIT },
+ [CAPS_0] = { 0x0064, 0x00, OMAP_DMA_REG_32BIT },
+ [CAPS_2] = { 0x006c, 0x00, OMAP_DMA_REG_32BIT },
+ [CAPS_3] = { 0x0070, 0x00, OMAP_DMA_REG_32BIT },
+ [CAPS_4] = { 0x0074, 0x00, OMAP_DMA_REG_32BIT },
+
+ /* Common register offsets */
+ [CCR] = { 0x0080, 0x60, OMAP_DMA_REG_32BIT },
+ [CLNK_CTRL] = { 0x0084, 0x60, OMAP_DMA_REG_32BIT },
+ [CICR] = { 0x0088, 0x60, OMAP_DMA_REG_32BIT },
+ [CSR] = { 0x008c, 0x60, OMAP_DMA_REG_32BIT },
+ [CSDP] = { 0x0090, 0x60, OMAP_DMA_REG_32BIT },
+ [CEN] = { 0x0094, 0x60, OMAP_DMA_REG_32BIT },
+ [CFN] = { 0x0098, 0x60, OMAP_DMA_REG_32BIT },
+ [CSEI] = { 0x00a4, 0x60, OMAP_DMA_REG_32BIT },
+ [CSFI] = { 0x00a8, 0x60, OMAP_DMA_REG_32BIT },
+ [CDEI] = { 0x00ac, 0x60, OMAP_DMA_REG_32BIT },
+ [CDFI] = { 0x00b0, 0x60, OMAP_DMA_REG_32BIT },
+ [CSAC] = { 0x00b4, 0x60, OMAP_DMA_REG_32BIT },
+ [CDAC] = { 0x00b8, 0x60, OMAP_DMA_REG_32BIT },
+
+ /* Channel specific register offsets */
+ [CSSA] = { 0x009c, 0x60, OMAP_DMA_REG_32BIT },
+ [CDSA] = { 0x00a0, 0x60, OMAP_DMA_REG_32BIT },
+ [CCEN] = { 0x00bc, 0x60, OMAP_DMA_REG_32BIT },
+ [CCFN] = { 0x00c0, 0x60, OMAP_DMA_REG_32BIT },
+ [COLOR] = { 0x00c4, 0x60, OMAP_DMA_REG_32BIT },
+
+ /* OMAP4 specific registers */
+ [CDP] = { 0x00d0, 0x60, OMAP_DMA_REG_32BIT },
+ [CNDP] = { 0x00d4, 0x60, OMAP_DMA_REG_32BIT },
+ [CCDN] = { 0x00d8, 0x60, OMAP_DMA_REG_32BIT },
+};
+
+static void __iomem *dma_base;
+static inline void dma_write(u32 val, int reg, int lch)
+{
+ void __iomem *addr = dma_base;
+
+ addr += reg_map[reg].offset;
+ addr += reg_map[reg].stride * lch;
+
+ writel_relaxed(val, addr);
+}
+
+static inline u32 dma_read(int reg, int lch)
+{
+ void __iomem *addr = dma_base;
+
+ addr += reg_map[reg].offset;
+ addr += reg_map[reg].stride * lch;
+
+ return readl_relaxed(addr);
+}
+
+static void omap2_clear_dma(int lch)
+{
+ int i;
+
+ for (i = CSDP; 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 unsigned configure_dma_errata(void)
+{
+ unsigned errata = 0;
+
+ /*
+ * 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;
+}
+
+static struct omap_system_dma_plat_info dma_plat_info __initdata = {
+ .reg_map = reg_map,
+ .channel_stride = 0x60,
+ .show_dma_caps = omap2_show_dma_caps,
+ .clear_dma = omap2_clear_dma,
+ .dma_write = dma_write,
+ .dma_read = dma_read,
+};
+
+static struct platform_device_info omap_dma_dev_info = {
+ .name = "omap-dma-engine",
+ .id = -1,
+ .dma_mask = DMA_BIT_MASK(32),
+};
+
+/* One time initializations */
+static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
+{
+ struct platform_device *pdev;
+ struct omap_system_dma_plat_info p;
+ struct omap_dma_dev_attr *d;
+ struct resource *mem;
+ char *name = "omap_dma_system";
+
+ p = dma_plat_info;
+ p.dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr;
+ p.errata = configure_dma_errata();
+
+ pdev = omap_device_build(name, 0, oh, &p, sizeof(p));
+ if (IS_ERR(pdev)) {
+ pr_err("%s: Can't build omap_device for %s:%s.\n",
+ __func__, name, oh->name);
+ return PTR_ERR(pdev);
+ }
+
+ omap_dma_dev_info.res = pdev->resource;
+ omap_dma_dev_info.num_res = pdev->num_resources;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
+ return -EINVAL;
+ }
+
+ dma_base = ioremap(mem->start, resource_size(mem));
+ if (!dma_base) {
+ dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
+ return -ENOMEM;
+ }
+
+ d = oh->dev_attr;
+
+ if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
+ d->dev_caps |= HS_CHANNELS_RESERVED;
+
+ if (platform_get_irq_byname(pdev, "0") < 0)
+ d->dev_caps |= DMA_ENGINE_HANDLE_IRQ;
+
+ /* Check the capabilities register for descriptor loading feature */
+ if (dma_read(CAPS_0, 0) & DMA_HAS_DESCRIPTOR_CAPS)
+ dma_common_ch_end = CCDN;
+ else
+ dma_common_ch_end = CCFN;
+
+ return 0;
+}
+
+static int __init omap2_system_dma_init(void)
+{
+ struct platform_device *pdev;
+ int res;
+
+ res = omap_hwmod_for_each_by_class("dma",
+ omap2_system_dma_init_dev, NULL);
+ if (res)
+ return res;
+
+ if (of_have_populated_dt())
+ return res;
+
+ pdev = platform_device_register_full(&omap_dma_dev_info);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return res;
+}
+omap_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 000000000..44e57ec22
--- /dev/null
+++ b/arch/arm/mach-omap2/dpll3xxx.c
@@ -0,0 +1,818 @@
+/*
+ * 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 "clockdomain.h"
+#include "clock.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_hw_omap *clk, u8 clken_bits)
+{
+ const struct dpll_data *dd;
+ u32 v;
+
+ dd = clk->dpll_data;
+
+ v = omap2_clk_readl(clk, dd->control_reg);
+ v &= ~dd->enable_mask;
+ v |= clken_bits << __ffs(dd->enable_mask);
+ omap2_clk_writel(v, clk, dd->control_reg);
+}
+
+/* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */
+static int _omap3_wait_dpll_status(struct clk_hw_omap *clk, u8 state)
+{
+ const struct dpll_data *dd;
+ int i = 0;
+ int ret = -EINVAL;
+ const char *clk_name;
+
+ dd = clk->dpll_data;
+ clk_name = __clk_get_name(clk->hw.clk);
+
+ state <<= __ffs(dd->idlest_mask);
+
+ while (((omap2_clk_readl(clk, 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_hw_omap *clk, u8 n)
+{
+ unsigned long fint;
+ u16 f = 0;
+
+ fint = __clk_get_rate(clk->dpll_data->clk_ref) / 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_hw_omap *clk)
+{
+ const struct dpll_data *dd;
+ u8 ai;
+ u8 state = 1;
+ int r = 0;
+
+ pr_debug("clock: locking DPLL %s\n", __clk_get_name(clk->hw.clk));
+
+ dd = clk->dpll_data;
+ state <<= __ffs(dd->idlest_mask);
+
+ /* Check if already locked */
+ if ((omap2_clk_readl(clk, dd->idlest_reg) & dd->idlest_mask) == state)
+ goto done;
+
+ ai = omap3_dpll_autoidle_read(clk);
+
+ if (ai)
+ 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);
+
+done:
+ 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_hw_omap *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_get_name(clk->hw.clk));
+
+ 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);
+
+ 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_hw_omap *clk)
+{
+ u8 ai;
+
+ if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP)))
+ return -EINVAL;
+
+ pr_debug("clock: stopping DPLL %s\n", __clk_get_name(clk->hw.clk));
+
+ ai = omap3_dpll_autoidle_read(clk);
+
+ _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_STOP);
+
+ if (ai)
+ omap3_dpll_allow_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_hw_omap *clk, u8 *dco, u16 m, u8 n)
+{
+ unsigned long fint, clkinp; /* watch out for overflow */
+
+ clkinp = __clk_get_rate(__clk_get_parent(clk->hw.clk));
+ 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_hw_omap *clk, u8 *sd_div, u16 m, u8 n)
+{
+ unsigned long clkinp, sd; /* watch out for overflow */
+ int mod1, mod2;
+
+ clkinp = __clk_get_rate(__clk_get_parent(clk->hw.clk));
+
+ /*
+ * 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
+ * @freqsel: FREQSEL value to set
+ *
+ * Program the DPLL with the last M, N values calculated, and wait for
+ * the DPLL to lock. Returns -EINVAL upon error, or 0 upon success.
+ */
+static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, 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. Jitter correction applicable for OMAP343X
+ * only since freqsel field is no longer present on other devices.
+ */
+ if (ti_clk_features.flags & TI_CLK_DPLL_HAS_FREQSEL) {
+ v = omap2_clk_readl(clk, dd->control_reg);
+ v &= ~dd->freqsel_mask;
+ v |= freqsel << __ffs(dd->freqsel_mask);
+ omap2_clk_writel(v, clk, dd->control_reg);
+ }
+
+ /* Set DPLL multiplier, divider */
+ v = omap2_clk_readl(clk, dd->mult_div1_reg);
+
+ /* Handle Duty Cycle Correction */
+ if (dd->dcc_mask) {
+ if (dd->last_rounded_rate >= dd->dcc_rate)
+ v |= dd->dcc_mask; /* Enable DCC */
+ else
+ v &= ~dd->dcc_mask; /* Disable DCC */
+ }
+
+ v &= ~(dd->mult_mask | dd->div1_mask);
+ v |= dd->last_rounded_m << __ffs(dd->mult_mask);
+ v |= (dd->last_rounded_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, dd->last_rounded_m, dd->last_rounded_n);
+ v &= ~(dd->dco_mask);
+ v |= dco << __ffs(dd->dco_mask);
+ }
+ if (dd->sddiv_mask) {
+ _lookup_sddiv(clk, &sd_div, dd->last_rounded_m,
+ dd->last_rounded_n);
+ v &= ~(dd->sddiv_mask);
+ v |= sd_div << __ffs(dd->sddiv_mask);
+ }
+
+ omap2_clk_writel(v, clk, dd->mult_div1_reg);
+
+ /* Set 4X multiplier and low-power mode */
+ if (dd->m4xen_mask || dd->lpmode_mask) {
+ v = omap2_clk_readl(clk, dd->control_reg);
+
+ if (dd->m4xen_mask) {
+ if (dd->last_rounded_m4xen)
+ v |= dd->m4xen_mask;
+ else
+ v &= ~dd->m4xen_mask;
+ }
+
+ if (dd->lpmode_mask) {
+ if (dd->last_rounded_lpmode)
+ v |= dd->lpmode_mask;
+ else
+ v &= ~dd->lpmode_mask;
+ }
+
+ omap2_clk_writel(v, clk, dd->control_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_hw *hw, unsigned long parent_rate)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+
+ 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_hw *hw)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ int r;
+ struct dpll_data *dd;
+ struct clk_hw *parent;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return -EINVAL;
+
+ if (clk->clkdm) {
+ r = clkdm_clk_enable(clk->clkdm, hw->clk);
+ if (r) {
+ WARN(1,
+ "%s: could not enable %s's clockdomain %s: %d\n",
+ __func__, __clk_get_name(hw->clk),
+ clk->clkdm->name, r);
+ return r;
+ }
+ }
+
+ parent = __clk_get_hw(__clk_get_parent(hw->clk));
+
+ if (__clk_get_rate(hw->clk) == __clk_get_rate(dd->clk_bypass)) {
+ WARN_ON(parent != __clk_get_hw(dd->clk_bypass));
+ r = _omap3_noncore_dpll_bypass(clk);
+ } else {
+ WARN_ON(parent != __clk_get_hw(dd->clk_ref));
+ r = _omap3_noncore_dpll_lock(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_hw *hw)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+
+ _omap3_noncore_dpll_stop(clk);
+ if (clk->clkdm)
+ clkdm_clk_disable(clk->clkdm, hw->clk);
+}
+
+
+/* Non-CORE DPLL rate set code */
+
+/**
+ * omap3_noncore_dpll_determine_rate - determine rate for a DPLL
+ * @hw: pointer to the clock to determine rate for
+ * @rate: target rate for the DPLL
+ * @best_parent_rate: pointer for returning best parent rate
+ * @best_parent_clk: pointer for returning best parent clock
+ *
+ * Determines which DPLL mode to use for reaching a desired target rate.
+ * Checks whether the DPLL shall be in bypass or locked mode, and if
+ * locked, calculates the M,N values for the DPLL via round-rate.
+ * Returns a positive clock rate with success, negative error value
+ * in failure.
+ */
+long omap3_noncore_dpll_determine_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long min_rate,
+ unsigned long max_rate,
+ unsigned long *best_parent_rate,
+ struct clk_hw **best_parent_clk)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ struct dpll_data *dd;
+
+ if (!hw || !rate)
+ return -EINVAL;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return -EINVAL;
+
+ if (__clk_get_rate(dd->clk_bypass) == rate &&
+ (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
+ *best_parent_clk = __clk_get_hw(dd->clk_bypass);
+ } else {
+ rate = omap2_dpll_round_rate(hw, rate, best_parent_rate);
+ *best_parent_clk = __clk_get_hw(dd->clk_ref);
+ }
+
+ *best_parent_rate = rate;
+
+ return rate;
+}
+
+/**
+ * omap3_noncore_dpll_set_parent - set parent for a DPLL clock
+ * @hw: pointer to the clock to set parent for
+ * @index: parent index to select
+ *
+ * Sets parent for a DPLL clock. This sets the DPLL into bypass or
+ * locked mode. Returns 0 with success, negative error value otherwise.
+ */
+int omap3_noncore_dpll_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ int ret;
+
+ if (!hw)
+ return -EINVAL;
+
+ if (index)
+ ret = _omap3_noncore_dpll_bypass(clk);
+ else
+ ret = _omap3_noncore_dpll_lock(clk);
+
+ return ret;
+}
+
+/**
+ * omap3_noncore_dpll_set_rate - set rate for a DPLL clock
+ * @hw: pointer to the clock to set parent for
+ * @rate: target rate for the clock
+ * @parent_rate: rate of the parent clock
+ *
+ * Sets rate for a DPLL clock. First checks if the clock parent is
+ * reference clock (in bypass mode, the rate of the clock can't be
+ * changed) and proceeds with the rate change operation. Returns 0
+ * with success, negative error value otherwise.
+ */
+int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ struct dpll_data *dd;
+ u16 freqsel = 0;
+ int ret;
+
+ if (!hw || !rate)
+ return -EINVAL;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return -EINVAL;
+
+ if (__clk_get_hw(__clk_get_parent(hw->clk)) !=
+ __clk_get_hw(dd->clk_ref))
+ return -EINVAL;
+
+ if (dd->last_rounded_rate == 0)
+ return -EINVAL;
+
+ /* Freqsel is available only on OMAP343X devices */
+ if (ti_clk_features.flags & TI_CLK_DPLL_HAS_FREQSEL) {
+ freqsel = _omap3_dpll_compute_freqsel(clk, dd->last_rounded_n);
+ WARN_ON(!freqsel);
+ }
+
+ pr_debug("%s: %s: set rate: locking rate to %lu.\n", __func__,
+ __clk_get_name(hw->clk), rate);
+
+ ret = omap3_noncore_dpll_program(clk, freqsel);
+
+ return ret;
+}
+
+/**
+ * omap3_noncore_dpll_set_rate_and_parent - set rate and parent for a DPLL clock
+ * @hw: pointer to the clock to set rate and parent for
+ * @rate: target rate for the DPLL
+ * @parent_rate: clock rate of the DPLL parent
+ * @index: new parent index for the DPLL, 0 - reference, 1 - bypass
+ *
+ * Sets rate and parent for a DPLL clock. If new parent is the bypass
+ * clock, only selects the parent. Otherwise proceeds with a rate
+ * change, as this will effectively also change the parent as the
+ * DPLL is put into locked mode. Returns 0 with success, negative error
+ * value otherwise.
+ */
+int omap3_noncore_dpll_set_rate_and_parent(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long parent_rate,
+ u8 index)
+{
+ int ret;
+
+ if (!hw || !rate)
+ return -EINVAL;
+
+ /*
+ * clk-ref at index[0], in which case we only need to set rate,
+ * the parent will be changed automatically with the lock sequence.
+ * With clk-bypass case we only need to change parent.
+ */
+ if (index)
+ ret = omap3_noncore_dpll_set_parent(hw, index);
+ else
+ ret = omap3_noncore_dpll_set_rate(hw, rate, parent_rate);
+
+ return ret;
+}
+
+/* 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_hw_omap *clk)
+{
+ const struct dpll_data *dd;
+ u32 v;
+
+ if (!clk || !clk->dpll_data)
+ return -EINVAL;
+
+ dd = clk->dpll_data;
+
+ if (!dd->autoidle_reg)
+ return -EINVAL;
+
+ v = omap2_clk_readl(clk, 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_hw_omap *clk)
+{
+ const struct dpll_data *dd;
+ u32 v;
+
+ if (!clk || !clk->dpll_data)
+ return;
+
+ dd = clk->dpll_data;
+
+ if (!dd->autoidle_reg)
+ return;
+
+ /*
+ * REVISIT: CORE DPLL can optionally enter low-power bypass
+ * by writing 0x5 instead of 0x1. Add some mechanism to
+ * optionally enter this mode.
+ */
+ v = omap2_clk_readl(clk, dd->autoidle_reg);
+ v &= ~dd->autoidle_mask;
+ v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask);
+ omap2_clk_writel(v, clk, 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_hw_omap *clk)
+{
+ const struct dpll_data *dd;
+ u32 v;
+
+ if (!clk || !clk->dpll_data)
+ return;
+
+ dd = clk->dpll_data;
+
+ if (!dd->autoidle_reg)
+ return;
+
+ v = omap2_clk_readl(clk, dd->autoidle_reg);
+ v &= ~dd->autoidle_mask;
+ v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask);
+ omap2_clk_writel(v, clk, dd->autoidle_reg);
+
+}
+
+/* Clock control for DPLL outputs */
+
+/* Find the parent DPLL for the given clkoutx2 clock */
+static struct clk_hw_omap *omap3_find_clkoutx2_dpll(struct clk_hw *hw)
+{
+ struct clk_hw_omap *pclk = NULL;
+ struct clk *parent;
+
+ /* Walk up the parents of clk, looking for a DPLL */
+ do {
+ do {
+ parent = __clk_get_parent(hw->clk);
+ hw = __clk_get_hw(parent);
+ } while (hw && (__clk_get_flags(hw->clk) & CLK_IS_BASIC));
+ if (!hw)
+ break;
+ pclk = to_clk_hw_omap(hw);
+ } while (pclk && !pclk->dpll_data);
+
+ /* clk does not have a DPLL as a parent? error in the clock data */
+ if (!pclk) {
+ WARN_ON(1);
+ return NULL;
+ }
+
+ return pclk;
+}
+
+/**
+ * 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_hw *hw,
+ unsigned long parent_rate)
+{
+ const struct dpll_data *dd;
+ unsigned long rate;
+ u32 v;
+ struct clk_hw_omap *pclk = NULL;
+
+ if (!parent_rate)
+ return 0;
+
+ pclk = omap3_find_clkoutx2_dpll(hw);
+
+ if (!pclk)
+ return 0;
+
+ dd = pclk->dpll_data;
+
+ WARN_ON(!dd->enable_mask);
+
+ v = omap2_clk_readl(pclk, dd->control_reg) & dd->enable_mask;
+ v >>= __ffs(dd->enable_mask);
+ if ((v != OMAP3XXX_EN_DPLL_LOCKED) || (dd->flags & DPLL_J_TYPE))
+ rate = parent_rate;
+ else
+ rate = parent_rate * 2;
+ return rate;
+}
+
+int omap3_clkoutx2_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ return 0;
+}
+
+long omap3_clkoutx2_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ const struct dpll_data *dd;
+ u32 v;
+ struct clk_hw_omap *pclk = NULL;
+
+ if (!*prate)
+ return 0;
+
+ pclk = omap3_find_clkoutx2_dpll(hw);
+
+ if (!pclk)
+ return 0;
+
+ dd = pclk->dpll_data;
+
+ /* TYPE J does not have a clkoutx2 */
+ if (dd->flags & DPLL_J_TYPE) {
+ *prate = __clk_round_rate(__clk_get_parent(pclk->hw.clk), rate);
+ return *prate;
+ }
+
+ WARN_ON(!dd->enable_mask);
+
+ v = omap2_clk_readl(pclk, dd->control_reg) & dd->enable_mask;
+ v >>= __ffs(dd->enable_mask);
+
+ /* If in bypass, the rate is fixed to the bypass rate*/
+ if (v != OMAP3XXX_EN_DPLL_LOCKED)
+ return *prate;
+
+ if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) {
+ unsigned long best_parent;
+
+ best_parent = (rate / 2);
+ *prate = __clk_round_rate(__clk_get_parent(hw->clk),
+ best_parent);
+ }
+
+ return *prate * 2;
+}
+
+/* OMAP3/4 non-CORE DPLL clkops */
+const struct clk_hw_omap_ops clkhwops_omap3_dpll = {
+ .allow_idle = omap3_dpll_allow_idle,
+ .deny_idle = omap3_dpll_deny_idle,
+};
diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c
new file mode 100644
index 000000000..f231be05b
--- /dev/null
+++ b/arch/arm/mach-omap2/dpll44xx.c
@@ -0,0 +1,232 @@
+/*
+ * 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 "clock.h"
+
+/*
+ * Maximum DPLL input frequency (FINT) and output frequency (FOUT) that
+ * can supported when using the DPLL low-power mode. Frequencies are
+ * defined in OMAP4430/60 Public TRM section 3.6.3.3.2 "Enable Control,
+ * Status, and Low-Power Operation Mode".
+ */
+#define OMAP4_DPLL_LP_FINT_MAX 1000000
+#define OMAP4_DPLL_LP_FOUT_MAX 100000000
+
+/*
+ * Bitfield declarations
+ */
+#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK (1 << 8)
+#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK (1 << 10)
+#define OMAP4430_DPLL_REGM4XEN_MASK (1 << 11)
+
+/* Static rate multiplier for OMAP4 REGM4XEN clocks */
+#define OMAP4430_REGM4XEN_MULT 4
+
+void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk)
+{
+ u32 v;
+ u32 mask;
+
+ if (!clk || !clk->clksel_reg)
+ return;
+
+ mask = clk->flags & CLOCK_CLKOUTX2 ?
+ OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK :
+ OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK;
+
+ v = omap2_clk_readl(clk, clk->clksel_reg);
+ /* Clear the bit to allow gatectrl */
+ v &= ~mask;
+ omap2_clk_writel(v, clk, clk->clksel_reg);
+}
+
+void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk)
+{
+ u32 v;
+ u32 mask;
+
+ if (!clk || !clk->clksel_reg)
+ return;
+
+ mask = clk->flags & CLOCK_CLKOUTX2 ?
+ OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK :
+ OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK;
+
+ v = omap2_clk_readl(clk, clk->clksel_reg);
+ /* Set the bit to deny gatectrl */
+ v |= mask;
+ omap2_clk_writel(v, clk, clk->clksel_reg);
+}
+
+const struct clk_hw_omap_ops clkhwops_omap4_dpllmx = {
+ .allow_idle = omap4_dpllmx_allow_gatectrl,
+ .deny_idle = omap4_dpllmx_deny_gatectrl,
+};
+
+/**
+ * omap4_dpll_lpmode_recalc - compute DPLL low-power setting
+ * @dd: pointer to the dpll data structure
+ *
+ * Calculates if low-power mode can be enabled based upon the last
+ * multiplier and divider values calculated. If low-power mode can be
+ * enabled, then the bit to enable low-power mode is stored in the
+ * last_rounded_lpmode variable. This implementation is based upon the
+ * criteria for enabling low-power mode as described in the OMAP4430/60
+ * Public TRM section 3.6.3.3.2 "Enable Control, Status, and Low-Power
+ * Operation Mode".
+ */
+static void omap4_dpll_lpmode_recalc(struct dpll_data *dd)
+{
+ long fint, fout;
+
+ fint = __clk_get_rate(dd->clk_ref) / (dd->last_rounded_n + 1);
+ fout = fint * dd->last_rounded_m;
+
+ if ((fint < OMAP4_DPLL_LP_FINT_MAX) && (fout < OMAP4_DPLL_LP_FOUT_MAX))
+ dd->last_rounded_lpmode = 1;
+ else
+ dd->last_rounded_lpmode = 0;
+}
+
+/**
+ * omap4_dpll_regm4xen_recalc - compute DPLL rate, considering REGM4XEN bit
+ * @clk: struct clk * of the DPLL to compute the rate for
+ *
+ * Compute the output rate for the OMAP4 DPLL represented by @clk.
+ * Takes the REGM4XEN bit into consideration, which is needed for the
+ * OMAP4 ABE DPLL. Returns the DPLL's output rate (before M-dividers)
+ * upon success, or 0 upon error.
+ */
+unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ u32 v;
+ unsigned long rate;
+ struct dpll_data *dd;
+
+ if (!clk || !clk->dpll_data)
+ return 0;
+
+ dd = clk->dpll_data;
+
+ rate = omap2_get_dpll_rate(clk);
+
+ /* regm4xen adds a multiplier of 4 to DPLL calculations */
+ v = omap2_clk_readl(clk, dd->control_reg);
+ if (v & OMAP4430_DPLL_REGM4XEN_MASK)
+ rate *= OMAP4430_REGM4XEN_MULT;
+
+ return rate;
+}
+
+/**
+ * omap4_dpll_regm4xen_round_rate - round DPLL rate, considering REGM4XEN bit
+ * @clk: struct clk * of the DPLL to round a rate for
+ * @target_rate: the desired rate of the DPLL
+ *
+ * Compute the rate that would be programmed into the DPLL hardware
+ * for @clk if set_rate() were to be provided with the rate
+ * @target_rate. Takes the REGM4XEN bit into consideration, which is
+ * needed for the OMAP4 ABE DPLL. Returns the rounded rate (before
+ * M-dividers) upon success, -EINVAL if @clk is null or not a DPLL, or
+ * ~0 if an error occurred in omap2_dpll_round_rate().
+ */
+long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
+ unsigned long target_rate,
+ unsigned long *parent_rate)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ struct dpll_data *dd;
+ long r;
+
+ if (!clk || !clk->dpll_data)
+ return -EINVAL;
+
+ dd = clk->dpll_data;
+
+ dd->last_rounded_m4xen = 0;
+
+ /*
+ * First try to compute the DPLL configuration for
+ * target rate without using the 4X multiplier.
+ */
+ r = omap2_dpll_round_rate(hw, target_rate, NULL);
+ if (r != ~0)
+ goto out;
+
+ /*
+ * If we did not find a valid DPLL configuration, try again, but
+ * this time see if using the 4X multiplier can help. Enabling the
+ * 4X multiplier is equivalent to dividing the target rate by 4.
+ */
+ r = omap2_dpll_round_rate(hw, target_rate / OMAP4430_REGM4XEN_MULT,
+ NULL);
+ if (r == ~0)
+ return r;
+
+ dd->last_rounded_rate *= OMAP4430_REGM4XEN_MULT;
+ dd->last_rounded_m4xen = 1;
+
+out:
+ omap4_dpll_lpmode_recalc(dd);
+
+ return dd->last_rounded_rate;
+}
+
+/**
+ * omap4_dpll_regm4xen_determine_rate - determine rate for a DPLL
+ * @hw: pointer to the clock to determine rate for
+ * @rate: target rate for the DPLL
+ * @best_parent_rate: pointer for returning best parent rate
+ * @best_parent_clk: pointer for returning best parent clock
+ *
+ * Determines which DPLL mode to use for reaching a desired rate.
+ * Checks whether the DPLL shall be in bypass or locked mode, and if
+ * locked, calculates the M,N values for the DPLL via round-rate.
+ * Returns a positive clock rate with success, negative error value
+ * in failure.
+ */
+long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long min_rate,
+ unsigned long max_rate,
+ unsigned long *best_parent_rate,
+ struct clk_hw **best_parent_clk)
+{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+ struct dpll_data *dd;
+
+ if (!hw || !rate)
+ return -EINVAL;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return -EINVAL;
+
+ if (__clk_get_rate(dd->clk_bypass) == rate &&
+ (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
+ *best_parent_clk = __clk_get_hw(dd->clk_bypass);
+ } else {
+ rate = omap4_dpll_regm4xen_round_rate(hw, rate,
+ best_parent_rate);
+ *best_parent_clk = __clk_get_hw(dd->clk_ref);
+ }
+
+ *best_parent_rate = rate;
+
+ return rate;
+}
diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c
new file mode 100644
index 000000000..facd7406a
--- /dev/null
+++ b/arch/arm/mach-omap2/drm.c
@@ -0,0 +1,53 @@
+/*
+ * DRM/KMS device registration for TI OMAP platforms
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * Author: Rob Clark <rob.clark@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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_data/omap_drm.h>
+
+#include "soc.h"
+#include "display.h"
+
+#if defined(CONFIG_DRM_OMAP) || defined(CONFIG_DRM_OMAP_MODULE)
+
+static struct omap_drm_platform_data platform_data;
+
+static struct platform_device omap_drm_device = {
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &platform_data,
+ },
+ .name = "omapdrm",
+ .id = 0,
+};
+
+int __init omap_init_drm(void)
+{
+ platform_data.omaprev = GET_OMAP_TYPE;
+
+ return platform_device_register(&omap_drm_device);
+
+}
+#else
+int __init omap_init_drm(void) { return 0; }
+#endif
diff --git a/arch/arm/mach-omap2/dss-common.c b/arch/arm/mach-omap2/dss-common.c
new file mode 100644
index 000000000..ea2be0f59
--- /dev/null
+++ b/arch/arm/mach-omap2/dss-common.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 Texas Instruments, Inc..
+ * Author: Tomi Valkeinen <tomi.valkeinen@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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/*
+ * NOTE: this is a transitional file to help with DT adaptation.
+ * This file will be removed when DSS supports DT.
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+
+#include <video/omapdss.h>
+#include <video/omap-panel-data.h>
+
+#include "soc.h"
+#include "dss-common.h"
+#include "mux.h"
+#include "display.h"
+
diff --git a/arch/arm/mach-omap2/dss-common.h b/arch/arm/mach-omap2/dss-common.h
new file mode 100644
index 000000000..a9becf0d5
--- /dev/null
+++ b/arch/arm/mach-omap2/dss-common.h
@@ -0,0 +1,13 @@
+#ifndef __OMAP_DSS_COMMON__
+#define __OMAP_DSS_COMMON__
+
+/*
+ * NOTE: this is a transitional file to help with DT adaptation.
+ * This file will be removed when DSS supports DT.
+ */
+
+void __init omap4_panda_display_init_of(void);
+void __init omap_4430sdp_display_init_of(void);
+void __init omap3_igep2_display_init_of(void);
+
+#endif
diff --git a/arch/arm/mach-omap2/fb.c b/arch/arm/mach-omap2/fb.c
new file mode 100644
index 000000000..26e28e94f
--- /dev/null
+++ b/arch/arm/mach-omap2/fb.c
@@ -0,0 +1,115 @@
+/*
+ * 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 <linux/dma-mapping.h>
+
+#include <asm/mach/map.h>
+
+#include "soc.h"
+#include "display.h"
+
+#ifdef CONFIG_OMAP2_VRFB
+
+/*
+ * The first memory resource is the register region for VRFB,
+ * the rest are VRFB virtual memory areas for each VRFB context.
+ */
+
+static const struct resource omap2_vrfb_resources[] = {
+ DEFINE_RES_MEM_NAMED(0x68008000u, 0x40, "vrfb-regs"),
+ DEFINE_RES_MEM_NAMED(0x70000000u, 0x4000000, "vrfb-area-0"),
+ DEFINE_RES_MEM_NAMED(0x74000000u, 0x4000000, "vrfb-area-1"),
+ DEFINE_RES_MEM_NAMED(0x78000000u, 0x4000000, "vrfb-area-2"),
+ DEFINE_RES_MEM_NAMED(0x7c000000u, 0x4000000, "vrfb-area-3"),
+};
+
+static const struct resource omap3_vrfb_resources[] = {
+ DEFINE_RES_MEM_NAMED(0x6C000180u, 0xc0, "vrfb-regs"),
+ DEFINE_RES_MEM_NAMED(0x70000000u, 0x4000000, "vrfb-area-0"),
+ DEFINE_RES_MEM_NAMED(0x74000000u, 0x4000000, "vrfb-area-1"),
+ DEFINE_RES_MEM_NAMED(0x78000000u, 0x4000000, "vrfb-area-2"),
+ DEFINE_RES_MEM_NAMED(0x7c000000u, 0x4000000, "vrfb-area-3"),
+ DEFINE_RES_MEM_NAMED(0xe0000000u, 0x4000000, "vrfb-area-4"),
+ DEFINE_RES_MEM_NAMED(0xe4000000u, 0x4000000, "vrfb-area-5"),
+ DEFINE_RES_MEM_NAMED(0xe8000000u, 0x4000000, "vrfb-area-6"),
+ DEFINE_RES_MEM_NAMED(0xec000000u, 0x4000000, "vrfb-area-7"),
+ DEFINE_RES_MEM_NAMED(0xf0000000u, 0x4000000, "vrfb-area-8"),
+ DEFINE_RES_MEM_NAMED(0xf4000000u, 0x4000000, "vrfb-area-9"),
+ DEFINE_RES_MEM_NAMED(0xf8000000u, 0x4000000, "vrfb-area-10"),
+ DEFINE_RES_MEM_NAMED(0xfc000000u, 0x4000000, "vrfb-area-11"),
+};
+
+int __init omap_init_vrfb(void)
+{
+ struct platform_device *pdev;
+ const struct resource *res;
+ unsigned int num_res;
+
+ if (cpu_is_omap24xx()) {
+ res = omap2_vrfb_resources;
+ num_res = ARRAY_SIZE(omap2_vrfb_resources);
+ } else if (cpu_is_omap34xx()) {
+ res = omap3_vrfb_resources;
+ num_res = ARRAY_SIZE(omap3_vrfb_resources);
+ } else {
+ return 0;
+ }
+
+ pdev = platform_device_register_resndata(NULL, "omapvrfb", -1,
+ res, num_res, NULL, 0);
+
+ return PTR_RET(pdev);
+}
+#else
+int __init omap_init_vrfb(void) { return 0; }
+#endif
+
+#if 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 = DMA_BIT_MASK(32),
+ .platform_data = &omapfb_config,
+ },
+ .num_resources = 0,
+};
+
+int __init omap_init_fb(void)
+{
+ return platform_device_register(&omap_fb_device);
+}
+#else
+int __init omap_init_fb(void) { return 0; }
+#endif
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
new file mode 100644
index 000000000..7a577145b
--- /dev/null
+++ b/arch/arm/mach-omap2/gpio.c
@@ -0,0 +1,160 @@
+/*
+ * 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 <linux/of.h>
+#include <linux/platform_data/gpio-omap.h>
+
+#include "soc.h"
+#include "omap_hwmod.h"
+#include "omap_device.h"
+#include "omap-pm.h"
+
+#include "powerdomain.h"
+
+static int __init omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
+{
+ struct platform_device *pdev;
+ struct omap_gpio_platform_data *pdata;
+ struct omap_gpio_dev_attr *dev_attr;
+ char *name = "omap_gpio";
+ int id;
+ struct powerdomain *pwrdm;
+
+ /*
+ * 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->get_context_loss_count = omap_pm_get_dev_context_loss_count;
+ pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL);
+ if (!pdata->regs) {
+ pr_err("gpio%d: Memory allocation failed\n", id);
+ kfree(pdata);
+ return -ENOMEM;
+ }
+
+ switch (oh->class->rev) {
+ case 0:
+ if (id == 1)
+ /* non-wakeup GPIO pins for OMAP2 Bank1 */
+ pdata->non_wakeup_gpios = 0xe203ffc0;
+ else if (id == 2)
+ /* non-wakeup GPIO pins for OMAP2 Bank2 */
+ pdata->non_wakeup_gpios = 0x08700040;
+ /* fall through */
+
+ case 1:
+ pdata->regs->revision = OMAP24XX_GPIO_REVISION;
+ pdata->regs->direction = OMAP24XX_GPIO_OE;
+ pdata->regs->datain = OMAP24XX_GPIO_DATAIN;
+ pdata->regs->dataout = OMAP24XX_GPIO_DATAOUT;
+ pdata->regs->set_dataout = OMAP24XX_GPIO_SETDATAOUT;
+ pdata->regs->clr_dataout = OMAP24XX_GPIO_CLEARDATAOUT;
+ pdata->regs->irqstatus = OMAP24XX_GPIO_IRQSTATUS1;
+ pdata->regs->irqstatus2 = OMAP24XX_GPIO_IRQSTATUS2;
+ pdata->regs->irqenable = OMAP24XX_GPIO_IRQENABLE1;
+ pdata->regs->irqenable2 = OMAP24XX_GPIO_IRQENABLE2;
+ pdata->regs->set_irqenable = OMAP24XX_GPIO_SETIRQENABLE1;
+ pdata->regs->clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1;
+ pdata->regs->debounce = OMAP24XX_GPIO_DEBOUNCE_VAL;
+ pdata->regs->debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN;
+ pdata->regs->ctrl = OMAP24XX_GPIO_CTRL;
+ pdata->regs->wkup_en = OMAP24XX_GPIO_WAKE_EN;
+ pdata->regs->leveldetect0 = OMAP24XX_GPIO_LEVELDETECT0;
+ pdata->regs->leveldetect1 = OMAP24XX_GPIO_LEVELDETECT1;
+ pdata->regs->risingdetect = OMAP24XX_GPIO_RISINGDETECT;
+ pdata->regs->fallingdetect = OMAP24XX_GPIO_FALLINGDETECT;
+ break;
+ case 2:
+ pdata->regs->revision = OMAP4_GPIO_REVISION;
+ pdata->regs->direction = OMAP4_GPIO_OE;
+ pdata->regs->datain = OMAP4_GPIO_DATAIN;
+ pdata->regs->dataout = OMAP4_GPIO_DATAOUT;
+ pdata->regs->set_dataout = OMAP4_GPIO_SETDATAOUT;
+ pdata->regs->clr_dataout = OMAP4_GPIO_CLEARDATAOUT;
+ pdata->regs->irqstatus_raw0 = OMAP4_GPIO_IRQSTATUSRAW0;
+ pdata->regs->irqstatus_raw1 = OMAP4_GPIO_IRQSTATUSRAW1;
+ pdata->regs->irqstatus = OMAP4_GPIO_IRQSTATUS0;
+ pdata->regs->irqstatus2 = OMAP4_GPIO_IRQSTATUS1;
+ pdata->regs->irqenable = OMAP4_GPIO_IRQSTATUSSET0;
+ pdata->regs->irqenable2 = OMAP4_GPIO_IRQSTATUSSET1;
+ pdata->regs->set_irqenable = OMAP4_GPIO_IRQSTATUSSET0;
+ pdata->regs->clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0;
+ pdata->regs->debounce = OMAP4_GPIO_DEBOUNCINGTIME;
+ pdata->regs->debounce_en = OMAP4_GPIO_DEBOUNCENABLE;
+ pdata->regs->ctrl = OMAP4_GPIO_CTRL;
+ pdata->regs->wkup_en = OMAP4_GPIO_IRQWAKEN0;
+ pdata->regs->leveldetect0 = OMAP4_GPIO_LEVELDETECT0;
+ pdata->regs->leveldetect1 = OMAP4_GPIO_LEVELDETECT1;
+ pdata->regs->risingdetect = OMAP4_GPIO_RISINGDETECT;
+ pdata->regs->fallingdetect = OMAP4_GPIO_FALLINGDETECT;
+ break;
+ default:
+ WARN(1, "Invalid gpio bank_type\n");
+ kfree(pdata->regs);
+ kfree(pdata);
+ return -EINVAL;
+ }
+
+ pwrdm = omap_hwmod_get_pwrdm(oh);
+ pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm);
+
+ pdev = omap_device_build(name, id - 1, oh, pdata, sizeof(*pdata));
+ kfree(pdata);
+
+ if (IS_ERR(pdev)) {
+ WARN(1, "Can't build omap_device for %s:%s.\n",
+ name, oh->name);
+ return PTR_ERR(pdev);
+ }
+
+ return 0;
+}
+
+/*
+ * gpio_init needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence gpio_init is a omap_postcore_initcall.
+ */
+static int __init omap2_gpio_init(void)
+{
+ /* If dtb is there, the devices will be created dynamically */
+ if (of_have_populated_dt())
+ return -ENODEV;
+
+ return omap_hwmod_for_each_by_class("gpio", omap2_gpio_dev_init, NULL);
+}
+omap_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 000000000..72918c497
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -0,0 +1,159 @@
+/*
+ * 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/omap-gpmc.h>
+#include <linux/mtd/nand.h>
+#include <linux/platform_data/mtd-nand-omap2.h>
+
+#include <asm/mach/flash.h>
+
+#include "soc.h"
+
+/* minimum size for IO mapping */
+#define NAND_IO_SIZE 4
+
+static bool gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
+{
+ /* platforms which support all ECC schemes */
+ if (soc_is_am33xx() || soc_is_am43xx() || cpu_is_omap44xx() ||
+ soc_is_omap54xx() || soc_is_dra7xx())
+ return 1;
+
+ if (ecc_opt == OMAP_ECC_BCH4_CODE_HW_DETECTION_SW ||
+ ecc_opt == OMAP_ECC_BCH8_CODE_HW_DETECTION_SW) {
+ if (cpu_is_omap24xx())
+ return 0;
+ else if (cpu_is_omap3630() && (GET_OMAP_REVISION() == 0))
+ return 0;
+ else
+ return 1;
+ }
+
+ /* OMAP3xxx do not have ELM engine, so cannot support ECC schemes
+ * which require H/W based ECC error detection */
+ if ((cpu_is_omap34xx() || cpu_is_omap3630()) &&
+ ((ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
+ (ecc_opt == OMAP_ECC_BCH8_CODE_HW)))
+ return 0;
+
+ /* legacy platforms support only HAM1 (1-bit Hamming) ECC scheme */
+ if (ecc_opt == OMAP_ECC_HAM1_CODE_HW ||
+ ecc_opt == OMAP_ECC_HAM1_CODE_SW)
+ return 1;
+ else
+ return 0;
+}
+
+/* This function will go away once the device-tree convertion is complete */
+static void gpmc_set_legacy(struct omap_nand_platform_data *gpmc_nand_data,
+ struct gpmc_settings *s)
+{
+ /* Enable RD PIN Monitoring Reg */
+ if (gpmc_nand_data->dev_ready) {
+ s->wait_on_read = true;
+ s->wait_on_write = true;
+ }
+
+ if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
+ s->device_width = GPMC_DEVWIDTH_16BIT;
+ else
+ s->device_width = GPMC_DEVWIDTH_8BIT;
+}
+
+int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
+ struct gpmc_timings *gpmc_t)
+{
+ int err = 0;
+ struct gpmc_settings s;
+ struct platform_device *pdev;
+ struct resource gpmc_nand_res[] = {
+ { .flags = IORESOURCE_MEM, },
+ { .flags = IORESOURCE_IRQ, },
+ { .flags = IORESOURCE_IRQ, },
+ };
+
+ BUG_ON(gpmc_nand_data->cs >= GPMC_CS_NUM);
+
+ err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE,
+ (unsigned long *)&gpmc_nand_res[0].start);
+ if (err < 0) {
+ pr_err("omap2-gpmc: Cannot request GPMC CS %d, error %d\n",
+ gpmc_nand_data->cs, err);
+ return err;
+ }
+ gpmc_nand_res[0].end = gpmc_nand_res[0].start + NAND_IO_SIZE - 1;
+ gpmc_nand_res[1].start = gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE);
+ gpmc_nand_res[2].start = gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
+
+ memset(&s, 0, sizeof(struct gpmc_settings));
+ if (gpmc_nand_data->of_node)
+ gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
+ else
+ gpmc_set_legacy(gpmc_nand_data, &s);
+
+ s.device_nand = true;
+
+ if (gpmc_t) {
+ err = gpmc_cs_set_timings(gpmc_nand_data->cs, gpmc_t, &s);
+ if (err < 0) {
+ pr_err("omap2-gpmc: Unable to set gpmc timings: %d\n",
+ err);
+ return err;
+ }
+ }
+
+ err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s);
+ if (err < 0)
+ goto out_free_cs;
+
+ err = gpmc_configure(GPMC_CONFIG_WP, 0);
+ if (err < 0)
+ goto out_free_cs;
+
+ gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs);
+
+ if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt)) {
+ pr_err("omap2-nand: Unsupported NAND ECC scheme selected\n");
+ err = -EINVAL;
+ goto out_free_cs;
+ }
+
+
+ pdev = platform_device_alloc("omap2-nand", gpmc_nand_data->cs);
+ if (pdev) {
+ err = platform_device_add_resources(pdev, gpmc_nand_res,
+ ARRAY_SIZE(gpmc_nand_res));
+ if (!err)
+ pdev->dev.platform_data = gpmc_nand_data;
+ } else {
+ err = -ENOMEM;
+ }
+ if (err)
+ goto out_free_pdev;
+
+ err = platform_device_add(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "Unable to register NAND device\n");
+ goto out_free_pdev;
+ }
+
+ return 0;
+
+out_free_pdev:
+ platform_device_put(pdev);
+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 000000000..f899e77ff
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -0,0 +1,403 @@
+/*
+ * 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/string.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/onenand_regs.h>
+#include <linux/io.h>
+#include <linux/omap-gpmc.h>
+#include <linux/platform_data/mtd-onenand-omap2.h>
+#include <linux/err.h>
+
+#include <asm/mach/flash.h>
+
+#include "soc.h"
+
+#define ONENAND_IO_SIZE SZ_128K
+
+#define ONENAND_FLAG_SYNCREAD (1 << 0)
+#define ONENAND_FLAG_SYNCWRITE (1 << 1)
+#define ONENAND_FLAG_HF (1 << 2)
+#define ONENAND_FLAG_VHF (1 << 3)
+
+static unsigned onenand_flags;
+static unsigned latency;
+
+static struct omap_onenand_platform_data *gpmc_onenand_data;
+
+static struct resource gpmc_onenand_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device gpmc_onenand_device = {
+ .name = "omap2-onenand",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &gpmc_onenand_resource,
+};
+
+static struct gpmc_settings onenand_async = {
+ .device_width = GPMC_DEVWIDTH_16BIT,
+ .mux_add_data = GPMC_MUX_AD,
+};
+
+static struct gpmc_settings onenand_sync = {
+ .burst_read = true,
+ .burst_wrap = true,
+ .burst_len = GPMC_BURST_16,
+ .device_width = GPMC_DEVWIDTH_16BIT,
+ .mux_add_data = GPMC_MUX_AD,
+ .wait_pin = 0,
+};
+
+static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
+{
+ struct gpmc_device_timings dev_t;
+ 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_wpl = 40;
+ const int t_wph = 30;
+
+ memset(&dev_t, 0, sizeof(dev_t));
+
+ dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000;
+ dev_t.t_avdp_w = dev_t.t_avdp_r;
+ dev_t.t_aavdh = t_aavdh * 1000;
+ dev_t.t_aa = t_aa * 1000;
+ dev_t.t_ce = t_ce * 1000;
+ dev_t.t_oe = t_oe * 1000;
+ dev_t.t_cez_r = t_cez * 1000;
+ dev_t.t_cez_w = dev_t.t_cez_r;
+ dev_t.t_wpl = t_wpl * 1000;
+ dev_t.t_wph = t_wph * 1000;
+
+ gpmc_calc_timings(t, &onenand_async, &dev_t);
+}
+
+static void omap2_onenand_set_async_mode(void __iomem *onenand_base)
+{
+ u32 reg;
+
+ /* 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);
+}
+
+static void set_onenand_cfg(void __iomem *onenand_base)
+{
+ 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 (onenand_flags & ONENAND_FLAG_SYNCREAD)
+ reg |= ONENAND_SYS_CFG1_SYNC_READ;
+ else
+ reg &= ~ONENAND_SYS_CFG1_SYNC_READ;
+ if (onenand_flags & ONENAND_FLAG_SYNCWRITE)
+ reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
+ else
+ reg &= ~ONENAND_SYS_CFG1_SYNC_WRITE;
+ if (onenand_flags & ONENAND_FLAG_HF)
+ reg |= ONENAND_SYS_CFG1_HF;
+ else
+ reg &= ~ONENAND_SYS_CFG1_HF;
+ if (onenand_flags & ONENAND_FLAG_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)
+{
+ u16 ver = readw(onenand_base + ONENAND_REG_VERSION_ID);
+ int 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 void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
+ unsigned int flags,
+ int freq)
+{
+ struct gpmc_device_timings dev_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_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 div, gpmc_clk_ns;
+
+ if (flags & ONENAND_SYNC_READ)
+ onenand_flags = ONENAND_FLAG_SYNCREAD;
+ else if (flags & ONENAND_SYNC_READWRITE)
+ onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE;
+
+ 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;
+ onenand_flags &= ~ONENAND_FLAG_SYNCWRITE;
+ break;
+ }
+
+ div = gpmc_calc_divider(min_gpmc_clk_period);
+ gpmc_clk_ns = gpmc_ticks_to_ns(div);
+ if (gpmc_clk_ns < 15) /* >66Mhz */
+ onenand_flags |= ONENAND_FLAG_HF;
+ else
+ onenand_flags &= ~ONENAND_FLAG_HF;
+ if (gpmc_clk_ns < 12) /* >83Mhz */
+ onenand_flags |= ONENAND_FLAG_VHF;
+ else
+ onenand_flags &= ~ONENAND_FLAG_VHF;
+ if (onenand_flags & ONENAND_FLAG_VHF)
+ latency = 8;
+ else if (onenand_flags & ONENAND_FLAG_HF)
+ latency = 6;
+ else if (gpmc_clk_ns >= 25) /* 40 MHz*/
+ latency = 3;
+ else
+ latency = 4;
+
+ /* Set synchronous read timings */
+ memset(&dev_t, 0, sizeof(dev_t));
+
+ if (onenand_flags & ONENAND_FLAG_SYNCREAD)
+ onenand_sync.sync_read = true;
+ if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
+ onenand_sync.sync_write = true;
+ onenand_sync.burst_write = true;
+ } else {
+ dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
+ dev_t.t_wpl = t_wpl * 1000;
+ dev_t.t_wph = t_wph * 1000;
+ dev_t.t_aavdh = t_aavdh * 1000;
+ }
+ dev_t.ce_xdelay = true;
+ dev_t.avd_xdelay = true;
+ dev_t.oe_xdelay = true;
+ dev_t.we_xdelay = true;
+ dev_t.clk = min_gpmc_clk_period;
+ dev_t.t_bacc = dev_t.clk;
+ dev_t.t_ces = t_ces * 1000;
+ dev_t.t_avds = t_avds * 1000;
+ dev_t.t_avdh = t_avdh * 1000;
+ dev_t.t_ach = t_ach * 1000;
+ dev_t.cyc_iaa = (latency + 1);
+ dev_t.t_cez_r = t_cez * 1000;
+ dev_t.t_cez_w = dev_t.t_cez_r;
+ dev_t.cyc_aavdh_oe = 1;
+ dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
+
+ gpmc_calc_timings(t, &onenand_sync, &dev_t);
+}
+
+static int omap2_onenand_setup_async(void __iomem *onenand_base)
+{
+ struct gpmc_timings t;
+ int ret;
+
+ if (gpmc_onenand_data->of_node) {
+ gpmc_read_settings_dt(gpmc_onenand_data->of_node,
+ &onenand_async);
+ if (onenand_async.sync_read || onenand_async.sync_write) {
+ if (onenand_async.sync_write)
+ gpmc_onenand_data->flags |=
+ ONENAND_SYNC_READWRITE;
+ else
+ gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
+ onenand_async.sync_read = false;
+ onenand_async.sync_write = false;
+ }
+ }
+
+ omap2_onenand_set_async_mode(onenand_base);
+
+ omap2_onenand_calc_async_timings(&t);
+
+ ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_async);
+ if (ret < 0)
+ return ret;
+
+ ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t, &onenand_async);
+ if (ret < 0)
+ return ret;
+
+ omap2_onenand_set_async_mode(onenand_base);
+
+ return 0;
+}
+
+static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
+{
+ int ret, freq = *freq_ptr;
+ struct gpmc_timings t;
+
+ if (!freq) {
+ /* Very first call freq is not known */
+ freq = omap2_onenand_get_freq(gpmc_onenand_data, onenand_base);
+ set_onenand_cfg(onenand_base);
+ }
+
+ if (gpmc_onenand_data->of_node) {
+ gpmc_read_settings_dt(gpmc_onenand_data->of_node,
+ &onenand_sync);
+ } else {
+ /*
+ * FIXME: Appears to be legacy code from initial ONENAND commit.
+ * Unclear what boards this is for and if this can be removed.
+ */
+ if (!cpu_is_omap34xx())
+ onenand_sync.wait_on_read = true;
+ }
+
+ omap2_onenand_calc_sync_timings(&t, gpmc_onenand_data->flags, freq);
+
+ ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_sync);
+ if (ret < 0)
+ return ret;
+
+ ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t, &onenand_sync);
+ if (ret < 0)
+ return ret;
+
+ set_onenand_cfg(onenand_base);
+
+ *freq_ptr = freq;
+
+ return 0;
+}
+
+static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)
+{
+ struct device *dev = &gpmc_onenand_device.dev;
+ unsigned l = ONENAND_SYNC_READ | ONENAND_SYNC_READWRITE;
+ int ret;
+
+ ret = omap2_onenand_setup_async(onenand_base);
+ if (ret) {
+ dev_err(dev, "unable to set to async mode\n");
+ return ret;
+ }
+
+ if (!(gpmc_onenand_data->flags & l))
+ return 0;
+
+ ret = omap2_onenand_setup_sync(onenand_base, freq_ptr);
+ if (ret)
+ dev_err(dev, "unable to set to sync mode\n");
+ return ret;
+}
+
+void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
+{
+ int err;
+ struct device *dev = &gpmc_onenand_device.dev;
+
+ 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)) {
+ dev_warn(dev, "OneNAND using only SYNC_READ on 24xx\n");
+ gpmc_onenand_data->flags &= ~ONENAND_SYNC_READWRITE;
+ gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
+ }
+
+ if (cpu_is_omap34xx())
+ gpmc_onenand_data->flags |= ONENAND_IN_OMAP34XX;
+ else
+ gpmc_onenand_data->flags &= ~ONENAND_IN_OMAP34XX;
+
+ err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE,
+ (unsigned long *)&gpmc_onenand_resource.start);
+ if (err < 0) {
+ dev_err(dev, "Cannot request GPMC CS %d, error %d\n",
+ gpmc_onenand_data->cs, err);
+ return;
+ }
+
+ gpmc_onenand_resource.end = gpmc_onenand_resource.start +
+ ONENAND_IO_SIZE - 1;
+
+ if (platform_device_register(&gpmc_onenand_device) < 0) {
+ dev_err(dev, "Unable to register OneNAND device\n");
+ gpmc_cs_free(gpmc_onenand_data->cs);
+ return;
+ }
+}
diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c b/arch/arm/mach-omap2/gpmc-smsc911x.c
new file mode 100644
index 000000000..2757504a1
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc-smsc911x.c
@@ -0,0 +1,100 @@
+/*
+ * 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 "gpmc.h"
+#include "gpmc-smsc911x.h"
+
+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,
+};
+
+/*
+ * 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 *gpmc_cfg)
+{
+ struct platform_device *pdev;
+ unsigned long cs_mem_base;
+ int ret;
+
+ 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);
+ }
+
+ gpmc_smsc911x_config.flags = gpmc_cfg->flags ? : SMSC911X_USE_16BIT;
+
+ 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 (IS_ERR(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-smsc911x.h b/arch/arm/mach-omap2/gpmc-smsc911x.h
new file mode 100644
index 000000000..ea6c9c88c
--- /dev/null
+++ b/arch/arm/mach-omap2/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/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
new file mode 100644
index 000000000..9caa41a6c
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -0,0 +1,14 @@
+/*
+ * 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.
+ *
+ * Do not include this file in any new code, this will get removed
+ * once omap3 boots in device tree only mode.
+ *
+ */
+#include <linux/omap-gpmc.h>
diff --git a/arch/arm/mach-omap2/hdq1w.c b/arch/arm/mach-omap2/hdq1w.c
new file mode 100644
index 000000000..f3897d82e
--- /dev/null
+++ b/arch/arm/mach-omap2/hdq1w.c
@@ -0,0 +1,99 @@
+/*
+ * IP block integration code for the HDQ1W/1-wire IP block
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * Paul Walmsley
+ *
+ * Based on the I2C reset code in arch/arm/mach-omap2/i2c.c by
+ * Avinash.H.M <avinashhm@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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+#include "soc.h"
+#include "omap_hwmod.h"
+#include "omap_device.h"
+#include "hdq1w.h"
+
+#include "prm.h"
+#include "common.h"
+
+/**
+ * omap_hdq1w_reset - reset the OMAP HDQ1W module
+ * @oh: struct omap_hwmod *
+ *
+ * OCP soft reset the HDQ1W IP block. Section 20.6.1.4 "HDQ1W/1-Wire
+ * Software Reset" of the OMAP34xx Technical Reference Manual Revision
+ * ZR (SWPU223R) does not include the rather important fact that, for
+ * the reset to succeed, the HDQ1W module's internal clock gate must be
+ * programmed to allow the clock to propagate to the rest of the
+ * module. In this sense, it's rather similar to the I2C custom reset
+ * function. Returns 0.
+ */
+int omap_hdq1w_reset(struct omap_hwmod *oh)
+{
+ u32 v;
+ int c = 0;
+
+ /* Write to the SOFTRESET bit */
+ omap_hwmod_softreset(oh);
+
+ /* Enable the module's internal clocks */
+ v = omap_hwmod_read(oh, HDQ_CTRL_STATUS_OFFSET);
+ v |= 1 << HDQ_CTRL_STATUS_CLOCKENABLE_SHIFT;
+ omap_hwmod_write(v, oh, HDQ_CTRL_STATUS_OFFSET);
+
+ /* Poll on RESETDONE bit */
+ omap_test_timeout((omap_hwmod_read(oh,
+ oh->class->sysc->syss_offs)
+ & SYSS_RESETDONE_MASK),
+ MAX_MODULE_SOFTRESET_WAIT, c);
+
+ if (c == MAX_MODULE_SOFTRESET_WAIT)
+ pr_warn("%s: %s: softreset failed (waited %d usec)\n",
+ __func__, oh->name, MAX_MODULE_SOFTRESET_WAIT);
+ else
+ pr_debug("%s: %s: softreset in %d usec\n", __func__,
+ oh->name, c);
+
+ return 0;
+}
+
+#ifndef CONFIG_OF
+static int __init omap_init_hdq(void)
+{
+ int id = -1;
+ struct platform_device *pdev;
+ struct omap_hwmod *oh;
+ char *oh_name = "hdq1w";
+ char *devname = "omap_hdq";
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh)
+ return 0;
+
+ pdev = omap_device_build(devname, id, oh, NULL, 0);
+ WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",
+ devname, oh->name);
+
+ return 0;
+}
+omap_arch_initcall(omap_init_hdq);
+#endif
diff --git a/arch/arm/mach-omap2/hdq1w.h b/arch/arm/mach-omap2/hdq1w.h
new file mode 100644
index 000000000..c7e08d2a7
--- /dev/null
+++ b/arch/arm/mach-omap2/hdq1w.h
@@ -0,0 +1,36 @@
+/*
+ * Shared macros and function prototypes for the HDQ1W/1-wire IP block
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * 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 in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have 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 ARCH_ARM_MACH_OMAP2_HDQ1W_H
+#define ARCH_ARM_MACH_OMAP2_HDQ1W_H
+
+#include "omap_hwmod.h"
+
+/*
+ * XXX A future cleanup patch should modify
+ * drivers/w1/masters/omap_hdq.c to use these macros
+ */
+#define HDQ_CTRL_STATUS_OFFSET 0x0c
+#define HDQ_CTRL_STATUS_CLOCKENABLE_SHIFT 5
+
+
+extern int omap_hdq1w_reset(struct omap_hwmod *oh);
+
+#endif
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
new file mode 100644
index 000000000..9a8611ab5
--- /dev/null
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -0,0 +1,505 @@
+/*
+ * 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 <linux/gpio.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_data/gpio-omap.h>
+#include <linux/platform_data/hsmmc-omap.h>
+
+#include "soc.h"
+#include "omap_device.h"
+#include "omap-pm.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;
+
+#define HSMMC_NAME_LEN 9
+
+static void omap_hsmmc1_before_set_reg(struct device *dev,
+ int power_on, int vdd)
+{
+ u32 reg, prog_io;
+ struct omap_hsmmc_platform_data *mmc = dev->platform_data;
+
+ if (mmc->remux)
+ mmc->remux(dev, 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->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 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 hsmmc2_select_input_clk_src(struct omap_hsmmc_platform_data *mmc)
+{
+ u32 reg;
+
+ reg = omap_ctrl_readl(control_devconf1_offset);
+ if (mmc->internal_clock)
+ reg |= OMAP2_MMCSDIO2ADPCLKISEL;
+ else
+ reg &= ~OMAP2_MMCSDIO2ADPCLKISEL;
+ omap_ctrl_writel(reg, control_devconf1_offset);
+}
+
+static void hsmmc2_before_set_reg(struct device *dev, int power_on, int vdd)
+{
+ struct omap_hsmmc_platform_data *mmc = dev->platform_data;
+
+ if (mmc->remux)
+ mmc->remux(dev, power_on);
+
+ if (power_on)
+ hsmmc2_select_input_clk_src(mmc);
+}
+
+static int am35x_hsmmc2_set_power(struct device *dev, int power_on, int vdd)
+{
+ struct omap_hsmmc_platform_data *mmc = dev->platform_data;
+
+ if (power_on)
+ hsmmc2_select_input_clk_src(mmc);
+
+ return 0;
+}
+
+static int nop_mmc_set_power(struct device *dev, int power_on, int vdd)
+{
+ return 0;
+}
+
+static inline void omap_hsmmc_mux(struct omap_hsmmc_platform_data
+ *mmc_controller, int controller_nr)
+{
+ if (gpio_is_valid(mmc_controller->gpio_cd) &&
+ (mmc_controller->gpio_cd < OMAP_MAX_GPIO_LINES))
+ omap_mux_init_gpio(mmc_controller->gpio_cd,
+ OMAP_PIN_INPUT_PULLUP);
+ if (gpio_is_valid(mmc_controller->gpio_cod) &&
+ (mmc_controller->gpio_cod < OMAP_MAX_GPIO_LINES))
+ omap_mux_init_gpio(mmc_controller->gpio_cod,
+ OMAP_PIN_INPUT_PULLUP);
+ if (gpio_is_valid(mmc_controller->gpio_wp) &&
+ (mmc_controller->gpio_wp < OMAP_MAX_GPIO_LINES))
+ omap_mux_init_gpio(mmc_controller->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->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->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->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->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_hsmmc_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->name = hc_name;
+ mmc->caps = c->caps;
+ mmc->internal_clock = !c->ext_clock;
+ mmc->reg_offset = 0;
+
+ if (c->cover_only) {
+ /* detect if mobile phone cover removed */
+ mmc->gpio_cd = -EINVAL;
+ mmc->gpio_cod = c->gpio_cd;
+ } else {
+ /* card detect pin on the mmc socket itself */
+ mmc->gpio_cd = c->gpio_cd;
+ mmc->gpio_cod = -EINVAL;
+ }
+ mmc->gpio_wp = c->gpio_wp;
+
+ mmc->remux = c->remux;
+ mmc->init_card = c->init_card;
+
+ if (c->nonremovable)
+ mmc->nonremovable = 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
+ */
+ if (soc_is_am35xx())
+ mmc->ocr_mask = MMC_VDD_165_195 |
+ MMC_VDD_26_27 |
+ MMC_VDD_27_28 |
+ MMC_VDD_29_30 |
+ MMC_VDD_30_31 |
+ MMC_VDD_31_32;
+ else
+ mmc->ocr_mask = c->ocr_mask;
+
+ if (!soc_is_am35xx())
+ mmc->features |= HSMMC_HAS_PBIAS;
+
+ switch (c->mmc) {
+ case 1:
+ if (mmc->features & HSMMC_HAS_PBIAS) {
+ /* on-chip level shifting via PBIAS0/PBIAS1 */
+ mmc->before_set_reg =
+ omap_hsmmc1_before_set_reg;
+ mmc->after_set_reg =
+ omap_hsmmc1_after_set_reg;
+ }
+
+ if (soc_is_am35xx())
+ mmc->set_power = nop_mmc_set_power;
+
+ /* 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->caps = c->caps;
+ }
+ break;
+ case 2:
+ if (soc_is_am35xx())
+ mmc->set_power = am35x_hsmmc2_set_power;
+
+ 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;
+ }
+ if (mmc->features & HSMMC_HAS_PBIAS) {
+ /* off-chip level shifting, or none */
+ mmc->before_set_reg = hsmmc2_before_set_reg;
+ mmc->after_set_reg = NULL;
+ }
+ break;
+ case 3:
+ case 4:
+ case 5:
+ mmc->before_set_reg = NULL;
+ mmc->after_set_reg = NULL;
+ break;
+ default:
+ pr_err("MMC%d configuration not supported!\n", c->mmc);
+ kfree(hc_name);
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static int omap_hsmmc_done;
+
+void omap_hsmmc_late_init(struct omap2_hsmmc_info *c)
+{
+ struct platform_device *pdev;
+ struct omap_hsmmc_platform_data *mmc_pdata;
+ int res;
+
+ if (omap_hsmmc_done != 1)
+ return;
+
+ omap_hsmmc_done++;
+
+ for (; c->mmc; c++) {
+ if (!c->deferred)
+ continue;
+
+ pdev = c->pdev;
+ if (!pdev)
+ continue;
+
+ mmc_pdata = pdev->dev.platform_data;
+ if (!mmc_pdata)
+ continue;
+
+ if (c->cover_only) {
+ /* detect if mobile phone cover removed */
+ mmc_pdata->gpio_cd = -EINVAL;
+ mmc_pdata->gpio_cod = c->gpio_cd;
+ } else {
+ /* card detect pin on the mmc socket itself */
+ mmc_pdata->gpio_cd = c->gpio_cd;
+ mmc_pdata->gpio_cod = -EINVAL;
+ }
+ mmc_pdata->gpio_wp = c->gpio_wp;
+
+ res = omap_device_register(pdev);
+ if (res)
+ pr_err("Could not late init MMC %s\n",
+ c->name);
+ }
+}
+
+#define MAX_OMAP_MMC_HWMOD_NAME_LEN 16
+
+static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
+ int ctrl_nr)
+{
+ struct omap_hwmod *oh;
+ struct omap_hwmod *ohs[1];
+ struct omap_device *od;
+ struct platform_device *pdev;
+ char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN];
+ struct omap_hsmmc_platform_data *mmc_data;
+ struct omap_hsmmc_dev_attr *mmc_dev_attr;
+ char *name;
+ int res;
+
+ mmc_data = kzalloc(sizeof(*mmc_data), GFP_KERNEL);
+ if (!mmc_data) {
+ pr_err("Cannot allocate memory for mmc device!\n");
+ return;
+ }
+
+ res = omap_hsmmc_pdata_init(hsmmcinfo, mmc_data);
+ if (res < 0)
+ goto free_mmc;
+
+ omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
+
+ name = "omap_hsmmc";
+ res = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
+ "mmc%d", ctrl_nr);
+ WARN(res >= 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);
+ goto free_name;
+ }
+ ohs[0] = oh;
+ if (oh->dev_attr != NULL) {
+ mmc_dev_attr = oh->dev_attr;
+ mmc_data->controller_flags = mmc_dev_attr->flags;
+ /*
+ * erratum 2.1.1.128 doesn't apply if board has
+ * a transceiver is attached
+ */
+ if (hsmmcinfo->transceiver)
+ mmc_data->controller_flags &=
+ ~OMAP_HSMMC_BROKEN_MULTIBLOCK_READ;
+ }
+
+ pdev = platform_device_alloc(name, ctrl_nr - 1);
+ if (!pdev) {
+ pr_err("Could not allocate pdev for %s\n", name);
+ goto free_name;
+ }
+ dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
+
+ od = omap_device_alloc(pdev, ohs, 1);
+ if (IS_ERR(od)) {
+ pr_err("Could not allocate od for %s\n", name);
+ goto put_pdev;
+ }
+
+ res = platform_device_add_data(pdev, mmc_data,
+ sizeof(struct omap_hsmmc_platform_data));
+ if (res) {
+ pr_err("Could not add pdata for %s\n", name);
+ goto put_pdev;
+ }
+
+ hsmmcinfo->pdev = pdev;
+
+ if (hsmmcinfo->deferred)
+ goto free_mmc;
+
+ res = omap_device_register(pdev);
+ if (res) {
+ pr_err("Could not register od for %s\n", name);
+ goto free_od;
+ }
+
+ goto free_mmc;
+
+free_od:
+ omap_device_delete(od);
+
+put_pdev:
+ platform_device_put(pdev);
+
+free_name:
+ kfree(mmc_data->name);
+
+free_mmc:
+ kfree(mmc_data);
+}
+
+void __init omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
+{
+ if (omap_hsmmc_done)
+ return;
+
+ omap_hsmmc_done = 1;
+
+ 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;
+ }
+
+ for (; controllers->mmc; controllers++)
+ omap_hsmmc_init_one(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 000000000..148cd9b15
--- /dev/null
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -0,0 +1,46 @@
+/*
+ * 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 deferred; /* mmc needs a deferred probe */
+ int gpio_cd; /* or -EINVAL */
+ int gpio_wp; /* or -EINVAL */
+ char *name; /* or NULL for default */
+ struct platform_device *pdev; /* mmc controller instance */
+ int ocr_mask; /* temporary HACK */
+ /* Remux (pad configuration) when powering on/off */
+ void (*remux)(struct device *dev, 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 omap_hsmmc_init(struct omap2_hsmmc_info *);
+void omap_hsmmc_late_init(struct omap2_hsmmc_info *);
+
+#else
+
+static inline void omap_hsmmc_init(struct omap2_hsmmc_info *info)
+{
+}
+
+static inline void omap_hsmmc_late_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 000000000..ef175acae
--- /dev/null
+++ b/arch/arm/mach-omap2/hwspinlock.c
@@ -0,0 +1,60 @@
+/*
+ * 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 <linux/hwspinlock.h>
+
+#include "soc.h"
+#include "omap_hwmod.h"
+#include "omap_device.h"
+
+static struct hwspinlock_pdata omap_hwspinlock_pdata __initdata = {
+ .base_id = 0,
+};
+
+static int __init hwspinlocks_init(void)
+{
+ int retval = 0;
+ struct omap_hwmod *oh;
+ struct platform_device *pdev;
+ 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;
+
+ pdev = omap_device_build(dev_name, 0, oh, &omap_hwspinlock_pdata,
+ sizeof(struct hwspinlock_pdata));
+ if (IS_ERR(pdev)) {
+ pr_err("Can't build omap_device for %s:%s\n", dev_name,
+ oh_name);
+ retval = PTR_ERR(pdev);
+ }
+
+ return retval;
+}
+/* early board code might need to reserve specific hwspinlock instances */
+omap_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 000000000..b9d8e47ff
--- /dev/null
+++ b/arch/arm/mach-omap2/i2c.c
@@ -0,0 +1,191 @@
+/*
+ * 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 "soc.h"
+#include "omap_hwmod.h"
+#include "omap_device.h"
+#include "omap-pm.h"
+
+#include "prm.h"
+#include "common.h"
+#include "mux.h"
+#include "i2c.h"
+
+/* In register I2C_CON, Bit 15 is the I2C enable bit */
+#define I2C_EN BIT(15)
+#define OMAP2_I2C_CON_OFFSET 0x24
+#define OMAP4_I2C_CON_OFFSET 0xA4
+
+#define MAX_OMAP_I2C_HWMOD_NAME_LEN 16
+
+static 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);
+}
+
+/**
+ * omap_i2c_reset - reset the omap i2c module.
+ * @oh: struct omap_hwmod *
+ *
+ * The i2c moudle in omap2, omap3 had a special sequence to reset. The
+ * sequence is:
+ * - Disable the I2C.
+ * - Write to SOFTRESET bit.
+ * - Enable the I2C.
+ * - Poll on the RESETDONE bit.
+ * The sequence is implemented in below function. This is called for 2420,
+ * 2430 and omap3.
+ */
+int omap_i2c_reset(struct omap_hwmod *oh)
+{
+ u32 v;
+ u16 i2c_con;
+ int c = 0;
+
+ if (oh->class->rev == OMAP_I2C_IP_VERSION_2) {
+ i2c_con = OMAP4_I2C_CON_OFFSET;
+ } else if (oh->class->rev == OMAP_I2C_IP_VERSION_1) {
+ i2c_con = OMAP2_I2C_CON_OFFSET;
+ } else {
+ WARN(1, "Cannot reset I2C block %s: unsupported revision\n",
+ oh->name);
+ return -EINVAL;
+ }
+
+ /* Disable I2C */
+ v = omap_hwmod_read(oh, i2c_con);
+ v &= ~I2C_EN;
+ omap_hwmod_write(v, oh, i2c_con);
+
+ /* Write to the SOFTRESET bit */
+ omap_hwmod_softreset(oh);
+
+ /* Enable I2C */
+ v = omap_hwmod_read(oh, i2c_con);
+ v |= I2C_EN;
+ omap_hwmod_write(v, oh, i2c_con);
+
+ /* Poll on RESETDONE bit */
+ omap_test_timeout((omap_hwmod_read(oh,
+ oh->class->sysc->syss_offs)
+ & SYSS_RESETDONE_MASK),
+ MAX_MODULE_SOFTRESET_WAIT, c);
+
+ if (c == MAX_MODULE_SOFTRESET_WAIT)
+ pr_warn("%s: %s: softreset failed (waited %d usec)\n",
+ __func__, oh->name, MAX_MODULE_SOFTRESET_WAIT);
+ else
+ pr_debug("%s: %s: softreset in %d usec\n", __func__,
+ oh->name, c);
+
+ return 0;
+}
+
+static int __init omap_i2c_nr_ports(void)
+{
+ int ports = 0;
+
+ if (cpu_is_omap24xx())
+ ports = 2;
+ else if (cpu_is_omap34xx())
+ ports = 3;
+ else if (cpu_is_omap44xx())
+ ports = 4;
+ return ports;
+}
+
+/*
+ * 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 const char name[] = "omap_i2c";
+
+int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *i2c_pdata,
+ int bus_id)
+{
+ int l;
+ struct omap_hwmod *oh;
+ struct platform_device *pdev;
+ char oh_name[MAX_OMAP_I2C_HWMOD_NAME_LEN];
+ struct omap_i2c_bus_platform_data *pdata;
+ struct omap_i2c_dev_attr *dev_attr;
+
+ if (bus_id > omap_i2c_nr_ports())
+ return -EINVAL;
+
+ 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;
+ /*
+ * pass the hwmod class's CPU-specific knowledge of I2C IP revision in
+ * use, and functionality implementation flags, up to the OMAP I2C
+ * driver via platform data
+ */
+ pdata->rev = oh->class->rev;
+
+ dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr;
+ pdata->flags = dev_attr->flags;
+
+ /*
+ * 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;
+ pdev = omap_device_build(name, bus_id, oh, pdata,
+ sizeof(struct omap_i2c_bus_platform_data));
+ WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name);
+
+ return PTR_ERR_OR_ZERO(pdev);
+}
+
+static int __init omap_i2c_cmdline(void)
+{
+ return omap_register_i2c_bus_cmdline();
+}
+omap_subsys_initcall(omap_i2c_cmdline);
diff --git a/arch/arm/mach-omap2/i2c.h b/arch/arm/mach-omap2/i2c.h
new file mode 100644
index 000000000..42b6f2e7d
--- /dev/null
+++ b/arch/arm/mach-omap2/i2c.h
@@ -0,0 +1,42 @@
+/*
+ * 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>
+
+#ifndef __MACH_OMAP2_I2C_H
+#define __MACH_OMAP2_I2C_H
+
+/**
+ * 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;
+ u32 flags;
+};
+
+int omap_i2c_reset(struct omap_hwmod *oh);
+
+#endif /* __MACH_OMAP2_I2C_H */
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
new file mode 100644
index 000000000..e3f713ffb
--- /dev/null
+++ b/arch/arm/mach-omap2/id.c
@@ -0,0 +1,769 @@
+/*
+ * 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 <linux/random.h>
+#include <linux/slab.h>
+
+#ifdef CONFIG_SOC_BUS
+#include <linux/sys_soc.h>
+#endif
+
+#include <asm/cputype.h>
+
+#include "common.h"
+
+#include "id.h"
+
+#include "soc.h"
+#include "control.h"
+
+#define OMAP4_SILICON_TYPE_STANDARD 0x01
+#define OMAP4_SILICON_TYPE_PERFORMANCE 0x02
+
+#define OMAP_SOC_MAX_NAME_LENGTH 16
+
+static unsigned int omap_revision;
+static char soc_name[OMAP_SOC_MAX_NAME_LENGTH];
+static char soc_rev[OMAP_SOC_MAX_NAME_LENGTH];
+u32 omap_features;
+
+unsigned int omap_rev(void)
+{
+ return omap_revision;
+}
+EXPORT_SYMBOL(omap_rev);
+
+int omap_type(void)
+{
+ static u32 val = OMAP2_DEVICETYPE_MASK;
+
+ if (val < OMAP2_DEVICETYPE_MASK)
+ return val;
+
+ if (cpu_is_omap24xx()) {
+ val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
+ } else if (cpu_is_ti81xx()) {
+ val = omap_ctrl_readl(TI81XX_CONTROL_STATUS);
+ } else if (soc_is_am33xx() || soc_is_am43xx()) {
+ val = omap_ctrl_readl(AM33XX_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 if (soc_is_omap54xx() || soc_is_dra7xx()) {
+ val = omap_ctrl_readl(OMAP5XXX_CONTROL_STATUS);
+ val &= OMAP5_DEVICETYPE_MASK;
+ val >>= 6;
+ goto out;
+ } 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) readl_relaxed(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() || soc_is_omap54xx() || soc_is_dra7xx()) {
+ 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 int __init omap_feed_randpool(void)
+{
+ struct omap_die_id odi;
+
+ /* Throw the die ID into the entropy pool at boot */
+ omap_get_die_id(&odi);
+ add_device_randomness(&odi, sizeof(odi));
+ return 0;
+}
+omap_device_initcall(omap_feed_randpool);
+
+void __init omap2xxx_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)) {
+ pr_err("Unknown OMAP device type. Handling it as OMAP%04x\n",
+ omap_ids[i].type >> 16);
+ j = i;
+ }
+
+ sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
+ sprintf(soc_rev, "ES%x", (omap_rev() >> 12) & 0xf);
+
+ pr_info("%s", soc_name);
+ if ((omap_rev() >> 8) & 0x0f)
+ pr_info("%s", soc_rev);
+ pr_info("\n");
+}
+
+#define OMAP3_SHOW_FEATURE(feat) \
+ if (omap3_has_ ##feat()) \
+ printk(#feat" ");
+
+static void __init omap3_cpuinfo(void)
+{
+ const char *cpu_name;
+
+ /*
+ * 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()) {
+ cpu_name = "OMAP3630";
+ } else if (soc_is_am35xx()) {
+ cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";
+ } else if (cpu_is_ti816x()) {
+ cpu_name = "TI816X";
+ } else if (soc_is_am335x()) {
+ cpu_name = "AM335X";
+ } else if (soc_is_am437x()) {
+ cpu_name = "AM437x";
+ } else if (cpu_is_ti814x()) {
+ cpu_name = "TI814X";
+ } else if (omap3_has_iva() && omap3_has_sgx()) {
+ /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
+ cpu_name = "OMAP3430/3530";
+ } else if (omap3_has_iva()) {
+ cpu_name = "OMAP3525";
+ } else if (omap3_has_sgx()) {
+ cpu_name = "OMAP3515";
+ } else {
+ cpu_name = "OMAP3503";
+ }
+
+ sprintf(soc_name, "%s", cpu_name);
+
+ /* Print verbose information */
+ pr_info("%s %s (", soc_name, soc_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");
+}
+
+#define OMAP3_CHECK_FEATURE(status,feat) \
+ if (((status & OMAP3_ ##feat## _MASK) \
+ >> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) { \
+ omap_features |= OMAP3_HAS_ ##feat; \
+ }
+
+void __init omap3xxx_check_features(void)
+{
+ u32 status;
+
+ omap_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())
+ omap_features |= OMAP3_HAS_192MHZ_CLK;
+ if (cpu_is_omap3430() || cpu_is_omap3630())
+ omap_features |= OMAP3_HAS_IO_WAKEUP;
+ if (cpu_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 ||
+ omap_rev() == OMAP3430_REV_ES3_1_2)
+ omap_features |= OMAP3_HAS_IO_CHAIN_CTRL;
+
+ omap_features |= OMAP3_HAS_SDRC;
+
+ /*
+ * am35x fixups:
+ * - The am35x Chip ID register has bits 12, 7:5, and 3:2 marked as
+ * reserved and therefore return 0 when read. Unfortunately,
+ * OMAP3_CHECK_FEATURE() will interpret some of those zeroes to
+ * mean that a feature is present even though it isn't so clear
+ * the incorrectly set feature bits.
+ */
+ if (soc_is_am35xx())
+ omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP);
+
+ /*
+ * TODO: Get additional info (where applicable)
+ * e.g. Size of L2 cache.
+ */
+
+ omap3_cpuinfo();
+}
+
+void __init omap4xxx_check_features(void)
+{
+ u32 si_type;
+
+ si_type =
+ (read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1) >> 16) & 0x03;
+
+ if (si_type == OMAP4_SILICON_TYPE_PERFORMANCE)
+ omap_features = OMAP4_HAS_PERF_SILICON;
+}
+
+void __init ti81xx_check_features(void)
+{
+ omap_features = OMAP3_HAS_NEON;
+ omap3_cpuinfo();
+}
+
+void __init am33xx_check_features(void)
+{
+ u32 status;
+
+ omap_features = OMAP3_HAS_NEON;
+
+ status = omap_ctrl_readl(AM33XX_DEV_FEATURE);
+ if (status & AM33XX_SGX_MASK)
+ omap_features |= OMAP3_HAS_SGX;
+
+ omap3_cpuinfo();
+}
+
+void __init omap3xxx_check_revision(void)
+{
+ const char *cpu_rev;
+ u32 cpuid, idcode;
+ u16 hawkeye;
+ u8 rev;
+
+ /*
+ * 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_id();
+ if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) {
+ omap_revision = OMAP3430_REV_ES1_0;
+ cpu_rev = "1.0";
+ 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;
+ cpu_rev = "2.0";
+ break;
+ case 2:
+ omap_revision = OMAP3430_REV_ES2_1;
+ cpu_rev = "2.1";
+ break;
+ case 3:
+ omap_revision = OMAP3430_REV_ES3_0;
+ cpu_rev = "3.0";
+ break;
+ case 4:
+ omap_revision = OMAP3430_REV_ES3_1;
+ cpu_rev = "3.1";
+ break;
+ case 7:
+ /* FALLTHROUGH */
+ default:
+ /* Use the latest known revision as default */
+ omap_revision = OMAP3430_REV_ES3_1_2;
+ cpu_rev = "3.1.2";
+ }
+ break;
+ case 0xb868:
+ /*
+ * Handle OMAP/AM 3505/3517 devices
+ *
+ * Set the device to be OMAP3517 here. Actual device
+ * is identified later based on the features.
+ */
+ switch (rev) {
+ case 0:
+ omap_revision = AM35XX_REV_ES1_0;
+ cpu_rev = "1.0";
+ break;
+ case 1:
+ /* FALLTHROUGH */
+ default:
+ omap_revision = AM35XX_REV_ES1_1;
+ cpu_rev = "1.1";
+ }
+ break;
+ case 0xb891:
+ /* Handle 36xx devices */
+
+ switch(rev) {
+ case 0: /* Take care of early samples */
+ omap_revision = OMAP3630_REV_ES1_0;
+ cpu_rev = "1.0";
+ break;
+ case 1:
+ omap_revision = OMAP3630_REV_ES1_1;
+ cpu_rev = "1.1";
+ break;
+ case 2:
+ /* FALLTHROUGH */
+ default:
+ omap_revision = OMAP3630_REV_ES1_2;
+ cpu_rev = "1.2";
+ }
+ break;
+ case 0xb81e:
+ switch (rev) {
+ case 0:
+ omap_revision = TI8168_REV_ES1_0;
+ cpu_rev = "1.0";
+ break;
+ case 1:
+ omap_revision = TI8168_REV_ES1_1;
+ cpu_rev = "1.1";
+ break;
+ case 2:
+ omap_revision = TI8168_REV_ES2_0;
+ cpu_rev = "2.0";
+ break;
+ case 3:
+ /* FALLTHROUGH */
+ default:
+ omap_revision = TI8168_REV_ES2_1;
+ cpu_rev = "2.1";
+ }
+ break;
+ case 0xb944:
+ switch (rev) {
+ case 0:
+ omap_revision = AM335X_REV_ES1_0;
+ cpu_rev = "1.0";
+ break;
+ case 1:
+ omap_revision = AM335X_REV_ES2_0;
+ cpu_rev = "2.0";
+ break;
+ case 2:
+ /* FALLTHROUGH */
+ default:
+ omap_revision = AM335X_REV_ES2_1;
+ cpu_rev = "2.1";
+ break;
+ }
+ break;
+ case 0xb98c:
+ switch (rev) {
+ case 0:
+ omap_revision = AM437X_REV_ES1_0;
+ cpu_rev = "1.0";
+ break;
+ case 1:
+ omap_revision = AM437X_REV_ES1_1;
+ cpu_rev = "1.1";
+ break;
+ case 2:
+ /* FALLTHROUGH */
+ default:
+ omap_revision = AM437X_REV_ES1_2;
+ cpu_rev = "1.2";
+ break;
+ }
+ break;
+ case 0xb8f2:
+ switch (rev) {
+ case 0:
+ /* FALLTHROUGH */
+ case 1:
+ omap_revision = TI8148_REV_ES1_0;
+ cpu_rev = "1.0";
+ break;
+ case 2:
+ omap_revision = TI8148_REV_ES2_0;
+ cpu_rev = "2.0";
+ break;
+ case 3:
+ /* FALLTHROUGH */
+ default:
+ omap_revision = TI8148_REV_ES2_1;
+ cpu_rev = "2.1";
+ break;
+ }
+ break;
+ default:
+ /* Unknown default to latest silicon rev as default */
+ omap_revision = OMAP3630_REV_ES1_2;
+ cpu_rev = "1.2";
+ pr_warn("Warning: unknown chip type; assuming OMAP3630ES1.2\n");
+ }
+ sprintf(soc_rev, "ES%s", cpu_rev);
+}
+
+void __init omap4xxx_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 4430 ES2.0 samples IDCODE is same as ES1.0
+ * Use ARM register to detect the correct ES version
+ */
+ if (!rev && (hawkeye != 0xb94e) && (hawkeye != 0xb975)) {
+ idcode = read_cpuid_id();
+ rev = (idcode & 0xf) - 1;
+ }
+
+ switch (hawkeye) {
+ case 0xb852:
+ switch (rev) {
+ case 0:
+ omap_revision = OMAP4430_REV_ES1_0;
+ break;
+ case 1:
+ default:
+ omap_revision = OMAP4430_REV_ES2_0;
+ }
+ break;
+ case 0xb95c:
+ switch (rev) {
+ case 3:
+ omap_revision = OMAP4430_REV_ES2_1;
+ break;
+ case 4:
+ omap_revision = OMAP4430_REV_ES2_2;
+ break;
+ case 6:
+ default:
+ omap_revision = OMAP4430_REV_ES2_3;
+ }
+ break;
+ case 0xb94e:
+ switch (rev) {
+ case 0:
+ omap_revision = OMAP4460_REV_ES1_0;
+ break;
+ case 2:
+ default:
+ omap_revision = OMAP4460_REV_ES1_1;
+ break;
+ }
+ break;
+ case 0xb975:
+ switch (rev) {
+ case 0:
+ default:
+ omap_revision = OMAP4470_REV_ES1_0;
+ break;
+ }
+ break;
+ default:
+ /* Unknown default to latest silicon rev as default */
+ omap_revision = OMAP4430_REV_ES2_3;
+ }
+
+ sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
+ sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf,
+ (omap_rev() >> 8) & 0xf);
+ pr_info("%s %s\n", soc_name, soc_rev);
+}
+
+void __init omap5xxx_check_revision(void)
+{
+ u32 idcode;
+ u16 hawkeye;
+ u8 rev;
+
+ idcode = read_tap_reg(OMAP_TAP_IDCODE);
+ hawkeye = (idcode >> 12) & 0xffff;
+ rev = (idcode >> 28) & 0xff;
+ switch (hawkeye) {
+ case 0xb942:
+ switch (rev) {
+ case 0:
+ /* No support for ES1.0 Test chip */
+ BUG();
+ case 1:
+ default:
+ omap_revision = OMAP5430_REV_ES2_0;
+ }
+ break;
+
+ case 0xb998:
+ switch (rev) {
+ case 0:
+ /* No support for ES1.0 Test chip */
+ BUG();
+ case 1:
+ default:
+ omap_revision = OMAP5432_REV_ES2_0;
+ }
+ break;
+
+ default:
+ /* Unknown default to latest silicon rev as default*/
+ omap_revision = OMAP5430_REV_ES2_0;
+ }
+
+ sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
+ sprintf(soc_rev, "ES%d.0", (omap_rev() >> 12) & 0xf);
+
+ pr_info("%s %s\n", soc_name, soc_rev);
+}
+
+void __init dra7xxx_check_revision(void)
+{
+ u32 idcode;
+ u16 hawkeye;
+ u8 rev;
+
+ idcode = read_tap_reg(OMAP_TAP_IDCODE);
+ hawkeye = (idcode >> 12) & 0xffff;
+ rev = (idcode >> 28) & 0xff;
+ switch (hawkeye) {
+ case 0xb990:
+ switch (rev) {
+ case 0:
+ omap_revision = DRA752_REV_ES1_0;
+ break;
+ case 1:
+ default:
+ omap_revision = DRA752_REV_ES1_1;
+ }
+ break;
+
+ case 0xb9bc:
+ switch (rev) {
+ case 0:
+ omap_revision = DRA722_REV_ES1_0;
+ break;
+ default:
+ /* If we have no new revisions */
+ omap_revision = DRA722_REV_ES1_0;
+ break;
+ }
+ break;
+
+ default:
+ /* Unknown default to latest silicon rev as default*/
+ pr_warn("%s: unknown idcode=0x%08x (hawkeye=0x%08x,rev=0x%x)\n",
+ __func__, idcode, hawkeye, rev);
+ omap_revision = DRA752_REV_ES1_1;
+ }
+
+ sprintf(soc_name, "DRA%03x", omap_rev() >> 16);
+ sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf,
+ (omap_rev() >> 8) & 0xf);
+
+ pr_info("%s %s\n", soc_name, soc_rev);
+}
+
+/*
+ * 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(u32 class, void __iomem *tap)
+{
+ omap_revision = class;
+ tap_base = tap;
+
+ /* XXX What is this intended to do? */
+ if (cpu_is_omap34xx())
+ tap_prod_id = 0x0210;
+ else
+ tap_prod_id = 0x0208;
+}
+
+#ifdef CONFIG_SOC_BUS
+
+static const char * const omap_types[] = {
+ [OMAP2_DEVICE_TYPE_TEST] = "TST",
+ [OMAP2_DEVICE_TYPE_EMU] = "EMU",
+ [OMAP2_DEVICE_TYPE_SEC] = "HS",
+ [OMAP2_DEVICE_TYPE_GP] = "GP",
+ [OMAP2_DEVICE_TYPE_BAD] = "BAD",
+};
+
+static const char * __init omap_get_family(void)
+{
+ if (cpu_is_omap24xx())
+ return kasprintf(GFP_KERNEL, "OMAP2");
+ else if (cpu_is_omap34xx())
+ return kasprintf(GFP_KERNEL, "OMAP3");
+ else if (cpu_is_omap44xx())
+ return kasprintf(GFP_KERNEL, "OMAP4");
+ else if (soc_is_omap54xx())
+ return kasprintf(GFP_KERNEL, "OMAP5");
+ else if (soc_is_am33xx() || soc_is_am335x())
+ return kasprintf(GFP_KERNEL, "AM33xx");
+ else if (soc_is_am43xx())
+ return kasprintf(GFP_KERNEL, "AM43xx");
+ else if (soc_is_dra7xx())
+ return kasprintf(GFP_KERNEL, "DRA7");
+ else
+ return kasprintf(GFP_KERNEL, "Unknown");
+}
+
+static ssize_t omap_get_type(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%s\n", omap_types[omap_type()]);
+}
+
+static struct device_attribute omap_soc_attr =
+ __ATTR(type, S_IRUGO, omap_get_type, NULL);
+
+void __init omap_soc_device_init(void)
+{
+ struct device *parent;
+ struct soc_device *soc_dev;
+ struct soc_device_attribute *soc_dev_attr;
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ return;
+
+ soc_dev_attr->machine = soc_name;
+ soc_dev_attr->family = omap_get_family();
+ soc_dev_attr->revision = soc_rev;
+
+ soc_dev = soc_device_register(soc_dev_attr);
+ if (IS_ERR(soc_dev)) {
+ kfree(soc_dev_attr);
+ return;
+ }
+
+ parent = soc_device_to_device(soc_dev);
+ device_create_file(parent, &omap_soc_attr);
+}
+#endif /* CONFIG_SOC_BUS */
diff --git a/arch/arm/mach-omap2/id.h b/arch/arm/mach-omap2/id.h
new file mode 100644
index 000000000..02ed3aa56
--- /dev/null
+++ b/arch/arm/mach-omap2/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/barriers.h b/arch/arm/mach-omap2/include/mach/barriers.h
new file mode 100644
index 000000000..1c582a859
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/barriers.h
@@ -0,0 +1,33 @@
+/*
+ * OMAP memory barrier header.
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Santosh Shilimkar <santosh.shilimkar@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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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>
+
+extern void omap_bus_sync(void);
+
+#define rmb() dsb()
+#define wmb() do { dsb(); outer_sync(); omap_bus_sync(); } while (0)
+#define mb() wmb()
+
+#endif /* __MACH_BARRIERS_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 000000000..54492dbf6
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/hardware.h
@@ -0,0 +1,3 @@
+/*
+ * arch/arm/mach-omap2/include/mach/hardware.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 000000000..ba5282caf
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/irqs.h
@@ -0,0 +1,3 @@
+/*
+ * arch/arm/mach-omap2/include/mach/irqs.h
+ */
diff --git a/arch/arm/mach-omap2/include/mach/serial.h b/arch/arm/mach-omap2/include/mach/serial.h
new file mode 100644
index 000000000..7ca1fcff4
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/serial.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2009 Texas Instruments
+ * Added 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.
+ */
+
+/* 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 */
+#define OMAP3_UART4_AM35XX_BASE 0x4809E000 /* Only on AM35xx */
+
+/* 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
+
+/* TI81XX serial ports */
+#define TI81XX_UART1_BASE 0x48020000
+#define TI81XX_UART2_BASE 0x48022000
+#define TI81XX_UART3_BASE 0x48024000
+
+/* AM3505/3517 UART4 */
+#define AM35XX_UART4_BASE 0x4809E000 /* Only on AM3505/3517 */
+
+/* AM33XX serial port */
+#define AM33XX_UART1_BASE 0x44E09000
+
+/* OMAP5 serial ports */
+#define OMAP5_UART1_BASE OMAP2_UART1_BASE
+#define OMAP5_UART2_BASE OMAP2_UART2_BASE
+#define OMAP5_UART3_BASE OMAP4_UART3_BASE
+#define OMAP5_UART4_BASE OMAP4_UART4_BASE
+#define OMAP5_UART5_BASE 0x48066000
+#define OMAP5_UART6_BASE 0x48068000
+
+/* External port on Zoom2/3 */
+#define ZOOM_UART_BASE 0x10000000
+#define ZOOM_UART_VIRT 0xfa400000
+
+#define OMAP_PORT_SHIFT 2
+#define ZOOM_PORT_SHIFT 1
+
+#define OMAP24XX_BASE_BAUD (48000000/16)
+
+#ifndef __ASSEMBLER__
+
+struct omap_board_data;
+struct omap_uart_port_info;
+
+extern void omap_serial_init(void);
+extern void omap_serial_board_init(struct omap_uart_port_info *platform_data);
+extern void omap_serial_init_port(struct omap_board_data *bdata,
+ struct omap_uart_port_info *platform_data);
+#endif
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
new file mode 100644
index 000000000..820dde8b5
--- /dev/null
+++ b/arch/arm/mach-omap2/io.c
@@ -0,0 +1,745 @@
+/*
+ * 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 <asm/tlb.h>
+#include <asm/mach/map.h>
+
+#include <linux/omap-dma.h>
+
+#include "omap_hwmod.h"
+#include "soc.h"
+#include "iomap.h"
+#include "voltage.h"
+#include "powerdomain.h"
+#include "clockdomain.h"
+#include "common.h"
+#include "clock.h"
+#include "clock2xxx.h"
+#include "clock3xxx.h"
+#include "clock44xx.h"
+#include "omap-pm.h"
+#include "sdrc.h"
+#include "control.h"
+#include "serial.h"
+#include "sram.h"
+#include "cm2xxx.h"
+#include "cm3xxx.h"
+#include "cm33xx.h"
+#include "cm44xx.h"
+#include "prm.h"
+#include "cm.h"
+#include "prcm_mpu44xx.h"
+#include "prminst44xx.h"
+#include "prm2xxx.h"
+#include "prm3xxx.h"
+#include "prm33xx.h"
+#include "prm44xx.h"
+#include "opp2xxx.h"
+
+/*
+ * omap_clk_soc_init: points to a function that does the SoC-specific
+ * clock initializations
+ */
+static int (*omap_clk_soc_init)(void);
+
+/*
+ * The machine specific code may provide the extra mapping besides the
+ * default mapping provided here.
+ */
+
+#if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
+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
+ },
+};
+#endif
+
+#ifdef CONFIG_SOC_TI81XX
+static struct map_desc omapti81xx_io_desc[] __initdata = {
+ {
+ .virtual = L4_34XX_VIRT,
+ .pfn = __phys_to_pfn(L4_34XX_PHYS),
+ .length = L4_34XX_SIZE,
+ .type = MT_DEVICE
+ }
+};
+#endif
+
+#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
+static struct map_desc omapam33xx_io_desc[] __initdata = {
+ {
+ .virtual = L4_34XX_VIRT,
+ .pfn = __phys_to_pfn(L4_34XX_PHYS),
+ .length = L4_34XX_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = L4_WK_AM33XX_VIRT,
+ .pfn = __phys_to_pfn(L4_WK_AM33XX_PHYS),
+ .length = L4_WK_AM33XX_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 = L4_PER_44XX_VIRT,
+ .pfn = __phys_to_pfn(L4_PER_44XX_PHYS),
+ .length = L4_PER_44XX_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+#endif
+
+#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX)
+static struct map_desc omap54xx_io_desc[] __initdata = {
+ {
+ .virtual = L3_54XX_VIRT,
+ .pfn = __phys_to_pfn(L3_54XX_PHYS),
+ .length = L3_54XX_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = L4_54XX_VIRT,
+ .pfn = __phys_to_pfn(L4_54XX_PHYS),
+ .length = L4_54XX_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = L4_WK_54XX_VIRT,
+ .pfn = __phys_to_pfn(L4_WK_54XX_PHYS),
+ .length = L4_WK_54XX_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = L4_PER_54XX_VIRT,
+ .pfn = __phys_to_pfn(L4_PER_54XX_PHYS),
+ .length = L4_PER_54XX_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+#endif
+
+#ifdef CONFIG_SOC_OMAP2420
+void __init omap242x_map_io(void)
+{
+ iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
+ iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc));
+}
+#endif
+
+#ifdef CONFIG_SOC_OMAP2430
+void __init omap243x_map_io(void)
+{
+ iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
+ iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc));
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+void __init omap3_map_io(void)
+{
+ iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc));
+}
+#endif
+
+#ifdef CONFIG_SOC_TI81XX
+void __init ti81xx_map_io(void)
+{
+ iotable_init(omapti81xx_io_desc, ARRAY_SIZE(omapti81xx_io_desc));
+}
+#endif
+
+#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
+void __init am33xx_map_io(void)
+{
+ iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc));
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+void __init omap4_map_io(void)
+{
+ iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc));
+}
+#endif
+
+#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX)
+void __init omap5_map_io(void)
+{
+ iotable_init(omap54xx_io_desc, ARRAY_SIZE(omap54xx_io_desc));
+}
+#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);
+}
+
+static void __init omap_hwmod_init_postsetup(void)
+{
+ u8 postsetup_state;
+
+ /* Set the default postsetup state for all hwmods */
+#ifdef CONFIG_PM
+ postsetup_state = _HWMOD_STATE_IDLE;
+#else
+ postsetup_state = _HWMOD_STATE_ENABLED;
+#endif
+ omap_hwmod_for_each(_set_hwmod_postsetup_state, &postsetup_state);
+
+ omap_pm_if_early_init();
+}
+
+static void __init __maybe_unused omap_common_late_init(void)
+{
+ omap_mux_late_init();
+ omap2_common_pm_late_init();
+ omap_soc_device_init();
+}
+
+#ifdef CONFIG_SOC_OMAP2420
+void __init omap2420_init_early(void)
+{
+ omap2_set_globals_tap(OMAP242X_CLASS, OMAP2_L4_IO_ADDRESS(0x48014000));
+ omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP2420_SDRC_BASE),
+ OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE));
+ omap2_control_base_init();
+ omap2xxx_check_revision();
+ omap2_prcm_base_init();
+ omap2xxx_voltagedomains_init();
+ omap242x_powerdomains_init();
+ omap242x_clockdomains_init();
+ omap2420_hwmod_init();
+ omap_hwmod_init_postsetup();
+ omap_clk_soc_init = omap2420_dt_clk_init;
+ rate_table = omap2420_rate_table;
+}
+
+void __init omap2420_init_late(void)
+{
+ omap_common_late_init();
+ omap2_pm_init();
+ omap2_clk_enable_autoidle_all();
+}
+#endif
+
+#ifdef CONFIG_SOC_OMAP2430
+void __init omap2430_init_early(void)
+{
+ omap2_set_globals_tap(OMAP243X_CLASS, OMAP2_L4_IO_ADDRESS(0x4900a000));
+ omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP243X_SDRC_BASE),
+ OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE));
+ omap2_control_base_init();
+ omap2xxx_check_revision();
+ omap2_prcm_base_init();
+ omap2xxx_voltagedomains_init();
+ omap243x_powerdomains_init();
+ omap243x_clockdomains_init();
+ omap2430_hwmod_init();
+ omap_hwmod_init_postsetup();
+ omap_clk_soc_init = omap2430_dt_clk_init;
+ rate_table = omap2430_rate_table;
+}
+
+void __init omap2430_init_late(void)
+{
+ omap_common_late_init();
+ omap2_pm_init();
+ omap2_clk_enable_autoidle_all();
+}
+#endif
+
+/*
+ * Currently only board-omap3beagle.c should call this because of the
+ * same machine_id for 34xx and 36xx beagle.. Will get fixed with DT.
+ */
+#ifdef CONFIG_ARCH_OMAP3
+void __init omap3_init_early(void)
+{
+ omap2_set_globals_tap(OMAP343X_CLASS, OMAP2_L4_IO_ADDRESS(0x4830A000));
+ omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE),
+ OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE));
+ /* XXX: remove these once OMAP3 is DT only */
+ if (!of_have_populated_dt()) {
+ omap2_set_globals_control(
+ OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE));
+ omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE));
+ omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE),
+ NULL);
+ }
+ omap2_control_base_init();
+ omap3xxx_check_revision();
+ omap3xxx_check_features();
+ omap2_prcm_base_init();
+ /* XXX: remove these once OMAP3 is DT only */
+ if (!of_have_populated_dt()) {
+ omap3xxx_prm_init(NULL);
+ omap3xxx_cm_init(NULL);
+ }
+ omap3xxx_voltagedomains_init();
+ omap3xxx_powerdomains_init();
+ omap3xxx_clockdomains_init();
+ omap3xxx_hwmod_init();
+ omap_hwmod_init_postsetup();
+ if (!of_have_populated_dt()) {
+ omap3_control_legacy_iomap_init();
+ if (soc_is_am35xx())
+ omap_clk_soc_init = am35xx_clk_legacy_init;
+ else if (cpu_is_omap3630())
+ omap_clk_soc_init = omap36xx_clk_legacy_init;
+ else if (omap_rev() == OMAP3430_REV_ES1_0)
+ omap_clk_soc_init = omap3430es1_clk_legacy_init;
+ else
+ omap_clk_soc_init = omap3430_clk_legacy_init;
+ }
+}
+
+void __init omap3430_init_early(void)
+{
+ omap3_init_early();
+ if (of_have_populated_dt())
+ omap_clk_soc_init = omap3430_dt_clk_init;
+}
+
+void __init omap35xx_init_early(void)
+{
+ omap3_init_early();
+ if (of_have_populated_dt())
+ omap_clk_soc_init = omap3430_dt_clk_init;
+}
+
+void __init omap3630_init_early(void)
+{
+ omap3_init_early();
+ if (of_have_populated_dt())
+ omap_clk_soc_init = omap3630_dt_clk_init;
+}
+
+void __init am35xx_init_early(void)
+{
+ omap3_init_early();
+ if (of_have_populated_dt())
+ omap_clk_soc_init = am35xx_dt_clk_init;
+}
+
+void __init omap3_init_late(void)
+{
+ omap_common_late_init();
+ omap3_pm_init();
+ omap2_clk_enable_autoidle_all();
+}
+
+void __init omap3430_init_late(void)
+{
+ omap_common_late_init();
+ omap3_pm_init();
+ omap2_clk_enable_autoidle_all();
+}
+
+void __init omap35xx_init_late(void)
+{
+ omap_common_late_init();
+ omap3_pm_init();
+ omap2_clk_enable_autoidle_all();
+}
+
+void __init omap3630_init_late(void)
+{
+ omap_common_late_init();
+ omap3_pm_init();
+ omap2_clk_enable_autoidle_all();
+}
+
+void __init am35xx_init_late(void)
+{
+ omap_common_late_init();
+ omap3_pm_init();
+ omap2_clk_enable_autoidle_all();
+}
+
+void __init ti81xx_init_late(void)
+{
+ omap_common_late_init();
+ omap2_clk_enable_autoidle_all();
+}
+#endif
+
+#ifdef CONFIG_SOC_TI81XX
+void __init ti814x_init_early(void)
+{
+ omap2_set_globals_tap(TI814X_CLASS,
+ OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE));
+ omap2_control_base_init();
+ omap3xxx_check_revision();
+ ti81xx_check_features();
+ omap2_prcm_base_init();
+ omap3xxx_voltagedomains_init();
+ omap3xxx_powerdomains_init();
+ ti81xx_clockdomains_init();
+ ti81xx_hwmod_init();
+ omap_hwmod_init_postsetup();
+ if (of_have_populated_dt())
+ omap_clk_soc_init = ti81xx_dt_clk_init;
+}
+
+void __init ti816x_init_early(void)
+{
+ omap2_set_globals_tap(TI816X_CLASS,
+ OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE));
+ omap2_control_base_init();
+ omap3xxx_check_revision();
+ ti81xx_check_features();
+ omap2_prcm_base_init();
+ omap3xxx_voltagedomains_init();
+ omap3xxx_powerdomains_init();
+ ti81xx_clockdomains_init();
+ ti81xx_hwmod_init();
+ omap_hwmod_init_postsetup();
+ if (of_have_populated_dt())
+ omap_clk_soc_init = ti81xx_dt_clk_init;
+}
+#endif
+
+#ifdef CONFIG_SOC_AM33XX
+void __init am33xx_init_early(void)
+{
+ omap2_set_globals_tap(AM335X_CLASS,
+ AM33XX_L4_WK_IO_ADDRESS(AM33XX_TAP_BASE));
+ omap2_control_base_init();
+ omap3xxx_check_revision();
+ am33xx_check_features();
+ omap2_prcm_base_init();
+ am33xx_powerdomains_init();
+ am33xx_clockdomains_init();
+ am33xx_hwmod_init();
+ omap_hwmod_init_postsetup();
+ omap_clk_soc_init = am33xx_dt_clk_init;
+}
+
+void __init am33xx_init_late(void)
+{
+ omap_common_late_init();
+}
+#endif
+
+#ifdef CONFIG_SOC_AM43XX
+void __init am43xx_init_early(void)
+{
+ omap2_set_globals_tap(AM335X_CLASS,
+ AM33XX_L4_WK_IO_ADDRESS(AM33XX_TAP_BASE));
+ omap2_control_base_init();
+ omap3xxx_check_revision();
+ am33xx_check_features();
+ omap2_prcm_base_init();
+ am43xx_powerdomains_init();
+ am43xx_clockdomains_init();
+ am43xx_hwmod_init();
+ omap_hwmod_init_postsetup();
+ omap_l2_cache_init();
+ omap_clk_soc_init = am43xx_dt_clk_init;
+}
+
+void __init am43xx_init_late(void)
+{
+ omap_common_late_init();
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+void __init omap4430_init_early(void)
+{
+ omap2_set_globals_tap(OMAP443X_CLASS,
+ OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE));
+ omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP4430_PRCM_MPU_BASE));
+ omap2_control_base_init();
+ omap4xxx_check_revision();
+ omap4xxx_check_features();
+ omap2_prcm_base_init();
+ omap4_pm_init_early();
+ omap44xx_voltagedomains_init();
+ omap44xx_powerdomains_init();
+ omap44xx_clockdomains_init();
+ omap44xx_hwmod_init();
+ omap_hwmod_init_postsetup();
+ omap_l2_cache_init();
+ omap_clk_soc_init = omap4xxx_dt_clk_init;
+}
+
+void __init omap4430_init_late(void)
+{
+ omap_common_late_init();
+ omap4_pm_init();
+ omap2_clk_enable_autoidle_all();
+}
+#endif
+
+#ifdef CONFIG_SOC_OMAP5
+void __init omap5_init_early(void)
+{
+ omap2_set_globals_tap(OMAP54XX_CLASS,
+ OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE));
+ omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE));
+ omap2_control_base_init();
+ omap4_pm_init_early();
+ omap2_prcm_base_init();
+ omap5xxx_check_revision();
+ omap54xx_voltagedomains_init();
+ omap54xx_powerdomains_init();
+ omap54xx_clockdomains_init();
+ omap54xx_hwmod_init();
+ omap_hwmod_init_postsetup();
+ omap_clk_soc_init = omap5xxx_dt_clk_init;
+}
+
+void __init omap5_init_late(void)
+{
+ omap_common_late_init();
+ omap4_pm_init();
+ omap2_clk_enable_autoidle_all();
+}
+#endif
+
+#ifdef CONFIG_SOC_DRA7XX
+void __init dra7xx_init_early(void)
+{
+ omap2_set_globals_tap(-1, OMAP2_L4_IO_ADDRESS(DRA7XX_TAP_BASE));
+ omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE));
+ omap2_control_base_init();
+ omap4_pm_init_early();
+ omap2_prcm_base_init();
+ dra7xxx_check_revision();
+ dra7xx_powerdomains_init();
+ dra7xx_clockdomains_init();
+ dra7xx_hwmod_init();
+ omap_hwmod_init_postsetup();
+ omap_clk_soc_init = dra7xx_dt_clk_init;
+}
+
+void __init dra7xx_init_late(void)
+{
+ omap_common_late_init();
+ omap4_pm_init();
+ omap2_clk_enable_autoidle_all();
+}
+#endif
+
+
+void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
+ struct omap_sdrc_params *sdrc_cs1)
+{
+ omap_sram_init();
+
+ if (cpu_is_omap24xx() || omap3_has_sdrc()) {
+ omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
+ _omap2_init_reprogram_sdrc();
+ }
+}
+
+int __init omap_clk_init(void)
+{
+ int ret = 0;
+
+ if (!omap_clk_soc_init)
+ return 0;
+
+ ti_clk_init_features();
+
+ if (of_have_populated_dt()) {
+ ret = omap_control_init();
+ if (ret)
+ return ret;
+
+ ret = omap_prcm_init();
+ if (ret)
+ return ret;
+
+ of_clk_init(NULL);
+
+ ti_dt_clk_init_retry_clks();
+
+ ti_dt_clockdomains_setup();
+ }
+
+ ret = omap_clk_soc_init();
+
+ return ret;
+}
diff --git a/arch/arm/mach-omap2/iomap.h b/arch/arm/mach-omap2/iomap.h
new file mode 100644
index 000000000..cce2b6503
--- /dev/null
+++ b/arch/arm/mach-omap2/iomap.h
@@ -0,0 +1,196 @@
+/*
+ * IO mappings for OMAP2+
+ *
+ * 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-2012 Texas Instruments
+ * Added OMAP4/5 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.
+ */
+
+#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 AM33XX_L4_WK_IO_OFFSET 0xb5000000
+#define AM33XX_L4_WK_IO_ADDRESS(pa) IOMEM((pa) + AM33XX_L4_WK_IO_OFFSET)
+
+#define OMAP4_L3_PER_IO_OFFSET 0xb1100000
+#define OMAP4_L3_PER_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_L3_PER_IO_OFFSET)
+
+#define OMAP2_EMU_IO_OFFSET 0xaa800000 /* Emulation */
+#define OMAP2_EMU_IO_ADDRESS(pa) IOMEM((pa) + OMAP2_EMU_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 */
+
+/*
+ * ----------------------------------------------------------------------------
+ * AM33XX specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+#define L4_WK_AM33XX_PHYS L4_WK_AM33XX_BASE
+#define L4_WK_AM33XX_VIRT (L4_WK_AM33XX_PHYS + AM33XX_L4_WK_IO_OFFSET)
+#define L4_WK_AM33XX_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
+/*
+ * ----------------------------------------------------------------------------
+ * Omap5 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+#define L3_54XX_PHYS L3_54XX_BASE /* 0x44000000 --> 0xf8000000 */
+#define L3_54XX_VIRT (L3_54XX_PHYS + OMAP4_L3_IO_OFFSET)
+#define L3_54XX_SIZE SZ_1M
+
+#define L4_54XX_PHYS L4_54XX_BASE /* 0x4a000000 --> 0xfc000000 */
+#define L4_54XX_VIRT (L4_54XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_54XX_SIZE SZ_4M
+
+#define L4_WK_54XX_PHYS L4_WK_54XX_BASE /* 0x4ae00000 --> 0xfce00000 */
+#define L4_WK_54XX_VIRT (L4_WK_54XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_WK_54XX_SIZE SZ_2M
+
+#define L4_PER_54XX_PHYS L4_PER_54XX_BASE /* 0x48000000 --> 0xfa000000 */
+#define L4_PER_54XX_VIRT (L4_PER_54XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_PER_54XX_SIZE SZ_4M
diff --git a/arch/arm/mach-omap2/l3_2xxx.h b/arch/arm/mach-omap2/l3_2xxx.h
new file mode 100644
index 000000000..b8b564137
--- /dev/null
+++ b/arch/arm/mach-omap2/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/mach-omap2/l3_3xxx.h b/arch/arm/mach-omap2/l3_3xxx.h
new file mode 100644
index 000000000..cde1938c5
--- /dev/null
+++ b/arch/arm/mach-omap2/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/mach-omap2/l4_2xxx.h b/arch/arm/mach-omap2/l4_2xxx.h
new file mode 100644
index 000000000..3f39cf8a3
--- /dev/null
+++ b/arch/arm/mach-omap2/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/mach-omap2/l4_3xxx.h b/arch/arm/mach-omap2/l4_3xxx.h
new file mode 100644
index 000000000..881a858b1
--- /dev/null
+++ b/arch/arm/mach-omap2/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/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
new file mode 100644
index 000000000..b4ac3af11
--- /dev/null
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -0,0 +1,122 @@
+/*
+ * 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/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/platform_data/asoc-ti-mcbsp.h>
+#include <linux/pm_runtime.h>
+
+#include <linux/omap-dma.h>
+
+#include "soc.h"
+#include "omap_device.h"
+#include "clock.h"
+
+/*
+ * FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle.
+ * Sidetone needs non-gated ICLK and sidetone autoidle is broken.
+ */
+#include "cm3xxx.h"
+#include "cm-regbits-34xx.h"
+
+static struct clk *mcbsp_iclks[5];
+
+static int omap3_enable_st_clock(unsigned int id, bool enable)
+{
+ /*
+ * Sidetone uses McBSP ICLK - which must not idle when sidetones
+ * are enabled or sidetones start sounding ugly.
+ */
+ if (enable)
+ return omap2_clk_deny_idle(mcbsp_iclks[id]);
+ else
+ return omap2_clk_allow_idle(mcbsp_iclks[id]);
+}
+
+static int __init 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 platform_device *pdev;
+ char clk_name[11];
+
+ 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->reg_step = 4;
+ if (oh->class->rev < MCBSP_CONFIG_TYPE2) {
+ pdata->reg_size = 2;
+ } else {
+ pdata->reg_size = 4;
+ pdata->has_ccr = true;
+ }
+
+ if (oh->class->rev == MCBSP_CONFIG_TYPE2) {
+ /* The FIFO has 128 locations */
+ pdata->buffer_size = 0x80;
+ } else 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;
+ } else if (oh->class->rev == MCBSP_CONFIG_TYPE4) {
+ /* The FIFO has 128 locations for all instances */
+ pdata->buffer_size = 0x80;
+ }
+
+ if (oh->class->rev >= MCBSP_CONFIG_TYPE3)
+ pdata->has_wakeup = true;
+
+ oh_device[0] = oh;
+
+ if (oh->dev_attr) {
+ oh_device[1] = omap_hwmod_lookup((
+ (struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone);
+ pdata->enable_st_clock = omap3_enable_st_clock;
+ sprintf(clk_name, "mcbsp%d_ick", id);
+ mcbsp_iclks[id] = clk_get(NULL, clk_name);
+ count++;
+ }
+ pdev = omap_device_build_ss(name, id, oh_device, count, pdata,
+ sizeof(*pdata));
+ kfree(pdata);
+ if (IS_ERR(pdev)) {
+ pr_err("%s: Can't build omap_device for %s:%s.\n", __func__,
+ name, oh->name);
+ return PTR_ERR(pdev);
+ }
+ return 0;
+}
+
+static int __init omap2_mcbsp_init(void)
+{
+ if (!of_have_populated_dt())
+ omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL);
+
+ return 0;
+}
+omap_arch_initcall(omap2_mcbsp_init);
diff --git a/arch/arm/mach-omap2/mmc.h b/arch/arm/mach-omap2/mmc.h
new file mode 100644
index 000000000..30d39b97e
--- /dev/null
+++ b/arch/arm/mach-omap2/mmc.h
@@ -0,0 +1,13 @@
+
+#define OMAP24XX_NR_MMC 2
+#define OMAP2420_MMC_SIZE OMAP1_MMC_SIZE
+#define OMAP2_MMC1_BASE 0x4809c000
+
+#define OMAP4_MMC_REG_OFFSET 0x100
+
+struct omap_hwmod;
+int omap_msdi_reset(struct omap_hwmod *oh);
+
+/* called from board-specific card detection service routine */
+extern void omap_mmc_notify_cover_event(struct device *dev, int slot,
+ int is_closed);
diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c
new file mode 100644
index 000000000..8bdf18242
--- /dev/null
+++ b/arch/arm/mach-omap2/msdi.c
@@ -0,0 +1,90 @@
+/*
+ * MSDI IP block reset
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * 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 in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have 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
+ *
+ * XXX What about pad muxing?
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/platform_data/gpio-omap.h>
+
+#include "prm.h"
+#include "common.h"
+#include "control.h"
+#include "omap_hwmod.h"
+#include "omap_device.h"
+#include "mux.h"
+#include "mmc.h"
+
+/*
+ * MSDI_CON_OFFSET: offset in bytes of the MSDI IP block's CON register
+ * from the IP block's base address
+ */
+#define MSDI_CON_OFFSET 0x0c
+
+/* Register bitfields in the CON register */
+#define MSDI_CON_POW_MASK BIT(11)
+#define MSDI_CON_CLKD_MASK (0x3f << 0)
+#define MSDI_CON_CLKD_SHIFT 0
+
+/* MSDI_TARGET_RESET_CLKD: clock divisor to use throughout the reset */
+#define MSDI_TARGET_RESET_CLKD 0x3ff
+
+/**
+ * omap_msdi_reset - reset the MSDI IP block
+ * @oh: struct omap_hwmod *
+ *
+ * The MSDI IP block on OMAP2420 has to have both the POW and CLKD
+ * fields set inside its CON register for a reset to complete
+ * successfully. This is not documented in the TRM. For CLKD, we use
+ * the value that results in the lowest possible clock rate, to attempt
+ * to avoid disturbing any cards.
+ */
+int omap_msdi_reset(struct omap_hwmod *oh)
+{
+ u16 v = 0;
+ int c = 0;
+
+ /* Write to the SOFTRESET bit */
+ omap_hwmod_softreset(oh);
+
+ /* Enable the MSDI core and internal clock */
+ v |= MSDI_CON_POW_MASK;
+ v |= MSDI_TARGET_RESET_CLKD << MSDI_CON_CLKD_SHIFT;
+ omap_hwmod_write(v, oh, MSDI_CON_OFFSET);
+
+ /* Poll on RESETDONE bit */
+ omap_test_timeout((omap_hwmod_read(oh, oh->class->sysc->syss_offs)
+ & SYSS_RESETDONE_MASK),
+ MAX_MODULE_SOFTRESET_WAIT, c);
+
+ if (c == MAX_MODULE_SOFTRESET_WAIT)
+ pr_warn("%s: %s: softreset failed (waited %d usec)\n",
+ __func__, oh->name, MAX_MODULE_SOFTRESET_WAIT);
+ else
+ pr_debug("%s: %s: softreset in %d usec\n", __func__,
+ oh->name, c);
+
+ /* Disable the MSDI internal clock */
+ v &= ~MSDI_CON_CLKD_MASK;
+ omap_hwmod_write(v, oh, MSDI_CON_OFFSET);
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
new file mode 100644
index 000000000..176eef6ef
--- /dev/null
+++ b/arch/arm/mach-omap2/mux.c
@@ -0,0 +1,1153 @@
+/*
+ * 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 <linux/irq.h>
+#include <linux/interrupt.h>
+
+
+#include "omap_hwmod.h"
+
+#include "soc.h"
+#include "control.h"
+#include "mux.h"
+#include "prm.h"
+#include "common.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 readb_relaxed(partition->base + reg);
+ else
+ return readw_relaxed(partition->base + reg);
+}
+
+void omap_mux_write(struct omap_mux_partition *partition, u16 val,
+ u16 reg)
+{
+ if (partition->flags & OMAP_MUX_REG_8BIT)
+ writeb_relaxed(val, partition->base + reg);
+ else
+ writew_relaxed(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);
+ mux_mode |= partition->gpio;
+ 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)
+ if (strncmp(muxname, m0_entry, mode0_len) ||
+ (strlen(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;
+ }
+
+ return -ENODEV;
+}
+
+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;
+ }
+
+ pr_err("%s: Could not find signal %s\n", __func__, muxname);
+
+ 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 || !mux)
+ 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 | OMAP_DEVICE_PAD_WAKEUP))
+ 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 | OMAP_DEVICE_PAD_WAKEUP)) {
+ 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;
+}
+
+/**
+ * omap_hwmod_mux_scan_wakeups - omap hwmod scan wakeup pads
+ * @hmux: Pads for a hwmod
+ * @mpu_irqs: MPU irq array for a hwmod
+ *
+ * Scans the wakeup status of pads for a single hwmod. If an irq
+ * array is defined for this mux, the parser will call the registered
+ * ISRs for corresponding pads, otherwise the parser will stop at the
+ * first wakeup active pad and return. Returns true if there is a
+ * pending and non-served wakeup event for the mux, otherwise false.
+ */
+static bool omap_hwmod_mux_scan_wakeups(struct omap_hwmod_mux_info *hmux,
+ struct omap_hwmod_irq_info *mpu_irqs)
+{
+ int i, irq;
+ unsigned int val;
+ u32 handled_irqs = 0;
+
+ for (i = 0; i < hmux->nr_pads_dynamic; i++) {
+ struct omap_device_pad *pad = hmux->pads_dynamic[i];
+
+ if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP) ||
+ !(pad->idle & OMAP_WAKEUP_EN))
+ continue;
+
+ val = omap_mux_read(pad->partition, pad->mux->reg_offset);
+ if (!(val & OMAP_WAKEUP_EVENT))
+ continue;
+
+ if (!hmux->irqs)
+ return true;
+
+ irq = hmux->irqs[i];
+ /* make sure we only handle each irq once */
+ if (handled_irqs & 1 << irq)
+ continue;
+
+ handled_irqs |= 1 << irq;
+
+ generic_handle_irq(mpu_irqs[irq].irq);
+ }
+
+ return false;
+}
+
+/**
+ * _omap_hwmod_mux_handle_irq - Process wakeup events for a single hwmod
+ *
+ * Checks a single hwmod for every wakeup capable pad to see if there is an
+ * active wakeup event. If this is the case, call the corresponding ISR.
+ */
+static int _omap_hwmod_mux_handle_irq(struct omap_hwmod *oh, void *data)
+{
+ if (!oh->mux || !oh->mux->enabled)
+ return 0;
+ if (omap_hwmod_mux_scan_wakeups(oh->mux, oh->mpu_irqs))
+ generic_handle_irq(oh->mpu_irqs[0].irq);
+ return 0;
+}
+
+/**
+ * omap_hwmod_mux_handle_irq - Process pad wakeup irqs.
+ *
+ * Calls a function for each registered omap_hwmod to check
+ * pad wakeup statuses.
+ */
+static irqreturn_t omap_hwmod_mux_handle_irq(int irq, void *unused)
+{
+ omap_hwmod_for_each(_omap_hwmod_mux_handle_irq, NULL);
+ return IRQ_HANDLED;
+}
+
+/* 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)
+{
+ struct seq_file *seqf;
+ struct omap_mux *m;
+ u16 val;
+ int ret;
+ struct omap_mux_partition *partition;
+
+ if (count > OMAP_MUX_MAX_ARG_CHAR)
+ return -EINVAL;
+
+ ret = kstrtou16_from_user(user_buf, count, 0x10, &val);
+ if (ret < 0)
+ return ret;
+
+ seqf = file->private_data;
+ m = seqf->private;
+
+ partition = omap_mux_get_partition(m);
+ if (!partition)
+ return -ENODEV;
+
+ omap_mux_write(partition, 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 | S_IRUGO,
+ 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 */
+int __init omap_mux_late_init(void)
+{
+ struct omap_mux_partition *partition;
+ int ret;
+
+ 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(partition, 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();
+
+ /* see pinctrl-single-omap for the wake-up interrupt handling */
+ if (of_have_populated_dt())
+ return 0;
+
+ ret = request_irq(omap_prcm_event_to_irq("io"),
+ omap_hwmod_mux_handle_irq, IRQF_SHARED | IRQF_NO_SUSPEND,
+ "hwmod_io", omap_mux_late_init);
+
+ if (ret)
+ pr_warn("mux: Failed to setup hwmod io irq %d\n", ret);
+
+ return 0;
+}
+
+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 = kstrdup(omap_mux_options, GFP_KERNEL);
+ if (!options)
+ return;
+
+ next_opt = options;
+
+ while ((token = strsep(&next_opt, ",")) != NULL) {
+ char *keyval, *name;
+ u16 val;
+
+ keyval = token;
+ name = strsep(&keyval, "=");
+ if (name) {
+ int res;
+
+ res = kstrtou16(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] = kstrdup(src->muxnames[i],
+ GFP_KERNEL);
+ if (!dst->muxnames[i])
+ goto free;
+ }
+ }
+
+#ifdef CONFIG_DEBUG_FS
+ for (i = 0; i < OMAP_MUX_NR_SIDES; i++) {
+ if (src->balls[i]) {
+ dst->balls[i] = kstrdup(src->balls[i], GFP_KERNEL);
+ if (!dst->balls[i])
+ goto free;
+ }
+ }
+#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[0]) {
+ superset++;
+ continue;
+ }
+#else
+ /* Skip pins that are not muxed as GPIO by bootloader */
+ if (!OMAP_MODE_GPIO(partition, 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 __init 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 __init 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->gpio = flags & OMAP_MUX_MODE7;
+ 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 000000000..d121fb6df
--- /dev/null
+++ b/arch/arm/mach-omap2/mux.h
@@ -0,0 +1,352 @@
+/*
+ * 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 "mux34xx.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)
+
+/* omap3/4/5 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)
+#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(partition, x) (((x) & OMAP_MUX_MODE7) == \
+ partition->gpio)
+#define OMAP_MODE_UART(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE0)
+
+/* Flags for omapX_mux_init */
+#define OMAP_PACKAGE_MASK 0xffff
+#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_MUX_NR_MODES 8 /* Available modes */
+#define OMAP_MUX_NR_SIDES 2 /* Bottom & top */
+
+/*
+ * omap_mux_init flags definition:
+ *
+ * OMAP_GPIO_MUX_MODE, bits 0-2: gpio muxing mode, same like pad control
+ * register which includes values from 0-7.
+ * OMAP_MUX_REG_8BIT: Ensure that access to padconf is done in 8 bits.
+ * The default value is 16 bits.
+ */
+#define OMAP_MUX_GPIO_IN_MODE0 OMAP_MUX_MODE0
+#define OMAP_MUX_GPIO_IN_MODE1 OMAP_MUX_MODE1
+#define OMAP_MUX_GPIO_IN_MODE2 OMAP_MUX_MODE2
+#define OMAP_MUX_GPIO_IN_MODE3 OMAP_MUX_MODE3
+#define OMAP_MUX_GPIO_IN_MODE4 OMAP_MUX_MODE4
+#define OMAP_MUX_GPIO_IN_MODE5 OMAP_MUX_MODE5
+#define OMAP_MUX_GPIO_IN_MODE6 OMAP_MUX_MODE6
+#define OMAP_MUX_GPIO_IN_MODE7 OMAP_MUX_MODE7
+#define OMAP_MUX_REG_8BIT (1 << 3)
+
+/**
+ * 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
+ * @gpio: gpio mux mode
+ * @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 gpio;
+ 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
+ */
+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);
+
+int omap_mux_get_by_name(const char *muxname,
+ struct omap_mux_partition **found_partition,
+ struct omap_mux **found_mux);
+#else
+
+static inline int omap_mux_get_by_name(const char *muxname,
+ struct omap_mux_partition **found_partition,
+ struct omap_mux **found_mux)
+{
+ return 0;
+}
+
+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 __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/mux34xx.c b/arch/arm/mach-omap2/mux34xx.c
new file mode 100644
index 000000000..be271f1d5
--- /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", "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_RX, 151,
+ "uart1_rx", "ssi1_wake_tx", "mcbsp1_clkr", "mcspi4_clk",
+ "gpio_151", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART1_TX, 148,
+ "uart1_tx", "ssi1_dat_tx", 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", OMAP_MUX_GPIO_IN_MODE4,
+ 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 000000000..3f26d297c
--- /dev/null
+++ b/arch/arm/mach-omap2/mux34xx.h
@@ -0,0 +1,402 @@
+/*
+ * 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_GPIO_127 0xa24
+#define OMAP3_CONTROL_PADCONF_GPIO_126 0xa26
+#define OMAP3_CONTROL_PADCONF_GPIO_128 0xa28
+#define OMAP3_CONTROL_PADCONF_GPIO_129 0xa2a
+
+#define OMAP3_CONTROL_PADCONF_MUX_SIZE \
+ (OMAP3_CONTROL_PADCONF_GPIO_129 + 0x2)
diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S
new file mode 100644
index 000000000..6d1dffca6
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-headsmp.S
@@ -0,0 +1,123 @@
+/*
+ * Secondary CPU startup routine source file.
+ *
+ * Copyright (C) 2009-2014 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>
+
+#include "omap44xx.h"
+
+/* Physical address needed since MMU not enabled yet on secondary core */
+#define AUX_CORE_BOOT0_PA 0x48281800
+#define API_HYP_ENTRY 0x102
+
+/*
+ * OMAP5 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(omap5_secondary_startup)
+wait: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0
+ ldr r0, [r2]
+ mov r0, r0, lsr #5
+ mrc p15, 0, r4, c0, c0, 5
+ and r4, r4, #0x0f
+ cmp r0, r4
+ bne wait
+ b secondary_startup
+ENDPROC(omap5_secondary_startup)
+/*
+ * Same as omap5_secondary_startup except we call into the ROM to
+ * enable HYP mode first. This is called instead of
+ * omap5_secondary_startup if the primary CPU was put into HYP mode by
+ * the boot loader.
+ */
+ENTRY(omap5_secondary_hyp_startup)
+wait_2: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0
+ ldr r0, [r2]
+ mov r0, r0, lsr #5
+ mrc p15, 0, r4, c0, c0, 5
+ and r4, r4, #0x0f
+ cmp r0, r4
+ bne wait_2
+ ldr r12, =API_HYP_ENTRY
+ adr r0, hyp_boot
+ smc #0
+hyp_boot:
+ b secondary_startup
+ENDPROC(omap5_secondary_hyp_startup)
+/*
+ * 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(omap4_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(omap4_secondary_startup)
+
+ENTRY(omap4460_secondary_startup)
+hold_2: 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_2
+
+ /*
+ * GIC distributor control register has changed between
+ * CortexA9 r1pX and r2pX. The Control Register secure
+ * banked version is now composed of 2 bits:
+ * bit 0 == Secure Enable
+ * bit 1 == Non-Secure Enable
+ * The Non-Secure banked register has not changed
+ * Because the ROM Code is based on the r1pX GIC, the CPU1
+ * GIC restoration will cause a problem to CPU0 Non-Secure SW.
+ * The workaround must be:
+ * 1) Before doing the CPU1 wakeup, CPU0 must disable
+ * the GIC distributor
+ * 2) CPU1 must re-enable the GIC distributor on
+ * it's wakeup path.
+ */
+ ldr r1, =OMAP44XX_GIC_DIST_BASE
+ ldr r0, [r1]
+ orr r0, #1
+ str r0, [r1]
+
+ /*
+ * we've been released from the wait loop,secondary_stack
+ * should now contain the SVC stack for this core
+ */
+ b secondary_startup
+ENDPROC(omap4460_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 000000000..971791fe9
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-hotplug.c
@@ -0,0 +1,66 @@
+/*
+ * 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 <linux/io.h>
+
+#include "omap-wakeupgen.h"
+#include "common.h"
+#include "powerdomain.h"
+
+/*
+ * platform-specific code to shutdown a CPU
+ * Called with IRQs disabled
+ */
+void __ref omap4_cpu_die(unsigned int cpu)
+{
+ unsigned int boot_cpu = 0;
+ void __iomem *base = omap_get_wakeupgen_base();
+
+ /*
+ * we're ready for shutdown now, so do it
+ */
+ if (omap_secure_apis_support()) {
+ if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0)
+ pr_err("Secure clear status failed\n");
+ } else {
+ writel_relaxed(0, base + OMAP_AUX_CORE_BOOT_0);
+ }
+
+
+ for (;;) {
+ /*
+ * Enter into low power state
+ */
+ omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF);
+
+ if (omap_secure_apis_support())
+ boot_cpu = omap_read_auxcoreboot0();
+ else
+ boot_cpu =
+ readl_relaxed(base + OMAP_AUX_CORE_BOOT_0) >> 5;
+
+ if (boot_cpu == smp_processor_id()) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+ pr_debug("CPU%u: spurious wakeup call\n", cpu);
+ }
+}
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
new file mode 100644
index 000000000..4068350f9
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -0,0 +1,77 @@
+/*
+ * 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/of.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include <linux/platform_data/iommu-omap.h>
+#include "soc.h"
+#include "omap_hwmod.h"
+#include "omap_device.h"
+
+static int __init omap_iommu_dev_init(struct omap_hwmod *oh, void *unused)
+{
+ struct platform_device *pdev;
+ struct iommu_platform_data *pdata;
+ struct omap_mmu_dev_attr *a = (struct omap_mmu_dev_attr *)oh->dev_attr;
+ static int i;
+
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ pdata->name = oh->name;
+ pdata->nr_tlb_entries = a->nr_tlb_entries;
+
+ if (oh->rst_lines_cnt == 1) {
+ pdata->reset_name = oh->rst_lines->name;
+ pdata->assert_reset = omap_device_assert_hardreset;
+ pdata->deassert_reset = omap_device_deassert_hardreset;
+ }
+
+ pdev = omap_device_build("omap-iommu", i, oh, pdata, sizeof(*pdata));
+
+ kfree(pdata);
+
+ if (IS_ERR(pdev)) {
+ pr_err("%s: device build err: %ld\n", __func__, PTR_ERR(pdev));
+ return PTR_ERR(pdev);
+ }
+
+ i++;
+
+ return 0;
+}
+
+static int __init omap_iommu_init(void)
+{
+ /* If dtb is there, the devices will be created dynamically */
+ if (of_have_populated_dt())
+ return -ENODEV;
+
+ return omap_hwmod_for_each_by_class("mmu", omap_iommu_dev_init, NULL);
+}
+/* must be ready before omap3isp is probed */
+omap_subsys_initcall(omap_iommu_init);
+
+static void __exit omap_iommu_exit(void)
+{
+ /* Do nothing */
+}
+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-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
new file mode 100644
index 000000000..79f49d904
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -0,0 +1,446 @@
+/*
+ * OMAP MPUSS low power code
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * OMAP4430 MPUSS mainly consists of dual Cortex-A9 with per-CPU
+ * Local timer and Watchdog, GIC, SCU, PL310 L2 cache controller,
+ * CPU0 and CPU1 LPRM modules.
+ * CPU0, CPU1 and MPUSS each have there own power domain and
+ * hence multiple low power combinations of MPUSS are possible.
+ *
+ * The CPU0 and CPU1 can't support Closed switch Retention (CSWR)
+ * because the mode is not supported by hw constraints of dormant
+ * mode. While waking up from the dormant mode, a reset signal
+ * to the Cortex-A9 processor must be asserted by the external
+ * power controller.
+ *
+ * With architectural inputs and hardware recommendations, only
+ * below modes are supported from power gain vs latency point of view.
+ *
+ * CPU0 CPU1 MPUSS
+ * ----------------------------------------------
+ * ON ON ON
+ * ON(Inactive) OFF ON(Inactive)
+ * OFF OFF CSWR
+ * OFF OFF OSWR
+ * OFF OFF OFF(Device OFF *TBD)
+ * ----------------------------------------------
+ *
+ * Note: CPU0 is the master core and it is the last CPU to go down
+ * and first to wake-up when MPUSS low power states are excercised
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it 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/errno.h>
+#include <linux/linkage.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/smp_scu.h>
+#include <asm/pgalloc.h>
+#include <asm/suspend.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "soc.h"
+#include "common.h"
+#include "omap44xx.h"
+#include "omap4-sar-layout.h"
+#include "pm.h"
+#include "prcm_mpu44xx.h"
+#include "prcm_mpu54xx.h"
+#include "prminst44xx.h"
+#include "prcm44xx.h"
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
+
+#ifdef CONFIG_SMP
+
+struct omap4_cpu_pm_info {
+ struct powerdomain *pwrdm;
+ void __iomem *scu_sar_addr;
+ void __iomem *wkup_sar_addr;
+ void __iomem *l2x0_sar_addr;
+};
+
+/**
+ * struct cpu_pm_ops - CPU pm operations
+ * @finish_suspend: CPU suspend finisher function pointer
+ * @resume: CPU resume function pointer
+ * @scu_prepare: CPU Snoop Control program function pointer
+ * @hotplug_restart: CPU restart function pointer
+ *
+ * Structure holds functions pointer for CPU low power operations like
+ * suspend, resume and scu programming.
+ */
+struct cpu_pm_ops {
+ int (*finish_suspend)(unsigned long cpu_state);
+ void (*resume)(void);
+ void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
+ void (*hotplug_restart)(void);
+};
+
+static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
+static struct powerdomain *mpuss_pd;
+static void __iomem *sar_base;
+static u32 cpu_context_offset;
+
+static int default_finish_suspend(unsigned long cpu_state)
+{
+ omap_do_wfi();
+ return 0;
+}
+
+static void dummy_cpu_resume(void)
+{}
+
+static void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state)
+{}
+
+struct cpu_pm_ops omap_pm_ops = {
+ .finish_suspend = default_finish_suspend,
+ .resume = dummy_cpu_resume,
+ .scu_prepare = dummy_scu_prepare,
+ .hotplug_restart = dummy_cpu_resume,
+};
+
+/*
+ * Program the wakeup routine address for the CPU0 and CPU1
+ * used for OFF or DORMANT wakeup.
+ */
+static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr)
+{
+ struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
+
+ if (pm_info->wkup_sar_addr)
+ writel_relaxed(addr, pm_info->wkup_sar_addr);
+}
+
+/*
+ * Store the SCU power status value to scratchpad memory
+ */
+static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state)
+{
+ struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
+ u32 scu_pwr_st;
+
+ switch (cpu_state) {
+ case PWRDM_POWER_RET:
+ scu_pwr_st = SCU_PM_DORMANT;
+ break;
+ case PWRDM_POWER_OFF:
+ scu_pwr_st = SCU_PM_POWEROFF;
+ break;
+ case PWRDM_POWER_ON:
+ case PWRDM_POWER_INACTIVE:
+ default:
+ scu_pwr_st = SCU_PM_NORMAL;
+ break;
+ }
+
+ if (pm_info->scu_sar_addr)
+ writel_relaxed(scu_pwr_st, pm_info->scu_sar_addr);
+}
+
+/* Helper functions for MPUSS OSWR */
+static inline void mpuss_clear_prev_logic_pwrst(void)
+{
+ u32 reg;
+
+ reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
+ omap4_prminst_write_inst_reg(reg, OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
+}
+
+static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id)
+{
+ u32 reg;
+
+ if (cpu_id) {
+ reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU1_INST,
+ cpu_context_offset);
+ omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU1_INST,
+ cpu_context_offset);
+ } else {
+ reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU0_INST,
+ cpu_context_offset);
+ omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU0_INST,
+ cpu_context_offset);
+ }
+}
+
+/*
+ * Store the CPU cluster state for L2X0 low power operations.
+ */
+static void l2x0_pwrst_prepare(unsigned int cpu_id, unsigned int save_state)
+{
+ struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
+
+ if (pm_info->l2x0_sar_addr)
+ writel_relaxed(save_state, pm_info->l2x0_sar_addr);
+}
+
+/*
+ * Save the L2X0 AUXCTRL and POR value to SAR memory. Its used to
+ * in every restore MPUSS OFF path.
+ */
+#ifdef CONFIG_CACHE_L2X0
+static void __init save_l2x0_context(void)
+{
+ void __iomem *l2x0_base = omap4_get_l2cache_base();
+
+ if (l2x0_base && sar_base) {
+ writel_relaxed(l2x0_saved_regs.aux_ctrl,
+ sar_base + L2X0_AUXCTRL_OFFSET);
+ writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
+ sar_base + L2X0_PREFETCH_CTRL_OFFSET);
+ }
+}
+#else
+static void __init save_l2x0_context(void)
+{}
+#endif
+
+/**
+ * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function
+ * The purpose of this function is to manage low power programming
+ * of OMAP4 MPUSS subsystem
+ * @cpu : CPU ID
+ * @power_state: Low power state.
+ *
+ * MPUSS states for the context save:
+ * save_state =
+ * 0 - Nothing lost and no need to save: MPUSS INACTIVE
+ * 1 - CPUx L1 and logic lost: MPUSS CSWR
+ * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
+ * 3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
+ */
+int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
+{
+ struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
+ unsigned int save_state = 0, cpu_logic_state = PWRDM_POWER_RET;
+ unsigned int wakeup_cpu;
+
+ if (omap_rev() == OMAP4430_REV_ES1_0)
+ return -ENXIO;
+
+ switch (power_state) {
+ case PWRDM_POWER_ON:
+ case PWRDM_POWER_INACTIVE:
+ save_state = 0;
+ break;
+ case PWRDM_POWER_OFF:
+ cpu_logic_state = PWRDM_POWER_OFF;
+ save_state = 1;
+ break;
+ case PWRDM_POWER_RET:
+ if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE)) {
+ save_state = 0;
+ break;
+ }
+ default:
+ /*
+ * CPUx CSWR is invalid hardware state. Also CPUx OSWR
+ * doesn't make much scense, since logic is lost and $L1
+ * needs to be cleaned because of coherency. This makes
+ * CPUx OSWR equivalent to CPUX OFF and hence not supported
+ */
+ WARN_ON(1);
+ return -ENXIO;
+ }
+
+ pwrdm_pre_transition(NULL);
+
+ /*
+ * Check MPUSS next state and save interrupt controller if needed.
+ * In MPUSS OSWR or device OFF, interrupt controller contest is lost.
+ */
+ mpuss_clear_prev_logic_pwrst();
+ if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
+ (pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF))
+ save_state = 2;
+
+ cpu_clear_prev_logic_pwrst(cpu);
+ pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
+ pwrdm_set_logic_retst(pm_info->pwrdm, cpu_logic_state);
+ set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.resume));
+ omap_pm_ops.scu_prepare(cpu, power_state);
+ l2x0_pwrst_prepare(cpu, save_state);
+
+ /*
+ * Call low level function with targeted low power state.
+ */
+ if (save_state)
+ cpu_suspend(save_state, omap_pm_ops.finish_suspend);
+ else
+ omap_pm_ops.finish_suspend(save_state);
+
+ if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD) && cpu)
+ gic_dist_enable();
+
+ /*
+ * Restore the CPUx power state to ON otherwise CPUx
+ * power domain can transitions to programmed low power
+ * state while doing WFI outside the low powe code. On
+ * secure devices, CPUx does WFI which can result in
+ * domain transition
+ */
+ wakeup_cpu = smp_processor_id();
+ pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
+
+ pwrdm_post_transition(NULL);
+
+ return 0;
+}
+
+/**
+ * omap4_hotplug_cpu: OMAP4 CPU hotplug entry
+ * @cpu : CPU ID
+ * @power_state: CPU low power state.
+ */
+int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
+{
+ struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
+ unsigned int cpu_state = 0;
+
+ if (omap_rev() == OMAP4430_REV_ES1_0)
+ return -ENXIO;
+
+ /* Use the achievable power state for the domain */
+ power_state = pwrdm_get_valid_lp_state(pm_info->pwrdm,
+ false, power_state);
+
+ if (power_state == PWRDM_POWER_OFF)
+ cpu_state = 1;
+
+ pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
+ pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
+ set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.hotplug_restart));
+ omap_pm_ops.scu_prepare(cpu, power_state);
+
+ /*
+ * CPU never retuns back if targeted power state is OFF mode.
+ * CPU ONLINE follows normal CPU ONLINE ptah via
+ * omap4_secondary_startup().
+ */
+ omap_pm_ops.finish_suspend(cpu_state);
+
+ pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
+ return 0;
+}
+
+
+/*
+ * Enable Mercury Fast HG retention mode by default.
+ */
+static void enable_mercury_retention_mode(void)
+{
+ u32 reg;
+
+ reg = omap4_prcm_mpu_read_inst_reg(OMAP54XX_PRCM_MPU_DEVICE_INST,
+ OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
+ /* Enable HG_EN, HG_RAMPUP = fast mode */
+ reg |= BIT(24) | BIT(25);
+ omap4_prcm_mpu_write_inst_reg(reg, OMAP54XX_PRCM_MPU_DEVICE_INST,
+ OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
+}
+
+/*
+ * Initialise OMAP4 MPUSS
+ */
+int __init omap4_mpuss_init(void)
+{
+ struct omap4_cpu_pm_info *pm_info;
+
+ if (omap_rev() == OMAP4430_REV_ES1_0) {
+ WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
+ return -ENODEV;
+ }
+
+ if (cpu_is_omap44xx())
+ sar_base = omap4_get_sar_ram_base();
+
+ /* Initilaise per CPU PM information */
+ pm_info = &per_cpu(omap4_pm_info, 0x0);
+ if (sar_base) {
+ pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
+ pm_info->wkup_sar_addr = sar_base +
+ CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
+ pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
+ }
+ pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
+ if (!pm_info->pwrdm) {
+ pr_err("Lookup failed for CPU0 pwrdm\n");
+ return -ENODEV;
+ }
+
+ /* Clear CPU previous power domain state */
+ pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
+ cpu_clear_prev_logic_pwrst(0);
+
+ /* Initialise CPU0 power domain state to ON */
+ pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
+
+ pm_info = &per_cpu(omap4_pm_info, 0x1);
+ if (sar_base) {
+ pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
+ pm_info->wkup_sar_addr = sar_base +
+ CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
+ pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
+ }
+
+ pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
+ if (!pm_info->pwrdm) {
+ pr_err("Lookup failed for CPU1 pwrdm\n");
+ return -ENODEV;
+ }
+
+ /* Clear CPU previous power domain state */
+ pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
+ cpu_clear_prev_logic_pwrst(1);
+
+ /* Initialise CPU1 power domain state to ON */
+ pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
+
+ mpuss_pd = pwrdm_lookup("mpu_pwrdm");
+ if (!mpuss_pd) {
+ pr_err("Failed to lookup MPUSS power domain\n");
+ return -ENODEV;
+ }
+ pwrdm_clear_all_prev_pwrst(mpuss_pd);
+ mpuss_clear_prev_logic_pwrst();
+
+ if (sar_base) {
+ /* Save device type on scratchpad for low level code to use */
+ writel_relaxed((omap_type() != OMAP2_DEVICE_TYPE_GP) ? 1 : 0,
+ sar_base + OMAP_TYPE_OFFSET);
+ save_l2x0_context();
+ }
+
+ if (cpu_is_omap44xx()) {
+ omap_pm_ops.finish_suspend = omap4_finish_suspend;
+ omap_pm_ops.resume = omap4_cpu_resume;
+ omap_pm_ops.scu_prepare = scu_pwrst_prepare;
+ omap_pm_ops.hotplug_restart = omap4_secondary_startup;
+ cpu_context_offset = OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET;
+ } else if (soc_is_omap54xx() || soc_is_dra7xx()) {
+ cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
+ enable_mercury_retention_mode();
+ }
+
+ if (cpu_is_omap446x())
+ omap_pm_ops.hotplug_restart = omap4460_secondary_startup;
+
+ return 0;
+}
+
+#endif
diff --git a/arch/arm/mach-omap2/omap-pm-noop.c b/arch/arm/mach-omap2/omap-pm-noop.c
new file mode 100644
index 000000000..a1ee80669
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-pm-noop.c
@@ -0,0 +1,175 @@
+/*
+ * 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>
+
+#include "omap_device.h"
+#include "omap-pm.h"
+
+static bool off_mode_enabled;
+static int 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;
+}
+
+/*
+ * DSP Bridge-specific constraints
+ */
+
+
+/**
+ * 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
+
+int omap_pm_get_dev_context_loss_count(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ int count;
+
+ if (WARN_ON(!dev))
+ return -ENODEV;
+
+ if (dev->pm_domain == &omap_device_pm_domain) {
+ 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));
+
+ count = dummy_context_loss_counter;
+
+ if (off_mode_enabled) {
+ count++;
+ /*
+ * Context loss count has to be a non-negative value.
+ * Clear the sign bit to get a value range from 0 to
+ * INT_MAX.
+ */
+ count &= INT_MAX;
+ dummy_context_loss_counter = count;
+ }
+ }
+
+ pr_debug("OMAP PM: context loss count for dev %s = %d\n",
+ dev_name(dev), count);
+
+ return count;
+}
+
+#else
+
+int 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;
+}
diff --git a/arch/arm/mach-omap2/omap-pm.h b/arch/arm/mach-omap2/omap-pm.h
new file mode 100644
index 000000000..109bef553
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-pm.h
@@ -0,0 +1,160 @@
+/*
+ * 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/pm_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.
+ */
+int __init omap_pm_if_early_init(void);
+
+/**
+ * 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.
+ */
+int __init omap_pm_if_init(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);
+
+
+/*
+ * CPUFreq-originated constraint
+ *
+ * In the future, this should be handled by custom OPP clocktype
+ * functions.
+ */
+
+
+/*
+ * 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 negative value upon error.
+ */
+int 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/mach-omap2/omap-secure.c b/arch/arm/mach-omap2/omap-secure.c
new file mode 100644
index 000000000..5ac122e88
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-secure.c
@@ -0,0 +1,148 @@
+/*
+ * OMAP Secure API infrastructure.
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg>
+ * Copyright (C) 2013 Pali RohĂ¡r <pali.rohar@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/init.h>
+#include <linux/io.h>
+#include <linux/memblock.h>
+
+#include <asm/cacheflush.h>
+#include <asm/memblock.h>
+
+#include "omap-secure.h"
+
+static phys_addr_t omap_secure_memblock_base;
+
+/**
+ * omap_sec_dispatcher: Routine to dispatch low power secure
+ * service routines
+ * @idx: The HAL API index
+ * @flag: The flag indicating criticality of operation
+ * @nargs: Number of valid arguments out of four.
+ * @arg1, arg2, arg3 args4: Parameters passed to secure API
+ *
+ * Return the non-zero error value on failure.
+ */
+u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2,
+ u32 arg3, u32 arg4)
+{
+ u32 ret;
+ u32 param[5];
+
+ param[0] = nargs;
+ param[1] = arg1;
+ param[2] = arg2;
+ param[3] = arg3;
+ param[4] = arg4;
+
+ /*
+ * Secure API needs physical address
+ * pointer for the parameters
+ */
+ flush_cache_all();
+ outer_clean_range(__pa(param), __pa(param + 5));
+ ret = omap_smc2(idx, flag, __pa(param));
+
+ return ret;
+}
+
+/* Allocate the memory to save secure ram */
+int __init omap_secure_ram_reserve_memblock(void)
+{
+ u32 size = OMAP_SECURE_RAM_STORAGE;
+
+ size = ALIGN(size, SECTION_SIZE);
+ omap_secure_memblock_base = arm_memblock_steal(size, SECTION_SIZE);
+
+ return 0;
+}
+
+phys_addr_t omap_secure_ram_mempool_base(void)
+{
+ return omap_secure_memblock_base;
+}
+
+/**
+ * rx51_secure_dispatcher: Routine to dispatch secure PPA API calls
+ * @idx: The PPA API index
+ * @process: Process ID
+ * @flag: The flag indicating criticality of operation
+ * @nargs: Number of valid arguments out of four.
+ * @arg1, arg2, arg3 args4: Parameters passed to secure API
+ *
+ * Return the non-zero error value on failure.
+ *
+ * NOTE: rx51_secure_dispatcher differs from omap_secure_dispatcher because
+ * it calling omap_smc3() instead omap_smc2() and param[0] is nargs+1
+ */
+u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs,
+ u32 arg1, u32 arg2, u32 arg3, u32 arg4)
+{
+ u32 ret;
+ u32 param[5];
+
+ param[0] = nargs+1; /* RX-51 needs number of arguments + 1 */
+ param[1] = arg1;
+ param[2] = arg2;
+ param[3] = arg3;
+ param[4] = arg4;
+
+ /*
+ * Secure API needs physical address
+ * pointer for the parameters
+ */
+ local_irq_disable();
+ local_fiq_disable();
+ flush_cache_all();
+ outer_clean_range(__pa(param), __pa(param + 5));
+ ret = omap_smc3(idx, process, flag, __pa(param));
+ flush_cache_all();
+ local_fiq_enable();
+ local_irq_enable();
+
+ return ret;
+}
+
+/**
+ * rx51_secure_update_aux_cr: Routine to modify the contents of Auxiliary Control Register
+ * @set_bits: bits to set in ACR
+ * @clr_bits: bits to clear in ACR
+ *
+ * Return the non-zero error value on failure.
+*/
+u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits)
+{
+ u32 acr;
+
+ /* Read ACR */
+ asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr));
+ acr &= ~clear_bits;
+ acr |= set_bits;
+
+ return rx51_secure_dispatcher(RX51_PPA_WRITE_ACR,
+ 0,
+ FLAG_START_CRITICAL,
+ 1, acr, 0, 0, 0);
+}
+
+/**
+ * rx51_secure_rng_call: Routine for HW random generator
+ */
+u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag)
+{
+ return rx51_secure_dispatcher(RX51_PPA_HWRNG,
+ 0,
+ NO_FLAG,
+ 3, ptr, count, flag, 0);
+}
diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
new file mode 100644
index 000000000..af2851fbc
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-secure.h
@@ -0,0 +1,82 @@
+/*
+ * omap-secure.h: OMAP Secure infrastructure header.
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg>
+ * Copyright (C) 2013 Pali RohĂ¡r <pali.rohar@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 OMAP_ARCH_OMAP_SECURE_H
+#define OMAP_ARCH_OMAP_SECURE_H
+
+/* Monitor error code */
+#define API_HAL_RET_VALUE_NS2S_CONVERSION_ERROR 0xFFFFFFFE
+#define API_HAL_RET_VALUE_SERVICE_UNKNWON 0xFFFFFFFF
+
+/* HAL API error codes */
+#define API_HAL_RET_VALUE_OK 0x00
+#define API_HAL_RET_VALUE_FAIL 0x01
+
+/* Secure HAL API flags */
+#define FLAG_START_CRITICAL 0x4
+#define FLAG_IRQFIQ_MASK 0x3
+#define FLAG_IRQ_ENABLE 0x2
+#define FLAG_FIQ_ENABLE 0x1
+#define NO_FLAG 0x0
+
+/* Maximum Secure memory storage size */
+#define OMAP_SECURE_RAM_STORAGE (88 * SZ_1K)
+
+/* Secure low power HAL API index */
+#define OMAP4_HAL_SAVESECURERAM_INDEX 0x1a
+#define OMAP4_HAL_SAVEHW_INDEX 0x1b
+#define OMAP4_HAL_SAVEALL_INDEX 0x1c
+#define OMAP4_HAL_SAVEGIC_INDEX 0x1d
+
+/* Secure Monitor mode APIs */
+#define OMAP4_MON_SCU_PWR_INDEX 0x108
+#define OMAP4_MON_L2X0_DBG_CTRL_INDEX 0x100
+#define OMAP4_MON_L2X0_CTRL_INDEX 0x102
+#define OMAP4_MON_L2X0_AUXCTRL_INDEX 0x109
+#define OMAP4_MON_L2X0_PREFETCH_INDEX 0x113
+
+#define OMAP5_DRA7_MON_SET_CNTFRQ_INDEX 0x109
+#define OMAP5_MON_AMBA_IF_INDEX 0x108
+
+/* Secure PPA(Primary Protected Application) APIs */
+#define OMAP4_PPA_L2_POR_INDEX 0x23
+#define OMAP4_PPA_CPU_ACTRL_SMP_INDEX 0x25
+
+/* Secure RX-51 PPA (Primary Protected Application) APIs */
+#define RX51_PPA_HWRNG 29
+#define RX51_PPA_L2_INVAL 40
+#define RX51_PPA_WRITE_ACR 42
+
+#ifndef __ASSEMBLER__
+
+extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs,
+ u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+extern u32 omap_smc2(u32 id, u32 falg, u32 pargs);
+extern u32 omap_smc3(u32 id, u32 process, u32 flag, u32 pargs);
+extern phys_addr_t omap_secure_ram_mempool_base(void);
+extern int omap_secure_ram_reserve_memblock(void);
+
+extern u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs,
+ u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+extern u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits);
+extern u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag);
+
+#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
+void set_cntfreq(void);
+#else
+static inline void set_cntfreq(void)
+{
+}
+#endif
+
+#endif /* __ASSEMBLER__ */
+#endif /* OMAP_ARCH_OMAP_SECURE_H */
diff --git a/arch/arm/mach-omap2/omap-smc.S b/arch/arm/mach-omap2/omap-smc.S
new file mode 100644
index 000000000..fd90125bf
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-smc.S
@@ -0,0 +1,99 @@
+/*
+ * OMAP34xx and OMAP44xx secure APIs file.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Written by Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg>
+ * Copyright (C) 2013 Pali RohĂ¡r <pali.rohar@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/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)
+
+/**
+ * u32 omap_smc2(u32 id, u32 falg, u32 pargs)
+ * Low level common routine for secure HAL and PPA APIs.
+ * @id: Application ID of HAL APIs
+ * @flag: Flag to indicate the criticality of operation
+ * @pargs: Physical address of parameter list starting
+ * with number of parametrs
+ */
+ENTRY(omap_smc2)
+ stmfd sp!, {r4-r12, lr}
+ mov r3, r2
+ mov r2, r1
+ mov r1, #0x0 @ Process ID
+ mov r6, #0xff
+ mov r12, #0x00 @ Secure Service ID
+ mov r7, #0
+ mcr p15, 0, r7, c7, c5, 6
+ dsb
+ dmb
+ smc #0
+ ldmfd sp!, {r4-r12, pc}
+ENDPROC(omap_smc2)
+
+/**
+ * u32 omap_smc3(u32 service_id, u32 process_id, u32 flag, u32 pargs)
+ * Low level common routine for secure HAL and PPA APIs via smc #1
+ * r0 - @service_id: Secure Service ID
+ * r1 - @process_id: Process ID
+ * r2 - @flag: Flag to indicate the criticality of operation
+ * r3 - @pargs: Physical address of parameter list
+ */
+ENTRY(omap_smc3)
+ stmfd sp!, {r4-r11, lr}
+ mov r12, r0 @ Copy the secure service ID
+ mov r6, #0xff @ Indicate new Task call
+ dsb @ Memory Barrier (not sure if needed, copied from omap_smc2)
+ smc #1 @ Call PPA service
+ ldmfd sp!, {r4-r11, pc}
+ENDPROC(omap_smc3)
+
+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-smp.c b/arch/arm/mach-omap2/omap-smp.c
new file mode 100644
index 000000000..5305ec734
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -0,0 +1,252 @@
+/*
+ * OMAP4 SMP source file. It contains platform specific functions
+ * 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 <linux/irqchip/arm-gic.h>
+
+#include <asm/smp_scu.h>
+#include <asm/virt.h>
+
+#include "omap-secure.h"
+#include "omap-wakeupgen.h"
+#include <asm/cputype.h>
+
+#include "soc.h"
+#include "iomap.h"
+#include "common.h"
+#include "clockdomain.h"
+#include "pm.h"
+
+#define CPU_MASK 0xff0ffff0
+#define CPU_CORTEX_A9 0x410FC090
+#define CPU_CORTEX_A15 0x410FC0F0
+
+#define OMAP5_CORE_COUNT 0x2
+
+/* SCU base address */
+static void __iomem *scu_base;
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __iomem *omap4_get_scu_base(void)
+{
+ return scu_base;
+}
+
+static void omap4_secondary_init(unsigned int cpu)
+{
+ /*
+ * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device.
+ * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA
+ * init and for CPU1, a secure PPA API provided. CPU0 must be ON
+ * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+.
+ * OMAP443X GP devices- SMP bit isn't accessible.
+ * OMAP446X GP devices - SMP bit access is enabled on both CPUs.
+ */
+ if (cpu_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
+ omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX,
+ 4, 0, 0, 0, 0, 0);
+
+ /*
+ * Configure the CNTFRQ register for the secondary cpu's which
+ * indicates the frequency of the cpu local timers.
+ */
+ if (soc_is_omap54xx() || soc_is_dra7xx())
+ set_cntfreq();
+
+ /*
+ * Synchronise with the boot thread.
+ */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+
+static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ static struct clockdomain *cpu1_clkdm;
+ static bool booted;
+ static struct powerdomain *cpu1_pwrdm;
+ void __iomem *base = omap_get_wakeupgen_base();
+
+ /*
+ * Set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+ /*
+ * Update the AuxCoreBoot0 with boot state for secondary core.
+ * omap4_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
+ */
+ if (omap_secure_apis_support())
+ omap_modify_auxcoreboot0(0x200, 0xfffffdff);
+ else
+ writel_relaxed(0x20, base + OMAP_AUX_CORE_BOOT_0);
+
+ if (!cpu1_clkdm && !cpu1_pwrdm) {
+ cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
+ cpu1_pwrdm = pwrdm_lookup("cpu1_pwrdm");
+ }
+
+ /*
+ * The SGI(Software Generated Interrupts) are not wakeup capable
+ * from low power states. This is known limitation on OMAP4 and
+ * needs to be worked around by using software forced clockdomain
+ * wake-up. To wakeup CPU1, CPU0 forces the CPU1 clockdomain to
+ * software force wakeup. The clockdomain is then put back to
+ * hardware supervised mode.
+ * More details can be found in OMAP4430 TRM - Version J
+ * Section :
+ * 4.3.4.2 Power States of CPU0 and CPU1
+ */
+ if (booted && cpu1_pwrdm && cpu1_clkdm) {
+ /*
+ * GIC distributor control register has changed between
+ * CortexA9 r1pX and r2pX. The Control Register secure
+ * banked version is now composed of 2 bits:
+ * bit 0 == Secure Enable
+ * bit 1 == Non-Secure Enable
+ * The Non-Secure banked register has not changed
+ * Because the ROM Code is based on the r1pX GIC, the CPU1
+ * GIC restoration will cause a problem to CPU0 Non-Secure SW.
+ * The workaround must be:
+ * 1) Before doing the CPU1 wakeup, CPU0 must disable
+ * the GIC distributor
+ * 2) CPU1 must re-enable the GIC distributor on
+ * it's wakeup path.
+ */
+ if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) {
+ local_irq_disable();
+ gic_dist_disable();
+ }
+
+ /*
+ * Ensure that CPU power state is set to ON to avoid CPU
+ * powerdomain transition on wfi
+ */
+ clkdm_wakeup(cpu1_clkdm);
+ omap_set_pwrdm_state(cpu1_pwrdm, PWRDM_POWER_ON);
+ clkdm_allow_idle(cpu1_clkdm);
+
+ if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) {
+ while (gic_dist_disabled()) {
+ udelay(1);
+ cpu_relax();
+ }
+ gic_timer_retrigger();
+ local_irq_enable();
+ }
+ } else {
+ dsb_sev();
+ booted = true;
+ }
+
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+ /*
+ * 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.
+ */
+static void __init omap4_smp_init_cpus(void)
+{
+ unsigned int i = 0, ncores = 1, cpu_id;
+
+ /* Use ARM cpuid check here, as SoC detection will not work so early */
+ cpu_id = read_cpuid_id() & CPU_MASK;
+ if (cpu_id == CPU_CORTEX_A9) {
+ /*
+ * Currently we can't call ioremap here because
+ * SoC detection won't work until after init_early.
+ */
+ scu_base = OMAP2_L4_IO_ADDRESS(scu_a9_get_base());
+ BUG_ON(!scu_base);
+ ncores = scu_get_core_count(scu_base);
+ } else if (cpu_id == CPU_CORTEX_A15) {
+ ncores = OMAP5_CORE_COUNT;
+ }
+
+ /* sanity check */
+ if (ncores > nr_cpu_ids) {
+ pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
+ ncores, nr_cpu_ids);
+ ncores = nr_cpu_ids;
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+}
+
+static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)
+{
+ void *startup_addr = omap4_secondary_startup;
+ void __iomem *base = omap_get_wakeupgen_base();
+
+ /*
+ * Initialise the SCU and wake up the secondary core using
+ * wakeup_secondary().
+ */
+ if (scu_base)
+ scu_enable(scu_base);
+
+ if (cpu_is_omap446x())
+ startup_addr = omap4460_secondary_startup;
+
+ /*
+ * 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
+ */
+ if (omap_secure_apis_support())
+ omap_auxcoreboot_addr(virt_to_phys(startup_addr));
+ else
+ /*
+ * If the boot CPU is in HYP mode then start secondary
+ * CPU in HYP mode as well.
+ */
+ if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE)
+ writel_relaxed(virt_to_phys(omap5_secondary_hyp_startup),
+ base + OMAP_AUX_CORE_BOOT_1);
+ else
+ writel_relaxed(virt_to_phys(omap5_secondary_startup),
+ base + OMAP_AUX_CORE_BOOT_1);
+
+}
+
+struct smp_operations omap4_smp_ops __initdata = {
+ .smp_init_cpus = omap4_smp_init_cpus,
+ .smp_prepare_cpus = omap4_smp_prepare_cpus,
+ .smp_secondary_init = omap4_secondary_init,
+ .smp_boot_secondary = omap4_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = omap4_cpu_die,
+#endif
+};
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
new file mode 100644
index 000000000..3b56722df
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -0,0 +1,544 @@
+/*
+ * OMAP WakeupGen Source file
+ *
+ * OMAP WakeupGen is the interrupt controller extension used along
+ * with ARM GIC to wake the CPU out from low power states on
+ * external interrupts. It is responsible for generating wakeup
+ * event from the incoming interrupts and enable bits. It is
+ * implemented in MPU always ON power domain. During normal operation,
+ * WakeupGen delivers external interrupts directly to the GIC.
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * 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/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <linux/notifier.h>
+#include <linux/cpu_pm.h>
+
+#include "omap-wakeupgen.h"
+#include "omap-secure.h"
+
+#include "soc.h"
+#include "omap4-sar-layout.h"
+#include "common.h"
+#include "pm.h"
+
+#define AM43XX_NR_REG_BANKS 7
+#define AM43XX_IRQS 224
+#define MAX_NR_REG_BANKS AM43XX_NR_REG_BANKS
+#define MAX_IRQS AM43XX_IRQS
+#define DEFAULT_NR_REG_BANKS 5
+#define DEFAULT_IRQS 160
+#define WKG_MASK_ALL 0x00000000
+#define WKG_UNMASK_ALL 0xffffffff
+#define CPU_ENA_OFFSET 0x400
+#define CPU0_ID 0x0
+#define CPU1_ID 0x1
+#define OMAP4_NR_BANKS 4
+#define OMAP4_NR_IRQS 128
+
+static void __iomem *wakeupgen_base;
+static void __iomem *sar_base;
+static DEFINE_RAW_SPINLOCK(wakeupgen_lock);
+static unsigned int irq_target_cpu[MAX_IRQS];
+static unsigned int irq_banks = DEFAULT_NR_REG_BANKS;
+static unsigned int max_irqs = DEFAULT_IRQS;
+static unsigned int omap_secure_apis;
+
+/*
+ * Static helper functions.
+ */
+static inline u32 wakeupgen_readl(u8 idx, u32 cpu)
+{
+ return readl_relaxed(wakeupgen_base + OMAP_WKG_ENB_A_0 +
+ (cpu * CPU_ENA_OFFSET) + (idx * 4));
+}
+
+static inline void wakeupgen_writel(u32 val, u8 idx, u32 cpu)
+{
+ writel_relaxed(val, wakeupgen_base + OMAP_WKG_ENB_A_0 +
+ (cpu * CPU_ENA_OFFSET) + (idx * 4));
+}
+
+static inline void sar_writel(u32 val, u32 offset, u8 idx)
+{
+ writel_relaxed(val, sar_base + offset + (idx * 4));
+}
+
+static inline int _wakeupgen_get_irq_info(u32 irq, u32 *bit_posn, u8 *reg_index)
+{
+ /*
+ * Each WakeupGen register controls 32 interrupt.
+ * i.e. 1 bit per SPI IRQ
+ */
+ *reg_index = irq >> 5;
+ *bit_posn = irq %= 32;
+
+ return 0;
+}
+
+static void _wakeupgen_clear(unsigned int irq, unsigned int cpu)
+{
+ u32 val, bit_number;
+ u8 i;
+
+ if (_wakeupgen_get_irq_info(irq, &bit_number, &i))
+ return;
+
+ val = wakeupgen_readl(i, cpu);
+ val &= ~BIT(bit_number);
+ wakeupgen_writel(val, i, cpu);
+}
+
+static void _wakeupgen_set(unsigned int irq, unsigned int cpu)
+{
+ u32 val, bit_number;
+ u8 i;
+
+ if (_wakeupgen_get_irq_info(irq, &bit_number, &i))
+ return;
+
+ val = wakeupgen_readl(i, cpu);
+ val |= BIT(bit_number);
+ wakeupgen_writel(val, i, cpu);
+}
+
+/*
+ * Architecture specific Mask extension
+ */
+static void wakeupgen_mask(struct irq_data *d)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&wakeupgen_lock, flags);
+ _wakeupgen_clear(d->hwirq, irq_target_cpu[d->hwirq]);
+ raw_spin_unlock_irqrestore(&wakeupgen_lock, flags);
+ irq_chip_mask_parent(d);
+}
+
+/*
+ * Architecture specific Unmask extension
+ */
+static void wakeupgen_unmask(struct irq_data *d)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&wakeupgen_lock, flags);
+ _wakeupgen_set(d->hwirq, irq_target_cpu[d->hwirq]);
+ raw_spin_unlock_irqrestore(&wakeupgen_lock, flags);
+ irq_chip_unmask_parent(d);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static DEFINE_PER_CPU(u32 [MAX_NR_REG_BANKS], irqmasks);
+
+static void _wakeupgen_save_masks(unsigned int cpu)
+{
+ u8 i;
+
+ for (i = 0; i < irq_banks; i++)
+ per_cpu(irqmasks, cpu)[i] = wakeupgen_readl(i, cpu);
+}
+
+static void _wakeupgen_restore_masks(unsigned int cpu)
+{
+ u8 i;
+
+ for (i = 0; i < irq_banks; i++)
+ wakeupgen_writel(per_cpu(irqmasks, cpu)[i], i, cpu);
+}
+
+static void _wakeupgen_set_all(unsigned int cpu, unsigned int reg)
+{
+ u8 i;
+
+ for (i = 0; i < irq_banks; i++)
+ wakeupgen_writel(reg, i, cpu);
+}
+
+/*
+ * Mask or unmask all interrupts on given CPU.
+ * 0 = Mask all interrupts on the 'cpu'
+ * 1 = Unmask all interrupts on the 'cpu'
+ * Ensure that the initial mask is maintained. This is faster than
+ * iterating through GIC registers to arrive at the correct masks.
+ */
+static void wakeupgen_irqmask_all(unsigned int cpu, unsigned int set)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&wakeupgen_lock, flags);
+ if (set) {
+ _wakeupgen_save_masks(cpu);
+ _wakeupgen_set_all(cpu, WKG_MASK_ALL);
+ } else {
+ _wakeupgen_set_all(cpu, WKG_UNMASK_ALL);
+ _wakeupgen_restore_masks(cpu);
+ }
+ raw_spin_unlock_irqrestore(&wakeupgen_lock, flags);
+}
+#endif
+
+#ifdef CONFIG_CPU_PM
+static inline void omap4_irq_save_context(void)
+{
+ u32 i, val;
+
+ if (omap_rev() == OMAP4430_REV_ES1_0)
+ return;
+
+ for (i = 0; i < irq_banks; i++) {
+ /* Save the CPUx interrupt mask for IRQ 0 to 127 */
+ val = wakeupgen_readl(i, 0);
+ sar_writel(val, WAKEUPGENENB_OFFSET_CPU0, i);
+ val = wakeupgen_readl(i, 1);
+ sar_writel(val, WAKEUPGENENB_OFFSET_CPU1, i);
+
+ /*
+ * Disable the secure interrupts for CPUx. The restore
+ * code blindly restores secure and non-secure interrupt
+ * masks from SAR RAM. Secure interrupts are not suppose
+ * to be enabled from HLOS. So overwrite the SAR location
+ * so that the secure interrupt remains disabled.
+ */
+ sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU0, i);
+ sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU1, i);
+ }
+
+ /* Save AuxBoot* registers */
+ val = readl_relaxed(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
+ writel_relaxed(val, sar_base + AUXCOREBOOT0_OFFSET);
+ val = readl_relaxed(wakeupgen_base + OMAP_AUX_CORE_BOOT_1);
+ writel_relaxed(val, sar_base + AUXCOREBOOT1_OFFSET);
+
+ /* Save SyncReq generation logic */
+ val = readl_relaxed(wakeupgen_base + OMAP_PTMSYNCREQ_MASK);
+ writel_relaxed(val, sar_base + PTMSYNCREQ_MASK_OFFSET);
+ val = readl_relaxed(wakeupgen_base + OMAP_PTMSYNCREQ_EN);
+ writel_relaxed(val, sar_base + PTMSYNCREQ_EN_OFFSET);
+
+ /* Set the Backup Bit Mask status */
+ val = readl_relaxed(sar_base + SAR_BACKUP_STATUS_OFFSET);
+ val |= SAR_BACKUP_STATUS_WAKEUPGEN;
+ writel_relaxed(val, sar_base + SAR_BACKUP_STATUS_OFFSET);
+
+}
+
+static inline void omap5_irq_save_context(void)
+{
+ u32 i, val;
+
+ for (i = 0; i < irq_banks; i++) {
+ /* Save the CPUx interrupt mask for IRQ 0 to 159 */
+ val = wakeupgen_readl(i, 0);
+ sar_writel(val, OMAP5_WAKEUPGENENB_OFFSET_CPU0, i);
+ val = wakeupgen_readl(i, 1);
+ sar_writel(val, OMAP5_WAKEUPGENENB_OFFSET_CPU1, i);
+ sar_writel(0x0, OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU0, i);
+ sar_writel(0x0, OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU1, i);
+ }
+
+ /* Save AuxBoot* registers */
+ val = readl_relaxed(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
+ writel_relaxed(val, sar_base + OMAP5_AUXCOREBOOT0_OFFSET);
+ val = readl_relaxed(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
+ writel_relaxed(val, sar_base + OMAP5_AUXCOREBOOT1_OFFSET);
+
+ /* Set the Backup Bit Mask status */
+ val = readl_relaxed(sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET);
+ val |= SAR_BACKUP_STATUS_WAKEUPGEN;
+ writel_relaxed(val, sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET);
+
+}
+
+/*
+ * Save WakeupGen interrupt context in SAR BANK3. Restore is done by
+ * ROM code. WakeupGen IP is integrated along with GIC to manage the
+ * interrupt wakeups from CPU low power states. It manages
+ * masking/unmasking of Shared peripheral interrupts(SPI). So the
+ * interrupt enable/disable control should be in sync and consistent
+ * at WakeupGen and GIC so that interrupts are not lost.
+ */
+static void irq_save_context(void)
+{
+ if (!sar_base)
+ sar_base = omap4_get_sar_ram_base();
+
+ if (soc_is_omap54xx())
+ omap5_irq_save_context();
+ else
+ omap4_irq_save_context();
+}
+
+/*
+ * Clear WakeupGen SAR backup status.
+ */
+static void irq_sar_clear(void)
+{
+ u32 val;
+ u32 offset = SAR_BACKUP_STATUS_OFFSET;
+
+ if (soc_is_omap54xx())
+ offset = OMAP5_SAR_BACKUP_STATUS_OFFSET;
+
+ val = readl_relaxed(sar_base + offset);
+ val &= ~SAR_BACKUP_STATUS_WAKEUPGEN;
+ writel_relaxed(val, sar_base + offset);
+}
+
+/*
+ * Save GIC and Wakeupgen interrupt context using secure API
+ * for HS/EMU devices.
+ */
+static void irq_save_secure_context(void)
+{
+ u32 ret;
+ ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX,
+ FLAG_START_CRITICAL,
+ 0, 0, 0, 0, 0);
+ if (ret != API_HAL_RET_VALUE_OK)
+ pr_err("GIC and Wakeupgen context save failed\n");
+}
+#endif
+
+#ifdef CONFIG_HOTPLUG_CPU
+static int irq_cpu_hotplug_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned int)hcpu;
+
+ switch (action) {
+ case CPU_ONLINE:
+ wakeupgen_irqmask_all(cpu, 0);
+ break;
+ case CPU_DEAD:
+ wakeupgen_irqmask_all(cpu, 1);
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __refdata irq_hotplug_notifier = {
+ .notifier_call = irq_cpu_hotplug_notify,
+};
+
+static void __init irq_hotplug_init(void)
+{
+ register_hotcpu_notifier(&irq_hotplug_notifier);
+}
+#else
+static void __init irq_hotplug_init(void)
+{}
+#endif
+
+#ifdef CONFIG_CPU_PM
+static int irq_notifier(struct notifier_block *self, unsigned long cmd, void *v)
+{
+ switch (cmd) {
+ case CPU_CLUSTER_PM_ENTER:
+ if (omap_type() == OMAP2_DEVICE_TYPE_GP)
+ irq_save_context();
+ else
+ irq_save_secure_context();
+ break;
+ case CPU_CLUSTER_PM_EXIT:
+ if (omap_type() == OMAP2_DEVICE_TYPE_GP)
+ irq_sar_clear();
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block irq_notifier_block = {
+ .notifier_call = irq_notifier,
+};
+
+static void __init irq_pm_init(void)
+{
+ /* FIXME: Remove this when MPU OSWR support is added */
+ if (!IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE))
+ cpu_pm_register_notifier(&irq_notifier_block);
+}
+#else
+static void __init irq_pm_init(void)
+{}
+#endif
+
+void __iomem *omap_get_wakeupgen_base(void)
+{
+ return wakeupgen_base;
+}
+
+int omap_secure_apis_support(void)
+{
+ return omap_secure_apis;
+}
+
+static struct irq_chip wakeupgen_chip = {
+ .name = "WUGEN",
+ .irq_eoi = irq_chip_eoi_parent,
+ .irq_mask = wakeupgen_mask,
+ .irq_unmask = wakeupgen_unmask,
+ .irq_retrigger = irq_chip_retrigger_hierarchy,
+ .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = irq_chip_set_affinity_parent,
+#endif
+};
+
+static int wakeupgen_domain_xlate(struct irq_domain *domain,
+ struct device_node *controller,
+ const u32 *intspec,
+ unsigned int intsize,
+ unsigned long *out_hwirq,
+ unsigned int *out_type)
+{
+ if (domain->of_node != controller)
+ return -EINVAL; /* Shouldn't happen, really... */
+ if (intsize != 3)
+ return -EINVAL; /* Not GIC compliant */
+ if (intspec[0] != 0)
+ return -EINVAL; /* No PPI should point to this domain */
+
+ *out_hwirq = intspec[1];
+ *out_type = intspec[2];
+ return 0;
+}
+
+static int wakeupgen_domain_alloc(struct irq_domain *domain,
+ unsigned int virq,
+ unsigned int nr_irqs, void *data)
+{
+ struct of_phandle_args *args = data;
+ struct of_phandle_args parent_args;
+ irq_hw_number_t hwirq;
+ int i;
+
+ if (args->args_count != 3)
+ return -EINVAL; /* Not GIC compliant */
+ if (args->args[0] != 0)
+ return -EINVAL; /* No PPI should point to this domain */
+
+ hwirq = args->args[1];
+ if (hwirq >= MAX_IRQS)
+ return -EINVAL; /* Can't deal with this */
+
+ for (i = 0; i < nr_irqs; i++)
+ irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
+ &wakeupgen_chip, NULL);
+
+ parent_args = *args;
+ parent_args.np = domain->parent->of_node;
+ return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args);
+}
+
+static struct irq_domain_ops wakeupgen_domain_ops = {
+ .xlate = wakeupgen_domain_xlate,
+ .alloc = wakeupgen_domain_alloc,
+ .free = irq_domain_free_irqs_common,
+};
+
+/*
+ * Initialise the wakeupgen module.
+ */
+static int __init wakeupgen_init(struct device_node *node,
+ struct device_node *parent)
+{
+ struct irq_domain *parent_domain, *domain;
+ int i;
+ unsigned int boot_cpu = smp_processor_id();
+ u32 val;
+
+ if (!parent) {
+ pr_err("%s: no parent, giving up\n", node->full_name);
+ return -ENODEV;
+ }
+
+ parent_domain = irq_find_host(parent);
+ if (!parent_domain) {
+ pr_err("%s: unable to obtain parent domain\n", node->full_name);
+ return -ENXIO;
+ }
+ /* Not supported on OMAP4 ES1.0 silicon */
+ if (omap_rev() == OMAP4430_REV_ES1_0) {
+ WARN(1, "WakeupGen: Not supported on OMAP4430 ES1.0\n");
+ return -EPERM;
+ }
+
+ /* Static mapping, never released */
+ wakeupgen_base = of_iomap(node, 0);
+ if (WARN_ON(!wakeupgen_base))
+ return -ENOMEM;
+
+ if (cpu_is_omap44xx()) {
+ irq_banks = OMAP4_NR_BANKS;
+ max_irqs = OMAP4_NR_IRQS;
+ omap_secure_apis = 1;
+ } else if (soc_is_am43xx()) {
+ irq_banks = AM43XX_NR_REG_BANKS;
+ max_irqs = AM43XX_IRQS;
+ }
+
+ domain = irq_domain_add_hierarchy(parent_domain, 0, max_irqs,
+ node, &wakeupgen_domain_ops,
+ NULL);
+ if (!domain) {
+ iounmap(wakeupgen_base);
+ return -ENOMEM;
+ }
+
+ /* Clear all IRQ bitmasks at wakeupGen level */
+ for (i = 0; i < irq_banks; i++) {
+ wakeupgen_writel(0, i, CPU0_ID);
+ if (!soc_is_am43xx())
+ wakeupgen_writel(0, i, CPU1_ID);
+ }
+
+ /*
+ * FIXME: Add support to set_smp_affinity() once the core
+ * GIC code has necessary hooks in place.
+ */
+
+ /* Associate all the IRQs to boot CPU like GIC init does. */
+ for (i = 0; i < max_irqs; i++)
+ irq_target_cpu[i] = boot_cpu;
+
+ /*
+ * Enables OMAP5 ES2 PM Mode using ES2_PM_MODE in AMBA_IF_MODE
+ * 0x0: ES1 behavior, CPU cores would enter and exit OFF mode together.
+ * 0x1: ES2 behavior, CPU cores are allowed to enter/exit OFF mode
+ * independently.
+ * This needs to be set one time thanks to always ON domain.
+ *
+ * We do not support ES1 behavior anymore. OMAP5 is assumed to be
+ * ES2.0, and the same is applicable for DRA7.
+ */
+ if (soc_is_omap54xx() || soc_is_dra7xx()) {
+ val = __raw_readl(wakeupgen_base + OMAP_AMBA_IF_MODE);
+ val |= BIT(5);
+ omap_smc1(OMAP5_MON_AMBA_IF_INDEX, val);
+ }
+
+ irq_hotplug_init();
+ irq_pm_init();
+
+ return 0;
+}
+
+/*
+ * We cannot use the IRQCHIP_DECLARE macro that lives in
+ * drivers/irqchip, so we're forced to roll our own. Not very nice.
+ */
+OF_DECLARE_2(irqchip, ti_wakeupgen, "ti,omap4-wugen-mpu", wakeupgen_init);
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.h b/arch/arm/mach-omap2/omap-wakeupgen.h
new file mode 100644
index 000000000..a3491ad12
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-wakeupgen.h
@@ -0,0 +1,38 @@
+/*
+ * OMAP WakeupGen header file
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * 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_WAKEUPGEN_H
+#define OMAP_ARCH_WAKEUPGEN_H
+
+/* OMAP4 and OMAP5 has same base address */
+#define OMAP_WKUPGEN_BASE 0x48281000
+
+#define OMAP_WKG_CONTROL_0 0x00
+#define OMAP_WKG_ENB_A_0 0x10
+#define OMAP_WKG_ENB_B_0 0x14
+#define OMAP_WKG_ENB_C_0 0x18
+#define OMAP_WKG_ENB_D_0 0x1c
+#define OMAP_WKG_ENB_E_0 0x20
+#define OMAP_WKG_ENB_A_1 0x410
+#define OMAP_WKG_ENB_B_1 0x414
+#define OMAP_WKG_ENB_C_1 0x418
+#define OMAP_WKG_ENB_D_1 0x41c
+#define OMAP_WKG_ENB_E_1 0x420
+#define OMAP_AUX_CORE_BOOT_0 0x800
+#define OMAP_AUX_CORE_BOOT_1 0x804
+#define OMAP_AMBA_IF_MODE 0x80c
+#define OMAP_PTMSYNCREQ_MASK 0xc00
+#define OMAP_PTMSYNCREQ_EN 0xc04
+#define OMAP_TIMESTAMPCYCLELO 0xc08
+#define OMAP_TIMESTAMPCYCLEHI 0xc0c
+
+extern void __iomem *omap_get_wakeupgen_base(void);
+extern int omap_secure_apis_support(void);
+#endif
diff --git a/arch/arm/mach-omap2/omap2-restart.c b/arch/arm/mach-omap2/omap2-restart.c
new file mode 100644
index 000000000..d937b2e40
--- /dev/null
+++ b/arch/arm/mach-omap2/omap2-restart.c
@@ -0,0 +1,65 @@
+/*
+ * omap2-restart.c - code common to all OMAP2xxx machines.
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * 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/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include "soc.h"
+#include "common.h"
+#include "prm.h"
+
+/*
+ * reset_virt_prcm_set_ck, reset_sys_ck: pointers to the virt_prcm_set
+ * clock and the sys_ck. Used during the reset process
+ */
+static struct clk *reset_virt_prcm_set_ck, *reset_sys_ck;
+
+/* Reboot handling */
+
+/**
+ * omap2xxx_restart - Set DPLL to bypass mode for reboot to work
+ *
+ * Set the DPLL to bypass so that reboot completes successfully. No
+ * return value.
+ */
+void omap2xxx_restart(enum reboot_mode mode, const char *cmd)
+{
+ u32 rate;
+
+ rate = clk_get_rate(reset_sys_ck);
+ clk_set_rate(reset_virt_prcm_set_ck, rate);
+
+ /* XXX Should save the cmd argument for use after the reboot */
+
+ omap_prm_reset_system();
+}
+
+/**
+ * omap2xxx_common_look_up_clks_for_reset - look up clocks needed for restart
+ *
+ * Some clocks need to be looked up in advance for the SoC restart
+ * operation to work - see omap2xxx_restart(). Returns -EINVAL upon
+ * error or 0 upon success.
+ */
+static int __init omap2xxx_common_look_up_clks_for_reset(void)
+{
+ reset_virt_prcm_set_ck = clk_get(NULL, "virt_prcm_set");
+ if (IS_ERR(reset_virt_prcm_set_ck))
+ return -EINVAL;
+
+ reset_sys_ck = clk_get(NULL, "sys_ck");
+ if (IS_ERR(reset_sys_ck))
+ return -EINVAL;
+
+ return 0;
+}
+omap_core_initcall(omap2xxx_common_look_up_clks_for_reset);
diff --git a/arch/arm/mach-omap2/omap24xx.h b/arch/arm/mach-omap2/omap24xx.h
new file mode 100644
index 000000000..641a2c8d2
--- /dev/null
+++ b/arch/arm/mach-omap2/omap24xx.h
@@ -0,0 +1,87 @@
+/*
+ * 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/mach-omap2/omap3-restart.c b/arch/arm/mach-omap2/omap3-restart.c
new file mode 100644
index 000000000..103a49f68
--- /dev/null
+++ b/arch/arm/mach-omap2/omap3-restart.c
@@ -0,0 +1,34 @@
+/*
+ * omap3-restart.c - Code common to all OMAP3xxx machines.
+ *
+ * Copyright (C) 2009, 2012 Texas Instruments
+ * Copyright (C) 2010 Nokia Corporation
+ * Tony Lindgren <tony@atomide.com>
+ * 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/reboot.h>
+
+#include "control.h"
+#include "prm.h"
+
+/* Global address base setup code */
+
+/**
+ * omap3xxx_restart - trigger a software restart of the SoC
+ * @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c
+ * @cmd: passed from the userspace program rebooting the system (if provided)
+ *
+ * Resets the SoC. For @cmd, see the 'reboot' syscall in
+ * kernel/sys.c. No return value.
+ */
+void omap3xxx_restart(enum reboot_mode mode, const char *cmd)
+{
+ omap3_ctrl_write_boot_mode((cmd ? (u8)*cmd : 0));
+ omap_prm_reset_system();
+}
diff --git a/arch/arm/mach-omap2/omap34xx.h b/arch/arm/mach-omap2/omap34xx.h
new file mode 100644
index 000000000..ed0024dda
--- /dev/null
+++ b/arch/arm/mach-omap2/omap34xx.h
@@ -0,0 +1,69 @@
+/*
+ * 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 L4_WK_AM33XX_BASE 0x44C00000
+
+#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_MMU_BASE (OMAP3430_ISP_BASE + 0x1400)
+#define OMAP3430_ISP_BASE2 (OMAP3430_ISP_BASE + 0x1800)
+
+#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/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
new file mode 100644
index 000000000..16350eefa
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -0,0 +1,231 @@
+/*
+ * 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/irq.h>
+#include <linux/irqchip.h>
+#include <linux/platform_device.h>
+#include <linux/memblock.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/export.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/of_address.h>
+#include <linux/reboot.h>
+#include <linux/genalloc.h>
+
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/map.h>
+#include <asm/memblock.h>
+#include <asm/smp_twd.h>
+
+#include "omap-wakeupgen.h"
+#include "soc.h"
+#include "iomap.h"
+#include "common.h"
+#include "prminst44xx.h"
+#include "prcm_mpu44xx.h"
+#include "omap4-sar-layout.h"
+#include "omap-secure.h"
+#include "sram.h"
+
+#ifdef CONFIG_CACHE_L2X0
+static void __iomem *l2cache_base;
+#endif
+
+static void __iomem *sar_ram_base;
+static void __iomem *gic_dist_base_addr;
+static void __iomem *twd_base;
+
+#define IRQ_LOCALTIMER 29
+
+void gic_dist_disable(void)
+{
+ if (gic_dist_base_addr)
+ writel_relaxed(0x0, gic_dist_base_addr + GIC_DIST_CTRL);
+}
+
+void gic_dist_enable(void)
+{
+ if (gic_dist_base_addr)
+ writel_relaxed(0x1, gic_dist_base_addr + GIC_DIST_CTRL);
+}
+
+bool gic_dist_disabled(void)
+{
+ return !(readl_relaxed(gic_dist_base_addr + GIC_DIST_CTRL) & 0x1);
+}
+
+void gic_timer_retrigger(void)
+{
+ u32 twd_int = readl_relaxed(twd_base + TWD_TIMER_INTSTAT);
+ u32 gic_int = readl_relaxed(gic_dist_base_addr + GIC_DIST_PENDING_SET);
+ u32 twd_ctrl = readl_relaxed(twd_base + TWD_TIMER_CONTROL);
+
+ if (twd_int && !(gic_int & BIT(IRQ_LOCALTIMER))) {
+ /*
+ * The local timer interrupt got lost while the distributor was
+ * disabled. Ack the pending interrupt, and retrigger it.
+ */
+ pr_warn("%s: lost localtimer interrupt\n", __func__);
+ writel_relaxed(1, twd_base + TWD_TIMER_INTSTAT);
+ if (!(twd_ctrl & TWD_TIMER_CONTROL_PERIODIC)) {
+ writel_relaxed(1, twd_base + TWD_TIMER_COUNTER);
+ twd_ctrl |= TWD_TIMER_CONTROL_ENABLE;
+ writel_relaxed(twd_ctrl, twd_base + TWD_TIMER_CONTROL);
+ }
+ }
+}
+
+#ifdef CONFIG_CACHE_L2X0
+
+void __iomem *omap4_get_l2cache_base(void)
+{
+ return l2cache_base;
+}
+
+void omap4_l2c310_write_sec(unsigned long val, unsigned reg)
+{
+ unsigned smc_op;
+
+ switch (reg) {
+ case L2X0_CTRL:
+ smc_op = OMAP4_MON_L2X0_CTRL_INDEX;
+ break;
+
+ case L2X0_AUX_CTRL:
+ smc_op = OMAP4_MON_L2X0_AUXCTRL_INDEX;
+ break;
+
+ case L2X0_DEBUG_CTRL:
+ smc_op = OMAP4_MON_L2X0_DBG_CTRL_INDEX;
+ break;
+
+ case L310_PREFETCH_CTRL:
+ smc_op = OMAP4_MON_L2X0_PREFETCH_INDEX;
+ break;
+
+ case L310_POWER_CTRL:
+ pr_info_once("OMAP L2C310: ROM does not support power control setting\n");
+ return;
+
+ default:
+ WARN_ONCE(1, "OMAP L2C310: ignoring write to reg 0x%x\n", reg);
+ return;
+ }
+
+ omap_smc1(smc_op, val);
+}
+
+int __init omap_l2_cache_init(void)
+{
+ /* Static mapping, never released */
+ l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
+ if (WARN_ON(!l2cache_base))
+ return -ENOMEM;
+ return 0;
+}
+#endif
+
+void __iomem *omap4_get_sar_ram_base(void)
+{
+ return sar_ram_base;
+}
+
+/*
+ * SAR RAM used to save and restore the HW
+ * context in low power modes
+ */
+static int __init omap4_sar_ram_init(void)
+{
+ unsigned long sar_base;
+
+ /*
+ * To avoid code running on other OMAPs in
+ * multi-omap builds
+ */
+ if (cpu_is_omap44xx())
+ sar_base = OMAP44XX_SAR_RAM_BASE;
+ else if (soc_is_omap54xx())
+ sar_base = OMAP54XX_SAR_RAM_BASE;
+ else
+ return -ENOMEM;
+
+ /* Static mapping, never released */
+ sar_ram_base = ioremap(sar_base, SZ_16K);
+ if (WARN_ON(!sar_ram_base))
+ return -ENOMEM;
+
+ return 0;
+}
+omap_early_initcall(omap4_sar_ram_init);
+
+static const struct of_device_id intc_match[] = {
+ { .compatible = "ti,omap4-wugen-mpu", },
+ { .compatible = "ti,omap5-wugen-mpu", },
+ { },
+};
+
+static struct device_node *intc_node;
+
+unsigned int omap4_xlate_irq(unsigned int hwirq)
+{
+ struct of_phandle_args irq_data;
+ unsigned int irq;
+
+ if (!intc_node)
+ intc_node = of_find_matching_node(NULL, intc_match);
+
+ if (WARN_ON(!intc_node))
+ return hwirq;
+
+ irq_data.np = intc_node;
+ irq_data.args_count = 3;
+ irq_data.args[0] = 0;
+ irq_data.args[1] = hwirq - OMAP44XX_IRQ_GIC_START;
+ irq_data.args[2] = IRQ_TYPE_LEVEL_HIGH;
+
+ irq = irq_create_of_mapping(&irq_data);
+ if (WARN_ON(!irq))
+ irq = hwirq;
+
+ return irq;
+}
+
+void __init omap_gic_of_init(void)
+{
+ struct device_node *np;
+
+ intc_node = of_find_matching_node(NULL, intc_match);
+ if (WARN_ON(!intc_node)) {
+ pr_err("No WUGEN found in DT, system will misbehave.\n");
+ pr_err("UPDATE YOUR DEVICE TREE!\n");
+ }
+
+ /* Extract GIC distributor and TWD bases for OMAP4460 ROM Errata WA */
+ if (!cpu_is_omap446x())
+ goto skip_errata_init;
+
+ np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic");
+ gic_dist_base_addr = of_iomap(np, 0);
+ WARN_ON(!gic_dist_base_addr);
+
+ np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-twd-timer");
+ twd_base = of_iomap(np, 0);
+ WARN_ON(!twd_base);
+
+skip_errata_init:
+ irqchip_init();
+}
diff --git a/arch/arm/mach-omap2/omap4-restart.c b/arch/arm/mach-omap2/omap4-restart.c
new file mode 100644
index 000000000..a99e7f7fb
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4-restart.c
@@ -0,0 +1,26 @@
+/*
+ * omap4-restart.c - Common to OMAP4 and OMAP5
+ *
+ *
+ * This program is free software; you can redistribute it 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/reboot.h>
+#include "prm.h"
+
+/**
+ * omap44xx_restart - trigger a software restart of the SoC
+ * @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c
+ * @cmd: passed from the userspace program rebooting the system (if provided)
+ *
+ * Resets the SoC. For @cmd, see the 'reboot' syscall in
+ * kernel/sys.c. No return value.
+ */
+void omap44xx_restart(enum reboot_mode mode, const char *cmd)
+{
+ /* XXX Should save 'cmd' into scratchpad for use after reboot */
+ omap_prm_reset_system();
+}
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
new file mode 100644
index 000000000..792b1069f
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -0,0 +1,60 @@
+/*
+ * omap4-sar-layout.h: OMAP4 SAR RAM layout header file
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * 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_SAR_LAYOUT_H
+#define OMAP_ARCH_OMAP4_SAR_LAYOUT_H
+
+/*
+ * SAR BANK offsets from base address OMAP44XX/54XX_SAR_RAM_BASE
+ */
+#define SAR_BANK1_OFFSET 0x0000
+#define SAR_BANK2_OFFSET 0x1000
+#define SAR_BANK3_OFFSET 0x2000
+#define SAR_BANK4_OFFSET 0x3000
+
+/* Scratch pad memory offsets from SAR_BANK1 */
+#define SCU_OFFSET0 0xfe4
+#define SCU_OFFSET1 0xfe8
+#define OMAP_TYPE_OFFSET 0xfec
+#define L2X0_SAVE_OFFSET0 0xff0
+#define L2X0_SAVE_OFFSET1 0xff4
+#define L2X0_AUXCTRL_OFFSET 0xff8
+#define L2X0_PREFETCH_CTRL_OFFSET 0xffc
+
+/* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */
+#define CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xa04
+#define CPU1_WAKEUP_NS_PA_ADDR_OFFSET 0xa08
+
+#define SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x500)
+#define SAR_SECURE_RAM_SIZE_OFFSET (SAR_BANK3_OFFSET + 0x504)
+#define SAR_SECRAM_SAVED_AT_OFFSET (SAR_BANK3_OFFSET + 0x508)
+
+/* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */
+#define WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x684)
+#define WAKEUPGENENB_SECURE_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x694)
+#define WAKEUPGENENB_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x6a4)
+#define WAKEUPGENENB_SECURE_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x6b4)
+#define AUXCOREBOOT0_OFFSET (SAR_BANK3_OFFSET + 0x6c4)
+#define AUXCOREBOOT1_OFFSET (SAR_BANK3_OFFSET + 0x6c8)
+#define PTMSYNCREQ_MASK_OFFSET (SAR_BANK3_OFFSET + 0x6cc)
+#define PTMSYNCREQ_EN_OFFSET (SAR_BANK3_OFFSET + 0x6d0)
+#define SAR_BACKUP_STATUS_WAKEUPGEN 0x10
+
+/* WakeUpGen save restore offset from OMAP54XX_SAR_RAM_BASE */
+#define OMAP5_WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x9dc)
+#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x9f0)
+#define OMAP5_WAKEUPGENENB_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0xa04)
+#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0xa18)
+#define OMAP5_AUXCOREBOOT0_OFFSET (SAR_BANK3_OFFSET + 0xa2c)
+#define OMAP5_AUXCOREBOOT1_OFFSET (SAR_BANK3_OFFSET + 0x930)
+#define OMAP5_AMBA_IF_MODE_OFFSET (SAR_BANK3_OFFSET + 0xa34)
+#define OMAP5_SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x800)
+
+#endif
diff --git a/arch/arm/mach-omap2/omap44xx.h b/arch/arm/mach-omap2/omap44xx.h
new file mode 100644
index 000000000..8a515bb74
--- /dev/null
+++ b/arch/arm/mach-omap2/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_IRQ_GIC_START 32
+#define OMAP44XX_LOCAL_TWD_BASE 0x48240600
+#define OMAP44XX_L2CACHE_BASE 0x48242000
+#define OMAP44XX_WKUPGEN_BASE 0x48281000
+#define OMAP44XX_MCPDM_BASE 0x40132000
+#define OMAP44XX_SAR_RAM_BASE 0x4a326000
+
+#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/mach-omap2/omap54xx.h b/arch/arm/mach-omap2/omap54xx.h
new file mode 100644
index 000000000..2d35c5709
--- /dev/null
+++ b/arch/arm/mach-omap2/omap54xx.h
@@ -0,0 +1,37 @@
+/*:
+ * Address mappings and base address for OMAP5 interconnects
+ * and peripherals.
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_SOC_OMAP54XX_H
+#define __ASM_SOC_OMAP54XX_H
+
+/*
+ * Please place only base defines here and put the rest in device
+ * specific headers.
+ */
+#define L4_54XX_BASE 0x4a000000
+#define L4_WK_54XX_BASE 0x4ae00000
+#define L4_PER_54XX_BASE 0x48000000
+#define L3_54XX_BASE 0x44000000
+#define OMAP54XX_32KSYNCT_BASE 0x4ae04000
+#define OMAP54XX_CM_CORE_AON_BASE 0x4a004000
+#define OMAP54XX_CM_CORE_BASE 0x4a008000
+#define OMAP54XX_PRM_BASE 0x4ae06000
+#define OMAP54XX_PRCM_MPU_BASE 0x48243000
+#define OMAP54XX_SCM_BASE 0x4a002000
+#define OMAP54XX_CTRL_BASE 0x4a002800
+#define OMAP54XX_SAR_RAM_BASE 0x4ae26000
+
+#define DRA7XX_CM_CORE_AON_BASE 0x4a005000
+#define DRA7XX_CTRL_BASE 0x4a003400
+#define DRA7XX_TAP_BASE 0x4ae0c000
+
+#endif /* __ASM_SOC_OMAP555554XX_H */
diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
new file mode 100644
index 000000000..166b18f51
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_device.c
@@ -0,0 +1,929 @@
+/*
+ * 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 be implemented as a
+ * proper omap_bus/omap_device in Linux, no more platform_data func
+ * pointers
+ *
+ *
+ */
+#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 <linux/of.h>
+#include <linux/notifier.h>
+
+#include "common.h"
+#include "soc.h"
+#include "omap_device.h"
+#include "omap_hwmod.h"
+
+/* Private functions */
+
+static void _add_clkdev(struct omap_device *od, const char *clk_alias,
+ const char *clk_name)
+{
+ struct clk *r;
+ struct clk_lookup *l;
+
+ if (!clk_alias || !clk_name)
+ return;
+
+ dev_dbg(&od->pdev->dev, "Creating %s -> %s\n", clk_alias, clk_name);
+
+ r = clk_get_sys(dev_name(&od->pdev->dev), clk_alias);
+ if (!IS_ERR(r)) {
+ dev_dbg(&od->pdev->dev,
+ "alias %s already exists\n", clk_alias);
+ clk_put(r);
+ return;
+ }
+
+ r = clk_get(NULL, clk_name);
+ if (IS_ERR(r)) {
+ dev_err(&od->pdev->dev,
+ "clk_get for %s failed\n", clk_name);
+ return;
+ }
+
+ l = clkdev_alloc(r, clk_alias, dev_name(&od->pdev->dev));
+ if (!l) {
+ dev_err(&od->pdev->dev,
+ "clkdev_alloc for %s failed\n", clk_alias);
+ return;
+ }
+
+ clkdev_add(l);
+}
+
+/**
+ * _add_hwmod_clocks_clkdev - Add clkdev entry for hwmod optional clocks
+ * and main clock
+ * @od: struct omap_device *od
+ * @oh: struct omap_hwmod *oh
+ *
+ * For the main clock and 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>).
+ * In the case of the main clock, a "fck" alias is used.
+ *
+ * No return value.
+ */
+static void _add_hwmod_clocks_clkdev(struct omap_device *od,
+ struct omap_hwmod *oh)
+{
+ int i;
+
+ _add_clkdev(od, "fck", oh->main_clk);
+
+ for (i = 0; i < oh->opt_clks_cnt; i++)
+ _add_clkdev(od, oh->opt_clks[i].role, oh->opt_clks[i].clk);
+}
+
+
+/**
+ * omap_device_build_from_dt - build 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
+ *
+ * Function for building an omap_device already registered from device-tree
+ *
+ * Returns 0 or PTR_ERR() on error.
+ */
+static int omap_device_build_from_dt(struct platform_device *pdev)
+{
+ struct omap_hwmod **hwmods;
+ struct omap_device *od;
+ struct omap_hwmod *oh;
+ struct device_node *node = pdev->dev.of_node;
+ const char *oh_name;
+ int oh_cnt, i, ret = 0;
+ bool device_active = false;
+
+ oh_cnt = of_property_count_strings(node, "ti,hwmods");
+ if (oh_cnt <= 0) {
+ dev_dbg(&pdev->dev, "No 'hwmods' to build omap_device\n");
+ return -ENODEV;
+ }
+
+ hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL);
+ if (!hwmods) {
+ ret = -ENOMEM;
+ goto odbfd_exit;
+ }
+
+ for (i = 0; i < oh_cnt; i++) {
+ of_property_read_string_index(node, "ti,hwmods", i, &oh_name);
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ dev_err(&pdev->dev, "Cannot lookup hwmod '%s'\n",
+ oh_name);
+ ret = -EINVAL;
+ goto odbfd_exit1;
+ }
+ hwmods[i] = oh;
+ if (oh->flags & HWMOD_INIT_NO_IDLE)
+ device_active = true;
+ }
+
+ od = omap_device_alloc(pdev, hwmods, oh_cnt);
+ if (IS_ERR(od)) {
+ dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n",
+ oh_name);
+ ret = PTR_ERR(od);
+ goto odbfd_exit1;
+ }
+
+ /* Fix up missing resource names */
+ for (i = 0; i < pdev->num_resources; i++) {
+ struct resource *r = &pdev->resource[i];
+
+ if (r->name == NULL)
+ r->name = dev_name(&pdev->dev);
+ }
+
+ pdev->dev.pm_domain = &omap_device_pm_domain;
+
+ if (device_active) {
+ omap_device_enable(pdev);
+ pm_runtime_set_active(&pdev->dev);
+ }
+
+odbfd_exit1:
+ kfree(hwmods);
+odbfd_exit:
+ /* if data/we are at fault.. load up a fail handler */
+ if (ret)
+ pdev->dev.pm_domain = &omap_device_fail_pm_domain;
+
+ return ret;
+}
+
+static int _omap_device_notifier_call(struct notifier_block *nb,
+ unsigned long event, void *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct omap_device *od;
+
+ switch (event) {
+ case BUS_NOTIFY_DEL_DEVICE:
+ if (pdev->archdata.od)
+ omap_device_delete(pdev->archdata.od);
+ break;
+ case BUS_NOTIFY_ADD_DEVICE:
+ if (pdev->dev.of_node)
+ omap_device_build_from_dt(pdev);
+ omap_auxdata_legacy_init(dev);
+ /* fall through */
+ default:
+ od = to_omap_device(pdev);
+ if (od)
+ od->_driver_status = event;
+ }
+
+ return NOTIFY_DONE;
+}
+
+/**
+ * _omap_device_enable_hwmods - call omap_hwmod_enable() on all hwmods
+ * @od: struct omap_device *od
+ *
+ * Enable all underlying hwmods. Returns 0.
+ */
+static 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.
+ */
+static 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;
+}
+
+/* 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.
+ */
+int omap_device_get_context_loss_count(struct platform_device *pdev)
+{
+ struct omap_device *od;
+ u32 ret = 0;
+
+ od = to_omap_device(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 *
+ * @flags: Type of resources to include when counting (IRQ/DMA/MEM)
+ *
+ * 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.
+ */
+static int omap_device_count_resources(struct omap_device *od,
+ unsigned long flags)
+{
+ int c = 0;
+ int i;
+
+ for (i = 0; i < od->hwmods_cnt; i++)
+ c += omap_hwmod_count_resources(od->hwmods[i], flags);
+
+ 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.
+ */
+static int omap_device_fill_resources(struct omap_device *od,
+ struct resource *res)
+{
+ int i, r;
+
+ for (i = 0; i < od->hwmods_cnt; i++) {
+ r = omap_hwmod_fill_resources(od->hwmods[i], res);
+ res += r;
+ }
+
+ return 0;
+}
+
+/**
+ * _od_fill_dma_resources - fill in array of struct resource with dma resources
+ * @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 dma resource data for this omap_device @od. Used by
+ * omap_device_alloc() after calling omap_device_count_resources().
+ *
+ * Ideally this function would not be needed at all. If we have
+ * mechanism to get dma resources from DT.
+ *
+ * Returns 0.
+ */
+static int _od_fill_dma_resources(struct omap_device *od,
+ struct resource *res)
+{
+ int i, r;
+
+ for (i = 0; i < od->hwmods_cnt; i++) {
+ r = omap_hwmod_fill_dma_resources(od->hwmods[i], res);
+ res += r;
+ }
+
+ return 0;
+}
+
+/**
+ * omap_device_alloc - allocate an omap_device
+ * @pdev: platform_device that will be included in this omap_device
+ * @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
+ *
+ * Convenience function for allocating an omap_device structure and filling
+ * hwmods, and resources.
+ *
+ * Returns an struct omap_device pointer or ERR_PTR() on error;
+ */
+struct omap_device *omap_device_alloc(struct platform_device *pdev,
+ struct omap_hwmod **ohs, int oh_cnt)
+{
+ int ret = -ENOMEM;
+ struct omap_device *od;
+ struct resource *res = NULL;
+ int i, res_count;
+ struct omap_hwmod **hwmods;
+
+ od = kzalloc(sizeof(struct omap_device), GFP_KERNEL);
+ if (!od) {
+ ret = -ENOMEM;
+ goto oda_exit1;
+ }
+ od->hwmods_cnt = oh_cnt;
+
+ hwmods = kmemdup(ohs, sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL);
+ if (!hwmods)
+ goto oda_exit2;
+
+ od->hwmods = hwmods;
+ od->pdev = pdev;
+
+ /*
+ * Non-DT Boot:
+ * Here, pdev->num_resources = 0, and we should get all the
+ * resources from hwmod.
+ *
+ * DT Boot:
+ * OF framework will construct the resource structure (currently
+ * does for MEM & IRQ resource) and we should respect/use these
+ * resources, killing hwmod dependency.
+ * If pdev->num_resources > 0, we assume that MEM & IRQ resources
+ * have been allocated by OF layer already (through DTB).
+ * As preparation for the future we examine the OF provided resources
+ * to see if we have DMA resources provided already. In this case
+ * there is no need to update the resources for the device, we use the
+ * OF provided ones.
+ *
+ * TODO: Once DMA resource is available from OF layer, we should
+ * kill filling any resources from hwmod.
+ */
+ if (!pdev->num_resources) {
+ /* Count all resources for the device */
+ res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
+ IORESOURCE_DMA |
+ IORESOURCE_MEM);
+ } else {
+ /* Take a look if we already have DMA resource via DT */
+ for (i = 0; i < pdev->num_resources; i++) {
+ struct resource *r = &pdev->resource[i];
+
+ /* We have it, no need to touch the resources */
+ if (r->flags == IORESOURCE_DMA)
+ goto have_everything;
+ }
+ /* Count only DMA resources for the device */
+ res_count = omap_device_count_resources(od, IORESOURCE_DMA);
+ /* The device has no DMA resource, no need for update */
+ if (!res_count)
+ goto have_everything;
+
+ res_count += pdev->num_resources;
+ }
+
+ /* Allocate resources memory to account for new resources */
+ res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
+ if (!res)
+ goto oda_exit3;
+
+ if (!pdev->num_resources) {
+ dev_dbg(&pdev->dev, "%s: using %d resources from hwmod\n",
+ __func__, res_count);
+ omap_device_fill_resources(od, res);
+ } else {
+ dev_dbg(&pdev->dev,
+ "%s: appending %d DMA resources from hwmod\n",
+ __func__, res_count - pdev->num_resources);
+ memcpy(res, pdev->resource,
+ sizeof(struct resource) * pdev->num_resources);
+ _od_fill_dma_resources(od, &res[pdev->num_resources]);
+ }
+
+ ret = platform_device_add_resources(pdev, res, res_count);
+ kfree(res);
+
+ if (ret)
+ goto oda_exit3;
+
+have_everything:
+ pdev->archdata.od = od;
+
+ for (i = 0; i < oh_cnt; i++) {
+ hwmods[i]->od = od;
+ _add_hwmod_clocks_clkdev(od, hwmods[i]);
+ }
+
+ return od;
+
+oda_exit3:
+ kfree(hwmods);
+oda_exit2:
+ kfree(od);
+oda_exit1:
+ dev_err(&pdev->dev, "omap_device: build failed (%d)\n", ret);
+
+ return ERR_PTR(ret);
+}
+
+void omap_device_delete(struct omap_device *od)
+{
+ if (!od)
+ return;
+
+ od->pdev->archdata.od = NULL;
+ kfree(od->hwmods);
+ kfree(od);
+}
+
+/**
+ * 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
+ *
+ * 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 platform_device __init *omap_device_build(const char *pdev_name,
+ int pdev_id,
+ struct omap_hwmod *oh,
+ void *pdata, int pdata_len)
+{
+ 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);
+}
+
+/**
+ * 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
+ *
+ * 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 platform_device __init *omap_device_build_ss(const char *pdev_name,
+ int pdev_id,
+ struct omap_hwmod **ohs,
+ int oh_cnt, void *pdata,
+ int pdata_len)
+{
+ int ret = -ENOMEM;
+ struct platform_device *pdev;
+ struct omap_device *od;
+
+ if (!ohs || oh_cnt == 0 || !pdev_name)
+ return ERR_PTR(-EINVAL);
+
+ if (!pdata && pdata_len > 0)
+ return ERR_PTR(-EINVAL);
+
+ pdev = platform_device_alloc(pdev_name, pdev_id);
+ if (!pdev) {
+ ret = -ENOMEM;
+ goto odbs_exit;
+ }
+
+ /* Set the dev_name early to allow dev_xxx in omap_device_alloc */
+ if (pdev->id != -1)
+ dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
+ else
+ dev_set_name(&pdev->dev, "%s", pdev->name);
+
+ od = omap_device_alloc(pdev, ohs, oh_cnt);
+ if (IS_ERR(od))
+ goto odbs_exit1;
+
+ ret = platform_device_add_data(pdev, pdata, pdata_len);
+ if (ret)
+ goto odbs_exit2;
+
+ ret = omap_device_register(pdev);
+ if (ret)
+ goto odbs_exit2;
+
+ return pdev;
+
+odbs_exit2:
+ omap_device_delete(od);
+odbs_exit1:
+ platform_device_put(pdev);
+odbs_exit:
+
+ pr_err("omap_device: %s: build failed (%d)\n", pdev_name, ret);
+
+ return ERR_PTR(ret);
+}
+
+#ifdef CONFIG_PM
+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_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ omap_device_enable(pdev);
+
+ return pm_generic_runtime_resume(dev);
+}
+
+static int _od_fail_runtime_suspend(struct device *dev)
+{
+ dev_warn(dev, "%s: FIXME: missing hwmod/omap_dev info\n", __func__);
+ return -ENODEV;
+}
+
+static int _od_fail_runtime_resume(struct device *dev)
+{
+ dev_warn(dev, "%s: FIXME: missing hwmod/omap_dev info\n", __func__);
+ return -ENODEV;
+}
+
+#endif
+
+#ifdef CONFIG_SUSPEND
+static int _od_suspend_noirq(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct omap_device *od = to_omap_device(pdev);
+ int ret;
+
+ /* Don't attempt late suspend on a driver that is not bound */
+ if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER)
+ return 0;
+
+ ret = pm_generic_suspend_noirq(dev);
+
+ if (!ret && !pm_runtime_status_suspended(dev)) {
+ if (pm_generic_runtime_suspend(dev) == 0) {
+ pm_runtime_set_suspended(dev);
+ omap_device_idle(pdev);
+ od->flags |= OMAP_DEVICE_SUSPENDED;
+ }
+ }
+
+ return ret;
+}
+
+static int _od_resume_noirq(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct omap_device *od = to_omap_device(pdev);
+
+ if (od->flags & OMAP_DEVICE_SUSPENDED) {
+ od->flags &= ~OMAP_DEVICE_SUSPENDED;
+ omap_device_enable(pdev);
+ /*
+ * XXX: we run before core runtime pm has resumed itself. At
+ * this point in time, we just restore the runtime pm state and
+ * considering symmetric operations in resume, we donot expect
+ * to fail. If we failed, something changed in core runtime_pm
+ * framework OR some device driver messed things up, hence, WARN
+ */
+ WARN(pm_runtime_set_active(dev),
+ "Could not set %s runtime state active\n", dev_name(dev));
+ pm_generic_runtime_resume(dev);
+ }
+
+ return pm_generic_resume_noirq(dev);
+}
+#else
+#define _od_suspend_noirq NULL
+#define _od_resume_noirq NULL
+#endif
+
+struct dev_pm_domain omap_device_fail_pm_domain = {
+ .ops = {
+ SET_RUNTIME_PM_OPS(_od_fail_runtime_suspend,
+ _od_fail_runtime_resume, NULL)
+ }
+};
+
+struct dev_pm_domain omap_device_pm_domain = {
+ .ops = {
+ SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume,
+ NULL)
+ USE_PLATFORM_PM_SLEEP_OPS
+ .suspend_noirq = _od_suspend_noirq,
+ .resume_noirq = _od_resume_noirq,
+ .freeze_noirq = _od_suspend_noirq,
+ .thaw_noirq = _od_resume_noirq,
+ .restore_noirq = _od_resume_noirq,
+ }
+};
+
+/**
+ * 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 platform_device *pdev)
+{
+ pr_debug("omap_device: %s: registering\n", pdev->name);
+
+ pdev->dev.pm_domain = &omap_device_pm_domain;
+ return platform_device_add(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
+ * indirectly via pm_runtime_get*(). Returns -EINVAL if called when
+ * the omap_device is already enabled, or passes along the return
+ * value of _omap_device_enable_hwmods().
+ */
+int omap_device_enable(struct platform_device *pdev)
+{
+ int ret;
+ struct omap_device *od;
+
+ od = to_omap_device(pdev);
+
+ if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
+ dev_warn(&pdev->dev,
+ "omap_device: %s() called from invalid state %d\n",
+ __func__, od->_state);
+ return -EINVAL;
+ }
+
+ ret = _omap_device_enable_hwmods(od);
+
+ 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. Device drivers call this function indirectly
+ * via pm_runtime_put*(). Returns -EINVAL if the omap_device is not
+ * currently enabled, or passes along the return value of
+ * _omap_device_idle_hwmods().
+ */
+int omap_device_idle(struct platform_device *pdev)
+{
+ int ret;
+ struct omap_device *od;
+
+ od = to_omap_device(pdev);
+
+ if (od->_state != OMAP_DEVICE_STATE_ENABLED) {
+ dev_warn(&pdev->dev,
+ "omap_device: %s() called from invalid state %d\n",
+ __func__, od->_state);
+ return -EINVAL;
+ }
+
+ ret = _omap_device_idle_hwmods(od);
+
+ od->_state = OMAP_DEVICE_STATE_IDLE;
+
+ return ret;
+}
+
+/**
+ * omap_device_assert_hardreset - set a device's hardreset line
+ * @pdev: struct platform_device * to reset
+ * @name: const char * name of the reset line
+ *
+ * Set the hardreset line identified by @name on the IP blocks
+ * associated with the hwmods backing the platform_device @pdev. All
+ * of the hwmods associated with @pdev must have the same hardreset
+ * line linked to them for this to work. Passes along the return value
+ * of omap_hwmod_assert_hardreset() in the event of any failure, or
+ * returns 0 upon success.
+ */
+int omap_device_assert_hardreset(struct platform_device *pdev, const char *name)
+{
+ struct omap_device *od = to_omap_device(pdev);
+ int ret = 0;
+ int i;
+
+ for (i = 0; i < od->hwmods_cnt; i++) {
+ ret = omap_hwmod_assert_hardreset(od->hwmods[i], name);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * omap_device_deassert_hardreset - release a device's hardreset line
+ * @pdev: struct platform_device * to reset
+ * @name: const char * name of the reset line
+ *
+ * Release the hardreset line identified by @name on the IP blocks
+ * associated with the hwmods backing the platform_device @pdev. All
+ * of the hwmods associated with @pdev must have the same hardreset
+ * line linked to them for this to work. Passes along the return
+ * value of omap_hwmod_deassert_hardreset() in the event of any
+ * failure, or returns 0 upon success.
+ */
+int omap_device_deassert_hardreset(struct platform_device *pdev,
+ const char *name)
+{
+ struct omap_device *od = to_omap_device(pdev);
+ int ret = 0;
+ int i;
+
+ for (i = 0; i < od->hwmods_cnt; i++) {
+ ret = omap_hwmod_deassert_hardreset(od->hwmods[i], name);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * omap_device_get_by_hwmod_name() - convert a hwmod name to
+ * device pointer.
+ * @oh_name: name of the hwmod device
+ *
+ * Returns back a struct device * pointer associated with a hwmod
+ * device represented by a hwmod_name
+ */
+struct device *omap_device_get_by_hwmod_name(const char *oh_name)
+{
+ struct omap_hwmod *oh;
+
+ if (!oh_name) {
+ WARN(1, "%s: no hwmod name!\n", __func__);
+ return ERR_PTR(-EINVAL);
+ }
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ WARN(1, "%s: no hwmod for %s\n", __func__,
+ oh_name);
+ return ERR_PTR(-ENODEV);
+ }
+ if (!oh->od) {
+ WARN(1, "%s: no omap_device for %s\n", __func__,
+ oh_name);
+ return ERR_PTR(-ENODEV);
+ }
+
+ return &oh->od->pdev->dev;
+}
+
+static struct notifier_block platform_nb = {
+ .notifier_call = _omap_device_notifier_call,
+};
+
+static int __init omap_device_init(void)
+{
+ bus_register_notifier(&platform_bus_type, &platform_nb);
+ return 0;
+}
+omap_core_initcall(omap_device_init);
+
+/**
+ * omap_device_late_idle - idle devices without drivers
+ * @dev: struct device * associated with omap_device
+ * @data: unused
+ *
+ * Check the driver bound status of this device, and idle it
+ * if there is no driver attached.
+ */
+static int __init omap_device_late_idle(struct device *dev, void *data)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct omap_device *od = to_omap_device(pdev);
+ int i;
+
+ if (!od)
+ return 0;
+
+ /*
+ * If omap_device state is enabled, but has no driver bound,
+ * idle it.
+ */
+
+ /*
+ * Some devices (like memory controllers) are always kept
+ * enabled, and should not be idled even with no drivers.
+ */
+ for (i = 0; i < od->hwmods_cnt; i++)
+ if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE)
+ return 0;
+
+ if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
+ if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
+ dev_warn(dev, "%s: enabled but no driver. Idling\n",
+ __func__);
+ omap_device_idle(pdev);
+ }
+ }
+
+ return 0;
+}
+
+static int __init omap_device_late_init(void)
+{
+ bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle);
+
+ WARN(!of_have_populated_dt(),
+ "legacy booting deprecated, please update to boot with .dts\n");
+
+ return 0;
+}
+omap_late_initcall_sync(omap_device_late_init);
diff --git a/arch/arm/mach-omap2/omap_device.h b/arch/arm/mach-omap2/omap_device.h
new file mode 100644
index 000000000..78c02b355
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_device.h
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ *
+ * This type of functionality should be implemented as a proper
+ * omap_bus/omap_device in Linux.
+ *
+ * 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.
+ */
+#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 "omap_hwmod.h"
+
+extern struct dev_pm_domain omap_device_pm_domain;
+extern struct dev_pm_domain omap_device_fail_pm_domain;
+
+/* 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
+
+/* omap_device.flags values */
+#define OMAP_DEVICE_SUSPENDED BIT(0)
+
+/**
+ * struct omap_device - omap_device wrapper for platform_devices
+ * @pdev: platform_device
+ * @hwmods: (one .. many per omap_device)
+ * @hwmods_cnt: ARRAY_SIZE() of @hwmods
+ * @_state: one of OMAP_DEVICE_STATE_* (see above)
+ * @flags: device flags
+ * @_driver_status: one of BUS_NOTIFY_*_DRIVER from <linux/device.h>
+ *
+ * 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;
+ unsigned long _driver_status;
+ u8 hwmods_cnt;
+ u8 _state;
+ u8 flags;
+};
+
+/* 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);
+
+/* Core code interface */
+
+struct platform_device *omap_device_build(const char *pdev_name, int pdev_id,
+ struct omap_hwmod *oh, void *pdata,
+ int pdata_len);
+
+struct platform_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 *omap_device_alloc(struct platform_device *pdev,
+ struct omap_hwmod **ohs, int oh_cnt);
+void omap_device_delete(struct omap_device *od);
+int omap_device_register(struct platform_device *pdev);
+
+struct device *omap_device_get_by_hwmod_name(const char *oh_name);
+
+/* OMAP PM interface */
+int omap_device_get_context_loss_count(struct platform_device *pdev);
+
+/* Other */
+
+int omap_device_assert_hardreset(struct platform_device *pdev,
+ const char *name);
+int omap_device_deassert_hardreset(struct platform_device *pdev,
+ const char *name);
+
+/* Get omap_device pointer from platform_device pointer */
+static inline struct omap_device *to_omap_device(struct platform_device *pdev)
+{
+ return pdev ? pdev->archdata.od : NULL;
+}
+#endif
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
new file mode 100644
index 000000000..752969ff9
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -0,0 +1,3907 @@
+/*
+ * omap_hwmod implementation for OMAP2/3/4
+ *
+ * Copyright (C) 2009-2011 Nokia Corporation
+ * Copyright (C) 2011-2012 Texas Instruments, Inc.
+ *
+ * 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 |
+ * | ({read,write}l_relaxed, 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-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/bootmem.h>
+#include <linux/cpu.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/system_misc.h>
+
+#include "clock.h"
+#include "omap_hwmod.h"
+
+#include "soc.h"
+#include "common.h"
+#include "clockdomain.h"
+#include "powerdomain.h"
+#include "cm2xxx.h"
+#include "cm3xxx.h"
+#include "cm33xx.h"
+#include "prm.h"
+#include "prm3xxx.h"
+#include "prm44xx.h"
+#include "prm33xx.h"
+#include "prminst44xx.h"
+#include "mux.h"
+#include "pm.h"
+
+/* Name of the OMAP hwmod for the MPU */
+#define MPU_INITIATOR_NAME "mpu"
+
+/*
+ * Number of struct omap_hwmod_link records per struct
+ * omap_hwmod_ocp_if record (master->slave and slave->master)
+ */
+#define LINKS_PER_OCP_IF 2
+
+/*
+ * Address offset (in bytes) between the reset control and the reset
+ * status registers: 4 bytes on OMAP4
+ */
+#define OMAP4_RST_CTRL_ST_OFFSET 4
+
+/**
+ * struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations
+ * @enable_module: function to enable a module (via MODULEMODE)
+ * @disable_module: function to disable a module (via MODULEMODE)
+ *
+ * XXX Eventually this functionality will be hidden inside the PRM/CM
+ * device drivers. Until then, this should avoid huge blocks of cpu_is_*()
+ * conditionals in this code.
+ */
+struct omap_hwmod_soc_ops {
+ void (*enable_module)(struct omap_hwmod *oh);
+ int (*disable_module)(struct omap_hwmod *oh);
+ int (*wait_target_ready)(struct omap_hwmod *oh);
+ int (*assert_hardreset)(struct omap_hwmod *oh,
+ struct omap_hwmod_rst_info *ohri);
+ int (*deassert_hardreset)(struct omap_hwmod *oh,
+ struct omap_hwmod_rst_info *ohri);
+ int (*is_hardreset_asserted)(struct omap_hwmod *oh,
+ struct omap_hwmod_rst_info *ohri);
+ int (*init_clkdm)(struct omap_hwmod *oh);
+ void (*update_context_lost)(struct omap_hwmod *oh);
+ int (*get_context_lost)(struct omap_hwmod *oh);
+};
+
+/* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
+static struct omap_hwmod_soc_ops soc_ops;
+
+/* 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;
+
+/* io_chain_lock: used to serialize reconfigurations of the I/O chain */
+static DEFINE_SPINLOCK(io_chain_lock);
+
+/*
+ * linkspace: ptr to a buffer that struct omap_hwmod_link records are
+ * allocated from - used to reduce the number of small memory
+ * allocations, which has a significant impact on performance
+ */
+static struct omap_hwmod_link *linkspace;
+
+/*
+ * free_ls, max_ls: array indexes into linkspace; representing the
+ * next free struct omap_hwmod_link index, and the maximum number of
+ * struct omap_hwmod_link records allocated (respectively)
+ */
+static unsigned short free_ls, max_ls, ls_supp;
+
+/* inited: set to true once the hwmod code is initialized */
+static bool inited;
+
+/* Private functions */
+
+/**
+ * _fetch_next_ocp_if - return the next OCP interface in a list
+ * @p: ptr to a ptr to the list_head inside the ocp_if to return
+ * @i: pointer to the index of the element pointed to by @p in the list
+ *
+ * Return a pointer to the struct omap_hwmod_ocp_if record
+ * containing the struct list_head pointed to by @p, and increment
+ * @p such that a future call to this routine will return the next
+ * record.
+ */
+static struct omap_hwmod_ocp_if *_fetch_next_ocp_if(struct list_head **p,
+ int *i)
+{
+ struct omap_hwmod_ocp_if *oi;
+
+ oi = list_entry(*p, struct omap_hwmod_link, node)->ocp_if;
+ *p = (*p)->next;
+
+ *i = *i + 1;
+
+ return oi;
+}
+
+/**
+ * _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.SOFTRESET bit 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;
+}
+
+/**
+ * _clear_softreset: clear OCP_SYSCONFIG.SOFTRESET bit in @v
+ * @oh: struct omap_hwmod *
+ * @v: pointer to register contents to modify
+ *
+ * Clear the SOFTRESET bit in @v for hwmod @oh. Returns -EINVAL upon
+ * error or 0 upon success.
+ */
+static int _clear_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: sysc_fields absent for sysconfig class\n",
+ oh->name);
+ return -EINVAL;
+ }
+
+ softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
+
+ *v &= ~softrst_mask;
+
+ return 0;
+}
+
+/**
+ * _wait_softreset_complete - wait for an OCP softreset to complete
+ * @oh: struct omap_hwmod * to wait on
+ *
+ * Wait until the IP block represented by @oh reports that its OCP
+ * softreset is complete. This can be triggered by software (see
+ * _ocp_softreset()) or by hardware upon returning from off-mode (one
+ * example is HSMMC). Waits for up to MAX_MODULE_SOFTRESET_WAIT
+ * microseconds. Returns the number of microseconds waited.
+ */
+static int _wait_softreset_complete(struct omap_hwmod *oh)
+{
+ struct omap_hwmod_class_sysconfig *sysc;
+ u32 softrst_mask;
+ int c = 0;
+
+ sysc = oh->class->sysc;
+
+ if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
+ omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs)
+ & SYSS_RESETDONE_MASK),
+ MAX_MODULE_SOFTRESET_WAIT, c);
+ else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
+ softrst_mask = (0x1 << sysc->sysc_fields->srst_shift);
+ omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs)
+ & softrst_mask),
+ MAX_MODULE_SOFTRESET_WAIT, c);
+ }
+
+ return c;
+}
+
+/**
+ * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v
+ * @oh: struct omap_hwmod *
+ *
+ * The DMADISABLE bit is a semi-automatic bit present in sysconfig register
+ * of some modules. When the DMA must perform read/write accesses, the
+ * DMADISABLE bit is cleared by the hardware. But when the DMA must stop
+ * for power management, software must set the DMADISABLE bit back to 1.
+ *
+ * Set the DMADISABLE bit in @v for hwmod @oh. Returns -EINVAL upon
+ * error or 0 upon success.
+ */
+static int _set_dmadisable(struct omap_hwmod *oh)
+{
+ u32 v;
+ u32 dmadisable_mask;
+
+ if (!oh->class->sysc ||
+ !(oh->class->sysc->sysc_flags & SYSC_HAS_DMADISABLE))
+ 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;
+ }
+
+ /* clocks must be on for this operation */
+ if (oh->_state != _HWMOD_STATE_ENABLED) {
+ pr_warn("omap_hwmod: %s: dma can be disabled only from enabled state\n", oh->name);
+ return -EINVAL;
+ }
+
+ pr_debug("omap_hwmod: %s: setting DMADISABLE\n", oh->name);
+
+ v = oh->_sysc_cache;
+ dmadisable_mask =
+ (0x1 << oh->class->sysc->sysc_fields->dmadisable_shift);
+ v |= dmadisable_mask;
+ _write_sysconfig(v, oh);
+
+ 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;
+}
+
+/**
+ * _set_idle_ioring_wakeup - enable/disable IO pad wakeup on hwmod idle for mux
+ * @oh: struct omap_hwmod *
+ * @set_wake: bool value indicating to set (true) or clear (false) wakeup enable
+ *
+ * Set or clear the I/O pad wakeup flag in the mux entries for the
+ * hwmod @oh. This function changes the @oh->mux->pads_dynamic array
+ * in memory. If the hwmod is currently idled, and the new idle
+ * values don't match the previous ones, this function will also
+ * update the SCM PADCTRL registers. Otherwise, if the hwmod is not
+ * currently idled, this function won't touch the hardware: the new
+ * mux settings are written to the SCM PADCTRL registers when the
+ * hwmod is idled. No return value.
+ */
+static void _set_idle_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
+{
+ struct omap_device_pad *pad;
+ bool change = false;
+ u16 prev_idle;
+ int j;
+
+ if (!oh->mux || !oh->mux->enabled)
+ return;
+
+ for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
+ pad = oh->mux->pads_dynamic[j];
+
+ if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP))
+ continue;
+
+ prev_idle = pad->idle;
+
+ if (set_wake)
+ pad->idle |= OMAP_WAKEUP_EN;
+ else
+ pad->idle &= ~OMAP_WAKEUP_EN;
+
+ if (prev_idle != pad->idle)
+ change = true;
+ }
+
+ if (change && oh->_state == _HWMOD_STATE_IDLE)
+ omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
+}
+
+/**
+ * _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)
+{
+ if (!oh->class->sysc ||
+ !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
+ (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) ||
+ (oh->class->sysc->idlemodes & MSTANDBY_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;
+ }
+
+ if (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)
+ *v |= 0x1 << oh->class->sysc->sysc_fields->enwkup_shift;
+
+ if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
+ _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
+ if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
+ _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
+
+ /* XXX test pwrdm_get_wken for this hwmod's subsystem */
+
+ 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)
+{
+ if (!oh->class->sysc ||
+ !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
+ (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) ||
+ (oh->class->sysc->idlemodes & MSTANDBY_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;
+ }
+
+ if (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)
+ *v &= ~(0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
+
+ if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
+ _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v);
+ if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
+ _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART, v);
+
+ /* XXX test pwrdm_get_wken for this hwmod's subsystem */
+
+ return 0;
+}
+
+static struct clockdomain *_get_clkdm(struct omap_hwmod *oh)
+{
+ struct clk_hw_omap *clk;
+
+ if (oh->clkdm) {
+ return oh->clkdm;
+ } else if (oh->_clk) {
+ if (__clk_get_flags(oh->_clk) & CLK_IS_BASIC)
+ return NULL;
+ clk = to_clk_hw_omap(__clk_get_hw(oh->_clk));
+ return clk->clkdm;
+ }
+ return NULL;
+}
+
+/**
+ * _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)
+{
+ struct clockdomain *clkdm, *init_clkdm;
+
+ clkdm = _get_clkdm(oh);
+ init_clkdm = _get_clkdm(init_oh);
+
+ if (!clkdm || !init_clkdm)
+ return -EINVAL;
+
+ if (clkdm && clkdm->flags & CLKDM_NO_AUTODEPS)
+ return 0;
+
+ return clkdm_add_sleepdep(clkdm, init_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)
+{
+ struct clockdomain *clkdm, *init_clkdm;
+
+ clkdm = _get_clkdm(oh);
+ init_clkdm = _get_clkdm(init_oh);
+
+ if (!clkdm || !init_clkdm)
+ return -EINVAL;
+
+ if (clkdm && clkdm->flags & CLKDM_NO_AUTODEPS)
+ return 0;
+
+ return clkdm_del_sleepdep(clkdm, init_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 = clk_get(NULL, oh->main_clk);
+ if (IS_ERR(oh->_clk)) {
+ pr_warn("omap_hwmod: %s: cannot clk_get main_clk %s\n",
+ oh->name, oh->main_clk);
+ return -EINVAL;
+ }
+ /*
+ * HACK: This needs a re-visit once clk_prepare() is implemented
+ * to do something meaningful. Today its just a no-op.
+ * If clk_prepare() is used at some point to do things like
+ * voltage scaling etc, then this would have to be moved to
+ * some point where subsystems like i2c and pmic become
+ * available.
+ */
+ clk_prepare(oh->_clk);
+
+ if (!_get_clkdm(oh))
+ pr_debug("omap_hwmod: %s: missing clockdomain for %s.\n",
+ oh->name, oh->main_clk);
+
+ 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 omap_hwmod_ocp_if *os;
+ struct list_head *p;
+ struct clk *c;
+ int i = 0;
+ int ret = 0;
+
+ p = oh->slave_ports.next;
+
+ while (i < oh->slaves_cnt) {
+ os = _fetch_next_ocp_if(&p, &i);
+ if (!os->clk)
+ continue;
+
+ c = clk_get(NULL, os->clk);
+ if (IS_ERR(c)) {
+ pr_warn("omap_hwmod: %s: cannot clk_get interface_clk %s\n",
+ oh->name, os->clk);
+ ret = -EINVAL;
+ continue;
+ }
+ os->_clk = c;
+ /*
+ * HACK: This needs a re-visit once clk_prepare() is implemented
+ * to do something meaningful. Today its just a no-op.
+ * If clk_prepare() is used at some point to do things like
+ * voltage scaling etc, then this would have to be moved to
+ * some point where subsystems like i2c and pmic become
+ * available.
+ */
+ clk_prepare(os->_clk);
+ }
+
+ 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 = clk_get(NULL, oc->clk);
+ if (IS_ERR(c)) {
+ pr_warn("omap_hwmod: %s: cannot clk_get opt_clk %s\n",
+ oh->name, oc->clk);
+ ret = -EINVAL;
+ continue;
+ }
+ oc->_clk = c;
+ /*
+ * HACK: This needs a re-visit once clk_prepare() is implemented
+ * to do something meaningful. Today its just a no-op.
+ * If clk_prepare() is used at some point to do things like
+ * voltage scaling etc, then this would have to be moved to
+ * some point where subsystems like i2c and pmic become
+ * available.
+ */
+ clk_prepare(oc->_clk);
+ }
+
+ 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)
+{
+ struct omap_hwmod_ocp_if *os;
+ struct list_head *p;
+ int i = 0;
+
+ pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name);
+
+ if (oh->_clk)
+ clk_enable(oh->_clk);
+
+ p = oh->slave_ports.next;
+
+ while (i < oh->slaves_cnt) {
+ os = _fetch_next_ocp_if(&p, &i);
+
+ if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE))
+ clk_enable(os->_clk);
+ }
+
+ /* 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)
+{
+ struct omap_hwmod_ocp_if *os;
+ struct list_head *p;
+ int i = 0;
+
+ pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name);
+
+ if (oh->_clk)
+ clk_disable(oh->_clk);
+
+ p = oh->slave_ports.next;
+
+ while (i < oh->slaves_cnt) {
+ os = _fetch_next_ocp_if(&p, &i);
+
+ if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE))
+ clk_disable(os->_clk);
+ }
+
+ /* 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,
+ __clk_get_name(oc->_clk));
+ 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,
+ __clk_get_name(oc->_clk));
+ clk_disable(oc->_clk);
+ }
+}
+
+/**
+ * _omap4_enable_module - enable CLKCTRL modulemode on OMAP4
+ * @oh: struct omap_hwmod *
+ *
+ * Enables the PRCM module mode related to the hwmod @oh.
+ * No return value.
+ */
+static void _omap4_enable_module(struct omap_hwmod *oh)
+{
+ if (!oh->clkdm || !oh->prcm.omap4.modulemode)
+ return;
+
+ pr_debug("omap_hwmod: %s: %s: %d\n",
+ oh->name, __func__, oh->prcm.omap4.modulemode);
+
+ omap_cm_module_enable(oh->prcm.omap4.modulemode,
+ oh->clkdm->prcm_partition,
+ oh->clkdm->cm_inst, oh->prcm.omap4.clkctrl_offs);
+}
+
+/**
+ * _omap4_wait_target_disable - wait for a module to be disabled on OMAP4
+ * @oh: struct omap_hwmod *
+ *
+ * Wait for a module @oh to enter slave idle. Returns 0 if the module
+ * does not have an IDLEST bit or if the module successfully enters
+ * slave idle; otherwise, pass along the return value of the
+ * appropriate *_cm*_wait_module_idle() function.
+ */
+static int _omap4_wait_target_disable(struct omap_hwmod *oh)
+{
+ if (!oh)
+ return -EINVAL;
+
+ if (oh->_int_flags & _HWMOD_NO_MPU_PORT || !oh->clkdm)
+ return 0;
+
+ if (oh->flags & HWMOD_NO_IDLEST)
+ return 0;
+
+ return omap_cm_wait_module_idle(oh->clkdm->prcm_partition,
+ oh->clkdm->cm_inst,
+ oh->prcm.omap4.clkctrl_offs, 0);
+}
+
+/**
+ * _count_mpu_irqs - count the number of MPU IRQ lines associated with @oh
+ * @oh: struct omap_hwmod *oh
+ *
+ * Count and return the number of MPU IRQs associated with the hwmod
+ * @oh. Used to allocate struct resource data. Returns 0 if @oh is
+ * NULL.
+ */
+static int _count_mpu_irqs(struct omap_hwmod *oh)
+{
+ struct omap_hwmod_irq_info *ohii;
+ int i = 0;
+
+ if (!oh || !oh->mpu_irqs)
+ return 0;
+
+ do {
+ ohii = &oh->mpu_irqs[i++];
+ } while (ohii->irq != -1);
+
+ return i-1;
+}
+
+/**
+ * _count_sdma_reqs - count the number of SDMA request lines associated with @oh
+ * @oh: struct omap_hwmod *oh
+ *
+ * Count and return the number of SDMA request lines associated with
+ * the hwmod @oh. Used to allocate struct resource data. Returns 0
+ * if @oh is NULL.
+ */
+static int _count_sdma_reqs(struct omap_hwmod *oh)
+{
+ struct omap_hwmod_dma_info *ohdi;
+ int i = 0;
+
+ if (!oh || !oh->sdma_reqs)
+ return 0;
+
+ do {
+ ohdi = &oh->sdma_reqs[i++];
+ } while (ohdi->dma_req != -1);
+
+ return i-1;
+}
+
+/**
+ * _count_ocp_if_addr_spaces - count the number of address space entries for @oh
+ * @oh: struct omap_hwmod *oh
+ *
+ * Count and return the number of address space ranges associated with
+ * the hwmod @oh. Used to allocate struct resource data. Returns 0
+ * if @oh is NULL.
+ */
+static int _count_ocp_if_addr_spaces(struct omap_hwmod_ocp_if *os)
+{
+ struct omap_hwmod_addr_space *mem;
+ int i = 0;
+
+ if (!os || !os->addr)
+ return 0;
+
+ do {
+ mem = &os->addr[i++];
+ } while (mem->pa_start != mem->pa_end);
+
+ return i-1;
+}
+
+/**
+ * _get_mpu_irq_by_name - fetch MPU interrupt line number by name
+ * @oh: struct omap_hwmod * to operate on
+ * @name: pointer to the name of the MPU interrupt number to fetch (optional)
+ * @irq: pointer to an unsigned int to store the MPU IRQ number to
+ *
+ * Retrieve a MPU hardware IRQ line number named by @name associated
+ * with the IP block pointed to by @oh. The IRQ number will be filled
+ * into the address pointed to by @dma. When @name is non-null, the
+ * IRQ line number associated with the named entry will be returned.
+ * If @name is null, the first matching entry will be returned. Data
+ * order is not meaningful in hwmod data, so callers are strongly
+ * encouraged to use a non-null @name whenever possible to avoid
+ * unpredictable effects if hwmod data is later added that causes data
+ * ordering to change. Returns 0 upon success or a negative error
+ * code upon error.
+ */
+static int _get_mpu_irq_by_name(struct omap_hwmod *oh, const char *name,
+ unsigned int *irq)
+{
+ int i;
+ bool found = false;
+
+ if (!oh->mpu_irqs)
+ return -ENOENT;
+
+ i = 0;
+ while (oh->mpu_irqs[i].irq != -1) {
+ if (name == oh->mpu_irqs[i].name ||
+ !strcmp(name, oh->mpu_irqs[i].name)) {
+ found = true;
+ break;
+ }
+ i++;
+ }
+
+ if (!found)
+ return -ENOENT;
+
+ *irq = oh->mpu_irqs[i].irq;
+
+ return 0;
+}
+
+/**
+ * _get_sdma_req_by_name - fetch SDMA request line ID by name
+ * @oh: struct omap_hwmod * to operate on
+ * @name: pointer to the name of the SDMA request line to fetch (optional)
+ * @dma: pointer to an unsigned int to store the request line ID to
+ *
+ * Retrieve an SDMA request line ID named by @name on the IP block
+ * pointed to by @oh. The ID will be filled into the address pointed
+ * to by @dma. When @name is non-null, the request line ID associated
+ * with the named entry will be returned. If @name is null, the first
+ * matching entry will be returned. Data order is not meaningful in
+ * hwmod data, so callers are strongly encouraged to use a non-null
+ * @name whenever possible to avoid unpredictable effects if hwmod
+ * data is later added that causes data ordering to change. Returns 0
+ * upon success or a negative error code upon error.
+ */
+static int _get_sdma_req_by_name(struct omap_hwmod *oh, const char *name,
+ unsigned int *dma)
+{
+ int i;
+ bool found = false;
+
+ if (!oh->sdma_reqs)
+ return -ENOENT;
+
+ i = 0;
+ while (oh->sdma_reqs[i].dma_req != -1) {
+ if (name == oh->sdma_reqs[i].name ||
+ !strcmp(name, oh->sdma_reqs[i].name)) {
+ found = true;
+ break;
+ }
+ i++;
+ }
+
+ if (!found)
+ return -ENOENT;
+
+ *dma = oh->sdma_reqs[i].dma_req;
+
+ return 0;
+}
+
+/**
+ * _get_addr_space_by_name - fetch address space start & end by name
+ * @oh: struct omap_hwmod * to operate on
+ * @name: pointer to the name of the address space to fetch (optional)
+ * @pa_start: pointer to a u32 to store the starting address to
+ * @pa_end: pointer to a u32 to store the ending address to
+ *
+ * Retrieve address space start and end addresses for the IP block
+ * pointed to by @oh. The data will be filled into the addresses
+ * pointed to by @pa_start and @pa_end. When @name is non-null, the
+ * address space data associated with the named entry will be
+ * returned. If @name is null, the first matching entry will be
+ * returned. Data order is not meaningful in hwmod data, so callers
+ * are strongly encouraged to use a non-null @name whenever possible
+ * to avoid unpredictable effects if hwmod data is later added that
+ * causes data ordering to change. Returns 0 upon success or a
+ * negative error code upon error.
+ */
+static int _get_addr_space_by_name(struct omap_hwmod *oh, const char *name,
+ u32 *pa_start, u32 *pa_end)
+{
+ int i, j;
+ struct omap_hwmod_ocp_if *os;
+ struct list_head *p = NULL;
+ bool found = false;
+
+ p = oh->slave_ports.next;
+
+ i = 0;
+ while (i < oh->slaves_cnt) {
+ os = _fetch_next_ocp_if(&p, &i);
+
+ if (!os->addr)
+ return -ENOENT;
+
+ j = 0;
+ while (os->addr[j].pa_start != os->addr[j].pa_end) {
+ if (name == os->addr[j].name ||
+ !strcmp(name, os->addr[j].name)) {
+ found = true;
+ break;
+ }
+ j++;
+ }
+
+ if (found)
+ break;
+ }
+
+ if (!found)
+ return -ENOENT;
+
+ *pa_start = os->addr[j].pa_start;
+ *pa_end = os->addr[j].pa_end;
+
+ return 0;
+}
+
+/**
+ * _save_mpu_port_index - find and save the index to @oh's MPU port
+ * @oh: struct omap_hwmod *
+ *
+ * Determines the array index of the OCP slave port that the MPU uses
+ * to address the device, and saves it into the struct omap_hwmod.
+ * Intended to be called during hwmod registration only. No return
+ * value.
+ */
+static void __init _save_mpu_port_index(struct omap_hwmod *oh)
+{
+ struct omap_hwmod_ocp_if *os = NULL;
+ struct list_head *p;
+ int i = 0;
+
+ if (!oh)
+ return;
+
+ oh->_int_flags |= _HWMOD_NO_MPU_PORT;
+
+ p = oh->slave_ports.next;
+
+ while (i < oh->slaves_cnt) {
+ os = _fetch_next_ocp_if(&p, &i);
+ if (os->user & OCP_USER_MPU) {
+ oh->_mpu_port = os;
+ oh->_int_flags &= ~_HWMOD_NO_MPU_PORT;
+ break;
+ }
+ }
+
+ return;
+}
+
+/**
+ * _find_mpu_rt_port - return omap_hwmod_ocp_if accessible by the MPU
+ * @oh: struct omap_hwmod *
+ *
+ * Given a pointer to a struct omap_hwmod record @oh, return a pointer
+ * to the struct omap_hwmod_ocp_if record that is used by the MPU to
+ * communicate with the IP block. This interface need not be directly
+ * connected to the MPU (and almost certainly is not), but is directly
+ * connected to the IP block represented by @oh. Returns a pointer
+ * to the struct omap_hwmod_ocp_if * upon success, or returns NULL upon
+ * error or if there does not appear to be a path from the MPU to this
+ * IP block.
+ */
+static struct omap_hwmod_ocp_if *_find_mpu_rt_port(struct omap_hwmod *oh)
+{
+ if (!oh || oh->_int_flags & _HWMOD_NO_MPU_PORT || oh->slaves_cnt == 0)
+ return NULL;
+
+ return oh->_mpu_port;
+};
+
+/**
+ * _find_mpu_rt_addr_space - return MPU register target address space for @oh
+ * @oh: struct omap_hwmod *
+ *
+ * Returns a pointer to the struct omap_hwmod_addr_space record representing
+ * the register target MPU address space; or returns NULL upon error.
+ */
+static struct omap_hwmod_addr_space * __init _find_mpu_rt_addr_space(struct omap_hwmod *oh)
+{
+ struct omap_hwmod_ocp_if *os;
+ struct omap_hwmod_addr_space *mem;
+ int found = 0, i = 0;
+
+ os = _find_mpu_rt_port(oh);
+ if (!os || !os->addr)
+ return NULL;
+
+ do {
+ mem = &os->addr[i++];
+ if (mem->flags & ADDR_TYPE_RT)
+ found = 1;
+ } while (!found && mem->pa_start != mem->pa_end);
+
+ return (found) ? mem : NULL;
+}
+
+/**
+ * _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG
+ * @oh: struct omap_hwmod *
+ *
+ * Ensure that the OCP_SYSCONFIG register for the IP block represented
+ * by @oh is set to indicate to the PRCM that the IP block is active.
+ * Usually this means placing the module into smart-idle mode and
+ * smart-standby, but if there is a bug in the automatic idle handling
+ * for the IP block, it may need to be placed into the force-idle or
+ * no-idle variants of these modes. No return value.
+ */
+static void _enable_sysc(struct omap_hwmod *oh)
+{
+ u8 idlemode, sf;
+ u32 v;
+ bool clkdm_act;
+ struct clockdomain *clkdm;
+
+ if (!oh->class->sysc)
+ return;
+
+ /*
+ * Wait until reset has completed, this is needed as the IP
+ * block is reset automatically by hardware in some cases
+ * (off-mode for example), and the drivers require the
+ * IP to be ready when they access it
+ */
+ if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
+ _enable_optional_clocks(oh);
+ _wait_softreset_complete(oh);
+ if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
+ _disable_optional_clocks(oh);
+
+ v = oh->_sysc_cache;
+ sf = oh->class->sysc->sysc_flags;
+
+ clkdm = _get_clkdm(oh);
+ if (sf & SYSC_HAS_SIDLEMODE) {
+ if (oh->flags & HWMOD_SWSUP_SIDLE ||
+ oh->flags & HWMOD_SWSUP_SIDLE_ACT) {
+ idlemode = HWMOD_IDLEMODE_NO;
+ } else {
+ if (sf & SYSC_HAS_ENAWAKEUP)
+ _enable_wakeup(oh, &v);
+ if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
+ idlemode = HWMOD_IDLEMODE_SMART_WKUP;
+ else
+ idlemode = HWMOD_IDLEMODE_SMART;
+ }
+
+ /*
+ * This is special handling for some IPs like
+ * 32k sync timer. Force them to idle!
+ */
+ clkdm_act = (clkdm && clkdm->flags & CLKDM_ACTIVE_WITH_MPU);
+ if (clkdm_act && !(oh->class->sysc->idlemodes &
+ (SIDLE_SMART | SIDLE_SMART_WKUP)))
+ idlemode = HWMOD_IDLEMODE_FORCE;
+
+ _set_slave_idlemode(oh, idlemode, &v);
+ }
+
+ if (sf & SYSC_HAS_MIDLEMODE) {
+ if (oh->flags & HWMOD_FORCE_MSTANDBY) {
+ idlemode = HWMOD_IDLEMODE_FORCE;
+ } else if (oh->flags & HWMOD_SWSUP_MSTANDBY) {
+ idlemode = HWMOD_IDLEMODE_NO;
+ } else {
+ if (sf & SYSC_HAS_ENAWAKEUP)
+ _enable_wakeup(oh, &v);
+ if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
+ idlemode = HWMOD_IDLEMODE_SMART_WKUP;
+ else
+ idlemode = 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 the cached value is the same as the new value, skip the write */
+ if (oh->_sysc_cache != 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) {
+ if (oh->flags & HWMOD_SWSUP_SIDLE) {
+ idlemode = HWMOD_IDLEMODE_FORCE;
+ } else {
+ if (sf & SYSC_HAS_ENAWAKEUP)
+ _enable_wakeup(oh, &v);
+ if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
+ idlemode = HWMOD_IDLEMODE_SMART_WKUP;
+ else
+ idlemode = HWMOD_IDLEMODE_SMART;
+ }
+ _set_slave_idlemode(oh, idlemode, &v);
+ }
+
+ if (sf & SYSC_HAS_MIDLEMODE) {
+ if ((oh->flags & HWMOD_SWSUP_MSTANDBY) ||
+ (oh->flags & HWMOD_FORCE_MSTANDBY)) {
+ idlemode = HWMOD_IDLEMODE_FORCE;
+ } else {
+ if (sf & SYSC_HAS_ENAWAKEUP)
+ _enable_wakeup(oh, &v);
+ if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
+ idlemode = HWMOD_IDLEMODE_SMART_WKUP;
+ else
+ idlemode = HWMOD_IDLEMODE_SMART;
+ }
+ _set_master_standbymode(oh, idlemode, &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_clkdm - look up a clockdomain name, store pointer in omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Convert a clockdomain name stored in a struct omap_hwmod into a
+ * clockdomain pointer, and save it into the struct omap_hwmod.
+ * Return -EINVAL if the clkdm_name lookup failed.
+ */
+static int _init_clkdm(struct omap_hwmod *oh)
+{
+ if (!oh->clkdm_name) {
+ pr_debug("omap_hwmod: %s: missing clockdomain\n", oh->name);
+ return 0;
+ }
+
+ oh->clkdm = clkdm_lookup(oh->clkdm_name);
+ if (!oh->clkdm) {
+ pr_warn("omap_hwmod: %s: could not associate to clkdm %s\n",
+ oh->name, oh->clkdm_name);
+ return 0;
+ }
+
+ pr_debug("omap_hwmod: %s: associated to clkdm %s\n",
+ oh->name, oh->clkdm_name);
+
+ return 0;
+}
+
+/**
+ * _init_clocks - clk_get() all clocks associated with this hwmod. Retrieve as
+ * well the clockdomain.
+ * @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);
+
+ if (soc_ops.init_clkdm)
+ ret |= soc_ops.init_clkdm(oh);
+
+ ret |= _init_main_clk(oh);
+ ret |= _init_interface_clks(oh);
+ ret |= _init_opt_clks(oh);
+
+ if (!ret)
+ oh->_state = _HWMOD_STATE_CLKS_INITED;
+ else
+ pr_warn("omap_hwmod: %s: cannot _init_clocks\n", oh->name);
+
+ 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 int _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.
+ * Returns -EINVAL if @oh is null, -ENOSYS if we have no way of
+ * asserting the hardreset line on the currently-booted SoC, or passes
+ * along the return value from _lookup_hardreset() or the SoC's
+ * assert_hardreset code.
+ */
+static int _assert_hardreset(struct omap_hwmod *oh, const char *name)
+{
+ struct omap_hwmod_rst_info ohri;
+ int ret = -EINVAL;
+
+ if (!oh)
+ return -EINVAL;
+
+ if (!soc_ops.assert_hardreset)
+ return -ENOSYS;
+
+ ret = _lookup_hardreset(oh, name, &ohri);
+ if (ret < 0)
+ return ret;
+
+ ret = soc_ops.assert_hardreset(oh, &ohri);
+
+ return ret;
+}
+
+/**
+ * _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, -ENOSYS if we have no way of
+ * deasserting the hardreset line on the currently-booted SoC, or passes
+ * along the return value from _lookup_hardreset() or the SoC's
+ * deassert_hardreset code.
+ */
+static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
+{
+ struct omap_hwmod_rst_info ohri;
+ int ret = -EINVAL;
+ int hwsup = 0;
+
+ if (!oh)
+ return -EINVAL;
+
+ if (!soc_ops.deassert_hardreset)
+ return -ENOSYS;
+
+ ret = _lookup_hardreset(oh, name, &ohri);
+ if (ret < 0)
+ return ret;
+
+ if (oh->clkdm) {
+ /*
+ * A clockdomain must be in SW_SUP otherwise reset
+ * might not be completed. The clockdomain can be set
+ * in HW_AUTO only when the module become ready.
+ */
+ hwsup = clkdm_in_hwsup(oh->clkdm);
+ ret = clkdm_hwmod_enable(oh->clkdm, oh);
+ if (ret) {
+ WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
+ oh->name, oh->clkdm->name, ret);
+ return ret;
+ }
+ }
+
+ _enable_clocks(oh);
+ if (soc_ops.enable_module)
+ soc_ops.enable_module(oh);
+
+ ret = soc_ops.deassert_hardreset(oh, &ohri);
+
+ if (soc_ops.disable_module)
+ soc_ops.disable_module(oh);
+ _disable_clocks(oh);
+
+ if (ret == -EBUSY)
+ pr_warn("omap_hwmod: %s: failed to hardreset\n", oh->name);
+
+ if (oh->clkdm) {
+ /*
+ * Set the clockdomain to HW_AUTO, assuming that the
+ * previous state was HW_AUTO.
+ */
+ if (hwsup)
+ clkdm_allow_idle(oh->clkdm);
+
+ clkdm_hwmod_disable(oh->clkdm, oh);
+ }
+
+ 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. Returns -EINVAL if @oh is
+ * null, -ENOSYS if we have no way of reading the hardreset line
+ * status on the currently-booted SoC, or passes along the return
+ * value from _lookup_hardreset() or the SoC's is_hardreset_asserted
+ * code.
+ */
+static int _read_hardreset(struct omap_hwmod *oh, const char *name)
+{
+ struct omap_hwmod_rst_info ohri;
+ int ret = -EINVAL;
+
+ if (!oh)
+ return -EINVAL;
+
+ if (!soc_ops.is_hardreset_asserted)
+ return -ENOSYS;
+
+ ret = _lookup_hardreset(oh, name, &ohri);
+ if (ret < 0)
+ return ret;
+
+ return soc_ops.is_hardreset_asserted(oh, &ohri);
+}
+
+/**
+ * _are_all_hardreset_lines_asserted - return true if the @oh is hard-reset
+ * @oh: struct omap_hwmod *
+ *
+ * If all hardreset lines associated with @oh are asserted, then return true.
+ * Otherwise, if part of @oh is out hardreset or if no hardreset lines
+ * associated with @oh are asserted, then return false.
+ * This function is used to avoid executing some parts of the IP block
+ * enable/disable sequence if its hardreset line is set.
+ */
+static bool _are_all_hardreset_lines_asserted(struct omap_hwmod *oh)
+{
+ int i, rst_cnt = 0;
+
+ if (oh->rst_lines_cnt == 0)
+ return false;
+
+ for (i = 0; i < oh->rst_lines_cnt; i++)
+ if (_read_hardreset(oh, oh->rst_lines[i].name) > 0)
+ rst_cnt++;
+
+ if (oh->rst_lines_cnt == rst_cnt)
+ return true;
+
+ return false;
+}
+
+/**
+ * _are_any_hardreset_lines_asserted - return true if any part of @oh is
+ * hard-reset
+ * @oh: struct omap_hwmod *
+ *
+ * If any hardreset lines associated with @oh are asserted, then
+ * return true. Otherwise, if no hardreset lines associated with @oh
+ * are asserted, or if @oh has no hardreset lines, then return false.
+ * This function is used to avoid executing some parts of the IP block
+ * enable/disable sequence if any hardreset line is set.
+ */
+static bool _are_any_hardreset_lines_asserted(struct omap_hwmod *oh)
+{
+ int rst_cnt = 0;
+ int i;
+
+ for (i = 0; i < oh->rst_lines_cnt && rst_cnt == 0; i++)
+ if (_read_hardreset(oh, oh->rst_lines[i].name) > 0)
+ rst_cnt++;
+
+ return (rst_cnt) ? true : false;
+}
+
+/**
+ * _omap4_disable_module - enable CLKCTRL modulemode on OMAP4
+ * @oh: struct omap_hwmod *
+ *
+ * Disable the PRCM module mode related to the hwmod @oh.
+ * Return EINVAL if the modulemode is not supported and 0 in case of success.
+ */
+static int _omap4_disable_module(struct omap_hwmod *oh)
+{
+ int v;
+
+ if (!oh->clkdm || !oh->prcm.omap4.modulemode)
+ return -EINVAL;
+
+ /*
+ * Since integration code might still be doing something, only
+ * disable if all lines are under hardreset.
+ */
+ if (_are_any_hardreset_lines_asserted(oh))
+ return 0;
+
+ pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);
+
+ omap_cm_module_disable(oh->clkdm->prcm_partition, oh->clkdm->cm_inst,
+ oh->prcm.omap4.clkctrl_offs);
+
+ v = _omap4_wait_target_disable(oh);
+ if (v)
+ pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
+ oh->name);
+
+ return 0;
+}
+
+/**
+ * _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 -ENOENT if the hwmod cannot be
+ * reset this way, -EINVAL 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 -ENOENT;
+
+ /* clocks must be on for this operation */
+ if (oh->_state != _HWMOD_STATE_ENABLED) {
+ pr_warn("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->srst_udelay)
+ udelay(oh->class->sysc->srst_udelay);
+
+ c = _wait_softreset_complete(oh);
+ if (c == MAX_MODULE_SOFTRESET_WAIT) {
+ pr_warn("omap_hwmod: %s: softreset failed (waited %d usec)\n",
+ oh->name, MAX_MODULE_SOFTRESET_WAIT);
+ ret = -ETIMEDOUT;
+ goto dis_opt_clks;
+ } else {
+ pr_debug("omap_hwmod: %s: softreset in %d usec\n", oh->name, c);
+ }
+
+ ret = _clear_softreset(oh, &v);
+ if (ret)
+ goto dis_opt_clks;
+
+ _write_sysconfig(v, oh);
+
+ /*
+ * XXX add _HWMOD_STATE_WEDGED for modules that don't come back from
+ * _wait_target_ready() or _reset()
+ */
+
+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. If the module has a custom reset
+ * function pointer defined, then call it to reset the IP block, and
+ * pass along its return value to the caller. Otherwise, if the IP
+ * block has an OCP_SYSCONFIG register with a SOFTRESET bitfield
+ * associated with it, call a function to reset the IP block via that
+ * method, and pass along the return value to the caller. Finally, if
+ * the IP block has some hardreset lines associated with it, assert
+ * all of those, but do _not_ deassert them. (This is because driver
+ * authors have expressed an apparent requirement to control the
+ * deassertion of the hardreset lines themselves.)
+ *
+ * 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.
+ *
+ * _set_dmadisable() is called to set the DMADISABLE bit so that it
+ * does not prevent idling of the system. This is necessary for cases
+ * where ROMCODE/BOOTLOADER uses dma and transfers control to the
+ * kernel without disabling dma.
+ *
+ * Passes along the return value from either _ocp_softreset() 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 i, r;
+
+ pr_debug("omap_hwmod: %s: resetting\n", oh->name);
+
+ if (oh->class->reset) {
+ r = oh->class->reset(oh);
+ } else {
+ if (oh->rst_lines_cnt > 0) {
+ for (i = 0; i < oh->rst_lines_cnt; i++)
+ _assert_hardreset(oh, oh->rst_lines[i].name);
+ return 0;
+ } else {
+ r = _ocp_softreset(oh);
+ if (r == -ENOENT)
+ r = 0;
+ }
+ }
+
+ _set_dmadisable(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);
+ }
+
+ return r;
+}
+
+/**
+ * _reconfigure_io_chain - clear any I/O chain wakeups and reconfigure chain
+ *
+ * Call the appropriate PRM function to clear any logged I/O chain
+ * wakeups and to reconfigure the chain. This apparently needs to be
+ * done upon every mux change. Since hwmods can be concurrently
+ * enabled and idled, hold a spinlock around the I/O chain
+ * reconfiguration sequence. No return value.
+ *
+ * XXX When the PRM code is moved to drivers, this function can be removed,
+ * as the PRM infrastructure should abstract this.
+ */
+static void _reconfigure_io_chain(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&io_chain_lock, flags);
+
+ omap_prm_reconfigure_io_chain();
+
+ spin_unlock_irqrestore(&io_chain_lock, flags);
+}
+
+/**
+ * _omap4_update_context_lost - increment hwmod context loss counter if
+ * hwmod context was lost, and clear hardware context loss reg
+ * @oh: hwmod to check for context loss
+ *
+ * If the PRCM indicates that the hwmod @oh lost context, increment
+ * our in-memory context loss counter, and clear the RM_*_CONTEXT
+ * bits. No return value.
+ */
+static void _omap4_update_context_lost(struct omap_hwmod *oh)
+{
+ if (oh->prcm.omap4.flags & HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT)
+ return;
+
+ if (!prm_was_any_context_lost_old(oh->clkdm->pwrdm.ptr->prcm_partition,
+ oh->clkdm->pwrdm.ptr->prcm_offs,
+ oh->prcm.omap4.context_offs))
+ return;
+
+ oh->prcm.omap4.context_lost_counter++;
+ prm_clear_context_loss_flags_old(oh->clkdm->pwrdm.ptr->prcm_partition,
+ oh->clkdm->pwrdm.ptr->prcm_offs,
+ oh->prcm.omap4.context_offs);
+}
+
+/**
+ * _omap4_get_context_lost - get context loss counter for a hwmod
+ * @oh: hwmod to get context loss counter for
+ *
+ * Returns the in-memory context loss counter for a hwmod.
+ */
+static int _omap4_get_context_lost(struct omap_hwmod *oh)
+{
+ return oh->prcm.omap4.context_lost_counter;
+}
+
+/**
+ * _enable_preprogram - Pre-program an IP block during the _enable() process
+ * @oh: struct omap_hwmod *
+ *
+ * Some IP blocks (such as AESS) require some additional programming
+ * after enable before they can enter idle. If a function pointer to
+ * do so is present in the hwmod data, then call it and pass along the
+ * return value; otherwise, return 0.
+ */
+static int _enable_preprogram(struct omap_hwmod *oh)
+{
+ if (!oh->class->enable_preprogram)
+ return 0;
+
+ return oh->class->enable_preprogram(oh);
+}
+
+/**
+ * _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;
+ int hwsup = 0;
+
+ pr_debug("omap_hwmod: %s: enabling\n", oh->name);
+
+ /*
+ * hwmods with HWMOD_INIT_NO_IDLE flag set are left in enabled
+ * state at init. Now that someone is really trying to enable
+ * them, just ensure that the hwmod mux is set.
+ */
+ if (oh->_int_flags & _HWMOD_SKIP_ENABLE) {
+ /*
+ * If the caller has mux data populated, do the mux'ing
+ * which wouldn't have been done as part of the _enable()
+ * done during setup.
+ */
+ if (oh->mux)
+ omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
+
+ oh->_int_flags &= ~_HWMOD_SKIP_ENABLE;
+ return 0;
+ }
+
+ 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;
+ }
+
+ /*
+ * If an IP block contains HW reset lines and all of them are
+ * asserted, we let integration code associated with that
+ * block handle the enable. We've received very little
+ * information on what those driver authors need, and until
+ * detailed information is provided and the driver code is
+ * posted to the public lists, this is probably the best we
+ * can do.
+ */
+ if (_are_all_hardreset_lines_asserted(oh))
+ return 0;
+
+ /* 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);
+ _reconfigure_io_chain();
+ } else if (oh->flags & HWMOD_RECONFIG_IO_CHAIN) {
+ _reconfigure_io_chain();
+ }
+
+ _add_initiator_dep(oh, mpu_oh);
+
+ if (oh->clkdm) {
+ /*
+ * A clockdomain must be in SW_SUP before enabling
+ * completely the module. The clockdomain can be set
+ * in HW_AUTO only when the module become ready.
+ */
+ hwsup = clkdm_in_hwsup(oh->clkdm) &&
+ !clkdm_missing_idle_reporting(oh->clkdm);
+ r = clkdm_hwmod_enable(oh->clkdm, oh);
+ if (r) {
+ WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
+ oh->name, oh->clkdm->name, r);
+ return r;
+ }
+ }
+
+ _enable_clocks(oh);
+ if (soc_ops.enable_module)
+ soc_ops.enable_module(oh);
+ if (oh->flags & HWMOD_BLOCK_WFI)
+ cpu_idle_poll_ctrl(true);
+
+ if (soc_ops.update_context_lost)
+ soc_ops.update_context_lost(oh);
+
+ r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) :
+ -EINVAL;
+ if (!r) {
+ /*
+ * Set the clockdomain to HW_AUTO only if the target is ready,
+ * assuming that the previous state was HW_AUTO
+ */
+ if (oh->clkdm && hwsup)
+ clkdm_allow_idle(oh->clkdm);
+
+ 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);
+ }
+ r = _enable_preprogram(oh);
+ } else {
+ if (soc_ops.disable_module)
+ soc_ops.disable_module(oh);
+ _disable_clocks(oh);
+ pr_err("omap_hwmod: %s: _wait_target_ready failed: %d\n",
+ oh->name, r);
+
+ if (oh->clkdm)
+ clkdm_hwmod_disable(oh->clkdm, oh);
+ }
+
+ 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)
+{
+ pr_debug("omap_hwmod: %s: idling\n", oh->name);
+
+ 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;
+ }
+
+ if (_are_all_hardreset_lines_asserted(oh))
+ return 0;
+
+ if (oh->class->sysc)
+ _idle_sysc(oh);
+ _del_initiator_dep(oh, mpu_oh);
+
+ if (oh->flags & HWMOD_BLOCK_WFI)
+ cpu_idle_poll_ctrl(false);
+ if (soc_ops.disable_module)
+ soc_ops.disable_module(oh);
+
+ /*
+ * The module must be in idle mode before disabling any parents
+ * clocks. Otherwise, the parent clock might be disabled before
+ * the module transition is done, and thus will prevent the
+ * transition to complete properly.
+ */
+ _disable_clocks(oh);
+ if (oh->clkdm)
+ clkdm_hwmod_disable(oh->clkdm, oh);
+
+ /* Mux pins for device idle if populated */
+ if (oh->mux && oh->mux->pads_dynamic) {
+ omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
+ _reconfigure_io_chain();
+ } else if (oh->flags & HWMOD_RECONFIG_IO_CHAIN) {
+ _reconfigure_io_chain();
+ }
+
+ oh->_state = _HWMOD_STATE_IDLE;
+
+ return 0;
+}
+
+/**
+ * _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, i;
+ 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;
+ }
+
+ if (_are_all_hardreset_lines_asserted(oh))
+ return 0;
+
+ 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) {
+ if (oh->_state == _HWMOD_STATE_IDLE)
+ _enable(oh);
+ _shutdown_sysc(oh);
+ }
+
+ /* 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 */
+ if (oh->flags & HWMOD_BLOCK_WFI)
+ cpu_idle_poll_ctrl(false);
+ if (soc_ops.disable_module)
+ soc_ops.disable_module(oh);
+ _disable_clocks(oh);
+ if (oh->clkdm)
+ clkdm_hwmod_disable(oh->clkdm, oh);
+ }
+ /* XXX Should this code also force-disable the optional clocks? */
+
+ for (i = 0; i < oh->rst_lines_cnt; i++)
+ _assert_hardreset(oh, oh->rst_lines[i].name);
+
+ /* 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;
+}
+
+static int of_dev_find_hwmod(struct device_node *np,
+ struct omap_hwmod *oh)
+{
+ int count, i, res;
+ const char *p;
+
+ count = of_property_count_strings(np, "ti,hwmods");
+ if (count < 1)
+ return -ENODEV;
+
+ for (i = 0; i < count; i++) {
+ res = of_property_read_string_index(np, "ti,hwmods",
+ i, &p);
+ if (res)
+ continue;
+ if (!strcmp(p, oh->name)) {
+ pr_debug("omap_hwmod: dt %s[%i] uses hwmod %s\n",
+ np->name, i, oh->name);
+ return i;
+ }
+ }
+
+ return -ENODEV;
+}
+
+/**
+ * of_dev_hwmod_lookup - look up needed hwmod from dt blob
+ * @np: struct device_node *
+ * @oh: struct omap_hwmod *
+ * @index: index of the entry found
+ * @found: struct device_node * found or NULL
+ *
+ * Parse the dt blob and find out needed hwmod. Recursive function is
+ * implemented to take care hierarchical dt blob parsing.
+ * Return: Returns 0 on success, -ENODEV when not found.
+ */
+static int of_dev_hwmod_lookup(struct device_node *np,
+ struct omap_hwmod *oh,
+ int *index,
+ struct device_node **found)
+{
+ struct device_node *np0 = NULL;
+ int res;
+
+ res = of_dev_find_hwmod(np, oh);
+ if (res >= 0) {
+ *found = np;
+ *index = res;
+ return 0;
+ }
+
+ for_each_child_of_node(np, np0) {
+ struct device_node *fc;
+ int i;
+
+ res = of_dev_hwmod_lookup(np0, oh, &i, &fc);
+ if (res == 0) {
+ *found = fc;
+ *index = i;
+ return 0;
+ }
+ }
+
+ *found = NULL;
+ *index = 0;
+
+ return -ENODEV;
+}
+
+/**
+ * _init_mpu_rt_base - populate the virtual address for a hwmod
+ * @oh: struct omap_hwmod * to locate the virtual address
+ * @data: (unused, caller should pass NULL)
+ * @index: index of the reg entry iospace in device tree
+ * @np: struct device_node * of the IP block's device node in the DT data
+ *
+ * Cache the virtual address used by the MPU to access this IP block's
+ * registers. This address is needed early so the OCP registers that
+ * are part of the device's address space can be ioremapped properly.
+ *
+ * Returns 0 on success, -EINVAL if an invalid hwmod is passed, and
+ * -ENXIO on absent or invalid register target address space.
+ */
+static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
+ int index, struct device_node *np)
+{
+ struct omap_hwmod_addr_space *mem;
+ void __iomem *va_start = NULL;
+
+ if (!oh)
+ return -EINVAL;
+
+ _save_mpu_port_index(oh);
+
+ if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
+ return -ENXIO;
+
+ mem = _find_mpu_rt_addr_space(oh);
+ if (!mem) {
+ pr_debug("omap_hwmod: %s: no MPU register target found\n",
+ oh->name);
+
+ /* Extract the IO space from device tree blob */
+ if (!np)
+ return -ENXIO;
+
+ va_start = of_iomap(np, index + oh->mpu_rt_idx);
+ } else {
+ va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
+ }
+
+ if (!va_start) {
+ if (mem)
+ pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
+ else
+ pr_err("omap_hwmod: %s: Missing dt reg%i for %s\n",
+ oh->name, index, np->full_name);
+ return -ENXIO;
+ }
+
+ pr_debug("omap_hwmod: %s: MPU register target at va %p\n",
+ oh->name, va_start);
+
+ oh->_mpu_rt_va = va_start;
+ return 0;
+}
+
+/**
+ * _init - initialize internal data for the hwmod @oh
+ * @oh: struct omap_hwmod *
+ * @n: (unused)
+ *
+ * Look up the clocks and the address space used by the MPU to access
+ * registers belonging to the hwmod @oh. @oh must already be
+ * registered at this point. This is the first of two phases for
+ * hwmod initialization. Code called here does not touch any hardware
+ * registers, it simply prepares internal data structures. Returns 0
+ * upon success or if the hwmod isn't registered or if the hwmod's
+ * address space is not defined, or -EINVAL upon failure.
+ */
+static int __init _init(struct omap_hwmod *oh, void *data)
+{
+ int r, index;
+ struct device_node *np = NULL;
+
+ if (oh->_state != _HWMOD_STATE_REGISTERED)
+ return 0;
+
+ if (of_have_populated_dt()) {
+ struct device_node *bus;
+
+ bus = of_find_node_by_name(NULL, "ocp");
+ if (!bus)
+ return -ENODEV;
+
+ r = of_dev_hwmod_lookup(bus, oh, &index, &np);
+ if (r)
+ pr_debug("omap_hwmod: %s missing dt data\n", oh->name);
+ else if (np && index)
+ pr_warn("omap_hwmod: %s using broken dt data from %s\n",
+ oh->name, np->name);
+ }
+
+ if (oh->class->sysc) {
+ r = _init_mpu_rt_base(oh, NULL, index, np);
+ if (r < 0) {
+ WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n",
+ oh->name);
+ return 0;
+ }
+ }
+
+ r = _init_clocks(oh, NULL);
+ if (r < 0) {
+ WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name);
+ return -EINVAL;
+ }
+
+ if (np) {
+ if (of_find_property(np, "ti,no-reset-on-init", NULL))
+ oh->flags |= HWMOD_INIT_NO_RESET;
+ if (of_find_property(np, "ti,no-idle-on-init", NULL))
+ oh->flags |= HWMOD_INIT_NO_IDLE;
+ }
+
+ oh->_state = _HWMOD_STATE_INITIALIZED;
+
+ return 0;
+}
+
+/**
+ * _setup_iclk_autoidle - configure an IP block's interface clocks
+ * @oh: struct omap_hwmod *
+ *
+ * Set up the module's interface clocks. XXX This function is still mostly
+ * a stub; implementing this properly requires iclk autoidle usecounting in
+ * the clock code. No return value.
+ */
+static void __init _setup_iclk_autoidle(struct omap_hwmod *oh)
+{
+ struct omap_hwmod_ocp_if *os;
+ struct list_head *p;
+ int i = 0;
+ if (oh->_state != _HWMOD_STATE_INITIALIZED)
+ return;
+
+ p = oh->slave_ports.next;
+
+ while (i < oh->slaves_cnt) {
+ os = _fetch_next_ocp_if(&p, &i);
+ if (!os->_clk)
+ continue;
+
+ if (os->flags & OCPIF_SWSUP_IDLE) {
+ /* XXX omap_iclk_deny_idle(c); */
+ } else {
+ /* XXX omap_iclk_allow_idle(c); */
+ clk_enable(os->_clk);
+ }
+ }
+
+ return;
+}
+
+/**
+ * _setup_reset - reset an IP block during the setup process
+ * @oh: struct omap_hwmod *
+ *
+ * Reset the IP block corresponding to the hwmod @oh during the setup
+ * process. The IP block is first enabled so it can be successfully
+ * reset. Returns 0 upon success or a negative error code upon
+ * failure.
+ */
+static int __init _setup_reset(struct omap_hwmod *oh)
+{
+ int r;
+
+ if (oh->_state != _HWMOD_STATE_INITIALIZED)
+ return -EINVAL;
+
+ if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK)
+ return -EPERM;
+
+ if (oh->rst_lines_cnt == 0) {
+ r = _enable(oh);
+ if (r) {
+ pr_warn("omap_hwmod: %s: cannot be enabled for reset (%d)\n",
+ oh->name, oh->_state);
+ return -EINVAL;
+ }
+ }
+
+ if (!(oh->flags & HWMOD_INIT_NO_RESET))
+ r = _reset(oh);
+
+ return r;
+}
+
+/**
+ * _setup_postsetup - transition to the appropriate state after _setup
+ * @oh: struct omap_hwmod *
+ *
+ * Place an IP block represented by @oh into a "post-setup" state --
+ * either IDLE, ENABLED, or DISABLED. ("post-setup" simply means that
+ * this function is called at the end of _setup().) The postsetup
+ * state for an IP block can be changed by calling
+ * omap_hwmod_enter_postsetup_state() early in the boot process,
+ * before one of the omap_hwmod_setup*() functions are called for the
+ * IP block.
+ *
+ * The IP block stays in this state until a PM runtime-based driver is
+ * loaded for that IP block. A post-setup state of IDLE is
+ * appropriate for almost all IP blocks with runtime PM-enabled
+ * drivers, since those drivers are able to enable the IP block. A
+ * post-setup state of ENABLED is appropriate for kernels with PM
+ * runtime disabled. The DISABLED state is appropriate for unusual IP
+ * blocks such as the MPU WDTIMER on kernels without WDTIMER drivers
+ * included, since the WDTIMER starts running on reset and will reset
+ * the MPU if left active.
+ *
+ * This post-setup mechanism is deprecated. Once all of the OMAP
+ * drivers have been converted to use PM runtime, and all of the IP
+ * block data and interconnect data is available to the hwmod code, it
+ * should be possible to replace this mechanism with a "lazy reset"
+ * arrangement. In a "lazy reset" setup, each IP block is enabled
+ * when the driver first probes, then all remaining IP blocks without
+ * drivers are either shut down or enabled after the drivers have
+ * loaded. However, this cannot take place until the above
+ * preconditions have been met, since otherwise the late reset code
+ * has no way of knowing which IP blocks are in use by drivers, and
+ * which ones are unused.
+ *
+ * No return value.
+ */
+static void __init _setup_postsetup(struct omap_hwmod *oh)
+{
+ u8 postsetup_state;
+
+ if (oh->rst_lines_cnt > 0)
+ return;
+
+ 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)) {
+ oh->_int_flags |= _HWMOD_SKIP_ENABLE;
+ 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;
+}
+
+/**
+ * _setup - prepare IP block hardware for use
+ * @oh: struct omap_hwmod *
+ * @n: (unused, pass NULL)
+ *
+ * Configure the IP block represented by @oh. This may include
+ * enabling the IP block, resetting it, and placing it into a
+ * post-setup state, depending on the type of IP block and applicable
+ * flags. IP blocks are reset to prevent any previous configuration
+ * by the bootloader or previous operating system from interfering
+ * with power management or other parts of the system. The reset can
+ * be avoided; see omap_hwmod_no_setup_reset(). This is the second of
+ * two phases for hwmod initialization. Code called here generally
+ * affects the IP block hardware, or system integration hardware
+ * associated with the IP block. Returns 0.
+ */
+static int __init _setup(struct omap_hwmod *oh, void *data)
+{
+ if (oh->_state != _HWMOD_STATE_INITIALIZED)
+ return 0;
+
+ if (oh->parent_hwmod) {
+ int r;
+
+ r = _enable(oh->parent_hwmod);
+ WARN(r, "hwmod: %s: setup: failed to enable parent hwmod %s\n",
+ oh->name, oh->parent_hwmod->name);
+ }
+
+ _setup_iclk_autoidle(oh);
+
+ if (!_setup_reset(oh))
+ _setup_postsetup(oh);
+
+ if (oh->parent_hwmod) {
+ u8 postsetup_state;
+
+ postsetup_state = oh->parent_hwmod->_postsetup_state;
+
+ if (postsetup_state == _HWMOD_STATE_IDLE)
+ _idle(oh->parent_hwmod);
+ else if (postsetup_state == _HWMOD_STATE_DISABLED)
+ _shutdown(oh->parent_hwmod);
+ else if (postsetup_state != _HWMOD_STATE_ENABLED)
+ WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n",
+ oh->parent_hwmod->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)
+{
+ 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;
+
+ list_add_tail(&oh->node, &omap_hwmod_list);
+
+ INIT_LIST_HEAD(&oh->master_ports);
+ INIT_LIST_HEAD(&oh->slave_ports);
+ spin_lock_init(&oh->_lock);
+ lockdep_set_class(&oh->_lock, &oh->hwmod_key);
+
+ 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;
+}
+
+/**
+ * _alloc_links - return allocated memory for hwmod links
+ * @ml: pointer to a struct omap_hwmod_link * for the master link
+ * @sl: pointer to a struct omap_hwmod_link * for the slave link
+ *
+ * Return pointers to two struct omap_hwmod_link records, via the
+ * addresses pointed to by @ml and @sl. Will first attempt to return
+ * memory allocated as part of a large initial block, but if that has
+ * been exhausted, will allocate memory itself. Since ideally this
+ * second allocation path will never occur, the number of these
+ * 'supplemental' allocations will be logged when debugging is
+ * enabled. Returns 0.
+ */
+static int __init _alloc_links(struct omap_hwmod_link **ml,
+ struct omap_hwmod_link **sl)
+{
+ unsigned int sz;
+
+ if ((free_ls + LINKS_PER_OCP_IF) <= max_ls) {
+ *ml = &linkspace[free_ls++];
+ *sl = &linkspace[free_ls++];
+ return 0;
+ }
+
+ sz = sizeof(struct omap_hwmod_link) * LINKS_PER_OCP_IF;
+
+ *sl = NULL;
+ *ml = memblock_virt_alloc(sz, 0);
+
+ *sl = (void *)(*ml) + sizeof(struct omap_hwmod_link);
+
+ ls_supp++;
+ pr_debug("omap_hwmod: supplemental link allocations needed: %d\n",
+ ls_supp * LINKS_PER_OCP_IF);
+
+ return 0;
+};
+
+/**
+ * _add_link - add an interconnect between two IP blocks
+ * @oi: pointer to a struct omap_hwmod_ocp_if record
+ *
+ * Add struct omap_hwmod_link records connecting the master IP block
+ * specified in @oi->master to @oi, and connecting the slave IP block
+ * specified in @oi->slave to @oi. This code is assumed to run before
+ * preemption or SMP has been enabled, thus avoiding the need for
+ * locking in this code. Changes to this assumption will require
+ * additional locking. Returns 0.
+ */
+static int __init _add_link(struct omap_hwmod_ocp_if *oi)
+{
+ struct omap_hwmod_link *ml, *sl;
+
+ pr_debug("omap_hwmod: %s -> %s: adding link\n", oi->master->name,
+ oi->slave->name);
+
+ _alloc_links(&ml, &sl);
+
+ ml->ocp_if = oi;
+ list_add(&ml->node, &oi->master->master_ports);
+ oi->master->masters_cnt++;
+
+ sl->ocp_if = oi;
+ list_add(&sl->node, &oi->slave->slave_ports);
+ oi->slave->slaves_cnt++;
+
+ return 0;
+}
+
+/**
+ * _register_link - register a struct omap_hwmod_ocp_if
+ * @oi: struct omap_hwmod_ocp_if *
+ *
+ * Registers the omap_hwmod_ocp_if record @oi. Returns -EEXIST if it
+ * has already been registered; -EINVAL if @oi is NULL or if the
+ * record pointed to by @oi is missing required fields; 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.
+ */
+static int __init _register_link(struct omap_hwmod_ocp_if *oi)
+{
+ if (!oi || !oi->master || !oi->slave || !oi->user)
+ return -EINVAL;
+
+ if (oi->_int_flags & _OCPIF_INT_FLAGS_REGISTERED)
+ return -EEXIST;
+
+ pr_debug("omap_hwmod: registering link from %s to %s\n",
+ oi->master->name, oi->slave->name);
+
+ /*
+ * Register the connected hwmods, if they haven't been
+ * registered already
+ */
+ if (oi->master->_state != _HWMOD_STATE_REGISTERED)
+ _register(oi->master);
+
+ if (oi->slave->_state != _HWMOD_STATE_REGISTERED)
+ _register(oi->slave);
+
+ _add_link(oi);
+
+ oi->_int_flags |= _OCPIF_INT_FLAGS_REGISTERED;
+
+ return 0;
+}
+
+/**
+ * _alloc_linkspace - allocate large block of hwmod links
+ * @ois: pointer to an array of struct omap_hwmod_ocp_if records to count
+ *
+ * Allocate a large block of struct omap_hwmod_link records. This
+ * improves boot time significantly by avoiding the need to allocate
+ * individual records one by one. If the number of records to
+ * allocate in the block hasn't been manually specified, this function
+ * will count the number of struct omap_hwmod_ocp_if records in @ois
+ * and use that to determine the allocation size. For SoC families
+ * that require multiple list registrations, such as OMAP3xxx, this
+ * estimation process isn't optimal, so manual estimation is advised
+ * in those cases. Returns -EEXIST if the allocation has already occurred
+ * or 0 upon success.
+ */
+static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois)
+{
+ unsigned int i = 0;
+ unsigned int sz;
+
+ if (linkspace) {
+ WARN(1, "linkspace already allocated\n");
+ return -EEXIST;
+ }
+
+ if (max_ls == 0)
+ while (ois[i++])
+ max_ls += LINKS_PER_OCP_IF;
+
+ sz = sizeof(struct omap_hwmod_link) * max_ls;
+
+ pr_debug("omap_hwmod: %s: allocating %d byte linkspace (%d links)\n",
+ __func__, sz, max_ls);
+
+ linkspace = memblock_virt_alloc(sz, 0);
+
+ return 0;
+}
+
+/* Static functions intended only for use in soc_ops field function pointers */
+
+/**
+ * _omap2xxx_3xxx_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 _omap2xxx_3xxx_wait_target_ready(struct omap_hwmod *oh)
+{
+ if (!oh)
+ return -EINVAL;
+
+ if (oh->flags & HWMOD_NO_IDLEST)
+ return 0;
+
+ if (!_find_mpu_rt_port(oh))
+ return 0;
+
+ /* XXX check module SIDLEMODE, hardreset status, enabled clocks */
+
+ return omap_cm_wait_module_ready(0, oh->prcm.omap2.module_offs,
+ oh->prcm.omap2.idlest_reg_id,
+ oh->prcm.omap2.idlest_idle_bit);
+}
+
+/**
+ * _omap4_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 _omap4_wait_target_ready(struct omap_hwmod *oh)
+{
+ if (!oh)
+ return -EINVAL;
+
+ if (oh->flags & HWMOD_NO_IDLEST || !oh->clkdm)
+ return 0;
+
+ if (!_find_mpu_rt_port(oh))
+ return 0;
+
+ /* XXX check module SIDLEMODE, hardreset status */
+
+ return omap_cm_wait_module_ready(oh->clkdm->prcm_partition,
+ oh->clkdm->cm_inst,
+ oh->prcm.omap4.clkctrl_offs, 0);
+}
+
+/**
+ * _omap2_assert_hardreset - call OMAP2 PRM hardreset fn with hwmod args
+ * @oh: struct omap_hwmod * to assert hardreset
+ * @ohri: hardreset line data
+ *
+ * Call omap2_prm_assert_hardreset() with parameters extracted from
+ * the hwmod @oh and the hardreset line data @ohri. Only intended for
+ * use as an soc_ops function pointer. Passes along the return value
+ * from omap2_prm_assert_hardreset(). XXX This function is scheduled
+ * for removal when the PRM code is moved into drivers/.
+ */
+static int _omap2_assert_hardreset(struct omap_hwmod *oh,
+ struct omap_hwmod_rst_info *ohri)
+{
+ return omap_prm_assert_hardreset(ohri->rst_shift, 0,
+ oh->prcm.omap2.module_offs, 0);
+}
+
+/**
+ * _omap2_deassert_hardreset - call OMAP2 PRM hardreset fn with hwmod args
+ * @oh: struct omap_hwmod * to deassert hardreset
+ * @ohri: hardreset line data
+ *
+ * Call omap2_prm_deassert_hardreset() with parameters extracted from
+ * the hwmod @oh and the hardreset line data @ohri. Only intended for
+ * use as an soc_ops function pointer. Passes along the return value
+ * from omap2_prm_deassert_hardreset(). XXX This function is
+ * scheduled for removal when the PRM code is moved into drivers/.
+ */
+static int _omap2_deassert_hardreset(struct omap_hwmod *oh,
+ struct omap_hwmod_rst_info *ohri)
+{
+ return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift, 0,
+ oh->prcm.omap2.module_offs, 0, 0);
+}
+
+/**
+ * _omap2_is_hardreset_asserted - call OMAP2 PRM hardreset fn with hwmod args
+ * @oh: struct omap_hwmod * to test hardreset
+ * @ohri: hardreset line data
+ *
+ * Call omap2_prm_is_hardreset_asserted() with parameters extracted
+ * from the hwmod @oh and the hardreset line data @ohri. Only
+ * intended for use as an soc_ops function pointer. Passes along the
+ * return value from omap2_prm_is_hardreset_asserted(). XXX This
+ * function is scheduled for removal when the PRM code is moved into
+ * drivers/.
+ */
+static int _omap2_is_hardreset_asserted(struct omap_hwmod *oh,
+ struct omap_hwmod_rst_info *ohri)
+{
+ return omap_prm_is_hardreset_asserted(ohri->st_shift, 0,
+ oh->prcm.omap2.module_offs, 0);
+}
+
+/**
+ * _omap4_assert_hardreset - call OMAP4 PRM hardreset fn with hwmod args
+ * @oh: struct omap_hwmod * to assert hardreset
+ * @ohri: hardreset line data
+ *
+ * Call omap4_prminst_assert_hardreset() with parameters extracted
+ * from the hwmod @oh and the hardreset line data @ohri. Only
+ * intended for use as an soc_ops function pointer. Passes along the
+ * return value from omap4_prminst_assert_hardreset(). XXX This
+ * function is scheduled for removal when the PRM code is moved into
+ * drivers/.
+ */
+static int _omap4_assert_hardreset(struct omap_hwmod *oh,
+ struct omap_hwmod_rst_info *ohri)
+{
+ if (!oh->clkdm)
+ return -EINVAL;
+
+ return omap_prm_assert_hardreset(ohri->rst_shift,
+ oh->clkdm->pwrdm.ptr->prcm_partition,
+ oh->clkdm->pwrdm.ptr->prcm_offs,
+ oh->prcm.omap4.rstctrl_offs);
+}
+
+/**
+ * _omap4_deassert_hardreset - call OMAP4 PRM hardreset fn with hwmod args
+ * @oh: struct omap_hwmod * to deassert hardreset
+ * @ohri: hardreset line data
+ *
+ * Call omap4_prminst_deassert_hardreset() with parameters extracted
+ * from the hwmod @oh and the hardreset line data @ohri. Only
+ * intended for use as an soc_ops function pointer. Passes along the
+ * return value from omap4_prminst_deassert_hardreset(). XXX This
+ * function is scheduled for removal when the PRM code is moved into
+ * drivers/.
+ */
+static int _omap4_deassert_hardreset(struct omap_hwmod *oh,
+ struct omap_hwmod_rst_info *ohri)
+{
+ if (!oh->clkdm)
+ return -EINVAL;
+
+ if (ohri->st_shift)
+ pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
+ oh->name, ohri->name);
+ return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->rst_shift,
+ oh->clkdm->pwrdm.ptr->prcm_partition,
+ oh->clkdm->pwrdm.ptr->prcm_offs,
+ oh->prcm.omap4.rstctrl_offs,
+ oh->prcm.omap4.rstctrl_offs +
+ OMAP4_RST_CTRL_ST_OFFSET);
+}
+
+/**
+ * _omap4_is_hardreset_asserted - call OMAP4 PRM hardreset fn with hwmod args
+ * @oh: struct omap_hwmod * to test hardreset
+ * @ohri: hardreset line data
+ *
+ * Call omap4_prminst_is_hardreset_asserted() with parameters
+ * extracted from the hwmod @oh and the hardreset line data @ohri.
+ * Only intended for use as an soc_ops function pointer. Passes along
+ * the return value from omap4_prminst_is_hardreset_asserted(). XXX
+ * This function is scheduled for removal when the PRM code is moved
+ * into drivers/.
+ */
+static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh,
+ struct omap_hwmod_rst_info *ohri)
+{
+ if (!oh->clkdm)
+ return -EINVAL;
+
+ return omap_prm_is_hardreset_asserted(ohri->rst_shift,
+ oh->clkdm->pwrdm.ptr->
+ prcm_partition,
+ oh->clkdm->pwrdm.ptr->prcm_offs,
+ oh->prcm.omap4.rstctrl_offs);
+}
+
+/**
+ * _am33xx_deassert_hardreset - call AM33XX PRM hardreset fn with hwmod args
+ * @oh: struct omap_hwmod * to deassert hardreset
+ * @ohri: hardreset line data
+ *
+ * Call am33xx_prminst_deassert_hardreset() with parameters extracted
+ * from the hwmod @oh and the hardreset line data @ohri. Only
+ * intended for use as an soc_ops function pointer. Passes along the
+ * return value from am33xx_prminst_deassert_hardreset(). XXX This
+ * function is scheduled for removal when the PRM code is moved into
+ * drivers/.
+ */
+static int _am33xx_deassert_hardreset(struct omap_hwmod *oh,
+ struct omap_hwmod_rst_info *ohri)
+{
+ return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift,
+ oh->clkdm->pwrdm.ptr->prcm_partition,
+ oh->clkdm->pwrdm.ptr->prcm_offs,
+ oh->prcm.omap4.rstctrl_offs,
+ oh->prcm.omap4.rstst_offs);
+}
+
+/* Public functions */
+
+u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs)
+{
+ if (oh->flags & HWMOD_16BIT_REG)
+ return readw_relaxed(oh->_mpu_rt_va + reg_offs);
+ else
+ return readl_relaxed(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)
+ writew_relaxed(v, oh->_mpu_rt_va + reg_offs);
+ else
+ writel_relaxed(v, oh->_mpu_rt_va + reg_offs);
+}
+
+/**
+ * omap_hwmod_softreset - reset a module via SYSCONFIG.SOFTRESET bit
+ * @oh: struct omap_hwmod *
+ *
+ * This is a public function exposed to drivers. Some drivers may need to do
+ * some settings before and after resetting the device. Those drivers after
+ * doing the necessary settings could use this function to start a reset by
+ * setting the SYSCONFIG.SOFTRESET bit.
+ */
+int omap_hwmod_softreset(struct omap_hwmod *oh)
+{
+ u32 v;
+ int ret;
+
+ if (!oh || !(oh->_sysc_cache))
+ return -EINVAL;
+
+ v = oh->_sysc_cache;
+ ret = _set_softreset(oh, &v);
+ if (ret)
+ goto error;
+ _write_sysconfig(v, oh);
+
+ ret = _clear_softreset(oh, &v);
+ if (ret)
+ goto error;
+ _write_sysconfig(v, oh);
+
+error:
+ return ret;
+}
+
+/**
+ * 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_links - register an array of hwmod links
+ * @ois: pointer to an array of omap_hwmod_ocp_if to register
+ *
+ * Intended to be called early in boot before the clock framework is
+ * initialized. If @ois is not null, will register all omap_hwmods
+ * listed in @ois that are valid for this chip. Returns -EINVAL if
+ * omap_hwmod_init() hasn't been called before calling this function,
+ * -ENOMEM if the link memory area can't be allocated, or 0 upon
+ * success.
+ */
+int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois)
+{
+ int r, i;
+
+ if (!inited)
+ return -EINVAL;
+
+ if (!ois)
+ return 0;
+
+ if (ois[0] == NULL) /* Empty list */
+ return 0;
+
+ if (!linkspace) {
+ if (_alloc_linkspace(ois)) {
+ pr_err("omap_hwmod: could not allocate link space\n");
+ return -ENOMEM;
+ }
+ }
+
+ i = 0;
+ do {
+ r = _register_link(ois[i]);
+ WARN(r && r != -EEXIST,
+ "omap_hwmod: _register_link(%s -> %s) returned %d\n",
+ ois[i]->master->name, ois[i]->slave->name, r);
+ } while (ois[++i]);
+
+ return 0;
+}
+
+/**
+ * _ensure_mpu_hwmod_is_setup - ensure the MPU SS hwmod is init'ed and set up
+ * @oh: pointer to the hwmod currently being set up (usually not the MPU)
+ *
+ * If the hwmod data corresponding to the MPU subsystem IP block
+ * hasn't been initialized and set up yet, do so now. This must be
+ * done first since sleep dependencies may be added from other hwmods
+ * to the MPU. Intended to be called only by omap_hwmod_setup*(). No
+ * return value.
+ */
+static void __init _ensure_mpu_hwmod_is_setup(struct omap_hwmod *oh)
+{
+ if (!mpu_oh || mpu_oh->_state == _HWMOD_STATE_UNKNOWN)
+ pr_err("omap_hwmod: %s: MPU initiator hwmod %s not yet registered\n",
+ __func__, MPU_INITIATOR_NAME);
+ else if (mpu_oh->_state == _HWMOD_STATE_REGISTERED && oh != mpu_oh)
+ omap_hwmod_setup_one(MPU_INITIATOR_NAME);
+}
+
+/**
+ * omap_hwmod_setup_one - set up a single hwmod
+ * @oh_name: const char * name of the already-registered hwmod to set up
+ *
+ * Initialize and set up a single hwmod. Intended to be used for a
+ * small number of early devices, such as the timer IP blocks used for
+ * the scheduler clock. 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;
+
+ pr_debug("omap_hwmod: %s: %s\n", oh_name, __func__);
+
+ oh = _lookup(oh_name);
+ if (!oh) {
+ WARN(1, "omap_hwmod: %s: hwmod not yet registered\n", oh_name);
+ return -EINVAL;
+ }
+
+ _ensure_mpu_hwmod_is_setup(oh);
+
+ _init(oh, NULL);
+ _setup(oh, NULL);
+
+ return 0;
+}
+
+/**
+ * omap_hwmod_setup_all - set up all registered IP blocks
+ *
+ * Initialize and set up all IP blocks registered with the hwmod code.
+ * 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)
+{
+ _ensure_mpu_hwmod_is_setup(NULL);
+
+ omap_hwmod_for_each(_init, NULL);
+ omap_hwmod_for_each(_setup, NULL);
+
+ return 0;
+}
+omap_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;
+}
+
+/*
+ * IP block data retrieval functions
+ */
+
+/**
+ * omap_hwmod_count_resources - count number of struct resources needed by hwmod
+ * @oh: struct omap_hwmod *
+ * @flags: Type of resources to include when counting (IRQ/DMA/MEM)
+ *
+ * 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, unsigned long flags)
+{
+ int ret = 0;
+
+ if (flags & IORESOURCE_IRQ)
+ ret += _count_mpu_irqs(oh);
+
+ if (flags & IORESOURCE_DMA)
+ ret += _count_sdma_reqs(oh);
+
+ if (flags & IORESOURCE_MEM) {
+ int i = 0;
+ struct omap_hwmod_ocp_if *os;
+ struct list_head *p = oh->slave_ports.next;
+
+ while (i < oh->slaves_cnt) {
+ os = _fetch_next_ocp_if(&p, &i);
+ ret += _count_ocp_if_addr_spaces(os);
+ }
+ }
+
+ 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)
+{
+ struct omap_hwmod_ocp_if *os;
+ struct list_head *p;
+ int i, j, mpu_irqs_cnt, sdma_reqs_cnt, addr_cnt;
+ int r = 0;
+
+ /* For each IRQ, DMA, memory area, fill in array.*/
+
+ mpu_irqs_cnt = _count_mpu_irqs(oh);
+ for (i = 0; i < mpu_irqs_cnt; i++) {
+ unsigned int irq;
+
+ if (oh->xlate_irq)
+ irq = oh->xlate_irq((oh->mpu_irqs + i)->irq);
+ else
+ irq = (oh->mpu_irqs + i)->irq;
+ (res + r)->name = (oh->mpu_irqs + i)->name;
+ (res + r)->start = irq;
+ (res + r)->end = irq;
+ (res + r)->flags = IORESOURCE_IRQ;
+ r++;
+ }
+
+ sdma_reqs_cnt = _count_sdma_reqs(oh);
+ for (i = 0; i < 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++;
+ }
+
+ p = oh->slave_ports.next;
+
+ i = 0;
+ while (i < oh->slaves_cnt) {
+ os = _fetch_next_ocp_if(&p, &i);
+ addr_cnt = _count_ocp_if_addr_spaces(os);
+
+ for (j = 0; j < 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_fill_dma_resources - fill struct resource array with dma data
+ * @oh: struct omap_hwmod *
+ * @res: pointer to the array of struct resource to fill
+ *
+ * Fill the struct resource array @res with dma 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_dma_resources(struct omap_hwmod *oh, struct resource *res)
+{
+ int i, sdma_reqs_cnt;
+ int r = 0;
+
+ sdma_reqs_cnt = _count_sdma_reqs(oh);
+ for (i = 0; i < 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++;
+ }
+
+ return r;
+}
+
+/**
+ * omap_hwmod_get_resource_byname - fetch IP block integration data by name
+ * @oh: struct omap_hwmod * to operate on
+ * @type: one of the IORESOURCE_* constants from include/linux/ioport.h
+ * @name: pointer to the name of the data to fetch (optional)
+ * @rsrc: pointer to a struct resource, allocated by the caller
+ *
+ * Retrieve MPU IRQ, SDMA request line, or address space start/end
+ * data for the IP block pointed to by @oh. The data will be filled
+ * into a struct resource record pointed to by @rsrc. The struct
+ * resource must be allocated by the caller. When @name is non-null,
+ * the data associated with the matching entry in the IRQ/SDMA/address
+ * space hwmod data arrays will be returned. If @name is null, the
+ * first array entry will be returned. Data order is not meaningful
+ * in hwmod data, so callers are strongly encouraged to use a non-null
+ * @name whenever possible to avoid unpredictable effects if hwmod
+ * data is later added that causes data ordering to change. This
+ * function is only intended for use by OMAP core code. Device
+ * drivers should not call this function - the appropriate bus-related
+ * data accessor functions should be used instead. Returns 0 upon
+ * success or a negative error code upon error.
+ */
+int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type,
+ const char *name, struct resource *rsrc)
+{
+ int r;
+ unsigned int irq, dma;
+ u32 pa_start, pa_end;
+
+ if (!oh || !rsrc)
+ return -EINVAL;
+
+ if (type == IORESOURCE_IRQ) {
+ r = _get_mpu_irq_by_name(oh, name, &irq);
+ if (r)
+ return r;
+
+ rsrc->start = irq;
+ rsrc->end = irq;
+ } else if (type == IORESOURCE_DMA) {
+ r = _get_sdma_req_by_name(oh, name, &dma);
+ if (r)
+ return r;
+
+ rsrc->start = dma;
+ rsrc->end = dma;
+ } else if (type == IORESOURCE_MEM) {
+ r = _get_addr_space_by_name(oh, name, &pa_start, &pa_end);
+ if (r)
+ return r;
+
+ rsrc->start = pa_start;
+ rsrc->end = pa_end;
+ } else {
+ return -EINVAL;
+ }
+
+ rsrc->flags = type;
+ rsrc->name = name;
+
+ return 0;
+}
+
+/**
+ * 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;
+ struct omap_hwmod_ocp_if *oi;
+ struct clockdomain *clkdm;
+ struct clk_hw_omap *clk;
+
+ if (!oh)
+ return NULL;
+
+ if (oh->clkdm)
+ return oh->clkdm->pwrdm.ptr;
+
+ if (oh->_clk) {
+ c = oh->_clk;
+ } else {
+ oi = _find_mpu_rt_port(oh);
+ if (!oi)
+ return NULL;
+ c = oi->_clk;
+ }
+
+ clk = to_clk_hw_omap(__clk_get_hw(c));
+ clkdm = clk->clkdm;
+ if (!clkdm)
+ return NULL;
+
+ return 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;
+}
+
+/*
+ * XXX what about functions for drivers to save/restore ocp_sysconfig
+ * for context save/restore operations?
+ */
+
+/**
+ * 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, and enable I/O ring wakeup events for
+ * this IP block if it has dynamic mux entries. Eventually this
+ * should set 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;
+
+ spin_lock_irqsave(&oh->_lock, flags);
+
+ if (oh->class->sysc &&
+ (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) {
+ v = oh->_sysc_cache;
+ _enable_wakeup(oh, &v);
+ _write_sysconfig(v, oh);
+ }
+
+ _set_idle_ioring_wakeup(oh, true);
+ 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, and disable I/O ring wakeup
+ * events for this IP block if it has dynamic mux entries. 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;
+
+ spin_lock_irqsave(&oh->_lock, flags);
+
+ if (oh->class->sysc &&
+ (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) {
+ v = oh->_sysc_cache;
+ _disable_wakeup(oh, &v);
+ _write_sysconfig(v, oh);
+ }
+
+ _set_idle_ioring_wakeup(oh, false);
+ 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_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_*()). See also the documentation
+ * for _setup_postsetup(), above. 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 *
+ *
+ * Returns the context loss count of associated @oh
+ * upon success, or zero if no context loss data is available.
+ *
+ * On OMAP4, this queries the per-hwmod context loss register,
+ * assuming one exists. If not, or on OMAP2/3, this queries the
+ * enclosing powerdomain context loss count.
+ */
+int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
+{
+ struct powerdomain *pwrdm;
+ int ret = 0;
+
+ if (soc_ops.get_context_lost)
+ return soc_ops.get_context_lost(oh);
+
+ pwrdm = omap_hwmod_get_pwrdm(oh);
+ if (pwrdm)
+ ret = pwrdm_get_context_loss_count(pwrdm);
+
+ return ret;
+}
+
+/**
+ * omap_hwmod_init - initialize the hwmod code
+ *
+ * Sets up some function pointers needed by the hwmod code to operate on the
+ * currently-booted SoC. Intended to be called once during kernel init
+ * before any hwmods are registered. No return value.
+ */
+void __init omap_hwmod_init(void)
+{
+ if (cpu_is_omap24xx()) {
+ soc_ops.wait_target_ready = _omap2xxx_3xxx_wait_target_ready;
+ soc_ops.assert_hardreset = _omap2_assert_hardreset;
+ soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
+ soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted;
+ } else if (cpu_is_omap34xx()) {
+ soc_ops.wait_target_ready = _omap2xxx_3xxx_wait_target_ready;
+ soc_ops.assert_hardreset = _omap2_assert_hardreset;
+ soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
+ soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted;
+ soc_ops.init_clkdm = _init_clkdm;
+ } else if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) {
+ soc_ops.enable_module = _omap4_enable_module;
+ soc_ops.disable_module = _omap4_disable_module;
+ soc_ops.wait_target_ready = _omap4_wait_target_ready;
+ soc_ops.assert_hardreset = _omap4_assert_hardreset;
+ soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
+ soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
+ soc_ops.init_clkdm = _init_clkdm;
+ soc_ops.update_context_lost = _omap4_update_context_lost;
+ soc_ops.get_context_lost = _omap4_get_context_lost;
+ } else if (cpu_is_ti816x() || soc_is_am33xx() || soc_is_am43xx()) {
+ soc_ops.enable_module = _omap4_enable_module;
+ soc_ops.disable_module = _omap4_disable_module;
+ soc_ops.wait_target_ready = _omap4_wait_target_ready;
+ soc_ops.assert_hardreset = _omap4_assert_hardreset;
+ soc_ops.deassert_hardreset = _am33xx_deassert_hardreset;
+ soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
+ soc_ops.init_clkdm = _init_clkdm;
+ } else {
+ WARN(1, "omap_hwmod: unknown SoC type\n");
+ }
+
+ inited = true;
+}
+
+/**
+ * omap_hwmod_get_main_clk - get pointer to main clock name
+ * @oh: struct omap_hwmod *
+ *
+ * Returns the main clock name assocated with @oh upon success,
+ * or NULL if @oh is NULL.
+ */
+const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh)
+{
+ if (!oh)
+ return NULL;
+
+ return oh->main_clk;
+}
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h
new file mode 100644
index 000000000..9611c91d9
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod.h
@@ -0,0 +1,758 @@
+/*
+ * omap_hwmod macros, structures
+ *
+ * Copyright (C) 2009-2011 Nokia Corporation
+ * Copyright (C) 2011-2012 Texas Instruments, Inc.
+ * 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>
+
+struct omap_device;
+
+extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type1;
+extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;
+extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type3;
+
+/*
+ * 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_TYPE1_MIDLEMODE_SHIFT)
+#define SYSC_TYPE1_CLOCKACTIVITY_SHIFT 8
+#define SYSC_TYPE1_CLOCKACTIVITY_MASK (0x3 << SYSC_TYPE1_CLOCKACTIVITY_SHIFT)
+#define SYSC_TYPE1_SIDLEMODE_SHIFT 3
+#define SYSC_TYPE1_SIDLEMODE_MASK (0x3 << SYSC_TYPE1_SIDLEMODE_SHIFT)
+#define SYSC_TYPE1_ENAWAKEUP_SHIFT 2
+#define SYSC_TYPE1_ENAWAKEUP_MASK (1 << SYSC_TYPE1_ENAWAKEUP_SHIFT)
+#define SYSC_TYPE1_SOFTRESET_SHIFT 1
+#define SYSC_TYPE1_SOFTRESET_MASK (1 << SYSC_TYPE1_SOFTRESET_SHIFT)
+#define SYSC_TYPE1_AUTOIDLE_SHIFT 0
+#define SYSC_TYPE1_AUTOIDLE_MASK (1 << SYSC_TYPE1_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)
+#define SYSC_TYPE2_DMADISABLE_SHIFT 16
+#define SYSC_TYPE2_DMADISABLE_MASK (0x1 << SYSC_TYPE2_DMADISABLE_SHIFT)
+
+/*
+ * OCP SYSCONFIG bit shifts/masks TYPE3.
+ * This is applicable for some IPs present in AM33XX
+ */
+#define SYSC_TYPE3_SIDLEMODE_SHIFT 0
+#define SYSC_TYPE3_SIDLEMODE_MASK (0x3 << SYSC_TYPE3_SIDLEMODE_SHIFT)
+#define SYSC_TYPE3_MIDLEMODE_SHIFT 2
+#define SYSC_TYPE3_MIDLEMODE_MASK (0x3 << SYSC_TYPE3_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)
+#define HWMOD_IDLEMODE_SMART_WKUP (1 << 3)
+
+/* modulemode control type (SW or HW) */
+#define MODULEMODE_HWCTRL 1
+#define MODULEMODE_SWCTRL 2
+
+#define DEBUG_OMAP2UART1_FLAGS 0
+#define DEBUG_OMAP2UART2_FLAGS 0
+#define DEBUG_OMAP2UART3_FLAGS 0
+#define DEBUG_OMAP3UART3_FLAGS 0
+#define DEBUG_OMAP3UART4_FLAGS 0
+#define DEBUG_OMAP4UART3_FLAGS 0
+#define DEBUG_OMAP4UART4_FLAGS 0
+#define DEBUG_TI81XXUART1_FLAGS 0
+#define DEBUG_TI81XXUART2_FLAGS 0
+#define DEBUG_TI81XXUART3_FLAGS 0
+#define DEBUG_AM33XXUART1_FLAGS 0
+
+#define DEBUG_OMAPUART_FLAGS (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET)
+
+#if defined(CONFIG_DEBUG_OMAP2UART1)
+#undef DEBUG_OMAP2UART1_FLAGS
+#define DEBUG_OMAP2UART1_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP2UART2)
+#undef DEBUG_OMAP2UART2_FLAGS
+#define DEBUG_OMAP2UART2_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP2UART3)
+#undef DEBUG_OMAP2UART3_FLAGS
+#define DEBUG_OMAP2UART3_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP3UART3)
+#undef DEBUG_OMAP3UART3_FLAGS
+#define DEBUG_OMAP3UART3_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP3UART4)
+#undef DEBUG_OMAP3UART4_FLAGS
+#define DEBUG_OMAP3UART4_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP4UART3)
+#undef DEBUG_OMAP4UART3_FLAGS
+#define DEBUG_OMAP4UART3_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP4UART4)
+#undef DEBUG_OMAP4UART4_FLAGS
+#define DEBUG_OMAP4UART4_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_TI81XXUART1)
+#undef DEBUG_TI81XXUART1_FLAGS
+#define DEBUG_TI81XXUART1_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_TI81XXUART2)
+#undef DEBUG_TI81XXUART2_FLAGS
+#define DEBUG_TI81XXUART2_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_TI81XXUART3)
+#undef DEBUG_TI81XXUART3_FLAGS
+#define DEBUG_TI81XXUART3_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_AM33XXUART1)
+#undef DEBUG_AM33XXUART1_FLAGS
+#define DEBUG_AM33XXUART1_FLAGS DEBUG_OMAPUART_FLAGS
+#endif
+
+/**
+ * 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;
+ int *irqs;
+ bool enabled;
+};
+
+/**
+ * struct omap_hwmod_irq_info - MPU IRQs used by the hwmod
+ * @name: name of the IRQ channel (module local name)
+ * @irq: IRQ channel ID (should be non-negative except -1 = terminator)
+ *
+ * @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;
+ s16 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 (should be non-negative except -1 = terminator)
+ *
+ * @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;
+ s16 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)
+#define OCP_USER_DSP (1 << 2)
+#define OCP_USER_IVA (1 << 3)
+
+/* omap_hwmod_ocp_if.flags bits */
+#define OCPIF_SWSUP_IDLE (1 << 0)
+#define OCPIF_CAN_BURST (1 << 1)
+
+/* omap_hwmod_ocp_if._int_flags possibilities */
+#define _OCPIF_INT_FLAGS_REGISTERED (1 << 0)
+
+
+/**
+ * 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
+ * @width: OCP data width
+ * @user: initiators using this interface (see OCP_USER_* macros above)
+ * @flags: OCP interface flags (see OCPIF_* macros above)
+ * @_int_flags: internal flags (see _OCPIF_INT_FLAGS* 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 width;
+ u8 user;
+ u8 flags;
+ u8 _int_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)
+#define MSTANDBY_SMART_WKUP (HWMOD_IDLEMODE_SMART_WKUP << 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)
+#define SYSC_HAS_DMADISABLE (1 << 10)
+
+/* 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
+ * @dmadisable_shift: Offset of the dmadisable bit
+ */
+struct omap_hwmod_sysc_fields {
+ u8 midle_shift;
+ u8 clkact_shift;
+ u8 sidle_shift;
+ u8 enwkup_shift;
+ u8 srst_shift;
+ u8 autoidle_shift;
+ u8 dmadisable_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)
+ * @srst_udelay: Delay needed after doing a softreset in usecs
+ * @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 {
+ u32 rev_offs;
+ u32 sysc_offs;
+ u32 syss_offs;
+ u16 sysc_flags;
+ struct omap_hwmod_sysc_fields *sysc_fields;
+ u8 srst_udelay;
+ u8 idlemodes;
+ u8 clockact;
+};
+
+/**
+ * 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;
+};
+
+/*
+ * Possible values for struct omap_hwmod_omap4_prcm.flags
+ *
+ * HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT: Some IP blocks don't have a PRCM
+ * module-level context loss register associated with them; this
+ * flag bit should be set in those cases
+ */
+#define HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT (1 << 0)
+
+/**
+ * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
+ * @clkctrl_offs: offset of the PRCM clock control register
+ * @rstctrl_offs: offset of the XXX_RSTCTRL register located in the PRM
+ * @context_offs: offset of the RM_*_CONTEXT register
+ * @lostcontext_mask: bitmask for selecting bits from RM_*_CONTEXT register
+ * @rstst_reg: (AM33XX only) address of the XXX_RSTST register in the PRM
+ * @submodule_wkdep_bit: bit shift of the WKDEP range
+ * @flags: PRCM register capabilities for this IP block
+ * @modulemode: allowable modulemodes
+ * @context_lost_counter: Count of module level context lost
+ *
+ * If @lostcontext_mask is not defined, context loss check code uses
+ * whole register without masking. @lostcontext_mask should only be
+ * defined in cases where @context_offs register is shared by two or
+ * more hwmods.
+ */
+struct omap_hwmod_omap4_prcm {
+ u16 clkctrl_offs;
+ u16 rstctrl_offs;
+ u16 rstst_offs;
+ u16 context_offs;
+ u32 lostcontext_mask;
+ u8 submodule_wkdep_bit;
+ u8 modulemode;
+ u8 flags;
+ int context_lost_counter;
+};
+
+
+/*
+ * 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_MSTANDBY: 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
+ * HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for
+ * this IP block comes from an off-chip source and is not always
+ * enabled. This prevents the hwmod code from being able to
+ * enable and reset the IP block early. XXX Eventually it should
+ * be possible to query the clock framework for this information.
+ * HWMOD_BLOCK_WFI: Some OMAP peripherals apparently don't work
+ * correctly if the MPU is allowed to go idle while the
+ * peripherals are active. This is apparently true for the I2C on
+ * OMAP2420, and also the EMAC on AM3517/3505. It's unlikely that
+ * this is really true -- we're probably not configuring something
+ * correctly, or this is being abused to deal with some PM latency
+ * issues -- but we're currently suffering from a shortage of
+ * folks who are able to track these issues down properly.
+ * HWMOD_FORCE_MSTANDBY: Always keep MIDLEMODE bits cleared so that device
+ * is kept in force-standby mode. Failing to do so causes PM problems
+ * with musb on OMAP3630 at least. Note that musb has a dedicated register
+ * to control MSTANDBY signal when MIDLEMODE is set to force-standby.
+ * HWMOD_SWSUP_SIDLE_ACT: omap_hwmod code should manually bring the module
+ * out of idle, but rely on smart-idle to the put it back in idle,
+ * so the wakeups are still functional (Only known case for now is UART)
+ * HWMOD_RECONFIG_IO_CHAIN: omap_hwmod code needs to reconfigure wake-up
+ * events by calling _reconfigure_io_chain() when a device is enabled
+ * or idled.
+ */
+#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)
+#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9)
+#define HWMOD_BLOCK_WFI (1 << 10)
+#define HWMOD_FORCE_MSTANDBY (1 << 11)
+#define HWMOD_SWSUP_SIDLE_ACT (1 << 12)
+#define HWMOD_RECONFIG_IO_CHAIN (1 << 13)
+
+/*
+ * 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_SYSCONFIG_LOADED: set when the OCP_SYSCONFIG value has been cached
+ * _HWMOD_SKIP_ENABLE: set if hwmod enabled during init (HWMOD_INIT_NO_IDLE) -
+ * causes the first call to _enable() to only update the pinmux
+ */
+#define _HWMOD_NO_MPU_PORT (1 << 0)
+#define _HWMOD_SYSCONFIG_LOADED (1 << 1)
+#define _HWMOD_SKIP_ENABLE (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
+ * @enable_preprogram: ptr to fn to be executed during device enable
+ *
+ * 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);
+ int (*enable_preprogram)(struct omap_hwmod *oh);
+};
+
+/**
+ * struct omap_hwmod_link - internal structure linking hwmods with ocp_ifs
+ * @ocp_if: OCP interface structure record pointer
+ * @node: list_head pointing to next struct omap_hwmod_link in a list
+ */
+struct omap_hwmod_link {
+ struct omap_hwmod_ocp_if *ocp_if;
+ struct list_head node;
+};
+
+/**
+ * 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
+ * @sdma_reqs: ptr to an array of System DMA request IDs
+ * @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..*)
+ * @voltdm: pointer to voltage domain (filled in at runtime)
+ * @dev_attr: arbitrary device attributes that can be passed to the driver
+ * @_sysc_cache: internal-use hwmod flags
+ * @mpu_rt_idx: index of device address space for register target (for DT boot)
+ * @_mpu_rt_va: cached register target start address (internal use)
+ * @_mpu_port: cached MPU register target slave (internal use)
+ * @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)
+ * @_lock: spinlock serializing operations on this hwmod
+ * @node: list node for hwmod list (internal use)
+ * @parent_hwmod: (temporary) a pointer to the hierarchical parent of this hwmod
+ *
+ * @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.
+ *
+ * @masters and @slaves are now deprecated.
+ *
+ * @parent_hwmod is temporary; there should be no need for it, as this
+ * information should already be expressed in the OCP interface
+ * structures. @parent_hwmod is present as a workaround until we improve
+ * handling for hwmods with multiple parents (e.g., OMAP4+ DSS with
+ * multiple register targets across different interconnects).
+ */
+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 *clkdm_name;
+ struct clockdomain *clkdm;
+ struct list_head master_ports; /* connect to *_IA */
+ struct list_head slave_ports; /* connect to *_TA */
+ void *dev_attr;
+ u32 _sysc_cache;
+ void __iomem *_mpu_rt_va;
+ spinlock_t _lock;
+ struct lock_class_key hwmod_key; /* unique lock class */
+ struct list_head node;
+ struct omap_hwmod_ocp_if *_mpu_port;
+ unsigned int (*xlate_irq)(unsigned int);
+ u16 flags;
+ u8 mpu_rt_idx;
+ u8 response_lat;
+ 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;
+ struct omap_hwmod *parent_hwmod;
+};
+
+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_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);
+
+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_softreset(struct omap_hwmod *oh);
+
+int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags);
+int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
+int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res);
+int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type,
+ const char *name, 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_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);
+int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
+
+extern void __init omap_hwmod_init(void);
+
+const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh);
+
+/*
+ *
+ */
+
+extern int omap_hwmod_aess_preprogram(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);
+extern int omap54xx_hwmod_init(void);
+extern int am33xx_hwmod_init(void);
+extern int ti81xx_hwmod_init(void);
+extern int dra7xx_hwmod_init(void);
+int am43xx_hwmod_init(void);
+
+extern int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois);
+
+#endif
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 000000000..65b164709
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -0,0 +1,488 @@
+/*
+ * omap_hwmod_2420_data.c - hardware modules present on the OMAP2420 chips
+ *
+ * Copyright (C) 2009-2011 Nokia Corporation
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * 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 <linux/i2c-omap.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+#include <linux/omap-dma.h>
+#include <plat/dmtimer.h>
+
+#include "omap_hwmod.h"
+#include "l3_2xxx.h"
+#include "l4_2xxx.h"
+
+#include "omap_hwmod_common_data.h"
+
+#include "cm-regbits-24xx.h"
+#include "prm-regbits-24xx.h"
+#include "i2c.h"
+#include "mmc.h"
+#include "serial.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.
+ */
+
+/*
+ * IP blocks
+ */
+
+/* IVA1 (IVA1) */
+static struct omap_hwmod_class iva1_hwmod_class = {
+ .name = "iva1",
+};
+
+static struct omap_hwmod_rst_info omap2420_iva_resets[] = {
+ { .name = "iva", .rst_shift = 8 },
+};
+
+static struct omap_hwmod omap2420_iva_hwmod = {
+ .name = "iva",
+ .class = &iva1_hwmod_class,
+ .clkdm_name = "iva1_clkdm",
+ .rst_lines = omap2420_iva_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap2420_iva_resets),
+ .main_clk = "iva1_ifck",
+};
+
+/* DSP */
+static struct omap_hwmod_class dsp_hwmod_class = {
+ .name = "dsp",
+};
+
+static struct omap_hwmod_rst_info omap2420_dsp_resets[] = {
+ { .name = "logic", .rst_shift = 0 },
+ { .name = "mmu", .rst_shift = 1 },
+};
+
+static struct omap_hwmod omap2420_dsp_hwmod = {
+ .name = "dsp",
+ .class = &dsp_hwmod_class,
+ .clkdm_name = "dsp_clkdm",
+ .rst_lines = omap2420_dsp_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap2420_dsp_resets),
+ .main_clk = "dsp_fck",
+};
+
+/* 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,
+ .rev = OMAP_I2C_IP_VERSION_1,
+ .reset = &omap_i2c_reset,
+};
+
+static struct omap_i2c_dev_attr i2c_dev_attr = {
+ .flags = OMAP_I2C_FLAG_NO_FIFO |
+ OMAP_I2C_FLAG_SIMPLE_CLOCK |
+ OMAP_I2C_FLAG_16BIT_DATA_REG |
+ OMAP_I2C_FLAG_BUS_SHIFT_2,
+};
+
+/* I2C1 */
+static struct omap_hwmod omap2420_i2c1_hwmod = {
+ .name = "i2c1",
+ .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,
+ },
+ },
+ .class = &i2c_class,
+ .dev_attr = &i2c_dev_attr,
+ /*
+ * From mach-omap2/pm24xx.c: "Putting MPU into the WFI state
+ * while a transfer is active seems to cause the I2C block to
+ * timeout. Why? Good question."
+ */
+ .flags = (HWMOD_16BIT_REG | HWMOD_BLOCK_WFI),
+};
+
+/* I2C2 */
+static struct omap_hwmod omap2420_i2c2_hwmod = {
+ .name = "i2c2",
+ .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,
+ },
+ },
+ .class = &i2c_class,
+ .dev_attr = &i2c_dev_attr,
+ .flags = HWMOD_16BIT_REG,
+};
+
+/* 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 omap2420_dma_system_hwmod = {
+ .name = "dma",
+ .class = &omap2xxx_dma_hwmod_class,
+ .mpu_irqs = omap2_dma_system_irqs,
+ .main_clk = "core_l3_ck",
+ .dev_attr = &dma_dev_attr,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* mailbox */
+static struct omap_hwmod omap2420_mailbox_hwmod = {
+ .name = "mailbox",
+ .class = &omap2xxx_mailbox_hwmod_class,
+ .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,
+ },
+ },
+};
+
+/*
+ * 'mcbsp' class
+ * multi channel buffered serial port controller
+ */
+
+static struct omap_hwmod_class omap2420_mcbsp_hwmod_class = {
+ .name = "mcbsp",
+};
+
+static struct omap_hwmod_opt_clk mcbsp_opt_clks[] = {
+ { .role = "pad_fck", .clk = "mcbsp_clks" },
+ { .role = "prcm_fck", .clk = "func_96m_ck" },
+};
+
+/* mcbsp1 */
+static struct omap_hwmod omap2420_mcbsp1_hwmod = {
+ .name = "mcbsp1",
+ .class = &omap2420_mcbsp_hwmod_class,
+ .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,
+ },
+ },
+ .opt_clks = mcbsp_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod omap2420_mcbsp2_hwmod = {
+ .name = "mcbsp2",
+ .class = &omap2420_mcbsp_hwmod_class,
+ .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,
+ },
+ },
+ .opt_clks = mcbsp_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks),
+};
+
+static struct omap_hwmod_class_sysconfig omap2420_msdi_sysc = {
+ .rev_offs = 0x3c,
+ .sysc_offs = 0x64,
+ .syss_offs = 0x68,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2420_msdi_hwmod_class = {
+ .name = "msdi",
+ .sysc = &omap2420_msdi_sysc,
+ .reset = &omap_msdi_reset,
+};
+
+/* msdi1 */
+static struct omap_hwmod omap2420_msdi1_hwmod = {
+ .name = "msdi1",
+ .class = &omap2420_msdi_hwmod_class,
+ .main_clk = "mmc_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP2420_EN_MMC_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP2420_ST_MMC_SHIFT,
+ },
+ },
+ .flags = HWMOD_16BIT_REG,
+};
+
+/* HDQ1W/1-wire */
+static struct omap_hwmod omap2420_hdq1w_hwmod = {
+ .name = "hdq1w",
+ .main_clk = "hdq_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_HDQ_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_HDQ_SHIFT,
+ },
+ },
+ .class = &omap2_hdq1w_class,
+};
+
+/*
+ * interfaces
+ */
+
+/* L4 CORE -> I2C1 interface */
+static struct omap_hwmod_ocp_if omap2420_l4_core__i2c1 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2420_i2c1_hwmod,
+ .clk = "i2c1_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> I2C2 interface */
+static struct omap_hwmod_ocp_if omap2420_l4_core__i2c2 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2420_i2c2_hwmod,
+ .clk = "i2c2_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* IVA <- L3 interface */
+static struct omap_hwmod_ocp_if omap2420_l3__iva = {
+ .master = &omap2xxx_l3_main_hwmod,
+ .slave = &omap2420_iva_hwmod,
+ .clk = "core_l3_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* DSP <- L3 interface */
+static struct omap_hwmod_ocp_if omap2420_l3__dsp = {
+ .master = &omap2xxx_l3_main_hwmod,
+ .slave = &omap2420_dsp_hwmod,
+ .clk = "dsp_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> timer1 */
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__timer1 = {
+ .master = &omap2xxx_l4_wkup_hwmod,
+ .slave = &omap2xxx_timer1_hwmod,
+ .clk = "gpt1_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> wd_timer2 */
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__wd_timer2 = {
+ .master = &omap2xxx_l4_wkup_hwmod,
+ .slave = &omap2xxx_wd_timer2_hwmod,
+ .clk = "mpu_wdt_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio1 */
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio1 = {
+ .master = &omap2xxx_l4_wkup_hwmod,
+ .slave = &omap2xxx_gpio1_hwmod,
+ .clk = "gpios_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio2 */
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio2 = {
+ .master = &omap2xxx_l4_wkup_hwmod,
+ .slave = &omap2xxx_gpio2_hwmod,
+ .clk = "gpios_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio3 */
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio3 = {
+ .master = &omap2xxx_l4_wkup_hwmod,
+ .slave = &omap2xxx_gpio3_hwmod,
+ .clk = "gpios_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio4 */
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio4 = {
+ .master = &omap2xxx_l4_wkup_hwmod,
+ .slave = &omap2xxx_gpio4_hwmod,
+ .clk = "gpios_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system -> L3 */
+static struct omap_hwmod_ocp_if omap2420_dma_system__l3 = {
+ .master = &omap2420_dma_system_hwmod,
+ .slave = &omap2xxx_l3_main_hwmod,
+ .clk = "core_l3_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> dma_system */
+static struct omap_hwmod_ocp_if omap2420_l4_core__dma_system = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2420_dma_system_hwmod,
+ .clk = "sdma_ick",
+ .addr = omap2_dma_system_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> mailbox */
+static struct omap_hwmod_ocp_if omap2420_l4_core__mailbox = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2420_mailbox_hwmod,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> mcbsp1 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__mcbsp1 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2420_mcbsp1_hwmod,
+ .clk = "mcbsp1_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> mcbsp2 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__mcbsp2 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2420_mcbsp2_hwmod,
+ .clk = "mcbsp2_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> msdi1 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__msdi1 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2420_msdi1_hwmod,
+ .clk = "mmc_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> hdq1w interface */
+static struct omap_hwmod_ocp_if omap2420_l4_core__hdq1w = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2420_hdq1w_hwmod,
+ .clk = "hdq_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+ .flags = OMAP_FIREWALL_L4 | OCPIF_SWSUP_IDLE,
+};
+
+
+/* l4_wkup -> 32ksync_counter */
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__counter_32k = {
+ .master = &omap2xxx_l4_wkup_hwmod,
+ .slave = &omap2xxx_counter_32k_hwmod,
+ .clk = "sync_32k_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if omap2420_l3__gpmc = {
+ .master = &omap2xxx_l3_main_hwmod,
+ .slave = &omap2xxx_gpmc_hwmod,
+ .clk = "core_l3_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap2420_hwmod_ocp_ifs[] __initdata = {
+ &omap2xxx_l3_main__l4_core,
+ &omap2xxx_mpu__l3_main,
+ &omap2xxx_dss__l3,
+ &omap2xxx_l4_core__mcspi1,
+ &omap2xxx_l4_core__mcspi2,
+ &omap2xxx_l4_core__l4_wkup,
+ &omap2_l4_core__uart1,
+ &omap2_l4_core__uart2,
+ &omap2_l4_core__uart3,
+ &omap2420_l4_core__i2c1,
+ &omap2420_l4_core__i2c2,
+ &omap2420_l3__iva,
+ &omap2420_l3__dsp,
+ &omap2420_l4_wkup__timer1,
+ &omap2xxx_l4_core__timer2,
+ &omap2xxx_l4_core__timer3,
+ &omap2xxx_l4_core__timer4,
+ &omap2xxx_l4_core__timer5,
+ &omap2xxx_l4_core__timer6,
+ &omap2xxx_l4_core__timer7,
+ &omap2xxx_l4_core__timer8,
+ &omap2xxx_l4_core__timer9,
+ &omap2xxx_l4_core__timer10,
+ &omap2xxx_l4_core__timer11,
+ &omap2xxx_l4_core__timer12,
+ &omap2420_l4_wkup__wd_timer2,
+ &omap2xxx_l4_core__dss,
+ &omap2xxx_l4_core__dss_dispc,
+ &omap2xxx_l4_core__dss_rfbi,
+ &omap2xxx_l4_core__dss_venc,
+ &omap2420_l4_wkup__gpio1,
+ &omap2420_l4_wkup__gpio2,
+ &omap2420_l4_wkup__gpio3,
+ &omap2420_l4_wkup__gpio4,
+ &omap2420_dma_system__l3,
+ &omap2420_l4_core__dma_system,
+ &omap2420_l4_core__mailbox,
+ &omap2420_l4_core__mcbsp1,
+ &omap2420_l4_core__mcbsp2,
+ &omap2420_l4_core__msdi1,
+ &omap2xxx_l4_core__rng,
+ &omap2xxx_l4_core__sham,
+ &omap2xxx_l4_core__aes,
+ &omap2420_l4_core__hdq1w,
+ &omap2420_l4_wkup__counter_32k,
+ &omap2420_l3__gpmc,
+ NULL,
+};
+
+int __init omap2420_hwmod_init(void)
+{
+ omap_hwmod_init();
+ return omap_hwmod_register_links(omap2420_hwmod_ocp_ifs);
+}
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 000000000..79127b35f
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -0,0 +1,711 @@
+/*
+ * omap_hwmod_2430_data.c - hardware modules present on the OMAP2430 chips
+ *
+ * Copyright (C) 2009-2011 Nokia Corporation
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * 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 <linux/i2c-omap.h>
+#include <linux/platform_data/asoc-ti-mcbsp.h>
+#include <linux/platform_data/hsmmc-omap.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+#include <linux/omap-dma.h>
+#include <plat/dmtimer.h>
+
+#include "omap_hwmod.h"
+#include "l3_2xxx.h"
+
+#include "soc.h"
+#include "omap_hwmod_common_data.h"
+#include "prm-regbits-24xx.h"
+#include "cm-regbits-24xx.h"
+#include "i2c.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.
+ */
+
+/*
+ * IP blocks
+ */
+
+/* IVA2 (IVA2) */
+static struct omap_hwmod_rst_info omap2430_iva_resets[] = {
+ { .name = "logic", .rst_shift = 0 },
+ { .name = "mmu", .rst_shift = 1 },
+};
+
+static struct omap_hwmod omap2430_iva_hwmod = {
+ .name = "iva",
+ .class = &iva_hwmod_class,
+ .clkdm_name = "dsp_clkdm",
+ .rst_lines = omap2430_iva_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap2430_iva_resets),
+ .main_clk = "dsp_fck",
+};
+
+/* 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,
+ .rev = OMAP_I2C_IP_VERSION_1,
+ .reset = &omap_i2c_reset,
+};
+
+static struct omap_i2c_dev_attr i2c_dev_attr = {
+ .fifo_depth = 8, /* bytes */
+ .flags = OMAP_I2C_FLAG_BUS_SHIFT_2 |
+ OMAP_I2C_FLAG_FORCE_19200_INT_CLK,
+};
+
+/* I2C1 */
+static struct omap_hwmod omap2430_i2c1_hwmod = {
+ .name = "i2c1",
+ .flags = HWMOD_16BIT_REG,
+ .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,
+ },
+ },
+ .class = &i2c_class,
+ .dev_attr = &i2c_dev_attr,
+};
+
+/* I2C2 */
+static struct omap_hwmod omap2430_i2c2_hwmod = {
+ .name = "i2c2",
+ .flags = HWMOD_16BIT_REG,
+ .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,
+ },
+ },
+ .class = &i2c_class,
+ .dev_attr = &i2c_dev_attr,
+};
+
+/* gpio5 */
+static struct omap_hwmod omap2430_gpio5_hwmod = {
+ .name = "gpio5",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .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,
+ },
+ },
+ .class = &omap2xxx_gpio_hwmod_class,
+ .dev_attr = &omap2xxx_gpio_dev_attr,
+};
+
+/* 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 omap2430_dma_system_hwmod = {
+ .name = "dma",
+ .class = &omap2xxx_dma_hwmod_class,
+ .mpu_irqs = omap2_dma_system_irqs,
+ .main_clk = "core_l3_ck",
+ .dev_attr = &dma_dev_attr,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* mailbox */
+static struct omap_hwmod omap2430_mailbox_hwmod = {
+ .name = "mailbox",
+ .class = &omap2xxx_mailbox_hwmod_class,
+ .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,
+ },
+ },
+};
+
+/* mcspi3 */
+static struct omap2_mcspi_dev_attr omap_mcspi3_dev_attr = {
+ .num_chipselect = 2,
+};
+
+static struct omap_hwmod omap2430_mcspi3_hwmod = {
+ .name = "mcspi3",
+ .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,
+ },
+ },
+ .class = &omap2xxx_mcspi_class,
+ .dev_attr = &omap_mcspi3_dev_attr,
+};
+
+/* 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 omap2430_usbhsotg_hwmod = {
+ .name = "usb_otg_hs",
+ .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,
+ },
+ },
+ .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,
+};
+
+/*
+ * '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,
+};
+
+static struct omap_hwmod_opt_clk mcbsp_opt_clks[] = {
+ { .role = "pad_fck", .clk = "mcbsp_clks" },
+ { .role = "prcm_fck", .clk = "func_96m_ck" },
+};
+
+/* mcbsp1 */
+static struct omap_hwmod omap2430_mcbsp1_hwmod = {
+ .name = "mcbsp1",
+ .class = &omap2430_mcbsp_hwmod_class,
+ .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,
+ },
+ },
+ .opt_clks = mcbsp_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod omap2430_mcbsp2_hwmod = {
+ .name = "mcbsp2",
+ .class = &omap2430_mcbsp_hwmod_class,
+ .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,
+ },
+ },
+ .opt_clks = mcbsp_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks),
+};
+
+/* mcbsp3 */
+static struct omap_hwmod omap2430_mcbsp3_hwmod = {
+ .name = "mcbsp3",
+ .class = &omap2430_mcbsp_hwmod_class,
+ .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,
+ },
+ },
+ .opt_clks = mcbsp_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks),
+};
+
+/* mcbsp4 */
+static struct omap_hwmod omap2430_mcbsp4_hwmod = {
+ .name = "mcbsp4",
+ .class = &omap2430_mcbsp_hwmod_class,
+ .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,
+ },
+ },
+ .opt_clks = mcbsp_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks),
+};
+
+/* mcbsp5 */
+static struct omap_hwmod omap2430_mcbsp5_hwmod = {
+ .name = "mcbsp5",
+ .class = &omap2430_mcbsp_hwmod_class,
+ .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,
+ },
+ },
+ .opt_clks = mcbsp_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks),
+};
+
+/* 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_opt_clk omap2430_mmc1_opt_clks[] = {
+ { .role = "dbck", .clk = "mmchsdb1_fck" },
+};
+
+static struct omap_hsmmc_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,
+ .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,
+ .class = &omap2430_mmc_class,
+};
+
+/* MMC/SD/SDIO2 */
+static struct omap_hwmod_opt_clk omap2430_mmc2_opt_clks[] = {
+ { .role = "dbck", .clk = "mmchsdb2_fck" },
+};
+
+static struct omap_hwmod omap2430_mmc2_hwmod = {
+ .name = "mmc2",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .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,
+ },
+ },
+ .class = &omap2430_mmc_class,
+};
+
+/* HDQ1W/1-wire */
+static struct omap_hwmod omap2430_hdq1w_hwmod = {
+ .name = "hdq1w",
+ .main_clk = "hdq_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_HDQ_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_HDQ_SHIFT,
+ },
+ },
+ .class = &omap2_hdq1w_class,
+};
+
+/*
+ * interfaces
+ */
+
+/* L3 -> L4_CORE interface */
+/* l3_core -> usbhsotg interface */
+static struct omap_hwmod_ocp_if omap2430_usbhsotg__l3 = {
+ .master = &omap2430_usbhsotg_hwmod,
+ .slave = &omap2xxx_l3_main_hwmod,
+ .clk = "core_l3_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* L4 CORE -> I2C1 interface */
+static struct omap_hwmod_ocp_if omap2430_l4_core__i2c1 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2430_i2c1_hwmod,
+ .clk = "i2c1_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> I2C2 interface */
+static struct omap_hwmod_ocp_if omap2430_l4_core__i2c2 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2430_i2c2_hwmod,
+ .clk = "i2c2_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core ->usbhsotg interface */
+static struct omap_hwmod_ocp_if omap2430_l4_core__usbhsotg = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2430_usbhsotg_hwmod,
+ .clk = "usb_l4_ick",
+ .user = OCP_USER_MPU,
+};
+
+/* L4 CORE -> MMC1 interface */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mmc1 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2430_mmc1_hwmod,
+ .clk = "mmchs1_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> MMC2 interface */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mmc2 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2430_mmc2_hwmod,
+ .clk = "mmchs2_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 core -> mcspi3 interface */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcspi3 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2430_mcspi3_hwmod,
+ .clk = "mcspi3_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* IVA2 <- L3 interface */
+static struct omap_hwmod_ocp_if omap2430_l3__iva = {
+ .master = &omap2xxx_l3_main_hwmod,
+ .slave = &omap2430_iva_hwmod,
+ .clk = "core_l3_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> timer1 */
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__timer1 = {
+ .master = &omap2xxx_l4_wkup_hwmod,
+ .slave = &omap2xxx_timer1_hwmod,
+ .clk = "gpt1_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> wd_timer2 */
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__wd_timer2 = {
+ .master = &omap2xxx_l4_wkup_hwmod,
+ .slave = &omap2xxx_wd_timer2_hwmod,
+ .clk = "mpu_wdt_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio1 */
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio1 = {
+ .master = &omap2xxx_l4_wkup_hwmod,
+ .slave = &omap2xxx_gpio1_hwmod,
+ .clk = "gpios_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio2 */
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio2 = {
+ .master = &omap2xxx_l4_wkup_hwmod,
+ .slave = &omap2xxx_gpio2_hwmod,
+ .clk = "gpios_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio3 */
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio3 = {
+ .master = &omap2xxx_l4_wkup_hwmod,
+ .slave = &omap2xxx_gpio3_hwmod,
+ .clk = "gpios_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio4 */
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio4 = {
+ .master = &omap2xxx_l4_wkup_hwmod,
+ .slave = &omap2xxx_gpio4_hwmod,
+ .clk = "gpios_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> gpio5 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__gpio5 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2430_gpio5_hwmod,
+ .clk = "gpio5_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system -> L3 */
+static struct omap_hwmod_ocp_if omap2430_dma_system__l3 = {
+ .master = &omap2430_dma_system_hwmod,
+ .slave = &omap2xxx_l3_main_hwmod,
+ .clk = "core_l3_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> dma_system */
+static struct omap_hwmod_ocp_if omap2430_l4_core__dma_system = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2430_dma_system_hwmod,
+ .clk = "sdma_ick",
+ .addr = omap2_dma_system_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> mailbox */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mailbox = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2430_mailbox_hwmod,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> mcbsp1 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp1 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2430_mcbsp1_hwmod,
+ .clk = "mcbsp1_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> mcbsp2 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp2 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2430_mcbsp2_hwmod,
+ .clk = "mcbsp2_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> mcbsp3 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp3 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2430_mcbsp3_hwmod,
+ .clk = "mcbsp3_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> mcbsp4 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp4 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2430_mcbsp4_hwmod,
+ .clk = "mcbsp4_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> mcbsp5 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp5 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2430_mcbsp5_hwmod,
+ .clk = "mcbsp5_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> hdq1w */
+static struct omap_hwmod_ocp_if omap2430_l4_core__hdq1w = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2430_hdq1w_hwmod,
+ .clk = "hdq_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+ .flags = OMAP_FIREWALL_L4 | OCPIF_SWSUP_IDLE,
+};
+
+/* l4_wkup -> 32ksync_counter */
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__counter_32k = {
+ .master = &omap2xxx_l4_wkup_hwmod,
+ .slave = &omap2xxx_counter_32k_hwmod,
+ .clk = "sync_32k_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if omap2430_l3__gpmc = {
+ .master = &omap2xxx_l3_main_hwmod,
+ .slave = &omap2xxx_gpmc_hwmod,
+ .clk = "core_l3_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap2430_hwmod_ocp_ifs[] __initdata = {
+ &omap2xxx_l3_main__l4_core,
+ &omap2xxx_mpu__l3_main,
+ &omap2xxx_dss__l3,
+ &omap2430_usbhsotg__l3,
+ &omap2430_l4_core__i2c1,
+ &omap2430_l4_core__i2c2,
+ &omap2xxx_l4_core__l4_wkup,
+ &omap2_l4_core__uart1,
+ &omap2_l4_core__uart2,
+ &omap2_l4_core__uart3,
+ &omap2430_l4_core__usbhsotg,
+ &omap2430_l4_core__mmc1,
+ &omap2430_l4_core__mmc2,
+ &omap2xxx_l4_core__mcspi1,
+ &omap2xxx_l4_core__mcspi2,
+ &omap2430_l4_core__mcspi3,
+ &omap2430_l3__iva,
+ &omap2430_l4_wkup__timer1,
+ &omap2xxx_l4_core__timer2,
+ &omap2xxx_l4_core__timer3,
+ &omap2xxx_l4_core__timer4,
+ &omap2xxx_l4_core__timer5,
+ &omap2xxx_l4_core__timer6,
+ &omap2xxx_l4_core__timer7,
+ &omap2xxx_l4_core__timer8,
+ &omap2xxx_l4_core__timer9,
+ &omap2xxx_l4_core__timer10,
+ &omap2xxx_l4_core__timer11,
+ &omap2xxx_l4_core__timer12,
+ &omap2430_l4_wkup__wd_timer2,
+ &omap2xxx_l4_core__dss,
+ &omap2xxx_l4_core__dss_dispc,
+ &omap2xxx_l4_core__dss_rfbi,
+ &omap2xxx_l4_core__dss_venc,
+ &omap2430_l4_wkup__gpio1,
+ &omap2430_l4_wkup__gpio2,
+ &omap2430_l4_wkup__gpio3,
+ &omap2430_l4_wkup__gpio4,
+ &omap2430_l4_core__gpio5,
+ &omap2430_dma_system__l3,
+ &omap2430_l4_core__dma_system,
+ &omap2430_l4_core__mailbox,
+ &omap2430_l4_core__mcbsp1,
+ &omap2430_l4_core__mcbsp2,
+ &omap2430_l4_core__mcbsp3,
+ &omap2430_l4_core__mcbsp4,
+ &omap2430_l4_core__mcbsp5,
+ &omap2430_l4_core__hdq1w,
+ &omap2xxx_l4_core__rng,
+ &omap2xxx_l4_core__sham,
+ &omap2xxx_l4_core__aes,
+ &omap2430_l4_wkup__counter_32k,
+ &omap2430_l3__gpmc,
+ NULL,
+};
+
+int __init omap2430_hwmod_init(void)
+{
+ omap_hwmod_init();
+ return omap_hwmod_register_links(omap2430_hwmod_ocp_ifs);
+}
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c
new file mode 100644
index 000000000..c1e98d589
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c
@@ -0,0 +1,172 @@
+/*
+ * omap_hwmod_2xxx_3xxx_interconnect_data.c - common interconnect data, OMAP2/3
+ *
+ * Copyright (C) 2009-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 handle crossbar/shared link difference for L3?
+ * XXX these should be marked initdata for multi-OMAP kernels
+ */
+#include <asm/sizes.h>
+
+#include "omap_hwmod.h"
+
+#include "omap_hwmod_common_data.h"
+
+struct omap_hwmod_addr_space omap2430_mmc1_addr_space[] = {
+ {
+ .pa_start = 0x4809c000,
+ .pa_end = 0x4809c1ff,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+struct omap_hwmod_addr_space omap2430_mmc2_addr_space[] = {
+ {
+ .pa_start = 0x480b4000,
+ .pa_end = 0x480b41ff,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+struct omap_hwmod_addr_space omap2_i2c1_addr_space[] = {
+ {
+ .pa_start = 0x48070000,
+ .pa_end = 0x48070000 + SZ_128 - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+struct omap_hwmod_addr_space omap2_i2c2_addr_space[] = {
+ {
+ .pa_start = 0x48072000,
+ .pa_end = 0x48072000 + SZ_128 - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+struct omap_hwmod_addr_space omap2_dss_addrs[] = {
+ {
+ .pa_start = 0x48050000,
+ .pa_end = 0x48050000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_addr_space omap2_dss_dispc_addrs[] = {
+ {
+ .pa_start = 0x48050400,
+ .pa_end = 0x48050400 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_addr_space omap2_dss_rfbi_addrs[] = {
+ {
+ .pa_start = 0x48050800,
+ .pa_end = 0x48050800 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_addr_space omap2_dss_venc_addrs[] = {
+ {
+ .pa_start = 0x48050C00,
+ .pa_end = 0x48050C00 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_addr_space omap2_timer10_addrs[] = {
+ {
+ .pa_start = 0x48086000,
+ .pa_end = 0x48086000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_addr_space omap2_timer11_addrs[] = {
+ {
+ .pa_start = 0x48088000,
+ .pa_end = 0x48088000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_addr_space omap2xxx_timer12_addrs[] = {
+ {
+ .pa_start = 0x4808a000,
+ .pa_end = 0x4808a000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_addr_space omap2_mcspi1_addr_space[] = {
+ {
+ .pa_start = 0x48098000,
+ .pa_end = 0x48098000 + SZ_256 - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+struct omap_hwmod_addr_space omap2_mcspi2_addr_space[] = {
+ {
+ .pa_start = 0x4809a000,
+ .pa_end = 0x4809a000 + SZ_256 - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+struct omap_hwmod_addr_space omap2430_mcspi3_addr_space[] = {
+ {
+ .pa_start = 0x480b8000,
+ .pa_end = 0x480b8000 + SZ_256 - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+struct omap_hwmod_addr_space omap2_dma_system_addrs[] = {
+ {
+ .pa_start = 0x48056000,
+ .pa_end = 0x48056000 + SZ_4K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_addr_space omap2_mcbsp1_addrs[] = {
+ {
+ .name = "mpu",
+ .pa_start = 0x48074000,
+ .pa_end = 0x480740ff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_addr_space omap2_hdq1w_addr_space[] = {
+ {
+ .pa_start = 0x480b2000,
+ .pa_end = 0x480b2fff,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
new file mode 100644
index 000000000..c6c6384de
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
@@ -0,0 +1,285 @@
+/*
+ * omap_hwmod_2xxx_3xxx_ipblock_data.c - common IP block data for OMAP2/3
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * 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/dmaengine.h>
+#include <linux/omap-dma.h>
+
+#include "omap_hwmod.h"
+#include "hdq1w.h"
+
+#include "omap_hwmod_common_data.h"
+
+/* UART */
+
+static struct omap_hwmod_class_sysconfig omap2_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,
+};
+
+struct omap_hwmod_class omap2_uart_class = {
+ .name = "uart",
+ .sysc = &omap2_uart_sysc,
+};
+
+/*
+ * 'venc' class
+ * video encoder
+ */
+
+struct omap_hwmod_class omap2_venc_hwmod_class = {
+ .name = "venc",
+};
+
+
+/* Common DMA request line data */
+struct omap_hwmod_dma_info omap2_uart1_sdma_reqs[] = {
+ { .name = "rx", .dma_req = 50, },
+ { .name = "tx", .dma_req = 49, },
+ { .dma_req = -1 }
+};
+
+struct omap_hwmod_dma_info omap2_uart2_sdma_reqs[] = {
+ { .name = "rx", .dma_req = 52, },
+ { .name = "tx", .dma_req = 51, },
+ { .dma_req = -1 }
+};
+
+struct omap_hwmod_dma_info omap2_uart3_sdma_reqs[] = {
+ { .name = "rx", .dma_req = 54, },
+ { .name = "tx", .dma_req = 53, },
+ { .dma_req = -1 }
+};
+
+struct omap_hwmod_dma_info omap2_i2c1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 27 },
+ { .name = "rx", .dma_req = 28 },
+ { .dma_req = -1 }
+};
+
+struct omap_hwmod_dma_info omap2_i2c2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 29 },
+ { .name = "rx", .dma_req = 30 },
+ { .dma_req = -1 }
+};
+
+struct omap_hwmod_dma_info omap2_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 */
+ { .dma_req = -1 }
+};
+
+struct omap_hwmod_dma_info omap2_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 */
+ { .dma_req = -1 }
+};
+
+struct omap_hwmod_dma_info omap2_mcbsp1_sdma_reqs[] = {
+ { .name = "rx", .dma_req = 32 },
+ { .name = "tx", .dma_req = 31 },
+ { .dma_req = -1 }
+};
+
+struct omap_hwmod_dma_info omap2_mcbsp2_sdma_reqs[] = {
+ { .name = "rx", .dma_req = 34 },
+ { .name = "tx", .dma_req = 33 },
+ { .dma_req = -1 }
+};
+
+struct omap_hwmod_dma_info omap2_mcbsp3_sdma_reqs[] = {
+ { .name = "rx", .dma_req = 18 },
+ { .name = "tx", .dma_req = 17 },
+ { .dma_req = -1 }
+};
+
+/* Other IP block data */
+
+
+/*
+ * 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"
+};
+
+/* Common MPU IRQ line data */
+
+struct omap_hwmod_irq_info omap2_timer1_mpu_irqs[] = {
+ { .irq = 37 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_timer2_mpu_irqs[] = {
+ { .irq = 38 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_timer3_mpu_irqs[] = {
+ { .irq = 39 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_timer4_mpu_irqs[] = {
+ { .irq = 40 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_timer5_mpu_irqs[] = {
+ { .irq = 41 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_timer6_mpu_irqs[] = {
+ { .irq = 42 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_timer7_mpu_irqs[] = {
+ { .irq = 43 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_timer8_mpu_irqs[] = {
+ { .irq = 44 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_timer9_mpu_irqs[] = {
+ { .irq = 45 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_timer10_mpu_irqs[] = {
+ { .irq = 46 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_timer11_mpu_irqs[] = {
+ { .irq = 47 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_uart1_mpu_irqs[] = {
+ { .irq = 72 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_uart2_mpu_irqs[] = {
+ { .irq = 73 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_uart3_mpu_irqs[] = {
+ { .irq = 74 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_dispc_irqs[] = {
+ { .irq = 25 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_i2c1_mpu_irqs[] = {
+ { .irq = 56 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_i2c2_mpu_irqs[] = {
+ { .irq = 57 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_gpio1_irqs[] = {
+ { .irq = 29 + OMAP_INTC_START, }, /* INT_24XX_GPIO_BANK1 */
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_gpio2_irqs[] = {
+ { .irq = 30 + OMAP_INTC_START, }, /* INT_24XX_GPIO_BANK2 */
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_gpio3_irqs[] = {
+ { .irq = 31 + OMAP_INTC_START, }, /* INT_24XX_GPIO_BANK3 */
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_gpio4_irqs[] = {
+ { .irq = 32 + OMAP_INTC_START, }, /* INT_24XX_GPIO_BANK4 */
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_dma_system_irqs[] = {
+ { .name = "0", .irq = 12 + OMAP_INTC_START, }, /* INT_24XX_SDMA_IRQ0 */
+ { .name = "1", .irq = 13 + OMAP_INTC_START, }, /* INT_24XX_SDMA_IRQ1 */
+ { .name = "2", .irq = 14 + OMAP_INTC_START, }, /* INT_24XX_SDMA_IRQ2 */
+ { .name = "3", .irq = 15 + OMAP_INTC_START, }, /* INT_24XX_SDMA_IRQ3 */
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_mcspi1_mpu_irqs[] = {
+ { .irq = 65 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_irq_info omap2_mcspi2_mpu_irqs[] = {
+ { .irq = 66 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+struct omap_hwmod_class_sysconfig omap2_hdq1w_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x14,
+ .syss_offs = 0x18,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+ SYSS_HAS_RESET_STATUS),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+struct omap_hwmod_class omap2_hdq1w_class = {
+ .name = "hdq1w",
+ .sysc = &omap2_hdq1w_sysc,
+ .reset = &omap_hdq1w_reset,
+};
+
+struct omap_hwmod_irq_info omap2_hdq1w_mpu_irqs[] = {
+ { .irq = 58 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c
new file mode 100644
index 000000000..656861c29
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c
@@ -0,0 +1,272 @@
+/*
+ * omap_hwmod_2xxx_interconnect_data.c - common interconnect data for OMAP2xxx
+ *
+ * Copyright (C) 2009-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 handle crossbar/shared link difference for L3?
+ * XXX these should be marked initdata for multi-OMAP kernels
+ */
+#include <asm/sizes.h>
+
+#include "omap_hwmod.h"
+#include "l3_2xxx.h"
+#include "l4_2xxx.h"
+#include "serial.h"
+
+#include "omap_hwmod_common_data.h"
+
+/*
+ * Common interconnect data
+ */
+
+/* L3 -> L4_CORE interface */
+struct omap_hwmod_ocp_if omap2xxx_l3_main__l4_core = {
+ .master = &omap2xxx_l3_main_hwmod,
+ .slave = &omap2xxx_l4_core_hwmod,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* MPU -> L3 interface */
+struct omap_hwmod_ocp_if omap2xxx_mpu__l3_main = {
+ .master = &omap2xxx_mpu_hwmod,
+ .slave = &omap2xxx_l3_main_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+/* DSS -> l3 */
+struct omap_hwmod_ocp_if omap2xxx_dss__l3 = {
+ .master = &omap2xxx_dss_core_hwmod,
+ .slave = &omap2xxx_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,
+};
+
+/* L4_CORE -> L4_WKUP interface */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__l4_wkup = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_l4_wkup_hwmod,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> UART1 interface */
+struct omap_hwmod_ocp_if omap2_l4_core__uart1 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_uart1_hwmod,
+ .clk = "uart1_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> UART2 interface */
+struct omap_hwmod_ocp_if omap2_l4_core__uart2 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_uart2_hwmod,
+ .clk = "uart2_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> UART3 interface */
+struct omap_hwmod_ocp_if omap2_l4_core__uart3 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_uart3_hwmod,
+ .clk = "uart3_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 core -> mcspi1 interface */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__mcspi1 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_mcspi1_hwmod,
+ .clk = "mcspi1_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 core -> mcspi2 interface */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__mcspi2 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_mcspi2_hwmod,
+ .clk = "mcspi2_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> timer2 */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__timer2 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_timer2_hwmod,
+ .clk = "gpt2_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> timer3 */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__timer3 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_timer3_hwmod,
+ .clk = "gpt3_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> timer4 */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__timer4 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_timer4_hwmod,
+ .clk = "gpt4_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> timer5 */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__timer5 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_timer5_hwmod,
+ .clk = "gpt5_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> timer6 */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__timer6 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_timer6_hwmod,
+ .clk = "gpt6_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> timer7 */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__timer7 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_timer7_hwmod,
+ .clk = "gpt7_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> timer8 */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__timer8 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_timer8_hwmod,
+ .clk = "gpt8_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> timer9 */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__timer9 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_timer9_hwmod,
+ .clk = "gpt9_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> timer10 */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__timer10 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_timer10_hwmod,
+ .clk = "gpt10_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> timer11 */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__timer11 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_timer11_hwmod,
+ .clk = "gpt11_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> timer12 */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__timer12 = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_timer12_hwmod,
+ .clk = "gpt12_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> dss */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__dss = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_dss_core_hwmod,
+ .clk = "dss_ick",
+ .addr = omap2_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,
+};
+
+/* l4_core -> dss_dispc */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_dispc = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_dss_dispc_hwmod,
+ .clk = "dss_ick",
+ .addr = omap2_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,
+};
+
+/* l4_core -> dss_rfbi */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_rfbi = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_dss_rfbi_hwmod,
+ .clk = "dss_ick",
+ .addr = omap2_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,
+};
+
+/* l4_core -> dss_venc */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_venc = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_dss_venc_hwmod,
+ .clk = "dss_ick",
+ .addr = omap2_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,
+};
+
+/* l4_core -> rng */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__rng = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_rng_hwmod,
+ .clk = "rng_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 core -> sham interface */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__sham = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_sham_hwmod,
+ .clk = "sha_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 core -> aes interface */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__aes = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_aes_hwmod,
+ .clk = "aes_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
new file mode 100644
index 000000000..8821b9d6b
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -0,0 +1,882 @@
+/*
+ * omap_hwmod_2xxx_ipblock_data.c - common IP block data for OMAP2xxx
+ *
+ * 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/platform_data/gpio-omap.h>
+#include <linux/omap-dma.h>
+#include <plat/dmtimer.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+
+#include "omap_hwmod.h"
+#include "omap_hwmod_common_data.h"
+#include "cm-regbits-24xx.h"
+#include "prm-regbits-24xx.h"
+#include "wd_timer.h"
+
+struct omap_hwmod_dma_info omap2xxx_dss_sdma_chs[] = {
+ { .name = "dispc", .dma_req = 5 },
+ { .dma_req = -1, },
+};
+
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap2_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,
+};
+
+struct omap_hwmod_class omap2_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &omap2_dispc_sysc,
+};
+
+/* OMAP2xxx Timer Common */
+static struct omap_hwmod_class_sysconfig omap2xxx_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 | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .clockact = CLOCKACT_TEST_ICLK,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+struct omap_hwmod_class omap2xxx_timer_hwmod_class = {
+ .name = "timer",
+ .sysc = &omap2xxx_timer_sysc,
+};
+
+/*
+ * '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 omap2xxx_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,
+};
+
+struct omap_hwmod_class omap2xxx_wd_timer_hwmod_class = {
+ .name = "wd_timer",
+ .sysc = &omap2xxx_wd_timer_sysc,
+ .pre_shutdown = &omap2_wd_timer_disable,
+ .reset = &omap2_wd_timer_reset,
+};
+
+/*
+ * 'gpio' class
+ * general purpose io module
+ */
+static struct omap_hwmod_class_sysconfig omap2xxx_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,
+};
+
+struct omap_hwmod_class omap2xxx_gpio_hwmod_class = {
+ .name = "gpio",
+ .sysc = &omap2xxx_gpio_sysc,
+ .rev = 0,
+};
+
+/* system dma */
+static struct omap_hwmod_class_sysconfig omap2xxx_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,
+};
+
+struct omap_hwmod_class omap2xxx_dma_hwmod_class = {
+ .name = "dma",
+ .sysc = &omap2xxx_dma_sysc,
+};
+
+/*
+ * 'mailbox' class
+ * mailbox module allowing communication between the on-chip processors
+ * using a queued mailbox-interrupt mechanism.
+ */
+
+static struct omap_hwmod_class_sysconfig omap2xxx_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,
+};
+
+struct omap_hwmod_class omap2xxx_mailbox_hwmod_class = {
+ .name = "mailbox",
+ .sysc = &omap2xxx_mailbox_sysc,
+};
+
+/*
+ * 'mcspi' class
+ * multichannel serial port interface (mcspi) / master/slave synchronous serial
+ * bus
+ */
+
+static struct omap_hwmod_class_sysconfig omap2xxx_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,
+};
+
+struct omap_hwmod_class omap2xxx_mcspi_class = {
+ .name = "mcspi",
+ .sysc = &omap2xxx_mcspi_sysc,
+ .rev = OMAP2_MCSPI_REV,
+};
+
+/*
+ * 'gpmc' class
+ * general purpose memory controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap2xxx_gpmc_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 omap2xxx_gpmc_hwmod_class = {
+ .name = "gpmc",
+ .sysc = &omap2xxx_gpmc_sysc,
+};
+
+/*
+ * IP blocks
+ */
+
+/* L3 */
+struct omap_hwmod omap2xxx_l3_main_hwmod = {
+ .name = "l3_main",
+ .class = &l3_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* L4 CORE */
+struct omap_hwmod omap2xxx_l4_core_hwmod = {
+ .name = "l4_core",
+ .class = &l4_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* L4 WKUP */
+struct omap_hwmod omap2xxx_l4_wkup_hwmod = {
+ .name = "l4_wkup",
+ .class = &l4_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* MPU */
+struct omap_hwmod omap2xxx_mpu_hwmod = {
+ .name = "mpu",
+ .class = &mpu_hwmod_class,
+ .main_clk = "mpu_ck",
+};
+
+/* IVA2 */
+struct omap_hwmod omap2xxx_iva_hwmod = {
+ .name = "iva",
+ .class = &iva_hwmod_class,
+};
+
+/* always-on timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
+ .timer_capability = OMAP_TIMER_ALWON,
+};
+
+/* pwm timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_PWM,
+};
+
+/* timers with DSP interrupt dev attribute */
+static struct omap_timer_capability_dev_attr capability_dsp_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_DSP_IRQ,
+};
+
+/* timer1 */
+
+struct omap_hwmod omap2xxx_timer1_hwmod = {
+ .name = "timer1",
+ .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,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer2 */
+
+struct omap_hwmod omap2xxx_timer2_hwmod = {
+ .name = "timer2",
+ .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,
+ },
+ },
+ .class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer3 */
+
+struct omap_hwmod omap2xxx_timer3_hwmod = {
+ .name = "timer3",
+ .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,
+ },
+ },
+ .class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer4 */
+
+struct omap_hwmod omap2xxx_timer4_hwmod = {
+ .name = "timer4",
+ .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,
+ },
+ },
+ .class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer5 */
+
+struct omap_hwmod omap2xxx_timer5_hwmod = {
+ .name = "timer5",
+ .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,
+ },
+ },
+ .dev_attr = &capability_dsp_dev_attr,
+ .class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer6 */
+
+struct omap_hwmod omap2xxx_timer6_hwmod = {
+ .name = "timer6",
+ .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,
+ },
+ },
+ .dev_attr = &capability_dsp_dev_attr,
+ .class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer7 */
+
+struct omap_hwmod omap2xxx_timer7_hwmod = {
+ .name = "timer7",
+ .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,
+ },
+ },
+ .dev_attr = &capability_dsp_dev_attr,
+ .class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer8 */
+
+struct omap_hwmod omap2xxx_timer8_hwmod = {
+ .name = "timer8",
+ .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,
+ },
+ },
+ .dev_attr = &capability_dsp_dev_attr,
+ .class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer9 */
+
+struct omap_hwmod omap2xxx_timer9_hwmod = {
+ .name = "timer9",
+ .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,
+ },
+ },
+ .dev_attr = &capability_pwm_dev_attr,
+ .class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer10 */
+
+struct omap_hwmod omap2xxx_timer10_hwmod = {
+ .name = "timer10",
+ .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,
+ },
+ },
+ .dev_attr = &capability_pwm_dev_attr,
+ .class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer11 */
+
+struct omap_hwmod omap2xxx_timer11_hwmod = {
+ .name = "timer11",
+ .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,
+ },
+ },
+ .dev_attr = &capability_pwm_dev_attr,
+ .class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer12 */
+
+struct omap_hwmod omap2xxx_timer12_hwmod = {
+ .name = "timer12",
+ .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,
+ },
+ },
+ .dev_attr = &capability_pwm_dev_attr,
+ .class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* wd_timer2 */
+struct omap_hwmod omap2xxx_wd_timer2_hwmod = {
+ .name = "wd_timer2",
+ .class = &omap2xxx_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,
+ },
+ },
+};
+
+/* UART1 */
+
+struct omap_hwmod omap2xxx_uart1_hwmod = {
+ .name = "uart1",
+ .main_clk = "uart1_fck",
+ .flags = DEBUG_OMAP2UART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
+ .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,
+ },
+ },
+ .class = &omap2_uart_class,
+};
+
+/* UART2 */
+
+struct omap_hwmod omap2xxx_uart2_hwmod = {
+ .name = "uart2",
+ .main_clk = "uart2_fck",
+ .flags = DEBUG_OMAP2UART2_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
+ .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,
+ },
+ },
+ .class = &omap2_uart_class,
+};
+
+/* UART3 */
+
+struct omap_hwmod omap2xxx_uart3_hwmod = {
+ .name = "uart3",
+ .main_clk = "uart3_fck",
+ .flags = DEBUG_OMAP2UART3_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
+ .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,
+ },
+ },
+ .class = &omap2_uart_class,
+};
+
+/* dss */
+
+static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+ /*
+ * The DSS HW needs all DSS clocks enabled during reset. The dss_core
+ * driver does not use these clocks.
+ */
+ { .role = "tv_clk", .clk = "dss_54m_fck" },
+ { .role = "sys_clk", .clk = "dss2_fck" },
+};
+
+struct omap_hwmod omap2xxx_dss_core_hwmod = {
+ .name = "dss_core",
+ .class = &omap2_dss_hwmod_class,
+ .main_clk = "dss1_fck", /* instead of dss_fck */
+ .sdma_reqs = omap2xxx_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),
+ .flags = HWMOD_NO_IDLEST | HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+};
+
+struct omap_hwmod omap2xxx_dss_dispc_hwmod = {
+ .name = "dss_dispc",
+ .class = &omap2_dispc_hwmod_class,
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .flags = HWMOD_NO_IDLEST,
+ .dev_attr = &omap2_3_dss_dispc_dev_attr,
+};
+
+static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = {
+ { .role = "ick", .clk = "dss_ick" },
+};
+
+struct omap_hwmod omap2xxx_dss_rfbi_hwmod = {
+ .name = "dss_rfbi",
+ .class = &omap2_rfbi_hwmod_class,
+ .main_clk = "dss1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ },
+ },
+ .opt_clks = dss_rfbi_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+struct omap_hwmod omap2xxx_dss_venc_hwmod = {
+ .name = "dss_venc",
+ .class = &omap2_venc_hwmod_class,
+ .main_clk = "dss_54m_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ },
+ },
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* gpio dev_attr */
+struct omap_gpio_dev_attr omap2xxx_gpio_dev_attr = {
+ .bank_width = 32,
+ .dbck_flag = false,
+};
+
+/* gpio1 */
+struct omap_hwmod omap2xxx_gpio1_hwmod = {
+ .name = "gpio1",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .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,
+ },
+ },
+ .class = &omap2xxx_gpio_hwmod_class,
+ .dev_attr = &omap2xxx_gpio_dev_attr,
+};
+
+/* gpio2 */
+struct omap_hwmod omap2xxx_gpio2_hwmod = {
+ .name = "gpio2",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .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,
+ },
+ },
+ .class = &omap2xxx_gpio_hwmod_class,
+ .dev_attr = &omap2xxx_gpio_dev_attr,
+};
+
+/* gpio3 */
+struct omap_hwmod omap2xxx_gpio3_hwmod = {
+ .name = "gpio3",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .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,
+ },
+ },
+ .class = &omap2xxx_gpio_hwmod_class,
+ .dev_attr = &omap2xxx_gpio_dev_attr,
+};
+
+/* gpio4 */
+struct omap_hwmod omap2xxx_gpio4_hwmod = {
+ .name = "gpio4",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .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,
+ },
+ },
+ .class = &omap2xxx_gpio_hwmod_class,
+ .dev_attr = &omap2xxx_gpio_dev_attr,
+};
+
+/* mcspi1 */
+static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = {
+ .num_chipselect = 4,
+};
+
+struct omap_hwmod omap2xxx_mcspi1_hwmod = {
+ .name = "mcspi1",
+ .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,
+ },
+ },
+ .class = &omap2xxx_mcspi_class,
+ .dev_attr = &omap_mcspi1_dev_attr,
+};
+
+/* mcspi2 */
+static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = {
+ .num_chipselect = 2,
+};
+
+struct omap_hwmod omap2xxx_mcspi2_hwmod = {
+ .name = "mcspi2",
+ .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,
+ },
+ },
+ .class = &omap2xxx_mcspi_class,
+ .dev_attr = &omap_mcspi2_dev_attr,
+};
+
+static struct omap_hwmod_class omap2xxx_counter_hwmod_class = {
+ .name = "counter",
+};
+
+struct omap_hwmod omap2xxx_counter_32k_hwmod = {
+ .name = "counter_32k",
+ .main_clk = "func_32k_ck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = WKUP_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_ST_32KSYNC_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_32KSYNC_SHIFT,
+ },
+ },
+ .class = &omap2xxx_counter_hwmod_class,
+};
+
+/* gpmc */
+struct omap_hwmod omap2xxx_gpmc_hwmod = {
+ .name = "gpmc",
+ .class = &omap2xxx_gpmc_hwmod_class,
+ .main_clk = "gpmc_fck",
+ /*
+ * XXX HWMOD_INIT_NO_RESET should not be needed for this IP
+ * block. It is not being added due to any known bugs with
+ * resetting the GPMC IP block, but rather because any timings
+ * set by the bootloader are not being correctly programmed by
+ * the kernel from the board file or DT data.
+ * HWMOD_INIT_NO_RESET should be removed ASAP.
+ */
+ .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
+ HWMOD_NO_IDLEST),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 3,
+ .module_bit = OMAP24XX_EN_GPMC_MASK,
+ .module_offs = CORE_MOD,
+ },
+ },
+};
+
+/* RNG */
+
+static struct omap_hwmod_class_sysconfig omap2_rng_sysc = {
+ .rev_offs = 0x3c,
+ .sysc_offs = 0x40,
+ .syss_offs = 0x44,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+ SYSS_HAS_RESET_STATUS),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2_rng_hwmod_class = {
+ .name = "rng",
+ .sysc = &omap2_rng_sysc,
+};
+
+struct omap_hwmod omap2xxx_rng_hwmod = {
+ .name = "rng",
+ .main_clk = "l4_ck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 4,
+ .module_bit = OMAP24XX_EN_RNG_SHIFT,
+ .idlest_reg_id = 4,
+ .idlest_idle_bit = OMAP24XX_ST_RNG_SHIFT,
+ },
+ },
+ /*
+ * XXX The first read from the SYSSTATUS register of the RNG
+ * after the SYSCONFIG SOFTRESET bit is set triggers an
+ * imprecise external abort. It's unclear why this happens.
+ * Until this is analyzed, skip the IP block reset.
+ */
+ .flags = HWMOD_INIT_NO_RESET,
+ .class = &omap2_rng_hwmod_class,
+};
+
+/* SHAM */
+
+static struct omap_hwmod_class_sysconfig omap2_sham_sysc = {
+ .rev_offs = 0x5c,
+ .sysc_offs = 0x60,
+ .syss_offs = 0x64,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+ SYSS_HAS_RESET_STATUS),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2xxx_sham_class = {
+ .name = "sham",
+ .sysc = &omap2_sham_sysc,
+};
+
+struct omap_hwmod omap2xxx_sham_hwmod = {
+ .name = "sham",
+ .main_clk = "l4_ck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 4,
+ .module_bit = OMAP24XX_EN_SHA_SHIFT,
+ .idlest_reg_id = 4,
+ .idlest_idle_bit = OMAP24XX_ST_SHA_SHIFT,
+ },
+ },
+ .class = &omap2xxx_sham_class,
+};
+
+/* AES */
+
+static struct omap_hwmod_class_sysconfig omap2_aes_sysc = {
+ .rev_offs = 0x44,
+ .sysc_offs = 0x48,
+ .syss_offs = 0x4c,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+ SYSS_HAS_RESET_STATUS),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2xxx_aes_class = {
+ .name = "aes",
+ .sysc = &omap2_aes_sysc,
+};
+
+struct omap_hwmod omap2xxx_aes_hwmod = {
+ .name = "aes",
+ .main_clk = "l4_ck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 4,
+ .module_bit = OMAP24XX_EN_AES_SHIFT,
+ .idlest_reg_id = 4,
+ .idlest_idle_bit = OMAP24XX_ST_AES_SHIFT,
+ },
+ },
+ .class = &omap2xxx_aes_class,
+};
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h
new file mode 100644
index 000000000..130332c05
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h
@@ -0,0 +1,163 @@
+/*
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated
+ *
+ * Data common for AM335x and AM43x
+ *
+ * This program is free software; 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 __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_33XX_43XX_COMMON_DATA_H
+#define __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_33XX_43XX_COMMON_DATA_H
+
+extern struct omap_hwmod_ocp_if am33xx_mpu__l3_main;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__l3_s;
+extern struct omap_hwmod_ocp_if am33xx_l3_s__l4_ls;
+extern struct omap_hwmod_ocp_if am33xx_l3_s__l4_wkup;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__l3_instr;
+extern struct omap_hwmod_ocp_if am33xx_mpu__prcm;
+extern struct omap_hwmod_ocp_if am33xx_l3_s__l3_main;
+extern struct omap_hwmod_ocp_if am33xx_pruss__l3_main;
+extern struct omap_hwmod_ocp_if am33xx_gfx__l3_main;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__gfx;
+extern struct omap_hwmod_ocp_if am33xx_l4_wkup__rtc;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__dcan0;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__dcan1;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__gpio1;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__gpio2;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__gpio3;
+extern struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__elm;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0;
+extern struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0;
+extern struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0;
+extern struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1;
+extern struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1;
+extern struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1;
+extern struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2;
+extern struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2;
+extern struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2;
+extern struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2;
+extern struct omap_hwmod_ocp_if am33xx_l3_s__gpmc;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__i2c2;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__i2c3;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__mailbox;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__spinlock;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp0;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp1;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__mmc0;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__mmc1;
+extern struct omap_hwmod_ocp_if am33xx_l3_s__mmc2;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi0;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi1;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer2;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer3;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer4;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer5;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer6;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer7;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__tpcc;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc0;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc1;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc2;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart2;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart3;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart4;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart5;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart6;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__ocmc;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__sha0;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__aes0;
+
+extern struct omap_hwmod am33xx_l3_main_hwmod;
+extern struct omap_hwmod am33xx_l3_s_hwmod;
+extern struct omap_hwmod am33xx_l3_instr_hwmod;
+extern struct omap_hwmod am33xx_l4_ls_hwmod;
+extern struct omap_hwmod am33xx_l4_wkup_hwmod;
+extern struct omap_hwmod am33xx_mpu_hwmod;
+extern struct omap_hwmod am33xx_pruss_hwmod;
+extern struct omap_hwmod am33xx_gfx_hwmod;
+extern struct omap_hwmod am33xx_prcm_hwmod;
+extern struct omap_hwmod am33xx_aes0_hwmod;
+extern struct omap_hwmod am33xx_sha0_hwmod;
+extern struct omap_hwmod am33xx_ocmcram_hwmod;
+extern struct omap_hwmod am33xx_smartreflex0_hwmod;
+extern struct omap_hwmod am33xx_smartreflex1_hwmod;
+extern struct omap_hwmod am33xx_cpgmac0_hwmod;
+extern struct omap_hwmod am33xx_mdio_hwmod;
+extern struct omap_hwmod am33xx_dcan0_hwmod;
+extern struct omap_hwmod am33xx_dcan1_hwmod;
+extern struct omap_hwmod am33xx_elm_hwmod;
+extern struct omap_hwmod am33xx_epwmss0_hwmod;
+extern struct omap_hwmod am33xx_ecap0_hwmod;
+extern struct omap_hwmod am33xx_eqep0_hwmod;
+extern struct omap_hwmod am33xx_ehrpwm0_hwmod;
+extern struct omap_hwmod am33xx_epwmss1_hwmod;
+extern struct omap_hwmod am33xx_ecap1_hwmod;
+extern struct omap_hwmod am33xx_eqep1_hwmod;
+extern struct omap_hwmod am33xx_ehrpwm1_hwmod;
+extern struct omap_hwmod am33xx_epwmss2_hwmod;
+extern struct omap_hwmod am33xx_ecap2_hwmod;
+extern struct omap_hwmod am33xx_eqep2_hwmod;
+extern struct omap_hwmod am33xx_ehrpwm2_hwmod;
+extern struct omap_hwmod am33xx_gpio1_hwmod;
+extern struct omap_hwmod am33xx_gpio2_hwmod;
+extern struct omap_hwmod am33xx_gpio3_hwmod;
+extern struct omap_hwmod am33xx_gpmc_hwmod;
+extern struct omap_hwmod am33xx_i2c1_hwmod;
+extern struct omap_hwmod am33xx_i2c2_hwmod;
+extern struct omap_hwmod am33xx_i2c3_hwmod;
+extern struct omap_hwmod am33xx_mailbox_hwmod;
+extern struct omap_hwmod am33xx_mcasp0_hwmod;
+extern struct omap_hwmod am33xx_mcasp1_hwmod;
+extern struct omap_hwmod am33xx_mmc0_hwmod;
+extern struct omap_hwmod am33xx_mmc1_hwmod;
+extern struct omap_hwmod am33xx_mmc2_hwmod;
+extern struct omap_hwmod am33xx_rtc_hwmod;
+extern struct omap_hwmod am33xx_spi0_hwmod;
+extern struct omap_hwmod am33xx_spi1_hwmod;
+extern struct omap_hwmod am33xx_spinlock_hwmod;
+extern struct omap_hwmod am33xx_timer1_hwmod;
+extern struct omap_hwmod am33xx_timer2_hwmod;
+extern struct omap_hwmod am33xx_timer3_hwmod;
+extern struct omap_hwmod am33xx_timer4_hwmod;
+extern struct omap_hwmod am33xx_timer5_hwmod;
+extern struct omap_hwmod am33xx_timer6_hwmod;
+extern struct omap_hwmod am33xx_timer7_hwmod;
+extern struct omap_hwmod am33xx_tpcc_hwmod;
+extern struct omap_hwmod am33xx_tptc0_hwmod;
+extern struct omap_hwmod am33xx_tptc1_hwmod;
+extern struct omap_hwmod am33xx_tptc2_hwmod;
+extern struct omap_hwmod am33xx_uart1_hwmod;
+extern struct omap_hwmod am33xx_uart2_hwmod;
+extern struct omap_hwmod am33xx_uart3_hwmod;
+extern struct omap_hwmod am33xx_uart4_hwmod;
+extern struct omap_hwmod am33xx_uart5_hwmod;
+extern struct omap_hwmod am33xx_uart6_hwmod;
+extern struct omap_hwmod am33xx_wd_timer1_hwmod;
+
+extern struct omap_hwmod_class am33xx_l4_hwmod_class;
+extern struct omap_hwmod_class am33xx_wkup_m3_hwmod_class;
+extern struct omap_hwmod_class am33xx_control_hwmod_class;
+extern struct omap_hwmod_class am33xx_gpio_hwmod_class;
+extern struct omap_hwmod_class am33xx_timer_hwmod_class;
+extern struct omap_hwmod_class am33xx_epwmss_hwmod_class;
+extern struct omap_hwmod_class am33xx_ehrpwm_hwmod_class;
+extern struct omap_hwmod_class am33xx_spi_hwmod_class;
+
+extern struct omap_gpio_dev_attr gpio_dev_attr;
+extern struct omap2_mcspi_dev_attr mcspi_attrib;
+
+void omap_hwmod_am33xx_reg(void);
+void omap_hwmod_am43xx_reg(void);
+
+#endif
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c
new file mode 100644
index 000000000..8f5989d48
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c
@@ -0,0 +1,633 @@
+/*
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated
+ *
+ * Interconnects common for AM335x and AM43x
+ *
+ * This program is free software; 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/sizes.h>
+#include "omap_hwmod.h"
+#include "omap_hwmod_33xx_43xx_common_data.h"
+
+/* mpu -> l3 main */
+struct omap_hwmod_ocp_if am33xx_mpu__l3_main = {
+ .master = &am33xx_mpu_hwmod,
+ .slave = &am33xx_l3_main_hwmod,
+ .clk = "dpll_mpu_m2_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* l3 main -> l3 s */
+struct omap_hwmod_ocp_if am33xx_l3_main__l3_s = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am33xx_l3_s_hwmod,
+ .clk = "l3s_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3 s -> l4 per/ls */
+struct omap_hwmod_ocp_if am33xx_l3_s__l4_ls = {
+ .master = &am33xx_l3_s_hwmod,
+ .slave = &am33xx_l4_ls_hwmod,
+ .clk = "l3s_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3 s -> l4 wkup */
+struct omap_hwmod_ocp_if am33xx_l3_s__l4_wkup = {
+ .master = &am33xx_l3_s_hwmod,
+ .slave = &am33xx_l4_wkup_hwmod,
+ .clk = "l3s_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3 main -> l3 instr */
+struct omap_hwmod_ocp_if am33xx_l3_main__l3_instr = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am33xx_l3_instr_hwmod,
+ .clk = "l3s_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> prcm */
+struct omap_hwmod_ocp_if am33xx_mpu__prcm = {
+ .master = &am33xx_mpu_hwmod,
+ .slave = &am33xx_prcm_hwmod,
+ .clk = "dpll_mpu_m2_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3 s -> l3 main*/
+struct omap_hwmod_ocp_if am33xx_l3_s__l3_main = {
+ .master = &am33xx_l3_s_hwmod,
+ .slave = &am33xx_l3_main_hwmod,
+ .clk = "l3s_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* pru-icss -> l3 main */
+struct omap_hwmod_ocp_if am33xx_pruss__l3_main = {
+ .master = &am33xx_pruss_hwmod,
+ .slave = &am33xx_l3_main_hwmod,
+ .clk = "l3_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gfx -> l3 main */
+struct omap_hwmod_ocp_if am33xx_gfx__l3_main = {
+ .master = &am33xx_gfx_hwmod,
+ .slave = &am33xx_l3_main_hwmod,
+ .clk = "dpll_core_m4_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3 main -> gfx */
+struct omap_hwmod_ocp_if am33xx_l3_main__gfx = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am33xx_gfx_hwmod,
+ .clk = "dpll_core_m4_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 wkup -> rtc */
+struct omap_hwmod_ocp_if am33xx_l4_wkup__rtc = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_rtc_hwmod,
+ .clk = "clkdiv32k_ick",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 per/ls -> DCAN0 */
+struct omap_hwmod_ocp_if am33xx_l4_per__dcan0 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_dcan0_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 per/ls -> DCAN1 */
+struct omap_hwmod_ocp_if am33xx_l4_per__dcan1 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_dcan1_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 per/ls -> GPIO2 */
+struct omap_hwmod_ocp_if am33xx_l4_per__gpio1 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_gpio1_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 per/ls -> gpio3 */
+struct omap_hwmod_ocp_if am33xx_l4_per__gpio2 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_gpio2_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 per/ls -> gpio4 */
+struct omap_hwmod_ocp_if am33xx_l4_per__gpio3 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_gpio3_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio = {
+ .master = &am33xx_cpgmac0_hwmod,
+ .slave = &am33xx_mdio_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_elm_addr_space[] = {
+ {
+ .pa_start = 0x48080000,
+ .pa_end = 0x48080000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_ls__elm = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_elm_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_elm_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_epwmss0_addr_space[] = {
+ {
+ .pa_start = 0x48300000,
+ .pa_end = 0x48300000 + SZ_16 - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_epwmss0_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_epwmss0_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0 = {
+ .master = &am33xx_epwmss0_hwmod,
+ .slave = &am33xx_ecap0_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0 = {
+ .master = &am33xx_epwmss0_hwmod,
+ .slave = &am33xx_eqep0_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0 = {
+ .master = &am33xx_epwmss0_hwmod,
+ .slave = &am33xx_ehrpwm0_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+
+static struct omap_hwmod_addr_space am33xx_epwmss1_addr_space[] = {
+ {
+ .pa_start = 0x48302000,
+ .pa_end = 0x48302000 + SZ_16 - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_epwmss1_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_epwmss1_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1 = {
+ .master = &am33xx_epwmss1_hwmod,
+ .slave = &am33xx_ecap1_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1 = {
+ .master = &am33xx_epwmss1_hwmod,
+ .slave = &am33xx_eqep1_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1 = {
+ .master = &am33xx_epwmss1_hwmod,
+ .slave = &am33xx_ehrpwm1_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_epwmss2_addr_space[] = {
+ {
+ .pa_start = 0x48304000,
+ .pa_end = 0x48304000 + SZ_16 - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_epwmss2_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_epwmss2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2 = {
+ .master = &am33xx_epwmss2_hwmod,
+ .slave = &am33xx_ecap2_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2 = {
+ .master = &am33xx_epwmss2_hwmod,
+ .slave = &am33xx_eqep2_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2 = {
+ .master = &am33xx_epwmss2_hwmod,
+ .slave = &am33xx_ehrpwm2_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l3s cfg -> gpmc */
+static struct omap_hwmod_addr_space am33xx_gpmc_addr_space[] = {
+ {
+ .pa_start = 0x50000000,
+ .pa_end = 0x50000000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l3_s__gpmc = {
+ .master = &am33xx_l3_s_hwmod,
+ .slave = &am33xx_gpmc_hwmod,
+ .clk = "l3s_gclk",
+ .addr = am33xx_gpmc_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+/* i2c2 */
+struct omap_hwmod_ocp_if am33xx_l4_per__i2c2 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_i2c2_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_per__i2c3 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_i2c3_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 ls -> mailbox */
+struct omap_hwmod_ocp_if am33xx_l4_per__mailbox = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_mailbox_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 ls -> spinlock */
+struct omap_hwmod_ocp_if am33xx_l4_ls__spinlock = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_spinlock_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 ls -> mcasp0 */
+static struct omap_hwmod_addr_space am33xx_mcasp0_addr_space[] = {
+ {
+ .pa_start = 0x48038000,
+ .pa_end = 0x48038000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp0 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_mcasp0_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_mcasp0_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+/* l4 ls -> mcasp1 */
+static struct omap_hwmod_addr_space am33xx_mcasp1_addr_space[] = {
+ {
+ .pa_start = 0x4803C000,
+ .pa_end = 0x4803C000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp1 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_mcasp1_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_mcasp1_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+/* l4 ls -> mmc0 */
+static struct omap_hwmod_addr_space am33xx_mmc0_addr_space[] = {
+ {
+ .pa_start = 0x48060100,
+ .pa_end = 0x48060100 + SZ_4K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_ls__mmc0 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_mmc0_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_mmc0_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+/* l4 ls -> mmc1 */
+static struct omap_hwmod_addr_space am33xx_mmc1_addr_space[] = {
+ {
+ .pa_start = 0x481d8100,
+ .pa_end = 0x481d8100 + SZ_4K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_ls__mmc1 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_mmc1_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_mmc1_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+/* l3 s -> mmc2 */
+static struct omap_hwmod_addr_space am33xx_mmc2_addr_space[] = {
+ {
+ .pa_start = 0x47810100,
+ .pa_end = 0x47810100 + SZ_64K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l3_s__mmc2 = {
+ .master = &am33xx_l3_s_hwmod,
+ .slave = &am33xx_mmc2_hwmod,
+ .clk = "l3s_gclk",
+ .addr = am33xx_mmc2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+/* l4 ls -> mcspi0 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi0 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_spi0_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 ls -> mcspi1 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi1 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_spi1_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 per -> timer2 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__timer2 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_timer2_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 per -> timer3 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__timer3 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_timer3_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 per -> timer4 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__timer4 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_timer4_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 per -> timer5 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__timer5 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_timer5_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 per -> timer6 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__timer6 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_timer6_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 per -> timer7 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__timer7 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_timer7_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l3 main -> tpcc */
+struct omap_hwmod_ocp_if am33xx_l3_main__tpcc = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am33xx_tpcc_hwmod,
+ .clk = "l3_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l3 main -> tpcc0 */
+static struct omap_hwmod_addr_space am33xx_tptc0_addr_space[] = {
+ {
+ .pa_start = 0x49800000,
+ .pa_end = 0x49800000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l3_main__tptc0 = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am33xx_tptc0_hwmod,
+ .clk = "l3_gclk",
+ .addr = am33xx_tptc0_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+/* l3 main -> tpcc1 */
+static struct omap_hwmod_addr_space am33xx_tptc1_addr_space[] = {
+ {
+ .pa_start = 0x49900000,
+ .pa_end = 0x49900000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l3_main__tptc1 = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am33xx_tptc1_hwmod,
+ .clk = "l3_gclk",
+ .addr = am33xx_tptc1_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+/* l3 main -> tpcc2 */
+static struct omap_hwmod_addr_space am33xx_tptc2_addr_space[] = {
+ {
+ .pa_start = 0x49a00000,
+ .pa_end = 0x49a00000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l3_main__tptc2 = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am33xx_tptc2_hwmod,
+ .clk = "l3_gclk",
+ .addr = am33xx_tptc2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+/* l4 ls -> uart2 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__uart2 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_uart2_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 ls -> uart3 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__uart3 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_uart3_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 ls -> uart4 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__uart4 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_uart4_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 ls -> uart5 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__uart5 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_uart5_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 ls -> uart6 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__uart6 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_uart6_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l3 main -> ocmc */
+struct omap_hwmod_ocp_if am33xx_l3_main__ocmc = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am33xx_ocmcram_hwmod,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3 main -> sha0 HIB2 */
+static struct omap_hwmod_addr_space am33xx_sha0_addrs[] = {
+ {
+ .pa_start = 0x53100000,
+ .pa_end = 0x53100000 + SZ_512 - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l3_main__sha0 = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am33xx_sha0_hwmod,
+ .clk = "sha0_fck",
+ .addr = am33xx_sha0_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3 main -> AES0 HIB2 */
+static struct omap_hwmod_addr_space am33xx_aes0_addrs[] = {
+ {
+ .pa_start = 0x53500000,
+ .pa_end = 0x53500000 + SZ_1M - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l3_main__aes0 = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am33xx_aes0_hwmod,
+ .clk = "aes0_fck",
+ .addr = am33xx_aes0_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
new file mode 100644
index 000000000..cabc5695b
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
@@ -0,0 +1,1470 @@
+/*
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated
+ *
+ * Hwmod common for AM335x and AM43x
+ *
+ * This program is free software; 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/platform_data/gpio-omap.h>
+#include <linux/platform_data/hsmmc-omap.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+#include "omap_hwmod.h"
+#include "i2c.h"
+#include "wd_timer.h"
+#include "cm33xx.h"
+#include "prm33xx.h"
+#include "omap_hwmod_33xx_43xx_common_data.h"
+#include "prcm43xx.h"
+#include "common.h"
+
+#define CLKCTRL(oh, clkctrl) ((oh).prcm.omap4.clkctrl_offs = (clkctrl))
+#define RSTCTRL(oh, rstctrl) ((oh).prcm.omap4.rstctrl_offs = (rstctrl))
+#define RSTST(oh, rstst) ((oh).prcm.omap4.rstst_offs = (rstst))
+
+/*
+ * 'l3' class
+ * instance(s): l3_main, l3_s, l3_instr
+ */
+static struct omap_hwmod_class am33xx_l3_hwmod_class = {
+ .name = "l3",
+};
+
+struct omap_hwmod am33xx_l3_main_hwmod = {
+ .name = "l3_main",
+ .class = &am33xx_l3_hwmod_class,
+ .clkdm_name = "l3_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "l3_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* l3_s */
+struct omap_hwmod am33xx_l3_s_hwmod = {
+ .name = "l3_s",
+ .class = &am33xx_l3_hwmod_class,
+ .clkdm_name = "l3s_clkdm",
+};
+
+/* l3_instr */
+struct omap_hwmod am33xx_l3_instr_hwmod = {
+ .name = "l3_instr",
+ .class = &am33xx_l3_hwmod_class,
+ .clkdm_name = "l3_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "l3_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'l4' class
+ * instance(s): l4_ls, l4_hs, l4_wkup, l4_fw
+ */
+struct omap_hwmod_class am33xx_l4_hwmod_class = {
+ .name = "l4",
+};
+
+/* l4_ls */
+struct omap_hwmod am33xx_l4_ls_hwmod = {
+ .name = "l4_ls",
+ .class = &am33xx_l4_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* l4_wkup */
+struct omap_hwmod am33xx_l4_wkup_hwmod = {
+ .name = "l4_wkup",
+ .class = &am33xx_l4_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'mpu' class
+ */
+static struct omap_hwmod_class am33xx_mpu_hwmod_class = {
+ .name = "mpu",
+};
+
+struct omap_hwmod am33xx_mpu_hwmod = {
+ .name = "mpu",
+ .class = &am33xx_mpu_hwmod_class,
+ .clkdm_name = "mpu_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "dpll_mpu_m2_ck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'wakeup m3' class
+ * Wakeup controller sub-system under wakeup domain
+ */
+struct omap_hwmod_class am33xx_wkup_m3_hwmod_class = {
+ .name = "wkup_m3",
+};
+
+/*
+ * 'pru-icss' class
+ * Programmable Real-Time Unit and Industrial Communication Subsystem
+ */
+static struct omap_hwmod_class am33xx_pruss_hwmod_class = {
+ .name = "pruss",
+};
+
+static struct omap_hwmod_rst_info am33xx_pruss_resets[] = {
+ { .name = "pruss", .rst_shift = 1 },
+};
+
+/* pru-icss */
+/* Pseudo hwmod for reset control purpose only */
+struct omap_hwmod am33xx_pruss_hwmod = {
+ .name = "pruss",
+ .class = &am33xx_pruss_hwmod_class,
+ .clkdm_name = "pruss_ocp_clkdm",
+ .main_clk = "pruss_ocp_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .rst_lines = am33xx_pruss_resets,
+ .rst_lines_cnt = ARRAY_SIZE(am33xx_pruss_resets),
+};
+
+/* gfx */
+/* Pseudo hwmod for reset control purpose only */
+static struct omap_hwmod_class am33xx_gfx_hwmod_class = {
+ .name = "gfx",
+};
+
+static struct omap_hwmod_rst_info am33xx_gfx_resets[] = {
+ { .name = "gfx", .rst_shift = 0, .st_shift = 0},
+};
+
+struct omap_hwmod am33xx_gfx_hwmod = {
+ .name = "gfx",
+ .class = &am33xx_gfx_hwmod_class,
+ .clkdm_name = "gfx_l3_clkdm",
+ .main_clk = "gfx_fck_div_ck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .rst_lines = am33xx_gfx_resets,
+ .rst_lines_cnt = ARRAY_SIZE(am33xx_gfx_resets),
+};
+
+/*
+ * 'prcm' class
+ * power and reset manager (whole prcm infrastructure)
+ */
+static struct omap_hwmod_class am33xx_prcm_hwmod_class = {
+ .name = "prcm",
+};
+
+/* prcm */
+struct omap_hwmod am33xx_prcm_hwmod = {
+ .name = "prcm",
+ .class = &am33xx_prcm_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+};
+
+/*
+ * 'aes0' class
+ */
+static struct omap_hwmod_class_sysconfig am33xx_aes0_sysc = {
+ .rev_offs = 0x80,
+ .sysc_offs = 0x84,
+ .syss_offs = 0x88,
+ .sysc_flags = SYSS_HAS_RESET_STATUS,
+};
+
+static struct omap_hwmod_class am33xx_aes0_hwmod_class = {
+ .name = "aes0",
+ .sysc = &am33xx_aes0_sysc,
+};
+
+struct omap_hwmod am33xx_aes0_hwmod = {
+ .name = "aes",
+ .class = &am33xx_aes0_hwmod_class,
+ .clkdm_name = "l3_clkdm",
+ .main_clk = "aes0_fck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* sha0 HIB2 (the 'P' (public) device) */
+static struct omap_hwmod_class_sysconfig am33xx_sha0_sysc = {
+ .rev_offs = 0x100,
+ .sysc_offs = 0x110,
+ .syss_offs = 0x114,
+ .sysc_flags = SYSS_HAS_RESET_STATUS,
+};
+
+static struct omap_hwmod_class am33xx_sha0_hwmod_class = {
+ .name = "sha0",
+ .sysc = &am33xx_sha0_sysc,
+};
+
+struct omap_hwmod am33xx_sha0_hwmod = {
+ .name = "sham",
+ .class = &am33xx_sha0_hwmod_class,
+ .clkdm_name = "l3_clkdm",
+ .main_clk = "l3_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* ocmcram */
+static struct omap_hwmod_class am33xx_ocmcram_hwmod_class = {
+ .name = "ocmcram",
+};
+
+struct omap_hwmod am33xx_ocmcram_hwmod = {
+ .name = "ocmcram",
+ .class = &am33xx_ocmcram_hwmod_class,
+ .clkdm_name = "l3_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "l3_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* 'smartreflex' class */
+static struct omap_hwmod_class am33xx_smartreflex_hwmod_class = {
+ .name = "smartreflex",
+};
+
+/* smartreflex0 */
+struct omap_hwmod am33xx_smartreflex0_hwmod = {
+ .name = "smartreflex0",
+ .class = &am33xx_smartreflex_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .main_clk = "smartreflex0_fck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* smartreflex1 */
+struct omap_hwmod am33xx_smartreflex1_hwmod = {
+ .name = "smartreflex1",
+ .class = &am33xx_smartreflex_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .main_clk = "smartreflex1_fck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'control' module class
+ */
+struct omap_hwmod_class am33xx_control_hwmod_class = {
+ .name = "control",
+};
+
+/*
+ * 'cpgmac' class
+ * cpsw/cpgmac sub system
+ */
+static struct omap_hwmod_class_sysconfig am33xx_cpgmac_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x8,
+ .syss_offs = 0x4,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | MSTANDBY_FORCE |
+ MSTANDBY_NO),
+ .sysc_fields = &omap_hwmod_sysc_type3,
+};
+
+static struct omap_hwmod_class am33xx_cpgmac0_hwmod_class = {
+ .name = "cpgmac0",
+ .sysc = &am33xx_cpgmac_sysc,
+};
+
+struct omap_hwmod am33xx_cpgmac0_hwmod = {
+ .name = "cpgmac0",
+ .class = &am33xx_cpgmac0_hwmod_class,
+ .clkdm_name = "cpsw_125mhz_clkdm",
+ .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
+ .main_clk = "cpsw_125mhz_gclk",
+ .mpu_rt_idx = 1,
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * mdio class
+ */
+static struct omap_hwmod_class am33xx_mdio_hwmod_class = {
+ .name = "davinci_mdio",
+};
+
+struct omap_hwmod am33xx_mdio_hwmod = {
+ .name = "davinci_mdio",
+ .class = &am33xx_mdio_hwmod_class,
+ .clkdm_name = "cpsw_125mhz_clkdm",
+ .main_clk = "cpsw_125mhz_gclk",
+};
+
+/*
+ * dcan class
+ */
+static struct omap_hwmod_class am33xx_dcan_hwmod_class = {
+ .name = "d_can",
+};
+
+/* dcan0 */
+struct omap_hwmod am33xx_dcan0_hwmod = {
+ .name = "d_can0",
+ .class = &am33xx_dcan_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "dcan0_fck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* dcan1 */
+struct omap_hwmod am33xx_dcan1_hwmod = {
+ .name = "d_can1",
+ .class = &am33xx_dcan_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "dcan1_fck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* elm */
+static struct omap_hwmod_class_sysconfig am33xx_elm_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | 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 am33xx_elm_hwmod_class = {
+ .name = "elm",
+ .sysc = &am33xx_elm_sysc,
+};
+
+struct omap_hwmod am33xx_elm_hwmod = {
+ .name = "elm",
+ .class = &am33xx_elm_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* pwmss */
+static struct omap_hwmod_class_sysconfig am33xx_epwmss_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x4,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+ MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+struct omap_hwmod_class am33xx_epwmss_hwmod_class = {
+ .name = "epwmss",
+ .sysc = &am33xx_epwmss_sysc,
+};
+
+static struct omap_hwmod_class am33xx_ecap_hwmod_class = {
+ .name = "ecap",
+};
+
+static struct omap_hwmod_class am33xx_eqep_hwmod_class = {
+ .name = "eqep",
+};
+
+struct omap_hwmod_class am33xx_ehrpwm_hwmod_class = {
+ .name = "ehrpwm",
+};
+
+/* epwmss0 */
+struct omap_hwmod am33xx_epwmss0_hwmod = {
+ .name = "epwmss0",
+ .class = &am33xx_epwmss_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* ecap0 */
+struct omap_hwmod am33xx_ecap0_hwmod = {
+ .name = "ecap0",
+ .class = &am33xx_ecap_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+};
+
+/* eqep0 */
+struct omap_hwmod am33xx_eqep0_hwmod = {
+ .name = "eqep0",
+ .class = &am33xx_eqep_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+};
+
+/* ehrpwm0 */
+struct omap_hwmod am33xx_ehrpwm0_hwmod = {
+ .name = "ehrpwm0",
+ .class = &am33xx_ehrpwm_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+};
+
+/* epwmss1 */
+struct omap_hwmod am33xx_epwmss1_hwmod = {
+ .name = "epwmss1",
+ .class = &am33xx_epwmss_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* ecap1 */
+struct omap_hwmod am33xx_ecap1_hwmod = {
+ .name = "ecap1",
+ .class = &am33xx_ecap_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+};
+
+/* eqep1 */
+struct omap_hwmod am33xx_eqep1_hwmod = {
+ .name = "eqep1",
+ .class = &am33xx_eqep_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+};
+
+/* ehrpwm1 */
+struct omap_hwmod am33xx_ehrpwm1_hwmod = {
+ .name = "ehrpwm1",
+ .class = &am33xx_ehrpwm_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+};
+
+/* epwmss2 */
+struct omap_hwmod am33xx_epwmss2_hwmod = {
+ .name = "epwmss2",
+ .class = &am33xx_epwmss_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* ecap2 */
+struct omap_hwmod am33xx_ecap2_hwmod = {
+ .name = "ecap2",
+ .class = &am33xx_ecap_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+};
+
+/* eqep2 */
+struct omap_hwmod am33xx_eqep2_hwmod = {
+ .name = "eqep2",
+ .class = &am33xx_eqep_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+};
+
+/* ehrpwm2 */
+struct omap_hwmod am33xx_ehrpwm2_hwmod = {
+ .name = "ehrpwm2",
+ .class = &am33xx_ehrpwm_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+};
+
+/*
+ * 'gpio' class: for gpio 0,1,2,3
+ */
+static struct omap_hwmod_class_sysconfig am33xx_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,
+};
+
+struct omap_hwmod_class am33xx_gpio_hwmod_class = {
+ .name = "gpio",
+ .sysc = &am33xx_gpio_sysc,
+ .rev = 2,
+};
+
+struct omap_gpio_dev_attr gpio_dev_attr = {
+ .bank_width = 32,
+ .dbck_flag = true,
+};
+
+/* gpio1 */
+static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio1_dbclk" },
+};
+
+struct omap_hwmod am33xx_gpio1_hwmod = {
+ .name = "gpio2",
+ .class = &am33xx_gpio_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = gpio1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio2 */
+static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio2_dbclk" },
+};
+
+struct omap_hwmod am33xx_gpio2_hwmod = {
+ .name = "gpio3",
+ .class = &am33xx_gpio_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = gpio2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio3 */
+static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio3_dbclk" },
+};
+
+struct omap_hwmod am33xx_gpio3_hwmod = {
+ .name = "gpio4",
+ .class = &am33xx_gpio_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = gpio3_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpmc */
+static struct omap_hwmod_class_sysconfig gpmc_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .syss_offs = 0x14,
+ .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 am33xx_gpmc_hwmod_class = {
+ .name = "gpmc",
+ .sysc = &gpmc_sysc,
+};
+
+struct omap_hwmod am33xx_gpmc_hwmod = {
+ .name = "gpmc",
+ .class = &am33xx_gpmc_hwmod_class,
+ .clkdm_name = "l3s_clkdm",
+ .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
+ .main_clk = "l3s_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* 'i2c' class */
+static struct omap_hwmod_class_sysconfig am33xx_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 i2c_class = {
+ .name = "i2c",
+ .sysc = &am33xx_i2c_sysc,
+ .rev = OMAP_I2C_IP_VERSION_2,
+ .reset = &omap_i2c_reset,
+};
+
+static struct omap_i2c_dev_attr i2c_dev_attr = {
+ .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE,
+};
+
+/* i2c1 */
+struct omap_hwmod am33xx_i2c1_hwmod = {
+ .name = "i2c1",
+ .class = &i2c_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "dpll_per_m2_div4_wkupdm_ck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/* i2c1 */
+struct omap_hwmod am33xx_i2c2_hwmod = {
+ .name = "i2c2",
+ .class = &i2c_class,
+ .clkdm_name = "l4ls_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "dpll_per_m2_div4_ck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/* i2c3 */
+struct omap_hwmod am33xx_i2c3_hwmod = {
+ .name = "i2c3",
+ .class = &i2c_class,
+ .clkdm_name = "l4ls_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "dpll_per_m2_div4_ck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/*
+ * 'mailbox' class
+ * mailbox module allowing communication between the on-chip processors using a
+ * queued mailbox-interrupt mechanism.
+ */
+static struct omap_hwmod_class_sysconfig am33xx_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 am33xx_mailbox_hwmod_class = {
+ .name = "mailbox",
+ .sysc = &am33xx_mailbox_sysc,
+};
+
+struct omap_hwmod am33xx_mailbox_hwmod = {
+ .name = "mailbox",
+ .class = &am33xx_mailbox_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'mcasp' class
+ */
+static struct omap_hwmod_class_sysconfig am33xx_mcasp_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x4,
+ .sysc_flags = SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type3,
+};
+
+static struct omap_hwmod_class am33xx_mcasp_hwmod_class = {
+ .name = "mcasp",
+ .sysc = &am33xx_mcasp_sysc,
+};
+
+/* mcasp0 */
+struct omap_hwmod am33xx_mcasp0_hwmod = {
+ .name = "mcasp0",
+ .class = &am33xx_mcasp_hwmod_class,
+ .clkdm_name = "l3s_clkdm",
+ .main_clk = "mcasp0_fck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* mcasp1 */
+struct omap_hwmod am33xx_mcasp1_hwmod = {
+ .name = "mcasp1",
+ .class = &am33xx_mcasp_hwmod_class,
+ .clkdm_name = "l3s_clkdm",
+ .main_clk = "mcasp1_fck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* 'mmc' class */
+static struct omap_hwmod_class_sysconfig am33xx_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 am33xx_mmc_hwmod_class = {
+ .name = "mmc",
+ .sysc = &am33xx_mmc_sysc,
+};
+
+/* mmc0 */
+static struct omap_hsmmc_dev_attr am33xx_mmc0_dev_attr = {
+ .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
+};
+
+struct omap_hwmod am33xx_mmc0_hwmod = {
+ .name = "mmc1",
+ .class = &am33xx_mmc_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "mmc_clk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &am33xx_mmc0_dev_attr,
+};
+
+/* mmc1 */
+static struct omap_hsmmc_dev_attr am33xx_mmc1_dev_attr = {
+ .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
+};
+
+struct omap_hwmod am33xx_mmc1_hwmod = {
+ .name = "mmc2",
+ .class = &am33xx_mmc_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "mmc_clk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &am33xx_mmc1_dev_attr,
+};
+
+/* mmc2 */
+static struct omap_hsmmc_dev_attr am33xx_mmc2_dev_attr = {
+ .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
+};
+struct omap_hwmod am33xx_mmc2_hwmod = {
+ .name = "mmc3",
+ .class = &am33xx_mmc_hwmod_class,
+ .clkdm_name = "l3s_clkdm",
+ .main_clk = "mmc_clk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &am33xx_mmc2_dev_attr,
+};
+
+/*
+ * 'rtc' class
+ * rtc subsystem
+ */
+static struct omap_hwmod_class_sysconfig am33xx_rtc_sysc = {
+ .rev_offs = 0x0074,
+ .sysc_offs = 0x0078,
+ .sysc_flags = SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO |
+ SIDLE_SMART | SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type3,
+};
+
+static struct omap_hwmod_class am33xx_rtc_hwmod_class = {
+ .name = "rtc",
+ .sysc = &am33xx_rtc_sysc,
+};
+
+struct omap_hwmod am33xx_rtc_hwmod = {
+ .name = "rtc",
+ .class = &am33xx_rtc_hwmod_class,
+ .clkdm_name = "l4_rtc_clkdm",
+ .main_clk = "clk_32768_ck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* 'spi' class */
+static struct omap_hwmod_class_sysconfig am33xx_mcspi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0110,
+ .syss_offs = 0x0114,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | 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,
+};
+
+struct omap_hwmod_class am33xx_spi_hwmod_class = {
+ .name = "mcspi",
+ .sysc = &am33xx_mcspi_sysc,
+ .rev = OMAP4_MCSPI_REV,
+};
+
+/* spi0 */
+struct omap2_mcspi_dev_attr mcspi_attrib = {
+ .num_chipselect = 2,
+};
+struct omap_hwmod am33xx_spi0_hwmod = {
+ .name = "spi0",
+ .class = &am33xx_spi_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "dpll_per_m2_div4_ck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi_attrib,
+};
+
+/* spi1 */
+struct omap_hwmod am33xx_spi1_hwmod = {
+ .name = "spi1",
+ .class = &am33xx_spi_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "dpll_per_m2_div4_ck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi_attrib,
+};
+
+/*
+ * 'spinlock' class
+ * spinlock provides hardware assistance for synchronizing the
+ * processes running on multiple processors
+ */
+
+static struct omap_hwmod_class_sysconfig am33xx_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),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class am33xx_spinlock_hwmod_class = {
+ .name = "spinlock",
+ .sysc = &am33xx_spinlock_sysc,
+};
+
+struct omap_hwmod am33xx_spinlock_hwmod = {
+ .name = "spinlock",
+ .class = &am33xx_spinlock_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* 'timer 2-7' class */
+static struct omap_hwmod_class_sysconfig am33xx_timer_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+struct omap_hwmod_class am33xx_timer_hwmod_class = {
+ .name = "timer",
+ .sysc = &am33xx_timer_sysc,
+};
+
+/* timer1 1ms */
+static struct omap_hwmod_class_sysconfig am33xx_timer1ms_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | 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 am33xx_timer1ms_hwmod_class = {
+ .name = "timer",
+ .sysc = &am33xx_timer1ms_sysc,
+};
+
+struct omap_hwmod am33xx_timer1_hwmod = {
+ .name = "timer1",
+ .class = &am33xx_timer1ms_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .main_clk = "timer1_fck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod am33xx_timer2_hwmod = {
+ .name = "timer2",
+ .class = &am33xx_timer_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "timer2_fck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod am33xx_timer3_hwmod = {
+ .name = "timer3",
+ .class = &am33xx_timer_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "timer3_fck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod am33xx_timer4_hwmod = {
+ .name = "timer4",
+ .class = &am33xx_timer_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "timer4_fck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod am33xx_timer5_hwmod = {
+ .name = "timer5",
+ .class = &am33xx_timer_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "timer5_fck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod am33xx_timer6_hwmod = {
+ .name = "timer6",
+ .class = &am33xx_timer_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "timer6_fck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod am33xx_timer7_hwmod = {
+ .name = "timer7",
+ .class = &am33xx_timer_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "timer7_fck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* tpcc */
+static struct omap_hwmod_class am33xx_tpcc_hwmod_class = {
+ .name = "tpcc",
+};
+
+struct omap_hwmod am33xx_tpcc_hwmod = {
+ .name = "tpcc",
+ .class = &am33xx_tpcc_hwmod_class,
+ .clkdm_name = "l3_clkdm",
+ .main_clk = "l3_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod_class_sysconfig am33xx_tptc_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_MIDLEMODE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_SMART | MSTANDBY_FORCE),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+/* 'tptc' class */
+static struct omap_hwmod_class am33xx_tptc_hwmod_class = {
+ .name = "tptc",
+ .sysc = &am33xx_tptc_sysc,
+};
+
+/* tptc0 */
+struct omap_hwmod am33xx_tptc0_hwmod = {
+ .name = "tptc0",
+ .class = &am33xx_tptc_hwmod_class,
+ .clkdm_name = "l3_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+ .main_clk = "l3_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* tptc1 */
+struct omap_hwmod am33xx_tptc1_hwmod = {
+ .name = "tptc1",
+ .class = &am33xx_tptc_hwmod_class,
+ .clkdm_name = "l3_clkdm",
+ .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
+ .main_clk = "l3_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* tptc2 */
+struct omap_hwmod am33xx_tptc2_hwmod = {
+ .name = "tptc2",
+ .class = &am33xx_tptc_hwmod_class,
+ .clkdm_name = "l3_clkdm",
+ .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
+ .main_clk = "l3_gclk",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* 'uart' class */
+static struct omap_hwmod_class_sysconfig uart_sysc = {
+ .rev_offs = 0x50,
+ .sysc_offs = 0x54,
+ .syss_offs = 0x58,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class uart_class = {
+ .name = "uart",
+ .sysc = &uart_sysc,
+};
+
+struct omap_hwmod am33xx_uart1_hwmod = {
+ .name = "uart1",
+ .class = &uart_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .flags = DEBUG_AM33XXUART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
+ .main_clk = "dpll_per_m2_div4_wkupdm_ck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod am33xx_uart2_hwmod = {
+ .name = "uart2",
+ .class = &uart_class,
+ .clkdm_name = "l4ls_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .main_clk = "dpll_per_m2_div4_ck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart3 */
+struct omap_hwmod am33xx_uart3_hwmod = {
+ .name = "uart3",
+ .class = &uart_class,
+ .clkdm_name = "l4ls_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .main_clk = "dpll_per_m2_div4_ck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod am33xx_uart4_hwmod = {
+ .name = "uart4",
+ .class = &uart_class,
+ .clkdm_name = "l4ls_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .main_clk = "dpll_per_m2_div4_ck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod am33xx_uart5_hwmod = {
+ .name = "uart5",
+ .class = &uart_class,
+ .clkdm_name = "l4ls_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .main_clk = "dpll_per_m2_div4_ck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod am33xx_uart6_hwmod = {
+ .name = "uart6",
+ .class = &uart_class,
+ .clkdm_name = "l4ls_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .main_clk = "dpll_per_m2_div4_ck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* 'wd_timer' class */
+static struct omap_hwmod_class_sysconfig wdt_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .syss_offs = 0x14,
+ .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 am33xx_wd_timer_hwmod_class = {
+ .name = "wd_timer",
+ .sysc = &wdt_sysc,
+ .pre_shutdown = &omap2_wd_timer_disable,
+};
+
+/*
+ * XXX: device.c file uses hardcoded name for watchdog timer
+ * driver "wd_timer2, so we are also using same name as of now...
+ */
+struct omap_hwmod am33xx_wd_timer1_hwmod = {
+ .name = "wd_timer2",
+ .class = &am33xx_wd_timer_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE,
+ .main_clk = "wdt1_fck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static void omap_hwmod_am33xx_clkctrl(void)
+{
+ CLKCTRL(am33xx_uart2_hwmod, AM33XX_CM_PER_UART1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_uart3_hwmod, AM33XX_CM_PER_UART2_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_uart4_hwmod, AM33XX_CM_PER_UART3_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_uart5_hwmod, AM33XX_CM_PER_UART4_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_uart6_hwmod, AM33XX_CM_PER_UART5_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_dcan0_hwmod, AM33XX_CM_PER_DCAN0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_dcan1_hwmod, AM33XX_CM_PER_DCAN1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_elm_hwmod, AM33XX_CM_PER_ELM_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_epwmss0_hwmod, AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_epwmss1_hwmod, AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_epwmss2_hwmod, AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_gpio1_hwmod, AM33XX_CM_PER_GPIO1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_gpio2_hwmod, AM33XX_CM_PER_GPIO2_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_gpio3_hwmod, AM33XX_CM_PER_GPIO3_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_i2c2_hwmod, AM33XX_CM_PER_I2C1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_i2c3_hwmod, AM33XX_CM_PER_I2C2_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_mailbox_hwmod, AM33XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_mcasp0_hwmod, AM33XX_CM_PER_MCASP0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_mcasp1_hwmod, AM33XX_CM_PER_MCASP1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_mmc0_hwmod, AM33XX_CM_PER_MMC0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_mmc1_hwmod, AM33XX_CM_PER_MMC1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_spi0_hwmod, AM33XX_CM_PER_SPI0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_spi1_hwmod, AM33XX_CM_PER_SPI1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_spinlock_hwmod, AM33XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_timer2_hwmod, AM33XX_CM_PER_TIMER2_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_timer3_hwmod, AM33XX_CM_PER_TIMER3_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_timer4_hwmod, AM33XX_CM_PER_TIMER4_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_timer5_hwmod, AM33XX_CM_PER_TIMER5_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_timer6_hwmod, AM33XX_CM_PER_TIMER6_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_timer7_hwmod, AM33XX_CM_PER_TIMER7_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_smartreflex0_hwmod,
+ AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_smartreflex1_hwmod,
+ AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_uart1_hwmod, AM33XX_CM_WKUP_UART0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_timer1_hwmod, AM33XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_i2c1_hwmod, AM33XX_CM_WKUP_I2C0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_wd_timer1_hwmod, AM33XX_CM_WKUP_WDT1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_rtc_hwmod, AM33XX_CM_RTC_RTC_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_mmc2_hwmod, AM33XX_CM_PER_MMC2_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_gpmc_hwmod, AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_l4_ls_hwmod, AM33XX_CM_PER_L4LS_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_l4_wkup_hwmod, AM33XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_l3_main_hwmod, AM33XX_CM_PER_L3_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_tpcc_hwmod, AM33XX_CM_PER_TPCC_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_tptc0_hwmod, AM33XX_CM_PER_TPTC0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_tptc1_hwmod, AM33XX_CM_PER_TPTC1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_tptc2_hwmod, AM33XX_CM_PER_TPTC2_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_gfx_hwmod, AM33XX_CM_GFX_GFX_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_cpgmac0_hwmod, AM33XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_pruss_hwmod, AM33XX_CM_PER_PRUSS_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_mpu_hwmod , AM33XX_CM_MPU_MPU_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_l3_instr_hwmod , AM33XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_ocmcram_hwmod , AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_sha0_hwmod , AM33XX_CM_PER_SHA0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_aes0_hwmod , AM33XX_CM_PER_AES0_CLKCTRL_OFFSET);
+}
+
+static void omap_hwmod_am33xx_rst(void)
+{
+ RSTCTRL(am33xx_pruss_hwmod, AM33XX_RM_PER_RSTCTRL_OFFSET);
+ RSTCTRL(am33xx_gfx_hwmod, AM33XX_RM_GFX_RSTCTRL_OFFSET);
+ RSTST(am33xx_gfx_hwmod, AM33XX_RM_GFX_RSTST_OFFSET);
+}
+
+void omap_hwmod_am33xx_reg(void)
+{
+ omap_hwmod_am33xx_clkctrl();
+ omap_hwmod_am33xx_rst();
+}
+
+static void omap_hwmod_am43xx_clkctrl(void)
+{
+ CLKCTRL(am33xx_uart2_hwmod, AM43XX_CM_PER_UART1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_uart3_hwmod, AM43XX_CM_PER_UART2_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_uart4_hwmod, AM43XX_CM_PER_UART3_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_uart5_hwmod, AM43XX_CM_PER_UART4_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_uart6_hwmod, AM43XX_CM_PER_UART5_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_dcan0_hwmod, AM43XX_CM_PER_DCAN0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_dcan1_hwmod, AM43XX_CM_PER_DCAN1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_elm_hwmod, AM43XX_CM_PER_ELM_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_epwmss0_hwmod, AM43XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_epwmss1_hwmod, AM43XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_epwmss2_hwmod, AM43XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_gpio1_hwmod, AM43XX_CM_PER_GPIO1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_gpio2_hwmod, AM43XX_CM_PER_GPIO2_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_gpio3_hwmod, AM43XX_CM_PER_GPIO3_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_i2c2_hwmod, AM43XX_CM_PER_I2C1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_i2c3_hwmod, AM43XX_CM_PER_I2C2_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_mailbox_hwmod, AM43XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_mcasp0_hwmod, AM43XX_CM_PER_MCASP0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_mcasp1_hwmod, AM43XX_CM_PER_MCASP1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_mmc0_hwmod, AM43XX_CM_PER_MMC0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_mmc1_hwmod, AM43XX_CM_PER_MMC1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_spi0_hwmod, AM43XX_CM_PER_SPI0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_spi1_hwmod, AM43XX_CM_PER_SPI1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_spinlock_hwmod, AM43XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_timer2_hwmod, AM43XX_CM_PER_TIMER2_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_timer3_hwmod, AM43XX_CM_PER_TIMER3_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_timer4_hwmod, AM43XX_CM_PER_TIMER4_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_timer5_hwmod, AM43XX_CM_PER_TIMER5_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_timer6_hwmod, AM43XX_CM_PER_TIMER6_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_timer7_hwmod, AM43XX_CM_PER_TIMER7_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_smartreflex0_hwmod,
+ AM43XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_smartreflex1_hwmod,
+ AM43XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_uart1_hwmod, AM43XX_CM_WKUP_UART0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_timer1_hwmod, AM43XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_i2c1_hwmod, AM43XX_CM_WKUP_I2C0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_wd_timer1_hwmod, AM43XX_CM_WKUP_WDT1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_rtc_hwmod, AM43XX_CM_RTC_RTC_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_mmc2_hwmod, AM43XX_CM_PER_MMC2_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_gpmc_hwmod, AM43XX_CM_PER_GPMC_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_l4_ls_hwmod, AM43XX_CM_PER_L4LS_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_l4_wkup_hwmod, AM43XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_l3_main_hwmod, AM43XX_CM_PER_L3_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_tpcc_hwmod, AM43XX_CM_PER_TPCC_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_tptc0_hwmod, AM43XX_CM_PER_TPTC0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_tptc1_hwmod, AM43XX_CM_PER_TPTC1_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_tptc2_hwmod, AM43XX_CM_PER_TPTC2_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_gfx_hwmod, AM43XX_CM_GFX_GFX_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_cpgmac0_hwmod, AM43XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_pruss_hwmod, AM43XX_CM_PER_PRUSS_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_mpu_hwmod , AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_l3_instr_hwmod , AM43XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_ocmcram_hwmod , AM43XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_sha0_hwmod , AM43XX_CM_PER_SHA0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_aes0_hwmod , AM43XX_CM_PER_AES0_CLKCTRL_OFFSET);
+}
+
+static void omap_hwmod_am43xx_rst(void)
+{
+ RSTCTRL(am33xx_pruss_hwmod, AM43XX_RM_PER_RSTCTRL_OFFSET);
+ RSTCTRL(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTCTRL_OFFSET);
+ RSTST(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTST_OFFSET);
+}
+
+void omap_hwmod_am43xx_reg(void)
+{
+ omap_hwmod_am43xx_clkctrl();
+ omap_hwmod_am43xx_rst();
+}
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
new file mode 100644
index 000000000..0cf7b563d
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -0,0 +1,642 @@
+/*
+ * omap_hwmod_33xx_data.c: Hardware modules present on the AM33XX chips
+ *
+ * Copyright (C) {2012} Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This file is automatically generated from the AM33XX hardware databases.
+ * This program is free software; 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/i2c-omap.h>
+
+#include "omap_hwmod.h"
+#include <linux/platform_data/gpio-omap.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+
+#include "omap_hwmod_common_data.h"
+
+#include "control.h"
+#include "cm33xx.h"
+#include "prm33xx.h"
+#include "prm-regbits-33xx.h"
+#include "i2c.h"
+#include "wd_timer.h"
+#include "omap_hwmod_33xx_43xx_common_data.h"
+
+/*
+ * IP blocks
+ */
+
+/*
+ * 'emif' class
+ * instance(s): emif
+ */
+static struct omap_hwmod_class_sysconfig am33xx_emif_sysc = {
+ .rev_offs = 0x0000,
+};
+
+static struct omap_hwmod_class am33xx_emif_hwmod_class = {
+ .name = "emif",
+ .sysc = &am33xx_emif_sysc,
+};
+
+/* emif */
+static struct omap_hwmod am33xx_emif_hwmod = {
+ .name = "emif",
+ .class = &am33xx_emif_hwmod_class,
+ .clkdm_name = "l3_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "dpll_ddr_m2_div2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM33XX_CM_PER_EMIF_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* l4_hs */
+static struct omap_hwmod am33xx_l4_hs_hwmod = {
+ .name = "l4_hs",
+ .class = &am33xx_l4_hwmod_class,
+ .clkdm_name = "l4hs_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "l4hs_gclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM33XX_CM_PER_L4HS_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod_rst_info am33xx_wkup_m3_resets[] = {
+ { .name = "wkup_m3", .rst_shift = 3, .st_shift = 5 },
+};
+
+/* wkup_m3 */
+static struct omap_hwmod am33xx_wkup_m3_hwmod = {
+ .name = "wkup_m3",
+ .class = &am33xx_wkup_m3_hwmod_class,
+ .clkdm_name = "l4_wkup_aon_clkdm",
+ /* Keep hardreset asserted */
+ .flags = HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST,
+ .main_clk = "dpll_core_m4_div2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM33XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET,
+ .rstctrl_offs = AM33XX_RM_WKUP_RSTCTRL_OFFSET,
+ .rstst_offs = AM33XX_RM_WKUP_RSTST_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .rst_lines = am33xx_wkup_m3_resets,
+ .rst_lines_cnt = ARRAY_SIZE(am33xx_wkup_m3_resets),
+};
+
+/*
+ * 'adc/tsc' class
+ * TouchScreen Controller (Anolog-To-Digital Converter)
+ */
+static struct omap_hwmod_class_sysconfig am33xx_adc_tsc_sysc = {
+ .rev_offs = 0x00,
+ .sysc_offs = 0x10,
+ .sysc_flags = SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class am33xx_adc_tsc_hwmod_class = {
+ .name = "adc_tsc",
+ .sysc = &am33xx_adc_tsc_sysc,
+};
+
+static struct omap_hwmod am33xx_adc_tsc_hwmod = {
+ .name = "adc_tsc",
+ .class = &am33xx_adc_tsc_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .main_clk = "adc_tsc_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM33XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 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
+ *
+ * - cEFUSE (doesn't fall under any ocp_if)
+ * - clkdiv32k
+ * - ocp watch point
+ */
+#if 0
+/*
+ * 'cefuse' class
+ */
+static struct omap_hwmod_class am33xx_cefuse_hwmod_class = {
+ .name = "cefuse",
+};
+
+static struct omap_hwmod am33xx_cefuse_hwmod = {
+ .name = "cefuse",
+ .class = &am33xx_cefuse_hwmod_class,
+ .clkdm_name = "l4_cefuse_clkdm",
+ .main_clk = "cefuse_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'clkdiv32k' class
+ */
+static struct omap_hwmod_class am33xx_clkdiv32k_hwmod_class = {
+ .name = "clkdiv32k",
+};
+
+static struct omap_hwmod am33xx_clkdiv32k_hwmod = {
+ .name = "clkdiv32k",
+ .class = &am33xx_clkdiv32k_hwmod_class,
+ .clkdm_name = "clk_24mhz_clkdm",
+ .main_clk = "clkdiv32k_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM33XX_CM_PER_CLKDIV32K_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* ocpwp */
+static struct omap_hwmod_class am33xx_ocpwp_hwmod_class = {
+ .name = "ocpwp",
+};
+
+static struct omap_hwmod am33xx_ocpwp_hwmod = {
+ .name = "ocpwp",
+ .class = &am33xx_ocpwp_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM33XX_CM_PER_OCPWP_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+#endif
+
+/*
+ * 'debugss' class
+ * debug sub system
+ */
+static struct omap_hwmod_opt_clk debugss_opt_clks[] = {
+ { .role = "dbg_sysclk", .clk = "dbg_sysclk_ck" },
+ { .role = "dbg_clka", .clk = "dbg_clka_ck" },
+};
+
+static struct omap_hwmod_class am33xx_debugss_hwmod_class = {
+ .name = "debugss",
+};
+
+static struct omap_hwmod am33xx_debugss_hwmod = {
+ .name = "debugss",
+ .class = &am33xx_debugss_hwmod_class,
+ .clkdm_name = "l3_aon_clkdm",
+ .main_clk = "trace_clk_div_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM33XX_CM_WKUP_DEBUGSS_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = debugss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(debugss_opt_clks),
+};
+
+static struct omap_hwmod am33xx_control_hwmod = {
+ .name = "control",
+ .class = &am33xx_control_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "dpll_core_m4_div2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM33XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* gpio0 */
+static struct omap_hwmod_opt_clk gpio0_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio0_dbclk" },
+};
+
+static struct omap_hwmod am33xx_gpio0_hwmod = {
+ .name = "gpio1",
+ .class = &am33xx_gpio_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "dpll_core_m4_div2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM33XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = gpio0_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio0_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* lcdc */
+static struct omap_hwmod_class_sysconfig lcdc_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x54,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class am33xx_lcdc_hwmod_class = {
+ .name = "lcdc",
+ .sysc = &lcdc_sysc,
+};
+
+static struct omap_hwmod am33xx_lcdc_hwmod = {
+ .name = "lcdc",
+ .class = &am33xx_lcdc_hwmod_class,
+ .clkdm_name = "lcdc_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+ .main_clk = "lcd_gclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM33XX_CM_PER_LCDC_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'usb_otg' class
+ * high-speed on-the-go universal serial bus (usb_otg) controller
+ */
+static struct omap_hwmod_class_sysconfig am33xx_usbhsotg_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class am33xx_usbotg_class = {
+ .name = "usbotg",
+ .sysc = &am33xx_usbhsotg_sysc,
+};
+
+static struct omap_hwmod am33xx_usbss_hwmod = {
+ .name = "usb_otg_hs",
+ .class = &am33xx_usbotg_class,
+ .clkdm_name = "l3s_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+ .main_clk = "usbotg_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM33XX_CM_PER_USB0_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+
+/*
+ * Interfaces
+ */
+
+static struct omap_hwmod_addr_space am33xx_emif_addrs[] = {
+ {
+ .pa_start = 0x4c000000,
+ .pa_end = 0x4c000fff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+/* l3 main -> emif */
+static struct omap_hwmod_ocp_if am33xx_l3_main__emif = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am33xx_emif_hwmod,
+ .clk = "dpll_core_m4_ck",
+ .addr = am33xx_emif_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3 main -> l4 hs */
+static struct omap_hwmod_ocp_if am33xx_l3_main__l4_hs = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am33xx_l4_hs_hwmod,
+ .clk = "l3s_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* wkup m3 -> l4 wkup */
+static struct omap_hwmod_ocp_if am33xx_wkup_m3__l4_wkup = {
+ .master = &am33xx_wkup_m3_hwmod,
+ .slave = &am33xx_l4_wkup_hwmod,
+ .clk = "dpll_core_m4_div2_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 wkup -> wkup m3 */
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__wkup_m3 = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_wkup_m3_hwmod,
+ .clk = "dpll_core_m4_div2_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 hs -> pru-icss */
+static struct omap_hwmod_ocp_if am33xx_l4_hs__pruss = {
+ .master = &am33xx_l4_hs_hwmod,
+ .slave = &am33xx_pruss_hwmod,
+ .clk = "dpll_core_m4_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main -> debugss */
+static struct omap_hwmod_addr_space am33xx_debugss_addrs[] = {
+ {
+ .pa_start = 0x4b000000,
+ .pa_end = 0x4b000000 + SZ_16M - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+static struct omap_hwmod_ocp_if am33xx_l3_main__debugss = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am33xx_debugss_hwmod,
+ .clk = "dpll_core_m4_ck",
+ .addr = am33xx_debugss_addrs,
+ .user = OCP_USER_MPU,
+};
+
+/* l4 wkup -> smartreflex0 */
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__smartreflex0 = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_smartreflex0_hwmod,
+ .clk = "dpll_core_m4_div2_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 wkup -> smartreflex1 */
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__smartreflex1 = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_smartreflex1_hwmod,
+ .clk = "dpll_core_m4_div2_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 wkup -> control */
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__control = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_control_hwmod,
+ .clk = "dpll_core_m4_div2_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* L4 WKUP -> I2C1 */
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__i2c1 = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_i2c1_hwmod,
+ .clk = "dpll_core_m4_div2_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* L4 WKUP -> GPIO1 */
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__gpio0 = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_gpio0_hwmod,
+ .clk = "dpll_core_m4_div2_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 WKUP -> ADC_TSC */
+static struct omap_hwmod_addr_space am33xx_adc_tsc_addrs[] = {
+ {
+ .pa_start = 0x44E0D000,
+ .pa_end = 0x44E0D000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__adc_tsc = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_adc_tsc_hwmod,
+ .clk = "dpll_core_m4_div2_ck",
+ .addr = am33xx_adc_tsc_addrs,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am33xx_l4_hs__cpgmac0 = {
+ .master = &am33xx_l4_hs_hwmod,
+ .slave = &am33xx_cpgmac0_hwmod,
+ .clk = "cpsw_125mhz_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_lcdc_addr_space[] = {
+ {
+ .pa_start = 0x4830E000,
+ .pa_end = 0x4830E000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+static struct omap_hwmod_ocp_if am33xx_l3_main__lcdc = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am33xx_lcdc_hwmod,
+ .clk = "dpll_core_m4_ck",
+ .addr = am33xx_lcdc_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+/* l4 wkup -> timer1 */
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__timer1 = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_timer1_hwmod,
+ .clk = "dpll_core_m4_div2_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 wkup -> uart1 */
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__uart1 = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_uart1_hwmod,
+ .clk = "dpll_core_m4_div2_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* l4 wkup -> wd_timer1 */
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__wd_timer1 = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_wd_timer1_hwmod,
+ .clk = "dpll_core_m4_div2_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* usbss */
+/* l3 s -> USBSS interface */
+static struct omap_hwmod_ocp_if am33xx_l3_s__usbss = {
+ .master = &am33xx_l3_s_hwmod,
+ .slave = &am33xx_usbss_hwmod,
+ .clk = "l3s_gclk",
+ .user = OCP_USER_MPU,
+ .flags = OCPIF_SWSUP_IDLE,
+};
+
+/* rng */
+static struct omap_hwmod_class_sysconfig am33xx_rng_sysc = {
+ .rev_offs = 0x1fe0,
+ .sysc_offs = 0x1fe4,
+ .sysc_flags = SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class am33xx_rng_hwmod_class = {
+ .name = "rng",
+ .sysc = &am33xx_rng_sysc,
+};
+
+static struct omap_hwmod am33xx_rng_hwmod = {
+ .name = "rng",
+ .class = &am33xx_rng_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE,
+ .main_clk = "rng_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM33XX_CM_PER_RNG_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod_ocp_if am33xx_l4_per__rng = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_rng_hwmod,
+ .clk = "rng_fck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {
+ &am33xx_l3_main__emif,
+ &am33xx_mpu__l3_main,
+ &am33xx_mpu__prcm,
+ &am33xx_l3_s__l4_ls,
+ &am33xx_l3_s__l4_wkup,
+ &am33xx_l3_main__l4_hs,
+ &am33xx_l3_main__l3_s,
+ &am33xx_l3_main__l3_instr,
+ &am33xx_l3_main__gfx,
+ &am33xx_l3_s__l3_main,
+ &am33xx_pruss__l3_main,
+ &am33xx_wkup_m3__l4_wkup,
+ &am33xx_gfx__l3_main,
+ &am33xx_l3_main__debugss,
+ &am33xx_l4_wkup__wkup_m3,
+ &am33xx_l4_wkup__control,
+ &am33xx_l4_wkup__smartreflex0,
+ &am33xx_l4_wkup__smartreflex1,
+ &am33xx_l4_wkup__uart1,
+ &am33xx_l4_wkup__timer1,
+ &am33xx_l4_wkup__rtc,
+ &am33xx_l4_wkup__i2c1,
+ &am33xx_l4_wkup__gpio0,
+ &am33xx_l4_wkup__adc_tsc,
+ &am33xx_l4_wkup__wd_timer1,
+ &am33xx_l4_hs__pruss,
+ &am33xx_l4_per__dcan0,
+ &am33xx_l4_per__dcan1,
+ &am33xx_l4_per__gpio1,
+ &am33xx_l4_per__gpio2,
+ &am33xx_l4_per__gpio3,
+ &am33xx_l4_per__i2c2,
+ &am33xx_l4_per__i2c3,
+ &am33xx_l4_per__mailbox,
+ &am33xx_l4_ls__mcasp0,
+ &am33xx_l4_ls__mcasp1,
+ &am33xx_l4_ls__mmc0,
+ &am33xx_l4_ls__mmc1,
+ &am33xx_l3_s__mmc2,
+ &am33xx_l4_ls__timer2,
+ &am33xx_l4_ls__timer3,
+ &am33xx_l4_ls__timer4,
+ &am33xx_l4_ls__timer5,
+ &am33xx_l4_ls__timer6,
+ &am33xx_l4_ls__timer7,
+ &am33xx_l3_main__tpcc,
+ &am33xx_l4_ls__uart2,
+ &am33xx_l4_ls__uart3,
+ &am33xx_l4_ls__uart4,
+ &am33xx_l4_ls__uart5,
+ &am33xx_l4_ls__uart6,
+ &am33xx_l4_ls__spinlock,
+ &am33xx_l4_ls__elm,
+ &am33xx_l4_ls__epwmss0,
+ &am33xx_epwmss0__ecap0,
+ &am33xx_epwmss0__eqep0,
+ &am33xx_epwmss0__ehrpwm0,
+ &am33xx_l4_ls__epwmss1,
+ &am33xx_epwmss1__ecap1,
+ &am33xx_epwmss1__eqep1,
+ &am33xx_epwmss1__ehrpwm1,
+ &am33xx_l4_ls__epwmss2,
+ &am33xx_epwmss2__ecap2,
+ &am33xx_epwmss2__eqep2,
+ &am33xx_epwmss2__ehrpwm2,
+ &am33xx_l3_s__gpmc,
+ &am33xx_l3_main__lcdc,
+ &am33xx_l4_ls__mcspi0,
+ &am33xx_l4_ls__mcspi1,
+ &am33xx_l3_main__tptc0,
+ &am33xx_l3_main__tptc1,
+ &am33xx_l3_main__tptc2,
+ &am33xx_l3_main__ocmc,
+ &am33xx_l3_s__usbss,
+ &am33xx_l4_hs__cpgmac0,
+ &am33xx_cpgmac0__mdio,
+ &am33xx_l3_main__sha0,
+ &am33xx_l3_main__aes0,
+ &am33xx_l4_per__rng,
+ NULL,
+};
+
+int __init am33xx_hwmod_init(void)
+{
+ omap_hwmod_am33xx_reg();
+ omap_hwmod_init();
+ return omap_hwmod_register_links(am33xx_hwmod_ocp_ifs);
+}
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 000000000..4e8e93c39
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -0,0 +1,3967 @@
+/*
+ * omap_hwmod_3xxx_data.c - hardware modules present on the OMAP3xxx chips
+ *
+ * Copyright (C) 2009-2011 Nokia Corporation
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * 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 <linux/i2c-omap.h>
+#include <linux/power/smartreflex.h>
+#include <linux/platform_data/gpio-omap.h>
+#include <linux/platform_data/hsmmc-omap.h>
+
+#include <linux/omap-dma.h>
+#include "l3_3xxx.h"
+#include "l4_3xxx.h"
+#include <linux/platform_data/asoc-ti-mcbsp.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+#include <linux/platform_data/iommu-omap.h>
+#include <linux/platform_data/mailbox-omap.h>
+#include <plat/dmtimer.h>
+
+#include "soc.h"
+#include "omap_hwmod.h"
+#include "omap_hwmod_common_data.h"
+#include "prm-regbits-34xx.h"
+#include "cm-regbits-34xx.h"
+
+#include "i2c.h"
+#include "wd_timer.h"
+#include "serial.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.
+ */
+
+#define AM35XX_IPSS_USBOTGSS_BASE 0x5C040000
+
+/*
+ * IP blocks
+ */
+
+/* L3 */
+static struct omap_hwmod_irq_info omap3xxx_l3_main_irqs[] = {
+ { .irq = 9 + OMAP_INTC_START, },
+ { .irq = 10 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod omap3xxx_l3_main_hwmod = {
+ .name = "l3_main",
+ .class = &l3_hwmod_class,
+ .mpu_irqs = omap3xxx_l3_main_irqs,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* L4 CORE */
+static struct omap_hwmod omap3xxx_l4_core_hwmod = {
+ .name = "l4_core",
+ .class = &l4_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* L4 PER */
+static struct omap_hwmod omap3xxx_l4_per_hwmod = {
+ .name = "l4_per",
+ .class = &l4_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* L4 WKUP */
+static struct omap_hwmod omap3xxx_l4_wkup_hwmod = {
+ .name = "l4_wkup",
+ .class = &l4_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* L4 SEC */
+static struct omap_hwmod omap3xxx_l4_sec_hwmod = {
+ .name = "l4_sec",
+ .class = &l4_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* MPU */
+static struct omap_hwmod_irq_info omap3xxx_mpu_irqs[] = {
+ { .name = "pmu", .irq = 3 + OMAP_INTC_START },
+ { .irq = -1 }
+};
+
+static struct omap_hwmod omap3xxx_mpu_hwmod = {
+ .name = "mpu",
+ .mpu_irqs = omap3xxx_mpu_irqs,
+ .class = &mpu_hwmod_class,
+ .main_clk = "arm_fck",
+};
+
+/* IVA2 (IVA2) */
+static struct omap_hwmod_rst_info omap3xxx_iva_resets[] = {
+ { .name = "logic", .rst_shift = 0, .st_shift = 8 },
+ { .name = "seq0", .rst_shift = 1, .st_shift = 9 },
+ { .name = "seq1", .rst_shift = 2, .st_shift = 10 },
+};
+
+static struct omap_hwmod omap3xxx_iva_hwmod = {
+ .name = "iva",
+ .class = &iva_hwmod_class,
+ .clkdm_name = "iva2_clkdm",
+ .rst_lines = omap3xxx_iva_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap3xxx_iva_resets),
+ .main_clk = "iva2_ck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = OMAP3430_IVA2_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_IVA2_SHIFT,
+ }
+ },
+};
+
+/*
+ * 'debugss' class
+ * debug and emulation sub system
+ */
+
+static struct omap_hwmod_class omap3xxx_debugss_hwmod_class = {
+ .name = "debugss",
+};
+
+/* debugss */
+static struct omap_hwmod omap3xxx_debugss_hwmod = {
+ .name = "debugss",
+ .class = &omap3xxx_debugss_hwmod_class,
+ .clkdm_name = "emu_clkdm",
+ .main_clk = "emu_src_ck",
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* timer class */
+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_CLOCKACTIVITY |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .clockact = CLOCKACT_TEST_ICLK,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_timer_hwmod_class = {
+ .name = "timer",
+ .sysc = &omap3xxx_timer_sysc,
+};
+
+/* secure timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_secure_dev_attr = {
+ .timer_capability = OMAP_TIMER_ALWON | OMAP_TIMER_SECURE,
+};
+
+/* always-on timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
+ .timer_capability = OMAP_TIMER_ALWON,
+};
+
+/* pwm timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_PWM,
+};
+
+/* timers with DSP interrupt dev attribute */
+static struct omap_timer_capability_dev_attr capability_dsp_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_DSP_IRQ,
+};
+
+/* pwm timers with DSP interrupt dev attribute */
+static struct omap_timer_capability_dev_attr capability_dsp_pwm_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_DSP_IRQ | OMAP_TIMER_HAS_PWM,
+};
+
+/* timer1 */
+static struct omap_hwmod omap3xxx_timer1_hwmod = {
+ .name = "timer1",
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer2 */
+static struct omap_hwmod omap3xxx_timer2_hwmod = {
+ .name = "timer2",
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer3 */
+static struct omap_hwmod omap3xxx_timer3_hwmod = {
+ .name = "timer3",
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer4 */
+static struct omap_hwmod omap3xxx_timer4_hwmod = {
+ .name = "timer4",
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer5 */
+static struct omap_hwmod omap3xxx_timer5_hwmod = {
+ .name = "timer5",
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .dev_attr = &capability_dsp_dev_attr,
+ .class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer6 */
+static struct omap_hwmod omap3xxx_timer6_hwmod = {
+ .name = "timer6",
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .dev_attr = &capability_dsp_dev_attr,
+ .class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer7 */
+static struct omap_hwmod omap3xxx_timer7_hwmod = {
+ .name = "timer7",
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .dev_attr = &capability_dsp_dev_attr,
+ .class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer8 */
+static struct omap_hwmod omap3xxx_timer8_hwmod = {
+ .name = "timer8",
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .dev_attr = &capability_dsp_pwm_dev_attr,
+ .class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer9 */
+static struct omap_hwmod omap3xxx_timer9_hwmod = {
+ .name = "timer9",
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .dev_attr = &capability_pwm_dev_attr,
+ .class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer10 */
+static struct omap_hwmod omap3xxx_timer10_hwmod = {
+ .name = "timer10",
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .dev_attr = &capability_pwm_dev_attr,
+ .class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer11 */
+static struct omap_hwmod omap3xxx_timer11_hwmod = {
+ .name = "timer11",
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .dev_attr = &capability_pwm_dev_attr,
+ .class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* timer12 */
+static struct omap_hwmod_irq_info omap3xxx_timer12_mpu_irqs[] = {
+ { .irq = 95 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod omap3xxx_timer12_hwmod = {
+ .name = "timer12",
+ .mpu_irqs = 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,
+ },
+ },
+ .dev_attr = &capability_secure_dev_attr,
+ .class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/*
+ * '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),
+ .clockact = CLOCKACT_TEST_ICLK,
+ .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,
+ .reset = &omap2_wd_timer_reset,
+};
+
+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,
+ },
+ },
+ /*
+ * 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,
+};
+
+/* UART1 */
+static struct omap_hwmod omap3xxx_uart1_hwmod = {
+ .name = "uart1",
+ .mpu_irqs = omap2_uart1_mpu_irqs,
+ .sdma_reqs = omap2_uart1_sdma_reqs,
+ .main_clk = "uart1_fck",
+ .flags = DEBUG_TI81XXUART1_FLAGS | HWMOD_SWSUP_SIDLE,
+ .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,
+ },
+ },
+ .class = &omap2_uart_class,
+};
+
+/* UART2 */
+static struct omap_hwmod omap3xxx_uart2_hwmod = {
+ .name = "uart2",
+ .mpu_irqs = omap2_uart2_mpu_irqs,
+ .sdma_reqs = omap2_uart2_sdma_reqs,
+ .main_clk = "uart2_fck",
+ .flags = DEBUG_TI81XXUART2_FLAGS | HWMOD_SWSUP_SIDLE,
+ .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,
+ },
+ },
+ .class = &omap2_uart_class,
+};
+
+/* UART3 */
+static struct omap_hwmod omap3xxx_uart3_hwmod = {
+ .name = "uart3",
+ .mpu_irqs = omap2_uart3_mpu_irqs,
+ .sdma_reqs = omap2_uart3_sdma_reqs,
+ .main_clk = "uart3_fck",
+ .flags = DEBUG_OMAP3UART3_FLAGS | DEBUG_TI81XXUART3_FLAGS |
+ HWMOD_SWSUP_SIDLE,
+ .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,
+ },
+ },
+ .class = &omap2_uart_class,
+};
+
+/* UART4 */
+static struct omap_hwmod_irq_info uart4_mpu_irqs[] = {
+ { .irq = 80 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod_dma_info uart4_sdma_reqs[] = {
+ { .name = "rx", .dma_req = 82, },
+ { .name = "tx", .dma_req = 81, },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod omap36xx_uart4_hwmod = {
+ .name = "uart4",
+ .mpu_irqs = uart4_mpu_irqs,
+ .sdma_reqs = uart4_sdma_reqs,
+ .main_clk = "uart4_fck",
+ .flags = DEBUG_OMAP3UART4_FLAGS | HWMOD_SWSUP_SIDLE,
+ .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,
+ },
+ },
+ .class = &omap2_uart_class,
+};
+
+static struct omap_hwmod_irq_info am35xx_uart4_mpu_irqs[] = {
+ { .irq = 84 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod_dma_info am35xx_uart4_sdma_reqs[] = {
+ { .name = "rx", .dma_req = 55, },
+ { .name = "tx", .dma_req = 54, },
+ { .dma_req = -1 }
+};
+
+/*
+ * XXX AM35xx UART4 cannot complete its softreset without uart1_fck or
+ * uart2_fck being enabled. So we add uart1_fck as an optional clock,
+ * below, and set the HWMOD_CONTROL_OPT_CLKS_IN_RESET. This really
+ * should not be needed. The functional clock structure of the AM35xx
+ * UART4 is extremely unclear and opaque; it is unclear what the role
+ * of uart1/2_fck is for the UART4. Any clarification from either
+ * empirical testing or the AM3505/3517 hardware designers would be
+ * most welcome.
+ */
+static struct omap_hwmod_opt_clk am35xx_uart4_opt_clks[] = {
+ { .role = "softreset_uart1_fck", .clk = "uart1_fck" },
+};
+
+static struct omap_hwmod am35xx_uart4_hwmod = {
+ .name = "uart4",
+ .mpu_irqs = am35xx_uart4_mpu_irqs,
+ .sdma_reqs = am35xx_uart4_sdma_reqs,
+ .main_clk = "uart4_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = AM35XX_EN_UART4_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = AM35XX_ST_UART4_SHIFT,
+ },
+ },
+ .opt_clks = am35xx_uart4_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(am35xx_uart4_opt_clks),
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .class = &omap2_uart_class,
+};
+
+static struct omap_hwmod_class i2c_class = {
+ .name = "i2c",
+ .sysc = &i2c_sysc,
+ .rev = OMAP_I2C_IP_VERSION_1,
+ .reset = &omap_i2c_reset,
+};
+
+static struct omap_hwmod_dma_info omap3xxx_dss_sdma_chs[] = {
+ { .name = "dispc", .dma_req = 5 },
+ { .name = "dsi1", .dma_req = 74 },
+ { .dma_req = -1 }
+};
+
+/* dss */
+static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+ /*
+ * The DSS HW needs all DSS clocks enabled during reset. The dss_core
+ * driver does not use these clocks.
+ */
+ { .role = "sys_clk", .clk = "dss2_alwon_fck" },
+ { .role = "tv_clk", .clk = "dss_tv_fck" },
+ /* required only on OMAP3430 */
+ { .role = "tv_dac_clk", .clk = "dss_96m_fck" },
+};
+
+static struct omap_hwmod omap3430es1_dss_core_hwmod = {
+ .name = "dss_core",
+ .class = &omap2_dss_hwmod_class,
+ .main_clk = "dss1_alwon_fck", /* instead of dss_fck */
+ .sdma_reqs = 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),
+ .flags = HWMOD_NO_IDLEST | HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+};
+
+static struct omap_hwmod omap3xxx_dss_core_hwmod = {
+ .name = "dss_core",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .class = &omap2_dss_hwmod_class,
+ .main_clk = "dss1_alwon_fck", /* instead of dss_fck */
+ .sdma_reqs = 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),
+};
+
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap3_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 |
+ SYSC_HAS_ENAWAKEUP),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &omap3_dispc_sysc,
+};
+
+static struct omap_hwmod omap3xxx_dss_dispc_hwmod = {
+ .name = "dss_dispc",
+ .class = &omap3_dispc_hwmod_class,
+ .mpu_irqs = omap2_dispc_irqs,
+ .main_clk = "dss1_alwon_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_DSS1_SHIFT,
+ .module_offs = OMAP3430_DSS_MOD,
+ },
+ },
+ .flags = HWMOD_NO_IDLEST,
+ .dev_attr = &omap2_3_dss_dispc_dev_attr
+};
+
+/*
+ * '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 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+/* dss_dsi1 */
+static struct omap_hwmod_opt_clk dss_dsi1_opt_clks[] = {
+ { .role = "sys_clk", .clk = "dss2_alwon_fck" },
+};
+
+static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = {
+ .name = "dss_dsi1",
+ .class = &omap3xxx_dsi_hwmod_class,
+ .mpu_irqs = 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,
+ },
+ },
+ .opt_clks = dss_dsi1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_opt_clks),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = {
+ { .role = "ick", .clk = "dss_ick" },
+};
+
+static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = {
+ .name = "dss_rfbi",
+ .class = &omap2_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,
+ },
+ },
+ .opt_clks = dss_rfbi_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod_opt_clk dss_venc_opt_clks[] = {
+ /* required only on OMAP3430 */
+ { .role = "tv_dac_clk", .clk = "dss_96m_fck" },
+};
+
+static struct omap_hwmod omap3xxx_dss_venc_hwmod = {
+ .name = "dss_venc",
+ .class = &omap2_venc_hwmod_class,
+ .main_clk = "dss_tv_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_DSS1_SHIFT,
+ .module_offs = OMAP3430_DSS_MOD,
+ },
+ },
+ .opt_clks = dss_venc_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_venc_opt_clks),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* I2C1 */
+static struct omap_i2c_dev_attr i2c1_dev_attr = {
+ .fifo_depth = 8, /* bytes */
+ .flags = OMAP_I2C_FLAG_BUS_SHIFT_2,
+};
+
+static struct omap_hwmod omap3xxx_i2c1_hwmod = {
+ .name = "i2c1",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .mpu_irqs = omap2_i2c1_mpu_irqs,
+ .sdma_reqs = omap2_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,
+ },
+ },
+ .class = &i2c_class,
+ .dev_attr = &i2c1_dev_attr,
+};
+
+/* I2C2 */
+static struct omap_i2c_dev_attr i2c2_dev_attr = {
+ .fifo_depth = 8, /* bytes */
+ .flags = OMAP_I2C_FLAG_BUS_SHIFT_2,
+};
+
+static struct omap_hwmod omap3xxx_i2c2_hwmod = {
+ .name = "i2c2",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .mpu_irqs = omap2_i2c2_mpu_irqs,
+ .sdma_reqs = omap2_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,
+ },
+ },
+ .class = &i2c_class,
+ .dev_attr = &i2c2_dev_attr,
+};
+
+/* I2C3 */
+static struct omap_i2c_dev_attr i2c3_dev_attr = {
+ .fifo_depth = 64, /* bytes */
+ .flags = OMAP_I2C_FLAG_BUS_SHIFT_2,
+};
+
+static struct omap_hwmod_irq_info i2c3_mpu_irqs[] = {
+ { .irq = 61 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod_dma_info i2c3_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 25 },
+ { .name = "rx", .dma_req = 26 },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod omap3xxx_i2c3_hwmod = {
+ .name = "i2c3",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .mpu_irqs = i2c3_mpu_irqs,
+ .sdma_reqs = 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,
+ },
+ },
+ .class = &i2c_class,
+ .dev_attr = &i2c3_dev_attr,
+};
+
+/*
+ * '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_opt_clk gpio1_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio1_dbck", },
+};
+
+static struct omap_hwmod omap3xxx_gpio1_hwmod = {
+ .name = "gpio1",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio2 */
+static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio2_dbck", },
+};
+
+static struct omap_hwmod omap3xxx_gpio2_hwmod = {
+ .name = "gpio2",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio3 */
+static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio3_dbck", },
+};
+
+static struct omap_hwmod omap3xxx_gpio3_hwmod = {
+ .name = "gpio3",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio4 */
+static struct omap_hwmod_opt_clk gpio4_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio4_dbck", },
+};
+
+static struct omap_hwmod omap3xxx_gpio4_hwmod = {
+ .name = "gpio4",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio5 */
+static struct omap_hwmod_irq_info omap3xxx_gpio5_irqs[] = {
+ { .irq = 33 + OMAP_INTC_START, }, /* INT_34XX_GPIO_BANK5 */
+ { .irq = -1 },
+};
+
+static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio5_dbck", },
+};
+
+static struct omap_hwmod omap3xxx_gpio5_hwmod = {
+ .name = "gpio5",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = 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,
+ },
+ },
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio6 */
+static struct omap_hwmod_irq_info omap3xxx_gpio6_irqs[] = {
+ { .irq = 34 + OMAP_INTC_START, }, /* INT_34XX_GPIO_BANK6 */
+ { .irq = -1 },
+};
+
+static struct omap_hwmod_opt_clk gpio6_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio6_dbck", },
+};
+
+static struct omap_hwmod omap3xxx_gpio6_hwmod = {
+ .name = "gpio6",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = 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,
+ },
+ },
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* 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 omap3xxx_dma_system_hwmod = {
+ .name = "dma",
+ .class = &omap3xxx_dma_hwmod_class,
+ .mpu_irqs = omap2_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,
+ },
+ },
+ .dev_attr = &dma_dev_attr,
+ .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,
+};
+
+/* McBSP functional clock mapping */
+static struct omap_hwmod_opt_clk mcbsp15_opt_clks[] = {
+ { .role = "pad_fck", .clk = "mcbsp_clks" },
+ { .role = "prcm_fck", .clk = "core_96m_fck" },
+};
+
+static struct omap_hwmod_opt_clk mcbsp234_opt_clks[] = {
+ { .role = "pad_fck", .clk = "mcbsp_clks" },
+ { .role = "prcm_fck", .clk = "per_96m_fck" },
+};
+
+/* mcbsp1 */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp1_irqs[] = {
+ { .name = "common", .irq = 16 + OMAP_INTC_START, },
+ { .name = "tx", .irq = 59 + OMAP_INTC_START, },
+ { .name = "rx", .irq = 60 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod omap3xxx_mcbsp1_hwmod = {
+ .name = "mcbsp1",
+ .class = &omap3xxx_mcbsp_hwmod_class,
+ .mpu_irqs = omap3xxx_mcbsp1_irqs,
+ .sdma_reqs = omap2_mcbsp1_sdma_reqs,
+ .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,
+ },
+ },
+ .opt_clks = mcbsp15_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp15_opt_clks),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp2_irqs[] = {
+ { .name = "common", .irq = 17 + OMAP_INTC_START, },
+ { .name = "tx", .irq = 62 + OMAP_INTC_START, },
+ { .name = "rx", .irq = 63 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+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,
+ .sdma_reqs = omap2_mcbsp2_sdma_reqs,
+ .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,
+ },
+ },
+ .opt_clks = mcbsp234_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp234_opt_clks),
+ .dev_attr = &omap34xx_mcbsp2_dev_attr,
+};
+
+/* mcbsp3 */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp3_irqs[] = {
+ { .name = "common", .irq = 22 + OMAP_INTC_START, },
+ { .name = "tx", .irq = 89 + OMAP_INTC_START, },
+ { .name = "rx", .irq = 90 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+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,
+ .sdma_reqs = omap2_mcbsp3_sdma_reqs,
+ .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,
+ },
+ },
+ .opt_clks = mcbsp234_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp234_opt_clks),
+ .dev_attr = &omap34xx_mcbsp3_dev_attr,
+};
+
+/* mcbsp4 */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp4_irqs[] = {
+ { .name = "common", .irq = 23 + OMAP_INTC_START, },
+ { .name = "tx", .irq = 54 + OMAP_INTC_START, },
+ { .name = "rx", .irq = 55 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod_dma_info omap3xxx_mcbsp4_sdma_chs[] = {
+ { .name = "rx", .dma_req = 20 },
+ { .name = "tx", .dma_req = 19 },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod omap3xxx_mcbsp4_hwmod = {
+ .name = "mcbsp4",
+ .class = &omap3xxx_mcbsp_hwmod_class,
+ .mpu_irqs = omap3xxx_mcbsp4_irqs,
+ .sdma_reqs = 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,
+ },
+ },
+ .opt_clks = mcbsp234_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp234_opt_clks),
+};
+
+/* mcbsp5 */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp5_irqs[] = {
+ { .name = "common", .irq = 27 + OMAP_INTC_START, },
+ { .name = "tx", .irq = 81 + OMAP_INTC_START, },
+ { .name = "rx", .irq = 82 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod_dma_info omap3xxx_mcbsp5_sdma_chs[] = {
+ { .name = "rx", .dma_req = 22 },
+ { .name = "tx", .dma_req = 21 },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod omap3xxx_mcbsp5_hwmod = {
+ .name = "mcbsp5",
+ .class = &omap3xxx_mcbsp_hwmod_class,
+ .mpu_irqs = omap3xxx_mcbsp5_irqs,
+ .sdma_reqs = 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,
+ },
+ },
+ .opt_clks = mcbsp15_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp15_opt_clks),
+};
+
+/* '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 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod = {
+ .name = "mcbsp2_sidetone",
+ .class = &omap3xxx_mcbsp_sidetone_hwmod_class,
+ .mpu_irqs = 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,
+ },
+ },
+};
+
+/* mcbsp3_sidetone */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp3_sidetone_irqs[] = {
+ { .name = "irq", .irq = 5 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod = {
+ .name = "mcbsp3_sidetone",
+ .class = &omap3xxx_mcbsp_sidetone_hwmod_class,
+ .mpu_irqs = 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,
+ },
+ },
+};
+
+/* 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_smartreflex_dev_attr sr1_dev_attr = {
+ .sensor_voltdm_name = "mpu_iva",
+};
+
+static struct omap_hwmod_irq_info omap3_smartreflex_mpu_irqs[] = {
+ { .irq = 18 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod omap34xx_sr1_hwmod = {
+ .name = "smartreflex_mpu_iva",
+ .class = &omap34xx_smartreflex_hwmod_class,
+ .main_clk = "sr1_fck",
+ .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,
+ },
+ },
+ .dev_attr = &sr1_dev_attr,
+ .mpu_irqs = omap3_smartreflex_mpu_irqs,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+static struct omap_hwmod omap36xx_sr1_hwmod = {
+ .name = "smartreflex_mpu_iva",
+ .class = &omap36xx_smartreflex_hwmod_class,
+ .main_clk = "sr1_fck",
+ .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,
+ },
+ },
+ .dev_attr = &sr1_dev_attr,
+ .mpu_irqs = omap3_smartreflex_mpu_irqs,
+};
+
+/* SR2 */
+static struct omap_smartreflex_dev_attr sr2_dev_attr = {
+ .sensor_voltdm_name = "core",
+};
+
+static struct omap_hwmod_irq_info omap3_smartreflex_core_irqs[] = {
+ { .irq = 19 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod omap34xx_sr2_hwmod = {
+ .name = "smartreflex_core",
+ .class = &omap34xx_smartreflex_hwmod_class,
+ .main_clk = "sr2_fck",
+ .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,
+ },
+ },
+ .dev_attr = &sr2_dev_attr,
+ .mpu_irqs = omap3_smartreflex_core_irqs,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+static struct omap_hwmod omap36xx_sr2_hwmod = {
+ .name = "smartreflex_core",
+ .class = &omap36xx_smartreflex_hwmod_class,
+ .main_clk = "sr2_fck",
+ .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,
+ },
+ },
+ .dev_attr = &sr2_dev_attr,
+ .mpu_irqs = omap3_smartreflex_core_irqs,
+};
+
+/*
+ * '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_mbox_dev_info omap3xxx_mailbox_info[] = {
+ { .name = "dsp", .tx_id = 0, .rx_id = 1 },
+};
+
+static struct omap_mbox_pdata omap3xxx_mailbox_attrs = {
+ .num_users = 2,
+ .num_fifos = 2,
+ .info_cnt = ARRAY_SIZE(omap3xxx_mailbox_info),
+ .info = omap3xxx_mailbox_info,
+};
+
+static struct omap_hwmod_irq_info omap3xxx_mailbox_irqs[] = {
+ { .irq = 26 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod omap3xxx_mailbox_hwmod = {
+ .name = "mailbox",
+ .class = &omap3xxx_mailbox_hwmod_class,
+ .mpu_irqs = 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,
+ },
+ },
+ .dev_attr = &omap3xxx_mailbox_attrs,
+};
+
+/*
+ * '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 omap2_mcspi_dev_attr omap_mcspi1_dev_attr = {
+ .num_chipselect = 4,
+};
+
+static struct omap_hwmod omap34xx_mcspi1 = {
+ .name = "mcspi1",
+ .mpu_irqs = omap2_mcspi1_mpu_irqs,
+ .sdma_reqs = omap2_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,
+ },
+ },
+ .class = &omap34xx_mcspi_class,
+ .dev_attr = &omap_mcspi1_dev_attr,
+};
+
+/* mcspi2 */
+static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = {
+ .num_chipselect = 2,
+};
+
+static struct omap_hwmod omap34xx_mcspi2 = {
+ .name = "mcspi2",
+ .mpu_irqs = omap2_mcspi2_mpu_irqs,
+ .sdma_reqs = omap2_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,
+ },
+ },
+ .class = &omap34xx_mcspi_class,
+ .dev_attr = &omap_mcspi2_dev_attr,
+};
+
+/* mcspi3 */
+static struct omap_hwmod_irq_info omap34xx_mcspi3_mpu_irqs[] = {
+ { .name = "irq", .irq = 91 + OMAP_INTC_START, }, /* 91 */
+ { .irq = -1 },
+};
+
+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 },
+ { .dma_req = -1 }
+};
+
+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,
+ .sdma_reqs = 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,
+ },
+ },
+ .class = &omap34xx_mcspi_class,
+ .dev_attr = &omap_mcspi3_dev_attr,
+};
+
+/* mcspi4 */
+static struct omap_hwmod_irq_info omap34xx_mcspi4_mpu_irqs[] = {
+ { .name = "irq", .irq = 48 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+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 */
+ { .dma_req = -1 }
+};
+
+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,
+ .sdma_reqs = 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,
+ },
+ },
+ .class = &omap34xx_mcspi_class,
+ .dev_attr = &omap_mcspi4_dev_attr,
+};
+
+/* 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 + OMAP_INTC_START, },
+ { .name = "dma", .irq = 93 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod omap3xxx_usbhsotg_hwmod = {
+ .name = "usb_otg_hs",
+ .mpu_irqs = 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
+ },
+ },
+ .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.
+ *
+ * Enabling the device in any other MIDLEMODE setting but force-idle
+ * causes core_pwrdm not enter idle states at least on OMAP3630.
+ * Note that musb has OTG_FORCESTDBY register that controls MSTANDBY
+ * signal when MIDLEMODE is set to force-idle.
+ */
+ .flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE |
+ HWMOD_FORCE_MSTANDBY | HWMOD_RECONFIG_IO_CHAIN,
+};
+
+/* usb_otg_hs */
+static struct omap_hwmod_irq_info am35xx_usbhsotg_mpu_irqs[] = {
+ { .name = "mc", .irq = 71 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod_class am35xx_usbotg_class = {
+ .name = "am35xx_usbotg",
+};
+
+static struct omap_hwmod am35xx_usbhsotg_hwmod = {
+ .name = "am35x_otg_hs",
+ .mpu_irqs = am35xx_usbhsotg_mpu_irqs,
+ .main_clk = "hsotgusb_fck",
+ .class = &am35xx_usbotg_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* 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 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod_dma_info omap34xx_mmc1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 61, },
+ { .name = "rx", .dma_req = 62, },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod_opt_clk omap34xx_mmc1_opt_clks[] = {
+ { .role = "dbck", .clk = "omap_32k_fck", },
+};
+
+static struct omap_hsmmc_dev_attr mmc1_dev_attr = {
+ .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
+};
+
+/* See 35xx errata 2.1.1.128 in SPRZ278F */
+static struct omap_hsmmc_dev_attr mmc1_pre_es3_dev_attr = {
+ .flags = (OMAP_HSMMC_SUPPORTS_DUAL_VOLT |
+ OMAP_HSMMC_BROKEN_MULTIBLOCK_READ),
+};
+
+static struct omap_hwmod omap3xxx_pre_es3_mmc1_hwmod = {
+ .name = "mmc1",
+ .mpu_irqs = omap34xx_mmc1_mpu_irqs,
+ .sdma_reqs = 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_pre_es3_dev_attr,
+ .class = &omap34xx_mmc_class,
+};
+
+static struct omap_hwmod omap3xxx_es3plus_mmc1_hwmod = {
+ .name = "mmc1",
+ .mpu_irqs = omap34xx_mmc1_mpu_irqs,
+ .sdma_reqs = 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,
+ .class = &omap34xx_mmc_class,
+};
+
+/* MMC/SD/SDIO2 */
+
+static struct omap_hwmod_irq_info omap34xx_mmc2_mpu_irqs[] = {
+ { .irq = 86 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod_dma_info omap34xx_mmc2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 47, },
+ { .name = "rx", .dma_req = 48, },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod_opt_clk omap34xx_mmc2_opt_clks[] = {
+ { .role = "dbck", .clk = "omap_32k_fck", },
+};
+
+/* See 35xx errata 2.1.1.128 in SPRZ278F */
+static struct omap_hsmmc_dev_attr mmc2_pre_es3_dev_attr = {
+ .flags = OMAP_HSMMC_BROKEN_MULTIBLOCK_READ,
+};
+
+static struct omap_hwmod omap3xxx_pre_es3_mmc2_hwmod = {
+ .name = "mmc2",
+ .mpu_irqs = omap34xx_mmc2_mpu_irqs,
+ .sdma_reqs = 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,
+ },
+ },
+ .dev_attr = &mmc2_pre_es3_dev_attr,
+ .class = &omap34xx_mmc_class,
+};
+
+static struct omap_hwmod omap3xxx_es3plus_mmc2_hwmod = {
+ .name = "mmc2",
+ .mpu_irqs = omap34xx_mmc2_mpu_irqs,
+ .sdma_reqs = 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,
+ },
+ },
+ .class = &omap34xx_mmc_class,
+};
+
+/* MMC/SD/SDIO3 */
+
+static struct omap_hwmod_irq_info omap34xx_mmc3_mpu_irqs[] = {
+ { .irq = 94 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod_dma_info omap34xx_mmc3_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 77, },
+ { .name = "rx", .dma_req = 78, },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod_opt_clk omap34xx_mmc3_opt_clks[] = {
+ { .role = "dbck", .clk = "omap_32k_fck", },
+};
+
+static struct omap_hwmod omap3xxx_mmc3_hwmod = {
+ .name = "mmc3",
+ .mpu_irqs = omap34xx_mmc3_mpu_irqs,
+ .sdma_reqs = 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,
+ },
+ },
+ .class = &omap34xx_mmc_class,
+};
+
+/*
+ * 'usb_host_hs' class
+ * high-speed multi-port usb host controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_usb_host_hs_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_MIDLEMODE | 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 |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_usb_host_hs_hwmod_class = {
+ .name = "usb_host_hs",
+ .sysc = &omap3xxx_usb_host_hs_sysc,
+};
+
+static struct omap_hwmod_irq_info omap3xxx_usb_host_hs_irqs[] = {
+ { .name = "ohci-irq", .irq = 76 + OMAP_INTC_START, },
+ { .name = "ehci-irq", .irq = 77 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = {
+ .name = "usb_host_hs",
+ .class = &omap3xxx_usb_host_hs_hwmod_class,
+ .clkdm_name = "usbhost_clkdm",
+ .mpu_irqs = omap3xxx_usb_host_hs_irqs,
+ .main_clk = "usbhost_48m_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = OMAP3430ES2_USBHOST_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430ES2_EN_USBHOST1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430ES2_ST_USBHOST_IDLE_SHIFT,
+ .idlest_stdby_bit = OMAP3430ES2_ST_USBHOST_STDBY_SHIFT,
+ },
+ },
+
+ /*
+ * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock
+ * id: i660
+ *
+ * Description:
+ * In the following configuration :
+ * - USBHOST module is set to smart-idle mode
+ * - PRCM asserts idle_req to the USBHOST module ( This typically
+ * happens when the system is going to a low power mode : all ports
+ * have been suspended, the master part of the USBHOST module has
+ * entered the standby state, and SW has cut the functional clocks)
+ * - an USBHOST interrupt occurs before the module is able to answer
+ * idle_ack, typically a remote wakeup IRQ.
+ * Then the USB HOST module will enter a deadlock situation where it
+ * is no more accessible nor functional.
+ *
+ * Workaround:
+ * Don't use smart idle; use only force idle, hence HWMOD_SWSUP_SIDLE
+ */
+
+ /*
+ * Errata: USB host EHCI may stall when entering smart-standby mode
+ * Id: i571
+ *
+ * Description:
+ * When the USBHOST module is set to smart-standby mode, and when it is
+ * ready to enter the standby state (i.e. all ports are suspended and
+ * all attached devices are in suspend mode), then it can wrongly assert
+ * the Mstandby signal too early while there are still some residual OCP
+ * transactions ongoing. If this condition occurs, the internal state
+ * machine may go to an undefined state and the USB link may be stuck
+ * upon the next resume.
+ *
+ * Workaround:
+ * Don't use smart standby; use only force standby,
+ * hence HWMOD_SWSUP_MSTANDBY
+ */
+
+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+};
+
+/*
+ * 'usb_tll_hs' class
+ * usb_tll_hs module is the adapter on the usb_host_hs ports
+ */
+static struct omap_hwmod_class_sysconfig omap3xxx_usb_tll_hs_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),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_usb_tll_hs_hwmod_class = {
+ .name = "usb_tll_hs",
+ .sysc = &omap3xxx_usb_tll_hs_sysc,
+};
+
+static struct omap_hwmod_irq_info omap3xxx_usb_tll_hs_irqs[] = {
+ { .name = "tll-irq", .irq = 78 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod omap3xxx_usb_tll_hs_hwmod = {
+ .name = "usb_tll_hs",
+ .class = &omap3xxx_usb_tll_hs_hwmod_class,
+ .clkdm_name = "core_l4_clkdm",
+ .mpu_irqs = omap3xxx_usb_tll_hs_irqs,
+ .main_clk = "usbtll_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 3,
+ .module_bit = OMAP3430ES2_EN_USBTLL_SHIFT,
+ .idlest_reg_id = 3,
+ .idlest_idle_bit = OMAP3430ES2_ST_USBTLL_SHIFT,
+ },
+ },
+};
+
+static struct omap_hwmod omap3xxx_hdq1w_hwmod = {
+ .name = "hdq1w",
+ .mpu_irqs = omap2_hdq1w_mpu_irqs,
+ .main_clk = "hdq_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_HDQ_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_HDQ_SHIFT,
+ },
+ },
+ .class = &omap2_hdq1w_class,
+};
+
+/* SAD2D */
+static struct omap_hwmod_rst_info omap3xxx_sad2d_resets[] = {
+ { .name = "rst_modem_pwron_sw", .rst_shift = 0 },
+ { .name = "rst_modem_sw", .rst_shift = 1 },
+};
+
+static struct omap_hwmod_class omap3xxx_sad2d_class = {
+ .name = "sad2d",
+};
+
+static struct omap_hwmod omap3xxx_sad2d_hwmod = {
+ .name = "sad2d",
+ .rst_lines = omap3xxx_sad2d_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap3xxx_sad2d_resets),
+ .main_clk = "sad2d_ick",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_SAD2D_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_SAD2D_SHIFT,
+ },
+ },
+ .class = &omap3xxx_sad2d_class,
+};
+
+/*
+ * '32K sync counter' class
+ * 32-bit ordinary counter, clocked by the falling edge of the 32 khz clock
+ */
+static struct omap_hwmod_class_sysconfig omap3xxx_counter_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0004,
+ .sysc_flags = SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_counter_hwmod_class = {
+ .name = "counter",
+ .sysc = &omap3xxx_counter_sysc,
+};
+
+static struct omap_hwmod omap3xxx_counter_32k_hwmod = {
+ .name = "counter_32k",
+ .class = &omap3xxx_counter_hwmod_class,
+ .clkdm_name = "wkup_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE,
+ .main_clk = "wkup_32k_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = WKUP_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_ST_32KSYNC_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_32KSYNC_SHIFT,
+ },
+ },
+};
+
+/*
+ * 'gpmc' class
+ * general purpose memory controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_gpmc_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 omap3xxx_gpmc_hwmod_class = {
+ .name = "gpmc",
+ .sysc = &omap3xxx_gpmc_sysc,
+};
+
+static struct omap_hwmod_irq_info omap3xxx_gpmc_irqs[] = {
+ { .irq = 20 + OMAP_INTC_START, },
+ { .irq = -1 }
+};
+
+static struct omap_hwmod omap3xxx_gpmc_hwmod = {
+ .name = "gpmc",
+ .class = &omap3xxx_gpmc_hwmod_class,
+ .clkdm_name = "core_l3_clkdm",
+ .mpu_irqs = omap3xxx_gpmc_irqs,
+ .main_clk = "gpmc_fck",
+ /*
+ * XXX HWMOD_INIT_NO_RESET should not be needed for this IP
+ * block. It is not being added due to any known bugs with
+ * resetting the GPMC IP block, but rather because any timings
+ * set by the bootloader are not being correctly programmed by
+ * the kernel from the board file or DT data.
+ * HWMOD_INIT_NO_RESET should be removed ASAP.
+ */
+ .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
+ HWMOD_NO_IDLEST),
+};
+
+/*
+ * interfaces
+ */
+
+/* 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,
+};
+
+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,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap3xxx_l4_emu_addrs[] = {
+ {
+ .pa_start = 0x54000000,
+ .pa_end = 0x547fffff,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+/* l3 -> debugss */
+static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_debugss = {
+ .master = &omap3xxx_l3_main_hwmod,
+ .slave = &omap3xxx_debugss_hwmod,
+ .addr = omap3xxx_l4_emu_addrs,
+ .user = OCP_USER_MPU,
+};
+
+/* DSS -> l3 */
+static struct omap_hwmod_ocp_if omap3430es1_dss__l3 = {
+ .master = &omap3430es1_dss_core_hwmod,
+ .slave = &omap3xxx_l3_main_hwmod,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+};
+
+/* 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 = "hsotgusb_ick",
+ .user = OCP_USER_MPU,
+};
+
+/* l3_core -> sad2d interface */
+static struct omap_hwmod_ocp_if omap3xxx_sad2d__l3 = {
+ .master = &omap3xxx_sad2d_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_ocp_if omap3xxx_l4_core__pre_es3_mmc1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_pre_es3_mmc1_hwmod,
+ .clk = "mmchs1_ick",
+ .addr = omap2430_mmc1_addr_space,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+ .flags = OMAP_FIREWALL_L4
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__es3plus_mmc1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_es3plus_mmc1_hwmod,
+ .clk = "mmchs1_ick",
+ .addr = omap2430_mmc1_addr_space,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+ .flags = OMAP_FIREWALL_L4
+};
+
+/* L4 CORE -> MMC2 interface */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__pre_es3_mmc2 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_pre_es3_mmc2_hwmod,
+ .clk = "mmchs2_ick",
+ .addr = omap2430_mmc2_addr_space,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+ .flags = OMAP_FIREWALL_L4
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__es3plus_mmc2 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_es3plus_mmc2_hwmod,
+ .clk = "mmchs2_ick",
+ .addr = omap2430_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,
+ .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,
+ .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,
+ .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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> UART4 interface */
+static struct omap_hwmod_addr_space omap36xx_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 omap36xx_l4_per__uart4 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap36xx_uart4_hwmod,
+ .clk = "uart4_ick",
+ .addr = omap36xx_uart4_addr_space,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* AM35xx: L4 CORE -> UART4 interface */
+static struct omap_hwmod_addr_space am35xx_uart4_addr_space[] = {
+ {
+ .pa_start = OMAP3_UART4_AM35XX_BASE,
+ .pa_end = OMAP3_UART4_AM35XX_BASE + SZ_1K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+ { }
+};
+
+static struct omap_hwmod_ocp_if am35xx_l4_core__uart4 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &am35xx_uart4_hwmod,
+ .clk = "uart4_ick",
+ .addr = am35xx_uart4_addr_space,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> I2C1 interface */
+static struct omap_hwmod_ocp_if omap3_l4_core__i2c1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_i2c1_hwmod,
+ .clk = "i2c1_ick",
+ .addr = omap2_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_ocp_if omap3_l4_core__i2c2 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_i2c2_hwmod,
+ .clk = "i2c2_ick",
+ .addr = omap2_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 + SZ_128 - 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,
+ .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 omap34xx_l4_core__sr1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap34xx_sr1_hwmod,
+ .clk = "sr_l4_ick",
+ .addr = omap3_sr1_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if omap36xx_l4_core__sr1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap36xx_sr1_hwmod,
+ .clk = "sr_l4_ick",
+ .addr = 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 omap34xx_l4_core__sr2 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap34xx_sr2_hwmod,
+ .clk = "sr_l4_ick",
+ .addr = omap3_sr2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if omap36xx_l4_core__sr2 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap36xx_sr2_hwmod,
+ .clk = "sr_l4_ick",
+ .addr = omap3_sr2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+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,
+ .user = OCP_USER_MPU,
+};
+
+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 = "hsotgusb_ick",
+ .addr = am35xx_usbhsotg_addrs,
+ .user = OCP_USER_MPU,
+};
+
+/* L4_WKUP -> L4_SEC interface */
+static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__l4_sec = {
+ .master = &omap3xxx_l4_wkup_hwmod,
+ .slave = &omap3xxx_l4_sec_hwmod,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* IVA2 <- L3 interface */
+static struct omap_hwmod_ocp_if omap3xxx_l3__iva = {
+ .master = &omap3xxx_l3_main_hwmod,
+ .slave = &omap3xxx_iva_hwmod,
+ .clk = "core_l3_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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 = omap2_timer10_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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 = omap2_timer11_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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_sec__timer12 = {
+ .master = &omap3xxx_l4_sec_hwmod,
+ .slave = &omap3xxx_timer12_hwmod,
+ .clk = "gpt12_ick",
+ .addr = omap3xxx_timer12_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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 = omap2_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 = omap2_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,
+};
+
+/* 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 = omap2_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,
+};
+
+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,
+ .clk = "dss_ick",
+ .addr = 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,
+};
+
+/* 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 = omap2_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,
+};
+
+/* 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_ick",
+ .addr = omap2_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,
+};
+
+/* 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,
+ .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,
+ .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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/*
+ * 'mmu' class
+ * The memory management unit performs virtual to physical address translation
+ * for its requestors.
+ */
+
+static struct omap_hwmod_class_sysconfig mmu_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_mmu_hwmod_class = {
+ .name = "mmu",
+ .sysc = &mmu_sysc,
+};
+
+/* mmu isp */
+
+static struct omap_mmu_dev_attr mmu_isp_dev_attr = {
+ .nr_tlb_entries = 8,
+};
+
+static struct omap_hwmod omap3xxx_mmu_isp_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_mmu_isp_irqs[] = {
+ { .irq = 24 + OMAP_INTC_START, },
+ { .irq = -1 }
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mmu_isp_addrs[] = {
+ {
+ .pa_start = 0x480bd400,
+ .pa_end = 0x480bd47f,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+/* l4_core -> mmu isp */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__mmu_isp = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_mmu_isp_hwmod,
+ .addr = omap3xxx_mmu_isp_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod omap3xxx_mmu_isp_hwmod = {
+ .name = "mmu_isp",
+ .class = &omap3xxx_mmu_hwmod_class,
+ .mpu_irqs = omap3xxx_mmu_isp_irqs,
+ .main_clk = "cam_ick",
+ .dev_attr = &mmu_isp_dev_attr,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* mmu iva */
+
+static struct omap_mmu_dev_attr mmu_iva_dev_attr = {
+ .nr_tlb_entries = 32,
+};
+
+static struct omap_hwmod omap3xxx_mmu_iva_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_mmu_iva_irqs[] = {
+ { .irq = 28 + OMAP_INTC_START, },
+ { .irq = -1 }
+};
+
+static struct omap_hwmod_rst_info omap3xxx_mmu_iva_resets[] = {
+ { .name = "mmu", .rst_shift = 1, .st_shift = 9 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mmu_iva_addrs[] = {
+ {
+ .pa_start = 0x5d000000,
+ .pa_end = 0x5d00007f,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+/* l3_main -> iva mmu */
+static struct omap_hwmod_ocp_if omap3xxx_l3_main__mmu_iva = {
+ .master = &omap3xxx_l3_main_hwmod,
+ .slave = &omap3xxx_mmu_iva_hwmod,
+ .addr = omap3xxx_mmu_iva_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod omap3xxx_mmu_iva_hwmod = {
+ .name = "mmu_iva",
+ .class = &omap3xxx_mmu_hwmod_class,
+ .mpu_irqs = omap3xxx_mmu_iva_irqs,
+ .clkdm_name = "iva2_clkdm",
+ .rst_lines = omap3xxx_mmu_iva_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap3xxx_mmu_iva_resets),
+ .main_clk = "iva2_ck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = OMAP3430_IVA2_MOD,
+ .module_bit = OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_IVA2_SHIFT,
+ },
+ },
+ .dev_attr = &mmu_iva_dev_attr,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* 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,
+ .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,
+ .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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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,
+};
+
+static struct omap_hwmod_addr_space omap3xxx_dma_system_addrs[] = {
+ {
+ .pa_start = 0x48056000,
+ .pa_end = 0x48056fff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* 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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU,
+};
+
+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,
+ .user = OCP_USER_MPU,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 core -> mcspi1 interface */
+static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap34xx_mcspi1,
+ .clk = "mcspi1_ick",
+ .addr = omap2_mcspi1_addr_space,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 core -> mcspi2 interface */
+static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi2 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap34xx_mcspi2,
+ .clk = "mcspi2_ick",
+ .addr = omap2_mcspi2_addr_space,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 core -> mcspi3 interface */
+static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi3 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap34xx_mcspi3,
+ .clk = "mcspi3_ick",
+ .addr = omap2430_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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_usb_host_hs__l3_main_2 = {
+ .master = &omap3xxx_usb_host_hs_hwmod,
+ .slave = &omap3xxx_l3_main_hwmod,
+ .clk = "core_l3_ick",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap3xxx_usb_host_hs_addrs[] = {
+ {
+ .name = "uhh",
+ .pa_start = 0x48064000,
+ .pa_end = 0x480643ff,
+ .flags = ADDR_TYPE_RT
+ },
+ {
+ .name = "ohci",
+ .pa_start = 0x48064400,
+ .pa_end = 0x480647ff,
+ },
+ {
+ .name = "ehci",
+ .pa_start = 0x48064800,
+ .pa_end = 0x48064cff,
+ },
+ {}
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__usb_host_hs = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_usb_host_hs_hwmod,
+ .clk = "usbhost_ick",
+ .addr = omap3xxx_usb_host_hs_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap3xxx_usb_tll_hs_addrs[] = {
+ {
+ .name = "tll",
+ .pa_start = 0x48062000,
+ .pa_end = 0x48062fff,
+ .flags = ADDR_TYPE_RT
+ },
+ {}
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__usb_tll_hs = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_usb_tll_hs_hwmod,
+ .clk = "usbtll_ick",
+ .addr = omap3xxx_usb_tll_hs_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> hdq1w interface */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__hdq1w = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_hdq1w_hwmod,
+ .clk = "hdq_ick",
+ .addr = omap2_hdq1w_addr_space,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+ .flags = OMAP_FIREWALL_L4 | OCPIF_SWSUP_IDLE,
+};
+
+/* l4_wkup -> 32ksync_counter */
+static struct omap_hwmod_addr_space omap3xxx_counter_32k_addrs[] = {
+ {
+ .pa_start = 0x48320000,
+ .pa_end = 0x4832001f,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+static struct omap_hwmod_addr_space omap3xxx_gpmc_addrs[] = {
+ {
+ .pa_start = 0x6e000000,
+ .pa_end = 0x6e000fff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__counter_32k = {
+ .master = &omap3xxx_l4_wkup_hwmod,
+ .slave = &omap3xxx_counter_32k_hwmod,
+ .clk = "omap_32ksync_ick",
+ .addr = omap3xxx_counter_32k_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* am35xx has Davinci MDIO & EMAC */
+static struct omap_hwmod_class am35xx_mdio_class = {
+ .name = "davinci_mdio",
+};
+
+static struct omap_hwmod am35xx_mdio_hwmod = {
+ .name = "davinci_mdio",
+ .class = &am35xx_mdio_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * XXX Should be connected to an IPSS hwmod, not the L3 directly;
+ * but this will probably require some additional hwmod core support,
+ * so is left as a future to-do item.
+ */
+static struct omap_hwmod_ocp_if am35xx_mdio__l3 = {
+ .master = &am35xx_mdio_hwmod,
+ .slave = &omap3xxx_l3_main_hwmod,
+ .clk = "emac_fck",
+ .user = OCP_USER_MPU,
+};
+
+/* l4_core -> davinci mdio */
+/*
+ * XXX Should be connected to an IPSS hwmod, not the L4_CORE directly;
+ * but this will probably require some additional hwmod core support,
+ * so is left as a future to-do item.
+ */
+static struct omap_hwmod_ocp_if am35xx_l4_core__mdio = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &am35xx_mdio_hwmod,
+ .clk = "emac_fck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class am35xx_emac_class = {
+ .name = "davinci_emac",
+};
+
+static struct omap_hwmod am35xx_emac_hwmod = {
+ .name = "davinci_emac",
+ .class = &am35xx_emac_class,
+ /*
+ * According to Mark Greer, the MPU will not return from WFI
+ * when the EMAC signals an interrupt.
+ * http://www.spinics.net/lists/arm-kernel/msg174734.html
+ */
+ .flags = (HWMOD_NO_IDLEST | HWMOD_BLOCK_WFI),
+};
+
+/* l3_core -> davinci emac interface */
+/*
+ * XXX Should be connected to an IPSS hwmod, not the L3 directly;
+ * but this will probably require some additional hwmod core support,
+ * so is left as a future to-do item.
+ */
+static struct omap_hwmod_ocp_if am35xx_emac__l3 = {
+ .master = &am35xx_emac_hwmod,
+ .slave = &omap3xxx_l3_main_hwmod,
+ .clk = "emac_ick",
+ .user = OCP_USER_MPU,
+};
+
+/* l4_core -> davinci emac */
+/*
+ * XXX Should be connected to an IPSS hwmod, not the L4_CORE directly;
+ * but this will probably require some additional hwmod core support,
+ * so is left as a future to-do item.
+ */
+static struct omap_hwmod_ocp_if am35xx_l4_core__emac = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &am35xx_emac_hwmod,
+ .clk = "emac_ick",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l3_main__gpmc = {
+ .master = &omap3xxx_l3_main_hwmod,
+ .slave = &omap3xxx_gpmc_hwmod,
+ .clk = "core_l3_ick",
+ .addr = omap3xxx_gpmc_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> SHAM2 (SHA1/MD5) (similar to omap24xx) */
+static struct omap_hwmod_sysc_fields omap3_sham_sysc_fields = {
+ .sidle_shift = 4,
+ .srst_shift = 1,
+ .autoidle_shift = 0,
+};
+
+static struct omap_hwmod_class_sysconfig omap3_sham_sysc = {
+ .rev_offs = 0x5c,
+ .sysc_offs = 0x60,
+ .syss_offs = 0x64,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
+ .sysc_fields = &omap3_sham_sysc_fields,
+};
+
+static struct omap_hwmod_class omap3xxx_sham_class = {
+ .name = "sham",
+ .sysc = &omap3_sham_sysc,
+};
+
+static struct omap_hwmod_irq_info omap3_sham_mpu_irqs[] = {
+ { .irq = 49 + OMAP_INTC_START, },
+ { .irq = -1 }
+};
+
+static struct omap_hwmod_dma_info omap3_sham_sdma_reqs[] = {
+ { .name = "rx", .dma_req = 69, },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod omap3xxx_sham_hwmod = {
+ .name = "sham",
+ .mpu_irqs = omap3_sham_mpu_irqs,
+ .sdma_reqs = omap3_sham_sdma_reqs,
+ .main_clk = "sha12_ick",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_SHA12_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_SHA12_SHIFT,
+ },
+ },
+ .class = &omap3xxx_sham_class,
+};
+
+static struct omap_hwmod_addr_space omap3xxx_sham_addrs[] = {
+ {
+ .pa_start = 0x480c3000,
+ .pa_end = 0x480c3000 + 0x64 - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__sham = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_sham_hwmod,
+ .clk = "sha12_ick",
+ .addr = omap3xxx_sham_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> AES */
+static struct omap_hwmod_sysc_fields omap3xxx_aes_sysc_fields = {
+ .sidle_shift = 6,
+ .srst_shift = 1,
+ .autoidle_shift = 0,
+};
+
+static struct omap_hwmod_class_sysconfig omap3_aes_sysc = {
+ .rev_offs = 0x44,
+ .sysc_offs = 0x48,
+ .syss_offs = 0x4c,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap3xxx_aes_sysc_fields,
+};
+
+static struct omap_hwmod_class omap3xxx_aes_class = {
+ .name = "aes",
+ .sysc = &omap3_aes_sysc,
+};
+
+static struct omap_hwmod_dma_info omap3_aes_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 65, },
+ { .name = "rx", .dma_req = 66, },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod omap3xxx_aes_hwmod = {
+ .name = "aes",
+ .sdma_reqs = omap3_aes_sdma_reqs,
+ .main_clk = "aes2_ick",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_AES2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_AES2_SHIFT,
+ },
+ },
+ .class = &omap3xxx_aes_class,
+};
+
+static struct omap_hwmod_addr_space omap3xxx_aes_addrs[] = {
+ {
+ .pa_start = 0x480c5000,
+ .pa_end = 0x480c5000 + 0x50 - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__aes = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_aes_hwmod,
+ .clk = "aes2_ick",
+ .addr = omap3xxx_aes_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/*
+ * 'ssi' class
+ * synchronous serial interface (multichannel and full-duplex serial if)
+ */
+
+static struct omap_hwmod_class_sysconfig omap34xx_ssi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap34xx_ssi_hwmod_class = {
+ .name = "ssi",
+ .sysc = &omap34xx_ssi_sysc,
+};
+
+static struct omap_hwmod omap34xx_ssi_hwmod = {
+ .name = "ssi",
+ .class = &omap34xx_ssi_hwmod_class,
+ .clkdm_name = "core_l4_clkdm",
+ .main_clk = "ssi_ssr_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_SSI_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT,
+ },
+ },
+};
+
+/* L4 CORE -> SSI */
+static struct omap_hwmod_ocp_if omap34xx_l4_core__ssi = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap34xx_ssi_hwmod,
+ .clk = "ssi_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
+ &omap3xxx_l3_main__l4_core,
+ &omap3xxx_l3_main__l4_per,
+ &omap3xxx_mpu__l3_main,
+ &omap3xxx_l3_main__l4_debugss,
+ &omap3xxx_l4_core__l4_wkup,
+ &omap3xxx_l4_core__mmc3,
+ &omap3_l4_core__uart1,
+ &omap3_l4_core__uart2,
+ &omap3_l4_per__uart3,
+ &omap3_l4_core__i2c1,
+ &omap3_l4_core__i2c2,
+ &omap3_l4_core__i2c3,
+ &omap3xxx_l4_wkup__l4_sec,
+ &omap3xxx_l4_wkup__timer1,
+ &omap3xxx_l4_per__timer2,
+ &omap3xxx_l4_per__timer3,
+ &omap3xxx_l4_per__timer4,
+ &omap3xxx_l4_per__timer5,
+ &omap3xxx_l4_per__timer6,
+ &omap3xxx_l4_per__timer7,
+ &omap3xxx_l4_per__timer8,
+ &omap3xxx_l4_per__timer9,
+ &omap3xxx_l4_core__timer10,
+ &omap3xxx_l4_core__timer11,
+ &omap3xxx_l4_wkup__wd_timer2,
+ &omap3xxx_l4_wkup__gpio1,
+ &omap3xxx_l4_per__gpio2,
+ &omap3xxx_l4_per__gpio3,
+ &omap3xxx_l4_per__gpio4,
+ &omap3xxx_l4_per__gpio5,
+ &omap3xxx_l4_per__gpio6,
+ &omap3xxx_dma_system__l3,
+ &omap3xxx_l4_core__dma_system,
+ &omap3xxx_l4_core__mcbsp1,
+ &omap3xxx_l4_per__mcbsp2,
+ &omap3xxx_l4_per__mcbsp3,
+ &omap3xxx_l4_per__mcbsp4,
+ &omap3xxx_l4_core__mcbsp5,
+ &omap3xxx_l4_per__mcbsp2_sidetone,
+ &omap3xxx_l4_per__mcbsp3_sidetone,
+ &omap34xx_l4_core__mcspi1,
+ &omap34xx_l4_core__mcspi2,
+ &omap34xx_l4_core__mcspi3,
+ &omap34xx_l4_core__mcspi4,
+ &omap3xxx_l4_wkup__counter_32k,
+ &omap3xxx_l3_main__gpmc,
+ NULL,
+};
+
+/* GP-only hwmod links */
+static struct omap_hwmod_ocp_if *omap34xx_gp_hwmod_ocp_ifs[] __initdata = {
+ &omap3xxx_l4_sec__timer12,
+ &omap3xxx_l4_core__sham,
+ &omap3xxx_l4_core__aes,
+ NULL
+};
+
+static struct omap_hwmod_ocp_if *omap36xx_gp_hwmod_ocp_ifs[] __initdata = {
+ &omap3xxx_l4_sec__timer12,
+ &omap3xxx_l4_core__sham,
+ &omap3xxx_l4_core__aes,
+ NULL
+};
+
+static struct omap_hwmod_ocp_if *am35xx_gp_hwmod_ocp_ifs[] __initdata = {
+ &omap3xxx_l4_sec__timer12,
+ /*
+ * Apparently the SHA/MD5 and AES accelerator IP blocks are
+ * only present on some AM35xx chips, and no one knows which
+ * ones. See
+ * http://www.spinics.net/lists/arm-kernel/msg215466.html So
+ * if you need these IP blocks on an AM35xx, try uncommenting
+ * the following lines.
+ */
+ /* &omap3xxx_l4_core__sham, */
+ /* &omap3xxx_l4_core__aes, */
+ NULL
+};
+
+/* 3430ES1-only hwmod links */
+static struct omap_hwmod_ocp_if *omap3430es1_hwmod_ocp_ifs[] __initdata = {
+ &omap3430es1_dss__l3,
+ &omap3430es1_l4_core__dss,
+ NULL
+};
+
+/* 3430ES2+-only hwmod links */
+static struct omap_hwmod_ocp_if *omap3430es2plus_hwmod_ocp_ifs[] __initdata = {
+ &omap3xxx_dss__l3,
+ &omap3xxx_l4_core__dss,
+ &omap3xxx_usbhsotg__l3,
+ &omap3xxx_l4_core__usbhsotg,
+ &omap3xxx_usb_host_hs__l3_main_2,
+ &omap3xxx_l4_core__usb_host_hs,
+ &omap3xxx_l4_core__usb_tll_hs,
+ NULL
+};
+
+/* <= 3430ES3-only hwmod links */
+static struct omap_hwmod_ocp_if *omap3430_pre_es3_hwmod_ocp_ifs[] __initdata = {
+ &omap3xxx_l4_core__pre_es3_mmc1,
+ &omap3xxx_l4_core__pre_es3_mmc2,
+ NULL
+};
+
+/* 3430ES3+-only hwmod links */
+static struct omap_hwmod_ocp_if *omap3430_es3plus_hwmod_ocp_ifs[] __initdata = {
+ &omap3xxx_l4_core__es3plus_mmc1,
+ &omap3xxx_l4_core__es3plus_mmc2,
+ NULL
+};
+
+/* 34xx-only hwmod links (all ES revisions) */
+static struct omap_hwmod_ocp_if *omap34xx_hwmod_ocp_ifs[] __initdata = {
+ &omap3xxx_l3__iva,
+ &omap34xx_l4_core__sr1,
+ &omap34xx_l4_core__sr2,
+ &omap3xxx_l4_core__mailbox,
+ &omap3xxx_l4_core__hdq1w,
+ &omap3xxx_sad2d__l3,
+ &omap3xxx_l4_core__mmu_isp,
+ &omap3xxx_l3_main__mmu_iva,
+ &omap34xx_l4_core__ssi,
+ NULL
+};
+
+/* 36xx-only hwmod links (all ES revisions) */
+static struct omap_hwmod_ocp_if *omap36xx_hwmod_ocp_ifs[] __initdata = {
+ &omap3xxx_l3__iva,
+ &omap36xx_l4_per__uart4,
+ &omap3xxx_dss__l3,
+ &omap3xxx_l4_core__dss,
+ &omap36xx_l4_core__sr1,
+ &omap36xx_l4_core__sr2,
+ &omap3xxx_usbhsotg__l3,
+ &omap3xxx_l4_core__usbhsotg,
+ &omap3xxx_l4_core__mailbox,
+ &omap3xxx_usb_host_hs__l3_main_2,
+ &omap3xxx_l4_core__usb_host_hs,
+ &omap3xxx_l4_core__usb_tll_hs,
+ &omap3xxx_l4_core__es3plus_mmc1,
+ &omap3xxx_l4_core__es3plus_mmc2,
+ &omap3xxx_l4_core__hdq1w,
+ &omap3xxx_sad2d__l3,
+ &omap3xxx_l4_core__mmu_isp,
+ &omap3xxx_l3_main__mmu_iva,
+ NULL
+};
+
+static struct omap_hwmod_ocp_if *am35xx_hwmod_ocp_ifs[] __initdata = {
+ &omap3xxx_dss__l3,
+ &omap3xxx_l4_core__dss,
+ &am35xx_usbhsotg__l3,
+ &am35xx_l4_core__usbhsotg,
+ &am35xx_l4_core__uart4,
+ &omap3xxx_usb_host_hs__l3_main_2,
+ &omap3xxx_l4_core__usb_host_hs,
+ &omap3xxx_l4_core__usb_tll_hs,
+ &omap3xxx_l4_core__es3plus_mmc1,
+ &omap3xxx_l4_core__es3plus_mmc2,
+ &omap3xxx_l4_core__hdq1w,
+ &am35xx_mdio__l3,
+ &am35xx_l4_core__mdio,
+ &am35xx_emac__l3,
+ &am35xx_l4_core__emac,
+ NULL
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_dss_hwmod_ocp_ifs[] __initdata = {
+ &omap3xxx_l4_core__dss_dispc,
+ &omap3xxx_l4_core__dss_dsi1,
+ &omap3xxx_l4_core__dss_rfbi,
+ &omap3xxx_l4_core__dss_venc,
+ NULL
+};
+
+int __init omap3xxx_hwmod_init(void)
+{
+ int r;
+ struct omap_hwmod_ocp_if **h = NULL, **h_gp = NULL;
+ unsigned int rev;
+
+ omap_hwmod_init();
+
+ /* Register hwmod links common to all OMAP3 */
+ r = omap_hwmod_register_links(omap3xxx_hwmod_ocp_ifs);
+ if (r < 0)
+ return r;
+
+ rev = omap_rev();
+
+ /*
+ * Register hwmod links common to individual OMAP3 families, all
+ * silicon revisions (e.g., 34xx, or AM3505/3517, or 36xx)
+ * All possible revisions should be included in this conditional.
+ */
+ if (rev == OMAP3430_REV_ES1_0 || rev == OMAP3430_REV_ES2_0 ||
+ rev == OMAP3430_REV_ES2_1 || rev == OMAP3430_REV_ES3_0 ||
+ rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2) {
+ h = omap34xx_hwmod_ocp_ifs;
+ h_gp = omap34xx_gp_hwmod_ocp_ifs;
+ } else if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) {
+ h = am35xx_hwmod_ocp_ifs;
+ h_gp = am35xx_gp_hwmod_ocp_ifs;
+ } else if (rev == OMAP3630_REV_ES1_0 || rev == OMAP3630_REV_ES1_1 ||
+ rev == OMAP3630_REV_ES1_2) {
+ h = omap36xx_hwmod_ocp_ifs;
+ h_gp = omap36xx_gp_hwmod_ocp_ifs;
+ } else {
+ WARN(1, "OMAP3 hwmod family init: unknown chip type\n");
+ return -EINVAL;
+ }
+
+ r = omap_hwmod_register_links(h);
+ if (r < 0)
+ return r;
+
+ /* Register GP-only hwmod links. */
+ if (h_gp && omap_type() == OMAP2_DEVICE_TYPE_GP) {
+ r = omap_hwmod_register_links(h_gp);
+ if (r < 0)
+ return r;
+ }
+
+
+ /*
+ * Register hwmod links specific to certain ES levels of a
+ * particular family of silicon (e.g., 34xx ES1.0)
+ */
+ h = NULL;
+ if (rev == OMAP3430_REV_ES1_0) {
+ h = omap3430es1_hwmod_ocp_ifs;
+ } else if (rev == OMAP3430_REV_ES2_0 || rev == OMAP3430_REV_ES2_1 ||
+ rev == OMAP3430_REV_ES3_0 || rev == OMAP3430_REV_ES3_1 ||
+ rev == OMAP3430_REV_ES3_1_2) {
+ h = omap3430es2plus_hwmod_ocp_ifs;
+ }
+
+ if (h) {
+ r = omap_hwmod_register_links(h);
+ if (r < 0)
+ return r;
+ }
+
+ h = NULL;
+ if (rev == OMAP3430_REV_ES1_0 || rev == OMAP3430_REV_ES2_0 ||
+ rev == OMAP3430_REV_ES2_1) {
+ h = omap3430_pre_es3_hwmod_ocp_ifs;
+ } else if (rev == OMAP3430_REV_ES3_0 || rev == OMAP3430_REV_ES3_1 ||
+ rev == OMAP3430_REV_ES3_1_2) {
+ h = omap3430_es3plus_hwmod_ocp_ifs;
+ }
+
+ if (h)
+ r = omap_hwmod_register_links(h);
+ if (r < 0)
+ return r;
+
+ /*
+ * DSS code presumes that dss_core hwmod is handled first,
+ * _before_ any other DSS related hwmods so register common
+ * DSS hwmod links last to ensure that dss_core is already
+ * registered. Otherwise some change things may happen, for
+ * ex. if dispc is handled before dss_core and DSS is enabled
+ * in bootloader DISPC will be reset with outputs enabled
+ * which sometimes leads to unrecoverable L3 error. XXX The
+ * long-term fix to this is to ensure hwmods are set up in
+ * dependency order in the hwmod core code.
+ */
+ r = omap_hwmod_register_links(omap3xxx_dss_hwmod_ocp_ifs);
+
+ return r;
+}
diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
new file mode 100644
index 000000000..17e8004fc
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
@@ -0,0 +1,1006 @@
+/*
+ * Copyright (C) 2013 Texas Instruments Incorporated
+ *
+ * Hwmod present only in AM43x and those that differ other than register
+ * offsets as compared to AM335x.
+ *
+ * This program is free software; 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/platform_data/gpio-omap.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+#include "omap_hwmod.h"
+#include "omap_hwmod_33xx_43xx_common_data.h"
+#include "prcm43xx.h"
+#include "omap_hwmod_common_data.h"
+#include "hdq1w.h"
+
+
+/* IP blocks */
+static struct omap_hwmod am43xx_l4_hs_hwmod = {
+ .name = "l4_hs",
+ .class = &am33xx_l4_hwmod_class,
+ .clkdm_name = "l3_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "l4hs_gclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_L4HS_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod_rst_info am33xx_wkup_m3_resets[] = {
+ { .name = "wkup_m3", .rst_shift = 3, .st_shift = 5 },
+};
+
+static struct omap_hwmod am43xx_wkup_m3_hwmod = {
+ .name = "wkup_m3",
+ .class = &am33xx_wkup_m3_hwmod_class,
+ .clkdm_name = "l4_wkup_aon_clkdm",
+ /* Keep hardreset asserted */
+ .flags = HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST,
+ .main_clk = "sys_clkin_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET,
+ .rstctrl_offs = AM43XX_RM_WKUP_RSTCTRL_OFFSET,
+ .rstst_offs = AM43XX_RM_WKUP_RSTST_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .rst_lines = am33xx_wkup_m3_resets,
+ .rst_lines_cnt = ARRAY_SIZE(am33xx_wkup_m3_resets),
+};
+
+static struct omap_hwmod am43xx_control_hwmod = {
+ .name = "control",
+ .class = &am33xx_control_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "sys_clkin_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod_opt_clk gpio0_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio0_dbclk" },
+};
+
+static struct omap_hwmod am43xx_gpio0_hwmod = {
+ .name = "gpio1",
+ .class = &am33xx_gpio_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "sys_clkin_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = gpio0_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio0_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+static struct omap_hwmod_class_sysconfig am43xx_synctimer_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x4,
+ .sysc_flags = SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class am43xx_synctimer_hwmod_class = {
+ .name = "synctimer",
+ .sysc = &am43xx_synctimer_sysc,
+};
+
+static struct omap_hwmod am43xx_synctimer_hwmod = {
+ .name = "counter_32k",
+ .class = &am43xx_synctimer_hwmod_class,
+ .clkdm_name = "l4_wkup_aon_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE,
+ .main_clk = "synctimer_32kclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod am43xx_timer8_hwmod = {
+ .name = "timer8",
+ .class = &am33xx_timer_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "timer8_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_TIMER8_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod am43xx_timer9_hwmod = {
+ .name = "timer9",
+ .class = &am33xx_timer_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "timer9_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_TIMER9_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod am43xx_timer10_hwmod = {
+ .name = "timer10",
+ .class = &am33xx_timer_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "timer10_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_TIMER10_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod am43xx_timer11_hwmod = {
+ .name = "timer11",
+ .class = &am33xx_timer_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "timer11_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_TIMER11_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod am43xx_epwmss3_hwmod = {
+ .name = "epwmss3",
+ .class = &am33xx_epwmss_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_EPWMSS3_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod am43xx_ehrpwm3_hwmod = {
+ .name = "ehrpwm3",
+ .class = &am33xx_ehrpwm_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+};
+
+static struct omap_hwmod am43xx_epwmss4_hwmod = {
+ .name = "epwmss4",
+ .class = &am33xx_epwmss_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_EPWMSS4_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod am43xx_ehrpwm4_hwmod = {
+ .name = "ehrpwm4",
+ .class = &am33xx_ehrpwm_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+};
+
+static struct omap_hwmod am43xx_epwmss5_hwmod = {
+ .name = "epwmss5",
+ .class = &am33xx_epwmss_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_EPWMSS5_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod am43xx_ehrpwm5_hwmod = {
+ .name = "ehrpwm5",
+ .class = &am33xx_ehrpwm_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+};
+
+static struct omap_hwmod am43xx_spi2_hwmod = {
+ .name = "spi2",
+ .class = &am33xx_spi_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "dpll_per_m2_div4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_SPI2_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi_attrib,
+};
+
+static struct omap_hwmod am43xx_spi3_hwmod = {
+ .name = "spi3",
+ .class = &am33xx_spi_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "dpll_per_m2_div4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_SPI3_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi_attrib,
+};
+
+static struct omap_hwmod am43xx_spi4_hwmod = {
+ .name = "spi4",
+ .class = &am33xx_spi_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "dpll_per_m2_div4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_SPI4_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi_attrib,
+};
+
+static struct omap_hwmod_opt_clk gpio4_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio4_dbclk" },
+};
+
+static struct omap_hwmod am43xx_gpio4_hwmod = {
+ .name = "gpio5",
+ .class = &am33xx_gpio_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_GPIO4_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = gpio4_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio5_dbclk" },
+};
+
+static struct omap_hwmod am43xx_gpio5_hwmod = {
+ .name = "gpio6",
+ .class = &am33xx_gpio_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_GPIO5_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = gpio5_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+static struct omap_hwmod_class am43xx_ocp2scp_hwmod_class = {
+ .name = "ocp2scp",
+};
+
+static struct omap_hwmod am43xx_ocp2scp0_hwmod = {
+ .name = "ocp2scp0",
+ .class = &am43xx_ocp2scp_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_USBPHYOCP2SCP0_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod am43xx_ocp2scp1_hwmod = {
+ .name = "ocp2scp1",
+ .class = &am43xx_ocp2scp_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_USBPHYOCP2SCP1_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod_class_sysconfig am43xx_usb_otg_ss_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = (SYSC_HAS_DMADISABLE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SIDLEMODE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP | MSTANDBY_FORCE |
+ MSTANDBY_NO | MSTANDBY_SMART |
+ MSTANDBY_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class am43xx_usb_otg_ss_hwmod_class = {
+ .name = "usb_otg_ss",
+ .sysc = &am43xx_usb_otg_ss_sysc,
+};
+
+static struct omap_hwmod am43xx_usb_otg_ss0_hwmod = {
+ .name = "usb_otg_ss0",
+ .class = &am43xx_usb_otg_ss_hwmod_class,
+ .clkdm_name = "l3s_clkdm",
+ .main_clk = "l3s_gclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_USB_OTG_SS0_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod am43xx_usb_otg_ss1_hwmod = {
+ .name = "usb_otg_ss1",
+ .class = &am43xx_usb_otg_ss_hwmod_class,
+ .clkdm_name = "l3s_clkdm",
+ .main_clk = "l3s_gclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_USB_OTG_SS1_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod_class_sysconfig am43xx_qspi_sysc = {
+ .sysc_offs = 0x0010,
+ .sysc_flags = SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class am43xx_qspi_hwmod_class = {
+ .name = "qspi",
+ .sysc = &am43xx_qspi_sysc,
+};
+
+static struct omap_hwmod am43xx_qspi_hwmod = {
+ .name = "qspi",
+ .class = &am43xx_qspi_hwmod_class,
+ .clkdm_name = "l3s_clkdm",
+ .main_clk = "l3s_gclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_QSPI_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'adc/tsc' class
+ * TouchScreen Controller (Analog-To-Digital Converter)
+ */
+static struct omap_hwmod_class_sysconfig am43xx_adc_tsc_sysc = {
+ .rev_offs = 0x00,
+ .sysc_offs = 0x10,
+ .sysc_flags = SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class am43xx_adc_tsc_hwmod_class = {
+ .name = "adc_tsc",
+ .sysc = &am43xx_adc_tsc_sysc,
+};
+
+static struct omap_hwmod am43xx_adc_tsc_hwmod = {
+ .name = "adc_tsc",
+ .class = &am43xx_adc_tsc_hwmod_class,
+ .clkdm_name = "l3s_tsc_clkdm",
+ .main_clk = "adc_tsc_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* dss */
+
+static struct omap_hwmod am43xx_dss_core_hwmod = {
+ .name = "dss_core",
+ .class = &omap2_dss_hwmod_class,
+ .clkdm_name = "dss_clkdm",
+ .main_clk = "disp_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_DSS_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* dispc */
+
+struct omap_dss_dispc_dev_attr am43xx_dss_dispc_dev_attr = {
+ .manager_count = 1,
+ .has_framedonetv_irq = 0
+};
+
+static struct omap_hwmod_class_sysconfig am43xx_dispc_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_MIDLEMODE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class am43xx_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &am43xx_dispc_sysc,
+};
+
+static struct omap_hwmod am43xx_dss_dispc_hwmod = {
+ .name = "dss_dispc",
+ .class = &am43xx_dispc_hwmod_class,
+ .clkdm_name = "dss_clkdm",
+ .main_clk = "disp_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_DSS_CLKCTRL_OFFSET,
+ },
+ },
+ .dev_attr = &am43xx_dss_dispc_dev_attr,
+ .parent_hwmod = &am43xx_dss_core_hwmod,
+};
+
+/* rfbi */
+
+static struct omap_hwmod am43xx_dss_rfbi_hwmod = {
+ .name = "dss_rfbi",
+ .class = &omap2_rfbi_hwmod_class,
+ .clkdm_name = "dss_clkdm",
+ .main_clk = "disp_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_DSS_CLKCTRL_OFFSET,
+ },
+ },
+ .parent_hwmod = &am43xx_dss_core_hwmod,
+};
+
+/* HDQ1W */
+static struct omap_hwmod_class_sysconfig am43xx_hdq1w_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0014,
+ .syss_offs = 0x0018,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class am43xx_hdq1w_hwmod_class = {
+ .name = "hdq1w",
+ .sysc = &am43xx_hdq1w_sysc,
+ .reset = &omap_hdq1w_reset,
+};
+
+static struct omap_hwmod am43xx_hdq1w_hwmod = {
+ .name = "hdq1w",
+ .class = &am43xx_hdq1w_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_HDQ1W_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod_class_sysconfig am43xx_vpfe_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x104,
+ .sysc_flags = SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_SMART | MSTANDBY_NO),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class am43xx_vpfe_hwmod_class = {
+ .name = "vpfe",
+ .sysc = &am43xx_vpfe_sysc,
+};
+
+static struct omap_hwmod am43xx_vpfe0_hwmod = {
+ .name = "vpfe0",
+ .class = &am43xx_vpfe_hwmod_class,
+ .clkdm_name = "l3s_clkdm",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ .clkctrl_offs = AM43XX_CM_PER_VPFE0_CLKCTRL_OFFSET,
+ },
+ },
+};
+
+static struct omap_hwmod am43xx_vpfe1_hwmod = {
+ .name = "vpfe1",
+ .class = &am43xx_vpfe_hwmod_class,
+ .clkdm_name = "l3s_clkdm",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ .clkctrl_offs = AM43XX_CM_PER_VPFE1_CLKCTRL_OFFSET,
+ },
+ },
+};
+
+/* Interfaces */
+static struct omap_hwmod_ocp_if am43xx_l3_main__l4_hs = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am43xx_l4_hs_hwmod,
+ .clk = "l3s_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_wkup_m3__l4_wkup = {
+ .master = &am43xx_wkup_m3_hwmod,
+ .slave = &am33xx_l4_wkup_hwmod,
+ .clk = "sys_clkin_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__wkup_m3 = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am43xx_wkup_m3_hwmod,
+ .clk = "sys_clkin_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l3_main__pruss = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am33xx_pruss_hwmod,
+ .clk = "dpll_core_m4_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__smartreflex0 = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_smartreflex0_hwmod,
+ .clk = "sys_clkin_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__smartreflex1 = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_smartreflex1_hwmod,
+ .clk = "sys_clkin_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__control = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am43xx_control_hwmod,
+ .clk = "sys_clkin_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__i2c1 = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_i2c1_hwmod,
+ .clk = "sys_clkin_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__gpio0 = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am43xx_gpio0_hwmod,
+ .clk = "sys_clkin_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__adc_tsc = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am43xx_adc_tsc_hwmod,
+ .clk = "dpll_core_m4_div2_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_hs__cpgmac0 = {
+ .master = &am43xx_l4_hs_hwmod,
+ .slave = &am33xx_cpgmac0_hwmod,
+ .clk = "cpsw_125mhz_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__timer1 = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_timer1_hwmod,
+ .clk = "sys_clkin_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__uart1 = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_uart1_hwmod,
+ .clk = "sys_clkin_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__wd_timer1 = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am33xx_wd_timer1_hwmod,
+ .clk = "sys_clkin_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__synctimer = {
+ .master = &am33xx_l4_wkup_hwmod,
+ .slave = &am43xx_synctimer_hwmod,
+ .clk = "sys_clkin_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__timer8 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_timer8_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__timer9 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_timer9_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__timer10 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_timer10_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__timer11 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_timer11_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss3 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_epwmss3_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_epwmss3__ehrpwm3 = {
+ .master = &am43xx_epwmss3_hwmod,
+ .slave = &am43xx_ehrpwm3_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss4 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_epwmss4_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_epwmss4__ehrpwm4 = {
+ .master = &am43xx_epwmss4_hwmod,
+ .slave = &am43xx_ehrpwm4_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss5 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_epwmss5_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_epwmss5__ehrpwm5 = {
+ .master = &am43xx_epwmss5_hwmod,
+ .slave = &am43xx_ehrpwm5_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi2 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_spi2_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi3 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_spi3_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi4 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_spi4_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__gpio4 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_gpio4_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__gpio5 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_gpio5_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__ocp2scp0 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_ocp2scp0_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__ocp2scp1 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_ocp2scp1_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l3_s__usbotgss0 = {
+ .master = &am33xx_l3_s_hwmod,
+ .slave = &am43xx_usb_otg_ss0_hwmod,
+ .clk = "l3s_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l3_s__usbotgss1 = {
+ .master = &am33xx_l3_s_hwmod,
+ .slave = &am43xx_usb_otg_ss1_hwmod,
+ .clk = "l3s_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l3_s__qspi = {
+ .master = &am33xx_l3_s_hwmod,
+ .slave = &am43xx_qspi_hwmod,
+ .clk = "l3s_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_dss__l3_main = {
+ .master = &am43xx_dss_core_hwmod,
+ .slave = &am33xx_l3_main_hwmod,
+ .clk = "l3_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__dss = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_dss_core_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__dss_dispc = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_dss_dispc_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__dss_rfbi = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_dss_rfbi_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__hdq1w = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_hdq1w_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l3__vpfe0 = {
+ .master = &am43xx_vpfe0_hwmod,
+ .slave = &am33xx_l3_main_hwmod,
+ .clk = "l3_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l3__vpfe1 = {
+ .master = &am43xx_vpfe1_hwmod,
+ .slave = &am33xx_l3_main_hwmod,
+ .clk = "l3_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__vpfe0 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_vpfe0_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__vpfe1 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_vpfe1_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
+ &am33xx_l4_wkup__synctimer,
+ &am43xx_l4_ls__timer8,
+ &am43xx_l4_ls__timer9,
+ &am43xx_l4_ls__timer10,
+ &am43xx_l4_ls__timer11,
+ &am43xx_l4_ls__epwmss3,
+ &am43xx_epwmss3__ehrpwm3,
+ &am43xx_l4_ls__epwmss4,
+ &am43xx_epwmss4__ehrpwm4,
+ &am43xx_l4_ls__epwmss5,
+ &am43xx_epwmss5__ehrpwm5,
+ &am43xx_l4_ls__mcspi2,
+ &am43xx_l4_ls__mcspi3,
+ &am43xx_l4_ls__mcspi4,
+ &am43xx_l4_ls__gpio4,
+ &am43xx_l4_ls__gpio5,
+ &am43xx_l3_main__pruss,
+ &am33xx_mpu__l3_main,
+ &am33xx_mpu__prcm,
+ &am33xx_l3_s__l4_ls,
+ &am33xx_l3_s__l4_wkup,
+ &am43xx_l3_main__l4_hs,
+ &am33xx_l3_main__l3_s,
+ &am33xx_l3_main__l3_instr,
+ &am33xx_l3_main__gfx,
+ &am33xx_l3_s__l3_main,
+ &am33xx_pruss__l3_main,
+ &am43xx_wkup_m3__l4_wkup,
+ &am33xx_gfx__l3_main,
+ &am43xx_l4_wkup__wkup_m3,
+ &am43xx_l4_wkup__control,
+ &am43xx_l4_wkup__smartreflex0,
+ &am43xx_l4_wkup__smartreflex1,
+ &am43xx_l4_wkup__uart1,
+ &am43xx_l4_wkup__timer1,
+ &am43xx_l4_wkup__i2c1,
+ &am43xx_l4_wkup__gpio0,
+ &am43xx_l4_wkup__wd_timer1,
+ &am43xx_l4_wkup__adc_tsc,
+ &am43xx_l3_s__qspi,
+ &am33xx_l4_per__dcan0,
+ &am33xx_l4_per__dcan1,
+ &am33xx_l4_per__gpio1,
+ &am33xx_l4_per__gpio2,
+ &am33xx_l4_per__gpio3,
+ &am33xx_l4_per__i2c2,
+ &am33xx_l4_per__i2c3,
+ &am33xx_l4_per__mailbox,
+ &am33xx_l4_ls__mcasp0,
+ &am33xx_l4_ls__mcasp1,
+ &am33xx_l4_ls__mmc0,
+ &am33xx_l4_ls__mmc1,
+ &am33xx_l3_s__mmc2,
+ &am33xx_l4_ls__timer2,
+ &am33xx_l4_ls__timer3,
+ &am33xx_l4_ls__timer4,
+ &am33xx_l4_ls__timer5,
+ &am33xx_l4_ls__timer6,
+ &am33xx_l4_ls__timer7,
+ &am33xx_l3_main__tpcc,
+ &am33xx_l4_ls__uart2,
+ &am33xx_l4_ls__uart3,
+ &am33xx_l4_ls__uart4,
+ &am33xx_l4_ls__uart5,
+ &am33xx_l4_ls__uart6,
+ &am33xx_l4_ls__spinlock,
+ &am33xx_l4_ls__elm,
+ &am33xx_l4_ls__epwmss0,
+ &am33xx_epwmss0__ecap0,
+ &am33xx_epwmss0__eqep0,
+ &am33xx_epwmss0__ehrpwm0,
+ &am33xx_l4_ls__epwmss1,
+ &am33xx_epwmss1__ecap1,
+ &am33xx_epwmss1__eqep1,
+ &am33xx_epwmss1__ehrpwm1,
+ &am33xx_l4_ls__epwmss2,
+ &am33xx_epwmss2__ecap2,
+ &am33xx_epwmss2__eqep2,
+ &am33xx_epwmss2__ehrpwm2,
+ &am33xx_l3_s__gpmc,
+ &am33xx_l4_ls__mcspi0,
+ &am33xx_l4_ls__mcspi1,
+ &am33xx_l3_main__tptc0,
+ &am33xx_l3_main__tptc1,
+ &am33xx_l3_main__tptc2,
+ &am33xx_l3_main__ocmc,
+ &am43xx_l4_hs__cpgmac0,
+ &am33xx_cpgmac0__mdio,
+ &am33xx_l3_main__sha0,
+ &am33xx_l3_main__aes0,
+ &am43xx_l4_ls__ocp2scp0,
+ &am43xx_l4_ls__ocp2scp1,
+ &am43xx_l3_s__usbotgss0,
+ &am43xx_l3_s__usbotgss1,
+ &am43xx_dss__l3_main,
+ &am43xx_l4_ls__dss,
+ &am43xx_l4_ls__dss_dispc,
+ &am43xx_l4_ls__dss_rfbi,
+ &am43xx_l4_ls__hdq1w,
+ &am43xx_l3__vpfe0,
+ &am43xx_l3__vpfe1,
+ &am43xx_l4_ls__vpfe0,
+ &am43xx_l4_ls__vpfe1,
+ NULL,
+};
+
+int __init am43xx_hwmod_init(void)
+{
+ omap_hwmod_am43xx_reg();
+ omap_hwmod_init();
+ return omap_hwmod_register_links(am43xx_hwmod_ocp_ifs);
+}
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 000000000..f5e68a782
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -0,0 +1,4864 @@
+/*
+ * Hardware modules present on the OMAP44xx chips
+ *
+ * Copyright (C) 2009-2012 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.
+ * Note that this file is currently not in sync with autogeneration scripts.
+ * The above note to be removed, once it is synced up.
+ *
+ * This program is free software; you can redistribute it 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/platform_data/gpio-omap.h>
+#include <linux/platform_data/hsmmc-omap.h>
+#include <linux/power/smartreflex.h>
+#include <linux/i2c-omap.h>
+
+#include <linux/omap-dma.h>
+
+#include <linux/platform_data/spi-omap2-mcspi.h>
+#include <linux/platform_data/asoc-ti-mcbsp.h>
+#include <linux/platform_data/iommu-omap.h>
+#include <plat/dmtimer.h>
+
+#include "omap_hwmod.h"
+#include "omap_hwmod_common_data.h"
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
+#include "i2c.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
+
+/*
+ * IP blocks
+ */
+
+/*
+ * 'dmm' class
+ * instance(s): dmm
+ */
+static struct omap_hwmod_class omap44xx_dmm_hwmod_class = {
+ .name = "dmm",
+};
+
+/* dmm */
+static struct omap_hwmod omap44xx_dmm_hwmod = {
+ .name = "dmm",
+ .class = &omap44xx_dmm_hwmod_class,
+ .clkdm_name = "l3_emif_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_MEMIF_DMM_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * '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 */
+static struct omap_hwmod omap44xx_l3_instr_hwmod = {
+ .name = "l3_instr",
+ .class = &omap44xx_l3_hwmod_class,
+ .clkdm_name = "l3_instr_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/* l3_main_1 */
+static struct omap_hwmod omap44xx_l3_main_1_hwmod = {
+ .name = "l3_main_1",
+ .class = &omap44xx_l3_hwmod_class,
+ .clkdm_name = "l3_1_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* l3_main_2 */
+static struct omap_hwmod omap44xx_l3_main_2_hwmod = {
+ .name = "l3_main_2",
+ .class = &omap44xx_l3_hwmod_class,
+ .clkdm_name = "l3_2_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3_2_L3_2_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* l3_main_3 */
+static struct omap_hwmod omap44xx_l3_main_3_hwmod = {
+ .name = "l3_main_3",
+ .class = &omap44xx_l3_hwmod_class,
+ .clkdm_name = "l3_instr_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INSTR_L3_3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * '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 */
+static struct omap_hwmod omap44xx_l4_abe_hwmod = {
+ .name = "l4_abe",
+ .class = &omap44xx_l4_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM1_ABE_L4ABE_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_AESS_CONTEXT_OFFSET,
+ .lostcontext_mask = OMAP4430_LOSTMEM_AESSMEM_MASK,
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+};
+
+/* l4_cfg */
+static struct omap_hwmod omap44xx_l4_cfg_hwmod = {
+ .name = "l4_cfg",
+ .class = &omap44xx_l4_hwmod_class,
+ .clkdm_name = "l4_cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4CFG_L4_CFG_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* l4_per */
+static struct omap_hwmod omap44xx_l4_per_hwmod = {
+ .name = "l4_per",
+ .class = &omap44xx_l4_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_L4_PER_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* l4_wkup */
+static struct omap_hwmod omap44xx_l4_wkup_hwmod = {
+ .name = "l4_wkup",
+ .class = &omap44xx_l4_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_WKUP_L4WKUP_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_WKUP_L4WKUP_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'mpu_bus' class
+ * instance(s): mpu_private
+ */
+static struct omap_hwmod_class omap44xx_mpu_bus_hwmod_class = {
+ .name = "mpu_bus",
+};
+
+/* mpu_private */
+static struct omap_hwmod omap44xx_mpu_private_hwmod = {
+ .name = "mpu_private",
+ .class = &omap44xx_mpu_bus_hwmod_class,
+ .clkdm_name = "mpuss_clkdm",
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+};
+
+/*
+ * 'ocp_wp_noc' class
+ * instance(s): ocp_wp_noc
+ */
+static struct omap_hwmod_class omap44xx_ocp_wp_noc_hwmod_class = {
+ .name = "ocp_wp_noc",
+};
+
+/* ocp_wp_noc */
+static struct omap_hwmod omap44xx_ocp_wp_noc_hwmod = {
+ .name = "ocp_wp_noc",
+ .class = &omap44xx_ocp_wp_noc_hwmod_class,
+ .clkdm_name = "l3_instr_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INSTR_OCP_WP1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * 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
+ *
+ * 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 |
+ MSTANDBY_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_aess_hwmod_class = {
+ .name = "aess",
+ .sysc = &omap44xx_aess_sysc,
+ .enable_preprogram = omap_hwmod_aess_preprogram,
+};
+
+/* aess */
+static struct omap_hwmod omap44xx_aess_hwmod = {
+ .name = "aess",
+ .class = &omap44xx_aess_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "aess_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_AESS_CONTEXT_OFFSET,
+ .lostcontext_mask = OMAP4430_LOSTCONTEXT_DFF_MASK,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'c2c' class
+ * chip 2 chip interface used to plug the ape soc (omap) with an external modem
+ * soc
+ */
+
+static struct omap_hwmod_class omap44xx_c2c_hwmod_class = {
+ .name = "c2c",
+};
+
+/* c2c */
+static struct omap_hwmod omap44xx_c2c_hwmod = {
+ .name = "c2c",
+ .class = &omap44xx_c2c_hwmod_class,
+ .clkdm_name = "d2d_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_D2D_SAD2D_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_D2D_SAD2D_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * '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),
+ .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 = {
+ .name = "counter_32k",
+ .class = &omap44xx_counter_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE,
+ .main_clk = "sys_32k_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_WKUP_SYNCTIMER_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'ctrl_module' class
+ * attila core control module + core pad control module + wkup pad control
+ * module + attila wkup control module
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_ctrl_module_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_ctrl_module_hwmod_class = {
+ .name = "ctrl_module",
+ .sysc = &omap44xx_ctrl_module_sysc,
+};
+
+/* ctrl_module_core */
+static struct omap_hwmod omap44xx_ctrl_module_core_hwmod = {
+ .name = "ctrl_module_core",
+ .class = &omap44xx_ctrl_module_hwmod_class,
+ .clkdm_name = "l4_cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+};
+
+/* ctrl_module_pad_core */
+static struct omap_hwmod omap44xx_ctrl_module_pad_core_hwmod = {
+ .name = "ctrl_module_pad_core",
+ .class = &omap44xx_ctrl_module_hwmod_class,
+ .clkdm_name = "l4_cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+};
+
+/* ctrl_module_wkup */
+static struct omap_hwmod omap44xx_ctrl_module_wkup_hwmod = {
+ .name = "ctrl_module_wkup",
+ .class = &omap44xx_ctrl_module_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+};
+
+/* ctrl_module_pad_wkup */
+static struct omap_hwmod omap44xx_ctrl_module_pad_wkup_hwmod = {
+ .name = "ctrl_module_pad_wkup",
+ .class = &omap44xx_ctrl_module_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+};
+
+/*
+ * 'debugss' class
+ * debug and emulation sub system
+ */
+
+static struct omap_hwmod_class omap44xx_debugss_hwmod_class = {
+ .name = "debugss",
+};
+
+/* debugss */
+static struct omap_hwmod omap44xx_debugss_hwmod = {
+ .name = "debugss",
+ .class = &omap44xx_debugss_hwmod_class,
+ .clkdm_name = "emu_sys_clkdm",
+ .main_clk = "trace_clk_div_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_EMU_DEBUGSS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_EMU_DEBUGSS_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * '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 },
+ { .irq = -1 }
+};
+
+static struct omap_hwmod omap44xx_dma_system_hwmod = {
+ .name = "dma_system",
+ .class = &omap44xx_dma_hwmod_class,
+ .clkdm_name = "l3_dma_clkdm",
+ .mpu_irqs = omap44xx_dma_system_irqs,
+ .xlate_irq = omap4_xlate_irq,
+ .main_clk = "l3_div_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_SDMA_SDMA_CONTEXT_OFFSET,
+ },
+ },
+ .dev_attr = &dma_dev_attr,
+};
+
+/*
+ * '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 = {
+ .name = "dmic",
+ .class = &omap44xx_dmic_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "func_dmic_abe_gfclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_DMIC_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'dsp' class
+ * dsp sub-system
+ */
+
+static struct omap_hwmod_class omap44xx_dsp_hwmod_class = {
+ .name = "dsp",
+};
+
+/* dsp */
+static struct omap_hwmod_rst_info omap44xx_dsp_resets[] = {
+ { .name = "dsp", .rst_shift = 0 },
+};
+
+static struct omap_hwmod omap44xx_dsp_hwmod = {
+ .name = "dsp",
+ .class = &omap44xx_dsp_hwmod_class,
+ .clkdm_name = "tesla_clkdm",
+ .rst_lines = omap44xx_dsp_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_dsp_resets),
+ .main_clk = "dpll_iva_m4x2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET,
+ .rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET,
+ .context_offs = OMAP4_RM_TESLA_TESLA_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * '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,
+ .reset = omap_dss_reset,
+};
+
+/* 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 = "hdmi_clk", .clk = "dss_48mhz_clk" },
+};
+
+static struct omap_hwmod omap44xx_dss_hwmod = {
+ .name = "dss_core",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .class = &omap44xx_dss_hwmod_class,
+ .clkdm_name = "l3_dss_clkdm",
+ .main_clk = "dss_dss_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = dss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks),
+};
+
+/*
+ * '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_irq_info omap44xx_dss_dispc_irqs[] = {
+ { .irq = 25 + OMAP44XX_IRQ_GIC_START },
+ { .irq = -1 }
+};
+
+static struct omap_hwmod_dma_info omap44xx_dss_dispc_sdma_reqs[] = {
+ { .dma_req = 5 + OMAP44XX_DMA_REQ_START },
+ { .dma_req = -1 }
+};
+
+static struct omap_dss_dispc_dev_attr omap44xx_dss_dispc_dev_attr = {
+ .manager_count = 3,
+ .has_framedonetv_irq = 1
+};
+
+static struct omap_hwmod omap44xx_dss_dispc_hwmod = {
+ .name = "dss_dispc",
+ .class = &omap44xx_dispc_hwmod_class,
+ .clkdm_name = "l3_dss_clkdm",
+ .mpu_irqs = omap44xx_dss_dispc_irqs,
+ .xlate_irq = omap4_xlate_irq,
+ .sdma_reqs = omap44xx_dss_dispc_sdma_reqs,
+ .main_clk = "dss_dss_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
+ },
+ },
+ .dev_attr = &omap44xx_dss_dispc_dev_attr,
+ .parent_hwmod = &omap44xx_dss_hwmod,
+};
+
+/*
+ * '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_irq_info omap44xx_dss_dsi1_irqs[] = {
+ { .irq = 53 + OMAP44XX_IRQ_GIC_START },
+ { .irq = -1 }
+};
+
+static struct omap_hwmod_dma_info omap44xx_dss_dsi1_sdma_reqs[] = {
+ { .dma_req = 74 + OMAP44XX_DMA_REQ_START },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod_opt_clk dss_dsi1_opt_clks[] = {
+ { .role = "sys_clk", .clk = "dss_sys_clk" },
+};
+
+static struct omap_hwmod omap44xx_dss_dsi1_hwmod = {
+ .name = "dss_dsi1",
+ .class = &omap44xx_dsi_hwmod_class,
+ .clkdm_name = "l3_dss_clkdm",
+ .mpu_irqs = omap44xx_dss_dsi1_irqs,
+ .xlate_irq = omap4_xlate_irq,
+ .sdma_reqs = omap44xx_dss_dsi1_sdma_reqs,
+ .main_clk = "dss_dss_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
+ },
+ },
+ .opt_clks = dss_dsi1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_opt_clks),
+ .parent_hwmod = &omap44xx_dss_hwmod,
+};
+
+/* dss_dsi2 */
+static struct omap_hwmod_irq_info omap44xx_dss_dsi2_irqs[] = {
+ { .irq = 84 + OMAP44XX_IRQ_GIC_START },
+ { .irq = -1 }
+};
+
+static struct omap_hwmod_dma_info omap44xx_dss_dsi2_sdma_reqs[] = {
+ { .dma_req = 83 + OMAP44XX_DMA_REQ_START },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod_opt_clk dss_dsi2_opt_clks[] = {
+ { .role = "sys_clk", .clk = "dss_sys_clk" },
+};
+
+static struct omap_hwmod omap44xx_dss_dsi2_hwmod = {
+ .name = "dss_dsi2",
+ .class = &omap44xx_dsi_hwmod_class,
+ .clkdm_name = "l3_dss_clkdm",
+ .mpu_irqs = omap44xx_dss_dsi2_irqs,
+ .xlate_irq = omap4_xlate_irq,
+ .sdma_reqs = omap44xx_dss_dsi2_sdma_reqs,
+ .main_clk = "dss_dss_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
+ },
+ },
+ .opt_clks = dss_dsi2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_dsi2_opt_clks),
+ .parent_hwmod = &omap44xx_dss_hwmod,
+};
+
+/*
+ * '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_irq_info omap44xx_dss_hdmi_irqs[] = {
+ { .irq = 101 + OMAP44XX_IRQ_GIC_START },
+ { .irq = -1 }
+};
+
+static struct omap_hwmod_dma_info omap44xx_dss_hdmi_sdma_reqs[] = {
+ { .dma_req = 75 + OMAP44XX_DMA_REQ_START },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = {
+ { .role = "sys_clk", .clk = "dss_sys_clk" },
+};
+
+static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
+ .name = "dss_hdmi",
+ .class = &omap44xx_hdmi_hwmod_class,
+ .clkdm_name = "l3_dss_clkdm",
+ /*
+ * HDMI audio requires to use no-idle mode. Hence,
+ * set idle mode by software.
+ */
+ .flags = HWMOD_SWSUP_SIDLE,
+ .mpu_irqs = omap44xx_dss_hdmi_irqs,
+ .xlate_irq = omap4_xlate_irq,
+ .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs,
+ .main_clk = "dss_48mhz_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
+ },
+ },
+ .opt_clks = dss_hdmi_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks),
+ .parent_hwmod = &omap44xx_dss_hwmod,
+};
+
+/*
+ * '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_dma_info omap44xx_dss_rfbi_sdma_reqs[] = {
+ { .dma_req = 13 + OMAP44XX_DMA_REQ_START },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = {
+ { .role = "ick", .clk = "l3_div_ck" },
+};
+
+static struct omap_hwmod omap44xx_dss_rfbi_hwmod = {
+ .name = "dss_rfbi",
+ .class = &omap44xx_rfbi_hwmod_class,
+ .clkdm_name = "l3_dss_clkdm",
+ .sdma_reqs = omap44xx_dss_rfbi_sdma_reqs,
+ .main_clk = "dss_dss_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
+ },
+ },
+ .opt_clks = dss_rfbi_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks),
+ .parent_hwmod = &omap44xx_dss_hwmod,
+};
+
+/*
+ * '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 = {
+ .name = "dss_venc",
+ .class = &omap44xx_venc_hwmod_class,
+ .clkdm_name = "l3_dss_clkdm",
+ .main_clk = "dss_tv_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
+ },
+ },
+ .parent_hwmod = &omap44xx_dss_hwmod,
+};
+
+/*
+ * 'elm' class
+ * bch error location module
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_elm_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+ 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_elm_hwmod_class = {
+ .name = "elm",
+ .sysc = &omap44xx_elm_sysc,
+};
+
+/* elm */
+static struct omap_hwmod omap44xx_elm_hwmod = {
+ .name = "elm",
+ .class = &omap44xx_elm_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_ELM_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_ELM_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'emif' class
+ * external memory interface no1
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_emif_sysc = {
+ .rev_offs = 0x0000,
+};
+
+static struct omap_hwmod_class omap44xx_emif_hwmod_class = {
+ .name = "emif",
+ .sysc = &omap44xx_emif_sysc,
+};
+
+/* emif1 */
+static struct omap_hwmod omap44xx_emif1_hwmod = {
+ .name = "emif1",
+ .class = &omap44xx_emif_hwmod_class,
+ .clkdm_name = "l3_emif_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "ddrphy_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_MEMIF_EMIF_1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_MEMIF_EMIF_1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/* emif2 */
+static struct omap_hwmod omap44xx_emif2_hwmod = {
+ .name = "emif2",
+ .class = &omap44xx_emif_hwmod_class,
+ .clkdm_name = "l3_emif_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "ddrphy_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_MEMIF_EMIF_2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_MEMIF_EMIF_2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * 'fdif' class
+ * face detection hw accelerator module
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_fdif_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ /*
+ * FDIF needs 100 OCP clk cycles delay after a softreset before
+ * accessing sysconfig again.
+ * The lowest frequency at the moment for L3 bus is 100 MHz, so
+ * 1usec delay is needed. Add an x2 margin to be safe (2 usecs).
+ *
+ * TODO: Indicate errata when available.
+ */
+ .srst_udelay = 2,
+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+ .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_fdif_hwmod_class = {
+ .name = "fdif",
+ .sysc = &omap44xx_fdif_sysc,
+};
+
+/* fdif */
+static struct omap_hwmod omap44xx_fdif_hwmod = {
+ .name = "fdif",
+ .class = &omap44xx_fdif_hwmod_class,
+ .clkdm_name = "iss_clkdm",
+ .main_clk = "fdif_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_CAM_FDIF_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_CAM_FDIF_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * '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_opt_clk gpio1_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio1_dbclk" },
+};
+
+static struct omap_hwmod omap44xx_gpio1_hwmod = {
+ .name = "gpio1",
+ .class = &omap44xx_gpio_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .main_clk = "l4_wkup_clk_mux_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_WKUP_GPIO1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_WKUP_GPIO1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* 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,
+ .clkdm_name = "l4_per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4_div_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_GPIO2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* 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,
+ .clkdm_name = "l4_per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4_div_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_GPIO3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio3_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* 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,
+ .clkdm_name = "l4_per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4_div_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_GPIO4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio4_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* 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,
+ .clkdm_name = "l4_per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4_div_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_GPIO5_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio5_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* 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,
+ .clkdm_name = "l4_per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4_div_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_GPIO6_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio6_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/*
+ * 'gpmc' class
+ * general purpose memory controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_gpmc_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_gpmc_hwmod_class = {
+ .name = "gpmc",
+ .sysc = &omap44xx_gpmc_sysc,
+};
+
+/* gpmc */
+static struct omap_hwmod omap44xx_gpmc_hwmod = {
+ .name = "gpmc",
+ .class = &omap44xx_gpmc_hwmod_class,
+ .clkdm_name = "l3_2_clkdm",
+ /*
+ * XXX HWMOD_INIT_NO_RESET should not be needed for this IP
+ * block. It is not being added due to any known bugs with
+ * resetting the GPMC IP block, but rather because any timings
+ * set by the bootloader are not being correctly programmed by
+ * the kernel from the board file or DT data.
+ * HWMOD_INIT_NO_RESET should be removed ASAP.
+ */
+ .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3_2_GPMC_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * 'gpu' class
+ * 2d/3d graphics accelerator
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_gpu_sysc = {
+ .rev_offs = 0x1fc00,
+ .sysc_offs = 0x1fc10,
+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+ MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_gpu_hwmod_class = {
+ .name = "gpu",
+ .sysc = &omap44xx_gpu_sysc,
+};
+
+/* gpu */
+static struct omap_hwmod omap44xx_gpu_hwmod = {
+ .name = "gpu",
+ .class = &omap44xx_gpu_hwmod_class,
+ .clkdm_name = "l3_gfx_clkdm",
+ .main_clk = "sgx_clk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_GFX_GFX_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'hdq1w' class
+ * hdq / 1-wire serial interface controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_hdq1w_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0014,
+ .syss_offs = 0x0018,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_hdq1w_hwmod_class = {
+ .name = "hdq1w",
+ .sysc = &omap44xx_hdq1w_sysc,
+};
+
+/* hdq1w */
+static struct omap_hwmod omap44xx_hdq1w_hwmod = {
+ .name = "hdq1w",
+ .class = &omap44xx_hdq1w_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .flags = HWMOD_INIT_NO_RESET, /* XXX temporary */
+ .main_clk = "func_12m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_HDQ1W_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * '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 | MSTANDBY_SMART_WKUP),
+ .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 omap44xx_hsi_hwmod = {
+ .name = "hsi",
+ .class = &omap44xx_hsi_hwmod_class,
+ .clkdm_name = "l3_init_clkdm",
+ .main_clk = "hsi_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INIT_HSI_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * '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),
+ .clockact = CLOCKACT_TEST_ICLK,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_i2c_hwmod_class = {
+ .name = "i2c",
+ .sysc = &omap44xx_i2c_sysc,
+ .rev = OMAP_I2C_IP_VERSION_2,
+ .reset = &omap_i2c_reset,
+};
+
+static struct omap_i2c_dev_attr i2c_dev_attr = {
+ .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE,
+};
+
+/* i2c1 */
+static struct omap_hwmod omap44xx_i2c1_hwmod = {
+ .name = "i2c1",
+ .class = &omap44xx_i2c_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "func_96m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_I2C1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/* i2c2 */
+static struct omap_hwmod omap44xx_i2c2_hwmod = {
+ .name = "i2c2",
+ .class = &omap44xx_i2c_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "func_96m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_I2C2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/* i2c3 */
+static struct omap_hwmod omap44xx_i2c3_hwmod = {
+ .name = "i2c3",
+ .class = &omap44xx_i2c_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "func_96m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_I2C3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/* i2c4 */
+static struct omap_hwmod omap44xx_i2c4_hwmod = {
+ .name = "i2c4",
+ .class = &omap44xx_i2c_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "func_96m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_I2C4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/*
+ * 'ipu' class
+ * imaging processor unit
+ */
+
+static struct omap_hwmod_class omap44xx_ipu_hwmod_class = {
+ .name = "ipu",
+};
+
+/* ipu */
+static struct omap_hwmod_rst_info omap44xx_ipu_resets[] = {
+ { .name = "cpu0", .rst_shift = 0 },
+ { .name = "cpu1", .rst_shift = 1 },
+};
+
+static struct omap_hwmod omap44xx_ipu_hwmod = {
+ .name = "ipu",
+ .class = &omap44xx_ipu_hwmod_class,
+ .clkdm_name = "ducati_clkdm",
+ .rst_lines = omap44xx_ipu_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_resets),
+ .main_clk = "ducati_clk_mux_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET,
+ .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * 'iss' class
+ * external images sensor pixel data processor
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_iss_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ /*
+ * ISS needs 100 OCP clk cycles delay after a softreset before
+ * accessing sysconfig again.
+ * The lowest frequency at the moment for L3 bus is 100 MHz, so
+ * 1usec delay is needed. Add an x2 margin to be safe (2 usecs).
+ *
+ * TODO: Indicate errata when available.
+ */
+ .srst_udelay = 2,
+ .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 | MSTANDBY_SMART_WKUP),
+ .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_opt_clk iss_opt_clks[] = {
+ { .role = "ctrlclk", .clk = "iss_ctrlclk" },
+};
+
+static struct omap_hwmod omap44xx_iss_hwmod = {
+ .name = "iss",
+ .class = &omap44xx_iss_hwmod_class,
+ .clkdm_name = "iss_clkdm",
+ .main_clk = "ducati_clk_mux_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_CAM_ISS_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = iss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(iss_opt_clks),
+};
+
+/*
+ * '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_rst_info omap44xx_iva_resets[] = {
+ { .name = "seq0", .rst_shift = 0 },
+ { .name = "seq1", .rst_shift = 1 },
+ { .name = "logic", .rst_shift = 2 },
+};
+
+static struct omap_hwmod omap44xx_iva_hwmod = {
+ .name = "iva",
+ .class = &omap44xx_iva_hwmod_class,
+ .clkdm_name = "ivahd_clkdm",
+ .rst_lines = omap44xx_iva_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_resets),
+ .main_clk = "dpll_iva_m5x2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET,
+ .rstctrl_offs = OMAP4_RM_IVAHD_RSTCTRL_OFFSET,
+ .context_offs = OMAP4_RM_IVAHD_IVAHD_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * '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 = {
+ .name = "kbd",
+ .class = &omap44xx_kbd_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .main_clk = "sys_32k_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_WKUP_KEYBOARD_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * '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 = {
+ .name = "mailbox",
+ .class = &omap44xx_mailbox_hwmod_class,
+ .clkdm_name = "l4_cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4CFG_MAILBOX_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'mcasp' class
+ * multi-channel audio serial port controller
+ */
+
+/* The IP is not compliant to type1 / type2 scheme */
+static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_mcasp = {
+ .sidle_shift = 0,
+};
+
+static struct omap_hwmod_class_sysconfig omap44xx_mcasp_sysc = {
+ .sysc_offs = 0x0004,
+ .sysc_flags = SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type_mcasp,
+};
+
+static struct omap_hwmod_class omap44xx_mcasp_hwmod_class = {
+ .name = "mcasp",
+ .sysc = &omap44xx_mcasp_sysc,
+};
+
+/* mcasp */
+static struct omap_hwmod omap44xx_mcasp_hwmod = {
+ .name = "mcasp",
+ .class = &omap44xx_mcasp_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "func_mcasp_abe_gfclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_MCASP_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * '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_opt_clk mcbsp1_opt_clks[] = {
+ { .role = "pad_fck", .clk = "pad_clks_ck" },
+ { .role = "prcm_fck", .clk = "mcbsp1_sync_mux_ck" },
+};
+
+static struct omap_hwmod omap44xx_mcbsp1_hwmod = {
+ .name = "mcbsp1",
+ .class = &omap44xx_mcbsp_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "func_mcbsp1_gfclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_MCBSP1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = mcbsp1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp1_opt_clks),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod_opt_clk mcbsp2_opt_clks[] = {
+ { .role = "pad_fck", .clk = "pad_clks_ck" },
+ { .role = "prcm_fck", .clk = "mcbsp2_sync_mux_ck" },
+};
+
+static struct omap_hwmod omap44xx_mcbsp2_hwmod = {
+ .name = "mcbsp2",
+ .class = &omap44xx_mcbsp_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "func_mcbsp2_gfclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_MCBSP2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = mcbsp2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp2_opt_clks),
+};
+
+/* mcbsp3 */
+static struct omap_hwmod_opt_clk mcbsp3_opt_clks[] = {
+ { .role = "pad_fck", .clk = "pad_clks_ck" },
+ { .role = "prcm_fck", .clk = "mcbsp3_sync_mux_ck" },
+};
+
+static struct omap_hwmod omap44xx_mcbsp3_hwmod = {
+ .name = "mcbsp3",
+ .class = &omap44xx_mcbsp_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "func_mcbsp3_gfclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_MCBSP3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = mcbsp3_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp3_opt_clks),
+};
+
+/* mcbsp4 */
+static struct omap_hwmod_opt_clk mcbsp4_opt_clks[] = {
+ { .role = "pad_fck", .clk = "pad_clks_ck" },
+ { .role = "prcm_fck", .clk = "mcbsp4_sync_mux_ck" },
+};
+
+static struct omap_hwmod omap44xx_mcbsp4_hwmod = {
+ .name = "mcbsp4",
+ .class = &omap44xx_mcbsp_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .main_clk = "per_mcbsp4_gfclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_MCBSP4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = mcbsp4_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp4_opt_clks),
+};
+
+/*
+ * '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 = {
+ .name = "mcpdm",
+ .class = &omap44xx_mcpdm_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ /*
+ * It's suspected that the McPDM requires an off-chip main
+ * functional clock, controlled via I2C. This IP block is
+ * currently reset very early during boot, before I2C is
+ * available, so it doesn't seem that we have any choice in
+ * the kernel other than to avoid resetting it.
+ *
+ * Also, McPDM needs to be configured to NO_IDLE mode when it
+ * is in used otherwise vital clocks will be gated which
+ * results 'slow motion' audio playback.
+ */
+ .flags = HWMOD_EXT_OPT_MAIN_CLK | HWMOD_SWSUP_SIDLE,
+ .main_clk = "pad_clks_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_PDM_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * '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_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 },
+ { .dma_req = -1 }
+};
+
+/* 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,
+ .clkdm_name = "l4_per_clkdm",
+ .sdma_reqs = omap44xx_mcspi1_sdma_reqs,
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_MCSPI1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi1_dev_attr,
+};
+
+/* mcspi2 */
+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 },
+ { .dma_req = -1 }
+};
+
+/* 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,
+ .clkdm_name = "l4_per_clkdm",
+ .sdma_reqs = omap44xx_mcspi2_sdma_reqs,
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_MCSPI2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi2_dev_attr,
+};
+
+/* mcspi3 */
+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 },
+ { .dma_req = -1 }
+};
+
+/* 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,
+ .clkdm_name = "l4_per_clkdm",
+ .sdma_reqs = omap44xx_mcspi3_sdma_reqs,
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_MCSPI3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi3_dev_attr,
+};
+
+/* mcspi4 */
+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 },
+ { .dma_req = -1 }
+};
+
+/* 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,
+ .clkdm_name = "l4_per_clkdm",
+ .sdma_reqs = omap44xx_mcspi4_sdma_reqs,
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_MCSPI4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi4_dev_attr,
+};
+
+/*
+ * '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 | MSTANDBY_SMART_WKUP),
+ .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_dma_info omap44xx_mmc1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 60 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 61 + OMAP44XX_DMA_REQ_START },
+ { .dma_req = -1 }
+};
+
+/* mmc1 dev_attr */
+static struct omap_hsmmc_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,
+ .clkdm_name = "l3_init_clkdm",
+ .sdma_reqs = omap44xx_mmc1_sdma_reqs,
+ .main_clk = "hsmmc1_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INIT_MMC1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mmc1_dev_attr,
+};
+
+/* mmc2 */
+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 },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod omap44xx_mmc2_hwmod = {
+ .name = "mmc2",
+ .class = &omap44xx_mmc_hwmod_class,
+ .clkdm_name = "l3_init_clkdm",
+ .sdma_reqs = omap44xx_mmc2_sdma_reqs,
+ .main_clk = "hsmmc2_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INIT_MMC2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* mmc3 */
+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 },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod omap44xx_mmc3_hwmod = {
+ .name = "mmc3",
+ .class = &omap44xx_mmc_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .sdma_reqs = omap44xx_mmc3_sdma_reqs,
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_MMCSD3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* mmc4 */
+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 },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod omap44xx_mmc4_hwmod = {
+ .name = "mmc4",
+ .class = &omap44xx_mmc_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .sdma_reqs = omap44xx_mmc4_sdma_reqs,
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_MMCSD4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* mmc5 */
+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 },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod omap44xx_mmc5_hwmod = {
+ .name = "mmc5",
+ .class = &omap44xx_mmc_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .sdma_reqs = omap44xx_mmc5_sdma_reqs,
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_MMCSD5_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'mmu' class
+ * The memory management unit performs virtual to physical address translation
+ * for its requestors.
+ */
+
+static struct omap_hwmod_class_sysconfig mmu_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 omap44xx_mmu_hwmod_class = {
+ .name = "mmu",
+ .sysc = &mmu_sysc,
+};
+
+/* mmu ipu */
+
+static struct omap_mmu_dev_attr mmu_ipu_dev_attr = {
+ .nr_tlb_entries = 32,
+};
+
+static struct omap_hwmod omap44xx_mmu_ipu_hwmod;
+static struct omap_hwmod_rst_info omap44xx_mmu_ipu_resets[] = {
+ { .name = "mmu_cache", .rst_shift = 2 },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mmu_ipu_addrs[] = {
+ {
+ .pa_start = 0x55082000,
+ .pa_end = 0x550820ff,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+/* l3_main_2 -> mmu_ipu */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__mmu_ipu = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_mmu_ipu_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_mmu_ipu_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod omap44xx_mmu_ipu_hwmod = {
+ .name = "mmu_ipu",
+ .class = &omap44xx_mmu_hwmod_class,
+ .clkdm_name = "ducati_clkdm",
+ .rst_lines = omap44xx_mmu_ipu_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_mmu_ipu_resets),
+ .main_clk = "ducati_clk_mux_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET,
+ .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .dev_attr = &mmu_ipu_dev_attr,
+};
+
+/* mmu dsp */
+
+static struct omap_mmu_dev_attr mmu_dsp_dev_attr = {
+ .nr_tlb_entries = 32,
+};
+
+static struct omap_hwmod omap44xx_mmu_dsp_hwmod;
+static struct omap_hwmod_rst_info omap44xx_mmu_dsp_resets[] = {
+ { .name = "mmu_cache", .rst_shift = 1 },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mmu_dsp_addrs[] = {
+ {
+ .pa_start = 0x4a066000,
+ .pa_end = 0x4a0660ff,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+/* l4_cfg -> dsp */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__mmu_dsp = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_mmu_dsp_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_mmu_dsp_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod omap44xx_mmu_dsp_hwmod = {
+ .name = "mmu_dsp",
+ .class = &omap44xx_mmu_hwmod_class,
+ .clkdm_name = "tesla_clkdm",
+ .rst_lines = omap44xx_mmu_dsp_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_mmu_dsp_resets),
+ .main_clk = "dpll_iva_m4x2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET,
+ .rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET,
+ .context_offs = OMAP4_RM_TESLA_TESLA_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .dev_attr = &mmu_dsp_dev_attr,
+};
+
+/*
+ * 'mpu' class
+ * mpu sub-system
+ */
+
+static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
+ .name = "mpu",
+};
+
+/* mpu */
+static struct omap_hwmod omap44xx_mpu_hwmod = {
+ .name = "mpu",
+ .class = &omap44xx_mpu_hwmod_class,
+ .clkdm_name = "mpuss_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "dpll_mpu_m2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_MPU_MPU_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'ocmc_ram' class
+ * top-level core on-chip ram
+ */
+
+static struct omap_hwmod_class omap44xx_ocmc_ram_hwmod_class = {
+ .name = "ocmc_ram",
+};
+
+/* ocmc_ram */
+static struct omap_hwmod omap44xx_ocmc_ram_hwmod = {
+ .name = "ocmc_ram",
+ .class = &omap44xx_ocmc_ram_hwmod_class,
+ .clkdm_name = "l3_2_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3_2_OCMC_RAM_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3_2_OCMC_RAM_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'ocp2scp' class
+ * bridge to transform ocp interface protocol to scp (serial control port)
+ * protocol
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_ocp2scp_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_ocp2scp_hwmod_class = {
+ .name = "ocp2scp",
+ .sysc = &omap44xx_ocp2scp_sysc,
+};
+
+/* ocp2scp_usb_phy */
+static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
+ .name = "ocp2scp_usb_phy",
+ .class = &omap44xx_ocp2scp_hwmod_class,
+ .clkdm_name = "l3_init_clkdm",
+ /*
+ * ocp2scp_usb_phy_phy_48m is provided by the OMAP4 PRCM IP
+ * block as an "optional clock," and normally should never be
+ * specified as the main_clk for an OMAP IP block. However it
+ * turns out that this clock is actually the main clock for
+ * the ocp2scp_usb_phy IP block:
+ * http://lists.infradead.org/pipermail/linux-arm-kernel/2012-September/119943.html
+ * So listing ocp2scp_usb_phy_phy_48m as a main_clk here seems
+ * to be the best workaround.
+ */
+ .main_clk = "ocp2scp_usb_phy_phy_48m",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INIT_USBPHYOCP2SCP_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * 'prcm' class
+ * power and reset manager (part of the prcm infrastructure) + clock manager 2
+ * + clock manager 1 (in always on power domain) + local prm in mpu
+ */
+
+static struct omap_hwmod_class omap44xx_prcm_hwmod_class = {
+ .name = "prcm",
+};
+
+/* prcm_mpu */
+static struct omap_hwmod omap44xx_prcm_mpu_hwmod = {
+ .name = "prcm_mpu",
+ .class = &omap44xx_prcm_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .flags = HWMOD_NO_IDLEST,
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+};
+
+/* cm_core_aon */
+static struct omap_hwmod omap44xx_cm_core_aon_hwmod = {
+ .name = "cm_core_aon",
+ .class = &omap44xx_prcm_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+};
+
+/* cm_core */
+static struct omap_hwmod omap44xx_cm_core_hwmod = {
+ .name = "cm_core",
+ .class = &omap44xx_prcm_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+};
+
+/* prm */
+static struct omap_hwmod_rst_info omap44xx_prm_resets[] = {
+ { .name = "rst_global_warm_sw", .rst_shift = 0 },
+ { .name = "rst_global_cold_sw", .rst_shift = 1 },
+};
+
+static struct omap_hwmod omap44xx_prm_hwmod = {
+ .name = "prm",
+ .class = &omap44xx_prcm_hwmod_class,
+ .rst_lines = omap44xx_prm_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_prm_resets),
+};
+
+/*
+ * 'scrm' class
+ * system clock and reset manager
+ */
+
+static struct omap_hwmod_class omap44xx_scrm_hwmod_class = {
+ .name = "scrm",
+};
+
+/* scrm */
+static struct omap_hwmod omap44xx_scrm_hwmod = {
+ .name = "scrm",
+ .class = &omap44xx_scrm_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+};
+
+/*
+ * 'sl2if' class
+ * shared level 2 memory interface
+ */
+
+static struct omap_hwmod_class omap44xx_sl2if_hwmod_class = {
+ .name = "sl2if",
+};
+
+/* sl2if */
+static struct omap_hwmod omap44xx_sl2if_hwmod = {
+ .name = "sl2if",
+ .class = &omap44xx_sl2if_hwmod_class,
+ .clkdm_name = "ivahd_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_IVAHD_SL2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * 'slimbus' class
+ * bidirectional, multi-drop, multi-channel two-line serial interface between
+ * the device and external components
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_slimbus_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_slimbus_hwmod_class = {
+ .name = "slimbus",
+ .sysc = &omap44xx_slimbus_sysc,
+};
+
+/* slimbus1 */
+static struct omap_hwmod_opt_clk slimbus1_opt_clks[] = {
+ { .role = "fclk_1", .clk = "slimbus1_fclk_1" },
+ { .role = "fclk_0", .clk = "slimbus1_fclk_0" },
+ { .role = "fclk_2", .clk = "slimbus1_fclk_2" },
+ { .role = "slimbus_clk", .clk = "slimbus1_slimbus_clk" },
+};
+
+static struct omap_hwmod omap44xx_slimbus1_hwmod = {
+ .name = "slimbus1",
+ .class = &omap44xx_slimbus_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM1_ABE_SLIMBUS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_SLIMBUS_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = slimbus1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(slimbus1_opt_clks),
+};
+
+/* slimbus2 */
+static struct omap_hwmod_opt_clk slimbus2_opt_clks[] = {
+ { .role = "fclk_1", .clk = "slimbus2_fclk_1" },
+ { .role = "fclk_0", .clk = "slimbus2_fclk_0" },
+ { .role = "slimbus_clk", .clk = "slimbus2_slimbus_clk" },
+};
+
+static struct omap_hwmod omap44xx_slimbus2_hwmod = {
+ .name = "slimbus2",
+ .class = &omap44xx_slimbus_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_SLIMBUS2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_SLIMBUS2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = slimbus2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(slimbus2_opt_clks),
+};
+
+/*
+ * '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_smartreflex_dev_attr smartreflex_core_dev_attr = {
+ .sensor_voltdm_name = "core",
+};
+
+static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
+ .name = "smartreflex_core",
+ .class = &omap44xx_smartreflex_hwmod_class,
+ .clkdm_name = "l4_ao_clkdm",
+
+ .main_clk = "smartreflex_core_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ALWON_SR_CORE_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &smartreflex_core_dev_attr,
+};
+
+/* smartreflex_iva */
+static struct omap_smartreflex_dev_attr smartreflex_iva_dev_attr = {
+ .sensor_voltdm_name = "iva",
+};
+
+static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
+ .name = "smartreflex_iva",
+ .class = &omap44xx_smartreflex_hwmod_class,
+ .clkdm_name = "l4_ao_clkdm",
+ .main_clk = "smartreflex_iva_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ALWON_SR_IVA_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &smartreflex_iva_dev_attr,
+};
+
+/* smartreflex_mpu */
+static struct omap_smartreflex_dev_attr smartreflex_mpu_dev_attr = {
+ .sensor_voltdm_name = "mpu",
+};
+
+static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
+ .name = "smartreflex_mpu",
+ .class = &omap44xx_smartreflex_hwmod_class,
+ .clkdm_name = "l4_ao_clkdm",
+ .main_clk = "smartreflex_mpu_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ALWON_SR_MPU_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &smartreflex_mpu_dev_attr,
+};
+
+/*
+ * '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),
+ .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 = {
+ .name = "spinlock",
+ .class = &omap44xx_spinlock_hwmod_class,
+ .clkdm_name = "l4_cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4CFG_HW_SEM_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * '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),
+ .clockact = CLOCKACT_TEST_ICLK,
+ .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,
+};
+
+/* always-on timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
+ .timer_capability = OMAP_TIMER_ALWON,
+};
+
+/* pwm timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_PWM,
+};
+
+/* timers with DSP interrupt dev attribute */
+static struct omap_timer_capability_dev_attr capability_dsp_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_DSP_IRQ,
+};
+
+/* pwm timers with DSP interrupt dev attribute */
+static struct omap_timer_capability_dev_attr capability_dsp_pwm_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_DSP_IRQ | OMAP_TIMER_HAS_PWM,
+};
+
+/* timer1 */
+static struct omap_hwmod omap44xx_timer1_hwmod = {
+ .name = "timer1",
+ .class = &omap44xx_timer_1ms_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "dmt1_clk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_WKUP_TIMER1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+};
+
+/* timer2 */
+static struct omap_hwmod omap44xx_timer2_hwmod = {
+ .name = "timer2",
+ .class = &omap44xx_timer_1ms_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "cm2_dm2_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_DMTIMER2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer3 */
+static struct omap_hwmod omap44xx_timer3_hwmod = {
+ .name = "timer3",
+ .class = &omap44xx_timer_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .main_clk = "cm2_dm3_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_DMTIMER3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer4 */
+static struct omap_hwmod omap44xx_timer4_hwmod = {
+ .name = "timer4",
+ .class = &omap44xx_timer_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .main_clk = "cm2_dm4_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_DMTIMER4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer5 */
+static struct omap_hwmod omap44xx_timer5_hwmod = {
+ .name = "timer5",
+ .class = &omap44xx_timer_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "timer5_sync_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_TIMER5_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_dsp_dev_attr,
+};
+
+/* timer6 */
+static struct omap_hwmod omap44xx_timer6_hwmod = {
+ .name = "timer6",
+ .class = &omap44xx_timer_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "timer6_sync_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_TIMER6_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_dsp_dev_attr,
+};
+
+/* timer7 */
+static struct omap_hwmod omap44xx_timer7_hwmod = {
+ .name = "timer7",
+ .class = &omap44xx_timer_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "timer7_sync_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_TIMER7_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_dsp_dev_attr,
+};
+
+/* timer8 */
+static struct omap_hwmod omap44xx_timer8_hwmod = {
+ .name = "timer8",
+ .class = &omap44xx_timer_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "timer8_sync_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_TIMER8_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_dsp_pwm_dev_attr,
+};
+
+/* timer9 */
+static struct omap_hwmod omap44xx_timer9_hwmod = {
+ .name = "timer9",
+ .class = &omap44xx_timer_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .main_clk = "cm2_dm9_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_DMTIMER9_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_pwm_dev_attr,
+};
+
+/* timer10 */
+static struct omap_hwmod omap44xx_timer10_hwmod = {
+ .name = "timer10",
+ .class = &omap44xx_timer_1ms_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "cm2_dm10_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_DMTIMER10_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_pwm_dev_attr,
+};
+
+/* timer11 */
+static struct omap_hwmod omap44xx_timer11_hwmod = {
+ .name = "timer11",
+ .class = &omap44xx_timer_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .main_clk = "cm2_dm11_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_DMTIMER11_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_pwm_dev_attr,
+};
+
+/*
+ * '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 = {
+ .name = "uart1",
+ .class = &omap44xx_uart_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_UART1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart2 */
+static struct omap_hwmod omap44xx_uart2_hwmod = {
+ .name = "uart2",
+ .class = &omap44xx_uart_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_UART2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart3 */
+static struct omap_hwmod omap44xx_uart3_hwmod = {
+ .name = "uart3",
+ .class = &omap44xx_uart_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .flags = DEBUG_OMAP4UART3_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_UART3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart4 */
+static struct omap_hwmod omap44xx_uart4_hwmod = {
+ .name = "uart4",
+ .class = &omap44xx_uart_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
+ .flags = DEBUG_OMAP4UART4_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_UART4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'usb_host_fs' class
+ * full-speed usb host controller
+ */
+
+/* The IP is not compliant to type1 / type2 scheme */
+static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_usb_host_fs = {
+ .midle_shift = 4,
+ .sidle_shift = 2,
+ .srst_shift = 1,
+};
+
+static struct omap_hwmod_class_sysconfig omap44xx_usb_host_fs_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0210,
+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type_usb_host_fs,
+};
+
+static struct omap_hwmod_class omap44xx_usb_host_fs_hwmod_class = {
+ .name = "usb_host_fs",
+ .sysc = &omap44xx_usb_host_fs_sysc,
+};
+
+/* usb_host_fs */
+static struct omap_hwmod omap44xx_usb_host_fs_hwmod = {
+ .name = "usb_host_fs",
+ .class = &omap44xx_usb_host_fs_hwmod_class,
+ .clkdm_name = "l3_init_clkdm",
+ .main_clk = "usb_host_fs_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3INIT_USB_HOST_FS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INIT_USB_HOST_FS_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'usb_host_hs' class
+ * high-speed multi-port usb host controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_usb_host_hs_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+ MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_usb_host_hs_hwmod_class = {
+ .name = "usb_host_hs",
+ .sysc = &omap44xx_usb_host_hs_sysc,
+};
+
+/* usb_host_hs */
+static struct omap_hwmod omap44xx_usb_host_hs_hwmod = {
+ .name = "usb_host_hs",
+ .class = &omap44xx_usb_host_hs_hwmod_class,
+ .clkdm_name = "l3_init_clkdm",
+ .main_clk = "usb_host_hs_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INIT_USB_HOST_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+
+ /*
+ * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock
+ * id: i660
+ *
+ * Description:
+ * In the following configuration :
+ * - USBHOST module is set to smart-idle mode
+ * - PRCM asserts idle_req to the USBHOST module ( This typically
+ * happens when the system is going to a low power mode : all ports
+ * have been suspended, the master part of the USBHOST module has
+ * entered the standby state, and SW has cut the functional clocks)
+ * - an USBHOST interrupt occurs before the module is able to answer
+ * idle_ack, typically a remote wakeup IRQ.
+ * Then the USB HOST module will enter a deadlock situation where it
+ * is no more accessible nor functional.
+ *
+ * Workaround:
+ * Don't use smart idle; use only force idle, hence HWMOD_SWSUP_SIDLE
+ */
+
+ /*
+ * Errata: USB host EHCI may stall when entering smart-standby mode
+ * Id: i571
+ *
+ * Description:
+ * When the USBHOST module is set to smart-standby mode, and when it is
+ * ready to enter the standby state (i.e. all ports are suspended and
+ * all attached devices are in suspend mode), then it can wrongly assert
+ * the Mstandby signal too early while there are still some residual OCP
+ * transactions ongoing. If this condition occurs, the internal state
+ * machine may go to an undefined state and the USB link may be stuck
+ * upon the next resume.
+ *
+ * Workaround:
+ * Don't use smart standby; use only force standby,
+ * hence HWMOD_SWSUP_MSTANDBY
+ */
+
+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+};
+
+/*
+ * '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_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,
+ .clkdm_name = "l3_init_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+ .main_clk = "usb_otg_hs_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INIT_USB_OTG_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = usb_otg_hs_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(usb_otg_hs_opt_clks),
+};
+
+/*
+ * 'usb_tll_hs' class
+ * usb_tll_hs module is the adapter on the usb_host_hs ports
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_usb_tll_hs_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),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_usb_tll_hs_hwmod_class = {
+ .name = "usb_tll_hs",
+ .sysc = &omap44xx_usb_tll_hs_sysc,
+};
+
+static struct omap_hwmod omap44xx_usb_tll_hs_hwmod = {
+ .name = "usb_tll_hs",
+ .class = &omap44xx_usb_tll_hs_hwmod_class,
+ .clkdm_name = "l3_init_clkdm",
+ .main_clk = "usb_tll_hs_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INIT_USB_TLL_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * '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,
+ .reset = &omap2_wd_timer_reset,
+};
+
+/* wd_timer2 */
+static struct omap_hwmod omap44xx_wd_timer2_hwmod = {
+ .name = "wd_timer2",
+ .class = &omap44xx_wd_timer_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
+ .main_clk = "sys_32k_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_WKUP_WDT2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_WKUP_WDT2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* wd_timer3 */
+static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
+ .name = "wd_timer3",
+ .class = &omap44xx_wd_timer_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "sys_32k_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_WDT3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+
+/*
+ * interfaces
+ */
+
+/* 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,
+};
+
+/* mpu -> dmm */
+static struct omap_hwmod_ocp_if omap44xx_mpu__dmm = {
+ .master = &omap44xx_mpu_hwmod,
+ .slave = &omap44xx_dmm_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* 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,
+};
+
+/* ocp_wp_noc -> l3_instr */
+static struct omap_hwmod_ocp_if omap44xx_ocp_wp_noc__l3_instr = {
+ .master = &omap44xx_ocp_wp_noc_hwmod,
+ .slave = &omap44xx_l3_instr_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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,
+};
+
+/* mpu -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap44xx_mpu__l3_main_1 = {
+ .master = &omap44xx_mpu_hwmod,
+ .slave = &omap44xx_l3_main_1_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* debugss -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_debugss__l3_main_2 = {
+ .master = &omap44xx_debugss_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "dbgclk_mux_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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,
+};
+
+/* fdif -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_fdif__l3_main_2 = {
+ .master = &omap44xx_fdif_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpu -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_gpu__l3_main_2 = {
+ .master = &omap44xx_gpu_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,
+};
+
+/* l3_main_1 -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_2 = {
+ .master = &omap44xx_l3_main_1_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* 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_host_fs -> l3_main_2 */
+static struct omap_hwmod_ocp_if __maybe_unused omap44xx_usb_host_fs__l3_main_2 = {
+ .master = &omap44xx_usb_host_fs_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* usb_host_hs -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_usb_host_hs__l3_main_2 = {
+ .master = &omap44xx_usb_host_hs_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l3_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_1 -> l3_main_3 */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_3 = {
+ .master = &omap44xx_l3_main_1_hwmod,
+ .slave = &omap44xx_l3_main_3_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* 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,
+};
+
+/* aess -> l4_abe */
+static struct omap_hwmod_ocp_if __maybe_unused 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,
+};
+
+/* 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,
+};
+
+/* 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_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,
+};
+
+/* 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,
+};
+
+/* l4_cfg -> ocp_wp_noc */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ocp_wp_noc = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_ocp_wp_noc_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_aess_addrs[] = {
+ {
+ .name = "dmem",
+ .pa_start = 0x40180000,
+ .pa_end = 0x4018ffff
+ },
+ {
+ .name = "cmem",
+ .pa_start = 0x401a0000,
+ .pa_end = 0x401a1fff
+ },
+ {
+ .name = "smem",
+ .pa_start = 0x401c0000,
+ .pa_end = 0x401c5fff
+ },
+ {
+ .name = "pmem",
+ .pa_start = 0x401e0000,
+ .pa_end = 0x401e1fff
+ },
+ {
+ .name = "mpu",
+ .pa_start = 0x401f1000,
+ .pa_end = 0x401f13ff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_abe -> aess */
+static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_abe__aess = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_aess_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_aess_addrs,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_aess_dma_addrs[] = {
+ {
+ .name = "dmem_dma",
+ .pa_start = 0x49080000,
+ .pa_end = 0x4908ffff
+ },
+ {
+ .name = "cmem_dma",
+ .pa_start = 0x490a0000,
+ .pa_end = 0x490a1fff
+ },
+ {
+ .name = "smem_dma",
+ .pa_start = 0x490c0000,
+ .pa_end = 0x490c5fff
+ },
+ {
+ .name = "pmem_dma",
+ .pa_start = 0x490e0000,
+ .pa_end = 0x490e1fff
+ },
+ {
+ .name = "dma",
+ .pa_start = 0x490f1000,
+ .pa_end = 0x490f13ff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_abe -> aess (dma) */
+static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_abe__aess_dma = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_aess_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_aess_dma_addrs,
+ .user = OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> c2c */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__c2c = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_c2c_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_ctrl_module_core_addrs[] = {
+ {
+ .pa_start = 0x4a002000,
+ .pa_end = 0x4a0027ff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_cfg -> ctrl_module_core */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ctrl_module_core = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_ctrl_module_core_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_ctrl_module_core_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_ctrl_module_pad_core_addrs[] = {
+ {
+ .pa_start = 0x4a100000,
+ .pa_end = 0x4a1007ff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_cfg -> ctrl_module_pad_core */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ctrl_module_pad_core = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_ctrl_module_pad_core_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_ctrl_module_pad_core_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_ctrl_module_wkup_addrs[] = {
+ {
+ .pa_start = 0x4a30c000,
+ .pa_end = 0x4a30c7ff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_wkup -> ctrl_module_wkup */
+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__ctrl_module_wkup = {
+ .master = &omap44xx_l4_wkup_hwmod,
+ .slave = &omap44xx_ctrl_module_wkup_hwmod,
+ .clk = "l4_wkup_clk_mux_ck",
+ .addr = omap44xx_ctrl_module_wkup_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_ctrl_module_pad_wkup_addrs[] = {
+ {
+ .pa_start = 0x4a31e000,
+ .pa_end = 0x4a31e7ff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_wkup -> ctrl_module_pad_wkup */
+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__ctrl_module_pad_wkup = {
+ .master = &omap44xx_l4_wkup_hwmod,
+ .slave = &omap44xx_ctrl_module_pad_wkup_hwmod,
+ .clk = "l4_wkup_clk_mux_ck",
+ .addr = omap44xx_ctrl_module_pad_wkup_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_instr -> debugss */
+static struct omap_hwmod_ocp_if omap44xx_l3_instr__debugss = {
+ .master = &omap44xx_l3_instr_hwmod,
+ .slave = &omap44xx_debugss_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dsp -> iva */
+static struct omap_hwmod_ocp_if omap44xx_dsp__iva = {
+ .master = &omap44xx_dsp_hwmod,
+ .slave = &omap44xx_iva_hwmod,
+ .clk = "dpll_iva_m5x2_ck",
+ .user = OCP_USER_DSP,
+};
+
+/* dsp -> sl2if */
+static struct omap_hwmod_ocp_if __maybe_unused omap44xx_dsp__sl2if = {
+ .master = &omap44xx_dsp_hwmod,
+ .slave = &omap44xx_sl2if_hwmod,
+ .clk = "dpll_iva_m5x2_ck",
+ .user = OCP_USER_DSP,
+};
+
+/* 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,
+};
+
+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,
+ .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,
+ .user = OCP_USER_MPU,
+};
+
+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,
+ .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,
+ .user = OCP_USER_MPU,
+};
+
+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,
+ .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,
+ .user = OCP_USER_MPU,
+};
+
+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,
+ .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,
+ .user = OCP_USER_MPU,
+};
+
+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,
+ .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,
+ .user = OCP_USER_MPU,
+};
+
+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,
+ .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,
+ .user = OCP_USER_MPU,
+};
+
+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,
+ .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,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_elm_addrs[] = {
+ {
+ .pa_start = 0x48078000,
+ .pa_end = 0x48078fff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_per -> elm */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__elm = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_elm_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_elm_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_fdif_addrs[] = {
+ {
+ .pa_start = 0x4a10a000,
+ .pa_end = 0x4a10a1ff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_cfg -> fdif */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__fdif = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_fdif_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_fdif_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> gpmc */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__gpmc = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_gpmc_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_gpu_addrs[] = {
+ {
+ .pa_start = 0x56000000,
+ .pa_end = 0x5600ffff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l3_main_2 -> gpu */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__gpu = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_gpu_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_gpu_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_hdq1w_addrs[] = {
+ {
+ .pa_start = 0x480b2000,
+ .pa_end = 0x480b201f,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_per -> hdq1w */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__hdq1w = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_hdq1w_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_hdq1w_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* iva -> sl2if */
+static struct omap_hwmod_ocp_if __maybe_unused omap44xx_iva__sl2if = {
+ .master = &omap44xx_iva_hwmod,
+ .slave = &omap44xx_sl2if_hwmod,
+ .clk = "dpll_iva_m5x2_ck",
+ .user = OCP_USER_IVA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcasp_addrs[] = {
+ {
+ .pa_start = 0x40128000,
+ .pa_end = 0x401283ff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_abe -> mcasp */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcasp = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_mcasp_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_mcasp_addrs,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcasp_dma_addrs[] = {
+ {
+ .pa_start = 0x49028000,
+ .pa_end = 0x490283ff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_abe -> mcasp (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcasp_dma = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_mcasp_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_mcasp_dma_addrs,
+ .user = OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> ocmc_ram */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__ocmc_ram = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_ocmc_ram_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> ocp2scp_usb_phy */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ocp2scp_usb_phy = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_ocp2scp_usb_phy_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu_private -> prcm_mpu */
+static struct omap_hwmod_ocp_if omap44xx_mpu_private__prcm_mpu = {
+ .master = &omap44xx_mpu_private_hwmod,
+ .slave = &omap44xx_prcm_mpu_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> cm_core_aon */
+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__cm_core_aon = {
+ .master = &omap44xx_l4_wkup_hwmod,
+ .slave = &omap44xx_cm_core_aon_hwmod,
+ .clk = "l4_wkup_clk_mux_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> cm_core */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__cm_core = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_cm_core_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> prm */
+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__prm = {
+ .master = &omap44xx_l4_wkup_hwmod,
+ .slave = &omap44xx_prm_hwmod,
+ .clk = "l4_wkup_clk_mux_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> scrm */
+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__scrm = {
+ .master = &omap44xx_l4_wkup_hwmod,
+ .slave = &omap44xx_scrm_hwmod,
+ .clk = "l4_wkup_clk_mux_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> sl2if */
+static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l3_main_2__sl2if = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_sl2if_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_slimbus1_addrs[] = {
+ {
+ .pa_start = 0x4012c000,
+ .pa_end = 0x4012c3ff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_abe -> slimbus1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__slimbus1 = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_slimbus1_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_slimbus1_addrs,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_slimbus1_dma_addrs[] = {
+ {
+ .pa_start = 0x4902c000,
+ .pa_end = 0x4902c3ff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_abe -> slimbus1 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__slimbus1_dma = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_slimbus1_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_slimbus1_dma_addrs,
+ .user = OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_slimbus2_addrs[] = {
+ {
+ .pa_start = 0x48076000,
+ .pa_end = 0x480763ff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_per -> slimbus2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__slimbus2 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_slimbus2_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_slimbus2_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> usb_host_fs */
+static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_cfg__usb_host_fs = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_usb_host_fs_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> usb_host_hs */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_host_hs = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_usb_host_hs_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> usb_tll_hs */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_tll_hs = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_usb_tll_hs_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* 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",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+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,
+ .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,
+ .user = OCP_USER_SDMA,
+};
+
+/* mpu -> emif1 */
+static struct omap_hwmod_ocp_if omap44xx_mpu__emif1 = {
+ .master = &omap44xx_mpu_hwmod,
+ .slave = &omap44xx_emif1_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> emif2 */
+static struct omap_hwmod_ocp_if omap44xx_mpu__emif2 = {
+ .master = &omap44xx_mpu_hwmod,
+ .slave = &omap44xx_emif2_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
+ &omap44xx_l3_main_1__dmm,
+ &omap44xx_mpu__dmm,
+ &omap44xx_iva__l3_instr,
+ &omap44xx_l3_main_3__l3_instr,
+ &omap44xx_ocp_wp_noc__l3_instr,
+ &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,
+ &omap44xx_debugss__l3_main_2,
+ &omap44xx_dma_system__l3_main_2,
+ &omap44xx_fdif__l3_main_2,
+ &omap44xx_gpu__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_host_fs__l3_main_2, */
+ &omap44xx_usb_host_hs__l3_main_2,
+ &omap44xx_usb_otg_hs__l3_main_2,
+ &omap44xx_l3_main_1__l3_main_3,
+ &omap44xx_l3_main_2__l3_main_3,
+ &omap44xx_l4_cfg__l3_main_3,
+ &omap44xx_aess__l4_abe,
+ &omap44xx_dsp__l4_abe,
+ &omap44xx_l3_main_1__l4_abe,
+ &omap44xx_mpu__l4_abe,
+ &omap44xx_l3_main_1__l4_cfg,
+ &omap44xx_l3_main_2__l4_per,
+ &omap44xx_l4_cfg__l4_wkup,
+ &omap44xx_mpu__mpu_private,
+ &omap44xx_l4_cfg__ocp_wp_noc,
+ &omap44xx_l4_abe__aess,
+ &omap44xx_l4_abe__aess_dma,
+ &omap44xx_l3_main_2__c2c,
+ &omap44xx_l4_wkup__counter_32k,
+ &omap44xx_l4_cfg__ctrl_module_core,
+ &omap44xx_l4_cfg__ctrl_module_pad_core,
+ &omap44xx_l4_wkup__ctrl_module_wkup,
+ &omap44xx_l4_wkup__ctrl_module_pad_wkup,
+ &omap44xx_l3_instr__debugss,
+ &omap44xx_l4_cfg__dma_system,
+ &omap44xx_l4_abe__dmic,
+ &omap44xx_dsp__iva,
+ /* &omap44xx_dsp__sl2if, */
+ &omap44xx_l4_cfg__dsp,
+ &omap44xx_l3_main_2__dss,
+ &omap44xx_l4_per__dss,
+ &omap44xx_l3_main_2__dss_dispc,
+ &omap44xx_l4_per__dss_dispc,
+ &omap44xx_l3_main_2__dss_dsi1,
+ &omap44xx_l4_per__dss_dsi1,
+ &omap44xx_l3_main_2__dss_dsi2,
+ &omap44xx_l4_per__dss_dsi2,
+ &omap44xx_l3_main_2__dss_hdmi,
+ &omap44xx_l4_per__dss_hdmi,
+ &omap44xx_l3_main_2__dss_rfbi,
+ &omap44xx_l4_per__dss_rfbi,
+ &omap44xx_l3_main_2__dss_venc,
+ &omap44xx_l4_per__dss_venc,
+ &omap44xx_l4_per__elm,
+ &omap44xx_l4_cfg__fdif,
+ &omap44xx_l4_wkup__gpio1,
+ &omap44xx_l4_per__gpio2,
+ &omap44xx_l4_per__gpio3,
+ &omap44xx_l4_per__gpio4,
+ &omap44xx_l4_per__gpio5,
+ &omap44xx_l4_per__gpio6,
+ &omap44xx_l3_main_2__gpmc,
+ &omap44xx_l3_main_2__gpu,
+ &omap44xx_l4_per__hdq1w,
+ &omap44xx_l4_cfg__hsi,
+ &omap44xx_l4_per__i2c1,
+ &omap44xx_l4_per__i2c2,
+ &omap44xx_l4_per__i2c3,
+ &omap44xx_l4_per__i2c4,
+ &omap44xx_l3_main_2__ipu,
+ &omap44xx_l3_main_2__iss,
+ /* &omap44xx_iva__sl2if, */
+ &omap44xx_l3_main_2__iva,
+ &omap44xx_l4_wkup__kbd,
+ &omap44xx_l4_cfg__mailbox,
+ &omap44xx_l4_abe__mcasp,
+ &omap44xx_l4_abe__mcasp_dma,
+ &omap44xx_l4_abe__mcbsp1,
+ &omap44xx_l4_abe__mcbsp2,
+ &omap44xx_l4_abe__mcbsp3,
+ &omap44xx_l4_per__mcbsp4,
+ &omap44xx_l4_abe__mcpdm,
+ &omap44xx_l4_per__mcspi1,
+ &omap44xx_l4_per__mcspi2,
+ &omap44xx_l4_per__mcspi3,
+ &omap44xx_l4_per__mcspi4,
+ &omap44xx_l4_per__mmc1,
+ &omap44xx_l4_per__mmc2,
+ &omap44xx_l4_per__mmc3,
+ &omap44xx_l4_per__mmc4,
+ &omap44xx_l4_per__mmc5,
+ &omap44xx_l3_main_2__mmu_ipu,
+ &omap44xx_l4_cfg__mmu_dsp,
+ &omap44xx_l3_main_2__ocmc_ram,
+ &omap44xx_l4_cfg__ocp2scp_usb_phy,
+ &omap44xx_mpu_private__prcm_mpu,
+ &omap44xx_l4_wkup__cm_core_aon,
+ &omap44xx_l4_cfg__cm_core,
+ &omap44xx_l4_wkup__prm,
+ &omap44xx_l4_wkup__scrm,
+ /* &omap44xx_l3_main_2__sl2if, */
+ &omap44xx_l4_abe__slimbus1,
+ &omap44xx_l4_abe__slimbus1_dma,
+ &omap44xx_l4_per__slimbus2,
+ &omap44xx_l4_cfg__smartreflex_core,
+ &omap44xx_l4_cfg__smartreflex_iva,
+ &omap44xx_l4_cfg__smartreflex_mpu,
+ &omap44xx_l4_cfg__spinlock,
+ &omap44xx_l4_wkup__timer1,
+ &omap44xx_l4_per__timer2,
+ &omap44xx_l4_per__timer3,
+ &omap44xx_l4_per__timer4,
+ &omap44xx_l4_abe__timer5,
+ &omap44xx_l4_abe__timer6,
+ &omap44xx_l4_abe__timer7,
+ &omap44xx_l4_abe__timer8,
+ &omap44xx_l4_per__timer9,
+ &omap44xx_l4_per__timer10,
+ &omap44xx_l4_per__timer11,
+ &omap44xx_l4_per__uart1,
+ &omap44xx_l4_per__uart2,
+ &omap44xx_l4_per__uart3,
+ &omap44xx_l4_per__uart4,
+ /* &omap44xx_l4_cfg__usb_host_fs, */
+ &omap44xx_l4_cfg__usb_host_hs,
+ &omap44xx_l4_cfg__usb_otg_hs,
+ &omap44xx_l4_cfg__usb_tll_hs,
+ &omap44xx_l4_wkup__wd_timer2,
+ &omap44xx_l4_abe__wd_timer3,
+ &omap44xx_l4_abe__wd_timer3_dma,
+ &omap44xx_mpu__emif1,
+ &omap44xx_mpu__emif2,
+ NULL,
+};
+
+int __init omap44xx_hwmod_init(void)
+{
+ omap_hwmod_init();
+ return omap_hwmod_register_links(omap44xx_hwmod_ocp_ifs);
+}
+
diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
new file mode 100644
index 000000000..7c3fac035
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
@@ -0,0 +1,2854 @@
+/*
+ * Hardware modules present on the OMAP54xx chips
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * 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 <linux/platform_data/gpio-omap.h>
+#include <linux/platform_data/hsmmc-omap.h>
+#include <linux/power/smartreflex.h>
+#include <linux/i2c-omap.h>
+
+#include <linux/omap-dma.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+#include <linux/platform_data/asoc-ti-mcbsp.h>
+#include <plat/dmtimer.h>
+
+#include "omap_hwmod.h"
+#include "omap_hwmod_common_data.h"
+#include "cm1_54xx.h"
+#include "cm2_54xx.h"
+#include "prm54xx.h"
+#include "i2c.h"
+#include "wd_timer.h"
+
+/* Base offset for all OMAP5 interrupts external to MPUSS */
+#define OMAP54XX_IRQ_GIC_START 32
+
+/* Base offset for all OMAP5 dma requests */
+#define OMAP54XX_DMA_REQ_START 1
+
+
+/*
+ * IP blocks
+ */
+
+/*
+ * 'dmm' class
+ * instance(s): dmm
+ */
+static struct omap_hwmod_class omap54xx_dmm_hwmod_class = {
+ .name = "dmm",
+};
+
+/* dmm */
+static struct omap_hwmod omap54xx_dmm_hwmod = {
+ .name = "dmm",
+ .class = &omap54xx_dmm_hwmod_class,
+ .clkdm_name = "emif_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_EMIF_DMM_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_EMIF_DMM_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'l3' class
+ * instance(s): l3_instr, l3_main_1, l3_main_2, l3_main_3
+ */
+static struct omap_hwmod_class omap54xx_l3_hwmod_class = {
+ .name = "l3",
+};
+
+/* l3_instr */
+static struct omap_hwmod omap54xx_l3_instr_hwmod = {
+ .name = "l3_instr",
+ .class = &omap54xx_l3_hwmod_class,
+ .clkdm_name = "l3instr_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/* l3_main_1 */
+static struct omap_hwmod omap54xx_l3_main_1_hwmod = {
+ .name = "l3_main_1",
+ .class = &omap54xx_l3_hwmod_class,
+ .clkdm_name = "l3main1_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L3MAIN1_L3_MAIN_1_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L3MAIN1_L3_MAIN_1_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* l3_main_2 */
+static struct omap_hwmod omap54xx_l3_main_2_hwmod = {
+ .name = "l3_main_2",
+ .class = &omap54xx_l3_hwmod_class,
+ .clkdm_name = "l3main2_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L3MAIN2_L3_MAIN_2_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L3MAIN2_L3_MAIN_2_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* l3_main_3 */
+static struct omap_hwmod omap54xx_l3_main_3_hwmod = {
+ .name = "l3_main_3",
+ .class = &omap54xx_l3_hwmod_class,
+ .clkdm_name = "l3instr_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L3INSTR_L3_MAIN_3_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L3INSTR_L3_MAIN_3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * 'l4' class
+ * instance(s): l4_abe, l4_cfg, l4_per, l4_wkup
+ */
+static struct omap_hwmod_class omap54xx_l4_hwmod_class = {
+ .name = "l4",
+};
+
+/* l4_abe */
+static struct omap_hwmod omap54xx_l4_abe_hwmod = {
+ .name = "l4_abe",
+ .class = &omap54xx_l4_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_ABE_L4_ABE_CLKCTRL_OFFSET,
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+};
+
+/* l4_cfg */
+static struct omap_hwmod omap54xx_l4_cfg_hwmod = {
+ .name = "l4_cfg",
+ .class = &omap54xx_l4_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4CFG_L4_CFG_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* l4_per */
+static struct omap_hwmod omap54xx_l4_per_hwmod = {
+ .name = "l4_per",
+ .class = &omap54xx_l4_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_L4_PER_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_L4_PER_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* l4_wkup */
+static struct omap_hwmod omap54xx_l4_wkup_hwmod = {
+ .name = "l4_wkup",
+ .class = &omap54xx_l4_hwmod_class,
+ .clkdm_name = "wkupaon_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_WKUPAON_L4_WKUP_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_WKUPAON_L4_WKUP_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'mpu_bus' class
+ * instance(s): mpu_private
+ */
+static struct omap_hwmod_class omap54xx_mpu_bus_hwmod_class = {
+ .name = "mpu_bus",
+};
+
+/* mpu_private */
+static struct omap_hwmod omap54xx_mpu_private_hwmod = {
+ .name = "mpu_private",
+ .class = &omap54xx_mpu_bus_hwmod_class,
+ .clkdm_name = "mpu_clkdm",
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+};
+
+/*
+ * 'counter' class
+ * 32-bit ordinary counter, clocked by the falling edge of the 32 khz clock
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_counter_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap54xx_counter_hwmod_class = {
+ .name = "counter",
+ .sysc = &omap54xx_counter_sysc,
+};
+
+/* counter_32k */
+static struct omap_hwmod omap54xx_counter_32k_hwmod = {
+ .name = "counter_32k",
+ .class = &omap54xx_counter_hwmod_class,
+ .clkdm_name = "wkupaon_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE,
+ .main_clk = "wkupaon_iclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_WKUPAON_COUNTER_32K_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_WKUPAON_COUNTER_32K_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * '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 omap54xx_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 omap54xx_dma_hwmod_class = {
+ .name = "dma",
+ .sysc = &omap54xx_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 omap54xx_dma_system_irqs[] = {
+ { .name = "0", .irq = 12 + OMAP54XX_IRQ_GIC_START },
+ { .name = "1", .irq = 13 + OMAP54XX_IRQ_GIC_START },
+ { .name = "2", .irq = 14 + OMAP54XX_IRQ_GIC_START },
+ { .name = "3", .irq = 15 + OMAP54XX_IRQ_GIC_START },
+ { .irq = -1 }
+};
+
+static struct omap_hwmod omap54xx_dma_system_hwmod = {
+ .name = "dma_system",
+ .class = &omap54xx_dma_hwmod_class,
+ .clkdm_name = "dma_clkdm",
+ .mpu_irqs = omap54xx_dma_system_irqs,
+ .xlate_irq = omap4_xlate_irq,
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_DMA_DMA_SYSTEM_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_DMA_DMA_SYSTEM_CONTEXT_OFFSET,
+ },
+ },
+ .dev_attr = &dma_dev_attr,
+};
+
+/*
+ * 'dmic' class
+ * digital microphone controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_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 omap54xx_dmic_hwmod_class = {
+ .name = "dmic",
+ .sysc = &omap54xx_dmic_sysc,
+};
+
+/* dmic */
+static struct omap_hwmod omap54xx_dmic_hwmod = {
+ .name = "dmic",
+ .class = &omap54xx_dmic_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "dmic_gfclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_ABE_DMIC_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_ABE_DMIC_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'dss' class
+ * display sub-system
+ */
+static struct omap_hwmod_class_sysconfig omap54xx_dss_sysc = {
+ .rev_offs = 0x0000,
+ .syss_offs = 0x0014,
+ .sysc_flags = SYSS_HAS_RESET_STATUS,
+};
+
+static struct omap_hwmod_class omap54xx_dss_hwmod_class = {
+ .name = "dss",
+ .sysc = &omap54xx_dss_sysc,
+ .reset = omap_dss_reset,
+};
+
+/* dss */
+static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+ { .role = "32khz_clk", .clk = "dss_32khz_clk" },
+ { .role = "sys_clk", .clk = "dss_sys_clk" },
+ { .role = "hdmi_clk", .clk = "dss_48mhz_clk" },
+};
+
+static struct omap_hwmod omap54xx_dss_hwmod = {
+ .name = "dss_core",
+ .class = &omap54xx_dss_hwmod_class,
+ .clkdm_name = "dss_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "dss_dss_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = dss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks),
+};
+
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_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 omap54xx_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &omap54xx_dispc_sysc,
+};
+
+/* dss_dispc */
+static struct omap_hwmod_opt_clk dss_dispc_opt_clks[] = {
+ { .role = "sys_clk", .clk = "dss_sys_clk" },
+};
+
+/* dss_dispc dev_attr */
+static struct omap_dss_dispc_dev_attr dss_dispc_dev_attr = {
+ .has_framedonetv_irq = 1,
+ .manager_count = 4,
+};
+
+static struct omap_hwmod omap54xx_dss_dispc_hwmod = {
+ .name = "dss_dispc",
+ .class = &omap54xx_dispc_hwmod_class,
+ .clkdm_name = "dss_clkdm",
+ .main_clk = "dss_dss_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+ .opt_clks = dss_dispc_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_dispc_opt_clks),
+ .dev_attr = &dss_dispc_dev_attr,
+ .parent_hwmod = &omap54xx_dss_hwmod,
+};
+
+/*
+ * 'dsi1' class
+ * display serial interface controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_dsi1_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 omap54xx_dsi1_hwmod_class = {
+ .name = "dsi1",
+ .sysc = &omap54xx_dsi1_sysc,
+};
+
+/* dss_dsi1_a */
+static struct omap_hwmod_opt_clk dss_dsi1_a_opt_clks[] = {
+ { .role = "sys_clk", .clk = "dss_sys_clk" },
+};
+
+static struct omap_hwmod omap54xx_dss_dsi1_a_hwmod = {
+ .name = "dss_dsi1",
+ .class = &omap54xx_dsi1_hwmod_class,
+ .clkdm_name = "dss_clkdm",
+ .main_clk = "dss_dss_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+ .opt_clks = dss_dsi1_a_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_a_opt_clks),
+ .parent_hwmod = &omap54xx_dss_hwmod,
+};
+
+/* dss_dsi1_c */
+static struct omap_hwmod_opt_clk dss_dsi1_c_opt_clks[] = {
+ { .role = "sys_clk", .clk = "dss_sys_clk" },
+};
+
+static struct omap_hwmod omap54xx_dss_dsi1_c_hwmod = {
+ .name = "dss_dsi2",
+ .class = &omap54xx_dsi1_hwmod_class,
+ .clkdm_name = "dss_clkdm",
+ .main_clk = "dss_dss_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+ .opt_clks = dss_dsi1_c_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_c_opt_clks),
+ .parent_hwmod = &omap54xx_dss_hwmod,
+};
+
+/*
+ * 'hdmi' class
+ * hdmi controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_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 omap54xx_hdmi_hwmod_class = {
+ .name = "hdmi",
+ .sysc = &omap54xx_hdmi_sysc,
+};
+
+static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = {
+ { .role = "sys_clk", .clk = "dss_sys_clk" },
+};
+
+static struct omap_hwmod omap54xx_dss_hdmi_hwmod = {
+ .name = "dss_hdmi",
+ .class = &omap54xx_hdmi_hwmod_class,
+ .clkdm_name = "dss_clkdm",
+ .main_clk = "dss_48mhz_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+ .opt_clks = dss_hdmi_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks),
+ .parent_hwmod = &omap54xx_dss_hwmod,
+};
+
+/*
+ * 'rfbi' class
+ * remote frame buffer interface
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_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 omap54xx_rfbi_hwmod_class = {
+ .name = "rfbi",
+ .sysc = &omap54xx_rfbi_sysc,
+};
+
+/* dss_rfbi */
+static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = {
+ { .role = "ick", .clk = "l3_iclk_div" },
+};
+
+static struct omap_hwmod omap54xx_dss_rfbi_hwmod = {
+ .name = "dss_rfbi",
+ .class = &omap54xx_rfbi_hwmod_class,
+ .clkdm_name = "dss_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+ .opt_clks = dss_rfbi_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks),
+ .parent_hwmod = &omap54xx_dss_hwmod,
+};
+
+/*
+ * 'emif' class
+ * external memory interface no1 (wrapper)
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_emif_sysc = {
+ .rev_offs = 0x0000,
+};
+
+static struct omap_hwmod_class omap54xx_emif_hwmod_class = {
+ .name = "emif",
+ .sysc = &omap54xx_emif_sysc,
+};
+
+/* emif1 */
+static struct omap_hwmod omap54xx_emif1_hwmod = {
+ .name = "emif1",
+ .class = &omap54xx_emif_hwmod_class,
+ .clkdm_name = "emif_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "dpll_core_h11x2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_EMIF_EMIF1_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_EMIF_EMIF1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/* emif2 */
+static struct omap_hwmod omap54xx_emif2_hwmod = {
+ .name = "emif2",
+ .class = &omap54xx_emif_hwmod_class,
+ .clkdm_name = "emif_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "dpll_core_h11x2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_EMIF_EMIF2_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_EMIF_EMIF2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * 'gpio' class
+ * general purpose io module
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_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 omap54xx_gpio_hwmod_class = {
+ .name = "gpio",
+ .sysc = &omap54xx_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_opt_clk gpio1_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio1_dbclk" },
+};
+
+static struct omap_hwmod omap54xx_gpio1_hwmod = {
+ .name = "gpio1",
+ .class = &omap54xx_gpio_hwmod_class,
+ .clkdm_name = "wkupaon_clkdm",
+ .main_clk = "wkupaon_iclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_WKUPAON_GPIO1_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_WKUPAON_GPIO1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio2 */
+static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio2_dbclk" },
+};
+
+static struct omap_hwmod omap54xx_gpio2_hwmod = {
+ .name = "gpio2",
+ .class = &omap54xx_gpio_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4_root_clk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO2_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_GPIO2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio3 */
+static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio3_dbclk" },
+};
+
+static struct omap_hwmod omap54xx_gpio3_hwmod = {
+ .name = "gpio3",
+ .class = &omap54xx_gpio_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4_root_clk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO3_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_GPIO3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio3_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio4 */
+static struct omap_hwmod_opt_clk gpio4_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio4_dbclk" },
+};
+
+static struct omap_hwmod omap54xx_gpio4_hwmod = {
+ .name = "gpio4",
+ .class = &omap54xx_gpio_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4_root_clk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO4_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_GPIO4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio4_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio5 */
+static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio5_dbclk" },
+};
+
+static struct omap_hwmod omap54xx_gpio5_hwmod = {
+ .name = "gpio5",
+ .class = &omap54xx_gpio_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4_root_clk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO5_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_GPIO5_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio5_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio6 */
+static struct omap_hwmod_opt_clk gpio6_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio6_dbclk" },
+};
+
+static struct omap_hwmod omap54xx_gpio6_hwmod = {
+ .name = "gpio6",
+ .class = &omap54xx_gpio_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4_root_clk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO6_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_GPIO6_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio6_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio7 */
+static struct omap_hwmod_opt_clk gpio7_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio7_dbclk" },
+};
+
+static struct omap_hwmod omap54xx_gpio7_hwmod = {
+ .name = "gpio7",
+ .class = &omap54xx_gpio_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4_root_clk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO7_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_GPIO7_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio7_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio7_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio8 */
+static struct omap_hwmod_opt_clk gpio8_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio8_dbclk" },
+};
+
+static struct omap_hwmod omap54xx_gpio8_hwmod = {
+ .name = "gpio8",
+ .class = &omap54xx_gpio_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l4_root_clk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO8_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_GPIO8_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio8_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio8_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/*
+ * 'i2c' class
+ * multimaster high-speed i2c controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_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),
+ .clockact = CLOCKACT_TEST_ICLK,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap54xx_i2c_hwmod_class = {
+ .name = "i2c",
+ .sysc = &omap54xx_i2c_sysc,
+ .reset = &omap_i2c_reset,
+ .rev = OMAP_I2C_IP_VERSION_2,
+};
+
+/* i2c dev_attr */
+static struct omap_i2c_dev_attr i2c_dev_attr = {
+ .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE,
+};
+
+/* i2c1 */
+static struct omap_hwmod omap54xx_i2c1_hwmod = {
+ .name = "i2c1",
+ .class = &omap54xx_i2c_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "func_96m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_I2C1_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_I2C1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/* i2c2 */
+static struct omap_hwmod omap54xx_i2c2_hwmod = {
+ .name = "i2c2",
+ .class = &omap54xx_i2c_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "func_96m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_I2C2_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_I2C2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/* i2c3 */
+static struct omap_hwmod omap54xx_i2c3_hwmod = {
+ .name = "i2c3",
+ .class = &omap54xx_i2c_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "func_96m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_I2C3_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_I2C3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/* i2c4 */
+static struct omap_hwmod omap54xx_i2c4_hwmod = {
+ .name = "i2c4",
+ .class = &omap54xx_i2c_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "func_96m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_I2C4_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_I2C4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/* i2c5 */
+static struct omap_hwmod omap54xx_i2c5_hwmod = {
+ .name = "i2c5",
+ .class = &omap54xx_i2c_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "func_96m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_I2C5_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_I2C5_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/*
+ * 'kbd' class
+ * keyboard controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_kbd_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap54xx_kbd_hwmod_class = {
+ .name = "kbd",
+ .sysc = &omap54xx_kbd_sysc,
+};
+
+/* kbd */
+static struct omap_hwmod omap54xx_kbd_hwmod = {
+ .name = "kbd",
+ .class = &omap54xx_kbd_hwmod_class,
+ .clkdm_name = "wkupaon_clkdm",
+ .main_clk = "sys_32k_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_WKUPAON_KBD_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_WKUPAON_KBD_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'mailbox' class
+ * mailbox module allowing communication between the on-chip processors using a
+ * queued mailbox-interrupt mechanism.
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_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 omap54xx_mailbox_hwmod_class = {
+ .name = "mailbox",
+ .sysc = &omap54xx_mailbox_sysc,
+};
+
+/* mailbox */
+static struct omap_hwmod omap54xx_mailbox_hwmod = {
+ .name = "mailbox",
+ .class = &omap54xx_mailbox_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4CFG_MAILBOX_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'mcbsp' class
+ * multi channel buffered serial port controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_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 omap54xx_mcbsp_hwmod_class = {
+ .name = "mcbsp",
+ .sysc = &omap54xx_mcbsp_sysc,
+ .rev = MCBSP_CONFIG_TYPE4,
+};
+
+/* mcbsp1 */
+static struct omap_hwmod_opt_clk mcbsp1_opt_clks[] = {
+ { .role = "pad_fck", .clk = "pad_clks_ck" },
+ { .role = "prcm_fck", .clk = "mcbsp1_sync_mux_ck" },
+};
+
+static struct omap_hwmod omap54xx_mcbsp1_hwmod = {
+ .name = "mcbsp1",
+ .class = &omap54xx_mcbsp_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "mcbsp1_gfclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_ABE_MCBSP1_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_ABE_MCBSP1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = mcbsp1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp1_opt_clks),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod_opt_clk mcbsp2_opt_clks[] = {
+ { .role = "pad_fck", .clk = "pad_clks_ck" },
+ { .role = "prcm_fck", .clk = "mcbsp2_sync_mux_ck" },
+};
+
+static struct omap_hwmod omap54xx_mcbsp2_hwmod = {
+ .name = "mcbsp2",
+ .class = &omap54xx_mcbsp_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "mcbsp2_gfclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_ABE_MCBSP2_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_ABE_MCBSP2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = mcbsp2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp2_opt_clks),
+};
+
+/* mcbsp3 */
+static struct omap_hwmod_opt_clk mcbsp3_opt_clks[] = {
+ { .role = "pad_fck", .clk = "pad_clks_ck" },
+ { .role = "prcm_fck", .clk = "mcbsp3_sync_mux_ck" },
+};
+
+static struct omap_hwmod omap54xx_mcbsp3_hwmod = {
+ .name = "mcbsp3",
+ .class = &omap54xx_mcbsp_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "mcbsp3_gfclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_ABE_MCBSP3_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_ABE_MCBSP3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = mcbsp3_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcbsp3_opt_clks),
+};
+
+/*
+ * 'mcpdm' class
+ * multi channel pdm controller (proprietary interface with phoenix power
+ * ic)
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_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 omap54xx_mcpdm_hwmod_class = {
+ .name = "mcpdm",
+ .sysc = &omap54xx_mcpdm_sysc,
+};
+
+/* mcpdm */
+static struct omap_hwmod omap54xx_mcpdm_hwmod = {
+ .name = "mcpdm",
+ .class = &omap54xx_mcpdm_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ /*
+ * It's suspected that the McPDM requires an off-chip main
+ * functional clock, controlled via I2C. This IP block is
+ * currently reset very early during boot, before I2C is
+ * available, so it doesn't seem that we have any choice in
+ * the kernel other than to avoid resetting it. XXX This is
+ * really a hardware issue workaround: every IP block should
+ * be able to source its main functional clock from either
+ * on-chip or off-chip sources. McPDM seems to be the only
+ * current exception.
+ */
+
+ .flags = HWMOD_EXT_OPT_MAIN_CLK | HWMOD_SWSUP_SIDLE,
+ .main_clk = "pad_clks_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_ABE_MCPDM_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_ABE_MCPDM_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'mcspi' class
+ * multichannel serial port interface (mcspi) / master/slave synchronous serial
+ * bus
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_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 omap54xx_mcspi_hwmod_class = {
+ .name = "mcspi",
+ .sysc = &omap54xx_mcspi_sysc,
+ .rev = OMAP4_MCSPI_REV,
+};
+
+/* mcspi1 */
+/* mcspi1 dev_attr */
+static struct omap2_mcspi_dev_attr mcspi1_dev_attr = {
+ .num_chipselect = 4,
+};
+
+static struct omap_hwmod omap54xx_mcspi1_hwmod = {
+ .name = "mcspi1",
+ .class = &omap54xx_mcspi_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI1_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_MCSPI1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi1_dev_attr,
+};
+
+/* mcspi2 */
+/* mcspi2 dev_attr */
+static struct omap2_mcspi_dev_attr mcspi2_dev_attr = {
+ .num_chipselect = 2,
+};
+
+static struct omap_hwmod omap54xx_mcspi2_hwmod = {
+ .name = "mcspi2",
+ .class = &omap54xx_mcspi_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI2_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_MCSPI2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi2_dev_attr,
+};
+
+/* mcspi3 */
+/* mcspi3 dev_attr */
+static struct omap2_mcspi_dev_attr mcspi3_dev_attr = {
+ .num_chipselect = 2,
+};
+
+static struct omap_hwmod omap54xx_mcspi3_hwmod = {
+ .name = "mcspi3",
+ .class = &omap54xx_mcspi_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI3_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_MCSPI3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi3_dev_attr,
+};
+
+/* mcspi4 */
+/* mcspi4 dev_attr */
+static struct omap2_mcspi_dev_attr mcspi4_dev_attr = {
+ .num_chipselect = 1,
+};
+
+static struct omap_hwmod omap54xx_mcspi4_hwmod = {
+ .name = "mcspi4",
+ .class = &omap54xx_mcspi_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI4_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_MCSPI4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi4_dev_attr,
+};
+
+/*
+ * 'mmc' class
+ * multimedia card high-speed/sd/sdio (mmc/sd/sdio) host controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_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 | MSTANDBY_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap54xx_mmc_hwmod_class = {
+ .name = "mmc",
+ .sysc = &omap54xx_mmc_sysc,
+};
+
+/* mmc1 */
+static struct omap_hwmod_opt_clk mmc1_opt_clks[] = {
+ { .role = "32khz_clk", .clk = "mmc1_32khz_clk" },
+};
+
+/* mmc1 dev_attr */
+static struct omap_hsmmc_dev_attr mmc1_dev_attr = {
+ .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
+};
+
+static struct omap_hwmod omap54xx_mmc1_hwmod = {
+ .name = "mmc1",
+ .class = &omap54xx_mmc_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ .main_clk = "mmc1_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L3INIT_MMC1_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L3INIT_MMC1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = mmc1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mmc1_opt_clks),
+ .dev_attr = &mmc1_dev_attr,
+};
+
+/* mmc2 */
+static struct omap_hwmod omap54xx_mmc2_hwmod = {
+ .name = "mmc2",
+ .class = &omap54xx_mmc_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ .main_clk = "mmc2_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L3INIT_MMC2_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L3INIT_MMC2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* mmc3 */
+static struct omap_hwmod omap54xx_mmc3_hwmod = {
+ .name = "mmc3",
+ .class = &omap54xx_mmc_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_MMC3_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_MMC3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* mmc4 */
+static struct omap_hwmod omap54xx_mmc4_hwmod = {
+ .name = "mmc4",
+ .class = &omap54xx_mmc_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_MMC4_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_MMC4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* mmc5 */
+static struct omap_hwmod omap54xx_mmc5_hwmod = {
+ .name = "mmc5",
+ .class = &omap54xx_mmc_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "func_96m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_MMC5_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_MMC5_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'mmu' class
+ * The memory management unit performs virtual to physical address translation
+ * for its requestors.
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_mmu_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+ 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 omap54xx_mmu_hwmod_class = {
+ .name = "mmu",
+ .sysc = &omap54xx_mmu_sysc,
+};
+
+static struct omap_hwmod_rst_info omap54xx_mmu_dsp_resets[] = {
+ { .name = "mmu_cache", .rst_shift = 1 },
+};
+
+static struct omap_hwmod omap54xx_mmu_dsp_hwmod = {
+ .name = "mmu_dsp",
+ .class = &omap54xx_mmu_hwmod_class,
+ .clkdm_name = "dsp_clkdm",
+ .rst_lines = omap54xx_mmu_dsp_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap54xx_mmu_dsp_resets),
+ .main_clk = "dpll_iva_h11x2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_DSP_DSP_CLKCTRL_OFFSET,
+ .rstctrl_offs = OMAP54XX_RM_DSP_RSTCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_DSP_DSP_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/* mmu ipu */
+static struct omap_hwmod_rst_info omap54xx_mmu_ipu_resets[] = {
+ { .name = "mmu_cache", .rst_shift = 2 },
+};
+
+static struct omap_hwmod omap54xx_mmu_ipu_hwmod = {
+ .name = "mmu_ipu",
+ .class = &omap54xx_mmu_hwmod_class,
+ .clkdm_name = "ipu_clkdm",
+ .rst_lines = omap54xx_mmu_ipu_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap54xx_mmu_ipu_resets),
+ .main_clk = "dpll_core_h22x2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_IPU_IPU_CLKCTRL_OFFSET,
+ .rstctrl_offs = OMAP54XX_RM_IPU_RSTCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_IPU_IPU_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * 'mpu' class
+ * mpu sub-system
+ */
+
+static struct omap_hwmod_class omap54xx_mpu_hwmod_class = {
+ .name = "mpu",
+};
+
+/* mpu */
+static struct omap_hwmod omap54xx_mpu_hwmod = {
+ .name = "mpu",
+ .class = &omap54xx_mpu_hwmod_class,
+ .clkdm_name = "mpu_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "dpll_mpu_m2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_MPU_MPU_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_MPU_MPU_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'spinlock' class
+ * spinlock provides hardware assistance for synchronizing the processes
+ * running on multiple processors
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_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),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap54xx_spinlock_hwmod_class = {
+ .name = "spinlock",
+ .sysc = &omap54xx_spinlock_sysc,
+};
+
+/* spinlock */
+static struct omap_hwmod omap54xx_spinlock_hwmod = {
+ .name = "spinlock",
+ .class = &omap54xx_spinlock_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4CFG_SPINLOCK_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4CFG_SPINLOCK_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'ocp2scp' class
+ * bridge to transform ocp interface protocol to scp (serial control port)
+ * protocol
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_ocp2scp_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 omap54xx_ocp2scp_hwmod_class = {
+ .name = "ocp2scp",
+ .sysc = &omap54xx_ocp2scp_sysc,
+};
+
+/* ocp2scp1 */
+static struct omap_hwmod omap54xx_ocp2scp1_hwmod = {
+ .name = "ocp2scp1",
+ .class = &omap54xx_ocp2scp_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ .main_clk = "l4_root_clk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L3INIT_OCP2SCP1_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L3INIT_OCP2SCP1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * 'timer' class
+ * general purpose timer module with accurate 1ms tick
+ * This class contains several variants: ['timer_1ms', 'timer']
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_timer_1ms_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,
+ .clockact = CLOCKACT_TEST_ICLK,
+};
+
+static struct omap_hwmod_class omap54xx_timer_1ms_hwmod_class = {
+ .name = "timer",
+ .sysc = &omap54xx_timer_1ms_sysc,
+};
+
+static struct omap_hwmod_class_sysconfig omap54xx_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 omap54xx_timer_hwmod_class = {
+ .name = "timer",
+ .sysc = &omap54xx_timer_sysc,
+};
+
+/* timer1 */
+static struct omap_hwmod omap54xx_timer1_hwmod = {
+ .name = "timer1",
+ .class = &omap54xx_timer_1ms_hwmod_class,
+ .clkdm_name = "wkupaon_clkdm",
+ .main_clk = "timer1_gfclk_mux",
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_WKUPAON_TIMER1_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_WKUPAON_TIMER1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer2 */
+static struct omap_hwmod omap54xx_timer2_hwmod = {
+ .name = "timer2",
+ .class = &omap54xx_timer_1ms_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "timer2_gfclk_mux",
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER2_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_TIMER2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer3 */
+static struct omap_hwmod omap54xx_timer3_hwmod = {
+ .name = "timer3",
+ .class = &omap54xx_timer_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "timer3_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER3_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_TIMER3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer4 */
+static struct omap_hwmod omap54xx_timer4_hwmod = {
+ .name = "timer4",
+ .class = &omap54xx_timer_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "timer4_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER4_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_TIMER4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer5 */
+static struct omap_hwmod omap54xx_timer5_hwmod = {
+ .name = "timer5",
+ .class = &omap54xx_timer_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "timer5_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_ABE_TIMER5_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_ABE_TIMER5_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer6 */
+static struct omap_hwmod omap54xx_timer6_hwmod = {
+ .name = "timer6",
+ .class = &omap54xx_timer_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "timer6_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_ABE_TIMER6_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_ABE_TIMER6_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer7 */
+static struct omap_hwmod omap54xx_timer7_hwmod = {
+ .name = "timer7",
+ .class = &omap54xx_timer_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "timer7_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_ABE_TIMER7_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_ABE_TIMER7_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer8 */
+static struct omap_hwmod omap54xx_timer8_hwmod = {
+ .name = "timer8",
+ .class = &omap54xx_timer_hwmod_class,
+ .clkdm_name = "abe_clkdm",
+ .main_clk = "timer8_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_ABE_TIMER8_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_ABE_TIMER8_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer9 */
+static struct omap_hwmod omap54xx_timer9_hwmod = {
+ .name = "timer9",
+ .class = &omap54xx_timer_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "timer9_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER9_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_TIMER9_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer10 */
+static struct omap_hwmod omap54xx_timer10_hwmod = {
+ .name = "timer10",
+ .class = &omap54xx_timer_1ms_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "timer10_gfclk_mux",
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER10_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_TIMER10_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer11 */
+static struct omap_hwmod omap54xx_timer11_hwmod = {
+ .name = "timer11",
+ .class = &omap54xx_timer_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "timer11_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER11_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_TIMER11_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'uart' class
+ * universal asynchronous receiver/transmitter (uart)
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_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 omap54xx_uart_hwmod_class = {
+ .name = "uart",
+ .sysc = &omap54xx_uart_sysc,
+};
+
+/* uart1 */
+static struct omap_hwmod omap54xx_uart1_hwmod = {
+ .name = "uart1",
+ .class = &omap54xx_uart_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_UART1_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_UART1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart2 */
+static struct omap_hwmod omap54xx_uart2_hwmod = {
+ .name = "uart2",
+ .class = &omap54xx_uart_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_UART2_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_UART2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart3 */
+static struct omap_hwmod omap54xx_uart3_hwmod = {
+ .name = "uart3",
+ .class = &omap54xx_uart_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = DEBUG_OMAP4UART3_FLAGS,
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_UART3_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_UART3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart4 */
+static struct omap_hwmod omap54xx_uart4_hwmod = {
+ .name = "uart4",
+ .class = &omap54xx_uart_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = DEBUG_OMAP4UART4_FLAGS,
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_UART4_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_UART4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart5 */
+static struct omap_hwmod omap54xx_uart5_hwmod = {
+ .name = "uart5",
+ .class = &omap54xx_uart_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_UART5_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_UART5_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart6 */
+static struct omap_hwmod omap54xx_uart6_hwmod = {
+ .name = "uart6",
+ .class = &omap54xx_uart_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L4PER_UART6_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L4PER_UART6_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'usb_host_hs' class
+ * high-speed multi-port usb host controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_usb_host_hs_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+ MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap54xx_usb_host_hs_hwmod_class = {
+ .name = "usb_host_hs",
+ .sysc = &omap54xx_usb_host_hs_sysc,
+};
+
+static struct omap_hwmod omap54xx_usb_host_hs_hwmod = {
+ .name = "usb_host_hs",
+ .class = &omap54xx_usb_host_hs_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ /*
+ * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock
+ * id: i660
+ *
+ * Description:
+ * In the following configuration :
+ * - USBHOST module is set to smart-idle mode
+ * - PRCM asserts idle_req to the USBHOST module ( This typically
+ * happens when the system is going to a low power mode : all ports
+ * have been suspended, the master part of the USBHOST module has
+ * entered the standby state, and SW has cut the functional clocks)
+ * - an USBHOST interrupt occurs before the module is able to answer
+ * idle_ack, typically a remote wakeup IRQ.
+ * Then the USB HOST module will enter a deadlock situation where it
+ * is no more accessible nor functional.
+ *
+ * Workaround:
+ * Don't use smart idle; use only force idle, hence HWMOD_SWSUP_SIDLE
+ */
+
+ /*
+ * Errata: USB host EHCI may stall when entering smart-standby mode
+ * Id: i571
+ *
+ * Description:
+ * When the USBHOST module is set to smart-standby mode, and when it is
+ * ready to enter the standby state (i.e. all ports are suspended and
+ * all attached devices are in suspend mode), then it can wrongly assert
+ * the Mstandby signal too early while there are still some residual OCP
+ * transactions ongoing. If this condition occurs, the internal state
+ * machine may go to an undefined state and the USB link may be stuck
+ * upon the next resume.
+ *
+ * Workaround:
+ * Don't use smart standby; use only force standby,
+ * hence HWMOD_SWSUP_MSTANDBY
+ */
+
+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+ .main_clk = "l3init_60m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L3INIT_USB_HOST_HS_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'usb_tll_hs' class
+ * usb_tll_hs module is the adapter on the usb_host_hs ports
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_usb_tll_hs_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 omap54xx_usb_tll_hs_hwmod_class = {
+ .name = "usb_tll_hs",
+ .sysc = &omap54xx_usb_tll_hs_sysc,
+};
+
+static struct omap_hwmod omap54xx_usb_tll_hs_hwmod = {
+ .name = "usb_tll_hs",
+ .class = &omap54xx_usb_tll_hs_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ .main_clk = "l4_root_clk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L3INIT_USB_TLL_HS_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L3INIT_USB_TLL_HS_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * 'usb_otg_ss' class
+ * 2.0 super speed (usb_otg_ss) controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_usb_otg_ss_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = (SYSC_HAS_DMADISABLE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SIDLEMODE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+ MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap54xx_usb_otg_ss_hwmod_class = {
+ .name = "usb_otg_ss",
+ .sysc = &omap54xx_usb_otg_ss_sysc,
+};
+
+/* usb_otg_ss */
+static struct omap_hwmod_opt_clk usb_otg_ss_opt_clks[] = {
+ { .role = "refclk960m", .clk = "usb_otg_ss_refclk960m" },
+};
+
+static struct omap_hwmod omap54xx_usb_otg_ss_hwmod = {
+ .name = "usb_otg_ss",
+ .class = &omap54xx_usb_otg_ss_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE,
+ .main_clk = "dpll_core_h13x2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L3INIT_USB_OTG_SS_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L3INIT_USB_OTG_SS_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = usb_otg_ss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(usb_otg_ss_opt_clks),
+};
+
+/*
+ * '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 omap54xx_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 omap54xx_wd_timer_hwmod_class = {
+ .name = "wd_timer",
+ .sysc = &omap54xx_wd_timer_sysc,
+ .pre_shutdown = &omap2_wd_timer_disable,
+};
+
+/* wd_timer2 */
+static struct omap_hwmod omap54xx_wd_timer2_hwmod = {
+ .name = "wd_timer2",
+ .class = &omap54xx_wd_timer_hwmod_class,
+ .clkdm_name = "wkupaon_clkdm",
+ .main_clk = "sys_32k_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_WKUPAON_WD_TIMER2_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_WKUPAON_WD_TIMER2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'ocp2scp' class
+ * bridge to transform ocp interface protocol to scp (serial control port)
+ * protocol
+ */
+/* ocp2scp3 */
+static struct omap_hwmod omap54xx_ocp2scp3_hwmod;
+/* l4_cfg -> ocp2scp3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__ocp2scp3 = {
+ .master = &omap54xx_l4_cfg_hwmod,
+ .slave = &omap54xx_ocp2scp3_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod omap54xx_ocp2scp3_hwmod = {
+ .name = "ocp2scp3",
+ .class = &omap54xx_ocp2scp_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L3INIT_OCP2SCP3_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L3INIT_OCP2SCP3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * 'sata' class
+ * sata: serial ata interface gen2 compliant ( 1 rx/ 1 tx)
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_sata_sysc = {
+ .sysc_offs = 0x0000,
+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+ MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap54xx_sata_hwmod_class = {
+ .name = "sata",
+ .sysc = &omap54xx_sata_sysc,
+};
+
+/* sata */
+static struct omap_hwmod omap54xx_sata_hwmod = {
+ .name = "sata",
+ .class = &omap54xx_sata_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+ .main_clk = "func_48m_fclk",
+ .mpu_rt_idx = 1,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP54XX_CM_L3INIT_SATA_CLKCTRL_OFFSET,
+ .context_offs = OMAP54XX_RM_L3INIT_SATA_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* l4_cfg -> sata */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__sata = {
+ .master = &omap54xx_l4_cfg_hwmod,
+ .slave = &omap54xx_sata_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/*
+ * Interfaces
+ */
+
+/* l3_main_1 -> dmm */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_1__dmm = {
+ .master = &omap54xx_l3_main_1_hwmod,
+ .slave = &omap54xx_dmm_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_SDMA,
+};
+
+/* l3_main_3 -> l3_instr */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_3__l3_instr = {
+ .master = &omap54xx_l3_main_3_hwmod,
+ .slave = &omap54xx_l3_instr_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__l3_main_1 = {
+ .master = &omap54xx_l3_main_2_hwmod,
+ .slave = &omap54xx_l3_main_1_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__l3_main_1 = {
+ .master = &omap54xx_l4_cfg_hwmod,
+ .slave = &omap54xx_l3_main_1_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> mmu_dsp */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mmu_dsp = {
+ .master = &omap54xx_l4_cfg_hwmod,
+ .slave = &omap54xx_mmu_dsp_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap54xx_mpu__l3_main_1 = {
+ .master = &omap54xx_mpu_hwmod,
+ .slave = &omap54xx_l3_main_1_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU,
+};
+
+/* l3_main_1 -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l3_main_2 = {
+ .master = &omap54xx_l3_main_1_hwmod,
+ .slave = &omap54xx_l3_main_2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU,
+};
+
+/* l4_cfg -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__l3_main_2 = {
+ .master = &omap54xx_l4_cfg_hwmod,
+ .slave = &omap54xx_l3_main_2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> mmu_ipu */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__mmu_ipu = {
+ .master = &omap54xx_l3_main_2_hwmod,
+ .slave = &omap54xx_mmu_ipu_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> l3_main_3 */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l3_main_3 = {
+ .master = &omap54xx_l3_main_1_hwmod,
+ .slave = &omap54xx_l3_main_3_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU,
+};
+
+/* l3_main_2 -> l3_main_3 */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__l3_main_3 = {
+ .master = &omap54xx_l3_main_2_hwmod,
+ .slave = &omap54xx_l3_main_3_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> l3_main_3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__l3_main_3 = {
+ .master = &omap54xx_l4_cfg_hwmod,
+ .slave = &omap54xx_l3_main_3_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> l4_abe */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l4_abe = {
+ .master = &omap54xx_l3_main_1_hwmod,
+ .slave = &omap54xx_l4_abe_hwmod,
+ .clk = "abe_iclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> l4_abe */
+static struct omap_hwmod_ocp_if omap54xx_mpu__l4_abe = {
+ .master = &omap54xx_mpu_hwmod,
+ .slave = &omap54xx_l4_abe_hwmod,
+ .clk = "abe_iclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> l4_cfg */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l4_cfg = {
+ .master = &omap54xx_l3_main_1_hwmod,
+ .slave = &omap54xx_l4_cfg_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> l4_per */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__l4_per = {
+ .master = &omap54xx_l3_main_2_hwmod,
+ .slave = &omap54xx_l4_per_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> l4_wkup */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l4_wkup = {
+ .master = &omap54xx_l3_main_1_hwmod,
+ .slave = &omap54xx_l4_wkup_hwmod,
+ .clk = "wkupaon_iclk_mux",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> mpu_private */
+static struct omap_hwmod_ocp_if omap54xx_mpu__mpu_private = {
+ .master = &omap54xx_mpu_hwmod,
+ .slave = &omap54xx_mpu_private_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> counter_32k */
+static struct omap_hwmod_ocp_if omap54xx_l4_wkup__counter_32k = {
+ .master = &omap54xx_l4_wkup_hwmod,
+ .slave = &omap54xx_counter_32k_hwmod,
+ .clk = "wkupaon_iclk_mux",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap54xx_dma_system_addrs[] = {
+ {
+ .pa_start = 0x4a056000,
+ .pa_end = 0x4a056fff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_cfg -> dma_system */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__dma_system = {
+ .master = &omap54xx_l4_cfg_hwmod,
+ .slave = &omap54xx_dma_system_hwmod,
+ .clk = "l4_root_clk_div",
+ .addr = omap54xx_dma_system_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_abe -> dmic */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__dmic = {
+ .master = &omap54xx_l4_abe_hwmod,
+ .slave = &omap54xx_dmic_hwmod,
+ .clk = "abe_iclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l3_main_2 -> dss */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss = {
+ .master = &omap54xx_l3_main_2_hwmod,
+ .slave = &omap54xx_dss_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> dss_dispc */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dispc = {
+ .master = &omap54xx_l3_main_2_hwmod,
+ .slave = &omap54xx_dss_dispc_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> dss_dsi1_a */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dsi1_a = {
+ .master = &omap54xx_l3_main_2_hwmod,
+ .slave = &omap54xx_dss_dsi1_a_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> dss_dsi1_c */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dsi1_c = {
+ .master = &omap54xx_l3_main_2_hwmod,
+ .slave = &omap54xx_dss_dsi1_c_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> dss_hdmi */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_hdmi = {
+ .master = &omap54xx_l3_main_2_hwmod,
+ .slave = &omap54xx_dss_hdmi_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> dss_rfbi */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_rfbi = {
+ .master = &omap54xx_l3_main_2_hwmod,
+ .slave = &omap54xx_dss_rfbi_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> emif1 */
+static struct omap_hwmod_ocp_if omap54xx_mpu__emif1 = {
+ .master = &omap54xx_mpu_hwmod,
+ .slave = &omap54xx_emif1_hwmod,
+ .clk = "dpll_core_h11x2_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> emif2 */
+static struct omap_hwmod_ocp_if omap54xx_mpu__emif2 = {
+ .master = &omap54xx_mpu_hwmod,
+ .slave = &omap54xx_emif2_hwmod,
+ .clk = "dpll_core_h11x2_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_wkup__gpio1 = {
+ .master = &omap54xx_l4_wkup_hwmod,
+ .slave = &omap54xx_gpio1_hwmod,
+ .clk = "wkupaon_iclk_mux",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio2 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_gpio2_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio3 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_gpio3_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio4 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio4 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_gpio4_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio5 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio5 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_gpio5_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio6 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio6 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_gpio6_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio7 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio7 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_gpio7_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio8 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio8 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_gpio8_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> i2c1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__i2c1 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_i2c1_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> i2c2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__i2c2 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_i2c2_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> i2c3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__i2c3 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_i2c3_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> i2c4 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__i2c4 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_i2c4_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> i2c5 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__i2c5 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_i2c5_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> kbd */
+static struct omap_hwmod_ocp_if omap54xx_l4_wkup__kbd = {
+ .master = &omap54xx_l4_wkup_hwmod,
+ .slave = &omap54xx_kbd_hwmod,
+ .clk = "wkupaon_iclk_mux",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> mailbox */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mailbox = {
+ .master = &omap54xx_l4_cfg_hwmod,
+ .slave = &omap54xx_mailbox_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_abe -> mcbsp1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcbsp1 = {
+ .master = &omap54xx_l4_abe_hwmod,
+ .slave = &omap54xx_mcbsp1_hwmod,
+ .clk = "abe_iclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4_abe -> mcbsp2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcbsp2 = {
+ .master = &omap54xx_l4_abe_hwmod,
+ .slave = &omap54xx_mcbsp2_hwmod,
+ .clk = "abe_iclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4_abe -> mcbsp3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcbsp3 = {
+ .master = &omap54xx_l4_abe_hwmod,
+ .slave = &omap54xx_mcbsp3_hwmod,
+ .clk = "abe_iclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4_abe -> mcpdm */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcpdm = {
+ .master = &omap54xx_l4_abe_hwmod,
+ .slave = &omap54xx_mcpdm_hwmod,
+ .clk = "abe_iclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4_per -> mcspi1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mcspi1 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_mcspi1_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> mcspi2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mcspi2 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_mcspi2_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> mcspi3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mcspi3 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_mcspi3_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> mcspi4 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mcspi4 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_mcspi4_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> mmc1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mmc1 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_mmc1_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> mmc2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mmc2 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_mmc2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> mmc3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mmc3 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_mmc3_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> mmc4 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mmc4 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_mmc4_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> mmc5 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mmc5 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_mmc5_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> mpu */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mpu = {
+ .master = &omap54xx_l4_cfg_hwmod,
+ .slave = &omap54xx_mpu_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> spinlock */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__spinlock = {
+ .master = &omap54xx_l4_cfg_hwmod,
+ .slave = &omap54xx_spinlock_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> ocp2scp1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__ocp2scp1 = {
+ .master = &omap54xx_l4_cfg_hwmod,
+ .slave = &omap54xx_ocp2scp1_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> timer1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_wkup__timer1 = {
+ .master = &omap54xx_l4_wkup_hwmod,
+ .slave = &omap54xx_timer1_hwmod,
+ .clk = "wkupaon_iclk_mux",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> timer2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__timer2 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_timer2_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> timer3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__timer3 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_timer3_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> timer4 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__timer4 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_timer4_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_abe -> timer5 */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__timer5 = {
+ .master = &omap54xx_l4_abe_hwmod,
+ .slave = &omap54xx_timer5_hwmod,
+ .clk = "abe_iclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4_abe -> timer6 */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__timer6 = {
+ .master = &omap54xx_l4_abe_hwmod,
+ .slave = &omap54xx_timer6_hwmod,
+ .clk = "abe_iclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4_abe -> timer7 */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__timer7 = {
+ .master = &omap54xx_l4_abe_hwmod,
+ .slave = &omap54xx_timer7_hwmod,
+ .clk = "abe_iclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4_abe -> timer8 */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__timer8 = {
+ .master = &omap54xx_l4_abe_hwmod,
+ .slave = &omap54xx_timer8_hwmod,
+ .clk = "abe_iclk",
+ .user = OCP_USER_MPU,
+};
+
+/* l4_per -> timer9 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__timer9 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_timer9_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> timer10 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__timer10 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_timer10_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> timer11 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__timer11 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_timer11_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> uart1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__uart1 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_uart1_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> uart2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__uart2 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_uart2_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> uart3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__uart3 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_uart3_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> uart4 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__uart4 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_uart4_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> uart5 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__uart5 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_uart5_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> uart6 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__uart6 = {
+ .master = &omap54xx_l4_per_hwmod,
+ .slave = &omap54xx_uart6_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> usb_host_hs */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_host_hs = {
+ .master = &omap54xx_l4_cfg_hwmod,
+ .slave = &omap54xx_usb_host_hs_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> usb_tll_hs */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_tll_hs = {
+ .master = &omap54xx_l4_cfg_hwmod,
+ .slave = &omap54xx_usb_tll_hs_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> usb_otg_ss */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_otg_ss = {
+ .master = &omap54xx_l4_cfg_hwmod,
+ .slave = &omap54xx_usb_otg_ss_hwmod,
+ .clk = "dpll_core_h13x2_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> wd_timer2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_wkup__wd_timer2 = {
+ .master = &omap54xx_l4_wkup_hwmod,
+ .slave = &omap54xx_wd_timer2_hwmod,
+ .clk = "wkupaon_iclk_mux",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = {
+ &omap54xx_l3_main_1__dmm,
+ &omap54xx_l3_main_3__l3_instr,
+ &omap54xx_l3_main_2__l3_main_1,
+ &omap54xx_l4_cfg__l3_main_1,
+ &omap54xx_mpu__l3_main_1,
+ &omap54xx_l3_main_1__l3_main_2,
+ &omap54xx_l4_cfg__l3_main_2,
+ &omap54xx_l3_main_1__l3_main_3,
+ &omap54xx_l3_main_2__l3_main_3,
+ &omap54xx_l4_cfg__l3_main_3,
+ &omap54xx_l3_main_1__l4_abe,
+ &omap54xx_mpu__l4_abe,
+ &omap54xx_l3_main_1__l4_cfg,
+ &omap54xx_l3_main_2__l4_per,
+ &omap54xx_l3_main_1__l4_wkup,
+ &omap54xx_mpu__mpu_private,
+ &omap54xx_l4_wkup__counter_32k,
+ &omap54xx_l4_cfg__dma_system,
+ &omap54xx_l4_abe__dmic,
+ &omap54xx_l4_cfg__mmu_dsp,
+ &omap54xx_l3_main_2__dss,
+ &omap54xx_l3_main_2__dss_dispc,
+ &omap54xx_l3_main_2__dss_dsi1_a,
+ &omap54xx_l3_main_2__dss_dsi1_c,
+ &omap54xx_l3_main_2__dss_hdmi,
+ &omap54xx_l3_main_2__dss_rfbi,
+ &omap54xx_mpu__emif1,
+ &omap54xx_mpu__emif2,
+ &omap54xx_l4_wkup__gpio1,
+ &omap54xx_l4_per__gpio2,
+ &omap54xx_l4_per__gpio3,
+ &omap54xx_l4_per__gpio4,
+ &omap54xx_l4_per__gpio5,
+ &omap54xx_l4_per__gpio6,
+ &omap54xx_l4_per__gpio7,
+ &omap54xx_l4_per__gpio8,
+ &omap54xx_l4_per__i2c1,
+ &omap54xx_l4_per__i2c2,
+ &omap54xx_l4_per__i2c3,
+ &omap54xx_l4_per__i2c4,
+ &omap54xx_l4_per__i2c5,
+ &omap54xx_l3_main_2__mmu_ipu,
+ &omap54xx_l4_wkup__kbd,
+ &omap54xx_l4_cfg__mailbox,
+ &omap54xx_l4_abe__mcbsp1,
+ &omap54xx_l4_abe__mcbsp2,
+ &omap54xx_l4_abe__mcbsp3,
+ &omap54xx_l4_abe__mcpdm,
+ &omap54xx_l4_per__mcspi1,
+ &omap54xx_l4_per__mcspi2,
+ &omap54xx_l4_per__mcspi3,
+ &omap54xx_l4_per__mcspi4,
+ &omap54xx_l4_per__mmc1,
+ &omap54xx_l4_per__mmc2,
+ &omap54xx_l4_per__mmc3,
+ &omap54xx_l4_per__mmc4,
+ &omap54xx_l4_per__mmc5,
+ &omap54xx_l4_cfg__mpu,
+ &omap54xx_l4_cfg__spinlock,
+ &omap54xx_l4_cfg__ocp2scp1,
+ &omap54xx_l4_wkup__timer1,
+ &omap54xx_l4_per__timer2,
+ &omap54xx_l4_per__timer3,
+ &omap54xx_l4_per__timer4,
+ &omap54xx_l4_abe__timer5,
+ &omap54xx_l4_abe__timer6,
+ &omap54xx_l4_abe__timer7,
+ &omap54xx_l4_abe__timer8,
+ &omap54xx_l4_per__timer9,
+ &omap54xx_l4_per__timer10,
+ &omap54xx_l4_per__timer11,
+ &omap54xx_l4_per__uart1,
+ &omap54xx_l4_per__uart2,
+ &omap54xx_l4_per__uart3,
+ &omap54xx_l4_per__uart4,
+ &omap54xx_l4_per__uart5,
+ &omap54xx_l4_per__uart6,
+ &omap54xx_l4_cfg__usb_host_hs,
+ &omap54xx_l4_cfg__usb_tll_hs,
+ &omap54xx_l4_cfg__usb_otg_ss,
+ &omap54xx_l4_wkup__wd_timer2,
+ &omap54xx_l4_cfg__ocp2scp3,
+ &omap54xx_l4_cfg__sata,
+ NULL,
+};
+
+int __init omap54xx_hwmod_init(void)
+{
+ omap_hwmod_init();
+ return omap_hwmod_register_links(omap54xx_hwmod_ocp_ifs);
+}
diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
new file mode 100644
index 000000000..0e64c2fac
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
@@ -0,0 +1,3422 @@
+/*
+ * Hardware modules present on the DRA7xx chips
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * 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 <linux/platform_data/gpio-omap.h>
+#include <linux/platform_data/hsmmc-omap.h>
+#include <linux/power/smartreflex.h>
+#include <linux/i2c-omap.h>
+
+#include <linux/omap-dma.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+#include <linux/platform_data/asoc-ti-mcbsp.h>
+#include <plat/dmtimer.h>
+
+#include "omap_hwmod.h"
+#include "omap_hwmod_common_data.h"
+#include "cm1_7xx.h"
+#include "cm2_7xx.h"
+#include "prm7xx.h"
+#include "i2c.h"
+#include "wd_timer.h"
+#include "soc.h"
+
+/* Base offset for all DRA7XX interrupts external to MPUSS */
+#define DRA7XX_IRQ_GIC_START 32
+
+/* Base offset for all DRA7XX dma requests */
+#define DRA7XX_DMA_REQ_START 1
+
+
+/*
+ * IP blocks
+ */
+
+/*
+ * 'l3' class
+ * instance(s): l3_instr, l3_main_1, l3_main_2
+ */
+static struct omap_hwmod_class dra7xx_l3_hwmod_class = {
+ .name = "l3",
+};
+
+/* l3_instr */
+static struct omap_hwmod dra7xx_l3_instr_hwmod = {
+ .name = "l3_instr",
+ .class = &dra7xx_l3_hwmod_class,
+ .clkdm_name = "l3instr_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/* l3_main_1 */
+static struct omap_hwmod dra7xx_l3_main_1_hwmod = {
+ .name = "l3_main_1",
+ .class = &dra7xx_l3_hwmod_class,
+ .clkdm_name = "l3main1_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3MAIN1_L3_MAIN_1_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3MAIN1_L3_MAIN_1_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* l3_main_2 */
+static struct omap_hwmod dra7xx_l3_main_2_hwmod = {
+ .name = "l3_main_2",
+ .class = &dra7xx_l3_hwmod_class,
+ .clkdm_name = "l3instr_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3INSTR_L3_MAIN_2_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3INSTR_L3_MAIN_2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * 'l4' class
+ * instance(s): l4_cfg, l4_per1, l4_per2, l4_per3, l4_wkup
+ */
+static struct omap_hwmod_class dra7xx_l4_hwmod_class = {
+ .name = "l4",
+};
+
+/* l4_cfg */
+static struct omap_hwmod dra7xx_l4_cfg_hwmod = {
+ .name = "l4_cfg",
+ .class = &dra7xx_l4_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4CFG_L4_CFG_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* l4_per1 */
+static struct omap_hwmod dra7xx_l4_per1_hwmod = {
+ .name = "l4_per1",
+ .class = &dra7xx_l4_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_L4_PER1_CLKCTRL_OFFSET,
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+};
+
+/* l4_per2 */
+static struct omap_hwmod dra7xx_l4_per2_hwmod = {
+ .name = "l4_per2",
+ .class = &dra7xx_l4_hwmod_class,
+ .clkdm_name = "l4per2_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER2_L4_PER2_CLKCTRL_OFFSET,
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+};
+
+/* l4_per3 */
+static struct omap_hwmod dra7xx_l4_per3_hwmod = {
+ .name = "l4_per3",
+ .class = &dra7xx_l4_hwmod_class,
+ .clkdm_name = "l4per3_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER3_L4_PER3_CLKCTRL_OFFSET,
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+};
+
+/* l4_wkup */
+static struct omap_hwmod dra7xx_l4_wkup_hwmod = {
+ .name = "l4_wkup",
+ .class = &dra7xx_l4_hwmod_class,
+ .clkdm_name = "wkupaon_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_WKUPAON_L4_WKUP_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_WKUPAON_L4_WKUP_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'atl' class
+ *
+ */
+
+static struct omap_hwmod_class dra7xx_atl_hwmod_class = {
+ .name = "atl",
+};
+
+/* atl */
+static struct omap_hwmod dra7xx_atl_hwmod = {
+ .name = "atl",
+ .class = &dra7xx_atl_hwmod_class,
+ .clkdm_name = "atl_clkdm",
+ .main_clk = "atl_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_ATL_ATL_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_ATL_ATL_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'bb2d' class
+ *
+ */
+
+static struct omap_hwmod_class dra7xx_bb2d_hwmod_class = {
+ .name = "bb2d",
+};
+
+/* bb2d */
+static struct omap_hwmod dra7xx_bb2d_hwmod = {
+ .name = "bb2d",
+ .class = &dra7xx_bb2d_hwmod_class,
+ .clkdm_name = "dss_clkdm",
+ .main_clk = "dpll_core_h24x2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_DSS_BB2D_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_DSS_BB2D_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'counter' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_counter_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .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 dra7xx_counter_hwmod_class = {
+ .name = "counter",
+ .sysc = &dra7xx_counter_sysc,
+};
+
+/* counter_32k */
+static struct omap_hwmod dra7xx_counter_32k_hwmod = {
+ .name = "counter_32k",
+ .class = &dra7xx_counter_hwmod_class,
+ .clkdm_name = "wkupaon_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE,
+ .main_clk = "wkupaon_iclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_WKUPAON_COUNTER_32K_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_WKUPAON_COUNTER_32K_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'ctrl_module' class
+ *
+ */
+
+static struct omap_hwmod_class dra7xx_ctrl_module_hwmod_class = {
+ .name = "ctrl_module",
+};
+
+/* ctrl_module_wkup */
+static struct omap_hwmod dra7xx_ctrl_module_wkup_hwmod = {
+ .name = "ctrl_module_wkup",
+ .class = &dra7xx_ctrl_module_hwmod_class,
+ .clkdm_name = "wkupaon_clkdm",
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+};
+
+/*
+ * 'gmac' class
+ * cpsw/gmac sub system
+ */
+static struct omap_hwmod_class_sysconfig dra7xx_gmac_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x8,
+ .syss_offs = 0x4,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | MSTANDBY_FORCE |
+ MSTANDBY_NO),
+ .sysc_fields = &omap_hwmod_sysc_type3,
+};
+
+static struct omap_hwmod_class dra7xx_gmac_hwmod_class = {
+ .name = "gmac",
+ .sysc = &dra7xx_gmac_sysc,
+};
+
+static struct omap_hwmod dra7xx_gmac_hwmod = {
+ .name = "gmac",
+ .class = &dra7xx_gmac_hwmod_class,
+ .clkdm_name = "gmac_clkdm",
+ .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
+ .main_clk = "dpll_gmac_ck",
+ .mpu_rt_idx = 1,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_GMAC_GMAC_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_GMAC_GMAC_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'mdio' class
+ */
+static struct omap_hwmod_class dra7xx_mdio_hwmod_class = {
+ .name = "davinci_mdio",
+};
+
+static struct omap_hwmod dra7xx_mdio_hwmod = {
+ .name = "davinci_mdio",
+ .class = &dra7xx_mdio_hwmod_class,
+ .clkdm_name = "gmac_clkdm",
+ .main_clk = "dpll_gmac_ck",
+};
+
+/*
+ * 'dcan' class
+ *
+ */
+
+static struct omap_hwmod_class dra7xx_dcan_hwmod_class = {
+ .name = "dcan",
+};
+
+/* dcan1 */
+static struct omap_hwmod dra7xx_dcan1_hwmod = {
+ .name = "dcan1",
+ .class = &dra7xx_dcan_hwmod_class,
+ .clkdm_name = "wkupaon_clkdm",
+ .main_clk = "dcan1_sys_clk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_WKUPAON_DCAN1_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_WKUPAON_DCAN1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* dcan2 */
+static struct omap_hwmod dra7xx_dcan2_hwmod = {
+ .name = "dcan2",
+ .class = &dra7xx_dcan_hwmod_class,
+ .clkdm_name = "l4per2_clkdm",
+ .main_clk = "sys_clkin1",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER2_DCAN2_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER2_DCAN2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'dma' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_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 |
+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+ MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dra7xx_dma_hwmod_class = {
+ .name = "dma",
+ .sysc = &dra7xx_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 dra7xx_dma_system_hwmod = {
+ .name = "dma_system",
+ .class = &dra7xx_dma_hwmod_class,
+ .clkdm_name = "dma_clkdm",
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_DMA_DMA_SYSTEM_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_DMA_DMA_SYSTEM_CONTEXT_OFFSET,
+ },
+ },
+ .dev_attr = &dma_dev_attr,
+};
+
+/*
+ * 'dss' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_dss_sysc = {
+ .rev_offs = 0x0000,
+ .syss_offs = 0x0014,
+ .sysc_flags = SYSS_HAS_RESET_STATUS,
+};
+
+static struct omap_hwmod_class dra7xx_dss_hwmod_class = {
+ .name = "dss",
+ .sysc = &dra7xx_dss_sysc,
+ .reset = omap_dss_reset,
+};
+
+/* dss */
+static struct omap_hwmod_dma_info dra7xx_dss_sdma_reqs[] = {
+ { .dma_req = 75 + DRA7XX_DMA_REQ_START },
+ { .dma_req = -1 }
+};
+
+static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+ { .role = "dss_clk", .clk = "dss_dss_clk" },
+ { .role = "hdmi_phy_clk", .clk = "dss_48mhz_clk" },
+ { .role = "32khz_clk", .clk = "dss_32khz_clk" },
+ { .role = "video2_clk", .clk = "dss_video2_clk" },
+ { .role = "video1_clk", .clk = "dss_video1_clk" },
+ { .role = "hdmi_clk", .clk = "dss_hdmi_clk" },
+};
+
+static struct omap_hwmod dra7xx_dss_hwmod = {
+ .name = "dss_core",
+ .class = &dra7xx_dss_hwmod_class,
+ .clkdm_name = "dss_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .sdma_reqs = dra7xx_dss_sdma_reqs,
+ .main_clk = "dss_dss_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_DSS_DSS_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = dss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks),
+};
+
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_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 dra7xx_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &dra7xx_dispc_sysc,
+};
+
+/* dss_dispc */
+/* dss_dispc dev_attr */
+static struct omap_dss_dispc_dev_attr dss_dispc_dev_attr = {
+ .has_framedonetv_irq = 1,
+ .manager_count = 4,
+};
+
+static struct omap_hwmod dra7xx_dss_dispc_hwmod = {
+ .name = "dss_dispc",
+ .class = &dra7xx_dispc_hwmod_class,
+ .clkdm_name = "dss_clkdm",
+ .main_clk = "dss_dss_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+ .dev_attr = &dss_dispc_dev_attr,
+};
+
+/*
+ * 'hdmi' class
+ * hdmi controller
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_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 dra7xx_hdmi_hwmod_class = {
+ .name = "hdmi",
+ .sysc = &dra7xx_hdmi_sysc,
+};
+
+/* dss_hdmi */
+
+static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = {
+ { .role = "sys_clk", .clk = "dss_hdmi_clk" },
+};
+
+static struct omap_hwmod dra7xx_dss_hdmi_hwmod = {
+ .name = "dss_hdmi",
+ .class = &dra7xx_hdmi_hwmod_class,
+ .clkdm_name = "dss_clkdm",
+ .main_clk = "dss_48mhz_clk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
+ .opt_clks = dss_hdmi_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks),
+};
+
+/*
+ * 'elm' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_elm_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+ 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 dra7xx_elm_hwmod_class = {
+ .name = "elm",
+ .sysc = &dra7xx_elm_sysc,
+};
+
+/* elm */
+
+static struct omap_hwmod dra7xx_elm_hwmod = {
+ .name = "elm",
+ .class = &dra7xx_elm_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_ELM_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_ELM_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'gpio' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_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 dra7xx_gpio_hwmod_class = {
+ .name = "gpio",
+ .sysc = &dra7xx_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_opt_clk gpio1_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio1_dbclk" },
+};
+
+static struct omap_hwmod dra7xx_gpio1_hwmod = {
+ .name = "gpio1",
+ .class = &dra7xx_gpio_hwmod_class,
+ .clkdm_name = "wkupaon_clkdm",
+ .main_clk = "wkupaon_iclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_WKUPAON_GPIO1_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_WKUPAON_GPIO1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio2 */
+static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio2_dbclk" },
+};
+
+static struct omap_hwmod dra7xx_gpio2_hwmod = {
+ .name = "gpio2",
+ .class = &dra7xx_gpio_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_GPIO2_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_GPIO2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio3 */
+static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio3_dbclk" },
+};
+
+static struct omap_hwmod dra7xx_gpio3_hwmod = {
+ .name = "gpio3",
+ .class = &dra7xx_gpio_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_GPIO3_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_GPIO3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio3_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio4 */
+static struct omap_hwmod_opt_clk gpio4_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio4_dbclk" },
+};
+
+static struct omap_hwmod dra7xx_gpio4_hwmod = {
+ .name = "gpio4",
+ .class = &dra7xx_gpio_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_GPIO4_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_GPIO4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio4_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio5 */
+static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio5_dbclk" },
+};
+
+static struct omap_hwmod dra7xx_gpio5_hwmod = {
+ .name = "gpio5",
+ .class = &dra7xx_gpio_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_GPIO5_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_GPIO5_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio5_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio6 */
+static struct omap_hwmod_opt_clk gpio6_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio6_dbclk" },
+};
+
+static struct omap_hwmod dra7xx_gpio6_hwmod = {
+ .name = "gpio6",
+ .class = &dra7xx_gpio_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_GPIO6_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_GPIO6_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio6_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio7 */
+static struct omap_hwmod_opt_clk gpio7_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio7_dbclk" },
+};
+
+static struct omap_hwmod dra7xx_gpio7_hwmod = {
+ .name = "gpio7",
+ .class = &dra7xx_gpio_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_GPIO7_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_GPIO7_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio7_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio7_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/* gpio8 */
+static struct omap_hwmod_opt_clk gpio8_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio8_dbclk" },
+};
+
+static struct omap_hwmod dra7xx_gpio8_hwmod = {
+ .name = "gpio8",
+ .class = &dra7xx_gpio_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_GPIO8_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_GPIO8_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = gpio8_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio8_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+/*
+ * 'gpmc' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_gpmc_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 |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dra7xx_gpmc_hwmod_class = {
+ .name = "gpmc",
+ .sysc = &dra7xx_gpmc_sysc,
+};
+
+/* gpmc */
+
+static struct omap_hwmod dra7xx_gpmc_hwmod = {
+ .name = "gpmc",
+ .class = &dra7xx_gpmc_hwmod_class,
+ .clkdm_name = "l3main1_clkdm",
+ .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
+ HWMOD_SWSUP_SIDLE),
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3MAIN1_GPMC_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3MAIN1_GPMC_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * 'hdq1w' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_hdq1w_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0014,
+ .syss_offs = 0x0018,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dra7xx_hdq1w_hwmod_class = {
+ .name = "hdq1w",
+ .sysc = &dra7xx_hdq1w_sysc,
+};
+
+/* hdq1w */
+
+static struct omap_hwmod dra7xx_hdq1w_hwmod = {
+ .name = "hdq1w",
+ .class = &dra7xx_hdq1w_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_INIT_NO_RESET,
+ .main_clk = "func_12m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_HDQ1W_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_HDQ1W_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'i2c' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_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),
+ .clockact = CLOCKACT_TEST_ICLK,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dra7xx_i2c_hwmod_class = {
+ .name = "i2c",
+ .sysc = &dra7xx_i2c_sysc,
+ .reset = &omap_i2c_reset,
+ .rev = OMAP_I2C_IP_VERSION_2,
+};
+
+/* i2c dev_attr */
+static struct omap_i2c_dev_attr i2c_dev_attr = {
+ .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE,
+};
+
+/* i2c1 */
+static struct omap_hwmod dra7xx_i2c1_hwmod = {
+ .name = "i2c1",
+ .class = &dra7xx_i2c_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "func_96m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_I2C1_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_I2C1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/* i2c2 */
+static struct omap_hwmod dra7xx_i2c2_hwmod = {
+ .name = "i2c2",
+ .class = &dra7xx_i2c_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "func_96m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_I2C2_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_I2C2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/* i2c3 */
+static struct omap_hwmod dra7xx_i2c3_hwmod = {
+ .name = "i2c3",
+ .class = &dra7xx_i2c_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "func_96m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_I2C3_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_I2C3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/* i2c4 */
+static struct omap_hwmod dra7xx_i2c4_hwmod = {
+ .name = "i2c4",
+ .class = &dra7xx_i2c_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "func_96m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_I2C4_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_I2C4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/* i2c5 */
+static struct omap_hwmod dra7xx_i2c5_hwmod = {
+ .name = "i2c5",
+ .class = &dra7xx_i2c_hwmod_class,
+ .clkdm_name = "ipu_clkdm",
+ .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+ .main_clk = "func_96m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_IPU_I2C5_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_IPU_I2C5_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &i2c_dev_attr,
+};
+
+/*
+ * 'mailbox' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_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 dra7xx_mailbox_hwmod_class = {
+ .name = "mailbox",
+ .sysc = &dra7xx_mailbox_sysc,
+};
+
+/* mailbox1 */
+static struct omap_hwmod dra7xx_mailbox1_hwmod = {
+ .name = "mailbox1",
+ .class = &dra7xx_mailbox_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX1_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX1_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* mailbox2 */
+static struct omap_hwmod dra7xx_mailbox2_hwmod = {
+ .name = "mailbox2",
+ .class = &dra7xx_mailbox_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX2_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX2_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* mailbox3 */
+static struct omap_hwmod dra7xx_mailbox3_hwmod = {
+ .name = "mailbox3",
+ .class = &dra7xx_mailbox_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX3_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX3_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* mailbox4 */
+static struct omap_hwmod dra7xx_mailbox4_hwmod = {
+ .name = "mailbox4",
+ .class = &dra7xx_mailbox_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX4_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX4_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* mailbox5 */
+static struct omap_hwmod dra7xx_mailbox5_hwmod = {
+ .name = "mailbox5",
+ .class = &dra7xx_mailbox_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX5_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX5_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* mailbox6 */
+static struct omap_hwmod dra7xx_mailbox6_hwmod = {
+ .name = "mailbox6",
+ .class = &dra7xx_mailbox_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX6_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX6_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* mailbox7 */
+static struct omap_hwmod dra7xx_mailbox7_hwmod = {
+ .name = "mailbox7",
+ .class = &dra7xx_mailbox_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX7_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX7_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* mailbox8 */
+static struct omap_hwmod dra7xx_mailbox8_hwmod = {
+ .name = "mailbox8",
+ .class = &dra7xx_mailbox_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX8_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX8_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* mailbox9 */
+static struct omap_hwmod dra7xx_mailbox9_hwmod = {
+ .name = "mailbox9",
+ .class = &dra7xx_mailbox_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX9_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX9_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* mailbox10 */
+static struct omap_hwmod dra7xx_mailbox10_hwmod = {
+ .name = "mailbox10",
+ .class = &dra7xx_mailbox_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX10_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX10_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* mailbox11 */
+static struct omap_hwmod dra7xx_mailbox11_hwmod = {
+ .name = "mailbox11",
+ .class = &dra7xx_mailbox_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX11_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX11_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* mailbox12 */
+static struct omap_hwmod dra7xx_mailbox12_hwmod = {
+ .name = "mailbox12",
+ .class = &dra7xx_mailbox_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX12_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX12_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* mailbox13 */
+static struct omap_hwmod dra7xx_mailbox13_hwmod = {
+ .name = "mailbox13",
+ .class = &dra7xx_mailbox_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX13_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX13_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'mcspi' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_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 dra7xx_mcspi_hwmod_class = {
+ .name = "mcspi",
+ .sysc = &dra7xx_mcspi_sysc,
+ .rev = OMAP4_MCSPI_REV,
+};
+
+/* mcspi1 */
+/* mcspi1 dev_attr */
+static struct omap2_mcspi_dev_attr mcspi1_dev_attr = {
+ .num_chipselect = 4,
+};
+
+static struct omap_hwmod dra7xx_mcspi1_hwmod = {
+ .name = "mcspi1",
+ .class = &dra7xx_mcspi_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_MCSPI1_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_MCSPI1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi1_dev_attr,
+};
+
+/* mcspi2 */
+/* mcspi2 dev_attr */
+static struct omap2_mcspi_dev_attr mcspi2_dev_attr = {
+ .num_chipselect = 2,
+};
+
+static struct omap_hwmod dra7xx_mcspi2_hwmod = {
+ .name = "mcspi2",
+ .class = &dra7xx_mcspi_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_MCSPI2_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_MCSPI2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi2_dev_attr,
+};
+
+/* mcspi3 */
+/* mcspi3 dev_attr */
+static struct omap2_mcspi_dev_attr mcspi3_dev_attr = {
+ .num_chipselect = 2,
+};
+
+static struct omap_hwmod dra7xx_mcspi3_hwmod = {
+ .name = "mcspi3",
+ .class = &dra7xx_mcspi_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_MCSPI3_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_MCSPI3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi3_dev_attr,
+};
+
+/* mcspi4 */
+/* mcspi4 dev_attr */
+static struct omap2_mcspi_dev_attr mcspi4_dev_attr = {
+ .num_chipselect = 1,
+};
+
+static struct omap_hwmod dra7xx_mcspi4_hwmod = {
+ .name = "mcspi4",
+ .class = &dra7xx_mcspi_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "func_48m_fclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_MCSPI4_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_MCSPI4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mcspi4_dev_attr,
+};
+
+/*
+ * 'mmc' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_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 | MSTANDBY_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class dra7xx_mmc_hwmod_class = {
+ .name = "mmc",
+ .sysc = &dra7xx_mmc_sysc,
+};
+
+/* mmc1 */
+static struct omap_hwmod_opt_clk mmc1_opt_clks[] = {
+ { .role = "clk32k", .clk = "mmc1_clk32k" },
+};
+
+/* mmc1 dev_attr */
+static struct omap_hsmmc_dev_attr mmc1_dev_attr = {
+ .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
+};
+
+static struct omap_hwmod dra7xx_mmc1_hwmod = {
+ .name = "mmc1",
+ .class = &dra7xx_mmc_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ .main_clk = "mmc1_fclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3INIT_MMC1_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3INIT_MMC1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = mmc1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mmc1_opt_clks),
+ .dev_attr = &mmc1_dev_attr,
+};
+
+/* mmc2 */
+static struct omap_hwmod_opt_clk mmc2_opt_clks[] = {
+ { .role = "clk32k", .clk = "mmc2_clk32k" },
+};
+
+static struct omap_hwmod dra7xx_mmc2_hwmod = {
+ .name = "mmc2",
+ .class = &dra7xx_mmc_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ .main_clk = "mmc2_fclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3INIT_MMC2_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3INIT_MMC2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = mmc2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mmc2_opt_clks),
+};
+
+/* mmc3 */
+static struct omap_hwmod_opt_clk mmc3_opt_clks[] = {
+ { .role = "clk32k", .clk = "mmc3_clk32k" },
+};
+
+static struct omap_hwmod dra7xx_mmc3_hwmod = {
+ .name = "mmc3",
+ .class = &dra7xx_mmc_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "mmc3_gfclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_MMC3_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_MMC3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = mmc3_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mmc3_opt_clks),
+};
+
+/* mmc4 */
+static struct omap_hwmod_opt_clk mmc4_opt_clks[] = {
+ { .role = "clk32k", .clk = "mmc4_clk32k" },
+};
+
+static struct omap_hwmod dra7xx_mmc4_hwmod = {
+ .name = "mmc4",
+ .class = &dra7xx_mmc_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "mmc4_gfclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_MMC4_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_MMC4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = mmc4_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mmc4_opt_clks),
+};
+
+/*
+ * 'mpu' class
+ *
+ */
+
+static struct omap_hwmod_class dra7xx_mpu_hwmod_class = {
+ .name = "mpu",
+};
+
+/* mpu */
+static struct omap_hwmod dra7xx_mpu_hwmod = {
+ .name = "mpu",
+ .class = &dra7xx_mpu_hwmod_class,
+ .clkdm_name = "mpu_clkdm",
+ .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+ .main_clk = "dpll_mpu_m2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_MPU_MPU_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_MPU_MPU_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'ocp2scp' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_ocp2scp_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 |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dra7xx_ocp2scp_hwmod_class = {
+ .name = "ocp2scp",
+ .sysc = &dra7xx_ocp2scp_sysc,
+};
+
+/* ocp2scp1 */
+static struct omap_hwmod dra7xx_ocp2scp1_hwmod = {
+ .name = "ocp2scp1",
+ .class = &dra7xx_ocp2scp_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ .main_clk = "l4_root_clk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3INIT_OCP2SCP1_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3INIT_OCP2SCP1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/* ocp2scp3 */
+static struct omap_hwmod dra7xx_ocp2scp3_hwmod = {
+ .name = "ocp2scp3",
+ .class = &dra7xx_ocp2scp_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ .main_clk = "l4_root_clk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3INIT_OCP2SCP3_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3INIT_OCP2SCP3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * 'PCIE' class
+ *
+ */
+
+static struct omap_hwmod_class dra7xx_pciess_hwmod_class = {
+ .name = "pcie",
+};
+
+/* pcie1 */
+static struct omap_hwmod dra7xx_pciess1_hwmod = {
+ .name = "pcie1",
+ .class = &dra7xx_pciess_hwmod_class,
+ .clkdm_name = "pcie_clkdm",
+ .main_clk = "l4_root_clk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3INIT_PCIESS1_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3INIT_PCIESS1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* pcie2 */
+static struct omap_hwmod dra7xx_pciess2_hwmod = {
+ .name = "pcie2",
+ .class = &dra7xx_pciess_hwmod_class,
+ .clkdm_name = "pcie_clkdm",
+ .main_clk = "l4_root_clk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3INIT_PCIESS2_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3INIT_PCIESS2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'qspi' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_qspi_sysc = {
+ .sysc_offs = 0x0010,
+ .sysc_flags = SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class dra7xx_qspi_hwmod_class = {
+ .name = "qspi",
+ .sysc = &dra7xx_qspi_sysc,
+};
+
+/* qspi */
+static struct omap_hwmod dra7xx_qspi_hwmod = {
+ .name = "qspi",
+ .class = &dra7xx_qspi_hwmod_class,
+ .clkdm_name = "l4per2_clkdm",
+ .main_clk = "qspi_gfclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER2_QSPI_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER2_QSPI_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'rtcss' class
+ *
+ */
+static struct omap_hwmod_class_sysconfig dra7xx_rtcss_sysc = {
+ .sysc_offs = 0x0078,
+ .sysc_flags = SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type3,
+};
+
+static struct omap_hwmod_class dra7xx_rtcss_hwmod_class = {
+ .name = "rtcss",
+ .sysc = &dra7xx_rtcss_sysc,
+};
+
+/* rtcss */
+static struct omap_hwmod dra7xx_rtcss_hwmod = {
+ .name = "rtcss",
+ .class = &dra7xx_rtcss_hwmod_class,
+ .clkdm_name = "rtc_clkdm",
+ .main_clk = "sys_32k_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_RTC_RTCSS_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_RTC_RTCSS_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'sata' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_sata_sysc = {
+ .sysc_offs = 0x0000,
+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+ MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class dra7xx_sata_hwmod_class = {
+ .name = "sata",
+ .sysc = &dra7xx_sata_sysc,
+};
+
+/* sata */
+
+static struct omap_hwmod dra7xx_sata_hwmod = {
+ .name = "sata",
+ .class = &dra7xx_sata_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+ .main_clk = "func_48m_fclk",
+ .mpu_rt_idx = 1,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3INIT_SATA_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3INIT_SATA_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'smartreflex' class
+ *
+ */
+
+/* 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 dra7xx_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 dra7xx_smartreflex_hwmod_class = {
+ .name = "smartreflex",
+ .sysc = &dra7xx_smartreflex_sysc,
+ .rev = 2,
+};
+
+/* smartreflex_core */
+/* smartreflex_core dev_attr */
+static struct omap_smartreflex_dev_attr smartreflex_core_dev_attr = {
+ .sensor_voltdm_name = "core",
+};
+
+static struct omap_hwmod dra7xx_smartreflex_core_hwmod = {
+ .name = "smartreflex_core",
+ .class = &dra7xx_smartreflex_hwmod_class,
+ .clkdm_name = "coreaon_clkdm",
+ .main_clk = "wkupaon_iclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_COREAON_SMARTREFLEX_CORE_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_COREAON_SMARTREFLEX_CORE_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &smartreflex_core_dev_attr,
+};
+
+/* smartreflex_mpu */
+/* smartreflex_mpu dev_attr */
+static struct omap_smartreflex_dev_attr smartreflex_mpu_dev_attr = {
+ .sensor_voltdm_name = "mpu",
+};
+
+static struct omap_hwmod dra7xx_smartreflex_mpu_hwmod = {
+ .name = "smartreflex_mpu",
+ .class = &dra7xx_smartreflex_hwmod_class,
+ .clkdm_name = "coreaon_clkdm",
+ .main_clk = "wkupaon_iclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_COREAON_SMARTREFLEX_MPU_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_COREAON_SMARTREFLEX_MPU_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &smartreflex_mpu_dev_attr,
+};
+
+/*
+ * 'spinlock' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_spinlock_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .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),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dra7xx_spinlock_hwmod_class = {
+ .name = "spinlock",
+ .sysc = &dra7xx_spinlock_sysc,
+};
+
+/* spinlock */
+static struct omap_hwmod dra7xx_spinlock_hwmod = {
+ .name = "spinlock",
+ .class = &dra7xx_spinlock_hwmod_class,
+ .clkdm_name = "l4cfg_clkdm",
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4CFG_SPINLOCK_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4CFG_SPINLOCK_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'timer' class
+ *
+ * This class contains several variants: ['timer_1ms', 'timer_secure',
+ * 'timer']
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_timer_1ms_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 dra7xx_timer_1ms_hwmod_class = {
+ .name = "timer",
+ .sysc = &dra7xx_timer_1ms_sysc,
+};
+
+static struct omap_hwmod_class_sysconfig dra7xx_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 dra7xx_timer_hwmod_class = {
+ .name = "timer",
+ .sysc = &dra7xx_timer_sysc,
+};
+
+/* timer1 */
+static struct omap_hwmod dra7xx_timer1_hwmod = {
+ .name = "timer1",
+ .class = &dra7xx_timer_1ms_hwmod_class,
+ .clkdm_name = "wkupaon_clkdm",
+ .main_clk = "timer1_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_WKUPAON_TIMER1_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_WKUPAON_TIMER1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer2 */
+static struct omap_hwmod dra7xx_timer2_hwmod = {
+ .name = "timer2",
+ .class = &dra7xx_timer_1ms_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "timer2_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_TIMER2_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_TIMER2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer3 */
+static struct omap_hwmod dra7xx_timer3_hwmod = {
+ .name = "timer3",
+ .class = &dra7xx_timer_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "timer3_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_TIMER3_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_TIMER3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer4 */
+static struct omap_hwmod dra7xx_timer4_hwmod = {
+ .name = "timer4",
+ .class = &dra7xx_timer_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "timer4_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_TIMER4_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_TIMER4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer5 */
+static struct omap_hwmod dra7xx_timer5_hwmod = {
+ .name = "timer5",
+ .class = &dra7xx_timer_hwmod_class,
+ .clkdm_name = "ipu_clkdm",
+ .main_clk = "timer5_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_IPU_TIMER5_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_IPU_TIMER5_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer6 */
+static struct omap_hwmod dra7xx_timer6_hwmod = {
+ .name = "timer6",
+ .class = &dra7xx_timer_hwmod_class,
+ .clkdm_name = "ipu_clkdm",
+ .main_clk = "timer6_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_IPU_TIMER6_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_IPU_TIMER6_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer7 */
+static struct omap_hwmod dra7xx_timer7_hwmod = {
+ .name = "timer7",
+ .class = &dra7xx_timer_hwmod_class,
+ .clkdm_name = "ipu_clkdm",
+ .main_clk = "timer7_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_IPU_TIMER7_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_IPU_TIMER7_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer8 */
+static struct omap_hwmod dra7xx_timer8_hwmod = {
+ .name = "timer8",
+ .class = &dra7xx_timer_hwmod_class,
+ .clkdm_name = "ipu_clkdm",
+ .main_clk = "timer8_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_IPU_TIMER8_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_IPU_TIMER8_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer9 */
+static struct omap_hwmod dra7xx_timer9_hwmod = {
+ .name = "timer9",
+ .class = &dra7xx_timer_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "timer9_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_TIMER9_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_TIMER9_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer10 */
+static struct omap_hwmod dra7xx_timer10_hwmod = {
+ .name = "timer10",
+ .class = &dra7xx_timer_1ms_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "timer10_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_TIMER10_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_TIMER10_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer11 */
+static struct omap_hwmod dra7xx_timer11_hwmod = {
+ .name = "timer11",
+ .class = &dra7xx_timer_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "timer11_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_TIMER11_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_TIMER11_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer13 */
+static struct omap_hwmod dra7xx_timer13_hwmod = {
+ .name = "timer13",
+ .class = &dra7xx_timer_hwmod_class,
+ .clkdm_name = "l4per3_clkdm",
+ .main_clk = "timer13_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER3_TIMER13_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER3_TIMER13_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer14 */
+static struct omap_hwmod dra7xx_timer14_hwmod = {
+ .name = "timer14",
+ .class = &dra7xx_timer_hwmod_class,
+ .clkdm_name = "l4per3_clkdm",
+ .main_clk = "timer14_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER3_TIMER14_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER3_TIMER14_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer15 */
+static struct omap_hwmod dra7xx_timer15_hwmod = {
+ .name = "timer15",
+ .class = &dra7xx_timer_hwmod_class,
+ .clkdm_name = "l4per3_clkdm",
+ .main_clk = "timer15_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER3_TIMER15_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER3_TIMER15_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* timer16 */
+static struct omap_hwmod dra7xx_timer16_hwmod = {
+ .name = "timer16",
+ .class = &dra7xx_timer_hwmod_class,
+ .clkdm_name = "l4per3_clkdm",
+ .main_clk = "timer16_gfclk_mux",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER3_TIMER16_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER3_TIMER16_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'uart' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_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 dra7xx_uart_hwmod_class = {
+ .name = "uart",
+ .sysc = &dra7xx_uart_sysc,
+};
+
+/* uart1 */
+static struct omap_hwmod dra7xx_uart1_hwmod = {
+ .name = "uart1",
+ .class = &dra7xx_uart_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "uart1_gfclk_mux",
+ .flags = HWMOD_SWSUP_SIDLE_ACT | DEBUG_OMAP2UART1_FLAGS,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_UART1_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_UART1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart2 */
+static struct omap_hwmod dra7xx_uart2_hwmod = {
+ .name = "uart2",
+ .class = &dra7xx_uart_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "uart2_gfclk_mux",
+ .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_UART2_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_UART2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart3 */
+static struct omap_hwmod dra7xx_uart3_hwmod = {
+ .name = "uart3",
+ .class = &dra7xx_uart_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "uart3_gfclk_mux",
+ .flags = HWMOD_SWSUP_SIDLE_ACT | DEBUG_OMAP4UART3_FLAGS,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_UART3_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_UART3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart4 */
+static struct omap_hwmod dra7xx_uart4_hwmod = {
+ .name = "uart4",
+ .class = &dra7xx_uart_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "uart4_gfclk_mux",
+ .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_UART4_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_UART4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart5 */
+static struct omap_hwmod dra7xx_uart5_hwmod = {
+ .name = "uart5",
+ .class = &dra7xx_uart_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "uart5_gfclk_mux",
+ .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_UART5_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER_UART5_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart6 */
+static struct omap_hwmod dra7xx_uart6_hwmod = {
+ .name = "uart6",
+ .class = &dra7xx_uart_hwmod_class,
+ .clkdm_name = "ipu_clkdm",
+ .main_clk = "uart6_gfclk_mux",
+ .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_IPU_UART6_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_IPU_UART6_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart7 */
+static struct omap_hwmod dra7xx_uart7_hwmod = {
+ .name = "uart7",
+ .class = &dra7xx_uart_hwmod_class,
+ .clkdm_name = "l4per2_clkdm",
+ .main_clk = "uart7_gfclk_mux",
+ .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER2_UART7_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER2_UART7_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart8 */
+static struct omap_hwmod dra7xx_uart8_hwmod = {
+ .name = "uart8",
+ .class = &dra7xx_uart_hwmod_class,
+ .clkdm_name = "l4per2_clkdm",
+ .main_clk = "uart8_gfclk_mux",
+ .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER2_UART8_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER2_UART8_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart9 */
+static struct omap_hwmod dra7xx_uart9_hwmod = {
+ .name = "uart9",
+ .class = &dra7xx_uart_hwmod_class,
+ .clkdm_name = "l4per2_clkdm",
+ .main_clk = "uart9_gfclk_mux",
+ .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER2_UART9_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER2_UART9_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/* uart10 */
+static struct omap_hwmod dra7xx_uart10_hwmod = {
+ .name = "uart10",
+ .class = &dra7xx_uart_hwmod_class,
+ .clkdm_name = "wkupaon_clkdm",
+ .main_clk = "uart10_gfclk_mux",
+ .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_WKUPAON_UART10_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_WKUPAON_UART10_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+/*
+ * 'usb_otg_ss' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_usb_otg_ss_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = (SYSC_HAS_DMADISABLE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SIDLEMODE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+ MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class dra7xx_usb_otg_ss_hwmod_class = {
+ .name = "usb_otg_ss",
+ .sysc = &dra7xx_usb_otg_ss_sysc,
+};
+
+/* usb_otg_ss1 */
+static struct omap_hwmod_opt_clk usb_otg_ss1_opt_clks[] = {
+ { .role = "refclk960m", .clk = "usb_otg_ss1_refclk960m" },
+};
+
+static struct omap_hwmod dra7xx_usb_otg_ss1_hwmod = {
+ .name = "usb_otg_ss1",
+ .class = &dra7xx_usb_otg_ss_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ .main_clk = "dpll_core_h13x2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3INIT_USB_OTG_SS1_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3INIT_USB_OTG_SS1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = usb_otg_ss1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(usb_otg_ss1_opt_clks),
+};
+
+/* usb_otg_ss2 */
+static struct omap_hwmod_opt_clk usb_otg_ss2_opt_clks[] = {
+ { .role = "refclk960m", .clk = "usb_otg_ss2_refclk960m" },
+};
+
+static struct omap_hwmod dra7xx_usb_otg_ss2_hwmod = {
+ .name = "usb_otg_ss2",
+ .class = &dra7xx_usb_otg_ss_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ .main_clk = "dpll_core_h13x2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3INIT_USB_OTG_SS2_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3INIT_USB_OTG_SS2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .opt_clks = usb_otg_ss2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(usb_otg_ss2_opt_clks),
+};
+
+/* usb_otg_ss3 */
+static struct omap_hwmod dra7xx_usb_otg_ss3_hwmod = {
+ .name = "usb_otg_ss3",
+ .class = &dra7xx_usb_otg_ss_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ .main_clk = "dpll_core_h13x2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3INIT_USB_OTG_SS3_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3INIT_USB_OTG_SS3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/* usb_otg_ss4 */
+static struct omap_hwmod dra7xx_usb_otg_ss4_hwmod = {
+ .name = "usb_otg_ss4",
+ .class = &dra7xx_usb_otg_ss_hwmod_class,
+ .clkdm_name = "l3init_clkdm",
+ .main_clk = "dpll_core_h13x2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3INIT_USB_OTG_SS4_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3INIT_USB_OTG_SS4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/*
+ * 'vcp' class
+ *
+ */
+
+static struct omap_hwmod_class dra7xx_vcp_hwmod_class = {
+ .name = "vcp",
+};
+
+/* vcp1 */
+static struct omap_hwmod dra7xx_vcp1_hwmod = {
+ .name = "vcp1",
+ .class = &dra7xx_vcp_hwmod_class,
+ .clkdm_name = "l3main1_clkdm",
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3MAIN1_VCP1_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3MAIN1_VCP1_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/* vcp2 */
+static struct omap_hwmod dra7xx_vcp2_hwmod = {
+ .name = "vcp2",
+ .class = &dra7xx_vcp_hwmod_class,
+ .clkdm_name = "l3main1_clkdm",
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L3MAIN1_VCP2_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L3MAIN1_VCP2_CONTEXT_OFFSET,
+ },
+ },
+};
+
+/*
+ * 'wd_timer' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_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 dra7xx_wd_timer_hwmod_class = {
+ .name = "wd_timer",
+ .sysc = &dra7xx_wd_timer_sysc,
+ .pre_shutdown = &omap2_wd_timer_disable,
+ .reset = &omap2_wd_timer_reset,
+};
+
+/* wd_timer2 */
+static struct omap_hwmod dra7xx_wd_timer2_hwmod = {
+ .name = "wd_timer2",
+ .class = &dra7xx_wd_timer_hwmod_class,
+ .clkdm_name = "wkupaon_clkdm",
+ .main_clk = "sys_32k_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_WKUPAON_WD_TIMER2_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_WKUPAON_WD_TIMER2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+
+/*
+ * Interfaces
+ */
+
+/* l3_main_2 -> l3_instr */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_2__l3_instr = {
+ .master = &dra7xx_l3_main_2_hwmod,
+ .slave = &dra7xx_l3_instr_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> l3_main_1 */
+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__l3_main_1 = {
+ .master = &dra7xx_l4_cfg_hwmod,
+ .slave = &dra7xx_l3_main_1_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> l3_main_1 */
+static struct omap_hwmod_ocp_if dra7xx_mpu__l3_main_1 = {
+ .master = &dra7xx_mpu_hwmod,
+ .slave = &dra7xx_l3_main_1_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU,
+};
+
+/* l3_main_1 -> l3_main_2 */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__l3_main_2 = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_l3_main_2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU,
+};
+
+/* l4_cfg -> l3_main_2 */
+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__l3_main_2 = {
+ .master = &dra7xx_l4_cfg_hwmod,
+ .slave = &dra7xx_l3_main_2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> l4_cfg */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__l4_cfg = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_l4_cfg_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> l4_per1 */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__l4_per1 = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_l4_per1_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> l4_per2 */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__l4_per2 = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_l4_per2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> l4_per3 */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__l4_per3 = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_l4_per3_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> l4_wkup */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__l4_wkup = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_l4_wkup_hwmod,
+ .clk = "wkupaon_iclk_mux",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per2 -> atl */
+static struct omap_hwmod_ocp_if dra7xx_l4_per2__atl = {
+ .master = &dra7xx_l4_per2_hwmod,
+ .slave = &dra7xx_atl_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> bb2d */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__bb2d = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_bb2d_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> counter_32k */
+static struct omap_hwmod_ocp_if dra7xx_l4_wkup__counter_32k = {
+ .master = &dra7xx_l4_wkup_hwmod,
+ .slave = &dra7xx_counter_32k_hwmod,
+ .clk = "wkupaon_iclk_mux",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> ctrl_module_wkup */
+static struct omap_hwmod_ocp_if dra7xx_l4_wkup__ctrl_module_wkup = {
+ .master = &dra7xx_l4_wkup_hwmod,
+ .slave = &dra7xx_ctrl_module_wkup_hwmod,
+ .clk = "wkupaon_iclk_mux",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if dra7xx_l4_per2__cpgmac0 = {
+ .master = &dra7xx_l4_per2_hwmod,
+ .slave = &dra7xx_gmac_hwmod,
+ .clk = "dpll_gmac_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if dra7xx_gmac__mdio = {
+ .master = &dra7xx_gmac_hwmod,
+ .slave = &dra7xx_mdio_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+/* l4_wkup -> dcan1 */
+static struct omap_hwmod_ocp_if dra7xx_l4_wkup__dcan1 = {
+ .master = &dra7xx_l4_wkup_hwmod,
+ .slave = &dra7xx_dcan1_hwmod,
+ .clk = "wkupaon_iclk_mux",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per2 -> dcan2 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per2__dcan2 = {
+ .master = &dra7xx_l4_per2_hwmod,
+ .slave = &dra7xx_dcan2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space dra7xx_dma_system_addrs[] = {
+ {
+ .pa_start = 0x4a056000,
+ .pa_end = 0x4a056fff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_cfg -> dma_system */
+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__dma_system = {
+ .master = &dra7xx_l4_cfg_hwmod,
+ .slave = &dra7xx_dma_system_hwmod,
+ .clk = "l3_iclk_div",
+ .addr = dra7xx_dma_system_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space dra7xx_dss_addrs[] = {
+ {
+ .name = "family",
+ .pa_start = 0x58000000,
+ .pa_end = 0x5800007f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_1 -> dss */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__dss = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_dss_hwmod,
+ .clk = "l3_iclk_div",
+ .addr = dra7xx_dss_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space dra7xx_dss_dispc_addrs[] = {
+ {
+ .name = "dispc",
+ .pa_start = 0x58001000,
+ .pa_end = 0x58001fff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_1 -> dispc */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__dispc = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_dss_dispc_hwmod,
+ .clk = "l3_iclk_div",
+ .addr = dra7xx_dss_dispc_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space dra7xx_dss_hdmi_addrs[] = {
+ {
+ .name = "hdmi_wp",
+ .pa_start = 0x58040000,
+ .pa_end = 0x580400ff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l3_main_1 -> dispc */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__hdmi = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_dss_hdmi_hwmod,
+ .clk = "l3_iclk_div",
+ .addr = dra7xx_dss_hdmi_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space dra7xx_elm_addrs[] = {
+ {
+ .pa_start = 0x48078000,
+ .pa_end = 0x48078fff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_per1 -> elm */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__elm = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_elm_hwmod,
+ .clk = "l3_iclk_div",
+ .addr = dra7xx_elm_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio1 */
+static struct omap_hwmod_ocp_if dra7xx_l4_wkup__gpio1 = {
+ .master = &dra7xx_l4_wkup_hwmod,
+ .slave = &dra7xx_gpio1_hwmod,
+ .clk = "wkupaon_iclk_mux",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> gpio2 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__gpio2 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_gpio2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> gpio3 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__gpio3 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_gpio3_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> gpio4 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__gpio4 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_gpio4_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> gpio5 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__gpio5 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_gpio5_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> gpio6 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__gpio6 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_gpio6_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> gpio7 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__gpio7 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_gpio7_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> gpio8 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__gpio8 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_gpio8_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space dra7xx_gpmc_addrs[] = {
+ {
+ .pa_start = 0x50000000,
+ .pa_end = 0x500003ff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l3_main_1 -> gpmc */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__gpmc = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_gpmc_hwmod,
+ .clk = "l3_iclk_div",
+ .addr = dra7xx_gpmc_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space dra7xx_hdq1w_addrs[] = {
+ {
+ .pa_start = 0x480b2000,
+ .pa_end = 0x480b201f,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_per1 -> hdq1w */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__hdq1w = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_hdq1w_hwmod,
+ .clk = "l3_iclk_div",
+ .addr = dra7xx_hdq1w_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> i2c1 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__i2c1 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_i2c1_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> i2c2 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__i2c2 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_i2c2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> i2c3 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__i2c3 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_i2c3_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> i2c4 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__i2c4 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_i2c4_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> i2c5 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__i2c5 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_i2c5_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> mailbox1 */
+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__mailbox1 = {
+ .master = &dra7xx_l4_cfg_hwmod,
+ .slave = &dra7xx_mailbox1_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> mailbox2 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox2 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_mailbox2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> mailbox3 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox3 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_mailbox3_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> mailbox4 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox4 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_mailbox4_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> mailbox5 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox5 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_mailbox5_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> mailbox6 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox6 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_mailbox6_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> mailbox7 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox7 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_mailbox7_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> mailbox8 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox8 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_mailbox8_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> mailbox9 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox9 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_mailbox9_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> mailbox10 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox10 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_mailbox10_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> mailbox11 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox11 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_mailbox11_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> mailbox12 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox12 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_mailbox12_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> mailbox13 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox13 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_mailbox13_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> mcspi1 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__mcspi1 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_mcspi1_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> mcspi2 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__mcspi2 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_mcspi2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> mcspi3 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__mcspi3 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_mcspi3_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> mcspi4 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__mcspi4 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_mcspi4_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> mmc1 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__mmc1 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_mmc1_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> mmc2 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__mmc2 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_mmc2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> mmc3 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__mmc3 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_mmc3_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> mmc4 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__mmc4 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_mmc4_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> mpu */
+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__mpu = {
+ .master = &dra7xx_l4_cfg_hwmod,
+ .slave = &dra7xx_mpu_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> ocp2scp1 */
+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__ocp2scp1 = {
+ .master = &dra7xx_l4_cfg_hwmod,
+ .slave = &dra7xx_ocp2scp1_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> ocp2scp3 */
+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__ocp2scp3 = {
+ .master = &dra7xx_l4_cfg_hwmod,
+ .slave = &dra7xx_ocp2scp3_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> pciess1 */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__pciess1 = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_pciess1_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> pciess1 */
+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pciess1 = {
+ .master = &dra7xx_l4_cfg_hwmod,
+ .slave = &dra7xx_pciess1_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> pciess2 */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__pciess2 = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_pciess2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> pciess2 */
+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pciess2 = {
+ .master = &dra7xx_l4_cfg_hwmod,
+ .slave = &dra7xx_pciess2_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space dra7xx_qspi_addrs[] = {
+ {
+ .pa_start = 0x4b300000,
+ .pa_end = 0x4b30007f,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l3_main_1 -> qspi */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__qspi = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_qspi_hwmod,
+ .clk = "l3_iclk_div",
+ .addr = dra7xx_qspi_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> rtcss */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__rtcss = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_rtcss_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space dra7xx_sata_addrs[] = {
+ {
+ .name = "sysc",
+ .pa_start = 0x4a141100,
+ .pa_end = 0x4a141107,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_cfg -> sata */
+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__sata = {
+ .master = &dra7xx_l4_cfg_hwmod,
+ .slave = &dra7xx_sata_hwmod,
+ .clk = "l3_iclk_div",
+ .addr = dra7xx_sata_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space dra7xx_smartreflex_core_addrs[] = {
+ {
+ .pa_start = 0x4a0dd000,
+ .pa_end = 0x4a0dd07f,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_cfg -> smartreflex_core */
+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__smartreflex_core = {
+ .master = &dra7xx_l4_cfg_hwmod,
+ .slave = &dra7xx_smartreflex_core_hwmod,
+ .clk = "l4_root_clk_div",
+ .addr = dra7xx_smartreflex_core_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space dra7xx_smartreflex_mpu_addrs[] = {
+ {
+ .pa_start = 0x4a0d9000,
+ .pa_end = 0x4a0d907f,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_cfg -> smartreflex_mpu */
+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__smartreflex_mpu = {
+ .master = &dra7xx_l4_cfg_hwmod,
+ .slave = &dra7xx_smartreflex_mpu_hwmod,
+ .clk = "l4_root_clk_div",
+ .addr = dra7xx_smartreflex_mpu_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space dra7xx_spinlock_addrs[] = {
+ {
+ .pa_start = 0x4a0f6000,
+ .pa_end = 0x4a0f6fff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+/* l4_cfg -> spinlock */
+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__spinlock = {
+ .master = &dra7xx_l4_cfg_hwmod,
+ .slave = &dra7xx_spinlock_hwmod,
+ .clk = "l3_iclk_div",
+ .addr = dra7xx_spinlock_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> timer1 */
+static struct omap_hwmod_ocp_if dra7xx_l4_wkup__timer1 = {
+ .master = &dra7xx_l4_wkup_hwmod,
+ .slave = &dra7xx_timer1_hwmod,
+ .clk = "wkupaon_iclk_mux",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> timer2 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer2 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_timer2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> timer3 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer3 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_timer3_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> timer4 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer4 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_timer4_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> timer5 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer5 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_timer5_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> timer6 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer6 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_timer6_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> timer7 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer7 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_timer7_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> timer8 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer8 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_timer8_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> timer9 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer9 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_timer9_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> timer10 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer10 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_timer10_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> timer11 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer11 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_timer11_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> timer13 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer13 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_timer13_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> timer14 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer14 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_timer14_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> timer15 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer15 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_timer15_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> timer16 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer16 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_timer16_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> uart1 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__uart1 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_uart1_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> uart2 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__uart2 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_uart2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> uart3 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__uart3 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_uart3_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> uart4 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__uart4 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_uart4_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> uart5 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__uart5 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_uart5_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per1 -> uart6 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__uart6 = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_uart6_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per2 -> uart7 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per2__uart7 = {
+ .master = &dra7xx_l4_per2_hwmod,
+ .slave = &dra7xx_uart7_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per2 -> uart8 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per2__uart8 = {
+ .master = &dra7xx_l4_per2_hwmod,
+ .slave = &dra7xx_uart8_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per2 -> uart9 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per2__uart9 = {
+ .master = &dra7xx_l4_per2_hwmod,
+ .slave = &dra7xx_uart9_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> uart10 */
+static struct omap_hwmod_ocp_if dra7xx_l4_wkup__uart10 = {
+ .master = &dra7xx_l4_wkup_hwmod,
+ .slave = &dra7xx_uart10_hwmod,
+ .clk = "wkupaon_iclk_mux",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> usb_otg_ss1 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss1 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_usb_otg_ss1_hwmod,
+ .clk = "dpll_core_h13x2_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> usb_otg_ss2 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss2 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_usb_otg_ss2_hwmod,
+ .clk = "dpll_core_h13x2_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> usb_otg_ss3 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss3 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_usb_otg_ss3_hwmod,
+ .clk = "dpll_core_h13x2_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per3 -> usb_otg_ss4 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss4 = {
+ .master = &dra7xx_l4_per3_hwmod,
+ .slave = &dra7xx_usb_otg_ss4_hwmod,
+ .clk = "dpll_core_h13x2_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> vcp1 */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__vcp1 = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_vcp1_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per2 -> vcp1 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per2__vcp1 = {
+ .master = &dra7xx_l4_per2_hwmod,
+ .slave = &dra7xx_vcp1_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> vcp2 */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__vcp2 = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_vcp2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per2 -> vcp2 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per2__vcp2 = {
+ .master = &dra7xx_l4_per2_hwmod,
+ .slave = &dra7xx_vcp2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> wd_timer2 */
+static struct omap_hwmod_ocp_if dra7xx_l4_wkup__wd_timer2 = {
+ .master = &dra7xx_l4_wkup_hwmod,
+ .slave = &dra7xx_wd_timer2_hwmod,
+ .clk = "wkupaon_iclk_mux",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
+ &dra7xx_l3_main_2__l3_instr,
+ &dra7xx_l4_cfg__l3_main_1,
+ &dra7xx_mpu__l3_main_1,
+ &dra7xx_l3_main_1__l3_main_2,
+ &dra7xx_l4_cfg__l3_main_2,
+ &dra7xx_l3_main_1__l4_cfg,
+ &dra7xx_l3_main_1__l4_per1,
+ &dra7xx_l3_main_1__l4_per2,
+ &dra7xx_l3_main_1__l4_per3,
+ &dra7xx_l3_main_1__l4_wkup,
+ &dra7xx_l4_per2__atl,
+ &dra7xx_l3_main_1__bb2d,
+ &dra7xx_l4_wkup__counter_32k,
+ &dra7xx_l4_wkup__ctrl_module_wkup,
+ &dra7xx_l4_wkup__dcan1,
+ &dra7xx_l4_per2__dcan2,
+ &dra7xx_l4_per2__cpgmac0,
+ &dra7xx_gmac__mdio,
+ &dra7xx_l4_cfg__dma_system,
+ &dra7xx_l3_main_1__dss,
+ &dra7xx_l3_main_1__dispc,
+ &dra7xx_l3_main_1__hdmi,
+ &dra7xx_l4_per1__elm,
+ &dra7xx_l4_wkup__gpio1,
+ &dra7xx_l4_per1__gpio2,
+ &dra7xx_l4_per1__gpio3,
+ &dra7xx_l4_per1__gpio4,
+ &dra7xx_l4_per1__gpio5,
+ &dra7xx_l4_per1__gpio6,
+ &dra7xx_l4_per1__gpio7,
+ &dra7xx_l4_per1__gpio8,
+ &dra7xx_l3_main_1__gpmc,
+ &dra7xx_l4_per1__hdq1w,
+ &dra7xx_l4_per1__i2c1,
+ &dra7xx_l4_per1__i2c2,
+ &dra7xx_l4_per1__i2c3,
+ &dra7xx_l4_per1__i2c4,
+ &dra7xx_l4_per1__i2c5,
+ &dra7xx_l4_cfg__mailbox1,
+ &dra7xx_l4_per3__mailbox2,
+ &dra7xx_l4_per3__mailbox3,
+ &dra7xx_l4_per3__mailbox4,
+ &dra7xx_l4_per3__mailbox5,
+ &dra7xx_l4_per3__mailbox6,
+ &dra7xx_l4_per3__mailbox7,
+ &dra7xx_l4_per3__mailbox8,
+ &dra7xx_l4_per3__mailbox9,
+ &dra7xx_l4_per3__mailbox10,
+ &dra7xx_l4_per3__mailbox11,
+ &dra7xx_l4_per3__mailbox12,
+ &dra7xx_l4_per3__mailbox13,
+ &dra7xx_l4_per1__mcspi1,
+ &dra7xx_l4_per1__mcspi2,
+ &dra7xx_l4_per1__mcspi3,
+ &dra7xx_l4_per1__mcspi4,
+ &dra7xx_l4_per1__mmc1,
+ &dra7xx_l4_per1__mmc2,
+ &dra7xx_l4_per1__mmc3,
+ &dra7xx_l4_per1__mmc4,
+ &dra7xx_l4_cfg__mpu,
+ &dra7xx_l4_cfg__ocp2scp1,
+ &dra7xx_l4_cfg__ocp2scp3,
+ &dra7xx_l3_main_1__pciess1,
+ &dra7xx_l4_cfg__pciess1,
+ &dra7xx_l3_main_1__pciess2,
+ &dra7xx_l4_cfg__pciess2,
+ &dra7xx_l3_main_1__qspi,
+ &dra7xx_l4_per3__rtcss,
+ &dra7xx_l4_cfg__sata,
+ &dra7xx_l4_cfg__smartreflex_core,
+ &dra7xx_l4_cfg__smartreflex_mpu,
+ &dra7xx_l4_cfg__spinlock,
+ &dra7xx_l4_wkup__timer1,
+ &dra7xx_l4_per1__timer2,
+ &dra7xx_l4_per1__timer3,
+ &dra7xx_l4_per1__timer4,
+ &dra7xx_l4_per3__timer5,
+ &dra7xx_l4_per3__timer6,
+ &dra7xx_l4_per3__timer7,
+ &dra7xx_l4_per3__timer8,
+ &dra7xx_l4_per1__timer9,
+ &dra7xx_l4_per1__timer10,
+ &dra7xx_l4_per1__timer11,
+ &dra7xx_l4_per3__timer13,
+ &dra7xx_l4_per3__timer14,
+ &dra7xx_l4_per3__timer15,
+ &dra7xx_l4_per3__timer16,
+ &dra7xx_l4_per1__uart1,
+ &dra7xx_l4_per1__uart2,
+ &dra7xx_l4_per1__uart3,
+ &dra7xx_l4_per1__uart4,
+ &dra7xx_l4_per1__uart5,
+ &dra7xx_l4_per1__uart6,
+ &dra7xx_l4_per2__uart7,
+ &dra7xx_l4_per2__uart8,
+ &dra7xx_l4_per2__uart9,
+ &dra7xx_l4_wkup__uart10,
+ &dra7xx_l4_per3__usb_otg_ss1,
+ &dra7xx_l4_per3__usb_otg_ss2,
+ &dra7xx_l4_per3__usb_otg_ss3,
+ &dra7xx_l3_main_1__vcp1,
+ &dra7xx_l4_per2__vcp1,
+ &dra7xx_l3_main_1__vcp2,
+ &dra7xx_l4_per2__vcp2,
+ &dra7xx_l4_wkup__wd_timer2,
+ NULL,
+};
+
+static struct omap_hwmod_ocp_if *dra74x_hwmod_ocp_ifs[] __initdata = {
+ &dra7xx_l4_per3__usb_otg_ss4,
+ NULL,
+};
+
+static struct omap_hwmod_ocp_if *dra72x_hwmod_ocp_ifs[] __initdata = {
+ NULL,
+};
+
+int __init dra7xx_hwmod_init(void)
+{
+ int ret;
+
+ omap_hwmod_init();
+ ret = omap_hwmod_register_links(dra7xx_hwmod_ocp_ifs);
+
+ if (!ret && soc_is_dra74x())
+ return omap_hwmod_register_links(dra74x_hwmod_ocp_ifs);
+ else if (!ret && soc_is_dra72x())
+ return omap_hwmod_register_links(dra72x_hwmod_ocp_ifs);
+
+ return ret;
+}
diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
new file mode 100644
index 000000000..cab1eb61a
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
@@ -0,0 +1,1136 @@
+/*
+ * DM81xx hwmod data.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/
+ * Copyright (C) 2013 SKTB SKiT, http://www.skitlab.ru/
+ *
+ * This program is free software; 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/platform_data/gpio-omap.h>
+#include <linux/platform_data/hsmmc-omap.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+#include <plat/dmtimer.h>
+
+#include "omap_hwmod_common_data.h"
+#include "cm81xx.h"
+#include "ti81xx.h"
+#include "wd_timer.h"
+
+/*
+ * DM816X hardware modules integration data
+ *
+ * Note: This is incomplete and at present, not generated from h/w database.
+ */
+
+/*
+ * The alwon .clkctrl_offs field is offset from the CM_ALWON, that's
+ * TRM 18.7.17 CM_ALWON device register values minus 0x1400.
+ */
+#define DM816X_DM_ALWON_BASE 0x1400
+#define DM816X_CM_ALWON_MCASP0_CLKCTRL (0x1540 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MCASP1_CLKCTRL (0x1544 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MCASP2_CLKCTRL (0x1548 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MCBSP_CLKCTRL (0x154c - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_UART_0_CLKCTRL (0x1550 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_UART_1_CLKCTRL (0x1554 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_UART_2_CLKCTRL (0x1558 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_GPIO_0_CLKCTRL (0x155c - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_GPIO_1_CLKCTRL (0x1560 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_I2C_0_CLKCTRL (0x1564 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_I2C_1_CLKCTRL (0x1568 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_1_CLKCTRL (0x1570 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_2_CLKCTRL (0x1574 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_3_CLKCTRL (0x1578 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_4_CLKCTRL (0x157c - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_5_CLKCTRL (0x1580 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_6_CLKCTRL (0x1584 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_7_CLKCTRL (0x1588 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_WDTIMER_CLKCTRL (0x158c - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_SPI_CLKCTRL (0x1590 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MAILBOX_CLKCTRL (0x1594 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_SPINBOX_CLKCTRL (0x1598 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MMUDATA_CLKCTRL (0x159c - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MMUCFG_CLKCTRL (0x15a8 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_SDIO_CLKCTRL (0x15b0 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_OCMC_0_CLKCTRL (0x15b4 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_OCMC_1_CLKCTRL (0x15b8 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_CONTRL_CLKCTRL (0x15c4 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_GPMC_CLKCTRL (0x15d0 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_ETHERNET_0_CLKCTRL (0x15d4 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_ETHERNET_1_CLKCTRL (0x15d8 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MPU_CLKCTRL (0x15dc - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_L3_CLKCTRL (0x15e4 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_L4HS_CLKCTRL (0x15e8 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_L4LS_CLKCTRL (0x15ec - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_RTC_CLKCTRL (0x15f0 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TPCC_CLKCTRL (0x15f4 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TPTC0_CLKCTRL (0x15f8 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TPTC1_CLKCTRL (0x15fc - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TPTC2_CLKCTRL (0x1600 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TPTC3_CLKCTRL (0x1604 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_SR_0_CLKCTRL (0x1608 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_SR_1_CLKCTRL (0x160c - DM816X_DM_ALWON_BASE)
+
+/*
+ * The default .clkctrl_offs field is offset from CM_DEFAULT, that's
+ * TRM 18.7.6 CM_DEFAULT device register values minus 0x500
+ */
+#define DM816X_CM_DEFAULT_OFFSET 0x500
+#define DM816X_CM_DEFAULT_USB_CLKCTRL (0x558 - DM816X_CM_DEFAULT_OFFSET)
+
+/* L3 Interconnect entries clocked at 125, 250 and 500MHz */
+static struct omap_hwmod dm816x_alwon_l3_slow_hwmod = {
+ .name = "alwon_l3_slow",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &l3_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod dm816x_default_l3_slow_hwmod = {
+ .name = "default_l3_slow",
+ .clkdm_name = "default_l3_slow_clkdm",
+ .class = &l3_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod dm816x_alwon_l3_med_hwmod = {
+ .name = "l3_med",
+ .clkdm_name = "alwon_l3_med_clkdm",
+ .class = &l3_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod dm816x_alwon_l3_fast_hwmod = {
+ .name = "l3_fast",
+ .clkdm_name = "alwon_l3_fast_clkdm",
+ .class = &l3_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * L4 standard peripherals, see TRM table 1-12 for devices using this.
+ * See TRM table 1-73 for devices using the 125MHz SYSCLK6 clock.
+ */
+static struct omap_hwmod dm816x_l4_ls_hwmod = {
+ .name = "l4_ls",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &l4_hwmod_class,
+};
+
+/*
+ * L4 high-speed peripherals. For devices using this, please see the TRM
+ * table 1-13. On dm816x, only EMAC, MDIO and SATA use this. See also TRM
+ * table 1-73 for devices using 250MHz SYSCLK5 clock.
+ */
+static struct omap_hwmod dm816x_l4_hs_hwmod = {
+ .name = "l4_hs",
+ .clkdm_name = "alwon_l3_med_clkdm",
+ .class = &l4_hwmod_class,
+};
+
+/* L3 slow -> L4 ls peripheral interface running at 125MHz */
+static struct omap_hwmod_ocp_if dm816x_alwon_l3_slow__l4_ls = {
+ .master = &dm816x_alwon_l3_slow_hwmod,
+ .slave = &dm816x_l4_ls_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+/* L3 med -> L4 fast peripheral interface running at 250MHz */
+static struct omap_hwmod_ocp_if dm816x_alwon_l3_slow__l4_hs = {
+ .master = &dm816x_alwon_l3_med_hwmod,
+ .slave = &dm816x_l4_hs_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+/* MPU */
+static struct omap_hwmod dm816x_mpu_hwmod = {
+ .name = "mpu",
+ .clkdm_name = "alwon_mpu_clkdm",
+ .class = &mpu_hwmod_class,
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "mpu_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_MPU_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod_ocp_if dm816x_mpu__alwon_l3_slow = {
+ .master = &dm816x_mpu_hwmod,
+ .slave = &dm816x_alwon_l3_slow_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+/* L3 med peripheral interface running at 250MHz */
+static struct omap_hwmod_ocp_if dm816x_mpu__alwon_l3_med = {
+ .master = &dm816x_mpu_hwmod,
+ .slave = &dm816x_alwon_l3_med_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+/* UART common */
+static struct omap_hwmod_class_sysconfig uart_sysc = {
+ .rev_offs = 0x50,
+ .sysc_offs = 0x54,
+ .syss_offs = 0x58,
+ .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 |
+ MSTANDBY_SMART_WKUP,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class uart_class = {
+ .name = "uart",
+ .sysc = &uart_sysc,
+};
+
+static struct omap_hwmod dm816x_uart1_hwmod = {
+ .name = "uart1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_UART_0_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &uart_class,
+ .flags = DEBUG_TI81XXUART1_FLAGS,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__uart1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_uart1_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_uart2_hwmod = {
+ .name = "uart2",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_UART_1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &uart_class,
+ .flags = DEBUG_TI81XXUART2_FLAGS,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__uart2 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_uart2_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_uart3_hwmod = {
+ .name = "uart3",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_UART_2_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &uart_class,
+ .flags = DEBUG_TI81XXUART3_FLAGS,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__uart3 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_uart3_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig wd_timer_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .syss_offs = 0x14,
+ .sysc_flags = SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class wd_timer_class = {
+ .name = "wd_timer",
+ .sysc = &wd_timer_sysc,
+ .pre_shutdown = &omap2_wd_timer_disable,
+ .reset = &omap2_wd_timer_reset,
+};
+
+static struct omap_hwmod dm816x_wd_timer_hwmod = {
+ .name = "wd_timer",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk18_ck",
+ .flags = HWMOD_NO_IDLEST,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_WDTIMER_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &wd_timer_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__wd_timer1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_wd_timer_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* I2C common */
+static struct omap_hwmod_class_sysconfig i2c_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .syss_offs = 0x90,
+ .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 i2c_class = {
+ .name = "i2c",
+ .sysc = &i2c_sysc,
+};
+
+static struct omap_hwmod dm81xx_i2c1_hwmod = {
+ .name = "i2c1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_I2C_0_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &i2c_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__i2c1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm81xx_i2c1_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_i2c2_hwmod = {
+ .name = "i2c2",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_I2C_1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &i2c_class,
+};
+
+static struct omap_hwmod_class_sysconfig dm81xx_elm_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = SYSC_HAS_CLOCKACTIVITY | 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_ocp_if dm816x_l4_ls__i2c2 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_i2c2_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class dm81xx_elm_hwmod_class = {
+ .name = "elm",
+ .sysc = &dm81xx_elm_sysc,
+};
+
+static struct omap_hwmod dm81xx_elm_hwmod = {
+ .name = "elm",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &dm81xx_elm_hwmod_class,
+ .main_clk = "sysclk6_ck",
+};
+
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__elm = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm81xx_elm_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm81xx_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 dm81xx_gpio_hwmod_class = {
+ .name = "gpio",
+ .sysc = &dm81xx_gpio_sysc,
+ .rev = 2,
+};
+
+static struct omap_gpio_dev_attr gpio_dev_attr = {
+ .bank_width = 32,
+ .dbck_flag = true,
+};
+
+static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
+ { .role = "dbclk", .clk = "sysclk18_ck" },
+};
+
+static struct omap_hwmod dm81xx_gpio1_hwmod = {
+ .name = "gpio1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &dm81xx_gpio_hwmod_class,
+ .main_clk = "sysclk6_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_GPIO_0_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = gpio1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__gpio1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm81xx_gpio1_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
+ { .role = "dbclk", .clk = "sysclk18_ck" },
+};
+
+static struct omap_hwmod dm81xx_gpio2_hwmod = {
+ .name = "gpio2",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &dm81xx_gpio_hwmod_class,
+ .main_clk = "sysclk6_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_GPIO_1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = gpio2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__gpio2 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm81xx_gpio2_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm81xx_gpmc_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .syss_offs = 0x14,
+ .sysc_flags = 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 dm81xx_gpmc_hwmod_class = {
+ .name = "gpmc",
+ .sysc = &dm81xx_gpmc_sysc,
+};
+
+static struct omap_hwmod dm81xx_gpmc_hwmod = {
+ .name = "gpmc",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &dm81xx_gpmc_hwmod_class,
+ .main_clk = "sysclk6_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_GPMC_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm81xx_alwon_l3_slow__gpmc = {
+ .master = &dm816x_alwon_l3_slow_hwmod,
+ .slave = &dm81xx_gpmc_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm81xx_usbhsotg_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SOFTRESET,
+ .idlemodes = SIDLE_SMART | MSTANDBY_FORCE | MSTANDBY_SMART,
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class dm81xx_usbotg_class = {
+ .name = "usbotg",
+ .sysc = &dm81xx_usbhsotg_sysc,
+};
+
+static struct omap_hwmod dm81xx_usbss_hwmod = {
+ .name = "usb_otg_hs",
+ .clkdm_name = "default_l3_slow_clkdm",
+ .main_clk = "sysclk6_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_DEFAULT_USB_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &dm81xx_usbotg_class,
+};
+
+static struct omap_hwmod_ocp_if dm81xx_default_l3_slow__usbss = {
+ .master = &dm816x_default_l3_slow_hwmod,
+ .slave = &dm81xx_usbss_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm816x_timer_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = 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 dm816x_timer_hwmod_class = {
+ .name = "timer",
+ .sysc = &dm816x_timer_sysc,
+};
+
+static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
+ .timer_capability = OMAP_TIMER_ALWON,
+};
+
+static struct omap_hwmod dm816x_timer1_hwmod = {
+ .name = "timer1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer1_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer1_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer2_hwmod = {
+ .name = "timer2",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer2_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_2_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer2 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer2_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer3_hwmod = {
+ .name = "timer3",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer3_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_3_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer3 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer3_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer4_hwmod = {
+ .name = "timer4",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer4_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_4_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer4 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer4_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer5_hwmod = {
+ .name = "timer5",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer5_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_5_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer5 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer5_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer6_hwmod = {
+ .name = "timer6",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer6_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_6_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer6 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer6_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer7_hwmod = {
+ .name = "timer7",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer7_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_7_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer7 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer7_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* EMAC Ethernet */
+static struct omap_hwmod_class_sysconfig dm816x_emac_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x4,
+ .sysc_flags = SYSC_HAS_SOFTRESET,
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class dm816x_emac_hwmod_class = {
+ .name = "emac",
+ .sysc = &dm816x_emac_sysc,
+};
+
+/*
+ * On dm816x the MDIO is within EMAC0. As the MDIO driver is a separate
+ * driver probed before EMAC0, we let MDIO do the clock idling.
+ */
+static struct omap_hwmod dm816x_emac0_hwmod = {
+ .name = "emac0",
+ .clkdm_name = "alwon_ethernet_clkdm",
+ .class = &dm816x_emac_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_hs__emac0 = {
+ .master = &dm816x_l4_hs_hwmod,
+ .slave = &dm816x_emac0_hwmod,
+ .clk = "sysclk5_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class dm816x_mdio_hwmod_class = {
+ .name = "davinci_mdio",
+ .sysc = &dm816x_emac_sysc,
+};
+
+struct omap_hwmod dm816x_emac0_mdio_hwmod = {
+ .name = "davinci_mdio",
+ .class = &dm816x_mdio_hwmod_class,
+ .clkdm_name = "alwon_ethernet_clkdm",
+ .main_clk = "sysclk24_ck",
+ .flags = HWMOD_NO_IDLEST,
+ /*
+ * REVISIT: This should be moved to the emac0_hwmod
+ * once we have a better way to handle device slaves.
+ */
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_ETHERNET_0_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_emac0__mdio = {
+ .master = &dm816x_l4_hs_hwmod,
+ .slave = &dm816x_emac0_mdio_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_emac1_hwmod = {
+ .name = "emac1",
+ .clkdm_name = "alwon_ethernet_clkdm",
+ .main_clk = "sysclk24_ck",
+ .flags = HWMOD_NO_IDLEST,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_ETHERNET_1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &dm816x_emac_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_hs__emac1 = {
+ .master = &dm816x_l4_hs_hwmod,
+ .slave = &dm816x_emac1_hwmod,
+ .clk = "sysclk5_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm816x_mmc_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x110,
+ .syss_offs = 0x114,
+ .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 dm816x_mmc_class = {
+ .name = "mmc",
+ .sysc = &dm816x_mmc_sysc,
+};
+
+static struct omap_hwmod_opt_clk dm816x_mmc1_opt_clks[] = {
+ { .role = "dbck", .clk = "sysclk18_ck", },
+};
+
+static struct omap_hsmmc_dev_attr mmc1_dev_attr = {
+ .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
+};
+
+static struct omap_hwmod dm816x_mmc1_hwmod = {
+ .name = "mmc1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .opt_clks = dm816x_mmc1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dm816x_mmc1_opt_clks),
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_SDIO_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mmc1_dev_attr,
+ .class = &dm816x_mmc_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__mmc1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_mmc1_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+ .flags = OMAP_FIREWALL_L4
+};
+
+static struct omap_hwmod_class_sysconfig dm816x_mcspi_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x110,
+ .syss_offs = 0x114,
+ .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 dm816x_mcspi_class = {
+ .name = "mcspi",
+ .sysc = &dm816x_mcspi_sysc,
+ .rev = OMAP3_MCSPI_REV,
+};
+
+static struct omap2_mcspi_dev_attr dm816x_mcspi1_dev_attr = {
+ .num_chipselect = 4,
+};
+
+static struct omap_hwmod dm816x_mcspi1_hwmod = {
+ .name = "mcspi1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_SPI_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &dm816x_mcspi_class,
+ .dev_attr = &dm816x_mcspi1_dev_attr,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__mcspi1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_mcspi1_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm816x_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 dm816x_mailbox_hwmod_class = {
+ .name = "mailbox",
+ .sysc = &dm816x_mailbox_sysc,
+};
+
+static struct omap_hwmod dm816x_mailbox_hwmod = {
+ .name = "mailbox",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &dm816x_mailbox_hwmod_class,
+ .main_clk = "sysclk6_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_MAILBOX_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__mailbox = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_mailbox_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class dm816x_tpcc_hwmod_class = {
+ .name = "tpcc",
+};
+
+struct omap_hwmod dm816x_tpcc_hwmod = {
+ .name = "tpcc",
+ .class = &dm816x_tpcc_hwmod_class,
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TPCC_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tpcc = {
+ .master = &dm816x_alwon_l3_fast_hwmod,
+ .slave = &dm816x_tpcc_hwmod,
+ .clk = "sysclk4_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space dm816x_tptc0_addr_space[] = {
+ {
+ .pa_start = 0x49800000,
+ .pa_end = 0x49800000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { },
+};
+
+static struct omap_hwmod_class dm816x_tptc0_hwmod_class = {
+ .name = "tptc0",
+};
+
+struct omap_hwmod dm816x_tptc0_hwmod = {
+ .name = "tptc0",
+ .class = &dm816x_tptc0_hwmod_class,
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TPTC0_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc0 = {
+ .master = &dm816x_alwon_l3_fast_hwmod,
+ .slave = &dm816x_tptc0_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc0_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if dm816x_tptc0__alwon_l3_fast = {
+ .master = &dm816x_tptc0_hwmod,
+ .slave = &dm816x_alwon_l3_fast_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc0_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space dm816x_tptc1_addr_space[] = {
+ {
+ .pa_start = 0x49900000,
+ .pa_end = 0x49900000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { },
+};
+
+static struct omap_hwmod_class dm816x_tptc1_hwmod_class = {
+ .name = "tptc1",
+};
+
+struct omap_hwmod dm816x_tptc1_hwmod = {
+ .name = "tptc1",
+ .class = &dm816x_tptc1_hwmod_class,
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TPTC1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc1 = {
+ .master = &dm816x_alwon_l3_fast_hwmod,
+ .slave = &dm816x_tptc1_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc1_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if dm816x_tptc1__alwon_l3_fast = {
+ .master = &dm816x_tptc1_hwmod,
+ .slave = &dm816x_alwon_l3_fast_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc1_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space dm816x_tptc2_addr_space[] = {
+ {
+ .pa_start = 0x49a00000,
+ .pa_end = 0x49a00000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { },
+};
+
+static struct omap_hwmod_class dm816x_tptc2_hwmod_class = {
+ .name = "tptc2",
+};
+
+struct omap_hwmod dm816x_tptc2_hwmod = {
+ .name = "tptc2",
+ .class = &dm816x_tptc2_hwmod_class,
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TPTC2_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc2 = {
+ .master = &dm816x_alwon_l3_fast_hwmod,
+ .slave = &dm816x_tptc2_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if dm816x_tptc2__alwon_l3_fast = {
+ .master = &dm816x_tptc2_hwmod,
+ .slave = &dm816x_alwon_l3_fast_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space dm816x_tptc3_addr_space[] = {
+ {
+ .pa_start = 0x49b00000,
+ .pa_end = 0x49b00000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { },
+};
+
+static struct omap_hwmod_class dm816x_tptc3_hwmod_class = {
+ .name = "tptc3",
+};
+
+struct omap_hwmod dm816x_tptc3_hwmod = {
+ .name = "tptc3",
+ .class = &dm816x_tptc3_hwmod_class,
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TPTC3_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc3 = {
+ .master = &dm816x_alwon_l3_fast_hwmod,
+ .slave = &dm816x_tptc3_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc3_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if dm816x_tptc3__alwon_l3_fast = {
+ .master = &dm816x_tptc3_hwmod,
+ .slave = &dm816x_alwon_l3_fast_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc3_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = {
+ &dm816x_mpu__alwon_l3_slow,
+ &dm816x_mpu__alwon_l3_med,
+ &dm816x_alwon_l3_slow__l4_ls,
+ &dm816x_alwon_l3_slow__l4_hs,
+ &dm816x_l4_ls__uart1,
+ &dm816x_l4_ls__uart2,
+ &dm816x_l4_ls__uart3,
+ &dm816x_l4_ls__wd_timer1,
+ &dm816x_l4_ls__i2c1,
+ &dm816x_l4_ls__i2c2,
+ &dm81xx_l4_ls__gpio1,
+ &dm81xx_l4_ls__gpio2,
+ &dm81xx_l4_ls__elm,
+ &dm816x_l4_ls__mmc1,
+ &dm816x_l4_ls__timer1,
+ &dm816x_l4_ls__timer2,
+ &dm816x_l4_ls__timer3,
+ &dm816x_l4_ls__timer4,
+ &dm816x_l4_ls__timer5,
+ &dm816x_l4_ls__timer6,
+ &dm816x_l4_ls__timer7,
+ &dm816x_l4_ls__mcspi1,
+ &dm816x_l4_ls__mailbox,
+ &dm816x_l4_hs__emac0,
+ &dm816x_emac0__mdio,
+ &dm816x_l4_hs__emac1,
+ &dm816x_alwon_l3_fast__tpcc,
+ &dm816x_alwon_l3_fast__tptc0,
+ &dm816x_alwon_l3_fast__tptc1,
+ &dm816x_alwon_l3_fast__tptc2,
+ &dm816x_alwon_l3_fast__tptc3,
+ &dm816x_tptc0__alwon_l3_fast,
+ &dm816x_tptc1__alwon_l3_fast,
+ &dm816x_tptc2__alwon_l3_fast,
+ &dm816x_tptc3__alwon_l3_fast,
+ &dm81xx_alwon_l3_slow__gpmc,
+ &dm81xx_default_l3_slow__usbss,
+ NULL,
+};
+
+int __init ti81xx_hwmod_init(void)
+{
+ omap_hwmod_init();
+ return omap_hwmod_register_links(dm816x_hwmod_ocp_ifs);
+}
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 000000000..79d623b83
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_common_data.c
@@ -0,0 +1,65 @@
+/*
+ * 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 "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,
+ .dmadisable_shift = SYSC_TYPE2_DMADISABLE_SHIFT,
+};
+
+/**
+ * struct omap_hwmod_sysc_type3 - TYPE3 sysconfig scheme.
+ * Used by some IPs on AM33xx
+ */
+struct omap_hwmod_sysc_fields omap_hwmod_sysc_type3 = {
+ .midle_shift = SYSC_TYPE3_MIDLEMODE_SHIFT,
+ .sidle_shift = SYSC_TYPE3_SIDLEMODE_SHIFT,
+};
+
+struct omap_dss_dispc_dev_attr omap2_3_dss_dispc_dev_attr = {
+ .manager_count = 2,
+ .has_framedonetv_irq = 0
+};
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 000000000..11ed5a17d
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_common_data.h
@@ -0,0 +1,171 @@
+/*
+ * omap_hwmod_common_data.h - OMAP hwmod common macros and declarations
+ *
+ * Copyright (C) 2010-2011 Nokia Corporation
+ * Copyright (C) 2010-2012 Texas Instruments, Inc.
+ * Paul Walmsley
+ * 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 "omap_hwmod.h"
+
+#include "common.h"
+#include "display.h"
+
+/* Common address space across OMAP2xxx/3xxx */
+extern struct omap_hwmod_addr_space omap2_i2c1_addr_space[];
+extern struct omap_hwmod_addr_space omap2_i2c2_addr_space[];
+extern struct omap_hwmod_addr_space omap2_dss_addrs[];
+extern struct omap_hwmod_addr_space omap2_dss_dispc_addrs[];
+extern struct omap_hwmod_addr_space omap2_dss_rfbi_addrs[];
+extern struct omap_hwmod_addr_space omap2_dss_venc_addrs[];
+extern struct omap_hwmod_addr_space omap2_timer10_addrs[];
+extern struct omap_hwmod_addr_space omap2_timer11_addrs[];
+extern struct omap_hwmod_addr_space omap2430_mmc1_addr_space[];
+extern struct omap_hwmod_addr_space omap2430_mmc2_addr_space[];
+extern struct omap_hwmod_addr_space omap2_mcspi1_addr_space[];
+extern struct omap_hwmod_addr_space omap2_mcspi2_addr_space[];
+extern struct omap_hwmod_addr_space omap2430_mcspi3_addr_space[];
+extern struct omap_hwmod_addr_space omap2_dma_system_addrs[];
+extern struct omap_hwmod_addr_space omap2_mcbsp1_addrs[];
+extern struct omap_hwmod_addr_space omap2_hdq1w_addr_space[];
+
+/* Common IP block data across OMAP2xxx */
+extern struct omap_gpio_dev_attr omap2xxx_gpio_dev_attr;
+extern struct omap_hwmod omap2xxx_l3_main_hwmod;
+extern struct omap_hwmod omap2xxx_l4_core_hwmod;
+extern struct omap_hwmod omap2xxx_l4_wkup_hwmod;
+extern struct omap_hwmod omap2xxx_mpu_hwmod;
+extern struct omap_hwmod omap2xxx_iva_hwmod;
+extern struct omap_hwmod omap2xxx_timer1_hwmod;
+extern struct omap_hwmod omap2xxx_timer2_hwmod;
+extern struct omap_hwmod omap2xxx_timer3_hwmod;
+extern struct omap_hwmod omap2xxx_timer4_hwmod;
+extern struct omap_hwmod omap2xxx_timer5_hwmod;
+extern struct omap_hwmod omap2xxx_timer6_hwmod;
+extern struct omap_hwmod omap2xxx_timer7_hwmod;
+extern struct omap_hwmod omap2xxx_timer8_hwmod;
+extern struct omap_hwmod omap2xxx_timer9_hwmod;
+extern struct omap_hwmod omap2xxx_timer10_hwmod;
+extern struct omap_hwmod omap2xxx_timer11_hwmod;
+extern struct omap_hwmod omap2xxx_timer12_hwmod;
+extern struct omap_hwmod omap2xxx_wd_timer2_hwmod;
+extern struct omap_hwmod omap2xxx_uart1_hwmod;
+extern struct omap_hwmod omap2xxx_uart2_hwmod;
+extern struct omap_hwmod omap2xxx_uart3_hwmod;
+extern struct omap_hwmod omap2xxx_dss_core_hwmod;
+extern struct omap_hwmod omap2xxx_dss_dispc_hwmod;
+extern struct omap_hwmod omap2xxx_dss_rfbi_hwmod;
+extern struct omap_hwmod omap2xxx_dss_venc_hwmod;
+extern struct omap_hwmod omap2xxx_gpio1_hwmod;
+extern struct omap_hwmod omap2xxx_gpio2_hwmod;
+extern struct omap_hwmod omap2xxx_gpio3_hwmod;
+extern struct omap_hwmod omap2xxx_gpio4_hwmod;
+extern struct omap_hwmod omap2xxx_mcspi1_hwmod;
+extern struct omap_hwmod omap2xxx_mcspi2_hwmod;
+extern struct omap_hwmod omap2xxx_counter_32k_hwmod;
+extern struct omap_hwmod omap2xxx_gpmc_hwmod;
+extern struct omap_hwmod omap2xxx_rng_hwmod;
+extern struct omap_hwmod omap2xxx_sham_hwmod;
+extern struct omap_hwmod omap2xxx_aes_hwmod;
+
+/* Common interface data across OMAP2xxx */
+extern struct omap_hwmod_ocp_if omap2xxx_l3_main__l4_core;
+extern struct omap_hwmod_ocp_if omap2xxx_mpu__l3_main;
+extern struct omap_hwmod_ocp_if omap2xxx_dss__l3;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__l4_wkup;
+extern struct omap_hwmod_ocp_if omap2_l4_core__uart1;
+extern struct omap_hwmod_ocp_if omap2_l4_core__uart2;
+extern struct omap_hwmod_ocp_if omap2_l4_core__uart3;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__mcspi1;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__mcspi2;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer2;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer3;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer4;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer5;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer6;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer7;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer8;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer9;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer10;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer11;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer12;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__dss;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_dispc;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_rfbi;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_venc;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__rng;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__sham;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__aes;
+
+/* Common IP block data */
+extern struct omap_hwmod_dma_info omap2_uart1_sdma_reqs[];
+extern struct omap_hwmod_dma_info omap2_uart2_sdma_reqs[];
+extern struct omap_hwmod_dma_info omap2_uart3_sdma_reqs[];
+extern struct omap_hwmod_dma_info omap2_i2c1_sdma_reqs[];
+extern struct omap_hwmod_dma_info omap2_i2c2_sdma_reqs[];
+extern struct omap_hwmod_dma_info omap2_mcspi1_sdma_reqs[];
+extern struct omap_hwmod_dma_info omap2_mcspi2_sdma_reqs[];
+extern struct omap_hwmod_dma_info omap2_mcbsp1_sdma_reqs[];
+extern struct omap_hwmod_dma_info omap2_mcbsp2_sdma_reqs[];
+
+/* Common IP block data on OMAP2430/OMAP3 */
+extern struct omap_hwmod_dma_info omap2_mcbsp3_sdma_reqs[];
+
+/* Common IP block data across OMAP2/3 */
+extern struct omap_hwmod_irq_info omap2_timer1_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_timer2_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_timer3_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_timer4_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_timer5_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_timer6_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_timer7_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_timer8_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_timer9_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_timer10_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_timer11_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_uart1_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_uart2_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_uart3_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_dispc_irqs[];
+extern struct omap_hwmod_irq_info omap2_i2c1_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_i2c2_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_gpio1_irqs[];
+extern struct omap_hwmod_irq_info omap2_gpio2_irqs[];
+extern struct omap_hwmod_irq_info omap2_gpio3_irqs[];
+extern struct omap_hwmod_irq_info omap2_gpio4_irqs[];
+extern struct omap_hwmod_irq_info omap2_dma_system_irqs[];
+extern struct omap_hwmod_irq_info omap2_mcspi1_mpu_irqs[];
+extern struct omap_hwmod_irq_info omap2_mcspi2_mpu_irqs[];
+extern struct omap_hwmod_addr_space omap2xxx_timer12_addrs[];
+extern struct omap_hwmod_irq_info omap2_hdq1w_mpu_irqs[];
+
+/* 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;
+extern struct omap_hwmod_class omap2_uart_class;
+extern struct omap_hwmod_class omap2_dss_hwmod_class;
+extern struct omap_hwmod_class omap2_dispc_hwmod_class;
+extern struct omap_hwmod_class omap2_rfbi_hwmod_class;
+extern struct omap_hwmod_class omap2_venc_hwmod_class;
+extern struct omap_hwmod_class_sysconfig omap2_hdq1w_sysc;
+extern struct omap_hwmod_class omap2_hdq1w_class;
+
+extern struct omap_hwmod_class omap2xxx_timer_hwmod_class;
+extern struct omap_hwmod_class omap2xxx_wd_timer_hwmod_class;
+extern struct omap_hwmod_class omap2xxx_gpio_hwmod_class;
+extern struct omap_hwmod_class omap2xxx_dma_hwmod_class;
+extern struct omap_hwmod_class omap2xxx_mailbox_hwmod_class;
+extern struct omap_hwmod_class omap2xxx_mcspi_class;
+
+extern struct omap_dss_dispc_dev_attr omap2_3_dss_dispc_dev_attr;
+
+#endif
diff --git a/arch/arm/mach-omap2/omap_hwmod_common_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_common_ipblock_data.c
new file mode 100644
index 000000000..f21664da2
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_common_ipblock_data.c
@@ -0,0 +1,55 @@
+/*
+ * omap_hwmod_common_ipblock_data.c - common IP block data for OMAP2+
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * 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 "omap_hwmod.h"
+#include "omap_hwmod_common_data.h"
+
+/*
+ * 'dss' class
+ * display sub-system
+ */
+
+static struct omap_hwmod_class_sysconfig omap2_dss_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+ SYSS_HAS_RESET_STATUS),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+struct omap_hwmod_class omap2_dss_hwmod_class = {
+ .name = "dss",
+ .sysc = &omap2_dss_sysc,
+ .reset = omap_dss_reset,
+};
+
+/*
+ * 'rfbi' class
+ * remote frame buffer interface
+ */
+
+static struct omap_hwmod_class_sysconfig omap2_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,
+};
+
+struct omap_hwmod_class omap2_rfbi_hwmod_class = {
+ .name = "rfbi",
+ .sysc = &omap2_rfbi_sysc,
+};
+
diff --git a/arch/arm/mach-omap2/omap_hwmod_reset.c b/arch/arm/mach-omap2/omap_hwmod_reset.c
new file mode 100644
index 000000000..65e186c9d
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_reset.c
@@ -0,0 +1,53 @@
+/*
+ * OMAP IP block custom reset and preprogramming stubs
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * Paul Walmsley
+ *
+ * A small number of IP blocks need custom reset and preprogramming
+ * functions. The stubs in this file provide a standard way for the
+ * hwmod code to call these functions, which are to be located under
+ * drivers/.
+ *
+ * This program is free software; 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.
+ *
+ * You should have 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/errno.h>
+
+#include <sound/aess.h>
+
+#include "omap_hwmod.h"
+
+/**
+ * omap_hwmod_aess_preprogram - enable AESS internal autogating
+ * @oh: struct omap_hwmod *
+ *
+ * The AESS will not IdleAck to the PRCM until its internal autogating
+ * is enabled. Since internal autogating is disabled by default after
+ * AESS reset, we must enable autogating after the hwmod code resets
+ * the AESS. Returns 0.
+ */
+int omap_hwmod_aess_preprogram(struct omap_hwmod *oh)
+{
+ void __iomem *va;
+
+ va = omap_hwmod_get_mpu_rt_va(oh);
+ if (!va)
+ return -EINVAL;
+
+ aess_enable_autogating(va);
+
+ return 0;
+}
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 000000000..336fdfcf8
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_opp_data.h
@@ -0,0 +1,99 @@
+/*
+ * 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 "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 omap443x_vdd_mpu_volt_data[];
+extern struct omap_volt_data omap443x_vdd_iva_volt_data[];
+extern struct omap_volt_data omap443x_vdd_core_volt_data[];
+extern struct omap_volt_data omap446x_vdd_mpu_volt_data[];
+extern struct omap_volt_data omap446x_vdd_iva_volt_data[];
+extern struct omap_volt_data omap446x_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 000000000..8e903564e
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_phy_internal.c
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#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 <linux/usb/musb.h>
+
+#include "soc.h"
+#include "control.h"
+#include "usb.h"
+
+#define CONTROL_DEV_CONF 0x300
+#define PHY_PD 0x1
+
+/**
+ * omap4430_phy_power_down: disable MUSB PHY during early init
+ *
+ * OMAP4 MUSB PHY module is enabled by default on reset, but this will
+ * prevent core retention if not disabled by SW. USB driver will
+ * later on enable this, once and if the driver needs it.
+ */
+static int __init omap4430_phy_power_down(void)
+{
+ void __iomem *ctrl_base;
+
+ if (!cpu_is_omap44xx())
+ return 0;
+
+ ctrl_base = ioremap(OMAP443X_SCM_BASE, SZ_1K);
+ if (!ctrl_base) {
+ pr_err("control module ioremap failed\n");
+ return -ENOMEM;
+ }
+
+ /* Power down the phy */
+ writel_relaxed(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+
+ iounmap(ctrl_base);
+
+ return 0;
+}
+omap_early_initcall(omap4430_phy_power_down);
+
+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("Waiting for PHY clock good...\n");
+ while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2)
+ & CONF2_PHYCLKGD)) {
+ cpu_relax();
+
+ if (time_after(jiffies, timeout)) {
+ pr_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) {
+ case MUSB_HOST: /* Force VBUS valid, ID = 0 */
+ devconf2 |= CONF2_FORCE_HOST;
+ break;
+ case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */
+ devconf2 |= CONF2_FORCE_DEVICE;
+ break;
+ case MUSB_OTG: /* Don't override the VBUS/ID comparators */
+ devconf2 |= CONF2_NO_OVERRIDE;
+ break;
+ default:
+ pr_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 000000000..6bf626700
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -0,0 +1,254 @@
+/**
+ * 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 "soc.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 OMAP4_SRI2C_SLAVE_ADDR 0x12
+#define OMAP4_VDD_MPU_SR_VOLT_REG 0x55
+#define OMAP4_VDD_MPU_SR_CMD_REG 0x56
+#define OMAP4_VDD_IVA_SR_VOLT_REG 0x5B
+#define OMAP4_VDD_IVA_SR_CMD_REG 0x5C
+#define OMAP4_VDD_CORE_SR_VOLT_REG 0x61
+#define OMAP4_VDD_CORE_SR_CMD_REG 0x62
+
+#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
+
+static bool is_offset_valid;
+static u8 smps_offset;
+
+#define REG_SMPS_OFFSET 0xE0
+
+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;
+ }
+
+ if (!vsel)
+ return 0;
+ /*
+ * 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) * 1266) + 70900)) * 10;
+ else
+ return ((((vsel - 1) * 1266) + 60770)) * 10;
+}
+
+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;
+ }
+
+ if (!uv)
+ return 0x00;
+ /*
+ * 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 > twl6030_vsel_to_uv(0x39)) {
+ if (uv == 1350000)
+ return 0x3A;
+ pr_err("%s:OUT OF RANGE! non mapped vsel for %ld Vs max %ld\n",
+ __func__, uv, twl6030_vsel_to_uv(0x39));
+ return 0x3A;
+ }
+
+ if (smps_offset & 0x8)
+ return DIV_ROUND_UP(uv - 709000, 12660) + 1;
+ else
+ return DIV_ROUND_UP(uv - 607700, 12660) + 1;
+}
+
+static struct omap_voltdm_pmic omap3_mpu_pmic = {
+ .slew_rate = 4000,
+ .step_size = 12500,
+ .vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX,
+ .vddmin = 600000,
+ .vddmax = 1450000,
+ .vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
+ .volt_reg_addr = OMAP3_VDD_MPU_SR_CONTROL_REG,
+ .i2c_high_speed = true,
+ .vsel_to_uv = twl4030_vsel_to_uv,
+ .uv_to_vsel = twl4030_uv_to_vsel,
+};
+
+static struct omap_voltdm_pmic omap3_core_pmic = {
+ .slew_rate = 4000,
+ .step_size = 12500,
+ .vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX,
+ .vddmin = 600000,
+ .vddmax = 1450000,
+ .vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
+ .volt_reg_addr = OMAP3_VDD_CORE_SR_CONTROL_REG,
+ .i2c_high_speed = true,
+ .vsel_to_uv = twl4030_vsel_to_uv,
+ .uv_to_vsel = twl4030_uv_to_vsel,
+};
+
+static struct omap_voltdm_pmic omap4_mpu_pmic = {
+ .slew_rate = 4000,
+ .step_size = 12660,
+ .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
+ .vddmin = 0,
+ .vddmax = 2100000,
+ .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
+ .volt_reg_addr = OMAP4_VDD_MPU_SR_VOLT_REG,
+ .cmd_reg_addr = OMAP4_VDD_MPU_SR_CMD_REG,
+ .i2c_high_speed = true,
+ .i2c_pad_load = 3,
+ .vsel_to_uv = twl6030_vsel_to_uv,
+ .uv_to_vsel = twl6030_uv_to_vsel,
+};
+
+static struct omap_voltdm_pmic omap4_iva_pmic = {
+ .slew_rate = 4000,
+ .step_size = 12660,
+ .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
+ .vddmin = 0,
+ .vddmax = 2100000,
+ .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
+ .volt_reg_addr = OMAP4_VDD_IVA_SR_VOLT_REG,
+ .cmd_reg_addr = OMAP4_VDD_IVA_SR_CMD_REG,
+ .i2c_high_speed = true,
+ .i2c_pad_load = 3,
+ .vsel_to_uv = twl6030_vsel_to_uv,
+ .uv_to_vsel = twl6030_uv_to_vsel,
+};
+
+static struct omap_voltdm_pmic omap4_core_pmic = {
+ .slew_rate = 4000,
+ .step_size = 12660,
+ .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
+ .vddmin = 0,
+ .vddmax = 2100000,
+ .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
+ .volt_reg_addr = OMAP4_VDD_CORE_SR_VOLT_REG,
+ .cmd_reg_addr = OMAP4_VDD_CORE_SR_CMD_REG,
+ .i2c_high_speed = true,
+ .i2c_pad_load = 3,
+ .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 = voltdm_lookup("mpu");
+ omap_voltage_register_pmic(voltdm, &omap4_mpu_pmic);
+
+ voltdm = voltdm_lookup("iva");
+ omap_voltage_register_pmic(voltdm, &omap4_iva_pmic);
+
+ voltdm = voltdm_lookup("core");
+ omap_voltage_register_pmic(voltdm, &omap4_core_pmic);
+
+ return 0;
+}
+
+int __init omap3_twl_init(void)
+{
+ struct voltagedomain *voltdm;
+
+ if (!cpu_is_omap34xx())
+ return -ENODEV;
+
+ voltdm = voltdm_lookup("mpu_iva");
+ omap_voltage_register_pmic(voltdm, &omap3_mpu_pmic);
+
+ voltdm = voltdm_lookup("core");
+ omap_voltage_register_pmic(voltdm, &omap3_core_pmic);
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c
new file mode 100644
index 000000000..a358a07e1
--- /dev/null
+++ b/arch/arm/mach-omap2/opp.c
@@ -0,0 +1,104 @@
+/*
+ * 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/of.h>
+#include <linux/pm_opp.h>
+#include <linux/cpu.h>
+
+#include "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 (of_have_populated_dt())
+ return -EINVAL;
+
+ 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++, opp_def++) {
+ 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;
+ }
+
+ if (!strncmp(opp_def->hwmod_name, "mpu", 3)) {
+ /*
+ * All current OMAPs share voltage rail and
+ * clock source, so CPU0 is used to represent
+ * the MPU-SS.
+ */
+ dev = get_cpu_device(0);
+ } else {
+ oh = omap_hwmod_lookup(opp_def->hwmod_name);
+ if (!oh || !oh->od) {
+ pr_debug("%s: no hwmod or odev for %s, [%d] cannot add OPPs.\n",
+ __func__, opp_def->hwmod_name, i);
+ continue;
+ }
+ dev = &oh->od->pdev->dev;
+ }
+
+ r = dev_pm_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 = dev_pm_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);
+ }
+ }
+
+ 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 000000000..a9e8cf217
--- /dev/null
+++ b/arch/arm/mach-omap2/opp2420_data.c
@@ -0,0 +1,130 @@
+/*
+ * 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 <linux/kernel.h>
+
+#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 000000000..0e75ec3e1
--- /dev/null
+++ b/arch/arm/mach-omap2/opp2430_data.c
@@ -0,0 +1,135 @@
+/*
+ * 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 <linux/kernel.h>
+
+#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 000000000..8fae534eb
--- /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 short 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 000000000..fc67add76
--- /dev/null
+++ b/arch/arm/mach-omap2/opp3xxx_data.c
@@ -0,0 +1,171 @@
+/*
+ * 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 "soc.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;
+}
+omap_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 000000000..1ef7a3e5c
--- /dev/null
+++ b/arch/arm/mach-omap2/opp4xxx_data.c
@@ -0,0 +1,180 @@
+/*
+ * OMAP4 OPP table definitions.
+ *
+ * Copyright (C) 2010-2012 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 "soc.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 omap443x_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 omap443x_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 omap443x_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 omap443x_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 */
+};
+
+#define OMAP4460_VDD_MPU_OPP50_UV 1025000
+#define OMAP4460_VDD_MPU_OPP100_UV 1200000
+#define OMAP4460_VDD_MPU_OPPTURBO_UV 1313000
+#define OMAP4460_VDD_MPU_OPPNITRO_UV 1375000
+
+struct omap_volt_data omap446x_vdd_mpu_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
+ VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+#define OMAP4460_VDD_IVA_OPP50_UV 1025000
+#define OMAP4460_VDD_IVA_OPP100_UV 1200000
+#define OMAP4460_VDD_IVA_OPPTURBO_UV 1313000
+#define OMAP4460_VDD_IVA_OPPNITRO_UV 1375000
+
+struct omap_volt_data omap446x_vdd_iva_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
+ VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO, 0xfa, 0x23),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+#define OMAP4460_VDD_CORE_OPP50_UV 1025000
+#define OMAP4460_VDD_CORE_OPP100_UV 1200000
+#define OMAP4460_VDD_CORE_OPP100_OV_UV 1250000
+
+struct omap_volt_data omap446x_vdd_core_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_OV_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+static struct omap_opp_def __initdata omap446x_opp_def_list[] = {
+ /* MPU OPP1 - OPP50 */
+ OPP_INITIALIZER("mpu", true, 350000000, OMAP4460_VDD_MPU_OPP50_UV),
+ /* MPU OPP2 - OPP100 */
+ OPP_INITIALIZER("mpu", true, 700000000, OMAP4460_VDD_MPU_OPP100_UV),
+ /* MPU OPP3 - OPP-Turbo */
+ OPP_INITIALIZER("mpu", true, 920000000, OMAP4460_VDD_MPU_OPPTURBO_UV),
+ /*
+ * MPU OPP4 - OPP-Nitro + Disabled as the reference schematics
+ * recommends TPS623631 - confirm and enable the opp in board file
+ * XXX: May be we should enable these based on mpu capability and
+ * Exception board files disable it...
+ */
+ OPP_INITIALIZER("mpu", false, 1200000000, OMAP4460_VDD_MPU_OPPNITRO_UV),
+ /* MPU OPP4 - OPP-Nitro SpeedBin */
+ OPP_INITIALIZER("mpu", false, 1500000000, OMAP4460_VDD_MPU_OPPNITRO_UV),
+ /* L3 OPP1 - OPP50 */
+ OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4460_VDD_CORE_OPP50_UV),
+ /* L3 OPP2 - OPP100 */
+ OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4460_VDD_CORE_OPP100_UV),
+ /* IVA OPP1 - OPP50 */
+ OPP_INITIALIZER("iva", true, 133000000, OMAP4460_VDD_IVA_OPP50_UV),
+ /* IVA OPP2 - OPP100 */
+ OPP_INITIALIZER("iva", true, 266100000, OMAP4460_VDD_IVA_OPP100_UV),
+ /*
+ * IVA OPP3 - OPP-Turbo + Disabled as the reference schematics
+ * recommends Phoenix VCORE2 which can supply only 600mA - so the ones
+ * above this OPP frequency, even though OMAP is capable, should be
+ * enabled by board file which is sure of the chip power capability
+ */
+ OPP_INITIALIZER("iva", false, 332000000, OMAP4460_VDD_IVA_OPPTURBO_UV),
+ /* IVA OPP4 - OPP-Nitro */
+ OPP_INITIALIZER("iva", false, 430000000, OMAP4460_VDD_IVA_OPPNITRO_UV),
+ /* IVA OPP5 - OPP-Nitro SpeedBin*/
+ OPP_INITIALIZER("iva", false, 500000000, OMAP4460_VDD_IVA_OPPNITRO_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_omap443x())
+ r = omap_init_opp_table(omap443x_opp_def_list,
+ ARRAY_SIZE(omap443x_opp_def_list));
+ else if (cpu_is_omap446x())
+ r = omap_init_opp_table(omap446x_opp_def_list,
+ ARRAY_SIZE(omap446x_opp_def_list));
+ return r;
+}
+omap_device_initcall(omap4_opp_init);
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
new file mode 100644
index 000000000..af11511dd
--- /dev/null
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -0,0 +1,388 @@
+/*
+ * Legacy platform_data quirks
+ *
+ * Copyright (C) 2013 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/clk.h>
+#include <linux/davinci_emac.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of_platform.h>
+#include <linux/ti_wilink_st.h>
+
+#include <linux/platform_data/pinctrl-single.h>
+#include <linux/platform_data/iommu-omap.h>
+
+#include "common.h"
+#include "common-board-devices.h"
+#include "dss-common.h"
+#include "control.h"
+#include "omap_device.h"
+#include "omap-secure.h"
+#include "soc.h"
+
+struct pdata_init {
+ const char *compatible;
+ void (*fn)(void);
+};
+
+struct of_dev_auxdata omap_auxdata_lookup[];
+static struct twl4030_gpio_platform_data twl_gpio_auxdata;
+
+#ifdef CONFIG_MACH_NOKIA_N8X0
+static void __init omap2420_n8x0_legacy_init(void)
+{
+ omap_auxdata_lookup[0].platform_data = n8x0_legacy_init();
+}
+#else
+#define omap2420_n8x0_legacy_init NULL
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+static void __init hsmmc2_internal_input_clk(void)
+{
+ u32 reg;
+
+ reg = omap_ctrl_readl(OMAP343X_CONTROL_DEVCONF1);
+ reg |= OMAP2_MMCSDIO2ADPCLKISEL;
+ omap_ctrl_writel(reg, OMAP343X_CONTROL_DEVCONF1);
+}
+
+static struct iommu_platform_data omap3_iommu_pdata = {
+ .reset_name = "mmu",
+ .assert_reset = omap_device_assert_hardreset,
+ .deassert_reset = omap_device_deassert_hardreset,
+};
+
+static int omap3_sbc_t3730_twl_callback(struct device *dev,
+ unsigned gpio,
+ unsigned ngpio)
+{
+ int res;
+
+ res = gpio_request_one(gpio + 2, GPIOF_OUT_INIT_HIGH,
+ "wlan pwr");
+ if (res)
+ return res;
+
+ gpio_export(gpio, 0);
+
+ return 0;
+}
+
+static void __init omap3_sbc_t3x_usb_hub_init(int gpio, char *hub_name)
+{
+ int err = gpio_request_one(gpio, GPIOF_OUT_INIT_LOW, hub_name);
+
+ if (err) {
+ pr_err("SBC-T3x: %s reset gpio request failed: %d\n",
+ hub_name, err);
+ return;
+ }
+
+ gpio_export(gpio, 0);
+
+ udelay(10);
+ gpio_set_value(gpio, 1);
+ msleep(1);
+}
+
+static void __init omap3_sbc_t3730_twl_init(void)
+{
+ twl_gpio_auxdata.setup = omap3_sbc_t3730_twl_callback;
+}
+
+static void __init omap3_sbc_t3730_legacy_init(void)
+{
+ omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub");
+}
+
+static void __init omap3_sbc_t3530_legacy_init(void)
+{
+ omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub");
+}
+
+struct ti_st_plat_data wilink_pdata = {
+ .nshutdown_gpio = 137,
+ .dev_name = "/dev/ttyO1",
+ .flow_cntrl = 1,
+ .baud_rate = 300000,
+};
+
+static struct platform_device wl18xx_device = {
+ .name = "kim",
+ .id = -1,
+ .dev = {
+ .platform_data = &wilink_pdata,
+ }
+};
+
+static struct platform_device btwilink_device = {
+ .name = "btwilink",
+ .id = -1,
+};
+
+static void __init omap3_igep0020_rev_f_legacy_init(void)
+{
+ platform_device_register(&wl18xx_device);
+ platform_device_register(&btwilink_device);
+}
+
+static void __init omap3_igep0030_rev_g_legacy_init(void)
+{
+ platform_device_register(&wl18xx_device);
+ platform_device_register(&btwilink_device);
+}
+
+static void __init omap3_evm_legacy_init(void)
+{
+ hsmmc2_internal_input_clk();
+}
+
+static void am35xx_enable_emac_int(void)
+{
+ u32 v;
+
+ v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+ v |= (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(v, AM35XX_CONTROL_LVL_INTR_CLEAR);
+ omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */
+}
+
+static void am35xx_disable_emac_int(void)
+{
+ u32 v;
+
+ v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+ v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR);
+ omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR);
+ omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */
+}
+
+static struct emac_platform_data am35xx_emac_pdata = {
+ .interrupt_enable = am35xx_enable_emac_int,
+ .interrupt_disable = am35xx_disable_emac_int,
+};
+
+static void __init am35xx_emac_reset(void)
+{
+ u32 v;
+
+ v = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
+ v &= ~AM35XX_CPGMACSS_SW_RST;
+ omap_ctrl_writel(v, AM35XX_CONTROL_IP_SW_RESET);
+ omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */
+}
+
+static struct gpio cm_t3517_wlan_gpios[] __initdata = {
+ { 56, GPIOF_OUT_INIT_HIGH, "wlan pwr" },
+ { 4, GPIOF_OUT_INIT_HIGH, "xcvr noe" },
+};
+
+static void __init omap3_sbc_t3517_wifi_init(void)
+{
+ int err = gpio_request_array(cm_t3517_wlan_gpios,
+ ARRAY_SIZE(cm_t3517_wlan_gpios));
+ if (err) {
+ pr_err("SBC-T3517: wl12xx gpios request failed: %d\n", err);
+ return;
+ }
+
+ gpio_export(cm_t3517_wlan_gpios[0].gpio, 0);
+ gpio_export(cm_t3517_wlan_gpios[1].gpio, 0);
+
+ msleep(100);
+ gpio_set_value(cm_t3517_wlan_gpios[1].gpio, 0);
+}
+
+static void __init omap3_sbc_t3517_legacy_init(void)
+{
+ omap3_sbc_t3x_usb_hub_init(152, "cm-t3517 usb hub");
+ omap3_sbc_t3x_usb_hub_init(98, "sb-t35 usb hub");
+ am35xx_emac_reset();
+ hsmmc2_internal_input_clk();
+ omap3_sbc_t3517_wifi_init();
+}
+
+static void __init am3517_evm_legacy_init(void)
+{
+ am35xx_emac_reset();
+}
+
+static struct platform_device omap3_rom_rng_device = {
+ .name = "omap3-rom-rng",
+ .id = -1,
+ .dev = {
+ .platform_data = rx51_secure_rng_call,
+ },
+};
+
+static void __init nokia_n900_legacy_init(void)
+{
+ hsmmc2_internal_input_clk();
+
+ if (omap_type() == OMAP2_DEVICE_TYPE_SEC) {
+ if (IS_ENABLED(CONFIG_ARM_ERRATA_430973)) {
+ pr_info("RX-51: Enabling ARM errata 430973 workaround\n");
+ /* set IBE to 1 */
+ rx51_secure_update_aux_cr(BIT(6), 0);
+ } else {
+ pr_warn("RX-51: Not enabling ARM errata 430973 workaround\n");
+ pr_warn("Thumb binaries may crash randomly without this workaround\n");
+ }
+
+ pr_info("RX-51: Registring OMAP3 HWRNG device\n");
+ platform_device_register(&omap3_rom_rng_device);
+
+ }
+}
+
+static void __init omap3_tao3530_legacy_init(void)
+{
+ hsmmc2_internal_input_clk();
+}
+#endif /* CONFIG_ARCH_OMAP3 */
+
+#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
+static struct iommu_platform_data omap4_iommu_pdata = {
+ .reset_name = "mmu_cache",
+ .assert_reset = omap_device_assert_hardreset,
+ .deassert_reset = omap_device_deassert_hardreset,
+};
+#endif
+
+#ifdef CONFIG_SOC_OMAP5
+static void __init omap5_uevm_legacy_init(void)
+{
+}
+#endif
+
+static struct pcs_pdata pcs_pdata;
+
+void omap_pcs_legacy_init(int irq, void (*rearm)(void))
+{
+ pcs_pdata.irq = irq;
+ pcs_pdata.rearm = rearm;
+}
+
+/*
+ * GPIOs for TWL are initialized by the I2C bus and need custom
+ * handing until DSS has device tree bindings.
+ */
+void omap_auxdata_legacy_init(struct device *dev)
+{
+ if (dev->platform_data)
+ return;
+
+ if (strcmp("twl4030-gpio", dev_name(dev)))
+ return;
+
+ dev->platform_data = &twl_gpio_auxdata;
+}
+
+/*
+ * Few boards still need auxdata populated before we populate
+ * the dev entries in of_platform_populate().
+ */
+static struct pdata_init auxdata_quirks[] __initdata = {
+#ifdef CONFIG_SOC_OMAP2420
+ { "nokia,n800", omap2420_n8x0_legacy_init, },
+ { "nokia,n810", omap2420_n8x0_legacy_init, },
+ { "nokia,n810-wimax", omap2420_n8x0_legacy_init, },
+#endif
+#ifdef CONFIG_ARCH_OMAP3
+ { "compulab,omap3-sbc-t3730", omap3_sbc_t3730_twl_init, },
+#endif
+ { /* sentinel */ },
+};
+
+struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
+#ifdef CONFIG_MACH_NOKIA_N8X0
+ OF_DEV_AUXDATA("ti,omap2420-mmc", 0x4809c000, "mmci-omap.0", NULL),
+ OF_DEV_AUXDATA("menelaus", 0x72, "1-0072", &n8x0_menelaus_platform_data),
+ OF_DEV_AUXDATA("tlv320aic3x", 0x18, "2-0018", &n810_aic33_data),
+#endif
+#ifdef CONFIG_ARCH_OMAP3
+ OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002030, "48002030.pinmux", &pcs_pdata),
+ OF_DEV_AUXDATA("ti,omap3-padconf", 0x480025a0, "480025a0.pinmux", &pcs_pdata),
+ OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002a00, "48002a00.pinmux", &pcs_pdata),
+ OF_DEV_AUXDATA("ti,omap2-iommu", 0x5d000000, "5d000000.mmu",
+ &omap3_iommu_pdata),
+ /* Only on am3517 */
+ OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL),
+ OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0",
+ &am35xx_emac_pdata),
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+ OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a100040, "4a100040.pinmux", &pcs_pdata),
+ OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a31e040, "4a31e040.pinmux", &pcs_pdata),
+#endif
+#ifdef CONFIG_SOC_OMAP5
+ OF_DEV_AUXDATA("ti,omap5-padconf", 0x4a002840, "4a002840.pinmux", &pcs_pdata),
+ OF_DEV_AUXDATA("ti,omap5-padconf", 0x4ae0c840, "4ae0c840.pinmux", &pcs_pdata),
+#endif
+#ifdef CONFIG_SOC_DRA7XX
+ OF_DEV_AUXDATA("ti,dra7-padconf", 0x4a003400, "4a003400.pinmux", &pcs_pdata),
+#endif
+#ifdef CONFIG_SOC_AM43XX
+ OF_DEV_AUXDATA("ti,am437-padconf", 0x44e10800, "44e10800.pinmux", &pcs_pdata),
+#endif
+#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
+ OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu",
+ &omap4_iommu_pdata),
+ OF_DEV_AUXDATA("ti,omap4-iommu", 0x55082000, "55082000.mmu",
+ &omap4_iommu_pdata),
+#endif
+ { /* sentinel */ },
+};
+
+/*
+ * Few boards still need to initialize some legacy devices with
+ * platform data until the drivers support device tree.
+ */
+static struct pdata_init pdata_quirks[] __initdata = {
+#ifdef CONFIG_ARCH_OMAP3
+ { "compulab,omap3-sbc-t3517", omap3_sbc_t3517_legacy_init, },
+ { "compulab,omap3-sbc-t3530", omap3_sbc_t3530_legacy_init, },
+ { "compulab,omap3-sbc-t3730", omap3_sbc_t3730_legacy_init, },
+ { "nokia,omap3-n900", nokia_n900_legacy_init, },
+ { "nokia,omap3-n9", hsmmc2_internal_input_clk, },
+ { "nokia,omap3-n950", hsmmc2_internal_input_clk, },
+ { "isee,omap3-igep0020-rev-f", omap3_igep0020_rev_f_legacy_init, },
+ { "isee,omap3-igep0030-rev-g", omap3_igep0030_rev_g_legacy_init, },
+ { "ti,omap3-evm-37xx", omap3_evm_legacy_init, },
+ { "ti,am3517-evm", am3517_evm_legacy_init, },
+ { "technexion,omap3-tao3530", omap3_tao3530_legacy_init, },
+#endif
+#ifdef CONFIG_SOC_OMAP5
+ { "ti,omap5-uevm", omap5_uevm_legacy_init, },
+#endif
+ { /* sentinel */ },
+};
+
+static void pdata_quirks_check(struct pdata_init *quirks)
+{
+ while (quirks->compatible) {
+ if (of_machine_is_compatible(quirks->compatible)) {
+ if (quirks->fn)
+ quirks->fn();
+ break;
+ }
+ quirks++;
+ }
+}
+
+void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table)
+{
+ omap_sdrc_init(NULL, NULL);
+ pdata_quirks_check(auxdata_quirks);
+ of_platform_populate(NULL, omap_dt_match_table,
+ omap_auxdata_lookup, NULL);
+ pdata_quirks_check(pdata_quirks);
+}
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
new file mode 100644
index 000000000..0b339861d
--- /dev/null
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -0,0 +1,282 @@
+/*
+ * 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 "clock.h"
+#include "powerdomain.h"
+#include "clockdomain.h"
+#include "omap-pm.h"
+
+#include "soc.h"
+#include "cm2xxx_3xxx.h"
+#include "prm2xxx_3xxx.h"
+#include "pm.h"
+
+u32 enable_off_mode;
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static int pm_dbg_init_done;
+
+static int pm_dbg_init(void);
+
+enum {
+ DEBUG_FILE_COUNTERS = 0,
+ DEBUG_FILE_TIMERS,
+};
+
+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)\n", clkdm->name, clkdm->pwrdm.ptr->name,
+ clkdm->usecount);
+
+ 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 const struct file_operations debug_fops = {
+ .open = pm_dbg_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+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);
+ if (d)
+ (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;
+
+ *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 __init pm_dbg_init(void)
+{
+ struct dentry *d;
+
+ if (pm_dbg_init_done)
+ return 0;
+
+ d = debugfs_create_dir("pm_debug", NULL);
+ if (!d)
+ return -EINVAL;
+
+ (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);
+
+ (void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d,
+ &enable_off_mode, &pm_dbg_option_fops);
+ pm_dbg_init_done = 1;
+
+ return 0;
+}
+omap_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 000000000..58920bc88
--- /dev/null
+++ b/arch/arm/mach-omap2/pm.c
@@ -0,0 +1,321 @@
+/*
+ * 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/pm_opp.h>
+#include <linux/export.h>
+#include <linux/suspend.h>
+#include <linux/cpu.h>
+
+#include <asm/system_misc.h>
+
+#include "omap-pm.h"
+#include "omap_device.h"
+#include "common.h"
+
+#include "soc.h"
+#include "prcm-common.h"
+#include "voltage.h"
+#include "powerdomain.h"
+#include "clockdomain.h"
+#include "pm.h"
+#include "twl-common.h"
+
+#ifdef CONFIG_SUSPEND
+/*
+ * omap_pm_suspend: points to a function that does the SoC-specific
+ * suspend work
+ */
+static int (*omap_pm_suspend)(void);
+#endif
+
+#ifdef CONFIG_PM
+/**
+ * struct omap2_oscillator - Describe the board main oscillator latencies
+ * @startup_time: oscillator startup latency
+ * @shutdown_time: oscillator shutdown latency
+ */
+struct omap2_oscillator {
+ u32 startup_time;
+ u32 shutdown_time;
+};
+
+static struct omap2_oscillator oscillator = {
+ .startup_time = ULONG_MAX,
+ .shutdown_time = ULONG_MAX,
+};
+
+void omap_pm_setup_oscillator(u32 tstart, u32 tshut)
+{
+ oscillator.startup_time = tstart;
+ oscillator.shutdown_time = tshut;
+}
+
+void omap_pm_get_oscillator(u32 *tstart, u32 *tshut)
+{
+ if (!tstart || !tshut)
+ return;
+
+ *tstart = oscillator.startup_time;
+ *tshut = oscillator.shutdown_time;
+}
+#endif
+
+static int __init _init_omap_device(char *name)
+{
+ struct omap_hwmod *oh;
+ struct platform_device *pdev;
+
+ oh = omap_hwmod_lookup(name);
+ if (WARN(!oh, "%s: could not find omap_hwmod for %s\n",
+ __func__, name))
+ return -ENODEV;
+
+ pdev = omap_device_build(oh->name, 0, oh, NULL, 0);
+ if (WARN(IS_ERR(pdev), "%s: could not build omap_device for %s\n",
+ __func__, name))
+ return -ENODEV;
+
+ return 0;
+}
+
+/*
+ * Build omap_devices for processors and bus.
+ */
+static void __init omap2_init_processor_devices(void)
+{
+ _init_omap_device("mpu");
+ if (omap3_has_iva())
+ _init_omap_device("iva");
+
+ if (cpu_is_omap44xx()) {
+ _init_omap_device("l3_main_1");
+ _init_omap_device("dsp");
+ _init_omap_device("iva");
+ } else {
+ _init_omap_device("l3_main");
+ }
+}
+
+int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
+{
+ /* XXX The usecount test is racy */
+ if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) &&
+ !(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING))
+ clkdm_allow_idle(clkdm);
+ else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
+ clkdm->usecount == 0)
+ clkdm_sleep(clkdm);
+ return 0;
+}
+
+/*
+ * This API is to be called during init to set 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 sets the voltage domain to the voltage specified
+ * in the opp entry
+ */
+static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
+ const char *oh_name)
+{
+ struct voltagedomain *voltdm;
+ struct clk *clk;
+ struct dev_pm_opp *opp;
+ unsigned long freq, bootup_volt;
+ struct device *dev;
+
+ if (!vdd_name || !clk_name || !oh_name) {
+ pr_err("%s: invalid parameters\n", __func__);
+ goto exit;
+ }
+
+ if (!strncmp(oh_name, "mpu", 3))
+ /*
+ * All current OMAPs share voltage rail and clock
+ * source, so CPU0 is used to represent the MPU-SS.
+ */
+ dev = get_cpu_device(0);
+ else
+ dev = omap_device_get_by_hwmod_name(oh_name);
+
+ if (IS_ERR(dev)) {
+ pr_err("%s: Unable to get dev pointer for hwmod %s\n",
+ __func__, oh_name);
+ goto exit;
+ }
+
+ voltdm = voltdm_lookup(vdd_name);
+ if (!voltdm) {
+ pr_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)) {
+ pr_err("%s: unable to get clk %s\n", __func__, clk_name);
+ goto exit;
+ }
+
+ freq = clk_get_rate(clk);
+ clk_put(clk);
+
+ rcu_read_lock();
+ opp = dev_pm_opp_find_freq_ceil(dev, &freq);
+ if (IS_ERR(opp)) {
+ rcu_read_unlock();
+ pr_err("%s: unable to find boot up OPP for vdd_%s\n",
+ __func__, vdd_name);
+ goto exit;
+ }
+
+ bootup_volt = dev_pm_opp_get_voltage(opp);
+ rcu_read_unlock();
+ if (!bootup_volt) {
+ pr_err("%s: unable to find voltage corresponding to the bootup OPP for vdd_%s\n",
+ __func__, vdd_name);
+ goto exit;
+ }
+
+ voltdm_scale(voltdm, bootup_volt);
+ return 0;
+
+exit:
+ pr_err("%s: unable to set vdd_%s\n", __func__, vdd_name);
+ return -EINVAL;
+}
+
+#ifdef CONFIG_SUSPEND
+static int omap_pm_enter(suspend_state_t suspend_state)
+{
+ int ret = 0;
+
+ if (!omap_pm_suspend)
+ return -ENOENT; /* XXX doublecheck */
+
+ switch (suspend_state) {
+ case PM_SUSPEND_STANDBY:
+ case PM_SUSPEND_MEM:
+ ret = omap_pm_suspend();
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int omap_pm_begin(suspend_state_t state)
+{
+ cpu_idle_poll_ctrl(true);
+ if (cpu_is_omap34xx())
+ omap_prcm_irq_prepare();
+ return 0;
+}
+
+static void omap_pm_end(void)
+{
+ cpu_idle_poll_ctrl(false);
+}
+
+static void omap_pm_finish(void)
+{
+ if (cpu_is_omap34xx())
+ omap_prcm_irq_complete();
+}
+
+static const struct platform_suspend_ops omap_pm_ops = {
+ .begin = omap_pm_begin,
+ .end = omap_pm_end,
+ .enter = omap_pm_enter,
+ .finish = omap_pm_finish,
+ .valid = suspend_valid_only_mem,
+};
+
+/**
+ * omap_common_suspend_init - Set common suspend routines for OMAP SoCs
+ * @pm_suspend: function pointer to SoC specific suspend function
+ */
+void omap_common_suspend_init(void *pm_suspend)
+{
+ omap_pm_suspend = pm_suspend;
+ suspend_set_ops(&omap_pm_ops);
+}
+#endif /* CONFIG_SUSPEND */
+
+static void __init omap3_init_voltages(void)
+{
+ if (!cpu_is_omap34xx())
+ return;
+
+ omap2_set_init_voltage("mpu_iva", "dpll1_ck", "mpu");
+ omap2_set_init_voltage("core", "l3_ick", "l3_main");
+}
+
+static void __init omap4_init_voltages(void)
+{
+ if (!cpu_is_omap44xx())
+ return;
+
+ omap2_set_init_voltage("mpu", "dpll_mpu_ck", "mpu");
+ omap2_set_init_voltage("core", "l3_div_ck", "l3_main_1");
+ omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", "iva");
+}
+
+static inline void omap_init_cpufreq(void)
+{
+ struct platform_device_info devinfo = { };
+
+ if (!of_have_populated_dt())
+ devinfo.name = "omap-cpufreq";
+ else
+ devinfo.name = "cpufreq-dt";
+ platform_device_register_full(&devinfo);
+}
+
+static int __init omap2_common_pm_init(void)
+{
+ if (!of_have_populated_dt())
+ omap2_init_processor_devices();
+ omap_pm_if_init();
+
+ return 0;
+}
+omap_postcore_initcall(omap2_common_pm_init);
+
+int __init omap2_common_pm_late_init(void)
+{
+ if (of_have_populated_dt()) {
+ omap3_twl_init();
+ omap4_twl_init();
+ }
+
+ /* Init the voltage layer */
+ omap_pmic_late_init();
+ omap_voltage_late_init();
+
+ /* Initialize the voltages */
+ omap3_init_voltages();
+ omap4_init_voltages();
+
+ /* Smartreflex device init */
+ omap_devinit_smartreflex();
+
+ /* cpufreq dummy device instantiation */
+ omap_init_cpufreq();
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
new file mode 100644
index 000000000..425bfcd67
--- /dev/null
+++ b/arch/arm/mach-omap2/pm.h
@@ -0,0 +1,157 @@
+/*
+ * 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"
+
+#ifdef CONFIG_CPU_IDLE
+extern int __init omap3_idle_init(void);
+extern int __init omap4_idle_init(void);
+#else
+static inline int omap3_idle_init(void)
+{
+ return 0;
+}
+
+static inline int omap4_idle_init(void)
+{
+ return 0;
+}
+#endif
+
+extern void *omap3_secure_ram_storage;
+extern void omap3_pm_off_mode_enable(int);
+extern void omap_sram_idle(void);
+extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused);
+
+#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
+
+extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm);
+extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
+
+#ifdef CONFIG_PM_DEBUG
+extern u32 enable_off_mode;
+#else
+#define enable_off_mode 0
+#endif
+
+#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
+extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev);
+#else
+#define pm_dbg_update_time(pwrdm, prev) do {} while (0);
+#endif /* CONFIG_PM_DEBUG */
+
+/* 24xx */
+extern void omap24xx_idle_loop_suspend(void);
+extern unsigned int omap24xx_idle_loop_suspend_sz;
+
+extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
+ void __iomem *sdrc_power);
+extern unsigned int omap24xx_cpu_suspend_sz;
+
+/* 3xxx */
+extern void omap34xx_cpu_suspend(int save_state);
+
+/* omap3_do_wfi function pointer and size, for copy to SRAM */
+extern void omap3_do_wfi(void);
+extern unsigned int omap3_do_wfi_sz;
+/* ... and its pointer from SRAM after copy */
+extern void (*omap3_do_wfi_sram)(void);
+
+/* save_secure_ram_context function pointer and size, for copy to SRAM */
+extern int save_secure_ram_context(u32 *addr);
+extern unsigned int save_secure_ram_context_sz;
+
+extern void omap3_save_scratchpad_contents(void);
+
+#define PM_RTA_ERRATUM_i608 (1 << 0)
+#define PM_SDRC_WAKEUP_ERRATUM_i583 (1 << 1)
+#define PM_PER_MEMORIES_ERRATUM_i582 (1 << 2)
+
+#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) */
+
+#define PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD (1 << 0)
+#define PM_OMAP4_CPU_OSWR_DISABLE (1 << 1)
+
+#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
+extern u16 pm44xx_errata;
+#define IS_PM44XX_ERRATUM(id) (pm44xx_errata & (id))
+#else
+#define IS_PM44XX_ERRATUM(id) 0
+#endif
+
+#ifdef CONFIG_POWER_AVS_OMAP
+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
+
+#ifdef CONFIG_PM
+extern void omap_pm_setup_oscillator(u32 tstart, u32 tshut);
+extern void omap_pm_get_oscillator(u32 *tstart, u32 *tshut);
+extern void omap_pm_setup_sr_i2c_pcb_length(u32 mm);
+#else
+static inline void omap_pm_setup_oscillator(u32 tstart, u32 tshut) { }
+static inline void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) { *tstart = *tshut = 0; }
+static inline void omap_pm_setup_sr_i2c_pcb_length(u32 mm) { }
+#endif
+
+#ifdef CONFIG_SUSPEND
+void omap_common_suspend_init(void *pm_suspend);
+#else
+static inline void omap_common_suspend_init(void *pm_suspend)
+{
+}
+#endif /* CONFIG_SUSPEND */
+#endif
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
new file mode 100644
index 000000000..b1aad7e14
--- /dev/null
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -0,0 +1,317 @@
+/*
+ * 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-provider.h>
+#include <linux/irq.h>
+#include <linux/time.h>
+#include <linux/gpio.h>
+#include <linux/platform_data/gpio-omap.h>
+
+#include <asm/fncpy.h>
+
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
+#include <asm/system_misc.h>
+
+#include <linux/omap-dma.h>
+
+#include "soc.h"
+#include "common.h"
+#include "clock.h"
+#include "prm2xxx.h"
+#include "prm-regbits-24xx.h"
+#include "cm2xxx.h"
+#include "cm-regbits-24xx.h"
+#include "sdrc.h"
+#include "sram.h"
+#include "pm.h"
+#include "control.h"
+#include "powerdomain.h"
+#include "clockdomain.h"
+
+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_enter_full_retention(void)
+{
+ u32 l;
+
+ /* 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? */
+ omap_prm_clear_mod_irqs(CORE_MOD, PM_WKST1, ~0);
+ omap_prm_clear_mod_irqs(CORE_MOD, OMAP24XX_PM_WKST2, ~0);
+ omap_prm_clear_mod_irqs(WKUP_MOD, PM_WKST, ~0);
+
+ pwrdm_set_next_pwrst(core_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);
+
+ /* One last check for pending IRQs to avoid extra latency due
+ * to sleeping unnecessarily. */
+ if (omap_irq_pending())
+ goto no_sleep;
+
+ /* 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));
+
+no_sleep:
+ omap2_gpio_resume_after_idle();
+
+ clk_enable(osc_ck);
+
+ /* clear CORE wake-up events */
+ omap_prm_clear_mod_irqs(CORE_MOD, PM_WKST1, ~0);
+ omap_prm_clear_mod_irqs(CORE_MOD, OMAP24XX_PM_WKST2, ~0);
+
+ /* wakeup domain events - bit 1: GPT1, bit5 GPIO */
+ omap_prm_clear_mod_irqs(WKUP_MOD, PM_WKST, 0x4 | 0x1);
+
+ /* MPU domain wake events */
+ omap_prm_clear_mod_irqs(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET, 0x1);
+
+ omap_prm_clear_mod_irqs(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET, 0x20);
+
+ pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
+ pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_ON);
+
+ return 0;
+}
+
+static int sti_console_enabled;
+
+static int omap2_allow_mpu_retention(void)
+{
+ if (!omap2xxx_cm_mpu_retention_allowed())
+ return 0;
+ if (sti_console_enabled)
+ return 0;
+
+ return 1;
+}
+
+static void omap2_enter_mpu_retention(void)
+{
+ const int zero = 0;
+
+ /* 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? */
+ omap_prm_clear_mod_irqs(CORE_MOD, PM_WKST1, ~0);
+ omap_prm_clear_mod_irqs(CORE_MOD, OMAP24XX_PM_WKST2, ~0);
+ omap_prm_clear_mod_irqs(WKUP_MOD, PM_WKST, ~0);
+
+ /* Try to enter MPU retention */
+ pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);
+
+ } else {
+ /* Block MPU retention */
+ pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
+ }
+
+ /* WFI */
+ asm("mcr p15, 0, %0, c7, c0, 4" : : "r" (zero) : "memory", "cc");
+
+ pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
+}
+
+static int omap2_can_sleep(void)
+{
+ if (omap2xxx_cm_fclks_active())
+ return 0;
+ if (__clk_is_enabled(osc_ck))
+ return 0;
+ if (omap_dma_running())
+ return 0;
+
+ return 1;
+}
+
+static void omap2_pm_idle(void)
+{
+ if (!omap2_can_sleep()) {
+ if (omap_irq_pending())
+ return;
+ omap2_enter_mpu_retention();
+ return;
+ }
+
+ if (omap_irq_pending())
+ return;
+
+ omap2_enter_full_retention();
+}
+
+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);
+
+ pwrdm_set_logic_retst(core_pwrdm, PWRDM_POWER_RET);
+
+ pwrdm_set_logic_retst(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);
+
+ pwrdm = clkdm_get_pwrdm(gfx_clkdm);
+ pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
+
+ /* Enable hardware-supervised idle for all clkdms */
+ clkdm_for_each(omap_pm_clkdms_setup, NULL);
+ clkdm_add_wkdep(mpu_clkdm, wkup_clkdm);
+
+ omap_common_suspend_init(omap2_enter_full_retention);
+
+ /* 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);
+
+ /* Enable SYS_CLKEN control when all domains idle */
+ omap2_prm_set_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK, OMAP24XX_GR_MOD,
+ OMAP2_PRCM_CLKSRC_CTRL_OFFSET);
+}
+
+int __init omap2_pm_init(void)
+{
+ u32 l;
+
+ 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();
+
+ /*
+ * 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 after the entire
+ * chip enters idle.
+ */
+ omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
+ omap24xx_cpu_suspend_sz);
+
+ arm_pm_idle = omap2_pm_idle;
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
new file mode 100644
index 000000000..87b98bf92
--- /dev/null
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -0,0 +1,580 @@
+/*
+ * 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/omap-dma.h>
+#include <linux/omap-gpmc.h>
+#include <linux/platform_data/gpio-omap.h>
+
+#include <trace/events/power.h>
+
+#include <asm/fncpy.h>
+#include <asm/suspend.h>
+#include <asm/system_misc.h>
+
+#include "clockdomain.h"
+#include "powerdomain.h"
+#include "soc.h"
+#include "common.h"
+#include "cm3xxx.h"
+#include "cm-regbits-34xx.h"
+#include "prm-regbits-34xx.h"
+#include "prm3xxx.h"
+#include "pm.h"
+#include "sdrc.h"
+#include "sram.h"
+#include "control.h"
+#include "vc.h"
+
+/* 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 int (*_omap_save_secure_sram)(u32 *addr);
+void (*omap3_do_wfi_sram)(void);
+
+static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
+static struct powerdomain *core_pwrdm, *per_pwrdm;
+
+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 *)(unsigned long)
+ __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) {
+ pr_err("save_secure_sram() returns %08x\n", ret);
+ while (1)
+ ;
+ }
+ }
+}
+
+static irqreturn_t _prcm_int_handle_io(int irq, void *unused)
+{
+ int c;
+
+ c = omap_prm_clear_mod_irqs(WKUP_MOD, 1, OMAP3430_ST_IO_MASK |
+ OMAP3430_ST_IO_CHAIN_MASK);
+
+ return c ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused)
+{
+ int c;
+
+ /*
+ * Clear all except ST_IO and ST_IO_CHAIN for wkup module,
+ * these are handled in a separate handler to avoid acking
+ * IO events before parsing in mux code
+ */
+ c = omap_prm_clear_mod_irqs(WKUP_MOD, 1, ~(OMAP3430_ST_IO_MASK |
+ OMAP3430_ST_IO_CHAIN_MASK));
+ c += omap_prm_clear_mod_irqs(CORE_MOD, 1, ~0);
+ c += omap_prm_clear_mod_irqs(OMAP3430_PER_MOD, 1, ~0);
+ if (omap_rev() > OMAP3430_REV_ES1_0) {
+ c += omap_prm_clear_mod_irqs(CORE_MOD, 3, ~0);
+ c += omap_prm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, ~0);
+ }
+
+ return c ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static void omap34xx_save_context(u32 *save)
+{
+ u32 val;
+
+ /* Read Auxiliary Control Register */
+ asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (val));
+ *save++ = 1;
+ *save++ = val;
+
+ /* Read L2 AUX ctrl register */
+ asm("mrc p15, 1, %0, c9, c0, 2" : "=r" (val));
+ *save++ = 1;
+ *save++ = val;
+}
+
+static int omap34xx_do_sram_idle(unsigned long save_state)
+{
+ omap34xx_cpu_suspend(save_state);
+ return 0;
+}
+
+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;
+ u32 sdrc_pwr = 0;
+
+ 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 */
+ pr_err("Invalid mpu state in sram_idle\n");
+ return;
+ }
+
+ /* 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);
+
+ pwrdm_pre_transition(NULL);
+
+ /* PER */
+ if (per_next_state < PWRDM_POWER_ON) {
+ per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
+ omap2_gpio_prepare_for_idle(per_going_off);
+ }
+
+ /* CORE */
+ if (core_next_state < PWRDM_POWER_ON) {
+ if (core_next_state == PWRDM_POWER_OFF) {
+ omap3_core_save_context();
+ omap3_cm_save_context();
+ }
+ }
+
+ /* Configure PMIC signaling for I2C4 or sys_off_mode */
+ omap3_vc_set_pmic_signaling(core_next_state);
+
+ 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 (cpu_is_omap3430() && omap_rev() >= OMAP3430_REV_ES3_0 &&
+ (omap_type() == OMAP2_DEVICE_TYPE_EMU ||
+ omap_type() == OMAP2_DEVICE_TYPE_SEC) &&
+ core_next_state == PWRDM_POWER_OFF)
+ sdrc_pwr = sdrc_read_reg(SDRC_POWER);
+
+ /*
+ * omap3_arm_context is the location where some ARM context
+ * get saved. The rest is placed on the stack, and restored
+ * from there before resuming.
+ */
+ if (save_state)
+ omap34xx_save_context(omap3_arm_context);
+ if (save_state == 1 || save_state == 3)
+ cpu_suspend(save_state, omap34xx_do_sram_idle);
+ else
+ omap34xx_do_sram_idle(save_state);
+
+ /* Restore normal SDRC POWER settings */
+ if (cpu_is_omap3430() && omap_rev() >= OMAP3430_REV_ES3_0 &&
+ (omap_type() == OMAP2_DEVICE_TYPE_EMU ||
+ omap_type() == OMAP2_DEVICE_TYPE_SEC) &&
+ core_next_state == PWRDM_POWER_OFF)
+ sdrc_write_reg(sdrc_pwr, SDRC_POWER);
+
+ /* 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();
+ }
+ }
+ omap3_intc_resume_idle();
+
+ pwrdm_post_transition(NULL);
+
+ /* PER */
+ if (per_next_state < PWRDM_POWER_ON)
+ omap2_gpio_resume_after_idle();
+}
+
+static void omap3_pm_idle(void)
+{
+ if (omap_irq_pending())
+ return;
+
+ trace_cpu_idle(1, smp_processor_id());
+
+ omap_sram_idle();
+
+ trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
+}
+
+#ifdef CONFIG_SUSPEND
+static int omap3_pm_suspend(void)
+{
+ struct power_state *pwrst;
+ int state, ret = 0;
+
+ /* 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;
+ }
+
+ 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) {
+ pr_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)
+ pr_err("Could not enter target state in pm_suspend\n");
+ else
+ pr_info("Successfully put all powerdomains to target state\n");
+
+ return ret;
+}
+#else
+#define omap3_pm_suspend NULL
+#endif /* CONFIG_SUSPEND */
+
+static void __init prcm_setup_regs(void)
+{
+ omap3_ctrl_init();
+
+ omap3_prm_init_pm(cpu_is_omap3630(), omap3_has_iva());
+}
+
+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);
+}
+
+/*
+ * Push functions to SRAM
+ *
+ * The minimum set of functions is pushed to SRAM for execution:
+ * - omap3_do_wfi for erratum i581 WA,
+ * - save_secure_ram_context for security extensions.
+ */
+void omap_push_sram_idle(void)
+{
+ omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi, omap3_do_wfi_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 |
+ PM_PER_MEMORIES_ERRATUM_i582);
+ } else if (cpu_is_omap34xx()) {
+ pm34xx_errata |= PM_PER_MEMORIES_ERRATUM_i582;
+ }
+}
+
+int __init omap3_pm_init(void)
+{
+ struct power_state *pwrst, *tmp;
+ struct clockdomain *neon_clkdm, *mpu_clkdm, *per_clkdm, *wkup_clkdm;
+ int ret;
+
+ if (!omap3_has_io_chain_ctrl())
+ pr_warn("PM: no software I/O chain control; some wakeups may be lost\n");
+
+ pm_errata_configure();
+
+ /* XXX prcm_setup_regs needs to be before enabling hw
+ * supervised mode for powerdomains */
+ prcm_setup_regs();
+
+ ret = request_irq(omap_prcm_event_to_irq("wkup"),
+ _prcm_int_handle_wakeup, IRQF_NO_SUSPEND, "pm_wkup", NULL);
+
+ if (ret) {
+ pr_err("pm: Failed to request pm_wkup irq\n");
+ goto err1;
+ }
+
+ /* IO interrupt is shared with mux code */
+ ret = request_irq(omap_prcm_event_to_irq("io"),
+ _prcm_int_handle_io, IRQF_SHARED | IRQF_NO_SUSPEND, "pm_io",
+ omap3_pm_init);
+ enable_irq(omap_prcm_event_to_irq("io"));
+
+ if (ret) {
+ pr_err("pm: Failed to request pm_io irq\n");
+ goto err2;
+ }
+
+ ret = pwrdm_for_each(pwrdms_setup, NULL);
+ if (ret) {
+ pr_err("Failed to setup powerdomains\n");
+ goto err3;
+ }
+
+ (void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
+
+ mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
+ if (mpu_pwrdm == NULL) {
+ pr_err("Failed to get mpu_pwrdm\n");
+ ret = -EINVAL;
+ goto err3;
+ }
+
+ neon_pwrdm = pwrdm_lookup("neon_pwrdm");
+ per_pwrdm = pwrdm_lookup("per_pwrdm");
+ core_pwrdm = pwrdm_lookup("core_pwrdm");
+
+ neon_clkdm = clkdm_lookup("neon_clkdm");
+ mpu_clkdm = clkdm_lookup("mpu_clkdm");
+ per_clkdm = clkdm_lookup("per_clkdm");
+ wkup_clkdm = clkdm_lookup("wkup_clkdm");
+
+ omap_common_suspend_init(omap3_pm_suspend);
+
+ arm_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();
+
+ /*
+ * The UART3/4 FIFO and the sidetone memory in McBSP2/3 are
+ * not correctly reset when the PER powerdomain comes back
+ * from OFF or OSWR when the CORE powerdomain is kept active.
+ * See OMAP36xx Erratum i582 "PER Domain reset issue after
+ * Domain-OFF/OSWR Wakeup". This wakeup dependency is not a
+ * complete workaround. The kernel must also prevent the PER
+ * powerdomain from going to OSWR/OFF while the CORE
+ * powerdomain is not going to OSWR/OFF. And if PER last
+ * power state was off while CORE last power state was ON, the
+ * UART3/4 and McBSP2/3 SIDETONE devices need to run a
+ * self-test using their loopback tests; if that fails, those
+ * devices are unusable until the PER/CORE can complete a transition
+ * from ON to OSWR/OFF and then back to ON.
+ *
+ * XXX Technically this workaround is only needed if off-mode
+ * or OSWR is enabled.
+ */
+ if (IS_PM34XX_ERRATUM(PM_PER_MEMORIES_ERRATUM_i582))
+ clkdm_add_wkdep(per_clkdm, wkup_clkdm);
+
+ 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)
+ pr_err("Memory allocation failed when allocating for secure sram context\n");
+
+ local_irq_disable();
+
+ omap_dma_global_context_save();
+ omap3_save_secure_ram_context();
+ omap_dma_global_context_restore();
+
+ local_irq_enable();
+ }
+
+ omap3_save_scratchpad_contents();
+ return ret;
+
+err3:
+ list_for_each_entry_safe(pwrst, tmp, &pwrst_list, node) {
+ list_del(&pwrst->node);
+ kfree(pwrst);
+ }
+ free_irq(omap_prcm_event_to_irq("io"), omap3_pm_init);
+err2:
+ free_irq(omap_prcm_event_to_irq("wkup"), NULL);
+err1:
+ return ret;
+}
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
new file mode 100644
index 000000000..d697cecf7
--- /dev/null
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -0,0 +1,295 @@
+/*
+ * OMAP4+ Power Management Routines
+ *
+ * Copyright (C) 2010-2013 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * 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/pm.h>
+#include <linux/suspend.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <asm/system_misc.h>
+
+#include "soc.h"
+#include "common.h"
+#include "clockdomain.h"
+#include "powerdomain.h"
+#include "pm.h"
+
+u16 pm44xx_errata;
+
+struct power_state {
+ struct powerdomain *pwrdm;
+ u32 next_state;
+ u32 next_logic_state;
+#ifdef CONFIG_SUSPEND
+ u32 saved_state;
+ u32 saved_logic_state;
+#endif
+ struct list_head node;
+};
+
+/**
+ * struct static_dep_map - Static dependency map
+ * @from: from clockdomain
+ * @to: to clockdomain
+ */
+struct static_dep_map {
+ const char *from;
+ const char *to;
+};
+
+static u32 cpu_suspend_state = PWRDM_POWER_OFF;
+
+static LIST_HEAD(pwrst_list);
+
+#ifdef CONFIG_SUSPEND
+static int omap4_pm_suspend(void)
+{
+ struct power_state *pwrst;
+ int state, ret = 0;
+ u32 cpu_id = smp_processor_id();
+
+ /* Save current powerdomain state */
+ list_for_each_entry(pwrst, &pwrst_list, node) {
+ pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
+ pwrst->saved_logic_state = pwrdm_read_logic_retst(pwrst->pwrdm);
+ }
+
+ /* Set targeted power domain states by suspend */
+ list_for_each_entry(pwrst, &pwrst_list, node) {
+ omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+ pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->next_logic_state);
+ }
+
+ /*
+ * For MPUSS to hit power domain retention(CSWR or OSWR),
+ * CPU0 and CPU1 power domains need to be in OFF or DORMANT state,
+ * since CPU power domain CSWR is not supported by hardware
+ * Only master CPU follows suspend path. All other CPUs follow
+ * CPU hotplug path in system wide suspend. On OMAP4, CPU power
+ * domain CSWR is not supported by hardware.
+ * More details can be found in OMAP4430 TRM section 4.3.4.2.
+ */
+ omap4_enter_lowpower(cpu_id, cpu_suspend_state);
+
+ /* Restore next powerdomain state */
+ list_for_each_entry(pwrst, &pwrst_list, node) {
+ state = pwrdm_read_prev_pwrst(pwrst->pwrdm);
+ if (state > pwrst->next_state) {
+ pr_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);
+ pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->saved_logic_state);
+ }
+ if (ret) {
+ pr_crit("Could not enter target state in pm_suspend\n");
+ /*
+ * OMAP4 chip PM currently works only with certain (newer)
+ * versions of bootloaders. This is due to missing code in the
+ * kernel to properly reset and initialize some devices.
+ * Warn the user about the bootloader version being one of the
+ * possible causes.
+ * http://www.spinics.net/lists/arm-kernel/msg218641.html
+ */
+ pr_warn("A possible cause could be an old bootloader - try u-boot >= v2012.07\n");
+ } else {
+ pr_info("Successfully put all powerdomains to target state\n");
+ }
+
+ return 0;
+}
+#else
+#define omap4_pm_suspend NULL
+#endif /* CONFIG_SUSPEND */
+
+static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
+{
+ struct power_state *pwrst;
+
+ if (!pwrdm->pwrsts)
+ return 0;
+
+ /*
+ * Skip CPU0 and CPU1 power domains. CPU1 is programmed
+ * through hotplug path and CPU0 explicitly programmed
+ * further down in the code path
+ */
+ if (!strncmp(pwrdm->name, "cpu", 3)) {
+ if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE))
+ cpu_suspend_state = PWRDM_POWER_RET;
+ return 0;
+ }
+
+ pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
+ if (!pwrst)
+ return -ENOMEM;
+
+ pwrst->pwrdm = pwrdm;
+ pwrst->next_state = pwrdm_get_valid_lp_state(pwrdm, false,
+ PWRDM_POWER_RET);
+ pwrst->next_logic_state = pwrdm_get_valid_lp_state(pwrdm, true,
+ PWRDM_POWER_OFF);
+
+ list_add(&pwrst->node, &pwrst_list);
+
+ return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+}
+
+/**
+ * omap_default_idle - OMAP4 default ilde routine.'
+ *
+ * Implements OMAP4 memory, IO ordering requirements which can't be addressed
+ * with default cpu_do_idle() hook. Used by all CPUs with !CONFIG_CPU_IDLE and
+ * by secondary CPU with CONFIG_CPU_IDLE.
+ */
+static void omap_default_idle(void)
+{
+ omap_do_wfi();
+}
+
+/*
+ * The dynamic dependency between MPUSS -> MEMIF and
+ * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as
+ * expected. The hardware recommendation is to enable static
+ * dependencies for these to avoid system lock ups or random crashes.
+ * The L4 wakeup depedency is added to workaround the OCP sync hardware
+ * BUG with 32K synctimer which lead to incorrect timer value read
+ * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which
+ * are part of L4 wakeup clockdomain.
+ */
+static const struct static_dep_map omap4_static_dep_map[] = {
+ {.from = "mpuss_clkdm", .to = "l3_emif_clkdm"},
+ {.from = "mpuss_clkdm", .to = "l3_1_clkdm"},
+ {.from = "mpuss_clkdm", .to = "l3_2_clkdm"},
+ {.from = "ducati_clkdm", .to = "l3_1_clkdm"},
+ {.from = "ducati_clkdm", .to = "l3_2_clkdm"},
+ {.from = NULL} /* TERMINATION */
+};
+
+static const struct static_dep_map omap5_dra7_static_dep_map[] = {
+ {.from = "mpu_clkdm", .to = "emif_clkdm"},
+ {.from = NULL} /* TERMINATION */
+};
+
+/**
+ * omap4plus_init_static_deps() - Initialize a static dependency map
+ * @map: Mapping of clock domains
+ */
+static inline int omap4plus_init_static_deps(const struct static_dep_map *map)
+{
+ int ret;
+ struct clockdomain *from, *to;
+
+ if (!map)
+ return 0;
+
+ while (map->from) {
+ from = clkdm_lookup(map->from);
+ to = clkdm_lookup(map->to);
+ if (!from || !to) {
+ pr_err("Failed lookup %s or %s for wakeup dependency\n",
+ map->from, map->to);
+ return -EINVAL;
+ }
+ ret = clkdm_add_wkdep(from, to);
+ if (ret) {
+ pr_err("Failed to add %s -> %s wakeup dependency(%d)\n",
+ map->from, map->to, ret);
+ return ret;
+ }
+
+ map++;
+ };
+
+ return 0;
+}
+
+/**
+ * omap4_pm_init_early - Does early initialization necessary for OMAP4+ devices
+ *
+ * Initializes basic stuff for power management functionality.
+ */
+int __init omap4_pm_init_early(void)
+{
+ if (cpu_is_omap446x())
+ pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD;
+
+ if (soc_is_omap54xx() || soc_is_dra7xx())
+ pm44xx_errata |= PM_OMAP4_CPU_OSWR_DISABLE;
+
+ return 0;
+}
+
+/**
+ * omap4_pm_init - Init routine for OMAP4+ devices
+ *
+ * Initializes all powerdomain and clockdomain target states
+ * and all PRCM settings.
+ * Return: Returns the error code returned by called functions.
+ */
+int __init omap4_pm_init(void)
+{
+ int ret = 0;
+
+ if (omap_rev() == OMAP4430_REV_ES1_0) {
+ WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
+ return -ENODEV;
+ }
+
+ pr_info("Power Management for TI OMAP4+ devices.\n");
+
+ /*
+ * OMAP4 chip PM currently works only with certain (newer)
+ * versions of bootloaders. This is due to missing code in the
+ * kernel to properly reset and initialize some devices.
+ * http://www.spinics.net/lists/arm-kernel/msg218641.html
+ */
+ if (cpu_is_omap44xx())
+ pr_warn("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n");
+
+ ret = pwrdm_for_each(pwrdms_setup, NULL);
+ if (ret) {
+ pr_err("Failed to setup powerdomains.\n");
+ goto err2;
+ }
+
+ if (cpu_is_omap44xx())
+ ret = omap4plus_init_static_deps(omap4_static_dep_map);
+ else if (soc_is_omap54xx() || soc_is_dra7xx())
+ ret = omap4plus_init_static_deps(omap5_dra7_static_dep_map);
+
+ if (ret) {
+ pr_err("Failed to initialise static dependencies.\n");
+ goto err2;
+ }
+
+ ret = omap4_mpuss_init();
+ if (ret) {
+ pr_err("Failed to initialise OMAP4 MPUSS\n");
+ goto err2;
+ }
+
+ (void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
+
+ omap_common_suspend_init(omap4_pm_suspend);
+
+ /* Overwrite the default cpu_do_idle() */
+ arm_pm_idle = omap_default_idle;
+
+ if (cpu_is_omap44xx())
+ omap4_idle_init();
+
+err2:
+ return ret;
+}
diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
new file mode 100644
index 000000000..a69e9a33c
--- /dev/null
+++ b/arch/arm/mach-omap2/pmu.c
@@ -0,0 +1,97 @@
+/*
+ * OMAP2 ARM Performance Monitoring Unit (PMU) Support
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * Contacts:
+ * Jon Hunter <jon-hunter@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.
+ */
+#include <linux/of.h>
+
+#include <asm/system_info.h>
+
+#include "soc.h"
+#include "omap_hwmod.h"
+#include "omap_device.h"
+
+static char *omap2_pmu_oh_names[] = {"mpu"};
+static char *omap3_pmu_oh_names[] = {"mpu", "debugss"};
+static char *omap4430_pmu_oh_names[] = {"l3_main_3", "l3_instr", "debugss"};
+static struct platform_device *omap_pmu_dev;
+
+/**
+ * omap2_init_pmu - creates and registers PMU platform device
+ * @oh_num: Number of OMAP HWMODs required to create PMU device
+ * @oh_names: Array of OMAP HWMODS names required to create PMU device
+ *
+ * Uses OMAP HWMOD framework to create and register an ARM PMU device
+ * from a list of HWMOD names passed. Currently supports OMAP2, OMAP3
+ * and OMAP4 devices.
+ */
+static int __init omap2_init_pmu(unsigned oh_num, char *oh_names[])
+{
+ int i;
+ struct omap_hwmod *oh[3];
+ char *dev_name = cpu_architecture() == CPU_ARCH_ARMv6 ?
+ "armv6-pmu" : "armv7-pmu";
+
+ if ((!oh_num) || (oh_num > 3))
+ return -EINVAL;
+
+ for (i = 0; i < oh_num; i++) {
+ oh[i] = omap_hwmod_lookup(oh_names[i]);
+ if (!oh[i]) {
+ pr_err("Could not look up %s hwmod\n", oh_names[i]);
+ return -ENODEV;
+ }
+ }
+
+ omap_pmu_dev = omap_device_build_ss(dev_name, -1, oh, oh_num, NULL, 0);
+ WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
+ dev_name);
+
+ return PTR_RET(omap_pmu_dev);
+}
+
+static int __init omap_init_pmu(void)
+{
+ unsigned oh_num;
+ char **oh_names;
+
+ /* XXX Remove this check when the CTI driver is available */
+ if (cpu_is_omap443x()) {
+ pr_info("ARM PMU: not yet supported on OMAP4430 due to missing CTI driver\n");
+ return 0;
+ }
+
+ if (of_have_populated_dt())
+ return 0;
+
+ /*
+ * To create an ARM-PMU device the following HWMODs
+ * are required for the various OMAP2+ devices.
+ *
+ * OMAP24xx: mpu
+ * OMAP3xxx: mpu, debugss
+ * OMAP4430: l3_main_3, l3_instr, debugss
+ * OMAP4460/70: mpu, debugss
+ */
+ if (cpu_is_omap443x()) {
+ oh_num = ARRAY_SIZE(omap4430_pmu_oh_names);
+ oh_names = omap4430_pmu_oh_names;
+ } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ oh_num = ARRAY_SIZE(omap3_pmu_oh_names);
+ oh_names = omap3_pmu_oh_names;
+ } else {
+ oh_num = ARRAY_SIZE(omap2_pmu_oh_names);
+ oh_names = omap2_pmu_oh_names;
+ }
+
+ return omap2_init_pmu(oh_num, oh_names);
+}
+omap_subsys_initcall(omap_init_pmu);
diff --git a/arch/arm/mach-omap2/powerdomain-common.c b/arch/arm/mach-omap2/powerdomain-common.c
new file mode 100644
index 000000000..c40e5f009
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomain-common.c
@@ -0,0 +1,109 @@
+/*
+ * Common powerdomain framework functions
+ *
+ * Copyright (C) 2010-2011 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 <linux/bug.h>
+#include "pm.h"
+#include "cm.h"
+#include "cm-regbits-34xx.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 000000000..78af6d8cf
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -0,0 +1,1208 @@
+/*
+ * OMAP powerdomain control
+ *
+ * Copyright (C) 2007-2008, 2011 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 <linux/spinlock.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 "powerdomain.h"
+#include "clockdomain.h"
+#include "voltage.h"
+
+#include "soc.h"
+#include "pm.h"
+
+#define PWRDM_TRACE_STATES_FLAG (1<<31)
+
+enum {
+ PWRDM_STATE_NOW = 0,
+ PWRDM_STATE_PREV,
+};
+
+/*
+ * Types of sleep_switch used internally in omap_set_pwrdm_state()
+ * and its associated static functions
+ *
+ * XXX Better documentation is needed here
+ */
+#define ALREADYACTIVE_SWITCH 0
+#define FORCEWAKEUP_SWITCH 1
+#define LOWPOWERSTATE_SWITCH 2
+
+/* 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;
+ struct voltagedomain *voltdm;
+
+ if (!pwrdm || !pwrdm->name)
+ 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;
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_has_voltdm)
+ if (!arch_pwrdm->pwrdm_has_voltdm())
+ goto skip_voltdm;
+
+ voltdm = voltdm_lookup(pwrdm->voltdm.name);
+ if (!voltdm) {
+ pr_err("powerdomain: %s: voltagedomain %s does not exist\n",
+ pwrdm->name, pwrdm->voltdm.name);
+ return -EINVAL;
+ }
+ pwrdm->voltdm.ptr = voltdm;
+ INIT_LIST_HEAD(&pwrdm->voltdm_node);
+skip_voltdm:
+ spin_lock_init(&pwrdm->_lock);
+
+ 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;
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition)
+ arch_pwrdm->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, next, 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
+ */
+ next = pwrdm_read_next_pwrst(pwrdm);
+ if (next != prev) {
+ trace_state = (PWRDM_TRACE_STATES_FLAG |
+ ((next & 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;
+}
+
+/**
+ * _pwrdm_save_clkdm_state_and_activate - prepare for power state change
+ * @pwrdm: struct powerdomain * to operate on
+ * @curr_pwrst: current power state of @pwrdm
+ * @pwrst: power state to switch to
+ * @hwsup: ptr to a bool to return whether the clkdm is hardware-supervised
+ *
+ * Determine whether the powerdomain needs to be turned on before
+ * attempting to switch power states. Called by
+ * omap_set_pwrdm_state(). NOTE that if the powerdomain contains
+ * multiple clockdomains, this code assumes that the first clockdomain
+ * supports software-supervised wakeup mode - potentially a problem.
+ * Returns the power state switch mode currently in use (see the
+ * "Types of sleep_switch" comment above).
+ */
+static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm,
+ u8 curr_pwrst, u8 pwrst,
+ bool *hwsup)
+{
+ u8 sleep_switch;
+
+ if (curr_pwrst < PWRDM_POWER_ON) {
+ if (curr_pwrst > pwrst &&
+ pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
+ arch_pwrdm->pwrdm_set_lowpwrstchange) {
+ sleep_switch = LOWPOWERSTATE_SWITCH;
+ } else {
+ *hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
+ clkdm_wakeup_nolock(pwrdm->pwrdm_clkdms[0]);
+ sleep_switch = FORCEWAKEUP_SWITCH;
+ }
+ } else {
+ sleep_switch = ALREADYACTIVE_SWITCH;
+ }
+
+ return sleep_switch;
+}
+
+/**
+ * _pwrdm_restore_clkdm_state - restore the clkdm hwsup state after pwrst change
+ * @pwrdm: struct powerdomain * to operate on
+ * @sleep_switch: return value from _pwrdm_save_clkdm_state_and_activate()
+ * @hwsup: should @pwrdm's first clockdomain be set to hardware-supervised mode?
+ *
+ * Restore the clockdomain state perturbed by
+ * _pwrdm_save_clkdm_state_and_activate(), and call the power state
+ * bookkeeping code. Called by omap_set_pwrdm_state(). NOTE that if
+ * the powerdomain contains multiple clockdomains, this assumes that
+ * the first associated clockdomain supports either
+ * hardware-supervised idle control in the register, or
+ * software-supervised sleep. No return value.
+ */
+static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm,
+ u8 sleep_switch, bool hwsup)
+{
+ switch (sleep_switch) {
+ case FORCEWAKEUP_SWITCH:
+ if (hwsup)
+ clkdm_allow_idle_nolock(pwrdm->pwrdm_clkdms[0]);
+ else
+ clkdm_sleep_nolock(pwrdm->pwrdm_clkdms[0]);
+ break;
+ case LOWPOWERSTATE_SWITCH:
+ if (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
+ arch_pwrdm->pwrdm_set_lowpwrstchange)
+ arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm);
+ pwrdm_state_switch_nolock(pwrdm);
+ break;
+ }
+}
+
+/* Public functions */
+
+/**
+ * pwrdm_register_platform_funcs - register powerdomain implementation fns
+ * @po: func pointers for arch specific implementations
+ *
+ * Register the list of function pointers used to implement the
+ * powerdomain functions on different OMAP SoCs. Should be called
+ * before any other pwrdm_register*() function. Returns -EINVAL if
+ * @po is null, -EEXIST if platform functions have already been
+ * registered, or 0 upon success.
+ */
+int pwrdm_register_platform_funcs(struct pwrdm_ops *po)
+{
+ if (!po)
+ return -EINVAL;
+
+ if (arch_pwrdm)
+ return -EEXIST;
+
+ arch_pwrdm = po;
+
+ return 0;
+}
+
+/**
+ * pwrdm_register_pwrdms - register SoC powerdomains
+ * @ps: pointer to an array of struct powerdomain to register
+ *
+ * Register the powerdomains available on a particular OMAP SoC. Must
+ * be called after pwrdm_register_platform_funcs(). May be called
+ * multiple times. Returns -EACCES if called before
+ * pwrdm_register_platform_funcs(); -EINVAL if the argument @ps is
+ * null; or 0 upon success.
+ */
+int pwrdm_register_pwrdms(struct powerdomain **ps)
+{
+ struct powerdomain **p = NULL;
+
+ if (!arch_pwrdm)
+ return -EEXIST;
+
+ if (!ps)
+ return -EINVAL;
+
+ for (p = ps; *p; p++)
+ _pwrdm_register(*p);
+
+ return 0;
+}
+
+/**
+ * pwrdm_complete_init - set up the powerdomain layer
+ *
+ * Do whatever is necessary to initialize registered powerdomains and
+ * powerdomain code. Currently, this programs the next power state
+ * for each powerdomain to ON. This prevents powerdomains from
+ * unexpectedly losing context or entering high wakeup latency modes
+ * with non-power-management-enabled kernels. Must be called after
+ * pwrdm_register_pwrdms(). Returns -EACCES if called before
+ * pwrdm_register_pwrdms(), or 0 upon success.
+ */
+int pwrdm_complete_init(void)
+{
+ struct powerdomain *temp_p;
+
+ if (list_empty(&pwrdm_list))
+ return -EACCES;
+
+ list_for_each_entry(temp_p, &pwrdm_list, node)
+ pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON);
+
+ return 0;
+}
+
+/**
+ * pwrdm_lock - acquire a Linux spinlock on a powerdomain
+ * @pwrdm: struct powerdomain * to lock
+ *
+ * Acquire the powerdomain spinlock on @pwrdm. No return value.
+ */
+void pwrdm_lock(struct powerdomain *pwrdm)
+ __acquires(&pwrdm->_lock)
+{
+ spin_lock_irqsave(&pwrdm->_lock, pwrdm->_lock_flags);
+}
+
+/**
+ * pwrdm_unlock - release a Linux spinlock on a powerdomain
+ * @pwrdm: struct powerdomain * to unlock
+ *
+ * Release the powerdomain spinlock on @pwrdm. No return value.
+ */
+void pwrdm_unlock(struct powerdomain *pwrdm)
+ __releases(&pwrdm->_lock)
+{
+ spin_unlock_irqrestore(&pwrdm->_lock, pwrdm->_lock_flags);
+}
+
+/**
+ * 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: %s: associating clockdomain %s\n",
+ pwrdm->name, clkdm->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: %s: increase PWRDM_MAX_CLKDMS for 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_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: %s: setting next powerstate 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. Note that if the power domain only supports the ON state
+ * then just return ON as the current state.
+ */
+int pwrdm_read_pwrst(struct powerdomain *pwrdm)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (pwrdm->pwrsts == PWRSTS_ON)
+ return PWRDM_POWER_ON;
+
+ 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: %s: setting next logic powerstate 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: %s: setting next memory powerstate for 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: %s: setting next memory powerstate for 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: %s: clearing previous power state reg\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;
+}
+
+int pwrdm_state_switch_nolock(struct powerdomain *pwrdm)
+{
+ int ret;
+
+ if (!pwrdm || !arch_pwrdm)
+ return -EINVAL;
+
+ ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
+ if (!ret)
+ ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
+
+ return ret;
+}
+
+int __deprecated pwrdm_state_switch(struct powerdomain *pwrdm)
+{
+ int ret;
+
+ pwrdm_lock(pwrdm);
+ ret = pwrdm_state_switch_nolock(pwrdm);
+ pwrdm_unlock(pwrdm);
+
+ return ret;
+}
+
+int pwrdm_pre_transition(struct powerdomain *pwrdm)
+{
+ if (pwrdm)
+ _pwrdm_pre_transition_cb(pwrdm, NULL);
+ else
+ pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
+
+ return 0;
+}
+
+int pwrdm_post_transition(struct powerdomain *pwrdm)
+{
+ if (pwrdm)
+ _pwrdm_post_transition_cb(pwrdm, NULL);
+ else
+ pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
+
+ return 0;
+}
+
+/**
+ * pwrdm_get_valid_lp_state() - Find best match deep power state
+ * @pwrdm: power domain for which we want to find best match
+ * @is_logic_state: Are we looking for logic state match here? Should
+ * be one of PWRDM_xxx macro values
+ * @req_state: requested power state
+ *
+ * Returns: closest match for requested power state. default fallback
+ * is RET for logic state and ON for power state.
+ *
+ * This does a search from the power domain data looking for the
+ * closest valid power domain state that the hardware can achieve.
+ * PRCM definitions for PWRSTCTRL allows us to program whatever
+ * configuration we'd like, and PRCM will actually attempt such
+ * a transition, however if the powerdomain does not actually support it,
+ * we endup with a hung system. The valid power domain states are already
+ * available in our powerdomain data files. So this function tries to do
+ * the following:
+ * a) find if we have an exact match to the request - no issues.
+ * b) else find if a deeper power state is possible.
+ * c) failing which, it tries to find closest higher power state for the
+ * request.
+ */
+u8 pwrdm_get_valid_lp_state(struct powerdomain *pwrdm,
+ bool is_logic_state, u8 req_state)
+{
+ u8 pwrdm_states = is_logic_state ? pwrdm->pwrsts_logic_ret :
+ pwrdm->pwrsts;
+ /* For logic, ret is highest and others, ON is highest */
+ u8 default_pwrst = is_logic_state ? PWRDM_POWER_RET : PWRDM_POWER_ON;
+ u8 new_pwrst;
+ bool found;
+
+ /* If it is already supported, nothing to search */
+ if (pwrdm_states & BIT(req_state))
+ return req_state;
+
+ if (!req_state)
+ goto up_search;
+
+ /*
+ * So, we dont have a exact match
+ * Can we get a deeper power state match?
+ */
+ new_pwrst = req_state - 1;
+ found = true;
+ while (!(pwrdm_states & BIT(new_pwrst))) {
+ /* No match even at OFF? Not available */
+ if (new_pwrst == PWRDM_POWER_OFF) {
+ found = false;
+ break;
+ }
+ new_pwrst--;
+ }
+
+ if (found)
+ goto done;
+
+up_search:
+ /* OK, no deeper ones, can we get a higher match? */
+ new_pwrst = req_state + 1;
+ while (!(pwrdm_states & BIT(new_pwrst))) {
+ if (new_pwrst > PWRDM_POWER_ON) {
+ WARN(1, "powerdomain: %s: Fix max powerstate to ON\n",
+ pwrdm->name);
+ return PWRDM_POWER_ON;
+ }
+
+ if (new_pwrst == default_pwrst)
+ break;
+ new_pwrst++;
+ }
+done:
+ return new_pwrst;
+}
+
+/**
+ * omap_set_pwrdm_state - change a powerdomain's current power state
+ * @pwrdm: struct powerdomain * to change the power state of
+ * @pwrst: power state to change to
+ *
+ * Change the current hardware power state of the powerdomain
+ * represented by @pwrdm to the power state represented by @pwrst.
+ * Returns -EINVAL if @pwrdm is null or invalid or if the
+ * powerdomain's current power state could not be read, or returns 0
+ * upon success or if @pwrdm does not support @pwrst or any
+ * lower-power state. XXX Should not return 0 if the @pwrdm does not
+ * support @pwrst or any lower-power state: this should be an error.
+ */
+int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst)
+{
+ u8 next_pwrst, sleep_switch;
+ int curr_pwrst;
+ int ret = 0;
+ bool hwsup = false;
+
+ if (!pwrdm || IS_ERR(pwrdm))
+ return -EINVAL;
+
+ while (!(pwrdm->pwrsts & (1 << pwrst))) {
+ if (pwrst == PWRDM_POWER_OFF)
+ return ret;
+ pwrst--;
+ }
+
+ pwrdm_lock(pwrdm);
+
+ curr_pwrst = pwrdm_read_pwrst(pwrdm);
+ if (curr_pwrst < 0) {
+ ret = -EINVAL;
+ goto osps_out;
+ }
+
+ next_pwrst = pwrdm_read_next_pwrst(pwrdm);
+ if (curr_pwrst == pwrst && next_pwrst == pwrst)
+ goto osps_out;
+
+ sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, curr_pwrst,
+ pwrst, &hwsup);
+
+ ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
+ if (ret)
+ pr_err("%s: unable to set power state of powerdomain: %s\n",
+ __func__, pwrdm->name);
+
+ _pwrdm_restore_clkdm_state(pwrdm, sleep_switch, hwsup);
+
+osps_out:
+ pwrdm_unlock(pwrdm);
+
+ return ret;
+}
+
+/**
+ * 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 negative
+ * (and WARNs) upon error, otherwise, returns the context loss count.
+ */
+int pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
+{
+ int i, count;
+
+ if (!pwrdm) {
+ WARN(1, "powerdomain: %s: pwrdm is null\n", __func__);
+ return -ENODEV;
+ }
+
+ 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];
+
+ /*
+ * Context loss count has to be a non-negative value. Clear the sign
+ * bit to get a value range from 0 to INT_MAX.
+ */
+ count &= INT_MAX;
+
+ pr_debug("powerdomain: %s: context loss count = %d\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 (!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 000000000..28a796ce0
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -0,0 +1,276 @@
+/*
+ * 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/spinlock.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)
+#define PWRSTS_INA_ON (PWRSTS_INACTIVE | PWRSTS_ON)
+
+
+/*
+ * Powerdomain flags (struct powerdomain.flags)
+ *
+ * PWRDM_HAS_HDWR_SAR - powerdomain has hardware save-and-restore support
+ *
+ * PWRDM_HAS_MPU_QUIRK - MPU pwr domain has MEM bank 0 bits in MEM
+ * bank 1 position. This is true for OMAP3430
+ *
+ * PWRDM_HAS_LOWPOWERSTATECHANGE - can transition from a sleep state
+ * to a lower sleep state without waking up the powerdomain
+ */
+#define PWRDM_HAS_HDWR_SAR BIT(0)
+#define PWRDM_HAS_MPU_QUIRK BIT(1)
+#define PWRDM_HAS_LOWPOWERSTATECHANGE BIT(2)
+
+/*
+ * 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.
+ * PER powerdomain on AM33XX is the worst case
+ */
+#define PWRDM_MAX_CLKDMS 11
+
+/* XXX A completely arbitrary number. What is reasonable here? */
+#define PWRDM_TRANSITION_BAILOUT 100000
+
+struct clockdomain;
+struct powerdomain;
+struct voltagedomain;
+
+/**
+ * struct powerdomain - OMAP powerdomain
+ * @name: Powerdomain name
+ * @voltdm: voltagedomain containing this powerdomain
+ * @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
+ * @voltdm_node: list_head linking all powerdomains in a voltagedomain
+ * @pwrstctrl_offs: (AM33XX only) XXX_PWRSTCTRL reg offset from prcm_offs
+ * @pwrstst_offs: (AM33XX only) XXX_PWRSTST reg offset from prcm_offs
+ * @logicretstate_mask: (AM33XX only) mask for logic retention bitfield
+ * in @pwrstctrl_offs
+ * @mem_on_mask: (AM33XX only) mask for mem on bitfield in @pwrstctrl_offs
+ * @mem_ret_mask: (AM33XX only) mask for mem ret bitfield in @pwrstctrl_offs
+ * @mem_pwrst_mask: (AM33XX only) mask for mem state bitfield in @pwrstst_offs
+ * @mem_retst_mask: (AM33XX only) mask for mem retention state bitfield
+ * in @pwrstctrl_offs
+ * @state:
+ * @state_counter:
+ * @timer:
+ * @state_timer:
+ * @_lock: spinlock used to serialize powerdomain and some clockdomain ops
+ * @_lock_flags: stored flags when @_lock is taken
+ *
+ * @prcm_partition possible values are defined in mach-omap2/prcm44xx.h.
+ */
+struct powerdomain {
+ const char *name;
+ union {
+ const char *name;
+ struct voltagedomain *ptr;
+ } voltdm;
+ 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;
+ struct list_head voltdm_node;
+ int state;
+ unsigned state_counter[PWRDM_MAX_PWRSTS];
+ unsigned ret_logic_off_counter;
+ unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS];
+ spinlock_t _lock;
+ unsigned long _lock_flags;
+ const u8 pwrstctrl_offs;
+ const u8 pwrstst_offs;
+ const u32 logicretstate_mask;
+ const u32 mem_on_mask[PWRDM_MAX_MEM_BANKS];
+ const u32 mem_ret_mask[PWRDM_MAX_MEM_BANKS];
+ const u32 mem_pwrst_mask[PWRDM_MAX_MEM_BANKS];
+ const u32 mem_retst_mask[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
+ * @pwrdm_has_voltdm: Check if a voltdm association is needed
+ *
+ * Regarding @pwrdm_set_lowpwrstchange: On the OMAP2 and 3-family
+ * chips, a powerdomain's power state is not allowed to directly
+ * transition from one low-power state (e.g., CSWR) to another
+ * low-power state (e.g., OFF) without first waking up the
+ * powerdomain. This wastes energy. So OMAP4 chips support the
+ * ability to transition a powerdomain power state directly from one
+ * low-power state to another. The function pointed to by
+ * @pwrdm_set_lowpwrstchange is intended to configure the OMAP4
+ * hardware powerdomain state machine to enable this feature.
+ */
+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);
+ int (*pwrdm_has_voltdm)(void);
+};
+
+int pwrdm_register_platform_funcs(struct pwrdm_ops *custom_funcs);
+int pwrdm_register_pwrdms(struct powerdomain **pwrdm_list);
+int pwrdm_complete_init(void);
+
+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_get_mem_bank_count(struct powerdomain *pwrdm);
+
+u8 pwrdm_get_valid_lp_state(struct powerdomain *pwrdm,
+ bool is_logic_state, u8 req_state);
+
+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_state_switch_nolock(struct powerdomain *pwrdm);
+int pwrdm_state_switch(struct powerdomain *pwrdm);
+int pwrdm_pre_transition(struct powerdomain *pwrdm);
+int pwrdm_post_transition(struct powerdomain *pwrdm);
+int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
+bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
+
+extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 state);
+
+extern void omap242x_powerdomains_init(void);
+extern void omap243x_powerdomains_init(void);
+extern void omap3xxx_powerdomains_init(void);
+extern void am33xx_powerdomains_init(void);
+extern void omap44xx_powerdomains_init(void);
+extern void omap54xx_powerdomains_init(void);
+extern void dra7xx_powerdomains_init(void);
+void am43xx_powerdomains_init(void);
+
+extern struct pwrdm_ops omap2_pwrdm_operations;
+extern struct pwrdm_ops omap3_pwrdm_operations;
+extern struct pwrdm_ops am33xx_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;
+
+extern void pwrdm_lock(struct powerdomain *pwrdm);
+extern void pwrdm_unlock(struct powerdomain *pwrdm);
+
+#endif
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 000000000..7b946f100
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
@@ -0,0 +1,65 @@
+/*
+ * OMAP2/3 common powerdomain definitions
+ *
+ * Copyright (C) 2007-2008, 2011 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.
+ */
+
+/*
+ * 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,
+ .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 */
+ },
+ .voltdm = { .name = "core" },
+};
+
+struct powerdomain wkup_omap2_pwrdm = {
+ .name = "wkup_pwrdm",
+ .prcm_offs = WKUP_MOD,
+ .pwrsts = PWRSTS_ON,
+ .voltdm = { .name = "wakeup" },
+};
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 000000000..fa311669d
--- /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 000000000..578eef86f
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains2xxx_data.c
@@ -0,0 +1,137 @@
+/*
+ * OMAP2XXX powerdomain definitions
+ *
+ * Copyright (C) 2007-2008, 2011 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 "soc.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,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_RET,
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON,
+ },
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain mpu_24xx_pwrdm = {
+ .name = "mpu_pwrdm",
+ .prcm_offs = MPU_MOD,
+ .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,
+ },
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain core_24xx_pwrdm = {
+ .name = "core_pwrdm",
+ .prcm_offs = CORE_MOD,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .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 */
+ },
+ .voltdm = { .name = "core" },
+};
+
+
+/*
+ * 2430-specific powerdomains
+ */
+
+/* XXX 2430 KILLDOMAINWKUP bit? No current users apparently */
+
+static struct powerdomain mdm_pwrdm = {
+ .name = "mdm_pwrdm",
+ .prcm_offs = OMAP2430_MDM_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 */
+ },
+ .voltdm = { .name = "core" },
+};
+
+/*
+ *
+ */
+
+static struct powerdomain *powerdomains_omap24xx[] __initdata = {
+ &wkup_omap2_pwrdm,
+ &gfx_omap2_pwrdm,
+ &dsp_pwrdm,
+ &mpu_24xx_pwrdm,
+ &core_24xx_pwrdm,
+ NULL
+};
+
+static struct powerdomain *powerdomains_omap2430[] __initdata = {
+ &mdm_pwrdm,
+ NULL
+};
+
+void __init omap242x_powerdomains_init(void)
+{
+ if (!cpu_is_omap2420())
+ return;
+
+ pwrdm_register_platform_funcs(&omap2_pwrdm_operations);
+ pwrdm_register_pwrdms(powerdomains_omap24xx);
+ pwrdm_complete_init();
+}
+
+void __init omap243x_powerdomains_init(void)
+{
+ if (!cpu_is_omap2430())
+ return;
+
+ pwrdm_register_platform_funcs(&omap2_pwrdm_operations);
+ pwrdm_register_pwrdms(powerdomains_omap24xx);
+ pwrdm_register_pwrdms(powerdomains_omap2430);
+ pwrdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/powerdomains33xx_data.c b/arch/arm/mach-omap2/powerdomains33xx_data.c
new file mode 100644
index 000000000..869adb825
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains33xx_data.c
@@ -0,0 +1,185 @@
+/*
+ * AM33XX Power domain data
+ *
+ * Copyright (C) 2011-2012 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 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 "powerdomain.h"
+#include "prcm-common.h"
+#include "prm-regbits-33xx.h"
+#include "prm33xx.h"
+
+static struct powerdomain gfx_33xx_pwrdm = {
+ .name = "gfx_pwrdm",
+ .voltdm = { .name = "core" },
+ .prcm_offs = AM33XX_PRM_GFX_MOD,
+ .pwrstctrl_offs = AM33XX_PM_GFX_PWRSTCTRL_OFFSET,
+ .pwrstst_offs = AM33XX_PM_GFX_PWRSTST_OFFSET,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+ .banks = 1,
+ .logicretstate_mask = AM33XX_LOGICRETSTATE_MASK,
+ .mem_on_mask = {
+ [0] = AM33XX_GFX_MEM_ONSTATE_MASK, /* gfx_mem */
+ },
+ .mem_ret_mask = {
+ [0] = AM33XX_GFX_MEM_RETSTATE_MASK, /* gfx_mem */
+ },
+ .mem_pwrst_mask = {
+ [0] = AM33XX_GFX_MEM_STATEST_MASK, /* gfx_mem */
+ },
+ .mem_retst_mask = {
+ [0] = AM33XX_GFX_MEM_RETSTATE_MASK, /* gfx_mem */
+ },
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* gfx_mem */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* gfx_mem */
+ },
+};
+
+static struct powerdomain rtc_33xx_pwrdm = {
+ .name = "rtc_pwrdm",
+ .voltdm = { .name = "rtc" },
+ .prcm_offs = AM33XX_PRM_RTC_MOD,
+ .pwrstctrl_offs = AM33XX_PM_RTC_PWRSTCTRL_OFFSET,
+ .pwrstst_offs = AM33XX_PM_RTC_PWRSTST_OFFSET,
+ .pwrsts = PWRSTS_ON,
+ .logicretstate_mask = AM33XX_LOGICRETSTATE_MASK,
+};
+
+static struct powerdomain wkup_33xx_pwrdm = {
+ .name = "wkup_pwrdm",
+ .voltdm = { .name = "core" },
+ .prcm_offs = AM33XX_PRM_WKUP_MOD,
+ .pwrstctrl_offs = AM33XX_PM_WKUP_PWRSTCTRL_OFFSET,
+ .pwrstst_offs = AM33XX_PM_WKUP_PWRSTST_OFFSET,
+ .pwrsts = PWRSTS_ON,
+ .logicretstate_mask = AM33XX_LOGICRETSTATE_3_3_MASK,
+};
+
+static struct powerdomain per_33xx_pwrdm = {
+ .name = "per_pwrdm",
+ .voltdm = { .name = "core" },
+ .prcm_offs = AM33XX_PRM_PER_MOD,
+ .pwrstctrl_offs = AM33XX_PM_PER_PWRSTCTRL_OFFSET,
+ .pwrstst_offs = AM33XX_PM_PER_PWRSTST_OFFSET,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+ .banks = 3,
+ .logicretstate_mask = AM33XX_LOGICRETSTATE_3_3_MASK,
+ .mem_on_mask = {
+ [0] = AM33XX_PRUSS_MEM_ONSTATE_MASK, /* pruss_mem */
+ [1] = AM33XX_PER_MEM_ONSTATE_MASK, /* per_mem */
+ [2] = AM33XX_RAM_MEM_ONSTATE_MASK, /* ram_mem */
+ },
+ .mem_ret_mask = {
+ [0] = AM33XX_PRUSS_MEM_RETSTATE_MASK, /* pruss_mem */
+ [1] = AM33XX_PER_MEM_RETSTATE_MASK, /* per_mem */
+ [2] = AM33XX_RAM_MEM_RETSTATE_MASK, /* ram_mem */
+ },
+ .mem_pwrst_mask = {
+ [0] = AM33XX_PRUSS_MEM_STATEST_MASK, /* pruss_mem */
+ [1] = AM33XX_PER_MEM_STATEST_MASK, /* per_mem */
+ [2] = AM33XX_RAM_MEM_STATEST_MASK, /* ram_mem */
+ },
+ .mem_retst_mask = {
+ [0] = AM33XX_PRUSS_MEM_RETSTATE_MASK, /* pruss_mem */
+ [1] = AM33XX_PER_MEM_RETSTATE_MASK, /* per_mem */
+ [2] = AM33XX_RAM_MEM_RETSTATE_MASK, /* ram_mem */
+ },
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* pruss_mem */
+ [1] = PWRSTS_OFF_RET, /* per_mem */
+ [2] = PWRSTS_OFF_RET, /* ram_mem */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* pruss_mem */
+ [1] = PWRSTS_ON, /* per_mem */
+ [2] = PWRSTS_ON, /* ram_mem */
+ },
+};
+
+static struct powerdomain mpu_33xx_pwrdm = {
+ .name = "mpu_pwrdm",
+ .voltdm = { .name = "mpu" },
+ .prcm_offs = AM33XX_PRM_MPU_MOD,
+ .pwrstctrl_offs = AM33XX_PM_MPU_PWRSTCTRL_OFFSET,
+ .pwrstst_offs = AM33XX_PM_MPU_PWRSTST_OFFSET,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+ .banks = 3,
+ .logicretstate_mask = AM33XX_LOGICRETSTATE_MASK,
+ .mem_on_mask = {
+ [0] = AM33XX_MPU_L1_ONSTATE_MASK, /* mpu_l1 */
+ [1] = AM33XX_MPU_L2_ONSTATE_MASK, /* mpu_l2 */
+ [2] = AM33XX_MPU_RAM_ONSTATE_MASK, /* mpu_ram */
+ },
+ .mem_ret_mask = {
+ [0] = AM33XX_MPU_L1_RETSTATE_MASK, /* mpu_l1 */
+ [1] = AM33XX_MPU_L2_RETSTATE_MASK, /* mpu_l2 */
+ [2] = AM33XX_MPU_RAM_RETSTATE_MASK, /* mpu_ram */
+ },
+ .mem_pwrst_mask = {
+ [0] = AM33XX_MPU_L1_STATEST_MASK, /* mpu_l1 */
+ [1] = AM33XX_MPU_L2_STATEST_MASK, /* mpu_l2 */
+ [2] = AM33XX_MPU_RAM_STATEST_MASK, /* mpu_ram */
+ },
+ .mem_retst_mask = {
+ [0] = AM33XX_MPU_L1_RETSTATE_MASK, /* mpu_l1 */
+ [1] = AM33XX_MPU_L2_RETSTATE_MASK, /* mpu_l2 */
+ [2] = AM33XX_MPU_RAM_RETSTATE_MASK, /* mpu_ram */
+ },
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* mpu_l1 */
+ [1] = PWRSTS_OFF_RET, /* mpu_l2 */
+ [2] = PWRSTS_OFF_RET, /* mpu_ram */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* mpu_l1 */
+ [1] = PWRSTS_ON, /* mpu_l2 */
+ [2] = PWRSTS_ON, /* mpu_ram */
+ },
+};
+
+static struct powerdomain cefuse_33xx_pwrdm = {
+ .name = "cefuse_pwrdm",
+ .voltdm = { .name = "core" },
+ .prcm_offs = AM33XX_PRM_CEFUSE_MOD,
+ .pwrstctrl_offs = AM33XX_PM_CEFUSE_PWRSTCTRL_OFFSET,
+ .pwrstst_offs = AM33XX_PM_CEFUSE_PWRSTST_OFFSET,
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct powerdomain *powerdomains_am33xx[] __initdata = {
+ &gfx_33xx_pwrdm,
+ &rtc_33xx_pwrdm,
+ &wkup_33xx_pwrdm,
+ &per_33xx_pwrdm,
+ &mpu_33xx_pwrdm,
+ &cefuse_33xx_pwrdm,
+ NULL,
+};
+
+void __init am33xx_powerdomains_init(void)
+{
+ pwrdm_register_platform_funcs(&am33xx_pwrdm_operations);
+ pwrdm_register_pwrdms(powerdomains_am33xx);
+ pwrdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
new file mode 100644
index 000000000..70bc7066a
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -0,0 +1,504 @@
+/*
+ * OMAP3 powerdomain definitions
+ *
+ * Copyright (C) 2007-2008, 2011 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 <linux/bug.h>
+
+#include "soc.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
+ */
+
+/*
+ * Powerdomains
+ */
+
+static struct powerdomain iva2_pwrdm = {
+ .name = "iva2_pwrdm",
+ .prcm_offs = OMAP3430_IVA2_MOD,
+ .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,
+ },
+ .voltdm = { .name = "mpu_iva" },
+};
+
+static struct powerdomain mpu_3xxx_pwrdm = {
+ .name = "mpu_pwrdm",
+ .prcm_offs = MPU_MOD,
+ .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,
+ },
+ .voltdm = { .name = "mpu_iva" },
+};
+
+static struct powerdomain mpu_am35x_pwrdm = {
+ .name = "mpu_pwrdm",
+ .prcm_offs = MPU_MOD,
+ .pwrsts = PWRSTS_ON,
+ .pwrsts_logic_ret = PWRSTS_ON,
+ .flags = PWRDM_HAS_MPU_QUIRK,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_ON,
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON,
+ },
+ .voltdm = { .name = "mpu_iva" },
+};
+
+/*
+ * 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,
+ .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 */
+ },
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain core_3xxx_es3_1_pwrdm = {
+ .name = "core_pwrdm",
+ .prcm_offs = CORE_MOD,
+ .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 */
+ },
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain core_am35x_pwrdm = {
+ .name = "core_pwrdm",
+ .prcm_offs = CORE_MOD,
+ .pwrsts = PWRSTS_ON,
+ .pwrsts_logic_ret = PWRSTS_ON,
+ .banks = 2,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_ON, /* MEM1RETSTATE */
+ [1] = PWRSTS_ON, /* MEM2RETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* MEM1ONSTATE */
+ [1] = PWRSTS_ON, /* MEM2ONSTATE */
+ },
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain dss_pwrdm = {
+ .name = "dss_pwrdm",
+ .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 */
+ },
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain dss_am35x_pwrdm = {
+ .name = "dss_pwrdm",
+ .prcm_offs = OMAP3430_DSS_MOD,
+ .pwrsts = PWRSTS_ON,
+ .pwrsts_logic_ret = PWRSTS_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_ON, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* MEMONSTATE */
+ },
+ .voltdm = { .name = "core" },
+};
+
+/*
+ * 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,
+ /* 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 */
+ },
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain sgx_am35x_pwrdm = {
+ .name = "sgx_pwrdm",
+ .prcm_offs = OMAP3430ES2_SGX_MOD,
+ .pwrsts = PWRSTS_ON,
+ .pwrsts_logic_ret = PWRSTS_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_ON, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* MEMONSTATE */
+ },
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain cam_pwrdm = {
+ .name = "cam_pwrdm",
+ .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 */
+ },
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain per_pwrdm = {
+ .name = "per_pwrdm",
+ .prcm_offs = OMAP3430_PER_MOD,
+ .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 */
+ },
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain per_am35x_pwrdm = {
+ .name = "per_pwrdm",
+ .prcm_offs = OMAP3430_PER_MOD,
+ .pwrsts = PWRSTS_ON,
+ .pwrsts_logic_ret = PWRSTS_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_ON, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* MEMONSTATE */
+ },
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain emu_pwrdm = {
+ .name = "emu_pwrdm",
+ .prcm_offs = OMAP3430_EMU_MOD,
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain neon_pwrdm = {
+ .name = "neon_pwrdm",
+ .prcm_offs = OMAP3430_NEON_MOD,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .voltdm = { .name = "mpu_iva" },
+};
+
+static struct powerdomain neon_am35x_pwrdm = {
+ .name = "neon_pwrdm",
+ .prcm_offs = OMAP3430_NEON_MOD,
+ .pwrsts = PWRSTS_ON,
+ .pwrsts_logic_ret = PWRSTS_ON,
+ .voltdm = { .name = "mpu_iva" },
+};
+
+static struct powerdomain usbhost_pwrdm = {
+ .name = "usbhost_pwrdm",
+ .prcm_offs = OMAP3430ES2_USBHOST_MOD,
+ .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 */
+ },
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain dpll1_pwrdm = {
+ .name = "dpll1_pwrdm",
+ .prcm_offs = MPU_MOD,
+ .voltdm = { .name = "mpu_iva" },
+};
+
+static struct powerdomain dpll2_pwrdm = {
+ .name = "dpll2_pwrdm",
+ .prcm_offs = OMAP3430_IVA2_MOD,
+ .voltdm = { .name = "mpu_iva" },
+};
+
+static struct powerdomain dpll3_pwrdm = {
+ .name = "dpll3_pwrdm",
+ .prcm_offs = PLL_MOD,
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain dpll4_pwrdm = {
+ .name = "dpll4_pwrdm",
+ .prcm_offs = PLL_MOD,
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain dpll5_pwrdm = {
+ .name = "dpll5_pwrdm",
+ .prcm_offs = PLL_MOD,
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain alwon_81xx_pwrdm = {
+ .name = "alwon_pwrdm",
+ .prcm_offs = TI81XX_PRM_ALWON_MOD,
+ .pwrsts = PWRSTS_OFF_ON,
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain device_81xx_pwrdm = {
+ .name = "device_pwrdm",
+ .prcm_offs = TI81XX_PRM_DEVICE_MOD,
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain active_816x_pwrdm = {
+ .name = "active_pwrdm",
+ .prcm_offs = TI816X_PRM_ACTIVE_MOD,
+ .pwrsts = PWRSTS_OFF_ON,
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain default_816x_pwrdm = {
+ .name = "default_pwrdm",
+ .prcm_offs = TI81XX_PRM_DEFAULT_MOD,
+ .pwrsts = PWRSTS_OFF_ON,
+ .voltdm = { .name = "core" },
+};
+
+static struct powerdomain ivahd0_816x_pwrdm = {
+ .name = "ivahd0_pwrdm",
+ .prcm_offs = TI816X_PRM_IVAHD0_MOD,
+ .pwrsts = PWRSTS_OFF_ON,
+ .voltdm = { .name = "mpu_iva" },
+};
+
+static struct powerdomain ivahd1_816x_pwrdm = {
+ .name = "ivahd1_pwrdm",
+ .prcm_offs = TI816X_PRM_IVAHD1_MOD,
+ .pwrsts = PWRSTS_OFF_ON,
+ .voltdm = { .name = "mpu_iva" },
+};
+
+static struct powerdomain ivahd2_816x_pwrdm = {
+ .name = "ivahd2_pwrdm",
+ .prcm_offs = TI816X_PRM_IVAHD2_MOD,
+ .pwrsts = PWRSTS_OFF_ON,
+ .voltdm = { .name = "mpu_iva" },
+};
+
+static struct powerdomain sgx_816x_pwrdm = {
+ .name = "sgx_pwrdm",
+ .prcm_offs = TI816X_PRM_SGX_MOD,
+ .pwrsts = PWRSTS_OFF_ON,
+ .voltdm = { .name = "core" },
+};
+
+/* As powerdomains are added or removed above, this list must also be changed */
+static struct powerdomain *powerdomains_omap3430_common[] __initdata = {
+ &wkup_omap2_pwrdm,
+ &iva2_pwrdm,
+ &mpu_3xxx_pwrdm,
+ &neon_pwrdm,
+ &cam_pwrdm,
+ &dss_pwrdm,
+ &per_pwrdm,
+ &emu_pwrdm,
+ &dpll1_pwrdm,
+ &dpll2_pwrdm,
+ &dpll3_pwrdm,
+ &dpll4_pwrdm,
+ NULL
+};
+
+static struct powerdomain *powerdomains_omap3430es1[] __initdata = {
+ &gfx_omap2_pwrdm,
+ &core_3xxx_pre_es3_1_pwrdm,
+ NULL
+};
+
+/* also includes 3630ES1.0 */
+static struct powerdomain *powerdomains_omap3430es2_es3_0[] __initdata = {
+ &core_3xxx_pre_es3_1_pwrdm,
+ &sgx_pwrdm,
+ &usbhost_pwrdm,
+ &dpll5_pwrdm,
+ NULL
+};
+
+/* also includes 3630ES1.1+ */
+static struct powerdomain *powerdomains_omap3430es3_1plus[] __initdata = {
+ &core_3xxx_es3_1_pwrdm,
+ &sgx_pwrdm,
+ &usbhost_pwrdm,
+ &dpll5_pwrdm,
+ NULL
+};
+
+static struct powerdomain *powerdomains_am35x[] __initdata = {
+ &wkup_omap2_pwrdm,
+ &mpu_am35x_pwrdm,
+ &neon_am35x_pwrdm,
+ &core_am35x_pwrdm,
+ &sgx_am35x_pwrdm,
+ &dss_am35x_pwrdm,
+ &per_am35x_pwrdm,
+ &emu_pwrdm,
+ &dpll1_pwrdm,
+ &dpll3_pwrdm,
+ &dpll4_pwrdm,
+ &dpll5_pwrdm,
+ NULL
+};
+
+static struct powerdomain *powerdomains_ti81xx[] __initdata = {
+ &alwon_81xx_pwrdm,
+ &device_81xx_pwrdm,
+ &active_816x_pwrdm,
+ &default_816x_pwrdm,
+ &ivahd0_816x_pwrdm,
+ &ivahd1_816x_pwrdm,
+ &ivahd2_816x_pwrdm,
+ &sgx_816x_pwrdm,
+ NULL
+};
+
+void __init omap3xxx_powerdomains_init(void)
+{
+ unsigned int rev;
+
+ if (!cpu_is_omap34xx() && !cpu_is_ti81xx())
+ return;
+
+ pwrdm_register_platform_funcs(&omap3_pwrdm_operations);
+
+ rev = omap_rev();
+
+ if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) {
+ pwrdm_register_pwrdms(powerdomains_am35x);
+ } else if (rev == TI8168_REV_ES1_0 || rev == TI8168_REV_ES1_1
+ || rev == TI8168_REV_ES2_0 || rev == TI8168_REV_ES2_1) {
+ pwrdm_register_pwrdms(powerdomains_ti81xx);
+ } else {
+ pwrdm_register_pwrdms(powerdomains_omap3430_common);
+
+ switch (rev) {
+ case OMAP3430_REV_ES1_0:
+ pwrdm_register_pwrdms(powerdomains_omap3430es1);
+ break;
+ case OMAP3430_REV_ES2_0:
+ case OMAP3430_REV_ES2_1:
+ case OMAP3430_REV_ES3_0:
+ case OMAP3630_REV_ES1_0:
+ pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
+ break;
+ case OMAP3430_REV_ES3_1:
+ case OMAP3430_REV_ES3_1_2:
+ case OMAP3630_REV_ES1_1:
+ case OMAP3630_REV_ES1_2:
+ pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
+ break;
+ default:
+ WARN(1, "OMAP3 powerdomain init: unknown chip type\n");
+ }
+ }
+
+ pwrdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/powerdomains43xx_data.c b/arch/arm/mach-omap2/powerdomains43xx_data.c
new file mode 100644
index 000000000..95fee54c3
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains43xx_data.c
@@ -0,0 +1,136 @@
+/*
+ * AM43xx Power domains framework
+ *
+ * Copyright (C) 2013 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 "powerdomain.h"
+
+#include "prcm-common.h"
+#include "prcm44xx.h"
+#include "prcm43xx.h"
+
+static struct powerdomain gfx_43xx_pwrdm = {
+ .name = "gfx_pwrdm",
+ .voltdm = { .name = "core" },
+ .prcm_offs = AM43XX_PRM_GFX_INST,
+ .prcm_partition = AM43XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .banks = 1,
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* gfx_mem */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+static struct powerdomain mpu_43xx_pwrdm = {
+ .name = "mpu_pwrdm",
+ .voltdm = { .name = "mpu" },
+ .prcm_offs = AM43XX_PRM_MPU_INST,
+ .prcm_partition = AM43XX_PRM_PARTITION,
+ .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_OFF_RET, /* mpu_ram */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* mpu_l1 */
+ [1] = PWRSTS_ON, /* mpu_l2 */
+ [2] = PWRSTS_ON, /* mpu_ram */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+static struct powerdomain rtc_43xx_pwrdm = {
+ .name = "rtc_pwrdm",
+ .voltdm = { .name = "rtc" },
+ .prcm_offs = AM43XX_PRM_RTC_INST,
+ .prcm_partition = AM43XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_ON,
+};
+
+static struct powerdomain wkup_43xx_pwrdm = {
+ .name = "wkup_pwrdm",
+ .voltdm = { .name = "core" },
+ .prcm_offs = AM43XX_PRM_WKUP_INST,
+ .prcm_partition = AM43XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_ON,
+ .banks = 1,
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* debugss_mem */
+ },
+};
+
+static struct powerdomain tamper_43xx_pwrdm = {
+ .name = "tamper_pwrdm",
+ .voltdm = { .name = "tamper" },
+ .prcm_offs = AM43XX_PRM_TAMPER_INST,
+ .prcm_partition = AM43XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_ON,
+};
+
+static struct powerdomain cefuse_43xx_pwrdm = {
+ .name = "cefuse_pwrdm",
+ .voltdm = { .name = "core" },
+ .prcm_offs = AM43XX_PRM_CEFUSE_INST,
+ .prcm_partition = AM43XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+static struct powerdomain per_43xx_pwrdm = {
+ .name = "per_pwrdm",
+ .voltdm = { .name = "core" },
+ .prcm_offs = AM43XX_PRM_PER_INST,
+ .prcm_partition = AM43XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 4,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* icss_mem */
+ [1] = PWRSTS_OFF_RET, /* per_mem */
+ [2] = PWRSTS_OFF_RET, /* ram1_mem */
+ [3] = PWRSTS_OFF_RET, /* ram2_mem */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* icss_mem */
+ [1] = PWRSTS_ON, /* per_mem */
+ [2] = PWRSTS_ON, /* ram1_mem */
+ [3] = PWRSTS_ON, /* ram2_mem */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+static struct powerdomain *powerdomains_am43xx[] __initdata = {
+ &gfx_43xx_pwrdm,
+ &mpu_43xx_pwrdm,
+ &rtc_43xx_pwrdm,
+ &wkup_43xx_pwrdm,
+ &tamper_43xx_pwrdm,
+ &cefuse_43xx_pwrdm,
+ &per_43xx_pwrdm,
+ NULL
+};
+
+static int am43xx_check_vcvp(void)
+{
+ return 0;
+}
+
+void __init am43xx_powerdomains_init(void)
+{
+ omap4_pwrdm_operations.pwrdm_has_voltdm = am43xx_check_vcvp;
+ pwrdm_register_platform_funcs(&omap4_pwrdm_operations);
+ pwrdm_register_pwrdms(powerdomains_am43xx);
+ pwrdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c
new file mode 100644
index 000000000..704664c0e
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains44xx_data.c
@@ -0,0 +1,358 @@
+/*
+ * OMAP4 Power domains framework
+ *
+ * Copyright (C) 2009-2011 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",
+ .voltdm = { .name = "core" },
+ .prcm_offs = OMAP4430_PRM_CORE_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .pwrsts = PWRSTS_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 5,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF, /* core_nret_bank */
+ [1] = PWRSTS_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_ON, /* 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",
+ .voltdm = { .name = "core" },
+ .prcm_offs = OMAP4430_PRM_GFX_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .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",
+ .voltdm = { .name = "iva" },
+ .prcm_offs = OMAP4430_PRM_ABE_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .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",
+ .voltdm = { .name = "core" },
+ .prcm_offs = OMAP4430_PRM_DSS_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .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",
+ .voltdm = { .name = "iva" },
+ .prcm_offs = OMAP4430_PRM_TESLA_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .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",
+ .voltdm = { .name = "wakeup" },
+ .prcm_offs = OMAP4430_PRM_WKUP_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .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",
+ .voltdm = { .name = "mpu" },
+ .prcm_offs = OMAP4430_PRCM_MPU_CPU0_INST,
+ .prcm_partition = OMAP4430_PRCM_MPU_PARTITION,
+ .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",
+ .voltdm = { .name = "mpu" },
+ .prcm_offs = OMAP4430_PRCM_MPU_CPU1_INST,
+ .prcm_partition = OMAP4430_PRCM_MPU_PARTITION,
+ .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",
+ .voltdm = { .name = "wakeup" },
+ .prcm_offs = OMAP4430_PRM_EMU_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .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",
+ .voltdm = { .name = "mpu" },
+ .prcm_offs = OMAP4430_PRM_MPU_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .pwrsts = PWRSTS_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",
+ .voltdm = { .name = "iva" },
+ .prcm_offs = OMAP4430_PRM_IVAHD_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .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",
+ .voltdm = { .name = "core" },
+ .prcm_offs = OMAP4430_PRM_CAM_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .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",
+ .voltdm = { .name = "core" },
+ .prcm_offs = OMAP4430_PRM_L3INIT_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .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",
+ .voltdm = { .name = "core" },
+ .prcm_offs = OMAP4430_PRM_L4PER_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .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",
+ .voltdm = { .name = "core" },
+ .prcm_offs = OMAP4430_PRM_ALWAYS_ON_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .pwrsts = PWRSTS_ON,
+};
+
+/* cefuse_44xx_pwrdm: Customer efuse controller power domain */
+static struct powerdomain cefuse_44xx_pwrdm = {
+ .name = "cefuse_pwrdm",
+ .voltdm = { .name = "core" },
+ .prcm_offs = OMAP4430_PRM_CEFUSE_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/*
+ * 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_register_platform_funcs(&omap4_pwrdm_operations);
+ pwrdm_register_pwrdms(powerdomains_omap44xx);
+ pwrdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/powerdomains54xx_data.c b/arch/arm/mach-omap2/powerdomains54xx_data.c
new file mode 100644
index 000000000..60d7ed8ef
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains54xx_data.c
@@ -0,0 +1,330 @@
+/*
+ * OMAP54XX Power domains framework
+ *
+ * Copyright (C) 2013 Texas Instruments, Inc.
+ *
+ * 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 "prm54xx.h"
+#include "prcm_mpu54xx.h"
+
+/* core_54xx_pwrdm: CORE power domain */
+static struct powerdomain core_54xx_pwrdm = {
+ .name = "core_pwrdm",
+ .voltdm = { .name = "core" },
+ .prcm_offs = OMAP54XX_PRM_CORE_INST,
+ .prcm_partition = OMAP54XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .banks = 5,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* core_nret_bank */
+ [1] = PWRSTS_OFF_RET, /* core_ocmram */
+ [2] = PWRSTS_OFF_RET, /* core_other_bank */
+ [3] = PWRSTS_OFF_RET, /* ipu_l2ram */
+ [4] = PWRSTS_OFF_RET, /* ipu_unicache */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* core_nret_bank */
+ [1] = PWRSTS_OFF_RET, /* core_ocmram */
+ [2] = PWRSTS_OFF_RET, /* core_other_bank */
+ [3] = PWRSTS_OFF_RET, /* ipu_l2ram */
+ [4] = PWRSTS_OFF_RET, /* ipu_unicache */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* abe_54xx_pwrdm: Audio back end power domain */
+static struct powerdomain abe_54xx_pwrdm = {
+ .name = "abe_pwrdm",
+ .voltdm = { .name = "core" },
+ .prcm_offs = OMAP54XX_PRM_ABE_INST,
+ .prcm_partition = OMAP54XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF,
+ .banks = 2,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* aessmem */
+ [1] = PWRSTS_OFF_RET, /* periphmem */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* aessmem */
+ [1] = PWRSTS_OFF_RET, /* periphmem */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* coreaon_54xx_pwrdm: Always ON logic that sits in VDD_CORE voltage domain */
+static struct powerdomain coreaon_54xx_pwrdm = {
+ .name = "coreaon_pwrdm",
+ .voltdm = { .name = "core" },
+ .prcm_offs = OMAP54XX_PRM_COREAON_INST,
+ .prcm_partition = OMAP54XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_ON,
+};
+
+/* dss_54xx_pwrdm: Display subsystem power domain */
+static struct powerdomain dss_54xx_pwrdm = {
+ .name = "dss_pwrdm",
+ .voltdm = { .name = "core" },
+ .prcm_offs = OMAP54XX_PRM_DSS_INST,
+ .prcm_partition = OMAP54XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* dss_mem */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* dss_mem */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* cpu0_54xx_pwrdm: MPU0 processor and Neon coprocessor power domain */
+static struct powerdomain cpu0_54xx_pwrdm = {
+ .name = "cpu0_pwrdm",
+ .voltdm = { .name = "mpu" },
+ .prcm_offs = OMAP54XX_PRCM_MPU_PRM_C0_INST,
+ .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION,
+ .pwrsts = PWRSTS_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* cpu0_l1 */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* cpu0_l1 */
+ },
+};
+
+/* cpu1_54xx_pwrdm: MPU1 processor and Neon coprocessor power domain */
+static struct powerdomain cpu1_54xx_pwrdm = {
+ .name = "cpu1_pwrdm",
+ .voltdm = { .name = "mpu" },
+ .prcm_offs = OMAP54XX_PRCM_MPU_PRM_C1_INST,
+ .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION,
+ .pwrsts = PWRSTS_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* cpu1_l1 */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* cpu1_l1 */
+ },
+};
+
+/* emu_54xx_pwrdm: Emulation power domain */
+static struct powerdomain emu_54xx_pwrdm = {
+ .name = "emu_pwrdm",
+ .voltdm = { .name = "wkup" },
+ .prcm_offs = OMAP54XX_PRM_EMU_INST,
+ .prcm_partition = OMAP54XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* emu_bank */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* emu_bank */
+ },
+};
+
+/* mpu_54xx_pwrdm: Modena processor and the Neon coprocessor power domain */
+static struct powerdomain mpu_54xx_pwrdm = {
+ .name = "mpu_pwrdm",
+ .voltdm = { .name = "mpu" },
+ .prcm_offs = OMAP54XX_PRM_MPU_INST,
+ .prcm_partition = OMAP54XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .banks = 2,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* mpu_l2 */
+ [1] = PWRSTS_RET, /* mpu_ram */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* mpu_l2 */
+ [1] = PWRSTS_OFF_RET, /* mpu_ram */
+ },
+};
+
+/* custefuse_54xx_pwrdm: Customer efuse controller power domain */
+static struct powerdomain custefuse_54xx_pwrdm = {
+ .name = "custefuse_pwrdm",
+ .voltdm = { .name = "core" },
+ .prcm_offs = OMAP54XX_PRM_CUSTEFUSE_INST,
+ .prcm_partition = OMAP54XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* dsp_54xx_pwrdm: Tesla processor power domain */
+static struct powerdomain dsp_54xx_pwrdm = {
+ .name = "dsp_pwrdm",
+ .voltdm = { .name = "mm" },
+ .prcm_offs = OMAP54XX_PRM_DSP_INST,
+ .prcm_partition = OMAP54XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 3,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* dsp_edma */
+ [1] = PWRSTS_OFF_RET, /* dsp_l1 */
+ [2] = PWRSTS_OFF_RET, /* dsp_l2 */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* dsp_edma */
+ [1] = PWRSTS_OFF_RET, /* dsp_l1 */
+ [2] = PWRSTS_OFF_RET, /* dsp_l2 */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* cam_54xx_pwrdm: Camera subsystem power domain */
+static struct powerdomain cam_54xx_pwrdm = {
+ .name = "cam_pwrdm",
+ .voltdm = { .name = "core" },
+ .prcm_offs = OMAP54XX_PRM_CAM_INST,
+ .prcm_partition = OMAP54XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* cam_mem */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* cam_mem */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* l3init_54xx_pwrdm: L3 initators pheripherals power domain */
+static struct powerdomain l3init_54xx_pwrdm = {
+ .name = "l3init_pwrdm",
+ .voltdm = { .name = "core" },
+ .prcm_offs = OMAP54XX_PRM_L3INIT_INST,
+ .prcm_partition = OMAP54XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 2,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* l3init_bank1 */
+ [1] = PWRSTS_OFF_RET, /* l3init_bank2 */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* l3init_bank1 */
+ [1] = PWRSTS_OFF_RET, /* l3init_bank2 */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* gpu_54xx_pwrdm: 3D accelerator power domain */
+static struct powerdomain gpu_54xx_pwrdm = {
+ .name = "gpu_pwrdm",
+ .voltdm = { .name = "mm" },
+ .prcm_offs = OMAP54XX_PRM_GPU_INST,
+ .prcm_partition = OMAP54XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* gpu_mem */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* gpu_mem */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* wkupaon_54xx_pwrdm: Wake-up power domain */
+static struct powerdomain wkupaon_54xx_pwrdm = {
+ .name = "wkupaon_pwrdm",
+ .voltdm = { .name = "wkup" },
+ .prcm_offs = OMAP54XX_PRM_WKUPAON_INST,
+ .prcm_partition = OMAP54XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* wkup_bank */
+ },
+};
+
+/* iva_54xx_pwrdm: IVA-HD power domain */
+static struct powerdomain iva_54xx_pwrdm = {
+ .name = "iva_pwrdm",
+ .voltdm = { .name = "mm" },
+ .prcm_offs = OMAP54XX_PRM_IVA_INST,
+ .prcm_partition = OMAP54XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF,
+ .banks = 4,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* 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_OFF_RET, /* hwa_mem */
+ [1] = PWRSTS_OFF_RET, /* sl2_mem */
+ [2] = PWRSTS_OFF_RET, /* tcm1_mem */
+ [3] = PWRSTS_OFF_RET, /* tcm2_mem */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/*
+ * The following power domains are not under SW control
+ *
+ * mpuaon
+ * mmaon
+ */
+
+/* As powerdomains are added or removed above, this list must also be changed */
+static struct powerdomain *powerdomains_omap54xx[] __initdata = {
+ &core_54xx_pwrdm,
+ &abe_54xx_pwrdm,
+ &coreaon_54xx_pwrdm,
+ &dss_54xx_pwrdm,
+ &cpu0_54xx_pwrdm,
+ &cpu1_54xx_pwrdm,
+ &emu_54xx_pwrdm,
+ &mpu_54xx_pwrdm,
+ &custefuse_54xx_pwrdm,
+ &dsp_54xx_pwrdm,
+ &cam_54xx_pwrdm,
+ &l3init_54xx_pwrdm,
+ &gpu_54xx_pwrdm,
+ &wkupaon_54xx_pwrdm,
+ &iva_54xx_pwrdm,
+ NULL
+};
+
+void __init omap54xx_powerdomains_init(void)
+{
+ pwrdm_register_platform_funcs(&omap4_pwrdm_operations);
+ pwrdm_register_pwrdms(powerdomains_omap54xx);
+ pwrdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/powerdomains7xx_data.c b/arch/arm/mach-omap2/powerdomains7xx_data.c
new file mode 100644
index 000000000..287a2037a
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains7xx_data.c
@@ -0,0 +1,454 @@
+/*
+ * DRA7xx Power domains framework
+ *
+ * Copyright (C) 2009-2013 Texas Instruments, Inc.
+ * Copyright (C) 2009-2011 Nokia Corporation
+ *
+ * Generated by code originally written by:
+ * 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 "prm7xx.h"
+#include "prcm_mpu7xx.h"
+
+/* iva_7xx_pwrdm: IVA-HD power domain */
+static struct powerdomain iva_7xx_pwrdm = {
+ .name = "iva_pwrdm",
+ .prcm_offs = DRA7XX_PRM_IVA_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF,
+ .banks = 4,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* 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_OFF_RET, /* hwa_mem */
+ [1] = PWRSTS_OFF_RET, /* sl2_mem */
+ [2] = PWRSTS_OFF_RET, /* tcm1_mem */
+ [3] = PWRSTS_OFF_RET, /* tcm2_mem */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* rtc_7xx_pwrdm: */
+static struct powerdomain rtc_7xx_pwrdm = {
+ .name = "rtc_pwrdm",
+ .prcm_offs = DRA7XX_PRM_RTC_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_ON,
+};
+
+/* custefuse_7xx_pwrdm: Customer efuse controller power domain */
+static struct powerdomain custefuse_7xx_pwrdm = {
+ .name = "custefuse_pwrdm",
+ .prcm_offs = DRA7XX_PRM_CUSTEFUSE_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* ipu_7xx_pwrdm: Audio back end power domain */
+static struct powerdomain ipu_7xx_pwrdm = {
+ .name = "ipu_pwrdm",
+ .prcm_offs = DRA7XX_PRM_IPU_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF,
+ .banks = 2,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* aessmem */
+ [1] = PWRSTS_OFF_RET, /* periphmem */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* aessmem */
+ [1] = PWRSTS_OFF_RET, /* periphmem */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* dss_7xx_pwrdm: Display subsystem power domain */
+static struct powerdomain dss_7xx_pwrdm = {
+ .name = "dss_pwrdm",
+ .prcm_offs = DRA7XX_PRM_DSS_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* dss_mem */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* dss_mem */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* l4per_7xx_pwrdm: Target peripherals power domain */
+static struct powerdomain l4per_7xx_pwrdm = {
+ .name = "l4per_pwrdm",
+ .prcm_offs = DRA7XX_PRM_L4PER_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 2,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* nonretained_bank */
+ [1] = PWRSTS_OFF_RET, /* retained_bank */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* nonretained_bank */
+ [1] = PWRSTS_OFF_RET, /* retained_bank */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* gpu_7xx_pwrdm: 3D accelerator power domain */
+static struct powerdomain gpu_7xx_pwrdm = {
+ .name = "gpu_pwrdm",
+ .prcm_offs = DRA7XX_PRM_GPU_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* gpu_mem */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* gpu_mem */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* wkupaon_7xx_pwrdm: Wake-up power domain */
+static struct powerdomain wkupaon_7xx_pwrdm = {
+ .name = "wkupaon_pwrdm",
+ .prcm_offs = DRA7XX_PRM_WKUPAON_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* wkup_bank */
+ },
+};
+
+/* core_7xx_pwrdm: CORE power domain */
+static struct powerdomain core_7xx_pwrdm = {
+ .name = "core_pwrdm",
+ .prcm_offs = DRA7XX_PRM_CORE_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_INA_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .banks = 5,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* core_nret_bank */
+ [1] = PWRSTS_OFF_RET, /* core_ocmram */
+ [2] = PWRSTS_OFF_RET, /* core_other_bank */
+ [3] = PWRSTS_OFF_RET, /* ipu_l2ram */
+ [4] = PWRSTS_OFF_RET, /* ipu_unicache */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* core_nret_bank */
+ [1] = PWRSTS_OFF_RET, /* core_ocmram */
+ [2] = PWRSTS_OFF_RET, /* core_other_bank */
+ [3] = PWRSTS_OFF_RET, /* ipu_l2ram */
+ [4] = PWRSTS_OFF_RET, /* ipu_unicache */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* coreaon_7xx_pwrdm: Always ON logic that sits in VDD_CORE voltage domain */
+static struct powerdomain coreaon_7xx_pwrdm = {
+ .name = "coreaon_pwrdm",
+ .prcm_offs = DRA7XX_PRM_COREAON_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_ON,
+};
+
+/* cpu0_7xx_pwrdm: MPU0 processor and Neon coprocessor power domain */
+static struct powerdomain cpu0_7xx_pwrdm = {
+ .name = "cpu0_pwrdm",
+ .prcm_offs = DRA7XX_MPU_PRCM_PRM_C0_INST,
+ .prcm_partition = DRA7XX_MPU_PRCM_PARTITION,
+ .pwrsts = PWRSTS_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* cpu0_l1 */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* cpu0_l1 */
+ },
+};
+
+/* cpu1_7xx_pwrdm: MPU1 processor and Neon coprocessor power domain */
+static struct powerdomain cpu1_7xx_pwrdm = {
+ .name = "cpu1_pwrdm",
+ .prcm_offs = DRA7XX_MPU_PRCM_PRM_C1_INST,
+ .prcm_partition = DRA7XX_MPU_PRCM_PARTITION,
+ .pwrsts = PWRSTS_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* cpu1_l1 */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* cpu1_l1 */
+ },
+};
+
+/* vpe_7xx_pwrdm: */
+static struct powerdomain vpe_7xx_pwrdm = {
+ .name = "vpe_pwrdm",
+ .prcm_offs = DRA7XX_PRM_VPE_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* vpe_bank */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* vpe_bank */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* mpu_7xx_pwrdm: Modena processor and the Neon coprocessor power domain */
+static struct powerdomain mpu_7xx_pwrdm = {
+ .name = "mpu_pwrdm",
+ .prcm_offs = DRA7XX_PRM_MPU_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .banks = 2,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* mpu_l2 */
+ [1] = PWRSTS_RET, /* mpu_ram */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* mpu_l2 */
+ [1] = PWRSTS_OFF_RET, /* mpu_ram */
+ },
+};
+
+/* l3init_7xx_pwrdm: L3 initators pheripherals power domain */
+static struct powerdomain l3init_7xx_pwrdm = {
+ .name = "l3init_pwrdm",
+ .prcm_offs = DRA7XX_PRM_L3INIT_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 3,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* gmac_bank */
+ [1] = PWRSTS_OFF_RET, /* l3init_bank1 */
+ [2] = PWRSTS_OFF_RET, /* l3init_bank2 */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* gmac_bank */
+ [1] = PWRSTS_OFF_RET, /* l3init_bank1 */
+ [2] = PWRSTS_OFF_RET, /* l3init_bank2 */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* eve3_7xx_pwrdm: */
+static struct powerdomain eve3_7xx_pwrdm = {
+ .name = "eve3_pwrdm",
+ .prcm_offs = DRA7XX_PRM_EVE3_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* eve3_bank */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* eve3_bank */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* emu_7xx_pwrdm: Emulation power domain */
+static struct powerdomain emu_7xx_pwrdm = {
+ .name = "emu_pwrdm",
+ .prcm_offs = DRA7XX_PRM_EMU_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* emu_bank */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* emu_bank */
+ },
+};
+
+/* dsp2_7xx_pwrdm: */
+static struct powerdomain dsp2_7xx_pwrdm = {
+ .name = "dsp2_pwrdm",
+ .prcm_offs = DRA7XX_PRM_DSP2_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .banks = 3,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* dsp2_edma */
+ [1] = PWRSTS_OFF_RET, /* dsp2_l1 */
+ [2] = PWRSTS_OFF_RET, /* dsp2_l2 */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* dsp2_edma */
+ [1] = PWRSTS_OFF_RET, /* dsp2_l1 */
+ [2] = PWRSTS_OFF_RET, /* dsp2_l2 */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* dsp1_7xx_pwrdm: Tesla processor power domain */
+static struct powerdomain dsp1_7xx_pwrdm = {
+ .name = "dsp1_pwrdm",
+ .prcm_offs = DRA7XX_PRM_DSP1_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .banks = 3,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* dsp1_edma */
+ [1] = PWRSTS_OFF_RET, /* dsp1_l1 */
+ [2] = PWRSTS_OFF_RET, /* dsp1_l2 */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* dsp1_edma */
+ [1] = PWRSTS_OFF_RET, /* dsp1_l1 */
+ [2] = PWRSTS_OFF_RET, /* dsp1_l2 */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* cam_7xx_pwrdm: Camera subsystem power domain */
+static struct powerdomain cam_7xx_pwrdm = {
+ .name = "cam_pwrdm",
+ .prcm_offs = DRA7XX_PRM_CAM_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* vip_bank */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* vip_bank */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* eve4_7xx_pwrdm: */
+static struct powerdomain eve4_7xx_pwrdm = {
+ .name = "eve4_pwrdm",
+ .prcm_offs = DRA7XX_PRM_EVE4_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* eve4_bank */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* eve4_bank */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* eve2_7xx_pwrdm: */
+static struct powerdomain eve2_7xx_pwrdm = {
+ .name = "eve2_pwrdm",
+ .prcm_offs = DRA7XX_PRM_EVE2_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* eve2_bank */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* eve2_bank */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* eve1_7xx_pwrdm: */
+static struct powerdomain eve1_7xx_pwrdm = {
+ .name = "eve1_pwrdm",
+ .prcm_offs = DRA7XX_PRM_EVE1_INST,
+ .prcm_partition = DRA7XX_PRM_PARTITION,
+ .pwrsts = PWRSTS_OFF_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* eve1_bank */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET, /* eve1_bank */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/*
+ * The following power domains are not under SW control
+ *
+ * mpuaon
+ * mmaon
+ */
+
+/* As powerdomains are added or removed above, this list must also be changed */
+static struct powerdomain *powerdomains_dra7xx[] __initdata = {
+ &iva_7xx_pwrdm,
+ &rtc_7xx_pwrdm,
+ &custefuse_7xx_pwrdm,
+ &ipu_7xx_pwrdm,
+ &dss_7xx_pwrdm,
+ &l4per_7xx_pwrdm,
+ &gpu_7xx_pwrdm,
+ &wkupaon_7xx_pwrdm,
+ &core_7xx_pwrdm,
+ &coreaon_7xx_pwrdm,
+ &cpu0_7xx_pwrdm,
+ &cpu1_7xx_pwrdm,
+ &vpe_7xx_pwrdm,
+ &mpu_7xx_pwrdm,
+ &l3init_7xx_pwrdm,
+ &eve3_7xx_pwrdm,
+ &emu_7xx_pwrdm,
+ &dsp2_7xx_pwrdm,
+ &dsp1_7xx_pwrdm,
+ &cam_7xx_pwrdm,
+ &eve4_7xx_pwrdm,
+ &eve2_7xx_pwrdm,
+ &eve1_7xx_pwrdm,
+ NULL
+};
+
+void __init dra7xx_powerdomains_init(void)
+{
+ pwrdm_register_platform_funcs(&omap4_pwrdm_operations);
+ pwrdm_register_pwrdms(powerdomains_dra7xx);
+ pwrdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
new file mode 100644
index 000000000..6ae0b3a17
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -0,0 +1,551 @@
+#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, 2011 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
+
+/*
+ * TI81XX PRM module offsets
+ */
+#define TI81XX_PRM_DEVICE_MOD 0x0000
+#define TI816X_PRM_ACTIVE_MOD 0x0a00
+#define TI81XX_PRM_DEFAULT_MOD 0x0b00
+#define TI816X_PRM_IVAHD0_MOD 0x0c00
+#define TI816X_PRM_IVAHD1_MOD 0x0d00
+#define TI816X_PRM_IVAHD2_MOD 0x0e00
+#define TI816X_PRM_SGX_MOD 0x0f00
+#define TI81XX_PRM_ALWON_MOD 0x1800
+
+/* 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)
+#define OMAP24XX_EN_GPMC_SHIFT 1
+#define OMAP24XX_EN_GPMC_MASK (1 << 1)
+
+/* 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_32KSYNC_SHIFT 1
+#define OMAP24XX_ST_32KSYNC_MASK (1 << 1)
+#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 AM35XX_EN_UART4_MASK (1 << 23)
+#define AM35XX_EN_UART4_SHIFT 23
+#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_32KSYNC_SHIFT 2
+#define OMAP3430_ST_32KSYNC_MASK (1 << 2)
+#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)
+
+
+
+/*
+ * Maximum time(us) it takes to output the signal WUCLKOUT of the last
+ * pad of the I/O ring after asserting WUCLKIN high. Tero measured
+ * the actual time at 7 to 8 microseconds on OMAP3 and 2 to 4
+ * microseconds on OMAP4, so this timeout may be too high.
+ */
+#define MAX_IOPAD_LATCH_TIME 100
+# ifndef __ASSEMBLER__
+
+#include <linux/delay.h>
+
+/**
+ * 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); \
+ } \
+})
+
+/**
+ * struct omap_prcm_irq - describes a PRCM interrupt bit
+ * @name: a short name describing the interrupt type, e.g. "wkup" or "io"
+ * @offset: the bit shift of the interrupt inside the IRQ{ENABLE,STATUS} regs
+ * @priority: should this interrupt be handled before @priority=false IRQs?
+ *
+ * Describes interrupt bits inside the PRM_IRQ{ENABLE,STATUS}_MPU* registers.
+ * On systems with multiple PRM MPU IRQ registers, the bitfields read from
+ * the registers are concatenated, so @offset could be > 31 on these systems -
+ * see omap_prm_irq_handler() for more details. I/O ring interrupts should
+ * have @priority set to true.
+ */
+struct omap_prcm_irq {
+ const char *name;
+ unsigned int offset;
+ bool priority;
+};
+
+/**
+ * struct omap_prcm_irq_setup - PRCM interrupt controller details
+ * @ack: PRM register offset for the first PRM_IRQSTATUS_MPU register
+ * @mask: PRM register offset for the first PRM_IRQENABLE_MPU register
+ * @nr_regs: number of PRM_IRQ{STATUS,ENABLE}_MPU* registers
+ * @nr_irqs: number of entries in the @irqs array
+ * @irqs: ptr to an array of PRCM interrupt bits (see @nr_irqs)
+ * @irq: MPU IRQ asserted when a PRCM interrupt arrives
+ * @read_pending_irqs: fn ptr to determine if any PRCM IRQs are pending
+ * @ocp_barrier: fn ptr to force buffered PRM writes to complete
+ * @save_and_clear_irqen: fn ptr to save and clear IRQENABLE regs
+ * @restore_irqen: fn ptr to save and clear IRQENABLE regs
+ * @reconfigure_io_chain: fn ptr to reconfigure IO chain
+ * @saved_mask: IRQENABLE regs are saved here during suspend
+ * @priority_mask: 1 bit per IRQ, set to 1 if omap_prcm_irq.priority = true
+ * @base_irq: base dynamic IRQ number, returned from irq_alloc_descs() in init
+ * @suspended: set to true after Linux suspend code has called our ->prepare()
+ * @suspend_save_flag: set to true after IRQ masks have been saved and disabled
+ *
+ * @saved_mask, @priority_mask, @base_irq, @suspended, and
+ * @suspend_save_flag are populated dynamically, and are not to be
+ * specified in static initializers.
+ */
+struct omap_prcm_irq_setup {
+ u16 ack;
+ u16 mask;
+ u8 nr_regs;
+ u8 nr_irqs;
+ const struct omap_prcm_irq *irqs;
+ int irq;
+ unsigned int (*xlate_irq)(unsigned int);
+ void (*read_pending_irqs)(unsigned long *events);
+ void (*ocp_barrier)(void);
+ void (*save_and_clear_irqen)(u32 *saved_mask);
+ void (*restore_irqen)(u32 *saved_mask);
+ void (*reconfigure_io_chain)(void);
+ u32 *saved_mask;
+ u32 *priority_mask;
+ int base_irq;
+ bool suspended;
+ bool suspend_save_flag;
+};
+
+/* OMAP_PRCM_IRQ: convenience macro for creating struct omap_prcm_irq records */
+#define OMAP_PRCM_IRQ(_name, _offset, _priority) { \
+ .name = _name, \
+ .offset = _offset, \
+ .priority = _priority \
+ }
+
+/**
+ * struct omap_prcm_init_data - PRCM driver init data
+ * @index: clock memory mapping index to be used
+ * @mem: IO mem pointer for this module
+ * @offset: module base address offset from the IO base
+ * @flags: PRCM module init flags
+ * @device_inst_offset: device instance offset within the module address space
+ * @init: low level PRCM init function for this module
+ * @np: device node for this PRCM module
+ */
+struct omap_prcm_init_data {
+ int index;
+ void __iomem *mem;
+ s16 offset;
+ u16 flags;
+ s32 device_inst_offset;
+ int (*init)(const struct omap_prcm_init_data *data);
+ struct device_node *np;
+};
+
+extern void omap_prcm_irq_cleanup(void);
+extern int omap_prcm_register_chain_handler(
+ struct omap_prcm_irq_setup *irq_setup);
+extern int omap_prcm_event_to_irq(const char *event);
+extern void omap_prcm_irq_prepare(void);
+extern void omap_prcm_irq_complete(void);
+
+# endif
+
+#endif
+
diff --git a/arch/arm/mach-omap2/prcm43xx.h b/arch/arm/mach-omap2/prcm43xx.h
new file mode 100644
index 000000000..d0261996d
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm43xx.h
@@ -0,0 +1,149 @@
+/*
+ * AM43x PRCM defines
+ *
+ * Copyright (C) 2013 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_43XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRCM_43XX_H
+
+#define AM43XX_PRM_PARTITION 1
+#define AM43XX_CM_PARTITION 1
+
+/* PRM instances */
+#define AM43XX_PRM_OCP_SOCKET_INST 0x0000
+#define AM43XX_PRM_MPU_INST 0x0300
+#define AM43XX_PRM_GFX_INST 0x0400
+#define AM43XX_PRM_RTC_INST 0x0500
+#define AM43XX_PRM_TAMPER_INST 0x0600
+#define AM43XX_PRM_CEFUSE_INST 0x0700
+#define AM43XX_PRM_PER_INST 0x0800
+#define AM43XX_PRM_WKUP_INST 0x2000
+#define AM43XX_PRM_DEVICE_INST 0x4000
+
+/* RM RSTCTRL offsets */
+#define AM43XX_RM_PER_RSTCTRL_OFFSET 0x0010
+#define AM43XX_RM_GFX_RSTCTRL_OFFSET 0x0010
+#define AM43XX_RM_WKUP_RSTCTRL_OFFSET 0x0010
+
+/* RM RSTST offsets */
+#define AM43XX_RM_GFX_RSTST_OFFSET 0x0014
+#define AM43XX_RM_WKUP_RSTST_OFFSET 0x0014
+
+/* CM instances */
+#define AM43XX_CM_WKUP_INST 0x2800
+#define AM43XX_CM_DEVICE_INST 0x4100
+#define AM43XX_CM_DPLL_INST 0x4200
+#define AM43XX_CM_MPU_INST 0x8300
+#define AM43XX_CM_GFX_INST 0x8400
+#define AM43XX_CM_RTC_INST 0x8500
+#define AM43XX_CM_TAMPER_INST 0x8600
+#define AM43XX_CM_CEFUSE_INST 0x8700
+#define AM43XX_CM_PER_INST 0x8800
+
+/* CD offsets */
+#define AM43XX_CM_WKUP_L3_AON_CDOFFS 0x0000
+#define AM43XX_CM_WKUP_L3S_TSC_CDOFFS 0x0100
+#define AM43XX_CM_WKUP_L4_WKUP_AON_CDOFFS 0x0200
+#define AM43XX_CM_WKUP_WKUP_CDOFFS 0x0300
+#define AM43XX_CM_MPU_MPU_CDOFFS 0x0000
+#define AM43XX_CM_GFX_GFX_L3_CDOFFS 0x0000
+#define AM43XX_CM_RTC_RTC_CDOFFS 0x0000
+#define AM43XX_CM_TAMPER_TAMPER_CDOFFS 0x0000
+#define AM43XX_CM_CEFUSE_CEFUSE_CDOFFS 0x0000
+#define AM43XX_CM_PER_L3_CDOFFS 0x0000
+#define AM43XX_CM_PER_L3S_CDOFFS 0x0200
+#define AM43XX_CM_PER_ICSS_CDOFFS 0x0300
+#define AM43XX_CM_PER_L4LS_CDOFFS 0x0400
+#define AM43XX_CM_PER_EMIF_CDOFFS 0x0700
+#define AM43XX_CM_PER_DSS_CDOFFS 0x0a00
+#define AM43XX_CM_PER_CPSW_CDOFFS 0x0b00
+#define AM43XX_CM_PER_OCPWP_L3_CDOFFS 0x0c00
+
+/* CLK CTRL offsets */
+#define AM43XX_CM_PER_UART1_CLKCTRL_OFFSET 0x0580
+#define AM43XX_CM_PER_UART2_CLKCTRL_OFFSET 0x0588
+#define AM43XX_CM_PER_UART3_CLKCTRL_OFFSET 0x0590
+#define AM43XX_CM_PER_UART4_CLKCTRL_OFFSET 0x0598
+#define AM43XX_CM_PER_UART5_CLKCTRL_OFFSET 0x05a0
+#define AM43XX_CM_PER_DCAN0_CLKCTRL_OFFSET 0x0428
+#define AM43XX_CM_PER_DCAN1_CLKCTRL_OFFSET 0x0430
+#define AM43XX_CM_PER_ELM_CLKCTRL_OFFSET 0x0468
+#define AM43XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET 0x0438
+#define AM43XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET 0x0440
+#define AM43XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET 0x0448
+#define AM43XX_CM_PER_GPIO1_CLKCTRL_OFFSET 0x0478
+#define AM43XX_CM_PER_GPIO2_CLKCTRL_OFFSET 0x0480
+#define AM43XX_CM_PER_GPIO3_CLKCTRL_OFFSET 0x0488
+#define AM43XX_CM_PER_I2C1_CLKCTRL_OFFSET 0x04a8
+#define AM43XX_CM_PER_I2C2_CLKCTRL_OFFSET 0x04b0
+#define AM43XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET 0x04b8
+#define AM43XX_CM_PER_MMC0_CLKCTRL_OFFSET 0x04c0
+#define AM43XX_CM_PER_MMC1_CLKCTRL_OFFSET 0x04c8
+#define AM43XX_CM_PER_SPI0_CLKCTRL_OFFSET 0x0500
+#define AM43XX_CM_PER_SPI1_CLKCTRL_OFFSET 0x0508
+#define AM43XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET 0x0528
+#define AM43XX_CM_PER_TIMER2_CLKCTRL_OFFSET 0x0530
+#define AM43XX_CM_PER_TIMER3_CLKCTRL_OFFSET 0x0538
+#define AM43XX_CM_PER_TIMER4_CLKCTRL_OFFSET 0x0540
+#define AM43XX_CM_PER_TIMER5_CLKCTRL_OFFSET 0x0548
+#define AM43XX_CM_PER_TIMER6_CLKCTRL_OFFSET 0x0550
+#define AM43XX_CM_PER_TIMER7_CLKCTRL_OFFSET 0x0558
+#define AM43XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET 0x0228
+#define AM43XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET 0x0360
+#define AM43XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET 0x0350
+#define AM43XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET 0x0358
+#define AM43XX_CM_WKUP_UART0_CLKCTRL_OFFSET 0x0348
+#define AM43XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET 0x0328
+#define AM43XX_CM_WKUP_I2C0_CLKCTRL_OFFSET 0x0340
+#define AM43XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET 0x0368
+#define AM43XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET 0x0120
+#define AM43XX_CM_WKUP_WDT1_CLKCTRL_OFFSET 0x0338
+#define AM43XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET 0x0220
+#define AM43XX_CM_RTC_RTC_CLKCTRL_OFFSET 0x0020
+#define AM43XX_CM_PER_MMC2_CLKCTRL_OFFSET 0x0248
+#define AM43XX_CM_PER_QSPI_CLKCTRL_OFFSET 0x0258
+#define AM43XX_CM_PER_GPMC_CLKCTRL_OFFSET 0x0220
+#define AM43XX_CM_PER_MCASP0_CLKCTRL_OFFSET 0x0238
+#define AM43XX_CM_PER_MCASP1_CLKCTRL_OFFSET 0x0240
+#define AM43XX_CM_PER_L4LS_CLKCTRL_OFFSET 0x0420
+#define AM43XX_CM_PER_L3_CLKCTRL_OFFSET 0x0020
+#define AM43XX_CM_PER_TPCC_CLKCTRL_OFFSET 0x0078
+#define AM43XX_CM_PER_TPTC0_CLKCTRL_OFFSET 0x0080
+#define AM43XX_CM_PER_TPTC1_CLKCTRL_OFFSET 0x0088
+#define AM43XX_CM_PER_TPTC2_CLKCTRL_OFFSET 0x0090
+#define AM43XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET 0x0b20
+#define AM43XX_CM_PER_PRUSS_CLKCTRL_OFFSET 0x0320
+#define AM43XX_CM_GFX_GFX_CLKCTRL_OFFSET 0x0020
+#define AM43XX_CM_PER_L4HS_CLKCTRL_OFFSET 0x00a0
+#define AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET 0x0020
+#define AM43XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET 0x0040
+#define AM43XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET 0x0050
+#define AM43XX_CM_PER_SHA0_CLKCTRL_OFFSET 0x0058
+#define AM43XX_CM_PER_AES0_CLKCTRL_OFFSET 0x0028
+#define AM43XX_CM_PER_TIMER8_CLKCTRL_OFFSET 0x0560
+#define AM43XX_CM_PER_TIMER9_CLKCTRL_OFFSET 0x0568
+#define AM43XX_CM_PER_TIMER10_CLKCTRL_OFFSET 0x0570
+#define AM43XX_CM_PER_TIMER11_CLKCTRL_OFFSET 0x0578
+#define AM43XX_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET 0x0230
+#define AM43XX_CM_PER_EPWMSS3_CLKCTRL_OFFSET 0x0450
+#define AM43XX_CM_PER_EPWMSS4_CLKCTRL_OFFSET 0x0458
+#define AM43XX_CM_PER_EPWMSS5_CLKCTRL_OFFSET 0x0460
+#define AM43XX_CM_PER_SPI2_CLKCTRL_OFFSET 0x0510
+#define AM43XX_CM_PER_SPI3_CLKCTRL_OFFSET 0x0518
+#define AM43XX_CM_PER_SPI4_CLKCTRL_OFFSET 0x0520
+#define AM43XX_CM_PER_GPIO4_CLKCTRL_OFFSET 0x0490
+#define AM43XX_CM_PER_GPIO5_CLKCTRL_OFFSET 0x0498
+#define AM43XX_CM_PER_USB_OTG_SS0_CLKCTRL_OFFSET 0x0260
+#define AM43XX_CM_PER_USBPHYOCP2SCP0_CLKCTRL_OFFSET 0x05B8
+#define AM43XX_CM_PER_USB_OTG_SS1_CLKCTRL_OFFSET 0x0268
+#define AM43XX_CM_PER_USBPHYOCP2SCP1_CLKCTRL_OFFSET 0x05C0
+#define AM43XX_CM_PER_DSS_CLKCTRL_OFFSET 0x0a20
+#define AM43XX_CM_PER_HDQ1W_CLKCTRL_OFFSET 0x04a0
+#define AM43XX_CM_PER_VPFE0_CLKCTRL_OFFSET 0x0068
+#define AM43XX_CM_PER_VPFE1_CLKCTRL_OFFSET 0x0070
+#endif
diff --git a/arch/arm/mach-omap2/prcm44xx.h b/arch/arm/mach-omap2/prcm44xx.h
new file mode 100644
index 000000000..4fea2cfdf
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm44xx.h
@@ -0,0 +1,53 @@
+/*
+ * 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
+
+#define OMAP54XX_PRM_PARTITION 1
+#define OMAP54XX_CM_CORE_AON_PARTITION 2
+#define OMAP54XX_CM_CORE_PARTITION 3
+#define OMAP54XX_SCRM_PARTITION 4
+#define OMAP54XX_PRCM_MPU_PARTITION 5
+
+#define DRA7XX_PRM_PARTITION 1
+#define DRA7XX_CM_CORE_AON_PARTITION 2
+#define DRA7XX_CM_CORE_PARTITION 3
+#define DRA7XX_MPU_PRCM_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 000000000..cdbee6326
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm_mpu44xx.c
@@ -0,0 +1,62 @@
+/*
+ * 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 "iomap.h"
+#include "common.h"
+#include "prcm_mpu44xx.h"
+#include "cm-regbits-44xx.h"
+
+/*
+ * prcm_mpu_base: the virtual address of the start of the PRCM_MPU IP
+ * block registers
+ */
+void __iomem *prcm_mpu_base;
+
+/* PRCM_MPU low-level functions */
+
+u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 reg)
+{
+ return readl_relaxed(OMAP44XX_PRCM_MPU_REGADDR(inst, reg));
+}
+
+void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 reg)
+{
+ writel_relaxed(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;
+}
+
+/**
+ * omap2_set_globals_prcm_mpu - set the MPU PRCM base address (for early use)
+ * @prcm_mpu: PRCM_MPU base virtual address
+ *
+ * XXX Will be replaced when the PRM/CM drivers are completed.
+ */
+void __init omap2_set_globals_prcm_mpu(void __iomem *prcm_mpu)
+{
+ prcm_mpu_base = prcm_mpu;
+}
diff --git a/arch/arm/mach-omap2/prcm_mpu44xx.h b/arch/arm/mach-omap2/prcm_mpu44xx.h
new file mode 100644
index 000000000..ac9cb4550
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm_mpu44xx.h
@@ -0,0 +1,97 @@
+/*
+ * OMAP44xx PRCM MPU instance offset macros
+ *
+ * Copyright (C) 2010, 2012 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
+
+#include "prcm_mpu_44xx_54xx.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)
+
+#endif
diff --git a/arch/arm/mach-omap2/prcm_mpu54xx.h b/arch/arm/mach-omap2/prcm_mpu54xx.h
new file mode 100644
index 000000000..bc2ce3288
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm_mpu54xx.h
@@ -0,0 +1,87 @@
+/*
+ * OMAP54xx PRCM MPU instance offset macros
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * 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_PRCM_MPU54XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRCM_MPU54XX_H
+
+#include "prcm_mpu_44xx_54xx.h"
+#include "common.h"
+
+#define OMAP54XX_PRCM_MPU_BASE 0x48243000
+
+#define OMAP54XX_PRCM_MPU_REGADDR(inst, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE + (inst) + (reg))
+
+/* PRCM_MPU instances */
+#define OMAP54XX_PRCM_MPU_OCP_SOCKET_INST 0x0000
+#define OMAP54XX_PRCM_MPU_DEVICE_INST 0x0200
+#define OMAP54XX_PRCM_MPU_PRM_C0_INST 0x0400
+#define OMAP54XX_PRCM_MPU_CM_C0_INST 0x0600
+#define OMAP54XX_PRCM_MPU_PRM_C1_INST 0x0800
+#define OMAP54XX_PRCM_MPU_CM_C1_INST 0x0a00
+
+/* PRCM_MPU clockdomain register offsets (from instance start) */
+#define OMAP54XX_PRCM_MPU_CM_C0_CPU0_CDOFFS 0x0000
+#define OMAP54XX_PRCM_MPU_CM_C1_CPU1_CDOFFS 0x0000
+
+
+/*
+ * 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.PRCM_MPU_OCP_SOCKET register offsets */
+#define OMAP54XX_REVISION_PRCM_MPU_OFFSET 0x0000
+
+/* PRCM_MPU.PRCM_MPU_DEVICE register offsets */
+#define OMAP54XX_PRCM_MPU_PRM_RSTST_OFFSET 0x0000
+#define OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET 0x0004
+#define OMAP54XX_PRM_FRAC_INCREMENTER_NUMERATOR_OFFSET 0x0010
+#define OMAP54XX_PRM_FRAC_INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x0014
+
+/* PRCM_MPU.PRCM_MPU_PRM_C0 register offsets */
+#define OMAP54XX_PM_CPU0_PWRSTCTRL_OFFSET 0x0000
+#define OMAP54XX_PM_CPU0_PWRSTST_OFFSET 0x0004
+#define OMAP54XX_RM_CPU0_CPU0_RSTCTRL_OFFSET 0x0010
+#define OMAP54XX_RM_CPU0_CPU0_RSTST_OFFSET 0x0014
+#define OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET 0x0024
+
+/* PRCM_MPU.PRCM_MPU_CM_C0 register offsets */
+#define OMAP54XX_CM_CPU0_CLKSTCTRL_OFFSET 0x0000
+#define OMAP54XX_CM_CPU0_CPU0_CLKCTRL_OFFSET 0x0020
+#define OMAP54XX_CM_CPU0_CPU0_CLKCTRL OMAP54XX_PRCM_MPU_REGADDR(OMAP54XX_PRCM_MPU_CM_C0_INST, 0x0020)
+
+/* PRCM_MPU.PRCM_MPU_PRM_C1 register offsets */
+#define OMAP54XX_PM_CPU1_PWRSTCTRL_OFFSET 0x0000
+#define OMAP54XX_PM_CPU1_PWRSTST_OFFSET 0x0004
+#define OMAP54XX_RM_CPU1_CPU1_RSTCTRL_OFFSET 0x0010
+#define OMAP54XX_RM_CPU1_CPU1_RSTST_OFFSET 0x0014
+#define OMAP54XX_RM_CPU1_CPU1_CONTEXT_OFFSET 0x0024
+
+/* PRCM_MPU.PRCM_MPU_CM_C1 register offsets */
+#define OMAP54XX_CM_CPU1_CLKSTCTRL_OFFSET 0x0000
+#define OMAP54XX_CM_CPU1_CPU1_CLKCTRL_OFFSET 0x0020
+#define OMAP54XX_CM_CPU1_CPU1_CLKCTRL OMAP54XX_PRCM_MPU_REGADDR(OMAP54XX_PRCM_MPU_CM_C1_INST, 0x0020)
+
+#endif
diff --git a/arch/arm/mach-omap2/prcm_mpu7xx.h b/arch/arm/mach-omap2/prcm_mpu7xx.h
new file mode 100644
index 000000000..9ebb5ce08
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm_mpu7xx.h
@@ -0,0 +1,78 @@
+/*
+ * DRA7xx PRCM MPU instance offset macros
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Generated by code originally written by:
+ * 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_PRCM_MPU7XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRCM_MPU7XX_H
+
+#include "prcm_mpu_44xx_54xx.h"
+
+#define DRA7XX_PRCM_MPU_BASE 0x48243000
+
+#define DRA7XX_PRCM_MPU_REGADDR(inst, reg) \
+ OMAP2_L4_IO_ADDRESS(DRA7XX_PRCM_MPU_BASE + (inst) + (reg))
+
+/* MPU_PRCM instances */
+#define DRA7XX_MPU_PRCM_OCP_SOCKET_INST 0x0000
+#define DRA7XX_MPU_PRCM_DEVICE_INST 0x0200
+#define DRA7XX_MPU_PRCM_PRM_C0_INST 0x0400
+#define DRA7XX_MPU_PRCM_CM_C0_INST 0x0600
+#define DRA7XX_MPU_PRCM_PRM_C1_INST 0x0800
+#define DRA7XX_MPU_PRCM_CM_C1_INST 0x0a00
+
+/* PRCM_MPU clockdomain register offsets (from instance start) */
+#define DRA7XX_MPU_PRCM_CM_C0_CPU0_CDOFFS 0x0000
+#define DRA7XX_MPU_PRCM_CM_C1_CPU1_CDOFFS 0x0000
+
+
+/* MPU_PRCM */
+
+/* MPU_PRCM.PRCM_MPU_OCP_SOCKET register offsets */
+#define DRA7XX_REVISION_PRCM_MPU_OFFSET 0x0000
+
+/* MPU_PRCM.PRCM_MPU_DEVICE register offsets */
+#define DRA7XX_PRM_FRAC_INCREMENTER_NUMERATOR_OFFSET 0x0010
+#define DRA7XX_PRM_FRAC_INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x0014
+
+/* MPU_PRCM.PRCM_MPU_PRM_C0 register offsets */
+#define DRA7XX_PM_CPU0_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_CPU0_PWRSTST_OFFSET 0x0004
+#define DRA7XX_RM_CPU0_CPU0_RSTCTRL_OFFSET 0x0010
+#define DRA7XX_RM_CPU0_CPU0_RSTST_OFFSET 0x0014
+#define DRA7XX_RM_CPU0_CPU0_CONTEXT_OFFSET 0x0024
+
+/* MPU_PRCM.PRCM_MPU_CM_C0 register offsets */
+#define DRA7XX_CM_CPU0_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_CPU0_CPU0_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_CPU0_CPU0_CLKCTRL DRA7XX_MPU_PRCM_REGADDR(DRA7XX_MPU_PRCM_CM_C0_INST, 0x0020)
+
+/* MPU_PRCM.PRCM_MPU_PRM_C1 register offsets */
+#define DRA7XX_PM_CPU1_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_CPU1_PWRSTST_OFFSET 0x0004
+#define DRA7XX_RM_CPU1_CPU1_RSTCTRL_OFFSET 0x0010
+#define DRA7XX_RM_CPU1_CPU1_RSTST_OFFSET 0x0014
+#define DRA7XX_RM_CPU1_CPU1_CONTEXT_OFFSET 0x0024
+
+/* MPU_PRCM.PRCM_MPU_CM_C1 register offsets */
+#define DRA7XX_CM_CPU1_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_CPU1_CPU1_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_CPU1_CPU1_CLKCTRL DRA7XX_MPU_PRCM_REGADDR(DRA7XX_MPU_PRCM_CM_C1_INST, 0x0020)
+
+#endif
diff --git a/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h b/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h
new file mode 100644
index 000000000..ca149e70b
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h
@@ -0,0 +1,36 @@
+/*
+ * OMAP44xx and OMAP54xx PRCM MPU function prototypes
+ *
+ * Copyright (C) 2010, 2013 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.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_MPU_44XX_54XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRCM_MPU_44XX_54XX_H
+
+#ifndef __ASSEMBLER__
+extern void __iomem *prcm_mpu_base;
+
+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);
+extern void __init omap2_set_globals_prcm_mpu(void __iomem *prcm_mpu);
+#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 000000000..37fc905c9
--- /dev/null
+++ b/arch/arm/mach-omap2/prm-regbits-24xx.h
@@ -0,0 +1,42 @@
+#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.h"
+
+#define OMAP24XX_EN_CORE_SHIFT 0
+#define OMAP24XX_FORCESTATE_MASK (1 << 18)
+#define OMAP24XX_AUTOIDLE_MASK (1 << 0)
+#define OMAP24XX_AUTO_EXTVOLT_MASK (1 << 15)
+#define OMAP24XX_SETOFF_LEVEL_SHIFT 12
+#define OMAP24XX_MEMRETCTRL_MASK (1 << 8)
+#define OMAP24XX_SETRET_LEVEL_SHIFT 6
+#define OMAP24XX_VOLT_LEVEL_SHIFT 0
+#define OMAP2420_CLKOUT2_EN_SHIFT 15
+#define OMAP2420_CLKOUT2_DIV_SHIFT 11
+#define OMAP2420_CLKOUT2_DIV_WIDTH 3
+#define OMAP2420_CLKOUT2_SOURCE_MASK (0x3 << 8)
+#define OMAP24XX_CLKOUT_EN_SHIFT 7
+#define OMAP24XX_CLKOUT_DIV_SHIFT 3
+#define OMAP24XX_CLKOUT_DIV_WIDTH 3
+#define OMAP24XX_CLKOUT_SOURCE_MASK (0x3 << 0)
+#define OMAP24XX_EMULATION_EN_SHIFT 0
+#define OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT 5
+#define OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT 2
+#define OMAP24XX_EXTWMPU_RST_SHIFT 6
+#define OMAP24XX_SECU_WD_RST_SHIFT 5
+#define OMAP24XX_MPU_WD_RST_SHIFT 4
+#define OMAP24XX_SECU_VIOL_RST_SHIFT 3
+#endif
diff --git a/arch/arm/mach-omap2/prm-regbits-33xx.h b/arch/arm/mach-omap2/prm-regbits-33xx.h
new file mode 100644
index 000000000..84feecee4
--- /dev/null
+++ b/arch/arm/mach-omap2/prm-regbits-33xx.h
@@ -0,0 +1,52 @@
+/*
+ * AM33XX PRM_XXX register bits
+ *
+ * Copyright (C) 2011-2012 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 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 __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_33XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_33XX_H
+
+#include "prm.h"
+
+#define AM33XX_GFX_MEM_ONSTATE_MASK (0x3 << 17)
+#define AM33XX_GFX_MEM_RETSTATE_MASK (1 << 6)
+#define AM33XX_GFX_MEM_STATEST_MASK (0x3 << 4)
+#define AM33XX_GLOBAL_WARM_SW_RST_MASK (1 << 1)
+#define AM33XX_RST_GLOBAL_WARM_SW_MASK (1 << 0)
+#define AM33XX_PRUSS_MEM_ONSTATE_MASK (0x3 << 5)
+#define AM33XX_PRUSS_MEM_RETSTATE_MASK (1 << 7)
+#define AM33XX_PRUSS_MEM_STATEST_MASK (0x3 << 23)
+#define AM33XX_LASTPOWERSTATEENTERED_SHIFT 24
+#define AM33XX_LASTPOWERSTATEENTERED_MASK (0x3 << 24)
+#define AM33XX_LOGICRETSTATE_MASK (1 << 2)
+#define AM33XX_LOGICRETSTATE_3_3_MASK (1 << 3)
+#define AM33XX_LOGICSTATEST_SHIFT 2
+#define AM33XX_LOGICSTATEST_MASK (1 << 2)
+#define AM33XX_LOWPOWERSTATECHANGE_SHIFT 4
+#define AM33XX_LOWPOWERSTATECHANGE_MASK (1 << 4)
+#define AM33XX_MPU_L1_ONSTATE_MASK (0x3 << 18)
+#define AM33XX_MPU_L1_RETSTATE_MASK (1 << 22)
+#define AM33XX_MPU_L1_STATEST_MASK (0x3 << 6)
+#define AM33XX_MPU_L2_ONSTATE_MASK (0x3 << 20)
+#define AM33XX_MPU_L2_RETSTATE_MASK (1 << 23)
+#define AM33XX_MPU_L2_STATEST_MASK (0x3 << 8)
+#define AM33XX_MPU_RAM_ONSTATE_MASK (0x3 << 16)
+#define AM33XX_MPU_RAM_RETSTATE_MASK (1 << 24)
+#define AM33XX_MPU_RAM_STATEST_MASK (0x3 << 4)
+#define AM33XX_PER_MEM_ONSTATE_MASK (0x3 << 25)
+#define AM33XX_PER_MEM_RETSTATE_MASK (1 << 29)
+#define AM33XX_PER_MEM_STATEST_MASK (0x3 << 17)
+#define AM33XX_RAM_MEM_ONSTATE_MASK (0x3 << 30)
+#define AM33XX_RAM_MEM_RETSTATE_MASK (1 << 27)
+#define AM33XX_RAM_MEM_STATEST_MASK (0x3 << 21)
+#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 000000000..661d753df
--- /dev/null
+++ b/arch/arm/mach-omap2/prm-regbits-34xx.h
@@ -0,0 +1,144 @@
+/*
+ * 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 "prm3xxx.h"
+
+#define OMAP3430_ERROROFFSET_MASK (0xff << 24)
+#define OMAP3430_ERRORGAIN_MASK (0xff << 16)
+#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)
+#define OMAP3430_SMPSWAITTIMEMIN_SHIFT 8
+#define OMAP3430_VSTEPMIN_SHIFT 0
+#define OMAP3430_SMPSWAITTIMEMAX_SHIFT 8
+#define OMAP3430_VSTEPMAX_SHIFT 0
+#define OMAP3430_VDDMAX_SHIFT 24
+#define OMAP3430_VDDMIN_SHIFT 16
+#define OMAP3430_TIMEOUT_SHIFT 0
+#define OMAP3430_VPVOLTAGE_MASK (0xff << 0)
+#define OMAP3430_EN_PER_SHIFT 7
+#define OMAP3430_LOGICSTATEST_MASK (1 << 2)
+#define OMAP3430_LASTLOGICSTATEENTERED_MASK (1 << 2)
+#define OMAP3430_LASTPOWERSTATEENTERED_MASK (0x3 << 0)
+#define OMAP3430_GRPSEL_MCBSP5_MASK (1 << 10)
+#define OMAP3430_GRPSEL_MCBSP1_MASK (1 << 9)
+#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_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_MCBSP4_MASK (1 << 2)
+#define OMAP3430_GRPSEL_MCBSP3_MASK (1 << 1)
+#define OMAP3430_GRPSEL_MCBSP2_MASK (1 << 0)
+#define OMAP3430_GRPSEL_GPIO1_MASK (1 << 3)
+#define OMAP3430_GRPSEL_GPT12_MASK (1 << 1)
+#define OMAP3430_GRPSEL_GPT1_MASK (1 << 0)
+#define OMAP3430_RST3_IVA2_MASK (1 << 2)
+#define OMAP3430_RST2_IVA2_MASK (1 << 1)
+#define OMAP3430_RST1_IVA2_MASK (1 << 0)
+#define OMAP3430_L2FLATMEMONSTATE_MASK (0x3 << 22)
+#define OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK (0x3 << 20)
+#define OMAP3430_L1FLATMEMONSTATE_MASK (0x3 << 18)
+#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)
+#define OMAP3430_L2FLATMEMSTATEST_MASK (0x3 << 10)
+#define OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK (0x3 << 8)
+#define OMAP3430_L1FLATMEMSTATEST_MASK (0x3 << 6)
+#define OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK (0x3 << 4)
+#define OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK (0x3 << 10)
+#define OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK (0x3 << 8)
+#define OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT 25
+#define OMAP3430_VP2_TRANXDONE_ST_MASK (1 << 21)
+#define OMAP3430_VP1_TRANXDONE_ST_MASK (1 << 15)
+#define OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT 8
+#define OMAP3430_MPU_DPLL_ST_SHIFT 7
+#define OMAP3430_PERIPH_DPLL_ST_SHIFT 6
+#define OMAP3430_CORE_DPLL_ST_SHIFT 5
+#define OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT 25
+#define OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT 8
+#define OMAP3430_MPU_DPLL_RECAL_EN_SHIFT 7
+#define OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT 6
+#define OMAP3430_CORE_DPLL_RECAL_EN_SHIFT 5
+#define OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT 5
+#define OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT 2
+#define OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON_MASK (1 << 1)
+#define OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST_MASK (1 << 0)
+#define OMAP3430_LASTMEM2STATEENTERED_MASK (0x3 << 6)
+#define OMAP3430_LASTMEM1STATEENTERED_MASK (0x3 << 4)
+#define OMAP3430_EN_IO_CHAIN_MASK (1 << 16)
+#define OMAP3430_EN_IO_MASK (1 << 8)
+#define OMAP3430_EN_GPIO1_MASK (1 << 3)
+#define OMAP3430_ST_IO_CHAIN_MASK (1 << 16)
+#define OMAP3430_ST_IO_MASK (1 << 8)
+#define OMAP3430_SYS_CLKIN_SEL_SHIFT 0
+#define OMAP3430_SYS_CLKIN_SEL_WIDTH 3
+#define OMAP3430_CLKOUT_EN_SHIFT 7
+#define OMAP3430_PM_WKEN_DSS_EN_DSS_MASK (1 << 0)
+#define OMAP3430ES2_SAVEANDRESTORE_SHIFT 4
+#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)
+#define OMAP3430_VOLRA1_MASK (0xff << 16)
+#define OMAP3430_VOLRA0_MASK (0xff << 0)
+#define OMAP3430_CMDRA1_MASK (0xff << 16)
+#define OMAP3430_CMDRA0_MASK (0xff << 0)
+#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_RET_SHIFT 8
+#define OMAP3430_VC_CMD_OFF_SHIFT 0
+#define OMAP3430_SREN_MASK (1 << 4)
+#define OMAP3430_HSEN_MASK (1 << 3)
+#define OMAP3430_MCODE_MASK (0x7 << 0)
+#define OMAP3430_VALID_MASK (1 << 24)
+#define OMAP3430_DATA_SHIFT 16
+#define OMAP3430_REGADDR_SHIFT 8
+#define OMAP3430_SLAVEADDR_SHIFT 0
+#define OMAP3430_ICECRUSHER_RST_SHIFT 10
+#define OMAP3430_ICEPICK_RST_SHIFT 9
+#define OMAP3430_VDD2_VOLTAGE_MANAGER_RST_SHIFT 8
+#define OMAP3430_VDD1_VOLTAGE_MANAGER_RST_SHIFT 7
+#define OMAP3430_EXTERNAL_WARM_RST_SHIFT 6
+#define OMAP3430_SECURE_WD_RST_SHIFT 5
+#define OMAP3430_MPU_WD_RST_SHIFT 4
+#define OMAP3430_SECURITY_VIOL_RST_SHIFT 3
+#define OMAP3430_GLOBAL_SW_RST_SHIFT 1
+#define OMAP3430_GLOBAL_COLD_RST_SHIFT 0
+#define OMAP3430_GLOBAL_COLD_RST_MASK (1 << 0)
+#define OMAP3430_PRM_VOLTCTRL_SEL_VMODE (1 << 4)
+#define OMAP3430_PRM_VOLTCTRL_SEL_OFF (1 << 3)
+#define OMAP3430_PRM_VOLTCTRL_AUTO_OFF (1 << 2)
+#define OMAP3430_PRM_VOLTCTRL_AUTO_RET (1 << 1)
+#define OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP (1 << 0)
+#define OMAP3430_SETUP_TIME2_MASK (0xffff << 16)
+#define OMAP3430_SETUP_TIME1_MASK (0xffff << 0)
+#define OMAP3430_PRM_POLCTRL_OFFMODE_POL (1 << 3)
+#define OMAP3430_PRM_POLCTRL_CLKOUT_POL (1 << 2)
+#define OMAP3430_PRM_POLCTRL_CLKREQ_POL (1 << 1)
+#define OMAP3430_PRM_POLCTRL_EXTVOL_POL (1 << 0)
+#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 000000000..e794828de
--- /dev/null
+++ b/arch/arm/mach-omap2/prm-regbits-44xx.h
@@ -0,0 +1,102 @@
+/*
+ * 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
+
+#define OMAP4430_C2C_RST_SHIFT 10
+#define OMAP4430_CMDRA_VDD_CORE_L_MASK (0xff << 0)
+#define OMAP4430_CMDRA_VDD_IVA_L_MASK (0xff << 8)
+#define OMAP4430_CMDRA_VDD_MPU_L_MASK (0xff << 16)
+#define OMAP4430_DATA_SHIFT 16
+#define OMAP4430_ERRORGAIN_MASK (0xff << 16)
+#define OMAP4430_ERROROFFSET_MASK (0xff << 24)
+#define OMAP4430_EXTERNAL_WARM_RST_SHIFT 5
+#define OMAP4430_FORCEUPDATE_MASK (1 << 1)
+#define OMAP4430_GLOBAL_COLD_RST_SHIFT 0
+#define OMAP4430_GLOBAL_WARM_SW_RST_SHIFT 1
+#define OMAP4430_GLOBAL_WUEN_MASK (1 << 16)
+#define OMAP4430_HSMCODE_MASK (0x7 << 0)
+#define OMAP4430_SRMODEEN_MASK (1 << 4)
+#define OMAP4430_HSMODEEN_MASK (1 << 3)
+#define OMAP4430_HSSCLL_SHIFT 24
+#define OMAP4430_ICEPICK_RST_SHIFT 9
+#define OMAP4430_INITVDD_MASK (1 << 2)
+#define OMAP4430_INITVOLTAGE_MASK (0xff << 8)
+#define OMAP4430_LASTPOWERSTATEENTERED_SHIFT 24
+#define OMAP4430_LASTPOWERSTATEENTERED_MASK (0x3 << 24)
+#define OMAP4430_LOGICRETSTATE_SHIFT 2
+#define OMAP4430_LOGICRETSTATE_MASK (1 << 2)
+#define OMAP4430_LOGICSTATEST_SHIFT 2
+#define OMAP4430_LOGICSTATEST_MASK (1 << 2)
+#define OMAP4430_LOSTCONTEXT_DFF_MASK (1 << 0)
+#define OMAP4430_LOSTMEM_AESSMEM_MASK (1 << 8)
+#define OMAP4430_LOWPOWERSTATECHANGE_SHIFT 4
+#define OMAP4430_LOWPOWERSTATECHANGE_MASK (1 << 4)
+#define OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT 2
+#define OMAP4430_MPU_WDT_RST_SHIFT 3
+#define OMAP4430_OCP_NRET_BANK_ONSTATE_MASK (0x3 << 24)
+#define OMAP4430_OCP_NRET_BANK_RETSTATE_MASK (1 << 12)
+#define OMAP4430_OCP_NRET_BANK_STATEST_MASK (0x3 << 12)
+#define OMAP4430_OFF_SHIFT 0
+#define OMAP4430_ON_SHIFT 24
+#define OMAP4430_ON_MASK (0xff << 24)
+#define OMAP4430_ONLP_SHIFT 16
+#define OMAP4430_RAMP_DOWN_COUNT_SHIFT 16
+#define OMAP4430_RAMP_UP_COUNT_SHIFT 0
+#define OMAP4430_RAMP_UP_PRESCAL_SHIFT 8
+#define OMAP4430_REGADDR_SHIFT 8
+#define OMAP4430_RET_SHIFT 8
+#define OMAP4430_RST_GLOBAL_WARM_SW_MASK (1 << 0)
+#define OMAP4430_SA_VDD_CORE_L_SHIFT 0
+#define OMAP4430_SA_VDD_CORE_L_0_6_MASK (0x7f << 0)
+#define OMAP4430_SA_VDD_IVA_L_SHIFT 8
+#define OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK (0x7f << 8)
+#define OMAP4430_SA_VDD_MPU_L_SHIFT 16
+#define OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK (0x7f << 16)
+#define OMAP4430_SCLH_SHIFT 0
+#define OMAP4430_SCLL_SHIFT 8
+#define OMAP4430_SECURE_WDT_RST_SHIFT 4
+#define OMAP4430_SLAVEADDR_SHIFT 0
+#define OMAP4430_SMPSWAITTIMEMAX_SHIFT 8
+#define OMAP4430_SMPSWAITTIMEMIN_SHIFT 8
+#define OMAP4430_TIMEOUT_SHIFT 0
+#define OMAP4430_TIMEOUTEN_MASK (1 << 3)
+#define OMAP4430_VALID_MASK (1 << 24)
+#define OMAP4430_VDDMAX_SHIFT 24
+#define OMAP4430_VDDMIN_SHIFT 16
+#define OMAP4430_VDD_CORE_VOLT_MGR_RST_SHIFT 8
+#define OMAP4430_VDD_IVA_VOLT_MGR_RST_SHIFT 7
+#define OMAP4430_VDD_MPU_VOLT_MGR_RST_SHIFT 6
+#define OMAP4430_VOLRA_VDD_CORE_L_MASK (0xff << 0)
+#define OMAP4430_VOLRA_VDD_IVA_L_MASK (0xff << 8)
+#define OMAP4430_VOLRA_VDD_MPU_L_MASK (0xff << 16)
+#define OMAP4430_VPENABLE_MASK (1 << 0)
+#define OMAP4430_VPVOLTAGE_MASK (0xff << 0)
+#define OMAP4430_VP_CORE_TRANXDONE_ST_MASK (1 << 21)
+#define OMAP4430_VP_IVA_TRANXDONE_ST_MASK (1 << 29)
+#define OMAP4430_VP_MPU_TRANXDONE_ST_MASK (1 << 5)
+#define OMAP4430_VSTEPMAX_SHIFT 0
+#define OMAP4430_VSTEPMIN_SHIFT 0
+#define OMAP4430_WUCLK_CTRL_MASK (1 << 8)
+#define OMAP4430_WUCLK_STATUS_SHIFT 9
+#define OMAP4430_WUCLK_STATUS_MASK (1 << 9)
+#endif
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
new file mode 100644
index 000000000..233bc84fb
--- /dev/null
+++ b/arch/arm/mach-omap2/prm.h
@@ -0,0 +1,187 @@
+/*
+ * OMAP2/3/4 Power/Reset Management (PRM) bitfield definitions
+ *
+ * Copyright (C) 2007-2009, 2012 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"
+
+# ifndef __ASSEMBLER__
+extern void __iomem *prm_base;
+extern u16 prm_features;
+extern void omap2_set_globals_prm(void __iomem *prm);
+int omap_prcm_init(void);
+int omap2_prm_base_init(void);
+int omap2_prcm_base_init(void);
+# endif
+
+/*
+ * prm_features flag values
+ *
+ * PRM_HAS_IO_WAKEUP: has IO wakeup capability
+ * PRM_HAS_VOLTAGE: has voltage domains
+ * PRM_IRQ_DEFAULT: use default irq number for PRM irq
+ */
+#define PRM_HAS_IO_WAKEUP BIT(0)
+#define PRM_HAS_VOLTAGE BIT(1)
+#define PRM_IRQ_DEFAULT BIT(2)
+
+/*
+ * MAX_MODULE_SOFTRESET_WAIT: Maximum microseconds to wait for OMAP
+ * module to softreset
+ */
+#define MAX_MODULE_SOFTRESET_WAIT 10000
+
+/*
+ * MAX_MODULE_HARDRESET_WAIT: Maximum microseconds to wait for an OMAP
+ * submodule to exit hardreset
+ */
+#define MAX_MODULE_HARDRESET_WAIT 10000
+
+/*
+ * Register bitfields
+ */
+
+/*
+ * 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)
+
+/*
+ * Standardized OMAP reset source bits
+ *
+ * To the extent these happen to match the hardware register bit
+ * shifts, it's purely coincidental. Used by omap-wdt.c.
+ * OMAP_UNKNOWN_RST_SRC_ID_SHIFT is a special value, used whenever
+ * there are any bits remaining in the global PRM_RSTST register that
+ * haven't been identified, or when the PRM code for the current SoC
+ * doesn't know how to interpret the register.
+ */
+#define OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT 0
+#define OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT 1
+#define OMAP_SECU_VIOL_RST_SRC_ID_SHIFT 2
+#define OMAP_MPU_WD_RST_SRC_ID_SHIFT 3
+#define OMAP_SECU_WD_RST_SRC_ID_SHIFT 4
+#define OMAP_EXTWARM_RST_SRC_ID_SHIFT 5
+#define OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT 6
+#define OMAP_VDD_IVA_VM_RST_SRC_ID_SHIFT 7
+#define OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT 8
+#define OMAP_ICEPICK_RST_SRC_ID_SHIFT 9
+#define OMAP_ICECRUSHER_RST_SRC_ID_SHIFT 10
+#define OMAP_C2C_RST_SRC_ID_SHIFT 11
+#define OMAP_UNKNOWN_RST_SRC_ID_SHIFT 12
+
+#ifndef __ASSEMBLER__
+
+/**
+ * struct prm_reset_src_map - map register bitshifts to standard bitshifts
+ * @reg_shift: bitshift in the PRM reset source register
+ * @std_shift: bitshift equivalent in the standard reset source list
+ *
+ * The fields are signed because -1 is used as a terminator.
+ */
+struct prm_reset_src_map {
+ s8 reg_shift;
+ s8 std_shift;
+};
+
+/**
+ * struct prm_ll_data - fn ptrs to per-SoC PRM function implementations
+ * @read_reset_sources: ptr to the SoC PRM-specific get_reset_source impl
+ * @was_any_context_lost_old: ptr to the SoC PRM context loss test fn
+ * @clear_context_loss_flags_old: ptr to the SoC PRM context loss flag clear fn
+ * @late_init: ptr to the late init function
+ * @assert_hardreset: ptr to the SoC PRM hardreset assert impl
+ * @deassert_hardreset: ptr to the SoC PRM hardreset deassert impl
+ *
+ * XXX @was_any_context_lost_old and @clear_context_loss_flags_old are
+ * deprecated.
+ */
+struct prm_ll_data {
+ u32 (*read_reset_sources)(void);
+ bool (*was_any_context_lost_old)(u8 part, s16 inst, u16 idx);
+ void (*clear_context_loss_flags_old)(u8 part, s16 inst, u16 idx);
+ int (*late_init)(void);
+ int (*assert_hardreset)(u8 shift, u8 part, s16 prm_mod, u16 offset);
+ int (*deassert_hardreset)(u8 shift, u8 st_shift, u8 part, s16 prm_mod,
+ u16 offset, u16 st_offset);
+ int (*is_hardreset_asserted)(u8 shift, u8 part, s16 prm_mod,
+ u16 offset);
+ void (*reset_system)(void);
+ int (*clear_mod_irqs)(s16 module, u8 regs, u32 wkst_mask);
+ u32 (*vp_check_txdone)(u8 vp_id);
+ void (*vp_clear_txdone)(u8 vp_id);
+};
+
+extern int prm_register(struct prm_ll_data *pld);
+extern int prm_unregister(struct prm_ll_data *pld);
+
+int omap_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod, u16 offset);
+int omap_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 prm_mod,
+ u16 offset, u16 st_offset);
+int omap_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset);
+extern u32 prm_read_reset_sources(void);
+extern bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx);
+extern void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx);
+void omap_prm_reset_system(void);
+
+void omap_prm_reconfigure_io_chain(void);
+int omap_prm_clear_mod_irqs(s16 module, u8 regs, u32 wkst_mask);
+
+/*
+ * Voltage Processor (VP) identifiers
+ */
+#define OMAP3_VP_VDD_MPU_ID 0
+#define OMAP3_VP_VDD_CORE_ID 1
+#define OMAP4_VP_VDD_CORE_ID 0
+#define OMAP4_VP_VDD_IVA_ID 1
+#define OMAP4_VP_VDD_MPU_ID 2
+
+u32 omap_prm_vp_check_txdone(u8 vp_id);
+void omap_prm_vp_clear_txdone(u8 vp_id);
+
+#endif
+
+
+#endif
diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c
new file mode 100644
index 000000000..752018ce1
--- /dev/null
+++ b/arch/arm/mach-omap2/prm2xxx.c
@@ -0,0 +1,232 @@
+/*
+ * OMAP2xxx PRM module functions
+ *
+ * Copyright (C) 2010-2012 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ * Benoît Cousson
+ * 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 <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+
+#include "powerdomain.h"
+#include "clockdomain.h"
+#include "prm2xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "prm-regbits-24xx.h"
+
+/*
+ * OMAP24xx PM_PWSTCTRL_*.POWERSTATE and PM_PWSTST_*.LASTSTATEENTERED bits -
+ * these are reversed from the bits used on OMAP3+
+ */
+#define OMAP24XX_PWRDM_POWER_ON 0x0
+#define OMAP24XX_PWRDM_POWER_RET 0x1
+#define OMAP24XX_PWRDM_POWER_OFF 0x3
+
+/*
+ * omap2xxx_prm_reset_src_map - map from bits in the PRM_RSTST_WKUP
+ * hardware register (which are specific to the OMAP2xxx SoCs) to
+ * reset source ID bit shifts (which is an OMAP SoC-independent
+ * enumeration)
+ */
+static struct prm_reset_src_map omap2xxx_prm_reset_src_map[] = {
+ { OMAP_GLOBALCOLD_RST_SHIFT, OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT },
+ { OMAP_GLOBALWARM_RST_SHIFT, OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT },
+ { OMAP24XX_SECU_VIOL_RST_SHIFT, OMAP_SECU_VIOL_RST_SRC_ID_SHIFT },
+ { OMAP24XX_MPU_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
+ { OMAP24XX_SECU_WD_RST_SHIFT, OMAP_SECU_WD_RST_SRC_ID_SHIFT },
+ { OMAP24XX_EXTWMPU_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT },
+ { -1, -1 },
+};
+
+/**
+ * omap2xxx_prm_read_reset_sources - return the last SoC reset source
+ *
+ * Return a u32 representing the last reset sources of the SoC. The
+ * returned reset source bits are standardized across OMAP SoCs.
+ */
+static u32 omap2xxx_prm_read_reset_sources(void)
+{
+ struct prm_reset_src_map *p;
+ u32 r = 0;
+ u32 v;
+
+ v = omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST);
+
+ p = omap2xxx_prm_reset_src_map;
+ while (p->reg_shift >= 0 && p->std_shift >= 0) {
+ if (v & (1 << p->reg_shift))
+ r |= 1 << p->std_shift;
+ p++;
+ }
+
+ return r;
+}
+
+/**
+ * omap2xxx_pwrst_to_common_pwrst - convert OMAP2xxx pwrst to common pwrst
+ * @omap2xxx_pwrst: OMAP2xxx hardware power state to convert
+ *
+ * Return the common power state bits corresponding to the OMAP2xxx
+ * hardware power state bits @omap2xxx_pwrst, or -EINVAL upon error.
+ */
+static int omap2xxx_pwrst_to_common_pwrst(u8 omap2xxx_pwrst)
+{
+ u8 pwrst;
+
+ switch (omap2xxx_pwrst) {
+ case OMAP24XX_PWRDM_POWER_OFF:
+ pwrst = PWRDM_POWER_OFF;
+ break;
+ case OMAP24XX_PWRDM_POWER_RET:
+ pwrst = PWRDM_POWER_RET;
+ break;
+ case OMAP24XX_PWRDM_POWER_ON:
+ pwrst = PWRDM_POWER_ON;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return pwrst;
+}
+
+/**
+ * omap2xxx_prm_dpll_reset - use DPLL reset to reboot the OMAP SoC
+ *
+ * Set the DPLL reset bit, which should reboot the SoC. This is the
+ * recommended way to restart the SoC. No return value.
+ */
+static void omap2xxx_prm_dpll_reset(void)
+{
+ omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, WKUP_MOD,
+ OMAP2_RM_RSTCTRL);
+ /* OCP barrier */
+ omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTCTRL);
+}
+
+/**
+ * omap2xxx_prm_clear_mod_irqs - clear wakeup status bits for a module
+ * @module: PRM module to clear wakeups from
+ * @regs: register offset to clear
+ * @wkst_mask: wakeup status mask to clear
+ *
+ * Clears wakeup status bits for a given module, so that the device can
+ * re-enter idle.
+ */
+static int omap2xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 wkst_mask)
+{
+ u32 wkst;
+
+ wkst = omap2_prm_read_mod_reg(module, regs);
+ wkst &= wkst_mask;
+ omap2_prm_write_mod_reg(wkst, module, regs);
+ return 0;
+}
+
+int omap2xxx_clkdm_sleep(struct clockdomain *clkdm)
+{
+ omap2_prm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
+ clkdm->pwrdm.ptr->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+ return 0;
+}
+
+int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm)
+{
+ omap2_prm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
+ clkdm->pwrdm.ptr->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+ return 0;
+}
+
+static int omap2xxx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ u8 omap24xx_pwrst;
+
+ switch (pwrst) {
+ case PWRDM_POWER_OFF:
+ omap24xx_pwrst = OMAP24XX_PWRDM_POWER_OFF;
+ break;
+ case PWRDM_POWER_RET:
+ omap24xx_pwrst = OMAP24XX_PWRDM_POWER_RET;
+ break;
+ case PWRDM_POWER_ON:
+ omap24xx_pwrst = OMAP24XX_PWRDM_POWER_ON;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
+ (omap24xx_pwrst << OMAP_POWERSTATE_SHIFT),
+ pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
+ return 0;
+}
+
+static int omap2xxx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
+{
+ u8 omap2xxx_pwrst;
+
+ omap2xxx_pwrst = omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL,
+ OMAP_POWERSTATE_MASK);
+
+ return omap2xxx_pwrst_to_common_pwrst(omap2xxx_pwrst);
+}
+
+static int omap2xxx_pwrdm_read_pwrst(struct powerdomain *pwrdm)
+{
+ u8 omap2xxx_pwrst;
+
+ omap2xxx_pwrst = omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTST,
+ OMAP_POWERSTATEST_MASK);
+
+ return omap2xxx_pwrst_to_common_pwrst(omap2xxx_pwrst);
+}
+
+struct pwrdm_ops omap2_pwrdm_operations = {
+ .pwrdm_set_next_pwrst = omap2xxx_pwrdm_set_next_pwrst,
+ .pwrdm_read_next_pwrst = omap2xxx_pwrdm_read_next_pwrst,
+ .pwrdm_read_pwrst = omap2xxx_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,
+};
+
+/*
+ *
+ */
+
+static struct prm_ll_data omap2xxx_prm_ll_data = {
+ .read_reset_sources = &omap2xxx_prm_read_reset_sources,
+ .assert_hardreset = &omap2_prm_assert_hardreset,
+ .deassert_hardreset = &omap2_prm_deassert_hardreset,
+ .is_hardreset_asserted = &omap2_prm_is_hardreset_asserted,
+ .reset_system = &omap2xxx_prm_dpll_reset,
+ .clear_mod_irqs = &omap2xxx_prm_clear_mod_irqs,
+};
+
+int __init omap2xxx_prm_init(const struct omap_prcm_init_data *data)
+{
+ return prm_register(&omap2xxx_prm_ll_data);
+}
+
+static void __exit omap2xxx_prm_exit(void)
+{
+ prm_unregister(&omap2xxx_prm_ll_data);
+}
+__exitcall(omap2xxx_prm_exit);
diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h
new file mode 100644
index 000000000..9008a9e55
--- /dev/null
+++ b/arch/arm/mach-omap2/prm2xxx.h
@@ -0,0 +1,131 @@
+/*
+ * OMAP2xxx Power/Reset Management (PRM) register definitions
+ *
+ * Copyright (C) 2007-2009, 2011-2012 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_H
+#define __ARCH_ARM_MACH_OMAP2_PRM2XXX_H
+
+#include "prcm-common.h"
+#include "prm.h"
+#include "prm2xxx_3xxx.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))
+
+/*
+ * OMAP2-specific global PRM registers
+ * Use {read,write}l_relaxed() 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)
+
+/*
+ * 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
+
+#ifndef __ASSEMBLER__
+/* Function prototypes */
+extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm);
+extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm);
+
+int __init omap2xxx_prm_init(const struct omap_prcm_init_data *data);
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
new file mode 100644
index 000000000..cc3341f26
--- /dev/null
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -0,0 +1,240 @@
+/*
+ * OMAP2/3 PRM module functions
+ *
+ * Copyright (C) 2010-2011 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 "powerdomain.h"
+#include "prm2xxx_3xxx.h"
+#include "prm-regbits-24xx.h"
+#include "clockdomain.h"
+
+/**
+ * omap2_prm_is_hardreset_asserted - read the HW reset line state of
+ * submodules contained in the hwmod module
+ * @shift: register bit shift corresponding to the reset line to check
+ * @part: PRM partition, ignored for OMAP2
+ * @prm_mod: PRM submodule base (e.g. CORE_MOD)
+ * @offset: register offset, ignored for OMAP2
+ *
+ * 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(u8 shift, u8 part, s16 prm_mod, u16 offset)
+{
+ 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
+ * @shift: register bit shift corresponding to the reset line to assert
+ * @part: PRM partition, ignored for OMAP2
+ * @prm_mod: PRM submodule base (e.g. CORE_MOD)
+ * @offset: register offset, ignored for OMAP2
+ *
+ * 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(u8 shift, u8 part, s16 prm_mod, u16 offset)
+{
+ u32 mask;
+
+ 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
+ * @part: PRM partition, not used for OMAP2
+ * @prm_mod: PRM submodule base (e.g. CORE_MOD)
+ * @rst_offset: reset register offset, not used for OMAP2
+ * @st_offset: reset status register offset, not used for OMAP2
+ *
+ * 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(u8 rst_shift, u8 st_shift, u8 part,
+ s16 prm_mod, u16 rst_offset, u16 st_offset)
+{
+ u32 rst, st;
+ int c;
+
+ 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;
+}
+
+
+/* Powerdomain low-level functions */
+
+/* Common functions across OMAP2 and OMAP3 */
+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;
+}
+
+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;
+}
+
+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);
+}
+
+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);
+}
+
+int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ u32 v;
+
+ v = pwrst << __ffs(OMAP_LOGICRETSTATE_MASK);
+ omap2_prm_rmw_mod_reg_bits(OMAP_LOGICRETSTATE_MASK, v, pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+
+ return 0;
+}
+
+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) {
+ pr_err("powerdomain: %s: waited too long to complete transition\n",
+ pwrdm->name);
+ return -EAGAIN;
+ }
+
+ pr_debug("powerdomain: completed transition in %d loops\n", c);
+
+ return 0;
+}
+
+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;
+}
+
+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;
+}
+
+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));
+}
+
+/* XXX Caller must hold the clkdm's powerdomain lock */
+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 (!cd->clkdm)
+ continue; /* only happens if data is erroneous */
+
+ /* PRM accesses are slow, so minimize them */
+ mask |= 1 << cd->clkdm->dep_bit;
+ cd->wkdep_usecount = 0;
+ }
+
+ omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
+ PM_WKDEP);
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
new file mode 100644
index 000000000..f57e29b0e
--- /dev/null
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -0,0 +1,248 @@
+/*
+ * OMAP2xxx/3xxx-common Power/Reset Management (PRM) register definitions
+ *
+ * Copyright (C) 2007-2009, 2011-2012 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"
+
+/*
+ * 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
+
+
+#ifndef __ASSEMBLER__
+
+#include <linux/io.h>
+#include "powerdomain.h"
+
+/* Power/reset management domain register get/set */
+static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
+{
+ return readl_relaxed(prm_base + module + idx);
+}
+
+static inline void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx)
+{
+ writel_relaxed(val, prm_base + module + idx);
+}
+
+/* Read-modify-write a register in a PRM module. Caller must lock */
+static inline 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 */
+static inline 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;
+}
+
+static inline u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ return omap2_prm_rmw_mod_reg_bits(bits, bits, module, idx);
+}
+
+static inline u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ return omap2_prm_rmw_mod_reg_bits(bits, 0x0, module, idx);
+}
+
+/* These omap2_ PRM functions apply to both OMAP2 and 3 */
+int omap2_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset);
+int omap2_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod,
+ u16 offset);
+int omap2_prm_deassert_hardreset(u8 rst_shift, u8 st_shift, u8 part,
+ s16 prm_mod, u16 reset_offset,
+ u16 st_offset);
+
+extern int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
+extern int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
+extern int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm);
+extern int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst);
+extern int omap2_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst);
+extern int omap2_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
+extern int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank);
+extern int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst);
+extern int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm);
+
+extern int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2);
+extern int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2);
+extern int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2);
+extern int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm);
+
+#endif /* __ASSEMBLER */
+
+/*
+ * 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_SYSCLKDIV_WIDTH 2
+#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_SHIFT 1
+#define OMAP_GLOBALWARM_RST_MASK (1 << 1)
+#define OMAP_GLOBALCOLD_RST_SHIFT 0
+#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)
+
+
+#endif
diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c
new file mode 100644
index 000000000..dcb5001d7
--- /dev/null
+++ b/arch/arm/mach-omap2/prm33xx.c
@@ -0,0 +1,390 @@
+/*
+ * AM33XX PRM functions
+ *
+ * Copyright (C) 2011-2012 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 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/types.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include "powerdomain.h"
+#include "prm33xx.h"
+#include "prm-regbits-33xx.h"
+
+#define AM33XX_PRM_RSTCTRL_OFFSET 0x0000
+
+#define AM33XX_RST_GLOBAL_WARM_SW_MASK (1 << 0)
+
+/* Read a register in a PRM instance */
+static u32 am33xx_prm_read_reg(s16 inst, u16 idx)
+{
+ return readl_relaxed(prm_base + inst + idx);
+}
+
+/* Write into a register in a PRM instance */
+static void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx)
+{
+ writel_relaxed(val, prm_base + inst + idx);
+}
+
+/* Read-modify-write a register in PRM. Caller must lock */
+static u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx)
+{
+ u32 v;
+
+ v = am33xx_prm_read_reg(inst, idx);
+ v &= ~mask;
+ v |= bits;
+ am33xx_prm_write_reg(v, inst, idx);
+
+ return v;
+}
+
+/**
+ * am33xx_prm_is_hardreset_asserted - read the HW reset line state of
+ * submodules contained in the hwmod module
+ * @shift: register bit shift corresponding to the reset line to check
+ * @part: PRM partition, ignored for AM33xx
+ * @inst: CM instance register offset (*_INST macro)
+ * @rstctrl_offs: RM_RSTCTRL register address offset for this module
+ *
+ * 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.
+ */
+static int am33xx_prm_is_hardreset_asserted(u8 shift, u8 part, s16 inst,
+ u16 rstctrl_offs)
+{
+ u32 v;
+
+ v = am33xx_prm_read_reg(inst, rstctrl_offs);
+ v &= 1 << shift;
+ v >>= shift;
+
+ return v;
+}
+
+/**
+ * am33xx_prm_assert_hardreset - assert the HW reset line of a submodule
+ * @shift: register bit shift corresponding to the reset line to assert
+ * @part: CM partition, ignored for AM33xx
+ * @inst: CM instance register offset (*_INST macro)
+ * @rstctrl_reg: RM_RSTCTRL register address for this module
+ *
+ * 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.
+ */
+static int am33xx_prm_assert_hardreset(u8 shift, u8 part, s16 inst,
+ u16 rstctrl_offs)
+{
+ u32 mask = 1 << shift;
+
+ am33xx_prm_rmw_reg_bits(mask, mask, inst, rstctrl_offs);
+
+ return 0;
+}
+
+/**
+ * am33xx_prm_deassert_hardreset - deassert a submodule hardreset line and
+ * wait
+ * @shift: register bit shift corresponding to the reset line to deassert
+ * @st_shift: reset status register bit shift corresponding to the reset line
+ * @part: PRM partition, not used for AM33xx
+ * @inst: CM instance register offset (*_INST macro)
+ * @rstctrl_reg: RM_RSTCTRL register address for this module
+ * @rstst_reg: RM_RSTST register address for this module
+ *
+ * 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.
+ */
+static int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part,
+ s16 inst, u16 rstctrl_offs,
+ u16 rstst_offs)
+{
+ int c;
+ u32 mask = 1 << st_shift;
+
+ /* Check the current status to avoid de-asserting the line twice */
+ if (am33xx_prm_is_hardreset_asserted(shift, 0, inst, rstctrl_offs) == 0)
+ return -EEXIST;
+
+ /* Clear the reset status by writing 1 to the status bit */
+ am33xx_prm_rmw_reg_bits(0xffffffff, mask, inst, rstst_offs);
+
+ /* de-assert the reset control line */
+ mask = 1 << shift;
+
+ am33xx_prm_rmw_reg_bits(mask, 0, inst, rstctrl_offs);
+
+ /* wait the status to be set */
+ omap_test_timeout(am33xx_prm_is_hardreset_asserted(st_shift, 0, inst,
+ rstst_offs),
+ MAX_MODULE_HARDRESET_WAIT, c);
+
+ return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
+}
+
+static int am33xx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ am33xx_prm_rmw_reg_bits(OMAP_POWERSTATE_MASK,
+ (pwrst << OMAP_POWERSTATE_SHIFT),
+ pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
+ return 0;
+}
+
+static int am33xx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
+ v &= OMAP_POWERSTATE_MASK;
+ v >>= OMAP_POWERSTATE_SHIFT;
+
+ return v;
+}
+
+static int am33xx_pwrdm_read_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
+ v &= OMAP_POWERSTATEST_MASK;
+ v >>= OMAP_POWERSTATEST_SHIFT;
+
+ return v;
+}
+
+static int am33xx_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
+ v &= AM33XX_LASTPOWERSTATEENTERED_MASK;
+ v >>= AM33XX_LASTPOWERSTATEENTERED_SHIFT;
+
+ return v;
+}
+
+static int am33xx_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
+{
+ am33xx_prm_rmw_reg_bits(AM33XX_LOWPOWERSTATECHANGE_MASK,
+ (1 << AM33XX_LOWPOWERSTATECHANGE_SHIFT),
+ pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
+ return 0;
+}
+
+static int am33xx_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
+{
+ am33xx_prm_rmw_reg_bits(AM33XX_LASTPOWERSTATEENTERED_MASK,
+ AM33XX_LASTPOWERSTATEENTERED_MASK,
+ pwrdm->prcm_offs, pwrdm->pwrstst_offs);
+ return 0;
+}
+
+static int am33xx_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ u32 m;
+
+ m = pwrdm->logicretstate_mask;
+ if (!m)
+ return -EINVAL;
+
+ am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
+ pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
+
+ return 0;
+}
+
+static int am33xx_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
+ v &= AM33XX_LOGICSTATEST_MASK;
+ v >>= AM33XX_LOGICSTATEST_SHIFT;
+
+ return v;
+}
+
+static int am33xx_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
+{
+ u32 v, m;
+
+ m = pwrdm->logicretstate_mask;
+ if (!m)
+ return -EINVAL;
+
+ v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
+ v &= m;
+ v >>= __ffs(m);
+
+ return v;
+}
+
+static int am33xx_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst)
+{
+ u32 m;
+
+ m = pwrdm->mem_on_mask[bank];
+ if (!m)
+ return -EINVAL;
+
+ am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
+ pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
+
+ return 0;
+}
+
+static int am33xx_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst)
+{
+ u32 m;
+
+ m = pwrdm->mem_ret_mask[bank];
+ if (!m)
+ return -EINVAL;
+
+ am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
+ pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
+
+ return 0;
+}
+
+static int am33xx_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m, v;
+
+ m = pwrdm->mem_pwrst_mask[bank];
+ if (!m)
+ return -EINVAL;
+
+ v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
+ v &= m;
+ v >>= __ffs(m);
+
+ return v;
+}
+
+static int am33xx_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m, v;
+
+ m = pwrdm->mem_retst_mask[bank];
+ if (!m)
+ return -EINVAL;
+
+ v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
+ v &= m;
+ v >>= __ffs(m);
+
+ return v;
+}
+
+static int am33xx_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 ((am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs)
+ & OMAP_INTRANSITION_MASK) &&
+ (c++ < PWRDM_TRANSITION_BAILOUT))
+ udelay(1);
+
+ if (c > PWRDM_TRANSITION_BAILOUT) {
+ pr_err("powerdomain: %s: waited too long to complete transition\n",
+ pwrdm->name);
+ return -EAGAIN;
+ }
+
+ pr_debug("powerdomain: completed transition in %d loops\n", c);
+
+ return 0;
+}
+
+static int am33xx_check_vcvp(void)
+{
+ /* No VC/VP on am33xx devices */
+ return 0;
+}
+
+/**
+ * am33xx_prm_global_warm_sw_reset - reboot the device via warm reset
+ *
+ * Immediately reboots the device through warm reset.
+ */
+static void am33xx_prm_global_warm_sw_reset(void)
+{
+ am33xx_prm_rmw_reg_bits(AM33XX_RST_GLOBAL_WARM_SW_MASK,
+ AM33XX_RST_GLOBAL_WARM_SW_MASK,
+ AM33XX_PRM_DEVICE_MOD,
+ AM33XX_PRM_RSTCTRL_OFFSET);
+
+ /* OCP barrier */
+ (void)am33xx_prm_read_reg(AM33XX_PRM_DEVICE_MOD,
+ AM33XX_PRM_RSTCTRL_OFFSET);
+}
+
+struct pwrdm_ops am33xx_pwrdm_operations = {
+ .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst,
+ .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst,
+ .pwrdm_read_pwrst = am33xx_pwrdm_read_pwrst,
+ .pwrdm_read_prev_pwrst = am33xx_pwrdm_read_prev_pwrst,
+ .pwrdm_set_logic_retst = am33xx_pwrdm_set_logic_retst,
+ .pwrdm_read_logic_pwrst = am33xx_pwrdm_read_logic_pwrst,
+ .pwrdm_read_logic_retst = am33xx_pwrdm_read_logic_retst,
+ .pwrdm_clear_all_prev_pwrst = am33xx_pwrdm_clear_all_prev_pwrst,
+ .pwrdm_set_lowpwrstchange = am33xx_pwrdm_set_lowpwrstchange,
+ .pwrdm_read_mem_pwrst = am33xx_pwrdm_read_mem_pwrst,
+ .pwrdm_read_mem_retst = am33xx_pwrdm_read_mem_retst,
+ .pwrdm_set_mem_onst = am33xx_pwrdm_set_mem_onst,
+ .pwrdm_set_mem_retst = am33xx_pwrdm_set_mem_retst,
+ .pwrdm_wait_transition = am33xx_pwrdm_wait_transition,
+ .pwrdm_has_voltdm = am33xx_check_vcvp,
+};
+
+static struct prm_ll_data am33xx_prm_ll_data = {
+ .assert_hardreset = am33xx_prm_assert_hardreset,
+ .deassert_hardreset = am33xx_prm_deassert_hardreset,
+ .is_hardreset_asserted = am33xx_prm_is_hardreset_asserted,
+ .reset_system = am33xx_prm_global_warm_sw_reset,
+};
+
+int __init am33xx_prm_init(const struct omap_prcm_init_data *data)
+{
+ return prm_register(&am33xx_prm_ll_data);
+}
+
+static void __exit am33xx_prm_exit(void)
+{
+ prm_unregister(&am33xx_prm_ll_data);
+}
+__exitcall(am33xx_prm_exit);
diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h
new file mode 100644
index 000000000..2bc4ec52b
--- /dev/null
+++ b/arch/arm/mach-omap2/prm33xx.h
@@ -0,0 +1,124 @@
+/*
+ * AM33XX PRM instance offset macros
+ *
+ * Copyright (C) 2011-2012 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 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 __ARCH_ARM_MACH_OMAP2_PRM33XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM33XX_H
+
+#include "prcm-common.h"
+#include "prm.h"
+
+#define AM33XX_PRM_BASE 0x44E00000
+
+#define AM33XX_PRM_REGADDR(inst, reg) \
+ AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRM_BASE + (inst) + (reg))
+
+
+/* PRM instances */
+#define AM33XX_PRM_OCP_SOCKET_MOD 0x0B00
+#define AM33XX_PRM_PER_MOD 0x0C00
+#define AM33XX_PRM_WKUP_MOD 0x0D00
+#define AM33XX_PRM_MPU_MOD 0x0E00
+#define AM33XX_PRM_DEVICE_MOD 0x0F00
+#define AM33XX_PRM_RTC_MOD 0x1000
+#define AM33XX_PRM_GFX_MOD 0x1100
+#define AM33XX_PRM_CEFUSE_MOD 0x1200
+
+/* PRM */
+
+/* PRM.OCP_SOCKET_PRM register offsets */
+#define AM33XX_REVISION_PRM_OFFSET 0x0000
+#define AM33XX_REVISION_PRM AM33XX_PRM_REGADDR(AM33XX_PRM_OCP_SOCKET_MOD, 0x0000)
+#define AM33XX_PRM_IRQSTATUS_MPU_OFFSET 0x0004
+#define AM33XX_PRM_IRQSTATUS_MPU AM33XX_PRM_REGADDR(AM33XX_PRM_OCP_SOCKET_MOD, 0x0004)
+#define AM33XX_PRM_IRQENABLE_MPU_OFFSET 0x0008
+#define AM33XX_PRM_IRQENABLE_MPU AM33XX_PRM_REGADDR(AM33XX_PRM_OCP_SOCKET_MOD, 0x0008)
+#define AM33XX_PRM_IRQSTATUS_M3_OFFSET 0x000c
+#define AM33XX_PRM_IRQSTATUS_M3 AM33XX_PRM_REGADDR(AM33XX_PRM_OCP_SOCKET_MOD, 0x000c)
+#define AM33XX_PRM_IRQENABLE_M3_OFFSET 0x0010
+#define AM33XX_PRM_IRQENABLE_M3 AM33XX_PRM_REGADDR(AM33XX_PRM_OCP_SOCKET_MOD, 0x0010)
+
+/* PRM.PER_PRM register offsets */
+#define AM33XX_RM_PER_RSTCTRL_OFFSET 0x0000
+#define AM33XX_RM_PER_RSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x0000)
+#define AM33XX_RM_PER_RSTST_OFFSET 0x0004
+#define AM33XX_RM_PER_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x0004)
+#define AM33XX_PM_PER_PWRSTST_OFFSET 0x0008
+#define AM33XX_PM_PER_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x0008)
+#define AM33XX_PM_PER_PWRSTCTRL_OFFSET 0x000c
+#define AM33XX_PM_PER_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x000c)
+
+/* PRM.WKUP_PRM register offsets */
+#define AM33XX_RM_WKUP_RSTCTRL_OFFSET 0x0000
+#define AM33XX_RM_WKUP_RSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_WKUP_MOD, 0x0000)
+#define AM33XX_PM_WKUP_PWRSTCTRL_OFFSET 0x0004
+#define AM33XX_PM_WKUP_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_WKUP_MOD, 0x0004)
+#define AM33XX_PM_WKUP_PWRSTST_OFFSET 0x0008
+#define AM33XX_PM_WKUP_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_WKUP_MOD, 0x0008)
+#define AM33XX_RM_WKUP_RSTST_OFFSET 0x000c
+#define AM33XX_RM_WKUP_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_WKUP_MOD, 0x000c)
+
+/* PRM.MPU_PRM register offsets */
+#define AM33XX_PM_MPU_PWRSTCTRL_OFFSET 0x0000
+#define AM33XX_PM_MPU_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_MPU_MOD, 0x0000)
+#define AM33XX_PM_MPU_PWRSTST_OFFSET 0x0004
+#define AM33XX_PM_MPU_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_MPU_MOD, 0x0004)
+#define AM33XX_RM_MPU_RSTST_OFFSET 0x0008
+#define AM33XX_RM_MPU_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_MPU_MOD, 0x0008)
+
+/* PRM.DEVICE_PRM register offsets */
+#define AM33XX_PRM_RSTCTRL_OFFSET 0x0000
+#define AM33XX_PRM_RSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0000)
+#define AM33XX_PRM_RSTTIME_OFFSET 0x0004
+#define AM33XX_PRM_RSTTIME AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0004)
+#define AM33XX_PRM_RSTST_OFFSET 0x0008
+#define AM33XX_PRM_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0008)
+#define AM33XX_PRM_SRAM_COUNT_OFFSET 0x000c
+#define AM33XX_PRM_SRAM_COUNT AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x000c)
+#define AM33XX_PRM_LDO_SRAM_CORE_SETUP_OFFSET 0x0010
+#define AM33XX_PRM_LDO_SRAM_CORE_SETUP AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0010)
+#define AM33XX_PRM_LDO_SRAM_CORE_CTRL_OFFSET 0x0014
+#define AM33XX_PRM_LDO_SRAM_CORE_CTRL AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0014)
+#define AM33XX_PRM_LDO_SRAM_MPU_SETUP_OFFSET 0x0018
+#define AM33XX_PRM_LDO_SRAM_MPU_SETUP AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0018)
+#define AM33XX_PRM_LDO_SRAM_MPU_CTRL_OFFSET 0x001c
+#define AM33XX_PRM_LDO_SRAM_MPU_CTRL AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x001c)
+
+/* PRM.RTC_PRM register offsets */
+#define AM33XX_PM_RTC_PWRSTCTRL_OFFSET 0x0000
+#define AM33XX_PM_RTC_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_RTC_MOD, 0x0000)
+#define AM33XX_PM_RTC_PWRSTST_OFFSET 0x0004
+#define AM33XX_PM_RTC_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_RTC_MOD, 0x0004)
+
+/* PRM.GFX_PRM register offsets */
+#define AM33XX_PM_GFX_PWRSTCTRL_OFFSET 0x0000
+#define AM33XX_PM_GFX_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_GFX_MOD, 0x0000)
+#define AM33XX_RM_GFX_RSTCTRL_OFFSET 0x0004
+#define AM33XX_RM_GFX_RSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_GFX_MOD, 0x0004)
+#define AM33XX_PM_GFX_PWRSTST_OFFSET 0x0010
+#define AM33XX_PM_GFX_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_GFX_MOD, 0x0010)
+#define AM33XX_RM_GFX_RSTST_OFFSET 0x0014
+#define AM33XX_RM_GFX_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_GFX_MOD, 0x0014)
+
+/* PRM.CEFUSE_PRM register offsets */
+#define AM33XX_PM_CEFUSE_PWRSTCTRL_OFFSET 0x0000
+#define AM33XX_PM_CEFUSE_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0000)
+#define AM33XX_PM_CEFUSE_PWRSTST_OFFSET 0x0004
+#define AM33XX_PM_CEFUSE_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004)
+
+#ifndef __ASSEMBLER__
+int am33xx_prm_init(const struct omap_prcm_init_data *data);
+
+#endif /* ASSEMBLER */
+#endif
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c
new file mode 100644
index 000000000..62680aad2
--- /dev/null
+++ b/arch/arm/mach-omap2/prm3xxx.c
@@ -0,0 +1,727 @@
+/*
+ * OMAP3xxx PRM module functions
+ *
+ * Copyright (C) 2010-2012 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ * Benoît Cousson
+ * 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 <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of_irq.h>
+
+#include "soc.h"
+#include "common.h"
+#include "vp.h"
+#include "powerdomain.h"
+#include "prm3xxx.h"
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "prm-regbits-34xx.h"
+#include "cm3xxx.h"
+#include "cm-regbits-34xx.h"
+#include "clock.h"
+
+static void omap3xxx_prm_read_pending_irqs(unsigned long *events);
+static void omap3xxx_prm_ocp_barrier(void);
+static void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask);
+static void omap3xxx_prm_restore_irqen(u32 *saved_mask);
+
+static const struct omap_prcm_irq omap3_prcm_irqs[] = {
+ OMAP_PRCM_IRQ("wkup", 0, 0),
+ OMAP_PRCM_IRQ("io", 9, 1),
+};
+
+static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
+ .ack = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
+ .mask = OMAP3_PRM_IRQENABLE_MPU_OFFSET,
+ .nr_regs = 1,
+ .irqs = omap3_prcm_irqs,
+ .nr_irqs = ARRAY_SIZE(omap3_prcm_irqs),
+ .irq = 11 + OMAP_INTC_START,
+ .read_pending_irqs = &omap3xxx_prm_read_pending_irqs,
+ .ocp_barrier = &omap3xxx_prm_ocp_barrier,
+ .save_and_clear_irqen = &omap3xxx_prm_save_and_clear_irqen,
+ .restore_irqen = &omap3xxx_prm_restore_irqen,
+ .reconfigure_io_chain = NULL,
+};
+
+/*
+ * omap3_prm_reset_src_map - map from bits in the PRM_RSTST hardware
+ * register (which are specific to OMAP3xxx SoCs) to reset source ID
+ * bit shifts (which is an OMAP SoC-independent enumeration)
+ */
+static struct prm_reset_src_map omap3xxx_prm_reset_src_map[] = {
+ { OMAP3430_GLOBAL_COLD_RST_SHIFT, OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT },
+ { OMAP3430_GLOBAL_SW_RST_SHIFT, OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT },
+ { OMAP3430_SECURITY_VIOL_RST_SHIFT, OMAP_SECU_VIOL_RST_SRC_ID_SHIFT },
+ { OMAP3430_MPU_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
+ { OMAP3430_SECURE_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
+ { OMAP3430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT },
+ { OMAP3430_VDD1_VOLTAGE_MANAGER_RST_SHIFT,
+ OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT },
+ { OMAP3430_VDD2_VOLTAGE_MANAGER_RST_SHIFT,
+ OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT },
+ { OMAP3430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT },
+ { OMAP3430_ICECRUSHER_RST_SHIFT, OMAP_ICECRUSHER_RST_SRC_ID_SHIFT },
+ { -1, -1 },
+};
+
+/* PRM VP */
+
+/*
+ * struct omap3_vp - OMAP3 VP register access description.
+ * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
+ */
+struct omap3_vp {
+ u32 tranxdone_status;
+};
+
+static struct omap3_vp omap3_vp[] = {
+ [OMAP3_VP_VDD_MPU_ID] = {
+ .tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK,
+ },
+ [OMAP3_VP_VDD_CORE_ID] = {
+ .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK,
+ },
+};
+
+#define MAX_VP_ID ARRAY_SIZE(omap3_vp);
+
+static u32 omap3_prm_vp_check_txdone(u8 vp_id)
+{
+ struct omap3_vp *vp = &omap3_vp[vp_id];
+ u32 irqstatus;
+
+ irqstatus = omap2_prm_read_mod_reg(OCP_MOD,
+ OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+ return irqstatus & vp->tranxdone_status;
+}
+
+static void omap3_prm_vp_clear_txdone(u8 vp_id)
+{
+ struct omap3_vp *vp = &omap3_vp[vp_id];
+
+ omap2_prm_write_mod_reg(vp->tranxdone_status,
+ OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+}
+
+u32 omap3_prm_vcvp_read(u8 offset)
+{
+ return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, offset);
+}
+
+void omap3_prm_vcvp_write(u32 val, u8 offset)
+{
+ omap2_prm_write_mod_reg(val, OMAP3430_GR_MOD, offset);
+}
+
+u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
+{
+ return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset);
+}
+
+/**
+ * omap3xxx_prm_dpll3_reset - use DPLL3 reset to reboot the OMAP SoC
+ *
+ * Set the DPLL3 reset bit, which should reboot the SoC. This is the
+ * recommended way to restart the SoC, considering Errata i520. No
+ * return value.
+ */
+static void omap3xxx_prm_dpll3_reset(void)
+{
+ omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, OMAP3430_GR_MOD,
+ OMAP2_RM_RSTCTRL);
+ /* OCP barrier */
+ omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP2_RM_RSTCTRL);
+}
+
+/**
+ * omap3xxx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events
+ * @events: ptr to a u32, preallocated by caller
+ *
+ * Read PRM_IRQSTATUS_MPU bits, AND'ed with the currently-enabled PRM
+ * MPU IRQs, and store the result into the u32 pointed to by @events.
+ * No return value.
+ */
+static void omap3xxx_prm_read_pending_irqs(unsigned long *events)
+{
+ u32 mask, st;
+
+ /* XXX Can the mask read be avoided (e.g., can it come from RAM?) */
+ mask = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
+ st = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+
+ events[0] = mask & st;
+}
+
+/**
+ * omap3xxx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete
+ *
+ * Force any buffered writes to the PRM IP block to complete. Needed
+ * by the PRM IRQ handler, which reads and writes directly to the IP
+ * block, to avoid race conditions after acknowledging or clearing IRQ
+ * bits. No return value.
+ */
+static void omap3xxx_prm_ocp_barrier(void)
+{
+ omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
+}
+
+/**
+ * omap3xxx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU reg
+ * @saved_mask: ptr to a u32 array to save IRQENABLE bits
+ *
+ * Save the PRM_IRQENABLE_MPU register to @saved_mask. @saved_mask
+ * must be allocated by the caller. Intended to be used in the PRM
+ * interrupt handler suspend callback. The OCP barrier is needed to
+ * ensure the write to disable PRM interrupts reaches the PRM before
+ * returning; otherwise, spurious interrupts might occur. No return
+ * value.
+ */
+static void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask)
+{
+ saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD,
+ OMAP3_PRM_IRQENABLE_MPU_OFFSET);
+ omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
+
+ /* OCP barrier */
+ omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
+}
+
+/**
+ * omap3xxx_prm_restore_irqen - set PRM_IRQENABLE_MPU register from args
+ * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously
+ *
+ * Restore the PRM_IRQENABLE_MPU register from @saved_mask. Intended
+ * to be used in the PRM interrupt handler resume callback to restore
+ * values saved by omap3xxx_prm_save_and_clear_irqen(). No OCP
+ * barrier should be needed here; any pending PRM interrupts will fire
+ * once the writes reach the PRM. No return value.
+ */
+static void omap3xxx_prm_restore_irqen(u32 *saved_mask)
+{
+ omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD,
+ OMAP3_PRM_IRQENABLE_MPU_OFFSET);
+}
+
+/**
+ * omap3xxx_prm_clear_mod_irqs - clear wake-up events from PRCM interrupt
+ * @module: PRM module to clear wakeups from
+ * @regs: register set to clear, 1 or 3
+ * @wkst_mask: wkst bits to clear
+ *
+ * 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 omap3xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 wkst_mask)
+{
+ 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);
+ wkst &= wkst_mask;
+ 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);
+ wkst &= wkst_mask;
+ c++;
+ }
+ omap2_cm_write_mod_reg(iclk, module, iclk_off);
+ omap2_cm_write_mod_reg(fclk, module, fclk_off);
+ }
+
+ return c;
+}
+
+/**
+ * omap3_prm_reset_modem - toggle reset signal for modem
+ *
+ * Toggles the reset signal to modem IP block. Required to allow
+ * OMAP3430 without stacked modem to idle properly.
+ */
+void __init omap3_prm_reset_modem(void)
+{
+ 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);
+}
+
+/**
+ * omap3_prm_init_pm - initialize PM related registers for PRM
+ * @has_uart4: SoC has UART4
+ * @has_iva: SoC has IVA
+ *
+ * Initializes PRM registers for PM use. Called from PM init.
+ */
+void __init omap3_prm_init_pm(bool has_uart4, bool has_iva)
+{
+ u32 en_uart4_mask;
+ u32 grpsel_uart4_mask;
+
+ /*
+ * 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);
+
+ /* Enable PM_WKEN to support DSS LPR */
+ omap2_prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK,
+ OMAP3430_DSS_MOD, PM_WKEN);
+
+ if (has_uart4) {
+ en_uart4_mask = OMAP3630_EN_UART4_MASK;
+ grpsel_uart4_mask = OMAP3630_GRPSEL_UART4_MASK;
+ }
+
+ /* Enable wakeups in PER */
+ omap2_prm_write_mod_reg(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(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 */
+ if (has_iva) {
+ 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);
+
+ /* We need to idle iva2_pwrdm even on am3703 with no iva2. */
+ omap3xxx_prm_iva_idle();
+
+ omap3_prm_reset_modem();
+}
+
+/**
+ * omap3430_pre_es3_1_reconfigure_io_chain - restart wake-up daisy chain
+ *
+ * The ST_IO_CHAIN bit does not exist in 3430 before es3.1. The only
+ * thing we can do is toggle EN_IO bit for earlier omaps.
+ */
+static void omap3430_pre_es3_1_reconfigure_io_chain(void)
+{
+ omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
+ PM_WKEN);
+ omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
+ PM_WKEN);
+ omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
+}
+
+/**
+ * omap3_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
+ *
+ * Clear any previously-latched I/O wakeup events and ensure that the
+ * I/O wakeup gates are aligned with the current mux settings. Works
+ * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
+ * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No
+ * return value. These registers are only available in 3430 es3.1 and later.
+ */
+static void omap3_prm_reconfigure_io_chain(void)
+{
+ int i = 0;
+
+ omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+ PM_WKEN);
+
+ omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
+ OMAP3430_ST_IO_CHAIN_MASK,
+ MAX_IOPAD_LATCH_TIME, i);
+ if (i == MAX_IOPAD_LATCH_TIME)
+ pr_warn("PRM: I/O chain clock line assertion timed out\n");
+
+ omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+ PM_WKEN);
+
+ omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
+ PM_WKST);
+
+ omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
+}
+
+/**
+ * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
+ *
+ * Activates the I/O wakeup event latches and allows events logged by
+ * those latches to signal a wakeup event to the PRCM. For I/O
+ * wakeups to occur, WAKEUPENABLE bits must be set in the pad mux
+ * registers, and omap3xxx_prm_reconfigure_io_chain() must be called.
+ * No return value.
+ */
+static void __init omap3xxx_prm_enable_io_wakeup(void)
+{
+ if (prm_features & PRM_HAS_IO_WAKEUP)
+ omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
+ PM_WKEN);
+}
+
+/**
+ * omap3xxx_prm_read_reset_sources - return the last SoC reset source
+ *
+ * Return a u32 representing the last reset sources of the SoC. The
+ * returned reset source bits are standardized across OMAP SoCs.
+ */
+static u32 omap3xxx_prm_read_reset_sources(void)
+{
+ struct prm_reset_src_map *p;
+ u32 r = 0;
+ u32 v;
+
+ v = omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST);
+
+ p = omap3xxx_prm_reset_src_map;
+ while (p->reg_shift >= 0 && p->std_shift >= 0) {
+ if (v & (1 << p->reg_shift))
+ r |= 1 << p->std_shift;
+ p++;
+ }
+
+ return r;
+}
+
+/**
+ * omap3xxx_prm_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.
+ */
+void omap3xxx_prm_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);
+
+ /* 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);
+}
+
+/**
+ * omap3xxx_prm_clear_global_cold_reset - checks the global cold reset status
+ * and clears it if asserted
+ *
+ * Checks if cold-reset has occurred and clears the status bit if yes. Returns
+ * 1 if cold-reset has occurred, 0 otherwise.
+ */
+int omap3xxx_prm_clear_global_cold_reset(void)
+{
+ if (omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) &
+ OMAP3430_GLOBAL_COLD_RST_MASK) {
+ omap2_prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST_MASK,
+ OMAP3430_GR_MOD,
+ OMAP3_PRM_RSTST_OFFSET);
+ return 1;
+ }
+
+ return 0;
+}
+
+void omap3_prm_save_scratchpad_contents(u32 *ptr)
+{
+ *ptr++ = omap2_prm_read_mod_reg(OMAP3430_GR_MOD,
+ OMAP3_PRM_CLKSRC_CTRL_OFFSET);
+
+ *ptr++ = omap2_prm_read_mod_reg(OMAP3430_GR_MOD,
+ OMAP3_PRM_CLKSEL_OFFSET);
+}
+
+/* Powerdomain low-level functions */
+
+static int omap3_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 omap3_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 omap3_pwrdm_read_pwrst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTST,
+ OMAP_POWERSTATEST_MASK);
+}
+
+/* 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 omap3_pwrdm_operations = {
+ .pwrdm_set_next_pwrst = omap3_pwrdm_set_next_pwrst,
+ .pwrdm_read_next_pwrst = omap3_pwrdm_read_next_pwrst,
+ .pwrdm_read_pwrst = omap3_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,
+};
+
+/*
+ *
+ */
+
+static int omap3xxx_prm_late_init(void);
+
+static struct prm_ll_data omap3xxx_prm_ll_data = {
+ .read_reset_sources = &omap3xxx_prm_read_reset_sources,
+ .late_init = &omap3xxx_prm_late_init,
+ .assert_hardreset = &omap2_prm_assert_hardreset,
+ .deassert_hardreset = &omap2_prm_deassert_hardreset,
+ .is_hardreset_asserted = &omap2_prm_is_hardreset_asserted,
+ .reset_system = &omap3xxx_prm_dpll3_reset,
+ .clear_mod_irqs = &omap3xxx_prm_clear_mod_irqs,
+ .vp_check_txdone = &omap3_prm_vp_check_txdone,
+ .vp_clear_txdone = &omap3_prm_vp_clear_txdone,
+};
+
+int __init omap3xxx_prm_init(const struct omap_prcm_init_data *data)
+{
+ omap2_clk_legacy_provider_init(TI_CLKM_PRM,
+ prm_base + OMAP3430_IVA2_MOD);
+ if (omap3_has_io_wakeup())
+ prm_features |= PRM_HAS_IO_WAKEUP;
+
+ return prm_register(&omap3xxx_prm_ll_data);
+}
+
+static const struct of_device_id omap3_prm_dt_match_table[] = {
+ { .compatible = "ti,omap3-prm" },
+ { }
+};
+
+static int omap3xxx_prm_late_init(void)
+{
+ int ret;
+
+ if (!(prm_features & PRM_HAS_IO_WAKEUP))
+ return 0;
+
+ if (omap3_has_io_chain_ctrl())
+ omap3_prcm_irq_setup.reconfigure_io_chain =
+ omap3_prm_reconfigure_io_chain;
+ else
+ omap3_prcm_irq_setup.reconfigure_io_chain =
+ omap3430_pre_es3_1_reconfigure_io_chain;
+
+ if (of_have_populated_dt()) {
+ struct device_node *np;
+ int irq_num;
+
+ np = of_find_matching_node(NULL, omap3_prm_dt_match_table);
+ if (np) {
+ irq_num = of_irq_get(np, 0);
+ if (irq_num >= 0)
+ omap3_prcm_irq_setup.irq = irq_num;
+ }
+ }
+
+ omap3xxx_prm_enable_io_wakeup();
+ ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
+ if (!ret)
+ irq_set_status_flags(omap_prcm_event_to_irq("io"),
+ IRQ_NOAUTOEN);
+
+ return ret;
+}
+
+static void __exit omap3xxx_prm_exit(void)
+{
+ prm_unregister(&omap3xxx_prm_ll_data);
+}
+__exitcall(omap3xxx_prm_exit);
diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h
new file mode 100644
index 000000000..5f095eec3
--- /dev/null
+++ b/arch/arm/mach-omap2/prm3xxx.h
@@ -0,0 +1,153 @@
+/*
+ * OMAP3xxx Power/Reset Management (PRM) register definitions
+ *
+ * Copyright (C) 2007-2009, 2011-2012 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_PRM3XXX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM3XXX_H
+
+#include "prcm-common.h"
+#include "prm.h"
+#include "prm2xxx_3xxx.h"
+
+#define OMAP34XX_PRM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg))
+
+
+/*
+ * OMAP3-specific global PRM registers
+ * Use {read,write}l_relaxed() 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)
+
+/* 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__
+
+/*
+ * OMAP3 access functions for voltage controller (VC) and
+ * voltage proccessor (VP) in the PRM.
+ */
+extern u32 omap3_prm_vcvp_read(u8 offset);
+extern void omap3_prm_vcvp_write(u32 val, u8 offset);
+extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
+
+int __init omap3xxx_prm_init(const struct omap_prcm_init_data *data);
+void omap3xxx_prm_iva_idle(void);
+void omap3_prm_reset_modem(void);
+int omap3xxx_prm_clear_global_cold_reset(void);
+void omap3_prm_save_scratchpad_contents(u32 *ptr);
+void omap3_prm_init_pm(bool has_uart4, bool has_iva);
+
+#endif /* __ASSEMBLER */
+
+
+#endif
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
new file mode 100644
index 000000000..4541700f7
--- /dev/null
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -0,0 +1,764 @@
+/*
+ * OMAP4 PRM module functions
+ *
+ * Copyright (C) 2011-2012 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ * Benoît Cousson
+ * 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 <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of_irq.h>
+
+
+#include "soc.h"
+#include "iomap.h"
+#include "common.h"
+#include "vp.h"
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
+#include "prcm44xx.h"
+#include "prminst44xx.h"
+#include "powerdomain.h"
+
+/* Static data */
+
+static void omap44xx_prm_read_pending_irqs(unsigned long *events);
+static void omap44xx_prm_ocp_barrier(void);
+static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
+static void omap44xx_prm_restore_irqen(u32 *saved_mask);
+static void omap44xx_prm_reconfigure_io_chain(void);
+
+static const struct omap_prcm_irq omap4_prcm_irqs[] = {
+ OMAP_PRCM_IRQ("io", 9, 1),
+};
+
+static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
+ .ack = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
+ .mask = OMAP4_PRM_IRQENABLE_MPU_OFFSET,
+ .nr_regs = 2,
+ .irqs = omap4_prcm_irqs,
+ .nr_irqs = ARRAY_SIZE(omap4_prcm_irqs),
+ .irq = 11 + OMAP44XX_IRQ_GIC_START,
+ .xlate_irq = omap4_xlate_irq,
+ .read_pending_irqs = &omap44xx_prm_read_pending_irqs,
+ .ocp_barrier = &omap44xx_prm_ocp_barrier,
+ .save_and_clear_irqen = &omap44xx_prm_save_and_clear_irqen,
+ .restore_irqen = &omap44xx_prm_restore_irqen,
+ .reconfigure_io_chain = &omap44xx_prm_reconfigure_io_chain,
+};
+
+/*
+ * omap44xx_prm_reset_src_map - map from bits in the PRM_RSTST
+ * hardware register (which are specific to OMAP44xx SoCs) to reset
+ * source ID bit shifts (which is an OMAP SoC-independent
+ * enumeration)
+ */
+static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = {
+ { OMAP4430_GLOBAL_WARM_SW_RST_SHIFT,
+ OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT },
+ { OMAP4430_GLOBAL_COLD_RST_SHIFT,
+ OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT },
+ { OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT,
+ OMAP_SECU_VIOL_RST_SRC_ID_SHIFT },
+ { OMAP4430_MPU_WDT_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
+ { OMAP4430_SECURE_WDT_RST_SHIFT, OMAP_SECU_WD_RST_SRC_ID_SHIFT },
+ { OMAP4430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT },
+ { OMAP4430_VDD_MPU_VOLT_MGR_RST_SHIFT,
+ OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT },
+ { OMAP4430_VDD_IVA_VOLT_MGR_RST_SHIFT,
+ OMAP_VDD_IVA_VM_RST_SRC_ID_SHIFT },
+ { OMAP4430_VDD_CORE_VOLT_MGR_RST_SHIFT,
+ OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT },
+ { OMAP4430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT },
+ { OMAP4430_C2C_RST_SHIFT, OMAP_C2C_RST_SRC_ID_SHIFT },
+ { -1, -1 },
+};
+
+/* PRM low-level functions */
+
+/* Read a register in a CM/PRM instance in the PRM module */
+static u32 omap4_prm_read_inst_reg(s16 inst, u16 reg)
+{
+ return readl_relaxed(prm_base + inst + reg);
+}
+
+/* Write into a register in a CM/PRM instance in the PRM module */
+static void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg)
+{
+ writel_relaxed(val, prm_base + inst + reg);
+}
+
+/* Read-modify-write a register in a PRM module. Caller must lock */
+static 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;
+}
+
+/* PRM VP */
+
+/*
+ * struct omap4_vp - OMAP4 VP register access description.
+ * @irqstatus_mpu: offset to IRQSTATUS_MPU register for VP
+ * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
+ */
+struct omap4_vp {
+ u32 irqstatus_mpu;
+ u32 tranxdone_status;
+};
+
+static struct omap4_vp omap4_vp[] = {
+ [OMAP4_VP_VDD_MPU_ID] = {
+ .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET,
+ .tranxdone_status = OMAP4430_VP_MPU_TRANXDONE_ST_MASK,
+ },
+ [OMAP4_VP_VDD_IVA_ID] = {
+ .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
+ .tranxdone_status = OMAP4430_VP_IVA_TRANXDONE_ST_MASK,
+ },
+ [OMAP4_VP_VDD_CORE_ID] = {
+ .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
+ .tranxdone_status = OMAP4430_VP_CORE_TRANXDONE_ST_MASK,
+ },
+};
+
+static u32 omap4_prm_vp_check_txdone(u8 vp_id)
+{
+ struct omap4_vp *vp = &omap4_vp[vp_id];
+ u32 irqstatus;
+
+ irqstatus = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_OCP_SOCKET_INST,
+ vp->irqstatus_mpu);
+ return irqstatus & vp->tranxdone_status;
+}
+
+static void omap4_prm_vp_clear_txdone(u8 vp_id)
+{
+ struct omap4_vp *vp = &omap4_vp[vp_id];
+
+ omap4_prminst_write_inst_reg(vp->tranxdone_status,
+ OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_OCP_SOCKET_INST,
+ vp->irqstatus_mpu);
+};
+
+u32 omap4_prm_vcvp_read(u8 offset)
+{
+ s32 inst = omap4_prmst_get_prm_dev_inst();
+
+ if (inst == PRM_INSTANCE_UNKNOWN)
+ return 0;
+
+ return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+ inst, offset);
+}
+
+void omap4_prm_vcvp_write(u32 val, u8 offset)
+{
+ s32 inst = omap4_prmst_get_prm_dev_inst();
+
+ if (inst == PRM_INSTANCE_UNKNOWN)
+ return;
+
+ omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION,
+ inst, offset);
+}
+
+u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
+{
+ s32 inst = omap4_prmst_get_prm_dev_inst();
+
+ if (inst == PRM_INSTANCE_UNKNOWN)
+ return 0;
+
+ return omap4_prminst_rmw_inst_reg_bits(mask, bits,
+ OMAP4430_PRM_PARTITION,
+ inst,
+ offset);
+}
+
+static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs)
+{
+ u32 mask, st;
+
+ /* XXX read mask from RAM? */
+ mask = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
+ irqen_offs);
+ st = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, irqst_offs);
+
+ return mask & st;
+}
+
+/**
+ * omap44xx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events
+ * @events: ptr to two consecutive u32s, preallocated by caller
+ *
+ * Read PRM_IRQSTATUS_MPU* bits, AND'ed with the currently-enabled PRM
+ * MPU IRQs, and store the result into the two u32s pointed to by @events.
+ * No return value.
+ */
+static void omap44xx_prm_read_pending_irqs(unsigned long *events)
+{
+ events[0] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_OFFSET,
+ OMAP4_PRM_IRQSTATUS_MPU_OFFSET);
+
+ events[1] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_2_OFFSET,
+ OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET);
+}
+
+/**
+ * omap44xx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete
+ *
+ * Force any buffered writes to the PRM IP block to complete. Needed
+ * by the PRM IRQ handler, which reads and writes directly to the IP
+ * block, to avoid race conditions after acknowledging or clearing IRQ
+ * bits. No return value.
+ */
+static void omap44xx_prm_ocp_barrier(void)
+{
+ omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
+ OMAP4_REVISION_PRM_OFFSET);
+}
+
+/**
+ * omap44xx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU* regs
+ * @saved_mask: ptr to a u32 array to save IRQENABLE bits
+ *
+ * Save the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers to
+ * @saved_mask. @saved_mask must be allocated by the caller.
+ * Intended to be used in the PRM interrupt handler suspend callback.
+ * The OCP barrier is needed to ensure the write to disable PRM
+ * interrupts reaches the PRM before returning; otherwise, spurious
+ * interrupts might occur. No return value.
+ */
+static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask)
+{
+ saved_mask[0] =
+ omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
+ OMAP4_PRM_IRQENABLE_MPU_OFFSET);
+ saved_mask[1] =
+ omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
+ OMAP4_PRM_IRQENABLE_MPU_2_OFFSET);
+
+ omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST,
+ OMAP4_PRM_IRQENABLE_MPU_OFFSET);
+ omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST,
+ OMAP4_PRM_IRQENABLE_MPU_2_OFFSET);
+
+ /* OCP barrier */
+ omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
+ OMAP4_REVISION_PRM_OFFSET);
+}
+
+/**
+ * omap44xx_prm_restore_irqen - set PRM_IRQENABLE_MPU* registers from args
+ * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously
+ *
+ * Restore the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers from
+ * @saved_mask. Intended to be used in the PRM interrupt handler resume
+ * callback to restore values saved by omap44xx_prm_save_and_clear_irqen().
+ * No OCP barrier should be needed here; any pending PRM interrupts will fire
+ * once the writes reach the PRM. No return value.
+ */
+static void omap44xx_prm_restore_irqen(u32 *saved_mask)
+{
+ omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_OCP_SOCKET_INST,
+ OMAP4_PRM_IRQENABLE_MPU_OFFSET);
+ omap4_prm_write_inst_reg(saved_mask[1], OMAP4430_PRM_OCP_SOCKET_INST,
+ OMAP4_PRM_IRQENABLE_MPU_2_OFFSET);
+}
+
+/**
+ * omap44xx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
+ *
+ * Clear any previously-latched I/O wakeup events and ensure that the
+ * I/O wakeup gates are aligned with the current mux settings. Works
+ * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
+ * deasserting WUCLKIN and waiting for WUCLKOUT to be deasserted.
+ * No return value. XXX Are the final two steps necessary?
+ */
+static void omap44xx_prm_reconfigure_io_chain(void)
+{
+ int i = 0;
+ s32 inst = omap4_prmst_get_prm_dev_inst();
+
+ if (inst == PRM_INSTANCE_UNKNOWN)
+ return;
+
+ /* Trigger WUCLKIN enable */
+ omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK,
+ OMAP4430_WUCLK_CTRL_MASK,
+ inst,
+ OMAP4_PRM_IO_PMCTRL_OFFSET);
+ omap_test_timeout(
+ (((omap4_prm_read_inst_reg(inst,
+ OMAP4_PRM_IO_PMCTRL_OFFSET) &
+ OMAP4430_WUCLK_STATUS_MASK) >>
+ OMAP4430_WUCLK_STATUS_SHIFT) == 1),
+ MAX_IOPAD_LATCH_TIME, i);
+ if (i == MAX_IOPAD_LATCH_TIME)
+ pr_warn("PRM: I/O chain clock line assertion timed out\n");
+
+ /* Trigger WUCLKIN disable */
+ omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 0x0,
+ inst,
+ OMAP4_PRM_IO_PMCTRL_OFFSET);
+ omap_test_timeout(
+ (((omap4_prm_read_inst_reg(inst,
+ OMAP4_PRM_IO_PMCTRL_OFFSET) &
+ OMAP4430_WUCLK_STATUS_MASK) >>
+ OMAP4430_WUCLK_STATUS_SHIFT) == 0),
+ MAX_IOPAD_LATCH_TIME, i);
+ if (i == MAX_IOPAD_LATCH_TIME)
+ pr_warn("PRM: I/O chain clock line deassertion timed out\n");
+
+ return;
+}
+
+/**
+ * omap44xx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
+ *
+ * Activates the I/O wakeup event latches and allows events logged by
+ * those latches to signal a wakeup event to the PRCM. For I/O wakeups
+ * to occur, WAKEUPENABLE bits must be set in the pad mux registers, and
+ * omap44xx_prm_reconfigure_io_chain() must be called. No return value.
+ */
+static void __init omap44xx_prm_enable_io_wakeup(void)
+{
+ s32 inst = omap4_prmst_get_prm_dev_inst();
+
+ if (inst == PRM_INSTANCE_UNKNOWN)
+ return;
+
+ omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
+ OMAP4430_GLOBAL_WUEN_MASK,
+ inst,
+ OMAP4_PRM_IO_PMCTRL_OFFSET);
+}
+
+/**
+ * omap44xx_prm_read_reset_sources - return the last SoC reset source
+ *
+ * Return a u32 representing the last reset sources of the SoC. The
+ * returned reset source bits are standardized across OMAP SoCs.
+ */
+static u32 omap44xx_prm_read_reset_sources(void)
+{
+ struct prm_reset_src_map *p;
+ u32 r = 0;
+ u32 v;
+ s32 inst = omap4_prmst_get_prm_dev_inst();
+
+ if (inst == PRM_INSTANCE_UNKNOWN)
+ return 0;
+
+
+ v = omap4_prm_read_inst_reg(inst,
+ OMAP4_RM_RSTST);
+
+ p = omap44xx_prm_reset_src_map;
+ while (p->reg_shift >= 0 && p->std_shift >= 0) {
+ if (v & (1 << p->reg_shift))
+ r |= 1 << p->std_shift;
+ p++;
+ }
+
+ return r;
+}
+
+/**
+ * omap44xx_prm_was_any_context_lost_old - was module hardware context lost?
+ * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
+ * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
+ * @idx: CONTEXT register offset
+ *
+ * Return 1 if any bits were set in the *_CONTEXT_* register
+ * identified by (@part, @inst, @idx), which means that some context
+ * was lost for that module; otherwise, return 0.
+ */
+static bool omap44xx_prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
+{
+ return (omap4_prminst_read_inst_reg(part, inst, idx)) ? 1 : 0;
+}
+
+/**
+ * omap44xx_prm_clear_context_lost_flags_old - clear context loss flags
+ * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
+ * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
+ * @idx: CONTEXT register offset
+ *
+ * Clear hardware context loss bits for the module identified by
+ * (@part, @inst, @idx). No return value. XXX Writes to reserved bits;
+ * is there a way to avoid this?
+ */
+static void omap44xx_prm_clear_context_loss_flags_old(u8 part, s16 inst,
+ u16 idx)
+{
+ omap4_prminst_write_inst_reg(0xffffffff, part, inst, idx);
+}
+
+/* Powerdomain low-level functions */
+
+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;
+}
+
+/**
+ * omap4_pwrdm_read_prev_logic_pwrst - read the previous logic powerstate
+ * @pwrdm: struct powerdomain * to read the state for
+ *
+ * Reads the previous logic powerstate for a powerdomain. This
+ * function must determine the previous logic powerstate by first
+ * checking the previous powerstate for the domain. If that was OFF,
+ * then logic has been lost. If previous state was RETENTION, the
+ * function reads the setting for the next retention logic state to
+ * see the actual value. In every other case, the logic is
+ * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
+ * depending whether the logic was retained or not.
+ */
+static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
+{
+ int state;
+
+ state = omap4_pwrdm_read_prev_pwrst(pwrdm);
+
+ if (state == PWRDM_POWER_OFF)
+ return PWRDM_POWER_OFF;
+
+ if (state != PWRDM_POWER_RET)
+ return PWRDM_POWER_RET;
+
+ return omap4_pwrdm_read_logic_retst(pwrdm);
+}
+
+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;
+}
+
+/**
+ * omap4_pwrdm_read_prev_mem_pwrst - reads the previous memory powerstate
+ * @pwrdm: struct powerdomain * to read mem powerstate for
+ * @bank: memory bank index
+ *
+ * Reads the previous memory powerstate for a powerdomain. This
+ * function must determine the previous memory powerstate by first
+ * checking the previous powerstate for the domain. If that was OFF,
+ * then logic has been lost. If previous state was RETENTION, the
+ * function reads the setting for the next memory retention state to
+ * see the actual value. In every other case, the logic is
+ * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
+ * depending whether logic was retained or not.
+ */
+static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ int state;
+
+ state = omap4_pwrdm_read_prev_pwrst(pwrdm);
+
+ if (state == PWRDM_POWER_OFF)
+ return PWRDM_POWER_OFF;
+
+ if (state != PWRDM_POWER_RET)
+ return PWRDM_POWER_RET;
+
+ return omap4_pwrdm_read_mem_retst(pwrdm, bank);
+}
+
+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) {
+ pr_err("powerdomain: %s: waited too long to complete transition\n",
+ pwrdm->name);
+ return -EAGAIN;
+ }
+
+ pr_debug("powerdomain: completed transition in %d loops\n", c);
+
+ return 0;
+}
+
+static int omap4_check_vcvp(void)
+{
+ if (prm_features & PRM_HAS_VOLTAGE)
+ return 1;
+
+ 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_prev_logic_pwrst = omap4_pwrdm_read_prev_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_read_prev_mem_pwrst = omap4_pwrdm_read_prev_mem_pwrst,
+ .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,
+ .pwrdm_has_voltdm = omap4_check_vcvp,
+};
+
+static int omap44xx_prm_late_init(void);
+
+/*
+ * XXX document
+ */
+static struct prm_ll_data omap44xx_prm_ll_data = {
+ .read_reset_sources = &omap44xx_prm_read_reset_sources,
+ .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old,
+ .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old,
+ .late_init = &omap44xx_prm_late_init,
+ .assert_hardreset = omap4_prminst_assert_hardreset,
+ .deassert_hardreset = omap4_prminst_deassert_hardreset,
+ .is_hardreset_asserted = omap4_prminst_is_hardreset_asserted,
+ .reset_system = omap4_prminst_global_warm_sw_reset,
+ .vp_check_txdone = omap4_prm_vp_check_txdone,
+ .vp_clear_txdone = omap4_prm_vp_clear_txdone,
+};
+
+static const struct omap_prcm_init_data *prm_init_data;
+
+int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
+{
+ omap_prm_base_init();
+
+ prm_init_data = data;
+
+ if (data->flags & PRM_HAS_IO_WAKEUP)
+ prm_features |= PRM_HAS_IO_WAKEUP;
+
+ if (data->flags & PRM_HAS_VOLTAGE)
+ prm_features |= PRM_HAS_VOLTAGE;
+
+ omap4_prminst_set_prm_dev_inst(data->device_inst_offset);
+
+ return prm_register(&omap44xx_prm_ll_data);
+}
+
+static int omap44xx_prm_late_init(void)
+{
+ int irq_num;
+
+ if (!(prm_features & PRM_HAS_IO_WAKEUP))
+ return 0;
+
+ /* OMAP4+ is DT only now */
+ if (!of_have_populated_dt())
+ return 0;
+
+ irq_num = of_irq_get(prm_init_data->np, 0);
+ /*
+ * Already have OMAP4 IRQ num. For all other platforms, we need
+ * IRQ numbers from DT
+ */
+ if (irq_num < 0 && !(prm_init_data->flags & PRM_IRQ_DEFAULT)) {
+ if (irq_num == -EPROBE_DEFER)
+ return irq_num;
+
+ /* Have nothing to do */
+ return 0;
+ }
+
+ /* Once OMAP4 DT is filled as well */
+ if (irq_num >= 0) {
+ omap4_prcm_irq_setup.irq = irq_num;
+ omap4_prcm_irq_setup.xlate_irq = NULL;
+ }
+
+ omap44xx_prm_enable_io_wakeup();
+
+ return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
+}
+
+static void __exit omap44xx_prm_exit(void)
+{
+ prm_unregister(&omap44xx_prm_ll_data);
+}
+__exitcall(omap44xx_prm_exit);
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
new file mode 100644
index 000000000..efd6035d0
--- /dev/null
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -0,0 +1,747 @@
+/*
+ * OMAP44xx PRM instance offset macros
+ *
+ * Copyright (C) 2009-2011 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 "prm44xx_54xx.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_WKUP_CM_WKUP_CDOFFS 0x0000
+#define OMAP4430_PRM_EMU_CM_EMU_CDOFFS 0x0000
+
+/* OMAP4 specific register offsets */
+#define OMAP4_RM_RSTCTRL 0x0000
+#define OMAP4_RM_RSTST 0x0004
+#define OMAP4_RM_RSTTIME 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_MODEM_ICR_CONTEXT_OFFSET 0x052c
+#define OMAP4430_RM_D2D_MODEM_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_MODE_OFFSET 0x00a8
+#define OMAP4430_PRM_VC_CFG_I2C_MODE 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_MODEM_IF_CTRL_OFFSET 0x00f4
+#define OMAP4430_PRM_MODEM_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)
+
+#endif
diff --git a/arch/arm/mach-omap2/prm44xx_54xx.h b/arch/arm/mach-omap2/prm44xx_54xx.h
new file mode 100644
index 000000000..3f139ebc8
--- /dev/null
+++ b/arch/arm/mach-omap2/prm44xx_54xx.h
@@ -0,0 +1,43 @@
+/*
+ * OMAP44xx and 54xx PRM common functions
+ *
+ * Copyright (C) 2009-2013 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_PRM44XX_54XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM44XX_54XX_H
+
+#include "prcm-common.h"
+
+/* Function prototypes */
+#ifndef __ASSEMBLER__
+
+/*
+ * OMAP4/OMAP5 access functions for voltage controller (VC) and
+ * voltage proccessor (VP) in the PRM.
+ */
+extern u32 omap4_prm_vcvp_read(u8 offset);
+extern void omap4_prm_vcvp_write(u32 val, u8 offset);
+extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
+
+int __init omap44xx_prm_init(const struct omap_prcm_init_data *data);
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-omap2/prm54xx.h b/arch/arm/mach-omap2/prm54xx.h
new file mode 100644
index 000000000..1eb22ff08
--- /dev/null
+++ b/arch/arm/mach-omap2/prm54xx.h
@@ -0,0 +1,420 @@
+/*
+ * OMAP54xx PRM instance offset macros
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * 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_PRM54XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM54XX_H
+
+#include "prm44xx_54xx.h"
+#include "prm.h"
+
+#define OMAP54XX_PRM_BASE 0x4ae06000
+
+#define OMAP54XX_PRM_REGADDR(inst, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP54XX_PRM_BASE + (inst) + (reg))
+
+
+/* PRM instances */
+#define OMAP54XX_PRM_OCP_SOCKET_INST 0x0000
+#define OMAP54XX_PRM_CKGEN_INST 0x0100
+#define OMAP54XX_PRM_MPU_INST 0x0300
+#define OMAP54XX_PRM_DSP_INST 0x0400
+#define OMAP54XX_PRM_ABE_INST 0x0500
+#define OMAP54XX_PRM_COREAON_INST 0x0600
+#define OMAP54XX_PRM_CORE_INST 0x0700
+#define OMAP54XX_PRM_IVA_INST 0x1200
+#define OMAP54XX_PRM_CAM_INST 0x1300
+#define OMAP54XX_PRM_DSS_INST 0x1400
+#define OMAP54XX_PRM_GPU_INST 0x1500
+#define OMAP54XX_PRM_L3INIT_INST 0x1600
+#define OMAP54XX_PRM_CUSTEFUSE_INST 0x1700
+#define OMAP54XX_PRM_WKUPAON_INST 0x1800
+#define OMAP54XX_PRM_WKUPAON_CM_INST 0x1900
+#define OMAP54XX_PRM_EMU_INST 0x1a00
+#define OMAP54XX_PRM_EMU_CM_INST 0x1b00
+#define OMAP54XX_PRM_DEVICE_INST 0x1c00
+#define OMAP54XX_PRM_INSTR_INST 0x1f00
+
+/* PRM clockdomain register offsets (from instance start) */
+#define OMAP54XX_PRM_WKUPAON_CM_WKUPAON_CDOFFS 0x0000
+#define OMAP54XX_PRM_EMU_CM_EMU_CDOFFS 0x0000
+
+/* PRM */
+
+/* PRM.OCP_SOCKET_PRM register offsets */
+#define OMAP54XX_REVISION_PRM_OFFSET 0x0000
+#define OMAP54XX_PRM_IRQSTATUS_MPU_OFFSET 0x0010
+#define OMAP54XX_PRM_IRQSTATUS_MPU_2_OFFSET 0x0014
+#define OMAP54XX_PRM_IRQENABLE_MPU_OFFSET 0x0018
+#define OMAP54XX_PRM_IRQENABLE_MPU_2_OFFSET 0x001c
+#define OMAP54XX_PRM_IRQSTATUS_IPU_OFFSET 0x0020
+#define OMAP54XX_PRM_IRQENABLE_IPU_OFFSET 0x0028
+#define OMAP54XX_PRM_IRQSTATUS_DSP_OFFSET 0x0030
+#define OMAP54XX_PRM_IRQENABLE_DSP_OFFSET 0x0038
+#define OMAP54XX_CM_PRM_PROFILING_CLKCTRL_OFFSET 0x0040
+#define OMAP54XX_CM_PRM_PROFILING_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_OCP_SOCKET_INST, 0x0040)
+#define OMAP54XX_PRM_DEBUG_OUT_OFFSET 0x0084
+#define OMAP54XX_PRM_DEBUG_TRANS_CFG_OFFSET 0x0090
+#define OMAP54XX_PRM_DEBUG_OFF_TRANS_OFFSET 0x0094
+#define OMAP54XX_PRM_DEBUG_CORE_RET_TRANS_OFFSET 0x0098
+#define OMAP54XX_PRM_DEBUG_MPU_RET_TRANS_OFFSET 0x009c
+#define OMAP54XX_PRM_DEBUG_MM_RET_TRANS_OFFSET 0x00a0
+#define OMAP54XX_PRM_DEBUG_WKUPAON_FD_TRANS_OFFSET 0x00a4
+
+/* PRM.CKGEN_PRM register offsets */
+#define OMAP54XX_CM_CLKSEL_ABE_DSS_SYS_OFFSET 0x0000
+#define OMAP54XX_CM_CLKSEL_ABE_DSS_SYS OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_CKGEN_INST, 0x0000)
+#define OMAP54XX_CM_CLKSEL_WKUPAON_OFFSET 0x0008
+#define OMAP54XX_CM_CLKSEL_WKUPAON OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_CKGEN_INST, 0x0008)
+#define OMAP54XX_CM_CLKSEL_ABE_PLL_REF_OFFSET 0x000c
+#define OMAP54XX_CM_CLKSEL_ABE_PLL_REF OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_CKGEN_INST, 0x000c)
+#define OMAP54XX_CM_CLKSEL_SYS_OFFSET 0x0010
+#define OMAP54XX_CM_CLKSEL_SYS OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_CKGEN_INST, 0x0010)
+
+/* PRM.MPU_PRM register offsets */
+#define OMAP54XX_PM_MPU_PWRSTCTRL_OFFSET 0x0000
+#define OMAP54XX_PM_MPU_PWRSTST_OFFSET 0x0004
+#define OMAP54XX_RM_MPU_MPU_CONTEXT_OFFSET 0x0024
+
+/* PRM.DSP_PRM register offsets */
+#define OMAP54XX_PM_DSP_PWRSTCTRL_OFFSET 0x0000
+#define OMAP54XX_PM_DSP_PWRSTST_OFFSET 0x0004
+#define OMAP54XX_RM_DSP_RSTCTRL_OFFSET 0x0010
+#define OMAP54XX_RM_DSP_RSTST_OFFSET 0x0014
+#define OMAP54XX_RM_DSP_DSP_CONTEXT_OFFSET 0x0024
+
+/* PRM.ABE_PRM register offsets */
+#define OMAP54XX_PM_ABE_PWRSTCTRL_OFFSET 0x0000
+#define OMAP54XX_PM_ABE_PWRSTST_OFFSET 0x0004
+#define OMAP54XX_RM_ABE_AESS_CONTEXT_OFFSET 0x002c
+#define OMAP54XX_PM_ABE_MCPDM_WKDEP_OFFSET 0x0030
+#define OMAP54XX_RM_ABE_MCPDM_CONTEXT_OFFSET 0x0034
+#define OMAP54XX_PM_ABE_DMIC_WKDEP_OFFSET 0x0038
+#define OMAP54XX_RM_ABE_DMIC_CONTEXT_OFFSET 0x003c
+#define OMAP54XX_PM_ABE_MCASP_WKDEP_OFFSET 0x0040
+#define OMAP54XX_RM_ABE_MCASP_CONTEXT_OFFSET 0x0044
+#define OMAP54XX_PM_ABE_MCBSP1_WKDEP_OFFSET 0x0048
+#define OMAP54XX_RM_ABE_MCBSP1_CONTEXT_OFFSET 0x004c
+#define OMAP54XX_PM_ABE_MCBSP2_WKDEP_OFFSET 0x0050
+#define OMAP54XX_RM_ABE_MCBSP2_CONTEXT_OFFSET 0x0054
+#define OMAP54XX_PM_ABE_MCBSP3_WKDEP_OFFSET 0x0058
+#define OMAP54XX_RM_ABE_MCBSP3_CONTEXT_OFFSET 0x005c
+#define OMAP54XX_PM_ABE_SLIMBUS1_WKDEP_OFFSET 0x0060
+#define OMAP54XX_RM_ABE_SLIMBUS1_CONTEXT_OFFSET 0x0064
+#define OMAP54XX_PM_ABE_TIMER5_WKDEP_OFFSET 0x0068
+#define OMAP54XX_RM_ABE_TIMER5_CONTEXT_OFFSET 0x006c
+#define OMAP54XX_PM_ABE_TIMER6_WKDEP_OFFSET 0x0070
+#define OMAP54XX_RM_ABE_TIMER6_CONTEXT_OFFSET 0x0074
+#define OMAP54XX_PM_ABE_TIMER7_WKDEP_OFFSET 0x0078
+#define OMAP54XX_RM_ABE_TIMER7_CONTEXT_OFFSET 0x007c
+#define OMAP54XX_PM_ABE_TIMER8_WKDEP_OFFSET 0x0080
+#define OMAP54XX_RM_ABE_TIMER8_CONTEXT_OFFSET 0x0084
+#define OMAP54XX_PM_ABE_WD_TIMER3_WKDEP_OFFSET 0x0088
+#define OMAP54XX_RM_ABE_WD_TIMER3_CONTEXT_OFFSET 0x008c
+
+/* PRM.COREAON_PRM register offsets */
+#define OMAP54XX_PM_COREAON_SMARTREFLEX_MPU_WKDEP_OFFSET 0x0028
+#define OMAP54XX_RM_COREAON_SMARTREFLEX_MPU_CONTEXT_OFFSET 0x002c
+#define OMAP54XX_PM_COREAON_SMARTREFLEX_MM_WKDEP_OFFSET 0x0030
+#define OMAP54XX_RM_COREAON_SMARTREFLEX_MM_CONTEXT_OFFSET 0x0034
+#define OMAP54XX_PM_COREAON_SMARTREFLEX_CORE_WKDEP_OFFSET 0x0038
+#define OMAP54XX_RM_COREAON_SMARTREFLEX_CORE_CONTEXT_OFFSET 0x003c
+
+/* PRM.CORE_PRM register offsets */
+#define OMAP54XX_PM_CORE_PWRSTCTRL_OFFSET 0x0000
+#define OMAP54XX_PM_CORE_PWRSTST_OFFSET 0x0004
+#define OMAP54XX_RM_L3MAIN1_L3_MAIN_1_CONTEXT_OFFSET 0x0024
+#define OMAP54XX_RM_L3MAIN2_L3_MAIN_2_CONTEXT_OFFSET 0x0124
+#define OMAP54XX_RM_L3MAIN2_GPMC_CONTEXT_OFFSET 0x012c
+#define OMAP54XX_RM_L3MAIN2_OCMC_RAM_CONTEXT_OFFSET 0x0134
+#define OMAP54XX_RM_IPU_RSTCTRL_OFFSET 0x0210
+#define OMAP54XX_RM_IPU_RSTST_OFFSET 0x0214
+#define OMAP54XX_RM_IPU_IPU_CONTEXT_OFFSET 0x0224
+#define OMAP54XX_RM_DMA_DMA_SYSTEM_CONTEXT_OFFSET 0x0324
+#define OMAP54XX_RM_EMIF_DMM_CONTEXT_OFFSET 0x0424
+#define OMAP54XX_RM_EMIF_EMIF_OCP_FW_CONTEXT_OFFSET 0x042c
+#define OMAP54XX_RM_EMIF_EMIF1_CONTEXT_OFFSET 0x0434
+#define OMAP54XX_RM_EMIF_EMIF2_CONTEXT_OFFSET 0x043c
+#define OMAP54XX_RM_EMIF_EMIF_DLL_CONTEXT_OFFSET 0x0444
+#define OMAP54XX_RM_C2C_C2C_CONTEXT_OFFSET 0x0524
+#define OMAP54XX_RM_C2C_MODEM_ICR_CONTEXT_OFFSET 0x052c
+#define OMAP54XX_RM_C2C_C2C_OCP_FW_CONTEXT_OFFSET 0x0534
+#define OMAP54XX_RM_L4CFG_L4_CFG_CONTEXT_OFFSET 0x0624
+#define OMAP54XX_RM_L4CFG_SPINLOCK_CONTEXT_OFFSET 0x062c
+#define OMAP54XX_RM_L4CFG_MAILBOX_CONTEXT_OFFSET 0x0634
+#define OMAP54XX_RM_L4CFG_SAR_ROM_CONTEXT_OFFSET 0x063c
+#define OMAP54XX_RM_L4CFG_OCP2SCP2_CONTEXT_OFFSET 0x0644
+#define OMAP54XX_RM_L3INSTR_L3_MAIN_3_CONTEXT_OFFSET 0x0724
+#define OMAP54XX_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET 0x072c
+#define OMAP54XX_RM_L3INSTR_OCP_WP_NOC_CONTEXT_OFFSET 0x0744
+#define OMAP54XX_RM_MIPIEXT_LLI_CONTEXT_OFFSET 0x0824
+#define OMAP54XX_RM_MIPIEXT_LLI_OCP_FW_CONTEXT_OFFSET 0x082c
+#define OMAP54XX_RM_MIPIEXT_MPHY_CONTEXT_OFFSET 0x0834
+#define OMAP54XX_PM_L4PER_TIMER10_WKDEP_OFFSET 0x0928
+#define OMAP54XX_RM_L4PER_TIMER10_CONTEXT_OFFSET 0x092c
+#define OMAP54XX_PM_L4PER_TIMER11_WKDEP_OFFSET 0x0930
+#define OMAP54XX_RM_L4PER_TIMER11_CONTEXT_OFFSET 0x0934
+#define OMAP54XX_PM_L4PER_TIMER2_WKDEP_OFFSET 0x0938
+#define OMAP54XX_RM_L4PER_TIMER2_CONTEXT_OFFSET 0x093c
+#define OMAP54XX_PM_L4PER_TIMER3_WKDEP_OFFSET 0x0940
+#define OMAP54XX_RM_L4PER_TIMER3_CONTEXT_OFFSET 0x0944
+#define OMAP54XX_PM_L4PER_TIMER4_WKDEP_OFFSET 0x0948
+#define OMAP54XX_RM_L4PER_TIMER4_CONTEXT_OFFSET 0x094c
+#define OMAP54XX_PM_L4PER_TIMER9_WKDEP_OFFSET 0x0950
+#define OMAP54XX_RM_L4PER_TIMER9_CONTEXT_OFFSET 0x0954
+#define OMAP54XX_RM_L4PER_ELM_CONTEXT_OFFSET 0x095c
+#define OMAP54XX_PM_L4PER_GPIO2_WKDEP_OFFSET 0x0960
+#define OMAP54XX_RM_L4PER_GPIO2_CONTEXT_OFFSET 0x0964
+#define OMAP54XX_PM_L4PER_GPIO3_WKDEP_OFFSET 0x0968
+#define OMAP54XX_RM_L4PER_GPIO3_CONTEXT_OFFSET 0x096c
+#define OMAP54XX_PM_L4PER_GPIO4_WKDEP_OFFSET 0x0970
+#define OMAP54XX_RM_L4PER_GPIO4_CONTEXT_OFFSET 0x0974
+#define OMAP54XX_PM_L4PER_GPIO5_WKDEP_OFFSET 0x0978
+#define OMAP54XX_RM_L4PER_GPIO5_CONTEXT_OFFSET 0x097c
+#define OMAP54XX_PM_L4PER_GPIO6_WKDEP_OFFSET 0x0980
+#define OMAP54XX_RM_L4PER_GPIO6_CONTEXT_OFFSET 0x0984
+#define OMAP54XX_RM_L4PER_HDQ1W_CONTEXT_OFFSET 0x098c
+#define OMAP54XX_PM_L4PER_I2C1_WKDEP_OFFSET 0x09a0
+#define OMAP54XX_RM_L4PER_I2C1_CONTEXT_OFFSET 0x09a4
+#define OMAP54XX_PM_L4PER_I2C2_WKDEP_OFFSET 0x09a8
+#define OMAP54XX_RM_L4PER_I2C2_CONTEXT_OFFSET 0x09ac
+#define OMAP54XX_PM_L4PER_I2C3_WKDEP_OFFSET 0x09b0
+#define OMAP54XX_RM_L4PER_I2C3_CONTEXT_OFFSET 0x09b4
+#define OMAP54XX_PM_L4PER_I2C4_WKDEP_OFFSET 0x09b8
+#define OMAP54XX_RM_L4PER_I2C4_CONTEXT_OFFSET 0x09bc
+#define OMAP54XX_RM_L4PER_L4_PER_CONTEXT_OFFSET 0x09c0
+#define OMAP54XX_PM_L4PER_MCSPI1_WKDEP_OFFSET 0x09f0
+#define OMAP54XX_RM_L4PER_MCSPI1_CONTEXT_OFFSET 0x09f4
+#define OMAP54XX_PM_L4PER_MCSPI2_WKDEP_OFFSET 0x09f8
+#define OMAP54XX_RM_L4PER_MCSPI2_CONTEXT_OFFSET 0x09fc
+#define OMAP54XX_PM_L4PER_MCSPI3_WKDEP_OFFSET 0x0a00
+#define OMAP54XX_RM_L4PER_MCSPI3_CONTEXT_OFFSET 0x0a04
+#define OMAP54XX_PM_L4PER_MCSPI4_WKDEP_OFFSET 0x0a08
+#define OMAP54XX_RM_L4PER_MCSPI4_CONTEXT_OFFSET 0x0a0c
+#define OMAP54XX_PM_L4PER_GPIO7_WKDEP_OFFSET 0x0a10
+#define OMAP54XX_RM_L4PER_GPIO7_CONTEXT_OFFSET 0x0a14
+#define OMAP54XX_PM_L4PER_GPIO8_WKDEP_OFFSET 0x0a18
+#define OMAP54XX_RM_L4PER_GPIO8_CONTEXT_OFFSET 0x0a1c
+#define OMAP54XX_PM_L4PER_MMC3_WKDEP_OFFSET 0x0a20
+#define OMAP54XX_RM_L4PER_MMC3_CONTEXT_OFFSET 0x0a24
+#define OMAP54XX_PM_L4PER_MMC4_WKDEP_OFFSET 0x0a28
+#define OMAP54XX_RM_L4PER_MMC4_CONTEXT_OFFSET 0x0a2c
+#define OMAP54XX_PM_L4PER_UART1_WKDEP_OFFSET 0x0a40
+#define OMAP54XX_RM_L4PER_UART1_CONTEXT_OFFSET 0x0a44
+#define OMAP54XX_PM_L4PER_UART2_WKDEP_OFFSET 0x0a48
+#define OMAP54XX_RM_L4PER_UART2_CONTEXT_OFFSET 0x0a4c
+#define OMAP54XX_PM_L4PER_UART3_WKDEP_OFFSET 0x0a50
+#define OMAP54XX_RM_L4PER_UART3_CONTEXT_OFFSET 0x0a54
+#define OMAP54XX_RM_L4PER_UART4_CONTEXT_OFFSET 0x0a58
+#define OMAP54XX_PM_L4PER_UART4_WKDEP_OFFSET 0x0a5c
+#define OMAP54XX_PM_L4PER_MMC5_WKDEP_OFFSET 0x0a60
+#define OMAP54XX_RM_L4PER_MMC5_CONTEXT_OFFSET 0x0a64
+#define OMAP54XX_PM_L4PER_I2C5_WKDEP_OFFSET 0x0a68
+#define OMAP54XX_RM_L4PER_I2C5_CONTEXT_OFFSET 0x0a6c
+#define OMAP54XX_PM_L4PER_UART5_WKDEP_OFFSET 0x0a70
+#define OMAP54XX_RM_L4PER_UART5_CONTEXT_OFFSET 0x0a74
+#define OMAP54XX_PM_L4PER_UART6_WKDEP_OFFSET 0x0a78
+#define OMAP54XX_RM_L4PER_UART6_CONTEXT_OFFSET 0x0a7c
+#define OMAP54XX_RM_L4SEC_AES1_CONTEXT_OFFSET 0x0aa4
+#define OMAP54XX_RM_L4SEC_AES2_CONTEXT_OFFSET 0x0aac
+#define OMAP54XX_RM_L4SEC_DES3DES_CONTEXT_OFFSET 0x0ab4
+#define OMAP54XX_RM_L4SEC_FPKA_CONTEXT_OFFSET 0x0abc
+#define OMAP54XX_RM_L4SEC_RNG_CONTEXT_OFFSET 0x0ac4
+#define OMAP54XX_RM_L4SEC_SHA2MD5_CONTEXT_OFFSET 0x0acc
+#define OMAP54XX_RM_L4SEC_DMA_CRYPTO_CONTEXT_OFFSET 0x0adc
+
+/* PRM.IVA_PRM register offsets */
+#define OMAP54XX_PM_IVA_PWRSTCTRL_OFFSET 0x0000
+#define OMAP54XX_PM_IVA_PWRSTST_OFFSET 0x0004
+#define OMAP54XX_RM_IVA_RSTCTRL_OFFSET 0x0010
+#define OMAP54XX_RM_IVA_RSTST_OFFSET 0x0014
+#define OMAP54XX_RM_IVA_IVA_CONTEXT_OFFSET 0x0024
+#define OMAP54XX_RM_IVA_SL2_CONTEXT_OFFSET 0x002c
+
+/* PRM.CAM_PRM register offsets */
+#define OMAP54XX_PM_CAM_PWRSTCTRL_OFFSET 0x0000
+#define OMAP54XX_PM_CAM_PWRSTST_OFFSET 0x0004
+#define OMAP54XX_RM_CAM_ISS_CONTEXT_OFFSET 0x0024
+#define OMAP54XX_RM_CAM_FDIF_CONTEXT_OFFSET 0x002c
+#define OMAP54XX_RM_CAM_CAL_CONTEXT_OFFSET 0x0034
+
+/* PRM.DSS_PRM register offsets */
+#define OMAP54XX_PM_DSS_PWRSTCTRL_OFFSET 0x0000
+#define OMAP54XX_PM_DSS_PWRSTST_OFFSET 0x0004
+#define OMAP54XX_PM_DSS_DSS_WKDEP_OFFSET 0x0020
+#define OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET 0x0024
+#define OMAP54XX_RM_DSS_BB2D_CONTEXT_OFFSET 0x0034
+
+/* PRM.GPU_PRM register offsets */
+#define OMAP54XX_PM_GPU_PWRSTCTRL_OFFSET 0x0000
+#define OMAP54XX_PM_GPU_PWRSTST_OFFSET 0x0004
+#define OMAP54XX_RM_GPU_GPU_CONTEXT_OFFSET 0x0024
+
+/* PRM.L3INIT_PRM register offsets */
+#define OMAP54XX_PM_L3INIT_PWRSTCTRL_OFFSET 0x0000
+#define OMAP54XX_PM_L3INIT_PWRSTST_OFFSET 0x0004
+#define OMAP54XX_PM_L3INIT_MMC1_WKDEP_OFFSET 0x0028
+#define OMAP54XX_RM_L3INIT_MMC1_CONTEXT_OFFSET 0x002c
+#define OMAP54XX_PM_L3INIT_MMC2_WKDEP_OFFSET 0x0030
+#define OMAP54XX_RM_L3INIT_MMC2_CONTEXT_OFFSET 0x0034
+#define OMAP54XX_PM_L3INIT_HSI_WKDEP_OFFSET 0x0038
+#define OMAP54XX_RM_L3INIT_HSI_CONTEXT_OFFSET 0x003c
+#define OMAP54XX_PM_L3INIT_UNIPRO2_WKDEP_OFFSET 0x0040
+#define OMAP54XX_RM_L3INIT_UNIPRO2_CONTEXT_OFFSET 0x0044
+#define OMAP54XX_PM_L3INIT_USB_HOST_HS_WKDEP_OFFSET 0x0058
+#define OMAP54XX_RM_L3INIT_USB_HOST_HS_CONTEXT_OFFSET 0x005c
+#define OMAP54XX_PM_L3INIT_USB_TLL_HS_WKDEP_OFFSET 0x0068
+#define OMAP54XX_RM_L3INIT_USB_TLL_HS_CONTEXT_OFFSET 0x006c
+#define OMAP54XX_RM_L3INIT_IEEE1500_2_OCP_CONTEXT_OFFSET 0x007c
+#define OMAP54XX_PM_L3INIT_SATA_WKDEP_OFFSET 0x0088
+#define OMAP54XX_RM_L3INIT_SATA_CONTEXT_OFFSET 0x008c
+#define OMAP54XX_RM_L3INIT_OCP2SCP1_CONTEXT_OFFSET 0x00e4
+#define OMAP54XX_RM_L3INIT_OCP2SCP3_CONTEXT_OFFSET 0x00ec
+#define OMAP54XX_PM_L3INIT_USB_OTG_SS_WKDEP_OFFSET 0x00f0
+#define OMAP54XX_RM_L3INIT_USB_OTG_SS_CONTEXT_OFFSET 0x00f4
+
+/* PRM.CUSTEFUSE_PRM register offsets */
+#define OMAP54XX_PM_CUSTEFUSE_PWRSTCTRL_OFFSET 0x0000
+#define OMAP54XX_PM_CUSTEFUSE_PWRSTST_OFFSET 0x0004
+#define OMAP54XX_RM_CUSTEFUSE_EFUSE_CTRL_CUST_CONTEXT_OFFSET 0x0024
+
+/* PRM.WKUPAON_PRM register offsets */
+#define OMAP54XX_RM_WKUPAON_L4_WKUP_CONTEXT_OFFSET 0x0024
+#define OMAP54XX_RM_WKUPAON_WD_TIMER1_CONTEXT_OFFSET 0x002c
+#define OMAP54XX_PM_WKUPAON_WD_TIMER2_WKDEP_OFFSET 0x0030
+#define OMAP54XX_RM_WKUPAON_WD_TIMER2_CONTEXT_OFFSET 0x0034
+#define OMAP54XX_PM_WKUPAON_GPIO1_WKDEP_OFFSET 0x0038
+#define OMAP54XX_RM_WKUPAON_GPIO1_CONTEXT_OFFSET 0x003c
+#define OMAP54XX_PM_WKUPAON_TIMER1_WKDEP_OFFSET 0x0040
+#define OMAP54XX_RM_WKUPAON_TIMER1_CONTEXT_OFFSET 0x0044
+#define OMAP54XX_PM_WKUPAON_TIMER12_WKDEP_OFFSET 0x0048
+#define OMAP54XX_RM_WKUPAON_TIMER12_CONTEXT_OFFSET 0x004c
+#define OMAP54XX_RM_WKUPAON_COUNTER_32K_CONTEXT_OFFSET 0x0054
+#define OMAP54XX_RM_WKUPAON_SAR_RAM_CONTEXT_OFFSET 0x0064
+#define OMAP54XX_PM_WKUPAON_KBD_WKDEP_OFFSET 0x0078
+#define OMAP54XX_RM_WKUPAON_KBD_CONTEXT_OFFSET 0x007c
+
+/* PRM.WKUPAON_CM register offsets */
+#define OMAP54XX_CM_WKUPAON_CLKSTCTRL_OFFSET 0x0000
+#define OMAP54XX_CM_WKUPAON_L4_WKUP_CLKCTRL_OFFSET 0x0020
+#define OMAP54XX_CM_WKUPAON_L4_WKUP_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0020)
+#define OMAP54XX_CM_WKUPAON_WD_TIMER1_CLKCTRL_OFFSET 0x0028
+#define OMAP54XX_CM_WKUPAON_WD_TIMER1_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0028)
+#define OMAP54XX_CM_WKUPAON_WD_TIMER2_CLKCTRL_OFFSET 0x0030
+#define OMAP54XX_CM_WKUPAON_WD_TIMER2_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0030)
+#define OMAP54XX_CM_WKUPAON_GPIO1_CLKCTRL_OFFSET 0x0038
+#define OMAP54XX_CM_WKUPAON_GPIO1_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0038)
+#define OMAP54XX_CM_WKUPAON_TIMER1_CLKCTRL_OFFSET 0x0040
+#define OMAP54XX_CM_WKUPAON_TIMER1_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0040)
+#define OMAP54XX_CM_WKUPAON_TIMER12_CLKCTRL_OFFSET 0x0048
+#define OMAP54XX_CM_WKUPAON_TIMER12_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0048)
+#define OMAP54XX_CM_WKUPAON_COUNTER_32K_CLKCTRL_OFFSET 0x0050
+#define OMAP54XX_CM_WKUPAON_COUNTER_32K_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0050)
+#define OMAP54XX_CM_WKUPAON_SAR_RAM_CLKCTRL_OFFSET 0x0060
+#define OMAP54XX_CM_WKUPAON_SAR_RAM_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0060)
+#define OMAP54XX_CM_WKUPAON_KBD_CLKCTRL_OFFSET 0x0078
+#define OMAP54XX_CM_WKUPAON_KBD_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0078)
+#define OMAP54XX_CM_WKUPAON_SCRM_CLKCTRL_OFFSET 0x0090
+#define OMAP54XX_CM_WKUPAON_SCRM_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0090)
+#define OMAP54XX_CM_WKUPAON_IO_SRCOMP_CLKCTRL_OFFSET 0x0098
+#define OMAP54XX_CM_WKUPAON_IO_SRCOMP_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0098)
+
+/* PRM.EMU_PRM register offsets */
+#define OMAP54XX_PM_EMU_PWRSTCTRL_OFFSET 0x0000
+#define OMAP54XX_PM_EMU_PWRSTST_OFFSET 0x0004
+#define OMAP54XX_RM_EMU_DEBUGSS_CONTEXT_OFFSET 0x0024
+
+/* PRM.EMU_CM register offsets */
+#define OMAP54XX_CM_EMU_CLKSTCTRL_OFFSET 0x0000
+#define OMAP54XX_CM_EMU_DYNAMICDEP_OFFSET 0x0008
+#define OMAP54XX_CM_EMU_DEBUGSS_CLKCTRL_OFFSET 0x0020
+#define OMAP54XX_CM_EMU_DEBUGSS_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_EMU_CM_INST, 0x0020)
+#define OMAP54XX_CM_EMU_MPU_EMU_DBG_CLKCTRL_OFFSET 0x0028
+#define OMAP54XX_CM_EMU_MPU_EMU_DBG_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_EMU_CM_INST, 0x0028)
+
+/* PRM.DEVICE_PRM register offsets */
+#define OMAP54XX_PRM_RSTCTRL_OFFSET 0x0000
+#define OMAP54XX_PRM_RSTST_OFFSET 0x0004
+#define OMAP54XX_PRM_RSTTIME_OFFSET 0x0008
+#define OMAP54XX_PRM_CLKREQCTRL_OFFSET 0x000c
+#define OMAP54XX_PRM_VOLTCTRL_OFFSET 0x0010
+#define OMAP54XX_PRM_PWRREQCTRL_OFFSET 0x0014
+#define OMAP54XX_PRM_PSCON_COUNT_OFFSET 0x0018
+#define OMAP54XX_PRM_IO_COUNT_OFFSET 0x001c
+#define OMAP54XX_PRM_IO_PMCTRL_OFFSET 0x0020
+#define OMAP54XX_PRM_VOLTSETUP_WARMRESET_OFFSET 0x0024
+#define OMAP54XX_PRM_VOLTSETUP_CORE_OFF_OFFSET 0x0028
+#define OMAP54XX_PRM_VOLTSETUP_MPU_OFF_OFFSET 0x002c
+#define OMAP54XX_PRM_VOLTSETUP_MM_OFF_OFFSET 0x0030
+#define OMAP54XX_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET 0x0034
+#define OMAP54XX_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET 0x0038
+#define OMAP54XX_PRM_VOLTSETUP_MM_RET_SLEEP_OFFSET 0x003c
+#define OMAP54XX_PRM_VP_CORE_CONFIG_OFFSET 0x0040
+#define OMAP54XX_PRM_VP_CORE_STATUS_OFFSET 0x0044
+#define OMAP54XX_PRM_VP_CORE_VLIMITTO_OFFSET 0x0048
+#define OMAP54XX_PRM_VP_CORE_VOLTAGE_OFFSET 0x004c
+#define OMAP54XX_PRM_VP_CORE_VSTEPMAX_OFFSET 0x0050
+#define OMAP54XX_PRM_VP_CORE_VSTEPMIN_OFFSET 0x0054
+#define OMAP54XX_PRM_VP_MPU_CONFIG_OFFSET 0x0058
+#define OMAP54XX_PRM_VP_MPU_STATUS_OFFSET 0x005c
+#define OMAP54XX_PRM_VP_MPU_VLIMITTO_OFFSET 0x0060
+#define OMAP54XX_PRM_VP_MPU_VOLTAGE_OFFSET 0x0064
+#define OMAP54XX_PRM_VP_MPU_VSTEPMAX_OFFSET 0x0068
+#define OMAP54XX_PRM_VP_MPU_VSTEPMIN_OFFSET 0x006c
+#define OMAP54XX_PRM_VP_MM_CONFIG_OFFSET 0x0070
+#define OMAP54XX_PRM_VP_MM_STATUS_OFFSET 0x0074
+#define OMAP54XX_PRM_VP_MM_VLIMITTO_OFFSET 0x0078
+#define OMAP54XX_PRM_VP_MM_VOLTAGE_OFFSET 0x007c
+#define OMAP54XX_PRM_VP_MM_VSTEPMAX_OFFSET 0x0080
+#define OMAP54XX_PRM_VP_MM_VSTEPMIN_OFFSET 0x0084
+#define OMAP54XX_PRM_VC_SMPS_CORE_CONFIG_OFFSET 0x0088
+#define OMAP54XX_PRM_VC_SMPS_MM_CONFIG_OFFSET 0x008c
+#define OMAP54XX_PRM_VC_SMPS_MPU_CONFIG_OFFSET 0x0090
+#define OMAP54XX_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET 0x0094
+#define OMAP54XX_PRM_VC_VAL_CMD_VDD_MM_L_OFFSET 0x0098
+#define OMAP54XX_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET 0x009c
+#define OMAP54XX_PRM_VC_VAL_BYPASS_OFFSET 0x00a0
+#define OMAP54XX_PRM_VC_CORE_ERRST_OFFSET 0x00a4
+#define OMAP54XX_PRM_VC_MM_ERRST_OFFSET 0x00a8
+#define OMAP54XX_PRM_VC_MPU_ERRST_OFFSET 0x00ac
+#define OMAP54XX_PRM_VC_BYPASS_ERRST_OFFSET 0x00b0
+#define OMAP54XX_PRM_VC_CFG_I2C_MODE_OFFSET 0x00b4
+#define OMAP54XX_PRM_VC_CFG_I2C_CLK_OFFSET 0x00b8
+#define OMAP54XX_PRM_SRAM_COUNT_OFFSET 0x00bc
+#define OMAP54XX_PRM_SRAM_WKUP_SETUP_OFFSET 0x00c0
+#define OMAP54XX_PRM_SLDO_CORE_SETUP_OFFSET 0x00c4
+#define OMAP54XX_PRM_SLDO_CORE_CTRL_OFFSET 0x00c8
+#define OMAP54XX_PRM_SLDO_MPU_SETUP_OFFSET 0x00cc
+#define OMAP54XX_PRM_SLDO_MPU_CTRL_OFFSET 0x00d0
+#define OMAP54XX_PRM_SLDO_MM_SETUP_OFFSET 0x00d4
+#define OMAP54XX_PRM_SLDO_MM_CTRL_OFFSET 0x00d8
+#define OMAP54XX_PRM_ABBLDO_MPU_SETUP_OFFSET 0x00dc
+#define OMAP54XX_PRM_ABBLDO_MPU_CTRL_OFFSET 0x00e0
+#define OMAP54XX_PRM_ABBLDO_MM_SETUP_OFFSET 0x00e4
+#define OMAP54XX_PRM_ABBLDO_MM_CTRL_OFFSET 0x00e8
+#define OMAP54XX_PRM_BANDGAP_SETUP_OFFSET 0x00ec
+#define OMAP54XX_PRM_DEVICE_OFF_CTRL_OFFSET 0x00f0
+#define OMAP54XX_PRM_PHASE1_CNDP_OFFSET 0x00f4
+#define OMAP54XX_PRM_PHASE2A_CNDP_OFFSET 0x00f8
+#define OMAP54XX_PRM_PHASE2B_CNDP_OFFSET 0x00fc
+#define OMAP54XX_PRM_MODEM_IF_CTRL_OFFSET 0x0100
+#define OMAP54XX_PRM_VOLTST_MPU_OFFSET 0x0110
+#define OMAP54XX_PRM_VOLTST_MM_OFFSET 0x0114
+
+#endif
diff --git a/arch/arm/mach-omap2/prm7xx.h b/arch/arm/mach-omap2/prm7xx.h
new file mode 100644
index 000000000..cc1e6a2b9
--- /dev/null
+++ b/arch/arm/mach-omap2/prm7xx.h
@@ -0,0 +1,682 @@
+/*
+ * DRA7xx PRM instance offset macros
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Generated by code originally written by:
+ * 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_PRM7XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM7XX_H
+
+#include "prcm-common.h"
+#include "prm44xx_54xx.h"
+#include "prm.h"
+
+#define DRA7XX_PRM_BASE 0x4ae06000
+
+#define DRA7XX_PRM_REGADDR(inst, reg) \
+ OMAP2_L4_IO_ADDRESS(DRA7XX_PRM_BASE + (inst) + (reg))
+
+
+/* PRM instances */
+#define DRA7XX_PRM_OCP_SOCKET_INST 0x0000
+#define DRA7XX_PRM_CKGEN_INST 0x0100
+#define DRA7XX_PRM_MPU_INST 0x0300
+#define DRA7XX_PRM_DSP1_INST 0x0400
+#define DRA7XX_PRM_IPU_INST 0x0500
+#define DRA7XX_PRM_COREAON_INST 0x0628
+#define DRA7XX_PRM_CORE_INST 0x0700
+#define DRA7XX_PRM_IVA_INST 0x0f00
+#define DRA7XX_PRM_CAM_INST 0x1000
+#define DRA7XX_PRM_DSS_INST 0x1100
+#define DRA7XX_PRM_GPU_INST 0x1200
+#define DRA7XX_PRM_L3INIT_INST 0x1300
+#define DRA7XX_PRM_L4PER_INST 0x1400
+#define DRA7XX_PRM_CUSTEFUSE_INST 0x1600
+#define DRA7XX_PRM_WKUPAON_INST 0x1724
+#define DRA7XX_PRM_WKUPAON_CM_INST 0x1800
+#define DRA7XX_PRM_EMU_INST 0x1900
+#define DRA7XX_PRM_EMU_CM_INST 0x1a00
+#define DRA7XX_PRM_DSP2_INST 0x1b00
+#define DRA7XX_PRM_EVE1_INST 0x1b40
+#define DRA7XX_PRM_EVE2_INST 0x1b80
+#define DRA7XX_PRM_EVE3_INST 0x1bc0
+#define DRA7XX_PRM_EVE4_INST 0x1c00
+#define DRA7XX_PRM_RTC_INST 0x1c60
+#define DRA7XX_PRM_VPE_INST 0x1c80
+#define DRA7XX_PRM_DEVICE_INST 0x1d00
+#define DRA7XX_PRM_INSTR_INST 0x1f00
+
+/* PRM clockdomain register offsets (from instance start) */
+#define DRA7XX_PRM_WKUPAON_CM_WKUPAON_CDOFFS 0x0000
+#define DRA7XX_PRM_EMU_CM_EMU_CDOFFS 0x0000
+
+/* PRM */
+
+/* PRM.OCP_SOCKET_PRM register offsets */
+#define DRA7XX_REVISION_PRM_OFFSET 0x0000
+#define DRA7XX_PRM_IRQSTATUS_MPU_OFFSET 0x0010
+#define DRA7XX_PRM_IRQSTATUS_MPU_2_OFFSET 0x0014
+#define DRA7XX_PRM_IRQENABLE_MPU_OFFSET 0x0018
+#define DRA7XX_PRM_IRQENABLE_MPU_2_OFFSET 0x001c
+#define DRA7XX_PRM_IRQSTATUS_IPU2_OFFSET 0x0020
+#define DRA7XX_PRM_IRQENABLE_IPU2_OFFSET 0x0028
+#define DRA7XX_PRM_IRQSTATUS_DSP1_OFFSET 0x0030
+#define DRA7XX_PRM_IRQENABLE_DSP1_OFFSET 0x0038
+#define DRA7XX_CM_PRM_PROFILING_CLKCTRL_OFFSET 0x0040
+#define DRA7XX_CM_PRM_PROFILING_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_OCP_SOCKET_INST, 0x0040)
+#define DRA7XX_PRM_IRQENABLE_DSP2_OFFSET 0x0044
+#define DRA7XX_PRM_IRQENABLE_EVE1_OFFSET 0x0048
+#define DRA7XX_PRM_IRQENABLE_EVE2_OFFSET 0x004c
+#define DRA7XX_PRM_IRQENABLE_EVE3_OFFSET 0x0050
+#define DRA7XX_PRM_IRQENABLE_EVE4_OFFSET 0x0054
+#define DRA7XX_PRM_IRQENABLE_IPU1_OFFSET 0x0058
+#define DRA7XX_PRM_IRQSTATUS_DSP2_OFFSET 0x005c
+#define DRA7XX_PRM_IRQSTATUS_EVE1_OFFSET 0x0060
+#define DRA7XX_PRM_IRQSTATUS_EVE2_OFFSET 0x0064
+#define DRA7XX_PRM_IRQSTATUS_EVE3_OFFSET 0x0068
+#define DRA7XX_PRM_IRQSTATUS_EVE4_OFFSET 0x006c
+#define DRA7XX_PRM_IRQSTATUS_IPU1_OFFSET 0x0070
+#define DRA7XX_PRM_DEBUG_CFG1_OFFSET 0x00e4
+#define DRA7XX_PRM_DEBUG_CFG2_OFFSET 0x00e8
+#define DRA7XX_PRM_DEBUG_CFG3_OFFSET 0x00ec
+#define DRA7XX_PRM_DEBUG_OUT_OFFSET 0x00f4
+
+/* PRM.CKGEN_PRM register offsets */
+#define DRA7XX_CM_CLKSEL_SYSCLK1_OFFSET 0x0000
+#define DRA7XX_CM_CLKSEL_SYSCLK1 DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0000)
+#define DRA7XX_CM_CLKSEL_WKUPAON_OFFSET 0x0008
+#define DRA7XX_CM_CLKSEL_WKUPAON DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0008)
+#define DRA7XX_CM_CLKSEL_ABE_PLL_REF_OFFSET 0x000c
+#define DRA7XX_CM_CLKSEL_ABE_PLL_REF DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x000c)
+#define DRA7XX_CM_CLKSEL_SYS_OFFSET 0x0010
+#define DRA7XX_CM_CLKSEL_SYS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0010)
+#define DRA7XX_CM_CLKSEL_ABE_PLL_BYPAS_OFFSET 0x0014
+#define DRA7XX_CM_CLKSEL_ABE_PLL_BYPAS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0014)
+#define DRA7XX_CM_CLKSEL_ABE_PLL_SYS_OFFSET 0x0018
+#define DRA7XX_CM_CLKSEL_ABE_PLL_SYS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0018)
+#define DRA7XX_CM_CLKSEL_ABE_24M_OFFSET 0x001c
+#define DRA7XX_CM_CLKSEL_ABE_24M DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x001c)
+#define DRA7XX_CM_CLKSEL_ABE_SYS_OFFSET 0x0020
+#define DRA7XX_CM_CLKSEL_ABE_SYS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0020)
+#define DRA7XX_CM_CLKSEL_HDMI_MCASP_AUX_OFFSET 0x0024
+#define DRA7XX_CM_CLKSEL_HDMI_MCASP_AUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0024)
+#define DRA7XX_CM_CLKSEL_HDMI_TIMER_OFFSET 0x0028
+#define DRA7XX_CM_CLKSEL_HDMI_TIMER DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0028)
+#define DRA7XX_CM_CLKSEL_MCASP_SYS_OFFSET 0x002c
+#define DRA7XX_CM_CLKSEL_MCASP_SYS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x002c)
+#define DRA7XX_CM_CLKSEL_MLBP_MCASP_OFFSET 0x0030
+#define DRA7XX_CM_CLKSEL_MLBP_MCASP DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0030)
+#define DRA7XX_CM_CLKSEL_MLB_MCASP_OFFSET 0x0034
+#define DRA7XX_CM_CLKSEL_MLB_MCASP DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0034)
+#define DRA7XX_CM_CLKSEL_PER_ABE_X1_GFCLK_MCASP_AUX_OFFSET 0x0038
+#define DRA7XX_CM_CLKSEL_PER_ABE_X1_GFCLK_MCASP_AUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0038)
+#define DRA7XX_CM_CLKSEL_SYS_CLK1_32K_OFFSET 0x0040
+#define DRA7XX_CM_CLKSEL_SYS_CLK1_32K DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0040)
+#define DRA7XX_CM_CLKSEL_TIMER_SYS_OFFSET 0x0044
+#define DRA7XX_CM_CLKSEL_TIMER_SYS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0044)
+#define DRA7XX_CM_CLKSEL_VIDEO1_MCASP_AUX_OFFSET 0x0048
+#define DRA7XX_CM_CLKSEL_VIDEO1_MCASP_AUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0048)
+#define DRA7XX_CM_CLKSEL_VIDEO1_TIMER_OFFSET 0x004c
+#define DRA7XX_CM_CLKSEL_VIDEO1_TIMER DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x004c)
+#define DRA7XX_CM_CLKSEL_VIDEO2_MCASP_AUX_OFFSET 0x0050
+#define DRA7XX_CM_CLKSEL_VIDEO2_MCASP_AUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0050)
+#define DRA7XX_CM_CLKSEL_VIDEO2_TIMER_OFFSET 0x0054
+#define DRA7XX_CM_CLKSEL_VIDEO2_TIMER DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0054)
+#define DRA7XX_CM_CLKSEL_CLKOUTMUX0_OFFSET 0x0058
+#define DRA7XX_CM_CLKSEL_CLKOUTMUX0 DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0058)
+#define DRA7XX_CM_CLKSEL_CLKOUTMUX1_OFFSET 0x005c
+#define DRA7XX_CM_CLKSEL_CLKOUTMUX1 DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x005c)
+#define DRA7XX_CM_CLKSEL_CLKOUTMUX2_OFFSET 0x0060
+#define DRA7XX_CM_CLKSEL_CLKOUTMUX2 DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0060)
+#define DRA7XX_CM_CLKSEL_HDMI_PLL_SYS_OFFSET 0x0064
+#define DRA7XX_CM_CLKSEL_HDMI_PLL_SYS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0064)
+#define DRA7XX_CM_CLKSEL_VIDEO1_PLL_SYS_OFFSET 0x0068
+#define DRA7XX_CM_CLKSEL_VIDEO1_PLL_SYS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0068)
+#define DRA7XX_CM_CLKSEL_VIDEO2_PLL_SYS_OFFSET 0x006c
+#define DRA7XX_CM_CLKSEL_VIDEO2_PLL_SYS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x006c)
+#define DRA7XX_CM_CLKSEL_ABE_CLK_DIV_OFFSET 0x0070
+#define DRA7XX_CM_CLKSEL_ABE_CLK_DIV DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0070)
+#define DRA7XX_CM_CLKSEL_ABE_GICLK_DIV_OFFSET 0x0074
+#define DRA7XX_CM_CLKSEL_ABE_GICLK_DIV DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0074)
+#define DRA7XX_CM_CLKSEL_AESS_FCLK_DIV_OFFSET 0x0078
+#define DRA7XX_CM_CLKSEL_AESS_FCLK_DIV DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0078)
+#define DRA7XX_CM_CLKSEL_EVE_CLK_OFFSET 0x0080
+#define DRA7XX_CM_CLKSEL_EVE_CLK DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0080)
+#define DRA7XX_CM_CLKSEL_USB_OTG_CLK_CLKOUTMUX_OFFSET 0x0084
+#define DRA7XX_CM_CLKSEL_USB_OTG_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0084)
+#define DRA7XX_CM_CLKSEL_CORE_DPLL_OUT_CLK_CLKOUTMUX_OFFSET 0x0088
+#define DRA7XX_CM_CLKSEL_CORE_DPLL_OUT_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0088)
+#define DRA7XX_CM_CLKSEL_DSP_GFCLK_CLKOUTMUX_OFFSET 0x008c
+#define DRA7XX_CM_CLKSEL_DSP_GFCLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x008c)
+#define DRA7XX_CM_CLKSEL_EMIF_PHY_GCLK_CLKOUTMUX_OFFSET 0x0090
+#define DRA7XX_CM_CLKSEL_EMIF_PHY_GCLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0090)
+#define DRA7XX_CM_CLKSEL_EMU_CLK_CLKOUTMUX_OFFSET 0x0094
+#define DRA7XX_CM_CLKSEL_EMU_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0094)
+#define DRA7XX_CM_CLKSEL_FUNC_96M_AON_CLK_CLKOUTMUX_OFFSET 0x0098
+#define DRA7XX_CM_CLKSEL_FUNC_96M_AON_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0098)
+#define DRA7XX_CM_CLKSEL_GMAC_250M_CLK_CLKOUTMUX_OFFSET 0x009c
+#define DRA7XX_CM_CLKSEL_GMAC_250M_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x009c)
+#define DRA7XX_CM_CLKSEL_GPU_GCLK_CLKOUTMUX_OFFSET 0x00a0
+#define DRA7XX_CM_CLKSEL_GPU_GCLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00a0)
+#define DRA7XX_CM_CLKSEL_HDMI_CLK_CLKOUTMUX_OFFSET 0x00a4
+#define DRA7XX_CM_CLKSEL_HDMI_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00a4)
+#define DRA7XX_CM_CLKSEL_IVA_GCLK_CLKOUTMUX_OFFSET 0x00a8
+#define DRA7XX_CM_CLKSEL_IVA_GCLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00a8)
+#define DRA7XX_CM_CLKSEL_L3INIT_480M_GFCLK_CLKOUTMUX_OFFSET 0x00ac
+#define DRA7XX_CM_CLKSEL_L3INIT_480M_GFCLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00ac)
+#define DRA7XX_CM_CLKSEL_MPU_GCLK_CLKOUTMUX_OFFSET 0x00b0
+#define DRA7XX_CM_CLKSEL_MPU_GCLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00b0)
+#define DRA7XX_CM_CLKSEL_PCIE1_CLK_CLKOUTMUX_OFFSET 0x00b4
+#define DRA7XX_CM_CLKSEL_PCIE1_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00b4)
+#define DRA7XX_CM_CLKSEL_PCIE2_CLK_CLKOUTMUX_OFFSET 0x00b8
+#define DRA7XX_CM_CLKSEL_PCIE2_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00b8)
+#define DRA7XX_CM_CLKSEL_PER_ABE_X1_CLK_CLKOUTMUX_OFFSET 0x00bc
+#define DRA7XX_CM_CLKSEL_PER_ABE_X1_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00bc)
+#define DRA7XX_CM_CLKSEL_SATA_CLK_CLKOUTMUX_OFFSET 0x00c0
+#define DRA7XX_CM_CLKSEL_SATA_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00c0)
+#define DRA7XX_CM_CLKSEL_SECURE_32K_CLK_CLKOUTMUX_OFFSET 0x00c4
+#define DRA7XX_CM_CLKSEL_SECURE_32K_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00c4)
+#define DRA7XX_CM_CLKSEL_SYS_CLK1_CLKOUTMUX_OFFSET 0x00c8
+#define DRA7XX_CM_CLKSEL_SYS_CLK1_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00c8)
+#define DRA7XX_CM_CLKSEL_SYS_CLK2_CLKOUTMUX_OFFSET 0x00cc
+#define DRA7XX_CM_CLKSEL_SYS_CLK2_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00cc)
+#define DRA7XX_CM_CLKSEL_VIDEO1_CLK_CLKOUTMUX_OFFSET 0x00d0
+#define DRA7XX_CM_CLKSEL_VIDEO1_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00d0)
+#define DRA7XX_CM_CLKSEL_VIDEO2_CLK_CLKOUTMUX_OFFSET 0x00d4
+#define DRA7XX_CM_CLKSEL_VIDEO2_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00d4)
+#define DRA7XX_CM_CLKSEL_ABE_LP_CLK_OFFSET 0x00d8
+#define DRA7XX_CM_CLKSEL_ABE_LP_CLK DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00d8)
+#define DRA7XX_CM_CLKSEL_ADC_GFCLK_OFFSET 0x00dc
+#define DRA7XX_CM_CLKSEL_ADC_GFCLK DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00dc)
+#define DRA7XX_CM_CLKSEL_EVE_GFCLK_CLKOUTMUX_OFFSET 0x00e0
+#define DRA7XX_CM_CLKSEL_EVE_GFCLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00e0)
+
+/* PRM.MPU_PRM register offsets */
+#define DRA7XX_PM_MPU_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_MPU_PWRSTST_OFFSET 0x0004
+#define DRA7XX_RM_MPU_MPU_CONTEXT_OFFSET 0x0024
+
+/* PRM.DSP1_PRM register offsets */
+#define DRA7XX_PM_DSP1_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_DSP1_PWRSTST_OFFSET 0x0004
+#define DRA7XX_RM_DSP1_RSTCTRL_OFFSET 0x0010
+#define DRA7XX_RM_DSP1_RSTST_OFFSET 0x0014
+#define DRA7XX_RM_DSP1_DSP1_CONTEXT_OFFSET 0x0024
+
+/* PRM.IPU_PRM register offsets */
+#define DRA7XX_PM_IPU_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_IPU_PWRSTST_OFFSET 0x0004
+#define DRA7XX_RM_IPU1_RSTCTRL_OFFSET 0x0010
+#define DRA7XX_RM_IPU1_RSTST_OFFSET 0x0014
+#define DRA7XX_RM_IPU1_IPU1_CONTEXT_OFFSET 0x0024
+#define DRA7XX_PM_IPU_MCASP1_WKDEP_OFFSET 0x0050
+#define DRA7XX_RM_IPU_MCASP1_CONTEXT_OFFSET 0x0054
+#define DRA7XX_PM_IPU_TIMER5_WKDEP_OFFSET 0x0058
+#define DRA7XX_RM_IPU_TIMER5_CONTEXT_OFFSET 0x005c
+#define DRA7XX_PM_IPU_TIMER6_WKDEP_OFFSET 0x0060
+#define DRA7XX_RM_IPU_TIMER6_CONTEXT_OFFSET 0x0064
+#define DRA7XX_PM_IPU_TIMER7_WKDEP_OFFSET 0x0068
+#define DRA7XX_RM_IPU_TIMER7_CONTEXT_OFFSET 0x006c
+#define DRA7XX_PM_IPU_TIMER8_WKDEP_OFFSET 0x0070
+#define DRA7XX_RM_IPU_TIMER8_CONTEXT_OFFSET 0x0074
+#define DRA7XX_PM_IPU_I2C5_WKDEP_OFFSET 0x0078
+#define DRA7XX_RM_IPU_I2C5_CONTEXT_OFFSET 0x007c
+#define DRA7XX_PM_IPU_UART6_WKDEP_OFFSET 0x0080
+#define DRA7XX_RM_IPU_UART6_CONTEXT_OFFSET 0x0084
+
+/* PRM.COREAON_PRM register offsets */
+#define DRA7XX_PM_COREAON_SMARTREFLEX_MPU_WKDEP_OFFSET 0x0000
+#define DRA7XX_RM_COREAON_SMARTREFLEX_MPU_CONTEXT_OFFSET 0x0004
+#define DRA7XX_PM_COREAON_SMARTREFLEX_CORE_WKDEP_OFFSET 0x0010
+#define DRA7XX_RM_COREAON_SMARTREFLEX_CORE_CONTEXT_OFFSET 0x0014
+#define DRA7XX_PM_COREAON_SMARTREFLEX_GPU_WKDEP_OFFSET 0x0030
+#define DRA7XX_RM_COREAON_SMARTREFLEX_GPU_CONTEXT_OFFSET 0x0034
+#define DRA7XX_PM_COREAON_SMARTREFLEX_DSPEVE_WKDEP_OFFSET 0x0040
+#define DRA7XX_RM_COREAON_SMARTREFLEX_DSPEVE_CONTEXT_OFFSET 0x0044
+#define DRA7XX_PM_COREAON_SMARTREFLEX_IVAHD_WKDEP_OFFSET 0x0050
+#define DRA7XX_RM_COREAON_SMARTREFLEX_IVAHD_CONTEXT_OFFSET 0x0054
+#define DRA7XX_RM_COREAON_DUMMY_MODULE1_CONTEXT_OFFSET 0x0084
+#define DRA7XX_RM_COREAON_DUMMY_MODULE2_CONTEXT_OFFSET 0x0094
+#define DRA7XX_RM_COREAON_DUMMY_MODULE3_CONTEXT_OFFSET 0x00a4
+#define DRA7XX_RM_COREAON_DUMMY_MODULE4_CONTEXT_OFFSET 0x00b4
+
+/* PRM.CORE_PRM register offsets */
+#define DRA7XX_PM_CORE_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_CORE_PWRSTST_OFFSET 0x0004
+#define DRA7XX_RM_L3MAIN1_L3_MAIN_1_CONTEXT_OFFSET 0x0024
+#define DRA7XX_RM_L3MAIN1_GPMC_CONTEXT_OFFSET 0x002c
+#define DRA7XX_RM_L3MAIN1_MMU_EDMA_CONTEXT_OFFSET 0x0034
+#define DRA7XX_PM_L3MAIN1_OCMC_RAM1_WKDEP_OFFSET 0x0050
+#define DRA7XX_RM_L3MAIN1_OCMC_RAM1_CONTEXT_OFFSET 0x0054
+#define DRA7XX_PM_L3MAIN1_OCMC_RAM2_WKDEP_OFFSET 0x0058
+#define DRA7XX_RM_L3MAIN1_OCMC_RAM2_CONTEXT_OFFSET 0x005c
+#define DRA7XX_PM_L3MAIN1_OCMC_RAM3_WKDEP_OFFSET 0x0060
+#define DRA7XX_RM_L3MAIN1_OCMC_RAM3_CONTEXT_OFFSET 0x0064
+#define DRA7XX_RM_L3MAIN1_OCMC_ROM_CONTEXT_OFFSET 0x006c
+#define DRA7XX_PM_L3MAIN1_TPCC_WKDEP_OFFSET 0x0070
+#define DRA7XX_RM_L3MAIN1_TPCC_CONTEXT_OFFSET 0x0074
+#define DRA7XX_PM_L3MAIN1_TPTC1_WKDEP_OFFSET 0x0078
+#define DRA7XX_RM_L3MAIN1_TPTC1_CONTEXT_OFFSET 0x007c
+#define DRA7XX_PM_L3MAIN1_TPTC2_WKDEP_OFFSET 0x0080
+#define DRA7XX_RM_L3MAIN1_TPTC2_CONTEXT_OFFSET 0x0084
+#define DRA7XX_RM_L3MAIN1_VCP1_CONTEXT_OFFSET 0x008c
+#define DRA7XX_RM_L3MAIN1_VCP2_CONTEXT_OFFSET 0x0094
+#define DRA7XX_RM_L3MAIN1_SPARE_CME_CONTEXT_OFFSET 0x009c
+#define DRA7XX_RM_L3MAIN1_SPARE_HDMI_CONTEXT_OFFSET 0x00a4
+#define DRA7XX_RM_L3MAIN1_SPARE_ICM_CONTEXT_OFFSET 0x00ac
+#define DRA7XX_RM_L3MAIN1_SPARE_IVA2_CONTEXT_OFFSET 0x00b4
+#define DRA7XX_RM_L3MAIN1_SPARE_SATA2_CONTEXT_OFFSET 0x00bc
+#define DRA7XX_RM_L3MAIN1_SPARE_UNKNOWN4_CONTEXT_OFFSET 0x00c4
+#define DRA7XX_RM_L3MAIN1_SPARE_UNKNOWN5_CONTEXT_OFFSET 0x00cc
+#define DRA7XX_RM_L3MAIN1_SPARE_UNKNOWN6_CONTEXT_OFFSET 0x00d4
+#define DRA7XX_RM_L3MAIN1_SPARE_VIDEOPLL1_CONTEXT_OFFSET 0x00dc
+#define DRA7XX_RM_L3MAIN1_SPARE_VIDEOPLL2_CONTEXT_OFFSET 0x00f4
+#define DRA7XX_RM_L3MAIN1_SPARE_VIDEOPLL3_CONTEXT_OFFSET 0x00fc
+#define DRA7XX_RM_IPU2_RSTCTRL_OFFSET 0x0210
+#define DRA7XX_RM_IPU2_RSTST_OFFSET 0x0214
+#define DRA7XX_RM_IPU2_IPU2_CONTEXT_OFFSET 0x0224
+#define DRA7XX_RM_DMA_DMA_SYSTEM_CONTEXT_OFFSET 0x0324
+#define DRA7XX_RM_EMIF_DMM_CONTEXT_OFFSET 0x0424
+#define DRA7XX_RM_EMIF_EMIF_OCP_FW_CONTEXT_OFFSET 0x042c
+#define DRA7XX_RM_EMIF_EMIF1_CONTEXT_OFFSET 0x0434
+#define DRA7XX_RM_EMIF_EMIF2_CONTEXT_OFFSET 0x043c
+#define DRA7XX_RM_EMIF_EMIF_DLL_CONTEXT_OFFSET 0x0444
+#define DRA7XX_RM_ATL_ATL_CONTEXT_OFFSET 0x0524
+#define DRA7XX_RM_L4CFG_L4_CFG_CONTEXT_OFFSET 0x0624
+#define DRA7XX_RM_L4CFG_SPINLOCK_CONTEXT_OFFSET 0x062c
+#define DRA7XX_RM_L4CFG_MAILBOX1_CONTEXT_OFFSET 0x0634
+#define DRA7XX_RM_L4CFG_SAR_ROM_CONTEXT_OFFSET 0x063c
+#define DRA7XX_RM_L4CFG_OCP2SCP2_CONTEXT_OFFSET 0x0644
+#define DRA7XX_RM_L4CFG_MAILBOX2_CONTEXT_OFFSET 0x064c
+#define DRA7XX_RM_L4CFG_MAILBOX3_CONTEXT_OFFSET 0x0654
+#define DRA7XX_RM_L4CFG_MAILBOX4_CONTEXT_OFFSET 0x065c
+#define DRA7XX_RM_L4CFG_MAILBOX5_CONTEXT_OFFSET 0x0664
+#define DRA7XX_RM_L4CFG_MAILBOX6_CONTEXT_OFFSET 0x066c
+#define DRA7XX_RM_L4CFG_MAILBOX7_CONTEXT_OFFSET 0x0674
+#define DRA7XX_RM_L4CFG_MAILBOX8_CONTEXT_OFFSET 0x067c
+#define DRA7XX_RM_L4CFG_MAILBOX9_CONTEXT_OFFSET 0x0684
+#define DRA7XX_RM_L4CFG_MAILBOX10_CONTEXT_OFFSET 0x068c
+#define DRA7XX_RM_L4CFG_MAILBOX11_CONTEXT_OFFSET 0x0694
+#define DRA7XX_RM_L4CFG_MAILBOX12_CONTEXT_OFFSET 0x069c
+#define DRA7XX_RM_L4CFG_MAILBOX13_CONTEXT_OFFSET 0x06a4
+#define DRA7XX_RM_L4CFG_SPARE_SMARTREFLEX_RTC_CONTEXT_OFFSET 0x06ac
+#define DRA7XX_RM_L4CFG_SPARE_SMARTREFLEX_SDRAM_CONTEXT_OFFSET 0x06b4
+#define DRA7XX_RM_L4CFG_SPARE_SMARTREFLEX_WKUP_CONTEXT_OFFSET 0x06bc
+#define DRA7XX_RM_L4CFG_IO_DELAY_BLOCK_CONTEXT_OFFSET 0x06c4
+#define DRA7XX_RM_L3INSTR_L3_MAIN_2_CONTEXT_OFFSET 0x0724
+#define DRA7XX_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET 0x072c
+#define DRA7XX_RM_L3INSTR_OCP_WP_NOC_CONTEXT_OFFSET 0x0744
+
+/* PRM.IVA_PRM register offsets */
+#define DRA7XX_PM_IVA_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_IVA_PWRSTST_OFFSET 0x0004
+#define DRA7XX_RM_IVA_RSTCTRL_OFFSET 0x0010
+#define DRA7XX_RM_IVA_RSTST_OFFSET 0x0014
+#define DRA7XX_RM_IVA_IVA_CONTEXT_OFFSET 0x0024
+#define DRA7XX_RM_IVA_SL2_CONTEXT_OFFSET 0x002c
+
+/* PRM.CAM_PRM register offsets */
+#define DRA7XX_PM_CAM_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_CAM_PWRSTST_OFFSET 0x0004
+#define DRA7XX_PM_CAM_VIP1_WKDEP_OFFSET 0x0020
+#define DRA7XX_RM_CAM_VIP1_CONTEXT_OFFSET 0x0024
+#define DRA7XX_PM_CAM_VIP2_WKDEP_OFFSET 0x0028
+#define DRA7XX_RM_CAM_VIP2_CONTEXT_OFFSET 0x002c
+#define DRA7XX_PM_CAM_VIP3_WKDEP_OFFSET 0x0030
+#define DRA7XX_RM_CAM_VIP3_CONTEXT_OFFSET 0x0034
+#define DRA7XX_RM_CAM_LVDSRX_CONTEXT_OFFSET 0x003c
+#define DRA7XX_RM_CAM_CSI1_CONTEXT_OFFSET 0x0044
+#define DRA7XX_RM_CAM_CSI2_CONTEXT_OFFSET 0x004c
+
+/* PRM.DSS_PRM register offsets */
+#define DRA7XX_PM_DSS_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_DSS_PWRSTST_OFFSET 0x0004
+#define DRA7XX_PM_DSS_DSS_WKDEP_OFFSET 0x0020
+#define DRA7XX_RM_DSS_DSS_CONTEXT_OFFSET 0x0024
+#define DRA7XX_PM_DSS_DSS2_WKDEP_OFFSET 0x0028
+#define DRA7XX_RM_DSS_BB2D_CONTEXT_OFFSET 0x0034
+#define DRA7XX_RM_DSS_SDVENC_CONTEXT_OFFSET 0x003c
+
+/* PRM.GPU_PRM register offsets */
+#define DRA7XX_PM_GPU_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_GPU_PWRSTST_OFFSET 0x0004
+#define DRA7XX_RM_GPU_GPU_CONTEXT_OFFSET 0x0024
+
+/* PRM.L3INIT_PRM register offsets */
+#define DRA7XX_PM_L3INIT_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_L3INIT_PWRSTST_OFFSET 0x0004
+#define DRA7XX_PM_L3INIT_MMC1_WKDEP_OFFSET 0x0028
+#define DRA7XX_RM_L3INIT_MMC1_CONTEXT_OFFSET 0x002c
+#define DRA7XX_PM_L3INIT_MMC2_WKDEP_OFFSET 0x0030
+#define DRA7XX_RM_L3INIT_MMC2_CONTEXT_OFFSET 0x0034
+#define DRA7XX_PM_L3INIT_USB_OTG_SS2_WKDEP_OFFSET 0x0040
+#define DRA7XX_RM_L3INIT_USB_OTG_SS2_CONTEXT_OFFSET 0x0044
+#define DRA7XX_PM_L3INIT_USB_OTG_SS3_WKDEP_OFFSET 0x0048
+#define DRA7XX_RM_L3INIT_USB_OTG_SS3_CONTEXT_OFFSET 0x004c
+#define DRA7XX_PM_L3INIT_USB_OTG_SS4_WKDEP_OFFSET 0x0050
+#define DRA7XX_RM_L3INIT_USB_OTG_SS4_CONTEXT_OFFSET 0x0054
+#define DRA7XX_RM_L3INIT_MLB_SS_CONTEXT_OFFSET 0x005c
+#define DRA7XX_RM_L3INIT_IEEE1500_2_OCP_CONTEXT_OFFSET 0x007c
+#define DRA7XX_PM_L3INIT_SATA_WKDEP_OFFSET 0x0088
+#define DRA7XX_RM_L3INIT_SATA_CONTEXT_OFFSET 0x008c
+#define DRA7XX_PM_L3INIT_PCIESS1_WKDEP_OFFSET 0x00b0
+#define DRA7XX_RM_L3INIT_PCIESS1_CONTEXT_OFFSET 0x00b4
+#define DRA7XX_PM_L3INIT_PCIESS2_WKDEP_OFFSET 0x00b8
+#define DRA7XX_RM_L3INIT_PCIESS2_CONTEXT_OFFSET 0x00bc
+#define DRA7XX_RM_GMAC_GMAC_CONTEXT_OFFSET 0x00d4
+#define DRA7XX_RM_L3INIT_OCP2SCP1_CONTEXT_OFFSET 0x00e4
+#define DRA7XX_RM_L3INIT_OCP2SCP3_CONTEXT_OFFSET 0x00ec
+#define DRA7XX_PM_L3INIT_USB_OTG_SS1_WKDEP_OFFSET 0x00f0
+#define DRA7XX_RM_L3INIT_USB_OTG_SS1_CONTEXT_OFFSET 0x00f4
+
+/* PRM.L4PER_PRM register offsets */
+#define DRA7XX_PM_L4PER_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_L4PER_PWRSTST_OFFSET 0x0004
+#define DRA7XX_RM_L4PER2_L4PER2_CONTEXT_OFFSET 0x000c
+#define DRA7XX_RM_L4PER3_L4PER3_CONTEXT_OFFSET 0x0014
+#define DRA7XX_RM_L4PER2_PRUSS1_CONTEXT_OFFSET 0x001c
+#define DRA7XX_RM_L4PER2_PRUSS2_CONTEXT_OFFSET 0x0024
+#define DRA7XX_PM_L4PER_TIMER10_WKDEP_OFFSET 0x0028
+#define DRA7XX_RM_L4PER_TIMER10_CONTEXT_OFFSET 0x002c
+#define DRA7XX_PM_L4PER_TIMER11_WKDEP_OFFSET 0x0030
+#define DRA7XX_RM_L4PER_TIMER11_CONTEXT_OFFSET 0x0034
+#define DRA7XX_PM_L4PER_TIMER2_WKDEP_OFFSET 0x0038
+#define DRA7XX_RM_L4PER_TIMER2_CONTEXT_OFFSET 0x003c
+#define DRA7XX_PM_L4PER_TIMER3_WKDEP_OFFSET 0x0040
+#define DRA7XX_RM_L4PER_TIMER3_CONTEXT_OFFSET 0x0044
+#define DRA7XX_PM_L4PER_TIMER4_WKDEP_OFFSET 0x0048
+#define DRA7XX_RM_L4PER_TIMER4_CONTEXT_OFFSET 0x004c
+#define DRA7XX_PM_L4PER_TIMER9_WKDEP_OFFSET 0x0050
+#define DRA7XX_RM_L4PER_TIMER9_CONTEXT_OFFSET 0x0054
+#define DRA7XX_RM_L4PER_ELM_CONTEXT_OFFSET 0x005c
+#define DRA7XX_PM_L4PER_GPIO2_WKDEP_OFFSET 0x0060
+#define DRA7XX_RM_L4PER_GPIO2_CONTEXT_OFFSET 0x0064
+#define DRA7XX_PM_L4PER_GPIO3_WKDEP_OFFSET 0x0068
+#define DRA7XX_RM_L4PER_GPIO3_CONTEXT_OFFSET 0x006c
+#define DRA7XX_PM_L4PER_GPIO4_WKDEP_OFFSET 0x0070
+#define DRA7XX_RM_L4PER_GPIO4_CONTEXT_OFFSET 0x0074
+#define DRA7XX_PM_L4PER_GPIO5_WKDEP_OFFSET 0x0078
+#define DRA7XX_RM_L4PER_GPIO5_CONTEXT_OFFSET 0x007c
+#define DRA7XX_PM_L4PER_GPIO6_WKDEP_OFFSET 0x0080
+#define DRA7XX_RM_L4PER_GPIO6_CONTEXT_OFFSET 0x0084
+#define DRA7XX_RM_L4PER_HDQ1W_CONTEXT_OFFSET 0x008c
+#define DRA7XX_RM_L4PER2_PWMSS2_CONTEXT_OFFSET 0x0094
+#define DRA7XX_RM_L4PER2_PWMSS3_CONTEXT_OFFSET 0x009c
+#define DRA7XX_PM_L4PER_I2C1_WKDEP_OFFSET 0x00a0
+#define DRA7XX_RM_L4PER_I2C1_CONTEXT_OFFSET 0x00a4
+#define DRA7XX_PM_L4PER_I2C2_WKDEP_OFFSET 0x00a8
+#define DRA7XX_RM_L4PER_I2C2_CONTEXT_OFFSET 0x00ac
+#define DRA7XX_PM_L4PER_I2C3_WKDEP_OFFSET 0x00b0
+#define DRA7XX_RM_L4PER_I2C3_CONTEXT_OFFSET 0x00b4
+#define DRA7XX_PM_L4PER_I2C4_WKDEP_OFFSET 0x00b8
+#define DRA7XX_RM_L4PER_I2C4_CONTEXT_OFFSET 0x00bc
+#define DRA7XX_RM_L4PER_L4PER1_CONTEXT_OFFSET 0x00c0
+#define DRA7XX_RM_L4PER2_PWMSS1_CONTEXT_OFFSET 0x00c4
+#define DRA7XX_PM_L4PER_TIMER13_WKDEP_OFFSET 0x00c8
+#define DRA7XX_RM_L4PER3_TIMER13_CONTEXT_OFFSET 0x00cc
+#define DRA7XX_PM_L4PER_TIMER14_WKDEP_OFFSET 0x00d0
+#define DRA7XX_RM_L4PER3_TIMER14_CONTEXT_OFFSET 0x00d4
+#define DRA7XX_PM_L4PER_TIMER15_WKDEP_OFFSET 0x00d8
+#define DRA7XX_RM_L4PER3_TIMER15_CONTEXT_OFFSET 0x00dc
+#define DRA7XX_PM_L4PER_MCSPI1_WKDEP_OFFSET 0x00f0
+#define DRA7XX_RM_L4PER_MCSPI1_CONTEXT_OFFSET 0x00f4
+#define DRA7XX_PM_L4PER_MCSPI2_WKDEP_OFFSET 0x00f8
+#define DRA7XX_RM_L4PER_MCSPI2_CONTEXT_OFFSET 0x00fc
+#define DRA7XX_PM_L4PER_MCSPI3_WKDEP_OFFSET 0x0100
+#define DRA7XX_RM_L4PER_MCSPI3_CONTEXT_OFFSET 0x0104
+#define DRA7XX_PM_L4PER_MCSPI4_WKDEP_OFFSET 0x0108
+#define DRA7XX_RM_L4PER_MCSPI4_CONTEXT_OFFSET 0x010c
+#define DRA7XX_PM_L4PER_GPIO7_WKDEP_OFFSET 0x0110
+#define DRA7XX_RM_L4PER_GPIO7_CONTEXT_OFFSET 0x0114
+#define DRA7XX_PM_L4PER_GPIO8_WKDEP_OFFSET 0x0118
+#define DRA7XX_RM_L4PER_GPIO8_CONTEXT_OFFSET 0x011c
+#define DRA7XX_PM_L4PER_MMC3_WKDEP_OFFSET 0x0120
+#define DRA7XX_RM_L4PER_MMC3_CONTEXT_OFFSET 0x0124
+#define DRA7XX_PM_L4PER_MMC4_WKDEP_OFFSET 0x0128
+#define DRA7XX_RM_L4PER_MMC4_CONTEXT_OFFSET 0x012c
+#define DRA7XX_PM_L4PER_TIMER16_WKDEP_OFFSET 0x0130
+#define DRA7XX_RM_L4PER3_TIMER16_CONTEXT_OFFSET 0x0134
+#define DRA7XX_PM_L4PER2_QSPI_WKDEP_OFFSET 0x0138
+#define DRA7XX_RM_L4PER2_QSPI_CONTEXT_OFFSET 0x013c
+#define DRA7XX_PM_L4PER_UART1_WKDEP_OFFSET 0x0140
+#define DRA7XX_RM_L4PER_UART1_CONTEXT_OFFSET 0x0144
+#define DRA7XX_PM_L4PER_UART2_WKDEP_OFFSET 0x0148
+#define DRA7XX_RM_L4PER_UART2_CONTEXT_OFFSET 0x014c
+#define DRA7XX_PM_L4PER_UART3_WKDEP_OFFSET 0x0150
+#define DRA7XX_RM_L4PER_UART3_CONTEXT_OFFSET 0x0154
+#define DRA7XX_PM_L4PER_UART4_WKDEP_OFFSET 0x0158
+#define DRA7XX_RM_L4PER_UART4_CONTEXT_OFFSET 0x015c
+#define DRA7XX_PM_L4PER2_MCASP2_WKDEP_OFFSET 0x0160
+#define DRA7XX_RM_L4PER2_MCASP2_CONTEXT_OFFSET 0x0164
+#define DRA7XX_PM_L4PER2_MCASP3_WKDEP_OFFSET 0x0168
+#define DRA7XX_RM_L4PER2_MCASP3_CONTEXT_OFFSET 0x016c
+#define DRA7XX_PM_L4PER_UART5_WKDEP_OFFSET 0x0170
+#define DRA7XX_RM_L4PER_UART5_CONTEXT_OFFSET 0x0174
+#define DRA7XX_PM_L4PER2_MCASP5_WKDEP_OFFSET 0x0178
+#define DRA7XX_RM_L4PER2_MCASP5_CONTEXT_OFFSET 0x017c
+#define DRA7XX_PM_L4PER2_MCASP6_WKDEP_OFFSET 0x0180
+#define DRA7XX_RM_L4PER2_MCASP6_CONTEXT_OFFSET 0x0184
+#define DRA7XX_PM_L4PER2_MCASP7_WKDEP_OFFSET 0x0188
+#define DRA7XX_RM_L4PER2_MCASP7_CONTEXT_OFFSET 0x018c
+#define DRA7XX_PM_L4PER2_MCASP8_WKDEP_OFFSET 0x0190
+#define DRA7XX_RM_L4PER2_MCASP8_CONTEXT_OFFSET 0x0194
+#define DRA7XX_PM_L4PER2_MCASP4_WKDEP_OFFSET 0x0198
+#define DRA7XX_RM_L4PER2_MCASP4_CONTEXT_OFFSET 0x019c
+#define DRA7XX_RM_L4SEC_AES1_CONTEXT_OFFSET 0x01a4
+#define DRA7XX_RM_L4SEC_AES2_CONTEXT_OFFSET 0x01ac
+#define DRA7XX_RM_L4SEC_DES3DES_CONTEXT_OFFSET 0x01b4
+#define DRA7XX_RM_L4SEC_FPKA_CONTEXT_OFFSET 0x01bc
+#define DRA7XX_RM_L4SEC_RNG_CONTEXT_OFFSET 0x01c4
+#define DRA7XX_RM_L4SEC_SHA2MD51_CONTEXT_OFFSET 0x01cc
+#define DRA7XX_PM_L4PER2_UART7_WKDEP_OFFSET 0x01d0
+#define DRA7XX_RM_L4PER2_UART7_CONTEXT_OFFSET 0x01d4
+#define DRA7XX_RM_L4SEC_DMA_CRYPTO_CONTEXT_OFFSET 0x01dc
+#define DRA7XX_PM_L4PER2_UART8_WKDEP_OFFSET 0x01e0
+#define DRA7XX_RM_L4PER2_UART8_CONTEXT_OFFSET 0x01e4
+#define DRA7XX_PM_L4PER2_UART9_WKDEP_OFFSET 0x01e8
+#define DRA7XX_RM_L4PER2_UART9_CONTEXT_OFFSET 0x01ec
+#define DRA7XX_PM_L4PER2_DCAN2_WKDEP_OFFSET 0x01f0
+#define DRA7XX_RM_L4PER2_DCAN2_CONTEXT_OFFSET 0x01f4
+#define DRA7XX_RM_L4SEC_SHA2MD52_CONTEXT_OFFSET 0x01fc
+
+/* PRM.CUSTEFUSE_PRM register offsets */
+#define DRA7XX_PM_CUSTEFUSE_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_CUSTEFUSE_PWRSTST_OFFSET 0x0004
+#define DRA7XX_RM_CUSTEFUSE_EFUSE_CTRL_CUST_CONTEXT_OFFSET 0x0024
+
+/* PRM.WKUPAON_PRM register offsets */
+#define DRA7XX_RM_WKUPAON_L4_WKUP_CONTEXT_OFFSET 0x0000
+#define DRA7XX_PM_WKUPAON_WD_TIMER1_WKDEP_OFFSET 0x0004
+#define DRA7XX_RM_WKUPAON_WD_TIMER1_CONTEXT_OFFSET 0x0008
+#define DRA7XX_PM_WKUPAON_WD_TIMER2_WKDEP_OFFSET 0x000c
+#define DRA7XX_RM_WKUPAON_WD_TIMER2_CONTEXT_OFFSET 0x0010
+#define DRA7XX_PM_WKUPAON_GPIO1_WKDEP_OFFSET 0x0014
+#define DRA7XX_RM_WKUPAON_GPIO1_CONTEXT_OFFSET 0x0018
+#define DRA7XX_PM_WKUPAON_TIMER1_WKDEP_OFFSET 0x001c
+#define DRA7XX_RM_WKUPAON_TIMER1_CONTEXT_OFFSET 0x0020
+#define DRA7XX_PM_WKUPAON_TIMER12_WKDEP_OFFSET 0x0024
+#define DRA7XX_RM_WKUPAON_TIMER12_CONTEXT_OFFSET 0x0028
+#define DRA7XX_RM_WKUPAON_COUNTER_32K_CONTEXT_OFFSET 0x0030
+#define DRA7XX_RM_WKUPAON_SAR_RAM_CONTEXT_OFFSET 0x0040
+#define DRA7XX_PM_WKUPAON_KBD_WKDEP_OFFSET 0x0054
+#define DRA7XX_RM_WKUPAON_KBD_CONTEXT_OFFSET 0x0058
+#define DRA7XX_PM_WKUPAON_UART10_WKDEP_OFFSET 0x005c
+#define DRA7XX_RM_WKUPAON_UART10_CONTEXT_OFFSET 0x0060
+#define DRA7XX_PM_WKUPAON_DCAN1_WKDEP_OFFSET 0x0064
+#define DRA7XX_RM_WKUPAON_DCAN1_CONTEXT_OFFSET 0x0068
+#define DRA7XX_PM_WKUPAON_ADC_WKDEP_OFFSET 0x007c
+#define DRA7XX_RM_WKUPAON_ADC_CONTEXT_OFFSET 0x0080
+#define DRA7XX_RM_WKUPAON_SPARE_SAFETY1_CONTEXT_OFFSET 0x0090
+#define DRA7XX_RM_WKUPAON_SPARE_SAFETY2_CONTEXT_OFFSET 0x0098
+#define DRA7XX_RM_WKUPAON_SPARE_SAFETY3_CONTEXT_OFFSET 0x00a0
+#define DRA7XX_RM_WKUPAON_SPARE_SAFETY4_CONTEXT_OFFSET 0x00a8
+#define DRA7XX_RM_WKUPAON_SPARE_UNKNOWN2_CONTEXT_OFFSET 0x00b0
+#define DRA7XX_RM_WKUPAON_SPARE_UNKNOWN3_CONTEXT_OFFSET 0x00b8
+
+/* PRM.WKUPAON_CM register offsets */
+#define DRA7XX_CM_WKUPAON_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_WKUPAON_L4_WKUP_CLKCTRL_OFFSET 0x0020
+#define DRA7XX_CM_WKUPAON_L4_WKUP_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0020)
+#define DRA7XX_CM_WKUPAON_WD_TIMER1_CLKCTRL_OFFSET 0x0028
+#define DRA7XX_CM_WKUPAON_WD_TIMER1_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0028)
+#define DRA7XX_CM_WKUPAON_WD_TIMER2_CLKCTRL_OFFSET 0x0030
+#define DRA7XX_CM_WKUPAON_WD_TIMER2_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0030)
+#define DRA7XX_CM_WKUPAON_GPIO1_CLKCTRL_OFFSET 0x0038
+#define DRA7XX_CM_WKUPAON_GPIO1_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0038)
+#define DRA7XX_CM_WKUPAON_TIMER1_CLKCTRL_OFFSET 0x0040
+#define DRA7XX_CM_WKUPAON_TIMER1_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0040)
+#define DRA7XX_CM_WKUPAON_TIMER12_CLKCTRL_OFFSET 0x0048
+#define DRA7XX_CM_WKUPAON_TIMER12_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0048)
+#define DRA7XX_CM_WKUPAON_COUNTER_32K_CLKCTRL_OFFSET 0x0050
+#define DRA7XX_CM_WKUPAON_COUNTER_32K_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0050)
+#define DRA7XX_CM_WKUPAON_SAR_RAM_CLKCTRL_OFFSET 0x0060
+#define DRA7XX_CM_WKUPAON_SAR_RAM_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0060)
+#define DRA7XX_CM_WKUPAON_KBD_CLKCTRL_OFFSET 0x0078
+#define DRA7XX_CM_WKUPAON_KBD_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0078)
+#define DRA7XX_CM_WKUPAON_UART10_CLKCTRL_OFFSET 0x0080
+#define DRA7XX_CM_WKUPAON_UART10_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0080)
+#define DRA7XX_CM_WKUPAON_DCAN1_CLKCTRL_OFFSET 0x0088
+#define DRA7XX_CM_WKUPAON_DCAN1_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0088)
+#define DRA7XX_CM_WKUPAON_SCRM_CLKCTRL_OFFSET 0x0090
+#define DRA7XX_CM_WKUPAON_SCRM_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0090)
+#define DRA7XX_CM_WKUPAON_IO_SRCOMP_CLKCTRL_OFFSET 0x0098
+#define DRA7XX_CM_WKUPAON_IO_SRCOMP_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0098)
+#define DRA7XX_CM_WKUPAON_ADC_CLKCTRL_OFFSET 0x00a0
+#define DRA7XX_CM_WKUPAON_ADC_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x00a0)
+#define DRA7XX_CM_WKUPAON_SPARE_SAFETY1_CLKCTRL_OFFSET 0x00b0
+#define DRA7XX_CM_WKUPAON_SPARE_SAFETY1_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x00b0)
+#define DRA7XX_CM_WKUPAON_SPARE_SAFETY2_CLKCTRL_OFFSET 0x00b8
+#define DRA7XX_CM_WKUPAON_SPARE_SAFETY2_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x00b8)
+#define DRA7XX_CM_WKUPAON_SPARE_SAFETY3_CLKCTRL_OFFSET 0x00c0
+#define DRA7XX_CM_WKUPAON_SPARE_SAFETY3_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x00c0)
+#define DRA7XX_CM_WKUPAON_SPARE_SAFETY4_CLKCTRL_OFFSET 0x00c8
+#define DRA7XX_CM_WKUPAON_SPARE_SAFETY4_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x00c8)
+#define DRA7XX_CM_WKUPAON_SPARE_UNKNOWN2_CLKCTRL_OFFSET 0x00d0
+#define DRA7XX_CM_WKUPAON_SPARE_UNKNOWN2_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x00d0)
+#define DRA7XX_CM_WKUPAON_SPARE_UNKNOWN3_CLKCTRL_OFFSET 0x00d8
+#define DRA7XX_CM_WKUPAON_SPARE_UNKNOWN3_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x00d8)
+
+/* PRM.EMU_PRM register offsets */
+#define DRA7XX_PM_EMU_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_EMU_PWRSTST_OFFSET 0x0004
+#define DRA7XX_RM_EMU_DEBUGSS_CONTEXT_OFFSET 0x0024
+
+/* PRM.EMU_CM register offsets */
+#define DRA7XX_CM_EMU_CLKSTCTRL_OFFSET 0x0000
+#define DRA7XX_CM_EMU_DEBUGSS_CLKCTRL_OFFSET 0x0004
+#define DRA7XX_CM_EMU_DEBUGSS_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_EMU_CM_INST, 0x0004)
+#define DRA7XX_CM_EMU_DYNAMICDEP_OFFSET 0x0008
+#define DRA7XX_CM_EMU_MPU_EMU_DBG_CLKCTRL_OFFSET 0x000c
+#define DRA7XX_CM_EMU_MPU_EMU_DBG_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_EMU_CM_INST, 0x000c)
+
+/* PRM.DSP2_PRM register offsets */
+#define DRA7XX_PM_DSP2_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_DSP2_PWRSTST_OFFSET 0x0004
+#define DRA7XX_RM_DSP2_RSTCTRL_OFFSET 0x0010
+#define DRA7XX_RM_DSP2_RSTST_OFFSET 0x0014
+#define DRA7XX_RM_DSP2_DSP2_CONTEXT_OFFSET 0x0024
+
+/* PRM.EVE1_PRM register offsets */
+#define DRA7XX_PM_EVE1_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_EVE1_PWRSTST_OFFSET 0x0004
+#define DRA7XX_RM_EVE1_RSTCTRL_OFFSET 0x0010
+#define DRA7XX_RM_EVE1_RSTST_OFFSET 0x0014
+#define DRA7XX_PM_EVE1_EVE1_WKDEP_OFFSET 0x0020
+#define DRA7XX_RM_EVE1_EVE1_CONTEXT_OFFSET 0x0024
+
+/* PRM.EVE2_PRM register offsets */
+#define DRA7XX_PM_EVE2_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_EVE2_PWRSTST_OFFSET 0x0004
+#define DRA7XX_RM_EVE2_RSTCTRL_OFFSET 0x0010
+#define DRA7XX_RM_EVE2_RSTST_OFFSET 0x0014
+#define DRA7XX_PM_EVE2_EVE2_WKDEP_OFFSET 0x0020
+#define DRA7XX_RM_EVE2_EVE2_CONTEXT_OFFSET 0x0024
+
+/* PRM.EVE3_PRM register offsets */
+#define DRA7XX_PM_EVE3_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_EVE3_PWRSTST_OFFSET 0x0004
+#define DRA7XX_RM_EVE3_RSTCTRL_OFFSET 0x0010
+#define DRA7XX_RM_EVE3_RSTST_OFFSET 0x0014
+#define DRA7XX_PM_EVE3_EVE3_WKDEP_OFFSET 0x0020
+#define DRA7XX_RM_EVE3_EVE3_CONTEXT_OFFSET 0x0024
+
+/* PRM.EVE4_PRM register offsets */
+#define DRA7XX_PM_EVE4_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_EVE4_PWRSTST_OFFSET 0x0004
+#define DRA7XX_RM_EVE4_RSTCTRL_OFFSET 0x0010
+#define DRA7XX_RM_EVE4_RSTST_OFFSET 0x0014
+#define DRA7XX_PM_EVE4_EVE4_WKDEP_OFFSET 0x0020
+#define DRA7XX_RM_EVE4_EVE4_CONTEXT_OFFSET 0x0024
+
+/* PRM.RTC_PRM register offsets */
+#define DRA7XX_PM_RTC_RTCSS_WKDEP_OFFSET 0x0000
+#define DRA7XX_RM_RTC_RTCSS_CONTEXT_OFFSET 0x0004
+
+/* PRM.VPE_PRM register offsets */
+#define DRA7XX_PM_VPE_PWRSTCTRL_OFFSET 0x0000
+#define DRA7XX_PM_VPE_PWRSTST_OFFSET 0x0004
+#define DRA7XX_PM_VPE_VPE_WKDEP_OFFSET 0x0020
+#define DRA7XX_RM_VPE_VPE_CONTEXT_OFFSET 0x0024
+
+/* PRM.DEVICE_PRM register offsets */
+#define DRA7XX_PRM_RSTCTRL_OFFSET 0x0000
+#define DRA7XX_PRM_RSTST_OFFSET 0x0004
+#define DRA7XX_PRM_RSTTIME_OFFSET 0x0008
+#define DRA7XX_PRM_CLKREQCTRL_OFFSET 0x000c
+#define DRA7XX_PRM_VOLTCTRL_OFFSET 0x0010
+#define DRA7XX_PRM_PWRREQCTRL_OFFSET 0x0014
+#define DRA7XX_PRM_PSCON_COUNT_OFFSET 0x0018
+#define DRA7XX_PRM_IO_COUNT_OFFSET 0x001c
+#define DRA7XX_PRM_IO_PMCTRL_OFFSET 0x0020
+#define DRA7XX_PRM_VOLTSETUP_WARMRESET_OFFSET 0x0024
+#define DRA7XX_PRM_VOLTSETUP_CORE_OFF_OFFSET 0x0028
+#define DRA7XX_PRM_VOLTSETUP_MPU_OFF_OFFSET 0x002c
+#define DRA7XX_PRM_VOLTSETUP_MM_OFF_OFFSET 0x0030
+#define DRA7XX_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET 0x0034
+#define DRA7XX_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET 0x0038
+#define DRA7XX_PRM_VOLTSETUP_MM_RET_SLEEP_OFFSET 0x003c
+#define DRA7XX_PRM_SRAM_COUNT_OFFSET 0x00bc
+#define DRA7XX_PRM_SRAM_WKUP_SETUP_OFFSET 0x00c0
+#define DRA7XX_PRM_SLDO_CORE_SETUP_OFFSET 0x00c4
+#define DRA7XX_PRM_SLDO_CORE_CTRL_OFFSET 0x00c8
+#define DRA7XX_PRM_SLDO_MPU_SETUP_OFFSET 0x00cc
+#define DRA7XX_PRM_SLDO_MPU_CTRL_OFFSET 0x00d0
+#define DRA7XX_PRM_SLDO_GPU_SETUP_OFFSET 0x00d4
+#define DRA7XX_PRM_SLDO_GPU_CTRL_OFFSET 0x00d8
+#define DRA7XX_PRM_ABBLDO_MPU_SETUP_OFFSET 0x00dc
+#define DRA7XX_PRM_ABBLDO_MPU_CTRL_OFFSET 0x00e0
+#define DRA7XX_PRM_ABBLDO_GPU_SETUP_OFFSET 0x00e4
+#define DRA7XX_PRM_ABBLDO_GPU_CTRL_OFFSET 0x00e8
+#define DRA7XX_PRM_BANDGAP_SETUP_OFFSET 0x00ec
+#define DRA7XX_PRM_DEVICE_OFF_CTRL_OFFSET 0x00f0
+#define DRA7XX_PRM_PHASE1_CNDP_OFFSET 0x00f4
+#define DRA7XX_PRM_PHASE2A_CNDP_OFFSET 0x00f8
+#define DRA7XX_PRM_PHASE2B_CNDP_OFFSET 0x00fc
+#define DRA7XX_PRM_MODEM_IF_CTRL_OFFSET 0x0100
+#define DRA7XX_PRM_VOLTST_MPU_OFFSET 0x0110
+#define DRA7XX_PRM_VOLTST_MM_OFFSET 0x0114
+#define DRA7XX_PRM_SLDO_DSPEVE_SETUP_OFFSET 0x0118
+#define DRA7XX_PRM_SLDO_IVA_SETUP_OFFSET 0x011c
+#define DRA7XX_PRM_ABBLDO_DSPEVE_CTRL_OFFSET 0x0120
+#define DRA7XX_PRM_ABBLDO_IVA_CTRL_OFFSET 0x0124
+#define DRA7XX_PRM_SLDO_DSPEVE_CTRL_OFFSET 0x0128
+#define DRA7XX_PRM_SLDO_IVA_CTRL_OFFSET 0x012c
+#define DRA7XX_PRM_ABBLDO_DSPEVE_SETUP_OFFSET 0x0130
+#define DRA7XX_PRM_ABBLDO_IVA_SETUP_OFFSET 0x0134
+
+#endif
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
new file mode 100644
index 000000000..7add7994d
--- /dev/null
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -0,0 +1,817 @@
+/*
+ * OMAP2+ common Power & Reset Management (PRM) IP block functions
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Tero Kristo <t-kristo@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.
+ *
+ *
+ * For historical purposes, the API used to configure the PRM
+ * interrupt handler refers to it as the "PRCM interrupt." The
+ * underlying registers are located in the PRM on OMAP3/4.
+ *
+ * XXX This code should eventually be moved to a PRM driver.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/ti.h>
+
+#include "soc.h"
+#include "prm2xxx_3xxx.h"
+#include "prm2xxx.h"
+#include "prm3xxx.h"
+#include "prm33xx.h"
+#include "prm44xx.h"
+#include "prm54xx.h"
+#include "prm7xx.h"
+#include "prcm43xx.h"
+#include "common.h"
+#include "clock.h"
+#include "cm.h"
+#include "control.h"
+
+/*
+ * OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs
+ * XXX this is technically not needed, since
+ * omap_prcm_register_chain_handler() could allocate this based on the
+ * actual amount of memory needed for the SoC
+ */
+#define OMAP_PRCM_MAX_NR_PENDING_REG 2
+
+/*
+ * prcm_irq_chips: an array of all of the "generic IRQ chips" in use
+ * by the PRCM interrupt handler code. There will be one 'chip' per
+ * PRM_{IRQSTATUS,IRQENABLE}_MPU register pair. (So OMAP3 will have
+ * one "chip" and OMAP4 will have two.)
+ */
+static struct irq_chip_generic **prcm_irq_chips;
+
+/*
+ * prcm_irq_setup: the PRCM IRQ parameters for the hardware the code
+ * is currently running on. Defined and passed by initialization code
+ * that calls omap_prcm_register_chain_handler().
+ */
+static struct omap_prcm_irq_setup *prcm_irq_setup;
+
+/* prm_base: base virtual address of the PRM IP block */
+void __iomem *prm_base;
+
+u16 prm_features;
+
+/*
+ * prm_ll_data: function pointers to SoC-specific implementations of
+ * common PRM functions
+ */
+static struct prm_ll_data null_prm_ll_data;
+static struct prm_ll_data *prm_ll_data = &null_prm_ll_data;
+
+/* Private functions */
+
+/*
+ * Move priority events from events to priority_events array
+ */
+static void omap_prcm_events_filter_priority(unsigned long *events,
+ unsigned long *priority_events)
+{
+ int i;
+
+ for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
+ priority_events[i] =
+ events[i] & prcm_irq_setup->priority_mask[i];
+ events[i] ^= priority_events[i];
+ }
+}
+
+/*
+ * PRCM Interrupt Handler
+ *
+ * This is a common handler for the OMAP PRCM interrupts. Pending
+ * interrupts are detected by a call to prcm_pending_events and
+ * dispatched accordingly. Clearing of the wakeup events should be
+ * done by the SoC specific individual handlers.
+ */
+static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned long pending[OMAP_PRCM_MAX_NR_PENDING_REG];
+ unsigned long priority_pending[OMAP_PRCM_MAX_NR_PENDING_REG];
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ unsigned int virtirq;
+ int nr_irq = prcm_irq_setup->nr_regs * 32;
+
+ /*
+ * If we are suspended, mask all interrupts from PRCM level,
+ * this does not ack them, and they will be pending until we
+ * re-enable the interrupts, at which point the
+ * omap_prcm_irq_handler will be executed again. The
+ * _save_and_clear_irqen() function must ensure that the PRM
+ * write to disable all IRQs has reached the PRM before
+ * returning, or spurious PRCM interrupts may occur during
+ * suspend.
+ */
+ if (prcm_irq_setup->suspended) {
+ prcm_irq_setup->save_and_clear_irqen(prcm_irq_setup->saved_mask);
+ prcm_irq_setup->suspend_save_flag = true;
+ }
+
+ /*
+ * Loop until all pending irqs are handled, since
+ * generic_handle_irq() can cause new irqs to come
+ */
+ while (!prcm_irq_setup->suspended) {
+ prcm_irq_setup->read_pending_irqs(pending);
+
+ /* No bit set, then all IRQs are handled */
+ if (find_first_bit(pending, nr_irq) >= nr_irq)
+ break;
+
+ omap_prcm_events_filter_priority(pending, priority_pending);
+
+ /*
+ * Loop on all currently pending irqs so that new irqs
+ * cannot starve previously pending irqs
+ */
+
+ /* Serve priority events first */
+ for_each_set_bit(virtirq, priority_pending, nr_irq)
+ generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
+
+ /* Serve normal events next */
+ for_each_set_bit(virtirq, pending, nr_irq)
+ generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
+ }
+ if (chip->irq_ack)
+ chip->irq_ack(&desc->irq_data);
+ if (chip->irq_eoi)
+ chip->irq_eoi(&desc->irq_data);
+ chip->irq_unmask(&desc->irq_data);
+
+ prcm_irq_setup->ocp_barrier(); /* avoid spurious IRQs */
+}
+
+/* Public functions */
+
+/**
+ * omap_prcm_event_to_irq - given a PRCM event name, returns the
+ * corresponding IRQ on which the handler should be registered
+ * @name: name of the PRCM interrupt bit to look up - see struct omap_prcm_irq
+ *
+ * Returns the Linux internal IRQ ID corresponding to @name upon success,
+ * or -ENOENT upon failure.
+ */
+int omap_prcm_event_to_irq(const char *name)
+{
+ int i;
+
+ if (!prcm_irq_setup || !name)
+ return -ENOENT;
+
+ for (i = 0; i < prcm_irq_setup->nr_irqs; i++)
+ if (!strcmp(prcm_irq_setup->irqs[i].name, name))
+ return prcm_irq_setup->base_irq +
+ prcm_irq_setup->irqs[i].offset;
+
+ return -ENOENT;
+}
+
+/**
+ * omap_prcm_irq_cleanup - reverses memory allocated and other steps
+ * done by omap_prcm_register_chain_handler()
+ *
+ * No return value.
+ */
+void omap_prcm_irq_cleanup(void)
+{
+ unsigned int irq;
+ int i;
+
+ if (!prcm_irq_setup) {
+ pr_err("PRCM: IRQ handler not initialized; cannot cleanup\n");
+ return;
+ }
+
+ if (prcm_irq_chips) {
+ for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
+ if (prcm_irq_chips[i])
+ irq_remove_generic_chip(prcm_irq_chips[i],
+ 0xffffffff, 0, 0);
+ prcm_irq_chips[i] = NULL;
+ }
+ kfree(prcm_irq_chips);
+ prcm_irq_chips = NULL;
+ }
+
+ kfree(prcm_irq_setup->saved_mask);
+ prcm_irq_setup->saved_mask = NULL;
+
+ kfree(prcm_irq_setup->priority_mask);
+ prcm_irq_setup->priority_mask = NULL;
+
+ if (prcm_irq_setup->xlate_irq)
+ irq = prcm_irq_setup->xlate_irq(prcm_irq_setup->irq);
+ else
+ irq = prcm_irq_setup->irq;
+ irq_set_chained_handler(irq, NULL);
+
+ if (prcm_irq_setup->base_irq > 0)
+ irq_free_descs(prcm_irq_setup->base_irq,
+ prcm_irq_setup->nr_regs * 32);
+ prcm_irq_setup->base_irq = 0;
+}
+
+void omap_prcm_irq_prepare(void)
+{
+ prcm_irq_setup->suspended = true;
+}
+
+void omap_prcm_irq_complete(void)
+{
+ prcm_irq_setup->suspended = false;
+
+ /* If we have not saved the masks, do not attempt to restore */
+ if (!prcm_irq_setup->suspend_save_flag)
+ return;
+
+ prcm_irq_setup->suspend_save_flag = false;
+
+ /*
+ * Re-enable all masked PRCM irq sources, this causes the PRCM
+ * interrupt to fire immediately if the events were masked
+ * previously in the chain handler
+ */
+ prcm_irq_setup->restore_irqen(prcm_irq_setup->saved_mask);
+}
+
+/**
+ * omap_prcm_register_chain_handler - initializes the prcm chained interrupt
+ * handler based on provided parameters
+ * @irq_setup: hardware data about the underlying PRM/PRCM
+ *
+ * Set up the PRCM chained interrupt handler on the PRCM IRQ. Sets up
+ * one generic IRQ chip per PRM interrupt status/enable register pair.
+ * Returns 0 upon success, -EINVAL if called twice or if invalid
+ * arguments are passed, or -ENOMEM on any other error.
+ */
+int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
+{
+ int nr_regs;
+ u32 mask[OMAP_PRCM_MAX_NR_PENDING_REG];
+ int offset, i;
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+ unsigned int irq;
+
+ if (!irq_setup)
+ return -EINVAL;
+
+ nr_regs = irq_setup->nr_regs;
+
+ if (prcm_irq_setup) {
+ pr_err("PRCM: already initialized; won't reinitialize\n");
+ return -EINVAL;
+ }
+
+ if (nr_regs > OMAP_PRCM_MAX_NR_PENDING_REG) {
+ pr_err("PRCM: nr_regs too large\n");
+ return -EINVAL;
+ }
+
+ prcm_irq_setup = irq_setup;
+
+ prcm_irq_chips = kzalloc(sizeof(void *) * nr_regs, GFP_KERNEL);
+ prcm_irq_setup->saved_mask = kzalloc(sizeof(u32) * nr_regs, GFP_KERNEL);
+ prcm_irq_setup->priority_mask = kzalloc(sizeof(u32) * nr_regs,
+ GFP_KERNEL);
+
+ if (!prcm_irq_chips || !prcm_irq_setup->saved_mask ||
+ !prcm_irq_setup->priority_mask) {
+ pr_err("PRCM: kzalloc failed\n");
+ goto err;
+ }
+
+ memset(mask, 0, sizeof(mask));
+
+ for (i = 0; i < irq_setup->nr_irqs; i++) {
+ offset = irq_setup->irqs[i].offset;
+ mask[offset >> 5] |= 1 << (offset & 0x1f);
+ if (irq_setup->irqs[i].priority)
+ irq_setup->priority_mask[offset >> 5] |=
+ 1 << (offset & 0x1f);
+ }
+
+ if (irq_setup->xlate_irq)
+ irq = irq_setup->xlate_irq(irq_setup->irq);
+ else
+ irq = irq_setup->irq;
+ irq_set_chained_handler(irq, omap_prcm_irq_handler);
+
+ irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32,
+ 0);
+
+ if (irq_setup->base_irq < 0) {
+ pr_err("PRCM: failed to allocate irq descs: %d\n",
+ irq_setup->base_irq);
+ goto err;
+ }
+
+ for (i = 0; i < irq_setup->nr_regs; i++) {
+ gc = irq_alloc_generic_chip("PRCM", 1,
+ irq_setup->base_irq + i * 32, prm_base,
+ handle_level_irq);
+
+ if (!gc) {
+ pr_err("PRCM: failed to allocate generic chip\n");
+ goto err;
+ }
+ 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_setup->ack + i * 4;
+ ct->regs.mask = irq_setup->mask + i * 4;
+
+ irq_setup_generic_chip(gc, mask[i], 0, IRQ_NOREQUEST, 0);
+ prcm_irq_chips[i] = gc;
+ }
+
+ if (of_have_populated_dt()) {
+ int irq = omap_prcm_event_to_irq("io");
+ omap_pcs_legacy_init(irq, irq_setup->reconfigure_io_chain);
+ }
+
+ return 0;
+
+err:
+ omap_prcm_irq_cleanup();
+ return -ENOMEM;
+}
+
+/**
+ * omap2_set_globals_prm - set the PRM base address (for early use)
+ * @prm: PRM base virtual address
+ *
+ * XXX Will be replaced when the PRM/CM drivers are completed.
+ */
+void __init omap2_set_globals_prm(void __iomem *prm)
+{
+ prm_base = prm;
+}
+
+/**
+ * prm_read_reset_sources - return the sources of the SoC's last reset
+ *
+ * Return a u32 bitmask representing the reset sources that caused the
+ * SoC to reset. The low-level per-SoC functions called by this
+ * function remap the SoC-specific reset source bits into an
+ * OMAP-common set of reset source bits, defined in
+ * arch/arm/mach-omap2/prm.h. Returns the standardized reset source
+ * u32 bitmask from the hardware upon success, or returns (1 <<
+ * OMAP_UNKNOWN_RST_SRC_ID_SHIFT) if no low-level read_reset_sources()
+ * function was registered.
+ */
+u32 prm_read_reset_sources(void)
+{
+ u32 ret = 1 << OMAP_UNKNOWN_RST_SRC_ID_SHIFT;
+
+ if (prm_ll_data->read_reset_sources)
+ ret = prm_ll_data->read_reset_sources();
+ else
+ WARN_ONCE(1, "prm: %s: no mapping function defined for reset sources\n", __func__);
+
+ return ret;
+}
+
+/**
+ * prm_was_any_context_lost_old - was device context lost? (old API)
+ * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
+ * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
+ * @idx: CONTEXT register offset
+ *
+ * Return 1 if any bits were set in the *_CONTEXT_* register
+ * identified by (@part, @inst, @idx), which means that some context
+ * was lost for that module; otherwise, return 0. XXX Deprecated;
+ * callers need to use a less-SoC-dependent way to identify hardware
+ * IP blocks.
+ */
+bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
+{
+ bool ret = true;
+
+ if (prm_ll_data->was_any_context_lost_old)
+ ret = prm_ll_data->was_any_context_lost_old(part, inst, idx);
+ else
+ WARN_ONCE(1, "prm: %s: no mapping function defined\n",
+ __func__);
+
+ return ret;
+}
+
+/**
+ * prm_clear_context_lost_flags_old - clear context loss flags (old API)
+ * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
+ * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
+ * @idx: CONTEXT register offset
+ *
+ * Clear hardware context loss bits for the module identified by
+ * (@part, @inst, @idx). No return value. XXX Deprecated; callers
+ * need to use a less-SoC-dependent way to identify hardware IP
+ * blocks.
+ */
+void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx)
+{
+ if (prm_ll_data->clear_context_loss_flags_old)
+ prm_ll_data->clear_context_loss_flags_old(part, inst, idx);
+ else
+ WARN_ONCE(1, "prm: %s: no mapping function defined\n",
+ __func__);
+}
+
+/**
+ * omap_prm_assert_hardreset - assert hardreset for an IP block
+ * @shift: register bit shift corresponding to the reset line
+ * @part: PRM partition
+ * @prm_mod: PRM submodule base or instance offset
+ * @offset: register offset
+ *
+ * Asserts a hardware reset line for an IP block.
+ */
+int omap_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod, u16 offset)
+{
+ if (!prm_ll_data->assert_hardreset) {
+ WARN_ONCE(1, "prm: %s: no mapping function defined\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return prm_ll_data->assert_hardreset(shift, part, prm_mod, offset);
+}
+
+/**
+ * omap_prm_deassert_hardreset - deassert hardreset for an IP block
+ * @shift: register bit shift corresponding to the reset line
+ * @st_shift: reset status bit shift corresponding to the reset line
+ * @part: PRM partition
+ * @prm_mod: PRM submodule base or instance offset
+ * @offset: register offset
+ * @st_offset: status register offset
+ *
+ * Deasserts a hardware reset line for an IP block.
+ */
+int omap_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 prm_mod,
+ u16 offset, u16 st_offset)
+{
+ if (!prm_ll_data->deassert_hardreset) {
+ WARN_ONCE(1, "prm: %s: no mapping function defined\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return prm_ll_data->deassert_hardreset(shift, st_shift, part, prm_mod,
+ offset, st_offset);
+}
+
+/**
+ * omap_prm_is_hardreset_asserted - check the hardreset status for an IP block
+ * @shift: register bit shift corresponding to the reset line
+ * @part: PRM partition
+ * @prm_mod: PRM submodule base or instance offset
+ * @offset: register offset
+ *
+ * Checks if a hardware reset line for an IP block is enabled or not.
+ */
+int omap_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset)
+{
+ if (!prm_ll_data->is_hardreset_asserted) {
+ WARN_ONCE(1, "prm: %s: no mapping function defined\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return prm_ll_data->is_hardreset_asserted(shift, part, prm_mod, offset);
+}
+
+/**
+ * omap_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
+ *
+ * Clear any previously-latched I/O wakeup events and ensure that the
+ * I/O wakeup gates are aligned with the current mux settings.
+ * Calls SoC specific I/O chain reconfigure function if available,
+ * otherwise does nothing.
+ */
+void omap_prm_reconfigure_io_chain(void)
+{
+ if (!prcm_irq_setup || !prcm_irq_setup->reconfigure_io_chain)
+ return;
+
+ prcm_irq_setup->reconfigure_io_chain();
+}
+
+/**
+ * omap_prm_reset_system - trigger global SW reset
+ *
+ * Triggers SoC specific global warm reset to reboot the device.
+ */
+void omap_prm_reset_system(void)
+{
+ if (!prm_ll_data->reset_system) {
+ WARN_ONCE(1, "prm: %s: no mapping function defined\n",
+ __func__);
+ return;
+ }
+
+ prm_ll_data->reset_system();
+
+ while (1)
+ cpu_relax();
+}
+
+/**
+ * omap_prm_clear_mod_irqs - clear wake-up events from PRCM interrupt
+ * @module: PRM module to clear wakeups from
+ * @regs: register to clear
+ * @wkst_mask: wkst bits to clear
+ *
+ * Clears any wakeup events for the module and register set defined.
+ * Uses SoC specific implementation to do the actual wakeup status
+ * clearing.
+ */
+int omap_prm_clear_mod_irqs(s16 module, u8 regs, u32 wkst_mask)
+{
+ if (!prm_ll_data->clear_mod_irqs) {
+ WARN_ONCE(1, "prm: %s: no mapping function defined\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return prm_ll_data->clear_mod_irqs(module, regs, wkst_mask);
+}
+
+/**
+ * omap_prm_vp_check_txdone - check voltage processor TX done status
+ *
+ * Checks if voltage processor transmission has been completed.
+ * Returns non-zero if a transmission has completed, 0 otherwise.
+ */
+u32 omap_prm_vp_check_txdone(u8 vp_id)
+{
+ if (!prm_ll_data->vp_check_txdone) {
+ WARN_ONCE(1, "prm: %s: no mapping function defined\n",
+ __func__);
+ return 0;
+ }
+
+ return prm_ll_data->vp_check_txdone(vp_id);
+}
+
+/**
+ * omap_prm_vp_clear_txdone - clears voltage processor TX done status
+ *
+ * Clears the status bit for completed voltage processor transmission
+ * returned by prm_vp_check_txdone.
+ */
+void omap_prm_vp_clear_txdone(u8 vp_id)
+{
+ if (!prm_ll_data->vp_clear_txdone) {
+ WARN_ONCE(1, "prm: %s: no mapping function defined\n",
+ __func__);
+ return;
+ }
+
+ prm_ll_data->vp_clear_txdone(vp_id);
+}
+
+/**
+ * prm_register - register per-SoC low-level data with the PRM
+ * @pld: low-level per-SoC OMAP PRM data & function pointers to register
+ *
+ * Register per-SoC low-level OMAP PRM data and function pointers with
+ * the OMAP PRM common interface. The caller must keep the data
+ * pointed to by @pld valid until it calls prm_unregister() and
+ * it returns successfully. Returns 0 upon success, -EINVAL if @pld
+ * is NULL, or -EEXIST if prm_register() has already been called
+ * without an intervening prm_unregister().
+ */
+int prm_register(struct prm_ll_data *pld)
+{
+ if (!pld)
+ return -EINVAL;
+
+ if (prm_ll_data != &null_prm_ll_data)
+ return -EEXIST;
+
+ prm_ll_data = pld;
+
+ return 0;
+}
+
+/**
+ * prm_unregister - unregister per-SoC low-level data & function pointers
+ * @pld: low-level per-SoC OMAP PRM data & function pointers to unregister
+ *
+ * Unregister per-SoC low-level OMAP PRM data and function pointers
+ * that were previously registered with prm_register(). The
+ * caller may not destroy any of the data pointed to by @pld until
+ * this function returns successfully. Returns 0 upon success, or
+ * -EINVAL if @pld is NULL or if @pld does not match the struct
+ * prm_ll_data * previously registered by prm_register().
+ */
+int prm_unregister(struct prm_ll_data *pld)
+{
+ if (!pld || prm_ll_data != pld)
+ return -EINVAL;
+
+ prm_ll_data = &null_prm_ll_data;
+
+ return 0;
+}
+
+#ifdef CONFIG_ARCH_OMAP2
+static struct omap_prcm_init_data omap2_prm_data __initdata = {
+ .index = TI_CLKM_PRM,
+ .init = omap2xxx_prm_init,
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+static struct omap_prcm_init_data omap3_prm_data __initdata = {
+ .index = TI_CLKM_PRM,
+ .init = omap3xxx_prm_init,
+
+ /*
+ * IVA2 offset is a negative value, must offset the prm_base
+ * address by this to get it to positive
+ */
+ .offset = -OMAP3430_IVA2_MOD,
+};
+#endif
+
+#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_TI81XX)
+static struct omap_prcm_init_data am3_prm_data __initdata = {
+ .index = TI_CLKM_PRM,
+ .init = am33xx_prm_init,
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+static struct omap_prcm_init_data omap4_prm_data __initdata = {
+ .index = TI_CLKM_PRM,
+ .init = omap44xx_prm_init,
+ .device_inst_offset = OMAP4430_PRM_DEVICE_INST,
+ .flags = PRM_HAS_IO_WAKEUP | PRM_HAS_VOLTAGE | PRM_IRQ_DEFAULT,
+};
+#endif
+
+#ifdef CONFIG_SOC_OMAP5
+static struct omap_prcm_init_data omap5_prm_data __initdata = {
+ .index = TI_CLKM_PRM,
+ .init = omap44xx_prm_init,
+ .device_inst_offset = OMAP54XX_PRM_DEVICE_INST,
+ .flags = PRM_HAS_IO_WAKEUP | PRM_HAS_VOLTAGE,
+};
+#endif
+
+#ifdef CONFIG_SOC_DRA7XX
+static struct omap_prcm_init_data dra7_prm_data __initdata = {
+ .index = TI_CLKM_PRM,
+ .init = omap44xx_prm_init,
+ .device_inst_offset = DRA7XX_PRM_DEVICE_INST,
+ .flags = PRM_HAS_IO_WAKEUP,
+};
+#endif
+
+#ifdef CONFIG_SOC_AM43XX
+static struct omap_prcm_init_data am4_prm_data __initdata = {
+ .index = TI_CLKM_PRM,
+ .init = omap44xx_prm_init,
+ .device_inst_offset = AM43XX_PRM_DEVICE_INST,
+};
+#endif
+
+#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
+static struct omap_prcm_init_data scrm_data __initdata = {
+ .index = TI_CLKM_SCRM,
+};
+#endif
+
+static const struct of_device_id omap_prcm_dt_match_table[] __initconst = {
+#ifdef CONFIG_SOC_AM33XX
+ { .compatible = "ti,am3-prcm", .data = &am3_prm_data },
+#endif
+#ifdef CONFIG_SOC_AM43XX
+ { .compatible = "ti,am4-prcm", .data = &am4_prm_data },
+#endif
+#ifdef CONFIG_SOC_TI81XX
+ { .compatible = "ti,dm814-prcm", .data = &am3_prm_data },
+ { .compatible = "ti,dm816-prcm", .data = &am3_prm_data },
+#endif
+#ifdef CONFIG_ARCH_OMAP2
+ { .compatible = "ti,omap2-prcm", .data = &omap2_prm_data },
+#endif
+#ifdef CONFIG_ARCH_OMAP3
+ { .compatible = "ti,omap3-prm", .data = &omap3_prm_data },
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+ { .compatible = "ti,omap4-prm", .data = &omap4_prm_data },
+ { .compatible = "ti,omap4-scrm", .data = &scrm_data },
+#endif
+#ifdef CONFIG_SOC_OMAP5
+ { .compatible = "ti,omap5-prm", .data = &omap5_prm_data },
+ { .compatible = "ti,omap5-scrm", .data = &scrm_data },
+#endif
+#ifdef CONFIG_SOC_DRA7XX
+ { .compatible = "ti,dra7-prm", .data = &dra7_prm_data },
+#endif
+ { }
+};
+
+/**
+ * omap2_prm_base_init - initialize iomappings for the PRM driver
+ *
+ * Detects and initializes the iomappings for the PRM driver, based
+ * on the DT data. Returns 0 in success, negative error value
+ * otherwise.
+ */
+int __init omap2_prm_base_init(void)
+{
+ struct device_node *np;
+ const struct of_device_id *match;
+ struct omap_prcm_init_data *data;
+ void __iomem *mem;
+
+ for_each_matching_node_and_match(np, omap_prcm_dt_match_table, &match) {
+ data = (struct omap_prcm_init_data *)match->data;
+
+ mem = of_iomap(np, 0);
+ if (!mem)
+ return -ENOMEM;
+
+ if (data->index == TI_CLKM_PRM)
+ prm_base = mem + data->offset;
+
+ data->mem = mem;
+
+ data->np = np;
+
+ if (data->init)
+ data->init(data);
+ }
+
+ return 0;
+}
+
+int __init omap2_prcm_base_init(void)
+{
+ int ret;
+
+ ret = omap2_prm_base_init();
+ if (ret)
+ return ret;
+
+ return omap2_cm_base_init();
+}
+
+/**
+ * omap_prcm_init - low level init for the PRCM drivers
+ *
+ * Initializes the low level clock infrastructure for PRCM drivers.
+ * Returns 0 in success, negative error value in failure.
+ */
+int __init omap_prcm_init(void)
+{
+ struct device_node *np;
+ const struct of_device_id *match;
+ const struct omap_prcm_init_data *data;
+ int ret;
+
+ for_each_matching_node_and_match(np, omap_prcm_dt_match_table, &match) {
+ data = match->data;
+
+ ret = omap2_clk_provider_init(np, data->index, NULL, data->mem);
+ if (ret)
+ return ret;
+ }
+
+ omap_cm_init();
+
+ return 0;
+}
+
+static int __init prm_late_init(void)
+{
+ if (prm_ll_data->late_init)
+ return prm_ll_data->late_init();
+ return 0;
+}
+subsys_initcall(prm_late_init);
diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c
new file mode 100644
index 000000000..d0b15dbaf
--- /dev/null
+++ b/arch/arm/mach-omap2/prminst44xx.c
@@ -0,0 +1,196 @@
+/*
+ * OMAP4 PRM instance functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * 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 "iomap.h"
+#include "common.h"
+#include "prcm-common.h"
+#include "prm44xx.h"
+#include "prm54xx.h"
+#include "prm7xx.h"
+#include "prminst44xx.h"
+#include "prm-regbits-44xx.h"
+#include "prcm44xx.h"
+#include "prcm43xx.h"
+#include "prcm_mpu44xx.h"
+#include "soc.h"
+
+static void __iomem *_prm_bases[OMAP4_MAX_PRCM_PARTITIONS];
+
+static s32 prm_dev_inst = PRM_INSTANCE_UNKNOWN;
+
+/**
+ * omap_prm_base_init - Populates the prm partitions
+ *
+ * Populates the base addresses of the _prm_bases
+ * array used for read/write of prm module registers.
+ */
+void omap_prm_base_init(void)
+{
+ _prm_bases[OMAP4430_PRM_PARTITION] = prm_base;
+ _prm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_base;
+}
+
+s32 omap4_prmst_get_prm_dev_inst(void)
+{
+ return prm_dev_inst;
+}
+
+void omap4_prminst_set_prm_dev_inst(s32 dev_inst)
+{
+ prm_dev_inst = dev_inst;
+}
+
+/* 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 readl_relaxed(_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]);
+ writel_relaxed(val, _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,
+ u16 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;
+}
+
+/**
+ * omap4_prminst_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_prminst_is_hardreset_asserted(u8 shift, u8 part, s16 inst,
+ u16 rstctrl_offs)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(part, inst, rstctrl_offs);
+ v &= 1 << shift;
+ v >>= shift;
+
+ return v;
+}
+
+/**
+ * omap4_prminst_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_prminst_assert_hardreset(u8 shift, u8 part, s16 inst,
+ u16 rstctrl_offs)
+{
+ u32 mask = 1 << shift;
+
+ omap4_prminst_rmw_inst_reg_bits(mask, mask, part, inst, rstctrl_offs);
+
+ return 0;
+}
+
+/**
+ * omap4_prminst_deassert_hardreset - deassert a submodule hardreset line and
+ * wait
+ * @shift: register bit shift corresponding to the reset line to deassert
+ * @st_shift: status bit offset corresponding to the reset line
+ * @part: PRM partition
+ * @inst: PRM instance offset
+ * @rstctrl_offs: reset register offset
+ * @rstst_offs: reset status register offset
+ *
+ * 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_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 inst,
+ u16 rstctrl_offs, u16 rstst_offs)
+{
+ int c;
+ u32 mask = 1 << shift;
+ u32 st_mask = 1 << st_shift;
+
+ /* Check the current status to avoid de-asserting the line twice */
+ if (omap4_prminst_is_hardreset_asserted(shift, part, inst,
+ rstctrl_offs) == 0)
+ return -EEXIST;
+
+ /* Clear the reset status by writing 1 to the status bit */
+ omap4_prminst_rmw_inst_reg_bits(0xffffffff, st_mask, part, inst,
+ rstst_offs);
+ /* de-assert the reset control line */
+ omap4_prminst_rmw_inst_reg_bits(mask, 0, part, inst, rstctrl_offs);
+ /* wait the status to be set */
+ omap_test_timeout(omap4_prminst_is_hardreset_asserted(st_shift, part,
+ inst, rstst_offs),
+ MAX_MODULE_HARDRESET_WAIT, c);
+
+ return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
+}
+
+
+void omap4_prminst_global_warm_sw_reset(void)
+{
+ u32 v;
+ s32 inst = omap4_prmst_get_prm_dev_inst();
+
+ if (inst == PRM_INSTANCE_UNKNOWN)
+ return;
+
+ v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, inst,
+ OMAP4_PRM_RSTCTRL_OFFSET);
+ v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
+ omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION,
+ inst, OMAP4_PRM_RSTCTRL_OFFSET);
+
+ /* OCP barrier */
+ v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+ inst, OMAP4_PRM_RSTCTRL_OFFSET);
+}
diff --git a/arch/arm/mach-omap2/prminst44xx.h b/arch/arm/mach-omap2/prminst44xx.h
new file mode 100644
index 000000000..0c03d0731
--- /dev/null
+++ b/arch/arm/mach-omap2/prminst44xx.h
@@ -0,0 +1,40 @@
+/*
+ * OMAP4 Power/Reset Management (PRM) function prototypes
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * 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
+
+#define PRM_INSTANCE_UNKNOWN -1
+extern s32 omap4_prmst_get_prm_dev_inst(void);
+void omap4_prminst_set_prm_dev_inst(s32 dev_inst);
+
+/*
+ * 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, u16 idx);
+
+extern void omap4_prminst_global_warm_sw_reset(void);
+
+extern int omap4_prminst_is_hardreset_asserted(u8 shift, u8 part, s16 inst,
+ u16 rstctrl_offs);
+extern int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst,
+ u16 rstctrl_offs);
+int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part,
+ s16 inst, u16 rstctrl_offs,
+ u16 rstst_offs);
+
+extern void omap_prm_base_init(void);
+
+#endif
diff --git a/arch/arm/mach-omap2/scrm44xx.h b/arch/arm/mach-omap2/scrm44xx.h
new file mode 100644
index 000000000..e897ac89a
--- /dev/null
+++ b/arch/arm/mach-omap2/scrm44xx.h
@@ -0,0 +1,177 @@
+/*
+ * 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_MAPPING_WIDTH 3
+#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_CLKDIV_WIDTH 4
+#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/scrm54xx.h b/arch/arm/mach-omap2/scrm54xx.h
new file mode 100644
index 000000000..57e86c8f8
--- /dev/null
+++ b/arch/arm/mach-omap2/scrm54xx.h
@@ -0,0 +1,231 @@
+/*
+ * OMAP54XX SCRM registers and bitfields
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.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_SCRM_54XX_H
+#define __ARCH_ARM_MACH_OMAP2_SCRM_54XX_H
+
+#define OMAP5_SCRM_BASE 0x4ae0a000
+
+#define OMAP54XX_SCRM_REGADDR(reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP5_SCRM_BASE + (reg))
+
+/* SCRM */
+
+/* SCRM.SCRM register offsets */
+#define OMAP5_SCRM_REVISION_SCRM_OFFSET 0x0000
+#define OMAP5_SCRM_REVISION_SCRM OMAP54XX_SCRM_REGADDR(0x0000)
+#define OMAP5_SCRM_CLKSETUPTIME_OFFSET 0x0100
+#define OMAP5_SCRM_CLKSETUPTIME OMAP54XX_SCRM_REGADDR(0x0100)
+#define OMAP5_SCRM_PMICSETUPTIME_OFFSET 0x0104
+#define OMAP5_SCRM_PMICSETUPTIME OMAP54XX_SCRM_REGADDR(0x0104)
+#define OMAP5_SCRM_ALTCLKSRC_OFFSET 0x0110
+#define OMAP5_SCRM_ALTCLKSRC OMAP54XX_SCRM_REGADDR(0x0110)
+#define OMAP5_SCRM_MODEMCLKM_OFFSET 0x0118
+#define OMAP5_SCRM_MODEMCLKM OMAP54XX_SCRM_REGADDR(0x0118)
+#define OMAP5_SCRM_D2DCLKM_OFFSET 0x011c
+#define OMAP5_SCRM_D2DCLKM OMAP54XX_SCRM_REGADDR(0x011c)
+#define OMAP5_SCRM_EXTCLKREQ_OFFSET 0x0200
+#define OMAP5_SCRM_EXTCLKREQ OMAP54XX_SCRM_REGADDR(0x0200)
+#define OMAP5_SCRM_ACCCLKREQ_OFFSET 0x0204
+#define OMAP5_SCRM_ACCCLKREQ OMAP54XX_SCRM_REGADDR(0x0204)
+#define OMAP5_SCRM_PWRREQ_OFFSET 0x0208
+#define OMAP5_SCRM_PWRREQ OMAP54XX_SCRM_REGADDR(0x0208)
+#define OMAP5_SCRM_AUXCLKREQ0_OFFSET 0x0210
+#define OMAP5_SCRM_AUXCLKREQ0 OMAP54XX_SCRM_REGADDR(0x0210)
+#define OMAP5_SCRM_AUXCLKREQ1_OFFSET 0x0214
+#define OMAP5_SCRM_AUXCLKREQ1 OMAP54XX_SCRM_REGADDR(0x0214)
+#define OMAP5_SCRM_AUXCLKREQ2_OFFSET 0x0218
+#define OMAP5_SCRM_AUXCLKREQ2 OMAP54XX_SCRM_REGADDR(0x0218)
+#define OMAP5_SCRM_AUXCLKREQ3_OFFSET 0x021c
+#define OMAP5_SCRM_AUXCLKREQ3 OMAP54XX_SCRM_REGADDR(0x021c)
+#define OMAP5_SCRM_AUXCLKREQ4_OFFSET 0x0220
+#define OMAP5_SCRM_AUXCLKREQ4 OMAP54XX_SCRM_REGADDR(0x0220)
+#define OMAP5_SCRM_AUXCLKREQ5_OFFSET 0x0224
+#define OMAP5_SCRM_AUXCLKREQ5 OMAP54XX_SCRM_REGADDR(0x0224)
+#define OMAP5_SCRM_D2DCLKREQ_OFFSET 0x0234
+#define OMAP5_SCRM_D2DCLKREQ OMAP54XX_SCRM_REGADDR(0x0234)
+#define OMAP5_SCRM_AUXCLK0_OFFSET 0x0310
+#define OMAP5_SCRM_AUXCLK0 OMAP54XX_SCRM_REGADDR(0x0310)
+#define OMAP5_SCRM_AUXCLK1_OFFSET 0x0314
+#define OMAP5_SCRM_AUXCLK1 OMAP54XX_SCRM_REGADDR(0x0314)
+#define OMAP5_SCRM_AUXCLK2_OFFSET 0x0318
+#define OMAP5_SCRM_AUXCLK2 OMAP54XX_SCRM_REGADDR(0x0318)
+#define OMAP5_SCRM_AUXCLK3_OFFSET 0x031c
+#define OMAP5_SCRM_AUXCLK3 OMAP54XX_SCRM_REGADDR(0x031c)
+#define OMAP5_SCRM_AUXCLK4_OFFSET 0x0320
+#define OMAP5_SCRM_AUXCLK4 OMAP54XX_SCRM_REGADDR(0x0320)
+#define OMAP5_SCRM_AUXCLK5_OFFSET 0x0324
+#define OMAP5_SCRM_AUXCLK5 OMAP54XX_SCRM_REGADDR(0x0324)
+#define OMAP5_SCRM_RSTTIME_OFFSET 0x0400
+#define OMAP5_SCRM_RSTTIME OMAP54XX_SCRM_REGADDR(0x0400)
+#define OMAP5_SCRM_MODEMRSTCTRL_OFFSET 0x0418
+#define OMAP5_SCRM_MODEMRSTCTRL OMAP54XX_SCRM_REGADDR(0x0418)
+#define OMAP5_SCRM_D2DRSTCTRL_OFFSET 0x041c
+#define OMAP5_SCRM_D2DRSTCTRL OMAP54XX_SCRM_REGADDR(0x041c)
+#define OMAP5_SCRM_EXTPWRONRSTCTRL_OFFSET 0x0420
+#define OMAP5_SCRM_EXTPWRONRSTCTRL OMAP54XX_SCRM_REGADDR(0x0420)
+#define OMAP5_SCRM_EXTWARMRSTST_OFFSET 0x0510
+#define OMAP5_SCRM_EXTWARMRSTST OMAP54XX_SCRM_REGADDR(0x0510)
+#define OMAP5_SCRM_APEWARMRSTST_OFFSET 0x0514
+#define OMAP5_SCRM_APEWARMRSTST OMAP54XX_SCRM_REGADDR(0x0514)
+#define OMAP5_SCRM_MODEMWARMRSTST_OFFSET 0x0518
+#define OMAP5_SCRM_MODEMWARMRSTST OMAP54XX_SCRM_REGADDR(0x0518)
+#define OMAP5_SCRM_D2DWARMRSTST_OFFSET 0x051c
+#define OMAP5_SCRM_D2DWARMRSTST OMAP54XX_SCRM_REGADDR(0x051c)
+
+/*
+ * Used by AUXCLKREQ0, AUXCLKREQ1, AUXCLKREQ2, AUXCLKREQ3, AUXCLKREQ4,
+ * AUXCLKREQ5, D2DCLKREQ
+ */
+#define OMAP5_ACCURACY_SHIFT 1
+#define OMAP5_ACCURACY_WIDTH 0x1
+#define OMAP5_ACCURACY_MASK (1 << 1)
+
+/* Used by APEWARMRSTST */
+#define OMAP5_APEWARMRSTST_SHIFT 1
+#define OMAP5_APEWARMRSTST_WIDTH 0x1
+#define OMAP5_APEWARMRSTST_MASK (1 << 1)
+
+/* Used by AUXCLK0, AUXCLK1, AUXCLK2, AUXCLK3, AUXCLK4, AUXCLK5 */
+#define OMAP5_CLKDIV_SHIFT 16
+#define OMAP5_CLKDIV_WIDTH 0x4
+#define OMAP5_CLKDIV_MASK (0xf << 16)
+
+/* Used by D2DCLKM, MODEMCLKM */
+#define OMAP5_CLK_32KHZ_SHIFT 0
+#define OMAP5_CLK_32KHZ_WIDTH 0x1
+#define OMAP5_CLK_32KHZ_MASK (1 << 0)
+
+/* Used by D2DRSTCTRL, MODEMRSTCTRL */
+#define OMAP5_COLDRST_SHIFT 0
+#define OMAP5_COLDRST_WIDTH 0x1
+#define OMAP5_COLDRST_MASK (1 << 0)
+
+/* Used by D2DWARMRSTST */
+#define OMAP5_D2DWARMRSTST_SHIFT 3
+#define OMAP5_D2DWARMRSTST_WIDTH 0x1
+#define OMAP5_D2DWARMRSTST_MASK (1 << 3)
+
+/* Used by AUXCLK0 */
+#define OMAP5_DISABLECLK_SHIFT 9
+#define OMAP5_DISABLECLK_WIDTH 0x1
+#define OMAP5_DISABLECLK_MASK (1 << 9)
+
+/* Used by CLKSETUPTIME */
+#define OMAP5_DOWNTIME_SHIFT 16
+#define OMAP5_DOWNTIME_WIDTH 0x6
+#define OMAP5_DOWNTIME_MASK (0x3f << 16)
+
+/* Used by AUXCLK0, AUXCLK1, AUXCLK2, AUXCLK3, AUXCLK4, AUXCLK5 */
+#define OMAP5_ENABLE_SHIFT 8
+#define OMAP5_ENABLE_WIDTH 0x1
+#define OMAP5_ENABLE_MASK (1 << 8)
+
+/* Renamed from ENABLE Used by EXTPWRONRSTCTRL */
+#define OMAP5_ENABLE_0_0_SHIFT 0
+#define OMAP5_ENABLE_0_0_WIDTH 0x1
+#define OMAP5_ENABLE_0_0_MASK (1 << 0)
+
+/* Used by ALTCLKSRC */
+#define OMAP5_ENABLE_EXT_SHIFT 3
+#define OMAP5_ENABLE_EXT_WIDTH 0x1
+#define OMAP5_ENABLE_EXT_MASK (1 << 3)
+
+/* Used by ALTCLKSRC */
+#define OMAP5_ENABLE_INT_SHIFT 2
+#define OMAP5_ENABLE_INT_WIDTH 0x1
+#define OMAP5_ENABLE_INT_MASK (1 << 2)
+
+/* Used by EXTWARMRSTST */
+#define OMAP5_EXTWARMRSTST_SHIFT 0
+#define OMAP5_EXTWARMRSTST_WIDTH 0x1
+#define OMAP5_EXTWARMRSTST_MASK (1 << 0)
+
+/*
+ * Used by AUXCLKREQ0, AUXCLKREQ1, AUXCLKREQ2, AUXCLKREQ3, AUXCLKREQ4,
+ * AUXCLKREQ5
+ */
+#define OMAP5_MAPPING_SHIFT 2
+#define OMAP5_MAPPING_WIDTH 0x3
+#define OMAP5_MAPPING_MASK (0x7 << 2)
+
+/* Used by ALTCLKSRC */
+#define OMAP5_MODE_SHIFT 0
+#define OMAP5_MODE_WIDTH 0x2
+#define OMAP5_MODE_MASK (0x3 << 0)
+
+/* Used by MODEMWARMRSTST */
+#define OMAP5_MODEMWARMRSTST_SHIFT 2
+#define OMAP5_MODEMWARMRSTST_WIDTH 0x1
+#define OMAP5_MODEMWARMRSTST_MASK (1 << 2)
+
+/*
+ * Used by ACCCLKREQ, AUXCLK0, AUXCLK1, AUXCLK2, AUXCLK3, AUXCLK4, AUXCLK5,
+ * AUXCLKREQ0, AUXCLKREQ1, AUXCLKREQ2, AUXCLKREQ3, AUXCLKREQ4, AUXCLKREQ5,
+ * D2DCLKREQ, EXTCLKREQ, PWRREQ
+ */
+#define OMAP5_POLARITY_SHIFT 0
+#define OMAP5_POLARITY_WIDTH 0x1
+#define OMAP5_POLARITY_MASK (1 << 0)
+
+/* Used by EXTPWRONRSTCTRL */
+#define OMAP5_PWRONRST_SHIFT 1
+#define OMAP5_PWRONRST_WIDTH 0x1
+#define OMAP5_PWRONRST_MASK (1 << 1)
+
+/* Used by REVISION_SCRM */
+#define OMAP5_REV_SHIFT 0
+#define OMAP5_REV_WIDTH 0x8
+#define OMAP5_REV_MASK (0xff << 0)
+
+/* Used by RSTTIME */
+#define OMAP5_RSTTIME_SHIFT 0
+#define OMAP5_RSTTIME_WIDTH 0x4
+#define OMAP5_RSTTIME_MASK (0xf << 0)
+
+/* Used by CLKSETUPTIME */
+#define OMAP5_SETUPTIME_SHIFT 0
+#define OMAP5_SETUPTIME_WIDTH 0xc
+#define OMAP5_SETUPTIME_MASK (0xfff << 0)
+
+/* Used by PMICSETUPTIME */
+#define OMAP5_SLEEPTIME_SHIFT 0
+#define OMAP5_SLEEPTIME_WIDTH 0x6
+#define OMAP5_SLEEPTIME_MASK (0x3f << 0)
+
+/* Used by AUXCLK0, AUXCLK1, AUXCLK2, AUXCLK3, AUXCLK4, AUXCLK5 */
+#define OMAP5_SRCSELECT_SHIFT 1
+#define OMAP5_SRCSELECT_WIDTH 0x2
+#define OMAP5_SRCSELECT_MASK (0x3 << 1)
+
+/* Used by D2DCLKM */
+#define OMAP5_SYSCLK_SHIFT 1
+#define OMAP5_SYSCLK_WIDTH 0x1
+#define OMAP5_SYSCLK_MASK (1 << 1)
+
+/* Used by PMICSETUPTIME */
+#define OMAP5_WAKEUPTIME_SHIFT 16
+#define OMAP5_WAKEUPTIME_WIDTH 0x6
+#define OMAP5_WAKEUPTIME_MASK (0x3f << 16)
+
+/* Used by D2DRSTCTRL, MODEMRSTCTRL */
+#define OMAP5_WARMRST_SHIFT 1
+#define OMAP5_WARMRST_WIDTH 0x1
+#define OMAP5_WARMRST_MASK (1 << 1)
+
+#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 000000000..1ee58c281
--- /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 "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 000000000..85cccc004
--- /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 "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 000000000..0fa7ffa9b
--- /dev/null
+++ b/arch/arm/mach-omap2/sdram-nokia.c
@@ -0,0 +1,299 @@
+/*
+ * SDRC register values for Nokia boards
+ *
+ * Copyright (C) 2008, 2010-2011 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 "common.h"
+#include "sdram-nokia.h"
+#include "sdrc.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 sdram_timings nokia_200mhz_timings[] = {
+ {
+ .casl = 3,
+ .tDAL = 30000,
+ .tDPL = 15000,
+ .tRRD = 10000,
+ .tRCD = 20000,
+ .tRP = 15000,
+ .tRAS = 40000,
+ .tRC = 55000,
+ .tRFC = 140000,
+ .tXSR = 200000,
+
+ .tREF = 7800,
+
+ .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 },
+ { 100000000, nokia_200mhz_timings },
+ { 166000000, nokia_166mhz_timings },
+ { 195200000, nokia_195dot2mhz_timings },
+ { 200000000, nokia_200mhz_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 000000000..ee63da5f8
--- /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 000000000..003f7bf4e
--- /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 "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 000000000..8dc3de5eb
--- /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 "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 000000000..dae7e4804
--- /dev/null
+++ b/arch/arm/mach-omap2/sdrc.c
@@ -0,0 +1,157 @@
+/*
+ * 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 "common.h"
+#include "clock.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(void __iomem *sdrc, void __iomem *sms)
+{
+ omap2_sdrc_base = sdrc;
+ omap2_sms_base = sms;
+}
+
+/**
+ * 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();
+}
diff --git a/arch/arm/mach-omap2/sdrc.h b/arch/arm/mach-omap2/sdrc.h
new file mode 100644
index 000000000..645a2a46b
--- /dev/null
+++ b/arch/arm/mach-omap2/sdrc.h
@@ -0,0 +1,213 @@
+#ifndef __ARCH_ARM_MACH_OMAP2_SDRC_H
+#define __ARCH_ARM_MACH_OMAP2_SDRC_H
+
+/*
+ * OMAP2/3 SDRC/SMS macros and prototypes
+ *
+ * Copyright (C) 2007-2008, 2012 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
+ *
+ * Paul Walmsley
+ * Tony Lindgren
+ * 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.
+ */
+#undef DEBUG
+
+#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)
+{
+ writel_relaxed(val, OMAP_SDRC_REGADDR(reg));
+}
+
+static inline u32 sdrc_read_reg(u16 reg)
+{
+ return readl_relaxed(OMAP_SDRC_REGADDR(reg));
+}
+
+/* SMS global register get/set */
+
+static inline void sms_write_reg(u32 val, u16 reg)
+{
+ writel_relaxed(val, OMAP_SMS_REGADDR(reg));
+}
+
+static inline u32 sms_read_reg(u16 reg)
+{
+ return readl_relaxed(OMAP_SMS_REGADDR(reg));
+}
+
+extern void omap2_set_globals_sdrc(void __iomem *sdrc, void __iomem *sms);
+
+
+/**
+ * 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;
+};
+
+#ifdef CONFIG_SOC_HAS_OMAP2_SDRC
+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);
+
+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);
+
+
+#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
+
+/* 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
+/* REVISIT: fill in other SMS registers here */
+
+
+
+#endif
diff --git a/arch/arm/mach-omap2/sdrc2xxx.c b/arch/arm/mach-omap2/sdrc2xxx.c
new file mode 100644
index 000000000..ae3f15531
--- /dev/null
+++ b/arch/arm/mach-omap2/sdrc2xxx.c
@@ -0,0 +1,169 @@
+/*
+ * 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 "soc.h"
+#include "iomap.h"
+#include "common.h"
+#include "prm2xxx.h"
+#include "clock.h"
+#include "sdrc.h"
+#include "sram.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())
+ writel_relaxed(0xffff, OMAP2420_PRCM_VOLTSETUP);
+ else
+ writel_relaxed(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 000000000..57dee0c7c
--- /dev/null
+++ b/arch/arm/mach-omap2/serial.c
@@ -0,0 +1,332 @@
+/*
+ * 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/clk.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <linux/console.h>
+#include <linux/omap-dma.h>
+#include <linux/platform_data/serial-omap.h>
+
+#include "common.h"
+#include "omap_hwmod.h"
+#include "omap_device.h"
+#include "omap-pm.h"
+#include "soc.h"
+#include "prm2xxx_3xxx.h"
+#include "pm.h"
+#include "cm2xxx_3xxx.h"
+#include "prm-regbits-34xx.h"
+#include "control.h"
+#include "mux.h"
+#include "serial.h"
+
+/*
+ * NOTE: By default the serial auto_suspend timeout is disabled as it causes
+ * lost characters over the serial ports. This means that the UART clocks will
+ * stay on until power/autosuspend_delay is set for the uart from sysfs.
+ * This also causes that any deeper omap sleep states are blocked.
+ */
+#define DEFAULT_AUTOSUSPEND_DELAY -1
+
+#define MAX_UART_HWMOD_NAME_LEN 16
+
+struct omap_uart_state {
+ int num;
+
+ struct list_head node;
+ struct omap_hwmod *oh;
+ struct omap_device_pad default_omap_uart_pads[2];
+};
+
+static LIST_HEAD(uart_list);
+static u8 num_uarts;
+static u8 console_uart_id = -1;
+static u8 uart_debug;
+
+#define DEFAULT_RXDMA_POLLRATE 1 /* RX DMA polling rate (us) */
+#define DEFAULT_RXDMA_BUFSIZE 4096 /* RX DMA buffer size */
+#define DEFAULT_RXDMA_TIMEOUT (3 * HZ)/* RX DMA timeout (jiffies) */
+
+static struct omap_uart_port_info omap_serial_default_info[] __initdata = {
+ {
+ .dma_enabled = false,
+ .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE,
+ .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE,
+ .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT,
+ .autosuspend_timeout = DEFAULT_AUTOSUSPEND_DELAY,
+ },
+};
+
+#ifdef CONFIG_PM
+static void omap_uart_enable_wakeup(struct device *dev, bool enable)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct omap_device *od = to_omap_device(pdev);
+
+ if (!od)
+ return;
+
+ if (enable)
+ omap_hwmod_enable_wakeup(od->hwmods[0]);
+ else
+ omap_hwmod_disable_wakeup(od->hwmods[0]);
+}
+
+#else
+static void omap_uart_enable_wakeup(struct device *dev, bool enable)
+{}
+#endif /* CONFIG_PM */
+
+#ifdef CONFIG_OMAP_MUX
+
+#define OMAP_UART_DEFAULT_PAD_NAME_LEN 28
+static char rx_pad_name[OMAP_UART_DEFAULT_PAD_NAME_LEN],
+ tx_pad_name[OMAP_UART_DEFAULT_PAD_NAME_LEN] __initdata;
+
+static void __init
+omap_serial_fill_uart_tx_rx_pads(struct omap_board_data *bdata,
+ struct omap_uart_state *uart)
+{
+ uart->default_omap_uart_pads[0].name = rx_pad_name;
+ uart->default_omap_uart_pads[0].flags = OMAP_DEVICE_PAD_REMUX |
+ OMAP_DEVICE_PAD_WAKEUP;
+ uart->default_omap_uart_pads[0].enable = OMAP_PIN_INPUT |
+ OMAP_MUX_MODE0;
+ uart->default_omap_uart_pads[0].idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0;
+ uart->default_omap_uart_pads[1].name = tx_pad_name;
+ uart->default_omap_uart_pads[1].enable = OMAP_PIN_OUTPUT |
+ OMAP_MUX_MODE0;
+ bdata->pads = uart->default_omap_uart_pads;
+ bdata->pads_cnt = ARRAY_SIZE(uart->default_omap_uart_pads);
+}
+
+static void __init omap_serial_check_wakeup(struct omap_board_data *bdata,
+ struct omap_uart_state *uart)
+{
+ struct omap_mux_partition *tx_partition = NULL, *rx_partition = NULL;
+ struct omap_mux *rx_mux = NULL, *tx_mux = NULL;
+ char *rx_fmt, *tx_fmt;
+ int uart_nr = bdata->id + 1;
+
+ if (bdata->id != 2) {
+ rx_fmt = "uart%d_rx.uart%d_rx";
+ tx_fmt = "uart%d_tx.uart%d_tx";
+ } else {
+ rx_fmt = "uart%d_rx_irrx.uart%d_rx_irrx";
+ tx_fmt = "uart%d_tx_irtx.uart%d_tx_irtx";
+ }
+
+ snprintf(rx_pad_name, OMAP_UART_DEFAULT_PAD_NAME_LEN, rx_fmt,
+ uart_nr, uart_nr);
+ snprintf(tx_pad_name, OMAP_UART_DEFAULT_PAD_NAME_LEN, tx_fmt,
+ uart_nr, uart_nr);
+
+ if (omap_mux_get_by_name(rx_pad_name, &rx_partition, &rx_mux) >= 0 &&
+ omap_mux_get_by_name
+ (tx_pad_name, &tx_partition, &tx_mux) >= 0) {
+ u16 tx_mode, rx_mode;
+
+ tx_mode = omap_mux_read(tx_partition, tx_mux->reg_offset);
+ rx_mode = omap_mux_read(rx_partition, rx_mux->reg_offset);
+
+ /*
+ * Check if uart is used in default tx/rx mode i.e. in mux mode0
+ * if yes then configure rx pin for wake up capability
+ */
+ if (OMAP_MODE_UART(rx_mode) && OMAP_MODE_UART(tx_mode))
+ omap_serial_fill_uart_tx_rx_pads(bdata, uart);
+ }
+}
+#else
+static void __init omap_serial_check_wakeup(struct omap_board_data *bdata,
+ struct omap_uart_state *uart)
+{
+}
+#endif
+
+static char *cmdline_find_option(char *str)
+{
+ extern char *saved_command_line;
+
+ return strstr(saved_command_line, str);
+}
+
+static int __init omap_serial_early_init(void)
+{
+ if (of_have_populated_dt())
+ return -ENODEV;
+
+ do {
+ char oh_name[MAX_UART_HWMOD_NAME_LEN];
+ struct omap_hwmod *oh;
+ struct omap_uart_state *uart;
+ char uart_name[MAX_UART_HWMOD_NAME_LEN];
+
+ snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN,
+ "uart%d", num_uarts + 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 = num_uarts++;
+ list_add_tail(&uart->node, &uart_list);
+ snprintf(uart_name, MAX_UART_HWMOD_NAME_LEN,
+ "%s%d", OMAP_SERIAL_NAME, uart->num);
+
+ if (cmdline_find_option(uart_name)) {
+ console_uart_id = uart->num;
+
+ if (console_loglevel >= 10) {
+ uart_debug = true;
+ pr_info("%s used as console in debug mode: uart%d clocks will not be gated",
+ uart_name, uart->num);
+ }
+ }
+ } while (1);
+
+ return 0;
+}
+omap_core_initcall(omap_serial_early_init);
+
+/**
+ * omap_serial_init_port() - initialize single serial port
+ * @bdata: port specific board data pointer
+ * @info: platform specific 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_port_info *info)
+{
+ struct omap_uart_state *uart;
+ struct omap_hwmod *oh;
+ struct platform_device *pdev;
+ void *pdata = NULL;
+ u32 pdata_size = 0;
+ char *name;
+ struct omap_uart_port_info omap_up;
+
+ 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;
+ if (!info)
+ info = omap_serial_default_info;
+
+ oh = uart->oh;
+ name = DRIVER_NAME;
+
+ omap_up.dma_enabled = info->dma_enabled;
+ omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
+ omap_up.flags = UPF_BOOT_AUTOCONF;
+ omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count;
+ omap_up.enable_wakeup = omap_uart_enable_wakeup;
+ omap_up.dma_rx_buf_size = info->dma_rx_buf_size;
+ omap_up.dma_rx_timeout = info->dma_rx_timeout;
+ omap_up.dma_rx_poll_rate = info->dma_rx_poll_rate;
+ omap_up.autosuspend_timeout = info->autosuspend_timeout;
+
+ pdata = &omap_up;
+ pdata_size = sizeof(struct omap_uart_port_info);
+
+ if (WARN_ON(!oh))
+ return;
+
+ pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size);
+ if (IS_ERR(pdev)) {
+ WARN(1, "Could not build omap_device for %s: %s.\n", name,
+ oh->name);
+ return;
+ }
+
+ oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
+
+ if (console_uart_id == bdata->id) {
+ omap_device_enable(pdev);
+ pm_runtime_set_active(&pdev->dev);
+ }
+
+ oh->dev_attr = uart;
+
+ if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
+ && !uart_debug)
+ device_init_wakeup(&pdev->dev, true);
+}
+
+/**
+ * omap_serial_board_init() - initialize all supported serial ports
+ * @info: platform specific data pointer
+ *
+ * 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_board_init(struct omap_uart_port_info *info)
+{
+ 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_check_wakeup(&bdata, uart);
+
+ if (!info)
+ omap_serial_init_port(&bdata, NULL);
+ else
+ omap_serial_init_port(&bdata, &info[uart->num]);
+ }
+}
+
+/**
+ * omap_serial_init() - initialize all supported serial ports
+ *
+ * Initializes all available UARTs.
+ * 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)
+{
+ omap_serial_board_init(NULL);
+}
diff --git a/arch/arm/mach-omap2/serial.h b/arch/arm/mach-omap2/serial.h
new file mode 100644
index 000000000..c4014f013
--- /dev/null
+++ b/arch/arm/mach-omap2/serial.h
@@ -0,0 +1 @@
+#include <mach/serial.h>
diff --git a/arch/arm/mach-omap2/sleep24xx.S b/arch/arm/mach-omap2/sleep24xx.S
new file mode 100644
index 000000000..1d3cb25c9
--- /dev/null
+++ b/arch/arm/mach-omap2/sleep24xx.S
@@ -0,0 +1,105 @@
+/*
+ * 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 "omap24xx.h"
+#include "sdrc.h"
+
+/* First address of reserved address space? apparently valid for OMAP2 & 3 */
+#define A_SDRC0_V (0xC0000000)
+
+ .text
+
+/*
+ * 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 000000000..eafd120b5
--- /dev/null
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -0,0 +1,598 @@
+/*
+ * (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 "omap34xx.h"
+#include "iomap.h"
+#include "cm3xxx.h"
+#include "prm3xxx.h"
+#include "sdrc.h"
+#include "sram.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
+ */
+
+ .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!, {r4 - r11, 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!, {r4 - r11, 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:
+ * - only the minimum set of functions gets copied to internal SRAM at boot
+ * and after wake-up from OFF mode, cf. omap_push_sram_idle. The function
+ * pointers in SDRAM or SRAM are called depending on the desired low power
+ * target state.
+ * - 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!, {r4 - r11, lr} @ save registers on stack
+
+ /*
+ * r0 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
+ */
+
+ /*
+ * For OFF mode: save context and jump to WFI in SDRAM (omap3_do_wfi)
+ * For non-OFF modes: jump to the WFI code in SRAM (omap3_do_wfi_sram)
+ */
+ ldr r4, omap3_do_wfi_sram_addr
+ ldr r5, [r4]
+ cmp r0, #0x0 @ If no context save required,
+ bxeq r5 @ jump to the WFI code in SRAM
+
+
+ /* Otherwise fall through to the save context code */
+save_context_wfi:
+ /*
+ * 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
+ b omap3_do_wfi
+ENDPROC(omap34xx_cpu_suspend)
+omap3_do_wfi_sram_addr:
+ .word omap3_do_wfi_sram
+kernel_flush:
+ .word v7_flush_dcache_all
+
+/* ===================================
+ * == WFI instruction => Enter idle ==
+ * ===================================
+ */
+
+/*
+ * Do WFI instruction
+ * Includes the resume path for non-OFF modes
+ *
+ * This code gets copied to internal SRAM and is accessible
+ * from both SDRAM and SRAM:
+ * - executed from SRAM for non-off modes (omap3_do_wfi_sram),
+ * - executed from SDRAM for OFF mode (omap3_do_wfi).
+ */
+ .align 3
+ENTRY(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
+
+/*
+ * 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
+ bne exit_nonoff_modes @ 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
+ b exit_nonoff_modes @ 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
+
+exit_nonoff_modes:
+ /* Re-enable C-bit if needed */
+ 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!, {r4 - r11, pc} @ restore regs and return
+ENDPROC(omap3_do_wfi)
+sdrc_power:
+ .word SDRC_POWER_V
+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
+ /*
+ * 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
+
+ENTRY(omap3_do_wfi_sz)
+ .word . - omap3_do_wfi
+
+
+/*
+ * ==============================
+ * == 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
+ *
+ * Note: when back from CORE and MPU OFF mode we are running
+ * from SDRAM, without MMU, without the caches and prediction.
+ * Also the SRAM content has been cleared.
+ */
+ENTRY(omap3_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 omap3_restore @ Fall through to OMAP3 common code
+ 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 omap3_restore @ Fall through to OMAP3 common code
+ENDPROC(omap3_restore_es3)
+
+ENTRY(omap3_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 omap3_restore @ Fall through to OMAP3 common code
+ /* Disable RTA before giving control */
+ ldr r1, control_mem_rta
+ mov r2, #OMAP36XX_RTA_DISABLE
+ str r2, [r1]
+ENDPROC(omap3_restore_3630)
+
+ /* Fall through to common code for the remaining logic */
+
+ENTRY(omap3_restore)
+ /*
+ * Read the pwstctrl register to check the reason for mpu reset.
+ * This tells us what was 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
+ 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:
+
+ /* Now branch to the common CPU resume function */
+ b cpu_resume
+ENDPROC(omap3_restore)
+
+ .ltorg
+
+/*
+ * Local variables
+ */
+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
+control_stat:
+ .word CONTROL_STAT
+control_mem_rta:
+ .word CONTROL_MEM_RTA_CTRL
+l2dis_3630:
+ .word 0
+
+/*
+ * Internal functions
+ */
+
+/*
+ * This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0
+ * Copied to and run from SRAM in order to reconfigure the SDRC parameters.
+ */
+ .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
+
+/*
+ * Local variables
+ */
+ .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
diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S
new file mode 100644
index 000000000..ad1bb9431
--- /dev/null
+++ b/arch/arm/mach-omap2/sleep44xx.S
@@ -0,0 +1,385 @@
+/*
+ * OMAP44xx sleep code.
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * 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>
+#include <asm/assembler.h>
+#include <asm/smp_scu.h>
+#include <asm/memory.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "omap-secure.h"
+
+#include "common.h"
+#include "omap44xx.h"
+#include "omap4-sar-layout.h"
+
+#if defined(CONFIG_SMP) && defined(CONFIG_PM)
+
+.macro DO_SMC
+ dsb
+ smc #0
+ dsb
+.endm
+
+ppa_zero_params:
+ .word 0x0
+
+ppa_por_params:
+ .word 1, 0
+
+#ifdef CONFIG_ARCH_OMAP4
+
+/*
+ * =============================
+ * == CPU suspend finisher ==
+ * =============================
+ *
+ * void omap4_finish_suspend(unsigned long cpu_state)
+ *
+ * This function code saves the CPU context and performs the CPU
+ * power down sequence. Calling WFI effectively changes the CPU
+ * power domains states to the desired target power state.
+ *
+ * @cpu_state : contains context save state (r0)
+ * 0 - No context lost
+ * 1 - CPUx L1 and logic lost: MPUSS CSWR
+ * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
+ * 3 - CPUx L1 and logic lost + GIC + L2 lost: MPUSS OFF
+ * @return: This function never returns for CPU OFF and DORMANT power states.
+ * Post WFI, CPU transitions to DORMANT or OFF power state and on wake-up
+ * from this follows a full CPU reset path via ROM code to CPU restore code.
+ * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET.
+ * It returns to the caller for CPU INACTIVE and ON power states or in case
+ * CPU failed to transition to targeted OFF/DORMANT state.
+ *
+ * omap4_finish_suspend() calls v7_flush_dcache_all() which doesn't save
+ * stack frame and it expects the caller to take care of it. Hence the entire
+ * stack frame is saved to avoid possible stack corruption.
+ */
+ENTRY(omap4_finish_suspend)
+ stmfd sp!, {r4-r12, lr}
+ cmp r0, #0x0
+ beq do_WFI @ No lowpower state, jump to WFI
+
+ /*
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ bl omap4_get_sar_ram_base
+ ldr r9, [r0, #OMAP_TYPE_OFFSET]
+ cmp r9, #0x1 @ Check for HS device
+ bne skip_secure_l1_clean
+ mov r0, #SCU_PM_NORMAL
+ mov r1, #0xFF @ clean seucre L1
+ stmfd r13!, {r4-r12, r14}
+ ldr r12, =OMAP4_MON_SCU_PWR_INDEX
+ DO_SMC
+ ldmfd r13!, {r4-r12, r14}
+skip_secure_l1_clean:
+ bl v7_flush_dcache_all
+
+ /*
+ * 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.
+ */
+ bl v7_flush_dcache_all
+
+ /*
+ * Switch the CPU from Symmetric Multiprocessing (SMP) mode
+ * to AsymmetricMultiprocessing (AMP) mode by programming
+ * the SCU power status to DORMANT or OFF mode.
+ * This enables the CPU to be taken out of coherency by
+ * preventing the CPU from receiving cache, TLB, or BTB
+ * maintenance operations broadcast by other CPUs in the cluster.
+ */
+ bl omap4_get_sar_ram_base
+ mov r8, r0
+ ldr r9, [r8, #OMAP_TYPE_OFFSET]
+ cmp r9, #0x1 @ Check for HS device
+ bne scu_gp_set
+ mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
+ ands r0, r0, #0x0f
+ ldreq r0, [r8, #SCU_OFFSET0]
+ ldrne r0, [r8, #SCU_OFFSET1]
+ mov r1, #0x00
+ stmfd r13!, {r4-r12, r14}
+ ldr r12, =OMAP4_MON_SCU_PWR_INDEX
+ DO_SMC
+ ldmfd r13!, {r4-r12, r14}
+ b skip_scu_gp_set
+scu_gp_set:
+ mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
+ ands r0, r0, #0x0f
+ ldreq r1, [r8, #SCU_OFFSET0]
+ ldrne r1, [r8, #SCU_OFFSET1]
+ bl omap4_get_scu_base
+ bl scu_power_mode
+skip_scu_gp_set:
+ mrc p15, 0, r0, c1, c1, 2 @ Read NSACR data
+ tst r0, #(1 << 18)
+ mrcne p15, 0, r0, c1, c0, 1
+ bicne r0, r0, #(1 << 6) @ Disable SMP bit
+ mcrne p15, 0, r0, c1, c0, 1
+ isb
+ dsb
+#ifdef CONFIG_CACHE_L2X0
+ /*
+ * Clean and invalidate the L2 cache.
+ * Common cache-l2x0.c functions can't be used here since it
+ * uses spinlocks. We are out of coherency here with data cache
+ * disabled. The spinlock implementation uses exclusive load/store
+ * instruction which can fail without data cache being enabled.
+ * OMAP4 hardware doesn't support exclusive monitor which can
+ * overcome exclusive access issue. Because of this, CPU can
+ * lead to deadlock.
+ */
+ bl omap4_get_sar_ram_base
+ mov r8, r0
+ mrc p15, 0, r5, c0, c0, 5 @ Read MPIDR
+ ands r5, r5, #0x0f
+ ldreq r0, [r8, #L2X0_SAVE_OFFSET0] @ Retrieve L2 state from SAR
+ ldrne r0, [r8, #L2X0_SAVE_OFFSET1] @ memory.
+ cmp r0, #3
+ bne do_WFI
+#ifdef CONFIG_PL310_ERRATA_727915
+ mov r0, #0x03
+ mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
+ DO_SMC
+#endif
+ bl omap4_get_l2cache_base
+ mov r2, r0
+ ldr r0, =0xffff
+ str r0, [r2, #L2X0_CLEAN_INV_WAY]
+wait:
+ ldr r0, [r2, #L2X0_CLEAN_INV_WAY]
+ ldr r1, =0xffff
+ ands r0, r0, r1
+ bne wait
+#ifdef CONFIG_PL310_ERRATA_727915
+ mov r0, #0x00
+ mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
+ DO_SMC
+#endif
+l2x_sync:
+ bl omap4_get_l2cache_base
+ mov r2, r0
+ mov r0, #0x0
+ str r0, [r2, #L2X0_CACHE_SYNC]
+sync:
+ ldr r0, [r2, #L2X0_CACHE_SYNC]
+ ands r0, r0, #0x1
+ bne sync
+#endif
+
+do_WFI:
+ bl omap_do_wfi
+
+ /*
+ * CPU is here when it failed to enter OFF/DORMANT or
+ * no low power state was attempted.
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ tst r0, #(1 << 2) @ Check C bit enabled?
+ orreq r0, r0, #(1 << 2) @ Enable the C bit
+ mcreq p15, 0, r0, c1, c0, 0
+ isb
+
+ /*
+ * Ensure the CPU power state is set to NORMAL in
+ * SCU power state so that CPU is back in coherency.
+ * In non-coherent mode CPU can lock-up and lead to
+ * system deadlock.
+ */
+ mrc p15, 0, r0, c1, c0, 1
+ tst r0, #(1 << 6) @ Check SMP bit enabled?
+ orreq r0, r0, #(1 << 6)
+ mcreq p15, 0, r0, c1, c0, 1
+ isb
+ bl omap4_get_sar_ram_base
+ mov r8, r0
+ ldr r9, [r8, #OMAP_TYPE_OFFSET]
+ cmp r9, #0x1 @ Check for HS device
+ bne scu_gp_clear
+ mov r0, #SCU_PM_NORMAL
+ mov r1, #0x00
+ stmfd r13!, {r4-r12, r14}
+ ldr r12, =OMAP4_MON_SCU_PWR_INDEX
+ DO_SMC
+ ldmfd r13!, {r4-r12, r14}
+ b skip_scu_gp_clear
+scu_gp_clear:
+ bl omap4_get_scu_base
+ mov r1, #SCU_PM_NORMAL
+ bl scu_power_mode
+skip_scu_gp_clear:
+ isb
+ dsb
+ ldmfd sp!, {r4-r12, pc}
+ENDPROC(omap4_finish_suspend)
+
+/*
+ * ============================
+ * == CPU resume entry point ==
+ * ============================
+ *
+ * void omap4_cpu_resume(void)
+ *
+ * ROM code jumps to this function while waking up from CPU
+ * OFF or DORMANT state. Physical address of the function is
+ * stored in the SAR RAM while entering to OFF or DORMANT mode.
+ * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET.
+ */
+ENTRY(omap4_cpu_resume)
+ /*
+ * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device.
+ * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA
+ * init and for CPU1, a secure PPA API provided. CPU0 must be ON
+ * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+.
+ * OMAP443X GP devices- SMP bit isn't accessible.
+ * OMAP446X GP devices - SMP bit access is enabled on both CPUs.
+ */
+ ldr r8, =OMAP44XX_SAR_RAM_BASE
+ ldr r9, [r8, #OMAP_TYPE_OFFSET]
+ cmp r9, #0x1 @ Skip if GP device
+ bne skip_ns_smp_enable
+ mrc p15, 0, r0, c0, c0, 5
+ ands r0, r0, #0x0f
+ beq skip_ns_smp_enable
+ppa_actrl_retry:
+ mov r0, #OMAP4_PPA_CPU_ACTRL_SMP_INDEX
+ adr r3, ppa_zero_params @ Pointer to parameters
+ mov r1, #0x0 @ Process ID
+ mov r2, #0x4 @ Flag
+ mov r6, #0xff
+ mov r12, #0x00 @ Secure Service ID
+ DO_SMC
+ cmp r0, #0x0 @ API returns 0 on success.
+ beq enable_smp_bit
+ b ppa_actrl_retry
+enable_smp_bit:
+ mrc p15, 0, r0, c1, c0, 1
+ tst r0, #(1 << 6) @ Check SMP bit enabled?
+ orreq r0, r0, #(1 << 6)
+ mcreq p15, 0, r0, c1, c0, 1
+ isb
+skip_ns_smp_enable:
+#ifdef CONFIG_CACHE_L2X0
+ /*
+ * Restore the L2 AUXCTRL and enable the L2 cache.
+ * OMAP4_MON_L2X0_AUXCTRL_INDEX = Program the L2X0 AUXCTRL
+ * OMAP4_MON_L2X0_CTRL_INDEX = Enable the L2 using L2X0 CTRL
+ * register r0 contains value to be programmed.
+ * L2 cache is already invalidate by ROM code as part
+ * of MPUSS OFF wakeup path.
+ */
+ ldr r2, =OMAP44XX_L2CACHE_BASE
+ ldr r0, [r2, #L2X0_CTRL]
+ and r0, #0x0f
+ cmp r0, #1
+ beq skip_l2en @ Skip if already enabled
+ ldr r3, =OMAP44XX_SAR_RAM_BASE
+ ldr r1, [r3, #OMAP_TYPE_OFFSET]
+ cmp r1, #0x1 @ Check for HS device
+ bne set_gp_por
+ ldr r0, =OMAP4_PPA_L2_POR_INDEX
+ ldr r1, =OMAP44XX_SAR_RAM_BASE
+ ldr r4, [r1, #L2X0_PREFETCH_CTRL_OFFSET]
+ adr r3, ppa_por_params
+ str r4, [r3, #0x04]
+ mov r1, #0x0 @ Process ID
+ mov r2, #0x4 @ Flag
+ mov r6, #0xff
+ mov r12, #0x00 @ Secure Service ID
+ DO_SMC
+ b set_aux_ctrl
+set_gp_por:
+ ldr r1, =OMAP44XX_SAR_RAM_BASE
+ ldr r0, [r1, #L2X0_PREFETCH_CTRL_OFFSET]
+ ldr r12, =OMAP4_MON_L2X0_PREFETCH_INDEX @ Setup L2 PREFETCH
+ DO_SMC
+set_aux_ctrl:
+ ldr r1, =OMAP44XX_SAR_RAM_BASE
+ ldr r0, [r1, #L2X0_AUXCTRL_OFFSET]
+ ldr r12, =OMAP4_MON_L2X0_AUXCTRL_INDEX @ Setup L2 AUXCTRL
+ DO_SMC
+ mov r0, #0x1
+ ldr r12, =OMAP4_MON_L2X0_CTRL_INDEX @ Enable L2 cache
+ DO_SMC
+skip_l2en:
+#endif
+
+ b cpu_resume @ Jump to generic resume
+ENDPROC(omap4_cpu_resume)
+#endif /* CONFIG_ARCH_OMAP4 */
+
+#endif /* defined(CONFIG_SMP) && defined(CONFIG_PM) */
+
+ENTRY(omap_bus_sync)
+ ret lr
+ENDPROC(omap_bus_sync)
+
+ENTRY(omap_do_wfi)
+ stmfd sp!, {lr}
+ /* Drain interconnect write buffers. */
+ bl omap_bus_sync
+
+ /*
+ * 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
+
+ /*
+ * Execute a WFI instruction and wait until the
+ * STANDBYWFI output is asserted to indicate that the
+ * CPU is in idle and low power state. CPU can specualatively
+ * prefetch the instructions so add NOPs after WFI. Sixteen
+ * NOPs as per Cortex-A9 pipeline.
+ */
+ wfi @ Wait For Interrupt
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ ldmfd sp!, {pc}
+ENDPROC(omap_do_wfi)
diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c
new file mode 100644
index 000000000..d3a588cf3
--- /dev/null
+++ b/arch/arm/mach-omap2/smartreflex-class3.c
@@ -0,0 +1,62 @@
+/*
+ * 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 <linux/power/smartreflex.h>
+#include "soc.h"
+#include "voltage.h"
+
+static int sr_class3_enable(struct omap_sr *sr)
+{
+ unsigned long volt = voltdm_get_voltage(sr->voltdm);
+
+ if (!volt) {
+ pr_warn("%s: Curr voltage unknown. Cannot enable %s\n",
+ __func__, sr->name);
+ return -ENODATA;
+ }
+
+ omap_vp_enable(sr->voltdm);
+ return sr_enable(sr, volt);
+}
+
+static int sr_class3_disable(struct omap_sr *sr, int is_volt_reset)
+{
+ sr_disable_errgen(sr);
+ omap_vp_disable(sr->voltdm);
+ sr_disable(sr);
+ if (is_volt_reset)
+ voltdm_reset(sr->voltdm);
+
+ return 0;
+}
+
+static int sr_class3_configure(struct omap_sr *sr)
+{
+ return sr_configure_errgen(sr);
+}
+
+/* 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);
+}
+omap_late_initcall(sr_class3_init);
diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h
new file mode 100644
index 000000000..f97654d11
--- /dev/null
+++ b/arch/arm/mach-omap2/soc.h
@@ -0,0 +1,558 @@
+/*
+ * 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/5 specific defines - Santosh Shilimkar<santosh.shilimkar@ti.com>
+ * Added DRA7xxx specific defines - Sricharan R<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 "omap24xx.h"
+#include "omap34xx.h"
+#include "omap44xx.h"
+#include "ti81xx.h"
+#include "am33xx.h"
+#include "omap54xx.h"
+
+#ifndef __ASSEMBLY__
+
+#include <linux/bitops.h>
+#include <linux/of.h>
+
+/*
+ * Test if multicore OMAP support is needed
+ */
+#undef MULTI_OMAP2
+#undef OMAP_NAME
+
+#ifdef CONFIG_ARCH_MULTIPLATFORM
+#define MULTI_OMAP2
+#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
+
+#ifdef CONFIG_SOC_OMAP5
+# ifdef OMAP_NAME
+# undef MULTI_OMAP2
+# define MULTI_OMAP2
+# else
+# define OMAP_NAME omap5
+# endif
+#endif
+
+#ifdef CONFIG_SOC_AM33XX
+# ifdef OMAP_NAME
+# undef MULTI_OMAP2
+# define MULTI_OMAP2
+# else
+# define OMAP_NAME am33xx
+# endif
+#endif
+
+#ifdef CONFIG_SOC_AM43XX
+# ifdef OMAP_NAME
+# undef MULTI_OMAP2
+# define MULTI_OMAP2
+# else
+# define OMAP_NAME am43xx
+# endif
+#endif
+
+#ifdef CONFIG_SOC_DRA7XX
+# ifdef OMAP_NAME
+# undef MULTI_OMAP2
+# define MULTI_OMAP2
+# else
+# define OMAP_NAME DRA7XX
+# endif
+#endif
+
+/*
+ * 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);
+
+/*
+ * 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);
+
+static inline int soc_is_omap(void)
+{
+ return omap_rev() != 0;
+}
+
+/*
+ * 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_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
+ * cpu_is_omap446x(): True for OMAP4460
+ * cpu_is_omap447x(): True for OMAP4470
+ * soc_is_omap543x(): True for OMAP5430, OMAP5432
+ */
+#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_AM_CLASS ((omap_rev() >> 24) & 0xff)
+
+#define IS_AM_CLASS(class, id) \
+static inline int is_am ##class (void) \
+{ \
+ return (GET_AM_CLASS == (id)) ? 1 : 0; \
+}
+
+#define GET_TI_CLASS ((omap_rev() >> 24) & 0xff)
+
+#define IS_TI_CLASS(class, id) \
+static inline int is_ti ##class (void) \
+{ \
+ return (GET_TI_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; \
+}
+
+#define IS_AM_SUBCLASS(subclass, id) \
+static inline int is_am ##subclass (void) \
+{ \
+ return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \
+}
+
+IS_OMAP_CLASS(24xx, 0x24)
+IS_OMAP_CLASS(34xx, 0x34)
+IS_OMAP_CLASS(44xx, 0x44)
+IS_AM_CLASS(35xx, 0x35)
+IS_OMAP_CLASS(54xx, 0x54)
+IS_AM_CLASS(33xx, 0x33)
+IS_AM_CLASS(43xx, 0x43)
+
+IS_TI_CLASS(81xx, 0x81)
+
+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_OMAP_SUBCLASS(446x, 0x446)
+IS_OMAP_SUBCLASS(447x, 0x447)
+IS_OMAP_SUBCLASS(543x, 0x543)
+
+IS_TI_SUBCLASS(816x, 0x816)
+IS_TI_SUBCLASS(814x, 0x814)
+IS_AM_SUBCLASS(335x, 0x335)
+IS_AM_SUBCLASS(437x, 0x437)
+
+#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_ti81xx() 0
+#define cpu_is_ti816x() 0
+#define cpu_is_ti814x() 0
+#define soc_is_am35xx() 0
+#define soc_is_am33xx() 0
+#define soc_is_am335x() 0
+#define soc_is_am43xx() 0
+#define soc_is_am437x() 0
+#define cpu_is_omap44xx() 0
+#define cpu_is_omap443x() 0
+#define cpu_is_omap446x() 0
+#define cpu_is_omap447x() 0
+#define soc_is_omap54xx() 0
+#define soc_is_omap543x() 0
+#define soc_is_dra7xx() 0
+#define soc_is_dra74x() 0
+#define soc_is_dra72x() 0
+
+#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_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
+ */
+#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(2420, 0x2420)
+IS_OMAP_TYPE(2422, 0x2422)
+IS_OMAP_TYPE(2423, 0x2423)
+IS_OMAP_TYPE(2430, 0x2430)
+IS_OMAP_TYPE(3430, 0x3430)
+
+#define cpu_is_omap2420() 0
+#define cpu_is_omap2422() 0
+#define cpu_is_omap2423() 0
+#define cpu_is_omap2430() 0
+#define cpu_is_omap3430() 0
+#define cpu_is_omap3630() 0
+#define soc_is_omap5430() 0
+
+/* These are needed for the common code */
+#ifdef CONFIG_ARCH_OMAP2PLUS
+#define cpu_is_omap7xx() 0
+#define cpu_is_omap15xx() 0
+#define cpu_is_omap16xx() 0
+#define cpu_is_omap1510() 0
+#define cpu_is_omap1610() 0
+#define cpu_is_omap1611() 0
+#define cpu_is_omap1621() 0
+#define cpu_is_omap1710() 0
+#define cpu_class_is_omap1() 0
+#define cpu_class_is_omap2() 1
+#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_ti81xx
+# undef cpu_is_ti816x
+# undef cpu_is_ti814x
+# undef soc_is_am35xx
+# define cpu_is_omap3430() is_omap3430()
+# undef cpu_is_omap3630
+# define cpu_is_omap3630() is_omap363x()
+# define cpu_is_ti81xx() is_ti81xx()
+# define cpu_is_ti816x() is_ti816x()
+# define cpu_is_ti814x() is_ti814x()
+# define soc_is_am35xx() is_am35xx()
+#endif
+
+# if defined(CONFIG_SOC_AM33XX)
+# undef soc_is_am33xx
+# undef soc_is_am335x
+# define soc_is_am33xx() is_am33xx()
+# define soc_is_am335x() is_am335x()
+#endif
+
+#ifdef CONFIG_SOC_AM43XX
+# undef soc_is_am43xx
+# undef soc_is_am437x
+# define soc_is_am43xx() is_am43xx()
+# define soc_is_am437x() is_am437x()
+#endif
+
+# if defined(CONFIG_ARCH_OMAP4)
+# undef cpu_is_omap44xx
+# undef cpu_is_omap443x
+# undef cpu_is_omap446x
+# undef cpu_is_omap447x
+# define cpu_is_omap44xx() is_omap44xx()
+# define cpu_is_omap443x() is_omap443x()
+# define cpu_is_omap446x() is_omap446x()
+# define cpu_is_omap447x() is_omap447x()
+# endif
+
+# if defined(CONFIG_SOC_OMAP5)
+# undef soc_is_omap54xx
+# undef soc_is_omap543x
+# define soc_is_omap54xx() is_omap54xx()
+# define soc_is_omap543x() is_omap543x()
+#endif
+
+#if defined(CONFIG_SOC_DRA7XX)
+#undef soc_is_dra7xx
+#undef soc_is_dra74x
+#undef soc_is_dra72x
+#define soc_is_dra7xx() (of_machine_is_compatible("ti,dra7"))
+#define soc_is_dra74x() (of_machine_is_compatible("ti,dra74"))
+#define soc_is_dra72x() (of_machine_is_compatible("ti,dra72"))
+#endif
+
+/* Various silicon revisions for omap2 */
+#define OMAP242X_CLASS 0x24200024
+#define OMAP2420_REV_ES1_0 OMAP242X_CLASS
+#define OMAP2420_REV_ES2_0 (OMAP242X_CLASS | (0x1 << 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 | (0x1 << 8))
+#define OMAP3430_REV_ES2_1 (OMAP343X_CLASS | (0x2 << 8))
+#define OMAP3430_REV_ES3_0 (OMAP343X_CLASS | (0x3 << 8))
+#define OMAP3430_REV_ES3_1 (OMAP343X_CLASS | (0x4 << 8))
+#define OMAP3430_REV_ES3_1_2 (OMAP343X_CLASS | (0x5 << 8))
+
+#define OMAP363X_CLASS 0x36300034
+#define OMAP3630_REV_ES1_0 OMAP363X_CLASS
+#define OMAP3630_REV_ES1_1 (OMAP363X_CLASS | (0x1 << 8))
+#define OMAP3630_REV_ES1_2 (OMAP363X_CLASS | (0x2 << 8))
+
+#define TI816X_CLASS 0x81600081
+#define TI8168_REV_ES1_0 TI816X_CLASS
+#define TI8168_REV_ES1_1 (TI816X_CLASS | (0x1 << 8))
+#define TI8168_REV_ES2_0 (TI816X_CLASS | (0x2 << 8))
+#define TI8168_REV_ES2_1 (TI816X_CLASS | (0x3 << 8))
+
+#define TI814X_CLASS 0x81400081
+#define TI8148_REV_ES1_0 TI814X_CLASS
+#define TI8148_REV_ES2_0 (TI814X_CLASS | (0x1 << 8))
+#define TI8148_REV_ES2_1 (TI814X_CLASS | (0x2 << 8))
+
+#define AM35XX_CLASS 0x35170034
+#define AM35XX_REV_ES1_0 AM35XX_CLASS
+#define AM35XX_REV_ES1_1 (AM35XX_CLASS | (0x1 << 8))
+
+#define AM335X_CLASS 0x33500033
+#define AM335X_REV_ES1_0 AM335X_CLASS
+#define AM335X_REV_ES2_0 (AM335X_CLASS | (0x1 << 8))
+#define AM335X_REV_ES2_1 (AM335X_CLASS | (0x2 << 8))
+
+#define AM437X_CLASS 0x43700000
+#define AM437X_REV_ES1_0 (AM437X_CLASS | (0x10 << 8))
+#define AM437X_REV_ES1_1 (AM437X_CLASS | (0x11 << 8))
+#define AM437X_REV_ES1_2 (AM437X_CLASS | (0x12 << 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))
+#define OMAP4430_REV_ES2_3 (OMAP443X_CLASS | (0x23 << 8))
+
+#define OMAP446X_CLASS 0x44600044
+#define OMAP4460_REV_ES1_0 (OMAP446X_CLASS | (0x10 << 8))
+#define OMAP4460_REV_ES1_1 (OMAP446X_CLASS | (0x11 << 8))
+
+#define OMAP447X_CLASS 0x44700044
+#define OMAP4470_REV_ES1_0 (OMAP447X_CLASS | (0x10 << 8))
+
+#define OMAP54XX_CLASS 0x54000054
+#define OMAP5430_REV_ES2_0 (OMAP54XX_CLASS | (0x30 << 16) | (0x20 << 8))
+#define OMAP5432_REV_ES2_0 (OMAP54XX_CLASS | (0x32 << 16) | (0x20 << 8))
+
+#define DRA7XX_CLASS 0x07000000
+#define DRA752_REV_ES1_0 (DRA7XX_CLASS | (0x52 << 16) | (0x10 << 8))
+#define DRA752_REV_ES1_1 (DRA7XX_CLASS | (0x52 << 16) | (0x11 << 8))
+#define DRA722_REV_ES1_0 (DRA7XX_CLASS | (0x22 << 16) | (0x10 << 8))
+
+void omap2xxx_check_revision(void);
+void omap3xxx_check_revision(void);
+void omap4xxx_check_revision(void);
+void omap5xxx_check_revision(void);
+void dra7xxx_check_revision(void);
+void omap3xxx_check_features(void);
+void ti81xx_check_features(void);
+void am33xx_check_features(void);
+void omap4xxx_check_features(void);
+
+/*
+ * Runtime detection of OMAP3 features
+ *
+ * OMAP3_HAS_IO_CHAIN_CTRL: Some later members of the OMAP3 chip
+ * family have OS-level control over the I/O chain clock. This is
+ * to avoid a window during which wakeups could potentially be lost
+ * during powerdomain transitions. If this bit is set, it
+ * indicates that the chip does support OS-level control of this
+ * feature.
+ */
+extern u32 omap_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_IO_CHAIN_CTRL BIT(8)
+#define OMAP4_HAS_PERF_SILICON BIT(9)
+
+
+#define OMAP3_HAS_FEATURE(feat,flag) \
+static inline unsigned int omap3_has_ ##feat(void) \
+{ \
+ return omap_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)
+OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL)
+
+/*
+ * Runtime detection of OMAP4 features
+ */
+#define OMAP4_HAS_FEATURE(feat, flag) \
+static inline unsigned int omap4_has_ ##feat(void) \
+{ \
+ return omap_features & OMAP4_HAS_ ##flag; \
+} \
+
+OMAP4_HAS_FEATURE(perf_silicon, PERF_SILICON)
+
+/*
+ * We need to make sure omap initcalls don't run when
+ * multiplatform kernels are booted on other SoCs.
+ */
+#define omap_initcall(level, fn) \
+static int __init __used __##fn(void) \
+{ \
+ if (!soc_is_omap()) \
+ return 0; \
+ return fn(); \
+} \
+level(__##fn);
+
+#define omap_early_initcall(fn) omap_initcall(early_initcall, fn)
+#define omap_core_initcall(fn) omap_initcall(core_initcall, fn)
+#define omap_postcore_initcall(fn) omap_initcall(postcore_initcall, fn)
+#define omap_arch_initcall(fn) omap_initcall(arch_initcall, fn)
+#define omap_subsys_initcall(fn) omap_initcall(subsys_initcall, fn)
+#define omap_device_initcall(fn) omap_initcall(device_initcall, fn)
+#define omap_late_initcall(fn) omap_initcall(late_initcall, fn)
+#define omap_late_initcall_sync(fn) omap_initcall(late_initcall_sync, fn)
+
+#endif /* __ASSEMBLY__ */
+
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
new file mode 100644
index 000000000..d7cff2632
--- /dev/null
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -0,0 +1,177 @@
+/*
+ * 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/power/smartreflex.h>
+
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+#include "soc.h"
+#include "omap_device.h"
+#include "voltage.h"
+#include "control.h"
+#include "pm.h"
+
+static bool sr_enable_on_init;
+
+/* 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, j, count = 0;
+
+ sr_data->nvalue_count = 0;
+ sr_data->nvalue_table = NULL;
+
+ while (volt_data[count].volt_nominal)
+ count++;
+
+ nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count,
+ GFP_KERNEL);
+
+ if (!nvalue_table) {
+ pr_err("OMAP: SmartReflex: cannot allocate memory for n-value table\n");
+ return;
+ }
+
+ for (i = 0, j = 0; i < count; i++) {
+ u32 v;
+
+ /*
+ * In OMAP4 the efuse registers are 24 bit aligned.
+ * A readl_relaxed 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);
+ }
+
+ /*
+ * Many OMAP SoCs don't have the eFuse values set.
+ * For example, pretty much all OMAP3xxx before
+ * ES3.something.
+ *
+ * XXX There needs to be some way for board files or
+ * userspace to add these in.
+ */
+ if (v == 0)
+ continue;
+
+ nvalue_table[j].nvalue = v;
+ nvalue_table[j].efuse_offs = volt_data[i].sr_efuse_offs;
+ nvalue_table[j].errminlimit = volt_data[i].sr_errminlimit;
+ nvalue_table[j].volt_nominal = volt_data[i].volt_nominal;
+
+ j++;
+ }
+
+ sr_data->nvalue_table = nvalue_table;
+ sr_data->nvalue_count = j;
+}
+
+static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
+{
+ struct omap_sr_data *sr_data;
+ struct platform_device *pdev;
+ struct omap_volt_data *volt_data;
+ struct omap_smartreflex_dev_attr *sr_dev_attr;
+ 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\n",
+ __func__, oh->name);
+ return -ENOMEM;
+ }
+
+ sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr;
+ if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) {
+ pr_err("%s: No voltage domain specified for %s. Cannot initialize\n",
+ __func__, oh->name);
+ goto exit;
+ }
+
+ sr_data->name = oh->name;
+ sr_data->ip_type = oh->class->rev;
+ sr_data->senn_mod = 0x1;
+ sr_data->senp_mod = 0x1;
+
+ if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ sr_data->err_weight = OMAP3430_SR_ERRWEIGHT;
+ sr_data->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT;
+ sr_data->accum_data = OMAP3430_SR_ACCUMDATA;
+ if (!(strcmp(sr_data->name, "smartreflex_mpu"))) {
+ sr_data->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT;
+ sr_data->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT;
+ } else {
+ sr_data->senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT;
+ sr_data->senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT;
+ }
+ }
+
+ sr_data->voltdm = voltdm_lookup(sr_dev_attr->sensor_voltdm_name);
+ if (!sr_data->voltdm) {
+ pr_err("%s: Unable to get voltage domain pointer for VDD %s\n",
+ __func__, sr_dev_attr->sensor_voltdm_name);
+ goto exit;
+ }
+
+ omap_voltage_get_volttable(sr_data->voltdm, &volt_data);
+ if (!volt_data) {
+ pr_err("%s: No Voltage table registered for VDD%d\n",
+ __func__, i + 1);
+ goto exit;
+ }
+
+ sr_set_nvalues(volt_data, sr_data);
+
+ sr_data->enable_on_init = sr_enable_on_init;
+
+ pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data));
+ if (IS_ERR(pdev))
+ pr_warn("%s: Could not build omap_device for %s: %s\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/sram.c b/arch/arm/mach-omap2/sram.c
new file mode 100644
index 000000000..cd488b80b
--- /dev/null
+++ b/arch/arm/mach-omap2/sram.c
@@ -0,0 +1,271 @@
+/*
+ *
+ * OMAP SRAM detection and management
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * Copyright (C) 2009-2012 Texas Instruments
+ * Added OMAP4/5 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/fncpy.h>
+#include <asm/tlb.h>
+#include <asm/cacheflush.h>
+
+#include <asm/mach/map.h>
+
+#include "soc.h"
+#include "iomap.h"
+#include "prm2xxx_3xxx.h"
+#include "sdrc.h"
+#include "sram.h"
+
+#define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800)
+#define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000)
+
+#define SRAM_BOOTLOADER_SZ 0x00
+
+#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_skip;
+static unsigned long omap_sram_size;
+
+/*
+ * 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()) {
+ writel_relaxed(0xFF, OMAP24XX_VA_REQINFOPERM0); /* all q-vects */
+ writel_relaxed(0xCFDE, OMAP24XX_VA_READPERM0); /* all i-read */
+ writel_relaxed(0xCFDE, OMAP24XX_VA_WRITEPERM0); /* all i-write */
+ }
+ if (cpu_is_omap34xx()) {
+ writel_relaxed(0xFFFF, OMAP34XX_VA_REQINFOPERM0); /* all q-vects */
+ writel_relaxed(0xFFFF, OMAP34XX_VA_READPERM0); /* all i-read */
+ writel_relaxed(0xFFFF, OMAP34XX_VA_WRITEPERM0); /* all i-write */
+ writel_relaxed(0x0, OMAP34XX_VA_ADDR_MATCH2);
+ writel_relaxed(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)
+{
+ omap_sram_skip = SRAM_BOOTLOADER_SZ;
+ if (is_sram_locked()) {
+ if (cpu_is_omap34xx()) {
+ 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 */
+ omap_sram_skip += SZ_16K;
+ } else {
+ omap_sram_size = 0x8000; /* 32K */
+ }
+ } else {
+ omap_sram_start = OMAP2_SRAM_PUB_PA;
+ omap_sram_size = 0x800; /* 2K */
+ }
+ } else {
+ if (cpu_is_omap34xx()) {
+ omap_sram_start = OMAP3_SRAM_PA;
+ omap_sram_size = 0x10000; /* 64K */
+ } else {
+ 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 */
+ }
+ }
+}
+
+/*
+ * Note that we cannot use ioremap for SRAM, as clock init needs SRAM early.
+ */
+static void __init omap2_map_sram(void)
+{
+ int cached = 1;
+
+ 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.
+ */
+ cached = 0;
+ }
+
+ omap_map_sram(omap_sram_start, omap_sram_size,
+ omap_sram_skip, cached);
+}
+
+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);
+}
+
+#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);
+}
+
+void omap3_sram_restore_context(void)
+{
+ omap_sram_reset();
+
+ _omap3_sram_configure_core_dpll =
+ omap_sram_push(omap3_sram_configure_core_dpll,
+ omap3_sram_configure_core_dpll_sz);
+ omap_push_sram_idle();
+}
+
+static inline int omap34xx_sram_init(void)
+{
+ omap3_sram_restore_context();
+ return 0;
+}
+#else
+static inline int omap34xx_sram_init(void)
+{
+ return 0;
+}
+#endif /* CONFIG_ARCH_OMAP3 */
+
+int __init omap_sram_init(void)
+{
+ omap_detect_sram();
+ omap2_map_sram();
+
+ 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/mach-omap2/sram.h b/arch/arm/mach-omap2/sram.h
new file mode 100644
index 000000000..948d3edef
--- /dev/null
+++ b/arch/arm/mach-omap2/sram.h
@@ -0,0 +1,76 @@
+/*
+ * 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 __ASSEMBLY__
+#include <plat/sram.h>
+
+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 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
diff --git a/arch/arm/mach-omap2/sram242x.S b/arch/arm/mach-omap2/sram242x.S
new file mode 100644
index 000000000..2c88ff2d0
--- /dev/null
+++ b/arch/arm/mach-omap2/sram242x.S
@@ -0,0 +1,331 @@
+/*
+ * 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 "soc.h"
+#include "iomap.h"
+#include "prm2xxx.h"
+#include "cm2xxx.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
+ ret 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
+ ret 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
+ ret 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 000000000..d5deb9761
--- /dev/null
+++ b/arch/arm/mach-omap2/sram243x.S
@@ -0,0 +1,331 @@
+/*
+ * 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 "soc.h"
+#include "iomap.h"
+#include "prm2xxx.h"
+#include "cm2xxx.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
+ ret 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
+ ret 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
+ ret 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 000000000..1446331b5
--- /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 "soc.h"
+#include "iomap.h"
+#include "sdrc.h"
+#include "cm3xxx.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/ti81xx-restart.c b/arch/arm/mach-omap2/ti81xx-restart.c
new file mode 100644
index 000000000..6c3ce7c46
--- /dev/null
+++ b/arch/arm/mach-omap2/ti81xx-restart.c
@@ -0,0 +1,34 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it 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/reboot.h>
+
+#include "iomap.h"
+#include "common.h"
+#include "control.h"
+#include "prm3xxx.h"
+
+#define TI81XX_PRM_DEVICE_RSTCTRL 0x00a0
+#define TI81XX_GLOBAL_RST_COLD BIT(1)
+
+/**
+ * ti81xx_restart - trigger a software restart of the SoC
+ * @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c
+ * @cmd: passed from the userspace program rebooting the system (if provided)
+ *
+ * Resets the SoC. For @cmd, see the 'reboot' syscall in
+ * kernel/sys.c. No return value.
+ *
+ * NOTE: Warm reset does not seem to work, may require resetting
+ * clocks to bypass mode.
+ */
+void ti81xx_restart(enum reboot_mode mode, const char *cmd)
+{
+ omap2_prm_set_mod_reg_bits(TI81XX_GLOBAL_RST_COLD, 0,
+ TI81XX_PRM_DEVICE_RSTCTRL);
+ while (1);
+}
diff --git a/arch/arm/mach-omap2/ti81xx.h b/arch/arm/mach-omap2/ti81xx.h
new file mode 100644
index 000000000..a1e6caf0d
--- /dev/null
+++ b/arch/arm/mach-omap2/ti81xx.h
@@ -0,0 +1,36 @@
+/*
+ * This file contains the address data for various TI81XX 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_TI81XX_H
+#define __ASM_ARCH_TI81XX_H
+
+#define L4_SLOW_TI81XX_BASE 0x48000000
+
+#define TI81XX_SCM_BASE 0x48140000
+#define TI81XX_CTRL_BASE TI81XX_SCM_BASE
+#define TI81XX_PRCM_BASE 0x48180000
+
+/*
+ * Adjust TAP register base such that omap3_check_revision accesses the correct
+ * TI81XX register for checking device ID (it adds 0x204 to tap base while
+ * TI81XX DEVICE ID register is at offset 0x600 from control base).
+ */
+#define TI81XX_TAP_BASE (TI81XX_CTRL_BASE + \
+ TI81XX_CONTROL_DEVICE_ID - 0x204)
+
+
+#define TI81XX_ARM_INTC_BASE 0x48200000
+
+#endif /* __ASM_ARCH_TI81XX_H */
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
new file mode 100644
index 000000000..cac46d852
--- /dev/null
+++ b/arch/arm/mach-omap2/timer.c
@@ -0,0 +1,801 @@
+/*
+ * linux/arch/arm/mach-omap2/timer.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 <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/dmtimer-omap.h>
+#include <linux/sched_clock.h>
+
+#include <asm/mach/time.h>
+#include <asm/smp_twd.h>
+
+#include "omap_hwmod.h"
+#include "omap_device.h"
+#include <plat/counter-32k.h>
+#include <plat/dmtimer.h>
+#include "omap-pm.h"
+
+#include "soc.h"
+#include "common.h"
+#include "control.h"
+#include "powerdomain.h"
+#include "omap-secure.h"
+
+#define REALTIME_COUNTER_BASE 0x48243200
+#define INCREMENTER_NUMERATOR_OFFSET 0x10
+#define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14
+#define NUMERATOR_DENUMERATOR_MASK 0xfffff000
+
+/* Clockevent code */
+
+static struct omap_dm_timer clkev;
+static struct clock_event_device clockevent_gpt;
+
+#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
+static unsigned long arch_timer_freq;
+
+void set_cntfreq(void)
+{
+ omap_smc1(OMAP5_DRA7_MON_SET_CNTFRQ_INDEX, arch_timer_freq);
+}
+#endif
+
+static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_gpt;
+
+ __omap_dm_timer_write_status(&clkev, OMAP_TIMER_INT_OVERFLOW);
+
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction omap2_gp_timer_irq = {
+ .name = "gp_timer",
+ .flags = 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_load_start(&clkev, OMAP_TIMER_CTRL_ST,
+ 0xffffffff - cycles, OMAP_TIMER_POSTED);
+
+ 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(&clkev, OMAP_TIMER_POSTED, clkev.rate);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ period = clkev.rate / HZ;
+ period -= 1;
+ /* Looks like we need to first set the load value separately */
+ __omap_dm_timer_write(&clkev, OMAP_TIMER_LOAD_REG,
+ 0xffffffff - period, OMAP_TIMER_POSTED);
+ __omap_dm_timer_load_start(&clkev,
+ OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST,
+ 0xffffffff - period, OMAP_TIMER_POSTED);
+ 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 = {
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 300,
+ .set_next_event = omap2_gp_timer_set_next_event,
+ .set_mode = omap2_gp_timer_set_mode,
+};
+
+static struct property device_disabled = {
+ .name = "status",
+ .length = sizeof("disabled"),
+ .value = "disabled",
+};
+
+static const struct of_device_id omap_timer_match[] __initconst = {
+ { .compatible = "ti,omap2420-timer", },
+ { .compatible = "ti,omap3430-timer", },
+ { .compatible = "ti,omap4430-timer", },
+ { .compatible = "ti,omap5430-timer", },
+ { .compatible = "ti,dm814-timer", },
+ { .compatible = "ti,dm816-timer", },
+ { .compatible = "ti,am335x-timer", },
+ { .compatible = "ti,am335x-timer-1ms", },
+ { }
+};
+
+/**
+ * omap_get_timer_dt - get a timer using device-tree
+ * @match - device-tree match structure for matching a device type
+ * @property - optional timer property to match
+ *
+ * Helper function to get a timer during early boot using device-tree for use
+ * as kernel system timer. Optionally, the property argument can be used to
+ * select a timer with a specific property. Once a timer is found then mark
+ * the timer node in device-tree as disabled, to prevent the kernel from
+ * registering this timer as a platform device and so no one else can use it.
+ */
+static struct device_node * __init omap_get_timer_dt(const struct of_device_id *match,
+ const char *property)
+{
+ struct device_node *np;
+
+ for_each_matching_node(np, match) {
+ if (!of_device_is_available(np))
+ continue;
+
+ if (property && !of_get_property(np, property, NULL))
+ continue;
+
+ if (!property && (of_get_property(np, "ti,timer-alwon", NULL) ||
+ of_get_property(np, "ti,timer-dsp", NULL) ||
+ of_get_property(np, "ti,timer-pwm", NULL) ||
+ of_get_property(np, "ti,timer-secure", NULL)))
+ continue;
+
+ of_add_property(np, &device_disabled);
+ return np;
+ }
+
+ return NULL;
+}
+
+/**
+ * omap_dmtimer_init - initialisation function when device tree is used
+ *
+ * For secure OMAP3 devices, timers with device type "timer-secure" cannot
+ * be used by the kernel as they are reserved. Therefore, to prevent the
+ * kernel registering these devices remove them dynamically from the device
+ * tree on boot.
+ */
+static void __init omap_dmtimer_init(void)
+{
+ struct device_node *np;
+
+ if (!cpu_is_omap34xx())
+ return;
+
+ /* If we are a secure device, remove any secure timer nodes */
+ if ((omap_type() != OMAP2_DEVICE_TYPE_GP)) {
+ np = omap_get_timer_dt(omap_timer_match, "ti,timer-secure");
+ if (np)
+ of_node_put(np);
+ }
+}
+
+/**
+ * omap_dm_timer_get_errata - get errata flags for a timer
+ *
+ * Get the timer errata flags that are specific to the OMAP device being used.
+ */
+static u32 __init omap_dm_timer_get_errata(void)
+{
+ if (cpu_is_omap24xx())
+ return 0;
+
+ return OMAP_TIMER_ERRATA_I103_I767;
+}
+
+static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
+ const char *fck_source,
+ const char *property,
+ const char **timer_name,
+ int posted)
+{
+ char name[10]; /* 10 = sizeof("gptXX_Xck0") */
+ const char *oh_name = NULL;
+ struct device_node *np;
+ struct omap_hwmod *oh;
+ struct resource irq, mem;
+ struct clk *src;
+ int r = 0;
+
+ if (of_have_populated_dt()) {
+ np = omap_get_timer_dt(omap_timer_match, property);
+ if (!np)
+ return -ENODEV;
+
+ of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
+ if (!oh_name)
+ return -ENODEV;
+
+ timer->irq = irq_of_parse_and_map(np, 0);
+ if (!timer->irq)
+ return -ENXIO;
+
+ timer->io_base = of_iomap(np, 0);
+
+ of_node_put(np);
+ } else {
+ if (omap_dm_timer_reserve_systimer(timer->id))
+ return -ENODEV;
+
+ sprintf(name, "timer%d", timer->id);
+ oh_name = name;
+ }
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh)
+ return -ENODEV;
+
+ *timer_name = oh->name;
+
+ if (!of_have_populated_dt()) {
+ r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL,
+ &irq);
+ if (r)
+ return -ENXIO;
+ timer->irq = irq.start;
+
+ r = omap_hwmod_get_resource_byname(oh, IORESOURCE_MEM, NULL,
+ &mem);
+ if (r)
+ return -ENXIO;
+
+ /* Static mapping, never released */
+ timer->io_base = ioremap(mem.start, mem.end - mem.start);
+ }
+
+ if (!timer->io_base)
+ return -ENXIO;
+
+ /* After the dmtimer is using hwmod these clocks won't be needed */
+ timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh));
+ if (IS_ERR(timer->fclk))
+ return PTR_ERR(timer->fclk);
+
+ src = clk_get(NULL, fck_source);
+ if (IS_ERR(src))
+ return PTR_ERR(src);
+
+ r = clk_set_parent(timer->fclk, src);
+ if (r < 0) {
+ pr_warn("%s: %s cannot set source\n", __func__, oh->name);
+ clk_put(src);
+ return r;
+ }
+
+ clk_put(src);
+
+ omap_hwmod_setup_one(oh_name);
+ omap_hwmod_enable(oh);
+ __omap_dm_timer_init_regs(timer);
+
+ if (posted)
+ __omap_dm_timer_enable_posted(timer);
+
+ /* Check that the intended posted configuration matches the actual */
+ if (posted != timer->posted)
+ return -EINVAL;
+
+ timer->rate = clk_get_rate(timer->fclk);
+ timer->reserved = 1;
+
+ return r;
+}
+
+static void __init omap2_gp_clockevent_init(int gptimer_id,
+ const char *fck_source,
+ const char *property)
+{
+ int res;
+
+ clkev.id = gptimer_id;
+ clkev.errata = omap_dm_timer_get_errata();
+
+ /*
+ * For clock-event timers we never read the timer counter and
+ * so we are not impacted by errata i103 and i767. Therefore,
+ * we can safely ignore this errata for clock-event timers.
+ */
+ __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767);
+
+ res = omap_dm_timer_init_one(&clkev, fck_source, property,
+ &clockevent_gpt.name, OMAP_TIMER_POSTED);
+ BUG_ON(res);
+
+ omap2_gp_timer_irq.dev_id = &clkev;
+ setup_irq(clkev.irq, &omap2_gp_timer_irq);
+
+ __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
+
+ clockevent_gpt.cpumask = cpu_possible_mask;
+ clockevent_gpt.irq = omap_dm_timer_get_irq(&clkev);
+ clockevents_config_and_register(&clockevent_gpt, clkev.rate,
+ 3, /* Timer internal resynch latency */
+ 0xffffffff);
+
+ pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name,
+ clkev.rate);
+}
+
+/* Clocksource code */
+static struct omap_dm_timer clksrc;
+static bool use_gptimer_clksrc __initdata;
+
+/*
+ * clocksource
+ */
+static cycle_t clocksource_read_cycles(struct clocksource *cs)
+{
+ return (cycle_t)__omap_dm_timer_read_counter(&clksrc,
+ OMAP_TIMER_NONPOSTED);
+}
+
+static struct clocksource clocksource_gpt = {
+ .rating = 300,
+ .read = clocksource_read_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static u64 notrace dmtimer_read_sched_clock(void)
+{
+ if (clksrc.reserved)
+ return __omap_dm_timer_read_counter(&clksrc,
+ OMAP_TIMER_NONPOSTED);
+
+ return 0;
+}
+
+static const struct of_device_id omap_counter_match[] __initconst = {
+ { .compatible = "ti,omap-counter32k", },
+ { }
+};
+
+/* Setup free-running counter for clocksource */
+static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
+{
+ int ret;
+ struct device_node *np = NULL;
+ struct omap_hwmod *oh;
+ void __iomem *vbase;
+ const char *oh_name = "counter_32k";
+
+ /*
+ * If device-tree is present, then search the DT blob
+ * to see if the 32kHz counter is supported.
+ */
+ if (of_have_populated_dt()) {
+ np = omap_get_timer_dt(omap_counter_match, NULL);
+ if (!np)
+ return -ENODEV;
+
+ of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
+ if (!oh_name)
+ return -ENODEV;
+ }
+
+ /*
+ * First check hwmod data is available for sync32k counter
+ */
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh || oh->slaves_cnt == 0)
+ return -ENODEV;
+
+ omap_hwmod_setup_one(oh_name);
+
+ if (np) {
+ vbase = of_iomap(np, 0);
+ of_node_put(np);
+ } else {
+ vbase = omap_hwmod_get_mpu_rt_va(oh);
+ }
+
+ if (!vbase) {
+ pr_warn("%s: failed to get counter_32k resource\n", __func__);
+ return -ENXIO;
+ }
+
+ ret = omap_hwmod_enable(oh);
+ if (ret) {
+ pr_warn("%s: failed to enable counter_32k module (%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = omap_init_clocksource_32k(vbase);
+ if (ret) {
+ pr_warn("%s: failed to initialize counter_32k as a clocksource (%d)\n",
+ __func__, ret);
+ omap_hwmod_idle(oh);
+ }
+
+ return ret;
+}
+
+static void __init omap2_gptimer_clocksource_init(int gptimer_id,
+ const char *fck_source,
+ const char *property)
+{
+ int res;
+
+ clksrc.id = gptimer_id;
+ clksrc.errata = omap_dm_timer_get_errata();
+
+ res = omap_dm_timer_init_one(&clksrc, fck_source, property,
+ &clocksource_gpt.name,
+ OMAP_TIMER_NONPOSTED);
+ BUG_ON(res);
+
+ __omap_dm_timer_load_start(&clksrc,
+ OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0,
+ OMAP_TIMER_NONPOSTED);
+ sched_clock_register(dmtimer_read_sched_clock, 32, clksrc.rate);
+
+ if (clocksource_register_hz(&clocksource_gpt, clksrc.rate))
+ pr_err("Could not register clocksource %s\n",
+ clocksource_gpt.name);
+ else
+ pr_info("OMAP clocksource: %s at %lu Hz\n",
+ clocksource_gpt.name, clksrc.rate);
+}
+
+#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
+/*
+ * The realtime counter also called master counter, is a free-running
+ * counter, which is related to real time. It produces the count used
+ * by the CPU local timer peripherals in the MPU cluster. The timer counts
+ * at a rate of 6.144 MHz. Because the device operates on different clocks
+ * in different power modes, the master counter shifts operation between
+ * clocks, adjusting the increment per clock in hardware accordingly to
+ * maintain a constant count rate.
+ */
+static void __init realtime_counter_init(void)
+{
+ void __iomem *base;
+ static struct clk *sys_clk;
+ unsigned long rate;
+ unsigned int reg;
+ unsigned long long num, den;
+
+ base = ioremap(REALTIME_COUNTER_BASE, SZ_32);
+ if (!base) {
+ pr_err("%s: ioremap failed\n", __func__);
+ return;
+ }
+ sys_clk = clk_get(NULL, "sys_clkin");
+ if (IS_ERR(sys_clk)) {
+ pr_err("%s: failed to get system clock handle\n", __func__);
+ iounmap(base);
+ return;
+ }
+
+ rate = clk_get_rate(sys_clk);
+
+ if (soc_is_dra7xx()) {
+ /*
+ * Errata i856 says the 32.768KHz crystal does not start at
+ * power on, so the CPU falls back to an emulated 32KHz clock
+ * based on sysclk / 610 instead. This causes the master counter
+ * frequency to not be 6.144MHz but at sysclk / 610 * 375 / 2
+ * (OR sysclk * 75 / 244)
+ *
+ * This affects at least the DRA7/AM572x 1.0, 1.1 revisions.
+ * Of course any board built without a populated 32.768KHz
+ * crystal would also need this fix even if the CPU is fixed
+ * later.
+ *
+ * Either case can be detected by using the two speedselect bits
+ * If they are not 0, then the 32.768KHz clock driving the
+ * coarse counter that corrects the fine counter every time it
+ * ticks is actually rate/610 rather than 32.768KHz and we
+ * should compensate to avoid the 570ppm (at 20MHz, much worse
+ * at other rates) too fast system time.
+ */
+ reg = omap_ctrl_readl(DRA7_CTRL_CORE_BOOTSTRAP);
+ if (reg & DRA7_SPEEDSELECT_MASK) {
+ num = 75;
+ den = 244;
+ goto sysclk1_based;
+ }
+ }
+
+ /* Numerator/denumerator values refer TRM Realtime Counter section */
+ switch (rate) {
+ case 12000000:
+ num = 64;
+ den = 125;
+ break;
+ case 13000000:
+ num = 768;
+ den = 1625;
+ break;
+ case 19200000:
+ num = 8;
+ den = 25;
+ break;
+ case 20000000:
+ num = 192;
+ den = 625;
+ break;
+ case 26000000:
+ num = 384;
+ den = 1625;
+ break;
+ case 27000000:
+ num = 256;
+ den = 1125;
+ break;
+ case 38400000:
+ default:
+ /* Program it for 38.4 MHz */
+ num = 4;
+ den = 25;
+ break;
+ }
+
+sysclk1_based:
+ /* Program numerator and denumerator registers */
+ reg = readl_relaxed(base + INCREMENTER_NUMERATOR_OFFSET) &
+ NUMERATOR_DENUMERATOR_MASK;
+ reg |= num;
+ writel_relaxed(reg, base + INCREMENTER_NUMERATOR_OFFSET);
+
+ reg = readl_relaxed(base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET) &
+ NUMERATOR_DENUMERATOR_MASK;
+ reg |= den;
+ writel_relaxed(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET);
+
+ arch_timer_freq = DIV_ROUND_UP_ULL(rate * num, den);
+ set_cntfreq();
+
+ iounmap(base);
+}
+#else
+static inline void __init realtime_counter_init(void)
+{}
+#endif
+
+#define OMAP_SYS_GP_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \
+ clksrc_nr, clksrc_src, clksrc_prop) \
+void __init omap##name##_gptimer_timer_init(void) \
+{ \
+ omap_clk_init(); \
+ omap_dmtimer_init(); \
+ omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \
+ omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \
+ clksrc_prop); \
+}
+
+#define OMAP_SYS_32K_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \
+ clksrc_nr, clksrc_src, clksrc_prop) \
+void __init omap##name##_sync32k_timer_init(void) \
+{ \
+ omap_clk_init(); \
+ omap_dmtimer_init(); \
+ omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \
+ /* Enable the use of clocksource="gp_timer" kernel parameter */ \
+ if (use_gptimer_clksrc) \
+ omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \
+ clksrc_prop); \
+ else \
+ omap2_sync32k_clocksource_init(); \
+}
+
+#ifdef CONFIG_ARCH_OMAP2
+OMAP_SYS_32K_TIMER_INIT(2, 1, "timer_32k_ck", "ti,timer-alwon",
+ 2, "timer_sys_ck", NULL);
+#endif /* CONFIG_ARCH_OMAP2 */
+
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM43XX)
+OMAP_SYS_32K_TIMER_INIT(3, 1, "timer_32k_ck", "ti,timer-alwon",
+ 2, "timer_sys_ck", NULL);
+OMAP_SYS_32K_TIMER_INIT(3_secure, 12, "secure_32k_fck", "ti,timer-secure",
+ 2, "timer_sys_ck", NULL);
+#endif /* CONFIG_ARCH_OMAP3 */
+
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) || \
+ defined(CONFIG_SOC_AM43XX)
+OMAP_SYS_GP_TIMER_INIT(3, 2, "timer_sys_ck", NULL,
+ 1, "timer_sys_ck", "ti,timer-alwon");
+#endif
+
+#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
+ defined(CONFIG_SOC_DRA7XX)
+static OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon",
+ 2, "sys_clkin_ck", NULL);
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+#ifdef CONFIG_HAVE_ARM_TWD
+static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29);
+void __init omap4_local_timer_init(void)
+{
+ omap4_sync32k_timer_init();
+ /* Local timers are not supprted on OMAP4430 ES1.0 */
+ if (omap_rev() != OMAP4430_REV_ES1_0) {
+ int err;
+
+ if (of_have_populated_dt()) {
+ clocksource_of_init();
+ return;
+ }
+
+ err = twd_local_timer_register(&twd_local_timer);
+ if (err)
+ pr_err("twd_local_timer_register failed %d\n", err);
+ }
+}
+#else
+void __init omap4_local_timer_init(void)
+{
+ omap4_sync32k_timer_init();
+}
+#endif /* CONFIG_HAVE_ARM_TWD */
+#endif /* CONFIG_ARCH_OMAP4 */
+
+#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX)
+void __init omap5_realtime_timer_init(void)
+{
+ omap4_sync32k_timer_init();
+ realtime_counter_init();
+
+ clocksource_of_init();
+}
+#endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */
+
+/**
+ * omap_timer_init - build and register timer device with an
+ * associated timer hwmod
+ * @oh: timer hwmod pointer to be used to build timer device
+ * @user: parameter that can be passed from calling hwmod API
+ *
+ * Called by omap_hwmod_for_each_by_class to register each of the timer
+ * devices present in the system. The number of timer devices is known
+ * by parsing through the hwmod database for a given class name. At the
+ * end of function call memory is allocated for timer device and it is
+ * registered to the framework ready to be proved by the driver.
+ */
+static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
+{
+ int id;
+ int ret = 0;
+ char *name = "omap_timer";
+ struct dmtimer_platform_data *pdata;
+ struct platform_device *pdev;
+ struct omap_timer_capability_dev_attr *timer_dev_attr;
+
+ pr_debug("%s: %s\n", __func__, oh->name);
+
+ /* on secure device, do not register secure timer */
+ timer_dev_attr = oh->dev_attr;
+ if (omap_type() != OMAP2_DEVICE_TYPE_GP && timer_dev_attr)
+ if (timer_dev_attr->timer_capability == OMAP_TIMER_SECURE)
+ return ret;
+
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ pr_err("%s: No memory for [%s]\n", __func__, oh->name);
+ return -ENOMEM;
+ }
+
+ /*
+ * Extract the IDs from name field in hwmod database
+ * and use the same for constructing ids' for the
+ * timer devices. In a way, we are avoiding usage of
+ * static variable witin the function to do the same.
+ * CAUTION: We have to be careful and make sure the
+ * name in hwmod database does not change in which case
+ * we might either make corresponding change here or
+ * switch back static variable mechanism.
+ */
+ sscanf(oh->name, "timer%2d", &id);
+
+ if (timer_dev_attr)
+ pdata->timer_capability = timer_dev_attr->timer_capability;
+
+ pdata->timer_errata = omap_dm_timer_get_errata();
+ pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
+
+ pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata));
+
+ if (IS_ERR(pdev)) {
+ pr_err("%s: Can't build omap_device for %s: %s.\n",
+ __func__, name, oh->name);
+ ret = -EINVAL;
+ }
+
+ kfree(pdata);
+
+ return ret;
+}
+
+/**
+ * omap2_dm_timer_init - top level regular device initialization
+ *
+ * Uses dedicated hwmod api to parse through hwmod database for
+ * given class name and then build and register the timer device.
+ */
+static int __init omap2_dm_timer_init(void)
+{
+ int ret;
+
+ /* If dtb is there, the devices will be created dynamically */
+ if (of_have_populated_dt())
+ return -ENODEV;
+
+ ret = omap_hwmod_for_each_by_class("timer", omap_timer_init, NULL);
+ if (unlikely(ret)) {
+ pr_err("%s: device registration failed.\n", __func__);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+omap_arch_initcall(omap2_dm_timer_init);
+
+/**
+ * omap2_override_clocksource - clocksource override with user configuration
+ *
+ * Allows user to override default clocksource, using kernel parameter
+ * clocksource="gp_timer" (For all OMAP2PLUS architectures)
+ *
+ * Note that, here we are using same standard kernel parameter "clocksource=",
+ * and not introducing any OMAP specific interface.
+ */
+static int __init omap2_override_clocksource(char *str)
+{
+ if (!str)
+ return 0;
+ /*
+ * For OMAP architecture, we only have two options
+ * - sync_32k (default)
+ * - gp_timer (sys_clk based)
+ */
+ if (!strcmp(str, "gp_timer"))
+ use_gptimer_clksrc = true;
+
+ return 0;
+}
+early_param("clocksource", omap2_override_clocksource);
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
new file mode 100644
index 000000000..292eca0e7
--- /dev/null
+++ b/arch/arm/mach-omap2/twl-common.c
@@ -0,0 +1,565 @@
+/*
+ * twl-common.c
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc..
+ * Author: Peter Ujfalusi <peter.ujfalusi@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., 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/string.h>
+#include <linux/phy/phy.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+
+#include "soc.h"
+#include "twl-common.h"
+#include "pm.h"
+#include "voltage.h"
+#include "mux.h"
+
+static struct i2c_board_info __initdata pmic_i2c_board_info = {
+ .addr = 0x48,
+ .flags = I2C_CLIENT_WAKE,
+};
+
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
+static int twl_set_voltage(void *data, int target_uV)
+{
+ struct voltagedomain *voltdm = (struct voltagedomain *)data;
+ return voltdm_scale(voltdm, target_uV);
+}
+
+static int twl_get_voltage(void *data)
+{
+ struct voltagedomain *voltdm = (struct voltagedomain *)data;
+ return voltdm_get_voltage(voltdm);
+}
+#endif
+
+void __init omap_pmic_init(int bus, u32 clkrate,
+ const char *pmic_type, int pmic_irq,
+ struct twl4030_platform_data *pmic_data)
+{
+ omap_mux_init_signal("sys_nirq", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE);
+ strlcpy(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);
+}
+
+#ifdef CONFIG_ARCH_OMAP4
+void __init omap4_pmic_init(const char *pmic_type,
+ struct twl4030_platform_data *pmic_data,
+ struct i2c_board_info *devices, int nr_devices)
+{
+ /* PMIC part*/
+ unsigned int irq;
+
+ omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE);
+ omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT);
+ irq = omap4_xlate_irq(7 + OMAP44XX_IRQ_GIC_START);
+ omap_pmic_init(1, 400, pmic_type, irq, pmic_data);
+
+ /* Register additional devices on i2c1 bus if needed */
+ if (devices)
+ i2c_register_board_info(1, devices, nr_devices);
+}
+#endif
+
+void __init omap_pmic_late_init(void)
+{
+ /* Init the OMAP TWL parameters (if PMIC has been registerd) */
+ if (!pmic_i2c_board_info.irq)
+ return;
+
+ omap3_twl_init();
+ omap4_twl_init();
+}
+
+#if defined(CONFIG_ARCH_OMAP3)
+static struct twl4030_usb_data omap3_usb_pdata = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static int omap3_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 omap3_bci_pdata = {
+ .battery_tmp_tbl = omap3_batt_table,
+ .tblsize = ARRAY_SIZE(omap3_batt_table),
+};
+
+static struct twl4030_madc_platform_data omap3_madc_pdata = {
+ .irq_line = 1,
+};
+
+static struct twl4030_codec_data omap3_codec;
+
+static struct twl4030_audio_data omap3_audio_pdata = {
+ .audio_mclk = 26000000,
+ .codec = &omap3_codec,
+};
+
+static struct regulator_consumer_supply omap3_vdda_dac_supplies[] = {
+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"),
+};
+
+static struct regulator_init_data omap3_vdac_idata = {
+ .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(omap3_vdda_dac_supplies),
+ .consumer_supplies = omap3_vdda_dac_supplies,
+};
+
+static struct regulator_consumer_supply omap3_vpll2_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dpi.0"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
+};
+
+static struct regulator_init_data omap3_vpll2_idata = {
+ .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(omap3_vpll2_supplies),
+ .consumer_supplies = omap3_vpll2_supplies,
+};
+
+static struct regulator_consumer_supply omap3_vdd1_supply[] = {
+ REGULATOR_SUPPLY("vcc", "cpu0"),
+};
+
+static struct regulator_consumer_supply omap3_vdd2_supply[] = {
+ REGULATOR_SUPPLY("vcc", "l3_main.0"),
+};
+
+static struct regulator_init_data omap3_vdd1 = {
+ .constraints = {
+ .name = "vdd_mpu_iva",
+ .min_uV = 600000,
+ .max_uV = 1450000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap3_vdd1_supply),
+ .consumer_supplies = omap3_vdd1_supply,
+};
+
+static struct regulator_init_data omap3_vdd2 = {
+ .constraints = {
+ .name = "vdd_core",
+ .min_uV = 600000,
+ .max_uV = 1450000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap3_vdd2_supply),
+ .consumer_supplies = omap3_vdd2_supply,
+};
+
+static struct twl_regulator_driver_data omap3_vdd1_drvdata = {
+ .get_voltage = twl_get_voltage,
+ .set_voltage = twl_set_voltage,
+};
+
+static struct twl_regulator_driver_data omap3_vdd2_drvdata = {
+ .get_voltage = twl_get_voltage,
+ .set_voltage = twl_set_voltage,
+};
+
+void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
+ u32 pdata_flags, u32 regulators_flags)
+{
+ if (!pmic_data->vdd1) {
+ omap3_vdd1.driver_data = &omap3_vdd1_drvdata;
+ omap3_vdd1_drvdata.data = voltdm_lookup("mpu_iva");
+ pmic_data->vdd1 = &omap3_vdd1;
+ }
+ if (!pmic_data->vdd2) {
+ omap3_vdd2.driver_data = &omap3_vdd2_drvdata;
+ omap3_vdd2_drvdata.data = voltdm_lookup("core");
+ pmic_data->vdd2 = &omap3_vdd2;
+ }
+
+ /* Common platform data configurations */
+ if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb)
+ pmic_data->usb = &omap3_usb_pdata;
+
+ if (pdata_flags & TWL_COMMON_PDATA_BCI && !pmic_data->bci)
+ pmic_data->bci = &omap3_bci_pdata;
+
+ if (pdata_flags & TWL_COMMON_PDATA_MADC && !pmic_data->madc)
+ pmic_data->madc = &omap3_madc_pdata;
+
+ if (pdata_flags & TWL_COMMON_PDATA_AUDIO && !pmic_data->audio)
+ pmic_data->audio = &omap3_audio_pdata;
+
+ /* Common regulator configurations */
+ if (regulators_flags & TWL_COMMON_REGULATOR_VDAC && !pmic_data->vdac)
+ pmic_data->vdac = &omap3_vdac_idata;
+
+ if (regulators_flags & TWL_COMMON_REGULATOR_VPLL2 && !pmic_data->vpll2)
+ pmic_data->vpll2 = &omap3_vpll2_idata;
+}
+#endif /* CONFIG_ARCH_OMAP3 */
+
+#if defined(CONFIG_ARCH_OMAP4)
+static struct twl4030_usb_data omap4_usb_pdata = {
+};
+
+static struct regulator_consumer_supply omap4_vdda_hdmi_dac_supplies[] = {
+ REGULATOR_SUPPLY("vdda_hdmi_dac", "omapdss_hdmi"),
+};
+
+static struct regulator_init_data omap4_vdac_idata = {
+ .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(omap4_vdda_hdmi_dac_supplies),
+ .consumer_supplies = omap4_vdda_hdmi_dac_supplies,
+ .supply_regulator = "V2V1",
+};
+
+static struct regulator_init_data omap4_vaux2_idata = {
+ .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_vaux3_idata = {
+ .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,
+ },
+};
+
+static struct regulator_consumer_supply omap4_vmmc_supply[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+/* VMMC1 for MMC1 card */
+static struct regulator_init_data omap4_vmmc_idata = {
+ .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 = ARRAY_SIZE(omap4_vmmc_supply),
+ .consumer_supplies = omap4_vmmc_supply,
+};
+
+static struct regulator_init_data omap4_vpp_idata = {
+ .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_vana_idata = {
+ .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_consumer_supply omap4_vcxio_supply[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.1"),
+};
+
+static struct regulator_init_data omap4_vcxio_idata = {
+ .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,
+ .always_on = true,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap4_vcxio_supply),
+ .consumer_supplies = omap4_vcxio_supply,
+ .supply_regulator = "V2V1",
+};
+
+static struct regulator_init_data omap4_vusb_idata = {
+ .constraints = {
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data omap4_clk32kg_idata = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_consumer_supply omap4_vdd1_supply[] = {
+ REGULATOR_SUPPLY("vcc", "cpu0"),
+};
+
+static struct regulator_consumer_supply omap4_vdd2_supply[] = {
+ REGULATOR_SUPPLY("vcc", "iva.0"),
+};
+
+static struct regulator_consumer_supply omap4_vdd3_supply[] = {
+ REGULATOR_SUPPLY("vcc", "l3_main.0"),
+};
+
+static struct regulator_init_data omap4_vdd1 = {
+ .constraints = {
+ .name = "vdd_mpu",
+ .min_uV = 500000,
+ .max_uV = 1500000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap4_vdd1_supply),
+ .consumer_supplies = omap4_vdd1_supply,
+};
+
+static struct regulator_init_data omap4_vdd2 = {
+ .constraints = {
+ .name = "vdd_iva",
+ .min_uV = 500000,
+ .max_uV = 1500000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap4_vdd2_supply),
+ .consumer_supplies = omap4_vdd2_supply,
+};
+
+static struct regulator_init_data omap4_vdd3 = {
+ .constraints = {
+ .name = "vdd_core",
+ .min_uV = 500000,
+ .max_uV = 1500000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap4_vdd3_supply),
+ .consumer_supplies = omap4_vdd3_supply,
+};
+
+
+static struct twl_regulator_driver_data omap4_vdd1_drvdata = {
+ .get_voltage = twl_get_voltage,
+ .set_voltage = twl_set_voltage,
+};
+
+static struct twl_regulator_driver_data omap4_vdd2_drvdata = {
+ .get_voltage = twl_get_voltage,
+ .set_voltage = twl_set_voltage,
+};
+
+static struct twl_regulator_driver_data omap4_vdd3_drvdata = {
+ .get_voltage = twl_get_voltage,
+ .set_voltage = twl_set_voltage,
+};
+
+static struct regulator_consumer_supply omap4_v1v8_supply[] = {
+ REGULATOR_SUPPLY("vio", "1-004b"),
+};
+
+static struct regulator_init_data omap4_v1v8_idata = {
+ .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,
+ .always_on = true,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap4_v1v8_supply),
+ .consumer_supplies = omap4_v1v8_supply,
+};
+
+static struct regulator_consumer_supply omap4_v2v1_supply[] = {
+ REGULATOR_SUPPLY("v2v1", "1-004b"),
+};
+
+static struct regulator_init_data omap4_v2v1_idata = {
+ .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,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap4_v2v1_supply),
+ .consumer_supplies = omap4_v2v1_supply,
+};
+
+void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
+ u32 pdata_flags, u32 regulators_flags)
+{
+ if (!pmic_data->vdd1) {
+ omap4_vdd1.driver_data = &omap4_vdd1_drvdata;
+ omap4_vdd1_drvdata.data = voltdm_lookup("mpu");
+ pmic_data->vdd1 = &omap4_vdd1;
+ }
+
+ if (!pmic_data->vdd2) {
+ omap4_vdd2.driver_data = &omap4_vdd2_drvdata;
+ omap4_vdd2_drvdata.data = voltdm_lookup("iva");
+ pmic_data->vdd2 = &omap4_vdd2;
+ }
+
+ if (!pmic_data->vdd3) {
+ omap4_vdd3.driver_data = &omap4_vdd3_drvdata;
+ omap4_vdd3_drvdata.data = voltdm_lookup("core");
+ pmic_data->vdd3 = &omap4_vdd3;
+ }
+
+ /* Common platform data configurations */
+ if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb)
+ pmic_data->usb = &omap4_usb_pdata;
+
+ /* Common regulator configurations */
+ if (regulators_flags & TWL_COMMON_REGULATOR_VDAC && !pmic_data->vdac)
+ pmic_data->vdac = &omap4_vdac_idata;
+
+ if (regulators_flags & TWL_COMMON_REGULATOR_VAUX2 && !pmic_data->vaux2)
+ pmic_data->vaux2 = &omap4_vaux2_idata;
+
+ if (regulators_flags & TWL_COMMON_REGULATOR_VAUX3 && !pmic_data->vaux3)
+ pmic_data->vaux3 = &omap4_vaux3_idata;
+
+ if (regulators_flags & TWL_COMMON_REGULATOR_VMMC && !pmic_data->vmmc)
+ pmic_data->vmmc = &omap4_vmmc_idata;
+
+ if (regulators_flags & TWL_COMMON_REGULATOR_VPP && !pmic_data->vpp)
+ pmic_data->vpp = &omap4_vpp_idata;
+
+ if (regulators_flags & TWL_COMMON_REGULATOR_VANA && !pmic_data->vana)
+ pmic_data->vana = &omap4_vana_idata;
+
+ if (regulators_flags & TWL_COMMON_REGULATOR_VCXIO && !pmic_data->vcxio)
+ pmic_data->vcxio = &omap4_vcxio_idata;
+
+ if (regulators_flags & TWL_COMMON_REGULATOR_VUSB && !pmic_data->vusb)
+ pmic_data->vusb = &omap4_vusb_idata;
+
+ if (regulators_flags & TWL_COMMON_REGULATOR_CLK32KG &&
+ !pmic_data->clk32kg)
+ pmic_data->clk32kg = &omap4_clk32kg_idata;
+
+ if (regulators_flags & TWL_COMMON_REGULATOR_V1V8 && !pmic_data->v1v8)
+ pmic_data->v1v8 = &omap4_v1v8_idata;
+
+ if (regulators_flags & TWL_COMMON_REGULATOR_V2V1 && !pmic_data->v2v1)
+ pmic_data->v2v1 = &omap4_v2v1_idata;
+}
+#endif /* CONFIG_ARCH_OMAP4 */
+
+#if defined(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) || \
+ defined(CONFIG_SND_OMAP_SOC_OMAP_TWL4030_MODULE)
+#include <linux/platform_data/omap-twl4030.h>
+
+/* Commonly used configuration */
+static struct omap_tw4030_pdata omap_twl4030_audio_data;
+
+static struct platform_device audio_device = {
+ .name = "omap-twl4030",
+ .id = -1,
+};
+
+void omap_twl4030_audio_init(char *card_name,
+ struct omap_tw4030_pdata *pdata)
+{
+ if (!pdata)
+ pdata = &omap_twl4030_audio_data;
+
+ pdata->card_name = card_name;
+
+ audio_device.dev.platform_data = pdata;
+ platform_device_register(&audio_device);
+}
+
+#else /* SOC_OMAP_TWL4030 */
+void omap_twl4030_audio_init(char *card_name,
+ struct omap_tw4030_pdata *pdata)
+{
+ return;
+}
+#endif /* SOC_OMAP_TWL4030 */
diff --git a/arch/arm/mach-omap2/twl-common.h b/arch/arm/mach-omap2/twl-common.h
new file mode 100644
index 000000000..24b65d081
--- /dev/null
+++ b/arch/arm/mach-omap2/twl-common.h
@@ -0,0 +1,66 @@
+#ifndef __OMAP_PMIC_COMMON__
+#define __OMAP_PMIC_COMMON__
+
+#include "common.h"
+
+#define TWL_COMMON_PDATA_USB (1 << 0)
+#define TWL_COMMON_PDATA_BCI (1 << 1)
+#define TWL_COMMON_PDATA_MADC (1 << 2)
+#define TWL_COMMON_PDATA_AUDIO (1 << 3)
+
+/* Common LDO regulators for TWL4030/TWL6030 */
+#define TWL_COMMON_REGULATOR_VDAC (1 << 0)
+#define TWL_COMMON_REGULATOR_VAUX1 (1 << 1)
+#define TWL_COMMON_REGULATOR_VAUX2 (1 << 2)
+#define TWL_COMMON_REGULATOR_VAUX3 (1 << 3)
+
+/* TWL6030 LDO regulators */
+#define TWL_COMMON_REGULATOR_VMMC (1 << 4)
+#define TWL_COMMON_REGULATOR_VPP (1 << 5)
+#define TWL_COMMON_REGULATOR_VUSIM (1 << 6)
+#define TWL_COMMON_REGULATOR_VANA (1 << 7)
+#define TWL_COMMON_REGULATOR_VCXIO (1 << 8)
+#define TWL_COMMON_REGULATOR_VUSB (1 << 9)
+#define TWL_COMMON_REGULATOR_CLK32KG (1 << 10)
+#define TWL_COMMON_REGULATOR_V1V8 (1 << 11)
+#define TWL_COMMON_REGULATOR_V2V1 (1 << 12)
+
+/* TWL4030 LDO regulators */
+#define TWL_COMMON_REGULATOR_VPLL1 (1 << 4)
+#define TWL_COMMON_REGULATOR_VPLL2 (1 << 5)
+
+
+struct twl4030_platform_data;
+struct twl6040_platform_data;
+struct omap_tw4030_pdata;
+struct i2c_board_info;
+
+void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq,
+ struct twl4030_platform_data *pmic_data);
+void omap_pmic_late_init(void);
+
+static inline void omap2_pmic_init(const char *pmic_type,
+ struct twl4030_platform_data *pmic_data)
+{
+ omap_pmic_init(2, 2600, pmic_type, 7 + OMAP_INTC_START, 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, 7 + OMAP_INTC_START, pmic_data);
+}
+
+void omap4_pmic_init(const char *pmic_type,
+ struct twl4030_platform_data *pmic_data,
+ struct i2c_board_info *devices, int nr_devices);
+
+void omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
+ u32 pdata_flags, u32 regulators_flags);
+
+void omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
+ u32 pdata_flags, u32 regulators_flags);
+
+void omap_twl4030_audio_init(char *card_name, struct omap_tw4030_pdata *pdata);
+
+#endif /* __OMAP_PMIC_COMMON__ */
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
new file mode 100644
index 000000000..745367c0c
--- /dev/null
+++ b/arch/arm/mach-omap2/usb-host.c
@@ -0,0 +1,496 @@
+/*
+ * 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 <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/usb/phy.h>
+#include <linux/usb/usb_phy_generic.h>
+
+#include "soc.h"
+#include "omap_device.h"
+#include "mux.h"
+#include "usb.h"
+
+#ifdef CONFIG_MFD_OMAP_USB_HOST
+
+#define OMAP_USBHS_DEVICE "usbhs_omap"
+#define OMAP_USBTLL_DEVICE "usbhs_tll"
+#define USBHS_UHH_HWMODNAME "usb_host_hs"
+#define USBHS_TLL_HWMODNAME "usb_tll_hs"
+
+/* MUX settings for EHCI pins */
+/*
+ * setup_ehci_io_mux - initialize IO pad mux for USBHOST
+ */
+static void __init 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 __init 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;
+ }
+}
+
+void __init usbhs_init(struct usbhs_omap_platform_data *pdata)
+{
+ struct omap_hwmod *uhh_hwm, *tll_hwm;
+ struct platform_device *pdev;
+ int bus_id = -1;
+
+ if (cpu_is_omap34xx()) {
+ setup_ehci_io_mux(pdata->port_mode);
+ setup_ohci_io_mux(pdata->port_mode);
+
+ if (omap_rev() <= OMAP3430_REV_ES2_1)
+ pdata->single_ulpi_bypass = true;
+
+ }
+
+ uhh_hwm = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
+ if (!uhh_hwm) {
+ pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME);
+ return;
+ }
+
+ tll_hwm = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
+ if (!tll_hwm) {
+ pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
+ return;
+ }
+
+ pdev = omap_device_build(OMAP_USBTLL_DEVICE, bus_id, tll_hwm,
+ pdata, sizeof(*pdata));
+ if (IS_ERR(pdev)) {
+ pr_err("Could not build hwmod device %s\n",
+ USBHS_TLL_HWMODNAME);
+ return;
+ }
+
+ pdev = omap_device_build(OMAP_USBHS_DEVICE, bus_id, uhh_hwm,
+ pdata, sizeof(*pdata));
+ if (IS_ERR(pdev)) {
+ pr_err("Could not build hwmod devices %s\n",
+ USBHS_UHH_HWMODNAME);
+ return;
+ }
+}
+
+#else
+
+void __init usbhs_init(struct usbhs_omap_platform_data *pdata)
+{
+}
+
+#endif
+
+/* Template for PHY regulators */
+static struct fixed_voltage_config hsusb_reg_config = {
+ /* .supply_name filled later */
+ .microvolts = 3300000,
+ .gpio = -1, /* updated later */
+ .startup_delay = 70000, /* 70msec */
+ .enable_high = 1, /* updated later */
+ .enabled_at_boot = 0, /* keep in RESET */
+ /* .init_data filled later */
+};
+
+static const char *nop_name = "usb_phy_generic"; /* NOP PHY driver */
+static const char *reg_name = "reg-fixed-voltage"; /* Regulator driver */
+
+/**
+ * usbhs_add_regulator - Add a gpio based fixed voltage regulator device
+ * @name: name for the regulator
+ * @dev_id: device id of the device this regulator supplies power to
+ * @dev_supply: supply name that the device expects
+ * @gpio: GPIO number
+ * @polarity: 1 - Active high, 0 - Active low
+ */
+static int usbhs_add_regulator(char *name, char *dev_id, char *dev_supply,
+ int gpio, int polarity)
+{
+ struct regulator_consumer_supply *supplies;
+ struct regulator_init_data *reg_data;
+ struct fixed_voltage_config *config;
+ struct platform_device *pdev;
+ struct platform_device_info pdevinfo;
+ int ret = -ENOMEM;
+
+ supplies = kzalloc(sizeof(*supplies), GFP_KERNEL);
+ if (!supplies)
+ return -ENOMEM;
+
+ supplies->supply = dev_supply;
+ supplies->dev_name = dev_id;
+
+ reg_data = kzalloc(sizeof(*reg_data), GFP_KERNEL);
+ if (!reg_data)
+ goto err_data;
+
+ reg_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
+ reg_data->consumer_supplies = supplies;
+ reg_data->num_consumer_supplies = 1;
+
+ config = kmemdup(&hsusb_reg_config, sizeof(hsusb_reg_config),
+ GFP_KERNEL);
+ if (!config)
+ goto err_config;
+
+ config->supply_name = kstrdup(name, GFP_KERNEL);
+ if (!config->supply_name)
+ goto err_supplyname;
+
+ config->gpio = gpio;
+ config->enable_high = polarity;
+ config->init_data = reg_data;
+
+ /* create a regulator device */
+ memset(&pdevinfo, 0, sizeof(pdevinfo));
+ pdevinfo.name = reg_name;
+ pdevinfo.id = PLATFORM_DEVID_AUTO;
+ pdevinfo.data = config;
+ pdevinfo.size_data = sizeof(*config);
+
+ pdev = platform_device_register_full(&pdevinfo);
+ if (IS_ERR(pdev)) {
+ ret = PTR_ERR(pdev);
+ pr_err("%s: Failed registering regulator %s for %s : %d\n",
+ __func__, name, dev_id, ret);
+ goto err_register;
+ }
+
+ return 0;
+
+err_register:
+ kfree(config->supply_name);
+err_supplyname:
+ kfree(config);
+err_config:
+ kfree(reg_data);
+err_data:
+ kfree(supplies);
+ return ret;
+}
+
+#define MAX_STR 20
+
+int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys)
+{
+ char rail_name[MAX_STR];
+ int i;
+ struct platform_device *pdev;
+ char *phy_id;
+ struct platform_device_info pdevinfo;
+ struct usb_phy_generic_platform_data nop_pdata;
+
+ for (i = 0; i < num_phys; i++) {
+
+ if (!phy->port) {
+ pr_err("%s: Invalid port 0. Must start from 1\n",
+ __func__);
+ continue;
+ }
+
+ /* do we need a NOP PHY device ? */
+ if (!gpio_is_valid(phy->reset_gpio) &&
+ !gpio_is_valid(phy->vcc_gpio))
+ continue;
+
+ phy_id = kmalloc(MAX_STR, GFP_KERNEL);
+ if (!phy_id) {
+ pr_err("%s: kmalloc() failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* set platform data */
+ memset(&nop_pdata, 0, sizeof(nop_pdata));
+ if (gpio_is_valid(phy->vcc_gpio))
+ nop_pdata.needs_vcc = true;
+ nop_pdata.gpio_reset = phy->reset_gpio;
+ nop_pdata.type = USB_PHY_TYPE_USB2;
+
+ /* create a NOP PHY device */
+ memset(&pdevinfo, 0, sizeof(pdevinfo));
+ pdevinfo.name = nop_name;
+ pdevinfo.id = phy->port;
+ pdevinfo.data = &nop_pdata;
+ pdevinfo.size_data =
+ sizeof(struct usb_phy_generic_platform_data);
+ scnprintf(phy_id, MAX_STR, "usb_phy_generic.%d",
+ phy->port);
+ pdev = platform_device_register_full(&pdevinfo);
+ if (IS_ERR(pdev)) {
+ pr_err("%s: Failed to register device %s : %ld\n",
+ __func__, phy_id, PTR_ERR(pdev));
+ kfree(phy_id);
+ continue;
+ }
+
+ usb_bind_phy("ehci-omap.0", phy->port - 1, phy_id);
+
+ /* Do we need VCC regulator ? */
+ if (gpio_is_valid(phy->vcc_gpio)) {
+ scnprintf(rail_name, MAX_STR, "hsusb%d_vcc", phy->port);
+ usbhs_add_regulator(rail_name, phy_id, "vcc",
+ phy->vcc_gpio, phy->vcc_polarity);
+ }
+
+ phy++;
+ }
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
new file mode 100644
index 000000000..e4562b2b9
--- /dev/null
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -0,0 +1,106 @@
+/*
+ * 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 "omap_device.h"
+#include "soc.h"
+#include "mux.h"
+#include "usb.h"
+
+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 = {
+ .mode = MUSB_OTG,
+
+ /* .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_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 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;
+
+ oh_name = "usb_otg_hs";
+ name = "musb-omap2430";
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (WARN(!oh, "%s: could not find omap_hwmod for %s\n",
+ __func__, oh_name))
+ return;
+
+ pdev = omap_device_build(name, bus_id, oh, &musb_plat,
+ sizeof(musb_plat));
+ if (IS_ERR(pdev)) {
+ pr_err("Could not build omap_device for %s %s\n",
+ name, oh_name);
+ return;
+ }
+
+ dev = &pdev->dev;
+ get_device(dev);
+ dev->dma_mask = &musb_dmamask;
+ dev->coherent_dma_mask = musb_dmamask;
+ put_device(dev);
+}
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
new file mode 100644
index 000000000..e554d9e66
--- /dev/null
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -0,0 +1,255 @@
+/*
+ * 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/err.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/export.h>
+#include <linux/platform_data/usb-omap.h>
+
+#include <linux/usb/musb.h>
+
+#include "gpmc.h"
+
+#include "mux.h"
+
+static u8 async_cs, sync_cs;
+static unsigned refclk_psec;
+
+static struct gpmc_settings tusb_async = {
+ .wait_on_read = true,
+ .wait_on_write = true,
+ .device_width = GPMC_DEVWIDTH_16BIT,
+ .mux_add_data = GPMC_MUX_AD,
+};
+
+static struct gpmc_settings tusb_sync = {
+ .burst_read = true,
+ .burst_write = true,
+ .sync_read = true,
+ .sync_write = true,
+ .wait_on_read = true,
+ .wait_on_write = true,
+ .burst_len = GPMC_BURST_16,
+ .device_width = GPMC_DEVWIDTH_16BIT,
+ .mux_add_data = GPMC_MUX_AD,
+};
+
+/* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
+
+static int tusb_set_async_mode(unsigned sysclk_ps)
+{
+ struct gpmc_device_timings dev_t;
+ struct gpmc_timings t;
+ unsigned t_acsnh_advnh = sysclk_ps + 3000;
+
+ memset(&dev_t, 0, sizeof(dev_t));
+
+ dev_t.t_ceasu = 8 * 1000;
+ dev_t.t_avdasu = t_acsnh_advnh - 7000;
+ dev_t.t_ce_avd = 1000;
+ dev_t.t_avdp_r = t_acsnh_advnh;
+ dev_t.t_oeasu = t_acsnh_advnh + 1000;
+ dev_t.t_oe = 300;
+ dev_t.t_cez_r = 7000;
+ dev_t.t_cez_w = dev_t.t_cez_r;
+ dev_t.t_avdp_w = t_acsnh_advnh;
+ dev_t.t_weasu = t_acsnh_advnh + 1000;
+ dev_t.t_wpl = 300;
+ dev_t.cyc_aavdh_we = 1;
+
+ gpmc_calc_timings(&t, &tusb_async, &dev_t);
+
+ return gpmc_cs_set_timings(async_cs, &t, &tusb_async);
+}
+
+static int tusb_set_sync_mode(unsigned sysclk_ps)
+{
+ struct gpmc_device_timings dev_t;
+ struct gpmc_timings t;
+ unsigned t_scsnh_advnh = sysclk_ps + 3000;
+
+ memset(&dev_t, 0, sizeof(dev_t));
+
+ dev_t.clk = 11100;
+ dev_t.t_bacc = 1000;
+ dev_t.t_ces = 1000;
+ dev_t.t_ceasu = 8 * 1000;
+ dev_t.t_avdasu = t_scsnh_advnh - 7000;
+ dev_t.t_ce_avd = 1000;
+ dev_t.t_avdp_r = t_scsnh_advnh;
+ dev_t.cyc_aavdh_oe = 3;
+ dev_t.cyc_oe = 5;
+ dev_t.t_ce_rdyz = 7000;
+ dev_t.t_avdp_w = t_scsnh_advnh;
+ dev_t.cyc_aavdh_we = 3;
+ dev_t.cyc_wpl = 6;
+
+ gpmc_calc_timings(&t, &tusb_sync, &dev_t);
+
+ return gpmc_cs_set_timings(sync_cs, &t, &tusb_sync);
+}
+
+/* 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 sysclk_ps;
+ int status;
+
+ if (!refclk_psec)
+ return -ENODEV;
+
+ sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
+
+ status = tusb_set_async_mode(sysclk_ps);
+ if (status < 0) {
+ printk(error, "async", status);
+ goto done;
+ }
+ status = tusb_set_sync_mode(sysclk_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;
+ tusb_async.wait_pin = waitpin;
+ async_cs = async;
+
+ status = gpmc_cs_program_settings(async_cs, &tusb_async);
+ if (status < 0)
+ return status;
+
+ /* 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;
+ tusb_sync.wait_pin = waitpin;
+ sync_cs = sync;
+
+ status = gpmc_cs_program_settings(sync_cs, &tusb_sync);
+ if (status < 0)
+ return status;
+
+ /* IRQ */
+ status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq");
+ if (status < 0) {
+ printk(error, 3, status);
+ return status;
+ }
+ tusb_resources[2].start = gpio_to_irq(irq);
+
+ /* 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/usb.h b/arch/arm/mach-omap2/usb.h
new file mode 100644
index 000000000..3395365ef
--- /dev/null
+++ b/arch/arm/mach-omap2/usb.h
@@ -0,0 +1,70 @@
+#include <linux/platform_data/usb-omap.h>
+
+/* 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)
+
+/* TI81XX specific definitions */
+#define USBCTRL0 0x620
+#define USBSTAT0 0x624
+
+/* TI816X PHY controls bits */
+#define TI816X_USBPHY0_NORMAL_MODE (1 << 0)
+#define TI816X_USBPHY_REFCLK_OSC (1 << 8)
+
+/* TI814X PHY controls bits */
+#define USBPHY_CM_PWRDN (1 << 0)
+#define USBPHY_OTG_PWRDN (1 << 1)
+#define USBPHY_CHGDET_DIS (1 << 2)
+#define USBPHY_CHGDET_RSTRT (1 << 3)
+#define USBPHY_SRCONDM (1 << 4)
+#define USBPHY_SINKONDP (1 << 5)
+#define USBPHY_CHGISINK_EN (1 << 6)
+#define USBPHY_CHGVSRC_EN (1 << 7)
+#define USBPHY_DMPULLUP (1 << 8)
+#define USBPHY_DPPULLUP (1 << 9)
+#define USBPHY_CDET_EXTCTL (1 << 10)
+#define USBPHY_GPIO_MODE (1 << 12)
+#define USBPHY_DPOPBUFCTL (1 << 13)
+#define USBPHY_DMOPBUFCTL (1 << 14)
+#define USBPHY_DPINPUT (1 << 15)
+#define USBPHY_DMINPUT (1 << 16)
+#define USBPHY_DPGPIO_PD (1 << 17)
+#define USBPHY_DMGPIO_PD (1 << 18)
+#define USBPHY_OTGVDET_EN (1 << 19)
+#define USBPHY_OTGSESSEND_EN (1 << 20)
+#define USBPHY_DATA_POLARITY (1 << 23)
+
+struct usbhs_phy_data {
+ int port; /* 1 indexed port number */
+ int reset_gpio;
+ int vcc_gpio;
+ bool vcc_polarity; /* 1 active high, 0 active low */
+};
+
+extern void usb_musb_init(struct omap_musb_board_data *board_data);
+extern void usbhs_init(struct usbhs_omap_platform_data *pdata);
+extern int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys);
+
+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);
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
new file mode 100644
index 000000000..076fd20d7
--- /dev/null
+++ b/arch/arm/mach-omap2/vc.c
@@ -0,0 +1,847 @@
+/*
+ * OMAP Voltage Controller (VC) interface
+ *
+ * Copyright (C) 2011 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/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/bug.h>
+#include <linux/io.h>
+
+#include <asm/div64.h>
+
+#include "iomap.h"
+#include "soc.h"
+#include "voltage.h"
+#include "vc.h"
+#include "prm-regbits-34xx.h"
+#include "prm-regbits-44xx.h"
+#include "prm44xx.h"
+#include "pm.h"
+#include "scrm44xx.h"
+#include "control.h"
+
+/**
+ * struct omap_vc_channel_cfg - describe the cfg_channel bitfield
+ * @sa: bit for slave address
+ * @rav: bit for voltage configuration register
+ * @rac: bit for command configuration register
+ * @racen: enable bit for RAC
+ * @cmd: bit for command value set selection
+ *
+ * Channel configuration bits, common for OMAP3+
+ * OMAP3 register: PRM_VC_CH_CONF
+ * OMAP4 register: PRM_VC_CFG_CHANNEL
+ * OMAP5 register: PRM_VC_SMPS_<voltdm>_CONFIG
+ */
+struct omap_vc_channel_cfg {
+ u8 sa;
+ u8 rav;
+ u8 rac;
+ u8 racen;
+ u8 cmd;
+};
+
+static struct omap_vc_channel_cfg vc_default_channel_cfg = {
+ .sa = BIT(0),
+ .rav = BIT(1),
+ .rac = BIT(2),
+ .racen = BIT(3),
+ .cmd = BIT(4),
+};
+
+/*
+ * On OMAP3+, all VC channels have the above default bitfield
+ * configuration, except the OMAP4 MPU channel. This appears
+ * to be a freak accident as every other VC channel has the
+ * default configuration, thus creating a mutant channel config.
+ */
+static struct omap_vc_channel_cfg vc_mutant_channel_cfg = {
+ .sa = BIT(0),
+ .rav = BIT(2),
+ .rac = BIT(3),
+ .racen = BIT(4),
+ .cmd = BIT(1),
+};
+
+static struct omap_vc_channel_cfg *vc_cfg_bits;
+
+/* Default I2C trace length on pcb, 6.3cm. Used for capacitance calculations. */
+static u32 sr_i2c_pcb_length = 63;
+#define CFG_CHANNEL_MASK 0x1f
+
+/**
+ * omap_vc_config_channel - configure VC channel to PMIC mappings
+ * @voltdm: pointer to voltagdomain defining the desired VC channel
+ *
+ * Configures the VC channel to PMIC mappings for the following
+ * PMIC settings
+ * - i2c slave address (SA)
+ * - voltage configuration address (RAV)
+ * - command configuration address (RAC) and enable bit (RACEN)
+ * - command values for ON, ONLP, RET and OFF (CMD)
+ *
+ * This function currently only allows flexible configuration of the
+ * non-default channel. Starting with OMAP4, there are more than 2
+ * channels, with one defined as the default (on OMAP4, it's MPU.)
+ * Only the non-default channel can be configured.
+ */
+static int omap_vc_config_channel(struct voltagedomain *voltdm)
+{
+ struct omap_vc_channel *vc = voltdm->vc;
+
+ /*
+ * For default channel, the only configurable bit is RACEN.
+ * All others must stay at zero (see function comment above.)
+ */
+ if (vc->flags & OMAP_VC_CHANNEL_DEFAULT)
+ vc->cfg_channel &= vc_cfg_bits->racen;
+
+ voltdm->rmw(CFG_CHANNEL_MASK << vc->cfg_channel_sa_shift,
+ vc->cfg_channel << vc->cfg_channel_sa_shift,
+ vc->cfg_channel_reg);
+
+ return 0;
+}
+
+/* Voltage scale and accessory APIs */
+int omap_vc_pre_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt,
+ u8 *target_vsel, u8 *current_vsel)
+{
+ struct omap_vc_channel *vc = voltdm->vc;
+ u32 vc_cmdval;
+
+ /* Check if sufficient pmic info is available for this vdd */
+ if (!voltdm->pmic) {
+ pr_err("%s: Insufficient pmic info to scale the vdd_%s\n",
+ __func__, voltdm->name);
+ return -EINVAL;
+ }
+
+ if (!voltdm->pmic->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__, voltdm->name);
+ return -ENODATA;
+ }
+
+ if (!voltdm->read || !voltdm->write) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return -EINVAL;
+ }
+
+ *target_vsel = voltdm->pmic->uv_to_vsel(target_volt);
+ *current_vsel = voltdm->pmic->uv_to_vsel(voltdm->nominal_volt);
+
+ /* Setting the ON voltage to the new target voltage */
+ vc_cmdval = voltdm->read(vc->cmdval_reg);
+ vc_cmdval &= ~vc->common->cmd_on_mask;
+ vc_cmdval |= (*target_vsel << vc->common->cmd_on_shift);
+ voltdm->write(vc_cmdval, vc->cmdval_reg);
+
+ voltdm->vc_param->on = target_volt;
+
+ omap_vp_update_errorgain(voltdm, target_volt);
+
+ return 0;
+}
+
+void omap_vc_post_scale(struct voltagedomain *voltdm,
+ 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 * voltdm->pmic->step_size) /
+ voltdm->pmic->slew_rate) + 2;
+ udelay(smps_delay);
+}
+
+/* vc_bypass_scale - VC bypass method of voltage scaling */
+int omap_vc_bypass_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt)
+{
+ struct omap_vc_channel *vc = voltdm->vc;
+ 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 = omap_vc_pre_scale(voltdm, target_volt, &target_vsel, &current_vsel);
+ if (ret)
+ return ret;
+
+ vc_valid = vc->common->valid;
+ vc_bypass_val_reg = vc->common->bypass_val_reg;
+ vc_bypass_value = (target_vsel << vc->common->data_shift) |
+ (vc->volt_reg_addr << vc->common->regaddr_shift) |
+ (vc->i2c_slave_addr << vc->common->slaveaddr_shift);
+
+ voltdm->write(vc_bypass_value, vc_bypass_val_reg);
+ voltdm->write(vc_bypass_value | vc_valid, vc_bypass_val_reg);
+
+ vc_bypass_value = voltdm->read(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_warn("%s: Retry count exceeded\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ if (loop_cnt > 50) {
+ retries_cnt++;
+ loop_cnt = 0;
+ udelay(10);
+ }
+ vc_bypass_value = voltdm->read(vc_bypass_val_reg);
+ }
+
+ omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel);
+ return 0;
+}
+
+/* Convert microsecond value to number of 32kHz clock cycles */
+static inline u32 omap_usec_to_32k(u32 usec)
+{
+ return DIV_ROUND_UP_ULL(32768ULL * (u64)usec, 1000000ULL);
+}
+
+struct omap3_vc_timings {
+ u32 voltsetup1;
+ u32 voltsetup2;
+};
+
+struct omap3_vc {
+ struct voltagedomain *vd;
+ u32 voltctrl;
+ u32 voltsetup1;
+ u32 voltsetup2;
+ struct omap3_vc_timings timings[2];
+};
+static struct omap3_vc vc;
+
+void omap3_vc_set_pmic_signaling(int core_next_state)
+{
+ struct voltagedomain *vd = vc.vd;
+ struct omap3_vc_timings *c = vc.timings;
+ u32 voltctrl, voltsetup1, voltsetup2;
+
+ voltctrl = vc.voltctrl;
+ voltsetup1 = vc.voltsetup1;
+ voltsetup2 = vc.voltsetup2;
+
+ switch (core_next_state) {
+ case PWRDM_POWER_OFF:
+ voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_RET |
+ OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP);
+ voltctrl |= OMAP3430_PRM_VOLTCTRL_AUTO_OFF;
+ if (voltctrl & OMAP3430_PRM_VOLTCTRL_SEL_OFF)
+ voltsetup2 = c->voltsetup2;
+ else
+ voltsetup1 = c->voltsetup1;
+ break;
+ case PWRDM_POWER_RET:
+ default:
+ c++;
+ voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_OFF |
+ OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP);
+ voltctrl |= OMAP3430_PRM_VOLTCTRL_AUTO_RET;
+ voltsetup1 = c->voltsetup1;
+ break;
+ }
+
+ if (voltctrl != vc.voltctrl) {
+ vd->write(voltctrl, OMAP3_PRM_VOLTCTRL_OFFSET);
+ vc.voltctrl = voltctrl;
+ }
+ if (voltsetup1 != vc.voltsetup1) {
+ vd->write(c->voltsetup1,
+ OMAP3_PRM_VOLTSETUP1_OFFSET);
+ vc.voltsetup1 = voltsetup1;
+ }
+ if (voltsetup2 != vc.voltsetup2) {
+ vd->write(c->voltsetup2,
+ OMAP3_PRM_VOLTSETUP2_OFFSET);
+ vc.voltsetup2 = voltsetup2;
+ }
+}
+
+#define PRM_POLCTRL_TWL_MASK (OMAP3430_PRM_POLCTRL_CLKREQ_POL | \
+ OMAP3430_PRM_POLCTRL_CLKREQ_POL)
+#define PRM_POLCTRL_TWL_VAL OMAP3430_PRM_POLCTRL_CLKREQ_POL
+
+/*
+ * Configure signal polarity for sys_clkreq and sys_off_mode pins
+ * as the default values are wrong and can cause the system to hang
+ * if any twl4030 scripts are loaded.
+ */
+static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm)
+{
+ u32 val;
+
+ if (vc.vd)
+ return;
+
+ vc.vd = voltdm;
+
+ val = voltdm->read(OMAP3_PRM_POLCTRL_OFFSET);
+ if (!(val & OMAP3430_PRM_POLCTRL_CLKREQ_POL) ||
+ (val & OMAP3430_PRM_POLCTRL_CLKREQ_POL)) {
+ val |= OMAP3430_PRM_POLCTRL_CLKREQ_POL;
+ val &= ~OMAP3430_PRM_POLCTRL_OFFMODE_POL;
+ pr_debug("PM: fixing sys_clkreq and sys_off_mode polarity to 0x%x\n",
+ val);
+ voltdm->write(val, OMAP3_PRM_POLCTRL_OFFSET);
+ }
+
+ /*
+ * By default let's use I2C4 signaling for retention idle
+ * and sys_off_mode pin signaling for off idle. This way we
+ * have sys_clk_req pin go down for retention and both
+ * sys_clk_req and sys_off_mode pins will go down for off
+ * idle. And we can also scale voltages to zero for off-idle.
+ * Note that no actual voltage scaling during off-idle will
+ * happen unless the board specific twl4030 PMIC scripts are
+ * loaded. See also omap_vc_i2c_init for comments regarding
+ * erratum i531.
+ */
+ val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET);
+ if (!(val & OMAP3430_PRM_VOLTCTRL_SEL_OFF)) {
+ val |= OMAP3430_PRM_VOLTCTRL_SEL_OFF;
+ pr_debug("PM: setting voltctrl sys_off_mode signaling to 0x%x\n",
+ val);
+ voltdm->write(val, OMAP3_PRM_VOLTCTRL_OFFSET);
+ }
+ vc.voltctrl = val;
+
+ omap3_vc_set_pmic_signaling(PWRDM_POWER_ON);
+}
+
+static void omap3_init_voltsetup1(struct voltagedomain *voltdm,
+ struct omap3_vc_timings *c, u32 idle)
+{
+ unsigned long val;
+
+ val = (voltdm->vc_param->on - idle) / voltdm->pmic->slew_rate;
+ val *= voltdm->sys_clk.rate / 8 / 1000000 + 1;
+ val <<= __ffs(voltdm->vfsm->voltsetup_mask);
+ c->voltsetup1 &= ~voltdm->vfsm->voltsetup_mask;
+ c->voltsetup1 |= val;
+}
+
+/**
+ * omap3_set_i2c_timings - sets i2c sleep timings for a channel
+ * @voltdm: channel to configure
+ * @off_mode: select whether retention or off mode values used
+ *
+ * Calculates and sets up voltage controller to use I2C based
+ * voltage scaling for sleep modes. This can be used for either off mode
+ * or retention. Off mode has additionally an option to use sys_off_mode
+ * pad, which uses a global signal to program the whole power IC to
+ * off-mode.
+ *
+ * Note that pmic is not controlling the voltage scaling during
+ * retention signaled over I2C4, so we can keep voltsetup2 as 0.
+ * And the oscillator is not shut off over I2C4, so no need to
+ * set clksetup.
+ */
+static void omap3_set_i2c_timings(struct voltagedomain *voltdm)
+{
+ struct omap3_vc_timings *c = vc.timings;
+
+ /* Configure PRWDM_POWER_OFF over I2C4 */
+ omap3_init_voltsetup1(voltdm, c, voltdm->vc_param->off);
+ c++;
+ /* Configure PRWDM_POWER_RET over I2C4 */
+ omap3_init_voltsetup1(voltdm, c, voltdm->vc_param->ret);
+}
+
+/**
+ * omap3_set_off_timings - sets off-mode timings for a channel
+ * @voltdm: channel to configure
+ *
+ * Calculates and sets up off-mode timings for a channel. Off-mode
+ * can use either I2C based voltage scaling, or alternatively
+ * sys_off_mode pad can be used to send a global command to power IC.n,
+ * sys_off_mode has the additional benefit that voltages can be
+ * scaled to zero volt level with TWL4030 / TWL5030, I2C can only
+ * scale to 600mV.
+ *
+ * Note that omap is not controlling the voltage scaling during
+ * off idle signaled by sys_off_mode, so we can keep voltsetup1
+ * as 0.
+ */
+static void omap3_set_off_timings(struct voltagedomain *voltdm)
+{
+ struct omap3_vc_timings *c = vc.timings;
+ u32 tstart, tshut, clksetup, voltoffset;
+
+ if (c->voltsetup2)
+ return;
+
+ omap_pm_get_oscillator(&tstart, &tshut);
+ if (tstart == ULONG_MAX) {
+ pr_debug("PM: oscillator start-up time not initialized, using 10ms\n");
+ clksetup = omap_usec_to_32k(10000);
+ } else {
+ clksetup = omap_usec_to_32k(tstart);
+ }
+
+ /*
+ * For twl4030 errata 27, we need to allow minimum ~488.32 us wait to
+ * switch from HFCLKIN to internal oscillator. That means timings
+ * have voltoffset fixed to 0xa in rounded up 32 KiHz cycles. And
+ * that means we can calculate the value based on the oscillator
+ * start-up time since voltoffset2 = clksetup - voltoffset.
+ */
+ voltoffset = omap_usec_to_32k(488);
+ c->voltsetup2 = clksetup - voltoffset;
+ voltdm->write(clksetup, OMAP3_PRM_CLKSETUP_OFFSET);
+ voltdm->write(voltoffset, OMAP3_PRM_VOLTOFFSET_OFFSET);
+}
+
+static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
+{
+ omap3_vc_init_pmic_signaling(voltdm);
+ omap3_set_off_timings(voltdm);
+ omap3_set_i2c_timings(voltdm);
+}
+
+/**
+ * omap4_calc_volt_ramp - calculates voltage ramping delays on omap4
+ * @voltdm: channel to calculate values for
+ * @voltage_diff: voltage difference in microvolts
+ *
+ * Calculates voltage ramp prescaler + counter values for a voltage
+ * difference on omap4. Returns a field value suitable for writing to
+ * VOLTSETUP register for a channel in following format:
+ * bits[8:9] prescaler ... bits[0:5] counter. See OMAP4 TRM for reference.
+ */
+static u32 omap4_calc_volt_ramp(struct voltagedomain *voltdm, u32 voltage_diff)
+{
+ u32 prescaler;
+ u32 cycles;
+ u32 time;
+
+ time = voltage_diff / voltdm->pmic->slew_rate;
+
+ cycles = voltdm->sys_clk.rate / 1000 * time / 1000;
+
+ cycles /= 64;
+ prescaler = 0;
+
+ /* shift to next prescaler until no overflow */
+
+ /* scale for div 256 = 64 * 4 */
+ if (cycles > 63) {
+ cycles /= 4;
+ prescaler++;
+ }
+
+ /* scale for div 512 = 256 * 2 */
+ if (cycles > 63) {
+ cycles /= 2;
+ prescaler++;
+ }
+
+ /* scale for div 2048 = 512 * 4 */
+ if (cycles > 63) {
+ cycles /= 4;
+ prescaler++;
+ }
+
+ /* check for overflow => invalid ramp time */
+ if (cycles > 63) {
+ pr_warn("%s: invalid setuptime for vdd_%s\n", __func__,
+ voltdm->name);
+ return 0;
+ }
+
+ cycles++;
+
+ return (prescaler << OMAP4430_RAMP_UP_PRESCAL_SHIFT) |
+ (cycles << OMAP4430_RAMP_UP_COUNT_SHIFT);
+}
+
+/**
+ * omap4_usec_to_val_scrm - convert microsecond value to SCRM module bitfield
+ * @usec: microseconds
+ * @shift: number of bits to shift left
+ * @mask: bitfield mask
+ *
+ * Converts microsecond value to OMAP4 SCRM bitfield. Bitfield is
+ * shifted to requested position, and checked agains the mask value.
+ * If larger, forced to the max value of the field (i.e. the mask itself.)
+ * Returns the SCRM bitfield value.
+ */
+static u32 omap4_usec_to_val_scrm(u32 usec, int shift, u32 mask)
+{
+ u32 val;
+
+ val = omap_usec_to_32k(usec) << shift;
+
+ /* Check for overflow, if yes, force to max value */
+ if (val > mask)
+ val = mask;
+
+ return val;
+}
+
+/**
+ * omap4_set_timings - set voltage ramp timings for a channel
+ * @voltdm: channel to configure
+ * @off_mode: whether off-mode values are used
+ *
+ * Calculates and sets the voltage ramp up / down values for a channel.
+ */
+static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode)
+{
+ u32 val;
+ u32 ramp;
+ int offset;
+ u32 tstart, tshut;
+
+ if (off_mode) {
+ ramp = omap4_calc_volt_ramp(voltdm,
+ voltdm->vc_param->on - voltdm->vc_param->off);
+ offset = voltdm->vfsm->voltsetup_off_reg;
+ } else {
+ ramp = omap4_calc_volt_ramp(voltdm,
+ voltdm->vc_param->on - voltdm->vc_param->ret);
+ offset = voltdm->vfsm->voltsetup_reg;
+ }
+
+ if (!ramp)
+ return;
+
+ val = voltdm->read(offset);
+
+ val |= ramp << OMAP4430_RAMP_DOWN_COUNT_SHIFT;
+
+ val |= ramp << OMAP4430_RAMP_UP_COUNT_SHIFT;
+
+ voltdm->write(val, offset);
+
+ omap_pm_get_oscillator(&tstart, &tshut);
+
+ val = omap4_usec_to_val_scrm(tstart, OMAP4_SETUPTIME_SHIFT,
+ OMAP4_SETUPTIME_MASK);
+ val |= omap4_usec_to_val_scrm(tshut, OMAP4_DOWNTIME_SHIFT,
+ OMAP4_DOWNTIME_MASK);
+
+ writel_relaxed(val, OMAP4_SCRM_CLKSETUPTIME);
+}
+
+/* OMAP4 specific voltage init functions */
+static void __init omap4_vc_init_channel(struct voltagedomain *voltdm)
+{
+ omap4_set_timings(voltdm, true);
+ omap4_set_timings(voltdm, false);
+}
+
+struct i2c_init_data {
+ u8 loadbits;
+ u8 load;
+ u8 hsscll_38_4;
+ u8 hsscll_26;
+ u8 hsscll_19_2;
+ u8 hsscll_16_8;
+ u8 hsscll_12;
+};
+
+static const __initdata struct i2c_init_data omap4_i2c_timing_data[] = {
+ {
+ .load = 50,
+ .loadbits = 0x3,
+ .hsscll_38_4 = 13,
+ .hsscll_26 = 11,
+ .hsscll_19_2 = 9,
+ .hsscll_16_8 = 9,
+ .hsscll_12 = 8,
+ },
+ {
+ .load = 25,
+ .loadbits = 0x2,
+ .hsscll_38_4 = 13,
+ .hsscll_26 = 11,
+ .hsscll_19_2 = 9,
+ .hsscll_16_8 = 9,
+ .hsscll_12 = 8,
+ },
+ {
+ .load = 12,
+ .loadbits = 0x1,
+ .hsscll_38_4 = 11,
+ .hsscll_26 = 10,
+ .hsscll_19_2 = 9,
+ .hsscll_16_8 = 9,
+ .hsscll_12 = 8,
+ },
+ {
+ .load = 0,
+ .loadbits = 0x0,
+ .hsscll_38_4 = 12,
+ .hsscll_26 = 10,
+ .hsscll_19_2 = 9,
+ .hsscll_16_8 = 8,
+ .hsscll_12 = 8,
+ },
+};
+
+/**
+ * omap4_vc_i2c_timing_init - sets up board I2C timing parameters
+ * @voltdm: voltagedomain pointer to get data from
+ *
+ * Use PMIC + board supplied settings for calculating the total I2C
+ * channel capacitance and set the timing parameters based on this.
+ * Pre-calculated values are provided in data tables, as it is not
+ * too straightforward to calculate these runtime.
+ */
+static void __init omap4_vc_i2c_timing_init(struct voltagedomain *voltdm)
+{
+ u32 capacitance;
+ u32 val;
+ u16 hsscll;
+ const struct i2c_init_data *i2c_data;
+
+ if (!voltdm->pmic->i2c_high_speed) {
+ pr_warn("%s: only high speed supported!\n", __func__);
+ return;
+ }
+
+ /* PCB trace capacitance, 0.125pF / mm => mm / 8 */
+ capacitance = DIV_ROUND_UP(sr_i2c_pcb_length, 8);
+
+ /* OMAP pad capacitance */
+ capacitance += 4;
+
+ /* PMIC pad capacitance */
+ capacitance += voltdm->pmic->i2c_pad_load;
+
+ /* Search for capacitance match in the table */
+ i2c_data = omap4_i2c_timing_data;
+
+ while (i2c_data->load > capacitance)
+ i2c_data++;
+
+ /* Select proper values based on sysclk frequency */
+ switch (voltdm->sys_clk.rate) {
+ case 38400000:
+ hsscll = i2c_data->hsscll_38_4;
+ break;
+ case 26000000:
+ hsscll = i2c_data->hsscll_26;
+ break;
+ case 19200000:
+ hsscll = i2c_data->hsscll_19_2;
+ break;
+ case 16800000:
+ hsscll = i2c_data->hsscll_16_8;
+ break;
+ case 12000000:
+ hsscll = i2c_data->hsscll_12;
+ break;
+ default:
+ pr_warn("%s: unsupported sysclk rate: %d!\n", __func__,
+ voltdm->sys_clk.rate);
+ return;
+ }
+
+ /* Loadbits define pull setup for the I2C channels */
+ val = i2c_data->loadbits << 25 | i2c_data->loadbits << 29;
+
+ /* Write to SYSCTRL_PADCONF_WKUP_CTRL_I2C_2 to setup I2C pull */
+ writel_relaxed(val, OMAP2_L4_IO_ADDRESS(OMAP4_CTRL_MODULE_PAD_WKUP +
+ OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_I2C_2));
+
+ /* HSSCLH can always be zero */
+ val = hsscll << OMAP4430_HSSCLL_SHIFT;
+ val |= (0x28 << OMAP4430_SCLL_SHIFT | 0x2c << OMAP4430_SCLH_SHIFT);
+
+ /* Write setup times to I2C config register */
+ voltdm->write(val, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
+}
+
+
+
+/**
+ * omap_vc_i2c_init - initialize I2C interface to PMIC
+ * @voltdm: voltage domain containing VC data
+ *
+ * Use PMIC supplied settings for I2C high-speed mode and
+ * master code (if set) and program the VC I2C configuration
+ * register.
+ *
+ * The VC I2C configuration is common to all VC channels,
+ * so this function only configures I2C for the first VC
+ * channel registers. All other VC channels will use the
+ * same configuration.
+ */
+static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)
+{
+ struct omap_vc_channel *vc = voltdm->vc;
+ static bool initialized;
+ static bool i2c_high_speed;
+ u8 mcode;
+
+ if (initialized) {
+ if (voltdm->pmic->i2c_high_speed != i2c_high_speed)
+ pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).\n",
+ __func__, voltdm->name, i2c_high_speed);
+ return;
+ }
+
+ /*
+ * Note that for omap3 OMAP3430_SREN_MASK clears SREN to work around
+ * erratum i531 "Extra Power Consumed When Repeated Start Operation
+ * Mode Is Enabled on I2C Interface Dedicated for Smart Reflex (I2C4)".
+ * Otherwise I2C4 eventually leads into about 23mW extra power being
+ * consumed even during off idle using VMODE.
+ */
+ i2c_high_speed = voltdm->pmic->i2c_high_speed;
+ if (i2c_high_speed)
+ voltdm->rmw(vc->common->i2c_cfg_clear_mask,
+ vc->common->i2c_cfg_hsen_mask,
+ vc->common->i2c_cfg_reg);
+
+ mcode = voltdm->pmic->i2c_mcode;
+ if (mcode)
+ voltdm->rmw(vc->common->i2c_mcode_mask,
+ mcode << __ffs(vc->common->i2c_mcode_mask),
+ vc->common->i2c_cfg_reg);
+
+ if (cpu_is_omap44xx())
+ omap4_vc_i2c_timing_init(voltdm);
+
+ initialized = true;
+}
+
+/**
+ * omap_vc_calc_vsel - calculate vsel value for a channel
+ * @voltdm: channel to calculate value for
+ * @uvolt: microvolt value to convert to vsel
+ *
+ * Converts a microvolt value to vsel value for the used PMIC.
+ * This checks whether the microvolt value is out of bounds, and
+ * adjusts the value accordingly. If unsupported value detected,
+ * warning is thrown.
+ */
+static u8 omap_vc_calc_vsel(struct voltagedomain *voltdm, u32 uvolt)
+{
+ if (voltdm->pmic->vddmin > uvolt)
+ uvolt = voltdm->pmic->vddmin;
+ if (voltdm->pmic->vddmax < uvolt) {
+ WARN(1, "%s: voltage not supported by pmic: %u vs max %u\n",
+ __func__, uvolt, voltdm->pmic->vddmax);
+ /* Lets try maximum value anyway */
+ uvolt = voltdm->pmic->vddmax;
+ }
+
+ return voltdm->pmic->uv_to_vsel(uvolt);
+}
+
+#ifdef CONFIG_PM
+/**
+ * omap_pm_setup_sr_i2c_pcb_length - set length of SR I2C traces on PCB
+ * @mm: length of the PCB trace in millimetres
+ *
+ * Sets the PCB trace length for the I2C channel. By default uses 63mm.
+ * This is needed for properly calculating the capacitance value for
+ * the PCB trace, and for setting the SR I2C channel timing parameters.
+ */
+void __init omap_pm_setup_sr_i2c_pcb_length(u32 mm)
+{
+ sr_i2c_pcb_length = mm;
+}
+#endif
+
+void __init omap_vc_init_channel(struct voltagedomain *voltdm)
+{
+ struct omap_vc_channel *vc = voltdm->vc;
+ u8 on_vsel, onlp_vsel, ret_vsel, off_vsel;
+ u32 val;
+
+ if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) {
+ pr_err("%s: No PMIC info for vdd_%s\n", __func__, voltdm->name);
+ return;
+ }
+
+ if (!voltdm->read || !voltdm->write) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ vc->cfg_channel = 0;
+ if (vc->flags & OMAP_VC_CHANNEL_CFG_MUTANT)
+ vc_cfg_bits = &vc_mutant_channel_cfg;
+ else
+ vc_cfg_bits = &vc_default_channel_cfg;
+
+ /* get PMIC/board specific settings */
+ vc->i2c_slave_addr = voltdm->pmic->i2c_slave_addr;
+ vc->volt_reg_addr = voltdm->pmic->volt_reg_addr;
+ vc->cmd_reg_addr = voltdm->pmic->cmd_reg_addr;
+
+ /* Configure the i2c slave address for this VC */
+ voltdm->rmw(vc->smps_sa_mask,
+ vc->i2c_slave_addr << __ffs(vc->smps_sa_mask),
+ vc->smps_sa_reg);
+ vc->cfg_channel |= vc_cfg_bits->sa;
+
+ /*
+ * Configure the PMIC register addresses.
+ */
+ voltdm->rmw(vc->smps_volra_mask,
+ vc->volt_reg_addr << __ffs(vc->smps_volra_mask),
+ vc->smps_volra_reg);
+ vc->cfg_channel |= vc_cfg_bits->rav;
+
+ if (vc->cmd_reg_addr) {
+ voltdm->rmw(vc->smps_cmdra_mask,
+ vc->cmd_reg_addr << __ffs(vc->smps_cmdra_mask),
+ vc->smps_cmdra_reg);
+ vc->cfg_channel |= vc_cfg_bits->rac;
+ }
+
+ if (vc->cmd_reg_addr == vc->volt_reg_addr)
+ vc->cfg_channel |= vc_cfg_bits->racen;
+
+ /* Set up the on, inactive, retention and off voltage */
+ on_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->on);
+ onlp_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->onlp);
+ ret_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->ret);
+ off_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->off);
+
+ val = ((on_vsel << vc->common->cmd_on_shift) |
+ (onlp_vsel << vc->common->cmd_onlp_shift) |
+ (ret_vsel << vc->common->cmd_ret_shift) |
+ (off_vsel << vc->common->cmd_off_shift));
+ voltdm->write(val, vc->cmdval_reg);
+ vc->cfg_channel |= vc_cfg_bits->cmd;
+
+ /* Channel configuration */
+ omap_vc_config_channel(voltdm);
+
+ omap_vc_i2c_init(voltdm);
+
+ if (cpu_is_omap34xx())
+ omap3_vc_init_channel(voltdm);
+ else if (cpu_is_omap44xx())
+ omap4_vc_init_channel(voltdm);
+}
+
diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h
new file mode 100644
index 000000000..89b83b7ff
--- /dev/null
+++ b/arch/arm/mach-omap2/vc.h
@@ -0,0 +1,136 @@
+/*
+ * 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 voltagedomain;
+
+/**
+ * struct omap_vc_common - 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
+ * @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
+ * @i2c_cfg_reg: I2C configuration register offset
+ * @i2c_cfg_clear_mask: high-speed mode bit clear mask in I2C config register
+ * @i2c_cfg_hsen_mask: high-speed mode bit field mask in I2C config register
+ * @i2c_mcode_mask: MCODE field mask for I2C config 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 {
+ u32 cmd_on_mask;
+ u32 valid;
+ 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;
+ u8 i2c_cfg_reg;
+ u8 i2c_cfg_clear_mask;
+ u8 i2c_cfg_hsen_mask;
+ u8 i2c_mcode_mask;
+};
+
+/* omap_vc_channel.flags values */
+#define OMAP_VC_CHANNEL_DEFAULT BIT(0)
+#define OMAP_VC_CHANNEL_CFG_MUTANT BIT(1)
+
+/**
+ * struct omap_vc_channel - VC per-instance data
+ * @i2c_slave_addr: I2C slave address of PMIC for this VC channel
+ * @volt_reg_addr: voltage configuration register address
+ * @cmd_reg_addr: command configuration register address
+ * @setup_time: setup time (in sys_clk cycles) of regulator for this channel
+ * @cfg_channel: current value of VC channel configuration register
+ * @i2c_high_speed: whether or not to use I2C high-speed mode
+ *
+ * @common: pointer to VC common data for this platform
+ * @smps_sa_mask: i2c slave address bitmask in the PRM_VC_SMPS_SA register
+ * @smps_volra_mask: VOLRA* bitmask in the PRM_VC_VOL_RA register
+ * @smps_cmdra_mask: CMDRA* bitmask in the PRM_VC_CMD_RA register
+ * @cmdval_reg: register for on/ret/off voltage level values for this channel
+ * @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
+ * @smps_cmdra_reg: Offset of PRM_VC_SMPS_CMD_RA reg from PRM start
+ * @cfg_channel_reg: VC channel configuration register
+ * @cfg_channel_sa_shift: bit shift for slave address cfg_channel register
+ * @flags: VC channel-specific flags (optional)
+ */
+struct omap_vc_channel {
+ /* channel state */
+ u16 i2c_slave_addr;
+ u16 volt_reg_addr;
+ u16 cmd_reg_addr;
+ u8 cfg_channel;
+ bool i2c_high_speed;
+
+ /* register access data */
+ const struct omap_vc_common *common;
+ u32 smps_sa_mask;
+ u32 smps_volra_mask;
+ u32 smps_cmdra_mask;
+ u8 cmdval_reg;
+ u8 smps_sa_reg;
+ u8 smps_volra_reg;
+ u8 smps_cmdra_reg;
+ u8 cfg_channel_reg;
+ u8 cfg_channel_sa_shift;
+ u8 flags;
+};
+
+extern struct omap_vc_channel omap3_vc_mpu;
+extern struct omap_vc_channel omap3_vc_core;
+
+extern struct omap_vc_channel omap4_vc_mpu;
+extern struct omap_vc_channel omap4_vc_iva;
+extern struct omap_vc_channel omap4_vc_core;
+
+extern struct omap_vc_param omap3_mpu_vc_data;
+extern struct omap_vc_param omap3_core_vc_data;
+
+extern struct omap_vc_param omap4_mpu_vc_data;
+extern struct omap_vc_param omap4_iva_vc_data;
+extern struct omap_vc_param omap4_core_vc_data;
+
+void omap3_vc_set_pmic_signaling(int core_next_state);
+
+
+void omap_vc_init_channel(struct voltagedomain *voltdm);
+int omap_vc_pre_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt,
+ u8 *target_vsel, u8 *current_vsel);
+void omap_vc_post_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt,
+ u8 target_vsel, u8 current_vsel);
+int omap_vc_bypass_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt);
+
+#endif
+
diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c
new file mode 100644
index 000000000..71d74c917
--- /dev/null
+++ b/arch/arm/mach-omap2/vc3xxx_data.c
@@ -0,0 +1,96 @@
+/*
+ * 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 "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 omap3_vc_common = {
+ .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,
+ .i2c_cfg_clear_mask = OMAP3430_SREN_MASK | OMAP3430_HSEN_MASK,
+ .i2c_cfg_hsen_mask = OMAP3430_HSEN_MASK,
+ .i2c_cfg_reg = OMAP3_PRM_VC_I2C_CFG_OFFSET,
+ .i2c_mcode_mask = OMAP3430_MCODE_MASK,
+};
+
+struct omap_vc_channel omap3_vc_mpu = {
+ .flags = OMAP_VC_CHANNEL_DEFAULT,
+ .common = &omap3_vc_common,
+ .smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET,
+ .smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET,
+ .smps_cmdra_reg = OMAP3_PRM_VC_SMPS_CMD_RA_OFFSET,
+ .cfg_channel_reg = OMAP3_PRM_VC_CH_CONF_OFFSET,
+ .cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET,
+ .smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA0_MASK,
+ .smps_volra_mask = OMAP3430_VOLRA0_MASK,
+ .smps_cmdra_mask = OMAP3430_CMDRA0_MASK,
+ .cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT,
+};
+
+struct omap_vc_channel omap3_vc_core = {
+ .common = &omap3_vc_common,
+ .smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET,
+ .smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET,
+ .smps_cmdra_reg = OMAP3_PRM_VC_SMPS_CMD_RA_OFFSET,
+ .cfg_channel_reg = OMAP3_PRM_VC_CH_CONF_OFFSET,
+ .cmdval_reg = OMAP3_PRM_VC_CMD_VAL_1_OFFSET,
+ .smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA1_MASK,
+ .smps_volra_mask = OMAP3430_VOLRA1_MASK,
+ .smps_cmdra_mask = OMAP3430_CMDRA1_MASK,
+ .cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT,
+};
+
+/*
+ * Voltage levels for different operating modes: on, sleep, retention and off
+ */
+#define OMAP3_ON_VOLTAGE_UV 1200000
+#define OMAP3_ONLP_VOLTAGE_UV 1000000
+#define OMAP3_RET_VOLTAGE_UV 975000
+#define OMAP3_OFF_VOLTAGE_UV 600000
+
+struct omap_vc_param omap3_mpu_vc_data = {
+ .on = OMAP3_ON_VOLTAGE_UV,
+ .onlp = OMAP3_ONLP_VOLTAGE_UV,
+ .ret = OMAP3_RET_VOLTAGE_UV,
+ .off = OMAP3_OFF_VOLTAGE_UV,
+};
+
+struct omap_vc_param omap3_core_vc_data = {
+ .on = OMAP3_ON_VOLTAGE_UV,
+ .onlp = OMAP3_ONLP_VOLTAGE_UV,
+ .ret = OMAP3_RET_VOLTAGE_UV,
+ .off = OMAP3_OFF_VOLTAGE_UV,
+};
diff --git a/arch/arm/mach-omap2/vc44xx_data.c b/arch/arm/mach-omap2/vc44xx_data.c
new file mode 100644
index 000000000..2abd5fa8a
--- /dev/null
+++ b/arch/arm/mach-omap2/vc44xx_data.c
@@ -0,0 +1,118 @@
+/*
+ * 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 "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 omap4_vc_common = {
+ .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,
+ .i2c_cfg_reg = OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET,
+ .i2c_cfg_clear_mask = OMAP4430_SRMODEEN_MASK | OMAP4430_HSMODEEN_MASK,
+ .i2c_cfg_hsen_mask = OMAP4430_HSMODEEN_MASK,
+ .i2c_mcode_mask = OMAP4430_HSMCODE_MASK,
+};
+
+/* VC instance data for each controllable voltage line */
+struct omap_vc_channel omap4_vc_mpu = {
+ .flags = OMAP_VC_CHANNEL_DEFAULT | OMAP_VC_CHANNEL_CFG_MUTANT,
+ .common = &omap4_vc_common,
+ .smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET,
+ .smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
+ .smps_cmdra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET,
+ .cfg_channel_reg = OMAP4_PRM_VC_CFG_CHANNEL_OFFSET,
+ .cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET,
+ .smps_sa_mask = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK,
+ .smps_volra_mask = OMAP4430_VOLRA_VDD_MPU_L_MASK,
+ .smps_cmdra_mask = OMAP4430_CMDRA_VDD_MPU_L_MASK,
+ .cfg_channel_sa_shift = OMAP4430_SA_VDD_MPU_L_SHIFT,
+};
+
+struct omap_vc_channel omap4_vc_iva = {
+ .common = &omap4_vc_common,
+ .smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET,
+ .smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
+ .smps_cmdra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET,
+ .cfg_channel_reg = OMAP4_PRM_VC_CFG_CHANNEL_OFFSET,
+ .cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET,
+ .smps_sa_mask = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK,
+ .smps_volra_mask = OMAP4430_VOLRA_VDD_IVA_L_MASK,
+ .smps_cmdra_mask = OMAP4430_CMDRA_VDD_IVA_L_MASK,
+ .cfg_channel_sa_shift = OMAP4430_SA_VDD_IVA_L_SHIFT,
+};
+
+struct omap_vc_channel omap4_vc_core = {
+ .common = &omap4_vc_common,
+ .smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET,
+ .smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
+ .smps_cmdra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET,
+ .cfg_channel_reg = OMAP4_PRM_VC_CFG_CHANNEL_OFFSET,
+ .cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET,
+ .smps_sa_mask = OMAP4430_SA_VDD_CORE_L_0_6_MASK,
+ .smps_volra_mask = OMAP4430_VOLRA_VDD_CORE_L_MASK,
+ .smps_cmdra_mask = OMAP4430_CMDRA_VDD_CORE_L_MASK,
+ .cfg_channel_sa_shift = OMAP4430_SA_VDD_CORE_L_SHIFT,
+};
+
+/*
+ * Voltage levels for different operating modes: on, sleep, retention and off
+ */
+#define OMAP4_ON_VOLTAGE_UV 1375000
+#define OMAP4_ONLP_VOLTAGE_UV 1375000
+#define OMAP4_RET_VOLTAGE_UV 837500
+#define OMAP4_OFF_VOLTAGE_UV 0
+
+struct omap_vc_param omap4_mpu_vc_data = {
+ .on = OMAP4_ON_VOLTAGE_UV,
+ .onlp = OMAP4_ONLP_VOLTAGE_UV,
+ .ret = OMAP4_RET_VOLTAGE_UV,
+ .off = OMAP4_OFF_VOLTAGE_UV,
+};
+
+struct omap_vc_param omap4_iva_vc_data = {
+ .on = OMAP4_ON_VOLTAGE_UV,
+ .onlp = OMAP4_ONLP_VOLTAGE_UV,
+ .ret = OMAP4_RET_VOLTAGE_UV,
+ .off = OMAP4_OFF_VOLTAGE_UV,
+};
+
+struct omap_vc_param omap4_core_vc_data = {
+ .on = OMAP4_ON_VOLTAGE_UV,
+ .onlp = OMAP4_ONLP_VOLTAGE_UV,
+ .ret = OMAP4_RET_VOLTAGE_UV,
+ .off = OMAP4_OFF_VOLTAGE_UV,
+};
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
new file mode 100644
index 000000000..cba8cada8
--- /dev/null
+++ b/arch/arm/mach-omap2/voltage.c
@@ -0,0 +1,336 @@
+/*
+ * 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/err.h>
+#include <linux/export.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+
+#include "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 "powerdomain.h"
+
+#include "vc.h"
+#include "vp.h"
+
+static LIST_HEAD(voltdm_list);
+
+/* Public functions */
+/**
+ * voltdm_get_voltage() - Gets the current non-auto-compensated voltage
+ * @voltdm: pointer to the voltdm for which current voltage info is needed
+ *
+ * API to get the current non-auto-compensated voltage for a voltage domain.
+ * Returns 0 in case of error else returns the current voltage.
+ */
+unsigned long voltdm_get_voltage(struct voltagedomain *voltdm)
+{
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warn("%s: VDD specified does not exist!\n", __func__);
+ return 0;
+ }
+
+ return voltdm->nominal_volt;
+}
+
+/**
+ * voltdm_scale() - API to scale voltage of a particular voltage domain.
+ * @voltdm: pointer to the voltage domain 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.
+ */
+int voltdm_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt)
+{
+ int ret, i;
+ unsigned long volt = 0;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warn("%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ if (!voltdm->scale) {
+ pr_err("%s: No voltage scale API registered for vdd_%s\n",
+ __func__, voltdm->name);
+ return -ENODATA;
+ }
+
+ /* Adjust voltage to the exact voltage from the OPP table */
+ for (i = 0; voltdm->volt_data[i].volt_nominal != 0; i++) {
+ if (voltdm->volt_data[i].volt_nominal >= target_volt) {
+ volt = voltdm->volt_data[i].volt_nominal;
+ break;
+ }
+ }
+
+ if (!volt) {
+ pr_warn("%s: not scaling. OPP voltage for %lu, not found.\n",
+ __func__, target_volt);
+ return -EINVAL;
+ }
+
+ ret = voltdm->scale(voltdm, volt);
+ if (!ret)
+ voltdm->nominal_volt = volt;
+
+ return ret;
+}
+
+/**
+ * voltdm_reset() - Resets the voltage of a particular voltage domain
+ * to that of the current OPP.
+ * @voltdm: pointer to the voltage domain 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 voltdm_reset(struct voltagedomain *voltdm)
+{
+ unsigned long target_volt;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warn("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ target_volt = voltdm_get_voltage(voltdm);
+ if (!target_volt) {
+ pr_err("%s: unable to find current voltage for vdd_%s\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ voltdm_scale(voltdm, target_volt);
+}
+
+/**
+ * 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)
+{
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warn("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ *volt_data = voltdm->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)
+{
+ int i;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warn("%s: VDD specified does not exist!\n", __func__);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (!voltdm->volt_data) {
+ pr_warn("%s: voltage table does not exist for vdd_%s\n",
+ __func__, voltdm->name);
+ return ERR_PTR(-ENODATA);
+ }
+
+ for (i = 0; voltdm->volt_data[i].volt_nominal != 0; i++) {
+ if (voltdm->volt_data[i].volt_nominal == volt)
+ return &voltdm->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: 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_voltdm_pmic structure.
+ */
+int omap_voltage_register_pmic(struct voltagedomain *voltdm,
+ struct omap_voltdm_pmic *pmic)
+{
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warn("%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ voltdm->pmic = pmic;
+
+ return 0;
+}
+
+/**
+ * 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)
+{
+ struct voltagedomain *voltdm;
+
+ if (list_empty(&voltdm_list)) {
+ pr_err("%s: Voltage driver support not added\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ list_for_each_entry(voltdm, &voltdm_list, node) {
+ struct clk *sys_ck;
+
+ if (!voltdm->scalable)
+ continue;
+
+ sys_ck = clk_get(NULL, voltdm->sys_clk.name);
+ if (IS_ERR(sys_ck)) {
+ pr_warn("%s: Could not get sys clk.\n", __func__);
+ return -EINVAL;
+ }
+ voltdm->sys_clk.rate = clk_get_rate(sys_ck);
+ WARN_ON(!voltdm->sys_clk.rate);
+ clk_put(sys_ck);
+
+ if (voltdm->vc) {
+ voltdm->scale = omap_vc_bypass_scale;
+ omap_vc_init_channel(voltdm);
+ }
+
+ if (voltdm->vp) {
+ voltdm->scale = omap_vp_forceupdate_scale;
+ omap_vp_init(voltdm);
+ }
+ }
+
+ return 0;
+}
+
+static struct voltagedomain *_voltdm_lookup(const char *name)
+{
+ struct voltagedomain *voltdm, *temp_voltdm;
+
+ voltdm = NULL;
+
+ list_for_each_entry(temp_voltdm, &voltdm_list, node) {
+ if (!strcmp(name, temp_voltdm->name)) {
+ voltdm = temp_voltdm;
+ break;
+ }
+ }
+
+ return voltdm;
+}
+
+static int _voltdm_register(struct voltagedomain *voltdm)
+{
+ if (!voltdm || !voltdm->name)
+ return -EINVAL;
+
+ list_add(&voltdm->node, &voltdm_list);
+
+ pr_debug("voltagedomain: registered %s\n", voltdm->name);
+
+ return 0;
+}
+
+/**
+ * voltdm_lookup - look up a voltagedomain by name, return a pointer
+ * @name: name of voltagedomain
+ *
+ * Find a registered voltagedomain by its name @name. Returns a pointer
+ * to the struct voltagedomain if found, or NULL otherwise.
+ */
+struct voltagedomain *voltdm_lookup(const char *name)
+{
+ struct voltagedomain *voltdm ;
+
+ if (!name)
+ return NULL;
+
+ voltdm = _voltdm_lookup(name);
+
+ return voltdm;
+}
+
+/**
+ * voltdm_init - set up the voltagedomain layer
+ * @voltdm_list: array of struct voltagedomain pointers to register
+ *
+ * Loop through the array of voltagedomains @voltdm_list, registering all
+ * that are available on the current CPU. If voltdm_list is supplied
+ * and not null, all of the referenced voltagedomains will be
+ * registered. No return value.
+ */
+void voltdm_init(struct voltagedomain **voltdms)
+{
+ struct voltagedomain **v;
+
+ if (voltdms) {
+ for (v = voltdms; *v; v++)
+ _voltdm_register(*v);
+ }
+}
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
new file mode 100644
index 000000000..e64550321
--- /dev/null
+++ b/arch/arm/mach-omap2/voltage.h
@@ -0,0 +1,173 @@
+/*
+ * 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 <linux/platform_data/voltage-omap.h>
+
+#include "vc.h"
+#include "vp.h"
+
+struct powerdomain;
+
+/*
+ * 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 - 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_off_reg: register offset of PRM_VOLTSETUP_OFF from PRM base
+ *
+ * XXX What about VOLTOFFSET/VOLTCTRL?
+ */
+struct omap_vfsm_instance {
+ u32 voltsetup_mask;
+ u8 voltsetup_reg;
+ u8 voltsetup_off_reg;
+};
+
+/**
+ * struct voltagedomain - omap voltage domain global structure.
+ * @name: Name of the voltage domain which can be used as a unique identifier.
+ * @scalable: Whether or not this voltage domain is scalable
+ * @node: list_head linking all voltage domains
+ * @vc: pointer to VC channel associated with this voltagedomain
+ * @vp: pointer to VP associated with this voltagedomain
+ * @read: read a VC/VP register
+ * @write: write a VC/VP register
+ * @read: read-modify-write a VC/VP register
+ * @sys_clk: system clock name/frequency, used for various timing calculations
+ * @scale: function used to scale the voltage of the voltagedomain
+ * @nominal_volt: current nominal voltage for this voltage domain
+ * @volt_data: voltage table having the distinct voltages supported
+ * by the domain and other associated per voltage data.
+ */
+struct voltagedomain {
+ char *name;
+ bool scalable;
+ struct list_head node;
+ struct omap_vc_channel *vc;
+ const struct omap_vfsm_instance *vfsm;
+ struct omap_vp_instance *vp;
+ struct omap_voltdm_pmic *pmic;
+ struct omap_vp_param *vp_param;
+ struct omap_vc_param *vc_param;
+
+ /* VC/VP register access functions: SoC specific */
+ u32 (*read) (u8 offset);
+ void (*write) (u32 val, u8 offset);
+ u32 (*rmw)(u32 mask, u32 bits, u8 offset);
+
+ union {
+ const char *name;
+ u32 rate;
+ } sys_clk;
+
+ int (*scale) (struct voltagedomain *voltdm,
+ unsigned long target_volt);
+
+ u32 nominal_volt;
+ struct omap_volt_data *volt_data;
+};
+
+/* Min and max voltages from OMAP perspective */
+#define OMAP3430_VP1_VLIMITTO_VDDMIN 850000
+#define OMAP3430_VP1_VLIMITTO_VDDMAX 1425000
+#define OMAP3430_VP2_VLIMITTO_VDDMIN 900000
+#define OMAP3430_VP2_VLIMITTO_VDDMAX 1150000
+
+#define OMAP3630_VP1_VLIMITTO_VDDMIN 900000
+#define OMAP3630_VP1_VLIMITTO_VDDMAX 1350000
+#define OMAP3630_VP2_VLIMITTO_VDDMIN 900000
+#define OMAP3630_VP2_VLIMITTO_VDDMAX 1200000
+
+#define OMAP4_VP_MPU_VLIMITTO_VDDMIN 830000
+#define OMAP4_VP_MPU_VLIMITTO_VDDMAX 1410000
+#define OMAP4_VP_IVA_VLIMITTO_VDDMIN 830000
+#define OMAP4_VP_IVA_VLIMITTO_VDDMAX 1260000
+#define OMAP4_VP_CORE_VLIMITTO_VDDMIN 830000
+#define OMAP4_VP_CORE_VLIMITTO_VDDMAX 1200000
+
+/**
+ * struct omap_voltdm_pmic - PMIC specific data required by voltage driver.
+ * @slew_rate: PMIC slew rate (in uv/us)
+ * @step_size: PMIC voltage step size (in uv)
+ * @i2c_slave_addr: I2C slave address of PMIC
+ * @volt_reg_addr: voltage configuration register address
+ * @cmd_reg_addr: command (on, on-LP, ret, off) configuration register address
+ * @i2c_high_speed: whether VC uses I2C high-speed mode to PMIC
+ * @i2c_mcode: master code value for I2C high-speed preamble transmission
+ * @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_voltdm_pmic {
+ int slew_rate;
+ int step_size;
+ u16 i2c_slave_addr;
+ u16 volt_reg_addr;
+ u16 cmd_reg_addr;
+ u8 vp_erroroffset;
+ u8 vp_vstepmin;
+ u8 vp_vstepmax;
+ u32 vddmin;
+ u32 vddmax;
+ u8 vp_timeout_us;
+ bool i2c_high_speed;
+ u32 i2c_pad_load;
+ u8 i2c_mcode;
+ unsigned long (*vsel_to_uv) (const u8 vsel);
+ u8 (*uv_to_vsel) (unsigned long uV);
+};
+
+struct omap_vp_param {
+ u32 vddmax;
+ u32 vddmin;
+};
+
+struct omap_vc_param {
+ u32 on;
+ u32 onlp;
+ u32 ret;
+ u32 off;
+};
+
+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);
+int omap_voltage_register_pmic(struct voltagedomain *voltdm,
+ struct omap_voltdm_pmic *pmic);
+int omap_voltage_late_init(void);
+
+extern void omap2xxx_voltagedomains_init(void);
+extern void omap3xxx_voltagedomains_init(void);
+extern void omap44xx_voltagedomains_init(void);
+extern void omap54xx_voltagedomains_init(void);
+
+struct voltagedomain *voltdm_lookup(const char *name);
+void voltdm_init(struct voltagedomain **voltdm_list);
+int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm);
+int voltdm_scale(struct voltagedomain *voltdm, unsigned long target_volt);
+void voltdm_reset(struct voltagedomain *voltdm);
+unsigned long voltdm_get_voltage(struct voltagedomain *voltdm);
+#endif
diff --git a/arch/arm/mach-omap2/voltagedomains2xxx_data.c b/arch/arm/mach-omap2/voltagedomains2xxx_data.c
new file mode 100644
index 000000000..7a4134998
--- /dev/null
+++ b/arch/arm/mach-omap2/voltagedomains2xxx_data.c
@@ -0,0 +1,32 @@
+/*
+ * OMAP3 voltage domain data
+ *
+ * Copyright (C) 2011 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 "voltage.h"
+
+static struct voltagedomain omap2_voltdm_core = {
+ .name = "core",
+};
+
+static struct voltagedomain omap2_voltdm_wkup = {
+ .name = "wakeup",
+};
+
+static struct voltagedomain *voltagedomains_omap2[] __initdata = {
+ &omap2_voltdm_core,
+ &omap2_voltdm_wkup,
+ NULL,
+};
+
+void __init omap2xxx_voltagedomains_init(void)
+{
+ voltdm_init(voltagedomains_omap2);
+}
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
new file mode 100644
index 000000000..261bb7cb4
--- /dev/null
+++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
@@ -0,0 +1,134 @@
+/*
+ * 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 "soc.h"
+#include "common.h"
+#include "prm-regbits-34xx.h"
+#include "omap_opp_data.h"
+#include "voltage.h"
+#include "vc.h"
+#include "vp.h"
+
+/*
+ * VDD data
+ */
+
+/* OMAP3-common voltagedomain data */
+
+static struct voltagedomain omap3_voltdm_wkup = {
+ .name = "wakeup",
+};
+
+/* 34xx/36xx voltagedomain data */
+
+static const struct omap_vfsm_instance omap3_vdd1_vfsm = {
+ .voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET,
+ .voltsetup_mask = OMAP3430_SETUP_TIME1_MASK,
+};
+
+static const struct omap_vfsm_instance omap3_vdd2_vfsm = {
+ .voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET,
+ .voltsetup_mask = OMAP3430_SETUP_TIME2_MASK,
+};
+
+static struct voltagedomain omap3_voltdm_mpu = {
+ .name = "mpu_iva",
+ .scalable = true,
+ .read = omap3_prm_vcvp_read,
+ .write = omap3_prm_vcvp_write,
+ .rmw = omap3_prm_vcvp_rmw,
+ .vc = &omap3_vc_mpu,
+ .vfsm = &omap3_vdd1_vfsm,
+ .vp = &omap3_vp_mpu,
+};
+
+static struct voltagedomain omap3_voltdm_core = {
+ .name = "core",
+ .scalable = true,
+ .read = omap3_prm_vcvp_read,
+ .write = omap3_prm_vcvp_write,
+ .rmw = omap3_prm_vcvp_rmw,
+ .vc = &omap3_vc_core,
+ .vfsm = &omap3_vdd2_vfsm,
+ .vp = &omap3_vp_core,
+};
+
+static struct voltagedomain *voltagedomains_omap3[] __initdata = {
+ &omap3_voltdm_mpu,
+ &omap3_voltdm_core,
+ &omap3_voltdm_wkup,
+ NULL,
+};
+
+/* AM35xx voltagedomain data */
+
+static struct voltagedomain am35xx_voltdm_mpu = {
+ .name = "mpu_iva",
+};
+
+static struct voltagedomain am35xx_voltdm_core = {
+ .name = "core",
+};
+
+static struct voltagedomain *voltagedomains_am35xx[] __initdata = {
+ &am35xx_voltdm_mpu,
+ &am35xx_voltdm_core,
+ &omap3_voltdm_wkup,
+ NULL,
+};
+
+
+static const char *sys_clk_name __initdata = "sys_ck";
+
+void __init omap3xxx_voltagedomains_init(void)
+{
+ struct voltagedomain *voltdm;
+ struct voltagedomain **voltdms;
+ int i;
+
+ /*
+ * XXX Will depend on the process, validation, and binning
+ * for the currently-running IC
+ */
+#ifdef CONFIG_PM_OPP
+ if (cpu_is_omap3630()) {
+ omap3_voltdm_mpu.volt_data = omap36xx_vddmpu_volt_data;
+ omap3_voltdm_core.volt_data = omap36xx_vddcore_volt_data;
+ } else {
+ omap3_voltdm_mpu.volt_data = omap34xx_vddmpu_volt_data;
+ omap3_voltdm_core.volt_data = omap34xx_vddcore_volt_data;
+ }
+#endif
+
+ omap3_voltdm_mpu.vp_param = &omap3_mpu_vp_data;
+ omap3_voltdm_core.vp_param = &omap3_core_vp_data;
+ omap3_voltdm_mpu.vc_param = &omap3_mpu_vc_data;
+ omap3_voltdm_core.vc_param = &omap3_core_vc_data;
+
+ if (soc_is_am35xx())
+ voltdms = voltagedomains_am35xx;
+ else
+ voltdms = voltagedomains_omap3;
+
+ for (i = 0; voltdm = voltdms[i], voltdm; i++)
+ voltdm->sys_clk.name = sys_clk_name;
+
+ voltdm_init(voltdms);
+};
diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c
new file mode 100644
index 000000000..48b22a0a0
--- /dev/null
+++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
@@ -0,0 +1,130 @@
+/*
+ * 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 "common.h"
+#include "soc.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 omap4_vdd_mpu_vfsm = {
+ .voltsetup_reg = OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET,
+ .voltsetup_off_reg = OMAP4_PRM_VOLTSETUP_MPU_OFF_OFFSET,
+};
+
+static const struct omap_vfsm_instance omap4_vdd_iva_vfsm = {
+ .voltsetup_reg = OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET,
+ .voltsetup_off_reg = OMAP4_PRM_VOLTSETUP_IVA_OFF_OFFSET,
+};
+
+static const struct omap_vfsm_instance omap4_vdd_core_vfsm = {
+ .voltsetup_reg = OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET,
+ .voltsetup_off_reg = OMAP4_PRM_VOLTSETUP_CORE_OFF_OFFSET,
+};
+
+static struct voltagedomain omap4_voltdm_mpu = {
+ .name = "mpu",
+ .scalable = true,
+ .read = omap4_prm_vcvp_read,
+ .write = omap4_prm_vcvp_write,
+ .rmw = omap4_prm_vcvp_rmw,
+ .vc = &omap4_vc_mpu,
+ .vfsm = &omap4_vdd_mpu_vfsm,
+ .vp = &omap4_vp_mpu,
+};
+
+static struct voltagedomain omap4_voltdm_iva = {
+ .name = "iva",
+ .scalable = true,
+ .read = omap4_prm_vcvp_read,
+ .write = omap4_prm_vcvp_write,
+ .rmw = omap4_prm_vcvp_rmw,
+ .vc = &omap4_vc_iva,
+ .vfsm = &omap4_vdd_iva_vfsm,
+ .vp = &omap4_vp_iva,
+};
+
+static struct voltagedomain omap4_voltdm_core = {
+ .name = "core",
+ .scalable = true,
+ .read = omap4_prm_vcvp_read,
+ .write = omap4_prm_vcvp_write,
+ .rmw = omap4_prm_vcvp_rmw,
+ .vc = &omap4_vc_core,
+ .vfsm = &omap4_vdd_core_vfsm,
+ .vp = &omap4_vp_core,
+};
+
+static struct voltagedomain omap4_voltdm_wkup = {
+ .name = "wakeup",
+};
+
+static struct voltagedomain *voltagedomains_omap4[] __initdata = {
+ &omap4_voltdm_mpu,
+ &omap4_voltdm_iva,
+ &omap4_voltdm_core,
+ &omap4_voltdm_wkup,
+ NULL,
+};
+
+static const char *sys_clk_name __initdata = "sys_clkin_ck";
+
+void __init omap44xx_voltagedomains_init(void)
+{
+ struct voltagedomain *voltdm;
+ int i;
+
+ /*
+ * XXX Will depend on the process, validation, and binning
+ * for the currently-running IC
+ */
+#ifdef CONFIG_PM_OPP
+ if (cpu_is_omap443x()) {
+ omap4_voltdm_mpu.volt_data = omap443x_vdd_mpu_volt_data;
+ omap4_voltdm_iva.volt_data = omap443x_vdd_iva_volt_data;
+ omap4_voltdm_core.volt_data = omap443x_vdd_core_volt_data;
+ } else if (cpu_is_omap446x()) {
+ omap4_voltdm_mpu.volt_data = omap446x_vdd_mpu_volt_data;
+ omap4_voltdm_iva.volt_data = omap446x_vdd_iva_volt_data;
+ omap4_voltdm_core.volt_data = omap446x_vdd_core_volt_data;
+ }
+#endif
+
+ omap4_voltdm_mpu.vp_param = &omap4_mpu_vp_data;
+ omap4_voltdm_iva.vp_param = &omap4_iva_vp_data;
+ omap4_voltdm_core.vp_param = &omap4_core_vp_data;
+
+ omap4_voltdm_mpu.vc_param = &omap4_mpu_vc_data;
+ omap4_voltdm_iva.vc_param = &omap4_iva_vc_data;
+ omap4_voltdm_core.vc_param = &omap4_core_vc_data;
+
+ for (i = 0; voltdm = voltagedomains_omap4[i], voltdm; i++)
+ voltdm->sys_clk.name = sys_clk_name;
+
+ voltdm_init(voltagedomains_omap4);
+};
diff --git a/arch/arm/mach-omap2/voltagedomains54xx_data.c b/arch/arm/mach-omap2/voltagedomains54xx_data.c
new file mode 100644
index 000000000..33d22b872
--- /dev/null
+++ b/arch/arm/mach-omap2/voltagedomains54xx_data.c
@@ -0,0 +1,92 @@
+/*
+ * OMAP5 Voltage Management Routines
+ *
+ * Based on voltagedomains44xx_data.c
+ *
+ * Copyright (C) 2013 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/err.h>
+#include <linux/init.h>
+
+#include "common.h"
+
+#include "prm54xx.h"
+#include "voltage.h"
+#include "omap_opp_data.h"
+#include "vc.h"
+#include "vp.h"
+
+static const struct omap_vfsm_instance omap5_vdd_mpu_vfsm = {
+ .voltsetup_reg = OMAP54XX_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET,
+};
+
+static const struct omap_vfsm_instance omap5_vdd_mm_vfsm = {
+ .voltsetup_reg = OMAP54XX_PRM_VOLTSETUP_MM_RET_SLEEP_OFFSET,
+};
+
+static const struct omap_vfsm_instance omap5_vdd_core_vfsm = {
+ .voltsetup_reg = OMAP54XX_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET,
+};
+
+static struct voltagedomain omap5_voltdm_mpu = {
+ .name = "mpu",
+ .scalable = true,
+ .read = omap4_prm_vcvp_read,
+ .write = omap4_prm_vcvp_write,
+ .rmw = omap4_prm_vcvp_rmw,
+ .vc = &omap4_vc_mpu,
+ .vfsm = &omap5_vdd_mpu_vfsm,
+ .vp = &omap4_vp_mpu,
+};
+
+static struct voltagedomain omap5_voltdm_mm = {
+ .name = "mm",
+ .scalable = true,
+ .read = omap4_prm_vcvp_read,
+ .write = omap4_prm_vcvp_write,
+ .rmw = omap4_prm_vcvp_rmw,
+ .vc = &omap4_vc_iva,
+ .vfsm = &omap5_vdd_mm_vfsm,
+ .vp = &omap4_vp_iva,
+};
+
+static struct voltagedomain omap5_voltdm_core = {
+ .name = "core",
+ .scalable = true,
+ .read = omap4_prm_vcvp_read,
+ .write = omap4_prm_vcvp_write,
+ .rmw = omap4_prm_vcvp_rmw,
+ .vc = &omap4_vc_core,
+ .vfsm = &omap5_vdd_core_vfsm,
+ .vp = &omap4_vp_core,
+};
+
+static struct voltagedomain omap5_voltdm_wkup = {
+ .name = "wkup",
+};
+
+static struct voltagedomain *voltagedomains_omap5[] __initdata = {
+ &omap5_voltdm_mpu,
+ &omap5_voltdm_mm,
+ &omap5_voltdm_core,
+ &omap5_voltdm_wkup,
+ NULL,
+};
+
+static const char *sys_clk_name __initdata = "sys_clkin";
+
+void __init omap54xx_voltagedomains_init(void)
+{
+ struct voltagedomain *voltdm;
+ int i;
+
+ for (i = 0; voltdm = voltagedomains_omap5[i], voltdm; i++)
+ voltdm->sys_clk.name = sys_clk_name;
+
+ voltdm_init(voltagedomains_omap5);
+};
diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c
new file mode 100644
index 000000000..a3c30655a
--- /dev/null
+++ b/arch/arm/mach-omap2/vp.c
@@ -0,0 +1,282 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include "common.h"
+
+#include "voltage.h"
+#include "vp.h"
+#include "prm-regbits-34xx.h"
+#include "prm-regbits-44xx.h"
+#include "prm44xx.h"
+
+static u32 _vp_set_init_voltage(struct voltagedomain *voltdm, u32 volt)
+{
+ struct omap_vp_instance *vp = voltdm->vp;
+ u32 vpconfig;
+ char vsel;
+
+ vsel = voltdm->pmic->uv_to_vsel(volt);
+
+ vpconfig = voltdm->read(vp->vpconfig);
+ vpconfig &= ~(vp->common->vpconfig_initvoltage_mask |
+ vp->common->vpconfig_forceupdate |
+ vp->common->vpconfig_initvdd);
+ vpconfig |= vsel << __ffs(vp->common->vpconfig_initvoltage_mask);
+ voltdm->write(vpconfig, vp->vpconfig);
+
+ /* Trigger initVDD value copy to voltage processor */
+ voltdm->write((vpconfig | vp->common->vpconfig_initvdd),
+ vp->vpconfig);
+
+ /* Clear initVDD copy trigger bit */
+ voltdm->write(vpconfig, vp->vpconfig);
+
+ return vpconfig;
+}
+
+/* Generic voltage init functions */
+void __init omap_vp_init(struct voltagedomain *voltdm)
+{
+ struct omap_vp_instance *vp = voltdm->vp;
+ u32 val, sys_clk_rate, timeout, waittime;
+ u32 vddmin, vddmax, vstepmin, vstepmax;
+
+ if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) {
+ pr_err("%s: No PMIC info for vdd_%s\n", __func__, voltdm->name);
+ return;
+ }
+
+ if (!voltdm->read || !voltdm->write) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ vp->enabled = false;
+
+ /* Divide to avoid overflow */
+ sys_clk_rate = voltdm->sys_clk.rate / 1000;
+
+ timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000;
+ vddmin = max(voltdm->vp_param->vddmin, voltdm->pmic->vddmin);
+ vddmax = min(voltdm->vp_param->vddmax, voltdm->pmic->vddmax);
+ vddmin = voltdm->pmic->uv_to_vsel(vddmin);
+ vddmax = voltdm->pmic->uv_to_vsel(vddmax);
+
+ waittime = DIV_ROUND_UP(voltdm->pmic->step_size * sys_clk_rate,
+ 1000 * voltdm->pmic->slew_rate);
+ vstepmin = voltdm->pmic->vp_vstepmin;
+ vstepmax = voltdm->pmic->vp_vstepmax;
+
+ /*
+ * VP_CONFIG: error gain is not set here, it will be updated
+ * on each scale, based on OPP.
+ */
+ val = (voltdm->pmic->vp_erroroffset <<
+ __ffs(voltdm->vp->common->vpconfig_erroroffset_mask)) |
+ vp->common->vpconfig_timeouten;
+ voltdm->write(val, vp->vpconfig);
+
+ /* VSTEPMIN */
+ val = (waittime << vp->common->vstepmin_smpswaittimemin_shift) |
+ (vstepmin << vp->common->vstepmin_stepmin_shift);
+ voltdm->write(val, vp->vstepmin);
+
+ /* VSTEPMAX */
+ val = (vstepmax << vp->common->vstepmax_stepmax_shift) |
+ (waittime << vp->common->vstepmax_smpswaittimemax_shift);
+ voltdm->write(val, vp->vstepmax);
+
+ /* VLIMITTO */
+ val = (vddmax << vp->common->vlimitto_vddmax_shift) |
+ (vddmin << vp->common->vlimitto_vddmin_shift) |
+ (timeout << vp->common->vlimitto_timeout_shift);
+ voltdm->write(val, vp->vlimitto);
+}
+
+int omap_vp_update_errorgain(struct voltagedomain *voltdm,
+ unsigned long target_volt)
+{
+ struct omap_volt_data *volt_data;
+
+ if (!voltdm->vp)
+ return -EINVAL;
+
+ /* Get volt_data corresponding to target_volt */
+ volt_data = omap_voltage_get_voltdata(voltdm, target_volt);
+ if (IS_ERR(volt_data))
+ return -EINVAL;
+
+ /* Setting vp errorgain based on the voltage */
+ voltdm->rmw(voltdm->vp->common->vpconfig_errorgain_mask,
+ volt_data->vp_errgain <<
+ __ffs(voltdm->vp->common->vpconfig_errorgain_mask),
+ voltdm->vp->vpconfig);
+
+ return 0;
+}
+
+/* VP force update method of voltage scaling */
+int omap_vp_forceupdate_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt)
+{
+ struct omap_vp_instance *vp = voltdm->vp;
+ u32 vpconfig;
+ u8 target_vsel, current_vsel;
+ int ret, timeout = 0;
+
+ ret = omap_vc_pre_scale(voltdm, target_volt, &target_vsel, &current_vsel);
+ if (ret)
+ return ret;
+
+ /*
+ * Clear all pending TransactionDone interrupt/status. Typical latency
+ * is <3us
+ */
+ while (timeout++ < VP_TRANXDONE_TIMEOUT) {
+ vp->common->ops->clear_txdone(vp->id);
+ if (!vp->common->ops->check_txdone(vp->id))
+ break;
+ udelay(1);
+ }
+ if (timeout >= VP_TRANXDONE_TIMEOUT) {
+ pr_warn("%s: vdd_%s TRANXDONE timeout exceeded. Voltage change aborted\n",
+ __func__, voltdm->name);
+ return -ETIMEDOUT;
+ }
+
+ vpconfig = _vp_set_init_voltage(voltdm, target_volt);
+
+ /* Force update of voltage */
+ voltdm->write(vpconfig | vp->common->vpconfig_forceupdate,
+ voltdm->vp->vpconfig);
+
+ /*
+ * Wait for TransactionDone. Typical latency is <200us.
+ * Depends on SMPSWAITTIMEMIN/MAX and voltage change
+ */
+ timeout = 0;
+ omap_test_timeout(vp->common->ops->check_txdone(vp->id),
+ 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__, voltdm->name);
+
+ omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel);
+
+ /*
+ * Disable TransactionDone interrupt , clear all status, clear
+ * control registers
+ */
+ timeout = 0;
+ while (timeout++ < VP_TRANXDONE_TIMEOUT) {
+ vp->common->ops->clear_txdone(vp->id);
+ if (!vp->common->ops->check_txdone(vp->id))
+ break;
+ udelay(1);
+ }
+
+ if (timeout >= VP_TRANXDONE_TIMEOUT)
+ pr_warn("%s: vdd_%s TRANXDONE timeout exceeded while trying to clear the TRANXDONE status\n",
+ __func__, voltdm->name);
+
+ /* Clear force bit */
+ voltdm->write(vpconfig, vp->vpconfig);
+
+ return 0;
+}
+
+/**
+ * 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_vp_instance *vp;
+ u32 vpconfig, volt;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warn("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ vp = voltdm->vp;
+ if (!voltdm->read || !voltdm->write) {
+ 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 (vp->enabled)
+ return;
+
+ volt = voltdm_get_voltage(voltdm);
+ if (!volt) {
+ pr_warn("%s: unable to find current voltage for %s\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ vpconfig = _vp_set_init_voltage(voltdm, volt);
+
+ /* Enable VP */
+ vpconfig |= vp->common->vpconfig_vpenable;
+ voltdm->write(vpconfig, vp->vpconfig);
+
+ 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_vp_instance *vp;
+ u32 vpconfig;
+ int timeout;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warn("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ vp = voltdm->vp;
+ if (!voltdm->read || !voltdm->write) {
+ 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 (!vp->enabled) {
+ pr_warn("%s: Trying to disable VP for vdd_%s when it is already disabled\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ /* Disable VP */
+ vpconfig = voltdm->read(vp->vpconfig);
+ vpconfig &= ~vp->common->vpconfig_vpenable;
+ voltdm->write(vpconfig, vp->vpconfig);
+
+ /*
+ * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
+ */
+ omap_test_timeout((voltdm->read(vp->vstatus)),
+ VP_IDLE_TIMEOUT, timeout);
+
+ if (timeout >= VP_IDLE_TIMEOUT)
+ pr_warn("%s: vdd_%s idle timedout\n", __func__, voltdm->name);
+
+ vp->enabled = false;
+
+ return;
+}
diff --git a/arch/arm/mach-omap2/vp.h b/arch/arm/mach-omap2/vp.h
new file mode 100644
index 000000000..7e0829682
--- /dev/null
+++ b/arch/arm/mach-omap2/vp.h
@@ -0,0 +1,126 @@
+/*
+ * 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>
+
+struct voltagedomain;
+
+/* XXX document */
+#define VP_IDLE_TIMEOUT 200
+#define VP_TRANXDONE_TIMEOUT 300
+
+/**
+ * struct omap_vp_ops - per-VP operations
+ * @check_txdone: check for VP transaction done
+ * @clear_txdone: clear VP transaction done status
+ */
+struct omap_vp_ops {
+ u32 (*check_txdone)(u8 vp_id);
+ void (*clear_txdone)(u8 vp_id);
+};
+
+/**
+ * struct omap_vp_common - register data common to all VDDs
+ * @vpconfig_erroroffset_mask: ERROROFFSET bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_errorgain_mask: ERRORGAIN bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_initvoltage_mask: INITVOLTAGE bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_timeouten: 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
+ * @vstepmin_stepmin_shift: VSTEPMIN field shift in the PRM_VP*_VSTEPMIN reg
+ * @vstepmin_smpswaittimemin_shift: SMPSWAITTIMEMIN field shift in PRM_VP*_VSTEPMIN reg
+ * @vstepmax_stepmax_shift: VSTEPMAX field shift in the PRM_VP*_VSTEPMAX reg
+ * @vstepmax_smpswaittimemax_shift: SMPSWAITTIMEMAX field shift in PRM_VP*_VSTEPMAX reg
+ * @vlimitto_vddmin_shift: VDDMIN field shift in PRM_VP*_VLIMITTO reg
+ * @vlimitto_vddmax_shift: VDDMAX field shift in PRM_VP*_VLIMITTO reg
+ * @vlimitto_timeout_shift: TIMEOUT field shift in PRM_VP*_VLIMITTO reg
+ * @vpvoltage_mask: VPVOLTAGE field mask in PRM_VP*_VOLTAGE reg
+ */
+struct omap_vp_common {
+ u32 vpconfig_erroroffset_mask;
+ u32 vpconfig_errorgain_mask;
+ u32 vpconfig_initvoltage_mask;
+ u8 vpconfig_timeouten;
+ u8 vpconfig_initvdd;
+ u8 vpconfig_forceupdate;
+ u8 vpconfig_vpenable;
+ 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;
+ u8 vpvoltage_mask;
+
+ const struct omap_vp_ops *ops;
+};
+
+/**
+ * struct omap_vp_instance - VP register offsets (per-VDD)
+ * @common: pointer to struct omap_vp_common * for this SoC
+ * @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
+ * @id: Unique identifier for VP instance.
+ * @enabled: flag to keep track of whether vp is enabled or not
+ *
+ * XXX vp_common is probably not needed since it is per-SoC
+ */
+struct omap_vp_instance {
+ const struct omap_vp_common *common;
+ u8 vpconfig;
+ u8 vstepmin;
+ u8 vstepmax;
+ u8 vlimitto;
+ u8 vstatus;
+ u8 voltage;
+ u8 id;
+ bool enabled;
+};
+
+extern struct omap_vp_instance omap3_vp_mpu;
+extern struct omap_vp_instance omap3_vp_core;
+
+extern struct omap_vp_instance omap4_vp_mpu;
+extern struct omap_vp_instance omap4_vp_iva;
+extern struct omap_vp_instance omap4_vp_core;
+
+extern struct omap_vp_param omap3_mpu_vp_data;
+extern struct omap_vp_param omap3_core_vp_data;
+
+extern struct omap_vp_param omap4_mpu_vp_data;
+extern struct omap_vp_param omap4_iva_vp_data;
+extern struct omap_vp_param omap4_core_vp_data;
+
+void omap_vp_init(struct voltagedomain *voltdm);
+void omap_vp_enable(struct voltagedomain *voltdm);
+void omap_vp_disable(struct voltagedomain *voltdm);
+int omap_vp_forceupdate_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt);
+int omap_vp_update_errorgain(struct voltagedomain *voltdm,
+ unsigned long target_volt);
+
+#endif
diff --git a/arch/arm/mach-omap2/vp3xxx_data.c b/arch/arm/mach-omap2/vp3xxx_data.c
new file mode 100644
index 000000000..b0590fe6a
--- /dev/null
+++ b/arch/arm/mach-omap2/vp3xxx_data.c
@@ -0,0 +1,89 @@
+/*
+ * 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 "common.h"
+
+#include "prm-regbits-34xx.h"
+#include "voltage.h"
+
+#include "vp.h"
+#include "prm2xxx_3xxx.h"
+
+static const struct omap_vp_ops omap3_vp_ops = {
+ .check_txdone = omap_prm_vp_check_txdone,
+ .clear_txdone = omap_prm_vp_clear_txdone,
+};
+
+/*
+ * 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 omap3_vp_common = {
+ .vpconfig_erroroffset_mask = OMAP3430_ERROROFFSET_MASK,
+ .vpconfig_errorgain_mask = OMAP3430_ERRORGAIN_MASK,
+ .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,
+ .vpvoltage_mask = OMAP3430_VPVOLTAGE_MASK,
+
+ .ops = &omap3_vp_ops,
+};
+
+struct omap_vp_instance omap3_vp_mpu = {
+ .id = OMAP3_VP_VDD_MPU_ID,
+ .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,
+};
+
+struct omap_vp_instance omap3_vp_core = {
+ .id = OMAP3_VP_VDD_CORE_ID,
+ .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,
+};
+
+struct omap_vp_param omap3_mpu_vp_data = {
+ .vddmin = OMAP3430_VP1_VLIMITTO_VDDMIN,
+ .vddmax = OMAP3430_VP1_VLIMITTO_VDDMAX,
+};
+
+struct omap_vp_param omap3_core_vp_data = {
+ .vddmin = OMAP3430_VP2_VLIMITTO_VDDMIN,
+ .vddmax = OMAP3430_VP2_VLIMITTO_VDDMAX,
+};
diff --git a/arch/arm/mach-omap2/vp44xx_data.c b/arch/arm/mach-omap2/vp44xx_data.c
new file mode 100644
index 000000000..2448bb9a8
--- /dev/null
+++ b/arch/arm/mach-omap2/vp44xx_data.c
@@ -0,0 +1,104 @@
+/*
+ * 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 "common.h"
+
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
+#include "voltage.h"
+
+#include "vp.h"
+
+static const struct omap_vp_ops omap4_vp_ops = {
+ .check_txdone = omap_prm_vp_check_txdone,
+ .clear_txdone = omap_prm_vp_clear_txdone,
+};
+
+/*
+ * 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 omap4_vp_common = {
+ .vpconfig_erroroffset_mask = OMAP4430_ERROROFFSET_MASK,
+ .vpconfig_errorgain_mask = OMAP4430_ERRORGAIN_MASK,
+ .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,
+ .vpvoltage_mask = OMAP4430_VPVOLTAGE_MASK,
+ .ops = &omap4_vp_ops,
+};
+
+struct omap_vp_instance omap4_vp_mpu = {
+ .id = OMAP4_VP_VDD_MPU_ID,
+ .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,
+};
+
+struct omap_vp_instance omap4_vp_iva = {
+ .id = OMAP4_VP_VDD_IVA_ID,
+ .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,
+};
+
+struct omap_vp_instance omap4_vp_core = {
+ .id = OMAP4_VP_VDD_CORE_ID,
+ .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,
+};
+
+struct omap_vp_param omap4_mpu_vp_data = {
+ .vddmin = OMAP4_VP_MPU_VLIMITTO_VDDMIN,
+ .vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX,
+};
+
+struct omap_vp_param omap4_iva_vp_data = {
+ .vddmin = OMAP4_VP_IVA_VLIMITTO_VDDMIN,
+ .vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX,
+};
+
+struct omap_vp_param omap4_core_vp_data = {
+ .vddmin = OMAP4_VP_CORE_VLIMITTO_VDDMIN,
+ .vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX,
+};
diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c
new file mode 100644
index 000000000..ff0a68cf7
--- /dev/null
+++ b/arch/arm/mach-omap2/wd_timer.c
@@ -0,0 +1,132 @@
+/*
+ * OMAP2+ MPU WD_TIMER-specific code
+ *
+ * Copyright (C) 2012 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/err.h>
+
+#include <linux/platform_data/omap-wd-timer.h>
+
+#include "omap_hwmod.h"
+#include "omap_device.h"
+#include "wd_timer.h"
+#include "common.h"
+#include "prm.h"
+#include "soc.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 */
+ writel_relaxed(0xAAAA, base + OMAP_WDT_SPR);
+ while (readl_relaxed(base + OMAP_WDT_WPS) & 0x10)
+ cpu_relax();
+
+ writel_relaxed(0x5555, base + OMAP_WDT_SPR);
+ while (readl_relaxed(base + OMAP_WDT_WPS) & 0x10)
+ cpu_relax();
+
+ return 0;
+}
+
+/**
+ * omap2_wdtimer_reset - reset and disable the WDTIMER IP block
+ * @oh: struct omap_hwmod *
+ *
+ * After the WDTIMER IP blocks are reset on OMAP2/3, we must also take
+ * care to execute the special watchdog disable sequence. This is
+ * because the watchdog is re-armed upon OCP softreset. (On OMAP4,
+ * this behavior was apparently changed and the watchdog is no longer
+ * re-armed after an OCP soft-reset.) Returns -ETIMEDOUT if the reset
+ * did not complete, or 0 upon success.
+ *
+ * XXX Most of this code should be moved to the omap_hwmod.c layer
+ * during a normal merge window. omap_hwmod_softreset() should be
+ * renamed to omap_hwmod_set_ocp_softreset(), and omap_hwmod_softreset()
+ * should call the hwmod _ocp_softreset() code.
+ */
+int omap2_wd_timer_reset(struct omap_hwmod *oh)
+{
+ int c = 0;
+
+ /* Write to the SOFTRESET bit */
+ omap_hwmod_softreset(oh);
+
+ /* Poll on RESETDONE bit */
+ omap_test_timeout((omap_hwmod_read(oh,
+ oh->class->sysc->syss_offs)
+ & SYSS_RESETDONE_MASK),
+ MAX_MODULE_SOFTRESET_WAIT, c);
+
+ if (oh->class->sysc->srst_udelay)
+ udelay(oh->class->sysc->srst_udelay);
+
+ if (c == MAX_MODULE_SOFTRESET_WAIT)
+ pr_warn("%s: %s: softreset failed (waited %d usec)\n",
+ __func__, oh->name, MAX_MODULE_SOFTRESET_WAIT);
+ else
+ pr_debug("%s: %s: softreset in %d usec\n", __func__,
+ oh->name, c);
+
+ return (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT :
+ omap2_wd_timer_disable(oh);
+}
+
+static int __init omap_init_wdt(void)
+{
+ int id = -1;
+ struct platform_device *pdev;
+ struct omap_hwmod *oh;
+ char *oh_name = "wd_timer2";
+ char *dev_name = "omap_wdt";
+ struct omap_wd_timer_platform_data pdata;
+
+ if (!cpu_class_is_omap2() || of_have_populated_dt())
+ return 0;
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("Could not look up wd_timer%d hwmod\n", id);
+ return -EINVAL;
+ }
+
+ pdata.read_reset_sources = prm_read_reset_sources;
+
+ pdev = omap_device_build(dev_name, id, oh, &pdata,
+ sizeof(struct omap_wd_timer_platform_data));
+ WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",
+ dev_name, oh->name);
+ return 0;
+}
+omap_subsys_initcall(omap_init_wdt);
diff --git a/arch/arm/mach-omap2/wd_timer.h b/arch/arm/mach-omap2/wd_timer.h
new file mode 100644
index 000000000..a78f81034
--- /dev/null
+++ b/arch/arm/mach-omap2/wd_timer.h
@@ -0,0 +1,18 @@
+/*
+ * 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 "omap_hwmod.h"
+
+extern int omap2_wd_timer_disable(struct omap_hwmod *oh);
+extern int omap2_wd_timer_reset(struct omap_hwmod *oh);
+
+#endif
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
new file mode 100644
index 000000000..2412efb6c
--- /dev/null
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -0,0 +1,165 @@
+if ARCH_ORION5X
+
+menu "Orion Implementations"
+
+config ARCH_ORION5X_DT
+ bool "Marvell Orion5x Flattened Device Tree"
+ select USE_OF
+ select ORION_CLK
+ select ORION_IRQCHIP
+ select ORION_TIMER
+ select PINCTRL
+ select PINCTRL_ORION
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell Orion5x using flattened device tree.
+
+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_RD88F5182_DT
+ bool "Marvell Orion-NAS Reference Design (Flattened Device Tree)"
+ select ARCH_ORION5X_DT
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the Marvell
+ Orion-NAS (88F5182) RD2, Flattened Device Tree.
+
+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
+ 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"
+ 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_D2NET_DT
+ bool "LaCie d2 Network / Big Disk Network (Flattened Device Tree)"
+ select ARCH_ORION5X_DT
+ help
+ Say 'Y' here if you want your kernel to support the
+ LaCie d2 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_DT
+ bool "Maxtor Shared Storage II (Flattened Device Tree)"
+ select ARCH_ORION5X_DT
+ 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 000000000..a40b5c9a5
--- /dev/null
+++ b/arch/arm/mach-orion5x/Makefile
@@ -0,0 +1,25 @@
+obj-y += common.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_NET2BIG) += net2big-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
+
+obj-$(CONFIG_ARCH_ORION5X_DT) += board-dt.o
+obj-$(CONFIG_MACH_D2NET_DT) += board-d2net.o
+obj-$(CONFIG_MACH_MSS2_DT) += board-mss2.o
+obj-$(CONFIG_MACH_RD88F5182_DT) += board-rd88f5182.o
diff --git a/arch/arm/mach-orion5x/Makefile.boot b/arch/arm/mach-orion5x/Makefile.boot
new file mode 100644
index 000000000..760a0efe7
--- /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/board-d2net.c b/arch/arm/mach-orion5x/board-d2net.c
new file mode 100644
index 000000000..8a7284124
--- /dev/null
+++ b/arch/arm/mach-orion5x/board-d2net.c
@@ -0,0 +1,109 @@
+/*
+ * arch/arm/mach-orion5x/board-d2net.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/leds.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 <plat/orion-gpio.h>
+#include "common.h"
+
+/*****************************************************************************
+ * LaCie d2 Network Info
+ ****************************************************************************/
+
+/*****************************************************************************
+ * 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 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);
+}
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+void __init d2net_init(void)
+{
+ d2net_gpio_leds_init();
+
+ pr_notice("d2net: Flash write are not yet supported.\n");
+}
diff --git a/arch/arm/mach-orion5x/board-dt.c b/arch/arm/mach-orion5x/board-dt.c
new file mode 100644
index 000000000..79f033b1d
--- /dev/null
+++ b/arch/arm/mach-orion5x/board-dt.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2012 (C), Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * arch/arm/mach-orion5x/board-dt.c
+ *
+ * Flattened Device Tree board initialization
+ *
+ * This file is licensed under the terms 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/of.h>
+#include <linux/of_platform.h>
+#include <linux/cpu.h>
+#include <linux/mbus.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <asm/system_misc.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/orion5x.h>
+#include <mach/bridge-regs.h>
+#include <plat/irq.h>
+#include <plat/time.h>
+#include "common.h"
+
+static struct of_dev_auxdata orion5x_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL),
+ OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0",
+ NULL),
+ OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL),
+ OF_DEV_AUXDATA("marvell,orion-sata", 0xf1080000, "sata_mv.0", NULL),
+ OF_DEV_AUXDATA("marvell,orion-crypto", 0xf1090000, "mv_crypto", NULL),
+ {},
+};
+
+static void __init orion5x_dt_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);
+
+ BUG_ON(mvebu_mbus_dt_init(false));
+
+ /*
+ * Setup Orion address map
+ */
+ orion5x_setup_wins();
+
+ /*
+ * 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");
+ cpu_idle_poll_ctrl(true);
+ }
+
+ if (of_machine_is_compatible("maxtor,shared-storage-2"))
+ mss2_init();
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ orion5x_auxdata_lookup, NULL);
+}
+
+static const char *orion5x_dt_compat[] = {
+ "marvell,orion5x",
+ NULL,
+};
+
+DT_MACHINE_START(ORION5X_DT, "Marvell Orion5x (Flattened Device Tree)")
+ /* Maintainer: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> */
+ .map_io = orion5x_map_io,
+ .init_machine = orion5x_dt_init,
+ .restart = orion5x_restart,
+ .dt_compat = orion5x_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/board-mss2.c b/arch/arm/mach-orion5x/board-mss2.c
new file mode 100644
index 000000000..66f9c3ba8
--- /dev/null
+++ b/arch/arm/mach-orion5x/board-mss2.c
@@ -0,0 +1,90 @@
+/*
+ * 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 <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"
+
+/*****************************************************************************
+ * Maxtor Shared Storage II Info
+ ****************************************************************************/
+
+/****************************************************************************
+ * PCI setup
+ ****************************************************************************/
+static int __init mss2_pci_map_irq(const 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,
+ .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);
+
+/*****************************************************************************
+ * 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);
+}
+
+void __init mss2_init(void)
+{
+ /* register mss2 specific power-off method */
+ pm_power_off = mss2_power_off;
+}
diff --git a/arch/arm/mach-orion5x/board-rd88f5182.c b/arch/arm/mach-orion5x/board-rd88f5182.c
new file mode 100644
index 000000000..270824b0e
--- /dev/null
+++ b/arch/arm/mach-orion5x/board-rd88f5182.c
@@ -0,0 +1,116 @@
+/*
+ * 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/gpio.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+
+/*****************************************************************************
+ * RD-88F5182 Info
+ ****************************************************************************/
+
+/*
+ * PCI
+ */
+
+#define RD88F5182_PCI_SLOT0_OFFS 7
+#define RD88F5182_PCI_SLOT0_IRQ_A_PIN 7
+#define RD88F5182_PCI_SLOT0_IRQ_B_PIN 6
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+
+static 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 failed 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 failed 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(const 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,
+ .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 (of_machine_is_compatible("marvell,rd-88f5182-nas"))
+ pci_common_init(&rd88f5182_pci);
+
+ return 0;
+}
+
+subsys_initcall(rd88f5182_pci_init);
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
new file mode 100644
index 000000000..6bbb7b55c
--- /dev/null
+++ b/arch/arm/mach-orion5x/common.c
@@ -0,0 +1,379 @@
+/*
+ * 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/mv643xx_i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/delay.h>
+#include <linux/clk-provider.h>
+#include <linux/cpu.h>
+#include <net/dsa.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/system_misc.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 <linux/platform_data/mtd-orion_nand.h>
+#include <linux/platform_data/usb-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 = (unsigned long) ORION5X_REGS_VIRT_BASE,
+ .pfn = __phys_to_pfn(ORION5X_REGS_PHYS_BASE),
+ .length = ORION5X_REGS_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long) 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));
+}
+
+
+/*****************************************************************************
+ * CLK tree
+ ****************************************************************************/
+static struct clk *tclk;
+
+void __init clk_init(void)
+{
+ tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT,
+ orion5x_tclk);
+
+ orion_clkdev_init(tclk);
+}
+
+/*****************************************************************************
+ * EHCI0
+ ****************************************************************************/
+void __init orion5x_ehci0_init(void)
+{
+ orion_ehci_init(ORION5X_USB0_PHYS_BASE, IRQ_ORION5X_USB0_CTRL,
+ EHCI_PHY_ORION);
+}
+
+
+/*****************************************************************************
+ * EHCI1
+ ****************************************************************************/
+void __init orion5x_ehci1_init(void)
+{
+ orion_ehci_1_init(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_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM,
+ IRQ_ORION5X_ETH_ERR,
+ MV643XX_TX_CSUM_DEFAULT_LIMIT);
+}
+
+
+/*****************************************************************************
+ * 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_SATA_PHYS_BASE, IRQ_ORION5X_SATA);
+}
+
+
+/*****************************************************************************
+ * SPI
+ ****************************************************************************/
+void __init orion5x_spi_init(void)
+{
+ orion_spi_init(SPI_PHYS_BASE);
+}
+
+
+/*****************************************************************************
+ * UART0
+ ****************************************************************************/
+void __init orion5x_uart0_init(void)
+{
+ orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
+ IRQ_ORION5X_UART0, tclk);
+}
+
+/*****************************************************************************
+ * UART1
+ ****************************************************************************/
+void __init orion5x_uart1_init(void)
+{
+ orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
+ IRQ_ORION5X_UART1, tclk);
+}
+
+/*****************************************************************************
+ * XOR engine
+ ****************************************************************************/
+void __init orion5x_xor_init(void)
+{
+ orion_xor0_init(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)
+{
+ mvebu_mbus_add_window_by_id(ORION_MBUS_SRAM_TARGET,
+ ORION_MBUS_SRAM_ATTR,
+ ORION5X_SRAM_PHYS_BASE,
+ ORION5X_SRAM_SIZE);
+ orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE,
+ SZ_8K, IRQ_ORION5X_CESA);
+}
+
+/*****************************************************************************
+ * Watchdog
+ ****************************************************************************/
+static void __init orion5x_wdt_init(void)
+{
+ orion_wdt_init();
+}
+
+
+/*****************************************************************************
+ * Time handling
+ ****************************************************************************/
+void __init orion5x_init_early(void)
+{
+ u32 rev, dev;
+ const char *mbus_soc_name;
+
+ orion_time_set_base(TIMER_VIRT_BASE);
+
+ /* Initialize the MBUS driver */
+ orion5x_pcie_id(&dev, &rev);
+ if (dev == MV88F5281_DEV_ID)
+ mbus_soc_name = "marvell,orion5x-88f5281-mbus";
+ else if (dev == MV88F5182_DEV_ID)
+ mbus_soc_name = "marvell,orion5x-88f5182-mbus";
+ else if (dev == MV88F5181_DEV_ID)
+ mbus_soc_name = "marvell,orion5x-88f5181-mbus";
+ else if (dev == MV88F6183_DEV_ID)
+ mbus_soc_name = "marvell,orion5x-88f6183-mbus";
+ else
+ mbus_soc_name = NULL;
+ mvebu_mbus_init(mbus_soc_name, ORION5X_BRIDGE_WINS_BASE,
+ ORION5X_BRIDGE_WINS_SZ,
+ ORION5X_DDR_WINS_BASE, ORION5X_DDR_WINS_SZ);
+}
+
+void orion5x_setup_wins(void)
+{
+ /*
+ * The PCIe windows will no longer be statically allocated
+ * here once Orion5x is migrated to the pci-mvebu driver.
+ */
+ mvebu_mbus_add_window_remap_by_id(ORION_MBUS_PCIE_IO_TARGET,
+ ORION_MBUS_PCIE_IO_ATTR,
+ ORION5X_PCIE_IO_PHYS_BASE,
+ ORION5X_PCIE_IO_SIZE,
+ ORION5X_PCIE_IO_BUS_BASE);
+ mvebu_mbus_add_window_by_id(ORION_MBUS_PCIE_MEM_TARGET,
+ ORION_MBUS_PCIE_MEM_ATTR,
+ ORION5X_PCIE_MEM_PHYS_BASE,
+ ORION5X_PCIE_MEM_SIZE);
+ mvebu_mbus_add_window_remap_by_id(ORION_MBUS_PCI_IO_TARGET,
+ ORION_MBUS_PCI_IO_ATTR,
+ ORION5X_PCI_IO_PHYS_BASE,
+ ORION5X_PCI_IO_SIZE,
+ ORION5X_PCI_IO_BUS_BASE);
+ mvebu_mbus_add_window_by_id(ORION_MBUS_PCI_MEM_TARGET,
+ ORION_MBUS_PCI_MEM_ATTR,
+ ORION5X_PCI_MEM_PHYS_BASE,
+ ORION5X_PCI_MEM_SIZE);
+}
+
+int orion5x_tclk;
+
+static 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;
+}
+
+void __init 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);
+}
+
+
+/*****************************************************************************
+ * General
+ ****************************************************************************/
+/*
+ * Identify device ID and rev from PCIe configuration header space '0'.
+ */
+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_wins();
+
+ /* Setup root of clk tree */
+ clk_init();
+
+ /*
+ * 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");
+ cpu_idle_poll_ctrl(true);
+ }
+
+ /*
+ * 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();
+}
+
+void orion5x_restart(enum reboot_mode 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);
+}
+
+/*
+ * Many orion-based systems have buggy bootloader implementations.
+ * This is a common fixup for bogus memory tags.
+ */
+void __init tag_fixup_mem32(struct tag *t, char **from)
+{
+ 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 000000000..cd0389c6e
--- /dev/null
+++ b/arch/arm/mach-orion5x/common.h
@@ -0,0 +1,86 @@
+#ifndef __ARCH_ORION5X_COMMON_H
+#define __ARCH_ORION5X_COMMON_H
+
+#include <linux/reboot.h>
+
+struct dsa_platform_data;
+struct mv643xx_eth_platform_data;
+struct mv_sata_platform_data;
+
+#define ORION_MBUS_PCIE_MEM_TARGET 0x04
+#define ORION_MBUS_PCIE_MEM_ATTR 0x59
+#define ORION_MBUS_PCIE_IO_TARGET 0x04
+#define ORION_MBUS_PCIE_IO_ATTR 0x51
+#define ORION_MBUS_PCIE_WA_TARGET 0x04
+#define ORION_MBUS_PCIE_WA_ATTR 0x79
+#define ORION_MBUS_PCI_MEM_TARGET 0x03
+#define ORION_MBUS_PCI_MEM_ATTR 0x59
+#define ORION_MBUS_PCI_IO_TARGET 0x03
+#define ORION_MBUS_PCI_IO_ATTR 0x51
+#define ORION_MBUS_DEVBUS_BOOT_TARGET 0x01
+#define ORION_MBUS_DEVBUS_BOOT_ATTR 0x0f
+#define ORION_MBUS_DEVBUS_TARGET(cs) 0x01
+#define ORION_MBUS_DEVBUS_ATTR(cs) (~(1 << cs))
+#define ORION_MBUS_SRAM_TARGET 0x09
+#define ORION_MBUS_SRAM_ATTR 0x00
+
+/*
+ * 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);
+void orion5x_id(u32 *dev, u32 *rev, char **dev_name);
+void clk_init(void);
+extern int orion5x_tclk;
+extern void orion5x_timer_init(void);
+
+void orion5x_setup_wins(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);
+void orion5x_restart(enum reboot_mode, const char *);
+
+/*
+ * PCIe/PCI functions.
+ */
+struct pci_bus;
+struct pci_sys_data;
+struct pci_dev;
+
+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(const struct pci_dev *dev, u8 slot, u8 pin);
+
+struct tag;
+extern void __init tag_fixup_mem32(struct tag *, char **);
+
+#ifdef CONFIG_MACH_MSS2_DT
+extern void mss2_init(void);
+#else
+static inline void mss2_init(void) {}
+#endif
+
+/*****************************************************************************
+ * 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/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c
new file mode 100644
index 000000000..dc01c4ffc
--- /dev/null
+++ b/arch/arm/mach-orion5x/db88f5281-setup.c
@@ -0,0 +1,378 @@
+/*
+ * 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/gpio.h>
+#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/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include <linux/platform_data/mtd-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
+ ****************************************************************************/
+
+static 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 failed 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 failed "
+ "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(const 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,
+ .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();
+
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
+ ORION_MBUS_DEVBUS_BOOT_ATTR,
+ DB88F5281_NOR_BOOT_BASE,
+ DB88F5281_NOR_BOOT_SIZE);
+ platform_device_register(&db88f5281_boot_flash);
+
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_TARGET(0),
+ ORION_MBUS_DEVBUS_ATTR(0),
+ DB88F5281_7SEG_BASE,
+ DB88F5281_7SEG_SIZE);
+
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_TARGET(1),
+ ORION_MBUS_DEVBUS_ATTR(1),
+ DB88F5281_NOR_BASE,
+ DB88F5281_NOR_SIZE);
+ platform_device_register(&db88f5281_nor_flash);
+
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_TARGET(2),
+ ORION_MBUS_DEVBUS_ATTR(2),
+ 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> */
+ .atag_offset = 0x100,
+ .init_machine = db88f5281_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .restart = orion5x_restart,
+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 000000000..09d2a2698
--- /dev/null
+++ b/arch/arm/mach-orion5x/dns323-setup.c
@@ -0,0 +1,725 @@
+/*
+ * 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/gpio.h>
+#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/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <asm/system_info.h>
+#include <mach/orion5x.h>
+#include <plat/orion-gpio.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(const 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,
+ .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)
+ */
+
+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 = orion_gpio_led_blink_set,
+};
+
+static struct gpio_led_platform_data dns323c_led_data = {
+ .num_leds = ARRAY_SIZE(dns323c_leds),
+ .leds = dns323c_leds,
+ .gpio_blink_set = orion_gpio_led_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_warn("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_warn("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_warn("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
+ */
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
+ ORION_MBUS_DEVBUS_BOOT_ATTR,
+ 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 */
+ if (!IS_BUILTIN(CONFIG_PHYLIB))
+ break;
+ 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> */
+ .atag_offset = 0x100,
+ .init_machine = dns323_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .fixup = tag_fixup_mem32,
+ .restart = orion5x_restart,
+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 000000000..5766e3fbf
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/bridge-regs.h
@@ -0,0 +1,37 @@
+/*
+ * 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 RSTOUTn_MASK_PHYS (ORION5X_BRIDGE_PHYS_BASE + 0x108)
+
+#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 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)
+#define TIMER_PHYS_BASE (ORION5X_BRIDGE_PHYS_BASE + 0x300)
+#endif
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 000000000..79eb502a1
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/entry-macro.S
@@ -0,0 +1,25 @@
+/*
+ * 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 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/hardware.h b/arch/arm/mach-orion5x/include/mach/hardware.h
new file mode 100644
index 000000000..395735482
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/hardware.h
@@ -0,0 +1,14 @@
+/*
+ * 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"
+
+#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 000000000..a6fa9d8f1
--- /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/orion5x.h b/arch/arm/mach-orion5x/include/mach/orion5x.h
new file mode 100644
index 000000000..b78ff3248
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/orion5x.h
@@ -0,0 +1,146 @@
+/*
+ * 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
+ * fe000000 f1000000 1M on-chip peripheral registers
+ * fee00000 f2000000 64K PCIe I/O space
+ * fee10000 f2100000 64K PCI I/O space
+ * fd000000 f0000000 16M PCIe WA space (Orion-1/Orion-NAS only)
+ ****************************************************************************/
+#define ORION5X_REGS_PHYS_BASE 0xf1000000
+#define ORION5X_REGS_VIRT_BASE IOMEM(0xfe000000)
+#define ORION5X_REGS_SIZE SZ_1M
+
+#define ORION5X_PCIE_IO_PHYS_BASE 0xf2000000
+#define ORION5X_PCIE_IO_BUS_BASE 0x00000000
+#define ORION5X_PCIE_IO_SIZE SZ_64K
+
+#define ORION5X_PCI_IO_PHYS_BASE 0xf2100000
+#define ORION5X_PCI_IO_BUS_BASE 0x00010000
+#define ORION5X_PCI_IO_SIZE SZ_64K
+
+#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 IOMEM(0xfd000000)
+#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_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x00000)
+#define ORION5X_DDR_WINS_BASE (ORION5X_DDR_PHYS_BASE + 0x1500)
+#define ORION5X_DDR_WINS_SZ (0x10)
+#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_BRIDGE_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x20000)
+#define ORION5X_BRIDGE_WINS_BASE (ORION5X_BRIDGE_PHYS_BASE)
+#define ORION5X_BRIDGE_WINS_SZ (0x80)
+
+#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/uncompress.h b/arch/arm/mach-orion5x/include/mach/uncompress.h
new file mode 100644
index 000000000..abd26b542
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/uncompress.h
@@ -0,0 +1,48 @@
+/*
+ * 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()
diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c
new file mode 100644
index 000000000..cd4bac4d7
--- /dev/null
+++ b/arch/arm/mach-orion5x/irq.c
@@ -0,0 +1,65 @@
+/*
+ * 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/gpio.h>
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/bridge-regs.h>
+#include <plat/orion-gpio.h>
+#include <plat/irq.h>
+#include <asm/exception.h>
+#include "common.h"
+
+static int __initdata gpio0_irqs[4] = {
+ IRQ_ORION5X_GPIO_0_7,
+ IRQ_ORION5X_GPIO_8_15,
+ IRQ_ORION5X_GPIO_16_23,
+ IRQ_ORION5X_GPIO_24_31,
+};
+
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+/*
+ * Compiling with both non-DT and DT support enabled, will
+ * break asm irq handler used by non-DT boards. Therefore,
+ * we provide a C-style irq handler even for non-DT boards,
+ * if MULTI_IRQ_HANDLER is set.
+ */
+
+asmlinkage void
+__exception_irq_entry orion5x_legacy_handle_irq(struct pt_regs *regs)
+{
+ u32 stat;
+
+ stat = readl_relaxed(MAIN_IRQ_CAUSE);
+ stat &= readl_relaxed(MAIN_IRQ_MASK);
+ if (stat) {
+ unsigned int hwirq = __fls(stat);
+ handle_IRQ(hwirq, regs);
+ return;
+ }
+}
+#endif
+
+void __init orion5x_init_irq(void)
+{
+ orion_irq_init(0, MAIN_IRQ_MASK);
+
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+ set_handle_irq(orion5x_legacy_handle_irq);
+#endif
+
+ /*
+ * Initialize gpiolib for GPIOs 0-31.
+ */
+ orion_gpio_init(NULL, 0, 32, GPIO_VIRT_BASE, 0,
+ IRQ_ORION5X_GPIO_START, gpio0_irqs);
+}
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 000000000..fe6a48a32
--- /dev/null
+++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c
@@ -0,0 +1,408 @@
+/*
+ * 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/gpio.h>
+#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/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include <linux/platform_data/mtd-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(const 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,
+ .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();
+
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
+ ORION_MBUS_DEVBUS_BOOT_ATTR,
+ KUROBOX_PRO_NOR_BOOT_BASE,
+ KUROBOX_PRO_NOR_BOOT_SIZE);
+ platform_device_register(&kurobox_pro_nor_flash);
+
+ if (machine_is_kurobox_pro()) {
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_TARGET(0),
+ ORION_MBUS_DEVBUS_ATTR(0),
+ 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> */
+ .atag_offset = 0x100,
+ .init_machine = kurobox_pro_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .fixup = tag_fixup_mem32,
+ .restart = orion5x_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_LINKSTATION_PRO
+MACHINE_START(LINKSTATION_PRO, "Buffalo Linkstation Pro/Live")
+ /* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */
+ .atag_offset = 0x100,
+ .init_machine = kurobox_pro_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .fixup = tag_fixup_mem32,
+ .restart = orion5x_restart,
+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 000000000..028ea038d
--- /dev/null
+++ b/arch/arm/mach-orion5x/ls-chl-setup.c
@@ -0,0 +1,330 @@
+/*
+ * 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 <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)
+{
+ orion5x_restart(REBOOT_HARD, 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();
+
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
+ ORION_MBUS_DEVBUS_BOOT_ATTR,
+ 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> */
+ .atag_offset = 0x100,
+ .init_machine = lschl_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .fixup = tag_fixup_mem32,
+ .restart = orion5x_restart,
+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 000000000..32b7129b7
--- /dev/null
+++ b/arch/arm/mach-orion5x/ls_hgl-setup.c
@@ -0,0 +1,277 @@
+/*
+ * 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 <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)
+{
+ orion5x_restart(REBOOT_HARD, 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();
+
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
+ ORION_MBUS_DEVBUS_BOOT_ATTR,
+ 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> */
+ .atag_offset = 0x100,
+ .init_machine = ls_hgl_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .fixup = tag_fixup_mem32,
+ .restart = orion5x_restart,
+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 000000000..a6493e76f
--- /dev/null
+++ b/arch/arm/mach-orion5x/lsmini-setup.c
@@ -0,0 +1,280 @@
+/*
+ * 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 <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)
+{
+ orion5x_restart(REBOOT_HARD, 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();
+
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
+ ORION_MBUS_DEVBUS_BOOT_ATTR,
+ 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> */
+ .atag_offset = 0x100,
+ .init_machine = lsmini_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .fixup = tag_fixup_mem32,
+ .restart = orion5x_restart,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-orion5x/mpp.c b/arch/arm/mach-orion5x/mpp.c
new file mode 100644
index 000000000..5b70026f4
--- /dev/null
+++ b/arch/arm/mach-orion5x/mpp.c
@@ -0,0 +1,44 @@
+/*
+ * 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/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)
+ 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 000000000..db70e79a1
--- /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/mv2120-setup.c b/arch/arm/mach-orion5x/mv2120-setup.c
new file mode 100644
index 000000000..e032f01da
--- /dev/null
+++ b/arch/arm/mach-orion5x/mv2120-setup.c
@@ -0,0 +1,242 @@
+/*
+ * 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/gpio.h>
+#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/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();
+
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
+ ORION_MBUS_DEVBUS_BOOT_ATTR,
+ 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> */
+ .atag_offset = 0x100,
+ .init_machine = mv2120_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .fixup = tag_fixup_mem32,
+ .restart = orion5x_restart,
+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 000000000..ba73dc7ff
--- /dev/null
+++ b/arch/arm/mach-orion5x/net2big-setup.c
@@ -0,0 +1,434 @@
+/*
+ * 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 <plat/orion-gpio.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);
+
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
+ ORION_MBUS_DEVBUS_BOOT_ATTR,
+ 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")
+ .atag_offset = 0x100,
+ .init_machine = net2big_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .fixup = tag_fixup_mem32,
+ .restart = orion5x_restart,
+MACHINE_END
+
diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c
new file mode 100644
index 000000000..b02f3947b
--- /dev/null
+++ b/arch/arm/mach-orion5x/pci.c
@@ -0,0 +1,583 @@
+/*
+ * 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 <video/vga.h>
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <plat/pcie.h>
+#include <plat/addr-map.h>
+#include <mach/orion5x.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 (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(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);
+
+ /*
+ * 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");
+ mvebu_mbus_add_window_by_id(ORION_MBUS_PCIE_WA_TARGET,
+ ORION_MBUS_PCIE_WA_ATTR,
+ ORION5X_PCIE_WA_PHYS_BASE,
+ ORION5X_PCIE_WA_SIZE);
+ pcie_ops.read = pcie_rd_conf_wa;
+ }
+
+ pci_ioremap_io(sys->busnr * SZ_64K, ORION5X_PCIE_IO_PHYS_BASE);
+
+ /*
+ * Request resources.
+ */
+ res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+ if (!res)
+ panic("pcie_setup unable to alloc resources");
+
+ /*
+ * IORESOURCE_MEM
+ */
+ res->name = "PCIe Memory Space";
+ res->flags = IORESOURCE_MEM;
+ res->start = ORION5X_PCIE_MEM_PHYS_BASE;
+ res->end = res->start + ORION5X_PCIE_MEM_SIZE - 1;
+ if (request_resource(&iomem_resource, res))
+ panic("Request PCIe Memory resource failed\n");
+ pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
+
+ 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) : NULL)
+#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) : NULL)
+#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(void)
+{
+ const struct mbus_dram_target_info *dram = mv_mbus_dram_info();
+ 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++) {
+ const 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();
+
+ /*
+ * Master + Slave enable
+ */
+ orion5x_pci_master_slave_enable();
+
+ /*
+ * Force ordering
+ */
+ orion5x_setbits(PCI_CMD, PCI_CMD_HOST_REORDER);
+
+ pci_ioremap_io(sys->busnr * SZ_64K, ORION5X_PCI_IO_PHYS_BASE);
+
+ /*
+ * Request resources
+ */
+ res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+ if (!res)
+ panic("pci_setup unable to alloc resources");
+
+ /*
+ * IORESOURCE_MEM
+ */
+ res->name = "PCI Memory Space";
+ res->flags = IORESOURCE_MEM;
+ res->start = ORION5X_PCI_MEM_PHYS_BASE;
+ res->end = res->start + ORION5X_PCI_MEM_SIZE - 1;
+ if (request_resource(&iomem_resource, res))
+ panic("Request PCI Memory resource failed\n");
+ pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
+
+ return 1;
+}
+
+
+/*****************************************************************************
+ * General PCIe + PCI
+ ****************************************************************************/
+static void 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)
+{
+ vga_base = ORION5X_PCIE_MEM_PHYS_BASE;
+
+ if (nr == 0) {
+ orion_pcie_set_local_bus_nr(PCIE_BASE, sys->busnr);
+ return pcie_setup(sys);
+ }
+
+ if (nr == 1 && !orion5x_pci_disabled) {
+ orion5x_pci_set_bus_nr(sys->busnr);
+ return pci_setup(sys);
+ }
+
+ return 0;
+}
+
+struct pci_bus __init *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ if (nr == 0)
+ return pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys,
+ &sys->resources);
+
+ if (nr == 1 && !orion5x_pci_disabled)
+ return pci_scan_root_bus(NULL, sys->busnr, &pci_ops, sys,
+ &sys->resources);
+
+ BUG();
+ return NULL;
+}
+
+int __init orion5x_pci_map_irq(const 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 000000000..213b3e143
--- /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/gpio.h>
+#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/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();
+
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
+ ORION_MBUS_DEVBUS_BOOT_ATTR,
+ 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(const 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,
+ .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> */
+ .atag_offset = 0x100,
+ .init_machine = rd88f5181l_fxo_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .fixup = tag_fixup_mem32,
+ .restart = orion5x_restart,
+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 000000000..594800e1d
--- /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/gpio.h>
+#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/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();
+
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
+ ORION_MBUS_DEVBUS_BOOT_ATTR,
+ 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(const 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,
+ .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> */
+ .atag_offset = 0x100,
+ .init_machine = rd88f5181l_ge_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .fixup = tag_fixup_mem32,
+ .restart = orion5x_restart,
+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 000000000..b576ef5f1
--- /dev/null
+++ b/arch/arm/mach-orion5x/rd88f5182-setup.c
@@ -0,0 +1,290 @@
+/*
+ * 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/gpio.h>
+#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 <linux/leds.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"
+
+/*****************************************************************************
+ * 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
+
+/*****************************************************************************
+ * 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,
+};
+
+/*****************************************************************************
+ * Use GPIO LED as CPU active indication
+ ****************************************************************************/
+
+#define RD88F5182_GPIO_LED 0
+
+static struct gpio_led rd88f5182_gpio_led_pins[] = {
+ {
+ .name = "rd88f5182:cpu",
+ .default_trigger = "cpu0",
+ .gpio = RD88F5182_GPIO_LED,
+ },
+};
+
+static struct gpio_led_platform_data rd88f5182_gpio_led_data = {
+ .leds = rd88f5182_gpio_led_pins,
+ .num_leds = ARRAY_SIZE(rd88f5182_gpio_led_pins),
+};
+
+static struct platform_device rd88f5182_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &rd88f5182_gpio_led_data,
+ },
+};
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+
+static 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 failed 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 failed 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(const 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,
+ .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();
+
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
+ ORION_MBUS_DEVBUS_BOOT_ATTR,
+ RD88F5182_NOR_BOOT_BASE,
+ RD88F5182_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_TARGET(1),
+ ORION_MBUS_DEVBUS_ATTR(1),
+ RD88F5182_NOR_BASE,
+ RD88F5182_NOR_SIZE);
+ platform_device_register(&rd88f5182_nor_flash);
+ platform_device_register(&rd88f5182_gpio_leds);
+
+ i2c_register_board_info(0, &rd88f5182_i2c_rtc, 1);
+}
+
+MACHINE_START(RD88F5182, "Marvell Orion-NAS Reference Design")
+ /* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
+ .atag_offset = 0x100,
+ .init_machine = rd88f5182_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .restart = orion5x_restart,
+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 000000000..78a1e6ab1
--- /dev/null
+++ b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
@@ -0,0 +1,129 @@
+/*
+ * 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/gpio.h>
+#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/flash.h>
+#include <linux/ethtool.h>
+#include <net/dsa.h>
+#include <asm/mach-types.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,
+ .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> */
+ .atag_offset = 0x100,
+ .init_machine = rd88f6183ap_ge_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .fixup = tag_fixup_mem32,
+ .restart = orion5x_restart,
+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 000000000..12086745c
--- /dev/null
+++ b/arch/arm/mach-orion5x/terastation_pro2-setup.c
@@ -0,0 +1,369 @@
+/*
+ * 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/gpio.h>
+#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/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
+
+static 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(const 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,
+ .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.
+ */
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
+ ORION_MBUS_DEVBUS_BOOT_ATTR,
+ 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_warn("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> */
+ .atag_offset = 0x100,
+ .init_machine = tsp2_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .fixup = tag_fixup_mem32,
+ .restart = orion5x_restart,
+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 000000000..c725b7cb9
--- /dev/null
+++ b/arch/arm/mach-orion5x/ts209-setup.c
@@ -0,0 +1,334 @@
+/*
+ * 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/gpio.h>
+#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/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
+
+static 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(const 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,
+ .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_ts209())
+ 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.
+ */
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
+ ORION_MBUS_DEVBUS_BOOT_ATTR,
+ 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_warn("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> */
+ .atag_offset = 0x100,
+ .init_machine = qnap_ts209_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .fixup = tag_fixup_mem32,
+ .restart = orion5x_restart,
+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 000000000..cf2ab531c
--- /dev/null
+++ b/arch/arm/mach-orion5x/ts409-setup.c
@@ -0,0 +1,323 @@
+/*
+ * 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/gpio.h>
+#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/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(const 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,
+ .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.
+ */
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
+ ORION_MBUS_DEVBUS_BOOT_ATTR,
+ 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_warn("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> */
+ .atag_offset = 0x100,
+ .init_machine = qnap_ts409_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .fixup = tag_fixup_mem32,
+ .restart = orion5x_restart,
+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 000000000..97c393d39
--- /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 000000000..1b704d35c
--- /dev/null
+++ b/arch/arm/mach-orion5x/ts78xx-setup.c
@@ -0,0 +1,624 @@
+/*
+ * 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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#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 IOMEM(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 = (unsigned long)TS78XX_FPGA_REGS_VIRT_BASE,
+ .pfn = __phys_to_pfn(TS78XX_FPGA_REGS_PHYS_BASE),
+ .length = TS78XX_FPGA_REGS_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+static 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);
+
+ if (rc)
+ pr_info("RTC could not be registered: %d\n",
+ rc);
+ return rc;
+ }
+ }
+
+ pr_info("RTC not found\n");
+ 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);
+}
+
+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,
+ .partitions = ts78xx_ts_nand_parts,
+ .nr_partitions = ARRAY_SIZE(ts78xx_ts_nand_parts),
+ .chip_delay = 15,
+ .bbt_options = NAND_BBT_USE_FLASH,
+ },
+ .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
+ = DEFINE_RES_MEM(TS_NAND_DATA, 4);
+
+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);
+
+ if (rc)
+ pr_info("NAND could not be registered: %d\n", rc);
+ 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
+ = DEFINE_RES_MEM(TS_RNG_DATA, 4);
+
+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);
+
+ if (rc)
+ pr_info("RNG could not be registered: %d\n", rc);
+ 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_warn("unrecognised FPGA 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)
+ ts78xx_fpga.supports.ts_rtc.present = 0;
+ ret |= tmp;
+ }
+ if (ts78xx_fpga.supports.ts_nand.present == 1) {
+ tmp = ts78xx_ts_nand_load();
+ if (tmp)
+ ts78xx_fpga.supports.ts_nand.present = 0;
+ ret |= tmp;
+ }
+ if (ts78xx_fpga.supports.ts_rng.present == 1) {
+ tmp = ts78xx_ts_rng_load();
+ if (tmp)
+ 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("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("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("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
+ 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(firmware_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> */
+ .atag_offset = 0x100,
+ .init_machine = ts78xx_init,
+ .map_io = ts78xx_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .restart = orion5x_restart,
+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 000000000..7189827d6
--- /dev/null
+++ b/arch/arm/mach-orion5x/tsx09-common.c
@@ -0,0 +1,135 @@
+/*
+ * 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 <mach/orion5x.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 000000000..098426461
--- /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 000000000..80a56ee24
--- /dev/null
+++ b/arch/arm/mach-orion5x/wnr854t-setup.c
@@ -0,0 +1,184 @@
+/*
+ * 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/gpio.h>
+#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/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();
+
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
+ ORION_MBUS_DEVBUS_BOOT_ATTR,
+ WNR854T_NOR_BOOT_BASE,
+ WNR854T_NOR_BOOT_SIZE);
+ platform_device_register(&wnr854t_nor_flash);
+}
+
+static int __init wnr854t_pci_map_irq(const 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,
+ .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> */
+ .atag_offset = 0x100,
+ .init_machine = wnr854t_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .fixup = tag_fixup_mem32,
+ .restart = orion5x_restart,
+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 000000000..670e30dc0
--- /dev/null
+++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
@@ -0,0 +1,272 @@
+/*
+ * 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/gpio.h>
+#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/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();
+
+ mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
+ ORION_MBUS_DEVBUS_BOOT_ATTR,
+ 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(const 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,
+ .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> */
+ .atag_offset = 0x100,
+ .init_machine = wrt350n_v2_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .init_time = orion5x_timer_init,
+ .fixup = tag_fixup_mem32,
+ .restart = orion5x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-picoxcell/Kconfig b/arch/arm/mach-picoxcell/Kconfig
new file mode 100644
index 000000000..62240f69b
--- /dev/null
+++ b/arch/arm/mach-picoxcell/Kconfig
@@ -0,0 +1,7 @@
+config ARCH_PICOXCELL
+ bool "Picochip PicoXcell" if ARCH_MULTI_V6
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_VIC
+ select DW_APB_TIMER_OF
+ select HAVE_TCM
+ select NO_IOPORT_MAP
diff --git a/arch/arm/mach-picoxcell/Makefile b/arch/arm/mach-picoxcell/Makefile
new file mode 100644
index 000000000..8e39f80fc
--- /dev/null
+++ b/arch/arm/mach-picoxcell/Makefile
@@ -0,0 +1 @@
+obj-y := common.o
diff --git a/arch/arm/mach-picoxcell/common.c b/arch/arm/mach-picoxcell/common.c
new file mode 100644
index 000000000..ec79fea82
--- /dev/null
+++ b/arch/arm/mach-picoxcell/common.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2011 Picochip 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.
+ *
+ * All enquiries to support@picochip.com
+ */
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/reboot.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#define PHYS_TO_IO(x) (((x) & 0x00ffffff) | 0xfe000000)
+#define PICOXCELL_PERIPH_BASE 0x80000000
+#define PICOXCELL_PERIPH_LENGTH SZ_4M
+
+#define WDT_CTRL_REG_EN_MASK (1 << 0)
+#define WDT_CTRL_REG_OFFS (0x00)
+#define WDT_TIMEOUT_REG_OFFS (0x04)
+static void __iomem *wdt_regs;
+
+/*
+ * The machine restart method can be called from an atomic context so we won't
+ * be able to ioremap the regs then.
+ */
+static void picoxcell_setup_restart(void)
+{
+ struct device_node *np = of_find_compatible_node(NULL, NULL,
+ "snps,dw-apb-wdg");
+ if (WARN(!np, "unable to setup watchdog restart"))
+ return;
+
+ wdt_regs = of_iomap(np, 0);
+ WARN(!wdt_regs, "failed to remap watchdog regs");
+}
+
+static struct map_desc io_map __initdata = {
+ .virtual = PHYS_TO_IO(PICOXCELL_PERIPH_BASE),
+ .pfn = __phys_to_pfn(PICOXCELL_PERIPH_BASE),
+ .length = PICOXCELL_PERIPH_LENGTH,
+ .type = MT_DEVICE,
+};
+
+static void __init picoxcell_map_io(void)
+{
+ iotable_init(&io_map, 1);
+}
+
+static void __init picoxcell_init_machine(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ picoxcell_setup_restart();
+}
+
+static const char *picoxcell_dt_match[] = {
+ "picochip,pc3x2",
+ "picochip,pc3x3",
+ NULL
+};
+
+static void picoxcell_wdt_restart(enum reboot_mode mode, const char *cmd)
+{
+ /*
+ * Configure the watchdog to reset with the shortest possible timeout
+ * and give it chance to do the reset.
+ */
+ if (wdt_regs) {
+ writel_relaxed(WDT_CTRL_REG_EN_MASK, wdt_regs + WDT_CTRL_REG_OFFS);
+ writel_relaxed(0, wdt_regs + WDT_TIMEOUT_REG_OFFS);
+ /* No sleeping, possibly atomic. */
+ mdelay(500);
+ }
+}
+
+DT_MACHINE_START(PICOXCELL, "Picochip picoXcell")
+ .map_io = picoxcell_map_io,
+ .init_machine = picoxcell_init_machine,
+ .dt_compat = picoxcell_dt_match,
+ .restart = picoxcell_wdt_restart,
+MACHINE_END
diff --git a/arch/arm/mach-prima2/Kconfig b/arch/arm/mach-prima2/Kconfig
new file mode 100644
index 000000000..e03d8b5c9
--- /dev/null
+++ b/arch/arm/mach-prima2/Kconfig
@@ -0,0 +1,44 @@
+menuconfig ARCH_SIRF
+ bool "CSR SiRF" if ARCH_MULTI_V7
+ select ARCH_HAS_RESET_CONTROLLER
+ select ARCH_REQUIRE_GPIOLIB
+ select GENERIC_IRQ_CHIP
+ select NO_IOPORT_MAP
+ select PINCTRL
+ select PINCTRL_SIRF
+ help
+ Support for CSR SiRFprimaII/Marco/Polo platforms
+
+if ARCH_SIRF
+
+comment "CSR SiRF atlas6/primaII/Atlas7 Specific Features"
+
+config ARCH_ATLAS6
+ bool "CSR SiRFSoC ATLAS6 ARM Cortex A9 Platform"
+ default y
+ select SIRF_IRQ
+ help
+ Support for CSR SiRFSoC ARM Cortex A9 Platform
+
+config ARCH_ATLAS7
+ bool "CSR SiRFSoC ATLAS7 ARM Cortex A7 Platform"
+ default y
+ select ARM_GIC
+ select CPU_V7
+ select HAVE_ARM_SCU if SMP
+ select HAVE_SMP
+ help
+ Support for CSR SiRFSoC ARM Cortex A7 Platform
+
+config ARCH_PRIMA2
+ bool "CSR SiRFSoC PRIMA2 ARM Cortex A9 Platform"
+ default y
+ select SIRF_IRQ
+ select ZONE_DMA
+ help
+ Support for CSR SiRFSoC ARM Cortex A9 Platform
+
+config SIRF_IRQ
+ bool
+
+endif
diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile
new file mode 100644
index 000000000..d7d02b043
--- /dev/null
+++ b/arch/arm/mach-prima2/Makefile
@@ -0,0 +1,8 @@
+obj-y += rstc.o
+obj-y += common.o
+obj-y += rtciobrg.o
+obj-$(CONFIG_SUSPEND) += pm.o sleep.o
+obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+
+CFLAGS_hotplug.o += -march=armv7-a
diff --git a/arch/arm/mach-prima2/Makefile.boot b/arch/arm/mach-prima2/Makefile.boot
new file mode 100644
index 000000000..c77a4883a
--- /dev/null
+++ b/arch/arm/mach-prima2/Makefile.boot
@@ -0,0 +1,3 @@
+zreladdr-y += 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
diff --git a/arch/arm/mach-prima2/common.c b/arch/arm/mach-prima2/common.c
new file mode 100644
index 000000000..8cadb302a
--- /dev/null
+++ b/arch/arm/mach-prima2/common.c
@@ -0,0 +1,65 @@
+/*
+ * Defines machines for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/sizes.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include "common.h"
+
+static void __init sirfsoc_init_late(void)
+{
+ sirfsoc_pm_init();
+}
+
+#ifdef CONFIG_ARCH_ATLAS6
+static const char *const atlas6_dt_match[] __initconst = {
+ "sirf,atlas6",
+ NULL
+};
+
+DT_MACHINE_START(ATLAS6_DT, "Generic ATLAS6 (Flattened Device Tree)")
+ /* Maintainer: Barry Song <baohua.song@csr.com> */
+ .l2c_aux_val = 0,
+ .l2c_aux_mask = ~0,
+ .init_late = sirfsoc_init_late,
+ .dt_compat = atlas6_dt_match,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_PRIMA2
+static const char *const prima2_dt_match[] __initconst = {
+ "sirf,prima2",
+ NULL
+};
+
+DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)")
+ /* Maintainer: Barry Song <baohua.song@csr.com> */
+ .l2c_aux_val = 0,
+ .l2c_aux_mask = ~0,
+ .dma_zone_size = SZ_256M,
+ .init_late = sirfsoc_init_late,
+ .dt_compat = prima2_dt_match,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_ATLAS7
+static const char *const atlas7_dt_match[] __initconst = {
+ "sirf,atlas7",
+ NULL
+};
+
+DT_MACHINE_START(ATLAS7_DT, "Generic ATLAS7 (Flattened Device Tree)")
+ /* Maintainer: Barry Song <baohua.song@csr.com> */
+ .smp = smp_ops(sirfsoc_smp_ops),
+ .dt_compat = atlas7_dt_match,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-prima2/common.h b/arch/arm/mach-prima2/common.h
new file mode 100644
index 000000000..3916a6665
--- /dev/null
+++ b/arch/arm/mach-prima2/common.h
@@ -0,0 +1,31 @@
+/*
+ * This file contains common function prototypes to avoid externs in the c files.
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_PRIMA2_COMMON_H__
+#define __MACH_PRIMA2_COMMON_H__
+
+#include <linux/init.h>
+#include <linux/reboot.h>
+
+#include <asm/mach/time.h>
+#include <asm/exception.h>
+
+extern struct smp_operations sirfsoc_smp_ops;
+extern void sirfsoc_secondary_startup(void);
+extern void sirfsoc_cpu_die(unsigned int cpu);
+
+extern void __init sirfsoc_of_irq_init(void);
+extern asmlinkage void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs);
+
+#ifdef CONFIG_SUSPEND
+extern int sirfsoc_pm_init(void);
+#else
+static inline int sirfsoc_pm_init(void) { return 0; }
+#endif
+
+#endif
diff --git a/arch/arm/mach-prima2/headsmp.S b/arch/arm/mach-prima2/headsmp.S
new file mode 100644
index 000000000..d86fe33c5
--- /dev/null
+++ b/arch/arm/mach-prima2/headsmp.S
@@ -0,0 +1,38 @@
+/*
+ * Entry of the second core for CSR Marco dual-core SMP SoCs
+ *
+ * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+/*
+ * SIRFSOC 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(sirfsoc_secondary_startup)
+ bl v7_invalidate_l1
+ 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
+ENDPROC(sirfsoc_secondary_startup)
+
+ .align
+1: .long .
+ .long pen_release
diff --git a/arch/arm/mach-prima2/hotplug.c b/arch/arm/mach-prima2/hotplug.c
new file mode 100644
index 000000000..0ab2f8bae
--- /dev/null
+++ b/arch/arm/mach-prima2/hotplug.c
@@ -0,0 +1,38 @@
+/*
+ * CPU hotplug support for CSR Marco dual-core SMP SoCs
+ *
+ * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+#include <asm/smp_plat.h>
+
+static inline void platform_do_lowpower(unsigned int cpu)
+{
+ /* we put the platform to just WFI */
+ for (;;) {
+ __asm__ __volatile__("dsb\n\t" "wfi\n\t"
+ : : : "memory");
+ if (pen_release == cpu_logical_map(cpu)) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+ }
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void __ref sirfsoc_cpu_die(unsigned int cpu)
+{
+ platform_do_lowpower(cpu);
+}
diff --git a/arch/arm/mach-prima2/platsmp.c b/arch/arm/mach-prima2/platsmp.c
new file mode 100644
index 000000000..e46c91094
--- /dev/null
+++ b/arch/arm/mach-prima2/platsmp.c
@@ -0,0 +1,121 @@
+/*
+ * plat smp support for CSR Marco dual-core SMP SoCs
+ *
+ * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+#include <asm/cacheflush.h>
+#include <asm/cputype.h>
+
+#include "common.h"
+
+static void __iomem *clk_base;
+
+static DEFINE_SPINLOCK(boot_lock);
+
+static void sirfsoc_secondary_init(unsigned int cpu)
+{
+ /*
+ * 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 const struct of_device_id clk_ids[] = {
+ { .compatible = "sirf,atlas7-clkc" },
+ {},
+};
+
+static int sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ unsigned long timeout;
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, clk_ids);
+ if (!np)
+ return -ENODEV;
+
+ clk_base = of_iomap(np, 0);
+ if (!clk_base)
+ return -ENOMEM;
+
+ /*
+ * write the address of secondary startup into the clkc register
+ * at offset 0x2bC, then write the magic number 0x3CAF5D62 to the
+ * clkc register at offset 0x2b8, which is what boot rom code is
+ * waiting for. This would wake up the secondary core from WFE
+ */
+#define SIRFSOC_CPU1_JUMPADDR_OFFSET 0x2bc
+ __raw_writel(virt_to_phys(sirfsoc_secondary_startup),
+ clk_base + SIRFSOC_CPU1_JUMPADDR_OFFSET);
+
+#define SIRFSOC_CPU1_WAKEMAGIC_OFFSET 0x2b8
+ __raw_writel(0x3CAF5D62,
+ clk_base + SIRFSOC_CPU1_WAKEMAGIC_OFFSET);
+
+ /* make sure write buffer is drained */
+ mb();
+
+ 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_logical_map(cpu);
+ sync_cache_w(&pen_release);
+
+ /*
+ * Send the secondary CPU SEV, thereby causing the boot monitor to read
+ * the JUMPADDR and WAKEMAGIC, and branch to the address found there.
+ */
+ dsb_sev();
+
+ 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;
+}
+
+struct smp_operations sirfsoc_smp_ops __initdata = {
+ .smp_secondary_init = sirfsoc_secondary_init,
+ .smp_boot_secondary = sirfsoc_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = sirfsoc_cpu_die,
+#endif
+};
diff --git a/arch/arm/mach-prima2/pm.c b/arch/arm/mach-prima2/pm.c
new file mode 100644
index 000000000..d99d08eeb
--- /dev/null
+++ b/arch/arm/mach-prima2/pm.c
@@ -0,0 +1,153 @@
+/*
+ * power management entry for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <linux/rtc/sirfsoc_rtciobrg.h>
+#include <asm/suspend.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "pm.h"
+
+/*
+ * suspend asm codes will access these to make DRAM become self-refresh and
+ * system sleep
+ */
+u32 sirfsoc_pwrc_base;
+void __iomem *sirfsoc_memc_base;
+
+static void sirfsoc_set_wakeup_source(void)
+{
+ u32 pwr_trigger_en_reg;
+ pwr_trigger_en_reg = sirfsoc_rtc_iobrg_readl(sirfsoc_pwrc_base +
+ SIRFSOC_PWRC_TRIGGER_EN);
+#define X_ON_KEY_B (1 << 0)
+#define RTC_ALARM0_B (1 << 2)
+#define RTC_ALARM1_B (1 << 3)
+ sirfsoc_rtc_iobrg_writel(pwr_trigger_en_reg | X_ON_KEY_B |
+ RTC_ALARM0_B | RTC_ALARM1_B,
+ sirfsoc_pwrc_base + SIRFSOC_PWRC_TRIGGER_EN);
+}
+
+static void sirfsoc_set_sleep_mode(u32 mode)
+{
+ u32 sleep_mode = sirfsoc_rtc_iobrg_readl(sirfsoc_pwrc_base +
+ SIRFSOC_PWRC_PDN_CTRL);
+ sleep_mode &= ~(SIRFSOC_SLEEP_MODE_MASK << 1);
+ sleep_mode |= mode << 1;
+ sirfsoc_rtc_iobrg_writel(sleep_mode, sirfsoc_pwrc_base +
+ SIRFSOC_PWRC_PDN_CTRL);
+}
+
+static int sirfsoc_pre_suspend_power_off(void)
+{
+ u32 wakeup_entry = virt_to_phys(cpu_resume);
+
+ sirfsoc_rtc_iobrg_writel(wakeup_entry, sirfsoc_pwrc_base +
+ SIRFSOC_PWRC_SCRATCH_PAD1);
+
+ sirfsoc_set_wakeup_source();
+
+ sirfsoc_set_sleep_mode(SIRFSOC_DEEP_SLEEP_MODE);
+
+ return 0;
+}
+
+static int sirfsoc_pm_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ sirfsoc_pre_suspend_power_off();
+
+ outer_disable();
+ /* go zzz */
+ cpu_suspend(0, sirfsoc_finish_suspend);
+ outer_resume();
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static const struct platform_suspend_ops sirfsoc_pm_ops = {
+ .enter = sirfsoc_pm_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+static const struct of_device_id pwrc_ids[] = {
+ { .compatible = "sirf,prima2-pwrc" },
+ {}
+};
+
+static int __init sirfsoc_of_pwrc_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, pwrc_ids);
+ if (!np) {
+ pr_err("unable to find compatible sirf pwrc node in dtb\n");
+ return -ENOENT;
+ }
+
+ /*
+ * pwrc behind rtciobrg is not located in memory space
+ * though the property is named reg. reg only means base
+ * offset for pwrc. then of_iomap is not suitable here.
+ */
+ if (of_property_read_u32(np, "reg", &sirfsoc_pwrc_base))
+ panic("unable to find base address of pwrc node in dtb\n");
+
+ of_node_put(np);
+
+ return 0;
+}
+
+static const struct of_device_id memc_ids[] = {
+ { .compatible = "sirf,prima2-memc" },
+ {}
+};
+
+static int sirfsoc_memc_probe(struct platform_device *op)
+{
+ struct device_node *np = op->dev.of_node;
+
+ sirfsoc_memc_base = of_iomap(np, 0);
+ if (!sirfsoc_memc_base)
+ panic("unable to map memc registers\n");
+
+ return 0;
+}
+
+static struct platform_driver sirfsoc_memc_driver = {
+ .probe = sirfsoc_memc_probe,
+ .driver = {
+ .name = "sirfsoc-memc",
+ .of_match_table = memc_ids,
+ },
+};
+
+static int __init sirfsoc_memc_init(void)
+{
+ return platform_driver_register(&sirfsoc_memc_driver);
+}
+
+int __init sirfsoc_pm_init(void)
+{
+ sirfsoc_of_pwrc_init();
+ sirfsoc_memc_init();
+ suspend_set_ops(&sirfsoc_pm_ops);
+ return 0;
+}
diff --git a/arch/arm/mach-prima2/pm.h b/arch/arm/mach-prima2/pm.h
new file mode 100644
index 000000000..bae6d77e0
--- /dev/null
+++ b/arch/arm/mach-prima2/pm.h
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-prima2/pm.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef _MACH_PRIMA2_PM_H_
+#define _MACH_PRIMA2_PM_H_
+
+#define SIRFSOC_PWR_SLEEPFORCE 0x01
+
+#define SIRFSOC_SLEEP_MODE_MASK 0x3
+#define SIRFSOC_DEEP_SLEEP_MODE 0x1
+
+#define SIRFSOC_PWRC_PDN_CTRL 0x0
+#define SIRFSOC_PWRC_PON_OFF 0x4
+#define SIRFSOC_PWRC_TRIGGER_EN 0x8
+#define SIRFSOC_PWRC_PIN_STATUS 0x14
+#define SIRFSOC_PWRC_SCRATCH_PAD1 0x18
+#define SIRFSOC_PWRC_SCRATCH_PAD2 0x1C
+
+#ifndef __ASSEMBLY__
+extern int sirfsoc_finish_suspend(unsigned long);
+#endif
+
+#endif
+
diff --git a/arch/arm/mach-prima2/rstc.c b/arch/arm/mach-prima2/rstc.c
new file mode 100644
index 000000000..7c251eb11
--- /dev/null
+++ b/arch/arm/mach-prima2/rstc.c
@@ -0,0 +1,108 @@
+/*
+ * reset controller for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/reset-controller.h>
+
+#include <asm/system_misc.h>
+
+#define SIRFSOC_RSTBIT_NUM 64
+
+static void __iomem *sirfsoc_rstc_base;
+static DEFINE_MUTEX(rstc_lock);
+
+static int sirfsoc_reset_module(struct reset_controller_dev *rcdev,
+ unsigned long sw_reset_idx)
+{
+ u32 reset_bit = sw_reset_idx;
+
+ if (reset_bit >= SIRFSOC_RSTBIT_NUM)
+ return -EINVAL;
+
+ mutex_lock(&rstc_lock);
+
+ /*
+ * Writing 1 to this bit resets corresponding block.
+ * Writing 0 to this bit de-asserts reset signal of the
+ * corresponding block. datasheet doesn't require explicit
+ * delay between the set and clear of reset bit. it could
+ * be shorter if tests pass.
+ */
+ writel(readl(sirfsoc_rstc_base +
+ (reset_bit / 32) * 4) | (1 << reset_bit),
+ sirfsoc_rstc_base + (reset_bit / 32) * 4);
+ msleep(20);
+ writel(readl(sirfsoc_rstc_base +
+ (reset_bit / 32) * 4) & ~(1 << reset_bit),
+ sirfsoc_rstc_base + (reset_bit / 32) * 4);
+
+ mutex_unlock(&rstc_lock);
+
+ return 0;
+}
+
+static struct reset_control_ops sirfsoc_rstc_ops = {
+ .reset = sirfsoc_reset_module,
+};
+
+static struct reset_controller_dev sirfsoc_reset_controller = {
+ .ops = &sirfsoc_rstc_ops,
+ .nr_resets = SIRFSOC_RSTBIT_NUM,
+};
+
+#define SIRFSOC_SYS_RST_BIT BIT(31)
+
+static void sirfsoc_restart(enum reboot_mode mode, const char *cmd)
+{
+ writel(SIRFSOC_SYS_RST_BIT, sirfsoc_rstc_base);
+}
+
+static int sirfsoc_rstc_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ sirfsoc_rstc_base = of_iomap(np, 0);
+ if (!sirfsoc_rstc_base) {
+ dev_err(&pdev->dev, "unable to map rstc cpu registers\n");
+ return -ENOMEM;
+ }
+
+ sirfsoc_reset_controller.of_node = np;
+ arm_pm_restart = sirfsoc_restart;
+
+ if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
+ reset_controller_register(&sirfsoc_reset_controller);
+
+ return 0;
+}
+
+static const struct of_device_id rstc_ids[] = {
+ { .compatible = "sirf,prima2-rstc" },
+ {},
+};
+
+static struct platform_driver sirfsoc_rstc_driver = {
+ .probe = sirfsoc_rstc_probe,
+ .driver = {
+ .name = "sirfsoc_rstc",
+ .of_match_table = rstc_ids,
+ },
+};
+
+static int __init sirfsoc_rstc_init(void)
+{
+ return platform_driver_register(&sirfsoc_rstc_driver);
+}
+subsys_initcall(sirfsoc_rstc_init);
diff --git a/arch/arm/mach-prima2/rtciobrg.c b/arch/arm/mach-prima2/rtciobrg.c
new file mode 100644
index 000000000..8f66d8f7c
--- /dev/null
+++ b/arch/arm/mach-prima2/rtciobrg.c
@@ -0,0 +1,138 @@
+/*
+ * RTC I/O Bridge interfaces for CSR SiRFprimaII
+ * ARM access the registers of SYSRTC, GPSRTC and PWRC through this module
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+
+#define SIRFSOC_CPUIOBRG_CTRL 0x00
+#define SIRFSOC_CPUIOBRG_WRBE 0x04
+#define SIRFSOC_CPUIOBRG_ADDR 0x08
+#define SIRFSOC_CPUIOBRG_DATA 0x0c
+
+/*
+ * suspend asm codes will access this address to make system deepsleep
+ * after DRAM becomes self-refresh
+ */
+void __iomem *sirfsoc_rtciobrg_base;
+static DEFINE_SPINLOCK(rtciobrg_lock);
+
+/*
+ * symbols without lock are only used by suspend asm codes
+ * and these symbols are not exported too
+ */
+void sirfsoc_rtc_iobrg_wait_sync(void)
+{
+ while (readl_relaxed(sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_CTRL))
+ cpu_relax();
+}
+
+void sirfsoc_rtc_iobrg_besyncing(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtciobrg_lock, flags);
+
+ sirfsoc_rtc_iobrg_wait_sync();
+
+ spin_unlock_irqrestore(&rtciobrg_lock, flags);
+}
+EXPORT_SYMBOL_GPL(sirfsoc_rtc_iobrg_besyncing);
+
+u32 __sirfsoc_rtc_iobrg_readl(u32 addr)
+{
+ sirfsoc_rtc_iobrg_wait_sync();
+
+ writel_relaxed(0x00, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_WRBE);
+ writel_relaxed(addr, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_ADDR);
+ writel_relaxed(0x01, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_CTRL);
+
+ sirfsoc_rtc_iobrg_wait_sync();
+
+ return readl_relaxed(sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_DATA);
+}
+
+u32 sirfsoc_rtc_iobrg_readl(u32 addr)
+{
+ unsigned long flags, val;
+
+ spin_lock_irqsave(&rtciobrg_lock, flags);
+
+ val = __sirfsoc_rtc_iobrg_readl(addr);
+
+ spin_unlock_irqrestore(&rtciobrg_lock, flags);
+
+ return val;
+}
+EXPORT_SYMBOL_GPL(sirfsoc_rtc_iobrg_readl);
+
+void sirfsoc_rtc_iobrg_pre_writel(u32 val, u32 addr)
+{
+ sirfsoc_rtc_iobrg_wait_sync();
+
+ writel_relaxed(0xf1, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_WRBE);
+ writel_relaxed(addr, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_ADDR);
+
+ writel_relaxed(val, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_DATA);
+}
+
+void sirfsoc_rtc_iobrg_writel(u32 val, u32 addr)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtciobrg_lock, flags);
+
+ sirfsoc_rtc_iobrg_pre_writel(val, addr);
+
+ writel_relaxed(0x01, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_CTRL);
+
+ sirfsoc_rtc_iobrg_wait_sync();
+
+ spin_unlock_irqrestore(&rtciobrg_lock, flags);
+}
+EXPORT_SYMBOL_GPL(sirfsoc_rtc_iobrg_writel);
+
+static const struct of_device_id rtciobrg_ids[] = {
+ { .compatible = "sirf,prima2-rtciobg" },
+ {}
+};
+
+static int sirfsoc_rtciobrg_probe(struct platform_device *op)
+{
+ struct device_node *np = op->dev.of_node;
+
+ sirfsoc_rtciobrg_base = of_iomap(np, 0);
+ if (!sirfsoc_rtciobrg_base)
+ panic("unable to map rtc iobrg registers\n");
+
+ return 0;
+}
+
+static struct platform_driver sirfsoc_rtciobrg_driver = {
+ .probe = sirfsoc_rtciobrg_probe,
+ .driver = {
+ .name = "sirfsoc-rtciobrg",
+ .of_match_table = rtciobrg_ids,
+ },
+};
+
+static int __init sirfsoc_rtciobrg_init(void)
+{
+ return platform_driver_register(&sirfsoc_rtciobrg_driver);
+}
+postcore_initcall(sirfsoc_rtciobrg_init);
+
+MODULE_AUTHOR("Zhiwu Song <zhiwu.song@csr.com>, "
+ "Barry Song <baohua.song@csr.com>");
+MODULE_DESCRIPTION("CSR SiRFprimaII rtc io bridge");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-prima2/sleep.S b/arch/arm/mach-prima2/sleep.S
new file mode 100644
index 000000000..0745abc36
--- /dev/null
+++ b/arch/arm/mach-prima2/sleep.S
@@ -0,0 +1,64 @@
+/*
+ * sleep mode for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/assembler.h>
+
+#include "pm.h"
+
+#define DENALI_CTL_22_OFF 0x58
+#define DENALI_CTL_112_OFF 0x1c0
+
+ .text
+
+ENTRY(sirfsoc_finish_suspend)
+ @ r5: mem controller
+ ldr r0, =sirfsoc_memc_base
+ ldr r5, [r0]
+ @ r6: pwrc base offset
+ ldr r0, =sirfsoc_pwrc_base
+ ldr r6, [r0]
+ @ r7: rtc iobrg controller
+ ldr r0, =sirfsoc_rtciobrg_base
+ ldr r7, [r0]
+
+ @ Read the power control register and set the
+ @ sleep force bit.
+ add r0, r6, #SIRFSOC_PWRC_PDN_CTRL
+ bl __sirfsoc_rtc_iobrg_readl
+ orr r0,r0,#SIRFSOC_PWR_SLEEPFORCE
+ add r1, r6, #SIRFSOC_PWRC_PDN_CTRL
+ bl sirfsoc_rtc_iobrg_pre_writel
+ mov r1, #0x1
+
+ @ read the MEM ctl register and set the self
+ @ refresh bit
+
+ ldr r2, [r5, #DENALI_CTL_22_OFF]
+ orr r2, r2, #0x1
+
+ @ Following code has to run from cache since
+ @ the RAM is going to self refresh mode
+ .align 5
+ str r2, [r5, #DENALI_CTL_22_OFF]
+
+1:
+ ldr r4, [r5, #DENALI_CTL_112_OFF]
+ tst r4, #0x1
+ bne 1b
+
+ @ write SLEEPFORCE through rtc iobridge
+
+ str r1, [r7]
+ @ wait rtc io bridge sync
+1:
+ ldr r3, [r7]
+ tst r3, #0x01
+ bne 1b
+ b .
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
new file mode 100644
index 000000000..f09683687
--- /dev/null
+++ b/arch/arm/mach-pxa/Kconfig
@@ -0,0 +1,703 @@
+if ARCH_PXA
+
+menu "Intel PXA2xx/PXA3xx Implementations"
+
+comment "Intel/Marvell Dev Platforms (sorted by hardware release time)"
+
+config MACH_PXA27X_DT
+ bool "Support PXA27x platforms from device tree"
+ select POWER_SUPPLY
+ select PXA27x
+ select USE_OF
+ help
+ Include support for Marvell PXA27x based platforms using
+ the device tree. Needn't select any other machine while
+ MACH_PXA27X_DT is enabled.
+
+config MACH_PXA3XX_DT
+ bool "Support PXA3xx platforms from device tree"
+ select CPU_PXA300
+ select POWER_SUPPLY
+ select PXA3xx
+ select USE_OF
+ help
+ Include support for Marvell PXA3xx based platforms using
+ the device tree. Needn't select any other machine while
+ MACH_PXA3XX_DT is enabled.
+
+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
+
+config MACH_ZYLONITE
+ bool
+ select PXA3xx
+
+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 CPU_PXA300
+ select CPU_PXA310
+ select PXA3xx
+
+config MACH_TAVOREVB
+ bool "PXA930 Evaluation Board (aka TavorEVB)"
+ select CPU_PXA930
+ select CPU_PXA935
+ select PXA3xx
+ select FB
+ select FB_PXA
+
+config MACH_SAAR
+ bool "PXA930 Handheld Platform (aka SAAR)"
+ select CPU_PXA930
+ select CPU_PXA935
+ select PXA3xx
+ select FB
+ select FB_PXA
+
+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 ARCOM_PCMCIA
+ select I2C_GPIO if I2C=y
+ select ISA
+ select PXA25x
+
+config MACH_ARCOM_ZEUS
+ bool "Arcom/Eurotech ZEUS SBC"
+ select ARCOM_PCMCIA
+ select ISA
+ select PXA27x
+
+config MACH_BALLOON3
+ bool "Balloon 3 board"
+ select IWMMXT
+ select PXA27x
+
+config MACH_CSB726
+ bool "Enable Cogent CSB726 System On a Module"
+ select IWMMXT
+ select PXA27x
+ 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 ARCH_HAS_DMA_SET_COHERENT_MASK if PCI
+ select IWMMXT
+ select MIGHT_HAVE_PCI
+ select NEED_MACH_IO_H if PCI
+ select PXA25x
+ select PXA27x
+
+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 CPU_PXA300
+ select CPU_PXA310
+ select PXA3xx
+
+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 IWMMXT
+ select PXA27x
+
+config MACH_STARGATE2
+ bool "Intel Stargate 2 Platform"
+ select IWMMXT
+ select PXA27x
+
+config MACH_XCEP
+ bool "Iskratel Electronics XCEP"
+ select MTD
+ select MTD_CFI
+ select MTD_CFI_INTELEXT
+ select MTD_PHYSMAP
+ select PXA25x
+ 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 PXA27x
+ select TRIZEPS_PCMCIA
+
+config MACH_TRIZEPS4WL
+ bool "Keith und Koep Trizeps4-WL DIMM-Module"
+ depends on TRIZEPS_PXA
+ select MACH_TRIZEPS4
+ select PXA27x
+ select TRIZEPS_PCMCIA
+
+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
+
+config MACH_PCM027
+ bool "Phytec phyCORE-PXA270 CPU module (PCM-027)"
+ select IWMMXT
+ select PXA27x
+
+config MACH_PCM990_BASEBOARD
+ bool "PHYTEC PCM-990 development board"
+ 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
+
+config MACH_COLIBRI300
+ bool "Toradex Colibri PXA300/310"
+ select CPU_PXA300
+ select CPU_PXA310
+ select PXA3xx
+
+config MACH_COLIBRI320
+ bool "Toradex Colibri PXA320"
+ select CPU_PXA320
+ select PXA3xx
+
+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 HAVE_PATA_PLATFORM
+ select PXA27x
+ help
+ PXA270 based Single Board Computer.
+
+comment "End-user Products (sorted by vendor name)"
+
+config MACH_H4700
+ bool "HP iPAQ hx4700"
+ select IWMMXT
+ select PXA27x
+
+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 IWMMXT
+ select PXA27x
+
+config MACH_MIOA701
+ bool "Mitac Mio A701 Support"
+ select GPIO_SYSFS
+ select IWMMXT
+ select PXA27x
+ 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 IWMMXT
+ select PXA27x
+
+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"
+
+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 IWMMXT
+ select MACH_PALM27X
+ select PXA27x
+ 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 IWMMXT
+ select MACH_PALM27X
+ select PXA27x
+ 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 IWMMXT
+ select MACH_PALM27X
+ select PXA27x
+ 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 IWMMXT
+ select MACH_PALM27X
+ select PXA27x
+ 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 IWMMXT
+ select MACH_PALM27X
+ select PALM_TREO
+ select PXA27x
+ 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 IWMMXT
+ select MACH_PALM27X
+ select PALM_TREO
+ select PXA27x
+ help
+ Say Y here if you intend to run this kernel on Palm Treo 680
+ smartphone.
+
+config MACH_RAUMFELD_RC
+ bool "Raumfeld Controller"
+ select CPU_PXA300
+ select POWER_SUPPLY
+ select PXA3xx
+
+config MACH_RAUMFELD_CONNECTOR
+ bool "Raumfeld Connector"
+ select CPU_PXA300
+ select POWER_SUPPLY
+ select PXA3xx
+
+config MACH_RAUMFELD_SPEAKER
+ bool "Raumfeld Speaker"
+ select CPU_PXA300
+ select POWER_SUPPLY
+ select PXA3xx
+
+config PXA_SHARPSL
+ bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models"
+ select SHARP_PARAM
+ select SHARP_SCOOP
+ 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 I2C
+ select I2C_PXA
+ select MACH_SPITZ
+ select PXA27x
+ select PXA_SHARP_Cxx00
+
+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 FB_W100
+ select PXA25x
+
+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
+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 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
+ select SPI
+ select SPI_MASTER
+
+config PXA310_ULPI
+ bool
+
+config PXA_SYSTEMS_CPLDS
+ tristate "Motherboard cplds"
+ default ARCH_LUBBOCK || MACH_MAINSTONE
+ help
+ This driver supports the Lubbock and Mainstone multifunction chip
+ found on the pxa25x development platform system (Lubbock) and pxa27x
+ development platform system (Mainstone). This IO board supports the
+ interrupts handling, ethernet controller, flash chips, etc ...
+
+endif
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
new file mode 100644
index 000000000..4087d334e
--- /dev/null
+++ b/arch/arm/mach-pxa/Makefile
@@ -0,0 +1,94 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support (must be linked before board specific support)
+obj-y += clock.o devices.o generic.o irq.o \
+ reset.o
+obj-$(CONFIG_PM) += pm.o sleep.o standby.o
+
+# 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_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
+
+# Device Tree support
+obj-$(CONFIG_MACH_PXA3XX_DT) += pxa-dt.o
+obj-$(CONFIG_MACH_PXA27X_DT) += pxa-dt.o
+
+# 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_SAAR) += saar.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
+
+obj-$(CONFIG_PXA_SYSTEMS_CPLDS) += pxa_cplds_irqs.o
+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 000000000..2c1ae92f2
--- /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 000000000..12fb0f4ae
--- /dev/null
+++ b/arch/arm/mach-pxa/am200epd.c
@@ -0,0 +1,386 @@
+/*
+ * 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 <linux/platform_data/video-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(PXA_GPIO_TO_IRQ(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(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), am200_handle_irq,
+ 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 000000000..8b90c4f2d
--- /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/irqs.h>
+#include <linux/platform_data/video-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(PXA_GPIO_TO_IRQ(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(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), am300_handle_irq,
+ 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 000000000..d89729271
--- /dev/null
+++ b/arch/arm/mach-pxa/balloon3.c
@@ -0,0 +1,828 @@
+/*
+ * 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/export.h>
+#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 <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <mach/udc.h>
+#include <mach/pxa27x-udc.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <linux/platform_data/usb-ohci-pxa27x.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 kstrtoul(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 = PXA_GPIO_TO_IRQ(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);
+}
+#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
+ },
+};
+
+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,
+ },
+ .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[] = {
+ REGULATOR_SUPPLY("vcc_core", NULL),
+};
+
+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 = (unsigned long)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,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = balloon3_init,
+ .atag_offset = 0x100,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/capc7117.c b/arch/arm/mach-pxa/capc7117.c
new file mode 100644
index 000000000..c09273074
--- /dev/null
+++ b/arch/arm/mach-pxa/capc7117.c
@@ -0,0 +1,159 @@
+/*
+ * 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 = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO76)),
+ .end = PXA_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 = PXA_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 = PXA_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 = PXA_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 = PXA_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")
+ .atag_offset = 0x100,
+ .map_io = pxa3xx_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .handle_irq = pxa3xx_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = capc7117_init,
+ .restart = pxa_restart,
+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 000000000..9ee2ad6a0
--- /dev/null
+++ b/arch/arm/mach-pxa/clock-pxa2xx.c
@@ -0,0 +1,55 @@
+/*
+ * 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/io.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 000000000..d4e949983
--- /dev/null
+++ b/arch/arm/mach-pxa/clock-pxa3xx.c
@@ -0,0 +1,212 @@
+/*
+ * 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 if (clk->cken < 64)
+ CKENB |= mask;
+ else
+ CKENC |= mask;
+}
+
+void clk_pxa3xx_cken_disable(struct clk *clk)
+{
+ unsigned long mask = 1ul << (clk->cken & 0x1f);
+
+ if (clk->cken < 32)
+ CKENA &= ~mask;
+ else if (clk->cken < 64)
+ CKENB &= ~mask;
+ else
+ CKENC &= ~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 000000000..4d466102a
--- /dev/null
+++ b/arch/arm/mach-pxa/clock.c
@@ -0,0 +1,86 @@
+/*
+ * 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);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ if (clk->ops->setrate) {
+ spin_lock_irqsave(&clocks_lock, flags);
+ ret = clk->ops->setrate(clk, rate);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_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 000000000..1f65d32c8
--- /dev/null
+++ b/arch/arm/mach-pxa/clock.h
@@ -0,0 +1,80 @@
+#include <linux/clkdev.h>
+#include <linux/syscore_ops.h>
+
+struct clkops {
+ void (*enable)(struct clk *);
+ void (*disable)(struct clk *);
+ unsigned long (*getrate)(struct clk *);
+ int (*setrate)(struct clk *, unsigned long);
+};
+
+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)
+#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 000000000..be751470d
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x255.c
@@ -0,0 +1,236 @@
+/*
+ * 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/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 000000000..2503db9e3
--- /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 <linux/platform_data/usb-ohci-pxa27x.h>
+#include <linux/platform_data/mmc-pxamci.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 PXA_GPIO_TO_IRQ(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 = PXA_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 000000000..d8f816c24
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x2xx-pci.c
@@ -0,0 +1,199 @@
+/*
+ * 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>
+
+void __iomem *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(const 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");
+
+ pcibios_min_io = 0;
+ pcibios_min_mem = 0;
+
+ __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 = {
+ .map_irq = cmx2xx_pci_map_irq,
+ .nr_controllers = 1,
+ .ops = &it8152_ops,
+ .setup = it8152_pci_setup,
+ .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 000000000..e24aad2e3
--- /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 000000000..bb99f59a3
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x2xx.c
@@ -0,0 +1,529 @@
+/*
+ * 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/pxa25x.h>
+#undef GPIO24_SSP1_SFRM
+#include <mach/pxa27x.h>
+#include <mach/audio.h>
+#include <linux/platform_data/video-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 (void __iomem *)(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 PXA_GPIO_TO_IRQ(GPIO22_ETHIRQ)
+#define CMX270_ETHIRQ PXA_GPIO_TO_IRQ(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 = (unsigned long)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")
+ .atag_offset = 0x100,
+ .map_io = cmx2xx_map_io,
+ .nr_irqs = CMX2XX_NR_IRQS,
+ .init_irq = cmx2xx_init_irq,
+ /* NOTE: pxa25x_handle_irq() works on PXA27x w/o camera support */
+ .handle_irq = pxa25x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = cmx2xx_init,
+#ifdef CONFIG_PCI
+ .dma_zone_size = SZ_64M,
+#endif
+ .restart = pxa_restart,
+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 000000000..4d3588d26
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -0,0 +1,861 @@
+/*
+ * 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.
+ */
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#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/platform_data/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 <asm/system_info.h>
+
+#include <mach/pxa300.h>
+#include <mach/pxa27x-udc.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/usb-ohci-pxa27x.h>
+#include <linux/platform_data/mtd-nand-pxa3xx.h>
+#include <mach/audio.h>
+#include <linux/platform_data/usb-pxa3xx-ulpi.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 PXA_GPIO_TO_IRQ(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 = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO99)),
+ .end = PXA_GPIO_TO_IRQ(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,
+ .enable_gpio = -1,
+};
+
+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,
+ .num_cs = 1,
+ .parts[0] = cm_x300_nand_partitions,
+ .nr_parts[0] = 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_one(GPIO_ULPI_PHY_RST, GPIOF_OUT_INIT_LOW,
+ "ulpi reset");
+ if (err) {
+ pr_err("failed to request ULPI reset GPIO: %d\n", err);
+ return err;
+ }
+
+ 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("failed to get CLK_POUT: %d\n", 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[] = {
+ REGULATOR_SUPPLY("vcc_core", NULL),
+};
+
+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);
+}
+
+/* wi2wi gpio setting for system_rev >= 130 */
+static struct gpio cm_x300_wi2wi_gpios[] __initdata = {
+ { 71, GPIOF_OUT_INIT_HIGH, "wlan en" },
+ { 70, GPIOF_OUT_INIT_HIGH, "bt reset" },
+};
+
+static void __init cm_x300_init_wi2wi(void)
+{
+ int err;
+
+ if (system_rev < 130) {
+ cm_x300_wi2wi_gpios[0].gpio = 77; /* wlan en */
+ cm_x300_wi2wi_gpios[1].gpio = 78; /* bt reset */
+ }
+
+ /* Libertas and CSR reset */
+ err = gpio_request_array(ARRAY_AND_SIZE(cm_x300_wi2wi_gpios));
+ if (err) {
+ pr_err("failed to request wifi/bt gpios: %d\n", err);
+ return;
+ }
+
+ udelay(10);
+ gpio_set_value(cm_x300_wi2wi_gpios[1].gpio, 0);
+ udelay(10);
+ gpio_set_value(cm_x300_wi2wi_gpios[1].gpio, 1);
+
+ gpio_free_array(ARRAY_AND_SIZE(cm_x300_wi2wi_gpios));
+}
+
+/* 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 tag *tags, char **cmdline)
+{
+ /* 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")
+ .atag_offset = 0x100,
+ .map_io = pxa3xx_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .handle_irq = pxa3xx_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = cm_x300_init,
+ .fixup = cm_x300_fixup,
+ .restart = pxa_restart,
+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 000000000..638b0bb88
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri-evalboard.c
@@ -0,0 +1,120 @@
+/*
+ * 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 <asm/io.h>
+
+#include <mach/pxa27x.h>
+#include <mach/colibri.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/usb-ohci-pxa27x.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 000000000..3aa264640
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri-pxa270-income.c
@@ -0,0 +1,224 @@
+/*
+ * 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 <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/usb-ohci-pxa27x.h>
+#include <mach/pxa27x.h>
+#include <mach/pxa27x-udc.h>
+#include <linux/platform_data/video-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,
+ .enable_gpio = -1,
+};
+
+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 000000000..5f9d9303b
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri-pxa270.c
@@ -0,0 +1,330 @@
+/*
+ * 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/moduleparam.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 = PXA_GPIO_TO_IRQ(GPIO114_COLIBRI_PXA270_ETH_IRQ),
+ .end = PXA_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 = PXA_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")
+ .atag_offset = 0x100,
+ .init_machine = colibri_pxa270_init,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+MACHINE_END
+
+MACHINE_START(INCOME, "Income s.r.o. SH-Dmaster PXA270 SBC")
+ .atag_offset = 0x100,
+ .init_machine = colibri_pxa270_income_init,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+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 000000000..f1a1ac1fb
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri-pxa300.c
@@ -0,0 +1,195 @@
+/*
+ * 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 <linux/platform_data/usb-ohci-pxa27x.h>
+#include <linux/platform_data/video-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 = PXA_GPIO_TO_IRQ(COLIBRI_ETH_IRQ_GPIO),
+ .end = PXA_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")
+ .atag_offset = 0x100,
+ .init_machine = colibri_pxa300_init,
+ .map_io = pxa3xx_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .handle_irq = pxa3xx_handle_irq,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+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 000000000..f6cc8b0ab
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri-pxa320.c
@@ -0,0 +1,265 @@
+/*
+ * 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/pxa320.h>
+#include <mach/colibri.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/usb-ohci-pxa27x.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 = PXA_GPIO_TO_IRQ(COLIBRI_ETH_IRQ_GPIO),
+ .end = PXA_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")
+ .atag_offset = 0x100,
+ .init_machine = colibri_pxa320_init,
+ .map_io = pxa3xx_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .handle_irq = pxa3xx_handle_irq,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+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 000000000..8240291ab
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri-pxa3xx.c
@@ -0,0 +1,153 @@
+/*
+ * 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/system_info.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 <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/mtd-nand-pxa3xx.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,
+ .num_cs = 1,
+ .parts[0] = colibri_nand_partitions,
+ .nr_parts[0] = 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 000000000..89f790dda
--- /dev/null
+++ b/arch/arm/mach-pxa/corgi.c
@@ -0,0 +1,807 @@
+/*
+ * 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/regulator/machine.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 <linux/gpio_keys.h>
+#include <linux/module.h>
+#include <linux/memblock.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/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/pxa25x.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <linux/platform_data/mmc-pxamci.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,
+ },
+};
+
+static struct gpio_keys_button corgi_gpio_keys[] = {
+ {
+ .type = EV_SW,
+ .code = SW_LID,
+ .gpio = CORGI_GPIO_SWA,
+ .desc = "Lid close switch",
+ .debounce_interval = 500,
+ },
+ {
+ .type = EV_SW,
+ .code = SW_TABLET_MODE,
+ .gpio = CORGI_GPIO_SWB,
+ .desc = "Tablet mode switch",
+ .debounce_interval = 500,
+ },
+ {
+ .type = EV_SW,
+ .code = SW_HEADPHONE_INSERT,
+ .gpio = CORGI_GPIO_AK_INT,
+ .desc = "HeadPhone insert",
+ .debounce_interval = 500,
+ },
+};
+
+static struct gpio_keys_platform_data corgi_gpio_keys_platform_data = {
+ .buttons = corgi_gpio_keys,
+ .nbuttons = ARRAY_SIZE(corgi_gpio_keys),
+ .poll_interval = 250,
+};
+
+static struct platform_device corgi_gpio_keys_device = {
+ .name = "gpio-keys-polled",
+ .id = -1,
+ .dev = {
+ .platform_data = &corgi_gpio_keys_platform_data,
+ },
+};
+
+/*
+ * 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,
+ },
+};
+
+/*
+ * Corgi Audio
+ */
+static struct platform_device corgi_audio_device = {
+ .name = "corgi-audio",
+ .id = -1,
+};
+
+/*
+ * 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 IS_ENABLED(CONFIG_SPI_PXA2XX)
+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 = PXA_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,
+ &corgi_gpio_keys_device,
+ &corgikbd_device,
+ &corgiled_device,
+ &corgi_audio_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);
+
+ pxa_restart(REBOOT_HARD, NULL);
+}
+
+static void corgi_restart(enum reboot_mode mode, const char *cmd)
+{
+ if (!machine_is_corgi())
+ /* Green LED on tells the bootloader to reboot */
+ gpio_set_value(CORGI_GPIO_LED_GREEN, 1);
+
+ pxa_restart(REBOOT_HARD, cmd);
+}
+
+static void __init corgi_init(void)
+{
+ pm_power_off = corgi_poweroff;
+
+ /* 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));
+
+ regulator_has_full_constraints();
+}
+
+static void __init fixup_corgi(struct tag *tags, char **cmdline)
+{
+ sharpsl_save_param();
+ if (machine_is_corgi())
+ memblock_add(0xa0000000, SZ_32M);
+ else
+ memblock_add(0xa0000000, SZ_64M);
+}
+
+#ifdef CONFIG_MACH_CORGI
+MACHINE_START(CORGI, "SHARP Corgi")
+ .fixup = fixup_corgi,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .init_machine = corgi_init,
+ .init_time = pxa_timer_init,
+ .restart = corgi_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_SHEPHERD
+MACHINE_START(SHEPHERD, "SHARP Shepherd")
+ .fixup = fixup_corgi,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .init_machine = corgi_init,
+ .init_time = pxa_timer_init,
+ .restart = corgi_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_HUSKY
+MACHINE_START(HUSKY, "SHARP Husky")
+ .fixup = fixup_corgi,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .init_machine = corgi_init,
+ .init_time = pxa_timer_init,
+ .restart = corgi_restart,
+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 000000000..7a39efc50
--- /dev/null
+++ b/arch/arm/mach-pxa/corgi_pm.c
@@ -0,0 +1,231 @@
+/*
+ * 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/gpio-pxa.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/apm-emulation.h>
+#include <linux/io.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_AC_IN, GPIOF_IN, "Charger Detection" },
+ { CORGI_GPIO_KEY_INT, GPIOF_IN, "Key Interrupt" },
+ { CORGI_GPIO_WAKEUP, GPIOF_IN, "System wakeup notification" },
+};
+
+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, "PEDR = %x, GPIO_AC_IN = %d, "
+ "GPIO_CHRG_FULL = %d, GPIO_KEY_INT = %d, GPIO_WAKEUP = %d\n",
+ PEDR, gpio_get_value(CORGI_GPIO_AC_IN),
+ gpio_get_value(CORGI_GPIO_CHRG_FULL),
+ gpio_get_value(CORGI_GPIO_KEY_INT),
+ gpio_get_value(CORGI_GPIO_WAKEUP));
+
+ 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)
+{
+ unsigned long ret;
+
+ ret = (!gpio_get_value(CORGI_GPIO_AC_IN) << GPIO_bit(CORGI_GPIO_AC_IN))
+ | (!gpio_get_value(CORGI_GPIO_KEY_INT)
+ << GPIO_bit(CORGI_GPIO_KEY_INT))
+ | (!gpio_get_value(CORGI_GPIO_WAKEUP)
+ << GPIO_bit(CORGI_GPIO_WAKEUP));
+ return ret;
+}
+
+unsigned long corgipm_read_devdata(int type)
+{
+ switch(type) {
+ case SHARPSL_STATUS_ACIN:
+ return !gpio_get_value(CORGI_GPIO_AC_IN);
+ 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 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/csb701.c b/arch/arm/mach-pxa/csb701.c
new file mode 100644
index 000000000..5a221a49e
--- /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 000000000..fadfff8fe
--- /dev/null
+++ b/arch/arm/mach-pxa/csb726.c
@@ -0,0 +1,283 @@
+/*
+ * 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/pxa27x.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/usb-ohci-pxa27x.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")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_machine = csb726_init,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
new file mode 100644
index 000000000..35434662d
--- /dev/null
+++ b/arch/arm/mach-pxa/devices.c
@@ -0,0 +1,1195 @@
+#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 <mach/udc.h>
+#include <linux/platform_data/usb-pxa3xx-ulpi.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <mach/irqs.h>
+#include <linux/platform_data/usb-ohci-pxa27x.h>
+#include <linux/platform_data/keypad-pxa27x.h>
+#include <linux/platform_data/camera-pxa.h>
+#include <mach/audio.h>
+#include <mach/hardware.h>
+#include <linux/platform_data/mtd-nand-pxa3xx.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 = "xscale-pmu",
+ .id = -1,
+ .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;
+
+static struct resource pxa_ir_resources[] = {
+ [0] = {
+ .start = IRQ_STUART,
+ .end = IRQ_STUART,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = IRQ_ICP,
+ .end = IRQ_ICP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa_device_ficp = {
+ .name = "pxa2xx-ir",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pxa_ir_resources),
+ .resource = pxa_ir_resources,
+ .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,
+ .name = "rtc 1Hz",
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_RTCAlrm,
+ .end = IRQ_RTCAlrm,
+ .name = "rtc alarm",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+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 sa1100_rtc_resources[] = {
+ {
+ .start = IRQ_RTC1Hz,
+ .end = IRQ_RTC1Hz,
+ .name = "rtc 1Hz",
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = IRQ_RTCAlrm,
+ .end = IRQ_RTCAlrm,
+ .name = "rtc alarm",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device sa1100_device_rtc = {
+ .name = "sa1100-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(sa1100_rtc_resources),
+ .resource = sa1100_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)
+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 */
+
+#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)
+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,
+ },
+};
+
+/*
+ * PXA3xx SSP is basically equivalent to PXA27x.
+ * However, we need to register the device by the correct name in order to
+ * make the driver set the correct internal type, hence we provide specific
+ * platform_devices for each of them.
+ */
+struct platform_device pxa3xx_device_ssp1 = {
+ .name = "pxa3xx-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),
+};
+
+struct platform_device pxa3xx_device_ssp2 = {
+ .name = "pxa3xx-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),
+};
+
+struct platform_device pxa3xx_device_ssp3 = {
+ .name = "pxa3xx-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),
+};
+
+struct platform_device pxa3xx_device_ssp4 = {
+ .name = "pxa3xx-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 */
+
+struct resource pxa_resource_gpio[] = {
+ {
+ .start = 0x40e00000,
+ .end = 0x40e0ffff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_GPIO0,
+ .end = IRQ_GPIO0,
+ .name = "gpio0",
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = IRQ_GPIO1,
+ .end = IRQ_GPIO1,
+ .name = "gpio1",
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = IRQ_GPIO_2_x,
+ .end = IRQ_GPIO_2_x,
+ .name = "gpio_mux",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa25x_device_gpio = {
+#ifdef CONFIG_CPU_PXA26x
+ .name = "pxa26x-gpio",
+#else
+ .name = "pxa25x-gpio",
+#endif
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pxa_resource_gpio),
+ .resource = pxa_resource_gpio,
+};
+
+struct platform_device pxa27x_device_gpio = {
+ .name = "pxa27x-gpio",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pxa_resource_gpio),
+ .resource = pxa_resource_gpio,
+};
+
+struct platform_device pxa3xx_device_gpio = {
+ .name = "pxa3xx-gpio",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pxa_resource_gpio),
+ .resource = pxa_resource_gpio,
+};
+
+struct platform_device pxa93x_device_gpio = {
+ .name = "pxa93x-gpio",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pxa_resource_gpio),
+ .resource = pxa_resource_gpio,
+};
+
+/* 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 000000000..4a13c32fb
--- /dev/null
+++ b/arch/arm/mach-pxa/devices.h
@@ -0,0 +1,56 @@
+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_ssp1;
+extern struct platform_device pxa3xx_device_ssp2;
+extern struct platform_device pxa3xx_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;
+
+extern struct platform_device pxa25x_device_gpio;
+extern struct platform_device pxa27x_device_gpio;
+extern struct platform_device pxa3xx_device_gpio;
+extern struct platform_device pxa93x_device_gpio;
+
+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 000000000..51531ecff
--- /dev/null
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -0,0 +1,1331 @@
+/*
+ * 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/platform_data/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 <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/usb-ohci-pxa27x.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/keypad-pxa27x.h>
+#include <linux/platform_data/camera-pxa.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 PXA_GPIO_TO_IRQ(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
+ },
+};
+
+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,
+ },
+ .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_warn("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_warn("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);
+ err = regulator_enable(em_x270_usb_ldo);
+ if (err)
+ goto err_free_rst_gpio;
+
+ gpio_set_value(usb_hub_reset, 0);
+ gpio_set_value(usb_hub_reset, 1);
+ regulator_disable(em_x270_usb_ldo);
+ err = regulator_enable(em_x270_usb_ldo);
+ if (err)
+ goto err_free_rst_gpio;
+
+ gpio_set_value(usb_hub_reset, 0);
+ gpio_set_value(GPIO9_USB_VBUS_EN, 1);
+
+ return 0;
+
+err_free_rst_gpio:
+ gpio_free(usb_hub_reset);
+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_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 int 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);
+ return regulator_enable(em_x270_sdio_ldo);
+ } else {
+ regulator_disable(em_x270_sdio_ldo);
+ }
+ return 0;
+}
+
+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 = PXA_GPIO_TO_IRQ(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 const 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),
+};
+
+static struct matrix_keymap_data em_x270_matrix_keymap_data = {
+ .keymap = em_x270_module_matrix_keys,
+ .keymap_size = ARRAY_SIZE(em_x270_module_matrix_keys),
+};
+
+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_keymap_data = &em_x270_matrix_keymap_data,
+};
+
+static const 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),
+};
+
+static struct matrix_keymap_data em_x270_exeda_matrix_keymap_data = {
+ .keymap = em_x270_exeda_matrix_keys,
+ .keymap_size = ARRAY_SIZE(em_x270_exeda_matrix_keys),
+};
+
+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_keymap_data = &em_x270_exeda_matrix_keymap_data,
+};
+
+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_name, _supply) \
+ static struct regulator_consumer_supply _name##_consumers[] = { \
+ REGULATOR_SUPPLY(_supply, _dev_name), \
+ }
+
+REGULATOR_CONSUMER(ldo3, "reg-userspace-consumer.0", "vcc gps");
+REGULATOR_CONSUMER(ldo5, NULL, "vcc cam");
+REGULATOR_CONSUMER(ldo10, "pxa2xx-mci", "vcc sdio");
+REGULATOR_CONSUMER(ldo12, NULL, "vcc usb");
+REGULATOR_CONSUMER(ldo19, "reg-userspace-consumer.1", "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 = PXA_GPIO_TO_IRQ(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")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = em_x270_init,
+ .restart = pxa_restart,
+MACHINE_END
+
+MACHINE_START(EXEDA, "Compulab eXeda")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = em_x270_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
new file mode 100644
index 000000000..cfb864173
--- /dev/null
+++ b/arch/arm/mach-pxa/eseries.c
@@ -0,0 +1,982 @@
+/*
+ * 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 <linux/memblock.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 <linux/platform_data/video-pxafb.h>
+#include <mach/udc.h>
+#include <linux/platform_data/irda-pxaficp.h>
+
+#include "devices.h"
+#include "generic.h"
+#include "clock.h"
+
+/* Only e800 has 128MB RAM */
+void __init eseries_fixup(struct tag *tags, char **cmdline)
+{
+ if (machine_is_e800())
+ memblock_add(0xa0000000, SZ_128M);
+ else
+ memblock_add(0xa0000000, SZ_64M);
+}
+
+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 = PXA_GPIO_TO_IRQ(GPIO_ESERIES_TMIO_IRQ),
+ .end = PXA_GPIO_TO_IRQ(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"),
+};
+
+static void __init 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) */
+ .atag_offset = 0x100,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .fixup = eseries_fixup,
+ .init_machine = e330_init,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+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) */
+ .atag_offset = 0x100,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .fixup = eseries_fixup,
+ .init_machine = e350_init,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+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) */
+ .atag_offset = 0x100,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .fixup = eseries_fixup,
+ .init_machine = e400_init,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+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_audio_device = {
+ .name = "e740-audio",
+ .id = -1,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static struct platform_device *e740_devices[] __initdata = {
+ &e740_fb_device,
+ &e740_t7l66xb_device,
+ &e7xx_gpio_vbus,
+ &e740_audio_device,
+};
+
+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) */
+ .atag_offset = 0x100,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .fixup = eseries_fixup,
+ .init_machine = e740_init,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+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_audio_device = {
+ .name = "e750-audio",
+ .id = -1,
+};
+
+/* ------------------------------------------------------------- */
+
+static struct platform_device *e750_devices[] __initdata = {
+ &e750_fb_device,
+ &e750_tc6393xb_device,
+ &e7xx_gpio_vbus,
+ &e750_audio_device,
+};
+
+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) */
+ .atag_offset = 0x100,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .fixup = eseries_fixup,
+ .init_machine = e750_init,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+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_audio_device = {
+ .name = "e800-audio",
+ .id = -1,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static struct platform_device *e800_devices[] __initdata = {
+ &e800_fb_device,
+ &e800_tc6393xb_device,
+ &e800_gpio_vbus,
+ &e800_audio_device,
+};
+
+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) */
+ .atag_offset = 0x100,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .fixup = eseries_fixup,
+ .init_machine = e800_init,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c
new file mode 100644
index 000000000..ab93441e5
--- /dev/null
+++ b/arch/arm/mach-pxa/ezx.c
@@ -0,0 +1,1268 @@
+/*
+ * 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 <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/usb-ohci-pxa27x.h>
+#include <mach/hardware.h>
+#include <linux/platform_data/keypad-pxa27x.h>
+#include <linux/platform_data/camera-pxa.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,
+ .enable_gpio = -1,
+};
+
+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 const 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 matrix_keymap_data a780_matrix_keymap_data = {
+ .keymap = a780_key_map,
+ .keymap_size = ARRAY_SIZE(a780_key_map),
+};
+
+static struct pxa27x_keypad_platform_data a780_keypad_platform_data = {
+ .matrix_key_rows = 5,
+ .matrix_key_cols = 5,
+ .matrix_keymap_data = &a780_matrix_keymap_data,
+
+ .direct_key_map = { KEY_CAMERA },
+ .direct_key_num = 1,
+
+ .debounce_interval = 30,
+};
+#endif /* CONFIG_MACH_EZX_A780 */
+
+#ifdef CONFIG_MACH_EZX_E680
+static const 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 matrix_keymap_data e680_matrix_keymap_data = {
+ .keymap = e680_key_map,
+ .keymap_size = ARRAY_SIZE(e680_key_map),
+};
+
+static struct pxa27x_keypad_platform_data e680_keypad_platform_data = {
+ .matrix_key_rows = 3,
+ .matrix_key_cols = 4,
+ .matrix_keymap_data = &e680_matrix_keymap_data,
+
+ .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 const 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 matrix_keymap_data a1200_matrix_keymap_data = {
+ .keymap = a1200_key_map,
+ .keymap_size = ARRAY_SIZE(a1200_key_map),
+};
+
+static struct pxa27x_keypad_platform_data a1200_keypad_platform_data = {
+ .matrix_key_rows = 5,
+ .matrix_key_cols = 6,
+ .matrix_keymap_data = &a1200_matrix_keymap_data,
+
+ .debounce_interval = 30,
+};
+#endif /* CONFIG_MACH_EZX_A1200 */
+
+#ifdef CONFIG_MACH_EZX_E6
+static const 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 matrix_keymap_data e6_keymap_data = {
+ .keymap = e6_key_map,
+ .keymap_size = ARRAY_SIZE(e6_key_map),
+};
+
+static struct pxa27x_keypad_platform_data e6_keypad_platform_data = {
+ .matrix_key_rows = 5,
+ .matrix_key_cols = 6,
+ .matrix_keymap_data = &e6_keymap_data,
+
+ .debounce_interval = 30,
+};
+#endif /* CONFIG_MACH_EZX_E6 */
+
+#ifdef CONFIG_MACH_EZX_A910
+static const 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 matrix_keymap_data a910_matrix_keymap_data = {
+ .keymap = a910_key_map,
+ .keymap_size = ARRAY_SIZE(a910_key_map),
+};
+
+static struct pxa27x_keypad_platform_data a910_keypad_platform_data = {
+ .matrix_key_rows = 5,
+ .matrix_key_cols = 6,
+ .matrix_keymap_data = &a910_matrix_keymap_data,
+
+ .debounce_interval = 30,
+};
+#endif /* CONFIG_MACH_EZX_A910 */
+
+#ifdef CONFIG_MACH_EZX_E2
+static const 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 matrix_keymap_data e2_matrix_keymap_data = {
+ .keymap = e2_key_map,
+ .keymap_size = ARRAY_SIZE(e2_key_map),
+};
+
+static struct pxa27x_keypad_platform_data e2_keypad_platform_data = {
+ .matrix_key_rows = 5,
+ .matrix_key_cols = 6,
+ .matrix_keymap_data = &e2_matrix_keymap_data,
+
+ .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")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = EZX_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = a780_init,
+ .restart = pxa_restart,
+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")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = EZX_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = e680_init,
+ .restart = pxa_restart,
+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")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = EZX_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = a1200_init,
+ .restart = pxa_restart,
+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")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = EZX_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = a910_init,
+ .restart = pxa_restart,
+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")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = EZX_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = e6_init,
+ .restart = pxa_restart,
+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")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = EZX_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = e2_init,
+ .restart = pxa_restart,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
new file mode 100644
index 000000000..04b013fbc
--- /dev/null
+++ b/arch/arm/mach-pxa/generic.c
@@ -0,0 +1,104 @@
+/*
+ * 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/gpio.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+
+#include <mach/irqs.h>
+#include <mach/reset.h>
+#include <mach/smemc.h>
+#include <mach/pxa3xx-regs.h>
+
+#include "generic.h"
+#include <clocksource/pxa.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);
+
+/*
+ * For non device-tree builds, keep legacy timer init
+ */
+void __init pxa_timer_init(void)
+{
+ pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x40a00000),
+ 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 = (unsigned long)PERIPH_VIRT,
+ .pfn = __phys_to_pfn(PERIPH_PHYS),
+ .length = PERIPH_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+void __init pxa_map_io(void)
+{
+ debug_ll_io_init();
+ 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 000000000..7a9fa1aa4
--- /dev/null
+++ b/arch/arm/mach-pxa/generic.h
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+#include <linux/reboot.h>
+
+struct irq_data;
+
+extern unsigned int get_clk_frequency_khz(int info);
+extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *,
+ unsigned int));
+extern void __init pxa_map_io(void);
+extern void pxa_timer_init(void);
+
+#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)
+
+#define pxa25x_handle_irq icip_handle_irq
+extern void __init pxa25x_init_irq(void);
+extern void __init pxa25x_map_io(void);
+extern void __init pxa26x_init_irq(void);
+
+#define pxa27x_handle_irq ichp_handle_irq
+extern void __init pxa27x_dt_init_irq(void);
+extern unsigned pxa27x_get_clk_frequency_khz(int);
+extern void __init pxa27x_init_irq(void);
+extern void __init pxa27x_map_io(void);
+
+#define pxa3xx_handle_irq ichp_handle_irq
+extern void __init pxa3xx_dt_init_irq(void);
+extern void __init pxa3xx_init_irq(void);
+extern void __init pxa3xx_map_io(void);
+
+extern struct syscore_ops pxa_irq_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);
+
+void pxa_restart(enum reboot_mode, const char *);
+
+#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
+
+/*
+ * Once fully converted to the clock framework, all these functions should be
+ * removed, and replaced with a clk_get(NULL, "core").
+ */
+#ifdef CONFIG_PXA25x
+extern unsigned pxa25x_get_clk_frequency_khz(int);
+#else
+#define pxa25x_get_clk_frequency_khz(x) (0)
+#endif
+
+#ifdef CONFIG_PXA27x
+#else
+#define pxa27x_get_clk_frequency_khz(x) (0)
+#endif
+
+#ifdef CONFIG_PXA3xx
+extern unsigned pxa3xx_get_clk_frequency_khz(int);
+#else
+#define pxa3xx_get_clk_frequency_khz(x) (0)
+#endif
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c
new file mode 100644
index 000000000..f6c76a3ee
--- /dev/null
+++ b/arch/arm/mach-pxa/gumstix.c
@@ -0,0 +1,243 @@
+/*
+ * 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 <linux/platform_data/mmc-pxamci.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_warn("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")
+ .atag_offset = 0x100, /* match u-boot bi_boot_params */
+ .map_io = pxa25x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = gumstix_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/h5000.c b/arch/arm/mach-pxa/h5000.c
new file mode 100644
index 000000000..875ec3351
--- /dev/null
+++ b/arch/arm/mach-pxa/h5000.c
@@ -0,0 +1,214 @@
+/*
+ * 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 <asm/irq.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")
+ .atag_offset = 0x100,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = h5000_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/himalaya.c b/arch/arm/mach-pxa/himalaya.c
new file mode 100644
index 000000000..7a8d749a0
--- /dev/null
+++ b/arch/arm/mach-pxa/himalaya.c
@@ -0,0 +1,169 @@
+/*
+ * 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/pxa25x.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")
+ .atag_offset = 0x100,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .init_machine = himalaya_init,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
new file mode 100644
index 000000000..5fb41ad6e
--- /dev/null
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -0,0 +1,909 @@
+/*
+ * 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/input/navpoint.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.h>
+#include <linux/pwm_backlight.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/gpio-regulator.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 <linux/platform_data/irda-pxaficp.h>
+
+#include <sound/ak4641.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_LPM_LOW,
+ GPIO44_BTUART_CTS,
+ GPIO45_BTUART_RTS_LPM_LOW,
+
+ /* STUART (IRDA) */
+ GPIO46_STUART_RXD,
+ GPIO47_STUART_TXD,
+
+ /* 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_IN,
+ GPIO24_SSP1_SFRM,
+ GPIO25_SSP1_TXD,
+ GPIO26_SSP1_RXD,
+
+ /* SSP 2 (TSC2046) */
+ GPIO19_SSP2_SCLK,
+ GPIO86_SSP2_RXD,
+ GPIO87_SSP2_TXD,
+ GPIO88_GPIO | MFP_LPM_DRIVE_HIGH, /* TSC2046_CS */
+
+ /* BQ24022 Regulator */
+ GPIO72_GPIO | MFP_LPM_KEEP_OUTPUT, /* BQ24022_nCHARGE_EN */
+ GPIO96_GPIO | MFP_LPM_KEEP_OUTPUT, /* BQ24022_ISET2 */
+
+ /* HX4700 specific input GPIOs */
+ GPIO12_GPIO | WAKEUP_ON_EDGE_RISE, /* ASIC3_IRQ */
+ GPIO13_GPIO, /* W3220_IRQ */
+ GPIO14_GPIO, /* nWLAN_IRQ */
+
+ /* HX4700 specific output GPIOs */
+ GPIO61_GPIO | MFP_LPM_DRIVE_HIGH, /* W3220_nRESET */
+ GPIO71_GPIO | MFP_LPM_DRIVE_HIGH, /* ASIC3_nRESET */
+ GPIO81_GPIO | MFP_LPM_DRIVE_HIGH, /* CPU_GP_nRESET */
+ GPIO116_GPIO | MFP_LPM_DRIVE_HIGH, /* CPU_HW_nRESET */
+ GPIO102_GPIO | MFP_LPM_DRIVE_LOW, /* SYNAPTICS_POWER_ON */
+
+ GPIO10_GPIO, /* GSM_IRQ */
+ GPIO13_GPIO, /* CPLD_IRQ */
+ GPIO107_GPIO, /* DS1WM_IRQ */
+ GPIO108_GPIO, /* GSM_READY */
+ GPIO58_GPIO, /* TSC2046_nPENIRQ */
+ GPIO66_GPIO, /* nSDIO_IRQ */
+};
+
+/*
+ * 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,
+};
+
+/*
+ * Synaptics NavPoint connected to SSP1
+ */
+
+static struct navpoint_platform_data navpoint_platform_data = {
+ .port = 1,
+ .gpio = GPIO102_HX4700_SYNAPTICS_POWER_ON,
+};
+
+static struct platform_device navpoint = {
+ .name = "navpoint",
+ .id = -1,
+ .dev = {
+ .platform_data = &navpoint_platform_data,
+ },
+};
+
+/*
+ * 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_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_GPIOD4_CF_nCD,
+ ASIC3_GPIOD11_nCIOIS16,
+ ASIC3_GPIOD12_nCWAIT,
+ ASIC3_GPIOD15_nPIOW,
+};
+
+static struct asic3_led asic3_leds[ASIC3_NUM_LEDS] = {
+ [0] = {
+ .name = "hx4700:amber",
+ .default_trigger = "ds2760-battery.0-charging-blink-full-solid",
+ },
+ [1] = {
+ .name = "hx4700:green",
+ .default_trigger = "unused",
+ },
+ [2] = {
+ .name = "hx4700:blue",
+ .default_trigger = "hx4700-radio",
+ },
+};
+
+static struct resource asic3_resources[] = {
+ /* GPIO part */
+ [0] = DEFINE_RES_MEM(ASIC3_PHYS, ASIC3_MAP_SIZE_16BIT),
+ [1] = DEFINE_RES_IRQ(PXA_GPIO_TO_IRQ(GPIO12_HX4700_ASIC3_IRQ)),
+ /* SD part */
+ [2] = DEFINE_RES_MEM(ASIC3_SD_PHYS, ASIC3_MAP_SIZE_16BIT),
+ [3] = DEFINE_RES_IRQ(PXA_GPIO_TO_IRQ(GPIO66_HX4700_ASIC3_nSDIO_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,
+ .clock_rate = 4000000,
+ .leds = asic3_leds,
+};
+
+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] = DEFINE_RES_MEM(PXA_CS5_PHYS, 0x4),
+};
+
+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] = DEFINE_RES_MEM(ATI_W3220_PHYS, SZ_16M),
+};
+
+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, /* Superseded by pwm_lookup */
+ .max_brightness = 200,
+ .dft_brightness = 100,
+ .pwm_period_ns = 30923,
+ .enable_gpio = -1,
+};
+
+static struct platform_device backlight = {
+ .name = "pwm-backlight",
+ .id = -1,
+ .dev = {
+ .parent = &pxa27x_device_pwm1.dev,
+ .platform_data = &backlight_data,
+ },
+};
+
+static struct pwm_lookup hx4700_pwm_lookup[] = {
+ PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight", NULL,
+ 30923, PWM_POLARITY_NORMAL),
+};
+
+/*
+ * 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 = PXA_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] = DEFINE_RES_NAMED(PXA_GPIO_TO_IRQ(GPIOD9_nAC_IN), 1, "ac",
+ IORESOURCE_IRQ |
+ IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE),
+ [1] = DEFINE_RES_NAMED(PXA_GPIO_TO_IRQ(GPIOD14_nUSBC_DETECT), 1, "usb",
+ IORESOURCE_IRQ |
+ IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE),
+};
+
+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[] = {
+ REGULATOR_SUPPLY("vbus_draw", NULL),
+ REGULATOR_SUPPLY("ac_draw", NULL),
+};
+
+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 gpio bq24022_gpios[] = {
+ { GPIO96_HX4700_BQ24022_ISET2, GPIOF_OUT_INIT_LOW, "bq24022_iset2" },
+};
+
+static struct gpio_regulator_state bq24022_states[] = {
+ { .value = 100000, .gpios = (0 << 0) },
+ { .value = 500000, .gpios = (1 << 0) },
+};
+
+static struct gpio_regulator_config bq24022_info = {
+ .supply_name = "bq24022",
+
+ .enable_gpio = GPIO72_HX4700_BQ24022_nCHARGE_EN,
+ .enable_high = 0,
+ .enabled_at_boot = 0,
+
+ .gpios = bq24022_gpios,
+ .nr_gpios = ARRAY_SIZE(bq24022_gpios),
+
+ .states = bq24022_states,
+ .nr_states = ARRAY_SIZE(bq24022_states),
+
+ .type = REGULATOR_CURRENT,
+ .init_data = &bq24022_init_data,
+};
+
+static struct platform_device bq24022 = {
+ .name = "gpio-regulator",
+ .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[] = {
+ [0] = DEFINE_RES_MEM(PXA_CS0_PHYS, SZ_64M),
+ [1] = DEFINE_RES_MEM(PXA_CS0_PHYS + SZ_64M, SZ_64M),
+};
+
+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 = ARRAY_SIZE(strataflash_resource),
+ .dev = {
+ .platform_data = &strataflash_data,
+ },
+};
+
+/*
+ * Maxim MAX1587A on PI2C
+ */
+
+static struct regulator_consumer_supply max1587a_consumer =
+ REGULATOR_SUPPLY("vcc_core", NULL);
+
+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,
+ },
+};
+
+/*
+ * Asahi Kasei AK4641 on I2C
+ */
+
+static struct ak4641_platform_data ak4641_info = {
+ .gpio_power = GPIO27_HX4700_CODEC_ON,
+ .gpio_npdn = GPIO109_HX4700_CODEC_nPDN,
+};
+
+static struct i2c_board_info i2c_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("ak4641", 0x12),
+ .platform_data = &ak4641_info,
+ },
+};
+
+static struct platform_device audio = {
+ .name = "hx4700-audio",
+ .id = -1,
+};
+
+
+/*
+ * Platform devices
+ */
+
+static struct platform_device *devices[] __initdata = {
+ &asic3,
+ &gpio_keys,
+ &navpoint,
+ &backlight,
+ &w3220,
+ &hx4700_lcd,
+ &egpio,
+ &bq24022,
+ &gpio_vbus,
+ &power_supply,
+ &strataflash,
+ &audio,
+};
+
+static struct gpio global_gpios[] = {
+ { GPIO12_HX4700_ASIC3_IRQ, GPIOF_IN, "ASIC3_IRQ" },
+ { GPIO13_HX4700_W3220_IRQ, GPIOF_IN, "W3220_IRQ" },
+ { GPIO14_HX4700_nWLAN_IRQ, GPIOF_IN, "WLAN_IRQ" },
+ { GPIO59_HX4700_LCD_PC1, GPIOF_OUT_INIT_HIGH, "LCD_PC1" },
+ { GPIO62_HX4700_LCD_nRESET, GPIOF_OUT_INIT_HIGH, "LCD_RESET" },
+ { GPIO70_HX4700_LCD_SLIN1, GPIOF_OUT_INIT_HIGH, "LCD_SLIN1" },
+ { GPIO84_HX4700_LCD_SQN, GPIOF_OUT_INIT_HIGH, "LCD_SQN" },
+ { GPIO110_HX4700_LCD_LVDD_3V3_ON, GPIOF_OUT_INIT_HIGH, "LCD_LVDD" },
+ { GPIO111_HX4700_LCD_AVDD_3V3_ON, GPIOF_OUT_INIT_HIGH, "LCD_AVDD" },
+ { GPIO32_HX4700_RS232_ON, GPIOF_OUT_INIT_HIGH, "RS232_ON" },
+ { GPIO61_HX4700_W3220_nRESET, GPIOF_OUT_INIT_HIGH, "W3220_nRESET" },
+ { GPIO71_HX4700_ASIC3_nRESET, GPIOF_OUT_INIT_HIGH, "ASIC3_nRESET" },
+ { GPIO81_HX4700_CPU_GP_nRESET, GPIOF_OUT_INIT_HIGH, "CPU_GP_nRESET" },
+ { GPIO82_HX4700_EUART_RESET, GPIOF_OUT_INIT_HIGH, "EUART_RESET" },
+ { GPIO116_HX4700_CPU_HW_nRESET, GPIOF_OUT_INIT_HIGH, "CPU_HW_nRESET" },
+};
+
+static void __init hx4700_init(void)
+{
+ int ret;
+
+ PCFR = PCFR_GPR_EN | PCFR_OPDE;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(hx4700_pin_config));
+ gpio_set_wake(GPIO12_HX4700_ASIC3_IRQ, 1);
+ ret = gpio_request_array(ARRAY_AND_SIZE(global_gpios));
+ if (ret)
+ pr_err ("hx4700: Failed to request GPIOs.\n");
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup));
+
+ pxa_set_ficp_info(&ficp_info);
+ pxa27x_set_i2c_power_info(NULL);
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(i2c_board_info));
+ 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);
+
+ regulator_has_full_constraints();
+}
+
+MACHINE_START(H4700, "HP iPAQ HX4700")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = HX4700_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_machine = hx4700_init,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c
new file mode 100644
index 000000000..c98511c5a
--- /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,
+};
+
+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 = PXA_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 = PXA_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 = PXA_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 = PXA_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")
+ .atag_offset = 0x100,
+ .map_io = pxa3xx_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .handle_irq = pxa3xx_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = icontrol_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
new file mode 100644
index 000000000..f6d02e4cb
--- /dev/null
+++ b/arch/arm/mach-pxa/idp.c
@@ -0,0 +1,291 @@
+/*
+ * 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 <linux/platform_data/video-pxafb.h>
+#include <mach/bitfield.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/smc91x.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 = PXA_GPIO_TO_IRQ(4),
+ .end = PXA_GPIO_TO_IRQ(4),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct smc91x_platdata smc91x_platdata = {
+ .flags = SMC91X_USE_32BIT | SMC91X_USE_DMA | SMC91X_NOWAIT,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+ .dev.platform_data = &smc91x_platdata,
+};
+
+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));
+}
+
+/* LEDs */
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+struct idp_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;
+} idp_leds[] = {
+ { "idp:green", "heartbeat", },
+ { "idp:red", "cpu0", },
+};
+
+static void idp_led_set(struct led_classdev *cdev,
+ enum led_brightness b)
+{
+ struct idp_led *led = container_of(cdev,
+ struct idp_led, cdev);
+ u32 reg = IDP_CPLD_LED_CONTROL;
+
+ if (b != LED_OFF)
+ reg &= ~led->mask;
+ else
+ reg |= led->mask;
+
+ IDP_CPLD_LED_CONTROL = reg;
+}
+
+static enum led_brightness idp_led_get(struct led_classdev *cdev)
+{
+ struct idp_led *led = container_of(cdev,
+ struct idp_led, cdev);
+
+ return (IDP_CPLD_LED_CONTROL & led->mask) ? LED_OFF : LED_FULL;
+}
+
+static int __init idp_leds_init(void)
+{
+ int i;
+
+ if (!machine_is_pxa_idp())
+ return -ENODEV;
+
+ for (i = 0; i < ARRAY_SIZE(idp_leds); i++) {
+ struct idp_led *led;
+
+ led = kzalloc(sizeof(*led), GFP_KERNEL);
+ if (!led)
+ break;
+
+ led->cdev.name = idp_leds[i].name;
+ led->cdev.brightness_set = idp_led_set;
+ led->cdev.brightness_get = idp_led_get;
+ led->cdev.default_trigger = idp_leds[i].trigger;
+
+ if (i == 0)
+ led->mask = IDP_HB_LED;
+ else
+ led->mask = IDP_BUSY_LED;
+
+ 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(idp_leds_init);
+#endif
+
+MACHINE_START(PXA_IDP, "Vibren PXA255 IDP")
+ /* Maintainer: Vibren Technologies */
+ .map_io = idp_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = idp_init,
+ .restart = pxa_restart,
+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 000000000..d28fe2912
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/addr-map.h
@@ -0,0 +1,53 @@
+#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 IOMEM(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 IOMEM(0xf6000000)
+#define SMEMC_SIZE 0x00100000
+
+/*
+ * Dynamic Memory Controller (only on PXA3xx)
+ */
+#define DMEMC_PHYS 0x48100000
+#define DMEMC_VIRT IOMEM(0xf6100000)
+#define DMEMC_SIZE 0x00100000
+
+/*
+ * Reserved space for low level debug virtual addresses within
+ * 0xf6200000..0xf6201000
+ */
+
+/*
+ * Internal Memory Controller (PXA27x and later)
+ */
+#define IMEMC_PHYS 0x58000000
+#define IMEMC_VIRT IOMEM(0xfe000000)
+#define IMEMC_SIZE 0x00100000
+
+#endif /* __ASM_MACH_ADDR_MAP_H */
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 000000000..a3449e35a
--- /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 000000000..1b0825911
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/balloon3.h
@@ -0,0 +1,184 @@
+/*
+ * 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
+
+#include "irqs.h" /* PXA_NR_BUILTIN_GPIO */
+
+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 IOMEM(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 PXA_GPIO_TO_IRQ(BALLOON3_GPIO_AUX_NIRQ)
+#define BALLOON3_CODEC_IRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_CODEC_IRQ)
+
+#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 000000000..f1f0e3387
--- /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/colibri.h b/arch/arm/mach-pxa/include/mach/colibri.h
new file mode 100644
index 000000000..cb4236e98
--- /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 000000000..c030d955b
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/corgi.h
@@ -0,0 +1,114 @@
+/*
+ * 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
+
+#include "irqs.h" /* PXA_NR_BUILTIN_GPIO */
+
+/*
+ * 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 Transceiver */
+#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 PXA_GPIO_TO_IRQ(0)
+#define CORGI_IRQ_GPIO_AC_IN PXA_GPIO_TO_IRQ(1)
+#define CORGI_IRQ_GPIO_WAKEUP PXA_GPIO_TO_IRQ(3)
+#define CORGI_IRQ_GPIO_AK_INT PXA_GPIO_TO_IRQ(4)
+#define CORGI_IRQ_GPIO_TP_INT PXA_GPIO_TO_IRQ(5)
+#define CORGI_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(9)
+#define CORGI_IRQ_GPIO_nSD_INT PXA_GPIO_TO_IRQ(10)
+#define CORGI_IRQ_GPIO_MAIN_BAT_LOW PXA_GPIO_TO_IRQ(11)
+#define CORGI_IRQ_GPIO_CF_CD PXA_GPIO_TO_IRQ(14)
+#define CORGI_IRQ_GPIO_CHRG_FULL PXA_GPIO_TO_IRQ(16) /* Battery fully charged */
+#define CORGI_IRQ_GPIO_CF_IRQ PXA_GPIO_TO_IRQ(17)
+#define CORGI_IRQ_GPIO_KEY_SENSE(a) PXA_GPIO_TO_IRQ(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 (PXA_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 000000000..00cfbbbf7
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/csb726.h
@@ -0,0 +1,28 @@
+/*
+ * 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
+
+#include "irqs.h" /* PXA_GPIO_TO_IRQ */
+
+#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 PXA_GPIO_TO_IRQ(CSB726_GPIO_IRQ_LAN)
+#define CSB726_IRQ_SM501 PXA_GPIO_TO_IRQ(CSB726_GPIO_IRQ_SM501)
+
+#endif
+
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 000000000..5bd55894a
--- /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/eseries-gpio.h b/arch/arm/mach-pxa/include/mach/eseries-gpio.h
new file mode 100644
index 000000000..f3e550982
--- /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 000000000..de292b269
--- /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/generic.h b/arch/arm/mach-pxa/include/mach/generic.h
new file mode 100644
index 000000000..665542e0c
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/generic.h
@@ -0,0 +1 @@
+#include "../../generic.h"
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 000000000..f7df27bbb
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/gumstix.h
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+#include "irqs.h" /* PXA_GPIO_TO_IRQ */
+
+/* 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 PXA_GPIO_TO_IRQ(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 PXA_GPIO_TO_IRQ(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 PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_ETH0)
+#define GPIO_GUMSTIX_ETH1 27
+#define GPIO_GUMSTIX_ETH1_MD (GPIO_GUMSTIX_ETH1 | GPIO_IN)
+#define GUMSTIX_ETH1_IRQ PXA_GPIO_TO_IRQ(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 PXA_GPIO_TO_IRQ(GPIO4_nSTSCHG)
+#define GUMSTIX_S0_nCD_IRQ PXA_GPIO_TO_IRQ(GPIO11_nCD)
+#define GUMSTIX_S0_PRDY_nBSY_IRQ PXA_GPIO_TO_IRQ(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 PXA_GPIO_TO_IRQ(GPIO18_nSTSCHG)
+#define GUMSTIX_S1_nCD_IRQ PXA_GPIO_TO_IRQ(GPIO36_nCD)
+#define GUMSTIX_S1_PRDY_nBSY_IRQ PXA_GPIO_TO_IRQ(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 000000000..2a5ae3802
--- /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 000000000..8d63c211b
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/hardware.h
@@ -0,0 +1,310 @@
+/*
+ * 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 0xfe000000
+#define UNCACHED_PHYS_0_SIZE 0x00100000
+
+/*
+ * 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_v2p(x) (0x3c000000 + ((x) & 0x01ffffff) + (((x) & 0x0e000000) << 1))
+#define io_p2v(x) IOMEM(0xf2000000 + ((x) & 0x01ffffff) + (((x) & 0x1c000000) >> 1))
+
+#ifndef __ASSEMBLY__
+# define __REG(x) (*((volatile u32 __iomem *)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 __iomem*)((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
+
+#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()); \
+ })
+
+
+
+/*
+ * 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
+
+#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()); \
+ })
+
+
+/*
+ * 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
+
+#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 000000000..0e1bb4626
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/hx4700.h
@@ -0,0 +1,133 @@
+/*
+ * 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>
+#include "irqs.h" /* PXA_NR_BUILTIN_GPIO */
+
+#define HX4700_ASIC3_GPIO_BASE PXA_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 000000000..7e63f4680
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/idp.h
@@ -0,0 +1,198 @@
+/*
+ * 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.
+ */
+
+#include "irqs.h" /* PXA_GPIO_TO_IRQ */
+
+#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)
+
+/* A listing of interrupts used by external hardware devices */
+
+#define TOUCH_PANEL_IRQ PXA_GPIO_TO_IRQ(5)
+#define IDE_IRQ PXA_GPIO_TO_IRQ(21)
+
+#define TOUCH_PANEL_IRQ_EDGE IRQ_TYPE_EDGE_FALLING
+
+#define ETHERNET_IRQ PXA_GPIO_TO_IRQ(4)
+#define ETHERNET_IRQ_EDGE IRQ_TYPE_EDGE_RISING
+
+#define IDE_IRQ_EDGE IRQ_TYPE_EDGE_RISING
+
+#define PCMCIA_S0_CD_VALID PXA_GPIO_TO_IRQ(7)
+#define PCMCIA_S0_CD_VALID_EDGE IRQ_TYPE_EDGE_BOTH
+
+#define PCMCIA_S1_CD_VALID PXA_GPIO_TO_IRQ(8)
+#define PCMCIA_S1_CD_VALID_EDGE IRQ_TYPE_EDGE_BOTH
+
+#define PCMCIA_S0_RDYINT PXA_GPIO_TO_IRQ(19)
+#define PCMCIA_S1_RDYINT PXA_GPIO_TO_IRQ(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 000000000..cd78b7fe3
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/io.h
@@ -0,0 +1,17 @@
+/*
+ * 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
+
+#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)
+
+#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 000000000..7e3ea351f
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/irqs.h
@@ -0,0 +1,112 @@
+/*
+ * 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
+
+#include <asm/irq.h>
+
+#define PXA_ISA_IRQ(x) (x)
+#define PXA_IRQ(x) (NR_IRQS_LEGACY + (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_U2P PXA_IRQ(93) /* USB PHY D+/D- Lines (PXA935) */
+
+#define PXA_GPIO_IRQ_BASE PXA_IRQ(96)
+#define PXA_NR_BUILTIN_GPIO (192)
+#define PXA_GPIO_TO_IRQ(x) (PXA_GPIO_IRQ_BASE + (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_NR_BUILTIN_GPIO)
+
+#define PXA_NR_IRQS (IRQ_BOARD_START)
+
+#ifndef __ASSEMBLY__
+struct irq_data;
+struct pt_regs;
+
+void pxa_mask_irq(struct irq_data *);
+void pxa_unmask_irq(struct irq_data *);
+void icip_handle_irq(struct pt_regs *);
+void ichp_handle_irq(struct pt_regs *);
+
+void pxa_init_irq(int irq_nr, int (*set_wake)(struct irq_data *, unsigned int));
+#endif
+
+#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 000000000..8066be54e
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/littleton.h
@@ -0,0 +1,13 @@
+#ifndef __ASM_ARCH_LITTLETON_H
+#define __ASM_ARCH_LITTLETON_H
+
+#define LITTLETON_ETH_PHYS 0x30000000
+
+#define LITTLETON_GPIO_LCD_CS (17)
+
+#define EXT0_GPIO_BASE (PXA_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 000000000..4edc712a2
--- /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 IOMEM(0xf0000000)
+#define LPD270_CPLD_SIZE 0x00100000
+
+#define LPD270_ETH_PHYS (PXA_CS2_PHYS + 0x01000000)
+
+/* CPLD registers */
+#define LPD270_CPLD_REG(x) (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 000000000..1eecf794a
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/lubbock.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#include <mach/irqs.h>
+
+#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_NR_IRQS IRQ_BOARD_START
+
+#define LUBBOCK_IRQ(x) (LUBBOCK_NR_IRQS + (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 (LUBBOCK_NR_IRQS + 32)
+
+#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 000000000..ba6a6e1d2
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/magician.h
@@ -0,0 +1,120 @@
+/*
+ * 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 <linux/gpio.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 PXA_NR_BUILTIN_GPIO
+#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 000000000..e82a7d311
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mainstone.h
@@ -0,0 +1,141 @@
+/*
+ * 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
+
+#include <mach/irqs.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_NR_IRQS IRQ_BOARD_START
+
+#define MAINSTONE_IRQ(x) (MAINSTONE_NR_IRQS + (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)
+
+#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 000000000..cafadc33d
--- /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 000000000..b6132aa95
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
@@ -0,0 +1,471 @@
+#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 GPIO45_BTUART_RTS_LPM_LOW MFP_CFG_OUT(GPIO45, AF2, DRIVE_LOW)
+#define GPIO43_BTUART_TXD MFP_CFG_OUT(GPIO43, AF2, DRIVE_HIGH)
+#define GPIO43_BTUART_TXD_LPM_LOW MFP_CFG_OUT(GPIO43, AF2, DRIVE_LOW)
+
+/* 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_IN MFP_CFG_IN(GPIO23, AF2)
+#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
+
+/* these enable a work-around for a hw bug in pxa27x during ac97 warm reset */
+#define GPIO113_AC97_nRESET_GPIO_HIGH MFP_CFG_OUT(GPIO113, AF0, DEFAULT)
+#define GPIO95_AC97_nRESET_GPIO_HIGH MFP_CFG_OUT(GPIO95, AF0, DEFAULT)
+
+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 000000000..cbf51ae81
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
@@ -0,0 +1,142 @@
+#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)
+ * bit 25 - Keep Output (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)
+
+/*
+ * MFP_LPM_KEEP_OUTPUT must be specified for pins that need to
+ * retain their last output level (low or high).
+ * Note: MFP_LPM_KEEP_OUTPUT has no effect on pins configured for input.
+ */
+#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 000000000..4e1287070
--- /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 000000000..3ce4682ea
--- /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 000000000..d375195d9
--- /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 000000000..04f7c9704
--- /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 000000000..271e249ae
--- /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 000000000..e57f5c724
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mioa701.h
@@ -0,0 +1,75 @@
+#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
+
+/* Camera */
+#define GPIO56_MT9M111_nOE 56
+
+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/mtd-xip.h b/arch/arm/mach-pxa/include/mach/mtd-xip.h
new file mode 100644
index 000000000..990d2bf2f
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mtd-xip.h
@@ -0,0 +1,35 @@
+/*
+ * 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>
+
+#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 000000000..ffa15665a
--- /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/palm27x.h b/arch/arm/mach-pxa/include/mach/palm27x.h
new file mode 100644
index 000000000..d4eac3d6f
--- /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
+#define palm27x_lcd_init(power, mode) do {} while (0)
+#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/palmld.h b/arch/arm/mach-pxa/include/mach/palmld.h
new file mode 100644
index 000000000..b184f2960
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmld.h
@@ -0,0 +1,111 @@
+/*
+ * 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_
+
+#include "irqs.h" /* PXA_GPIO_TO_IRQ */
+
+/** 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 PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_GPIO_RESET)
+#define IRQ_GPIO_PALMLD_SD_DETECT_N PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_SD_DETECT_N)
+#define IRQ_GPIO_PALMLD_WM9712_IRQ PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_WM9712_IRQ)
+#define IRQ_GPIO_PALMLD_IDE_IRQ PXA_GPIO_TO_IRQ(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 000000000..e342c5921
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmt5.h
@@ -0,0 +1,86 @@
+/*
+ * 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_
+
+#include "irqs.h" /* PXA_GPIO_TO_IRQ */
+
+/** 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 PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_SD_DETECT_N)
+#define IRQ_GPIO_PALMT5_WM9712_IRQ PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_WM9712_IRQ)
+#define IRQ_GPIO_PALMT5_USB_DETECT PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_USB_DETECT)
+#define IRQ_GPIO_PALMT5_GPIO_RESET PXA_GPIO_TO_IRQ(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 000000000..81c727b3c
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmtc.h
@@ -0,0 +1,88 @@
+/*
+ * 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_
+
+#include "irqs.h" /* PXA_GPIO_TO_IRQ */
+
+/** 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 PXA_GPIO_TO_IRQ(GPIO_NR_PALMTC_SD_DETECT_N)
+#define IRQ_GPIO_PALMTC_WLAN_READY PXA_GPIO_TO_IRQ(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 000000000..f89e989a7
--- /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 000000000..714b65743
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmtreo.h
@@ -0,0 +1,68 @@
+/*
+ * 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 */
+#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
+#define GPIO_NR_TREO680_LCD_POWER 77
+#define GPIO_NR_TREO680_LCD_EN 86
+#define GPIO_NR_TREO680_LCD_EN_N 25
+
+/* 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 000000000..92bc1f053
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmtx.h
@@ -0,0 +1,114 @@
+/*
+ * 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_
+
+#include "irqs.h" /* PXA_GPIO_TO_IRQ */
+
+/** 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 PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_SD_DETECT_N)
+#define IRQ_GPIO_PALMTX_WM9712_IRQ PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_WM9712_IRQ)
+#define IRQ_GPIO_PALMTX_USB_DETECT PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_USB_DETECT)
+#define IRQ_GPIO_PALMTX_GPIO_RESET PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_GPIO_RESET)
+
+/** HERE ARE INIT VALUES **/
+
+/* Various addresses */
+#define PALMTX_PCMCIA_PHYS 0x28000000
+#define PALMTX_PCMCIA_VIRT IOMEM(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 IOMEM(0xff100000)
+#define PALMTX_NAND_CLE_VIRT IOMEM(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 000000000..0d4700a79
--- /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/pcm027.h b/arch/arm/mach-pxa/include/mach/pcm027.h
new file mode 100644
index 000000000..86ebd7b6c
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pcm027.h
@@ -0,0 +1,86 @@
+/*
+ * 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
+ */
+
+#include "irqs.h" /* PXA_GPIO_TO_IRQ */
+
+/* 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 PXA_GPIO_TO_IRQ(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 PXA_GPIO_TO_IRQ(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 PXA_GPIO_TO_IRQ(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 PXA_GPIO_TO_IRQ(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 000000000..7e544c149
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h
@@ -0,0 +1,212 @@
+/*
+ * 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>
+#include "irqs.h" /* PXA_GPIO_TO_IRQ */
+
+/*
+ * 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 PXA_GPIO_TO_IRQ(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_SIZE (1*1024*1024)
+
+#define PCM990_CTRL_PWR_IRQ_GPIO 14
+#define PCM990_CTRL_PWR_IRQ PXA_GPIO_TO_IRQ(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_INTSETCLR 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_INTMSKENA 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 */
+
+/*
+ * IDE
+ */
+#define PCM990_IDE_IRQ_GPIO 13
+#define PCM990_IDE_IRQ PXA_GPIO_TO_IRQ(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)
+
+/*
+ * Compact Flash
+ */
+#define PCM990_CF_IRQ_GPIO 11
+#define PCM990_CF_IRQ PXA_GPIO_TO_IRQ(PCM990_CF_IRQ_GPIO)
+#define PCM990_CF_IRQ_EDGE IRQ_TYPE_EDGE_RISING
+
+#define PCM990_CF_CD_GPIO 12
+#define PCM990_CF_CD PXA_GPIO_TO_IRQ(PCM990_CF_CD_GPIO)
+#define PCM990_CF_CD_EDGE IRQ_TYPE_EDGE_RISING
+
+#define PCM990_CF_PLD_PHYS 0x30000000 /* 16 bit wide */
+
+/* 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 */
+
+/*
+ * Wolfson AC97 Touch
+ */
+#define PCM990_AC97_IRQ_GPIO 10
+#define PCM990_AC97_IRQ PXA_GPIO_TO_IRQ(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 PXA_GPIO_TO_IRQ(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 000000000..51558bcee
--- /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 int pxa25x_finish_suspend(unsigned long);
+extern int pxa27x_finish_suspend(unsigned 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 000000000..b56b19351
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/poodle.h
@@ -0,0 +1,94 @@
+/*
+ * 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
+
+#include "irqs.h" /* PXA_GPIO_TO_IRQ */
+
+/*
+ * 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 PXA_GPIO_TO_IRQ(0)
+#define POODLE_IRQ_GPIO_AC_IN PXA_GPIO_TO_IRQ(1)
+#define POODLE_IRQ_GPIO_HP_IN PXA_GPIO_TO_IRQ(4)
+#define POODLE_IRQ_GPIO_CO PXA_GPIO_TO_IRQ(16)
+#define POODLE_IRQ_GPIO_TP_INT PXA_GPIO_TO_IRQ(5)
+#define POODLE_IRQ_GPIO_WAKEUP PXA_GPIO_TO_IRQ(11)
+#define POODLE_IRQ_GPIO_GA_INT PXA_GPIO_TO_IRQ(10)
+#define POODLE_IRQ_GPIO_CF_IRQ PXA_GPIO_TO_IRQ(17)
+#define POODLE_IRQ_GPIO_CF_CD PXA_GPIO_TO_IRQ(14)
+#define POODLE_IRQ_GPIO_nSD_INT PXA_GPIO_TO_IRQ(8)
+#define POODLE_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(9)
+#define POODLE_IRQ_GPIO_MAIN_BAT_LOW PXA_GPIO_TO_IRQ(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 (PXA_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 000000000..1b80a4805
--- /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 000000000..5a341752e
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa25x.h
@@ -0,0 +1,9 @@
+#ifndef __MACH_PXA25x_H
+#define __MACH_PXA25x_H
+
+#include <mach/hardware.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/mfp-pxa25x.h>
+#include <mach/irqs.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 000000000..4cf28f670
--- /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 Transceiver Interrupt
+ Rising Edge Interrupt Enable */
+#define UDCOTGICR_IEXF (1 << 16) /* Extra Transceiver 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 000000000..599b925a6
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa27x.h
@@ -0,0 +1,25 @@
+#ifndef __MACH_PXA27x_H
+#define __MACH_PXA27x_H
+
+#include <linux/suspend.h>
+#include <mach/hardware.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/mfp-pxa27x.h>
+#include <mach/irqs.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);
+extern void pxa27x_cpu_pm_enter(suspend_state_t state);
+
+#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 000000000..f1dd62946
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h
@@ -0,0 +1,197 @@
+/*
+ * 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 CCCR_CPDIS_BIT (31)
+#define CCCR_PPDIS_BIT (30)
+#define CCCR_LCD_26_BIT (27)
+#define CCCR_A_BIT (25)
+
+#define CCSR_N2_MASK CCCR_N_MASK
+#define CCSR_M_MASK CCCR_M_MASK
+#define CCSR_L_MASK CCCR_L_MASK
+#define CCSR_N2_SHIFT 7
+
+#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 000000000..733b6412c
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa300.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_PXA300_H
+#define __MACH_PXA300_H
+
+#include <mach/pxa3xx.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 000000000..b6204e470
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa320.h
@@ -0,0 +1,8 @@
+#ifndef __MACH_PXA320_H
+#define __MACH_PXA320_H
+
+#include <mach/pxa3xx.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 000000000..f4d48d207
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
@@ -0,0 +1,206 @@
+/*
+ * 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 CKENC __REG(0x41340024) /* C 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.h b/arch/arm/mach-pxa/include/mach/pxa3xx.h
new file mode 100644
index 000000000..b4143fb66
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa3xx.h
@@ -0,0 +1,8 @@
+#ifndef __MACH_PXA3XX_H
+#define __MACH_PXA3XX_H
+
+#include <mach/hardware.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/irqs.h>
+
+#endif /* __MACH_PXA3XX_H */
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 000000000..190363b98
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa930.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_PXA930_H
+#define __MACH_PXA930_H
+
+#include <mach/pxa3xx.h>
+#include <mach/mfp-pxa930.h>
+
+#endif /* __MACH_PXA930_H */
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 000000000..b8d14bd9a
--- /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-lcd.h b/arch/arm/mach-pxa/include/mach/regs-lcd.h
new file mode 100644
index 000000000..f82dcea79
--- /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 000000000..628819995
--- /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 io_p2v(0x40A00000) /* */
+#define OSMR1 io_p2v(0x40A00004) /* */
+#define OSMR2 io_p2v(0x40A00008) /* */
+#define OSMR3 io_p2v(0x40A0000C) /* */
+#define OSMR4 io_p2v(0x40A00080) /* */
+#define OSCR io_p2v(0x40A00010) /* OS Timer Counter Register */
+#define OSCR4 io_p2v(0x40A00040) /* OS Timer Counter Register */
+#define OMCR4 io_p2v(0x40A000C0) /* */
+#define OSSR io_p2v(0x40A00014) /* OS Timer Status Register */
+#define OWER io_p2v(0x40A00018) /* OS Timer Watchdog Enable Register */
+#define OIER io_p2v(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 000000000..f0e4a589b
--- /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 000000000..c15c0c57d
--- /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 000000000..55aeb7fb7
--- /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 000000000..b6c10556f
--- /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 000000000..905be6755
--- /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 000000000..b802f285f
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/smemc.h
@@ -0,0 +1,75 @@
+/*
+ * 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 IOMEM(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 */
+#define CSMSADRCFG (SMEMC_VIRT + 0xA0) /* Chip Select Configuration Register */
+
+/*
+ * 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 000000000..25c9f62e4
--- /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 "irqs.h" /* PXA_NR_BUILTIN_GPIO, PXA_GPIO_TO_IRQ */
+#include <linux/fb.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 (PXA_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 (PXA_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 (PXA_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 PXA_GPIO_TO_IRQ(SPITZ_GPIO_KEY_INT)
+#define SPITZ_IRQ_GPIO_AC_IN PXA_GPIO_TO_IRQ(SPITZ_GPIO_AC_IN)
+#define SPITZ_IRQ_GPIO_AK_INT PXA_GPIO_TO_IRQ(SPITZ_GPIO_AK_INT)
+#define SPITZ_IRQ_GPIO_HP_IN PXA_GPIO_TO_IRQ(SPITZ_GPIO_HP_IN)
+#define SPITZ_IRQ_GPIO_TP_INT PXA_GPIO_TO_IRQ(SPITZ_GPIO_TP_INT)
+#define SPITZ_IRQ_GPIO_SYNC PXA_GPIO_TO_IRQ(SPITZ_GPIO_SYNC)
+#define SPITZ_IRQ_GPIO_ON_KEY PXA_GPIO_TO_IRQ(SPITZ_GPIO_ON_KEY)
+#define SPITZ_IRQ_GPIO_SWA PXA_GPIO_TO_IRQ(SPITZ_GPIO_SWA)
+#define SPITZ_IRQ_GPIO_SWB PXA_GPIO_TO_IRQ(SPITZ_GPIO_SWB)
+#define SPITZ_IRQ_GPIO_BAT_COVER PXA_GPIO_TO_IRQ(SPITZ_GPIO_BAT_COVER)
+#define SPITZ_IRQ_GPIO_FATAL_BAT PXA_GPIO_TO_IRQ(SPITZ_GPIO_FATAL_BAT)
+#define SPITZ_IRQ_GPIO_CO PXA_GPIO_TO_IRQ(SPITZ_GPIO_CO)
+#define SPITZ_IRQ_GPIO_CF_IRQ PXA_GPIO_TO_IRQ(SPITZ_GPIO_CF_IRQ)
+#define SPITZ_IRQ_GPIO_CF_CD PXA_GPIO_TO_IRQ(SPITZ_GPIO_CF_CD)
+#define SPITZ_IRQ_GPIO_CF2_IRQ PXA_GPIO_TO_IRQ(SPITZ_GPIO_CF2_IRQ)
+#define SPITZ_IRQ_GPIO_nSD_INT PXA_GPIO_TO_IRQ(SPITZ_GPIO_nSD_INT)
+#define SPITZ_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(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/tosa.h b/arch/arm/mach-pxa/include/mach/tosa.h
new file mode 100644
index 000000000..0497d95ce
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/tosa.h
@@ -0,0 +1,202 @@
+/*
+ * 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
+
+#include "irqs.h" /* PXA_NR_BUILTIN_GPIO */
+
+/* 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 PXA_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 (PXA_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 (PXA_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 PXA_GPIO_TO_IRQ(TOSA_GPIO_WAKEUP)
+#define TOSA_IRQ_GPIO_AC_IN PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN)
+#define TOSA_IRQ_GPIO_RECORD_BTN PXA_GPIO_TO_IRQ(TOSA_GPIO_RECORD_BTN)
+#define TOSA_IRQ_GPIO_SYNC PXA_GPIO_TO_IRQ(TOSA_GPIO_SYNC)
+#define TOSA_IRQ_GPIO_USB_IN PXA_GPIO_TO_IRQ(TOSA_GPIO_USB_IN)
+#define TOSA_IRQ_GPIO_JACKET_DETECT PXA_GPIO_TO_IRQ(TOSA_GPIO_JACKET_DETECT)
+#define TOSA_IRQ_GPIO_nSD_INT PXA_GPIO_TO_IRQ(TOSA_GPIO_nSD_INT)
+#define TOSA_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(TOSA_GPIO_nSD_DETECT)
+#define TOSA_IRQ_GPIO_BAT1_CRG PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT1_CRG)
+#define TOSA_IRQ_GPIO_CF_CD PXA_GPIO_TO_IRQ(TOSA_GPIO_CF_CD)
+#define TOSA_IRQ_GPIO_BAT0_CRG PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT0_CRG)
+#define TOSA_IRQ_GPIO_TC6393XB_INT PXA_GPIO_TO_IRQ(TOSA_GPIO_TC6393XB_INT)
+#define TOSA_IRQ_GPIO_BAT0_LOW PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT0_LOW)
+#define TOSA_IRQ_GPIO_EAR_IN PXA_GPIO_TO_IRQ(TOSA_GPIO_EAR_IN)
+#define TOSA_IRQ_GPIO_CF_IRQ PXA_GPIO_TO_IRQ(TOSA_GPIO_CF_IRQ)
+#define TOSA_IRQ_GPIO_ON_KEY PXA_GPIO_TO_IRQ(TOSA_GPIO_ON_KEY)
+#define TOSA_IRQ_GPIO_VGA_LINE PXA_GPIO_TO_IRQ(TOSA_GPIO_VGA_LINE)
+#define TOSA_IRQ_GPIO_TP_INT PXA_GPIO_TO_IRQ(TOSA_GPIO_TP_INT)
+#define TOSA_IRQ_GPIO_JC_CF_IRQ PXA_GPIO_TO_IRQ(TOSA_GPIO_JC_CF_IRQ)
+#define TOSA_IRQ_GPIO_BAT_LOCKED PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT_LOCKED)
+#define TOSA_IRQ_GPIO_BAT1_LOW PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT1_LOW)
+#define TOSA_IRQ_GPIO_KEY_SENSE(a) PXA_GPIO_TO_IRQ(69+(a))
+
+#define TOSA_IRQ_GPIO_MAIN_BAT_LOW PXA_GPIO_TO_IRQ(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 000000000..efc3c3d3b
--- /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 000000000..ae3ca013a
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/trizeps4.h
@@ -0,0 +1,164 @@
+/************************************************************************
+ * Include file for TRIZEPS4 SoM and ConXS eval-board
+ * Copyright (c) JĂ¼rgen Schindele
+ * 2006
+ ************************************************************************/
+
+/*
+ * Includes/Defines
+ */
+#ifndef _TRIPEPS4_H_
+#define _TRIPEPS4_H_
+
+#include "irqs.h" /* PXA_GPIO_TO_IRQ */
+
+/* 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 PXA_GPIO_TO_IRQ(GPIO_DM9000)
+
+/* UCB1400 audio / TS-controller */
+#define GPIO_UCB1400 1
+#define TRIZEPS4_UCB1400_IRQ PXA_GPIO_TO_IRQ(GPIO_UCB1400)
+
+/* PCMCIA socket Compact Flash */
+#define GPIO_PCD 11 /* PCMCIA Card Detect */
+#define TRIZEPS4_CD_IRQ PXA_GPIO_TO_IRQ(GPIO_PCD)
+#define GPIO_PRDY 13 /* READY / nINT */
+#define TRIZEPS4_READY_NINT PXA_GPIO_TO_IRQ(GPIO_PRDY)
+
+/* MMC socket */
+#define GPIO_MMC_DET 12
+#define TRIZEPS4_MMC_IRQ PXA_GPIO_TO_IRQ(GPIO_MMC_DET)
+
+/* DOC NAND chip */
+#define GPIO_DOC_LOCK 94
+#define GPIO_DOC_IRQ 93
+#define TRIZEPS4_DOC_IRQ PXA_GPIO_TO_IRQ(GPIO_DOC_IRQ)
+
+/* SPI interface */
+#define GPIO_SPI 53
+#define TRIZEPS4_SPI_IRQ PXA_GPIO_TO_IRQ(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 PXA_GPIO_TO_IRQ(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 000000000..9a827e32d
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/udc.h
@@ -0,0 +1,8 @@
+/*
+ * arch/arm/mach-pxa/include/mach/udc.h
+ *
+ */
+#include <linux/platform_data/pxa2xx_udc.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 000000000..8c27757e6
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/uncompress.h
@@ -0,0 +1,74 @@
+/*
+ * 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;
+ }
+}
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 000000000..5f5fbf1f6
--- /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/vpac270.h b/arch/arm/mach-pxa/include/mach/vpac270.h
new file mode 100644
index 000000000..7bfa3dd0f
--- /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 000000000..7b0f71ef3
--- /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 000000000..56024f81d
--- /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 IOMEM(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 IOMEM(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 000000000..ecca976f0
--- /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_MACH_ZYLONITE300
+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_MACH_ZYLONITE320
+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 000000000..89a7c0657
--- /dev/null
+++ b/arch/arm/mach-pxa/irq.c
@@ -0,0 +1,274 @@
+/*
+ * 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/bitops.h>
+#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 <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#include <asm/exception.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+#include "generic.h"
+
+#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 ICHP_VAL_IRQ (1 << 31)
+#define ICHP_IRQ(i) (((i) >> 16) & 0x7fff)
+#define IPR_VALID (1 << 31)
+
+#define MAX_INTERNAL_IRQS 128
+
+/*
+ * This is for peripheral IRQs internal to the PXA chip.
+ */
+
+static void __iomem *pxa_irq_base;
+static int pxa_internal_irq_nr;
+static bool cpu_has_ipr;
+static struct irq_domain *pxa_irq_domain;
+
+static inline void __iomem *irq_base(int i)
+{
+ static unsigned long phys_base_offset[] = {
+ 0x0,
+ 0x9c,
+ 0x130,
+ };
+
+ return pxa_irq_base + phys_base_offset[i];
+}
+
+void pxa_mask_irq(struct irq_data *d)
+{
+ void __iomem *base = irq_data_get_irq_chip_data(d);
+ irq_hw_number_t irq = irqd_to_hwirq(d);
+ uint32_t icmr = __raw_readl(base + ICMR);
+
+ icmr &= ~BIT(irq & 0x1f);
+ __raw_writel(icmr, base + ICMR);
+}
+
+void pxa_unmask_irq(struct irq_data *d)
+{
+ void __iomem *base = irq_data_get_irq_chip_data(d);
+ irq_hw_number_t irq = irqd_to_hwirq(d);
+ uint32_t icmr = __raw_readl(base + ICMR);
+
+ icmr |= BIT(irq & 0x1f);
+ __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,
+};
+
+asmlinkage void __exception_irq_entry icip_handle_irq(struct pt_regs *regs)
+{
+ uint32_t icip, icmr, mask;
+
+ do {
+ icip = __raw_readl(pxa_irq_base + ICIP);
+ icmr = __raw_readl(pxa_irq_base + ICMR);
+ mask = icip & icmr;
+
+ if (mask == 0)
+ break;
+
+ handle_IRQ(PXA_IRQ(fls(mask) - 1), regs);
+ } while (1);
+}
+
+asmlinkage void __exception_irq_entry ichp_handle_irq(struct pt_regs *regs)
+{
+ uint32_t ichp;
+
+ do {
+ __asm__ __volatile__("mrc p6, 0, %0, c5, c0, 0\n": "=r"(ichp));
+
+ if ((ichp & ICHP_VAL_IRQ) == 0)
+ break;
+
+ handle_IRQ(PXA_IRQ(ICHP_IRQ(ichp)), regs);
+ } while (1);
+}
+
+static int pxa_irq_map(struct irq_domain *h, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ void __iomem *base = irq_base(hw / 32);
+
+ /* initialize interrupt priority */
+ if (cpu_has_ipr)
+ __raw_writel(hw | IPR_VALID, pxa_irq_base + IPR(hw));
+
+ irq_set_chip_and_handler(virq, &pxa_internal_irq_chip,
+ handle_level_irq);
+ irq_set_chip_data(virq, base);
+ set_irq_flags(virq, IRQF_VALID);
+
+ return 0;
+}
+
+static struct irq_domain_ops pxa_irq_ops = {
+ .map = pxa_irq_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+static __init void
+pxa_init_irq_common(struct device_node *node, int irq_nr,
+ int (*fn)(struct irq_data *, unsigned int))
+{
+ int n;
+
+ pxa_internal_irq_nr = irq_nr;
+ pxa_irq_domain = irq_domain_add_legacy(node, irq_nr,
+ PXA_IRQ(0), 0,
+ &pxa_irq_ops, NULL);
+ if (!pxa_irq_domain)
+ panic("Unable to add PXA IRQ domain\n");
+ irq_set_default_host(pxa_irq_domain);
+
+ 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 */
+ }
+ /* only unmasked interrupts kick us out of idle */
+ __raw_writel(1, irq_base(0) + ICCR);
+
+ pxa_internal_irq_chip.irq_set_wake = fn;
+}
+
+void __init pxa_init_irq(int irq_nr, int (*fn)(struct irq_data *, unsigned int))
+{
+ BUG_ON(irq_nr > MAX_INTERNAL_IRQS);
+
+ pxa_irq_base = io_p2v(0x40d00000);
+ cpu_has_ipr = !cpu_is_pxa25x();
+ pxa_init_irq_common(NULL, irq_nr, 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(pxa_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], pxa_irq_base + IPR(i));
+
+ __raw_writel(1, pxa_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,
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id intc_ids[] __initconst = {
+ { .compatible = "marvell,pxa-intc", },
+ {}
+};
+
+void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int))
+{
+ struct device_node *node;
+ struct resource res;
+ int ret;
+
+ node = of_find_matching_node(NULL, intc_ids);
+ if (!node) {
+ pr_err("Failed to find interrupt controller in arch-pxa\n");
+ return;
+ }
+
+ ret = of_property_read_u32(node, "marvell,intc-nr-irqs",
+ &pxa_internal_irq_nr);
+ if (ret) {
+ pr_err("Not found marvell,intc-nr-irqs property\n");
+ return;
+ }
+
+ ret = of_address_to_resource(node, 0, &res);
+ if (ret < 0) {
+ pr_err("No registers defined for node\n");
+ return;
+ }
+ pxa_irq_base = io_p2v(res.start);
+
+ if (of_find_property(node, "marvell,intc-priority", NULL))
+ cpu_has_ipr = 1;
+
+ ret = irq_alloc_descs(-1, 0, pxa_internal_irq_nr, 0);
+ if (ret < 0) {
+ pr_err("Failed to allocate IRQ numbers\n");
+ return;
+ }
+
+ pxa_init_irq_common(node, pxa_internal_irq_nr, fn);
+}
+#endif /* CONFIG_OF */
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
new file mode 100644
index 000000000..5d665588c
--- /dev/null
+++ b/arch/arm/mach-pxa/littleton.c
@@ -0,0 +1,453 @@
+/*
+ * 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 <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/keypad-pxa27x.h>
+#include <mach/littleton.h>
+#include <linux/platform_data/mtd-nand-pxa3xx.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 = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO90)),
+ .end = PXA_GPIO_TO_IRQ(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 const 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 matrix_keymap_data littleton_matrix_keymap_data = {
+ .keymap = littleton_matrix_key_map,
+ .keymap_size = ARRAY_SIZE(littleton_matrix_key_map),
+};
+
+static struct pxa27x_keypad_platform_data littleton_keypad_info = {
+ .matrix_key_rows = 6,
+ .matrix_key_cols = 5,
+ .matrix_keymap_data = &littleton_matrix_keymap_data,
+
+ .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,
+ .num_cs = 1,
+ .parts[0] = littleton_nand_partitions,
+ .nr_parts[0] = 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 = PXA_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)")
+ .atag_offset = 0x100,
+ .map_io = pxa3xx_map_io,
+ .nr_irqs = LITTLETON_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .handle_irq = pxa3xx_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = littleton_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
new file mode 100644
index 000000000..eaee2c20b
--- /dev/null
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -0,0 +1,516 @@
+/*
+ * 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/gpio.h>
+#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 <linux/smc91x.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/lpd270.h>
+#include <mach/audio.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <linux/platform_data/usb-ohci-pxa27x.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(PXA_GPIO_TO_IRQ(0), lpd270_irq_handler);
+ irq_set_irq_type(PXA_GPIO_TO_IRQ(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 | IORESOURCE_IRQ_HIGHEDGE,
+ },
+};
+
+struct smc91x_platdata smc91x_platdata = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+ .dev.platform_data = &smc91x_platdata,
+};
+
+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,
+ .enable_gpio = -1,
+};
+
+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 (!strncasecmp(str, "lq057q3dc02", 11)) {
+ lpd270_lcd_to_use = &sharp_lq057q3dc02;
+ } else if (!strncasecmp(str, "lq121s1dg31", 11)) {
+ lpd270_lcd_to_use = &sharp_lq121s1dg31;
+ } else if (!strncasecmp(str, "lq036q1da01", 11)) {
+ lpd270_lcd_to_use = &sharp_lq036q1da01;
+ } else if (!strncasecmp(str, "lq64d343", 8)) {
+ lpd270_lcd_to_use = &sharp_lq64d343;
+ } else if (!strncasecmp(str, "lq10d368", 8)) {
+ lpd270_lcd_to_use = &sharp_lq10d368;
+ } else if (!strncasecmp(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 = (unsigned long)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 */
+ .atag_offset = 0x100,
+ .map_io = lpd270_map_io,
+ .nr_irqs = LPD270_NR_IRQS,
+ .init_irq = lpd270_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = lpd270_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
new file mode 100644
index 000000000..4ac9ab80d
--- /dev/null
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -0,0 +1,606 @@
+/*
+ * 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/gpio.h>
+#include <linux/gpio/machine.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.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/slab.h>
+#include <linux/leds.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/audio.h>
+#include <mach/lubbock.h>
+#include <mach/udc.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/mmc-pxamci.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 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,
+ .disable_devs = SA1111_DEVID_SAC,
+};
+
+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 resource lubbock_cplds_resources[] = {
+ [0] = {
+ .start = LUBBOCK_FPGA_PHYS + 0xc0,
+ .end = LUBBOCK_FPGA_PHYS + 0xe0 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PXA_GPIO_TO_IRQ(0),
+ .end = PXA_GPIO_TO_IRQ(0),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+ },
+ [2] = {
+ .start = LUBBOCK_IRQ(0),
+ .end = LUBBOCK_IRQ(6),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device lubbock_cplds_device = {
+ .name = "pxa_cplds_irqs",
+ .id = -1,
+ .resource = &lubbock_cplds_resources[0],
+ .num_resources = 3,
+};
+
+
+static struct platform_device *devices[] __initdata = {
+ &sa1111_device,
+ &smc91x_device,
+ &lubbock_flash_device[0],
+ &lubbock_flash_device[1],
+ &lubbock_cplds_device,
+};
+
+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,
+ 0, "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;
+}
+
+/*
+ * Driver for the 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.
+ */
+
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+struct lubbock_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;
+} lubbock_leds[] = {
+ { "lubbock:D28", "default-on", },
+ { "lubbock:D27", "cpu0", },
+ { "lubbock:D26", "heartbeat" },
+ { "lubbock:D25", },
+ { "lubbock:D24", },
+ { "lubbock:D23", },
+ { "lubbock:D22", },
+ { "lubbock:D21", },
+};
+
+static void lubbock_led_set(struct led_classdev *cdev,
+ enum led_brightness b)
+{
+ struct lubbock_led *led = container_of(cdev,
+ struct lubbock_led, cdev);
+ u32 reg = LUB_DISC_BLNK_LED;
+
+ if (b != LED_OFF)
+ reg |= led->mask;
+ else
+ reg &= ~led->mask;
+
+ LUB_DISC_BLNK_LED = reg;
+}
+
+static enum led_brightness lubbock_led_get(struct led_classdev *cdev)
+{
+ struct lubbock_led *led = container_of(cdev,
+ struct lubbock_led, cdev);
+ u32 reg = LUB_DISC_BLNK_LED;
+
+ return (reg & led->mask) ? LED_FULL : LED_OFF;
+}
+
+static int __init lubbock_leds_init(void)
+{
+ int i;
+
+ if (!machine_is_lubbock())
+ return -ENODEV;
+
+ /* All ON */
+ LUB_DISC_BLNK_LED |= 0xff;
+ for (i = 0; i < ARRAY_SIZE(lubbock_leds); i++) {
+ struct lubbock_led *led;
+
+ led = kzalloc(sizeof(*led), GFP_KERNEL);
+ if (!led)
+ break;
+
+ led->cdev.name = lubbock_leds[i].name;
+ led->cdev.brightness_set = lubbock_led_set;
+ led->cdev.brightness_get = lubbock_led_get;
+ led->cdev.default_trigger = lubbock_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(lubbock_leds_init);
+#endif
+
+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 = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = lubbock_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
new file mode 100644
index 000000000..a9761c293
--- /dev/null
+++ b/arch/arm/mach-pxa/magician.c
@@ -0,0 +1,780 @@
+/*
+ * 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/driver.h>
+#include <linux/regulator/gpio-regulator.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 <asm/system_info.h>
+
+#include <mach/pxa27x.h>
+#include <mach/magician.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <linux/platform_data/usb-ohci-pxa27x.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 = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
+ .end = PXA_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 struct gpio magician_bl_gpios[] = {
+ { EGPIO_MAGICIAN_BL_POWER, GPIOF_DIR_OUT, "Backlight power" },
+ { EGPIO_MAGICIAN_BL_POWER2, GPIOF_DIR_OUT, "Backlight power 2" },
+};
+
+static int magician_backlight_init(struct device *dev)
+{
+ return gpio_request_array(ARRAY_AND_SIZE(magician_bl_gpios));
+}
+
+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_array(ARRAY_AND_SIZE(magician_bl_gpios));
+}
+
+static struct platform_pwm_backlight_data backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 272,
+ .dft_brightness = 100,
+ .pwm_period_ns = 30923,
+ .enable_gpio = -1,
+ .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 = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
+ .end = PXA_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[] = {
+ REGULATOR_SUPPLY("vbus_draw", NULL),
+ REGULATOR_SUPPLY("ac_draw", NULL),
+};
+
+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 gpio bq24022_gpios[] = {
+ { EGPIO_MAGICIAN_BQ24022_ISET2, GPIOF_OUT_INIT_LOW, "bq24022_iset2" },
+};
+
+static struct gpio_regulator_state bq24022_states[] = {
+ { .value = 100000, .gpios = (0 << 0) },
+ { .value = 500000, .gpios = (1 << 0) },
+};
+
+static struct gpio_regulator_config bq24022_info = {
+ .supply_name = "bq24022",
+
+ .enable_gpio = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
+ .enable_high = 0,
+ .enabled_at_boot = 0,
+
+ .gpios = bq24022_gpios,
+ .nr_gpios = ARRAY_SIZE(bq24022_gpios),
+
+ .states = bq24022_states,
+ .nr_states = ARRAY_SIZE(bq24022_states),
+
+ .type = REGULATOR_CURRENT,
+ .init_data = &bq24022_init_data,
+};
+
+static struct platform_device bq24022 = {
+ .name = "gpio-regulator",
+ .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, 0,
+ "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 struct gpio magician_global_gpios[] = {
+ { GPIO13_MAGICIAN_CPLD_IRQ, GPIOF_IN, "CPLD_IRQ" },
+ { GPIO107_MAGICIAN_DS1WM_IRQ, GPIOF_IN, "DS1WM_IRQ" },
+ { GPIO104_MAGICIAN_LCD_POWER_1, GPIOF_OUT_INIT_LOW, "LCD power 1" },
+ { GPIO105_MAGICIAN_LCD_POWER_2, GPIOF_OUT_INIT_LOW, "LCD power 2" },
+ { GPIO106_MAGICIAN_LCD_POWER_3, GPIOF_OUT_INIT_LOW, "LCD power 3" },
+ { GPIO83_MAGICIAN_nIR_EN, GPIOF_OUT_INIT_HIGH, "nIR_EN" },
+};
+
+static void __init magician_init(void)
+{
+ void __iomem *cpld;
+ int lcd_select;
+ int err;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config));
+ err = gpio_request_array(ARRAY_AND_SIZE(magician_global_gpios));
+ if (err)
+ pr_err("magician: Failed to request GPIOs: %d\n", err);
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ platform_add_devices(ARRAY_AND_SIZE(devices));
+
+ 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_one(GPIO75_MAGICIAN_SAMSUNG_POWER,
+ GPIOF_OUT_INIT_LOW, "SAMSUNG_POWER");
+ 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")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = MAGICIAN_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_machine = magician_init,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
new file mode 100644
index 000000000..2c0658cf6
--- /dev/null
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -0,0 +1,667 @@
+/*
+ * 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/gpio.h>
+#include <linux/gpio/machine.h>
+#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 <linux/slab.h>
+#include <linux/leds.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/mainstone.h>
+#include <mach/audio.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <linux/platform_data/usb-ohci-pxa27x.h>
+#include <linux/platform_data/keypad-pxa27x.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 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,
+ .enable_gpio = -1,
+};
+
+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, 0,
+ "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 int 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;
+ }
+ return 0;
+}
+
+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 resource mst_cplds_resources[] = {
+ [0] = {
+ .start = MST_FPGA_PHYS + 0xc0,
+ .end = MST_FPGA_PHYS + 0xe0 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PXA_GPIO_TO_IRQ(0),
+ .end = PXA_GPIO_TO_IRQ(0),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+ },
+ [2] = {
+ .start = MAINSTONE_IRQ(0),
+ .end = MAINSTONE_IRQ(15),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mst_cplds_device = {
+ .name = "pxa_cplds_irqs",
+ .id = -1,
+ .resource = &mst_cplds_resources[0],
+ .num_resources = 3,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &smc91x_device,
+ &mst_flash_device[0],
+ &mst_flash_device[1],
+ &mst_gpio_keys_device,
+ &mst_cplds_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 const 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),
+};
+
+static struct matrix_keymap_data mainstone_matrix_keymap_data = {
+ .keymap = mainstone_matrix_keys,
+ .keymap_size = ARRAY_SIZE(mainstone_matrix_keys),
+};
+
+struct pxa27x_keypad_platform_data mainstone_keypad_info = {
+ .matrix_key_rows = 6,
+ .matrix_key_cols = 7,
+ .matrix_keymap_data = &mainstone_matrix_keymap_data,
+
+ .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;
+}
+
+/*
+ * Driver for the 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.
+ */
+
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+struct mainstone_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;
+} mainstone_leds[] = {
+ { "mainstone:D28", "default-on", },
+ { "mainstone:D27", "cpu0", },
+ { "mainstone:D26", "heartbeat" },
+ { "mainstone:D25", },
+ { "mainstone:D24", },
+ { "mainstone:D23", },
+ { "mainstone:D22", },
+ { "mainstone:D21", },
+};
+
+static void mainstone_led_set(struct led_classdev *cdev,
+ enum led_brightness b)
+{
+ struct mainstone_led *led = container_of(cdev,
+ struct mainstone_led, cdev);
+ u32 reg = MST_LEDCTRL;
+
+ if (b != LED_OFF)
+ reg |= led->mask;
+ else
+ reg &= ~led->mask;
+
+ MST_LEDCTRL = reg;
+}
+
+static enum led_brightness mainstone_led_get(struct led_classdev *cdev)
+{
+ struct mainstone_led *led = container_of(cdev,
+ struct mainstone_led, cdev);
+ u32 reg = MST_LEDCTRL;
+
+ return (reg & led->mask) ? LED_FULL : LED_OFF;
+}
+
+static int __init mainstone_leds_init(void)
+{
+ int i;
+
+ if (!machine_is_mainstone())
+ return -ENODEV;
+
+ /* All ON */
+ MST_LEDCTRL |= 0xff;
+ for (i = 0; i < ARRAY_SIZE(mainstone_leds); i++) {
+ struct mainstone_led *led;
+
+ led = kzalloc(sizeof(*led), GFP_KERNEL);
+ if (!led)
+ break;
+
+ led->cdev.name = mainstone_leds[i].name;
+ led->cdev.brightness_set = mainstone_led_set;
+ led->cdev.brightness_get = mainstone_led_get;
+ led->cdev.default_trigger = mainstone_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(mainstone_leds_init);
+#endif
+
+MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
+ /* Maintainer: MontaVista Software Inc. */
+ .atag_offset = 0x100, /* BLOB boot parameter setting */
+ .map_io = mainstone_map_io,
+ .nr_irqs = MAINSTONE_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = mainstone_init,
+ .restart = pxa_restart,
+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 000000000..666b78972
--- /dev/null
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
@@ -0,0 +1,439 @@
+/*
+ * 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/gpio.h>
+#include <linux/gpio-pxa.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.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 BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
+#define GPLR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5))
+#define GPDR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x0c)
+#define GPSR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x18)
+#define GPCR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x24)
+
+#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_warn("%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_warn("%s: GPIO%d unable to wakeup\n", __func__, gpio);
+ return -EINVAL;
+ }
+
+ if ((c & MFP_LPM_CAN_WAKEUP) && is_out) {
+ pr_warn("%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_warn("%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;
+
+ /* running before pxa_gpio_probe() */
+#ifdef CONFIG_CPU_PXA26x
+ pxa_last_gpio = 89;
+#else
+ pxa_last_gpio = 84;
+#endif
+ 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;
+
+ pxa_last_gpio = 120; /* running before pxa_gpio_probe() */
+ 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_gplr[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_gplr[i] = GPLR(i * 32);
+ saved_pgsr[i] = PGSR(i);
+
+ GPSR(i * 32) = PGSR(i);
+ GPCR(i * 32) = ~PGSR(i);
+ }
+
+ /* set GPDR bits taking into account MFP_LPM_KEEP_OUTPUT */
+ for (i = 0; i < pxa_last_gpio; i++) {
+ if ((gpdr_lpm[gpio_to_bank(i)] & GPIO_bit(i)) ||
+ ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) &&
+ (saved_gpdr[gpio_to_bank(i)] & GPIO_bit(i))))
+ GPDR(i) |= GPIO_bit(i);
+ else
+ GPDR(i) &= ~GPIO_bit(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];
+ GPSR(i * 32) = saved_gplr[i];
+ GPCR(i * 32) = ~saved_gplr[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 000000000..89863a01e
--- /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 000000000..29997bde2
--- /dev/null
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -0,0 +1,782 @@
+/*
+ * 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/reboot.h>
+#include <linux/regulator/fixed.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 <linux/platform_data/keypad-pxa27x.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <mach/udc.h>
+#include <mach/pxa27x-udc.h>
+#include <linux/platform_data/camera-pxa.h>
+#include <mach/audio.h>
+#include <mach/smemc.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,
+ MIO_CFG_OUT(GPIO56_MT9M111_nOE, AF0, DRIVE_LOW),
+
+ /* 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),
+};
+
+/* 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 */
+ .enable_gpio = -1,
+};
+
+/*
+ * 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 const 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 matrix_keymap_data mioa701_matrix_keymap_data = {
+ .keymap = mioa701_matrix_keys,
+ .keymap_size = ARRAY_SIZE(mioa701_matrix_keys),
+};
+
+static struct pxa27x_keypad_platform_data mioa701_keypad_info = {
+ .matrix_key_rows = 3,
+ .matrix_key_cols = 3,
+ .matrix_keymap_data = &mioa701_matrix_keymap_data,
+};
+
+/*
+ * 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;
+}
+
+static struct gpio gsm_gpios[] = {
+ { GPIO25_GSM_MOD_ON_STATE, GPIOF_IN, "GSM state" },
+ { GPIO113_GSM_EVENT, GPIOF_IN, "GSM event" },
+};
+
+static int __init gsm_init(void)
+{
+ int rc;
+
+ rc = gpio_request_array(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");
+ gpio_free_array(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);
+ gpio_free_array(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 docg3_resource = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device docg3 = {
+ .name = "docg3",
+ .id = -1,
+ .resource = &docg3_resource,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = NULL,
+ },
+};
+
+/*
+ * 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 = PXA_GPIO_TO_IRQ(GPIO96_AC_DETECT),
+ .end = PXA_GPIO_TO_IRQ(GPIO96_AC_DETECT),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+ IORESOURCE_IRQ_LOWEDGE,
+ },
+ [1] = {
+ .name = "usb",
+ .start = PXA_GPIO_TO_IRQ(GPIO13_nUSB_DETECT),
+ .end = PXA_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[] = {
+ REGULATOR_SUPPLY("vcc_core", NULL),
+};
+
+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,
+ &docg3,
+ &gpio_vbus,
+ &mioa701_camera,
+ &mioa701_board,
+};
+
+static void mioa701_machine_exit(void);
+
+static void mioa701_poweroff(void)
+{
+ mioa701_machine_exit();
+ pxa_restart(REBOOT_SOFT, NULL);
+}
+
+static void mioa701_restart(enum reboot_mode c, const char *cmd)
+{
+ mioa701_machine_exit();
+ pxa_restart(REBOOT_SOFT, cmd);
+}
+
+static struct gpio global_gpios[] = {
+ { GPIO9_CHARGE_EN, GPIOF_OUT_INIT_HIGH, "Charger enable" },
+ { GPIO18_POWEROFF, GPIOF_OUT_INIT_LOW, "Power Off" },
+ { GPIO87_LCD_POWER, GPIOF_OUT_INIT_LOW, "LCD Power" },
+ { GPIO56_MT9M111_nOE, GPIOF_OUT_INIT_LOW, "Camera nOE" },
+};
+
+static struct regulator_consumer_supply fixed_5v0_consumers[] = {
+ REGULATOR_SUPPLY("power", "pwm-backlight"),
+};
+
+static void __init mioa701_machine_init(void)
+{
+ int rc;
+
+ 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;
+
+ /*
+ * Set up the flash memory : DiskOnChip G3 on first static memory bank
+ */
+ __raw_writel(0x7ff02dd8, MSC0);
+ __raw_writel(0x0001c391, MCMEM0);
+ __raw_writel(0x0001c391, MCATT0);
+ __raw_writel(0x0001c391, MCIO0);
+
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(mioa701_pin_config));
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ rc = gpio_request_array(ARRAY_AND_SIZE(global_gpios));
+ if (rc)
+ pr_err("MioA701: Failed to request GPIOs: %d", rc);
+ 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;
+ 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);
+
+ regulator_register_always_on(0, "fixed-5.0V", fixed_5v0_consumers,
+ ARRAY_SIZE(fixed_5v0_consumers),
+ 5000000);
+}
+
+static void mioa701_machine_exit(void)
+{
+ bootstrap_exit();
+ gsm_exit();
+}
+
+MACHINE_START(MIOA701, "MIO A701")
+ .atag_offset = 0x100,
+ .map_io = &pxa27x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = &pxa27x_init_irq,
+ .handle_irq = &pxa27x_handle_irq,
+ .init_machine = mioa701_machine_init,
+ .init_time = pxa_timer_init,
+ .restart = mioa701_restart,
+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 000000000..81591491a
--- /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]
+ ret 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 000000000..854f1f562
--- /dev/null
+++ b/arch/arm/mach-pxa/mp900.c
@@ -0,0 +1,104 @@
+/*
+ * 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")
+ .atag_offset = 0x220100,
+ .init_time = pxa_timer_init,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .init_machine = mp900c_init,
+ .restart = pxa_restart,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c
new file mode 100644
index 000000000..d04ed4961
--- /dev/null
+++ b/arch/arm/mach-pxa/mxm8x10.c
@@ -0,0 +1,475 @@
+/*
+ * 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 <linux/platform_data/mtd-nand-pxa3xx.h>
+
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/usb-ohci-pxa27x.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,
+ .num_cs = 1,
+ .parts[0] = mxm_8x10_nand_partitions,
+ .nr_parts[0] = 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 = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO9)),
+ .end = PXA_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 000000000..e54a296fb
--- /dev/null
+++ b/arch/arm/mach-pxa/palm27x.c
@@ -0,0 +1,478 @@
+/*
+ * 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 <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <mach/udc.h>
+#include <linux/platform_data/asoc-palm27x.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,
+ .enable_gpio = -1,
+ .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[] = {
+ REGULATOR_SUPPLY("vcc_core", NULL),
+};
+
+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 000000000..cf210b11f
--- /dev/null
+++ b/arch/arm/mach-pxa/palmld.c
@@ -0,0 +1,357 @@
+/*
+ * 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 <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <linux/platform_data/keypad-pxa27x.h>
+#include <linux/platform_data/asoc-palm27x.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 const 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 matrix_keymap_data palmld_matrix_keymap_data = {
+ .keymap = palmld_matrix_keys,
+ .keymap_size = ARRAY_SIZE(palmld_matrix_keys),
+};
+
+static struct pxa27x_keypad_platform_data palmld_keypad_platform_data = {
+ .matrix_key_rows = 4,
+ .matrix_key_cols = 3,
+ .matrix_keymap_data = &palmld_matrix_keymap_data,
+
+ .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")
+ .atag_offset = 0x100,
+ .map_io = palmld_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = palmld_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
new file mode 100644
index 000000000..3ed9b0294
--- /dev/null
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -0,0 +1,218 @@
+/*
+ * 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 <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <linux/platform_data/keypad-pxa27x.h>
+#include <mach/udc.h>
+#include <linux/platform_data/asoc-palm27x.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 const 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 matrix_keymap_data palmt5_matrix_keymap_data = {
+ .keymap = palmt5_matrix_keys,
+ .keymap_size = ARRAY_SIZE(palmt5_matrix_keys),
+};
+
+static struct pxa27x_keypad_platform_data palmt5_keypad_platform_data = {
+ .matrix_key_rows = 4,
+ .matrix_key_cols = 3,
+ .matrix_keymap_data = &palmt5_matrix_keymap_data,
+
+ .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")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .reserve = palmt5_reserve,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = palmt5_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c
new file mode 100644
index 000000000..7691c974c
--- /dev/null
+++ b/arch/arm/mach-pxa/palmtc.c
@@ -0,0 +1,515 @@
+/*
+ * 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/pxa25x.h>
+#include <mach/audio.h>
+#include <mach/palmtc.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <mach/udc.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 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,
+ .enable_gpio = GPIO_NR_PALMTC_BL_POWER,
+};
+
+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")
+ .atag_offset = 0x100,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = palmtc_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c
new file mode 100644
index 000000000..956fd24ee
--- /dev/null
+++ b/arch/arm/mach-pxa/palmte2.c
@@ -0,0 +1,370 @@
+/*
+ * 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/pxa25x.h>
+#include <mach/audio.h>
+#include <mach/palmte2.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <mach/udc.h>
+#include <linux/platform_data/asoc-palm27x.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,
+};
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+/******************************************************************************
+ * 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,
+ },
+};
+#endif
+
+/******************************************************************************
+ * 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,
+ .enable_gpio = -1,
+ .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")
+ .atag_offset = 0x100,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = palmte2_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c
new file mode 100644
index 000000000..d8b937c87
--- /dev/null
+++ b/arch/arm/mach-pxa/palmtreo.c
@@ -0,0 +1,560 @@
+/*
+ * 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 <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <linux/platform_data/keypad-pxa27x.h>
+#include <mach/udc.h>
+#include <linux/platform_data/usb-ohci-pxa27x.h>
+#include <mach/pxa2xx-regs.h>
+#include <linux/platform_data/asoc-palm27x.h>
+#include <linux/platform_data/camera-pxa.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 */
+
+ /* 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,
+
+ /* LCD... L_BIAS alt fn not configured on Treo680; is GPIO instead */
+ GPIOxx_LCD_16BPP,
+ GPIO74_LCD_FCLK,
+ GPIO75_LCD_LCLK,
+ GPIO76_LCD_PCLK,
+};
+#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,
+
+ /* LCD */
+ GPIOxx_LCD_TFT_16BPP,
+};
+#endif /* CONFIG_MACH_CENTRO */
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+#if IS_ENABLED(CONFIG_KEYBOARD_PXA27x)
+static const 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 const 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 matrix_keymap_data treo680_matrix_keymap_data = {
+ .keymap = treo680_matrix_keys,
+ .keymap_size = ARRAY_SIZE(treo680_matrix_keys),
+};
+
+static struct matrix_keymap_data centro_matrix_keymap_data = {
+ .keymap = centro_matrix_keys,
+ .keymap_size = ARRAY_SIZE(centro_matrix_keys),
+};
+
+static struct pxa27x_keypad_platform_data treo680_keypad_pdata = {
+ .matrix_key_rows = 8,
+ .matrix_key_cols = 7,
+ .matrix_keymap_data = &treo680_matrix_keymap_data,
+ .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_keymap_data = &centro_matrix_keymap_data;
+
+ pxa_set_keypad_info(&treo680_keypad_pdata);
+}
+#else
+static inline void palmtreo_kpc_init(void) {}
+#endif
+
+/******************************************************************************
+ * USB host
+ ******************************************************************************/
+#if IS_ENABLED(CONFIG_USB_OHCI_HCD)
+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
+ ******************************************************************************/
+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,
+};
+
+static void __init palmtreo_leds_init(void)
+{
+ if (machine_is_centro())
+ palmtreo_leds.dev.platform_data = &centro_gpio_led_info;
+ else if (machine_is_treo680())
+ palmtreo_leds.dev.platform_data = &treo680_gpio_led_info;
+
+ platform_device_register(&palmtreo_leds);
+}
+
+/******************************************************************************
+ * diskonchip docg4 flash
+ ******************************************************************************/
+#if defined(CONFIG_MACH_TREO680)
+/* REVISIT: does the centro have this device also? */
+#if IS_ENABLED(CONFIG_MTD_NAND_DOCG4)
+static struct resource docg4_resources[] = {
+ {
+ .start = 0x00000000,
+ .end = 0x00001FFF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device treo680_docg4_flash = {
+ .name = "docg4",
+ .id = -1,
+ .resource = docg4_resources,
+ .num_resources = ARRAY_SIZE(docg4_resources),
+};
+
+static void __init treo680_docg4_flash_init(void)
+{
+ platform_device_register(&treo680_docg4_flash);
+}
+#else
+static inline void treo680_docg4_flash_init(void) {}
+#endif
+#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();
+}
+
+#ifdef CONFIG_MACH_TREO680
+void __init treo680_gpio_init(void)
+{
+ unsigned int gpio;
+
+ /* drive all three lcd gpios high initially */
+ const unsigned long lcd_flags = GPIOF_INIT_HIGH | GPIOF_DIR_OUT;
+
+ /*
+ * LCD GPIO initialization...
+ */
+
+ /*
+ * This is likely the power to the lcd. Toggling it low/high appears to
+ * turn the lcd off/on. Can be toggled after lcd is initialized without
+ * any apparent adverse effects to the lcd operation. Note that this
+ * gpio line is used by the lcd controller as the L_BIAS signal, but
+ * treo680 configures it as gpio.
+ */
+ gpio = GPIO_NR_TREO680_LCD_POWER;
+ if (gpio_request_one(gpio, lcd_flags, "LCD power") < 0)
+ goto fail;
+
+ /*
+ * These two are called "enables", for lack of a better understanding.
+ * If either of these are toggled after the lcd is initialized, the
+ * image becomes degraded. N.B. The IPL shipped with the treo
+ * configures GPIO_NR_TREO680_LCD_EN_N as output and drives it high. If
+ * the IPL is ever reprogrammed, this initialization may be need to be
+ * revisited.
+ */
+ gpio = GPIO_NR_TREO680_LCD_EN;
+ if (gpio_request_one(gpio, lcd_flags, "LCD enable") < 0)
+ goto fail;
+ gpio = GPIO_NR_TREO680_LCD_EN_N;
+ if (gpio_request_one(gpio, lcd_flags, "LCD enable_n") < 0)
+ goto fail;
+
+ /* driving this low turns LCD on */
+ gpio_set_value(GPIO_NR_TREO680_LCD_EN_N, 0);
+
+ return;
+ fail:
+ pr_err("gpio %d initialization failed\n", gpio);
+ gpio_free(GPIO_NR_TREO680_LCD_POWER);
+ gpio_free(GPIO_NR_TREO680_LCD_EN);
+ gpio_free(GPIO_NR_TREO680_LCD_EN_N);
+}
+
+static void __init treo680_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(treo680_pin_config));
+ palmphone_common_init();
+ treo680_gpio_init();
+ palm27x_mmc_init(GPIO_NR_TREO_SD_DETECT_N, GPIO_NR_TREO680_SD_READONLY,
+ GPIO_NR_TREO680_SD_POWER, 0);
+ treo680_docg4_flash_init();
+}
+#endif
+
+#ifdef CONFIG_MACH_CENTRO
+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);
+}
+#endif
+
+#ifdef CONFIG_MACH_TREO680
+MACHINE_START(TREO680, "Palm Treo 680")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .reserve = treo_reserve,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = treo680_init,
+ .restart = pxa_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_CENTRO
+MACHINE_START(CENTRO, "Palm Centro 685")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .reserve = treo_reserve,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = centro_init,
+ .restart = pxa_restart,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
new file mode 100644
index 000000000..83f830dd8
--- /dev/null
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -0,0 +1,376 @@
+/*
+ * 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 <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <linux/platform_data/keypad-pxa27x.h>
+#include <mach/udc.h>
+#include <linux/platform_data/asoc-palm27x.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 const 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 matrix_keymap_data palmtx_matrix_keymap_data = {
+ .keymap = palmtx_matrix_keys,
+ .keymap_size = ARRAY_SIZE(palmtx_matrix_keys),
+};
+
+static struct pxa27x_keypad_platform_data palmtx_keypad_platform_data = {
+ .matrix_key_rows = 4,
+ .matrix_key_cols = 3,
+ .matrix_keymap_data = &palmtx_matrix_keymap_data,
+
+ .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;
+ char __iomem *nandaddr = 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
+ },
+};
+
+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,
+ },
+ .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 = (unsigned long)PALMTX_PCMCIA_VIRT,
+ .pfn = __phys_to_pfn(PALMTX_PCMCIA_PHYS),
+ .length = PALMTX_PCMCIA_SIZE,
+ .type = MT_DEVICE,
+}, {
+ .virtual = (unsigned long)PALMTX_NAND_ALE_VIRT,
+ .pfn = __phys_to_pfn(PALMTX_NAND_ALE_PHYS),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+}, {
+ .virtual = (unsigned long)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")
+ .atag_offset = 0x100,
+ .map_io = palmtx_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = palmtx_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
new file mode 100644
index 000000000..1a35ddf21
--- /dev/null
+++ b/arch/arm/mach-pxa/palmz72.c
@@ -0,0 +1,414 @@
+/*
+ * 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/suspend.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa27x.h>
+#include <mach/audio.h>
+#include <mach/palmz72.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <linux/platform_data/keypad-pxa27x.h>
+#include <mach/udc.h>
+#include <linux/platform_data/asoc-palm27x.h>
+#include <mach/palm27x.h>
+
+#include <mach/pm.h>
+#include <linux/platform_data/camera-pxa.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 const 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 matrix_keymap_data almz72_matrix_keymap_data = {
+ .keymap = palmz72_matrix_keys,
+ .keymap_size = ARRAY_SIZE(palmz72_matrix_keys),
+};
+
+static struct pxa27x_keypad_platform_data palmz72_keypad_platform_data = {
+ .matrix_key_rows = 4,
+ .matrix_key_cols = 3,
+ .matrix_keymap_data = &almz72_matrix_keymap_data,
+
+ .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")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = palmz72_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c
new file mode 100644
index 000000000..69918c7e3
--- /dev/null
+++ b/arch/arm/mach-pxa/pcm027.c
@@ -0,0 +1,269 @@
+/*
+ * 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 */
+ .atag_offset = 0x100,
+ .map_io = pcm027_map_io,
+ .nr_irqs = PCM027_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = pcm027_init,
+ .restart = pxa_restart,
+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 000000000..2897da2a5
--- /dev/null
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -0,0 +1,566 @@
+/*
+ * 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/gpio.h>
+#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/mt9v022.h>
+#include <media/soc_camera.h>
+
+#include <linux/platform_data/camera-pxa.h>
+#include <asm/mach/map.h>
+#include <mach/pxa27x.h>
+#include <mach/audio.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/usb-ohci-pxa27x.h>
+#include <mach/pcm990_baseboard.h>
+#include <linux/platform_data/video-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,
+};
+
+static void __iomem *pcm990_cpld_base;
+
+static u8 pcm990_cpld_readb(unsigned int reg)
+{
+ return readb(pcm990_cpld_base + reg);
+}
+
+static void pcm990_cpld_writeb(u8 value, unsigned int reg)
+{
+ writeb(value, pcm990_cpld_base + reg);
+}
+
+/*
+ * 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_cpld_writeb(PCM990_CTRL_LCDPWR + PCM990_CTRL_LCDON,
+ PCM990_CTRL_REG3);
+ } else {
+ /* disable LCD-Latches
+ * power off LCD
+ */
+ pcm990_cpld_writeb(0, PCM990_CTRL_REG3);
+ }
+}
+#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,
+ .enable_gpio = -1,
+};
+
+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_irq_enabled &= ~(1 << pcm990_irq);
+
+ pcm990_cpld_writeb(pcm990_irq_enabled, PCM990_CTRL_INTMSKENA);
+}
+
+static void pcm990_unmask_irq(struct irq_data *d)
+{
+ int pcm990_irq = (d->irq - PCM027_IRQ(0));
+ u8 val;
+
+ /* the irq can be acknowledged only if deasserted, so it's done here */
+
+ pcm990_irq_enabled |= (1 << pcm990_irq);
+
+ val = pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
+ val |= 1 << pcm990_irq;
+ pcm990_cpld_writeb(val, PCM990_CTRL_INTSETCLR);
+
+ pcm990_cpld_writeb(pcm990_irq_enabled, PCM990_CTRL_INTMSKENA);
+}
+
+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;
+
+ pending = ~pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
+ pending &= 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_cpld_readb(PCM990_CTRL_INTSETCLR);
+ pending &= 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);
+ }
+
+ /* disable all Interrupts */
+ pcm990_cpld_writeb(0x0, PCM990_CTRL_INTMSKENA);
+ pcm990_cpld_writeb(0xff, PCM990_CTRL_INTSETCLR);
+
+ 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, 0,
+ "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 int pcm990_mci_setpower(struct device *dev, unsigned int vdd)
+{
+ struct pxamci_platform_data *p_d = dev->platform_data;
+ u8 val;
+
+ val = pcm990_cpld_readb(PCM990_CTRL_REG5);
+
+ if ((1 << vdd) & p_d->ocr_mask)
+ val |= PCM990_CTRL_MMC2PWR;
+ else
+ val &= ~PCM990_CTRL_MMC2PWR;
+
+ pcm990_cpld_writeb(PCM990_CTRL_MMC2PWR, PCM990_CTRL_REG5);
+ return 0;
+}
+
+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/platform_data/pca953x.h>
+
+static struct pca953x_platform_data pca9536_data = {
+ .gpio_base = PXA_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_cansleep(gpio_bus_switch, 1);
+ else
+ gpio_set_value_cansleep(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(PXA_NR_BUILTIN_GPIO, "camera");
+ if (!ret) {
+ gpio_bus_switch = PXA_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 mt9v022_platform_data mt9v022_pdata = {
+ .y_skip_top = 1,
+};
+
+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],
+ .priv = &mt9v022_pdata,
+ .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 */
+
+/*
+ * 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));
+
+ pcm990_cpld_base = ioremap(PCM990_CTRL_PHYS, PCM990_CTRL_SIZE);
+ if (!pcm990_cpld_base) {
+ pr_err("pcm990: failed to ioremap cpld\n");
+ return;
+ }
+
+ /* 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 000000000..37178a855
--- /dev/null
+++ b/arch/arm/mach-pxa/pm.c
@@ -0,0 +1,118 @@
+/*
+ * 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);
+
+ 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 000000000..195b1121c
--- /dev/null
+++ b/arch/arm/mach-pxa/poodle.c
@@ -0,0 +1,477 @@
+/*
+ * 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/export.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/regulator/machine.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/mtd/sharpsl.h>
+#include <linux/memblock.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/pxa25x.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <mach/udc.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <mach/poodle.h>
+#include <linux/platform_data/video-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);
+
+
+static struct platform_device poodle_audio_device = {
+ .name = "poodle-audio",
+ .id = -1,
+};
+
+/* LoCoMo device */
+static struct resource locomo_resources[] = {
+ [0] = {
+ .start = 0x10000000,
+ .end = 0x10001fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PXA_GPIO_TO_IRQ(10),
+ .end = PXA_GPIO_TO_IRQ(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 = PXA_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 int 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);
+ }
+
+ return 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,
+ &poodle_audio_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)
+{
+ pxa_restart(REBOOT_HARD, NULL);
+}
+
+static void __init poodle_init(void)
+{
+ int ret = 0;
+
+ pm_power_off = poodle_poweroff;
+
+ 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_warn("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();
+ regulator_has_full_constraints();
+}
+
+static void __init fixup_poodle(struct tag *tags, char **cmdline)
+{
+ sharpsl_save_param();
+ memblock_add(0xa0000000, SZ_32M);
+}
+
+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,
+ .handle_irq = pxa25x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = poodle_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/pxa-dt.c b/arch/arm/mach-pxa/pxa-dt.c
new file mode 100644
index 000000000..7e0e5bd0c
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa-dt.c
@@ -0,0 +1,75 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa-dt.c
+ *
+ * Copyright (C) 2012 Daniel Mack
+ *
+ * This 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/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/irqs.h>
+
+#include "generic.h"
+
+#ifdef CONFIG_PXA3xx
+static const struct of_dev_auxdata pxa3xx_auxdata_lookup[] __initconst = {
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40100000, "pxa2xx-uart.0", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40200000, "pxa2xx-uart.1", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40700000, "pxa2xx-uart.2", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-uart", 0x41600000, "pxa2xx-uart.3", NULL),
+ OF_DEV_AUXDATA("marvell,pxa-mmc", 0x41100000, "pxa2xx-mci.0", NULL),
+ OF_DEV_AUXDATA("intel,pxa3xx-gpio", 0x40e00000, "pxa3xx-gpio", NULL),
+ OF_DEV_AUXDATA("marvell,pxa-ohci", 0x4c000000, "pxa27x-ohci", NULL),
+ OF_DEV_AUXDATA("mrvl,pxa-i2c", 0x40301680, "pxa2xx-i2c.0", NULL),
+ OF_DEV_AUXDATA("mrvl,pwri2c", 0x40f500c0, "pxa3xx-i2c.1", NULL),
+ OF_DEV_AUXDATA("marvell,pxa3xx-nand", 0x43100000, "pxa3xx-nand", NULL),
+ {}
+};
+
+static void __init pxa3xx_dt_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table,
+ pxa3xx_auxdata_lookup, NULL);
+}
+
+static const char *pxa3xx_dt_board_compat[] __initdata = {
+ "marvell,pxa300",
+ "marvell,pxa310",
+ "marvell,pxa320",
+ NULL,
+};
+#endif
+
+#ifdef CONFIG_PXA3xx
+DT_MACHINE_START(PXA_DT, "Marvell PXA3xx (Device Tree Support)")
+ .map_io = pxa3xx_map_io,
+ .init_irq = pxa3xx_dt_init_irq,
+ .handle_irq = pxa3xx_handle_irq,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+ .init_machine = pxa3xx_dt_init,
+ .dt_compat = pxa3xx_dt_board_compat,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_PXA27x
+static const char * const pxa27x_dt_board_compat[] __initconst = {
+ "marvell,pxa270",
+ NULL,
+};
+
+DT_MACHINE_START(PXA27X_DT, "Marvell PXA2xx (Device Tree Support)")
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_dt_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .restart = pxa_restart,
+ .dt_compat = pxa27x_dt_board_compat,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
new file mode 100644
index 000000000..66e4a2b63
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -0,0 +1,402 @@
+/*
+ * 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/gpio.h>
+#include <linux/gpio-pxa.h>
+#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 <asm/suspend.h>
+#include <mach/hardware.h>
+#include <mach/irqs.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),
+#ifdef CONFIG_CPU_PXA26x
+ INIT_CLKREG(&clk_dummy, "pxa26x-gpio", NULL),
+#else
+ INIT_CLKREG(&clk_dummy, "pxa25x-gpio", NULL),
+#endif
+ INIT_CLKREG(&clk_dummy, "sa1100-rtc", 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:
+ cpu_suspend(PWRMODE_SLEEP, pxa25x_finish_suspend);
+ 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 = pxa_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);
+}
+
+#ifdef CONFIG_CPU_PXA26x
+void __init pxa26x_init_irq(void)
+{
+ pxa_init_irq(32, pxa25x_set_wake);
+}
+#endif
+
+static struct map_desc pxa25x_io_desc[] __initdata = {
+ { /* Mem Ctl */
+ .virtual = (unsigned long)SMEMC_VIRT,
+ .pfn = __phys_to_pfn(PXA2XX_SMEMC_BASE),
+ .length = SMEMC_SIZE,
+ .type = MT_DEVICE
+ }, { /* UNCACHED_PHYS_0 */
+ .virtual = UNCACHED_PHYS_0,
+ .pfn = __phys_to_pfn(0x00000000),
+ .length = UNCACHED_PHYS_0_SIZE,
+ .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 pxa_gpio_platform_data pxa25x_gpio_info __initdata = {
+ .irq_base = PXA_GPIO_TO_IRQ(0),
+ .gpio_set_wake = gpio_set_wake,
+};
+
+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(&pxa2xx_clock_syscore_ops);
+
+ pxa_register_device(&pxa25x_device_gpio, &pxa25x_gpio_info);
+ 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 000000000..af423a48c
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -0,0 +1,487 @@
+/*
+ * 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/gpio.h>
+#include <linux/gpio-pxa.h>
+#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 <asm/suspend.h>
+#include <mach/irqs.h>
+#include <mach/pxa27x.h>
+#include <mach/reset.h>
+#include <linux/platform_data/usb-ohci-pxa27x.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_AC97_nRESET_GPIO_HIGH,
+ GPIO113_AC97_nRESET,
+ GPIO95_AC97_nRESET_GPIO_HIGH,
+ GPIO95_AC97_nRESET,
+};
+
+void pxa27x_configure_ac97reset(int reset_gpio, bool to_gpio)
+{
+ /*
+ * This helper function is used to work around a bug in the pxa27x's
+ * ac97 controller during a warm reset. The configuration of the
+ * reset_gpio is changed as follows:
+ * to_gpio == true: configured to generic output gpio and driven high
+ * to_gpio == false: configured to ac97 controller alt fn AC97_nRESET
+ */
+
+ if (reset_gpio == 113)
+ pxa2xx_mfp_config(to_gpio ? &ac97_reset_config[0] :
+ &ac97_reset_config[1], 1);
+
+ if (reset_gpio == 95)
+ pxa2xx_mfp_config(to_gpio ? &ac97_reset_config[2] :
+ &ac97_reset_config[3], 1);
+}
+EXPORT_SYMBOL_GPL(pxa27x_configure_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),
+ INIT_CLKREG(&clk_dummy, "pxa27x-gpio", NULL),
+ INIT_CLKREG(&clk_dummy, "sa1100-rtc", 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);
+#ifndef CONFIG_IWMMXT
+ u64 acc0;
+
+ asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0));
+#endif
+
+ /* 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:
+ cpu_suspend(pwrmode, pxa27x_finish_suspend);
+#ifndef CONFIG_IWMMXT
+ asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0));
+#endif
+ 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 = pxa_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);
+}
+
+void __init pxa27x_dt_init_irq(void)
+{
+ if (IS_ENABLED(CONFIG_OF))
+ pxa_dt_irq_init(pxa27x_set_wake);
+}
+
+static struct map_desc pxa27x_io_desc[] __initdata = {
+ { /* Mem Ctl */
+ .virtual = (unsigned long)SMEMC_VIRT,
+ .pfn = __phys_to_pfn(PXA2XX_SMEMC_BASE),
+ .length = SMEMC_SIZE,
+ .type = MT_DEVICE
+ }, { /* UNCACHED_PHYS_0 */
+ .virtual = UNCACHED_PHYS_0,
+ .pfn = __phys_to_pfn(0x00000000),
+ .length = UNCACHED_PHYS_0_SIZE,
+ .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 pxa_gpio_platform_data pxa27x_gpio_info __initdata = {
+ .irq_base = PXA_GPIO_TO_IRQ(0),
+ .gpio_set_wake = gpio_set_wake,
+};
+
+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(&pxa2xx_clock_syscore_ops);
+
+ pxa_register_device(&pxa27x_device_gpio, &pxa27x_gpio_info);
+ 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 000000000..447dcbb22
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa2xx.c
@@ -0,0 +1,56 @@
+/*
+ * 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 <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/mfp-pxa25x.h>
+#include <mach/reset.h>
+#include <linux/platform_data/irda-pxaficp.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 000000000..17cbc0c7b
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa300.c
@@ -0,0 +1,117 @@
+/*
+ * 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 <linux/io.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 000000000..6dc99d4f2
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa320.c
@@ -0,0 +1,100 @@
+/*
+ * 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 <linux/io.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 000000000..1c85275cb
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa3xx-ulpi.c
@@ -0,0 +1,390 @@
+/*
+ * 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 <linux/platform_data/usb-pxa3xx-ulpi.h>
+
+struct pxa3xx_u2d_ulpi {
+ struct clk *clk;
+ void __iomem *mmio_base;
+
+ struct usb_phy *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_warn("%s: ULPI access timed out!\n", __func__);
+
+ return -ETIMEDOUT;
+}
+
+static int pxa310_ulpi_read(struct usb_phy *otg, u32 reg)
+{
+ int err;
+
+ if (pxa310_ulpi_get_phymode() != SYNCH) {
+ pr_warn("%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 usb_phy *otg, u32 val, u32 reg)
+{
+ if (pxa310_ulpi_get_phymode() != SYNCH) {
+ pr_warn("%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 usb_phy_io_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 = usb_phy_init(u2d->otg);
+ if (err) {
+ pr_err("OTG transceiver init failed");
+ return err;
+ }
+
+ err = otg_set_vbus(u2d->otg->otg, 1);
+ if (err) {
+ pr_err("OTG transceiver VBUS set failed");
+ return err;
+ }
+
+ err = otg_set_host(u2d->otg->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->otg, NULL);
+ otg_set_vbus(u2d->otg->otg, 0);
+ usb_phy_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;
+}
+EXPORT_SYMBOL_GPL(pxa3xx_u2d_start_hc);
+
+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);
+}
+EXPORT_SYMBOL_GPL(pxa3xx_u2d_stop_hc);
+
+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",
+ },
+ .probe = pxa3xx_u2d_probe,
+ .remove = pxa3xx_u2d_remove,
+};
+module_platform_driver(pxa3xx_u2d_ulpi_driver);
+
+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 000000000..edcbd9c0b
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -0,0 +1,507 @@
+/*
+ * 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/gpio-pxa.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/syscore_ops.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <asm/mach/map.h>
+#include <asm/suspend.h>
+#include <mach/hardware.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/reset.h>
+#include <linux/platform_data/usb-ohci-pxa27x.h>
+#include <mach/pm.h>
+#include <mach/dma.h>
+#include <mach/smemc.h>
+#include <mach/irqs.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)
+
+extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int));
+
+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_PXA3_CKEN(pxa3xx_gpio, GPIO, 13000000, 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, "pxa3xx-ssp.0", NULL),
+ INIT_CLKREG(&clk_pxa3xx_ssp2, "pxa3xx-ssp.1", NULL),
+ INIT_CLKREG(&clk_pxa3xx_ssp3, "pxa3xx-ssp.2", NULL),
+ INIT_CLKREG(&clk_pxa3xx_ssp4, "pxa3xx-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),
+ INIT_CLKREG(&clk_pxa3xx_gpio, "pxa3xx-gpio", NULL),
+ INIT_CLKREG(&clk_pxa3xx_gpio, "pxa93x-gpio", NULL),
+ INIT_CLKREG(&clk_dummy, "sa1100-rtc", 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;
+#ifndef CONFIG_IWMMXT
+ u64 acc0;
+
+ asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0));
+#endif
+
+ extern int pxa3xx_finish_suspend(unsigned 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);
+
+ cpu_suspend(0, pxa3xx_finish_suspend);
+
+ *p = saved_data;
+
+ AD3ER = 0;
+
+#ifndef CONFIG_IWMMXT
+ asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0));
+#endif
+}
+
+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)
+{
+ pxa_mask_irq(d);
+ PECR &= ~PECR_IE(d->irq - IRQ_WAKEUP0);
+}
+
+static void pxa_unmask_ext_wakeup(struct irq_data *d)
+{
+ pxa_unmask_irq(d);
+ 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(int (*fn)(struct irq_data *,
+ unsigned int))
+{
+ 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;
+}
+
+static 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_ext_wakeup_irq(pxa3xx_set_wake);
+}
+
+void __init pxa3xx_init_irq(void)
+{
+ __pxa3xx_init_irq();
+ pxa_init_irq(56, pxa3xx_set_wake);
+}
+
+#ifdef CONFIG_OF
+void __init pxa3xx_dt_init_irq(void)
+{
+ __pxa3xx_init_irq();
+ pxa_dt_irq_init(pxa3xx_set_wake);
+}
+#endif /* CONFIG_OF */
+
+static struct map_desc pxa3xx_io_desc[] __initdata = {
+ { /* Mem Ctl */
+ .virtual = (unsigned long)SMEMC_VIRT,
+ .pfn = __phys_to_pfn(PXA3XX_SMEMC_BASE),
+ .length = SMEMC_SIZE,
+ .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 pxa_gpio_platform_data pxa3xx_gpio_pdata = {
+ .irq_base = PXA_GPIO_TO_IRQ(0),
+};
+
+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,
+ &pxa3xx_device_ssp1,
+ &pxa3xx_device_ssp2,
+ &pxa3xx_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(&pxa3xx_clock_syscore_ops);
+
+ if (of_have_populated_dt())
+ return 0;
+
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ if (ret)
+ return ret;
+ if (cpu_is_pxa300() || cpu_is_pxa310() || cpu_is_pxa320()) {
+ platform_device_add_data(&pxa3xx_device_gpio,
+ &pxa3xx_gpio_pdata,
+ sizeof(pxa3xx_gpio_pdata));
+ ret = platform_device_register(&pxa3xx_device_gpio);
+ }
+ }
+
+ 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 000000000..ab624487c
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa930.c
@@ -0,0 +1,219 @@
+/*
+ * 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/dma-mapping.h>
+#include <linux/irq.h>
+#include <linux/gpio-pxa.h>
+#include <linux/platform_device.h>
+
+#include <mach/pxa930.h>
+
+#include "devices.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 struct pxa_gpio_platform_data pxa93x_gpio_pdata = {
+ .irq_base = PXA_GPIO_TO_IRQ(0),
+};
+
+static int __init pxa930_init(void)
+{
+ int ret = 0;
+
+ if (cpu_is_pxa93x()) {
+ mfp_init_base(io_p2v(MFPR_BASE));
+ mfp_init_addr(pxa930_mfp_addr_map);
+ platform_device_add_data(&pxa93x_device_gpio,
+ &pxa93x_gpio_pdata,
+ sizeof(pxa93x_gpio_pdata));
+ ret = platform_device_register(&pxa93x_device_gpio);
+ }
+
+ if (cpu_is_pxa935())
+ mfp_init_addr(pxa935_mfp_addr_map);
+
+ return 0;
+}
+
+core_initcall(pxa930_init);
diff --git a/arch/arm/mach-pxa/pxa_cplds_irqs.c b/arch/arm/mach-pxa/pxa_cplds_irqs.c
new file mode 100644
index 000000000..2385052b0
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa_cplds_irqs.c
@@ -0,0 +1,200 @@
+/*
+ * Intel Reference Systems cplds
+ *
+ * Copyright (C) 2014 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.
+ *
+ * Cplds motherboard driver, supporting lubbock and mainstone SoC board.
+ */
+
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+
+#define FPGA_IRQ_MASK_EN 0x0
+#define FPGA_IRQ_SET_CLR 0x10
+
+#define CPLDS_NB_IRQ 32
+
+struct cplds {
+ void __iomem *base;
+ int irq;
+ unsigned int irq_mask;
+ struct gpio_desc *gpio0;
+ struct irq_domain *irqdomain;
+};
+
+static irqreturn_t cplds_irq_handler(int in_irq, void *d)
+{
+ struct cplds *fpga = d;
+ unsigned long pending;
+ unsigned int bit;
+
+ pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask;
+ for_each_set_bit(bit, &pending, CPLDS_NB_IRQ)
+ generic_handle_irq(irq_find_mapping(fpga->irqdomain, bit));
+
+ return IRQ_HANDLED;
+}
+
+static void cplds_irq_mask_ack(struct irq_data *d)
+{
+ struct cplds *fpga = irq_data_get_irq_chip_data(d);
+ unsigned int cplds_irq = irqd_to_hwirq(d);
+ unsigned int set, bit = BIT(cplds_irq);
+
+ fpga->irq_mask &= ~bit;
+ writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
+ set = readl(fpga->base + FPGA_IRQ_SET_CLR);
+ writel(set & ~bit, fpga->base + FPGA_IRQ_SET_CLR);
+}
+
+static void cplds_irq_unmask(struct irq_data *d)
+{
+ struct cplds *fpga = irq_data_get_irq_chip_data(d);
+ unsigned int cplds_irq = irqd_to_hwirq(d);
+ unsigned int bit = BIT(cplds_irq);
+
+ fpga->irq_mask |= bit;
+ writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
+}
+
+static struct irq_chip cplds_irq_chip = {
+ .name = "pxa_cplds",
+ .irq_mask_ack = cplds_irq_mask_ack,
+ .irq_unmask = cplds_irq_unmask,
+ .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
+};
+
+static int cplds_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ struct cplds *fpga = d->host_data;
+
+ irq_set_chip_and_handler(irq, &cplds_irq_chip, handle_level_irq);
+ irq_set_chip_data(irq, fpga);
+
+ return 0;
+}
+
+static const struct irq_domain_ops cplds_irq_domain_ops = {
+ .xlate = irq_domain_xlate_twocell,
+ .map = cplds_irq_domain_map,
+};
+
+static int cplds_resume(struct platform_device *pdev)
+{
+ struct cplds *fpga = platform_get_drvdata(pdev);
+
+ writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
+
+ return 0;
+}
+
+static int cplds_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct cplds *fpga;
+ int ret;
+ int base_irq;
+ unsigned long irqflags = 0;
+
+ fpga = devm_kzalloc(&pdev->dev, sizeof(*fpga), GFP_KERNEL);
+ if (!fpga)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (res) {
+ fpga->irq = (unsigned int)res->start;
+ irqflags = res->flags;
+ }
+ if (!fpga->irq)
+ return -ENODEV;
+
+ base_irq = platform_get_irq(pdev, 1);
+ if (base_irq < 0)
+ base_irq = 0;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ fpga->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(fpga->base))
+ return PTR_ERR(fpga->base);
+
+ platform_set_drvdata(pdev, fpga);
+
+ writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
+ writel(0, fpga->base + FPGA_IRQ_SET_CLR);
+
+ ret = devm_request_irq(&pdev->dev, fpga->irq, cplds_irq_handler,
+ irqflags, dev_name(&pdev->dev), fpga);
+ if (ret == -ENOSYS)
+ return -EPROBE_DEFER;
+
+ if (ret) {
+ dev_err(&pdev->dev, "couldn't request main irq%d: %d\n",
+ fpga->irq, ret);
+ return ret;
+ }
+
+ irq_set_irq_wake(fpga->irq, 1);
+ fpga->irqdomain = irq_domain_add_linear(pdev->dev.of_node,
+ CPLDS_NB_IRQ,
+ &cplds_irq_domain_ops, fpga);
+ if (!fpga->irqdomain)
+ return -ENODEV;
+
+ if (base_irq) {
+ ret = irq_create_strict_mappings(fpga->irqdomain, base_irq, 0,
+ CPLDS_NB_IRQ);
+ if (ret) {
+ dev_err(&pdev->dev, "couldn't create the irq mapping %d..%d\n",
+ base_irq, base_irq + CPLDS_NB_IRQ);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int cplds_remove(struct platform_device *pdev)
+{
+ struct cplds *fpga = platform_get_drvdata(pdev);
+
+ irq_set_chip_and_handler(fpga->irq, NULL, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id cplds_id_table[] = {
+ { .compatible = "intel,lubbock-cplds-irqs", },
+ { .compatible = "intel,mainstone-cplds-irqs", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, cplds_id_table);
+
+static struct platform_driver cplds_driver = {
+ .driver = {
+ .name = "pxa_cplds_irqs",
+ .of_match_table = of_match_ptr(cplds_id_table),
+ },
+ .probe = cplds_probe,
+ .remove = cplds_remove,
+ .resume = cplds_resume,
+};
+
+module_platform_driver(cplds_driver);
+
+MODULE_DESCRIPTION("PXA Cplds interrupts driver");
+MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c
new file mode 100644
index 000000000..6dc4f025e
--- /dev/null
+++ b/arch/arm/mach-pxa/raumfeld.c
@@ -0,0 +1,1131 @@
+/*
+ * 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/system_info.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa300.h>
+#include <linux/platform_data/usb-ohci-pxa27x.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/mtd-nand-pxa3xx.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 = PXA_GPIO_TO_IRQ(GPIO_ETH_IRQ),
+ .end = PXA_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,
+ .num_cs = 1,
+ .parts[0] = raumfeld_nand_partitions,
+ .nr_parts[0] = 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,
+ .ext_pullup_enable_pin = -EINVAL,
+};
+
+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_warn("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,
+ .enable_gpio = -1,
+};
+
+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_warn("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_warn("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 = PXA_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);
+ power_supply_put(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_warn("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_warn("Unable to request GPIO_CHARGE_DC_OK\n");
+
+ ret = gpio_request(GPIO_CHARGE_USB_SUSP, "CHARGE_USB_SUSP");
+ if (ret < 0)
+ pr_warn("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,
+ .irq_gpio = GPIO_TOUCH_IRQ,
+};
+
+static struct i2c_board_info raumfeld_controller_i2c_board_info __initdata = {
+ .type = "eeti_ts",
+ .addr = 0x0a,
+ .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_warn("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_warn("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_warn("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_warn("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_warn("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_warn("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_warn("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")
+ .atag_offset = 0x100,
+ .init_machine = raumfeld_controller_init,
+ .map_io = pxa3xx_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .handle_irq = pxa3xx_handle_irq,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_RAUMFELD_CONNECTOR
+MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector")
+ .atag_offset = 0x100,
+ .init_machine = raumfeld_connector_init,
+ .map_io = pxa3xx_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .handle_irq = pxa3xx_handle_irq,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_RAUMFELD_SPEAKER
+MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker")
+ .atag_offset = 0x100,
+ .init_machine = raumfeld_speaker_init,
+ .map_io = pxa3xx_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .handle_irq = pxa3xx_handle_irq,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c
new file mode 100644
index 000000000..263b15249
--- /dev/null
+++ b/arch/arm/mach-pxa/reset.c
@@ -0,0 +1,113 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it 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 <asm/system_misc.h>
+
+#include <mach/regs-ost.h>
+#include <mach/reset.h>
+#include <mach/smemc.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 */
+ writel_relaxed(OWER_WME, OWER);
+ writel_relaxed(OSSR_M3, OSSR);
+ /* ... in 100 ms */
+ writel_relaxed(readl_relaxed(OSCR) + 368640, OSMR3);
+ /*
+ * SDRAM hangs on watchdog reset on Marvell PXA270 (erratum 71)
+ * we put SDRAM into self-refresh to prevent that
+ */
+ while (1)
+ writel_relaxed(MDREFR_SLFRSH, MDREFR);
+}
+
+void pxa_restart(enum reboot_mode mode, const char *cmd)
+{
+ local_irq_disable();
+ local_fiq_disable();
+
+ clear_reset_status(RESET_STATUS_ALL);
+
+ switch (mode) {
+ case REBOOT_SOFT:
+ /* Jump into ROM at address 0 */
+ soft_restart(0);
+ break;
+ case REBOOT_GPIO:
+ do_gpio_reset();
+ break;
+ case REBOOT_HARD:
+ 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 000000000..710c493ea
--- /dev/null
+++ b/arch/arm/mach-pxa/saar.c
@@ -0,0 +1,607 @@
+/*
+ * 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 <linux/platform_data/video-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 = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO97)),
+ .end = PXA_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 = PXA_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_32M + SZ_16M,
+ .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> */
+ .atag_offset = 0x100,
+ .map_io = pxa3xx_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .handle_irq = pxa3xx_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = saar_init,
+ .restart = pxa_restart,
+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 000000000..051a6555c
--- /dev/null
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -0,0 +1,955 @@
+/*
+ * 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 <linux/io.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);
+#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)
+
+extern int max1111_read_channel(int);
+/*
+ * 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;
+
+ /* 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(&toggle_charger);
+ flush_delayed_work(&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;
+}
+
+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 sharpsl_pm_probe(struct platform_device *pdev)
+{
+ int ret, irq;
+
+ 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 */
+ irq = gpio_to_irq(sharpsl_pm.machinfo->gpio_acin);
+ if (request_irq(irq, sharpsl_ac_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "AC Input Detect", sharpsl_ac_isr)) {
+ dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", irq);
+ }
+
+ irq = gpio_to_irq(sharpsl_pm.machinfo->gpio_batlock);
+ if (request_irq(irq, sharpsl_fatal_isr, IRQF_TRIGGER_FALLING, "Battery Cover", sharpsl_fatal_isr)) {
+ dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", irq);
+ }
+
+ if (sharpsl_pm.machinfo->gpio_fatal) {
+ irq = gpio_to_irq(sharpsl_pm.machinfo->gpio_fatal);
+ if (request_irq(irq, sharpsl_fatal_isr, IRQF_TRIGGER_FALLING, "Fatal Battery", sharpsl_fatal_isr)) {
+ dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", irq);
+ }
+ }
+
+ if (sharpsl_pm.machinfo->batfull_irq) {
+ /* Register interrupt handler. */
+ irq = gpio_to_irq(sharpsl_pm.machinfo->gpio_batfull);
+ if (request_irq(irq, sharpsl_chrg_full_isr, IRQF_TRIGGER_RISING, "CO", sharpsl_chrg_full_isr)) {
+ dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", irq);
+ }
+ }
+
+ 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(gpio_to_irq(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
+ free_irq(gpio_to_irq(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
+
+ if (sharpsl_pm.machinfo->gpio_fatal)
+ free_irq(gpio_to_irq(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr);
+
+ if (sharpsl_pm.machinfo->batfull_irq)
+ free_irq(gpio_to_irq(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 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 000000000..6c5b3ffd2
--- /dev/null
+++ b/arch/arm/mach-pxa/sleep.S
@@ -0,0 +1,171 @@
+/*
+ * 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_finish_suspend() - forces CPU into sleep state (S2D3C4)
+ */
+ENTRY(pxa3xx_finish_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_finish_suspend()
+ *
+ * Forces CPU into sleep state.
+ *
+ * r0 = value for PWRMODE M field for desired sleep state
+ */
+ENTRY(pxa27x_finish_suspend)
+ @ Put the processor to sleep
+ @ (also workaround for sighting 28071)
+
+ @ prepare value for sleep mode
+ mov r1, r0 @ 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_finish_suspend()
+ *
+ * Forces CPU into sleep state.
+ *
+ * r0 = value for PWRMODE M field for desired sleep state
+ */
+
+ENTRY(pxa25x_finish_suspend)
+ @ prepare value for sleep mode
+ mov r1, r0 @ 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 38 ...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
diff --git a/arch/arm/mach-pxa/smemc.c b/arch/arm/mach-pxa/smemc.c
new file mode 100644
index 000000000..f38aa890b
--- /dev/null
+++ b/arch/arm/mach-pxa/smemc.c
@@ -0,0 +1,71 @@
+/*
+ * 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);
+ /* CSMSADRCFG wakes up in its default state (0), so we need to set it */
+ __raw_writel(0x2, CSMSADRCFG);
+}
+
+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()) {
+ /*
+ * The only documentation we have on the
+ * Chip Select Configuration Register (CSMSADRCFG) is that
+ * it must be programmed to 0x2.
+ * Moreover, in the bit definitions, the second bit
+ * (CSMSADRCFG[1]) is called "SETALWAYS".
+ * Other bits are reserved in this register.
+ */
+ __raw_writel(0x2, CSMSADRCFG);
+
+ 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 000000000..f4e2e2719
--- /dev/null
+++ b/arch/arm/mach-pxa/spitz.c
@@ -0,0 +1,1029 @@
+/*
+ * 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/platform_data/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 <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/memblock.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 <linux/platform_data/irda-pxaficp.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/usb-ohci-pxa27x.h>
+#include <linux/platform_data/video-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 = PXA_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 int 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);
+
+ return 0;
+}
+
+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
+
+/******************************************************************************
+ * NAND Flash
+ ******************************************************************************/
+#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
+
+/******************************************************************************
+ * I2C devices
+ ******************************************************************************/
+#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[] = {
+ REGULATOR_SUPPLY("vcc_core", NULL),
+};
+
+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
+
+/******************************************************************************
+ * Audio devices
+ ******************************************************************************/
+static inline void spitz_audio_init(void)
+{
+ platform_device_register_simple("spitz-audio", -1, NULL, 0);
+}
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static void spitz_poweroff(void)
+{
+ pxa_restart(REBOOT_GPIO, NULL);
+}
+
+static void spitz_restart(enum reboot_mode 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;
+
+ 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();
+ spitz_audio_init();
+
+ regulator_has_full_constraints();
+}
+
+static void __init spitz_fixup(struct tag *tags, char **cmdline)
+{
+ sharpsl_save_param();
+ memblock_add(0xa0000000, SZ_64M);
+}
+
+#ifdef CONFIG_MACH_SPITZ
+MACHINE_START(SPITZ, "SHARP Spitz")
+ .fixup = spitz_fixup,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_machine = spitz_init,
+ .init_time = pxa_timer_init,
+ .restart = spitz_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_BORZOI
+MACHINE_START(BORZOI, "SHARP Borzoi")
+ .fixup = spitz_fixup,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_machine = spitz_init,
+ .init_time = pxa_timer_init,
+ .restart = spitz_restart,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_AKITA
+MACHINE_START(AKITA, "SHARP Akita")
+ .fixup = spitz_fixup,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_machine = spitz_init,
+ .init_time = pxa_timer_init,
+ .restart = spitz_restart,
+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 000000000..e191f9996
--- /dev/null
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -0,0 +1,262 @@
+/*
+ * 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/gpio-pxa.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_AC_IN, GPIOF_IN, "Charger Detection" },
+ { 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_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, 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)
+{
+}
+
+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)
+{
+ unsigned long ret;
+ ret = ((!gpio_get_value(SPITZ_GPIO_KEY_INT)
+ << GPIO_bit(SPITZ_GPIO_KEY_INT))
+ | gpio_get_value(SPITZ_GPIO_SYNC));
+ return ret;
+}
+
+unsigned long spitzpm_read_devdata(int type)
+{
+ switch (type) {
+ case SHARPSL_STATUS_ACIN:
+ return !gpio_get_value(SPITZ_GPIO_AC_IN);
+ 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 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 000000000..eab1645bb
--- /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
+ ret 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]
+
+ ret 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 000000000..01de54243
--- /dev/null
+++ b/arch/arm/mach-pxa/stargate2.c
@@ -0,0 +1,1028 @@
+/*
+ * 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/platform_data/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 <linux/platform_data/mmc-pxamci.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/platform_data/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[] = {
+ REGULATOR_SUPPLY("vcc", "sht15"),
+};
+
+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 = PXA_GPIO_TO_IRQ(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 = PXA_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 = PXA_GPIO_TO_IRQ(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 = PXA_GPIO_TO_IRQ(99),
+ }, { /* ITS400 Sensor board only */
+ .type = "tmp175",
+ .addr = 0x4A,
+ .irq = PXA_GPIO_TO_IRQ(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_audio_device = {
+ .name = "imote2-audio",
+ .id = -1,
+};
+
+static struct platform_device *imote2_devices[] = {
+ &stargate2_flash_device,
+ &imote2_leds,
+ &sht15,
+ &imote2_audio_device,
+};
+
+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 = PXA_GPIO_TO_IRQ(40),
+ .end = PXA_GPIO_TO_IRQ(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(PXA_GPIO_TO_IRQ(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 int stargate2_mci_setpower(struct device *dev, unsigned int vdd)
+{
+ gpio_set_value(SG2_SD_POWER_ENABLE, !!vdd);
+ return 0;
+}
+
+static void stargate2_mci_exit(struct device *dev, void *data)
+{
+ free_irq(PXA_GPIO_TO_IRQ(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 = PXA_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 = PXA_GPIO_TO_IRQ(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 = PXA_GPIO_TO_IRQ(99),
+ }, { /* ITS400 Sensor board only */
+ .type = "tmp175",
+ .addr = 0x4A,
+ .irq = PXA_GPIO_TO_IRQ(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,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = imote2_init,
+ .atag_offset = 0x100,
+ .restart = pxa_restart,
+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,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = stargate2_init,
+ .atag_offset = 0x100,
+ .restart = pxa_restart,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c
new file mode 100644
index 000000000..a71da84e7
--- /dev/null
+++ b/arch/arm/mach-pxa/tavorevb.c
@@ -0,0 +1,506 @@
+/*
+ * 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 <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/keypad-pxa27x.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 = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO47)),
+ .end = PXA_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 const 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 matrix_keymap_data tavorevb_matrix_keymap_data = {
+ .keymap = tavorevb_matrix_key_map,
+ .keymap_size = ARRAY_SIZE(tavorevb_matrix_key_map),
+};
+
+static struct pxa27x_keypad_platform_data tavorevb_keypad_info = {
+ .matrix_key_rows = 7,
+ .matrix_key_cols = 7,
+ .matrix_keymap_data = &tavorevb_matrix_keymap_data,
+ .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,
+ .enable_gpio = -1,
+ },
+ [1] = {
+ /* secondary backlight */
+ .pwm_id = 0,
+ .max_brightness = 100,
+ .dft_brightness = 100,
+ .pwm_period_ns = 100000,
+ .enable_gpio = -1,
+ },
+};
+
+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> */
+ .atag_offset = 0x100,
+ .map_io = pxa3xx_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .handle_irq = pxa3xx_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = tavorevb_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c
new file mode 100644
index 000000000..685deff86
--- /dev/null
+++ b/arch/arm/mach-pxa/tosa-bt.c
@@ -0,0 +1,147 @@
+/*
+ * 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 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 = tosa_bt_remove,
+
+ .driver = {
+ .name = "tosa-bt",
+ },
+};
+
+
+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 000000000..7780d1faa
--- /dev/null
+++ b/arch/arm/mach-pxa/tosa.c
@@ -0,0 +1,952 @@
+/*
+ * 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/power/gpio-charger.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 <linux/reboot.h>
+#include <linux/memblock.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <mach/pxa25x.h>
+#include <mach/reset.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <linux/platform_data/mmc-pxamci.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 char *tosa_ac_supplied_to[] = {
+ "main-battery",
+ "backup-battery",
+ "jacket-battery",
+};
+
+static struct gpio_charger_platform_data tosa_power_data = {
+ .name = "charger",
+ .type = POWER_SUPPLY_TYPE_MAINS,
+ .gpio = TOSA_GPIO_AC_IN,
+ .gpio_active_low = 1,
+ .supplied_to = tosa_ac_supplied_to,
+ .num_supplicants = ARRAY_SIZE(tosa_ac_supplied_to),
+};
+
+static struct resource tosa_power_resource[] = {
+ {
+ .name = "ac",
+ .start = PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN),
+ .end = PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN),
+ .flags = IORESOURCE_IRQ |
+ IORESOURCE_IRQ_HIGHEDGE |
+ IORESOURCE_IRQ_LOWEDGE,
+ },
+};
+
+static struct platform_device tosa_power_device = {
+ .name = "gpio-charger",
+ .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, 1, KEY_W),
+ KEY(0, 5, KEY_K),
+ KEY(0, 6, KEY_BACKSPACE),
+ KEY(0, 7, KEY_P),
+ KEY(1, 0, KEY_Q),
+ KEY(1, 1, KEY_E),
+ KEY(1, 2, KEY_T),
+ KEY(1, 3, KEY_Y),
+ KEY(1, 5, KEY_O),
+ KEY(1, 6, KEY_I),
+ KEY(1, 7, KEY_COMMA),
+ KEY(2, 0, KEY_A),
+ KEY(2, 1, KEY_D),
+ KEY(2, 2, KEY_G),
+ KEY(2, 3, KEY_U),
+ KEY(2, 5, KEY_L),
+ KEY(2, 6, KEY_ENTER),
+ KEY(2, 7, KEY_DOT),
+ KEY(3, 0, KEY_Z),
+ KEY(3, 1, KEY_C),
+ KEY(3, 2, KEY_V),
+ KEY(3, 3, KEY_J),
+ KEY(3, 4, TOSA_KEY_ADDRESSBOOK),
+ KEY(3, 5, TOSA_KEY_CANCEL),
+ KEY(3, 6, TOSA_KEY_CENTER),
+ KEY(3, 7, TOSA_KEY_OK),
+ KEY(3, 8, KEY_LEFTSHIFT),
+ KEY(4, 0, KEY_S),
+ KEY(4, 1, KEY_R),
+ KEY(4, 2, KEY_B),
+ KEY(4, 3, KEY_N),
+ KEY(4, 4, TOSA_KEY_CALENDAR),
+ KEY(4, 5, TOSA_KEY_HOMEPAGE),
+ KEY(4, 6, KEY_LEFTCTRL),
+ KEY(4, 7, TOSA_KEY_LIGHT),
+ KEY(4, 9, KEY_RIGHTSHIFT),
+ KEY(5, 0, KEY_TAB),
+ KEY(5, 1, KEY_SLASH),
+ KEY(5, 2, KEY_H),
+ KEY(5, 3, KEY_M),
+ KEY(5, 4, TOSA_KEY_MENU),
+ KEY(5, 6, KEY_UP),
+ KEY(5, 10, TOSA_KEY_FN),
+ KEY(6, 0, KEY_X),
+ KEY(6, 1, KEY_F),
+ KEY(6, 2, KEY_SPACE),
+ KEY(6, 3, KEY_APOSTROPHE),
+ KEY(6, 4, TOSA_KEY_MAIL),
+ KEY(6, 5, KEY_LEFT),
+ KEY(6, 6, KEY_DOWN),
+ KEY(6, 7, 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 tosa_audio_device = {
+ .name = "tosa-audio",
+ .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,
+ &tosa_audio_device,
+};
+
+static void tosa_poweroff(void)
+{
+ pxa_restart(REBOOT_GPIO, NULL);
+}
+
+static void tosa_restart(enum reboot_mode 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)
+{
+ 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;
+
+ PCFR |= PCFR_OPDE;
+
+ /* enable batt_fault */
+ PMCR = 0x01;
+
+ 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 tag *tags, char **cmdline)
+{
+ sharpsl_save_param();
+ memblock_add(0xa0000000, SZ_64M);
+}
+
+MACHINE_START(TOSA, "SHARP Tosa")
+ .fixup = fixup_tosa,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = TOSA_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .init_machine = tosa_init,
+ .init_time = pxa_timer_init,
+ .restart = tosa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
new file mode 100644
index 000000000..872dcb20e
--- /dev/null
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -0,0 +1,577 @@
+/*
+ * 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/export.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 <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/irda-pxaficp.h>
+#include <linux/platform_data/usb-ohci-pxa27x.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_TRIGGER_RISING, "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") */
+ .atag_offset = 0x100,
+ .init_machine = trizeps4_init,
+ .map_io = trizeps4_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+MACHINE_END
+
+MACHINE_START(TRIZEPS4WL, "Keith und Koep Trizeps IV-WL module")
+ /* MAINTAINER("JĂ¼rgen Schindele") */
+ .atag_offset = 0x100,
+ .init_machine = trizeps4_init,
+ .map_io = trizeps4_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
new file mode 100644
index 000000000..de3b08073
--- /dev/null
+++ b/arch/arm/mach-pxa/viper.c
@@ -0,0 +1,1001 @@
+/*
+ * 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 <linux/platform_data/video-pxafb.h>
+#include <mach/regs-uart.h>
+#include <linux/platform_data/pcmcia-pxa2xx_viper.h>
+#include <mach/viper.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+#include <asm/system_info.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,
+ .enable_gpio = -1,
+ .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 = PXA_GPIO_TO_IRQ(VIPER_ETH_GPIO),
+ .end = PXA_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 = PXA_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 = PXA_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 = PXA_GPIO_TO_IRQ(VIPER_USB_GPIO),
+ .end = PXA_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)
+{
+ return kstrtoul(str, 10, &viper_tpm) >= 0;
+}
+
+__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;
+ 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> */
+ .atag_offset = 0x100,
+ .map_io = viper_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = viper_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = viper_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c
new file mode 100644
index 000000000..aa89488f9
--- /dev/null
+++ b/arch/arm/mach-pxa/vpac270.c
@@ -0,0 +1,725 @@
+/*
+ * 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 <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/usb-ohci-pxa27x.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/udc.h>
+#include <linux/platform_data/ata-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 = PXA_GPIO_TO_IRQ(GPIO114_VPAC270_ETH_IRQ),
+ .end = PXA_GPIO_TO_IRQ(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 = PXA_GPIO_TO_IRQ(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 = PXA_GPIO_TO_IRQ(GPIO36_VPAC270_IDE_IRQ),
+ .end = PXA_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[] = {
+ REGULATOR_SUPPLY("vcc_core", NULL),
+};
+
+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")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = vpac270_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/xcep.c b/arch/arm/mach-pxa/xcep.c
new file mode 100644
index 000000000..13b1d4586
--- /dev/null
+++ b/arch/arm/mach-pxa/xcep.c
@@ -0,0 +1,191 @@
+/* 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/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. */
+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")
+ .atag_offset = 0x100,
+ .init_machine = xcep_init,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
+ .init_time = pxa_timer_init,
+ .restart = pxa_restart,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
new file mode 100644
index 000000000..e1a121b36
--- /dev/null
+++ b/arch/arm/mach-pxa/z2.c
@@ -0,0 +1,734 @@
+/*
+ * 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 <linux/platform_data/video-pxafb.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/keypad-pxa27x.h>
+#include <mach/pm.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,
+ .enable_gpio = -1,
+ },
+ [1] = {
+ /* LCD Backlight */
+ .pwm_id = 2,
+ .max_brightness = 1023,
+ .dft_brightness = 512,
+ .pwm_period_ns = 1260320,
+ .enable_gpio = -1,
+ },
+};
+
+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 const 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 matrix_keymap_data z2_matrix_keymap_data = {
+ .keymap = z2_matrix_keys,
+ .keymap_size = ARRAY_SIZE(z2_matrix_keys),
+};
+
+static struct pxa27x_keypad_platform_data z2_keypad_platform_data = {
+ .matrix_key_rows = 7,
+ .matrix_key_cols = 8,
+ .matrix_keymap_data = &z2_matrix_keymap_data,
+
+ .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 = PXA_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[] = {
+ REGULATOR_SUPPLY("vcc_core", NULL),
+};
+
+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
+
+#ifdef CONFIG_PM
+static void z2_power_off(void)
+{
+ /* We're using deep sleep as poweroff, so clear PSPR to ensure that
+ * bootloader will jump to its entry point in resume handler
+ */
+ PSPR = 0x0;
+ local_irq_disable();
+ pxa27x_set_pwrmode(PWRMODE_DEEPSLEEP);
+ pxa27x_cpu_pm_enter(PM_SUSPEND_MEM);
+}
+#else
+#define z2_power_off NULL
+#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();
+
+ pm_power_off = z2_power_off;
+}
+
+MACHINE_START(ZIPIT2, "Zipit Z2")
+ .atag_offset = 0x100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = PXA_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = z2_init,
+ .restart = pxa_restart,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
new file mode 100644
index 000000000..ac2ae5c71
--- /dev/null
+++ b/arch/arm/mach-pxa/zeus.c
@@ -0,0 +1,928 @@
+/*
+ * 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/platform_data/pca953x.h>
+#include <linux/apm-emulation.h>
+#include <linux/can/platform/mcp251x.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+
+#include <asm/mach-types.h>
+#include <asm/suspend.h>
+#include <asm/system_info.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa27x.h>
+#include <mach/regs-uart.h>
+#include <linux/platform_data/usb-ohci-pxa27x.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/udc.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <mach/pm.h>
+#include <mach/audio.h>
+#include <linux/platform_data/pcmcia-pxa2xx_viper.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 = PXA_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 = PXA_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 = PXA_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 = PXA_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 = PXA_GPIO_TO_IRQ(ZEUS_ETH0_GPIO),
+ .end = PXA_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 = PXA_GPIO_TO_IRQ(ZEUS_ETH1_GPIO),
+ .end = PXA_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 struct regulator_consumer_supply can_regulator_consumer =
+ REGULATOR_SUPPLY("vdd", "spi3.0");
+
+static struct regulator_init_data can_regulator_init_data = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .consumer_supplies = &can_regulator_consumer,
+ .num_consumer_supplies = 1,
+};
+
+static struct fixed_voltage_config can_regulator_pdata = {
+ .supply_name = "CAN_SHDN",
+ .microvolts = 3300000,
+ .gpio = ZEUS_CAN_SHDN_GPIO,
+ .init_data = &can_regulator_init_data,
+};
+
+static struct platform_device can_regulator_device = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &can_regulator_pdata,
+ },
+};
+
+static struct mcp251x_platform_data zeus_mcp2515_pdata = {
+ .oscillator_frequency = 16*1000*1000,
+};
+
+static struct spi_board_info zeus_spi_board_info[] = {
+ [0] = {
+ .modalias = "mcp2515",
+ .platform_data = &zeus_mcp2515_pdata,
+ .irq = PXA_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,
+};
+
+/* AC'97 */
+static pxa2xx_audio_ops_t zeus_ac97_info = {
+ .reset_gpio = 95,
+};
+
+
+/*
+ * USB host
+ */
+
+static struct regulator_consumer_supply zeus_ohci_regulator_supplies[] = {
+ REGULATOR_SUPPLY("vbus2", "pxa27x-ohci"),
+};
+
+static struct regulator_init_data zeus_ohci_regulator_data = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(zeus_ohci_regulator_supplies),
+ .consumer_supplies = zeus_ohci_regulator_supplies,
+};
+
+static struct fixed_voltage_config zeus_ohci_regulator_config = {
+ .supply_name = "vbus2",
+ .microvolts = 5000000, /* 5.0V */
+ .gpio = ZEUS_USB2_PWREN_GPIO,
+ .enable_high = 1,
+ .startup_delay = 0,
+ .init_data = &zeus_ohci_regulator_data,
+};
+
+static struct platform_device zeus_ohci_regulator_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &zeus_ohci_regulator_config,
+ },
+};
+
+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,
+};
+
+static void zeus_register_ohci(void)
+{
+ /* Port 2 is shared between host and client interface. */
+ UP2OCR = UP2OCR_HXOE | UP2OCR_HXS | UP2OCR_DMPDE | UP2OCR_DPPDE;
+
+ pxa_set_ohci_info(&zeus_ohci_platform_data);
+}
+
+/*
+ * 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,
+};
+
+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,
+ &can_regulator_device,
+ &zeus_ohci_regulator_device,
+};
+
+#ifdef CONFIG_PM
+static void zeus_power_off(void)
+{
+ local_irq_disable();
+ cpu_suspend(PWRMODE_DEEPSLEEP, pxa27x_finish_suspend);
+}
+#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 = PXA_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));
+
+ zeus_register_ohci();
+
+ 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 = (unsigned long)ZEUS_CPLD_VERSION,
+ .pfn = __phys_to_pfn(ZEUS_CPLD_VERSION_PHYS),
+ .length = 0x1000,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = (unsigned long)ZEUS_CPLD_ISA_IRQ,
+ .pfn = __phys_to_pfn(ZEUS_CPLD_ISA_IRQ_PHYS),
+ .length = 0x1000,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = (unsigned long)ZEUS_CPLD_CONTROL,
+ .pfn = __phys_to_pfn(ZEUS_CPLD_CONTROL_PHYS),
+ .length = 0x1000,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = (unsigned long)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> */
+ .atag_offset = 0x100,
+ .map_io = zeus_map_io,
+ .nr_irqs = ZEUS_NR_IRQS,
+ .init_irq = zeus_init_irq,
+ .handle_irq = pxa27x_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = zeus_init,
+ .restart = pxa_restart,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
new file mode 100644
index 000000000..77daea478
--- /dev/null
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -0,0 +1,439 @@
+/*
+ * 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/pxa3xx.h>
+#include <mach/audio.h>
+#include <linux/platform_data/video-pxafb.h>
+#include <mach/zylonite.h>
+#include <linux/platform_data/mmc-pxamci.h>
+#include <linux/platform_data/usb-ohci-pxa27x.h>
+#include <linux/platform_data/keypad-pxa27x.h>
+#include <linux/platform_data/mtd-nand-pxa3xx.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,
+ .enable_gpio = -1,
+};
+
+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 const 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 matrix_keymap_data zylonite_matrix_keymap_data = {
+ .keymap = zylonite_matrix_key_map,
+ .keymap_size = ARRAY_SIZE(zylonite_matrix_key_map),
+};
+
+static struct pxa27x_keypad_platform_data zylonite_keypad_info = {
+ .matrix_key_rows = 8,
+ .matrix_key_cols = 8,
+ .matrix_keymap_data = &zylonite_matrix_keymap_data,
+
+ .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,
+ .num_cs = 1,
+ .parts[0] = zylonite_nand_partitions,
+ .nr_parts[0] = 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 = PXA_GPIO_TO_IRQ(gpio_eth_irq);
+ smc91x_resources[1].end = PXA_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)")
+ .atag_offset = 0x100,
+ .map_io = pxa3xx_map_io,
+ .nr_irqs = ZYLONITE_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .handle_irq = pxa3xx_handle_irq,
+ .init_time = pxa_timer_init,
+ .init_machine = zylonite_init,
+ .restart = pxa_restart,
+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 000000000..869bce7c3
--- /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/platform_data/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 = PXA_GPIO_TO_IRQ(18),
+ }, {
+ .type = "pca9539",
+ .addr = 0x75,
+ .platform_data = &gpio_exp[1],
+ .irq = PXA_GPIO_TO_IRQ(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 000000000..9942bac4c
--- /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-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
new file mode 100644
index 000000000..2256cd1e2
--- /dev/null
+++ b/arch/arm/mach-qcom/Kconfig
@@ -0,0 +1,25 @@
+menuconfig ARCH_QCOM
+ bool "Qualcomm Support" if ARCH_MULTI_V7
+ select ARCH_SUPPORTS_BIG_ENDIAN
+ select ARM_GIC
+ select ARM_AMBA
+ select PINCTRL
+ select QCOM_SCM if SMP
+ help
+ Support for Qualcomm's devicetree based systems.
+
+if ARCH_QCOM
+
+config ARCH_MSM8X60
+ bool "Enable support for MSM8X60"
+ select CLKSRC_QCOM
+
+config ARCH_MSM8960
+ bool "Enable support for MSM8960"
+ select CLKSRC_QCOM
+
+config ARCH_MSM8974
+ bool "Enable support for MSM8974"
+ select HAVE_ARM_ARCH_TIMER
+
+endif
diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile
new file mode 100644
index 000000000..e324375fa
--- /dev/null
+++ b/arch/arm/mach-qcom/Makefile
@@ -0,0 +1,2 @@
+obj-y := board.o
+obj-$(CONFIG_SMP) += platsmp.o
diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c
new file mode 100644
index 000000000..6d8bbf7d3
--- /dev/null
+++ b/arch/arm/mach-qcom/board.c
@@ -0,0 +1,30 @@
+/* Copyright (c) 2010-2014 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+
+#include <asm/mach/arch.h>
+
+static const char * const qcom_dt_match[] __initconst = {
+ "qcom,apq8064",
+ "qcom,apq8074-dragonboard",
+ "qcom,apq8084",
+ "qcom,ipq8062",
+ "qcom,ipq8064",
+ "qcom,msm8660-surf",
+ "qcom,msm8960-cdp",
+ NULL
+};
+
+DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)")
+ .dt_compat = qcom_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
new file mode 100644
index 000000000..5cde63a64
--- /dev/null
+++ b/arch/arm/mach-qcom/platsmp.c
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it 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/of.h>
+#include <linux/of_address.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/qcom_scm.h>
+
+#include <asm/smp_plat.h>
+
+
+#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x35a0
+#define SCSS_CPU1CORE_RESET 0x2d80
+#define SCSS_DBG_STATUS_CORE_PWRDUP 0x2e64
+
+#define APCS_CPU_PWR_CTL 0x04
+#define PLL_CLAMP BIT(8)
+#define CORE_PWRD_UP BIT(7)
+#define COREPOR_RST BIT(5)
+#define CORE_RST BIT(4)
+#define L2DT_SLP BIT(3)
+#define CLAMP BIT(0)
+
+#define APC_PWR_GATE_CTL 0x14
+#define BHS_CNT_SHIFT 24
+#define LDO_PWR_DWN_SHIFT 16
+#define LDO_BYP_SHIFT 8
+#define BHS_SEG_SHIFT 1
+#define BHS_EN BIT(0)
+
+#define APCS_SAW2_VCTL 0x14
+#define APCS_SAW2_2_VCTL 0x1c
+
+extern void secondary_startup_arm(void);
+
+static DEFINE_SPINLOCK(boot_lock);
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void __ref qcom_cpu_die(unsigned int cpu)
+{
+ wfi();
+}
+#endif
+
+static void qcom_secondary_init(unsigned int cpu)
+{
+ /*
+ * Synchronise with the boot thread.
+ */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+
+static int scss_release_secondary(unsigned int cpu)
+{
+ struct device_node *node;
+ void __iomem *base;
+
+ node = of_find_compatible_node(NULL, NULL, "qcom,gcc-msm8660");
+ if (!node) {
+ pr_err("%s: can't find node\n", __func__);
+ return -ENXIO;
+ }
+
+ base = of_iomap(node, 0);
+ of_node_put(node);
+ if (!base)
+ return -ENOMEM;
+
+ writel_relaxed(0, base + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
+ writel_relaxed(0, base + SCSS_CPU1CORE_RESET);
+ writel_relaxed(3, base + SCSS_DBG_STATUS_CORE_PWRDUP);
+ mb();
+ iounmap(base);
+
+ return 0;
+}
+
+static int kpssv1_release_secondary(unsigned int cpu)
+{
+ int ret = 0;
+ void __iomem *reg, *saw_reg;
+ struct device_node *cpu_node, *acc_node, *saw_node;
+ u32 val;
+
+ cpu_node = of_get_cpu_node(cpu, NULL);
+ if (!cpu_node)
+ return -ENODEV;
+
+ acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
+ if (!acc_node) {
+ ret = -ENODEV;
+ goto out_acc;
+ }
+
+ saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
+ if (!saw_node) {
+ ret = -ENODEV;
+ goto out_saw;
+ }
+
+ reg = of_iomap(acc_node, 0);
+ if (!reg) {
+ ret = -ENOMEM;
+ goto out_acc_map;
+ }
+
+ saw_reg = of_iomap(saw_node, 0);
+ if (!saw_reg) {
+ ret = -ENOMEM;
+ goto out_saw_map;
+ }
+
+ /* Turn on CPU rail */
+ writel_relaxed(0xA4, saw_reg + APCS_SAW2_VCTL);
+ mb();
+ udelay(512);
+
+ /* Krait bring-up sequence */
+ val = PLL_CLAMP | L2DT_SLP | CLAMP;
+ writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+ val &= ~L2DT_SLP;
+ writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+ mb();
+ ndelay(300);
+
+ val |= COREPOR_RST;
+ writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+ mb();
+ udelay(2);
+
+ val &= ~CLAMP;
+ writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+ mb();
+ udelay(2);
+
+ val &= ~COREPOR_RST;
+ writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+ mb();
+ udelay(100);
+
+ val |= CORE_PWRD_UP;
+ writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+ mb();
+
+ iounmap(saw_reg);
+out_saw_map:
+ iounmap(reg);
+out_acc_map:
+ of_node_put(saw_node);
+out_saw:
+ of_node_put(acc_node);
+out_acc:
+ of_node_put(cpu_node);
+ return ret;
+}
+
+static int kpssv2_release_secondary(unsigned int cpu)
+{
+ void __iomem *reg;
+ struct device_node *cpu_node, *l2_node, *acc_node, *saw_node;
+ void __iomem *l2_saw_base;
+ unsigned reg_val;
+ int ret;
+
+ cpu_node = of_get_cpu_node(cpu, NULL);
+ if (!cpu_node)
+ return -ENODEV;
+
+ acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
+ if (!acc_node) {
+ ret = -ENODEV;
+ goto out_acc;
+ }
+
+ l2_node = of_parse_phandle(cpu_node, "next-level-cache", 0);
+ if (!l2_node) {
+ ret = -ENODEV;
+ goto out_l2;
+ }
+
+ saw_node = of_parse_phandle(l2_node, "qcom,saw", 0);
+ if (!saw_node) {
+ ret = -ENODEV;
+ goto out_saw;
+ }
+
+ reg = of_iomap(acc_node, 0);
+ if (!reg) {
+ ret = -ENOMEM;
+ goto out_map;
+ }
+
+ l2_saw_base = of_iomap(saw_node, 0);
+ if (!l2_saw_base) {
+ ret = -ENOMEM;
+ goto out_saw_map;
+ }
+
+ /* Turn on the BHS, turn off LDO Bypass and power down LDO */
+ reg_val = (64 << BHS_CNT_SHIFT) | (0x3f << LDO_PWR_DWN_SHIFT) | BHS_EN;
+ writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
+ mb();
+ /* wait for the BHS to settle */
+ udelay(1);
+
+ /* Turn on BHS segments */
+ reg_val |= 0x3f << BHS_SEG_SHIFT;
+ writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
+ mb();
+ /* wait for the BHS to settle */
+ udelay(1);
+
+ /* Finally turn on the bypass so that BHS supplies power */
+ reg_val |= 0x3f << LDO_BYP_SHIFT;
+ writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
+
+ /* enable max phases */
+ writel_relaxed(0x10003, l2_saw_base + APCS_SAW2_2_VCTL);
+ mb();
+ udelay(50);
+
+ reg_val = COREPOR_RST | CLAMP;
+ writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
+ mb();
+ udelay(2);
+
+ reg_val &= ~CLAMP;
+ writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
+ mb();
+ udelay(2);
+
+ reg_val &= ~COREPOR_RST;
+ writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
+ mb();
+
+ reg_val |= CORE_PWRD_UP;
+ writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
+ mb();
+
+ ret = 0;
+
+ iounmap(l2_saw_base);
+out_saw_map:
+ iounmap(reg);
+out_map:
+ of_node_put(saw_node);
+out_saw:
+ of_node_put(l2_node);
+out_l2:
+ of_node_put(acc_node);
+out_acc:
+ of_node_put(cpu_node);
+
+ return ret;
+}
+
+static DEFINE_PER_CPU(int, cold_boot_done);
+
+static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
+{
+ int ret = 0;
+
+ if (!per_cpu(cold_boot_done, cpu)) {
+ ret = func(cpu);
+ if (!ret)
+ per_cpu(cold_boot_done, cpu) = true;
+ }
+
+ /*
+ * set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+ /*
+ * 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.
+ */
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+ /*
+ * now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&boot_lock);
+
+ return ret;
+}
+
+static int msm8660_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ return qcom_boot_secondary(cpu, scss_release_secondary);
+}
+
+static int kpssv1_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ return qcom_boot_secondary(cpu, kpssv1_release_secondary);
+}
+
+static int kpssv2_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ return qcom_boot_secondary(cpu, kpssv2_release_secondary);
+}
+
+static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int cpu;
+
+ if (qcom_scm_set_cold_boot_addr(secondary_startup_arm,
+ cpu_present_mask)) {
+ for_each_present_cpu(cpu) {
+ if (cpu == smp_processor_id())
+ continue;
+ set_cpu_present(cpu, false);
+ }
+ pr_warn("Failed to set CPU boot address, disabling SMP\n");
+ }
+}
+
+static struct smp_operations smp_msm8660_ops __initdata = {
+ .smp_prepare_cpus = qcom_smp_prepare_cpus,
+ .smp_secondary_init = qcom_secondary_init,
+ .smp_boot_secondary = msm8660_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = qcom_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);
+
+static struct smp_operations qcom_smp_kpssv1_ops __initdata = {
+ .smp_prepare_cpus = qcom_smp_prepare_cpus,
+ .smp_secondary_init = qcom_secondary_init,
+ .smp_boot_secondary = kpssv1_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = qcom_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(qcom_smp_kpssv1, "qcom,kpss-acc-v1", &qcom_smp_kpssv1_ops);
+
+static struct smp_operations qcom_smp_kpssv2_ops __initdata = {
+ .smp_prepare_cpus = qcom_smp_prepare_cpus,
+ .smp_secondary_init = qcom_secondary_init,
+ .smp_boot_secondary = kpssv2_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = qcom_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(qcom_smp_kpssv2, "qcom,kpss-acc-v2", &qcom_smp_kpssv2_ops);
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
new file mode 100644
index 000000000..565925f37
--- /dev/null
+++ b/arch/arm/mach-realview/Kconfig
@@ -0,0 +1,129 @@
+menu "RealView platform type"
+ depends on ARCH_REALVIEW
+
+config REALVIEW_DT
+ bool "Support RealView(R) Device Tree based boot"
+ select ARM_GIC
+ select MFD_SYSCON
+ select POWER_RESET
+ select POWER_RESET_VERSATILE
+ select POWER_SUPPLY
+ select SOC_REALVIEW
+ select USE_OF
+ help
+ Include support for booting the ARM(R) RealView(R) evaluation
+ boards using a device tree machine description.
+
+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
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select HAVE_SMP
+ select MIGHT_HAVE_CACHE_L2X0
+ 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 ARCH_HAS_BARRIERS if SMP
+ select CPU_V6K
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select HAVE_SMP
+ select MIGHT_HAVE_CACHE_L2X0
+ 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 ARCH_HAS_BARRIERS if SMP
+ select ARM_GIC
+ select CPU_V6K
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select HAVE_PATA_PLATFORM
+ select HAVE_SMP
+ select MIGHT_HAVE_CACHE_L2X0
+ 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 ARM_GIC
+ select CPU_V6
+ select HAVE_TCM
+ select MIGHT_HAVE_CACHE_L2X0
+ 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 ARM_GIC
+ select CPU_V7
+ 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 ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET
+ select ARM_GIC
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select HAVE_PATA_PLATFORM
+ select HAVE_SMP
+ select MIGHT_HAVE_CACHE_L2X0
+ 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 000000000..e07fdf7ae
--- /dev/null
+++ b/arch/arm/mach-realview/Makefile
@@ -0,0 +1,13 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := core.o
+obj-$(CONFIG_REALVIEW_DT) += realview-dt.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 000000000..d2c3d788f
--- /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 000000000..c309593ab
--- /dev/null
+++ b/arch/arm/mach-realview/core.c
@@ -0,0 +1,407 @@
+/*
+ * 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/device.h>
+#include <linux/interrupt.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/platform_data/video-clcd-versatile.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
+#include <linux/smc91x.h>
+#include <linux/ata_platform.h>
+#include <linux/amba/mmci.h>
+#include <linux/gfp.h>
+#include <linux/mtd/physmap.h>
+#include <linux/memblock.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.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 <mach/platform.h>
+#include <mach/irqs.h>
+#include <asm/hardware/timer-sp.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 smc91x_platdata smc91x_platdata = {
+ .flags = SMC91X_USE_32BIT | SMC91X_NOWAIT,
+};
+
+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;
+ else
+ realview_eth_device.dev.platform_data = &smc91x_platdata;
+
+ 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_leds_resources[] = {
+ {
+ .start = REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET,
+ .end = REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET + 4,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device realview_leds_device = {
+ .name = "versatile-leds",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(realview_leds_resources),
+ .resource = realview_leds_resources,
+};
+
+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,
+};
+
+void __init realview_init_early(void)
+{
+ void __iomem *sys = __io_address(REALVIEW_SYS_BASE);
+
+ 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,
+};
+
+/*
+ * 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 tag *tags, char **from)
+{
+ /*
+ * Most RealView platforms have 512MB contiguous RAM at 0x70000000.
+ * Half of this is mirrored at 0.
+ */
+#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
+ memblock_add(0x70000000, SZ_512M);
+#else
+ memblock_add(0, SZ_256M);
+#endif
+}
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
new file mode 100644
index 000000000..868ece221
--- /dev/null
+++ b/arch/arm/mach-realview/core.h
@@ -0,0 +1,60 @@
+/*
+ * 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>
+
+#define APB_DEVICE(name, busid, base, plat) \
+static AMBA_APB_DEVICE(name, busid, 0, REALVIEW_##base##_BASE, base##_IRQ, plat)
+
+#define AHB_DEVICE(name, busid, base, plat) \
+static AMBA_AHB_DEVICE(name, busid, 0, REALVIEW_##base##_BASE, base##_IRQ, plat)
+
+struct machine_desc;
+
+extern struct platform_device realview_flash_device;
+extern struct platform_device realview_cf_device;
+extern struct platform_device realview_leds_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_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 tag *tags, char **from);
+
+extern struct smp_operations realview_smp_ops;
+extern void realview_cpu_die(unsigned int cpu);
+
+#endif
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
new file mode 100644
index 000000000..ac22dd41b
--- /dev/null
+++ b/arch/arm/mach-realview/hotplug.c
@@ -0,0 +1,111 @@
+/*
+ * 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/cp15.h>
+#include <asm/smp_plat.h>
+
+static inline void cpu_enter_lowpower(void)
+{
+ unsigned int v;
+
+ 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_logical_map(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)++;
+ }
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void __ref realview_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);
+}
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 000000000..9a732195a
--- /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 000000000..a301e61a5
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/board-eb.h
@@ -0,0 +1,96 @@
+/*
+ * 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_PRIV_MEM_BASE 0x10100000
+#define REALVIEW_EB11MP_L220_BASE 0x10102000 /* L220 registers */
+#define REALVIEW_EB11MP_SYS_PLD_CTRL1 0xD8 /* Register offset for MPCore sysctl */
+#else
+#define REALVIEW_EB11MP_PRIV_MEM_BASE 0x1F000000
+#define REALVIEW_EB11MP_L220_BASE 0x1F002000 /* L220 registers */
+#define REALVIEW_EB11MP_SYS_PLD_CTRL1 0x74 /* Register offset for MPCore sysctl */
+#endif
+
+#define REALVIEW_EB11MP_PRIV_MEM_SIZE SZ_8K
+#define REALVIEW_EB11MP_PRIV_MEM_OFF(x) (REALVIEW_EB11MP_PRIV_MEM_BASE + (x))
+
+#define REALVIEW_EB11MP_SCU_BASE REALVIEW_EB11MP_PRIV_MEM_OFF(0) /* SCU registers */
+#define REALVIEW_EB11MP_GIC_CPU_BASE REALVIEW_EB11MP_PRIV_MEM_OFF(0x0100) /* Generic interrupt controller CPU interface */
+#define REALVIEW_EB11MP_TWD_BASE REALVIEW_EB11MP_PRIV_MEM_OFF(0x0600)
+#define REALVIEW_EB11MP_GIC_DIST_BASE REALVIEW_EB11MP_PRIV_MEM_OFF(0x1000) /* Generic interrupt controller distributor */
+
+/*
+ * 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 000000000..2a15fef94
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/board-pb1176.h
@@ -0,0 +1,83 @@
+/*
+ * 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_DC1176_ROM_BASE 0x10200000 /* 16KiB NRAM preudo-ROM, 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 000000000..aa2d4e02e
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/board-pb11mp.h
@@ -0,0 +1,98 @@
+/*
+ * 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_PRIV_MEM_BASE 0x1F000000
+#define REALVIEW_TC11MP_PRIV_MEM_SIZE SZ_8K
+#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 000000000..4dfc67a4f
--- /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 000000000..848bfff6d
--- /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/hardware.h b/arch/arm/mach-realview/include/mach/hardware.h
new file mode 100644
index 000000000..281e71c97
--- /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) IOMEM(IO_ADDRESS(n))
+
+#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 000000000..44754230f
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/irqs-eb.h
@@ -0,0 +1,132 @@
+/*
+ * 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)
+
+/*
+ * The 11MPcore tile leaves the following unconnected.
+ */
+#define IRQ_EB11MP_UART2 0
+#define IRQ_EB11MP_UART3 0
+#define IRQ_EB11MP_CLCD 0
+#define IRQ_EB11MP_DMA 0
+#define IRQ_EB11MP_WDOG 0
+#define IRQ_EB11MP_GPIO0 0
+#define IRQ_EB11MP_GPIO1 0
+#define IRQ_EB11MP_GPIO2 0
+#define IRQ_EB11MP_SCI 0
+#define IRQ_EB11MP_SSP 0
+
+#define NR_GIC_EB11MP 2
+
+/*
+ * Only define NR_IRQS if less than NR_IRQS_EB
+ */
+#define NR_IRQS_EB (IRQ_EB_GIC_START + 128)
+
+#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 000000000..708f84156
--- /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_GPIO0 (IRQ_DC1176_GIC_START + 16)
+#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_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 000000000..34e255add
--- /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 000000000..4a88a4edb
--- /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 000000000..206a3001f
--- /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 000000000..78854f2fa
--- /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 000000000..23e7a313f
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/memory.h
@@ -0,0 +1,64 @@
+/*
+ * 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
+
+#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_OFFSET PLAT_PHYS_OFFSET
+
+#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 000000000..1b77a27ba
--- /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/uncompress.h b/arch/arm/mach-realview/include/mach/uncompress.h
new file mode 100644
index 000000000..cfa30d217
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/uncompress.h
@@ -0,0 +1,77 @@
+/*
+ * 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()
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
new file mode 100644
index 000000000..98e3052b7
--- /dev/null
+++ b/arch/arm/mach-realview/platsmp.c
@@ -0,0 +1,86 @@
+/*
+ * 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/mach-types.h>
+#include <asm/smp_scu.h>
+
+#include <mach/board-eb.h>
+#include <mach/board-pb11mp.h>
+#include <mach/board-pbx.h>
+
+#include <plat/platsmp.h>
+
+#include "core.h"
+
+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.
+ */
+static void __init realview_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_cpu_ids) {
+ pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
+ ncores, nr_cpu_ids);
+ ncores = nr_cpu_ids;
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+}
+
+static void __init realview_smp_prepare_cpus(unsigned int max_cpus)
+{
+
+ 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(virt_to_phys(versatile_secondary_startup),
+ __io_address(REALVIEW_SYS_FLAGSSET));
+}
+
+struct smp_operations realview_smp_ops __initdata = {
+ .smp_init_cpus = realview_smp_init_cpus,
+ .smp_prepare_cpus = realview_smp_prepare_cpus,
+ .smp_secondary_init = versatile_secondary_init,
+ .smp_boot_secondary = versatile_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = realview_cpu_die,
+#endif
+};
diff --git a/arch/arm/mach-realview/realview-dt.c b/arch/arm/mach-realview/realview-dt.c
new file mode 100644
index 000000000..cc28b89dd
--- /dev/null
+++ b/arch/arm/mach-realview/realview-dt.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * Author: Linus Walleij <linus.walleij@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 <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware/cache-l2x0.h>
+#include "core.h"
+
+static const char *realview_dt_platform_compat[] __initconst = {
+ "arm,realview-eb",
+ "arm,realview-pb1176",
+ "arm,realview-pb11mp",
+ "arm,realview-pba8",
+ "arm,realview-pbx",
+ NULL,
+};
+
+DT_MACHINE_START(REALVIEW_DT, "ARM RealView Machine (Device Tree Support)")
+#ifdef CONFIG_ZONE_DMA
+ .dma_zone_size = SZ_256M,
+#endif
+ .dt_compat = realview_dt_platform_compat,
+ .l2c_aux_val = 0x0,
+ .l2c_aux_mask = ~0x0,
+MACHINE_END
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
new file mode 100644
index 000000000..b3869cbbc
--- /dev/null
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -0,0 +1,485 @@
+/*
+ * 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/device.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 <linux/irqchip/arm-gic.h>
+#include <linux/platform_data/clk-realview.h>
+#include <linux/reboot.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/pgtable.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/smp_twd.h>
+#include <asm/system_info.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_PRIV_MEM_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_EB11MP_PRIV_MEM_BASE),
+ .length = REALVIEW_EB11MP_PRIV_MEM_SIZE,
+ .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,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+ .gpio_base = 8,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+ .gpio_base = 16,
+};
+
+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 }
+#define GPIO3_IRQ { IRQ_EB_GPIO3 }
+
+#define AACI_IRQ { IRQ_EB_AACI }
+#define MMCI0_IRQ { IRQ_EB_MMCI0A, IRQ_EB_MMCI0B }
+#define KMI0_IRQ { IRQ_EB_KMI0 }
+#define KMI1_IRQ { IRQ_EB_KMI1 }
+
+/*
+ * These devices are connected directly to the multi-layer AHB switch
+ */
+#define EB_SMC_IRQ { }
+#define MPMC_IRQ { }
+#define EB_CLCD_IRQ { IRQ_EB_CLCD }
+#define DMAC_IRQ { IRQ_EB_DMA }
+
+/*
+ * These devices are connected via the core APB bridge
+ */
+#define SCTL_IRQ { }
+#define EB_WATCHDOG_IRQ { IRQ_EB_WDOG }
+#define EB_GPIO0_IRQ { IRQ_EB_GPIO0 }
+#define GPIO1_IRQ { IRQ_EB_GPIO1 }
+#define EB_RTC_IRQ { IRQ_EB_RTC }
+
+/*
+ * These devices are connected via the DMA APB bridge
+ */
+#define SCI_IRQ { IRQ_EB_SCI }
+#define EB_UART0_IRQ { IRQ_EB_UART0 }
+#define EB_UART1_IRQ { IRQ_EB_UART1 }
+#define EB_UART2_IRQ { IRQ_EB_UART2 }
+#define EB_UART3_IRQ { IRQ_EB_UART3 }
+#define EB_SSP_IRQ { IRQ_EB_SSP }
+
+/* FPGA Primecells */
+APB_DEVICE(aaci, "fpga:aaci", AACI, NULL);
+APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
+APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
+APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
+APB_DEVICE(uart3, "fpga:uart3", EB_UART3, NULL);
+
+/* DevChip Primecells */
+AHB_DEVICE(smc, "dev:smc", EB_SMC, NULL);
+AHB_DEVICE(clcd, "dev:clcd", EB_CLCD, &clcd_plat_data);
+AHB_DEVICE(dmac, "dev:dmac", DMAC, NULL);
+AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL);
+APB_DEVICE(wdog, "dev:wdog", EB_WATCHDOG, NULL);
+APB_DEVICE(gpio0, "dev:gpio0", EB_GPIO0, &gpio0_plat_data);
+APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
+APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
+APB_DEVICE(rtc, "dev:rtc", EB_RTC, NULL);
+APB_DEVICE(sci0, "dev:sci0", SCI, NULL);
+APB_DEVICE(uart0, "dev:uart0", EB_UART0, NULL);
+APB_DEVICE(uart1, "dev:uart1", EB_UART1, NULL);
+APB_DEVICE(uart2, "dev:uart2", EB_UART2, NULL);
+APB_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 | IORESOURCE_IRQ_HIGHEDGE,
+ },
+};
+
+/*
+ * 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 = {
+ .id = -1,
+ .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;
+}
+
+#ifdef CONFIG_HAVE_ARM_TWD
+static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
+ REALVIEW_EB11MP_TWD_BASE,
+ IRQ_LOCALTIMER);
+
+static void __init realview_eb_twd_init(void)
+{
+ if (core_tile_eb11mp() || core_tile_a9mp()) {
+ int err = twd_local_timer_register(&twd_local_timer);
+ if (err)
+ pr_err("twd_local_timer_register failed %d\n", err);
+ }
+}
+#else
+#define realview_eb_twd_init() do { } while(0)
+#endif
+
+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())
+ timer_irq = IRQ_EB11MP_TIMER0_1;
+ else
+ timer_irq = IRQ_EB_TIMER0_1;
+
+ realview_clk_init(__io_address(REALVIEW_SYS_BASE), false);
+ realview_timer_init(timer_irq);
+ realview_eb_twd_init();
+}
+
+static void realview_eb_restart(enum reboot_mode mode, const char *cmd)
+{
+ 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);
+ dsb();
+}
+
+static void __init realview_eb_init(void)
+{
+ int i;
+
+ if (core_tile_eb11mp() || core_tile_a9mp()) {
+ realview_eb11mp_fixup();
+
+#ifdef CONFIG_CACHE_L2X0
+ /*
+ * The PL220 needs to be manually configured as the hardware
+ * doesn't report the correct sizes.
+ * 1MB (128KB/way), 8-way associativity, event monitor and
+ * parity enabled, ignore share bit, no force write allocate
+ * Bits: .... ...0 0111 1001 0000 .... .... ....
+ */
+ l2x0_init(__io_address(REALVIEW_EB11MP_L220_BASE), 0x00790000, 0xfe000fff);
+#endif
+ pmu_device.name = core_tile_a9mp() ? "armv7-pmu" : "armv6-pmu";
+ 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);
+ platform_device_register(&realview_leds_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);
+ }
+}
+
+MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .atag_offset = 0x100,
+ .smp = smp_ops(realview_smp_ops),
+ .fixup = realview_fixup,
+ .map_io = realview_eb_map_io,
+ .init_early = realview_init_early,
+ .init_irq = gic_init_irq,
+ .init_time = realview_eb_timer_init,
+ .init_machine = realview_eb_init,
+#ifdef CONFIG_ZONE_DMA
+ .dma_zone_size = SZ_256M,
+#endif
+ .restart = realview_eb_restart,
+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 000000000..ce92c1823
--- /dev/null
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -0,0 +1,395 @@
+/*
+ * 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/device.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/pl061.h>
+#include <linux/amba/mmci.h>
+#include <linux/amba/pl022.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+#include <linux/io.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/platform_data/clk-realview.h>
+#include <linux/reboot.h>
+#include <linux/memblock.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/pgtable.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,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+ .gpio_base = 8,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+ .gpio_base = 16,
+};
+
+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 }
+#define GPIO3_IRQ { IRQ_PB1176_GPIO3 }
+#define AACI_IRQ { IRQ_PB1176_AACI }
+#define MMCI0_IRQ { IRQ_PB1176_MMCI0A, IRQ_PB1176_MMCI0B }
+#define KMI0_IRQ { IRQ_PB1176_KMI0 }
+#define KMI1_IRQ { IRQ_PB1176_KMI1 }
+#define PB1176_SMC_IRQ { }
+#define MPMC_IRQ { }
+#define PB1176_CLCD_IRQ { IRQ_DC1176_CLCD }
+#define SCTL_IRQ { }
+#define PB1176_WATCHDOG_IRQ { IRQ_DC1176_WATCHDOG }
+#define PB1176_GPIO0_IRQ { IRQ_DC1176_GPIO0 }
+#define GPIO1_IRQ { IRQ_PB1176_GPIO1 }
+#define PB1176_RTC_IRQ { IRQ_DC1176_RTC }
+#define SCI_IRQ { IRQ_PB1176_SCI }
+#define PB1176_UART0_IRQ { IRQ_DC1176_UART0 }
+#define PB1176_UART1_IRQ { IRQ_DC1176_UART1 }
+#define PB1176_UART2_IRQ { IRQ_DC1176_UART2 }
+#define PB1176_UART3_IRQ { IRQ_DC1176_UART3 }
+#define PB1176_UART4_IRQ { IRQ_PB1176_UART4 }
+#define PB1176_SSP_IRQ { IRQ_DC1176_SSP }
+
+/* FPGA Primecells */
+APB_DEVICE(aaci, "fpga:aaci", AACI, NULL);
+APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
+APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
+APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
+APB_DEVICE(uart4, "fpga:uart4", PB1176_UART4, NULL);
+
+/* DevChip Primecells */
+AHB_DEVICE(smc, "dev:smc", PB1176_SMC, NULL);
+AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL);
+APB_DEVICE(wdog, "dev:wdog", PB1176_WATCHDOG, NULL);
+APB_DEVICE(gpio0, "dev:gpio0", PB1176_GPIO0, &gpio0_plat_data);
+APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
+APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
+APB_DEVICE(rtc, "dev:rtc", PB1176_RTC, NULL);
+APB_DEVICE(sci0, "dev:sci0", SCI, NULL);
+APB_DEVICE(uart0, "dev:uart0", PB1176_UART0, NULL);
+APB_DEVICE(uart1, "dev:uart1", PB1176_UART1, NULL);
+APB_DEVICE(uart2, "dev:uart2", PB1176_UART2, NULL);
+APB_DEVICE(uart3, "dev:uart3", PB1176_UART3, NULL);
+APB_DEVICE(ssp0, "dev:ssp0", PB1176_SSP, &ssp0_plat_data);
+AHB_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[] = {
+ {
+ .start = REALVIEW_PB1176_FLASH_BASE,
+ .end = REALVIEW_PB1176_FLASH_BASE + REALVIEW_PB1176_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+#ifdef CONFIG_REALVIEW_PB1176_SECURE_FLASH
+ {
+ .start = REALVIEW_PB1176_SEC_FLASH_BASE,
+ .end = REALVIEW_PB1176_SEC_FLASH_BASE + REALVIEW_PB1176_SEC_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+#endif
+};
+
+static struct physmap_flash_data pb1176_rom_pdata = {
+ .probe_type = "map_rom",
+ .width = 4,
+ .nr_parts = 0,
+};
+
+static struct resource pb1176_rom_resources[] = {
+ /*
+ * This exposes the PB1176 DevChip ROM as an MTD ROM mapping.
+ * The reference manual states that this is actually a pseudo-ROM
+ * programmed in NVRAM.
+ */
+ {
+ .start = REALVIEW_DC1176_ROM_BASE,
+ .end = REALVIEW_DC1176_ROM_BASE + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device pb1176_rom_device = {
+ .name = "physmap-flash",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pb1176_rom_resources),
+ .resource = pb1176_rom_resources,
+ .dev = {
+ .platform_data = &pb1176_rom_pdata,
+ },
+};
+
+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 = "armv6-pmu",
+ .id = -1,
+ .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_clk_init(__io_address(REALVIEW_SYS_BASE), true);
+ realview_timer_init(IRQ_DC1176_TIMER0);
+}
+
+static void realview_pb1176_restart(enum reboot_mode mode, const char *cmd)
+{
+ 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);
+ dsb();
+}
+
+static void realview_pb1176_fixup(struct tag *tags, char **from)
+{
+ /*
+ * RealView PB1176 only has 128MB of RAM mapped at 0.
+ */
+ memblock_add(0, SZ_128M);
+}
+
+static void __init realview_pb1176_init(void)
+{
+ int i;
+
+#ifdef CONFIG_CACHE_L2X0
+ /*
+ * The PL220 needs to be manually configured as the hardware
+ * doesn't report the correct sizes.
+ * 128kB (16kB/way), 8-way associativity, event monitor and
+ * parity enabled, ignore share bit, no force write allocate
+ * Bits: .... ...0 0111 0011 0000 .... .... ....
+ */
+ l2x0_init(__io_address(REALVIEW_PB1176_L220_BASE), 0x00730000, 0xfe000fff);
+#endif
+
+ realview_flash_register(realview_pb1176_flash_resources,
+ ARRAY_SIZE(realview_pb1176_flash_resources));
+ platform_device_register(&pb1176_rom_device);
+ 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);
+ platform_device_register(&realview_leds_device);
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+}
+
+MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .atag_offset = 0x100,
+ .fixup = realview_pb1176_fixup,
+ .map_io = realview_pb1176_map_io,
+ .init_early = realview_init_early,
+ .init_irq = gic_init_irq,
+ .init_time = realview_pb1176_timer_init,
+ .init_machine = realview_pb1176_init,
+#ifdef CONFIG_ZONE_DMA
+ .dma_zone_size = SZ_256M,
+#endif
+ .restart = realview_pb1176_restart,
+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 000000000..15c45e250
--- /dev/null
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -0,0 +1,379 @@
+/*
+ * 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/device.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 <linux/irqchip/arm-gic.h>
+#include <linux/platform_data/clk-realview.h>
+#include <linux/reboot.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/pgtable.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/smp_twd.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,
+ }, { /* Maps the SCU, GIC CPU interface, TWD, GIC DIST */
+ .virtual = IO_ADDRESS(REALVIEW_TC11MP_PRIV_MEM_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_TC11MP_PRIV_MEM_BASE),
+ .length = REALVIEW_TC11MP_PRIV_MEM_SIZE,
+ .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,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+ .gpio_base = 8,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+ .gpio_base = 16,
+};
+
+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 }
+#define GPIO3_IRQ { IRQ_PB11MP_GPIO3 }
+#define AACI_IRQ { IRQ_TC11MP_AACI }
+#define MMCI0_IRQ { IRQ_TC11MP_MMCI0A, IRQ_TC11MP_MMCI0B }
+#define KMI0_IRQ { IRQ_TC11MP_KMI0 }
+#define KMI1_IRQ { IRQ_TC11MP_KMI1 }
+#define PB11MP_SMC_IRQ { }
+#define MPMC_IRQ { }
+#define PB11MP_CLCD_IRQ { IRQ_PB11MP_CLCD }
+#define DMAC_IRQ { IRQ_PB11MP_DMAC }
+#define SCTL_IRQ { }
+#define PB11MP_WATCHDOG_IRQ { IRQ_PB11MP_WATCHDOG }
+#define PB11MP_GPIO0_IRQ { IRQ_PB11MP_GPIO0 }
+#define GPIO1_IRQ { IRQ_PB11MP_GPIO1 }
+#define PB11MP_RTC_IRQ { IRQ_TC11MP_RTC }
+#define SCI_IRQ { IRQ_PB11MP_SCI }
+#define PB11MP_UART0_IRQ { IRQ_TC11MP_UART0 }
+#define PB11MP_UART1_IRQ { IRQ_TC11MP_UART1 }
+#define PB11MP_UART2_IRQ { IRQ_PB11MP_UART2 }
+#define PB11MP_UART3_IRQ { IRQ_PB11MP_UART3 }
+#define PB11MP_SSP_IRQ { IRQ_PB11MP_SSP }
+
+/* FPGA Primecells */
+APB_DEVICE(aaci, "fpga:aaci", AACI, NULL);
+APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
+APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
+APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
+APB_DEVICE(uart3, "fpga:uart3", PB11MP_UART3, NULL);
+
+/* DevChip Primecells */
+AHB_DEVICE(smc, "dev:smc", PB11MP_SMC, NULL);
+AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL);
+APB_DEVICE(wdog, "dev:wdog", PB11MP_WATCHDOG, NULL);
+APB_DEVICE(gpio0, "dev:gpio0", PB11MP_GPIO0, &gpio0_plat_data);
+APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
+APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
+APB_DEVICE(rtc, "dev:rtc", PB11MP_RTC, NULL);
+APB_DEVICE(sci0, "dev:sci0", SCI, NULL);
+APB_DEVICE(uart0, "dev:uart0", PB11MP_UART0, NULL);
+APB_DEVICE(uart1, "dev:uart1", PB11MP_UART1, NULL);
+APB_DEVICE(uart2, "dev:uart2", PB11MP_UART2, NULL);
+APB_DEVICE(ssp0, "dev:ssp0", PB11MP_SSP, &ssp0_plat_data);
+
+/* Primecells on the NEC ISSP chip */
+AHB_DEVICE(clcd, "issp:clcd", PB11MP_CLCD, &clcd_plat_data);
+AHB_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 = "armv6-pmu",
+ .id = -1,
+ .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);
+}
+
+#ifdef CONFIG_HAVE_ARM_TWD
+static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
+ REALVIEW_TC11MP_TWD_BASE,
+ IRQ_LOCALTIMER);
+
+static void __init realview_pb11mp_twd_init(void)
+{
+ int err = twd_local_timer_register(&twd_local_timer);
+ if (err)
+ pr_err("twd_local_timer_register failed %d\n", err);
+}
+#else
+#define realview_pb11mp_twd_init() do {} while(0)
+#endif
+
+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;
+
+ realview_clk_init(__io_address(REALVIEW_SYS_BASE), false);
+ realview_timer_init(IRQ_TC11MP_TIMER0_1);
+ realview_pb11mp_twd_init();
+}
+
+static void realview_pb11mp_restart(enum reboot_mode mode, const char *cmd)
+{
+ 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);
+ dsb();
+}
+
+static void __init realview_pb11mp_init(void)
+{
+ int i;
+
+#ifdef CONFIG_CACHE_L2X0
+ /*
+ * The PL220 needs to be manually configured as the hardware
+ * doesn't report the correct sizes.
+ * 1MB (128KB/way), 8-way associativity, event monitor and
+ * parity enabled, ignore share bit, no force write allocate
+ * 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);
+ platform_device_register(&realview_leds_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);
+ }
+}
+
+MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .atag_offset = 0x100,
+ .smp = smp_ops(realview_smp_ops),
+ .fixup = realview_fixup,
+ .map_io = realview_pb11mp_map_io,
+ .init_early = realview_init_early,
+ .init_irq = gic_init_irq,
+ .init_time = realview_pb11mp_timer_init,
+ .init_machine = realview_pb11mp_init,
+#ifdef CONFIG_ZONE_DMA
+ .dma_zone_size = SZ_256M,
+#endif
+ .restart = realview_pb11mp_restart,
+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 000000000..4c64662f5
--- /dev/null
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -0,0 +1,315 @@
+/*
+ * 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/device.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 <linux/irqchip/arm-gic.h>
+#include <linux/platform_data/clk-realview.h>
+#include <linux/reboot.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/pgtable.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,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+ .gpio_base = 8,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+ .gpio_base = 16,
+};
+
+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 }
+#define GPIO3_IRQ { IRQ_PBA8_GPIO3 }
+#define AACI_IRQ { IRQ_PBA8_AACI }
+#define MMCI0_IRQ { IRQ_PBA8_MMCI0A, IRQ_PBA8_MMCI0B }
+#define KMI0_IRQ { IRQ_PBA8_KMI0 }
+#define KMI1_IRQ { IRQ_PBA8_KMI1 }
+#define PBA8_SMC_IRQ { }
+#define MPMC_IRQ { }
+#define PBA8_CLCD_IRQ { IRQ_PBA8_CLCD }
+#define DMAC_IRQ { IRQ_PBA8_DMAC }
+#define SCTL_IRQ { }
+#define PBA8_WATCHDOG_IRQ { IRQ_PBA8_WATCHDOG }
+#define PBA8_GPIO0_IRQ { IRQ_PBA8_GPIO0 }
+#define GPIO1_IRQ { IRQ_PBA8_GPIO1 }
+#define PBA8_RTC_IRQ { IRQ_PBA8_RTC }
+#define SCI_IRQ { IRQ_PBA8_SCI }
+#define PBA8_UART0_IRQ { IRQ_PBA8_UART0 }
+#define PBA8_UART1_IRQ { IRQ_PBA8_UART1 }
+#define PBA8_UART2_IRQ { IRQ_PBA8_UART2 }
+#define PBA8_UART3_IRQ { IRQ_PBA8_UART3 }
+#define PBA8_SSP_IRQ { IRQ_PBA8_SSP }
+
+/* FPGA Primecells */
+APB_DEVICE(aaci, "fpga:aaci", AACI, NULL);
+APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
+APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
+APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
+APB_DEVICE(uart3, "fpga:uart3", PBA8_UART3, NULL);
+
+/* DevChip Primecells */
+AHB_DEVICE(smc, "dev:smc", PBA8_SMC, NULL);
+AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL);
+APB_DEVICE(wdog, "dev:wdog", PBA8_WATCHDOG, NULL);
+APB_DEVICE(gpio0, "dev:gpio0", PBA8_GPIO0, &gpio0_plat_data);
+APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
+APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
+APB_DEVICE(rtc, "dev:rtc", PBA8_RTC, NULL);
+APB_DEVICE(sci0, "dev:sci0", SCI, NULL);
+APB_DEVICE(uart0, "dev:uart0", PBA8_UART0, NULL);
+APB_DEVICE(uart1, "dev:uart1", PBA8_UART1, NULL);
+APB_DEVICE(uart2, "dev:uart2", PBA8_UART2, NULL);
+APB_DEVICE(ssp0, "dev:ssp0", PBA8_SSP, &ssp0_plat_data);
+
+/* Primecells on the NEC ISSP chip */
+AHB_DEVICE(clcd, "issp:clcd", PBA8_CLCD, &clcd_plat_data);
+AHB_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 = "armv7-pmu",
+ .id = -1,
+ .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_clk_init(__io_address(REALVIEW_SYS_BASE), false);
+ realview_timer_init(IRQ_PBA8_TIMER0_1);
+}
+
+static void realview_pba8_restart(enum reboot_mode mode, const char *cmd)
+{
+ 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);
+ dsb();
+}
+
+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);
+ platform_device_register(&realview_leds_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);
+ }
+}
+
+MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .atag_offset = 0x100,
+ .fixup = realview_fixup,
+ .map_io = realview_pba8_map_io,
+ .init_early = realview_init_early,
+ .init_irq = gic_init_irq,
+ .init_time = realview_pba8_timer_init,
+ .init_machine = realview_pba8_init,
+#ifdef CONFIG_ZONE_DMA
+ .dma_zone_size = SZ_256M,
+#endif
+ .restart = realview_pba8_restart,
+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 000000000..9a22b8642
--- /dev/null
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -0,0 +1,408 @@
+/*
+ * 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/device.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 <linux/irqchip/arm-gic.h>
+#include <linux/platform_data/clk-realview.h>
+#include <linux/reboot.h>
+#include <linux/memblock.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/smp_twd.h>
+#include <asm/pgtable.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_SCU_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PBX_TILE_SCU_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,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+ .gpio_base = 8,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+ .gpio_base = 16,
+};
+
+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 }
+#define GPIO3_IRQ { IRQ_PBX_GPIO3 }
+#define AACI_IRQ { IRQ_PBX_AACI }
+#define MMCI0_IRQ { IRQ_PBX_MMCI0A, IRQ_PBX_MMCI0B }
+#define KMI0_IRQ { IRQ_PBX_KMI0 }
+#define KMI1_IRQ { IRQ_PBX_KMI1 }
+#define PBX_SMC_IRQ { }
+#define MPMC_IRQ { }
+#define PBX_CLCD_IRQ { IRQ_PBX_CLCD }
+#define DMAC_IRQ { IRQ_PBX_DMAC }
+#define SCTL_IRQ { }
+#define PBX_WATCHDOG_IRQ { IRQ_PBX_WATCHDOG }
+#define PBX_GPIO0_IRQ { IRQ_PBX_GPIO0 }
+#define GPIO1_IRQ { IRQ_PBX_GPIO1 }
+#define PBX_RTC_IRQ { IRQ_PBX_RTC }
+#define SCI_IRQ { IRQ_PBX_SCI }
+#define PBX_UART0_IRQ { IRQ_PBX_UART0 }
+#define PBX_UART1_IRQ { IRQ_PBX_UART1 }
+#define PBX_UART2_IRQ { IRQ_PBX_UART2 }
+#define PBX_UART3_IRQ { IRQ_PBX_UART3 }
+#define PBX_SSP_IRQ { IRQ_PBX_SSP }
+
+/* FPGA Primecells */
+APB_DEVICE(aaci, "fpga:aaci", AACI, NULL);
+APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
+APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
+APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
+APB_DEVICE(uart3, "fpga:uart3", PBX_UART3, NULL);
+
+/* DevChip Primecells */
+AHB_DEVICE(smc, "dev:smc", PBX_SMC, NULL);
+AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL);
+APB_DEVICE(wdog, "dev:wdog", PBX_WATCHDOG, NULL);
+APB_DEVICE(gpio0, "dev:gpio0", PBX_GPIO0, &gpio0_plat_data);
+APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
+APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
+APB_DEVICE(rtc, "dev:rtc", PBX_RTC, NULL);
+APB_DEVICE(sci0, "dev:sci0", SCI, NULL);
+APB_DEVICE(uart0, "dev:uart0", PBX_UART0, NULL);
+APB_DEVICE(uart1, "dev:uart1", PBX_UART1, NULL);
+APB_DEVICE(uart2, "dev:uart2", PBX_UART2, NULL);
+APB_DEVICE(ssp0, "dev:ssp0", PBX_SSP, &ssp0_plat_data);
+
+/* Primecells on the NEC ISSP chip */
+AHB_DEVICE(clcd, "issp:clcd", PBX_CLCD, &clcd_plat_data);
+AHB_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 = "armv7-pmu",
+ .id = -1,
+ .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));
+ }
+}
+
+#ifdef CONFIG_HAVE_ARM_TWD
+static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
+ REALVIEW_PBX_TILE_TWD_BASE,
+ IRQ_LOCALTIMER);
+
+static void __init realview_pbx_twd_init(void)
+{
+ int err = twd_local_timer_register(&twd_local_timer);
+ if (err)
+ pr_err("twd_local_timer_register failed %d\n", err);
+}
+#else
+#define realview_pbx_twd_init() do { } while(0)
+#endif
+
+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;
+
+ realview_clk_init(__io_address(REALVIEW_SYS_BASE), false);
+ realview_timer_init(IRQ_PBX_TIMER0_1);
+ realview_pbx_twd_init();
+}
+
+static void realview_pbx_fixup(struct tag *tags, char **from)
+{
+#ifdef CONFIG_SPARSEMEM
+ /*
+ * Memory configuration with SPARSEMEM enabled on RealView PBX (see
+ * asm/mach/memory.h for more information).
+ */
+
+ memblock_add(0, SZ_256M);
+ memblock_add(0x20000000, SZ_512M);
+ memblock_add(0x80000000, SZ_256M);
+#else
+ realview_fixup(tags, from);
+#endif
+}
+
+static void realview_pbx_restart(enum reboot_mode mode, const char *cmd)
+{
+ 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);
+ dsb();
+}
+
+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 + L310_TAG_LATENCY_CTRL);
+ writel(0, l2x0_base + L310_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);
+ platform_device_register(&realview_leds_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);
+ }
+}
+
+MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .atag_offset = 0x100,
+ .smp = smp_ops(realview_smp_ops),
+ .fixup = realview_pbx_fixup,
+ .map_io = realview_pbx_map_io,
+ .init_early = realview_init_early,
+ .init_irq = gic_init_irq,
+ .init_time = realview_pbx_timer_init,
+ .init_machine = realview_pbx_init,
+#ifdef CONFIG_ZONE_DMA
+ .dma_zone_size = SZ_256M,
+#endif
+ .restart = realview_pbx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
new file mode 100644
index 000000000..ae4eb7cc4
--- /dev/null
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -0,0 +1,20 @@
+config ARCH_ROCKCHIP
+ bool "Rockchip RK2928 and RK3xxx SOCs" if ARCH_MULTI_V7
+ select PINCTRL
+ select PINCTRL_ROCKCHIP
+ select ARCH_HAS_RESET_CONTROLLER
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_AMBA
+ select ARM_GIC
+ select CACHE_L2X0
+ select HAVE_ARM_ARCH_TIMER
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select DW_APB_TIMER_OF
+ select REGULATOR if PM
+ select ROCKCHIP_TIMER
+ select ARM_GLOBAL_TIMER
+ select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+ help
+ Support for Rockchip's Cortex-A9 Single-to-Quad-Core-SoCs
+ containing the RK2928, RK30xx and RK31xx series.
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
new file mode 100644
index 000000000..5c3a9b2de
--- /dev/null
+++ b/arch/arm/mach-rockchip/Makefile
@@ -0,0 +1,5 @@
+CFLAGS_platsmp.o := -march=armv7-a
+
+obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip.o
+obj-$(CONFIG_PM_SLEEP) += pm.o sleep.o
+obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/mach-rockchip/core.h b/arch/arm/mach-rockchip/core.h
new file mode 100644
index 000000000..39bca96b5
--- /dev/null
+++ b/arch/arm/mach-rockchip/core.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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.
+ */
+
+extern char rockchip_secondary_trampoline;
+extern char rockchip_secondary_trampoline_end;
+
+extern unsigned long rockchip_boot_fn;
+extern void rockchip_secondary_startup(void);
diff --git a/arch/arm/mach-rockchip/headsmp.S b/arch/arm/mach-rockchip/headsmp.S
new file mode 100644
index 000000000..46c22dedf
--- /dev/null
+++ b/arch/arm/mach-rockchip/headsmp.S
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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/linkage.h>
+#include <linux/init.h>
+
+ENTRY(rockchip_secondary_startup)
+ mrc p15, 0, r0, c0, c0, 0 @ read main ID register
+ ldr r1, =0x00000c09 @ Cortex-A9 primary part number
+ teq r0, r1
+ beq v7_invalidate_l1
+ b secondary_startup
+ENDPROC(rockchip_secondary_startup)
+
+ENTRY(rockchip_secondary_trampoline)
+ ldr pc, 1f
+ENDPROC(rockchip_secondary_trampoline)
+ .globl rockchip_boot_fn
+rockchip_boot_fn:
+1: .space 4
+
+ENTRY(rockchip_secondary_trampoline_end)
diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c
new file mode 100644
index 000000000..5b4ca3c3c
--- /dev/null
+++ b/arch/arm/mach-rockchip/platsmp.c
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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/delay.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+#include <linux/reset.h>
+#include <linux/cpu.h>
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+#include <asm/smp_scu.h>
+#include <asm/smp_plat.h>
+#include <asm/mach/map.h>
+
+#include "core.h"
+
+static void __iomem *scu_base_addr;
+static void __iomem *sram_base_addr;
+static int ncores;
+
+#define PMU_PWRDN_CON 0x08
+#define PMU_PWRDN_ST 0x0c
+
+#define PMU_PWRDN_SCU 4
+
+static struct regmap *pmu;
+
+static int pmu_power_domain_is_on(int pd)
+{
+ u32 val;
+ int ret;
+
+ ret = regmap_read(pmu, PMU_PWRDN_ST, &val);
+ if (ret < 0)
+ return ret;
+
+ return !(val & BIT(pd));
+}
+
+static struct reset_control *rockchip_get_core_reset(int cpu)
+{
+ struct device *dev = get_cpu_device(cpu);
+ struct device_node *np;
+
+ /* The cpu device is only available after the initial core bringup */
+ if (dev)
+ np = dev->of_node;
+ else
+ np = of_get_cpu_node(cpu, 0);
+
+ return of_reset_control_get(np, NULL);
+}
+
+static int pmu_set_power_domain(int pd, bool on)
+{
+ u32 val = (on) ? 0 : BIT(pd);
+ int ret;
+
+ /*
+ * We need to soft reset the cpu when we turn off the cpu power domain,
+ * or else the active processors might be stalled when the individual
+ * processor is powered down.
+ */
+ if (read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) {
+ struct reset_control *rstc = rockchip_get_core_reset(pd);
+
+ if (IS_ERR(rstc)) {
+ pr_err("%s: could not get reset control for core %d\n",
+ __func__, pd);
+ return PTR_ERR(rstc);
+ }
+
+ if (on)
+ reset_control_deassert(rstc);
+ else
+ reset_control_assert(rstc);
+
+ reset_control_put(rstc);
+ }
+
+ ret = regmap_update_bits(pmu, PMU_PWRDN_CON, BIT(pd), val);
+ if (ret < 0) {
+ pr_err("%s: could not update power domain\n", __func__);
+ return ret;
+ }
+
+ ret = -1;
+ while (ret != on) {
+ ret = pmu_power_domain_is_on(pd);
+ if (ret < 0) {
+ pr_err("%s: could not read power domain state\n",
+ __func__);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Handling of CPU cores
+ */
+
+static int __cpuinit rockchip_boot_secondary(unsigned int cpu,
+ struct task_struct *idle)
+{
+ int ret;
+
+ if (!sram_base_addr || !pmu) {
+ pr_err("%s: sram or pmu missing for cpu boot\n", __func__);
+ return -ENXIO;
+ }
+
+ if (cpu >= ncores) {
+ pr_err("%s: cpu %d outside maximum number of cpus %d\n",
+ __func__, cpu, ncores);
+ return -ENXIO;
+ }
+
+ /* start the core */
+ ret = pmu_set_power_domain(0 + cpu, true);
+ if (ret < 0)
+ return ret;
+
+ if (read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) {
+ /* We communicate with the bootrom to active the cpus other
+ * than cpu0, after a blob of initialize code, they will
+ * stay at wfe state, once they are actived, they will check
+ * the mailbox:
+ * sram_base_addr + 4: 0xdeadbeaf
+ * sram_base_addr + 8: start address for pc
+ * */
+ udelay(10);
+ writel(virt_to_phys(rockchip_secondary_startup),
+ sram_base_addr + 8);
+ writel(0xDEADBEAF, sram_base_addr + 4);
+ dsb_sev();
+ }
+
+ return 0;
+}
+
+/**
+ * rockchip_smp_prepare_sram - populate necessary sram block
+ * Starting cores execute the code residing at the start of the on-chip sram
+ * after power-on. Therefore make sure, this sram region is reserved and
+ * big enough. After this check, copy the trampoline code that directs the
+ * core to the real startup code in ram into the sram-region.
+ * @node: mmio-sram device node
+ */
+static int __init rockchip_smp_prepare_sram(struct device_node *node)
+{
+ unsigned int trampoline_sz = &rockchip_secondary_trampoline_end -
+ &rockchip_secondary_trampoline;
+ struct resource res;
+ unsigned int rsize;
+ int ret;
+
+ ret = of_address_to_resource(node, 0, &res);
+ if (ret < 0) {
+ pr_err("%s: could not get address for node %s\n",
+ __func__, node->full_name);
+ return ret;
+ }
+
+ rsize = resource_size(&res);
+ if (rsize < trampoline_sz) {
+ pr_err("%s: reserved block with size 0x%x is to small for trampoline size 0x%x\n",
+ __func__, rsize, trampoline_sz);
+ return -EINVAL;
+ }
+
+ /* set the boot function for the sram code */
+ rockchip_boot_fn = virt_to_phys(rockchip_secondary_startup);
+
+ /* copy the trampoline to sram, that runs during startup of the core */
+ memcpy(sram_base_addr, &rockchip_secondary_trampoline, trampoline_sz);
+ flush_cache_all();
+ outer_clean_range(0, trampoline_sz);
+
+ dsb_sev();
+
+ return 0;
+}
+
+static const struct regmap_config rockchip_pmu_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+};
+
+static int __init rockchip_smp_prepare_pmu(void)
+{
+ struct device_node *node;
+ void __iomem *pmu_base;
+
+ /*
+ * This function is only called via smp_ops->smp_prepare_cpu().
+ * That only happens if a "/cpus" device tree node exists
+ * and has an "enable-method" property that selects the SMP
+ * operations defined herein.
+ */
+ node = of_find_node_by_path("/cpus");
+
+ pmu = syscon_regmap_lookup_by_phandle(node, "rockchip,pmu");
+ of_node_put(node);
+ if (!IS_ERR(pmu))
+ return 0;
+
+ pmu = syscon_regmap_lookup_by_compatible("rockchip,rk3066-pmu");
+ if (!IS_ERR(pmu))
+ return 0;
+
+ /* fallback, create our own regmap for the pmu area */
+ pmu = NULL;
+ node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-pmu");
+ if (!node) {
+ pr_err("%s: could not find pmu dt node\n", __func__);
+ return -ENODEV;
+ }
+
+ pmu_base = of_iomap(node, 0);
+ if (!pmu_base) {
+ pr_err("%s: could not map pmu registers\n", __func__);
+ return -ENOMEM;
+ }
+
+ pmu = regmap_init_mmio(NULL, pmu_base, &rockchip_pmu_regmap_config);
+ if (IS_ERR(pmu)) {
+ int ret = PTR_ERR(pmu);
+
+ iounmap(pmu_base);
+ pmu = NULL;
+ pr_err("%s: regmap init failed\n", __func__);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus)
+{
+ struct device_node *node;
+ unsigned int i;
+
+ node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-smp-sram");
+ if (!node) {
+ pr_err("%s: could not find sram dt node\n", __func__);
+ return;
+ }
+
+ sram_base_addr = of_iomap(node, 0);
+ if (!sram_base_addr) {
+ pr_err("%s: could not map sram registers\n", __func__);
+ return;
+ }
+
+ if (rockchip_smp_prepare_pmu())
+ return;
+
+ if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
+ if (rockchip_smp_prepare_sram(node))
+ return;
+
+ /* enable the SCU power domain */
+ pmu_set_power_domain(PMU_PWRDN_SCU, true);
+
+ node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+ if (!node) {
+ pr_err("%s: missing scu\n", __func__);
+ return;
+ }
+
+ scu_base_addr = of_iomap(node, 0);
+ if (!scu_base_addr) {
+ pr_err("%s: could not map scu registers\n", __func__);
+ return;
+ }
+
+ /*
+ * While the number of cpus is gathered from dt, also get the
+ * number of cores from the scu to verify this value when
+ * booting the cores.
+ */
+ ncores = scu_get_core_count(scu_base_addr);
+ pr_err("%s: ncores %d\n", __func__, ncores);
+
+ scu_enable(scu_base_addr);
+ } else {
+ unsigned int l2ctlr;
+
+ asm ("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr));
+ ncores = ((l2ctlr >> 24) & 0x3) + 1;
+ }
+
+ /* Make sure that all cores except the first are really off */
+ for (i = 1; i < ncores; i++)
+ pmu_set_power_domain(0 + i, false);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static int rockchip_cpu_kill(unsigned int cpu)
+{
+ pmu_set_power_domain(0 + cpu, false);
+ return 1;
+}
+
+static void rockchip_cpu_die(unsigned int cpu)
+{
+ v7_exit_coherency_flush(louis);
+ while(1)
+ cpu_do_idle();
+}
+#endif
+
+static struct smp_operations rockchip_smp_ops __initdata = {
+ .smp_prepare_cpus = rockchip_smp_prepare_cpus,
+ .smp_boot_secondary = rockchip_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_kill = rockchip_cpu_kill,
+ .cpu_die = rockchip_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(rk3066_smp, "rockchip,rk3066-smp", &rockchip_smp_ops);
diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c
new file mode 100644
index 000000000..b0dcbe28f
--- /dev/null
+++ b/arch/arm/mach-rockchip/pm.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Tony Xie <tony.xie@rock-chips.com>
+ *
+ * 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.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/suspend.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regulator/machine.h>
+
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/suspend.h>
+
+#include "pm.h"
+
+/* These enum are option of low power mode */
+enum {
+ ROCKCHIP_ARM_OFF_LOGIC_NORMAL = 0,
+ ROCKCHIP_ARM_OFF_LOGIC_DEEP = 1,
+};
+
+struct rockchip_pm_data {
+ const struct platform_suspend_ops *ops;
+ int (*init)(struct device_node *np);
+};
+
+static void __iomem *rk3288_bootram_base;
+static phys_addr_t rk3288_bootram_phy;
+
+static struct regmap *pmu_regmap;
+static struct regmap *sgrf_regmap;
+
+static u32 rk3288_pmu_pwr_mode_con;
+static u32 rk3288_sgrf_soc_con0;
+
+static inline u32 rk3288_l2_config(void)
+{
+ u32 l2ctlr;
+
+ asm("mrc p15, 1, %0, c9, c0, 2" : "=r" (l2ctlr));
+ return l2ctlr;
+}
+
+static void rk3288_config_bootdata(void)
+{
+ rkpm_bootdata_cpusp = rk3288_bootram_phy + (SZ_4K - 8);
+ rkpm_bootdata_cpu_code = virt_to_phys(cpu_resume);
+
+ rkpm_bootdata_l2ctlr_f = 1;
+ rkpm_bootdata_l2ctlr = rk3288_l2_config();
+}
+
+static void rk3288_slp_mode_set(int level)
+{
+ u32 mode_set, mode_set1;
+
+ regmap_read(sgrf_regmap, RK3288_SGRF_SOC_CON0, &rk3288_sgrf_soc_con0);
+
+ regmap_read(pmu_regmap, RK3288_PMU_PWRMODE_CON,
+ &rk3288_pmu_pwr_mode_con);
+
+ /*
+ * SGRF_FAST_BOOT_EN - system to boot from FAST_BOOT_ADDR
+ * PCLK_WDT_GATE - disable WDT during suspend.
+ */
+ regmap_write(sgrf_regmap, RK3288_SGRF_SOC_CON0,
+ SGRF_PCLK_WDT_GATE | SGRF_FAST_BOOT_EN
+ | SGRF_PCLK_WDT_GATE_WRITE | SGRF_FAST_BOOT_EN_WRITE);
+
+ /*
+ * The dapswjdp can not auto reset before resume, that cause it may
+ * access some illegal address during resume. Let's disable it before
+ * suspend, and the MASKROM will enable it back.
+ */
+ regmap_write(sgrf_regmap, RK3288_SGRF_CPU_CON0, SGRF_DAPDEVICEEN_WRITE);
+
+ /* booting address of resuming system is from this register value */
+ regmap_write(sgrf_regmap, RK3288_SGRF_FAST_BOOT_ADDR,
+ rk3288_bootram_phy);
+
+ regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1,
+ PMU_ARMINT_WAKEUP_EN);
+
+ mode_set = BIT(PMU_GLOBAL_INT_DISABLE) | BIT(PMU_L2FLUSH_EN) |
+ BIT(PMU_SREF0_ENTER_EN) | BIT(PMU_SREF1_ENTER_EN) |
+ BIT(PMU_DDR0_GATING_EN) | BIT(PMU_DDR1_GATING_EN) |
+ BIT(PMU_PWR_MODE_EN) | BIT(PMU_CHIP_PD_EN) |
+ BIT(PMU_SCU_EN);
+
+ mode_set1 = BIT(PMU_CLR_CORE) | BIT(PMU_CLR_CPUP);
+
+ if (level == ROCKCHIP_ARM_OFF_LOGIC_DEEP) {
+ /* arm off, logic deep sleep */
+ mode_set |= BIT(PMU_BUS_PD_EN) |
+ BIT(PMU_DDR1IO_RET_EN) | BIT(PMU_DDR0IO_RET_EN) |
+ BIT(PMU_OSC_24M_DIS) | BIT(PMU_PMU_USE_LF) |
+ BIT(PMU_ALIVE_USE_LF) | BIT(PMU_PLL_PD_EN);
+
+ mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) |
+ BIT(PMU_CLR_PERI) | BIT(PMU_CLR_DMA);
+ } else {
+ /*
+ * arm off, logic normal
+ * if pmu_clk_core_src_gate_en is not set,
+ * wakeup will be error
+ */
+ mode_set |= BIT(PMU_CLK_CORE_SRC_GATE_EN);
+ }
+
+ regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON, mode_set);
+ regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON1, mode_set1);
+}
+
+static void rk3288_slp_mode_set_resume(void)
+{
+ regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON,
+ rk3288_pmu_pwr_mode_con);
+
+ regmap_write(sgrf_regmap, RK3288_SGRF_SOC_CON0,
+ rk3288_sgrf_soc_con0 | SGRF_PCLK_WDT_GATE_WRITE
+ | SGRF_FAST_BOOT_EN_WRITE);
+}
+
+static int rockchip_lpmode_enter(unsigned long arg)
+{
+ flush_cache_all();
+
+ cpu_do_idle();
+
+ pr_err("%s: Failed to suspend\n", __func__);
+
+ return 1;
+}
+
+static int rk3288_suspend_enter(suspend_state_t state)
+{
+ local_fiq_disable();
+
+ rk3288_slp_mode_set(ROCKCHIP_ARM_OFF_LOGIC_NORMAL);
+
+ cpu_suspend(0, rockchip_lpmode_enter);
+
+ rk3288_slp_mode_set_resume();
+
+ local_fiq_enable();
+
+ return 0;
+}
+
+static int rk3288_suspend_prepare(void)
+{
+ return regulator_suspend_prepare(PM_SUSPEND_MEM);
+}
+
+static void rk3288_suspend_finish(void)
+{
+ if (regulator_suspend_finish())
+ pr_err("%s: Suspend finish failed\n", __func__);
+}
+
+static int rk3288_suspend_init(struct device_node *np)
+{
+ struct device_node *sram_np;
+ struct resource res;
+ int ret;
+
+ pmu_regmap = syscon_node_to_regmap(np);
+ if (IS_ERR(pmu_regmap)) {
+ pr_err("%s: could not find pmu regmap\n", __func__);
+ return PTR_ERR(pmu_regmap);
+ }
+
+ sgrf_regmap = syscon_regmap_lookup_by_compatible(
+ "rockchip,rk3288-sgrf");
+ if (IS_ERR(sgrf_regmap)) {
+ pr_err("%s: could not find sgrf regmap\n", __func__);
+ return PTR_ERR(pmu_regmap);
+ }
+
+ sram_np = of_find_compatible_node(NULL, NULL,
+ "rockchip,rk3288-pmu-sram");
+ if (!sram_np) {
+ pr_err("%s: could not find bootram dt node\n", __func__);
+ return -ENODEV;
+ }
+
+ rk3288_bootram_base = of_iomap(sram_np, 0);
+ if (!rk3288_bootram_base) {
+ pr_err("%s: could not map bootram base\n", __func__);
+ return -ENOMEM;
+ }
+
+ ret = of_address_to_resource(sram_np, 0, &res);
+ if (ret) {
+ pr_err("%s: could not get bootram phy addr\n", __func__);
+ return ret;
+ }
+ rk3288_bootram_phy = res.start;
+
+ of_node_put(sram_np);
+
+ rk3288_config_bootdata();
+
+ /* copy resume code and data to bootsram */
+ memcpy(rk3288_bootram_base, rockchip_slp_cpu_resume,
+ rk3288_bootram_sz);
+
+ regmap_write(pmu_regmap, RK3288_PMU_OSC_CNT, OSC_STABL_CNT_THRESH);
+ regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, PMU_STABL_CNT_THRESH);
+
+ return 0;
+}
+
+static const struct platform_suspend_ops rk3288_suspend_ops = {
+ .enter = rk3288_suspend_enter,
+ .valid = suspend_valid_only_mem,
+ .prepare = rk3288_suspend_prepare,
+ .finish = rk3288_suspend_finish,
+};
+
+static const struct rockchip_pm_data rk3288_pm_data __initconst = {
+ .ops = &rk3288_suspend_ops,
+ .init = rk3288_suspend_init,
+};
+
+static const struct of_device_id rockchip_pmu_of_device_ids[] __initconst = {
+ {
+ .compatible = "rockchip,rk3288-pmu",
+ .data = &rk3288_pm_data,
+ },
+ { /* sentinel */ },
+};
+
+void __init rockchip_suspend_init(void)
+{
+ const struct rockchip_pm_data *pm_data;
+ const struct of_device_id *match;
+ struct device_node *np;
+ int ret;
+
+ np = of_find_matching_node_and_match(NULL, rockchip_pmu_of_device_ids,
+ &match);
+ if (!match) {
+ pr_err("Failed to find PMU node\n");
+ return;
+ }
+ pm_data = (struct rockchip_pm_data *) match->data;
+
+ if (pm_data->init) {
+ ret = pm_data->init(np);
+
+ if (ret) {
+ pr_err("%s: matches init error %d\n", __func__, ret);
+ return;
+ }
+ }
+
+ suspend_set_ops(pm_data->ops);
+}
diff --git a/arch/arm/mach-rockchip/pm.h b/arch/arm/mach-rockchip/pm.h
new file mode 100644
index 000000000..3e8d39c0c
--- /dev/null
+++ b/arch/arm/mach-rockchip/pm.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Tony Xie <tony.xie@rock-chips.com>
+ *
+ * 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.
+ */
+
+#ifndef __MACH_ROCKCHIP_PM_H
+#define __MACH_ROCKCHIP_PM_H
+
+extern unsigned long rkpm_bootdata_cpusp;
+extern unsigned long rkpm_bootdata_cpu_code;
+extern unsigned long rkpm_bootdata_l2ctlr_f;
+extern unsigned long rkpm_bootdata_l2ctlr;
+extern unsigned long rkpm_bootdata_ddr_code;
+extern unsigned long rkpm_bootdata_ddr_data;
+extern unsigned long rk3288_bootram_sz;
+
+void rockchip_slp_cpu_resume(void);
+#ifdef CONFIG_PM_SLEEP
+void __init rockchip_suspend_init(void);
+#else
+static inline void rockchip_suspend_init(void)
+{
+}
+#endif
+
+/****** following is rk3288 defined **********/
+#define RK3288_PMU_WAKEUP_CFG0 0x00
+#define RK3288_PMU_WAKEUP_CFG1 0x04
+#define RK3288_PMU_PWRMODE_CON 0x18
+#define RK3288_PMU_OSC_CNT 0x20
+#define RK3288_PMU_PLL_CNT 0x24
+#define RK3288_PMU_STABL_CNT 0x28
+#define RK3288_PMU_DDR0IO_PWRON_CNT 0x2c
+#define RK3288_PMU_DDR1IO_PWRON_CNT 0x30
+#define RK3288_PMU_CORE_PWRDWN_CNT 0x34
+#define RK3288_PMU_CORE_PWRUP_CNT 0x38
+#define RK3288_PMU_GPU_PWRDWN_CNT 0x3c
+#define RK3288_PMU_GPU_PWRUP_CNT 0x40
+#define RK3288_PMU_WAKEUP_RST_CLR_CNT 0x44
+#define RK3288_PMU_PWRMODE_CON1 0x90
+
+#define RK3288_SGRF_SOC_CON0 (0x0000)
+#define RK3288_SGRF_FAST_BOOT_ADDR (0x0120)
+#define SGRF_PCLK_WDT_GATE BIT(6)
+#define SGRF_PCLK_WDT_GATE_WRITE BIT(22)
+#define SGRF_FAST_BOOT_EN BIT(8)
+#define SGRF_FAST_BOOT_EN_WRITE BIT(24)
+
+#define RK3288_SGRF_CPU_CON0 (0x40)
+#define SGRF_DAPDEVICEEN BIT(0)
+#define SGRF_DAPDEVICEEN_WRITE BIT(16)
+
+#define RK3288_CRU_MODE_CON 0x50
+#define RK3288_CRU_SEL0_CON 0x60
+#define RK3288_CRU_SEL1_CON 0x64
+#define RK3288_CRU_SEL10_CON 0x88
+#define RK3288_CRU_SEL33_CON 0xe4
+#define RK3288_CRU_SEL37_CON 0xf4
+
+/* PMU_WAKEUP_CFG1 bits */
+#define PMU_ARMINT_WAKEUP_EN BIT(0)
+
+/* wait 30ms for OSC stable and 30ms for pmic stable */
+#define OSC_STABL_CNT_THRESH (32 * 30)
+#define PMU_STABL_CNT_THRESH (32 * 30)
+
+enum rk3288_pwr_mode_con {
+ PMU_PWR_MODE_EN = 0,
+ PMU_CLK_CORE_SRC_GATE_EN,
+ PMU_GLOBAL_INT_DISABLE,
+ PMU_L2FLUSH_EN,
+ PMU_BUS_PD_EN,
+ PMU_A12_0_PD_EN,
+ PMU_SCU_EN,
+ PMU_PLL_PD_EN,
+ PMU_CHIP_PD_EN, /* POWER OFF PIN ENABLE */
+ PMU_PWROFF_COMB,
+ PMU_ALIVE_USE_LF,
+ PMU_PMU_USE_LF,
+ PMU_OSC_24M_DIS,
+ PMU_INPUT_CLAMP_EN,
+ PMU_WAKEUP_RESET_EN,
+ PMU_SREF0_ENTER_EN,
+ PMU_SREF1_ENTER_EN,
+ PMU_DDR0IO_RET_EN,
+ PMU_DDR1IO_RET_EN,
+ PMU_DDR0_GATING_EN,
+ PMU_DDR1_GATING_EN,
+ PMU_DDR0IO_RET_DE_REQ,
+ PMU_DDR1IO_RET_DE_REQ
+};
+
+enum rk3288_pwr_mode_con1 {
+ PMU_CLR_BUS = 0,
+ PMU_CLR_CORE,
+ PMU_CLR_CPUP,
+ PMU_CLR_ALIVE,
+ PMU_CLR_DMA,
+ PMU_CLR_PERI,
+ PMU_CLR_GPU,
+ PMU_CLR_VIDEO,
+ PMU_CLR_HEVC,
+ PMU_CLR_VIO,
+};
+
+#endif /* __MACH_ROCKCHIP_PM_H */
diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c
new file mode 100644
index 000000000..b6cf3b449
--- /dev/null
+++ b/arch/arm/mach-rockchip/rockchip.c
@@ -0,0 +1,95 @@
+/*
+ * Device Tree support for Rockchip SoCs
+ *
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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/kernel.h>
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <linux/irqchip.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/cache-l2x0.h>
+#include "core.h"
+#include "pm.h"
+
+#define RK3288_GRF_SOC_CON0 0x244
+#define RK3288_TIMER6_7_PHYS 0xff810000
+
+static void __init rockchip_timer_init(void)
+{
+ if (of_machine_is_compatible("rockchip,rk3288")) {
+ struct regmap *grf;
+ void __iomem *reg_base;
+
+ /*
+ * Most/all uboot versions for rk3288 don't enable timer7
+ * which is needed for the architected timer to work.
+ * So make sure it is running during early boot.
+ */
+ reg_base = ioremap(RK3288_TIMER6_7_PHYS, SZ_16K);
+ if (reg_base) {
+ writel(0, reg_base + 0x30);
+ writel(0xffffffff, reg_base + 0x20);
+ writel(0xffffffff, reg_base + 0x24);
+ writel(1, reg_base + 0x30);
+ dsb();
+ iounmap(reg_base);
+ } else {
+ pr_err("rockchip: could not map timer7 registers\n");
+ }
+
+ /*
+ * Disable auto jtag/sdmmc switching that causes issues
+ * with the mmc controllers making them unreliable
+ */
+ grf = syscon_regmap_lookup_by_compatible("rockchip,rk3288-grf");
+ if (!IS_ERR(grf))
+ regmap_write(grf, RK3288_GRF_SOC_CON0, 0x10000000);
+ else
+ pr_err("rockchip: could not get grf syscon\n");
+ }
+
+ of_clk_init(NULL);
+ clocksource_of_init();
+}
+
+static void __init rockchip_dt_init(void)
+{
+ rockchip_suspend_init();
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ platform_device_register_simple("cpufreq-dt", 0, NULL, 0);
+}
+
+static const char * const rockchip_board_dt_compat[] = {
+ "rockchip,rk2928",
+ "rockchip,rk3066a",
+ "rockchip,rk3066b",
+ "rockchip,rk3188",
+ "rockchip,rk3288",
+ NULL,
+};
+
+DT_MACHINE_START(ROCKCHIP_DT, "Rockchip (Device Tree)")
+ .l2c_aux_val = 0,
+ .l2c_aux_mask = ~0,
+ .init_time = rockchip_timer_init,
+ .dt_compat = rockchip_board_dt_compat,
+ .init_machine = rockchip_dt_init,
+MACHINE_END
diff --git a/arch/arm/mach-rockchip/sleep.S b/arch/arm/mach-rockchip/sleep.S
new file mode 100644
index 000000000..2eec9a341
--- /dev/null
+++ b/arch/arm/mach-rockchip/sleep.S
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Tony Xie <tony.xie@rock-chips.com>
+ *
+ * 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.
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/memory.h>
+
+.data
+/*
+ * this code will be copied from
+ * ddr to sram for system resumeing.
+ * so it is ".data section".
+ */
+.align
+
+ENTRY(rockchip_slp_cpu_resume)
+ setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set svc, irqs off
+ mrc p15, 0, r1, c0, c0, 5
+ and r1, r1, #0xf
+ cmp r1, #0
+ /* olny cpu0 can continue to run, the others is halt here */
+ beq cpu0run
+secondary_loop:
+ wfe
+ b secondary_loop
+cpu0run:
+ ldr r3, rkpm_bootdata_l2ctlr_f
+ cmp r3, #0
+ beq sp_set
+ ldr r3, rkpm_bootdata_l2ctlr
+ mcr p15, 1, r3, c9, c0, 2
+sp_set:
+ ldr sp, rkpm_bootdata_cpusp
+ ldr r1, rkpm_bootdata_cpu_code
+ bx r1
+ENDPROC(rockchip_slp_cpu_resume)
+
+/* Parameters filled in by the kernel */
+
+/* Flag for whether to restore L2CTLR on resume */
+ .global rkpm_bootdata_l2ctlr_f
+rkpm_bootdata_l2ctlr_f:
+ .long 0
+
+/* Saved L2CTLR to restore on resume */
+ .global rkpm_bootdata_l2ctlr
+rkpm_bootdata_l2ctlr:
+ .long 0
+
+/* CPU resume SP addr */
+ .globl rkpm_bootdata_cpusp
+rkpm_bootdata_cpusp:
+ .long 0
+
+/* CPU resume function (physical address) */
+ .globl rkpm_bootdata_cpu_code
+rkpm_bootdata_cpu_code:
+ .long 0
+
+ENTRY(rk3288_bootram_sz)
+ .word . - rockchip_slp_cpu_resume
diff --git a/arch/arm/mach-rpc/Makefile b/arch/arm/mach-rpc/Makefile
new file mode 100644
index 000000000..2ebc6875a
--- /dev/null
+++ b/arch/arm/mach-rpc/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := dma.o ecard.o fiq.o irq.o riscpc.o time.o
diff --git a/arch/arm/mach-rpc/Makefile.boot b/arch/arm/mach-rpc/Makefile.boot
new file mode 100644
index 000000000..ae2df0d7d
--- /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 000000000..6d3517dc4
--- /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,
+ 0, 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/ecard.c b/arch/arm/mach-rpc/ecard.c
new file mode 100644
index 000000000..fcb1d59f7
--- /dev/null
+++ b/arch/arm/mach-rpc/ecard.c
@@ -0,0 +1,1140 @@
+/*
+ * 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/irq.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"
+
+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;
+
+/* 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, (unsigned long)EASI_BASE);
+ dst_pgd = pgd_offset(mm, EASI_START);
+
+ memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (EASI_SIZE / PGDIR_SIZE));
+
+ vma.vm_flags = VM_EXEC;
+ 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)
+{
+}
+
+static void ecard_def_irq_disable(ecard_t *ec, int irqnr)
+{
+}
+
+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 = irq_data_get_irq_chip_data(d);
+
+ 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 = irq_data_get_irq_chip_data(d);
+
+ 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 || 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);
+}
+
+static void __iomem *__ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
+{
+ void __iomem *address = NULL;
+ int slot = ec->slot_no;
+
+ if (ec->slot_no == 8)
+ return ECARD_MEMC8_BASE;
+
+ ectcr &= ~(1 << slot);
+
+ switch (type) {
+ case ECARD_MEMC:
+ if (slot < 4)
+ address = ECARD_MEMC_BASE + (slot << 14);
+ break;
+
+ case ECARD_IOC:
+ if (slot < 4)
+ address = ECARD_IOC_BASE + (slot << 14);
+ else
+ address = ECARD_IOC4_BASE + ((slot - 4) << 14);
+ if (address)
+ address += speed << 19;
+ break;
+
+ case ECARD_EASI:
+ address = ECARD_EASI_BASE + (slot << 24);
+ if (speed == ECARD_FAST)
+ ectcr |= 1 << slot;
+ break;
+
+ 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 = 0;
+ ec->fiq = 0;
+ 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, unsigned irq, card_type_t type)
+{
+ ecard_t **ecp;
+ ecard_t *ec;
+ struct ex_ecid cid;
+ void __iomem *addr;
+ int i, rc;
+
+ ec = ecard_alloc_card(type, slot);
+ if (IS_ERR(ec)) {
+ rc = PTR_ERR(ec);
+ goto nomem;
+ }
+
+ rc = -ENODEV;
+ if ((addr = __ecard_address(ec, type, ECARD_SYNC)) == NULL)
+ 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 = addr;
+
+ 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;
+ }
+
+ ec->irq = irq;
+
+ /*
+ * hook the interrupt handlers
+ */
+ if (slot < 8) {
+ irq_set_chip_and_handler(ec->irq, &ecard_chip,
+ handle_level_irq);
+ irq_set_chip_data(ec->irq, ec);
+ set_irq_flags(ec->irq, IRQF_VALID);
+ }
+
+#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;
+
+ rc = device_register(&ec->dev);
+ if (rc)
+ goto nodev;
+
+ 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, irqbase;
+
+ irqbase = irq_alloc_descs(-1, 0, 8, -1);
+ if (irqbase < 0)
+ return irqbase;
+
+ 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));
+ irq_free_descs(irqbase, 8);
+ return PTR_ERR(task);
+ }
+
+ printk("Probing expansion cards\n");
+
+ for (slot = 0; slot < 8; slot ++) {
+ if (ecard_probe(slot, irqbase + slot, ECARD_EASI) == -ENODEV)
+ ecard_probe(slot, irqbase + slot, ECARD_IOC);
+ }
+
+ ecard_probe(8, 11, ECARD_IOC);
+
+ irq_set_chained_handler(IRQ_EXPANSIONCARD, 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/mach-rpc/ecard.h b/arch/arm/mach-rpc/ecard.h
new file mode 100644
index 000000000..4642d436b
--- /dev/null
+++ b/arch/arm/mach-rpc/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/mach-rpc/fiq.S b/arch/arm/mach-rpc/fiq.S
new file mode 100644
index 000000000..48ddd57db
--- /dev/null
+++ b/arch/arm/mach-rpc/fiq.S
@@ -0,0 +1,16 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+#include <mach/entry-macro.S>
+
+ .text
+
+ .global rpc_default_fiq_end
+ENTRY(rpc_default_fiq_start)
+ mov r12, #ioc_base_high
+ .if ioc_base_low
+ orr r12, r12, #ioc_base_low
+ .endif
+ strb r12, [r12, #0x38] @ Disable FIQ register
+ subs pc, lr, #4
+rpc_default_fiq_end:
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 000000000..395d76288
--- /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/entry-macro.S b/arch/arm/mach-rpc/include/mach/entry-macro.S
new file mode 100644
index 000000000..7178368d7
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/entry-macro.S
@@ -0,0 +1,12 @@
+#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
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 000000000..257166b21
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/hardware.h
@@ -0,0 +1,76 @@
+/*
+ * 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>
+
+/*
+ * 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 IOMEM(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 ECARD_EASI_BASE (EASI_BASE)
+#define VIDC_BASE (IO_BASE + 0x00400000)
+#define EXPMASK_BASE (IO_BASE + 0x00360000)
+#define ECARD_IOC4_BASE (IO_BASE + 0x00270000)
+#define ECARD_IOC_BASE (IO_BASE + 0x00240000)
+#define IOMD_BASE (IO_BASE + 0x00200000)
+#define IOC_BASE (IO_BASE + 0x00200000)
+#define ECARD_MEMC8_BASE (IO_BASE + 0x0002b000)
+#define FLOPPYDMA_BASE (IO_BASE + 0x0002a000)
+#define PCIO_BASE (IO_BASE + 0x00010000)
+#define ECARD_MEMC_BASE (IO_BASE + 0x00000000)
+
+#define vidc_writel(val) __raw_writel(val, VIDC_BASE)
+
+#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 000000000..707071a7e
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/io.h
@@ -0,0 +1,31 @@
+/*
+ * 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 0xffff
+
+/*
+ * We need PC style IO addressing for:
+ * - floppy (at 0x3f2,0x3f4,0x3f5,0x3f7)
+ * - parport (at 0x278-0x27a, 0x27b-0x27f, 0x778-0x77a)
+ * - 8250 serial (only for compile)
+ *
+ * These peripherals are found in an area of MMIO which looks very much
+ * like an ISA bus, but with registers at the low byte of each word.
+ */
+#define __io(a) (PCIO_BASE + ((a) << 2))
+
+#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 000000000..6868e1782
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/irqs.h
@@ -0,0 +1,45 @@
+/*
+ * 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 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 000000000..67bfc6719
--- /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 000000000..b7e495714
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/memory.h
@@ -0,0 +1,35 @@
+/*
+ * 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
+
+/*
+ * 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/uncompress.h b/arch/arm/mach-rpc/include/mach/uncompress.h
new file mode 100644
index 000000000..0fd4b0b8e
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/uncompress.h
@@ -0,0 +1,191 @@
+/*
+ * 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
diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c
new file mode 100644
index 000000000..3e4fa849c
--- /dev/null
+++ b/arch/arm/mach-rpc/irq.c
@@ -0,0 +1,168 @@
+#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>
+#include <asm/fiq.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,
+};
+
+extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end;
+
+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);
+
+ set_fiq_handler(&rpc_default_fiq_start,
+ &rpc_default_fiq_end - &rpc_default_fiq_start);
+
+ 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(FIQ_START);
+}
+
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c
new file mode 100644
index 000000000..09d602b10
--- /dev/null
+++ b/arch/arm/mach-rpc/riscpc.c
@@ -0,0 +1,226 @@
+/*
+ * 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 <linux/reboot.h>
+
+#include <asm/elf.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/hardware/iomd.h>
+#include <asm/page.h>
+#include <asm/domain.h>
+#include <asm/setup.h>
+#include <asm/system_misc.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 = (unsigned long)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 */
+ DEFINE_RES_MEM(0x03400000, 0x00200000),
+ DEFINE_RES_IRQ(IRQ_VSYNCPULSE),
+};
+
+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[] = {
+ DEFINE_RES_MEM(0x03200000, 0x10000),
+};
+
+static struct platform_device iomd_device = {
+ .name = "iomd",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(iomd_resources),
+ .resource = iomd_resources,
+};
+
+static struct resource iomd_kart_resources[] = {
+ DEFINE_RES_IRQ(IRQ_KEYBOARDRX),
+ DEFINE_RES_IRQ(IRQ_KEYBOARDTX),
+};
+
+static struct platform_device kbd_device = {
+ .name = "kart",
+ .id = -1,
+ .dev = {
+ .parent = &iomd_device.dev,
+ },
+ .num_resources = ARRAY_SIZE(iomd_kart_resources),
+ .resource = iomd_kart_resources,
+};
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .mapbase = 0x03010fe0,
+ .irq = IRQ_SERIALPORT,
+ .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[] = {
+ DEFINE_RES_MEM(0x030107c0, 0x20),
+ DEFINE_RES_MEM(0x03010fd8, 0x04),
+ DEFINE_RES_IRQ(IRQ_HARDDISK),
+};
+
+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);
+
+static void rpc_restart(enum reboot_mode mode, const char *cmd)
+{
+ iomd_writeb(0, IOMD_ROMCR0);
+
+ /*
+ * Jump into the ROM
+ */
+ soft_restart(0);
+}
+
+void ioc_timer_init(void);
+
+MACHINE_START(RISCPC, "Acorn-RiscPC")
+ /* Maintainer: Russell King */
+ .atag_offset = 0x100,
+ .reserve_lp0 = 1,
+ .reserve_lp1 = 1,
+ .map_io = rpc_map_io,
+ .init_irq = rpc_init_irq,
+ .init_time = ioc_timer_init,
+ .restart = rpc_restart,
+MACHINE_END
diff --git a/arch/arm/mach-rpc/time.c b/arch/arm/mach-rpc/time.c
new file mode 100644
index 000000000..2689771c1
--- /dev/null
+++ b/arch/arm/mach-rpc/time.c
@@ -0,0 +1,92 @@
+/*
+ * 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>
+
+#define RPC_CLOCK_FREQ 2000000
+#define RPC_LATCH DIV_ROUND_CLOSEST(RPC_CLOCK_FREQ, HZ)
+
+static u32 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 -= RPC_LATCH;
+ } else if (count2 > count1) {
+ /*
+ * We have just had another interrupt between reading
+ * count1 and count2.
+ */
+ offset -= RPC_LATCH;
+ }
+
+ offset = (RPC_LATCH - offset) * (tick_nsec / 1000);
+ return DIV_ROUND_CLOSEST(offset, RPC_LATCH) * 1000;
+}
+
+void __init ioctime_init(void)
+{
+ ioc_writeb(RPC_LATCH & 255, IOC_T0LTCHL);
+ ioc_writeb(RPC_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",
+ .handler = ioc_timer_interrupt
+};
+
+/*
+ * Set up timer interrupt.
+ */
+void __init ioc_timer_init(void)
+{
+ arch_gettimeoffset = ioc_timer_gettimeoffset;
+ ioctime_init();
+ setup_irq(IRQ_TIMER0, &ioc_timer_irq);
+}
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
new file mode 100644
index 000000000..23bec3a85
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -0,0 +1,590 @@
+# arch/arm/mach-s3c24xx/Kconfig
+#
+# Copyright (c) 2012 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+if ARCH_S3C24XX
+
+config PLAT_S3C24XX
+ def_bool y
+ select ARCH_REQUIRE_GPIOLIB
+ select NO_IOPORT_MAP
+ select S3C_DEV_NAND
+ select IRQ_DOMAIN
+ help
+ Base platform code for any Samsung S3C24XX device
+
+
+
+menu "SAMSUNG S3C24XX SoCs Support"
+
+comment "S3C24XX SoCs"
+
+config CPU_S3C2410
+ bool "SAMSUNG S3C2410"
+ default y
+ select CPU_ARM920T
+ select S3C2410_COMMON_CLK
+ select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ
+ select S3C2410_PM if PM
+ help
+ Support for S3C2410 and S3C2410A family from the S3C24XX line
+ of Samsung Mobile CPUs.
+
+config CPU_S3C2412
+ bool "SAMSUNG S3C2412"
+ select CPU_ARM926T
+ select S3C2412_COMMON_CLK
+ select S3C2412_PM if PM_SLEEP
+ help
+ Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
+
+config CPU_S3C2416
+ bool "SAMSUNG S3C2416/S3C2450"
+ select CPU_ARM926T
+ select S3C2416_PM if PM_SLEEP
+ select S3C2443_COMMON_CLK
+ help
+ Support for the S3C2416 SoC from the S3C24XX line
+
+config CPU_S3C2440
+ bool "SAMSUNG S3C2440"
+ select CPU_ARM920T
+ select S3C2410_COMMON_CLK
+ select S3C2410_PM if PM_SLEEP
+ help
+ Support for S3C2440 Samsung Mobile CPU based systems.
+
+config CPU_S3C2442
+ bool "SAMSUNG S3C2442"
+ select CPU_ARM920T
+ select S3C2410_COMMON_CLK
+ select S3C2410_PM if PM_SLEEP
+ help
+ Support for S3C2442 Samsung Mobile CPU based systems.
+
+config CPU_S3C244X
+ def_bool y
+ depends on CPU_S3C2440 || CPU_S3C2442
+
+config CPU_S3C2443
+ bool "SAMSUNG S3C2443"
+ select CPU_ARM920T
+ select S3C2443_COMMON_CLK
+ help
+ Support for the S3C2443 SoC from the S3C24XX line
+
+# common code
+
+config S3C24XX_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 S3C24XX_SIMTEC_PM
+ bool
+ help
+ Common power management code for systems that are
+ compatible with the Simtec style of power management
+
+config S3C24XX_SIMTEC_USB
+ bool
+ help
+ USB management code for common Simtec S3C24XX boards
+
+config S3C24XX_SETUP_TS
+ bool
+ help
+ Compile in platform device definition for Samsung TouchScreen.
+
+config S3C2410_PM
+ bool
+ help
+ Power Management code common to S3C2410 and better
+
+config S3C24XX_PLL
+ bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)"
+ depends on ARM_S3C24XX_CPUFREQ
+ 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.
+
+# cpu frequency items common between s3c2410 and s3c2440/s3c2442
+
+config S3C2410_IOTIMING
+ bool
+ depends on ARM_S3C24XX_CPUFREQ
+ 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 ARM_S3C24XX_CPUFREQ
+ 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 ARM_S3C24XX_CPUFREQ && (CPU_S3C2412 || CPU_S3C2443)
+ help
+ Intel node to select io timing code that is common to the s3c2412
+ and the s3c2443.
+
+# cpu-specific sections
+
+if CPU_S3C2410
+
+config S3C2410_PLL
+ bool
+ depends on ARM_S3C2410_CPUFREQ && S3C24XX_PLL
+ default y
+ help
+ Select the PLL table for the S3C2410
+
+config S3C24XX_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
+
+comment "S3C2410 Boards"
+
+#
+# The "S3C2410 Boards" list is ordered alphabetically by option text.
+# (without ARCH_ or MACH_)
+#
+
+config MACH_AML_M5900
+ bool "AML M5900 Series"
+ select S3C24XX_SIMTEC_PM 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 ARCH_BAST
+ bool "Simtec Electronics BAST (EB2410ITX)"
+ select ISA
+ select MACH_BAST_IDE
+ select S3C2410_COMMON_DCLK
+ select S3C2410_IOTIMING if ARM_S3C2410_CPUFREQ
+ select S3C24XX_SIMTEC_NOR
+ select S3C24XX_SIMTEC_PM if PM
+ select S3C24XX_SIMTEC_USB
+ select S3C_DEV_HWMON
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the Simtec Electronics EB2410ITX
+ development board (also known as BAST)
+
+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 ARCH_H1940
+ bool "IPAQ H1940"
+ select PM_H1940 if PM
+ select S3C24XX_SETUP_TS
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ 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 MACH_N30
+ bool "Acer N30 family"
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you want suppt for the Acer N30, Acer N35,
+ Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs.
+
+config MACH_OTOM
+ bool "NexVision OTOM Board"
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the Nex Vision OTOM board
+
+config MACH_QT2410
+ bool "QT2410"
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the Armzone QT2410
+
+config ARCH_SMDK2410
+ bool "SMDK2410/A9M2410"
+ select S3C24XX_SMDK
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the SMDK2410 or the derived module A9M2410
+ <http://www.fsforth.de>
+
+config MACH_TCT_HAMMER
+ bool "TCT Hammer Board"
+ 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 MACH_BAST_IDE
+ select S3C2410_COMMON_DCLK
+ select S3C24XX_SIMTEC_NOR
+ select S3C24XX_SIMTEC_PM if PM
+ select S3C24XX_SIMTEC_USB
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the Thorcom VR1000 board.
+
+endif # CPU_S3C2410
+
+config S3C2412_PM_SLEEP
+ bool
+ help
+ Internal config node to apply sleep for S3C2412 power management.
+ Can be selected by another SoCs such as S3C2416 with similar
+ sleep procedure.
+
+if CPU_S3C2412
+
+config CPU_S3C2412_ONLY
+ bool
+ depends on !CPU_S3C2410 && !CPU_S3C2416 && !CPU_S3C2440 && \
+ !CPU_S3C2442 && !CPU_S3C2443
+ default y
+
+config S3C2412_PM
+ bool
+ select S3C2412_PM_SLEEP
+ select SAMSUNG_WAKEMASK
+ help
+ Internal config node to apply S3C2412 power management
+
+comment "S3C2412 Boards"
+
+#
+# The "S3C2412 Boards" list is ordered alphabetically by option text.
+# (without ARCH_ or MACH_)
+#
+
+config MACH_JIVE
+ bool "Logitech Jive"
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the Logitech Jive.
+
+config MACH_JIVE_SHOW_BOOTLOADER
+ bool "Allow access to bootloader partitions in MTD"
+ depends on MACH_JIVE
+
+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_SMDK2413
+ bool "SMDK2413"
+ select MACH_S3C2413
+ select S3C24XX_SMDK
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using an SMDK2413
+
+config MACH_VSTMS
+ bool "VMSTMS"
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using an VSTMS board
+
+endif # CPU_S3C2412
+
+if CPU_S3C2416
+
+config S3C2416_PM
+ bool
+ select S3C2412_PM_SLEEP
+ select SAMSUNG_WAKEMASK
+ 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.
+
+comment "S3C2416 Boards"
+
+config MACH_SMDK2416
+ bool "SMDK2416"
+ select S3C2416_SETUP_SDHCI
+ select S3C24XX_SMDK
+ select S3C_DEV_FB
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using an SMDK2416
+
+config MACH_S3C2416_DT
+ bool "Samsung S3C2416 machine using devicetree"
+ select CLKSRC_OF
+ select USE_OF
+ select PINCTRL
+ select PINCTRL_S3C24XX
+ help
+ Machine support for Samsung S3C2416 machines with device tree enabled.
+ Select this if a fdt blob is available for the S3C2416 SoC based board.
+ Note: This is under development and not all peripherals can be supported
+ with this machine file.
+
+endif # CPU_S3C2416
+
+if CPU_S3C2440
+
+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 ARM_S3C2440_CPUFREQ && S3C2440_XTAL_12000000
+ default y if S3C24XX_PLL
+ help
+ PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals.
+
+config S3C2440_PLL_16934400
+ bool
+ depends on ARM_S3C2440_CPUFREQ && S3C2440_XTAL_16934400
+ default y if S3C24XX_PLL
+ help
+ PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals.
+
+comment "S3C2440 Boards"
+
+#
+# The "S3C2440 Boards" list is ordered alphabetically by option text.
+# (without ARCH_ or MACH_)
+#
+
+config MACH_ANUBIS
+ bool "Simtec Electronics ANUBIS"
+ select HAVE_PATA_PLATFORM
+ select S3C2410_COMMON_DCLK
+ select S3C2440_XTAL_12000000
+ select S3C24XX_SIMTEC_PM if PM
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the Simtec Electronics ANUBIS
+ development system
+
+config MACH_AT2440EVB
+ bool "Avantech AT2440EVB development board"
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the AT2440EVB development board
+
+config MACH_MINI2440
+ bool "MINI2440 development board"
+ select EEPROM_AT24 if I2C
+ select LEDS_CLASS
+ select LEDS_TRIGGERS
+ select LEDS_TRIGGER_BACKLIGHT
+ select NEW_LEDS
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ select S3C_SETUP_CAMIF
+ 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_NEXCODER_2440
+ bool "NexVision NEXCODER 2440 Light Board"
+ select S3C2440_XTAL_12000000
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
+
+config MACH_OSIRIS
+ bool "Simtec IM2440D20 (OSIRIS) module"
+ select S3C2410_COMMON_DCLK
+ select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
+ select S3C2440_XTAL_12000000
+ select S3C24XX_SIMTEC_PM if PM
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ 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
+ depends on 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 PM_H1940 if PM
+ select S3C2440_XTAL_16934400
+ select S3C_DEV_NAND
+ help
+ Say Y here if you are using the HP iPAQ rx3715.
+
+config ARCH_S3C2440
+ bool "SMDK2440"
+ select S3C2440_XTAL_16934400
+ select S3C24XX_SMDK
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the SMDK2440.
+
+config SMDK2440_CPU2440
+ bool "SMDK2440 with S3C2440 CPU module"
+ default y if ARCH_S3C2440
+ select S3C2440_XTAL_16934400
+
+endif # CPU_S3C2440
+
+if CPU_S3C2442
+
+comment "S3C2442 Boards"
+
+#
+# The "S3C2442 Boards" list is ordered alphabetically by option text.
+# (without ARCH_ or MACH_)
+#
+
+config MACH_NEO1973_GTA02
+ bool "Openmoko GTA02 / Freerunner phone"
+ select I2C
+ select MFD_PCF50633
+ select PCF50633_GPIO
+ select POWER_SUPPLY
+ select S3C24XX_PWM
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone
+
+config MACH_RX1950
+ bool "HP iPAQ rx1950"
+ select I2C
+ select PM_H1940 if PM
+ select S3C2410_COMMON_DCLK
+ select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
+ select S3C2440_XTAL_16934400
+ select S3C24XX_PWM
+ select S3C_DEV_NAND
+ help
+ Say Y here if you're using HP iPAQ rx1950
+
+endif # CPU_S3C2442
+
+if CPU_S3C2443 || CPU_S3C2416
+
+config S3C2443_SETUP_SPI
+ bool
+ help
+ Common setup code for SPI GPIO configurations
+
+endif # CPU_S3C2443 || CPU_S3C2416
+
+if CPU_S3C2443
+
+comment "S3C2443 Boards"
+
+config MACH_SMDK2443
+ bool "SMDK2443"
+ select S3C24XX_SMDK
+ select S3C_DEV_HSMMC1
+ help
+ Say Y here if you are using an SMDK2443
+
+endif # CPU_S3C2443
+
+config PM_H1940
+ bool
+ help
+ Internal node for H1940 and related PM
+
+endmenu # SAMSUNG S3C24XX SoCs Support
+
+endif # ARCH_S3C24XX
diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
new file mode 100644
index 000000000..05920c8a5
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -0,0 +1,101 @@
+# arch/arm/mach-s3c24xx/Makefile
+#
+# Copyright (c) 2012 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+# core
+
+obj-y += common.o
+
+obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
+obj-$(CONFIG_S3C2410_PLL) += pll-s3c2410.o
+obj-$(CONFIG_S3C2410_PM) += pm-s3c2410.o sleep-s3c2410.o
+
+obj-$(CONFIG_CPU_S3C2412) += s3c2412.o
+obj-$(CONFIG_S3C2412_PM) += pm-s3c2412.o
+obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep-s3c2412.o
+
+obj-$(CONFIG_CPU_S3C2416) += s3c2416.o
+obj-$(CONFIG_S3C2416_PM) += pm-s3c2416.o
+
+obj-$(CONFIG_CPU_S3C2440) += s3c2440.o
+obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
+obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
+obj-$(CONFIG_S3C2440_PLL_12000000) += pll-s3c2440-12000000.o
+obj-$(CONFIG_S3C2440_PLL_16934400) += pll-s3c2440-16934400.o
+
+obj-$(CONFIG_CPU_S3C2443) += s3c2443.o
+
+# PM
+
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM_SLEEP) += irq-pm.o sleep.o
+
+# common code
+
+obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += cpufreq-utils.o
+
+obj-$(CONFIG_S3C2410_IOTIMING) += iotiming-s3c2410.o
+obj-$(CONFIG_S3C2412_IOTIMING) += iotiming-s3c2412.o
+
+#
+# machine support
+# following is ordered alphabetically by option text.
+#
+
+obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o
+obj-$(CONFIG_ARCH_BAST) += mach-bast.o
+obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.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_MACH_OTOM) += mach-otom.o
+obj-$(CONFIG_MACH_QT2410) += mach-qt2410.o
+obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o
+obj-$(CONFIG_MACH_TCT_HAMMER) += mach-tct_hammer.o
+obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o
+
+obj-$(CONFIG_MACH_JIVE) += mach-jive.o
+obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o
+obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o
+
+obj-$(CONFIG_MACH_SMDK2416) += mach-smdk2416.o
+obj-$(CONFIG_MACH_S3C2416_DT) += mach-s3c2416-dt.o
+
+obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o
+obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o
+obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o
+obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.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_NEO1973_GTA02) += mach-gta02.o
+obj-$(CONFIG_MACH_RX1950) += mach-rx1950.o
+
+obj-$(CONFIG_MACH_SMDK2443) += mach-smdk2443.o
+
+# common bits of machine support
+
+obj-$(CONFIG_S3C24XX_SMDK) += common-smdk.o
+obj-$(CONFIG_S3C24XX_SIMTEC_AUDIO) += simtec-audio.o
+obj-$(CONFIG_S3C24XX_SIMTEC_NOR) += simtec-nor.o
+obj-$(CONFIG_S3C24XX_SIMTEC_PM) += simtec-pm.o
+obj-$(CONFIG_S3C24XX_SIMTEC_USB) += simtec-usb.o
+
+# machine additions
+
+obj-$(CONFIG_MACH_BAST_IDE) += bast-ide.o
+obj-$(CONFIG_MACH_OSIRIS_DVS) += mach-osiris-dvs.o
+
+# device setup
+
+obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
+obj-$(CONFIG_S3C2443_SETUP_SPI) += setup-spi.o
+obj-$(CONFIG_ARCH_S3C24XX) += setup-i2c.o
+obj-$(CONFIG_S3C24XX_SETUP_TS) += setup-ts.o
diff --git a/arch/arm/mach-s3c24xx/Makefile.boot b/arch/arm/mach-s3c24xx/Makefile.boot
new file mode 100644
index 000000000..4457605ba
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/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-s3c24xx/anubis.h b/arch/arm/mach-s3c24xx/anubis.h
new file mode 100644
index 000000000..2691665f2
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/anubis.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2005 Simtec Electronics
+ * http://www.simtec.co.uk/products/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * ANUBIS - CPLD control constants
+ * ANUBIS - IRQ Number definitions
+ * 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.
+*/
+
+#ifndef __MACH_S3C24XX_ANUBIS_H
+#define __MACH_S3C24XX_ANUBIS_H __FILE__
+
+/* CTRL2 - NAND WP control, IDE Reset assert/check */
+
+#define ANUBIS_CTRL1_NANDSEL (0x3)
+
+/* IDREG - revision */
+
+#define ANUBIS_IDREG_REVMASK (0x7)
+
+/* irq */
+
+#define ANUBIS_IRQ_IDE0 IRQ_EINT2
+#define ANUBIS_IRQ_IDE1 IRQ_EINT3
+#define ANUBIS_IRQ_ASIX IRQ_EINT1
+
+/* map */
+
+/* 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)
+#define ANUBIS_PA_CTRL1 ANUBIS_PA_CPLD
+
+#define ANUBIS_VA_IDREG ANUBIS_IOADDR(0x00300000)
+#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 /* __MACH_S3C24XX_ANUBIS_H */
diff --git a/arch/arm/mach-s3c24xx/bast-ide.c b/arch/arm/mach-s3c24xx/bast-ide.c
new file mode 100644
index 000000000..3f0288f2f
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/bast-ide.c
@@ -0,0 +1,86 @@
+/* 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 "bast.h"
+
+/* IDE ports */
+
+static struct pata_platform_info bast_ide_platdata = {
+ .ioport_shift = 5,
+};
+
+static struct resource bast_ide0_resource[] = {
+ [0] = DEFINE_RES_MEM(BAST_IDE_CS + BAST_PA_IDEPRI, 8 * 0x20),
+ [1] = DEFINE_RES_MEM(BAST_IDE_CS + BAST_PA_IDEPRIAUX + (6 * 0x20), 0x20),
+ [2] = DEFINE_RES_IRQ(BAST_IRQ_IDE0),
+};
+
+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] = DEFINE_RES_MEM(BAST_IDE_CS + BAST_PA_IDESEC, 8 * 0x20),
+ [1] = DEFINE_RES_MEM(BAST_IDE_CS + BAST_PA_IDESECAUX + (6 * 0x20), 0x20),
+ [2] = DEFINE_RES_IRQ(BAST_IRQ_IDE1),
+};
+
+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-s3c24xx/bast-irq.c b/arch/arm/mach-s3c24xx/bast-irq.c
new file mode 100644
index 000000000..cb1b79195
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/bast-irq.c
@@ -0,0 +1,157 @@
+/* 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/device.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-irq.h>
+
+#include "bast.h"
+
+#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 + BAST_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 + BAST_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(BAST_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-s3c24xx/bast.h b/arch/arm/mach-s3c24xx/bast.h
new file mode 100644
index 000000000..5c7534bae
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/bast.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2003-2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * BAST - CPLD control constants
+ * BAST - IRQ Number definitions
+ * 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.
+*/
+
+#ifndef __MACH_S3C24XX_BAST_H
+#define __MACH_S3C24XX_BAST_H __FILE__
+
+/* 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)
+#define BAST_CPLD_DMA0_SECIDE (1)
+#define BAST_CPLD_DMA0_ISA15 (2)
+#define BAST_CPLD_DMA0_ISA36 (3)
+
+#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)
+
+/* irq numbers to onboard peripherals */
+
+#define BAST_IRQ_USBOC IRQ_EINT18
+#define BAST_IRQ_IDE0 IRQ_EINT16
+#define BAST_IRQ_IDE1 IRQ_EINT17
+#define BAST_IRQ_PCSERIAL1 IRQ_EINT15
+#define BAST_IRQ_PCSERIAL2 IRQ_EINT14
+#define BAST_IRQ_PCPARALLEL IRQ_EINT13
+#define BAST_IRQ_ASIX IRQ_EINT11
+#define BAST_IRQ_DM9000 IRQ_EINT10
+#define BAST_IRQ_ISA IRQ_EINT9
+#define BAST_IRQ_SMALERT IRQ_EINT8
+
+/* map */
+
+/*
+ * 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.
+ */
+
+#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)
+#define BAST_PA_CTRL1 (S3C2410_CS5 | 0x7800000)
+
+#define BAST_VA_CTRL2 BAST_IOADDR(0x00100000)
+#define BAST_PA_CTRL2 (S3C2410_CS1 | 0x6000000)
+
+#define BAST_VA_CTRL3 BAST_IOADDR(0x00200000)
+#define BAST_PA_CTRL3 (S3C2410_CS1 | 0x6800000)
+
+#define BAST_VA_CTRL4 BAST_IOADDR(0x00300000)
+#define BAST_PA_CTRL4 (S3C2410_CS1 | 0x7000000)
+
+/* next, we have the PC104 ISA interrupt registers */
+
+#define BAST_PA_PC104_IRQREQ (S3C2410_CS5 | 0x6000000)
+#define BAST_VA_PC104_IRQREQ BAST_IOADDR(0x00400000)
+
+#define BAST_PA_PC104_IRQRAW (S3C2410_CS5 | 0x6800000)
+#define BAST_VA_PC104_IRQRAW BAST_IOADDR(0x00500000)
+
+#define BAST_PA_PC104_IRQMASK (S3C2410_CS5 | 0x7000000)
+#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
+ * whether 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_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_DM9000_CS BAST_VAM_CS4
+
+#define BAST_IDE_CS S3C2410_CS5
+
+#endif /* __MACH_S3C24XX_BAST_H */
diff --git a/arch/arm/mach-s3c24xx/common-smdk.c b/arch/arm/mach-s3c24xx/common-smdk.c
new file mode 100644
index 000000000..e9fbcc91c
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/common-smdk.c
@@ -0,0 +1,210 @@
+/* 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/device.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/gpio-samsung.h>
+#include <linux/platform_data/leds-s3c24xx.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
+
+#include "common-smdk.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,
+};
+
+static const struct gpio smdk_led_gpios[] = {
+ { S3C2410_GPF(4), GPIOF_OUT_INIT_HIGH, NULL },
+ { S3C2410_GPF(5), GPIOF_OUT_INIT_HIGH, NULL },
+ { S3C2410_GPF(6), GPIOF_OUT_INIT_HIGH, NULL },
+ { S3C2410_GPF(7), GPIOF_OUT_INIT_HIGH, NULL },
+};
+
+void __init smdk_machine_init(void)
+{
+ /* Configure the LEDs (even if we have no LED support)*/
+
+ int ret = gpio_request_array(smdk_led_gpios,
+ ARRAY_SIZE(smdk_led_gpios));
+ if (!WARN_ON(ret < 0))
+ gpio_free_array(smdk_led_gpios, ARRAY_SIZE(smdk_led_gpios));
+
+ 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/mach-s3c24xx/common-smdk.h b/arch/arm/mach-s3c24xx/common-smdk.h
new file mode 100644
index 000000000..98f733e1c
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/common-smdk.h
@@ -0,0 +1,14 @@
+/*
+ * 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/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
new file mode 100644
index 000000000..bf5032810
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -0,0 +1,565 @@
+/* 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>
+ *
+ * Common code for S3C24XX 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.
+ *
+ * You should have received a copy of the GNU General Public 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/serial_s3c.h>
+#include <clocksource/samsung_pwm.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/platform_data/dma-s3c24xx.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-clock.h>
+#include <asm/irq.h>
+#include <asm/cacheflush.h>
+#include <asm/system_info.h>
+#include <asm/system_misc.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/dma.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/cpu-freq.h>
+#include <plat/pwm-core.h>
+
+#include "common.h"
+
+/* table of supported CPUs */
+
+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_uarts = s3c2410_init_uarts,
+ .init = s3c2410_init,
+ .name = name_s3c2410
+ },
+ {
+ .idcode = 0x32410002,
+ .idmask = 0xffffffff,
+ .map_io = s3c2410_map_io,
+ .init_uarts = s3c2410_init_uarts,
+ .init = s3c2410a_init,
+ .name = name_s3c2410a
+ },
+ {
+ .idcode = 0x32440000,
+ .idmask = 0xffffffff,
+ .map_io = s3c2440_map_io,
+ .init_uarts = s3c244x_init_uarts,
+ .init = s3c2440_init,
+ .name = name_s3c2440
+ },
+ {
+ .idcode = 0x32440001,
+ .idmask = 0xffffffff,
+ .map_io = s3c2440_map_io,
+ .init_uarts = s3c244x_init_uarts,
+ .init = s3c2440_init,
+ .name = name_s3c2440a
+ },
+ {
+ .idcode = 0x32440aaa,
+ .idmask = 0xffffffff,
+ .map_io = s3c2442_map_io,
+ .init_uarts = s3c244x_init_uarts,
+ .init = s3c2442_init,
+ .name = name_s3c2442
+ },
+ {
+ .idcode = 0x32440aab,
+ .idmask = 0xffffffff,
+ .map_io = s3c2442_map_io,
+ .init_uarts = s3c244x_init_uarts,
+ .init = s3c2442_init,
+ .name = name_s3c2442b
+ },
+ {
+ .idcode = 0x32412001,
+ .idmask = 0xffffffff,
+ .map_io = s3c2412_map_io,
+ .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_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_uarts = s3c2416_init_uarts,
+ .init = s3c2416_init,
+ .name = name_s3c2416,
+ },
+ {
+ .idcode = 0x32443001,
+ .idmask = 0xffffffff,
+ .map_io = s3c2443_map_io,
+ .init_uarts = s3c2443_init_uarts,
+ .init = s3c2443_init,
+ .name = name_s3c2443,
+ },
+};
+
+/* 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)
+{
+ return __raw_readl(S3C2410_GSTATUS1);
+}
+
+static void s3c24xx_default_idle(void)
+{
+ unsigned long tmp = 0;
+ 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 struct samsung_pwm_variant s3c24xx_pwm_variant = {
+ .bits = 16,
+ .div_base = 1,
+ .has_tint_cstat = false,
+ .tclk_mask = (1 << 4),
+};
+
+void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
+{
+ arm_pm_idle = s3c24xx_default_idle;
+
+ /* 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) {
+ samsung_cpu_id = s3c24xx_read_idcode_v5();
+ } else {
+ samsung_cpu_id = s3c24xx_read_idcode_v4();
+ }
+
+ s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+ samsung_pwm_set_platdata(&s3c24xx_pwm_variant);
+}
+
+void __init samsung_set_timer_source(unsigned int event, unsigned int source)
+{
+ s3c24xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+ s3c24xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
+}
+
+void __init samsung_timer_init(void)
+{
+ unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
+ IRQ_TIMER0, IRQ_TIMER1, IRQ_TIMER2, IRQ_TIMER3, IRQ_TIMER4,
+ };
+
+ samsung_pwm_clocksource_init(S3C_VA_TIMER,
+ timer_irqs, &s3c24xx_pwm_variant);
+}
+
+/* Serial port registrations */
+
+#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 )
+
+static struct resource s3c2410_uart0_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_PA_UART0, SZ_16K),
+ [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX0, \
+ IRQ_S3CUART_ERR0 - IRQ_S3CUART_RX0 + 1, \
+ NULL, IORESOURCE_IRQ)
+};
+
+static struct resource s3c2410_uart1_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_PA_UART1, SZ_16K),
+ [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX1, \
+ IRQ_S3CUART_ERR1 - IRQ_S3CUART_RX1 + 1, \
+ NULL, IORESOURCE_IRQ)
+};
+
+static struct resource s3c2410_uart2_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_PA_UART2, SZ_16K),
+ [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX2, \
+ IRQ_S3CUART_ERR2 - IRQ_S3CUART_RX2 + 1, \
+ NULL, IORESOURCE_IRQ)
+};
+
+static struct resource s3c2410_uart3_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2443_PA_UART3, SZ_16K),
+ [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX3, \
+ IRQ_S3CUART_ERR3 - IRQ_S3CUART_RX3 + 1, \
+ NULL, 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),
+ },
+};
+
+#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \
+ defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
+static struct resource s3c2410_dma_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C24XX_PA_DMA, S3C24XX_SZ_DMA),
+ [1] = DEFINE_RES_IRQ(IRQ_DMA0),
+ [2] = DEFINE_RES_IRQ(IRQ_DMA1),
+ [3] = DEFINE_RES_IRQ(IRQ_DMA2),
+ [4] = DEFINE_RES_IRQ(IRQ_DMA3),
+};
+#endif
+
+#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2442)
+static struct s3c24xx_dma_channel s3c2410_dma_channels[DMACH_MAX] = {
+ [DMACH_XD0] = { S3C24XX_DMA_AHB, true, S3C24XX_DMA_CHANREQ(0, 0), },
+ [DMACH_XD1] = { S3C24XX_DMA_AHB, true, S3C24XX_DMA_CHANREQ(0, 1), },
+ [DMACH_SDI] = { S3C24XX_DMA_APB, false, S3C24XX_DMA_CHANREQ(2, 0) |
+ S3C24XX_DMA_CHANREQ(2, 2) |
+ S3C24XX_DMA_CHANREQ(1, 3),
+ },
+ [DMACH_SPI0] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(3, 1), },
+ [DMACH_SPI1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(2, 3), },
+ [DMACH_UART0] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(1, 0), },
+ [DMACH_UART1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(1, 1), },
+ [DMACH_UART2] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(0, 3), },
+ [DMACH_TIMER] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(3, 0) |
+ S3C24XX_DMA_CHANREQ(3, 2) |
+ S3C24XX_DMA_CHANREQ(3, 3),
+ },
+ [DMACH_I2S_IN] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(2, 1) |
+ S3C24XX_DMA_CHANREQ(1, 2),
+ },
+ [DMACH_I2S_OUT] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(0, 2), },
+ [DMACH_USB_EP1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 0), },
+ [DMACH_USB_EP2] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 1), },
+ [DMACH_USB_EP3] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 2), },
+ [DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 3), },
+};
+
+static struct s3c24xx_dma_platdata s3c2410_dma_platdata = {
+ .num_phy_channels = 4,
+ .channels = s3c2410_dma_channels,
+ .num_channels = DMACH_MAX,
+};
+
+struct platform_device s3c2410_device_dma = {
+ .name = "s3c2410-dma",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c2410_dma_resource),
+ .resource = s3c2410_dma_resource,
+ .dev = {
+ .platform_data = &s3c2410_dma_platdata,
+ },
+};
+#endif
+
+#ifdef CONFIG_CPU_S3C2412
+static struct s3c24xx_dma_channel s3c2412_dma_channels[DMACH_MAX] = {
+ [DMACH_XD0] = { S3C24XX_DMA_AHB, true, 17 },
+ [DMACH_XD1] = { S3C24XX_DMA_AHB, true, 18 },
+ [DMACH_SDI] = { S3C24XX_DMA_APB, false, 10 },
+ [DMACH_SPI0_RX] = { S3C24XX_DMA_APB, true, 1 },
+ [DMACH_SPI0_TX] = { S3C24XX_DMA_APB, true, 0 },
+ [DMACH_SPI1_RX] = { S3C24XX_DMA_APB, true, 3 },
+ [DMACH_SPI1_TX] = { S3C24XX_DMA_APB, true, 2 },
+ [DMACH_UART0] = { S3C24XX_DMA_APB, true, 19 },
+ [DMACH_UART1] = { S3C24XX_DMA_APB, true, 21 },
+ [DMACH_UART2] = { S3C24XX_DMA_APB, true, 23 },
+ [DMACH_UART0_SRC2] = { S3C24XX_DMA_APB, true, 20 },
+ [DMACH_UART1_SRC2] = { S3C24XX_DMA_APB, true, 22 },
+ [DMACH_UART2_SRC2] = { S3C24XX_DMA_APB, true, 24 },
+ [DMACH_TIMER] = { S3C24XX_DMA_APB, true, 9 },
+ [DMACH_I2S_IN] = { S3C24XX_DMA_APB, true, 5 },
+ [DMACH_I2S_OUT] = { S3C24XX_DMA_APB, true, 4 },
+ [DMACH_USB_EP1] = { S3C24XX_DMA_APB, true, 13 },
+ [DMACH_USB_EP2] = { S3C24XX_DMA_APB, true, 14 },
+ [DMACH_USB_EP3] = { S3C24XX_DMA_APB, true, 15 },
+ [DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, 16 },
+};
+
+static struct s3c24xx_dma_platdata s3c2412_dma_platdata = {
+ .num_phy_channels = 4,
+ .channels = s3c2412_dma_channels,
+ .num_channels = DMACH_MAX,
+};
+
+struct platform_device s3c2412_device_dma = {
+ .name = "s3c2412-dma",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c2410_dma_resource),
+ .resource = s3c2410_dma_resource,
+ .dev = {
+ .platform_data = &s3c2412_dma_platdata,
+ },
+};
+#endif
+
+#if defined(CONFIG_CPU_S3C2440)
+static struct s3c24xx_dma_channel s3c2440_dma_channels[DMACH_MAX] = {
+ [DMACH_XD0] = { S3C24XX_DMA_AHB, true, S3C24XX_DMA_CHANREQ(0, 0), },
+ [DMACH_XD1] = { S3C24XX_DMA_AHB, true, S3C24XX_DMA_CHANREQ(0, 1), },
+ [DMACH_SDI] = { S3C24XX_DMA_APB, false, S3C24XX_DMA_CHANREQ(2, 0) |
+ S3C24XX_DMA_CHANREQ(6, 1) |
+ S3C24XX_DMA_CHANREQ(2, 2) |
+ S3C24XX_DMA_CHANREQ(1, 3),
+ },
+ [DMACH_SPI0] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(3, 1), },
+ [DMACH_SPI1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(2, 3), },
+ [DMACH_UART0] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(1, 0), },
+ [DMACH_UART1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(1, 1), },
+ [DMACH_UART2] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(0, 3), },
+ [DMACH_TIMER] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(3, 0) |
+ S3C24XX_DMA_CHANREQ(3, 2) |
+ S3C24XX_DMA_CHANREQ(3, 3),
+ },
+ [DMACH_I2S_IN] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(2, 1) |
+ S3C24XX_DMA_CHANREQ(1, 2),
+ },
+ [DMACH_I2S_OUT] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(5, 0) |
+ S3C24XX_DMA_CHANREQ(0, 2),
+ },
+ [DMACH_PCM_IN] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(6, 0) |
+ S3C24XX_DMA_CHANREQ(5, 2),
+ },
+ [DMACH_PCM_OUT] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(5, 1) |
+ S3C24XX_DMA_CHANREQ(6, 3),
+ },
+ [DMACH_MIC_IN] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(6, 2) |
+ S3C24XX_DMA_CHANREQ(5, 3),
+ },
+ [DMACH_USB_EP1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 0), },
+ [DMACH_USB_EP2] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 1), },
+ [DMACH_USB_EP3] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 2), },
+ [DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 3), },
+};
+
+static struct s3c24xx_dma_platdata s3c2440_dma_platdata = {
+ .num_phy_channels = 4,
+ .channels = s3c2440_dma_channels,
+ .num_channels = DMACH_MAX,
+};
+
+struct platform_device s3c2440_device_dma = {
+ .name = "s3c2410-dma",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c2410_dma_resource),
+ .resource = s3c2410_dma_resource,
+ .dev = {
+ .platform_data = &s3c2440_dma_platdata,
+ },
+};
+#endif
+
+#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
+static struct resource s3c2443_dma_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C24XX_PA_DMA, S3C24XX_SZ_DMA),
+ [1] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA0),
+ [2] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA1),
+ [3] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA2),
+ [4] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA3),
+ [5] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA4),
+ [6] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA5),
+};
+
+static struct s3c24xx_dma_channel s3c2443_dma_channels[DMACH_MAX] = {
+ [DMACH_XD0] = { S3C24XX_DMA_AHB, true, 17 },
+ [DMACH_XD1] = { S3C24XX_DMA_AHB, true, 18 },
+ [DMACH_SDI] = { S3C24XX_DMA_APB, false, 10 },
+ [DMACH_SPI0_RX] = { S3C24XX_DMA_APB, true, 1 },
+ [DMACH_SPI0_TX] = { S3C24XX_DMA_APB, true, 0 },
+ [DMACH_SPI1_RX] = { S3C24XX_DMA_APB, true, 3 },
+ [DMACH_SPI1_TX] = { S3C24XX_DMA_APB, true, 2 },
+ [DMACH_UART0] = { S3C24XX_DMA_APB, true, 19 },
+ [DMACH_UART1] = { S3C24XX_DMA_APB, true, 21 },
+ [DMACH_UART2] = { S3C24XX_DMA_APB, true, 23 },
+ [DMACH_UART3] = { S3C24XX_DMA_APB, true, 25 },
+ [DMACH_UART0_SRC2] = { S3C24XX_DMA_APB, true, 20 },
+ [DMACH_UART1_SRC2] = { S3C24XX_DMA_APB, true, 22 },
+ [DMACH_UART2_SRC2] = { S3C24XX_DMA_APB, true, 24 },
+ [DMACH_UART3_SRC2] = { S3C24XX_DMA_APB, true, 26 },
+ [DMACH_TIMER] = { S3C24XX_DMA_APB, true, 9 },
+ [DMACH_I2S_IN] = { S3C24XX_DMA_APB, true, 5 },
+ [DMACH_I2S_OUT] = { S3C24XX_DMA_APB, true, 4 },
+ [DMACH_PCM_IN] = { S3C24XX_DMA_APB, true, 28 },
+ [DMACH_PCM_OUT] = { S3C24XX_DMA_APB, true, 27 },
+ [DMACH_MIC_IN] = { S3C24XX_DMA_APB, true, 29 },
+};
+
+static struct s3c24xx_dma_platdata s3c2443_dma_platdata = {
+ .num_phy_channels = 6,
+ .channels = s3c2443_dma_channels,
+ .num_channels = DMACH_MAX,
+};
+
+struct platform_device s3c2443_device_dma = {
+ .name = "s3c2443-dma",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c2443_dma_resource),
+ .resource = s3c2443_dma_resource,
+ .dev = {
+ .platform_data = &s3c2443_dma_platdata,
+ },
+};
+#endif
+
+#if defined(CONFIG_COMMON_CLK) && defined(CONFIG_CPU_S3C2410)
+void __init s3c2410_init_clocks(int xtal)
+{
+ s3c2410_common_clk_init(NULL, xtal, 0, S3C24XX_VA_CLKPWR);
+}
+#endif
+
+#ifdef CONFIG_CPU_S3C2412
+void __init s3c2412_init_clocks(int xtal)
+{
+ s3c2412_common_clk_init(NULL, xtal, 0, S3C24XX_VA_CLKPWR);
+}
+#endif
+
+#ifdef CONFIG_CPU_S3C2416
+void __init s3c2416_init_clocks(int xtal)
+{
+ s3c2443_common_clk_init(NULL, xtal, 0, S3C24XX_VA_CLKPWR);
+}
+#endif
+
+#if defined(CONFIG_COMMON_CLK) && defined(CONFIG_CPU_S3C2440)
+void __init s3c2440_init_clocks(int xtal)
+{
+ s3c2410_common_clk_init(NULL, xtal, 1, S3C24XX_VA_CLKPWR);
+}
+#endif
+
+#if defined(CONFIG_COMMON_CLK) && defined(CONFIG_CPU_S3C2442)
+void __init s3c2442_init_clocks(int xtal)
+{
+ s3c2410_common_clk_init(NULL, xtal, 2, S3C24XX_VA_CLKPWR);
+}
+#endif
+
+#ifdef CONFIG_CPU_S3C2443
+void __init s3c2443_init_clocks(int xtal)
+{
+ s3c2443_common_clk_init(NULL, xtal, 1, S3C24XX_VA_CLKPWR);
+}
+#endif
+
+#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2440) || \
+ defined(CONFIG_CPU_S3C2442)
+static struct resource s3c2410_dclk_resource[] = {
+ [0] = DEFINE_RES_MEM(0x56000084, 0x4),
+};
+
+struct platform_device s3c2410_device_dclk = {
+ .name = "s3c2410-dclk",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c2410_dclk_resource),
+ .resource = s3c2410_dclk_resource,
+};
+#endif
diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h
new file mode 100644
index 000000000..c7ac7e61a
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/common.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Common Header for S3C24XX 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 __ARCH_ARM_MACH_S3C24XX_COMMON_H
+#define __ARCH_ARM_MACH_S3C24XX_COMMON_H __FILE__
+
+#include <linux/reboot.h>
+
+struct s3c2410_uartcfg;
+
+#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);
+extern void s3c2410_init_irq(void);
+#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
+
+#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);
+extern void s3c2412_init_irq(void);
+#else
+#define s3c2412_init_clocks NULL
+#define s3c2412_init_uarts NULL
+#define s3c2412_map_io NULL
+#define s3c2412_init NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2416
+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);
+extern void s3c2416_init_irq(void);
+
+extern struct syscore_ops s3c2416_irq_syscore_ops;
+#else
+#define s3c2416_init_clocks NULL
+#define s3c2416_init_uarts NULL
+#define s3c2416_map_io NULL
+#define s3c2416_init NULL
+#endif
+
+#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);
+#else
+#define s3c244x_init_uarts NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2440
+extern int s3c2440_init(void);
+extern void s3c2440_map_io(void);
+extern void s3c2440_init_clocks(int xtal);
+extern void s3c2440_init_irq(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);
+extern void s3c2442_init_clocks(int xtal);
+extern void s3c2442_init_irq(void);
+#else
+#define s3c2442_init NULL
+#define s3c2442_map_io NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2443
+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);
+extern void s3c2443_init_irq(void);
+#else
+#define s3c2443_init_clocks NULL
+#define s3c2443_init_uarts NULL
+#define s3c2443_map_io NULL
+#define s3c2443_init NULL
+#endif
+
+extern struct syscore_ops s3c24xx_irq_syscore_ops;
+
+extern struct platform_device s3c2410_device_dma;
+extern struct platform_device s3c2412_device_dma;
+extern struct platform_device s3c2440_device_dma;
+extern struct platform_device s3c2443_device_dma;
+
+extern struct platform_device s3c2410_device_dclk;
+
+#ifdef CONFIG_S3C2410_COMMON_CLK
+void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
+ int current_soc,
+ void __iomem *reg_base);
+#endif
+#ifdef CONFIG_S3C2412_COMMON_CLK
+void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f,
+ unsigned long ext_f, void __iomem *reg_base);
+#endif
+#ifdef CONFIG_S3C2443_COMMON_CLK
+void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
+ int current_soc,
+ void __iomem *reg_base);
+#endif
+
+#endif /* __ARCH_ARM_MACH_S3C24XX_COMMON_H */
diff --git a/arch/arm/mach-s3c24xx/cpufreq-utils.c b/arch/arm/mach-s3c24xx/cpufreq-utils.c
new file mode 100644
index 000000000..d4d951433
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/cpufreq-utils.c
@@ -0,0 +1,66 @@
+/*
+ * 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 <linux/clk.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu-freq-core.h>
+
+#include "regs-mem.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)
+{
+ if (!IS_ERR(cfg->mpll))
+ clk_set_rate(cfg->mpll, cfg->pll.frequency);
+}
diff --git a/arch/arm/mach-s3c24xx/gta02.h b/arch/arm/mach-s3c24xx/gta02.h
new file mode 100644
index 000000000..9430a71e9
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/gta02.h
@@ -0,0 +1,23 @@
+/*
+ * GTA02 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 __MACH_S3C24XX_GTA02_H
+#define __MACH_S3C24XX_GTA02_H __FILE__
+
+#include <mach/regs-gpio.h>
+
+#define GTA02_GPIO_AUX_LED S3C2410_GPB(2)
+#define GTA02_GPIO_USB_PULLUP S3C2410_GPB(9)
+#define GTA02_GPIO_AUX_KEY S3C2410_GPF(6)
+#define GTA02_GPIO_HOLD_KEY S3C2410_GPF(7)
+#define GTA02_GPIO_AMP_SHUT S3C2410_GPJ(1) /* v2 + v3 + v4 only */
+#define GTA02_GPIO_HP_IN S3C2410_GPJ(2) /* v2 + v3 + v4 only */
+
+#define GTA02_IRQ_PCF50633 IRQ_EINT9
+
+#endif /* __MACH_S3C24XX_GTA02_H */
diff --git a/arch/arm/mach-s3c24xx/h1940-bluetooth.c b/arch/arm/mach-s3c24xx/h1940-bluetooth.c
new file mode 100644
index 000000000..9c8b1279a
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/h1940-bluetooth.c
@@ -0,0 +1,147 @@
+/*
+ * 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 <plat/gpio-cfg.h>
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include "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(NULL, 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(NULL, 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 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,
+};
+
+module_platform_driver(h1940bt_driver);
+
+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-s3c24xx/h1940.h b/arch/arm/mach-s3c24xx/h1940.h
new file mode 100644
index 000000000..596d9f64c
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/h1940.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2006 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Copyright (c) 2005 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * iPAQ H1940 series definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __MACH_S3C24XX_H1940_H
+#define __MACH_S3C24XX_H1940_H __FILE__
+
+#define H1940_SUSPEND_CHECKSUM (0x30003ff8)
+#define H1940_SUSPEND_RESUMEAT (0x30081000)
+#define H1940_SUSPEND_CHECK (0x30080000)
+
+struct gpio_desc;
+
+extern void h1940_pm_return(void);
+extern int h1940_led_blink_set(struct gpio_desc *desc, int state,
+ unsigned long *delay_on,
+ unsigned long *delay_off);
+
+#include <linux/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 /* __MACH_S3C24XX_H1940_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/dma.h b/arch/arm/mach-s3c24xx/include/mach/dma.h
new file mode 100644
index 000000000..9e8117198
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/dma.h
@@ -0,0 +1,55 @@
+/* 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 <linux/device.h>
+
+/* 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 = 0,
+ 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_SPI0_TX, /* s3c2443/2416/2450 hsspi0 */
+ DMACH_SPI0_RX, /* s3c2443/2416/2450 hsspi0 */
+ DMACH_SPI1_TX, /* s3c2443/2450 hsspi1 */
+ DMACH_SPI1_RX, /* s3c2443/2450 hsspi1 */
+ DMACH_MAX, /* the end entry */
+};
+
+#endif /* __ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/fb.h b/arch/arm/mach-s3c24xx/include/mach/fb.h
new file mode 100644
index 000000000..a957bc8ed
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/fb.h
@@ -0,0 +1 @@
+#include <plat/fb-s3c2410.h>
diff --git a/arch/arm/mach-s3c24xx/include/mach/gpio-samsung.h b/arch/arm/mach-s3c24xx/include/mach/gpio-samsung.h
new file mode 100644
index 000000000..528fcdc4f
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/gpio-samsung.h
@@ -0,0 +1,104 @@
+/*
+ * 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.
+*/
+
+/* some boards require extra gpio capacity to support external
+ * devices that need GPIO.
+ */
+
+#ifndef GPIO_SAMSUNG_S3C24XX_H
+#define GPIO_SAMSUNG_S3C24XX_H
+
+/*
+ * GPIO sizes for various SoCs:
+ *
+ * 2410 2412 2440 2443 2416
+ * 2442
+ * ---- ---- ---- ---- ----
+ * A 23 22 25 16 27
+ * B 11 11 11 11 11
+ * C 16 16 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 11 15 15
+ * J -- -- 13 16 --
+ * K -- -- -- -- 16
+ * L -- -- -- 15 14
+ * 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 nonzero 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))
+
+#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
+
+#endif /* GPIO_SAMSUNG_S3C24XX_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/hardware.h b/arch/arm/mach-s3c24xx/include/mach/hardware.h
new file mode 100644
index 000000000..dedd3837c
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/hardware.h
@@ -0,0 +1,24 @@
+/*
+ * 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);
+
+#endif /* __ASSEMBLY__ */
+
+#include <asm/sizes.h>
+#include <mach/map.h>
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/io.h b/arch/arm/mach-s3c24xx/include/mach/io.h
new file mode 100644
index 000000000..5dd1db4e2
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/io.h
@@ -0,0 +1,211 @@
+/*
+ * 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))
+
+#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)
+
+#endif
diff --git a/arch/arm/mach-s3c24xx/include/mach/irqs.h b/arch/arm/mach-s3c24xx/include/mach/irqs.h
new file mode 100644
index 000000000..b6dd4cb5a
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/irqs.h
@@ -0,0 +1,217 @@
+/* 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_EINT0_2412 S3C2410_IRQ(32)
+#define IRQ_EINT1_2412 S3C2410_IRQ(33)
+#define IRQ_EINT2_2412 S3C2410_IRQ(34)
+#define IRQ_EINT3_2412 S3C2410_IRQ(35)
+#define IRQ_EINT4 S3C2410_IRQ(36) /* 52 */
+#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_EINT19 S3C2410_IRQ(51)
+#define IRQ_EINT20 S3C2410_IRQ(52) /* 68 */
+#define IRQ_EINT21 S3C2410_IRQ(53)
+#define IRQ_EINT22 S3C2410_IRQ(54)
+#define IRQ_EINT23 S3C2410_IRQ(55)
+
+#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(56)
+#define IRQ_LCD_FRAME S3C2410_IRQ(57)
+
+/* 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)+58)
+
+#define IRQ_S3CUART_RX0 S3C2410_IRQSUB(0) /* 74 */
+#define IRQ_S3CUART_TX0 S3C2410_IRQSUB(1)
+#define IRQ_S3CUART_ERR0 S3C2410_IRQSUB(2)
+
+#define IRQ_S3CUART_RX1 S3C2410_IRQSUB(3) /* 77 */
+#define IRQ_S3CUART_TX1 S3C2410_IRQSUB(4)
+#define IRQ_S3CUART_ERR1 S3C2410_IRQSUB(5)
+
+#define IRQ_S3CUART_RX2 S3C2410_IRQSUB(6) /* 80 */
+#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)
+
+/* second interrupt-register of s3c2416/s3c2450 */
+
+#define S3C2416_IRQ(x) S3C2410_IRQ((x) + 58 + 29)
+#define IRQ_S3C2416_2D S3C2416_IRQ(0)
+#define IRQ_S3C2416_IIC1 S3C2416_IRQ(1)
+#define IRQ_S3C2416_RESERVED2 S3C2416_IRQ(2)
+#define IRQ_S3C2416_RESERVED3 S3C2416_IRQ(3)
+#define IRQ_S3C2416_PCM0 S3C2416_IRQ(4)
+#define IRQ_S3C2416_PCM1 S3C2416_IRQ(5)
+#define IRQ_S3C2416_I2S0 S3C2416_IRQ(6)
+#define IRQ_S3C2416_I2S1 S3C2416_IRQ(7)
+
+/* 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_S3C2416)
+#define NR_IRQS (IRQ_S3C2416_I2S1 + 1)
+#else
+#define NR_IRQS (IRQ_S3C2443_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-s3c24xx/include/mach/map.h b/arch/arm/mach-s3c24xx/include/mach/map.h
new file mode 100644
index 000000000..444793f0f
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/map.h
@@ -0,0 +1,172 @@
+/* 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>
+
+/*
+ * S3C2410 UART offset is 0x4000 but the other SoCs are 0x400.
+ * So need to define it, and here is to avoid redefinition warning.
+ */
+#define S3C_UART_OFFSET (0x4000)
+
+#include <plat/map-s3c.h>
+
+/*
+ * interrupt controller is the first thing we put in, to make
+ * the assembly code for the irq detection easier
+ */
+#define S3C2410_PA_IRQ (0x4A000000)
+#define S3C24XX_SZ_IRQ SZ_1M
+
+/* memory controller registers */
+#define S3C2410_PA_MEMCTRL (0x48000000)
+#define S3C24XX_SZ_MEMCTRL SZ_1M
+
+/* UARTs */
+#define S3C_VA_UARTx(uart) (S3C_VA_UART + ((uart * S3C_UART_OFFSET)))
+
+/* Timers */
+#define S3C2410_PA_TIMER (0x51000000)
+#define S3C24XX_SZ_TIMER SZ_1M
+
+/* Clock and Power management */
+#define S3C24XX_SZ_CLKPWR SZ_1M
+
+/* USB Device port */
+#define S3C2410_PA_USBDEV (0x52000000)
+#define S3C24XX_SZ_USBDEV SZ_1M
+
+/* Watchdog */
+#define S3C2410_PA_WATCHDOG (0x53000000)
+#define S3C24XX_SZ_WATCHDOG SZ_1M
+
+/* Standard size definitions for peripheral blocks. */
+
+#define S3C24XX_SZ_UART SZ_1M
+#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
+#define S3C24XX_SZ_GPIO SZ_1M
+
+/* 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)
+#define S3C2443_PA_SPI0 (0x52000000)
+#define S3C2443_PA_SPI1 S3C2410_PA_SPI
+
+/* 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_PA_EBI (0x48800000)
+
+/* 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_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_RTC S3C2410_PA_RTC
+#define S3C24XX_PA_ADC S3C2410_PA_ADC
+#define S3C24XX_PA_SPI S3C2410_PA_SPI
+#define S3C24XX_PA_SPI1 (S3C2410_PA_SPI + S3C2410_SPI1)
+#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
+
+#define S3C_PA_SPI0 S3C2443_PA_SPI0
+#define S3C_PA_SPI1 S3C2443_PA_SPI1
+
+#define SAMSUNG_PA_TIMER S3C2410_PA_TIMER
+
+#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/pm-core.h b/arch/arm/mach-s3c24xx/include/mach/pm-core.h
new file mode 100644
index 000000000..69459dbbd
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/pm-core.h
@@ -0,0 +1,87 @@
+/* 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.
+ */
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include "regs-clock.h"
+#include "regs-irq.h"
+
+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 */
+}
+
+/* s3c2410_pm_show_resume_irqs
+ *
+ * print any IRQs asserted at resume time (ie, we woke from)
+*/
+static inline void 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);
+ }
+ }
+}
+
+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)
+{
+}
+
+static inline void s3c_pm_restored_gpios(void) { }
+static inline void samsung_pm_saved_gpios(void) { }
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-clock.h b/arch/arm/mach-s3c24xx/include/mach/regs-clock.h
new file mode 100644
index 000000000..3db6c10de
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/regs-clock.h
@@ -0,0 +1,148 @@
+/* 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)
+
+#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-s3c24xx/include/mach/regs-gpio.h b/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h
new file mode 100644
index 000000000..c6583cfa5
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h
@@ -0,0 +1,610 @@
+/* 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
+
+#define S3C24XX_MISCCR S3C24XX_GPIOREG2(0x80)
+
+/* 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
+ * 1 makes port special function, this is default
+*/
+#define S3C2410_GPACON S3C2410_GPIOREG(0x00)
+#define S3C2410_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 S3C2410_GPA11_ADDR26 (1<<11)
+#define S3C2410_GPA12_nGCS1 (1<<12)
+#define S3C2410_GPA13_nGCS2 (1<<13)
+#define S3C2410_GPA14_nGCS3 (1<<14)
+#define S3C2410_GPA15_nGCS4 (1<<15)
+#define S3C2410_GPA16_nGCS5 (1<<16)
+#define S3C2410_GPA17_CLE (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
+
+ * 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)
+
+/* no i/o pin in port b can have value 3 (unless it is a s3c2443) ! */
+
+#define S3C2410_GPB0_TOUT0 (0x02 << 0)
+
+#define S3C2410_GPB1_TOUT1 (0x02 << 2)
+
+#define S3C2410_GPB2_TOUT2 (0x02 << 4)
+
+#define S3C2410_GPB3_TOUT3 (0x02 << 6)
+
+#define S3C2410_GPB4_TCLK0 (0x02 << 8)
+#define S3C2410_GPB4_MASK (0x03 << 8)
+
+#define S3C2410_GPB5_nXBACK (0x02 << 10)
+#define S3C2443_GPB5_XBACK (0x03 << 10)
+
+#define S3C2410_GPB6_nXBREQ (0x02 << 12)
+#define S3C2443_GPB6_XBREQ (0x03 << 12)
+
+#define S3C2410_GPB7_nXDACK1 (0x02 << 14)
+#define S3C2443_GPB7_XDACK1 (0x03 << 14)
+
+#define S3C2410_GPB8_nXDREQ1 (0x02 << 16)
+
+#define S3C2410_GPB9_nXDACK0 (0x02 << 18)
+#define S3C2443_GPB9_XDACK0 (0x03 << 18)
+
+#define S3C2410_GPB10_nXDRE0 (0x02 << 20)
+#define S3C2443_GPB10_XDREQ0 (0x03 << 20)
+
+#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 S3C2410_GPC0_LEND (0x02 << 0)
+#define S3C2410_GPC1_VCLK (0x02 << 2)
+#define S3C2410_GPC2_VLINE (0x02 << 4)
+#define S3C2410_GPC3_VFRAME (0x02 << 6)
+#define S3C2410_GPC4_VM (0x02 << 8)
+#define S3C2410_GPC5_LCDVF0 (0x02 << 10)
+#define S3C2410_GPC6_LCDVF1 (0x02 << 12)
+#define S3C2410_GPC7_LCDVF2 (0x02 << 14)
+#define S3C2410_GPC8_VD0 (0x02 << 16)
+#define S3C2410_GPC9_VD1 (0x02 << 18)
+#define S3C2410_GPC10_VD2 (0x02 << 20)
+#define S3C2410_GPC11_VD3 (0x02 << 22)
+#define S3C2410_GPC12_VD4 (0x02 << 24)
+#define S3C2410_GPC13_VD5 (0x02 << 26)
+#define S3C2410_GPC14_VD6 (0x02 << 28)
+#define S3C2410_GPC15_VD7 (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.
+ *
+ * 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 S3C2410_GPD0_VD8 (0x02 << 0)
+#define S3C2442_GPD0_nSPICS1 (0x03 << 0)
+
+#define S3C2410_GPD1_VD9 (0x02 << 2)
+#define S3C2442_GPD1_SPICLK1 (0x03 << 2)
+
+#define S3C2410_GPD2_VD10 (0x02 << 4)
+
+#define S3C2410_GPD3_VD11 (0x02 << 6)
+
+#define S3C2410_GPD4_VD12 (0x02 << 8)
+
+#define S3C2410_GPD5_VD13 (0x02 << 10)
+
+#define S3C2410_GPD6_VD14 (0x02 << 12)
+
+#define S3C2410_GPD7_VD15 (0x02 << 14)
+
+#define S3C2410_GPD8_VD16 (0x02 << 16)
+#define S3C2440_GPD8_SPIMISO1 (0x03 << 16)
+
+#define S3C2410_GPD9_VD17 (0x02 << 18)
+#define S3C2440_GPD9_SPIMOSI1 (0x03 << 18)
+
+#define S3C2410_GPD10_VD18 (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
+ *
+ * GPIO / interrupt inputs
+*/
+
+#define S3C2410_GPECON S3C2410_GPIOREG(0x40)
+#define S3C2410_GPEDAT S3C2410_GPIOREG(0x44)
+#define S3C2410_GPEUP S3C2410_GPIOREG(0x48)
+
+#define S3C2410_GPE0_I2SLRCK (0x02 << 0)
+#define S3C2443_GPE0_AC_nRESET (0x03 << 0)
+#define S3C2410_GPE0_MASK (0x03 << 0)
+
+#define S3C2410_GPE1_I2SSCLK (0x02 << 2)
+#define S3C2443_GPE1_AC_SYNC (0x03 << 2)
+#define S3C2410_GPE1_MASK (0x03 << 2)
+
+#define S3C2410_GPE2_CDCLK (0x02 << 4)
+#define S3C2443_GPE2_AC_BITCLK (0x03 << 4)
+
+#define S3C2410_GPE3_I2SSDI (0x02 << 6)
+#define S3C2443_GPE3_AC_SDI (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 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 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 S3C2410_GPE7_SDDAT0 (0x02 << 14)
+#define S3C2443_GPE5_SD1_DAT0 (0x02 << 14)
+#define S3C2443_GPE7_AC_SDO (0x03 << 14)
+
+#define S3C2410_GPE8_SDDAT1 (0x02 << 16)
+#define S3C2443_GPE8_SD1_DAT1 (0x02 << 16)
+#define S3C2443_GPE8_AC_SYNC (0x03 << 16)
+
+#define S3C2410_GPE9_SDDAT2 (0x02 << 18)
+#define S3C2443_GPE9_SD1_DAT2 (0x02 << 18)
+#define S3C2443_GPE9_AC_nRESET (0x03 << 18)
+
+#define S3C2410_GPE10_SDDAT3 (0x02 << 20)
+#define S3C2443_GPE10_SD1_DAT3 (0x02 << 20)
+
+#define S3C2410_GPE11_SPIMISO0 (0x02 << 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.
+ *
+ * GPIO/serial/misc pins
+*/
+
+#define S3C2410_GPFCON S3C2410_GPIOREG(0x50)
+#define S3C2410_GPFDAT S3C2410_GPIOREG(0x54)
+#define S3C2410_GPFUP S3C2410_GPIOREG(0x58)
+
+#define S3C2410_GPF0_EINT0 (0x02 << 0)
+#define S3C2410_GPF1_EINT1 (0x02 << 2)
+#define S3C2410_GPF2_EINT2 (0x02 << 4)
+#define S3C2410_GPF3_EINT3 (0x02 << 6)
+#define S3C2410_GPF4_EINT4 (0x02 << 8)
+#define S3C2410_GPF5_EINT5 (0x02 << 10)
+#define S3C2410_GPF6_EINT6 (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 G
+ * 00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 special func
+ *
+ * pull up works like all other ports.
+*/
+
+#define S3C2410_GPGCON S3C2410_GPIOREG(0x60)
+#define S3C2410_GPGDAT S3C2410_GPIOREG(0x64)
+#define S3C2410_GPGUP S3C2410_GPIOREG(0x68)
+
+#define S3C2410_GPG0_EINT8 (0x02 << 0)
+
+#define S3C2410_GPG1_EINT9 (0x02 << 2)
+
+#define S3C2410_GPG2_EINT10 (0x02 << 4)
+#define S3C2410_GPG2_nSS0 (0x03 << 4)
+
+#define S3C2410_GPG3_EINT11 (0x02 << 6)
+#define S3C2410_GPG3_nSS1 (0x03 << 6)
+
+#define S3C2410_GPG4_EINT12 (0x02 << 8)
+#define S3C2410_GPG4_LCDPWREN (0x03 << 8)
+#define S3C2443_GPG4_LCDPWRDN (0x03 << 8)
+
+#define S3C2410_GPG5_EINT13 (0x02 << 10)
+#define S3C2410_GPG5_SPIMISO1 (0x03 << 10) /* not s3c2443 */
+
+#define S3C2410_GPG6_EINT14 (0x02 << 12)
+#define S3C2410_GPG6_SPIMOSI1 (0x03 << 12)
+
+#define S3C2410_GPG7_EINT15 (0x02 << 14)
+#define S3C2410_GPG7_SPICLK1 (0x03 << 14)
+
+#define S3C2410_GPG8_EINT16 (0x02 << 16)
+
+#define S3C2410_GPG9_EINT17 (0x02 << 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
+ *
+ * GPHCON has 2 bits for each of the input pins on port H
+ * 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
+*/
+
+/*
+ * Port J consists of 13 GPIO/Camera pins. GPJCON has 2 bits
+ * for each of the pins on port J.
+ * 00 - input, 01 output, 10 - 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)
+
+/* 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 S3C2410_MISCCR S3C2410_GPIOREG(0x80)
+
+/* 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 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 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)
+
+/* 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-s3c24xx/include/mach/regs-irq.h b/arch/arm/mach-s3c24xx/include/mach/regs-irq.h
new file mode 100644
index 000000000..0f07ba30b
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/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-s3c24xx/include/mach/regs-lcd.h b/arch/arm/mach-s3c24xx/include/mach/regs-lcd.h
new file mode 100644
index 000000000..ee8f040af
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/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-s3c24xx/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h
new file mode 100644
index 000000000..ffe37bdb9
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/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_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 S3C2416_CLKDIV0_ARMDIV_MASK (7 << 9)
+#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_HSSPI (1<<6)
+#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-s3c24xx/include/mach/rtc-core.h b/arch/arm/mach-s3c24xx/include/mach/rtc-core.h
new file mode 100644
index 000000000..4d5f5768f
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/rtc-core.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2011 Heiko Stuebner <heiko@sntech.de>
+ *
+ * Samsung RTC 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 __RTC_CORE_H
+#define __RTC_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+extern struct platform_device s3c_device_rtc;
+
+/* re-define device name depending on support. */
+static inline void s3c_rtc_setname(char *name)
+{
+ s3c_device_rtc.name = name;
+}
+
+#endif /* __RTC_CORE_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/s3c2412.h b/arch/arm/mach-s3c24xx/include/mach/s3c2412.h
new file mode 100644
index 000000000..548ced42c
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/s3c2412.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_S3C24XX_S3C2412_H
+#define __ARCH_ARM_REGS_S3C24XX_S3C2412_H __FILE__
+
+#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_REFRESH S3C2412_MEMREG(0x10)
+
+#define S3C2412_EBI_BANKCFG S3C2412_EBIREG(0x4)
+
+#define S3C2412_SSMC_BANK(x) S3C2412_SSMC(x, 0x0)
+
+#endif /* __ARCH_ARM_MACH_S3C24XX_S3C2412_H */
diff --git a/arch/arm/mach-s3c24xx/iotiming-s3c2410.c b/arch/arm/mach-s3c24xx/iotiming-s3c2410.c
new file mode 100644
index 000000000..4cd13ab64
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/iotiming-s3c2410.c
@@ -0,0 +1,478 @@
+/*
+ * 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-clock.h>
+
+#include <plat/cpu-freq-core.h>
+
+#include "regs-mem.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/mach-s3c24xx/iotiming-s3c2412.c b/arch/arm/mach-s3c24xx/iotiming-s3c2412.c
new file mode 100644
index 000000000..28b13951d
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/iotiming-s3c2412.c
@@ -0,0 +1,284 @@
+/*
+ * 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/device.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 <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+
+#include <mach/s3c2412.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/mach-s3c24xx/irq-pm.c b/arch/arm/mach-s3c24xx/irq-pm.c
new file mode 100644
index 000000000..b91341ef2
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/irq-pm.c
@@ -0,0 +1,129 @@
+/* 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 <linux/syscore_ops.h>
+#include <linux/io.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/map-base.h>
+#include <plat/map-s3c.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.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 << 30 | 0xfL;
+unsigned long s3c_irqwake_eintallow = 0x0000fff0L;
+
+int s3c_irq_wake(struct irq_data *data, unsigned int state)
+{
+ unsigned long irqbit = 1 << data->hwirq;
+
+ if (!(s3c_irqwake_intallow & irqbit))
+ return -ENOENT;
+
+ pr_info("wake %s for hwirq %lu\n",
+ state ? "enabled" : "disabled", data->hwirq);
+
+ 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;
+
+static 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;
+}
+
+static 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);
+}
+
+struct syscore_ops s3c24xx_irq_syscore_ops = {
+ .suspend = s3c24xx_irq_suspend,
+ .resume = s3c24xx_irq_resume,
+};
+
+#ifdef CONFIG_CPU_S3C2416
+static struct sleep_save s3c2416_irq_save[] = {
+ SAVE_ITEM(S3C2416_INTMSK2),
+};
+
+static int s3c2416_irq_suspend(void)
+{
+ s3c_pm_do_save(s3c2416_irq_save, ARRAY_SIZE(s3c2416_irq_save));
+
+ return 0;
+}
+
+static void s3c2416_irq_resume(void)
+{
+ s3c_pm_do_restore(s3c2416_irq_save, ARRAY_SIZE(s3c2416_irq_save));
+}
+
+struct syscore_ops s3c2416_irq_syscore_ops = {
+ .suspend = s3c2416_irq_suspend,
+ .resume = s3c2416_irq_resume,
+};
+#endif
diff --git a/arch/arm/mach-s3c24xx/mach-amlm5900.c b/arch/arm/mach-s3c24xx/mach-amlm5900.c
new file mode 100644
index 000000000..3e63777a1
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-amlm5900.c
@@ -0,0 +1,250 @@
+/* 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/serial_s3c.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 <mach/regs-lcd.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <linux/platform_data/i2c-s3c2410.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>
+
+#include <plat/samsung-time.h>
+
+#include "common.h"
+
+static struct resource amlm5900_nor_resource =
+ DEFINE_RES_MEM(0x00000000, SZ_16M);
+
+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_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init amlm5900_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+#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")
+ .atag_offset = 0x100,
+ .map_io = amlm5900_map_io,
+ .init_irq = s3c2410_init_irq,
+ .init_machine = amlm5900_init,
+ .init_time = amlm5900_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-anubis.c b/arch/arm/mach-s3c24xx/mach-anubis.c
new file mode 100644
index 000000000..d03df0df0
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-anubis.c
@@ -0,0 +1,433 @@
+/* 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/serial_s3c.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/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/gpio-samsung.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/i2c-s3c2410.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/devs.h>
+#include <plat/cpu.h>
+#include <linux/platform_data/asoc-s3c24xx_simtec.h>
+#include <plat/samsung-time.h>
+
+#include "anubis.h"
+#include "common.h"
+#include "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 s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
+ },
+ [1] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
+ },
+};
+
+/* 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[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_CS3, 8 * 32),
+ [2] = DEFINE_RES_MEM(S3C2410_CS3 + (1 << 26) + (6 * 32), 32),
+ [3] = DEFINE_RES_IRQ(ANUBIS_IRQ_IDE0),
+};
+
+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[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_CS4, 8 * 32),
+ [1] = DEFINE_RES_MEM(S3C2410_CS4 + (1 << 26) + (6 * 32), 32),
+ [2] = DEFINE_RES_IRQ(ANUBIS_IRQ_IDE0),
+};
+
+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] = DEFINE_RES_MEM(S3C2410_CS5, 0x20 * 0x20),
+ [1] = DEFINE_RES_IRQ(ANUBIS_IRQ_ASIX),
+};
+
+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] = DEFINE_RES_MEM(S3C2410_CS2, SZ_8M),
+ [1] = DEFINE_RES_MEM(S3C2410_CS2 + SZ_64M - SZ_2M, SZ_2M),
+ [2] = DEFINE_RES_IRQ(IRQ_EINT0),
+};
+
+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 = {
+ &s3c2410_device_dclk,
+ &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,
+};
+
+/* 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)
+{
+ s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
+ s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ /* 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 */
+ gpio_request_one(S3C2410_GPA(0), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPA(0));
+ }
+}
+
+static void __init anubis_init_time(void)
+{
+ s3c2440_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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> */
+ .atag_offset = 0x100,
+ .map_io = anubis_map_io,
+ .init_machine = anubis_init,
+ .init_irq = s3c2440_init_irq,
+ .init_time = anubis_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-at2440evb.c b/arch/arm/mach-s3c24xx/mach-at2440evb.c
new file mode 100644
index 000000000..9ae170fef
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-at2440evb.c
@@ -0,0 +1,221 @@
+/* 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/gpio.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/serial_s3c.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 <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/gpio-samsung.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <linux/platform_data/mmc-s3cmci.h>
+#include <plat/samsung-time.h>
+
+#include "common.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 s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
+ },
+};
+
+/* 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] = DEFINE_RES_MEM(S3C2410_CS3, 4),
+ [1] = DEFINE_RES_MEM(S3C2410_CS3 + 4, 4),
+ [2] = DEFINE_RES_NAMED(IRQ_EINT7, 1, NULL, 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_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init at2440evb_init_time(void)
+{
+ s3c2440_init_clocks(16934400);
+ samsung_timer_init();
+}
+
+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")
+ .atag_offset = 0x100,
+ .map_io = at2440evb_map_io,
+ .init_machine = at2440evb_init,
+ .init_irq = s3c2440_init_irq,
+ .init_time = at2440evb_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-bast.c b/arch/arm/mach-s3c24xx/mach-bast.c
new file mode 100644
index 000000000..ed07cf392
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-bast.c
@@ -0,0 +1,594 @@
+/* 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/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/dm9000.h>
+#include <linux/ata_platform.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/serial_8250.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <linux/platform_data/asoc-s3c24xx_simtec.h>
+#include <linux/platform_data/hwmon-s3c.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+
+#include <net/ax88796.h>
+
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/fb.h>
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/samsung-time.h>
+
+#include "bast.h"
+#include "common.h"
+#include "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 s3c2410_uartcfg bast_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,
+ }
+};
+
+/* 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] = DEFINE_RES_MEM(S3C2410_CS5 + BAST_PA_DM9000, 4),
+ [1] = DEFINE_RES_MEM(S3C2410_CS5 + BAST_PA_DM9000 + 0x40, 0x40),
+ [2] = DEFINE_RES_NAMED(BAST_IRQ_DM9000 , 1, NULL, 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 = BAST_IRQ_PCSERIAL1,
+ .flags = SERIAL_FLAGS,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = SERIAL_CLK,
+ },
+ [1] = {
+ .mapbase = SERIAL_BASE + 0x3f8,
+ .irq = BAST_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] = DEFINE_RES_MEM(S3C2410_CS5 + BAST_PA_ASIXNET, 0x18 * 0x20),
+ [1] = DEFINE_RES_MEM(S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20), 1),
+ [2] = DEFINE_RES_IRQ(BAST_IRQ_ASIX),
+};
+
+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] = DEFINE_RES_MEM(S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20), \
+ 0x30 * 0x20),
+};
+
+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 = {
+ &s3c2410_device_dclk,
+ &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 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)
+{
+ s3c_hwmon_set_platdata(&bast_hwmon_info);
+
+ s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
+ s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init bast_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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> */
+ .atag_offset = 0x100,
+ .map_io = bast_map_io,
+ .init_irq = s3c2410_init_irq,
+ .init_machine = bast_init,
+ .init_time = bast_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c
new file mode 100644
index 000000000..6d1e0b9c5
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-gta02.c
@@ -0,0 +1,600 @@
+/*
+ * 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/gpio_keys.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+
+#include <linux/mmc/host.h>
+
+#include <linux/mfd/pcf50633/adc.h>
+#include <linux/mfd/pcf50633/backlight.h>
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/gpio.h>
+#include <linux/mfd/pcf50633/mbc.h>
+#include <linux/mfd/pcf50633/pmic.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/regulator/machine.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/s3c24xx.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/touchscreen-s3c2410.h>
+#include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <linux/platform_data/usb-s3c2410_udc.h>
+
+#include <mach/fb.h>
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-irq.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/pm.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "gta02.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(gta02_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,
+};
+
+static 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 =
+ DEFINE_RES_MEM(GTA02_FLASH_BASE, GTA02_FLASH_SIZE);
+
+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,
+};
+
+
+static 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_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+
+/* 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,
+ &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();
+}
+
+static void __init gta02_init_time(void)
+{
+ s3c2442_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+MACHINE_START(NEO1973_GTA02, "GTA02")
+ /* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
+ .atag_offset = 0x100,
+ .map_io = gta02_map_io,
+ .init_irq = s3c2442_init_irq,
+ .init_machine = gta02_machine_init,
+ .init_time = gta02_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c
new file mode 100644
index 000000000..d40d4f524
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-h1940.c
@@ -0,0 +1,751 @@
+/*
+ * 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/device.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.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 <linux/export.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <linux/platform_data/mmc-s3cmci.h>
+#include <linux/platform_data/touchscreen-s3c2410.h>
+#include <linux/platform_data/usb-s3c2410_udc.h>
+
+#include <sound/uda1380.h>
+
+#include <mach/fb.h>
+#include <mach/hardware.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/pm.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "h1940.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))
+
+#define S3C24XX_PLL_MDIV_SHIFT (12)
+#define S3C24XX_PLL_PDIV_SHIFT (4)
+#define S3C24XX_PLL_SDIV_SHIFT (0)
+
+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;
+}
+
+static 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] = DEFINE_RES_NAMED(IRQ_EINT2, 1, "ac", IORESOURCE_IRQ \
+ | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE),
+};
+
+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},
+};
+
+static 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;
+
+}
+
+static void h1940_bat_exit(void)
+{
+ gpio_free(H1940_LATCH_SM803_ENABLE);
+}
+
+static void h1940_enable_charger(void)
+{
+ gpio_set_value(H1940_LATCH_SM803_ENABLE, 1);
+}
+
+static 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,
+ },
+};
+
+static DEFINE_SPINLOCK(h1940_blink_spin);
+
+int h1940_led_blink_set(struct gpio_desc *desc, int state,
+ unsigned long *delay_on, unsigned long *delay_off)
+{
+ int blink_gpio, check_gpio1, check_gpio2;
+ int gpio = desc ? desc_to_gpio(desc) : -EINVAL;
+
+ 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_gpio2 = 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,
+ .enable_gpio = -1,
+ .init = h1940_backlight_init,
+ .notify = h1940_backlight_notify,
+ .exit = h1940_backlight_exit,
+};
+
+static struct platform_device h1940_backlight = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &samsung_device_pwm.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,
+ &s3c_device_usbgadget,
+ &h1940_device_leds,
+ &h1940_device_bluetooth,
+ &s3c_device_sdi,
+ &s3c_device_rtc,
+ &samsung_device_pwm,
+ &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_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ /* 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));
+}
+
+static void __init h1940_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+/* 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(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_PLL_MDIV_SHIFT)
+ | (0x02 << S3C24XX_PLL_PDIV_SHIFT)
+ | (0x03 << S3C24XX_PLL_SDIV_SHIFT);
+ 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> */
+ .atag_offset = 0x100,
+ .map_io = h1940_map_io,
+ .reserve = h1940_reserve,
+ .init_irq = s3c2410_init_irq,
+ .init_machine = h1940_init,
+ .init_time = h1940_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-jive.c b/arch/arm/mach-s3c24xx/mach-jive.c
new file mode 100644
index 000000000..7d99fe8f6
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-jive.c
@@ -0,0 +1,673 @@
+/* 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/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+
+#include <video/ili9320.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/fb.h>
+#include <mach/gpio-samsung.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/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <linux/platform_data/usb-s3c2410_udc.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "s3c2412-power.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 (kstrtoul(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 struct spi_gpio_platform_data jive_lcd_spi = {
+ .sck = S3C2410_GPG(8),
+ .mosi = S3C2410_GPB(8),
+ .miso = SPI_GPIO_NO_MISO,
+};
+
+static struct platform_device jive_device_lcdspi = {
+ .name = "spi-gpio",
+ .id = 1,
+ .dev.platform_data = &jive_lcd_spi,
+};
+
+
+/* WM8750 audio code SPI definition */
+
+static struct spi_gpio_platform_data jive_wm8750_spi = {
+ .sck = S3C2410_GPB(4),
+ .mosi = S3C2410_GPB(9),
+ .miso = SPI_GPIO_NO_MISO,
+};
+
+static struct platform_device jive_device_wm8750 = {
+ .name = "spi-gpio",
+ .id = 2,
+ .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,
+ .controller_data = (void *)S3C2410_GPB(7),
+ }, {
+ .modalias = "WM8750",
+ .bus_num = 2,
+ .chip_select = 0,
+ .mode = SPI_MODE_0, /* CPOL=0, CPHA=0 */
+ .max_speed_hz = 100000,
+ .controller_data = (void *)S3C2410_GPH(10),
+ },
+};
+
+/* 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,
+ &s3c2412_device_dma,
+};
+
+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_uarts(jive_uartcfgs, ARRAY_SIZE(jive_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init jive_init_time(void)
+{
+ s3c2412_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+static void jive_power_off(void)
+{
+ printk(KERN_INFO "powering system down...\n");
+
+ gpio_request_one(S3C2410_GPC(5), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPC(5));
+}
+
+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);
+
+ gpio_request_one(S3C2410_GPB(6), GPIOF_OUT_INIT_LOW, NULL);
+ gpio_free(S3C2410_GPB(6));
+
+ gpio_request_one(S3C2410_GPG(8), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPG(8));
+
+ /* 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> */
+ .atag_offset = 0x100,
+
+ .init_irq = s3c2412_init_irq,
+ .map_io = jive_map_io,
+ .init_machine = jive_machine_init,
+ .init_time = jive_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c
new file mode 100644
index 000000000..a8521684a
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-mini2440.c
@@ -0,0 +1,698 @@
+/* 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/serial_s3c.h>
+#include <linux/dm9000.h>
+#include <linux/platform_data/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 <mach/regs-gpio.h>
+#include <linux/platform_data/leds-s3c24xx.h>
+#include <mach/regs-lcd.h>
+#include <mach/irqs.h>
+#include <mach/gpio-samsung.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <linux/platform_data/mmc-s3cmci.h>
+#include <linux/platform_data/usb-s3c2410_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/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.h>
+
+#include <sound/s3c24xx_uda134x.h>
+
+#include "common.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),
+ },
+ /* mini2440 + 3.5" TFT (LCD-W35i, LQ035Q1DG06 type) + touchscreen*/
+ [3] = {
+ _LCD_DECLARE(
+ /* clock */
+ 7,
+ /* xres, margin_right, margin_left, hsync */
+ 320, 68, 66, 4,
+ /* yres, margin_top, margin_bottom, vsync */
+ 240, 4, 4, 9,
+ /* refresh rate */
+ 60),
+ .lcdcon5 = (S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_INVVDEN |
+ S3C2410_LCDCON5_INVVFRAME |
+ S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_INVVCLK |
+ 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] = DEFINE_RES_MEM(MACH_MINI2440_DM9K_BASE, 4),
+ [1] = DEFINE_RES_MEM(MACH_MINI2440_DM9K_BASE + 4, 4),
+ [2] = DEFINE_RES_NAMED(IRQ_EINT7, 1, NULL, 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,
+};
+
+static void __init mini2440_map_io(void)
+{
+ s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc));
+ s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init mini2440_init_time(void)
+{
+ s3c2440_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+/*
+ * 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_one(S3C2410_GPG(4), GPIOF_OUT_INIT_HIGH, NULL));
+ gpio_free(S3C2410_GPG(4));
+
+ /* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */
+ gpio_request_one(S3C2410_GPB(1), GPIOF_IN, NULL);
+ s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_UP);
+ gpio_free(S3C2410_GPB(1));
+
+ /* 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> */
+ .atag_offset = 0x100,
+ .map_io = mini2440_map_io,
+ .init_machine = mini2440_init,
+ .init_irq = s3c2440_init_irq,
+ .init_time = mini2440_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-n30.c b/arch/arm/mach-s3c24xx/mach-n30.c
new file mode 100644
index 000000000..171c1f11f
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-n30.c
@@ -0,0 +1,612 @@
+/* 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/serial_s3c.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 <linux/platform_data/leds-s3c24xx.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/gpio-samsung.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <linux/platform_data/mmc-s3cmci.h>
+#include <linux/platform_data/usb-s3c2410_udc.h>
+#include <plat/samsung-time.h>
+
+#include "common.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_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init n30_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+/* 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>
+ */
+ .atag_offset = 0x100,
+ .init_time = n30_init_time,
+ .init_machine = n30_init,
+ .init_irq = s3c2410_init_irq,
+ .map_io = n30_map_io,
+MACHINE_END
+
+MACHINE_START(N35, "Acer-N35")
+ /* Maintainer: Christer Weinigel <christer@weinigel.se>
+ */
+ .atag_offset = 0x100,
+ .init_time = n30_init_time,
+ .init_machine = n30_init,
+ .init_irq = s3c2410_init_irq,
+ .map_io = n30_map_io,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-nexcoder.c b/arch/arm/mach-s3c24xx/mach-nexcoder.c
new file mode 100644
index 000000000..2a61d13dc
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-nexcoder.c
@@ -0,0 +1,162 @@
+/* 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/serial_s3c.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 <mach/gpio-samsung.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.h>
+
+#include "common.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] = DEFINE_RES_MEM(S3C2410_CS0, SZ_8M),
+};
+
+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 */
+ gpio_request_one(S3C2410_GPE(14), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPE(14)); /* IICSCL */
+ gpio_request_one(S3C2410_GPE(15), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPE(15)); /* IICSDA */
+
+ /* Power up the sensor board */
+ gpio_request_one(S3C2410_GPF(1), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPF(1)); /* CAM_GPIO7 => nLDO_PWRDN */
+ gpio_request_one(S3C2410_GPF(2), GPIOF_OUT_INIT_LOW, NULL);
+ gpio_free(S3C2410_GPF(2)); /* CAM_GPIO6 => CAM_PWRDN */
+}
+
+static void __init nexcoder_map_io(void)
+{
+ s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
+ s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ nexcoder_sensorboard_init();
+}
+
+static void __init nexcoder_init_time(void)
+{
+ s3c2440_init_clocks(12000000);
+ samsung_timer_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> */
+ .atag_offset = 0x100,
+ .map_io = nexcoder_map_io,
+ .init_machine = nexcoder_init,
+ .init_irq = s3c2440_init_irq,
+ .init_time = nexcoder_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-osiris-dvs.c b/arch/arm/mach-s3c24xx/mach-osiris-dvs.c
new file mode 100644
index 000000000..ce2db235d
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-osiris-dvs.c
@@ -0,0 +1,183 @@
+/* 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>
+#include <mach/gpio-samsung.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 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 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 = osiris_dvs_remove,
+ .driver = {
+ .name = "osiris-dvs",
+ .pm = &osiris_dvs_pm,
+ },
+};
+
+module_platform_driver(osiris_dvs_driver);
+
+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-s3c24xx/mach-osiris.c b/arch/arm/mach-s3c24xx/mach-osiris.c
new file mode 100644
index 000000000..2f6fdc326
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-osiris.c
@@ -0,0 +1,415 @@
+/*
+ * 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/serial_s3c.h>
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include <linux/i2c/tps65010.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/samsung-time.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/gpio-samsung.h>
+
+#include "common.h"
+#include "osiris.h"
+#include "regs-mem.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 s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
+ }
+};
+
+/* 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] = DEFINE_RES_MEM(0x0f000000, SZ_1M),
+ [1] = DEFINE_RES_MEM(0x0c000000, SZ_1M),
+};
+
+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. */
+ gpio_request_one(S3C2410_GPA(21), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPA(21));
+
+ 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 = {
+ &s3c2410_device_dclk,
+ &s3c_device_i2c0,
+ &s3c_device_wdt,
+ &s3c_device_nand,
+ &osiris_pcmcia,
+};
+
+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;
+
+ s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
+ s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ /* 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 */
+ gpio_request_one(S3C2410_GPA(0), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPA(0));
+ }
+
+ /* 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_time(void)
+{
+ s3c2440_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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> */
+ .atag_offset = 0x100,
+ .map_io = osiris_map_io,
+ .init_irq = s3c2440_init_irq,
+ .init_machine = osiris_init,
+ .init_time = osiris_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-otom.c b/arch/arm/mach-s3c24xx/mach-otom.c
new file mode 100644
index 000000000..345a484b9
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-otom.c
@@ -0,0 +1,125 @@
+/*
+ *
+ * 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/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <asm/irq.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/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "otom.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] = DEFINE_RES_MEM(S3C2410_CS0, SZ_4M),
+};
+
+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_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init otom11_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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> */
+ .atag_offset = 0x100,
+ .map_io = otom11_map_io,
+ .init_machine = otom11_init,
+ .init_irq = s3c2410_init_irq,
+ .init_time = otom11_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-qt2410.c b/arch/arm/mach-s3c24xx/mach-qt2410.c
new file mode 100644
index 000000000..984516e83
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-qt2410.c
@@ -0,0 +1,355 @@
+/* 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/device.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.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 <linux/platform_data/leds-s3c24xx.h>
+#include <mach/regs-lcd.h>
+#include <mach/fb.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/usb-s3c2410_udc.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "common-smdk.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] = DEFINE_RES_MEM(0x19000000, 17),
+ [1] = DEFINE_RES_IRQ(IRQ_EINT9),
+};
+
+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 struct spi_gpio_platform_data spi_gpio_cfg = {
+ .sck = S3C2410_GPG(7),
+ .mosi = S3C2410_GPG(6),
+ .miso = S3C2410_GPG(5),
+};
+
+static struct platform_device qt2410_spi = {
+ .name = "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_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init qt2410_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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);
+
+ /* set initial state of the LED GPIO */
+ WARN_ON(gpio_request_one(S3C2410_GPB(0), GPIOF_OUT_INIT_HIGH, NULL));
+ gpio_free(S3C2410_GPB(0));
+
+ 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")
+ .atag_offset = 0x100,
+ .map_io = qt2410_map_io,
+ .init_irq = s3c2410_init_irq,
+ .init_machine = qt2410_machine_init,
+ .init_time = qt2410_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c
new file mode 100644
index 000000000..1d35ff375
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-rx1950.c
@@ -0,0 +1,816 @@
+/*
+ * 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/serial_s3c.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/device.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-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <linux/platform_data/mmc-s3cmci.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/touchscreen-s3c2410.h>
+#include <linux/platform_data/usb-s3c2410_udc.h>
+
+#include <sound/uda1380.h>
+
+#include <mach/fb.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
+#include <plat/samsung-time.h>
+#include <plat/gpio-cfg.h>
+
+#include "common.h"
+#include "h1940.h"
+
+#define LCD_PWM_PERIOD 192960
+#define LCD_PWM_DUTY 127353
+
+static struct map_desc rx1950_iodesc[] __initdata = {
+};
+
+static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ .clk_sel = S3C2410_UCON_CLKSEL3,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ .clk_sel = S3C2410_UCON_CLKSEL3,
+ },
+ /* IR port */
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x43,
+ .ufcon = 0xf1,
+ .clk_sel = S3C2410_UCON_CLKSEL3,
+ },
+};
+
+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] = DEFINE_RES_NAMED(IRQ_EINT2, 1, "ac", IORESOURCE_IRQ \
+ | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE),
+};
+
+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},
+};
+
+static 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;
+}
+
+static void rx1950_bat_exit(void)
+{
+ gpio_free(S3C2410_GPJ(2));
+ gpio_free(S3C2410_GPJ(3));
+}
+
+static void rx1950_enable_charger(void)
+{
+ gpio_direction_output(S3C2410_GPJ(2), 1);
+ gpio_direction_output(S3C2410_GPJ(3), 1);
+}
+
+static void rx1950_disable_charger(void)
+{
+ gpio_direction_output(S3C2410_GPJ(2), 0);
+ gpio_direction_output(S3C2410_GPJ(3), 0);
+}
+
+static DEFINE_SPINLOCK(rx1950_blink_spin);
+
+static int rx1950_led_blink_set(struct gpio_desc *desc, int state,
+ unsigned long *delay_on, unsigned long *delay_off)
+{
+ int gpio = desc_to_gpio(desc);
+ 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;
+
+static 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,
+ .enable_gpio = -1,
+ .init = rx1950_backlight_init,
+ .notify = rx1950_backlight_notify,
+ .exit = rx1950_backlight_exit,
+};
+
+static struct platform_device rx1950_backlight = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &samsung_device_pwm.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 = {
+ &s3c2410_device_dclk,
+ &s3c_device_lcd,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_iis,
+ &s3c_device_usbgadget,
+ &s3c_device_rtc,
+ &s3c_device_nand,
+ &s3c_device_sdi,
+ &s3c_device_adc,
+ &s3c_device_ts,
+ &samsung_device_pwm,
+ &rx1950_backlight,
+ &rx1950_device_gpiokeys,
+ &power_supply,
+ &rx1950_battery,
+ &rx1950_leds,
+};
+
+static void __init rx1950_map_io(void)
+{
+ s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc));
+ s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ /* 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_time(void)
+{
+ s3c2442_init_clocks(16934000);
+ samsung_timer_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 */
+ .atag_offset = 0x100,
+ .map_io = rx1950_map_io,
+ .reserve = rx1950_reserve,
+ .init_irq = s3c2442_init_irq,
+ .init_machine = rx1950_init_machine,
+ .init_time = rx1950_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-rx3715.c b/arch/arm/mach-s3c24xx/mach-rx3715.c
new file mode 100644
index 000000000..cf55196f8
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-rx3715.c
@@ -0,0 +1,218 @@
+/* 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/device.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.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/irq.h>
+#include <asm/mach/map.h>
+
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/fb.h>
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "h1940.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 s3c2410_uartcfg rx3715_uartcfgs[] = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ .clk_sel = S3C2410_UCON_CLKSEL3,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x00,
+ .clk_sel = S3C2410_UCON_CLKSEL3,
+ },
+ /* IR port */
+ [2] = {
+ .hwport = 2,
+ .uart_flags = UPF_CONS_FLOW,
+ .ucon = 0x3c5,
+ .ulcon = 0x43,
+ .ufcon = 0x51,
+ .clk_sel = S3C2410_UCON_CLKSEL3,
+ }
+};
+
+/* 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_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init rx3715_init_time(void)
+{
+ s3c2440_init_clocks(16934000);
+ samsung_timer_init();
+}
+
+/* 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_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> */
+ .atag_offset = 0x100,
+ .map_io = rx3715_map_io,
+ .reserve = rx3715_reserve,
+ .init_irq = s3c2440_init_irq,
+ .init_machine = rx3715_init_machine,
+ .init_time = rx3715_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c b/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c
new file mode 100644
index 000000000..f886478b8
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c
@@ -0,0 +1,54 @@
+/*
+ * Samsung's S3C2416 flattened device tree enabled machine
+ *
+ * Copyright (c) 2012 Heiko Stuebner <heiko@sntech.de>
+ *
+ * based on mach-exynos/mach-exynos4-dt.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Copyright (c) 2010-2011 Linaro Ltd.
+ * www.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 <linux/clocksource.h>
+#include <linux/irqchip.h>
+#include <linux/of_platform.h>
+#include <linux/serial_s3c.h>
+
+#include <asm/mach/arch.h>
+#include <mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include "common.h"
+
+static void __init s3c2416_dt_map_io(void)
+{
+ s3c24xx_init_io(NULL, 0);
+}
+
+static void __init s3c2416_dt_machine_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ s3c_pm_init();
+}
+
+static char const *s3c2416_dt_compat[] __initdata = {
+ "samsung,s3c2416",
+ "samsung,s3c2450",
+ NULL
+};
+
+DT_MACHINE_START(S3C2416_DT, "Samsung S3C2416 (Flattened Device Tree)")
+ /* Maintainer: Heiko Stuebner <heiko@sntech.de> */
+ .dt_compat = s3c2416_dt_compat,
+ .map_io = s3c2416_dt_map_io,
+ .init_irq = irqchip_init,
+ .init_machine = s3c2416_dt_machine_init,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2410.c b/arch/arm/mach-s3c24xx/mach-smdk2410.c
new file mode 100644
index 000000000..27dd6605e
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-smdk2410.c
@@ -0,0 +1,127 @@
+/* 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/serial_s3c.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 <linux/platform_data/i2c-s3c2410.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "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_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init smdk2410_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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 */
+ .atag_offset = 0x100,
+ .map_io = smdk2410_map_io,
+ .init_irq = s3c2410_init_irq,
+ .init_machine = smdk2410_init,
+ .init_time = smdk2410_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2413.c b/arch/arm/mach-s3c24xx/mach-smdk2413.c
new file mode 100644
index 000000000..586e4a3b8
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-smdk2413.c
@@ -0,0 +1,163 @@
+/* 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/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/memblock.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 <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <linux/platform_data/usb-s3c2410_udc.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <mach/gpio-samsung.h>
+#include <mach/fb.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "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,
+ &s3c2412_device_dma,
+};
+
+static void __init smdk2413_fixup(struct tag *tags, char **cmdline)
+{
+ if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
+ memblock_add(0x30000000, SZ_64M);
+ }
+}
+
+static void __init smdk2413_map_io(void)
+{
+ s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc));
+ s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init smdk2413_init_time(void)
+{
+ s3c2412_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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> */
+ .atag_offset = 0x100,
+
+ .fixup = smdk2413_fixup,
+ .init_irq = s3c2412_init_irq,
+ .map_io = smdk2413_map_io,
+ .init_machine = smdk2413_machine_init,
+ .init_time = samsung_timer_init,
+MACHINE_END
+
+MACHINE_START(SMDK2412, "SMDK2412")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .atag_offset = 0x100,
+
+ .fixup = smdk2413_fixup,
+ .init_irq = s3c2412_init_irq,
+ .map_io = smdk2413_map_io,
+ .init_machine = smdk2413_machine_init,
+ .init_time = samsung_timer_init,
+MACHINE_END
+
+MACHINE_START(SMDK2413, "SMDK2413")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .atag_offset = 0x100,
+
+ .fixup = smdk2413_fixup,
+ .init_irq = s3c2412_init_irq,
+ .map_io = smdk2413_map_io,
+ .init_machine = smdk2413_machine_init,
+ .init_time = smdk2413_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2416.c b/arch/arm/mach-s3c24xx/mach-smdk2416.c
new file mode 100644
index 000000000..86394f72d
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-smdk2416.c
@@ -0,0 +1,265 @@
+/* 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/serial_s3c.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 <video/samsung_fimd.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-s3c2443-clock.h>
+#include <mach/gpio-samsung.h>
+
+#include <linux/platform_data/leds-s3c24xx.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <plat/sdhci.h>
+#include <linux/platform_data/usb-s3c2410_udc.h>
+#include <linux/platform_data/s3c-hsudc.h>
+#include <plat/samsung-time.h>
+
+#include <plat/fb.h>
+
+#include "common.h"
+#include "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,
+ }
+};
+
+static 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);
+}
+
+static 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));
+}
+
+static struct s3c24xx_hsudc_platdata smdk2416_hsudc_platdata = {
+ .epnum = 9,
+ .gpio_init = smdk2416_hsudc_gpio_init,
+ .gpio_uninit = smdk2416_hsudc_gpio_uninit,
+};
+
+static struct s3c_fb_pd_win smdk2416_fb_win[] = {
+ [0] = {
+ .default_bpp = 16,
+ .max_bpp = 32,
+ .xres = 800,
+ .yres = 480,
+ },
+};
+
+static struct fb_videomode smdk2416_lcd_timing = {
+ .pixclock = 41094,
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+};
+
+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],
+ .vtiming = &smdk2416_lcd_timing,
+ .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,
+ &s3c2443_device_dma,
+};
+
+static void __init smdk2416_init_time(void)
+{
+ s3c2416_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+static void __init smdk2416_map_io(void)
+{
+ s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc));
+ s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+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> */
+ .atag_offset = 0x100,
+
+ .init_irq = s3c2416_init_irq,
+ .map_io = smdk2416_map_io,
+ .init_machine = smdk2416_machine_init,
+ .init_time = smdk2416_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2440.c b/arch/arm/mach-s3c24xx/mach-smdk2440.c
new file mode 100644
index 000000000..9bb96bfbb
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-smdk2440.c
@@ -0,0 +1,188 @@
+/* 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/serial_s3c.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 <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/fb.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "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_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init smdk2440_init_time(void)
+{
+ s3c2440_init_clocks(16934400);
+ samsung_timer_init();
+}
+
+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> */
+ .atag_offset = 0x100,
+
+ .init_irq = s3c2440_init_irq,
+ .map_io = smdk2440_map_io,
+ .init_machine = smdk2440_machine_init,
+ .init_time = smdk2440_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2443.c b/arch/arm/mach-s3c24xx/mach-smdk2443.c
new file mode 100644
index 000000000..87fe5c5b8
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-smdk2443.c
@@ -0,0 +1,153 @@
+/* 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/serial_s3c.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 <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/fb.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "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
+ &s3c2443_device_dma,
+};
+
+static void __init smdk2443_map_io(void)
+{
+ s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc));
+ s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init smdk2443_init_time(void)
+{
+ s3c2443_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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> */
+ .atag_offset = 0x100,
+
+ .init_irq = s3c2443_init_irq,
+ .map_io = smdk2443_map_io,
+ .init_machine = smdk2443_machine_init,
+ .init_time = smdk2443_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-tct_hammer.c b/arch/arm/mach-s3c24xx/mach-tct_hammer.c
new file mode 100644
index 000000000..2deb62f92
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-tct_hammer.c
@@ -0,0 +1,160 @@
+/* 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/serial_s3c.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 <linux/platform_data/i2c-s3c2410.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>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+
+static struct resource tct_hammer_nor_resource =
+ DEFINE_RES_MEM(0x00000000, SZ_16M);
+
+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_uarts(tct_hammer_uartcfgs, ARRAY_SIZE(tct_hammer_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init tct_hammer_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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")
+ .atag_offset = 0x100,
+ .map_io = tct_hammer_map_io,
+ .init_irq = s3c2410_init_irq,
+ .init_machine = tct_hammer_init,
+ .init_time = tct_hammer_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-vr1000.c b/arch/arm/mach-s3c24xx/mach-vr1000.c
new file mode 100644
index 000000000..89f32bd3f
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-vr1000.c
@@ -0,0 +1,343 @@
+/*
+ * 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/serial_s3c.h>
+#include <linux/io.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 <linux/platform_data/leds-s3c24xx.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <linux/platform_data/asoc-s3c24xx_simtec.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/samsung-time.h>
+
+#include "bast.h"
+#include "common.h"
+#include "simtec.h"
+#include "vr1000.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
+
+static struct s3c2410_uartcfg vr1000_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,
+ }
+};
+
+/* 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 = VR1000_IRQ_SERIAL + 0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = VR1000_BAUDBASE,
+ },
+ [1] = {
+ .mapbase = VR1000_SERIAL_MAPBASE(1),
+ .irq = VR1000_IRQ_SERIAL + 1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = VR1000_BAUDBASE,
+ },
+ [2] = {
+ .mapbase = VR1000_SERIAL_MAPBASE(2),
+ .irq = VR1000_IRQ_SERIAL + 2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = VR1000_BAUDBASE,
+ },
+ [3] = {
+ .mapbase = VR1000_SERIAL_MAPBASE(3),
+ .irq = VR1000_IRQ_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] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000, 4),
+ [1] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000 + 0x40, 0x40),
+ [2] = DEFINE_RES_NAMED(VR1000_IRQ_DM9000A, 1, NULL, IORESOURCE_IRQ \
+ | IORESOURCE_IRQ_HIGHLEVEL),
+};
+
+static struct resource vr1000_dm9k1_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000 + 0x80, 4),
+ [1] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000 + 0xC0, 0x40),
+ [2] = DEFINE_RES_NAMED(VR1000_IRQ_DM9000N, 1, NULL, 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 = {
+ &s3c2410_device_dclk,
+ &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 void vr1000_power_off(void)
+{
+ gpio_direction_output(S3C2410_GPB(9), 1);
+}
+
+static void __init vr1000_map_io(void)
+{
+ pm_power_off = vr1000_power_off;
+
+ s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
+ s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init vr1000_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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> */
+ .atag_offset = 0x100,
+ .map_io = vr1000_map_io,
+ .init_machine = vr1000_init,
+ .init_irq = s3c2410_init_irq,
+ .init_time = vr1000_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-vstms.c b/arch/arm/mach-s3c24xx/mach-vstms.c
new file mode 100644
index 000000000..b4460d5f7
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-vstms.c
@@ -0,0 +1,168 @@
+/* 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/serial_s3c.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 <linux/memblock.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 <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/fb.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.h>
+
+#include "common.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,
+ &s3c2412_device_dma,
+};
+
+static void __init vstms_fixup(struct tag *tags, char **cmdline)
+{
+ if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
+ memblock_add(0x30000000, SZ_64M);
+ }
+}
+
+static void __init vstms_map_io(void)
+{
+ s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc));
+ s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init vstms_init_time(void)
+{
+ s3c2412_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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")
+ .atag_offset = 0x100,
+
+ .fixup = vstms_fixup,
+ .init_irq = s3c2412_init_irq,
+ .init_machine = vstms_init,
+ .map_io = vstms_map_io,
+ .init_time = vstms_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/osiris.h b/arch/arm/mach-s3c24xx/osiris.h
new file mode 100644
index 000000000..b8d56074a
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/osiris.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2005 Simtec Electronics
+ * http://www.simtec.co.uk/products/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * OSIRIS - CPLD control constants
+ * 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.
+*/
+
+#ifndef __MACH_S3C24XX_OSIRIS_H
+#define __MACH_S3C24XX_OSIRIS_H __FILE__
+
+/* 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)
+
+/* 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 /* __MACH_S3C24XX_OSIRIS_H */
diff --git a/arch/arm/mach-s3c24xx/otom.h b/arch/arm/mach-s3c24xx/otom.h
new file mode 100644
index 000000000..321b7be1c
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/otom.h
@@ -0,0 +1,28 @@
+/*
+ * (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.
+*/
+
+/*
+ * 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 __MACH_S3C24XX_OTOM_H
+#define __MACH_S3C24XX_OTOM_H __FILE__
+
+#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)
+
+#endif /* __MACH_S3C24XX_OTOM_H */
diff --git a/arch/arm/mach-s3c24xx/pll-s3c2410.c b/arch/arm/mach-s3c24xx/pll-s3c2410.c
new file mode 100644
index 000000000..5e37d3685
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/pll-s3c2410.c
@@ -0,0 +1,96 @@
+/*
+ * 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/device.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, .driver_data = PLLVAL(82, 2, 3), },
+ { .frequency = 45000000, .driver_data = PLLVAL(82, 1, 3), },
+ { .frequency = 51000000, .driver_data = PLLVAL(161, 3, 3), },
+ { .frequency = 48000000, .driver_data = PLLVAL(120, 2, 3), },
+ { .frequency = 56000000, .driver_data = PLLVAL(142, 2, 3), },
+ { .frequency = 68000000, .driver_data = PLLVAL(82, 2, 2), },
+ { .frequency = 79000000, .driver_data = PLLVAL(71, 1, 2), },
+ { .frequency = 85000000, .driver_data = PLLVAL(105, 2, 2), },
+ { .frequency = 90000000, .driver_data = PLLVAL(112, 2, 2), },
+ { .frequency = 101000000, .driver_data = PLLVAL(127, 2, 2), },
+ { .frequency = 113000000, .driver_data = PLLVAL(105, 1, 2), },
+ { .frequency = 118000000, .driver_data = PLLVAL(150, 2, 2), },
+ { .frequency = 124000000, .driver_data = PLLVAL(116, 1, 2), },
+ { .frequency = 135000000, .driver_data = PLLVAL(82, 2, 1), },
+ { .frequency = 147000000, .driver_data = PLLVAL(90, 2, 1), },
+ { .frequency = 152000000, .driver_data = PLLVAL(68, 1, 1), },
+ { .frequency = 158000000, .driver_data = PLLVAL(71, 1, 1), },
+ { .frequency = 170000000, .driver_data = PLLVAL(77, 1, 1), },
+ { .frequency = 180000000, .driver_data = PLLVAL(82, 1, 1), },
+ { .frequency = 186000000, .driver_data = PLLVAL(85, 1, 1), },
+ { .frequency = 192000000, .driver_data = PLLVAL(88, 1, 1), },
+ { .frequency = 203000000, .driver_data = PLLVAL(161, 3, 1), },
+
+ /* 2410A extras */
+
+ { .frequency = 210000000, .driver_data = PLLVAL(132, 2, 1), },
+ { .frequency = 226000000, .driver_data = PLLVAL(105, 1, 1), },
+ { .frequency = 266000000, .driver_data = PLLVAL(125, 1, 1), },
+ { .frequency = 268000000, .driver_data = PLLVAL(126, 1, 1), },
+ { .frequency = 270000000, .driver_data = PLLVAL(127, 1, 1), },
+};
+
+static int s3c2410_plls_add(struct device *dev, struct subsys_interface *sif)
+{
+ return s3c_plltab_register(pll_vals_12MHz, ARRAY_SIZE(pll_vals_12MHz));
+}
+
+static struct subsys_interface s3c2410_plls_interface = {
+ .name = "s3c2410_plls",
+ .subsys = &s3c2410_subsys,
+ .add_dev = s3c2410_plls_add,
+};
+
+static int __init s3c2410_pll_init(void)
+{
+ return subsys_interface_register(&s3c2410_plls_interface);
+
+}
+arch_initcall(s3c2410_pll_init);
+
+static struct subsys_interface s3c2410a_plls_interface = {
+ .name = "s3c2410a_plls",
+ .subsys = &s3c2410a_subsys,
+ .add_dev = s3c2410_plls_add,
+};
+
+static int __init s3c2410a_pll_init(void)
+{
+ return subsys_interface_register(&s3c2410a_plls_interface);
+}
+arch_initcall(s3c2410a_pll_init);
diff --git a/arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c b/arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c
new file mode 100644
index 000000000..a19460e6e
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c
@@ -0,0 +1,98 @@
+/*
+ * 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/device.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, .driver_data = PLLVAL(0x75, 3, 3), }, /* FVco 600.000000 */
+ { .frequency = 80000000, .driver_data = PLLVAL(0x98, 4, 3), }, /* FVco 640.000000 */
+ { .frequency = 90000000, .driver_data = PLLVAL(0x70, 2, 3), }, /* FVco 720.000000 */
+ { .frequency = 100000000, .driver_data = PLLVAL(0x5c, 1, 3), }, /* FVco 800.000000 */
+ { .frequency = 110000000, .driver_data = PLLVAL(0x66, 1, 3), }, /* FVco 880.000000 */
+ { .frequency = 120000000, .driver_data = PLLVAL(0x70, 1, 3), }, /* FVco 960.000000 */
+ { .frequency = 150000000, .driver_data = PLLVAL(0x75, 3, 2), }, /* FVco 600.000000 */
+ { .frequency = 160000000, .driver_data = PLLVAL(0x98, 4, 2), }, /* FVco 640.000000 */
+ { .frequency = 170000000, .driver_data = PLLVAL(0x4d, 1, 2), }, /* FVco 680.000000 */
+ { .frequency = 180000000, .driver_data = PLLVAL(0x70, 2, 2), }, /* FVco 720.000000 */
+ { .frequency = 190000000, .driver_data = PLLVAL(0x57, 1, 2), }, /* FVco 760.000000 */
+ { .frequency = 200000000, .driver_data = PLLVAL(0x5c, 1, 2), }, /* FVco 800.000000 */
+ { .frequency = 210000000, .driver_data = PLLVAL(0x84, 2, 2), }, /* FVco 840.000000 */
+ { .frequency = 220000000, .driver_data = PLLVAL(0x66, 1, 2), }, /* FVco 880.000000 */
+ { .frequency = 230000000, .driver_data = PLLVAL(0x6b, 1, 2), }, /* FVco 920.000000 */
+ { .frequency = 240000000, .driver_data = PLLVAL(0x70, 1, 2), }, /* FVco 960.000000 */
+ { .frequency = 300000000, .driver_data = PLLVAL(0x75, 3, 1), }, /* FVco 600.000000 */
+ { .frequency = 310000000, .driver_data = PLLVAL(0x93, 4, 1), }, /* FVco 620.000000 */
+ { .frequency = 320000000, .driver_data = PLLVAL(0x98, 4, 1), }, /* FVco 640.000000 */
+ { .frequency = 330000000, .driver_data = PLLVAL(0x66, 2, 1), }, /* FVco 660.000000 */
+ { .frequency = 340000000, .driver_data = PLLVAL(0x4d, 1, 1), }, /* FVco 680.000000 */
+ { .frequency = 350000000, .driver_data = PLLVAL(0xa7, 4, 1), }, /* FVco 700.000000 */
+ { .frequency = 360000000, .driver_data = PLLVAL(0x70, 2, 1), }, /* FVco 720.000000 */
+ { .frequency = 370000000, .driver_data = PLLVAL(0xb1, 4, 1), }, /* FVco 740.000000 */
+ { .frequency = 380000000, .driver_data = PLLVAL(0x57, 1, 1), }, /* FVco 760.000000 */
+ { .frequency = 390000000, .driver_data = PLLVAL(0x7a, 2, 1), }, /* FVco 780.000000 */
+ { .frequency = 400000000, .driver_data = PLLVAL(0x5c, 1, 1), }, /* FVco 800.000000 */
+};
+
+static int s3c2440_plls12_add(struct device *dev, struct subsys_interface *sif)
+{
+ 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 subsys_interface s3c2440_plls12_interface = {
+ .name = "s3c2440_plls12",
+ .subsys = &s3c2440_subsys,
+ .add_dev = s3c2440_plls12_add,
+};
+
+static int __init s3c2440_pll_12mhz(void)
+{
+ return subsys_interface_register(&s3c2440_plls12_interface);
+
+}
+arch_initcall(s3c2440_pll_12mhz);
+
+static struct subsys_interface s3c2442_plls12_interface = {
+ .name = "s3c2442_plls12",
+ .subsys = &s3c2442_subsys,
+ .add_dev = s3c2440_plls12_add,
+};
+
+static int __init s3c2442_pll_12mhz(void)
+{
+ return subsys_interface_register(&s3c2442_plls12_interface);
+
+}
+arch_initcall(s3c2442_pll_12mhz);
diff --git a/arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c b/arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c
new file mode 100644
index 000000000..1191b2905
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c
@@ -0,0 +1,125 @@
+/*
+ * 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/device.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, .driver_data = PLLVAL(121, 5, 3), }, /* FVco 624.153600 */
+ { .frequency = 84067200, .driver_data = PLLVAL(131, 5, 3), }, /* FVco 672.537600 */
+ { .frequency = 90115200, .driver_data = PLLVAL(141, 5, 3), }, /* FVco 720.921600 */
+ { .frequency = 96163200, .driver_data = PLLVAL(151, 5, 3), }, /* FVco 769.305600 */
+ { .frequency = 102135600, .driver_data = PLLVAL(185, 6, 3), }, /* FVco 817.084800 */
+ { .frequency = 108259200, .driver_data = PLLVAL(171, 5, 3), }, /* FVco 866.073600 */
+ { .frequency = 114307200, .driver_data = PLLVAL(127, 3, 3), }, /* FVco 914.457600 */
+ { .frequency = 120234240, .driver_data = PLLVAL(134, 3, 3), }, /* FVco 961.873920 */
+ { .frequency = 126161280, .driver_data = PLLVAL(141, 3, 3), }, /* FVco 1009.290240 */
+ { .frequency = 132088320, .driver_data = PLLVAL(148, 3, 3), }, /* FVco 1056.706560 */
+ { .frequency = 138015360, .driver_data = PLLVAL(155, 3, 3), }, /* FVco 1104.122880 */
+ { .frequency = 144789120, .driver_data = PLLVAL(163, 3, 3), }, /* FVco 1158.312960 */
+ { .frequency = 150100363, .driver_data = PLLVAL(187, 9, 2), }, /* FVco 600.401454 */
+ { .frequency = 156038400, .driver_data = PLLVAL(121, 5, 2), }, /* FVco 624.153600 */
+ { .frequency = 162086400, .driver_data = PLLVAL(126, 5, 2), }, /* FVco 648.345600 */
+ { .frequency = 168134400, .driver_data = PLLVAL(131, 5, 2), }, /* FVco 672.537600 */
+ { .frequency = 174048000, .driver_data = PLLVAL(177, 7, 2), }, /* FVco 696.192000 */
+ { .frequency = 180230400, .driver_data = PLLVAL(141, 5, 2), }, /* FVco 720.921600 */
+ { .frequency = 186278400, .driver_data = PLLVAL(124, 4, 2), }, /* FVco 745.113600 */
+ { .frequency = 192326400, .driver_data = PLLVAL(151, 5, 2), }, /* FVco 769.305600 */
+ { .frequency = 198132480, .driver_data = PLLVAL(109, 3, 2), }, /* FVco 792.529920 */
+ { .frequency = 204271200, .driver_data = PLLVAL(185, 6, 2), }, /* FVco 817.084800 */
+ { .frequency = 210268800, .driver_data = PLLVAL(141, 4, 2), }, /* FVco 841.075200 */
+ { .frequency = 216518400, .driver_data = PLLVAL(171, 5, 2), }, /* FVco 866.073600 */
+ { .frequency = 222264000, .driver_data = PLLVAL(97, 2, 2), }, /* FVco 889.056000 */
+ { .frequency = 228614400, .driver_data = PLLVAL(127, 3, 2), }, /* FVco 914.457600 */
+ { .frequency = 234259200, .driver_data = PLLVAL(158, 4, 2), }, /* FVco 937.036800 */
+ { .frequency = 240468480, .driver_data = PLLVAL(134, 3, 2), }, /* FVco 961.873920 */
+ { .frequency = 246960000, .driver_data = PLLVAL(167, 4, 2), }, /* FVco 987.840000 */
+ { .frequency = 252322560, .driver_data = PLLVAL(141, 3, 2), }, /* FVco 1009.290240 */
+ { .frequency = 258249600, .driver_data = PLLVAL(114, 2, 2), }, /* FVco 1032.998400 */
+ { .frequency = 264176640, .driver_data = PLLVAL(148, 3, 2), }, /* FVco 1056.706560 */
+ { .frequency = 270950400, .driver_data = PLLVAL(120, 2, 2), }, /* FVco 1083.801600 */
+ { .frequency = 276030720, .driver_data = PLLVAL(155, 3, 2), }, /* FVco 1104.122880 */
+ { .frequency = 282240000, .driver_data = PLLVAL(92, 1, 2), }, /* FVco 1128.960000 */
+ { .frequency = 289578240, .driver_data = PLLVAL(163, 3, 2), }, /* FVco 1158.312960 */
+ { .frequency = 294235200, .driver_data = PLLVAL(131, 2, 2), }, /* FVco 1176.940800 */
+ { .frequency = 300200727, .driver_data = PLLVAL(187, 9, 1), }, /* FVco 600.401454 */
+ { .frequency = 306358690, .driver_data = PLLVAL(191, 9, 1), }, /* FVco 612.717380 */
+ { .frequency = 312076800, .driver_data = PLLVAL(121, 5, 1), }, /* FVco 624.153600 */
+ { .frequency = 318366720, .driver_data = PLLVAL(86, 3, 1), }, /* FVco 636.733440 */
+ { .frequency = 324172800, .driver_data = PLLVAL(126, 5, 1), }, /* FVco 648.345600 */
+ { .frequency = 330220800, .driver_data = PLLVAL(109, 4, 1), }, /* FVco 660.441600 */
+ { .frequency = 336268800, .driver_data = PLLVAL(131, 5, 1), }, /* FVco 672.537600 */
+ { .frequency = 342074880, .driver_data = PLLVAL(93, 3, 1), }, /* FVco 684.149760 */
+ { .frequency = 348096000, .driver_data = PLLVAL(177, 7, 1), }, /* FVco 696.192000 */
+ { .frequency = 355622400, .driver_data = PLLVAL(118, 4, 1), }, /* FVco 711.244800 */
+ { .frequency = 360460800, .driver_data = PLLVAL(141, 5, 1), }, /* FVco 720.921600 */
+ { .frequency = 366206400, .driver_data = PLLVAL(165, 6, 1), }, /* FVco 732.412800 */
+ { .frequency = 372556800, .driver_data = PLLVAL(124, 4, 1), }, /* FVco 745.113600 */
+ { .frequency = 378201600, .driver_data = PLLVAL(126, 4, 1), }, /* FVco 756.403200 */
+ { .frequency = 384652800, .driver_data = PLLVAL(151, 5, 1), }, /* FVco 769.305600 */
+ { .frequency = 391608000, .driver_data = PLLVAL(177, 6, 1), }, /* FVco 783.216000 */
+ { .frequency = 396264960, .driver_data = PLLVAL(109, 3, 1), }, /* FVco 792.529920 */
+ { .frequency = 402192000, .driver_data = PLLVAL(87, 2, 1), }, /* FVco 804.384000 */
+};
+
+static int s3c2440_plls169344_add(struct device *dev,
+ struct subsys_interface *sif)
+{
+ 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 subsys_interface s3c2440_plls169344_interface = {
+ .name = "s3c2440_plls169344",
+ .subsys = &s3c2440_subsys,
+ .add_dev = s3c2440_plls169344_add,
+};
+
+static int __init s3c2440_pll_16934400(void)
+{
+ return subsys_interface_register(&s3c2440_plls169344_interface);
+}
+arch_initcall(s3c2440_pll_16934400);
+
+static struct subsys_interface s3c2442_plls169344_interface = {
+ .name = "s3c2442_plls169344",
+ .subsys = &s3c2442_subsys,
+ .add_dev = s3c2440_plls169344_add,
+};
+
+static int __init s3c2442_pll_16934400(void)
+{
+ return subsys_interface_register(&s3c2442_plls169344_interface);
+}
+arch_initcall(s3c2442_pll_16934400);
diff --git a/arch/arm/mach-s3c24xx/pm-h1940.S b/arch/arm/mach-s3c24xx/pm-h1940.S
new file mode 100644
index 000000000..6183a6880
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/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-s3c24xx/pm-s3c2410.c b/arch/arm/mach-s3c24xx/pm-s3c2410.c
new file mode 100644
index 000000000..20e481d8a
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/pm-s3c2410.c
@@ -0,0 +1,186 @@
+/* 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/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include "h1940.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()) {
+ gpio_request_one(S3C2410_GPF(2), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPF(2));
+ }
+
+ 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()) {
+ gpio_request_one(S3C2410_GPF(2), GPIOF_OUT_INIT_LOW, NULL);
+ gpio_free(S3C2410_GPF(2));
+ }
+}
+
+struct syscore_ops s3c2410_pm_syscore_ops = {
+ .resume = s3c2410_pm_resume,
+};
+
+static int s3c2410_pm_add(struct device *dev, struct subsys_interface *sif)
+{
+ pm_cpu_prep = s3c2410_pm_prepare;
+ pm_cpu_sleep = s3c2410_cpu_suspend;
+
+ return 0;
+}
+
+#if defined(CONFIG_CPU_S3C2410)
+static struct subsys_interface s3c2410_pm_interface = {
+ .name = "s3c2410_pm",
+ .subsys = &s3c2410_subsys,
+ .add_dev = s3c2410_pm_add,
+};
+
+/* register ourselves */
+
+static int __init s3c2410_pm_drvinit(void)
+{
+ return subsys_interface_register(&s3c2410_pm_interface);
+}
+
+arch_initcall(s3c2410_pm_drvinit);
+
+static struct subsys_interface s3c2410a_pm_interface = {
+ .name = "s3c2410a_pm",
+ .subsys = &s3c2410a_subsys,
+ .add_dev = s3c2410_pm_add,
+};
+
+static int __init s3c2410a_pm_drvinit(void)
+{
+ return subsys_interface_register(&s3c2410a_pm_interface);
+}
+
+arch_initcall(s3c2410a_pm_drvinit);
+#endif
+
+#if defined(CONFIG_CPU_S3C2440)
+static struct subsys_interface s3c2440_pm_interface = {
+ .name = "s3c2440_pm",
+ .subsys = &s3c2440_subsys,
+ .add_dev = s3c2410_pm_add,
+};
+
+static int __init s3c2440_pm_drvinit(void)
+{
+ return subsys_interface_register(&s3c2440_pm_interface);
+}
+
+arch_initcall(s3c2440_pm_drvinit);
+#endif
+
+#if defined(CONFIG_CPU_S3C2442)
+static struct subsys_interface s3c2442_pm_interface = {
+ .name = "s3c2442_pm",
+ .subsys = &s3c2442_subsys,
+ .add_dev = s3c2410_pm_add,
+};
+
+static int __init s3c2442_pm_drvinit(void)
+{
+ return subsys_interface_register(&s3c2442_pm_interface);
+}
+
+arch_initcall(s3c2442_pm_drvinit);
+#endif
diff --git a/arch/arm/mach-s3c24xx/pm-s3c2412.c b/arch/arm/mach-s3c24xx/pm-s3c2412.c
new file mode 100644
index 000000000..d75f95e48
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/pm-s3c2412.c
@@ -0,0 +1,131 @@
+/* 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/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/wakeup-mask.h>
+
+#include "regs-dsc.h"
+#include "s3c2412-power.h"
+
+extern void s3c2412_sleep_enter(void);
+
+static int s3c2412_cpu_suspend(unsigned long arg)
+{
+ unsigned long tmp;
+
+ /* set our standby method to sleep */
+
+ tmp = __raw_readl(S3C2412_PWRCFG);
+ tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP;
+ __raw_writel(tmp, S3C2412_PWRCFG);
+
+ s3c2412_sleep_enter();
+
+ pr_info("Failed to suspend the system\n");
+ return 1; /* Aborting suspend */
+}
+
+/* mapping of interrupts to parts of the wakeup mask */
+static struct samsung_wakeup_mask wake_irqs[] = {
+ { .irq = IRQ_RTC, .bit = S3C2412_PWRCFG_RTC_MASKIRQ, },
+};
+
+static void s3c2412_pm_prepare(void)
+{
+ samsung_sync_wakemask(S3C2412_PWRCFG,
+ wake_irqs, ARRAY_SIZE(wake_irqs));
+}
+
+static int s3c2412_pm_add(struct device *dev, struct subsys_interface *sif)
+{
+ 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 subsys_interface s3c2412_pm_interface = {
+ .name = "s3c2412_pm",
+ .subsys = &s3c2412_subsys,
+ .add_dev = s3c2412_pm_add,
+};
+
+static __init int s3c2412_pm_init(void)
+{
+ return subsys_interface_register(&s3c2412_pm_interface);
+}
+
+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-s3c24xx/pm-s3c2416.c b/arch/arm/mach-s3c24xx/pm-s3c2416.c
new file mode 100644
index 000000000..c0e328e37
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/pm-s3c2416.c
@@ -0,0 +1,86 @@
+/* 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/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include "s3c2412-power.h"
+
+#ifdef CONFIG_PM_SLEEP
+extern void s3c2412_sleep_enter(void);
+
+static int s3c2416_cpu_suspend(unsigned long arg)
+{
+ /* 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();
+
+ pr_info("Failed to suspend the system\n");
+ return 1; /* Aborting suspend */
+}
+
+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 device *dev, struct subsys_interface *sif)
+{
+ pm_cpu_prep = s3c2416_pm_prepare;
+ pm_cpu_sleep = s3c2416_cpu_suspend;
+
+ return 0;
+}
+
+static struct subsys_interface s3c2416_pm_interface = {
+ .name = "s3c2416_pm",
+ .subsys = &s3c2416_subsys,
+ .add_dev = s3c2416_pm_add,
+};
+
+static __init int s3c2416_pm_init(void)
+{
+ return subsys_interface_register(&s3c2416_pm_interface);
+}
+
+arch_initcall(s3c2416_pm_init);
+#endif
+
+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-s3c24xx/pm.c b/arch/arm/mach-s3c24xx/pm.c
new file mode 100644
index 000000000..5d510bca0
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/pm.c
@@ -0,0 +1,136 @@
+/* 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/serial_s3c.h>
+#include <linux/io.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-irq.h>
+#include <mach/gpio-samsung.h>
+
+#include <asm/mach/time.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/pm.h>
+
+#include "regs-mem.h"
+
+#define PFX "s3c24xx-pm: "
+
+#ifdef CONFIG_PM_SLEEP
+static struct sleep_save core_save[] = {
+ /* 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),
+};
+#endif
+
+/* 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 whether 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);
+ }
+}
+
+#ifdef CONFIG_PM_SLEEP
+void s3c_pm_restore_core(void)
+{
+ s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
+}
+
+void s3c_pm_save_core(void)
+{
+ s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
+}
+#endif
diff --git a/arch/arm/mach-s3c24xx/regs-dsc.h b/arch/arm/mach-s3c24xx/regs-dsc.h
new file mode 100644
index 000000000..61b3d1387
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/regs-dsc.h
@@ -0,0 +1,25 @@
+/*
+ * 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 __FILE__
+
+/* S3C2412 */
+#define S3C2412_DSC0 S3C2410_GPIOREG(0xdc)
+#define S3C2412_DSC1 S3C2410_GPIOREG(0xe0)
+
+/* S3C2440 */
+#define S3C2440_DSC0 S3C2410_GPIOREG(0xc4)
+#define S3C2440_DSC1 S3C2410_GPIOREG(0xc8)
+
+#endif /* __ASM_ARCH_REGS_DSC_H */
+
diff --git a/arch/arm/mach-s3c24xx/regs-mem.h b/arch/arm/mach-s3c24xx/regs-mem.h
new file mode 100644
index 000000000..86b125836
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/regs-mem.h
@@ -0,0 +1,54 @@
+/*
+ * 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 __ARCH_ARM_MACH_S3C24XX_REGS_MEM_H
+#define __ARCH_ARM_MACH_S3C24XX_REGS_MEM_H __FILE__
+
+#define S3C2410_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
+
+#define S3C2410_BWSCON S3C2410_MEMREG(0x00)
+#define S3C2410_BANKCON0 S3C2410_MEMREG(0x04)
+#define S3C2410_BANKCON1 S3C2410_MEMREG(0x08)
+#define S3C2410_BANKCON2 S3C2410_MEMREG(0x0C)
+#define S3C2410_BANKCON3 S3C2410_MEMREG(0x10)
+#define S3C2410_BANKCON4 S3C2410_MEMREG(0x14)
+#define S3C2410_BANKCON5 S3C2410_MEMREG(0x18)
+#define S3C2410_BANKCON6 S3C2410_MEMREG(0x1C)
+#define S3C2410_BANKCON7 S3C2410_MEMREG(0x20)
+#define S3C2410_REFRESH S3C2410_MEMREG(0x24)
+#define S3C2410_BANKSIZE S3C2410_MEMREG(0x28)
+
+#define S3C2410_BWSCON_ST1 (1 << 7)
+#define S3C2410_BWSCON_ST2 (1 << 11)
+#define S3C2410_BWSCON_ST3 (1 << 15)
+#define S3C2410_BWSCON_ST4 (1 << 19)
+#define S3C2410_BWSCON_ST5 (1 << 23)
+
+#define S3C2410_BWSCON_GET(_bwscon, _bank) (((_bwscon) >> ((_bank) * 4)) & 0xf)
+
+#define S3C2410_BWSCON_WS (1 << 2)
+
+#define S3C2410_BANKCON_PMC16 (0x3)
+
+#define S3C2410_BANKCON_Tacp_SHIFT (2)
+#define S3C2410_BANKCON_Tcah_SHIFT (4)
+#define S3C2410_BANKCON_Tcoh_SHIFT (6)
+#define S3C2410_BANKCON_Tacc_SHIFT (8)
+#define S3C2410_BANKCON_Tcos_SHIFT (11)
+#define S3C2410_BANKCON_Tacs_SHIFT (13)
+
+#define S3C2410_BANKCON_SDRAM (0x3 << 15)
+
+#define S3C2410_REFRESH_SELF (1 << 22)
+
+#define S3C2410_BANKSIZE_MASK (0x7 << 0)
+
+#endif /* __ARCH_ARM_MACH_S3C24XX_REGS_MEM_H */
diff --git a/arch/arm/mach-s3c24xx/s3c2410.c b/arch/arm/mach-s3c24xx/s3c2410.c
new file mode 100644
index 000000000..5061d66ca
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/s3c2410.c
@@ -0,0 +1,136 @@
+/* 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/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.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 <mach/gpio-samsung.h>
+#include <asm/irq.h>
+#include <asm/system_misc.h>
+
+#include <plat/cpu-freq.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+#include "common.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 = s3c24xx_gpio_setpull_1up;
+ s3c24xx_gpiocfg_default.get_pull = s3c24xx_gpio_getpull_1up;
+
+ iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
+}
+
+struct bus_type s3c2410_subsys = {
+ .name = "s3c2410-core",
+ .dev_name = "s3c2410-core",
+};
+
+/* Note, we would have liked to name this s3c2410-core, but we cannot
+ * register two subsystems with the same name.
+ */
+struct bus_type s3c2410a_subsys = {
+ .name = "s3c2410a-core",
+ .dev_name = "s3c2410a-core",
+};
+
+static struct device s3c2410_dev = {
+ .bus = &s3c2410_subsys,
+};
+
+/* need to register the subsystem 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 subsys_system_register(&s3c2410_subsys, NULL);
+}
+
+core_initcall(s3c2410_core_init);
+
+static int __init s3c2410a_core_init(void)
+{
+ return subsys_system_register(&s3c2410a_subsys, NULL);
+}
+
+core_initcall(s3c2410a_core_init);
+
+int __init s3c2410_init(void)
+{
+ printk("S3C2410: Initialising architecture\n");
+
+#ifdef CONFIG_PM_SLEEP
+ register_syscore_ops(&s3c2410_pm_syscore_ops);
+ register_syscore_ops(&s3c24xx_irq_syscore_ops);
+#endif
+
+ return device_register(&s3c2410_dev);
+}
+
+int __init s3c2410a_init(void)
+{
+ s3c2410_dev.bus = &s3c2410a_subsys;
+ return s3c2410_init();
+}
diff --git a/arch/arm/mach-s3c24xx/s3c2412-power.h b/arch/arm/mach-s3c24xx/s3c2412-power.h
new file mode 100644
index 000000000..1b02c5ddb
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/s3c2412-power.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_S3C24XX_S3C2412_POWER_H
+#define __ARCH_ARM_MACH_S3C24XX_S3C2412_POWER_H __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 /* __ARCH_ARM_MACH_S3C24XX_S3C2412_POWER_H */
diff --git a/arch/arm/mach-s3c24xx/s3c2412.c b/arch/arm/mach-s3c24xx/s3c2412.c
new file mode 100644
index 000000000..64a13605c
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/s3c2412.c
@@ -0,0 +1,181 @@
+/*
+ * 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/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/reboot.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 <asm/system_misc.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq.h>
+#include <plat/devs.h>
+#include <plat/nand-core.h>
+#include <plat/pm.h>
+#include <plat/regs-spi.h>
+
+#include "common.h"
+#include "regs-dsc.h"
+#include "s3c2412-power.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();
+}
+
+/* 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 */
+
+ arm_pm_idle = s3c2412_idle;
+
+ /* register our io-tables */
+
+ iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
+}
+
+/* need to register the subsystem 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 bus_type s3c2412_subsys = {
+ .name = "s3c2412-core",
+ .dev_name = "s3c2412-core",
+};
+
+static int __init s3c2412_core_init(void)
+{
+ return subsys_system_register(&s3c2412_subsys, NULL);
+}
+
+core_initcall(s3c2412_core_init);
+
+static struct device s3c2412_dev = {
+ .bus = &s3c2412_subsys,
+};
+
+int __init s3c2412_init(void)
+{
+ printk("S3C2412: Initialising architecture\n");
+
+#ifdef CONFIG_PM_SLEEP
+ register_syscore_ops(&s3c2412_pm_syscore_ops);
+ register_syscore_ops(&s3c24xx_irq_syscore_ops);
+#endif
+
+ return device_register(&s3c2412_dev);
+}
diff --git a/arch/arm/mach-s3c24xx/s3c2416.c b/arch/arm/mach-s3c24xx/s3c2416.c
new file mode 100644
index 000000000..3f8ca2a3e
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/s3c2416.c
@@ -0,0 +1,147 @@
+/* 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/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/reboot.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio-samsung.h>
+#include <asm/proc-fns.h>
+#include <asm/irq.h>
+#include <asm/system_misc.h>
+
+#include <mach/regs-s3c2443-clock.h>
+#include <mach/rtc-core.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.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>
+#include <plat/adc-core.h>
+#include <plat/spi-core.h>
+
+#include "common.h"
+
+static struct map_desc s3c2416_iodesc[] __initdata = {
+ IODESC_ENT(WATCHDOG),
+ IODESC_ENT(CLKPWR),
+ IODESC_ENT(TIMER),
+};
+
+struct bus_type s3c2416_subsys = {
+ .name = "s3c2416-core",
+ .dev_name = "s3c2416-core",
+};
+
+static struct device s3c2416_dev = {
+ .bus = &s3c2416_subsys,
+};
+
+int __init s3c2416_init(void)
+{
+ printk(KERN_INFO "S3C2416: Initializing architecture\n");
+
+ /* 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");
+
+ s3c_adc_setname("s3c2416-adc");
+ s3c_rtc_setname("s3c2416-rtc");
+
+#ifdef CONFIG_PM_SLEEP
+ register_syscore_ops(&s3c2416_pm_syscore_ops);
+ register_syscore_ops(&s3c24xx_irq_syscore_ops);
+ register_syscore_ops(&s3c2416_irq_syscore_ops);
+#endif
+
+ return device_register(&s3c2416_dev);
+}
+
+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 = samsung_gpio_setpull_updown;
+ s3c24xx_gpiocfg_default.get_pull = samsung_gpio_getpull_updown;
+
+ /* initialize device information early */
+ s3c2416_default_sdhci0();
+ s3c2416_default_sdhci1();
+ s3c64xx_spi_setname("s3c2443-spi");
+
+ iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc));
+}
+
+/* need to register the subsystem 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 subsys_system_register(&s3c2416_subsys, NULL);
+}
+
+core_initcall(s3c2416_core_init);
diff --git a/arch/arm/mach-s3c24xx/s3c2440.c b/arch/arm/mach-s3c24xx/s3c2440.c
new file mode 100644
index 000000000..eb733555f
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/s3c2440.c
@@ -0,0 +1,77 @@
+/* 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/device.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 <mach/gpio-samsung.h>
+#include <asm/irq.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+#include "common.h"
+
+static struct device s3c2440_dev = {
+ .bus = &s3c2440_subsys,
+};
+
+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 */
+
+#ifdef CONFIG_PM_SLEEP
+ register_syscore_ops(&s3c2410_pm_syscore_ops);
+ register_syscore_ops(&s3c24xx_irq_syscore_ops);
+ register_syscore_ops(&s3c244x_pm_syscore_ops);
+#endif
+
+ /* register our system device for everything else */
+
+ return device_register(&s3c2440_dev);
+}
+
+void __init s3c2440_map_io(void)
+{
+ s3c244x_map_io();
+
+ s3c24xx_gpiocfg_default.set_pull = s3c24xx_gpio_setpull_1up;
+ s3c24xx_gpiocfg_default.get_pull = s3c24xx_gpio_getpull_1up;
+}
diff --git a/arch/arm/mach-s3c24xx/s3c2442.c b/arch/arm/mach-s3c24xx/s3c2442.c
new file mode 100644
index 000000000..893998ede
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/s3c2442.c
@@ -0,0 +1,78 @@
+/* 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/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 <mach/gpio-samsung.h>
+#include <linux/atomic.h>
+#include <asm/irq.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+#include "common.h"
+
+static struct device s3c2442_dev = {
+ .bus = &s3c2442_subsys,
+};
+
+int __init s3c2442_init(void)
+{
+ printk("S3C2442: Initialising architecture\n");
+
+#ifdef CONFIG_PM_SLEEP
+ register_syscore_ops(&s3c2410_pm_syscore_ops);
+ register_syscore_ops(&s3c24xx_irq_syscore_ops);
+ register_syscore_ops(&s3c244x_pm_syscore_ops);
+#endif
+
+ return device_register(&s3c2442_dev);
+}
+
+void __init s3c2442_map_io(void)
+{
+ s3c244x_map_io();
+
+ s3c24xx_gpiocfg_default.set_pull = s3c24xx_gpio_setpull_1down;
+ s3c24xx_gpiocfg_default.get_pull = s3c24xx_gpio_getpull_1down;
+}
diff --git a/arch/arm/mach-s3c24xx/s3c2443.c b/arch/arm/mach-s3c24xx/s3c2443.c
new file mode 100644
index 000000000..87b6b89d8
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/s3c2443.c
@@ -0,0 +1,114 @@
+/* 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/device.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/reboot.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio-samsung.h>
+#include <asm/irq.h>
+#include <asm/system_misc.h>
+
+#include <mach/regs-s3c2443-clock.h>
+#include <mach/rtc-core.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/fb-core.h>
+#include <plat/nand-core.h>
+#include <plat/adc-core.h>
+#include <plat/spi-core.h>
+
+static struct map_desc s3c2443_iodesc[] __initdata = {
+ IODESC_ENT(WATCHDOG),
+ IODESC_ENT(CLKPWR),
+ IODESC_ENT(TIMER),
+};
+
+struct bus_type s3c2443_subsys = {
+ .name = "s3c2443-core",
+ .dev_name = "s3c2443-core",
+};
+
+static struct device s3c2443_dev = {
+ .bus = &s3c2443_subsys,
+};
+
+int __init s3c2443_init(void)
+{
+ printk("S3C2443: Initialising architecture\n");
+
+ s3c_nand_setname("s3c2412-nand");
+ s3c_fb_setname("s3c2443-fb");
+
+ s3c_adc_setname("s3c2443-adc");
+ s3c_rtc_setname("s3c2443-rtc");
+
+ /* change WDT IRQ number */
+ s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
+ s3c_device_wdt.resource[1].end = IRQ_S3C2443_WDT;
+
+ return device_register(&s3c2443_dev);
+}
+
+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 = s3c2443_gpio_setpull;
+ s3c24xx_gpiocfg_default.get_pull = s3c2443_gpio_getpull;
+
+ /* initialize device information early */
+ s3c64xx_spi_setname("s3c2443-spi");
+
+ iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc));
+}
+
+/* need to register the subsystem 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 subsys_system_register(&s3c2443_subsys, NULL);
+}
+
+core_initcall(s3c2443_core_init);
diff --git a/arch/arm/mach-s3c24xx/s3c244x.c b/arch/arm/mach-s3c24xx/s3c244x.c
new file mode 100644
index 000000000..b14119585
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/s3c244x.c
@@ -0,0 +1,135 @@
+/* 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/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/system_misc.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 <mach/regs-gpio.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/nand-core.h>
+
+#include "common.h"
+#include "regs-dsc.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";
+ s3c2410_device_dclk.name = "s3c2440-dclk";
+}
+
+/* Since the S3C2442 and S3C2440 share items, put both subsystems here */
+
+struct bus_type s3c2440_subsys = {
+ .name = "s3c2440-core",
+ .dev_name = "s3c2440-core",
+};
+
+struct bus_type s3c2442_subsys = {
+ .name = "s3c2442-core",
+ .dev_name = "s3c2442-core",
+};
+
+/* need to register the subsystem 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 subsys_system_register(&s3c2440_subsys, NULL);
+}
+
+core_initcall(s3c2440_core_init);
+
+static int __init s3c2442_core_init(void)
+{
+ return subsys_system_register(&s3c2442_subsys, NULL);
+}
+
+core_initcall(s3c2442_core_init);
+
+
+#ifdef CONFIG_PM_SLEEP
+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));
+}
+
+struct syscore_ops s3c244x_pm_syscore_ops = {
+ .suspend = s3c244x_suspend,
+ .resume = s3c244x_resume,
+};
+#endif
diff --git a/arch/arm/mach-s3c24xx/setup-i2c.c b/arch/arm/mach-s3c24xx/setup-i2c.c
new file mode 100644
index 000000000..1852696ca
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/setup-i2c.c
@@ -0,0 +1,28 @@
+/* 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 <linux/platform_data/i2c-s3c2410.h>
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.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/mach-s3c24xx/setup-sdhci-gpio.c b/arch/arm/mach-s3c24xx/setup-sdhci-gpio.c
new file mode 100644
index 000000000..c99b0f664
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/setup-sdhci-gpio.c
@@ -0,0 +1,35 @@
+/* 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 <mach/gpio-samsung.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-s3c24xx/setup-spi.c b/arch/arm/mach-s3c24xx/setup-spi.c
new file mode 100644
index 000000000..3d47e023c
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/setup-spi.c
@@ -0,0 +1,31 @@
+/*
+ * HS-SPI device setup for S3C2443/S3C2416
+ *
+ * Copyright (C) 2011 Samsung Electronics 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/platform_device.h>
+
+#include <plat/gpio-cfg.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+#ifdef CONFIG_S3C64XX_DEV_SPI0
+int s3c64xx_spi0_cfg_gpio(void)
+{
+ /* enable hsspi bit in misccr */
+ s3c2410_modify_misccr(S3C2416_MISCCR_HSSPI_EN2, 1);
+
+ s3c_gpio_cfgall_range(S3C2410_GPE(11), 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-s3c24xx/setup-ts.c b/arch/arm/mach-s3c24xx/setup-ts.c
new file mode 100644
index 000000000..46466d202
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/setup-ts.c
@@ -0,0 +1,32 @@
+/* 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 <plat/gpio-cfg.h>
+#include <mach/hardware.h>
+#include <mach/gpio-samsung.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)
+{
+ s3c_gpio_cfgpin_range(S3C2410_GPG(12), 4, S3C_GPIO_SFN(3));
+}
diff --git a/arch/arm/mach-s3c24xx/simtec-audio.c b/arch/arm/mach-s3c24xx/simtec-audio.c
new file mode 100644
index 000000000..67cb5120d
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/simtec-audio.c
@@ -0,0 +1,76 @@
+/* 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/hardware.h>
+#include <mach/regs-gpio.h>
+
+#include <linux/platform_data/asoc-s3c24xx_simtec.h>
+#include <plat/devs.h>
+
+#include "bast.h"
+#include "simtec.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/mach-s3c24xx/simtec-nor.c b/arch/arm/mach-s3c24xx/simtec-nor.c
new file mode 100644
index 000000000..8884bffa6
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/simtec-nor.c
@@ -0,0 +1,79 @@
+/* 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 "bast.h"
+#include "simtec.h"
+
+static void simtec_nor_vpp(struct platform_device *pdev, int vpp)
+{
+ unsigned int val;
+
+ 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);
+}
+
+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] = DEFINE_RES_MEM(S3C2410_CS1 + 0x4000000, SZ_8M),
+};
+
+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-s3c24xx/simtec-pm.c b/arch/arm/mach-s3c24xx/simtec-pm.c
new file mode 100644
index 000000000..38a2f1fde
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/simtec-pm.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/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 <asm/mach-types.h>
+
+#include <plat/pm.h>
+
+#include "regs-mem.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 Management" 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/mach-s3c24xx/simtec-usb.c b/arch/arm/mach-s3c24xx/simtec-usb.c
new file mode 100644
index 000000000..b70aa66ef
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/simtec-usb.c
@@ -0,0 +1,130 @@
+/* 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/hardware.h>
+#include <mach/gpio-samsung.h>
+#include <asm/irq.h>
+
+#include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <plat/devs.h>
+
+#include "bast.h"
+#include "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(BAST_IRQ_USBOC, usb_simtec_ocirq,
+ 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(BAST_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 __init 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-s3c24xx/simtec.h b/arch/arm/mach-s3c24xx/simtec.h
new file mode 100644
index 000000000..ae8f4f9ad
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/simtec.h
@@ -0,0 +1,21 @@
+/* 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 common 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.
+*/
+
+struct s3c24xx_audio_simtec_pdata;
+
+extern void nor_simtec_init(void);
+
+extern int usb_simtec_init(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/mach-s3c24xx/sleep-s3c2410.S b/arch/arm/mach-s3c24xx/sleep-s3c2410.S
new file mode 100644
index 000000000..875ba8911
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/sleep-s3c2410.S
@@ -0,0 +1,69 @@
+/* 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 <linux/serial_s3c.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+
+#include "regs-mem.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
+ ret lr
diff --git a/arch/arm/mach-s3c24xx/sleep-s3c2412.S b/arch/arm/mach-s3c24xx/sleep-s3c2412.S
new file mode 100644
index 000000000..6bf5b4d87
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/sleep-s3c2412.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
+
+ ret lr
diff --git a/arch/arm/mach-s3c24xx/sleep.S b/arch/arm/mach-s3c24xx/sleep.S
new file mode 100644
index 000000000..d833d616b
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/sleep.S
@@ -0,0 +1,83 @@
+/* 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 <linux/serial_s3c.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.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
+
+ /* 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/mach-s3c24xx/vr1000.h b/arch/arm/mach-s3c24xx/vr1000.h
new file mode 100644
index 000000000..7fcd2c2f1
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/vr1000.h
@@ -0,0 +1,118 @@
+
+/* arch/arm/mach-s3c2410/include/mach/vr1000-cpld.h
+ *
+ * Copyright (c) 2003 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * VR1000 - CPLD control constants
+ * Machine VR1000 - IRQ Number definitions
+ * 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.
+*/
+
+#ifndef __MACH_S3C24XX_VR1000_H
+#define __MACH_S3C24XX_VR1000_H __FILE__
+
+#define VR1000_CPLD_CTRL2_RAMWEN (0x04) /* SRAM Write Enable */
+
+/* irq numbers to onboard peripherals */
+
+#define VR1000_IRQ_USBOC IRQ_EINT19
+#define VR1000_IRQ_IDE0 IRQ_EINT16
+#define VR1000_IRQ_IDE1 IRQ_EINT17
+#define VR1000_IRQ_SERIAL IRQ_EINT12
+#define VR1000_IRQ_DM9000A IRQ_EINT10
+#define VR1000_IRQ_DM9000N IRQ_EINT9
+#define VR1000_IRQ_SMALERT IRQ_EINT8
+
+/* map */
+
+#define VR1000_IOADDR(x) (S3C2410_ADDR((x) + 0x01300000))
+
+/* 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
+ * whether 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 /* __MACH_S3C24XX_VR1000_H */
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
new file mode 100644
index 000000000..eff95e950
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -0,0 +1,316 @@
+# Copyright 2008 Openmoko, Inc.
+# Simtec Electronics, Ben Dooks <ben@simtec.co.uk>
+#
+# Licensed under GPLv2
+
+if ARCH_S3C64XX
+
+# 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_PL080
+ def_bool DMADEVICES
+ select ARM_AMBA
+ select AMBA_PL08X
+
+config S3C64XX_SETUP_SDHCI
+ bool
+ select S3C64XX_SETUP_SDHCI_GPIO
+ 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
+
+config S3C64XX_SETUP_SPI
+ bool
+ help
+ Common setup code for SPI GPIO configurations
+
+config S3C64XX_SETUP_USB_PHY
+ bool
+ help
+ Common setup code for USB PHY controller
+
+# S36400 Macchine support
+
+config MACH_SMDK6400
+ bool "SMDK6400"
+ select CPU_S3C6400
+ select S3C64XX_SETUP_SDHCI
+ select S3C_DEV_HSMMC1
+ help
+ Machine support for the Samsung SMDK6400
+
+# S3C6410 machine support
+
+config MACH_ANW6410
+ bool "A&W6410"
+ select CPU_S3C6410
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C_DEV_FB
+ help
+ Machine support for the A&W6410
+
+config MACH_MINI6410
+ bool "MINI6410"
+ select CPU_S3C6410
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C64XX_SETUP_SDHCI
+ select S3C_DEV_FB
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_TS
+ help
+ Machine support for the FriendlyARM MINI6410
+
+config MACH_REAL6410
+ bool "REAL6410"
+ select CPU_S3C6410
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C64XX_SETUP_SDHCI
+ select S3C_DEV_FB
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_TS
+ help
+ Machine support for the CoreWind REAL6410
+
+config MACH_SMDK6410
+ bool "SMDK6410"
+ select CPU_S3C6410
+ select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C64XX_SETUP_I2C1
+ select S3C64XX_SETUP_IDE
+ select S3C64XX_SETUP_KEYPAD
+ select S3C64XX_SETUP_SDHCI
+ select S3C64XX_SETUP_USB_PHY
+ select S3C_DEV_FB
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_I2C1
+ select S3C_DEV_RTC
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_USB_HSOTG
+ select S3C_DEV_WDT
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_BACKLIGHT
+ select SAMSUNG_DEV_IDE
+ select SAMSUNG_DEV_KEYPAD
+ select SAMSUNG_DEV_PWM
+ select SAMSUNG_DEV_TS
+ 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
+ depends on I2C=y
+ select MFD_WM8350_I2C
+ select REGULATOR
+ select REGULATOR_WM8350
+ 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 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
+ depends on I2C=y
+ select MFD_WM831X
+ select MFD_WM831X_I2C
+ select REGULATOR
+ select REGULATOR_WM831X
+ 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 resulting kernel can be used
+ with or without the 1192-EV1 fitted.
+
+config MACH_NCP
+ bool "NCP"
+ select CPU_S3C6410
+ select S3C64XX_SETUP_I2C1
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_I2C1
+ help
+ Machine support for the Samsung NCP
+
+config MACH_HMT
+ bool "Airgoo HMT"
+ select CPU_S3C6410
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C_DEV_FB
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ select SAMSUNG_DEV_PWM
+ help
+ Machine support for the Airgoo HMT
+
+config MACH_SMARTQ
+ bool
+ select CPU_S3C6410
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C64XX_SETUP_SDHCI
+ select S3C64XX_SETUP_USB_PHY
+ select S3C_DEV_FB
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HWMON
+ select S3C_DEV_RTC
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_USB_HSOTG
+ 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
+
+config MACH_WLF_CRAGG_6410
+ bool "Wolfson Cragganmore 6410"
+ depends on I2C=y
+ select CPU_S3C6410
+ select LEDS_GPIO_REGISTER
+ select S3C64XX_DEV_SPI0
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C64XX_SETUP_I2C1
+ select S3C64XX_SETUP_IDE
+ select S3C64XX_SETUP_KEYPAD
+ select S3C64XX_SETUP_SDHCI
+ select S3C64XX_SETUP_SPI
+ select S3C64XX_SETUP_USB_PHY
+ 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_USB_HOST
+ select S3C_DEV_USB_HSOTG
+ select S3C_DEV_WDT
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_KEYPAD
+ select SAMSUNG_DEV_PWM
+ help
+ Machine support for the Wolfson Cragganmore S3C6410 variant.
+
+config MACH_S3C64XX_DT
+ bool "Samsung S3C6400/S3C6410 machine using Device Tree"
+ select CLKSRC_OF
+ select CPU_S3C6400
+ select CPU_S3C6410
+ select PINCTRL
+ select PINCTRL_S3C64XX
+ select USE_OF
+ help
+ Machine support for Samsung S3C6400/S3C6410 machines with Device Tree
+ enabled.
+ Select this if a fdt blob is available for your S3C64XX SoC based
+ board.
+ Note: This is under development and not all peripherals can be
+ supported with this machine file.
+
+endif
diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile
new file mode 100644
index 000000000..17f4b07ec
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/Makefile
@@ -0,0 +1,56 @@
+# arch/arm/mach-s3c64xx/Makefile
+#
+# Copyright 2008 Openmoko, Inc.
+# Copyright 2008 Simtec Electronics
+#
+# Licensed under GPLv2
+
+# Core
+
+obj-y += common.o
+
+# Core support
+
+obj-$(CONFIG_CPU_S3C6400) += s3c6400.o
+obj-$(CONFIG_CPU_S3C6410) += s3c6410.o
+
+# PM
+
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM_SLEEP) += irq-pm.o sleep.o
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
+
+# DMA support
+
+obj-$(CONFIG_S3C64XX_PL080) += pl080.o
+
+# Device support
+
+obj-y += dev-uart.o
+obj-y += dev-audio.o
+
+# Device setup
+
+obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
+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_GPIO) += setup-sdhci-gpio.o
+obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi.o
+obj-$(CONFIG_S3C64XX_SETUP_USB_PHY) += setup-usb-phy.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o
+obj-$(CONFIG_MACH_HMT) += mach-hmt.o
+obj-$(CONFIG_MACH_MINI6410) += mach-mini6410.o
+obj-$(CONFIG_MACH_NCP) += mach-ncp.o
+obj-$(CONFIG_MACH_REAL6410) += mach-real6410.o
+obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o
+obj-$(CONFIG_MACH_SMARTQ5) += mach-smartq5.o
+obj-$(CONFIG_MACH_SMARTQ7) += mach-smartq7.o
+obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o
+obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o
+obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o mach-crag6410-module.o
+obj-$(CONFIG_MACH_S3C64XX_DT) += mach-s3c64xx-dt.o
diff --git a/arch/arm/mach-s3c64xx/Makefile.boot b/arch/arm/mach-s3c64xx/Makefile.boot
new file mode 100644
index 000000000..c642333af
--- /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/common.c b/arch/arm/mach-s3c64xx/common.c
new file mode 100644
index 000000000..16547f264
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/common.c
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 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/
+ *
+ * Common Codes for S3C64XX 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.
+ */
+
+/*
+ * NOTE: Code in this file is not used when booting with Device Tree support.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/clk-provider.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/irqchip/arm-vic.h>
+#include <clocksource/samsung_pwm.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/system_misc.h>
+
+#include <mach/map.h>
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
+#include <plat/gpio-cfg.h>
+#include <plat/irq-uart.h>
+#include <plat/pwm-core.h>
+#include <plat/regs-irqtype.h>
+#include <plat/watchdog-reset.h>
+
+#include "common.h"
+
+/* External clock frequency */
+static unsigned long xtal_f = 12000000, xusbxti_f = 48000000;
+
+void __init s3c64xx_set_xtal_freq(unsigned long freq)
+{
+ xtal_f = freq;
+}
+
+void __init s3c64xx_set_xusbxti_freq(unsigned long freq)
+{
+ xusbxti_f = freq;
+}
+
+/* uart registration process */
+
+static void __init s3c64xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ s3c24xx_init_uartdevs("s3c6400-uart", s3c64xx_uart_resources, cfg, no);
+}
+
+/* table of supported CPUs */
+
+static const char name_s3c6400[] = "S3C6400";
+static const char name_s3c6410[] = "S3C6410";
+
+static struct cpu_table cpu_ids[] __initdata = {
+ {
+ .idcode = S3C6400_CPU_ID,
+ .idmask = S3C64XX_CPU_MASK,
+ .map_io = s3c6400_map_io,
+ .init_uarts = s3c64xx_init_uarts,
+ .init = s3c6400_init,
+ .name = name_s3c6400,
+ }, {
+ .idcode = S3C6410_CPU_ID,
+ .idmask = S3C64XX_CPU_MASK,
+ .map_io = s3c6410_map_io,
+ .init_uarts = s3c64xx_init_uarts,
+ .init = s3c6410_init,
+ .name = name_s3c6410,
+ },
+};
+
+/* minimal IO mapping */
+
+/* see notes on uart map in arch/arm/mach-s3c64xx/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,
+ },
+};
+
+static struct bus_type s3c64xx_subsys = {
+ .name = "s3c64xx-core",
+ .dev_name = "s3c64xx-core",
+};
+
+static struct device s3c64xx_dev = {
+ .bus = &s3c64xx_subsys,
+};
+
+static struct samsung_pwm_variant s3c64xx_pwm_variant = {
+ .bits = 32,
+ .div_base = 0,
+ .has_tint_cstat = true,
+ .tclk_mask = (1 << 7) | (1 << 6) | (1 << 5),
+};
+
+void __init samsung_set_timer_source(unsigned int event, unsigned int source)
+{
+ s3c64xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+ s3c64xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
+}
+
+void __init samsung_timer_init(void)
+{
+ unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
+ IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
+ IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
+ };
+
+ samsung_pwm_clocksource_init(S3C_VA_TIMER,
+ timer_irqs, &s3c64xx_pwm_variant);
+}
+
+/* read cpu identification code */
+
+void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
+{
+ /* initialise the io descriptors we need for initialisation */
+ iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
+ iotable_init(mach_desc, size);
+
+ /* detect cpu id */
+ s3c64xx_init_cpu();
+
+ s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+ samsung_pwm_set_platdata(&s3c64xx_pwm_variant);
+}
+
+static __init int s3c64xx_dev_init(void)
+{
+ /* Not applicable when using DT. */
+ if (of_have_populated_dt())
+ return 0;
+
+ subsys_system_register(&s3c64xx_subsys, NULL);
+ return device_register(&s3c64xx_dev);
+}
+core_initcall(s3c64xx_dev_init);
+
+/*
+ * setup the sources the vic should advertise resume
+ * for, even though it is not doing the wake
+ * (set_irq_wake needs to be valid)
+ */
+#define IRQ_VIC0_RESUME (1 << (IRQ_RTC_TIC - IRQ_VIC0_BASE))
+#define IRQ_VIC1_RESUME (1 << (IRQ_RTC_ALARM - IRQ_VIC1_BASE) | \
+ 1 << (IRQ_PENDN - IRQ_VIC1_BASE) | \
+ 1 << (IRQ_HSMMC0 - IRQ_VIC1_BASE) | \
+ 1 << (IRQ_HSMMC1 - IRQ_VIC1_BASE) | \
+ 1 << (IRQ_HSMMC2 - IRQ_VIC1_BASE))
+
+void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
+{
+ /*
+ * FIXME: there is no better place to put this at the moment
+ * (s3c64xx_clk_init needs ioremap and must happen before init_time
+ * samsung_wdt_reset_init needs clocks)
+ */
+ s3c64xx_clk_init(NULL, xtal_f, xusbxti_f, soc_is_s3c6400(), S3C_VA_SYS);
+ samsung_wdt_reset_init(S3C_VA_WATCHDOG);
+
+ printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
+
+ /* initialise the pair of VICs */
+ vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, IRQ_VIC0_RESUME);
+ vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, IRQ_VIC1_RESUME);
+}
+
+#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;
+
+ /* On DT-enabled systems EINTs are handled by pinctrl-s3c64xx driver. */
+ if (of_have_populated_dt())
+ return -ENODEV;
+
+ 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);
+
+void s3c64xx_restart(enum reboot_mode mode, const char *cmd)
+{
+ if (mode != REBOOT_SOFT)
+ samsung_wdt_reset();
+
+ /* if all else fails, or mode was for soft, jump to 0 */
+ soft_restart(0);
+}
diff --git a/arch/arm/mach-s3c64xx/common.h b/arch/arm/mach-s3c64xx/common.h
new file mode 100644
index 000000000..9eb864412
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/common.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 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/
+ *
+ * Common Header for S3C64XX 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_S3C64XX_COMMON_H
+#define __ARCH_ARM_MACH_S3C64XX_COMMON_H
+
+#include <linux/reboot.h>
+
+void s3c64xx_init_irq(u32 vic0, u32 vic1);
+void s3c64xx_init_io(struct map_desc *mach_desc, int size);
+
+void s3c64xx_restart(enum reboot_mode mode, const char *cmd);
+
+void s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
+ unsigned long xusbxti_f, bool is_s3c6400, void __iomem *reg_base);
+void s3c64xx_set_xtal_freq(unsigned long freq);
+void s3c64xx_set_xusbxti_freq(unsigned long freq);
+
+#ifdef CONFIG_CPU_S3C6400
+
+extern int s3c6400_init(void);
+extern void s3c6400_init_irq(void);
+extern void s3c6400_map_io(void);
+
+#else
+#define s3c6400_map_io NULL
+#define s3c6400_init NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C6410
+
+extern int s3c6410_init(void);
+extern void s3c6410_init_irq(void);
+extern void s3c6410_map_io(void);
+
+#else
+#define s3c6410_map_io NULL
+#define s3c6410_init NULL
+#endif
+
+#ifdef CONFIG_S3C64XX_PL080
+extern struct pl08x_platform_data s3c64xx_dma0_plat_data;
+extern struct pl08x_platform_data s3c64xx_dma1_plat_data;
+#endif
+
+#endif /* __ARCH_ARM_MACH_S3C64XX_COMMON_H */
diff --git a/arch/arm/mach-s3c64xx/cpuidle.c b/arch/arm/mach-s3c64xx/cpuidle.c
new file mode 100644
index 000000000..93aa8cb70
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/cpuidle.c
@@ -0,0 +1,62 @@
+/* linux/arch/arm/mach-s3c64xx/cpuidle.c
+ *
+ * Copyright (c) 2011 Wolfson Microelectronics, plc
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/cpuidle.h>
+#include <linux/io.h>
+#include <linux/export.h>
+#include <linux/time.h>
+
+#include <asm/cpuidle.h>
+
+#include <mach/map.h>
+
+#include "regs-sys.h"
+#include "regs-syscon-power.h"
+
+static int s3c64xx_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ unsigned long tmp;
+
+ /* Setup PWRCFG to enter idle mode */
+ tmp = __raw_readl(S3C64XX_PWR_CFG);
+ tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
+ tmp |= S3C64XX_PWRCFG_CFG_WFI_IDLE;
+ __raw_writel(tmp, S3C64XX_PWR_CFG);
+
+ cpu_do_idle();
+
+ return index;
+}
+
+static struct cpuidle_driver s3c64xx_cpuidle_driver = {
+ .name = "s3c64xx_cpuidle",
+ .owner = THIS_MODULE,
+ .states = {
+ {
+ .enter = s3c64xx_enter_idle,
+ .exit_latency = 1,
+ .target_residency = 1,
+ .name = "IDLE",
+ .desc = "System active, ARM gated",
+ },
+ },
+ .state_count = 1,
+};
+
+static int __init s3c64xx_init_cpuidle(void)
+{
+ return cpuidle_register(&s3c64xx_cpuidle_driver, NULL);
+}
+device_initcall(s3c64xx_init_cpuidle);
diff --git a/arch/arm/mach-s3c64xx/crag6410.h b/arch/arm/mach-s3c64xx/crag6410.h
new file mode 100644
index 000000000..dcbe17f5e
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/crag6410.h
@@ -0,0 +1,25 @@
+/* Cragganmore 6410 shared definitions
+ *
+ * Copyright 2011 Wolfson Microelectronics plc
+ * 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.
+ */
+
+#ifndef MACH_CRAG6410_H
+#define MACH_CRAG6410_H
+
+#include <mach/gpio-samsung.h>
+
+#define GLENFARCLAS_PMIC_IRQ_BASE IRQ_BOARD_START
+#define BANFF_PMIC_IRQ_BASE (IRQ_BOARD_START + 64)
+
+#define PCA935X_GPIO_BASE GPIO_BOARD_START
+#define CODEC_GPIO_BASE (GPIO_BOARD_START + 8)
+#define GLENFARCLAS_PMIC_GPIO_BASE (GPIO_BOARD_START + 32)
+#define BANFF_PMIC_GPIO_BASE (GPIO_BOARD_START + 64)
+#define MMGPIO_GPIO_BASE (GPIO_BOARD_START + 96)
+
+#endif
diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c
new file mode 100644
index 000000000..ff780a8d8
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/dev-audio.c
@@ -0,0 +1,228 @@
+/* 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 <linux/export.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <mach/dma.h>
+
+#include <plat/devs.h>
+#include <linux/platform_data/asoc-s3c.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-samsung.h>
+
+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] = DEFINE_RES_MEM(S3C64XX_PA_IIS0, SZ_256),
+ [1] = DEFINE_RES_DMA(DMACH_I2S0_OUT),
+ [2] = DEFINE_RES_DMA(DMACH_I2S0_IN),
+};
+
+static struct s3c_audio_pdata i2sv3_pdata = {
+ .cfg_gpio = s3c64xx_i2s_cfg_gpio,
+};
+
+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] = DEFINE_RES_MEM(S3C64XX_PA_IIS1, SZ_256),
+ [1] = DEFINE_RES_DMA(DMACH_I2S1_OUT),
+ [2] = DEFINE_RES_DMA(DMACH_I2S1_IN),
+};
+
+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] = DEFINE_RES_MEM(S3C64XX_PA_IISV4, SZ_256),
+ [1] = DEFINE_RES_DMA(DMACH_HSI_I2SV40_TX),
+ [2] = DEFINE_RES_DMA(DMACH_HSI_I2SV40_RX),
+};
+
+static struct s3c_audio_pdata i2sv4_pdata = {
+ .cfg_gpio = s3c64xx_i2s_cfg_gpio,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_PRI_6CHAN,
+ },
+ },
+};
+
+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] = DEFINE_RES_MEM(S3C64XX_PA_PCM0, SZ_256),
+ [1] = DEFINE_RES_DMA(DMACH_PCM0_TX),
+ [2] = DEFINE_RES_DMA(DMACH_PCM0_RX),
+};
+
+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] = DEFINE_RES_MEM(S3C64XX_PA_PCM1, SZ_256),
+ [1] = DEFINE_RES_DMA(DMACH_PCM1_TX),
+ [2] = DEFINE_RES_DMA(DMACH_PCM1_RX),
+};
+
+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] = DEFINE_RES_MEM(S3C64XX_PA_AC97, SZ_256),
+ [1] = DEFINE_RES_DMA(DMACH_AC97_PCMOUT),
+ [2] = DEFINE_RES_DMA(DMACH_AC97_PCMIN),
+ [3] = DEFINE_RES_DMA(DMACH_AC97_MICIN),
+ [4] = DEFINE_RES_IRQ(IRQ_AC97),
+};
+
+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-uart.c b/arch/arm/mach-s3c64xx/dev-uart.c
new file mode 100644
index 000000000..46e18d77e
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/dev-uart.c
@@ -0,0 +1,71 @@
+/* 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] = DEFINE_RES_MEM(S3C_PA_UART0, SZ_256),
+ [1] = DEFINE_RES_IRQ(IRQ_UART0),
+};
+
+static struct resource s3c64xx_uart1_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_UART1, SZ_256),
+ [1] = DEFINE_RES_IRQ(IRQ_UART1),
+};
+
+static struct resource s3c6xx_uart2_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_UART2, SZ_256),
+ [1] = DEFINE_RES_IRQ(IRQ_UART2),
+};
+
+static struct resource s3c64xx_uart3_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_UART3, SZ_256),
+ [1] = DEFINE_RES_IRQ(IRQ_UART3),
+};
+
+
+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/include/mach/debug-macro.S b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S
new file mode 100644
index 000000000..c9b95325b
--- /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 <linux/serial_s3c.h>
+#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, tmp
+ 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 <debug/samsung.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 000000000..096e14073
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/dma.h
@@ -0,0 +1,56 @@
+/* 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 S3C64XX_DMA_CHAN(name) ((unsigned long)(name))
+
+/* DMA0/SDMA0 */
+#define DMACH_UART0 S3C64XX_DMA_CHAN("uart0_tx")
+#define DMACH_UART0_SRC2 S3C64XX_DMA_CHAN("uart0_rx")
+#define DMACH_UART1 S3C64XX_DMA_CHAN("uart1_tx")
+#define DMACH_UART1_SRC2 S3C64XX_DMA_CHAN("uart1_rx")
+#define DMACH_UART2 S3C64XX_DMA_CHAN("uart2_tx")
+#define DMACH_UART2_SRC2 S3C64XX_DMA_CHAN("uart2_rx")
+#define DMACH_UART3 S3C64XX_DMA_CHAN("uart3_tx")
+#define DMACH_UART3_SRC2 S3C64XX_DMA_CHAN("uart3_rx")
+#define DMACH_PCM0_TX S3C64XX_DMA_CHAN("pcm0_tx")
+#define DMACH_PCM0_RX S3C64XX_DMA_CHAN("pcm0_rx")
+#define DMACH_I2S0_OUT S3C64XX_DMA_CHAN("i2s0_tx")
+#define DMACH_I2S0_IN S3C64XX_DMA_CHAN("i2s0_rx")
+#define DMACH_SPI0_TX S3C64XX_DMA_CHAN("spi0_tx")
+#define DMACH_SPI0_RX S3C64XX_DMA_CHAN("spi0_rx")
+#define DMACH_HSI_I2SV40_TX S3C64XX_DMA_CHAN("i2s2_tx")
+#define DMACH_HSI_I2SV40_RX S3C64XX_DMA_CHAN("i2s2_rx")
+
+/* DMA1/SDMA1 */
+#define DMACH_PCM1_TX S3C64XX_DMA_CHAN("pcm1_tx")
+#define DMACH_PCM1_RX S3C64XX_DMA_CHAN("pcm1_rx")
+#define DMACH_I2S1_OUT S3C64XX_DMA_CHAN("i2s1_tx")
+#define DMACH_I2S1_IN S3C64XX_DMA_CHAN("i2s1_rx")
+#define DMACH_SPI1_TX S3C64XX_DMA_CHAN("spi1_tx")
+#define DMACH_SPI1_RX S3C64XX_DMA_CHAN("spi1_rx")
+#define DMACH_AC97_PCMOUT S3C64XX_DMA_CHAN("ac97_out")
+#define DMACH_AC97_PCMIN S3C64XX_DMA_CHAN("ac97_in")
+#define DMACH_AC97_MICIN S3C64XX_DMA_CHAN("ac97_mic")
+#define DMACH_PWM S3C64XX_DMA_CHAN("pwm")
+#define DMACH_IRDA S3C64XX_DMA_CHAN("irda")
+#define DMACH_EXTERNAL S3C64XX_DMA_CHAN("external")
+#define DMACH_SECURITY_RX S3C64XX_DMA_CHAN("sec_rx")
+#define DMACH_SECURITY_TX S3C64XX_DMA_CHAN("sec_tx")
+
+enum dma_ch {
+ DMACH_MAX = 32
+};
+
+#include <linux/amba/pl08x.h>
+
+#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h b/arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h
new file mode 100644
index 000000000..9c81fac3b
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h
@@ -0,0 +1,94 @@
+/*
+ * 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.
+*/
+
+#ifndef GPIO_SAMSUNG_S3C64XX_H
+#define GPIO_SAMSUNG_S3C64XX_H
+
+/* 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)
+
+#endif /* GPIO_SAMSUNG_S3C64XX_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 000000000..862d033e5
--- /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/irqs.h b/arch/arm/mach-s3c64xx/include/mach/irqs.h
new file mode 100644
index 000000000..67bbd1dd0
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/irqs.h
@@ -0,0 +1,185 @@
+/* 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)
+
+/* 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)
+
+/* 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_MACH_WLF_CRAGG_6410
+#define IRQ_BOARD_NR 160
+#elif defined(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
+#define IRQ_I2S0 IRQ_S3C6410_IIS
+
+#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 000000000..f55ccb1ce
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/map.h
@@ -0,0 +1,126 @@
+/* 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>
+#include <plat/map-s3c.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_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_PA_USBHOST (0x74300000)
+
+#define S3C64XX_PA_USB_HSPHY (0x7C100000)
+
+/* 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_PA_RTC S3C64XX_PA_RTC
+#define S3C_PA_WDT S3C64XX_PA_WATCHDOG
+#define S3C_PA_SPI0 S3C64XX_PA_SPI0
+#define S3C_PA_SPI1 S3C64XX_PA_SPI1
+
+#define SAMSUNG_PA_ADC S3C64XX_PA_ADC
+#define SAMSUNG_PA_CFCON S3C64XX_PA_CFCON
+#define SAMSUNG_PA_KEYPAD S3C64XX_PA_KEYPAD
+#define SAMSUNG_PA_TIMER S3C64XX_PA_TIMER
+
+#endif /* __ASM_ARCH_6400_MAP_H */
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 000000000..a30a1e3ff
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/pm-core.h
@@ -0,0 +1,121 @@
+/* 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.
+ */
+
+#ifndef __MACH_S3C64XX_PM_CORE_H
+#define __MACH_S3C64XX_PM_CORE_H __FILE__
+
+#include <linux/serial_s3c.h>
+
+#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;
+ }
+}
+
+static inline void s3c_pm_restored_gpios(void)
+{
+ /* ensure sleep mode has been cleared from the system */
+
+ __raw_writel(0, S3C64XX_SLPEN);
+}
+
+static inline void samsung_pm_saved_gpios(void)
+{
+ /* turn on the sleep mode and keep it there, as it seems that during
+ * suspend the xCON registers get re-set and thus you can end up with
+ * problems between going to sleep and resuming.
+ */
+
+ __raw_writel(S3C64XX_SLPEN_USE_xSLP, S3C64XX_SLPEN);
+}
+#endif /* __MACH_S3C64XX_PM_CORE_H */
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 000000000..4f44aac77
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
@@ -0,0 +1,38 @@
+/* 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__
+
+/*
+ * FIXME: Remove remaining definitions
+ */
+
+#define S3C_CLKREG(x) (S3C_VA_SYS + (x))
+
+#define S3C_PCLK_GATE S3C_CLKREG(0x34)
+#define S3C6410_CLK_SRC2 S3C_CLKREG(0x10C)
+#define S3C_MEM_SYS_CFG S3C_CLKREG(0x120)
+
+/* PCLK GATE Registers */
+#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)
+
+/* 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-gpio.h b/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h
new file mode 100644
index 000000000..81f7f6e68
--- /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 000000000..6a1127891
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-irq.h
@@ -0,0 +1,19 @@
+/* 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__
+
+
+#endif /* __ASM_ARCH_6400_REGS_IRQ_H */
diff --git a/arch/arm/mach-s3c64xx/irq-pm.c b/arch/arm/mach-s3c64xx/irq-pm.c
new file mode 100644
index 000000000..ae4ea7601
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/irq-pm.c
@@ -0,0 +1,124 @@
+/* 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.
+ */
+
+/*
+ * NOTE: Code in this file is not used when booting with Device Tree support.
+ */
+
+#include <linux/kernel.h>
+#include <linux/syscore_ops.h>
+#include <linux/interrupt.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include <mach/map.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),
+};
+
+static struct irq_grp_save {
+ u32 fltcon;
+ u32 con;
+ u32 mask;
+} eint_grp_save[5];
+
+#ifndef CONFIG_SERIAL_SAMSUNG_UARTS
+#define SERIAL_SAMSUNG_UARTS 0
+#else
+#define SERIAL_SAMSUNG_UARTS CONFIG_SERIAL_SAMSUNG_UARTS
+#endif
+
+static u32 irq_uart_mask[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 < 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 < 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__);
+}
+
+static struct syscore_ops s3c64xx_irq_syscore_ops = {
+ .suspend = s3c64xx_irq_pm_suspend,
+ .resume = s3c64xx_irq_pm_resume,
+};
+
+static __init int s3c64xx_syscore_init(void)
+{
+ /* Appropriate drivers (pinctrl, uart) handle this when using DT. */
+ if (of_have_populated_dt())
+ return 0;
+
+ register_syscore_ops(&s3c64xx_irq_syscore_ops);
+
+ return 0;
+}
+
+core_initcall(s3c64xx_syscore_init);
diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c
new file mode 100644
index 000000000..6224c67f5
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-anw6410.c
@@ -0,0 +1,238 @@
+/* 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/serial_s3c.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 <video/samsung_fimd.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 <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <plat/fb.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "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 = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 800,
+ .yres = 480,
+};
+
+static struct fb_videomode anw6410_lcd_timing = {
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+};
+
+/* 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,
+ .vtiming = &anw6410_lcd_timing,
+ .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] = DEFINE_RES_MEM(ANW6410_PA_DM9000, 4),
+ [1] = DEFINE_RES_MEM(ANW6410_PA_DM9000 + 4, 501),
+ [2] = DEFINE_RES_NAMED(IRQ_EINT(15), 1, NULL, 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));
+ s3c64xx_set_xtal_freq(12000000);
+ s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ 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> */
+ .atag_offset = 0x100,
+
+ .init_irq = s3c6410_init_irq,
+ .map_io = anw6410_map_io,
+ .init_machine = anw6410_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
new file mode 100644
index 000000000..9c00d83f7
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
@@ -0,0 +1,404 @@
+/* Speyside modules for Cragganmore - board data probing
+ *
+ * Copyright 2011 Wolfson Microelectronics plc
+ * 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/export.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
+
+#include <linux/mfd/wm831x/irq.h>
+#include <linux/mfd/wm831x/gpio.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/mfd/arizona/pdata.h>
+
+#include <linux/regulator/machine.h>
+
+#include <sound/wm0010.h>
+#include <sound/wm2200.h>
+#include <sound/wm5100.h>
+#include <sound/wm8996.h>
+#include <sound/wm8962.h>
+#include <sound/wm9081.h>
+
+#include <linux/platform_data/spi-s3c64xx.h>
+
+#include "crag6410.h"
+
+static struct s3c64xx_spi_csinfo wm0010_spi_csinfo = {
+ .line = S3C64XX_GPC(3),
+};
+
+static struct wm0010_pdata wm0010_pdata = {
+ .gpio_reset = S3C64XX_GPN(6),
+ .reset_active_high = 1, /* Active high for Glenfarclas Rev 2 */
+};
+
+static struct spi_board_info wm1253_devs[] = {
+ [0] = {
+ .modalias = "wm0010",
+ .max_speed_hz = 26 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .irq = S3C_EINT(4),
+ .controller_data = &wm0010_spi_csinfo,
+ .platform_data = &wm0010_pdata,
+ },
+};
+
+static struct spi_board_info balblair_devs[] = {
+ [0] = {
+ .modalias = "wm0010",
+ .max_speed_hz = 26 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .irq = S3C_EINT(4),
+ .controller_data = &wm0010_spi_csinfo,
+ .platform_data = &wm0010_pdata,
+ },
+};
+
+static struct wm5100_pdata wm5100_pdata = {
+ .ldo_ena = S3C64XX_GPN(7),
+ .irq_flags = IRQF_TRIGGER_HIGH,
+ .gpio_base = CODEC_GPIO_BASE,
+
+ .in_mode = {
+ WM5100_IN_DIFF,
+ WM5100_IN_DIFF,
+ WM5100_IN_DIFF,
+ WM5100_IN_SE,
+ },
+
+ .hp_pol = CODEC_GPIO_BASE + 3,
+ .jack_modes = {
+ { WM5100_MICDET_MICBIAS3, 0, 0 },
+ { WM5100_MICDET_MICBIAS2, 1, 1 },
+ },
+
+ .gpio_defaults = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0x2, /* IRQ: CMOS output */
+ 0x3, /* CLKOUT: CMOS output */
+ },
+};
+
+static struct wm8996_retune_mobile_config wm8996_retune[] = {
+ {
+ .name = "Sub LPF",
+ .rate = 48000,
+ .regs = {
+ 0x6318, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
+ 0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
+ 0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
+ },
+ },
+ {
+ .name = "Sub HPF",
+ .rate = 48000,
+ .regs = {
+ 0x000A, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
+ 0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
+ 0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
+ },
+ },
+};
+
+static struct wm8996_pdata wm8996_pdata __initdata = {
+ .ldo_ena = S3C64XX_GPN(7),
+ .gpio_base = CODEC_GPIO_BASE,
+ .micdet_def = 1,
+ .inl_mode = WM8996_DIFFERRENTIAL_1,
+ .inr_mode = WM8996_DIFFERRENTIAL_1,
+
+ .irq_flags = IRQF_TRIGGER_RISING,
+
+ .gpio_default = {
+ 0x8001, /* GPIO1 == ADCLRCLK1 */
+ 0x8001, /* GPIO2 == ADCLRCLK2, input due to CPU */
+ 0x0141, /* GPIO3 == HP_SEL */
+ 0x0002, /* GPIO4 == IRQ */
+ 0x020e, /* GPIO5 == CLKOUT */
+ },
+
+ .retune_mobile_cfgs = wm8996_retune,
+ .num_retune_mobile_cfgs = ARRAY_SIZE(wm8996_retune),
+};
+
+static struct wm8962_pdata wm8962_pdata __initdata = {
+ .gpio_init = {
+ 0,
+ WM8962_GPIO_FN_OPCLK,
+ WM8962_GPIO_FN_DMICCLK,
+ 0,
+ 0x8000 | WM8962_GPIO_FN_DMICDAT,
+ WM8962_GPIO_FN_IRQ, /* Open drain mode */
+ },
+ .in4_dc_measure = true,
+};
+
+static struct wm9081_pdata wm9081_pdata __initdata = {
+ .irq_high = false,
+ .irq_cmos = false,
+};
+
+static const struct i2c_board_info wm1254_devs[] = {
+ { I2C_BOARD_INFO("wm8996", 0x1a),
+ .platform_data = &wm8996_pdata,
+ .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
+ },
+ { I2C_BOARD_INFO("wm9081", 0x6c),
+ .platform_data = &wm9081_pdata, },
+};
+
+static const struct i2c_board_info wm1255_devs[] = {
+ { I2C_BOARD_INFO("wm5100", 0x1a),
+ .platform_data = &wm5100_pdata,
+ .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
+ },
+ { I2C_BOARD_INFO("wm9081", 0x6c),
+ .platform_data = &wm9081_pdata, },
+};
+
+static const struct i2c_board_info wm1259_devs[] = {
+ { I2C_BOARD_INFO("wm8962", 0x1a),
+ .platform_data = &wm8962_pdata,
+ .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
+ },
+};
+
+static struct regulator_init_data wm8994_ldo1 = {
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data wm8994_ldo2 = {
+ .supply_regulator = "WALLVDD",
+};
+
+static struct wm8994_pdata wm8994_pdata = {
+ .gpio_base = CODEC_GPIO_BASE,
+ .micb2_delay = 150,
+ .gpio_defaults = {
+ 0x3, /* IRQ out, active high, CMOS */
+ },
+ .ldo = {
+ { .enable = S3C64XX_GPN(6), .init_data = &wm8994_ldo1, },
+ { .enable = S3C64XX_GPN(4), .init_data = &wm8994_ldo2, },
+ },
+};
+
+static const struct i2c_board_info wm1277_devs[] = {
+ { I2C_BOARD_INFO("wm8958", 0x1a), /* WM8958 is the superset */
+ .platform_data = &wm8994_pdata,
+ .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
+ },
+};
+
+static struct arizona_pdata wm5102_reva_pdata = {
+ .ldoena = S3C64XX_GPN(7),
+ .gpio_base = CODEC_GPIO_BASE,
+ .irq_flags = IRQF_TRIGGER_HIGH,
+ .micd_pol_gpio = CODEC_GPIO_BASE + 4,
+ .micd_rate = 6,
+ .gpio_defaults = {
+ [2] = 0x10000, /* AIF3TXLRCLK */
+ [3] = 0x4, /* OPCLK */
+ },
+};
+
+static struct s3c64xx_spi_csinfo codec_spi_csinfo = {
+ .line = S3C64XX_GPN(5),
+};
+
+static struct spi_board_info wm5102_reva_spi_devs[] = {
+ [0] = {
+ .modalias = "wm5102",
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ .irq = GLENFARCLAS_PMIC_IRQ_BASE +
+ WM831X_IRQ_GPIO_2,
+ .controller_data = &codec_spi_csinfo,
+ .platform_data = &wm5102_reva_pdata,
+ },
+};
+
+static struct arizona_pdata wm5102_pdata = {
+ .ldoena = S3C64XX_GPN(7),
+ .gpio_base = CODEC_GPIO_BASE,
+ .irq_flags = IRQF_TRIGGER_HIGH,
+ .micd_pol_gpio = CODEC_GPIO_BASE + 2,
+ .gpio_defaults = {
+ [2] = 0x10000, /* AIF3TXLRCLK */
+ [3] = 0x4, /* OPCLK */
+ },
+};
+
+static struct spi_board_info wm5102_spi_devs[] = {
+ [0] = {
+ .modalias = "wm5102",
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ .irq = GLENFARCLAS_PMIC_IRQ_BASE +
+ WM831X_IRQ_GPIO_2,
+ .controller_data = &codec_spi_csinfo,
+ .platform_data = &wm5102_pdata,
+ },
+};
+
+static struct spi_board_info wm5110_spi_devs[] = {
+ [0] = {
+ .modalias = "wm5110",
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ .irq = GLENFARCLAS_PMIC_IRQ_BASE +
+ WM831X_IRQ_GPIO_2,
+ .controller_data = &codec_spi_csinfo,
+ .platform_data = &wm5102_reva_pdata,
+ },
+};
+
+static const struct i2c_board_info wm6230_i2c_devs[] = {
+ { I2C_BOARD_INFO("wm9081", 0x6c),
+ .platform_data = &wm9081_pdata, },
+};
+
+static struct wm2200_pdata wm2200_pdata = {
+ .ldo_ena = S3C64XX_GPN(7),
+ .gpio_defaults = {
+ [2] = 0x0005, /* GPIO3 24.576MHz output clock */
+ },
+};
+
+static const struct i2c_board_info wm2200_i2c[] = {
+ { I2C_BOARD_INFO("wm2200", 0x3a),
+ .platform_data = &wm2200_pdata, },
+};
+
+static const struct {
+ u8 id;
+ u8 rev;
+ const char *name;
+ const struct i2c_board_info *i2c_devs;
+ int num_i2c_devs;
+ const struct spi_board_info *spi_devs;
+ int num_spi_devs;
+} gf_mods[] = {
+ { .id = 0x01, .rev = 0xff, .name = "1250-EV1 Springbank" },
+ { .id = 0x02, .rev = 0xff, .name = "1251-EV1 Jura" },
+ { .id = 0x03, .rev = 0xff, .name = "1252-EV1 Glenlivet" },
+ { .id = 0x06, .rev = 0xff, .name = "WM8997-6721-CS96-EV1 Lapraoig" },
+ { .id = 0x07, .rev = 0xff, .name = "WM5110-6271 Deanston",
+ .spi_devs = wm5110_spi_devs,
+ .num_spi_devs = ARRAY_SIZE(wm5110_spi_devs) },
+ { .id = 0x08, .rev = 0xff, .name = "WM8903-6102 Tamdhu" },
+ { .id = 0x09, .rev = 0xff, .name = "WM1811A-6305 Adelphi" },
+ { .id = 0x0a, .rev = 0xff, .name = "WM8996-6272 Blackadder" },
+ { .id = 0x0b, .rev = 0xff, .name = "WM8994-6235 Benromach" },
+ { .id = 0x11, .rev = 0xff, .name = "6249-EV2 Glenfarclas", },
+ { .id = 0x14, .rev = 0xff, .name = "6271-EV1 Lochnagar" },
+ { .id = 0x15, .rev = 0xff, .name = "6320-EV1 Bells",
+ .i2c_devs = wm6230_i2c_devs,
+ .num_i2c_devs = ARRAY_SIZE(wm6230_i2c_devs) },
+ { .id = 0x21, .rev = 0xff, .name = "1275-EV1 Mortlach" },
+ { .id = 0x25, .rev = 0xff, .name = "1274-EV1 Glencadam" },
+ { .id = 0x31, .rev = 0xff, .name = "1253-EV1 Tomatin",
+ .spi_devs = wm1253_devs, .num_spi_devs = ARRAY_SIZE(wm1253_devs) },
+ { .id = 0x32, .rev = 0xff, .name = "XXXX-EV1 Caol Illa" },
+ { .id = 0x33, .rev = 0xff, .name = "XXXX-EV1 Oban" },
+ { .id = 0x34, .rev = 0xff, .name = "WM0010-6320-CS42 Balblair",
+ .spi_devs = balblair_devs,
+ .num_spi_devs = ARRAY_SIZE(balblair_devs) },
+ { .id = 0x39, .rev = 0xff, .name = "1254-EV1 Dallas Dhu",
+ .i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs) },
+ { .id = 0x3a, .rev = 0xff, .name = "1259-EV1 Tobermory",
+ .i2c_devs = wm1259_devs, .num_i2c_devs = ARRAY_SIZE(wm1259_devs) },
+ { .id = 0x3b, .rev = 0xff, .name = "1255-EV1 Kilchoman",
+ .i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs) },
+ { .id = 0x3c, .rev = 0xff, .name = "1273-EV1 Longmorn" },
+ { .id = 0x3d, .rev = 0xff, .name = "1277-EV1 Littlemill",
+ .i2c_devs = wm1277_devs, .num_i2c_devs = ARRAY_SIZE(wm1277_devs) },
+ { .id = 0x3e, .rev = 0, .name = "WM5102-6271-EV1-CS127 Amrut",
+ .spi_devs = wm5102_reva_spi_devs,
+ .num_spi_devs = ARRAY_SIZE(wm5102_reva_spi_devs) },
+ { .id = 0x3e, .rev = -1, .name = "WM5102-6271-EV1-CS127 Amrut",
+ .spi_devs = wm5102_spi_devs,
+ .num_spi_devs = ARRAY_SIZE(wm5102_spi_devs) },
+ { .id = 0x3f, .rev = -1, .name = "WM2200-6271-CS90-M-REV1",
+ .i2c_devs = wm2200_i2c, .num_i2c_devs = ARRAY_SIZE(wm2200_i2c) },
+};
+
+static int wlf_gf_module_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *i2c_id)
+{
+ int ret, i, j, id, rev;
+
+ ret = i2c_smbus_read_byte_data(i2c, 0);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to read ID: %d\n", ret);
+ return ret;
+ }
+
+ id = (ret & 0xfe) >> 2;
+ rev = ret & 0x3;
+ for (i = 0; i < ARRAY_SIZE(gf_mods); i++)
+ if (id == gf_mods[i].id && (gf_mods[i].rev == 0xff ||
+ rev == gf_mods[i].rev))
+ break;
+
+ if (i < ARRAY_SIZE(gf_mods)) {
+ dev_info(&i2c->dev, "%s revision %d\n",
+ gf_mods[i].name, rev + 1);
+
+ for (j = 0; j < gf_mods[i].num_i2c_devs; j++) {
+ if (!i2c_new_device(i2c->adapter,
+ &(gf_mods[i].i2c_devs[j])))
+ dev_err(&i2c->dev,
+ "Failed to register dev: %d\n", ret);
+ }
+
+ spi_register_board_info(gf_mods[i].spi_devs,
+ gf_mods[i].num_spi_devs);
+ } else {
+ dev_warn(&i2c->dev, "Unknown module ID 0x%x revision %d\n",
+ id, rev + 1);
+ }
+
+ return 0;
+}
+
+static const struct i2c_device_id wlf_gf_module_id[] = {
+ { "wlf-gf-module", 0 },
+ { }
+};
+
+static struct i2c_driver wlf_gf_module_driver = {
+ .driver = {
+ .name = "wlf-gf-module",
+ .owner = THIS_MODULE,
+ },
+ .probe = wlf_gf_module_probe,
+ .id_table = wlf_gf_module_id,
+};
+
+static int __init wlf_gf_module_register(void)
+{
+ return i2c_add_driver(&wlf_gf_module_driver);
+}
+device_initcall(wlf_gf_module_register);
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
new file mode 100644
index 000000000..65c426bc4
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -0,0 +1,863 @@
+/* linux/arch/arm/mach-s3c64xx/mach-crag6410.c
+ *
+ * Copyright 2011 Wolfson Microelectronics plc
+ * Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * Copyright 2011 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/kernel.h>
+#include <linux/list.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/delay.h>
+#include <linux/mmc/host.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/pwm_backlight.h>
+#include <linux/dm9000.h>
+#include <linux/gpio_keys.h>
+#include <linux/basic_mmio_gpio.h>
+#include <linux/spi/spi.h>
+
+#include <linux/platform_data/pca953x.h>
+#include <linux/platform_data/s3c-hsotg.h>
+
+#include <video/platform_lcd.h>
+
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/pdata.h>
+#include <linux/mfd/wm831x/irq.h>
+#include <linux/mfd/wm831x/gpio.h>
+
+#include <sound/wm1250-ev1.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <video/samsung_fimd.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/fb.h>
+#include <plat/sdhci.h>
+#include <plat/gpio-cfg.h>
+#include <linux/platform_data/spi-s3c64xx.h>
+
+#include <plat/keypad.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/adc.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <plat/pm.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "crag6410.h"
+#include "regs-gpio-memport.h"
+#include "regs-modem.h"
+#include "regs-sys.h"
+
+/* serial port setup */
+
+#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 crag6410_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,
+ },
+};
+
+static struct platform_pwm_backlight_data crag6410_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 1000,
+ .dft_brightness = 600,
+ .pwm_period_ns = 100000, /* about 1kHz */
+ .enable_gpio = -1,
+};
+
+static struct platform_device crag6410_backlight_device = {
+ .name = "pwm-backlight",
+ .id = -1,
+ .dev = {
+ .parent = &samsung_device_pwm.dev,
+ .platform_data = &crag6410_backlight_data,
+ },
+};
+
+static void crag6410_lcd_power_set(struct plat_lcd_data *pd, unsigned int power)
+{
+ pr_debug("%s: setting power %d\n", __func__, power);
+
+ if (power) {
+ gpio_set_value(S3C64XX_GPB(0), 1);
+ msleep(1);
+ s3c_gpio_cfgpin(S3C64XX_GPF(14), S3C_GPIO_SFN(2));
+ } else {
+ gpio_direction_output(S3C64XX_GPF(14), 0);
+ gpio_set_value(S3C64XX_GPB(0), 0);
+ }
+}
+
+static struct platform_device crag6410_lcd_powerdev = {
+ .name = "platform-lcd",
+ .id = -1,
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &(struct plat_lcd_data) {
+ .set_power = crag6410_lcd_power_set,
+ },
+};
+
+/* 640x480 URT */
+static struct s3c_fb_pd_win crag6410_fb_win0 = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 640,
+ .yres = 480,
+ .virtual_y = 480 * 2,
+ .virtual_x = 640,
+};
+
+static struct fb_videomode crag6410_lcd_timing = {
+ .left_margin = 150,
+ .right_margin = 80,
+ .upper_margin = 40,
+ .lower_margin = 5,
+ .hsync_len = 40,
+ .vsync_len = 5,
+ .xres = 640,
+ .yres = 480,
+};
+
+/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
+static struct s3c_fb_platdata crag6410_lcd_pdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &crag6410_lcd_timing,
+ .win[0] = &crag6410_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+/* 2x6 keypad */
+
+static uint32_t crag6410_keymap[] = {
+ /* KEY(row, col, keycode) */
+ KEY(0, 0, KEY_VOLUMEUP),
+ KEY(0, 1, KEY_HOME),
+ KEY(0, 2, KEY_VOLUMEDOWN),
+ KEY(0, 3, KEY_HELP),
+ KEY(0, 4, KEY_MENU),
+ KEY(0, 5, KEY_MEDIA),
+ KEY(1, 0, 232),
+ KEY(1, 1, KEY_DOWN),
+ KEY(1, 2, KEY_LEFT),
+ KEY(1, 3, KEY_UP),
+ KEY(1, 4, KEY_RIGHT),
+ KEY(1, 5, KEY_CAMERA),
+};
+
+static struct matrix_keymap_data crag6410_keymap_data = {
+ .keymap = crag6410_keymap,
+ .keymap_size = ARRAY_SIZE(crag6410_keymap),
+};
+
+static struct samsung_keypad_platdata crag6410_keypad_data = {
+ .keymap_data = &crag6410_keymap_data,
+ .rows = 2,
+ .cols = 6,
+};
+
+static struct gpio_keys_button crag6410_gpio_keys[] = {
+ [0] = {
+ .code = KEY_SUSPEND,
+ .gpio = S3C64XX_GPL(10), /* EINT 18 */
+ .type = EV_KEY,
+ .wakeup = 1,
+ .active_low = 1,
+ },
+ [1] = {
+ .code = SW_FRONT_PROXIMITY,
+ .gpio = S3C64XX_GPN(11), /* EINT 11 */
+ .type = EV_SW,
+ },
+};
+
+static struct gpio_keys_platform_data crag6410_gpio_keydata = {
+ .buttons = crag6410_gpio_keys,
+ .nbuttons = ARRAY_SIZE(crag6410_gpio_keys),
+};
+
+static struct platform_device crag6410_gpio_keydev = {
+ .name = "gpio-keys",
+ .id = 0,
+ .dev.platform_data = &crag6410_gpio_keydata,
+};
+
+static struct resource crag6410_dm9k_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN5, 2),
+ [1] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN5 + (1 << 8), 2),
+ [2] = DEFINE_RES_NAMED(S3C_EINT(17), 1, NULL, IORESOURCE_IRQ \
+ | IORESOURCE_IRQ_HIGHLEVEL),
+};
+
+static struct dm9000_plat_data mini6410_dm9k_pdata = {
+ .flags = DM9000_PLATF_16BITONLY,
+};
+
+static struct platform_device crag6410_dm9k_device = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(crag6410_dm9k_resource),
+ .resource = crag6410_dm9k_resource,
+ .dev.platform_data = &mini6410_dm9k_pdata,
+};
+
+static struct resource crag6410_mmgpio_resource[] = {
+ [0] = DEFINE_RES_MEM_NAMED(S3C64XX_PA_XM0CSN4, 1, "dat"),
+};
+
+static struct platform_device crag6410_mmgpio = {
+ .name = "basic-mmio-gpio",
+ .id = -1,
+ .resource = crag6410_mmgpio_resource,
+ .num_resources = ARRAY_SIZE(crag6410_mmgpio_resource),
+ .dev.platform_data = &(struct bgpio_pdata) {
+ .base = MMGPIO_GPIO_BASE,
+ },
+};
+
+static struct platform_device speyside_device = {
+ .name = "speyside",
+ .id = -1,
+};
+
+static struct platform_device lowland_device = {
+ .name = "lowland",
+ .id = -1,
+};
+
+static struct platform_device tobermory_device = {
+ .name = "tobermory",
+ .id = -1,
+};
+
+static struct platform_device littlemill_device = {
+ .name = "littlemill",
+ .id = -1,
+};
+
+static struct platform_device bells_wm2200_device = {
+ .name = "bells",
+ .id = 0,
+};
+
+static struct platform_device bells_wm5102_device = {
+ .name = "bells",
+ .id = 1,
+};
+
+static struct platform_device bells_wm5110_device = {
+ .name = "bells",
+ .id = 2,
+};
+
+static struct regulator_consumer_supply wallvdd_consumers[] = {
+ REGULATOR_SUPPLY("SPKVDD", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDD1", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDD2", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDDL", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDDR", "1-001a"),
+
+ REGULATOR_SUPPLY("SPKVDDL", "spi0.1"),
+ REGULATOR_SUPPLY("SPKVDDR", "spi0.1"),
+
+ REGULATOR_SUPPLY("DC1VDD", "0-0034"),
+ REGULATOR_SUPPLY("DC2VDD", "0-0034"),
+ REGULATOR_SUPPLY("DC3VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO1VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO2VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO4VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO5VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO6VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO7VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO8VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO9VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO10VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO11VDD", "0-0034"),
+
+ REGULATOR_SUPPLY("DC1VDD", "1-0034"),
+ REGULATOR_SUPPLY("DC2VDD", "1-0034"),
+ REGULATOR_SUPPLY("DC3VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO1VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO2VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO4VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO5VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO6VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO7VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO8VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO9VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO10VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO11VDD", "1-0034"),
+};
+
+static struct regulator_init_data wallvdd_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wallvdd_consumers),
+ .consumer_supplies = wallvdd_consumers,
+};
+
+static struct fixed_voltage_config wallvdd_pdata = {
+ .supply_name = "WALLVDD",
+ .microvolts = 5000000,
+ .init_data = &wallvdd_data,
+ .gpio = -EINVAL,
+};
+
+static struct platform_device wallvdd_device = {
+ .name = "reg-fixed-voltage",
+ .id = -1,
+ .dev = {
+ .platform_data = &wallvdd_pdata,
+ },
+};
+
+static struct platform_device *crag6410_devices[] __initdata = {
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc2,
+ &s3c_device_i2c0,
+ &s3c_device_i2c1,
+ &s3c_device_fb,
+ &s3c_device_ohci,
+ &s3c_device_usb_hsotg,
+ &samsung_device_pwm,
+ &s3c64xx_device_iis0,
+ &s3c64xx_device_iis1,
+ &samsung_device_keypad,
+ &crag6410_gpio_keydev,
+ &crag6410_dm9k_device,
+ &s3c64xx_device_spi0,
+ &crag6410_mmgpio,
+ &crag6410_lcd_powerdev,
+ &crag6410_backlight_device,
+ &speyside_device,
+ &tobermory_device,
+ &littlemill_device,
+ &lowland_device,
+ &bells_wm2200_device,
+ &bells_wm5102_device,
+ &bells_wm5110_device,
+ &wallvdd_device,
+};
+
+static struct pca953x_platform_data crag6410_pca_data = {
+ .gpio_base = PCA935X_GPIO_BASE,
+ .irq_base = -1,
+};
+
+/* VDDARM is controlled by DVS1 connected to GPK(0) */
+static struct wm831x_buckv_pdata vddarm_pdata = {
+ .dvs_control_src = 1,
+ .dvs_gpio = S3C64XX_GPK(0),
+};
+
+static struct regulator_consumer_supply vddarm_consumers[] = {
+ REGULATOR_SUPPLY("vddarm", NULL),
+};
+
+static struct regulator_init_data vddarm = {
+ .constraints = {
+ .name = "VDDARM",
+ .min_uV = 1000000,
+ .max_uV = 1300000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vddarm_consumers),
+ .consumer_supplies = vddarm_consumers,
+ .supply_regulator = "WALLVDD",
+ .driver_data = &vddarm_pdata,
+};
+
+static struct regulator_consumer_supply vddint_consumers[] = {
+ REGULATOR_SUPPLY("vddint", NULL),
+};
+
+static struct regulator_init_data vddint = {
+ .constraints = {
+ .name = "VDDINT",
+ .min_uV = 1000000,
+ .max_uV = 1200000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vddint_consumers),
+ .consumer_supplies = vddint_consumers,
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddmem = {
+ .constraints = {
+ .name = "VDDMEM",
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data vddsys = {
+ .constraints = {
+ .name = "VDDSYS,VDDEXT,VDDPCM,VDDSS",
+ .always_on = 1,
+ },
+};
+
+static struct regulator_consumer_supply vddmmc_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
+ REGULATOR_SUPPLY("vmmc", "s3c-sdhci.1"),
+ REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"),
+};
+
+static struct regulator_init_data vddmmc = {
+ .constraints = {
+ .name = "VDDMMC,UH",
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vddmmc_consumers),
+ .consumer_supplies = vddmmc_consumers,
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddotgi = {
+ .constraints = {
+ .name = "VDDOTGi",
+ .always_on = 1,
+ },
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddotg = {
+ .constraints = {
+ .name = "VDDOTG",
+ .always_on = 1,
+ },
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddhi = {
+ .constraints = {
+ .name = "VDDHI",
+ .always_on = 1,
+ },
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddadc = {
+ .constraints = {
+ .name = "VDDADC,VDDDAC",
+ .always_on = 1,
+ },
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddmem0 = {
+ .constraints = {
+ .name = "VDDMEM0",
+ .always_on = 1,
+ },
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddpll = {
+ .constraints = {
+ .name = "VDDPLL",
+ .always_on = 1,
+ },
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddlcd = {
+ .constraints = {
+ .name = "VDDLCD",
+ .always_on = 1,
+ },
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddalive = {
+ .constraints = {
+ .name = "VDDALIVE",
+ .always_on = 1,
+ },
+ .supply_regulator = "WALLVDD",
+};
+
+static struct wm831x_backup_pdata banff_backup_pdata = {
+ .charger_enable = 1,
+ .vlim = 2500, /* mV */
+ .ilim = 200, /* uA */
+};
+
+static struct wm831x_status_pdata banff_red_led = {
+ .name = "banff:red:",
+ .default_src = WM831X_STATUS_MANUAL,
+};
+
+static struct wm831x_status_pdata banff_green_led = {
+ .name = "banff:green:",
+ .default_src = WM831X_STATUS_MANUAL,
+};
+
+static struct wm831x_touch_pdata touch_pdata = {
+ .data_irq = S3C_EINT(26),
+ .pd_irq = S3C_EINT(27),
+};
+
+static struct wm831x_pdata crag_pmic_pdata = {
+ .wm831x_num = 1,
+ .irq_base = BANFF_PMIC_IRQ_BASE,
+ .gpio_base = BANFF_PMIC_GPIO_BASE,
+ .soft_shutdown = true,
+
+ .backup = &banff_backup_pdata,
+
+ .gpio_defaults = {
+ /* GPIO5: DVS1_REQ - CMOS, DBVDD, active high */
+ [4] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA | 0x8,
+ /* GPIO11: Touchscreen data - CMOS, DBVDD, active high*/
+ [10] = WM831X_GPN_POL | WM831X_GPN_ENA | 0x6,
+ /* GPIO12: Touchscreen pen down - CMOS, DBVDD, active high*/
+ [11] = WM831X_GPN_POL | WM831X_GPN_ENA | 0x7,
+ },
+
+ .dcdc = {
+ &vddarm, /* DCDC1 */
+ &vddint, /* DCDC2 */
+ &vddmem, /* DCDC3 */
+ },
+
+ .ldo = {
+ &vddsys, /* LDO1 */
+ &vddmmc, /* LDO2 */
+ NULL, /* LDO3 */
+ &vddotgi, /* LDO4 */
+ &vddotg, /* LDO5 */
+ &vddhi, /* LDO6 */
+ &vddadc, /* LDO7 */
+ &vddmem0, /* LDO8 */
+ &vddpll, /* LDO9 */
+ &vddlcd, /* LDO10 */
+ &vddalive, /* LDO11 */
+ },
+
+ .status = {
+ &banff_green_led,
+ &banff_red_led,
+ },
+
+ .touch = &touch_pdata,
+};
+
+static struct i2c_board_info i2c_devs0[] = {
+ { I2C_BOARD_INFO("24c08", 0x50), },
+ { I2C_BOARD_INFO("tca6408", 0x20),
+ .platform_data = &crag6410_pca_data,
+ },
+ { I2C_BOARD_INFO("wm8312", 0x34),
+ .platform_data = &crag_pmic_pdata,
+ .irq = S3C_EINT(23),
+ },
+};
+
+static struct s3c2410_platform_i2c i2c0_pdata = {
+ .frequency = 400000,
+};
+
+static struct regulator_consumer_supply pvdd_1v2_consumers[] = {
+ REGULATOR_SUPPLY("DCVDD", "spi0.0"),
+ REGULATOR_SUPPLY("AVDD", "spi0.0"),
+ REGULATOR_SUPPLY("AVDD", "spi0.1"),
+};
+
+static struct regulator_init_data pvdd_1v2 = {
+ .constraints = {
+ .name = "PVDD_1V2",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+
+ .consumer_supplies = pvdd_1v2_consumers,
+ .num_consumer_supplies = ARRAY_SIZE(pvdd_1v2_consumers),
+};
+
+static struct regulator_consumer_supply pvdd_1v8_consumers[] = {
+ REGULATOR_SUPPLY("LDOVDD", "1-001a"),
+ REGULATOR_SUPPLY("PLLVDD", "1-001a"),
+ REGULATOR_SUPPLY("DBVDD", "1-001a"),
+ REGULATOR_SUPPLY("DBVDD1", "1-001a"),
+ REGULATOR_SUPPLY("DBVDD2", "1-001a"),
+ REGULATOR_SUPPLY("DBVDD3", "1-001a"),
+ REGULATOR_SUPPLY("CPVDD", "1-001a"),
+ REGULATOR_SUPPLY("AVDD2", "1-001a"),
+ REGULATOR_SUPPLY("DCVDD", "1-001a"),
+ REGULATOR_SUPPLY("AVDD", "1-001a"),
+ REGULATOR_SUPPLY("DBVDD", "spi0.0"),
+
+ REGULATOR_SUPPLY("DBVDD", "1-003a"),
+ REGULATOR_SUPPLY("LDOVDD", "1-003a"),
+ REGULATOR_SUPPLY("CPVDD", "1-003a"),
+ REGULATOR_SUPPLY("AVDD", "1-003a"),
+ REGULATOR_SUPPLY("DBVDD1", "spi0.1"),
+ REGULATOR_SUPPLY("DBVDD2", "spi0.1"),
+ REGULATOR_SUPPLY("DBVDD3", "spi0.1"),
+ REGULATOR_SUPPLY("LDOVDD", "spi0.1"),
+ REGULATOR_SUPPLY("CPVDD", "spi0.1"),
+};
+
+static struct regulator_init_data pvdd_1v8 = {
+ .constraints = {
+ .name = "PVDD_1V8",
+ .always_on = 1,
+ },
+
+ .consumer_supplies = pvdd_1v8_consumers,
+ .num_consumer_supplies = ARRAY_SIZE(pvdd_1v8_consumers),
+};
+
+static struct regulator_consumer_supply pvdd_3v3_consumers[] = {
+ REGULATOR_SUPPLY("MICVDD", "1-001a"),
+ REGULATOR_SUPPLY("AVDD1", "1-001a"),
+};
+
+static struct regulator_init_data pvdd_3v3 = {
+ .constraints = {
+ .name = "PVDD_3V3",
+ .always_on = 1,
+ },
+
+ .consumer_supplies = pvdd_3v3_consumers,
+ .num_consumer_supplies = ARRAY_SIZE(pvdd_3v3_consumers),
+};
+
+static struct wm831x_pdata glenfarclas_pmic_pdata = {
+ .wm831x_num = 2,
+ .irq_base = GLENFARCLAS_PMIC_IRQ_BASE,
+ .gpio_base = GLENFARCLAS_PMIC_GPIO_BASE,
+ .soft_shutdown = true,
+
+ .gpio_defaults = {
+ /* GPIO1-3: IRQ inputs, rising edge triggered, CMOS */
+ [0] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA,
+ [1] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA,
+ [2] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA,
+ },
+
+ .dcdc = {
+ &pvdd_1v2, /* DCDC1 */
+ &pvdd_1v8, /* DCDC2 */
+ &pvdd_3v3, /* DCDC3 */
+ },
+
+ .disable_touch = true,
+};
+
+static struct wm1250_ev1_pdata wm1250_ev1_pdata = {
+ .gpios = {
+ [WM1250_EV1_GPIO_CLK_ENA] = S3C64XX_GPN(12),
+ [WM1250_EV1_GPIO_CLK_SEL0] = S3C64XX_GPL(12),
+ [WM1250_EV1_GPIO_CLK_SEL1] = S3C64XX_GPL(13),
+ [WM1250_EV1_GPIO_OSR] = S3C64XX_GPL(14),
+ [WM1250_EV1_GPIO_MASTER] = S3C64XX_GPL(8),
+ },
+};
+
+static struct i2c_board_info i2c_devs1[] = {
+ { I2C_BOARD_INFO("wm8311", 0x34),
+ .irq = S3C_EINT(0),
+ .platform_data = &glenfarclas_pmic_pdata },
+
+ { I2C_BOARD_INFO("wlf-gf-module", 0x20) },
+ { I2C_BOARD_INFO("wlf-gf-module", 0x22) },
+ { I2C_BOARD_INFO("wlf-gf-module", 0x24) },
+ { I2C_BOARD_INFO("wlf-gf-module", 0x25) },
+ { I2C_BOARD_INFO("wlf-gf-module", 0x26) },
+
+ { I2C_BOARD_INFO("wm1250-ev1", 0x27),
+ .platform_data = &wm1250_ev1_pdata },
+};
+
+static struct s3c2410_platform_i2c i2c1_pdata = {
+ .frequency = 400000,
+ .bus_num = 1,
+};
+
+static void __init crag6410_map_io(void)
+{
+ s3c64xx_init_io(NULL, 0);
+ s3c64xx_set_xtal_freq(12000000);
+ s3c24xx_init_uarts(crag6410_uartcfgs, ARRAY_SIZE(crag6410_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ /* LCD type and Bypass set by bootloader */
+}
+
+static struct s3c_sdhci_platdata crag6410_hsmmc2_pdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_PERMANENT,
+ .host_caps = MMC_CAP_POWER_OFF_CARD,
+};
+
+static void crag6410_cfg_sdhci0(struct platform_device *dev, int width)
+{
+ /* Set all the necessary GPG pins to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPG(0), 2 + width, S3C_GPIO_SFN(2));
+
+ /* force card-detected for prototype 0 */
+ s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_DOWN);
+}
+
+static struct s3c_sdhci_platdata crag6410_hsmmc0_pdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .cfg_gpio = crag6410_cfg_sdhci0,
+ .host_caps = MMC_CAP_POWER_OFF_CARD,
+};
+
+static const struct gpio_led gpio_leds[] = {
+ {
+ .name = "d13:green:",
+ .gpio = MMGPIO_GPIO_BASE + 0,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "d14:green:",
+ .gpio = MMGPIO_GPIO_BASE + 1,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "d15:green:",
+ .gpio = MMGPIO_GPIO_BASE + 2,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "d16:green:",
+ .gpio = MMGPIO_GPIO_BASE + 3,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "d17:green:",
+ .gpio = MMGPIO_GPIO_BASE + 4,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "d18:green:",
+ .gpio = MMGPIO_GPIO_BASE + 5,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "d19:green:",
+ .gpio = MMGPIO_GPIO_BASE + 6,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "d20:green:",
+ .gpio = MMGPIO_GPIO_BASE + 7,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+};
+
+static const struct gpio_led_platform_data gpio_leds_pdata = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct s3c_hsotg_plat crag6410_hsotg_pdata;
+
+static void __init crag6410_machine_init(void)
+{
+ /* Open drain IRQs need pullups */
+ s3c_gpio_setpull(S3C64XX_GPM(0), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S3C64XX_GPN(0), S3C_GPIO_PULL_UP);
+
+ gpio_request(S3C64XX_GPB(0), "LCD power");
+ gpio_direction_output(S3C64XX_GPB(0), 0);
+
+ gpio_request(S3C64XX_GPF(14), "LCD PWM");
+ gpio_direction_output(S3C64XX_GPF(14), 0); /* turn off */
+
+ gpio_request(S3C64XX_GPB(1), "SD power");
+ gpio_direction_output(S3C64XX_GPB(1), 0);
+
+ gpio_request(S3C64XX_GPF(10), "nRESETSEL");
+ gpio_direction_output(S3C64XX_GPF(10), 1);
+
+ s3c_sdhci0_set_platdata(&crag6410_hsmmc0_pdata);
+ s3c_sdhci2_set_platdata(&crag6410_hsmmc2_pdata);
+
+ s3c_i2c0_set_platdata(&i2c0_pdata);
+ s3c_i2c1_set_platdata(&i2c1_pdata);
+ s3c_fb_set_platdata(&crag6410_lcd_pdata);
+ s3c_hsotg_set_platdata(&crag6410_hsotg_pdata);
+
+ i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
+ samsung_keypad_set_platdata(&crag6410_keypad_data);
+ s3c64xx_spi0_set_platdata(NULL, 0, 2);
+
+ platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices));
+
+ gpio_led_register_device(-1, &gpio_leds_pdata);
+
+ regulator_has_full_constraints();
+
+ s3c64xx_pm_init();
+}
+
+MACHINE_START(WLF_CRAGG_6410, "Wolfson Cragganmore 6410")
+ /* Maintainer: Mark Brown <broonie@opensource.wolfsonmicro.com> */
+ .atag_offset = 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = crag6410_map_io,
+ .init_machine = crag6410_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+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 000000000..e4b087c58
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-hmt.c
@@ -0,0 +1,282 @@
+/* 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/serial_s3c.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 <video/samsung_fimd.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <mach/gpio-samsung.h>
+#include <plat/fb.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.h>
+
+#include "common.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),
+ .enable_gpio = -1,
+ .init = hmt_bl_init,
+ .notify = hmt_bl_notify,
+ .exit = hmt_bl_exit,
+
+};
+
+static struct platform_device hmt_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &samsung_device_pwm.dev,
+ .platform_data = &hmt_backlight_data,
+ },
+};
+
+static struct s3c_fb_pd_win hmt_fb_win0 = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 800,
+ .yres = 480,
+};
+
+static struct fb_videomode hmt_lcd_timing = {
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+};
+
+/* 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,
+ .vtiming = &hmt_lcd_timing,
+ .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,
+ &samsung_device_pwm,
+ &hmt_backlight_device,
+ &hmt_leds_device,
+};
+
+static void __init hmt_map_io(void)
+{
+ s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc));
+ s3c64xx_set_xtal_freq(12000000);
+ s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+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> */
+ .atag_offset = 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = hmt_map_io,
+ .init_machine = hmt_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+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 000000000..ab61af50b
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-mini6410.c
@@ -0,0 +1,371 @@
+/* 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/serial_s3c.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-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/adc.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/mmc-sdhci-s3c.h>
+#include <plat/sdhci.h>
+#include <linux/platform_data/touchscreen-s3c2410.h>
+
+#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "regs-modem.h"
+#include "regs-srom.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] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1, 2),
+ [1] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1 + 4, 2),
+ [2] = DEFINE_RES_NAMED(S3C_EINT(7), 1, NULL, 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_lcd_type0_fb_win = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 480,
+ .yres = 272,
+};
+
+static struct fb_videomode mini6410_lcd_type0_timing = {
+ /* 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,
+};
+
+static struct s3c_fb_pd_win mini6410_lcd_type1_fb_win = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 800,
+ .yres = 480,
+};
+
+static struct fb_videomode mini6410_lcd_type1_timing = {
+ /* 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,
+};
+
+static struct s3c_fb_platdata mini6410_lcd_pdata[] __initdata = {
+ {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &mini6410_lcd_type0_timing,
+ .win[0] = &mini6410_lcd_type0_fb_win,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ }, {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &mini6410_lcd_type1_timing,
+ .win[0] = &mini6410_lcd_type1_fb_win,
+ .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 s3c_sdhci_platdata mini6410_hsmmc1_pdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = S3C64XX_GPN(10),
+ .ext_cd_gpio_invert = true,
+};
+
+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);
+ s3c64xx_set_xtal_freq(12000000);
+ s3c24xx_init_uarts(mini6410_uartcfgs, ARRAY_SIZE(mini6410_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ /* 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_lcd_pdata))
+ 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);
+
+ printk(KERN_INFO "MINI6410: selected LCD display is %dx%d\n",
+ mini6410_lcd_pdata[features.lcd_index].win[0]->xres,
+ mini6410_lcd_pdata[features.lcd_index].win[0]->yres);
+
+ s3c_nand_set_platdata(&mini6410_nand_info);
+ s3c_fb_set_platdata(&mini6410_lcd_pdata[features.lcd_index]);
+ s3c_sdhci1_set_platdata(&mini6410_hsmmc1_pdata);
+ s3c24xx_ts_set_platdata(NULL);
+
+ /* 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> */
+ .atag_offset = 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = mini6410_map_io,
+ .init_machine = mini6410_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+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 000000000..80cb1446f
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-ncp.c
@@ -0,0 +1,108 @@
+/*
+ * 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/serial_s3c.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 <video/samsung_fimd.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 <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <plat/fb.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.h>
+
+#include "common.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));
+ s3c64xx_set_xtal_freq(12000000);
+ s3c24xx_init_uarts(ncp_uartcfgs, ARRAY_SIZE(ncp_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+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 */
+ .atag_offset = 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = ncp_map_io,
+ .init_machine = ncp_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+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 000000000..85fa9598b
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-real6410.c
@@ -0,0 +1,340 @@
+/* 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/serial_s3c.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-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/adc.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/touchscreen-s3c2410.h>
+
+#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "regs-modem.h"
+#include "regs-srom.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] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1, 2),
+ [1] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1 + 4, 2),
+ [2] = DEFINE_RES_NAMED(S3C_EINT(7), 1, NULL, 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_lcd_type0_fb_win = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 480,
+ .yres = 272,
+};
+
+static struct fb_videomode real6410_lcd_type0_timing = {
+ /* 4.3" 480x272 */
+ .left_margin = 3,
+ .right_margin = 2,
+ .upper_margin = 1,
+ .lower_margin = 1,
+ .hsync_len = 40,
+ .vsync_len = 1,
+};
+
+static struct s3c_fb_pd_win real6410_lcd_type1_fb_win = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 800,
+ .yres = 480,
+};
+
+static struct fb_videomode real6410_lcd_type1_timing = {
+ /* 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,
+};
+
+static struct s3c_fb_platdata real6410_lcd_pdata[] __initdata = {
+ {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &real6410_lcd_type0_timing,
+ .win[0] = &real6410_lcd_type0_fb_win,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ }, {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &real6410_lcd_type1_timing,
+ .win[0] = &real6410_lcd_type1_fb_win,
+ .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 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));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ /* 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_lcd_pdata))
+ 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);
+
+ printk(KERN_INFO "REAL6410: selected LCD display is %dx%d\n",
+ real6410_lcd_pdata[features.lcd_index].win[0]->xres,
+ real6410_lcd_pdata[features.lcd_index].win[0]->yres);
+
+ s3c_fb_set_platdata(&real6410_lcd_pdata[features.lcd_index]);
+ s3c_nand_set_platdata(&real6410_nand_info);
+ s3c24xx_ts_set_platdata(NULL);
+
+ /* 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> */
+ .atag_offset = 0x100,
+
+ .init_irq = s3c6410_init_irq,
+ .map_io = real6410_map_io,
+ .init_machine = real6410_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c
new file mode 100644
index 000000000..2fddf3819
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c
@@ -0,0 +1,76 @@
+/*
+ * Samsung's S3C64XX flattened device tree enabled machine
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@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/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/system_misc.h>
+
+#include <plat/cpu.h>
+#include <plat/watchdog-reset.h>
+
+#include <mach/map.h>
+
+#include "common.h"
+
+/*
+ * IO mapping for shared system controller IP.
+ *
+ * FIXME: Make remaining drivers use dynamic mapping.
+ */
+static struct map_desc s3c64xx_dt_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S3C_VA_SYS,
+ .pfn = __phys_to_pfn(S3C64XX_PA_SYSCON),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init s3c64xx_dt_map_io(void)
+{
+ debug_ll_io_init();
+ iotable_init(s3c64xx_dt_iodesc, ARRAY_SIZE(s3c64xx_dt_iodesc));
+
+ s3c64xx_init_cpu();
+
+ if (!soc_is_s3c64xx())
+ panic("SoC is not S3C64xx!");
+}
+
+static void __init s3c64xx_dt_init_machine(void)
+{
+ samsung_wdt_reset_of_init();
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static void s3c64xx_dt_restart(enum reboot_mode mode, const char *cmd)
+{
+ if (mode != REBOOT_SOFT)
+ samsung_wdt_reset();
+
+ /* if all else fails, or mode was for soft, jump to 0 */
+ soft_restart(0);
+}
+
+static char const *s3c64xx_dt_compat[] __initdata = {
+ "samsung,s3c6400",
+ "samsung,s3c6410",
+ NULL
+};
+
+DT_MACHINE_START(S3C6400_DT, "Samsung S3C64xx (Flattened Device Tree)")
+ /* Maintainer: Tomasz Figa <tomasz.figa@gmail.com> */
+ .dt_compat = s3c64xx_dt_compat,
+ .map_io = s3c64xx_dt_map_io,
+ .init_machine = s3c64xx_dt_init_machine,
+ .restart = s3c64xx_dt_restart,
+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 000000000..b3d13537a
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smartq.c
@@ -0,0 +1,400 @@
+/*
+ * 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/serial_s3c.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/usb/gpio_vbus.h>
+#include <linux/platform_data/s3c-hsotg.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <plat/gpio-cfg.h>
+#include <linux/platform_data/hwmon-s3c.h>
+#include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <plat/sdhci.h>
+#include <linux/platform_data/touchscreen-s3c2410.h>
+
+#include <video/platform_lcd.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "regs-modem.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_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),
+ .enable_gpio = -1,
+ .init = smartq_bl_init,
+};
+
+static struct platform_device smartq_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &samsung_device_pwm.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 struct s3c_hsotg_plat smartq_hsotg_pdata;
+
+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,
+ &samsung_device_pwm,
+ &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_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));
+ s3c64xx_set_xtal_freq(12000000);
+ s3c64xx_set_xusbxti_freq(12000000);
+ s3c24xx_init_uarts(smartq_uartcfgs, ARRAY_SIZE(smartq_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ smartq_lcd_mode_set();
+}
+
+void __init smartq_machine_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ s3c_hsotg_set_platdata(&smartq_hsotg_pdata);
+ 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_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 000000000..8e8b693db
--- /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 000000000..33224ab36
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smartq5.c
@@ -0,0 +1,161 @@
+/*
+ * 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 <video/samsung_fimd.h>
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+#include <plat/samsung-time.h>
+
+#include "common.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 = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 800,
+ .yres = 480,
+};
+
+static struct fb_videomode smartq5_lcd_timing = {
+ .left_margin = 216,
+ .right_margin = 40,
+ .upper_margin = 35,
+ .lower_margin = 10,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ .refresh = 80,
+};
+
+static struct s3c_fb_platdata smartq5_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &smartq5_lcd_timing,
+ .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> */
+ .atag_offset = 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = smartq_map_io,
+ .init_machine = smartq5_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+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 000000000..fc7fece22
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smartq7.c
@@ -0,0 +1,177 @@
+/*
+ * 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 <video/samsung_fimd.h>
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+#include <plat/samsung-time.h>
+
+#include "common.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 = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 800,
+ .yres = 480,
+};
+
+static struct fb_videomode smartq7_lcd_timing = {
+ .left_margin = 3,
+ .right_margin = 5,
+ .upper_margin = 1,
+ .lower_margin = 20,
+ .hsync_len = 10,
+ .vsync_len = 3,
+ .xres = 800,
+ .yres = 480,
+ .refresh = 80,
+};
+
+static struct s3c_fb_platdata smartq7_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &smartq7_lcd_timing,
+ .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> */
+ .atag_offset = 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = smartq_map_io,
+ .init_machine = smartq7_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+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 000000000..6f425126a
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c
@@ -0,0 +1,97 @@
+/* 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/serial_s3c.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/devs.h>
+#include <plat/cpu.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <mach/gpio-samsung.h>
+#include <plat/samsung-time.h>
+
+#include "common.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));
+ s3c64xx_set_xtal_freq(12000000);
+ s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+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> */
+ .atag_offset = 0x100,
+
+ .init_irq = s3c6400_init_irq,
+ .map_io = smdk6400_map_io,
+ .init_machine = smdk6400_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+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 000000000..b7447a922
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -0,0 +1,710 @@
+/* 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/serial_s3c.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>
+#include <linux/platform_data/s3c-hsotg.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 <video/samsung_fimd.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 <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+#include <linux/platform_data/ata-samsung_cf.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/adc.h>
+#include <linux/platform_data/touchscreen-s3c2410.h>
+#include <plat/keypad.h>
+#include <plat/backlight.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "regs-modem.h"
+#include "regs-srom.h"
+#include "regs-sys.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 = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 800,
+ .yres = 480,
+ .virtual_y = 480 * 2,
+ .virtual_x = 800,
+};
+
+static struct fb_videomode smdk6410_lcd_timing = {
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+};
+
+/* 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,
+ .vtiming = &smdk6410_lcd_timing,
+ .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] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1, SZ_64K),
+ [1] = DEFINE_RES_NAMED(S3C_EINT(10), 1, NULL, 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[] = {
+ REGULATOR_SUPPLY("PVDD", "0-001b"),
+ REGULATOR_SUPPLY("AVDD", "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 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,
+ &samsung_device_pwm,
+ &s3c_device_usb_hsotg,
+ &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,
+};
+
+#ifdef CONFIG_REGULATOR
+/* ARM core */
+static struct regulator_consumer_supply smdk6410_vddarm_consumers[] = {
+ REGULATOR_SUPPLY("vddarm", NULL),
+};
+
+/* 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[] = {
+ REGULATOR_SUPPLY("DVDD", "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[] = {
+ REGULATOR_SUPPLY("DVDD", "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,
+
+ .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 */
+};
+
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdk6410_bl_gpio_info = {
+ .no = S3C64XX_GPF(15),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdk6410_bl_data = {
+ .pwm_id = 1,
+ .enable_gpio = -1,
+};
+
+static struct s3c_hsotg_plat smdk6410_hsotg_pdata;
+
+static void __init smdk6410_map_io(void)
+{
+ u32 tmp;
+
+ s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc));
+ s3c64xx_set_xtal_freq(12000000);
+ s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ /* 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);
+ s3c_hsotg_set_platdata(&smdk6410_hsotg_pdata);
+
+ samsung_keypad_set_platdata(&smdk6410_keypad_data);
+
+ s3c24xx_ts_set_platdata(NULL);
+
+ /* 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));
+
+ samsung_bl_set(&smdk6410_bl_gpio_info, &smdk6410_bl_data);
+}
+
+MACHINE_START(SMDK6410, "SMDK6410")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .atag_offset = 0x100,
+
+ .init_irq = s3c6410_init_irq,
+ .map_io = smdk6410_map_io,
+ .init_machine = smdk6410_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/pl080.c b/arch/arm/mach-s3c64xx/pl080.c
new file mode 100644
index 000000000..901a984bd
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/pl080.c
@@ -0,0 +1,244 @@
+/*
+ * Samsung's S3C64XX generic DMA support using amba-pl08x driver.
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@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/amba/bus.h>
+#include <linux/amba/pl080.h>
+#include <linux/amba/pl08x.h>
+#include <linux/of.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include "regs-sys.h"
+
+static int pl08x_get_xfer_signal(const struct pl08x_channel_data *cd)
+{
+ return cd->min_signal;
+}
+
+static void pl08x_put_xfer_signal(const struct pl08x_channel_data *cd, int ch)
+{
+}
+
+/*
+ * DMA0
+ */
+
+static struct pl08x_channel_data s3c64xx_dma0_info[] = {
+ {
+ .bus_id = "uart0_tx",
+ .min_signal = 0,
+ .max_signal = 0,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart0_rx",
+ .min_signal = 1,
+ .max_signal = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart1_tx",
+ .min_signal = 2,
+ .max_signal = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart1_rx",
+ .min_signal = 3,
+ .max_signal = 3,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart2_tx",
+ .min_signal = 4,
+ .max_signal = 4,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart2_rx",
+ .min_signal = 5,
+ .max_signal = 5,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart3_tx",
+ .min_signal = 6,
+ .max_signal = 6,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart3_rx",
+ .min_signal = 7,
+ .max_signal = 7,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "pcm0_tx",
+ .min_signal = 8,
+ .max_signal = 8,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "pcm0_rx",
+ .min_signal = 9,
+ .max_signal = 9,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2s0_tx",
+ .min_signal = 10,
+ .max_signal = 10,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2s0_rx",
+ .min_signal = 11,
+ .max_signal = 11,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "spi0_tx",
+ .min_signal = 12,
+ .max_signal = 12,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "spi0_rx",
+ .min_signal = 13,
+ .max_signal = 13,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2s2_tx",
+ .min_signal = 14,
+ .max_signal = 14,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2s2_rx",
+ .min_signal = 15,
+ .max_signal = 15,
+ .periph_buses = PL08X_AHB2,
+ }
+};
+
+struct pl08x_platform_data s3c64xx_dma0_plat_data = {
+ .memcpy_channel = {
+ .bus_id = "memcpy",
+ .cctl_memcpy =
+ (PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT |
+ PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT |
+ PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT |
+ PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT |
+ PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE |
+ PL080_CONTROL_PROT_SYS),
+ },
+ .lli_buses = PL08X_AHB1,
+ .mem_buses = PL08X_AHB1,
+ .get_xfer_signal = pl08x_get_xfer_signal,
+ .put_xfer_signal = pl08x_put_xfer_signal,
+ .slave_channels = s3c64xx_dma0_info,
+ .num_slave_channels = ARRAY_SIZE(s3c64xx_dma0_info),
+};
+
+static AMBA_AHB_DEVICE(s3c64xx_dma0, "dma-pl080s.0", 0,
+ 0x75000000, {IRQ_DMA0}, &s3c64xx_dma0_plat_data);
+
+/*
+ * DMA1
+ */
+
+static struct pl08x_channel_data s3c64xx_dma1_info[] = {
+ {
+ .bus_id = "pcm1_tx",
+ .min_signal = 0,
+ .max_signal = 0,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "pcm1_rx",
+ .min_signal = 1,
+ .max_signal = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2s1_tx",
+ .min_signal = 2,
+ .max_signal = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2s1_rx",
+ .min_signal = 3,
+ .max_signal = 3,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "spi1_tx",
+ .min_signal = 4,
+ .max_signal = 4,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "spi1_rx",
+ .min_signal = 5,
+ .max_signal = 5,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ac97_out",
+ .min_signal = 6,
+ .max_signal = 6,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ac97_in",
+ .min_signal = 7,
+ .max_signal = 7,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ac97_mic",
+ .min_signal = 8,
+ .max_signal = 8,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "pwm",
+ .min_signal = 9,
+ .max_signal = 9,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "irda",
+ .min_signal = 10,
+ .max_signal = 10,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "external",
+ .min_signal = 11,
+ .max_signal = 11,
+ .periph_buses = PL08X_AHB2,
+ },
+};
+
+struct pl08x_platform_data s3c64xx_dma1_plat_data = {
+ .memcpy_channel = {
+ .bus_id = "memcpy",
+ .cctl_memcpy =
+ (PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT |
+ PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT |
+ PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT |
+ PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT |
+ PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE |
+ PL080_CONTROL_PROT_SYS),
+ },
+ .lli_buses = PL08X_AHB1,
+ .mem_buses = PL08X_AHB1,
+ .get_xfer_signal = pl08x_get_xfer_signal,
+ .put_xfer_signal = pl08x_put_xfer_signal,
+ .slave_channels = s3c64xx_dma1_info,
+ .num_slave_channels = ARRAY_SIZE(s3c64xx_dma1_info),
+};
+
+static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0,
+ 0x75100000, {IRQ_DMA1}, &s3c64xx_dma1_plat_data);
+
+static int __init s3c64xx_pl080_init(void)
+{
+ /* Set all DMA configuration to be DMA, not SDMA */
+ writel(0xffffff, S3C64XX_SDMA_SEL);
+
+ if (of_have_populated_dt())
+ return 0;
+
+ amba_device_register(&s3c64xx_dma0_device, &iomem_resource);
+ amba_device_register(&s3c64xx_dma1_device, &iomem_resource);
+
+ return 0;
+}
+arch_initcall(s3c64xx_pl080_init);
diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
new file mode 100644
index 000000000..75b14e756
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -0,0 +1,351 @@
+/* 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 <linux/gpio.h>
+#include <linux/pm_domain.h>
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#include <plat/devs.h>
+#include <plat/pm.h>
+#include <plat/wakeup-mask.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+#include <mach/gpio-samsung.h>
+
+#include "regs-gpio-memport.h"
+#include "regs-modem.h"
+#include "regs-sys.h"
+#include "regs-syscon-power.h"
+
+struct s3c64xx_pm_domain {
+ char *const name;
+ u32 ena;
+ u32 pwr_stat;
+ struct generic_pm_domain pd;
+};
+
+static int s3c64xx_pd_off(struct generic_pm_domain *domain)
+{
+ struct s3c64xx_pm_domain *pd;
+ u32 val;
+
+ pd = container_of(domain, struct s3c64xx_pm_domain, pd);
+
+ val = __raw_readl(S3C64XX_NORMAL_CFG);
+ val &= ~(pd->ena);
+ __raw_writel(val, S3C64XX_NORMAL_CFG);
+
+ return 0;
+}
+
+static int s3c64xx_pd_on(struct generic_pm_domain *domain)
+{
+ struct s3c64xx_pm_domain *pd;
+ u32 val;
+ long retry = 1000000L;
+
+ pd = container_of(domain, struct s3c64xx_pm_domain, pd);
+
+ val = __raw_readl(S3C64XX_NORMAL_CFG);
+ val |= pd->ena;
+ __raw_writel(val, S3C64XX_NORMAL_CFG);
+
+ /* Not all domains provide power status readback */
+ if (pd->pwr_stat) {
+ do {
+ cpu_relax();
+ if (__raw_readl(S3C64XX_BLK_PWR_STAT) & pd->pwr_stat)
+ break;
+ } while (retry--);
+
+ if (!retry) {
+ pr_err("Failed to start domain %s\n", pd->name);
+ return -EBUSY;
+ }
+ }
+
+ return 0;
+}
+
+static struct s3c64xx_pm_domain s3c64xx_pm_irom = {
+ .name = "IROM",
+ .ena = S3C64XX_NORMALCFG_IROM_ON,
+ .pd = {
+ .power_off = s3c64xx_pd_off,
+ .power_on = s3c64xx_pd_on,
+ },
+};
+
+static struct s3c64xx_pm_domain s3c64xx_pm_etm = {
+ .name = "ETM",
+ .ena = S3C64XX_NORMALCFG_DOMAIN_ETM_ON,
+ .pwr_stat = S3C64XX_BLKPWRSTAT_ETM,
+ .pd = {
+ .power_off = s3c64xx_pd_off,
+ .power_on = s3c64xx_pd_on,
+ },
+};
+
+static struct s3c64xx_pm_domain s3c64xx_pm_s = {
+ .name = "S",
+ .ena = S3C64XX_NORMALCFG_DOMAIN_S_ON,
+ .pwr_stat = S3C64XX_BLKPWRSTAT_S,
+ .pd = {
+ .power_off = s3c64xx_pd_off,
+ .power_on = s3c64xx_pd_on,
+ },
+};
+
+static struct s3c64xx_pm_domain s3c64xx_pm_f = {
+ .name = "F",
+ .ena = S3C64XX_NORMALCFG_DOMAIN_F_ON,
+ .pwr_stat = S3C64XX_BLKPWRSTAT_F,
+ .pd = {
+ .power_off = s3c64xx_pd_off,
+ .power_on = s3c64xx_pd_on,
+ },
+};
+
+static struct s3c64xx_pm_domain s3c64xx_pm_p = {
+ .name = "P",
+ .ena = S3C64XX_NORMALCFG_DOMAIN_P_ON,
+ .pwr_stat = S3C64XX_BLKPWRSTAT_P,
+ .pd = {
+ .power_off = s3c64xx_pd_off,
+ .power_on = s3c64xx_pd_on,
+ },
+};
+
+static struct s3c64xx_pm_domain s3c64xx_pm_i = {
+ .name = "I",
+ .ena = S3C64XX_NORMALCFG_DOMAIN_I_ON,
+ .pwr_stat = S3C64XX_BLKPWRSTAT_I,
+ .pd = {
+ .power_off = s3c64xx_pd_off,
+ .power_on = s3c64xx_pd_on,
+ },
+};
+
+static struct s3c64xx_pm_domain s3c64xx_pm_g = {
+ .name = "G",
+ .ena = S3C64XX_NORMALCFG_DOMAIN_G_ON,
+ .pd = {
+ .power_off = s3c64xx_pd_off,
+ .power_on = s3c64xx_pd_on,
+ },
+};
+
+static struct s3c64xx_pm_domain s3c64xx_pm_v = {
+ .name = "V",
+ .ena = S3C64XX_NORMALCFG_DOMAIN_V_ON,
+ .pwr_stat = S3C64XX_BLKPWRSTAT_V,
+ .pd = {
+ .power_off = s3c64xx_pd_off,
+ .power_on = s3c64xx_pd_on,
+ },
+};
+
+static struct s3c64xx_pm_domain *s3c64xx_always_on_pm_domains[] = {
+ &s3c64xx_pm_irom,
+};
+
+static struct s3c64xx_pm_domain *s3c64xx_pm_domains[] = {
+ &s3c64xx_pm_etm,
+ &s3c64xx_pm_g,
+ &s3c64xx_pm_v,
+ &s3c64xx_pm_i,
+ &s3c64xx_pm_p,
+ &s3c64xx_pm_s,
+ &s3c64xx_pm_f,
+};
+
+#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
+
+#ifdef CONFIG_PM_SLEEP
+static struct sleep_save core_save[] = {
+ SAVE_ITEM(S3C64XX_MEM0DRVCON),
+ SAVE_ITEM(S3C64XX_MEM1DRVCON),
+};
+
+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),
+
+ SAVE_ITEM(S3C64XX_SDMA_SEL),
+ SAVE_ITEM(S3C64XX_MODEM_MIFPCON),
+
+ SAVE_ITEM(S3C64XX_NORMAL_CFG),
+};
+
+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));
+}
+#endif
+
+/* 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 int s3c64xx_cpu_suspend(unsigned long arg)
+{
+ 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 */
+
+ pr_info("Failed to suspend the system\n");
+ return 1; /* Aborting suspend */
+}
+
+/* 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);
+}
+
+int __init s3c64xx_pm_init(void)
+{
+ int i;
+
+ s3c_pm_init();
+
+ for (i = 0; i < ARRAY_SIZE(s3c64xx_always_on_pm_domains); i++)
+ pm_genpd_init(&s3c64xx_always_on_pm_domains[i]->pd,
+ &pm_domain_always_on_gov, false);
+
+ for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); i++)
+ pm_genpd_init(&s3c64xx_pm_domains[i]->pd, NULL, false);
+
+#ifdef CONFIG_S3C_DEV_FB
+ if (dev_get_platdata(&s3c_device_fb.dev))
+ pm_genpd_add_device(&s3c64xx_pm_f.pd, &s3c_device_fb.dev);
+#endif
+
+ return 0;
+}
+
+static __init int s3c64xx_pm_initcall(void)
+{
+ pm_cpu_prep = s3c64xx_pm_prepare;
+ pm_cpu_sleep = s3c64xx_cpu_suspend;
+
+#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_initcall);
diff --git a/arch/arm/mach-s3c64xx/regs-gpio-memport.h b/arch/arm/mach-s3c64xx/regs-gpio-memport.h
new file mode 100644
index 000000000..b92759301
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/regs-gpio-memport.h
@@ -0,0 +1,24 @@
+/*
+ * 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 __MACH_S3C64XX_REGS_GPIO_MEMPORT_H
+#define __MACH_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 /* __MACH_S3C64XX_REGS_GPIO_MEMPORT_H */
+
diff --git a/arch/arm/mach-s3c64xx/regs-modem.h b/arch/arm/mach-s3c64xx/regs-modem.h
new file mode 100644
index 000000000..073cdd3a0
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/regs-modem.h
@@ -0,0 +1,30 @@
+/*
+ * 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 __MACH_S3C64XX_REGS_MODEM_H
+#define __MACH_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 /* __MACH_S3C64XX_REGS_MODEM_H */
diff --git a/arch/arm/mach-s3c64xx/regs-srom.h b/arch/arm/mach-s3c64xx/regs-srom.h
new file mode 100644
index 000000000..d56f3386e
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/regs-srom.h
@@ -0,0 +1,58 @@
+/*
+ * 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 __MACH_S3C64XX_REGS_SROM_H
+#define __MACH_S3C64XX_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 /* __MACH_S3C64XX_REGS_SROM_H */
diff --git a/arch/arm/mach-s3c64xx/regs-sys.h b/arch/arm/mach-s3c64xx/regs-sys.h
new file mode 100644
index 000000000..8c411fbb0
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/regs-sys.h
@@ -0,0 +1,30 @@
+/*
+ * 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 __MACH_S3C64XX_REGS_SYS_H
+#define __MACH_S3C64XX_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_SDMA_SEL S3C_SYSREG(0x110)
+
+#define S3C64XX_OTHERS S3C_SYSREG(0x900)
+
+#define S3C64XX_OTHERS_USBMASK (1 << 16)
+#define S3C64XX_OTHERS_SYNCMUXSEL (1 << 6)
+
+#endif /* __MACH_S3C64XX_REGS_SYS_H */
diff --git a/arch/arm/mach-s3c64xx/regs-syscon-power.h b/arch/arm/mach-s3c64xx/regs-syscon-power.h
new file mode 100644
index 000000000..6e16b3404
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/regs-syscon-power.h
@@ -0,0 +1,115 @@
+/*
+ * 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 __MACH_S3C64XX_REGS_SYSCON_POWER_H
+#define __MACH_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 /* __MACH_S3C64XX_REGS_SYSCON_POWER_H */
diff --git a/arch/arm/mach-s3c64xx/s3c6400.c b/arch/arm/mach-s3c64xx/s3c6400.c
new file mode 100644
index 000000000..1ce48c54c
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/s3c6400.c
@@ -0,0 +1,97 @@
+/* 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.
+*/
+
+/*
+ * NOTE: Code in this file is not used when booting with Device Tree support.
+ */
+
+#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/device.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/of.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/cpu.h>
+#include <plat/devs.h>
+#include <plat/sdhci.h>
+#include <plat/iic-core.h>
+#include <plat/onenand-core.h>
+
+#include "common.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_irq(void)
+{
+ /* VIC0 does not have IRQS 5..7,
+ * VIC1 is fully populated. */
+ s3c64xx_init_irq(~0 & ~(0xf << 5), ~0);
+}
+
+static struct bus_type s3c6400_subsys = {
+ .name = "s3c6400-core",
+ .dev_name = "s3c6400-core",
+};
+
+static struct device s3c6400_dev = {
+ .bus = &s3c6400_subsys,
+};
+
+static int __init s3c6400_core_init(void)
+{
+ /* Not applicable when using DT. */
+ if (of_have_populated_dt())
+ return 0;
+
+ return subsys_system_register(&s3c6400_subsys, NULL);
+}
+
+core_initcall(s3c6400_core_init);
+
+int __init s3c6400_init(void)
+{
+ printk("S3C6400: Initialising architecture\n");
+
+ return device_register(&s3c6400_dev);
+}
diff --git a/arch/arm/mach-s3c64xx/s3c6410.c b/arch/arm/mach-s3c64xx/s3c6410.c
new file mode 100644
index 000000000..b2a793054
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/s3c6410.c
@@ -0,0 +1,100 @@
+/* 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.
+*/
+
+/*
+ * NOTE: Code in this file is not used when booting with Device Tree support.
+ */
+
+#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/device.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/of.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/cpu.h>
+#include <plat/devs.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 "common.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_irq(void)
+{
+ /* VIC0 is missing IRQ7, VIC1 is fully populated. */
+ s3c64xx_init_irq(~0 & ~(1 << 7), ~0);
+}
+
+struct bus_type s3c6410_subsys = {
+ .name = "s3c6410-core",
+ .dev_name = "s3c6410-core",
+};
+
+static struct device s3c6410_dev = {
+ .bus = &s3c6410_subsys,
+};
+
+static int __init s3c6410_core_init(void)
+{
+ /* Not applicable when using DT. */
+ if (of_have_populated_dt())
+ return 0;
+
+ return subsys_system_register(&s3c6410_subsys, NULL);
+}
+
+core_initcall(s3c6410_core_init);
+
+int __init s3c6410_init(void)
+{
+ printk("S3C6410: Initialising architecture\n");
+
+ return device_register(&s3c6410_dev);
+}
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 000000000..9d17bff12
--- /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 <plat/fb.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-samsung.h>
+
+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 000000000..4b8c1cfdd
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-i2c0.c
@@ -0,0 +1,29 @@
+/* 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 <linux/platform_data/i2c-s3c2410.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-samsung.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 000000000..cd1df71ee
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-i2c1.c
@@ -0,0 +1,29 @@
+/* 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 <linux/platform_data/i2c-s3c2410.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-samsung.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 000000000..689fb72e7
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-ide.c
@@ -0,0 +1,44 @@
+/* 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 <mach/gpio-samsung.h>
+#include <linux/platform_data/ata-samsung_cf.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 000000000..6ad9a89df
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-keypad.c
@@ -0,0 +1,25 @@
+/* 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>
+#include <mach/gpio-samsung.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 000000000..f426b7a16
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
@@ -0,0 +1,58 @@
+/* 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>
+#include <mach/gpio-samsung.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-spi.c b/arch/arm/mach-s3c64xx/setup-spi.c
new file mode 100644
index 000000000..5fd1a315c
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-spi.c
@@ -0,0 +1,31 @@
+/* linux/arch/arm/mach-s3c64xx/setup-spi.c
+ *
+ * Copyright (C) 2011 Samsung Electronics 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 <plat/gpio-cfg.h>
+#include <mach/gpio-samsung.h>
+
+#ifdef CONFIG_S3C64XX_DEV_SPI0
+int s3c64xx_spi0_cfg_gpio(void)
+{
+ s3c_gpio_cfgall_range(S3C64XX_GPC(0), 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI1
+int s3c64xx_spi1_cfg_gpio(void)
+{
+ s3c_gpio_cfgall_range(S3C64XX_GPC(4), 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-s3c64xx/setup-usb-phy.c b/arch/arm/mach-s3c64xx/setup-usb-phy.c
new file mode 100644
index 000000000..ca960bda0
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-usb-phy.c
@@ -0,0 +1,91 @@
+/*
+ * 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/map.h>
+#include <plat/cpu.h>
+#include <plat/regs-usb-hsotg-phy.h>
+#include <plat/usb-phy.h>
+
+#include "regs-sys.h"
+
+static int s3c_usb_otgphy_init(struct platform_device *pdev)
+{
+ struct clk *xusbxti;
+ u32 phyclk;
+
+ writel(readl(S3C64XX_OTHERS) | S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS);
+
+ /* set clock frequency for PLL */
+ phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK;
+
+ xusbxti = clk_get(&pdev->dev, "xusbxti");
+ if (xusbxti && !IS_ERR(xusbxti)) {
+ switch (clk_get_rate(xusbxti)) {
+ case 12 * MHZ:
+ phyclk |= S3C_PHYCLK_CLKSEL_12M;
+ break;
+ case 24 * MHZ:
+ phyclk |= S3C_PHYCLK_CLKSEL_24M;
+ break;
+ default:
+ case 48 * MHZ:
+ /* default reference clock */
+ break;
+ }
+ clk_put(xusbxti);
+ }
+
+ /* TODO: select external clock/oscillator */
+ writel(phyclk | S3C_PHYCLK_CLK_FORCE, S3C_PHYCLK);
+
+ /* set to normal OTG PHY */
+ writel((readl(S3C_PHYPWR) & ~S3C_PHYPWR_NORMAL_MASK), S3C_PHYPWR);
+ mdelay(1);
+
+ /* reset OTG PHY and Link */
+ writel(S3C_RSTCON_PHY | S3C_RSTCON_HCLK | S3C_RSTCON_PHYCLK,
+ S3C_RSTCON);
+ udelay(20); /* at-least 10uS */
+ writel(0, S3C_RSTCON);
+
+ return 0;
+}
+
+static int s3c_usb_otgphy_exit(struct platform_device *pdev)
+{
+ writel((readl(S3C_PHYPWR) | S3C_PHYPWR_ANALOG_POWERDOWN |
+ S3C_PHYPWR_OTG_DISABLE), S3C_PHYPWR);
+
+ writel(readl(S3C64XX_OTHERS) & ~S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS);
+
+ return 0;
+}
+
+int s5p_usb_phy_init(struct platform_device *pdev, int type)
+{
+ if (type == USB_PHY_TYPE_DEVICE)
+ return s3c_usb_otgphy_init(pdev);
+
+ return -EINVAL;
+}
+
+int s5p_usb_phy_exit(struct platform_device *pdev, int type)
+{
+ if (type == USB_PHY_TYPE_DEVICE)
+ return s3c_usb_otgphy_exit(pdev);
+
+ return -EINVAL;
+}
diff --git a/arch/arm/mach-s3c64xx/sleep.S b/arch/arm/mach-s3c64xx/sleep.S
new file mode 100644
index 000000000..34313f9c8
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/sleep.S
@@ -0,0 +1,72 @@
+/* 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
+
+ /* 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-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
new file mode 100644
index 000000000..330bfc8fc
--- /dev/null
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -0,0 +1,34 @@
+# 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
+
+config ARCH_S5PV210
+ bool "Samsung S5PV210/S5PC110" if ARCH_MULTI_V7
+ select ARCH_HAS_HOLES_MEMORYMODEL
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_VIC
+ select CLKSRC_SAMSUNG_PWM
+ select COMMON_CLK_SAMSUNG
+ select HAVE_S3C2410_I2C if I2C
+ select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select HAVE_S3C_RTC if RTC_CLASS
+ select PINCTRL
+ select PINCTRL_EXYNOS
+ help
+ Samsung S5PV210/S5PC110 series based systems
+
+if ARCH_S5PV210
+
+config CPU_S5PV210
+ def_bool y
+ select ARM_AMBA
+ select PL330_DMA if DMADEVICES
+ help
+ Enable S5PV210 CPU support
+
+endif
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
new file mode 100644
index 000000000..72b9e9671
--- /dev/null
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -0,0 +1,16 @@
+# arch/arm/mach-s5pv210/Makefile
+#
+# Copyright (c) 2010 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/$(src)/include -I$(srctree)/arch/arm/plat-samsung/include
+
+# Core
+
+obj-$(CONFIG_PM_SLEEP) += pm.o sleep.o
+
+# machine support
+
+obj-y += s5pv210.o
diff --git a/arch/arm/mach-s5pv210/common.h b/arch/arm/mach-s5pv210/common.h
new file mode 100644
index 000000000..2ad387c1e
--- /dev/null
+++ b/arch/arm/mach-s5pv210/common.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Common Header for S5PV210 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_S5PV210_COMMON_H
+#define __ARCH_ARM_MACH_S5PV210_COMMON_H
+
+#ifdef CONFIG_PM_SLEEP
+u32 exynos_get_eint_wake_mask(void);
+void s5pv210_cpu_resume(void);
+void s5pv210_pm_init(void);
+#else
+static inline void s5pv210_pm_init(void) {}
+#endif
+
+#endif /* __ARCH_ARM_MACH_S5PV210_COMMON_H */
diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c
new file mode 100644
index 000000000..21b4b13c5
--- /dev/null
+++ b/arch/arm/mach-s5pv210/pm.c
@@ -0,0 +1,179 @@
+/* linux/arch/arm/mach-s5pv210/pm.c
+ *
+ * Copyright (c) 2010-2014 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 <asm/cacheflush.h>
+#include <asm/suspend.h>
+
+#include <plat/pm-common.h>
+
+#include "common.h"
+#include "regs-clock.h"
+
+static struct sleep_save s5pv210_core_save[] = {
+ /* Clock ETC */
+ SAVE_ITEM(S5P_MDNIE_SEL),
+};
+
+/*
+ * VIC wake-up support (TODO)
+ */
+static u32 s5pv210_irqwake_intmask = 0xffffffff;
+
+/*
+ * Suspend helpers.
+ */
+static int s5pv210_cpu_suspend(unsigned long arg)
+{
+ 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));
+
+ pr_info("Failed to suspend the system\n");
+ return 1; /* Aborting suspend */
+}
+
+static void s5pv210_pm_prepare(void)
+{
+ unsigned int tmp;
+
+ /* Set wake-up mask registers */
+ __raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
+ __raw_writel(s5pv210_irqwake_intmask, S5P_WAKEUP_MASK);
+
+ /* ensure at least INFORM0 has the resume address */
+ __raw_writel(virt_to_phys(s5pv210_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));
+}
+
+/*
+ * Suspend operations.
+ */
+static int s5pv210_suspend_enter(suspend_state_t state)
+{
+ int ret;
+
+ s3c_pm_debug_init();
+
+ S3C_PMDBG("%s: suspending the system...\n", __func__);
+
+ S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__,
+ s5pv210_irqwake_intmask, exynos_get_eint_wake_mask());
+
+ if (s5pv210_irqwake_intmask == -1U
+ && exynos_get_eint_wake_mask() == -1U) {
+ pr_err("%s: No wake-up sources!\n", __func__);
+ pr_err("%s: Aborting sleep\n", __func__);
+ return -EINVAL;
+ }
+
+ s3c_pm_save_uarts();
+ s5pv210_pm_prepare();
+ flush_cache_all();
+ s3c_pm_check_store();
+
+ ret = cpu_suspend(0, s5pv210_cpu_suspend);
+ if (ret)
+ return ret;
+
+ s3c_pm_restore_uarts();
+
+ S3C_PMDBG("%s: wakeup stat: %08x\n", __func__,
+ __raw_readl(S5P_WAKEUP_STAT));
+
+ s3c_pm_check_restore();
+
+ S3C_PMDBG("%s: resuming the system...\n", __func__);
+
+ return 0;
+}
+
+static int s5pv210_suspend_prepare(void)
+{
+ s3c_pm_check_prepare();
+
+ return 0;
+}
+
+static void s5pv210_suspend_finish(void)
+{
+ s3c_pm_check_cleanup();
+}
+
+static const struct platform_suspend_ops s5pv210_suspend_ops = {
+ .enter = s5pv210_suspend_enter,
+ .prepare = s5pv210_suspend_prepare,
+ .finish = s5pv210_suspend_finish,
+ .valid = suspend_valid_only_mem,
+};
+
+/*
+ * Syscore operations used to delay restore of certain registers.
+ */
+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,
+};
+
+/*
+ * Initialization entry point.
+ */
+void __init s5pv210_pm_init(void)
+{
+ register_syscore_ops(&s5pv210_pm_syscore_ops);
+ suspend_set_ops(&s5pv210_suspend_ops);
+}
diff --git a/arch/arm/mach-s5pv210/regs-clock.h b/arch/arm/mach-s5pv210/regs-clock.h
new file mode 100644
index 000000000..4640f0f03
--- /dev/null
+++ b/arch/arm/mach-s5pv210/regs-clock.h
@@ -0,0 +1,201 @@
+/*
+ * 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 <plat/map-base.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_HDMI_PHY_CONTROL S5P_CLKREG(0xE804)
+#define S5P_USB_PHY_CONTROL S5P_CLKREG(0xE80C)
+#define S5P_DAC_PHY_CONTROL S5P_CLKREG(0xE810)
+
+#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/s5pv210.c b/arch/arm/mach-s5pv210/s5pv210.c
new file mode 100644
index 000000000..83e656ea9
--- /dev/null
+++ b/arch/arm/mach-s5pv210/s5pv210.c
@@ -0,0 +1,77 @@
+/*
+ * Samsung's S5PC110/S5PV210 flattened device tree enabled machine.
+ *
+ * Copyright (c) 2013-2014 Samsung Electronics Co., Ltd.
+ * Mateusz Krawczuk <m.krawczuk@partner.samsung.com>
+ * Tomasz Figa <t.figa@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/of_fdt.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/system_misc.h>
+
+#include <plat/map-base.h>
+
+#include "common.h"
+#include "regs-clock.h"
+
+static int __init s5pv210_fdt_map_sys(unsigned long node, const char *uname,
+ int depth, void *data)
+{
+ struct map_desc iodesc;
+ const __be32 *reg;
+ int len;
+
+ if (!of_flat_dt_is_compatible(node, "samsung,s5pv210-clock"))
+ return 0;
+
+ reg = of_get_flat_dt_prop(node, "reg", &len);
+ if (reg == NULL || len != (sizeof(unsigned long) * 2))
+ return 0;
+
+ iodesc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
+ iodesc.length = be32_to_cpu(reg[1]) - 1;
+ iodesc.virtual = (unsigned long)S3C_VA_SYS;
+ iodesc.type = MT_DEVICE;
+ iotable_init(&iodesc, 1);
+
+ return 1;
+}
+
+static void __init s5pv210_dt_map_io(void)
+{
+ debug_ll_io_init();
+
+ of_scan_flat_dt(s5pv210_fdt_map_sys, NULL);
+}
+
+static void s5pv210_dt_restart(enum reboot_mode mode, const char *cmd)
+{
+ __raw_writel(0x1, S5P_SWRESET);
+}
+
+static void __init s5pv210_dt_init_late(void)
+{
+ platform_device_register_simple("s5pv210-cpufreq", -1, NULL, 0);
+ s5pv210_pm_init();
+}
+
+static char const *const s5pv210_dt_compat[] __initconst = {
+ "samsung,s5pc110",
+ "samsung,s5pv210",
+ NULL
+};
+
+DT_MACHINE_START(S5PV210_DT, "Samsung S5PC110/S5PV210-based board")
+ .dt_compat = s5pv210_dt_compat,
+ .map_io = s5pv210_dt_map_io,
+ .restart = s5pv210_dt_restart,
+ .init_late = s5pv210_dt_init_late,
+MACHINE_END
diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S
new file mode 100644
index 000000000..dfbfc0f7f
--- /dev/null
+++ b/arch/arm/mach-s5pv210/sleep.S
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PV210 Sleep Code
+ * Based on S3C64XX sleep code by:
+ * Ben Dooks, (c) 2008 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.
+ */
+
+#include <linux/linkage.h>
+
+ .text
+ .align
+
+ /*
+ * 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(s5pv210_cpu_resume)
+ b cpu_resume
+ENDPROC(s5pv210_cpu_resume)
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
new file mode 100644
index 000000000..c6f6ed1cb
--- /dev/null
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -0,0 +1,172 @@
+if ARCH_SA1100
+
+menu "SA11x0 Implementations"
+
+config SA1100_ASSABET
+ bool "Assabet"
+ select ARM_SA1110_CPUFREQ
+ 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 ARM_SA1110_CPUFREQ
+ 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 ARM_SA11x0_CPUFREQ
+ select SHARP_LOCOMO
+ select SHARP_PARAM
+ select SHARP_SCOOP
+ help
+ Say Y here to support the Sharp Zaurus SL5500 PDAs.
+
+config SA1100_H3100
+ bool "Compaq iPAQ H3100"
+ select ARM_SA1110_CPUFREQ
+ select HTC_EGPIO
+ select MFD_IPAQ_MICRO
+ 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 ARM_SA1110_CPUFREQ
+ select HTC_EGPIO
+ select MFD_IPAQ_MICRO
+ 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 ARM_SA1100_CPUFREQ
+ select SA1111
+ help
+ Say Y here if you want to build a kernel for the HP Laboratories
+ BadgePAD 4.
+
+config SA1100_JORNADA720
+ bool "HP Jornada 720"
+ # FIXME: select ARM_SA11x0_CPUFREQ
+ select SA1111
+ 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"
+ depends on SA1100_JORNADA720
+ select SA1100_SSP
+ 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 ARM_SA1100_CPUFREQ
+ help
+ Say Y here to support the HackKit Core CPU Board
+ <http://hackkit.eletztrick.de>;
+
+config SA1100_LART
+ bool "LART"
+ select ARM_SA1100_CPUFREQ
+ 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 ARM_SA1110_CPUFREQ
+ 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 ARM_SA1100_CPUFREQ
+ 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 ARM_SA1100_CPUFREQ
+ 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 ARM_SA1110_CPUFREQ
+ 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 000000000..61ff91e76
--- /dev/null
+++ b/arch/arm/mach-sa1100/Makefile
@@ -0,0 +1,40 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := clock.o generic.o irq.o #nmi-oopser.o
+
+# Specific board support
+obj-$(CONFIG_SA1100_ASSABET) += assabet.o
+obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o
+
+obj-$(CONFIG_SA1100_BADGE4) += badge4.o
+
+obj-$(CONFIG_SA1100_CERF) += 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
+
+obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o
+obj-$(CONFIG_SA1100_JORNADA720_SSP) += jornada720_ssp.o
+
+obj-$(CONFIG_SA1100_LART) += 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
+
+# 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 000000000..f7951aa04
--- /dev/null
+++ b/arch/arm/mach-sa1100/Makefile.boot
@@ -0,0 +1,8 @@
+ifeq ($(CONFIG_SA1111),y)
+ zreladdr-y += 0xc0208000
+else
+ zreladdr-y += 0xc0008000
+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 000000000..d28ecb9ef
--- /dev/null
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -0,0 +1,764 @@
+/*
+ * 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/platform_data/sa11x0-serial.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/ucb1x00.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+
+#include <video/sa1100fb.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.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 <linux/platform_data/irda-sa11x0.h>
+#include <asm/mach/map.h>
+#include <mach/assabet.h>
+#include <linux/platform_data/mfd-mcp-sa11x0.h>
+#include <mach/irqs.h>
+
+#include "generic.h"
+
+#define ASSABET_BCR_DB1110 \
+ (ASSABET_BCR_SPK_OFF | \
+ 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_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);
+
+/*
+ * The codec reset goes to three devices, so we need to release
+ * the rest when any one of these requests it. However, that
+ * causes the ADV7171 to consume around 100mA - more than half
+ * the LCD-blanked power.
+ *
+ * With the ADV7171, LCD and backlight enabled, we go over
+ * budget on the MAX846 Li-Ion charger, and if no Li-Ion battery
+ * is connected, the Assabet crashes.
+ */
+#define RST_UCB1X00 (1 << 0)
+#define RST_UDA1341 (1 << 1)
+#define RST_ADV7171 (1 << 2)
+
+#define SDA GPIO_GPIO(15)
+#define SCK GPIO_GPIO(18)
+#define MOD GPIO_GPIO(17)
+
+static void adv7171_start(void)
+{
+ GPSR = SCK;
+ udelay(1);
+ GPSR = SDA;
+ udelay(2);
+ GPCR = SDA;
+}
+
+static void adv7171_stop(void)
+{
+ GPSR = SCK;
+ udelay(2);
+ GPSR = SDA;
+ udelay(1);
+}
+
+static void adv7171_send(unsigned byte)
+{
+ unsigned i;
+
+ for (i = 0; i < 8; i++, byte <<= 1) {
+ GPCR = SCK;
+ udelay(1);
+ if (byte & 0x80)
+ GPSR = SDA;
+ else
+ GPCR = SDA;
+ udelay(1);
+ GPSR = SCK;
+ udelay(1);
+ }
+ GPCR = SCK;
+ udelay(1);
+ GPSR = SDA;
+ udelay(1);
+ GPDR &= ~SDA;
+ GPSR = SCK;
+ udelay(1);
+ if (GPLR & SDA)
+ printk(KERN_WARNING "No ACK from ADV7171\n");
+ udelay(1);
+ GPCR = SCK | SDA;
+ udelay(1);
+ GPDR |= SDA;
+ udelay(1);
+}
+
+static void adv7171_write(unsigned reg, unsigned val)
+{
+ unsigned gpdr = GPDR;
+ unsigned gplr = GPLR;
+
+ ASSABET_BCR = BCR_value | ASSABET_BCR_AUDIO_ON;
+ udelay(100);
+
+ GPCR = SDA | SCK | MOD; /* clear L3 mode to ensure UDA1341 doesn't respond */
+ GPDR = (GPDR | SCK | MOD) & ~SDA;
+ udelay(10);
+ if (!(GPLR & SDA))
+ printk(KERN_WARNING "Something dragging SDA down?\n");
+ GPDR |= SDA;
+
+ adv7171_start();
+ adv7171_send(0x54);
+ adv7171_send(reg);
+ adv7171_send(val);
+ adv7171_stop();
+
+ /* Restore GPIO state for L3 bus */
+ GPSR = gplr & (SDA | SCK | MOD);
+ GPCR = (~gplr) & (SDA | SCK | MOD);
+ GPDR = gpdr;
+}
+
+static void adv7171_sleep(void)
+{
+ /* Put the ADV7171 into sleep mode */
+ adv7171_write(0x04, 0x40);
+}
+
+static unsigned codec_nreset;
+
+static void assabet_codec_reset(unsigned mask, int set)
+{
+ unsigned long flags;
+ bool old;
+
+ local_irq_save(flags);
+ old = !codec_nreset;
+ if (set)
+ codec_nreset &= ~mask;
+ else
+ codec_nreset |= mask;
+
+ if (old != !codec_nreset) {
+ if (codec_nreset) {
+ ASSABET_BCR_set(ASSABET_BCR_NCODEC_RST);
+ adv7171_sleep();
+ } else {
+ ASSABET_BCR_clear(ASSABET_BCR_NCODEC_RST);
+ }
+ }
+ local_irq_restore(flags);
+}
+
+static void assabet_ucb1x00_reset(enum ucb1x00_reset state)
+{
+ int set = state == UCB_RST_REMOVE || state == UCB_RST_SUSPEND ||
+ state == UCB_RST_PROBE_FAIL;
+ assabet_codec_reset(RST_UCB1X00, set);
+}
+
+void assabet_uda1341_reset(int set)
+{
+ assabet_codec_reset(RST_UDA1341, set);
+}
+EXPORT_SYMBOL(assabet_uda1341_reset);
+
+
+/*
+ * 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[] = {
+ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
+ DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M),
+};
+
+
+/*
+ * 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)
+ ASSABET_BCR_frob(ASSABET_BCR_IRDA_MD1 | ASSABET_BCR_IRDA_MD0,
+ bcr_state[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 ucb1x00_plat_data assabet_ucb1x00_data = {
+ .reset = assabet_ucb1x00_reset,
+ .gpio_base = -1,
+ .can_wakeup = 1,
+};
+
+static struct mcp_plat_data assabet_mcp_data = {
+ .mccr0 = MCCR0_ADM,
+ .sclk_rate = 11981000,
+ .codec_pdata = &assabet_ucb1x00_data,
+};
+
+static void assabet_lcd_set_visual(u32 visual)
+{
+ u_int is_true_color = visual == FB_VISUAL_TRUECOLOR;
+
+ if (machine_is_assabet()) {
+#if 1 // phase 4 or newer Assabet's
+ if (is_true_color)
+ ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
+ else
+ ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
+#else
+ // older Assabet's
+ if (is_true_color)
+ ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
+ else
+ ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
+#endif
+ }
+}
+
+#ifndef ASSABET_PAL_VIDEO
+static void assabet_lcd_backlight_power(int on)
+{
+ if (on)
+ ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON);
+ else
+ 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)
+{
+ if (on) {
+ ASSABET_BCR_set(ASSABET_BCR_LCD_ON);
+ udelay(500);
+ } else
+ ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
+}
+
+/*
+ * The assabet uses a sharp LQ039Q2DS54 LCD module. It is actually
+ * takes an RGB666 signal, but we provide it with an RGB565 signal
+ * instead (def_rgb_16).
+ */
+static struct sa1100fb_mach_info lq039q2ds54_info = {
+ .pixclock = 171521, .bpp = 16,
+ .xres = 320, .yres = 240,
+
+ .hsync_len = 5, .vsync_len = 1,
+ .left_margin = 61, .upper_margin = 3,
+ .right_margin = 9, .lower_margin = 0,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+ .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+ .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+
+ .backlight_power = assabet_lcd_backlight_power,
+ .lcd_power = assabet_lcd_power,
+ .set_visual = assabet_lcd_set_visual,
+};
+#else
+static void assabet_pal_backlight_power(int on)
+{
+ ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
+}
+
+static void assabet_pal_power(int on)
+{
+ ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
+}
+
+static struct sa1100fb_mach_info pal_info = {
+ .pixclock = 67797, .bpp = 16,
+ .xres = 640, .yres = 512,
+
+ .hsync_len = 64, .vsync_len = 6,
+ .left_margin = 125, .upper_margin = 70,
+ .right_margin = 115, .lower_margin = 36,
+
+ .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+ .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
+
+ .backlight_power = assabet_pal_backlight_power,
+ .lcd_power = assabet_pal_power,
+ .set_visual = assabet_lcd_set_visual,
+};
+#endif
+
+#ifdef CONFIG_ASSABET_NEPONSET
+static struct resource neponset_resources[] = {
+ DEFINE_RES_MEM(0x10000000, 0x08000000),
+ DEFINE_RES_MEM(0x18000000, 0x04000000),
+ DEFINE_RES_MEM(0x40000000, SZ_8K),
+ DEFINE_RES_IRQ(IRQ_GPIO25),
+};
+#endif
+
+static void __init assabet_init(void)
+{
+ /*
+ * Ensure that the power supply is in "high power" mode.
+ */
+ GPSR = GPIO_GPIO16;
+ GPDR |= 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
+ */
+ GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+ GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+
+ /*
+ * Also set GPIO27 as an output; this is used to clock UART3
+ * via the FPGA and as otherwise has no pullups or pulldowns,
+ * so stop it floating.
+ */
+ GPCR = GPIO_GPIO27;
+ GPDR |= GPIO_GPIO27;
+
+ /*
+ * 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;
+
+ sa11x0_ppc_configure_mcp();
+
+ 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" );
+#else
+ platform_device_register_simple("neponset", 0,
+ neponset_resources, ARRAY_SIZE(neponset_resources));
+#endif
+ }
+
+#ifndef ASSABET_PAL_VIDEO
+ sa11x0_register_lcd(&lq039q2ds54_info);
+#else
+ sa11x0_register_lcd(&pal_video);
+#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 = (unsigned long)io_p2v(phys);
+ int prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_DOMAIN(DOMAIN_IO);
+ pmd_t *pmd;
+
+ pmd = pmd_offset(pud_offset(pgd_offset_k(virt), 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 uninitialized_var(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 tag *tags, char **cmdline)
+{
+ /* 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;
+ MSC1 = (MSC1 & ~0xffff) |
+ MSC_NonBrst | MSC_32BitStMem |
+ MSC_RdAcc(2) | MSC_WrAcc(2) | MSC_Rec(0);
+
+ if (!machine_has_neponset())
+ 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);
+}
+
+/* LEDs */
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+struct assabet_led {
+ struct led_classdev cdev;
+ u32 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;
+} assabet_leds[] = {
+ { "assabet:red", "cpu0",},
+ { "assabet:green", "heartbeat", },
+};
+
+/*
+ * The LED control in Assabet is reversed:
+ * - setting bit means turn off LED
+ * - clearing bit means turn on LED
+ */
+static void assabet_led_set(struct led_classdev *cdev,
+ enum led_brightness b)
+{
+ struct assabet_led *led = container_of(cdev,
+ struct assabet_led, cdev);
+
+ if (b != LED_OFF)
+ ASSABET_BCR_clear(led->mask);
+ else
+ ASSABET_BCR_set(led->mask);
+}
+
+static enum led_brightness assabet_led_get(struct led_classdev *cdev)
+{
+ struct assabet_led *led = container_of(cdev,
+ struct assabet_led, cdev);
+
+ return (ASSABET_BCR & led->mask) ? LED_OFF : LED_FULL;
+}
+
+static int __init assabet_leds_init(void)
+{
+ int i;
+
+ if (!machine_is_assabet())
+ return -ENODEV;
+
+ for (i = 0; i < ARRAY_SIZE(assabet_leds); i++) {
+ struct assabet_led *led;
+
+ led = kzalloc(sizeof(*led), GFP_KERNEL);
+ if (!led)
+ break;
+
+ led->cdev.name = assabet_leds[i].name;
+ led->cdev.brightness_set = assabet_led_set;
+ led->cdev.brightness_get = assabet_led_get;
+ led->cdev.default_trigger = assabet_leds[i].trigger;
+
+ if (!i)
+ led->mask = ASSABET_BCR_LED_RED;
+ else
+ led->mask = ASSABET_BCR_LED_GREEN;
+
+ 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(assabet_leds_init);
+#endif
+
+MACHINE_START(ASSABET, "Intel-Assabet")
+ .atag_offset = 0x100,
+ .fixup = fixup_assabet,
+ .map_io = assabet_map_io,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = sa1100_init_irq,
+ .init_time = sa1100_timer_init,
+ .init_machine = assabet_init,
+ .init_late = sa11x0_init_late,
+#ifdef CONFIG_SA1111
+ .dma_zone_size = SZ_1M,
+#endif
+ .restart = sa11x0_restart,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
new file mode 100644
index 000000000..63361b6d0
--- /dev/null
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -0,0 +1,344 @@
+/*
+ * 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_data/sa11x0-serial.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 <linux/gpio.h>
+#include <linux/leds.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 <mach/badge4.h>
+
+#include "generic.h"
+
+static struct resource sa1111_resources[] = {
+ [0] = DEFINE_RES_MEM(BADGE4_SA1111_BASE, 0x2000),
+ [1] = DEFINE_RES_IRQ(BADGE4_IRQ_GPIO_SA1111),
+};
+
+static int badge4_sa1111_enable(void *data, unsigned devid)
+{
+ if (devid == SA1111_DEVID_USB)
+ badge4_set_5V(BADGE4_5V_USB, 1);
+ return 0;
+}
+
+static void badge4_sa1111_disable(void *data, unsigned devid)
+{
+ if (devid == SA1111_DEVID_USB)
+ badge4_set_5V(BADGE4_5V_USB, 0);
+}
+
+static struct sa1111_platform_data sa1111_info = {
+ .disable_devs = SA1111_DEVID_PS2_MSE,
+ .enable = badge4_sa1111_enable,
+ .disable = badge4_sa1111_disable,
+};
+
+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,
+};
+
+/* LEDs */
+struct gpio_led badge4_gpio_leds[] = {
+ {
+ .name = "badge4:red",
+ .default_trigger = "heartbeat",
+ .gpio = 7,
+ },
+ {
+ .name = "badge4:green",
+ .default_trigger = "cpu0",
+ .gpio = 9,
+ },
+};
+
+static struct gpio_led_platform_data badge4_gpio_led_info = {
+ .leds = badge4_gpio_leds,
+ .num_leds = ARRAY_SIZE(badge4_gpio_leds),
+};
+
+static struct platform_device badge4_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &badge4_gpio_led_info,
+ }
+};
+
+static struct platform_device *devices[] __initdata = {
+ &sa1111_device,
+ &badge4_leds,
+};
+
+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 =
+ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_64M);
+
+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
+ }
+};
+
+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")
+ .atag_offset = 0x100,
+ .map_io = badge4_map_io,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = sa1100_init_irq,
+ .init_late = sa11x0_init_late,
+ .init_time = sa1100_timer_init,
+#ifdef CONFIG_SA1111
+ .dma_zone_size = SZ_1M,
+#endif
+ .restart = sa11x0_restart,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
new file mode 100644
index 000000000..2d25ececb
--- /dev/null
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -0,0 +1,181 @@
+/*
+ * 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_data/sa11x0-serial.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/gpio.h>
+#include <linux/leds.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 <mach/cerf.h>
+#include <linux/platform_data/mfd-mcp-sa11x0.h>
+#include <mach/irqs.h>
+#include "generic.h"
+
+static struct resource cerfuart2_resources[] = {
+ [0] = DEFINE_RES_MEM(0x80030000, SZ_64K),
+};
+
+static struct platform_device cerfuart2_device = {
+ .name = "sa11x0-uart",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(cerfuart2_resources),
+ .resource = cerfuart2_resources,
+};
+
+/* LEDs */
+struct gpio_led cerf_gpio_leds[] = {
+ {
+ .name = "cerf:d0",
+ .default_trigger = "heartbeat",
+ .gpio = 0,
+ },
+ {
+ .name = "cerf:d1",
+ .default_trigger = "cpu0",
+ .gpio = 1,
+ },
+ {
+ .name = "cerf:d2",
+ .default_trigger = "default-on",
+ .gpio = 2,
+ },
+ {
+ .name = "cerf:d3",
+ .default_trigger = "default-on",
+ .gpio = 3,
+ },
+
+};
+
+static struct gpio_led_platform_data cerf_gpio_led_info = {
+ .leds = cerf_gpio_leds,
+ .num_leds = ARRAY_SIZE(cerf_gpio_leds),
+};
+
+static struct platform_device cerf_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &cerf_gpio_led_info,
+ }
+};
+
+
+static struct platform_device *cerf_devices[] __initdata = {
+ &cerfuart2_device,
+ &cerf_leds,
+};
+
+#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 =
+ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
+
+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)
+{
+ sa11x0_ppc_configure_mcp();
+ 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,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = cerf_init_irq,
+ .init_time = sa1100_timer_init,
+ .init_machine = cerf_init,
+ .init_late = sa11x0_init_late,
+ .restart = sa11x0_restart,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
new file mode 100644
index 000000000..cbf53bb9c
--- /dev/null
+++ b/arch/arm/mach-sa1100/clock.c
@@ -0,0 +1,148 @@
+/*
+ * 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 <linux/io.h>
+#include <linux/clkdev.h>
+
+#include <mach/hardware.h>
+#include <mach/generic.h>
+
+struct clkops {
+ void (*enable)(struct clk *);
+ void (*disable)(struct clk *);
+ unsigned long (*get_rate)(struct clk *);
+};
+
+struct clk {
+ const struct clkops *ops;
+ unsigned int enabled;
+};
+
+#define DEFINE_CLK(_name, _ops) \
+struct clk clk_##_name = { \
+ .ops = _ops, \
+ }
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+static void clk_gpio27_enable(struct clk *clk)
+{
+ /*
+ * 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(struct clk *clk)
+{
+ TUCR = 0;
+ GPDR &= ~GPIO_32_768kHz;
+ GAFR &= ~GPIO_32_768kHz;
+}
+
+static void clk_cpu_enable(struct clk *clk)
+{
+}
+
+static void clk_cpu_disable(struct clk *clk)
+{
+}
+
+static unsigned long clk_cpu_get_rate(struct clk *clk)
+{
+ return sa11x0_getspeed(0) * 1000;
+}
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+
+ if (clk) {
+ 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;
+
+ if (clk) {
+ 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)
+{
+ if (clk && clk->ops && clk->ops->get_rate)
+ return clk->ops->get_rate(clk);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+const struct clkops clk_gpio27_ops = {
+ .enable = clk_gpio27_enable,
+ .disable = clk_gpio27_disable,
+};
+
+const struct clkops clk_cpu_ops = {
+ .enable = clk_cpu_enable,
+ .disable = clk_cpu_disable,
+ .get_rate = clk_cpu_get_rate,
+};
+
+static DEFINE_CLK(gpio27, &clk_gpio27_ops);
+
+static DEFINE_CLK(cpu, &clk_cpu_ops);
+
+static unsigned long clk_36864_get_rate(struct clk *clk)
+{
+ return 3686400;
+}
+
+static struct clkops clk_36864_ops = {
+ .get_rate = clk_36864_get_rate,
+};
+
+static DEFINE_CLK(36864, &clk_36864_ops);
+
+static struct clk_lookup sa11xx_clkregs[] = {
+ CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27),
+ CLKDEV_INIT("sa1100-rtc", NULL, NULL),
+ CLKDEV_INIT("sa11x0-fb", NULL, &clk_cpu),
+ CLKDEV_INIT("sa11x0-pcmcia", NULL, &clk_cpu),
+ /* sa1111 names devices using internal offsets, PCMCIA is at 0x1800 */
+ CLKDEV_INIT("1800", NULL, &clk_cpu),
+ CLKDEV_INIT(NULL, "OSTIMER0", &clk_36864),
+};
+
+static int __init sa11xx_clk_init(void)
+{
+ clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs));
+ return 0;
+}
+core_initcall(sa11xx_clk_init);
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
new file mode 100644
index 000000000..3cc2b71e1
--- /dev/null
+++ b/arch/arm/mach-sa1100/collie.c
@@ -0,0 +1,437 @@
+/*
+ * 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_data/sa11x0-serial.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/ucb1x00.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/timer.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/power/gpio-charger.h>
+
+#include <video/sa1100fb.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/page.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 <linux/platform_data/irda-sa11x0.h>
+
+#include <asm/hardware/scoop.h>
+#include <asm/mach/sharpsl_param.h>
+#include <asm/hardware/locomo.h>
+#include <linux/platform_data/mfd-mcp-sa11x0.h>
+#include <mach/irqs.h>
+
+#include "generic.h"
+
+static struct resource collie_scoop_resources[] = {
+ [0] = DEFINE_RES_MEM(0x40800000, SZ_4K),
+};
+
+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 ucb1x00_plat_data collie_ucb1x00_data = {
+ .gpio_base = COLLIE_TC35143_GPIO_BASE,
+};
+
+static struct mcp_plat_data collie_mcp_data = {
+ .mccr0 = MCCR0_ADM | MCCR0_ExtClk,
+ .sclk_rate = 9216000,
+ .codec_pdata = &collie_ucb1x00_data,
+};
+
+static int collie_ir_startup(struct device *dev)
+{
+ int rc = gpio_request(COLLIE_GPIO_IR_ON, "IrDA");
+ if (rc)
+ return rc;
+ rc = gpio_direction_output(COLLIE_GPIO_IR_ON, 1);
+
+ if (!rc)
+ return 0;
+
+ gpio_free(COLLIE_GPIO_IR_ON);
+ return rc;
+}
+
+static void collie_ir_shutdown(struct device *dev)
+{
+ gpio_free(COLLIE_GPIO_IR_ON);
+}
+
+static int collie_ir_set_power(struct device *dev, unsigned int state)
+{
+ gpio_set_value(COLLIE_GPIO_IR_ON, !state);
+ return 0;
+}
+
+static struct irda_platform_data collie_ir_data = {
+ .startup = collie_ir_startup,
+ .shutdown = collie_ir_shutdown,
+ .set_power = collie_ir_set_power,
+};
+
+/*
+ * Collie AC IN
+ */
+static char *collie_ac_supplied_to[] = {
+ "main-battery",
+ "backup-battery",
+};
+
+
+static struct gpio_charger_platform_data collie_power_data = {
+ .name = "charger",
+ .type = POWER_SUPPLY_TYPE_MAINS,
+ .gpio = COLLIE_GPIO_AC_IN,
+ .supplied_to = collie_ac_supplied_to,
+ .num_supplicants = ARRAY_SIZE(collie_ac_supplied_to),
+};
+
+static struct platform_device collie_power_device = {
+ .name = "gpio-charger",
+ .id = -1,
+ .dev.platform_data = &collie_power_data,
+};
+
+#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] = DEFINE_RES_MEM(0x40000000, SZ_8K),
+ [1] = DEFINE_RES_IRQ(IRQ_GPIO25),
+};
+
+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 gpio_keys_button collie_gpio_keys[] = {
+ {
+ .type = EV_PWR,
+ .code = KEY_RESERVED,
+ .gpio = COLLIE_GPIO_ON_KEY,
+ .desc = "On key",
+ .wakeup = 1,
+ .active_low = 1,
+ },
+ {
+ .type = EV_PWR,
+ .code = KEY_WAKEUP,
+ .gpio = COLLIE_GPIO_WAKEUP,
+ .desc = "Sync",
+ .wakeup = 1,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data collie_gpio_keys_data = {
+ .buttons = collie_gpio_keys,
+ .nbuttons = ARRAY_SIZE(collie_gpio_keys),
+};
+
+static struct platform_device collie_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &collie_gpio_keys_data,
+ },
+};
+
+static struct platform_device *devices[] __initdata = {
+ &collie_locomo_device,
+ &colliescoop_device,
+ &collie_power_device,
+ &collie_gpio_keys_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,
+ }, {
+ .name = "bootblock",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x00020000,
+ .mask_flags = MTD_WRITEABLE
+ }
+};
+
+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[] = {
+ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
+};
+
+static struct sa1100fb_mach_info collie_lcd_info = {
+ .pixclock = 171521, .bpp = 16,
+ .xres = 320, .yres = 240,
+
+ .hsync_len = 5, .vsync_len = 1,
+ .left_margin = 11, .upper_margin = 2,
+ .right_margin = 30, .lower_margin = 0,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+ .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+ .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+
+#ifdef CONFIG_BACKLIGHT_LOCOMO
+ .lcd_power = locomolcd_power
+#endif
+};
+
+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 = 0;
+
+ PGSR = _COLLIE_GPIO_nREMOCON_ON;
+
+ PSDR = PPC_RXD1 | PPC_RXD2 | PPC_RXD3 | PPC_RXD4;
+
+ PCFR = PCFR_OPDE;
+
+ GPSR |= _COLLIE_GPIO_UCB1x00_RESET;
+
+ sa11x0_ppc_configure_mcp();
+
+
+ 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_lcd(&collie_lcd_info);
+ sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
+ ARRAY_SIZE(collie_flash_resources));
+ sa11x0_register_mcp(&collie_mcp_data);
+ sa11x0_register_irda(&collie_ir_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,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = sa1100_init_irq,
+ .init_time = sa1100_timer_init,
+ .init_machine = collie_init,
+ .init_late = sa11x0_init_late,
+ .restart = sa11x0_restart,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
new file mode 100644
index 000000000..40e0d8619
--- /dev/null
+++ b/arch/arm/mach-sa1100/generic.c
@@ -0,0 +1,418 @@
+/*
+ * 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/gpio.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/pm.h>
+#include <linux/cpufreq.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+
+#include <video/sa1100fb.h>
+
+#include <asm/div64.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+#include <asm/irq.h>
+#include <asm/system_misc.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+#include "generic.h"
+#include <clocksource/pxa.h>
+
+unsigned int reset_status;
+EXPORT_SYMBOL(reset_status);
+
+#define NR_FREQS 16
+
+/*
+ * This table is setup for a 3.6864MHz Crystal.
+ */
+struct cpufreq_frequency_table sa11x0_freq_table[NR_FREQS+1] = {
+ { .frequency = 59000, /* 59.0 MHz */},
+ { .frequency = 73700, /* 73.7 MHz */},
+ { .frequency = 88500, /* 88.5 MHz */},
+ { .frequency = 103200, /* 103.2 MHz */},
+ { .frequency = 118000, /* 118.0 MHz */},
+ { .frequency = 132700, /* 132.7 MHz */},
+ { .frequency = 147500, /* 147.5 MHz */},
+ { .frequency = 162200, /* 162.2 MHz */},
+ { .frequency = 176900, /* 176.9 MHz */},
+ { .frequency = 191700, /* 191.7 MHz */},
+ { .frequency = 206400, /* 206.4 MHz */},
+ { .frequency = 221200, /* 221.2 MHz */},
+ { .frequency = 235900, /* 235.9 MHz */},
+ { .frequency = 250700, /* 250.7 MHz */},
+ { .frequency = 265400, /* 265.4 MHz */},
+ { .frequency = 280200, /* 280.2 MHz */},
+ { .frequency = CPUFREQ_TABLE_END, },
+};
+
+unsigned int sa11x0_getspeed(unsigned int cpu)
+{
+ if (cpu)
+ return 0;
+ return sa11x0_freq_table[PPCR & 0xf].frequency;
+}
+
+/*
+ * 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;
+}
+
+void sa11x0_restart(enum reboot_mode mode, const char *cmd)
+{
+ if (mode == REBOOT_SOFT) {
+ /* Jump into ROM at address 0 */
+ soft_restart(0);
+ } else {
+ /* Use on-chip reset capability */
+ RSRR = RSRR_SWR;
+ }
+}
+
+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] = DEFINE_RES_MEM(__PREG(Ser0UDCCR), SZ_64K),
+ [1] = DEFINE_RES_IRQ(IRQ_Ser0UDC),
+};
+
+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] = DEFINE_RES_MEM(__PREG(Ser1UTCR0), SZ_64K),
+ [1] = DEFINE_RES_IRQ(IRQ_Ser1UART),
+};
+
+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] = DEFINE_RES_MEM(__PREG(Ser3UTCR0), SZ_64K),
+ [1] = DEFINE_RES_IRQ(IRQ_Ser3UART),
+};
+
+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] = DEFINE_RES_MEM(__PREG(Ser4MCCR0), SZ_64K),
+ [1] = DEFINE_RES_MEM(__PREG(Ser4MCCR1), 4),
+ [2] = DEFINE_RES_IRQ(IRQ_Ser4MCP),
+};
+
+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 __init sa11x0_ppc_configure_mcp(void)
+{
+ /* Setup the PPC unit for the MCP */
+ PPDR &= ~PPC_RXD4;
+ PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+ PSDR |= PPC_RXD4;
+ PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+ PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+}
+
+void sa11x0_register_mcp(struct mcp_plat_data *data)
+{
+ sa11x0_register_device(&sa11x0mcp_device, data);
+}
+
+static struct resource sa11x0ssp_resources[] = {
+ [0] = DEFINE_RES_MEM(0x80070000, SZ_64K),
+ [1] = DEFINE_RES_IRQ(IRQ_Ser4SSP),
+};
+
+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] = DEFINE_RES_MEM(0xb0100000, SZ_64K),
+ [1] = DEFINE_RES_IRQ(IRQ_LCD),
+};
+
+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,
+};
+
+void sa11x0_register_lcd(struct sa1100fb_mach_info *inf)
+{
+ sa11x0_register_device(&sa11x0fb_device, inf);
+}
+
+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[] = {
+ DEFINE_RES_MEM(__PREG(Ser2UTCR0), 0x24),
+ DEFINE_RES_MEM(__PREG(Ser2HSCR0), 0x1c),
+ DEFINE_RES_MEM(__PREG(Ser2HSCR2), 0x04),
+ DEFINE_RES_IRQ(IRQ_Ser2ICP),
+};
+
+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 resource sa1100_rtc_resources[] = {
+ DEFINE_RES_MEM(0x90010000, 0x40),
+ DEFINE_RES_IRQ_NAMED(IRQ_RTC1Hz, "rtc 1Hz"),
+ DEFINE_RES_IRQ_NAMED(IRQ_RTCAlrm, "rtc alarm"),
+};
+
+static struct platform_device sa11x0rtc_device = {
+ .name = "sa1100-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(sa1100_rtc_resources),
+ .resource = sa1100_rtc_resources,
+};
+
+static struct resource sa11x0dma_resources[] = {
+ DEFINE_RES_MEM(DMA_PHYS, DMA_SIZE),
+ DEFINE_RES_IRQ(IRQ_DMA0),
+ DEFINE_RES_IRQ(IRQ_DMA1),
+ DEFINE_RES_IRQ(IRQ_DMA2),
+ DEFINE_RES_IRQ(IRQ_DMA3),
+ DEFINE_RES_IRQ(IRQ_DMA4),
+ DEFINE_RES_IRQ(IRQ_DMA5),
+};
+
+static u64 sa11x0dma_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device sa11x0dma_device = {
+ .name = "sa11x0-dma",
+ .id = -1,
+ .dev = {
+ .dma_mask = &sa11x0dma_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(sa11x0dma_resources),
+ .resource = sa11x0dma_resources,
+};
+
+static struct platform_device *sa11x0_devices[] __initdata = {
+ &sa11x0udc_device,
+ &sa11x0uart1_device,
+ &sa11x0uart3_device,
+ &sa11x0ssp_device,
+ &sa11x0pcmcia_device,
+ &sa11x0rtc_device,
+ &sa11x0dma_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 __init sa11x0_init_late(void)
+{
+ sa11x0_pm_init();
+}
+
+/*
+ * 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));
+}
+
+void __init sa1100_timer_init(void)
+{
+ pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x90000000), 3686400);
+}
+
+/*
+ * 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 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 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 000000000..0d92e119b
--- /dev/null
+++ b/arch/arm/mach-sa1100/generic.h
@@ -0,0 +1,46 @@
+/*
+ * linux/arch/arm/mach-sa1100/generic.h
+ *
+ * Author: Nicolas Pitre
+ */
+#include <linux/cpufreq.h>
+#include <linux/reboot.h>
+
+extern void sa1100_timer_init(void);
+extern void __init sa1100_map_io(void);
+extern void __init sa1100_init_irq(void);
+extern void __init sa1100_init_gpio(void);
+extern void sa11x0_restart(enum reboot_mode, const char *);
+extern void sa11x0_init_late(void);
+
+#define SET_BANK(__nr,__start,__size) \
+ mi->bank[__nr].start = (__start), \
+ mi->bank[__nr].size = (__size)
+
+extern void sa1110_mb_enable(void);
+extern void sa1110_mb_disable(void);
+
+extern struct cpufreq_frequency_table sa11x0_freq_table[];
+extern unsigned int sa11x0_getspeed(unsigned int cpu);
+
+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_ppc_configure_mcp(void);
+void sa11x0_register_mcp(struct mcp_plat_data *data);
+
+struct sa1100fb_mach_info;
+void sa11x0_register_lcd(struct sa1100fb_mach_info *inf);
+
+#ifdef CONFIG_PM
+int sa11x0_pm_init(void);
+#else
+static inline int sa11x0_pm_init(void) { return 0; }
+#endif
diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c
new file mode 100644
index 000000000..c6b412054
--- /dev/null
+++ b/arch/arm/mach-sa1100/h3100.c
@@ -0,0 +1,143 @@
+/*
+ * 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 <video/sa1100fb.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <linux/platform_data/irda-sa11x0.h>
+
+#include <mach/h3xxx.h>
+#include <mach/irqs.h>
+
+#include "generic.h"
+
+/*
+ * helper for sa1100fb
+ */
+static struct gpio h3100_lcd_gpio[] = {
+ { H3100_GPIO_LCD_3V_ON, GPIOF_OUT_INIT_LOW, "LCD 3V" },
+ { H3XXX_EGPIO_LCD_ON, GPIOF_OUT_INIT_LOW, "LCD ON" },
+};
+
+static bool h3100_lcd_request(void)
+{
+ static bool h3100_lcd_ok;
+ int rc;
+
+ if (h3100_lcd_ok)
+ return true;
+
+ rc = gpio_request_array(h3100_lcd_gpio, ARRAY_SIZE(h3100_lcd_gpio));
+ if (rc)
+ pr_err("%s: can't request GPIOs\n", __func__);
+ else
+ h3100_lcd_ok = true;
+
+ return h3100_lcd_ok;
+}
+
+static void h3100_lcd_power(int enable)
+{
+ if (!h3100_lcd_request())
+ return;
+
+ gpio_set_value(H3100_GPIO_LCD_3V_ON, enable);
+ gpio_set_value(H3XXX_EGPIO_LCD_ON, enable);
+}
+
+static struct sa1100fb_mach_info h3100_lcd_info = {
+ .pixclock = 406977, .bpp = 4,
+ .xres = 320, .yres = 240,
+
+ .hsync_len = 26, .vsync_len = 41,
+ .left_margin = 4, .upper_margin = 0,
+ .right_margin = 4, .lower_margin = 0,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .cmap_greyscale = 1,
+ .cmap_inverse = 1,
+
+ .lccr0 = LCCR0_Mono | LCCR0_4PixMono | LCCR0_Sngl | LCCR0_Pas,
+ .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+
+ .lcd_power = h3100_lcd_power,
+};
+
+static void __init h3100_map_io(void)
+{
+ h3xxx_map_io();
+
+ /* 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 struct gpio h3100_irda_gpio[] = {
+ { H3100_GPIO_IR_ON, GPIOF_OUT_INIT_LOW, "IrDA power" },
+ { H3100_GPIO_IR_FSEL, GPIOF_OUT_INIT_LOW, "IrDA fsel" },
+};
+
+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 int h3100_irda_startup(struct device *dev)
+{
+ return gpio_request_array(h3100_irda_gpio, sizeof(h3100_irda_gpio));
+}
+
+static void h3100_irda_shutdown(struct device *dev)
+{
+ return gpio_free_array(h3100_irda_gpio, sizeof(h3100_irda_gpio));
+}
+
+static struct irda_platform_data h3100_irda_data = {
+ .set_power = h3100_irda_set_power,
+ .set_speed = h3100_irda_set_speed,
+ .startup = h3100_irda_startup,
+ .shutdown = h3100_irda_shutdown,
+};
+
+static void __init h3100_mach_init(void)
+{
+ h3xxx_mach_init();
+
+ sa11x0_register_lcd(&h3100_lcd_info);
+ sa11x0_register_irda(&h3100_irda_data);
+}
+
+MACHINE_START(H3100, "Compaq iPAQ H3100")
+ .atag_offset = 0x100,
+ .map_io = h3100_map_io,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = sa1100_init_irq,
+ .init_time = sa1100_timer_init,
+ .init_machine = h3100_mach_init,
+ .init_late = sa11x0_init_late,
+ .restart = sa11x0_restart,
+MACHINE_END
+
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
new file mode 100644
index 000000000..118338efd
--- /dev/null
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -0,0 +1,151 @@
+/*
+ * 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 <video/sa1100fb.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <linux/platform_data/irda-sa11x0.h>
+
+#include <mach/h3xxx.h>
+#include <mach/irqs.h>
+
+#include "generic.h"
+
+/*
+ * helper for sa1100fb
+ */
+static struct gpio h3600_lcd_gpio[] = {
+ { H3XXX_EGPIO_LCD_ON, GPIOF_OUT_INIT_LOW, "LCD power" },
+ { H3600_EGPIO_LCD_PCI, GPIOF_OUT_INIT_LOW, "LCD control" },
+ { H3600_EGPIO_LCD_5V_ON, GPIOF_OUT_INIT_LOW, "LCD 5v" },
+ { H3600_EGPIO_LVDD_ON, GPIOF_OUT_INIT_LOW, "LCD 9v/-6.5v" },
+};
+
+static bool h3600_lcd_request(void)
+{
+ static bool h3600_lcd_ok;
+ int rc;
+
+ if (h3600_lcd_ok)
+ return true;
+
+ rc = gpio_request_array(h3600_lcd_gpio, ARRAY_SIZE(h3600_lcd_gpio));
+ if (rc)
+ pr_err("%s: can't request GPIOs\n", __func__);
+ else
+ h3600_lcd_ok = true;
+
+ return h3600_lcd_ok;
+}
+
+static void h3600_lcd_power(int enable)
+{
+ if (!h3600_lcd_request())
+ return;
+
+ 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);
+}
+
+static const struct sa1100fb_rgb h3600_rgb_16 = {
+ .red = { .offset = 12, .length = 4, },
+ .green = { .offset = 7, .length = 4, },
+ .blue = { .offset = 1, .length = 4, },
+ .transp = { .offset = 0, .length = 0, },
+};
+
+static struct sa1100fb_mach_info h3600_lcd_info = {
+ .pixclock = 174757, .bpp = 16,
+ .xres = 320, .yres = 240,
+
+ .hsync_len = 3, .vsync_len = 3,
+ .left_margin = 12, .upper_margin = 10,
+ .right_margin = 17, .lower_margin = 1,
+
+ .cmap_static = 1,
+
+ .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+ .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+
+ .rgb[RGB_16] = &h3600_rgb_16,
+
+ .lcd_power = h3600_lcd_power,
+};
+
+
+static void __init h3600_map_io(void)
+{
+ h3xxx_map_io();
+}
+
+/*
+ * This turns the IRDA power on or off on the Compaq H3600
+ */
+static struct gpio h3600_irda_gpio[] = {
+ { H3600_EGPIO_IR_ON, GPIOF_OUT_INIT_LOW, "IrDA power" },
+ { H3600_EGPIO_IR_FSEL, GPIOF_OUT_INIT_LOW, "IrDA fsel" },
+};
+
+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)
+{
+ return gpio_request_array(h3600_irda_gpio, sizeof(h3600_irda_gpio));
+}
+
+static void h3600_irda_shutdown(struct device *dev)
+{
+ return gpio_free_array(h3600_irda_gpio, sizeof(h3600_irda_gpio));
+}
+
+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 void __init h3600_mach_init(void)
+{
+ h3xxx_mach_init();
+
+ sa11x0_register_lcd(&h3600_lcd_info);
+ sa11x0_register_irda(&h3600_irda_data);
+}
+
+MACHINE_START(H3600, "Compaq iPAQ H3600")
+ .atag_offset = 0x100,
+ .map_io = h3600_map_io,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = sa1100_init_irq,
+ .init_time = sa1100_timer_init,
+ .init_machine = h3600_mach_init,
+ .init_late = sa11x0_init_late,
+ .restart = sa11x0_restart,
+MACHINE_END
+
diff --git a/arch/arm/mach-sa1100/h3xxx.c b/arch/arm/mach-sa1100/h3xxx.c
new file mode 100644
index 000000000..b1d4faa12
--- /dev/null
+++ b/arch/arm/mach-sa1100/h3xxx.c
@@ -0,0 +1,317 @@
+/*
+ * 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_data/sa11x0-serial.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <mach/h3xxx.h>
+#include <mach/irqs.h>
+
+#include "generic.h"
+
+/*
+ * 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 =
+ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
+
+
+/*
+ * H3xxx uart support
+ */
+static struct gpio h3xxx_uart_gpio[] = {
+ { H3XXX_GPIO_COM_DCD, GPIOF_IN, "COM DCD" },
+ { H3XXX_GPIO_COM_CTS, GPIOF_IN, "COM CTS" },
+ { H3XXX_GPIO_COM_RTS, GPIOF_OUT_INIT_LOW, "COM RTS" },
+};
+
+static bool h3xxx_uart_request_gpios(void)
+{
+ static bool h3xxx_uart_gpio_ok;
+ int rc;
+
+ if (h3xxx_uart_gpio_ok)
+ return true;
+
+ rc = gpio_request_array(h3xxx_uart_gpio, ARRAY_SIZE(h3xxx_uart_gpio));
+ if (rc)
+ pr_err("h3xxx_uart_request_gpios: error %d\n", rc);
+ else
+ h3xxx_uart_gpio_ok = true;
+
+ return h3xxx_uart_gpio_ok;
+}
+
+static void h3xxx_uart_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+ if (port->mapbase == _Ser3UTCR0) {
+ if (!h3xxx_uart_request_gpios())
+ return;
+ 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) {
+ if (!h3xxx_uart_request_gpios())
+ return ret;
+ /*
+ * 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] = DEFINE_RES_MEM(H3600_EGPIO_PHYS, 0x4),
+};
+
+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 resource h3xxx_micro_resources[] = {
+ DEFINE_RES_MEM(0x80010000, SZ_4K),
+ DEFINE_RES_MEM(0x80020000, SZ_4K),
+ DEFINE_RES_IRQ(IRQ_Ser1UART),
+};
+
+struct platform_device h3xxx_micro_asic = {
+ .name = "ipaq-h3xxx-micro",
+ .id = -1,
+ .resource = h3xxx_micro_resources,
+ .num_resources = ARRAY_SIZE(h3xxx_micro_resources),
+};
+
+static struct platform_device *h3xxx_devices[] = {
+ &h3xxx_egpio,
+ &h3xxx_keys,
+ &h3xxx_micro_asic,
+};
+
+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 000000000..643d5f2d9
--- /dev/null
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -0,0 +1,236 @@
+/*
+ * 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/platform_data/sa11x0-serial.h>
+#include <linux/serial_core.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/tty.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.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 =
+ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
+
+/* LEDs */
+struct gpio_led hackkit_gpio_leds[] = {
+ {
+ .name = "hackkit:red",
+ .default_trigger = "cpu0",
+ .gpio = 22,
+ },
+ {
+ .name = "hackkit:green",
+ .default_trigger = "heartbeat",
+ .gpio = 23,
+ },
+};
+
+static struct gpio_led_platform_data hackkit_gpio_led_info = {
+ .leds = hackkit_gpio_leds,
+ .num_leds = ARRAY_SIZE(hackkit_gpio_leds),
+};
+
+static struct platform_device hackkit_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &hackkit_gpio_led_info,
+ }
+};
+
+static void __init hackkit_init(void)
+{
+ sa11x0_register_mtd(&hackkit_flash_data, &hackkit_flash_resource, 1);
+ platform_device_register(&hackkit_leds);
+}
+
+/**********************************************************************
+ * Exported Functions
+ */
+
+MACHINE_START(HACKKIT, "HackKit Cpu Board")
+ .atag_offset = 0x100,
+ .map_io = hackkit_map_io,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = sa1100_init_irq,
+ .init_time = sa1100_timer_init,
+ .init_machine = hackkit_init,
+ .init_late = sa11x0_init_late,
+ .restart = sa11x0_restart,
+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 000000000..0ac6cc08a
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/SA-1100.h
@@ -0,0 +1,1831 @@
+/*
+ * 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 io_p2v(0x90000000) /* OS timer Match Reg. 0 */
+#define OSMR1 io_p2v(0x90000004) /* OS timer Match Reg. 1 */
+#define OSMR2 io_p2v(0x90000008) /* OS timer Match Reg. 2 */
+#define OSMR3 io_p2v(0x9000000c) /* OS timer Match Reg. 3 */
+#define OSCR io_p2v(0x90000010) /* OS timer Counter Reg. */
+#define OSSR io_p2v(0x90000014) /* OS timer Status Reg. */
+#define OWER io_p2v(0x90000018) /* OS timer Watch-dog Enable Reg. */
+#define OIER io_p2v(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
+ */
+#define DMA_SIZE (6 * 0x20)
+#define DMA_PHYS 0xb0000000
+
+
+/*
+ * 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_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 000000000..5d2ad7db9
--- /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/assabet.h b/arch/arm/mach-sa1100/include/mach/assabet.h
new file mode 100644
index 000000000..c23fcdb04
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/assabet.h
@@ -0,0 +1,104 @@
+/*
+ * 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_NGFX_RST (1<<1) /* Graphics Accelerator Reset (0 = hold reset) */
+#define ASSABET_BCR_NCODEC_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
+
+extern void assabet_uda1341_reset(int set);
+
+#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 (bitmasks) 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_GFX_IRQ GPIO_GPIO (24) /* Graphics IRQ */
+#define ASSABET_GPIO_BATT_LOW GPIO_GPIO (26) /* Low battery */
+#define ASSABET_GPIO_RCLK GPIO_GPIO (26) /* CCLK/2 */
+
+/* These are gpiolib GPIO numbers, not bitmasks */
+#define ASSABET_GPIO_CF_IRQ 21 /* CF IRQ */
+#define ASSABET_GPIO_CF_CD 22 /* CF CD */
+#define ASSABET_GPIO_CF_BVD2 24 /* CF BVD / IOSPKR */
+#define ASSABET_GPIO_CF_BVD1 25 /* CF BVD / IOSTSCHG */
+
+#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 000000000..44d2e1bfc
--- /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 000000000..f1f0e3387
--- /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 000000000..88fd9c006
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/cerf.h
@@ -0,0 +1,23 @@
+/*
+ * 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 19
+#define CERF_GPIO_CF_BVD1 20
+#define CERF_GPIO_CF_RESET 21
+#define CERF_GPIO_CF_IRQ 22
+#define CERF_GPIO_CF_CD 23
+
+#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 000000000..b478ca180
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/collie.h
@@ -0,0 +1,95 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/collie.h
+ *
+ * This file contains the hardware specific definitions for Collie
+ * 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
+
+#include "hardware.h" /* Gives GPIO_MAX */
+
+extern void locomolcd_power(int on);
+
+#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_GPIO_IR_ON (COLLIE_TC35143_GPIO_BASE + 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/generic.h b/arch/arm/mach-sa1100/include/mach/generic.h
new file mode 100644
index 000000000..665542e0c
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/generic.h
@@ -0,0 +1 @@
+#include "../../generic.h"
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 000000000..603d4343f
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/h3xxx.h
@@ -0,0 +1,85 @@
+/*
+ * 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_
+
+#include "hardware.h" /* Gives GPIO_MAX */
+
+/* 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. */
+
+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 000000000..cbedd75a9
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/hardware.h
@@ -0,0 +1,81 @@
+/*
+ * 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 ) \
+ IOMEM( (((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)
+
+#define __MREG(x) IOMEM(io_p2v(x))
+
+#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 __iomem *)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
+
+#endif /* _ASM_ARCH_HARDWARE_H */
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 000000000..734e30e40
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/irqs.h
@@ -0,0 +1,100 @@
+/*
+ * 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_SC 1
+#define IRQ_GPIO1_SC 2
+#define IRQ_GPIO2_SC 3
+#define IRQ_GPIO3_SC 4
+#define IRQ_GPIO4_SC 5
+#define IRQ_GPIO5_SC 6
+#define IRQ_GPIO6_SC 7
+#define IRQ_GPIO7_SC 8
+#define IRQ_GPIO8_SC 9
+#define IRQ_GPIO9_SC 10
+#define IRQ_GPIO10_SC 11
+#define IRQ_GPIO11_27 12
+#define IRQ_LCD 13 /* LCD controller */
+#define IRQ_Ser0UDC 14 /* Ser. port 0 UDC */
+#define IRQ_Ser1SDLC 15 /* Ser. port 1 SDLC */
+#define IRQ_Ser1UART 16 /* Ser. port 1 UART */
+#define IRQ_Ser2ICP 17 /* Ser. port 2 ICP */
+#define IRQ_Ser3UART 18 /* Ser. port 3 UART */
+#define IRQ_Ser4MCP 19 /* Ser. port 4 MCP */
+#define IRQ_Ser4SSP 20 /* Ser. port 4 SSP */
+#define IRQ_DMA0 21 /* DMA controller channel 0 */
+#define IRQ_DMA1 22 /* DMA controller channel 1 */
+#define IRQ_DMA2 23 /* DMA controller channel 2 */
+#define IRQ_DMA3 24 /* DMA controller channel 3 */
+#define IRQ_DMA4 25 /* DMA controller channel 4 */
+#define IRQ_DMA5 26 /* DMA controller channel 5 */
+#define IRQ_OST0 27 /* OS Timer match 0 */
+#define IRQ_OST1 28 /* OS Timer match 1 */
+#define IRQ_OST2 29 /* OS Timer match 2 */
+#define IRQ_OST3 30 /* OS Timer match 3 */
+#define IRQ_RTC1Hz 31 /* RTC 1 Hz clock */
+#define IRQ_RTCAlrm 32 /* RTC Alarm */
+
+#define IRQ_GPIO0 33
+#define IRQ_GPIO1 34
+#define IRQ_GPIO2 35
+#define IRQ_GPIO3 36
+#define IRQ_GPIO4 37
+#define IRQ_GPIO5 38
+#define IRQ_GPIO6 39
+#define IRQ_GPIO7 40
+#define IRQ_GPIO8 41
+#define IRQ_GPIO9 42
+#define IRQ_GPIO10 43
+#define IRQ_GPIO11 44
+#define IRQ_GPIO12 45
+#define IRQ_GPIO13 46
+#define IRQ_GPIO14 47
+#define IRQ_GPIO15 48
+#define IRQ_GPIO16 49
+#define IRQ_GPIO17 50
+#define IRQ_GPIO18 51
+#define IRQ_GPIO19 52
+#define IRQ_GPIO20 53
+#define IRQ_GPIO21 54
+#define IRQ_GPIO22 55
+#define IRQ_GPIO23 56
+#define IRQ_GPIO24 57
+#define IRQ_GPIO25 58
+#define IRQ_GPIO26 59
+#define IRQ_GPIO27 60
+
+/*
+ * 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 61 to 76 are available.
+ */
+#define IRQ_BOARD_START 61
+#define IRQ_BOARD_END 77
+
+/*
+ * Figure out the MAX IRQ number.
+ *
+ * Neponset, SA1111 and UCB1x00 are sparse IRQ aware, so can dynamically
+ * allocate their IRQs above NR_IRQS.
+ *
+ * LoCoMo has 4 additional IRQs, but is not sparse IRQ aware, and so has
+ * to be included in the NR_IRQS calculation.
+ */
+#ifdef CONFIG_SHARP_LOCOMO
+#define NR_IRQS_LOCOMO 4
+#else
+#define NR_IRQS_LOCOMO 0
+#endif
+
+#ifndef NR_IRQS
+#define NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
+#endif
+#define SA1100_NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
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 000000000..cc6b4bfce
--- /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/memory.h b/arch/arm/mach-sa1100/include/mach/memory.h
new file mode 100644
index 000000000..2054051eb
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/memory.h
@@ -0,0 +1,36 @@
+/*
+ * 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>
+
+/*
+ * 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 000000000..b3d684098
--- /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 000000000..5ebd469a3
--- /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 11 /* ready for socket 0 (active high)*/
+#define GPIO_PC_READY1 12 /* ready for socket 1 (active high) */
+#define GPIO_PC_CD0 13 /* detect for socket 0 (active low) */
+#define GPIO_PC_CD1 14 /* detect for socket 1 (active low) */
+#define GPIO_PC_RESET0 15 /* reset socket 0 */
+#define GPIO_PC_RESET1 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 000000000..5516a52a3
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/neponset.h
@@ -0,0 +1,30 @@
+/*
+ * 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 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)
+
+void neponset_ncr_frob(unsigned int, unsigned int);
+#define neponset_ncr_set(v) neponset_ncr_frob(0, v)
+#define neponset_ncr_clear(v) neponset_ncr_frob(v, 0)
+
+#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 000000000..f61957e68
--- /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 000000000..fff39e02b
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/shannon.h
@@ -0,0 +1,39 @@
+#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 22 /* out */
+/* XXX GPIO 23 unaccounted for */
+#define SHANNON_GPIO_EJECT_0 24 /* in */
+#define SHANNON_GPIO_EJECT_1 25 /* in */
+#define SHANNON_GPIO_RDY_0 26 /* in */
+#define SHANNON_GPIO_RDY_1 27 /* in */
+
+/* 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 000000000..ac2ea7672
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/simpad.h
@@ -0,0 +1,158 @@
+/*
+ * 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 24
+#define GPIO_CF_IRQ 1
+
+/*--- SmartCard ---*/
+#define GPIO_SMART_CARD GPIO_GPIO10
+#define IRQ_GPIO_SMARD_CARD IRQ_GPIO10
+
+/*--- ucb1x00 GPIO ---*/
+#define SIMPAD_UCB1X00_GPIO_BASE (GPIO_MAX + 1)
+#define SIMPAD_UCB1X00_GPIO_PROG1 (SIMPAD_UCB1X00_GPIO_BASE)
+#define SIMPAD_UCB1X00_GPIO_PROG2 (SIMPAD_UCB1X00_GPIO_BASE + 1)
+#define SIMPAD_UCB1X00_GPIO_UP (SIMPAD_UCB1X00_GPIO_BASE + 2)
+#define SIMPAD_UCB1X00_GPIO_DOWN (SIMPAD_UCB1X00_GPIO_BASE + 3)
+#define SIMPAD_UCB1X00_GPIO_LEFT (SIMPAD_UCB1X00_GPIO_BASE + 4)
+#define SIMPAD_UCB1X00_GPIO_RIGHT (SIMPAD_UCB1X00_GPIO_BASE + 5)
+#define SIMPAD_UCB1X00_GPIO_6 (SIMPAD_UCB1X00_GPIO_BASE + 6)
+#define SIMPAD_UCB1X00_GPIO_7 (SIMPAD_UCB1X00_GPIO_BASE + 7)
+#define SIMPAD_UCB1X00_GPIO_HEADSET (SIMPAD_UCB1X00_GPIO_BASE + 8)
+#define SIMPAD_UCB1X00_GPIO_SPEAKER (SIMPAD_UCB1X00_GPIO_BASE + 9)
+
+/*--- CS3 Latch ---*/
+#define SIMPAD_CS3_GPIO_BASE (GPIO_MAX + 11)
+#define SIMPAD_CS3_VCC_5V_EN (SIMPAD_CS3_GPIO_BASE)
+#define SIMPAD_CS3_VCC_3V_EN (SIMPAD_CS3_GPIO_BASE + 1)
+#define SIMPAD_CS3_EN1 (SIMPAD_CS3_GPIO_BASE + 2)
+#define SIMPAD_CS3_EN0 (SIMPAD_CS3_GPIO_BASE + 3)
+#define SIMPAD_CS3_DISPLAY_ON (SIMPAD_CS3_GPIO_BASE + 4)
+#define SIMPAD_CS3_PCMCIA_BUFF_DIS (SIMPAD_CS3_GPIO_BASE + 5)
+#define SIMPAD_CS3_MQ_RESET (SIMPAD_CS3_GPIO_BASE + 6)
+#define SIMPAD_CS3_PCMCIA_RESET (SIMPAD_CS3_GPIO_BASE + 7)
+#define SIMPAD_CS3_DECT_POWER_ON (SIMPAD_CS3_GPIO_BASE + 8)
+#define SIMPAD_CS3_IRDA_SD (SIMPAD_CS3_GPIO_BASE + 9)
+#define SIMPAD_CS3_RS232_ON (SIMPAD_CS3_GPIO_BASE + 10)
+#define SIMPAD_CS3_SD_MEDIAQ (SIMPAD_CS3_GPIO_BASE + 11)
+#define SIMPAD_CS3_LED2_ON (SIMPAD_CS3_GPIO_BASE + 12)
+#define SIMPAD_CS3_IRDA_MODE (SIMPAD_CS3_GPIO_BASE + 13)
+#define SIMPAD_CS3_ENABLE_5V (SIMPAD_CS3_GPIO_BASE + 14)
+#define SIMPAD_CS3_RESET_SIMCARD (SIMPAD_CS3_GPIO_BASE + 15)
+
+#define SIMPAD_CS3_PCMCIA_BVD1 (SIMPAD_CS3_GPIO_BASE + 16)
+#define SIMPAD_CS3_PCMCIA_BVD2 (SIMPAD_CS3_GPIO_BASE + 17)
+#define SIMPAD_CS3_PCMCIA_VS1 (SIMPAD_CS3_GPIO_BASE + 18)
+#define SIMPAD_CS3_PCMCIA_VS2 (SIMPAD_CS3_GPIO_BASE + 19)
+#define SIMPAD_CS3_LOCK_IND (SIMPAD_CS3_GPIO_BASE + 20)
+#define SIMPAD_CS3_CHARGING_STATE (SIMPAD_CS3_GPIO_BASE + 21)
+#define SIMPAD_CS3_PCMCIA_SHORT (SIMPAD_CS3_GPIO_BASE + 22)
+#define SIMPAD_CS3_GPIO_23 (SIMPAD_CS3_GPIO_BASE + 23)
+
+#define CS3_BASE IOMEM(0xf1000000)
+
+long simpad_get_cs3_ro(void);
+long simpad_get_cs3_shadow(void);
+void simpad_set_cs3_bit(int value);
+void simpad_clear_cs3_bit(int value);
+
+#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 PCMCIA_BVD1 0x01
+#define PCMCIA_BVD2 0x02
+#define PCMCIA_VS1 0x04
+#define PCMCIA_VS2 0x08
+#define LOCK_IND 0x10
+#define CHARGING_STATE 0x20
+#define PCMCIA_SHORT 0x40
+
+/*--- Battery ---*/
+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/uncompress.h b/arch/arm/mach-sa1100/include/mach/uncompress.h
new file mode 100644
index 000000000..73093dc89
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/uncompress.h
@@ -0,0 +1,51 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/uncompress.h
+ *
+ * (C) 1999 Nicolas Pitre <nico@fluxnic.net>
+ *
+ * Reorganised to be machine independent.
+ */
+
+#include "hardware.h"
+
+#define IOMEM(x) (x)
+
+/*
+ * 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()
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
new file mode 100644
index 000000000..65aebfa66
--- /dev/null
+++ b/arch/arm/mach-sa1100/irq.c
@@ -0,0 +1,178 @@
+/*
+ * 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/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/ioport.h>
+#include <linux/syscore_ops.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <asm/mach/irq.h>
+#include <asm/exception.h>
+
+#include "generic.h"
+
+
+/*
+ * We don't need to ACK IRQs on the SA1100 unless they're GPIOs
+ * this is for internal IRQs i.e. from IRQ LCD to RTCAlrm.
+ */
+static void sa1100_mask_irq(struct irq_data *d)
+{
+ ICMR &= ~BIT(d->hwirq);
+}
+
+static void sa1100_unmask_irq(struct irq_data *d)
+{
+ ICMR |= BIT(d->hwirq);
+}
+
+/*
+ * 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 (BIT(d->hwirq) == IC_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 int sa1100_normal_irqdomain_map(struct irq_domain *d,
+ unsigned int irq, irq_hw_number_t hwirq)
+{
+ irq_set_chip_and_handler(irq, &sa1100_normal_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+
+ return 0;
+}
+
+static struct irq_domain_ops sa1100_normal_irqdomain_ops = {
+ .map = sa1100_normal_irqdomain_map,
+ .xlate = irq_domain_xlate_onetwocell,
+};
+
+static struct irq_domain *sa1100_normal_irqdomain;
+
+static struct resource irq_resource =
+ DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs");
+
+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);
+
+ return 0;
+}
+
+static void sa1100irq_resume(void)
+{
+ struct sa1100irq_state *st = &sa1100irq_state;
+
+ if (st->saved) {
+ ICCR = st->iccr;
+ ICLR = st->iclr;
+
+ 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);
+
+static asmlinkage void __exception_irq_entry
+sa1100_handle_irq(struct pt_regs *regs)
+{
+ uint32_t icip, icmr, mask;
+
+ do {
+ icip = (ICIP);
+ icmr = (ICMR);
+ mask = icip & icmr;
+
+ if (mask == 0)
+ break;
+
+ handle_domain_irq(sa1100_normal_irqdomain,
+ ffs(mask) - 1, regs);
+ } while (1);
+}
+
+void __init sa1100_init_irq(void)
+{
+ request_resource(&iomem_resource, &irq_resource);
+
+ /* disable all IRQs */
+ ICMR = 0;
+
+ /* all IRQs are IRQ, not FIQ */
+ ICLR = 0;
+
+ /*
+ * 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;
+
+ sa1100_normal_irqdomain = irq_domain_add_simple(NULL,
+ 32, IRQ_GPIO0_SC,
+ &sa1100_normal_irqdomain_ops, NULL);
+
+ set_handle_irq(sa1100_handle_irq);
+
+ sa1100_init_gpio();
+}
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
new file mode 100644
index 000000000..c0b1f5baf
--- /dev/null
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -0,0 +1,356 @@
+/*
+ * 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_data/sa11x0-serial.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 <asm/hardware/sa1111.h>
+#include <asm/page.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 <mach/hardware.h>
+#include <mach/irqs.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 0x00002000
+#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] = DEFINE_RES_MEM(EPSONFBSTART, EPSONFBLEN),
+ [1] = DEFINE_RES_MEM(EPSONREGSTART, EPSONREGLEN),
+};
+
+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] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN),
+ [1] = DEFINE_RES_IRQ(IRQ_GPIO1),
+};
+
+static struct sa1111_platform_data sa1111_info = {
+ .disable_devs = SA1111_DEVID_PS2_MSE,
+};
+
+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
+ }
+};
+
+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 =
+ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
+
+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> */
+ .atag_offset = 0x100,
+ .map_io = jornada720_map_io,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = sa1100_init_irq,
+ .init_time = sa1100_timer_init,
+ .init_machine = jornada720_mach_init,
+ .init_late = sa11x0_init_late,
+#ifdef CONFIG_SA1111
+ .dma_zone_size = SZ_1M,
+#endif
+ .restart = sa11x0_restart,
+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 000000000..b143c4659
--- /dev/null
+++ b/arch/arm/mach-sa1100/jornada720_ssp.c
@@ -0,0 +1,203 @@
+/**
+ * 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 <linux/io.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 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);
+}
+
+module_init(jornada_ssp_init);
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
new file mode 100644
index 000000000..51b0eb52c
--- /dev/null
+++ b/arch/arm/mach-sa1100/lart.c
@@ -0,0 +1,176 @@
+/*
+ * linux/arch/arm/mach-sa1100/lart.c
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_data/sa11x0-serial.h>
+#include <linux/tty.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+
+#include <video/sa1100fb.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 <linux/platform_data/mfd-mcp-sa11x0.h>
+#include <mach/irqs.h>
+
+#include "generic.h"
+
+static struct mcp_plat_data lart_mcp_data = {
+ .mccr0 = MCCR0_ADM,
+ .sclk_rate = 11981000,
+};
+
+#ifdef LART_GREY_LCD
+static struct sa1100fb_mach_info lart_grey_info = {
+ .pixclock = 150000, .bpp = 4,
+ .xres = 320, .yres = 240,
+
+ .hsync_len = 1, .vsync_len = 1,
+ .left_margin = 4, .upper_margin = 0,
+ .right_margin = 2, .lower_margin = 0,
+
+ .cmap_greyscale = 1,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+ .lccr0 = LCCR0_Mono | LCCR0_Sngl | LCCR0_Pas | LCCR0_4PixMono,
+ .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
+};
+#endif
+#ifdef LART_COLOR_LCD
+static struct sa1100fb_mach_info lart_color_info = {
+ .pixclock = 150000, .bpp = 16,
+ .xres = 320, .yres = 240,
+
+ .hsync_len = 2, .vsync_len = 3,
+ .left_margin = 69, .upper_margin = 14,
+ .right_margin = 8, .lower_margin = 4,
+
+ .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+ .lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
+};
+#endif
+#ifdef LART_VIDEO_OUT
+static struct sa1100fb_mach_info lart_video_info = {
+ .pixclock = 39721, .bpp = 16,
+ .xres = 640, .yres = 480,
+
+ .hsync_len = 95, .vsync_len = 2,
+ .left_margin = 40, .upper_margin = 32,
+ .right_margin = 24, .lower_margin = 11,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+ .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+ .lccr3 = LCCR3_OutEnL | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
+};
+#endif
+
+#ifdef LART_KIT01_LCD
+static struct sa1100fb_mach_info lart_kit01_info = {
+ .pixclock = 63291, .bpp = 16,
+ .xres = 640, .yres = 480,
+
+ .hsync_len = 64, .vsync_len = 3,
+ .left_margin = 122, .upper_margin = 45,
+ .right_margin = 10, .lower_margin = 10,
+
+ .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+ .lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg
+};
+#endif
+
+static void __init lart_init(void)
+{
+ struct sa1100fb_mach_info *inf = NULL;
+
+#ifdef LART_GREY_LCD
+ inf = &lart_grey_info;
+#endif
+#ifdef LART_COLOR_LCD
+ inf = &lart_color_info;
+#endif
+#ifdef LART_VIDEO_OUT
+ inf = &lart_video_info;
+#endif
+#ifdef LART_KIT01_LCD
+ inf = &lart_kit01_info;
+#endif
+
+ if (inf)
+ sa11x0_register_lcd(inf);
+
+ sa11x0_ppc_configure_mcp();
+ 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
+ }
+};
+
+/* LEDs */
+struct gpio_led lart_gpio_leds[] = {
+ {
+ .name = "lart:red",
+ .default_trigger = "cpu0",
+ .gpio = 23,
+ },
+};
+
+static struct gpio_led_platform_data lart_gpio_led_info = {
+ .leds = lart_gpio_leds,
+ .num_leds = ARRAY_SIZE(lart_gpio_leds),
+};
+
+static struct platform_device lart_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &lart_gpio_led_info,
+ }
+};
+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;
+
+ platform_device_register(&lart_leds);
+}
+
+MACHINE_START(LART, "LART")
+ .atag_offset = 0x100,
+ .map_io = lart_map_io,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = sa1100_init_irq,
+ .init_machine = lart_init,
+ .init_late = sa11x0_init_late,
+ .init_time = sa1100_timer_init,
+ .restart = sa11x0_restart,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c
new file mode 100644
index 000000000..f1cb3784d
--- /dev/null
+++ b/arch/arm/mach-sa1100/nanoengine.c
@@ -0,0 +1,117 @@
+/*
+ * 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/platform_data/sa11x0-serial.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/page.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/nanoengine.h>
+#include <mach/irqs.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[] = {
+ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
+ DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M),
+};
+
+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")
+ .atag_offset = 0x100,
+ .map_io = nanoengine_map_io,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = sa1100_init_irq,
+ .init_time = sa1100_timer_init,
+ .init_machine = nanoengine_init,
+ .init_late = sa11x0_init_late,
+ .restart = sa11x0_restart,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
new file mode 100644
index 000000000..af868d258
--- /dev/null
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -0,0 +1,441 @@
+/*
+ * linux/arch/arm/mach-sa1100/neponset.c
+ */
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_data/sa11x0-serial.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/serial_core.h>
+#include <linux/slab.h>
+#include <linux/smc91x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/sa1111.h>
+#include <asm/sizes.h>
+
+#include <mach/hardware.h>
+#include <mach/assabet.h>
+#include <mach/neponset.h>
+#include <mach/irqs.h>
+
+#define NEP_IRQ_SMC91X 0
+#define NEP_IRQ_USAR 1
+#define NEP_IRQ_SA1111 2
+#define NEP_IRQ_NR 3
+
+#define WHOAMI 0x00
+#define LEDS 0x10
+#define SWPK 0x20
+#define IRR 0x24
+#define KP_Y_IN 0x80
+#define KP_X_OUT 0x90
+#define NCR_0 0xa0
+#define MDM_CTL_0 0xb0
+#define MDM_CTL_1 0xb4
+#define AUD_CTL 0xc0
+
+#define IRR_ETHERNET (1 << 0)
+#define IRR_USAR (1 << 1)
+#define IRR_SA1111 (1 << 2)
+
+#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 AUD_SEL_1341 (1 << 0)
+#define AUD_MUTE_1341 (1 << 1)
+
+extern void sa1110_mb_disable(void);
+
+struct neponset_drvdata {
+ void __iomem *base;
+ struct platform_device *sa1111;
+ struct platform_device *smc91x;
+ unsigned irq_base;
+#ifdef CONFIG_PM_SLEEP
+ u32 ncr0;
+ u32 mdm_ctl_0;
+#endif
+};
+
+static void __iomem *nep_base;
+
+void neponset_ncr_frob(unsigned int mask, unsigned int val)
+{
+ void __iomem *base = nep_base;
+
+ if (base) {
+ unsigned long flags;
+ unsigned v;
+
+ local_irq_save(flags);
+ v = readb_relaxed(base + NCR_0);
+ writeb_relaxed((v & ~mask) | val, base + NCR_0);
+ local_irq_restore(flags);
+ } else {
+ WARN(1, "nep_base unset\n");
+ }
+}
+EXPORT_SYMBOL(neponset_ncr_frob);
+
+static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+ void __iomem *base = nep_base;
+ u_int mdm_ctl0;
+
+ if (!base)
+ return;
+
+ mdm_ctl0 = readb_relaxed(base + 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;
+ }
+
+ writeb_relaxed(mdm_ctl0, base + MDM_CTL_0);
+}
+
+static u_int neponset_get_mctrl(struct uart_port *port)
+{
+ void __iomem *base = nep_base;
+ u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
+ u_int mdm_ctl1;
+
+ if (!base)
+ return ret;
+
+ mdm_ctl1 = readb_relaxed(base + 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 = {
+ .set_mctrl = neponset_set_mctrl,
+ .get_mctrl = neponset_get_mctrl,
+};
+
+/*
+ * 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)
+{
+ struct neponset_drvdata *d = irq_desc_get_handler_data(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 = readb_relaxed(d->base + 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(d->irq_base + NEP_IRQ_SMC91X);
+
+ if (irr & IRR_USAR)
+ generic_handle_irq(d->irq_base + NEP_IRQ_USAR);
+
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
+ }
+
+ if (irr & IRR_SA1111)
+ generic_handle_irq(d->irq_base + NEP_IRQ_SA1111);
+ }
+}
+
+/* Yes, we really do not have any kind of masking or unmasking */
+static void nochip_noop(struct irq_data *irq)
+{
+}
+
+static struct irq_chip nochip = {
+ .name = "neponset",
+ .irq_ack = nochip_noop,
+ .irq_mask = nochip_noop,
+ .irq_unmask = nochip_noop,
+};
+
+static struct sa1111_platform_data sa1111_info = {
+ .disable_devs = SA1111_DEVID_PS2_MSE,
+};
+
+static int neponset_probe(struct platform_device *dev)
+{
+ struct neponset_drvdata *d;
+ struct resource *nep_res, *sa1111_res, *smc91x_res;
+ struct resource sa1111_resources[] = {
+ DEFINE_RES_MEM(0x40000000, SZ_8K),
+ { .flags = IORESOURCE_IRQ },
+ };
+ struct platform_device_info sa1111_devinfo = {
+ .parent = &dev->dev,
+ .name = "sa1111",
+ .id = 0,
+ .res = sa1111_resources,
+ .num_res = ARRAY_SIZE(sa1111_resources),
+ .data = &sa1111_info,
+ .size_data = sizeof(sa1111_info),
+ .dma_mask = 0xffffffffUL,
+ };
+ struct resource smc91x_resources[] = {
+ DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS,
+ 0x02000000, "smc91x-regs"),
+ DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS + 0x02000000,
+ 0x02000000, "smc91x-attrib"),
+ { .flags = IORESOURCE_IRQ },
+ };
+ struct smc91x_platdata smc91x_platdata = {
+ .flags = SMC91X_USE_8BIT | SMC91X_IO_SHIFT_2 | SMC91X_NOWAIT,
+ };
+ struct platform_device_info smc91x_devinfo = {
+ .parent = &dev->dev,
+ .name = "smc91x",
+ .id = 0,
+ .res = smc91x_resources,
+ .num_res = ARRAY_SIZE(smc91x_resources),
+ .data = &smc91x_platdata,
+ .size_data = sizeof(smc91x_platdata),
+ };
+ int ret, irq;
+
+ if (nep_base)
+ return -EBUSY;
+
+ irq = ret = platform_get_irq(dev, 0);
+ if (ret < 0)
+ goto err_alloc;
+
+ nep_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ smc91x_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
+ sa1111_res = platform_get_resource(dev, IORESOURCE_MEM, 2);
+ if (!nep_res || !smc91x_res || !sa1111_res) {
+ ret = -ENXIO;
+ goto err_alloc;
+ }
+
+ d = kzalloc(sizeof(*d), GFP_KERNEL);
+ if (!d) {
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+
+ d->base = ioremap(nep_res->start, SZ_4K);
+ if (!d->base) {
+ ret = -ENOMEM;
+ goto err_ioremap;
+ }
+
+ if (readb_relaxed(d->base + WHOAMI) != 0x11) {
+ dev_warn(&dev->dev, "Neponset board detected, but wrong ID: %02x\n",
+ readb_relaxed(d->base + WHOAMI));
+ ret = -ENODEV;
+ goto err_id;
+ }
+
+ ret = irq_alloc_descs(-1, IRQ_BOARD_START, NEP_IRQ_NR, -1);
+ if (ret <= 0) {
+ dev_err(&dev->dev, "unable to allocate %u irqs: %d\n",
+ NEP_IRQ_NR, ret);
+ if (ret == 0)
+ ret = -ENOMEM;
+ goto err_irq_alloc;
+ }
+
+ d->irq_base = ret;
+
+ irq_set_chip_and_handler(d->irq_base + NEP_IRQ_SMC91X, &nochip,
+ handle_simple_irq);
+ set_irq_flags(d->irq_base + NEP_IRQ_SMC91X, IRQF_VALID | IRQF_PROBE);
+ irq_set_chip_and_handler(d->irq_base + NEP_IRQ_USAR, &nochip,
+ handle_simple_irq);
+ set_irq_flags(d->irq_base + NEP_IRQ_USAR, IRQF_VALID | IRQF_PROBE);
+ irq_set_chip(d->irq_base + NEP_IRQ_SA1111, &nochip);
+
+ irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
+ irq_set_handler_data(irq, d);
+ irq_set_chained_handler(irq, 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 (eth?)
+ */
+#if 0
+ enable_irq_wake(irq);
+#endif
+
+ dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n",
+ d->irq_base, d->irq_base + NEP_IRQ_NR - 1);
+ nep_base = d->base;
+
+ sa1100_register_uart_fns(&neponset_port_fns);
+
+ /* Ensure that the memory bus request/grant signals are setup */
+ sa1110_mb_disable();
+
+ /* Disable GPIO 0/1 drivers so the buttons work on the Assabet */
+ writeb_relaxed(NCR_GP01_OFF, d->base + NCR_0);
+
+ sa1111_resources[0].parent = sa1111_res;
+ sa1111_resources[1].start = d->irq_base + NEP_IRQ_SA1111;
+ sa1111_resources[1].end = d->irq_base + NEP_IRQ_SA1111;
+ d->sa1111 = platform_device_register_full(&sa1111_devinfo);
+
+ smc91x_resources[0].parent = smc91x_res;
+ smc91x_resources[1].parent = smc91x_res;
+ smc91x_resources[2].start = d->irq_base + NEP_IRQ_SMC91X;
+ smc91x_resources[2].end = d->irq_base + NEP_IRQ_SMC91X;
+ d->smc91x = platform_device_register_full(&smc91x_devinfo);
+
+ platform_set_drvdata(dev, d);
+
+ return 0;
+
+ err_irq_alloc:
+ err_id:
+ iounmap(d->base);
+ err_ioremap:
+ kfree(d);
+ err_alloc:
+ return ret;
+}
+
+static int neponset_remove(struct platform_device *dev)
+{
+ struct neponset_drvdata *d = platform_get_drvdata(dev);
+ int irq = platform_get_irq(dev, 0);
+
+ if (!IS_ERR(d->sa1111))
+ platform_device_unregister(d->sa1111);
+ if (!IS_ERR(d->smc91x))
+ platform_device_unregister(d->smc91x);
+ irq_set_chained_handler(irq, NULL);
+ irq_free_descs(d->irq_base, NEP_IRQ_NR);
+ nep_base = NULL;
+ iounmap(d->base);
+ kfree(d);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int neponset_suspend(struct device *dev)
+{
+ struct neponset_drvdata *d = dev_get_drvdata(dev);
+
+ d->ncr0 = readb_relaxed(d->base + NCR_0);
+ d->mdm_ctl_0 = readb_relaxed(d->base + MDM_CTL_0);
+
+ return 0;
+}
+
+static int neponset_resume(struct device *dev)
+{
+ struct neponset_drvdata *d = dev_get_drvdata(dev);
+
+ writeb_relaxed(d->ncr0, d->base + NCR_0);
+ writeb_relaxed(d->mdm_ctl_0, d->base + MDM_CTL_0);
+
+ return 0;
+}
+
+static const struct dev_pm_ops neponset_pm_ops = {
+ .suspend_noirq = neponset_suspend,
+ .resume_noirq = neponset_resume,
+ .freeze_noirq = neponset_suspend,
+ .restore_noirq = neponset_resume,
+};
+#define PM_OPS &neponset_pm_ops
+#else
+#define PM_OPS NULL
+#endif
+
+static struct platform_driver neponset_device_driver = {
+ .probe = neponset_probe,
+ .remove = neponset_remove,
+ .driver = {
+ .name = "neponset",
+ .pm = PM_OPS,
+ },
+};
+
+static int __init neponset_init(void)
+{
+ return platform_driver_register(&neponset_device_driver);
+}
+
+subsys_initcall(neponset_init);
diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c
new file mode 100644
index 000000000..d7ae8d50f
--- /dev/null
+++ b/arch/arm/mach-sa1100/pci-nanoengine.c
@@ -0,0 +1,204 @@
+/*
+ * 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 <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+#include <mach/nanoengine.h>
+#include <mach/hardware.h>
+
+static void __iomem *nanoengine_pci_map_bus(struct pci_bus *bus,
+ unsigned int devfn, int where)
+{
+ if (bus->number != 0 || (devfn >> 3) != 0)
+ return NULL;
+
+ return (void __iomem *)NANO_PCI_CONFIG_SPACE_VIRT +
+ ((bus->number << 16) | (devfn << 8) | (where & ~3));
+}
+
+static struct pci_ops pci_nano_ops = {
+ .map_bus = nanoengine_pci_map_bus,
+ .read = pci_generic_config_read32,
+ .write = pci_generic_config_write32,
+};
+
+static int __init pci_nanoengine_map_irq(const struct pci_dev *dev, u8 slot,
+ u8 pin)
+{
+ return NANOENGINE_IRQ_GPIO_PCI;
+}
+
+static struct resource pci_io_ports =
+ DEFINE_RES_IO_NAMED(0x400, 0x400, "PCI 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 pci_sys_data *sys)
+{
+ 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;
+ }
+ pci_add_resource_offset(&sys->resources, &pci_io_ports, sys->io_offset);
+ pci_add_resource_offset(&sys->resources,
+ &pci_non_prefetchable_memory, sys->mem_offset);
+ pci_add_resource_offset(&sys->resources,
+ &pci_prefetchable_memory, sys->mem_offset);
+
+ return 1;
+}
+
+int __init pci_nanoengine_setup(int nr, struct pci_sys_data *sys)
+{
+ int ret = 0;
+
+ pcibios_min_io = 0;
+ pcibios_min_mem = 0;
+
+ if (nr == 0) {
+ sys->mem_offset = NANO_PCI_MEM_RW_PHYS;
+ sys->io_offset = 0x400;
+ ret = pci_nanoengine_setup_resources(sys);
+ /* 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,
+ .ops = &pci_nano_ops,
+ .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 000000000..1525d7b5f
--- /dev/null
+++ b/arch/arm/mach-sa1100/pleb.c
@@ -0,0 +1,147 @@
+/*
+ * 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_data/sa11x0-serial.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/mtd/partitions.h>
+#include <linux/smc91x.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 <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] = DEFINE_RES_MEM(PLEB_ETH0_P, 0x04000000),
+#if 0 /* Autoprobe instead, to get rising/falling edge characteristic right */
+ [1] = DEFINE_RES_IRQ(IRQ_GPIO_ETH0_IRQ),
+#endif
+};
+
+static struct smc91x_platdata smc91x_platdata = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+ .dev = {
+ .platform_data = &smc91x_platdata,
+ },
+};
+
+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] = DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_8M),
+ [1] = DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_8M),
+};
+
+
+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,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = sa1100_init_irq,
+ .init_time = sa1100_timer_init,
+ .init_machine = pleb_init,
+ .init_late = sa11x0_init_late,
+ .restart = sa11x0_restart,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
new file mode 100644
index 000000000..34853d5df
--- /dev/null
+++ b/arch/arm/mach-sa1100/pm.c
@@ -0,0 +1,126 @@
+/*
+ * 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/io.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+
+#include <mach/hardware.h>
+#include <asm/memory.h>
+#include <asm/suspend.h>
+#include <asm/mach/time.h>
+
+extern int sa1100_finish_suspend(unsigned 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 */
+ cpu_suspend(0, sa1100_finish_suspend);
+
+ /*
+ * Ensure not to come back here if it wasn't intended
+ */
+ RCSR = RCSR_SMR;
+ 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,
+};
+
+int __init sa11x0_pm_init(void)
+{
+ suspend_set_ops(&sa11x0_pm_ops);
+ return 0;
+}
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
new file mode 100644
index 000000000..c8866bce7
--- /dev/null
+++ b/arch/arm/mach-sa1100/shannon.c
@@ -0,0 +1,109 @@
+/*
+ * linux/arch/arm/mach-sa1100/shannon.c
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/platform_data/sa11x0-serial.h>
+#include <linux/tty.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <video/sa1100fb.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 <linux/platform_data/mfd-mcp-sa11x0.h>
+#include <mach/shannon.h>
+#include <mach/irqs.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 =
+ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_4M);
+
+static struct mcp_plat_data shannon_mcp_data = {
+ .mccr0 = MCCR0_ADM,
+ .sclk_rate = 11981000,
+};
+
+static struct sa1100fb_mach_info shannon_lcd_info = {
+ .pixclock = 152500, .bpp = 8,
+ .xres = 640, .yres = 480,
+
+ .hsync_len = 4, .vsync_len = 3,
+ .left_margin = 2, .upper_margin = 0,
+ .right_margin = 1, .lower_margin = 0,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+ .lccr0 = LCCR0_Color | LCCR0_Dual | LCCR0_Pas,
+ .lccr3 = LCCR3_ACBsDiv(512),
+};
+
+static void __init shannon_init(void)
+{
+ sa11x0_ppc_configure_mcp();
+ sa11x0_register_lcd(&shannon_lcd_info);
+ 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)")
+ .atag_offset = 0x100,
+ .map_io = shannon_map_io,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = sa1100_init_irq,
+ .init_time = sa1100_timer_init,
+ .init_machine = shannon_init,
+ .init_late = sa11x0_init_late,
+ .restart = sa11x0_restart,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
new file mode 100644
index 000000000..41e476e57
--- /dev/null
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -0,0 +1,402 @@
+/*
+ * 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_data/sa11x0-serial.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/ucb1x00.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <linux/platform_data/mfd-mcp-sa11x0.h>
+#include <mach/simpad.h>
+#include <mach/irqs.h>
+
+#include <linux/serial_core.h>
+#include <linux/ioport.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/leds.h>
+#include <linux/i2c-gpio.h>
+
+#include "generic.h"
+
+/*
+ * CS3 support
+ */
+
+static long cs3_shadow;
+static spinlock_t cs3_lock;
+static struct gpio_chip cs3_gpio;
+
+long simpad_get_cs3_ro(void)
+{
+ return readl(CS3_BASE);
+}
+EXPORT_SYMBOL(simpad_get_cs3_ro);
+
+long simpad_get_cs3_shadow(void)
+{
+ return cs3_shadow;
+}
+EXPORT_SYMBOL(simpad_get_cs3_shadow);
+
+static void __simpad_write_cs3(void)
+{
+ writel(cs3_shadow, CS3_BASE);
+}
+
+void simpad_set_cs3_bit(int value)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&cs3_lock, flags);
+ cs3_shadow |= value;
+ __simpad_write_cs3();
+ spin_unlock_irqrestore(&cs3_lock, flags);
+}
+EXPORT_SYMBOL(simpad_set_cs3_bit);
+
+void simpad_clear_cs3_bit(int value)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&cs3_lock, flags);
+ cs3_shadow &= ~value;
+ __simpad_write_cs3();
+ spin_unlock_irqrestore(&cs3_lock, flags);
+}
+EXPORT_SYMBOL(simpad_clear_cs3_bit);
+
+static void cs3_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ if (offset > 15)
+ return;
+ if (value)
+ simpad_set_cs3_bit(1 << offset);
+ else
+ simpad_clear_cs3_bit(1 << offset);
+};
+
+static int cs3_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ if (offset > 15)
+ return simpad_get_cs3_ro() & (1 << (offset - 16));
+ return simpad_get_cs3_shadow() & (1 << offset);
+};
+
+static int cs3_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ if (offset > 15)
+ return 0;
+ return -EINVAL;
+};
+
+static int cs3_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ if (offset > 15)
+ return -EINVAL;
+ cs3_gpio_set(chip, offset, value);
+ return 0;
+};
+
+static struct map_desc simpad_io_desc[] __initdata = {
+ { /* MQ200 */
+ .virtual = 0xf2800000,
+ .pfn = __phys_to_pfn(0x4b800000),
+ .length = 0x00800000,
+ .type = MT_DEVICE
+ }, { /* Simpad CS3 */
+ .virtual = (unsigned long)CS3_BASE,
+ .pfn = __phys_to_pfn(SA1100_CS3_PHYS),
+ .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)
+ {
+ simpad_clear_cs3_bit(RS232_ON);
+ simpad_clear_cs3_bit(DECT_POWER_ON);
+ }else
+ {
+ simpad_set_cs3_bit(RS232_ON);
+ simpad_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 [] = {
+ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_16M),
+ DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_16M),
+};
+
+static struct ucb1x00_plat_data simpad_ucb1x00_data = {
+ .gpio_base = SIMPAD_UCB1X00_GPIO_BASE,
+};
+
+static struct mcp_plat_data simpad_mcp_data = {
+ .mccr0 = MCCR0_ADM,
+ .sclk_rate = 11981000,
+ .codec_pdata = &simpad_ucb1x00_data,
+};
+
+
+
+static void __init simpad_map_io(void)
+{
+ sa1100_map_io();
+
+ iotable_init(simpad_io_desc, ARRAY_SIZE(simpad_io_desc));
+
+ /* Initialize CS3 */
+ cs3_shadow = (EN1 | EN0 | LED2_ON | DISPLAY_ON |
+ RS232_ON | ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON);
+ __simpad_write_cs3(); /* Spinlocks not yet initialized */
+
+ 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();
+ cs3_shadow = SD_MEDIAQ;
+ __simpad_write_cs3(); /* Bypass spinlock here */
+
+ /* disable internal oscillator, float CS lines */
+ PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
+ /* enable wake-up on GPIO0 */
+ PWER = GFER = GRER = PWER_GPIO0;
+ /*
+ * 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 */
+
+
+}
+
+/*
+ * gpio_keys
+*/
+
+static struct gpio_keys_button simpad_button_table[] = {
+ { KEY_POWER, IRQ_GPIO_POWER_BUTTON, 1, "power button" },
+};
+
+static struct gpio_keys_platform_data simpad_keys_data = {
+ .buttons = simpad_button_table,
+ .nbuttons = ARRAY_SIZE(simpad_button_table),
+};
+
+static struct platform_device simpad_keys = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &simpad_keys_data,
+ },
+};
+
+static struct gpio_keys_button simpad_polled_button_table[] = {
+ { KEY_PROG1, SIMPAD_UCB1X00_GPIO_PROG1, 1, "prog1 button" },
+ { KEY_PROG2, SIMPAD_UCB1X00_GPIO_PROG2, 1, "prog2 button" },
+ { KEY_UP, SIMPAD_UCB1X00_GPIO_UP, 1, "up button" },
+ { KEY_DOWN, SIMPAD_UCB1X00_GPIO_DOWN, 1, "down button" },
+ { KEY_LEFT, SIMPAD_UCB1X00_GPIO_LEFT, 1, "left button" },
+ { KEY_RIGHT, SIMPAD_UCB1X00_GPIO_RIGHT, 1, "right button" },
+};
+
+static struct gpio_keys_platform_data simpad_polled_keys_data = {
+ .buttons = simpad_polled_button_table,
+ .nbuttons = ARRAY_SIZE(simpad_polled_button_table),
+ .poll_interval = 50,
+};
+
+static struct platform_device simpad_polled_keys = {
+ .name = "gpio-keys-polled",
+ .dev = {
+ .platform_data = &simpad_polled_keys_data,
+ },
+};
+
+/*
+ * GPIO LEDs
+ */
+
+static struct gpio_led simpad_leds[] = {
+ {
+ .name = "simpad:power",
+ .gpio = SIMPAD_CS3_LED2_ON,
+ .active_low = 0,
+ .default_trigger = "default-on",
+ },
+};
+
+static struct gpio_led_platform_data simpad_led_data = {
+ .num_leds = ARRAY_SIZE(simpad_leds),
+ .leds = simpad_leds,
+};
+
+static struct platform_device simpad_gpio_leds = {
+ .name = "leds-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &simpad_led_data,
+ },
+};
+
+/*
+ * i2c
+ */
+static struct i2c_gpio_platform_data simpad_i2c_data = {
+ .sda_pin = GPIO_GPIO21,
+ .scl_pin = GPIO_GPIO25,
+ .udelay = 10,
+ .timeout = HZ,
+};
+
+static struct platform_device simpad_i2c = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &simpad_i2c_data,
+ },
+};
+
+/*
+ * MediaQ Video Device
+ */
+static struct platform_device simpad_mq200fb = {
+ .name = "simpad-mq200",
+ .id = 0,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &simpad_keys,
+ &simpad_polled_keys,
+ &simpad_mq200fb,
+ &simpad_gpio_leds,
+ &simpad_i2c,
+};
+
+
+
+static int __init simpad_init(void)
+{
+ int ret;
+
+ spin_lock_init(&cs3_lock);
+
+ cs3_gpio.label = "simpad_cs3";
+ cs3_gpio.base = SIMPAD_CS3_GPIO_BASE;
+ cs3_gpio.ngpio = 24;
+ cs3_gpio.set = cs3_gpio_set;
+ cs3_gpio.get = cs3_gpio_get;
+ cs3_gpio.direction_input = cs3_gpio_direction_input;
+ cs3_gpio.direction_output = cs3_gpio_direction_output;
+ ret = gpiochip_add(&cs3_gpio);
+ if (ret)
+ printk(KERN_WARNING "simpad: Unable to register cs3 GPIO device");
+
+ pm_power_off = simpad_power_off;
+
+ sa11x0_ppc_configure_mcp();
+ 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 */
+ .atag_offset = 0x100,
+ .map_io = simpad_map_io,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = sa1100_init_irq,
+ .init_late = sa11x0_init_late,
+ .init_time = sa1100_timer_init,
+ .restart = sa11x0_restart,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S
new file mode 100644
index 000000000..85863741e
--- /dev/null
+++ b/arch/arm/mach-sa1100/sleep.S
@@ -0,0 +1,143 @@
+/*
+ * 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_finish_suspend()
+ *
+ * Causes sa11x0 to enter sleep state
+ *
+ * Must be aligned to a cacheline.
+ */
+ .balign 32
+ENTRY(sa1100_finish_suspend)
+ @ disable clock switching
+ mcr p15, 0, r1, c15, c2, 2
+
+ ldr r6, =MDREFR
+ ldr r4, [r6]
+ orr r4, r4, #MDREFR_K1DB2
+ ldr r5, =PPCR
+
+ @ Pre-load __loop_udelay into the I-cache
+ mov r0, #1
+ bl __loop_udelay
+ mov r0, r0
+
+ @ The following must all exist in a single cache line to
+ @ avoid accessing memory until this sequence is complete,
+ @ otherwise we occasionally hang.
+
+ @ Adjust memory timing before lowering CPU clock
+ str r4, [r6]
+
+ @ delay 90us and set CPU PLL to lowest speed
+ @ fixes resume problem on high speed SA1110
+ mov r0, #90
+ bl __loop_udelay
+ mov r1, #0
+ str r1, [r5]
+ mov r0, #90
+ bl __loop_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 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
diff --git a/arch/arm/mach-sa1100/ssp.c b/arch/arm/mach-sa1100/ssp.c
new file mode 100644
index 000000000..e22fca9ad
--- /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 <mach/hardware.h>
+#include <mach/irqs.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-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
new file mode 100644
index 000000000..0fb484221
--- /dev/null
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -0,0 +1,213 @@
+config ARCH_SHMOBILE
+ bool
+ select ZONE_DMA if ARM_LPAE
+
+config PM_RCAR
+ bool
+
+config PM_RMOBILE
+ bool
+ select PM_GENERIC_DOMAINS
+
+config ARCH_RCAR_GEN1
+ bool
+ select PM_RCAR if PM || SMP
+ select RENESAS_INTC_IRQPIN
+ select SYS_SUPPORTS_SH_TMU
+
+config ARCH_RCAR_GEN2
+ bool
+ select PM_RCAR if PM || SMP
+ select RENESAS_IRQC
+ select SYS_SUPPORTS_SH_CMT
+ select PCI_DOMAINS if PCI
+
+config ARCH_RMOBILE
+ bool
+ select PM_RMOBILE if PM
+ select SYS_SUPPORTS_SH_CMT
+ select SYS_SUPPORTS_SH_TMU
+
+menuconfig ARCH_SHMOBILE_MULTI
+ bool "Renesas ARM SoCs" if ARCH_MULTI_V7
+ depends on MMU
+ select ARCH_SHMOBILE
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select ARM_GIC
+ select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
+ select NO_IOPORT_MAP
+ select PINCTRL
+ select ARCH_REQUIRE_GPIOLIB
+
+if ARCH_SHMOBILE_MULTI
+
+#comment "Renesas ARM SoCs System Type"
+
+config ARCH_EMEV2
+ bool "Emma Mobile EV2"
+ select SYS_SUPPORTS_EM_STI
+
+config ARCH_R7S72100
+ bool "RZ/A1H (R7S72100)"
+ select SYS_SUPPORTS_SH_MTU2
+
+config ARCH_R8A73A4
+ bool "R-Mobile APE6 (R8A73A40)"
+ select ARCH_RMOBILE
+ select RENESAS_IRQC
+
+config ARCH_R8A7740
+ bool "R-Mobile A1 (R8A77400)"
+ select ARCH_RMOBILE
+ select RENESAS_INTC_IRQPIN
+
+config ARCH_R8A7778
+ bool "R-Car M1A (R8A77781)"
+ select ARCH_RCAR_GEN1
+
+config ARCH_R8A7779
+ bool "R-Car H1 (R8A77790)"
+ select ARCH_RCAR_GEN1
+
+config ARCH_R8A7790
+ bool "R-Car H2 (R8A77900)"
+ select ARCH_RCAR_GEN2
+ select I2C
+
+config ARCH_R8A7791
+ bool "R-Car M2-W (R8A77910)"
+ select ARCH_RCAR_GEN2
+ select I2C
+
+config ARCH_R8A7794
+ bool "R-Car E2 (R8A77940)"
+ select ARCH_RCAR_GEN2
+
+config ARCH_SH73A0
+ bool "SH-Mobile AG5 (R8A73A00)"
+ select ARCH_RMOBILE
+ select RENESAS_INTC_IRQPIN
+
+comment "Renesas ARM SoCs Board Type"
+
+config MACH_MARZEN
+ bool "MARZEN board"
+ depends on ARCH_R8A7779
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+
+comment "Renesas ARM SoCs System Configuration"
+endif
+
+if ARCH_SHMOBILE_LEGACY
+
+comment "Renesas ARM SoCs System Type"
+
+config ARCH_SH73A0
+ bool "SH-Mobile AG5 (R8A73A00)"
+ select ARCH_RMOBILE
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARM_GIC
+ select I2C
+ select SH_INTC
+ select RENESAS_INTC_IRQPIN
+
+config ARCH_R8A7740
+ bool "R-Mobile A1 (R8A77400)"
+ select ARCH_RMOBILE
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARM_GIC
+ select RENESAS_INTC_IRQPIN
+
+config ARCH_R8A7778
+ bool "R-Car M1A (R8A77781)"
+ select ARCH_RCAR_GEN1
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARM_GIC
+
+config ARCH_R8A7779
+ bool "R-Car H1 (R8A77790)"
+ select ARCH_RCAR_GEN1
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARM_GIC
+
+comment "Renesas ARM SoCs Board Type"
+
+config MACH_ARMADILLO800EVA
+ bool "Armadillo-800 EVA board"
+ depends on ARCH_R8A7740
+ select ARCH_REQUIRE_GPIOLIB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ select SMSC_PHY if SH_ETH
+ select SND_SOC_WM8978 if SND_SIMPLE_CARD
+ select USE_OF
+
+config MACH_BOCKW
+ bool "BOCK-W platform"
+ depends on ARCH_R8A7778
+ select ARCH_REQUIRE_GPIOLIB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ select SND_SOC_AK4554 if SND_SIMPLE_CARD
+ select SND_SOC_AK4642 if SND_SIMPLE_CARD
+ select USE_OF
+
+config MACH_BOCKW_REFERENCE
+ bool "BOCK-W - Reference Device Tree Implementation"
+ depends on ARCH_R8A7778
+ select ARCH_REQUIRE_GPIOLIB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ select USE_OF
+ ---help---
+ Use reference implementation of BockW board support
+ which makes use of device tree at the expense
+ of not supporting a number of devices.
+
+ This is intended to aid developers
+
+config MACH_MARZEN
+ bool "MARZEN board"
+ depends on ARCH_R8A7779
+ select ARCH_REQUIRE_GPIOLIB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ select USE_OF
+
+config MACH_KZM9G
+ bool "KZM-A9-GT board"
+ depends on ARCH_SH73A0
+ select ARCH_REQUIRE_GPIOLIB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ select SND_SOC_AK4642 if SND_SIMPLE_CARD
+ select USE_OF
+
+comment "Renesas ARM SoCs System Configuration"
+
+config CPU_HAS_INTEVT
+ bool
+ default y
+
+config SH_CLK_CPG
+ bool
+
+source "drivers/sh/Kconfig"
+
+endif
+
+if ARCH_SHMOBILE
+
+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.
+ Renesas ARM SoC 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.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
new file mode 100644
index 000000000..89e463de4
--- /dev/null
+++ b/arch/arm/mach-shmobile/Makefile
@@ -0,0 +1,65 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common objects
+obj-y := timer.o console.o
+
+# CPU objects
+obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a0.o pm-sh73a0.o
+obj-$(CONFIG_ARCH_R8A73A4) += setup-r8a73a4.o
+obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o pm-r8a7740.o
+obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o
+obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o pm-r8a7779.o
+obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o
+obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o
+obj-$(CONFIG_ARCH_R8A7794) += setup-r8a7794.o
+obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o
+obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o
+
+# Clock objects
+ifndef CONFIG_COMMON_CLK
+obj-y += clock.o
+obj-$(CONFIG_ARCH_SH73A0) += clock-sh73a0.o
+obj-$(CONFIG_ARCH_R8A7740) += clock-r8a7740.o
+obj-$(CONFIG_ARCH_R8A7778) += clock-r8a7778.o
+obj-$(CONFIG_ARCH_R8A7779) += clock-r8a7779.o
+endif
+
+# CPU reset vector handling objects
+cpu-y := platsmp.o headsmp.o
+
+# Shared SoC family objects
+obj-$(CONFIG_ARCH_RCAR_GEN2) += setup-rcar-gen2.o platsmp-apmu.o $(cpu-y)
+CFLAGS_setup-rcar-gen2.o += -march=armv7-a
+obj-$(CONFIG_ARCH_R8A7790) += regulator-quirk-rcar-gen2.o
+obj-$(CONFIG_ARCH_R8A7791) += regulator-quirk-rcar-gen2.o
+
+# SMP objects
+smp-y := $(cpu-y)
+smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-scu.o platsmp-scu.o
+smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o platsmp-scu.o
+smp-$(CONFIG_ARCH_R8A7790) += smp-r8a7790.o
+smp-$(CONFIG_ARCH_R8A7791) += smp-r8a7791.o
+smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o platsmp-scu.o
+
+# PM objects
+obj-$(CONFIG_SUSPEND) += suspend.o
+obj-$(CONFIG_CPU_FREQ) += cpufreq.o
+obj-$(CONFIG_PM_RCAR) += pm-rcar.o
+obj-$(CONFIG_PM_RMOBILE) += pm-rmobile.o
+obj-$(CONFIG_ARCH_RCAR_GEN2) += pm-rcar-gen2.o
+
+# Board objects
+ifdef CONFIG_ARCH_SHMOBILE_MULTI
+obj-$(CONFIG_MACH_MARZEN) += board-marzen-reference.o
+else
+obj-$(CONFIG_MACH_BOCKW) += board-bockw.o
+obj-$(CONFIG_MACH_BOCKW_REFERENCE) += board-bockw-reference.o
+obj-$(CONFIG_MACH_MARZEN) += board-marzen.o
+obj-$(CONFIG_MACH_ARMADILLO800EVA) += board-armadillo800eva.o
+obj-$(CONFIG_MACH_KZM9G) += board-kzm9g.o intc-sh73a0.o
+endif
+
+# Framework support
+obj-$(CONFIG_SMP) += $(smp-y)
diff --git a/arch/arm/mach-shmobile/Makefile.boot b/arch/arm/mach-shmobile/Makefile.boot
new file mode 100644
index 000000000..e1ef19cef
--- /dev/null
+++ b/arch/arm/mach-shmobile/Makefile.boot
@@ -0,0 +1,15 @@
+# per-board load address for uImage
+loadaddr-y :=
+loadaddr-$(CONFIG_MACH_ARMADILLO800EVA) += 0x40008000
+loadaddr-$(CONFIG_MACH_BOCKW) += 0x60008000
+loadaddr-$(CONFIG_MACH_BOCKW_REFERENCE) += 0x60008000
+loadaddr-$(CONFIG_MACH_KZM9G) += 0x41008000
+loadaddr-$(CONFIG_MACH_MARZEN) += 0x60008000
+
+__ZRELADDR := $(sort $(loadaddr-y))
+ 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-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
new file mode 100644
index 000000000..bf37e3c53
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
@@ -0,0 +1,1365 @@
+/*
+ * armadillo 800 eva board support
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@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.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/i2c-gpio.h>
+#include <linux/input.h>
+#include <linux/irq.h>
+#include <linux/kernel.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/pinctrl/machine.h>
+#include <linux/platform_data/st1232_pdata.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/pwm_backlight.h>
+#include <linux/reboot.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/gpio-regulator.h>
+#include <linux/regulator/machine.h>
+#include <linux/sh_eth.h>
+#include <linux/usb/renesas_usbhs.h>
+#include <linux/videodev2.h>
+
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/page.h>
+#include <media/mt9t112.h>
+#include <media/sh_mobile_ceu.h>
+#include <media/soc_camera.h>
+#include <sound/sh_fsi.h>
+#include <sound/simple_card.h>
+#include <video/sh_mobile_hdmi.h>
+#include <video/sh_mobile_lcdc.h>
+
+#include "common.h"
+#include "irqs.h"
+#include "pm-rmobile.h"
+#include "r8a7740.h"
+#include "sh-gpio.h"
+
+/*
+ * CON1 Camera Module
+ * CON2 Extension Bus
+ * CON3 HDMI Output
+ * CON4 Composite Video Output
+ * CON5 H-UDI JTAG
+ * CON6 ARM JTAG
+ * CON7 SD1
+ * CON8 SD2
+ * CON9 RTC BackUp
+ * CON10 Monaural Mic Input
+ * CON11 Stereo Headphone Output
+ * CON12 Audio Line Output(L)
+ * CON13 Audio Line Output(R)
+ * CON14 AWL13 Module
+ * CON15 Extension
+ * CON16 LCD1
+ * CON17 LCD2
+ * CON19 Power Input
+ * CON20 USB1
+ * CON21 USB2
+ * CON22 Serial
+ * CON23 LAN
+ * CON24 USB3
+ * LED1 Camera LED(Yellow)
+ * LED2 Power LED (Green)
+ * ED3-LED6 User LED(Yellow)
+ * LED7 LAN link LED(Green)
+ * LED8 LAN activity LED(Yellow)
+ */
+
+/*
+ * DipSwitch
+ *
+ * SW1
+ *
+ * -12345678-+---------------+----------------------------
+ * 1 | boot | hermit
+ * 0 | boot | OS auto boot
+ * -12345678-+---------------+----------------------------
+ * 00 | boot device | eMMC
+ * 10 | boot device | SDHI0 (CON7)
+ * 01 | boot device | -
+ * 11 | boot device | Extension Buss (CS0)
+ * -12345678-+---------------+----------------------------
+ * 0 | Extension Bus | D8-D15 disable, eMMC enable
+ * 1 | Extension Bus | D8-D15 enable, eMMC disable
+ * -12345678-+---------------+----------------------------
+ * 0 | SDHI1 | COM8 disable, COM14 enable
+ * 1 | SDHI1 | COM8 enable, COM14 disable
+ * -12345678-+---------------+----------------------------
+ * 0 | USB0 | COM20 enable, COM24 disable
+ * 1 | USB0 | COM20 disable, COM24 enable
+ * -12345678-+---------------+----------------------------
+ * 00 | JTAG | SH-X2
+ * 10 | JTAG | ARM
+ * 01 | JTAG | -
+ * 11 | JTAG | Boundary Scan
+ *-----------+---------------+----------------------------
+ */
+
+/*
+ * FSI-WM8978
+ *
+ * this command is required when playback.
+ *
+ * # amixer set "Headphone" 50
+ *
+ * this command is required when capture.
+ *
+ * # amixer set "Input PGA" 15
+ * # amixer set "Left Input Mixer MicP" on
+ * # amixer set "Left Input Mixer MicN" on
+ * # amixer set "Right Input Mixer MicN" on
+ * # amixer set "Right Input Mixer MicP" on
+ */
+
+/*
+ * USB function
+ *
+ * When you use USB Function,
+ * set SW1.6 ON, and connect cable to CN24.
+ *
+ * USBF needs workaround on R8A7740 chip.
+ * These are a little bit complex.
+ * see
+ * usbhsf_power_ctrl()
+ */
+#define IRQ7 irq_pin(7)
+#define USBCR1 IOMEM(0xe605810a)
+#define USBH 0xC6700000
+#define USBH_USBCTR 0x10834
+
+struct usbhsf_private {
+ struct clk *phy;
+ struct clk *usb24;
+ struct clk *pci;
+ struct clk *func;
+ struct clk *host;
+ void __iomem *usbh_base;
+ struct renesas_usbhs_platform_info info;
+};
+
+#define usbhsf_get_priv(pdev) \
+ container_of(renesas_usbhs_get_info(pdev), \
+ struct usbhsf_private, info)
+
+static int usbhsf_get_id(struct platform_device *pdev)
+{
+ return USBHS_GADGET;
+}
+
+static int usbhsf_power_ctrl(struct platform_device *pdev,
+ void __iomem *base, int enable)
+{
+ struct usbhsf_private *priv = usbhsf_get_priv(pdev);
+
+ /*
+ * Work around for USB Function.
+ * It needs USB host clock, and settings
+ */
+ if (enable) {
+ /*
+ * enable all the related usb clocks
+ * for usb workaround
+ */
+ clk_enable(priv->usb24);
+ clk_enable(priv->pci);
+ clk_enable(priv->host);
+ clk_enable(priv->func);
+ clk_enable(priv->phy);
+
+ /*
+ * set USBCR1
+ *
+ * Port1 is driven by USB function,
+ * Port2 is driven by USB HOST
+ * One HOST (Port1 or Port2 is HOST)
+ * USB PLL input clock = 24MHz
+ */
+ __raw_writew(0xd750, USBCR1);
+ mdelay(1);
+
+ /*
+ * start USB Host
+ */
+ __raw_writel(0x0000000c, priv->usbh_base + USBH_USBCTR);
+ __raw_writel(0x00000008, priv->usbh_base + USBH_USBCTR);
+ mdelay(10);
+
+ /*
+ * USB PHY Power ON
+ */
+ __raw_writew(0xd770, USBCR1);
+ __raw_writew(0x4000, base + 0x102); /* USBF :: SUSPMODE */
+
+ } else {
+ __raw_writel(0x0000010f, priv->usbh_base + USBH_USBCTR);
+ __raw_writew(0xd7c0, USBCR1); /* GPIO */
+
+ clk_disable(priv->phy);
+ clk_disable(priv->func); /* usb work around */
+ clk_disable(priv->host); /* usb work around */
+ clk_disable(priv->pci); /* usb work around */
+ clk_disable(priv->usb24); /* usb work around */
+ }
+
+ return 0;
+}
+
+static int usbhsf_get_vbus(struct platform_device *pdev)
+{
+ return gpio_get_value(209);
+}
+
+static irqreturn_t usbhsf_interrupt(int irq, void *data)
+{
+ struct platform_device *pdev = data;
+
+ renesas_usbhs_call_notify_hotplug(pdev);
+
+ return IRQ_HANDLED;
+}
+
+static int usbhsf_hardware_exit(struct platform_device *pdev)
+{
+ struct usbhsf_private *priv = usbhsf_get_priv(pdev);
+
+ if (!IS_ERR(priv->phy))
+ clk_put(priv->phy);
+ if (!IS_ERR(priv->usb24))
+ clk_put(priv->usb24);
+ if (!IS_ERR(priv->pci))
+ clk_put(priv->pci);
+ if (!IS_ERR(priv->host))
+ clk_put(priv->host);
+ if (!IS_ERR(priv->func))
+ clk_put(priv->func);
+ if (priv->usbh_base)
+ iounmap(priv->usbh_base);
+
+ priv->phy = NULL;
+ priv->usb24 = NULL;
+ priv->pci = NULL;
+ priv->host = NULL;
+ priv->func = NULL;
+ priv->usbh_base = NULL;
+
+ free_irq(IRQ7, pdev);
+
+ return 0;
+}
+
+static int usbhsf_hardware_init(struct platform_device *pdev)
+{
+ struct usbhsf_private *priv = usbhsf_get_priv(pdev);
+ int ret;
+
+ priv->phy = clk_get(&pdev->dev, "phy");
+ priv->usb24 = clk_get(&pdev->dev, "usb24");
+ priv->pci = clk_get(&pdev->dev, "pci");
+ priv->func = clk_get(&pdev->dev, "func");
+ priv->host = clk_get(&pdev->dev, "host");
+ priv->usbh_base = ioremap_nocache(USBH, 0x20000);
+
+ if (IS_ERR(priv->phy) ||
+ IS_ERR(priv->usb24) ||
+ IS_ERR(priv->pci) ||
+ IS_ERR(priv->host) ||
+ IS_ERR(priv->func) ||
+ !priv->usbh_base) {
+ dev_err(&pdev->dev, "USB clock setting failed\n");
+ usbhsf_hardware_exit(pdev);
+ return -EIO;
+ }
+
+ ret = request_irq(IRQ7, usbhsf_interrupt, IRQF_TRIGGER_NONE,
+ dev_name(&pdev->dev), pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq err\n");
+ return ret;
+ }
+ irq_set_irq_type(IRQ7, IRQ_TYPE_EDGE_BOTH);
+
+ /* usb24 use 1/1 of parent clock (= usb24s = 24MHz) */
+ clk_set_rate(priv->usb24,
+ clk_get_rate(clk_get_parent(priv->usb24)));
+
+ return 0;
+}
+
+static struct usbhsf_private usbhsf_private = {
+ .info = {
+ .platform_callback = {
+ .get_id = usbhsf_get_id,
+ .get_vbus = usbhsf_get_vbus,
+ .hardware_init = usbhsf_hardware_init,
+ .hardware_exit = usbhsf_hardware_exit,
+ .power_ctrl = usbhsf_power_ctrl,
+ },
+ .driver_param = {
+ .buswait_bwait = 5,
+ .detection_delay = 5,
+ .d0_rx_id = SHDMA_SLAVE_USBHS_RX,
+ .d1_tx_id = SHDMA_SLAVE_USBHS_TX,
+ },
+ }
+};
+
+static struct resource usbhsf_resources[] = {
+ {
+ .name = "USBHS",
+ .start = 0xe6890000,
+ .end = 0xe6890104 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = gic_spi(51),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usbhsf_device = {
+ .name = "renesas_usbhs",
+ .dev = {
+ .platform_data = &usbhsf_private.info,
+ },
+ .id = -1,
+ .num_resources = ARRAY_SIZE(usbhsf_resources),
+ .resource = usbhsf_resources,
+};
+
+/* Ether */
+static struct sh_eth_plat_data sh_eth_platdata = {
+ .phy = 0x00, /* LAN8710A */
+ .edmac_endian = EDMAC_LITTLE_ENDIAN,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct resource sh_eth_resources[] = {
+ {
+ .start = 0xe9a00000,
+ .end = 0xe9a00800 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = 0xe9a01800,
+ .end = 0xe9a02000 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = gic_spi(110),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sh_eth_device = {
+ .name = "r8a7740-gether",
+ .id = -1,
+ .dev = {
+ .platform_data = &sh_eth_platdata,
+ .dma_mask = &sh_eth_device.dev.coherent_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = sh_eth_resources,
+ .num_resources = ARRAY_SIZE(sh_eth_resources),
+};
+
+/* PWM */
+static struct resource pwm_resources[] = {
+ [0] = {
+ .start = 0xe6600000,
+ .end = 0xe66000ff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device pwm_device = {
+ .name = "renesas-tpu-pwm",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pwm_resources),
+ .resource = pwm_resources,
+};
+
+static struct pwm_lookup pwm_lookup[] = {
+ PWM_LOOKUP("renesas-tpu-pwm", 2, "pwm-backlight.0", NULL,
+ 33333, PWM_POLARITY_INVERSED),
+};
+
+/* LCDC and backlight */
+static struct platform_pwm_backlight_data pwm_backlight_data = {
+ .lth_brightness = 50,
+ .max_brightness = 255,
+ .dft_brightness = 255,
+ .pwm_period_ns = 33333, /* 30kHz */
+ .enable_gpio = 61,
+};
+
+static struct platform_device pwm_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .platform_data = &pwm_backlight_data,
+ },
+};
+
+static struct fb_videomode lcdc0_mode = {
+ .name = "AMPIER/AM-800480",
+ .xres = 800,
+ .yres = 480,
+ .left_margin = 88,
+ .right_margin = 40,
+ .hsync_len = 128,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+ .sync = 0,
+};
+
+static struct sh_mobile_lcdc_info lcdc0_info = {
+ .clock_source = LCDC_CLK_BUS,
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .interface_type = RGB24,
+ .clock_divider = 5,
+ .flags = 0,
+ .lcd_modes = &lcdc0_mode,
+ .num_modes = 1,
+ .panel_cfg = {
+ .width = 111,
+ .height = 68,
+ },
+ },
+};
+
+static struct resource lcdc0_resources[] = {
+ [0] = {
+ .name = "LCD0",
+ .start = 0xfe940000,
+ .end = 0xfe943fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(177),
+ .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 = DMA_BIT_MASK(32),
+ },
+};
+
+/*
+ * LCDC1/HDMI
+ */
+static struct sh_mobile_hdmi_info hdmi_info = {
+ .flags = HDMI_OUTPUT_PUSH_PULL |
+ HDMI_OUTPUT_POLARITY_HI |
+ HDMI_32BIT_REG |
+ HDMI_HAS_HTOP1 |
+ HDMI_SND_SRC_SPDIF,
+};
+
+static struct resource hdmi_resources[] = {
+ [0] = {
+ .name = "HDMI",
+ .start = 0xe6be0000,
+ .end = 0xe6be03ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(131),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .name = "HDMI emma3pf",
+ .start = 0xe6be4000,
+ .end = 0xe6be43ff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+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 const struct fb_videomode lcdc1_mode = {
+ .name = "HDMI 720p",
+ .xres = 1280,
+ .yres = 720,
+ .pixclock = 13468,
+ .left_margin = 220,
+ .right_margin = 110,
+ .hsync_len = 40,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+ .refresh = 60,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+};
+
+static struct sh_mobile_lcdc_info hdmi_lcdc_info = {
+ .clock_source = LCDC_CLK_PERIPHERAL, /* HDMI clock */
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .interface_type = RGB24,
+ .clock_divider = 1,
+ .flags = LCDC_FLAGS_DWPOL,
+ .lcd_modes = &lcdc1_mode,
+ .num_modes = 1,
+ .tx_dev = &hdmi_device,
+ .panel_cfg = {
+ .width = 1280,
+ .height = 720,
+ },
+ },
+};
+
+static struct resource hdmi_lcdc_resources[] = {
+ [0] = {
+ .name = "LCDC1",
+ .start = 0xfe944000,
+ .end = 0xfe948000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(178),
+ .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 = DMA_BIT_MASK(32),
+ },
+};
+
+/* LEDS */
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "LED3",
+ .gpio = 102,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ }, {
+ .name = "LED4",
+ .gpio = 111,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ }, {
+ .name = "LED5",
+ .gpio = 110,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ }, {
+ .name = "LED6",
+ .gpio = 177,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+};
+
+static struct gpio_led_platform_data leds_gpio_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &leds_gpio_info,
+ },
+};
+
+/* GPIO KEY */
+#define GPIO_KEY(c, g, d, ...) \
+ { .code = c, .gpio = g, .desc = d, .active_low = 1, __VA_ARGS__ }
+
+static struct gpio_keys_button gpio_buttons[] = {
+ GPIO_KEY(KEY_POWER, 99, "SW3", .wakeup = 1),
+ GPIO_KEY(KEY_BACK, 100, "SW4"),
+ GPIO_KEY(KEY_MENU, 97, "SW5"),
+ GPIO_KEY(KEY_HOME, 98, "SW6"),
+};
+
+static struct gpio_keys_platform_data gpio_key_info = {
+ .buttons = gpio_buttons,
+ .nbuttons = ARRAY_SIZE(gpio_buttons),
+};
+
+static struct platform_device gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_key_info,
+ },
+};
+
+/* Fixed 3.3V regulator to be used by SDHI1, MMCIF */
+static struct regulator_consumer_supply fixed3v3_power_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sh_mmcif"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mmcif"),
+};
+
+/* Fixed 3.3V regulator used by LCD backlight */
+static struct regulator_consumer_supply fixed5v0_power_consumers[] = {
+ REGULATOR_SUPPLY("power", "pwm-backlight.0"),
+};
+
+/* Fixed 3.3V regulator to be used by SDHI0 */
+static struct regulator_consumer_supply vcc_sdhi0_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+};
+
+static struct regulator_init_data vcc_sdhi0_init_data = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vcc_sdhi0_consumers),
+ .consumer_supplies = vcc_sdhi0_consumers,
+};
+
+static struct fixed_voltage_config vcc_sdhi0_info = {
+ .supply_name = "SDHI0 Vcc",
+ .microvolts = 3300000,
+ .gpio = 75,
+ .enable_high = 1,
+ .init_data = &vcc_sdhi0_init_data,
+};
+
+static struct platform_device vcc_sdhi0 = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &vcc_sdhi0_info,
+ },
+};
+
+/* 1.8 / 3.3V SDHI0 VccQ regulator */
+static struct regulator_consumer_supply vccq_sdhi0_consumers[] = {
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
+};
+
+static struct regulator_init_data vccq_sdhi0_init_data = {
+ .constraints = {
+ .input_uV = 3300000,
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vccq_sdhi0_consumers),
+ .consumer_supplies = vccq_sdhi0_consumers,
+};
+
+static struct gpio vccq_sdhi0_gpios[] = {
+ {17, GPIOF_OUT_INIT_LOW, "vccq-sdhi0" },
+};
+
+static struct gpio_regulator_state vccq_sdhi0_states[] = {
+ { .value = 3300000, .gpios = (0 << 0) },
+ { .value = 1800000, .gpios = (1 << 0) },
+};
+
+static struct gpio_regulator_config vccq_sdhi0_info = {
+ .supply_name = "vqmmc",
+
+ .enable_gpio = 74,
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+
+ .gpios = vccq_sdhi0_gpios,
+ .nr_gpios = ARRAY_SIZE(vccq_sdhi0_gpios),
+
+ .states = vccq_sdhi0_states,
+ .nr_states = ARRAY_SIZE(vccq_sdhi0_states),
+
+ .type = REGULATOR_VOLTAGE,
+ .init_data = &vccq_sdhi0_init_data,
+};
+
+static struct platform_device vccq_sdhi0 = {
+ .name = "gpio-regulator",
+ .id = -1,
+ .dev = {
+ .platform_data = &vccq_sdhi0_info,
+ },
+};
+
+/* Fixed 3.3V regulator to be used by SDHI1 */
+static struct regulator_consumer_supply vcc_sdhi1_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
+};
+
+static struct regulator_init_data vcc_sdhi1_init_data = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vcc_sdhi1_consumers),
+ .consumer_supplies = vcc_sdhi1_consumers,
+};
+
+static struct fixed_voltage_config vcc_sdhi1_info = {
+ .supply_name = "SDHI1 Vcc",
+ .microvolts = 3300000,
+ .gpio = 16,
+ .enable_high = 1,
+ .init_data = &vcc_sdhi1_init_data,
+};
+
+static struct platform_device vcc_sdhi1 = {
+ .name = "reg-fixed-voltage",
+ .id = 2,
+ .dev = {
+ .platform_data = &vcc_sdhi1_info,
+ },
+};
+
+/* SDHI0 */
+static struct tmio_mmc_data sdhi0_info = {
+ .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI0_TX,
+ .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI0_RX,
+ .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
+ MMC_CAP_POWER_OFF_CARD,
+ .flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD,
+ .cd_gpio = 167,
+};
+
+static struct resource sdhi0_resources[] = {
+ {
+ .name = "SDHI0",
+ .start = 0xe6850000,
+ .end = 0xe6850100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ * no SH_MOBILE_SDHI_IRQ_CARD_DETECT here
+ */
+ {
+ .name = SH_MOBILE_SDHI_IRQ_SDCARD,
+ .start = gic_spi(118),
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = SH_MOBILE_SDHI_IRQ_SDIO,
+ .start = gic_spi(119),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi0_device = {
+ .name = "sh_mobile_sdhi",
+ .id = 0,
+ .dev = {
+ .platform_data = &sdhi0_info,
+ },
+ .num_resources = ARRAY_SIZE(sdhi0_resources),
+ .resource = sdhi0_resources,
+};
+
+/* SDHI1 */
+static struct tmio_mmc_data sdhi1_info = {
+ .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI1_TX,
+ .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI1_RX,
+ .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
+ MMC_CAP_POWER_OFF_CARD,
+ .flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD,
+ /* Port72 cannot generate IRQs, will be used in polling mode. */
+ .cd_gpio = 72,
+};
+
+static struct resource sdhi1_resources[] = {
+ [0] = {
+ .name = "SDHI1",
+ .start = 0xe6860000,
+ .end = 0xe6860100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(121),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = gic_spi(122),
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = gic_spi(123),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi1_device = {
+ .name = "sh_mobile_sdhi",
+ .id = 1,
+ .dev = {
+ .platform_data = &sdhi1_info,
+ },
+ .num_resources = ARRAY_SIZE(sdhi1_resources),
+ .resource = sdhi1_resources,
+};
+
+static const struct pinctrl_map eva_sdhi1_pinctrl_map[] = {
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a7740",
+ "sdhi1_data4", "sdhi1"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a7740",
+ "sdhi1_ctrl", "sdhi1"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a7740",
+ "sdhi1_cd", "sdhi1"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a7740",
+ "sdhi1_wp", "sdhi1"),
+};
+
+/* MMCIF */
+static struct sh_mmcif_plat_data sh_mmcif_plat = {
+ .sup_pclk = 0,
+ .caps = MMC_CAP_4_BIT_DATA |
+ MMC_CAP_8_BIT_DATA |
+ MMC_CAP_NONREMOVABLE,
+ .ccs_unsupported = true,
+ .slave_id_tx = SHDMA_SLAVE_MMCIF_TX,
+ .slave_id_rx = SHDMA_SLAVE_MMCIF_RX,
+};
+
+static struct resource sh_mmcif_resources[] = {
+ [0] = {
+ .name = "MMCIF",
+ .start = 0xe6bd0000,
+ .end = 0xe6bd0100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* MMC ERR */
+ .start = gic_spi(56),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* MMC NOR */
+ .start = gic_spi(57),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sh_mmcif_device = {
+ .name = "sh_mmcif",
+ .id = -1,
+ .dev = {
+ .platform_data = &sh_mmcif_plat,
+ },
+ .num_resources = ARRAY_SIZE(sh_mmcif_resources),
+ .resource = sh_mmcif_resources,
+};
+
+/* Camera */
+static int mt9t111_power(struct device *dev, int mode)
+{
+ struct clk *mclk = clk_get(NULL, "video1");
+
+ if (IS_ERR(mclk)) {
+ dev_err(dev, "can't get video1 clock\n");
+ return -EINVAL;
+ }
+
+ if (mode) {
+ /* video1 (= CON1 camera) expect 24MHz */
+ clk_set_rate(mclk, clk_round_rate(mclk, 24000000));
+ clk_enable(mclk);
+ gpio_set_value(158, 1);
+ } else {
+ gpio_set_value(158, 0);
+ clk_disable(mclk);
+ }
+
+ clk_put(mclk);
+
+ return 0;
+}
+
+static struct i2c_board_info i2c_camera_mt9t111 = {
+ I2C_BOARD_INFO("mt9t112", 0x3d),
+};
+
+static struct mt9t112_camera_info mt9t111_info = {
+ .divider = { 16, 0, 0, 7, 0, 10, 14, 7, 7 },
+};
+
+static struct soc_camera_link mt9t111_link = {
+ .i2c_adapter_id = 0,
+ .bus_id = 0,
+ .board_info = &i2c_camera_mt9t111,
+ .power = mt9t111_power,
+ .priv = &mt9t111_info,
+};
+
+static struct platform_device camera_device = {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &mt9t111_link,
+ },
+};
+
+/* CEU0 */
+static struct sh_mobile_ceu_info sh_mobile_ceu0_info = {
+ .flags = SH_CEU_FLAG_LOWER_8BIT,
+};
+
+static struct resource ceu0_resources[] = {
+ [0] = {
+ .name = "CEU",
+ .start = 0xfe910000,
+ .end = 0xfe91009f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(160),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* place holder for contiguous memory */
+ },
+};
+
+static struct platform_device ceu0_device = {
+ .name = "sh_mobile_ceu",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(ceu0_resources),
+ .resource = ceu0_resources,
+ .dev = {
+ .platform_data = &sh_mobile_ceu0_info,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+/* FSI */
+static struct sh_fsi_platform_info fsi_info = {
+ /* FSI-WM8978 */
+ .port_a = {
+ .tx_id = SHDMA_SLAVE_FSIA_TX,
+ },
+ /* FSI-HDMI */
+ .port_b = {
+ .flags = SH_FSI_FMT_SPDIF |
+ SH_FSI_ENABLE_STREAM_MODE |
+ SH_FSI_CLK_CPG,
+ .tx_id = SHDMA_SLAVE_FSIB_TX,
+ }
+};
+
+static struct resource fsi_resources[] = {
+ [0] = {
+ .name = "FSI",
+ .start = 0xfe1f0000,
+ .end = 0xfe1f0400 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(9),
+ .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,
+ },
+};
+
+/* FSI-WM8978 */
+static struct asoc_simple_card_info fsi_wm8978_info = {
+ .name = "wm8978",
+ .card = "FSI2A-WM8978",
+ .codec = "wm8978.0-001a",
+ .platform = "sh_fsi2",
+ .daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM,
+ .cpu_dai = {
+ .name = "fsia-dai",
+ },
+ .codec_dai = {
+ .name = "wm8978-hifi",
+ .sysclk = 12288000,
+ },
+};
+
+static struct platform_device fsi_wm8978_device = {
+ .name = "asoc-simple-card",
+ .id = 0,
+ .dev = {
+ .platform_data = &fsi_wm8978_info,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .dma_mask = &fsi_wm8978_device.dev.coherent_dma_mask,
+ },
+};
+
+/* FSI-HDMI */
+static struct asoc_simple_card_info fsi2_hdmi_info = {
+ .name = "HDMI",
+ .card = "FSI2B-HDMI",
+ .codec = "sh-mobile-hdmi",
+ .platform = "sh_fsi2",
+ .daifmt = SND_SOC_DAIFMT_CBS_CFS,
+ .cpu_dai = {
+ .name = "fsib-dai",
+ },
+ .codec_dai = {
+ .name = "sh_mobile_hdmi-hifi",
+ },
+};
+
+static struct platform_device fsi_hdmi_device = {
+ .name = "asoc-simple-card",
+ .id = 1,
+ .dev = {
+ .platform_data = &fsi2_hdmi_info,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .dma_mask = &fsi_hdmi_device.dev.coherent_dma_mask,
+ },
+};
+
+/* RTC: RTC connects i2c-gpio. */
+static struct i2c_gpio_platform_data i2c_gpio_data = {
+ .sda_pin = 208,
+ .scl_pin = 91,
+ .udelay = 5, /* 100 kHz */
+};
+
+static struct platform_device i2c_gpio_device = {
+ .name = "i2c-gpio",
+ .id = 2,
+ .dev = {
+ .platform_data = &i2c_gpio_data,
+ },
+};
+
+/* I2C */
+static struct st1232_pdata st1232_i2c0_pdata = {
+ .reset_gpio = 166,
+};
+
+static struct i2c_board_info i2c0_devices[] = {
+ {
+ I2C_BOARD_INFO("st1232-ts", 0x55),
+ .irq = irq_pin(10),
+ .platform_data = &st1232_i2c0_pdata,
+ },
+ {
+ I2C_BOARD_INFO("wm8978", 0x1a),
+ },
+};
+
+static struct i2c_board_info i2c2_devices[] = {
+ {
+ I2C_BOARD_INFO("s35390a", 0x30),
+ .type = "s35390a",
+ },
+};
+
+/*
+ * board devices
+ */
+static struct platform_device *eva_devices[] __initdata = {
+ &lcdc0_device,
+ &pwm_device,
+ &pwm_backlight_device,
+ &leds_gpio_device,
+ &gpio_keys_device,
+ &sh_eth_device,
+ &vcc_sdhi0,
+ &vccq_sdhi0,
+ &sdhi0_device,
+ &sh_mmcif_device,
+ &hdmi_device,
+ &hdmi_lcdc_device,
+ &camera_device,
+ &ceu0_device,
+ &fsi_device,
+ &fsi_wm8978_device,
+ &fsi_hdmi_device,
+ &i2c_gpio_device,
+};
+
+static const struct pinctrl_map eva_pinctrl_map[] = {
+ /* CEU0 */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-r8a7740",
+ "ceu0_data_0_7", "ceu0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-r8a7740",
+ "ceu0_clk_0", "ceu0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-r8a7740",
+ "ceu0_sync", "ceu0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-r8a7740",
+ "ceu0_field", "ceu0"),
+ /* FSIA */
+ PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-r8a7740",
+ "fsia_sclk_in", "fsia"),
+ PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-r8a7740",
+ "fsia_mclk_out", "fsia"),
+ PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-r8a7740",
+ "fsia_data_in_1", "fsia"),
+ PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-r8a7740",
+ "fsia_data_out_0", "fsia"),
+ /* FSIB */
+ PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.1", "pfc-r8a7740",
+ "fsib_mclk_in", "fsib"),
+ /* GETHER */
+ PIN_MAP_MUX_GROUP_DEFAULT("r8a7740-gether", "pfc-r8a7740",
+ "gether_mii", "gether"),
+ PIN_MAP_MUX_GROUP_DEFAULT("r8a7740-gether", "pfc-r8a7740",
+ "gether_int", "gether"),
+ /* HDMI */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh-mobile-hdmi", "pfc-r8a7740",
+ "hdmi", "hdmi"),
+ /* LCD0 */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-r8a7740",
+ "lcd0_data24_0", "lcd0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-r8a7740",
+ "lcd0_lclk_1", "lcd0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-r8a7740",
+ "lcd0_sync", "lcd0"),
+ /* MMCIF */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-r8a7740",
+ "mmc0_data8_1", "mmc0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-r8a7740",
+ "mmc0_ctrl_1", "mmc0"),
+ /* SCIFA1 */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.1", "pfc-r8a7740",
+ "scifa1_data", "scifa1"),
+ /* SDHI0 */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7740",
+ "sdhi0_data4", "sdhi0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7740",
+ "sdhi0_ctrl", "sdhi0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7740",
+ "sdhi0_wp", "sdhi0"),
+ /* ST1232 */
+ PIN_MAP_MUX_GROUP_DEFAULT("0-0055", "pfc-r8a7740",
+ "intc_irq10", "intc"),
+ /* TPU0 */
+ PIN_MAP_MUX_GROUP_DEFAULT("renesas-tpu-pwm", "pfc-r8a7740",
+ "tpu0_to2_1", "tpu0"),
+ /* USBHS */
+ PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs", "pfc-r8a7740",
+ "intc_irq7_1", "intc"),
+};
+
+static void __init eva_clock_init(void)
+{
+ struct clk *system = clk_get(NULL, "system_clk");
+ struct clk *xtal1 = clk_get(NULL, "extal1");
+ struct clk *usb24s = clk_get(NULL, "usb24s");
+ struct clk *fsibck = clk_get(NULL, "fsibck");
+
+ if (IS_ERR(system) ||
+ IS_ERR(xtal1) ||
+ IS_ERR(usb24s) ||
+ IS_ERR(fsibck)) {
+ pr_err("armadillo800eva board clock init failed\n");
+ goto clock_error;
+ }
+
+ /* armadillo 800 eva extal1 is 24MHz */
+ clk_set_rate(xtal1, 24000000);
+
+ /* usb24s use extal1 (= system) clock (= 24MHz) */
+ clk_set_parent(usb24s, system);
+
+ /* FSIBCK is 12.288MHz, and it is parent of FSI-B */
+ clk_set_rate(fsibck, 12288000);
+
+clock_error:
+ if (!IS_ERR(system))
+ clk_put(system);
+ if (!IS_ERR(xtal1))
+ clk_put(xtal1);
+ if (!IS_ERR(usb24s))
+ clk_put(usb24s);
+ if (!IS_ERR(fsibck))
+ clk_put(fsibck);
+}
+
+/*
+ * board init
+ */
+#define GPIO_PORT7CR IOMEM(0xe6050007)
+#define GPIO_PORT8CR IOMEM(0xe6050008)
+static void __init eva_init(void)
+{
+ static struct pm_domain_device domain_devices[] __initdata = {
+ { "A4LC", &lcdc0_device },
+ { "A4LC", &hdmi_lcdc_device },
+ { "A4MP", &hdmi_device },
+ { "A4MP", &fsi_device },
+ { "A4R", &ceu0_device },
+ { "A4S", &sh_eth_device },
+ { "A3SP", &pwm_device },
+ { "A3SP", &sdhi0_device },
+ { "A3SP", &sh_mmcif_device },
+ };
+ struct platform_device *usb = NULL, *sdhi1 = NULL;
+
+ regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
+ ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
+ regulator_register_always_on(3, "fixed-5.0V", fixed5v0_power_consumers,
+ ARRAY_SIZE(fixed5v0_power_consumers), 5000000);
+
+ pinctrl_register_mappings(eva_pinctrl_map, ARRAY_SIZE(eva_pinctrl_map));
+ pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
+
+ r8a7740_pinmux_init();
+ r8a7740_meram_workaround();
+
+ /* GETHER */
+ gpio_request_one(18, GPIOF_OUT_INIT_HIGH, NULL); /* PHY_RST */
+
+ /* USB */
+ gpio_request_one(159, GPIOF_IN, NULL); /* USB_DEVICE_MODE */
+
+ if (gpio_get_value(159)) {
+ /* USB Host */
+ } else {
+ /* USB Func */
+ /*
+ * The USBHS interrupt handlers needs to read the IRQ pin value
+ * (HI/LOW) to diffentiate USB connection and disconnection
+ * events (usbhsf_get_vbus()). We thus need to select both the
+ * intc_irq7_1 pin group and GPIO 209 here.
+ */
+ gpio_request_one(209, GPIOF_IN, NULL);
+
+ platform_device_register(&usbhsf_device);
+ usb = &usbhsf_device;
+ }
+
+ /* CON1/CON15 Camera */
+ gpio_request_one(173, GPIOF_OUT_INIT_LOW, NULL); /* STANDBY */
+ gpio_request_one(172, GPIOF_OUT_INIT_HIGH, NULL); /* RST */
+ /* see mt9t111_power() */
+ gpio_request_one(158, GPIOF_OUT_INIT_LOW, NULL); /* CAM_PON */
+
+ /* FSI-WM8978 */
+ gpio_request(7, NULL);
+ gpio_request(8, NULL);
+ gpio_direction_none(GPIO_PORT7CR); /* FSIAOBT needs no direction */
+ gpio_direction_none(GPIO_PORT8CR); /* FSIAOLR needs no direction */
+
+ /*
+ * CAUTION
+ *
+ * DBGMD/LCDC0/FSIA MUX
+ * DBGMD_SELECT_B should be set after setting PFC Function.
+ */
+ gpio_request_one(176, GPIOF_OUT_INIT_HIGH, NULL);
+
+ /*
+ * We can switch CON8/CON14 by SW1.5,
+ * but it needs after DBGMD_SELECT_B
+ */
+ gpio_request_one(6, GPIOF_IN, NULL);
+ if (gpio_get_value(6)) {
+ /* CON14 enable */
+ } else {
+ /* CON8 (SDHI1) enable */
+ pinctrl_register_mappings(eva_sdhi1_pinctrl_map,
+ ARRAY_SIZE(eva_sdhi1_pinctrl_map));
+
+ platform_device_register(&vcc_sdhi1);
+ platform_device_register(&sdhi1_device);
+ sdhi1 = &sdhi1_device;
+ }
+
+
+#ifdef CONFIG_CACHE_L2X0
+ /* Shared attribute override enable, 32K*8way */
+ l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff);
+#endif
+
+ i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
+ i2c_register_board_info(2, i2c2_devices, ARRAY_SIZE(i2c2_devices));
+
+ r8a7740_add_standard_devices();
+
+ platform_add_devices(eva_devices,
+ ARRAY_SIZE(eva_devices));
+
+ rmobile_add_devices_to_domains(domain_devices,
+ ARRAY_SIZE(domain_devices));
+ if (usb)
+ rmobile_add_device_to_domain("A3SP", usb);
+ if (sdhi1)
+ rmobile_add_device_to_domain("A3SP", sdhi1);
+
+ r8a7740_pm_init();
+}
+
+static void __init eva_earlytimer_init(void)
+{
+ r8a7740_clock_init(MD_CK0 | MD_CK2);
+ shmobile_earlytimer_init();
+
+ /* the rate of extal1 clock must be set before late_time_init */
+ eva_clock_init();
+}
+
+#define RESCNT2 IOMEM(0xe6188020)
+static void eva_restart(enum reboot_mode mode, const char *cmd)
+{
+ /* Do soft power on reset */
+ writel((1 << 31), RESCNT2);
+}
+
+static const char *eva_boards_compat_dt[] __initdata = {
+ "renesas,armadillo800eva",
+ NULL,
+};
+
+DT_MACHINE_START(ARMADILLO800EVA_DT, "armadillo800eva")
+ .map_io = r8a7740_map_io,
+ .init_early = r8a7740_add_early_devices,
+ .init_irq = r8a7740_init_irq_of,
+ .init_machine = eva_init,
+ .init_late = shmobile_init_late,
+ .init_time = eva_earlytimer_init,
+ .dt_compat = eva_boards_compat_dt,
+ .restart = eva_restart,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-bockw-reference.c b/arch/arm/mach-shmobile/board-bockw-reference.c
new file mode 100644
index 000000000..9a74efda3
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-bockw-reference.c
@@ -0,0 +1,86 @@
+/*
+ * Bock-W board support
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@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.
+ */
+
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+
+#include "common.h"
+#include "r8a7778.h"
+
+/*
+ * see board-bock.c for checking detail of dip-switch
+ */
+
+#define FPGA 0x18200000
+#define IRQ0MR 0x30
+#define COMCTLR 0x101c
+
+#define PFC 0xfffc0000
+#define PUPR4 0x110
+static void __init bockw_init(void)
+{
+ void __iomem *fpga;
+ void __iomem *pfc;
+
+#ifndef CONFIG_COMMON_CLK
+ r8a7778_clock_init();
+#endif
+ r8a7778_init_irq_extpin_dt(1);
+ r8a7778_add_dt_devices();
+
+ fpga = ioremap_nocache(FPGA, SZ_1M);
+ if (fpga) {
+ /*
+ * CAUTION
+ *
+ * IRQ0/1 is cascaded interrupt from FPGA.
+ * it should be cared in the future
+ * Now, it is assuming IRQ0 was used only from SMSC.
+ */
+ u16 val = ioread16(fpga + IRQ0MR);
+ val &= ~(1 << 4); /* enable SMSC911x */
+ iowrite16(val, fpga + IRQ0MR);
+
+ iounmap(fpga);
+ }
+
+ pfc = ioremap_nocache(PFC, 0x200);
+ if (pfc) {
+ /*
+ * FIXME
+ *
+ * SDHI CD/WP pin needs pull-up
+ */
+ iowrite32(ioread32(pfc + PUPR4) | (3 << 26), pfc + PUPR4);
+ iounmap(pfc);
+ }
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char *bockw_boards_compat_dt[] __initdata = {
+ "renesas,bockw-reference",
+ NULL,
+};
+
+DT_MACHINE_START(BOCKW_DT, "bockw")
+ .init_early = shmobile_init_delay,
+ .init_irq = r8a7778_init_irq_dt,
+ .init_machine = bockw_init,
+ .init_late = shmobile_init_late,
+ .dt_compat = bockw_boards_compat_dt,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c
new file mode 100644
index 000000000..25558d1f4
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-bockw.c
@@ -0,0 +1,737 @@
+/*
+ * Bock-W board support
+ *
+ * Copyright (C) 2013-2014 Renesas Solutions Corp.
+ * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ * Copyright (C) 2013-2014 Cogent Embedded, 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; 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/mfd/tmio.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
+#include <linux/mmc/sh_mmcif.h>
+#include <linux/mtd/partitions.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/platform_data/camera-rcar.h>
+#include <linux/platform_data/usb-rcar-phy.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/smsc911x.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/usb/renesas_usbhs.h>
+
+#include <media/soc_camera.h>
+#include <asm/mach/arch.h>
+#include <sound/rcar_snd.h>
+#include <sound/simple_card.h>
+
+#include "common.h"
+#include "irqs.h"
+#include "r8a7778.h"
+
+#define FPGA 0x18200000
+#define IRQ0MR 0x30
+#define COMCTLR 0x101c
+static void __iomem *fpga;
+
+/*
+ * CN9(Upper side) SCIF/RCAN selection
+ *
+ * 1,4 3,6
+ * SW40 SCIF RCAN
+ * SW41 SCIF RCAN
+ */
+
+/*
+ * MMC (CN26) pin
+ *
+ * SW6 (D2) 3 pin
+ * SW7 (D5) ON
+ * SW8 (D3) 3 pin
+ * SW10 (D4) 1 pin
+ * SW12 (CLK) 1 pin
+ * SW13 (D6) 3 pin
+ * SW14 (CMD) ON
+ * SW15 (D6) 1 pin
+ * SW16 (D0) ON
+ * SW17 (D1) ON
+ * SW18 (D7) 3 pin
+ * SW19 (MMC) 1 pin
+ */
+
+/*
+ * SSI settings
+ *
+ * SW45: 1-4 side (SSI5 out, ROUT/LOUT CN19 Mid)
+ * SW46: 1101 (SSI6 Recorde)
+ * SW47: 1110 (SSI5 Playback)
+ * SW48: 11 (Recorde power)
+ * SW49: 1 (SSI slave mode)
+ * SW50: 1111 (SSI7, SSI8)
+ * SW51: 1111 (SSI3, SSI4)
+ * SW54: 1pin (ak4554 FPGA control)
+ * SW55: 1 (CLKB is 24.5760MHz)
+ * SW60: 1pin (ak4554 FPGA control)
+ * SW61: 3pin (use X11 clock)
+ * SW78: 3-6 (ak4642 connects I2C0)
+ *
+ * You can use sound as
+ *
+ * hw0: CN19: SSI56-AK4643
+ * hw1: CN21: SSI3-AK4554(playback)
+ * hw2: CN21: SSI4-AK4554(capture)
+ * hw3: CN20: SSI7-AK4554(playback)
+ * hw4: CN20: SSI8-AK4554(capture)
+ *
+ * this command is required when playback on hw0.
+ *
+ * # amixer set "LINEOUT Mixer DACL" on
+ */
+
+/*
+ * USB
+ *
+ * USB1 (CN29) can be Host/Function
+ *
+ * Host Func
+ * SW98 1 2
+ * SW99 1 3
+ */
+
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+};
+
+static struct regulator_consumer_supply fixed3v3_power_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sh_mmcif"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mmcif"),
+};
+
+static struct smsc911x_platform_config smsc911x_data __initdata = {
+ .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 resource smsc911x_resources[] __initdata = {
+ DEFINE_RES_MEM(0x18300000, 0x1000),
+ DEFINE_RES_IRQ(irq_pin(0)), /* IRQ 0 */
+};
+
+#if IS_ENABLED(CONFIG_USB_RENESAS_USBHS_UDC)
+/*
+ * When USB1 is Func
+ */
+static int usbhsf_get_id(struct platform_device *pdev)
+{
+ return USBHS_GADGET;
+}
+
+#define SUSPMODE 0x102
+static int usbhsf_power_ctrl(struct platform_device *pdev,
+ void __iomem *base, int enable)
+{
+ enable = !!enable;
+
+ r8a7778_usb_phy_power(enable);
+
+ iowrite16(enable << 14, base + SUSPMODE);
+
+ return 0;
+}
+
+static struct resource usbhsf_resources[] __initdata = {
+ DEFINE_RES_MEM(0xffe60000, 0x110),
+ DEFINE_RES_IRQ(gic_iid(0x4f)),
+};
+
+static struct renesas_usbhs_platform_info usbhs_info __initdata = {
+ .platform_callback = {
+ .get_id = usbhsf_get_id,
+ .power_ctrl = usbhsf_power_ctrl,
+ },
+ .driver_param = {
+ .buswait_bwait = 4,
+ .d0_tx_id = HPBDMA_SLAVE_USBFUNC_TX,
+ .d1_rx_id = HPBDMA_SLAVE_USBFUNC_RX,
+ },
+};
+
+#define USB_PHY_SETTING {.port1_func = 1, .ovc_pin[1].active_high = 1,}
+#define USB1_DEVICE "renesas_usbhs"
+#define ADD_USB_FUNC_DEVICE_IF_POSSIBLE() \
+ platform_device_register_resndata( \
+ NULL, "renesas_usbhs", -1, \
+ usbhsf_resources, \
+ ARRAY_SIZE(usbhsf_resources), \
+ &usbhs_info, sizeof(struct renesas_usbhs_platform_info))
+
+#else
+/*
+ * When USB1 is Host
+ */
+#define USB_PHY_SETTING { }
+#define USB1_DEVICE "ehci-platform"
+#define ADD_USB_FUNC_DEVICE_IF_POSSIBLE()
+
+#endif
+
+/* USB */
+static struct resource usb_phy_resources[] __initdata = {
+ DEFINE_RES_MEM(0xffe70800, 0x100),
+ DEFINE_RES_MEM(0xffe76000, 0x100),
+};
+
+static struct rcar_phy_platform_data usb_phy_platform_data __initdata =
+ USB_PHY_SETTING;
+
+
+/* SDHI */
+static struct tmio_mmc_data sdhi0_info __initdata = {
+ .chan_priv_tx = (void *)HPBDMA_SLAVE_SDHI0_TX,
+ .chan_priv_rx = (void *)HPBDMA_SLAVE_SDHI0_RX,
+ .capabilities = MMC_CAP_SD_HIGHSPEED,
+ .ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
+ .flags = TMIO_MMC_HAS_IDLE_WAIT,
+};
+
+static struct resource sdhi0_resources[] __initdata = {
+ DEFINE_RES_MEM(0xFFE4C000, 0x100),
+ DEFINE_RES_IRQ(gic_iid(0x77)),
+};
+
+/* Ether */
+static struct resource ether_resources[] __initdata = {
+ DEFINE_RES_MEM(0xfde00000, 0x400),
+ DEFINE_RES_IRQ(gic_iid(0x89)),
+};
+
+static struct sh_eth_plat_data ether_platform_data __initdata = {
+ .phy = 0x01,
+ .edmac_endian = EDMAC_LITTLE_ENDIAN,
+ .phy_interface = PHY_INTERFACE_MODE_RMII,
+ /*
+ * Although the LINK signal is available on the board, it's connected to
+ * the link/activity LED output of the PHY, thus the link disappears and
+ * reappears after each packet. We'd be better off ignoring such signal
+ * and getting the link state from the PHY indirectly.
+ */
+ .no_ether_link = 1,
+};
+
+static struct platform_device_info ether_info __initdata = {
+ .name = "r8a777x-ether",
+ .id = -1,
+ .res = ether_resources,
+ .num_res = ARRAY_SIZE(ether_resources),
+ .data = &ether_platform_data,
+ .size_data = sizeof(ether_platform_data),
+ .dma_mask = DMA_BIT_MASK(32),
+};
+
+/* I2C */
+static struct i2c_board_info i2c0_devices[] = {
+ {
+ I2C_BOARD_INFO("rx8581", 0x51),
+ }, {
+ I2C_BOARD_INFO("ak4643", 0x12),
+ }
+};
+
+/* HSPI*/
+static struct mtd_partition m25p80_spi_flash_partitions[] = {
+ {
+ .name = "data(spi)",
+ .size = 0x0100000,
+ .offset = 0,
+ },
+};
+
+static struct flash_platform_data spi_flash_data = {
+ .name = "m25p80",
+ .type = "s25fl008k",
+ .parts = m25p80_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(m25p80_spi_flash_partitions),
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "m25p80",
+ .max_speed_hz = 104000000,
+ .chip_select = 0,
+ .bus_num = 0,
+ .mode = SPI_MODE_0,
+ .platform_data = &spi_flash_data,
+ },
+};
+
+/* MMC */
+static struct resource mmc_resources[] __initdata = {
+ DEFINE_RES_MEM(0xffe4e000, 0x100),
+ DEFINE_RES_IRQ(gic_iid(0x5d)),
+};
+
+static struct sh_mmcif_plat_data sh_mmcif_plat __initdata = {
+ .sup_pclk = 0,
+ .caps = MMC_CAP_4_BIT_DATA |
+ MMC_CAP_8_BIT_DATA |
+ MMC_CAP_NEEDS_POLL,
+};
+
+/* In the default configuration both decoders reside on I2C bus 0 */
+#define BOCKW_CAMERA(idx) \
+static struct i2c_board_info camera##idx##_info = { \
+ I2C_BOARD_INFO("ml86v7667", 0x41 + 2 * (idx)), \
+}; \
+ \
+static struct soc_camera_link iclink##idx##_ml86v7667 __initdata = { \
+ .bus_id = idx, \
+ .i2c_adapter_id = 0, \
+ .board_info = &camera##idx##_info, \
+}
+
+BOCKW_CAMERA(0);
+BOCKW_CAMERA(1);
+
+/* VIN */
+static struct rcar_vin_platform_data vin_platform_data __initdata = {
+ .flags = RCAR_VIN_BT656,
+};
+
+#define R8A7778_VIN(idx) \
+static struct resource vin##idx##_resources[] __initdata = { \
+ DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000), \
+ DEFINE_RES_IRQ(gic_iid(0x5a)), \
+}; \
+ \
+static struct platform_device_info vin##idx##_info __initdata = { \
+ .name = "r8a7778-vin", \
+ .id = idx, \
+ .res = vin##idx##_resources, \
+ .num_res = ARRAY_SIZE(vin##idx##_resources), \
+ .dma_mask = DMA_BIT_MASK(32), \
+ .data = &vin_platform_data, \
+ .size_data = sizeof(vin_platform_data), \
+}
+R8A7778_VIN(0);
+R8A7778_VIN(1);
+
+/* Sound */
+static struct resource rsnd_resources[] __initdata = {
+ [RSND_GEN1_SRU] = DEFINE_RES_MEM(0xffd90000, 0x1000),
+ [RSND_GEN1_SSI] = DEFINE_RES_MEM(0xffd91000, 0x1240),
+ [RSND_GEN1_ADG] = DEFINE_RES_MEM(0xfffe0000, 0x24),
+};
+
+static struct rsnd_ssi_platform_info rsnd_ssi[] = {
+ RSND_SSI_UNUSED, /* SSI 0 */
+ RSND_SSI_UNUSED, /* SSI 1 */
+ RSND_SSI_UNUSED, /* SSI 2 */
+ RSND_SSI(HPBDMA_SLAVE_HPBIF3_TX, gic_iid(0x85), 0),
+ RSND_SSI(HPBDMA_SLAVE_HPBIF4_RX, gic_iid(0x85), RSND_SSI_CLK_PIN_SHARE),
+ RSND_SSI(HPBDMA_SLAVE_HPBIF5_TX, gic_iid(0x86), 0),
+ RSND_SSI(HPBDMA_SLAVE_HPBIF6_RX, gic_iid(0x86), 0),
+ RSND_SSI(HPBDMA_SLAVE_HPBIF7_TX, gic_iid(0x86), 0),
+ RSND_SSI(HPBDMA_SLAVE_HPBIF8_RX, gic_iid(0x86), RSND_SSI_CLK_PIN_SHARE),
+};
+
+static struct rsnd_src_platform_info rsnd_src[9] = {
+ RSND_SRC_UNUSED, /* SRU 0 */
+ RSND_SRC_UNUSED, /* SRU 1 */
+ RSND_SRC_UNUSED, /* SRU 2 */
+ RSND_SRC(0, 0),
+ RSND_SRC(0, 0),
+ RSND_SRC(0, 0),
+ RSND_SRC(0, 0),
+ RSND_SRC(0, 0),
+ RSND_SRC(0, 0),
+};
+
+static struct rsnd_dai_platform_info rsnd_dai[] = {
+ {
+ .playback = { .ssi = &rsnd_ssi[5], .src = &rsnd_src[5] },
+ .capture = { .ssi = &rsnd_ssi[6], .src = &rsnd_src[6] },
+ }, {
+ .playback = { .ssi = &rsnd_ssi[3], .src = &rsnd_src[3] },
+ }, {
+ .capture = { .ssi = &rsnd_ssi[4], .src = &rsnd_src[4] },
+ }, {
+ .playback = { .ssi = &rsnd_ssi[7], .src = &rsnd_src[7] },
+ }, {
+ .capture = { .ssi = &rsnd_ssi[8], .src = &rsnd_src[8] },
+ },
+};
+
+enum {
+ AK4554_34 = 0,
+ AK4643_56,
+ AK4554_78,
+ SOUND_MAX,
+};
+
+static int rsnd_codec_power(int id, int enable)
+{
+ static int sound_user[SOUND_MAX] = {0, 0, 0};
+ int *usr = NULL;
+ u32 bit;
+
+ switch (id) {
+ case 3:
+ case 4:
+ usr = sound_user + AK4554_34;
+ bit = (1 << 10);
+ break;
+ case 5:
+ case 6:
+ usr = sound_user + AK4643_56;
+ bit = (1 << 6);
+ break;
+ case 7:
+ case 8:
+ usr = sound_user + AK4554_78;
+ bit = (1 << 7);
+ break;
+ }
+
+ if (!usr)
+ return -EIO;
+
+ if (enable) {
+ if (*usr == 0) {
+ u32 val = ioread16(fpga + COMCTLR);
+ val &= ~bit;
+ iowrite16(val, fpga + COMCTLR);
+ }
+
+ (*usr)++;
+ } else {
+ if (*usr == 0)
+ return 0;
+
+ (*usr)--;
+
+ if (*usr == 0) {
+ u32 val = ioread16(fpga + COMCTLR);
+ val |= bit;
+ iowrite16(val, fpga + COMCTLR);
+ }
+ }
+
+ return 0;
+}
+
+static int rsnd_start(int id)
+{
+ return rsnd_codec_power(id, 1);
+}
+
+static int rsnd_stop(int id)
+{
+ return rsnd_codec_power(id, 0);
+}
+
+static struct rcar_snd_info rsnd_info = {
+ .flags = RSND_GEN1,
+ .ssi_info = rsnd_ssi,
+ .ssi_info_nr = ARRAY_SIZE(rsnd_ssi),
+ .src_info = rsnd_src,
+ .src_info_nr = ARRAY_SIZE(rsnd_src),
+ .dai_info = rsnd_dai,
+ .dai_info_nr = ARRAY_SIZE(rsnd_dai),
+ .start = rsnd_start,
+ .stop = rsnd_stop,
+};
+
+static struct asoc_simple_card_info rsnd_card_info[] = {
+ /* SSI5, SSI6 */
+ {
+ .name = "AK4643",
+ .card = "SSI56-AK4643",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "rcar_sound",
+ .daifmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM,
+ .cpu_dai = {
+ .name = "rsnd-dai.0",
+ },
+ .codec_dai = {
+ .name = "ak4642-hifi",
+ .sysclk = 11289600,
+ },
+ },
+ /* SSI3 */
+ {
+ .name = "AK4554",
+ .card = "SSI3-AK4554(playback)",
+ .codec = "ak4554-adc-dac.0",
+ .platform = "rcar_sound",
+ .daifmt = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_RIGHT_J,
+ .cpu_dai = {
+ .name = "rsnd-dai.1",
+ },
+ .codec_dai = {
+ .name = "ak4554-hifi",
+ },
+ },
+ /* SSI4 */
+ {
+ .name = "AK4554",
+ .card = "SSI4-AK4554(capture)",
+ .codec = "ak4554-adc-dac.0",
+ .platform = "rcar_sound",
+ .daifmt = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_LEFT_J,
+ .cpu_dai = {
+ .name = "rsnd-dai.2",
+ },
+ .codec_dai = {
+ .name = "ak4554-hifi",
+ },
+ },
+ /* SSI7 */
+ {
+ .name = "AK4554",
+ .card = "SSI7-AK4554(playback)",
+ .codec = "ak4554-adc-dac.1",
+ .platform = "rcar_sound",
+ .daifmt = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_RIGHT_J,
+ .cpu_dai = {
+ .name = "rsnd-dai.3",
+ },
+ .codec_dai = {
+ .name = "ak4554-hifi",
+ },
+ },
+ /* SSI8 */
+ {
+ .name = "AK4554",
+ .card = "SSI8-AK4554(capture)",
+ .codec = "ak4554-adc-dac.1",
+ .platform = "rcar_sound",
+ .daifmt = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_LEFT_J,
+ .cpu_dai = {
+ .name = "rsnd-dai.4",
+ },
+ .codec_dai = {
+ .name = "ak4554-hifi",
+ },
+ }
+};
+
+static const struct pinctrl_map bockw_pinctrl_map[] = {
+ /* AUDIO */
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+ "audio_clk_a", "audio_clk"),
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+ "audio_clk_b", "audio_clk"),
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+ "ssi34_ctrl", "ssi"),
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+ "ssi3_data", "ssi"),
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+ "ssi4_data", "ssi"),
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+ "ssi5_ctrl", "ssi"),
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+ "ssi5_data", "ssi"),
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+ "ssi6_ctrl", "ssi"),
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+ "ssi6_data", "ssi"),
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+ "ssi78_ctrl", "ssi"),
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+ "ssi7_data", "ssi"),
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+ "ssi8_data", "ssi"),
+ /* Ether */
+ PIN_MAP_MUX_GROUP_DEFAULT("r8a777x-ether", "pfc-r8a7778",
+ "ether_rmii", "ether"),
+ /* HSPI0 */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh-hspi.0", "pfc-r8a7778",
+ "hspi0_a", "hspi0"),
+ /* MMC */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif", "pfc-r8a7778",
+ "mmc_data8", "mmc"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif", "pfc-r8a7778",
+ "mmc_ctrl", "mmc"),
+ /* SCIF0 */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a7778",
+ "scif0_data_a", "scif0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a7778",
+ "scif0_ctrl", "scif0"),
+ /* USB */
+ PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform", "pfc-r8a7778",
+ "usb0", "usb0"),
+ PIN_MAP_MUX_GROUP_DEFAULT(USB1_DEVICE, "pfc-r8a7778",
+ "usb1", "usb1"),
+ /* SDHI0 */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778",
+ "sdhi0_data4", "sdhi0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778",
+ "sdhi0_ctrl", "sdhi0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778",
+ "sdhi0_cd", "sdhi0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778",
+ "sdhi0_wp", "sdhi0"),
+ /* VIN0 */
+ PIN_MAP_MUX_GROUP_DEFAULT("r8a7778-vin.0", "pfc-r8a7778",
+ "vin0_clk", "vin0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("r8a7778-vin.0", "pfc-r8a7778",
+ "vin0_data8", "vin0"),
+ /* VIN1 */
+ PIN_MAP_MUX_GROUP_DEFAULT("r8a7778-vin.1", "pfc-r8a7778",
+ "vin1_clk", "vin1"),
+ PIN_MAP_MUX_GROUP_DEFAULT("r8a7778-vin.1", "pfc-r8a7778",
+ "vin1_data8", "vin1"),
+};
+
+#define PFC 0xfffc0000
+#define PUPR4 0x110
+static void __init bockw_init(void)
+{
+ void __iomem *base;
+ struct clk *clk;
+ struct platform_device *pdev;
+ int i;
+
+ r8a7778_clock_init();
+ r8a7778_init_irq_extpin(1);
+ r8a7778_add_standard_devices();
+
+ platform_device_register_full(&ether_info);
+
+ platform_device_register_full(&vin0_info);
+ /* VIN1 has a pin conflict with Ether */
+ if (!IS_ENABLED(CONFIG_SH_ETH))
+ platform_device_register_full(&vin1_info);
+ platform_device_register_data(NULL, "soc-camera-pdrv", 0,
+ &iclink0_ml86v7667,
+ sizeof(iclink0_ml86v7667));
+ platform_device_register_data(NULL, "soc-camera-pdrv", 1,
+ &iclink1_ml86v7667,
+ sizeof(iclink1_ml86v7667));
+
+ i2c_register_board_info(0, i2c0_devices,
+ ARRAY_SIZE(i2c0_devices));
+ spi_register_board_info(spi_board_info,
+ ARRAY_SIZE(spi_board_info));
+ pinctrl_register_mappings(bockw_pinctrl_map,
+ ARRAY_SIZE(bockw_pinctrl_map));
+ r8a7778_pinmux_init();
+
+ platform_device_register_resndata(
+ NULL, "sh_mmcif", -1,
+ mmc_resources, ARRAY_SIZE(mmc_resources),
+ &sh_mmcif_plat, sizeof(struct sh_mmcif_plat_data));
+
+ platform_device_register_resndata(
+ NULL, "rcar_usb_phy", -1,
+ usb_phy_resources,
+ ARRAY_SIZE(usb_phy_resources),
+ &usb_phy_platform_data,
+ sizeof(struct rcar_phy_platform_data));
+
+ regulator_register_fixed(0, dummy_supplies,
+ ARRAY_SIZE(dummy_supplies));
+ regulator_register_always_on(1, "fixed-3.3V", fixed3v3_power_consumers,
+ ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
+
+ /* for SMSC */
+ fpga = ioremap_nocache(FPGA, SZ_1M);
+ if (fpga) {
+ /*
+ * CAUTION
+ *
+ * IRQ0/1 is cascaded interrupt from FPGA.
+ * it should be cared in the future
+ * Now, it is assuming IRQ0 was used only from SMSC.
+ */
+ u16 val = ioread16(fpga + IRQ0MR);
+ val &= ~(1 << 4); /* enable SMSC911x */
+ iowrite16(val, fpga + IRQ0MR);
+
+ platform_device_register_resndata(
+ NULL, "smsc911x", -1,
+ smsc911x_resources, ARRAY_SIZE(smsc911x_resources),
+ &smsc911x_data, sizeof(smsc911x_data));
+ }
+
+ /* for SDHI */
+ base = ioremap_nocache(PFC, 0x200);
+ if (base) {
+ /*
+ * FIXME
+ *
+ * SDHI CD/WP pin needs pull-up
+ */
+ iowrite32(ioread32(base + PUPR4) | (3 << 26), base + PUPR4);
+ iounmap(base);
+
+ platform_device_register_resndata(
+ NULL, "sh_mobile_sdhi", 0,
+ sdhi0_resources, ARRAY_SIZE(sdhi0_resources),
+ &sdhi0_info, sizeof(struct tmio_mmc_data));
+ }
+
+ /* for Audio */
+ rsnd_codec_power(5, 1); /* enable ak4642 */
+
+ platform_device_register_simple(
+ "ak4554-adc-dac", 0, NULL, 0);
+
+ platform_device_register_simple(
+ "ak4554-adc-dac", 1, NULL, 0);
+
+ pdev = platform_device_register_resndata(
+ NULL, "rcar_sound", -1,
+ rsnd_resources, ARRAY_SIZE(rsnd_resources),
+ &rsnd_info, sizeof(rsnd_info));
+
+ clk = clk_get(&pdev->dev, "clk_b");
+ clk_set_rate(clk, 24576000);
+ clk_put(clk);
+
+ for (i = 0; i < ARRAY_SIZE(rsnd_card_info); i++) {
+ struct platform_device_info cardinfo = {
+ .name = "asoc-simple-card",
+ .id = i,
+ .data = &rsnd_card_info[i],
+ .size_data = sizeof(struct asoc_simple_card_info),
+ .dma_mask = DMA_BIT_MASK(32),
+ };
+
+ platform_device_register_full(&cardinfo);
+ }
+}
+
+static void __init bockw_init_late(void)
+{
+ r8a7778_init_late();
+ ADD_USB_FUNC_DEVICE_IF_POSSIBLE();
+}
+
+static const char *bockw_boards_compat_dt[] __initdata = {
+ "renesas,bockw",
+ NULL,
+};
+
+DT_MACHINE_START(BOCKW_DT, "bockw")
+ .init_early = shmobile_init_delay,
+ .init_irq = r8a7778_init_irq_dt,
+ .init_machine = bockw_init,
+ .dt_compat = bockw_boards_compat_dt,
+ .init_late = bockw_init_late,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
new file mode 100644
index 000000000..260d8319f
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-kzm9g.c
@@ -0,0 +1,916 @@
+/*
+ * KZM-A9-GT board support
+ *
+ * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@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.
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pcf857x.h>
+#include <linux/input.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mmcif.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
+#include <linux/mfd/as3711.h>
+#include <linux/mfd/tmio.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/smsc911x.h>
+#include <linux/usb/r8a66597.h>
+#include <linux/usb/renesas_usbhs.h>
+#include <linux/videodev2.h>
+
+#include <sound/sh_fsi.h>
+#include <sound/simple_card.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <video/sh_mobile_lcdc.h>
+
+#include "common.h"
+#include "intc.h"
+#include "irqs.h"
+#include "sh73a0.h"
+
+/*
+ * external GPIO
+ */
+#define GPIO_PCF8575_BASE (310)
+#define GPIO_PCF8575_PORT10 (GPIO_PCF8575_BASE + 8)
+#define GPIO_PCF8575_PORT11 (GPIO_PCF8575_BASE + 9)
+#define GPIO_PCF8575_PORT12 (GPIO_PCF8575_BASE + 10)
+#define GPIO_PCF8575_PORT13 (GPIO_PCF8575_BASE + 11)
+#define GPIO_PCF8575_PORT14 (GPIO_PCF8575_BASE + 12)
+#define GPIO_PCF8575_PORT15 (GPIO_PCF8575_BASE + 13)
+#define GPIO_PCF8575_PORT16 (GPIO_PCF8575_BASE + 14)
+
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x.0"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x.0"),
+};
+
+/*
+ * FSI-AK4648
+ *
+ * this command is required when playback.
+ *
+ * # amixer set "LINEOUT Mixer DACL" on
+ */
+
+/* SMSC 9221 */
+static struct resource smsc9221_resources[] = {
+ [0] = {
+ .start = 0x10000000, /* CS4 */
+ .end = 0x100000ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = irq_pin(3), /* IRQ3 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config smsc9221_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 smsc_device = {
+ .name = "smsc911x",
+ .dev = {
+ .platform_data = &smsc9221_platdata,
+ },
+ .resource = smsc9221_resources,
+ .num_resources = ARRAY_SIZE(smsc9221_resources),
+};
+
+/* USB external chip */
+static struct r8a66597_platdata usb_host_data = {
+ .on_chip = 0,
+ .xtal = R8A66597_PLATDATA_XTAL_48MHZ,
+};
+
+static struct resource usb_resources[] = {
+ [0] = {
+ .start = 0x10010000,
+ .end = 0x1001ffff - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = irq_pin(1), /* IRQ1 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usb_host_device = {
+ .name = "r8a66597_hcd",
+ .dev = {
+ .platform_data = &usb_host_data,
+ .dma_mask = NULL,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(usb_resources),
+ .resource = usb_resources,
+};
+
+/* USB Func CN17 */
+struct usbhs_private {
+ void __iomem *phy;
+ void __iomem *cr2;
+ struct renesas_usbhs_platform_info info;
+};
+
+#define IRQ15 irq_pin(15)
+#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)
+
+#define usbhs_get_priv(pdev) \
+ container_of(renesas_usbhs_get_info(pdev), struct usbhs_private, info)
+
+static int usbhs_get_vbus(struct platform_device *pdev)
+{
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+ return !((1 << 7) & __raw_readw(priv->cr2));
+}
+
+static int usbhs_phy_reset(struct platform_device *pdev)
+{
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+ /* init phy */
+ __raw_writew(0x8a0a, priv->cr2);
+
+ return 0;
+}
+
+static int usbhs_get_id(struct platform_device *pdev)
+{
+ return USBHS_GADGET;
+}
+
+static irqreturn_t usbhs_interrupt(int irq, void *data)
+{
+ struct platform_device *pdev = data;
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+ renesas_usbhs_call_notify_hotplug(pdev);
+
+ /* clear status */
+ __raw_writew(__raw_readw(priv->phy) | USB_PHY_INT_CLR, priv->phy);
+
+ return IRQ_HANDLED;
+}
+
+static int usbhs_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->phy);
+
+ ret = request_irq(IRQ15, usbhs_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->phy);
+
+ return 0;
+}
+
+static int usbhs_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->phy);
+
+ free_irq(IRQ15, pdev);
+
+ return 0;
+}
+
+static u32 usbhs_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 usbhs_private = {
+ .phy = IOMEM(0xe60781e0), /* USBPHYINT */
+ .cr2 = IOMEM(0xe605810c), /* USBCR2 */
+ .info = {
+ .platform_callback = {
+ .hardware_init = usbhs_hardware_init,
+ .hardware_exit = usbhs_hardware_exit,
+ .get_id = usbhs_get_id,
+ .phy_reset = usbhs_phy_reset,
+ .get_vbus = usbhs_get_vbus,
+ },
+ .driver_param = {
+ .buswait_bwait = 4,
+ .has_otg = 1,
+ .pipe_type = usbhs_pipe_cfg,
+ .pipe_size = ARRAY_SIZE(usbhs_pipe_cfg),
+ },
+ },
+};
+
+static struct resource usbhs_resources[] = {
+ [0] = {
+ .start = 0xE6890000,
+ .end = 0xE68900e6 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(62),
+ .end = gic_spi(62),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usbhs_device = {
+ .name = "renesas_usbhs",
+ .id = -1,
+ .dev = {
+ .dma_mask = NULL,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &usbhs_private.info,
+ },
+ .num_resources = ARRAY_SIZE(usbhs_resources),
+ .resource = usbhs_resources,
+};
+
+/* LCDC */
+static struct fb_videomode kzm_lcdc_mode = {
+ .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 struct sh_mobile_lcdc_info lcdc_info = {
+ .clock_source = LCDC_CLK_BUS,
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .interface_type = RGB24,
+ .lcd_modes = &kzm_lcdc_mode,
+ .num_modes = 1,
+ .clock_divider = 5,
+ .flags = 0,
+ .panel_cfg = {
+ .width = 152,
+ .height = 91,
+ },
+ }
+};
+
+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 = DMA_BIT_MASK(32),
+ },
+};
+
+/* Fixed 1.8V regulator to be used by MMCIF */
+static struct regulator_consumer_supply fixed1v8_power_consumers[] =
+{
+ REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"),
+};
+
+/* MMCIF */
+static struct resource sh_mmcif_resources[] = {
+ [0] = {
+ .name = "MMCIF",
+ .start = 0xe6bd0000,
+ .end = 0xe6bd00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(140),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = gic_spi(141),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_mmcif_plat_data sh_mmcif_platdata = {
+ .ocr = MMC_VDD_165_195,
+ .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
+ .ccs_unsupported = true,
+ .slave_id_tx = SHDMA_SLAVE_MMCIF_TX,
+ .slave_id_rx = SHDMA_SLAVE_MMCIF_RX,
+};
+
+static struct platform_device mmc_device = {
+ .name = "sh_mmcif",
+ .dev = {
+ .dma_mask = NULL,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &sh_mmcif_platdata,
+ },
+ .num_resources = ARRAY_SIZE(sh_mmcif_resources),
+ .resource = sh_mmcif_resources,
+};
+
+/* Fixed 3.3V regulators to be used by SDHI0 */
+static struct regulator_consumer_supply vcc_sdhi0_consumers[] =
+{
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+};
+
+static struct regulator_init_data vcc_sdhi0_init_data = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vcc_sdhi0_consumers),
+ .consumer_supplies = vcc_sdhi0_consumers,
+};
+
+static struct fixed_voltage_config vcc_sdhi0_info = {
+ .supply_name = "SDHI0 Vcc",
+ .microvolts = 3300000,
+ .gpio = 15,
+ .enable_high = 1,
+ .init_data = &vcc_sdhi0_init_data,
+};
+
+static struct platform_device vcc_sdhi0 = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &vcc_sdhi0_info,
+ },
+};
+
+/* Fixed 3.3V regulators to be used by SDHI2 */
+static struct regulator_consumer_supply vcc_sdhi2_consumers[] =
+{
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.2"),
+};
+
+static struct regulator_init_data vcc_sdhi2_init_data = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vcc_sdhi2_consumers),
+ .consumer_supplies = vcc_sdhi2_consumers,
+};
+
+static struct fixed_voltage_config vcc_sdhi2_info = {
+ .supply_name = "SDHI2 Vcc",
+ .microvolts = 3300000,
+ .gpio = 14,
+ .enable_high = 1,
+ .init_data = &vcc_sdhi2_init_data,
+};
+
+static struct platform_device vcc_sdhi2 = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &vcc_sdhi2_info,
+ },
+};
+
+/* SDHI */
+static struct tmio_mmc_data sdhi0_info = {
+ .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI0_TX,
+ .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI0_RX,
+ .flags = TMIO_MMC_HAS_IDLE_WAIT,
+ .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
+ MMC_CAP_POWER_OFF_CARD,
+};
+
+static struct resource sdhi0_resources[] = {
+ [0] = {
+ .name = "SDHI0",
+ .start = 0xee100000,
+ .end = 0xee1000ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = SH_MOBILE_SDHI_IRQ_CARD_DETECT,
+ .start = gic_spi(83),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .name = SH_MOBILE_SDHI_IRQ_SDCARD,
+ .start = gic_spi(84),
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .name = SH_MOBILE_SDHI_IRQ_SDIO,
+ .start = gic_spi(85),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi0_device = {
+ .name = "sh_mobile_sdhi",
+ .num_resources = ARRAY_SIZE(sdhi0_resources),
+ .resource = sdhi0_resources,
+ .dev = {
+ .platform_data = &sdhi0_info,
+ },
+};
+
+/* Micro SD */
+static struct tmio_mmc_data sdhi2_info = {
+ .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI2_TX,
+ .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI2_RX,
+ .flags = TMIO_MMC_HAS_IDLE_WAIT |
+ TMIO_MMC_USE_GPIO_CD |
+ TMIO_MMC_WRPROTECT_DISABLE,
+ .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_POWER_OFF_CARD,
+ .cd_gpio = 13,
+};
+
+static struct resource sdhi2_resources[] = {
+ [0] = {
+ .name = "SDHI2",
+ .start = 0xee140000,
+ .end = 0xee1400ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = SH_MOBILE_SDHI_IRQ_CARD_DETECT,
+ .start = gic_spi(103),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .name = SH_MOBILE_SDHI_IRQ_SDCARD,
+ .start = gic_spi(104),
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .name = SH_MOBILE_SDHI_IRQ_SDIO,
+ .start = gic_spi(105),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi2_device = {
+ .name = "sh_mobile_sdhi",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(sdhi2_resources),
+ .resource = sdhi2_resources,
+ .dev = {
+ .platform_data = &sdhi2_info,
+ },
+};
+
+/* KEY */
+#define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 }
+
+static struct gpio_keys_button gpio_buttons[] = {
+ GPIO_KEY(KEY_BACK, GPIO_PCF8575_PORT10, "SW3"),
+ GPIO_KEY(KEY_RIGHT, GPIO_PCF8575_PORT11, "SW2-R"),
+ GPIO_KEY(KEY_LEFT, GPIO_PCF8575_PORT12, "SW2-L"),
+ GPIO_KEY(KEY_ENTER, GPIO_PCF8575_PORT13, "SW2-P"),
+ GPIO_KEY(KEY_UP, GPIO_PCF8575_PORT14, "SW2-U"),
+ GPIO_KEY(KEY_DOWN, GPIO_PCF8575_PORT15, "SW2-D"),
+ GPIO_KEY(KEY_HOME, GPIO_PCF8575_PORT16, "SW1"),
+};
+
+static struct gpio_keys_platform_data gpio_key_info = {
+ .buttons = gpio_buttons,
+ .nbuttons = ARRAY_SIZE(gpio_buttons),
+};
+
+static struct platform_device gpio_keys_device = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &gpio_key_info,
+ },
+};
+
+/* FSI-AK4648 */
+static struct sh_fsi_platform_info fsi_info = {
+ .port_a = {
+ .tx_id = SHDMA_SLAVE_FSI2A_TX,
+ },
+};
+
+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,
+ .dev = {
+ .platform_data = &fsi_info,
+ },
+};
+
+static struct asoc_simple_card_info fsi2_ak4648_info = {
+ .name = "AK4648",
+ .card = "FSI2A-AK4648",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi2",
+ .daifmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM,
+ .cpu_dai = {
+ .name = "fsia-dai",
+ },
+ .codec_dai = {
+ .name = "ak4642-hifi",
+ .sysclk = 11289600,
+ },
+};
+
+static struct platform_device fsi_ak4648_device = {
+ .name = "asoc-simple-card",
+ .dev = {
+ .platform_data = &fsi2_ak4648_info,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .dma_mask = &fsi_ak4648_device.dev.coherent_dma_mask,
+ },
+};
+
+/* I2C */
+
+/* StepDown1 is used to supply 1.315V to the CPU */
+static struct regulator_init_data as3711_sd1 = {
+ .constraints = {
+ .name = "1.315V CPU",
+ .boot_on = 1,
+ .always_on = 1,
+ .min_uV = 1315000,
+ .max_uV = 1335000,
+ },
+};
+
+/* StepDown2 is used to supply 1.8V to the CPU and to the board */
+static struct regulator_init_data as3711_sd2 = {
+ .constraints = {
+ .name = "1.8V",
+ .boot_on = 1,
+ .always_on = 1,
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ },
+};
+
+/*
+ * StepDown3 is switched in parallel with StepDown2, seems to be off,
+ * according to read-back pre-set register values
+ */
+
+/* StepDown4 is used to supply 1.215V to the CPU and to the board */
+static struct regulator_init_data as3711_sd4 = {
+ .constraints = {
+ .name = "1.215V",
+ .boot_on = 1,
+ .always_on = 1,
+ .min_uV = 1215000,
+ .max_uV = 1235000,
+ },
+};
+
+/* LDO1 is unused and unconnected */
+
+/* LDO2 is used to supply 2.8V to the CPU */
+static struct regulator_init_data as3711_ldo2 = {
+ .constraints = {
+ .name = "2.8V CPU",
+ .boot_on = 1,
+ .always_on = 1,
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ },
+};
+
+/* LDO3 is used to supply 3.0V to the CPU */
+static struct regulator_init_data as3711_ldo3 = {
+ .constraints = {
+ .name = "3.0V CPU",
+ .boot_on = 1,
+ .always_on = 1,
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ },
+};
+
+/* LDO4 is used to supply 2.8V to the board */
+static struct regulator_init_data as3711_ldo4 = {
+ .constraints = {
+ .name = "2.8V",
+ .boot_on = 1,
+ .always_on = 1,
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ },
+};
+
+/* LDO5 is switched parallel to LDO4, also set to 2.8V */
+static struct regulator_init_data as3711_ldo5 = {
+ .constraints = {
+ .name = "2.8V #2",
+ .boot_on = 1,
+ .always_on = 1,
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ },
+};
+
+/* LDO6 is unused and unconnected */
+
+/* LDO7 is used to supply 1.15V to the CPU */
+static struct regulator_init_data as3711_ldo7 = {
+ .constraints = {
+ .name = "1.15V CPU",
+ .boot_on = 1,
+ .always_on = 1,
+ .min_uV = 1150000,
+ .max_uV = 1150000,
+ },
+};
+
+/* LDO8 is switched parallel to LDO7, also set to 1.15V */
+static struct regulator_init_data as3711_ldo8 = {
+ .constraints = {
+ .name = "1.15V CPU #2",
+ .boot_on = 1,
+ .always_on = 1,
+ .min_uV = 1150000,
+ .max_uV = 1150000,
+ },
+};
+
+static struct as3711_platform_data as3711_pdata = {
+ .regulator = {
+ .init_data = {
+ [AS3711_REGULATOR_SD_1] = &as3711_sd1,
+ [AS3711_REGULATOR_SD_2] = &as3711_sd2,
+ [AS3711_REGULATOR_SD_4] = &as3711_sd4,
+ [AS3711_REGULATOR_LDO_2] = &as3711_ldo2,
+ [AS3711_REGULATOR_LDO_3] = &as3711_ldo3,
+ [AS3711_REGULATOR_LDO_4] = &as3711_ldo4,
+ [AS3711_REGULATOR_LDO_5] = &as3711_ldo5,
+ [AS3711_REGULATOR_LDO_7] = &as3711_ldo7,
+ [AS3711_REGULATOR_LDO_8] = &as3711_ldo8,
+ },
+ },
+ .backlight = {
+ .su2_fb = "sh_mobile_lcdc_fb.0",
+ .su2_max_uA = 36000,
+ .su2_feedback = AS3711_SU2_CURR_AUTO,
+ .su2_fbprot = AS3711_SU2_GPIO4,
+ .su2_auto_curr1 = true,
+ .su2_auto_curr2 = true,
+ .su2_auto_curr3 = true,
+ },
+};
+
+static struct pcf857x_platform_data pcf8575_pdata = {
+ .gpio_base = GPIO_PCF8575_BASE,
+};
+
+static struct i2c_board_info i2c0_devices[] = {
+ {
+ I2C_BOARD_INFO("ak4648", 0x12),
+ },
+ {
+ I2C_BOARD_INFO("r2025sd", 0x32),
+ },
+ {
+ I2C_BOARD_INFO("ak8975", 0x0c),
+ .irq = irq_pin(28), /* IRQ28 */
+ },
+ {
+ I2C_BOARD_INFO("adxl34x", 0x1d),
+ .irq = irq_pin(26), /* IRQ26 */
+ },
+ {
+ I2C_BOARD_INFO("as3711", 0x40),
+ .irq = intcs_evt2irq(0x3300), /* IRQ24 */
+ .platform_data = &as3711_pdata,
+ },
+};
+
+static struct i2c_board_info i2c1_devices[] = {
+ {
+ I2C_BOARD_INFO("st1232-ts", 0x55),
+ .irq = irq_pin(8), /* IRQ8 */
+ },
+};
+
+static struct i2c_board_info i2c3_devices[] = {
+ {
+ I2C_BOARD_INFO("pcf8575", 0x20),
+ .irq = irq_pin(19), /* IRQ19 */
+ .platform_data = &pcf8575_pdata,
+ },
+};
+
+static struct platform_device *kzm_devices[] __initdata = {
+ &smsc_device,
+ &usb_host_device,
+ &usbhs_device,
+ &lcdc_device,
+ &mmc_device,
+ &vcc_sdhi0,
+ &vcc_sdhi2,
+ &sdhi0_device,
+ &sdhi2_device,
+ &gpio_keys_device,
+ &fsi_device,
+ &fsi_ak4648_device,
+};
+
+static unsigned long pin_pullup_conf[] = {
+ PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 0),
+};
+
+static const struct pinctrl_map kzm_pinctrl_map[] = {
+ /* FSIA (AK4648) */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2", "pfc-sh73a0",
+ "fsia_mclk_in", "fsia"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2", "pfc-sh73a0",
+ "fsia_sclk_in", "fsia"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2", "pfc-sh73a0",
+ "fsia_data_in", "fsia"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2", "pfc-sh73a0",
+ "fsia_data_out", "fsia"),
+ /* I2C3 */
+ PIN_MAP_MUX_GROUP_DEFAULT("i2c-sh_mobile.3", "pfc-sh73a0",
+ "i2c3_1", "i2c3"),
+ /* LCD */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-sh73a0",
+ "lcd_data24", "lcd"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-sh73a0",
+ "lcd_sync", "lcd"),
+ /* MMCIF */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-sh73a0",
+ "mmc0_data8_0", "mmc0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-sh73a0",
+ "mmc0_ctrl_0", "mmc0"),
+ PIN_MAP_CONFIGS_PIN_DEFAULT("sh_mmcif.0", "pfc-sh73a0",
+ "PORT279", pin_pullup_conf),
+ PIN_MAP_CONFIGS_GROUP_DEFAULT("sh_mmcif.0", "pfc-sh73a0",
+ "mmc0_data8_0", pin_pullup_conf),
+ /* SCIFA4 */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.4", "pfc-sh73a0",
+ "scifa4_data", "scifa4"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.4", "pfc-sh73a0",
+ "scifa4_ctrl", "scifa4"),
+ /* SDHI0 */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0",
+ "sdhi0_data4", "sdhi0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0",
+ "sdhi0_ctrl", "sdhi0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0",
+ "sdhi0_cd", "sdhi0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0",
+ "sdhi0_wp", "sdhi0"),
+ /* SDHI2 */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-sh73a0",
+ "sdhi2_data4", "sdhi2"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-sh73a0",
+ "sdhi2_ctrl", "sdhi2"),
+ /* SMSC */
+ PIN_MAP_MUX_GROUP_DEFAULT("smsc911x.0", "pfc-sh73a0",
+ "bsc_cs4", "bsc"),
+ /* USB */
+ PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs", "pfc-sh73a0",
+ "usb_vbus", "usb"),
+};
+
+static void __init kzm_init(void)
+{
+ regulator_register_always_on(2, "fixed-1.8V", fixed1v8_power_consumers,
+ ARRAY_SIZE(fixed1v8_power_consumers), 1800000);
+ regulator_register_fixed(3, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
+ pinctrl_register_mappings(kzm_pinctrl_map, ARRAY_SIZE(kzm_pinctrl_map));
+
+ sh73a0_pinmux_init();
+
+ /* SMSC */
+ gpio_request_one(224, GPIOF_IN, NULL); /* IRQ3 */
+
+ /* LCDC */
+ gpio_request_one(222, GPIOF_OUT_INIT_HIGH, NULL); /* LCDCDON */
+ gpio_request_one(226, GPIOF_OUT_INIT_HIGH, NULL); /* SC */
+
+ /* Touchscreen */
+ gpio_request_one(223, GPIOF_IN, NULL); /* IRQ8 */
+
+#ifdef CONFIG_CACHE_L2X0
+ /* Shared attribute override enable, 64K*8way */
+ l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff);
+#endif
+
+ i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
+ i2c_register_board_info(1, i2c1_devices, ARRAY_SIZE(i2c1_devices));
+ i2c_register_board_info(3, i2c3_devices, ARRAY_SIZE(i2c3_devices));
+
+ sh73a0_add_standard_devices();
+ platform_add_devices(kzm_devices, ARRAY_SIZE(kzm_devices));
+
+ sh73a0_pm_init();
+}
+
+static void kzm9g_restart(enum reboot_mode mode, const char *cmd)
+{
+#define RESCNT2 IOMEM(0xe6188020)
+ /* Do soft power on reset */
+ writel((1 << 31), RESCNT2);
+}
+
+static const char *kzm9g_boards_compat_dt[] __initdata = {
+ "renesas,kzm9g",
+ NULL,
+};
+
+DT_MACHINE_START(KZM9G_DT, "kzm9g")
+ .smp = smp_ops(sh73a0_smp_ops),
+ .map_io = sh73a0_map_io,
+ .init_early = sh73a0_add_early_devices,
+ .init_irq = sh73a0_init_irq,
+ .init_machine = kzm_init,
+ .init_late = shmobile_init_late,
+ .init_time = sh73a0_earlytimer_init,
+ .restart = kzm9g_restart,
+ .dt_compat = kzm9g_boards_compat_dt,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-marzen-reference.c b/arch/arm/mach-shmobile/board-marzen-reference.c
new file mode 100644
index 000000000..b15eb9232
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-marzen-reference.c
@@ -0,0 +1,56 @@
+/*
+ * marzen board support - Reference DT implementation
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Magnus Damm
+ * Copyright (C) 2013 Simon Horman
+ *
+ * This program is free software; 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/clk/shmobile.h>
+#include <linux/clocksource.h>
+#include <linux/of_platform.h>
+
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+
+#include "common.h"
+#include "irqs.h"
+#include "r8a7779.h"
+
+static void __init marzen_init_timer(void)
+{
+ r8a7779_clocks_init(r8a7779_read_mode_pins());
+ clocksource_of_init();
+}
+
+static void __init marzen_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ r8a7779_init_irq_extpin_dt(1); /* IRQ1 as individual interrupt */
+}
+
+static const char *marzen_boards_compat_dt[] __initdata = {
+ "renesas,marzen",
+ "renesas,marzen-reference",
+ NULL,
+};
+
+DT_MACHINE_START(MARZEN, "marzen")
+ .smp = smp_ops(r8a7779_smp_ops),
+ .map_io = r8a7779_map_io,
+ .init_early = shmobile_init_delay,
+ .init_time = marzen_init_timer,
+ .init_irq = r8a7779_init_irq_dt,
+ .init_machine = marzen_init,
+ .init_late = shmobile_init_late,
+ .dt_compat = marzen_boards_compat_dt,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c
new file mode 100644
index 000000000..51db288f1
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-marzen.c
@@ -0,0 +1,347 @@
+/*
+ * marzen board support
+ *
+ * Copyright (C) 2011, 2013 Renesas Solutions Corp.
+ * Copyright (C) 2011 Magnus Damm
+ * Copyright (C) 2013 Cogent Embedded, 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; 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/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/leds.h>
+#include <linux/dma-mapping.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/platform_data/camera-rcar.h>
+#include <linux/platform_data/gpio-rcar.h>
+#include <linux/platform_data/usb-rcar-phy.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/smsc911x.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/sh_hspi.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
+#include <linux/mfd/tmio.h>
+
+#include <media/soc_camera.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/traps.h>
+
+#include "common.h"
+#include "irqs.h"
+#include "r8a7779.h"
+
+/* Fixed 3.3V regulator to be used by SDHI0 */
+static struct regulator_consumer_supply fixed3v3_power_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
+};
+
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+};
+
+/* USB PHY */
+static struct resource usb_phy_resources[] = {
+ [0] = {
+ .start = 0xffe70800,
+ .end = 0xffe70900 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct rcar_phy_platform_data usb_phy_platform_data;
+
+static struct platform_device usb_phy = {
+ .name = "rcar_usb_phy",
+ .id = -1,
+ .dev = {
+ .platform_data = &usb_phy_platform_data,
+ },
+ .resource = usb_phy_resources,
+ .num_resources = ARRAY_SIZE(usb_phy_resources),
+};
+
+/* SMSC LAN89218 */
+static struct resource smsc911x_resources[] = {
+ [0] = {
+ .start = 0x18000000, /* ExCS0 */
+ .end = 0x180000ff, /* A1->A7 */
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = irq_pin(1), /* IRQ 1 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_platdata = {
+ .flags = SMSC911X_USE_32BIT, /* 32-bit SW on 16-bit HW bus */
+ .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 = -1,
+ .dev = {
+ .platform_data = &smsc911x_platdata,
+ },
+ .resource = smsc911x_resources,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+};
+
+static struct resource sdhi0_resources[] = {
+ [0] = {
+ .name = "sdhi0",
+ .start = 0xffe4c000,
+ .end = 0xffe4c0ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_iid(0x88),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct tmio_mmc_data sdhi0_platform_data = {
+ .chan_priv_tx = (void *)HPBDMA_SLAVE_SDHI0_TX,
+ .chan_priv_rx = (void *)HPBDMA_SLAVE_SDHI0_RX,
+ .flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT,
+ .capabilities = MMC_CAP_SD_HIGHSPEED,
+};
+
+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_platform_data,
+ }
+};
+
+/* Thermal */
+static struct resource thermal_resources[] = {
+ [0] = {
+ .start = 0xFFC48000,
+ .end = 0xFFC48038 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device thermal_device = {
+ .name = "rcar_thermal",
+ .resource = thermal_resources,
+ .num_resources = ARRAY_SIZE(thermal_resources),
+};
+
+/* HSPI */
+static struct resource hspi_resources[] = {
+ [0] = {
+ .start = 0xFFFC7000,
+ .end = 0xFFFC7018 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device hspi_device = {
+ .name = "sh-hspi",
+ .id = 0,
+ .resource = hspi_resources,
+ .num_resources = ARRAY_SIZE(hspi_resources),
+};
+
+/* LEDS */
+static struct gpio_led marzen_leds[] = {
+ {
+ .name = "led2",
+ .gpio = RCAR_GP_PIN(4, 29),
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ }, {
+ .name = "led3",
+ .gpio = RCAR_GP_PIN(4, 30),
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ }, {
+ .name = "led4",
+ .gpio = RCAR_GP_PIN(4, 31),
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+};
+
+static struct gpio_led_platform_data marzen_leds_pdata = {
+ .leds = marzen_leds,
+ .num_leds = ARRAY_SIZE(marzen_leds),
+};
+
+static struct platform_device leds_device = {
+ .name = "leds-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &marzen_leds_pdata,
+ },
+};
+
+/* VIN */
+static struct rcar_vin_platform_data vin_platform_data __initdata = {
+ .flags = RCAR_VIN_BT656,
+};
+
+#define MARZEN_VIN(idx) \
+static struct resource vin##idx##_resources[] __initdata = { \
+ DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000), \
+ DEFINE_RES_IRQ(gic_iid(0x5f + (idx))), \
+}; \
+ \
+static struct platform_device_info vin##idx##_info __initdata = { \
+ .name = "r8a7779-vin", \
+ .id = idx, \
+ .res = vin##idx##_resources, \
+ .num_res = ARRAY_SIZE(vin##idx##_resources), \
+ .dma_mask = DMA_BIT_MASK(32), \
+ .data = &vin_platform_data, \
+ .size_data = sizeof(vin_platform_data), \
+}
+MARZEN_VIN(1);
+MARZEN_VIN(3);
+
+#define MARZEN_CAMERA(idx) \
+static struct i2c_board_info camera##idx##_info = { \
+ I2C_BOARD_INFO("adv7180", 0x20 + (idx)), \
+}; \
+ \
+static struct soc_camera_link iclink##idx##_adv7180 = { \
+ .bus_id = 1 + 2 * (idx), \
+ .i2c_adapter_id = 0, \
+ .board_info = &camera##idx##_info, \
+}; \
+ \
+static struct platform_device camera##idx##_device = { \
+ .name = "soc-camera-pdrv", \
+ .id = idx, \
+ .dev = { \
+ .platform_data = &iclink##idx##_adv7180, \
+ }, \
+};
+
+MARZEN_CAMERA(0);
+MARZEN_CAMERA(1);
+
+static struct platform_device *marzen_devices[] __initdata = {
+ &eth_device,
+ &sdhi0_device,
+ &thermal_device,
+ &hspi_device,
+ &leds_device,
+ &usb_phy,
+ &camera0_device,
+ &camera1_device,
+};
+
+static const struct pinctrl_map marzen_pinctrl_map[] = {
+ /* DU (CN10: ARGB0, CN13: LVDS) */
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
+ "du0_rgb888", "du0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
+ "du0_sync_1", "du0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
+ "du0_clk_out_0", "du0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
+ "du1_rgb666", "du1"),
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
+ "du1_sync_1", "du1"),
+ PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
+ "du1_clk_out", "du1"),
+ /* HSPI0 */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh-hspi.0", "pfc-r8a7779",
+ "hspi0", "hspi0"),
+ /* SCIF2 (CN18: DEBUG0) */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.2", "pfc-r8a7779",
+ "scif2_data_c", "scif2"),
+ /* SCIF4 (CN19: DEBUG1) */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.4", "pfc-r8a7779",
+ "scif4_data", "scif4"),
+ /* SDHI0 */
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7779",
+ "sdhi0_data4", "sdhi0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7779",
+ "sdhi0_ctrl", "sdhi0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7779",
+ "sdhi0_cd", "sdhi0"),
+ /* SMSC */
+ PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-r8a7779",
+ "intc_irq1_b", "intc"),
+ PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-r8a7779",
+ "lbsc_ex_cs0", "lbsc"),
+ /* USB0 */
+ PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform.0", "pfc-r8a7779",
+ "usb0", "usb0"),
+ /* USB1 */
+ PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform.0", "pfc-r8a7779",
+ "usb1", "usb1"),
+ /* USB2 */
+ PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform.1", "pfc-r8a7779",
+ "usb2", "usb2"),
+ /* VIN1 */
+ PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.1", "pfc-r8a7779",
+ "vin1_clk", "vin1"),
+ PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.1", "pfc-r8a7779",
+ "vin1_data8", "vin1"),
+ /* VIN3 */
+ PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.3", "pfc-r8a7779",
+ "vin3_clk", "vin3"),
+ PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.3", "pfc-r8a7779",
+ "vin3_data8", "vin3"),
+};
+
+static void __init marzen_init(void)
+{
+ regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
+ ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
+ regulator_register_fixed(1, dummy_supplies,
+ ARRAY_SIZE(dummy_supplies));
+
+ pinctrl_register_mappings(marzen_pinctrl_map,
+ ARRAY_SIZE(marzen_pinctrl_map));
+ r8a7779_pinmux_init();
+ r8a7779_init_irq_extpin(1); /* IRQ1 as individual interrupt */
+
+ r8a7779_add_standard_devices();
+ platform_device_register_full(&vin1_info);
+ platform_device_register_full(&vin3_info);
+ platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
+}
+
+static const char *marzen_boards_compat_dt[] __initdata = {
+ "renesas,marzen",
+ NULL,
+};
+
+DT_MACHINE_START(MARZEN, "marzen")
+ .smp = smp_ops(r8a7779_smp_ops),
+ .map_io = r8a7779_map_io,
+ .init_early = r8a7779_add_early_devices,
+ .init_irq = r8a7779_init_irq_dt,
+ .init_machine = marzen_init,
+ .init_late = r8a7779_init_late,
+ .dt_compat = marzen_boards_compat_dt,
+ .init_time = r8a7779_earlytimer_init,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
new file mode 100644
index 000000000..9cac8247c
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -0,0 +1,675 @@
+/*
+ * R8A7740 processor support
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@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; 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.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
+
+#include "clock.h"
+#include "common.h"
+#include "r8a7740.h"
+
+/*
+ * | MDx | XTAL1/EXTAL1 | System | EXTALR |
+ * Clock |-------+-----------------+ clock | 32.768 | RCLK
+ * Mode | 2/1/0 | src MHz | source | KHz | source
+ * -------+-------+-----------------+-----------+--------+----------
+ * 0 | 0 0 0 | External 20~50 | XTAL1 | O | EXTALR
+ * 1 | 0 0 1 | Crystal 20~30 | XTAL1 | O | EXTALR
+ * 2 | 0 1 0 | External 40~50 | XTAL1 / 2 | O | EXTALR
+ * 3 | 0 1 1 | Crystal 40~50 | XTAL1 / 2 | O | EXTALR
+ * 4 | 1 0 0 | External 20~50 | XTAL1 | x | XTAL1 / 1024
+ * 5 | 1 0 1 | Crystal 20~30 | XTAL1 | x | XTAL1 / 1024
+ * 6 | 1 1 0 | External 40~50 | XTAL1 / 2 | x | XTAL1 / 2048
+ * 7 | 1 1 1 | Crystal 40~50 | XTAL1 / 2 | x | XTAL1 / 2048
+ */
+
+/* CPG registers */
+#define FRQCRA IOMEM(0xe6150000)
+#define FRQCRB IOMEM(0xe6150004)
+#define VCLKCR1 IOMEM(0xE6150008)
+#define VCLKCR2 IOMEM(0xE615000c)
+#define FRQCRC IOMEM(0xe61500e0)
+#define FSIACKCR IOMEM(0xe6150018)
+#define PLLC01CR IOMEM(0xe6150028)
+
+#define SUBCKCR IOMEM(0xe6150080)
+#define USBCKCR IOMEM(0xe615008c)
+
+#define MSTPSR0 IOMEM(0xe6150030)
+#define MSTPSR1 IOMEM(0xe6150038)
+#define MSTPSR2 IOMEM(0xe6150040)
+#define MSTPSR3 IOMEM(0xe6150048)
+#define MSTPSR4 IOMEM(0xe615004c)
+#define FSIBCKCR IOMEM(0xe6150090)
+#define HDMICKCR IOMEM(0xe6150094)
+#define SMSTPCR0 IOMEM(0xe6150130)
+#define SMSTPCR1 IOMEM(0xe6150134)
+#define SMSTPCR2 IOMEM(0xe6150138)
+#define SMSTPCR3 IOMEM(0xe615013c)
+#define SMSTPCR4 IOMEM(0xe6150140)
+
+#define FSIDIVA IOMEM(0xFE1F8000)
+#define FSIDIVB IOMEM(0xFE1F8008)
+
+/* Fixed 32 KHz root clock from EXTALR pin */
+static struct clk extalr_clk = {
+ .rate = 32768,
+};
+
+/*
+ * 25MHz default rate for the EXTAL1 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+static struct clk extal1_clk = {
+ .rate = 25000000,
+};
+
+/*
+ * 48MHz default rate for the EXTAL2 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+static struct clk extal2_clk = {
+ .rate = 48000000,
+};
+
+/*
+ * 27MHz default rate for the DV_CLKI root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+static struct clk dv_clk = {
+ .rate = 27000000,
+};
+
+SH_CLK_RATIO(div2, 1, 2);
+SH_CLK_RATIO(div1k, 1, 1024);
+
+SH_FIXED_RATIO_CLK(extal1_div2_clk, extal1_clk, div2);
+SH_FIXED_RATIO_CLK(extal1_div1024_clk, extal1_clk, div1k);
+SH_FIXED_RATIO_CLK(extal1_div2048_clk, extal1_div2_clk, div1k);
+SH_FIXED_RATIO_CLK(extal2_div2_clk, extal2_clk, div2);
+
+static struct sh_clk_ops followparent_clk_ops = {
+ .recalc = followparent_recalc,
+};
+
+/* Main clock */
+static struct clk system_clk = {
+ .ops = &followparent_clk_ops,
+};
+
+SH_FIXED_RATIO_CLK(system_div2_clk, system_clk, div2);
+
+/* r_clk */
+static struct clk r_clk = {
+ .ops = &followparent_clk_ops,
+};
+
+/* PLLC0/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) & 0x7f) + 1;
+
+ return clk->parent->rate * mult;
+}
+
+static struct sh_clk_ops pllc01_clk_ops = {
+ .recalc = pllc01_recalc,
+};
+
+static struct clk pllc0_clk = {
+ .ops = &pllc01_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &system_clk,
+ .enable_reg = (void __iomem *)FRQCRC,
+};
+
+static struct clk pllc1_clk = {
+ .ops = &pllc01_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &system_div2_clk,
+ .enable_reg = (void __iomem *)FRQCRA,
+};
+
+/* PLLC1 / 2 */
+SH_FIXED_RATIO_CLK(pllc1_div2_clk, pllc1_clk, div2);
+
+/* USB clock */
+/*
+ * USBCKCR is controlling usb24 clock
+ * bit[7] : parent clock
+ * bit[6] : clock divide rate
+ * And this bit[7] is used as a "usb24s" from other devices.
+ * (Video clock / Sub clock / SPU clock)
+ * You can controll this clock as a below.
+ *
+ * struct clk *usb24 = clk_get(dev, "usb24");
+ * struct clk *usb24s = clk_get(NULL, "usb24s");
+ * struct clk *system = clk_get(NULL, "system_clk");
+ * int rate = clk_get_rate(system);
+ *
+ * clk_set_parent(usb24s, system); // for bit[7]
+ * clk_set_rate(usb24, rate / 2); // for bit[6]
+ */
+static struct clk *usb24s_parents[] = {
+ [0] = &system_clk,
+ [1] = &extal2_clk
+};
+
+static int usb24s_enable(struct clk *clk)
+{
+ __raw_writel(__raw_readl(USBCKCR) & ~(1 << 8), USBCKCR);
+
+ return 0;
+}
+
+static void usb24s_disable(struct clk *clk)
+{
+ __raw_writel(__raw_readl(USBCKCR) | (1 << 8), USBCKCR);
+}
+
+static int usb24s_set_parent(struct clk *clk, struct clk *parent)
+{
+ int i, ret;
+ u32 val;
+
+ 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;
+
+ val = __raw_readl(USBCKCR);
+ val &= ~(1 << 7);
+ val |= i << 7;
+ __raw_writel(val, USBCKCR);
+
+ return 0;
+}
+
+static struct sh_clk_ops usb24s_clk_ops = {
+ .recalc = followparent_recalc,
+ .enable = usb24s_enable,
+ .disable = usb24s_disable,
+ .set_parent = usb24s_set_parent,
+};
+
+static struct clk usb24s_clk = {
+ .ops = &usb24s_clk_ops,
+ .parent_table = usb24s_parents,
+ .parent_num = ARRAY_SIZE(usb24s_parents),
+ .parent = &system_clk,
+};
+
+static unsigned long usb24_recalc(struct clk *clk)
+{
+ return clk->parent->rate /
+ ((__raw_readl(USBCKCR) & (1 << 6)) ? 1 : 2);
+};
+
+static int usb24_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 val;
+
+ /* closer to which ? parent->rate or parent->rate/2 */
+ val = __raw_readl(USBCKCR);
+ val &= ~(1 << 6);
+ val |= (rate > (clk->parent->rate / 4) * 3) << 6;
+ __raw_writel(val, USBCKCR);
+
+ return 0;
+}
+
+static struct sh_clk_ops usb24_clk_ops = {
+ .recalc = usb24_recalc,
+ .set_rate = usb24_set_rate,
+};
+
+static struct clk usb24_clk = {
+ .ops = &usb24_clk_ops,
+ .parent = &usb24s_clk,
+};
+
+/* External FSIACK/FSIBCK clock */
+static struct clk fsiack_clk = {
+};
+
+static struct clk fsibck_clk = {
+};
+
+static struct clk *main_clks[] = {
+ &extalr_clk,
+ &extal1_clk,
+ &extal2_clk,
+ &extal1_div2_clk,
+ &extal1_div1024_clk,
+ &extal1_div2048_clk,
+ &extal2_div2_clk,
+ &dv_clk,
+ &system_clk,
+ &system_div2_clk,
+ &r_clk,
+ &pllc0_clk,
+ &pllc1_clk,
+ &pllc1_div2_clk,
+ &usb24s_clk,
+ &usb24_clk,
+ &fsiack_clk,
+ &fsibck_clk,
+};
+
+/* DIV4 clocks */
+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_HP,
+ DIV4_HPP, DIV4_USBP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP,
+ DIV4_NR
+};
+
+static struct clk div4_clks[DIV4_NR] = {
+ [DIV4_I] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_ZG] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_B] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_M1] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_HP] = SH_CLK_DIV4(&pllc1_clk, FRQCRB, 4, 0x6fff, 0),
+ [DIV4_HPP] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 20, 0x6fff, 0),
+ [DIV4_USBP] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 16, 0x6fff, 0),
+ [DIV4_S] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 12, 0x6fff, 0),
+ [DIV4_ZB] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 8, 0x6fff, 0),
+ [DIV4_M3] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 4, 0x6fff, 0),
+ [DIV4_CP] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 0, 0x6fff, 0),
+};
+
+/* DIV6 reparent */
+enum {
+ DIV6_HDMI,
+ DIV6_VCLK1, DIV6_VCLK2,
+ DIV6_FSIA, DIV6_FSIB,
+ DIV6_REPARENT_NR,
+};
+
+static struct clk *hdmi_parent[] = {
+ [0] = &pllc1_div2_clk,
+ [1] = &system_clk,
+ [2] = &dv_clk
+};
+
+static struct clk *vclk_parents[8] = {
+ [0] = &pllc1_div2_clk,
+ [2] = &dv_clk,
+ [3] = &usb24s_clk,
+ [4] = &extal1_div2_clk,
+ [5] = &extalr_clk,
+};
+
+static struct clk *fsia_parents[] = {
+ [0] = &pllc1_div2_clk,
+ [1] = &fsiack_clk, /* external clock */
+};
+
+static struct clk *fsib_parents[] = {
+ [0] = &pllc1_div2_clk,
+ [1] = &fsibck_clk, /* external clock */
+};
+
+static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
+ [DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0,
+ hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
+ [DIV6_VCLK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
+ vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3),
+ [DIV6_VCLK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
+ vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3),
+ [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
+ fsia_parents, ARRAY_SIZE(fsia_parents), 6, 2),
+ [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
+ fsib_parents, ARRAY_SIZE(fsib_parents), 6, 2),
+};
+
+/* DIV6 clocks */
+enum {
+ DIV6_SUB,
+ DIV6_NR
+};
+
+static struct clk div6_clks[DIV6_NR] = {
+ [DIV6_SUB] = SH_CLK_DIV6(&pllc1_div2_clk, SUBCKCR, 0),
+};
+
+/* HDMI1/2 clock */
+static unsigned long hdmi12_recalc(struct clk *clk)
+{
+ u32 val = __raw_readl(HDMICKCR);
+ int shift = (int)clk->priv;
+
+ val >>= shift;
+ val &= 0x3;
+
+ return clk->parent->rate / (1 << val);
+};
+
+static int hdmi12_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 val, mask;
+ int i, shift;
+
+ for (i = 0; i < 3; i++)
+ if (rate == clk->parent->rate / (1 << i))
+ goto find;
+ return -ENODEV;
+
+find:
+ shift = (int)clk->priv;
+
+ val = __raw_readl(HDMICKCR);
+ mask = ~(0x3 << shift);
+ val = (val & mask) | i << shift;
+ __raw_writel(val, HDMICKCR);
+
+ return 0;
+};
+
+static struct sh_clk_ops hdmi12_clk_ops = {
+ .recalc = hdmi12_recalc,
+ .set_rate = hdmi12_set_rate,
+};
+
+static struct clk hdmi1_clk = {
+ .ops = &hdmi12_clk_ops,
+ .priv = (void *)9,
+ .parent = &div6_reparent_clks[DIV6_HDMI], /* late install */
+};
+
+static struct clk hdmi2_clk = {
+ .ops = &hdmi12_clk_ops,
+ .priv = (void *)11,
+ .parent = &div6_reparent_clks[DIV6_HDMI], /* late install */
+};
+
+static struct clk *late_main_clks[] = {
+ &hdmi1_clk,
+ &hdmi2_clk,
+};
+
+/* FSI DIV */
+enum { FSIDIV_A, FSIDIV_B, FSIDIV_REPARENT_NR };
+
+static struct clk fsidivs[] = {
+ [FSIDIV_A] = SH_CLK_FSIDIV(FSIDIVA, &div6_reparent_clks[DIV6_FSIA]),
+ [FSIDIV_B] = SH_CLK_FSIDIV(FSIDIVB, &div6_reparent_clks[DIV6_FSIB]),
+};
+
+/* MSTP */
+enum {
+ MSTP128, MSTP127, MSTP125,
+ MSTP116, MSTP111, MSTP100, MSTP117,
+
+ MSTP230, MSTP229,
+ MSTP222,
+ MSTP218, MSTP217, MSTP216, MSTP214,
+ MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+
+ MSTP329, MSTP328, MSTP323, MSTP320,
+ MSTP314, MSTP313, MSTP312,
+ MSTP309, MSTP304,
+
+ MSTP416, MSTP415, MSTP407, MSTP406,
+
+ MSTP_NR
+};
+
+static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP128] = SH_CLK_MSTP32(&div4_clks[DIV4_S], SMSTPCR1, 28, 0), /* CEU21 */
+ [MSTP127] = SH_CLK_MSTP32(&div4_clks[DIV4_S], SMSTPCR1, 27, 0), /* CEU20 */
+ [MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
+ [MSTP117] = SH_CLK_MSTP32(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
+ [MSTP116] = SH_CLK_MSTP32(&div4_clks[DIV4_HPP], SMSTPCR1, 16, 0), /* IIC0 */
+ [MSTP111] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 11, 0), /* TMU1 */
+ [MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
+
+ [MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */
+ [MSTP229] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 29, 0), /* INTCA */
+ [MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */
+ [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */
+ [MSTP217] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */
+ [MSTP216] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */
+ [MSTP214] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 14, 0), /* USBDMAC */
+ [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
+ [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
+ [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
+ [MSTP203] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
+ [MSTP202] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
+ [MSTP201] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
+ [MSTP200] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
+
+ [MSTP329] = SH_CLK_MSTP32(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
+ [MSTP328] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /* FSI */
+ [MSTP323] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
+ [MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 20, 0), /* USBF */
+ [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
+ [MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
+ [MSTP312] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
+ [MSTP309] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 9, 0), /* GEther */
+ [MSTP304] = SH_CLK_MSTP32(&div4_clks[DIV4_CP], SMSTPCR3, 4, 0), /* TPU0 */
+
+ [MSTP416] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 16, 0), /* USBHOST */
+ [MSTP415] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
+ [MSTP407] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 7, 0), /* USB-Func */
+ [MSTP406] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 6, 0), /* USB Phy */
+};
+
+static struct clk_lookup lookups[] = {
+ /* main clocks */
+ CLKDEV_CON_ID("extalr", &extalr_clk),
+ CLKDEV_CON_ID("extal1", &extal1_clk),
+ CLKDEV_CON_ID("extal2", &extal2_clk),
+ CLKDEV_CON_ID("extal1_div2", &extal1_div2_clk),
+ CLKDEV_CON_ID("extal1_div1024", &extal1_div1024_clk),
+ CLKDEV_CON_ID("extal1_div2048", &extal1_div2048_clk),
+ CLKDEV_CON_ID("extal2_div2", &extal2_div2_clk),
+ CLKDEV_CON_ID("dv_clk", &dv_clk),
+ CLKDEV_CON_ID("system_clk", &system_clk),
+ CLKDEV_CON_ID("system_div2_clk", &system_div2_clk),
+ CLKDEV_CON_ID("r_clk", &r_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("usb24s", &usb24s_clk),
+ CLKDEV_CON_ID("hdmi1", &hdmi1_clk),
+ CLKDEV_CON_ID("hdmi2", &hdmi2_clk),
+ CLKDEV_CON_ID("video1", &div6_reparent_clks[DIV6_VCLK1]),
+ CLKDEV_CON_ID("video2", &div6_reparent_clks[DIV6_VCLK2]),
+ CLKDEV_CON_ID("fsiack", &fsiack_clk),
+ CLKDEV_CON_ID("fsibck", &fsibck_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("hp_clk", &div4_clks[DIV4_HP]),
+ CLKDEV_CON_ID("hpp_clk", &div4_clks[DIV4_HPP]),
+ CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]),
+ CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
+ CLKDEV_CON_ID("m3_clk", &div4_clks[DIV4_M3]),
+ CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
+
+ /* DIV6 clocks */
+ CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
+
+ /* MSTP32 clocks */
+ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]),
+ CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]),
+ CLKDEV_DEV_ID("fff20000.i2c", &mstp_clks[MSTP116]),
+ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]),
+ CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]),
+ CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP128]),
+
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]),
+ CLKDEV_DEV_ID("e6c80000.serial", &mstp_clks[MSTP200]),
+ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]),
+ CLKDEV_DEV_ID("e6c70000.serial", &mstp_clks[MSTP201]),
+ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]),
+ CLKDEV_DEV_ID("e6c60000.serial", &mstp_clks[MSTP202]),
+ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]),
+ CLKDEV_DEV_ID("e6c50000.serial", &mstp_clks[MSTP203]),
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
+ CLKDEV_DEV_ID("e6c40000.serial", &mstp_clks[MSTP204]),
+ CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]),
+ CLKDEV_DEV_ID("e6c30000.serial", &mstp_clks[MSTP206]),
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]),
+ CLKDEV_DEV_ID("e6cb0000.serial", &mstp_clks[MSTP207]),
+ CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]),
+ CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]),
+ CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]),
+ CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]),
+ CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]),
+ CLKDEV_DEV_ID("e6cd0000.serial", &mstp_clks[MSTP222]),
+ CLKDEV_DEV_ID("renesas_intc_irqpin.0", &mstp_clks[MSTP229]),
+ CLKDEV_DEV_ID("renesas_intc_irqpin.1", &mstp_clks[MSTP229]),
+ CLKDEV_DEV_ID("renesas_intc_irqpin.2", &mstp_clks[MSTP229]),
+ CLKDEV_DEV_ID("renesas_intc_irqpin.3", &mstp_clks[MSTP229]),
+ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]),
+ CLKDEV_DEV_ID("e6cc0000.serial", &mstp_clks[MSTP230]),
+
+ CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]),
+ CLKDEV_DEV_ID("fe1f0000.sound", &mstp_clks[MSTP328]),
+ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]),
+ CLKDEV_DEV_ID("e6c20000.i2c", &mstp_clks[MSTP323]),
+ CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP320]),
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
+ CLKDEV_DEV_ID("e6850000.sd", &mstp_clks[MSTP314]),
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
+ CLKDEV_DEV_ID("e6860000.sd", &mstp_clks[MSTP313]),
+ CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP312]),
+ CLKDEV_DEV_ID("e6bd0000.mmc", &mstp_clks[MSTP312]),
+ CLKDEV_DEV_ID("r8a7740-gether", &mstp_clks[MSTP309]),
+ CLKDEV_DEV_ID("e9a00000.ethernet", &mstp_clks[MSTP309]),
+ CLKDEV_DEV_ID("renesas-tpu-pwm", &mstp_clks[MSTP304]),
+ CLKDEV_DEV_ID("e6600000.pwm", &mstp_clks[MSTP304]),
+
+ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]),
+ CLKDEV_DEV_ID("e6870000.sd", &mstp_clks[MSTP415]),
+
+ /* ICK */
+ CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[MSTP111]),
+ CLKDEV_ICK_ID("fck", "fff90000.timer", &mstp_clks[MSTP111]),
+ CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP125]),
+ CLKDEV_ICK_ID("fck", "fff80000.timer", &mstp_clks[MSTP125]),
+ CLKDEV_ICK_ID("fck", "sh-cmt-48.1", &mstp_clks[MSTP329]),
+ CLKDEV_ICK_ID("fck", "e6138000.timer", &mstp_clks[MSTP329]),
+ CLKDEV_ICK_ID("host", "renesas_usbhs", &mstp_clks[MSTP416]),
+ CLKDEV_ICK_ID("func", "renesas_usbhs", &mstp_clks[MSTP407]),
+ CLKDEV_ICK_ID("phy", "renesas_usbhs", &mstp_clks[MSTP406]),
+ CLKDEV_ICK_ID("pci", "renesas_usbhs", &div4_clks[DIV4_USBP]),
+ CLKDEV_ICK_ID("usb24", "renesas_usbhs", &usb24_clk),
+ 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]),
+ CLKDEV_ICK_ID("diva", "sh_fsi2", &fsidivs[FSIDIV_A]),
+ CLKDEV_ICK_ID("divb", "sh_fsi2", &fsidivs[FSIDIV_B]),
+ CLKDEV_ICK_ID("xcka", "sh_fsi2", &fsiack_clk),
+ CLKDEV_ICK_ID("xckb", "sh_fsi2", &fsibck_clk),
+};
+
+void __init r8a7740_clock_init(u8 md_ck)
+{
+ int k, ret = 0;
+
+ /* detect system clock parent */
+ if (md_ck & MD_CK1)
+ system_clk.parent = &extal1_div2_clk;
+ else
+ system_clk.parent = &extal1_clk;
+
+ /* detect RCLK parent */
+ switch (md_ck & (MD_CK2 | MD_CK1)) {
+ case MD_CK2 | MD_CK1:
+ r_clk.parent = &extal1_div2048_clk;
+ break;
+ case MD_CK2:
+ r_clk.parent = &extal1_div1024_clk;
+ break;
+ case MD_CK1:
+ default:
+ r_clk.parent = &extalr_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_div6_reparent_register(div6_reparent_clks,
+ DIV6_REPARENT_NR);
+
+ if (!ret)
+ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
+ ret = clk_register(late_main_clks[k]);
+
+ if (!ret)
+ ret = sh_clk_fsidiv_register(fsidivs, FSIDIV_REPARENT_NR);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ if (!ret)
+ shmobile_clk_init();
+ else
+ panic("failed to setup r8a7740 clocks\n");
+}
diff --git a/arch/arm/mach-shmobile/clock-r8a7778.c b/arch/arm/mach-shmobile/clock-r8a7778.c
new file mode 100644
index 000000000..e8510c355
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-r8a7778.c
@@ -0,0 +1,342 @@
+/*
+ * r8a7778 clock framework support
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * based on r8a7779
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * MD MD MD MD PLLA PLLB EXTAL clki clkz
+ * 19 18 12 11 (HMz) (MHz) (MHz)
+ *----------------------------------------------------------------------------
+ * 1 0 0 0 x21 x21 38.00 800 800
+ * 1 0 0 1 x24 x24 33.33 800 800
+ * 1 0 1 0 x28 x28 28.50 800 800
+ * 1 0 1 1 x32 x32 25.00 800 800
+ * 1 1 0 1 x24 x21 33.33 800 700
+ * 1 1 1 0 x28 x21 28.50 800 600
+ * 1 1 1 1 x32 x24 25.00 800 600
+ */
+
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
+#include "clock.h"
+#include "common.h"
+
+#define MSTPCR0 IOMEM(0xffc80030)
+#define MSTPCR1 IOMEM(0xffc80034)
+#define MSTPCR3 IOMEM(0xffc8003c)
+#define MSTPSR1 IOMEM(0xffc80044)
+#define MSTPSR4 IOMEM(0xffc80048)
+#define MSTPSR6 IOMEM(0xffc8004c)
+#define MSTPCR4 IOMEM(0xffc80050)
+#define MSTPCR5 IOMEM(0xffc80054)
+#define MSTPCR6 IOMEM(0xffc80058)
+#define MODEMR 0xFFCC0020
+
+#define MD(nr) BIT(nr)
+
+/* ioremap() through clock mapping mandatory to avoid
+ * collision with ARM coherent DMA virtual memory range.
+ */
+
+static struct clk_mapping cpg_mapping = {
+ .phys = 0xffc80000,
+ .len = 0x80,
+};
+
+static struct clk extal_clk = {
+ /* .rate will be updated on r8a7778_clock_init() */
+ .mapping = &cpg_mapping,
+};
+
+static struct clk audio_clk_a = {
+};
+
+static struct clk audio_clk_b = {
+};
+
+static struct clk audio_clk_c = {
+};
+
+/*
+ * clock ratio of these clock will be updated
+ * on r8a7778_clock_init()
+ */
+SH_FIXED_RATIO_CLK_SET(plla_clk, extal_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(pllb_clk, extal_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(i_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(s_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(s1_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(s3_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(s4_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(b_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(out_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(p_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(g_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(z_clk, pllb_clk, 1, 1);
+
+static struct clk *main_clks[] = {
+ &extal_clk,
+ &plla_clk,
+ &pllb_clk,
+ &i_clk,
+ &s_clk,
+ &s1_clk,
+ &s3_clk,
+ &s4_clk,
+ &b_clk,
+ &out_clk,
+ &p_clk,
+ &g_clk,
+ &z_clk,
+ &audio_clk_a,
+ &audio_clk_b,
+ &audio_clk_c,
+};
+
+enum {
+ MSTP531, MSTP530,
+ MSTP529, MSTP528, MSTP527, MSTP526, MSTP525, MSTP524, MSTP523,
+ MSTP331,
+ MSTP323, MSTP322, MSTP321,
+ MSTP311, MSTP310,
+ MSTP309, MSTP308, MSTP307,
+ MSTP114,
+ MSTP110, MSTP109,
+ MSTP100,
+ MSTP030,
+ MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
+ MSTP016, MSTP015, MSTP012, MSTP011, MSTP010,
+ MSTP009, MSTP008, MSTP007,
+ MSTP_NR };
+
+static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP531] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 31, 0), /* SCU0 */
+ [MSTP530] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 30, 0), /* SCU1 */
+ [MSTP529] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 29, 0), /* SCU2 */
+ [MSTP528] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 28, 0), /* SCU3 */
+ [MSTP527] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 27, 0), /* SCU4 */
+ [MSTP526] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 26, 0), /* SCU5 */
+ [MSTP525] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 25, 0), /* SCU6 */
+ [MSTP524] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 24, 0), /* SCU7 */
+ [MSTP523] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 23, 0), /* SCU8 */
+ [MSTP331] = SH_CLK_MSTP32(&s4_clk, MSTPCR3, 31, 0), /* MMC */
+ [MSTP323] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 23, 0), /* SDHI0 */
+ [MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */
+ [MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */
+ [MSTP311] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 11, 0), /* SSI4 */
+ [MSTP310] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 10, 0), /* SSI5 */
+ [MSTP309] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 9, 0), /* SSI6 */
+ [MSTP308] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 8, 0), /* SSI7 */
+ [MSTP307] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 7, 0), /* SSI8 */
+ [MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */
+ [MSTP110] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 10, 0), /* VIN0 */
+ [MSTP109] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 9, 0), /* VIN1 */
+ [MSTP100] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 0, 0), /* USB0/1 */
+ [MSTP030] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 30, 0), /* I2C0 */
+ [MSTP029] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 29, 0), /* I2C1 */
+ [MSTP028] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 28, 0), /* I2C2 */
+ [MSTP027] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 27, 0), /* I2C3 */
+ [MSTP026] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 26, 0), /* SCIF0 */
+ [MSTP025] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 25, 0), /* SCIF1 */
+ [MSTP024] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 24, 0), /* SCIF2 */
+ [MSTP023] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 23, 0), /* SCIF3 */
+ [MSTP022] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 22, 0), /* SCIF4 */
+ [MSTP021] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 21, 0), /* SCIF5 */
+ [MSTP016] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 16, 0), /* TMU0 */
+ [MSTP015] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 15, 0), /* TMU1 */
+ [MSTP012] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 12, 0), /* SSI0 */
+ [MSTP011] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 11, 0), /* SSI1 */
+ [MSTP010] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 10, 0), /* SSI2 */
+ [MSTP009] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 9, 0), /* SSI3 */
+ [MSTP008] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 8, 0), /* SRU */
+ [MSTP007] = SH_CLK_MSTP32(&s_clk, MSTPCR0, 7, 0), /* HSPI */
+};
+
+static struct clk_lookup lookups[] = {
+ /* main */
+ CLKDEV_CON_ID("shyway_clk", &s_clk),
+ CLKDEV_CON_ID("peripheral_clk", &p_clk),
+
+ /* MSTP32 clocks */
+ CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP331]), /* MMC */
+ CLKDEV_DEV_ID("ffe4e000.mmc", &mstp_clks[MSTP331]), /* MMC */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
+ CLKDEV_DEV_ID("ffe4c000.sd", &mstp_clks[MSTP323]), /* SDHI0 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
+ CLKDEV_DEV_ID("ffe4d000.sd", &mstp_clks[MSTP322]), /* SDHI1 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
+ CLKDEV_DEV_ID("ffe4f000.sd", &mstp_clks[MSTP321]), /* SDHI2 */
+ CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */
+ CLKDEV_DEV_ID("r8a7778-vin.0", &mstp_clks[MSTP110]), /* VIN0 */
+ CLKDEV_DEV_ID("r8a7778-vin.1", &mstp_clks[MSTP109]), /* VIN1 */
+ CLKDEV_DEV_ID("ehci-platform", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
+ CLKDEV_DEV_ID("ohci-platform", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
+ CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP100]), /* USB FUNC */
+ CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
+ CLKDEV_DEV_ID("ffc70000.i2c", &mstp_clks[MSTP030]), /* I2C0 */
+ CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
+ CLKDEV_DEV_ID("ffc71000.i2c", &mstp_clks[MSTP029]), /* I2C1 */
+ CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
+ CLKDEV_DEV_ID("ffc72000.i2c", &mstp_clks[MSTP028]), /* I2C2 */
+ CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
+ CLKDEV_DEV_ID("ffc73000.i2c", &mstp_clks[MSTP027]), /* I2C3 */
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
+ CLKDEV_DEV_ID("ffe40000.serial", &mstp_clks[MSTP026]), /* SCIF0 */
+ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
+ CLKDEV_DEV_ID("ffe41000.serial", &mstp_clks[MSTP025]), /* SCIF1 */
+ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
+ CLKDEV_DEV_ID("ffe42000.serial", &mstp_clks[MSTP024]), /* SCIF2 */
+ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
+ CLKDEV_DEV_ID("ffe43000.serial", &mstp_clks[MSTP023]), /* SCIF3 */
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
+ CLKDEV_DEV_ID("ffe44000.serial", &mstp_clks[MSTP022]), /* SCIF4 */
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
+ CLKDEV_DEV_ID("ffe45000.serial", &mstp_clks[MSTP021]), /* SCIF5 */
+ CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
+ CLKDEV_DEV_ID("fffc7000.spi", &mstp_clks[MSTP007]), /* HSPI0 */
+ CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
+ CLKDEV_DEV_ID("fffc8000.spi", &mstp_clks[MSTP007]), /* HSPI1 */
+ CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
+ CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */
+ CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP008]), /* SRU */
+
+ CLKDEV_ICK_ID("clk_a", "rcar_sound", &audio_clk_a),
+ CLKDEV_ICK_ID("clk_b", "rcar_sound", &audio_clk_b),
+ CLKDEV_ICK_ID("clk_c", "rcar_sound", &audio_clk_c),
+ CLKDEV_ICK_ID("clk_i", "rcar_sound", &s1_clk),
+ CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP012]),
+ CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP011]),
+ CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP010]),
+ CLKDEV_ICK_ID("ssi.3", "rcar_sound", &mstp_clks[MSTP009]),
+ CLKDEV_ICK_ID("ssi.4", "rcar_sound", &mstp_clks[MSTP311]),
+ CLKDEV_ICK_ID("ssi.5", "rcar_sound", &mstp_clks[MSTP310]),
+ CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP309]),
+ CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP308]),
+ CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP307]),
+ CLKDEV_ICK_ID("src.0", "rcar_sound", &mstp_clks[MSTP531]),
+ CLKDEV_ICK_ID("src.1", "rcar_sound", &mstp_clks[MSTP530]),
+ CLKDEV_ICK_ID("src.2", "rcar_sound", &mstp_clks[MSTP529]),
+ CLKDEV_ICK_ID("src.3", "rcar_sound", &mstp_clks[MSTP528]),
+ CLKDEV_ICK_ID("src.4", "rcar_sound", &mstp_clks[MSTP527]),
+ CLKDEV_ICK_ID("src.5", "rcar_sound", &mstp_clks[MSTP526]),
+ CLKDEV_ICK_ID("src.6", "rcar_sound", &mstp_clks[MSTP525]),
+ CLKDEV_ICK_ID("src.7", "rcar_sound", &mstp_clks[MSTP524]),
+ CLKDEV_ICK_ID("src.8", "rcar_sound", &mstp_clks[MSTP523]),
+ CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP016]),
+ CLKDEV_ICK_ID("fck", "ffd80000.timer", &mstp_clks[MSTP016]),
+ CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[MSTP015]),
+ CLKDEV_ICK_ID("fck", "ffd81000.timer", &mstp_clks[MSTP015]),
+};
+
+void __init r8a7778_clock_init(void)
+{
+ void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
+ u32 mode;
+ int k, ret = 0;
+
+ BUG_ON(!modemr);
+ mode = ioread32(modemr);
+ iounmap(modemr);
+
+ switch (mode & (MD(19) | MD(18) | MD(12) | MD(11))) {
+ case MD(19):
+ extal_clk.rate = 38000000;
+ SH_CLK_SET_RATIO(&plla_clk_ratio, 21, 1);
+ SH_CLK_SET_RATIO(&pllb_clk_ratio, 21, 1);
+ break;
+ case MD(19) | MD(11):
+ extal_clk.rate = 33333333;
+ SH_CLK_SET_RATIO(&plla_clk_ratio, 24, 1);
+ SH_CLK_SET_RATIO(&pllb_clk_ratio, 24, 1);
+ break;
+ case MD(19) | MD(12):
+ extal_clk.rate = 28500000;
+ SH_CLK_SET_RATIO(&plla_clk_ratio, 28, 1);
+ SH_CLK_SET_RATIO(&pllb_clk_ratio, 28, 1);
+ break;
+ case MD(19) | MD(12) | MD(11):
+ extal_clk.rate = 25000000;
+ SH_CLK_SET_RATIO(&plla_clk_ratio, 32, 1);
+ SH_CLK_SET_RATIO(&pllb_clk_ratio, 32, 1);
+ break;
+ case MD(19) | MD(18) | MD(11):
+ extal_clk.rate = 33333333;
+ SH_CLK_SET_RATIO(&plla_clk_ratio, 24, 1);
+ SH_CLK_SET_RATIO(&pllb_clk_ratio, 21, 1);
+ break;
+ case MD(19) | MD(18) | MD(12):
+ extal_clk.rate = 28500000;
+ SH_CLK_SET_RATIO(&plla_clk_ratio, 28, 1);
+ SH_CLK_SET_RATIO(&pllb_clk_ratio, 21, 1);
+ break;
+ case MD(19) | MD(18) | MD(12) | MD(11):
+ extal_clk.rate = 25000000;
+ SH_CLK_SET_RATIO(&plla_clk_ratio, 32, 1);
+ SH_CLK_SET_RATIO(&pllb_clk_ratio, 24, 1);
+ break;
+ default:
+ BUG();
+ }
+
+ if (mode & MD(1)) {
+ SH_CLK_SET_RATIO(&i_clk_ratio, 1, 1);
+ SH_CLK_SET_RATIO(&s_clk_ratio, 1, 3);
+ SH_CLK_SET_RATIO(&s1_clk_ratio, 1, 6);
+ SH_CLK_SET_RATIO(&s3_clk_ratio, 1, 4);
+ SH_CLK_SET_RATIO(&s4_clk_ratio, 1, 8);
+ SH_CLK_SET_RATIO(&p_clk_ratio, 1, 12);
+ SH_CLK_SET_RATIO(&g_clk_ratio, 1, 12);
+ if (mode & MD(2)) {
+ SH_CLK_SET_RATIO(&b_clk_ratio, 1, 18);
+ SH_CLK_SET_RATIO(&out_clk_ratio, 1, 18);
+ } else {
+ SH_CLK_SET_RATIO(&b_clk_ratio, 1, 12);
+ SH_CLK_SET_RATIO(&out_clk_ratio, 1, 12);
+ }
+ } else {
+ SH_CLK_SET_RATIO(&i_clk_ratio, 1, 1);
+ SH_CLK_SET_RATIO(&s_clk_ratio, 1, 4);
+ SH_CLK_SET_RATIO(&s1_clk_ratio, 1, 8);
+ SH_CLK_SET_RATIO(&s3_clk_ratio, 1, 4);
+ SH_CLK_SET_RATIO(&s4_clk_ratio, 1, 8);
+ SH_CLK_SET_RATIO(&p_clk_ratio, 1, 16);
+ SH_CLK_SET_RATIO(&g_clk_ratio, 1, 12);
+ if (mode & MD(2)) {
+ SH_CLK_SET_RATIO(&b_clk_ratio, 1, 16);
+ SH_CLK_SET_RATIO(&out_clk_ratio, 1, 16);
+ } else {
+ SH_CLK_SET_RATIO(&b_clk_ratio, 1, 12);
+ SH_CLK_SET_RATIO(&out_clk_ratio, 1, 12);
+ }
+ }
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
+ ret = clk_register(main_clks[k]);
+
+ if (!ret)
+ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ if (!ret)
+ shmobile_clk_init();
+ else
+ panic("failed to setup r8a7778 clocks\n");
+}
diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c
new file mode 100644
index 000000000..fa8ab2cc9
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-r8a7779.c
@@ -0,0 +1,271 @@
+/*
+ * r8a7779 clock framework support
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 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.
+ */
+#include <linux/bitops.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
+#include <linux/sh_timer.h>
+
+#include "clock.h"
+#include "common.h"
+#include "r8a7779.h"
+
+/*
+ * MD1 = 1 MD1 = 0
+ * (PLLA = 1500) (PLLA = 1600)
+ * (MHz) (MHz)
+ *------------------------------------------------+--------------------
+ * clkz 1000 (2/3) 800 (1/2)
+ * clkzs 250 (1/6) 200 (1/8)
+ * clki 750 (1/2) 800 (1/2)
+ * clks 250 (1/6) 200 (1/8)
+ * clks1 125 (1/12) 100 (1/16)
+ * clks3 187.5 (1/8) 200 (1/8)
+ * clks4 93.7 (1/16) 100 (1/16)
+ * clkp 62.5 (1/24) 50 (1/32)
+ * clkg 62.5 (1/24) 66.6 (1/24)
+ * clkb, CLKOUT
+ * (MD2 = 0) 62.5 (1/24) 66.6 (1/24)
+ * (MD2 = 1) 41.6 (1/36) 50 (1/32)
+*/
+
+#define MD(nr) BIT(nr)
+
+#define MSTPCR0 IOMEM(0xffc80030)
+#define MSTPCR1 IOMEM(0xffc80034)
+#define MSTPCR3 IOMEM(0xffc8003c)
+#define MSTPSR1 IOMEM(0xffc80044)
+
+/* ioremap() through clock mapping mandatory to avoid
+ * collision with ARM coherent DMA virtual memory range.
+ */
+
+static struct clk_mapping cpg_mapping = {
+ .phys = 0xffc80000,
+ .len = 0x80,
+};
+
+/*
+ * Default rate for the root input clock, reset this with clk_set_rate()
+ * from the platform code.
+ */
+static struct clk plla_clk = {
+ /* .rate will be updated on r8a7779_clock_init() */
+ .mapping = &cpg_mapping,
+};
+
+/*
+ * clock ratio of these clock will be updated
+ * on r8a7779_clock_init()
+ */
+SH_FIXED_RATIO_CLK_SET(clkz_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(clkzs_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(clki_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(clks_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(clks1_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(clks3_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(clks4_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(clkb_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(clkout_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(clkp_clk, plla_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(clkg_clk, plla_clk, 1, 1);
+
+static struct clk *main_clks[] = {
+ &plla_clk,
+ &clkz_clk,
+ &clkzs_clk,
+ &clki_clk,
+ &clks_clk,
+ &clks1_clk,
+ &clks3_clk,
+ &clks4_clk,
+ &clkb_clk,
+ &clkout_clk,
+ &clkp_clk,
+ &clkg_clk,
+};
+
+enum { MSTP323, MSTP322, MSTP321, MSTP320,
+ MSTP120,
+ MSTP116, MSTP115, MSTP114,
+ MSTP110, MSTP109, MSTP108,
+ MSTP103, MSTP101, MSTP100,
+ MSTP030,
+ MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
+ MSTP016, MSTP015, MSTP014,
+ MSTP007,
+ MSTP_NR };
+
+static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP323] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 23, 0), /* SDHI0 */
+ [MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */
+ [MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */
+ [MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */
+ [MSTP120] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 20, MSTPSR1, 0), /* VIN3 */
+ [MSTP116] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 16, MSTPSR1, 0), /* PCIe */
+ [MSTP115] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 15, MSTPSR1, 0), /* SATA */
+ [MSTP114] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 14, MSTPSR1, 0), /* Ether */
+ [MSTP110] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 10, MSTPSR1, 0), /* VIN0 */
+ [MSTP109] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 9, MSTPSR1, 0), /* VIN1 */
+ [MSTP108] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 8, MSTPSR1, 0), /* VIN2 */
+ [MSTP103] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 3, MSTPSR1, 0), /* DU */
+ [MSTP101] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 1, MSTPSR1, 0), /* USB2 */
+ [MSTP100] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 0, MSTPSR1, 0), /* USB0/1 */
+ [MSTP030] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 30, 0), /* I2C0 */
+ [MSTP029] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 29, 0), /* I2C1 */
+ [MSTP028] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 28, 0), /* I2C2 */
+ [MSTP027] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 27, 0), /* I2C3 */
+ [MSTP026] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 26, 0), /* SCIF0 */
+ [MSTP025] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 25, 0), /* SCIF1 */
+ [MSTP024] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 24, 0), /* SCIF2 */
+ [MSTP023] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 23, 0), /* SCIF3 */
+ [MSTP022] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 22, 0), /* SCIF4 */
+ [MSTP021] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 21, 0), /* SCIF5 */
+ [MSTP016] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 16, 0), /* TMU0 */
+ [MSTP015] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 15, 0), /* TMU1 */
+ [MSTP014] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 14, 0), /* TMU2 */
+ [MSTP007] = SH_CLK_MSTP32(&clks_clk, MSTPCR0, 7, 0), /* HSPI */
+};
+
+static struct clk_lookup lookups[] = {
+ /* main clocks */
+ CLKDEV_CON_ID("plla_clk", &plla_clk),
+ CLKDEV_CON_ID("clkz_clk", &clkz_clk),
+ CLKDEV_CON_ID("clkzs_clk", &clkzs_clk),
+
+ /* DIV4 clocks */
+ CLKDEV_CON_ID("shyway_clk", &clks_clk),
+ CLKDEV_CON_ID("bus_clk", &clkout_clk),
+ CLKDEV_CON_ID("shyway4_clk", &clks4_clk),
+ CLKDEV_CON_ID("shyway3_clk", &clks3_clk),
+ CLKDEV_CON_ID("shyway1_clk", &clks1_clk),
+ CLKDEV_CON_ID("peripheral_clk", &clkp_clk),
+
+ /* MSTP32 clocks */
+ CLKDEV_DEV_ID("r8a7779-vin.3", &mstp_clks[MSTP120]), /* VIN3 */
+ CLKDEV_DEV_ID("rcar-pcie", &mstp_clks[MSTP116]), /* PCIe */
+ CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */
+ CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */
+ CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */
+ CLKDEV_DEV_ID("r8a7779-vin.0", &mstp_clks[MSTP110]), /* VIN0 */
+ CLKDEV_DEV_ID("r8a7779-vin.1", &mstp_clks[MSTP109]), /* VIN1 */
+ CLKDEV_DEV_ID("r8a7779-vin.2", &mstp_clks[MSTP108]), /* VIN2 */
+ CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */
+ CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */
+ CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
+ CLKDEV_DEV_ID("ohci-platform.0", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
+ CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP016]), /* TMU0 */
+ CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
+ CLKDEV_DEV_ID("ffc70000.i2c", &mstp_clks[MSTP030]), /* I2C0 */
+ CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
+ CLKDEV_DEV_ID("ffc71000.i2c", &mstp_clks[MSTP029]), /* I2C1 */
+ CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
+ CLKDEV_DEV_ID("ffc72000.i2c", &mstp_clks[MSTP028]), /* I2C2 */
+ CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
+ CLKDEV_DEV_ID("ffc73000.i2c", &mstp_clks[MSTP027]), /* I2C3 */
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
+ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
+ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
+ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
+ CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
+ CLKDEV_DEV_ID("fffc7000.spi", &mstp_clks[MSTP007]), /* HSPI0 */
+ CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
+ CLKDEV_DEV_ID("fffc8000.spi", &mstp_clks[MSTP007]), /* HSPI1 */
+ CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
+ CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
+ CLKDEV_DEV_ID("ffe4c000.sd", &mstp_clks[MSTP323]), /* SDHI0 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
+ CLKDEV_DEV_ID("ffe4d000.sd", &mstp_clks[MSTP322]), /* SDHI1 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
+ CLKDEV_DEV_ID("ffe4e000.sd", &mstp_clks[MSTP321]), /* SDHI2 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */
+ CLKDEV_DEV_ID("ffe4f000.sd", &mstp_clks[MSTP320]), /* SDHI3 */
+ CLKDEV_DEV_ID("rcar-du-r8a7779", &mstp_clks[MSTP103]), /* DU */
+};
+
+void __init r8a7779_clock_init(void)
+{
+ u32 mode = r8a7779_read_mode_pins();
+ int k, ret = 0;
+
+ if (mode & MD(1)) {
+ plla_clk.rate = 1500000000;
+
+ SH_CLK_SET_RATIO(&clkz_clk_ratio, 2, 3);
+ SH_CLK_SET_RATIO(&clkzs_clk_ratio, 1, 6);
+ SH_CLK_SET_RATIO(&clki_clk_ratio, 1, 2);
+ SH_CLK_SET_RATIO(&clks_clk_ratio, 1, 6);
+ SH_CLK_SET_RATIO(&clks1_clk_ratio, 1, 12);
+ SH_CLK_SET_RATIO(&clks3_clk_ratio, 1, 8);
+ SH_CLK_SET_RATIO(&clks4_clk_ratio, 1, 16);
+ SH_CLK_SET_RATIO(&clkp_clk_ratio, 1, 24);
+ SH_CLK_SET_RATIO(&clkg_clk_ratio, 1, 24);
+ if (mode & MD(2)) {
+ SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 36);
+ SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 36);
+ } else {
+ SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 24);
+ SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 24);
+ }
+ } else {
+ plla_clk.rate = 1600000000;
+
+ SH_CLK_SET_RATIO(&clkz_clk_ratio, 1, 2);
+ SH_CLK_SET_RATIO(&clkzs_clk_ratio, 1, 8);
+ SH_CLK_SET_RATIO(&clki_clk_ratio, 1, 2);
+ SH_CLK_SET_RATIO(&clks_clk_ratio, 1, 8);
+ SH_CLK_SET_RATIO(&clks1_clk_ratio, 1, 16);
+ SH_CLK_SET_RATIO(&clks3_clk_ratio, 1, 8);
+ SH_CLK_SET_RATIO(&clks4_clk_ratio, 1, 16);
+ SH_CLK_SET_RATIO(&clkp_clk_ratio, 1, 32);
+ SH_CLK_SET_RATIO(&clkg_clk_ratio, 1, 24);
+ if (mode & MD(2)) {
+ SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 32);
+ SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 32);
+ } else {
+ SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 24);
+ SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 24);
+ }
+ }
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
+ ret = clk_register(main_clks[k]);
+
+ if (!ret)
+ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ if (!ret)
+ shmobile_clk_init();
+ else
+ panic("failed to setup r8a7779 clocks\n");
+}
+
+/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
+void __init __weak r8a7779_register_twd(void) { }
+
+void __init r8a7779_earlytimer_init(void)
+{
+ r8a7779_clock_init();
+ r8a7779_register_twd();
+ shmobile_earlytimer_init();
+}
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
new file mode 100644
index 000000000..3855fb024
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -0,0 +1,752 @@
+/*
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
+#include <asm/processor.h>
+#include "clock.h"
+#include "common.h"
+
+#define FRQCRA IOMEM(0xe6150000)
+#define FRQCRB IOMEM(0xe6150004)
+#define FRQCRD IOMEM(0xe61500e4)
+#define VCLKCR1 IOMEM(0xe6150008)
+#define VCLKCR2 IOMEM(0xe615000C)
+#define VCLKCR3 IOMEM(0xe615001C)
+#define ZBCKCR IOMEM(0xe6150010)
+#define FLCKCR IOMEM(0xe6150014)
+#define SD0CKCR IOMEM(0xe6150074)
+#define SD1CKCR IOMEM(0xe6150078)
+#define SD2CKCR IOMEM(0xe615007C)
+#define FSIACKCR IOMEM(0xe6150018)
+#define FSIBCKCR IOMEM(0xe6150090)
+#define SUBCKCR IOMEM(0xe6150080)
+#define SPUACKCR IOMEM(0xe6150084)
+#define SPUVCKCR IOMEM(0xe6150094)
+#define MSUCKCR IOMEM(0xe6150088)
+#define HSICKCR IOMEM(0xe615008C)
+#define MFCK1CR IOMEM(0xe6150098)
+#define MFCK2CR IOMEM(0xe615009C)
+#define DSITCKCR IOMEM(0xe6150060)
+#define DSI0PCKCR IOMEM(0xe6150064)
+#define DSI1PCKCR IOMEM(0xe6150068)
+#define DSI0PHYCR 0xe615006C
+#define DSI1PHYCR 0xe6150070
+#define PLLECR IOMEM(0xe61500d0)
+#define PLL0CR IOMEM(0xe61500d8)
+#define PLL1CR IOMEM(0xe6150028)
+#define PLL2CR IOMEM(0xe615002c)
+#define PLL3CR IOMEM(0xe61500dc)
+#define SMSTPCR0 IOMEM(0xe6150130)
+#define SMSTPCR1 IOMEM(0xe6150134)
+#define SMSTPCR2 IOMEM(0xe6150138)
+#define SMSTPCR3 IOMEM(0xe615013c)
+#define SMSTPCR4 IOMEM(0xe6150140)
+#define SMSTPCR5 IOMEM(0xe6150144)
+#define CKSCR IOMEM(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,
+};
+
+static struct sh_clk_ops main_clk_ops = {
+ .recalc = followparent_recalc,
+};
+
+/* Main clock */
+static struct clk main_clk = {
+ /* .parent wll be set on sh73a0_clock_init() */
+ .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 sh_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,
+};
+
+/* A fixed divide block */
+SH_CLK_RATIO(div2, 1, 2);
+SH_CLK_RATIO(div7, 1, 7);
+SH_CLK_RATIO(div13, 1, 13);
+
+SH_FIXED_RATIO_CLK(extal1_div2_clk, sh73a0_extal1_clk, div2);
+SH_FIXED_RATIO_CLK(extal2_div2_clk, sh73a0_extal2_clk, div2);
+SH_FIXED_RATIO_CLK(main_div2_clk, main_clk, div2);
+SH_FIXED_RATIO_CLK(pll1_div2_clk, pll1_clk, div2);
+SH_FIXED_RATIO_CLK(pll1_div7_clk, pll1_clk, div7);
+SH_FIXED_RATIO_CLK(pll1_div13_clk, pll1_clk, div13);
+
+/* External input clock */
+struct clk sh73a0_extcki_clk = {
+};
+
+struct clk sh73a0_extalr_clk = {
+};
+
+static struct clk *main_clks[] = {
+ &r_clk,
+ &sh73a0_extal1_clk,
+ &sh73a0_extal2_clk,
+ &extal1_div2_clk,
+ &extal2_div2_clk,
+ &main_clk,
+ &main_div2_clk,
+ &pll0_clk,
+ &pll1_clk,
+ &pll2_clk,
+ &pll3_clk,
+ &pll1_div2_clk,
+ &pll1_div7_clk,
+ &pll1_div13_clk,
+ &sh73a0_extcki_clk,
+ &sh73a0_extalr_clk,
+};
+
+static int frqcr_kick(void)
+{
+ int i;
+
+ /* set KICK bit in FRQCRB to update hardware setting, check success */
+ __raw_writel(__raw_readl(FRQCRB) | (1 << 31), FRQCRB);
+ for (i = 1000; i; i--)
+ if (__raw_readl(FRQCRB) & (1 << 31))
+ cpu_relax();
+ else
+ return i;
+
+ return -ETIMEDOUT;
+}
+
+static void div4_kick(struct clk *clk)
+{
+ frqcr_kick();
+}
+
+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_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, 0xdff, CLK_ENABLE_ON_INIT),
+ /*
+ * ZG clock is dividing PLL0 frequency to supply SGX. Make sure not to
+ * exceed maximum frequencies of 201.5MHz for VDD_DVFS=1.175 and
+ * 239.2MHz for VDD_DVFS=1.315V.
+ */
+ [DIV4_ZG] = SH_CLK_DIV4(&pll0_clk, FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT),
+ [DIV4_M3] = DIV4(FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT),
+ [DIV4_B] = DIV4(FRQCRA, 8, 0xdff, CLK_ENABLE_ON_INIT),
+ [DIV4_M1] = DIV4(FRQCRA, 4, 0x1dff, 0),
+ [DIV4_M2] = DIV4(FRQCRA, 0, 0x1dff, 0),
+ [DIV4_Z] = SH_CLK_DIV4(&pll0_clk, FRQCRB, 24, 0x97f, 0),
+ [DIV4_ZX] = DIV4(FRQCRB, 12, 0xdff, 0),
+ [DIV4_HP] = DIV4(FRQCRB, 4, 0xdff, 0),
+};
+
+static unsigned long twd_recalc(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 4;
+}
+
+static struct sh_clk_ops twd_clk_ops = {
+ .recalc = twd_recalc,
+};
+
+static struct clk twd_clk = {
+ .parent = &div4_clks[DIV4_Z],
+ .ops = &twd_clk_ops,
+};
+
+static struct sh_clk_ops zclk_ops, kicker_ops;
+static const struct sh_clk_ops *div4_clk_ops;
+
+static int zclk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret;
+
+ if (!clk->parent || !__clk_get(clk->parent))
+ return -ENODEV;
+
+ if (readl(FRQCRB) & (1 << 31))
+ return -EBUSY;
+
+ if (rate == clk_get_rate(clk->parent)) {
+ /* 1:1 - switch off divider */
+ __raw_writel(__raw_readl(FRQCRB) & ~(1 << 28), FRQCRB);
+ /* nullify the divider to prepare for the next time */
+ ret = div4_clk_ops->set_rate(clk, rate / 2);
+ if (!ret)
+ ret = frqcr_kick();
+ if (ret > 0)
+ ret = 0;
+ } else {
+ /* Enable the divider */
+ __raw_writel(__raw_readl(FRQCRB) | (1 << 28), FRQCRB);
+
+ ret = frqcr_kick();
+ if (ret >= 0)
+ /*
+ * set the divider - call the DIV4 method, it will kick
+ * FRQCRB too
+ */
+ ret = div4_clk_ops->set_rate(clk, rate);
+ if (ret < 0)
+ goto esetrate;
+ }
+
+esetrate:
+ __clk_put(clk->parent);
+ return ret;
+}
+
+static long zclk_round_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long div_freq = div4_clk_ops->round_rate(clk, rate),
+ parent_freq = clk_get_rate(clk->parent);
+
+ if (rate > div_freq && abs(parent_freq - rate) < rate - div_freq)
+ return parent_freq;
+
+ return div_freq;
+}
+
+static unsigned long zclk_recalc(struct clk *clk)
+{
+ /*
+ * Must recalculate frequencies in case PLL0 has been changed, even if
+ * the divisor is unused ATM!
+ */
+ unsigned long div_freq = div4_clk_ops->recalc(clk);
+
+ if (__raw_readl(FRQCRB) & (1 << 28))
+ return div_freq;
+
+ return clk_get_rate(clk->parent);
+}
+
+static int kicker_set_rate(struct clk *clk, unsigned long rate)
+{
+ if (__raw_readl(FRQCRB) & (1 << 31))
+ return -EBUSY;
+
+ return div4_clk_ops->set_rate(clk, rate);
+}
+
+static void div4_clk_extend(void)
+{
+ int i;
+
+ div4_clk_ops = div4_clks[0].ops;
+
+ /* Add a kicker-busy check before changing the rate */
+ kicker_ops = *div4_clk_ops;
+ /* We extend the DIV4 clock with a 1:1 pass-through case */
+ zclk_ops = *div4_clk_ops;
+
+ kicker_ops.set_rate = kicker_set_rate;
+ zclk_ops.set_rate = zclk_set_rate;
+ zclk_ops.round_rate = zclk_round_rate;
+ zclk_ops.recalc = zclk_recalc;
+
+ for (i = 0; i < DIV4_NR; i++)
+ div4_clks[i].ops = i == DIV4_Z ? &zclk_ops : &kicker_ops;
+}
+
+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 *vck_parent[8] = {
+ [0] = &pll1_div2_clk,
+ [1] = &pll2_clk,
+ [2] = &sh73a0_extcki_clk,
+ [3] = &sh73a0_extal2_clk,
+ [4] = &main_div2_clk,
+ [5] = &sh73a0_extalr_clk,
+ [6] = &main_clk,
+};
+
+static struct clk *pll_parent[4] = {
+ [0] = &pll1_div2_clk,
+ [1] = &pll2_clk,
+ [2] = &pll1_div13_clk,
+};
+
+static struct clk *hsi_parent[4] = {
+ [0] = &pll1_div2_clk,
+ [1] = &pll2_clk,
+ [2] = &pll1_div7_clk,
+};
+
+static struct clk *pll_extal2_parent[] = {
+ [0] = &pll1_div2_clk,
+ [1] = &pll2_clk,
+ [2] = &sh73a0_extal2_clk,
+ [3] = &sh73a0_extal2_clk,
+};
+
+static struct clk *dsi_parent[8] = {
+ [0] = &pll1_div2_clk,
+ [1] = &pll2_clk,
+ [2] = &main_clk,
+ [3] = &sh73a0_extal2_clk,
+ [4] = &sh73a0_extcki_clk,
+};
+
+static struct clk div6_clks[DIV6_NR] = {
+ [DIV6_VCK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
+ vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
+ [DIV6_VCK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
+ vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
+ [DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0,
+ vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
+ [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
+ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+ [DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+ [DIV6_SDHI0] = SH_CLK_DIV6_EXT(SD0CKCR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
+ [DIV6_SDHI1] = SH_CLK_DIV6_EXT(SD1CKCR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
+ [DIV6_SDHI2] = SH_CLK_DIV6_EXT(SD2CKCR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
+ [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
+ [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
+ [DIV6_SUB] = SH_CLK_DIV6_EXT(SUBCKCR, 0,
+ pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
+ [DIV6_SPUA] = SH_CLK_DIV6_EXT(SPUACKCR, 0,
+ pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
+ [DIV6_SPUV] = SH_CLK_DIV6_EXT(SPUVCKCR, 0,
+ pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
+ [DIV6_MSU] = SH_CLK_DIV6_EXT(MSUCKCR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+ [DIV6_HSI] = SH_CLK_DIV6_EXT(HSICKCR, 0,
+ hsi_parent, ARRAY_SIZE(hsi_parent), 6, 2),
+ [DIV6_MFG1] = SH_CLK_DIV6_EXT(MFCK1CR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+ [DIV6_MFG2] = SH_CLK_DIV6_EXT(MFCK2CR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+ [DIV6_DSIT] = SH_CLK_DIV6_EXT(DSITCKCR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+ [DIV6_DSI0P] = SH_CLK_DIV6_EXT(DSI0PCKCR, 0,
+ dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
+ [DIV6_DSI1P] = SH_CLK_DIV6_EXT(DSI1PCKCR, 0,
+ dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
+};
+
+/* DSI DIV */
+static unsigned long dsiphy_recalc(struct clk *clk)
+{
+ u32 value;
+
+ value = __raw_readl(clk->mapping->base);
+
+ /* FIXME */
+ if (!(value & 0x000B8000))
+ return clk->parent->rate;
+
+ value &= 0x3f;
+ value += 1;
+
+ if ((value < 12) ||
+ (value > 33)) {
+ pr_err("DSIPHY has wrong value (%d)", value);
+ return 0;
+ }
+
+ return clk->parent->rate / value;
+}
+
+static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
+{
+ return clk_rate_mult_range_round(clk, 12, 33, rate);
+}
+
+static void dsiphy_disable(struct clk *clk)
+{
+ u32 value;
+
+ value = __raw_readl(clk->mapping->base);
+ value &= ~0x000B8000;
+
+ __raw_writel(value , clk->mapping->base);
+}
+
+static int dsiphy_enable(struct clk *clk)
+{
+ u32 value;
+ int multi;
+
+ value = __raw_readl(clk->mapping->base);
+ multi = (value & 0x3f) + 1;
+
+ if ((multi < 12) || (multi > 33))
+ return -EIO;
+
+ __raw_writel(value | 0x000B8000, clk->mapping->base);
+
+ return 0;
+}
+
+static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 value;
+ int idx;
+
+ idx = rate / clk->parent->rate;
+ if ((idx < 12) || (idx > 33))
+ return -EINVAL;
+
+ idx += -1;
+
+ value = __raw_readl(clk->mapping->base);
+ value = (value & ~0x3f) + idx;
+
+ __raw_writel(value, clk->mapping->base);
+
+ return 0;
+}
+
+static struct sh_clk_ops dsiphy_clk_ops = {
+ .recalc = dsiphy_recalc,
+ .round_rate = dsiphy_round_rate,
+ .set_rate = dsiphy_set_rate,
+ .enable = dsiphy_enable,
+ .disable = dsiphy_disable,
+};
+
+static struct clk_mapping dsi0phy_clk_mapping = {
+ .phys = DSI0PHYCR,
+ .len = 4,
+};
+
+static struct clk_mapping dsi1phy_clk_mapping = {
+ .phys = DSI1PHYCR,
+ .len = 4,
+};
+
+static struct clk dsi0phy_clk = {
+ .ops = &dsiphy_clk_ops,
+ .parent = &div6_clks[DIV6_DSI0P], /* late install */
+ .mapping = &dsi0phy_clk_mapping,
+};
+
+static struct clk dsi1phy_clk = {
+ .ops = &dsiphy_clk_ops,
+ .parent = &div6_clks[DIV6_DSI1P], /* late install */
+ .mapping = &dsi1phy_clk_mapping,
+};
+
+static struct clk *late_main_clks[] = {
+ &dsi0phy_clk,
+ &dsi1phy_clk,
+ &twd_clk,
+};
+
+enum { MSTP001,
+ MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP112, MSTP100,
+ MSTP219, MSTP218, MSTP217,
+ MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+ MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP322,
+ MSTP314, MSTP313, MSTP312, MSTP311,
+ MSTP304, MSTP303, MSTP302, MSTP301, MSTP300,
+ MSTP411, MSTP410, MSTP403,
+ MSTP508,
+ 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 */
+ [MSTP112] = MSTP(&div4_clks[DIV4_ZG], SMSTPCR1, 12, 0), /* SGX */
+ [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
+ [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
+ [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */
+ [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* MP-DMAC */
+ [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 */
+ [MSTP328] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /*FSI*/
+ [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
+ [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
+ [MSTP322] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 22, 0), /* USB */
+ [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 */
+ [MSTP304] = MSTP(&main_div2_clk, SMSTPCR3, 4, 0), /* TPU0 */
+ [MSTP303] = MSTP(&main_div2_clk, SMSTPCR3, 3, 0), /* TPU1 */
+ [MSTP302] = MSTP(&main_div2_clk, SMSTPCR3, 2, 0), /* TPU2 */
+ [MSTP301] = MSTP(&main_div2_clk, SMSTPCR3, 1, 0), /* TPU3 */
+ [MSTP300] = MSTP(&main_div2_clk, SMSTPCR3, 0, 0), /* TPU4 */
+ [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 */
+ [MSTP508] = MSTP(&div4_clks[DIV4_HP], SMSTPCR5, 8, 0), /* INTCA0 */
+};
+
+/* The lookups structure below includes duplicate entries for some clocks
+ * with alternate names.
+ * - The traditional name used when a device is initialised with platform data
+ * - The name used when a device is initialised using device tree
+ * The longer-term aim is to remove these duplicates, and indeed the
+ * lookups table entirely, by describing clocks using device tree.
+ */
+static struct clk_lookup lookups[] = {
+ /* main clocks */
+ CLKDEV_CON_ID("r_clk", &r_clk),
+ CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */
+
+ /* DIV4 clocks */
+ CLKDEV_DEV_ID("cpu0", &div4_clks[DIV4_Z]),
+
+ /* 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]),
+
+ /* MSTP32 clocks */
+ CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
+ CLKDEV_DEV_ID("e6824000.i2c", &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-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
+ CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
+ CLKDEV_DEV_ID("e6820000.i2c", &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("e6cd0000.serial", &mstp_clks[MSTP219]), /* SCIFA7 */
+ CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */
+ CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* MP-DMAC */
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
+ CLKDEV_DEV_ID("e6cb0000.serial", &mstp_clks[MSTP207]), /* SCIFA5 */
+ CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
+ CLKDEV_DEV_ID("e6c3000.serial", &mstp_clks[MSTP206]), /* SCIFB */
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
+ CLKDEV_DEV_ID("e6c40000.serial", &mstp_clks[MSTP204]), /* SCIFA0 */
+ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
+ CLKDEV_DEV_ID("e6c50000.serial", &mstp_clks[MSTP203]), /* SCIFA1 */
+ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
+ CLKDEV_DEV_ID("e6c60000.serial", &mstp_clks[MSTP202]), /* SCIFA2 */
+ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
+ CLKDEV_DEV_ID("e6c70000.serial", &mstp_clks[MSTP201]), /* SCIFA3 */
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
+ CLKDEV_DEV_ID("e6c80000.serial", &mstp_clks[MSTP200]), /* SCIFA4 */
+ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
+ CLKDEV_DEV_ID("e6cc0000.serial", &mstp_clks[MSTP331]), /* SCIFA6 */
+ CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
+ CLKDEV_DEV_ID("ec230000.sound", &mstp_clks[MSTP328]), /* FSI */
+ CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
+ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
+ CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */
+ CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
+ CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]), /* SDHI0 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
+ CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]), /* SDHI1 */
+ CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
+ CLKDEV_DEV_ID("e6bd0000.mmc", &mstp_clks[MSTP312]), /* MMCIF0 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
+ CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP311]), /* SDHI2 */
+ CLKDEV_DEV_ID("renesas-tpu-pwm.0", &mstp_clks[MSTP304]), /* TPU0 */
+ CLKDEV_DEV_ID("renesas-tpu-pwm.1", &mstp_clks[MSTP303]), /* TPU1 */
+ CLKDEV_DEV_ID("renesas-tpu-pwm.2", &mstp_clks[MSTP302]), /* TPU2 */
+ CLKDEV_DEV_ID("renesas-tpu-pwm.3", &mstp_clks[MSTP301]), /* TPU3 */
+ CLKDEV_DEV_ID("renesas-tpu-pwm.4", &mstp_clks[MSTP300]), /* TPU4 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
+ CLKDEV_DEV_ID("e6826000.i2c", &mstp_clks[MSTP411]), /* I2C3 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
+ CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */
+ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
+ CLKDEV_DEV_ID("renesas_intc_irqpin.0", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("e6900000.irqpin", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("renesas_intc_irqpin.1", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("e6900004.irqpin", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("renesas_intc_irqpin.2", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("e6900008.irqpin", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("renesas_intc_irqpin.3", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("e690000c.irqpin", &mstp_clks[MSTP508]), /* INTCA0 */
+
+ /* ICK */
+ 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("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
+ CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
+ CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
+ CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
+ CLKDEV_ICK_ID("fck", "sh-cmt-48.1", &mstp_clks[MSTP329]), /* CMT1 */
+ CLKDEV_ICK_ID("fck", "e6138000.timer", &mstp_clks[MSTP329]), /* CMT1 */
+ CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP125]), /* TMU0 */
+};
+
+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) >> 28) & 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)
+ div4_clk_extend();
+ }
+
+ if (!ret)
+ ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
+
+ if (!ret)
+ ret = sh_clk_mstp_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)
+ shmobile_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 000000000..68c2d06d0
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock.c
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ *
+ */
+
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sh_clk.h>
+
+#include "clock.h"
+#include "common.h"
+
+unsigned long shmobile_fixed_ratio_clk_recalc(struct clk *clk)
+{
+ struct clk_ratio *p = clk->priv;
+
+ return clk->parent->rate / p->div * p->mul;
+};
+
+struct sh_clk_ops shmobile_fixed_ratio_clk_ops = {
+ .recalc = shmobile_fixed_ratio_clk_recalc,
+};
+
+int __init shmobile_clk_init(void)
+{
+ /* Kick the child clocks.. */
+ recalculate_root_clocks();
+
+ /* Enable the necessary init clocks */
+ clk_enable_init_clocks();
+
+ return 0;
+}
diff --git a/arch/arm/mach-shmobile/clock.h b/arch/arm/mach-shmobile/clock.h
new file mode 100644
index 000000000..cf3552ea1
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock.h
@@ -0,0 +1,42 @@
+#ifndef CLOCK_H
+#define CLOCK_H
+
+/* legacy clock implementation */
+
+struct clk;
+unsigned long shmobile_fixed_ratio_clk_recalc(struct clk *clk);
+extern struct sh_clk_ops shmobile_fixed_ratio_clk_ops;
+
+/* clock ratio */
+struct clk_ratio {
+ int mul;
+ int div;
+};
+
+#define SH_CLK_RATIO(name, m, d) \
+static struct clk_ratio name ##_ratio = { \
+ .mul = m, \
+ .div = d, \
+}
+
+#define SH_FIXED_RATIO_CLKg(name, p, r) \
+struct clk name = { \
+ .parent = &p, \
+ .ops = &shmobile_fixed_ratio_clk_ops,\
+ .priv = &r ## _ratio, \
+}
+
+#define SH_FIXED_RATIO_CLK(name, p, r) \
+static SH_FIXED_RATIO_CLKg(name, p, r)
+
+#define SH_FIXED_RATIO_CLK_SET(name, p, m, d) \
+ SH_CLK_RATIO(name, m, d); \
+ SH_FIXED_RATIO_CLK(name, p, name)
+
+#define SH_CLK_SET_RATIO(p, m, d) \
+do { \
+ (p)->mul = m; \
+ (p)->div = d; \
+} while (0)
+
+#endif
diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h
new file mode 100644
index 000000000..afc60bad6
--- /dev/null
+++ b/arch/arm/mach-shmobile/common.h
@@ -0,0 +1,48 @@
+#ifndef __ARCH_MACH_COMMON_H
+#define __ARCH_MACH_COMMON_H
+
+extern void shmobile_earlytimer_init(void);
+extern void shmobile_init_delay(void);
+struct twd_local_timer;
+extern void shmobile_setup_console(void);
+extern void shmobile_boot_vector(void);
+extern unsigned long shmobile_boot_fn;
+extern unsigned long shmobile_boot_arg;
+extern unsigned long shmobile_boot_size;
+extern void shmobile_smp_boot(void);
+extern void shmobile_smp_sleep(void);
+extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn,
+ unsigned long arg);
+extern int shmobile_smp_cpu_disable(unsigned int cpu);
+extern void shmobile_invalidate_start(void);
+extern void shmobile_boot_scu(void);
+extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus);
+extern void shmobile_smp_scu_cpu_die(unsigned int cpu);
+extern int shmobile_smp_scu_cpu_kill(unsigned int cpu);
+struct clk;
+extern int shmobile_clk_init(void);
+extern struct platform_suspend_ops shmobile_suspend_ops;
+
+#ifdef CONFIG_SUSPEND
+int shmobile_suspend_init(void);
+void shmobile_smp_apmu_suspend_init(void);
+#else
+static inline int shmobile_suspend_init(void) { return 0; }
+static inline void shmobile_smp_apmu_suspend_init(void) { }
+#endif
+
+#ifdef CONFIG_CPU_FREQ
+int shmobile_cpufreq_init(void);
+#else
+static inline int shmobile_cpufreq_init(void) { return 0; }
+#endif
+
+extern void __iomem *shmobile_scu_base;
+
+static inline void __init shmobile_init_late(void)
+{
+ shmobile_suspend_init();
+ shmobile_cpufreq_init();
+}
+
+#endif /* __ARCH_MACH_COMMON_H */
diff --git a/arch/arm/mach-shmobile/console.c b/arch/arm/mach-shmobile/console.c
new file mode 100644
index 000000000..e329ccbd0
--- /dev/null
+++ b/arch/arm/mach-shmobile/console.c
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <asm/mach/map.h>
+#include "common.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/cpufreq.c b/arch/arm/mach-shmobile/cpufreq.c
new file mode 100644
index 000000000..57fbff024
--- /dev/null
+++ b/arch/arm/mach-shmobile/cpufreq.c
@@ -0,0 +1,17 @@
+/*
+ * CPUFreq support code for SH-Mobile ARM
+ *
+ * Copyright (C) 2014 Gaku Inami
+ *
+ * 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/platform_device.h>
+
+int __init shmobile_cpufreq_init(void)
+{
+ platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+ return 0;
+}
diff --git a/arch/arm/mach-shmobile/dma-register.h b/arch/arm/mach-shmobile/dma-register.h
new file mode 100644
index 000000000..52a2f66e6
--- /dev/null
+++ b/arch/arm/mach-shmobile/dma-register.h
@@ -0,0 +1,84 @@
+/*
+ * SH-ARM CPU-specific DMA definitions, used by both DMA drivers
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp
+ *
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * Based on arch/sh/include/cpu-sh4/cpu/dma-register.h
+ * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.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 DMA_REGISTER_H
+#define DMA_REGISTER_H
+
+/*
+ * Direct Memory Access Controller
+ */
+
+/* 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 */
+static const unsigned int dma_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_LOW_BIT 0x3 /* --xx */
+#define TS_HI_BIT 0xc /* xx-- */
+
+#define TS_LOW_SHIFT (3)
+#define TS_HI_SHIFT (20 - 2) /* 2 bits for shifted low TS */
+
+#define TS_INDEX2VAL(i) \
+ ((((i) & TS_LOW_BIT) << TS_LOW_SHIFT) |\
+ (((i) & TS_HI_BIT) << TS_HI_SHIFT))
+
+#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | RS_ERS | TS_INDEX2VAL((xmit_sz)))
+#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | RS_ERS | TS_INDEX2VAL((xmit_sz)))
+
+
+/*
+ * USB High-Speed DMAC
+ */
+/* Transmit sizes and respective CHCR register values */
+enum {
+ USBTS_XMIT_SZ_8BYTE = 0,
+ USBTS_XMIT_SZ_16BYTE = 1,
+ USBTS_XMIT_SZ_32BYTE = 2,
+};
+
+/* log2(size / 8) - used to calculate number of transfers */
+static const unsigned int dma_usbts_shift[] = {
+ [USBTS_XMIT_SZ_8BYTE] = 3,
+ [USBTS_XMIT_SZ_16BYTE] = 4,
+ [USBTS_XMIT_SZ_32BYTE] = 5,
+};
+
+#define USBTS_LOW_BIT 0x3 /* --xx */
+#define USBTS_HI_BIT 0x0 /* ---- */
+
+#define USBTS_LOW_SHIFT 6
+#define USBTS_HI_SHIFT 0
+
+#define USBTS_INDEX2VAL(i) (((i) & 3) << 6)
+
+#endif /* DMA_REGISTER_H */
diff --git a/arch/arm/mach-shmobile/headsmp-scu.S b/arch/arm/mach-shmobile/headsmp-scu.S
new file mode 100644
index 000000000..69df8bfac
--- /dev/null
+++ b/arch/arm/mach-shmobile/headsmp-scu.S
@@ -0,0 +1,46 @@
+/*
+ * Shared SCU setup for mach-shmobile
+ *
+ * Copyright (C) 2012 Bastian Hecht
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <linux/init.h>
+#include <asm/memory.h>
+
+/*
+ * Boot code for secondary CPUs.
+ *
+ * First we turn on L1 cache coherency for our CPU. Then we jump to
+ * shmobile_invalidate_start that invalidates the cache and hands over control
+ * to the common ARM startup code.
+ */
+ENTRY(shmobile_boot_scu)
+ @ r0 = SCU base address
+ mrc p15, 0, r1, c0, c0, 5 @ read MIPDR
+ and r1, r1, #3 @ mask out cpu ID
+ lsl r1, r1, #3 @ we will shift by cpu_id * 8 bits
+ ldr r2, [r0, #8] @ SCU Power Status Register
+ mov r3, #3
+ lsl r3, r3, r1
+ bic r2, r2, r3 @ Clear bits of our CPU (Run Mode)
+ str r2, [r0, #8] @ write back
+
+ b shmobile_invalidate_start
+ENDPROC(shmobile_boot_scu)
+
+ .text
+ .align 2
+ .globl shmobile_scu_base
+shmobile_scu_base:
+ .space 4
diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S
new file mode 100644
index 000000000..50c491567
--- /dev/null
+++ b/arch/arm/mach-shmobile/headsmp.S
@@ -0,0 +1,98 @@
+/*
+ * 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/init.h>
+#include <linux/linkage.h>
+#include <linux/threads.h>
+#include <asm/assembler.h>
+#include <asm/memory.h>
+
+#ifdef CONFIG_SMP
+ENTRY(shmobile_invalidate_start)
+ bl v7_invalidate_l1
+ b secondary_startup
+ENDPROC(shmobile_invalidate_start)
+#endif
+
+/*
+ * Reset vector for secondary CPUs.
+ * This will be mapped at address 0 by SBAR register.
+ * We need _long_ jump to the physical address.
+ */
+ .arm
+ .align 12
+ENTRY(shmobile_boot_vector)
+ ldr r0, 2f
+ ldr r1, 1f
+ bx r1
+
+ENDPROC(shmobile_boot_vector)
+
+ .align 2
+ .globl shmobile_boot_fn
+shmobile_boot_fn:
+1: .space 4
+ .globl shmobile_boot_arg
+shmobile_boot_arg:
+2: .space 4
+ .globl shmobile_boot_size
+shmobile_boot_size:
+ .long . - shmobile_boot_vector
+
+/*
+ * Per-CPU SMP boot function/argument selection code based on MPIDR
+ */
+
+ENTRY(shmobile_smp_boot)
+ @ r0 = MPIDR_HWID_BITMASK
+ mrc p15, 0, r1, c0, c0, 5 @ r1 = MPIDR
+ and r0, r1, r0 @ r0 = cpu_logical_map() value
+ mov r1, #0 @ r1 = CPU index
+ adr r5, 1f @ array of per-cpu mpidr values
+ adr r6, 2f @ array of per-cpu functions
+ adr r7, 3f @ array of per-cpu arguments
+
+shmobile_smp_boot_find_mpidr:
+ ldr r8, [r5, r1, lsl #2]
+ cmp r8, r0
+ bne shmobile_smp_boot_next
+
+ ldr r9, [r6, r1, lsl #2]
+ cmp r9, #0
+ bne shmobile_smp_boot_found
+
+shmobile_smp_boot_next:
+ add r1, r1, #1
+ cmp r1, #NR_CPUS
+ blo shmobile_smp_boot_find_mpidr
+
+ b shmobile_smp_sleep
+
+shmobile_smp_boot_found:
+ ldr r0, [r7, r1, lsl #2]
+ ret r9
+ENDPROC(shmobile_smp_boot)
+
+ENTRY(shmobile_smp_sleep)
+ wfi
+ b shmobile_smp_boot
+ENDPROC(shmobile_smp_sleep)
+
+ .globl shmobile_smp_mpidr
+shmobile_smp_mpidr:
+1: .space NR_CPUS * 4
+ .globl shmobile_smp_fn
+shmobile_smp_fn:
+2: .space NR_CPUS * 4
+ .globl shmobile_smp_arg
+shmobile_smp_arg:
+3: .space NR_CPUS * 4
diff --git a/arch/arm/mach-shmobile/include/mach/head-kzm9g.txt b/arch/arm/mach-shmobile/include/mach/head-kzm9g.txt
new file mode 100644
index 000000000..9531f46a8
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/head-kzm9g.txt
@@ -0,0 +1,410 @@
+LIST "KZM9G low-level initialization routine."
+LIST "Adapted from u-boot KZM9G support code."
+
+LIST "Copyright (C) 2013 Ulrich Hecht"
+
+LIST "This program is free software; you can redistribute it and/or modify"
+LIST "it under the terms of the GNU General Public License version 2 as"
+LIST "published by the Free Software Foundation."
+
+LIST "This program is distributed in the hope that it will be useful,"
+LIST "but WITHOUT ANY WARRANTY; without even the implied warranty of"
+LIST "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
+LIST "GNU General Public License for more details."
+
+
+LIST "Register definitions:"
+
+LIST "Secure control register"
+#define LIFEC_SEC_SRC (0xE6110008)
+
+LIST "RWDT"
+#define RWDT_BASE (0xE6020000)
+#define RWTCSRA0 (RWDT_BASE + 0x04)
+
+LIST "HPB Semaphore Control Registers"
+#define HPBSCR_BASE (0xE6000000)
+#define HPBCTRL6 (HPBSCR_BASE + 0x1030)
+
+#define SBSC1_BASE (0xFE400000)
+#define SDCR0A (SBSC1_BASE + 0x0008)
+#define SDCR1A (SBSC1_BASE + 0x000C)
+#define SDPCRA (SBSC1_BASE + 0x0010)
+#define SDCR0SA (SBSC1_BASE + 0x0018)
+#define SDCR1SA (SBSC1_BASE + 0x001C)
+#define RTCSRA (SBSC1_BASE + 0x0020)
+#define RTCORA (SBSC1_BASE + 0x0028)
+#define RTCORHA (SBSC1_BASE + 0x002C)
+#define SDWCRC0A (SBSC1_BASE + 0x0040)
+#define SDWCRC1A (SBSC1_BASE + 0x0044)
+#define SDWCR00A (SBSC1_BASE + 0x0048)
+#define SDWCR01A (SBSC1_BASE + 0x004C)
+#define SDWCR10A (SBSC1_BASE + 0x0050)
+#define SDWCR11A (SBSC1_BASE + 0x0054)
+#define SDWCR2A (SBSC1_BASE + 0x0060)
+#define SDWCRC2A (SBSC1_BASE + 0x0064)
+#define ZQCCRA (SBSC1_BASE + 0x0068)
+#define SDMRACR0A (SBSC1_BASE + 0x0084)
+#define SDMRTMPCRA (SBSC1_BASE + 0x008C)
+#define SDMRTMPMSKA (SBSC1_BASE + 0x0094)
+#define SDGENCNTA (SBSC1_BASE + 0x009C)
+#define SDDRVCR0A (SBSC1_BASE + 0x00B4)
+#define DLLCNT0A (SBSC1_BASE + 0x0354)
+
+#define SDMRA1 (0xFE500000)
+#define SDMRA2 (0xFE5C0000)
+#define SDMRA3 (0xFE504000)
+
+#define SBSC2_BASE (0xFB400000)
+#define SDCR0B (SBSC2_BASE + 0x0008)
+#define SDCR1B (SBSC2_BASE + 0x000C)
+#define SDPCRB (SBSC2_BASE + 0x0010)
+#define SDCR0SB (SBSC2_BASE + 0x0018)
+#define SDCR1SB (SBSC2_BASE + 0x001C)
+#define RTCSRB (SBSC2_BASE + 0x0020)
+#define RTCORB (SBSC2_BASE + 0x0028)
+#define RTCORHB (SBSC2_BASE + 0x002C)
+#define SDWCRC0B (SBSC2_BASE + 0x0040)
+#define SDWCRC1B (SBSC2_BASE + 0x0044)
+#define SDWCR00B (SBSC2_BASE + 0x0048)
+#define SDWCR01B (SBSC2_BASE + 0x004C)
+#define SDWCR10B (SBSC2_BASE + 0x0050)
+#define SDWCR11B (SBSC2_BASE + 0x0054)
+#define SDPDCR0B (SBSC2_BASE + 0x0058)
+#define SDWCR2B (SBSC2_BASE + 0x0060)
+#define SDWCRC2B (SBSC2_BASE + 0x0064)
+#define ZQCCRB (SBSC2_BASE + 0x0068)
+#define SDMRACR0B (SBSC2_BASE + 0x0084)
+#define SDMRTMPCRB (SBSC2_BASE + 0x008C)
+#define SDMRTMPMSKB (SBSC2_BASE + 0x0094)
+#define SDGENCNTB (SBSC2_BASE + 0x009C)
+#define DPHYCNT0B (SBSC2_BASE + 0x00A0)
+#define DPHYCNT1B (SBSC2_BASE + 0x00A4)
+#define DPHYCNT2B (SBSC2_BASE + 0x00A8)
+#define SDDRVCR0B (SBSC2_BASE + 0x00B4)
+#define DLLCNT0B (SBSC2_BASE + 0x0354)
+
+#define SDMRB1 (0xFB500000)
+#define SDMRB2 (0xFB5C0000)
+#define SDMRB3 (0xFB504000)
+
+#define CPG_BASE (0xE6150000)
+#define FRQCRA (CPG_BASE + 0x0000)
+#define FRQCRB (CPG_BASE + 0x0004)
+#define FRQCRD (CPG_BASE + 0x00E4)
+#define VCLKCR1 (CPG_BASE + 0x0008)
+#define VCLKCR2 (CPG_BASE + 0x000C)
+#define VCLKCR3 (CPG_BASE + 0x001C)
+#define ZBCKCR (CPG_BASE + 0x0010)
+#define FLCKCR (CPG_BASE + 0x0014)
+#define SD0CKCR (CPG_BASE + 0x0074)
+#define SD1CKCR (CPG_BASE + 0x0078)
+#define SD2CKCR (CPG_BASE + 0x007C)
+#define FSIACKCR (CPG_BASE + 0x0018)
+#define SUBCKCR (CPG_BASE + 0x0080)
+#define SPUACKCR (CPG_BASE + 0x0084)
+#define SPUVCKCR (CPG_BASE + 0x0094)
+#define MSUCKCR (CPG_BASE + 0x0088)
+#define HSICKCR (CPG_BASE + 0x008C)
+#define FSIBCKCR (CPG_BASE + 0x0090)
+#define MFCK1CR (CPG_BASE + 0x0098)
+#define MFCK2CR (CPG_BASE + 0x009C)
+#define DSITCKCR (CPG_BASE + 0x0060)
+#define DSI0PCKCR (CPG_BASE + 0x0064)
+#define DSI1PCKCR (CPG_BASE + 0x0068)
+#define DSI0PHYCR (CPG_BASE + 0x006C)
+#define DVFSCR3 (CPG_BASE + 0x0174)
+#define DVFSCR4 (CPG_BASE + 0x0178)
+#define DVFSCR5 (CPG_BASE + 0x017C)
+#define MPMODE (CPG_BASE + 0x00CC)
+
+#define PLLECR (CPG_BASE + 0x00D0)
+#define PLL0CR (CPG_BASE + 0x00D8)
+#define PLL1CR (CPG_BASE + 0x0028)
+#define PLL2CR (CPG_BASE + 0x002C)
+#define PLL3CR (CPG_BASE + 0x00DC)
+#define PLL0STPCR (CPG_BASE + 0x00F0)
+#define PLL1STPCR (CPG_BASE + 0x00C8)
+#define PLL2STPCR (CPG_BASE + 0x00F8)
+#define PLL3STPCR (CPG_BASE + 0x00FC)
+#define RMSTPCR0 (CPG_BASE + 0x0110)
+#define RMSTPCR1 (CPG_BASE + 0x0114)
+#define RMSTPCR2 (CPG_BASE + 0x0118)
+#define RMSTPCR3 (CPG_BASE + 0x011C)
+#define RMSTPCR4 (CPG_BASE + 0x0120)
+#define RMSTPCR5 (CPG_BASE + 0x0124)
+#define SMSTPCR0 (CPG_BASE + 0x0130)
+#define SMSTPCR2 (CPG_BASE + 0x0138)
+#define SMSTPCR3 (CPG_BASE + 0x013C)
+#define CPGXXCR4 (CPG_BASE + 0x0150)
+#define SRCR0 (CPG_BASE + 0x80A0)
+#define SRCR2 (CPG_BASE + 0x80B0)
+#define SRCR3 (CPG_BASE + 0x80A8)
+#define VREFCR (CPG_BASE + 0x00EC)
+#define PCLKCR (CPG_BASE + 0x1020)
+
+#define PORT32CR (0xE6051020)
+#define PORT33CR (0xE6051021)
+#define PORT34CR (0xE6051022)
+#define PORT35CR (0xE6051023)
+
+LIST "DRAM initialization code:"
+
+EW RWTCSRA0, 0xA507
+
+ED_AND LIFEC_SEC_SRC, 0xFFFF7FFF
+
+ED_AND SMSTPCR3,0xFFFF7FFF
+ED_AND SRCR3, 0xFFFF7FFF
+ED_AND SMSTPCR2,0xFFFBFFFF
+ED_AND SRCR2, 0xFFFBFFFF
+ED PLLECR, 0x00000000
+
+WAIT_MASK PLLECR, 0x00000F00, 0x00000000
+WAIT_MASK FRQCRB, 0x80000000, 0x00000000
+
+ED PLL0CR, 0x2D000000
+ED PLL1CR, 0x17100000
+ED FRQCRB, 0x96235880
+WAIT_MASK FRQCRB, 0x80000000, 0x00000000
+
+ED FLCKCR, 0x0000000B
+ED_AND SMSTPCR0, 0xFFFFFFFD
+
+ED_AND SRCR0, 0xFFFFFFFD
+ED 0xE6001628, 0x514
+ED 0xE6001648, 0x514
+ED 0xE6001658, 0x514
+ED 0xE6001678, 0x514
+
+ED DVFSCR4, 0x00092000
+ED DVFSCR5, 0x000000DC
+ED PLLECR, 0x00000000
+WAIT_MASK PLLECR, 0x00000F00, 0x00000000
+
+ED FRQCRA, 0x0012453C
+ED FRQCRB, 0x80431350
+WAIT_MASK FRQCRB, 0x80000000, 0x00000000
+ED FRQCRD, 0x00000B0B
+WAIT_MASK FRQCRD, 0x80000000, 0x00000000
+
+ED PCLKCR, 0x00000003
+ED VCLKCR1, 0x0000012F
+ED VCLKCR2, 0x00000119
+ED VCLKCR3, 0x00000119
+ED ZBCKCR, 0x00000002
+ED FLCKCR, 0x00000005
+ED SD0CKCR, 0x00000080
+ED SD1CKCR, 0x00000080
+ED SD2CKCR, 0x00000080
+ED FSIACKCR, 0x0000003F
+ED FSIBCKCR, 0x0000003F
+ED SUBCKCR, 0x00000080
+ED SPUACKCR, 0x0000000B
+ED SPUVCKCR, 0x0000000B
+ED MSUCKCR, 0x0000013F
+ED HSICKCR, 0x00000080
+ED MFCK1CR, 0x0000003F
+ED MFCK2CR, 0x0000003F
+ED DSITCKCR, 0x00000107
+ED DSI0PCKCR, 0x00000313
+ED DSI1PCKCR, 0x0000130D
+ED DSI0PHYCR, 0x2A800E0E
+ED PLL0CR, 0x1E000000
+ED PLL0CR, 0x2D000000
+ED PLL1CR, 0x17100000
+ED PLL2CR, 0x27000080
+ED PLL3CR, 0x1D000000
+ED PLL0STPCR, 0x00080000
+ED PLL1STPCR, 0x000120C0
+ED PLL2STPCR, 0x00012000
+ED PLL3STPCR, 0x00000030
+ED PLLECR, 0x0000000B
+WAIT_MASK PLLECR, 0x00000B00, 0x00000B00
+
+ED DVFSCR3, 0x000120F0
+ED MPMODE, 0x00000020
+ED VREFCR, 0x0000028A
+ED RMSTPCR0, 0xE4628087
+ED RMSTPCR1, 0xFFFFFFFF
+ED RMSTPCR2, 0x53FFFFFF
+ED RMSTPCR3, 0xFFFFFFFF
+ED RMSTPCR4, 0x00800D3D
+ED RMSTPCR5, 0xFFFFF3FF
+ED SMSTPCR2, 0x00000000
+ED SRCR2, 0x00040000
+ED_AND PLLECR, 0xFFFFFFF7
+WAIT_MASK PLLECR, 0x00000800, 0x00000000
+
+LIST "set SBSC operational"
+ED HPBCTRL6, 0x00000001
+WAIT_MASK HPBCTRL6, 0x00000001, 0x00000001
+
+LIST "set SBSC operating frequency"
+ED FRQCRD, 0x00001414
+WAIT_MASK FRQCRD, 0x80000000, 0x00000000
+ED PLL3CR, 0x1D000000
+ED_OR PLLECR, 0x00000008
+WAIT_MASK PLLECR, 0x00000800, 0x00000800
+
+LIST "enable DLL oscillation in DDRPHY"
+ED_OR DLLCNT0A, 0x00000002
+
+LIST "wait >= 100 ns"
+ED SDGENCNTA, 0x00000005
+WAIT_MASK SDGENCNTA, 0xFFFFFFFF, 0x00000000
+
+LIST "target LPDDR2 device settings"
+ED SDCR0A, 0xACC90159
+ED SDCR1A, 0x00010059
+ED SDWCRC0A, 0x50874114
+ED SDWCRC1A, 0x33199B37
+ED SDWCRC2A, 0x008F2313
+ED SDWCR00A, 0x31020707
+ED SDWCR01A, 0x0017040A
+ED SDWCR10A, 0x31020707
+ED SDWCR11A, 0x0017040A
+
+ED SDDRVCR0A, 0x055557ff
+
+ED SDWCR2A, 0x30000000
+
+LIST "drive CKE high"
+ED_OR SDPCRA, 0x00000080
+WAIT_MASK SDPCRA, 0x00000080, 0x00000080
+
+LIST "wait >= 200 us"
+ED SDGENCNTA, 0x00002710
+WAIT_MASK SDGENCNTA, 0xFFFFFFFF, 0x00000000
+
+LIST "issue reset command to LPDDR2 device"
+ED SDMRACR0A, 0x0000003F
+ED SDMRA1, 0x00000000
+
+LIST "wait >= 10 (or 1) us (docs inconsistent)"
+ED SDGENCNTA, 0x000001F4
+WAIT_MASK SDGENCNTA, 0xFFFFFFFF, 0x00000000
+
+LIST "MRW ZS initialization calibration command"
+ED SDMRACR0A, 0x0000FF0A
+ED SDMRA3, 0x00000000
+
+LIST "wait >= 1 us"
+ED SDGENCNTA, 0x00000032
+WAIT_MASK SDGENCNTA, 0xFFFFFFFF, 0x00000000
+
+LIST "specify operating mode in LPDDR2"
+ED SDMRACR0A, 0x00002201
+ED SDMRA1, 0x00000000
+ED SDMRACR0A, 0x00000402
+ED SDMRA1, 0x00000000
+ED SDMRACR0A, 0x00000203
+ED SDMRA1, 0x00000000
+
+LIST "initialize DDR interface"
+ED SDMRA2, 0x00000000
+
+LIST "temperature sensor control"
+ED SDMRTMPCRA, 0x88800004
+ED SDMRTMPMSKA,0x00000004
+
+LIST "auto-refreshing control"
+ED RTCORA, 0xA55A0032
+ED RTCORHA, 0xA55A000C
+ED RTCSRA, 0xA55A2048
+
+ED_OR SDCR0A, 0x00000800
+ED_OR SDCR1A, 0x00000400
+
+LIST "auto ZQ calibration control"
+ED ZQCCRA, 0xFFF20000
+
+ED_OR DLLCNT0B, 0x00000002
+ED SDGENCNTB, 0x00000005
+WAIT_MASK SDGENCNTB, 0xFFFFFFFF, 0x00000000
+
+ED SDCR0B, 0xACC90159
+ED SDCR1B, 0x00010059
+ED SDWCRC0B, 0x50874114
+ED SDWCRC1B, 0x33199B37
+ED SDWCRC2B, 0x008F2313
+ED SDWCR00B, 0x31020707
+ED SDWCR01B, 0x0017040A
+ED SDWCR10B, 0x31020707
+ED SDWCR11B, 0x0017040A
+ED SDDRVCR0B, 0x055557ff
+ED SDWCR2B, 0x30000000
+ED_OR SDPCRB, 0x00000080
+WAIT_MASK SDPCRB, 0x00000080, 0x00000080
+
+ED SDGENCNTB, 0x00002710
+WAIT_MASK SDGENCNTB, 0xFFFFFFFF, 0x00000000
+ED SDMRACR0B, 0x0000003F
+
+LIST "upstream u-boot writes to SDMRA1A for both SBSC 1 and 2, which does"
+LIST "not seem to make a lot of sense..."
+ED SDMRB1, 0x00000000
+
+ED SDGENCNTB, 0x000001F4
+WAIT_MASK SDGENCNTB, 0xFFFFFFFF, 0x00000000
+
+ED SDMRACR0B, 0x0000FF0A
+ED SDMRB3, 0x00000000
+ED SDGENCNTB, 0x00000032
+WAIT_MASK SDGENCNTB, 0xFFFFFFFF, 0x00000000
+
+ED SDMRACR0B, 0x00002201
+ED SDMRB1, 0x00000000
+ED SDMRACR0B, 0x00000402
+ED SDMRB1, 0x00000000
+ED SDMRACR0B, 0x00000203
+ED SDMRB1, 0x00000000
+ED SDMRB2, 0x00000000
+ED SDMRTMPCRB, 0x88800004
+ED SDMRTMPMSKB, 0x00000004
+ED RTCORB, 0xA55A0032
+ED RTCORHB, 0xA55A000C
+ED RTCSRB, 0xA55A2048
+ED_OR SDCR0B, 0x00000800
+ED_OR SDCR1B, 0x00000400
+ED ZQCCRB, 0xFFF20000
+ED_OR SDPDCR0B, 0x00030000
+ED DPHYCNT1B, 0xA5390000
+ED DPHYCNT0B, 0x00001200
+ED DPHYCNT1B, 0x07CE0000
+ED DPHYCNT0B, 0x00001247
+WAIT_MASK DPHYCNT2B, 0xFFFFFFFF, 0x07CE0000
+
+ED_AND SDPDCR0B, 0xFFFCFFFF
+
+ED FRQCRD, 0x00000B0B
+WAIT_MASK FRQCRD, 0x80000000, 0x00000000
+
+ED CPGXXCR4, 0xfffffffc
+
+LIST "Setup SCIF4 / workaround"
+EB PORT32CR, 0x12
+EB PORT33CR, 0x22
+EB PORT34CR, 0x12
+EB PORT35CR, 0x22
+
+EW 0xE6C80000, 0
+EB 0xE6C80004, 0x19
+EW 0xE6C80008, 0x0030
+EW 0xE6C80018, 0
+EW 0xE6C80030, 0x0014
+
+LIST "Magic to avoid hangs and corruption on DRAM writes."
+
+LIST "It has been observed that the system would most often hang while"
+LIST "decompressing the kernel, and if it didn't it would always write"
+LIST "a corrupt image to DRAM."
+LIST "This problem does not occur in u-boot, and the reason is that"
+LIST "u-boot performs an additional cache invalidation after setting up"
+LIST "the DRAM controller. Such an invalidation should not be necessary at"
+LIST "this point, and attempts at removing parts of the routine to arrive"
+LIST "at the minimal snippet of code necessary to avoid the DRAM stability"
+LIST "problem yielded the following:"
+
+MRC p15, 0, r0, c1, c0, 0
+MCR p15, 0, r0, c1, c0, 0
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 000000000..5aee83f07
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/irqs.h
@@ -0,0 +1,10 @@
+#ifndef __ASM_MACH_IRQS_H
+#define __ASM_MACH_IRQS_H
+
+/* Stuck here until drivers/pinctl/sh-pfc gets rid of legacy code */
+
+/* External IRQ pins */
+#define IRQPIN_BASE 2000
+#define irq_pin(nr) ((nr) + IRQPIN_BASE)
+
+#endif /* __ASM_MACH_IRQS_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 000000000..175ee0546
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/zboot.h
@@ -0,0 +1,19 @@
+#ifndef ZBOOT_H
+#define ZBOOT_H
+
+#include <mach/zboot_macros.h>
+
+/**************************************************
+ *
+ * board specific settings
+ *
+ **************************************************/
+
+#ifdef CONFIG_MACH_KZM9G
+#define MEMORY_START 0x43000000
+#include "mach/head-kzm9g.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 000000000..14fd3d538
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/zboot_macros.h
@@ -0,0 +1,108 @@
+#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
+
+/* loop until a given value has been read (with mask) */
+.macro WAIT_MASK, addr, data, cmp
+ LDR r0, 2f
+ LDR r1, 3f
+ LDR r2, 4f
+1:
+ LDR r3, [r0, #0]
+ AND r3, r1, r3
+ CMP r2, r3
+ BNE 1b
+ B 5f
+2: .long \addr
+3: .long \data
+4: .long \cmp
+5:
+.endm
+
+/* read 32-bit value from addr, "or" an immediate and write back */
+.macro ED_OR, addr, data
+ LDR r4, 1f
+ LDR r5, 2f
+ LDR r6, [r4]
+ ORR r5, r6, r5
+ STR r5, [r4]
+ B 3f
+1: .long \addr
+2: .long \data
+3:
+.endm
+
+/* read 32-bit value from addr, "and" an immediate and write back */
+.macro ED_AND, addr, data
+ LDR r4, 1f
+ LDR r5, 2f
+ LDR r6, [r4]
+ AND r5, r6, r5
+ STR r5, [r4]
+ B 3f
+1: .long \addr
+2: .long \data
+3:
+.endm
+
+#endif /* __ZBOOT_MACRO_H */
diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c
new file mode 100644
index 000000000..fd63ae653
--- /dev/null
+++ b/arch/arm/mach-shmobile/intc-sh73a0.c
@@ -0,0 +1,337 @@
+/*
+ * 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/arm-gic.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "intc.h"
+#include "irqs.h"
+#include "sh73a0.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;
+}
+
+#define PINTER0_PHYS 0xe69000a0
+#define PINTER1_PHYS 0xe69000a4
+#define PINTER0_VIRT IOMEM(0xe69000a0)
+#define PINTER1_VIRT IOMEM(0xe69000a4)
+#define PINTRR0 IOMEM(0xe69000d0)
+#define PINTRR1 IOMEM(0xe69000d4)
+
+#define PINT0A_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq))
+#define PINT0B_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq + 8))
+#define PINT0C_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq + 16))
+#define PINT0D_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq + 24))
+#define PINT1E_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT1_IRQ(irq))
+
+INTC_PINT(intc_pint0, PINTER0_PHYS, 0xe69000b0, "sh73a0-pint0", \
+ INTC_PINT_E(A), INTC_PINT_E(B), INTC_PINT_E(C), INTC_PINT_E(D), \
+ INTC_PINT_V(A, PINT0A_IRQ), INTC_PINT_V(B, PINT0B_IRQ), \
+ INTC_PINT_V(C, PINT0C_IRQ), INTC_PINT_V(D, PINT0D_IRQ), \
+ INTC_PINT_E(A), INTC_PINT_E(B), INTC_PINT_E(C), INTC_PINT_E(D), \
+ INTC_PINT_E(A), INTC_PINT_E(B), INTC_PINT_E(C), INTC_PINT_E(D));
+
+INTC_PINT(intc_pint1, PINTER1_PHYS, 0xe69000c0, "sh73a0-pint1", \
+ INTC_PINT_E(E), INTC_PINT_E_EMPTY, INTC_PINT_E_EMPTY, INTC_PINT_E_EMPTY, \
+ INTC_PINT_V(E, PINT1E_IRQ), INTC_PINT_V_NONE, \
+ INTC_PINT_V_NONE, INTC_PINT_V_NONE, \
+ INTC_PINT_E_NONE, INTC_PINT_E_NONE, INTC_PINT_E_NONE, INTC_PINT_E(E), \
+ INTC_PINT_E(E), INTC_PINT_E_NONE, INTC_PINT_E_NONE, INTC_PINT_E_NONE);
+
+static struct irqaction sh73a0_pint0_cascade;
+static struct irqaction sh73a0_pint1_cascade;
+
+static void pint_demux(void __iomem *rr, void __iomem *er, int base_irq)
+{
+ unsigned long value = ioread32(rr) & ioread32(er);
+ int k;
+
+ for (k = 0; k < 32; k++) {
+ if (value & (1 << (31 - k))) {
+ generic_handle_irq(base_irq + k);
+ iowrite32(~(1 << (31 - k)), rr);
+ }
+ }
+}
+
+static irqreturn_t sh73a0_pint0_demux(int irq, void *dev_id)
+{
+ pint_demux(PINTRR0, PINTER0_VIRT, SH73A0_PINT0_IRQ(0));
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t sh73a0_pint1_demux(int irq, void *dev_id)
+{
+ pint_demux(PINTRR1, PINTER1_VIRT, SH73A0_PINT1_IRQ(0));
+ return IRQ_HANDLED;
+}
+
+void __init sh73a0_init_irq(void)
+{
+ void __iomem *gic_dist_base = IOMEM(0xf0001000);
+ void __iomem *gic_cpu_base = IOMEM(0xf0000100);
+ void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
+
+ gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE);
+ gic_init(0, 29, gic_dist_base, gic_cpu_base);
+
+ register_intc_controller(&intcs_desc);
+ register_intc_controller(&intc_pint0_desc);
+ register_intc_controller(&intc_pint1_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);
+
+ /* PINT pins are sanely tied to the GIC as SPI */
+ sh73a0_pint0_cascade.name = "PINT0 cascade";
+ sh73a0_pint0_cascade.handler = sh73a0_pint0_demux;
+ setup_irq(gic_spi(33), &sh73a0_pint0_cascade);
+
+ sh73a0_pint1_cascade.name = "PINT1 cascade";
+ sh73a0_pint1_cascade.handler = sh73a0_pint1_demux;
+ setup_irq(gic_spi(34), &sh73a0_pint1_cascade);
+}
diff --git a/arch/arm/mach-shmobile/intc.h b/arch/arm/mach-shmobile/intc.h
new file mode 100644
index 000000000..40b2ad4ca
--- /dev/null
+++ b/arch/arm/mach-shmobile/intc.h
@@ -0,0 +1,295 @@
+#ifndef __ASM_MACH_INTC_H
+#define __ASM_MACH_INTC_H
+#include <linux/sh_intc.h>
+
+#define INTC_IRQ_PINS_ENUM_16L(p) \
+ p ## _IRQ0, p ## _IRQ1, p ## _IRQ2, p ## _IRQ3, \
+ p ## _IRQ4, p ## _IRQ5, p ## _IRQ6, p ## _IRQ7, \
+ p ## _IRQ8, p ## _IRQ9, p ## _IRQ10, p ## _IRQ11, \
+ p ## _IRQ12, p ## _IRQ13, p ## _IRQ14, p ## _IRQ15
+
+#define INTC_IRQ_PINS_ENUM_16H(p) \
+ p ## _IRQ16, p ## _IRQ17, p ## _IRQ18, p ## _IRQ19, \
+ p ## _IRQ20, p ## _IRQ21, p ## _IRQ22, p ## _IRQ23, \
+ p ## _IRQ24, p ## _IRQ25, p ## _IRQ26, p ## _IRQ27, \
+ p ## _IRQ28, p ## _IRQ29, p ## _IRQ30, p ## _IRQ31
+
+#define INTC_IRQ_PINS_VECT_16L(p, vect) \
+ vect(p ## _IRQ0, 0x0200), vect(p ## _IRQ1, 0x0220), \
+ vect(p ## _IRQ2, 0x0240), vect(p ## _IRQ3, 0x0260), \
+ vect(p ## _IRQ4, 0x0280), vect(p ## _IRQ5, 0x02a0), \
+ vect(p ## _IRQ6, 0x02c0), vect(p ## _IRQ7, 0x02e0), \
+ vect(p ## _IRQ8, 0x0300), vect(p ## _IRQ9, 0x0320), \
+ vect(p ## _IRQ10, 0x0340), vect(p ## _IRQ11, 0x0360), \
+ vect(p ## _IRQ12, 0x0380), vect(p ## _IRQ13, 0x03a0), \
+ vect(p ## _IRQ14, 0x03c0), vect(p ## _IRQ15, 0x03e0)
+
+#define INTC_IRQ_PINS_VECT_16H(p, vect) \
+ vect(p ## _IRQ16, 0x3200), vect(p ## _IRQ17, 0x3220), \
+ vect(p ## _IRQ18, 0x3240), vect(p ## _IRQ19, 0x3260), \
+ vect(p ## _IRQ20, 0x3280), vect(p ## _IRQ21, 0x32a0), \
+ vect(p ## _IRQ22, 0x32c0), vect(p ## _IRQ23, 0x32e0), \
+ vect(p ## _IRQ24, 0x3300), vect(p ## _IRQ25, 0x3320), \
+ vect(p ## _IRQ26, 0x3340), vect(p ## _IRQ27, 0x3360), \
+ vect(p ## _IRQ28, 0x3380), vect(p ## _IRQ29, 0x33a0), \
+ vect(p ## _IRQ30, 0x33c0), vect(p ## _IRQ31, 0x33e0)
+
+#define INTC_IRQ_PINS_MASK_16L(p, base) \
+ { base + 0x40, base + 0x60, 8, /* INTMSK00A / INTMSKCLR00A */ \
+ { p ## _IRQ0, p ## _IRQ1, p ## _IRQ2, p ## _IRQ3, \
+ p ## _IRQ4, p ## _IRQ5, p ## _IRQ6, p ## _IRQ7 } }, \
+ { base + 0x44, base + 0x64, 8, /* INTMSK10A / INTMSKCLR10A */ \
+ { p ## _IRQ8, p ## _IRQ9, p ## _IRQ10, p ## _IRQ11, \
+ p ## _IRQ12, p ## _IRQ13, p ## _IRQ14, p ## _IRQ15 } }
+
+#define INTC_IRQ_PINS_MASK_16H(p, base) \
+ { base + 0x48, base + 0x68, 8, /* INTMSK20A / INTMSKCLR20A */ \
+ { p ## _IRQ16, p ## _IRQ17, p ## _IRQ18, p ## _IRQ19, \
+ p ## _IRQ20, p ## _IRQ21, p ## _IRQ22, p ## _IRQ23 } }, \
+ { base + 0x4c, base + 0x6c, 8, /* INTMSK30A / INTMSKCLR30A */ \
+ { p ## _IRQ24, p ## _IRQ25, p ## _IRQ26, p ## _IRQ27, \
+ p ## _IRQ28, p ## _IRQ29, p ## _IRQ30, p ## _IRQ31 } }
+
+#define INTC_IRQ_PINS_PRIO_16L(p, base) \
+ { base + 0x10, 0, 32, 4, /* INTPRI00A */ \
+ { p ## _IRQ0, p ## _IRQ1, p ## _IRQ2, p ## _IRQ3, \
+ p ## _IRQ4, p ## _IRQ5, p ## _IRQ6, p ## _IRQ7 } }, \
+ { base + 0x14, 0, 32, 4, /* INTPRI10A */ \
+ { p ## _IRQ8, p ## _IRQ9, p ## _IRQ10, p ## _IRQ11, \
+ p ## _IRQ12, p ## _IRQ13, p ## _IRQ14, p ## _IRQ15 } }
+
+#define INTC_IRQ_PINS_PRIO_16H(p, base) \
+ { base + 0x18, 0, 32, 4, /* INTPRI20A */ \
+ { p ## _IRQ16, p ## _IRQ17, p ## _IRQ18, p ## _IRQ19, \
+ p ## _IRQ20, p ## _IRQ21, p ## _IRQ22, p ## _IRQ23 } }, \
+ { base + 0x1c, 0, 32, 4, /* INTPRI30A */ \
+ { p ## _IRQ24, p ## _IRQ25, p ## _IRQ26, p ## _IRQ27, \
+ p ## _IRQ28, p ## _IRQ29, p ## _IRQ30, p ## _IRQ31 } }
+
+#define INTC_IRQ_PINS_SENSE_16L(p, base) \
+ { base + 0x00, 32, 4, /* ICR1A */ \
+ { p ## _IRQ0, p ## _IRQ1, p ## _IRQ2, p ## _IRQ3, \
+ p ## _IRQ4, p ## _IRQ5, p ## _IRQ6, p ## _IRQ7 } }, \
+ { base + 0x04, 32, 4, /* ICR2A */ \
+ { p ## _IRQ8, p ## _IRQ9, p ## _IRQ10, p ## _IRQ11, \
+ p ## _IRQ12, p ## _IRQ13, p ## _IRQ14, p ## _IRQ15 } }
+
+#define INTC_IRQ_PINS_SENSE_16H(p, base) \
+ { base + 0x08, 32, 4, /* ICR3A */ \
+ { p ## _IRQ16, p ## _IRQ17, p ## _IRQ18, p ## _IRQ19, \
+ p ## _IRQ20, p ## _IRQ21, p ## _IRQ22, p ## _IRQ23 } }, \
+ { base + 0x0c, 32, 4, /* ICR4A */ \
+ { p ## _IRQ24, p ## _IRQ25, p ## _IRQ26, p ## _IRQ27, \
+ p ## _IRQ28, p ## _IRQ29, p ## _IRQ30, p ## _IRQ31 } }
+
+#define INTC_IRQ_PINS_ACK_16L(p, base) \
+ { base + 0x20, 0, 8, /* INTREQ00A */ \
+ { p ## _IRQ0, p ## _IRQ1, p ## _IRQ2, p ## _IRQ3, \
+ p ## _IRQ4, p ## _IRQ5, p ## _IRQ6, p ## _IRQ7 } }, \
+ { base + 0x24, 0, 8, /* INTREQ10A */ \
+ { p ## _IRQ8, p ## _IRQ9, p ## _IRQ10, p ## _IRQ11, \
+ p ## _IRQ12, p ## _IRQ13, p ## _IRQ14, p ## _IRQ15 } }
+
+#define INTC_IRQ_PINS_ACK_16H(p, base) \
+ { base + 0x28, 0, 8, /* INTREQ20A */ \
+ { p ## _IRQ16, p ## _IRQ17, p ## _IRQ18, p ## _IRQ19, \
+ p ## _IRQ20, p ## _IRQ21, p ## _IRQ22, p ## _IRQ23 } }, \
+ { base + 0x2c, 0, 8, /* INTREQ30A */ \
+ { p ## _IRQ24, p ## _IRQ25, p ## _IRQ26, p ## _IRQ27, \
+ p ## _IRQ28, p ## _IRQ29, p ## _IRQ30, p ## _IRQ31 } }
+
+#define INTC_IRQ_PINS_16(p, base, vect, str) \
+ \
+static struct resource p ## _resources[] __initdata = { \
+ [0] = { \
+ .start = base, \
+ .end = base + 0x64, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+}; \
+ \
+enum { \
+ p ## _UNUSED = 0, \
+ INTC_IRQ_PINS_ENUM_16L(p), \
+}; \
+ \
+static struct intc_vect p ## _vectors[] __initdata = { \
+ INTC_IRQ_PINS_VECT_16L(p, vect), \
+}; \
+ \
+static struct intc_mask_reg p ## _mask_registers[] __initdata = { \
+ INTC_IRQ_PINS_MASK_16L(p, base), \
+}; \
+ \
+static struct intc_prio_reg p ## _prio_registers[] __initdata = { \
+ INTC_IRQ_PINS_PRIO_16L(p, base), \
+}; \
+ \
+static struct intc_sense_reg p ## _sense_registers[] __initdata = { \
+ INTC_IRQ_PINS_SENSE_16L(p, base), \
+}; \
+ \
+static struct intc_mask_reg p ## _ack_registers[] __initdata = { \
+ INTC_IRQ_PINS_ACK_16L(p, base), \
+}; \
+ \
+static struct intc_desc p ## _desc __initdata = { \
+ .name = str, \
+ .resource = p ## _resources, \
+ .num_resources = ARRAY_SIZE(p ## _resources), \
+ .hw = INTC_HW_DESC(p ## _vectors, NULL, \
+ p ## _mask_registers, p ## _prio_registers, \
+ p ## _sense_registers, p ## _ack_registers) \
+}
+
+#define INTC_IRQ_PINS_16H(p, base, vect, str) \
+ \
+static struct resource p ## _resources[] __initdata = { \
+ [0] = { \
+ .start = base, \
+ .end = base + 0x64, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+}; \
+ \
+enum { \
+ p ## _UNUSED = 0, \
+ INTC_IRQ_PINS_ENUM_16H(p), \
+}; \
+ \
+static struct intc_vect p ## _vectors[] __initdata = { \
+ INTC_IRQ_PINS_VECT_16H(p, vect), \
+}; \
+ \
+static struct intc_mask_reg p ## _mask_registers[] __initdata = { \
+ INTC_IRQ_PINS_MASK_16H(p, base), \
+}; \
+ \
+static struct intc_prio_reg p ## _prio_registers[] __initdata = { \
+ INTC_IRQ_PINS_PRIO_16H(p, base), \
+}; \
+ \
+static struct intc_sense_reg p ## _sense_registers[] __initdata = { \
+ INTC_IRQ_PINS_SENSE_16H(p, base), \
+}; \
+ \
+static struct intc_mask_reg p ## _ack_registers[] __initdata = { \
+ INTC_IRQ_PINS_ACK_16H(p, base), \
+}; \
+ \
+static struct intc_desc p ## _desc __initdata = { \
+ .name = str, \
+ .resource = p ## _resources, \
+ .num_resources = ARRAY_SIZE(p ## _resources), \
+ .hw = INTC_HW_DESC(p ## _vectors, NULL, \
+ p ## _mask_registers, p ## _prio_registers, \
+ p ## _sense_registers, p ## _ack_registers) \
+}
+
+#define INTC_IRQ_PINS_32(p, base, vect, str) \
+ \
+static struct resource p ## _resources[] __initdata = { \
+ [0] = { \
+ .start = base, \
+ .end = base + 0x6c, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+}; \
+ \
+enum { \
+ p ## _UNUSED = 0, \
+ INTC_IRQ_PINS_ENUM_16L(p), \
+ INTC_IRQ_PINS_ENUM_16H(p), \
+}; \
+ \
+static struct intc_vect p ## _vectors[] __initdata = { \
+ INTC_IRQ_PINS_VECT_16L(p, vect), \
+ INTC_IRQ_PINS_VECT_16H(p, vect), \
+}; \
+ \
+static struct intc_mask_reg p ## _mask_registers[] __initdata = { \
+ INTC_IRQ_PINS_MASK_16L(p, base), \
+ INTC_IRQ_PINS_MASK_16H(p, base), \
+}; \
+ \
+static struct intc_prio_reg p ## _prio_registers[] __initdata = { \
+ INTC_IRQ_PINS_PRIO_16L(p, base), \
+ INTC_IRQ_PINS_PRIO_16H(p, base), \
+}; \
+ \
+static struct intc_sense_reg p ## _sense_registers[] __initdata = { \
+ INTC_IRQ_PINS_SENSE_16L(p, base), \
+ INTC_IRQ_PINS_SENSE_16H(p, base), \
+}; \
+ \
+static struct intc_mask_reg p ## _ack_registers[] __initdata = { \
+ INTC_IRQ_PINS_ACK_16L(p, base), \
+ INTC_IRQ_PINS_ACK_16H(p, base), \
+}; \
+ \
+static struct intc_desc p ## _desc __initdata = { \
+ .name = str, \
+ .resource = p ## _resources, \
+ .num_resources = ARRAY_SIZE(p ## _resources), \
+ .hw = INTC_HW_DESC(p ## _vectors, NULL, \
+ p ## _mask_registers, p ## _prio_registers, \
+ p ## _sense_registers, p ## _ack_registers) \
+}
+
+#define INTC_PINT_E_EMPTY
+#define INTC_PINT_E_NONE 0, 0, 0, 0, 0, 0, 0, 0,
+#define INTC_PINT_E(p) \
+ PINT ## p ## 0, PINT ## p ## 1, PINT ## p ## 2, PINT ## p ## 3, \
+ PINT ## p ## 4, PINT ## p ## 5, PINT ## p ## 6, PINT ## p ## 7,
+
+#define INTC_PINT_V_NONE
+#define INTC_PINT_V(p, vect) \
+ vect(PINT ## p ## 0, 0), vect(PINT ## p ## 1, 1), \
+ vect(PINT ## p ## 2, 2), vect(PINT ## p ## 3, 3), \
+ vect(PINT ## p ## 4, 4), vect(PINT ## p ## 5, 5), \
+ vect(PINT ## p ## 6, 6), vect(PINT ## p ## 7, 7),
+
+#define INTC_PINT(p, mask_reg, sense_base, str, \
+ enums_1, enums_2, enums_3, enums_4, \
+ vect_1, vect_2, vect_3, vect_4, \
+ mask_a, mask_b, mask_c, mask_d, \
+ sense_a, sense_b, sense_c, sense_d) \
+ \
+enum { \
+ PINT ## p ## _UNUSED = 0, \
+ enums_1 enums_2 enums_3 enums_4 \
+}; \
+ \
+static struct intc_vect p ## _vectors[] __initdata = { \
+ vect_1 vect_2 vect_3 vect_4 \
+}; \
+ \
+static struct intc_mask_reg p ## _mask_registers[] __initdata = { \
+ { mask_reg, 0, 32, /* PINTER */ \
+ { mask_a mask_b mask_c mask_d } } \
+}; \
+ \
+static struct intc_sense_reg p ## _sense_registers[] __initdata = { \
+ { sense_base + 0x00, 16, 2, /* PINTCR */ \
+ { sense_a } }, \
+ { sense_base + 0x04, 16, 2, /* PINTCR */ \
+ { sense_b } }, \
+ { sense_base + 0x08, 16, 2, /* PINTCR */ \
+ { sense_c } }, \
+ { sense_base + 0x0c, 16, 2, /* PINTCR */ \
+ { sense_d } }, \
+}; \
+ \
+static struct intc_desc p ## _desc __initdata = { \
+ .name = str, \
+ .hw = INTC_HW_DESC(p ## _vectors, NULL, \
+ p ## _mask_registers, NULL, \
+ p ## _sense_registers, NULL), \
+}
+
+/* INTCS */
+#define INTCS_VECT_BASE 0x3400
+#define INTCS_VECT(n, vect) INTC_VECT((n), INTCS_VECT_BASE + (vect))
+#define intcs_evt2irq(evt) evt2irq(INTCS_VECT_BASE + (evt))
+
+#endif /* __ASM_MACH_INTC_H */
diff --git a/arch/arm/mach-shmobile/irqs.h b/arch/arm/mach-shmobile/irqs.h
new file mode 100644
index 000000000..3070f6d88
--- /dev/null
+++ b/arch/arm/mach-shmobile/irqs.h
@@ -0,0 +1,15 @@
+#ifndef __SHMOBILE_IRQS_H
+#define __SHMOBILE_IRQS_H
+
+#include "include/mach/irqs.h"
+
+/* GIC */
+#define gic_spi(nr) ((nr) + 32)
+#define gic_iid(nr) (nr) /* ICCIAR / interrupt ID */
+
+/* GPIO IRQ */
+#define _GPIO_IRQ_BASE 2500
+#define GPIO_IRQ_BASE(x) (_GPIO_IRQ_BASE + (32 * x))
+#define GPIO_IRQ(x, y) (_GPIO_IRQ_BASE + (32 * x) + y)
+
+#endif /* __SHMOBILE_IRQS_H */
diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c
new file mode 100644
index 000000000..f483b560b
--- /dev/null
+++ b/arch/arm/mach-shmobile/platsmp-apmu.c
@@ -0,0 +1,238 @@
+/*
+ * SMP support for SoCs with APMU
+ *
+ * Copyright (C) 2014 Renesas Electronics Corporation
+ * Copyright (C) 2013 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/cpu_pm.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/of_address.h>
+#include <linux/smp.h>
+#include <linux/suspend.h>
+#include <linux/threads.h>
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+#include <asm/proc-fns.h>
+#include <asm/smp_plat.h>
+#include <asm/suspend.h>
+#include "common.h"
+#include "platsmp-apmu.h"
+
+static struct {
+ void __iomem *iomem;
+ int bit;
+} apmu_cpus[NR_CPUS];
+
+#define WUPCR_OFFS 0x10
+#define PSTR_OFFS 0x40
+#define CPUNCR_OFFS(n) (0x100 + (0x10 * (n)))
+
+static int __maybe_unused apmu_power_on(void __iomem *p, int bit)
+{
+ /* request power on */
+ writel_relaxed(BIT(bit), p + WUPCR_OFFS);
+
+ /* wait for APMU to finish */
+ while (readl_relaxed(p + WUPCR_OFFS) != 0)
+ ;
+
+ return 0;
+}
+
+static int apmu_power_off(void __iomem *p, int bit)
+{
+ /* request Core Standby for next WFI */
+ writel_relaxed(3, p + CPUNCR_OFFS(bit));
+ return 0;
+}
+
+static int __maybe_unused apmu_power_off_poll(void __iomem *p, int bit)
+{
+ int k;
+
+ for (k = 0; k < 1000; k++) {
+ if (((readl_relaxed(p + PSTR_OFFS) >> (bit * 4)) & 0x03) == 3)
+ return 1;
+
+ mdelay(1);
+ }
+
+ return 0;
+}
+
+static int apmu_wrap(int cpu, int (*fn)(void __iomem *p, int cpu))
+{
+ void __iomem *p = apmu_cpus[cpu].iomem;
+
+ return p ? fn(p, apmu_cpus[cpu].bit) : -EINVAL;
+}
+
+static void apmu_init_cpu(struct resource *res, int cpu, int bit)
+{
+ if ((cpu >= ARRAY_SIZE(apmu_cpus)) || apmu_cpus[cpu].iomem)
+ return;
+
+ apmu_cpus[cpu].iomem = ioremap_nocache(res->start, resource_size(res));
+ apmu_cpus[cpu].bit = bit;
+
+ pr_debug("apmu ioremap %d %d %pr\n", cpu, bit, res);
+}
+
+static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit),
+ struct rcar_apmu_config *apmu_config, int num)
+{
+ u32 id;
+ int k;
+ int bit, index;
+ bool is_allowed;
+
+ for (k = 0; k < num; k++) {
+ /* only enable the cluster that includes the boot CPU */
+ is_allowed = false;
+ for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) {
+ id = apmu_config[k].cpus[bit];
+ if (id >= 0) {
+ if (id == cpu_logical_map(0))
+ is_allowed = true;
+ }
+ }
+ if (!is_allowed)
+ continue;
+
+ for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) {
+ id = apmu_config[k].cpus[bit];
+ if (id >= 0) {
+ index = get_logical_index(id);
+ if (index >= 0)
+ fn(&apmu_config[k].iomem, index, bit);
+ }
+ }
+ }
+}
+
+void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
+ struct rcar_apmu_config *apmu_config,
+ int num)
+{
+ /* install boot code shared by all CPUs */
+ shmobile_boot_fn = virt_to_phys(shmobile_smp_boot);
+ shmobile_boot_arg = MPIDR_HWID_BITMASK;
+
+ /* perform per-cpu setup */
+ apmu_parse_cfg(apmu_init_cpu, apmu_config, num);
+}
+
+#ifdef CONFIG_SMP
+int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ /* For this particular CPU register boot vector */
+ shmobile_smp_hook(cpu, virt_to_phys(shmobile_invalidate_start), 0);
+
+ return apmu_wrap(cpu, apmu_power_on);
+}
+#endif
+
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_SUSPEND)
+/* nicked from arch/arm/mach-exynos/hotplug.c */
+static inline void cpu_enter_lowpower_a15(void)
+{
+ unsigned int v;
+
+ asm volatile(
+ " mrc p15, 0, %0, c1, c0, 0\n"
+ " bic %0, %0, %1\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ : "=&r" (v)
+ : "Ir" (CR_C)
+ : "cc");
+
+ flush_cache_louis();
+
+ asm volatile(
+ /*
+ * Turn off coherency
+ */
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " bic %0, %0, %1\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ : "=&r" (v)
+ : "Ir" (0x40)
+ : "cc");
+
+ isb();
+ dsb();
+}
+
+void shmobile_smp_apmu_cpu_shutdown(unsigned int cpu)
+{
+
+ /* Select next sleep mode using the APMU */
+ apmu_wrap(cpu, apmu_power_off);
+
+ /* Do ARM specific CPU shutdown */
+ cpu_enter_lowpower_a15();
+}
+
+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");
+}
+#endif
+
+#if defined(CONFIG_HOTPLUG_CPU)
+void shmobile_smp_apmu_cpu_die(unsigned int cpu)
+{
+ /* For this particular CPU deregister boot vector */
+ shmobile_smp_hook(cpu, 0, 0);
+
+ /* Shutdown CPU core */
+ shmobile_smp_apmu_cpu_shutdown(cpu);
+
+ /* jump to shared mach-shmobile sleep / reset code */
+ shmobile_smp_sleep();
+}
+
+int shmobile_smp_apmu_cpu_kill(unsigned int cpu)
+{
+ return apmu_wrap(cpu, apmu_power_off_poll);
+}
+#endif
+
+#if defined(CONFIG_SUSPEND)
+static int shmobile_smp_apmu_do_suspend(unsigned long cpu)
+{
+ shmobile_smp_hook(cpu, virt_to_phys(cpu_resume), 0);
+ shmobile_smp_apmu_cpu_shutdown(cpu);
+ cpu_do_idle(); /* WFI selects Core Standby */
+ return 1;
+}
+
+static int shmobile_smp_apmu_enter_suspend(suspend_state_t state)
+{
+ cpu_suspend(smp_processor_id(), shmobile_smp_apmu_do_suspend);
+ cpu_leave_lowpower();
+ return 0;
+}
+
+void __init shmobile_smp_apmu_suspend_init(void)
+{
+ shmobile_suspend_ops.enter = shmobile_smp_apmu_enter_suspend;
+}
+#endif
diff --git a/arch/arm/mach-shmobile/platsmp-apmu.h b/arch/arm/mach-shmobile/platsmp-apmu.h
new file mode 100644
index 000000000..76512c9a2
--- /dev/null
+++ b/arch/arm/mach-shmobile/platsmp-apmu.h
@@ -0,0 +1,32 @@
+/*
+ * rmobile apmu definition
+ *
+ * Copyright (C) 2014 Renesas Electronics Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 PLATSMP_APMU_H
+#define PLATSMP_APMU_H
+
+struct rcar_apmu_config {
+ struct resource iomem;
+ int cpus[4];
+};
+
+extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
+ struct rcar_apmu_config *apmu_config,
+ int num);
+extern int shmobile_smp_apmu_boot_secondary(unsigned int cpu,
+ struct task_struct *idle);
+extern void shmobile_smp_apmu_cpu_die(unsigned int cpu);
+extern int shmobile_smp_apmu_cpu_kill(unsigned int cpu);
+
+#endif /* PLATSMP_APMU_H */
diff --git a/arch/arm/mach-shmobile/platsmp-scu.c b/arch/arm/mach-shmobile/platsmp-scu.c
new file mode 100644
index 000000000..64663110a
--- /dev/null
+++ b/arch/arm/mach-shmobile/platsmp-scu.c
@@ -0,0 +1,97 @@
+/*
+ * SMP support for SoCs with SCU covered by mach-shmobile
+ *
+ * Copyright (C) 2013 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/cpu.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/smp.h>
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+#include "common.h"
+
+static int shmobile_smp_scu_notifier_call(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (long)hcpu;
+
+ switch (action) {
+ case CPU_UP_PREPARE:
+ /* For this particular CPU register SCU SMP boot vector */
+ shmobile_smp_hook(cpu, virt_to_phys(shmobile_boot_scu),
+ (unsigned long)shmobile_scu_base);
+ break;
+ };
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block shmobile_smp_scu_notifier = {
+ .notifier_call = shmobile_smp_scu_notifier_call,
+};
+
+void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus)
+{
+ /* install boot code shared by all CPUs */
+ shmobile_boot_fn = virt_to_phys(shmobile_smp_boot);
+ shmobile_boot_arg = MPIDR_HWID_BITMASK;
+
+ /* enable SCU and cache coherency on booting CPU */
+ scu_enable(shmobile_scu_base);
+ scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL);
+
+ /* Use CPU notifier for reset vector control */
+ register_cpu_notifier(&shmobile_smp_scu_notifier);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+void shmobile_smp_scu_cpu_die(unsigned int cpu)
+{
+ /* For this particular CPU deregister boot vector */
+ shmobile_smp_hook(cpu, 0, 0);
+
+ dsb();
+ flush_cache_all();
+
+ /* disable cache coherency */
+ scu_power_mode(shmobile_scu_base, SCU_PM_POWEROFF);
+
+ /* jump to shared mach-shmobile sleep / reset code */
+ shmobile_smp_sleep();
+}
+
+static int shmobile_smp_scu_psr_core_disabled(int cpu)
+{
+ unsigned long mask = SCU_PM_POWEROFF << (cpu * 8);
+
+ if ((__raw_readl(shmobile_scu_base + 8) & mask) == mask)
+ return 1;
+
+ return 0;
+}
+
+int shmobile_smp_scu_cpu_kill(unsigned int cpu)
+{
+ int k;
+
+ /* this function is running on another CPU than the offline target,
+ * here we need wait for shutdown code in platform_cpu_die() to
+ * finish before asking SoC-specific code to power off the CPU core.
+ */
+ for (k = 0; k < 1000; k++) {
+ if (shmobile_smp_scu_psr_core_disabled(cpu))
+ return 1;
+
+ mdelay(1);
+ }
+
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
new file mode 100644
index 000000000..3923e09e9
--- /dev/null
+++ b/arch/arm/mach-shmobile/platsmp.c
@@ -0,0 +1,38 @@
+/*
+ * 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 <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include "common.h"
+
+extern unsigned long shmobile_smp_fn[];
+extern unsigned long shmobile_smp_arg[];
+extern unsigned long shmobile_smp_mpidr[];
+
+void shmobile_smp_hook(unsigned int cpu, unsigned long fn, unsigned long arg)
+{
+ shmobile_smp_fn[cpu] = 0;
+ flush_cache_all();
+
+ shmobile_smp_mpidr[cpu] = cpu_logical_map(cpu);
+ shmobile_smp_fn[cpu] = fn;
+ shmobile_smp_arg[cpu] = arg;
+ flush_cache_all();
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+int shmobile_smp_cpu_disable(unsigned int cpu)
+{
+ return 0; /* Hotplug of any CPU is supported */
+}
+#endif
diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c
new file mode 100644
index 000000000..34608fcf0
--- /dev/null
+++ b/arch/arm/mach-shmobile/pm-r8a7740.c
@@ -0,0 +1,129 @@
+/*
+ * r8a7740 power management support
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@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.
+ */
+#include <linux/console.h>
+#include <linux/io.h>
+#include <linux/suspend.h>
+
+#include "common.h"
+#include "pm-rmobile.h"
+
+#define SYSC_BASE IOMEM(0xe6180000)
+
+#if defined(CONFIG_PM) && !defined(CONFIG_ARCH_MULTIPLATFORM)
+static int r8a7740_pd_a3sm_suspend(void)
+{
+ /*
+ * The A3SM domain contains the CPU core and therefore it should
+ * only be turned off if the CPU is not in use.
+ */
+ return -EBUSY;
+}
+
+static int r8a7740_pd_a3sp_suspend(void)
+{
+ /*
+ * Serial consoles make use of SCIF hardware located in A3SP,
+ * keep such power domain on if "no_console_suspend" is set.
+ */
+ return console_suspend_enabled ? 0 : -EBUSY;
+}
+
+static int r8a7740_pd_d4_suspend(void)
+{
+ /*
+ * The D4 domain contains the Coresight-ETM hardware block and
+ * therefore it should only be turned off if the debug module is
+ * not in use.
+ */
+ return -EBUSY;
+}
+
+static struct rmobile_pm_domain r8a7740_pm_domains[] = {
+ {
+ .genpd.name = "A4LC",
+ .base = SYSC_BASE,
+ .bit_shift = 1,
+ }, {
+ .genpd.name = "A4MP",
+ .base = SYSC_BASE,
+ .bit_shift = 2,
+ }, {
+ .genpd.name = "D4",
+ .base = SYSC_BASE,
+ .bit_shift = 3,
+ .gov = &pm_domain_always_on_gov,
+ .suspend = r8a7740_pd_d4_suspend,
+ }, {
+ .genpd.name = "A4R",
+ .base = SYSC_BASE,
+ .bit_shift = 5,
+ }, {
+ .genpd.name = "A3RV",
+ .base = SYSC_BASE,
+ .bit_shift = 6,
+ }, {
+ .genpd.name = "A4S",
+ .base = SYSC_BASE,
+ .bit_shift = 10,
+ .no_debug = true,
+ }, {
+ .genpd.name = "A3SP",
+ .base = SYSC_BASE,
+ .bit_shift = 11,
+ .gov = &pm_domain_always_on_gov,
+ .no_debug = true,
+ .suspend = r8a7740_pd_a3sp_suspend,
+ }, {
+ .genpd.name = "A3SM",
+ .base = SYSC_BASE,
+ .bit_shift = 12,
+ .gov = &pm_domain_always_on_gov,
+ .suspend = r8a7740_pd_a3sm_suspend,
+ }, {
+ .genpd.name = "A3SG",
+ .base = SYSC_BASE,
+ .bit_shift = 13,
+ }, {
+ .genpd.name = "A4SU",
+ .base = SYSC_BASE,
+ .bit_shift = 20,
+ },
+};
+
+void __init r8a7740_init_pm_domains(void)
+{
+ rmobile_init_domains(r8a7740_pm_domains, ARRAY_SIZE(r8a7740_pm_domains));
+ pm_genpd_add_subdomain_names("A4R", "A3RV");
+ pm_genpd_add_subdomain_names("A4S", "A3SP");
+ pm_genpd_add_subdomain_names("A4S", "A3SM");
+ pm_genpd_add_subdomain_names("A4S", "A3SG");
+}
+#endif /* CONFIG_PM && !CONFIG_ARCH_MULTIPLATFORM */
+
+#ifdef CONFIG_SUSPEND
+static int r8a7740_enter_suspend(suspend_state_t suspend_state)
+{
+ cpu_do_idle();
+ return 0;
+}
+
+static void r8a7740_suspend_init(void)
+{
+ shmobile_suspend_ops.enter = r8a7740_enter_suspend;
+}
+#else
+static void r8a7740_suspend_init(void) {}
+#endif
+
+void __init r8a7740_pm_init(void)
+{
+ r8a7740_suspend_init();
+}
diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c
new file mode 100644
index 000000000..44a74c4c5
--- /dev/null
+++ b/arch/arm/mach-shmobile/pm-r8a7779.c
@@ -0,0 +1,143 @@
+/*
+ * r8a7779 Power management support
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * 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/err.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_domain.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/console.h>
+
+#include <asm/io.h>
+
+#include "common.h"
+#include "pm-rcar.h"
+#include "r8a7779.h"
+
+/* SYSC */
+#define SYSCIER 0x0c
+#define SYSCIMR 0x10
+
+struct r8a7779_pm_domain {
+ struct generic_pm_domain genpd;
+ struct rcar_sysc_ch ch;
+};
+
+static inline struct rcar_sysc_ch *to_r8a7779_ch(struct generic_pm_domain *d)
+{
+ return &container_of(d, struct r8a7779_pm_domain, genpd)->ch;
+}
+
+#if defined(CONFIG_PM) || defined(CONFIG_SMP)
+
+static void __init r8a7779_sysc_init(void)
+{
+ void __iomem *base = rcar_sysc_init(0xffd85000);
+
+ /* enable all interrupt sources, but do not use interrupt handler */
+ iowrite32(0x0131000e, base + SYSCIER);
+ iowrite32(0, base + SYSCIMR);
+}
+
+#else /* CONFIG_PM || CONFIG_SMP */
+
+static inline void r8a7779_sysc_init(void) {}
+
+#endif /* CONFIG_PM || CONFIG_SMP */
+
+#ifdef CONFIG_PM
+
+static int pd_power_down(struct generic_pm_domain *genpd)
+{
+ return rcar_sysc_power_down(to_r8a7779_ch(genpd));
+}
+
+static int pd_power_up(struct generic_pm_domain *genpd)
+{
+ return rcar_sysc_power_up(to_r8a7779_ch(genpd));
+}
+
+static bool pd_is_off(struct generic_pm_domain *genpd)
+{
+ return rcar_sysc_power_is_off(to_r8a7779_ch(genpd));
+}
+
+static bool pd_active_wakeup(struct device *dev)
+{
+ return true;
+}
+
+static void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd)
+{
+ struct generic_pm_domain *genpd = &r8a7779_pd->genpd;
+
+ genpd->flags = GENPD_FLAG_PM_CLK;
+ pm_genpd_init(genpd, NULL, false);
+ genpd->dev_ops.active_wakeup = pd_active_wakeup;
+ genpd->power_off = pd_power_down;
+ genpd->power_on = pd_power_up;
+
+ if (pd_is_off(&r8a7779_pd->genpd))
+ pd_power_up(&r8a7779_pd->genpd);
+}
+
+static struct r8a7779_pm_domain r8a7779_pm_domains[] = {
+ {
+ .genpd.name = "SH4A",
+ .ch = {
+ .chan_offs = 0x80, /* PWRSR1 .. PWRER1 */
+ .isr_bit = 16, /* SH4A */
+ },
+ },
+ {
+ .genpd.name = "SGX",
+ .ch = {
+ .chan_offs = 0xc0, /* PWRSR2 .. PWRER2 */
+ .isr_bit = 20, /* SGX */
+ },
+ },
+ {
+ .genpd.name = "VDP1",
+ .ch = {
+ .chan_offs = 0x100, /* PWRSR3 .. PWRER3 */
+ .isr_bit = 21, /* VDP */
+ },
+ },
+ {
+ .genpd.name = "IMPX3",
+ .ch = {
+ .chan_offs = 0x140, /* PWRSR4 .. PWRER4 */
+ .isr_bit = 24, /* IMP */
+ },
+ },
+};
+
+void __init r8a7779_init_pm_domains(void)
+{
+ int j;
+
+ for (j = 0; j < ARRAY_SIZE(r8a7779_pm_domains); j++)
+ r8a7779_init_pm_domain(&r8a7779_pm_domains[j]);
+}
+
+#endif /* CONFIG_PM */
+
+void __init r8a7779_pm_init(void)
+{
+ static int once;
+
+ if (!once++)
+ r8a7779_sysc_init();
+}
diff --git a/arch/arm/mach-shmobile/pm-rcar-gen2.c b/arch/arm/mach-shmobile/pm-rcar-gen2.c
new file mode 100644
index 000000000..6815781ad
--- /dev/null
+++ b/arch/arm/mach-shmobile/pm-rcar-gen2.c
@@ -0,0 +1,115 @@
+/*
+ * R-Car Generation 2 Power management support
+ *
+ * Copyright (C) 2013 - 2015 Renesas Electronics Corporation
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * 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/kernel.h>
+#include <linux/of.h>
+#include <linux/smp.h>
+#include <asm/io.h>
+#include "common.h"
+#include "pm-rcar.h"
+#include "rcar-gen2.h"
+
+/* RST */
+#define RST 0xe6160000
+#define CA15BAR 0x0020
+#define CA7BAR 0x0030
+#define CA15RESCNT 0x0040
+#define CA7RESCNT 0x0044
+
+/* On-chip RAM */
+#define MERAM 0xe8080000
+#define RAM 0xe6300000
+
+/* SYSC */
+#define SYSCIER 0x0c
+#define SYSCIMR 0x10
+
+#if defined(CONFIG_SMP)
+
+static void __init rcar_gen2_sysc_init(u32 syscier)
+{
+ void __iomem *base = rcar_sysc_init(0xe6180000);
+
+ /* enable all interrupt sources, but do not use interrupt handler */
+ iowrite32(syscier, base + SYSCIER);
+ iowrite32(0, base + SYSCIMR);
+}
+
+#else /* CONFIG_SMP */
+
+static inline void rcar_gen2_sysc_init(u32 syscier) {}
+
+#endif /* CONFIG_SMP */
+
+void __init rcar_gen2_pm_init(void)
+{
+ void __iomem *p;
+ u32 bar;
+ static int once;
+ struct device_node *np, *cpus;
+ bool has_a7 = false;
+ bool has_a15 = false;
+ phys_addr_t boot_vector_addr = 0;
+ u32 syscier = 0;
+
+ if (once++)
+ return;
+
+ cpus = of_find_node_by_path("/cpus");
+ if (!cpus)
+ return;
+
+ for_each_child_of_node(cpus, np) {
+ if (of_device_is_compatible(np, "arm,cortex-a15"))
+ has_a15 = true;
+ else if (of_device_is_compatible(np, "arm,cortex-a7"))
+ has_a7 = true;
+ }
+
+ if (of_machine_is_compatible("renesas,r8a7790")) {
+ boot_vector_addr = MERAM;
+ syscier = 0x013111ef;
+
+ } else if (of_machine_is_compatible("renesas,r8a7791")) {
+ boot_vector_addr = RAM;
+ syscier = 0x00111003;
+ }
+
+ /* RAM for jump stub, because BAR requires 256KB aligned address */
+ p = ioremap_nocache(boot_vector_addr, shmobile_boot_size);
+ memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size);
+ iounmap(p);
+
+ /* setup reset vectors */
+ p = ioremap_nocache(RST, 0x63);
+ bar = (boot_vector_addr >> 8) & 0xfffffc00;
+ if (has_a15) {
+ writel_relaxed(bar, p + CA15BAR);
+ writel_relaxed(bar | 0x10, p + CA15BAR);
+
+ /* de-assert reset for CA15 CPUs */
+ writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) |
+ 0xa5a50000, p + CA15RESCNT);
+ }
+ if (has_a7) {
+ writel_relaxed(bar, p + CA7BAR);
+ writel_relaxed(bar | 0x10, p + CA7BAR);
+
+ /* de-assert reset for CA7 CPUs */
+ writel_relaxed((readl_relaxed(p + CA7RESCNT) & ~0x0f) |
+ 0x5a5a0000, p + CA7RESCNT);
+ }
+ iounmap(p);
+
+ rcar_gen2_sysc_init(syscier);
+ shmobile_smp_apmu_suspend_init();
+}
diff --git a/arch/arm/mach-shmobile/pm-rcar.c b/arch/arm/mach-shmobile/pm-rcar.c
new file mode 100644
index 000000000..00022ee56
--- /dev/null
+++ b/arch/arm/mach-shmobile/pm-rcar.c
@@ -0,0 +1,137 @@
+/*
+ * R-Car SYSC Power management support
+ *
+ * Copyright (C) 2014 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/delay.h>
+#include <linux/err.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <asm/io.h>
+#include "pm-rcar.h"
+
+/* SYSC */
+#define SYSCSR 0x00
+#define SYSCISR 0x04
+#define SYSCISCR 0x08
+
+#define PWRSR_OFFS 0x00
+#define PWROFFCR_OFFS 0x04
+#define PWRONCR_OFFS 0x0c
+#define PWRER_OFFS 0x14
+
+#define SYSCSR_RETRIES 100
+#define SYSCSR_DELAY_US 1
+
+#define SYSCISR_RETRIES 1000
+#define SYSCISR_DELAY_US 1
+
+static void __iomem *rcar_sysc_base;
+static DEFINE_SPINLOCK(rcar_sysc_lock); /* SMP CPUs + I/O devices */
+
+static int rcar_sysc_pwr_on_off(struct rcar_sysc_ch *sysc_ch,
+ int sr_bit, int reg_offs)
+{
+ int k;
+
+ for (k = 0; k < SYSCSR_RETRIES; k++) {
+ if (ioread32(rcar_sysc_base + SYSCSR) & (1 << sr_bit))
+ break;
+ udelay(SYSCSR_DELAY_US);
+ }
+
+ if (k == SYSCSR_RETRIES)
+ return -EAGAIN;
+
+ iowrite32(1 << sysc_ch->chan_bit,
+ rcar_sysc_base + sysc_ch->chan_offs + reg_offs);
+
+ return 0;
+}
+
+static int rcar_sysc_pwr_off(struct rcar_sysc_ch *sysc_ch)
+{
+ return rcar_sysc_pwr_on_off(sysc_ch, 0, PWROFFCR_OFFS);
+}
+
+static int rcar_sysc_pwr_on(struct rcar_sysc_ch *sysc_ch)
+{
+ return rcar_sysc_pwr_on_off(sysc_ch, 1, PWRONCR_OFFS);
+}
+
+static int rcar_sysc_update(struct rcar_sysc_ch *sysc_ch,
+ int (*on_off_fn)(struct rcar_sysc_ch *))
+{
+ unsigned int isr_mask = 1 << sysc_ch->isr_bit;
+ unsigned int chan_mask = 1 << sysc_ch->chan_bit;
+ unsigned int status;
+ unsigned long flags;
+ int ret = 0;
+ int k;
+
+ spin_lock_irqsave(&rcar_sysc_lock, flags);
+
+ iowrite32(isr_mask, rcar_sysc_base + SYSCISCR);
+
+ do {
+ ret = on_off_fn(sysc_ch);
+ if (ret)
+ goto out;
+
+ status = ioread32(rcar_sysc_base +
+ sysc_ch->chan_offs + PWRER_OFFS);
+ } while (status & chan_mask);
+
+ for (k = 0; k < SYSCISR_RETRIES; k++) {
+ if (ioread32(rcar_sysc_base + SYSCISR) & isr_mask)
+ break;
+ udelay(SYSCISR_DELAY_US);
+ }
+
+ if (k == SYSCISR_RETRIES)
+ ret = -EIO;
+
+ iowrite32(isr_mask, rcar_sysc_base + SYSCISCR);
+
+ out:
+ spin_unlock_irqrestore(&rcar_sysc_lock, flags);
+
+ pr_debug("sysc power domain %d: %08x -> %d\n",
+ sysc_ch->isr_bit, ioread32(rcar_sysc_base + SYSCISR), ret);
+ return ret;
+}
+
+int rcar_sysc_power_down(struct rcar_sysc_ch *sysc_ch)
+{
+ return rcar_sysc_update(sysc_ch, rcar_sysc_pwr_off);
+}
+
+int rcar_sysc_power_up(struct rcar_sysc_ch *sysc_ch)
+{
+ return rcar_sysc_update(sysc_ch, rcar_sysc_pwr_on);
+}
+
+bool rcar_sysc_power_is_off(struct rcar_sysc_ch *sysc_ch)
+{
+ unsigned int st;
+
+ st = ioread32(rcar_sysc_base + sysc_ch->chan_offs + PWRSR_OFFS);
+ if (st & (1 << sysc_ch->chan_bit))
+ return true;
+
+ return false;
+}
+
+void __iomem *rcar_sysc_init(phys_addr_t base)
+{
+ rcar_sysc_base = ioremap_nocache(base, PAGE_SIZE);
+ if (!rcar_sysc_base)
+ panic("unable to ioremap R-Car SYSC hardware block\n");
+
+ return rcar_sysc_base;
+}
diff --git a/arch/arm/mach-shmobile/pm-rcar.h b/arch/arm/mach-shmobile/pm-rcar.h
new file mode 100644
index 000000000..ef3a1ef62
--- /dev/null
+++ b/arch/arm/mach-shmobile/pm-rcar.h
@@ -0,0 +1,15 @@
+#ifndef PM_RCAR_H
+#define PM_RCAR_H
+
+struct rcar_sysc_ch {
+ unsigned long chan_offs;
+ unsigned int chan_bit;
+ unsigned int isr_bit;
+};
+
+int rcar_sysc_power_down(struct rcar_sysc_ch *sysc_ch);
+int rcar_sysc_power_up(struct rcar_sysc_ch *sysc_ch);
+bool rcar_sysc_power_is_off(struct rcar_sysc_ch *sysc_ch);
+void __iomem *rcar_sysc_init(phys_addr_t base);
+
+#endif /* PM_RCAR_H */
diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c
new file mode 100644
index 000000000..95018209f
--- /dev/null
+++ b/arch/arm/mach-shmobile/pm-rmobile.c
@@ -0,0 +1,434 @@
+/*
+ * rmobile power management support
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ * Copyright (C) 2014 Glider bvba
+ *
+ * based on pm-sh7372.c
+ * 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/console.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_clock.h>
+#include <linux/slab.h>
+
+#include <asm/io.h>
+
+#include "pm-rmobile.h"
+
+/* SYSC */
+#define SPDCR 0x08 /* SYS Power Down Control Register */
+#define SWUCR 0x14 /* SYS Wakeup Control Register */
+#define PSTR 0x80 /* Power Status Register */
+
+#define PSTR_RETRIES 100
+#define PSTR_DELAY_US 10
+
+static int rmobile_pd_power_down(struct generic_pm_domain *genpd)
+{
+ struct rmobile_pm_domain *rmobile_pd = to_rmobile_pd(genpd);
+ unsigned int mask;
+
+ if (rmobile_pd->bit_shift == ~0)
+ return -EBUSY;
+
+ mask = 1 << rmobile_pd->bit_shift;
+ if (rmobile_pd->suspend) {
+ int ret = rmobile_pd->suspend();
+
+ if (ret)
+ return ret;
+ }
+
+ if (__raw_readl(rmobile_pd->base + PSTR) & mask) {
+ unsigned int retry_count;
+ __raw_writel(mask, rmobile_pd->base + SPDCR);
+
+ for (retry_count = PSTR_RETRIES; retry_count; retry_count--) {
+ if (!(__raw_readl(rmobile_pd->base + SPDCR) & mask))
+ break;
+ cpu_relax();
+ }
+ }
+
+ if (!rmobile_pd->no_debug)
+ pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n",
+ genpd->name, mask,
+ __raw_readl(rmobile_pd->base + PSTR));
+
+ return 0;
+}
+
+static int __rmobile_pd_power_up(struct rmobile_pm_domain *rmobile_pd,
+ bool do_resume)
+{
+ unsigned int mask;
+ unsigned int retry_count;
+ int ret = 0;
+
+ if (rmobile_pd->bit_shift == ~0)
+ return 0;
+
+ mask = 1 << rmobile_pd->bit_shift;
+ if (__raw_readl(rmobile_pd->base + PSTR) & mask)
+ goto out;
+
+ __raw_writel(mask, rmobile_pd->base + SWUCR);
+
+ for (retry_count = 2 * PSTR_RETRIES; retry_count; retry_count--) {
+ if (!(__raw_readl(rmobile_pd->base + SWUCR) & mask))
+ break;
+ if (retry_count > PSTR_RETRIES)
+ udelay(PSTR_DELAY_US);
+ else
+ cpu_relax();
+ }
+ if (!retry_count)
+ ret = -EIO;
+
+ if (!rmobile_pd->no_debug)
+ pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n",
+ rmobile_pd->genpd.name, mask,
+ __raw_readl(rmobile_pd->base + PSTR));
+
+out:
+ if (ret == 0 && rmobile_pd->resume && do_resume)
+ rmobile_pd->resume();
+
+ return ret;
+}
+
+static int rmobile_pd_power_up(struct generic_pm_domain *genpd)
+{
+ return __rmobile_pd_power_up(to_rmobile_pd(genpd), true);
+}
+
+static bool rmobile_pd_active_wakeup(struct device *dev)
+{
+ return true;
+}
+
+static int rmobile_pd_attach_dev(struct generic_pm_domain *domain,
+ struct device *dev)
+{
+ int error;
+
+ error = pm_clk_create(dev);
+ if (error) {
+ dev_err(dev, "pm_clk_create failed %d\n", error);
+ return error;
+ }
+
+ error = pm_clk_add(dev, NULL);
+ if (error) {
+ dev_err(dev, "pm_clk_add failed %d\n", error);
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ pm_clk_destroy(dev);
+ return error;
+}
+
+static void rmobile_pd_detach_dev(struct generic_pm_domain *domain,
+ struct device *dev)
+{
+ pm_clk_destroy(dev);
+}
+
+static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
+{
+ struct generic_pm_domain *genpd = &rmobile_pd->genpd;
+ struct dev_power_governor *gov = rmobile_pd->gov;
+
+ genpd->flags = GENPD_FLAG_PM_CLK;
+ pm_genpd_init(genpd, gov ? : &simple_qos_governor, false);
+ genpd->dev_ops.active_wakeup = rmobile_pd_active_wakeup;
+ genpd->power_off = rmobile_pd_power_down;
+ genpd->power_on = rmobile_pd_power_up;
+ genpd->attach_dev = rmobile_pd_attach_dev;
+ genpd->detach_dev = rmobile_pd_detach_dev;
+ __rmobile_pd_power_up(rmobile_pd, false);
+}
+
+#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
+
+void rmobile_init_domains(struct rmobile_pm_domain domains[], int num)
+{
+ int j;
+
+ for (j = 0; j < num; j++)
+ rmobile_init_pm_domain(&domains[j]);
+}
+
+void rmobile_add_device_to_domain_td(const char *domain_name,
+ struct platform_device *pdev,
+ struct gpd_timing_data *td)
+{
+ struct device *dev = &pdev->dev;
+
+ __pm_genpd_name_add_device(domain_name, dev, td);
+}
+
+void rmobile_add_devices_to_domains(struct pm_domain_device data[],
+ int size)
+{
+ struct gpd_timing_data latencies = {
+ .stop_latency_ns = DEFAULT_DEV_LATENCY_NS,
+ .start_latency_ns = DEFAULT_DEV_LATENCY_NS,
+ .save_state_latency_ns = DEFAULT_DEV_LATENCY_NS,
+ .restore_state_latency_ns = DEFAULT_DEV_LATENCY_NS,
+ };
+ int j;
+
+ for (j = 0; j < size; j++)
+ rmobile_add_device_to_domain_td(data[j].domain_name,
+ data[j].pdev, &latencies);
+}
+
+#else /* !CONFIG_ARCH_SHMOBILE_LEGACY */
+
+static int rmobile_pd_suspend_busy(void)
+{
+ /*
+ * This domain should not be turned off.
+ */
+ return -EBUSY;
+}
+
+static int rmobile_pd_suspend_console(void)
+{
+ /*
+ * Serial consoles make use of SCIF hardware located in this domain,
+ * hence keep the power domain on if "no_console_suspend" is set.
+ */
+ return console_suspend_enabled ? 0 : -EBUSY;
+}
+
+enum pd_types {
+ PD_NORMAL,
+ PD_CPU,
+ PD_CONSOLE,
+ PD_DEBUG,
+ PD_MEMCTL,
+};
+
+#define MAX_NUM_SPECIAL_PDS 16
+
+static struct special_pd {
+ struct device_node *pd;
+ enum pd_types type;
+} special_pds[MAX_NUM_SPECIAL_PDS] __initdata;
+
+static unsigned int num_special_pds __initdata;
+
+static const struct of_device_id special_ids[] __initconst = {
+ { .compatible = "arm,coresight-etm3x", .data = (void *)PD_DEBUG },
+ { .compatible = "renesas,dbsc-r8a73a4", .data = (void *)PD_MEMCTL, },
+ { .compatible = "renesas,dbsc3-r8a7740", .data = (void *)PD_MEMCTL, },
+ { .compatible = "renesas,sbsc-sh73a0", .data = (void *)PD_MEMCTL, },
+ { /* sentinel */ },
+};
+
+static void __init add_special_pd(struct device_node *np, enum pd_types type)
+{
+ unsigned int i;
+ struct device_node *pd;
+
+ pd = of_parse_phandle(np, "power-domains", 0);
+ if (!pd)
+ return;
+
+ for (i = 0; i < num_special_pds; i++)
+ if (pd == special_pds[i].pd && type == special_pds[i].type) {
+ of_node_put(pd);
+ return;
+ }
+
+ if (num_special_pds == ARRAY_SIZE(special_pds)) {
+ pr_warn("Too many special PM domains\n");
+ of_node_put(pd);
+ return;
+ }
+
+ pr_debug("Special PM domain %s type %d for %s\n", pd->name, type,
+ np->full_name);
+
+ special_pds[num_special_pds].pd = pd;
+ special_pds[num_special_pds].type = type;
+ num_special_pds++;
+}
+
+static void __init get_special_pds(void)
+{
+ struct device_node *np;
+ const struct of_device_id *id;
+
+ /* PM domains containing CPUs */
+ for_each_node_by_type(np, "cpu")
+ add_special_pd(np, PD_CPU);
+
+ /* PM domain containing console */
+ if (of_stdout)
+ add_special_pd(of_stdout, PD_CONSOLE);
+
+ /* PM domains containing other special devices */
+ for_each_matching_node_and_match(np, special_ids, &id)
+ add_special_pd(np, (enum pd_types)id->data);
+}
+
+static void __init put_special_pds(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_special_pds; i++)
+ of_node_put(special_pds[i].pd);
+}
+
+static enum pd_types __init pd_type(const struct device_node *pd)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_special_pds; i++)
+ if (pd == special_pds[i].pd)
+ return special_pds[i].type;
+
+ return PD_NORMAL;
+}
+
+static void __init rmobile_setup_pm_domain(struct device_node *np,
+ struct rmobile_pm_domain *pd)
+{
+ const char *name = pd->genpd.name;
+
+ switch (pd_type(np)) {
+ case PD_CPU:
+ /*
+ * This domain contains the CPU core and therefore it should
+ * only be turned off if the CPU is not in use.
+ */
+ pr_debug("PM domain %s contains CPU\n", name);
+ pd->gov = &pm_domain_always_on_gov;
+ pd->suspend = rmobile_pd_suspend_busy;
+ break;
+
+ case PD_CONSOLE:
+ pr_debug("PM domain %s contains serial console\n", name);
+ pd->gov = &pm_domain_always_on_gov;
+ pd->suspend = rmobile_pd_suspend_console;
+ break;
+
+ case PD_DEBUG:
+ /*
+ * This domain contains the Coresight-ETM hardware block and
+ * therefore it should only be turned off if the debug module
+ * is not in use.
+ */
+ pr_debug("PM domain %s contains Coresight-ETM\n", name);
+ pd->gov = &pm_domain_always_on_gov;
+ pd->suspend = rmobile_pd_suspend_busy;
+ break;
+
+ case PD_MEMCTL:
+ /*
+ * This domain contains a memory-controller and therefore it
+ * should only be turned off if memory is not in use.
+ */
+ pr_debug("PM domain %s contains MEMCTL\n", name);
+ pd->gov = &pm_domain_always_on_gov;
+ pd->suspend = rmobile_pd_suspend_busy;
+ break;
+
+ case PD_NORMAL:
+ break;
+ }
+
+ rmobile_init_pm_domain(pd);
+}
+
+static int __init rmobile_add_pm_domains(void __iomem *base,
+ struct device_node *parent,
+ struct generic_pm_domain *genpd_parent)
+{
+ struct device_node *np;
+
+ for_each_child_of_node(parent, np) {
+ struct rmobile_pm_domain *pd;
+ u32 idx = ~0;
+
+ if (of_property_read_u32(np, "reg", &idx)) {
+ /* always-on domain */
+ }
+
+ pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+ if (!pd)
+ return -ENOMEM;
+
+ pd->genpd.name = np->name;
+ pd->base = base;
+ pd->bit_shift = idx;
+
+ rmobile_setup_pm_domain(np, pd);
+ if (genpd_parent)
+ pm_genpd_add_subdomain(genpd_parent, &pd->genpd);
+ of_genpd_add_provider_simple(np, &pd->genpd);
+
+ rmobile_add_pm_domains(base, np, &pd->genpd);
+ }
+ return 0;
+}
+
+static int __init rmobile_init_pm_domains(void)
+{
+ struct device_node *np, *pmd;
+ bool scanned = false;
+ void __iomem *base;
+ int ret = 0;
+
+ for_each_compatible_node(np, NULL, "renesas,sysc-rmobile") {
+ base = of_iomap(np, 0);
+ if (!base) {
+ pr_warn("%s cannot map reg 0\n", np->full_name);
+ continue;
+ }
+
+ pmd = of_get_child_by_name(np, "pm-domains");
+ if (!pmd) {
+ pr_warn("%s lacks pm-domains node\n", np->full_name);
+ continue;
+ }
+
+ if (!scanned) {
+ /* Find PM domains containing special blocks */
+ get_special_pds();
+ scanned = true;
+ }
+
+ ret = rmobile_add_pm_domains(base, pmd, NULL);
+ of_node_put(pmd);
+ if (ret) {
+ of_node_put(np);
+ break;
+ }
+ }
+
+ put_special_pds();
+
+ return ret;
+}
+
+core_initcall(rmobile_init_pm_domains);
+
+#endif /* !CONFIG_ARCH_SHMOBILE_LEGACY */
diff --git a/arch/arm/mach-shmobile/pm-rmobile.h b/arch/arm/mach-shmobile/pm-rmobile.h
new file mode 100644
index 000000000..53219786f
--- /dev/null
+++ b/arch/arm/mach-shmobile/pm-rmobile.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2012 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 PM_RMOBILE_H
+#define PM_RMOBILE_H
+
+#include <linux/pm_domain.h>
+
+#define DEFAULT_DEV_LATENCY_NS 250000
+
+struct platform_device;
+
+struct rmobile_pm_domain {
+ struct generic_pm_domain genpd;
+ struct dev_power_governor *gov;
+ int (*suspend)(void);
+ void (*resume)(void);
+ void __iomem *base;
+ unsigned int bit_shift;
+ bool no_debug;
+};
+
+static inline
+struct rmobile_pm_domain *to_rmobile_pd(struct generic_pm_domain *d)
+{
+ return container_of(d, struct rmobile_pm_domain, genpd);
+}
+
+struct pm_domain_device {
+ const char *domain_name;
+ struct platform_device *pdev;
+};
+
+#if defined(CONFIG_PM_RMOBILE) && defined(CONFIG_ARCH_SHMOBILE_LEGACY)
+extern void rmobile_init_domains(struct rmobile_pm_domain domains[], int num);
+extern void rmobile_add_device_to_domain_td(const char *domain_name,
+ struct platform_device *pdev,
+ struct gpd_timing_data *td);
+
+static inline void rmobile_add_device_to_domain(const char *domain_name,
+ struct platform_device *pdev)
+{
+ rmobile_add_device_to_domain_td(domain_name, pdev, NULL);
+}
+
+extern void rmobile_add_devices_to_domains(struct pm_domain_device data[],
+ int size);
+#else
+
+#define rmobile_init_domains(domains, num) do { } while (0)
+#define rmobile_add_device_to_domain_td(name, pdev, td) do { } while (0)
+#define rmobile_add_device_to_domain(name, pdev) do { } while (0)
+
+static inline void rmobile_add_devices_to_domains(struct pm_domain_device d[],
+ int size) {}
+#endif /* CONFIG_PM_RMOBILE */
+
+#endif /* PM_RMOBILE_H */
diff --git a/arch/arm/mach-shmobile/pm-sh73a0.c b/arch/arm/mach-shmobile/pm-sh73a0.c
new file mode 100644
index 000000000..a7e466817
--- /dev/null
+++ b/arch/arm/mach-shmobile/pm-sh73a0.c
@@ -0,0 +1,32 @@
+/*
+ * sh73a0 Power management support
+ *
+ * Copyright (C) 2012 Bastian Hecht <hechtb+renesas@gmail.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/suspend.h>
+#include "common.h"
+
+#ifdef CONFIG_SUSPEND
+static int sh73a0_enter_suspend(suspend_state_t suspend_state)
+{
+ cpu_do_idle();
+ return 0;
+}
+
+static void sh73a0_suspend_init(void)
+{
+ shmobile_suspend_ops.enter = sh73a0_enter_suspend;
+}
+#else
+static void sh73a0_suspend_init(void) {}
+#endif
+
+void __init sh73a0_pm_init(void)
+{
+ sh73a0_suspend_init();
+}
diff --git a/arch/arm/mach-shmobile/r8a7740.h b/arch/arm/mach-shmobile/r8a7740.h
new file mode 100644
index 000000000..ca7805ad7
--- /dev/null
+++ b/arch/arm/mach-shmobile/r8a7740.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@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.
+ */
+
+#ifndef __ASM_R8A7740_H__
+#define __ASM_R8A7740_H__
+
+/*
+ * MD_CKx pin
+ */
+#define MD_CK2 (1 << 2)
+#define MD_CK1 (1 << 1)
+#define MD_CK0 (1 << 0)
+
+/* DMA slave IDs */
+enum {
+ SHDMA_SLAVE_INVALID,
+ 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_FSIA_RX,
+ SHDMA_SLAVE_FSIA_TX,
+ SHDMA_SLAVE_FSIB_TX,
+ SHDMA_SLAVE_USBHS_TX,
+ SHDMA_SLAVE_USBHS_RX,
+ SHDMA_SLAVE_MMCIF_TX,
+ SHDMA_SLAVE_MMCIF_RX,
+};
+
+extern void r8a7740_meram_workaround(void);
+extern void r8a7740_init_irq_of(void);
+extern void r8a7740_map_io(void);
+extern void r8a7740_add_early_devices(void);
+extern void r8a7740_add_standard_devices(void);
+extern void r8a7740_clock_init(u8 md_ck);
+extern void r8a7740_pinmux_init(void);
+extern void r8a7740_pm_init(void);
+
+#if defined(CONFIG_PM) && !defined(CONFIG_ARCH_MULTIPLATFORM)
+extern void __init r8a7740_init_pm_domains(void);
+#else
+static inline void r8a7740_init_pm_domains(void) {}
+#endif /* CONFIG_PM && !CONFIG_ARCH_MULTIPLATFORM */
+
+#endif /* __ASM_R8A7740_H__ */
diff --git a/arch/arm/mach-shmobile/r8a7778.h b/arch/arm/mach-shmobile/r8a7778.h
new file mode 100644
index 000000000..f64fedb1f
--- /dev/null
+++ b/arch/arm/mach-shmobile/r8a7778.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ * Copyright (C) 2013 Cogent Embedded, 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; 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.
+ */
+#ifndef __ASM_R8A7778_H__
+#define __ASM_R8A7778_H__
+
+#include <linux/sh_eth.h>
+
+/* HPB-DMA slave IDs */
+enum {
+ HPBDMA_SLAVE_DUMMY,
+ HPBDMA_SLAVE_SDHI0_TX,
+ HPBDMA_SLAVE_SDHI0_RX,
+ HPBDMA_SLAVE_SSI0_TX,
+ HPBDMA_SLAVE_SSI0_RX,
+ HPBDMA_SLAVE_SSI1_TX,
+ HPBDMA_SLAVE_SSI1_RX,
+ HPBDMA_SLAVE_SSI2_TX,
+ HPBDMA_SLAVE_SSI2_RX,
+ HPBDMA_SLAVE_SSI3_TX,
+ HPBDMA_SLAVE_SSI3_RX,
+ HPBDMA_SLAVE_SSI4_TX,
+ HPBDMA_SLAVE_SSI4_RX,
+ HPBDMA_SLAVE_SSI5_TX,
+ HPBDMA_SLAVE_SSI5_RX,
+ HPBDMA_SLAVE_SSI6_TX,
+ HPBDMA_SLAVE_SSI6_RX,
+ HPBDMA_SLAVE_SSI7_TX,
+ HPBDMA_SLAVE_SSI7_RX,
+ HPBDMA_SLAVE_SSI8_TX,
+ HPBDMA_SLAVE_SSI8_RX,
+ HPBDMA_SLAVE_HPBIF0_TX,
+ HPBDMA_SLAVE_HPBIF0_RX,
+ HPBDMA_SLAVE_HPBIF1_TX,
+ HPBDMA_SLAVE_HPBIF1_RX,
+ HPBDMA_SLAVE_HPBIF2_TX,
+ HPBDMA_SLAVE_HPBIF2_RX,
+ HPBDMA_SLAVE_HPBIF3_TX,
+ HPBDMA_SLAVE_HPBIF3_RX,
+ HPBDMA_SLAVE_HPBIF4_TX,
+ HPBDMA_SLAVE_HPBIF4_RX,
+ HPBDMA_SLAVE_HPBIF5_TX,
+ HPBDMA_SLAVE_HPBIF5_RX,
+ HPBDMA_SLAVE_HPBIF6_TX,
+ HPBDMA_SLAVE_HPBIF6_RX,
+ HPBDMA_SLAVE_HPBIF7_TX,
+ HPBDMA_SLAVE_HPBIF7_RX,
+ HPBDMA_SLAVE_HPBIF8_TX,
+ HPBDMA_SLAVE_HPBIF8_RX,
+ HPBDMA_SLAVE_USBFUNC_TX,
+ HPBDMA_SLAVE_USBFUNC_RX,
+};
+
+extern void r8a7778_add_standard_devices(void);
+extern void r8a7778_add_standard_devices_dt(void);
+extern void r8a7778_add_dt_devices(void);
+
+extern void r8a7778_init_late(void);
+extern void r8a7778_init_irq_dt(void);
+extern void r8a7778_clock_init(void);
+extern void r8a7778_init_irq_extpin(int irlm);
+extern void r8a7778_init_irq_extpin_dt(int irlm);
+extern void r8a7778_pinmux_init(void);
+
+extern int r8a7778_usb_phy_power(bool enable);
+
+#endif /* __ASM_R8A7778_H__ */
diff --git a/arch/arm/mach-shmobile/r8a7779.h b/arch/arm/mach-shmobile/r8a7779.h
new file mode 100644
index 000000000..19f97046d
--- /dev/null
+++ b/arch/arm/mach-shmobile/r8a7779.h
@@ -0,0 +1,35 @@
+#ifndef __ASM_R8A7779_H__
+#define __ASM_R8A7779_H__
+
+#include <linux/sh_clk.h>
+
+/* HPB-DMA slave IDs */
+enum {
+ HPBDMA_SLAVE_DUMMY,
+ HPBDMA_SLAVE_SDHI0_TX,
+ HPBDMA_SLAVE_SDHI0_RX,
+};
+
+extern void r8a7779_init_irq_extpin(int irlm);
+extern void r8a7779_init_irq_extpin_dt(int irlm);
+extern void r8a7779_init_irq_dt(void);
+extern void r8a7779_map_io(void);
+extern void r8a7779_earlytimer_init(void);
+extern void r8a7779_add_early_devices(void);
+extern void r8a7779_add_standard_devices(void);
+extern void r8a7779_init_late(void);
+extern u32 r8a7779_read_mode_pins(void);
+extern void r8a7779_clock_init(void);
+extern void r8a7779_pinmux_init(void);
+extern void r8a7779_pm_init(void);
+extern void r8a7779_register_twd(void);
+
+#ifdef CONFIG_PM
+extern void __init r8a7779_init_pm_domains(void);
+#else
+static inline void r8a7779_init_pm_domains(void) {}
+#endif /* CONFIG_PM */
+
+extern struct smp_operations r8a7779_smp_ops;
+
+#endif /* __ASM_R8A7779_H__ */
diff --git a/arch/arm/mach-shmobile/r8a7790.h b/arch/arm/mach-shmobile/r8a7790.h
new file mode 100644
index 000000000..1a46d0260
--- /dev/null
+++ b/arch/arm/mach-shmobile/r8a7790.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_R8A7790_H__
+#define __ASM_R8A7790_H__
+
+extern struct smp_operations r8a7790_smp_ops;
+
+#endif /* __ASM_R8A7790_H__ */
diff --git a/arch/arm/mach-shmobile/r8a7791.h b/arch/arm/mach-shmobile/r8a7791.h
new file mode 100644
index 000000000..7ca0b7d0f
--- /dev/null
+++ b/arch/arm/mach-shmobile/r8a7791.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_R8A7791_H__
+#define __ASM_R8A7791_H__
+
+extern struct smp_operations r8a7791_smp_ops;
+
+#endif /* __ASM_R8A7791_H__ */
diff --git a/arch/arm/mach-shmobile/rcar-gen2.h b/arch/arm/mach-shmobile/rcar-gen2.h
new file mode 100644
index 000000000..8a66b4aae
--- /dev/null
+++ b/arch/arm/mach-shmobile/rcar-gen2.h
@@ -0,0 +1,10 @@
+#ifndef __ASM_RCAR_GEN2_H__
+#define __ASM_RCAR_GEN2_H__
+
+void rcar_gen2_timer_init(void);
+#define MD(nr) BIT(nr)
+u32 rcar_gen2_read_mode_pins(void);
+void rcar_gen2_reserve(void);
+void rcar_gen2_pm_init(void);
+
+#endif /* __ASM_RCAR_GEN2_H__ */
diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
new file mode 100644
index 000000000..384e6e934
--- /dev/null
+++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
@@ -0,0 +1,147 @@
+/*
+ * R-Car Generation 2 da9063/da9210 regulator quirk
+ *
+ * The r8a7790/lager and r8a7791/koelsch development boards have da9063 and
+ * da9210 regulators. Both regulators have their interrupt request lines tied
+ * to the same interrupt pin (IRQ2) on the SoC.
+ *
+ * After cold boot or da9063-induced restart, both the da9063 and da9210 seem
+ * to assert their interrupt request lines. Hence as soon as one driver
+ * requests this irq, it gets stuck in an interrupt storm, as it only manages
+ * to deassert its own interrupt request line, and the other driver hasn't
+ * installed an interrupt handler yet.
+ *
+ * To handle this, install a quirk that masks the interrupts in both the
+ * da9063 and da9210. This quirk has to run after the i2c master driver has
+ * been initialized, but before the i2c slave drivers are initialized.
+ *
+ * Copyright (C) 2015 Glider bvba
+ *
+ * This program is free software; 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/device.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/notifier.h>
+#include <linux/of.h>
+#include <linux/mfd/da9063/registers.h>
+
+
+#define IRQC_BASE 0xe61c0000
+#define IRQC_MONITOR 0x104 /* IRQn Signal Level Monitor Register */
+
+#define REGULATOR_IRQ_MASK BIT(2) /* IRQ2, active low */
+
+static void __iomem *irqc;
+
+static const u8 da9063_mask_regs[] = {
+ DA9063_REG_IRQ_MASK_A,
+ DA9063_REG_IRQ_MASK_B,
+ DA9063_REG_IRQ_MASK_C,
+ DA9063_REG_IRQ_MASK_D,
+};
+
+/* DA9210 System Control and Event Registers */
+#define DA9210_REG_MASK_A 0x54
+#define DA9210_REG_MASK_B 0x55
+
+static const u8 da9210_mask_regs[] = {
+ DA9210_REG_MASK_A,
+ DA9210_REG_MASK_B,
+};
+
+static void da9xxx_mask_irqs(struct i2c_client *client, const u8 regs[],
+ unsigned int nregs)
+{
+ unsigned int i;
+
+ dev_info(&client->dev, "Masking %s interrupt sources\n", client->name);
+
+ for (i = 0; i < nregs; i++) {
+ int error = i2c_smbus_write_byte_data(client, regs[i], ~0);
+ if (error) {
+ dev_err(&client->dev, "i2c error %d\n", error);
+ return;
+ }
+ }
+}
+
+static int regulator_quirk_notify(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct device *dev = data;
+ struct i2c_client *client;
+ u32 mon;
+
+ mon = ioread32(irqc + IRQC_MONITOR);
+ dev_dbg(dev, "%s: %ld, IRQC_MONITOR = 0x%x\n", __func__, action, mon);
+ if (mon & REGULATOR_IRQ_MASK)
+ goto remove;
+
+ if (action != BUS_NOTIFY_ADD_DEVICE || dev->type == &i2c_adapter_type)
+ return 0;
+
+ client = to_i2c_client(dev);
+ dev_dbg(dev, "Detected %s\n", client->name);
+
+ if ((client->addr == 0x58 && !strcmp(client->name, "da9063")))
+ da9xxx_mask_irqs(client, da9063_mask_regs,
+ ARRAY_SIZE(da9063_mask_regs));
+ else if (client->addr == 0x68 && !strcmp(client->name, "da9210"))
+ da9xxx_mask_irqs(client, da9210_mask_regs,
+ ARRAY_SIZE(da9210_mask_regs));
+
+ mon = ioread32(irqc + IRQC_MONITOR);
+ if (mon & REGULATOR_IRQ_MASK)
+ goto remove;
+
+ return 0;
+
+remove:
+ dev_info(dev, "IRQ2 is not asserted, removing quirk\n");
+
+ bus_unregister_notifier(&i2c_bus_type, nb);
+ iounmap(irqc);
+ return 0;
+}
+
+static struct notifier_block regulator_quirk_nb = {
+ .notifier_call = regulator_quirk_notify
+};
+
+static int __init rcar_gen2_regulator_quirk(void)
+{
+ u32 mon;
+
+ if (!of_machine_is_compatible("renesas,koelsch") &&
+ !of_machine_is_compatible("renesas,lager"))
+ return -ENODEV;
+
+ irqc = ioremap(IRQC_BASE, PAGE_SIZE);
+ if (!irqc)
+ return -ENOMEM;
+
+ mon = ioread32(irqc + IRQC_MONITOR);
+ if (mon & REGULATOR_IRQ_MASK) {
+ pr_debug("%s: IRQ2 is not asserted, not installing quirk\n",
+ __func__);
+ iounmap(irqc);
+ return 0;
+ }
+
+ pr_info("IRQ2 is asserted, installing da9063/da9210 regulator quirk\n");
+
+ bus_register_notifier(&i2c_bus_type, &regulator_quirk_nb);
+ return 0;
+}
+
+arch_initcall(rcar_gen2_regulator_quirk);
diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c
new file mode 100644
index 000000000..37f7b15c0
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-emev2.c
@@ -0,0 +1,53 @@
+/*
+ * Emma Mobile EV2 processor support
+ *
+ * Copyright (C) 2012 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include "common.h"
+
+static struct map_desc emev2_io_desc[] __initdata = {
+#ifdef CONFIG_SMP
+ /* 2M mapping for SCU + L2 controller */
+ {
+ .virtual = 0xf0000000,
+ .pfn = __phys_to_pfn(0x1e000000),
+ .length = SZ_2M,
+ .type = MT_DEVICE
+ },
+#endif
+};
+
+static void __init emev2_map_io(void)
+{
+ iotable_init(emev2_io_desc, ARRAY_SIZE(emev2_io_desc));
+}
+
+static const char *const emev2_boards_compat_dt[] __initconst = {
+ "renesas,emev2",
+ NULL,
+};
+
+extern struct smp_operations emev2_smp_ops;
+
+DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)")
+ .smp = smp_ops(emev2_smp_ops),
+ .map_io = emev2_map_io,
+ .init_early = shmobile_init_delay,
+ .init_late = shmobile_init_late,
+ .dt_compat = emev2_boards_compat_dt,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/setup-r7s72100.c b/arch/arm/mach-shmobile/setup-r7s72100.c
new file mode 100644
index 000000000..171174777
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-r7s72100.c
@@ -0,0 +1,32 @@
+/*
+ * r7s72100 processor support
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 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.
+ */
+
+#include <linux/kernel.h>
+
+#include <asm/mach/arch.h>
+
+#include "common.h"
+
+static const char *r7s72100_boards_compat_dt[] __initdata = {
+ "renesas,r7s72100",
+ NULL,
+};
+
+DT_MACHINE_START(R7S72100_DT, "Generic R7S72100 (Flattened Device Tree)")
+ .init_early = shmobile_init_delay,
+ .init_late = shmobile_init_late,
+ .dt_compat = r7s72100_boards_compat_dt,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/setup-r8a73a4.c b/arch/arm/mach-shmobile/setup-r8a73a4.c
new file mode 100644
index 000000000..446cee611
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-r8a73a4.c
@@ -0,0 +1,32 @@
+/*
+ * r8a73a4 processor support
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 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.
+ */
+
+#include <linux/init.h>
+
+#include <asm/mach/arch.h>
+
+#include "common.h"
+
+static const char *r8a73a4_boards_compat_dt[] __initdata = {
+ "renesas,r8a73a4",
+ NULL,
+};
+
+DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)")
+ .init_early = shmobile_init_delay,
+ .init_late = shmobile_init_late,
+ .dt_compat = r8a73a4_boards_compat_dt,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
new file mode 100644
index 000000000..9832e4839
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -0,0 +1,859 @@
+/*
+ * R8A7740 processor support
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@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.
+ */
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/platform_data/irq-renesas-intc-irqpin.h>
+#include <linux/platform_device.h>
+#include <linux/of_platform.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_dma.h>
+#include <linux/sh_timer.h>
+#include <linux/platform_data/sh_ipmmu.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "common.h"
+#include "dma-register.h"
+#include "irqs.h"
+#include "pm-rmobile.h"
+#include "r8a7740.h"
+
+static struct map_desc r8a7740_io_desc[] __initdata = {
+ /*
+ * for CPGA/INTC/PFC
+ * 0xe6000000-0xefffffff -> 0xe6000000-0xefffffff
+ */
+ {
+ .virtual = 0xe6000000,
+ .pfn = __phys_to_pfn(0xe6000000),
+ .length = 160 << 20,
+ .type = MT_DEVICE_NONSHARED
+ },
+#ifdef CONFIG_CACHE_L2X0
+ /*
+ * for l2x0_init()
+ * 0xf0100000-0xf0101000 -> 0xf0002000-0xf0003000
+ */
+ {
+ .virtual = 0xf0002000,
+ .pfn = __phys_to_pfn(0xf0100000),
+ .length = PAGE_SIZE,
+ .type = MT_DEVICE_NONSHARED
+ },
+#endif
+};
+
+void __init r8a7740_map_io(void)
+{
+ debug_ll_io_init();
+ iotable_init(r8a7740_io_desc, ARRAY_SIZE(r8a7740_io_desc));
+}
+
+/* PFC */
+static const struct resource pfc_resources[] = {
+ DEFINE_RES_MEM(0xe6050000, 0x8000),
+ DEFINE_RES_MEM(0xe605800c, 0x0020),
+};
+
+void __init r8a7740_pinmux_init(void)
+{
+ platform_device_register_simple("pfc-r8a7740", -1, pfc_resources,
+ ARRAY_SIZE(pfc_resources));
+}
+
+static struct renesas_intc_irqpin_config irqpin0_platform_data = {
+ .irq_base = irq_pin(0), /* IRQ0 -> IRQ7 */
+};
+
+static struct resource irqpin0_resources[] = {
+ DEFINE_RES_MEM(0xe6900000, 4), /* ICR1A */
+ DEFINE_RES_MEM(0xe6900010, 4), /* INTPRI00A */
+ DEFINE_RES_MEM(0xe6900020, 1), /* INTREQ00A */
+ DEFINE_RES_MEM(0xe6900040, 1), /* INTMSK00A */
+ DEFINE_RES_MEM(0xe6900060, 1), /* INTMSKCLR00A */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ0 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ1 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ2 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ3 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ4 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ5 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ6 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ7 */
+};
+
+static struct platform_device irqpin0_device = {
+ .name = "renesas_intc_irqpin",
+ .id = 0,
+ .resource = irqpin0_resources,
+ .num_resources = ARRAY_SIZE(irqpin0_resources),
+ .dev = {
+ .platform_data = &irqpin0_platform_data,
+ },
+};
+
+static struct renesas_intc_irqpin_config irqpin1_platform_data = {
+ .irq_base = irq_pin(8), /* IRQ8 -> IRQ15 */
+};
+
+static struct resource irqpin1_resources[] = {
+ DEFINE_RES_MEM(0xe6900004, 4), /* ICR2A */
+ DEFINE_RES_MEM(0xe6900014, 4), /* INTPRI10A */
+ DEFINE_RES_MEM(0xe6900024, 1), /* INTREQ10A */
+ DEFINE_RES_MEM(0xe6900044, 1), /* INTMSK10A */
+ DEFINE_RES_MEM(0xe6900064, 1), /* INTMSKCLR10A */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ8 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ9 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ10 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ11 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ12 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ13 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ14 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ15 */
+};
+
+static struct platform_device irqpin1_device = {
+ .name = "renesas_intc_irqpin",
+ .id = 1,
+ .resource = irqpin1_resources,
+ .num_resources = ARRAY_SIZE(irqpin1_resources),
+ .dev = {
+ .platform_data = &irqpin1_platform_data,
+ },
+};
+
+static struct renesas_intc_irqpin_config irqpin2_platform_data = {
+ .irq_base = irq_pin(16), /* IRQ16 -> IRQ23 */
+};
+
+static struct resource irqpin2_resources[] = {
+ DEFINE_RES_MEM(0xe6900008, 4), /* ICR3A */
+ DEFINE_RES_MEM(0xe6900018, 4), /* INTPRI30A */
+ DEFINE_RES_MEM(0xe6900028, 1), /* INTREQ30A */
+ DEFINE_RES_MEM(0xe6900048, 1), /* INTMSK30A */
+ DEFINE_RES_MEM(0xe6900068, 1), /* INTMSKCLR30A */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ16 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ17 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ18 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ19 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ20 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ21 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ22 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ23 */
+};
+
+static struct platform_device irqpin2_device = {
+ .name = "renesas_intc_irqpin",
+ .id = 2,
+ .resource = irqpin2_resources,
+ .num_resources = ARRAY_SIZE(irqpin2_resources),
+ .dev = {
+ .platform_data = &irqpin2_platform_data,
+ },
+};
+
+static struct renesas_intc_irqpin_config irqpin3_platform_data = {
+ .irq_base = irq_pin(24), /* IRQ24 -> IRQ31 */
+};
+
+static struct resource irqpin3_resources[] = {
+ DEFINE_RES_MEM(0xe690000c, 4), /* ICR3A */
+ DEFINE_RES_MEM(0xe690001c, 4), /* INTPRI30A */
+ DEFINE_RES_MEM(0xe690002c, 1), /* INTREQ30A */
+ DEFINE_RES_MEM(0xe690004c, 1), /* INTMSK30A */
+ DEFINE_RES_MEM(0xe690006c, 1), /* INTMSKCLR30A */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ24 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ25 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ26 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ27 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ28 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ29 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ30 */
+ DEFINE_RES_IRQ(gic_spi(149)), /* IRQ31 */
+};
+
+static struct platform_device irqpin3_device = {
+ .name = "renesas_intc_irqpin",
+ .id = 3,
+ .resource = irqpin3_resources,
+ .num_resources = ARRAY_SIZE(irqpin3_resources),
+ .dev = {
+ .platform_data = &irqpin3_platform_data,
+ },
+};
+
+/* SCIF */
+#define R8A7740_SCIF(scif_type, index, baseaddr, irq) \
+static struct plat_sci_port scif##index##_platform_data = { \
+ .type = scif_type, \
+ .flags = UPF_BOOT_AUTOCONF, \
+ .scscr = SCSCR_RE | SCSCR_TE, \
+}; \
+ \
+static struct resource scif##index##_resources[] = { \
+ DEFINE_RES_MEM(baseaddr, 0x100), \
+ DEFINE_RES_IRQ(irq), \
+}; \
+ \
+static struct platform_device scif##index##_device = { \
+ .name = "sh-sci", \
+ .id = index, \
+ .resource = scif##index##_resources, \
+ .num_resources = ARRAY_SIZE(scif##index##_resources), \
+ .dev = { \
+ .platform_data = &scif##index##_platform_data, \
+ }, \
+}
+
+R8A7740_SCIF(PORT_SCIFA, 0, 0xe6c40000, gic_spi(100));
+R8A7740_SCIF(PORT_SCIFA, 1, 0xe6c50000, gic_spi(101));
+R8A7740_SCIF(PORT_SCIFA, 2, 0xe6c60000, gic_spi(102));
+R8A7740_SCIF(PORT_SCIFA, 3, 0xe6c70000, gic_spi(103));
+R8A7740_SCIF(PORT_SCIFA, 4, 0xe6c80000, gic_spi(104));
+R8A7740_SCIF(PORT_SCIFA, 5, 0xe6cb0000, gic_spi(105));
+R8A7740_SCIF(PORT_SCIFA, 6, 0xe6cc0000, gic_spi(106));
+R8A7740_SCIF(PORT_SCIFA, 7, 0xe6cd0000, gic_spi(107));
+R8A7740_SCIF(PORT_SCIFB, 8, 0xe6c30000, gic_spi(108));
+
+/* CMT */
+static struct sh_timer_config cmt1_platform_data = {
+ .channels_mask = 0x3f,
+};
+
+static struct resource cmt1_resources[] = {
+ DEFINE_RES_MEM(0xe6138000, 0x170),
+ DEFINE_RES_IRQ(gic_spi(58)),
+};
+
+static struct platform_device cmt1_device = {
+ .name = "sh-cmt-48",
+ .id = 1,
+ .dev = {
+ .platform_data = &cmt1_platform_data,
+ },
+ .resource = cmt1_resources,
+ .num_resources = ARRAY_SIZE(cmt1_resources),
+};
+
+/* TMU */
+static struct sh_timer_config tmu0_platform_data = {
+ .channels_mask = 7,
+};
+
+static struct resource tmu0_resources[] = {
+ DEFINE_RES_MEM(0xfff80000, 0x2c),
+ DEFINE_RES_IRQ(gic_spi(198)),
+ DEFINE_RES_IRQ(gic_spi(199)),
+ DEFINE_RES_IRQ(gic_spi(200)),
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh-tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+/* IPMMUI (an IPMMU module for ICB/LMB) */
+static struct resource ipmmu_resources[] = {
+ [0] = {
+ .name = "IPMMUI",
+ .start = 0xfe951000,
+ .end = 0xfe9510ff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static const char * const ipmmu_dev_names[] = {
+ "sh_mobile_lcdc_fb.0",
+ "sh_mobile_lcdc_fb.1",
+ "sh_mobile_ceu.0",
+};
+
+static struct shmobile_ipmmu_platform_data ipmmu_platform_data = {
+ .dev_names = ipmmu_dev_names,
+ .num_dev_names = ARRAY_SIZE(ipmmu_dev_names),
+};
+
+static struct platform_device ipmmu_device = {
+ .name = "ipmmu",
+ .id = -1,
+ .dev = {
+ .platform_data = &ipmmu_platform_data,
+ },
+ .resource = ipmmu_resources,
+ .num_resources = ARRAY_SIZE(ipmmu_resources),
+};
+
+static struct platform_device *r8a7740_early_devices[] __initdata = {
+ &scif0_device,
+ &scif1_device,
+ &scif2_device,
+ &scif3_device,
+ &scif4_device,
+ &scif5_device,
+ &scif6_device,
+ &scif7_device,
+ &scif8_device,
+ &irqpin0_device,
+ &irqpin1_device,
+ &irqpin2_device,
+ &irqpin3_device,
+ &tmu0_device,
+ &ipmmu_device,
+ &cmt1_device,
+};
+
+/* DMA */
+static const struct sh_dmae_slave_config r8a7740_dmae_slaves[] = {
+ {
+ .slave_id = SHDMA_SLAVE_SDHI0_TX,
+ .addr = 0xe6850030,
+ .chcr = CHCR_TX(XMIT_SZ_16BIT),
+ .mid_rid = 0xc1,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI0_RX,
+ .addr = 0xe6850030,
+ .chcr = CHCR_RX(XMIT_SZ_16BIT),
+ .mid_rid = 0xc2,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI1_TX,
+ .addr = 0xe6860030,
+ .chcr = CHCR_TX(XMIT_SZ_16BIT),
+ .mid_rid = 0xc9,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI1_RX,
+ .addr = 0xe6860030,
+ .chcr = CHCR_RX(XMIT_SZ_16BIT),
+ .mid_rid = 0xca,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI2_TX,
+ .addr = 0xe6870030,
+ .chcr = CHCR_TX(XMIT_SZ_16BIT),
+ .mid_rid = 0xcd,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI2_RX,
+ .addr = 0xe6870030,
+ .chcr = CHCR_RX(XMIT_SZ_16BIT),
+ .mid_rid = 0xce,
+ }, {
+ .slave_id = SHDMA_SLAVE_FSIA_TX,
+ .addr = 0xfe1f0024,
+ .chcr = CHCR_TX(XMIT_SZ_32BIT),
+ .mid_rid = 0xb1,
+ }, {
+ .slave_id = SHDMA_SLAVE_FSIA_RX,
+ .addr = 0xfe1f0020,
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
+ .mid_rid = 0xb2,
+ }, {
+ .slave_id = SHDMA_SLAVE_FSIB_TX,
+ .addr = 0xfe1f0064,
+ .chcr = CHCR_TX(XMIT_SZ_32BIT),
+ .mid_rid = 0xb5,
+ }, {
+ .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 DMA_CHANNEL(a, b, c) \
+{ \
+ .offset = a, \
+ .dmars = b, \
+ .dmars_bit = c, \
+ .chclr_offset = (0x220 - 0x20) + a \
+}
+
+static const struct sh_dmae_channel r8a7740_dmae_channels[] = {
+ DMA_CHANNEL(0x00, 0, 0),
+ DMA_CHANNEL(0x10, 0, 8),
+ DMA_CHANNEL(0x20, 4, 0),
+ DMA_CHANNEL(0x30, 4, 8),
+ DMA_CHANNEL(0x50, 8, 0),
+ DMA_CHANNEL(0x60, 8, 8),
+};
+
+static struct sh_dmae_pdata dma_platform_data = {
+ .slave = r8a7740_dmae_slaves,
+ .slave_num = ARRAY_SIZE(r8a7740_dmae_slaves),
+ .channel = r8a7740_dmae_channels,
+ .channel_num = ARRAY_SIZE(r8a7740_dmae_channels),
+ .ts_low_shift = TS_LOW_SHIFT,
+ .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT,
+ .ts_high_shift = TS_HI_SHIFT,
+ .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT,
+ .ts_shift = dma_ts_shift,
+ .ts_shift_num = ARRAY_SIZE(dma_ts_shift),
+ .dmaor_init = DMAOR_DME,
+ .chclr_present = 1,
+};
+
+/* Resource order important! */
+static struct resource r8a7740_dmae0_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xfe008020,
+ .end = 0xfe00828f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMARSx */
+ .start = 0xfe009000,
+ .end = 0xfe00900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "error_irq",
+ .start = gic_spi(34),
+ .end = gic_spi(34),
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-5 */
+ .start = gic_spi(28),
+ .end = gic_spi(33),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* Resource order important! */
+static struct resource r8a7740_dmae1_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xfe018020,
+ .end = 0xfe01828f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMARSx */
+ .start = 0xfe019000,
+ .end = 0xfe01900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "error_irq",
+ .start = gic_spi(41),
+ .end = gic_spi(41),
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-5 */
+ .start = gic_spi(35),
+ .end = gic_spi(40),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* Resource order important! */
+static struct resource r8a7740_dmae2_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xfe028020,
+ .end = 0xfe02828f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMARSx */
+ .start = 0xfe029000,
+ .end = 0xfe02900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "error_irq",
+ .start = gic_spi(48),
+ .end = gic_spi(48),
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-5 */
+ .start = gic_spi(42),
+ .end = gic_spi(47),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dma0_device = {
+ .name = "sh-dma-engine",
+ .id = 0,
+ .resource = r8a7740_dmae0_resources,
+ .num_resources = ARRAY_SIZE(r8a7740_dmae0_resources),
+ .dev = {
+ .platform_data = &dma_platform_data,
+ },
+};
+
+static struct platform_device dma1_device = {
+ .name = "sh-dma-engine",
+ .id = 1,
+ .resource = r8a7740_dmae1_resources,
+ .num_resources = ARRAY_SIZE(r8a7740_dmae1_resources),
+ .dev = {
+ .platform_data = &dma_platform_data,
+ },
+};
+
+static struct platform_device dma2_device = {
+ .name = "sh-dma-engine",
+ .id = 2,
+ .resource = r8a7740_dmae2_resources,
+ .num_resources = ARRAY_SIZE(r8a7740_dmae2_resources),
+ .dev = {
+ .platform_data = &dma_platform_data,
+ },
+};
+
+/* USB-DMAC */
+static const struct sh_dmae_channel r8a7740_usb_dma_channels[] = {
+ {
+ .offset = 0,
+ }, {
+ .offset = 0x20,
+ },
+};
+
+static const struct sh_dmae_slave_config r8a7740_usb_dma_slaves[] = {
+ {
+ .slave_id = SHDMA_SLAVE_USBHS_TX,
+ .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE),
+ }, {
+ .slave_id = SHDMA_SLAVE_USBHS_RX,
+ .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE),
+ },
+};
+
+static struct sh_dmae_pdata usb_dma_platform_data = {
+ .slave = r8a7740_usb_dma_slaves,
+ .slave_num = ARRAY_SIZE(r8a7740_usb_dma_slaves),
+ .channel = r8a7740_usb_dma_channels,
+ .channel_num = ARRAY_SIZE(r8a7740_usb_dma_channels),
+ .ts_low_shift = USBTS_LOW_SHIFT,
+ .ts_low_mask = USBTS_LOW_BIT << USBTS_LOW_SHIFT,
+ .ts_high_shift = USBTS_HI_SHIFT,
+ .ts_high_mask = USBTS_HI_BIT << USBTS_HI_SHIFT,
+ .ts_shift = dma_usbts_shift,
+ .ts_shift_num = ARRAY_SIZE(dma_usbts_shift),
+ .dmaor_init = DMAOR_DME,
+ .chcr_offset = 0x14,
+ .chcr_ie_bit = 1 << 5,
+ .dmaor_is_32bit = 1,
+ .needs_tend_set = 1,
+ .no_dmars = 1,
+ .slave_only = 1,
+};
+
+static struct resource r8a7740_usb_dma_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xe68a0020,
+ .end = 0xe68a0064 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* VCR/SWR/DMICR */
+ .start = 0xe68a0000,
+ .end = 0xe68a0014 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* IRQ for channels */
+ .start = gic_spi(49),
+ .end = gic_spi(49),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usb_dma_device = {
+ .name = "sh-dma-engine",
+ .id = 3,
+ .resource = r8a7740_usb_dma_resources,
+ .num_resources = ARRAY_SIZE(r8a7740_usb_dma_resources),
+ .dev = {
+ .platform_data = &usb_dma_platform_data,
+ },
+};
+
+/* I2C */
+static struct resource i2c0_resources[] = {
+ [0] = {
+ .name = "IIC0",
+ .start = 0xfff20000,
+ .end = 0xfff20425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(201),
+ .end = gic_spi(204),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c1_resources[] = {
+ [0] = {
+ .name = "IIC1",
+ .start = 0xe6c20000,
+ .end = 0xe6c20425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(70), /* IIC1_ALI1 */
+ .end = gic_spi(73), /* IIC1_DTEI1 */
+ .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 resource pmu_resources[] = {
+ [0] = {
+ .start = gic_spi(83),
+ .end = gic_spi(83),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pmu_device = {
+ .name = "armv7-pmu",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pmu_resources),
+ .resource = pmu_resources,
+};
+
+static struct platform_device *r8a7740_late_devices[] __initdata = {
+ &i2c0_device,
+ &i2c1_device,
+ &dma0_device,
+ &dma1_device,
+ &dma2_device,
+ &usb_dma_device,
+ &pmu_device,
+};
+
+/*
+ * r8a7740 chip has lasting errata on MERAM buffer.
+ * this is work-around for it.
+ * see
+ * "Media RAM (MERAM)" on r8a7740 documentation
+ */
+#define MEBUFCNTR 0xFE950098
+void __init r8a7740_meram_workaround(void)
+{
+ void __iomem *reg;
+
+ reg = ioremap_nocache(MEBUFCNTR, 4);
+ if (reg) {
+ iowrite32(0x01600164, reg);
+ iounmap(reg);
+ }
+}
+
+#define ICCR 0x0004
+#define ICSTART 0x0070
+
+#define i2c_read(reg, offset) ioread8(reg + offset)
+#define i2c_write(reg, offset, data) iowrite8(data, reg + offset)
+
+/*
+ * r8a7740 chip has lasting errata on I2C I/O pad reset.
+ * this is work-around for it.
+ */
+static void r8a7740_i2c_workaround(struct platform_device *pdev)
+{
+ struct resource *res;
+ void __iomem *reg;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (unlikely(!res)) {
+ pr_err("r8a7740 i2c workaround fail (cannot find resource)\n");
+ return;
+ }
+
+ reg = ioremap(res->start, resource_size(res));
+ if (unlikely(!reg)) {
+ pr_err("r8a7740 i2c workaround fail (cannot map IO)\n");
+ return;
+ }
+
+ i2c_write(reg, ICCR, i2c_read(reg, ICCR) | 0x80);
+ i2c_read(reg, ICCR); /* dummy read */
+
+ i2c_write(reg, ICSTART, i2c_read(reg, ICSTART) | 0x10);
+ i2c_read(reg, ICSTART); /* dummy read */
+
+ udelay(10);
+
+ i2c_write(reg, ICCR, 0x01);
+ i2c_write(reg, ICSTART, 0x00);
+
+ udelay(10);
+
+ i2c_write(reg, ICCR, 0x10);
+ udelay(10);
+ i2c_write(reg, ICCR, 0x00);
+ udelay(10);
+ i2c_write(reg, ICCR, 0x10);
+ udelay(10);
+
+ iounmap(reg);
+}
+
+void __init r8a7740_add_standard_devices(void)
+{
+ static struct pm_domain_device domain_devices[] __initdata = {
+ { "A4R", &tmu0_device },
+ { "A4R", &i2c0_device },
+ { "A4S", &irqpin0_device },
+ { "A4S", &irqpin1_device },
+ { "A4S", &irqpin2_device },
+ { "A4S", &irqpin3_device },
+ { "A3SP", &scif0_device },
+ { "A3SP", &scif1_device },
+ { "A3SP", &scif2_device },
+ { "A3SP", &scif3_device },
+ { "A3SP", &scif4_device },
+ { "A3SP", &scif5_device },
+ { "A3SP", &scif6_device },
+ { "A3SP", &scif7_device },
+ { "A3SP", &scif8_device },
+ { "A3SP", &i2c1_device },
+ { "A3SP", &ipmmu_device },
+ { "A3SP", &dma0_device },
+ { "A3SP", &dma1_device },
+ { "A3SP", &dma2_device },
+ { "A3SP", &usb_dma_device },
+ };
+
+ /* I2C work-around */
+ r8a7740_i2c_workaround(&i2c0_device);
+ r8a7740_i2c_workaround(&i2c1_device);
+
+ r8a7740_init_pm_domains();
+
+ /* add devices */
+ platform_add_devices(r8a7740_early_devices,
+ ARRAY_SIZE(r8a7740_early_devices));
+ platform_add_devices(r8a7740_late_devices,
+ ARRAY_SIZE(r8a7740_late_devices));
+
+ /* add devices to PM domain */
+ rmobile_add_devices_to_domains(domain_devices,
+ ARRAY_SIZE(domain_devices));
+}
+
+void __init r8a7740_add_early_devices(void)
+{
+ early_platform_add_devices(r8a7740_early_devices,
+ ARRAY_SIZE(r8a7740_early_devices));
+
+ /* setup early console here as well */
+ shmobile_setup_console();
+}
+
+#ifdef CONFIG_USE_OF
+
+void __init r8a7740_init_irq_of(void)
+{
+ void __iomem *intc_prio_base = ioremap_nocache(0xe6900010, 0x10);
+ void __iomem *intc_msk_base = ioremap_nocache(0xe6900040, 0x10);
+ void __iomem *pfc_inta_ctrl = ioremap_nocache(0xe605807c, 0x4);
+
+#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
+ void __iomem *gic_dist_base = ioremap_nocache(0xc2800000, 0x1000);
+ void __iomem *gic_cpu_base = ioremap_nocache(0xc2000000, 0x1000);
+
+ gic_init(0, 29, gic_dist_base, gic_cpu_base);
+#else
+ irqchip_init();
+#endif
+
+ /* route signals to GIC */
+ iowrite32(0x0, pfc_inta_ctrl);
+
+ /*
+ * To mask the shared interrupt to SPI 149 we must ensure to set
+ * PRIO *and* MASK. Else we run into IRQ floods when registering
+ * the intc_irqpin devices
+ */
+ iowrite32(0x0, intc_prio_base + 0x0);
+ iowrite32(0x0, intc_prio_base + 0x4);
+ iowrite32(0x0, intc_prio_base + 0x8);
+ iowrite32(0x0, intc_prio_base + 0xc);
+ iowrite8(0xff, intc_msk_base + 0x0);
+ iowrite8(0xff, intc_msk_base + 0x4);
+ iowrite8(0xff, intc_msk_base + 0x8);
+ iowrite8(0xff, intc_msk_base + 0xc);
+
+ iounmap(intc_prio_base);
+ iounmap(intc_msk_base);
+ iounmap(pfc_inta_ctrl);
+}
+
+static void __init r8a7740_generic_init(void)
+{
+ r8a7740_meram_workaround();
+
+#ifdef CONFIG_CACHE_L2X0
+ /* Shared attribute override enable, 32K*8way */
+ l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff);
+#endif
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char *r8a7740_boards_compat_dt[] __initdata = {
+ "renesas,r8a7740",
+ NULL,
+};
+
+DT_MACHINE_START(R8A7740_DT, "Generic R8A7740 (Flattened Device Tree)")
+ .map_io = r8a7740_map_io,
+ .init_early = shmobile_init_delay,
+ .init_irq = r8a7740_init_irq_of,
+ .init_machine = r8a7740_generic_init,
+ .init_late = shmobile_init_late,
+ .dt_compat = r8a7740_boards_compat_dt,
+MACHINE_END
+
+#endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c
new file mode 100644
index 000000000..c49aa094f
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-r8a7778.c
@@ -0,0 +1,633 @@
+/*
+ * r8a7778 processor support
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ * Copyright (C) 2013 Cogent Embedded, 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; 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/clk/shmobile.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_data/dma-rcar-hpbdma.h>
+#include <linux/platform_data/gpio-rcar.h>
+#include <linux/platform_data/irq-renesas-intc-irqpin.h>
+#include <linux/platform_device.h>
+#include <linux/irqchip.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
+#include <linux/pm_runtime.h>
+#include <linux/usb/phy.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/mach/arch.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "common.h"
+#include "irqs.h"
+#include "r8a7778.h"
+
+#define MODEMR 0xffcc0020
+
+#ifdef CONFIG_COMMON_CLK
+static void __init r8a7778_timer_init(void)
+{
+ u32 mode;
+ void __iomem *modemr = ioremap_nocache(MODEMR, 4);
+
+ BUG_ON(!modemr);
+ mode = ioread32(modemr);
+ iounmap(modemr);
+ r8a7778_clocks_init(mode);
+}
+#endif
+
+/* SCIF */
+#define R8A7778_SCIF(index, baseaddr, irq) \
+static struct plat_sci_port scif##index##_platform_data = { \
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \
+ .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, \
+ .type = PORT_SCIF, \
+}; \
+ \
+static struct resource scif##index##_resources[] = { \
+ DEFINE_RES_MEM(baseaddr, 0x100), \
+ DEFINE_RES_IRQ(irq), \
+}
+
+R8A7778_SCIF(0, 0xffe40000, gic_iid(0x66));
+R8A7778_SCIF(1, 0xffe41000, gic_iid(0x67));
+R8A7778_SCIF(2, 0xffe42000, gic_iid(0x68));
+R8A7778_SCIF(3, 0xffe43000, gic_iid(0x69));
+R8A7778_SCIF(4, 0xffe44000, gic_iid(0x6a));
+R8A7778_SCIF(5, 0xffe45000, gic_iid(0x6b));
+
+#define r8a7778_register_scif(index) \
+ platform_device_register_resndata(NULL, "sh-sci", index, \
+ scif##index##_resources, \
+ ARRAY_SIZE(scif##index##_resources), \
+ &scif##index##_platform_data, \
+ sizeof(scif##index##_platform_data))
+
+/* TMU */
+static struct sh_timer_config sh_tmu0_platform_data = {
+ .channels_mask = 7,
+};
+
+static struct resource sh_tmu0_resources[] = {
+ DEFINE_RES_MEM(0xffd80000, 0x30),
+ DEFINE_RES_IRQ(gic_iid(0x40)),
+ DEFINE_RES_IRQ(gic_iid(0x41)),
+ DEFINE_RES_IRQ(gic_iid(0x42)),
+};
+
+#define r8a7778_register_tmu(idx) \
+ platform_device_register_resndata( \
+ NULL, "sh-tmu", idx, \
+ sh_tmu##idx##_resources, \
+ ARRAY_SIZE(sh_tmu##idx##_resources), \
+ &sh_tmu##idx##_platform_data, \
+ sizeof(sh_tmu##idx##_platform_data))
+
+int r8a7778_usb_phy_power(bool enable)
+{
+ static struct usb_phy *phy = NULL;
+ int ret = 0;
+
+ if (!phy)
+ phy = usb_get_phy(USB_PHY_TYPE_USB2);
+
+ if (IS_ERR(phy)) {
+ pr_err("kernel doesn't have usb phy driver\n");
+ return PTR_ERR(phy);
+ }
+
+ if (enable)
+ ret = usb_phy_init(phy);
+ else
+ usb_phy_shutdown(phy);
+
+ return ret;
+}
+
+/* USB */
+static int usb_power_on(struct platform_device *pdev)
+{
+ int ret = r8a7778_usb_phy_power(true);
+
+ if (ret)
+ return ret;
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+
+ return 0;
+}
+
+static void usb_power_off(struct platform_device *pdev)
+{
+ if (r8a7778_usb_phy_power(false))
+ return;
+
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+}
+
+static int ehci_init_internal_buffer(struct usb_hcd *hcd)
+{
+ /*
+ * Below are recommended values from the datasheet;
+ * see [USB :: Setting of EHCI Internal Buffer].
+ */
+ /* EHCI IP internal buffer setting */
+ iowrite32(0x00ff0040, hcd->regs + 0x0094);
+ /* EHCI IP internal buffer enable */
+ iowrite32(0x00000001, hcd->regs + 0x009C);
+
+ return 0;
+}
+
+static struct usb_ehci_pdata ehci_pdata __initdata = {
+ .power_on = usb_power_on,
+ .power_off = usb_power_off,
+ .power_suspend = usb_power_off,
+ .pre_setup = ehci_init_internal_buffer,
+};
+
+static struct resource ehci_resources[] __initdata = {
+ DEFINE_RES_MEM(0xffe70000, 0x400),
+ DEFINE_RES_IRQ(gic_iid(0x4c)),
+};
+
+static struct usb_ohci_pdata ohci_pdata __initdata = {
+ .power_on = usb_power_on,
+ .power_off = usb_power_off,
+ .power_suspend = usb_power_off,
+};
+
+static struct resource ohci_resources[] __initdata = {
+ DEFINE_RES_MEM(0xffe70400, 0x400),
+ DEFINE_RES_IRQ(gic_iid(0x4c)),
+};
+
+#define USB_PLATFORM_INFO(hci) \
+static struct platform_device_info hci##_info __initdata = { \
+ .name = #hci "-platform", \
+ .id = -1, \
+ .res = hci##_resources, \
+ .num_res = ARRAY_SIZE(hci##_resources), \
+ .data = &hci##_pdata, \
+ .size_data = sizeof(hci##_pdata), \
+ .dma_mask = DMA_BIT_MASK(32), \
+}
+
+USB_PLATFORM_INFO(ehci);
+USB_PLATFORM_INFO(ohci);
+
+/* PFC/GPIO */
+static struct resource pfc_resources[] __initdata = {
+ DEFINE_RES_MEM(0xfffc0000, 0x118),
+};
+
+#define R8A7778_GPIO(idx) \
+static struct resource r8a7778_gpio##idx##_resources[] __initdata = { \
+ DEFINE_RES_MEM(0xffc40000 + 0x1000 * (idx), 0x30), \
+ DEFINE_RES_IRQ(gic_iid(0x87)), \
+}; \
+ \
+static struct gpio_rcar_config r8a7778_gpio##idx##_platform_data __initdata = { \
+ .gpio_base = 32 * (idx), \
+ .irq_base = GPIO_IRQ_BASE(idx), \
+ .number_of_pins = 32, \
+ .pctl_name = "pfc-r8a7778", \
+}
+
+R8A7778_GPIO(0);
+R8A7778_GPIO(1);
+R8A7778_GPIO(2);
+R8A7778_GPIO(3);
+R8A7778_GPIO(4);
+
+#define r8a7778_register_gpio(idx) \
+ platform_device_register_resndata( \
+ NULL, "gpio_rcar", idx, \
+ r8a7778_gpio##idx##_resources, \
+ ARRAY_SIZE(r8a7778_gpio##idx##_resources), \
+ &r8a7778_gpio##idx##_platform_data, \
+ sizeof(r8a7778_gpio##idx##_platform_data))
+
+void __init r8a7778_pinmux_init(void)
+{
+ platform_device_register_simple(
+ "pfc-r8a7778", -1,
+ pfc_resources,
+ ARRAY_SIZE(pfc_resources));
+
+ r8a7778_register_gpio(0);
+ r8a7778_register_gpio(1);
+ r8a7778_register_gpio(2);
+ r8a7778_register_gpio(3);
+ r8a7778_register_gpio(4);
+};
+
+/* I2C */
+static struct resource i2c_resources[] __initdata = {
+ /* I2C0 */
+ DEFINE_RES_MEM(0xffc70000, 0x1000),
+ DEFINE_RES_IRQ(gic_iid(0x63)),
+ /* I2C1 */
+ DEFINE_RES_MEM(0xffc71000, 0x1000),
+ DEFINE_RES_IRQ(gic_iid(0x6e)),
+ /* I2C2 */
+ DEFINE_RES_MEM(0xffc72000, 0x1000),
+ DEFINE_RES_IRQ(gic_iid(0x6c)),
+ /* I2C3 */
+ DEFINE_RES_MEM(0xffc73000, 0x1000),
+ DEFINE_RES_IRQ(gic_iid(0x6d)),
+};
+
+static void __init r8a7778_register_i2c(int id)
+{
+ BUG_ON(id < 0 || id > 3);
+
+ platform_device_register_simple(
+ "i2c-rcar", id,
+ i2c_resources + (2 * id), 2);
+}
+
+/* HSPI */
+static struct resource hspi_resources[] __initdata = {
+ /* HSPI0 */
+ DEFINE_RES_MEM(0xfffc7000, 0x18),
+ DEFINE_RES_IRQ(gic_iid(0x5f)),
+ /* HSPI1 */
+ DEFINE_RES_MEM(0xfffc8000, 0x18),
+ DEFINE_RES_IRQ(gic_iid(0x74)),
+ /* HSPI2 */
+ DEFINE_RES_MEM(0xfffc6000, 0x18),
+ DEFINE_RES_IRQ(gic_iid(0x75)),
+};
+
+static void __init r8a7778_register_hspi(int id)
+{
+ BUG_ON(id < 0 || id > 2);
+
+ platform_device_register_simple(
+ "sh-hspi", id,
+ hspi_resources + (2 * id), 2);
+}
+
+void __init r8a7778_add_dt_devices(void)
+{
+#ifdef CONFIG_CACHE_L2X0
+ void __iomem *base = ioremap_nocache(0xf0100000, 0x1000);
+ if (base) {
+ /*
+ * Shared attribute override enable, 64K*16way
+ * don't call iounmap(base)
+ */
+ l2x0_init(base, 0x00400000, 0xc20f0fff);
+ }
+#endif
+}
+
+/* HPB-DMA */
+
+/* Asynchronous mode register (ASYNCMDR) bits */
+#define HPB_DMAE_ASYNCMDR_ASMD22_MASK BIT(2) /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE BIT(2) /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI 0 /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD21_MASK BIT(1) /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE BIT(1) /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0 /* SDHI0 */
+
+#define HPBDMA_SSI(_id) \
+{ \
+ .id = HPBDMA_SLAVE_SSI## _id ##_TX, \
+ .addr = 0xffd91008 + (_id * 0x40), \
+ .dcr = HPB_DMAE_DCR_CT | \
+ HPB_DMAE_DCR_DIP | \
+ HPB_DMAE_DCR_SPDS_32BIT | \
+ HPB_DMAE_DCR_DMDL | \
+ HPB_DMAE_DCR_DPDS_32BIT, \
+ .port = _id + (_id << 8), \
+ .dma_ch = (28 + _id), \
+}, { \
+ .id = HPBDMA_SLAVE_SSI## _id ##_RX, \
+ .addr = 0xffd9100c + (_id * 0x40), \
+ .dcr = HPB_DMAE_DCR_CT | \
+ HPB_DMAE_DCR_DIP | \
+ HPB_DMAE_DCR_SMDL | \
+ HPB_DMAE_DCR_SPDS_32BIT | \
+ HPB_DMAE_DCR_DPDS_32BIT, \
+ .port = _id + (_id << 8), \
+ .dma_ch = (28 + _id), \
+}
+
+#define HPBDMA_HPBIF(_id) \
+{ \
+ .id = HPBDMA_SLAVE_HPBIF## _id ##_TX, \
+ .addr = 0xffda0000 + (_id * 0x1000), \
+ .dcr = HPB_DMAE_DCR_CT | \
+ HPB_DMAE_DCR_DIP | \
+ HPB_DMAE_DCR_SPDS_32BIT | \
+ HPB_DMAE_DCR_DMDL | \
+ HPB_DMAE_DCR_DPDS_32BIT, \
+ .port = 0x1111, \
+ .dma_ch = (28 + _id), \
+}, { \
+ .id = HPBDMA_SLAVE_HPBIF## _id ##_RX, \
+ .addr = 0xffda0000 + (_id * 0x1000), \
+ .dcr = HPB_DMAE_DCR_CT | \
+ HPB_DMAE_DCR_DIP | \
+ HPB_DMAE_DCR_SMDL | \
+ HPB_DMAE_DCR_SPDS_32BIT | \
+ HPB_DMAE_DCR_DPDS_32BIT, \
+ .port = 0x1111, \
+ .dma_ch = (28 + _id), \
+}
+
+static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = {
+ {
+ .id = HPBDMA_SLAVE_SDHI0_TX,
+ .addr = 0xffe4c000 + 0x30,
+ .dcr = HPB_DMAE_DCR_SPDS_16BIT |
+ HPB_DMAE_DCR_DMDL |
+ HPB_DMAE_DCR_DPDS_16BIT,
+ .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 |
+ HPB_DMAE_ASYNCRSTR_ASRST22 |
+ HPB_DMAE_ASYNCRSTR_ASRST23,
+ .mdr = HPB_DMAE_ASYNCMDR_ASMD21_MULTI,
+ .mdm = HPB_DMAE_ASYNCMDR_ASMD21_MASK,
+ .port = 0x0D0C,
+ .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
+ .dma_ch = 21,
+ }, {
+ .id = HPBDMA_SLAVE_SDHI0_RX,
+ .addr = 0xffe4c000 + 0x30,
+ .dcr = HPB_DMAE_DCR_SMDL |
+ HPB_DMAE_DCR_SPDS_16BIT |
+ HPB_DMAE_DCR_DPDS_16BIT,
+ .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 |
+ HPB_DMAE_ASYNCRSTR_ASRST22 |
+ HPB_DMAE_ASYNCRSTR_ASRST23,
+ .mdr = HPB_DMAE_ASYNCMDR_ASMD22_MULTI,
+ .mdm = HPB_DMAE_ASYNCMDR_ASMD22_MASK,
+ .port = 0x0D0C,
+ .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
+ .dma_ch = 22,
+ }, {
+ .id = HPBDMA_SLAVE_USBFUNC_TX, /* for D0 */
+ .addr = 0xffe60018,
+ .dcr = HPB_DMAE_DCR_SPDS_32BIT |
+ HPB_DMAE_DCR_DMDL |
+ HPB_DMAE_DCR_DPDS_32BIT,
+ .port = 0x0000,
+ .dma_ch = 14,
+ }, {
+ .id = HPBDMA_SLAVE_USBFUNC_RX, /* for D1 */
+ .addr = 0xffe6001c,
+ .dcr = HPB_DMAE_DCR_SMDL |
+ HPB_DMAE_DCR_SPDS_32BIT |
+ HPB_DMAE_DCR_DPDS_32BIT,
+ .port = 0x0101,
+ .dma_ch = 15,
+ },
+
+ HPBDMA_SSI(0),
+ HPBDMA_SSI(1),
+ HPBDMA_SSI(2),
+ HPBDMA_SSI(3),
+ HPBDMA_SSI(4),
+ HPBDMA_SSI(5),
+ HPBDMA_SSI(6),
+ HPBDMA_SSI(7),
+ HPBDMA_SSI(8),
+
+ HPBDMA_HPBIF(0),
+ HPBDMA_HPBIF(1),
+ HPBDMA_HPBIF(2),
+ HPBDMA_HPBIF(3),
+ HPBDMA_HPBIF(4),
+ HPBDMA_HPBIF(5),
+ HPBDMA_HPBIF(6),
+ HPBDMA_HPBIF(7),
+ HPBDMA_HPBIF(8),
+};
+
+static const struct hpb_dmae_channel hpb_dmae_channels[] = {
+ HPB_DMAE_CHANNEL(0x7c, HPBDMA_SLAVE_USBFUNC_TX), /* ch. 14 */
+ HPB_DMAE_CHANNEL(0x7c, HPBDMA_SLAVE_USBFUNC_RX), /* ch. 15 */
+ HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */
+ HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI0_TX), /* ch. 28 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI0_RX), /* ch. 28 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF0_TX), /* ch. 28 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF0_RX), /* ch. 28 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI1_TX), /* ch. 29 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI1_RX), /* ch. 29 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF1_TX), /* ch. 29 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF1_RX), /* ch. 29 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI2_TX), /* ch. 30 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI2_RX), /* ch. 30 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF2_TX), /* ch. 30 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF2_RX), /* ch. 30 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI3_TX), /* ch. 31 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI3_RX), /* ch. 31 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF3_TX), /* ch. 31 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF3_RX), /* ch. 31 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI4_TX), /* ch. 32 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI4_RX), /* ch. 32 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF4_TX), /* ch. 32 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF4_RX), /* ch. 32 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI5_TX), /* ch. 33 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI5_RX), /* ch. 33 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF5_TX), /* ch. 33 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF5_RX), /* ch. 33 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI6_TX), /* ch. 34 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI6_RX), /* ch. 34 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF6_TX), /* ch. 34 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF6_RX), /* ch. 34 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI7_TX), /* ch. 35 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI7_RX), /* ch. 35 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF7_TX), /* ch. 35 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF7_RX), /* ch. 35 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI8_TX), /* ch. 36 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI8_RX), /* ch. 36 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF8_TX), /* ch. 36 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF8_RX), /* ch. 36 */
+};
+
+static struct hpb_dmae_pdata dma_platform_data __initdata = {
+ .slaves = hpb_dmae_slaves,
+ .num_slaves = ARRAY_SIZE(hpb_dmae_slaves),
+ .channels = hpb_dmae_channels,
+ .num_channels = ARRAY_SIZE(hpb_dmae_channels),
+ .ts_shift = {
+ [XMIT_SZ_8BIT] = 0,
+ [XMIT_SZ_16BIT] = 1,
+ [XMIT_SZ_32BIT] = 2,
+ },
+ .num_hw_channels = 39,
+};
+
+static struct resource hpb_dmae_resources[] __initdata = {
+ /* Channel registers */
+ DEFINE_RES_MEM(0xffc08000, 0x1000),
+ /* Common registers */
+ DEFINE_RES_MEM(0xffc09000, 0x170),
+ /* Asynchronous reset registers */
+ DEFINE_RES_MEM(0xffc00300, 4),
+ /* Asynchronous mode registers */
+ DEFINE_RES_MEM(0xffc00400, 4),
+ /* IRQ for DMA channels */
+ DEFINE_RES_NAMED(gic_iid(0x7b), 5, NULL, IORESOURCE_IRQ),
+};
+
+static void __init r8a7778_register_hpb_dmae(void)
+{
+ platform_device_register_resndata(NULL, "hpb-dma-engine",
+ -1, hpb_dmae_resources,
+ ARRAY_SIZE(hpb_dmae_resources),
+ &dma_platform_data,
+ sizeof(dma_platform_data));
+}
+
+void __init r8a7778_add_standard_devices(void)
+{
+ r8a7778_add_dt_devices();
+ r8a7778_register_tmu(0);
+ r8a7778_register_scif(0);
+ r8a7778_register_scif(1);
+ r8a7778_register_scif(2);
+ r8a7778_register_scif(3);
+ r8a7778_register_scif(4);
+ r8a7778_register_scif(5);
+ r8a7778_register_i2c(0);
+ r8a7778_register_i2c(1);
+ r8a7778_register_i2c(2);
+ r8a7778_register_i2c(3);
+ r8a7778_register_hspi(0);
+ r8a7778_register_hspi(1);
+ r8a7778_register_hspi(2);
+
+ r8a7778_register_hpb_dmae();
+}
+
+void __init r8a7778_init_late(void)
+{
+ shmobile_init_late();
+ platform_device_register_full(&ehci_info);
+ platform_device_register_full(&ohci_info);
+}
+
+static struct renesas_intc_irqpin_config irqpin_platform_data __initdata = {
+ .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */
+ .sense_bitfield_width = 2,
+};
+
+static struct resource irqpin_resources[] __initdata = {
+ DEFINE_RES_MEM(0xfe78001c, 4), /* ICR1 */
+ DEFINE_RES_MEM(0xfe780010, 4), /* INTPRI */
+ DEFINE_RES_MEM(0xfe780024, 4), /* INTREQ */
+ DEFINE_RES_MEM(0xfe780044, 4), /* INTMSK0 */
+ DEFINE_RES_MEM(0xfe780064, 4), /* INTMSKCLR0 */
+ DEFINE_RES_IRQ(gic_iid(0x3b)), /* IRQ0 */
+ DEFINE_RES_IRQ(gic_iid(0x3c)), /* IRQ1 */
+ DEFINE_RES_IRQ(gic_iid(0x3d)), /* IRQ2 */
+ DEFINE_RES_IRQ(gic_iid(0x3e)), /* IRQ3 */
+};
+
+void __init r8a7778_init_irq_extpin_dt(int irlm)
+{
+ void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE);
+ unsigned long tmp;
+
+ if (!icr0) {
+ pr_warn("r8a7778: unable to setup external irq pin mode\n");
+ return;
+ }
+
+ tmp = ioread32(icr0);
+ if (irlm)
+ tmp |= 1 << 23; /* IRQ0 -> IRQ3 as individual pins */
+ else
+ tmp &= ~(1 << 23); /* IRL mode - not supported */
+ tmp |= (1 << 21); /* LVLMODE = 1 */
+ iowrite32(tmp, icr0);
+ iounmap(icr0);
+}
+
+void __init r8a7778_init_irq_extpin(int irlm)
+{
+ r8a7778_init_irq_extpin_dt(irlm);
+ if (irlm)
+ platform_device_register_resndata(
+ NULL, "renesas_intc_irqpin", -1,
+ irqpin_resources, ARRAY_SIZE(irqpin_resources),
+ &irqpin_platform_data, sizeof(irqpin_platform_data));
+}
+
+#ifdef CONFIG_USE_OF
+#define INT2SMSKCR0 0x82288 /* 0xfe782288 */
+#define INT2SMSKCR1 0x8228c /* 0xfe78228c */
+
+#define INT2NTSR0 0x00018 /* 0xfe700018 */
+#define INT2NTSR1 0x0002c /* 0xfe70002c */
+void __init r8a7778_init_irq_dt(void)
+{
+ void __iomem *base = ioremap_nocache(0xfe700000, 0x00100000);
+#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
+ void __iomem *gic_dist_base = ioremap_nocache(0xfe438000, 0x1000);
+ void __iomem *gic_cpu_base = ioremap_nocache(0xfe430000, 0x1000);
+#endif
+
+ BUG_ON(!base);
+
+#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
+ gic_init(0, 29, gic_dist_base, gic_cpu_base);
+#else
+ irqchip_init();
+#endif
+ /* route all interrupts to ARM */
+ __raw_writel(0x73ffffff, base + INT2NTSR0);
+ __raw_writel(0xffffffff, base + INT2NTSR1);
+
+ /* unmask all known interrupts in INTCS2 */
+ __raw_writel(0x08330773, base + INT2SMSKCR0);
+ __raw_writel(0x00311110, base + INT2SMSKCR1);
+
+ iounmap(base);
+}
+
+static const char *r8a7778_compat_dt[] __initdata = {
+ "renesas,r8a7778",
+ NULL,
+};
+
+DT_MACHINE_START(R8A7778_DT, "Generic R8A7778 (Flattened Device Tree)")
+ .init_early = shmobile_init_delay,
+ .init_irq = r8a7778_init_irq_dt,
+ .init_late = shmobile_init_late,
+#ifdef CONFIG_COMMON_CLK
+ .init_time = r8a7778_timer_init,
+#endif
+ .dt_compat = r8a7778_compat_dt,
+MACHINE_END
+
+#endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
new file mode 100644
index 000000000..c03e562be
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -0,0 +1,771 @@
+/*
+ * r8a7779 processor support
+ *
+ * Copyright (C) 2011, 2013 Renesas Solutions Corp.
+ * Copyright (C) 2011 Magnus Damm
+ * Copyright (C) 2013 Cogent Embedded, 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; 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/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/of_platform.h>
+#include <linux/platform_data/dma-rcar-hpbdma.h>
+#include <linux/platform_data/gpio-rcar.h>
+#include <linux/platform_data/irq-renesas-intc-irqpin.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_timer.h>
+#include <linux/dma-mapping.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
+#include <linux/pm_runtime.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "common.h"
+#include "irqs.h"
+#include "r8a7779.h"
+
+static struct map_desc r8a7779_io_desc[] __initdata = {
+ /* 2M identity mapping for 0xf0000000 (MPCORE) */
+ {
+ .virtual = 0xf0000000,
+ .pfn = __phys_to_pfn(0xf0000000),
+ .length = SZ_2M,
+ .type = MT_DEVICE_NONSHARED
+ },
+ /* 16M identity mapping for 0xfexxxxxx (DMAC-S/HPBREG/INTC2/LRAM/DBSC) */
+ {
+ .virtual = 0xfe000000,
+ .pfn = __phys_to_pfn(0xfe000000),
+ .length = SZ_16M,
+ .type = MT_DEVICE_NONSHARED
+ },
+};
+
+void __init r8a7779_map_io(void)
+{
+ debug_ll_io_init();
+ iotable_init(r8a7779_io_desc, ARRAY_SIZE(r8a7779_io_desc));
+}
+
+/* IRQ */
+#define INT2SMSKCR0 IOMEM(0xfe7822a0)
+#define INT2SMSKCR1 IOMEM(0xfe7822a4)
+#define INT2SMSKCR2 IOMEM(0xfe7822a8)
+#define INT2SMSKCR3 IOMEM(0xfe7822ac)
+#define INT2SMSKCR4 IOMEM(0xfe7822b0)
+
+#define INT2NTSR0 IOMEM(0xfe700060)
+#define INT2NTSR1 IOMEM(0xfe700064)
+
+static struct renesas_intc_irqpin_config irqpin0_platform_data __initdata = {
+ .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */
+ .sense_bitfield_width = 2,
+};
+
+static struct resource irqpin0_resources[] __initdata = {
+ DEFINE_RES_MEM(0xfe78001c, 4), /* ICR1 */
+ DEFINE_RES_MEM(0xfe780010, 4), /* INTPRI */
+ DEFINE_RES_MEM(0xfe780024, 4), /* INTREQ */
+ DEFINE_RES_MEM(0xfe780044, 4), /* INTMSK0 */
+ DEFINE_RES_MEM(0xfe780064, 4), /* INTMSKCLR0 */
+ DEFINE_RES_IRQ(gic_spi(27)), /* IRQ0 */
+ DEFINE_RES_IRQ(gic_spi(28)), /* IRQ1 */
+ DEFINE_RES_IRQ(gic_spi(29)), /* IRQ2 */
+ DEFINE_RES_IRQ(gic_spi(30)), /* IRQ3 */
+};
+
+void __init r8a7779_init_irq_extpin_dt(int irlm)
+{
+ void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE);
+ u32 tmp;
+
+ if (!icr0) {
+ pr_warn("r8a7779: unable to setup external irq pin mode\n");
+ return;
+ }
+
+ tmp = ioread32(icr0);
+ if (irlm)
+ tmp |= 1 << 23; /* IRQ0 -> IRQ3 as individual pins */
+ else
+ tmp &= ~(1 << 23); /* IRL mode - not supported */
+ tmp |= (1 << 21); /* LVLMODE = 1 */
+ iowrite32(tmp, icr0);
+ iounmap(icr0);
+}
+
+void __init r8a7779_init_irq_extpin(int irlm)
+{
+ r8a7779_init_irq_extpin_dt(irlm);
+ if (irlm)
+ platform_device_register_resndata(
+ NULL, "renesas_intc_irqpin", -1,
+ irqpin0_resources, ARRAY_SIZE(irqpin0_resources),
+ &irqpin0_platform_data, sizeof(irqpin0_platform_data));
+}
+
+/* PFC/GPIO */
+static struct resource r8a7779_pfc_resources[] = {
+ DEFINE_RES_MEM(0xfffc0000, 0x023c),
+};
+
+static struct platform_device r8a7779_pfc_device = {
+ .name = "pfc-r8a7779",
+ .id = -1,
+ .resource = r8a7779_pfc_resources,
+ .num_resources = ARRAY_SIZE(r8a7779_pfc_resources),
+};
+
+#define R8A7779_GPIO(idx, npins) \
+static struct resource r8a7779_gpio##idx##_resources[] = { \
+ DEFINE_RES_MEM(0xffc40000 + (0x1000 * (idx)), 0x002c), \
+ DEFINE_RES_IRQ(gic_iid(0xad + (idx))), \
+}; \
+ \
+static struct gpio_rcar_config r8a7779_gpio##idx##_platform_data = { \
+ .gpio_base = 32 * (idx), \
+ .irq_base = 0, \
+ .number_of_pins = npins, \
+ .pctl_name = "pfc-r8a7779", \
+}; \
+ \
+static struct platform_device r8a7779_gpio##idx##_device = { \
+ .name = "gpio_rcar", \
+ .id = idx, \
+ .resource = r8a7779_gpio##idx##_resources, \
+ .num_resources = ARRAY_SIZE(r8a7779_gpio##idx##_resources), \
+ .dev = { \
+ .platform_data = &r8a7779_gpio##idx##_platform_data, \
+ }, \
+}
+
+R8A7779_GPIO(0, 32);
+R8A7779_GPIO(1, 32);
+R8A7779_GPIO(2, 32);
+R8A7779_GPIO(3, 32);
+R8A7779_GPIO(4, 32);
+R8A7779_GPIO(5, 32);
+R8A7779_GPIO(6, 9);
+
+static struct platform_device *r8a7779_pinctrl_devices[] __initdata = {
+ &r8a7779_pfc_device,
+ &r8a7779_gpio0_device,
+ &r8a7779_gpio1_device,
+ &r8a7779_gpio2_device,
+ &r8a7779_gpio3_device,
+ &r8a7779_gpio4_device,
+ &r8a7779_gpio5_device,
+ &r8a7779_gpio6_device,
+};
+
+void __init r8a7779_pinmux_init(void)
+{
+ platform_add_devices(r8a7779_pinctrl_devices,
+ ARRAY_SIZE(r8a7779_pinctrl_devices));
+}
+
+/* SCIF */
+#define R8A7779_SCIF(index, baseaddr, irq) \
+static struct plat_sci_port scif##index##_platform_data = { \
+ .type = PORT_SCIF, \
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \
+ .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, \
+}; \
+ \
+static struct resource scif##index##_resources[] = { \
+ DEFINE_RES_MEM(baseaddr, 0x100), \
+ DEFINE_RES_IRQ(irq), \
+}; \
+ \
+static struct platform_device scif##index##_device = { \
+ .name = "sh-sci", \
+ .id = index, \
+ .resource = scif##index##_resources, \
+ .num_resources = ARRAY_SIZE(scif##index##_resources), \
+ .dev = { \
+ .platform_data = &scif##index##_platform_data, \
+ }, \
+}
+
+R8A7779_SCIF(0, 0xffe40000, gic_iid(0x78));
+R8A7779_SCIF(1, 0xffe41000, gic_iid(0x79));
+R8A7779_SCIF(2, 0xffe42000, gic_iid(0x7a));
+R8A7779_SCIF(3, 0xffe43000, gic_iid(0x7b));
+R8A7779_SCIF(4, 0xffe44000, gic_iid(0x7c));
+R8A7779_SCIF(5, 0xffe45000, gic_iid(0x7d));
+
+/* TMU */
+static struct sh_timer_config tmu0_platform_data = {
+ .channels_mask = 7,
+};
+
+static struct resource tmu0_resources[] = {
+ DEFINE_RES_MEM(0xffd80000, 0x30),
+ DEFINE_RES_IRQ(gic_iid(0x40)),
+ DEFINE_RES_IRQ(gic_iid(0x41)),
+ DEFINE_RES_IRQ(gic_iid(0x42)),
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh-tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+/* I2C */
+static struct resource rcar_i2c0_res[] = {
+ {
+ .start = 0xffc70000,
+ .end = 0xffc70fff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = gic_iid(0x6f),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device i2c0_device = {
+ .name = "i2c-rcar",
+ .id = 0,
+ .resource = rcar_i2c0_res,
+ .num_resources = ARRAY_SIZE(rcar_i2c0_res),
+};
+
+static struct resource rcar_i2c1_res[] = {
+ {
+ .start = 0xffc71000,
+ .end = 0xffc71fff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = gic_iid(0x72),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device i2c1_device = {
+ .name = "i2c-rcar",
+ .id = 1,
+ .resource = rcar_i2c1_res,
+ .num_resources = ARRAY_SIZE(rcar_i2c1_res),
+};
+
+static struct resource rcar_i2c2_res[] = {
+ {
+ .start = 0xffc72000,
+ .end = 0xffc72fff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = gic_iid(0x70),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device i2c2_device = {
+ .name = "i2c-rcar",
+ .id = 2,
+ .resource = rcar_i2c2_res,
+ .num_resources = ARRAY_SIZE(rcar_i2c2_res),
+};
+
+static struct resource rcar_i2c3_res[] = {
+ {
+ .start = 0xffc73000,
+ .end = 0xffc73fff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = gic_iid(0x71),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device i2c3_device = {
+ .name = "i2c-rcar",
+ .id = 3,
+ .resource = rcar_i2c3_res,
+ .num_resources = ARRAY_SIZE(rcar_i2c3_res),
+};
+
+static struct resource sata_resources[] = {
+ [0] = {
+ .name = "rcar-sata",
+ .start = 0xfc600000,
+ .end = 0xfc601fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_iid(0x84),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sata_device = {
+ .name = "sata_rcar",
+ .id = -1,
+ .resource = sata_resources,
+ .num_resources = ARRAY_SIZE(sata_resources),
+ .dev = {
+ .dma_mask = &sata_device.dev.coherent_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+/* USB */
+static struct usb_phy *phy;
+
+static int usb_power_on(struct platform_device *pdev)
+{
+ if (IS_ERR(phy))
+ return PTR_ERR(phy);
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+
+ usb_phy_init(phy);
+
+ return 0;
+}
+
+static void usb_power_off(struct platform_device *pdev)
+{
+ if (IS_ERR(phy))
+ return;
+
+ usb_phy_shutdown(phy);
+
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+}
+
+static int ehci_init_internal_buffer(struct usb_hcd *hcd)
+{
+ /*
+ * Below are recommended values from the datasheet;
+ * see [USB :: Setting of EHCI Internal Buffer].
+ */
+ /* EHCI IP internal buffer setting */
+ iowrite32(0x00ff0040, hcd->regs + 0x0094);
+ /* EHCI IP internal buffer enable */
+ iowrite32(0x00000001, hcd->regs + 0x009C);
+
+ return 0;
+}
+
+static struct usb_ehci_pdata ehcix_pdata = {
+ .power_on = usb_power_on,
+ .power_off = usb_power_off,
+ .power_suspend = usb_power_off,
+ .pre_setup = ehci_init_internal_buffer,
+};
+
+static struct resource ehci0_resources[] = {
+ [0] = {
+ .start = 0xffe70000,
+ .end = 0xffe70400 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_iid(0x4c),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ehci0_device = {
+ .name = "ehci-platform",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ehci0_device.dev.coherent_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &ehcix_pdata,
+ },
+ .num_resources = ARRAY_SIZE(ehci0_resources),
+ .resource = ehci0_resources,
+};
+
+static struct resource ehci1_resources[] = {
+ [0] = {
+ .start = 0xfff70000,
+ .end = 0xfff70400 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_iid(0x4d),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ehci1_device = {
+ .name = "ehci-platform",
+ .id = 1,
+ .dev = {
+ .dma_mask = &ehci1_device.dev.coherent_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &ehcix_pdata,
+ },
+ .num_resources = ARRAY_SIZE(ehci1_resources),
+ .resource = ehci1_resources,
+};
+
+static struct usb_ohci_pdata ohcix_pdata = {
+ .power_on = usb_power_on,
+ .power_off = usb_power_off,
+ .power_suspend = usb_power_off,
+};
+
+static struct resource ohci0_resources[] = {
+ [0] = {
+ .start = 0xffe70400,
+ .end = 0xffe70800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_iid(0x4c),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ohci0_device = {
+ .name = "ohci-platform",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ohci0_device.dev.coherent_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &ohcix_pdata,
+ },
+ .num_resources = ARRAY_SIZE(ohci0_resources),
+ .resource = ohci0_resources,
+};
+
+static struct resource ohci1_resources[] = {
+ [0] = {
+ .start = 0xfff70400,
+ .end = 0xfff70800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_iid(0x4d),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ohci1_device = {
+ .name = "ohci-platform",
+ .id = 1,
+ .dev = {
+ .dma_mask = &ohci1_device.dev.coherent_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &ohcix_pdata,
+ },
+ .num_resources = ARRAY_SIZE(ohci1_resources),
+ .resource = ohci1_resources,
+};
+
+/* HPB-DMA */
+
+/* Asynchronous mode register bits */
+#define HPB_DMAE_ASYNCMDR_ASMD43_MASK BIT(23) /* MMC1 */
+#define HPB_DMAE_ASYNCMDR_ASMD43_SINGLE BIT(23) /* MMC1 */
+#define HPB_DMAE_ASYNCMDR_ASMD43_MULTI 0 /* MMC1 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD43_MASK BIT(22) /* MMC1 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD43_BURST BIT(22) /* MMC1 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD43_NBURST 0 /* MMC1 */
+#define HPB_DMAE_ASYNCMDR_ASMD24_MASK BIT(21) /* MMC0 */
+#define HPB_DMAE_ASYNCMDR_ASMD24_SINGLE BIT(21) /* MMC0 */
+#define HPB_DMAE_ASYNCMDR_ASMD24_MULTI 0 /* MMC0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD24_MASK BIT(20) /* MMC0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD24_BURST BIT(20) /* MMC0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD24_NBURST 0 /* MMC0 */
+#define HPB_DMAE_ASYNCMDR_ASMD41_MASK BIT(19) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD41_SINGLE BIT(19) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD41_MULTI 0 /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD41_MASK BIT(18) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD41_BURST BIT(18) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD41_NBURST 0 /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD40_MASK BIT(17) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD40_SINGLE BIT(17) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD40_MULTI 0 /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD40_MASK BIT(16) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD40_BURST BIT(16) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD40_NBURST 0 /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD39_MASK BIT(15) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD39_SINGLE BIT(15) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD39_MULTI 0 /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD39_MASK BIT(14) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD39_BURST BIT(14) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD39_NBURST 0 /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD27_MASK BIT(13) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD27_SINGLE BIT(13) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD27_MULTI 0 /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD27_MASK BIT(12) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD27_BURST BIT(12) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD27_NBURST 0 /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD26_MASK BIT(11) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD26_SINGLE BIT(11) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD26_MULTI 0 /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD26_MASK BIT(10) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD26_BURST BIT(10) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD26_NBURST 0 /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD25_MASK BIT(9) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD25_SINGLE BIT(9) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD25_MULTI 0 /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD25_MASK BIT(8) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD25_BURST BIT(8) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD25_NBURST 0 /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD23_MASK BIT(7) /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD23_SINGLE BIT(7) /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD23_MULTI 0 /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD23_MASK BIT(6) /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD23_BURST BIT(6) /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD23_NBURST 0 /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD22_MASK BIT(5) /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE BIT(5) /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI 0 /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD22_MASK BIT(4) /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD22_BURST BIT(4) /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST 0 /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD21_MASK BIT(3) /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE BIT(3) /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0 /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD21_MASK BIT(2) /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD21_BURST BIT(2) /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST 0 /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD20_MASK BIT(1) /* SDHI1 */
+#define HPB_DMAE_ASYNCMDR_ASMD20_SINGLE BIT(1) /* SDHI1 */
+#define HPB_DMAE_ASYNCMDR_ASMD20_MULTI 0 /* SDHI1 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD20_MASK BIT(0) /* SDHI1 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD20_BURST BIT(0) /* SDHI1 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD20_NBURST 0 /* SDHI1 */
+
+static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = {
+ {
+ .id = HPBDMA_SLAVE_SDHI0_TX,
+ .addr = 0xffe4c000 + 0x30,
+ .dcr = HPB_DMAE_DCR_SPDS_16BIT |
+ HPB_DMAE_DCR_DMDL |
+ HPB_DMAE_DCR_DPDS_16BIT,
+ .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 |
+ HPB_DMAE_ASYNCRSTR_ASRST22 |
+ HPB_DMAE_ASYNCRSTR_ASRST23,
+ .mdr = HPB_DMAE_ASYNCMDR_ASMD21_SINGLE |
+ HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST,
+ .mdm = HPB_DMAE_ASYNCMDR_ASMD21_MASK |
+ HPB_DMAE_ASYNCMDR_ASBTMD21_MASK,
+ .port = 0x0D0C,
+ .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
+ .dma_ch = 21,
+ }, {
+ .id = HPBDMA_SLAVE_SDHI0_RX,
+ .addr = 0xffe4c000 + 0x30,
+ .dcr = HPB_DMAE_DCR_SMDL |
+ HPB_DMAE_DCR_SPDS_16BIT |
+ HPB_DMAE_DCR_DPDS_16BIT,
+ .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 |
+ HPB_DMAE_ASYNCRSTR_ASRST22 |
+ HPB_DMAE_ASYNCRSTR_ASRST23,
+ .mdr = HPB_DMAE_ASYNCMDR_ASMD22_SINGLE |
+ HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST,
+ .mdm = HPB_DMAE_ASYNCMDR_ASMD22_MASK |
+ HPB_DMAE_ASYNCMDR_ASBTMD22_MASK,
+ .port = 0x0D0C,
+ .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
+ .dma_ch = 22,
+ },
+};
+
+static const struct hpb_dmae_channel hpb_dmae_channels[] = {
+ HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */
+ HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */
+};
+
+static struct hpb_dmae_pdata dma_platform_data __initdata = {
+ .slaves = hpb_dmae_slaves,
+ .num_slaves = ARRAY_SIZE(hpb_dmae_slaves),
+ .channels = hpb_dmae_channels,
+ .num_channels = ARRAY_SIZE(hpb_dmae_channels),
+ .ts_shift = {
+ [XMIT_SZ_8BIT] = 0,
+ [XMIT_SZ_16BIT] = 1,
+ [XMIT_SZ_32BIT] = 2,
+ },
+ .num_hw_channels = 44,
+};
+
+static struct resource hpb_dmae_resources[] __initdata = {
+ /* Channel registers */
+ DEFINE_RES_MEM(0xffc08000, 0x1000),
+ /* Common registers */
+ DEFINE_RES_MEM(0xffc09000, 0x170),
+ /* Asynchronous reset registers */
+ DEFINE_RES_MEM(0xffc00300, 4),
+ /* Asynchronous mode registers */
+ DEFINE_RES_MEM(0xffc00400, 4),
+ /* IRQ for DMA channels */
+ DEFINE_RES_NAMED(gic_iid(0x8e), 12, NULL, IORESOURCE_IRQ),
+};
+
+static void __init r8a7779_register_hpb_dmae(void)
+{
+ platform_device_register_resndata(NULL, "hpb-dma-engine",
+ -1, hpb_dmae_resources,
+ ARRAY_SIZE(hpb_dmae_resources),
+ &dma_platform_data,
+ sizeof(dma_platform_data));
+}
+
+static struct platform_device *r8a7779_early_devices[] __initdata = {
+ &tmu0_device,
+};
+
+static struct platform_device *r8a7779_standard_devices[] __initdata = {
+ &scif0_device,
+ &scif1_device,
+ &scif2_device,
+ &scif3_device,
+ &scif4_device,
+ &scif5_device,
+ &i2c0_device,
+ &i2c1_device,
+ &i2c2_device,
+ &i2c3_device,
+ &sata_device,
+};
+
+void __init r8a7779_add_standard_devices(void)
+{
+#ifdef CONFIG_CACHE_L2X0
+ /* Shared attribute override enable, 64K*16way */
+ l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff);
+#endif
+ r8a7779_pm_init();
+
+ r8a7779_init_pm_domains();
+
+ platform_add_devices(r8a7779_early_devices,
+ ARRAY_SIZE(r8a7779_early_devices));
+ platform_add_devices(r8a7779_standard_devices,
+ ARRAY_SIZE(r8a7779_standard_devices));
+ r8a7779_register_hpb_dmae();
+}
+
+void __init r8a7779_add_early_devices(void)
+{
+ early_platform_add_devices(r8a7779_early_devices,
+ ARRAY_SIZE(r8a7779_early_devices));
+
+ /* Early serial console setup is not included here due to
+ * memory map collisions. The SCIF serial ports in r8a7779
+ * are difficult to identity map 1:1 due to collision with the
+ * virtual memory range used by the coherent DMA code on ARM.
+ *
+ * Anyone wanting to debug early can remove UPF_IOREMAP from
+ * the sh-sci serial console platform data, adjust mapbase
+ * to a static M:N virt:phys mapping that needs to be added to
+ * the mappings passed with iotable_init() above.
+ *
+ * Then add a call to shmobile_setup_console() from this function.
+ *
+ * As a final step pass earlyprint=sh-sci.2,115200 on the kernel
+ * command line in case of the marzen board.
+ */
+}
+
+static struct platform_device *r8a7779_late_devices[] __initdata = {
+ &ehci0_device,
+ &ehci1_device,
+ &ohci0_device,
+ &ohci1_device,
+};
+
+void __init r8a7779_init_late(void)
+{
+ /* get USB PHY */
+ phy = usb_get_phy(USB_PHY_TYPE_USB2);
+
+ shmobile_init_late();
+ platform_add_devices(r8a7779_late_devices,
+ ARRAY_SIZE(r8a7779_late_devices));
+}
+
+#ifdef CONFIG_USE_OF
+void __init r8a7779_init_irq_dt(void)
+{
+#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
+ void __iomem *gic_dist_base = ioremap_nocache(0xf0001000, 0x1000);
+ void __iomem *gic_cpu_base = ioremap_nocache(0xf0000100, 0x1000);
+#endif
+ gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE);
+
+#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
+ gic_init(0, 29, gic_dist_base, gic_cpu_base);
+#else
+ irqchip_init();
+#endif
+ /* route all interrupts to ARM */
+ __raw_writel(0xffffffff, INT2NTSR0);
+ __raw_writel(0x3fffffff, INT2NTSR1);
+
+ /* unmask all known interrupts in INTCS2 */
+ __raw_writel(0xfffffff0, INT2SMSKCR0);
+ __raw_writel(0xfff7ffff, INT2SMSKCR1);
+ __raw_writel(0xfffbffdf, INT2SMSKCR2);
+ __raw_writel(0xbffffffc, INT2SMSKCR3);
+ __raw_writel(0x003fee3f, INT2SMSKCR4);
+}
+
+#define MODEMR 0xffcc0020
+
+u32 __init r8a7779_read_mode_pins(void)
+{
+ static u32 mode;
+ static bool mode_valid;
+
+ if (!mode_valid) {
+ void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
+ BUG_ON(!modemr);
+ mode = ioread32(modemr);
+ iounmap(modemr);
+ mode_valid = true;
+ }
+
+ return mode;
+}
+
+static const char *r8a7779_compat_dt[] __initdata = {
+ "renesas,r8a7779",
+ NULL,
+};
+
+DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)")
+ .map_io = r8a7779_map_io,
+ .init_early = shmobile_init_delay,
+ .init_irq = r8a7779_init_irq_dt,
+ .init_late = shmobile_init_late,
+ .dt_compat = r8a7779_compat_dt,
+MACHINE_END
+#endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c
new file mode 100644
index 000000000..3a18af492
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-r8a7790.c
@@ -0,0 +1,37 @@
+/*
+ * r8a7790 processor support
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 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.
+ */
+
+#include <linux/init.h>
+
+#include <asm/mach/arch.h>
+
+#include "common.h"
+#include "r8a7790.h"
+#include "rcar-gen2.h"
+
+static const char * const r8a7790_boards_compat_dt[] __initconst = {
+ "renesas,r8a7790",
+ NULL,
+};
+
+DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)")
+ .smp = smp_ops(r8a7790_smp_ops),
+ .init_early = shmobile_init_delay,
+ .init_time = rcar_gen2_timer_init,
+ .init_late = shmobile_init_late,
+ .reserve = rcar_gen2_reserve,
+ .dt_compat = r8a7790_boards_compat_dt,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c
new file mode 100644
index 000000000..ef8eb3af5
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-r8a7791.c
@@ -0,0 +1,38 @@
+/*
+ * r8a7791 processor support
+ *
+ * Copyright (C) 2013 Renesas Electronics Corporation
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 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.
+ */
+
+#include <linux/init.h>
+
+#include <asm/mach/arch.h>
+
+#include "common.h"
+#include "r8a7791.h"
+#include "rcar-gen2.h"
+
+static const char *r8a7791_boards_compat_dt[] __initdata = {
+ "renesas,r8a7791",
+ NULL,
+};
+
+DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)")
+ .smp = smp_ops(r8a7791_smp_ops),
+ .init_early = shmobile_init_delay,
+ .init_time = rcar_gen2_timer_init,
+ .init_late = shmobile_init_late,
+ .reserve = rcar_gen2_reserve,
+ .dt_compat = r8a7791_boards_compat_dt,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/setup-r8a7794.c b/arch/arm/mach-shmobile/setup-r8a7794.c
new file mode 100644
index 000000000..d2b093033
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-r8a7794.c
@@ -0,0 +1,33 @@
+/*
+ * r8a7794 processor support
+ *
+ * Copyright (C) 2014 Renesas Electronics Corporation
+ * Copyright (C) 2014 Ulrich Hecht
+ *
+ * This program is free software; 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/of_platform.h>
+#include "common.h"
+#include "rcar-gen2.h"
+#include <asm/mach/arch.h>
+
+static const char * const r8a7794_boards_compat_dt[] __initconst = {
+ "renesas,r8a7794",
+ NULL,
+};
+
+DT_MACHINE_START(R8A7794_DT, "Generic R8A7794 (Flattened Device Tree)")
+ .init_early = shmobile_init_delay,
+ .init_late = shmobile_init_late,
+ .init_time = rcar_gen2_timer_init,
+ .reserve = rcar_gen2_reserve,
+ .dt_compat = r8a7794_boards_compat_dt,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c
new file mode 100644
index 000000000..5d13595aa
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c
@@ -0,0 +1,203 @@
+/*
+ * R-Car Generation 2 support
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 Magnus Damm
+ * Copyright (C) 2014 Ulrich Hecht
+ *
+ * This program is free software; 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/clk/shmobile.h>
+#include <linux/clocksource.h>
+#include <linux/device.h>
+#include <linux/dma-contiguous.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/memblock.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <asm/mach/arch.h>
+#include "common.h"
+#include "rcar-gen2.h"
+
+#define MODEMR 0xe6160060
+
+u32 rcar_gen2_read_mode_pins(void)
+{
+ static u32 mode;
+ static bool mode_valid;
+
+ if (!mode_valid) {
+ void __iomem *modemr = ioremap_nocache(MODEMR, 4);
+ BUG_ON(!modemr);
+ mode = ioread32(modemr);
+ iounmap(modemr);
+ mode_valid = true;
+ }
+
+ return mode;
+}
+
+#define CNTCR 0
+#define CNTFID0 0x20
+
+void __init rcar_gen2_timer_init(void)
+{
+ u32 mode = rcar_gen2_read_mode_pins();
+#ifdef CONFIG_ARM_ARCH_TIMER
+ void __iomem *base;
+ int extal_mhz = 0;
+ u32 freq;
+
+ if (of_machine_is_compatible("renesas,r8a7794")) {
+ freq = 260000000 / 8; /* ZS / 8 */
+ /* CNTVOFF has to be initialized either from non-secure
+ * Hypervisor mode or secure Monitor mode with SCR.NS==1.
+ * If TrustZone is enabled then it should be handled by the
+ * secure code.
+ */
+ asm volatile(
+ " cps 0x16\n"
+ " mrc p15, 0, r1, c1, c1, 0\n"
+ " orr r0, r1, #1\n"
+ " mcr p15, 0, r0, c1, c1, 0\n"
+ " isb\n"
+ " mov r0, #0\n"
+ " mcrr p15, 4, r0, r0, c14\n"
+ " isb\n"
+ " mcr p15, 0, r1, c1, c1, 0\n"
+ " isb\n"
+ " cps 0x13\n"
+ : : : "r0", "r1");
+ } else {
+ /* At Linux boot time the r8a7790 arch timer comes up
+ * with the counter disabled. Moreover, it may also report
+ * a potentially incorrect fixed 13 MHz frequency. To be
+ * correct these registers need to be updated to use the
+ * frequency EXTAL / 2 which can be determined by the MD pins.
+ */
+
+ switch (mode & (MD(14) | MD(13))) {
+ case 0:
+ extal_mhz = 15;
+ break;
+ case MD(13):
+ extal_mhz = 20;
+ break;
+ case MD(14):
+ extal_mhz = 26;
+ break;
+ case MD(13) | MD(14):
+ extal_mhz = 30;
+ break;
+ }
+
+ /* The arch timer frequency equals EXTAL / 2 */
+ freq = extal_mhz * (1000000 / 2);
+ }
+
+ /* Remap "armgcnt address map" space */
+ base = ioremap(0xe6080000, PAGE_SIZE);
+
+ /*
+ * Update the timer if it is either not running, or is not at the
+ * right frequency. The timer is only configurable in secure mode
+ * so this avoids an abort if the loader started the timer and
+ * entered the kernel in non-secure mode.
+ */
+
+ if ((ioread32(base + CNTCR) & 1) == 0 ||
+ ioread32(base + CNTFID0) != freq) {
+ /* Update registers with correct frequency */
+ iowrite32(freq, base + CNTFID0);
+ asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
+
+ /* make sure arch timer is started by setting bit 0 of CNTCR */
+ iowrite32(1, base + CNTCR);
+ }
+
+ iounmap(base);
+#endif /* CONFIG_ARM_ARCH_TIMER */
+
+ rcar_gen2_clocks_init(mode);
+#ifdef CONFIG_ARCH_SHMOBILE_MULTI
+ clocksource_of_init();
+#endif
+}
+
+struct memory_reserve_config {
+ u64 reserved;
+ u64 base, size;
+};
+
+static int __init rcar_gen2_scan_mem(unsigned long node, const char *uname,
+ int depth, void *data)
+{
+ const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+ const __be32 *reg, *endp;
+ int l;
+ struct memory_reserve_config *mrc = data;
+ u64 lpae_start = 1ULL << 32;
+
+ /* We are scanning "memory" nodes only */
+ if (type == NULL || strcmp(type, "memory"))
+ return 0;
+
+ reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
+ if (reg == NULL)
+ reg = of_get_flat_dt_prop(node, "reg", &l);
+ if (reg == NULL)
+ return 0;
+
+ endp = reg + (l / sizeof(__be32));
+ while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+ u64 base, size;
+
+ base = dt_mem_next_cell(dt_root_addr_cells, &reg);
+ size = dt_mem_next_cell(dt_root_size_cells, &reg);
+
+ if (base >= lpae_start)
+ continue;
+
+ if ((base + size) >= lpae_start)
+ size = lpae_start - base;
+
+ if (size < mrc->reserved)
+ continue;
+
+ if (base < mrc->base)
+ continue;
+
+ /* keep the area at top near the 32-bit legacy limit */
+ mrc->base = base + size - mrc->reserved;
+ mrc->size = mrc->reserved;
+ }
+
+ return 0;
+}
+
+struct cma *rcar_gen2_dma_contiguous;
+
+void __init rcar_gen2_reserve(void)
+{
+ struct memory_reserve_config mrc;
+
+ /* reserve 256 MiB at the top of the physical legacy 32-bit space */
+ memset(&mrc, 0, sizeof(mrc));
+ mrc.reserved = SZ_256M;
+
+ of_scan_flat_dt(rcar_gen2_scan_mem, &mrc);
+#ifdef CONFIG_DMA_CMA
+ if (mrc.size && memblock_is_region_memory(mrc.base, mrc.size))
+ dma_contiguous_reserve_area(mrc.size, mrc.base, 0,
+ &rcar_gen2_dma_contiguous, true);
+#endif
+}
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
new file mode 100644
index 000000000..fb2ab7590
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -0,0 +1,810 @@
+/*
+ * 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/of_platform.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/i2c/i2c-sh_mobile.h>
+#include <linux/io.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_dma.h>
+#include <linux/sh_timer.h>
+#include <linux/platform_data/sh_ipmmu.h>
+#include <linux/platform_data/irq-renesas-intc-irqpin.h>
+
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "common.h"
+#include "dma-register.h"
+#include "intc.h"
+#include "irqs.h"
+#include "sh73a0.h"
+
+static struct map_desc sh73a0_io_desc[] __initdata = {
+ /* create a 1:1 identity mapping for 0xe6xxxxxx
+ * used by CPGA, INTC and PFC.
+ */
+ {
+ .virtual = 0xe6000000,
+ .pfn = __phys_to_pfn(0xe6000000),
+ .length = 256 << 20,
+ .type = MT_DEVICE_NONSHARED
+ },
+};
+
+void __init sh73a0_map_io(void)
+{
+ debug_ll_io_init();
+ iotable_init(sh73a0_io_desc, ARRAY_SIZE(sh73a0_io_desc));
+}
+
+/* PFC */
+static struct resource pfc_resources[] __initdata = {
+ DEFINE_RES_MEM(0xe6050000, 0x8000),
+ DEFINE_RES_MEM(0xe605801c, 0x000c),
+};
+
+void __init sh73a0_pinmux_init(void)
+{
+ platform_device_register_simple("pfc-sh73a0", -1, pfc_resources,
+ ARRAY_SIZE(pfc_resources));
+}
+
+/* SCIF */
+#define SH73A0_SCIF(scif_type, index, baseaddr, irq) \
+static struct plat_sci_port scif##index##_platform_data = { \
+ .type = scif_type, \
+ .flags = UPF_BOOT_AUTOCONF, \
+ .scscr = SCSCR_RE | SCSCR_TE, \
+}; \
+ \
+static struct resource scif##index##_resources[] = { \
+ DEFINE_RES_MEM(baseaddr, 0x100), \
+ DEFINE_RES_IRQ(irq), \
+}; \
+ \
+static struct platform_device scif##index##_device = { \
+ .name = "sh-sci", \
+ .id = index, \
+ .resource = scif##index##_resources, \
+ .num_resources = ARRAY_SIZE(scif##index##_resources), \
+ .dev = { \
+ .platform_data = &scif##index##_platform_data, \
+ }, \
+}
+
+SH73A0_SCIF(PORT_SCIFA, 0, 0xe6c40000, gic_spi(72));
+SH73A0_SCIF(PORT_SCIFA, 1, 0xe6c50000, gic_spi(73));
+SH73A0_SCIF(PORT_SCIFA, 2, 0xe6c60000, gic_spi(74));
+SH73A0_SCIF(PORT_SCIFA, 3, 0xe6c70000, gic_spi(75));
+SH73A0_SCIF(PORT_SCIFA, 4, 0xe6c80000, gic_spi(78));
+SH73A0_SCIF(PORT_SCIFA, 5, 0xe6cb0000, gic_spi(79));
+SH73A0_SCIF(PORT_SCIFA, 6, 0xe6cc0000, gic_spi(156));
+SH73A0_SCIF(PORT_SCIFA, 7, 0xe6cd0000, gic_spi(143));
+SH73A0_SCIF(PORT_SCIFB, 8, 0xe6c30000, gic_spi(80));
+
+static struct sh_timer_config cmt1_platform_data = {
+ .channels_mask = 0x3f,
+};
+
+static struct resource cmt1_resources[] = {
+ DEFINE_RES_MEM(0xe6138000, 0x200),
+ DEFINE_RES_IRQ(gic_spi(65)),
+};
+
+static struct platform_device cmt1_device = {
+ .name = "sh-cmt-48",
+ .id = 1,
+ .dev = {
+ .platform_data = &cmt1_platform_data,
+ },
+ .resource = cmt1_resources,
+ .num_resources = ARRAY_SIZE(cmt1_resources),
+};
+
+/* TMU */
+static struct sh_timer_config tmu0_platform_data = {
+ .channels_mask = 7,
+};
+
+static struct resource tmu0_resources[] = {
+ DEFINE_RES_MEM(0xfff60000, 0x2c),
+ DEFINE_RES_IRQ(intcs_evt2irq(0xe80)),
+ DEFINE_RES_IRQ(intcs_evt2irq(0xea0)),
+ DEFINE_RES_IRQ(intcs_evt2irq(0xec0)),
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh-tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct resource i2c0_resources[] = {
+ [0] = DEFINE_RES_MEM(0xe6820000, 0x426),
+ [1] = {
+ .start = gic_spi(167),
+ .end = gic_spi(170),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c1_resources[] = {
+ [0] = DEFINE_RES_MEM(0xe6822000, 0x426),
+ [1] = {
+ .start = gic_spi(51),
+ .end = gic_spi(54),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c2_resources[] = {
+ [0] = DEFINE_RES_MEM(0xe6824000, 0x426),
+ [1] = {
+ .start = gic_spi(171),
+ .end = gic_spi(174),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c3_resources[] = {
+ [0] = DEFINE_RES_MEM(0xe6826000, 0x426),
+ [1] = {
+ .start = gic_spi(183),
+ .end = gic_spi(186),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c4_resources[] = {
+ [0] = DEFINE_RES_MEM(0xe6828000, 0x426),
+ [1] = {
+ .start = gic_spi(187),
+ .end = gic_spi(190),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct i2c_sh_mobile_platform_data i2c_platform_data = {
+ .clks_per_count = 2,
+};
+
+static struct platform_device i2c0_device = {
+ .name = "i2c-sh_mobile",
+ .id = 0,
+ .resource = i2c0_resources,
+ .num_resources = ARRAY_SIZE(i2c0_resources),
+ .dev = {
+ .platform_data = &i2c_platform_data,
+ },
+};
+
+static struct platform_device i2c1_device = {
+ .name = "i2c-sh_mobile",
+ .id = 1,
+ .resource = i2c1_resources,
+ .num_resources = ARRAY_SIZE(i2c1_resources),
+ .dev = {
+ .platform_data = &i2c_platform_data,
+ },
+};
+
+static struct platform_device i2c2_device = {
+ .name = "i2c-sh_mobile",
+ .id = 2,
+ .resource = i2c2_resources,
+ .num_resources = ARRAY_SIZE(i2c2_resources),
+ .dev = {
+ .platform_data = &i2c_platform_data,
+ },
+};
+
+static struct platform_device i2c3_device = {
+ .name = "i2c-sh_mobile",
+ .id = 3,
+ .resource = i2c3_resources,
+ .num_resources = ARRAY_SIZE(i2c3_resources),
+ .dev = {
+ .platform_data = &i2c_platform_data,
+ },
+};
+
+static struct platform_device i2c4_device = {
+ .name = "i2c-sh_mobile",
+ .id = 4,
+ .resource = i2c4_resources,
+ .num_resources = ARRAY_SIZE(i2c4_resources),
+ .dev = {
+ .platform_data = &i2c_platform_data,
+ },
+};
+
+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 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 = TS_LOW_SHIFT,
+ .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT,
+ .ts_high_shift = TS_HI_SHIFT,
+ .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT,
+ .ts_shift = dma_ts_shift,
+ .ts_shift_num = ARRAY_SIZE(dma_ts_shift),
+ .dmaor_init = DMAOR_DME,
+};
+
+static struct resource sh73a0_dmae_resources[] = {
+ DEFINE_RES_MEM(0xfe000020, 0x89e0),
+ {
+ .name = "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,
+ },
+};
+
+/* MPDMAC */
+static const struct sh_dmae_slave_config sh73a0_mpdma_slaves[] = {
+ {
+ .slave_id = SHDMA_SLAVE_FSI2A_RX,
+ .addr = 0xec230020,
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
+ .mid_rid = 0xd6, /* CHECK ME */
+ }, {
+ .slave_id = SHDMA_SLAVE_FSI2A_TX,
+ .addr = 0xec230024,
+ .chcr = CHCR_TX(XMIT_SZ_32BIT),
+ .mid_rid = 0xd5, /* CHECK ME */
+ }, {
+ .slave_id = SHDMA_SLAVE_FSI2C_RX,
+ .addr = 0xec230060,
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
+ .mid_rid = 0xda, /* CHECK ME */
+ }, {
+ .slave_id = SHDMA_SLAVE_FSI2C_TX,
+ .addr = 0xec230064,
+ .chcr = CHCR_TX(XMIT_SZ_32BIT),
+ .mid_rid = 0xd9, /* CHECK ME */
+ }, {
+ .slave_id = SHDMA_SLAVE_FSI2B_RX,
+ .addr = 0xec240020,
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
+ .mid_rid = 0x8e, /* CHECK ME */
+ }, {
+ .slave_id = SHDMA_SLAVE_FSI2B_TX,
+ .addr = 0xec240024,
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
+ .mid_rid = 0x8d, /* CHECK ME */
+ }, {
+ .slave_id = SHDMA_SLAVE_FSI2D_RX,
+ .addr = 0xec240060,
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
+ .mid_rid = 0x9a, /* CHECK ME */
+ },
+};
+
+#define MPDMA_CHANNEL(a, b, c) \
+{ \
+ .offset = a, \
+ .dmars = b, \
+ .dmars_bit = c, \
+ .chclr_offset = (0x220 - 0x20) + a \
+}
+
+static const struct sh_dmae_channel sh73a0_mpdma_channels[] = {
+ MPDMA_CHANNEL(0x00, 0, 0),
+ MPDMA_CHANNEL(0x10, 0, 8),
+ MPDMA_CHANNEL(0x20, 4, 0),
+ MPDMA_CHANNEL(0x30, 4, 8),
+ MPDMA_CHANNEL(0x50, 8, 0),
+ MPDMA_CHANNEL(0x70, 8, 8),
+};
+
+static struct sh_dmae_pdata sh73a0_mpdma_platform_data = {
+ .slave = sh73a0_mpdma_slaves,
+ .slave_num = ARRAY_SIZE(sh73a0_mpdma_slaves),
+ .channel = sh73a0_mpdma_channels,
+ .channel_num = ARRAY_SIZE(sh73a0_mpdma_channels),
+ .ts_low_shift = TS_LOW_SHIFT,
+ .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT,
+ .ts_high_shift = TS_HI_SHIFT,
+ .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT,
+ .ts_shift = dma_ts_shift,
+ .ts_shift_num = ARRAY_SIZE(dma_ts_shift),
+ .dmaor_init = DMAOR_DME,
+ .chclr_present = 1,
+};
+
+/* Resource order important! */
+static struct resource sh73a0_mpdma_resources[] = {
+ /* Channel registers and DMAOR */
+ DEFINE_RES_MEM(0xec618020, 0x270),
+ /* DMARSx */
+ DEFINE_RES_MEM(0xec619000, 0xc),
+ {
+ .name = "error_irq",
+ .start = gic_spi(181),
+ .end = gic_spi(181),
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-5 */
+ .start = gic_spi(175),
+ .end = gic_spi(180),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mpdma0_device = {
+ .name = "sh-dma-engine",
+ .id = 1,
+ .resource = sh73a0_mpdma_resources,
+ .num_resources = ARRAY_SIZE(sh73a0_mpdma_resources),
+ .dev = {
+ .platform_data = &sh73a0_mpdma_platform_data,
+ },
+};
+
+static struct resource pmu_resources[] = {
+ [0] = {
+ .start = gic_spi(55),
+ .end = gic_spi(55),
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = gic_spi(56),
+ .end = gic_spi(56),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pmu_device = {
+ .name = "armv7-pmu",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pmu_resources),
+ .resource = pmu_resources,
+};
+
+/* an IPMMU module for ICB */
+static struct resource ipmmu_resources[] = {
+ DEFINE_RES_MEM(0xfe951000, 0x100),
+};
+
+static const char * const ipmmu_dev_names[] = {
+ "sh_mobile_lcdc_fb.0",
+};
+
+static struct shmobile_ipmmu_platform_data ipmmu_platform_data = {
+ .dev_names = ipmmu_dev_names,
+ .num_dev_names = ARRAY_SIZE(ipmmu_dev_names),
+};
+
+static struct platform_device ipmmu_device = {
+ .name = "ipmmu",
+ .id = -1,
+ .dev = {
+ .platform_data = &ipmmu_platform_data,
+ },
+ .resource = ipmmu_resources,
+ .num_resources = ARRAY_SIZE(ipmmu_resources),
+};
+
+static struct renesas_intc_irqpin_config irqpin0_platform_data = {
+ .irq_base = irq_pin(0), /* IRQ0 -> IRQ7 */
+ .control_parent = true,
+};
+
+static struct resource irqpin0_resources[] = {
+ DEFINE_RES_MEM(0xe6900000, 4), /* ICR1A */
+ DEFINE_RES_MEM(0xe6900010, 4), /* INTPRI00A */
+ DEFINE_RES_MEM(0xe6900020, 1), /* INTREQ00A */
+ DEFINE_RES_MEM(0xe6900040, 1), /* INTMSK00A */
+ DEFINE_RES_MEM(0xe6900060, 1), /* INTMSKCLR00A */
+ DEFINE_RES_IRQ(gic_spi(1)), /* IRQ0 */
+ DEFINE_RES_IRQ(gic_spi(2)), /* IRQ1 */
+ DEFINE_RES_IRQ(gic_spi(3)), /* IRQ2 */
+ DEFINE_RES_IRQ(gic_spi(4)), /* IRQ3 */
+ DEFINE_RES_IRQ(gic_spi(5)), /* IRQ4 */
+ DEFINE_RES_IRQ(gic_spi(6)), /* IRQ5 */
+ DEFINE_RES_IRQ(gic_spi(7)), /* IRQ6 */
+ DEFINE_RES_IRQ(gic_spi(8)), /* IRQ7 */
+};
+
+static struct platform_device irqpin0_device = {
+ .name = "renesas_intc_irqpin",
+ .id = 0,
+ .resource = irqpin0_resources,
+ .num_resources = ARRAY_SIZE(irqpin0_resources),
+ .dev = {
+ .platform_data = &irqpin0_platform_data,
+ },
+};
+
+static struct renesas_intc_irqpin_config irqpin1_platform_data = {
+ .irq_base = irq_pin(8), /* IRQ8 -> IRQ15 */
+ .control_parent = true, /* Disable spurious IRQ10 */
+};
+
+static struct resource irqpin1_resources[] = {
+ DEFINE_RES_MEM(0xe6900004, 4), /* ICR2A */
+ DEFINE_RES_MEM(0xe6900014, 4), /* INTPRI10A */
+ DEFINE_RES_MEM(0xe6900024, 1), /* INTREQ10A */
+ DEFINE_RES_MEM(0xe6900044, 1), /* INTMSK10A */
+ DEFINE_RES_MEM(0xe6900064, 1), /* INTMSKCLR10A */
+ DEFINE_RES_IRQ(gic_spi(9)), /* IRQ8 */
+ DEFINE_RES_IRQ(gic_spi(10)), /* IRQ9 */
+ DEFINE_RES_IRQ(gic_spi(11)), /* IRQ10 */
+ DEFINE_RES_IRQ(gic_spi(12)), /* IRQ11 */
+ DEFINE_RES_IRQ(gic_spi(13)), /* IRQ12 */
+ DEFINE_RES_IRQ(gic_spi(14)), /* IRQ13 */
+ DEFINE_RES_IRQ(gic_spi(15)), /* IRQ14 */
+ DEFINE_RES_IRQ(gic_spi(16)), /* IRQ15 */
+};
+
+static struct platform_device irqpin1_device = {
+ .name = "renesas_intc_irqpin",
+ .id = 1,
+ .resource = irqpin1_resources,
+ .num_resources = ARRAY_SIZE(irqpin1_resources),
+ .dev = {
+ .platform_data = &irqpin1_platform_data,
+ },
+};
+
+static struct renesas_intc_irqpin_config irqpin2_platform_data = {
+ .irq_base = irq_pin(16), /* IRQ16 -> IRQ23 */
+ .control_parent = true,
+};
+
+static struct resource irqpin2_resources[] = {
+ DEFINE_RES_MEM(0xe6900008, 4), /* ICR3A */
+ DEFINE_RES_MEM(0xe6900018, 4), /* INTPRI20A */
+ DEFINE_RES_MEM(0xe6900028, 1), /* INTREQ20A */
+ DEFINE_RES_MEM(0xe6900048, 1), /* INTMSK20A */
+ DEFINE_RES_MEM(0xe6900068, 1), /* INTMSKCLR20A */
+ DEFINE_RES_IRQ(gic_spi(17)), /* IRQ16 */
+ DEFINE_RES_IRQ(gic_spi(18)), /* IRQ17 */
+ DEFINE_RES_IRQ(gic_spi(19)), /* IRQ18 */
+ DEFINE_RES_IRQ(gic_spi(20)), /* IRQ19 */
+ DEFINE_RES_IRQ(gic_spi(21)), /* IRQ20 */
+ DEFINE_RES_IRQ(gic_spi(22)), /* IRQ21 */
+ DEFINE_RES_IRQ(gic_spi(23)), /* IRQ22 */
+ DEFINE_RES_IRQ(gic_spi(24)), /* IRQ23 */
+};
+
+static struct platform_device irqpin2_device = {
+ .name = "renesas_intc_irqpin",
+ .id = 2,
+ .resource = irqpin2_resources,
+ .num_resources = ARRAY_SIZE(irqpin2_resources),
+ .dev = {
+ .platform_data = &irqpin2_platform_data,
+ },
+};
+
+static struct renesas_intc_irqpin_config irqpin3_platform_data = {
+ .irq_base = irq_pin(24), /* IRQ24 -> IRQ31 */
+ .control_parent = true,
+};
+
+static struct resource irqpin3_resources[] = {
+ DEFINE_RES_MEM(0xe690000c, 4), /* ICR4A */
+ DEFINE_RES_MEM(0xe690001c, 4), /* INTPRI30A */
+ DEFINE_RES_MEM(0xe690002c, 1), /* INTREQ30A */
+ DEFINE_RES_MEM(0xe690004c, 1), /* INTMSK30A */
+ DEFINE_RES_MEM(0xe690006c, 1), /* INTMSKCLR30A */
+ DEFINE_RES_IRQ(gic_spi(25)), /* IRQ24 */
+ DEFINE_RES_IRQ(gic_spi(26)), /* IRQ25 */
+ DEFINE_RES_IRQ(gic_spi(27)), /* IRQ26 */
+ DEFINE_RES_IRQ(gic_spi(28)), /* IRQ27 */
+ DEFINE_RES_IRQ(gic_spi(29)), /* IRQ28 */
+ DEFINE_RES_IRQ(gic_spi(30)), /* IRQ29 */
+ DEFINE_RES_IRQ(gic_spi(31)), /* IRQ30 */
+ DEFINE_RES_IRQ(gic_spi(32)), /* IRQ31 */
+};
+
+static struct platform_device irqpin3_device = {
+ .name = "renesas_intc_irqpin",
+ .id = 3,
+ .resource = irqpin3_resources,
+ .num_resources = ARRAY_SIZE(irqpin3_resources),
+ .dev = {
+ .platform_data = &irqpin3_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,
+ &tmu0_device,
+ &ipmmu_device,
+ &cmt1_device,
+};
+
+static struct platform_device *sh73a0_late_devices[] __initdata = {
+ &i2c0_device,
+ &i2c1_device,
+ &i2c2_device,
+ &i2c3_device,
+ &i2c4_device,
+ &dma0_device,
+ &mpdma0_device,
+ &pmu_device,
+ &irqpin0_device,
+ &irqpin1_device,
+ &irqpin2_device,
+ &irqpin3_device,
+};
+
+#define SRCR2 IOMEM(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));
+}
+
+/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
+void __init __weak sh73a0_register_twd(void) { }
+
+void __init sh73a0_earlytimer_init(void)
+{
+ shmobile_init_delay();
+#ifndef CONFIG_COMMON_CLK
+ sh73a0_clock_init();
+#endif
+ shmobile_earlytimer_init();
+ sh73a0_register_twd();
+}
+
+void __init sh73a0_add_early_devices(void)
+{
+ early_platform_add_devices(sh73a0_early_devices,
+ ARRAY_SIZE(sh73a0_early_devices));
+
+ /* setup early console here as well */
+ shmobile_setup_console();
+}
+
+#ifdef CONFIG_USE_OF
+
+static void __init sh73a0_generic_init(void)
+{
+#ifdef CONFIG_CACHE_L2X0
+ /* Shared attribute override enable, 64K*8way */
+ l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff);
+#endif
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char *sh73a0_boards_compat_dt[] __initdata = {
+ "renesas,sh73a0",
+ NULL,
+};
+
+DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)")
+ .smp = smp_ops(sh73a0_smp_ops),
+ .map_io = sh73a0_map_io,
+ .init_early = shmobile_init_delay,
+ .init_machine = sh73a0_generic_init,
+ .init_late = shmobile_init_late,
+ .dt_compat = sh73a0_boards_compat_dt,
+MACHINE_END
+#endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/sh-gpio.h b/arch/arm/mach-shmobile/sh-gpio.h
new file mode 100644
index 000000000..2c4141413
--- /dev/null
+++ b/arch/arm/mach-shmobile/sh-gpio.h
@@ -0,0 +1,29 @@
+/*
+ * 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>
+#include <linux/io.h>
+
+/*
+ * FIXME !!
+ *
+ * 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 inline void __init gpio_direction_none(void __iomem * addr)
+{
+ __raw_writeb(0x00, addr);
+}
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-shmobile/sh73a0.h b/arch/arm/mach-shmobile/sh73a0.h
new file mode 100644
index 000000000..5a80f18b4
--- /dev/null
+++ b/arch/arm/mach-shmobile/sh73a0.h
@@ -0,0 +1,89 @@
+#ifndef __ASM_SH73A0_H__
+#define __ASM_SH73A0_H__
+
+/* 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,
+ SHDMA_SLAVE_FSI2A_TX,
+ SHDMA_SLAVE_FSI2A_RX,
+ SHDMA_SLAVE_FSI2B_TX,
+ SHDMA_SLAVE_FSI2B_RX,
+ SHDMA_SLAVE_FSI2C_TX,
+ SHDMA_SLAVE_FSI2C_RX,
+ SHDMA_SLAVE_FSI2D_RX,
+};
+
+/*
+ * SH73A0 IRQ LOCATION TABLE
+ *
+ * 416 -----------------------------------------
+ * IRQ0-IRQ15
+ * 431 -----------------------------------------
+ * ...
+ * 448 -----------------------------------------
+ * sh73a0-intcs
+ * sh73a0-intca-irq-pins
+ * 680 -----------------------------------------
+ * ...
+ * 700 -----------------------------------------
+ * sh73a0-pint0
+ * 731 -----------------------------------------
+ * 732 -----------------------------------------
+ * sh73a0-pint1
+ * 739 -----------------------------------------
+ * ...
+ * 800 -----------------------------------------
+ * IRQ16-IRQ31
+ * 815 -----------------------------------------
+ * ...
+ * 928 -----------------------------------------
+ * sh73a0-intca-irq-pins
+ * 943 -----------------------------------------
+ */
+
+/* PINT interrupts are located at Linux IRQ 700 and up */
+#define SH73A0_PINT0_IRQ(irq) ((irq) + 700)
+#define SH73A0_PINT1_IRQ(irq) ((irq) + 732)
+
+extern void sh73a0_init_irq(void);
+extern void sh73a0_init_irq_dt(void);
+extern void sh73a0_map_io(void);
+extern void sh73a0_earlytimer_init(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 void sh73a0_pm_init(void);
+extern struct clk sh73a0_extal1_clk;
+extern struct clk sh73a0_extal2_clk;
+extern struct clk sh73a0_extcki_clk;
+extern struct clk sh73a0_extalr_clk;
+extern struct smp_operations sh73a0_smp_ops;
+
+#endif /* __ASM_SH73A0_H__ */
diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c
new file mode 100644
index 000000000..baff3b5ef
--- /dev/null
+++ b/arch/arm/mach-shmobile/smp-emev2.c
@@ -0,0 +1,55 @@
+/*
+ * SMP support for Emma Mobile EV2
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ * Copyright (C) 2012 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+#include "common.h"
+
+#define EMEV2_SCU_BASE 0x1e000000
+#define EMEV2_SMU_BASE 0xe0110000
+#define SMU_GENERAL_REG0 0x7c0
+
+static int emev2_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu_logical_map(cpu)));
+ return 0;
+}
+
+static void __init emev2_smp_prepare_cpus(unsigned int max_cpus)
+{
+ void __iomem *smu;
+
+ /* Tell ROM loader about our vector (in headsmp.S) */
+ smu = ioremap(EMEV2_SMU_BASE, PAGE_SIZE);
+ if (smu) {
+ iowrite32(__pa(shmobile_boot_vector), smu + SMU_GENERAL_REG0);
+ iounmap(smu);
+ }
+
+ /* setup EMEV2 specific SCU bits */
+ shmobile_scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE);
+ shmobile_smp_scu_prepare_cpus(max_cpus);
+}
+
+struct smp_operations emev2_smp_ops __initdata = {
+ .smp_prepare_cpus = emev2_smp_prepare_cpus,
+ .smp_boot_secondary = emev2_boot_secondary,
+};
diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c
new file mode 100644
index 000000000..01f792fcb
--- /dev/null
+++ b/arch/arm/mach-shmobile/smp-r8a7779.c
@@ -0,0 +1,136 @@
+/*
+ * SMP support for R-Mobile / SH-Mobile - r8a7779 portion
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+#include <asm/smp_twd.h>
+
+#include "common.h"
+#include "pm-rcar.h"
+#include "r8a7779.h"
+
+#define AVECR IOMEM(0xfe700040)
+#define R8A7779_SCU_BASE 0xf0000000
+
+static struct rcar_sysc_ch r8a7779_ch_cpu1 = {
+ .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
+ .chan_bit = 1, /* ARM1 */
+ .isr_bit = 1, /* ARM1 */
+};
+
+static struct rcar_sysc_ch r8a7779_ch_cpu2 = {
+ .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
+ .chan_bit = 2, /* ARM2 */
+ .isr_bit = 2, /* ARM2 */
+};
+
+static struct rcar_sysc_ch r8a7779_ch_cpu3 = {
+ .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
+ .chan_bit = 3, /* ARM3 */
+ .isr_bit = 3, /* ARM3 */
+};
+
+static struct rcar_sysc_ch *r8a7779_ch_cpu[4] = {
+ [1] = &r8a7779_ch_cpu1,
+ [2] = &r8a7779_ch_cpu2,
+ [3] = &r8a7779_ch_cpu3,
+};
+
+#if defined(CONFIG_HAVE_ARM_TWD) && !defined(CONFIG_ARCH_MULTIPLATFORM)
+static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, R8A7779_SCU_BASE + 0x600, 29);
+void __init r8a7779_register_twd(void)
+{
+ twd_local_timer_register(&twd_local_timer);
+}
+#endif
+
+static int r8a7779_platform_cpu_kill(unsigned int cpu)
+{
+ struct rcar_sysc_ch *ch = NULL;
+ int ret = -EIO;
+
+ cpu = cpu_logical_map(cpu);
+
+ if (cpu < ARRAY_SIZE(r8a7779_ch_cpu))
+ ch = r8a7779_ch_cpu[cpu];
+
+ if (ch)
+ ret = rcar_sysc_power_down(ch);
+
+ return ret ? ret : 1;
+}
+
+static int r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ struct rcar_sysc_ch *ch = NULL;
+ unsigned int lcpu = cpu_logical_map(cpu);
+ int ret;
+
+ if (lcpu < ARRAY_SIZE(r8a7779_ch_cpu))
+ ch = r8a7779_ch_cpu[lcpu];
+
+ if (ch)
+ ret = rcar_sysc_power_up(ch);
+ else
+ ret = -EIO;
+
+ return ret;
+}
+
+static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus)
+{
+ /* Map the reset vector (in headsmp-scu.S, headsmp.S) */
+ __raw_writel(__pa(shmobile_boot_vector), AVECR);
+ shmobile_boot_fn = virt_to_phys(shmobile_boot_scu);
+ shmobile_boot_arg = (unsigned long)shmobile_scu_base;
+
+ /* setup r8a7779 specific SCU bits */
+ shmobile_scu_base = IOMEM(R8A7779_SCU_BASE);
+ shmobile_smp_scu_prepare_cpus(max_cpus);
+
+ r8a7779_pm_init();
+
+ /* power off secondary CPUs */
+ r8a7779_platform_cpu_kill(1);
+ r8a7779_platform_cpu_kill(2);
+ r8a7779_platform_cpu_kill(3);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static int r8a7779_cpu_kill(unsigned int cpu)
+{
+ if (shmobile_smp_scu_cpu_kill(cpu))
+ return r8a7779_platform_cpu_kill(cpu);
+
+ return 0;
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
+struct smp_operations r8a7779_smp_ops __initdata = {
+ .smp_prepare_cpus = r8a7779_smp_prepare_cpus,
+ .smp_boot_secondary = r8a7779_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = shmobile_smp_scu_cpu_die,
+ .cpu_kill = r8a7779_cpu_kill,
+#endif
+};
diff --git a/arch/arm/mach-shmobile/smp-r8a7790.c b/arch/arm/mach-shmobile/smp-r8a7790.c
new file mode 100644
index 000000000..930f45cbc
--- /dev/null
+++ b/arch/arm/mach-shmobile/smp-r8a7790.c
@@ -0,0 +1,71 @@
+/*
+ * SMP support for r8a7790
+ *
+ * Copyright (C) 2012-2013 Renesas Solutions Corp.
+ * Copyright (C) 2012 Takashi Yoshii <takashi.yoshii.ze@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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/smp_plat.h>
+
+#include "common.h"
+#include "platsmp-apmu.h"
+#include "pm-rcar.h"
+#include "rcar-gen2.h"
+#include "r8a7790.h"
+
+static struct rcar_sysc_ch r8a7790_ca15_scu = {
+ .chan_offs = 0x180, /* PWRSR5 .. PWRER5 */
+ .isr_bit = 12, /* CA15-SCU */
+};
+
+static struct rcar_sysc_ch r8a7790_ca7_scu = {
+ .chan_offs = 0x100, /* PWRSR3 .. PWRER3 */
+ .isr_bit = 21, /* CA7-SCU */
+};
+
+static struct rcar_apmu_config r8a7790_apmu_config[] = {
+ {
+ .iomem = DEFINE_RES_MEM(0xe6152000, 0x188),
+ .cpus = { 0, 1, 2, 3 },
+ },
+ {
+ .iomem = DEFINE_RES_MEM(0xe6151000, 0x188),
+ .cpus = { 0x100, 0x0101, 0x102, 0x103 },
+ }
+};
+
+static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus)
+{
+ /* let APMU code install data related to shmobile_boot_vector */
+ shmobile_smp_apmu_prepare_cpus(max_cpus,
+ r8a7790_apmu_config,
+ ARRAY_SIZE(r8a7790_apmu_config));
+
+ /* turn on power to SCU */
+ rcar_gen2_pm_init();
+ rcar_sysc_power_up(&r8a7790_ca15_scu);
+ rcar_sysc_power_up(&r8a7790_ca7_scu);
+}
+
+struct smp_operations r8a7790_smp_ops __initdata = {
+ .smp_prepare_cpus = r8a7790_smp_prepare_cpus,
+ .smp_boot_secondary = shmobile_smp_apmu_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_disable = shmobile_smp_cpu_disable,
+ .cpu_die = shmobile_smp_apmu_cpu_die,
+ .cpu_kill = shmobile_smp_apmu_cpu_kill,
+#endif
+};
diff --git a/arch/arm/mach-shmobile/smp-r8a7791.c b/arch/arm/mach-shmobile/smp-r8a7791.c
new file mode 100644
index 000000000..5e2d1db79
--- /dev/null
+++ b/arch/arm/mach-shmobile/smp-r8a7791.c
@@ -0,0 +1,65 @@
+/*
+ * SMP support for r8a7791
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/smp_plat.h>
+
+#include "common.h"
+#include "platsmp-apmu.h"
+#include "r8a7791.h"
+#include "rcar-gen2.h"
+
+static struct rcar_apmu_config r8a7791_apmu_config[] = {
+ {
+ .iomem = DEFINE_RES_MEM(0xe6152000, 0x188),
+ .cpus = { 0, 1 },
+ }
+};
+
+static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus)
+{
+ /* let APMU code install data related to shmobile_boot_vector */
+ shmobile_smp_apmu_prepare_cpus(max_cpus,
+ r8a7791_apmu_config,
+ ARRAY_SIZE(r8a7791_apmu_config));
+
+ rcar_gen2_pm_init();
+}
+
+static int r8a7791_smp_boot_secondary(unsigned int cpu,
+ struct task_struct *idle)
+{
+ /* Error out when hardware debug mode is enabled */
+ if (rcar_gen2_read_mode_pins() & BIT(21)) {
+ pr_warn("Unable to boot CPU%u when MD21 is set\n", cpu);
+ return -ENOTSUPP;
+ }
+
+ return shmobile_smp_apmu_boot_secondary(cpu, idle);
+}
+
+struct smp_operations r8a7791_smp_ops __initdata = {
+ .smp_prepare_cpus = r8a7791_smp_prepare_cpus,
+ .smp_boot_secondary = r8a7791_smp_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_disable = shmobile_smp_cpu_disable,
+ .cpu_die = shmobile_smp_apmu_cpu_die,
+ .cpu_kill = shmobile_smp_apmu_cpu_kill,
+#endif
+};
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
new file mode 100644
index 000000000..2106d6b76
--- /dev/null
+++ b/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include <asm/smp_plat.h>
+#include <asm/smp_twd.h>
+
+#include "common.h"
+#include "sh73a0.h"
+
+#define WUPCR IOMEM(0xe6151010)
+#define SRESCR IOMEM(0xe6151018)
+#define PSTR IOMEM(0xe6151040)
+#define SBAR IOMEM(0xe6180020)
+#define APARMBAREA IOMEM(0xe6f10020)
+
+#define SH73A0_SCU_BASE 0xf0000000
+
+#if defined(CONFIG_HAVE_ARM_TWD) && !defined(CONFIG_ARCH_MULTIPLATFORM)
+static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, SH73A0_SCU_BASE + 0x600, 29);
+void __init sh73a0_register_twd(void)
+{
+ twd_local_timer_register(&twd_local_timer);
+}
+#endif
+
+static int sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ unsigned int lcpu = cpu_logical_map(cpu);
+
+ if (((__raw_readl(PSTR) >> (4 * lcpu)) & 3) == 3)
+ __raw_writel(1 << lcpu, WUPCR); /* wake up */
+ else
+ __raw_writel(1 << lcpu, SRESCR); /* reset */
+
+ return 0;
+}
+
+static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus)
+{
+ /* Map the reset vector (in headsmp.S) */
+ __raw_writel(0, APARMBAREA); /* 4k */
+ __raw_writel(__pa(shmobile_boot_vector), SBAR);
+
+ /* setup sh73a0 specific SCU bits */
+ shmobile_scu_base = IOMEM(SH73A0_SCU_BASE);
+ shmobile_smp_scu_prepare_cpus(max_cpus);
+}
+
+struct smp_operations sh73a0_smp_ops __initdata = {
+ .smp_prepare_cpus = sh73a0_smp_prepare_cpus,
+ .smp_boot_secondary = sh73a0_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_disable = shmobile_smp_cpu_disable,
+ .cpu_die = shmobile_smp_scu_cpu_die,
+ .cpu_kill = shmobile_smp_scu_cpu_kill,
+#endif
+};
diff --git a/arch/arm/mach-shmobile/suspend.c b/arch/arm/mach-shmobile/suspend.c
new file mode 100644
index 000000000..5d92b5dd4
--- /dev/null
+++ b/arch/arm/mach-shmobile/suspend.c
@@ -0,0 +1,48 @@
+/*
+ * 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 <linux/cpu.h>
+
+#include <asm/io.h>
+#include <asm/system_misc.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)
+{
+ cpu_idle_poll_ctrl(true);
+ return 0;
+}
+
+static void shmobile_suspend_end(void)
+{
+ cpu_idle_poll_ctrl(false);
+}
+
+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,
+};
+
+int __init shmobile_suspend_init(void)
+{
+ suspend_set_ops(&shmobile_suspend_ops);
+ return 0;
+}
diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c
new file mode 100644
index 000000000..0edf2a6d2
--- /dev/null
+++ b/arch/arm/mach-shmobile/timer.c
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+#include <linux/platform_device.h>
+#include <linux/clocksource.h>
+#include <linux/delay.h>
+#include <linux/of_address.h>
+
+static void __init shmobile_setup_delay_hz(unsigned int max_cpu_core_hz,
+ unsigned int mult, unsigned int div)
+{
+ /* calculate a worst-case loops-per-jiffy value
+ * based on maximum cpu core hz setting and the
+ * __delay() implementation in arch/arm/lib/delay.S
+ *
+ * this will result in a longer delay than expected
+ * when the cpu core runs on lower frequencies.
+ */
+
+ unsigned int value = HZ * div / mult;
+
+ if (!preset_lpj)
+ preset_lpj = max_cpu_core_hz / value;
+}
+
+void __init shmobile_init_delay(void)
+{
+ struct device_node *np, *cpus;
+ bool is_a7_a8_a9 = false;
+ bool is_a15 = false;
+ bool has_arch_timer = false;
+ u32 max_freq = 0;
+
+ cpus = of_find_node_by_path("/cpus");
+ if (!cpus)
+ return;
+
+ for_each_child_of_node(cpus, np) {
+ u32 freq;
+
+ if (!of_property_read_u32(np, "clock-frequency", &freq))
+ max_freq = max(max_freq, freq);
+
+ if (of_device_is_compatible(np, "arm,cortex-a8") ||
+ of_device_is_compatible(np, "arm,cortex-a9")) {
+ is_a7_a8_a9 = true;
+ } else if (of_device_is_compatible(np, "arm,cortex-a7")) {
+ is_a7_a8_a9 = true;
+ has_arch_timer = true;
+ } else if (of_device_is_compatible(np, "arm,cortex-a15")) {
+ is_a15 = true;
+ has_arch_timer = true;
+ }
+ }
+
+ of_node_put(cpus);
+
+ if (!max_freq)
+ return;
+
+#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
+ /* Non-multiplatform r8a73a4 SoC cannot use arch timer due
+ * to GIC being initialized from C and arch timer via DT */
+ if (of_machine_is_compatible("renesas,r8a73a4"))
+ has_arch_timer = false;
+
+ /* Non-multiplatform r8a7790 SoC cannot use arch timer due
+ * to GIC being initialized from C and arch timer via DT */
+ if (of_machine_is_compatible("renesas,r8a7790"))
+ has_arch_timer = false;
+#endif
+
+ if (!has_arch_timer || !IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) {
+ if (is_a7_a8_a9)
+ shmobile_setup_delay_hz(max_freq, 1, 3);
+ else if (is_a15)
+ shmobile_setup_delay_hz(max_freq, 2, 4);
+ }
+}
+
+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);
+}
+
+void __init shmobile_earlytimer_init(void)
+{
+ late_time_init = shmobile_late_time_init;
+}
+
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
new file mode 100644
index 000000000..b5f8d75d5
--- /dev/null
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -0,0 +1,10 @@
+config ARCH_SOCFPGA
+ bool "Altera SOCFPGA family" if ARCH_MULTI_V7
+ select ARM_AMBA
+ select ARM_GIC
+ select CACHE_L2X0
+ select DW_APB_TIMER_OF
+ select GPIO_PL061 if GPIOLIB
+ select HAVE_ARM_SCU
+ select HAVE_ARM_TWD if SMP
+ select MFD_SYSCON
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
new file mode 100644
index 000000000..6dd7a93a9
--- /dev/null
+++ b/arch/arm/mach-socfpga/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := socfpga.o
+obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h
new file mode 100644
index 000000000..a0f3b1cd4
--- /dev/null
+++ b/arch/arm/mach-socfpga/core.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012 Pavel Machek <pavel@denx.de>
+ * Copyright (C) 2012 Altera 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 __MACH_CORE_H
+#define __MACH_CORE_H
+
+#define SOCFPGA_RSTMGR_CTRL 0x04
+#define SOCFPGA_RSTMGR_MODMPURST 0x10
+#define SOCFPGA_RSTMGR_MODPERRST 0x14
+#define SOCFPGA_RSTMGR_BRGMODRST 0x1c
+
+/* System Manager bits */
+#define RSTMGR_CTRL_SWCOLDRSTREQ 0x1 /* Cold Reset */
+#define RSTMGR_CTRL_SWWARMRSTREQ 0x2 /* Warm Reset */
+
+#define RSTMGR_MPUMODRST_CPU1 0x2 /* CPU1 Reset */
+
+extern void socfpga_secondary_startup(void);
+extern void __iomem *socfpga_scu_base_addr;
+
+extern void socfpga_init_clocks(void);
+extern void socfpga_sysmgr_init(void);
+
+extern void __iomem *sys_manager_base_addr;
+extern void __iomem *rst_manager_base_addr;
+
+extern struct smp_operations socfpga_smp_ops;
+extern char secondary_trampoline, secondary_trampoline_end;
+
+extern unsigned long socfpga_cpu1start_addr;
+
+#define SOCFPGA_SCU_VIRT_BASE 0xfee00000
+
+#endif
diff --git a/arch/arm/mach-socfpga/headsmp.S b/arch/arm/mach-socfpga/headsmp.S
new file mode 100644
index 000000000..f65ea0af4
--- /dev/null
+++ b/arch/arm/mach-socfpga/headsmp.S
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2003 ARM Limited
+ * Copyright (c) u-boot contributors
+ * Copyright (c) 2012 Pavel Machek <pavel@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/linkage.h>
+#include <linux/init.h>
+#include <asm/memory.h>
+
+ .arch armv7-a
+
+ENTRY(secondary_trampoline)
+ /* CPU1 will always fetch from 0x0 when it is brought out of reset.
+ * Thus, we can just subtract the PAGE_OFFSET to get the physical
+ * address of &cpu1start_addr. This would not work for platforms
+ * where the physical memory does not start at 0x0.
+ */
+ adr r0, 1f
+ ldmia r0, {r1, r2}
+ sub r2, r2, #PAGE_OFFSET
+ ldr r3, [r2]
+ ldr r4, [r3]
+ bx r4
+
+ .align
+1: .long .
+ .long socfpga_cpu1start_addr
+ENTRY(secondary_trampoline_end)
+
+ENTRY(socfpga_secondary_startup)
+ bl v7_invalidate_l1
+ b secondary_startup
+ENDPROC(socfpga_secondary_startup)
diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c
new file mode 100644
index 000000000..c64d89b7c
--- /dev/null
+++ b/arch/arm/mach-socfpga/platsmp.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2010-2011 Calxeda, Inc.
+ * Copyright 2012 Pavel Machek <pavel@denx.de>
+ * Based on platsmp.c, Copyright (C) 2002 ARM Ltd.
+ * Copyright (C) 2012 Altera 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_scu.h>
+#include <asm/smp_plat.h>
+
+#include "core.h"
+
+static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ int trampoline_size = &secondary_trampoline_end - &secondary_trampoline;
+
+ if (socfpga_cpu1start_addr) {
+ /* This will put CPU #1 into reset. */
+ writel(RSTMGR_MPUMODRST_CPU1,
+ rst_manager_base_addr + SOCFPGA_RSTMGR_MODMPURST);
+
+ memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size);
+
+ writel(virt_to_phys(socfpga_secondary_startup),
+ sys_manager_base_addr + (socfpga_cpu1start_addr & 0x000000ff));
+
+ flush_cache_all();
+ smp_wmb();
+ outer_clean_range(0, trampoline_size);
+
+ /* This will release CPU #1 out of reset. */
+ writel(0, rst_manager_base_addr + SOCFPGA_RSTMGR_MODMPURST);
+ }
+
+ return 0;
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+static void __init socfpga_smp_init_cpus(void)
+{
+ unsigned int i, ncores;
+
+ ncores = scu_get_core_count(socfpga_scu_base_addr);
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+
+ /* sanity check */
+ if (ncores > num_possible_cpus()) {
+ pr_warn("socfpga: no. of cores (%d) greater than configured"
+ "maximum of %d - clipping\n", ncores, num_possible_cpus());
+ ncores = num_possible_cpus();
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+}
+
+static void __init socfpga_smp_prepare_cpus(unsigned int max_cpus)
+{
+ scu_enable(socfpga_scu_base_addr);
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+static void socfpga_cpu_die(unsigned int cpu)
+{
+ /* Do WFI. If we wake up early, go back into WFI */
+ while (1)
+ cpu_do_idle();
+}
+
+struct smp_operations socfpga_smp_ops __initdata = {
+ .smp_init_cpus = socfpga_smp_init_cpus,
+ .smp_prepare_cpus = socfpga_smp_prepare_cpus,
+ .smp_boot_secondary = socfpga_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = socfpga_cpu_die,
+#endif
+};
diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c
new file mode 100644
index 000000000..f5e597c20
--- /dev/null
+++ b/arch/arm/mach-socfpga/socfpga.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2012 Altera 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/irqchip.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/reboot.h>
+
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/cacheflush.h>
+
+#include "core.h"
+
+void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE));
+void __iomem *sys_manager_base_addr;
+void __iomem *rst_manager_base_addr;
+unsigned long socfpga_cpu1start_addr;
+
+static struct map_desc scu_io_desc __initdata = {
+ .virtual = SOCFPGA_SCU_VIRT_BASE,
+ .pfn = 0, /* run-time */
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+};
+
+static struct map_desc uart_io_desc __initdata = {
+ .virtual = 0xfec02000,
+ .pfn = __phys_to_pfn(0xffc02000),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+};
+
+static void __init socfpga_scu_map_io(void)
+{
+ unsigned long base;
+
+ /* Get SCU base */
+ asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
+
+ scu_io_desc.pfn = __phys_to_pfn(base);
+ iotable_init(&scu_io_desc, 1);
+}
+
+static void __init socfpga_map_io(void)
+{
+ socfpga_scu_map_io();
+ iotable_init(&uart_io_desc, 1);
+ early_printk("Early printk initialized\n");
+}
+
+void __init socfpga_sysmgr_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr");
+
+ if (of_property_read_u32(np, "cpu1-start-addr",
+ (u32 *) &socfpga_cpu1start_addr))
+ pr_err("SMP: Need cpu1-start-addr in device tree.\n");
+
+ /* Ensure that socfpga_cpu1start_addr is visible to other CPUs */
+ smp_wmb();
+ sync_cache_w(&socfpga_cpu1start_addr);
+
+ sys_manager_base_addr = of_iomap(np, 0);
+
+ np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr");
+ rst_manager_base_addr = of_iomap(np, 0);
+}
+
+static void __init socfpga_init_irq(void)
+{
+ irqchip_init();
+ socfpga_sysmgr_init();
+}
+
+static void socfpga_cyclone5_restart(enum reboot_mode mode, const char *cmd)
+{
+ u32 temp;
+
+ temp = readl(rst_manager_base_addr + SOCFPGA_RSTMGR_CTRL);
+
+ if (mode == REBOOT_HARD)
+ temp |= RSTMGR_CTRL_SWCOLDRSTREQ;
+ else
+ temp |= RSTMGR_CTRL_SWWARMRSTREQ;
+ writel(temp, rst_manager_base_addr + SOCFPGA_RSTMGR_CTRL);
+}
+
+static const char *altera_dt_match[] = {
+ "altr,socfpga",
+ NULL
+};
+
+DT_MACHINE_START(SOCFPGA, "Altera SOCFPGA")
+ .l2c_aux_val = 0,
+ .l2c_aux_mask = ~0,
+ .smp = smp_ops(socfpga_smp_ops),
+ .map_io = socfpga_map_io,
+ .init_irq = socfpga_init_irq,
+ .restart = socfpga_cyclone5_restart,
+ .dt_compat = altera_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-spear/Kconfig b/arch/arm/mach-spear/Kconfig
new file mode 100644
index 000000000..b6f4bda27
--- /dev/null
+++ b/arch/arm/mach-spear/Kconfig
@@ -0,0 +1,95 @@
+#
+# SPEAr Platform configuration file
+#
+
+menuconfig PLAT_SPEAR
+ bool "ST SPEAr Family" if ARCH_MULTI_V7 || ARCH_MULTI_V5
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_AMBA
+ select CLKSRC_MMIO
+
+if PLAT_SPEAR
+
+config ARCH_SPEAR13XX
+ bool "ST SPEAr13xx"
+ depends on ARCH_MULTI_V7
+ select ARM_GIC
+ select GPIO_SPEAR_SPICS
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select PINCTRL
+ select MFD_SYSCON
+ select MIGHT_HAVE_PCI
+ help
+ Supports for ARM's SPEAR13XX family
+
+if ARCH_SPEAR13XX
+
+config MACH_SPEAR1310
+ bool "SPEAr1310 Machine support with Device Tree"
+ select PINCTRL_SPEAR1310
+ select PHY_ST_SPEAR1310_MIPHY
+ help
+ Supports ST SPEAr1310 machine configured via the device-tree
+
+config MACH_SPEAR1340
+ bool "SPEAr1340 Machine support with Device Tree"
+ select PINCTRL_SPEAR1340
+ select PHY_ST_SPEAR1340_MIPHY
+ help
+ Supports ST SPEAr1340 machine configured via the device-tree
+
+endif #ARCH_SPEAR13XX
+
+config ARCH_SPEAR3XX
+ bool "ST SPEAr3xx"
+ depends on ARCH_MULTI_V5
+ depends on !ARCH_SPEAR13XX
+ select ARM_VIC
+ select PINCTRL
+ help
+ Supports for ARM's SPEAR3XX family
+
+if ARCH_SPEAR3XX
+
+config MACH_SPEAR300
+ bool "SPEAr300 Machine support with Device Tree"
+ select PINCTRL_SPEAR300
+ help
+ Supports ST SPEAr300 machine configured via the device-tree
+
+config MACH_SPEAR310
+ bool "SPEAr310 Machine support with Device Tree"
+ select PINCTRL_SPEAR310
+ help
+ Supports ST SPEAr310 machine configured via the device-tree
+
+config MACH_SPEAR320
+ bool "SPEAr320 Machine support with Device Tree"
+ select PINCTRL_SPEAR320
+ help
+ Supports ST SPEAr320 machine configured via the device-tree
+
+endif
+
+config ARCH_SPEAR6XX
+ bool "ST SPEAr6XX"
+ depends on ARCH_MULTI_V5
+ depends on !ARCH_SPEAR13XX
+ select ARM_VIC
+ help
+ Supports for ARM's SPEAR6XX family
+
+config MACH_SPEAR600
+ def_bool y
+ depends on ARCH_SPEAR6XX
+ help
+ Supports ST SPEAr600 boards configured via the device-tree
+
+config ARCH_SPEAR_AUTO
+ bool
+ depends on !ARCH_SPEAR13XX && !ARCH_SPEAR6XX
+ select ARCH_SPEAR3XX
+
+endif
+
diff --git a/arch/arm/mach-spear/Makefile b/arch/arm/mach-spear/Makefile
new file mode 100644
index 000000000..a946c19ab
--- /dev/null
+++ b/arch/arm/mach-spear/Makefile
@@ -0,0 +1,26 @@
+#
+# SPEAr Platform specific Makefile
+#
+
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
+
+# Common support
+obj-y := restart.o time.o
+
+smp-$(CONFIG_SMP) += headsmp.o platsmp.o
+smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+
+obj-$(CONFIG_ARCH_SPEAR13XX) += spear13xx.o $(smp-y)
+obj-$(CONFIG_MACH_SPEAR1310) += spear1310.o
+obj-$(CONFIG_MACH_SPEAR1340) += spear1340.o
+
+obj-$(CONFIG_ARCH_SPEAR3XX) += spear3xx.o
+obj-$(CONFIG_ARCH_SPEAR3XX) += pl080.o
+obj-$(CONFIG_MACH_SPEAR300) += spear300.o
+obj-$(CONFIG_MACH_SPEAR310) += spear310.o
+obj-$(CONFIG_MACH_SPEAR320) += spear320.o
+
+obj-$(CONFIG_ARCH_SPEAR6XX) += spear6xx.o
+obj-$(CONFIG_ARCH_SPEAR6XX) += pl080.o
+
+CFLAGS_hotplug.o += -march=armv7-a
diff --git a/arch/arm/mach-spear/Makefile.boot b/arch/arm/mach-spear/Makefile.boot
new file mode 100644
index 000000000..4674a4c22
--- /dev/null
+++ b/arch/arm/mach-spear/Makefile.boot
@@ -0,0 +1,3 @@
+zreladdr-y += 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
diff --git a/arch/arm/mach-spear/generic.h b/arch/arm/mach-spear/generic.h
new file mode 100644
index 000000000..a99d90a4d
--- /dev/null
+++ b/arch/arm/mach-spear/generic.h
@@ -0,0 +1,56 @@
+/*
+ * spear machine family generic header file
+ *
+ * Copyright (C) 2009-2012 ST Microelectronics
+ * Rajeev Kumar <rajeev-dlh.kumar@st.com>
+ * Viresh Kumar <viresh.linux@gmail.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/dmaengine.h>
+#include <linux/amba/pl08x.h>
+#include <linux/init.h>
+#include <linux/reboot.h>
+
+#include <asm/mach/time.h>
+
+extern void spear13xx_timer_init(void);
+extern void spear3xx_timer_init(void);
+extern struct pl022_ssp_controller pl022_plat_data;
+extern struct pl08x_platform_data pl080_plat_data;
+
+void __init spear_setup_of_timer(void);
+void __init spear3xx_clk_init(void __iomem *misc_base,
+ void __iomem *soc_config_base);
+void __init spear3xx_map_io(void);
+void __init spear3xx_dt_init_irq(void);
+void __init spear6xx_clk_init(void __iomem *misc_base);
+void __init spear13xx_map_io(void);
+void __init spear13xx_l2x0_init(void);
+
+void spear_restart(enum reboot_mode, const char *);
+
+void spear13xx_secondary_startup(void);
+void spear13xx_cpu_die(unsigned int cpu);
+
+extern struct smp_operations spear13xx_smp_ops;
+
+#ifdef CONFIG_MACH_SPEAR1310
+void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base);
+#else
+static inline void spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base) {}
+#endif
+
+#ifdef CONFIG_MACH_SPEAR1340
+void __init spear1340_clk_init(void __iomem *misc_base);
+#else
+static inline void spear1340_clk_init(void __iomem *misc_base) {}
+#endif
+
+#endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear/headsmp.S b/arch/arm/mach-spear/headsmp.S
new file mode 100644
index 000000000..c52192dc3
--- /dev/null
+++ b/arch/arm/mach-spear/headsmp.S
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/mach-spear13XX/headsmp.S
+ *
+ * Picked from realview
+ * Copyright (c) 2012 ST Microelectronics Limited
+ * Shiraz Hashim <shiraz.linux.kernel@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/linkage.h>
+#include <linux/init.h>
+
+ __INIT
+
+/*
+ * spear13xx 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(spear13xx_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
+
+ /* re-enable coherency */
+ mrc p15, 0, r0, c1, c0, 1
+ orr r0, r0, #(1 << 6) | (1 << 0)
+ mcr p15, 0, r0, c1, c0, 1
+ /*
+ * 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
+ENDPROC(spear13xx_secondary_startup)
diff --git a/arch/arm/mach-spear/hotplug.c b/arch/arm/mach-spear/hotplug.c
new file mode 100644
index 000000000..d97749c64
--- /dev/null
+++ b/arch/arm/mach-spear/hotplug.c
@@ -0,0 +1,101 @@
+/*
+ * linux/arch/arm/mach-spear13xx/hotplug.c
+ *
+ * Copyright (C) 2012 ST Microelectronics Ltd.
+ * Deepak Sikri <deepak.sikri@st.com>
+ *
+ * based upon linux/arch/arm/mach-realview/hotplug.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/errno.h>
+#include <linux/smp.h>
+#include <asm/cp15.h>
+#include <asm/smp_plat.h>
+
+static inline void cpu_enter_lowpower(void)
+{
+ unsigned int v;
+
+ asm volatile(
+ " mcr p15, 0, %1, c7, c5, 0\n"
+ " dsb\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", "memory");
+}
+
+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 spear13xx_do_lowpower(unsigned int cpu, int *spurious)
+{
+ for (;;) {
+ wfi();
+
+ 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)++;
+ }
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void __ref spear13xx_cpu_die(unsigned int cpu)
+{
+ int spurious = 0;
+
+ /*
+ * we're ready for shutdown now, so do it
+ */
+ cpu_enter_lowpower();
+ spear13xx_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);
+}
diff --git a/arch/arm/mach-spear/include/mach/irqs.h b/arch/arm/mach-spear/include/mach/irqs.h
new file mode 100644
index 000000000..92da0a8c6
--- /dev/null
+++ b/arch/arm/mach-spear/include/mach/irqs.h
@@ -0,0 +1,35 @@
+/*
+ * IRQ helper macros for spear machine family
+ *
+ * Copyright (C) 2009-2012 ST Microelectronics
+ * Rajeev Kumar <rajeev-dlh.kumar@st.com>
+ * Viresh Kumar <viresh.linux@gmail.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
+
+#ifdef CONFIG_ARCH_SPEAR3XX
+#define NR_IRQS 256
+#endif
+
+#ifdef CONFIG_ARCH_SPEAR6XX
+/* IRQ definitions */
+/* VIC 1 */
+#define IRQ_VIC_END 64
+
+/* GPIO pins virtual irqs */
+#define VIRTUAL_IRQS 24
+#define NR_IRQS (IRQ_VIC_END + VIRTUAL_IRQS)
+#endif
+
+#ifdef CONFIG_ARCH_SPEAR13XX
+#define IRQ_GIC_END 160
+#define NR_IRQS IRQ_GIC_END
+#endif
+
+#endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-spear/include/mach/misc_regs.h b/arch/arm/mach-spear/include/mach/misc_regs.h
new file mode 100644
index 000000000..935639ce5
--- /dev/null
+++ b/arch/arm/mach-spear/include/mach/misc_regs.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/misc_regs.h
+ *
+ * Miscellaneous registers definitions for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.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/spear.h>
+
+#define MISC_BASE (VA_SPEAR_ICM3_MISC_REG_BASE)
+#define DMA_CHN_CFG (MISC_BASE + 0x0A0)
+
+#endif /* __MACH_MISC_REGS_H */
diff --git a/arch/arm/mach-spear/include/mach/spear.h b/arch/arm/mach-spear/include/mach/spear.h
new file mode 100644
index 000000000..f2d6a0176
--- /dev/null
+++ b/arch/arm/mach-spear/include/mach/spear.h
@@ -0,0 +1,91 @@
+/*
+ * SPEAr3xx/6xx Machine family specific definition
+ *
+ * Copyright (C) 2009,2012 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ * Viresh Kumar <viresh.linux@gmail.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_SPEAR_H
+#define __MACH_SPEAR_H
+
+#include <asm/memory.h>
+
+#if defined(CONFIG_ARCH_SPEAR3XX) || defined (CONFIG_ARCH_SPEAR6XX)
+
+/* ICM1 - Low speed connection */
+#define SPEAR_ICM1_2_BASE UL(0xD0000000)
+#define VA_SPEAR_ICM1_2_BASE IOMEM(0xFD000000)
+#define SPEAR_ICM1_UART_BASE UL(0xD0000000)
+#define VA_SPEAR_ICM1_UART_BASE (VA_SPEAR_ICM1_2_BASE - SPEAR_ICM1_2_BASE + SPEAR_ICM1_UART_BASE)
+#define SPEAR3XX_ICM1_SSP_BASE UL(0xD0100000)
+
+/* ML-1, 2 - Multi Layer CPU Subsystem */
+#define SPEAR_ICM3_ML1_2_BASE UL(0xF0000000)
+#define VA_SPEAR6XX_ML_CPU_BASE IOMEM(0xF0000000)
+
+/* ICM3 - Basic Subsystem */
+#define SPEAR_ICM3_SMI_CTRL_BASE UL(0xFC000000)
+#define VA_SPEAR_ICM3_SMI_CTRL_BASE IOMEM(0xFC000000)
+#define SPEAR_ICM3_DMA_BASE UL(0xFC400000)
+#define SPEAR_ICM3_SYS_CTRL_BASE UL(0xFCA00000)
+#define VA_SPEAR_ICM3_SYS_CTRL_BASE (VA_SPEAR_ICM3_SMI_CTRL_BASE - SPEAR_ICM3_SMI_CTRL_BASE + SPEAR_ICM3_SYS_CTRL_BASE)
+#define SPEAR_ICM3_MISC_REG_BASE UL(0xFCA80000)
+#define VA_SPEAR_ICM3_MISC_REG_BASE (VA_SPEAR_ICM3_SMI_CTRL_BASE - SPEAR_ICM3_SMI_CTRL_BASE + SPEAR_ICM3_MISC_REG_BASE)
+
+/* Debug uart for linux, will be used for debug and uncompress messages */
+#define SPEAR_DBG_UART_BASE SPEAR_ICM1_UART_BASE
+
+/* Sysctl base for spear platform */
+#define SPEAR_SYS_CTRL_BASE SPEAR_ICM3_SYS_CTRL_BASE
+#define VA_SPEAR_SYS_CTRL_BASE VA_SPEAR_ICM3_SYS_CTRL_BASE
+#endif /* SPEAR3xx || SPEAR6XX */
+
+/* SPEAr320 Macros */
+#define SPEAR320_SOC_CONFIG_BASE UL(0xB3000000)
+#define VA_SPEAR320_SOC_CONFIG_BASE IOMEM(0xFE000000)
+
+#ifdef CONFIG_ARCH_SPEAR13XX
+
+#define PERIP_GRP2_BASE UL(0xB3000000)
+#define VA_PERIP_GRP2_BASE IOMEM(0xF9000000)
+#define MCIF_SDHCI_BASE UL(0xB3000000)
+#define SYSRAM0_BASE UL(0xB3800000)
+#define VA_SYSRAM0_BASE IOMEM(0xF9800000)
+#define SYS_LOCATION (VA_SYSRAM0_BASE + 0x600)
+
+#define PERIP_GRP1_BASE UL(0xE0000000)
+#define VA_PERIP_GRP1_BASE IOMEM(0xFD000000)
+#define UART_BASE UL(0xE0000000)
+#define VA_UART_BASE IOMEM(0xFD000000)
+#define SSP_BASE UL(0xE0100000)
+#define MISC_BASE UL(0xE0700000)
+#define VA_MISC_BASE IOMEM(0xFD700000)
+
+#define A9SM_AND_MPMC_BASE UL(0xEC000000)
+#define VA_A9SM_AND_MPMC_BASE IOMEM(0xFC000000)
+
+#define SPEAR1310_RAS_BASE UL(0xD8400000)
+#define VA_SPEAR1310_RAS_BASE IOMEM(UL(0xFA400000))
+
+/* A9SM peripheral offsets */
+#define A9SM_PERIP_BASE UL(0xEC800000)
+#define VA_A9SM_PERIP_BASE IOMEM(0xFC800000)
+#define VA_SCU_BASE (VA_A9SM_PERIP_BASE + 0x00)
+
+#define L2CC_BASE UL(0xED000000)
+#define VA_L2CC_BASE IOMEM(UL(0xFB000000))
+
+/* others */
+#define MCIF_CF_BASE UL(0xB2800000)
+
+/* Debug uart for linux, will be used for debug and uncompress messages */
+#define SPEAR_DBG_UART_BASE UART_BASE
+
+#endif /* SPEAR13XX */
+
+#endif /* __MACH_SPEAR_H */
diff --git a/arch/arm/mach-spear/include/mach/uncompress.h b/arch/arm/mach-spear/include/mach/uncompress.h
new file mode 100644
index 000000000..51b2dc93e
--- /dev/null
+++ b/arch/arm/mach-spear/include/mach/uncompress.h
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/plat-spear/include/plat/uncompress.h
+ *
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.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/spear.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()
+
+#endif /* __PLAT_UNCOMPRESS_H */
diff --git a/arch/arm/mach-spear/pl080.c b/arch/arm/mach-spear/pl080.c
new file mode 100644
index 000000000..cfa1199d0
--- /dev/null
+++ b/arch/arm/mach-spear/pl080.c
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/plat-spear/pl080.c
+ *
+ * DMAC pl080 definitions for SPEAr platform
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.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/pl08x.h>
+#include <linux/amba/bus.h>
+#include <linux/bug.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/spinlock_types.h>
+#include <mach/spear.h>
+#include <mach/misc_regs.h>
+
+static spinlock_t lock = __SPIN_LOCK_UNLOCKED(x);
+
+struct {
+ unsigned char busy;
+ unsigned char val;
+} signals[16] = {{0, 0}, };
+
+int pl080_get_signal(const struct pl08x_channel_data *cd)
+{
+ unsigned int signal = cd->min_signal, val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&lock, flags);
+
+ /* Return if signal is already acquired by somebody else */
+ if (signals[signal].busy &&
+ (signals[signal].val != cd->muxval)) {
+ spin_unlock_irqrestore(&lock, flags);
+ return -EBUSY;
+ }
+
+ /* If acquiring for the first time, configure it */
+ if (!signals[signal].busy) {
+ val = readl(DMA_CHN_CFG);
+
+ /*
+ * Each request line has two bits in DMA_CHN_CFG register. To
+ * goto the bits of current request line, do left shift of
+ * value by 2 * signal number.
+ */
+ val &= ~(0x3 << (signal * 2));
+ val |= cd->muxval << (signal * 2);
+ writel(val, DMA_CHN_CFG);
+ }
+
+ signals[signal].busy++;
+ signals[signal].val = cd->muxval;
+ spin_unlock_irqrestore(&lock, flags);
+
+ return signal;
+}
+
+void pl080_put_signal(const struct pl08x_channel_data *cd, int signal)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&lock, flags);
+
+ /* if signal is not used */
+ if (!signals[signal].busy)
+ BUG();
+
+ signals[signal].busy--;
+
+ spin_unlock_irqrestore(&lock, flags);
+}
diff --git a/arch/arm/mach-spear/pl080.h b/arch/arm/mach-spear/pl080.h
new file mode 100644
index 000000000..eb6590ded
--- /dev/null
+++ b/arch/arm/mach-spear/pl080.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/plat-spear/include/plat/pl080.h
+ *
+ * DMAC pl080 definitions for SPEAr platform
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.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_PL080_H
+#define __PLAT_PL080_H
+
+struct pl08x_channel_data;
+int pl080_get_signal(const struct pl08x_channel_data *cd);
+void pl080_put_signal(const struct pl08x_channel_data *cd, int signal);
+
+#endif /* __PLAT_PL080_H */
diff --git a/arch/arm/mach-spear/platsmp.c b/arch/arm/mach-spear/platsmp.c
new file mode 100644
index 000000000..fd4297713
--- /dev/null
+++ b/arch/arm/mach-spear/platsmp.c
@@ -0,0 +1,131 @@
+/*
+ * arch/arm/mach-spear13xx/platsmp.c
+ *
+ * based upon linux/arch/arm/mach-realview/platsmp.c
+ *
+ * Copyright (C) 2012 ST Microelectronics Ltd.
+ * Shiraz Hashim <shiraz.linux.kernel@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/jiffies.h>
+#include <linux/io.h>
+#include <linux/smp.h>
+#include <asm/cacheflush.h>
+#include <asm/smp_scu.h>
+#include <mach/spear.h>
+#include "generic.h"
+
+/*
+ * 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();
+ sync_cache_w(&pen_release);
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+static void __iomem *scu_base = IOMEM(VA_SCU_BASE);
+
+static void spear13xx_secondary_init(unsigned int cpu)
+{
+ /*
+ * 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);
+}
+
+static int spear13xx_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);
+
+ 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.
+ */
+static void __init spear13xx_smp_init_cpus(void)
+{
+ unsigned int i, ncores = scu_get_core_count(scu_base);
+
+ if (ncores > nr_cpu_ids) {
+ pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
+ ncores, nr_cpu_ids);
+ ncores = nr_cpu_ids;
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+}
+
+static void __init spear13xx_smp_prepare_cpus(unsigned int max_cpus)
+{
+
+ scu_enable(scu_base);
+
+ /*
+ * Write the address of secondary startup into the system-wide location
+ * (presently it is in SRAM). The BootMonitor waits until it receives a
+ * soft interrupt, and then the secondary CPU branches to this address.
+ */
+ __raw_writel(virt_to_phys(spear13xx_secondary_startup), SYS_LOCATION);
+}
+
+struct smp_operations spear13xx_smp_ops __initdata = {
+ .smp_init_cpus = spear13xx_smp_init_cpus,
+ .smp_prepare_cpus = spear13xx_smp_prepare_cpus,
+ .smp_secondary_init = spear13xx_secondary_init,
+ .smp_boot_secondary = spear13xx_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = spear13xx_cpu_die,
+#endif
+};
diff --git a/arch/arm/mach-spear/restart.c b/arch/arm/mach-spear/restart.c
new file mode 100644
index 000000000..ce5e098c4
--- /dev/null
+++ b/arch/arm/mach-spear/restart.c
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/plat-spear/restart.c
+ *
+ * SPEAr platform specific restart functions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.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/sp810.h>
+#include <linux/reboot.h>
+#include <asm/system_misc.h>
+#include <mach/spear.h>
+#include "generic.h"
+
+#define SPEAR13XX_SYS_SW_RES (VA_MISC_BASE + 0x204)
+void spear_restart(enum reboot_mode mode, const char *cmd)
+{
+ if (mode == REBOOT_SOFT) {
+ /* software reset, Jump into ROM at address 0 */
+ soft_restart(0);
+ } else {
+ /* hardware reset, Use on-chip reset capability */
+#ifdef CONFIG_ARCH_SPEAR13XX
+ writel_relaxed(0x01, SPEAR13XX_SYS_SW_RES);
+#endif
+#if defined(CONFIG_ARCH_SPEAR3XX) || defined(CONFIG_ARCH_SPEAR6XX)
+ sysctl_soft_reset((void __iomem *)VA_SPEAR_SYS_CTRL_BASE);
+#endif
+ }
+}
diff --git a/arch/arm/mach-spear/spear1310.c b/arch/arm/mach-spear/spear1310.c
new file mode 100644
index 000000000..d9ce4d800
--- /dev/null
+++ b/arch/arm/mach-spear/spear1310.c
@@ -0,0 +1,67 @@
+/*
+ * arch/arm/mach-spear13xx/spear1310.c
+ *
+ * SPEAr1310 machine source file
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.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 pr_fmt(fmt) "SPEAr1310: " fmt
+
+#include <linux/amba/pl022.h>
+#include <linux/of_platform.h>
+#include <linux/pata_arasan_cf_data.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include "generic.h"
+#include <mach/spear.h>
+
+/* Base addresses */
+#define SPEAR1310_RAS_GRP1_BASE UL(0xD8000000)
+#define VA_SPEAR1310_RAS_GRP1_BASE UL(0xFA000000)
+
+static void __init spear1310_dt_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ platform_device_register_simple("spear-cpufreq", -1, NULL, 0);
+}
+
+static const char * const spear1310_dt_board_compat[] = {
+ "st,spear1310",
+ "st,spear1310-evb",
+ NULL,
+};
+
+/*
+ * Following will create 16MB static virtual/physical mappings
+ * PHYSICAL VIRTUAL
+ * 0xD8000000 0xFA000000
+ */
+static struct map_desc spear1310_io_desc[] __initdata = {
+ {
+ .virtual = VA_SPEAR1310_RAS_GRP1_BASE,
+ .pfn = __phys_to_pfn(SPEAR1310_RAS_GRP1_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ },
+};
+
+static void __init spear1310_map_io(void)
+{
+ iotable_init(spear1310_io_desc, ARRAY_SIZE(spear1310_io_desc));
+ spear13xx_map_io();
+}
+
+DT_MACHINE_START(SPEAR1310_DT, "ST SPEAr1310 SoC with Flattened Device Tree")
+ .smp = smp_ops(spear13xx_smp_ops),
+ .map_io = spear1310_map_io,
+ .init_time = spear13xx_timer_init,
+ .init_machine = spear1310_dt_init,
+ .restart = spear_restart,
+ .dt_compat = spear1310_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear/spear1340.c b/arch/arm/mach-spear/spear1340.c
new file mode 100644
index 000000000..3f3c0f124
--- /dev/null
+++ b/arch/arm/mach-spear/spear1340.c
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-spear13xx/spear1340.c
+ *
+ * SPEAr1340 machine source file
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.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 pr_fmt(fmt) "SPEAr1340: " fmt
+
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include "generic.h"
+
+static void __init spear1340_dt_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ platform_device_register_simple("spear-cpufreq", -1, NULL, 0);
+}
+
+static const char * const spear1340_dt_board_compat[] = {
+ "st,spear1340",
+ "st,spear1340-evb",
+ NULL,
+};
+
+DT_MACHINE_START(SPEAR1340_DT, "ST SPEAr1340 SoC with Flattened Device Tree")
+ .smp = smp_ops(spear13xx_smp_ops),
+ .map_io = spear13xx_map_io,
+ .init_time = spear13xx_timer_init,
+ .init_machine = spear1340_dt_init,
+ .restart = spear_restart,
+ .dt_compat = spear1340_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear/spear13xx.c b/arch/arm/mach-spear/spear13xx.c
new file mode 100644
index 000000000..2e463a934
--- /dev/null
+++ b/arch/arm/mach-spear/spear13xx.c
@@ -0,0 +1,128 @@
+/*
+ * arch/arm/mach-spear13xx/spear13xx.c
+ *
+ * SPEAr13XX machines common source file
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.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 pr_fmt(fmt) "SPEAr13xx: " fmt
+
+#include <linux/amba/pl022.h>
+#include <linux/clk.h>
+#include <linux/clocksource.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/map.h>
+#include <mach/spear.h>
+#include "generic.h"
+
+void __init spear13xx_l2x0_init(void)
+{
+ /*
+ * 512KB (64KB/way), 8-way associativity, parity supported
+ *
+ * FIXME: 9th bit, of Auxillary Controller register must be set
+ * for some spear13xx devices for stable L2 operation.
+ *
+ * Enable Early BRESP, L2 prefetch for Instruction and Data,
+ * write alloc and 'Full line of zero' options
+ *
+ */
+ if (!IS_ENABLED(CONFIG_CACHE_L2X0))
+ return;
+
+ writel_relaxed(0x06, VA_L2CC_BASE + L310_PREFETCH_CTRL);
+
+ /*
+ * Program following latencies in order to make
+ * SPEAr1340 work at 600 MHz
+ */
+ writel_relaxed(0x221, VA_L2CC_BASE + L310_TAG_LATENCY_CTRL);
+ writel_relaxed(0x441, VA_L2CC_BASE + L310_DATA_LATENCY_CTRL);
+ l2x0_init(VA_L2CC_BASE, 0x30a00001, 0xfe0fffff);
+}
+
+/*
+ * Following will create 16MB static virtual/physical mappings
+ * PHYSICAL VIRTUAL
+ * 0xB3000000 0xF9000000
+ * 0xE0000000 0xFD000000
+ * 0xEC000000 0xFC000000
+ * 0xED000000 0xFB000000
+ */
+static struct map_desc spear13xx_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long)VA_PERIP_GRP2_BASE,
+ .pfn = __phys_to_pfn(PERIP_GRP2_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = (unsigned long)VA_PERIP_GRP1_BASE,
+ .pfn = __phys_to_pfn(PERIP_GRP1_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = (unsigned long)VA_A9SM_AND_MPMC_BASE,
+ .pfn = __phys_to_pfn(A9SM_AND_MPMC_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = (unsigned long)VA_L2CC_BASE,
+ .pfn = __phys_to_pfn(L2CC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ },
+};
+
+/* This will create static memory mapping for selected devices */
+void __init spear13xx_map_io(void)
+{
+ iotable_init(spear13xx_io_desc, ARRAY_SIZE(spear13xx_io_desc));
+}
+
+static void __init spear13xx_clk_init(void)
+{
+ if (of_machine_is_compatible("st,spear1310"))
+ spear1310_clk_init(VA_MISC_BASE, VA_SPEAR1310_RAS_BASE);
+ else if (of_machine_is_compatible("st,spear1340"))
+ spear1340_clk_init(VA_MISC_BASE);
+ else
+ pr_err("%s: Unknown machine\n", __func__);
+}
+
+void __init spear13xx_timer_init(void)
+{
+ char pclk_name[] = "osc_24m_clk";
+ struct clk *gpt_clk, *pclk;
+
+ spear13xx_clk_init();
+
+ /* 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_of_timer();
+ clocksource_of_init();
+}
diff --git a/arch/arm/mach-spear/spear300.c b/arch/arm/mach-spear/spear300.c
new file mode 100644
index 000000000..b52e48f34
--- /dev/null
+++ b/arch/arm/mach-spear/spear300.c
@@ -0,0 +1,218 @@
+/*
+ * arch/arm/mach-spear3xx/spear300.c
+ *
+ * SPEAr300 machine source file
+ *
+ * Copyright (C) 2009-2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.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 pr_fmt(fmt) "SPEAr300: " fmt
+
+#include <linux/amba/pl08x.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include "generic.h"
+#include <mach/spear.h>
+
+/* DMAC platform data's slave info */
+struct pl08x_channel_data spear300_dma_info[] = {
+ {
+ .bus_id = "uart0_rx",
+ .min_signal = 2,
+ .max_signal = 2,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart0_tx",
+ .min_signal = 3,
+ .max_signal = 3,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ssp0_rx",
+ .min_signal = 8,
+ .max_signal = 8,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ssp0_tx",
+ .min_signal = 9,
+ .max_signal = 9,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "i2c_rx",
+ .min_signal = 10,
+ .max_signal = 10,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "i2c_tx",
+ .min_signal = 11,
+ .max_signal = 11,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "irda",
+ .min_signal = 12,
+ .max_signal = 12,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "adc",
+ .min_signal = 13,
+ .max_signal = 13,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "to_jpeg",
+ .min_signal = 14,
+ .max_signal = 14,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "from_jpeg",
+ .min_signal = 15,
+ .max_signal = 15,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras0_rx",
+ .min_signal = 0,
+ .max_signal = 0,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras0_tx",
+ .min_signal = 1,
+ .max_signal = 1,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras1_rx",
+ .min_signal = 2,
+ .max_signal = 2,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras1_tx",
+ .min_signal = 3,
+ .max_signal = 3,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras2_rx",
+ .min_signal = 4,
+ .max_signal = 4,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras2_tx",
+ .min_signal = 5,
+ .max_signal = 5,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras3_rx",
+ .min_signal = 6,
+ .max_signal = 6,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras3_tx",
+ .min_signal = 7,
+ .max_signal = 7,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras4_rx",
+ .min_signal = 8,
+ .max_signal = 8,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras4_tx",
+ .min_signal = 9,
+ .max_signal = 9,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras5_rx",
+ .min_signal = 10,
+ .max_signal = 10,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras5_tx",
+ .min_signal = 11,
+ .max_signal = 11,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras6_rx",
+ .min_signal = 12,
+ .max_signal = 12,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras6_tx",
+ .min_signal = 13,
+ .max_signal = 13,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras7_rx",
+ .min_signal = 14,
+ .max_signal = 14,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras7_tx",
+ .min_signal = 15,
+ .max_signal = 15,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ },
+};
+
+/* Add SPEAr300 auxdata to pass platform data */
+static struct of_dev_auxdata spear300_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("arm,pl022", SPEAR3XX_ICM1_SSP_BASE, NULL,
+ &pl022_plat_data),
+ OF_DEV_AUXDATA("arm,pl080", SPEAR_ICM3_DMA_BASE, NULL,
+ &pl080_plat_data),
+ {}
+};
+
+static void __init spear300_dt_init(void)
+{
+ pl080_plat_data.slave_channels = spear300_dma_info;
+ pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear300_dma_info);
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ spear300_auxdata_lookup, NULL);
+}
+
+static const char * const spear300_dt_board_compat[] = {
+ "st,spear300",
+ "st,spear300-evb",
+ NULL,
+};
+
+static void __init spear300_map_io(void)
+{
+ spear3xx_map_io();
+}
+
+DT_MACHINE_START(SPEAR300_DT, "ST SPEAr300 SoC with Flattened Device Tree")
+ .map_io = spear300_map_io,
+ .init_time = spear3xx_timer_init,
+ .init_machine = spear300_dt_init,
+ .restart = spear_restart,
+ .dt_compat = spear300_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear/spear310.c b/arch/arm/mach-spear/spear310.c
new file mode 100644
index 000000000..ed2029db3
--- /dev/null
+++ b/arch/arm/mach-spear/spear310.c
@@ -0,0 +1,260 @@
+/*
+ * arch/arm/mach-spear3xx/spear310.c
+ *
+ * SPEAr310 machine source file
+ *
+ * Copyright (C) 2009-2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.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 pr_fmt(fmt) "SPEAr310: " fmt
+
+#include <linux/amba/pl08x.h>
+#include <linux/amba/serial.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include "generic.h"
+#include <mach/spear.h>
+
+#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)
+
+/* DMAC platform data's slave info */
+struct pl08x_channel_data spear310_dma_info[] = {
+ {
+ .bus_id = "uart0_rx",
+ .min_signal = 2,
+ .max_signal = 2,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart0_tx",
+ .min_signal = 3,
+ .max_signal = 3,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ssp0_rx",
+ .min_signal = 8,
+ .max_signal = 8,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ssp0_tx",
+ .min_signal = 9,
+ .max_signal = 9,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "i2c_rx",
+ .min_signal = 10,
+ .max_signal = 10,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "i2c_tx",
+ .min_signal = 11,
+ .max_signal = 11,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "irda",
+ .min_signal = 12,
+ .max_signal = 12,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "adc",
+ .min_signal = 13,
+ .max_signal = 13,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "to_jpeg",
+ .min_signal = 14,
+ .max_signal = 14,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "from_jpeg",
+ .min_signal = 15,
+ .max_signal = 15,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart1_rx",
+ .min_signal = 0,
+ .max_signal = 0,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart1_tx",
+ .min_signal = 1,
+ .max_signal = 1,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart2_rx",
+ .min_signal = 2,
+ .max_signal = 2,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart2_tx",
+ .min_signal = 3,
+ .max_signal = 3,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart3_rx",
+ .min_signal = 4,
+ .max_signal = 4,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart3_tx",
+ .min_signal = 5,
+ .max_signal = 5,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart4_rx",
+ .min_signal = 6,
+ .max_signal = 6,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart4_tx",
+ .min_signal = 7,
+ .max_signal = 7,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart5_rx",
+ .min_signal = 8,
+ .max_signal = 8,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart5_tx",
+ .min_signal = 9,
+ .max_signal = 9,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras5_rx",
+ .min_signal = 10,
+ .max_signal = 10,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras5_tx",
+ .min_signal = 11,
+ .max_signal = 11,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras6_rx",
+ .min_signal = 12,
+ .max_signal = 12,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras6_tx",
+ .min_signal = 13,
+ .max_signal = 13,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras7_rx",
+ .min_signal = 14,
+ .max_signal = 14,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras7_tx",
+ .min_signal = 15,
+ .max_signal = 15,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ },
+};
+
+/* uart devices plat data */
+static struct amba_pl011_data spear310_uart_data[] = {
+ {
+ .dma_filter = pl08x_filter_id,
+ .dma_tx_param = "uart1_tx",
+ .dma_rx_param = "uart1_rx",
+ }, {
+ .dma_filter = pl08x_filter_id,
+ .dma_tx_param = "uart2_tx",
+ .dma_rx_param = "uart2_rx",
+ }, {
+ .dma_filter = pl08x_filter_id,
+ .dma_tx_param = "uart3_tx",
+ .dma_rx_param = "uart3_rx",
+ }, {
+ .dma_filter = pl08x_filter_id,
+ .dma_tx_param = "uart4_tx",
+ .dma_rx_param = "uart4_rx",
+ }, {
+ .dma_filter = pl08x_filter_id,
+ .dma_tx_param = "uart5_tx",
+ .dma_rx_param = "uart5_rx",
+ },
+};
+
+/* Add SPEAr310 auxdata to pass platform data */
+static struct of_dev_auxdata spear310_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("arm,pl022", SPEAR3XX_ICM1_SSP_BASE, NULL,
+ &pl022_plat_data),
+ OF_DEV_AUXDATA("arm,pl080", SPEAR_ICM3_DMA_BASE, NULL,
+ &pl080_plat_data),
+ OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART1_BASE, NULL,
+ &spear310_uart_data[0]),
+ OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART2_BASE, NULL,
+ &spear310_uart_data[1]),
+ OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART3_BASE, NULL,
+ &spear310_uart_data[2]),
+ OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART4_BASE, NULL,
+ &spear310_uart_data[3]),
+ OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART5_BASE, NULL,
+ &spear310_uart_data[4]),
+ {}
+};
+
+static void __init spear310_dt_init(void)
+{
+ pl080_plat_data.slave_channels = spear310_dma_info;
+ pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear310_dma_info);
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ spear310_auxdata_lookup, NULL);
+}
+
+static const char * const spear310_dt_board_compat[] = {
+ "st,spear310",
+ "st,spear310-evb",
+ NULL,
+};
+
+static void __init spear310_map_io(void)
+{
+ spear3xx_map_io();
+}
+
+DT_MACHINE_START(SPEAR310_DT, "ST SPEAr310 SoC with Flattened Device Tree")
+ .map_io = spear310_map_io,
+ .init_time = spear3xx_timer_init,
+ .init_machine = spear310_dt_init,
+ .restart = spear_restart,
+ .dt_compat = spear310_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear/spear320.c b/arch/arm/mach-spear/spear320.c
new file mode 100644
index 000000000..bf634b32a
--- /dev/null
+++ b/arch/arm/mach-spear/spear320.c
@@ -0,0 +1,275 @@
+/*
+ * arch/arm/mach-spear3xx/spear320.c
+ *
+ * SPEAr320 machine source file
+ *
+ * Copyright (C) 2009-2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.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 pr_fmt(fmt) "SPEAr320: " fmt
+
+#include <linux/amba/pl022.h>
+#include <linux/amba/pl08x.h>
+#include <linux/amba/serial.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include "generic.h"
+#include <mach/spear.h>
+
+#define SPEAR320_UART1_BASE UL(0xA3000000)
+#define SPEAR320_UART2_BASE UL(0xA4000000)
+#define SPEAR320_SSP0_BASE UL(0xA5000000)
+#define SPEAR320_SSP1_BASE UL(0xA6000000)
+
+/* DMAC platform data's slave info */
+struct pl08x_channel_data spear320_dma_info[] = {
+ {
+ .bus_id = "uart0_rx",
+ .min_signal = 2,
+ .max_signal = 2,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart0_tx",
+ .min_signal = 3,
+ .max_signal = 3,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ssp0_rx",
+ .min_signal = 8,
+ .max_signal = 8,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ssp0_tx",
+ .min_signal = 9,
+ .max_signal = 9,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "i2c0_rx",
+ .min_signal = 10,
+ .max_signal = 10,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "i2c0_tx",
+ .min_signal = 11,
+ .max_signal = 11,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "irda",
+ .min_signal = 12,
+ .max_signal = 12,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "adc",
+ .min_signal = 13,
+ .max_signal = 13,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "to_jpeg",
+ .min_signal = 14,
+ .max_signal = 14,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "from_jpeg",
+ .min_signal = 15,
+ .max_signal = 15,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ssp1_rx",
+ .min_signal = 0,
+ .max_signal = 0,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ssp1_tx",
+ .min_signal = 1,
+ .max_signal = 1,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ssp2_rx",
+ .min_signal = 2,
+ .max_signal = 2,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ssp2_tx",
+ .min_signal = 3,
+ .max_signal = 3,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart1_rx",
+ .min_signal = 4,
+ .max_signal = 4,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart1_tx",
+ .min_signal = 5,
+ .max_signal = 5,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart2_rx",
+ .min_signal = 6,
+ .max_signal = 6,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart2_tx",
+ .min_signal = 7,
+ .max_signal = 7,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2c1_rx",
+ .min_signal = 8,
+ .max_signal = 8,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2c1_tx",
+ .min_signal = 9,
+ .max_signal = 9,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2c2_rx",
+ .min_signal = 10,
+ .max_signal = 10,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2c2_tx",
+ .min_signal = 11,
+ .max_signal = 11,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2s_rx",
+ .min_signal = 12,
+ .max_signal = 12,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2s_tx",
+ .min_signal = 13,
+ .max_signal = 13,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "rs485_rx",
+ .min_signal = 14,
+ .max_signal = 14,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "rs485_tx",
+ .min_signal = 15,
+ .max_signal = 15,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB2,
+ },
+};
+
+static struct pl022_ssp_controller spear320_ssp_data[] = {
+ {
+ .bus_id = 1,
+ .enable_dma = 1,
+ .dma_filter = pl08x_filter_id,
+ .dma_tx_param = "ssp1_tx",
+ .dma_rx_param = "ssp1_rx",
+ .num_chipselect = 2,
+ }, {
+ .bus_id = 2,
+ .enable_dma = 1,
+ .dma_filter = pl08x_filter_id,
+ .dma_tx_param = "ssp2_tx",
+ .dma_rx_param = "ssp2_rx",
+ .num_chipselect = 2,
+ }
+};
+
+static struct amba_pl011_data spear320_uart_data[] = {
+ {
+ .dma_filter = pl08x_filter_id,
+ .dma_tx_param = "uart1_tx",
+ .dma_rx_param = "uart1_rx",
+ }, {
+ .dma_filter = pl08x_filter_id,
+ .dma_tx_param = "uart2_tx",
+ .dma_rx_param = "uart2_rx",
+ },
+};
+
+/* Add SPEAr310 auxdata to pass platform data */
+static struct of_dev_auxdata spear320_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("arm,pl022", SPEAR3XX_ICM1_SSP_BASE, NULL,
+ &pl022_plat_data),
+ OF_DEV_AUXDATA("arm,pl080", SPEAR_ICM3_DMA_BASE, NULL,
+ &pl080_plat_data),
+ OF_DEV_AUXDATA("arm,pl022", SPEAR320_SSP0_BASE, NULL,
+ &spear320_ssp_data[0]),
+ OF_DEV_AUXDATA("arm,pl022", SPEAR320_SSP1_BASE, NULL,
+ &spear320_ssp_data[1]),
+ OF_DEV_AUXDATA("arm,pl011", SPEAR320_UART1_BASE, NULL,
+ &spear320_uart_data[0]),
+ OF_DEV_AUXDATA("arm,pl011", SPEAR320_UART2_BASE, NULL,
+ &spear320_uart_data[1]),
+ {}
+};
+
+static void __init spear320_dt_init(void)
+{
+ pl080_plat_data.slave_channels = spear320_dma_info;
+ pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear320_dma_info);
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ spear320_auxdata_lookup, NULL);
+}
+
+static const char * const spear320_dt_board_compat[] = {
+ "st,spear320",
+ "st,spear320-evb",
+ "st,spear320-hmi",
+ NULL,
+};
+
+struct map_desc spear320_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long)VA_SPEAR320_SOC_CONFIG_BASE,
+ .pfn = __phys_to_pfn(SPEAR320_SOC_CONFIG_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ },
+};
+
+static void __init spear320_map_io(void)
+{
+ iotable_init(spear320_io_desc, ARRAY_SIZE(spear320_io_desc));
+ spear3xx_map_io();
+}
+
+DT_MACHINE_START(SPEAR320_DT, "ST SPEAr320 SoC with Flattened Device Tree")
+ .map_io = spear320_map_io,
+ .init_time = spear3xx_timer_init,
+ .init_machine = spear320_dt_init,
+ .restart = spear_restart,
+ .dt_compat = spear320_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear/spear3xx.c b/arch/arm/mach-spear/spear3xx.c
new file mode 100644
index 000000000..bf3b1fd8c
--- /dev/null
+++ b/arch/arm/mach-spear/spear3xx.c
@@ -0,0 +1,116 @@
+/*
+ * arch/arm/mach-spear3xx/spear3xx.c
+ *
+ * SPEAr3XX machines common source file
+ *
+ * Copyright (C) 2009-2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.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 pr_fmt(fmt) "SPEAr3xx: " fmt
+
+#include <linux/amba/pl022.h>
+#include <linux/amba/pl080.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <asm/mach/map.h>
+#include "pl080.h"
+#include "generic.h"
+#include <mach/spear.h>
+#include <mach/misc_regs.h>
+
+/* ssp device registration */
+struct pl022_ssp_controller pl022_plat_data = {
+ .bus_id = 0,
+ .enable_dma = 1,
+ .dma_filter = pl08x_filter_id,
+ .dma_tx_param = "ssp0_tx",
+ .dma_rx_param = "ssp0_rx",
+ /*
+ * This is number of spi devices that can be connected to spi. There are
+ * two type of chipselects on which slave devices can work. One is chip
+ * select provided by spi masters other is controlled through external
+ * gpio's. We can't use chipselect provided from spi master (because as
+ * soon as FIFO becomes empty, CS is disabled and transfer ends). So
+ * this number now depends on number of gpios available for spi. each
+ * slave on each master requires a separate gpio pin.
+ */
+ .num_chipselect = 2,
+};
+
+/* dmac device registration */
+struct pl08x_platform_data pl080_plat_data = {
+ .memcpy_channel = {
+ .bus_id = "memcpy",
+ .cctl_memcpy =
+ (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
+ PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \
+ PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \
+ PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \
+ PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | \
+ PL080_CONTROL_PROT_SYS),
+ },
+ .lli_buses = PL08X_AHB1,
+ .mem_buses = PL08X_AHB1,
+ .get_xfer_signal = pl080_get_signal,
+ .put_xfer_signal = pl080_put_signal,
+};
+
+/*
+ * Following will create 16MB static virtual/physical mappings
+ * PHYSICAL VIRTUAL
+ * 0xD0000000 0xFD000000
+ * 0xFC000000 0xFC000000
+ */
+struct map_desc spear3xx_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long)VA_SPEAR_ICM1_2_BASE,
+ .pfn = __phys_to_pfn(SPEAR_ICM1_2_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = (unsigned long)VA_SPEAR_ICM3_SMI_CTRL_BASE,
+ .pfn = __phys_to_pfn(SPEAR_ICM3_SMI_CTRL_BASE),
+ .length = SZ_16M,
+ .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));
+}
+
+void __init spear3xx_timer_init(void)
+{
+ char pclk_name[] = "pll3_clk";
+ struct clk *gpt_clk, *pclk;
+
+ spear3xx_clk_init(MISC_BASE, VA_SPEAR320_SOC_CONFIG_BASE);
+
+ /* 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_of_timer();
+}
diff --git a/arch/arm/mach-spear/spear6xx.c b/arch/arm/mach-spear/spear6xx.c
new file mode 100644
index 000000000..da26fa5b6
--- /dev/null
+++ b/arch/arm/mach-spear/spear6xx.c
@@ -0,0 +1,429 @@
+/*
+ * arch/arm/mach-spear6xx/spear6xx.c
+ *
+ * SPEAr6XX machines common source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * Copyright 2012 Stefan Roese <sr@denx.de>
+ *
+ * This file is licensed under the terms 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/pl08x.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/amba/pl080.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include "pl080.h"
+#include "generic.h"
+#include <mach/spear.h>
+#include <mach/misc_regs.h>
+
+/* dmac device registration */
+static struct pl08x_channel_data spear600_dma_info[] = {
+ {
+ .bus_id = "ssp1_rx",
+ .min_signal = 0,
+ .max_signal = 0,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ssp1_tx",
+ .min_signal = 1,
+ .max_signal = 1,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart0_rx",
+ .min_signal = 2,
+ .max_signal = 2,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart0_tx",
+ .min_signal = 3,
+ .max_signal = 3,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart1_rx",
+ .min_signal = 4,
+ .max_signal = 4,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "uart1_tx",
+ .min_signal = 5,
+ .max_signal = 5,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ssp2_rx",
+ .min_signal = 6,
+ .max_signal = 6,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ssp2_tx",
+ .min_signal = 7,
+ .max_signal = 7,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ssp0_rx",
+ .min_signal = 8,
+ .max_signal = 8,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ssp0_tx",
+ .min_signal = 9,
+ .max_signal = 9,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "i2c_rx",
+ .min_signal = 10,
+ .max_signal = 10,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "i2c_tx",
+ .min_signal = 11,
+ .max_signal = 11,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "irda",
+ .min_signal = 12,
+ .max_signal = 12,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "adc",
+ .min_signal = 13,
+ .max_signal = 13,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "to_jpeg",
+ .min_signal = 14,
+ .max_signal = 14,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "from_jpeg",
+ .min_signal = 15,
+ .max_signal = 15,
+ .muxval = 0,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras0_rx",
+ .min_signal = 0,
+ .max_signal = 0,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras0_tx",
+ .min_signal = 1,
+ .max_signal = 1,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras1_rx",
+ .min_signal = 2,
+ .max_signal = 2,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras1_tx",
+ .min_signal = 3,
+ .max_signal = 3,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras2_rx",
+ .min_signal = 4,
+ .max_signal = 4,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras2_tx",
+ .min_signal = 5,
+ .max_signal = 5,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras3_rx",
+ .min_signal = 6,
+ .max_signal = 6,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras3_tx",
+ .min_signal = 7,
+ .max_signal = 7,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras4_rx",
+ .min_signal = 8,
+ .max_signal = 8,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras4_tx",
+ .min_signal = 9,
+ .max_signal = 9,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras5_rx",
+ .min_signal = 10,
+ .max_signal = 10,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras5_tx",
+ .min_signal = 11,
+ .max_signal = 11,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras6_rx",
+ .min_signal = 12,
+ .max_signal = 12,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras6_tx",
+ .min_signal = 13,
+ .max_signal = 13,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras7_rx",
+ .min_signal = 14,
+ .max_signal = 14,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ras7_tx",
+ .min_signal = 15,
+ .max_signal = 15,
+ .muxval = 1,
+ .periph_buses = PL08X_AHB1,
+ }, {
+ .bus_id = "ext0_rx",
+ .min_signal = 0,
+ .max_signal = 0,
+ .muxval = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ext0_tx",
+ .min_signal = 1,
+ .max_signal = 1,
+ .muxval = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ext1_rx",
+ .min_signal = 2,
+ .max_signal = 2,
+ .muxval = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ext1_tx",
+ .min_signal = 3,
+ .max_signal = 3,
+ .muxval = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ext2_rx",
+ .min_signal = 4,
+ .max_signal = 4,
+ .muxval = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ext2_tx",
+ .min_signal = 5,
+ .max_signal = 5,
+ .muxval = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ext3_rx",
+ .min_signal = 6,
+ .max_signal = 6,
+ .muxval = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ext3_tx",
+ .min_signal = 7,
+ .max_signal = 7,
+ .muxval = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ext4_rx",
+ .min_signal = 8,
+ .max_signal = 8,
+ .muxval = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ext4_tx",
+ .min_signal = 9,
+ .max_signal = 9,
+ .muxval = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ext5_rx",
+ .min_signal = 10,
+ .max_signal = 10,
+ .muxval = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ext5_tx",
+ .min_signal = 11,
+ .max_signal = 11,
+ .muxval = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ext6_rx",
+ .min_signal = 12,
+ .max_signal = 12,
+ .muxval = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ext6_tx",
+ .min_signal = 13,
+ .max_signal = 13,
+ .muxval = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ext7_rx",
+ .min_signal = 14,
+ .max_signal = 14,
+ .muxval = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ext7_tx",
+ .min_signal = 15,
+ .max_signal = 15,
+ .muxval = 2,
+ .periph_buses = PL08X_AHB2,
+ },
+};
+
+static struct pl08x_platform_data spear6xx_pl080_plat_data = {
+ .memcpy_channel = {
+ .bus_id = "memcpy",
+ .cctl_memcpy =
+ (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
+ PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \
+ PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \
+ PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \
+ PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | \
+ PL080_CONTROL_PROT_SYS),
+ },
+ .lli_buses = PL08X_AHB1,
+ .mem_buses = PL08X_AHB1,
+ .get_xfer_signal = pl080_get_signal,
+ .put_xfer_signal = pl080_put_signal,
+ .slave_channels = spear600_dma_info,
+ .num_slave_channels = ARRAY_SIZE(spear600_dma_info),
+};
+
+/*
+ * Following will create 16MB static virtual/physical mappings
+ * PHYSICAL VIRTUAL
+ * 0xF0000000 0xF0000000
+ * 0xF1000000 0xF1000000
+ * 0xD0000000 0xFD000000
+ * 0xFC000000 0xFC000000
+ */
+struct map_desc spear6xx_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long)VA_SPEAR6XX_ML_CPU_BASE,
+ .pfn = __phys_to_pfn(SPEAR_ICM3_ML1_2_BASE),
+ .length = 2 * SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = (unsigned long)VA_SPEAR_ICM1_2_BASE,
+ .pfn = __phys_to_pfn(SPEAR_ICM1_2_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = (unsigned long)VA_SPEAR_ICM3_SMI_CTRL_BASE,
+ .pfn = __phys_to_pfn(SPEAR_ICM3_SMI_CTRL_BASE),
+ .length = SZ_16M,
+ .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));
+}
+
+void __init spear6xx_timer_init(void)
+{
+ char pclk_name[] = "pll3_clk";
+ struct clk *gpt_clk, *pclk;
+
+ spear6xx_clk_init(MISC_BASE);
+
+ /* 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_of_timer();
+}
+
+/* Add auxdata to pass platform data */
+struct of_dev_auxdata spear6xx_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("arm,pl080", SPEAR_ICM3_DMA_BASE, NULL,
+ &spear6xx_pl080_plat_data),
+ {}
+};
+
+static void __init spear600_dt_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table,
+ spear6xx_auxdata_lookup, NULL);
+}
+
+static const char *spear600_dt_board_compat[] = {
+ "st,spear600",
+ NULL
+};
+
+DT_MACHINE_START(SPEAR600_DT, "ST SPEAr600 (Flattened Device Tree)")
+ .map_io = spear6xx_map_io,
+ .init_time = spear6xx_timer_init,
+ .init_machine = spear600_dt_init,
+ .restart = spear_restart,
+ .dt_compat = spear600_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear/time.c b/arch/arm/mach-spear/time.c
new file mode 100644
index 000000000..26fda4ed4
--- /dev/null
+++ b/arch/arm/mach-spear/time.c
@@ -0,0 +1,245 @@
+/*
+ * arch/arm/plat-spear/time.c
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim<shiraz.linux.kernel@gmail.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/ioport.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/time.h>
+#include <linux/irq.h>
+#include <asm/mach/time.h>
+#include "generic.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 __init 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 = readw(gpt_base + CR(CLKEVT));
+
+ if (val & CTRL_ENABLE)
+ writew(val & ~CTRL_ENABLE, gpt_base + CR(CLKEVT));
+
+ writew(cycles, gpt_base + LOAD(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_TIMER,
+ .handler = spear_timer_interrupt
+};
+
+static void __init spear_clockevent_init(int irq)
+{
+ u32 tick_rate;
+
+ /* program the prescaler */
+ writew(CTRL_PRESCALER16, gpt_base + CR(CLKEVT));
+
+ tick_rate = clk_get_rate(gpt_clk);
+ tick_rate >>= CTRL_PRESCALER16;
+
+ clkevt.cpumask = cpumask_of(0);
+
+ clockevents_config_and_register(&clkevt, tick_rate, 3, 0xfff0);
+
+ setup_irq(irq, &spear_timer_irq);
+}
+
+const static struct of_device_id timer_of_match[] __initconst = {
+ { .compatible = "st,spear-timer", },
+ { },
+};
+
+void __init spear_setup_of_timer(void)
+{
+ struct device_node *np;
+ int irq, ret;
+
+ np = of_find_matching_node(NULL, timer_of_match);
+ if (!np) {
+ pr_err("%s: No timer passed via DT\n", __func__);
+ return;
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq) {
+ pr_err("%s: No irq passed for timer via DT\n", __func__);
+ return;
+ }
+
+ gpt_base = of_iomap(np, 0);
+ if (!gpt_base) {
+ pr_err("%s: of iomap failed\n", __func__);
+ return;
+ }
+
+ 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_prepare_enable(gpt_clk);
+ if (ret < 0) {
+ pr_err("%s:couldn't prepare-enable gpt clock\n", __func__);
+ goto err_prepare_enable_clk;
+ }
+
+ spear_clockevent_init(irq);
+ spear_clocksource_init();
+
+ return;
+
+err_prepare_enable_clk:
+ clk_put(gpt_clk);
+err_iomap:
+ iounmap(gpt_base);
+}
diff --git a/arch/arm/mach-sti/Kconfig b/arch/arm/mach-sti/Kconfig
new file mode 100644
index 000000000..3b1ac463a
--- /dev/null
+++ b/arch/arm/mach-sti/Kconfig
@@ -0,0 +1,56 @@
+menuconfig ARCH_STI
+ bool "STMicroelectronics Consumer Electronics SOCs" if ARCH_MULTI_V7
+ select ARM_GIC
+ select ARM_GLOBAL_TIMER
+ select PINCTRL
+ select PINCTRL_ST
+ select MFD_SYSCON
+ select ARCH_HAS_RESET_CONTROLLER
+ select HAVE_ARM_SCU if SMP
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_764369 if SMP
+ select ARM_ERRATA_775420
+ select PL310_ERRATA_753970 if CACHE_L2X0
+ select PL310_ERRATA_769419 if CACHE_L2X0
+ select RESET_CONTROLLER
+ help
+ Include support for STiH41x SOCs like STiH415/416 using the device tree
+ for discovery
+ More information at Documentation/arm/STiH41x and
+ at Documentation/devicetree
+
+
+if ARCH_STI
+
+config SOC_STIH415
+ bool "STiH415 STMicroelectronics Consumer Electronics family"
+ default y
+ select STIH415_RESET
+ help
+ This enables support for STMicroelectronics Digital Consumer
+ Electronics family StiH415 parts, primarily targeted at set-top-box
+ and other digital audio/video applications using Flattned Device
+ Trees.
+
+config SOC_STIH416
+ bool "STiH416 STMicroelectronics Consumer Electronics family"
+ default y
+ select STIH416_RESET
+ help
+ This enables support for STMicroelectronics Digital Consumer
+ Electronics family StiH416 parts, primarily targeted at set-top-box
+ and other digital audio/video applications using Flattened Device
+ Trees.
+
+config SOC_STIH407
+ bool "STiH407 STMicroelectronics Consumer Electronics family"
+ default y
+ select STIH407_RESET
+ help
+ This enables support for STMicroelectronics Digital Consumer
+ Electronics family StiH407 parts, targetted at set-top-box
+ and other digital audio/video applications using Flattened Device
+ Trees.
+
+endif
diff --git a/arch/arm/mach-sti/Makefile b/arch/arm/mach-sti/Makefile
new file mode 100644
index 000000000..acb330916
--- /dev/null
+++ b/arch/arm/mach-sti/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+obj-$(CONFIG_ARCH_STI) += board-dt.o
diff --git a/arch/arm/mach-sti/board-dt.c b/arch/arm/mach-sti/board-dt.c
new file mode 100644
index 000000000..b373acade
--- /dev/null
+++ b/arch/arm/mach-sti/board-dt.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author(s): Srinivas Kandagatla <srinivas.kandagatla@st.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/irq.h>
+#include <linux/of_platform.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/arch.h>
+
+#include "smp.h"
+
+static const char *stih41x_dt_match[] __initdata = {
+ "st,stih415",
+ "st,stih416",
+ "st,stih407",
+ "st,stih410",
+ "st,stih418",
+ NULL
+};
+
+DT_MACHINE_START(STM, "STiH415/416 SoC with Flattened Device Tree")
+ .dt_compat = stih41x_dt_match,
+ .l2c_aux_val = L2C_AUX_CTRL_SHARED_OVERRIDE |
+ L310_AUX_CTRL_DATA_PREFETCH |
+ L310_AUX_CTRL_INSTR_PREFETCH |
+ L2C_AUX_CTRL_WAY_SIZE(4),
+ .l2c_aux_mask = 0xc0000fff,
+ .smp = smp_ops(sti_smp_ops),
+MACHINE_END
diff --git a/arch/arm/mach-sti/headsmp.S b/arch/arm/mach-sti/headsmp.S
new file mode 100644
index 000000000..4c09bae86
--- /dev/null
+++ b/arch/arm/mach-sti/headsmp.S
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/mach-sti/headsmp.S
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * http://www.st.com
+ *
+ * Cloned from linux/arch/arm/mach-vexpress/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>
+
+/*
+ * ST 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(sti_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-sti/platsmp.c b/arch/arm/mach-sti/platsmp.c
new file mode 100644
index 000000000..d4b624f8d
--- /dev/null
+++ b/arch/arm/mach-sti/platsmp.c
@@ -0,0 +1,116 @@
+/*
+ * arch/arm/mach-sti/platsmp.c
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * http://www.st.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/smp.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+#include "smp.h"
+
+static void write_pen_release(int val)
+{
+ pen_release = val;
+ smp_wmb();
+ sync_cache_w(&pen_release);
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+static void sti_secondary_init(unsigned int cpu)
+{
+ trace_hardirqs_off();
+
+ /*
+ * 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);
+}
+
+static int sti_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_logical_map(cpu));
+
+ /*
+ * Send the secondary CPU a soft interrupt, thereby causing
+ * it to jump to the secondary entrypoint.
+ */
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+ 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;
+}
+
+static void __init sti_smp_prepare_cpus(unsigned int max_cpus)
+{
+ void __iomem *scu_base = NULL;
+ struct device_node *np = of_find_compatible_node(
+ NULL, NULL, "arm,cortex-a9-scu");
+ if (np) {
+ scu_base = of_iomap(np, 0);
+ scu_enable(scu_base);
+ of_node_put(np);
+ }
+}
+
+struct smp_operations __initdata sti_smp_ops = {
+ .smp_prepare_cpus = sti_smp_prepare_cpus,
+ .smp_secondary_init = sti_secondary_init,
+ .smp_boot_secondary = sti_boot_secondary,
+};
diff --git a/arch/arm/mach-sti/smp.h b/arch/arm/mach-sti/smp.h
new file mode 100644
index 000000000..1871b72b1
--- /dev/null
+++ b/arch/arm/mach-sti/smp.h
@@ -0,0 +1,17 @@
+/*
+ * arch/arm/mach-sti/smp.h
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * http://www.st.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_STI_SMP_H
+#define __MACH_STI_SMP_H
+
+extern struct smp_operations sti_smp_ops;
+
+#endif
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
new file mode 100644
index 000000000..81502b90d
--- /dev/null
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -0,0 +1,48 @@
+menuconfig ARCH_SUNXI
+ bool "Allwinner SoCs" if ARCH_MULTI_V7
+ select ARCH_REQUIRE_GPIOLIB
+ select ARCH_HAS_RESET_CONTROLLER
+ select CLKSRC_MMIO
+ select GENERIC_IRQ_CHIP
+ select PINCTRL
+ select SUN4I_TIMER
+ select RESET_CONTROLLER
+
+if ARCH_SUNXI
+
+config MACH_SUN4I
+ bool "Allwinner A10 (sun4i) SoCs support"
+ default ARCH_SUNXI
+
+config MACH_SUN5I
+ bool "Allwinner A10s / A13 (sun5i) SoCs support"
+ default ARCH_SUNXI
+ select SUN5I_HSTIMER
+
+config MACH_SUN6I
+ bool "Allwinner A31 (sun6i) SoCs support"
+ default ARCH_SUNXI
+ select ARM_GIC
+ select MFD_SUN6I_PRCM
+ select SUN5I_HSTIMER
+
+config MACH_SUN7I
+ bool "Allwinner A20 (sun7i) SoCs support"
+ default ARCH_SUNXI
+ select ARM_GIC
+ select ARM_PSCI
+ select HAVE_ARM_ARCH_TIMER
+ select SUN5I_HSTIMER
+
+config MACH_SUN8I
+ bool "Allwinner A23 (sun8i) SoCs support"
+ default ARCH_SUNXI
+ select ARM_GIC
+ select MFD_SUN6I_PRCM
+
+config MACH_SUN9I
+ bool "Allwinner (sun9i) SoCs support"
+ default ARCH_SUNXI
+ select ARM_GIC
+
+endif
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
new file mode 100644
index 000000000..27b168f12
--- /dev/null
+++ b/arch/arm/mach-sunxi/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
+obj-$(CONFIG_SMP) += platsmp.o
diff --git a/arch/arm/mach-sunxi/platsmp.c b/arch/arm/mach-sunxi/platsmp.c
new file mode 100644
index 000000000..587b0468e
--- /dev/null
+++ b/arch/arm/mach-sunxi/platsmp.c
@@ -0,0 +1,123 @@
+/*
+ * SMP support for Allwinner SoCs
+ *
+ * Copyright (C) 2013 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * Based on code
+ * Copyright (C) 2012-2013 Allwinner 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/memory.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/smp.h>
+
+#define CPUCFG_CPU_PWR_CLAMP_STATUS_REG(cpu) ((cpu) * 0x40 + 0x64)
+#define CPUCFG_CPU_RST_CTRL_REG(cpu) (((cpu) + 1) * 0x40)
+#define CPUCFG_CPU_CTRL_REG(cpu) (((cpu) + 1) * 0x40 + 0x04)
+#define CPUCFG_CPU_STATUS_REG(cpu) (((cpu) + 1) * 0x40 + 0x08)
+#define CPUCFG_GEN_CTRL_REG 0x184
+#define CPUCFG_PRIVATE0_REG 0x1a4
+#define CPUCFG_PRIVATE1_REG 0x1a8
+#define CPUCFG_DBG_CTL0_REG 0x1e0
+#define CPUCFG_DBG_CTL1_REG 0x1e4
+
+#define PRCM_CPU_PWROFF_REG 0x100
+#define PRCM_CPU_PWR_CLAMP_REG(cpu) (((cpu) * 4) + 0x140)
+
+static void __iomem *cpucfg_membase;
+static void __iomem *prcm_membase;
+
+static DEFINE_SPINLOCK(cpu_lock);
+
+static void __init sun6i_smp_prepare_cpus(unsigned int max_cpus)
+{
+ struct device_node *node;
+
+ node = of_find_compatible_node(NULL, NULL, "allwinner,sun6i-a31-prcm");
+ if (!node) {
+ pr_err("Missing A31 PRCM node in the device tree\n");
+ return;
+ }
+
+ prcm_membase = of_iomap(node, 0);
+ if (!prcm_membase) {
+ pr_err("Couldn't map A31 PRCM registers\n");
+ return;
+ }
+
+ node = of_find_compatible_node(NULL, NULL,
+ "allwinner,sun6i-a31-cpuconfig");
+ if (!node) {
+ pr_err("Missing A31 CPU config node in the device tree\n");
+ return;
+ }
+
+ cpucfg_membase = of_iomap(node, 0);
+ if (!cpucfg_membase)
+ pr_err("Couldn't map A31 CPU config registers\n");
+
+}
+
+static int sun6i_smp_boot_secondary(unsigned int cpu,
+ struct task_struct *idle)
+{
+ u32 reg;
+ int i;
+
+ if (!(prcm_membase && cpucfg_membase))
+ return -EFAULT;
+
+ spin_lock(&cpu_lock);
+
+ /* Set CPU boot address */
+ writel(virt_to_phys(secondary_startup),
+ cpucfg_membase + CPUCFG_PRIVATE0_REG);
+
+ /* Assert the CPU core in reset */
+ writel(0, cpucfg_membase + CPUCFG_CPU_RST_CTRL_REG(cpu));
+
+ /* Assert the L1 cache in reset */
+ reg = readl(cpucfg_membase + CPUCFG_GEN_CTRL_REG);
+ writel(reg & ~BIT(cpu), cpucfg_membase + CPUCFG_GEN_CTRL_REG);
+
+ /* Disable external debug access */
+ reg = readl(cpucfg_membase + CPUCFG_DBG_CTL1_REG);
+ writel(reg & ~BIT(cpu), cpucfg_membase + CPUCFG_DBG_CTL1_REG);
+
+ /* Power up the CPU */
+ for (i = 0; i <= 8; i++)
+ writel(0xff >> i, prcm_membase + PRCM_CPU_PWR_CLAMP_REG(cpu));
+ mdelay(10);
+
+ /* Clear CPU power-off gating */
+ reg = readl(prcm_membase + PRCM_CPU_PWROFF_REG);
+ writel(reg & ~BIT(cpu), prcm_membase + PRCM_CPU_PWROFF_REG);
+ mdelay(1);
+
+ /* Deassert the CPU core reset */
+ writel(3, cpucfg_membase + CPUCFG_CPU_RST_CTRL_REG(cpu));
+
+ /* Enable back the external debug accesses */
+ reg = readl(cpucfg_membase + CPUCFG_DBG_CTL1_REG);
+ writel(reg | BIT(cpu), cpucfg_membase + CPUCFG_DBG_CTL1_REG);
+
+ spin_unlock(&cpu_lock);
+
+ return 0;
+}
+
+static struct smp_operations sun6i_smp_ops __initdata = {
+ .smp_prepare_cpus = sun6i_smp_prepare_cpus,
+ .smp_boot_secondary = sun6i_smp_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(sun6i_a31_smp, "allwinner,sun6i-a31", &sun6i_smp_ops);
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
new file mode 100644
index 000000000..1bc811a74
--- /dev/null
+++ b/arch/arm/mach-sunxi/sunxi.c
@@ -0,0 +1,85 @@
+/*
+ * Device Tree support for Allwinner A1X SoCs
+ *
+ * Copyright (C) 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.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-provider.h>
+#include <linux/clocksource.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+
+static void __init sunxi_dt_cpufreq_init(void)
+{
+ platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+}
+
+static const char * const sunxi_board_dt_compat[] = {
+ "allwinner,sun4i-a10",
+ "allwinner,sun5i-a10s",
+ "allwinner,sun5i-a13",
+ NULL,
+};
+
+DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)")
+ .dt_compat = sunxi_board_dt_compat,
+ .init_late = sunxi_dt_cpufreq_init,
+MACHINE_END
+
+static const char * const sun6i_board_dt_compat[] = {
+ "allwinner,sun6i-a31",
+ "allwinner,sun6i-a31s",
+ NULL,
+};
+
+extern void __init sun6i_reset_init(void);
+static void __init sun6i_timer_init(void)
+{
+ of_clk_init(NULL);
+ if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
+ sun6i_reset_init();
+ clocksource_of_init();
+}
+
+DT_MACHINE_START(SUN6I_DT, "Allwinner sun6i (A31) Family")
+ .init_time = sun6i_timer_init,
+ .dt_compat = sun6i_board_dt_compat,
+ .init_late = sunxi_dt_cpufreq_init,
+MACHINE_END
+
+static const char * const sun7i_board_dt_compat[] = {
+ "allwinner,sun7i-a20",
+ NULL,
+};
+
+DT_MACHINE_START(SUN7I_DT, "Allwinner sun7i (A20) Family")
+ .dt_compat = sun7i_board_dt_compat,
+ .init_late = sunxi_dt_cpufreq_init,
+MACHINE_END
+
+static const char * const sun8i_board_dt_compat[] = {
+ "allwinner,sun8i-a23",
+ NULL,
+};
+
+DT_MACHINE_START(SUN8I_DT, "Allwinner sun8i (A23) Family")
+ .dt_compat = sun8i_board_dt_compat,
+ .init_late = sunxi_dt_cpufreq_init,
+MACHINE_END
+
+static const char * const sun9i_board_dt_compat[] = {
+ "allwinner,sun9i-a80",
+ NULL,
+};
+
+DT_MACHINE_START(SUN9I_DT, "Allwinner sun9i Family")
+ .dt_compat = sun9i_board_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
new file mode 100644
index 000000000..5d1a318f1
--- /dev/null
+++ b/arch/arm/mach-tegra/Kconfig
@@ -0,0 +1,67 @@
+menuconfig ARCH_TEGRA
+ bool "NVIDIA Tegra" if ARCH_MULTI_V7
+ select ARCH_REQUIRE_GPIOLIB
+ select ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
+ select ARM_AMBA
+ select ARM_GIC
+ select CLKSRC_MMIO
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select PINCTRL
+ select ARCH_HAS_RESET_CONTROLLER
+ select RESET_CONTROLLER
+ select SOC_BUS
+ select USB_ULPI if USB_PHY
+ select USB_ULPI_VIEWPORT if USB_PHY
+ help
+ This enables support for NVIDIA Tegra based systems.
+
+if ARCH_TEGRA
+
+config ARCH_TEGRA_2x_SOC
+ bool "Enable support for Tegra20 family"
+ select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
+ select ARM_ERRATA_720789
+ select ARM_ERRATA_754327 if SMP
+ select ARM_ERRATA_764369 if SMP
+ select PINCTRL_TEGRA20
+ select PL310_ERRATA_727915 if CACHE_L2X0
+ select PL310_ERRATA_769419 if CACHE_L2X0
+ select TEGRA_TIMER
+ help
+ Support for NVIDIA Tegra AP20 and T20 processors, based on the
+ ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
+
+config ARCH_TEGRA_3x_SOC
+ bool "Enable support for Tegra30 family"
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_764369 if SMP
+ select PINCTRL_TEGRA30
+ select PL310_ERRATA_769419 if CACHE_L2X0
+ select TEGRA_TIMER
+ help
+ Support for NVIDIA Tegra T30 processor family, based on the
+ ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
+
+config ARCH_TEGRA_114_SOC
+ bool "Enable support for Tegra114 family"
+ select ARM_ERRATA_798181 if SMP
+ select ARM_L1_CACHE_SHIFT_6
+ select HAVE_ARM_ARCH_TIMER
+ select PINCTRL_TEGRA114
+ select TEGRA_TIMER
+ help
+ Support for NVIDIA Tegra T114 processor family, based on the
+ ARM CortexA15MP CPU
+
+config ARCH_TEGRA_124_SOC
+ bool "Enable support for Tegra124 family"
+ select ARM_L1_CACHE_SHIFT_6
+ select HAVE_ARM_ARCH_TIMER
+ select PINCTRL_TEGRA124
+ select TEGRA_TIMER
+ help
+ Support for NVIDIA Tegra T124 processor family, based on the
+ ARM CortexA15MP CPU
+
+endif
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
new file mode 100644
index 000000000..e48a74458
--- /dev/null
+++ b/arch/arm/mach-tegra/Makefile
@@ -0,0 +1,36 @@
+asflags-y += -march=armv7-a
+
+obj-y += io.o
+obj-y += irq.o
+obj-y += flowctrl.o
+obj-y += pm.o
+obj-y += reset.o
+obj-y += reset-handler.o
+obj-y += sleep.o
+obj-y += tegra.o
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-tegra20.o
+ifeq ($(CONFIG_CPU_IDLE),y)
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o
+endif
+obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o
+obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pm-tegra30.o
+ifeq ($(CONFIG_CPU_IDLE),y)
+obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += cpuidle-tegra30.o
+endif
+obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+
+obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o
+obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o
+ifeq ($(CONFIG_CPU_IDLE),y)
+obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o
+endif
+obj-$(CONFIG_ARCH_TEGRA_124_SOC) += sleep-tegra30.o
+obj-$(CONFIG_ARCH_TEGRA_124_SOC) += pm-tegra30.o
+ifeq ($(CONFIG_CPU_IDLE),y)
+obj-$(CONFIG_ARCH_TEGRA_124_SOC) += cpuidle-tegra114.o
+endif
+
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-paz00.o
diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c
new file mode 100644
index 000000000..fbe74c680
--- /dev/null
+++ b/arch/arm/mach-tegra/board-paz00.c
@@ -0,0 +1,52 @@
+/*
+ * 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/gpio/machine.h>
+#include <linux/platform_device.h>
+#include <linux/rfkill-gpio.h>
+
+#include "board.h"
+
+static struct rfkill_gpio_platform_data wifi_rfkill_platform_data = {
+ .name = "wifi_rfkill",
+ .type = RFKILL_TYPE_WLAN,
+};
+
+static struct platform_device wifi_rfkill_device = {
+ .name = "rfkill_gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &wifi_rfkill_platform_data,
+ },
+};
+
+static struct gpiod_lookup_table wifi_gpio_lookup = {
+ .dev_id = "rfkill_gpio",
+ .table = {
+ GPIO_LOOKUP_IDX("tegra-gpio", 25, NULL, 0, 0),
+ GPIO_LOOKUP_IDX("tegra-gpio", 85, NULL, 1, 0),
+ { },
+ },
+};
+
+void __init tegra_paz00_wifikill_init(void)
+{
+ gpiod_add_lookup_table(&wifi_gpio_lookup);
+ platform_device_register(&wifi_rfkill_device);
+}
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
new file mode 100644
index 000000000..da90c8929
--- /dev/null
+++ b/arch/arm/mach-tegra/board.h
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/mach-tegra/board.h
+ *
+ * Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+ * 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>
+#include <linux/reboot.h>
+
+void __init tegra_map_common_io(void);
+void __init tegra_init_irq(void);
+
+void __init tegra_paz00_wifikill_init(void);
+
+#endif
diff --git a/arch/arm/mach-tegra/common.h b/arch/arm/mach-tegra/common.h
new file mode 100644
index 000000000..5900cc44f
--- /dev/null
+++ b/arch/arm/mach-tegra/common.h
@@ -0,0 +1,4 @@
+extern struct smp_operations tegra_smp_ops;
+
+extern int tegra_cpu_kill(unsigned int cpu);
+extern void tegra_cpu_die(unsigned int cpu);
diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c
new file mode 100644
index 000000000..155807fa6
--- /dev/null
+++ b/arch/arm/mach-tegra/cpuidle-tegra114.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2013, NVIDIA Corporation. 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <asm/firmware.h>
+#include <linux/tick.h>
+#include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/cpuidle.h>
+#include <asm/smp_plat.h>
+#include <asm/suspend.h>
+
+#include "pm.h"
+#include "sleep.h"
+
+#ifdef CONFIG_PM_SLEEP
+#define TEGRA114_MAX_STATES 2
+#else
+#define TEGRA114_MAX_STATES 1
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int tegra114_idle_power_down(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ local_fiq_disable();
+
+ tegra_set_cpu_in_lp2();
+ cpu_pm_enter();
+
+ tick_broadcast_enter();
+
+ call_firmware_op(prepare_idle);
+
+ /* Do suspend by ourselves if the firmware does not implement it */
+ if (call_firmware_op(do_idle, 0) == -ENOSYS)
+ cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
+
+ tick_broadcast_exit();
+
+ cpu_pm_exit();
+ tegra_clear_cpu_in_lp2();
+
+ local_fiq_enable();
+
+ return index;
+}
+#endif
+
+static struct cpuidle_driver tegra_idle_driver = {
+ .name = "tegra_idle",
+ .owner = THIS_MODULE,
+ .state_count = TEGRA114_MAX_STATES,
+ .states = {
+ [0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
+#ifdef CONFIG_PM_SLEEP
+ [1] = {
+ .enter = tegra114_idle_power_down,
+ .exit_latency = 500,
+ .target_residency = 1000,
+ .power_usage = 0,
+ .name = "powered-down",
+ .desc = "CPU power gated",
+ },
+#endif
+ },
+};
+
+int __init tegra114_cpuidle_init(void)
+{
+ return cpuidle_register(&tegra_idle_driver, NULL);
+}
diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c
new file mode 100644
index 000000000..7469347b1
--- /dev/null
+++ b/arch/arm/mach-tegra/cpuidle-tegra20.c
@@ -0,0 +1,226 @@
+/*
+ * CPU idle driver for Tegra CPUs
+ *
+ * Copyright (c) 2010-2012, NVIDIA Corporation.
+ * Copyright (c) 2011 Google, Inc.
+ * Author: Colin Cross <ccross@android.com>
+ * Gary King <gking@nvidia.com>
+ *
+ * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.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/clk/tegra.h>
+#include <linux/tick.h>
+#include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/cpuidle.h>
+#include <asm/smp_plat.h>
+#include <asm/suspend.h>
+
+#include "flowctrl.h"
+#include "iomap.h"
+#include "irq.h"
+#include "pm.h"
+#include "reset.h"
+#include "sleep.h"
+
+#ifdef CONFIG_PM_SLEEP
+static bool abort_flag;
+static atomic_t abort_barrier;
+static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index);
+#define TEGRA20_MAX_STATES 2
+#else
+#define TEGRA20_MAX_STATES 1
+#endif
+
+static struct cpuidle_driver tegra_idle_driver = {
+ .name = "tegra_idle",
+ .owner = THIS_MODULE,
+ .states = {
+ ARM_CPUIDLE_WFI_STATE_PWR(600),
+#ifdef CONFIG_PM_SLEEP
+ {
+ .enter = tegra20_idle_lp2_coupled,
+ .exit_latency = 5000,
+ .target_residency = 10000,
+ .power_usage = 0,
+ .flags = CPUIDLE_FLAG_COUPLED,
+ .name = "powered-down",
+ .desc = "CPU power gated",
+ },
+#endif
+ },
+ .state_count = TEGRA20_MAX_STATES,
+ .safe_state_index = 0,
+};
+
+#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_SMP
+static int tegra20_reset_sleeping_cpu_1(void)
+{
+ int ret = 0;
+
+ tegra_pen_lock();
+
+ if (readb(tegra20_cpu1_resettable_status) == CPU_RESETTABLE)
+ tegra20_cpu_shutdown(1);
+ else
+ ret = -EINVAL;
+
+ tegra_pen_unlock();
+
+ return ret;
+}
+
+static void tegra20_wake_cpu1_from_reset(void)
+{
+ tegra_pen_lock();
+
+ tegra20_cpu_clear_resettable();
+
+ /* enable cpu clock on cpu */
+ tegra_enable_cpu_clock(1);
+
+ /* take the CPU out of reset */
+ tegra_cpu_out_of_reset(1);
+
+ /* unhalt the cpu */
+ flowctrl_write_cpu_halt(1, 0);
+
+ tegra_pen_unlock();
+}
+
+static int tegra20_reset_cpu_1(void)
+{
+ if (!cpu_online(1) || !tegra20_reset_sleeping_cpu_1())
+ return 0;
+
+ tegra20_wake_cpu1_from_reset();
+ return -EBUSY;
+}
+#else
+static inline void tegra20_wake_cpu1_from_reset(void)
+{
+}
+
+static inline int tegra20_reset_cpu_1(void)
+{
+ return 0;
+}
+#endif
+
+static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ while (tegra20_cpu_is_resettable_soon())
+ cpu_relax();
+
+ if (tegra20_reset_cpu_1() || !tegra_cpu_rail_off_ready())
+ return false;
+
+ tick_broadcast_enter();
+
+ tegra_idle_lp2_last();
+
+ tick_broadcast_exit();
+
+ if (cpu_online(1))
+ tegra20_wake_cpu1_from_reset();
+
+ return true;
+}
+
+#ifdef CONFIG_SMP
+static bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ tick_broadcast_enter();
+
+ cpu_suspend(0, tegra20_sleep_cpu_secondary_finish);
+
+ tegra20_cpu_clear_resettable();
+
+ tick_broadcast_exit();
+
+ return true;
+}
+#else
+static inline bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ return true;
+}
+#endif
+
+static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ bool entered_lp2 = false;
+
+ if (tegra_pending_sgi())
+ ACCESS_ONCE(abort_flag) = true;
+
+ cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
+
+ if (abort_flag) {
+ cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
+ abort_flag = false; /* clean flag for next coming */
+ return -EINTR;
+ }
+
+ local_fiq_disable();
+
+ tegra_set_cpu_in_lp2();
+ cpu_pm_enter();
+
+ if (dev->cpu == 0)
+ entered_lp2 = tegra20_cpu_cluster_power_down(dev, drv, index);
+ else
+ entered_lp2 = tegra20_idle_enter_lp2_cpu_1(dev, drv, index);
+
+ cpu_pm_exit();
+ tegra_clear_cpu_in_lp2();
+
+ local_fiq_enable();
+
+ smp_rmb();
+
+ return entered_lp2 ? index : 0;
+}
+#endif
+
+/*
+ * Tegra20 HW appears to have a bug such that PCIe device interrupts, whether
+ * they are legacy IRQs or MSI, are lost when LP2 is enabled. To work around
+ * this, simply disable LP2 if the PCI driver and DT node are both enabled.
+ */
+void tegra20_cpuidle_pcie_irqs_in_use(void)
+{
+ pr_info_once(
+ "Disabling cpuidle LP2 state, since PCIe IRQs are in use\n");
+ tegra_idle_driver.states[1].disabled = true;
+}
+
+int __init tegra20_cpuidle_init(void)
+{
+ return cpuidle_register(&tegra_idle_driver, cpu_possible_mask);
+}
diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c
new file mode 100644
index 000000000..4dbe1dae9
--- /dev/null
+++ b/arch/arm/mach-tegra/cpuidle-tegra30.c
@@ -0,0 +1,147 @@
+/*
+ * CPU idle driver for Tegra CPUs
+ *
+ * Copyright (c) 2010-2012, NVIDIA Corporation.
+ * Copyright (c) 2011 Google, Inc.
+ * Author: Colin Cross <ccross@android.com>
+ * Gary King <gking@nvidia.com>
+ *
+ * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.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/clk/tegra.h>
+#include <linux/tick.h>
+#include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/cpuidle.h>
+#include <asm/smp_plat.h>
+#include <asm/suspend.h>
+
+#include "pm.h"
+#include "sleep.h"
+
+#ifdef CONFIG_PM_SLEEP
+static int tegra30_idle_lp2(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index);
+#endif
+
+static struct cpuidle_driver tegra_idle_driver = {
+ .name = "tegra_idle",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_PM_SLEEP
+ .state_count = 2,
+#else
+ .state_count = 1,
+#endif
+ .states = {
+ [0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
+#ifdef CONFIG_PM_SLEEP
+ [1] = {
+ .enter = tegra30_idle_lp2,
+ .exit_latency = 2000,
+ .target_residency = 2200,
+ .power_usage = 0,
+ .name = "powered-down",
+ .desc = "CPU power gated",
+ },
+#endif
+ },
+};
+
+#ifdef CONFIG_PM_SLEEP
+static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ /* All CPUs entering LP2 is not working.
+ * Don't let CPU0 enter LP2 when any secondary CPU is online.
+ */
+ if (num_online_cpus() > 1 || !tegra_cpu_rail_off_ready()) {
+ cpu_do_idle();
+ return false;
+ }
+
+ tick_broadcast_enter();
+
+ tegra_idle_lp2_last();
+
+ tick_broadcast_exit();
+
+ return true;
+}
+
+#ifdef CONFIG_SMP
+static bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ tick_broadcast_enter();
+
+ smp_wmb();
+
+ cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
+
+ tick_broadcast_exit();
+
+ return true;
+}
+#else
+static inline bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ return true;
+}
+#endif
+
+static int tegra30_idle_lp2(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ bool entered_lp2 = false;
+ bool last_cpu;
+
+ local_fiq_disable();
+
+ last_cpu = tegra_set_cpu_in_lp2();
+ cpu_pm_enter();
+
+ if (dev->cpu == 0) {
+ if (last_cpu)
+ entered_lp2 = tegra30_cpu_cluster_power_down(dev, drv,
+ index);
+ else
+ cpu_do_idle();
+ } else {
+ entered_lp2 = tegra30_cpu_core_power_down(dev, drv, index);
+ }
+
+ cpu_pm_exit();
+ tegra_clear_cpu_in_lp2();
+
+ local_fiq_enable();
+
+ smp_rmb();
+
+ return (entered_lp2) ? index : 0;
+}
+#endif
+
+int __init tegra30_cpuidle_init(void)
+{
+ return cpuidle_register(&tegra_idle_driver, NULL);
+}
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c
new file mode 100644
index 000000000..316563141
--- /dev/null
+++ b/arch/arm/mach-tegra/cpuidle.c
@@ -0,0 +1,59 @@
+/*
+ * arch/arm/mach-tegra/cpuidle.c
+ *
+ * CPU idle driver for Tegra CPUs
+ *
+ * Copyright (c) 2010-2012, NVIDIA Corporation.
+ * Copyright (c) 2011 Google, Inc.
+ * Author: Colin Cross <ccross@android.com>
+ * Gary King <gking@nvidia.com>
+ *
+ * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.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/module.h>
+
+#include <soc/tegra/fuse.h>
+
+#include "cpuidle.h"
+
+void __init tegra_cpuidle_init(void)
+{
+ switch (tegra_get_chip_id()) {
+ case TEGRA20:
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
+ tegra20_cpuidle_init();
+ break;
+ case TEGRA30:
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC))
+ tegra30_cpuidle_init();
+ break;
+ case TEGRA114:
+ case TEGRA124:
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
+ IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
+ tegra114_cpuidle_init();
+ break;
+ }
+}
+
+void tegra_cpuidle_pcie_irqs_in_use(void)
+{
+ switch (tegra_get_chip_id()) {
+ case TEGRA20:
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
+ tegra20_cpuidle_pcie_irqs_in_use();
+ break;
+ }
+}
diff --git a/arch/arm/mach-tegra/cpuidle.h b/arch/arm/mach-tegra/cpuidle.h
new file mode 100644
index 000000000..c017dab60
--- /dev/null
+++ b/arch/arm/mach-tegra/cpuidle.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012, NVIDIA Corporation. 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_TEGRA_CPUIDLE_H
+#define __MACH_TEGRA_CPUIDLE_H
+
+#ifdef CONFIG_CPU_IDLE
+int tegra20_cpuidle_init(void);
+void tegra20_cpuidle_pcie_irqs_in_use(void);
+int tegra30_cpuidle_init(void);
+int tegra114_cpuidle_init(void);
+void tegra_cpuidle_init(void);
+#else
+static inline void tegra_cpuidle_init(void) {}
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c
new file mode 100644
index 000000000..475e78399
--- /dev/null
+++ b/arch/arm/mach-tegra/flowctrl.c
@@ -0,0 +1,171 @@
+/*
+ * arch/arm/mach-tegra/flowctrl.c
+ *
+ * functions and macros to control the flowcontroller
+ *
+ * Copyright (c) 2010-2012, NVIDIA Corporation. 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 that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/cpumask.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <soc/tegra/fuse.h>
+
+#include "flowctrl.h"
+
+static u8 flowctrl_offset_halt_cpu[] = {
+ FLOW_CTRL_HALT_CPU0_EVENTS,
+ FLOW_CTRL_HALT_CPU1_EVENTS,
+ FLOW_CTRL_HALT_CPU1_EVENTS + 8,
+ FLOW_CTRL_HALT_CPU1_EVENTS + 16,
+};
+
+static u8 flowctrl_offset_cpu_csr[] = {
+ FLOW_CTRL_CPU0_CSR,
+ FLOW_CTRL_CPU1_CSR,
+ FLOW_CTRL_CPU1_CSR + 8,
+ FLOW_CTRL_CPU1_CSR + 16,
+};
+
+static void __iomem *tegra_flowctrl_base;
+
+static void flowctrl_update(u8 offset, u32 value)
+{
+ writel(value, tegra_flowctrl_base + offset);
+
+ /* ensure the update has reached the flow controller */
+ wmb();
+ readl_relaxed(tegra_flowctrl_base + offset);
+}
+
+u32 flowctrl_read_cpu_csr(unsigned int cpuid)
+{
+ u8 offset = flowctrl_offset_cpu_csr[cpuid];
+
+ return readl(tegra_flowctrl_base + offset);
+}
+
+void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value)
+{
+ return flowctrl_update(flowctrl_offset_cpu_csr[cpuid], value);
+}
+
+void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value)
+{
+ return flowctrl_update(flowctrl_offset_halt_cpu[cpuid], value);
+}
+
+void flowctrl_cpu_suspend_enter(unsigned int cpuid)
+{
+ unsigned int reg;
+ int i;
+
+ reg = flowctrl_read_cpu_csr(cpuid);
+ switch (tegra_get_chip_id()) {
+ case TEGRA20:
+ /* clear wfe bitmap */
+ reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;
+ /* clear wfi bitmap */
+ reg &= ~TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP;
+ /* pwr gating on wfe */
+ reg |= TEGRA20_FLOW_CTRL_CSR_WFE_CPU0 << cpuid;
+ break;
+ case TEGRA30:
+ case TEGRA114:
+ case TEGRA124:
+ /* clear wfe bitmap */
+ reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
+ /* clear wfi bitmap */
+ reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP;
+ /* pwr gating on wfi */
+ reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid;
+ break;
+ }
+ reg |= FLOW_CTRL_CSR_INTR_FLAG; /* clear intr flag */
+ reg |= FLOW_CTRL_CSR_EVENT_FLAG; /* clear event flag */
+ reg |= FLOW_CTRL_CSR_ENABLE; /* pwr gating */
+ flowctrl_write_cpu_csr(cpuid, reg);
+
+ for (i = 0; i < num_possible_cpus(); i++) {
+ if (i == cpuid)
+ continue;
+ reg = flowctrl_read_cpu_csr(i);
+ reg |= FLOW_CTRL_CSR_EVENT_FLAG;
+ reg |= FLOW_CTRL_CSR_INTR_FLAG;
+ flowctrl_write_cpu_csr(i, reg);
+ }
+}
+
+void flowctrl_cpu_suspend_exit(unsigned int cpuid)
+{
+ unsigned int reg;
+
+ /* Disable powergating via flow controller for CPU0 */
+ reg = flowctrl_read_cpu_csr(cpuid);
+ switch (tegra_get_chip_id()) {
+ case TEGRA20:
+ /* clear wfe bitmap */
+ reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;
+ /* clear wfi bitmap */
+ reg &= ~TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP;
+ break;
+ case TEGRA30:
+ case TEGRA114:
+ case TEGRA124:
+ /* clear wfe bitmap */
+ reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
+ /* clear wfi bitmap */
+ reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP;
+ break;
+ }
+ reg &= ~FLOW_CTRL_CSR_ENABLE; /* clear enable */
+ reg |= FLOW_CTRL_CSR_INTR_FLAG; /* clear intr */
+ reg |= FLOW_CTRL_CSR_EVENT_FLAG; /* clear event */
+ flowctrl_write_cpu_csr(cpuid, reg);
+}
+
+static const struct of_device_id matches[] __initconst = {
+ { .compatible = "nvidia,tegra124-flowctrl" },
+ { .compatible = "nvidia,tegra114-flowctrl" },
+ { .compatible = "nvidia,tegra30-flowctrl" },
+ { .compatible = "nvidia,tegra20-flowctrl" },
+ { }
+};
+
+void __init tegra_flowctrl_init(void)
+{
+ /* hardcoded fallback if device tree node is missing */
+ unsigned long base = 0x60007000;
+ unsigned long size = SZ_4K;
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, matches);
+ if (np) {
+ struct resource res;
+
+ if (of_address_to_resource(np, 0, &res) == 0) {
+ size = resource_size(&res);
+ base = res.start;
+ }
+
+ of_node_put(np);
+ }
+
+ tegra_flowctrl_base = ioremap_nocache(base, size);
+}
diff --git a/arch/arm/mach-tegra/flowctrl.h b/arch/arm/mach-tegra/flowctrl.h
new file mode 100644
index 000000000..73a9c5016
--- /dev/null
+++ b/arch/arm/mach-tegra/flowctrl.h
@@ -0,0 +1,66 @@
+/*
+ * arch/arm/mach-tegra/flowctrl.h
+ *
+ * functions and macros to control the flowcontroller
+ *
+ * Copyright (c) 2010-2012, NVIDIA Corporation. 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 that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_TEGRA_FLOWCTRL_H
+#define __MACH_TEGRA_FLOWCTRL_H
+
+#define FLOW_CTRL_HALT_CPU0_EVENTS 0x0
+#define FLOW_CTRL_WAITEVENT (2 << 29)
+#define FLOW_CTRL_WAIT_FOR_INTERRUPT (4 << 29)
+#define FLOW_CTRL_JTAG_RESUME (1 << 28)
+#define FLOW_CTRL_SCLK_RESUME (1 << 27)
+#define FLOW_CTRL_HALT_CPU_IRQ (1 << 10)
+#define FLOW_CTRL_HALT_CPU_FIQ (1 << 8)
+#define FLOW_CTRL_HALT_LIC_IRQ (1 << 11)
+#define FLOW_CTRL_HALT_LIC_FIQ (1 << 10)
+#define FLOW_CTRL_HALT_GIC_IRQ (1 << 9)
+#define FLOW_CTRL_HALT_GIC_FIQ (1 << 8)
+#define FLOW_CTRL_CPU0_CSR 0x8
+#define FLOW_CTRL_CSR_INTR_FLAG (1 << 15)
+#define FLOW_CTRL_CSR_EVENT_FLAG (1 << 14)
+#define FLOW_CTRL_CSR_ENABLE_EXT_CRAIL (1 << 13)
+#define FLOW_CTRL_CSR_ENABLE_EXT_NCPU (1 << 12)
+#define FLOW_CTRL_CSR_ENABLE_EXT_MASK ( \
+ FLOW_CTRL_CSR_ENABLE_EXT_NCPU | \
+ FLOW_CTRL_CSR_ENABLE_EXT_CRAIL)
+#define FLOW_CTRL_CSR_ENABLE (1 << 0)
+#define FLOW_CTRL_HALT_CPU1_EVENTS 0x14
+#define FLOW_CTRL_CPU1_CSR 0x18
+
+#define TEGRA20_FLOW_CTRL_CSR_WFE_CPU0 (1 << 4)
+#define TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP (3 << 4)
+#define TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP 0
+
+#define TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 (1 << 8)
+#define TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP (0xF << 4)
+#define TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP (0xF << 8)
+
+#ifndef __ASSEMBLY__
+u32 flowctrl_read_cpu_csr(unsigned int cpuid);
+void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value);
+void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value);
+
+void flowctrl_cpu_suspend_enter(unsigned int cpuid);
+void flowctrl_cpu_suspend_exit(unsigned int cpuid);
+
+void tegra_flowctrl_init(void);
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S
new file mode 100644
index 000000000..2072e7322
--- /dev/null
+++ b/arch/arm/mach-tegra/headsmp.S
@@ -0,0 +1,12 @@
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+#include "sleep.h"
+
+ .section ".text.head", "ax"
+
+ENTRY(tegra_secondary_startup)
+ check_cpu_part_num 0xc09, r8, r9
+ bleq v7_invalidate_l1
+ 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 000000000..6fc71f153
--- /dev/null
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ * Copyright (c) 2010, 2012-2013, NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk/tegra.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+
+#include <soc/tegra/common.h>
+#include <soc/tegra/fuse.h>
+
+#include <asm/smp_plat.h>
+
+#include "sleep.h"
+
+static void (*tegra_hotplug_shutdown)(void);
+
+int tegra_cpu_kill(unsigned cpu)
+{
+ cpu = cpu_logical_map(cpu);
+
+ /* Clock gate the CPU */
+ tegra_wait_cpu_in_reset(cpu);
+ tegra_disable_cpu_clock(cpu);
+
+ return 1;
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void __ref tegra_cpu_die(unsigned int cpu)
+{
+ if (!tegra_hotplug_shutdown) {
+ WARN(1, "hotplug is not yet initialized\n");
+ return;
+ }
+
+ /* Clean L1 data cache */
+ tegra_disable_clean_inv_dcache(TEGRA_FLUSH_CACHE_LOUIS);
+
+ /* Shut down the current CPU. */
+ tegra_hotplug_shutdown();
+
+ /* Should never return here. */
+ BUG();
+}
+
+static int __init tegra_hotplug_init(void)
+{
+ if (!IS_ENABLED(CONFIG_HOTPLUG_CPU))
+ return 0;
+
+ if (!soc_is_tegra())
+ return 0;
+
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_get_chip_id() == TEGRA20)
+ tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_get_chip_id() == TEGRA30)
+ tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_get_chip_id() == TEGRA114)
+ tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_get_chip_id() == TEGRA124)
+ tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
+
+ return 0;
+}
+pure_initcall(tegra_hotplug_init);
diff --git a/arch/arm/mach-tegra/io.c b/arch/arm/mach-tegra/io.c
new file mode 100644
index 000000000..352de159d
--- /dev/null
+++ b/arch/arm/mach-tegra/io.c
@@ -0,0 +1,64 @@
+/*
+ * 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/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+
+#include <asm/mach/map.h>
+#include <asm/page.h>
+
+#include "board.h"
+#include "iomap.h"
+
+static struct map_desc tegra_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long)IO_PPSB_VIRT,
+ .pfn = __phys_to_pfn(IO_PPSB_PHYS),
+ .length = IO_PPSB_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = (unsigned long)IO_APB_VIRT,
+ .pfn = __phys_to_pfn(IO_APB_PHYS),
+ .length = IO_APB_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = (unsigned long)IO_CPU_VIRT,
+ .pfn = __phys_to_pfn(IO_CPU_PHYS),
+ .length = IO_CPU_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = (unsigned long)IO_IRAM_VIRT,
+ .pfn = __phys_to_pfn(IO_IRAM_PHYS),
+ .length = IO_IRAM_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init tegra_map_common_io(void)
+{
+ debug_ll_io_init();
+ iotable_init(tegra_io_desc, ARRAY_SIZE(tegra_io_desc));
+}
diff --git a/arch/arm/mach-tegra/iomap.h b/arch/arm/mach-tegra/iomap.h
new file mode 100644
index 000000000..81dc950b4
--- /dev/null
+++ b/arch/arm/mach-tegra/iomap.h
@@ -0,0 +1,141 @@
+/*
+ * 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/pgtable.h>
+#include <asm/sizes.h>
+
+#define TEGRA_IRAM_BASE 0x40000000
+#define TEGRA_IRAM_SIZE SZ_256K
+
+#define TEGRA_ARM_PERIF_BASE 0x50040000
+#define TEGRA_ARM_PERIF_SIZE SZ_8K
+
+#define TEGRA_ARM_INT_DIST_BASE 0x50041000
+#define TEGRA_ARM_INT_DIST_SIZE SZ_4K
+
+#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_SB_BASE 0x6000C200
+#define TEGRA_SB_SIZE 256
+
+#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_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_PMC_BASE 0x7000E400
+#define TEGRA_PMC_SIZE SZ_256
+
+#define TEGRA_EMC_BASE 0x7000F400
+#define TEGRA_EMC_SIZE SZ_1K
+
+#define TEGRA_FUSE_BASE 0x7000F800
+#define TEGRA_FUSE_SIZE SZ_1K
+
+#define TEGRA_EMC0_BASE 0x7001A000
+#define TEGRA_EMC0_SIZE SZ_2K
+
+#define TEGRA_EMC1_BASE 0x7001A800
+#define TEGRA_EMC1_SIZE SZ_2K
+
+#define TEGRA124_EMC_BASE 0x7001B000
+#define TEGRA124_EMC_SIZE SZ_2K
+
+#define TEGRA_CSITE_BASE 0x70040000
+#define TEGRA_CSITE_SIZE SZ_256K
+
+/* 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 MMU section 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 IOMEM(0xFE400000)
+#define IO_IRAM_SIZE SZ_256K
+
+#define IO_CPU_PHYS 0x50040000
+#define IO_CPU_VIRT IOMEM(0xFE440000)
+#define IO_CPU_SIZE SZ_16K
+
+#define IO_PPSB_PHYS 0x60000000
+#define IO_PPSB_VIRT IOMEM(0xFE200000)
+#define IO_PPSB_SIZE SECTION_SIZE
+
+#define IO_APB_PHYS 0x70000000
+#define IO_APB_VIRT IOMEM(0xFE000000)
+#define IO_APB_SIZE SECTION_SIZE
+
+#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) : \
+ NULL)
+
+#define IO_ADDRESS(n) (IO_TO_VIRT(n))
+
+#endif
diff --git a/arch/arm/mach-tegra/irammap.h b/arch/arm/mach-tegra/irammap.h
new file mode 100644
index 000000000..e32e1742c
--- /dev/null
+++ b/arch/arm/mach-tegra/irammap.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, NVIDIA CORPORATION. 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_TEGRA_IRAMMAP_H
+#define __MACH_TEGRA_IRAMMAP_H
+
+#include <asm/sizes.h>
+
+/* The first 1K of IRAM is permanently reserved for the CPU reset handler */
+#define TEGRA_IRAM_RESET_HANDLER_OFFSET 0
+#define TEGRA_IRAM_RESET_HANDLER_SIZE SZ_1K
+
+/*
+ * This area is used for LPx resume vector, only while LPx power state is
+ * active. At other times, the AVP may use this area for arbitrary purposes
+ */
+#define TEGRA_IRAM_LPx_RESUME_AREA (TEGRA_IRAM_BASE + SZ_4K)
+
+#endif
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
new file mode 100644
index 000000000..3b9098d27
--- /dev/null
+++ b/arch/arm/mach-tegra/irq.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@android.com>
+ *
+ * Copyright (C) 2010,2013, 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/cpu_pm.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#include <linux/syscore_ops.h>
+
+#include "board.h"
+#include "iomap.h"
+
+#define SGI_MASK 0xFFFF
+
+#ifdef CONFIG_PM_SLEEP
+static void __iomem *tegra_gic_cpu_base;
+#endif
+
+bool tegra_pending_sgi(void)
+{
+ u32 pending_set;
+ void __iomem *distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
+
+ pending_set = readl_relaxed(distbase + GIC_DIST_PENDING_SET);
+
+ if (pending_set & SGI_MASK)
+ return true;
+
+ return false;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int tegra_gic_notifier(struct notifier_block *self,
+ unsigned long cmd, void *v)
+{
+ switch (cmd) {
+ case CPU_PM_ENTER:
+ writel_relaxed(0x1E0, tegra_gic_cpu_base + GIC_CPU_CTRL);
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block tegra_gic_notifier_block = {
+ .notifier_call = tegra_gic_notifier,
+};
+
+static const struct of_device_id tegra114_dt_gic_match[] __initconst = {
+ { .compatible = "arm,cortex-a15-gic" },
+ { }
+};
+
+static void tegra114_gic_cpu_pm_registration(void)
+{
+ struct device_node *dn;
+
+ dn = of_find_matching_node(NULL, tegra114_dt_gic_match);
+ if (!dn)
+ return;
+
+ tegra_gic_cpu_base = of_iomap(dn, 1);
+
+ cpu_pm_register_notifier(&tegra_gic_notifier_block);
+}
+#else
+static void tegra114_gic_cpu_pm_registration(void) { }
+#endif
+
+static const struct of_device_id tegra_ictlr_match[] __initconst = {
+ { .compatible = "nvidia,tegra20-ictlr" },
+ { .compatible = "nvidia,tegra30-ictlr" },
+ { }
+};
+
+void __init tegra_init_irq(void)
+{
+ if (WARN_ON(!of_find_matching_node(NULL, tegra_ictlr_match)))
+ pr_warn("Outdated DT detected, suspend/resume will NOT work\n");
+
+ tegra114_gic_cpu_pm_registration();
+}
diff --git a/arch/arm/mach-tegra/irq.h b/arch/arm/mach-tegra/irq.h
new file mode 100644
index 000000000..5142649bb
--- /dev/null
+++ b/arch/arm/mach-tegra/irq.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2012, NVIDIA Corporation. 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __TEGRA_IRQ_H
+#define __TEGRA_IRQ_H
+
+bool tegra_pending_sgi(void);
+
+#endif
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
new file mode 100644
index 000000000..b45086666
--- /dev/null
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -0,0 +1,203 @@
+/*
+ * 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/clk/tegra.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+
+#include <soc/tegra/fuse.h>
+#include <soc/tegra/pmc.h>
+
+#include <asm/cacheflush.h>
+#include <asm/mach-types.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+#include "common.h"
+#include "flowctrl.h"
+#include "iomap.h"
+#include "reset.h"
+
+static cpumask_t tegra_cpu_init_mask;
+
+static void tegra_secondary_init(unsigned int cpu)
+{
+ cpumask_set_cpu(cpu, &tegra_cpu_init_mask);
+}
+
+
+static int tegra20_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ cpu = cpu_logical_map(cpu);
+
+ /*
+ * Force the CPU into reset. The CPU must remain in reset when
+ * the flow controller state is cleared (which will cause the
+ * flow controller to stop driving reset if the CPU has been
+ * power-gated via the flow controller). This will have no
+ * effect on first boot of the CPU since it should already be
+ * in reset.
+ */
+ tegra_put_cpu_in_reset(cpu);
+
+ /*
+ * Unhalt the CPU. If the flow controller was used to
+ * power-gate the CPU this will cause the flow controller to
+ * stop driving reset. The CPU will remain in reset because the
+ * clock and reset block is now driving reset.
+ */
+ flowctrl_write_cpu_halt(cpu, 0);
+
+ tegra_enable_cpu_clock(cpu);
+ flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
+ tegra_cpu_out_of_reset(cpu);
+ return 0;
+}
+
+static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ int ret;
+ unsigned long timeout;
+
+ cpu = cpu_logical_map(cpu);
+ tegra_put_cpu_in_reset(cpu);
+ flowctrl_write_cpu_halt(cpu, 0);
+
+ /*
+ * The power up sequence of cold boot CPU and warm boot CPU
+ * was different.
+ *
+ * For warm boot CPU that was resumed from CPU hotplug, the
+ * power will be resumed automatically after un-halting the
+ * flow controller of the warm boot CPU. We need to wait for
+ * the confirmaiton that the CPU is powered then removing
+ * the IO clamps.
+ * For cold boot CPU, do not wait. After the cold boot CPU be
+ * booted, it will run to tegra_secondary_init() and set
+ * tegra_cpu_init_mask which influences what tegra30_boot_secondary()
+ * next time around.
+ */
+ if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) {
+ timeout = jiffies + msecs_to_jiffies(50);
+ do {
+ if (tegra_pmc_cpu_is_powered(cpu))
+ goto remove_clamps;
+ udelay(10);
+ } while (time_before(jiffies, timeout));
+ }
+
+ /*
+ * The power status of the cold boot CPU is power gated as
+ * default. To power up the cold boot CPU, the power should
+ * be un-gated by un-toggling the power gate register
+ * manually.
+ */
+ if (!tegra_pmc_cpu_is_powered(cpu)) {
+ ret = tegra_pmc_cpu_power_on(cpu);
+ if (ret)
+ return ret;
+
+ /* Wait for the power to come up. */
+ timeout = jiffies + msecs_to_jiffies(100);
+ while (!tegra_pmc_cpu_is_powered(cpu)) {
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+ udelay(10);
+ }
+ }
+
+remove_clamps:
+ /* CPU partition is powered. Enable the CPU clock. */
+ tegra_enable_cpu_clock(cpu);
+ udelay(10);
+
+ /* Remove I/O clamps. */
+ ret = tegra_pmc_cpu_remove_clamping(cpu);
+ if (ret)
+ return ret;
+
+ udelay(10);
+
+ flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
+ tegra_cpu_out_of_reset(cpu);
+ return 0;
+}
+
+static int tegra114_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ int ret = 0;
+
+ cpu = cpu_logical_map(cpu);
+
+ if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) {
+ /*
+ * Warm boot flow
+ * The flow controller in charge of the power state and
+ * control for each CPU.
+ */
+ /* set SCLK as event trigger for flow controller */
+ flowctrl_write_cpu_csr(cpu, 1);
+ flowctrl_write_cpu_halt(cpu,
+ FLOW_CTRL_WAITEVENT | FLOW_CTRL_SCLK_RESUME);
+ } else {
+ /*
+ * Cold boot flow
+ * The CPU is powered up by toggling PMC directly. It will
+ * also initial power state in flow controller. After that,
+ * the CPU's power state is maintained by flow controller.
+ */
+ ret = tegra_pmc_cpu_power_on(cpu);
+ }
+
+ return ret;
+}
+
+static int tegra_boot_secondary(unsigned int cpu,
+ struct task_struct *idle)
+{
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_get_chip_id() == TEGRA20)
+ return tegra20_boot_secondary(cpu, idle);
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_get_chip_id() == TEGRA30)
+ return tegra30_boot_secondary(cpu, idle);
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_get_chip_id() == TEGRA114)
+ return tegra114_boot_secondary(cpu, idle);
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_get_chip_id() == TEGRA124)
+ return tegra114_boot_secondary(cpu, idle);
+
+ return -EINVAL;
+}
+
+static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
+{
+ /* Always mark the boot CPU (CPU0) as initialized. */
+ cpumask_set_cpu(0, &tegra_cpu_init_mask);
+
+ if (scu_a9_has_base())
+ scu_enable(IO_ADDRESS(scu_a9_get_base()));
+}
+
+struct smp_operations tegra_smp_ops __initdata = {
+ .smp_prepare_cpus = tegra_smp_prepare_cpus,
+ .smp_secondary_init = tegra_secondary_init,
+ .smp_boot_secondary = tegra_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_kill = tegra_cpu_kill,
+ .cpu_die = tegra_cpu_die,
+#endif
+};
diff --git a/arch/arm/mach-tegra/pm-tegra20.c b/arch/arm/mach-tegra/pm-tegra20.c
new file mode 100644
index 000000000..39ac2b723
--- /dev/null
+++ b/arch/arm/mach-tegra/pm-tegra20.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2013, NVIDIA Corporation. 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+
+#include "pm.h"
+
+#ifdef CONFIG_PM_SLEEP
+extern u32 tegra20_iram_start, tegra20_iram_end;
+extern void tegra20_sleep_core_finish(unsigned long);
+
+void tegra20_lp1_iram_hook(void)
+{
+ tegra_lp1_iram.start_addr = &tegra20_iram_start;
+ tegra_lp1_iram.end_addr = &tegra20_iram_end;
+}
+
+void tegra20_sleep_core_init(void)
+{
+ tegra_sleep_core_finish = tegra20_sleep_core_finish;
+}
+#endif
diff --git a/arch/arm/mach-tegra/pm-tegra30.c b/arch/arm/mach-tegra/pm-tegra30.c
new file mode 100644
index 000000000..46cc19de9
--- /dev/null
+++ b/arch/arm/mach-tegra/pm-tegra30.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2013, NVIDIA Corporation. 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+
+#include "pm.h"
+
+#ifdef CONFIG_PM_SLEEP
+extern u32 tegra30_iram_start, tegra30_iram_end;
+extern void tegra30_sleep_core_finish(unsigned long);
+
+void tegra30_lp1_iram_hook(void)
+{
+ tegra_lp1_iram.start_addr = &tegra30_iram_start;
+ tegra_lp1_iram.end_addr = &tegra30_iram_end;
+}
+
+void tegra30_sleep_core_init(void)
+{
+ tegra_sleep_core_finish = tegra30_sleep_core_finish;
+}
+#endif
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
new file mode 100644
index 000000000..b0f48a394
--- /dev/null
+++ b/arch/arm/mach-tegra/pm.c
@@ -0,0 +1,400 @@
+/*
+ * CPU complex suspend & resume functions for Tegra SoCs
+ *
+ * Copyright (c) 2009-2012, NVIDIA Corporation. 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk/tegra.h>
+#include <linux/cpumask.h>
+#include <linux/cpu_pm.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/suspend.h>
+
+#include <soc/tegra/fuse.h>
+#include <soc/tegra/pm.h>
+#include <soc/tegra/pmc.h>
+
+#include <asm/cacheflush.h>
+#include <asm/idmap.h>
+#include <asm/proc-fns.h>
+#include <asm/smp_plat.h>
+#include <asm/suspend.h>
+#include <asm/tlbflush.h>
+
+#include "flowctrl.h"
+#include "iomap.h"
+#include "pm.h"
+#include "reset.h"
+#include "sleep.h"
+
+#ifdef CONFIG_PM_SLEEP
+static DEFINE_SPINLOCK(tegra_lp2_lock);
+static u32 iram_save_size;
+static void *iram_save_addr;
+struct tegra_lp1_iram tegra_lp1_iram;
+void (*tegra_tear_down_cpu)(void);
+void (*tegra_sleep_core_finish)(unsigned long v2p);
+static int (*tegra_sleep_func)(unsigned long v2p);
+
+static void tegra_tear_down_cpu_init(void)
+{
+ switch (tegra_get_chip_id()) {
+ case TEGRA20:
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
+ tegra_tear_down_cpu = tegra20_tear_down_cpu;
+ break;
+ case TEGRA30:
+ case TEGRA114:
+ case TEGRA124:
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) ||
+ IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
+ IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
+ tegra_tear_down_cpu = tegra30_tear_down_cpu;
+ break;
+ }
+}
+
+/*
+ * restore_cpu_complex
+ *
+ * restores cpu clock setting, clears flow controller
+ *
+ * Always called on CPU 0.
+ */
+static void restore_cpu_complex(void)
+{
+ int cpu = smp_processor_id();
+
+ BUG_ON(cpu != 0);
+
+#ifdef CONFIG_SMP
+ cpu = cpu_logical_map(cpu);
+#endif
+
+ /* Restore the CPU clock settings */
+ tegra_cpu_clock_resume();
+
+ flowctrl_cpu_suspend_exit(cpu);
+}
+
+/*
+ * suspend_cpu_complex
+ *
+ * saves pll state for use by restart_plls, prepares flow controller for
+ * transition to suspend state
+ *
+ * Must always be called on cpu 0.
+ */
+static void suspend_cpu_complex(void)
+{
+ int cpu = smp_processor_id();
+
+ BUG_ON(cpu != 0);
+
+#ifdef CONFIG_SMP
+ cpu = cpu_logical_map(cpu);
+#endif
+
+ /* Save the CPU clock settings */
+ tegra_cpu_clock_suspend();
+
+ flowctrl_cpu_suspend_enter(cpu);
+}
+
+void tegra_clear_cpu_in_lp2(void)
+{
+ int phy_cpu_id = cpu_logical_map(smp_processor_id());
+ u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
+
+ spin_lock(&tegra_lp2_lock);
+
+ BUG_ON(!(*cpu_in_lp2 & BIT(phy_cpu_id)));
+ *cpu_in_lp2 &= ~BIT(phy_cpu_id);
+
+ spin_unlock(&tegra_lp2_lock);
+}
+
+bool tegra_set_cpu_in_lp2(void)
+{
+ int phy_cpu_id = cpu_logical_map(smp_processor_id());
+ bool last_cpu = false;
+ cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask;
+ u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
+
+ spin_lock(&tegra_lp2_lock);
+
+ BUG_ON((*cpu_in_lp2 & BIT(phy_cpu_id)));
+ *cpu_in_lp2 |= BIT(phy_cpu_id);
+
+ if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
+ last_cpu = true;
+ else if (tegra_get_chip_id() == TEGRA20 && phy_cpu_id == 1)
+ tegra20_cpu_set_resettable_soon();
+
+ spin_unlock(&tegra_lp2_lock);
+ return last_cpu;
+}
+
+int tegra_cpu_do_idle(void)
+{
+ return cpu_do_idle();
+}
+
+static int tegra_sleep_cpu(unsigned long v2p)
+{
+ setup_mm_for_reboot();
+ tegra_sleep_cpu_finish(v2p);
+
+ /* should never here */
+ BUG();
+
+ return 0;
+}
+
+static void tegra_pm_set(enum tegra_suspend_mode mode)
+{
+ u32 value;
+
+ switch (tegra_get_chip_id()) {
+ case TEGRA20:
+ case TEGRA30:
+ break;
+ default:
+ /* Turn off CRAIL */
+ value = flowctrl_read_cpu_csr(0);
+ value &= ~FLOW_CTRL_CSR_ENABLE_EXT_MASK;
+ value |= FLOW_CTRL_CSR_ENABLE_EXT_CRAIL;
+ flowctrl_write_cpu_csr(0, value);
+ break;
+ }
+
+ tegra_pmc_enter_suspend_mode(mode);
+}
+
+void tegra_idle_lp2_last(void)
+{
+ tegra_pm_set(TEGRA_SUSPEND_LP2);
+
+ cpu_cluster_pm_enter();
+ suspend_cpu_complex();
+
+ cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
+
+ restore_cpu_complex();
+ cpu_cluster_pm_exit();
+}
+
+enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
+ enum tegra_suspend_mode mode)
+{
+ /*
+ * The Tegra devices support suspending to LP1 or lower currently.
+ */
+ if (mode > TEGRA_SUSPEND_LP1)
+ return TEGRA_SUSPEND_LP1;
+
+ return mode;
+}
+
+static int tegra_sleep_core(unsigned long v2p)
+{
+ setup_mm_for_reboot();
+ tegra_sleep_core_finish(v2p);
+
+ /* should never here */
+ BUG();
+
+ return 0;
+}
+
+/*
+ * tegra_lp1_iram_hook
+ *
+ * Hooking the address of LP1 reset vector and SDRAM self-refresh code in
+ * SDRAM. These codes not be copied to IRAM in this fuction. We need to
+ * copy these code to IRAM before LP0/LP1 suspend and restore the content
+ * of IRAM after resume.
+ */
+static bool tegra_lp1_iram_hook(void)
+{
+ switch (tegra_get_chip_id()) {
+ case TEGRA20:
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
+ tegra20_lp1_iram_hook();
+ break;
+ case TEGRA30:
+ case TEGRA114:
+ case TEGRA124:
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) ||
+ IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
+ IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
+ tegra30_lp1_iram_hook();
+ break;
+ default:
+ break;
+ }
+
+ if (!tegra_lp1_iram.start_addr || !tegra_lp1_iram.end_addr)
+ return false;
+
+ iram_save_size = tegra_lp1_iram.end_addr - tegra_lp1_iram.start_addr;
+ iram_save_addr = kmalloc(iram_save_size, GFP_KERNEL);
+ if (!iram_save_addr)
+ return false;
+
+ return true;
+}
+
+static bool tegra_sleep_core_init(void)
+{
+ switch (tegra_get_chip_id()) {
+ case TEGRA20:
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
+ tegra20_sleep_core_init();
+ break;
+ case TEGRA30:
+ case TEGRA114:
+ case TEGRA124:
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) ||
+ IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
+ IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
+ tegra30_sleep_core_init();
+ break;
+ default:
+ break;
+ }
+
+ if (!tegra_sleep_core_finish)
+ return false;
+
+ return true;
+}
+
+static void tegra_suspend_enter_lp1(void)
+{
+ /* copy the reset vector & SDRAM shutdown code into IRAM */
+ memcpy(iram_save_addr, IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA),
+ iram_save_size);
+ memcpy(IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA),
+ tegra_lp1_iram.start_addr, iram_save_size);
+
+ *((u32 *)tegra_cpu_lp1_mask) = 1;
+}
+
+static void tegra_suspend_exit_lp1(void)
+{
+ /* restore IRAM */
+ memcpy(IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA), iram_save_addr,
+ iram_save_size);
+
+ *(u32 *)tegra_cpu_lp1_mask = 0;
+}
+
+static const char *lp_state[TEGRA_MAX_SUSPEND_MODE] = {
+ [TEGRA_SUSPEND_NONE] = "none",
+ [TEGRA_SUSPEND_LP2] = "LP2",
+ [TEGRA_SUSPEND_LP1] = "LP1",
+ [TEGRA_SUSPEND_LP0] = "LP0",
+};
+
+static int tegra_suspend_enter(suspend_state_t state)
+{
+ enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode();
+
+ if (WARN_ON(mode < TEGRA_SUSPEND_NONE ||
+ mode >= TEGRA_MAX_SUSPEND_MODE))
+ return -EINVAL;
+
+ pr_info("Entering suspend state %s\n", lp_state[mode]);
+
+ tegra_pm_set(mode);
+
+ local_fiq_disable();
+
+ suspend_cpu_complex();
+ switch (mode) {
+ case TEGRA_SUSPEND_LP1:
+ tegra_suspend_enter_lp1();
+ break;
+ case TEGRA_SUSPEND_LP2:
+ tegra_set_cpu_in_lp2();
+ break;
+ default:
+ break;
+ }
+
+ cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, tegra_sleep_func);
+
+ switch (mode) {
+ case TEGRA_SUSPEND_LP1:
+ tegra_suspend_exit_lp1();
+ break;
+ case TEGRA_SUSPEND_LP2:
+ tegra_clear_cpu_in_lp2();
+ break;
+ default:
+ break;
+ }
+ restore_cpu_complex();
+
+ local_fiq_enable();
+
+ return 0;
+}
+
+static const struct platform_suspend_ops tegra_suspend_ops = {
+ .valid = suspend_valid_only_mem,
+ .enter = tegra_suspend_enter,
+};
+
+void __init tegra_init_suspend(void)
+{
+ enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode();
+
+ if (mode == TEGRA_SUSPEND_NONE)
+ return;
+
+ tegra_tear_down_cpu_init();
+
+ if (mode >= TEGRA_SUSPEND_LP1) {
+ if (!tegra_lp1_iram_hook() || !tegra_sleep_core_init()) {
+ pr_err("%s: unable to allocate memory for SDRAM"
+ "self-refresh -- LP0/LP1 unavailable\n",
+ __func__);
+ tegra_pmc_set_suspend_mode(TEGRA_SUSPEND_LP2);
+ mode = TEGRA_SUSPEND_LP2;
+ }
+ }
+
+ /* set up sleep function for cpu_suspend */
+ switch (mode) {
+ case TEGRA_SUSPEND_LP1:
+ tegra_sleep_func = tegra_sleep_core;
+ break;
+ case TEGRA_SUSPEND_LP2:
+ tegra_sleep_func = tegra_sleep_cpu;
+ break;
+ default:
+ break;
+ }
+
+ suspend_set_ops(&tegra_suspend_ops);
+}
+#endif
diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h
new file mode 100644
index 000000000..83bc87583
--- /dev/null
+++ b/arch/arm/mach-tegra/pm.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (c) 2010-2012 NVIDIA Corporation. All rights reserved.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _MACH_TEGRA_PM_H_
+#define _MACH_TEGRA_PM_H_
+
+struct tegra_lp1_iram {
+ void *start_addr;
+ void *end_addr;
+};
+
+extern struct tegra_lp1_iram tegra_lp1_iram;
+extern void (*tegra_sleep_core_finish)(unsigned long v2p);
+
+void tegra20_lp1_iram_hook(void);
+void tegra20_sleep_core_init(void);
+void tegra30_lp1_iram_hook(void);
+void tegra30_sleep_core_init(void);
+
+void tegra_clear_cpu_in_lp2(void);
+bool tegra_set_cpu_in_lp2(void);
+
+void tegra_idle_lp2_last(void);
+extern void (*tegra_tear_down_cpu)(void);
+
+#ifdef CONFIG_PM_SLEEP
+void tegra_init_suspend(void);
+#else
+static inline void tegra_init_suspend(void) {}
+#endif
+
+#endif /* _MACH_TEGRA_PM_H_ */
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
new file mode 100644
index 000000000..e3070fdab
--- /dev/null
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2012, NVIDIA Corporation. 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+
+#include <soc/tegra/fuse.h>
+
+#include <asm/asm-offsets.h>
+#include <asm/cache.h>
+
+#include "flowctrl.h"
+#include "iomap.h"
+#include "reset.h"
+#include "sleep.h"
+
+#define PMC_SCRATCH41 0x140
+
+#define RESET_DATA(x) ((TEGRA_RESET_##x)*4)
+
+#ifdef CONFIG_PM_SLEEP
+/*
+ * tegra_resume
+ *
+ * CPU boot vector when restarting the a CPU following
+ * an LP2 transition. Also branched to by LP0 and LP1 resume after
+ * re-enabling sdram.
+ *
+ * r6: SoC ID
+ * r8: CPU part number
+ */
+ENTRY(tegra_resume)
+ check_cpu_part_num 0xc09, r8, r9
+ bleq v7_invalidate_l1
+
+ cpu_id r0
+ cmp r0, #0 @ CPU0?
+ THUMB( it ne )
+ bne cpu_resume @ no
+
+ tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
+ /* Are we on Tegra20? */
+ cmp r6, #TEGRA20
+ beq 1f @ Yes
+ /* Clear the flow controller flags for this CPU. */
+ cpu_to_csr_reg r1, r0
+ mov32 r2, TEGRA_FLOW_CTRL_BASE
+ ldr r1, [r2, r1]
+ /* Clear event & intr flag */
+ orr r1, r1, \
+ #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
+ movw r0, #0x3FFD @ enable, cluster_switch, immed, bitmaps
+ @ & ext flags for CPU power mgnt
+ bic r1, r1, r0
+ str r1, [r2]
+1:
+
+ mov32 r9, 0xc09
+ cmp r8, r9
+ bne end_ca9_scu_l2_resume
+#ifdef CONFIG_HAVE_ARM_SCU
+ /* enable SCU */
+ mov32 r0, TEGRA_ARM_PERIF_BASE
+ ldr r1, [r0]
+ orr r1, r1, #1
+ str r1, [r0]
+#endif
+
+#ifdef CONFIG_CACHE_L2X0
+ /* L2 cache resume & re-enable */
+ bl l2c310_early_resume
+#endif
+end_ca9_scu_l2_resume:
+ mov32 r9, 0xc0f
+ cmp r8, r9
+ bleq tegra_init_l2_for_a15
+
+ b cpu_resume
+ENDPROC(tegra_resume)
+#endif
+
+ .align L1_CACHE_SHIFT
+ENTRY(__tegra_cpu_reset_handler_start)
+
+/*
+ * __tegra_cpu_reset_handler:
+ *
+ * Common handler for all CPU reset events.
+ *
+ * Register usage within the reset handler:
+ *
+ * Others: scratch
+ * R6 = SoC ID
+ * R7 = CPU present (to the OS) mask
+ * R8 = CPU in LP1 state mask
+ * R9 = CPU in LP2 state mask
+ * R10 = CPU number
+ * R11 = CPU mask
+ * R12 = pointer to reset handler data
+ *
+ * NOTE: This code is copied to IRAM. All code and data accesses
+ * must be position-independent.
+ */
+
+ .align L1_CACHE_SHIFT
+ENTRY(__tegra_cpu_reset_handler)
+
+ cpsid aif, 0x13 @ SVC mode, interrupts disabled
+
+ tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+t20_check:
+ cmp r6, #TEGRA20
+ bne after_t20_check
+t20_errata:
+ # Tegra20 is a Cortex-A9 r1p1
+ mrc p15, 0, r0, c1, c0, 0 @ read system control register
+ orr r0, r0, #1 << 14 @ erratum 716044
+ mcr p15, 0, r0, c1, c0, 0 @ write system control register
+ mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
+ orr r0, r0, #1 << 4 @ erratum 742230
+ orr r0, r0, #1 << 11 @ erratum 751472
+ mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
+ b after_errata
+after_t20_check:
+#endif
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+t30_check:
+ cmp r6, #TEGRA30
+ bne after_t30_check
+t30_errata:
+ # Tegra30 is a Cortex-A9 r2p9
+ mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
+ orr r0, r0, #1 << 6 @ erratum 743622
+ orr r0, r0, #1 << 11 @ erratum 751472
+ mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
+ b after_errata
+after_t30_check:
+#endif
+after_errata:
+ mrc p15, 0, r10, c0, c0, 5 @ MPIDR
+ and r10, r10, #0x3 @ R10 = CPU number
+ mov r11, #1
+ mov r11, r11, lsl r10 @ R11 = CPU mask
+ adr r12, __tegra_cpu_reset_handler_data
+
+#ifdef CONFIG_SMP
+ /* Does the OS know about this CPU? */
+ ldr r7, [r12, #RESET_DATA(MASK_PRESENT)]
+ tst r7, r11 @ if !present
+ bleq __die @ CPU not present (to OS)
+#endif
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ /* Are we on Tegra20? */
+ cmp r6, #TEGRA20
+ bne 1f
+ /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
+ mov32 r5, TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET
+ mov r0, #CPU_NOT_RESETTABLE
+ cmp r10, #0
+ strneb r0, [r5, #__tegra20_cpu1_resettable_status_offset]
+1:
+#endif
+
+ /* Waking up from LP1? */
+ ldr r8, [r12, #RESET_DATA(MASK_LP1)]
+ tst r8, r11 @ if in_lp1
+ beq __is_not_lp1
+ cmp r10, #0
+ bne __die @ only CPU0 can be here
+ ldr lr, [r12, #RESET_DATA(STARTUP_LP1)]
+ cmp lr, #0
+ bleq __die @ no LP1 startup handler
+ THUMB( add lr, lr, #1 ) @ switch to Thumb mode
+ bx lr
+__is_not_lp1:
+
+ /* Waking up from LP2? */
+ ldr r9, [r12, #RESET_DATA(MASK_LP2)]
+ tst r9, r11 @ if in_lp2
+ beq __is_not_lp2
+ ldr lr, [r12, #RESET_DATA(STARTUP_LP2)]
+ cmp lr, #0
+ bleq __die @ no LP2 startup handler
+ bx lr
+
+__is_not_lp2:
+
+#ifdef CONFIG_SMP
+ /*
+ * Can only be secondary boot (initial or hotplug)
+ * CPU0 can't be here for Tegra20/30
+ */
+ cmp r6, #TEGRA114
+ beq __no_cpu0_chk
+ cmp r10, #0
+ bleq __die @ CPU0 cannot be here
+__no_cpu0_chk:
+ ldr lr, [r12, #RESET_DATA(STARTUP_SECONDARY)]
+ cmp lr, #0
+ bleq __die @ no secondary startup handler
+ bx lr
+#endif
+
+/*
+ * We don't know why the CPU reset. Just kill it.
+ * The LR register will contain the address we died at + 4.
+ */
+
+__die:
+ sub lr, lr, #4
+ mov32 r7, TEGRA_PMC_BASE
+ str lr, [r7, #PMC_SCRATCH41]
+
+ mov32 r7, TEGRA_CLK_RESET_BASE
+
+ /* Are we on Tegra20? */
+ cmp r6, #TEGRA20
+ bne 1f
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ mov32 r0, 0x1111
+ mov r1, r0, lsl r10
+ str r1, [r7, #0x340] @ CLK_RST_CPU_CMPLX_SET
+#endif
+1:
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+ mov32 r6, TEGRA_FLOW_CTRL_BASE
+
+ cmp r10, #0
+ moveq r1, #FLOW_CTRL_HALT_CPU0_EVENTS
+ moveq r2, #FLOW_CTRL_CPU0_CSR
+ movne r1, r10, lsl #3
+ addne r2, r1, #(FLOW_CTRL_CPU1_CSR-8)
+ addne r1, r1, #(FLOW_CTRL_HALT_CPU1_EVENTS-8)
+
+ /* Clear CPU "event" and "interrupt" flags and power gate
+ it when halting but not before it is in the "WFI" state. */
+ ldr r0, [r6, +r2]
+ orr r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
+ orr r0, r0, #FLOW_CTRL_CSR_ENABLE
+ str r0, [r6, +r2]
+
+ /* Unconditionally halt this CPU */
+ mov r0, #FLOW_CTRL_WAITEVENT
+ str r0, [r6, +r1]
+ ldr r0, [r6, +r1] @ memory barrier
+
+ dsb
+ isb
+ wfi @ CPU should be power gated here
+
+ /* If the CPU didn't power gate above just kill it's clock. */
+
+ mov r0, r11, lsl #8
+ str r0, [r7, #348] @ CLK_CPU_CMPLX_SET
+#endif
+
+ /* If the CPU still isn't dead, just spin here. */
+ b .
+ENDPROC(__tegra_cpu_reset_handler)
+
+ .align L1_CACHE_SHIFT
+ .type __tegra_cpu_reset_handler_data, %object
+ .globl __tegra_cpu_reset_handler_data
+__tegra_cpu_reset_handler_data:
+ .rept TEGRA_RESET_DATA_SIZE
+ .long 0
+ .endr
+ .globl __tegra20_cpu1_resettable_status_offset
+ .equ __tegra20_cpu1_resettable_status_offset, \
+ . - __tegra_cpu_reset_handler_start
+ .byte 0
+ .align L1_CACHE_SHIFT
+
+ENTRY(__tegra_cpu_reset_handler_end)
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
new file mode 100644
index 000000000..894c5c472
--- /dev/null
+++ b/arch/arm/mach-tegra/reset.c
@@ -0,0 +1,108 @@
+/*
+ * arch/arm/mach-tegra/reset.c
+ *
+ * Copyright (C) 2011,2012 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/bitops.h>
+#include <linux/cpumask.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <soc/tegra/fuse.h>
+
+#include <asm/cacheflush.h>
+#include <asm/firmware.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "iomap.h"
+#include "irammap.h"
+#include "reset.h"
+#include "sleep.h"
+
+#define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \
+ TEGRA_IRAM_RESET_HANDLER_OFFSET)
+
+static bool is_enabled;
+
+static void __init tegra_cpu_reset_handler_set(const u32 reset_address)
+{
+ void __iomem *evp_cpu_reset =
+ IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE + 0x100);
+ void __iomem *sb_ctrl = IO_ADDRESS(TEGRA_SB_BASE);
+ u32 reg;
+
+ /*
+ * NOTE: This must be the one and only write to the EVP CPU reset
+ * vector in the entire system.
+ */
+ writel(reset_address, evp_cpu_reset);
+ wmb();
+ reg = readl(evp_cpu_reset);
+
+ /*
+ * Prevent further modifications to the physical reset vector.
+ * NOTE: Has no effect on chips prior to Tegra30.
+ */
+ reg = readl(sb_ctrl);
+ reg |= 2;
+ writel(reg, sb_ctrl);
+ wmb();
+}
+
+static void __init tegra_cpu_reset_handler_enable(void)
+{
+ void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE);
+ const u32 reset_address = TEGRA_IRAM_RESET_BASE +
+ tegra_cpu_reset_handler_offset;
+ int err;
+
+ BUG_ON(is_enabled);
+ BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);
+
+ memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
+ tegra_cpu_reset_handler_size);
+
+ err = call_firmware_op(set_cpu_boot_addr, 0, reset_address);
+ switch (err) {
+ case -ENOSYS:
+ tegra_cpu_reset_handler_set(reset_address);
+ /* pass-through */
+ case 0:
+ is_enabled = true;
+ break;
+ default:
+ pr_crit("Cannot set CPU reset handler: %d\n", err);
+ BUG();
+ }
+}
+
+void __init tegra_cpu_reset_handler_init(void)
+{
+
+#ifdef CONFIG_SMP
+ __tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] =
+ *((u32 *)cpu_possible_mask);
+ __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_SECONDARY] =
+ virt_to_phys((void *)tegra_secondary_startup);
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+ __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP1] =
+ TEGRA_IRAM_LPx_RESUME_AREA;
+ __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP2] =
+ virt_to_phys((void *)tegra_resume);
+#endif
+
+ tegra_cpu_reset_handler_enable();
+}
diff --git a/arch/arm/mach-tegra/reset.h b/arch/arm/mach-tegra/reset.h
new file mode 100644
index 000000000..29c3dec01
--- /dev/null
+++ b/arch/arm/mach-tegra/reset.h
@@ -0,0 +1,67 @@
+/*
+ * arch/arm/mach-tegra/reset.h
+ *
+ * CPU reset dispatcher.
+ *
+ * Copyright (c) 2011, 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.
+ *
+ */
+
+#ifndef __MACH_TEGRA_RESET_H
+#define __MACH_TEGRA_RESET_H
+
+#define TEGRA_RESET_MASK_PRESENT 0
+#define TEGRA_RESET_MASK_LP1 1
+#define TEGRA_RESET_MASK_LP2 2
+#define TEGRA_RESET_STARTUP_SECONDARY 3
+#define TEGRA_RESET_STARTUP_LP2 4
+#define TEGRA_RESET_STARTUP_LP1 5
+#define TEGRA_RESET_DATA_SIZE 6
+
+#ifndef __ASSEMBLY__
+
+#include "irammap.h"
+
+extern unsigned long __tegra_cpu_reset_handler_data[TEGRA_RESET_DATA_SIZE];
+
+void __tegra_cpu_reset_handler_start(void);
+void __tegra_cpu_reset_handler(void);
+void __tegra20_cpu1_resettable_status_offset(void);
+void __tegra_cpu_reset_handler_end(void);
+void tegra_secondary_startup(void);
+
+#ifdef CONFIG_PM_SLEEP
+#define tegra_cpu_lp1_mask \
+ (IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
+ ((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_LP1] - \
+ (u32)__tegra_cpu_reset_handler_start)))
+#define tegra_cpu_lp2_mask \
+ (IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
+ ((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_LP2] - \
+ (u32)__tegra_cpu_reset_handler_start)))
+#define tegra20_cpu1_resettable_status \
+ (IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
+ (u32)__tegra20_cpu1_resettable_status_offset))
+#endif
+
+#define tegra_cpu_reset_handler_offset \
+ ((u32)__tegra_cpu_reset_handler - \
+ (u32)__tegra_cpu_reset_handler_start)
+
+#define tegra_cpu_reset_handler_size \
+ (__tegra_cpu_reset_handler_end - \
+ __tegra_cpu_reset_handler_start)
+
+void __init tegra_cpu_reset_handler_init(void);
+
+#endif
+#endif
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S
new file mode 100644
index 000000000..e6b684e14
--- /dev/null
+++ b/arch/arm/mach-tegra/sleep-tegra20.S
@@ -0,0 +1,580 @@
+/*
+ * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2011, Google, Inc.
+ *
+ * Author: Colin Cross <ccross@android.com>
+ * Gary King <gking@nvidia.com>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/linkage.h>
+
+#include <asm/assembler.h>
+#include <asm/proc-fns.h>
+#include <asm/cp15.h>
+#include <asm/cache.h>
+
+#include "irammap.h"
+#include "sleep.h"
+#include "flowctrl.h"
+
+#define EMC_CFG 0xc
+#define EMC_ADR_CFG 0x10
+#define EMC_REFRESH 0x70
+#define EMC_NOP 0xdc
+#define EMC_SELF_REF 0xe0
+#define EMC_REQ_CTRL 0x2b0
+#define EMC_EMC_STATUS 0x2b4
+
+#define CLK_RESET_CCLK_BURST 0x20
+#define CLK_RESET_CCLK_DIVIDER 0x24
+#define CLK_RESET_SCLK_BURST 0x28
+#define CLK_RESET_SCLK_DIVIDER 0x2c
+#define CLK_RESET_PLLC_BASE 0x80
+#define CLK_RESET_PLLM_BASE 0x90
+#define CLK_RESET_PLLP_BASE 0xa0
+
+#define APB_MISC_XM2CFGCPADCTRL 0x8c8
+#define APB_MISC_XM2CFGDPADCTRL 0x8cc
+#define APB_MISC_XM2CLKCFGPADCTRL 0x8d0
+#define APB_MISC_XM2COMPPADCTRL 0x8d4
+#define APB_MISC_XM2VTTGENPADCTRL 0x8d8
+#define APB_MISC_XM2CFGCPADCTRL2 0x8e4
+#define APB_MISC_XM2CFGDPADCTRL2 0x8e8
+
+.macro pll_enable, rd, r_car_base, pll_base
+ ldr \rd, [\r_car_base, #\pll_base]
+ tst \rd, #(1 << 30)
+ orreq \rd, \rd, #(1 << 30)
+ streq \rd, [\r_car_base, #\pll_base]
+.endm
+
+.macro emc_device_mask, rd, base
+ ldr \rd, [\base, #EMC_ADR_CFG]
+ tst \rd, #(0x3 << 24)
+ moveq \rd, #(0x1 << 8) @ just 1 device
+ movne \rd, #(0x3 << 8) @ 2 devices
+.endm
+
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
+/*
+ * tegra20_hotplug_shutdown(void)
+ *
+ * puts the current cpu in reset
+ * should never return
+ */
+ENTRY(tegra20_hotplug_shutdown)
+ /* Put this CPU down */
+ cpu_id r0
+ bl tegra20_cpu_shutdown
+ ret lr @ should never get here
+ENDPROC(tegra20_hotplug_shutdown)
+
+/*
+ * tegra20_cpu_shutdown(int cpu)
+ *
+ * r0 is cpu to reset
+ *
+ * puts the specified CPU in wait-for-event mode on the flow controller
+ * and puts the CPU in reset
+ * can be called on the current cpu or another cpu
+ * if called on the current cpu, does not return
+ * MUST NOT BE CALLED FOR CPU 0.
+ *
+ * corrupts r0-r3, r12
+ */
+ENTRY(tegra20_cpu_shutdown)
+ cmp r0, #0
+ reteq lr @ must not be called for CPU 0
+ mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT
+ ldr r2, =__tegra20_cpu1_resettable_status_offset
+ mov r12, #CPU_RESETTABLE
+ strb r12, [r1, r2]
+
+ cpu_to_halt_reg r1, r0
+ ldr r3, =TEGRA_FLOW_CTRL_VIRT
+ mov r2, #FLOW_CTRL_WAITEVENT | FLOW_CTRL_JTAG_RESUME
+ str r2, [r3, r1] @ put flow controller in wait event mode
+ ldr r2, [r3, r1]
+ isb
+ dsb
+ movw r1, 0x1011
+ mov r1, r1, lsl r0
+ ldr r3, =TEGRA_CLK_RESET_VIRT
+ str r1, [r3, #0x340] @ put slave CPU in reset
+ isb
+ dsb
+ cpu_id r3
+ cmp r3, r0
+ beq .
+ ret lr
+ENDPROC(tegra20_cpu_shutdown)
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+/*
+ * tegra_pen_lock
+ *
+ * spinlock implementation with no atomic test-and-set and no coherence
+ * using Peterson's algorithm on strongly-ordered registers
+ * used to synchronize a cpu waking up from wfi with entering lp2 on idle
+ *
+ * The reference link of Peterson's algorithm:
+ * http://en.wikipedia.org/wiki/Peterson's_algorithm
+ *
+ * SCRATCH37 = r1 = !turn (inverted from Peterson's algorithm)
+ * on cpu 0:
+ * r2 = flag[0] (in SCRATCH38)
+ * r3 = flag[1] (in SCRATCH39)
+ * on cpu1:
+ * r2 = flag[1] (in SCRATCH39)
+ * r3 = flag[0] (in SCRATCH38)
+ *
+ * must be called with MMU on
+ * corrupts r0-r3, r12
+ */
+ENTRY(tegra_pen_lock)
+ mov32 r3, TEGRA_PMC_VIRT
+ cpu_id r0
+ add r1, r3, #PMC_SCRATCH37
+ cmp r0, #0
+ addeq r2, r3, #PMC_SCRATCH38
+ addeq r3, r3, #PMC_SCRATCH39
+ addne r2, r3, #PMC_SCRATCH39
+ addne r3, r3, #PMC_SCRATCH38
+
+ mov r12, #1
+ str r12, [r2] @ flag[cpu] = 1
+ dsb
+ str r12, [r1] @ !turn = cpu
+1: dsb
+ ldr r12, [r3]
+ cmp r12, #1 @ flag[!cpu] == 1?
+ ldreq r12, [r1]
+ cmpeq r12, r0 @ !turn == cpu?
+ beq 1b @ while !turn == cpu && flag[!cpu] == 1
+
+ ret lr @ locked
+ENDPROC(tegra_pen_lock)
+
+ENTRY(tegra_pen_unlock)
+ dsb
+ mov32 r3, TEGRA_PMC_VIRT
+ cpu_id r0
+ cmp r0, #0
+ addeq r2, r3, #PMC_SCRATCH38
+ addne r2, r3, #PMC_SCRATCH39
+ mov r12, #0
+ str r12, [r2]
+ ret lr
+ENDPROC(tegra_pen_unlock)
+
+/*
+ * tegra20_cpu_clear_resettable(void)
+ *
+ * Called to clear the "resettable soon" flag in IRAM variable when
+ * it is expected that the secondary CPU will be idle soon.
+ */
+ENTRY(tegra20_cpu_clear_resettable)
+ mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT
+ ldr r2, =__tegra20_cpu1_resettable_status_offset
+ mov r12, #CPU_NOT_RESETTABLE
+ strb r12, [r1, r2]
+ ret lr
+ENDPROC(tegra20_cpu_clear_resettable)
+
+/*
+ * tegra20_cpu_set_resettable_soon(void)
+ *
+ * Called to set the "resettable soon" flag in IRAM variable when
+ * it is expected that the secondary CPU will be idle soon.
+ */
+ENTRY(tegra20_cpu_set_resettable_soon)
+ mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT
+ ldr r2, =__tegra20_cpu1_resettable_status_offset
+ mov r12, #CPU_RESETTABLE_SOON
+ strb r12, [r1, r2]
+ ret lr
+ENDPROC(tegra20_cpu_set_resettable_soon)
+
+/*
+ * tegra20_cpu_is_resettable_soon(void)
+ *
+ * Returns true if the "resettable soon" flag in IRAM variable has been
+ * set because it is expected that the secondary CPU will be idle soon.
+ */
+ENTRY(tegra20_cpu_is_resettable_soon)
+ mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT
+ ldr r2, =__tegra20_cpu1_resettable_status_offset
+ ldrb r12, [r1, r2]
+ cmp r12, #CPU_RESETTABLE_SOON
+ moveq r0, #1
+ movne r0, #0
+ ret lr
+ENDPROC(tegra20_cpu_is_resettable_soon)
+
+/*
+ * tegra20_sleep_core_finish(unsigned long v2p)
+ *
+ * Enters suspend in LP0 or LP1 by turning off the mmu and jumping to
+ * tegra20_tear_down_core in IRAM
+ */
+ENTRY(tegra20_sleep_core_finish)
+ /* Flush, disable the L1 data cache and exit SMP */
+ bl tegra_disable_clean_inv_dcache
+
+ mov32 r3, tegra_shut_off_mmu
+ add r3, r3, r0
+
+ mov32 r0, tegra20_tear_down_core
+ mov32 r1, tegra20_iram_start
+ sub r0, r0, r1
+ mov32 r1, TEGRA_IRAM_LPx_RESUME_AREA
+ add r0, r0, r1
+
+ ret r3
+ENDPROC(tegra20_sleep_core_finish)
+
+/*
+ * tegra20_sleep_cpu_secondary_finish(unsigned long v2p)
+ *
+ * Enters WFI on secondary CPU by exiting coherency.
+ */
+ENTRY(tegra20_sleep_cpu_secondary_finish)
+ stmfd sp!, {r4-r11, lr}
+
+ mrc p15, 0, r11, c1, c0, 1 @ save actlr before exiting coherency
+
+ /* Flush and disable the L1 data cache */
+ mov r0, #TEGRA_FLUSH_CACHE_LOUIS
+ bl tegra_disable_clean_inv_dcache
+
+ mov32 r0, TEGRA_IRAM_RESET_BASE_VIRT
+ ldr r4, =__tegra20_cpu1_resettable_status_offset
+ mov r3, #CPU_RESETTABLE
+ strb r3, [r0, r4]
+
+ bl tegra_cpu_do_idle
+
+ /*
+ * cpu may be reset while in wfi, which will return through
+ * tegra_resume to cpu_resume
+ * or interrupt may wake wfi, which will return here
+ * cpu state is unchanged - MMU is on, cache is on, coherency
+ * is off, and the data cache is off
+ *
+ * r11 contains the original actlr
+ */
+
+ bl tegra_pen_lock
+
+ mov32 r0, TEGRA_IRAM_RESET_BASE_VIRT
+ ldr r4, =__tegra20_cpu1_resettable_status_offset
+ mov r3, #CPU_NOT_RESETTABLE
+ strb r3, [r0, r4]
+
+ bl tegra_pen_unlock
+
+ /* Re-enable the data cache */
+ mrc p15, 0, r10, c1, c0, 0
+ orr r10, r10, #CR_C
+ mcr p15, 0, r10, c1, c0, 0
+ isb
+
+ mcr p15, 0, r11, c1, c0, 1 @ reenable coherency
+
+ /* Invalidate the TLBs & BTAC */
+ mov r1, #0
+ mcr p15, 0, r1, c8, c3, 0 @ invalidate shared TLBs
+ mcr p15, 0, r1, c7, c1, 6 @ invalidate shared BTAC
+ dsb
+ isb
+
+ /* the cpu was running with coherency disabled,
+ * caches may be out of date */
+ bl v7_flush_kern_cache_louis
+
+ ldmfd sp!, {r4 - r11, pc}
+ENDPROC(tegra20_sleep_cpu_secondary_finish)
+
+/*
+ * tegra20_tear_down_cpu
+ *
+ * Switches the CPU cluster to PLL-P and enters sleep.
+ */
+ENTRY(tegra20_tear_down_cpu)
+ bl tegra_switch_cpu_to_pllp
+ b tegra20_enter_sleep
+ENDPROC(tegra20_tear_down_cpu)
+
+/* START OF ROUTINES COPIED TO IRAM */
+ .align L1_CACHE_SHIFT
+ .globl tegra20_iram_start
+tegra20_iram_start:
+
+/*
+ * tegra20_lp1_reset
+ *
+ * reset vector for LP1 restore; copied into IRAM during suspend.
+ * Brings the system back up to a safe staring point (SDRAM out of
+ * self-refresh, PLLC, PLLM and PLLP reenabled, CPU running on PLLP,
+ * system clock running on the same PLL that it suspended at), and
+ * jumps to tegra_resume to restore virtual addressing and PLLX.
+ * The physical address of tegra_resume expected to be stored in
+ * PMC_SCRATCH41.
+ *
+ * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_LPx_RESUME_AREA.
+ */
+ENTRY(tegra20_lp1_reset)
+ /*
+ * The CPU and system bus are running at 32KHz and executing from
+ * IRAM when this code is executed; immediately switch to CLKM and
+ * enable PLLM, PLLP, PLLC.
+ */
+ mov32 r0, TEGRA_CLK_RESET_BASE
+
+ mov r1, #(1 << 28)
+ str r1, [r0, #CLK_RESET_SCLK_BURST]
+ str r1, [r0, #CLK_RESET_CCLK_BURST]
+ mov r1, #0
+ str r1, [r0, #CLK_RESET_CCLK_DIVIDER]
+ str r1, [r0, #CLK_RESET_SCLK_DIVIDER]
+
+ pll_enable r1, r0, CLK_RESET_PLLM_BASE
+ pll_enable r1, r0, CLK_RESET_PLLP_BASE
+ pll_enable r1, r0, CLK_RESET_PLLC_BASE
+
+ adr r2, tegra20_sdram_pad_address
+ adr r4, tegra20_sdram_pad_save
+ mov r5, #0
+
+ ldr r6, tegra20_sdram_pad_size
+padload:
+ ldr r7, [r2, r5] @ r7 is the addr in the pad_address
+
+ ldr r1, [r4, r5]
+ str r1, [r7] @ restore the value in pad_save
+
+ add r5, r5, #4
+ cmp r6, r5
+ bne padload
+
+padload_done:
+ /* 255uS delay for PLL stabilization */
+ mov32 r7, TEGRA_TMRUS_BASE
+ ldr r1, [r7]
+ add r1, r1, #0xff
+ wait_until r1, r7, r9
+
+ adr r4, tegra20_sclk_save
+ ldr r4, [r4]
+ str r4, [r0, #CLK_RESET_SCLK_BURST]
+ mov32 r4, ((1 << 28) | (4)) @ burst policy is PLLP
+ str r4, [r0, #CLK_RESET_CCLK_BURST]
+
+ mov32 r0, TEGRA_EMC_BASE
+ ldr r1, [r0, #EMC_CFG]
+ bic r1, r1, #(1 << 31) @ disable DRAM_CLK_STOP
+ str r1, [r0, #EMC_CFG]
+
+ mov r1, #0
+ str r1, [r0, #EMC_SELF_REF] @ take DRAM out of self refresh
+ mov r1, #1
+ str r1, [r0, #EMC_NOP]
+ str r1, [r0, #EMC_NOP]
+ str r1, [r0, #EMC_REFRESH]
+
+ emc_device_mask r1, r0
+
+exit_selfrefresh_loop:
+ ldr r2, [r0, #EMC_EMC_STATUS]
+ ands r2, r2, r1
+ bne exit_selfrefresh_loop
+
+ mov r1, #0 @ unstall all transactions
+ str r1, [r0, #EMC_REQ_CTRL]
+
+ mov32 r0, TEGRA_PMC_BASE
+ ldr r0, [r0, #PMC_SCRATCH41]
+ ret r0 @ jump to tegra_resume
+ENDPROC(tegra20_lp1_reset)
+
+/*
+ * tegra20_tear_down_core
+ *
+ * copied into and executed from IRAM
+ * puts memory in self-refresh for LP0 and LP1
+ */
+tegra20_tear_down_core:
+ bl tegra20_sdram_self_refresh
+ bl tegra20_switch_cpu_to_clk32k
+ b tegra20_enter_sleep
+
+/*
+ * tegra20_switch_cpu_to_clk32k
+ *
+ * In LP0 and LP1 all PLLs will be turned off. Switch the CPU and system clock
+ * to the 32KHz clock.
+ */
+tegra20_switch_cpu_to_clk32k:
+ /*
+ * start by switching to CLKM to safely disable PLLs, then switch to
+ * CLKS.
+ */
+ mov r0, #(1 << 28)
+ str r0, [r5, #CLK_RESET_SCLK_BURST]
+ str r0, [r5, #CLK_RESET_CCLK_BURST]
+ mov r0, #0
+ str r0, [r5, #CLK_RESET_CCLK_DIVIDER]
+ str r0, [r5, #CLK_RESET_SCLK_DIVIDER]
+
+ /* 2uS delay delay between changing SCLK and disabling PLLs */
+ mov32 r7, TEGRA_TMRUS_BASE
+ ldr r1, [r7]
+ add r1, r1, #2
+ wait_until r1, r7, r9
+
+ /* disable PLLM, PLLP and PLLC */
+ ldr r0, [r5, #CLK_RESET_PLLM_BASE]
+ bic r0, r0, #(1 << 30)
+ str r0, [r5, #CLK_RESET_PLLM_BASE]
+ ldr r0, [r5, #CLK_RESET_PLLP_BASE]
+ bic r0, r0, #(1 << 30)
+ str r0, [r5, #CLK_RESET_PLLP_BASE]
+ ldr r0, [r5, #CLK_RESET_PLLC_BASE]
+ bic r0, r0, #(1 << 30)
+ str r0, [r5, #CLK_RESET_PLLC_BASE]
+
+ /* switch to CLKS */
+ mov r0, #0 /* brust policy = 32KHz */
+ str r0, [r5, #CLK_RESET_SCLK_BURST]
+
+ ret lr
+
+/*
+ * tegra20_enter_sleep
+ *
+ * uses flow controller to enter sleep state
+ * executes from IRAM with SDRAM in selfrefresh when target state is LP0 or LP1
+ * executes from SDRAM with target state is LP2
+ */
+tegra20_enter_sleep:
+ mov32 r6, TEGRA_FLOW_CTRL_BASE
+
+ mov r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT
+ orr r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ
+ cpu_id r1
+ cpu_to_halt_reg r1, r1
+ str r0, [r6, r1]
+ dsb
+ ldr r0, [r6, r1] /* memory barrier */
+
+halted:
+ dsb
+ wfe /* CPU should be power gated here */
+ isb
+ b halted
+
+/*
+ * tegra20_sdram_self_refresh
+ *
+ * called with MMU off and caches disabled
+ * puts sdram in self refresh
+ * must be executed from IRAM
+ */
+tegra20_sdram_self_refresh:
+ mov32 r1, TEGRA_EMC_BASE @ r1 reserved for emc base addr
+
+ mov r2, #3
+ str r2, [r1, #EMC_REQ_CTRL] @ stall incoming DRAM requests
+
+emcidle:
+ ldr r2, [r1, #EMC_EMC_STATUS]
+ tst r2, #4
+ beq emcidle
+
+ mov r2, #1
+ str r2, [r1, #EMC_SELF_REF]
+
+ emc_device_mask r2, r1
+
+emcself:
+ ldr r3, [r1, #EMC_EMC_STATUS]
+ and r3, r3, r2
+ cmp r3, r2
+ bne emcself @ loop until DDR in self-refresh
+
+ adr r2, tegra20_sdram_pad_address
+ adr r3, tegra20_sdram_pad_safe
+ adr r4, tegra20_sdram_pad_save
+ mov r5, #0
+
+ ldr r6, tegra20_sdram_pad_size
+padsave:
+ ldr r0, [r2, r5] @ r0 is the addr in the pad_address
+
+ ldr r1, [r0]
+ str r1, [r4, r5] @ save the content of the addr
+
+ ldr r1, [r3, r5]
+ str r1, [r0] @ set the save val to the addr
+
+ add r5, r5, #4
+ cmp r6, r5
+ bne padsave
+padsave_done:
+
+ mov32 r5, TEGRA_CLK_RESET_BASE
+ ldr r0, [r5, #CLK_RESET_SCLK_BURST]
+ adr r2, tegra20_sclk_save
+ str r0, [r2]
+ dsb
+ ret lr
+
+tegra20_sdram_pad_address:
+ .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGCPADCTRL
+ .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGDPADCTRL
+ .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CLKCFGPADCTRL
+ .word TEGRA_APB_MISC_BASE + APB_MISC_XM2COMPPADCTRL
+ .word TEGRA_APB_MISC_BASE + APB_MISC_XM2VTTGENPADCTRL
+ .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGCPADCTRL2
+ .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGDPADCTRL2
+
+tegra20_sdram_pad_size:
+ .word tegra20_sdram_pad_size - tegra20_sdram_pad_address
+
+tegra20_sdram_pad_safe:
+ .word 0x8
+ .word 0x8
+ .word 0x0
+ .word 0x8
+ .word 0x5500
+ .word 0x08080040
+ .word 0x0
+
+tegra20_sclk_save:
+ .word 0x0
+
+tegra20_sdram_pad_save:
+ .rept (tegra20_sdram_pad_size - tegra20_sdram_pad_address) / 4
+ .long 0
+ .endr
+
+ .ltorg
+/* dummy symbol for end of IRAM */
+ .align L1_CACHE_SHIFT
+ .globl tegra20_iram_end
+tegra20_iram_end:
+ b .
+#endif
diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S
new file mode 100644
index 000000000..5d8d13aea
--- /dev/null
+++ b/arch/arm/mach-tegra/sleep-tegra30.S
@@ -0,0 +1,831 @@
+/*
+ * Copyright (c) 2012, NVIDIA Corporation. 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/linkage.h>
+
+#include <soc/tegra/fuse.h>
+
+#include <asm/asm-offsets.h>
+#include <asm/assembler.h>
+#include <asm/cache.h>
+
+#include "flowctrl.h"
+#include "irammap.h"
+#include "sleep.h"
+
+#define EMC_CFG 0xc
+#define EMC_ADR_CFG 0x10
+#define EMC_TIMING_CONTROL 0x28
+#define EMC_REFRESH 0x70
+#define EMC_NOP 0xdc
+#define EMC_SELF_REF 0xe0
+#define EMC_MRW 0xe8
+#define EMC_FBIO_CFG5 0x104
+#define EMC_AUTO_CAL_CONFIG 0x2a4
+#define EMC_AUTO_CAL_INTERVAL 0x2a8
+#define EMC_AUTO_CAL_STATUS 0x2ac
+#define EMC_REQ_CTRL 0x2b0
+#define EMC_CFG_DIG_DLL 0x2bc
+#define EMC_EMC_STATUS 0x2b4
+#define EMC_ZCAL_INTERVAL 0x2e0
+#define EMC_ZQ_CAL 0x2ec
+#define EMC_XM2VTTGENPADCTRL 0x310
+#define EMC_XM2VTTGENPADCTRL2 0x314
+
+#define PMC_CTRL 0x0
+#define PMC_CTRL_SIDE_EFFECT_LP0 (1 << 14) /* enter LP0 when CPU pwr gated */
+
+#define PMC_PLLP_WB0_OVERRIDE 0xf8
+#define PMC_IO_DPD_REQ 0x1b8
+#define PMC_IO_DPD_STATUS 0x1bc
+
+#define CLK_RESET_CCLK_BURST 0x20
+#define CLK_RESET_CCLK_DIVIDER 0x24
+#define CLK_RESET_SCLK_BURST 0x28
+#define CLK_RESET_SCLK_DIVIDER 0x2c
+
+#define CLK_RESET_PLLC_BASE 0x80
+#define CLK_RESET_PLLC_MISC 0x8c
+#define CLK_RESET_PLLM_BASE 0x90
+#define CLK_RESET_PLLM_MISC 0x9c
+#define CLK_RESET_PLLP_BASE 0xa0
+#define CLK_RESET_PLLP_MISC 0xac
+#define CLK_RESET_PLLA_BASE 0xb0
+#define CLK_RESET_PLLA_MISC 0xbc
+#define CLK_RESET_PLLX_BASE 0xe0
+#define CLK_RESET_PLLX_MISC 0xe4
+#define CLK_RESET_PLLX_MISC3 0x518
+#define CLK_RESET_PLLX_MISC3_IDDQ 3
+#define CLK_RESET_PLLM_MISC_IDDQ 5
+#define CLK_RESET_PLLC_MISC_IDDQ 26
+
+#define CLK_RESET_CLK_SOURCE_MSELECT 0x3b4
+
+#define MSELECT_CLKM (0x3 << 30)
+
+#define LOCK_DELAY 50 /* safety delay after lock is detected */
+
+#define TEGRA30_POWER_HOTPLUG_SHUTDOWN (1 << 27) /* Hotplug shutdown */
+
+.macro emc_device_mask, rd, base
+ ldr \rd, [\base, #EMC_ADR_CFG]
+ tst \rd, #0x1
+ moveq \rd, #(0x1 << 8) @ just 1 device
+ movne \rd, #(0x3 << 8) @ 2 devices
+.endm
+
+.macro emc_timing_update, rd, base
+ mov \rd, #1
+ str \rd, [\base, #EMC_TIMING_CONTROL]
+1001:
+ ldr \rd, [\base, #EMC_EMC_STATUS]
+ tst \rd, #(0x1<<23) @ wait EMC_STATUS_TIMING_UPDATE_STALLED is clear
+ bne 1001b
+.endm
+
+.macro pll_enable, rd, r_car_base, pll_base, pll_misc
+ ldr \rd, [\r_car_base, #\pll_base]
+ tst \rd, #(1 << 30)
+ orreq \rd, \rd, #(1 << 30)
+ streq \rd, [\r_car_base, #\pll_base]
+ /* Enable lock detector */
+ .if \pll_misc
+ ldr \rd, [\r_car_base, #\pll_misc]
+ bic \rd, \rd, #(1 << 18)
+ str \rd, [\r_car_base, #\pll_misc]
+ ldr \rd, [\r_car_base, #\pll_misc]
+ ldr \rd, [\r_car_base, #\pll_misc]
+ orr \rd, \rd, #(1 << 18)
+ str \rd, [\r_car_base, #\pll_misc]
+ .endif
+.endm
+
+.macro pll_locked, rd, r_car_base, pll_base
+1:
+ ldr \rd, [\r_car_base, #\pll_base]
+ tst \rd, #(1 << 27)
+ beq 1b
+.endm
+
+.macro pll_iddq_exit, rd, car, iddq, iddq_bit
+ ldr \rd, [\car, #\iddq]
+ bic \rd, \rd, #(1<<\iddq_bit)
+ str \rd, [\car, #\iddq]
+.endm
+
+.macro pll_iddq_entry, rd, car, iddq, iddq_bit
+ ldr \rd, [\car, #\iddq]
+ orr \rd, \rd, #(1<<\iddq_bit)
+ str \rd, [\car, #\iddq]
+.endm
+
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
+/*
+ * tegra30_hotplug_shutdown(void)
+ *
+ * Powergates the current CPU.
+ * Should never return.
+ */
+ENTRY(tegra30_hotplug_shutdown)
+ /* Powergate this CPU */
+ mov r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN
+ bl tegra30_cpu_shutdown
+ ret lr @ should never get here
+ENDPROC(tegra30_hotplug_shutdown)
+
+/*
+ * tegra30_cpu_shutdown(unsigned long flags)
+ *
+ * Puts the current CPU in wait-for-event mode on the flow controller
+ * and powergates it -- flags (in R0) indicate the request type.
+ *
+ * r10 = SoC ID
+ * corrupts r0-r4, r10-r12
+ */
+ENTRY(tegra30_cpu_shutdown)
+ cpu_id r3
+ tegra_get_soc_id TEGRA_APB_MISC_VIRT, r10
+ cmp r10, #TEGRA30
+ bne _no_cpu0_chk @ It's not Tegra30
+
+ cmp r3, #0
+ reteq lr @ Must never be called for CPU 0
+_no_cpu0_chk:
+
+ ldr r12, =TEGRA_FLOW_CTRL_VIRT
+ cpu_to_csr_reg r1, r3
+ add r1, r1, r12 @ virtual CSR address for this CPU
+ cpu_to_halt_reg r2, r3
+ add r2, r2, r12 @ virtual HALT_EVENTS address for this CPU
+
+ /*
+ * Clear this CPU's "event" and "interrupt" flags and power gate
+ * it when halting but not before it is in the "WFE" state.
+ */
+ movw r12, \
+ FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | \
+ FLOW_CTRL_CSR_ENABLE
+ cmp r10, #TEGRA30
+ moveq r4, #(1 << 4) @ wfe bitmap
+ movne r4, #(1 << 8) @ wfi bitmap
+ ARM( orr r12, r12, r4, lsl r3 )
+ THUMB( lsl r4, r4, r3 )
+ THUMB( orr r12, r12, r4 )
+ str r12, [r1]
+
+ /* Halt this CPU. */
+ mov r3, #0x400
+delay_1:
+ subs r3, r3, #1 @ delay as a part of wfe war.
+ bge delay_1;
+ cpsid a @ disable imprecise aborts.
+ ldr r3, [r1] @ read CSR
+ str r3, [r1] @ clear CSR
+
+ tst r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN
+ beq flow_ctrl_setting_for_lp2
+
+ /* flow controller set up for hotplug */
+ mov r3, #FLOW_CTRL_WAITEVENT @ For hotplug
+ b flow_ctrl_done
+flow_ctrl_setting_for_lp2:
+ /* flow controller set up for LP2 */
+ cmp r10, #TEGRA30
+ moveq r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT @ For LP2
+ movne r3, #FLOW_CTRL_WAITEVENT
+ orrne r3, r3, #FLOW_CTRL_HALT_GIC_IRQ
+ orrne r3, r3, #FLOW_CTRL_HALT_GIC_FIQ
+flow_ctrl_done:
+ cmp r10, #TEGRA30
+ str r3, [r2]
+ ldr r0, [r2]
+ b wfe_war
+
+__cpu_reset_again:
+ dsb
+ .align 5
+ wfeeq @ CPU should be power gated here
+ wfine
+wfe_war:
+ b __cpu_reset_again
+
+ /*
+ * 38 nop's, which fills reset of wfe cache line and
+ * 4 more cachelines with nop
+ */
+ .rept 38
+ nop
+ .endr
+ b . @ should never get here
+
+ENDPROC(tegra30_cpu_shutdown)
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+/*
+ * tegra30_sleep_core_finish(unsigned long v2p)
+ *
+ * Enters suspend in LP0 or LP1 by turning off the MMU and jumping to
+ * tegra30_tear_down_core in IRAM
+ */
+ENTRY(tegra30_sleep_core_finish)
+ /* Flush, disable the L1 data cache and exit SMP */
+ bl tegra_disable_clean_inv_dcache
+
+ /*
+ * Preload all the address literals that are needed for the
+ * CPU power-gating process, to avoid loading from SDRAM which
+ * are not supported once SDRAM is put into self-refresh.
+ * LP0 / LP1 use physical address, since the MMU needs to be
+ * disabled before putting SDRAM into self-refresh to avoid
+ * memory access due to page table walks.
+ */
+ mov32 r4, TEGRA_PMC_BASE
+ mov32 r5, TEGRA_CLK_RESET_BASE
+ mov32 r6, TEGRA_FLOW_CTRL_BASE
+ mov32 r7, TEGRA_TMRUS_BASE
+
+ mov32 r3, tegra_shut_off_mmu
+ add r3, r3, r0
+
+ mov32 r0, tegra30_tear_down_core
+ mov32 r1, tegra30_iram_start
+ sub r0, r0, r1
+ mov32 r1, TEGRA_IRAM_LPx_RESUME_AREA
+ add r0, r0, r1
+
+ ret r3
+ENDPROC(tegra30_sleep_core_finish)
+
+/*
+ * tegra30_sleep_cpu_secondary_finish(unsigned long v2p)
+ *
+ * Enters LP2 on secondary CPU by exiting coherency and powergating the CPU.
+ */
+ENTRY(tegra30_sleep_cpu_secondary_finish)
+ mov r7, lr
+
+ /* Flush and disable the L1 data cache */
+ mov r0, #TEGRA_FLUSH_CACHE_LOUIS
+ bl tegra_disable_clean_inv_dcache
+
+ /* Powergate this CPU. */
+ mov r0, #0 @ power mode flags (!hotplug)
+ bl tegra30_cpu_shutdown
+ mov r0, #1 @ never return here
+ ret r7
+ENDPROC(tegra30_sleep_cpu_secondary_finish)
+
+/*
+ * tegra30_tear_down_cpu
+ *
+ * Switches the CPU to enter sleep.
+ */
+ENTRY(tegra30_tear_down_cpu)
+ mov32 r6, TEGRA_FLOW_CTRL_BASE
+
+ b tegra30_enter_sleep
+ENDPROC(tegra30_tear_down_cpu)
+
+/* START OF ROUTINES COPIED TO IRAM */
+ .align L1_CACHE_SHIFT
+ .globl tegra30_iram_start
+tegra30_iram_start:
+
+/*
+ * tegra30_lp1_reset
+ *
+ * reset vector for LP1 restore; copied into IRAM during suspend.
+ * Brings the system back up to a safe staring point (SDRAM out of
+ * self-refresh, PLLC, PLLM and PLLP reenabled, CPU running on PLLX,
+ * system clock running on the same PLL that it suspended at), and
+ * jumps to tegra_resume to restore virtual addressing.
+ * The physical address of tegra_resume expected to be stored in
+ * PMC_SCRATCH41.
+ *
+ * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_LPx_RESUME_AREA.
+ */
+ENTRY(tegra30_lp1_reset)
+ /*
+ * The CPU and system bus are running at 32KHz and executing from
+ * IRAM when this code is executed; immediately switch to CLKM and
+ * enable PLLP, PLLM, PLLC, PLLA and PLLX.
+ */
+ mov32 r0, TEGRA_CLK_RESET_BASE
+
+ mov r1, #(1 << 28)
+ str r1, [r0, #CLK_RESET_SCLK_BURST]
+ str r1, [r0, #CLK_RESET_CCLK_BURST]
+ mov r1, #0
+ str r1, [r0, #CLK_RESET_CCLK_DIVIDER]
+ str r1, [r0, #CLK_RESET_SCLK_DIVIDER]
+
+ tegra_get_soc_id TEGRA_APB_MISC_BASE, r10
+ cmp r10, #TEGRA30
+ beq _no_pll_iddq_exit
+
+ pll_iddq_exit r1, r0, CLK_RESET_PLLM_MISC, CLK_RESET_PLLM_MISC_IDDQ
+ pll_iddq_exit r1, r0, CLK_RESET_PLLC_MISC, CLK_RESET_PLLC_MISC_IDDQ
+ pll_iddq_exit r1, r0, CLK_RESET_PLLX_MISC3, CLK_RESET_PLLX_MISC3_IDDQ
+
+ mov32 r7, TEGRA_TMRUS_BASE
+ ldr r1, [r7]
+ add r1, r1, #2
+ wait_until r1, r7, r3
+
+ /* enable PLLM via PMC */
+ mov32 r2, TEGRA_PMC_BASE
+ ldr r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
+ orr r1, r1, #(1 << 12)
+ str r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
+
+ pll_enable r1, r0, CLK_RESET_PLLM_BASE, 0
+ pll_enable r1, r0, CLK_RESET_PLLC_BASE, 0
+ pll_enable r1, r0, CLK_RESET_PLLX_BASE, 0
+
+ b _pll_m_c_x_done
+
+_no_pll_iddq_exit:
+ /* enable PLLM via PMC */
+ mov32 r2, TEGRA_PMC_BASE
+ ldr r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
+ orr r1, r1, #(1 << 12)
+ str r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
+
+ pll_enable r1, r0, CLK_RESET_PLLM_BASE, CLK_RESET_PLLM_MISC
+ pll_enable r1, r0, CLK_RESET_PLLC_BASE, CLK_RESET_PLLC_MISC
+ pll_enable r1, r0, CLK_RESET_PLLX_BASE, CLK_RESET_PLLX_MISC
+
+_pll_m_c_x_done:
+ pll_enable r1, r0, CLK_RESET_PLLP_BASE, CLK_RESET_PLLP_MISC
+ pll_enable r1, r0, CLK_RESET_PLLA_BASE, CLK_RESET_PLLA_MISC
+
+ pll_locked r1, r0, CLK_RESET_PLLM_BASE
+ pll_locked r1, r0, CLK_RESET_PLLP_BASE
+ pll_locked r1, r0, CLK_RESET_PLLA_BASE
+ pll_locked r1, r0, CLK_RESET_PLLC_BASE
+ pll_locked r1, r0, CLK_RESET_PLLX_BASE
+
+ mov32 r7, TEGRA_TMRUS_BASE
+ ldr r1, [r7]
+ add r1, r1, #LOCK_DELAY
+ wait_until r1, r7, r3
+
+ adr r5, tegra_sdram_pad_save
+
+ ldr r4, [r5, #0x18] @ restore CLK_SOURCE_MSELECT
+ str r4, [r0, #CLK_RESET_CLK_SOURCE_MSELECT]
+
+ ldr r4, [r5, #0x1C] @ restore SCLK_BURST
+ str r4, [r0, #CLK_RESET_SCLK_BURST]
+
+ cmp r10, #TEGRA30
+ movweq r4, #:lower16:((1 << 28) | (0x8)) @ burst policy is PLLX
+ movteq r4, #:upper16:((1 << 28) | (0x8))
+ movwne r4, #:lower16:((1 << 28) | (0xe))
+ movtne r4, #:upper16:((1 << 28) | (0xe))
+ str r4, [r0, #CLK_RESET_CCLK_BURST]
+
+ /* Restore pad power state to normal */
+ ldr r1, [r5, #0x14] @ PMC_IO_DPD_STATUS
+ mvn r1, r1
+ bic r1, r1, #(1 << 31)
+ orr r1, r1, #(1 << 30)
+ str r1, [r2, #PMC_IO_DPD_REQ] @ DPD_OFF
+
+ cmp r10, #TEGRA30
+ movweq r0, #:lower16:TEGRA_EMC_BASE @ r0 reserved for emc base
+ movteq r0, #:upper16:TEGRA_EMC_BASE
+ cmp r10, #TEGRA114
+ movweq r0, #:lower16:TEGRA_EMC0_BASE
+ movteq r0, #:upper16:TEGRA_EMC0_BASE
+ cmp r10, #TEGRA124
+ movweq r0, #:lower16:TEGRA124_EMC_BASE
+ movteq r0, #:upper16:TEGRA124_EMC_BASE
+
+exit_self_refresh:
+ ldr r1, [r5, #0xC] @ restore EMC_XM2VTTGENPADCTRL
+ str r1, [r0, #EMC_XM2VTTGENPADCTRL]
+ ldr r1, [r5, #0x10] @ restore EMC_XM2VTTGENPADCTRL2
+ str r1, [r0, #EMC_XM2VTTGENPADCTRL2]
+ ldr r1, [r5, #0x8] @ restore EMC_AUTO_CAL_INTERVAL
+ str r1, [r0, #EMC_AUTO_CAL_INTERVAL]
+
+ /* Relock DLL */
+ ldr r1, [r0, #EMC_CFG_DIG_DLL]
+ orr r1, r1, #(1 << 30) @ set DLL_RESET
+ str r1, [r0, #EMC_CFG_DIG_DLL]
+
+ emc_timing_update r1, r0
+
+ cmp r10, #TEGRA114
+ movweq r1, #:lower16:TEGRA_EMC1_BASE
+ movteq r1, #:upper16:TEGRA_EMC1_BASE
+ cmpeq r0, r1
+
+ ldr r1, [r0, #EMC_AUTO_CAL_CONFIG]
+ orr r1, r1, #(1 << 31) @ set AUTO_CAL_ACTIVE
+ orreq r1, r1, #(1 << 27) @ set slave mode for channel 1
+ str r1, [r0, #EMC_AUTO_CAL_CONFIG]
+
+emc_wait_auto_cal_onetime:
+ ldr r1, [r0, #EMC_AUTO_CAL_STATUS]
+ tst r1, #(1 << 31) @ wait until AUTO_CAL_ACTIVE is cleared
+ bne emc_wait_auto_cal_onetime
+
+ ldr r1, [r0, #EMC_CFG]
+ bic r1, r1, #(1 << 31) @ disable DRAM_CLK_STOP_PD
+ str r1, [r0, #EMC_CFG]
+
+ mov r1, #0
+ str r1, [r0, #EMC_SELF_REF] @ take DRAM out of self refresh
+ mov r1, #1
+ cmp r10, #TEGRA30
+ streq r1, [r0, #EMC_NOP]
+ streq r1, [r0, #EMC_NOP]
+ streq r1, [r0, #EMC_REFRESH]
+
+ emc_device_mask r1, r0
+
+exit_selfrefresh_loop:
+ ldr r2, [r0, #EMC_EMC_STATUS]
+ ands r2, r2, r1
+ bne exit_selfrefresh_loop
+
+ lsr r1, r1, #8 @ devSel, bit0:dev0, bit1:dev1
+
+ mov32 r7, TEGRA_TMRUS_BASE
+ ldr r2, [r0, #EMC_FBIO_CFG5]
+
+ and r2, r2, #3 @ check DRAM_TYPE
+ cmp r2, #2
+ beq emc_lpddr2
+
+ /* Issue a ZQ_CAL for dev0 - DDR3 */
+ mov32 r2, 0x80000011 @ DEV_SELECTION=2, LENGTH=LONG, CMD=1
+ str r2, [r0, #EMC_ZQ_CAL]
+ ldr r2, [r7]
+ add r2, r2, #10
+ wait_until r2, r7, r3
+
+ tst r1, #2
+ beq zcal_done
+
+ /* Issue a ZQ_CAL for dev1 - DDR3 */
+ mov32 r2, 0x40000011 @ DEV_SELECTION=1, LENGTH=LONG, CMD=1
+ str r2, [r0, #EMC_ZQ_CAL]
+ ldr r2, [r7]
+ add r2, r2, #10
+ wait_until r2, r7, r3
+ b zcal_done
+
+emc_lpddr2:
+ /* Issue a ZQ_CAL for dev0 - LPDDR2 */
+ mov32 r2, 0x800A00AB @ DEV_SELECTION=2, MA=10, OP=0xAB
+ str r2, [r0, #EMC_MRW]
+ ldr r2, [r7]
+ add r2, r2, #1
+ wait_until r2, r7, r3
+
+ tst r1, #2
+ beq zcal_done
+
+ /* Issue a ZQ_CAL for dev0 - LPDDR2 */
+ mov32 r2, 0x400A00AB @ DEV_SELECTION=1, MA=10, OP=0xAB
+ str r2, [r0, #EMC_MRW]
+ ldr r2, [r7]
+ add r2, r2, #1
+ wait_until r2, r7, r3
+
+zcal_done:
+ mov r1, #0 @ unstall all transactions
+ str r1, [r0, #EMC_REQ_CTRL]
+ ldr r1, [r5, #0x4] @ restore EMC_ZCAL_INTERVAL
+ str r1, [r0, #EMC_ZCAL_INTERVAL]
+ ldr r1, [r5, #0x0] @ restore EMC_CFG
+ str r1, [r0, #EMC_CFG]
+
+ /* Tegra114 had dual EMC channel, now config the other one */
+ cmp r10, #TEGRA114
+ bne __no_dual_emc_chanl
+ mov32 r1, TEGRA_EMC1_BASE
+ cmp r0, r1
+ movne r0, r1
+ addne r5, r5, #0x20
+ bne exit_self_refresh
+__no_dual_emc_chanl:
+
+ mov32 r0, TEGRA_PMC_BASE
+ ldr r0, [r0, #PMC_SCRATCH41]
+ ret r0 @ jump to tegra_resume
+ENDPROC(tegra30_lp1_reset)
+
+ .align L1_CACHE_SHIFT
+tegra30_sdram_pad_address:
+ .word TEGRA_EMC_BASE + EMC_CFG @0x0
+ .word TEGRA_EMC_BASE + EMC_ZCAL_INTERVAL @0x4
+ .word TEGRA_EMC_BASE + EMC_AUTO_CAL_INTERVAL @0x8
+ .word TEGRA_EMC_BASE + EMC_XM2VTTGENPADCTRL @0xc
+ .word TEGRA_EMC_BASE + EMC_XM2VTTGENPADCTRL2 @0x10
+ .word TEGRA_PMC_BASE + PMC_IO_DPD_STATUS @0x14
+ .word TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT @0x18
+ .word TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST @0x1c
+tegra30_sdram_pad_address_end:
+
+tegra114_sdram_pad_address:
+ .word TEGRA_EMC0_BASE + EMC_CFG @0x0
+ .word TEGRA_EMC0_BASE + EMC_ZCAL_INTERVAL @0x4
+ .word TEGRA_EMC0_BASE + EMC_AUTO_CAL_INTERVAL @0x8
+ .word TEGRA_EMC0_BASE + EMC_XM2VTTGENPADCTRL @0xc
+ .word TEGRA_EMC0_BASE + EMC_XM2VTTGENPADCTRL2 @0x10
+ .word TEGRA_PMC_BASE + PMC_IO_DPD_STATUS @0x14
+ .word TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT @0x18
+ .word TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST @0x1c
+ .word TEGRA_EMC1_BASE + EMC_CFG @0x20
+ .word TEGRA_EMC1_BASE + EMC_ZCAL_INTERVAL @0x24
+ .word TEGRA_EMC1_BASE + EMC_AUTO_CAL_INTERVAL @0x28
+ .word TEGRA_EMC1_BASE + EMC_XM2VTTGENPADCTRL @0x2c
+ .word TEGRA_EMC1_BASE + EMC_XM2VTTGENPADCTRL2 @0x30
+tegra114_sdram_pad_adress_end:
+
+tegra124_sdram_pad_address:
+ .word TEGRA124_EMC_BASE + EMC_CFG @0x0
+ .word TEGRA124_EMC_BASE + EMC_ZCAL_INTERVAL @0x4
+ .word TEGRA124_EMC_BASE + EMC_AUTO_CAL_INTERVAL @0x8
+ .word TEGRA124_EMC_BASE + EMC_XM2VTTGENPADCTRL @0xc
+ .word TEGRA124_EMC_BASE + EMC_XM2VTTGENPADCTRL2 @0x10
+ .word TEGRA_PMC_BASE + PMC_IO_DPD_STATUS @0x14
+ .word TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT @0x18
+ .word TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST @0x1c
+tegra124_sdram_pad_address_end:
+
+tegra30_sdram_pad_size:
+ .word tegra30_sdram_pad_address_end - tegra30_sdram_pad_address
+
+tegra114_sdram_pad_size:
+ .word tegra114_sdram_pad_adress_end - tegra114_sdram_pad_address
+
+ .type tegra_sdram_pad_save, %object
+tegra_sdram_pad_save:
+ .rept (tegra114_sdram_pad_adress_end - tegra114_sdram_pad_address) / 4
+ .long 0
+ .endr
+
+/*
+ * tegra30_tear_down_core
+ *
+ * copied into and executed from IRAM
+ * puts memory in self-refresh for LP0 and LP1
+ */
+tegra30_tear_down_core:
+ bl tegra30_sdram_self_refresh
+ bl tegra30_switch_cpu_to_clk32k
+ b tegra30_enter_sleep
+
+/*
+ * tegra30_switch_cpu_to_clk32k
+ *
+ * In LP0 and LP1 all PLLs will be turned off. Switching the CPU and System CLK
+ * to the 32KHz clock.
+ * r4 = TEGRA_PMC_BASE
+ * r5 = TEGRA_CLK_RESET_BASE
+ * r6 = TEGRA_FLOW_CTRL_BASE
+ * r7 = TEGRA_TMRUS_BASE
+ * r10= SoC ID
+ */
+tegra30_switch_cpu_to_clk32k:
+ /*
+ * start by jumping to CLKM to safely disable PLLs, then jump to
+ * CLKS.
+ */
+ mov r0, #(1 << 28)
+ str r0, [r5, #CLK_RESET_SCLK_BURST]
+ /* 2uS delay delay between changing SCLK and CCLK */
+ ldr r1, [r7]
+ add r1, r1, #2
+ wait_until r1, r7, r9
+ str r0, [r5, #CLK_RESET_CCLK_BURST]
+ mov r0, #0
+ str r0, [r5, #CLK_RESET_CCLK_DIVIDER]
+ str r0, [r5, #CLK_RESET_SCLK_DIVIDER]
+
+ /* switch the clock source of mselect to be CLK_M */
+ ldr r0, [r5, #CLK_RESET_CLK_SOURCE_MSELECT]
+ orr r0, r0, #MSELECT_CLKM
+ str r0, [r5, #CLK_RESET_CLK_SOURCE_MSELECT]
+
+ /* 2uS delay delay between changing SCLK and disabling PLLs */
+ ldr r1, [r7]
+ add r1, r1, #2
+ wait_until r1, r7, r9
+
+ /* disable PLLM via PMC in LP1 */
+ ldr r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
+ bic r0, r0, #(1 << 12)
+ str r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
+
+ /* disable PLLP, PLLA, PLLC and PLLX */
+ ldr r0, [r5, #CLK_RESET_PLLP_BASE]
+ bic r0, r0, #(1 << 30)
+ str r0, [r5, #CLK_RESET_PLLP_BASE]
+ ldr r0, [r5, #CLK_RESET_PLLA_BASE]
+ bic r0, r0, #(1 << 30)
+ str r0, [r5, #CLK_RESET_PLLA_BASE]
+ ldr r0, [r5, #CLK_RESET_PLLC_BASE]
+ bic r0, r0, #(1 << 30)
+ str r0, [r5, #CLK_RESET_PLLC_BASE]
+ ldr r0, [r5, #CLK_RESET_PLLX_BASE]
+ bic r0, r0, #(1 << 30)
+ str r0, [r5, #CLK_RESET_PLLX_BASE]
+
+ cmp r10, #TEGRA30
+ beq _no_pll_in_iddq
+ pll_iddq_entry r1, r5, CLK_RESET_PLLX_MISC3, CLK_RESET_PLLX_MISC3_IDDQ
+_no_pll_in_iddq:
+
+ /* switch to CLKS */
+ mov r0, #0 /* brust policy = 32KHz */
+ str r0, [r5, #CLK_RESET_SCLK_BURST]
+
+ ret lr
+
+/*
+ * tegra30_enter_sleep
+ *
+ * uses flow controller to enter sleep state
+ * executes from IRAM with SDRAM in selfrefresh when target state is LP0 or LP1
+ * executes from SDRAM with target state is LP2
+ * r6 = TEGRA_FLOW_CTRL_BASE
+ */
+tegra30_enter_sleep:
+ cpu_id r1
+
+ cpu_to_csr_reg r2, r1
+ ldr r0, [r6, r2]
+ orr r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
+ orr r0, r0, #FLOW_CTRL_CSR_ENABLE
+ str r0, [r6, r2]
+
+ tegra_get_soc_id TEGRA_APB_MISC_BASE, r10
+ cmp r10, #TEGRA30
+ mov r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT
+ orreq r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ
+ orrne r0, r0, #FLOW_CTRL_HALT_LIC_IRQ | FLOW_CTRL_HALT_LIC_FIQ
+
+ cpu_to_halt_reg r2, r1
+ str r0, [r6, r2]
+ dsb
+ ldr r0, [r6, r2] /* memory barrier */
+
+halted:
+ isb
+ dsb
+ wfi /* CPU should be power gated here */
+
+ /* !!!FIXME!!! Implement halt failure handler */
+ b halted
+
+/*
+ * tegra30_sdram_self_refresh
+ *
+ * called with MMU off and caches disabled
+ * must be executed from IRAM
+ * r4 = TEGRA_PMC_BASE
+ * r5 = TEGRA_CLK_RESET_BASE
+ * r6 = TEGRA_FLOW_CTRL_BASE
+ * r7 = TEGRA_TMRUS_BASE
+ * r10= SoC ID
+ */
+tegra30_sdram_self_refresh:
+
+ adr r8, tegra_sdram_pad_save
+ tegra_get_soc_id TEGRA_APB_MISC_BASE, r10
+ cmp r10, #TEGRA30
+ adreq r2, tegra30_sdram_pad_address
+ ldreq r3, tegra30_sdram_pad_size
+ cmp r10, #TEGRA114
+ adreq r2, tegra114_sdram_pad_address
+ ldreq r3, tegra114_sdram_pad_size
+ cmp r10, #TEGRA124
+ adreq r2, tegra124_sdram_pad_address
+ ldreq r3, tegra30_sdram_pad_size
+
+ mov r9, #0
+
+padsave:
+ ldr r0, [r2, r9] @ r0 is the addr in the pad_address
+
+ ldr r1, [r0]
+ str r1, [r8, r9] @ save the content of the addr
+
+ add r9, r9, #4
+ cmp r3, r9
+ bne padsave
+padsave_done:
+
+ dsb
+
+ cmp r10, #TEGRA30
+ ldreq r0, =TEGRA_EMC_BASE @ r0 reserved for emc base addr
+ cmp r10, #TEGRA114
+ ldreq r0, =TEGRA_EMC0_BASE
+ cmp r10, #TEGRA124
+ ldreq r0, =TEGRA124_EMC_BASE
+
+enter_self_refresh:
+ cmp r10, #TEGRA30
+ mov r1, #0
+ str r1, [r0, #EMC_ZCAL_INTERVAL]
+ str r1, [r0, #EMC_AUTO_CAL_INTERVAL]
+ ldr r1, [r0, #EMC_CFG]
+ bic r1, r1, #(1 << 28)
+ bicne r1, r1, #(1 << 29)
+ str r1, [r0, #EMC_CFG] @ disable DYN_SELF_REF
+
+ emc_timing_update r1, r0
+
+ ldr r1, [r7]
+ add r1, r1, #5
+ wait_until r1, r7, r2
+
+emc_wait_auto_cal:
+ ldr r1, [r0, #EMC_AUTO_CAL_STATUS]
+ tst r1, #(1 << 31) @ wait until AUTO_CAL_ACTIVE is cleared
+ bne emc_wait_auto_cal
+
+ mov r1, #3
+ str r1, [r0, #EMC_REQ_CTRL] @ stall incoming DRAM requests
+
+emcidle:
+ ldr r1, [r0, #EMC_EMC_STATUS]
+ tst r1, #4
+ beq emcidle
+
+ mov r1, #1
+ str r1, [r0, #EMC_SELF_REF]
+
+ emc_device_mask r1, r0
+
+emcself:
+ ldr r2, [r0, #EMC_EMC_STATUS]
+ and r2, r2, r1
+ cmp r2, r1
+ bne emcself @ loop until DDR in self-refresh
+
+ /* Put VTTGEN in the lowest power mode */
+ ldr r1, [r0, #EMC_XM2VTTGENPADCTRL]
+ mov32 r2, 0xF8F8FFFF @ clear XM2VTTGEN_DRVUP and XM2VTTGEN_DRVDN
+ and r1, r1, r2
+ str r1, [r0, #EMC_XM2VTTGENPADCTRL]
+ ldr r1, [r0, #EMC_XM2VTTGENPADCTRL2]
+ cmp r10, #TEGRA30
+ orreq r1, r1, #7 @ set E_NO_VTTGEN
+ orrne r1, r1, #0x3f
+ str r1, [r0, #EMC_XM2VTTGENPADCTRL2]
+
+ emc_timing_update r1, r0
+
+ /* Tegra114 had dual EMC channel, now config the other one */
+ cmp r10, #TEGRA114
+ bne no_dual_emc_chanl
+ mov32 r1, TEGRA_EMC1_BASE
+ cmp r0, r1
+ movne r0, r1
+ bne enter_self_refresh
+no_dual_emc_chanl:
+
+ ldr r1, [r4, #PMC_CTRL]
+ tst r1, #PMC_CTRL_SIDE_EFFECT_LP0
+ bne pmc_io_dpd_skip
+ /*
+ * Put DDR_DATA, DISC_ADDR_CMD, DDR_ADDR_CMD, POP_ADDR_CMD, POP_CLK
+ * and COMP in the lowest power mode when LP1.
+ */
+ mov32 r1, 0x8EC00000
+ str r1, [r4, #PMC_IO_DPD_REQ]
+pmc_io_dpd_skip:
+
+ dsb
+
+ ret lr
+
+ .ltorg
+/* dummy symbol for end of IRAM */
+ .align L1_CACHE_SHIFT
+ .global tegra30_iram_end
+tegra30_iram_end:
+ b .
+#endif
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S
new file mode 100644
index 000000000..f024a5109
--- /dev/null
+++ b/arch/arm/mach-tegra/sleep.S
@@ -0,0 +1,161 @@
+/*
+ * arch/arm/mach-tegra/sleep.S
+ *
+ * Copyright (c) 2010-2011, NVIDIA Corporation.
+ * Copyright (c) 2011, Google, Inc.
+ *
+ * Author: Colin Cross <ccross@android.com>
+ * Gary King <gking@nvidia.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/linkage.h>
+
+#include <asm/assembler.h>
+#include <asm/cache.h>
+#include <asm/cp15.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "iomap.h"
+
+#include "flowctrl.h"
+#include "sleep.h"
+
+#define CLK_RESET_CCLK_BURST 0x20
+#define CLK_RESET_CCLK_DIVIDER 0x24
+
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
+/*
+ * tegra_disable_clean_inv_dcache
+ *
+ * disable, clean & invalidate the D-cache
+ *
+ * Corrupted registers: r1-r3, r6, r8, r9-r11
+ */
+ENTRY(tegra_disable_clean_inv_dcache)
+ stmfd sp!, {r0, r4-r5, r7, r9-r11, lr}
+ dmb @ ensure ordering
+
+ /* Disable the D-cache */
+ mrc p15, 0, r2, c1, c0, 0
+ bic r2, r2, #CR_C
+ mcr p15, 0, r2, c1, c0, 0
+ isb
+
+ /* Flush the D-cache */
+ cmp r0, #TEGRA_FLUSH_CACHE_ALL
+ blne v7_flush_dcache_louis
+ bleq v7_flush_dcache_all
+
+ /* Trun off coherency */
+ exit_smp r4, r5
+
+ ldmfd sp!, {r0, r4-r5, r7, r9-r11, pc}
+ENDPROC(tegra_disable_clean_inv_dcache)
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+/*
+ * tegra_init_l2_for_a15
+ *
+ * set up the correct L2 cache data RAM latency
+ */
+ENTRY(tegra_init_l2_for_a15)
+ mrc p15, 0, r0, c0, c0, 5
+ ubfx r0, r0, #8, #4
+ tst r0, #1 @ only need for cluster 0
+ bne _exit_init_l2_a15
+
+ mrc p15, 0x1, r0, c9, c0, 2
+ and r0, r0, #7
+ cmp r0, #2
+ bicne r0, r0, #7
+ orrne r0, r0, #2
+ mcrne p15, 0x1, r0, c9, c0, 2
+_exit_init_l2_a15:
+
+ ret lr
+ENDPROC(tegra_init_l2_for_a15)
+
+/*
+ * tegra_sleep_cpu_finish(unsigned long v2p)
+ *
+ * enters suspend in LP2 by turning off the mmu and jumping to
+ * tegra?_tear_down_cpu
+ */
+ENTRY(tegra_sleep_cpu_finish)
+ mov r4, r0
+ /* Flush and disable the L1 data cache */
+ mov r0, #TEGRA_FLUSH_CACHE_ALL
+ bl tegra_disable_clean_inv_dcache
+
+ mov r0, r4
+ mov32 r6, tegra_tear_down_cpu
+ ldr r1, [r6]
+ add r1, r1, r0
+
+ mov32 r3, tegra_shut_off_mmu
+ add r3, r3, r0
+ mov r0, r1
+
+ ret r3
+ENDPROC(tegra_sleep_cpu_finish)
+
+/*
+ * tegra_shut_off_mmu
+ *
+ * r0 = physical address to jump to with mmu off
+ *
+ * called with VA=PA mapping
+ * turns off MMU, icache, dcache and branch prediction
+ */
+ .align L1_CACHE_SHIFT
+ .pushsection .idmap.text, "ax"
+ENTRY(tegra_shut_off_mmu)
+ mrc p15, 0, r3, c1, c0, 0
+ movw r2, #CR_I | CR_Z | CR_C | CR_M
+ bic r3, r3, r2
+ dsb
+ mcr p15, 0, r3, c1, c0, 0
+ isb
+#ifdef CONFIG_CACHE_L2X0
+ /* Disable L2 cache */
+ check_cpu_part_num 0xc09, r9, r10
+ movweq r2, #:lower16:(TEGRA_ARM_PERIF_BASE + 0x3000)
+ movteq r2, #:upper16:(TEGRA_ARM_PERIF_BASE + 0x3000)
+ moveq r3, #0
+ streq r3, [r2, #L2X0_CTRL]
+#endif
+ ret r0
+ENDPROC(tegra_shut_off_mmu)
+ .popsection
+
+/*
+ * tegra_switch_cpu_to_pllp
+ *
+ * In LP2 the normal cpu clock pllx will be turned off. Switch the CPU to pllp
+ */
+ENTRY(tegra_switch_cpu_to_pllp)
+ /* in LP2 idle (SDRAM active), set the CPU burst policy to PLLP */
+ mov32 r5, TEGRA_CLK_RESET_BASE
+ mov r0, #(2 << 28) @ burst policy = run mode
+ orr r0, r0, #(4 << 4) @ use PLLP in run mode burst
+ str r0, [r5, #CLK_RESET_CCLK_BURST]
+ mov r0, #0
+ str r0, [r5, #CLK_RESET_CCLK_DIVIDER]
+ ret lr
+ENDPROC(tegra_switch_cpu_to_pllp)
+#endif
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
new file mode 100644
index 000000000..0d59360d8
--- /dev/null
+++ b/arch/arm/mach-tegra/sleep.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA Corporation. 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_TEGRA_SLEEP_H
+#define __MACH_TEGRA_SLEEP_H
+
+#include "iomap.h"
+#include "irammap.h"
+
+#define TEGRA_ARM_PERIF_VIRT (TEGRA_ARM_PERIF_BASE - IO_CPU_PHYS \
+ + IO_CPU_VIRT)
+#define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS \
+ + IO_PPSB_VIRT)
+#define TEGRA_CLK_RESET_VIRT (TEGRA_CLK_RESET_BASE - IO_PPSB_PHYS \
+ + IO_PPSB_VIRT)
+#define TEGRA_APB_MISC_VIRT (TEGRA_APB_MISC_BASE - IO_APB_PHYS \
+ + IO_APB_VIRT)
+#define TEGRA_PMC_VIRT (TEGRA_PMC_BASE - IO_APB_PHYS + IO_APB_VIRT)
+
+#define TEGRA_IRAM_RESET_BASE_VIRT (IO_IRAM_VIRT + \
+ TEGRA_IRAM_RESET_HANDLER_OFFSET)
+
+/* PMC_SCRATCH37-39 and 41 are used for tegra_pen_lock and idle */
+#define PMC_SCRATCH37 0x130
+#define PMC_SCRATCH38 0x134
+#define PMC_SCRATCH39 0x138
+#define PMC_SCRATCH41 0x140
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+#define CPU_RESETTABLE 2
+#define CPU_RESETTABLE_SOON 1
+#define CPU_NOT_RESETTABLE 0
+#endif
+
+/* flag of tegra_disable_clean_inv_dcache to do LoUIS or all */
+#define TEGRA_FLUSH_CACHE_LOUIS 0
+#define TEGRA_FLUSH_CACHE_ALL 1
+
+#ifdef __ASSEMBLY__
+/* waits until the microsecond counter (base) is > rn */
+.macro wait_until, rn, base, tmp
+ add \rn, \rn, #1
+1001: ldr \tmp, [\base]
+ cmp \tmp, \rn
+ bmi 1001b
+.endm
+
+/* returns the offset of the flow controller halt register for a cpu */
+.macro cpu_to_halt_reg rd, rcpu
+ cmp \rcpu, #0
+ subne \rd, \rcpu, #1
+ movne \rd, \rd, lsl #3
+ addne \rd, \rd, #0x14
+ moveq \rd, #0
+.endm
+
+/* returns the offset of the flow controller csr register for a cpu */
+.macro cpu_to_csr_reg rd, rcpu
+ cmp \rcpu, #0
+ subne \rd, \rcpu, #1
+ movne \rd, \rd, lsl #3
+ addne \rd, \rd, #0x18
+ moveq \rd, #8
+.endm
+
+/* returns the ID of the current processor */
+.macro cpu_id, rd
+ mrc p15, 0, \rd, c0, c0, 5
+ and \rd, \rd, #0xF
+.endm
+
+/* loads a 32-bit value into a register without a data access */
+.macro mov32, reg, val
+ movw \reg, #:lower16:\val
+ movt \reg, #:upper16:\val
+.endm
+
+/* Marco to check CPU part num */
+.macro check_cpu_part_num part_num, tmp1, tmp2
+ mrc p15, 0, \tmp1, c0, c0, 0
+ ubfx \tmp1, \tmp1, #4, #12
+ mov32 \tmp2, \part_num
+ cmp \tmp1, \tmp2
+.endm
+
+/* Macro to exit SMP coherency. */
+.macro exit_smp, tmp1, tmp2
+ mrc p15, 0, \tmp1, c1, c0, 1 @ ACTLR
+ bic \tmp1, \tmp1, #(1<<6) | (1<<0) @ clear ACTLR.SMP | ACTLR.FW
+ mcr p15, 0, \tmp1, c1, c0, 1 @ ACTLR
+ isb
+#ifdef CONFIG_HAVE_ARM_SCU
+ check_cpu_part_num 0xc09, \tmp1, \tmp2
+ mrceq p15, 0, \tmp1, c0, c0, 5
+ andeq \tmp1, \tmp1, #0xF
+ moveq \tmp1, \tmp1, lsl #2
+ moveq \tmp2, #0xf
+ moveq \tmp2, \tmp2, lsl \tmp1
+ ldreq \tmp1, =(TEGRA_ARM_PERIF_VIRT + 0xC)
+ streq \tmp2, [\tmp1] @ invalidate SCU tags for CPU
+ dsb
+#endif
+.endm
+
+/* Macro to check Tegra revision */
+#define APB_MISC_GP_HIDREV 0x804
+.macro tegra_get_soc_id base, tmp1
+ mov32 \tmp1, \base
+ ldr \tmp1, [\tmp1, #APB_MISC_GP_HIDREV]
+ and \tmp1, \tmp1, #0xff00
+ mov \tmp1, \tmp1, lsr #8
+.endm
+
+#else
+void tegra_pen_lock(void);
+void tegra_pen_unlock(void);
+void tegra_resume(void);
+int tegra_sleep_cpu_finish(unsigned long);
+void tegra_disable_clean_inv_dcache(u32 flag);
+
+#ifdef CONFIG_HOTPLUG_CPU
+void tegra20_hotplug_shutdown(void);
+void tegra30_hotplug_shutdown(void);
+#endif
+
+void tegra20_cpu_shutdown(int cpu);
+int tegra20_cpu_is_resettable_soon(void);
+void tegra20_cpu_clear_resettable(void);
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+void tegra20_cpu_set_resettable_soon(void);
+#else
+static inline void tegra20_cpu_set_resettable_soon(void) {}
+#endif
+
+int tegra20_sleep_cpu_secondary_finish(unsigned long);
+void tegra20_tear_down_cpu(void);
+int tegra30_sleep_cpu_secondary_finish(unsigned long);
+void tegra30_tear_down_cpu(void);
+
+#endif
+#endif
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
new file mode 100644
index 000000000..861d88486
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra.c
@@ -0,0 +1,168 @@
+/*
+ * NVIDIA Tegra SoC device tree board support
+ *
+ * Copyright (C) 2011, 2013, NVIDIA Corporation
+ * Copyright (C) 2010 Secret Lab Technologies, Ltd.
+ * 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/clk.h>
+#include <linux/clk/tegra.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/kernel.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/pda_power.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+#include <linux/usb/tegra_usb_phy.h>
+
+#include <soc/tegra/fuse.h>
+#include <soc/tegra/pmc.h>
+
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+#include <asm/trusted_foundations.h>
+
+#include "board.h"
+#include "common.h"
+#include "cpuidle.h"
+#include "flowctrl.h"
+#include "iomap.h"
+#include "irq.h"
+#include "pm.h"
+#include "reset.h"
+#include "sleep.h"
+
+/*
+ * Storage for debug-macro.S's state.
+ *
+ * This must be in .data not .bss so that it gets initialized each time the
+ * kernel is loaded. The data is declared here rather than debug-macro.S so
+ * that multiple inclusions of debug-macro.S point at the same data.
+ */
+u32 tegra_uart_config[3] = {
+ /* Debug UART initialization required */
+ 1,
+ /* Debug UART physical address */
+ 0,
+ /* Debug UART virtual address */
+ 0,
+};
+
+static void __init tegra_init_early(void)
+{
+ of_register_trusted_foundations();
+ tegra_cpu_reset_handler_init();
+ tegra_flowctrl_init();
+}
+
+static void __init tegra_dt_init_irq(void)
+{
+ tegra_init_irq();
+ irqchip_init();
+}
+
+static void __init tegra_dt_init(void)
+{
+ struct soc_device_attribute *soc_dev_attr;
+ struct soc_device *soc_dev;
+ struct device *parent = NULL;
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ goto out;
+
+ soc_dev_attr->family = kasprintf(GFP_KERNEL, "Tegra");
+ soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d",
+ tegra_sku_info.revision);
+ soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id());
+
+ soc_dev = soc_device_register(soc_dev_attr);
+ if (IS_ERR(soc_dev)) {
+ kfree(soc_dev_attr->family);
+ kfree(soc_dev_attr->revision);
+ kfree(soc_dev_attr->soc_id);
+ kfree(soc_dev_attr);
+ goto out;
+ }
+
+ parent = soc_device_to_device(soc_dev);
+
+ /*
+ * Finished with the static registrations now; fill in the missing
+ * devices
+ */
+out:
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
+}
+
+static void __init paz00_init(void)
+{
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
+ tegra_paz00_wifikill_init();
+}
+
+static struct {
+ char *machine;
+ void (*init)(void);
+} board_init_funcs[] = {
+ { "compal,paz00", paz00_init },
+};
+
+static void __init tegra_dt_init_late(void)
+{
+ int i;
+
+ tegra_init_suspend();
+ tegra_cpuidle_init();
+
+ for (i = 0; i < ARRAY_SIZE(board_init_funcs); i++) {
+ if (of_machine_is_compatible(board_init_funcs[i].machine)) {
+ board_init_funcs[i].init();
+ break;
+ }
+ }
+}
+
+static const char * const tegra_dt_board_compat[] = {
+ "nvidia,tegra124",
+ "nvidia,tegra114",
+ "nvidia,tegra30",
+ "nvidia,tegra20",
+ NULL
+};
+
+DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)")
+ .l2c_aux_val = 0x3c400001,
+ .l2c_aux_mask = 0xc20fc3fe,
+ .smp = smp_ops(tegra_smp_ops),
+ .map_io = tegra_map_common_io,
+ .init_early = tegra_init_early,
+ .init_irq = tegra_dt_init_irq,
+ .init_machine = tegra_dt_init,
+ .init_late = tegra_dt_init_late,
+ .restart = tegra_pmc_restart,
+ .dt_compat = tegra_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig
new file mode 100644
index 000000000..bc51a7139
--- /dev/null
+++ b/arch/arm/mach-u300/Kconfig
@@ -0,0 +1,44 @@
+menuconfig ARCH_U300
+ bool "ST-Ericsson U300 Series" if ARCH_MULTI_V5
+ depends on MMU
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_AMBA
+ select ARM_VIC
+ select CLKSRC_MMIO
+ select CPU_ARM926T
+ select HAVE_TCM
+ select PINCTRL
+ select PINCTRL_COH901
+ select PINCTRL_U300
+ select MFD_SYSCON
+ help
+ Support for ST-Ericsson U300 series mobile platforms.
+
+if ARCH_U300
+
+config MACH_U300
+ depends on ARCH_U300
+ bool "U300"
+ default y
+
+config U300_DEBUG
+ depends on ARCH_U300
+ bool "Debug support for U300"
+ depends on PM
+ help
+ Debug support for U300 in sysfs, procfs etc.
+
+config MACH_U300_SPIDUMMY
+ depends on ARCH_U300
+ 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.
+
+endif
diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile
new file mode 100644
index 000000000..87d37de05
--- /dev/null
+++ b/arch/arm/mach-u300/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux kernel, U300 machine.
+#
+
+obj-y := core.o
+
+obj-$(CONFIG_MACH_U300_SPIDUMMY) += dummyspichip.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 000000000..87811de0b
--- /dev/null
+++ b/arch/arm/mach-u300/Makefile.boot
@@ -0,0 +1,4 @@
+ zreladdr-y += 0x48008000
+params_phys-y := 0x48000100
+# This isn't used.
+#initrd_phys-y := 0x48800000
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
new file mode 100644
index 000000000..35670b15f
--- /dev/null
+++ b/arch/arm/mach-u300/core.c
@@ -0,0 +1,415 @@
+/*
+ *
+ * arch/arm/mach-u300/core.c
+ *
+ *
+ * Copyright (C) 2007-2012 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/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/platform_data/clk-u300.h>
+#include <linux/irqchip.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/clocksource.h>
+#include <linux/clk.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+
+/*
+ * These are the large blocks of memory allocated for I/O.
+ * the defines are used for setting up the I/O memory mapping.
+ */
+
+/* NAND Flash CS0 */
+#define U300_NAND_CS0_PHYS_BASE 0x80000000
+/* NFIF */
+#define U300_NAND_IF_PHYS_BASE 0x9f800000
+/* ALE, CLE offset for FSMC NAND */
+#define PLAT_NAND_CLE (1 << 16)
+#define PLAT_NAND_ALE (1 << 17)
+/* 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 */
+#define U300_SEMI_CONFIG_BASE 0x2FFE0000
+
+/*
+ * 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)
+/* Fast UART1 on U335 only */
+#define U300_UART1_BASE (U300_FAST_PER_PHYS_BASE+0x7000)
+
+/*
+ * 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) */
+#define U300_ISP_BASE (0xA0008000)
+/* 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 */
+#define U300_VIDEOENC_BASE (0xc0080000)
+/* XGAM Base */
+#define U300_XGAM_BASE (0xd0000000)
+
+/*
+ * SYSCON addresses applicable to the core machine.
+ */
+
+/* Chip ID register 16bit (R/-) */
+#define U300_SYSCON_CIDR (0x400)
+/* 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)
+
+static void __iomem *syscon_base;
+
+/*
+ * 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,
+ },
+};
+
+static void __init u300_map_io(void)
+{
+ iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc));
+}
+
+static unsigned long pin_pullup_conf[] = {
+ PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 1),
+};
+
+static unsigned long pin_highz_conf[] = {
+ PIN_CONF_PACKED(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0),
+};
+
+/* Pin control settings */
+static struct pinctrl_map __initdata u300_pinmux_map[] = {
+ /* anonymous maps for chip power and EMIFs */
+ PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "power"),
+ PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif0"),
+ PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif1"),
+ /* per-device maps for MMC/SD, SPI and UART */
+ PIN_MAP_MUX_GROUP_DEFAULT("mmci", "pinctrl-u300", NULL, "mmc0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("pl022", "pinctrl-u300", NULL, "spi0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-u300", NULL, "uart0"),
+ /* This pin is used for clock return rather than GPIO */
+ PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO APP GPIO 11",
+ pin_pullup_conf),
+ /* This pin is used for card detect */
+ PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO MS INS",
+ pin_highz_conf),
+};
+
+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(syscon_base + 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);
+
+ if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) {
+ printk(KERN_ERR "Platform configured for BS335 " \
+ " with DB3350 but %s detected, expect problems!",
+ chipname);
+ }
+}
+
+/* Forward declare this function from the watchdog */
+void coh901327_watchdog_reset(void);
+
+static void u300_restart(enum reboot_mode mode, const char *cmd)
+{
+ switch (mode) {
+ case REBOOT_SOFT:
+ case REBOOT_HARD:
+#ifdef CONFIG_COH901327_WATCHDOG
+ coh901327_watchdog_reset();
+#endif
+ break;
+ default:
+ /* Do nothing */
+ break;
+ }
+ /* Wait for system do die/reset. */
+ while (1);
+}
+
+/* These are mostly to get the right device names for the clock lookups */
+static struct of_dev_auxdata u300_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("stericsson,pinctrl-u300", U300_SYSCON_BASE,
+ "pinctrl-u300", NULL),
+ OF_DEV_AUXDATA("stericsson,gpio-coh901", U300_GPIO_BASE,
+ "u300-gpio", NULL),
+ OF_DEV_AUXDATA("stericsson,coh901327", U300_WDOG_BASE,
+ "coh901327_wdog", NULL),
+ OF_DEV_AUXDATA("stericsson,coh901331", U300_RTC_BASE,
+ "rtc-coh901331", NULL),
+ OF_DEV_AUXDATA("stericsson,coh901318", U300_DMAC_BASE,
+ "coh901318", NULL),
+ OF_DEV_AUXDATA("stericsson,fsmc-nand", U300_NAND_IF_PHYS_BASE,
+ "fsmc-nand", NULL),
+ OF_DEV_AUXDATA("arm,primecell", U300_UART0_BASE,
+ "uart0", NULL),
+ OF_DEV_AUXDATA("arm,primecell", U300_UART1_BASE,
+ "uart1", NULL),
+ OF_DEV_AUXDATA("arm,primecell", U300_SPI_BASE,
+ "pl022", NULL),
+ OF_DEV_AUXDATA("st,ddci2c", U300_I2C0_BASE,
+ "stu300.0", NULL),
+ OF_DEV_AUXDATA("st,ddci2c", U300_I2C1_BASE,
+ "stu300.1", NULL),
+ OF_DEV_AUXDATA("arm,primecell", U300_MMCSD_BASE,
+ "mmci", NULL),
+ { /* sentinel */ },
+};
+
+static void __init u300_init_irq_dt(void)
+{
+ struct device_node *syscon;
+ struct clk *clk;
+
+ syscon = of_find_node_by_path("/syscon@c0011000");
+ if (!syscon) {
+ pr_crit("could not find syscon node\n");
+ return;
+ }
+ syscon_base = of_iomap(syscon, 0);
+ if (!syscon_base) {
+ pr_crit("could not remap syscon\n");
+ return;
+ }
+ /* initialize clocking early, we want to clock the INTCON */
+ u300_clk_init(syscon_base);
+
+ /* Bootstrap EMIF and SEMI clocks */
+ clk = clk_get_sys("pl172", NULL);
+ BUG_ON(IS_ERR(clk));
+ clk_prepare_enable(clk);
+ clk = clk_get_sys("semi", NULL);
+ BUG_ON(IS_ERR(clk));
+ clk_prepare_enable(clk);
+
+ /* Clock the interrupt controller */
+ clk = clk_get_sys("intcon", NULL);
+ BUG_ON(IS_ERR(clk));
+ clk_prepare_enable(clk);
+
+ irqchip_init();
+}
+
+static void __init u300_init_machine_dt(void)
+{
+ u16 val;
+
+ /* Check what platform we run and print some status information */
+ u300_init_check_chip();
+
+ /* Initialize pinmuxing */
+ pinctrl_register_mappings(u300_pinmux_map,
+ ARRAY_SIZE(u300_pinmux_map));
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ u300_auxdata_lookup, NULL);
+
+ /* Enable SEMI self refresh */
+ val = readw(syscon_base + U300_SYSCON_SMCR) |
+ U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE;
+ writew(val, syscon_base + U300_SYSCON_SMCR);
+}
+
+static const char * u300_board_compat[] = {
+ "stericsson,u300",
+ NULL,
+};
+
+DT_MACHINE_START(U300_DT, "U300 S335/B335 (Device Tree)")
+ .map_io = u300_map_io,
+ .init_irq = u300_init_irq_dt,
+ .init_time = clocksource_of_init,
+ .init_machine = u300_init_machine_dt,
+ .restart = u300_restart,
+ .dt_compat = u300_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-u300/dummyspichip.c b/arch/arm/mach-u300/dummyspichip.c
new file mode 100644
index 000000000..131996805
--- /dev/null
+++ b/arch/arm/mach-u300/dummyspichip.c
@@ -0,0 +1,277 @@
+/*
+ * 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_warn("Simple 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_warn("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_warn("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_warn("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_warn("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_warn("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_warn("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_warn("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_warn("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_warn("Simple test 7: FAILURE: spi_write_then_read failed with status %d\n",
+ status);
+ else
+ pr_warn("Simple 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_warn("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_warn("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_warn("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_warn("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 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 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 const struct of_device_id pl022_dummy_dt_match[] = {
+ { .compatible = "arm,pl022-dummy" },
+ {},
+};
+
+static struct spi_driver pl022_dummy_driver = {
+ .driver = {
+ .name = "spi-dummy",
+ .owner = THIS_MODULE,
+ .of_match_table = pl022_dummy_dt_match,
+ },
+ .probe = pl022_dummy_probe,
+ .remove = pl022_dummy_remove,
+};
+
+module_spi_driver(pl022_dummy_driver);
+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/regulator.c b/arch/arm/mach-u300/regulator.c
new file mode 100644
index 000000000..595b574c2
--- /dev/null
+++ b/arch/arm/mach-u300/regulator.c
@@ -0,0 +1,132 @@
+/*
+ * 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/of.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+/* 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)
+
+/*
+ * 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(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *syscon_np;
+ struct regmap *regmap;
+ int err;
+
+ pr_info("U300: setting up board power\n");
+
+ syscon_np = of_parse_phandle(np, "syscon", 0);
+ if (!syscon_np) {
+ pr_crit("U300: no syscon node\n");
+ return -ENODEV;
+ }
+ regmap = syscon_node_to_regmap(syscon_np);
+ if (IS_ERR(regmap)) {
+ pr_crit("U300: could not locate syscon regmap\n");
+ return PTR_ERR(regmap);
+ }
+
+ main_power_15 = regulator_get(&pdev->dev, "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");
+ regmap_update_bits(regmap, U300_SYSCON_PMCR,
+ U300_SYSCON_PMCR_DCON_ENABLE, 0);
+
+ /* Register globally exported PM poweroff hook */
+ pm_power_off = u300_pm_poweroff;
+
+ return 0;
+}
+
+static int __init s365_board_probe(struct platform_device *pdev)
+{
+ return __u300_init_boardpower(pdev);
+}
+
+static const struct of_device_id s365_board_match[] = {
+ { .compatible = "stericsson,s365" },
+ {},
+};
+
+static struct platform_driver s365_board_driver = {
+ .driver = {
+ .name = "s365-board",
+ .of_match_table = s365_board_match,
+ },
+};
+
+/*
+ * So at module init time we hog the regulator!
+ */
+static int __init u300_init_boardpower(void)
+{
+ return platform_driver_probe(&s365_board_driver,
+ s365_board_probe);
+}
+
+device_initcall(u300_init_boardpower);
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
new file mode 100644
index 000000000..c9ac19b24
--- /dev/null
+++ b/arch/arm/mach-ux500/Kconfig
@@ -0,0 +1,76 @@
+menuconfig ARCH_U8500
+ bool "ST-Ericsson U8500 Series" if ARCH_MULTI_V7
+ depends on MMU
+ select AB8500_CORE
+ select ABX500_CORE
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_AMBA
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_764369 if SMP
+ select ARM_GIC
+ select CACHE_L2X0
+ select CLKSRC_NOMADIK_MTU
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select PINCTRL
+ select PINCTRL_ABX500
+ select PINCTRL_NOMADIK
+ select PL310_ERRATA_753970 if CACHE_L2X0
+ help
+ Support for ST-Ericsson's Ux500 architecture
+
+if ARCH_U8500
+
+config UX500_SOC_DB8500
+ bool
+ select MFD_DB8500_PRCMU
+ select PINCTRL_DB8500
+ select PINCTRL_DB8540
+ select PINCTRL_AB8500
+ select PINCTRL_AB8505
+ select PINCTRL_AB9540
+ select PINCTRL_AB8540
+ select REGULATOR
+ select REGULATOR_DB8500_PRCMU
+ select PM_GENERIC_DOMAINS if PM
+
+config MACH_MOP500
+ bool "U8500 Development platform, MOP500 versions"
+ select I2C
+ select I2C_NOMADIK
+ select REGULATOR
+ select REGULATOR_FIXED_VOLTAGE
+ select SOC_BUS
+ select UX500_SOC_DB8500
+ help
+ Include support for the MOP500 development platform.
+
+config MACH_HREFV60
+ bool "U8500 Development platform, HREFv60 version"
+ select MACH_MOP500
+ help
+ Include support for the HREFv60 new development platform.
+ Includes HREFv70, v71 etc.
+
+config MACH_SNOWBALL
+ bool "U8500 Snowball platform"
+ select MACH_MOP500
+ help
+ Include support for the snowball development platform.
+
+config UX500_AUTO_PLATFORM
+ def_bool y
+ select MACH_MOP500
+ help
+ At least one platform needs to be selected in order to build
+ a working kernel. If everything else is disabled, this
+ automatically enables MACH_MOP500.
+
+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.
+
+endif
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
new file mode 100644
index 000000000..4418a5078
--- /dev/null
+++ b/arch/arm/mach-ux500/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for the linux kernel, U8500 machine.
+#
+
+obj-y := cpu.o id.o timer.o pm.o
+obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
+obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o
+obj-$(CONFIG_MACH_MOP500) += board-mop500-regulators.o \
+ board-mop500-audio.o
+obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
+
+CFLAGS_hotplug.o += -march=armv7-a
diff --git a/arch/arm/mach-ux500/Makefile.boot b/arch/arm/mach-ux500/Makefile.boot
new file mode 100644
index 000000000..760a0efe7
--- /dev/null
+++ b/arch/arm/mach-ux500/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y += 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
diff --git a/arch/arm/mach-ux500/board-mop500-audio.c b/arch/arm/mach-ux500/board-mop500-audio.c
new file mode 100644
index 000000000..b2a0899e7
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-audio.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_data/dma-ste-dma40.h>
+
+#include <linux/platform_data/asoc-ux500-msp.h>
+
+#include "ste-dma40-db8500.h"
+#include "board-mop500.h"
+
+static struct stedma40_chan_cfg msp0_dma_rx = {
+ .high_priority = true,
+ .dir = DMA_DEV_TO_MEM,
+ .dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0,
+};
+
+static struct stedma40_chan_cfg msp0_dma_tx = {
+ .high_priority = true,
+ .dir = DMA_MEM_TO_DEV,
+ .dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0,
+};
+
+struct msp_i2s_platform_data msp0_platform_data = {
+ .id = 0,
+ .msp_i2s_dma_rx = &msp0_dma_rx,
+ .msp_i2s_dma_tx = &msp0_dma_tx,
+};
+
+static struct stedma40_chan_cfg msp1_dma_rx = {
+ .high_priority = true,
+ .dir = DMA_DEV_TO_MEM,
+ .dev_type = DB8500_DMA_DEV30_MSP3,
+};
+
+static struct stedma40_chan_cfg msp1_dma_tx = {
+ .high_priority = true,
+ .dir = DMA_MEM_TO_DEV,
+ .dev_type = DB8500_DMA_DEV30_MSP1,
+};
+
+struct msp_i2s_platform_data msp1_platform_data = {
+ .id = 1,
+ .msp_i2s_dma_rx = NULL,
+ .msp_i2s_dma_tx = &msp1_dma_tx,
+};
+
+static struct stedma40_chan_cfg msp2_dma_rx = {
+ .high_priority = true,
+ .dir = DMA_DEV_TO_MEM,
+ .dev_type = DB8500_DMA_DEV14_MSP2,
+};
+
+static struct stedma40_chan_cfg msp2_dma_tx = {
+ .high_priority = true,
+ .dir = DMA_MEM_TO_DEV,
+ .dev_type = DB8500_DMA_DEV14_MSP2,
+ .use_fixed_channel = true,
+ .phy_channel = 1,
+};
+
+struct msp_i2s_platform_data msp2_platform_data = {
+ .id = 2,
+ .msp_i2s_dma_rx = &msp2_dma_rx,
+ .msp_i2s_dma_tx = &msp2_dma_tx,
+};
+
+struct msp_i2s_platform_data msp3_platform_data = {
+ .id = 3,
+ .msp_i2s_dma_rx = &msp1_dma_rx,
+ .msp_i2s_dma_tx = NULL,
+};
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 000000000..32d744e91
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-regulators.c
@@ -0,0 +1,1065 @@
+/*
+ * 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>
+ * Daniel Willerud <daniel.willerud@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"
+#include "id.h"
+
+static struct regulator_consumer_supply gpio_en_3v3_consumers[] = {
+ REGULATOR_SUPPLY("vdd33a", "smsc911x.0"),
+};
+
+struct regulator_init_data gpio_en_3v3_regulator = {
+ .constraints = {
+ .name = "EN-3V3",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(gpio_en_3v3_consumers),
+ .consumer_supplies = gpio_en_3v3_consumers,
+};
+
+/*
+ * 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[] = {
+ /* Main display, u8500 R3 uib */
+ REGULATOR_SUPPLY("vddi", "mcde_disp_sony_acx424akp.0"),
+ /* Main display, u8500 uib and ST uib */
+ REGULATOR_SUPPLY("vdd1", "samsung_s6d16d0.0"),
+ /* Secondary display, ST uib */
+ REGULATOR_SUPPLY("vdd1", "samsung_s6d16d0.1"),
+ /* SFH7741 proximity sensor */
+ REGULATOR_SUPPLY("vcc", "gpio-keys.0"),
+ /* BH1780GLS ambient light sensor */
+ REGULATOR_SUPPLY("vcc", "2-0029"),
+ /* lsm303dlh accelerometer */
+ REGULATOR_SUPPLY("vdd", "2-0018"),
+ /* lsm303dlhc accelerometer */
+ REGULATOR_SUPPLY("vdd", "2-0019"),
+ /* lsm303dlh magnetometer */
+ REGULATOR_SUPPLY("vdd", "2-001e"),
+ /* Rohm BU21013 Touchscreen devices */
+ REGULATOR_SUPPLY("avdd", "3-005c"),
+ REGULATOR_SUPPLY("avdd", "3-005d"),
+ /* Synaptics RMI4 Touchscreen device */
+ REGULATOR_SUPPLY("vdd", "3-004b"),
+ /* L3G4200D Gyroscope device */
+ REGULATOR_SUPPLY("vdd", "2-0068"),
+ /* Ambient light sensor device */
+ REGULATOR_SUPPLY("vdd", "3-0029"),
+ /* Pressure sensor device */
+ REGULATOR_SUPPLY("vdd", "2-005c"),
+ /* Cypress TrueTouch Touchscreen device */
+ REGULATOR_SUPPLY("vcpin", "spi8.0"),
+ /* Camera device */
+ REGULATOR_SUPPLY("vaux12v5", "mmio_camera"),
+};
+
+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"),
+ /* AB8500 accessory detect 1 */
+ REGULATOR_SUPPLY("vcc-N2158", "ab8500-acc-det.0"),
+ /* AB8500 Tv-out device */
+ REGULATOR_SUPPLY("vcc-N2158", "mcde_tv_ab8500.4"),
+ /* AV8100 HDMI device */
+ REGULATOR_SUPPLY("vcc-N2158", "av8100_hdmi.3"),
+};
+
+static struct regulator_consumer_supply ab8500_vaux3_consumers[] = {
+ REGULATOR_SUPPLY("v-SD-STM", "stm"),
+ /* External MMC slot power */
+ REGULATOR_SUPPLY("vmmc", "sdi0"),
+};
+
+static struct regulator_consumer_supply ab8505_vaux4_consumers[] = {
+};
+
+static struct regulator_consumer_supply ab8505_vaux5_consumers[] = {
+};
+
+static struct regulator_consumer_supply ab8505_vaux6_consumers[] = {
+};
+
+static struct regulator_consumer_supply ab8505_vaux8_consumers[] = {
+ /* AB8500 audio codec device */
+ REGULATOR_SUPPLY("v-aux8", NULL),
+};
+
+static struct regulator_consumer_supply ab8505_vadc_consumers[] = {
+ /* Internal general-purpose ADC */
+ REGULATOR_SUPPLY("vddadc", "ab8500-gpadc.0"),
+ /* ADC for charger */
+ REGULATOR_SUPPLY("vddadc", "ab8500-charger.0"),
+};
+
+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"),
+ /* ADC for charger */
+ REGULATOR_SUPPLY("vddadc", "ab8500-charger.0"),
+ /* AB8500 Tv-out device */
+ REGULATOR_SUPPLY("vtvout", "mcde_tv_ab8500.4"),
+};
+
+static struct regulator_consumer_supply ab8500_vaud_consumers[] = {
+ /* AB8500 audio-codec main supply */
+ REGULATOR_SUPPLY("vaud", "ab8500-codec.0"),
+};
+
+static struct regulator_consumer_supply ab8500_vamic1_consumers[] = {
+ /* AB8500 audio-codec Mic1 supply */
+ REGULATOR_SUPPLY("vamic1", "ab8500-codec.0"),
+};
+
+static struct regulator_consumer_supply ab8500_vamic2_consumers[] = {
+ /* AB8500 audio-codec Mic2 supply */
+ REGULATOR_SUPPLY("vamic2", "ab8500-codec.0"),
+};
+
+static struct regulator_consumer_supply ab8500_vdmic_consumers[] = {
+ /* AB8500 audio-codec DMic supply */
+ REGULATOR_SUPPLY("vdmic", "ab8500-codec.0"),
+};
+
+static struct regulator_consumer_supply ab8500_vintcore_consumers[] = {
+ /* SoC core supply, no device */
+ REGULATOR_SUPPLY("v-intcore", NULL),
+ /* USB Transceiver */
+ REGULATOR_SUPPLY("vddulpivio18", "ab8500-usb.0"),
+ /* Handled by abx500 clk driver */
+ REGULATOR_SUPPLY("v-intcore", "abx500-clk.0"),
+};
+
+static struct regulator_consumer_supply ab8505_usb_consumers[] = {
+ /* HS USB OTG physical interface */
+ REGULATOR_SUPPLY("v-ape", NULL),
+};
+
+static struct regulator_consumer_supply ab8500_vana_consumers[] = {
+ /* DB8500 DSI */
+ REGULATOR_SUPPLY("vdddsi1v2", "mcde"),
+ REGULATOR_SUPPLY("vdddsi1v2", "b2r2_core"),
+ REGULATOR_SUPPLY("vdddsi1v2", "b2r2_1_core"),
+ REGULATOR_SUPPLY("vdddsi1v2", "dsilink.0"),
+ REGULATOR_SUPPLY("vdddsi1v2", "dsilink.1"),
+ REGULATOR_SUPPLY("vdddsi1v2", "dsilink.2"),
+ /* DB8500 CSI */
+ REGULATOR_SUPPLY("vddcsi1v2", "mmio_camera"),
+};
+
+/* ab8500 regulator register initialization */
+static struct ab8500_regulator_reg_init ab8500_reg_init[] = {
+ /*
+ * VanaRequestCtrl = HP/LP depending on VxRequest
+ * VextSupply1RequestCtrl = HP/LP depending on VxRequest
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL2, 0xf0, 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, 0xff, 0x00),
+ /*
+ * Vaux3RequestCtrl = HP/LP depending on VxRequest
+ * SwHPReq = Control through SWValid disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL4, 0x07, 0x00),
+ /*
+ * VanaSysClkReq1HPValid = disabled
+ * Vaux1SysClkReq1HPValid = disabled
+ * Vaux2SysClkReq1HPValid = disabled
+ * Vaux3SysClkReq1HPValid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID1, 0xe8, 0x00),
+ /*
+ * VextSupply1SysClkReq1HPValid = disabled
+ * VextSupply2SysClkReq1HPValid = disabled
+ * VextSupply3SysClkReq1HPValid = SysClkReq1 controlled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID2, 0x70, 0x40),
+ /*
+ * VanaHwHPReq1Valid = disabled
+ * Vaux1HwHPreq1Valid = disabled
+ * Vaux2HwHPReq1Valid = disabled
+ * Vaux3HwHPReqValid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID1, 0xe8, 0x00),
+ /*
+ * VextSupply1HwHPReq1Valid = disabled
+ * VextSupply2HwHPReq1Valid = disabled
+ * VextSupply3HwHPReq1Valid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID2, 0x07, 0x00),
+ /*
+ * VanaHwHPReq2Valid = disabled
+ * Vaux1HwHPReq2Valid = disabled
+ * Vaux2HwHPReq2Valid = disabled
+ * Vaux3HwHPReq2Valid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID1, 0xe8, 0x00),
+ /*
+ * VextSupply1HwHPReq2Valid = disabled
+ * VextSupply2HwHPReq2Valid = disabled
+ * VextSupply3HwHPReq2Valid = HWReq2 controlled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID2, 0x07, 0x04),
+ /*
+ * VanaSwHPReqValid = disabled
+ * Vaux1SwHPReqValid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID1, 0xa0, 0x00),
+ /*
+ * Vaux2SwHPReqValid = disabled
+ * Vaux3SwHPReqValid = disabled
+ * VextSupply1SwHPReqValid = disabled
+ * VextSupply2SwHPReqValid = disabled
+ * VextSupply3SwHPReqValid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID2, 0x1f, 0x00),
+ /*
+ * SysClkReq2Valid1 = SysClkReq2 controlled
+ * SysClkReq3Valid1 = disabled
+ * SysClkReq4Valid1 = SysClkReq4 controlled
+ * SysClkReq5Valid1 = disabled
+ * SysClkReq6Valid1 = SysClkReq6 controlled
+ * SysClkReq7Valid1 = disabled
+ * SysClkReq8Valid1 = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID1, 0xfe, 0x2a),
+ /*
+ * SysClkReq2Valid2 = disabled
+ * SysClkReq3Valid2 = disabled
+ * SysClkReq4Valid2 = disabled
+ * SysClkReq5Valid2 = disabled
+ * SysClkReq6Valid2 = SysClkReq6 controlled
+ * SysClkReq7Valid2 = disabled
+ * SysClkReq8Valid2 = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID2, 0xfe, 0x20),
+ /*
+ * VTVoutEna = disabled
+ * Vintcore12Ena = disabled
+ * Vintcore12Sel = 1.25 V
+ * Vintcore12LP = inactive (HP)
+ * VTVoutLP = inactive (HP)
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUMISC1, 0xfe, 0x10),
+ /*
+ * VaudioEna = disabled
+ * VdmicEna = disabled
+ * Vamic1Ena = disabled
+ * Vamic2Ena = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VAUDIOSUPPLY, 0x1e, 0x00),
+ /*
+ * Vamic1_dzout = high-Z when Vamic1 is disabled
+ * Vamic2_dzout = high-Z when Vamic2 is disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUCTRL1VAMIC, 0x03, 0x00),
+ /*
+ * VPll = Hw controlled (NOTE! PRCMU bits)
+ * VanaRegu = force off
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VPLLVANAREGU, 0x0f, 0x02),
+ /*
+ * VrefDDREna = disabled
+ * VrefDDRSleepMode = inactive (no pulldown)
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VREFDDR, 0x03, 0x00),
+ /*
+ * VextSupply1Regu = force LP
+ * VextSupply2Regu = force OFF
+ * VextSupply3Regu = force HP (-> STBB2=LP and TPS=LP)
+ * ExtSupply2Bypass = ExtSupply12LPn ball is 0 when Ena is 0
+ * ExtSupply3Bypass = ExtSupply3LPn ball is 0 when Ena is 0
+ */
+ INIT_REGULATOR_REGISTER(AB8500_EXTSUPPLYREGU, 0xff, 0x13),
+ /*
+ * Vaux1Regu = force HP
+ * Vaux2Regu = force off
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VAUX12REGU, 0x0f, 0x01),
+ /*
+ * Vaux3Regu = force off
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3REGU, 0x03, 0x00),
+ /*
+ * Vaux1Sel = 2.8 V
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VAUX1SEL, 0x0f, 0x0C),
+ /*
+ * Vaux2Sel = 2.9 V
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VAUX2SEL, 0x0f, 0x0d),
+ /*
+ * Vaux3Sel = 2.91 V
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3SEL, 0x07, 0x07),
+ /*
+ * VextSupply12LP = disabled (no LP)
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUCTRL2SPARE, 0x01, 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, 0xfc, 0x00),
+ /*
+ * VanaDisch = short discharge time
+ * VdmicPullDownEna = pulldown disabled when Vdmic is disabled
+ * VdmicDisch = short discharge time
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH2, 0x16, 0x00),
+};
+
+/* AB8500 regulators */
+static struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = {
+ /* supplies to the display/camera */
+ [AB8500_LDO_AUX1] = {
+ .supply_regulator = "ab8500-ext-supply3",
+ .constraints = {
+ .name = "V-DISPLAY",
+ .min_uV = 2800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1, /* display is on at boot */
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux1_consumers),
+ .consumer_supplies = ab8500_vaux1_consumers,
+ },
+ /* supplies to the on-board eMMC */
+ [AB8500_LDO_AUX2] = {
+ .supply_regulator = "ab8500-ext-supply3",
+ .constraints = {
+ .name = "V-eMMC1",
+ .min_uV = 1100000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_MODE,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_IDLE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux2_consumers),
+ .consumer_supplies = ab8500_vaux2_consumers,
+ },
+ /* supply for VAUX3, supplies to SDcard slots */
+ [AB8500_LDO_AUX3] = {
+ .supply_regulator = "ab8500-ext-supply3",
+ .constraints = {
+ .name = "V-MMC-SD",
+ .min_uV = 1100000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_MODE,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_IDLE,
+ },
+ .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,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vaud_consumers),
+ .consumer_supplies = ab8500_vaud_consumers,
+ },
+ /* supply for v-anamic1 VAMic1-LDO */
+ [AB8500_LDO_ANAMIC1] = {
+ .constraints = {
+ .name = "V-AMIC1",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vamic1_consumers),
+ .consumer_supplies = ab8500_vamic1_consumers,
+ },
+ /* supply for v-amic2, VAMIC2 LDO, reuse constants for AMIC1 */
+ [AB8500_LDO_ANAMIC2] = {
+ .constraints = {
+ .name = "V-AMIC2",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vamic2_consumers),
+ .consumer_supplies = ab8500_vamic2_consumers,
+ },
+ /* supply for v-dmic, VDMIC LDO */
+ [AB8500_LDO_DMIC] = {
+ .constraints = {
+ .name = "V-DMIC",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vdmic_consumers),
+ .consumer_supplies = ab8500_vdmic_consumers,
+ },
+ /* supply for v-intcore12, VINTCORE12 LDO */
+ [AB8500_LDO_INTCORE] = {
+ .constraints = {
+ .name = "V-INTCORE",
+ .min_uV = 1250000,
+ .max_uV = 1350000,
+ .input_uV = 1800000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_MODE |
+ REGULATOR_CHANGE_DRMS,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_IDLE,
+ },
+ .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,
+ },
+};
+
+/* supply for VextSupply3 */
+static struct regulator_consumer_supply ab8500_ext_supply3_consumers[] = {
+ /* SIM supply for 3 V SIM cards */
+ REGULATOR_SUPPLY("vinvsim", "sim-detect.0"),
+};
+
+/* extended configuration for VextSupply2, only used for HREFP_V20 boards */
+static struct ab8500_ext_regulator_cfg ab8500_ext_supply2 = {
+ .hwreq = true,
+};
+
+/*
+ * AB8500 external regulators
+ */
+static struct regulator_init_data ab8500_ext_regulators[] = {
+ /* fixed Vbat supplies VSMPS1_EXT_1V8 */
+ [AB8500_EXT_SUPPLY1] = {
+ .constraints = {
+ .name = "ab8500-ext-supply1",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .initial_mode = REGULATOR_MODE_IDLE,
+ .boot_on = 1,
+ .always_on = 1,
+ },
+ },
+ /* fixed Vbat supplies VSMPS2_EXT_1V36 and VSMPS5_EXT_1V15 */
+ [AB8500_EXT_SUPPLY2] = {
+ .constraints = {
+ .name = "ab8500-ext-supply2",
+ .min_uV = 1360000,
+ .max_uV = 1360000,
+ },
+ },
+ /* fixed Vbat supplies VSMPS3_EXT_3V4 and VSMPS4_EXT_3V4 */
+ [AB8500_EXT_SUPPLY3] = {
+ .constraints = {
+ .name = "ab8500-ext-supply3",
+ .min_uV = 3400000,
+ .max_uV = 3400000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies =
+ ARRAY_SIZE(ab8500_ext_supply3_consumers),
+ .consumer_supplies = ab8500_ext_supply3_consumers,
+ },
+};
+
+/* ab8505 regulator register initialization */
+static struct ab8500_regulator_reg_init ab8505_reg_init[] = {
+ /*
+ * VarmRequestCtrl
+ * VsmpsCRequestCtrl
+ * VsmpsARequestCtrl
+ * VsmpsBRequestCtrl
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUREQUESTCTRL1, 0x00, 0x00),
+ /*
+ * VsafeRequestCtrl
+ * VpllRequestCtrl
+ * VanaRequestCtrl = HP/LP depending on VxRequest
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUREQUESTCTRL2, 0x30, 0x00),
+ /*
+ * Vaux1RequestCtrl = HP/LP depending on VxRequest
+ * Vaux2RequestCtrl = HP/LP depending on VxRequest
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUREQUESTCTRL3, 0xf0, 0x00),
+ /*
+ * Vaux3RequestCtrl = HP/LP depending on VxRequest
+ * SwHPReq = Control through SWValid disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUREQUESTCTRL4, 0x07, 0x00),
+ /*
+ * VsmpsASysClkReq1HPValid
+ * VsmpsBSysClkReq1HPValid
+ * VsafeSysClkReq1HPValid
+ * VanaSysClkReq1HPValid = disabled
+ * VpllSysClkReq1HPValid
+ * Vaux1SysClkReq1HPValid = disabled
+ * Vaux2SysClkReq1HPValid = disabled
+ * Vaux3SysClkReq1HPValid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUSYSCLKREQ1HPVALID1, 0xe8, 0x00),
+ /*
+ * VsmpsCSysClkReq1HPValid
+ * VarmSysClkReq1HPValid
+ * VbbSysClkReq1HPValid
+ * VsmpsMSysClkReq1HPValid
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUSYSCLKREQ1HPVALID2, 0x00, 0x00),
+ /*
+ * VsmpsAHwHPReq1Valid
+ * VsmpsBHwHPReq1Valid
+ * VsafeHwHPReq1Valid
+ * VanaHwHPReq1Valid = disabled
+ * VpllHwHPReq1Valid
+ * Vaux1HwHPreq1Valid = disabled
+ * Vaux2HwHPReq1Valid = disabled
+ * Vaux3HwHPReqValid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUHWHPREQ1VALID1, 0xe8, 0x00),
+ /*
+ * VsmpsMHwHPReq1Valid
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUHWHPREQ1VALID2, 0x00, 0x00),
+ /*
+ * VsmpsAHwHPReq2Valid
+ * VsmpsBHwHPReq2Valid
+ * VsafeHwHPReq2Valid
+ * VanaHwHPReq2Valid = disabled
+ * VpllHwHPReq2Valid
+ * Vaux1HwHPReq2Valid = disabled
+ * Vaux2HwHPReq2Valid = disabled
+ * Vaux3HwHPReq2Valid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUHWHPREQ2VALID1, 0xe8, 0x00),
+ /*
+ * VsmpsMHwHPReq2Valid
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUHWHPREQ2VALID2, 0x00, 0x00),
+ /**
+ * VsmpsCSwHPReqValid
+ * VarmSwHPReqValid
+ * VsmpsASwHPReqValid
+ * VsmpsBSwHPReqValid
+ * VsafeSwHPReqValid
+ * VanaSwHPReqValid
+ * VanaSwHPReqValid = disabled
+ * VpllSwHPReqValid
+ * Vaux1SwHPReqValid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUSWHPREQVALID1, 0xa0, 0x00),
+ /*
+ * Vaux2SwHPReqValid = disabled
+ * Vaux3SwHPReqValid = disabled
+ * VsmpsMSwHPReqValid
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUSWHPREQVALID2, 0x03, 0x00),
+ /*
+ * SysClkReq2Valid1 = SysClkReq2 controlled
+ * SysClkReq3Valid1 = disabled
+ * SysClkReq4Valid1 = SysClkReq4 controlled
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUSYSCLKREQVALID1, 0x0e, 0x0a),
+ /*
+ * SysClkReq2Valid2 = disabled
+ * SysClkReq3Valid2 = disabled
+ * SysClkReq4Valid2 = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUSYSCLKREQVALID2, 0x0e, 0x00),
+ /*
+ * Vaux4SwHPReqValid
+ * Vaux4HwHPReq2Valid
+ * Vaux4HwHPReq1Valid
+ * Vaux4SysClkReq1HPValid
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUVAUX4REQVALID, 0x00, 0x00),
+ /*
+ * VadcEna = disabled
+ * VintCore12Ena = disabled
+ * VintCore12Sel = 1.25 V
+ * VintCore12LP = inactive (HP)
+ * VadcLP = inactive (HP)
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUMISC1, 0xfe, 0x10),
+ /*
+ * VaudioEna = disabled
+ * Vaux8Ena = disabled
+ * Vamic1Ena = disabled
+ * Vamic2Ena = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VAUDIOSUPPLY, 0x1e, 0x00),
+ /*
+ * Vamic1_dzout = high-Z when Vamic1 is disabled
+ * Vamic2_dzout = high-Z when Vamic2 is disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUCTRL1VAMIC, 0x03, 0x00),
+ /*
+ * VsmpsARegu
+ * VsmpsASelCtrl
+ * VsmpsAAutoMode
+ * VsmpsAPWMMode
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VSMPSAREGU, 0x00, 0x00),
+ /*
+ * VsmpsBRegu
+ * VsmpsBSelCtrl
+ * VsmpsBAutoMode
+ * VsmpsBPWMMode
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VSMPSBREGU, 0x00, 0x00),
+ /*
+ * VsafeRegu
+ * VsafeSelCtrl
+ * VsafeAutoMode
+ * VsafePWMMode
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VSAFEREGU, 0x00, 0x00),
+ /*
+ * VPll = Hw controlled (NOTE! PRCMU bits)
+ * VanaRegu = force off
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VPLLVANAREGU, 0x0f, 0x02),
+ /*
+ * VextSupply1Regu = force OFF (OTP_ExtSupply12LPnPolarity 1)
+ * VextSupply2Regu = force OFF (OTP_ExtSupply12LPnPolarity 1)
+ * VextSupply3Regu = force OFF (OTP_ExtSupply3LPnPolarity 0)
+ * ExtSupply2Bypass = ExtSupply12LPn ball is 0 when Ena is 0
+ * ExtSupply3Bypass = ExtSupply3LPn ball is 0 when Ena is 0
+ */
+ INIT_REGULATOR_REGISTER(AB8505_EXTSUPPLYREGU, 0xff, 0x30),
+ /*
+ * Vaux1Regu = force HP
+ * Vaux2Regu = force off
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VAUX12REGU, 0x0f, 0x01),
+ /*
+ * Vaux3Regu = force off
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VRF1VAUX3REGU, 0x03, 0x00),
+ /*
+ * VsmpsASel1
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VSMPSASEL1, 0x00, 0x00),
+ /*
+ * VsmpsASel2
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VSMPSASEL2, 0x00, 0x00),
+ /*
+ * VsmpsASel3
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VSMPSASEL3, 0x00, 0x00),
+ /*
+ * VsmpsBSel1
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VSMPSBSEL1, 0x00, 0x00),
+ /*
+ * VsmpsBSel2
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VSMPSBSEL2, 0x00, 0x00),
+ /*
+ * VsmpsBSel3
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VSMPSBSEL3, 0x00, 0x00),
+ /*
+ * VsafeSel1
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VSAFESEL1, 0x00, 0x00),
+ /*
+ * VsafeSel2
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VSAFESEL2, 0x00, 0x00),
+ /*
+ * VsafeSel3
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VSAFESEL3, 0x00, 0x00),
+ /*
+ * Vaux1Sel = 2.8 V
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VAUX1SEL, 0x0f, 0x0C),
+ /*
+ * Vaux2Sel = 2.9 V
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VAUX2SEL, 0x0f, 0x0d),
+ /*
+ * Vaux3Sel = 2.91 V
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VRF1VAUX3SEL, 0x07, 0x07),
+ /*
+ * Vaux4RequestCtrl
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VAUX4REQCTRL, 0x00, 0x00),
+ /*
+ * Vaux4Regu
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VAUX4REGU, 0x00, 0x00),
+ /*
+ * Vaux4Sel
+ */
+ INIT_REGULATOR_REGISTER(AB8505_VAUX4SEL, 0x00, 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(AB8505_REGUCTRLDISCH, 0xfc, 0x00),
+ /*
+ * VanaDisch = short discharge time
+ * Vaux8PullDownEna = pulldown disabled when Vaux8 is disabled
+ * Vaux8Disch = short discharge time
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUCTRLDISCH2, 0x16, 0x00),
+ /*
+ * Vaux4Disch = short discharge time
+ */
+ INIT_REGULATOR_REGISTER(AB8505_REGUCTRLDISCH3, 0x01, 0x00),
+ /*
+ * Vaux5Sel
+ * Vaux5LP
+ * Vaux5Ena
+ * Vaux5Disch
+ * Vaux5DisSfst
+ * Vaux5DisPulld
+ */
+ INIT_REGULATOR_REGISTER(AB8505_CTRLVAUX5, 0x00, 0x00),
+ /*
+ * Vaux6Sel
+ * Vaux6LP
+ * Vaux6Ena
+ * Vaux6DisPulld
+ */
+ INIT_REGULATOR_REGISTER(AB8505_CTRLVAUX6, 0x00, 0x00),
+};
+
+static struct regulator_init_data ab8505_regulators[AB8505_NUM_REGULATORS] = {
+ /* supplies to the display/camera */
+ [AB8505_LDO_AUX1] = {
+ .constraints = {
+ .name = "V-DISPLAY",
+ .min_uV = 2800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1, /* display is on at boot */
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux1_consumers),
+ .consumer_supplies = ab8500_vaux1_consumers,
+ },
+ /* supplies to the on-board eMMC */
+ [AB8505_LDO_AUX2] = {
+ .constraints = {
+ .name = "V-eMMC1",
+ .min_uV = 1100000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_MODE,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_IDLE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux2_consumers),
+ .consumer_supplies = ab8500_vaux2_consumers,
+ },
+ /* supply for VAUX3, supplies to SDcard slots */
+ [AB8505_LDO_AUX3] = {
+ .constraints = {
+ .name = "V-MMC-SD",
+ .min_uV = 1100000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_MODE,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_IDLE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux3_consumers),
+ .consumer_supplies = ab8500_vaux3_consumers,
+ },
+ /* supply for VAUX4, supplies to NFC and standalone secure element */
+ [AB8505_LDO_AUX4] = {
+ .constraints = {
+ .name = "V-NFC-SE",
+ .min_uV = 1100000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_MODE,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_IDLE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8505_vaux4_consumers),
+ .consumer_supplies = ab8505_vaux4_consumers,
+ },
+ /* supply for VAUX5, supplies to TBD */
+ [AB8505_LDO_AUX5] = {
+ .constraints = {
+ .name = "V-AUX5",
+ .min_uV = 1050000,
+ .max_uV = 2790000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_MODE,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_IDLE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8505_vaux5_consumers),
+ .consumer_supplies = ab8505_vaux5_consumers,
+ },
+ /* supply for VAUX6, supplies to TBD */
+ [AB8505_LDO_AUX6] = {
+ .constraints = {
+ .name = "V-AUX6",
+ .min_uV = 1050000,
+ .max_uV = 2790000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_MODE,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_IDLE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8505_vaux6_consumers),
+ .consumer_supplies = ab8505_vaux6_consumers,
+ },
+ /* supply for gpadc, ADC LDO */
+ [AB8505_LDO_ADC] = {
+ .constraints = {
+ .name = "V-ADC",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8505_vadc_consumers),
+ .consumer_supplies = ab8505_vadc_consumers,
+ },
+ /* supply for ab8500-vaudio, VAUDIO LDO */
+ [AB8505_LDO_AUDIO] = {
+ .constraints = {
+ .name = "V-AUD",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vaud_consumers),
+ .consumer_supplies = ab8500_vaud_consumers,
+ },
+ /* supply for v-anamic1 VAMic1-LDO */
+ [AB8505_LDO_ANAMIC1] = {
+ .constraints = {
+ .name = "V-AMIC1",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_MODE,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_IDLE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vamic1_consumers),
+ .consumer_supplies = ab8500_vamic1_consumers,
+ },
+ /* supply for v-amic2, VAMIC2 LDO, reuse constants for AMIC1 */
+ [AB8505_LDO_ANAMIC2] = {
+ .constraints = {
+ .name = "V-AMIC2",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_MODE,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_IDLE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vamic2_consumers),
+ .consumer_supplies = ab8500_vamic2_consumers,
+ },
+ /* supply for v-aux8, VAUX8 LDO */
+ [AB8505_LDO_AUX8] = {
+ .constraints = {
+ .name = "V-AUX8",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8505_vaux8_consumers),
+ .consumer_supplies = ab8505_vaux8_consumers,
+ },
+ /* supply for v-intcore12, VINTCORE12 LDO */
+ [AB8505_LDO_INTCORE] = {
+ .constraints = {
+ .name = "V-INTCORE",
+ .min_uV = 1250000,
+ .max_uV = 1350000,
+ .input_uV = 1800000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_MODE |
+ REGULATOR_CHANGE_DRMS,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_IDLE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vintcore_consumers),
+ .consumer_supplies = ab8500_vintcore_consumers,
+ },
+ /* supply for LDO USB */
+ [AB8505_LDO_USB] = {
+ .constraints = {
+ .name = "V-USB",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_MODE,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_IDLE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8505_usb_consumers),
+ .consumer_supplies = ab8505_usb_consumers,
+ },
+ /* supply for U8500 CSI-DSI, VANA LDO */
+ [AB8505_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,
+ },
+};
+
+struct ab8500_regulator_platform_data ab8500_regulator_plat_data = {
+ .reg_init = ab8500_reg_init,
+ .num_reg_init = ARRAY_SIZE(ab8500_reg_init),
+ .regulator = ab8500_regulators,
+ .num_regulator = ARRAY_SIZE(ab8500_regulators),
+ .ext_regulator = ab8500_ext_regulators,
+ .num_ext_regulator = ARRAY_SIZE(ab8500_ext_regulators),
+};
+
+struct ab8500_regulator_platform_data ab8505_regulator_plat_data = {
+ .reg_init = ab8505_reg_init,
+ .num_reg_init = ARRAY_SIZE(ab8505_reg_init),
+ .regulator = ab8505_regulators,
+ .num_regulator = ARRAY_SIZE(ab8505_regulators),
+};
+
+static void ab8500_modify_reg_init(int id, u8 mask, u8 value)
+{
+ int i;
+
+ if (cpu_is_u8520()) {
+ for (i = ARRAY_SIZE(ab8505_reg_init) - 1; i >= 0; i--) {
+ if (ab8505_reg_init[i].id == id) {
+ u8 initval = ab8505_reg_init[i].value;
+ initval = (initval & ~mask) | (value & mask);
+ ab8505_reg_init[i].value = initval;
+
+ BUG_ON(mask & ~ab8505_reg_init[i].mask);
+ return;
+ }
+ }
+ } else {
+ for (i = ARRAY_SIZE(ab8500_reg_init) - 1; i >= 0; i--) {
+ if (ab8500_reg_init[i].id == id) {
+ u8 initval = ab8500_reg_init[i].value;
+ initval = (initval & ~mask) | (value & mask);
+ ab8500_reg_init[i].value = initval;
+
+ BUG_ON(mask & ~ab8500_reg_init[i].mask);
+ return;
+ }
+ }
+ }
+
+ BUG_ON(1);
+}
+
+void mop500_regulator_init(void)
+{
+ struct regulator_init_data *regulator;
+
+ /*
+ * Temporarily turn on Vaux2 on 8520 machine
+ */
+ if (cpu_is_u8520()) {
+ /* Vaux2 initialized to be on */
+ ab8500_modify_reg_init(AB8505_VAUX12REGU, 0x0f, 0x05);
+ }
+
+ /*
+ * Handle AB8500_EXT_SUPPLY2 on HREFP_V20_V50 boards (do it for
+ * all HREFP_V20 boards)
+ */
+ if (cpu_is_u8500v20()) {
+ /* VextSupply2RequestCtrl = HP/OFF depending on VxRequest */
+ ab8500_modify_reg_init(AB8500_REGUREQUESTCTRL3, 0x01, 0x01);
+
+ /* VextSupply2SysClkReq1HPValid = SysClkReq1 controlled */
+ ab8500_modify_reg_init(AB8500_REGUSYSCLKREQ1HPVALID2,
+ 0x20, 0x20);
+
+ /* VextSupply2 = force HP at initialization */
+ ab8500_modify_reg_init(AB8500_EXTSUPPLYREGU, 0x0c, 0x04);
+
+ /* enable VextSupply2 during platform active */
+ regulator = &ab8500_ext_regulators[AB8500_EXT_SUPPLY2];
+ regulator->constraints.always_on = 1;
+
+ /* disable VextSupply2 in suspend */
+ regulator = &ab8500_ext_regulators[AB8500_EXT_SUPPLY2];
+ regulator->constraints.state_mem.disabled = 1;
+ regulator->constraints.state_standby.disabled = 1;
+
+ /* enable VextSupply2 HW control (used in suspend) */
+ regulator->driver_data = (void *)&ab8500_ext_supply2;
+ }
+}
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 000000000..9bece38fe
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-regulators.h
@@ -0,0 +1,24 @@
+/*
+ * 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_platform_data ab8500_regulator_plat_data;
+extern struct ab8500_regulator_platform_data ab8505_regulator_plat_data;
+extern struct regulator_init_data tps61052_regulator;
+extern struct regulator_init_data gpio_en_3v3_regulator;
+
+void mop500_regulator_init(void);
+
+#endif
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h
new file mode 100644
index 000000000..7c7b0adca
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __BOARD_MOP500_H
+#define __BOARD_MOP500_H
+
+#include <linux/platform_data/asoc-ux500-msp.h>
+
+extern struct msp_i2s_platform_data msp0_platform_data;
+extern struct msp_i2s_platform_data msp1_platform_data;
+extern struct msp_i2s_platform_data msp2_platform_data;
+extern struct msp_i2s_platform_data msp3_platform_data;
+
+#endif
diff --git a/arch/arm/mach-ux500/cache-l2x0.c b/arch/arm/mach-ux500/cache-l2x0.c
new file mode 100644
index 000000000..e97ee556f
--- /dev/null
+++ b/arch/arm/mach-ux500/cache-l2x0.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include <asm/hardware/cache-l2x0.h>
+
+#include "db8500-regs.h"
+#include "id.h"
+
+static int __init ux500_l2x0_unlock(void)
+{
+ int i;
+ void __iomem *l2x0_base = __io_address(U8500_L2CC_BASE);
+
+ /*
+ * 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 void ux500_l2c310_write_sec(unsigned long val, unsigned reg)
+{
+ /*
+ * We can't write to secure registers as we are in non-secure
+ * mode, until we have some SMI service available.
+ */
+}
+
+static int __init ux500_l2x0_init(void)
+{
+ /* Multiplatform guard */
+ if (!((cpu_is_u8500_family() || cpu_is_ux540_family())))
+ return -ENODEV;
+
+ /* Unlock before init */
+ ux500_l2x0_unlock();
+ outer_cache.write_sec = ux500_l2c310_write_sec;
+ l2x0_of_init(0, ~0);
+
+ return 0;
+}
+early_initcall(ux500_l2x0_init);
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
new file mode 100644
index 000000000..6f63954c8
--- /dev/null
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2008-2009 ST-Ericsson SA
+ *
+ * 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/platform_device.h>
+#include <linux/io.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include <linux/mfd/dbx500-prcmu.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/regulator/machine.h>
+#include <linux/random.h>
+
+#include <asm/pmu.h>
+#include <asm/mach/map.h>
+
+#include "setup.h"
+
+#include "board-mop500-regulators.h"
+#include "board-mop500.h"
+#include "db8500-regs.h"
+#include "id.h"
+
+static struct ab8500_platform_data ab8500_platdata = {
+ .regulator = &ab8500_regulator_plat_data,
+};
+
+static struct prcmu_pdata db8500_prcmu_pdata = {
+ .ab_platdata = &ab8500_platdata,
+ .version_offset = DB8500_PRCMU_FW_VERSION_OFFSET,
+ .legacy_offset = DB8500_PRCMU_LEGACY_OFFSET,
+};
+
+/* 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),
+};
+/* U8500 and U9540 common io_desc */
+static struct map_desc u8500_common_io_desc[] __initdata = {
+ /* SCU base also covers GIC CPU BASE and TWD with its 4K page */
+ __IO_DEV_DESC(U8500_SCU_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_L2CC_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_MTU0_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_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),
+};
+
+/* U8500 IO map specific description */
+static struct map_desc u8500_io_desc[] __initdata = {
+ __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K),
+
+};
+
+/* U9540 IO map specific description */
+static struct map_desc u9540_io_desc[] __initdata = {
+ __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K + SZ_8K),
+ __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K + SZ_8K),
+};
+
+static 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_common_io_desc, ARRAY_SIZE(u8500_common_io_desc));
+
+ if (cpu_is_ux540_family())
+ iotable_init(u9540_io_desc, ARRAY_SIZE(u9540_io_desc));
+ else
+ iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
+}
+
+/*
+ * 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 const char *db8500_read_soc_id(void)
+{
+ void __iomem *uid = __io_address(U8500_BB_UID_BASE);
+
+ /* Throw these device-specific numbers into the entropy pool */
+ add_device_randomness(uid, 0x14);
+ return kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x",
+ readl((u32 *)uid+0),
+ readl((u32 *)uid+1), readl((u32 *)uid+2),
+ readl((u32 *)uid+3), readl((u32 *)uid+4));
+}
+
+static struct device * __init db8500_soc_device_init(void)
+{
+ const char *soc_id = db8500_read_soc_id();
+
+ return ux500_soc_device_init(soc_id);
+}
+
+static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
+ /* Requires call-back bindings. */
+ OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata),
+ /* Requires DMA bindings. */
+ OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000,
+ "ux500-msp-i2s.0", &msp0_platform_data),
+ OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80124000,
+ "ux500-msp-i2s.1", &msp1_platform_data),
+ OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80117000,
+ "ux500-msp-i2s.2", &msp2_platform_data),
+ OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80125000,
+ "ux500-msp-i2s.3", &msp3_platform_data),
+ /* Requires non-DT:able platform data. */
+ OF_DEV_AUXDATA("stericsson,db8500-prcmu", 0x80157000, "db8500-prcmu",
+ &db8500_prcmu_pdata),
+ OF_DEV_AUXDATA("stericsson,ux500-cryp", 0xa03cb000, "cryp1", NULL),
+ OF_DEV_AUXDATA("stericsson,ux500-hash", 0xa03c2000, "hash1", NULL),
+ OF_DEV_AUXDATA("stericsson,snd-soc-mop500", 0, "snd-soc-mop500.0",
+ NULL),
+ {},
+};
+
+static struct of_dev_auxdata u8540_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("stericsson,db8500-prcmu", 0x80157000, "db8500-prcmu",
+ &db8500_prcmu_pdata),
+ {},
+};
+
+static const struct of_device_id u8500_local_bus_nodes[] = {
+ /* only create devices below soc node */
+ { .compatible = "stericsson,db8500", },
+ { .compatible = "stericsson,db8500-prcmu", },
+ { .compatible = "simple-bus"},
+ { },
+};
+
+static void __init u8500_init_machine(void)
+{
+ struct device *parent = db8500_soc_device_init();
+
+ /* automatically probe child nodes of dbx5x0 devices */
+ if (of_machine_is_compatible("st-ericsson,u8540"))
+ of_platform_populate(NULL, u8500_local_bus_nodes,
+ u8540_auxdata_lookup, parent);
+ else
+ of_platform_populate(NULL, u8500_local_bus_nodes,
+ u8500_auxdata_lookup, parent);
+}
+
+static const char * stericsson_dt_platform_compat[] = {
+ "st-ericsson,u8500",
+ "st-ericsson,u8540",
+ "st-ericsson,u9500",
+ "st-ericsson,u9540",
+ NULL,
+};
+
+DT_MACHINE_START(U8500_DT, "ST-Ericsson Ux5x0 platform (Device Tree Support)")
+ .smp = smp_ops(ux500_smp_ops),
+ .map_io = u8500_map_io,
+ .init_irq = ux500_init_irq,
+ /* we re-use nomadik timer here */
+ .init_time = ux500_timer_init,
+ .init_machine = u8500_init_machine,
+ .init_late = NULL,
+ .dt_compat = stericsson_dt_platform_compat,
+ .restart = ux500_restart,
+MACHINE_END
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
new file mode 100644
index 000000000..6ced0f680
--- /dev/null
+++ b/arch/arm/mach-ux500/cpu.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * Author: Lee Jones <lee.jones@linaro.org> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mfd/dbx500-prcmu.h>
+#include <linux/clksrc-dbx500-prcmu.h>
+#include <linux/sys_soc.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/platform_data/clk-ux500.h>
+#include <linux/platform_data/arm-ux500-pm.h>
+
+#include <asm/mach/map.h>
+
+#include "setup.h"
+
+#include "board-mop500.h"
+#include "db8500-regs.h"
+#include "id.h"
+
+void ux500_restart(enum reboot_mode mode, const char *cmd)
+{
+ local_irq_disable();
+ local_fiq_disable();
+
+ prcmu_system_reset(0);
+}
+
+/*
+ * FIXME: Should we set up the GPIO domain here?
+ *
+ * The problem is that we cannot put the interrupt resources into the platform
+ * device until the irqdomain has been added. Right now, we set the GIC interrupt
+ * domain from init_irq(), then load the gpio driver from
+ * core_initcall(nmk_gpio_init) and add the platform devices from
+ * arch_initcall(customize_machine).
+ *
+ * This feels fragile because it depends on the gpio device getting probed
+ * _before_ any device uses the gpio interrupts.
+*/
+void __init ux500_init_irq(void)
+{
+ gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND);
+ irqchip_init();
+
+ /*
+ * Init clocks here so that they are available for system timer
+ * initialization.
+ */
+ if (cpu_is_u8500_family()) {
+ prcmu_early_init(U8500_PRCMU_BASE, SZ_8K - 1);
+ ux500_pm_init(U8500_PRCMU_BASE, SZ_8K - 1);
+
+ u8500_of_clk_init(U8500_CLKRST1_BASE,
+ U8500_CLKRST2_BASE,
+ U8500_CLKRST3_BASE,
+ U8500_CLKRST5_BASE,
+ U8500_CLKRST6_BASE);
+ } else if (cpu_is_u9540()) {
+ prcmu_early_init(U8500_PRCMU_BASE, SZ_8K - 1);
+ ux500_pm_init(U8500_PRCMU_BASE, SZ_8K - 1);
+ u9540_clk_init(U8500_CLKRST1_BASE, U8500_CLKRST2_BASE,
+ U8500_CLKRST3_BASE, U8500_CLKRST5_BASE,
+ U8500_CLKRST6_BASE);
+ } else if (cpu_is_u8540()) {
+ prcmu_early_init(U8500_PRCMU_BASE, SZ_8K + SZ_4K - 1);
+ ux500_pm_init(U8500_PRCMU_BASE, SZ_8K + SZ_4K - 1);
+ u8540_clk_init(U8500_CLKRST1_BASE, U8500_CLKRST2_BASE,
+ U8500_CLKRST3_BASE, U8500_CLKRST5_BASE,
+ U8500_CLKRST6_BASE);
+ }
+}
+
+static const char * __init ux500_get_machine(void)
+{
+ return kasprintf(GFP_KERNEL, "DB%4x", dbx500_partnumber());
+}
+
+static const char * __init ux500_get_family(void)
+{
+ return kasprintf(GFP_KERNEL, "ux500");
+}
+
+static const char * __init ux500_get_revision(void)
+{
+ unsigned int rev = dbx500_revision();
+
+ if (rev == 0x01)
+ return kasprintf(GFP_KERNEL, "%s", "ED");
+ else if (rev >= 0xA0)
+ return kasprintf(GFP_KERNEL, "%d.%d",
+ (rev >> 4) - 0xA + 1, rev & 0xf);
+
+ return kasprintf(GFP_KERNEL, "%s", "Unknown");
+}
+
+static ssize_t ux500_get_process(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ if (dbx500_id.process == 0x00)
+ return sprintf(buf, "Standard\n");
+
+ return sprintf(buf, "%02xnm\n", dbx500_id.process);
+}
+
+static void __init soc_info_populate(struct soc_device_attribute *soc_dev_attr,
+ const char *soc_id)
+{
+ soc_dev_attr->soc_id = soc_id;
+ soc_dev_attr->machine = ux500_get_machine();
+ soc_dev_attr->family = ux500_get_family();
+ soc_dev_attr->revision = ux500_get_revision();
+}
+
+static const struct device_attribute ux500_soc_attr =
+ __ATTR(process, S_IRUGO, ux500_get_process, NULL);
+
+struct device * __init ux500_soc_device_init(const char *soc_id)
+{
+ struct device *parent;
+ struct soc_device *soc_dev;
+ struct soc_device_attribute *soc_dev_attr;
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ return ERR_PTR(-ENOMEM);
+
+ soc_info_populate(soc_dev_attr, soc_id);
+
+ soc_dev = soc_device_register(soc_dev_attr);
+ if (IS_ERR(soc_dev)) {
+ kfree(soc_dev_attr);
+ return NULL;
+ }
+
+ parent = soc_device_to_device(soc_dev);
+ device_create_file(parent, &ux500_soc_attr);
+
+ return parent;
+}
diff --git a/arch/arm/mach-ux500/db8500-regs.h b/arch/arm/mach-ux500/db8500-regs.h
new file mode 100644
index 000000000..27399553c
--- /dev/null
+++ b/arch/arm/mach-ux500/db8500-regs.h
@@ -0,0 +1,200 @@
+/*
+ * 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)
+
+/* This address fulfills the 256k alignment requirement of the lcla base */
+#define U8500_DMA_LCLA_BASE U8500_ESRAM_BANK4
+
+#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 U9540_BOOT_ROM_BASE 0xFFFE0000
+/* ASIC ID is at 0xbf4 offset within this region */
+#define U9540_ASIC_ID_BASE 0xFFFFD000
+
+#define U8500_PER6_BASE 0xa03c0000
+#define U8500_PER7_BASE 0xa03d0000
+#define U8500_PER5_BASE 0xa03e0000
+
+#define U8500_SVA_BASE 0xa0100000
+#define U8500_SIA_BASE 0xa0200000
+
+#define U8500_SGA_BASE 0xa0300000
+#define U8500_MCDE_BASE 0xa0350000
+#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)
+
+#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 U9540_DMC1_BASE (U8500_PER4_BASE + 0x0A000)
+#define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000)
+#define U8500_PRCMU_TCPM_BASE (U8500_PER4_BASE + 0x60000)
+#define U8500_PRCMU_TIMER_3_BASE (U8500_PER4_BASE + 0x07338)
+#define U8500_PRCMU_TIMER_4_BASE (U8500_PER4_BASE + 0x07450)
+
+/* 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
+
+/* SoC identification number information */
+#define U8500_BB_UID_BASE (U8500_BACKUPRAM1_BASE + 0xFC0)
+
+/* Offsets to specific addresses in some IP blocks for DMA */
+#define MSP_TX_RX_REG_OFFSET 0
+#define CRYP1_RX_REG_OFFSET 0x10
+#define CRYP1_TX_REG_OFFSET 0x8
+#define HASH1_TX_REG_OFFSET 0x4
+
+/*
+ * 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 is where we map in the ROM to check ASIC IDs */
+#define UX500_VIRT_ROM IOMEM(0xf0000000)
+
+/* 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) IOMEM(IO_ADDRESS(n))
+
+/* Used by some plat-nomadik code */
+#define io_p2v(n) __io_address(n)
+
+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
+
+#endif
diff --git a/arch/arm/mach-ux500/headsmp.S b/arch/arm/mach-ux500/headsmp.S
new file mode 100644
index 000000000..9cdea0494
--- /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>
+
+/*
+ * 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
+ENDPROC(u8500_secondary_startup)
+
+ .align 2
+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 000000000..2bc00b085
--- /dev/null
+++ b/arch/arm/mach-ux500/hotplug.c
@@ -0,0 +1,37 @@
+/*
+ * 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/smp_plat.h>
+
+#include "setup.h"
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void __ref ux500_cpu_die(unsigned int cpu)
+{
+ /* directly enter low power state, skipping secure registers */
+ for (;;) {
+ __asm__ __volatile__("dsb\n\t" "wfi\n\t"
+ : : : "memory");
+ if (pen_release == cpu_logical_map(cpu)) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+ }
+}
diff --git a/arch/arm/mach-ux500/id.c b/arch/arm/mach-ux500/id.c
new file mode 100644
index 000000000..392f2fdb3
--- /dev/null
+++ b/arch/arm/mach-ux500/id.c
@@ -0,0 +1,116 @@
+/*
+ * 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 "setup.h"
+
+#include "db8500-regs.h"
+#include "id.h"
+
+struct dbx500_asic_id dbx500_id;
+
+static unsigned int __init ux500_read_asicid(phys_addr_t addr)
+{
+ phys_addr_t base = addr & ~0xfff;
+ struct map_desc desc = {
+ .virtual = (unsigned long)UX500_VIRT_ROM,
+ .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(UX500_VIRT_ROM + (addr & 0xfff));
+}
+
+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
+ * DB8520v2.2 0x412fc091 0x9001DBF4 0x008500B2
+ * DB5500v1 0x412fc091 0x9001FFF4 0x005500A0
+ * DB9540 0x413fc090 0xFFFFDBF4 0x009540xx
+ */
+
+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: /* DB8520 / DB8500v2 / DB5500v1 */
+ asicid = ux500_read_asicid(0x9001DBF4);
+ if (partnumber(asicid) == 0x8500 ||
+ partnumber(asicid) == 0x8520)
+ /* DB8500v2 */
+ break;
+
+ /* DB5500v1 */
+ addr = 0x9001FFF4;
+ break;
+
+ case 0x413fc090: /* DB9540 */
+ addr = 0xFFFFDBF4;
+ 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/id.h b/arch/arm/mach-ux500/id.h
new file mode 100644
index 000000000..bcc58a8cc
--- /dev/null
+++ b/arch/arm/mach-ux500/id.h
@@ -0,0 +1,144 @@
+/*
+ * 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_u8520(void)
+{
+ return dbx500_partnumber() == 0x8520;
+}
+
+static inline bool cpu_is_u8500_family(void)
+{
+ return cpu_is_u8500() || cpu_is_u8520();
+}
+
+static inline bool __attribute_const__ cpu_is_u9540(void)
+{
+ return dbx500_partnumber() == 0x9540;
+}
+
+static inline bool __attribute_const__ cpu_is_u8540(void)
+{
+ return dbx500_partnumber() == 0x8540;
+}
+
+static inline bool __attribute_const__ cpu_is_u8580(void)
+{
+ return dbx500_partnumber() == 0x8580;
+}
+
+static inline bool cpu_is_ux540_family(void)
+{
+ return cpu_is_u9540() || cpu_is_u8540() || cpu_is_u8580();
+}
+
+/*
+ * 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_u8500v22(void)
+{
+ return cpu_is_u8500() && (dbx500_revision() == 0xB2);
+}
+
+static inline bool cpu_is_u8500v20_or_later(void)
+{
+ return (cpu_is_u8500() && !cpu_is_u8500v10() && !cpu_is_u8500v11());
+}
+
+/*
+ * 8540 revisions
+ */
+
+static inline bool __attribute_const__ cpu_is_u8540v10(void)
+{
+ return cpu_is_u8540() && dbx500_revision() == 0xA0;
+}
+
+static inline bool __attribute_const__ cpu_is_u8580v10(void)
+{
+ return cpu_is_u8580() && dbx500_revision() == 0xA0;
+}
+
+static inline bool ux500_is_svp(void)
+{
+ return false;
+}
+
+#define ux500_unknown_soc() BUG()
+
+#endif
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
new file mode 100644
index 000000000..a44967f31
--- /dev/null
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -0,0 +1,169 @@
+/*
+ * 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/smp_plat.h>
+#include <asm/smp_scu.h>
+
+#include "setup.h"
+
+#include "db8500-regs.h"
+#include "id.h"
+
+/* This is called from headsmp.S to wakeup the secondary core */
+extern void u8500_secondary_startup(void);
+
+/*
+ * 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();
+ sync_cache_w(&pen_release);
+}
+
+static void __iomem *scu_base_addr(void)
+{
+ if (cpu_is_u8500_family() || cpu_is_ux540_family())
+ return __io_address(U8500_SCU_BASE);
+ else
+ ux500_unknown_soc();
+
+ return NULL;
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+static void ux500_secondary_init(unsigned int cpu)
+{
+ /*
+ * 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);
+}
+
+static int ux500_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_logical_map(cpu));
+
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+ 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_u8500_family() || cpu_is_ux540_family())
+ 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.
+ */
+static void __init ux500_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_cpu_ids) {
+ pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
+ ncores, nr_cpu_ids);
+ ncores = nr_cpu_ids;
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+}
+
+static void __init ux500_smp_prepare_cpus(unsigned int max_cpus)
+{
+
+ scu_enable(scu_base_addr());
+ wakeup_secondary();
+}
+
+struct smp_operations ux500_smp_ops __initdata = {
+ .smp_init_cpus = ux500_smp_init_cpus,
+ .smp_prepare_cpus = ux500_smp_prepare_cpus,
+ .smp_secondary_init = ux500_secondary_init,
+ .smp_boot_secondary = ux500_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = ux500_cpu_die,
+#endif
+};
diff --git a/arch/arm/mach-ux500/pm.c b/arch/arm/mach-ux500/pm.c
new file mode 100644
index 000000000..2cb587b50
--- /dev/null
+++ b/arch/arm/mach-ux500/pm.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010-2013
+ * Author: Rickard Andersson <rickard.andersson@stericsson.com> for
+ * ST-Ericsson.
+ * Author: Daniel Lezcano <daniel.lezcano@linaro.org> for Linaro.
+ * Author: Ulf Hansson <ulf.hansson@linaro.org> for Linaro.
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/suspend.h>
+#include <linux/platform_data/arm-ux500-pm.h>
+
+#include "db8500-regs.h"
+#include "pm_domains.h"
+
+/* ARM WFI Standby signal register */
+#define PRCM_ARM_WFI_STANDBY (prcmu_base + 0x130)
+#define PRCM_ARM_WFI_STANDBY_WFI0 0x08
+#define PRCM_ARM_WFI_STANDBY_WFI1 0x10
+#define PRCM_IOCR (prcmu_base + 0x310)
+#define PRCM_IOCR_IOFORCE 0x1
+
+/* Dual A9 core interrupt management unit registers */
+#define PRCM_A9_MASK_REQ (prcmu_base + 0x328)
+#define PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ 0x1
+
+#define PRCM_A9_MASK_ACK (prcmu_base + 0x32c)
+#define PRCM_ARMITMSK31TO0 (prcmu_base + 0x11c)
+#define PRCM_ARMITMSK63TO32 (prcmu_base + 0x120)
+#define PRCM_ARMITMSK95TO64 (prcmu_base + 0x124)
+#define PRCM_ARMITMSK127TO96 (prcmu_base + 0x128)
+#define PRCM_POWER_STATE_VAL (prcmu_base + 0x25C)
+#define PRCM_ARMITVAL31TO0 (prcmu_base + 0x260)
+#define PRCM_ARMITVAL63TO32 (prcmu_base + 0x264)
+#define PRCM_ARMITVAL95TO64 (prcmu_base + 0x268)
+#define PRCM_ARMITVAL127TO96 (prcmu_base + 0x26C)
+
+static void __iomem *prcmu_base;
+
+/* This function decouple the gic from the prcmu */
+int prcmu_gic_decouple(void)
+{
+ u32 val = readl(PRCM_A9_MASK_REQ);
+
+ /* Set bit 0 register value to 1 */
+ writel(val | PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ,
+ PRCM_A9_MASK_REQ);
+
+ /* Make sure the register is updated */
+ readl(PRCM_A9_MASK_REQ);
+
+ /* Wait a few cycles for the gic mask completion */
+ udelay(1);
+
+ return 0;
+}
+
+/* This function recouple the gic with the prcmu */
+int prcmu_gic_recouple(void)
+{
+ u32 val = readl(PRCM_A9_MASK_REQ);
+
+ /* Set bit 0 register value to 0 */
+ writel(val & ~PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ, PRCM_A9_MASK_REQ);
+
+ return 0;
+}
+
+#define PRCMU_GIC_NUMBER_REGS 5
+
+/*
+ * This function checks if there are pending irq on the gic. It only
+ * makes sense if the gic has been decoupled before with the
+ * db8500_prcmu_gic_decouple function. Disabling an interrupt only
+ * disables the forwarding of the interrupt to any CPU interface. It
+ * does not prevent the interrupt from changing state, for example
+ * becoming pending, or active and pending if it is already
+ * active. Hence, we have to check the interrupt is pending *and* is
+ * active.
+ */
+bool prcmu_gic_pending_irq(void)
+{
+ u32 pr; /* Pending register */
+ u32 er; /* Enable register */
+ void __iomem *dist_base = __io_address(U8500_GIC_DIST_BASE);
+ int i;
+
+ /* 5 registers. STI & PPI not skipped */
+ for (i = 0; i < PRCMU_GIC_NUMBER_REGS; i++) {
+
+ pr = readl_relaxed(dist_base + GIC_DIST_PENDING_SET + i * 4);
+ er = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
+
+ if (pr & er)
+ return true; /* There is a pending interrupt */
+ }
+
+ return false;
+}
+
+/*
+ * This function checks if there are pending interrupt on the
+ * prcmu which has been delegated to monitor the irqs with the
+ * db8500_prcmu_copy_gic_settings function.
+ */
+bool prcmu_pending_irq(void)
+{
+ u32 it, im;
+ int i;
+
+ for (i = 0; i < PRCMU_GIC_NUMBER_REGS - 1; i++) {
+ it = readl(PRCM_ARMITVAL31TO0 + i * 4);
+ im = readl(PRCM_ARMITMSK31TO0 + i * 4);
+ if (it & im)
+ return true; /* There is a pending interrupt */
+ }
+
+ return false;
+}
+
+/*
+ * This function checks if the specified cpu is in in WFI. It's usage
+ * makes sense only if the gic is decoupled with the db8500_prcmu_gic_decouple
+ * function. Of course passing smp_processor_id() to this function will
+ * always return false...
+ */
+bool prcmu_is_cpu_in_wfi(int cpu)
+{
+ return readl(PRCM_ARM_WFI_STANDBY) & cpu ? PRCM_ARM_WFI_STANDBY_WFI1 :
+ PRCM_ARM_WFI_STANDBY_WFI0;
+}
+
+/*
+ * This function copies the gic SPI settings to the prcmu in order to
+ * monitor them and abort/finish the retention/off sequence or state.
+ */
+int prcmu_copy_gic_settings(void)
+{
+ u32 er; /* Enable register */
+ void __iomem *dist_base = __io_address(U8500_GIC_DIST_BASE);
+ int i;
+
+ /* We skip the STI and PPI */
+ for (i = 0; i < PRCMU_GIC_NUMBER_REGS - 1; i++) {
+ er = readl_relaxed(dist_base +
+ GIC_DIST_ENABLE_SET + (i + 1) * 4);
+ writel(er, PRCM_ARMITMSK31TO0 + i * 4);
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_SUSPEND
+static int ux500_suspend_enter(suspend_state_t state)
+{
+ cpu_do_idle();
+ return 0;
+}
+
+static int ux500_suspend_valid(suspend_state_t state)
+{
+ return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY;
+}
+
+static const struct platform_suspend_ops ux500_suspend_ops = {
+ .enter = ux500_suspend_enter,
+ .valid = ux500_suspend_valid,
+};
+#define UX500_SUSPEND_OPS (&ux500_suspend_ops)
+#else
+#define UX500_SUSPEND_OPS NULL
+#endif
+
+void __init ux500_pm_init(u32 phy_base, u32 size)
+{
+ prcmu_base = ioremap(phy_base, size);
+ if (!prcmu_base) {
+ pr_err("could not remap PRCMU for PM functions\n");
+ return;
+ }
+ /*
+ * On watchdog reboot the GIC is in some cases decoupled.
+ * This will make sure that the GIC is correctly configured.
+ */
+ prcmu_gic_recouple();
+
+ /* Set up ux500 suspend callbacks. */
+ suspend_set_ops(UX500_SUSPEND_OPS);
+
+ /* Initialize ux500 power domains */
+ ux500_pm_domains_init();
+}
diff --git a/arch/arm/mach-ux500/pm_domains.c b/arch/arm/mach-ux500/pm_domains.c
new file mode 100644
index 000000000..4d71c90f8
--- /dev/null
+++ b/arch/arm/mach-ux500/pm_domains.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * Author: Ulf Hansson <ulf.hansson@linaro.org>
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * Implements PM domains using the generic PM domain for ux500.
+ */
+#include <linux/printk.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/pm_domain.h>
+
+#include <dt-bindings/arm/ux500_pm_domains.h>
+#include "pm_domains.h"
+
+static int pd_power_off(struct generic_pm_domain *domain)
+{
+ /*
+ * Handle the gating of the PM domain regulator here.
+ *
+ * Drivers/subsystems handling devices in the PM domain needs to perform
+ * register context save/restore from their respective runtime PM
+ * callbacks, to be able to enable PM domain gating/ungating.
+ */
+ return 0;
+}
+
+static int pd_power_on(struct generic_pm_domain *domain)
+{
+ /*
+ * Handle the ungating of the PM domain regulator here.
+ *
+ * Drivers/subsystems handling devices in the PM domain needs to perform
+ * register context save/restore from their respective runtime PM
+ * callbacks, to be able to enable PM domain gating/ungating.
+ */
+ return 0;
+}
+
+static struct generic_pm_domain ux500_pm_domain_vape = {
+ .name = "VAPE",
+ .power_off = pd_power_off,
+ .power_on = pd_power_on,
+};
+
+static struct generic_pm_domain *ux500_pm_domains[NR_DOMAINS] = {
+ [DOMAIN_VAPE] = &ux500_pm_domain_vape,
+};
+
+static const struct of_device_id ux500_pm_domain_matches[] __initconst = {
+ { .compatible = "stericsson,ux500-pm-domains", },
+ { },
+};
+
+int __init ux500_pm_domains_init(void)
+{
+ struct device_node *np;
+ struct genpd_onecell_data *genpd_data;
+ int i;
+
+ np = of_find_matching_node(NULL, ux500_pm_domain_matches);
+ if (!np)
+ return -ENODEV;
+
+ genpd_data = kzalloc(sizeof(*genpd_data), GFP_KERNEL);
+ if (!genpd_data)
+ return -ENOMEM;
+
+ genpd_data->domains = ux500_pm_domains;
+ genpd_data->num_domains = ARRAY_SIZE(ux500_pm_domains);
+
+ for (i = 0; i < ARRAY_SIZE(ux500_pm_domains); ++i)
+ pm_genpd_init(ux500_pm_domains[i], NULL, false);
+
+ of_genpd_add_provider_onecell(np, genpd_data);
+ return 0;
+}
diff --git a/arch/arm/mach-ux500/pm_domains.h b/arch/arm/mach-ux500/pm_domains.h
new file mode 100644
index 000000000..263d3ba97
--- /dev/null
+++ b/arch/arm/mach-ux500/pm_domains.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * Author: Ulf Hansson <ulf.hansson@linaro.org>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_UX500_PM_DOMAINS_H
+#define __MACH_UX500_PM_DOMAINS_H
+
+#ifdef CONFIG_PM_GENERIC_DOMAINS
+extern int __init ux500_pm_domains_init(void);
+#else
+static inline int ux500_pm_domains_init(void) { return 0; }
+#endif
+
+#endif
diff --git a/arch/arm/mach-ux500/setup.h b/arch/arm/mach-ux500/setup.h
new file mode 100644
index 000000000..2dea8b59d
--- /dev/null
+++ b/arch/arm/mach-ux500/setup.h
@@ -0,0 +1,46 @@
+/*
+ * 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/arch.h>
+#include <asm/mach/time.h>
+#include <linux/init.h>
+#include <linux/mfd/abx500/ab8500.h>
+
+void ux500_restart(enum reboot_mode mode, const char *cmd);
+
+void __init ux500_map_io(void);
+
+extern void __init ux500_init_irq(void);
+
+extern struct device *ux500_soc_device_init(const char *soc_id);
+
+extern void ux500_timer_init(void);
+
+#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_RWX, \
+}
+
+extern struct smp_operations ux500_smp_ops;
+extern void ux500_cpu_die(unsigned int cpu);
+
+#endif /* __ASM_ARCH_SETUP_H */
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 000000000..0296ae5b0
--- /dev/null
+++ b/arch/arm/mach-ux500/ste-dma40-db8500.h
@@ -0,0 +1,85 @@
+/*
+ * 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
+
+/*
+ * Unless otherwise specified, all channels numbers are used for
+ * TX & RX, and can be used for either source or destination
+ * channels.
+ */
+enum dma_dev_type {
+ DB8500_DMA_DEV0_SPI0 = 0,
+ DB8500_DMA_DEV1_SD_MMC0 = 1,
+ DB8500_DMA_DEV2_SD_MMC1 = 2,
+ DB8500_DMA_DEV3_SD_MMC2 = 3,
+ DB8500_DMA_DEV4_I2C1 = 4,
+ DB8500_DMA_DEV5_I2C3 = 5,
+ DB8500_DMA_DEV6_I2C2 = 6,
+ DB8500_DMA_DEV7_I2C4 = 7, /* Only on V1 and later */
+ DB8500_DMA_DEV8_SSP0 = 8,
+ DB8500_DMA_DEV9_SSP1 = 9,
+ DB8500_DMA_DEV10_MCDE_RX = 10, /* RX only */
+ DB8500_DMA_DEV11_UART2 = 11,
+ DB8500_DMA_DEV12_UART1 = 12,
+ DB8500_DMA_DEV13_UART0 = 13,
+ DB8500_DMA_DEV14_MSP2 = 14,
+ DB8500_DMA_DEV15_I2C0 = 15,
+ DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15 = 16,
+ DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14 = 17,
+ DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13 = 18,
+ DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12 = 19,
+ DB8500_DMA_DEV20_SLIM0_CH0_HSI_CH0 = 20,
+ DB8500_DMA_DEV21_SLIM0_CH1_HSI_CH1 = 21,
+ DB8500_DMA_DEV22_SLIM0_CH2_HSI_CH2 = 22,
+ DB8500_DMA_DEV23_SLIM0_CH3_HSI_CH3 = 23,
+ DB8500_DMA_DEV24_SXA0 = 24,
+ DB8500_DMA_DEV25_SXA1 = 25,
+ DB8500_DMA_DEV26_SXA2 = 26,
+ DB8500_DMA_DEV27_SXA3 = 27,
+ DB8500_DMA_DEV28_SD_MM2 = 28,
+ DB8500_DMA_DEV29_SD_MM0 = 29,
+ DB8500_DMA_DEV30_MSP1 = 30,
+ /* On DB8500v2, MSP3 RX replaces MSP1 RX */
+ DB8500_DMA_DEV30_MSP3 = 30,
+ DB8500_DMA_DEV31_MSP0_SLIM0_CH0 = 31,
+ DB8500_DMA_DEV32_SD_MM1 = 32,
+ DB8500_DMA_DEV33_SPI2 = 33,
+ DB8500_DMA_DEV34_I2C3_RX2_TX2 = 34,
+ DB8500_DMA_DEV35_SPI1 = 35,
+ DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11 = 36,
+ DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10 = 37,
+ DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9 = 38,
+ DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8 = 39,
+ DB8500_DMA_DEV40_SPI3 = 40,
+ DB8500_DMA_DEV41_SD_MM3 = 41,
+ DB8500_DMA_DEV42_SD_MM4 = 42,
+ DB8500_DMA_DEV43_SD_MM5 = 43,
+ DB8500_DMA_DEV44_SXA4 = 44,
+ DB8500_DMA_DEV45_SXA5 = 45,
+ DB8500_DMA_DEV46_SLIM0_CH8_SRC_SXA6 = 46,
+ DB8500_DMA_DEV47_SLIM0_CH9_SRC_SXA7 = 47,
+ DB8500_DMA_DEV48_CAC1 = 48,
+ DB8500_DMA_DEV49_CAC1_TX_HAC1_TX = 49, /* TX only */
+ DB8500_DMA_DEV50_HAC1_TX = 50, /* TX only */
+ DB8500_DMA_MEMCPY_TX_0 = 51, /* TX only */
+ DB8500_DMA_DEV52_SLIM0_CH4_HSI_CH4 = 52,
+ DB8500_DMA_DEV53_SLIM0_CH5_HSI_CH5 = 53,
+ DB8500_DMA_DEV54_SLIM0_CH6_HSI_CH6 = 54,
+ DB8500_DMA_DEV55_SLIM0_CH7_HSI_CH7 = 55,
+ /* 56 -> 60 are channels reserved for memcpy only */
+ DB8500_DMA_DEV61_CAC0 = 61,
+ DB8500_DMA_DEV62_CAC0_TX_HAC0_TX = 62, /* TX only */
+ DB8500_DMA_DEV63_HAC0_TX = 63, /* TX only */
+};
+
+#endif
diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c
new file mode 100644
index 000000000..ff28d8ad1
--- /dev/null
+++ b/arch/arm/mach-ux500/timer.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * License Terms: GNU General Public License v2
+ * Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson
+ */
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/clksrc-dbx500-prcmu.h>
+#include <linux/clocksource.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include "setup.h"
+
+#include "db8500-regs.h"
+#include "id.h"
+
+static const struct of_device_id prcmu_timer_of_match[] __initconst = {
+ { .compatible = "stericsson,db8500-prcmu-timer-4", },
+ { },
+};
+
+void __init ux500_timer_init(void)
+{
+ void __iomem *prcmu_timer_base;
+ void __iomem *tmp_base;
+ struct device_node *np;
+
+ if (cpu_is_u8500_family() || cpu_is_ux540_family())
+ prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE);
+ else
+ ux500_unknown_soc();
+
+ np = of_find_matching_node(NULL, prcmu_timer_of_match);
+ if (!np)
+ goto dt_fail;
+
+ tmp_base = of_iomap(np, 0);
+ if (!tmp_base)
+ goto dt_fail;
+
+ prcmu_timer_base = tmp_base;
+
+dt_fail:
+ clksrc_dbx500_prcmu_init(prcmu_timer_base);
+ clocksource_of_init();
+}
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
new file mode 100644
index 000000000..1dba36882
--- /dev/null
+++ b/arch/arm/mach-versatile/Kconfig
@@ -0,0 +1,33 @@
+menu "Versatile platform type"
+ depends on ARCH_VERSATILE
+
+config ARCH_VERSATILE_PB
+ bool "Support Versatile Platform Baseboard for ARM926EJ-S"
+ default y
+ select CPU_ARM926T
+ select MIGHT_HAVE_PCI
+ 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.
+
+config MACH_VERSATILE_DT
+ bool "Support Versatile platform from device tree"
+ select CPU_ARM926T
+ select USE_OF
+ help
+ Include support for the ARM(R) Versatile/PB platform,
+ using the device tree for discovery
+
+config MACH_VERSATILE_AUTO
+ def_bool y
+ depends on !ARCH_VERSATILE_PB && !MACH_VERSATILE_AB
+ select MACH_VERSATILE_DT
+
+endmenu
diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile
new file mode 100644
index 000000000..81fa3fe25
--- /dev/null
+++ b/arch/arm/mach-versatile/Makefile
@@ -0,0 +1,9 @@
+#
+# 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_MACH_VERSATILE_DT) += versatile_dt.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 000000000..ff0a4b5b0
--- /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 000000000..6ea09fe53
--- /dev/null
+++ b/arch/arm/mach-versatile/core.c
@@ -0,0 +1,808 @@
+/*
+ * 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/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/platform_data/video-clcd-versatile.h>
+#include <linux/amba/pl061.h>
+#include <linux/amba/mmci.h>
+#include <linux/amba/pl022.h>
+#include <linux/io.h>
+#include <linux/irqchip/arm-vic.h>
+#include <linux/irqchip/versatile-fpga.h>
+#include <linux/gfp.h>
+#include <linux/clkdev.h>
+#include <linux/mtd/physmap.h>
+#include <linux/bitops.h>
+#include <linux/reboot.h>
+
+#include <asm/irq.h>
+#include <asm/hardware/arm_timer.h>
+#include <asm/hardware/icst.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/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)
+
+/* These PIC IRQs are valid in each configuration */
+#define PIC_VALID_ALL BIT(SIC_INT_KMI0) | BIT(SIC_INT_KMI1) | \
+ BIT(SIC_INT_SCI3) | BIT(SIC_INT_UART3) | \
+ BIT(SIC_INT_CLCD) | BIT(SIC_INT_TOUCH) | \
+ BIT(SIC_INT_KEYPAD) | BIT(SIC_INT_DoC) | \
+ BIT(SIC_INT_USB) | BIT(SIC_INT_PCI0) | \
+ BIT(SIC_INT_PCI1) | BIT(SIC_INT_PCI2) | \
+ BIT(SIC_INT_PCI3)
+#if 1
+#define IRQ_MMCI0A IRQ_VICSOURCE22
+#define IRQ_AACI IRQ_VICSOURCE24
+#define IRQ_ETH IRQ_VICSOURCE25
+#define PIC_MASK 0xFFD00000
+#define PIC_VALID PIC_VALID_ALL
+#else
+#define IRQ_MMCI0A IRQ_SIC_MMCI0A
+#define IRQ_AACI IRQ_SIC_AACI
+#define IRQ_ETH IRQ_SIC_ETH
+#define PIC_MASK 0
+#define PIC_VALID PIC_VALID_ALL | BIT(SIC_INT_MMCI0A) | \
+ BIT(SIC_INT_MMCI1A) | BIT(SIC_INT_AACI) | \
+ BIT(SIC_INT_ETH)
+#endif
+
+/* Lookup table for finding a DT node that represents the vic instance */
+static const struct of_device_id vic_of_match[] __initconst = {
+ { .compatible = "arm,versatile-vic", },
+ {}
+};
+
+static const struct of_device_id sic_of_match[] __initconst = {
+ { .compatible = "arm,versatile-sic", },
+ {}
+};
+
+void __init versatile_init_irq(void)
+{
+ struct device_node *np;
+
+ np = of_find_matching_node_by_address(NULL, vic_of_match,
+ VERSATILE_VIC_BASE);
+ __vic_init(VA_VIC_BASE, 0, IRQ_VIC_START, ~0, 0, np);
+
+ writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
+
+ np = of_find_matching_node_by_address(NULL, sic_of_match,
+ VERSATILE_SIC_BASE);
+
+ fpga_irq_init(VA_SIC_BASE, "SIC", IRQ_SIC_START,
+ IRQ_VICSOURCE31, PIC_VALID, np);
+
+ /*
+ * 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 __maybe_unused = {
+ {
+ .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_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
+ },
+#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,
+};
+
+static struct resource leds_resources[] = {
+ {
+ .start = VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET,
+ .end = VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET + 4,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device leds_device = {
+ .name = "versatile-leds",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(leds_resources),
+ .resource = leds_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 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,
+};
+
+static struct pl022_ssp_controller ssp0_plat_data = {
+ .bus_id = 0,
+ .enable_dma = 0,
+ .num_chipselect = 1,
+};
+
+#define AACI_IRQ { IRQ_AACI }
+#define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B }
+#define KMI0_IRQ { IRQ_SIC_KMI0 }
+#define KMI1_IRQ { IRQ_SIC_KMI1 }
+
+/*
+ * These devices are connected directly to the multi-layer AHB switch
+ */
+#define SMC_IRQ { }
+#define MPMC_IRQ { }
+#define CLCD_IRQ { IRQ_CLCDINT }
+#define DMAC_IRQ { IRQ_DMAINT }
+
+/*
+ * These devices are connected via the core APB bridge
+ */
+#define SCTL_IRQ { }
+#define WATCHDOG_IRQ { IRQ_WDOGINT }
+#define GPIO0_IRQ { IRQ_GPIOINT0 }
+#define GPIO1_IRQ { IRQ_GPIOINT1 }
+#define GPIO2_IRQ { IRQ_GPIOINT2 }
+#define GPIO3_IRQ { IRQ_GPIOINT3 }
+#define RTC_IRQ { IRQ_RTCINT }
+
+/*
+ * These devices are connected via the DMA APB bridge
+ */
+#define SCI_IRQ { IRQ_SCIINT }
+#define UART0_IRQ { IRQ_UARTINT0 }
+#define UART1_IRQ { IRQ_UARTINT1 }
+#define UART2_IRQ { IRQ_UARTINT2 }
+#define SSP_IRQ { IRQ_SSPINT }
+
+/* FPGA Primecells */
+APB_DEVICE(aaci, "fpga:04", AACI, NULL);
+APB_DEVICE(mmc0, "fpga:05", MMCI0, &mmc0_plat_data);
+APB_DEVICE(kmi0, "fpga:06", KMI0, NULL);
+APB_DEVICE(kmi1, "fpga:07", KMI1, NULL);
+
+/* DevChip Primecells */
+AHB_DEVICE(smc, "dev:00", SMC, NULL);
+AHB_DEVICE(mpmc, "dev:10", MPMC, NULL);
+AHB_DEVICE(clcd, "dev:20", CLCD, &clcd_plat_data);
+AHB_DEVICE(dmac, "dev:30", DMAC, NULL);
+APB_DEVICE(sctl, "dev:e0", SCTL, NULL);
+APB_DEVICE(wdog, "dev:e1", WATCHDOG, NULL);
+APB_DEVICE(gpio0, "dev:e4", GPIO0, &gpio0_plat_data);
+APB_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data);
+APB_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data);
+APB_DEVICE(gpio3, "dev:e7", GPIO3, &gpio3_plat_data);
+APB_DEVICE(rtc, "dev:e8", RTC, NULL);
+APB_DEVICE(sci0, "dev:f0", SCI, NULL);
+APB_DEVICE(uart0, "dev:f1", UART0, NULL);
+APB_DEVICE(uart1, "dev:f2", UART1, NULL);
+APB_DEVICE(uart2, "dev:f3", UART2, NULL);
+APB_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,
+ &gpio2_device,
+ &gpio3_device,
+ &rtc_device,
+ &sci0_device,
+ &ssp0_device,
+ &aaci_device,
+ &mmc0_device,
+ &kmi0_device,
+ &kmi1_device,
+};
+
+#ifdef CONFIG_OF
+/*
+ * Lookup table for attaching a specific name and platform_data pointer to
+ * devices as they get created by of_platform_populate(). Ideally this table
+ * would not exist, but the current clock implementation depends on some devices
+ * having a specific name.
+ */
+struct of_dev_auxdata versatile_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI0_BASE, "fpga:05", &mmc0_plat_data),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_KMI0_BASE, "fpga:06", NULL),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_KMI1_BASE, "fpga:07", NULL),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART3_BASE, "fpga:09", NULL),
+ /* FIXME: this is buggy, the platform data is needed for this MMC instance too */
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI1_BASE, "fpga:0b", NULL),
+
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_CLCD_BASE, "dev:20", &clcd_plat_data),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART0_BASE, "dev:f1", NULL),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART1_BASE, "dev:f2", NULL),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART2_BASE, "dev:f3", NULL),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_SSP_BASE, "dev:f4", &ssp0_plat_data),
+
+#if 0
+ /*
+ * These entries are unnecessary because no clocks referencing
+ * them. I've left them in for now as place holders in case
+ * any of them need to be added back, but they should be
+ * removed before actually committing this patch. --gcl
+ */
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_AACI_BASE, "fpga:04", NULL),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCI1_BASE, "fpga:0a", NULL),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_SMC_BASE, "dev:00", NULL),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_MPMC_BASE, "dev:10", NULL),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_DMAC_BASE, "dev:30", NULL),
+
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCTL_BASE, "dev:e0", NULL),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_WATCHDOG_BASE, "dev:e1", NULL),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO0_BASE, "dev:e4", NULL),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO1_BASE, "dev:e5", NULL),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO2_BASE, "dev:e6", NULL),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO3_BASE, "dev:e7", NULL),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_RTC_BASE, "dev:e8", NULL),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCI_BASE, "dev:f0", NULL),
+#endif
+ {}
+};
+#endif
+
+void versatile_restart(enum reboot_mode mode, const char *cmd)
+{
+ void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
+ u32 val;
+
+ val = __raw_readl(sys + VERSATILE_SYS_RESETCTL_OFFSET);
+ val |= 0x105;
+
+ __raw_writel(0xa05f, sys + VERSATILE_SYS_LOCK_OFFSET);
+ __raw_writel(val, sys + VERSATILE_SYS_RESETCTL_OFFSET);
+ __raw_writel(0, sys + VERSATILE_SYS_LOCK_OFFSET);
+}
+
+/* Early initializations */
+void __init versatile_init_early(void)
+{
+ u32 val;
+ 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);
+
+ /*
+ * 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));
+}
+
+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);
+ platform_device_register(&leds_device);
+
+ 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 __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.
+ */
+void __init versatile_timer_init(void)
+{
+
+ /*
+ * 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");
+}
diff --git a/arch/arm/mach-versatile/core.h b/arch/arm/mach-versatile/core.h
new file mode 100644
index 000000000..f06d5768e
--- /dev/null
+++ b/arch/arm/mach-versatile/core.h
@@ -0,0 +1,46 @@
+/*
+ * 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>
+#include <linux/of_platform.h>
+#include <linux/reboot.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 void versatile_timer_init(void);
+extern void versatile_restart(enum reboot_mode, const char *);
+extern unsigned int mmc_status(struct device *dev);
+#ifdef CONFIG_OF
+extern struct of_dev_auxdata versatile_auxdata_lookup[];
+#endif
+
+#define APB_DEVICE(name, busid, base, plat) \
+static AMBA_APB_DEVICE(name, busid, 0, VERSATILE_##base##_BASE, base##_IRQ, plat)
+
+#define AHB_DEVICE(name, busid, base, plat) \
+static AMBA_AHB_DEVICE(name, busid, 0, VERSATILE_##base##_BASE, base##_IRQ, plat)
+
+#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 000000000..e58d0771b
--- /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/hardware.h b/arch/arm/mach-versatile/include/mach/hardware.h
new file mode 100644
index 000000000..3e5d425e2
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/hardware.h
@@ -0,0 +1,38 @@
+/*
+ * 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
+
+/* macro to get at MMIO 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/irqs.h b/arch/arm/mach-versatile/include/mach/irqs.h
new file mode 100644
index 000000000..0fd771ca6
--- /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 32
+#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 64
+#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 95
+
+#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/platform.h b/arch/arm/mach-versatile/include/mach/platform.h
new file mode 100644
index 000000000..6f938ccb0
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/platform.h
@@ -0,0 +1,416 @@
+/*
+ * 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_IO_BASE 0x43000000
+#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_IO_BASE_SIZE 0x01000000
+#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/uncompress.h b/arch/arm/mach-versatile/include/mach/uncompress.h
new file mode 100644
index 000000000..986e3d303
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/uncompress.h
@@ -0,0 +1,45 @@
+/*
+ * 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()
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
new file mode 100644
index 000000000..c97be4ea7
--- /dev/null
+++ b/arch/arm/mach-versatile/pci.c
@@ -0,0 +1,368 @@
+/*
+ * 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 <mach/irqs.h>
+#include <asm/irq.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+0x14)
+#define PCI_SMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18)
+#define PCI_SMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x1c)
+#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 unused_mem = {
+ .name = "PCI unused",
+ .start = VERSATILE_PCI_MEM_BASE0,
+ .end = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1,
+ .flags = IORESOURCE_MEM,
+};
+
+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 pci_sys_data *sys)
+{
+ int ret = 0;
+
+ ret = request_resource(&iomem_resource, &unused_mem);
+ if (ret) {
+ printk(KERN_ERR "PCI: unable to allocate unused "
+ "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_unused_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;
+ }
+
+ /*
+ * the mem resource for this bus
+ * the prefetch mem resource for this bus
+ */
+ pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset);
+ pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset);
+
+ goto out;
+
+ release_non_mem:
+ release_resource(&non_mem);
+ release_unused_mem:
+ release_resource(&unused_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;
+ }
+
+ ret = pci_ioremap_io(0, VERSATILE_PCI_IO_BASE);
+ if (ret)
+ goto out;
+
+ if (nr == 0) {
+ ret = pci_versatile_setup_resources(sys);
+ 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);
+
+ /*
+ * For many years the kernel and QEMU were symbiotically buggy
+ * in that they both assumed the same broken IRQ mapping.
+ * QEMU therefore attempts to auto-detect old broken kernels
+ * so that they still work on newer QEMU as they did on old
+ * QEMU. Since we now use the correct (ie matching-hardware)
+ * IRQ mapping we write a definitely different value to a
+ * PCI_INTERRUPT_LINE register to tell QEMU that we expect
+ * real hardware behaviour and it need not be backwards
+ * compatible for us. This write is harmless on real hardware.
+ */
+ __raw_writel(0, VERSATILE_PCI_VIRT_BASE+PCI_INTERRUPT_LINE);
+
+ /*
+ * Do not to map Versatile FPGA PCI device into memory space
+ */
+ pci_slot_ignore |= (1 << myslot);
+ ret = 1;
+
+ out:
+ return ret;
+}
+
+
+void __init pci_versatile_preinit(void)
+{
+ pcibios_min_mem = 0x50000000;
+
+ __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(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Slot INTA INTB INTC INTD
+ * 31 PCI1 PCI2 PCI3 PCI0
+ * 30 PCI0 PCI1 PCI2 PCI3
+ * 29 PCI3 PCI0 PCI1 PCI2
+ */
+ irq = IRQ_SIC_PCI0 + ((slot + 2 + pin - 1) & 3);
+
+ return irq;
+}
+
+static struct hw_pci versatile_pci __initdata = {
+ .map_irq = versatile_map_irq,
+ .nr_controllers = 1,
+ .ops = &pci_versatile_ops,
+ .setup = pci_versatile_setup,
+ .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 000000000..1caef1093
--- /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/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 */
+ .atag_offset = 0x100,
+ .map_io = versatile_map_io,
+ .init_early = versatile_init_early,
+ .init_irq = versatile_init_irq,
+ .init_time = versatile_timer_init,
+ .init_machine = versatile_init,
+ .restart = versatile_restart,
+MACHINE_END
diff --git a/arch/arm/mach-versatile/versatile_dt.c b/arch/arm/mach-versatile/versatile_dt.c
new file mode 100644
index 000000000..7de3e92a1
--- /dev/null
+++ b/arch/arm/mach-versatile/versatile_dt.c
@@ -0,0 +1,50 @@
+/*
+ * Versatile board support using the device tree
+ *
+ * Copyright (C) 2010 Secret Lab Technologies Ltd.
+ * Copyright (C) 2009 Jeremy Kerr <jeremy.kerr@canonical.com>
+ * 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/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "core.h"
+
+static void __init versatile_dt_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table,
+ versatile_auxdata_lookup, NULL);
+}
+
+static const char *const versatile_dt_match[] __initconst = {
+ "arm,versatile-ab",
+ "arm,versatile-pb",
+ NULL,
+};
+
+DT_MACHINE_START(VERSATILE_PB, "ARM-Versatile (Device Tree Support)")
+ .map_io = versatile_map_io,
+ .init_early = versatile_init_early,
+ .init_machine = versatile_dt_init,
+ .dt_compat = versatile_dt_match,
+ .restart = versatile_restart,
+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 000000000..9a53d0bd9
--- /dev/null
+++ b/arch/arm/mach-versatile/versatile_pb.c
@@ -0,0 +1,91 @@
+/*
+ * 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/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,
+};
+
+#define UART3_IRQ { IRQ_SIC_UART3 }
+#define SCI1_IRQ { IRQ_SIC_SCI3 }
+#define MMCI1_IRQ { IRQ_MMCI1A, IRQ_SIC_MMCI1B }
+
+/*
+ * These devices are connected via the DMA APB bridge
+ */
+
+/* FPGA Primecells */
+APB_DEVICE(uart3, "fpga:09", UART3, NULL);
+APB_DEVICE(sci1, "fpga:0a", SCI1, NULL);
+APB_DEVICE(mmc1, "fpga:0b", MMCI1, &mmc1_plat_data);
+
+
+static struct amba_device *amba_devs[] __initdata = {
+ &uart3_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 */
+ .atag_offset = 0x100,
+ .map_io = versatile_map_io,
+ .init_early = versatile_init_early,
+ .init_irq = versatile_init_irq,
+ .init_time = versatile_timer_init,
+ .init_machine = versatile_pb_init,
+ .restart = versatile_restart,
+MACHINE_END
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
new file mode 100644
index 000000000..10f938957
--- /dev/null
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -0,0 +1,82 @@
+menuconfig ARCH_VEXPRESS
+ bool "ARM Ltd. Versatile Express family" if ARCH_MULTI_V7
+ select ARCH_REQUIRE_GPIOLIB
+ select ARCH_SUPPORTS_BIG_ENDIAN
+ select ARM_AMBA
+ select ARM_GIC
+ select ARM_GLOBAL_TIMER
+ select ARM_TIMER_SP804
+ select COMMON_CLK_VERSATILE
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select HAVE_PATA_PLATFORM
+ select ICST
+ select NO_IOPORT_MAP
+ select PLAT_VERSATILE
+ select POWER_RESET
+ select POWER_RESET_VEXPRESS
+ select POWER_SUPPLY
+ select REGULATOR if MMC_ARMMMCI
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ select VEXPRESS_CONFIG
+ select VEXPRESS_SYSCFG
+ select MFD_VEXPRESS_SYSREG
+ help
+ This option enables support for systems using Cortex processor based
+ ARM core and logic (FPGA) tiles on the Versatile Express motherboard,
+ for example:
+
+ - CoreTile Express A5x2 (V2P-CA5s)
+ - CoreTile Express A9x4 (V2P-CA9)
+ - CoreTile Express A15x2 (V2P-CA15)
+ - LogicTile Express 13MG (V2F-2XV6) with A5, A7, A9 or A15 SMMs
+ (Soft Macrocell Models)
+ - Versatile Express RTSMs (Models)
+
+ You must boot using a Flattened Device Tree in order to use these
+ platforms. The traditional (ATAGs) boot method is not usable on
+ these boards with this option.
+
+if ARCH_VEXPRESS
+
+config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
+ bool "Enable A5 and A9 only errata work-arounds"
+ default y
+ select ARM_ERRATA_643719 if SMP
+ select ARM_ERRATA_720789
+ select PL310_ERRATA_753970 if CACHE_L2X0
+ help
+ Provides common dependencies for Versatile Express platforms
+ based on Cortex-A5 and Cortex-A9 processors. In order to
+ build a working kernel, you must also enable relevant core
+ tile support or Flattened Device Tree based support options.
+
+config ARCH_VEXPRESS_DCSCB
+ bool "Dual Cluster System Control Block (DCSCB) support"
+ depends on MCPM
+ select ARM_CCI400_PORT_CTRL
+ help
+ Support for the Dual Cluster System Configuration Block (DCSCB).
+ This is needed to provide CPU and cluster power management
+ on RTSM implementing big.LITTLE.
+
+config ARCH_VEXPRESS_SPC
+ bool "Versatile Express Serial Power Controller (SPC)"
+ select PM_OPP
+ help
+ The TC2 (A15x2 A7x3) versatile express core tile integrates a logic
+ block called Serial Power Controller (SPC) that provides the interface
+ between the dual cluster test-chip and the M3 microcontroller that
+ carries out power management.
+
+config ARCH_VEXPRESS_TC2_PM
+ bool "Versatile Express TC2 power management"
+ depends on MCPM
+ select ARM_CCI400_PORT_CTRL
+ select ARCH_VEXPRESS_SPC
+ select ARM_CPU_SUSPEND
+ help
+ Support for CPU and cluster power management on Versatile Express
+ with a TC2 (A15x2 A7x3) big.LITTLE core tile.
+
+endif
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
new file mode 100644
index 000000000..f5c1006dd
--- /dev/null
+++ b/arch/arm/mach-vexpress/Makefile
@@ -0,0 +1,17 @@
+#
+# Makefile for the linux kernel.
+#
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := \
+ -I$(srctree)/arch/arm/plat-versatile/include
+
+obj-y := v2m.o
+obj-$(CONFIG_ARCH_VEXPRESS_DCSCB) += dcscb.o dcscb_setup.o
+CFLAGS_dcscb.o += -march=armv7-a
+CFLAGS_REMOVE_dcscb.o = -pg
+obj-$(CONFIG_ARCH_VEXPRESS_SPC) += spc.o
+CFLAGS_REMOVE_spc.o = -pg
+obj-$(CONFIG_ARCH_VEXPRESS_TC2_PM) += tc2_pm.o
+CFLAGS_tc2_pm.o += -march=armv7-a
+CFLAGS_REMOVE_tc2_pm.o = -pg
+obj-$(CONFIG_SMP) += platsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
new file mode 100644
index 000000000..2a11d3ac8
--- /dev/null
+++ b/arch/arm/mach-vexpress/core.h
@@ -0,0 +1,5 @@
+bool vexpress_smp_init_ops(void);
+
+extern struct smp_operations vexpress_smp_dt_ops;
+
+extern void vexpress_cpu_die(unsigned int cpu);
diff --git a/arch/arm/mach-vexpress/dcscb.c b/arch/arm/mach-vexpress/dcscb.c
new file mode 100644
index 000000000..5cedcf572
--- /dev/null
+++ b/arch/arm/mach-vexpress/dcscb.c
@@ -0,0 +1,174 @@
+/*
+ * arch/arm/mach-vexpress/dcscb.c - Dual Cluster System Configuration Block
+ *
+ * Created by: Nicolas Pitre, May 2012
+ * Copyright: (C) 2012-2013 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.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/of_address.h>
+#include <linux/vexpress.h>
+#include <linux/arm-cci.h>
+
+#include <asm/mcpm.h>
+#include <asm/proc-fns.h>
+#include <asm/cacheflush.h>
+#include <asm/cputype.h>
+#include <asm/cp15.h>
+
+
+#define RST_HOLD0 0x0
+#define RST_HOLD1 0x4
+#define SYS_SWRESET 0x8
+#define RST_STAT0 0xc
+#define RST_STAT1 0x10
+#define EAG_CFG_R 0x20
+#define EAG_CFG_W 0x24
+#define KFC_CFG_R 0x28
+#define KFC_CFG_W 0x2c
+#define DCS_CFG_R 0x30
+
+static void __iomem *dcscb_base;
+static int dcscb_allcpus_mask[2];
+
+static int dcscb_cpu_powerup(unsigned int cpu, unsigned int cluster)
+{
+ unsigned int rst_hold, cpumask = (1 << cpu);
+
+ pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+ if (cluster >= 2 || !(cpumask & dcscb_allcpus_mask[cluster]))
+ return -EINVAL;
+
+ rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
+ rst_hold &= ~(cpumask | (cpumask << 4));
+ writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
+ return 0;
+}
+
+static int dcscb_cluster_powerup(unsigned int cluster)
+{
+ unsigned int rst_hold;
+
+ pr_debug("%s: cluster %u\n", __func__, cluster);
+ if (cluster >= 2)
+ return -EINVAL;
+
+ /* remove cluster reset and add individual CPU's reset */
+ rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
+ rst_hold &= ~(1 << 8);
+ rst_hold |= dcscb_allcpus_mask[cluster];
+ writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
+ return 0;
+}
+
+static void dcscb_cpu_powerdown_prepare(unsigned int cpu, unsigned int cluster)
+{
+ unsigned int rst_hold;
+
+ pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+ BUG_ON(cluster >= 2 || !((1 << cpu) & dcscb_allcpus_mask[cluster]));
+
+ rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
+ rst_hold |= (1 << cpu);
+ writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
+}
+
+static void dcscb_cluster_powerdown_prepare(unsigned int cluster)
+{
+ unsigned int rst_hold;
+
+ pr_debug("%s: cluster %u\n", __func__, cluster);
+ BUG_ON(cluster >= 2);
+
+ rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
+ rst_hold |= (1 << 8);
+ writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
+}
+
+static void dcscb_cpu_cache_disable(void)
+{
+ /* Disable and flush the local CPU cache. */
+ v7_exit_coherency_flush(louis);
+}
+
+static void dcscb_cluster_cache_disable(void)
+{
+ /* Flush all cache levels for this cluster. */
+ v7_exit_coherency_flush(all);
+
+ /*
+ * A full outer cache flush could be needed at this point
+ * on platforms with such a cache, depending on where the
+ * outer cache sits. In some cases the notion of a "last
+ * cluster standing" would need to be implemented if the
+ * outer cache is shared across clusters. In any case, when
+ * the outer cache needs flushing, there is no concurrent
+ * access to the cache controller to worry about and no
+ * special locking besides what is already provided by the
+ * MCPM state machinery is needed.
+ */
+
+ /*
+ * Disable cluster-level coherency by masking
+ * incoming snoops and DVM messages:
+ */
+ cci_disable_port_by_cpu(read_cpuid_mpidr());
+}
+
+static const struct mcpm_platform_ops dcscb_power_ops = {
+ .cpu_powerup = dcscb_cpu_powerup,
+ .cluster_powerup = dcscb_cluster_powerup,
+ .cpu_powerdown_prepare = dcscb_cpu_powerdown_prepare,
+ .cluster_powerdown_prepare = dcscb_cluster_powerdown_prepare,
+ .cpu_cache_disable = dcscb_cpu_cache_disable,
+ .cluster_cache_disable = dcscb_cluster_cache_disable,
+};
+
+extern void dcscb_power_up_setup(unsigned int affinity_level);
+
+static int __init dcscb_init(void)
+{
+ struct device_node *node;
+ unsigned int cfg;
+ int ret;
+
+ if (!cci_probed())
+ return -ENODEV;
+
+ node = of_find_compatible_node(NULL, NULL, "arm,rtsm,dcscb");
+ if (!node)
+ return -ENODEV;
+ dcscb_base = of_iomap(node, 0);
+ if (!dcscb_base)
+ return -EADDRNOTAVAIL;
+ cfg = readl_relaxed(dcscb_base + DCS_CFG_R);
+ dcscb_allcpus_mask[0] = (1 << (((cfg >> 16) >> (0 << 2)) & 0xf)) - 1;
+ dcscb_allcpus_mask[1] = (1 << (((cfg >> 16) >> (1 << 2)) & 0xf)) - 1;
+
+ ret = mcpm_platform_register(&dcscb_power_ops);
+ if (!ret)
+ ret = mcpm_sync_init(dcscb_power_up_setup);
+ if (ret) {
+ iounmap(dcscb_base);
+ return ret;
+ }
+
+ pr_info("VExpress DCSCB support installed\n");
+
+ /*
+ * Future entries into the kernel can now go
+ * through the cluster entry vectors.
+ */
+ vexpress_flags_set(virt_to_phys(mcpm_entry_point));
+
+ return 0;
+}
+
+early_initcall(dcscb_init);
diff --git a/arch/arm/mach-vexpress/dcscb_setup.S b/arch/arm/mach-vexpress/dcscb_setup.S
new file mode 100644
index 000000000..4bb7fbe0f
--- /dev/null
+++ b/arch/arm/mach-vexpress/dcscb_setup.S
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/include/asm/dcscb_setup.S
+ *
+ * Created by: Dave Martin, 2012-06-22
+ * Copyright: (C) 2012-2013 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.
+ */
+
+#include <linux/linkage.h>
+
+
+ENTRY(dcscb_power_up_setup)
+
+ cmp r0, #0 @ check affinity level
+ beq 2f
+
+/*
+ * Enable cluster-level coherency, in preparation for turning on the MMU.
+ * The ACTLR SMP bit does not need to be set here, because cpu_resume()
+ * already restores that.
+ *
+ * A15/A7 may not require explicit L2 invalidation on reset, dependent
+ * on hardware integration decisions.
+ * For now, this code assumes that L2 is either already invalidated,
+ * or invalidation is not required.
+ */
+
+ b cci_enable_port_for_self
+
+2: @ Implementation-specific local CPU setup operations should go here,
+ @ if any. In this case, there is nothing to do.
+
+ bx lr
+
+ENDPROC(dcscb_power_up_setup)
diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c
new file mode 100644
index 000000000..f0ce6b8f5
--- /dev/null
+++ b/arch/arm/mach-vexpress/hotplug.c
@@ -0,0 +1,106 @@
+/*
+ * 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/smp_plat.h>
+#include <asm/cp15.h>
+
+static inline void cpu_enter_lowpower(void)
+{
+ unsigned int v;
+
+ 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 (;;) {
+ wfi();
+
+ if (pen_release == cpu_logical_map(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)++;
+ }
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void __ref vexpress_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);
+}
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
new file mode 100644
index 000000000..83188cf18
--- /dev/null
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -0,0 +1,74 @@
+/*
+ * 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 <linux/of_address.h>
+#include <linux/vexpress.h>
+
+#include <asm/mcpm.h>
+#include <asm/smp_scu.h>
+#include <asm/mach/map.h>
+
+#include <plat/platsmp.h>
+
+#include "core.h"
+
+bool __init vexpress_smp_init_ops(void)
+{
+#ifdef CONFIG_MCPM
+ /*
+ * The best way to detect a multi-cluster configuration at the moment
+ * is to look for the presence of a CCI in the system.
+ * Override the default vexpress_smp_ops if so.
+ */
+ struct device_node *node;
+ node = of_find_compatible_node(NULL, NULL, "arm,cci-400");
+ if (node && of_device_is_available(node)) {
+ mcpm_smp_set_ops();
+ return true;
+ }
+#endif
+ return false;
+}
+
+static const struct of_device_id vexpress_smp_dt_scu_match[] __initconst = {
+ { .compatible = "arm,cortex-a5-scu", },
+ { .compatible = "arm,cortex-a9-scu", },
+ {}
+};
+
+static void __init vexpress_smp_dt_prepare_cpus(unsigned int max_cpus)
+{
+ struct device_node *scu = of_find_matching_node(NULL,
+ vexpress_smp_dt_scu_match);
+
+ if (scu)
+ scu_enable(of_iomap(scu, 0));
+
+ /*
+ * 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.
+ */
+ vexpress_flags_set(virt_to_phys(versatile_secondary_startup));
+}
+
+struct smp_operations __initdata vexpress_smp_dt_ops = {
+ .smp_prepare_cpus = vexpress_smp_dt_prepare_cpus,
+ .smp_secondary_init = versatile_secondary_init,
+ .smp_boot_secondary = versatile_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = vexpress_cpu_die,
+#endif
+};
diff --git a/arch/arm/mach-vexpress/spc.c b/arch/arm/mach-vexpress/spc.c
new file mode 100644
index 000000000..f61158c6c
--- /dev/null
+++ b/arch/arm/mach-vexpress/spc.c
@@ -0,0 +1,592 @@
+/*
+ * Versatile Express Serial Power Controller (SPC) support
+ *
+ * Copyright (C) 2013 ARM Ltd.
+ *
+ * Authors: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
+ * Achin Gupta <achin.gupta@arm.com>
+ * Lorenzo Pieralisi <lorenzo.pieralisi@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 "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/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/cpu.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
+#include <linux/semaphore.h>
+
+#include <asm/cacheflush.h>
+
+#define SPCLOG "vexpress-spc: "
+
+#define PERF_LVL_A15 0x00
+#define PERF_REQ_A15 0x04
+#define PERF_LVL_A7 0x08
+#define PERF_REQ_A7 0x0c
+#define COMMS 0x10
+#define COMMS_REQ 0x14
+#define PWC_STATUS 0x18
+#define PWC_FLAG 0x1c
+
+/* SPC wake-up IRQs status and mask */
+#define WAKE_INT_MASK 0x24
+#define WAKE_INT_RAW 0x28
+#define WAKE_INT_STAT 0x2c
+/* SPC power down registers */
+#define A15_PWRDN_EN 0x30
+#define A7_PWRDN_EN 0x34
+/* SPC per-CPU mailboxes */
+#define A15_BX_ADDR0 0x68
+#define A7_BX_ADDR0 0x78
+
+/* SPC CPU/cluster reset statue */
+#define STANDBYWFI_STAT 0x3c
+#define STANDBYWFI_STAT_A15_CPU_MASK(cpu) (1 << (cpu))
+#define STANDBYWFI_STAT_A7_CPU_MASK(cpu) (1 << (3 + (cpu)))
+
+/* SPC system config interface registers */
+#define SYSCFG_WDATA 0x70
+#define SYSCFG_RDATA 0x74
+
+/* A15/A7 OPP virtual register base */
+#define A15_PERFVAL_BASE 0xC10
+#define A7_PERFVAL_BASE 0xC30
+
+/* Config interface control bits */
+#define SYSCFG_START (1 << 31)
+#define SYSCFG_SCC (6 << 20)
+#define SYSCFG_STAT (14 << 20)
+
+/* wake-up interrupt masks */
+#define GBL_WAKEUP_INT_MSK (0x3 << 10)
+
+/* TC2 static dual-cluster configuration */
+#define MAX_CLUSTERS 2
+
+/*
+ * Even though the SPC takes max 3-5 ms to complete any OPP/COMMS
+ * operation, the operation could start just before jiffie is about
+ * to be incremented. So setting timeout value of 20ms = 2jiffies@100Hz
+ */
+#define TIMEOUT_US 20000
+
+#define MAX_OPPS 8
+#define CA15_DVFS 0
+#define CA7_DVFS 1
+#define SPC_SYS_CFG 2
+#define STAT_COMPLETE(type) ((1 << 0) << (type << 2))
+#define STAT_ERR(type) ((1 << 1) << (type << 2))
+#define RESPONSE_MASK(type) (STAT_COMPLETE(type) | STAT_ERR(type))
+
+struct ve_spc_opp {
+ unsigned long freq;
+ unsigned long u_volt;
+};
+
+struct ve_spc_drvdata {
+ void __iomem *baseaddr;
+ /*
+ * A15s cluster identifier
+ * It corresponds to A15 processors MPIDR[15:8] bitfield
+ */
+ u32 a15_clusid;
+ uint32_t cur_rsp_mask;
+ uint32_t cur_rsp_stat;
+ struct semaphore sem;
+ struct completion done;
+ struct ve_spc_opp *opps[MAX_CLUSTERS];
+ int num_opps[MAX_CLUSTERS];
+};
+
+static struct ve_spc_drvdata *info;
+
+static inline bool cluster_is_a15(u32 cluster)
+{
+ return cluster == info->a15_clusid;
+}
+
+/**
+ * ve_spc_global_wakeup_irq()
+ *
+ * Function to set/clear global wakeup IRQs. Not protected by locking since
+ * it might be used in code paths where normal cacheable locks are not
+ * working. Locking must be provided by the caller to ensure atomicity.
+ *
+ * @set: if true, global wake-up IRQs are set, if false they are cleared
+ */
+void ve_spc_global_wakeup_irq(bool set)
+{
+ u32 reg;
+
+ reg = readl_relaxed(info->baseaddr + WAKE_INT_MASK);
+
+ if (set)
+ reg |= GBL_WAKEUP_INT_MSK;
+ else
+ reg &= ~GBL_WAKEUP_INT_MSK;
+
+ writel_relaxed(reg, info->baseaddr + WAKE_INT_MASK);
+}
+
+/**
+ * ve_spc_cpu_wakeup_irq()
+ *
+ * Function to set/clear per-CPU wake-up IRQs. Not protected by locking since
+ * it might be used in code paths where normal cacheable locks are not
+ * working. Locking must be provided by the caller to ensure atomicity.
+ *
+ * @cluster: mpidr[15:8] bitfield describing cluster affinity level
+ * @cpu: mpidr[7:0] bitfield describing cpu affinity level
+ * @set: if true, wake-up IRQs are set, if false they are cleared
+ */
+void ve_spc_cpu_wakeup_irq(u32 cluster, u32 cpu, bool set)
+{
+ u32 mask, reg;
+
+ if (cluster >= MAX_CLUSTERS)
+ return;
+
+ mask = 1 << cpu;
+
+ if (!cluster_is_a15(cluster))
+ mask <<= 4;
+
+ reg = readl_relaxed(info->baseaddr + WAKE_INT_MASK);
+
+ if (set)
+ reg |= mask;
+ else
+ reg &= ~mask;
+
+ writel_relaxed(reg, info->baseaddr + WAKE_INT_MASK);
+}
+
+/**
+ * ve_spc_set_resume_addr() - set the jump address used for warm boot
+ *
+ * @cluster: mpidr[15:8] bitfield describing cluster affinity level
+ * @cpu: mpidr[7:0] bitfield describing cpu affinity level
+ * @addr: physical resume address
+ */
+void ve_spc_set_resume_addr(u32 cluster, u32 cpu, u32 addr)
+{
+ void __iomem *baseaddr;
+
+ if (cluster >= MAX_CLUSTERS)
+ return;
+
+ if (cluster_is_a15(cluster))
+ baseaddr = info->baseaddr + A15_BX_ADDR0 + (cpu << 2);
+ else
+ baseaddr = info->baseaddr + A7_BX_ADDR0 + (cpu << 2);
+
+ writel_relaxed(addr, baseaddr);
+}
+
+/**
+ * ve_spc_powerdown()
+ *
+ * Function to enable/disable cluster powerdown. Not protected by locking
+ * since it might be used in code paths where normal cacheable locks are not
+ * working. Locking must be provided by the caller to ensure atomicity.
+ *
+ * @cluster: mpidr[15:8] bitfield describing cluster affinity level
+ * @enable: if true enables powerdown, if false disables it
+ */
+void ve_spc_powerdown(u32 cluster, bool enable)
+{
+ u32 pwdrn_reg;
+
+ if (cluster >= MAX_CLUSTERS)
+ return;
+
+ pwdrn_reg = cluster_is_a15(cluster) ? A15_PWRDN_EN : A7_PWRDN_EN;
+ writel_relaxed(enable, info->baseaddr + pwdrn_reg);
+}
+
+static u32 standbywfi_cpu_mask(u32 cpu, u32 cluster)
+{
+ return cluster_is_a15(cluster) ?
+ STANDBYWFI_STAT_A15_CPU_MASK(cpu)
+ : STANDBYWFI_STAT_A7_CPU_MASK(cpu);
+}
+
+/**
+ * ve_spc_cpu_in_wfi(u32 cpu, u32 cluster)
+ *
+ * @cpu: mpidr[7:0] bitfield describing CPU affinity level within cluster
+ * @cluster: mpidr[15:8] bitfield describing cluster affinity level
+ *
+ * @return: non-zero if and only if the specified CPU is in WFI
+ *
+ * Take care when interpreting the result of this function: a CPU might
+ * be in WFI temporarily due to idle, and is not necessarily safely
+ * parked.
+ */
+int ve_spc_cpu_in_wfi(u32 cpu, u32 cluster)
+{
+ int ret;
+ u32 mask = standbywfi_cpu_mask(cpu, cluster);
+
+ if (cluster >= MAX_CLUSTERS)
+ return 1;
+
+ ret = readl_relaxed(info->baseaddr + STANDBYWFI_STAT);
+
+ pr_debug("%s: PCFGREG[0x%X] = 0x%08X, mask = 0x%X\n",
+ __func__, STANDBYWFI_STAT, ret, mask);
+
+ return ret & mask;
+}
+
+static int ve_spc_get_performance(int cluster, u32 *freq)
+{
+ struct ve_spc_opp *opps = info->opps[cluster];
+ u32 perf_cfg_reg = 0;
+ u32 perf;
+
+ perf_cfg_reg = cluster_is_a15(cluster) ? PERF_LVL_A15 : PERF_LVL_A7;
+
+ perf = readl_relaxed(info->baseaddr + perf_cfg_reg);
+ if (perf >= info->num_opps[cluster])
+ return -EINVAL;
+
+ opps += perf;
+ *freq = opps->freq;
+
+ return 0;
+}
+
+/* find closest match to given frequency in OPP table */
+static int ve_spc_round_performance(int cluster, u32 freq)
+{
+ int idx, max_opp = info->num_opps[cluster];
+ struct ve_spc_opp *opps = info->opps[cluster];
+ u32 fmin = 0, fmax = ~0, ftmp;
+
+ freq /= 1000; /* OPP entries in kHz */
+ for (idx = 0; idx < max_opp; idx++, opps++) {
+ ftmp = opps->freq;
+ if (ftmp >= freq) {
+ if (ftmp <= fmax)
+ fmax = ftmp;
+ } else {
+ if (ftmp >= fmin)
+ fmin = ftmp;
+ }
+ }
+ if (fmax != ~0)
+ return fmax * 1000;
+ else
+ return fmin * 1000;
+}
+
+static int ve_spc_find_performance_index(int cluster, u32 freq)
+{
+ int idx, max_opp = info->num_opps[cluster];
+ struct ve_spc_opp *opps = info->opps[cluster];
+
+ for (idx = 0; idx < max_opp; idx++, opps++)
+ if (opps->freq == freq)
+ break;
+ return (idx == max_opp) ? -EINVAL : idx;
+}
+
+static int ve_spc_waitforcompletion(int req_type)
+{
+ int ret = wait_for_completion_interruptible_timeout(
+ &info->done, usecs_to_jiffies(TIMEOUT_US));
+ if (ret == 0)
+ ret = -ETIMEDOUT;
+ else if (ret > 0)
+ ret = info->cur_rsp_stat & STAT_COMPLETE(req_type) ? 0 : -EIO;
+ return ret;
+}
+
+static int ve_spc_set_performance(int cluster, u32 freq)
+{
+ u32 perf_cfg_reg, perf_stat_reg;
+ int ret, perf, req_type;
+
+ if (cluster_is_a15(cluster)) {
+ req_type = CA15_DVFS;
+ perf_cfg_reg = PERF_LVL_A15;
+ perf_stat_reg = PERF_REQ_A15;
+ } else {
+ req_type = CA7_DVFS;
+ perf_cfg_reg = PERF_LVL_A7;
+ perf_stat_reg = PERF_REQ_A7;
+ }
+
+ perf = ve_spc_find_performance_index(cluster, freq);
+
+ if (perf < 0)
+ return perf;
+
+ if (down_timeout(&info->sem, usecs_to_jiffies(TIMEOUT_US)))
+ return -ETIME;
+
+ init_completion(&info->done);
+ info->cur_rsp_mask = RESPONSE_MASK(req_type);
+
+ writel(perf, info->baseaddr + perf_cfg_reg);
+ ret = ve_spc_waitforcompletion(req_type);
+
+ info->cur_rsp_mask = 0;
+ up(&info->sem);
+
+ return ret;
+}
+
+static int ve_spc_read_sys_cfg(int func, int offset, uint32_t *data)
+{
+ int ret;
+
+ if (down_timeout(&info->sem, usecs_to_jiffies(TIMEOUT_US)))
+ return -ETIME;
+
+ init_completion(&info->done);
+ info->cur_rsp_mask = RESPONSE_MASK(SPC_SYS_CFG);
+
+ /* Set the control value */
+ writel(SYSCFG_START | func | offset >> 2, info->baseaddr + COMMS);
+ ret = ve_spc_waitforcompletion(SPC_SYS_CFG);
+
+ if (ret == 0)
+ *data = readl(info->baseaddr + SYSCFG_RDATA);
+
+ info->cur_rsp_mask = 0;
+ up(&info->sem);
+
+ return ret;
+}
+
+static irqreturn_t ve_spc_irq_handler(int irq, void *data)
+{
+ struct ve_spc_drvdata *drv_data = data;
+ uint32_t status = readl_relaxed(drv_data->baseaddr + PWC_STATUS);
+
+ if (info->cur_rsp_mask & status) {
+ info->cur_rsp_stat = status;
+ complete(&drv_data->done);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * +--------------------------+
+ * | 31 20 | 19 0 |
+ * +--------------------------+
+ * | m_volt | freq(kHz) |
+ * +--------------------------+
+ */
+#define MULT_FACTOR 20
+#define VOLT_SHIFT 20
+#define FREQ_MASK (0xFFFFF)
+static int ve_spc_populate_opps(uint32_t cluster)
+{
+ uint32_t data = 0, off, ret, idx;
+ struct ve_spc_opp *opps;
+
+ opps = kzalloc(sizeof(*opps) * MAX_OPPS, GFP_KERNEL);
+ if (!opps)
+ return -ENOMEM;
+
+ info->opps[cluster] = opps;
+
+ off = cluster_is_a15(cluster) ? A15_PERFVAL_BASE : A7_PERFVAL_BASE;
+ for (idx = 0; idx < MAX_OPPS; idx++, off += 4, opps++) {
+ ret = ve_spc_read_sys_cfg(SYSCFG_SCC, off, &data);
+ if (!ret) {
+ opps->freq = (data & FREQ_MASK) * MULT_FACTOR;
+ opps->u_volt = (data >> VOLT_SHIFT) * 1000;
+ } else {
+ break;
+ }
+ }
+ info->num_opps[cluster] = idx;
+
+ return ret;
+}
+
+static int ve_init_opp_table(struct device *cpu_dev)
+{
+ int cluster;
+ int idx, ret = 0, max_opp;
+ struct ve_spc_opp *opps;
+
+ cluster = topology_physical_package_id(cpu_dev->id);
+ cluster = cluster < 0 ? 0 : cluster;
+
+ max_opp = info->num_opps[cluster];
+ opps = info->opps[cluster];
+
+ for (idx = 0; idx < max_opp; idx++, opps++) {
+ ret = dev_pm_opp_add(cpu_dev, opps->freq * 1000, opps->u_volt);
+ if (ret) {
+ dev_warn(cpu_dev, "failed to add opp %lu %lu\n",
+ opps->freq, opps->u_volt);
+ return ret;
+ }
+ }
+ return ret;
+}
+
+int __init ve_spc_init(void __iomem *baseaddr, u32 a15_clusid, int irq)
+{
+ int ret;
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info) {
+ pr_err(SPCLOG "unable to allocate mem\n");
+ return -ENOMEM;
+ }
+
+ info->baseaddr = baseaddr;
+ info->a15_clusid = a15_clusid;
+
+ if (irq <= 0) {
+ pr_err(SPCLOG "Invalid IRQ %d\n", irq);
+ kfree(info);
+ return -EINVAL;
+ }
+
+ init_completion(&info->done);
+
+ readl_relaxed(info->baseaddr + PWC_STATUS);
+
+ ret = request_irq(irq, ve_spc_irq_handler, IRQF_TRIGGER_HIGH
+ | IRQF_ONESHOT, "vexpress-spc", info);
+ if (ret) {
+ pr_err(SPCLOG "IRQ %d request failed\n", irq);
+ kfree(info);
+ return -ENODEV;
+ }
+
+ sema_init(&info->sem, 1);
+ /*
+ * Multi-cluster systems may need this data when non-coherent, during
+ * cluster power-up/power-down. Make sure driver info reaches main
+ * memory.
+ */
+ sync_cache_w(info);
+ sync_cache_w(&info);
+
+ return 0;
+}
+
+struct clk_spc {
+ struct clk_hw hw;
+ int cluster;
+};
+
+#define to_clk_spc(spc) container_of(spc, struct clk_spc, hw)
+static unsigned long spc_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_spc *spc = to_clk_spc(hw);
+ u32 freq;
+
+ if (ve_spc_get_performance(spc->cluster, &freq))
+ return -EIO;
+
+ return freq * 1000;
+}
+
+static long spc_round_rate(struct clk_hw *hw, unsigned long drate,
+ unsigned long *parent_rate)
+{
+ struct clk_spc *spc = to_clk_spc(hw);
+
+ return ve_spc_round_performance(spc->cluster, drate);
+}
+
+static int spc_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_spc *spc = to_clk_spc(hw);
+
+ return ve_spc_set_performance(spc->cluster, rate / 1000);
+}
+
+static struct clk_ops clk_spc_ops = {
+ .recalc_rate = spc_recalc_rate,
+ .round_rate = spc_round_rate,
+ .set_rate = spc_set_rate,
+};
+
+static struct clk *ve_spc_clk_register(struct device *cpu_dev)
+{
+ struct clk_init_data init;
+ struct clk_spc *spc;
+
+ spc = kzalloc(sizeof(*spc), GFP_KERNEL);
+ if (!spc) {
+ pr_err("could not allocate spc clk\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ spc->hw.init = &init;
+ spc->cluster = topology_physical_package_id(cpu_dev->id);
+
+ spc->cluster = spc->cluster < 0 ? 0 : spc->cluster;
+
+ init.name = dev_name(cpu_dev);
+ init.ops = &clk_spc_ops;
+ init.flags = CLK_IS_ROOT | CLK_GET_RATE_NOCACHE;
+ init.num_parents = 0;
+
+ return devm_clk_register(cpu_dev, &spc->hw);
+}
+
+static int __init ve_spc_clk_init(void)
+{
+ int cpu;
+ struct clk *clk;
+
+ if (!info)
+ return 0; /* Continue only if SPC is initialised */
+
+ if (ve_spc_populate_opps(0) || ve_spc_populate_opps(1)) {
+ pr_err("failed to build OPP table\n");
+ return -ENODEV;
+ }
+
+ for_each_possible_cpu(cpu) {
+ struct device *cpu_dev = get_cpu_device(cpu);
+ if (!cpu_dev) {
+ pr_warn("failed to get cpu%d device\n", cpu);
+ continue;
+ }
+ clk = ve_spc_clk_register(cpu_dev);
+ if (IS_ERR(clk)) {
+ pr_warn("failed to register cpu%d clock\n", cpu);
+ continue;
+ }
+ if (clk_register_clkdev(clk, NULL, dev_name(cpu_dev))) {
+ pr_warn("failed to register cpu%d clock lookup\n", cpu);
+ continue;
+ }
+
+ if (ve_init_opp_table(cpu_dev))
+ pr_warn("failed to initialise cpu%d opp table\n", cpu);
+ }
+
+ platform_device_register_simple("vexpress-spc-cpufreq", -1, NULL, 0);
+ return 0;
+}
+module_init(ve_spc_clk_init);
diff --git a/arch/arm/mach-vexpress/spc.h b/arch/arm/mach-vexpress/spc.h
new file mode 100644
index 000000000..793d06524
--- /dev/null
+++ b/arch/arm/mach-vexpress/spc.h
@@ -0,0 +1,25 @@
+/*
+ * This program is free software; you can 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.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+
+#ifndef __SPC_H_
+#define __SPC_H_
+
+int __init ve_spc_init(void __iomem *base, u32 a15_clusid, int irq);
+void ve_spc_global_wakeup_irq(bool set);
+void ve_spc_cpu_wakeup_irq(u32 cluster, u32 cpu, bool set);
+void ve_spc_set_resume_addr(u32 cluster, u32 cpu, u32 addr);
+void ve_spc_powerdown(u32 cluster, bool enable);
+int ve_spc_cpu_in_wfi(u32 cpu, u32 cluster);
+
+#endif
diff --git a/arch/arm/mach-vexpress/tc2_pm.c b/arch/arm/mach-vexpress/tc2_pm.c
new file mode 100644
index 000000000..b3328cd46
--- /dev/null
+++ b/arch/arm/mach-vexpress/tc2_pm.c
@@ -0,0 +1,266 @@
+/*
+ * arch/arm/mach-vexpress/tc2_pm.c - TC2 power management support
+ *
+ * Created by: Nicolas Pitre, October 2012
+ * Copyright: (C) 2012-2013 Linaro Limited
+ *
+ * Some portions of this file were originally written by Achin Gupta
+ * Copyright: (C) 2012 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/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/errno.h>
+#include <linux/irqchip/arm-gic.h>
+
+#include <asm/mcpm.h>
+#include <asm/proc-fns.h>
+#include <asm/cacheflush.h>
+#include <asm/cputype.h>
+#include <asm/cp15.h>
+
+#include <linux/arm-cci.h>
+
+#include "spc.h"
+
+/* SCC conf registers */
+#define RESET_CTRL 0x018
+#define RESET_A15_NCORERESET(cpu) (1 << (2 + (cpu)))
+#define RESET_A7_NCORERESET(cpu) (1 << (16 + (cpu)))
+
+#define A15_CONF 0x400
+#define A7_CONF 0x500
+#define SYS_INFO 0x700
+#define SPC_BASE 0xb00
+
+static void __iomem *scc;
+
+#define TC2_CLUSTERS 2
+#define TC2_MAX_CPUS_PER_CLUSTER 3
+
+static unsigned int tc2_nr_cpus[TC2_CLUSTERS];
+
+static int tc2_pm_cpu_powerup(unsigned int cpu, unsigned int cluster)
+{
+ pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+ if (cluster >= TC2_CLUSTERS || cpu >= tc2_nr_cpus[cluster])
+ return -EINVAL;
+ ve_spc_set_resume_addr(cluster, cpu,
+ virt_to_phys(mcpm_entry_point));
+ ve_spc_cpu_wakeup_irq(cluster, cpu, true);
+ return 0;
+}
+
+static int tc2_pm_cluster_powerup(unsigned int cluster)
+{
+ pr_debug("%s: cluster %u\n", __func__, cluster);
+ if (cluster >= TC2_CLUSTERS)
+ return -EINVAL;
+ ve_spc_powerdown(cluster, false);
+ return 0;
+}
+
+static void tc2_pm_cpu_powerdown_prepare(unsigned int cpu, unsigned int cluster)
+{
+ pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+ BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
+ ve_spc_cpu_wakeup_irq(cluster, cpu, true);
+ /*
+ * If the CPU is committed to power down, make sure
+ * the power controller will be in charge of waking it
+ * up upon IRQ, ie IRQ lines are cut from GIC CPU IF
+ * to the CPU by disabling the GIC CPU IF to prevent wfi
+ * from completing execution behind power controller back
+ */
+ gic_cpu_if_down();
+}
+
+static void tc2_pm_cluster_powerdown_prepare(unsigned int cluster)
+{
+ pr_debug("%s: cluster %u\n", __func__, cluster);
+ BUG_ON(cluster >= TC2_CLUSTERS);
+ ve_spc_powerdown(cluster, true);
+ ve_spc_global_wakeup_irq(true);
+}
+
+static void tc2_pm_cpu_cache_disable(void)
+{
+ v7_exit_coherency_flush(louis);
+}
+
+static void tc2_pm_cluster_cache_disable(void)
+{
+ if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A15) {
+ /*
+ * On the Cortex-A15 we need to disable
+ * L2 prefetching before flushing the cache.
+ */
+ asm volatile(
+ "mcr p15, 1, %0, c15, c0, 3 \n\t"
+ "isb \n\t"
+ "dsb "
+ : : "r" (0x400) );
+ }
+
+ v7_exit_coherency_flush(all);
+ cci_disable_port_by_cpu(read_cpuid_mpidr());
+}
+
+static int tc2_core_in_reset(unsigned int cpu, unsigned int cluster)
+{
+ u32 mask = cluster ?
+ RESET_A7_NCORERESET(cpu)
+ : RESET_A15_NCORERESET(cpu);
+
+ return !(readl_relaxed(scc + RESET_CTRL) & mask);
+}
+
+#define POLL_MSEC 10
+#define TIMEOUT_MSEC 1000
+
+static int tc2_pm_wait_for_powerdown(unsigned int cpu, unsigned int cluster)
+{
+ unsigned tries;
+
+ pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+ BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
+
+ for (tries = 0; tries < TIMEOUT_MSEC / POLL_MSEC; ++tries) {
+ pr_debug("%s(cpu=%u, cluster=%u): RESET_CTRL = 0x%08X\n",
+ __func__, cpu, cluster,
+ readl_relaxed(scc + RESET_CTRL));
+
+ /*
+ * We need the CPU to reach WFI, but the power
+ * controller may put the cluster in reset and
+ * power it off as soon as that happens, before
+ * we have a chance to see STANDBYWFI.
+ *
+ * So we need to check for both conditions:
+ */
+ if (tc2_core_in_reset(cpu, cluster) ||
+ ve_spc_cpu_in_wfi(cpu, cluster))
+ return 0; /* success: the CPU is halted */
+
+ /* Otherwise, wait and retry: */
+ msleep(POLL_MSEC);
+ }
+
+ return -ETIMEDOUT; /* timeout */
+}
+
+static void tc2_pm_cpu_suspend_prepare(unsigned int cpu, unsigned int cluster)
+{
+ ve_spc_set_resume_addr(cluster, cpu, virt_to_phys(mcpm_entry_point));
+}
+
+static void tc2_pm_cpu_is_up(unsigned int cpu, unsigned int cluster)
+{
+ pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+ BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
+ ve_spc_cpu_wakeup_irq(cluster, cpu, false);
+ ve_spc_set_resume_addr(cluster, cpu, 0);
+}
+
+static void tc2_pm_cluster_is_up(unsigned int cluster)
+{
+ pr_debug("%s: cluster %u\n", __func__, cluster);
+ BUG_ON(cluster >= TC2_CLUSTERS);
+ ve_spc_powerdown(cluster, false);
+ ve_spc_global_wakeup_irq(false);
+}
+
+static const struct mcpm_platform_ops tc2_pm_power_ops = {
+ .cpu_powerup = tc2_pm_cpu_powerup,
+ .cluster_powerup = tc2_pm_cluster_powerup,
+ .cpu_suspend_prepare = tc2_pm_cpu_suspend_prepare,
+ .cpu_powerdown_prepare = tc2_pm_cpu_powerdown_prepare,
+ .cluster_powerdown_prepare = tc2_pm_cluster_powerdown_prepare,
+ .cpu_cache_disable = tc2_pm_cpu_cache_disable,
+ .cluster_cache_disable = tc2_pm_cluster_cache_disable,
+ .wait_for_powerdown = tc2_pm_wait_for_powerdown,
+ .cpu_is_up = tc2_pm_cpu_is_up,
+ .cluster_is_up = tc2_pm_cluster_is_up,
+};
+
+/*
+ * Enable cluster-level coherency, in preparation for turning on the MMU.
+ */
+static void __naked tc2_pm_power_up_setup(unsigned int affinity_level)
+{
+ asm volatile (" \n"
+" cmp r0, #1 \n"
+" bxne lr \n"
+" b cci_enable_port_for_self ");
+}
+
+static int __init tc2_pm_init(void)
+{
+ unsigned int mpidr, cpu, cluster;
+ int ret, irq;
+ u32 a15_cluster_id, a7_cluster_id, sys_info;
+ struct device_node *np;
+
+ /*
+ * The power management-related features are hidden behind
+ * SCC registers. We need to extract runtime information like
+ * cluster ids and number of CPUs really available in clusters.
+ */
+ np = of_find_compatible_node(NULL, NULL,
+ "arm,vexpress-scc,v2p-ca15_a7");
+ scc = of_iomap(np, 0);
+ if (!scc)
+ return -ENODEV;
+
+ a15_cluster_id = readl_relaxed(scc + A15_CONF) & 0xf;
+ a7_cluster_id = readl_relaxed(scc + A7_CONF) & 0xf;
+ if (a15_cluster_id >= TC2_CLUSTERS || a7_cluster_id >= TC2_CLUSTERS)
+ return -EINVAL;
+
+ sys_info = readl_relaxed(scc + SYS_INFO);
+ tc2_nr_cpus[a15_cluster_id] = (sys_info >> 16) & 0xf;
+ tc2_nr_cpus[a7_cluster_id] = (sys_info >> 20) & 0xf;
+
+ irq = irq_of_parse_and_map(np, 0);
+
+ /*
+ * A subset of the SCC registers is also used to communicate
+ * with the SPC (power controller). We need to be able to
+ * drive it very early in the boot process to power up
+ * processors, so we initialize the SPC driver here.
+ */
+ ret = ve_spc_init(scc + SPC_BASE, a15_cluster_id, irq);
+ if (ret)
+ return ret;
+
+ if (!cci_probed())
+ return -ENODEV;
+
+ mpidr = read_cpuid_mpidr();
+ cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+ pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+ if (cluster >= TC2_CLUSTERS || cpu >= tc2_nr_cpus[cluster]) {
+ pr_err("%s: boot CPU is out of bound!\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = mcpm_platform_register(&tc2_pm_power_ops);
+ if (!ret) {
+ mcpm_sync_init(tc2_pm_power_up_setup);
+ /* test if we can (re)enable the CCI on our own */
+ BUG_ON(mcpm_loopback(tc2_pm_cluster_cache_disable) != 0);
+ pr_info("TC2 power management initialized\n");
+ }
+ return ret;
+}
+
+early_initcall(tc2_pm_init);
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
new file mode 100644
index 000000000..a0400f4cc
--- /dev/null
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -0,0 +1,16 @@
+#include <asm/mach/arch.h>
+
+#include "core.h"
+
+static const char * const v2m_dt_match[] __initconst = {
+ "arm,vexpress",
+ NULL,
+};
+
+DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express")
+ .dt_compat = v2m_dt_match,
+ .l2c_aux_val = 0x00400000,
+ .l2c_aux_mask = 0xfe0fffff,
+ .smp = smp_ops(vexpress_smp_dt_ops),
+ .smp_init = smp_init_ops(vexpress_smp_init_ops),
+MACHINE_END
diff --git a/arch/arm/mach-vt8500/Kconfig b/arch/arm/mach-vt8500/Kconfig
new file mode 100644
index 000000000..aaaa24fe4
--- /dev/null
+++ b/arch/arm/mach-vt8500/Kconfig
@@ -0,0 +1,29 @@
+config ARCH_VT8500
+ bool
+ select ARCH_REQUIRE_GPIOLIB
+ select CLKDEV_LOOKUP
+ select VT8500_TIMER
+ select PINCTRL
+ help
+ Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
+
+config ARCH_WM8505
+ bool "VIA/Wondermedia 85xx and WM8650"
+ depends on ARCH_MULTI_V5
+ select ARCH_VT8500
+ select CPU_ARM926T
+ help
+
+config ARCH_WM8750
+ bool "WonderMedia WM8750"
+ depends on ARCH_MULTI_V6
+ select ARCH_VT8500
+ help
+ Support for WonderMedia WM8750 System-on-Chip.
+
+config ARCH_WM8850
+ bool "WonderMedia WM8850"
+ depends on ARCH_MULTI_V7
+ select ARCH_VT8500
+ help
+ Support for WonderMedia WM8850 System-on-Chip.
diff --git a/arch/arm/mach-vt8500/Makefile b/arch/arm/mach-vt8500/Makefile
new file mode 100644
index 000000000..4c8a84637
--- /dev/null
+++ b/arch/arm/mach-vt8500/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_VT8500) += vt8500.o
diff --git a/arch/arm/mach-vt8500/Makefile.boot b/arch/arm/mach-vt8500/Makefile.boot
new file mode 100644
index 000000000..b79c41cdf
--- /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/vt8500.c b/arch/arm/mach-vt8500/vt8500.c
new file mode 100644
index 000000000..3bc0dc9a4
--- /dev/null
+++ b/arch/arm/mach-vt8500/vt8500.c
@@ -0,0 +1,180 @@
+/*
+ * arch/arm/mach-vt8500/vt8500.c
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 <linux/reboot.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+
+#define LEGACY_GPIO_BASE 0xD8110000
+#define LEGACY_PMC_BASE 0xD8130000
+
+/* Registers in GPIO Controller */
+#define VT8500_GPIO_MUX_REG 0x200
+
+/* Registers in Power Management Controller */
+#define VT8500_HCR_REG 0x12
+#define VT8500_PMSR_REG 0x60
+
+static void __iomem *pmc_base;
+
+static void vt8500_restart(enum reboot_mode mode, const char *cmd)
+{
+ if (pmc_base)
+ writel(1, pmc_base + VT8500_PMSR_REG);
+}
+
+static struct map_desc vt8500_io_desc[] __initdata = {
+ /* SoC MMIO registers */
+ [0] = {
+ .virtual = 0xf8000000,
+ .pfn = __phys_to_pfn(0xd8000000),
+ .length = 0x00390000, /* max of all chip variants */
+ .type = MT_DEVICE
+ },
+};
+
+static void __init vt8500_map_io(void)
+{
+ iotable_init(vt8500_io_desc, ARRAY_SIZE(vt8500_io_desc));
+}
+
+static void vt8500_power_off(void)
+{
+ local_irq_disable();
+ writew(5, pmc_base + VT8500_HCR_REG);
+ asm("mcr p15, 0, %0, c7, c0, 4" : : "r" (0));
+}
+
+static void __init vt8500_init(void)
+{
+ struct device_node *np;
+#if defined(CONFIG_FB_VT8500) || defined(CONFIG_FB_WM8505)
+ struct device_node *fb;
+ void __iomem *gpio_base;
+#endif
+
+#ifdef CONFIG_FB_VT8500
+ fb = of_find_compatible_node(NULL, NULL, "via,vt8500-fb");
+ if (fb) {
+ np = of_find_compatible_node(NULL, NULL, "via,vt8500-gpio");
+ if (np) {
+ gpio_base = of_iomap(np, 0);
+
+ if (!gpio_base)
+ pr_err("%s: of_iomap(gpio_mux) failed\n",
+ __func__);
+
+ of_node_put(np);
+ } else {
+ gpio_base = ioremap(LEGACY_GPIO_BASE, 0x1000);
+ if (!gpio_base)
+ pr_err("%s: ioremap(legacy_gpio_mux) failed\n",
+ __func__);
+ }
+ if (gpio_base) {
+ writel(readl(gpio_base + VT8500_GPIO_MUX_REG) | 1,
+ gpio_base + VT8500_GPIO_MUX_REG);
+ iounmap(gpio_base);
+ } else
+ pr_err("%s: Could not remap GPIO mux\n", __func__);
+
+ of_node_put(fb);
+ }
+#endif
+
+#ifdef CONFIG_FB_WM8505
+ fb = of_find_compatible_node(NULL, NULL, "wm,wm8505-fb");
+ if (fb) {
+ np = of_find_compatible_node(NULL, NULL, "wm,wm8505-gpio");
+ if (!np)
+ np = of_find_compatible_node(NULL, NULL,
+ "wm,wm8650-gpio");
+ if (np) {
+ gpio_base = of_iomap(np, 0);
+
+ if (!gpio_base)
+ pr_err("%s: of_iomap(gpio_mux) failed\n",
+ __func__);
+
+ of_node_put(np);
+ } else {
+ gpio_base = ioremap(LEGACY_GPIO_BASE, 0x1000);
+ if (!gpio_base)
+ pr_err("%s: ioremap(legacy_gpio_mux) failed\n",
+ __func__);
+ }
+ if (gpio_base) {
+ writel(readl(gpio_base + VT8500_GPIO_MUX_REG) |
+ 0x80000000, gpio_base + VT8500_GPIO_MUX_REG);
+ iounmap(gpio_base);
+ } else
+ pr_err("%s: Could not remap GPIO mux\n", __func__);
+
+ of_node_put(fb);
+ }
+#endif
+
+ np = of_find_compatible_node(NULL, NULL, "via,vt8500-pmc");
+ if (np) {
+ pmc_base = of_iomap(np, 0);
+
+ if (!pmc_base)
+ pr_err("%s:of_iomap(pmc) failed\n", __func__);
+
+ of_node_put(np);
+ } else {
+ pmc_base = ioremap(LEGACY_PMC_BASE, 0x1000);
+ if (!pmc_base)
+ pr_err("%s:ioremap(power_off) failed\n", __func__);
+ }
+ if (pmc_base)
+ pm_power_off = &vt8500_power_off;
+ else
+ pr_err("%s: PMC Hibernation register could not be remapped, not enabling power off!\n", __func__);
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char * const vt8500_dt_compat[] = {
+ "via,vt8500",
+ "wm,wm8650",
+ "wm,wm8505",
+ "wm,wm8750",
+ "wm,wm8850",
+ NULL
+};
+
+DT_MACHINE_START(WMT_DT, "VIA/Wondermedia SoC (Device Tree Support)")
+ .dt_compat = vt8500_dt_compat,
+ .map_io = vt8500_map_io,
+ .init_machine = vt8500_init,
+ .restart = vt8500_restart,
+MACHINE_END
+
diff --git a/arch/arm/mach-w90x900/Kconfig b/arch/arm/mach-w90x900/Kconfig
new file mode 100644
index 000000000..69bab32a8
--- /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 000000000..828c03264
--- /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 000000000..6c3d421c2
--- /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 000000000..06d867dce
--- /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-ac97") == 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 000000000..2c371ff22
--- /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 000000000..b88a1b16b
--- /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 000000000..213230ee5
--- /dev/null
+++ b/arch/arm/mach-w90x900/cpu.c
@@ -0,0 +1,242 @@
+/*
+ * 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 <asm/system_misc.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-serial.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-ebi.h>
+#include <mach/regs-timer.h>
+
+#include "cpu.h"
+#include "clock.h"
+#include "nuc9xx.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-ac97", 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;
+
+ if (kstrtoul(str, 0, &cpufreq))
+ return 0;
+
+ 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));
+}
+
+#define WTCR (TMR_BA + 0x1C)
+#define WTCLK (1 << 10)
+#define WTE (1 << 7)
+#define WTRE (1 << 1)
+
+void nuc9xx_restart(enum reboot_mode mode, const char *cmd)
+{
+ if (mode == REBOOT_SOFT) {
+ /* Jump into ROM at address 0 */
+ soft_restart(0);
+ } else {
+ __raw_writel(WTE | WTRE | WTCLK, WTCR);
+ }
+}
diff --git a/arch/arm/mach-w90x900/cpu.h b/arch/arm/mach-w90x900/cpu.h
new file mode 100644
index 000000000..f8730b60b
--- /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 000000000..e65a80a1a
--- /dev/null
+++ b/arch/arm/mach-w90x900/dev.c
@@ -0,0 +1,541 @@
+/*
+ * 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/cpu.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/system_misc.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 <linux/platform_data/spi-nuc900.h>
+#include <mach/map.h>
+#include <linux/platform_data/video-nuc900fb.h>
+#include <mach/regs-ldm.h>
+#include <linux/platform_data/keypad-w90p910.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 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 = {
+#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_ac97 = {
+ .name = "nuc900-ac97",
+ .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_ac97,
+};
+
+/* Provide adding specific CPU platform devices API */
+
+void __init nuc900_board_init(struct platform_device **device, int size)
+{
+ cpu_idle_poll_ctrl(true);
+ 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 000000000..ba05aec7e
--- /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/entry-macro.S b/arch/arm/mach-w90x900/include/mach/entry-macro.S
new file mode 100644
index 000000000..0ff612ac9
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/entry-macro.S
@@ -0,0 +1,26 @@
+/*
+ * 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 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
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 000000000..fe3c6265a
--- /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/irqs.h b/arch/arm/mach-w90x900/include/mach/irqs.h
new file mode 100644
index 000000000..9d5cba3a5
--- /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 000000000..1a2095304
--- /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/mfp.h b/arch/arm/mach-w90x900/include/mach/mfp.h
new file mode 100644
index 000000000..23ef1f573
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/mfp.h
@@ -0,0 +1,25 @@
+/*
+ * 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, const char *subname);
+extern void mfp_set_groupd(struct device *dev, const char *subname);
+
+#endif /* __ASM_ARCH_MFP_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 000000000..516d6b477
--- /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 000000000..b68455e7f
--- /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 000000000..6087abd93
--- /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 000000000..8a3185fbc
--- /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 000000000..e9d480a5b
--- /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 000000000..f08fa0d75
--- /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 000000000..8f390620c
--- /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 000000000..ab74b0c24
--- /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/uncompress.h b/arch/arm/mach-w90x900/include/mach/uncompress.h
new file mode 100644
index 000000000..4b7c324ff
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/uncompress.h
@@ -0,0 +1,48 @@
+/*
+ * 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 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/irq.c b/arch/arm/mach-w90x900/irq.c
new file mode 100644
index 000000000..d66d43ae8
--- /dev/null
+++ b/arch/arm/mach-w90x900/irq.c
@@ -0,0 +1,216 @@
+/*
+ * 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/device.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-irq.h>
+
+#include "nuc9xx.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 000000000..92f1c978f
--- /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 */
+ .map_io = nuc910evb_map_io,
+ .init_irq = nuc900_init_irq,
+ .init_machine = nuc910evb_init,
+ .init_time = nuc900_timer_init,
+ .restart = nuc9xx_restart,
+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 000000000..26f718905
--- /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 <linux/platform_data/video-nuc900fb.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 */
+ .map_io = nuc950evb_map_io,
+ .init_irq = nuc900_init_irq,
+ .init_machine = nuc950evb_init,
+ .init_time = nuc900_timer_init,
+ .restart = nuc9xx_restart,
+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 000000000..9b4e73fe1
--- /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 */
+ .map_io = nuc960evb_map_io,
+ .init_irq = nuc900_init_irq,
+ .init_machine = nuc960evb_init,
+ .init_time = nuc900_timer_init,
+ .restart = nuc9xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-w90x900/mfp.c b/arch/arm/mach-w90x900/mfp.c
new file mode 100644
index 000000000..c58d142b8
--- /dev/null
+++ b/arch/arm/mach-w90x900/mfp.c
@@ -0,0 +1,200 @@
+/*
+ * 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 GPSELD (0x0f << 4)
+
+#define GPSELEI0 (0x01 << 26)
+#define GPSELEI1 (0x01 << 27)
+
+#define GPIOG0TO1 (0x03 << 14)
+#define GPIOG2TO3 (0x03 << 16)
+#define GPIOG22TO23 (0x03 << 22)
+#define GPIOG18TO20 (0x07 << 18)
+
+#define ENSPI (0x0a << 14)
+#define ENI2C0 (0x01 << 14)
+#define ENI2C1 (0x01 << 16)
+#define ENAC97 (0x02 << 22)
+#define ENSD1 (0x02 << 18)
+#define ENSD0 (0x0a << 4)
+#define ENKPI (0x02 << 2)
+#define ENNAND (0x01 << 2)
+
+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, const char *subname)
+{
+ unsigned long mfpen;
+ const char *dev_id;
+
+ BUG_ON((!dev) && (!subname));
+
+ mutex_lock(&mfp_mutex);
+
+ if (subname != NULL)
+ dev_id = subname;
+ else
+ 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-ac97") == 0) {
+ mfpen &= ~(GPIOG22TO23);
+ mfpen |= ENAC97;/*enable AC97*/
+ } else if (strcmp(dev_id, "nuc900-mmc-port1") == 0) {
+ mfpen &= ~(GPIOG18TO20);
+ mfpen |= (ENSD1 | 0x01);/*enable sd1*/
+ } else {
+ mfpen &= ~(GPIOG0TO1 | GPIOG2TO3);/*GPIOG[3:0]*/
+ }
+
+ __raw_writel(mfpen, REG_MFSEL);
+
+ mutex_unlock(&mfp_mutex);
+}
+EXPORT_SYMBOL(mfp_set_groupg);
+
+void mfp_set_groupd(struct device *dev, const char *subname)
+{
+ unsigned long mfpen;
+ const char *dev_id;
+
+ BUG_ON((!dev) && (!subname));
+
+ mutex_lock(&mfp_mutex);
+
+ if (subname != NULL)
+ dev_id = subname;
+ else
+ dev_id = dev_name(dev);
+
+ mfpen = __raw_readl(REG_MFSEL);
+
+ if (strcmp(dev_id, "nuc900-mmc-port0") == 0) {
+ mfpen &= ~GPSELD;/*enable sd0*/
+ mfpen |= ENSD0;
+ } else
+ mfpen &= (~GPSELD);
+
+ __raw_writel(mfpen, REG_MFSEL);
+
+ mutex_unlock(&mfp_mutex);
+}
+EXPORT_SYMBOL(mfp_set_groupd);
diff --git a/arch/arm/mach-w90x900/nuc910.c b/arch/arm/mach-w90x900/nuc910.c
new file mode 100644
index 000000000..1523f4136
--- /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 000000000..b14c71a9e
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc910.h
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ *
+ */
+#include "nuc9xx.h"
+
+/* 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 000000000..5704f74a5
--- /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 000000000..6e9de3051
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc950.h
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ *
+ */
+#include "nuc9xx.h"
+
+/* 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 000000000..8851a3a27
--- /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 000000000..9f6df9a00
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc960.h
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ *
+ */
+#include "nuc9xx.h"
+
+/* 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/nuc9xx.h b/arch/arm/mach-w90x900/nuc9xx.h
new file mode 100644
index 000000000..e3ab1e138
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc9xx.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-w90x900/nuc9xx.h
+ *
+ * Copied from nuc910.h, which had:
+ *
+ * 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.
+ *
+ */
+
+#include <linux/reboot.h>
+
+struct map_desc;
+
+/* core initialisation functions */
+
+extern void nuc900_init_irq(void);
+extern void nuc900_timer_init(void);
+extern void nuc9xx_restart(enum reboot_mode, const char *);
diff --git a/arch/arm/mach-w90x900/time.c b/arch/arm/mach-w90x900/time.c
new file mode 100644
index 000000000..9230d3725
--- /dev/null
+++ b/arch/arm/mach-w90x900/time.c
@@ -0,0 +1,168 @@
+/*
+ * 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>
+
+#include "nuc9xx.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",
+ .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_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.cpumask = cpumask_of(0);
+
+ clockevents_config_and_register(&nuc900_clockevent_device, rate,
+ 0xf, 0xffffffff);
+}
+
+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);
+}
+
+void __init nuc900_timer_init(void)
+{
+ nuc900_clocksource_init();
+ nuc900_clockevents_init();
+}
diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
new file mode 100644
index 000000000..78e5e007f
--- /dev/null
+++ b/arch/arm/mach-zynq/Kconfig
@@ -0,0 +1,16 @@
+config ARCH_ZYNQ
+ bool "Xilinx Zynq ARM Cortex A9 Platform" if ARCH_MULTI_V7
+ select ARCH_SUPPORTS_BIG_ENDIAN
+ select ARM_AMBA
+ select ARM_GIC
+ select ARM_GLOBAL_TIMER if !CPU_FREQ
+ select CADENCE_TTC_TIMER
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select ICST
+ select MFD_SYSCON
+ select PINCTRL
+ select PINCTRL_ZYNQ
+ select SOC_BUS
+ help
+ Support for Xilinx Zynq ARM Cortex A9 Platform
diff --git a/arch/arm/mach-zynq/Makefile b/arch/arm/mach-zynq/Makefile
new file mode 100644
index 000000000..b03a97eb7
--- /dev/null
+++ b/arch/arm/mach-zynq/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := common.o slcr.o pm.o
+obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/mach-zynq/Makefile.boot b/arch/arm/mach-zynq/Makefile.boot
new file mode 100644
index 000000000..760a0efe7
--- /dev/null
+++ b/arch/arm/mach-zynq/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y += 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
new file mode 100644
index 000000000..58ef2a700
--- /dev/null
+++ b/arch/arm/mach-zynq/common.c
@@ -0,0 +1,216 @@
+/*
+ * This file contains common code that is intended to be used across
+ * boards so that it's not replicated.
+ *
+ * Copyright (C) 2011 Xilinx
+ *
+ * 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/kernel.h>
+#include <linux/cpumask.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/zynq.h>
+#include <linux/clocksource.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/of.h>
+#include <linux/memblock.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/smp_scu.h>
+#include <asm/system_info.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "common.h"
+
+#define ZYNQ_DEVCFG_MCTRL 0x80
+#define ZYNQ_DEVCFG_PS_VERSION_SHIFT 28
+#define ZYNQ_DEVCFG_PS_VERSION_MASK 0xF
+
+void __iomem *zynq_scu_base;
+
+/**
+ * zynq_memory_init - Initialize special memory
+ *
+ * We need to stop things allocating the low memory as DMA can't work in
+ * the 1st 512K of memory.
+ */
+static void __init zynq_memory_init(void)
+{
+ if (!__pa(PAGE_OFFSET))
+ memblock_reserve(__pa(PAGE_OFFSET), __pa(swapper_pg_dir));
+}
+
+static struct platform_device zynq_cpuidle_device = {
+ .name = "cpuidle-zynq",
+};
+
+/**
+ * zynq_get_revision - Get Zynq silicon revision
+ *
+ * Return: Silicon version or -1 otherwise
+ */
+static int __init zynq_get_revision(void)
+{
+ struct device_node *np;
+ void __iomem *zynq_devcfg_base;
+ u32 revision;
+
+ np = of_find_compatible_node(NULL, NULL, "xlnx,zynq-devcfg-1.0");
+ if (!np) {
+ pr_err("%s: no devcfg node found\n", __func__);
+ return -1;
+ }
+
+ zynq_devcfg_base = of_iomap(np, 0);
+ if (!zynq_devcfg_base) {
+ pr_err("%s: Unable to map I/O memory\n", __func__);
+ return -1;
+ }
+
+ revision = readl(zynq_devcfg_base + ZYNQ_DEVCFG_MCTRL);
+ revision >>= ZYNQ_DEVCFG_PS_VERSION_SHIFT;
+ revision &= ZYNQ_DEVCFG_PS_VERSION_MASK;
+
+ iounmap(zynq_devcfg_base);
+
+ return revision;
+}
+
+static void __init zynq_init_late(void)
+{
+ zynq_core_pm_init();
+ zynq_pm_late_init();
+}
+
+/**
+ * zynq_init_machine - System specific initialization, intended to be
+ * called from board specific initialization.
+ */
+static void __init zynq_init_machine(void)
+{
+ struct platform_device_info devinfo = { .name = "cpufreq-dt", };
+ struct soc_device_attribute *soc_dev_attr;
+ struct soc_device *soc_dev;
+ struct device *parent = NULL;
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ goto out;
+
+ system_rev = zynq_get_revision();
+
+ soc_dev_attr->family = kasprintf(GFP_KERNEL, "Xilinx Zynq");
+ soc_dev_attr->revision = kasprintf(GFP_KERNEL, "0x%x", system_rev);
+ soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "0x%x",
+ zynq_slcr_get_device_id());
+
+ soc_dev = soc_device_register(soc_dev_attr);
+ if (IS_ERR(soc_dev)) {
+ kfree(soc_dev_attr->family);
+ kfree(soc_dev_attr->revision);
+ kfree(soc_dev_attr->soc_id);
+ kfree(soc_dev_attr);
+ goto out;
+ }
+
+ parent = soc_device_to_device(soc_dev);
+
+out:
+ /*
+ * Finished with the static registrations now; fill in the missing
+ * devices
+ */
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
+
+ platform_device_register(&zynq_cpuidle_device);
+ platform_device_register_full(&devinfo);
+}
+
+static void __init zynq_timer_init(void)
+{
+ zynq_early_slcr_init();
+
+ zynq_clock_init();
+ of_clk_init(NULL);
+ clocksource_of_init();
+}
+
+static struct map_desc zynq_cortex_a9_scu_map __initdata = {
+ .length = SZ_256,
+ .type = MT_DEVICE,
+};
+
+static void __init zynq_scu_map_io(void)
+{
+ unsigned long base;
+
+ base = scu_a9_get_base();
+ zynq_cortex_a9_scu_map.pfn = __phys_to_pfn(base);
+ /* Expected address is in vmalloc area that's why simple assign here */
+ zynq_cortex_a9_scu_map.virtual = base;
+ iotable_init(&zynq_cortex_a9_scu_map, 1);
+ zynq_scu_base = (void __iomem *)base;
+ BUG_ON(!zynq_scu_base);
+}
+
+/**
+ * zynq_map_io - Create memory mappings needed for early I/O.
+ */
+static void __init zynq_map_io(void)
+{
+ debug_ll_io_init();
+ zynq_scu_map_io();
+}
+
+static void __init zynq_irq_init(void)
+{
+ gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND);
+ irqchip_init();
+}
+
+static void zynq_system_reset(enum reboot_mode mode, const char *cmd)
+{
+ zynq_slcr_system_reset();
+}
+
+static const char * const zynq_dt_match[] = {
+ "xlnx,zynq-7000",
+ NULL
+};
+
+DT_MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform")
+ /* 64KB way size, 8-way associativity, parity disabled */
+ .l2c_aux_val = 0x00000000,
+ .l2c_aux_mask = 0xffffffff,
+ .smp = smp_ops(zynq_smp_ops),
+ .map_io = zynq_map_io,
+ .init_irq = zynq_irq_init,
+ .init_machine = zynq_init_machine,
+ .init_late = zynq_init_late,
+ .init_time = zynq_timer_init,
+ .dt_compat = zynq_dt_match,
+ .reserve = zynq_memory_init,
+ .restart = zynq_system_reset,
+MACHINE_END
diff --git a/arch/arm/mach-zynq/common.h b/arch/arm/mach-zynq/common.h
new file mode 100644
index 000000000..382c60e9a
--- /dev/null
+++ b/arch/arm/mach-zynq/common.h
@@ -0,0 +1,54 @@
+/*
+ * This file contains common function prototypes to avoid externs
+ * in the c files.
+ *
+ * Copyright (C) 2011 Xilinx
+ *
+ * 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_ZYNQ_COMMON_H__
+#define __MACH_ZYNQ_COMMON_H__
+
+void zynq_secondary_startup(void);
+
+extern int zynq_slcr_init(void);
+extern int zynq_early_slcr_init(void);
+extern void zynq_slcr_system_reset(void);
+extern void zynq_slcr_cpu_stop(int cpu);
+extern void zynq_slcr_cpu_start(int cpu);
+extern bool zynq_slcr_cpu_state_read(int cpu);
+extern void zynq_slcr_cpu_state_write(int cpu, bool die);
+extern u32 zynq_slcr_get_device_id(void);
+
+#ifdef CONFIG_SMP
+extern char zynq_secondary_trampoline;
+extern char zynq_secondary_trampoline_jump;
+extern char zynq_secondary_trampoline_end;
+extern int zynq_cpun_start(u32 address, int cpu);
+extern struct smp_operations zynq_smp_ops __initdata;
+#endif
+
+extern void __iomem *zynq_scu_base;
+
+void zynq_pm_late_init(void);
+
+static inline void zynq_core_pm_init(void)
+{
+ /* A9 clock gating */
+ asm volatile ("mrc p15, 0, r12, c15, c0, 0\n"
+ "orr r12, r12, #1\n"
+ "mcr p15, 0, r12, c15, c0, 0\n"
+ : /* no outputs */
+ : /* no inputs */
+ : "r12");
+}
+
+#endif
diff --git a/arch/arm/mach-zynq/headsmp.S b/arch/arm/mach-zynq/headsmp.S
new file mode 100644
index 000000000..dd8c07194
--- /dev/null
+++ b/arch/arm/mach-zynq/headsmp.S
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2013 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ * Copyright (c) 2012-2013 Xilinx
+ *
+ * This program is free software; you can redistribute it 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>
+
+ENTRY(zynq_secondary_trampoline)
+ARM_BE8(setend be) @ ensure we are in BE8 mode
+ ldr r0, zynq_secondary_trampoline_jump
+ARM_BE8(rev r0, r0)
+ bx r0
+.globl zynq_secondary_trampoline_jump
+zynq_secondary_trampoline_jump:
+ /* Space for jumping address */
+ .word /* cpu 1 */
+.globl zynq_secondary_trampoline_end
+zynq_secondary_trampoline_end:
+ENDPROC(zynq_secondary_trampoline)
+
+ENTRY(zynq_secondary_startup)
+ bl v7_invalidate_l1
+ b secondary_startup
+ENDPROC(zynq_secondary_startup)
diff --git a/arch/arm/mach-zynq/platsmp.c b/arch/arm/mach-zynq/platsmp.c
new file mode 100644
index 000000000..52d768ff7
--- /dev/null
+++ b/arch/arm/mach-zynq/platsmp.c
@@ -0,0 +1,170 @@
+/*
+ * This file contains Xilinx specific SMP code, used to start up
+ * the second processor.
+ *
+ * Copyright (C) 2011-2013 Xilinx
+ *
+ * based on linux/arch/arm/mach-realview/platsmp.c
+ *
+ * Copyright (C) 2002 ARM 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/export.h>
+#include <linux/jiffies.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <asm/cacheflush.h>
+#include <asm/smp_scu.h>
+#include <linux/irqchip/arm-gic.h>
+#include "common.h"
+
+/*
+ * Store number of cores in the system
+ * Because of scu_get_core_count() must be in __init section and can't
+ * be called from zynq_cpun_start() because it is not in __init section.
+ */
+static int ncores;
+
+int zynq_cpun_start(u32 address, int cpu)
+{
+ u32 trampoline_code_size = &zynq_secondary_trampoline_end -
+ &zynq_secondary_trampoline;
+
+ /* MS: Expectation that SLCR are directly map and accessible */
+ /* Not possible to jump to non aligned address */
+ if (!(address & 3) && (!address || (address >= trampoline_code_size))) {
+ /* Store pointer to ioremap area which points to address 0x0 */
+ static u8 __iomem *zero;
+ u32 trampoline_size = &zynq_secondary_trampoline_jump -
+ &zynq_secondary_trampoline;
+
+ zynq_slcr_cpu_stop(cpu);
+ if (address) {
+ if (__pa(PAGE_OFFSET)) {
+ zero = ioremap(0, trampoline_code_size);
+ if (!zero) {
+ pr_warn("BOOTUP jump vectors not accessible\n");
+ return -1;
+ }
+ } else {
+ zero = (__force u8 __iomem *)PAGE_OFFSET;
+ }
+
+ /*
+ * This is elegant way how to jump to any address
+ * 0x0: Load address at 0x8 to r0
+ * 0x4: Jump by mov instruction
+ * 0x8: Jumping address
+ */
+ memcpy((__force void *)zero, &zynq_secondary_trampoline,
+ trampoline_size);
+ writel(address, zero + trampoline_size);
+
+ flush_cache_all();
+ outer_flush_range(0, trampoline_code_size);
+ smp_wmb();
+
+ if (__pa(PAGE_OFFSET))
+ iounmap(zero);
+ }
+ zynq_slcr_cpu_start(cpu);
+
+ return 0;
+ }
+
+ pr_warn("Can't start CPU%d: Wrong starting address %x\n", cpu, address);
+
+ return -1;
+}
+EXPORT_SYMBOL(zynq_cpun_start);
+
+static int zynq_boot_secondary(unsigned int cpu,
+ struct task_struct *idle)
+{
+ return zynq_cpun_start(virt_to_phys(zynq_secondary_startup), cpu);
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+static void __init zynq_smp_init_cpus(void)
+{
+ int i;
+
+ ncores = scu_get_core_count(zynq_scu_base);
+
+ for (i = 0; i < ncores && i < CONFIG_NR_CPUS; i++)
+ set_cpu_possible(i, true);
+}
+
+static void __init zynq_smp_prepare_cpus(unsigned int max_cpus)
+{
+ scu_enable(zynq_scu_base);
+}
+
+/**
+ * zynq_secondary_init - Initialize secondary CPU cores
+ * @cpu: CPU that is initialized
+ *
+ * This function is in the hotplug path. Don't move it into the
+ * init section!!
+ */
+static void zynq_secondary_init(unsigned int cpu)
+{
+ zynq_core_pm_init();
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static int zynq_cpu_kill(unsigned cpu)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(50);
+
+ while (zynq_slcr_cpu_state_read(cpu))
+ if (time_after(jiffies, timeout))
+ return 0;
+
+ zynq_slcr_cpu_stop(cpu);
+ return 1;
+}
+
+/**
+ * zynq_cpu_die - Let a CPU core die
+ * @cpu: Dying CPU
+ *
+ * Platform-specific code to shutdown a CPU.
+ * Called with IRQs disabled on the dying CPU.
+ */
+static void zynq_cpu_die(unsigned int cpu)
+{
+ zynq_slcr_cpu_state_write(cpu, true);
+
+ /*
+ * 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 (;;)
+ cpu_do_idle();
+}
+#endif
+
+struct smp_operations zynq_smp_ops __initdata = {
+ .smp_init_cpus = zynq_smp_init_cpus,
+ .smp_prepare_cpus = zynq_smp_prepare_cpus,
+ .smp_boot_secondary = zynq_boot_secondary,
+ .smp_secondary_init = zynq_secondary_init,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = zynq_cpu_die,
+ .cpu_kill = zynq_cpu_kill,
+#endif
+};
diff --git a/arch/arm/mach-zynq/pm.c b/arch/arm/mach-zynq/pm.c
new file mode 100644
index 000000000..fa44fc1b6
--- /dev/null
+++ b/arch/arm/mach-zynq/pm.c
@@ -0,0 +1,83 @@
+/*
+ * Zynq power management
+ *
+ * Copyright (C) 2012 - 2014 Xilinx
+ *
+ * Sören Brinkmann <soren.brinkmann@xilinx.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include "common.h"
+
+/* register offsets */
+#define DDRC_CTRL_REG1_OFFS 0x60
+#define DDRC_DRAM_PARAM_REG3_OFFS 0x20
+
+/* bitfields */
+#define DDRC_CLOCKSTOP_MASK BIT(23)
+#define DDRC_SELFREFRESH_MASK BIT(12)
+
+static void __iomem *ddrc_base;
+
+/**
+ * zynq_pm_ioremap() - Create IO mappings
+ * @comp: DT compatible string
+ * Return: Pointer to the mapped memory or NULL.
+ *
+ * Remap the memory region for a compatible DT node.
+ */
+static void __iomem *zynq_pm_ioremap(const char *comp)
+{
+ struct device_node *np;
+ void __iomem *base = NULL;
+
+ np = of_find_compatible_node(NULL, NULL, comp);
+ if (np) {
+ base = of_iomap(np, 0);
+ of_node_put(np);
+ } else {
+ pr_warn("%s: no compatible node found for '%s'\n", __func__,
+ comp);
+ }
+
+ return base;
+}
+
+/**
+ * zynq_pm_late_init() - Power management init
+ *
+ * Initialization of power management related features and infrastructure.
+ */
+void __init zynq_pm_late_init(void)
+{
+ u32 reg;
+
+ ddrc_base = zynq_pm_ioremap("xlnx,zynq-ddrc-a05");
+ if (!ddrc_base) {
+ pr_warn("%s: Unable to map DDRC IO memory.\n", __func__);
+ } else {
+ /*
+ * Enable DDRC clock stop feature. The HW takes care of
+ * entering/exiting the correct mode depending
+ * on activity state.
+ */
+ reg = readl(ddrc_base + DDRC_DRAM_PARAM_REG3_OFFS);
+ reg |= DDRC_CLOCKSTOP_MASK;
+ writel(reg, ddrc_base + DDRC_DRAM_PARAM_REG3_OFFS);
+ }
+}
diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c
new file mode 100644
index 000000000..c3c24fd8b
--- /dev/null
+++ b/arch/arm/mach-zynq/slcr.c
@@ -0,0 +1,227 @@
+/*
+ * Xilinx SLCR driver
+ *
+ * Copyright (c) 2011-2013 Xilinx 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.
+ *
+ * You 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/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/clk/zynq.h>
+#include "common.h"
+
+/* register offsets */
+#define SLCR_UNLOCK_OFFSET 0x8 /* SCLR unlock register */
+#define SLCR_PS_RST_CTRL_OFFSET 0x200 /* PS Software Reset Control */
+#define SLCR_A9_CPU_RST_CTRL_OFFSET 0x244 /* CPU Software Reset Control */
+#define SLCR_REBOOT_STATUS_OFFSET 0x258 /* PS Reboot Status */
+#define SLCR_PSS_IDCODE 0x530 /* PS IDCODE */
+
+#define SLCR_UNLOCK_MAGIC 0xDF0D
+#define SLCR_A9_CPU_CLKSTOP 0x10
+#define SLCR_A9_CPU_RST 0x1
+#define SLCR_PSS_IDCODE_DEVICE_SHIFT 12
+#define SLCR_PSS_IDCODE_DEVICE_MASK 0x1F
+
+static void __iomem *zynq_slcr_base;
+static struct regmap *zynq_slcr_regmap;
+
+/**
+ * zynq_slcr_write - Write to a register in SLCR block
+ *
+ * @val: Value to write to the register
+ * @offset: Register offset in SLCR block
+ *
+ * Return: a negative value on error, 0 on success
+ */
+static int zynq_slcr_write(u32 val, u32 offset)
+{
+ return regmap_write(zynq_slcr_regmap, offset, val);
+}
+
+/**
+ * zynq_slcr_read - Read a register in SLCR block
+ *
+ * @val: Pointer to value to be read from SLCR
+ * @offset: Register offset in SLCR block
+ *
+ * Return: a negative value on error, 0 on success
+ */
+static int zynq_slcr_read(u32 *val, u32 offset)
+{
+ return regmap_read(zynq_slcr_regmap, offset, val);
+}
+
+/**
+ * zynq_slcr_unlock - Unlock SLCR registers
+ *
+ * Return: a negative value on error, 0 on success
+ */
+static inline int zynq_slcr_unlock(void)
+{
+ zynq_slcr_write(SLCR_UNLOCK_MAGIC, SLCR_UNLOCK_OFFSET);
+
+ return 0;
+}
+
+/**
+ * zynq_slcr_get_device_id - Read device code id
+ *
+ * Return: Device code id
+ */
+u32 zynq_slcr_get_device_id(void)
+{
+ u32 val;
+
+ zynq_slcr_read(&val, SLCR_PSS_IDCODE);
+ val >>= SLCR_PSS_IDCODE_DEVICE_SHIFT;
+ val &= SLCR_PSS_IDCODE_DEVICE_MASK;
+
+ return val;
+}
+
+/**
+ * zynq_slcr_system_reset - Reset the entire system.
+ */
+void zynq_slcr_system_reset(void)
+{
+ u32 reboot;
+
+ /*
+ * Unlock the SLCR then reset the system.
+ * Note that this seems to require raw i/o
+ * functions or there's a lockup?
+ */
+ zynq_slcr_unlock();
+
+ /*
+ * Clear 0x0F000000 bits of reboot status register to workaround
+ * the FSBL not loading the bitstream after soft-reboot
+ * This is a temporary solution until we know more.
+ */
+ zynq_slcr_read(&reboot, SLCR_REBOOT_STATUS_OFFSET);
+ zynq_slcr_write(reboot & 0xF0FFFFFF, SLCR_REBOOT_STATUS_OFFSET);
+ zynq_slcr_write(1, SLCR_PS_RST_CTRL_OFFSET);
+}
+
+/**
+ * zynq_slcr_cpu_start - Start cpu
+ * @cpu: cpu number
+ */
+void zynq_slcr_cpu_start(int cpu)
+{
+ u32 reg;
+
+ zynq_slcr_read(&reg, SLCR_A9_CPU_RST_CTRL_OFFSET);
+ reg &= ~(SLCR_A9_CPU_RST << cpu);
+ zynq_slcr_write(reg, SLCR_A9_CPU_RST_CTRL_OFFSET);
+ reg &= ~(SLCR_A9_CPU_CLKSTOP << cpu);
+ zynq_slcr_write(reg, SLCR_A9_CPU_RST_CTRL_OFFSET);
+
+ zynq_slcr_cpu_state_write(cpu, false);
+}
+
+/**
+ * zynq_slcr_cpu_stop - Stop cpu
+ * @cpu: cpu number
+ */
+void zynq_slcr_cpu_stop(int cpu)
+{
+ u32 reg;
+
+ zynq_slcr_read(&reg, SLCR_A9_CPU_RST_CTRL_OFFSET);
+ reg |= (SLCR_A9_CPU_CLKSTOP | SLCR_A9_CPU_RST) << cpu;
+ zynq_slcr_write(reg, SLCR_A9_CPU_RST_CTRL_OFFSET);
+}
+
+/**
+ * zynq_slcr_cpu_state - Read/write cpu state
+ * @cpu: cpu number
+ *
+ * SLCR_REBOOT_STATUS save upper 2 bits (31/30 cpu states for cpu0 and cpu1)
+ * 0 means cpu is running, 1 cpu is going to die.
+ *
+ * Return: true if cpu is running, false if cpu is going to die
+ */
+bool zynq_slcr_cpu_state_read(int cpu)
+{
+ u32 state;
+
+ state = readl(zynq_slcr_base + SLCR_REBOOT_STATUS_OFFSET);
+ state &= 1 << (31 - cpu);
+
+ return !state;
+}
+
+/**
+ * zynq_slcr_cpu_state - Read/write cpu state
+ * @cpu: cpu number
+ * @die: cpu state - true if cpu is going to die
+ *
+ * SLCR_REBOOT_STATUS save upper 2 bits (31/30 cpu states for cpu0 and cpu1)
+ * 0 means cpu is running, 1 cpu is going to die.
+ */
+void zynq_slcr_cpu_state_write(int cpu, bool die)
+{
+ u32 state, mask;
+
+ state = readl(zynq_slcr_base + SLCR_REBOOT_STATUS_OFFSET);
+ mask = 1 << (31 - cpu);
+ if (die)
+ state |= mask;
+ else
+ state &= ~mask;
+ writel(state, zynq_slcr_base + SLCR_REBOOT_STATUS_OFFSET);
+}
+
+/**
+ * zynq_early_slcr_init - Early slcr init function
+ *
+ * Return: 0 on success, negative errno otherwise.
+ *
+ * Called very early during boot from platform code to unlock SLCR.
+ */
+int __init zynq_early_slcr_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "xlnx,zynq-slcr");
+ if (!np) {
+ pr_err("%s: no slcr node found\n", __func__);
+ BUG();
+ }
+
+ zynq_slcr_base = of_iomap(np, 0);
+ if (!zynq_slcr_base) {
+ pr_err("%s: Unable to map I/O memory\n", __func__);
+ BUG();
+ }
+
+ np->data = (__force void *)zynq_slcr_base;
+
+ zynq_slcr_regmap = syscon_regmap_lookup_by_compatible("xlnx,zynq-slcr");
+ if (IS_ERR(zynq_slcr_regmap)) {
+ pr_err("%s: failed to find zynq-slcr\n", __func__);
+ return -ENODEV;
+ }
+
+ /* unlock the SLCR so that registers can be changed */
+ zynq_slcr_unlock();
+
+ pr_info("%s mapped to %p\n", np->name, zynq_slcr_base);
+
+ of_node_put(np);
+
+ return 0;
+}
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
new file mode 100644
index 000000000..b4f92b9a1
--- /dev/null
+++ b/arch/arm/mm/Kconfig
@@ -0,0 +1,1040 @@
+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.
+
+# ARM7TDMI
+config CPU_ARM7TDMI
+ bool "Support ARM7TDMI processor"
+ depends on !MMU
+ select CPU_32v4T
+ select CPU_ABRT_LV4T
+ select CPU_CACHE_V4
+ select CPU_PABRT_LEGACY
+ 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.
+
+# ARM720T
+config CPU_ARM720T
+ bool "Support ARM720T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR)
+ select CPU_32v4T
+ select CPU_ABRT_LV4T
+ select CPU_CACHE_V4
+ select CPU_CACHE_VIVT
+ select CPU_COPY_V4WT if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
+ 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_MULTI_V4T && ARCH_INTEGRATOR)
+ depends on !MMU
+ select CPU_32v4T
+ select CPU_ABRT_LV4T
+ select CPU_CACHE_V4
+ select CPU_CP15_MPU
+ select CPU_PABRT_LEGACY
+ 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_CACHE_V4
+ select CPU_PABRT_LEGACY
+ 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_MULTI_V4T && ARCH_INTEGRATOR)
+ select CPU_32v4T
+ select CPU_ABRT_EV4T
+ select CPU_CACHE_V4WT
+ select CPU_CACHE_VIVT
+ select CPU_COPY_V4WB if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
+ 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_MULTI_V4T && ARCH_INTEGRATOR)
+ select CPU_32v4T
+ select CPU_ABRT_EV4T
+ select CPU_CACHE_V4WT
+ select CPU_CACHE_VIVT
+ select CPU_COPY_V4WB if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
+ 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_CACHE_V4WT
+ select CPU_CACHE_VIVT
+ select CPU_COPY_V4WB if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
+ 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_MULTIPLATFORM || ARCH_MULTI_V5) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB)
+ select CPU_32v5
+ select CPU_ABRT_EV5TJ
+ select CPU_CACHE_VIVT
+ select CPU_COPY_V4WB if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
+ 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_CACHE_FA
+ select CPU_CACHE_VIVT
+ select CPU_COPY_FA if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
+ 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_MULTI_V4T && ARCH_INTEGRATOR)
+ depends on !MMU
+ select CPU_32v4T
+ select CPU_ABRT_NOMMU
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MPU
+ select CPU_PABRT_LEGACY
+ 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_MULTI_V5 && ARCH_INTEGRATOR)
+ depends on !MMU
+ select CPU_32v5
+ select CPU_ABRT_NOMMU
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MPU
+ select CPU_PABRT_LEGACY
+ 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_MULTI_V5 && ARCH_INTEGRATOR)
+ select CPU_32v5
+ select CPU_ABRT_EV4T
+ select CPU_CACHE_V4WT
+ select CPU_CACHE_VIVT
+ select CPU_COPY_V4WB if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
+ 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_MULTI_V5 && ARCH_INTEGRATOR)
+ depends on n
+ select CPU_32v5
+ select CPU_ABRT_EV4T
+ select CPU_CACHE_V4WT
+ select CPU_CACHE_VIVT
+ select CPU_COPY_V4WB if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
+ select CPU_TLB_V4WBI if MMU
+
+# ARM1022E
+config CPU_ARM1022
+ bool "Support ARM1022E processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR)
+ select CPU_32v5
+ select CPU_ABRT_EV4T
+ select CPU_CACHE_VIVT
+ select CPU_COPY_V4WB if MMU # can probably do better
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
+ 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_MULTI_V5 && ARCH_INTEGRATOR)
+ select CPU_32v5
+ select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
+ select CPU_CACHE_VIVT
+ select CPU_COPY_V4WB if MMU # can probably do better
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
+ 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
+ select CPU_32v3 if ARCH_RPC
+ select CPU_32v4 if !ARCH_RPC
+ select CPU_ABRT_EV4
+ select CPU_CACHE_V4WB
+ select CPU_CACHE_VIVT
+ select CPU_COPY_V4WB if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
+ 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_CACHE_V4WB
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
+ select CPU_TLB_V4WB if MMU
+
+# XScale
+config CPU_XSCALE
+ bool
+ select CPU_32v5
+ select CPU_ABRT_EV5T
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
+ select CPU_TLB_V4WBI if MMU
+
+# XScale Core Version 3
+config CPU_XSC3
+ bool
+ select CPU_32v5
+ select CPU_ABRT_EV5T
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
+ 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_CACHE_VIVT
+ select CPU_COPY_V4WB if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
+ select CPU_TLB_V4WBI if MMU
+
+# Feroceon
+config CPU_FEROCEON
+ bool
+ select CPU_32v5
+ select CPU_ABRT_EV5T
+ select CPU_CACHE_VIVT
+ select CPU_COPY_FEROCEON if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
+ 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 ARM_THUMBEE
+ select CPU_V7
+
+config CPU_PJ4B
+ bool
+ select CPU_V7
+
+# ARMv6
+config CPU_V6
+ bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX)
+ select CPU_32v6
+ select CPU_ABRT_EV6
+ select CPU_CACHE_V6
+ select CPU_CACHE_VIPT
+ select CPU_COPY_V6 if MMU
+ select CPU_CP15_MMU
+ select CPU_HAS_ASID if MMU
+ select CPU_PABRT_V6
+ select CPU_TLB_V6 if MMU
+
+# ARMv6k
+config CPU_V6K
+ bool "Support ARM V6K processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX)
+ select CPU_32v6
+ select CPU_32v6K
+ select CPU_ABRT_EV6
+ select CPU_CACHE_V6
+ select CPU_CACHE_VIPT
+ select CPU_COPY_V6 if MMU
+ select CPU_CP15_MMU
+ select CPU_HAS_ASID if MMU
+ select CPU_PABRT_V6
+ select CPU_TLB_V6 if MMU
+
+# ARMv7
+config CPU_V7
+ bool "Support ARM V7 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V7) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX)
+ select CPU_32v6K
+ select CPU_32v7
+ select CPU_ABRT_EV7
+ select CPU_CACHE_V7
+ select CPU_CACHE_VIPT
+ select CPU_COPY_V6 if MMU
+ select CPU_CP15_MMU if MMU
+ select CPU_CP15_MPU if !MMU
+ select CPU_HAS_ASID if MMU
+ select CPU_PABRT_V7
+ select CPU_TLB_V7 if MMU
+
+# ARMv7M
+config CPU_V7M
+ bool
+ select CPU_32v7M
+ select CPU_ABRT_NOMMU
+ select CPU_CACHE_NOP
+ select CPU_PABRT_LEGACY
+ select CPU_THUMBONLY
+
+config CPU_THUMBONLY
+ bool
+ # There are no CPUs available with MMU that don't implement an ARM ISA:
+ depends on !MMU
+ help
+ Select this if your CPU doesn't support the 32 bit ARM instructions.
+
+# 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 CPU_USE_DOMAINS if MMU
+ select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ select NEED_KUSER_HELPERS
+ select TLS_REG_EMUL if SMP || !MMU
+
+config CPU_32v4
+ bool
+ select CPU_USE_DOMAINS if MMU
+ select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ select NEED_KUSER_HELPERS
+ select TLS_REG_EMUL if SMP || !MMU
+
+config CPU_32v4T
+ bool
+ select CPU_USE_DOMAINS if MMU
+ select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ select NEED_KUSER_HELPERS
+ select TLS_REG_EMUL if SMP || !MMU
+
+config CPU_32v5
+ bool
+ select CPU_USE_DOMAINS if MMU
+ select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ select NEED_KUSER_HELPERS
+ select TLS_REG_EMUL if SMP || !MMU
+
+config CPU_32v6
+ bool
+ select TLS_REG_EMUL if !CPU_32v6K && !MMU
+
+config CPU_32v6K
+ bool
+
+config CPU_32v7
+ bool
+
+config CPU_32v7M
+ 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_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_NOP
+ 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_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_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_LPAE
+ bool "Support for the Large Physical Address Extension"
+ depends on MMU && CPU_32v7 && !CPU_32v6 && !CPU_32v5 && \
+ !CPU_32v4 && !CPU_32v3
+ help
+ Say Y if you have an ARMv7 processor supporting the LPAE page
+ table format and you would like to access memory beyond the
+ 4GB limit. The resulting kernel image will not run on
+ processors without the LPA extension.
+
+ If unsure, say N.
+
+config ARCH_PHYS_ADDR_T_64BIT
+ def_bool ARM_LPAE
+
+config ARCH_DMA_ADDR_T_64BIT
+ bool
+
+config ARM_THUMB
+ bool "Support Thumb user binaries" if !CPU_THUMBONLY
+ 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 || CPU_V7M
+ 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 ARM_VIRT_EXT
+ bool
+ depends on MMU
+ default y if CPU_V7
+ help
+ Enable the kernel to make use of the ARM Virtualization
+ Extensions to install hypervisors without run-time firmware
+ assistance.
+
+ A compliant bootloader is required in order to make maximum
+ use of this feature. Refer to Documentation/arm/Booting for
+ details.
+
+config SWP_EMULATE
+ bool "Emulate SWP/SWPB instructions" if !SMP
+ depends on CPU_V7
+ default y if SMP
+ select HAVE_PROC_CPU if PROC_FS
+ 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 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_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 && !SMP
+ 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
+ select NEED_KUSER_HELPERS
+ 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
+ select NEED_KUSER_HELPERS
+ help
+ SMP on a pre-ARMv6 processor? Well OK then.
+ Forget about fast user space cmpxchg support.
+ It is just not possible.
+
+config NEED_KUSER_HELPERS
+ bool
+
+config KUSER_HELPERS
+ bool "Enable kuser helpers in vector page" if !NEED_KUSER_HELPERS
+ depends on MMU
+ default y
+ help
+ Warning: disabling this option may break user programs.
+
+ Provide kuser helpers in the vector page. The kernel provides
+ helper code to userspace in read only form at a fixed location
+ in the high vector page to allow userspace to be independent of
+ the CPU type fitted to the system. This permits binaries to be
+ run on ARMv4 through to ARMv7 without modification.
+
+ See Documentation/arm/kernel_user_helpers.txt for details.
+
+ However, the fixed address nature of these helpers can be used
+ by ROP (return orientated programming) authors when creating
+ exploits.
+
+ If all of the binaries and libraries which run on your platform
+ are built specifically for your platform, and make no use of
+ these helpers, then you can turn this option off to hinder
+ such exploits. However, in that case, if a binary or library
+ relying on those helpers is run, it will receive a SIGILL signal,
+ which will terminate the program.
+
+ Say N here only if you are absolutely certain that you do not
+ need these helpers; otherwise, the safe option is to say Y.
+
+config VDSO
+ bool "Enable VDSO for acceleration of some system calls"
+ depends on AEABI && MMU && CPU_V7
+ default y if ARM_ARCH_TIMER
+ select GENERIC_TIME_VSYSCALL
+ help
+ Place in the process address space an ELF shared object
+ providing fast implementations of gettimeofday and
+ clock_gettime. Systems that implement the ARM architected
+ timer will receive maximum benefit.
+
+ You must have glibc 2.22 or later for programs to seamlessly
+ take advantage of this.
+
+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_MV78XX0 || ARCH_MVEBU
+ 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 MIGHT_HAVE_CACHE_L2X0
+ bool
+ help
+ This option should be selected by machines which have a L2x0
+ or PL310 cache controller, but where its use is optional.
+
+ The only effect of this option is to make CACHE_L2X0 and
+ related options available to the user for configuration.
+
+ Boards or SoCs which always require the cache controller
+ support to be present should select CACHE_L2X0 directly
+ instead of this option, thus preventing the user from
+ inadvertently configuring a broken kernel.
+
+config CACHE_L2X0
+ bool "Enable the L2x0 outer cache controller" if MIGHT_HAVE_CACHE_L2X0
+ default MIGHT_HAVE_CACHE_L2X0
+ select OUTER_CACHE
+ select OUTER_CACHE_SYNC
+ help
+ This option enables the L2x0 PrimeCell.
+
+if CACHE_L2X0
+
+config PL310_ERRATA_588369
+ bool "PL310 errata: Clean & Invalidate maintenance operations do not invalidate clean lines"
+ 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 prior to r2p0 (fixed in r2p0)
+ as clean lines are not invalidated as a result of these operations.
+
+config PL310_ERRATA_727915
+ bool "PL310 errata: Background Clean & Invalidate by Way operation can cause data corruption"
+ 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. Revisions prior to r3p1 are affected by
+ this errata (fixed in r3p1).
+
+config PL310_ERRATA_753970
+ bool "PL310 errata: cache sync operation may be faulty"
+ 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 PL310_ERRATA_769419
+ bool "PL310 errata: no automatic Store Buffer drain"
+ 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.
+
+endif
+
+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
+ default y if CPU_V7
+ 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.
+
+config ARCH_SUPPORTS_BIG_ENDIAN
+ bool
+ help
+ This option specifies the architecture can support big endian
+ operation.
+
+config ARM_KERNMEM_PERMS
+ bool "Restrict kernel memory permissions"
+ depends on MMU
+ help
+ If this is set, kernel memory other than kernel text (and rodata)
+ will be made non-executable. The tradeoff is that each region is
+ padded to section-size (1MiB) boundaries (because their permissions
+ are different and splitting the 1M pages into 4K ones causes TLB
+ performance problems), wasting memory.
+
+config DEBUG_RODATA
+ bool "Make kernel text and rodata read-only"
+ depends on ARM_KERNMEM_PERMS
+ default y
+ help
+ If this is set, kernel text and rodata will be made read-only. This
+ is to help catch accidental or malicious attempts to change the
+ kernel's executable code. Additionally splits rodata from kernel
+ text so it can be made explicitly non-executable. This creates
+ another section-size padded region, so it can waste more memory
+ space while gaining the read-only protections.
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
new file mode 100644
index 000000000..d3afdf9eb
--- /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 pageattr.o
+
+ifneq ($(CONFIG_MMU),y)
+obj-y += nommu.o
+endif
+
+obj-$(CONFIG_ARM_PTDUMP) += dump.o
+obj-$(CONFIG_MODULES) += proc-syms.o
+
+obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
+obj-$(CONFIG_HIGHMEM) += highmem.o
+obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.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_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
+obj-$(CONFIG_CPU_CACHE_NOP) += cache-nop.o
+
+AFLAGS_cache-v6.o :=-Wa,-march=armv6
+AFLAGS_cache-v7.o :=-Wa,-march=armv7-a
+
+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_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_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
+obj-$(CONFIG_CPU_V7M) += proc-v7m.o
+
+AFLAGS_proc-v6.o :=-Wa,-march=armv6
+AFLAGS_proc-v7.o :=-Wa,-march=armv7-a
+
+obj-$(CONFIG_OUTER_CACHE) += l2c-common.o
+obj-$(CONFIG_CACHE_FEROCEON_L2) += cache-feroceon-l2.o
+obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o l2c-l2x0-resume.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 000000000..54473cd4a
--- /dev/null
+++ b/arch/arm/mm/abort-ev4.S
@@ -0,0 +1,25 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+/*
+ * Function: v4_early_abort
+ *
+ * Params : r2 = pt_regs
+ * : r4 = aborted context pc
+ * : r5 = aborted context psr
+ *
+ * Returns : r4 - r11, r13 preserved
+ *
+ * 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, [r4] @ 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.
+ b do_DataAbort
diff --git a/arch/arm/mm/abort-ev4t.S b/arch/arm/mm/abort-ev4t.S
new file mode 100644
index 000000000..9da704e7b
--- /dev/null
+++ b/arch/arm/mm/abort-ev4t.S
@@ -0,0 +1,27 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include "abort-macro.S"
+/*
+ * Function: v4t_early_abort
+ *
+ * Params : r2 = pt_regs
+ * : r4 = aborted context pc
+ * : r5 = aborted context psr
+ *
+ * Returns : r4 - r11, r13 preserved
+ *
+ * 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 fsr=r1, pc=r4, psr=r5, tmp=r3
+ ldreq r3, [r4] @ 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
+ b do_DataAbort
diff --git a/arch/arm/mm/abort-ev5t.S b/arch/arm/mm/abort-ev5t.S
new file mode 100644
index 000000000..a0908d465
--- /dev/null
+++ b/arch/arm/mm/abort-ev5t.S
@@ -0,0 +1,28 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include "abort-macro.S"
+/*
+ * Function: v5t_early_abort
+ *
+ * Params : r2 = pt_regs
+ * : r4 = aborted context pc
+ * : r5 = aborted context psr
+ *
+ * Returns : r4 - r11, r13 preserved
+ *
+ * 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 fsr=r1, pc=r4, psr=r5, tmp=r3
+ ldreq r3, [r4] @ read aborted ARM instruction
+ bic r1, r1, #1 << 11 @ clear bits 11 of FSR
+ do_ldrd_abort tmp=ip, insn=r3
+ tst r3, #1 << 20 @ check write
+ orreq r1, r1, #1 << 11
+ b do_DataAbort
diff --git a/arch/arm/mm/abort-ev5tj.S b/arch/arm/mm/abort-ev5tj.S
new file mode 100644
index 000000000..4006b7a61
--- /dev/null
+++ b/arch/arm/mm/abort-ev5tj.S
@@ -0,0 +1,30 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include "abort-macro.S"
+/*
+ * Function: v5tj_early_abort
+ *
+ * Params : r2 = pt_regs
+ * : r4 = aborted context pc
+ * : r5 = aborted context psr
+ *
+ * Returns : r4 - r11, r13 preserved
+ *
+ * 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 r5, #PSR_J_BIT @ Java?
+ bne do_DataAbort
+ do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3
+ ldreq r3, [r4] @ read aborted ARM instruction
+ do_ldrd_abort tmp=ip, insn=r3
+ tst r3, #1 << 20 @ L = 0 -> write
+ orreq r1, r1, #1 << 11 @ yes.
+ b do_DataAbort
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S
new file mode 100644
index 000000000..8c48c5c22
--- /dev/null
+++ b/arch/arm/mm/abort-ev6.S
@@ -0,0 +1,41 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include "abort-macro.S"
+/*
+ * Function: v6_early_abort
+ *
+ * Params : r2 = pt_regs
+ * : r4 = aborted context pc
+ * : r5 = aborted context psr
+ *
+ * Returns : r4 - r11, r13 preserved
+ *
+ * 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)
+ 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.
+ */
+#ifdef CONFIG_ARM_ERRATA_326103
+ ldr ip, =0x4107b36
+ mrc p15, 0, r3, c0, c0, 0 @ get processor id
+ teq ip, r3, lsr #4 @ r0 ARM1136?
+ bne do_DataAbort
+ tst r5, #PSR_J_BIT @ Java?
+ tsteq r5, #PSR_T_BIT @ Thumb?
+ bne do_DataAbort
+ bic r1, r1, #1 << 11 @ clear bit 11 of FSR
+ ldr r3, [r4] @ read aborted ARM instruction
+ ARM_BE8(rev r3, r3)
+
+ do_ldrd_abort tmp=ip, insn=r3
+ tst r3, #1 << 20 @ L = 0 -> write
+ orreq r1, r1, #1 << 11 @ yes.
+#endif
+ b do_DataAbort
diff --git a/arch/arm/mm/abort-ev7.S b/arch/arm/mm/abort-ev7.S
new file mode 100644
index 000000000..4812ad054
--- /dev/null
+++ b/arch/arm/mm/abort-ev7.S
@@ -0,0 +1,45 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+/*
+ * Function: v7_early_abort
+ *
+ * Params : r2 = pt_regs
+ * : r4 = aborted context pc
+ * : r5 = aborted context psr
+ *
+ * Returns : r4 - r11, r13 preserved
+ *
+ * Purpose : obtain information about current aborted instruction.
+ */
+ .align 5
+ENTRY(v7_early_abort)
+ 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
+ bne do_DataAbort
+
+ mcr p15, 0, r0, c7, c8, 0 @ Retranslate FAR
+ isb
+ mrc p15, 0, ip, c7, c4, 0 @ Read the PAR
+ and r3, ip, #0x7b @ On translation fault
+ cmp r3, #0x0b
+ bne do_DataAbort
+ bic r1, r1, #0xf @ Fix up FSR FS[5:0]
+ and ip, ip, #0x7e
+ orr r1, r1, ip, LSR #1
+#endif
+
+ b do_DataAbort
+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 000000000..f3982580c
--- /dev/null
+++ b/arch/arm/mm/abort-lv4t.S
@@ -0,0 +1,220 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+/*
+ * Function: v4t_late_abort
+ *
+ * Params : r2 = pt_regs
+ * : r4 = aborted context pc
+ * : r5 = aborted context psr
+ *
+ * Returns : r4-r5, r10-r11, r13 preserved
+ *
+ * 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 r5, #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, [r4] @ 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 */ b do_DataAbort @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
+/* d */ b do_DataAbort @ ldc rd, [rn, #m]
+/* e */ b .data_unknown
+/* f */
+.data_unknown: @ Part of jumptable
+ mov r0, r4
+ mov r1, r8
+ b baddataabort
+
+.data_arm_ldmstm:
+ tst r8, #1 << 21 @ check writeback bit
+ beq do_DataAbort @ no writeback -> no fixup
+ mov r7, #0x11
+ orr r7, r7, #0x1100
+ and r6, r8, r7
+ and r9, r8, r7, lsl #1
+ add r6, r6, r9, lsr #1
+ and r9, r8, r7, lsl #2
+ add r6, r6, r9, lsr #2
+ and r9, r8, r7, lsl #3
+ add r6, r6, r9, 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 r9, r8, #15 << 16 @ Extract 'n' from instruction
+ ldr r7, [r2, r9, 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, [r2, r9, lsr #14] @ Put register 'Rn'
+ b do_DataAbort
+
+.data_arm_lateldrhpre:
+ tst r8, #1 << 21 @ Check writeback bit
+ beq do_DataAbort @ No writeback -> no fixup
+.data_arm_lateldrhpost:
+ and r9, 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, r9, r6, lsr #4 @ combine nibbles } else
+ ldreq r6, [r2, r9, lsl #2] @ { load Rm value }
+.data_arm_apply_r6_and_rn:
+ and r9, r8, #15 << 16 @ Extract 'n' from instruction
+ ldr r7, [r2, r9, 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, [r2, r9, lsr #14] @ Put register 'Rn'
+ b do_DataAbort
+
+.data_arm_lateldrpreconst:
+ tst r8, #1 << 21 @ check writeback bit
+ beq do_DataAbort @ no writeback -> no fixup
+.data_arm_lateldrpostconst:
+ movs r6, r8, lsl #20 @ Get offset
+ beq do_DataAbort @ zero -> no fixup
+ and r9, r8, #15 << 16 @ Extract 'n' from instruction
+ ldr r7, [r2, r9, lsr #14] @ Get register 'Rn'
+ tst r8, #1 << 23 @ Check U bit
+ subne r7, r7, r6, lsr #20 @ Undo increment
+ addeq r7, r7, r6, lsr #20 @ Undo decrement
+ str r7, [r2, r9, lsr #14] @ Put register 'Rn'
+ b do_DataAbort
+
+.data_arm_lateldrprereg:
+ tst r8, #1 << 21 @ check writeback bit
+ beq do_DataAbort @ no writeback -> no fixup
+.data_arm_lateldrpostreg:
+ and r7, r8, #15 @ Extract 'm' from instruction
+ ldr r6, [r2, r7, lsl #2] @ Get register 'Rm'
+ mov r9, r8, lsr #7 @ get shift count
+ ands r9, r9, #31
+ and r7, r8, #0x70 @ get shift type
+ orreq r7, r7, #8 @ shift count = 0
+ add pc, pc, r7
+ nop
+
+ mov r6, r6, lsl r9 @ 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 r9 @ 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 r9 @ 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 r9 @ 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, [r4] @ 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 */ b do_DataAbort
+/* 7 */ b do_DataAbort
+/* 8 */ b do_DataAbort
+/* 9 */ b do_DataAbort
+/* 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
+ beq do_DataAbort
+ tst r8, #1 << 10 @ If 'S' (signed) bit is set
+ movne r1, #0 @ it must be a load instr
+ b do_DataAbort
+
+.data_thumb_pushpop:
+ tst r8, #1 << 10
+ beq .data_unknown
+ and r6, r8, #0x55 @ hweight8(r8) + R bit
+ and r9, r8, #0xaa
+ add r6, r6, r9, lsr #1
+ and r9, r6, #0xcc
+ and r6, r6, #0x33
+ add r6, r6, r9, 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, [r2, #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, [r2, #13 << 2]
+ b do_DataAbort
+
+.data_thumb_ldmstm:
+ and r6, r8, #0x55 @ hweight8(r8)
+ and r9, r8, #0xaa
+ add r6, r6, r9, lsr #1
+ and r9, r6, #0xcc
+ and r6, r6, #0x33
+ add r6, r6, r9, lsr #2
+ add r6, r6, r6, lsr #4
+ and r9, r8, #7 << 8
+ ldr r7, [r2, r9, lsr #6]
+ and r6, r6, #15 @ number of regs to transfer
+ sub r7, r7, r6, lsl #2 @ always decrement
+ str r7, [r2, r9, lsr #6]
+ b do_DataAbort
diff --git a/arch/arm/mm/abort-macro.S b/arch/arm/mm/abort-macro.S
new file mode 100644
index 000000000..2cbf68ef0
--- /dev/null
+++ b/arch/arm/mm/abort-macro.S
@@ -0,0 +1,40 @@
+/*
+ * 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, fsr, pc, psr, tmp
+ tst \psr, #PSR_T_BIT
+ beq not_thumb
+ ldrh \tmp, [\pc] @ Read aborted Thumb instruction
+ and \tmp, \tmp, # 0xfe00 @ Mask opcode field
+ cmp \tmp, # 0x5600 @ Is it ldrsb?
+ orreq \tmp, \tmp, #1 << 11 @ Set L-bit if yes
+ tst \tmp, #1 << 11 @ L = 0 -> write
+ orreq \fsr, \fsr, #1 << 11 @ yes.
+ b do_DataAbort
+not_thumb:
+ .endm
+
+/*
+ * We check for the following instruction encoding for LDRD.
+ *
+ * [27:25] == 000
+ * [7:4] == 1101
+ * [20] == 0
+ */
+ .macro do_ldrd_abort, tmp, insn
+ tst \insn, #0x0e100000 @ [27:25,20] == 0
+ bne not_ldrd
+ and \tmp, \insn, #0x000000f0 @ [7:4] == 1101
+ cmp \tmp, #0x000000d0
+ beq do_DataAbort
+not_ldrd:
+ .endm
+
diff --git a/arch/arm/mm/abort-nommu.S b/arch/arm/mm/abort-nommu.S
new file mode 100644
index 000000000..119cb479c
--- /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 = pt_regs
+ * : r4 = aborted context pc
+ * : r5 = aborted context psr
+ *
+ * Returns : r4 - r11, r13 preserved
+ *
+ * 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
+ b do_DataAbort
+ENDPROC(nommu_early_abort)
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
new file mode 100644
index 000000000..9769f1eef
--- /dev/null
+++ b/arch/arm/mm/alignment.c
@@ -0,0 +1,1008 @@
+/*
+ * 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/cp15.h>
+#include <asm/system_info.h>
+#include <asm/unaligned.h>
+#include <asm/opcodes.h>
+
+#include "fault.h"
+#include "mm.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 COND_BITS(i) (i & 0xf0000000)
+
+#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 void *ai_sys_last_pc;
+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;
+static unsigned long cr_no_alignment;
+
+core_param(alignment, ai_usermode, int, 0600);
+
+#define UM_WARN (1 << 0)
+#define UM_FIXUP (1 << 1)
+#define UM_SIGNAL (1 << 2)
+
+/* Return true if and only if the ARMv6 unaligned access model is in use. */
+static bool cpu_is_v6_unaligned(void)
+{
+ return cpu_architecture() >= CPU_ARCH_ARMv6 && get_cr() & CR_U;
+}
+
+static int safe_usermode(int new_usermode, bool warn)
+{
+ /*
+ * 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_is_v6_unaligned() && !(new_usermode & (UM_FIXUP | UM_SIGNAL))) {
+ new_usermode |= UM_FIXUP;
+
+ if (warn)
+ pr_warn("alignment: ignoring faults is unsafe on this CPU. Defaulting to fixup mode.\n");
+ }
+
+ return new_usermode;
+}
+
+#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 (%pF)\n", ai_sys, ai_sys_last_pc);
+ 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 = safe_usermode(mode - '0', true);
+ }
+ 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 .text.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 .text.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 .text.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) {
+ pr_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:
+ pr_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;
+
+ 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 uninitialized_var(offset);
+ unsigned long instr = 0, instrptr;
+ int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
+ unsigned int type;
+ unsigned int fault;
+ u16 tinstr = 0;
+ int isize = 4;
+ int thumb2_32b = 0;
+
+ if (interrupts_enabled(regs))
+ local_irq_enable();
+
+ instrptr = instruction_pointer(regs);
+
+ if (thumb_mode(regs)) {
+ u16 *ptr = (u16 *)(instrptr & ~1);
+ fault = probe_kernel_address(ptr, tinstr);
+ tinstr = __mem_to_opcode_thumb16(tinstr);
+ if (!fault) {
+ if (cpu_architecture() >= CPU_ARCH_ARMv7 &&
+ IS_T32(tinstr)) {
+ /* Thumb-2 32-bit */
+ u16 tinst2 = 0;
+ fault = probe_kernel_address(ptr + 1, tinst2);
+ tinst2 = __mem_to_opcode_thumb16(tinst2);
+ instr = __opcode_thumb32_compose(tinstr, tinst2);
+ thumb2_32b = 1;
+ } else {
+ isize = 2;
+ instr = thumb2arm(tinstr);
+ }
+ }
+ } else {
+ fault = probe_kernel_address(instrptr, instr);
+ instr = __mem_to_opcode_arm(instr);
+ }
+
+ if (fault) {
+ type = TYPE_FAULT;
+ goto bad_or_fault;
+ }
+
+ if (user_mode(regs))
+ goto user;
+
+ ai_sys += 1;
+ ai_sys_last_pc = (void *)instruction_pointer(regs);
+
+ 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 */
+ if (COND_BITS(instr) == 0xf0000000) /* NEON VLDn, VSTn */
+ goto bad;
+ 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) {
+ offset.un = 0;
+ handler = do_alignment_t32_to_handler(&instr, regs, &offset);
+ } else {
+ offset.un = 0;
+ 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:
+ pr_err("Alignment trap: not handling swp instruction\n");
+
+ bad:
+ /*
+ * Oops, we didn't handle the instruction.
+ */
+ pr_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) {
+ siginfo_t si;
+
+ si.si_signo = SIGBUS;
+ si.si_errno = 0;
+ si.si_code = BUS_ADRALN;
+ si.si_addr = (void __user *)addr;
+
+ force_sig_info(si.si_signo, &si, 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;
+}
+
+static int __init noalign_setup(char *__unused)
+{
+ set_cr(__clear_cr(CR_A));
+ return 1;
+}
+__setup("noalign", noalign_setup);
+
+/*
+ * 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
+
+ if (cpu_is_v6_unaligned()) {
+ set_cr(__clear_cr(CR_A));
+ ai_usermode = safe_usermode(ai_usermode, false);
+ }
+
+ cr_no_alignment = get_cr() & ~CR_A;
+
+ hook_fault_code(FAULT_CODE_ALIGNMENT, 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-aurora-l2.h b/arch/arm/mm/cache-aurora-l2.h
new file mode 100644
index 000000000..c86124769
--- /dev/null
+++ b/arch/arm/mm/cache-aurora-l2.h
@@ -0,0 +1,55 @@
+/*
+ * AURORA shared L2 cache controller support
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Yehuda Yitschak <yehuday@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.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_HARDWARE_AURORA_L2_H
+#define __ASM_ARM_HARDWARE_AURORA_L2_H
+
+#define AURORA_SYNC_REG 0x700
+#define AURORA_RANGE_BASE_ADDR_REG 0x720
+#define AURORA_FLUSH_PHY_ADDR_REG 0x7f0
+#define AURORA_INVAL_RANGE_REG 0x774
+#define AURORA_CLEAN_RANGE_REG 0x7b4
+#define AURORA_FLUSH_RANGE_REG 0x7f4
+
+#define AURORA_ACR_REPLACEMENT_OFFSET 27
+#define AURORA_ACR_REPLACEMENT_MASK \
+ (0x3 << AURORA_ACR_REPLACEMENT_OFFSET)
+#define AURORA_ACR_REPLACEMENT_TYPE_WAYRR \
+ (0 << AURORA_ACR_REPLACEMENT_OFFSET)
+#define AURORA_ACR_REPLACEMENT_TYPE_LFSR \
+ (1 << AURORA_ACR_REPLACEMENT_OFFSET)
+#define AURORA_ACR_REPLACEMENT_TYPE_SEMIPLRU \
+ (3 << AURORA_ACR_REPLACEMENT_OFFSET)
+
+#define AURORA_ACR_FORCE_WRITE_POLICY_OFFSET 0
+#define AURORA_ACR_FORCE_WRITE_POLICY_MASK \
+ (0x3 << AURORA_ACR_FORCE_WRITE_POLICY_OFFSET)
+#define AURORA_ACR_FORCE_WRITE_POLICY_DIS \
+ (0 << AURORA_ACR_FORCE_WRITE_POLICY_OFFSET)
+#define AURORA_ACR_FORCE_WRITE_BACK_POLICY \
+ (1 << AURORA_ACR_FORCE_WRITE_POLICY_OFFSET)
+#define AURORA_ACR_FORCE_WRITE_THRO_POLICY \
+ (2 << AURORA_ACR_FORCE_WRITE_POLICY_OFFSET)
+
+#define MAX_RANGE_SIZE 1024
+
+#define AURORA_WAY_SIZE_SHIFT 2
+
+#define AURORA_CTRL_FW 0x100
+
+/* chose a number outside L2X0_CACHE_ID_PART_MASK to be sure to make
+ * the distinction between a number coming from hardware and a number
+ * coming from the device tree */
+#define AURORA_CACHE_ID 0x100
+
+#endif /* __ASM_ARM_HARDWARE_AURORA_L2_H */
diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S
new file mode 100644
index 000000000..2f0c58836
--- /dev/null
+++ b/arch/arm/mm/cache-fa.S
@@ -0,0 +1,250 @@
+/*
+ * 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/assembler.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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(fa_dma_unmap_area)
+
+ .globl fa_flush_kern_cache_louis
+ .equ fa_flush_kern_cache_louis, fa_flush_kern_cache_all
+
+ __INITDATA
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions fa
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
new file mode 100644
index 000000000..097181e08
--- /dev/null
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -0,0 +1,396 @@
+/*
+ * 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/of.h>
+#include <linux/of_address.h>
+#include <linux/highmem.h>
+#include <linux/io.h>
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+#include <asm/hardware/cache-feroceon-l2.h>
+
+#define L2_WRITETHROUGH_KIRKWOOD BIT(4)
+
+/*
+ * 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)) {
+ pr_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;
+
+ pr_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();
+ } else
+ pr_err(FW_BUG
+ "Feroceon L2: bootloader left the L2 cache on!\n");
+}
+
+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();
+
+ pr_info("Feroceon L2: Cache support initialised%s.\n",
+ l2_wt_override ? ", in WT override mode" : "");
+}
+#ifdef CONFIG_OF
+static const struct of_device_id feroceon_ids[] __initconst = {
+ { .compatible = "marvell,kirkwood-cache"},
+ { .compatible = "marvell,feroceon-cache"},
+ {}
+};
+
+int __init feroceon_of_init(void)
+{
+ struct device_node *node;
+ void __iomem *base;
+ bool l2_wt_override = false;
+ struct resource res;
+
+#if defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
+ l2_wt_override = true;
+#endif
+
+ node = of_find_matching_node(NULL, feroceon_ids);
+ if (node && of_device_is_compatible(node, "marvell,kirkwood-cache")) {
+ if (of_address_to_resource(node, 0, &res))
+ return -ENODEV;
+
+ base = ioremap(res.start, resource_size(&res));
+ if (!base)
+ return -ENOMEM;
+
+ if (l2_wt_override)
+ writel(readl(base) | L2_WRITETHROUGH_KIRKWOOD, base);
+ else
+ writel(readl(base) & ~L2_WRITETHROUGH_KIRKWOOD, base);
+ }
+
+ feroceon_l2_init(l2_wt_override);
+
+ return 0;
+}
+#endif
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
new file mode 100644
index 000000000..e309c8f35
--- /dev/null
+++ b/arch/arm/mm/cache-l2x0.c
@@ -0,0 +1,1705 @@
+/*
+ * arch/arm/mm/cache-l2x0.c - L210/L220/L310 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/cpu.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/log2.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+#include <asm/cputype.h>
+#include <asm/hardware/cache-l2x0.h>
+#include "cache-tauros3.h"
+#include "cache-aurora-l2.h"
+
+struct l2c_init_data {
+ const char *type;
+ unsigned way_size_0;
+ unsigned num_lock;
+ void (*of_parse)(const struct device_node *, u32 *, u32 *);
+ void (*enable)(void __iomem *, u32, unsigned);
+ void (*fixup)(void __iomem *, u32, struct outer_cache_fns *);
+ void (*save)(void __iomem *);
+ void (*configure)(void __iomem *);
+ struct outer_cache_fns outer_cache;
+};
+
+#define CACHE_LINE_SIZE 32
+
+static void __iomem *l2x0_base;
+static const struct l2c_init_data *l2x0_data;
+static DEFINE_RAW_SPINLOCK(l2x0_lock);
+static u32 l2x0_way_mask; /* Bitmask of active ways */
+static u32 l2x0_size;
+static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
+
+struct l2x0_regs l2x0_saved_regs;
+
+/*
+ * Common code for all cache controllers.
+ */
+static inline void l2c_wait_mask(void __iomem *reg, unsigned long mask)
+{
+ /* wait for cache operation by line or way to complete */
+ while (readl_relaxed(reg) & mask)
+ cpu_relax();
+}
+
+/*
+ * By default, we write directly to secure registers. Platforms must
+ * override this if they are running non-secure.
+ */
+static void l2c_write_sec(unsigned long val, void __iomem *base, unsigned reg)
+{
+ if (val == readl_relaxed(base + reg))
+ return;
+ if (outer_cache.write_sec)
+ outer_cache.write_sec(val, reg);
+ else
+ writel_relaxed(val, base + reg);
+}
+
+/*
+ * This should only be called when we have a requirement that the
+ * register be written due to a work-around, as platforms running
+ * in non-secure mode may not be able to access this register.
+ */
+static inline void l2c_set_debug(void __iomem *base, unsigned long val)
+{
+ l2c_write_sec(val, base, L2X0_DEBUG_CTRL);
+}
+
+static void __l2c_op_way(void __iomem *reg)
+{
+ writel_relaxed(l2x0_way_mask, reg);
+ l2c_wait_mask(reg, l2x0_way_mask);
+}
+
+static inline void l2c_unlock(void __iomem *base, unsigned num)
+{
+ unsigned i;
+
+ for (i = 0; i < num; i++) {
+ writel_relaxed(0, base + L2X0_LOCKDOWN_WAY_D_BASE +
+ i * L2X0_LOCKDOWN_STRIDE);
+ writel_relaxed(0, base + L2X0_LOCKDOWN_WAY_I_BASE +
+ i * L2X0_LOCKDOWN_STRIDE);
+ }
+}
+
+static void l2c_configure(void __iomem *base)
+{
+ if (outer_cache.configure) {
+ outer_cache.configure(&l2x0_saved_regs);
+ return;
+ }
+
+ if (l2x0_data->configure)
+ l2x0_data->configure(base);
+
+ l2c_write_sec(l2x0_saved_regs.aux_ctrl, base, L2X0_AUX_CTRL);
+}
+
+/*
+ * Enable the L2 cache controller. This function must only be
+ * called when the cache controller is known to be disabled.
+ */
+static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock)
+{
+ unsigned long flags;
+
+ /* Do not touch the controller if already enabled. */
+ if (readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN)
+ return;
+
+ l2x0_saved_regs.aux_ctrl = aux;
+ l2c_configure(base);
+
+ l2c_unlock(base, num_lock);
+
+ local_irq_save(flags);
+ __l2c_op_way(base + L2X0_INV_WAY);
+ writel_relaxed(0, base + sync_reg_offset);
+ l2c_wait_mask(base + sync_reg_offset, 1);
+ local_irq_restore(flags);
+
+ l2c_write_sec(L2X0_CTRL_EN, base, L2X0_CTRL);
+}
+
+static void l2c_disable(void)
+{
+ void __iomem *base = l2x0_base;
+
+ outer_cache.flush_all();
+ l2c_write_sec(0, base, L2X0_CTRL);
+ dsb(st);
+}
+
+static void l2c_save(void __iomem *base)
+{
+ l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
+}
+
+static void l2c_resume(void)
+{
+ l2c_enable(l2x0_base, l2x0_saved_regs.aux_ctrl, l2x0_data->num_lock);
+}
+
+/*
+ * L2C-210 specific code.
+ *
+ * The L2C-2x0 PA, set/way and sync operations are atomic, but we must
+ * ensure that no background operation is running. The way operations
+ * are all background tasks.
+ *
+ * While a background operation is in progress, any new operation is
+ * ignored (unspecified whether this causes an error.) Thankfully, not
+ * used on SMP.
+ *
+ * Never has a different sync register other than L2X0_CACHE_SYNC, but
+ * we use sync_reg_offset here so we can share some of this with L2C-310.
+ */
+static void __l2c210_cache_sync(void __iomem *base)
+{
+ writel_relaxed(0, base + sync_reg_offset);
+}
+
+static void __l2c210_op_pa_range(void __iomem *reg, unsigned long start,
+ unsigned long end)
+{
+ while (start < end) {
+ writel_relaxed(start, reg);
+ start += CACHE_LINE_SIZE;
+ }
+}
+
+static void l2c210_inv_range(unsigned long start, unsigned long end)
+{
+ void __iomem *base = l2x0_base;
+
+ if (start & (CACHE_LINE_SIZE - 1)) {
+ start &= ~(CACHE_LINE_SIZE - 1);
+ writel_relaxed(start, base + L2X0_CLEAN_INV_LINE_PA);
+ start += CACHE_LINE_SIZE;
+ }
+
+ if (end & (CACHE_LINE_SIZE - 1)) {
+ end &= ~(CACHE_LINE_SIZE - 1);
+ writel_relaxed(end, base + L2X0_CLEAN_INV_LINE_PA);
+ }
+
+ __l2c210_op_pa_range(base + L2X0_INV_LINE_PA, start, end);
+ __l2c210_cache_sync(base);
+}
+
+static void l2c210_clean_range(unsigned long start, unsigned long end)
+{
+ void __iomem *base = l2x0_base;
+
+ start &= ~(CACHE_LINE_SIZE - 1);
+ __l2c210_op_pa_range(base + L2X0_CLEAN_LINE_PA, start, end);
+ __l2c210_cache_sync(base);
+}
+
+static void l2c210_flush_range(unsigned long start, unsigned long end)
+{
+ void __iomem *base = l2x0_base;
+
+ start &= ~(CACHE_LINE_SIZE - 1);
+ __l2c210_op_pa_range(base + L2X0_CLEAN_INV_LINE_PA, start, end);
+ __l2c210_cache_sync(base);
+}
+
+static void l2c210_flush_all(void)
+{
+ void __iomem *base = l2x0_base;
+
+ BUG_ON(!irqs_disabled());
+
+ __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
+ __l2c210_cache_sync(base);
+}
+
+static void l2c210_sync(void)
+{
+ __l2c210_cache_sync(l2x0_base);
+}
+
+static const struct l2c_init_data l2c210_data __initconst = {
+ .type = "L2C-210",
+ .way_size_0 = SZ_8K,
+ .num_lock = 1,
+ .enable = l2c_enable,
+ .save = l2c_save,
+ .outer_cache = {
+ .inv_range = l2c210_inv_range,
+ .clean_range = l2c210_clean_range,
+ .flush_range = l2c210_flush_range,
+ .flush_all = l2c210_flush_all,
+ .disable = l2c_disable,
+ .sync = l2c210_sync,
+ .resume = l2c_resume,
+ },
+};
+
+/*
+ * L2C-220 specific code.
+ *
+ * All operations are background operations: they have to be waited for.
+ * Conflicting requests generate a slave error (which will cause an
+ * imprecise abort.) Never uses sync_reg_offset, so we hard-code the
+ * sync register here.
+ *
+ * However, we can re-use the l2c210_resume call.
+ */
+static inline void __l2c220_cache_sync(void __iomem *base)
+{
+ writel_relaxed(0, base + L2X0_CACHE_SYNC);
+ l2c_wait_mask(base + L2X0_CACHE_SYNC, 1);
+}
+
+static void l2c220_op_way(void __iomem *base, unsigned reg)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ __l2c_op_way(base + reg);
+ __l2c220_cache_sync(base);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static unsigned long l2c220_op_pa_range(void __iomem *reg, unsigned long start,
+ unsigned long end, unsigned long flags)
+{
+ raw_spinlock_t *lock = &l2x0_lock;
+
+ while (start < end) {
+ unsigned long blk_end = start + min(end - start, 4096UL);
+
+ while (start < blk_end) {
+ l2c_wait_mask(reg, 1);
+ writel_relaxed(start, reg);
+ start += CACHE_LINE_SIZE;
+ }
+
+ if (blk_end < end) {
+ raw_spin_unlock_irqrestore(lock, flags);
+ raw_spin_lock_irqsave(lock, flags);
+ }
+ }
+
+ return flags;
+}
+
+static void l2c220_inv_range(unsigned long start, unsigned long end)
+{
+ void __iomem *base = l2x0_base;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ if ((start | end) & (CACHE_LINE_SIZE - 1)) {
+ if (start & (CACHE_LINE_SIZE - 1)) {
+ start &= ~(CACHE_LINE_SIZE - 1);
+ writel_relaxed(start, base + L2X0_CLEAN_INV_LINE_PA);
+ start += CACHE_LINE_SIZE;
+ }
+
+ if (end & (CACHE_LINE_SIZE - 1)) {
+ end &= ~(CACHE_LINE_SIZE - 1);
+ l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
+ writel_relaxed(end, base + L2X0_CLEAN_INV_LINE_PA);
+ }
+ }
+
+ flags = l2c220_op_pa_range(base + L2X0_INV_LINE_PA,
+ start, end, flags);
+ l2c_wait_mask(base + L2X0_INV_LINE_PA, 1);
+ __l2c220_cache_sync(base);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void l2c220_clean_range(unsigned long start, unsigned long end)
+{
+ void __iomem *base = l2x0_base;
+ unsigned long flags;
+
+ start &= ~(CACHE_LINE_SIZE - 1);
+ if ((end - start) >= l2x0_size) {
+ l2c220_op_way(base, L2X0_CLEAN_WAY);
+ return;
+ }
+
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ flags = l2c220_op_pa_range(base + L2X0_CLEAN_LINE_PA,
+ start, end, flags);
+ l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
+ __l2c220_cache_sync(base);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void l2c220_flush_range(unsigned long start, unsigned long end)
+{
+ void __iomem *base = l2x0_base;
+ unsigned long flags;
+
+ start &= ~(CACHE_LINE_SIZE - 1);
+ if ((end - start) >= l2x0_size) {
+ l2c220_op_way(base, L2X0_CLEAN_INV_WAY);
+ return;
+ }
+
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ flags = l2c220_op_pa_range(base + L2X0_CLEAN_INV_LINE_PA,
+ start, end, flags);
+ l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
+ __l2c220_cache_sync(base);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void l2c220_flush_all(void)
+{
+ l2c220_op_way(l2x0_base, L2X0_CLEAN_INV_WAY);
+}
+
+static void l2c220_sync(void)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ __l2c220_cache_sync(l2x0_base);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void l2c220_enable(void __iomem *base, u32 aux, unsigned num_lock)
+{
+ /*
+ * Always enable non-secure access to the lockdown registers -
+ * we write to them as part of the L2C enable sequence so they
+ * need to be accessible.
+ */
+ aux |= L220_AUX_CTRL_NS_LOCKDOWN;
+
+ l2c_enable(base, aux, num_lock);
+}
+
+static const struct l2c_init_data l2c220_data = {
+ .type = "L2C-220",
+ .way_size_0 = SZ_8K,
+ .num_lock = 1,
+ .enable = l2c220_enable,
+ .save = l2c_save,
+ .outer_cache = {
+ .inv_range = l2c220_inv_range,
+ .clean_range = l2c220_clean_range,
+ .flush_range = l2c220_flush_range,
+ .flush_all = l2c220_flush_all,
+ .disable = l2c_disable,
+ .sync = l2c220_sync,
+ .resume = l2c_resume,
+ },
+};
+
+/*
+ * L2C-310 specific code.
+ *
+ * Very similar to L2C-210, the PA, set/way and sync operations are atomic,
+ * and the way operations are all background tasks. However, issuing an
+ * operation while a background operation is in progress results in a
+ * SLVERR response. We can reuse:
+ *
+ * __l2c210_cache_sync (using sync_reg_offset)
+ * l2c210_sync
+ * l2c210_inv_range (if 588369 is not applicable)
+ * l2c210_clean_range
+ * l2c210_flush_range (if 588369 is not applicable)
+ * l2c210_flush_all (if 727915 is not applicable)
+ *
+ * Errata:
+ * 588369: PL310 R0P0->R1P0, fixed R2P0.
+ * Affects: all clean+invalidate operations
+ * clean and invalidate skips the invalidate step, so we need to issue
+ * separate operations. We also require the above debug workaround
+ * enclosing this code fragment on affected parts. On unaffected parts,
+ * we must not use this workaround without the debug register writes
+ * to avoid exposing a problem similar to 727915.
+ *
+ * 727915: PL310 R2P0->R3P0, fixed R3P1.
+ * Affects: clean+invalidate by way
+ * clean and invalidate by way runs in the background, and a store can
+ * hit the line between the clean operation and invalidate operation,
+ * resulting in the store being lost.
+ *
+ * 752271: PL310 R3P0->R3P1-50REL0, fixed R3P2.
+ * Affects: 8x64-bit (double fill) line fetches
+ * double fill line fetches can fail to cause dirty data to be evicted
+ * from the cache before the new data overwrites the second line.
+ *
+ * 753970: PL310 R3P0, fixed R3P1.
+ * Affects: sync
+ * prevents merging writes after the sync operation, until another L2C
+ * operation is performed (or a number of other conditions.)
+ *
+ * 769419: PL310 R0P0->R3P1, fixed R3P2.
+ * Affects: store buffer
+ * store buffer is not automatically drained.
+ */
+static void l2c310_inv_range_erratum(unsigned long start, unsigned long end)
+{
+ void __iomem *base = l2x0_base;
+
+ if ((start | end) & (CACHE_LINE_SIZE - 1)) {
+ unsigned long flags;
+
+ /* Erratum 588369 for both clean+invalidate operations */
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ l2c_set_debug(base, 0x03);
+
+ if (start & (CACHE_LINE_SIZE - 1)) {
+ start &= ~(CACHE_LINE_SIZE - 1);
+ writel_relaxed(start, base + L2X0_CLEAN_LINE_PA);
+ writel_relaxed(start, base + L2X0_INV_LINE_PA);
+ start += CACHE_LINE_SIZE;
+ }
+
+ if (end & (CACHE_LINE_SIZE - 1)) {
+ end &= ~(CACHE_LINE_SIZE - 1);
+ writel_relaxed(end, base + L2X0_CLEAN_LINE_PA);
+ writel_relaxed(end, base + L2X0_INV_LINE_PA);
+ }
+
+ l2c_set_debug(base, 0x00);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ }
+
+ __l2c210_op_pa_range(base + L2X0_INV_LINE_PA, start, end);
+ __l2c210_cache_sync(base);
+}
+
+static void l2c310_flush_range_erratum(unsigned long start, unsigned long end)
+{
+ raw_spinlock_t *lock = &l2x0_lock;
+ unsigned long flags;
+ void __iomem *base = l2x0_base;
+
+ raw_spin_lock_irqsave(lock, flags);
+ while (start < end) {
+ unsigned long blk_end = start + min(end - start, 4096UL);
+
+ l2c_set_debug(base, 0x03);
+ while (start < blk_end) {
+ writel_relaxed(start, base + L2X0_CLEAN_LINE_PA);
+ writel_relaxed(start, base + L2X0_INV_LINE_PA);
+ start += CACHE_LINE_SIZE;
+ }
+ l2c_set_debug(base, 0x00);
+
+ if (blk_end < end) {
+ raw_spin_unlock_irqrestore(lock, flags);
+ raw_spin_lock_irqsave(lock, flags);
+ }
+ }
+ raw_spin_unlock_irqrestore(lock, flags);
+ __l2c210_cache_sync(base);
+}
+
+static void l2c310_flush_all_erratum(void)
+{
+ void __iomem *base = l2x0_base;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ l2c_set_debug(base, 0x03);
+ __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
+ l2c_set_debug(base, 0x00);
+ __l2c210_cache_sync(base);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void __init l2c310_save(void __iomem *base)
+{
+ unsigned revision;
+
+ l2c_save(base);
+
+ l2x0_saved_regs.tag_latency = readl_relaxed(base +
+ L310_TAG_LATENCY_CTRL);
+ l2x0_saved_regs.data_latency = readl_relaxed(base +
+ L310_DATA_LATENCY_CTRL);
+ l2x0_saved_regs.filter_end = readl_relaxed(base +
+ L310_ADDR_FILTER_END);
+ l2x0_saved_regs.filter_start = readl_relaxed(base +
+ L310_ADDR_FILTER_START);
+
+ revision = readl_relaxed(base + L2X0_CACHE_ID) &
+ L2X0_CACHE_ID_RTL_MASK;
+
+ /* From r2p0, there is Prefetch offset/control register */
+ if (revision >= L310_CACHE_ID_RTL_R2P0)
+ l2x0_saved_regs.prefetch_ctrl = readl_relaxed(base +
+ L310_PREFETCH_CTRL);
+
+ /* From r3p0, there is Power control register */
+ if (revision >= L310_CACHE_ID_RTL_R3P0)
+ l2x0_saved_regs.pwr_ctrl = readl_relaxed(base +
+ L310_POWER_CTRL);
+}
+
+static void l2c310_configure(void __iomem *base)
+{
+ unsigned revision;
+
+ /* restore pl310 setup */
+ l2c_write_sec(l2x0_saved_regs.tag_latency, base,
+ L310_TAG_LATENCY_CTRL);
+ l2c_write_sec(l2x0_saved_regs.data_latency, base,
+ L310_DATA_LATENCY_CTRL);
+ l2c_write_sec(l2x0_saved_regs.filter_end, base,
+ L310_ADDR_FILTER_END);
+ l2c_write_sec(l2x0_saved_regs.filter_start, base,
+ L310_ADDR_FILTER_START);
+
+ revision = readl_relaxed(base + L2X0_CACHE_ID) &
+ L2X0_CACHE_ID_RTL_MASK;
+
+ if (revision >= L310_CACHE_ID_RTL_R2P0)
+ l2c_write_sec(l2x0_saved_regs.prefetch_ctrl, base,
+ L310_PREFETCH_CTRL);
+ if (revision >= L310_CACHE_ID_RTL_R3P0)
+ l2c_write_sec(l2x0_saved_regs.pwr_ctrl, base,
+ L310_POWER_CTRL);
+}
+
+static int l2c310_cpu_enable_flz(struct notifier_block *nb, unsigned long act, void *data)
+{
+ switch (act & ~CPU_TASKS_FROZEN) {
+ case CPU_STARTING:
+ set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
+ break;
+ case CPU_DYING:
+ set_auxcr(get_auxcr() & ~(BIT(3) | BIT(2) | BIT(1)));
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static void __init l2c310_enable(void __iomem *base, u32 aux, unsigned num_lock)
+{
+ unsigned rev = readl_relaxed(base + L2X0_CACHE_ID) & L2X0_CACHE_ID_RTL_MASK;
+ bool cortex_a9 = read_cpuid_part() == ARM_CPU_PART_CORTEX_A9;
+
+ if (rev >= L310_CACHE_ID_RTL_R2P0) {
+ if (cortex_a9) {
+ aux |= L310_AUX_CTRL_EARLY_BRESP;
+ pr_info("L2C-310 enabling early BRESP for Cortex-A9\n");
+ } else if (aux & L310_AUX_CTRL_EARLY_BRESP) {
+ pr_warn("L2C-310 early BRESP only supported with Cortex-A9\n");
+ aux &= ~L310_AUX_CTRL_EARLY_BRESP;
+ }
+ }
+
+ if (cortex_a9) {
+ u32 aux_cur = readl_relaxed(base + L2X0_AUX_CTRL);
+ u32 acr = get_auxcr();
+
+ pr_debug("Cortex-A9 ACR=0x%08x\n", acr);
+
+ if (acr & BIT(3) && !(aux_cur & L310_AUX_CTRL_FULL_LINE_ZERO))
+ pr_err("L2C-310: full line of zeros enabled in Cortex-A9 but not L2C-310 - invalid\n");
+
+ if (aux & L310_AUX_CTRL_FULL_LINE_ZERO && !(acr & BIT(3)))
+ pr_err("L2C-310: enabling full line of zeros but not enabled in Cortex-A9\n");
+
+ if (!(aux & L310_AUX_CTRL_FULL_LINE_ZERO) && !outer_cache.write_sec) {
+ aux |= L310_AUX_CTRL_FULL_LINE_ZERO;
+ pr_info("L2C-310 full line of zeros enabled for Cortex-A9\n");
+ }
+ } else if (aux & (L310_AUX_CTRL_FULL_LINE_ZERO | L310_AUX_CTRL_EARLY_BRESP)) {
+ pr_err("L2C-310: disabling Cortex-A9 specific feature bits\n");
+ aux &= ~(L310_AUX_CTRL_FULL_LINE_ZERO | L310_AUX_CTRL_EARLY_BRESP);
+ }
+
+ /* r3p0 or later has power control register */
+ if (rev >= L310_CACHE_ID_RTL_R3P0)
+ l2x0_saved_regs.pwr_ctrl = L310_DYNAMIC_CLK_GATING_EN |
+ L310_STNDBY_MODE_EN;
+
+ /*
+ * Always enable non-secure access to the lockdown registers -
+ * we write to them as part of the L2C enable sequence so they
+ * need to be accessible.
+ */
+ aux |= L310_AUX_CTRL_NS_LOCKDOWN;
+
+ l2c_enable(base, aux, num_lock);
+
+ /* Read back resulting AUX_CTRL value as it could have been altered. */
+ aux = readl_relaxed(base + L2X0_AUX_CTRL);
+
+ if (aux & (L310_AUX_CTRL_DATA_PREFETCH | L310_AUX_CTRL_INSTR_PREFETCH)) {
+ u32 prefetch = readl_relaxed(base + L310_PREFETCH_CTRL);
+
+ pr_info("L2C-310 %s%s prefetch enabled, offset %u lines\n",
+ aux & L310_AUX_CTRL_INSTR_PREFETCH ? "I" : "",
+ aux & L310_AUX_CTRL_DATA_PREFETCH ? "D" : "",
+ 1 + (prefetch & L310_PREFETCH_CTRL_OFFSET_MASK));
+ }
+
+ /* r3p0 or later has power control register */
+ if (rev >= L310_CACHE_ID_RTL_R3P0) {
+ u32 power_ctrl;
+
+ power_ctrl = readl_relaxed(base + L310_POWER_CTRL);
+ pr_info("L2C-310 dynamic clock gating %sabled, standby mode %sabled\n",
+ power_ctrl & L310_DYNAMIC_CLK_GATING_EN ? "en" : "dis",
+ power_ctrl & L310_STNDBY_MODE_EN ? "en" : "dis");
+ }
+
+ if (aux & L310_AUX_CTRL_FULL_LINE_ZERO) {
+ set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
+ cpu_notifier(l2c310_cpu_enable_flz, 0);
+ }
+}
+
+static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
+ struct outer_cache_fns *fns)
+{
+ unsigned revision = cache_id & L2X0_CACHE_ID_RTL_MASK;
+ const char *errata[8];
+ unsigned n = 0;
+
+ if (IS_ENABLED(CONFIG_PL310_ERRATA_588369) &&
+ revision < L310_CACHE_ID_RTL_R2P0 &&
+ /* For bcm compatibility */
+ fns->inv_range == l2c210_inv_range) {
+ fns->inv_range = l2c310_inv_range_erratum;
+ fns->flush_range = l2c310_flush_range_erratum;
+ errata[n++] = "588369";
+ }
+
+ if (IS_ENABLED(CONFIG_PL310_ERRATA_727915) &&
+ revision >= L310_CACHE_ID_RTL_R2P0 &&
+ revision < L310_CACHE_ID_RTL_R3P1) {
+ fns->flush_all = l2c310_flush_all_erratum;
+ errata[n++] = "727915";
+ }
+
+ if (revision >= L310_CACHE_ID_RTL_R3P0 &&
+ revision < L310_CACHE_ID_RTL_R3P2) {
+ u32 val = l2x0_saved_regs.prefetch_ctrl;
+ /* I don't think bit23 is required here... but iMX6 does so */
+ if (val & (BIT(30) | BIT(23))) {
+ val &= ~(BIT(30) | BIT(23));
+ l2x0_saved_regs.prefetch_ctrl = val;
+ errata[n++] = "752271";
+ }
+ }
+
+ if (IS_ENABLED(CONFIG_PL310_ERRATA_753970) &&
+ revision == L310_CACHE_ID_RTL_R3P0) {
+ sync_reg_offset = L2X0_DUMMY_REG;
+ errata[n++] = "753970";
+ }
+
+ if (IS_ENABLED(CONFIG_PL310_ERRATA_769419))
+ errata[n++] = "769419";
+
+ if (n) {
+ unsigned i;
+
+ pr_info("L2C-310 errat%s", n > 1 ? "a" : "um");
+ for (i = 0; i < n; i++)
+ pr_cont(" %s", errata[i]);
+ pr_cont(" enabled\n");
+ }
+}
+
+static void l2c310_disable(void)
+{
+ /*
+ * If full-line-of-zeros is enabled, we must first disable it in the
+ * Cortex-A9 auxiliary control register before disabling the L2 cache.
+ */
+ if (l2x0_saved_regs.aux_ctrl & L310_AUX_CTRL_FULL_LINE_ZERO)
+ set_auxcr(get_auxcr() & ~(BIT(3) | BIT(2) | BIT(1)));
+
+ l2c_disable();
+}
+
+static void l2c310_resume(void)
+{
+ l2c_resume();
+
+ /* Re-enable full-line-of-zeros for Cortex-A9 */
+ if (l2x0_saved_regs.aux_ctrl & L310_AUX_CTRL_FULL_LINE_ZERO)
+ set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
+}
+
+static const struct l2c_init_data l2c310_init_fns __initconst = {
+ .type = "L2C-310",
+ .way_size_0 = SZ_8K,
+ .num_lock = 8,
+ .enable = l2c310_enable,
+ .fixup = l2c310_fixup,
+ .save = l2c310_save,
+ .configure = l2c310_configure,
+ .outer_cache = {
+ .inv_range = l2c210_inv_range,
+ .clean_range = l2c210_clean_range,
+ .flush_range = l2c210_flush_range,
+ .flush_all = l2c210_flush_all,
+ .disable = l2c310_disable,
+ .sync = l2c210_sync,
+ .resume = l2c310_resume,
+ },
+};
+
+static int __init __l2c_init(const struct l2c_init_data *data,
+ u32 aux_val, u32 aux_mask, u32 cache_id)
+{
+ struct outer_cache_fns fns;
+ unsigned way_size_bits, ways;
+ u32 aux, old_aux;
+
+ /*
+ * Save the pointer globally so that callbacks which do not receive
+ * context from callers can access the structure.
+ */
+ l2x0_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+ if (!l2x0_data)
+ return -ENOMEM;
+
+ /*
+ * Sanity check the aux values. aux_mask is the bits we preserve
+ * from reading the hardware register, and aux_val is the bits we
+ * set.
+ */
+ if (aux_val & aux_mask)
+ pr_alert("L2C: platform provided aux values permit register corruption.\n");
+
+ old_aux = aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
+ aux &= aux_mask;
+ aux |= aux_val;
+
+ if (old_aux != aux)
+ pr_warn("L2C: DT/platform modifies aux control register: 0x%08x -> 0x%08x\n",
+ old_aux, aux);
+
+ /* Determine the number of ways */
+ switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
+ case L2X0_CACHE_ID_PART_L310:
+ if ((aux_val | ~aux_mask) & (L2C_AUX_CTRL_WAY_SIZE_MASK | L310_AUX_CTRL_ASSOCIATIVITY_16))
+ pr_warn("L2C: DT/platform tries to modify or specify cache size\n");
+ if (aux & (1 << 16))
+ ways = 16;
+ else
+ ways = 8;
+ break;
+
+ case L2X0_CACHE_ID_PART_L210:
+ case L2X0_CACHE_ID_PART_L220:
+ ways = (aux >> 13) & 0xf;
+ break;
+
+ case AURORA_CACHE_ID:
+ ways = (aux >> 13) & 0xf;
+ ways = 2 << ((ways + 1) >> 2);
+ break;
+
+ default:
+ /* Assume unknown chips have 8 ways */
+ ways = 8;
+ break;
+ }
+
+ l2x0_way_mask = (1 << ways) - 1;
+
+ /*
+ * way_size_0 is the size that a way_size value of zero would be
+ * given the calculation: way_size = way_size_0 << way_size_bits.
+ * So, if way_size_bits=0 is reserved, but way_size_bits=1 is 16k,
+ * then way_size_0 would be 8k.
+ *
+ * L2 cache size = number of ways * way size.
+ */
+ way_size_bits = (aux & L2C_AUX_CTRL_WAY_SIZE_MASK) >>
+ L2C_AUX_CTRL_WAY_SIZE_SHIFT;
+ l2x0_size = ways * (data->way_size_0 << way_size_bits);
+
+ fns = data->outer_cache;
+ fns.write_sec = outer_cache.write_sec;
+ fns.configure = outer_cache.configure;
+ if (data->fixup)
+ data->fixup(l2x0_base, cache_id, &fns);
+
+ /*
+ * Check if l2x0 controller is already enabled. If we are booting
+ * in non-secure mode accessing the below registers will fault.
+ */
+ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN))
+ data->enable(l2x0_base, aux, data->num_lock);
+
+ outer_cache = fns;
+
+ /*
+ * It is strange to save the register state before initialisation,
+ * but hey, this is what the DT implementations decided to do.
+ */
+ if (data->save)
+ data->save(l2x0_base);
+
+ /* Re-read it in case some bits are reserved. */
+ aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
+
+ pr_info("%s cache controller enabled, %d ways, %d kB\n",
+ data->type, ways, l2x0_size >> 10);
+ pr_info("%s: CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
+ data->type, cache_id, aux);
+
+ return 0;
+}
+
+void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
+{
+ const struct l2c_init_data *data;
+ u32 cache_id;
+
+ l2x0_base = base;
+
+ cache_id = readl_relaxed(base + L2X0_CACHE_ID);
+
+ switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
+ default:
+ case L2X0_CACHE_ID_PART_L210:
+ data = &l2c210_data;
+ break;
+
+ case L2X0_CACHE_ID_PART_L220:
+ data = &l2c220_data;
+ break;
+
+ case L2X0_CACHE_ID_PART_L310:
+ data = &l2c310_init_fns;
+ break;
+ }
+
+ /* Read back current (default) hardware configuration */
+ if (data->save)
+ data->save(l2x0_base);
+
+ __l2c_init(data, aux_val, aux_mask, cache_id);
+}
+
+#ifdef CONFIG_OF
+static int l2_wt_override;
+
+/* Aurora don't have the cache ID register available, so we have to
+ * pass it though the device tree */
+static u32 cache_id_part_number_from_dt;
+
+/**
+ * l2x0_cache_size_of_parse() - read cache size parameters from DT
+ * @np: the device tree node for the l2 cache
+ * @aux_val: pointer to machine-supplied auxilary register value, to
+ * be augmented by the call (bits to be set to 1)
+ * @aux_mask: pointer to machine-supplied auxilary register mask, to
+ * be augmented by the call (bits to be set to 0)
+ * @associativity: variable to return the calculated associativity in
+ * @max_way_size: the maximum size in bytes for the cache ways
+ */
+static int __init l2x0_cache_size_of_parse(const struct device_node *np,
+ u32 *aux_val, u32 *aux_mask,
+ u32 *associativity,
+ u32 max_way_size)
+{
+ u32 mask = 0, val = 0;
+ u32 cache_size = 0, sets = 0;
+ u32 way_size_bits = 1;
+ u32 way_size = 0;
+ u32 block_size = 0;
+ u32 line_size = 0;
+
+ of_property_read_u32(np, "cache-size", &cache_size);
+ of_property_read_u32(np, "cache-sets", &sets);
+ of_property_read_u32(np, "cache-block-size", &block_size);
+ of_property_read_u32(np, "cache-line-size", &line_size);
+
+ if (!cache_size || !sets)
+ return -ENODEV;
+
+ /* All these l2 caches have the same line = block size actually */
+ if (!line_size) {
+ if (block_size) {
+ /* If linesize is not given, it is equal to blocksize */
+ line_size = block_size;
+ } else {
+ /* Fall back to known size */
+ pr_warn("L2C OF: no cache block/line size given: "
+ "falling back to default size %d bytes\n",
+ CACHE_LINE_SIZE);
+ line_size = CACHE_LINE_SIZE;
+ }
+ }
+
+ if (line_size != CACHE_LINE_SIZE)
+ pr_warn("L2C OF: DT supplied line size %d bytes does "
+ "not match hardware line size of %d bytes\n",
+ line_size,
+ CACHE_LINE_SIZE);
+
+ /*
+ * Since:
+ * set size = cache size / sets
+ * ways = cache size / (sets * line size)
+ * way size = cache size / (cache size / (sets * line size))
+ * way size = sets * line size
+ * associativity = ways = cache size / way size
+ */
+ way_size = sets * line_size;
+ *associativity = cache_size / way_size;
+
+ if (way_size > max_way_size) {
+ pr_err("L2C OF: set size %dKB is too large\n", way_size);
+ return -EINVAL;
+ }
+
+ pr_info("L2C OF: override cache size: %d bytes (%dKB)\n",
+ cache_size, cache_size >> 10);
+ pr_info("L2C OF: override line size: %d bytes\n", line_size);
+ pr_info("L2C OF: override way size: %d bytes (%dKB)\n",
+ way_size, way_size >> 10);
+ pr_info("L2C OF: override associativity: %d\n", *associativity);
+
+ /*
+ * Calculates the bits 17:19 to set for way size:
+ * 512KB -> 6, 256KB -> 5, ... 16KB -> 1
+ */
+ way_size_bits = ilog2(way_size >> 10) - 3;
+ if (way_size_bits < 1 || way_size_bits > 6) {
+ pr_err("L2C OF: cache way size illegal: %dKB is not mapped\n",
+ way_size);
+ return -EINVAL;
+ }
+
+ mask |= L2C_AUX_CTRL_WAY_SIZE_MASK;
+ val |= (way_size_bits << L2C_AUX_CTRL_WAY_SIZE_SHIFT);
+
+ *aux_val &= ~mask;
+ *aux_val |= val;
+ *aux_mask &= ~mask;
+
+ return 0;
+}
+
+static void __init l2x0_of_parse(const struct device_node *np,
+ u32 *aux_val, u32 *aux_mask)
+{
+ u32 data[2] = { 0, 0 };
+ u32 tag = 0;
+ u32 dirty = 0;
+ u32 val = 0, mask = 0;
+ u32 assoc;
+ int ret;
+
+ of_property_read_u32(np, "arm,tag-latency", &tag);
+ if (tag) {
+ mask |= L2X0_AUX_CTRL_TAG_LATENCY_MASK;
+ val |= (tag - 1) << L2X0_AUX_CTRL_TAG_LATENCY_SHIFT;
+ }
+
+ of_property_read_u32_array(np, "arm,data-latency",
+ data, ARRAY_SIZE(data));
+ if (data[0] && data[1]) {
+ mask |= L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK |
+ L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK;
+ val |= ((data[0] - 1) << L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT) |
+ ((data[1] - 1) << L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT);
+ }
+
+ of_property_read_u32(np, "arm,dirty-latency", &dirty);
+ if (dirty) {
+ mask |= L2X0_AUX_CTRL_DIRTY_LATENCY_MASK;
+ val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT;
+ }
+
+ ret = l2x0_cache_size_of_parse(np, aux_val, aux_mask, &assoc, SZ_256K);
+ if (ret)
+ return;
+
+ if (assoc > 8) {
+ pr_err("l2x0 of: cache setting yield too high associativity\n");
+ pr_err("l2x0 of: %d calculated, max 8\n", assoc);
+ } else {
+ mask |= L2X0_AUX_CTRL_ASSOC_MASK;
+ val |= (assoc << L2X0_AUX_CTRL_ASSOC_SHIFT);
+ }
+
+ *aux_val &= ~mask;
+ *aux_val |= val;
+ *aux_mask &= ~mask;
+}
+
+static const struct l2c_init_data of_l2c210_data __initconst = {
+ .type = "L2C-210",
+ .way_size_0 = SZ_8K,
+ .num_lock = 1,
+ .of_parse = l2x0_of_parse,
+ .enable = l2c_enable,
+ .save = l2c_save,
+ .outer_cache = {
+ .inv_range = l2c210_inv_range,
+ .clean_range = l2c210_clean_range,
+ .flush_range = l2c210_flush_range,
+ .flush_all = l2c210_flush_all,
+ .disable = l2c_disable,
+ .sync = l2c210_sync,
+ .resume = l2c_resume,
+ },
+};
+
+static const struct l2c_init_data of_l2c220_data __initconst = {
+ .type = "L2C-220",
+ .way_size_0 = SZ_8K,
+ .num_lock = 1,
+ .of_parse = l2x0_of_parse,
+ .enable = l2c220_enable,
+ .save = l2c_save,
+ .outer_cache = {
+ .inv_range = l2c220_inv_range,
+ .clean_range = l2c220_clean_range,
+ .flush_range = l2c220_flush_range,
+ .flush_all = l2c220_flush_all,
+ .disable = l2c_disable,
+ .sync = l2c220_sync,
+ .resume = l2c_resume,
+ },
+};
+
+static void __init l2c310_of_parse(const struct device_node *np,
+ u32 *aux_val, u32 *aux_mask)
+{
+ u32 data[3] = { 0, 0, 0 };
+ u32 tag[3] = { 0, 0, 0 };
+ u32 filter[2] = { 0, 0 };
+ u32 assoc;
+ u32 prefetch;
+ u32 val;
+ int ret;
+
+ of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
+ if (tag[0] && tag[1] && tag[2])
+ l2x0_saved_regs.tag_latency =
+ L310_LATENCY_CTRL_RD(tag[0] - 1) |
+ L310_LATENCY_CTRL_WR(tag[1] - 1) |
+ L310_LATENCY_CTRL_SETUP(tag[2] - 1);
+
+ of_property_read_u32_array(np, "arm,data-latency",
+ data, ARRAY_SIZE(data));
+ if (data[0] && data[1] && data[2])
+ l2x0_saved_regs.data_latency =
+ L310_LATENCY_CTRL_RD(data[0] - 1) |
+ L310_LATENCY_CTRL_WR(data[1] - 1) |
+ L310_LATENCY_CTRL_SETUP(data[2] - 1);
+
+ of_property_read_u32_array(np, "arm,filter-ranges",
+ filter, ARRAY_SIZE(filter));
+ if (filter[1]) {
+ l2x0_saved_regs.filter_end =
+ ALIGN(filter[0] + filter[1], SZ_1M);
+ l2x0_saved_regs.filter_start = (filter[0] & ~(SZ_1M - 1))
+ | L310_ADDR_FILTER_EN;
+ }
+
+ ret = l2x0_cache_size_of_parse(np, aux_val, aux_mask, &assoc, SZ_512K);
+ if (!ret) {
+ switch (assoc) {
+ case 16:
+ *aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK;
+ *aux_val |= L310_AUX_CTRL_ASSOCIATIVITY_16;
+ *aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK;
+ break;
+ case 8:
+ *aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK;
+ *aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK;
+ break;
+ default:
+ pr_err("L2C-310 OF cache associativity %d invalid, only 8 or 16 permitted\n",
+ assoc);
+ break;
+ }
+ }
+
+ prefetch = l2x0_saved_regs.prefetch_ctrl;
+
+ ret = of_property_read_u32(np, "arm,double-linefill", &val);
+ if (ret == 0) {
+ if (val)
+ prefetch |= L310_PREFETCH_CTRL_DBL_LINEFILL;
+ else
+ prefetch &= ~L310_PREFETCH_CTRL_DBL_LINEFILL;
+ } else if (ret != -EINVAL) {
+ pr_err("L2C-310 OF arm,double-linefill property value is missing\n");
+ }
+
+ ret = of_property_read_u32(np, "arm,double-linefill-incr", &val);
+ if (ret == 0) {
+ if (val)
+ prefetch |= L310_PREFETCH_CTRL_DBL_LINEFILL_INCR;
+ else
+ prefetch &= ~L310_PREFETCH_CTRL_DBL_LINEFILL_INCR;
+ } else if (ret != -EINVAL) {
+ pr_err("L2C-310 OF arm,double-linefill-incr property value is missing\n");
+ }
+
+ ret = of_property_read_u32(np, "arm,double-linefill-wrap", &val);
+ if (ret == 0) {
+ if (!val)
+ prefetch |= L310_PREFETCH_CTRL_DBL_LINEFILL_WRAP;
+ else
+ prefetch &= ~L310_PREFETCH_CTRL_DBL_LINEFILL_WRAP;
+ } else if (ret != -EINVAL) {
+ pr_err("L2C-310 OF arm,double-linefill-wrap property value is missing\n");
+ }
+
+ ret = of_property_read_u32(np, "arm,prefetch-drop", &val);
+ if (ret == 0) {
+ if (val)
+ prefetch |= L310_PREFETCH_CTRL_PREFETCH_DROP;
+ else
+ prefetch &= ~L310_PREFETCH_CTRL_PREFETCH_DROP;
+ } else if (ret != -EINVAL) {
+ pr_err("L2C-310 OF arm,prefetch-drop property value is missing\n");
+ }
+
+ ret = of_property_read_u32(np, "arm,prefetch-offset", &val);
+ if (ret == 0) {
+ prefetch &= ~L310_PREFETCH_CTRL_OFFSET_MASK;
+ prefetch |= val & L310_PREFETCH_CTRL_OFFSET_MASK;
+ } else if (ret != -EINVAL) {
+ pr_err("L2C-310 OF arm,prefetch-offset property value is missing\n");
+ }
+
+ l2x0_saved_regs.prefetch_ctrl = prefetch;
+}
+
+static const struct l2c_init_data of_l2c310_data __initconst = {
+ .type = "L2C-310",
+ .way_size_0 = SZ_8K,
+ .num_lock = 8,
+ .of_parse = l2c310_of_parse,
+ .enable = l2c310_enable,
+ .fixup = l2c310_fixup,
+ .save = l2c310_save,
+ .configure = l2c310_configure,
+ .outer_cache = {
+ .inv_range = l2c210_inv_range,
+ .clean_range = l2c210_clean_range,
+ .flush_range = l2c210_flush_range,
+ .flush_all = l2c210_flush_all,
+ .disable = l2c310_disable,
+ .sync = l2c210_sync,
+ .resume = l2c310_resume,
+ },
+};
+
+/*
+ * This is a variant of the of_l2c310_data with .sync set to
+ * NULL. Outer sync operations are not needed when the system is I/O
+ * coherent, and potentially harmful in certain situations (PCIe/PL310
+ * deadlock on Armada 375/38x due to hardware I/O coherency). The
+ * other operations are kept because they are infrequent (therefore do
+ * not cause the deadlock in practice) and needed for secondary CPU
+ * boot and other power management activities.
+ */
+static const struct l2c_init_data of_l2c310_coherent_data __initconst = {
+ .type = "L2C-310 Coherent",
+ .way_size_0 = SZ_8K,
+ .num_lock = 8,
+ .of_parse = l2c310_of_parse,
+ .enable = l2c310_enable,
+ .fixup = l2c310_fixup,
+ .save = l2c310_save,
+ .configure = l2c310_configure,
+ .outer_cache = {
+ .inv_range = l2c210_inv_range,
+ .clean_range = l2c210_clean_range,
+ .flush_range = l2c210_flush_range,
+ .flush_all = l2c210_flush_all,
+ .disable = l2c310_disable,
+ .resume = l2c310_resume,
+ },
+};
+
+/*
+ * Note that the end addresses passed to Linux primitives are
+ * noninclusive, while the hardware cache range operations use
+ * inclusive start and end addresses.
+ */
+static unsigned long aurora_range_end(unsigned long start, unsigned long end)
+{
+ /*
+ * Limit the number of cache lines processed at once,
+ * since cache range operations stall the CPU pipeline
+ * until completion.
+ */
+ if (end > start + MAX_RANGE_SIZE)
+ end = start + MAX_RANGE_SIZE;
+
+ /*
+ * Cache range operations can't straddle a page boundary.
+ */
+ if (end > PAGE_ALIGN(start+1))
+ end = PAGE_ALIGN(start+1);
+
+ return end;
+}
+
+static void aurora_pa_range(unsigned long start, unsigned long end,
+ unsigned long offset)
+{
+ void __iomem *base = l2x0_base;
+ unsigned long range_end;
+ unsigned long flags;
+
+ /*
+ * round start and end adresses up to cache line size
+ */
+ start &= ~(CACHE_LINE_SIZE - 1);
+ end = ALIGN(end, CACHE_LINE_SIZE);
+
+ /*
+ * perform operation on all full cache lines between 'start' and 'end'
+ */
+ while (start < end) {
+ range_end = aurora_range_end(start, end);
+
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ writel_relaxed(start, base + AURORA_RANGE_BASE_ADDR_REG);
+ writel_relaxed(range_end - CACHE_LINE_SIZE, base + offset);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+
+ writel_relaxed(0, base + AURORA_SYNC_REG);
+ start = range_end;
+ }
+}
+static void aurora_inv_range(unsigned long start, unsigned long end)
+{
+ aurora_pa_range(start, end, AURORA_INVAL_RANGE_REG);
+}
+
+static void aurora_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)
+ aurora_pa_range(start, end, AURORA_CLEAN_RANGE_REG);
+}
+
+static void aurora_flush_range(unsigned long start, unsigned long end)
+{
+ if (l2_wt_override)
+ aurora_pa_range(start, end, AURORA_INVAL_RANGE_REG);
+ else
+ aurora_pa_range(start, end, AURORA_FLUSH_RANGE_REG);
+}
+
+static void aurora_flush_all(void)
+{
+ void __iomem *base = l2x0_base;
+ unsigned long flags;
+
+ /* clean all ways */
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+
+ writel_relaxed(0, base + AURORA_SYNC_REG);
+}
+
+static void aurora_cache_sync(void)
+{
+ writel_relaxed(0, l2x0_base + AURORA_SYNC_REG);
+}
+
+static void aurora_disable(void)
+{
+ void __iomem *base = l2x0_base;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
+ writel_relaxed(0, base + AURORA_SYNC_REG);
+ l2c_write_sec(0, base, L2X0_CTRL);
+ dsb(st);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void aurora_save(void __iomem *base)
+{
+ l2x0_saved_regs.ctrl = readl_relaxed(base + L2X0_CTRL);
+ l2x0_saved_regs.aux_ctrl = readl_relaxed(base + L2X0_AUX_CTRL);
+}
+
+/*
+ * For Aurora cache in no outer mode, enable via the CP15 coprocessor
+ * broadcasting of cache commands to L2.
+ */
+static void __init aurora_enable_no_outer(void __iomem *base, u32 aux,
+ unsigned num_lock)
+{
+ u32 u;
+
+ asm volatile("mrc p15, 1, %0, c15, c2, 0" : "=r" (u));
+ u |= AURORA_CTRL_FW; /* Set the FW bit */
+ asm volatile("mcr p15, 1, %0, c15, c2, 0" : : "r" (u));
+
+ isb();
+
+ l2c_enable(base, aux, num_lock);
+}
+
+static void __init aurora_fixup(void __iomem *base, u32 cache_id,
+ struct outer_cache_fns *fns)
+{
+ sync_reg_offset = AURORA_SYNC_REG;
+}
+
+static void __init aurora_of_parse(const struct device_node *np,
+ u32 *aux_val, u32 *aux_mask)
+{
+ u32 val = AURORA_ACR_REPLACEMENT_TYPE_SEMIPLRU;
+ u32 mask = AURORA_ACR_REPLACEMENT_MASK;
+
+ of_property_read_u32(np, "cache-id-part",
+ &cache_id_part_number_from_dt);
+
+ /* Determine and save the write policy */
+ l2_wt_override = of_property_read_bool(np, "wt-override");
+
+ if (l2_wt_override) {
+ val |= AURORA_ACR_FORCE_WRITE_THRO_POLICY;
+ mask |= AURORA_ACR_FORCE_WRITE_POLICY_MASK;
+ }
+
+ *aux_val &= ~mask;
+ *aux_val |= val;
+ *aux_mask &= ~mask;
+}
+
+static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
+ .type = "Aurora",
+ .way_size_0 = SZ_4K,
+ .num_lock = 4,
+ .of_parse = aurora_of_parse,
+ .enable = l2c_enable,
+ .fixup = aurora_fixup,
+ .save = aurora_save,
+ .outer_cache = {
+ .inv_range = aurora_inv_range,
+ .clean_range = aurora_clean_range,
+ .flush_range = aurora_flush_range,
+ .flush_all = aurora_flush_all,
+ .disable = aurora_disable,
+ .sync = aurora_cache_sync,
+ .resume = l2c_resume,
+ },
+};
+
+static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
+ .type = "Aurora",
+ .way_size_0 = SZ_4K,
+ .num_lock = 4,
+ .of_parse = aurora_of_parse,
+ .enable = aurora_enable_no_outer,
+ .fixup = aurora_fixup,
+ .save = aurora_save,
+ .outer_cache = {
+ .resume = l2c_resume,
+ },
+};
+
+/*
+ * For certain Broadcom SoCs, depending on the address range, different offsets
+ * need to be added to the address before passing it to L2 for
+ * invalidation/clean/flush
+ *
+ * Section Address Range Offset EMI
+ * 1 0x00000000 - 0x3FFFFFFF 0x80000000 VC
+ * 2 0x40000000 - 0xBFFFFFFF 0x40000000 SYS
+ * 3 0xC0000000 - 0xFFFFFFFF 0x80000000 VC
+ *
+ * When the start and end addresses have crossed two different sections, we
+ * need to break the L2 operation into two, each within its own section.
+ * For example, if we need to invalidate addresses starts at 0xBFFF0000 and
+ * ends at 0xC0001000, we need do invalidate 1) 0xBFFF0000 - 0xBFFFFFFF and 2)
+ * 0xC0000000 - 0xC0001000
+ *
+ * Note 1:
+ * By breaking a single L2 operation into two, we may potentially suffer some
+ * performance hit, but keep in mind the cross section case is very rare
+ *
+ * Note 2:
+ * We do not need to handle the case when the start address is in
+ * Section 1 and the end address is in Section 3, since it is not a valid use
+ * case
+ *
+ * Note 3:
+ * Section 1 in practical terms can no longer be used on rev A2. Because of
+ * that the code does not need to handle section 1 at all.
+ *
+ */
+#define BCM_SYS_EMI_START_ADDR 0x40000000UL
+#define BCM_VC_EMI_SEC3_START_ADDR 0xC0000000UL
+
+#define BCM_SYS_EMI_OFFSET 0x40000000UL
+#define BCM_VC_EMI_OFFSET 0x80000000UL
+
+static inline int bcm_addr_is_sys_emi(unsigned long addr)
+{
+ return (addr >= BCM_SYS_EMI_START_ADDR) &&
+ (addr < BCM_VC_EMI_SEC3_START_ADDR);
+}
+
+static inline unsigned long bcm_l2_phys_addr(unsigned long addr)
+{
+ if (bcm_addr_is_sys_emi(addr))
+ return addr + BCM_SYS_EMI_OFFSET;
+ else
+ return addr + BCM_VC_EMI_OFFSET;
+}
+
+static void bcm_inv_range(unsigned long start, unsigned long end)
+{
+ unsigned long new_start, new_end;
+
+ BUG_ON(start < BCM_SYS_EMI_START_ADDR);
+
+ if (unlikely(end <= start))
+ return;
+
+ new_start = bcm_l2_phys_addr(start);
+ new_end = bcm_l2_phys_addr(end);
+
+ /* normal case, no cross section between start and end */
+ if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
+ l2c210_inv_range(new_start, new_end);
+ return;
+ }
+
+ /* They cross sections, so it can only be a cross from section
+ * 2 to section 3
+ */
+ l2c210_inv_range(new_start,
+ bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
+ l2c210_inv_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
+ new_end);
+}
+
+static void bcm_clean_range(unsigned long start, unsigned long end)
+{
+ unsigned long new_start, new_end;
+
+ BUG_ON(start < BCM_SYS_EMI_START_ADDR);
+
+ if (unlikely(end <= start))
+ return;
+
+ new_start = bcm_l2_phys_addr(start);
+ new_end = bcm_l2_phys_addr(end);
+
+ /* normal case, no cross section between start and end */
+ if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
+ l2c210_clean_range(new_start, new_end);
+ return;
+ }
+
+ /* They cross sections, so it can only be a cross from section
+ * 2 to section 3
+ */
+ l2c210_clean_range(new_start,
+ bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
+ l2c210_clean_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
+ new_end);
+}
+
+static void bcm_flush_range(unsigned long start, unsigned long end)
+{
+ unsigned long new_start, new_end;
+
+ BUG_ON(start < BCM_SYS_EMI_START_ADDR);
+
+ if (unlikely(end <= start))
+ return;
+
+ if ((end - start) >= l2x0_size) {
+ outer_cache.flush_all();
+ return;
+ }
+
+ new_start = bcm_l2_phys_addr(start);
+ new_end = bcm_l2_phys_addr(end);
+
+ /* normal case, no cross section between start and end */
+ if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
+ l2c210_flush_range(new_start, new_end);
+ return;
+ }
+
+ /* They cross sections, so it can only be a cross from section
+ * 2 to section 3
+ */
+ l2c210_flush_range(new_start,
+ bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
+ l2c210_flush_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
+ new_end);
+}
+
+/* Broadcom L2C-310 start from ARMs R3P2 or later, and require no fixups */
+static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
+ .type = "BCM-L2C-310",
+ .way_size_0 = SZ_8K,
+ .num_lock = 8,
+ .of_parse = l2c310_of_parse,
+ .enable = l2c310_enable,
+ .save = l2c310_save,
+ .configure = l2c310_configure,
+ .outer_cache = {
+ .inv_range = bcm_inv_range,
+ .clean_range = bcm_clean_range,
+ .flush_range = bcm_flush_range,
+ .flush_all = l2c210_flush_all,
+ .disable = l2c310_disable,
+ .sync = l2c210_sync,
+ .resume = l2c310_resume,
+ },
+};
+
+static void __init tauros3_save(void __iomem *base)
+{
+ l2c_save(base);
+
+ l2x0_saved_regs.aux2_ctrl =
+ readl_relaxed(base + TAUROS3_AUX2_CTRL);
+ l2x0_saved_regs.prefetch_ctrl =
+ readl_relaxed(base + L310_PREFETCH_CTRL);
+}
+
+static void tauros3_configure(void __iomem *base)
+{
+ writel_relaxed(l2x0_saved_regs.aux2_ctrl,
+ base + TAUROS3_AUX2_CTRL);
+ writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
+ base + L310_PREFETCH_CTRL);
+}
+
+static const struct l2c_init_data of_tauros3_data __initconst = {
+ .type = "Tauros3",
+ .way_size_0 = SZ_8K,
+ .num_lock = 8,
+ .enable = l2c_enable,
+ .save = tauros3_save,
+ .configure = tauros3_configure,
+ /* Tauros3 broadcasts L1 cache operations to L2 */
+ .outer_cache = {
+ .resume = l2c_resume,
+ },
+};
+
+#define L2C_ID(name, fns) { .compatible = name, .data = (void *)&fns }
+static const struct of_device_id l2x0_ids[] __initconst = {
+ L2C_ID("arm,l210-cache", of_l2c210_data),
+ L2C_ID("arm,l220-cache", of_l2c220_data),
+ L2C_ID("arm,pl310-cache", of_l2c310_data),
+ L2C_ID("brcm,bcm11351-a2-pl310-cache", of_bcm_l2x0_data),
+ L2C_ID("marvell,aurora-outer-cache", of_aurora_with_outer_data),
+ L2C_ID("marvell,aurora-system-cache", of_aurora_no_outer_data),
+ L2C_ID("marvell,tauros3-cache", of_tauros3_data),
+ /* Deprecated IDs */
+ L2C_ID("bcm,bcm11351-a2-pl310-cache", of_bcm_l2x0_data),
+ {}
+};
+
+int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
+{
+ const struct l2c_init_data *data;
+ struct device_node *np;
+ struct resource res;
+ u32 cache_id, old_aux;
+ u32 cache_level = 2;
+
+ np = of_find_matching_node(NULL, l2x0_ids);
+ if (!np)
+ return -ENODEV;
+
+ if (of_address_to_resource(np, 0, &res))
+ return -ENODEV;
+
+ l2x0_base = ioremap(res.start, resource_size(&res));
+ if (!l2x0_base)
+ return -ENOMEM;
+
+ l2x0_saved_regs.phy_base = res.start;
+
+ data = of_match_node(l2x0_ids, np)->data;
+
+ if (of_device_is_compatible(np, "arm,pl310-cache") &&
+ of_property_read_bool(np, "arm,io-coherent"))
+ data = &of_l2c310_coherent_data;
+
+ old_aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
+ if (old_aux != ((old_aux & aux_mask) | aux_val)) {
+ pr_warn("L2C: platform modifies aux control register: 0x%08x -> 0x%08x\n",
+ old_aux, (old_aux & aux_mask) | aux_val);
+ } else if (aux_mask != ~0U && aux_val != 0) {
+ pr_alert("L2C: platform provided aux values match the hardware, so have no effect. Please remove them.\n");
+ }
+
+ /* All L2 caches are unified, so this property should be specified */
+ if (!of_property_read_bool(np, "cache-unified"))
+ pr_err("L2C: device tree omits to specify unified cache\n");
+
+ if (of_property_read_u32(np, "cache-level", &cache_level))
+ pr_err("L2C: device tree omits to specify cache-level\n");
+
+ if (cache_level != 2)
+ pr_err("L2C: device tree specifies invalid cache level\n");
+
+ /* Read back current (default) hardware configuration */
+ if (data->save)
+ data->save(l2x0_base);
+
+ /* L2 configuration can only be changed if the cache is disabled */
+ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN))
+ if (data->of_parse)
+ data->of_parse(np, &aux_val, &aux_mask);
+
+ if (cache_id_part_number_from_dt)
+ cache_id = cache_id_part_number_from_dt;
+ else
+ cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
+
+ return __l2c_init(data, aux_val, aux_mask, cache_id);
+}
+#endif
diff --git a/arch/arm/mm/cache-nop.S b/arch/arm/mm/cache-nop.S
new file mode 100644
index 000000000..f1cc98610
--- /dev/null
+++ b/arch/arm/mm/cache-nop.S
@@ -0,0 +1,51 @@
+/*
+ * This program is free software; you can redistribute it 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 "proc-macros.S"
+
+ENTRY(nop_flush_icache_all)
+ ret lr
+ENDPROC(nop_flush_icache_all)
+
+ .globl nop_flush_kern_cache_all
+ .equ nop_flush_kern_cache_all, nop_flush_icache_all
+
+ .globl nop_flush_kern_cache_louis
+ .equ nop_flush_kern_cache_louis, nop_flush_icache_all
+
+ .globl nop_flush_user_cache_all
+ .equ nop_flush_user_cache_all, nop_flush_icache_all
+
+ .globl nop_flush_user_cache_range
+ .equ nop_flush_user_cache_range, nop_flush_icache_all
+
+ .globl nop_coherent_kern_range
+ .equ nop_coherent_kern_range, nop_flush_icache_all
+
+ENTRY(nop_coherent_user_range)
+ mov r0, 0
+ ret lr
+ENDPROC(nop_coherent_user_range)
+
+ .globl nop_flush_kern_dcache_area
+ .equ nop_flush_kern_dcache_area, nop_flush_icache_all
+
+ .globl nop_dma_flush_range
+ .equ nop_dma_flush_range, nop_flush_icache_all
+
+ .globl nop_dma_map_area
+ .equ nop_dma_map_area, nop_flush_icache_all
+
+ .globl nop_dma_unmap_area
+ .equ nop_dma_unmap_area, nop_flush_icache_all
+
+ __INITDATA
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions nop
diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c
new file mode 100644
index 000000000..1e373d268
--- /dev/null
+++ b/arch/arm/mm/cache-tauros2.c
@@ -0,0 +1,302 @@
+/*
+ * 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 <linux/of.h>
+#include <linux/of_address.h>
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+#include <asm/cputype.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.
+ */
+#ifdef CONFIG_CPU_32v5
+/*
+ * 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();
+}
+
+static void tauros2_disable(void)
+{
+ __asm__ __volatile__ (
+ "mcr p15, 1, %0, c7, c11, 0 @L2 Cache Clean All\n\t"
+ "mrc p15, 0, %0, c1, c0, 0\n\t"
+ "bic %0, %0, #(1 << 26)\n\t"
+ "mcr p15, 0, %0, c1, c0, 0 @Disable L2 Cache\n\t"
+ : : "r" (0x0));
+}
+
+static void tauros2_resume(void)
+{
+ __asm__ __volatile__ (
+ "mcr p15, 1, %0, c7, c7, 0 @L2 Cache Invalidate All\n\t"
+ "mrc p15, 0, %0, c1, c0, 0\n\t"
+ "orr %0, %0, #(1 << 26)\n\t"
+ "mcr p15, 0, %0, c1, c0, 0 @Enable L2 Cache\n\t"
+ : : "r" (0x0));
+}
+#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 inline int __init cpuid_scheme(void)
+{
+ 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));
+}
+
+static void enable_extra_feature(unsigned int features)
+{
+ u32 u;
+
+ u = read_extra_features();
+
+ if (features & CACHE_TAUROS2_PREFETCH_ON)
+ u &= ~0x01000000;
+ else
+ u |= 0x01000000;
+ pr_info("Tauros2: %s L2 prefetch.\n",
+ (features & CACHE_TAUROS2_PREFETCH_ON)
+ ? "Enabling" : "Disabling");
+
+ if (features & CACHE_TAUROS2_LINEFILL_BURST8)
+ u |= 0x00100000;
+ else
+ u &= ~0x00100000;
+ pr_info("Tauros2: %s line fill burt8.\n",
+ (features & CACHE_TAUROS2_LINEFILL_BURST8)
+ ? "Enabling" : "Disabling");
+
+ write_extra_features(u);
+}
+
+static void __init tauros2_internal_init(unsigned int features)
+{
+ char *mode = NULL;
+
+ enable_extra_feature(features);
+
+#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)) {
+ pr_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;
+ outer_cache.disable = tauros2_disable;
+ outer_cache.resume = tauros2_resume;
+ }
+#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)) {
+ pr_info("Tauros2: Enabling L2 cache.\n");
+ write_actlr(actlr | 0x00000002);
+ }
+
+ mode = "ARMv7";
+ }
+#endif
+
+ if (mode == NULL) {
+ pr_crit("Tauros2: Unable to detect CPU mode.\n");
+ return;
+ }
+
+ pr_info("Tauros2: L2 cache support initialised "
+ "in %s mode.\n", mode);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id tauros2_ids[] __initconst = {
+ { .compatible = "marvell,tauros2-cache"},
+ {}
+};
+#endif
+
+void __init tauros2_init(unsigned int features)
+{
+#ifdef CONFIG_OF
+ struct device_node *node;
+ int ret;
+ unsigned int f;
+
+ node = of_find_matching_node(NULL, tauros2_ids);
+ if (!node) {
+ pr_info("Not found marvell,tauros2-cache, disable it\n");
+ return;
+ }
+
+ ret = of_property_read_u32(node, "marvell,tauros2-cache-features", &f);
+ if (ret) {
+ pr_info("Not found marvell,tauros-cache-features property, "
+ "disable extra features\n");
+ features = 0;
+ } else
+ features = f;
+#endif
+ tauros2_internal_init(features);
+}
diff --git a/arch/arm/mm/cache-tauros3.h b/arch/arm/mm/cache-tauros3.h
new file mode 100644
index 000000000..02c0a97cb
--- /dev/null
+++ b/arch/arm/mm/cache-tauros3.h
@@ -0,0 +1,41 @@
+/*
+ * Marvell Tauros3 cache controller includes
+ *
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * based on GPL'ed 2.6 kernel sources
+ * (c) 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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_TAUROS3_H
+#define __ASM_ARM_HARDWARE_TAUROS3_H
+
+/*
+ * Marvell Tauros3 L2CC is compatible with PL310 r0p0
+ * but with PREFETCH_CTRL (r2p0) and an additional event counter.
+ * Also, there is AUX2_CTRL for some Marvell specific control.
+ */
+
+#define TAUROS3_EVENT_CNT2_CFG 0x224
+#define TAUROS3_EVENT_CNT2_VAL 0x228
+#define TAUROS3_INV_ALL 0x780
+#define TAUROS3_CLEAN_ALL 0x784
+#define TAUROS3_AUX2_CTRL 0x820
+
+/* Registers shifts and masks */
+#define TAUROS3_AUX2_CTRL_LINEFILL_BURST8_EN (1 << 2)
+
+#endif
diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S
new file mode 100644
index 000000000..91e3adf15
--- /dev/null
+++ b/arch/arm/mm/cache-v4.S
@@ -0,0 +1,150 @@
+/*
+ * 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/assembler.h>
+#include <asm/page.h>
+#include "proc-macros.S"
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(v4_flush_icache_all)
+ ret 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
+ ret 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
+ mcr p15, 0, ip, c7, c7, 0 @ flush ID cache
+ ret 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 r0, #0
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(v4_dma_unmap_area)
+ENDPROC(v4_dma_map_area)
+
+ .globl v4_flush_kern_cache_louis
+ .equ v4_flush_kern_cache_louis, v4_flush_kern_cache_all
+
+ __INITDATA
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v4
diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S
new file mode 100644
index 000000000..2522f8c8f
--- /dev/null
+++ b/arch/arm/mm/cache-v4wb.S
@@ -0,0 +1,261 @@
+/*
+ * 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/assembler.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
+ ret 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
+ ret 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
+ ret 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 r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ ret 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
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(v4wb_dma_unmap_area)
+
+ .globl v4wb_flush_kern_cache_louis
+ .equ v4wb_flush_kern_cache_louis, v4wb_flush_kern_cache_all
+
+ __INITDATA
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v4wb
diff --git a/arch/arm/mm/cache-v4wt.S b/arch/arm/mm/cache-v4wt.S
new file mode 100644
index 000000000..a0982ce49
--- /dev/null
+++ b/arch/arm/mm/cache-v4wt.S
@@ -0,0 +1,206 @@
+/*
+ * 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/assembler.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
+ ret 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
+ ret 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
+ ret 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 r0, #0
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(v4wt_dma_unmap_area)
+ENDPROC(v4wt_dma_map_area)
+
+ .globl v4wt_flush_kern_cache_louis
+ .equ v4wt_flush_kern_cache_louis, v4wt_flush_kern_cache_all
+
+ __INITDATA
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v4wt
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S
new file mode 100644
index 000000000..24659952c
--- /dev/null
+++ b/arch/arm/mm/cache-v6.S
@@ -0,0 +1,335 @@
+/*
+ * 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/errno.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
+ ret 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
+ ret 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)
+ ret 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
+ 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
+ ret lr
+
+/*
+ * Fault handling for the cache operation above. If the virtual address in r0
+ * isn't mapped, fail with -EFAULT.
+ */
+9001:
+ mov r0, #-EFAULT
+ ret lr
+ 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
+ ret 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
+ ret 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
+ ret 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_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
+ ret lr
+
+/*
+ * 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
+ ret lr
+ENDPROC(v6_dma_unmap_area)
+
+ .globl v6_flush_kern_cache_louis
+ .equ v6_flush_kern_cache_louis, v6_flush_kern_cache_all
+
+ __INITDATA
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v6
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
new file mode 100644
index 000000000..a134d8a13
--- /dev/null
+++ b/arch/arm/mm/cache-v7.S
@@ -0,0 +1,448 @@
+/*
+ * 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/errno.h>
+#include <asm/unwind.h>
+
+#include "proc-macros.S"
+
+/*
+ * 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.
+ *
+ * This function is cloned from arch/arm/mach-tegra/headsmp.S, and needs
+ * to be called for both secondary cores startup and primary core resume
+ * procedures.
+ */
+ENTRY(v7_invalidate_l1)
+ mov r0, #0
+ mcr p15, 2, r0, c0, c0, 0
+ mrc p15, 1, r0, c0, c0, 0
+
+ movw r1, #0x7fff
+ and r2, r1, r0, lsr #13
+
+ movw 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 st
+ isb
+ ret lr
+ENDPROC(v7_invalidate_l1)
+
+/*
+ * 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
+ ret lr
+ENDPROC(v7_flush_icache_all)
+
+ /*
+ * v7_flush_dcache_louis()
+ *
+ * Flush the D-cache up to the Level of Unification Inner Shareable
+ *
+ * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
+ */
+
+ENTRY(v7_flush_dcache_louis)
+ dmb @ ensure ordering with previous memory accesses
+ mrc p15, 1, r0, c0, c0, 1 @ read clidr, r0 = clidr
+ALT_SMP(mov r3, r0, lsr #20) @ move LoUIS into position
+ALT_UP( mov r3, r0, lsr #26) @ move LoUU into position
+ ands r3, r3, #7 << 1 @ extract LoU*2 field from clidr
+ bne start_flush_levels @ LoU != 0, start flushing
+#ifdef CONFIG_ARM_ERRATA_643719
+ALT_SMP(mrc p15, 0, r2, c0, c0, 0) @ read main ID register
+ALT_UP( ret lr) @ LoUU is zero, so nothing to do
+ movw r1, #:lower16:(0x410fc090 >> 4) @ ID of ARM Cortex A9 r0p?
+ movt r1, #:upper16:(0x410fc090 >> 4)
+ teq r1, r2, lsr #4 @ test for errata affected core and if so...
+ moveq r3, #1 << 1 @ fix LoUIS value
+ beq start_flush_levels @ start flushing cache levels
+#endif
+ ret lr
+ENDPROC(v7_flush_dcache_louis)
+
+/*
+ * 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
+ mov r3, r0, lsr #23 @ move LoC into position
+ ands r3, r3, #7 << 1 @ extract LoC*2 from clidr
+ beq finished @ if loc is 0, then no need to clean
+start_flush_levels:
+ mov r10, #0 @ start clean at cache level 0
+flush_levels:
+ 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)
+ movw 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
+ movw r7, #0x7fff
+ ands r7, r7, r1, lsr #13 @ extract max number of the index size
+loop1:
+ mov r9, r7 @ create working copy of max index
+loop2:
+ ARM( orr r11, r10, r4, lsl r5 ) @ factor way and cache number into r11
+ THUMB( lsl r6, r4, r5 )
+ THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
+ ARM( orr r11, r11, r9, lsl r2 ) @ factor index number into r11
+ THUMB( lsl r6, r9, 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 index
+ bge loop2
+ subs r4, r4, #1 @ decrement the way
+ bge loop1
+skip:
+ add r10, r10, #2 @ increment cache number
+ cmp r3, r10
+ bgt flush_levels
+finished:
+ mov r10, #0 @ swith back to cache level 0
+ mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
+ dsb st
+ isb
+ ret 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} )
+ ret lr
+ENDPROC(v7_flush_kern_cache_all)
+
+ /*
+ * v7_flush_kern_cache_louis(void)
+ *
+ * Flush the data cache up to Level of Unification Inner Shareable.
+ * Invalidate the I-cache to the point of unification.
+ */
+ENTRY(v7_flush_kern_cache_louis)
+ ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} )
+ THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
+ bl v7_flush_dcache_louis
+ 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} )
+ ret lr
+ENDPROC(v7_flush_kern_cache_louis)
+
+/*
+ * 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)
+ ret 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 ishst
+ 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
+ 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 ishst
+ isb
+ ret lr
+
+/*
+ * Fault handling for the cache operation above. If the virtual address in r0
+ * isn't mapped, fail with -EFAULT.
+ */
+9001:
+#ifdef CONFIG_ARM_ERRATA_775420
+ dsb
+#endif
+ mov r0, #-EFAULT
+ ret lr
+ 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 st
+ ret 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 st
+ ret 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 st
+ ret 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 st
+ ret 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
+ ret lr
+ENDPROC(v7_dma_unmap_area)
+
+ __INITDATA
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v7
diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c
new file mode 100644
index 000000000..6c3edeb66
--- /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/cp15.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 000000000..845769e41
--- /dev/null
+++ b/arch/arm/mm/context.c
@@ -0,0 +1,266 @@
+/*
+ * linux/arch/arm/mm/context.c
+ *
+ * Copyright (C) 2002-2003 Deep Blue Solutions Ltd, all rights reserved.
+ * Copyright (C) 2012 ARM Limited
+ *
+ * Author: Will Deacon <will.deacon@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/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/smp_plat.h>
+#include <asm/thread_notify.h>
+#include <asm/tlbflush.h>
+#include <asm/proc-fns.h>
+
+/*
+ * 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.
+ *
+ * In big endian operation, the two 32 bit words are swapped if accessed
+ * by non-64-bit operations.
+ */
+#define ASID_FIRST_VERSION (1ULL << ASID_BITS)
+#define NUM_USER_ASIDS ASID_FIRST_VERSION
+
+static DEFINE_RAW_SPINLOCK(cpu_asid_lock);
+static atomic64_t asid_generation = ATOMIC64_INIT(ASID_FIRST_VERSION);
+static DECLARE_BITMAP(asid_map, NUM_USER_ASIDS);
+
+static DEFINE_PER_CPU(atomic64_t, active_asids);
+static DEFINE_PER_CPU(u64, reserved_asids);
+static cpumask_t tlb_flush_pending;
+
+#ifdef CONFIG_ARM_ERRATA_798181
+void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm,
+ cpumask_t *mask)
+{
+ int cpu;
+ unsigned long flags;
+ u64 context_id, asid;
+
+ raw_spin_lock_irqsave(&cpu_asid_lock, flags);
+ context_id = mm->context.id.counter;
+ for_each_online_cpu(cpu) {
+ if (cpu == this_cpu)
+ continue;
+ /*
+ * We only need to send an IPI if the other CPUs are
+ * running the same ASID as the one being invalidated.
+ */
+ asid = per_cpu(active_asids, cpu).counter;
+ if (asid == 0)
+ asid = per_cpu(reserved_asids, cpu);
+ if (context_id == asid)
+ cpumask_set_cpu(cpu, mask);
+ }
+ raw_spin_unlock_irqrestore(&cpu_asid_lock, flags);
+}
+#endif
+
+#ifdef CONFIG_ARM_LPAE
+/*
+ * With LPAE, the ASID and page tables are updated atomicly, so there is
+ * no need for a reserved set of tables (the active ASID tracking prevents
+ * any issues across a rollover).
+ */
+#define cpu_set_reserved_ttbr0()
+#else
+static void cpu_set_reserved_ttbr0(void)
+{
+ u32 ttb;
+ /*
+ * Copy TTBR1 into TTBR0.
+ * This points at swapper_pg_dir, which contains only global
+ * entries so any speculative walks are perfectly safe.
+ */
+ asm volatile(
+ " mrc p15, 0, %0, c2, c0, 1 @ read TTBR1\n"
+ " mcr p15, 0, %0, c2, c0, 0 @ set TTBR0\n"
+ : "=r" (ttb));
+ isb();
+}
+#endif
+
+#ifdef CONFIG_PID_IN_CONTEXTIDR
+static int contextidr_notifier(struct notifier_block *unused, unsigned long cmd,
+ void *t)
+{
+ u32 contextidr;
+ pid_t pid;
+ struct thread_info *thread = t;
+
+ if (cmd != THREAD_NOTIFY_SWITCH)
+ return NOTIFY_DONE;
+
+ pid = task_pid_nr(thread->task) << ASID_BITS;
+ asm volatile(
+ " mrc p15, 0, %0, c13, c0, 1\n"
+ " and %0, %0, %2\n"
+ " orr %0, %0, %1\n"
+ " mcr p15, 0, %0, c13, c0, 1\n"
+ : "=r" (contextidr), "+r" (pid)
+ : "I" (~ASID_MASK));
+ isb();
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block contextidr_notifier_block = {
+ .notifier_call = contextidr_notifier,
+};
+
+static int __init contextidr_notifier_init(void)
+{
+ return thread_register_notifier(&contextidr_notifier_block);
+}
+arch_initcall(contextidr_notifier_init);
+#endif
+
+static void flush_context(unsigned int cpu)
+{
+ int i;
+ u64 asid;
+
+ /* Update the list of reserved ASIDs and the ASID bitmap. */
+ bitmap_clear(asid_map, 0, NUM_USER_ASIDS);
+ for_each_possible_cpu(i) {
+ asid = atomic64_xchg(&per_cpu(active_asids, i), 0);
+ /*
+ * If this CPU has already been through a
+ * rollover, but hasn't run another task in
+ * the meantime, we must preserve its reserved
+ * ASID, as this is the only trace we have of
+ * the process it is still running.
+ */
+ if (asid == 0)
+ asid = per_cpu(reserved_asids, i);
+ __set_bit(asid & ~ASID_MASK, asid_map);
+ per_cpu(reserved_asids, i) = asid;
+ }
+
+ /* Queue a TLB invalidate and flush the I-cache if necessary. */
+ cpumask_setall(&tlb_flush_pending);
+
+ if (icache_is_vivt_asid_tagged())
+ __flush_icache_all();
+}
+
+static int is_reserved_asid(u64 asid)
+{
+ int cpu;
+ for_each_possible_cpu(cpu)
+ if (per_cpu(reserved_asids, cpu) == asid)
+ return 1;
+ return 0;
+}
+
+static u64 new_context(struct mm_struct *mm, unsigned int cpu)
+{
+ static u32 cur_idx = 1;
+ u64 asid = atomic64_read(&mm->context.id);
+ u64 generation = atomic64_read(&asid_generation);
+
+ if (asid != 0) {
+ /*
+ * If our current ASID was active during a rollover, we
+ * can continue to use it and this was just a false alarm.
+ */
+ if (is_reserved_asid(asid))
+ return generation | (asid & ~ASID_MASK);
+
+ /*
+ * We had a valid ASID in a previous life, so try to re-use
+ * it if possible.,
+ */
+ asid &= ~ASID_MASK;
+ if (!__test_and_set_bit(asid, asid_map))
+ goto bump_gen;
+ }
+
+ /*
+ * Allocate a free ASID. If we can't find one, take a note of the
+ * currently active ASIDs and mark the TLBs as requiring flushes.
+ * We always count from ASID #1, as we reserve ASID #0 to switch
+ * via TTBR0 and to avoid speculative page table walks from hitting
+ * in any partial walk caches, which could be populated from
+ * overlapping level-1 descriptors used to map both the module
+ * area and the userspace stack.
+ */
+ asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, cur_idx);
+ if (asid == NUM_USER_ASIDS) {
+ generation = atomic64_add_return(ASID_FIRST_VERSION,
+ &asid_generation);
+ flush_context(cpu);
+ asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1);
+ }
+
+ __set_bit(asid, asid_map);
+ cur_idx = asid;
+
+bump_gen:
+ asid |= generation;
+ cpumask_clear(mm_cpumask(mm));
+ return asid;
+}
+
+void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
+{
+ unsigned long flags;
+ unsigned int cpu = smp_processor_id();
+ u64 asid;
+
+ if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq))
+ __check_vmalloc_seq(mm);
+
+ /*
+ * We cannot update the pgd and the ASID atomicly with classic
+ * MMU, so switch exclusively to global mappings to avoid
+ * speculative page table walking with the wrong TTBR.
+ */
+ cpu_set_reserved_ttbr0();
+
+ asid = atomic64_read(&mm->context.id);
+ if (!((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS)
+ && atomic64_xchg(&per_cpu(active_asids, cpu), asid))
+ goto switch_mm_fastpath;
+
+ raw_spin_lock_irqsave(&cpu_asid_lock, flags);
+ /* Check that our ASID belongs to the current generation. */
+ asid = atomic64_read(&mm->context.id);
+ if ((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS) {
+ asid = new_context(mm, cpu);
+ atomic64_set(&mm->context.id, asid);
+ }
+
+ if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) {
+ local_flush_bp_all();
+ local_flush_tlb_all();
+ }
+
+ atomic64_set(&per_cpu(active_asids, cpu), asid);
+ cpumask_set_cpu(cpu, mm_cpumask(mm));
+ raw_spin_unlock_irqrestore(&cpu_asid_lock, flags);
+
+switch_mm_fastpath:
+ cpu_switch_mm(mm->pgd, mm);
+}
diff --git a/arch/arm/mm/copypage-fa.c b/arch/arm/mm/copypage-fa.c
new file mode 100644
index 000000000..d130a5ece
--- /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);
+ kfrom = kmap_atomic(from);
+ fa_copy_user_page(kto, kfrom);
+ kunmap_atomic(kfrom);
+ kunmap_atomic(kto);
+}
+
+/*
+ * 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);
+ 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);
+}
+
+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 000000000..49ee0c1a7
--- /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);
+ kfrom = kmap_atomic(from);
+ flush_cache_page(vma, vaddr, page_to_pfn(from));
+ feroceon_copy_user_page(kto, kfrom);
+ kunmap_atomic(kfrom);
+ kunmap_atomic(kto);
+}
+
+void feroceon_clear_user_highpage(struct page *page, unsigned long vaddr)
+{
+ void *ptr, *kaddr = kmap_atomic(page);
+ 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);
+}
+
+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-v4mc.c b/arch/arm/mm/copypage-v4mc.c
new file mode 100644
index 000000000..1267e6413
--- /dev/null
+++ b/arch/arm/mm/copypage-v4mc.c
@@ -0,0 +1,115 @@
+/*
+ * 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"
+
+#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
+ L_PTE_MT_MINICACHE)
+
+static DEFINE_RAW_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);
+
+ if (!test_and_set_bit(PG_dcache_clean, &from->flags))
+ __flush_dcache_page(page_mapping(from), from);
+
+ raw_spin_lock(&minicache_lock);
+
+ set_top_pte(COPYPAGE_MINICACHE, mk_pte(from, minicache_pgprot));
+
+ mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
+
+ raw_spin_unlock(&minicache_lock);
+
+ kunmap_atomic(kto);
+}
+
+/*
+ * ARMv4 optimised clear_user_page
+ */
+void v4_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
+{
+ void *ptr, *kaddr = kmap_atomic(page);
+ 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);
+}
+
+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 000000000..067d0fdd6
--- /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);
+ kfrom = kmap_atomic(from);
+ flush_cache_page(vma, vaddr, page_to_pfn(from));
+ v4wb_copy_user_page(kto, kfrom);
+ kunmap_atomic(kfrom);
+ kunmap_atomic(kto);
+}
+
+/*
+ * 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);
+ 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);
+}
+
+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 000000000..b85c5da2e
--- /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);
+ kfrom = kmap_atomic(from);
+ v4wt_copy_user_page(kto, kfrom);
+ kunmap_atomic(kfrom);
+ kunmap_atomic(kto);
+}
+
+/*
+ * 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);
+ 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);
+}
+
+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 000000000..70423345d
--- /dev/null
+++ b/arch/arm/mm/copypage-v6.c
@@ -0,0 +1,140 @@
+/*
+ * 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
+
+static DEFINE_RAW_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);
+ kto = kmap_atomic(to);
+ copy_page(kto, kfrom);
+ kunmap_atomic(kto);
+ kunmap_atomic(kfrom);
+}
+
+/*
+ * 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);
+ clear_page(kaddr);
+ kunmap_atomic(kaddr);
+}
+
+/*
+ * 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 - 1)
+ : "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.
+ */
+ raw_spin_lock(&v6_lock);
+
+ kfrom = COPYPAGE_V6_FROM + (offset << PAGE_SHIFT);
+ kto = COPYPAGE_V6_TO + (offset << PAGE_SHIFT);
+
+ set_top_pte(kfrom, mk_pte(from, PAGE_KERNEL));
+ set_top_pte(kto, mk_pte(to, PAGE_KERNEL));
+
+ copy_page((void *)kto, (void *)kfrom);
+
+ raw_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 long to = COPYPAGE_V6_TO + (CACHE_COLOUR(vaddr) << 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.
+ */
+ raw_spin_lock(&v6_lock);
+
+ set_top_pte(to, mk_pte(page, PAGE_KERNEL));
+ clear_page((void *)to);
+
+ raw_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 000000000..03a2042ac
--- /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);
+ kfrom = kmap_atomic(from);
+ flush_cache_page(vma, vaddr, page_to_pfn(from));
+ xsc3_mc_copy_user_page(kto, kfrom);
+ kunmap_atomic(kfrom);
+ kunmap_atomic(kto);
+}
+
+/*
+ * 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);
+ 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);
+}
+
+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 000000000..0fb850253
--- /dev/null
+++ b/arch/arm/mm/copypage-xscale.c
@@ -0,0 +1,135 @@
+/*
+ * 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"
+
+#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
+ L_PTE_MT_MINICACHE)
+
+static DEFINE_RAW_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);
+
+ if (!test_and_set_bit(PG_dcache_clean, &from->flags))
+ __flush_dcache_page(page_mapping(from), from);
+
+ raw_spin_lock(&minicache_lock);
+
+ set_top_pte(COPYPAGE_MINICACHE, mk_pte(from, minicache_pgprot));
+
+ mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
+
+ raw_spin_unlock(&minicache_lock);
+
+ kunmap_atomic(kto);
+}
+
+/*
+ * XScale optimised clear_user_page
+ */
+void
+xscale_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
+{
+ void *ptr, *kaddr = kmap_atomic(page);
+ 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);
+}
+
+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 000000000..7e7583ddd
--- /dev/null
+++ b/arch/arm/mm/dma-mapping.c
@@ -0,0 +1,2128 @@
+/*
+ * 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/bootmem.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/genalloc.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/dma-contiguous.h>
+#include <linux/highmem.h>
+#include <linux/memblock.h>
+#include <linux/slab.h>
+#include <linux/iommu.h>
+#include <linux/io.h>
+#include <linux/vmalloc.h>
+#include <linux/sizes.h>
+#include <linux/cma.h>
+
+#include <asm/memory.h>
+#include <asm/highmem.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/mach/arch.h>
+#include <asm/dma-iommu.h>
+#include <asm/mach/map.h>
+#include <asm/system_info.h>
+#include <asm/dma-contiguous.h>
+
+#include "mm.h"
+
+/*
+ * 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.
+ *
+ */
+static void __dma_page_cpu_to_dev(struct page *, unsigned long,
+ size_t, enum dma_data_direction);
+static void __dma_page_dev_to_cpu(struct page *, unsigned long,
+ size_t, enum dma_data_direction);
+
+/**
+ * arm_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 dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ __dma_page_cpu_to_dev(page, offset, size, dir);
+ return pfn_to_dma(dev, page_to_pfn(page)) + offset;
+}
+
+static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ return pfn_to_dma(dev, page_to_pfn(page)) + offset;
+}
+
+/**
+ * arm_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 void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
+ handle & ~PAGE_MASK, size, dir);
+}
+
+static void arm_dma_sync_single_for_cpu(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ unsigned int offset = handle & (PAGE_SIZE - 1);
+ struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
+ __dma_page_dev_to_cpu(page, offset, size, dir);
+}
+
+static void arm_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ unsigned int offset = handle & (PAGE_SIZE - 1);
+ struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
+ __dma_page_cpu_to_dev(page, offset, size, dir);
+}
+
+struct dma_map_ops arm_dma_ops = {
+ .alloc = arm_dma_alloc,
+ .free = arm_dma_free,
+ .mmap = arm_dma_mmap,
+ .get_sgtable = arm_dma_get_sgtable,
+ .map_page = arm_dma_map_page,
+ .unmap_page = arm_dma_unmap_page,
+ .map_sg = arm_dma_map_sg,
+ .unmap_sg = arm_dma_unmap_sg,
+ .sync_single_for_cpu = arm_dma_sync_single_for_cpu,
+ .sync_single_for_device = arm_dma_sync_single_for_device,
+ .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu,
+ .sync_sg_for_device = arm_dma_sync_sg_for_device,
+ .set_dma_mask = arm_dma_set_mask,
+};
+EXPORT_SYMBOL(arm_dma_ops);
+
+static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
+ dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs);
+static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle, struct dma_attrs *attrs);
+
+struct dma_map_ops arm_coherent_dma_ops = {
+ .alloc = arm_coherent_dma_alloc,
+ .free = arm_coherent_dma_free,
+ .mmap = arm_dma_mmap,
+ .get_sgtable = arm_dma_get_sgtable,
+ .map_page = arm_coherent_dma_map_page,
+ .map_sg = arm_dma_map_sg,
+ .set_dma_mask = arm_dma_set_mask,
+};
+EXPORT_SYMBOL(arm_coherent_dma_ops);
+
+static int __dma_supported(struct device *dev, u64 mask, bool warn)
+{
+ unsigned long max_dma_pfn;
+
+ /*
+ * If the mask allows for more memory than we can address,
+ * and we actually have that much memory, then we must
+ * indicate that DMA to this device is not supported.
+ */
+ if (sizeof(mask) != sizeof(dma_addr_t) &&
+ mask > (dma_addr_t)~0 &&
+ dma_to_pfn(dev, ~0) < max_pfn - 1) {
+ if (warn) {
+ dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n",
+ mask);
+ dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n");
+ }
+ return 0;
+ }
+
+ max_dma_pfn = min(max_pfn, arm_dma_pfn_limit);
+
+ /*
+ * Translate the device's DMA mask to a PFN limit. This
+ * PFN number includes the page which we can DMA to.
+ */
+ if (dma_to_pfn(dev, mask) < max_dma_pfn) {
+ if (warn)
+ dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n",
+ mask,
+ dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1,
+ max_dma_pfn + 1);
+ return 0;
+ }
+
+ return 1;
+}
+
+static u64 get_coherent_dma_mask(struct device *dev)
+{
+ u64 mask = (u64)DMA_BIT_MASK(32);
+
+ 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 (!__dma_supported(dev, mask, true))
+ return 0;
+ }
+
+ return mask;
+}
+
+static void __dma_clear_buffer(struct page *page, size_t size)
+{
+ /*
+ * Ensure that the allocated pages are zeroed, and that any data
+ * lurking in the kernel direct-mapped region is invalidated.
+ */
+ if (PageHighMem(page)) {
+ phys_addr_t base = __pfn_to_phys(page_to_pfn(page));
+ phys_addr_t end = base + size;
+ while (size > 0) {
+ void *ptr = kmap_atomic(page);
+ memset(ptr, 0, PAGE_SIZE);
+ dmac_flush_range(ptr, ptr + PAGE_SIZE);
+ kunmap_atomic(ptr);
+ page++;
+ size -= PAGE_SIZE;
+ }
+ outer_flush_range(base, end);
+ } else {
+ void *ptr = page_address(page);
+ memset(ptr, 0, size);
+ dmac_flush_range(ptr, ptr + size);
+ outer_flush_range(__pa(ptr), __pa(ptr) + size);
+ }
+}
+
+/*
+ * 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;
+
+ 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);
+
+ __dma_clear_buffer(page, 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
+
+static void *__alloc_from_contiguous(struct device *dev, size_t size,
+ pgprot_t prot, struct page **ret_page,
+ const void *caller, bool want_vaddr);
+
+static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
+ pgprot_t prot, struct page **ret_page,
+ const void *caller, bool want_vaddr);
+
+static void *
+__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
+ const void *caller)
+{
+ /*
+ * DMA allocation can be mapped to user space, so lets
+ * set VM_USERMAP flags too.
+ */
+ return dma_common_contiguous_remap(page, size,
+ VM_ARM_DMA_CONSISTENT | VM_USERMAP,
+ prot, caller);
+}
+
+static void __dma_free_remap(void *cpu_addr, size_t size)
+{
+ dma_common_free_remap(cpu_addr, size,
+ VM_ARM_DMA_CONSISTENT | VM_USERMAP);
+}
+
+#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K
+static struct gen_pool *atomic_pool;
+
+static size_t atomic_pool_size = DEFAULT_DMA_COHERENT_POOL_SIZE;
+
+static int __init early_coherent_pool(char *p)
+{
+ atomic_pool_size = memparse(p, &p);
+ return 0;
+}
+early_param("coherent_pool", early_coherent_pool);
+
+void __init init_dma_coherent_pool_size(unsigned long size)
+{
+ /*
+ * Catch any attempt to set the pool size too late.
+ */
+ BUG_ON(atomic_pool);
+
+ /*
+ * Set architecture specific coherent pool size only if
+ * it has not been changed by kernel command line parameter.
+ */
+ if (atomic_pool_size == DEFAULT_DMA_COHERENT_POOL_SIZE)
+ atomic_pool_size = size;
+}
+
+/*
+ * Initialise the coherent pool for atomic allocations.
+ */
+static int __init atomic_pool_init(void)
+{
+ pgprot_t prot = pgprot_dmacoherent(PAGE_KERNEL);
+ gfp_t gfp = GFP_KERNEL | GFP_DMA;
+ struct page *page;
+ void *ptr;
+
+ atomic_pool = gen_pool_create(PAGE_SHIFT, -1);
+ if (!atomic_pool)
+ goto out;
+
+ if (dev_get_cma_area(NULL))
+ ptr = __alloc_from_contiguous(NULL, atomic_pool_size, prot,
+ &page, atomic_pool_init, true);
+ else
+ ptr = __alloc_remap_buffer(NULL, atomic_pool_size, gfp, prot,
+ &page, atomic_pool_init, true);
+ if (ptr) {
+ int ret;
+
+ ret = gen_pool_add_virt(atomic_pool, (unsigned long)ptr,
+ page_to_phys(page),
+ atomic_pool_size, -1);
+ if (ret)
+ goto destroy_genpool;
+
+ gen_pool_set_algo(atomic_pool,
+ gen_pool_first_fit_order_align,
+ (void *)PAGE_SHIFT);
+ pr_info("DMA: preallocated %zd KiB pool for atomic coherent allocations\n",
+ atomic_pool_size / 1024);
+ return 0;
+ }
+
+destroy_genpool:
+ gen_pool_destroy(atomic_pool);
+ atomic_pool = NULL;
+out:
+ pr_err("DMA: failed to allocate %zx KiB pool for atomic coherent allocation\n",
+ atomic_pool_size / 1024);
+ return -ENOMEM;
+}
+/*
+ * CMA is activated by core_initcall, so we must be called after it.
+ */
+postcore_initcall(atomic_pool_init);
+
+struct dma_contig_early_reserve {
+ phys_addr_t base;
+ unsigned long size;
+};
+
+static struct dma_contig_early_reserve dma_mmu_remap[MAX_CMA_AREAS] __initdata;
+
+static int dma_mmu_remap_num __initdata;
+
+void __init dma_contiguous_early_fixup(phys_addr_t base, unsigned long size)
+{
+ dma_mmu_remap[dma_mmu_remap_num].base = base;
+ dma_mmu_remap[dma_mmu_remap_num].size = size;
+ dma_mmu_remap_num++;
+}
+
+void __init dma_contiguous_remap(void)
+{
+ int i;
+ for (i = 0; i < dma_mmu_remap_num; i++) {
+ phys_addr_t start = dma_mmu_remap[i].base;
+ phys_addr_t end = start + dma_mmu_remap[i].size;
+ struct map_desc map;
+ unsigned long addr;
+
+ if (end > arm_lowmem_limit)
+ end = arm_lowmem_limit;
+ if (start >= end)
+ continue;
+
+ map.pfn = __phys_to_pfn(start);
+ map.virtual = __phys_to_virt(start);
+ map.length = end - start;
+ map.type = MT_MEMORY_DMA_READY;
+
+ /*
+ * Clear previous low-memory mapping to ensure that the
+ * TLB does not see any conflicting entries, then flush
+ * the TLB of the old entries before creating new mappings.
+ *
+ * This ensures that any speculatively loaded TLB entries
+ * (even though they may be rare) can not cause any problems,
+ * and ensures that this code is architecturally compliant.
+ */
+ for (addr = __phys_to_virt(start); addr < __phys_to_virt(end);
+ addr += PMD_SIZE)
+ pmd_clear(pmd_off_k(addr));
+
+ flush_tlb_kernel_range(__phys_to_virt(start),
+ __phys_to_virt(end));
+
+ iotable_init(&map, 1);
+ }
+}
+
+static int __dma_update_pte(pte_t *pte, pgtable_t token, unsigned long addr,
+ void *data)
+{
+ struct page *page = virt_to_page(addr);
+ pgprot_t prot = *(pgprot_t *)data;
+
+ set_pte_ext(pte, mk_pte(page, prot), 0);
+ return 0;
+}
+
+static void __dma_remap(struct page *page, size_t size, pgprot_t prot)
+{
+ unsigned long start = (unsigned long) page_address(page);
+ unsigned end = start + size;
+
+ apply_to_page_range(&init_mm, start, size, __dma_update_pte, &prot);
+ flush_tlb_kernel_range(start, end);
+}
+
+static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
+ pgprot_t prot, struct page **ret_page,
+ const void *caller, bool want_vaddr)
+{
+ struct page *page;
+ void *ptr = NULL;
+ page = __dma_alloc_buffer(dev, size, gfp);
+ if (!page)
+ return NULL;
+ if (!want_vaddr)
+ goto out;
+
+ ptr = __dma_alloc_remap(page, size, gfp, prot, caller);
+ if (!ptr) {
+ __dma_free_buffer(page, size);
+ return NULL;
+ }
+
+ out:
+ *ret_page = page;
+ return ptr;
+}
+
+static void *__alloc_from_pool(size_t size, struct page **ret_page)
+{
+ unsigned long val;
+ void *ptr = NULL;
+
+ if (!atomic_pool) {
+ WARN(1, "coherent pool not initialised!\n");
+ return NULL;
+ }
+
+ val = gen_pool_alloc(atomic_pool, size);
+ if (val) {
+ phys_addr_t phys = gen_pool_virt_to_phys(atomic_pool, val);
+
+ *ret_page = phys_to_page(phys);
+ ptr = (void *)val;
+ }
+
+ return ptr;
+}
+
+static bool __in_atomic_pool(void *start, size_t size)
+{
+ return addr_in_gen_pool(atomic_pool, (unsigned long)start, size);
+}
+
+static int __free_from_pool(void *start, size_t size)
+{
+ if (!__in_atomic_pool(start, size))
+ return 0;
+
+ gen_pool_free(atomic_pool, (unsigned long)start, size);
+
+ return 1;
+}
+
+static void *__alloc_from_contiguous(struct device *dev, size_t size,
+ pgprot_t prot, struct page **ret_page,
+ const void *caller, bool want_vaddr)
+{
+ unsigned long order = get_order(size);
+ size_t count = size >> PAGE_SHIFT;
+ struct page *page;
+ void *ptr = NULL;
+
+ page = dma_alloc_from_contiguous(dev, count, order);
+ if (!page)
+ return NULL;
+
+ __dma_clear_buffer(page, size);
+
+ if (!want_vaddr)
+ goto out;
+
+ if (PageHighMem(page)) {
+ ptr = __dma_alloc_remap(page, size, GFP_KERNEL, prot, caller);
+ if (!ptr) {
+ dma_release_from_contiguous(dev, page, count);
+ return NULL;
+ }
+ } else {
+ __dma_remap(page, size, prot);
+ ptr = page_address(page);
+ }
+
+ out:
+ *ret_page = page;
+ return ptr;
+}
+
+static void __free_from_contiguous(struct device *dev, struct page *page,
+ void *cpu_addr, size_t size, bool want_vaddr)
+{
+ if (want_vaddr) {
+ if (PageHighMem(page))
+ __dma_free_remap(cpu_addr, size);
+ else
+ __dma_remap(page, size, PAGE_KERNEL);
+ }
+ dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
+}
+
+static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
+{
+ prot = dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs) ?
+ pgprot_writecombine(prot) :
+ pgprot_dmacoherent(prot);
+ return prot;
+}
+
+#define nommu() 0
+
+#else /* !CONFIG_MMU */
+
+#define nommu() 1
+
+#define __get_dma_pgprot(attrs, prot) __pgprot(0)
+#define __alloc_remap_buffer(dev, size, gfp, prot, ret, c, wv) NULL
+#define __alloc_from_pool(size, ret_page) NULL
+#define __alloc_from_contiguous(dev, size, prot, ret, c, wv) NULL
+#define __free_from_pool(cpu_addr, size) 0
+#define __free_from_contiguous(dev, page, cpu_addr, size, wv) do { } while (0)
+#define __dma_free_remap(cpu_addr, size) do { } while (0)
+
+#endif /* CONFIG_MMU */
+
+static void *__alloc_simple_buffer(struct device *dev, size_t size, gfp_t gfp,
+ struct page **ret_page)
+{
+ struct page *page;
+ page = __dma_alloc_buffer(dev, size, gfp);
+ if (!page)
+ return NULL;
+
+ *ret_page = page;
+ return page_address(page);
+}
+
+
+
+static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+ gfp_t gfp, pgprot_t prot, bool is_coherent,
+ struct dma_attrs *attrs, const void *caller)
+{
+ u64 mask = get_coherent_dma_mask(dev);
+ struct page *page = NULL;
+ void *addr;
+ bool want_vaddr;
+
+#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;
+
+ /*
+ * Following is a work-around (a.k.a. hack) to prevent pages
+ * with __GFP_COMP being passed to split_page() which cannot
+ * handle them. The real problem is that this flag probably
+ * should be 0 on ARM as it is not supported on this
+ * platform; see CONFIG_HUGETLBFS.
+ */
+ gfp &= ~(__GFP_COMP);
+
+ *handle = DMA_ERROR_CODE;
+ size = PAGE_ALIGN(size);
+ want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs);
+
+ if (is_coherent || nommu())
+ addr = __alloc_simple_buffer(dev, size, gfp, &page);
+ else if (!(gfp & __GFP_WAIT))
+ addr = __alloc_from_pool(size, &page);
+ else if (!dev_get_cma_area(dev))
+ addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller, want_vaddr);
+ else
+ addr = __alloc_from_contiguous(dev, size, prot, &page, caller, want_vaddr);
+
+ if (page)
+ *handle = pfn_to_dma(dev, page_to_pfn(page));
+
+ return want_vaddr ? addr : page;
+}
+
+/*
+ * Allocate DMA-coherent memory space and return both the kernel remapped
+ * virtual and bus address for that space.
+ */
+void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+ gfp_t gfp, struct dma_attrs *attrs)
+{
+ pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
+ void *memory;
+
+ if (dma_alloc_from_coherent(dev, size, handle, &memory))
+ return memory;
+
+ return __dma_alloc(dev, size, handle, gfp, prot, false,
+ attrs, __builtin_return_address(0));
+}
+
+static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
+ dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+{
+ pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
+ void *memory;
+
+ if (dma_alloc_from_coherent(dev, size, handle, &memory))
+ return memory;
+
+ return __dma_alloc(dev, size, handle, gfp, prot, true,
+ attrs, __builtin_return_address(0));
+}
+
+/*
+ * Create userspace mapping for the DMA-coherent memory.
+ */
+int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size,
+ struct dma_attrs *attrs)
+{
+ int ret = -ENXIO;
+#ifdef CONFIG_MMU
+ unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+ unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ unsigned long pfn = dma_to_pfn(dev, dma_addr);
+ unsigned long off = vma->vm_pgoff;
+
+ vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
+
+ if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
+ return ret;
+
+ if (off < nr_pages && nr_vma_pages <= (nr_pages - off)) {
+ ret = remap_pfn_range(vma, vma->vm_start,
+ pfn + off,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+ }
+#endif /* CONFIG_MMU */
+
+ return ret;
+}
+
+/*
+ * Free a buffer as defined by the above mapping.
+ */
+static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle, struct dma_attrs *attrs,
+ bool is_coherent)
+{
+ struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
+ bool want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs);
+
+ if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
+ return;
+
+ size = PAGE_ALIGN(size);
+
+ if (is_coherent || nommu()) {
+ __dma_free_buffer(page, size);
+ } else if (__free_from_pool(cpu_addr, size)) {
+ return;
+ } else if (!dev_get_cma_area(dev)) {
+ if (want_vaddr)
+ __dma_free_remap(cpu_addr, size);
+ __dma_free_buffer(page, size);
+ } else {
+ /*
+ * Non-atomic allocations cannot be freed with IRQs disabled
+ */
+ WARN_ON(irqs_disabled());
+ __free_from_contiguous(dev, page, cpu_addr, size, want_vaddr);
+ }
+}
+
+void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle, struct dma_attrs *attrs)
+{
+ __arm_dma_free(dev, size, cpu_addr, handle, attrs, false);
+}
+
+static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle, struct dma_attrs *attrs)
+{
+ __arm_dma_free(dev, size, cpu_addr, handle, attrs, true);
+}
+
+int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
+ void *cpu_addr, dma_addr_t handle, size_t size,
+ struct dma_attrs *attrs)
+{
+ struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
+ int ret;
+
+ ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
+ if (unlikely(ret))
+ return ret;
+
+ sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0);
+ return 0;
+}
+
+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))
+{
+ unsigned long pfn;
+ size_t left = size;
+
+ pfn = page_to_pfn(page) + offset / PAGE_SIZE;
+ offset %= PAGE_SIZE;
+
+ /*
+ * 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.
+ */
+ do {
+ size_t len = left;
+ void *vaddr;
+
+ page = pfn_to_page(pfn);
+
+ if (PageHighMem(page)) {
+ if (len + offset > PAGE_SIZE)
+ len = PAGE_SIZE - offset;
+
+ if (cache_is_vipt_nonaliasing()) {
+ vaddr = kmap_atomic(page);
+ op(vaddr + offset, len, dir);
+ kunmap_atomic(vaddr);
+ } else {
+ vaddr = kmap_high_get(page);
+ if (vaddr) {
+ op(vaddr + offset, len, dir);
+ kunmap_high(page);
+ }
+ }
+ } else {
+ vaddr = page_address(page) + offset;
+ op(vaddr, len, dir);
+ }
+ offset = 0;
+ pfn++;
+ left -= len;
+ } while (left);
+}
+
+/*
+ * 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_*)
+ */
+static void __dma_page_cpu_to_dev(struct page *page, unsigned long off,
+ size_t size, enum dma_data_direction dir)
+{
+ phys_addr_t 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? */
+}
+
+static void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
+ size_t size, enum dma_data_direction dir)
+{
+ phys_addr_t paddr = page_to_phys(page) + off;
+
+ /* FIXME: non-speculating: not required */
+ /* in any case, 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 these pages to avoid extra flushing.
+ */
+ if (dir != DMA_TO_DEVICE && size >= PAGE_SIZE) {
+ unsigned long pfn;
+ size_t left = size;
+
+ pfn = page_to_pfn(page) + off / PAGE_SIZE;
+ off %= PAGE_SIZE;
+ if (off) {
+ pfn++;
+ left -= PAGE_SIZE - off;
+ }
+ while (left >= PAGE_SIZE) {
+ page = pfn_to_page(pfn++);
+ set_bit(PG_dcache_clean, &page->flags);
+ left -= PAGE_SIZE;
+ }
+ }
+}
+
+/**
+ * arm_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 arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ struct scatterlist *s;
+ int i, j;
+
+ for_each_sg(sg, s, nents, i) {
+#ifdef CONFIG_NEED_SG_DMA_LENGTH
+ s->dma_length = s->length;
+#endif
+ s->dma_address = ops->map_page(dev, sg_page(s), s->offset,
+ s->length, dir, attrs);
+ if (dma_mapping_error(dev, s->dma_address))
+ goto bad_mapping;
+ }
+ return nents;
+
+ bad_mapping:
+ for_each_sg(sg, s, i, j)
+ ops->unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, attrs);
+ return 0;
+}
+
+/**
+ * arm_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 arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ struct scatterlist *s;
+
+ int i;
+
+ for_each_sg(sg, s, nents, i)
+ ops->unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, attrs);
+}
+
+/**
+ * arm_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 arm_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ struct scatterlist *s;
+ int i;
+
+ for_each_sg(sg, s, nents, i)
+ ops->sync_single_for_cpu(dev, sg_dma_address(s), s->length,
+ dir);
+}
+
+/**
+ * arm_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 arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ struct scatterlist *s;
+ int i;
+
+ for_each_sg(sg, s, nents, i)
+ ops->sync_single_for_device(dev, sg_dma_address(s), s->length,
+ 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.
+ */
+int dma_supported(struct device *dev, u64 mask)
+{
+ return __dma_supported(dev, mask, false);
+}
+EXPORT_SYMBOL(dma_supported);
+
+int arm_dma_set_mask(struct device *dev, u64 dma_mask)
+{
+ if (!dev->dma_mask || !dma_supported(dev, dma_mask))
+ return -EIO;
+
+ *dev->dma_mask = dma_mask;
+
+ return 0;
+}
+
+#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);
+
+#ifdef CONFIG_ARM_DMA_USE_IOMMU
+
+/* IOMMU */
+
+static int extend_iommu_mapping(struct dma_iommu_mapping *mapping);
+
+static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping,
+ size_t size)
+{
+ unsigned int order = get_order(size);
+ unsigned int align = 0;
+ unsigned int count, start;
+ size_t mapping_size = mapping->bits << PAGE_SHIFT;
+ unsigned long flags;
+ dma_addr_t iova;
+ int i;
+
+ if (order > CONFIG_ARM_DMA_IOMMU_ALIGNMENT)
+ order = CONFIG_ARM_DMA_IOMMU_ALIGNMENT;
+
+ count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ align = (1 << order) - 1;
+
+ spin_lock_irqsave(&mapping->lock, flags);
+ for (i = 0; i < mapping->nr_bitmaps; i++) {
+ start = bitmap_find_next_zero_area(mapping->bitmaps[i],
+ mapping->bits, 0, count, align);
+
+ if (start > mapping->bits)
+ continue;
+
+ bitmap_set(mapping->bitmaps[i], start, count);
+ break;
+ }
+
+ /*
+ * No unused range found. Try to extend the existing mapping
+ * and perform a second attempt to reserve an IO virtual
+ * address range of size bytes.
+ */
+ if (i == mapping->nr_bitmaps) {
+ if (extend_iommu_mapping(mapping)) {
+ spin_unlock_irqrestore(&mapping->lock, flags);
+ return DMA_ERROR_CODE;
+ }
+
+ start = bitmap_find_next_zero_area(mapping->bitmaps[i],
+ mapping->bits, 0, count, align);
+
+ if (start > mapping->bits) {
+ spin_unlock_irqrestore(&mapping->lock, flags);
+ return DMA_ERROR_CODE;
+ }
+
+ bitmap_set(mapping->bitmaps[i], start, count);
+ }
+ spin_unlock_irqrestore(&mapping->lock, flags);
+
+ iova = mapping->base + (mapping_size * i);
+ iova += start << PAGE_SHIFT;
+
+ return iova;
+}
+
+static inline void __free_iova(struct dma_iommu_mapping *mapping,
+ dma_addr_t addr, size_t size)
+{
+ unsigned int start, count;
+ size_t mapping_size = mapping->bits << PAGE_SHIFT;
+ unsigned long flags;
+ dma_addr_t bitmap_base;
+ u32 bitmap_index;
+
+ if (!size)
+ return;
+
+ bitmap_index = (u32) (addr - mapping->base) / (u32) mapping_size;
+ BUG_ON(addr < mapping->base || bitmap_index > mapping->extensions);
+
+ bitmap_base = mapping->base + mapping_size * bitmap_index;
+
+ start = (addr - bitmap_base) >> PAGE_SHIFT;
+
+ if (addr + size > bitmap_base + mapping_size) {
+ /*
+ * The address range to be freed reaches into the iova
+ * range of the next bitmap. This should not happen as
+ * we don't allow this in __alloc_iova (at the
+ * moment).
+ */
+ BUG();
+ } else
+ count = size >> PAGE_SHIFT;
+
+ spin_lock_irqsave(&mapping->lock, flags);
+ bitmap_clear(mapping->bitmaps[bitmap_index], start, count);
+ spin_unlock_irqrestore(&mapping->lock, flags);
+}
+
+static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
+ gfp_t gfp, struct dma_attrs *attrs)
+{
+ struct page **pages;
+ int count = size >> PAGE_SHIFT;
+ int array_size = count * sizeof(struct page *);
+ int i = 0;
+
+ if (array_size <= PAGE_SIZE)
+ pages = kzalloc(array_size, GFP_KERNEL);
+ else
+ pages = vzalloc(array_size);
+ if (!pages)
+ return NULL;
+
+ if (dma_get_attr(DMA_ATTR_FORCE_CONTIGUOUS, attrs))
+ {
+ unsigned long order = get_order(size);
+ struct page *page;
+
+ page = dma_alloc_from_contiguous(dev, count, order);
+ if (!page)
+ goto error;
+
+ __dma_clear_buffer(page, size);
+
+ for (i = 0; i < count; i++)
+ pages[i] = page + i;
+
+ return pages;
+ }
+
+ /*
+ * IOMMU can map any pages, so himem can also be used here
+ */
+ gfp |= __GFP_NOWARN | __GFP_HIGHMEM;
+
+ while (count) {
+ int j, order;
+
+ for (order = __fls(count); order > 0; --order) {
+ /*
+ * We do not want OOM killer to be invoked as long
+ * as we can fall back to single pages, so we force
+ * __GFP_NORETRY for orders higher than zero.
+ */
+ pages[i] = alloc_pages(gfp | __GFP_NORETRY, order);
+ if (pages[i])
+ break;
+ }
+
+ if (!pages[i]) {
+ /*
+ * Fall back to single page allocation.
+ * Might invoke OOM killer as last resort.
+ */
+ pages[i] = alloc_pages(gfp, 0);
+ if (!pages[i])
+ goto error;
+ }
+
+ if (order) {
+ split_page(pages[i], order);
+ j = 1 << order;
+ while (--j)
+ pages[i + j] = pages[i] + j;
+ }
+
+ __dma_clear_buffer(pages[i], PAGE_SIZE << order);
+ i += 1 << order;
+ count -= 1 << order;
+ }
+
+ return pages;
+error:
+ while (i--)
+ if (pages[i])
+ __free_pages(pages[i], 0);
+ if (array_size <= PAGE_SIZE)
+ kfree(pages);
+ else
+ vfree(pages);
+ return NULL;
+}
+
+static int __iommu_free_buffer(struct device *dev, struct page **pages,
+ size_t size, struct dma_attrs *attrs)
+{
+ int count = size >> PAGE_SHIFT;
+ int array_size = count * sizeof(struct page *);
+ int i;
+
+ if (dma_get_attr(DMA_ATTR_FORCE_CONTIGUOUS, attrs)) {
+ dma_release_from_contiguous(dev, pages[0], count);
+ } else {
+ for (i = 0; i < count; i++)
+ if (pages[i])
+ __free_pages(pages[i], 0);
+ }
+
+ if (array_size <= PAGE_SIZE)
+ kfree(pages);
+ else
+ vfree(pages);
+ return 0;
+}
+
+/*
+ * Create a CPU mapping for a specified pages
+ */
+static void *
+__iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot,
+ const void *caller)
+{
+ return dma_common_pages_remap(pages, size,
+ VM_ARM_DMA_CONSISTENT | VM_USERMAP, prot, caller);
+}
+
+/*
+ * Create a mapping in device IO address space for specified pages
+ */
+static dma_addr_t
+__iommu_create_mapping(struct device *dev, struct page **pages, size_t size)
+{
+ struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+ unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ dma_addr_t dma_addr, iova;
+ int i, ret = DMA_ERROR_CODE;
+
+ dma_addr = __alloc_iova(mapping, size);
+ if (dma_addr == DMA_ERROR_CODE)
+ return dma_addr;
+
+ iova = dma_addr;
+ for (i = 0; i < count; ) {
+ unsigned int next_pfn = page_to_pfn(pages[i]) + 1;
+ phys_addr_t phys = page_to_phys(pages[i]);
+ unsigned int len, j;
+
+ for (j = i + 1; j < count; j++, next_pfn++)
+ if (page_to_pfn(pages[j]) != next_pfn)
+ break;
+
+ len = (j - i) << PAGE_SHIFT;
+ ret = iommu_map(mapping->domain, iova, phys, len,
+ IOMMU_READ|IOMMU_WRITE);
+ if (ret < 0)
+ goto fail;
+ iova += len;
+ i = j;
+ }
+ return dma_addr;
+fail:
+ iommu_unmap(mapping->domain, dma_addr, iova-dma_addr);
+ __free_iova(mapping, dma_addr, size);
+ return DMA_ERROR_CODE;
+}
+
+static int __iommu_remove_mapping(struct device *dev, dma_addr_t iova, size_t size)
+{
+ struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+
+ /*
+ * add optional in-page offset from iova to size and align
+ * result to page size
+ */
+ size = PAGE_ALIGN((iova & ~PAGE_MASK) + size);
+ iova &= PAGE_MASK;
+
+ iommu_unmap(mapping->domain, iova, size);
+ __free_iova(mapping, iova, size);
+ return 0;
+}
+
+static struct page **__atomic_get_pages(void *addr)
+{
+ struct page *page;
+ phys_addr_t phys;
+
+ phys = gen_pool_virt_to_phys(atomic_pool, (unsigned long)addr);
+ page = phys_to_page(phys);
+
+ return (struct page **)page;
+}
+
+static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
+{
+ struct vm_struct *area;
+
+ if (__in_atomic_pool(cpu_addr, PAGE_SIZE))
+ return __atomic_get_pages(cpu_addr);
+
+ if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs))
+ return cpu_addr;
+
+ area = find_vm_area(cpu_addr);
+ if (area && (area->flags & VM_ARM_DMA_CONSISTENT))
+ return area->pages;
+ return NULL;
+}
+
+static void *__iommu_alloc_atomic(struct device *dev, size_t size,
+ dma_addr_t *handle)
+{
+ struct page *page;
+ void *addr;
+
+ addr = __alloc_from_pool(size, &page);
+ if (!addr)
+ return NULL;
+
+ *handle = __iommu_create_mapping(dev, &page, size);
+ if (*handle == DMA_ERROR_CODE)
+ goto err_mapping;
+
+ return addr;
+
+err_mapping:
+ __free_from_pool(addr, size);
+ return NULL;
+}
+
+static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
+ dma_addr_t handle, size_t size)
+{
+ __iommu_remove_mapping(dev, handle, size);
+ __free_from_pool(cpu_addr, size);
+}
+
+static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
+ dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+{
+ pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
+ struct page **pages;
+ void *addr = NULL;
+
+ *handle = DMA_ERROR_CODE;
+ size = PAGE_ALIGN(size);
+
+ if (!(gfp & __GFP_WAIT))
+ return __iommu_alloc_atomic(dev, size, handle);
+
+ /*
+ * Following is a work-around (a.k.a. hack) to prevent pages
+ * with __GFP_COMP being passed to split_page() which cannot
+ * handle them. The real problem is that this flag probably
+ * should be 0 on ARM as it is not supported on this
+ * platform; see CONFIG_HUGETLBFS.
+ */
+ gfp &= ~(__GFP_COMP);
+
+ pages = __iommu_alloc_buffer(dev, size, gfp, attrs);
+ if (!pages)
+ return NULL;
+
+ *handle = __iommu_create_mapping(dev, pages, size);
+ if (*handle == DMA_ERROR_CODE)
+ goto err_buffer;
+
+ if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs))
+ return pages;
+
+ addr = __iommu_alloc_remap(pages, size, gfp, prot,
+ __builtin_return_address(0));
+ if (!addr)
+ goto err_mapping;
+
+ return addr;
+
+err_mapping:
+ __iommu_remove_mapping(dev, *handle, size);
+err_buffer:
+ __iommu_free_buffer(dev, pages, size, attrs);
+ return NULL;
+}
+
+static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size,
+ struct dma_attrs *attrs)
+{
+ unsigned long uaddr = vma->vm_start;
+ unsigned long usize = vma->vm_end - vma->vm_start;
+ struct page **pages = __iommu_get_pages(cpu_addr, attrs);
+
+ vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
+
+ if (!pages)
+ return -ENXIO;
+
+ do {
+ int ret = vm_insert_page(vma, uaddr, *pages++);
+ if (ret) {
+ pr_err("Remapping memory failed: %d\n", ret);
+ return ret;
+ }
+ uaddr += PAGE_SIZE;
+ usize -= PAGE_SIZE;
+ } while (usize > 0);
+
+ return 0;
+}
+
+/*
+ * free a page as defined by the above mapping.
+ * Must not be called with IRQs disabled.
+ */
+void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle, struct dma_attrs *attrs)
+{
+ struct page **pages;
+ size = PAGE_ALIGN(size);
+
+ if (__in_atomic_pool(cpu_addr, size)) {
+ __iommu_free_atomic(dev, cpu_addr, handle, size);
+ return;
+ }
+
+ pages = __iommu_get_pages(cpu_addr, attrs);
+ if (!pages) {
+ WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr);
+ return;
+ }
+
+ if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) {
+ dma_common_free_remap(cpu_addr, size,
+ VM_ARM_DMA_CONSISTENT | VM_USERMAP);
+ }
+
+ __iommu_remove_mapping(dev, handle, size);
+ __iommu_free_buffer(dev, pages, size, attrs);
+}
+
+static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
+ void *cpu_addr, dma_addr_t dma_addr,
+ size_t size, struct dma_attrs *attrs)
+{
+ unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ struct page **pages = __iommu_get_pages(cpu_addr, attrs);
+
+ if (!pages)
+ return -ENXIO;
+
+ return sg_alloc_table_from_pages(sgt, pages, count, 0, size,
+ GFP_KERNEL);
+}
+
+static int __dma_direction_to_prot(enum dma_data_direction dir)
+{
+ int prot;
+
+ switch (dir) {
+ case DMA_BIDIRECTIONAL:
+ prot = IOMMU_READ | IOMMU_WRITE;
+ break;
+ case DMA_TO_DEVICE:
+ prot = IOMMU_READ;
+ break;
+ case DMA_FROM_DEVICE:
+ prot = IOMMU_WRITE;
+ break;
+ default:
+ prot = 0;
+ }
+
+ return prot;
+}
+
+/*
+ * Map a part of the scatter-gather list into contiguous io address space
+ */
+static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
+ size_t size, dma_addr_t *handle,
+ enum dma_data_direction dir, struct dma_attrs *attrs,
+ bool is_coherent)
+{
+ struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+ dma_addr_t iova, iova_base;
+ int ret = 0;
+ unsigned int count;
+ struct scatterlist *s;
+ int prot;
+
+ size = PAGE_ALIGN(size);
+ *handle = DMA_ERROR_CODE;
+
+ iova_base = iova = __alloc_iova(mapping, size);
+ if (iova == DMA_ERROR_CODE)
+ return -ENOMEM;
+
+ for (count = 0, s = sg; count < (size >> PAGE_SHIFT); s = sg_next(s)) {
+ phys_addr_t phys = page_to_phys(sg_page(s));
+ unsigned int len = PAGE_ALIGN(s->offset + s->length);
+
+ if (!is_coherent &&
+ !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
+
+ prot = __dma_direction_to_prot(dir);
+
+ ret = iommu_map(mapping->domain, iova, phys, len, prot);
+ if (ret < 0)
+ goto fail;
+ count += len >> PAGE_SHIFT;
+ iova += len;
+ }
+ *handle = iova_base;
+
+ return 0;
+fail:
+ iommu_unmap(mapping->domain, iova_base, count * PAGE_SIZE);
+ __free_iova(mapping, iova_base, size);
+ return ret;
+}
+
+static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, struct dma_attrs *attrs,
+ bool is_coherent)
+{
+ struct scatterlist *s = sg, *dma = sg, *start = sg;
+ int i, count = 0;
+ unsigned int offset = s->offset;
+ unsigned int size = s->offset + s->length;
+ unsigned int max = dma_get_max_seg_size(dev);
+
+ for (i = 1; i < nents; i++) {
+ s = sg_next(s);
+
+ s->dma_address = DMA_ERROR_CODE;
+ s->dma_length = 0;
+
+ if (s->offset || (size & ~PAGE_MASK) || size + s->length > max) {
+ if (__map_sg_chunk(dev, start, size, &dma->dma_address,
+ dir, attrs, is_coherent) < 0)
+ goto bad_mapping;
+
+ dma->dma_address += offset;
+ dma->dma_length = size - offset;
+
+ size = offset = s->offset;
+ start = s;
+ dma = sg_next(dma);
+ count += 1;
+ }
+ size += s->length;
+ }
+ if (__map_sg_chunk(dev, start, size, &dma->dma_address, dir, attrs,
+ is_coherent) < 0)
+ goto bad_mapping;
+
+ dma->dma_address += offset;
+ dma->dma_length = size - offset;
+
+ return count+1;
+
+bad_mapping:
+ for_each_sg(sg, s, count, i)
+ __iommu_remove_mapping(dev, sg_dma_address(s), sg_dma_len(s));
+ return 0;
+}
+
+/**
+ * arm_coherent_iommu_map_sg - map a set of SG buffers for streaming mode DMA
+ * @dev: valid struct device pointer
+ * @sg: list of buffers
+ * @nents: number of buffers to map
+ * @dir: DMA transfer direction
+ *
+ * Map a set of i/o coherent buffers described by scatterlist in streaming
+ * mode for DMA. The scatter gather list elements are merged together (if
+ * possible) and tagged with the appropriate dma address and length. They are
+ * obtained via sg_dma_{address,length}.
+ */
+int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ return __iommu_map_sg(dev, sg, nents, dir, attrs, true);
+}
+
+/**
+ * arm_iommu_map_sg - map a set of SG buffers for streaming mode DMA
+ * @dev: valid struct device pointer
+ * @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.
+ * The scatter gather list elements are merged together (if possible) and
+ * tagged with the appropriate dma address and length. They are obtained via
+ * sg_dma_{address,length}.
+ */
+int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ return __iommu_map_sg(dev, sg, nents, dir, attrs, false);
+}
+
+static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir, struct dma_attrs *attrs,
+ bool is_coherent)
+{
+ struct scatterlist *s;
+ int i;
+
+ for_each_sg(sg, s, nents, i) {
+ if (sg_dma_len(s))
+ __iommu_remove_mapping(dev, sg_dma_address(s),
+ sg_dma_len(s));
+ if (!is_coherent &&
+ !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ __dma_page_dev_to_cpu(sg_page(s), s->offset,
+ s->length, dir);
+ }
+}
+
+/**
+ * arm_coherent_iommu_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
+ * @dev: valid struct device pointer
+ * @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 arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ __iommu_unmap_sg(dev, sg, nents, dir, attrs, true);
+}
+
+/**
+ * arm_iommu_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
+ * @dev: valid struct device pointer
+ * @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 arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ __iommu_unmap_sg(dev, sg, nents, dir, attrs, false);
+}
+
+/**
+ * arm_iommu_sync_sg_for_cpu
+ * @dev: valid struct device pointer
+ * @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 arm_iommu_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)
+ __dma_page_dev_to_cpu(sg_page(s), s->offset, s->length, dir);
+
+}
+
+/**
+ * arm_iommu_sync_sg_for_device
+ * @dev: valid struct device pointer
+ * @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 arm_iommu_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)
+ __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
+}
+
+
+/**
+ * arm_coherent_iommu_map_page
+ * @dev: valid struct device pointer
+ * @page: page that buffer resides in
+ * @offset: offset into page for start of buffer
+ * @size: size of buffer to map
+ * @dir: DMA transfer direction
+ *
+ * Coherent IOMMU aware version of arm_dma_map_page()
+ */
+static dma_addr_t arm_coherent_iommu_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+ dma_addr_t dma_addr;
+ int ret, prot, len = PAGE_ALIGN(size + offset);
+
+ dma_addr = __alloc_iova(mapping, len);
+ if (dma_addr == DMA_ERROR_CODE)
+ return dma_addr;
+
+ prot = __dma_direction_to_prot(dir);
+
+ ret = iommu_map(mapping->domain, dma_addr, page_to_phys(page), len, prot);
+ if (ret < 0)
+ goto fail;
+
+ return dma_addr + offset;
+fail:
+ __free_iova(mapping, dma_addr, len);
+ return DMA_ERROR_CODE;
+}
+
+/**
+ * arm_iommu_map_page
+ * @dev: valid struct device pointer
+ * @page: page that buffer resides in
+ * @offset: offset into page for start of buffer
+ * @size: size of buffer to map
+ * @dir: DMA transfer direction
+ *
+ * IOMMU aware version of arm_dma_map_page()
+ */
+static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ __dma_page_cpu_to_dev(page, offset, size, dir);
+
+ return arm_coherent_iommu_map_page(dev, page, offset, size, dir, attrs);
+}
+
+/**
+ * arm_coherent_iommu_unmap_page
+ * @dev: valid struct device pointer
+ * @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)
+ *
+ * Coherent IOMMU aware version of arm_dma_unmap_page()
+ */
+static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+ dma_addr_t iova = handle & PAGE_MASK;
+ int offset = handle & ~PAGE_MASK;
+ int len = PAGE_ALIGN(size + offset);
+
+ if (!iova)
+ return;
+
+ iommu_unmap(mapping->domain, iova, len);
+ __free_iova(mapping, iova, len);
+}
+
+/**
+ * arm_iommu_unmap_page
+ * @dev: valid struct device pointer
+ * @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)
+ *
+ * IOMMU aware version of arm_dma_unmap_page()
+ */
+static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+ dma_addr_t iova = handle & PAGE_MASK;
+ struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova));
+ int offset = handle & ~PAGE_MASK;
+ int len = PAGE_ALIGN(size + offset);
+
+ if (!iova)
+ return;
+
+ if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ __dma_page_dev_to_cpu(page, offset, size, dir);
+
+ iommu_unmap(mapping->domain, iova, len);
+ __free_iova(mapping, iova, len);
+}
+
+static void arm_iommu_sync_single_for_cpu(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+ dma_addr_t iova = handle & PAGE_MASK;
+ struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova));
+ unsigned int offset = handle & ~PAGE_MASK;
+
+ if (!iova)
+ return;
+
+ __dma_page_dev_to_cpu(page, offset, size, dir);
+}
+
+static void arm_iommu_sync_single_for_device(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+ dma_addr_t iova = handle & PAGE_MASK;
+ struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova));
+ unsigned int offset = handle & ~PAGE_MASK;
+
+ if (!iova)
+ return;
+
+ __dma_page_cpu_to_dev(page, offset, size, dir);
+}
+
+struct dma_map_ops iommu_ops = {
+ .alloc = arm_iommu_alloc_attrs,
+ .free = arm_iommu_free_attrs,
+ .mmap = arm_iommu_mmap_attrs,
+ .get_sgtable = arm_iommu_get_sgtable,
+
+ .map_page = arm_iommu_map_page,
+ .unmap_page = arm_iommu_unmap_page,
+ .sync_single_for_cpu = arm_iommu_sync_single_for_cpu,
+ .sync_single_for_device = arm_iommu_sync_single_for_device,
+
+ .map_sg = arm_iommu_map_sg,
+ .unmap_sg = arm_iommu_unmap_sg,
+ .sync_sg_for_cpu = arm_iommu_sync_sg_for_cpu,
+ .sync_sg_for_device = arm_iommu_sync_sg_for_device,
+
+ .set_dma_mask = arm_dma_set_mask,
+};
+
+struct dma_map_ops iommu_coherent_ops = {
+ .alloc = arm_iommu_alloc_attrs,
+ .free = arm_iommu_free_attrs,
+ .mmap = arm_iommu_mmap_attrs,
+ .get_sgtable = arm_iommu_get_sgtable,
+
+ .map_page = arm_coherent_iommu_map_page,
+ .unmap_page = arm_coherent_iommu_unmap_page,
+
+ .map_sg = arm_coherent_iommu_map_sg,
+ .unmap_sg = arm_coherent_iommu_unmap_sg,
+
+ .set_dma_mask = arm_dma_set_mask,
+};
+
+/**
+ * arm_iommu_create_mapping
+ * @bus: pointer to the bus holding the client device (for IOMMU calls)
+ * @base: start address of the valid IO address space
+ * @size: maximum size of the valid IO address space
+ *
+ * Creates a mapping structure which holds information about used/unused
+ * IO address ranges, which is required to perform memory allocation and
+ * mapping with IOMMU aware functions.
+ *
+ * The client device need to be attached to the mapping with
+ * arm_iommu_attach_device function.
+ */
+struct dma_iommu_mapping *
+arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, u64 size)
+{
+ unsigned int bits = size >> PAGE_SHIFT;
+ unsigned int bitmap_size = BITS_TO_LONGS(bits) * sizeof(long);
+ struct dma_iommu_mapping *mapping;
+ int extensions = 1;
+ int err = -ENOMEM;
+
+ /* currently only 32-bit DMA address space is supported */
+ if (size > DMA_BIT_MASK(32) + 1)
+ return ERR_PTR(-ERANGE);
+
+ if (!bitmap_size)
+ return ERR_PTR(-EINVAL);
+
+ if (bitmap_size > PAGE_SIZE) {
+ extensions = bitmap_size / PAGE_SIZE;
+ bitmap_size = PAGE_SIZE;
+ }
+
+ mapping = kzalloc(sizeof(struct dma_iommu_mapping), GFP_KERNEL);
+ if (!mapping)
+ goto err;
+
+ mapping->bitmap_size = bitmap_size;
+ mapping->bitmaps = kzalloc(extensions * sizeof(unsigned long *),
+ GFP_KERNEL);
+ if (!mapping->bitmaps)
+ goto err2;
+
+ mapping->bitmaps[0] = kzalloc(bitmap_size, GFP_KERNEL);
+ if (!mapping->bitmaps[0])
+ goto err3;
+
+ mapping->nr_bitmaps = 1;
+ mapping->extensions = extensions;
+ mapping->base = base;
+ mapping->bits = BITS_PER_BYTE * bitmap_size;
+
+ spin_lock_init(&mapping->lock);
+
+ mapping->domain = iommu_domain_alloc(bus);
+ if (!mapping->domain)
+ goto err4;
+
+ kref_init(&mapping->kref);
+ return mapping;
+err4:
+ kfree(mapping->bitmaps[0]);
+err3:
+ kfree(mapping->bitmaps);
+err2:
+ kfree(mapping);
+err:
+ return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(arm_iommu_create_mapping);
+
+static void release_iommu_mapping(struct kref *kref)
+{
+ int i;
+ struct dma_iommu_mapping *mapping =
+ container_of(kref, struct dma_iommu_mapping, kref);
+
+ iommu_domain_free(mapping->domain);
+ for (i = 0; i < mapping->nr_bitmaps; i++)
+ kfree(mapping->bitmaps[i]);
+ kfree(mapping->bitmaps);
+ kfree(mapping);
+}
+
+static int extend_iommu_mapping(struct dma_iommu_mapping *mapping)
+{
+ int next_bitmap;
+
+ if (mapping->nr_bitmaps > mapping->extensions)
+ return -EINVAL;
+
+ next_bitmap = mapping->nr_bitmaps;
+ mapping->bitmaps[next_bitmap] = kzalloc(mapping->bitmap_size,
+ GFP_ATOMIC);
+ if (!mapping->bitmaps[next_bitmap])
+ return -ENOMEM;
+
+ mapping->nr_bitmaps++;
+
+ return 0;
+}
+
+void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping)
+{
+ if (mapping)
+ kref_put(&mapping->kref, release_iommu_mapping);
+}
+EXPORT_SYMBOL_GPL(arm_iommu_release_mapping);
+
+static int __arm_iommu_attach_device(struct device *dev,
+ struct dma_iommu_mapping *mapping)
+{
+ int err;
+
+ err = iommu_attach_device(mapping->domain, dev);
+ if (err)
+ return err;
+
+ kref_get(&mapping->kref);
+ to_dma_iommu_mapping(dev) = mapping;
+
+ pr_debug("Attached IOMMU controller to %s device.\n", dev_name(dev));
+ return 0;
+}
+
+/**
+ * arm_iommu_attach_device
+ * @dev: valid struct device pointer
+ * @mapping: io address space mapping structure (returned from
+ * arm_iommu_create_mapping)
+ *
+ * Attaches specified io address space mapping to the provided device.
+ * This replaces the dma operations (dma_map_ops pointer) with the
+ * IOMMU aware version.
+ *
+ * More than one client might be attached to the same io address space
+ * mapping.
+ */
+int arm_iommu_attach_device(struct device *dev,
+ struct dma_iommu_mapping *mapping)
+{
+ int err;
+
+ err = __arm_iommu_attach_device(dev, mapping);
+ if (err)
+ return err;
+
+ set_dma_ops(dev, &iommu_ops);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(arm_iommu_attach_device);
+
+static void __arm_iommu_detach_device(struct device *dev)
+{
+ struct dma_iommu_mapping *mapping;
+
+ mapping = to_dma_iommu_mapping(dev);
+ if (!mapping) {
+ dev_warn(dev, "Not attached\n");
+ return;
+ }
+
+ iommu_detach_device(mapping->domain, dev);
+ kref_put(&mapping->kref, release_iommu_mapping);
+ to_dma_iommu_mapping(dev) = NULL;
+
+ pr_debug("Detached IOMMU controller from %s device.\n", dev_name(dev));
+}
+
+/**
+ * arm_iommu_detach_device
+ * @dev: valid struct device pointer
+ *
+ * Detaches the provided device from a previously attached map.
+ * This voids the dma operations (dma_map_ops pointer)
+ */
+void arm_iommu_detach_device(struct device *dev)
+{
+ __arm_iommu_detach_device(dev);
+ set_dma_ops(dev, NULL);
+}
+EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
+
+static struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
+{
+ return coherent ? &iommu_coherent_ops : &iommu_ops;
+}
+
+static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ struct iommu_ops *iommu)
+{
+ struct dma_iommu_mapping *mapping;
+
+ if (!iommu)
+ return false;
+
+ mapping = arm_iommu_create_mapping(dev->bus, dma_base, size);
+ if (IS_ERR(mapping)) {
+ pr_warn("Failed to create %llu-byte IOMMU mapping for device %s\n",
+ size, dev_name(dev));
+ return false;
+ }
+
+ if (__arm_iommu_attach_device(dev, mapping)) {
+ pr_warn("Failed to attached device %s to IOMMU_mapping\n",
+ dev_name(dev));
+ arm_iommu_release_mapping(mapping);
+ return false;
+ }
+
+ return true;
+}
+
+static void arm_teardown_iommu_dma_ops(struct device *dev)
+{
+ struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+
+ if (!mapping)
+ return;
+
+ __arm_iommu_detach_device(dev);
+ arm_iommu_release_mapping(mapping);
+}
+
+#else
+
+static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ struct iommu_ops *iommu)
+{
+ return false;
+}
+
+static void arm_teardown_iommu_dma_ops(struct device *dev) { }
+
+#define arm_get_iommu_dma_map_ops arm_get_dma_map_ops
+
+#endif /* CONFIG_ARM_DMA_USE_IOMMU */
+
+static struct dma_map_ops *arm_get_dma_map_ops(bool coherent)
+{
+ return coherent ? &arm_coherent_dma_ops : &arm_dma_ops;
+}
+
+void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ struct iommu_ops *iommu, bool coherent)
+{
+ struct dma_map_ops *dma_ops;
+
+ dev->archdata.dma_coherent = coherent;
+ if (arm_setup_iommu_dma_ops(dev, dma_base, size, iommu))
+ dma_ops = arm_get_iommu_dma_map_ops(coherent);
+ else
+ dma_ops = arm_get_dma_map_ops(coherent);
+
+ set_dma_ops(dev, dma_ops);
+}
+
+void arch_teardown_dma_ops(struct device *dev)
+{
+ arm_teardown_iommu_dma_ops(dev);
+}
diff --git a/arch/arm/mm/dump.c b/arch/arm/mm/dump.c
new file mode 100644
index 000000000..9fe8e2413
--- /dev/null
+++ b/arch/arm/mm/dump.c
@@ -0,0 +1,360 @@
+/*
+ * Debug helper to dump the current kernel pagetables of the system
+ * so that we can see what the various memory ranges are set to.
+ *
+ * Derived from x86 implementation:
+ * (C) Copyright 2008 Intel Corporation
+ *
+ * Author: Arjan van de Ven <arjan@linux.intel.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/debugfs.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/seq_file.h>
+
+#include <asm/fixmap.h>
+#include <asm/pgtable.h>
+
+struct addr_marker {
+ unsigned long start_address;
+ const char *name;
+};
+
+static struct addr_marker address_markers[] = {
+ { MODULES_VADDR, "Modules" },
+ { PAGE_OFFSET, "Kernel Mapping" },
+ { 0, "vmalloc() Area" },
+ { VMALLOC_END, "vmalloc() End" },
+ { FIXADDR_START, "Fixmap Area" },
+ { CONFIG_VECTORS_BASE, "Vectors" },
+ { CONFIG_VECTORS_BASE + PAGE_SIZE * 2, "Vectors End" },
+ { -1, NULL },
+};
+
+struct pg_state {
+ struct seq_file *seq;
+ const struct addr_marker *marker;
+ unsigned long start_address;
+ unsigned level;
+ u64 current_prot;
+};
+
+struct prot_bits {
+ u64 mask;
+ u64 val;
+ const char *set;
+ const char *clear;
+};
+
+static const struct prot_bits pte_bits[] = {
+ {
+ .mask = L_PTE_USER,
+ .val = L_PTE_USER,
+ .set = "USR",
+ .clear = " ",
+ }, {
+ .mask = L_PTE_RDONLY,
+ .val = L_PTE_RDONLY,
+ .set = "ro",
+ .clear = "RW",
+ }, {
+ .mask = L_PTE_XN,
+ .val = L_PTE_XN,
+ .set = "NX",
+ .clear = "x ",
+ }, {
+ .mask = L_PTE_SHARED,
+ .val = L_PTE_SHARED,
+ .set = "SHD",
+ .clear = " ",
+ }, {
+ .mask = L_PTE_MT_MASK,
+ .val = L_PTE_MT_UNCACHED,
+ .set = "SO/UNCACHED",
+ }, {
+ .mask = L_PTE_MT_MASK,
+ .val = L_PTE_MT_BUFFERABLE,
+ .set = "MEM/BUFFERABLE/WC",
+ }, {
+ .mask = L_PTE_MT_MASK,
+ .val = L_PTE_MT_WRITETHROUGH,
+ .set = "MEM/CACHED/WT",
+ }, {
+ .mask = L_PTE_MT_MASK,
+ .val = L_PTE_MT_WRITEBACK,
+ .set = "MEM/CACHED/WBRA",
+#ifndef CONFIG_ARM_LPAE
+ }, {
+ .mask = L_PTE_MT_MASK,
+ .val = L_PTE_MT_MINICACHE,
+ .set = "MEM/MINICACHE",
+#endif
+ }, {
+ .mask = L_PTE_MT_MASK,
+ .val = L_PTE_MT_WRITEALLOC,
+ .set = "MEM/CACHED/WBWA",
+ }, {
+ .mask = L_PTE_MT_MASK,
+ .val = L_PTE_MT_DEV_SHARED,
+ .set = "DEV/SHARED",
+#ifndef CONFIG_ARM_LPAE
+ }, {
+ .mask = L_PTE_MT_MASK,
+ .val = L_PTE_MT_DEV_NONSHARED,
+ .set = "DEV/NONSHARED",
+#endif
+ }, {
+ .mask = L_PTE_MT_MASK,
+ .val = L_PTE_MT_DEV_WC,
+ .set = "DEV/WC",
+ }, {
+ .mask = L_PTE_MT_MASK,
+ .val = L_PTE_MT_DEV_CACHED,
+ .set = "DEV/CACHED",
+ },
+};
+
+static const struct prot_bits section_bits[] = {
+#ifdef CONFIG_ARM_LPAE
+ {
+ .mask = PMD_SECT_USER,
+ .val = PMD_SECT_USER,
+ .set = "USR",
+ }, {
+ .mask = L_PMD_SECT_RDONLY,
+ .val = L_PMD_SECT_RDONLY,
+ .set = "ro",
+ .clear = "RW",
+#elif __LINUX_ARM_ARCH__ >= 6
+ {
+ .mask = PMD_SECT_APX | PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
+ .val = PMD_SECT_APX | PMD_SECT_AP_WRITE,
+ .set = " ro",
+ }, {
+ .mask = PMD_SECT_APX | PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
+ .val = PMD_SECT_AP_WRITE,
+ .set = " RW",
+ }, {
+ .mask = PMD_SECT_APX | PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
+ .val = PMD_SECT_AP_READ,
+ .set = "USR ro",
+ }, {
+ .mask = PMD_SECT_APX | PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
+ .val = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
+ .set = "USR RW",
+#else /* ARMv4/ARMv5 */
+ /* These are approximate */
+ {
+ .mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
+ .val = 0,
+ .set = " ro",
+ }, {
+ .mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
+ .val = PMD_SECT_AP_WRITE,
+ .set = " RW",
+ }, {
+ .mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
+ .val = PMD_SECT_AP_READ,
+ .set = "USR ro",
+ }, {
+ .mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
+ .val = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
+ .set = "USR RW",
+#endif
+ }, {
+ .mask = PMD_SECT_XN,
+ .val = PMD_SECT_XN,
+ .set = "NX",
+ .clear = "x ",
+ }, {
+ .mask = PMD_SECT_S,
+ .val = PMD_SECT_S,
+ .set = "SHD",
+ .clear = " ",
+ },
+};
+
+struct pg_level {
+ const struct prot_bits *bits;
+ size_t num;
+ u64 mask;
+};
+
+static struct pg_level pg_level[] = {
+ {
+ }, { /* pgd */
+ }, { /* pud */
+ }, { /* pmd */
+ .bits = section_bits,
+ .num = ARRAY_SIZE(section_bits),
+ }, { /* pte */
+ .bits = pte_bits,
+ .num = ARRAY_SIZE(pte_bits),
+ },
+};
+
+static void dump_prot(struct pg_state *st, const struct prot_bits *bits, size_t num)
+{
+ unsigned i;
+
+ for (i = 0; i < num; i++, bits++) {
+ const char *s;
+
+ if ((st->current_prot & bits->mask) == bits->val)
+ s = bits->set;
+ else
+ s = bits->clear;
+
+ if (s)
+ seq_printf(st->seq, " %s", s);
+ }
+}
+
+static void note_page(struct pg_state *st, unsigned long addr, unsigned level, u64 val)
+{
+ static const char units[] = "KMGTPE";
+ u64 prot = val & pg_level[level].mask;
+
+ if (!st->level) {
+ st->level = level;
+ st->current_prot = prot;
+ seq_printf(st->seq, "---[ %s ]---\n", st->marker->name);
+ } else if (prot != st->current_prot || level != st->level ||
+ addr >= st->marker[1].start_address) {
+ const char *unit = units;
+ unsigned long delta;
+
+ if (st->current_prot) {
+ seq_printf(st->seq, "0x%08lx-0x%08lx ",
+ st->start_address, addr);
+
+ delta = (addr - st->start_address) >> 10;
+ while (!(delta & 1023) && unit[1]) {
+ delta >>= 10;
+ unit++;
+ }
+ seq_printf(st->seq, "%9lu%c", delta, *unit);
+ if (pg_level[st->level].bits)
+ dump_prot(st, pg_level[st->level].bits, pg_level[st->level].num);
+ seq_printf(st->seq, "\n");
+ }
+
+ if (addr >= st->marker[1].start_address) {
+ st->marker++;
+ seq_printf(st->seq, "---[ %s ]---\n", st->marker->name);
+ }
+ st->start_address = addr;
+ st->current_prot = prot;
+ st->level = level;
+ }
+}
+
+static void walk_pte(struct pg_state *st, pmd_t *pmd, unsigned long start)
+{
+ pte_t *pte = pte_offset_kernel(pmd, 0);
+ unsigned long addr;
+ unsigned i;
+
+ for (i = 0; i < PTRS_PER_PTE; i++, pte++) {
+ addr = start + i * PAGE_SIZE;
+ note_page(st, addr, 4, pte_val(*pte));
+ }
+}
+
+static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start)
+{
+ pmd_t *pmd = pmd_offset(pud, 0);
+ unsigned long addr;
+ unsigned i;
+
+ for (i = 0; i < PTRS_PER_PMD; i++, pmd++) {
+ addr = start + i * PMD_SIZE;
+ if (pmd_none(*pmd) || pmd_large(*pmd) || !pmd_present(*pmd))
+ note_page(st, addr, 3, pmd_val(*pmd));
+ else
+ walk_pte(st, pmd, addr);
+
+ if (SECTION_SIZE < PMD_SIZE && pmd_large(pmd[1]))
+ note_page(st, addr + SECTION_SIZE, 3, pmd_val(pmd[1]));
+ }
+}
+
+static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start)
+{
+ pud_t *pud = pud_offset(pgd, 0);
+ unsigned long addr;
+ unsigned i;
+
+ for (i = 0; i < PTRS_PER_PUD; i++, pud++) {
+ addr = start + i * PUD_SIZE;
+ if (!pud_none(*pud)) {
+ walk_pmd(st, pud, addr);
+ } else {
+ note_page(st, addr, 2, pud_val(*pud));
+ }
+ }
+}
+
+static void walk_pgd(struct seq_file *m)
+{
+ pgd_t *pgd = swapper_pg_dir;
+ struct pg_state st;
+ unsigned long addr;
+ unsigned i;
+
+ memset(&st, 0, sizeof(st));
+ st.seq = m;
+ st.marker = address_markers;
+
+ for (i = 0; i < PTRS_PER_PGD; i++, pgd++) {
+ addr = i * PGDIR_SIZE;
+ if (!pgd_none(*pgd)) {
+ walk_pud(&st, pgd, addr);
+ } else {
+ note_page(&st, addr, 1, pgd_val(*pgd));
+ }
+ }
+
+ note_page(&st, 0, 0, 0);
+}
+
+static int ptdump_show(struct seq_file *m, void *v)
+{
+ walk_pgd(m);
+ return 0;
+}
+
+static int ptdump_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ptdump_show, NULL);
+}
+
+static const struct file_operations ptdump_fops = {
+ .open = ptdump_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int ptdump_init(void)
+{
+ struct dentry *pe;
+ unsigned i, j;
+
+ for (i = 0; i < ARRAY_SIZE(pg_level); i++)
+ if (pg_level[i].bits)
+ for (j = 0; j < pg_level[i].num; j++)
+ pg_level[i].mask |= pg_level[i].bits[j].mask;
+
+ address_markers[2].start_address = VMALLOC_START;
+
+ pe = debugfs_create_file("kernel_page_tables", 0400, NULL, NULL,
+ &ptdump_fops);
+ return pe ? 0 : -ENOMEM;
+}
+__initcall(ptdump_init);
diff --git a/arch/arm/mm/extable.c b/arch/arm/mm/extable.c
new file mode 100644
index 000000000..312e15e6d
--- /dev/null
+++ b/arch/arm/mm/extable.c
@@ -0,0 +1,21 @@
+/*
+ * 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;
+#ifdef CONFIG_THUMB2_KERNEL
+ /* Clear the IT state to avoid nasty surprises in the fixup */
+ regs->ARM_cpsr &= ~PSR_IT_MASK;
+#endif
+ }
+
+ return fixup != NULL;
+}
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
new file mode 100644
index 000000000..d9e0d00a6
--- /dev/null
+++ b/arch/arm/mm/fault-armv.c
@@ -0,0 +1,269 @@
+/*
+ * 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/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_PTE_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_PTE_PTLOCKS */
+static inline void do_pte_lock(spinlock_t *ptl) {}
+static inline void do_pte_unlock(spinlock_t *ptl) {}
+#endif /* USE_SPLIT_PTE_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;
+ 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_interval_tree_foreach(mpnt, &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;
+
+ pr_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) {
+ pr_cont("failed, %s\n", reason);
+ shared_pte_mask = L_PTE_MT_UNCACHED;
+ } else {
+ pr_cont("ok\n");
+ }
+}
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
new file mode 100644
index 000000000..6333d9c17
--- /dev/null
+++ b/arch/arm/mm/fault.c
@@ -0,0 +1,619 @@
+/*
+ * 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/exception.h>
+#include <asm/pgtable.h>
+#include <asm/system_misc.h>
+#include <asm/system_info.h>
+#include <asm/tlbflush.h>
+
+#include "fault.h"
+
+#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;
+
+ pr_alert("pgd = %p\n", mm->pgd);
+ pgd = pgd_offset(mm, addr);
+ pr_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)) {
+ pr_cont("(bad)");
+ break;
+ }
+
+ pud = pud_offset(pgd, addr);
+ if (PTRS_PER_PUD != 1)
+ pr_cont(", *pud=%08llx", (long long)pud_val(*pud));
+
+ if (pud_none(*pud))
+ break;
+
+ if (pud_bad(*pud)) {
+ pr_cont("(bad)");
+ break;
+ }
+
+ pmd = pmd_offset(pud, addr);
+ if (PTRS_PER_PMD != 1)
+ pr_cont(", *pmd=%08llx", (long long)pmd_val(*pmd));
+
+ if (pmd_none(*pmd))
+ break;
+
+ if (pmd_bad(*pmd)) {
+ pr_cont("(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);
+ pr_cont(", *pte=%08llx", (long long)pte_val(*pte));
+#ifndef CONFIG_ARM_LPAE
+ pr_cont(", *ppte=%08llx",
+ (long long)pte_val(pte[PTE_HWTABLE_PTRS]));
+#endif
+ pte_unmap(pte);
+ } while(0);
+
+ pr_cont("\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);
+ pr_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) && (sig == SIGSEGV)) ||
+ ((user_debug & UDBG_BUS) && (sig == SIGBUS))) {
+ 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,
+ unsigned int flags, 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;
+ }
+
+ return handle_mm_fault(mm, vma, addr & PAGE_MASK, flags);
+
+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;
+ unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
+
+ if (notify_page_fault(regs, fsr))
+ return 0;
+
+ tsk = current;
+ mm = tsk->mm;
+
+ /* Enable interrupts if they were enabled in the parent context. */
+ if (interrupts_enabled(regs))
+ local_irq_enable();
+
+ /*
+ * If we're in an interrupt or have no user
+ * context, we must not take the fault..
+ */
+ if (in_atomic() || !mm)
+ goto no_context;
+
+ if (user_mode(regs))
+ flags |= FAULT_FLAG_USER;
+ if (fsr & FSR_WRITE)
+ flags |= FAULT_FLAG_WRITE;
+
+ /*
+ * 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;
+retry:
+ 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, flags, tsk);
+
+ /* If we need to retry but a fatal signal is pending, handle the
+ * signal first. We do not need to release the mmap_sem because
+ * it would already be released in __lock_page_or_retry in
+ * mm/filemap.c. */
+ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+ return 0;
+
+ /*
+ * Major/minor page fault accounting is only done on the
+ * initial attempt. If we go through a retry, it is extremely
+ * likely that the page will be found in page cache at that point.
+ */
+
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
+ if (!(fault & VM_FAULT_ERROR) && flags & FAULT_FLAG_ALLOW_RETRY) {
+ if (fault & VM_FAULT_MAJOR) {
+ tsk->maj_flt++;
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1,
+ regs, addr);
+ } else {
+ tsk->min_flt++;
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1,
+ regs, addr);
+ }
+ if (fault & VM_FAULT_RETRY) {
+ /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
+ * of starvation. */
+ flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
+ goto retry;
+ }
+ }
+
+ up_read(&mm->mmap_sem);
+
+ /*
+ * 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 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_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 (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);
+
+ 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);
+
+#ifdef CONFIG_ARM_LPAE
+ /*
+ * Only one hardware entry per PMD with LPAE.
+ */
+ index = 0;
+#else
+ /*
+ * 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;
+#endif
+ 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.
+ */
+#ifndef CONFIG_ARM_LPAE
+static int
+do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+ do_bad_area(addr, fsr, regs);
+ return 0;
+}
+#endif /* CONFIG_ARM_LPAE */
+
+/*
+ * This abort handler always returns "fault".
+ */
+static int
+do_bad(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+ return 1;
+}
+
+struct fsr_info {
+ int (*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
+ int sig;
+ int code;
+ const char *name;
+};
+
+/* FSR definition */
+#ifdef CONFIG_ARM_LPAE
+#include "fsr-3level.c"
+#else
+#include "fsr-2level.c"
+#endif
+
+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;
+
+ pr_alert("Unhandled fault: %s (0x%03x) at 0x%08lx\n",
+ inf->name, fsr, addr);
+ show_pte(current->mm, 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);
+}
+
+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;
+
+ pr_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);
+}
+
+#ifndef CONFIG_ARM_LPAE
+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);
+#endif
diff --git a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h
new file mode 100644
index 000000000..cf08bdfbe
--- /dev/null
+++ b/arch/arm/mm/fault.h
@@ -0,0 +1,28 @@
+#ifndef __ARCH_ARM_FAULT_H
+#define __ARCH_ARM_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)
+#define FSR_FS5_0 (0x3f)
+
+#ifdef CONFIG_ARM_LPAE
+static inline int fsr_fs(unsigned int fsr)
+{
+ return fsr & FSR_FS5_0;
+}
+#else
+static inline int fsr_fs(unsigned int fsr)
+{
+ return (fsr & FSR_FS3_0) | (fsr & FSR_FS4) >> 6;
+}
+#endif
+
+void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
+unsigned long search_exception_table(unsigned long addr);
+
+#endif /* __ARCH_ARM_FAULT_H */
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
new file mode 100644
index 000000000..34b66af51
--- /dev/null
+++ b/arch/arm/mm/flush.c
@@ -0,0 +1,417 @@
+/*
+ * 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/tlbflush.h>
+#include <linux/hugetlb.h>
+
+#include "mm.h"
+
+#ifdef CONFIG_CPU_CACHE_VIPT
+
+static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
+{
+ unsigned long to = FLUSH_ALIAS_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
+ const int zero = 0;
+
+ set_top_pte(to, pfn_pte(pfn, PAGE_KERNEL));
+
+ asm( "mcrr p15, 0, %1, %0, c14\n"
+ " mcr p15, 0, %2, c7, c10, 4"
+ :
+ : "r" (to), "r" (to + PAGE_SIZE - 1), "r" (zero)
+ : "cc");
+}
+
+static void flush_icache_alias(unsigned long pfn, unsigned long vaddr, unsigned long len)
+{
+ unsigned long va = FLUSH_ALIAS_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
+ unsigned long offset = vaddr & (PAGE_SIZE - 1);
+ unsigned long to;
+
+ set_top_pte(va, pfn_pte(pfn, PAGE_KERNEL));
+ to = va + offset;
+ 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
+
+#define FLAG_PA_IS_EXEC 1
+#define FLAG_PA_CORE_IN_MM 2
+
+static void flush_ptrace_access_other(void *args)
+{
+ __flush_icache_all();
+}
+
+static inline
+void __flush_ptrace_access(struct page *page, unsigned long uaddr, void *kaddr,
+ unsigned long len, unsigned int flags)
+{
+ if (cache_is_vivt()) {
+ if (flags & FLAG_PA_CORE_IN_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 (flags & FLAG_PA_IS_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);
+ }
+}
+
+static
+void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
+ unsigned long uaddr, void *kaddr, unsigned long len)
+{
+ unsigned int flags = 0;
+ if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm)))
+ flags |= FLAG_PA_CORE_IN_MM;
+ if (vma->vm_flags & VM_EXEC)
+ flags |= FLAG_PA_IS_EXEC;
+ __flush_ptrace_access(page, uaddr, kaddr, len, flags);
+}
+
+void flush_uprobe_xol_access(struct page *page, unsigned long uaddr,
+ void *kaddr, unsigned long len)
+{
+ unsigned int flags = FLAG_PA_CORE_IN_MM|FLAG_PA_IS_EXEC;
+
+ __flush_ptrace_access(page, uaddr, kaddr, len, flags);
+}
+
+/*
+ * 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)) {
+ size_t page_size = PAGE_SIZE << compound_order(page);
+ __cpuc_flush_dcache_area(page_address(page), page_size);
+ } else {
+ unsigned long i;
+ if (cache_is_vipt_nonaliasing()) {
+ for (i = 0; i < (1 << compound_order(page)); i++) {
+ void *addr = kmap_atomic(page + i);
+ __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+ kunmap_atomic(addr);
+ }
+ } else {
+ for (i = 0; i < (1 << compound_order(page)); i++) {
+ void *addr = kmap_high_get(page + i);
+ if (addr) {
+ __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+ kunmap_high(page + i);
+ }
+ }
+ }
+ }
+
+ /*
+ * 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;
+ 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_interval_tree_foreach(mpnt, &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 (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 && !page_mapped(page))
+ 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);
+
+/*
+ * Ensure cache coherency for the kernel mapping of this page. We can
+ * assume that the page is pinned via kmap.
+ *
+ * If the page only exists in the page cache and there are no user
+ * space mappings, this is a no-op since the page was already marked
+ * dirty at creation. Otherwise, we need to flush the dirty kernel
+ * cache lines directly.
+ */
+void flush_kernel_dcache_page(struct page *page)
+{
+ if (cache_is_vivt() || cache_is_vipt_aliasing()) {
+ struct address_space *mapping;
+
+ mapping = page_mapping(page);
+
+ if (!mapping || mapping_mapped(mapping)) {
+ void *addr;
+
+ addr = page_address(page);
+ /*
+ * kmap_atomic() doesn't set the page virtual
+ * address for highmem pages, and
+ * kunmap_atomic() takes care of cache
+ * flushing already.
+ */
+ if (!IS_ENABLED(CONFIG_HIGHMEM) || addr)
+ __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+ }
+ }
+}
+EXPORT_SYMBOL(flush_kernel_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);
+}
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
+ pmd_t *pmdp)
+{
+ pmd_t pmd = pmd_mksplitting(*pmdp);
+ VM_BUG_ON(address & ~PMD_MASK);
+ set_pmd_at(vma->vm_mm, address, pmdp, pmd);
+
+ /* dummy IPI to serialise against fast_gup */
+ kick_all_cpus_sync();
+}
+#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
diff --git a/arch/arm/mm/fsr-2level.c b/arch/arm/mm/fsr-2level.c
new file mode 100644
index 000000000..18ca74c0f
--- /dev/null
+++ b/arch/arm/mm/fsr-2level.c
@@ -0,0 +1,78 @@
+static struct fsr_info 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" },
+};
+
+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" },
+};
diff --git a/arch/arm/mm/fsr-3level.c b/arch/arm/mm/fsr-3level.c
new file mode 100644
index 000000000..ab4409a23
--- /dev/null
+++ b/arch/arm/mm/fsr-3level.c
@@ -0,0 +1,68 @@
+static struct fsr_info fsr_info[] = {
+ { do_bad, SIGBUS, 0, "unknown 0" },
+ { do_bad, SIGBUS, 0, "unknown 1" },
+ { do_bad, SIGBUS, 0, "unknown 2" },
+ { do_bad, SIGBUS, 0, "unknown 3" },
+ { do_bad, SIGBUS, 0, "reserved translation fault" },
+ { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 1 translation fault" },
+ { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 2 translation fault" },
+ { do_page_fault, SIGSEGV, SEGV_MAPERR, "level 3 translation fault" },
+ { do_bad, SIGBUS, 0, "reserved access flag fault" },
+ { do_bad, SIGSEGV, SEGV_ACCERR, "level 1 access flag fault" },
+ { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 access flag fault" },
+ { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 access flag fault" },
+ { do_bad, SIGBUS, 0, "reserved permission fault" },
+ { do_bad, SIGSEGV, SEGV_ACCERR, "level 1 permission fault" },
+ { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 permission fault" },
+ { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 permission fault" },
+ { do_bad, SIGBUS, 0, "synchronous external abort" },
+ { do_bad, SIGBUS, 0, "asynchronous external abort" },
+ { do_bad, SIGBUS, 0, "unknown 18" },
+ { do_bad, SIGBUS, 0, "unknown 19" },
+ { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
+ { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
+ { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
+ { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
+ { do_bad, SIGBUS, 0, "synchronous parity error" },
+ { do_bad, SIGBUS, 0, "asynchronous parity error" },
+ { do_bad, SIGBUS, 0, "unknown 26" },
+ { do_bad, SIGBUS, 0, "unknown 27" },
+ { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk" },
+ { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk" },
+ { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk" },
+ { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk" },
+ { do_bad, SIGBUS, 0, "unknown 32" },
+ { do_bad, SIGBUS, BUS_ADRALN, "alignment fault" },
+ { do_bad, SIGBUS, 0, "debug event" },
+ { do_bad, SIGBUS, 0, "unknown 35" },
+ { do_bad, SIGBUS, 0, "unknown 36" },
+ { do_bad, SIGBUS, 0, "unknown 37" },
+ { do_bad, SIGBUS, 0, "unknown 38" },
+ { do_bad, SIGBUS, 0, "unknown 39" },
+ { do_bad, SIGBUS, 0, "unknown 40" },
+ { do_bad, SIGBUS, 0, "unknown 41" },
+ { do_bad, SIGBUS, 0, "unknown 42" },
+ { do_bad, SIGBUS, 0, "unknown 43" },
+ { do_bad, SIGBUS, 0, "unknown 44" },
+ { do_bad, SIGBUS, 0, "unknown 45" },
+ { do_bad, SIGBUS, 0, "unknown 46" },
+ { do_bad, SIGBUS, 0, "unknown 47" },
+ { do_bad, SIGBUS, 0, "unknown 48" },
+ { do_bad, SIGBUS, 0, "unknown 49" },
+ { do_bad, SIGBUS, 0, "unknown 50" },
+ { do_bad, SIGBUS, 0, "unknown 51" },
+ { do_bad, SIGBUS, 0, "implementation fault (lockdown abort)" },
+ { do_bad, SIGBUS, 0, "unknown 53" },
+ { do_bad, SIGBUS, 0, "unknown 54" },
+ { do_bad, SIGBUS, 0, "unknown 55" },
+ { do_bad, SIGBUS, 0, "unknown 56" },
+ { do_bad, SIGBUS, 0, "unknown 57" },
+ { do_bad, SIGBUS, 0, "implementation fault (coprocessor abort)" },
+ { do_bad, SIGBUS, 0, "unknown 59" },
+ { do_bad, SIGBUS, 0, "unknown 60" },
+ { do_bad, SIGBUS, 0, "unknown 61" },
+ { do_bad, SIGBUS, 0, "unknown 62" },
+ { do_bad, SIGBUS, 0, "unknown 63" },
+};
+
+#define ifsr_info fsr_info
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
new file mode 100644
index 000000000..b98895d9f
--- /dev/null
+++ b/arch/arm/mm/highmem.c
@@ -0,0 +1,156 @@
+/*
+ * 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"
+
+static inline void set_fixmap_pte(int idx, pte_t pte)
+{
+ unsigned long vaddr = __fix_to_virt(idx);
+ pte_t *ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
+
+ set_pte_ext(ptep, pte, 0);
+ local_flush_tlb_kernel_page(vaddr);
+}
+
+static inline pte_t get_fixmap_pte(unsigned long vaddr)
+{
+ pte_t *ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
+
+ return *ptep;
+}
+
+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(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(get_fixmap_pte(vaddr)));
+#endif
+ /*
+ * When debugging is off, kunmap_atomic leaves the previous mapping
+ * in place, so the contained TLB flush ensures the TLB is updated
+ * with the new mapping.
+ */
+ set_fixmap_pte(idx, mk_pte(page, kmap_prot));
+
+ 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(idx));
+ set_fixmap_pte(idx, __pte(0));
+#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;
+ struct page *page = pfn_to_page(pfn);
+
+ pagefault_disable();
+ if (!PageHighMem(page))
+ return page_address(page);
+
+ type = kmap_atomic_idx_push();
+ idx = type + KM_TYPE_NR * smp_processor_id();
+ vaddr = __fix_to_virt(idx);
+#ifdef CONFIG_DEBUG_HIGHMEM
+ BUG_ON(!pte_none(get_fixmap_pte(vaddr)));
+#endif
+ set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot));
+
+ return (void *)vaddr;
+}
+
+struct page *kmap_atomic_to_page(const void *ptr)
+{
+ unsigned long vaddr = (unsigned long)ptr;
+
+ if (vaddr < FIXADDR_START)
+ return virt_to_page(ptr);
+
+ return pte_page(get_fixmap_pte(vaddr));
+}
diff --git a/arch/arm/mm/hugetlbpage.c b/arch/arm/mm/hugetlbpage.c
new file mode 100644
index 000000000..c72412415
--- /dev/null
+++ b/arch/arm/mm/hugetlbpage.c
@@ -0,0 +1,52 @@
+/*
+ * arch/arm/mm/hugetlbpage.c
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * Based on arch/x86/include/asm/hugetlb.h and Bill Carson's 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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/fs.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/pagemap.h>
+#include <linux/err.h>
+#include <linux/sysctl.h>
+#include <asm/mman.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/pgalloc.h>
+
+/*
+ * On ARM, huge pages are backed by pmd's rather than pte's, so we do a lot
+ * of type casting from pmd_t * to pte_t *.
+ */
+
+int pud_huge(pud_t pud)
+{
+ return 0;
+}
+
+int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
+{
+ return 0;
+}
+
+int pmd_huge(pmd_t pmd)
+{
+ return pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT);
+}
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
new file mode 100644
index 000000000..e7a81cebb
--- /dev/null
+++ b/arch/arm/mm/idmap.c
@@ -0,0 +1,136 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include <asm/cputype.h>
+#include <asm/idmap.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/sections.h>
+#include <asm/system_info.h>
+
+/*
+ * Note: accesses outside of the kernel image and the identity map area
+ * are not supported on any CPU using the idmap tables as its current
+ * page tables.
+ */
+pgd_t *idmap_pgd;
+phys_addr_t (*arch_virt_to_idmap) (unsigned long x);
+
+#ifdef CONFIG_ARM_LPAE
+static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
+ unsigned long prot)
+{
+ pmd_t *pmd;
+ unsigned long next;
+
+ if (pud_none_or_clear_bad(pud) || (pud_val(*pud) & L_PGD_SWAPPER)) {
+ pmd = pmd_alloc_one(&init_mm, addr);
+ if (!pmd) {
+ pr_warn("Failed to allocate identity pmd.\n");
+ return;
+ }
+ /*
+ * Copy the original PMD to ensure that the PMD entries for
+ * the kernel image are preserved.
+ */
+ if (!pud_none(*pud))
+ memcpy(pmd, pmd_offset(pud, 0),
+ PTRS_PER_PMD * sizeof(pmd_t));
+ pud_populate(&init_mm, pud, pmd);
+ pmd += pmd_index(addr);
+ } else
+ pmd = pmd_offset(pud, addr);
+
+ do {
+ next = pmd_addr_end(addr, end);
+ *pmd = __pmd((addr & PMD_MASK) | prot);
+ flush_pmd_entry(pmd);
+ } while (pmd++, addr = next, addr != end);
+}
+#else /* !CONFIG_ARM_LPAE */
+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);
+}
+#endif /* CONFIG_ARM_LPAE */
+
+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);
+}
+
+static void identity_mapping_add(pgd_t *pgd, const char *text_start,
+ const char *text_end, unsigned long prot)
+{
+ unsigned long addr, end;
+ unsigned long next;
+
+ addr = virt_to_idmap(text_start);
+ end = virt_to_idmap(text_end);
+ pr_info("Setting up static identity map for 0x%lx - 0x%lx\n", addr, end);
+
+ prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF;
+
+ 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);
+}
+
+extern char __idmap_text_start[], __idmap_text_end[];
+
+static int __init init_static_idmap(void)
+{
+ idmap_pgd = pgd_alloc(&init_mm);
+ if (!idmap_pgd)
+ return -ENOMEM;
+
+ identity_mapping_add(idmap_pgd, __idmap_text_start,
+ __idmap_text_end, 0);
+
+ /* Flush L1 for the hardware to see this page table content */
+ flush_cache_louis();
+
+ return 0;
+}
+early_initcall(init_static_idmap);
+
+/*
+ * In order to soft-boot, we need to switch to a 1:1 mapping for the
+ * cpu_reset functions. This will then ensure that we have predictable
+ * results when turning off the mmu.
+ */
+void setup_mm_for_reboot(void)
+{
+ /* Switch to the identity mapping. */
+ cpu_switch_mm(idmap_pgd, &init_mm);
+ local_flush_bp_all();
+
+#ifdef CONFIG_CPU_HAS_ASID
+ /*
+ * We don't have a clean ASID for the identity mapping, which
+ * may clash with virtual addresses of the previous page tables
+ * and therefore potentially in the TLB.
+ */
+ local_flush_tlb_all();
+#endif
+}
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
new file mode 100644
index 000000000..be92fa0f2
--- /dev/null
+++ b/arch/arm/mm/init.c
@@ -0,0 +1,752 @@
+/*
+ * 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/export.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/dma-contiguous.h>
+#include <linux/sizes.h>
+
+#include <asm/cp15.h>
+#include <asm/mach-types.h>
+#include <asm/memblock.h>
+#include <asm/prom.h>
+#include <asm/sections.h>
+#include <asm/setup.h>
+#include <asm/system_info.h>
+#include <asm/tlb.h>
+#include <asm/fixmap.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "mm.h"
+
+#ifdef CONFIG_CPU_CP15_MMU
+unsigned long __init __clear_cr(unsigned long mask)
+{
+ cr_alignment = cr_alignment & ~mask;
+ return cr_alignment;
+}
+#endif
+
+static phys_addr_t phys_initrd_start __initdata = 0;
+static unsigned long phys_initrd_size __initdata = 0;
+
+static int __init early_initrd(char *p)
+{
+ phys_addr_t start;
+ unsigned long 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)
+{
+ pr_warn("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);
+
+static void __init find_limits(unsigned long *min, unsigned long *max_low,
+ unsigned long *max_high)
+{
+ *max_low = PFN_DOWN(memblock_get_current_limit());
+ *min = PFN_UP(memblock_start_of_DRAM());
+ *max_high = PFN_DOWN(memblock_end_of_DRAM());
+}
+
+#ifdef CONFIG_ZONE_DMA
+
+phys_addr_t arm_dma_zone_size __read_mostly;
+EXPORT_SYMBOL(arm_dma_zone_size);
+
+/*
+ * 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.
+ */
+phys_addr_t arm_dma_limit;
+unsigned long arm_dma_pfn_limit;
+
+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
+
+void __init setup_dma_zone(const struct machine_desc *mdesc)
+{
+#ifdef CONFIG_ZONE_DMA
+ if (mdesc->dma_zone_size) {
+ arm_dma_zone_size = mdesc->dma_zone_size;
+ arm_dma_limit = PHYS_OFFSET + arm_dma_zone_size - 1;
+ } else
+ arm_dma_limit = 0xffffffff;
+ arm_dma_pfn_limit = arm_dma_limit >> PAGE_SHIFT;
+#endif
+}
+
+static void __init zone_sizes_init(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 CONFIG_ZONE_DMA
+ /*
+ * Adjust the sizes according to any special requirements for
+ * this machine type.
+ */
+ if (arm_dma_zone_size)
+ 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_to_phys(pfn));
+}
+EXPORT_SYMBOL(pfn_valid);
+#endif
+
+#ifndef CONFIG_SPARSEMEM
+static void __init arm_memory_present(void)
+{
+}
+#else
+static void __init 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 bool arm_memblock_steal_permitted = true;
+
+phys_addr_t __init arm_memblock_steal(phys_addr_t size, phys_addr_t align)
+{
+ phys_addr_t phys;
+
+ BUG_ON(!arm_memblock_steal_permitted);
+
+ phys = memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ANYWHERE);
+ memblock_free(phys, size);
+ memblock_remove(phys, size);
+
+ return phys;
+}
+
+void __init arm_memblock_init(const struct machine_desc *mdesc)
+{
+ /* 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
+ /* FDT scan will populate initrd_start */
+ if (initrd_start && !phys_initrd_size) {
+ phys_initrd_start = __virt_to_phys(initrd_start);
+ phys_initrd_size = initrd_end - initrd_start;
+ }
+ initrd_start = initrd_end = 0;
+ if (phys_initrd_size &&
+ !memblock_is_region_memory(phys_initrd_start, phys_initrd_size)) {
+ pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region - disabling initrd\n",
+ (u64)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%08llx+0x%08lx overlaps in-use memory region - disabling initrd\n",
+ (u64)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();
+
+ /* reserve any platform specific memblock areas */
+ if (mdesc->reserve)
+ mdesc->reserve();
+
+ early_init_fdt_scan_reserved_mem();
+
+ /* reserve memory for DMA contiguous allocations */
+ dma_contiguous_reserve(arm_dma_limit);
+
+ arm_memblock_steal_permitted = false;
+ memblock_dump_all();
+}
+
+void __init bootmem_init(void)
+{
+ unsigned long min, max_low, max_high;
+
+ memblock_allow_resize();
+ max_low = max_high = 0;
+
+ find_limits(&min, &max_low, &max_high);
+
+ early_memtest((phys_addr_t)min << PAGE_SHIFT,
+ (phys_addr_t)max_low << PAGE_SHIFT);
+
+ /*
+ * 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.
+ */
+ zone_sizes_init(min, max_low, max_high);
+
+ /*
+ * 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.
+ */
+ min_low_pfn = min;
+ max_low_pfn = max_low;
+ max_pfn = max_high;
+}
+
+/*
+ * Poison init memory with an undefined instruction (ARM) or a branch to an
+ * undefined instruction (Thumb).
+ */
+static inline void poison_init_mem(void *s, size_t count)
+{
+ u32 *p = (u32 *)s;
+ for (; count != 0; count -= 4)
+ *p++ = 0xe7fddef0;
+}
+
+static inline void
+free_memmap(unsigned long start_pfn, unsigned long end_pfn)
+{
+ struct page *start_pg, *end_pg;
+ phys_addr_t 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 = PAGE_ALIGN(__pa(start_pg));
+ pgend = __pa(end_pg) & PAGE_MASK;
+
+ /*
+ * If there are free pages between these,
+ * free the section of the memmap array.
+ */
+ if (pg < pgend)
+ memblock_free_early(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(void)
+{
+ unsigned long start, prev_end = 0;
+ struct memblock_region *reg;
+
+ /*
+ * This relies on each bank being in address order.
+ * The banks are sorted previously in bootmem_init().
+ */
+ for_each_memblock(memory, reg) {
+ start = memblock_region_memory_base_pfn(reg);
+
+#ifdef CONFIG_SPARSEMEM
+ /*
+ * Take care not to free memmap entries that don't exist
+ * due to SPARSEMEM sections which aren't present.
+ */
+ start = min(start,
+ ALIGN(prev_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.
+ */
+ start = round_down(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_end && prev_end < start)
+ free_memmap(prev_end, 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_end = ALIGN(memblock_region_memory_end_pfn(reg),
+ MAX_ORDER_NR_PAGES);
+ }
+
+#ifdef CONFIG_SPARSEMEM
+ if (!IS_ALIGNED(prev_end, PAGES_PER_SECTION))
+ free_memmap(prev_end,
+ ALIGN(prev_end, PAGES_PER_SECTION));
+#endif
+}
+
+#ifdef CONFIG_HIGHMEM
+static inline void free_area_high(unsigned long pfn, unsigned long end)
+{
+ for (; pfn < end; pfn++)
+ free_highmem_page(pfn_to_page(pfn));
+}
+#endif
+
+static void __init free_highpages(void)
+{
+#ifdef CONFIG_HIGHMEM
+ unsigned long max_low = max_low_pfn;
+ 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)
+ free_area_high(start, res_start);
+ start = res_end;
+ if (start == end)
+ break;
+ }
+
+ /* And now free anything which remains */
+ if (start < end)
+ free_area_high(start, end);
+ }
+#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)
+{
+#ifdef CONFIG_HAVE_TCM
+ /* These pointers are filled in on TCM detection */
+ extern u32 dtcm_end;
+ extern u32 itcm_end;
+#endif
+
+ set_max_mapnr(pfn_to_page(max_pfn) - mem_map);
+
+ /* this will put all unused low memory onto the freelists */
+ free_unused_memmap();
+ free_all_bootmem();
+
+#ifdef CONFIG_SA1111
+ /* now that our DMA memory is actually so designated, we can free it */
+ free_reserved_area(__va(PHYS_OFFSET), swapper_pg_dir, -1, NULL);
+#endif
+
+ free_highpages();
+
+ mem_init_print_info(NULL);
+
+#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)
+
+ pr_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"
+ " 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
+#ifdef CONFIG_MODULES
+ " modules : 0x%08lx - 0x%08lx (%4ld MB)\n"
+#endif
+ " .text : 0x%p" " - 0x%p" " (%4td kB)\n"
+ " .init : 0x%p" " - 0x%p" " (%4td kB)\n"
+ " .data : 0x%p" " - 0x%p" " (%4td kB)\n"
+ " .bss : 0x%p" " - 0x%p" " (%4td 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_END),
+ 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
+#ifdef CONFIG_MODULES
+ MLM(MODULES_VADDR, MODULES_END),
+#endif
+
+ MLK_ROUNDUP(_text, _etext),
+ MLK_ROUNDUP(__init_begin, __init_end),
+ 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(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 && get_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;
+ }
+}
+
+#ifdef CONFIG_ARM_KERNMEM_PERMS
+struct section_perm {
+ unsigned long start;
+ unsigned long end;
+ pmdval_t mask;
+ pmdval_t prot;
+ pmdval_t clear;
+};
+
+static struct section_perm nx_perms[] = {
+ /* Make pages tables, etc before _stext RW (set NX). */
+ {
+ .start = PAGE_OFFSET,
+ .end = (unsigned long)_stext,
+ .mask = ~PMD_SECT_XN,
+ .prot = PMD_SECT_XN,
+ },
+ /* Make init RW (set NX). */
+ {
+ .start = (unsigned long)__init_begin,
+ .end = (unsigned long)_sdata,
+ .mask = ~PMD_SECT_XN,
+ .prot = PMD_SECT_XN,
+ },
+#ifdef CONFIG_DEBUG_RODATA
+ /* Make rodata NX (set RO in ro_perms below). */
+ {
+ .start = (unsigned long)__start_rodata,
+ .end = (unsigned long)__init_begin,
+ .mask = ~PMD_SECT_XN,
+ .prot = PMD_SECT_XN,
+ },
+#endif
+};
+
+#ifdef CONFIG_DEBUG_RODATA
+static struct section_perm ro_perms[] = {
+ /* Make kernel code and rodata RX (set RO). */
+ {
+ .start = (unsigned long)_stext,
+ .end = (unsigned long)__init_begin,
+#ifdef CONFIG_ARM_LPAE
+ .mask = ~L_PMD_SECT_RDONLY,
+ .prot = L_PMD_SECT_RDONLY,
+#else
+ .mask = ~(PMD_SECT_APX | PMD_SECT_AP_WRITE),
+ .prot = PMD_SECT_APX | PMD_SECT_AP_WRITE,
+ .clear = PMD_SECT_AP_WRITE,
+#endif
+ },
+};
+#endif
+
+/*
+ * Updates section permissions only for the current mm (sections are
+ * copied into each mm). During startup, this is the init_mm. Is only
+ * safe to be called with preemption disabled, as under stop_machine().
+ */
+static inline void section_update(unsigned long addr, pmdval_t mask,
+ pmdval_t prot)
+{
+ struct mm_struct *mm;
+ pmd_t *pmd;
+
+ mm = current->active_mm;
+ pmd = pmd_offset(pud_offset(pgd_offset(mm, addr), addr), addr);
+
+#ifdef CONFIG_ARM_LPAE
+ pmd[0] = __pmd((pmd_val(pmd[0]) & mask) | prot);
+#else
+ if (addr & SECTION_SIZE)
+ pmd[1] = __pmd((pmd_val(pmd[1]) & mask) | prot);
+ else
+ pmd[0] = __pmd((pmd_val(pmd[0]) & mask) | prot);
+#endif
+ flush_pmd_entry(pmd);
+ local_flush_tlb_kernel_range(addr, addr + SECTION_SIZE);
+}
+
+/* Make sure extended page tables are in use. */
+static inline bool arch_has_strict_perms(void)
+{
+ if (cpu_architecture() < CPU_ARCH_ARMv6)
+ return false;
+
+ return !!(get_cr() & CR_XP);
+}
+
+#define set_section_perms(perms, field) { \
+ size_t i; \
+ unsigned long addr; \
+ \
+ if (!arch_has_strict_perms()) \
+ return; \
+ \
+ for (i = 0; i < ARRAY_SIZE(perms); i++) { \
+ if (!IS_ALIGNED(perms[i].start, SECTION_SIZE) || \
+ !IS_ALIGNED(perms[i].end, SECTION_SIZE)) { \
+ pr_err("BUG: section %lx-%lx not aligned to %lx\n", \
+ perms[i].start, perms[i].end, \
+ SECTION_SIZE); \
+ continue; \
+ } \
+ \
+ for (addr = perms[i].start; \
+ addr < perms[i].end; \
+ addr += SECTION_SIZE) \
+ section_update(addr, perms[i].mask, \
+ perms[i].field); \
+ } \
+}
+
+static inline void fix_kernmem_perms(void)
+{
+ set_section_perms(nx_perms, prot);
+}
+
+#ifdef CONFIG_DEBUG_RODATA
+void mark_rodata_ro(void)
+{
+ set_section_perms(ro_perms, prot);
+}
+
+void set_kernel_text_rw(void)
+{
+ set_section_perms(ro_perms, clear);
+}
+
+void set_kernel_text_ro(void)
+{
+ set_section_perms(ro_perms, prot);
+}
+#endif /* CONFIG_DEBUG_RODATA */
+
+#else
+static inline void fix_kernmem_perms(void) { }
+#endif /* CONFIG_ARM_KERNMEM_PERMS */
+
+void free_tcmmem(void)
+{
+#ifdef CONFIG_HAVE_TCM
+ extern char __tcm_start, __tcm_end;
+
+ poison_init_mem(&__tcm_start, &__tcm_end - &__tcm_start);
+ free_reserved_area(&__tcm_start, &__tcm_end, -1, "TCM link");
+#endif
+}
+
+void free_initmem(void)
+{
+ fix_kernmem_perms();
+ free_tcmmem();
+
+ poison_init_mem(__init_begin, __init_end - __init_begin);
+ if (!machine_is_integrator() && !machine_is_cintegrator())
+ free_initmem_default(-1);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+
+static int keep_initrd;
+
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ if (!keep_initrd) {
+ if (start == initrd_start)
+ start = round_down(start, PAGE_SIZE);
+ if (end == initrd_end)
+ end = round_up(end, PAGE_SIZE);
+
+ poison_init_mem((void *)start, PAGE_ALIGN(end) - start);
+ free_reserved_area((void *)start, (void *)end, -1, "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 000000000..461420836
--- /dev/null
+++ b/arch/arm/mm/iomap.c
@@ -0,0 +1,42 @@
+/*
+ * 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>
+
+unsigned long vga_base;
+EXPORT_SYMBOL(vga_base);
+
+#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
+unsigned long pcibios_min_io = 0x1000;
+EXPORT_SYMBOL(pcibios_min_io);
+
+unsigned long pcibios_min_mem = 0x01000000;
+EXPORT_SYMBOL(pcibios_min_mem);
+
+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 000000000..d1e5ad7ab
--- /dev/null
+++ b/arch/arm/mm/ioremap.c
@@ -0,0 +1,458 @@
+/*
+ * 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 <linux/sizes.h>
+
+#include <asm/cp15.h>
+#include <asm/cputype.h>
+#include <asm/cacheflush.h>
+#include <asm/mmu_context.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+#include <asm/system_info.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/pci.h>
+#include "mm.h"
+
+
+LIST_HEAD(static_vmlist);
+
+static struct static_vm *find_static_vm_paddr(phys_addr_t paddr,
+ size_t size, unsigned int mtype)
+{
+ struct static_vm *svm;
+ struct vm_struct *vm;
+
+ list_for_each_entry(svm, &static_vmlist, list) {
+ vm = &svm->vm;
+ if (!(vm->flags & VM_ARM_STATIC_MAPPING))
+ continue;
+ if ((vm->flags & VM_ARM_MTYPE_MASK) != VM_ARM_MTYPE(mtype))
+ continue;
+
+ if (vm->phys_addr > paddr ||
+ paddr + size - 1 > vm->phys_addr + vm->size - 1)
+ continue;
+
+ return svm;
+ }
+
+ return NULL;
+}
+
+struct static_vm *find_static_vm_vaddr(void *vaddr)
+{
+ struct static_vm *svm;
+ struct vm_struct *vm;
+
+ list_for_each_entry(svm, &static_vmlist, list) {
+ vm = &svm->vm;
+
+ /* static_vmlist is ascending order */
+ if (vm->addr > vaddr)
+ break;
+
+ if (vm->addr <= vaddr && vm->addr + vm->size > vaddr)
+ return svm;
+ }
+
+ return NULL;
+}
+
+void __init add_static_vm_early(struct static_vm *svm)
+{
+ struct static_vm *curr_svm;
+ struct vm_struct *vm;
+ void *vaddr;
+
+ vm = &svm->vm;
+ vm_area_add_early(vm);
+ vaddr = vm->addr;
+
+ list_for_each_entry(curr_svm, &static_vmlist, list) {
+ vm = &curr_svm->vm;
+
+ if (vm->addr > vaddr)
+ break;
+ }
+ list_add_tail(&svm->list, &curr_svm->list);
+}
+
+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_vmalloc_seq(struct mm_struct *mm)
+{
+ unsigned int seq;
+
+ do {
+ seq = init_mm.context.vmalloc_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.vmalloc_seq = seq;
+ } while (seq != init_mm.context.vmalloc_seq);
+}
+
+#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
+/*
+ * 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;
+ pud_t *pud;
+ pmd_t *pmdp;
+
+ flush_cache_vunmap(addr, end);
+ pgd = pgd_offset_k(addr);
+ pud = pud_offset(pgd, addr);
+ pmdp = pmd_offset(pud, addr);
+ do {
+ pmd_t pmd = *pmdp;
+
+ if (!pmd_none(pmd)) {
+ /*
+ * Clear the PMD from the page table, and
+ * increment the vmalloc sequence so others
+ * notice this change.
+ *
+ * Note: this is still racy on SMP machines.
+ */
+ pmd_clear(pmdp);
+ init_mm.context.vmalloc_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 += PMD_SIZE;
+ pmdp += 2;
+ } 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.vmalloc_seq != init_mm.context.vmalloc_seq)
+ __check_vmalloc_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;
+ pud_t *pud;
+ pmd_t *pmd;
+
+ /*
+ * Remove and free any PTE-based mapping, and
+ * sync the current kernel mapping.
+ */
+ unmap_area_sections(virt, size);
+
+ pgd = pgd_offset_k(addr);
+ pud = pud_offset(pgd, addr);
+ pmd = pmd_offset(pud, addr);
+ do {
+ 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 += PMD_SIZE;
+ pmd += 2;
+ } 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;
+ pud_t *pud;
+ pmd_t *pmd;
+
+ /*
+ * Remove and free any PTE-based mapping, and
+ * sync the current kernel mapping.
+ */
+ unmap_area_sections(virt, size);
+
+ pgd = pgd_offset_k(virt);
+ pud = pud_offset(pgd, addr);
+ pmd = pmd_offset(pud, addr);
+ 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[0] = __pmd(super_pmd_val);
+ pmd[1] = __pmd(super_pmd_val);
+ flush_pmd_entry(pmd);
+
+ addr += PMD_SIZE;
+ pmd += 2;
+ }
+
+ 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;
+ phys_addr_t paddr = __pfn_to_phys(pfn);
+
+#ifndef CONFIG_ARM_LPAE
+ /*
+ * High mappings must be supersection aligned
+ */
+ if (pfn >= 0x100000 && (paddr & ~SUPERSECTION_MASK))
+ return NULL;
+#endif
+
+ type = get_mem_type(mtype);
+ if (!type)
+ return NULL;
+
+ /*
+ * Page align the mapping size, taking account of any offset.
+ */
+ size = PAGE_ALIGN(offset + size);
+
+ /*
+ * Try to reuse one of the static mapping whenever possible.
+ */
+ if (size && !(sizeof(phys_addr_t) == 4 && pfn >= 0x100000)) {
+ struct static_vm *svm;
+
+ svm = find_static_vm_paddr(paddr, size, mtype);
+ if (svm) {
+ addr = (unsigned long)svm->vm.addr;
+ addr += paddr - svm->vm.phys_addr;
+ return (void __iomem *) (offset + addr);
+ }
+ }
+
+ /*
+ * Don't allow RAM to be mapped - this causes problems with ARMv6+
+ */
+ if (WARN_ON(pfn_valid(pfn)))
+ return NULL;
+
+ area = get_vm_area_caller(size, VM_IOREMAP, caller);
+ if (!area)
+ return NULL;
+ addr = (unsigned long)area->addr;
+ area->phys_addr = paddr;
+
+#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
+ if (DOMAIN_IO == 0 &&
+ (((cpu_architecture() >= CPU_ARCH_ARMv6) && (get_cr() & CR_XP)) ||
+ cpu_is_xsc3()) && pfn >= 0x100000 &&
+ !((paddr | size | addr) & ~SUPERSECTION_MASK)) {
+ area->flags |= VM_ARM_SECTION_MAPPING;
+ err = remap_area_supersections(addr, pfn, size, type);
+ } else if (!((paddr | 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, paddr,
+ __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(phys_addr_t phys_addr, size_t size,
+ unsigned int mtype, void *caller)
+{
+ phys_addr_t 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 * (*arch_ioremap_caller)(phys_addr_t, size_t,
+ unsigned int, void *) =
+ __arm_ioremap_caller;
+
+void __iomem *
+__arm_ioremap(phys_addr_t phys_addr, size_t size, unsigned int mtype)
+{
+ return arch_ioremap_caller(phys_addr, size, mtype,
+ __builtin_return_address(0));
+}
+EXPORT_SYMBOL(__arm_ioremap);
+
+/*
+ * Remap an arbitrary physical address space into the kernel virtual
+ * address space as memory. Needed when the kernel wants to execute
+ * code in external memory. This is needed for reprogramming source
+ * clocks that would affect normal memory for example. Please see
+ * CONFIG_GENERIC_ALLOCATOR for allocating external memory.
+ */
+void __iomem *
+__arm_ioremap_exec(phys_addr_t phys_addr, size_t size, bool cached)
+{
+ unsigned int mtype;
+
+ if (cached)
+ mtype = MT_MEMORY_RWX;
+ else
+ mtype = MT_MEMORY_RWX_NONCACHED;
+
+ return __arm_ioremap_caller(phys_addr, size, mtype,
+ __builtin_return_address(0));
+}
+
+void __iounmap(volatile void __iomem *io_addr)
+{
+ void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr);
+ struct static_vm *svm;
+
+ /* If this is a static mapping, we must leave it alone */
+ svm = find_static_vm_vaddr(addr);
+ if (svm)
+ return;
+
+#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
+ {
+ struct vm_struct *vm;
+
+ vm = find_vm_area(addr);
+
+ /*
+ * 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.
+ */
+ if (vm && (vm->flags & VM_ARM_SECTION_MAPPING))
+ unmap_area_sections((unsigned long)vm->addr, vm->size);
+ }
+#endif
+
+ vunmap(addr);
+}
+
+void (*arch_iounmap)(volatile void __iomem *) = __iounmap;
+
+void __arm_iounmap(volatile void __iomem *io_addr)
+{
+ arch_iounmap(io_addr);
+}
+EXPORT_SYMBOL(__arm_iounmap);
+
+#ifdef CONFIG_PCI
+static int pci_ioremap_mem_type = MT_DEVICE;
+
+void pci_ioremap_set_mem_type(int mem_type)
+{
+ pci_ioremap_mem_type = mem_type;
+}
+
+int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr)
+{
+ BUG_ON(offset + SZ_64K > IO_SPACE_LIMIT);
+
+ return ioremap_page_range(PCI_IO_VIRT_BASE + offset,
+ PCI_IO_VIRT_BASE + offset + SZ_64K,
+ phys_addr,
+ __pgprot(get_mem_type(pci_ioremap_mem_type)->prot_pte));
+}
+EXPORT_SYMBOL_GPL(pci_ioremap_io);
+#endif
diff --git a/arch/arm/mm/l2c-common.c b/arch/arm/mm/l2c-common.c
new file mode 100644
index 000000000..10a3cf28c
--- /dev/null
+++ b/arch/arm/mm/l2c-common.c
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+#include <linux/bug.h>
+#include <linux/smp.h>
+#include <asm/outercache.h>
+
+void outer_disable(void)
+{
+ WARN_ON(!irqs_disabled());
+ WARN_ON(num_online_cpus() > 1);
+
+ if (outer_cache.disable)
+ outer_cache.disable();
+}
diff --git a/arch/arm/mm/l2c-l2x0-resume.S b/arch/arm/mm/l2c-l2x0-resume.S
new file mode 100644
index 000000000..fda415e4c
--- /dev/null
+++ b/arch/arm/mm/l2c-l2x0-resume.S
@@ -0,0 +1,59 @@
+/*
+ * L2C-310 early resume code. This can be used by platforms to restore
+ * the settings of their L2 cache controller before restoring the
+ * processor state.
+ *
+ * This code can only be used to if you are running in the secure world.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware/cache-l2x0.h>
+
+ .text
+
+ENTRY(l2c310_early_resume)
+ adr r0, 1f
+ ldr r2, [r0]
+ add r0, r2, r0
+
+ ldmia r0, {r1, r2, r3, r4, r5, r6, r7, r8}
+ @ r1 = phys address of L2C-310 controller
+ @ r2 = aux_ctrl
+ @ r3 = tag_latency
+ @ r4 = data_latency
+ @ r5 = filter_start
+ @ r6 = filter_end
+ @ r7 = prefetch_ctrl
+ @ r8 = pwr_ctrl
+
+ @ Check that the address has been initialised
+ teq r1, #0
+ reteq lr
+
+ @ The prefetch and power control registers are revision dependent
+ @ and can be written whether or not the L2 cache is enabled
+ ldr r0, [r1, #L2X0_CACHE_ID]
+ and r0, r0, #L2X0_CACHE_ID_RTL_MASK
+ cmp r0, #L310_CACHE_ID_RTL_R2P0
+ strcs r7, [r1, #L310_PREFETCH_CTRL]
+ cmp r0, #L310_CACHE_ID_RTL_R3P0
+ strcs r8, [r1, #L310_POWER_CTRL]
+
+ @ Don't setup the L2 cache if it is already enabled
+ ldr r0, [r1, #L2X0_CTRL]
+ tst r0, #L2X0_CTRL_EN
+ retne lr
+
+ str r3, [r1, #L310_TAG_LATENCY_CTRL]
+ str r4, [r1, #L310_DATA_LATENCY_CTRL]
+ str r6, [r1, #L310_ADDR_FILTER_END]
+ str r5, [r1, #L310_ADDR_FILTER_START]
+
+ str r2, [r1, #L2X0_AUX_CTRL]
+ mov r9, #L2X0_CTRL_EN
+ str r9, [r1, #L2X0_CTRL]
+ ret lr
+ENDPROC(l2c310_early_resume)
+
+ .align
+1: .long l2x0_saved_regs - .
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
new file mode 100644
index 000000000..ce727d472
--- /dev/null
+++ b/arch/arm/mm/mm.h
@@ -0,0 +1,99 @@
+#ifdef CONFIG_MMU
+#include <linux/list.h>
+#include <linux/vmalloc.h>
+
+#include <asm/pgtable.h>
+
+/* the upper-most page table pointer */
+extern pmd_t *top_pmd;
+
+/*
+ * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
+ * specific hacks for copying pages efficiently, while 0xffff4000
+ * is reserved for VIPT aliasing flushing by generic code.
+ *
+ * Note that we don't allow VIPT aliasing caches with SMP.
+ */
+#define COPYPAGE_MINICACHE 0xffff8000
+#define COPYPAGE_V6_FROM 0xffff8000
+#define COPYPAGE_V6_TO 0xffffc000
+/* PFN alias flushing, for VIPT caches */
+#define FLUSH_ALIAS_START 0xffff4000
+
+static inline void set_top_pte(unsigned long va, pte_t pte)
+{
+ pte_t *ptep = pte_offset_kernel(top_pmd, va);
+ set_pte_ext(ptep, pte, 0);
+ local_flush_tlb_kernel_page(va);
+}
+
+static inline pte_t get_top_pte(unsigned long va)
+{
+ pte_t *ptep = pte_offset_kernel(top_pmd, va);
+ return *ptep;
+}
+
+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;
+ pteval_t prot_pte_s2;
+ pmdval_t prot_l1;
+ pmdval_t 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);
+
+/*
+ * ARM specific vm_struct->flags bits.
+ */
+
+/* (super)section-mapped I/O regions used by ioremap()/iounmap() */
+#define VM_ARM_SECTION_MAPPING 0x80000000
+
+/* permanent static mappings from iotable_init() */
+#define VM_ARM_STATIC_MAPPING 0x40000000
+
+/* empty mapping */
+#define VM_ARM_EMPTY_MAPPING 0x20000000
+
+/* mapping type (attributes) for permanent static mappings */
+#define VM_ARM_MTYPE(mt) ((mt) << 20)
+#define VM_ARM_MTYPE_MASK (0x1f << 20)
+
+/* consistent regions used by dma_alloc_attrs() */
+#define VM_ARM_DMA_CONSISTENT 0x20000000
+
+
+struct static_vm {
+ struct vm_struct vm;
+ struct list_head list;
+};
+
+extern struct list_head static_vmlist;
+extern struct static_vm *find_static_vm_vaddr(void *vaddr);
+extern __init void add_static_vm_early(struct static_vm *svm);
+
+#endif
+
+#ifdef CONFIG_ZONE_DMA
+extern phys_addr_t arm_dma_limit;
+extern unsigned long arm_dma_pfn_limit;
+#else
+#define arm_dma_limit ((phys_addr_t)~0)
+#define arm_dma_pfn_limit (~0ul >> PAGE_SHIFT)
+#endif
+
+extern phys_addr_t arm_lowmem_limit;
+
+void __init bootmem_init(void);
+void arm_mm_memblock_reserve(void);
+void dma_contiguous_remap(void);
+
+unsigned long __clear_cr(unsigned long mask);
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
new file mode 100644
index 000000000..407dc7865
--- /dev/null
+++ b/arch/arm/mm/mmap.c
@@ -0,0 +1,240 @@
+/*
+ * 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/cachetype.h>
+
+#define COLOUR_ALIGN(addr,pgoff) \
+ ((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \
+ (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
+
+/* gap between mmap and stack */
+#define MIN_GAP (128*1024*1024UL)
+#define MAX_GAP ((TASK_SIZE)/6*5)
+
+static int mmap_is_legacy(void)
+{
+ if (current->personality & ADDR_COMPAT_LAYOUT)
+ return 1;
+
+ if (rlimit(RLIMIT_STACK) == RLIM_INFINITY)
+ return 1;
+
+ return sysctl_legacy_va_layout;
+}
+
+static unsigned long mmap_base(unsigned long rnd)
+{
+ unsigned long gap = rlimit(RLIMIT_STACK);
+
+ if (gap < MIN_GAP)
+ gap = MIN_GAP;
+ else if (gap > MAX_GAP)
+ gap = MAX_GAP;
+
+ return PAGE_ALIGN(TASK_SIZE - gap - rnd);
+}
+
+/*
+ * 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;
+ int do_align = 0;
+ int aliasing = cache_is_vipt_aliasing();
+ struct vm_unmapped_area_info info;
+
+ /*
+ * We only need to do colour alignment if either the I or D
+ * caches alias.
+ */
+ if (aliasing)
+ do_align = filp || (flags & MAP_SHARED);
+
+ /*
+ * 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;
+ }
+
+ info.flags = 0;
+ info.length = len;
+ info.low_limit = mm->mmap_base;
+ info.high_limit = TASK_SIZE;
+ info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
+ return vm_unmapped_area(&info);
+}
+
+unsigned long
+arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ const unsigned long len, const unsigned long pgoff,
+ const unsigned long flags)
+{
+ struct vm_area_struct *vma;
+ struct mm_struct *mm = current->mm;
+ unsigned long addr = addr0;
+ int do_align = 0;
+ int aliasing = cache_is_vipt_aliasing();
+ struct vm_unmapped_area_info info;
+
+ /*
+ * We only need to do colour alignment if either the I or D
+ * caches alias.
+ */
+ if (aliasing)
+ do_align = filp || (flags & MAP_SHARED);
+
+ /* requested length too big for entire address space */
+ if (len > TASK_SIZE)
+ return -ENOMEM;
+
+ if (flags & MAP_FIXED) {
+ if (aliasing && flags & MAP_SHARED &&
+ (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
+ return -EINVAL;
+ return addr;
+ }
+
+ /* requesting a specific address */
+ 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;
+ }
+
+ info.flags = VM_UNMAPPED_AREA_TOPDOWN;
+ info.length = len;
+ info.low_limit = FIRST_USER_ADDRESS;
+ info.high_limit = mm->mmap_base;
+ info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
+ addr = vm_unmapped_area(&info);
+
+ /*
+ * A failed mmap() very likely causes application failure,
+ * so fall back to the bottom-up function here. This scenario
+ * can happen with large stack limits and large mmap()
+ * allocations.
+ */
+ if (addr & ~PAGE_MASK) {
+ VM_BUG_ON(addr != -ENOMEM);
+ info.flags = 0;
+ info.low_limit = mm->mmap_base;
+ info.high_limit = TASK_SIZE;
+ addr = vm_unmapped_area(&info);
+ }
+
+ return addr;
+}
+
+unsigned long arch_mmap_rnd(void)
+{
+ unsigned long rnd;
+
+ /* 8 bits of randomness in 20 address space bits */
+ rnd = (unsigned long)get_random_int() % (1 << 8);
+
+ return rnd << PAGE_SHIFT;
+}
+
+void arch_pick_mmap_layout(struct mm_struct *mm)
+{
+ unsigned long random_factor = 0UL;
+
+ if (current->flags & PF_RANDOMIZE)
+ random_factor = arch_mmap_rnd();
+
+ if (mmap_is_legacy()) {
+ mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
+ mm->get_unmapped_area = arch_get_unmapped_area;
+ } else {
+ mm->mmap_base = mmap_base(random_factor);
+ mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+ }
+}
+
+/*
+ * You really shouldn't be using read() or write() on /dev/mem. This
+ * might go away in the future.
+ */
+int valid_phys_addr_range(phys_addr_t addr, size_t size)
+{
+ if (addr < PHYS_OFFSET)
+ return 0;
+ if (addr + size > __pa(high_memory - 1) + 1)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Do not allow /dev/mem mappings beyond the supported physical range.
+ */
+int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
+{
+ return (pfn + (size >> PAGE_SHIFT)) <= (1 + (PHYS_MASK >> PAGE_SHIFT));
+}
+
+#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 000000000..718638267
--- /dev/null
+++ b/arch/arm/mm/mmu.c
@@ -0,0 +1,1536 @@
+/*
+ * 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 <linux/vmalloc.h>
+#include <linux/sizes.h>
+
+#include <asm/cp15.h>
+#include <asm/cputype.h>
+#include <asm/sections.h>
+#include <asm/cachetype.h>
+#include <asm/fixmap.h>
+#include <asm/sections.h>
+#include <asm/setup.h>
+#include <asm/smp_plat.h>
+#include <asm/tlb.h>
+#include <asm/highmem.h>
+#include <asm/system_info.h>
+#include <asm/traps.h>
+#include <asm/procinfo.h>
+#include <asm/memory.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/pci.h>
+#include <asm/fixmap.h>
+
+#include "mm.h"
+#include "tcm.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;
+
+pmdval_t user_pmd_table = _PAGE_USER_TABLE;
+
+#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;
+pgprot_t pgprot_hyp_device;
+pgprot_t pgprot_s2;
+pgprot_t pgprot_s2_device;
+
+EXPORT_SYMBOL(pgprot_user);
+EXPORT_SYMBOL(pgprot_kernel);
+
+struct cachepolicy {
+ const char policy[16];
+ unsigned int cr_mask;
+ pmdval_t pmd;
+ pteval_t pte;
+ pteval_t pte_s2;
+};
+
+#ifdef CONFIG_ARM_LPAE
+#define s2_policy(policy) policy
+#else
+#define s2_policy(policy) 0
+#endif
+
+static struct cachepolicy cache_policies[] __initdata = {
+ {
+ .policy = "uncached",
+ .cr_mask = CR_W|CR_C,
+ .pmd = PMD_SECT_UNCACHED,
+ .pte = L_PTE_MT_UNCACHED,
+ .pte_s2 = s2_policy(L_PTE_S2_MT_UNCACHED),
+ }, {
+ .policy = "buffered",
+ .cr_mask = CR_C,
+ .pmd = PMD_SECT_BUFFERED,
+ .pte = L_PTE_MT_BUFFERABLE,
+ .pte_s2 = s2_policy(L_PTE_S2_MT_UNCACHED),
+ }, {
+ .policy = "writethrough",
+ .cr_mask = 0,
+ .pmd = PMD_SECT_WT,
+ .pte = L_PTE_MT_WRITETHROUGH,
+ .pte_s2 = s2_policy(L_PTE_S2_MT_WRITETHROUGH),
+ }, {
+ .policy = "writeback",
+ .cr_mask = 0,
+ .pmd = PMD_SECT_WB,
+ .pte = L_PTE_MT_WRITEBACK,
+ .pte_s2 = s2_policy(L_PTE_S2_MT_WRITEBACK),
+ }, {
+ .policy = "writealloc",
+ .cr_mask = 0,
+ .pmd = PMD_SECT_WBWA,
+ .pte = L_PTE_MT_WRITEALLOC,
+ .pte_s2 = s2_policy(L_PTE_S2_MT_WRITEBACK),
+ }
+};
+
+#ifdef CONFIG_CPU_CP15
+static unsigned long initial_pmd_value __initdata = 0;
+
+/*
+ * Initialise the cache_policy variable with the initial state specified
+ * via the "pmd" value. This is used to ensure that on ARMv6 and later,
+ * the C code sets the page tables up with the same policy as the head
+ * assembly code, which avoids an illegal state where the TLBs can get
+ * confused. See comments in early_cachepolicy() for more information.
+ */
+void __init init_default_cache_policy(unsigned long pmd)
+{
+ int i;
+
+ initial_pmd_value = pmd;
+
+ pmd &= PMD_SECT_TEX(1) | PMD_SECT_BUFFERABLE | PMD_SECT_CACHEABLE;
+
+ for (i = 0; i < ARRAY_SIZE(cache_policies); i++)
+ if (cache_policies[i].pmd == pmd) {
+ cachepolicy = i;
+ break;
+ }
+
+ if (i == ARRAY_SIZE(cache_policies))
+ pr_err("ERROR: could not find cache policy\n");
+}
+
+/*
+ * 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, selected = -1;
+
+ 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) {
+ selected = i;
+ break;
+ }
+ }
+
+ if (selected == -1)
+ pr_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 && selected != cachepolicy) {
+ pr_warn("Only cachepolicy=%s supported on ARMv6 and later\n",
+ cache_policies[cachepolicy].policy);
+ return 0;
+ }
+
+ if (selected != cachepolicy) {
+ unsigned long cr = __clear_cr(cache_policies[selected].cr_mask);
+ cachepolicy = selected;
+ flush_cache_all();
+ set_cr(cr);
+ }
+ return 0;
+}
+early_param("cachepolicy", early_cachepolicy);
+
+static int __init early_nocache(char *__unused)
+{
+ char *p = "buffered";
+ pr_warn("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";
+ pr_warn("nowb is deprecated; use cachepolicy=%s\n", p);
+ early_cachepolicy(p);
+ return 0;
+}
+early_param("nowb", early_nowrite);
+
+#ifndef CONFIG_ARM_LPAE
+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);
+#endif
+
+#else /* ifdef CONFIG_CPU_CP15 */
+
+static int __init early_cachepolicy(char *p)
+{
+ pr_warn("cachepolicy kernel parameter not supported without cp15\n");
+}
+early_param("cachepolicy", early_cachepolicy);
+
+static int __init noalign_setup(char *__unused)
+{
+ pr_warn("noalign kernel parameter not supported without cp15\n");
+}
+__setup("noalign", noalign_setup);
+
+#endif /* ifdef CONFIG_CPU_CP15 / else */
+
+#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN
+#define PROT_PTE_S2_DEVICE PROT_PTE_DEVICE
+#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_pte_s2 = s2_policy(PROT_PTE_S2_DEVICE) |
+ s2_policy(L_PTE_S2_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,
+ },
+#ifndef CONFIG_ARM_LPAE
+ [MT_MINICLEAN] = {
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_MINICACHE,
+ .domain = DOMAIN_KERNEL,
+ },
+#endif
+ [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_RWX] = {
+ .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_MEMORY_RW] = {
+ .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_AP_WRITE,
+ .domain = DOMAIN_KERNEL,
+ },
+ [MT_ROM] = {
+ .prot_sect = PMD_TYPE_SECT,
+ .domain = DOMAIN_KERNEL,
+ },
+ [MT_MEMORY_RWX_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_RW_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_RWX_ITCM] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .domain = DOMAIN_KERNEL,
+ },
+ [MT_MEMORY_RW_SO] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ L_PTE_MT_UNCACHED | L_PTE_XN,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_S |
+ PMD_SECT_UNCACHED | PMD_SECT_XN,
+ .domain = DOMAIN_KERNEL,
+ },
+ [MT_MEMORY_DMA_READY] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ L_PTE_XN,
+ .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);
+
+/*
+ * To avoid TLB flush broadcasts, this uses local_flush_tlb_kernel_range().
+ * As a result, this can only be called with preemption disabled, as under
+ * stop_machine().
+ */
+void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
+{
+ unsigned long vaddr = __fix_to_virt(idx);
+ pte_t *pte = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
+
+ /* Make sure fixmap region does not exceed available allocation. */
+ BUILD_BUG_ON(FIXADDR_START + (__end_of_fixed_addresses * PAGE_SIZE) >
+ FIXADDR_END);
+ BUG_ON(idx >= __end_of_fixed_addresses);
+
+ if (pgprot_val(prot))
+ set_pte_at(NULL, vaddr, pte,
+ pfn_pte(phys >> PAGE_SHIFT, prot));
+ else
+ pte_clear(NULL, vaddr, pte);
+ local_flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE);
+}
+
+/*
+ * 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();
+ pteval_t user_pgprot, kern_pgprot, vecs_pgprot;
+ pteval_t hyp_device_pgprot, s2_pgprot, s2_device_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()) {
+ if (cachepolicy != CPOLICY_WRITEALLOC) {
+ pr_warn("Forcing write-allocate cache policy for SMP\n");
+ cachepolicy = CPOLICY_WRITEALLOC;
+ }
+ if (!(initial_pmd_value & PMD_SECT_S)) {
+ pr_warn("Forcing shared mappings for SMP\n");
+ initial_pmd_value |= PMD_SECT_S;
+ }
+ }
+
+ /*
+ * 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;
+
+ /* Also setup NX memory mapping */
+ mem_types[MT_MEMORY_RW].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;
+ s2_pgprot = cp->pte_s2;
+ hyp_device_pgprot = mem_types[MT_DEVICE].prot_pte;
+ s2_device_pgprot = mem_types[MT_DEVICE].prot_pte_s2;
+
+#ifndef CONFIG_ARM_LPAE
+ /*
+ * We don't use domains on ARMv6 (since this causes problems with
+ * v6/v7 kernels), so we must use a separate memory type for user
+ * r/o, kernel r/w to map the vectors page.
+ */
+ if (cpu_arch == CPU_ARCH_ARMv6)
+ vecs_pgprot |= L_PTE_MT_VECTORS;
+
+ /*
+ * Check is it with support for the PXN bit
+ * in the Short-descriptor translation table format descriptors.
+ */
+ if (cpu_arch == CPU_ARCH_ARMv7 &&
+ (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xF) == 4) {
+ user_pmd_table |= PMD_PXNTABLE;
+ }
+#endif
+
+ /*
+ * ARMv6 and above have extended page tables.
+ */
+ if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) {
+#ifndef CONFIG_ARM_LPAE
+ /*
+ * 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;
+#endif
+
+ /*
+ * If the initial page tables were created with the S bit
+ * set, then we need to do the same here for the same
+ * reasons given in early_cachepolicy().
+ */
+ if (initial_pmd_value & PMD_SECT_S) {
+ user_pgprot |= L_PTE_SHARED;
+ kern_pgprot |= L_PTE_SHARED;
+ vecs_pgprot |= L_PTE_SHARED;
+ s2_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_RWX].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY_RWX].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY_RW].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY_RWX_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_RWX_NONCACHED].prot_sect |=
+ PMD_SECT_BUFFERED;
+ } else {
+ /* For both ARMv6 and non-TEX-remapping ARMv7 */
+ mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |=
+ PMD_SECT_TEX(1);
+ }
+ } else {
+ mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
+ }
+
+#ifdef CONFIG_ARM_LPAE
+ /*
+ * Do not generate access flag faults for the kernel mappings.
+ */
+ for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
+ mem_types[i].prot_pte |= PTE_EXT_AF;
+ if (mem_types[i].prot_sect)
+ mem_types[i].prot_sect |= PMD_SECT_AF;
+ }
+ kern_pgprot |= PTE_EXT_AF;
+ vecs_pgprot |= PTE_EXT_AF;
+
+ /*
+ * Set PXN for user mappings
+ */
+ user_pgprot |= PTE_EXT_PXN;
+#endif
+
+ for (i = 0; i < 16; i++) {
+ pteval_t 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);
+ pgprot_s2 = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | s2_pgprot);
+ pgprot_s2_device = __pgprot(s2_device_pgprot);
+ pgprot_hyp_device = __pgprot(hyp_device_pgprot);
+
+ mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
+ mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
+ mem_types[MT_MEMORY_RWX].prot_sect |= ecc_mask | cp->pmd;
+ mem_types[MT_MEMORY_RWX].prot_pte |= kern_pgprot;
+ mem_types[MT_MEMORY_RW].prot_sect |= ecc_mask | cp->pmd;
+ mem_types[MT_MEMORY_RW].prot_pte |= kern_pgprot;
+ mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot;
+ mem_types[MT_MEMORY_RWX_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;
+ }
+ pr_info("Memory policy: %sData cache %s\n",
+ ecc_mask ? "ECC enabled, " : "", 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_aligned(unsigned long sz, unsigned long align)
+{
+ void *ptr = __va(memblock_alloc(sz, align));
+ memset(ptr, 0, sz);
+ return ptr;
+}
+
+static void __init *early_alloc(unsigned long sz)
+{
+ return early_alloc_aligned(sz, sz);
+}
+
+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 __map_init_section(pmd_t *pmd, unsigned long addr,
+ unsigned long end, phys_addr_t phys,
+ const struct mem_type *type)
+{
+ pmd_t *p = pmd;
+
+#ifndef CONFIG_ARM_LPAE
+ /*
+ * In classic MMU format, puds and pmds are folded in to
+ * the pgds. pmd_offset gives the PGD entry. PGDs refer to a
+ * group of L1 entries making up one logical pointer to
+ * an L2 table (2MB), where as PMDs refer to the individual
+ * L1 entries (1MB). Hence increment to get the correct
+ * offset for odd 1MB sections.
+ * (See arch/arm/include/asm/pgtable-2level.h)
+ */
+ if (addr & SECTION_SIZE)
+ pmd++;
+#endif
+ do {
+ *pmd = __pmd(phys | type->prot_sect);
+ phys += SECTION_SIZE;
+ } while (pmd++, addr += SECTION_SIZE, addr != end);
+
+ flush_pmd_entry(p);
+}
+
+static void __init alloc_init_pmd(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);
+ unsigned long next;
+
+ do {
+ /*
+ * With LPAE, we must loop over to map
+ * all the pmds for the given range.
+ */
+ next = pmd_addr_end(addr, end);
+
+ /*
+ * Try a section mapping - addr, next and phys must all be
+ * aligned to a section boundary.
+ */
+ if (type->prot_sect &&
+ ((addr | next | phys) & ~SECTION_MASK) == 0) {
+ __map_init_section(pmd, addr, next, phys, type);
+ } else {
+ alloc_init_pte(pmd, addr, next,
+ __phys_to_pfn(phys), type);
+ }
+
+ phys += next - addr;
+
+ } while (pmd++, addr = next, addr != end);
+}
+
+static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
+ unsigned long end, phys_addr_t 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_pmd(pud, addr, next, phys, type);
+ phys += next - addr;
+ } while (pud++, addr = next, addr != end);
+}
+
+#ifndef CONFIG_ARM_LPAE
+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())) {
+ pr_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) {
+ pr_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) {
+ pr_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);
+}
+#endif /* !CONFIG_ARM_LPAE */
+
+/*
+ * 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) {
+ pr_warn("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_START || md->virtual >= VMALLOC_END)) {
+ pr_warn("BUG: mapping for 0x%08llx at 0x%08lx out of vmalloc space\n",
+ (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
+ }
+
+ type = &mem_types[md->type];
+
+#ifndef CONFIG_ARM_LPAE
+ /*
+ * Catch 36-bit addresses
+ */
+ if (md->pfn >= 0x100000) {
+ create_36bit_mapping(md, type);
+ return;
+ }
+#endif
+
+ 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)) {
+ pr_warn("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)
+{
+ struct map_desc *md;
+ struct vm_struct *vm;
+ struct static_vm *svm;
+
+ if (!nr)
+ return;
+
+ svm = early_alloc_aligned(sizeof(*svm) * nr, __alignof__(*svm));
+
+ for (md = io_desc; nr; md++, nr--) {
+ create_mapping(md);
+
+ vm = &svm->vm;
+ vm->addr = (void *)(md->virtual & PAGE_MASK);
+ vm->size = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
+ vm->phys_addr = __pfn_to_phys(md->pfn);
+ vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
+ vm->flags |= VM_ARM_MTYPE(md->type);
+ vm->caller = iotable_init;
+ add_static_vm_early(svm++);
+ }
+}
+
+void __init vm_reserve_area_early(unsigned long addr, unsigned long size,
+ void *caller)
+{
+ struct vm_struct *vm;
+ struct static_vm *svm;
+
+ svm = early_alloc_aligned(sizeof(*svm), __alignof__(*svm));
+
+ vm = &svm->vm;
+ vm->addr = (void *)addr;
+ vm->size = size;
+ vm->flags = VM_IOREMAP | VM_ARM_EMPTY_MAPPING;
+ vm->caller = caller;
+ add_static_vm_early(svm);
+}
+
+#ifndef CONFIG_ARM_LPAE
+
+/*
+ * The Linux PMD is made of two consecutive section entries covering 2MB
+ * (see definition in include/asm/pgtable-2level.h). However a call to
+ * create_mapping() may optimize static mappings by using individual
+ * 1MB section mappings. This leaves the actual PMD potentially half
+ * initialized if the top or bottom section entry isn't used, leaving it
+ * open to problems if a subsequent ioremap() or vmalloc() tries to use
+ * the virtual space left free by that unused section entry.
+ *
+ * Let's avoid the issue by inserting dummy vm entries covering the unused
+ * PMD halves once the static mappings are in place.
+ */
+
+static void __init pmd_empty_section_gap(unsigned long addr)
+{
+ vm_reserve_area_early(addr, SECTION_SIZE, pmd_empty_section_gap);
+}
+
+static void __init fill_pmd_gaps(void)
+{
+ struct static_vm *svm;
+ struct vm_struct *vm;
+ unsigned long addr, next = 0;
+ pmd_t *pmd;
+
+ list_for_each_entry(svm, &static_vmlist, list) {
+ vm = &svm->vm;
+ addr = (unsigned long)vm->addr;
+ if (addr < next)
+ continue;
+
+ /*
+ * Check if this vm starts on an odd section boundary.
+ * If so and the first section entry for this PMD is free
+ * then we block the corresponding virtual address.
+ */
+ if ((addr & ~PMD_MASK) == SECTION_SIZE) {
+ pmd = pmd_off_k(addr);
+ if (pmd_none(*pmd))
+ pmd_empty_section_gap(addr & PMD_MASK);
+ }
+
+ /*
+ * Then check if this vm ends on an odd section boundary.
+ * If so and the second section entry for this PMD is empty
+ * then we block the corresponding virtual address.
+ */
+ addr += vm->size;
+ if ((addr & ~PMD_MASK) == SECTION_SIZE) {
+ pmd = pmd_off_k(addr) + 1;
+ if (pmd_none(*pmd))
+ pmd_empty_section_gap(addr);
+ }
+
+ /* no need to look at any vm entry until we hit the next PMD */
+ next = (addr + PMD_SIZE - 1) & PMD_MASK;
+ }
+}
+
+#else
+#define fill_pmd_gaps() do { } while (0)
+#endif
+
+#if defined(CONFIG_PCI) && !defined(CONFIG_NEED_MACH_IO_H)
+static void __init pci_reserve_io(void)
+{
+ struct static_vm *svm;
+
+ svm = find_static_vm_vaddr((void *)PCI_IO_VIRT_BASE);
+ if (svm)
+ return;
+
+ vm_reserve_area_early(PCI_IO_VIRT_BASE, SZ_2M, pci_reserve_io);
+}
+#else
+#define pci_reserve_io() do { } while (0)
+#endif
+
+#ifdef CONFIG_DEBUG_LL
+void __init debug_ll_io_init(void)
+{
+ struct map_desc map;
+
+ debug_ll_addr(&map.pfn, &map.virtual);
+ if (!map.pfn || !map.virtual)
+ return;
+ map.pfn = __phys_to_pfn(map.pfn);
+ map.virtual &= PAGE_MASK;
+ map.length = PAGE_SIZE;
+ map.type = MT_DEVICE;
+ iotable_init(&map, 1);
+}
+#endif
+
+static void * __initdata vmalloc_min =
+ (void *)(VMALLOC_END - (240 << 20) - VMALLOC_OFFSET);
+
+/*
+ * 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 240m.
+ */
+static int __init early_vmalloc(char *arg)
+{
+ unsigned long vmalloc_reserve = memparse(arg, NULL);
+
+ if (vmalloc_reserve < SZ_16M) {
+ vmalloc_reserve = SZ_16M;
+ pr_warn("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);
+ pr_warn("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);
+
+phys_addr_t arm_lowmem_limit __initdata = 0;
+
+void __init sanity_check_meminfo(void)
+{
+ phys_addr_t memblock_limit = 0;
+ int highmem = 0;
+ phys_addr_t vmalloc_limit = __pa(vmalloc_min - 1) + 1;
+ struct memblock_region *reg;
+
+ for_each_memblock(memory, reg) {
+ phys_addr_t block_start = reg->base;
+ phys_addr_t block_end = reg->base + reg->size;
+ phys_addr_t size_limit = reg->size;
+
+ if (reg->base >= vmalloc_limit)
+ highmem = 1;
+ else
+ size_limit = vmalloc_limit - reg->base;
+
+
+ if (!IS_ENABLED(CONFIG_HIGHMEM) || cache_is_vipt_aliasing()) {
+
+ if (highmem) {
+ pr_notice("Ignoring RAM at %pa-%pa (!CONFIG_HIGHMEM)\n",
+ &block_start, &block_end);
+ memblock_remove(reg->base, reg->size);
+ continue;
+ }
+
+ if (reg->size > size_limit) {
+ phys_addr_t overlap_size = reg->size - size_limit;
+
+ pr_notice("Truncating RAM at %pa-%pa to -%pa",
+ &block_start, &block_end, &vmalloc_limit);
+ memblock_remove(vmalloc_limit, overlap_size);
+ block_end = vmalloc_limit;
+ }
+ }
+
+ if (!highmem) {
+ if (block_end > arm_lowmem_limit) {
+ if (reg->size > size_limit)
+ arm_lowmem_limit = vmalloc_limit;
+ else
+ arm_lowmem_limit = block_end;
+ }
+
+ /*
+ * Find the first non-pmd-aligned page, and point
+ * memblock_limit at it. This relies on rounding the
+ * limit down to be pmd-aligned, which happens at the
+ * end of this function.
+ *
+ * With this algorithm, the start or end of almost any
+ * bank can be non-pmd-aligned. The only exception is
+ * that the start of the bank 0 must be section-
+ * aligned, since otherwise memory would need to be
+ * allocated when mapping the start of bank 0, which
+ * occurs before any free memory is mapped.
+ */
+ if (!memblock_limit) {
+ if (!IS_ALIGNED(block_start, PMD_SIZE))
+ memblock_limit = block_start;
+ else if (!IS_ALIGNED(block_end, PMD_SIZE))
+ memblock_limit = arm_lowmem_limit;
+ }
+
+ }
+ }
+
+ high_memory = __va(arm_lowmem_limit - 1) + 1;
+
+ /*
+ * Round the memblock limit down to a pmd size. This
+ * helps to ensure that we will allocate memory from the
+ * last full pmd, which should be mapped.
+ */
+ if (memblock_limit)
+ memblock_limit = round_down(memblock_limit, PMD_SIZE);
+ if (!memblock_limit)
+ memblock_limit = arm_lowmem_limit;
+
+ memblock_set_current_limit(memblock_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 += PMD_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 + PMD_SIZE - 1) & PMD_MASK;
+#endif
+ for ( ; addr < PAGE_OFFSET; addr += PMD_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 >= arm_lowmem_limit)
+ end = arm_lowmem_limit;
+
+ /*
+ * Clear out all the kernel space mappings, except for the first
+ * memory bank, up to the vmalloc region.
+ */
+ for (addr = __phys_to_virt(end);
+ addr < VMALLOC_START; addr += PMD_SIZE)
+ pmd_clear(pmd_off_k(addr));
+}
+
+#ifdef CONFIG_ARM_LPAE
+/* the first page is reserved for pgd */
+#define SWAPPER_PG_DIR_SIZE (PAGE_SIZE + \
+ PTRS_PER_PGD * PTRS_PER_PMD * sizeof(pmd_t))
+#else
+#define SWAPPER_PG_DIR_SIZE (PTRS_PER_PGD * sizeof(pgd_t))
+#endif
+
+/*
+ * 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), SWAPPER_PG_DIR_SIZE);
+
+#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 the device mappings. Since we clear out the page tables for all
+ * mappings above VMALLOC_START, 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(const struct machine_desc *mdesc)
+{
+ struct map_desc map;
+ unsigned long addr;
+ void *vectors;
+
+ /*
+ * Allocate the vector page early.
+ */
+ vectors = early_alloc(PAGE_SIZE * 2);
+
+ early_trap_init(vectors);
+
+ for (addr = VMALLOC_START; addr; addr += PMD_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));
+ map.virtual = 0xffff0000;
+ map.length = PAGE_SIZE;
+#ifdef CONFIG_KUSER_HELPERS
+ map.type = MT_HIGH_VECTORS;
+#else
+ map.type = MT_LOW_VECTORS;
+#endif
+ create_mapping(&map);
+
+ if (!vectors_high()) {
+ map.virtual = 0;
+ map.length = PAGE_SIZE * 2;
+ map.type = MT_LOW_VECTORS;
+ create_mapping(&map);
+ }
+
+ /* Now create a kernel read-only mapping */
+ map.pfn += 1;
+ map.virtual = 0xffff0000 + PAGE_SIZE;
+ map.length = PAGE_SIZE;
+ 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();
+ else
+ debug_ll_io_init();
+ fill_pmd_gaps();
+
+ /* Reserve fixed i/o space in VMALLOC region */
+ pci_reserve_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
+
+ early_pte_alloc(pmd_off_k(FIXADDR_START), FIXADDR_START,
+ _PAGE_KERNEL_TABLE);
+}
+
+static void __init map_lowmem(void)
+{
+ struct memblock_region *reg;
+ phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE);
+ phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
+
+ /* 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 > arm_lowmem_limit)
+ end = arm_lowmem_limit;
+ if (start >= end)
+ break;
+
+ if (end < kernel_x_start) {
+ map.pfn = __phys_to_pfn(start);
+ map.virtual = __phys_to_virt(start);
+ map.length = end - start;
+ map.type = MT_MEMORY_RWX;
+
+ create_mapping(&map);
+ } else if (start >= kernel_x_end) {
+ map.pfn = __phys_to_pfn(start);
+ map.virtual = __phys_to_virt(start);
+ map.length = end - start;
+ map.type = MT_MEMORY_RW;
+
+ create_mapping(&map);
+ } else {
+ /* This better cover the entire kernel */
+ if (start < kernel_x_start) {
+ map.pfn = __phys_to_pfn(start);
+ map.virtual = __phys_to_virt(start);
+ map.length = kernel_x_start - start;
+ map.type = MT_MEMORY_RW;
+
+ create_mapping(&map);
+ }
+
+ map.pfn = __phys_to_pfn(kernel_x_start);
+ map.virtual = __phys_to_virt(kernel_x_start);
+ map.length = kernel_x_end - kernel_x_start;
+ map.type = MT_MEMORY_RWX;
+
+ create_mapping(&map);
+
+ if (kernel_x_end < end) {
+ map.pfn = __phys_to_pfn(kernel_x_end);
+ map.virtual = __phys_to_virt(kernel_x_end);
+ map.length = end - kernel_x_end;
+ map.type = MT_MEMORY_RW;
+
+ create_mapping(&map);
+ }
+ }
+ }
+}
+
+#ifdef CONFIG_ARM_LPAE
+/*
+ * early_paging_init() recreates boot time page table setup, allowing machines
+ * to switch over to a high (>4G) address space on LPAE systems
+ */
+void __init early_paging_init(const struct machine_desc *mdesc,
+ struct proc_info_list *procinfo)
+{
+ pmdval_t pmdprot = procinfo->__cpu_mm_mmu_flags;
+ unsigned long map_start, map_end;
+ pgd_t *pgd0, *pgdk;
+ pud_t *pud0, *pudk, *pud_start;
+ pmd_t *pmd0, *pmdk;
+ phys_addr_t phys;
+ int i;
+
+ if (!(mdesc->init_meminfo))
+ return;
+
+ /* remap kernel code and data */
+ map_start = init_mm.start_code & PMD_MASK;
+ map_end = ALIGN(init_mm.brk, PMD_SIZE);
+
+ /* get a handle on things... */
+ pgd0 = pgd_offset_k(0);
+ pud_start = pud0 = pud_offset(pgd0, 0);
+ pmd0 = pmd_offset(pud0, 0);
+
+ pgdk = pgd_offset_k(map_start);
+ pudk = pud_offset(pgdk, map_start);
+ pmdk = pmd_offset(pudk, map_start);
+
+ mdesc->init_meminfo();
+
+ /* Run the patch stub to update the constants */
+ fixup_pv_table(&__pv_table_begin,
+ (&__pv_table_end - &__pv_table_begin) << 2);
+
+ /*
+ * Cache cleaning operations for self-modifying code
+ * We should clean the entries by MVA but running a
+ * for loop over every pv_table entry pointer would
+ * just complicate the code.
+ */
+ flush_cache_louis();
+ dsb(ishst);
+ isb();
+
+ /*
+ * FIXME: This code is not architecturally compliant: we modify
+ * the mappings in-place, indeed while they are in use by this
+ * very same code. This may lead to unpredictable behaviour of
+ * the CPU.
+ *
+ * Even modifying the mappings in a separate page table does
+ * not resolve this.
+ *
+ * The architecture strongly recommends that when a mapping is
+ * changed, that it is changed by first going via an invalid
+ * mapping and back to the new mapping. This is to ensure that
+ * no TLB conflicts (caused by the TLB having more than one TLB
+ * entry match a translation) can occur. However, doing that
+ * here will result in unmapping the code we are running.
+ */
+ pr_warn("WARNING: unsafe modification of in-place page tables - tainting kernel\n");
+ add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
+
+ /*
+ * Remap level 1 table. This changes the physical addresses
+ * used to refer to the level 2 page tables to the high
+ * physical address alias, leaving everything else the same.
+ */
+ for (i = 0; i < PTRS_PER_PGD; pud0++, i++) {
+ set_pud(pud0,
+ __pud(__pa(pmd0) | PMD_TYPE_TABLE | L_PGD_SWAPPER));
+ pmd0 += PTRS_PER_PMD;
+ }
+
+ /*
+ * Remap the level 2 table, pointing the mappings at the high
+ * physical address alias of these pages.
+ */
+ phys = __pa(map_start);
+ do {
+ *pmdk++ = __pmd(phys | pmdprot);
+ phys += PMD_SIZE;
+ } while (phys < map_end);
+
+ /*
+ * Ensure that the above updates are flushed out of the cache.
+ * This is not strictly correct; on a system where the caches
+ * are coherent with each other, but the MMU page table walks
+ * may not be coherent, flush_cache_all() may be a no-op, and
+ * this will fail.
+ */
+ flush_cache_all();
+
+ /*
+ * Re-write the TTBR values to point them at the high physical
+ * alias of the page tables. We expect __va() will work on
+ * cpu_get_pgd(), which returns the value of TTBR0.
+ */
+ cpu_switch_mm(pgd0, &init_mm);
+ cpu_set_ttbr(1, __pa(pgd0) + TTBR1_OFFSET);
+
+ /* Finally flush any stale TLB values. */
+ local_flush_bp_all();
+ local_flush_tlb_all();
+}
+
+#else
+
+void __init early_paging_init(const struct machine_desc *mdesc,
+ struct proc_info_list *procinfo)
+{
+ if (mdesc->init_meminfo)
+ mdesc->init_meminfo();
+}
+
+#endif
+
+/*
+ * 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(const struct machine_desc *mdesc)
+{
+ void *zero_page;
+
+ build_mem_type_table();
+ prepare_page_table();
+ map_lowmem();
+ dma_contiguous_remap();
+ devicemaps_init(mdesc);
+ kmap_init();
+ tcm_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 000000000..a014dfacd
--- /dev/null
+++ b/arch/arm/mm/nommu.c
@@ -0,0 +1,389 @@
+/*
+ * 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 <linux/kernel.h>
+
+#include <asm/cacheflush.h>
+#include <asm/sections.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/traps.h>
+#include <asm/mach/arch.h>
+#include <asm/cputype.h>
+#include <asm/mpu.h>
+#include <asm/procinfo.h>
+
+#include "mm.h"
+
+#ifdef CONFIG_ARM_MPU
+struct mpu_rgn_info mpu_rgn_info;
+
+/* Region number */
+static void rgnr_write(u32 v)
+{
+ asm("mcr p15, 0, %0, c6, c2, 0" : : "r" (v));
+}
+
+/* Data-side / unified region attributes */
+
+/* Region access control register */
+static void dracr_write(u32 v)
+{
+ asm("mcr p15, 0, %0, c6, c1, 4" : : "r" (v));
+}
+
+/* Region size register */
+static void drsr_write(u32 v)
+{
+ asm("mcr p15, 0, %0, c6, c1, 2" : : "r" (v));
+}
+
+/* Region base address register */
+static void drbar_write(u32 v)
+{
+ asm("mcr p15, 0, %0, c6, c1, 0" : : "r" (v));
+}
+
+static u32 drbar_read(void)
+{
+ u32 v;
+ asm("mrc p15, 0, %0, c6, c1, 0" : "=r" (v));
+ return v;
+}
+/* Optional instruction-side region attributes */
+
+/* I-side Region access control register */
+static void iracr_write(u32 v)
+{
+ asm("mcr p15, 0, %0, c6, c1, 5" : : "r" (v));
+}
+
+/* I-side Region size register */
+static void irsr_write(u32 v)
+{
+ asm("mcr p15, 0, %0, c6, c1, 3" : : "r" (v));
+}
+
+/* I-side Region base address register */
+static void irbar_write(u32 v)
+{
+ asm("mcr p15, 0, %0, c6, c1, 1" : : "r" (v));
+}
+
+static unsigned long irbar_read(void)
+{
+ unsigned long v;
+ asm("mrc p15, 0, %0, c6, c1, 1" : "=r" (v));
+ return v;
+}
+
+/* MPU initialisation functions */
+void __init sanity_check_meminfo_mpu(void)
+{
+ int i;
+ phys_addr_t phys_offset = PHYS_OFFSET;
+ phys_addr_t aligned_region_size, specified_mem_size, rounded_mem_size;
+ struct memblock_region *reg;
+ bool first = true;
+ phys_addr_t mem_start;
+ phys_addr_t mem_end;
+
+ for_each_memblock(memory, reg) {
+ if (first) {
+ /*
+ * Initially only use memory continuous from
+ * PHYS_OFFSET */
+ if (reg->base != phys_offset)
+ panic("First memory bank must be contiguous from PHYS_OFFSET");
+
+ mem_start = reg->base;
+ mem_end = reg->base + reg->size;
+ specified_mem_size = reg->size;
+ first = false;
+ } else {
+ /*
+ * memblock auto merges contiguous blocks, remove
+ * all blocks afterwards
+ */
+ pr_notice("Ignoring RAM after %pa, memory at %pa ignored\n",
+ &mem_start, &reg->base);
+ memblock_remove(reg->base, reg->size);
+ }
+ }
+
+ /*
+ * MPU has curious alignment requirements: Size must be power of 2, and
+ * region start must be aligned to the region size
+ */
+ if (phys_offset != 0)
+ pr_info("PHYS_OFFSET != 0 => MPU Region size constrained by alignment requirements\n");
+
+ /*
+ * Maximum aligned region might overflow phys_addr_t if phys_offset is
+ * 0. Hence we keep everything below 4G until we take the smaller of
+ * the aligned_region_size and rounded_mem_size, one of which is
+ * guaranteed to be smaller than the maximum physical address.
+ */
+ aligned_region_size = (phys_offset - 1) ^ (phys_offset);
+ /* Find the max power-of-two sized region that fits inside our bank */
+ rounded_mem_size = (1 << __fls(specified_mem_size)) - 1;
+
+ /* The actual region size is the smaller of the two */
+ aligned_region_size = aligned_region_size < rounded_mem_size
+ ? aligned_region_size + 1
+ : rounded_mem_size + 1;
+
+ if (aligned_region_size != specified_mem_size) {
+ pr_warn("Truncating memory from %pa to %pa (MPU region constraints)",
+ &specified_mem_size, &aligned_region_size);
+ memblock_remove(mem_start + aligned_region_size,
+ specified_mem_size - aligned_round_size);
+
+ mem_end = mem_start + aligned_region_size;
+ }
+
+ pr_debug("MPU Region from %pa size %pa (end %pa))\n",
+ &phys_offset, &aligned_region_size, &mem_end);
+
+}
+
+static int mpu_present(void)
+{
+ return ((read_cpuid_ext(CPUID_EXT_MMFR0) & MMFR0_PMSA) == MMFR0_PMSAv7);
+}
+
+static int mpu_max_regions(void)
+{
+ /*
+ * We don't support a different number of I/D side regions so if we
+ * have separate instruction and data memory maps then return
+ * whichever side has a smaller number of supported regions.
+ */
+ u32 dregions, iregions, mpuir;
+ mpuir = read_cpuid(CPUID_MPUIR);
+
+ dregions = iregions = (mpuir & MPUIR_DREGION_SZMASK) >> MPUIR_DREGION;
+
+ /* Check for separate d-side and i-side memory maps */
+ if (mpuir & MPUIR_nU)
+ iregions = (mpuir & MPUIR_IREGION_SZMASK) >> MPUIR_IREGION;
+
+ /* Use the smallest of the two maxima */
+ return min(dregions, iregions);
+}
+
+static int mpu_iside_independent(void)
+{
+ /* MPUIR.nU specifies whether there is *not* a unified memory map */
+ return read_cpuid(CPUID_MPUIR) & MPUIR_nU;
+}
+
+static int mpu_min_region_order(void)
+{
+ u32 drbar_result, irbar_result;
+ /* We've kept a region free for this probing */
+ rgnr_write(MPU_PROBE_REGION);
+ isb();
+ /*
+ * As per ARM ARM, write 0xFFFFFFFC to DRBAR to find the minimum
+ * region order
+ */
+ drbar_write(0xFFFFFFFC);
+ drbar_result = irbar_result = drbar_read();
+ drbar_write(0x0);
+ /* If the MPU is non-unified, we use the larger of the two minima*/
+ if (mpu_iside_independent()) {
+ irbar_write(0xFFFFFFFC);
+ irbar_result = irbar_read();
+ irbar_write(0x0);
+ }
+ isb(); /* Ensure that MPU region operations have completed */
+ /* Return whichever result is larger */
+ return __ffs(max(drbar_result, irbar_result));
+}
+
+static int mpu_setup_region(unsigned int number, phys_addr_t start,
+ unsigned int size_order, unsigned int properties)
+{
+ u32 size_data;
+
+ /* We kept a region free for probing resolution of MPU regions*/
+ if (number > mpu_max_regions() || number == MPU_PROBE_REGION)
+ return -ENOENT;
+
+ if (size_order > 32)
+ return -ENOMEM;
+
+ if (size_order < mpu_min_region_order())
+ return -ENOMEM;
+
+ /* Writing N to bits 5:1 (RSR_SZ) specifies region size 2^N+1 */
+ size_data = ((size_order - 1) << MPU_RSR_SZ) | 1 << MPU_RSR_EN;
+
+ dsb(); /* Ensure all previous data accesses occur with old mappings */
+ rgnr_write(number);
+ isb();
+ drbar_write(start);
+ dracr_write(properties);
+ isb(); /* Propagate properties before enabling region */
+ drsr_write(size_data);
+
+ /* Check for independent I-side registers */
+ if (mpu_iside_independent()) {
+ irbar_write(start);
+ iracr_write(properties);
+ isb();
+ irsr_write(size_data);
+ }
+ isb();
+
+ /* Store region info (we treat i/d side the same, so only store d) */
+ mpu_rgn_info.rgns[number].dracr = properties;
+ mpu_rgn_info.rgns[number].drbar = start;
+ mpu_rgn_info.rgns[number].drsr = size_data;
+ return 0;
+}
+
+/*
+* Set up default MPU regions, doing nothing if there is no MPU
+*/
+void __init mpu_setup(void)
+{
+ int region_err;
+ if (!mpu_present())
+ return;
+
+ region_err = mpu_setup_region(MPU_RAM_REGION, PHYS_OFFSET,
+ ilog2(meminfo.bank[0].size),
+ MPU_AP_PL1RW_PL0RW | MPU_RGN_NORMAL);
+ if (region_err) {
+ panic("MPU region initialization failure! %d", region_err);
+ } else {
+ pr_info("Using ARMv7 PMSA Compliant MPU. "
+ "Region independence: %s, Max regions: %d\n",
+ mpu_iside_independent() ? "Yes" : "No",
+ mpu_max_regions());
+ }
+}
+#else
+static void sanity_check_meminfo_mpu(void) {}
+static void __init mpu_setup(void) {}
+#endif /* CONFIG_ARM_MPU */
+
+void __init arm_mm_memblock_reserve(void)
+{
+#ifndef CONFIG_CPU_V7M
+ /*
+ * 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);
+#else /* ifndef CONFIG_CPU_V7M */
+ /*
+ * There is no dedicated vector page on V7-M. So nothing needs to be
+ * reserved here.
+ */
+#endif
+}
+
+void __init sanity_check_meminfo(void)
+{
+ phys_addr_t end;
+ sanity_check_meminfo_mpu();
+ end = memblock_end_of_DRAM();
+ high_memory = __va(end - 1) + 1;
+ memblock_set_current_limit(end);
+}
+
+/*
+ * early_paging_init() recreates boot time page table setup, allowing machines
+ * to switch over to a high (>4G) address space on LPAE systems
+ */
+void __init early_paging_init(const struct machine_desc *mdesc,
+ struct proc_info_list *procinfo)
+{
+}
+
+/*
+ * 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(const struct machine_desc *mdesc)
+{
+ early_trap_init((void *)CONFIG_VECTORS_BASE);
+ mpu_setup();
+ bootmem_init();
+}
+
+/*
+ * We don't need to do anything here for nommu machines.
+ */
+void setup_mm_for_reboot(void)
+{
+}
+
+void flush_dcache_page(struct page *page)
+{
+ __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
+}
+EXPORT_SYMBOL(flush_dcache_page);
+
+void flush_kernel_dcache_page(struct page *page)
+{
+ __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
+}
+EXPORT_SYMBOL(flush_kernel_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(phys_addr_t phys_addr, size_t size,
+ unsigned int mtype)
+{
+ return (void __iomem *)phys_addr;
+}
+EXPORT_SYMBOL(__arm_ioremap);
+
+void __iomem * (*arch_ioremap_caller)(phys_addr_t, size_t, unsigned int, void *);
+
+void __iomem *__arm_ioremap_caller(phys_addr_t phys_addr, size_t size,
+ unsigned int mtype, void *caller)
+{
+ return __arm_ioremap(phys_addr, size, mtype);
+}
+
+void (*arch_iounmap)(volatile void __iomem *);
+
+void __arm_iounmap(volatile void __iomem *addr)
+{
+}
+EXPORT_SYMBOL(__arm_iounmap);
diff --git a/arch/arm/mm/pabort-legacy.S b/arch/arm/mm/pabort-legacy.S
new file mode 100644
index 000000000..8bbff0252
--- /dev/null
+++ b/arch/arm/mm/pabort-legacy.S
@@ -0,0 +1,21 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Function: legacy_pabort
+ *
+ * Params : r2 = pt_regs
+ * : r4 = address of aborted instruction
+ * : r5 = psr for parent context
+ *
+ * Returns : r4 - r11, r13 preserved
+ *
+ * Purpose : obtain information about current prefetch abort.
+ */
+
+ .align 5
+ENTRY(legacy_pabort)
+ mov r0, r4
+ mov r1, #5
+ b do_PrefetchAbort
+ENDPROC(legacy_pabort)
diff --git a/arch/arm/mm/pabort-v6.S b/arch/arm/mm/pabort-v6.S
new file mode 100644
index 000000000..9627646ce
--- /dev/null
+++ b/arch/arm/mm/pabort-v6.S
@@ -0,0 +1,21 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Function: v6_pabort
+ *
+ * Params : r2 = pt_regs
+ * : r4 = address of aborted instruction
+ * : r5 = psr for parent context
+ *
+ * Returns : r4 - r11, r13 preserved
+ *
+ * Purpose : obtain information about current prefetch abort.
+ */
+
+ .align 5
+ENTRY(v6_pabort)
+ mov r0, r4
+ mrc p15, 0, r1, c5, c0, 1 @ get IFSR
+ b do_PrefetchAbort
+ENDPROC(v6_pabort)
diff --git a/arch/arm/mm/pabort-v7.S b/arch/arm/mm/pabort-v7.S
new file mode 100644
index 000000000..875761f44
--- /dev/null
+++ b/arch/arm/mm/pabort-v7.S
@@ -0,0 +1,21 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Function: v7_pabort
+ *
+ * Params : r2 = pt_regs
+ * : r4 = address of aborted instruction
+ * : r5 = psr for parent context
+ *
+ * Returns : r4 - r11, r13 preserved
+ *
+ * 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
+ b do_PrefetchAbort
+ENDPROC(v7_pabort)
diff --git a/arch/arm/mm/pageattr.c b/arch/arm/mm/pageattr.c
new file mode 100644
index 000000000..cf30daff8
--- /dev/null
+++ b/arch/arm/mm/pageattr.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/mm.h>
+#include <linux/module.h>
+
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+struct page_change_data {
+ pgprot_t set_mask;
+ pgprot_t clear_mask;
+};
+
+static int change_page_range(pte_t *ptep, pgtable_t token, unsigned long addr,
+ void *data)
+{
+ struct page_change_data *cdata = data;
+ pte_t pte = *ptep;
+
+ pte = clear_pte_bit(pte, cdata->clear_mask);
+ pte = set_pte_bit(pte, cdata->set_mask);
+
+ set_pte_ext(ptep, pte, 0);
+ return 0;
+}
+
+static int change_memory_common(unsigned long addr, int numpages,
+ pgprot_t set_mask, pgprot_t clear_mask)
+{
+ unsigned long start = addr;
+ unsigned long size = PAGE_SIZE*numpages;
+ unsigned long end = start + size;
+ int ret;
+ struct page_change_data data;
+
+ if (!IS_ALIGNED(addr, PAGE_SIZE)) {
+ start &= PAGE_MASK;
+ end = start + size;
+ WARN_ON_ONCE(1);
+ }
+
+ if (start < MODULES_VADDR || start >= MODULES_END)
+ return -EINVAL;
+
+ if (end < MODULES_VADDR || start >= MODULES_END)
+ return -EINVAL;
+
+ data.set_mask = set_mask;
+ data.clear_mask = clear_mask;
+
+ ret = apply_to_page_range(&init_mm, start, size, change_page_range,
+ &data);
+
+ flush_tlb_kernel_range(start, end);
+ return ret;
+}
+
+int set_memory_ro(unsigned long addr, int numpages)
+{
+ return change_memory_common(addr, numpages,
+ __pgprot(L_PTE_RDONLY),
+ __pgprot(0));
+}
+
+int set_memory_rw(unsigned long addr, int numpages)
+{
+ return change_memory_common(addr, numpages,
+ __pgprot(0),
+ __pgprot(L_PTE_RDONLY));
+}
+
+int set_memory_nx(unsigned long addr, int numpages)
+{
+ return change_memory_common(addr, numpages,
+ __pgprot(L_PTE_XN),
+ __pgprot(0));
+}
+
+int set_memory_x(unsigned long addr, int numpages)
+{
+ return change_memory_common(addr, numpages,
+ __pgprot(0),
+ __pgprot(L_PTE_XN));
+}
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
new file mode 100644
index 000000000..a3681f11d
--- /dev/null
+++ b/arch/arm/mm/pgd.c
@@ -0,0 +1,164 @@
+/*
+ * 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 <linux/slab.h>
+
+#include <asm/cp15.h>
+#include <asm/pgalloc.h>
+#include <asm/page.h>
+#include <asm/tlbflush.h>
+
+#include "mm.h"
+
+#ifdef CONFIG_ARM_LPAE
+#define __pgd_alloc() kmalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL)
+#define __pgd_free(pgd) kfree(pgd)
+#else
+#define __pgd_alloc() (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_REPEAT, 2)
+#define __pgd_free(pgd) free_pages((unsigned long)pgd, 2)
+#endif
+
+/*
+ * 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_alloc();
+ 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));
+
+#ifdef CONFIG_ARM_LPAE
+ /*
+ * Allocate PMD table for modules and pkmap mappings.
+ */
+ new_pud = pud_alloc(mm, new_pgd + pgd_index(MODULES_VADDR),
+ MODULES_VADDR);
+ if (!new_pud)
+ goto no_pud;
+
+ new_pmd = pmd_alloc(mm, new_pud, 0);
+ if (!new_pmd)
+ goto no_pmd;
+#endif
+
+ if (!vectors_high()) {
+ /*
+ * On ARM, first page must always be allocated since it
+ * contains the machine vectors. The vectors are always high
+ * with LPAE.
+ */
+ 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 + 0, init_pte[0], 0);
+ set_pte_ext(new_pte + 1, init_pte[1], 0);
+ pte_unmap(init_pte);
+ pte_unmap(new_pte);
+ }
+
+ return new_pgd;
+
+no_pte:
+ pmd_free(mm, new_pmd);
+ mm_dec_nr_pmds(mm);
+no_pmd:
+ pud_free(mm, new_pud);
+no_pud:
+ __pgd_free(new_pgd);
+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);
+ atomic_long_dec(&mm->nr_ptes);
+no_pmd:
+ pud_clear(pud);
+ pmd_free(mm, pmd);
+ mm_dec_nr_pmds(mm);
+no_pud:
+ pgd_clear(pgd);
+ pud_free(mm, pud);
+no_pgd:
+#ifdef CONFIG_ARM_LPAE
+ /*
+ * Free modules/pkmap or identity pmd tables.
+ */
+ for (pgd = pgd_base; pgd < pgd_base + PTRS_PER_PGD; pgd++) {
+ if (pgd_none_or_clear_bad(pgd))
+ continue;
+ if (pgd_val(*pgd) & L_PGD_SWAPPER)
+ continue;
+ pud = pud_offset(pgd, 0);
+ if (pud_none_or_clear_bad(pud))
+ continue;
+ pmd = pmd_offset(pud, 0);
+ pud_clear(pud);
+ pmd_free(mm, pmd);
+ mm_dec_nr_pmds(mm);
+ pgd_clear(pgd);
+ pud_free(mm, pud);
+ }
+#endif
+ __pgd_free(pgd_base);
+}
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
new file mode 100644
index 000000000..774ef1323
--- /dev/null
+++ b/arch/arm/mm/proc-arm1020.S
@@ -0,0 +1,529 @@
+/*
+ * 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.
+ */
+#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)
+ ret 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
+ ret 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
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_arm1020_reset)
+ .popsection
+
+/*
+ * cpu_arm1020_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm1020_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ ret 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
+ ret 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
+ ret 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
+ ret 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 r0, #0
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(arm1020_dma_unmap_area)
+
+ .globl arm1020_flush_kern_cache_louis
+ .equ arm1020_flush_kern_cache_louis, arm1020_flush_kern_cache_all
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm1020
+
+ .align 5
+ENTRY(cpu_arm1020_dcache_clean_area)
+#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
+ ret 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 */
+ ret 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 */
+ ret lr
+
+ .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
+ ret 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
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm1020, dabort=v4t_early_abort, pabort=legacy_pabort
+
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv5t"
+ string cpu_elf_name, "v5"
+
+ .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
+
+ .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
+ initfn __arm1020_setup, __arm1020_proc_info
+ .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 000000000..ae3c27b71
--- /dev/null
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -0,0 +1,489 @@
+/*
+ * 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.
+ */
+#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)
+ ret 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
+ ret 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
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_arm1020e_reset)
+ .popsection
+
+/*
+ * cpu_arm1020e_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm1020e_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ ret 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
+ ret 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
+ ret 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
+ ret 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 r0, #0
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(arm1020e_dma_unmap_area)
+
+ .globl arm1020e_flush_kern_cache_louis
+ .equ arm1020e_flush_kern_cache_louis, arm1020e_flush_kern_cache_all
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm1020e
+
+ .align 5
+ENTRY(cpu_arm1020e_dcache_clean_area)
+#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
+ ret 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
+ ret 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 */
+ ret lr
+
+ .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
+ ret 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
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm1020e, dabort=v4t_early_abort, pabort=legacy_pabort
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+ string cpu_arm1020e_name, "ARM1020E"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+
+ .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
+ initfn __arm1020e_setup, __arm1020e_proc_info
+ .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 000000000..dbb2413fe
--- /dev/null
+++ b/arch/arm/mm/proc-arm1022.S
@@ -0,0 +1,474 @@
+/*
+ * 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)
+ ret 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
+ ret 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
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_arm1022_reset)
+ .popsection
+
+/*
+ * cpu_arm1022_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm1022_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ ret 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
+ ret 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
+ ret 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
+ ret 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 r0, #0
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(arm1022_dma_unmap_area)
+
+ .globl arm1022_flush_kern_cache_louis
+ .equ arm1022_flush_kern_cache_louis, arm1022_flush_kern_cache_all
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm1022
+
+ .align 5
+ENTRY(cpu_arm1022_dcache_clean_area)
+#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
+ ret 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
+ ret 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 */
+ ret lr
+
+ .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
+ ret 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
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm1022, dabort=v4t_early_abort, pabort=legacy_pabort
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+ string cpu_arm1022_name, "ARM1022"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+
+ .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
+ initfn __arm1022_setup, __arm1022_proc_info
+ .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 000000000..0b37b2cef
--- /dev/null
+++ b/arch/arm/mm/proc-arm1026.S
@@ -0,0 +1,468 @@
+/*
+ * 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)
+ ret 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
+ ret 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
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_arm1026_reset)
+ .popsection
+
+/*
+ * cpu_arm1026_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm1026_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ ret 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
+ ret 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
+ ret 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
+ ret 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 r0, #0
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(arm1026_dma_unmap_area)
+
+ .globl arm1026_flush_kern_cache_louis
+ .equ arm1026_flush_kern_cache_louis, arm1026_flush_kern_cache_all
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm1026
+
+ .align 5
+ENTRY(cpu_arm1026_dcache_clean_area)
+#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
+ ret 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
+ ret 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 */
+ ret lr
+
+ .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
+ ret 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
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm1026, dabort=v5t_early_abort, pabort=legacy_pabort
+
+ .section .rodata
+
+ string cpu_arch_name, "armv5tej"
+ string cpu_elf_name, "v5"
+ .align
+ string cpu_arm1026_name, "ARM1026EJ-S"
+ .align
+
+ .section ".proc.info.init", #alloc
+
+ .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
+ initfn __arm1026_setup, __arm1026_proc_info
+ .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-arm720.S b/arch/arm/mm/proc-arm720.S
new file mode 100644
index 000000000..3651cd70e
--- /dev/null
+++ b/arch/arm/mm/proc-arm720.S
@@ -0,0 +1,219 @@
+/*
+ * 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)
+ ret 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
+ ret lr
+
+/*
+ * Function: arm720_proc_do_idle(void)
+ * Params : r0 = unused
+ * Purpose : put the processor in proper idle mode
+ */
+ENTRY(cpu_arm720_do_idle)
+ ret 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
+ ret 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
+ ret lr
+
+/*
+ * Function: arm720_reset
+ * Params : r0 = address to jump to
+ * Notes : This sets up everything for a reset
+ */
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_arm720_reset)
+ .popsection
+
+ .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
+ ret 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
+ ret 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
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm720, dabort=v4t_late_abort, pabort=legacy_pabort
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm710_name, "ARM710T"
+ string cpu_arm720_name, "ARM720T"
+
+ .align
+
+/*
+ * See <asm/procinfo.h> for a definition of this structure.
+ */
+
+ .section ".proc.info.init", #alloc
+
+.macro arm720_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cpu_flush:req
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
+ .long PMD_TYPE_SECT | \
+ PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | \
+ PMD_BIT4 | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ .long PMD_TYPE_SECT | \
+ PMD_BIT4 | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ initfn \cpu_flush, __\name\()_proc_info @ 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_name
+ .long arm720_processor_functions
+ .long v4_tlb_fns
+ .long v4wt_user_fns
+ .long v4_cache_fns
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
+
+ arm720_proc_info arm710, 0x41807100, 0xffffff00, cpu_arm710_name, __arm710_setup
+ arm720_proc_info arm720, 0x41807200, 0xffffff00, cpu_arm720_name, __arm720_setup
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
new file mode 100644
index 000000000..024fb7732
--- /dev/null
+++ b/arch/arm/mm/proc-arm740.S
@@ -0,0 +1,151 @@
+/*
+ * 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>
+
+#include "proc-macros.S"
+
+ .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)
+ ret 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
+ ret lr
+
+/*
+ * cpu_arm740_reset(loc)
+ * Params : r0 = address to jump to
+ * Notes : This sets up everything for a reset
+ */
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_arm740_reset)
+ .popsection
+
+ .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 r3, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB)
+ mov r4, #10 @ 11 is the minimum (4KB)
+1: add r4, r4, #1 @ area size *= 2
+ movs r3, r3, lsr #1
+ bne 1b @ count not zero r-shift
+ orr r0, r0, r4, 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 r3, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB)
+ cmp r3, #0
+ moveq r0, #0
+ beq 2f
+ mov r4, #10 @ 11 is the minimum (4KB)
+1: add r4, r4, #1 @ area size *= 2
+ movs r3, r3, lsr #1
+ bne 1b @ count not zero r-shift
+ orr r0, r0, r4, lsl #1 @ the area register value
+ orr r0, r0, #1 @ set enable bit
+2: 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
+
+ ret lr
+
+ .size __arm740_setup, . - __arm740_setup
+
+ __INITDATA
+
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm740, dabort=v4t_late_abort, pabort=legacy_pabort, nommu=1
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv4"
+ string cpu_elf_name, "v4"
+ string cpu_arm740_name, "ARM740T"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+ .type __arm740_proc_info,#object
+__arm740_proc_info:
+ .long 0x41807400
+ .long 0xfffffff0
+ .long 0
+ .long 0
+ initfn __arm740_setup, __arm740_proc_info
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_26BIT
+ .long cpu_arm740_name
+ .long arm740_processor_functions
+ .long 0
+ .long 0
+ .long v4_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 000000000..25472d944
--- /dev/null
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -0,0 +1,114 @@
+/*
+ * 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>
+
+#include "proc-macros.S"
+
+ .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)
+ ret lr
+
+/*
+ * cpu_arm7tdmi_proc_fin()
+ */
+ENTRY(cpu_arm7tdmi_proc_fin)
+ ret 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.
+ */
+ .pushsection .idmap.text, "ax"
+ENTRY(cpu_arm7tdmi_reset)
+ ret r0
+ENDPROC(cpu_arm7tdmi_reset)
+ .popsection
+
+ .type __arm7tdmi_setup, #function
+__arm7tdmi_setup:
+ ret lr
+ .size __arm7tdmi_setup, . - __arm7tdmi_setup
+
+ __INITDATA
+
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm7tdmi, dabort=v4t_late_abort, pabort=legacy_pabort, nommu=1
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm7tdmi_name, "ARM7TDMI"
+ string cpu_triscenda7_name, "Triscend-A7x"
+ string cpu_at91_name, "Atmel-AT91M40xxx"
+ string cpu_s3c3410_name, "Samsung-S3C3410"
+ string cpu_s3c44b0x_name, "Samsung-S3C44B0x"
+ string cpu_s3c4510b_name, "Samsung-S3C4510B"
+ string cpu_s3c4530_name, "Samsung-S3C4530"
+ string cpu_netarm_name, "NETARM"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+
+.macro arm7tdmi_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, \
+ extra_hwcaps=0
+ .type __\name\()_proc_info, #object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
+ .long 0
+ .long 0
+ initfn __arm7tdmi_setup, __\name\()_proc_info
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_26BIT | ( \extra_hwcaps )
+ .long \cpu_name
+ .long arm7tdmi_processor_functions
+ .long 0
+ .long 0
+ .long v4_cache_fns
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
+
+ arm7tdmi_proc_info arm7tdmi, 0x41007700, 0xfff8ff00, \
+ cpu_arm7tdmi_name
+ arm7tdmi_proc_info triscenda7, 0x0001d2ff, 0x0001ffff, \
+ cpu_triscenda7_name, extra_hwcaps=HWCAP_THUMB
+ arm7tdmi_proc_info at91, 0x14000040, 0xfff000e0, \
+ cpu_at91_name, extra_hwcaps=HWCAP_THUMB
+ arm7tdmi_proc_info s3c4510b, 0x36365000, 0xfffff000, \
+ cpu_s3c4510b_name, extra_hwcaps=HWCAP_THUMB
+ arm7tdmi_proc_info s3c4530, 0x4c000000, 0xfff000e0, \
+ cpu_s3c4530_name, extra_hwcaps=HWCAP_THUMB
+ arm7tdmi_proc_info s3c3410, 0x34100000, 0xffff0000, \
+ cpu_s3c3410_name, extra_hwcaps=HWCAP_THUMB
+ arm7tdmi_proc_info s3c44b0x, 0x44b00000, 0xffff0000, \
+ cpu_s3c44b0x_name, extra_hwcaps=HWCAP_THUMB
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
new file mode 100644
index 000000000..7a14bd441
--- /dev/null
+++ b/arch/arm/mm/proc-arm920.S
@@ -0,0 +1,480 @@
+/*
+ * 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)
+ ret 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
+ ret 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
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_arm920_reset)
+ .popsection
+
+/*
+ * cpu_arm920_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm920_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ ret 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
+ ret 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
+ ret 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
+ ret 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 r0, #0
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(arm920_dma_unmap_area)
+
+ .globl arm920_flush_kern_cache_louis
+ .equ arm920_flush_kern_cache_louis, arm920_flush_kern_cache_all
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm920
+#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
+ ret 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
+ ret 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
+ ret 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_ARM_CPU_SUSPEND
+ENTRY(cpu_arm920_do_suspend)
+ stmfd sp!, {r4 - r6, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r6}
+ ldmfd sp!, {r4 - r6, 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 - r6}
+ mcr p15, 0, r4, c13, c0, 0 @ PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r1, c2, c0, 0 @ TTB address
+ mov r0, r6 @ control register
+ b cpu_resume_mmu
+ENDPROC(cpu_arm920_do_resume)
+#endif
+
+ .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
+ ret 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
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm920, dabort=v4t_early_abort, pabort=legacy_pabort, suspend=1
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm920_name, "ARM920T"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+
+ .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
+ initfn __arm920_setup, __arm920_proc_info
+ .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 000000000..edccfcdcd
--- /dev/null
+++ b/arch/arm/mm/proc-arm922.S
@@ -0,0 +1,458 @@
+/*
+ * 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)
+ ret 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
+ ret 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
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_arm922_reset)
+ .popsection
+
+/*
+ * cpu_arm922_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm922_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ ret 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
+ ret 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
+ ret 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
+ ret 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 r0, #0
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(arm922_dma_unmap_area)
+
+ .globl arm922_flush_kern_cache_louis
+ .equ arm922_flush_kern_cache_louis, arm922_flush_kern_cache_all
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm922
+#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
+ ret 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
+ ret 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 */
+ ret lr
+
+ .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
+ ret 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
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm922, dabort=v4t_early_abort, pabort=legacy_pabort
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm922_name, "ARM922T"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+
+ .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
+ initfn __arm922_setup, __arm922_proc_info
+ .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 000000000..32a47cc19
--- /dev/null
+++ b/arch/arm/mm/proc-arm925.S
@@ -0,0 +1,523 @@
+/*
+ * 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)
+ ret 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
+ ret 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
+ .pushsection .idmap.text, "ax"
+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]
+ENDPROC(cpu_arm925_reset)
+ .popsection
+
+ 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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 r0, #0
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(arm925_dma_unmap_area)
+
+ .globl arm925_flush_kern_cache_louis
+ .equ arm925_flush_kern_cache_louis, arm925_flush_kern_cache_all
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm925
+
+ENTRY(cpu_arm925_dcache_clean_area)
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+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
+ ret 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
+ ret 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 */
+ ret lr
+
+ .type __arm925_setup, #function
+__arm925_setup:
+ mov r0, #0
+
+ /* 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
+ ret 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
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm925, dabort=v4t_early_abort, pabort=legacy_pabort
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm925_name, "ARM925T"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+
+.macro arm925_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
+ .long PMD_TYPE_SECT | \
+ PMD_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
+ initfn __arm925_setup, __\name\()_proc_info
+ .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 __\name\()_proc_info, . - __\name\()_proc_info
+.endm
+
+ arm925_proc_info arm925, 0x54029250, 0xfffffff0, cpu_arm925_name
+ arm925_proc_info arm915, 0x54029150, 0xfffffff0, cpu_arm925_name
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
new file mode 100644
index 000000000..fb827c633
--- /dev/null
+++ b/arch/arm/mm/proc-arm926.S
@@ -0,0 +1,502 @@
+/*
+ * 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)
+ ret 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
+ ret 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
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_arm926_reset)
+ .popsection
+
+/*
+ * 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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 r0, #0
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(arm926_dma_unmap_area)
+
+ .globl arm926_flush_kern_cache_louis
+ .equ arm926_flush_kern_cache_louis, arm926_flush_kern_cache_all
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm926
+
+ENTRY(cpu_arm926_dcache_clean_area)
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+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
+ ret 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
+ ret 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
+ ret 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_ARM_CPU_SUSPEND
+ENTRY(cpu_arm926_do_suspend)
+ stmfd sp!, {r4 - r6, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r6}
+ ldmfd sp!, {r4 - r6, 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 - r6}
+ mcr p15, 0, r4, c13, c0, 0 @ PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r1, c2, c0, 0 @ TTB address
+ mov r0, r6 @ control register
+ b cpu_resume_mmu
+ENDPROC(cpu_arm926_do_resume)
+#endif
+
+ .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
+ ret 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
+
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm926, dabort=v5tj_early_abort, pabort=legacy_pabort, suspend=1
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv5tej"
+ string cpu_elf_name, "v5"
+ string cpu_arm926_name, "ARM926EJ-S"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+
+ .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
+ initfn __arm926_setup, __arm926_proc_info
+ .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 000000000..ee5b66f84
--- /dev/null
+++ b/arch/arm/mm/proc-arm940.S
@@ -0,0 +1,364 @@
+/*
+ * 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)
+ ret 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
+ ret lr
+
+/*
+ * cpu_arm940_reset(loc)
+ * Params : r0 = address to jump to
+ * Notes : This sets up everything for a reset
+ */
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_arm940_reset)
+ .popsection
+
+/*
+ * cpu_arm940_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm940_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ ret 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
+ ret 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
+ ret 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 r0, #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, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ ret 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
+ ret 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
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(arm940_dma_unmap_area)
+
+ .globl arm940_flush_kern_cache_louis
+ .equ arm940_flush_kern_cache_louis, arm940_flush_kern_cache_all
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm940
+
+ .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 r7, =CONFIG_DRAM_SIZE >> 12 @ size of RAM (must be >= 4KB)
+ pr_val r3, r0, r7, #1
+ mcr p15, 0, r3, c6, c1, 0 @ set area 1, RAM
+ mcr p15, 0, r3, c6, c1, 1
+
+ ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH
+ ldr r7, =CONFIG_FLASH_SIZE @ size of FLASH (must be >= 4KB)
+ pr_val r3, r0, r6, #1
+ mcr p15, 0, r3, c6, c2, 0 @ set area 2, ROM/FLASH
+ mcr p15, 0, r3, 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
+
+ ret lr
+
+ .size __arm940_setup, . - __arm940_setup
+
+ __INITDATA
+
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm940, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm940_name, "ARM940T"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+
+ .type __arm940_proc_info,#object
+__arm940_proc_info:
+ .long 0x41009400
+ .long 0xff00fff0
+ .long 0
+ initfn __arm940_setup, __arm940_proc_info
+ .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 000000000..7361837ed
--- /dev/null
+++ b/arch/arm/mm/proc-arm946.S
@@ -0,0 +1,419 @@
+/*
+ * 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)
+ ret 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
+ ret lr
+
+/*
+ * cpu_arm946_reset(loc)
+ * Params : r0 = address to jump to
+ * Notes : This sets up everything for a reset
+ */
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_arm946_reset)
+ .popsection
+
+/*
+ * cpu_arm946_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm946_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ ret 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
+ ret 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
+ ret 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
+ ret 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 r0, #0
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(arm946_dma_unmap_area)
+
+ .globl arm946_flush_kern_cache_louis
+ .equ arm946_flush_kern_cache_louis, arm946_flush_kern_cache_all
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm946
+
+ENTRY(cpu_arm946_dcache_clean_area)
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+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
+ ret lr
+
+ .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 r7, =CONFIG_DRAM_SIZE @ size of RAM (must be >= 4KB)
+ pr_val r3, r0, r7, #1
+ mcr p15, 0, r3, c6, c1, 0
+
+ ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH
+ ldr r7, =CONFIG_FLASH_SIZE @ size of FLASH (must be >= 4KB)
+ pr_val r3, r0, r7, #1
+ mcr p15, 0, r3, c6, c2, 0
+
+ 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
+ ret lr
+
+ .size __arm946_setup, . - __arm946_setup
+
+ __INITDATA
+
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm946, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5t"
+ string cpu_arm946_name, "ARM946E-S"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+ .type __arm946_proc_info,#object
+__arm946_proc_info:
+ .long 0x41009460
+ .long 0xff00fff0
+ .long 0
+ .long 0
+ initfn __arm946_setup, __arm946_proc_info
+ .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 arm946_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 000000000..7fac8c612
--- /dev/null
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -0,0 +1,95 @@
+/*
+ * 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>
+
+#include "proc-macros.S"
+
+ .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)
+ ret lr
+
+/*
+ * cpu_arm9tdmi_proc_fin()
+ */
+ENTRY(cpu_arm9tdmi_proc_fin)
+ ret 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.
+ */
+ .pushsection .idmap.text, "ax"
+ENTRY(cpu_arm9tdmi_reset)
+ ret r0
+ENDPROC(cpu_arm9tdmi_reset)
+ .popsection
+
+ .type __arm9tdmi_setup, #function
+__arm9tdmi_setup:
+ ret lr
+ .size __arm9tdmi_setup, . - __arm9tdmi_setup
+
+ __INITDATA
+
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm9tdmi, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm9tdmi_name, "ARM9TDMI"
+ string cpu_p2001_name, "P2001"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+
+.macro arm9tdmi_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req
+ .type __\name\()_proc_info, #object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
+ .long 0
+ .long 0
+ initfn __arm9tdmi_setup, __\name\()_proc_info
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
+ .long \cpu_name
+ .long arm9tdmi_processor_functions
+ .long 0
+ .long 0
+ .long v4_cache_fns
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
+
+ arm9tdmi_proc_info arm9tdmi, 0x41009900, 0xfff8ff00, cpu_arm9tdmi_name
+ arm9tdmi_proc_info p2001, 0x41029000, 0xffffffff, cpu_p2001_name
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
new file mode 100644
index 000000000..4001b73af
--- /dev/null
+++ b/arch/arm/mm/proc-fa526.S
@@ -0,0 +1,218 @@
+/*
+ * 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 "proc-macros.S"
+
+#define CACHE_DLINESIZE 16
+
+ .text
+/*
+ * cpu_fa526_proc_init()
+ */
+ENTRY(cpu_fa526_proc_init)
+ ret 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
+ ret 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
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_fa526_reset)
+ .popsection
+
+/*
+ * cpu_fa526_do_idle()
+ */
+ .align 4
+ENTRY(cpu_fa526_do_idle)
+ ret 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
+ ret 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
+ ret 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
+ ret lr
+
+ .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
+ ret 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
+
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions fa526, dabort=v4_early_abort, pabort=legacy_pabort
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv4"
+ string cpu_elf_name, "v4"
+ string cpu_fa526_name, "FA526"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+
+ .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
+ initfn __fa526_setup, __fa526_proc_info
+ .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 000000000..92e08bf37
--- /dev/null
+++ b/arch/arm/mm/proc-feroceon.S
@@ -0,0 +1,626 @@
+/*
+ * 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}
+ ret 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
+ ret 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
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_feroceon_reset)
+ .popsection
+
+/*
+ * 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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 r0, #0
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(feroceon_dma_unmap_area)
+
+ .globl feroceon_flush_kern_cache_louis
+ .equ feroceon_flush_kern_cache_louis, feroceon_flush_kern_cache_all
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions feroceon
+
+.macro range_alias basename
+ .globl feroceon_range_\basename
+ .type feroceon_range_\basename , %function
+ .equ feroceon_range_\basename , feroceon_\basename
+.endm
+
+/*
+ * Most of the cache functions are unchanged for this case.
+ * Export suitable alias symbols for the unchanged functions:
+ */
+ range_alias flush_icache_all
+ range_alias flush_user_cache_all
+ range_alias flush_kern_cache_all
+ range_alias flush_kern_cache_louis
+ range_alias flush_user_cache_range
+ range_alias coherent_kern_range
+ range_alias coherent_user_range
+ range_alias dma_unmap_area
+
+ define_cache_functions feroceon_range
+
+ .align 5
+ENTRY(cpu_feroceon_dcache_clean_area)
+#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
+ ret 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
+ ret r2
+#else
+ ret 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
+ ret lr
+
+/* Suspend/resume support: taken from arch/arm/mm/proc-arm926.S */
+.globl cpu_feroceon_suspend_size
+.equ cpu_feroceon_suspend_size, 4 * 3
+#ifdef CONFIG_ARM_CPU_SUSPEND
+ENTRY(cpu_feroceon_do_suspend)
+ stmfd sp!, {r4 - r6, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r6}
+ ldmfd sp!, {r4 - r6, pc}
+ENDPROC(cpu_feroceon_do_suspend)
+
+ENTRY(cpu_feroceon_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 - r6}
+ mcr p15, 0, r4, c13, c0, 0 @ PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r1, c2, c0, 0 @ TTB address
+ mov r0, r6 @ control register
+ b cpu_resume_mmu
+ENDPROC(cpu_feroceon_do_resume)
+#endif
+
+ .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
+ ret 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
+
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions feroceon, dabort=v5t_early_abort, pabort=legacy_pabort
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+ string cpu_feroceon_name, "Feroceon"
+ string cpu_88fr531_name, "Feroceon 88FR531-vd"
+ string cpu_88fr571_name, "Feroceon 88FR571-vd"
+ string cpu_88fr131_name, "Feroceon 88FR131"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+
+.macro feroceon_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache:req
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
+ .long PMD_TYPE_SECT | \
+ PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | \
+ PMD_BIT4 | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ .long PMD_TYPE_SECT | \
+ PMD_BIT4 | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ initfn __feroceon_setup, __\name\()_proc_info
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+ .long \cpu_name
+ .long feroceon_processor_functions
+ .long v4wbi_tlb_fns
+ .long feroceon_user_fns
+ .long \cache
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
+
+#ifdef CONFIG_CPU_FEROCEON_OLD_ID
+ feroceon_proc_info feroceon_old_id, 0x41009260, 0xff00fff0, \
+ cpu_name=cpu_feroceon_name, cache=feroceon_cache_fns
+#endif
+
+ feroceon_proc_info 88fr531, 0x56055310, 0xfffffff0, cpu_88fr531_name, \
+ cache=feroceon_cache_fns
+ feroceon_proc_info 88fr571, 0x56155710, 0xfffffff0, cpu_88fr571_name, \
+ cache=feroceon_range_cache_fns
+ feroceon_proc_info 88fr131, 0x56251310, 0xfffffff0, cpu_88fr131_name, \
+ cache=feroceon_range_cache_fns
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
new file mode 100644
index 000000000..c671f3452
--- /dev/null
+++ b/arch/arm/mm/proc-macros.S
@@ -0,0 +1,361 @@
+/*
+ * 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)
+ * note, this field is 64bit, so in big-endian the two words are swapped too.
+ */
+ .macro mmid, rd, rn
+#ifdef __ARMEB__
+ ldr \rd, [\rn, #MM_CONTEXT_ID + 4 ]
+#else
+ ldr \rd, [\rn, #MM_CONTEXT_ID]
+#endif
+ .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 !defined (CONFIG_ARM_LPAE) && \
+ (L_PTE_XN+L_PTE_USER+L_PTE_RDONLY+L_PTE_DIRTY+L_PTE_YOUNG+\
+ 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 1 1 1 r/o r/o
+ * 11x0 1 1 1 r/o r/o
+ * 1111 0 1 1 r/w r/w
+ */
+ .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 PTE_CACHEABLE | PTE_BUFFERABLE | PTE_EXT_APX @ L_PTE_MT_VECTORS
+ .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
+ tstne r3, #PTE_EXT_APX
+
+ @ user read-only -> kernel read-only
+ bicne r3, r3, #PTE_EXT_AP0
+
+ tst r1, #L_PTE_XN
+ orrne r3, r3, #PTE_EXT_XN
+
+ eor r3, r3, r2
+
+ tst r1, #L_PTE_YOUNG
+ tstne r1, #L_PTE_PRESENT
+ moveq r3, #0
+ tstne r1, #L_PTE_NONE
+ movne 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
+
+.macro define_processor_functions name:req, dabort:req, pabort:req, nommu=0, suspend=0
+ .type \name\()_processor_functions, #object
+ .align 2
+ENTRY(\name\()_processor_functions)
+ .word \dabort
+ .word \pabort
+ .word cpu_\name\()_proc_init
+ .word cpu_\name\()_proc_fin
+ .word cpu_\name\()_reset
+ .word cpu_\name\()_do_idle
+ .word cpu_\name\()_dcache_clean_area
+ .word cpu_\name\()_switch_mm
+
+ .if \nommu
+ .word 0
+ .else
+ .word cpu_\name\()_set_pte_ext
+ .endif
+
+ .if \suspend
+ .word cpu_\name\()_suspend_size
+#ifdef CONFIG_ARM_CPU_SUSPEND
+ .word cpu_\name\()_do_suspend
+ .word cpu_\name\()_do_resume
+#else
+ .word 0
+ .word 0
+#endif
+ .else
+ .word 0
+ .word 0
+ .word 0
+ .endif
+
+ .size \name\()_processor_functions, . - \name\()_processor_functions
+.endm
+
+.macro define_cache_functions name:req
+ .align 2
+ .type \name\()_cache_fns, #object
+ENTRY(\name\()_cache_fns)
+ .long \name\()_flush_icache_all
+ .long \name\()_flush_kern_cache_all
+ .long \name\()_flush_kern_cache_louis
+ .long \name\()_flush_user_cache_all
+ .long \name\()_flush_user_cache_range
+ .long \name\()_coherent_kern_range
+ .long \name\()_coherent_user_range
+ .long \name\()_flush_kern_dcache_area
+ .long \name\()_dma_map_area
+ .long \name\()_dma_unmap_area
+ .long \name\()_dma_flush_range
+ .size \name\()_cache_fns, . - \name\()_cache_fns
+.endm
+
+.macro define_tlb_functions name:req, flags_up:req, flags_smp
+ .type \name\()_tlb_fns, #object
+ENTRY(\name\()_tlb_fns)
+ .long \name\()_flush_user_tlb_range
+ .long \name\()_flush_kern_tlb_range
+ .ifnb \flags_smp
+ ALT_SMP(.long \flags_smp )
+ ALT_UP(.long \flags_up )
+ .else
+ .long \flags_up
+ .endif
+ .size \name\()_tlb_fns, . - \name\()_tlb_fns
+.endm
+
+.macro globl_equ x, y
+ .globl \x
+ .equ \x, \y
+.endm
+
+.macro initfn, func, base
+ .long \func - \base
+.endm
+
+ /*
+ * Macro to calculate the log2 size for the protection region
+ * registers. This calculates rd = log2(size) - 1. tmp must
+ * not be the same register as rd.
+ */
+.macro pr_sz, rd, size, tmp
+ mov \tmp, \size, lsr #12
+ mov \rd, #11
+1: movs \tmp, \tmp, lsr #1
+ addne \rd, \rd, #1
+ bne 1b
+.endm
+
+ /*
+ * Macro to generate a protection region register value
+ * given a pre-masked address, size, and enable bit.
+ * Corrupts size.
+ */
+.macro pr_val, dest, addr, size, enable
+ pr_sz \dest, \size, \size @ calculate log2(size) - 1
+ orr \dest, \addr, \dest, lsl #1 @ mask in the region size
+ orr \dest, \dest, \enable
+.endm
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
new file mode 100644
index 000000000..d65edf717
--- /dev/null
+++ b/arch/arm/mm/proc-mohawk.S
@@ -0,0 +1,455 @@
+/*
+ * 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)
+ ret 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
+ ret 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
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_mohawk_reset)
+ .popsection
+
+/*
+ * 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
+ ret lr
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(mohawk_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ ret lr
+ENDPROC(mohawk_flush_icache_all)
+
+/*
+ * 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
+ ret 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
+ ret 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 r0, #0
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(mohawk_dma_unmap_area)
+
+ .globl mohawk_flush_kern_cache_louis
+ .equ mohawk_flush_kern_cache_louis, mohawk_flush_kern_cache_all
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions mohawk
+
+ENTRY(cpu_mohawk_dcache_clean_area)
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ subs r1, r1, #CACHE_DLINESIZE
+ bhi 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ ret 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
+ ret 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
+ ret lr
+
+.globl cpu_mohawk_suspend_size
+.equ cpu_mohawk_suspend_size, 4 * 6
+#ifdef CONFIG_ARM_CPU_SUSPEND
+ENTRY(cpu_mohawk_do_suspend)
+ stmfd sp!, {r4 - r9, 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, c1, c0, 1 @ auxiliary control reg
+ mrc p15, 0, r9, c1, c0, 0 @ control reg
+ bic r4, r4, #2 @ clear frequency change bit
+ stmia r0, {r4 - r9} @ store cp regs
+ ldmia sp!, {r4 - r9, pc}
+ENDPROC(cpu_mohawk_do_suspend)
+
+ENTRY(cpu_mohawk_do_resume)
+ ldmia r0, {r4 - r9} @ load 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
+ orr r1, r1, #0x18 @ cache the page table in L2
+ mcr p15, 0, r1, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg
+ mov r0, r9 @ control register
+ b cpu_resume_mmu
+ENDPROC(cpu_mohawk_do_resume)
+#endif
+
+ .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
+ ret 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
+
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions mohawk, dabort=v5t_early_abort, pabort=legacy_pabort
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+ string cpu_mohawk_name, "Marvell 88SV331x"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+
+ .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
+ initfn __mohawk_setup, __88sv331x_proc_info
+ .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 000000000..ee2ce4962
--- /dev/null
+++ b/arch/arm/mm/proc-sa110.S
@@ -0,0 +1,225 @@
+/*
+ * 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
+ ret 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
+ ret 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
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_sa110_reset)
+ .popsection
+
+/*
+ * 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
+ ret 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
+ ret 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
+ ret 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
+ ret lr
+
+ .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
+ ret 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
+
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions sa110, dabort=v4_early_abort, pabort=legacy_pabort
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv4"
+ string cpu_elf_name, "v4"
+ string cpu_sa110_name, "StrongARM-110"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+
+ .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
+ initfn __sa110_setup, __sa110_proc_info
+ .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 000000000..222d5836f
--- /dev/null
+++ b/arch/arm/mm/proc-sa1100.S
@@ -0,0 +1,273 @@
+/*
+ * 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
+
+ .section .text
+
+/*
+ * 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
+ ret lr
+
+/*
+ * 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
+ ret 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
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_sa1100_reset)
+ .popsection
+
+/*
+ * 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
+ ret 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
+ ret 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
+ ret 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
+ ret lr
+
+.globl cpu_sa1100_suspend_size
+.equ cpu_sa1100_suspend_size, 4 * 3
+#ifdef CONFIG_ARM_CPU_SUSPEND
+ENTRY(cpu_sa1100_do_suspend)
+ stmfd sp!, {r4 - r6, lr}
+ mrc p15, 0, r4, c3, c0, 0 @ domain ID
+ mrc p15, 0, r5, c13, c0, 0 @ PID
+ mrc p15, 0, r6, c1, c0, 0 @ control reg
+ stmia r0, {r4 - r6} @ store cp regs
+ ldmfd sp!, {r4 - r6, pc}
+ENDPROC(cpu_sa1100_do_suspend)
+
+ENTRY(cpu_sa1100_do_resume)
+ ldmia r0, {r4 - r6} @ load cp regs
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ flush I+D TLBs
+ mcr p15, 0, ip, c7, c7, 0 @ flush I&D cache
+ mcr p15, 0, ip, c9, c0, 0 @ invalidate RB
+ mcr p15, 0, ip, c9, c0, 5 @ allow user space to use RB
+
+ mcr p15, 0, r4, c3, c0, 0 @ domain ID
+ mcr p15, 0, r1, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r5, c13, c0, 0 @ PID
+ mov r0, r6 @ control register
+ b cpu_resume_mmu
+ENDPROC(cpu_sa1100_do_resume)
+#endif
+
+ .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
+ ret 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
+
+/*
+ * SA1100 and SA1110 share the same function calls
+ */
+
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions sa1100, dabort=v4_early_abort, pabort=legacy_pabort, suspend=1
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv4"
+ string cpu_elf_name, "v4"
+ string cpu_sa1100_name, "StrongARM-1100"
+ string cpu_sa1110_name, "StrongARM-1110"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+
+.macro sa1100_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
+ .long PMD_TYPE_SECT | \
+ PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ .long PMD_TYPE_SECT | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ initfn __sa1100_setup, __\name\()_proc_info
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
+ .long \cpu_name
+ .long sa1100_processor_functions
+ .long v4wb_tlb_fns
+ .long v4_mc_user_fns
+ .long v4wb_cache_fns
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
+
+ sa1100_proc_info sa1100, 0x4401a110, 0xfffffff0, cpu_sa1100_name
+ sa1100_proc_info sa1110, 0x6901b110, 0xfffffff0, cpu_sa1110_name
diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c
new file mode 100644
index 000000000..054b491ff
--- /dev/null
+++ b/arch/arm/mm/proc-syms.c
@@ -0,0 +1,53 @@
+/*
+ * 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);
+#ifdef CONFIG_MMU
+EXPORT_SYMBOL(cpu_set_pte_ext);
+#endif
+#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 000000000..06d890a23
--- /dev/null
+++ b/arch/arm/mm/proc-v6.S
@@ -0,0 +1,300 @@
+/*
+ * 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)
+ ret 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
+ ret 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
+ .pushsection .idmap.text, "ax"
+ENTRY(cpu_v6_reset)
+ mrc p15, 0, r1, c1, c0, 0 @ ctrl register
+ bic r1, r1, #0x1 @ ...............m
+ mcr p15, 0, r1, c1, c0, 0 @ disable MMU
+ mov r1, #0
+ mcr p15, 0, r1, c7, c5, 4 @ ISB
+ ret r0
+ENDPROC(cpu_v6_reset)
+ .popsection
+
+/*
+ * 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
+ ret lr
+
+ENTRY(cpu_v6_dcache_clean_area)
+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
+ ret lr
+
+/*
+ * cpu_v6_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
+ mmid r1, r1 @ 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
+#ifdef CONFIG_PID_IN_CONTEXTIDR
+ mrc p15, 0, r2, c13, c0, 1 @ read current context ID
+ bic r2, r2, #0xff @ extract the PID
+ and r1, r1, #0xff
+ orr r1, r1, r2 @ insert into new context ID
+#endif
+ mcr p15, 0, r1, c13, c0, 1 @ set context ID
+#endif
+ ret 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
+ ret lr
+
+/* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
+.globl cpu_v6_suspend_size
+.equ cpu_v6_suspend_size, 4 * 6
+#ifdef CONFIG_ARM_CPU_SUSPEND
+ENTRY(cpu_v6_do_suspend)
+ stmfd sp!, {r4 - r9, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+#ifdef CONFIG_MMU
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 1 @ Translation table base 1
+#endif
+ mrc p15, 0, r7, c1, c0, 1 @ auxiliary control register
+ mrc p15, 0, r8, c1, c0, 2 @ co-processor access control
+ mrc p15, 0, r9, c1, c0, 0 @ control register
+ stmia r0, {r4 - r9}
+ ldmfd sp!, {r4- r9, 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
+ mcr p15, 0, ip, c13, c0, 1 @ set reserved context ID
+ ldmia r0, {r4 - r9}
+ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
+#ifdef CONFIG_MMU
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ ALT_SMP(orr r1, r1, #TTB_FLAGS_SMP)
+ ALT_UP(orr r1, r1, #TTB_FLAGS_UP)
+ mcr p15, 0, r1, c2, c0, 0 @ Translation table base 0
+ mcr p15, 0, r6, c2, c0, 1 @ Translation table base 1
+ mcr p15, 0, ip, c2, c0, 2 @ TTB control register
+#endif
+ mcr p15, 0, r7, c1, c0, 1 @ auxiliary control register
+ mcr p15, 0, r8, c1, c0, 2 @ co-processor access control
+ mcr p15, 0, ip, c7, c5, 4 @ ISB
+ mov r0, r9 @ control register
+ b cpu_resume_mmu
+ENDPROC(cpu_v6_do_resume)
+#endif
+
+ string cpu_v6_name, "ARMv6-compatible processor"
+
+ .align
+
+/*
+ * __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
+#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 */
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer and
+ @ complete invalidations
+ adr r5, v6_crval
+ ldmia r5, {r5, r6}
+ ARM_BE8(orr r6, r6, #1 << 25) @ big-endian page tables
+ 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 r0p2 erratum (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, =0x4107b362 @ id for ARM1136 r0p2
+ mrc p15, 0, r5, c0, c0, 0 @ get processor id
+ 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
+ ret 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
+
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions v6, dabort=v6_early_abort, pabort=v6_pabort, suspend=1
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv6"
+ string cpu_elf_name, "v6"
+ .align
+
+ .section ".proc.info.init", #alloc
+
+ /*
+ * 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
+ initfn __v6_setup, __v6_proc_info
+ .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-2level.S b/arch/arm/mm/proc-v7-2level.S
new file mode 100644
index 000000000..10405b8d3
--- /dev/null
+++ b/arch/arm/mm/proc-v7-2level.S
@@ -0,0 +1,169 @@
+/*
+ * arch/arm/mm/proc-v7-2level.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.
+ */
+
+#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
+
+/*
+ * 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_ca8_switch_mm)
+#ifdef CONFIG_MMU
+ mov r2, #0
+#ifdef CONFIG_ARM_ERRATA_430973
+ mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
+#endif
+#endif
+ENTRY(cpu_v7_switch_mm)
+#ifdef CONFIG_MMU
+ mmid r1, r1 @ get mm->context.id
+ ALT_SMP(orr r0, r0, #TTB_FLAGS_SMP)
+ ALT_UP(orr r0, r0, #TTB_FLAGS_UP)
+#ifdef CONFIG_PID_IN_CONTEXTIDR
+ mrc p15, 0, r2, c13, c0, 1 @ read current context ID
+ lsr r2, r2, #8 @ extract the PID
+ bfi r1, r2, #8, #24 @ insert into new context ID
+#endif
+#ifdef CONFIG_ARM_ERRATA_754322
+ dsb
+#endif
+ mcr p15, 0, r1, c13, c0, 1 @ set context ID
+ isb
+ mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
+ isb
+#endif
+ bx lr
+ENDPROC(cpu_v7_switch_mm)
+ENDPROC(cpu_ca8_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
+
+ tst r1, #L_PTE_XN
+ orrne r3, r3, #PTE_EXT_XN
+
+ tst r1, #L_PTE_YOUNG
+ tstne r1, #L_PTE_VALID
+ eorne r1, r1, #L_PTE_NONE
+ tstne r1, #L_PTE_NONE
+ moveq r3, #0
+
+ ARM( str r3, [r0, #2048]! )
+ THUMB( add r0, r0, #2048 )
+ THUMB( str r3, [r0] )
+ ALT_SMP(W(nop))
+ ALT_UP (mcr p15, 0, r0, c7, c10, 1) @ flush_pte
+#endif
+ bx lr
+ENDPROC(cpu_v7_set_pte_ext)
+
+ /*
+ * 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
+
+ /*
+ * Macro for setting up the TTBRx and TTBCR registers.
+ * - \ttb0 and \ttb1 updated with the corresponding flags.
+ */
+ .macro v7_ttb_setup, zero, ttbr0, ttbr1, tmp
+ mcr p15, 0, \zero, c2, c0, 2 @ TTB control register
+ ALT_SMP(orr \ttbr0, \ttbr0, #TTB_FLAGS_SMP)
+ ALT_UP(orr \ttbr0, \ttbr0, #TTB_FLAGS_UP)
+ ALT_SMP(orr \ttbr1, \ttbr1, #TTB_FLAGS_SMP)
+ ALT_UP(orr \ttbr1, \ttbr1, #TTB_FLAGS_UP)
+ mcr p15, 0, \ttbr1, c2, c0, 1 @ load TTB1
+ .endm
+
+ /* 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
+ * 01 0 110 0011 1100 .111 1101 < we want
+ */
+ .align 2
+ .type v7_crval, #object
+v7_crval:
+ crval clear=0x2120c302, mmuset=0x10c03c7d, ucset=0x00c01c7c
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
new file mode 100644
index 000000000..d3daed0ae
--- /dev/null
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -0,0 +1,165 @@
+/*
+ * arch/arm/mm/proc-v7-3level.S
+ *
+ * Copyright (C) 2001 Deep Blue Solutions Ltd.
+ * Copyright (C) 2011 ARM Ltd.
+ * Author: Catalin Marinas <catalin.marinas@arm.com>
+ * based on arch/arm/mm/proc-v7-2level.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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/assembler.h>
+
+#define TTB_IRGN_NC (0 << 8)
+#define TTB_IRGN_WBWA (1 << 8)
+#define TTB_IRGN_WT (2 << 8)
+#define TTB_IRGN_WB (3 << 8)
+#define TTB_RGN_NC (0 << 10)
+#define TTB_RGN_OC_WBWA (1 << 10)
+#define TTB_RGN_OC_WT (2 << 10)
+#define TTB_RGN_OC_WB (3 << 10)
+#define TTB_S (3 << 12)
+#define TTB_EAE (1 << 31)
+
+/* 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_RGN_OC_WBWA)
+#define PMD_FLAGS_SMP (PMD_SECT_WBWA|PMD_SECT_S)
+
+#ifndef __ARMEB__
+# define rpgdl r0
+# define rpgdh r1
+#else
+# define rpgdl r1
+# define rpgdh r0
+#endif
+
+/*
+ * cpu_v7_switch_mm(pgd_phys, tsk)
+ *
+ * Set the translation table base pointer to be pgd_phys (physical address of
+ * the new TTB).
+ */
+ENTRY(cpu_v7_switch_mm)
+#ifdef CONFIG_MMU
+ mmid r2, r2
+ asid r2, r2
+ orr rpgdh, rpgdh, r2, lsl #(48 - 32) @ upper 32-bits of pgd
+ mcrr p15, 0, rpgdl, rpgdh, c2 @ set TTB 0
+ isb
+#endif
+ ret lr
+ENDPROC(cpu_v7_switch_mm)
+
+#ifdef __ARMEB__
+#define rl r3
+#define rh r2
+#else
+#define rl r2
+#define rh r3
+#endif
+
+/*
+ * cpu_v7_set_pte_ext(ptep, pte)
+ *
+ * Set a level 2 translation table entry.
+ * - ptep - pointer to level 3 translation table entry
+ * - pte - PTE value to store (64-bit in r2 and r3)
+ */
+ENTRY(cpu_v7_set_pte_ext)
+#ifdef CONFIG_MMU
+ tst rl, #L_PTE_VALID
+ beq 1f
+ tst rh, #1 << (57 - 32) @ L_PTE_NONE
+ bicne rl, #L_PTE_VALID
+ bne 1f
+
+ eor ip, rh, #1 << (55 - 32) @ toggle L_PTE_DIRTY in temp reg to
+ @ test for !L_PTE_DIRTY || L_PTE_RDONLY
+ tst ip, #1 << (55 - 32) | 1 << (58 - 32)
+ orrne rl, #PTE_AP2
+ biceq rl, #PTE_AP2
+
+1: strd r2, r3, [r0]
+ ALT_SMP(W(nop))
+ ALT_UP (mcr p15, 0, r0, c7, c10, 1) @ flush_pte
+#endif
+ ret lr
+ENDPROC(cpu_v7_set_pte_ext)
+
+ /*
+ * Memory region attributes for LPAE (defined in pgtable-3level.h):
+ *
+ * n = AttrIndx[2:0]
+ *
+ * n MAIR
+ * UNCACHED 000 00000000
+ * BUFFERABLE 001 01000100
+ * DEV_WC 001 01000100
+ * WRITETHROUGH 010 10101010
+ * WRITEBACK 011 11101110
+ * DEV_CACHED 011 11101110
+ * DEV_SHARED 100 00000100
+ * DEV_NONSHARED 100 00000100
+ * unused 101
+ * unused 110
+ * WRITEALLOC 111 11111111
+ */
+.equ PRRR, 0xeeaa4400 @ MAIR0
+.equ NMRR, 0xff000004 @ MAIR1
+
+ /*
+ * Macro for setting up the TTBRx and TTBCR registers.
+ * - \ttbr1 updated.
+ */
+ .macro v7_ttb_setup, zero, ttbr0, ttbr1, tmp
+ ldr \tmp, =swapper_pg_dir @ swapper_pg_dir virtual address
+ mov \tmp, \tmp, lsr #ARCH_PGD_SHIFT
+ cmp \ttbr1, \tmp @ PHYS_OFFSET > PAGE_OFFSET?
+ mrc p15, 0, \tmp, c2, c0, 2 @ TTB control register
+ orr \tmp, \tmp, #TTB_EAE
+ ALT_SMP(orr \tmp, \tmp, #TTB_FLAGS_SMP)
+ ALT_UP(orr \tmp, \tmp, #TTB_FLAGS_UP)
+ ALT_SMP(orr \tmp, \tmp, #TTB_FLAGS_SMP << 16)
+ ALT_UP(orr \tmp, \tmp, #TTB_FLAGS_UP << 16)
+ /*
+ * Only use split TTBRs if PHYS_OFFSET <= PAGE_OFFSET (cmp above),
+ * otherwise booting secondary CPUs would end up using TTBR1 for the
+ * identity mapping set up in TTBR0.
+ */
+ orrls \tmp, \tmp, #TTBR1_SIZE @ TTBCR.T1SZ
+ mcr p15, 0, \tmp, c2, c0, 2 @ TTBCR
+ mov \tmp, \ttbr1, lsr #(32 - ARCH_PGD_SHIFT) @ upper bits
+ mov \ttbr1, \ttbr1, lsl #ARCH_PGD_SHIFT @ lower bits
+ addls \ttbr1, \ttbr1, #TTBR1_OFFSET
+ mcrr p15, 1, \ttbr1, \tmp, c2 @ load TTBR1
+ mov \tmp, \ttbr0, lsr #(32 - ARCH_PGD_SHIFT) @ upper bits
+ mov \ttbr0, \ttbr0, lsl #ARCH_PGD_SHIFT @ lower bits
+ mcrr p15, 0, \ttbr0, \tmp, c2 @ load TTBR0
+ .endm
+
+ /*
+ * AT
+ * TFR EV X F IHD LR S
+ * .EEE ..EE PUI. .TAT 4RVI ZWRS BLDP WCAM
+ * rxxx rrxx xxx0 0101 xxxx xxxx x111 xxxx < forced
+ * 11 0 110 0 0011 1100 .111 1101 < we want
+ */
+ .align 2
+ .type v7_crval, #object
+v7_crval:
+ crval clear=0x0122c302, mmuset=0x30c03c7d, ucset=0x00c01c7c
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
new file mode 100644
index 000000000..3d1054f11
--- /dev/null
+++ b/arch/arm/mm/proc-v7.S
@@ -0,0 +1,636 @@
+/*
+ * 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"
+
+#ifdef CONFIG_ARM_LPAE
+#include "proc-v7-3level.S"
+#else
+#include "proc-v7-2level.S"
+#endif
+
+ENTRY(cpu_v7_proc_init)
+ ret 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
+ ret 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
+ *
+ * This code must be executed using a flat identity mapping with
+ * caches disabled.
+ */
+ .align 5
+ .pushsection .idmap.text, "ax"
+ENTRY(cpu_v7_reset)
+ mrc p15, 0, r1, c1, c0, 0 @ ctrl register
+ bic r1, r1, #0x1 @ ...............m
+ THUMB( bic r1, r1, #1 << 30 ) @ SCTLR.TE (Thumb exceptions)
+ mcr p15, 0, r1, c1, c0, 0 @ disable MMU
+ isb
+ bx r0
+ENDPROC(cpu_v7_reset)
+ .popsection
+
+/*
+ * 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
+ ret lr
+ENDPROC(cpu_v7_do_idle)
+
+ENTRY(cpu_v7_dcache_clean_area)
+ ALT_SMP(W(nop)) @ MP extensions imply L1 PTW
+ ALT_UP_B(1f)
+ ret lr
+1: dcache_line_size r2, r3
+2: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, r2
+ subs r1, r1, r2
+ bhi 2b
+ dsb ishst
+ ret lr
+ENDPROC(cpu_v7_dcache_clean_area)
+
+ string cpu_v7_name, "ARMv7 Processor"
+ .align
+
+/* 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_ARM_CPU_SUSPEND
+ENTRY(cpu_v7_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mrc p15, 0, r5, c13, c0, 3 @ User r/o thread ID
+ stmia r0!, {r4 - r5}
+#ifdef CONFIG_MMU
+ mrc p15, 0, r6, c3, c0, 0 @ Domain ID
+#ifdef CONFIG_ARM_LPAE
+ mrrc p15, 1, r5, r7, c2 @ TTB 1
+#else
+ mrc p15, 0, r7, c2, c0, 1 @ TTB 1
+#endif
+ mrc p15, 0, r11, c2, c0, 2 @ TTB control register
+#endif
+ mrc p15, 0, r8, c1, c0, 0 @ Control register
+ mrc p15, 0, r9, c1, c0, 1 @ Auxiliary control register
+ mrc p15, 0, r10, c1, c0, 2 @ Co-processor access control
+ stmia r0, {r5 - r11}
+ ldmfd sp!, {r4 - r10, pc}
+ENDPROC(cpu_v7_do_suspend)
+
+ENTRY(cpu_v7_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c13, c0, 1 @ set reserved context ID
+ ldmia r0!, {r4 - r5}
+ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mcr p15, 0, r5, c13, c0, 3 @ User r/o thread ID
+ ldmia r0, {r5 - r11}
+#ifdef CONFIG_MMU
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs
+ mcr p15, 0, r6, c3, c0, 0 @ Domain ID
+#ifdef CONFIG_ARM_LPAE
+ mcrr p15, 0, r1, ip, c2 @ TTB 0
+ mcrr p15, 1, r5, r7, c2 @ TTB 1
+#else
+ ALT_SMP(orr r1, r1, #TTB_FLAGS_SMP)
+ ALT_UP(orr r1, r1, #TTB_FLAGS_UP)
+ mcr p15, 0, r1, c2, c0, 0 @ TTB 0
+ mcr p15, 0, r7, c2, c0, 1 @ TTB 1
+#endif
+ mcr p15, 0, r11, c2, c0, 2 @ TTB control register
+ 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
+#endif /* CONFIG_MMU */
+ mrc p15, 0, r4, c1, c0, 1 @ Read Auxiliary control register
+ teq r4, r9 @ Is it already set?
+ mcrne p15, 0, r9, c1, c0, 1 @ No, so write it
+ mcr p15, 0, r10, c1, c0, 2 @ Co-processor access control
+ isb
+ dsb
+ mov r0, r8 @ control register
+ b cpu_resume_mmu
+ENDPROC(cpu_v7_do_resume)
+#endif
+
+/*
+ * Cortex-A8
+ */
+ globl_equ cpu_ca8_proc_init, cpu_v7_proc_init
+ globl_equ cpu_ca8_proc_fin, cpu_v7_proc_fin
+ globl_equ cpu_ca8_reset, cpu_v7_reset
+ globl_equ cpu_ca8_do_idle, cpu_v7_do_idle
+ globl_equ cpu_ca8_dcache_clean_area, cpu_v7_dcache_clean_area
+ globl_equ cpu_ca8_set_pte_ext, cpu_v7_set_pte_ext
+ globl_equ cpu_ca8_suspend_size, cpu_v7_suspend_size
+#ifdef CONFIG_ARM_CPU_SUSPEND
+ globl_equ cpu_ca8_do_suspend, cpu_v7_do_suspend
+ globl_equ cpu_ca8_do_resume, cpu_v7_do_resume
+#endif
+
+/*
+ * Cortex-A9 processor functions
+ */
+ globl_equ cpu_ca9mp_proc_init, cpu_v7_proc_init
+ globl_equ cpu_ca9mp_proc_fin, cpu_v7_proc_fin
+ globl_equ cpu_ca9mp_reset, cpu_v7_reset
+ globl_equ cpu_ca9mp_do_idle, cpu_v7_do_idle
+ globl_equ cpu_ca9mp_dcache_clean_area, cpu_v7_dcache_clean_area
+ globl_equ cpu_ca9mp_switch_mm, cpu_v7_switch_mm
+ globl_equ cpu_ca9mp_set_pte_ext, cpu_v7_set_pte_ext
+.globl cpu_ca9mp_suspend_size
+.equ cpu_ca9mp_suspend_size, cpu_v7_suspend_size + 4 * 2
+#ifdef CONFIG_ARM_CPU_SUSPEND
+ENTRY(cpu_ca9mp_do_suspend)
+ stmfd sp!, {r4 - r5}
+ mrc p15, 0, r4, c15, c0, 1 @ Diagnostic register
+ mrc p15, 0, r5, c15, c0, 0 @ Power register
+ stmia r0!, {r4 - r5}
+ ldmfd sp!, {r4 - r5}
+ b cpu_v7_do_suspend
+ENDPROC(cpu_ca9mp_do_suspend)
+
+ENTRY(cpu_ca9mp_do_resume)
+ ldmia r0!, {r4 - r5}
+ mrc p15, 0, r10, c15, c0, 1 @ Read Diagnostic register
+ teq r4, r10 @ Already restored?
+ mcrne p15, 0, r4, c15, c0, 1 @ No, so restore it
+ mrc p15, 0, r10, c15, c0, 0 @ Read Power register
+ teq r5, r10 @ Already restored?
+ mcrne p15, 0, r5, c15, c0, 0 @ No, so restore it
+ b cpu_v7_do_resume
+ENDPROC(cpu_ca9mp_do_resume)
+#endif
+
+#ifdef CONFIG_CPU_PJ4B
+ globl_equ cpu_pj4b_switch_mm, cpu_v7_switch_mm
+ globl_equ cpu_pj4b_set_pte_ext, cpu_v7_set_pte_ext
+ globl_equ cpu_pj4b_proc_init, cpu_v7_proc_init
+ globl_equ cpu_pj4b_proc_fin, cpu_v7_proc_fin
+ globl_equ cpu_pj4b_reset, cpu_v7_reset
+#ifdef CONFIG_PJ4B_ERRATA_4742
+ENTRY(cpu_pj4b_do_idle)
+ dsb @ WFI may enter a low-power mode
+ wfi
+ dsb @barrier
+ ret lr
+ENDPROC(cpu_pj4b_do_idle)
+#else
+ globl_equ cpu_pj4b_do_idle, cpu_v7_do_idle
+#endif
+ globl_equ cpu_pj4b_dcache_clean_area, cpu_v7_dcache_clean_area
+#ifdef CONFIG_ARM_CPU_SUSPEND
+ENTRY(cpu_pj4b_do_suspend)
+ stmfd sp!, {r6 - r10}
+ mrc p15, 1, r6, c15, c1, 0 @ save CP15 - extra features
+ mrc p15, 1, r7, c15, c2, 0 @ save CP15 - Aux Func Modes Ctrl 0
+ mrc p15, 1, r8, c15, c1, 2 @ save CP15 - Aux Debug Modes Ctrl 2
+ mrc p15, 1, r9, c15, c1, 1 @ save CP15 - Aux Debug Modes Ctrl 1
+ mrc p15, 0, r10, c9, c14, 0 @ save CP15 - PMC
+ stmia r0!, {r6 - r10}
+ ldmfd sp!, {r6 - r10}
+ b cpu_v7_do_suspend
+ENDPROC(cpu_pj4b_do_suspend)
+
+ENTRY(cpu_pj4b_do_resume)
+ ldmia r0!, {r6 - r10}
+ mcr p15, 1, r6, c15, c1, 0 @ restore CP15 - extra features
+ mcr p15, 1, r7, c15, c2, 0 @ restore CP15 - Aux Func Modes Ctrl 0
+ mcr p15, 1, r8, c15, c1, 2 @ restore CP15 - Aux Debug Modes Ctrl 2
+ mcr p15, 1, r9, c15, c1, 1 @ restore CP15 - Aux Debug Modes Ctrl 1
+ mcr p15, 0, r10, c9, c14, 0 @ restore CP15 - PMC
+ b cpu_v7_do_resume
+ENDPROC(cpu_pj4b_do_resume)
+#endif
+.globl cpu_pj4b_suspend_size
+.equ cpu_pj4b_suspend_size, cpu_v7_suspend_size + 4 * 5
+
+#endif
+
+/*
+ * __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_ca5mp_setup:
+__v7_ca9mp_setup:
+__v7_cr7mp_setup:
+ mov r10, #(1 << 0) @ Cache/TLB ops broadcasting
+ b 1f
+__v7_ca7mp_setup:
+__v7_ca12mp_setup:
+__v7_ca15mp_setup:
+__v7_b15mp_setup:
+__v7_ca17mp_setup:
+ mov r10, #0
+1:
+#ifdef CONFIG_SMP
+ ALT_SMP(mrc p15, 0, r0, c1, c0, 1)
+ ALT_UP(mov r0, #(1 << 6)) @ fake it for UP
+ tst r0, #(1 << 6) @ SMP/nAMP mode enabled?
+ orreq r0, r0, #(1 << 6) @ Enable SMP/nAMP mode
+ orreq r0, r0, r10 @ Enable CPU-specific SMP bits
+ mcreq p15, 0, r0, c1, c0, 1
+#endif
+ b __v7_setup
+
+__v7_pj4b_setup:
+#ifdef CONFIG_CPU_PJ4B
+
+/* Auxiliary Debug Modes Control 1 Register */
+#define PJ4B_STATIC_BP (1 << 2) /* Enable Static BP */
+#define PJ4B_INTER_PARITY (1 << 8) /* Disable Internal Parity Handling */
+#define PJ4B_CLEAN_LINE (1 << 16) /* Disable data transfer for clean line */
+
+/* Auxiliary Debug Modes Control 2 Register */
+#define PJ4B_FAST_LDR (1 << 23) /* Disable fast LDR */
+#define PJ4B_SNOOP_DATA (1 << 25) /* Do not interleave write and snoop data */
+#define PJ4B_CWF (1 << 27) /* Disable Critical Word First feature */
+#define PJ4B_OUTSDNG_NC (1 << 29) /* Disable outstanding non cacheable rqst */
+#define PJ4B_L1_REP_RR (1 << 30) /* L1 replacement - Strict round robin */
+#define PJ4B_AUX_DBG_CTRL2 (PJ4B_SNOOP_DATA | PJ4B_CWF |\
+ PJ4B_OUTSDNG_NC | PJ4B_L1_REP_RR)
+
+/* Auxiliary Functional Modes Control Register 0 */
+#define PJ4B_SMP_CFB (1 << 1) /* Set SMP mode. Join the coherency fabric */
+#define PJ4B_L1_PAR_CHK (1 << 2) /* Support L1 parity checking */
+#define PJ4B_BROADCAST_CACHE (1 << 8) /* Broadcast Cache and TLB maintenance */
+
+/* Auxiliary Debug Modes Control 0 Register */
+#define PJ4B_WFI_WFE (1 << 22) /* WFI/WFE - serve the DVM and back to idle */
+
+ /* Auxiliary Debug Modes Control 1 Register */
+ mrc p15, 1, r0, c15, c1, 1
+ orr r0, r0, #PJ4B_CLEAN_LINE
+ orr r0, r0, #PJ4B_INTER_PARITY
+ bic r0, r0, #PJ4B_STATIC_BP
+ mcr p15, 1, r0, c15, c1, 1
+
+ /* Auxiliary Debug Modes Control 2 Register */
+ mrc p15, 1, r0, c15, c1, 2
+ bic r0, r0, #PJ4B_FAST_LDR
+ orr r0, r0, #PJ4B_AUX_DBG_CTRL2
+ mcr p15, 1, r0, c15, c1, 2
+
+ /* Auxiliary Functional Modes Control Register 0 */
+ mrc p15, 1, r0, c15, c2, 0
+#ifdef CONFIG_SMP
+ orr r0, r0, #PJ4B_SMP_CFB
+#endif
+ orr r0, r0, #PJ4B_L1_PAR_CHK
+ orr r0, r0, #PJ4B_BROADCAST_CACHE
+ mcr p15, 1, r0, c15, c2, 0
+
+ /* Auxiliary Debug Modes Control 0 Register */
+ mrc p15, 1, r0, c15, c1, 0
+ orr r0, r0, #PJ4B_WFI_WFE
+ mcr p15, 1, r0, c15, c1, 0
+
+#endif /* CONFIG_CPU_PJ4B */
+
+__v7_setup:
+ adr r12, __v7_setup_stack @ the local stack
+ stmia r12, {r0-r5, r7, r9, r11, lr}
+ bl v7_flush_dcache_louis
+ 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
+#if defined(CONFIG_ARM_ERRATA_430973) && !defined(CONFIG_ARCH_MULTIPLATFORM)
+
+ 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
+#if defined(CONFIG_ARM_ERRATA_751472) && defined(CONFIG_SMP)
+ ALT_SMP(cmp r6, #0x30) @ present prior to r3p0
+ ALT_UP_B(1f)
+ 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
+1:
+#endif
+
+ /* Cortex-A15 Errata */
+3: ldr r10, =0x00000c0f @ Cortex-A15 primary part number
+ teq r0, r10
+ bne 4f
+
+#ifdef CONFIG_ARM_ERRATA_773022
+ cmp r6, #0x4 @ only present up to r0p4
+ mrcle p15, 0, r10, c1, c0, 1 @ read aux control register
+ orrle r10, r10, #1 << 1 @ disable loop buffer
+ mcrle p15, 0, r10, c1, c0, 1 @ write aux control register
+#endif
+
+4: mov r10, #0
+ mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate
+#ifdef CONFIG_MMU
+ mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs
+ v7_ttb_setup r10, r4, r8, r5 @ TTBCR, TTBRx setup
+ 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
+ dsb @ Complete invalidations
+#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}
+ ARM_BE8(orr r6, r6, #1 << 25) @ big-endian page tables
+#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
+ ret lr @ return to head.S:__ret
+ENDPROC(__v7_setup)
+
+ .align 2
+__v7_setup_stack:
+ .space 4 * 11 @ 11 registers
+
+ __INITDATA
+
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions v7, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
+#ifndef CONFIG_ARM_LPAE
+ define_processor_functions ca8, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
+ define_processor_functions ca9mp, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
+#endif
+#ifdef CONFIG_CPU_PJ4B
+ define_processor_functions pj4b, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
+#endif
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv7"
+ string cpu_elf_name, "v7"
+ .align
+
+ .section ".proc.info.init", #alloc
+
+ /*
+ * Standard v7 proc info content
+ */
+.macro __v7_proc name, initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0, proc_fns = v7_processor_functions
+ ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \
+ PMD_SECT_AF | PMD_FLAGS_SMP | \mm_mmuflags)
+ ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \
+ PMD_SECT_AF | PMD_FLAGS_UP | \mm_mmuflags)
+ .long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ | PMD_SECT_AF | \io_mmuflags
+ initfn \initfunc, \name
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT | \
+ HWCAP_EDSP | HWCAP_TLS | \hwcaps
+ .long cpu_v7_name
+ .long \proc_fns
+ .long v7wbi_tlb_fns
+ .long v6_user_fns
+ .long v7_cache_fns
+.endm
+
+#ifndef CONFIG_ARM_LPAE
+ /*
+ * ARM Ltd. Cortex A5 processor.
+ */
+ .type __v7_ca5mp_proc_info, #object
+__v7_ca5mp_proc_info:
+ .long 0x410fc050
+ .long 0xff0ffff0
+ __v7_proc __v7_ca5mp_proc_info, __v7_ca5mp_setup
+ .size __v7_ca5mp_proc_info, . - __v7_ca5mp_proc_info
+
+ /*
+ * ARM Ltd. Cortex A9 processor.
+ */
+ .type __v7_ca9mp_proc_info, #object
+__v7_ca9mp_proc_info:
+ .long 0x410fc090
+ .long 0xff0ffff0
+ __v7_proc __v7_ca9mp_proc_info, __v7_ca9mp_setup, proc_fns = ca9mp_processor_functions
+ .size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info
+
+ /*
+ * ARM Ltd. Cortex A8 processor.
+ */
+ .type __v7_ca8_proc_info, #object
+__v7_ca8_proc_info:
+ .long 0x410fc080
+ .long 0xff0ffff0
+ __v7_proc __v7_ca8_proc_info, __v7_setup, proc_fns = ca8_processor_functions
+ .size __v7_ca8_proc_info, . - __v7_ca8_proc_info
+
+#endif /* CONFIG_ARM_LPAE */
+
+ /*
+ * Marvell PJ4B processor.
+ */
+#ifdef CONFIG_CPU_PJ4B
+ .type __v7_pj4b_proc_info, #object
+__v7_pj4b_proc_info:
+ .long 0x560f5800
+ .long 0xff0fff00
+ __v7_proc __v7_pj4b_proc_info, __v7_pj4b_setup, proc_fns = pj4b_processor_functions
+ .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info
+#endif
+
+ /*
+ * ARM Ltd. Cortex R7 processor.
+ */
+ .type __v7_cr7mp_proc_info, #object
+__v7_cr7mp_proc_info:
+ .long 0x410fc170
+ .long 0xff0ffff0
+ __v7_proc __v7_cr7mp_proc_info, __v7_cr7mp_setup
+ .size __v7_cr7mp_proc_info, . - __v7_cr7mp_proc_info
+
+ /*
+ * ARM Ltd. Cortex A7 processor.
+ */
+ .type __v7_ca7mp_proc_info, #object
+__v7_ca7mp_proc_info:
+ .long 0x410fc070
+ .long 0xff0ffff0
+ __v7_proc __v7_ca7mp_proc_info, __v7_ca7mp_setup
+ .size __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info
+
+ /*
+ * ARM Ltd. Cortex A12 processor.
+ */
+ .type __v7_ca12mp_proc_info, #object
+__v7_ca12mp_proc_info:
+ .long 0x410fc0d0
+ .long 0xff0ffff0
+ __v7_proc __v7_ca12mp_proc_info, __v7_ca12mp_setup
+ .size __v7_ca12mp_proc_info, . - __v7_ca12mp_proc_info
+
+ /*
+ * ARM Ltd. Cortex A15 processor.
+ */
+ .type __v7_ca15mp_proc_info, #object
+__v7_ca15mp_proc_info:
+ .long 0x410fc0f0
+ .long 0xff0ffff0
+ __v7_proc __v7_ca15mp_proc_info, __v7_ca15mp_setup
+ .size __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info
+
+ /*
+ * Broadcom Corporation Brahma-B15 processor.
+ */
+ .type __v7_b15mp_proc_info, #object
+__v7_b15mp_proc_info:
+ .long 0x420f00f0
+ .long 0xff0ffff0
+ __v7_proc __v7_b15mp_proc_info, __v7_b15mp_setup
+ .size __v7_b15mp_proc_info, . - __v7_b15mp_proc_info
+
+ /*
+ * ARM Ltd. Cortex A17 processor.
+ */
+ .type __v7_ca17mp_proc_info, #object
+__v7_ca17mp_proc_info:
+ .long 0x410fc0e0
+ .long 0xff0ffff0
+ __v7_proc __v7_ca17mp_proc_info, __v7_ca17mp_setup
+ .size __v7_ca17mp_proc_info, . - __v7_ca17mp_proc_info
+
+ /*
+ * Qualcomm Inc. Krait processors.
+ */
+ .type __krait_proc_info, #object
+__krait_proc_info:
+ .long 0x510f0400 @ Required ID value
+ .long 0xff0ffc00 @ Mask for ID
+ /*
+ * Some Krait processors don't indicate support for SDIV and UDIV
+ * instructions in the ARM instruction set, even though they actually
+ * do support them. They also don't indicate support for fused multiply
+ * instructions even though they actually do support them.
+ */
+ __v7_proc __krait_proc_info, __v7_setup, hwcaps = HWCAP_IDIV | HWCAP_VFPv4
+ .size __krait_proc_info, . - __krait_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
+ __v7_proc __v7_proc_info, __v7_setup
+ .size __v7_proc_info, . - __v7_proc_info
diff --git a/arch/arm/mm/proc-v7m.S b/arch/arm/mm/proc-v7m.S
new file mode 100644
index 000000000..e08e1f2ba
--- /dev/null
+++ b/arch/arm/mm/proc-v7m.S
@@ -0,0 +1,159 @@
+/*
+ * linux/arch/arm/mm/proc-v7m.S
+ *
+ * Copyright (C) 2008 ARM Ltd.
+ * 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-M processor support.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/v7m.h>
+#include "proc-macros.S"
+
+ENTRY(cpu_v7m_proc_init)
+ ret lr
+ENDPROC(cpu_v7m_proc_init)
+
+ENTRY(cpu_v7m_proc_fin)
+ ret lr
+ENDPROC(cpu_v7m_proc_fin)
+
+/*
+ * cpu_v7m_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_v7m_reset)
+ ret r0
+ENDPROC(cpu_v7m_reset)
+
+/*
+ * cpu_v7m_do_idle()
+ *
+ * Idle the processor (eg, wait for interrupt).
+ *
+ * IRQs are already disabled.
+ */
+ENTRY(cpu_v7m_do_idle)
+ wfi
+ ret lr
+ENDPROC(cpu_v7m_do_idle)
+
+ENTRY(cpu_v7m_dcache_clean_area)
+ ret lr
+ENDPROC(cpu_v7m_dcache_clean_area)
+
+/*
+ * There is no MMU, so here is nothing to do.
+ */
+ENTRY(cpu_v7m_switch_mm)
+ ret lr
+ENDPROC(cpu_v7m_switch_mm)
+
+.globl cpu_v7m_suspend_size
+.equ cpu_v7m_suspend_size, 0
+
+#ifdef CONFIG_ARM_CPU_SUSPEND
+ENTRY(cpu_v7m_do_suspend)
+ ret lr
+ENDPROC(cpu_v7m_do_suspend)
+
+ENTRY(cpu_v7m_do_resume)
+ ret lr
+ENDPROC(cpu_v7m_do_resume)
+#endif
+
+ .section ".text.init", #alloc, #execinstr
+
+/*
+ * __v7m_setup
+ *
+ * This should be able to cover all ARMv7-M cores.
+ */
+__v7m_setup:
+ @ Configure the vector table base address
+ ldr r0, =BASEADDR_V7M_SCB
+ ldr r12, =vector_table
+ str r12, [r0, V7M_SCB_VTOR]
+
+ @ enable UsageFault, BusFault and MemManage fault.
+ ldr r5, [r0, #V7M_SCB_SHCSR]
+ orr r5, #(V7M_SCB_SHCSR_USGFAULTENA | V7M_SCB_SHCSR_BUSFAULTENA | V7M_SCB_SHCSR_MEMFAULTENA)
+ str r5, [r0, #V7M_SCB_SHCSR]
+
+ @ Lower the priority of the SVC and PendSV exceptions
+ mov r5, #0x80000000
+ str r5, [r0, V7M_SCB_SHPR2] @ set SVC priority
+ mov r5, #0x00800000
+ str r5, [r0, V7M_SCB_SHPR3] @ set PendSV priority
+
+ @ SVC to run the kernel in this mode
+ adr r1, BSYM(1f)
+ ldr r5, [r12, #11 * 4] @ read the SVC vector entry
+ str r1, [r12, #11 * 4] @ write the temporary SVC vector entry
+ mov r6, lr @ save LR
+ mov r7, sp @ save SP
+ ldr sp, =__v7m_setup_stack_top
+ cpsie i
+ svc #0
+1: cpsid i
+ str r5, [r12, #11 * 4] @ restore the original SVC vector entry
+ mov lr, r6 @ restore LR
+ mov sp, r7 @ restore SP
+
+ @ Special-purpose control register
+ mov r1, #1
+ msr control, r1 @ Thread mode has unpriviledged access
+
+ @ Configure the System Control Register to ensure 8-byte stack alignment
+ @ Note the STKALIGN bit is either RW or RAO.
+ ldr r12, [r0, V7M_SCB_CCR] @ system control register
+ orr r12, #V7M_SCB_CCR_STKALIGN
+ str r12, [r0, V7M_SCB_CCR]
+ ret lr
+ENDPROC(__v7m_setup)
+
+ .align 2
+__v7m_setup_stack:
+ .space 4 * 8 @ 8 registers
+__v7m_setup_stack_top:
+
+ define_processor_functions v7m, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1
+
+ .section ".rodata"
+ string cpu_arch_name, "armv7m"
+ string cpu_elf_name "v7m"
+ string cpu_v7m_name "ARMv7-M"
+
+ .section ".proc.info.init", #alloc
+
+ /*
+ * Match any ARMv7-M processor core.
+ */
+ .type __v7m_proc_info, #object
+__v7m_proc_info:
+ .long 0x000f0000 @ Required ID value
+ .long 0x000f0000 @ Mask for ID
+ .long 0 @ proc_info_list.__cpu_mm_mmu_flags
+ .long 0 @ proc_info_list.__cpu_io_mmu_flags
+ initfn __v7m_setup, __v7m_proc_info @ proc_info_list.__cpu_flush
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT
+ .long cpu_v7m_name
+ .long v7m_processor_functions @ proc_info_list.proc
+ .long 0 @ proc_info_list.tlb
+ .long 0 @ proc_info_list.user
+ .long nop_cache_fns @ proc_info_list.cache
+ .size __v7m_proc_info, . - __v7m_proc_info
+
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
new file mode 100644
index 000000000..293dcc2c4
--- /dev/null
+++ b/arch/arm/mm/proc-xsc3.S
@@ -0,0 +1,532 @@
+/*
+ * 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 <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)
+ ret 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
+ ret 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
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_xsc3_reset)
+ .popsection
+
+/*
+ * 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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)
+ ret lr
+ENDPROC(xsc3_dma_unmap_area)
+
+ .globl xsc3_flush_kern_cache_louis
+ .equ xsc3_flush_kern_cache_louis, xsc3_flush_kern_cache_all
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions xsc3
+
+ENTRY(cpu_xsc3_dcache_clean_area)
+1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
+ add r0, r0, #CACHELINESIZE
+ subs r1, r1, #CACHELINESIZE
+ bhi 1b
+ ret 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
+ ret lr
+
+ .ltorg
+ .align
+
+.globl cpu_xsc3_suspend_size
+.equ cpu_xsc3_suspend_size, 4 * 6
+#ifdef CONFIG_ARM_CPU_SUSPEND
+ENTRY(cpu_xsc3_do_suspend)
+ stmfd sp!, {r4 - r9, 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, c1, c0, 1 @ auxiliary control reg
+ mrc p15, 0, r9, c1, c0, 0 @ control reg
+ bic r4, r4, #2 @ clear frequency change bit
+ stmia r0, {r4 - r9} @ store cp regs
+ ldmia sp!, {r4 - r9, pc}
+ENDPROC(cpu_xsc3_do_suspend)
+
+ENTRY(cpu_xsc3_do_resume)
+ ldmia r0, {r4 - r9} @ load 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
+ orr r1, r1, #0x18 @ cache the page table in L2
+ mcr p15, 0, r1, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg
+ mov r0, r9 @ control register
+ b cpu_resume_mmu
+ENDPROC(cpu_xsc3_do_resume)
+#endif
+
+ .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)
+ ret lr
+
+ .size __xsc3_setup, . - __xsc3_setup
+
+ .type xsc3_crval, #object
+xsc3_crval:
+ crval clear=0x04002202, mmuset=0x00003905, ucset=0x00001900
+
+ __INITDATA
+
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions xsc3, dabort=v5t_early_abort, pabort=legacy_pabort, suspend=1
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+ string cpu_xsc3_name, "XScale-V3 based processor"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+
+.macro xsc3_proc_info name:req, cpu_val:req, cpu_mask:req
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
+ .long PMD_TYPE_SECT | \
+ PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ .long PMD_TYPE_SECT | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ initfn __xsc3_setup, __\name\()_proc_info
+ .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 __\name\()_proc_info, . - __\name\()_proc_info
+.endm
+
+ xsc3_proc_info xsc3, 0x69056000, 0xffffe000
+
+/* Note: PXA935 changed its implementor ID from Intel to Marvell */
+ xsc3_proc_info xsc3_pxa935, 0x56056000, 0xffffe000
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
new file mode 100644
index 000000000..b6bbfdb6d
--- /dev/null
+++ b/arch/arm/mm/proc-xscale.S
@@ -0,0 +1,660 @@
+/*
+ * 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
+ ret 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
+ ret 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
+ .pushsection .idmap.text, "ax"
+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
+ ret r0
+ENDPROC(cpu_xscale_reset)
+ .popsection
+
+/*
+ * 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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
+ ret 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_80200_A0_A1_dma_map_area)
+ add r1, r1, r0
+ teq r2, #DMA_TO_DEVICE
+ beq xscale_dma_clean_range
+ b xscale_dma_flush_range
+ENDPROC(xscale_80200_A0_A1_dma_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)
+ ret lr
+ENDPROC(xscale_dma_unmap_area)
+
+ .globl xscale_flush_kern_cache_louis
+ .equ xscale_flush_kern_cache_louis, xscale_flush_kern_cache_all
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions xscale
+
+/*
+ * On stepping A0/A1 of the 80200, invalidating D-cache by line doesn't
+ * 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
+ */
+.macro a0_alias basename
+ .globl xscale_80200_A0_A1_\basename
+ .type xscale_80200_A0_A1_\basename , %function
+ .equ xscale_80200_A0_A1_\basename , xscale_\basename
+.endm
+
+/*
+ * Most of the cache functions are unchanged for these processor revisions.
+ * Export suitable alias symbols for the unchanged functions:
+ */
+ a0_alias flush_icache_all
+ a0_alias flush_user_cache_all
+ a0_alias flush_kern_cache_all
+ a0_alias flush_kern_cache_louis
+ a0_alias flush_user_cache_range
+ a0_alias coherent_kern_range
+ a0_alias coherent_user_range
+ a0_alias flush_kern_dcache_area
+ a0_alias dma_flush_range
+ a0_alias dma_unmap_area
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions xscale_80200_A0_A1
+
+ENTRY(cpu_xscale_dcache_clean_area)
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHELINESIZE
+ subs r1, r1, #CACHELINESIZE
+ bhi 1b
+ ret 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
+ ret lr
+
+ .ltorg
+ .align
+
+.globl cpu_xscale_suspend_size
+.equ cpu_xscale_suspend_size, 4 * 6
+#ifdef CONFIG_ARM_CPU_SUSPEND
+ENTRY(cpu_xscale_do_suspend)
+ stmfd sp!, {r4 - r9, 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, c1, c0, 1 @ auxiliary control reg
+ mrc p15, 0, r9, c1, c0, 0 @ control reg
+ bic r4, r4, #2 @ clear frequency change bit
+ stmia r0, {r4 - r9} @ store cp regs
+ ldmfd sp!, {r4 - r9, pc}
+ENDPROC(cpu_xscale_do_suspend)
+
+ENTRY(cpu_xscale_do_resume)
+ ldmia r0, {r4 - r9} @ 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, r1, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg
+ mov r0, r9 @ control register
+ b cpu_resume_mmu
+ENDPROC(cpu_xscale_do_resume)
+#endif
+
+ .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
+ ret 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
+
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions xscale, dabort=v5t_early_abort, pabort=legacy_pabort, suspend=1
+
+ .section ".rodata"
+
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+
+ string cpu_80200_A0_A1_name, "XScale-80200 A0/A1"
+ string cpu_80200_name, "XScale-80200"
+ string cpu_80219_name, "XScale-80219"
+ string cpu_8032x_name, "XScale-IOP8032x Family"
+ string cpu_8033x_name, "XScale-IOP8033x Family"
+ string cpu_pxa250_name, "XScale-PXA250"
+ string cpu_pxa210_name, "XScale-PXA210"
+ string cpu_ixp42x_name, "XScale-IXP42x Family"
+ string cpu_ixp43x_name, "XScale-IXP43x Family"
+ string cpu_ixp46x_name, "XScale-IXP46x Family"
+ string cpu_ixp2400_name, "XScale-IXP2400"
+ string cpu_ixp2800_name, "XScale-IXP2800"
+ string cpu_pxa255_name, "XScale-PXA255"
+ string cpu_pxa270_name, "XScale-PXA270"
+
+ .align
+
+ .section ".proc.info.init", #alloc
+
+.macro xscale_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
+ .long PMD_TYPE_SECT | \
+ PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ .long PMD_TYPE_SECT | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ initfn __xscale_setup, __\name\()_proc_info
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+ .long \cpu_name
+ .long xscale_processor_functions
+ .long v4wbi_tlb_fns
+ .long xscale_mc_user_fns
+ .ifb \cache
+ .long xscale_cache_fns
+ .else
+ .long \cache
+ .endif
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
+
+ xscale_proc_info 80200_A0_A1, 0x69052000, 0xfffffffe, cpu_80200_name, \
+ cache=xscale_80200_A0_A1_cache_fns
+ xscale_proc_info 80200, 0x69052000, 0xfffffff0, cpu_80200_name
+ xscale_proc_info 80219, 0x69052e20, 0xffffffe0, cpu_80219_name
+ xscale_proc_info 8032x, 0x69052420, 0xfffff7e0, cpu_8032x_name
+ xscale_proc_info 8033x, 0x69054010, 0xfffffd30, cpu_8033x_name
+ xscale_proc_info pxa250, 0x69052100, 0xfffff7f0, cpu_pxa250_name
+ xscale_proc_info pxa210, 0x69052120, 0xfffff3f0, cpu_pxa210_name
+ xscale_proc_info ixp2400, 0x69054190, 0xfffffff0, cpu_ixp2400_name
+ xscale_proc_info ixp2800, 0x690541a0, 0xfffffff0, cpu_ixp2800_name
+ xscale_proc_info ixp42x, 0x690541c0, 0xffffffc0, cpu_ixp42x_name
+ xscale_proc_info ixp43x, 0x69054040, 0xfffffff0, cpu_ixp43x_name
+ xscale_proc_info ixp46x, 0x69054200, 0xffffff00, cpu_ixp46x_name
+ xscale_proc_info pxa255, 0x69052d00, 0xfffffff0, cpu_pxa255_name
+ xscale_proc_info pxa270, 0x69054110, 0xfffffff0, cpu_pxa270_name
diff --git a/arch/arm/mm/tcm.h b/arch/arm/mm/tcm.h
new file mode 100644
index 000000000..8015ad434
--- /dev/null
+++ b/arch/arm/mm/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/mm/tlb-fa.S b/arch/arm/mm/tlb-fa.S
new file mode 100644
index 000000000..d2d9ecbe0
--- /dev/null
+++ b/arch/arm/mm/tlb-fa.S
@@ -0,0 +1,70 @@
+/*
+ * 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/assembler.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 ?
+ retne 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, c10, 4 @ data write barrier
+ ret 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, c10, 4 @ data write barrier
+ mcr p15, 0, r3, c7, c5, 4 @ prefetch flush (isb)
+ ret lr
+
+ __INITDATA
+
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions fa, fa_tlb_flags
diff --git a/arch/arm/mm/tlb-v4.S b/arch/arm/mm/tlb-v4.S
new file mode 100644
index 000000000..a2b5dca42
--- /dev/null
+++ b/arch/arm/mm/tlb-v4.S
@@ -0,0 +1,62 @@
+/*
+ * 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/assembler.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 ?
+ retne 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
+ ret 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
+
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v4, v4_tlb_flags
diff --git a/arch/arm/mm/tlb-v4wb.S b/arch/arm/mm/tlb-v4wb.S
new file mode 100644
index 000000000..5a093b458
--- /dev/null
+++ b/arch/arm/mm/tlb-v4wb.S
@@ -0,0 +1,74 @@
+/*
+ * 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/assembler.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 ?
+ retne 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
+ ret 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
+ ret lr
+
+ __INITDATA
+
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v4wb, v4wb_tlb_flags
diff --git a/arch/arm/mm/tlb-v4wbi.S b/arch/arm/mm/tlb-v4wbi.S
new file mode 100644
index 000000000..058861548
--- /dev/null
+++ b/arch/arm/mm/tlb-v4wbi.S
@@ -0,0 +1,65 @@
+/*
+ * 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/assembler.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 ?
+ retne 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
+ ret 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
+ ret lr
+
+ __INITDATA
+
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v4wbi, v4wbi_tlb_flags
diff --git a/arch/arm/mm/tlb-v6.S b/arch/arm/mm/tlb-v6.S
new file mode 100644
index 000000000..6f689be63
--- /dev/null
+++ b/arch/arm/mm/tlb-v6.S
@@ -0,0 +1,93 @@
+/*
+ * 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/assembler.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, c10, 4 @ data synchronization barrier
+ ret 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, c10, 4 @ data synchronization barrier
+ mcr p15, 0, r2, c7, c5, 4 @ prefetch flush (isb)
+ ret lr
+
+ __INIT
+
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v6wbi, v6wbi_tlb_flags
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S
new file mode 100644
index 000000000..e5101a3bc
--- /dev/null
+++ b/arch/arm/mm/tlb-v7.S
@@ -0,0 +1,95 @@
+/*
+ * 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 ish
+ mov r0, r0, lsr #PAGE_SHIFT @ align address
+ mov r1, r1, lsr #PAGE_SHIFT
+ asid r3, r3 @ mask ASID
+#ifdef CONFIG_ARM_ERRATA_720789
+ ALT_SMP(W(mov) r3, #0 )
+ ALT_UP(W(nop) )
+#endif
+ orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA
+ mov r1, r1, lsl #PAGE_SHIFT
+1:
+#ifdef CONFIG_ARM_ERRATA_720789
+ ALT_SMP(mcr p15, 0, r0, c8, c3, 3) @ TLB invalidate U MVA all ASID (shareable)
+#else
+ ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable)
+#endif
+ ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA
+
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ dsb ish
+ ret 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 ish
+ 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 CONFIG_ARM_ERRATA_720789
+ ALT_SMP(mcr p15, 0, r0, c8, c3, 3) @ TLB invalidate U MVA all ASID (shareable)
+#else
+ ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable)
+#endif
+ ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ dsb ish
+ isb
+ ret lr
+ENDPROC(v7wbi_flush_kern_tlb_range)
+
+ __INIT
+
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v7wbi, v7wbi_tlb_flags_up, flags_smp=v7wbi_tlb_flags_smp
diff --git a/arch/arm/net/Makefile b/arch/arm/net/Makefile
new file mode 100644
index 000000000..c2c10841b
--- /dev/null
+++ b/arch/arm/net/Makefile
@@ -0,0 +1,3 @@
+# ARM-specific networking code
+
+obj-$(CONFIG_BPF_JIT) += bpf_jit_32.o
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
new file mode 100644
index 000000000..e0e23582c
--- /dev/null
+++ b/arch/arm/net/bpf_jit_32.c
@@ -0,0 +1,991 @@
+/*
+ * Just-In-Time compiler for BPF filters on 32bit ARM
+ *
+ * Copyright (c) 2011 Mircea Gherzan <mgherzan@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/bitops.h>
+#include <linux/compiler.h>
+#include <linux/errno.h>
+#include <linux/filter.h>
+#include <linux/netdevice.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/if_vlan.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hwcap.h>
+#include <asm/opcodes.h>
+
+#include "bpf_jit_32.h"
+
+/*
+ * ABI:
+ *
+ * r0 scratch register
+ * r4 BPF register A
+ * r5 BPF register X
+ * r6 pointer to the skb
+ * r7 skb->data
+ * r8 skb_headlen(skb)
+ */
+
+#define r_scratch ARM_R0
+/* r1-r3 are (also) used for the unaligned loads on the non-ARMv7 slowpath */
+#define r_off ARM_R1
+#define r_A ARM_R4
+#define r_X ARM_R5
+#define r_skb ARM_R6
+#define r_skb_data ARM_R7
+#define r_skb_hl ARM_R8
+
+#define SCRATCH_SP_OFFSET 0
+#define SCRATCH_OFF(k) (SCRATCH_SP_OFFSET + 4 * (k))
+
+#define SEEN_MEM ((1 << BPF_MEMWORDS) - 1)
+#define SEEN_MEM_WORD(k) (1 << (k))
+#define SEEN_X (1 << BPF_MEMWORDS)
+#define SEEN_CALL (1 << (BPF_MEMWORDS + 1))
+#define SEEN_SKB (1 << (BPF_MEMWORDS + 2))
+#define SEEN_DATA (1 << (BPF_MEMWORDS + 3))
+
+#define FLAG_NEED_X_RESET (1 << 0)
+#define FLAG_IMM_OVERFLOW (1 << 1)
+
+struct jit_ctx {
+ const struct bpf_prog *skf;
+ unsigned idx;
+ unsigned prologue_bytes;
+ int ret0_fp_idx;
+ u32 seen;
+ u32 flags;
+ u32 *offsets;
+ u32 *target;
+#if __LINUX_ARM_ARCH__ < 7
+ u16 epilogue_bytes;
+ u16 imm_count;
+ u32 *imms;
+#endif
+};
+
+int bpf_jit_enable __read_mostly;
+
+static u64 jit_get_skb_b(struct sk_buff *skb, unsigned offset)
+{
+ u8 ret;
+ int err;
+
+ err = skb_copy_bits(skb, offset, &ret, 1);
+
+ return (u64)err << 32 | ret;
+}
+
+static u64 jit_get_skb_h(struct sk_buff *skb, unsigned offset)
+{
+ u16 ret;
+ int err;
+
+ err = skb_copy_bits(skb, offset, &ret, 2);
+
+ return (u64)err << 32 | ntohs(ret);
+}
+
+static u64 jit_get_skb_w(struct sk_buff *skb, unsigned offset)
+{
+ u32 ret;
+ int err;
+
+ err = skb_copy_bits(skb, offset, &ret, 4);
+
+ return (u64)err << 32 | ntohl(ret);
+}
+
+/*
+ * Wrapper that handles both OABI and EABI and assures Thumb2 interworking
+ * (where the assembly routines like __aeabi_uidiv could cause problems).
+ */
+static u32 jit_udiv(u32 dividend, u32 divisor)
+{
+ return dividend / divisor;
+}
+
+static inline void _emit(int cond, u32 inst, struct jit_ctx *ctx)
+{
+ inst |= (cond << 28);
+ inst = __opcode_to_mem_arm(inst);
+
+ if (ctx->target != NULL)
+ ctx->target[ctx->idx] = inst;
+
+ ctx->idx++;
+}
+
+/*
+ * Emit an instruction that will be executed unconditionally.
+ */
+static inline void emit(u32 inst, struct jit_ctx *ctx)
+{
+ _emit(ARM_COND_AL, inst, ctx);
+}
+
+static u16 saved_regs(struct jit_ctx *ctx)
+{
+ u16 ret = 0;
+
+ if ((ctx->skf->len > 1) ||
+ (ctx->skf->insns[0].code == (BPF_RET | BPF_A)))
+ ret |= 1 << r_A;
+
+#ifdef CONFIG_FRAME_POINTER
+ ret |= (1 << ARM_FP) | (1 << ARM_IP) | (1 << ARM_LR) | (1 << ARM_PC);
+#else
+ if (ctx->seen & SEEN_CALL)
+ ret |= 1 << ARM_LR;
+#endif
+ if (ctx->seen & (SEEN_DATA | SEEN_SKB))
+ ret |= 1 << r_skb;
+ if (ctx->seen & SEEN_DATA)
+ ret |= (1 << r_skb_data) | (1 << r_skb_hl);
+ if (ctx->seen & SEEN_X)
+ ret |= 1 << r_X;
+
+ return ret;
+}
+
+static inline int mem_words_used(struct jit_ctx *ctx)
+{
+ /* yes, we do waste some stack space IF there are "holes" in the set" */
+ return fls(ctx->seen & SEEN_MEM);
+}
+
+static inline bool is_load_to_a(u16 inst)
+{
+ switch (inst) {
+ case BPF_LD | BPF_W | BPF_LEN:
+ case BPF_LD | BPF_W | BPF_ABS:
+ case BPF_LD | BPF_H | BPF_ABS:
+ case BPF_LD | BPF_B | BPF_ABS:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static void jit_fill_hole(void *area, unsigned int size)
+{
+ u32 *ptr;
+ /* We are guaranteed to have aligned memory. */
+ for (ptr = area; size >= sizeof(u32); size -= sizeof(u32))
+ *ptr++ = __opcode_to_mem_arm(ARM_INST_UDF);
+}
+
+static void build_prologue(struct jit_ctx *ctx)
+{
+ u16 reg_set = saved_regs(ctx);
+ u16 first_inst = ctx->skf->insns[0].code;
+ u16 off;
+
+#ifdef CONFIG_FRAME_POINTER
+ emit(ARM_MOV_R(ARM_IP, ARM_SP), ctx);
+ emit(ARM_PUSH(reg_set), ctx);
+ emit(ARM_SUB_I(ARM_FP, ARM_IP, 4), ctx);
+#else
+ if (reg_set)
+ emit(ARM_PUSH(reg_set), ctx);
+#endif
+
+ if (ctx->seen & (SEEN_DATA | SEEN_SKB))
+ emit(ARM_MOV_R(r_skb, ARM_R0), ctx);
+
+ if (ctx->seen & SEEN_DATA) {
+ off = offsetof(struct sk_buff, data);
+ emit(ARM_LDR_I(r_skb_data, r_skb, off), ctx);
+ /* headlen = len - data_len */
+ off = offsetof(struct sk_buff, len);
+ emit(ARM_LDR_I(r_skb_hl, r_skb, off), ctx);
+ off = offsetof(struct sk_buff, data_len);
+ emit(ARM_LDR_I(r_scratch, r_skb, off), ctx);
+ emit(ARM_SUB_R(r_skb_hl, r_skb_hl, r_scratch), ctx);
+ }
+
+ if (ctx->flags & FLAG_NEED_X_RESET)
+ emit(ARM_MOV_I(r_X, 0), ctx);
+
+ /* do not leak kernel data to userspace */
+ if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst)))
+ emit(ARM_MOV_I(r_A, 0), ctx);
+
+ /* stack space for the BPF_MEM words */
+ if (ctx->seen & SEEN_MEM)
+ emit(ARM_SUB_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx);
+}
+
+static void build_epilogue(struct jit_ctx *ctx)
+{
+ u16 reg_set = saved_regs(ctx);
+
+ if (ctx->seen & SEEN_MEM)
+ emit(ARM_ADD_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx);
+
+ reg_set &= ~(1 << ARM_LR);
+
+#ifdef CONFIG_FRAME_POINTER
+ /* the first instruction of the prologue was: mov ip, sp */
+ reg_set &= ~(1 << ARM_IP);
+ reg_set |= (1 << ARM_SP);
+ emit(ARM_LDM(ARM_SP, reg_set), ctx);
+#else
+ if (reg_set) {
+ if (ctx->seen & SEEN_CALL)
+ reg_set |= 1 << ARM_PC;
+ emit(ARM_POP(reg_set), ctx);
+ }
+
+ if (!(ctx->seen & SEEN_CALL))
+ emit(ARM_BX(ARM_LR), ctx);
+#endif
+}
+
+static int16_t imm8m(u32 x)
+{
+ u32 rot;
+
+ for (rot = 0; rot < 16; rot++)
+ if ((x & ~ror32(0xff, 2 * rot)) == 0)
+ return rol32(x, 2 * rot) | (rot << 8);
+
+ return -1;
+}
+
+#if __LINUX_ARM_ARCH__ < 7
+
+static u16 imm_offset(u32 k, struct jit_ctx *ctx)
+{
+ unsigned i = 0, offset;
+ u16 imm;
+
+ /* on the "fake" run we just count them (duplicates included) */
+ if (ctx->target == NULL) {
+ ctx->imm_count++;
+ return 0;
+ }
+
+ while ((i < ctx->imm_count) && ctx->imms[i]) {
+ if (ctx->imms[i] == k)
+ break;
+ i++;
+ }
+
+ if (ctx->imms[i] == 0)
+ ctx->imms[i] = k;
+
+ /* constants go just after the epilogue */
+ offset = ctx->offsets[ctx->skf->len];
+ offset += ctx->prologue_bytes;
+ offset += ctx->epilogue_bytes;
+ offset += i * 4;
+
+ ctx->target[offset / 4] = k;
+
+ /* PC in ARM mode == address of the instruction + 8 */
+ imm = offset - (8 + ctx->idx * 4);
+
+ if (imm & ~0xfff) {
+ /*
+ * literal pool is too far, signal it into flags. we
+ * can only detect it on the second pass unfortunately.
+ */
+ ctx->flags |= FLAG_IMM_OVERFLOW;
+ return 0;
+ }
+
+ return imm;
+}
+
+#endif /* __LINUX_ARM_ARCH__ */
+
+/*
+ * Move an immediate that's not an imm8m to a core register.
+ */
+static inline void emit_mov_i_no8m(int rd, u32 val, struct jit_ctx *ctx)
+{
+#if __LINUX_ARM_ARCH__ < 7
+ emit(ARM_LDR_I(rd, ARM_PC, imm_offset(val, ctx)), ctx);
+#else
+ emit(ARM_MOVW(rd, val & 0xffff), ctx);
+ if (val > 0xffff)
+ emit(ARM_MOVT(rd, val >> 16), ctx);
+#endif
+}
+
+static inline void emit_mov_i(int rd, u32 val, struct jit_ctx *ctx)
+{
+ int imm12 = imm8m(val);
+
+ if (imm12 >= 0)
+ emit(ARM_MOV_I(rd, imm12), ctx);
+ else
+ emit_mov_i_no8m(rd, val, ctx);
+}
+
+#if __LINUX_ARM_ARCH__ < 6
+
+static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
+{
+ _emit(cond, ARM_LDRB_I(ARM_R3, r_addr, 1), ctx);
+ _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx);
+ _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 3), ctx);
+ _emit(cond, ARM_LSL_I(ARM_R3, ARM_R3, 16), ctx);
+ _emit(cond, ARM_LDRB_I(ARM_R0, r_addr, 2), ctx);
+ _emit(cond, ARM_ORR_S(ARM_R3, ARM_R3, ARM_R1, SRTYPE_LSL, 24), ctx);
+ _emit(cond, ARM_ORR_R(ARM_R3, ARM_R3, ARM_R2), ctx);
+ _emit(cond, ARM_ORR_S(r_res, ARM_R3, ARM_R0, SRTYPE_LSL, 8), ctx);
+}
+
+static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
+{
+ _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx);
+ _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 1), ctx);
+ _emit(cond, ARM_ORR_S(r_res, ARM_R2, ARM_R1, SRTYPE_LSL, 8), ctx);
+}
+
+static inline void emit_swap16(u8 r_dst, u8 r_src, struct jit_ctx *ctx)
+{
+ /* r_dst = (r_src << 8) | (r_src >> 8) */
+ emit(ARM_LSL_I(ARM_R1, r_src, 8), ctx);
+ emit(ARM_ORR_S(r_dst, ARM_R1, r_src, SRTYPE_LSR, 8), ctx);
+
+ /*
+ * we need to mask out the bits set in r_dst[23:16] due to
+ * the first shift instruction.
+ *
+ * note that 0x8ff is the encoded immediate 0x00ff0000.
+ */
+ emit(ARM_BIC_I(r_dst, r_dst, 0x8ff), ctx);
+}
+
+#else /* ARMv6+ */
+
+static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
+{
+ _emit(cond, ARM_LDR_I(r_res, r_addr, 0), ctx);
+#ifdef __LITTLE_ENDIAN
+ _emit(cond, ARM_REV(r_res, r_res), ctx);
+#endif
+}
+
+static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
+{
+ _emit(cond, ARM_LDRH_I(r_res, r_addr, 0), ctx);
+#ifdef __LITTLE_ENDIAN
+ _emit(cond, ARM_REV16(r_res, r_res), ctx);
+#endif
+}
+
+static inline void emit_swap16(u8 r_dst __maybe_unused,
+ u8 r_src __maybe_unused,
+ struct jit_ctx *ctx __maybe_unused)
+{
+#ifdef __LITTLE_ENDIAN
+ emit(ARM_REV16(r_dst, r_src), ctx);
+#endif
+}
+
+#endif /* __LINUX_ARM_ARCH__ < 6 */
+
+
+/* Compute the immediate value for a PC-relative branch. */
+static inline u32 b_imm(unsigned tgt, struct jit_ctx *ctx)
+{
+ u32 imm;
+
+ if (ctx->target == NULL)
+ return 0;
+ /*
+ * BPF allows only forward jumps and the offset of the target is
+ * still the one computed during the first pass.
+ */
+ imm = ctx->offsets[tgt] + ctx->prologue_bytes - (ctx->idx * 4 + 8);
+
+ return imm >> 2;
+}
+
+#define OP_IMM3(op, r1, r2, imm_val, ctx) \
+ do { \
+ imm12 = imm8m(imm_val); \
+ if (imm12 < 0) { \
+ emit_mov_i_no8m(r_scratch, imm_val, ctx); \
+ emit(op ## _R((r1), (r2), r_scratch), ctx); \
+ } else { \
+ emit(op ## _I((r1), (r2), imm12), ctx); \
+ } \
+ } while (0)
+
+static inline void emit_err_ret(u8 cond, struct jit_ctx *ctx)
+{
+ if (ctx->ret0_fp_idx >= 0) {
+ _emit(cond, ARM_B(b_imm(ctx->ret0_fp_idx, ctx)), ctx);
+ /* NOP to keep the size constant between passes */
+ emit(ARM_MOV_R(ARM_R0, ARM_R0), ctx);
+ } else {
+ _emit(cond, ARM_MOV_I(ARM_R0, 0), ctx);
+ _emit(cond, ARM_B(b_imm(ctx->skf->len, ctx)), ctx);
+ }
+}
+
+static inline void emit_blx_r(u8 tgt_reg, struct jit_ctx *ctx)
+{
+#if __LINUX_ARM_ARCH__ < 5
+ emit(ARM_MOV_R(ARM_LR, ARM_PC), ctx);
+
+ if (elf_hwcap & HWCAP_THUMB)
+ emit(ARM_BX(tgt_reg), ctx);
+ else
+ emit(ARM_MOV_R(ARM_PC, tgt_reg), ctx);
+#else
+ emit(ARM_BLX_R(tgt_reg), ctx);
+#endif
+}
+
+static inline void emit_udiv(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx)
+{
+#if __LINUX_ARM_ARCH__ == 7
+ if (elf_hwcap & HWCAP_IDIVA) {
+ emit(ARM_UDIV(rd, rm, rn), ctx);
+ return;
+ }
+#endif
+
+ /*
+ * For BPF_ALU | BPF_DIV | BPF_K instructions, rm is ARM_R4
+ * (r_A) and rn is ARM_R0 (r_scratch) so load rn first into
+ * ARM_R1 to avoid accidentally overwriting ARM_R0 with rm
+ * before using it as a source for ARM_R1.
+ *
+ * For BPF_ALU | BPF_DIV | BPF_X rm is ARM_R4 (r_A) and rn is
+ * ARM_R5 (r_X) so there is no particular register overlap
+ * issues.
+ */
+ if (rn != ARM_R1)
+ emit(ARM_MOV_R(ARM_R1, rn), ctx);
+ if (rm != ARM_R0)
+ emit(ARM_MOV_R(ARM_R0, rm), ctx);
+
+ ctx->seen |= SEEN_CALL;
+ emit_mov_i(ARM_R3, (u32)jit_udiv, ctx);
+ emit_blx_r(ARM_R3, ctx);
+
+ if (rd != ARM_R0)
+ emit(ARM_MOV_R(rd, ARM_R0), ctx);
+}
+
+static inline void update_on_xread(struct jit_ctx *ctx)
+{
+ if (!(ctx->seen & SEEN_X))
+ ctx->flags |= FLAG_NEED_X_RESET;
+
+ ctx->seen |= SEEN_X;
+}
+
+static int build_body(struct jit_ctx *ctx)
+{
+ void *load_func[] = {jit_get_skb_b, jit_get_skb_h, jit_get_skb_w};
+ const struct bpf_prog *prog = ctx->skf;
+ const struct sock_filter *inst;
+ unsigned i, load_order, off, condt;
+ int imm12;
+ u32 k;
+
+ for (i = 0; i < prog->len; i++) {
+ u16 code;
+
+ inst = &(prog->insns[i]);
+ /* K as an immediate value operand */
+ k = inst->k;
+ code = bpf_anc_helper(inst);
+
+ /* compute offsets only in the fake pass */
+ if (ctx->target == NULL)
+ ctx->offsets[i] = ctx->idx * 4;
+
+ switch (code) {
+ case BPF_LD | BPF_IMM:
+ emit_mov_i(r_A, k, ctx);
+ break;
+ case BPF_LD | BPF_W | BPF_LEN:
+ ctx->seen |= SEEN_SKB;
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
+ emit(ARM_LDR_I(r_A, r_skb,
+ offsetof(struct sk_buff, len)), ctx);
+ break;
+ case BPF_LD | BPF_MEM:
+ /* A = scratch[k] */
+ ctx->seen |= SEEN_MEM_WORD(k);
+ emit(ARM_LDR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx);
+ break;
+ case BPF_LD | BPF_W | BPF_ABS:
+ load_order = 2;
+ goto load;
+ case BPF_LD | BPF_H | BPF_ABS:
+ load_order = 1;
+ goto load;
+ case BPF_LD | BPF_B | BPF_ABS:
+ load_order = 0;
+load:
+ /* the interpreter will deal with the negative K */
+ if ((int)k < 0)
+ return -ENOTSUPP;
+ emit_mov_i(r_off, k, ctx);
+load_common:
+ ctx->seen |= SEEN_DATA | SEEN_CALL;
+
+ if (load_order > 0) {
+ emit(ARM_SUB_I(r_scratch, r_skb_hl,
+ 1 << load_order), ctx);
+ emit(ARM_CMP_R(r_scratch, r_off), ctx);
+ condt = ARM_COND_HS;
+ } else {
+ emit(ARM_CMP_R(r_skb_hl, r_off), ctx);
+ condt = ARM_COND_HI;
+ }
+
+ _emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data),
+ ctx);
+
+ if (load_order == 0)
+ _emit(condt, ARM_LDRB_I(r_A, r_scratch, 0),
+ ctx);
+ else if (load_order == 1)
+ emit_load_be16(condt, r_A, r_scratch, ctx);
+ else if (load_order == 2)
+ emit_load_be32(condt, r_A, r_scratch, ctx);
+
+ _emit(condt, ARM_B(b_imm(i + 1, ctx)), ctx);
+
+ /* the slowpath */
+ emit_mov_i(ARM_R3, (u32)load_func[load_order], ctx);
+ emit(ARM_MOV_R(ARM_R0, r_skb), ctx);
+ /* the offset is already in R1 */
+ emit_blx_r(ARM_R3, ctx);
+ /* check the result of skb_copy_bits */
+ emit(ARM_CMP_I(ARM_R1, 0), ctx);
+ emit_err_ret(ARM_COND_NE, ctx);
+ emit(ARM_MOV_R(r_A, ARM_R0), ctx);
+ break;
+ case BPF_LD | BPF_W | BPF_IND:
+ load_order = 2;
+ goto load_ind;
+ case BPF_LD | BPF_H | BPF_IND:
+ load_order = 1;
+ goto load_ind;
+ case BPF_LD | BPF_B | BPF_IND:
+ load_order = 0;
+load_ind:
+ OP_IMM3(ARM_ADD, r_off, r_X, k, ctx);
+ goto load_common;
+ case BPF_LDX | BPF_IMM:
+ ctx->seen |= SEEN_X;
+ emit_mov_i(r_X, k, ctx);
+ break;
+ case BPF_LDX | BPF_W | BPF_LEN:
+ ctx->seen |= SEEN_X | SEEN_SKB;
+ emit(ARM_LDR_I(r_X, r_skb,
+ offsetof(struct sk_buff, len)), ctx);
+ break;
+ case BPF_LDX | BPF_MEM:
+ ctx->seen |= SEEN_X | SEEN_MEM_WORD(k);
+ emit(ARM_LDR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx);
+ break;
+ case BPF_LDX | BPF_B | BPF_MSH:
+ /* x = ((*(frame + k)) & 0xf) << 2; */
+ ctx->seen |= SEEN_X | SEEN_DATA | SEEN_CALL;
+ /* the interpreter should deal with the negative K */
+ if ((int)k < 0)
+ return -1;
+ /* offset in r1: we might have to take the slow path */
+ emit_mov_i(r_off, k, ctx);
+ emit(ARM_CMP_R(r_skb_hl, r_off), ctx);
+
+ /* load in r0: common with the slowpath */
+ _emit(ARM_COND_HI, ARM_LDRB_R(ARM_R0, r_skb_data,
+ ARM_R1), ctx);
+ /*
+ * emit_mov_i() might generate one or two instructions,
+ * the same holds for emit_blx_r()
+ */
+ _emit(ARM_COND_HI, ARM_B(b_imm(i + 1, ctx) - 2), ctx);
+
+ emit(ARM_MOV_R(ARM_R0, r_skb), ctx);
+ /* r_off is r1 */
+ emit_mov_i(ARM_R3, (u32)jit_get_skb_b, ctx);
+ emit_blx_r(ARM_R3, ctx);
+ /* check the return value of skb_copy_bits */
+ emit(ARM_CMP_I(ARM_R1, 0), ctx);
+ emit_err_ret(ARM_COND_NE, ctx);
+
+ emit(ARM_AND_I(r_X, ARM_R0, 0x00f), ctx);
+ emit(ARM_LSL_I(r_X, r_X, 2), ctx);
+ break;
+ case BPF_ST:
+ ctx->seen |= SEEN_MEM_WORD(k);
+ emit(ARM_STR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx);
+ break;
+ case BPF_STX:
+ update_on_xread(ctx);
+ ctx->seen |= SEEN_MEM_WORD(k);
+ emit(ARM_STR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx);
+ break;
+ case BPF_ALU | BPF_ADD | BPF_K:
+ /* A += K */
+ OP_IMM3(ARM_ADD, r_A, r_A, k, ctx);
+ break;
+ case BPF_ALU | BPF_ADD | BPF_X:
+ update_on_xread(ctx);
+ emit(ARM_ADD_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_ALU | BPF_SUB | BPF_K:
+ /* A -= K */
+ OP_IMM3(ARM_SUB, r_A, r_A, k, ctx);
+ break;
+ case BPF_ALU | BPF_SUB | BPF_X:
+ update_on_xread(ctx);
+ emit(ARM_SUB_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_ALU | BPF_MUL | BPF_K:
+ /* A *= K */
+ emit_mov_i(r_scratch, k, ctx);
+ emit(ARM_MUL(r_A, r_A, r_scratch), ctx);
+ break;
+ case BPF_ALU | BPF_MUL | BPF_X:
+ update_on_xread(ctx);
+ emit(ARM_MUL(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_ALU | BPF_DIV | BPF_K:
+ if (k == 1)
+ break;
+ emit_mov_i(r_scratch, k, ctx);
+ emit_udiv(r_A, r_A, r_scratch, ctx);
+ break;
+ case BPF_ALU | BPF_DIV | BPF_X:
+ update_on_xread(ctx);
+ emit(ARM_CMP_I(r_X, 0), ctx);
+ emit_err_ret(ARM_COND_EQ, ctx);
+ emit_udiv(r_A, r_A, r_X, ctx);
+ break;
+ case BPF_ALU | BPF_OR | BPF_K:
+ /* A |= K */
+ OP_IMM3(ARM_ORR, r_A, r_A, k, ctx);
+ break;
+ case BPF_ALU | BPF_OR | BPF_X:
+ update_on_xread(ctx);
+ emit(ARM_ORR_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_ALU | BPF_XOR | BPF_K:
+ /* A ^= K; */
+ OP_IMM3(ARM_EOR, r_A, r_A, k, ctx);
+ break;
+ case BPF_ANC | SKF_AD_ALU_XOR_X:
+ case BPF_ALU | BPF_XOR | BPF_X:
+ /* A ^= X */
+ update_on_xread(ctx);
+ emit(ARM_EOR_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_ALU | BPF_AND | BPF_K:
+ /* A &= K */
+ OP_IMM3(ARM_AND, r_A, r_A, k, ctx);
+ break;
+ case BPF_ALU | BPF_AND | BPF_X:
+ update_on_xread(ctx);
+ emit(ARM_AND_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_ALU | BPF_LSH | BPF_K:
+ if (unlikely(k > 31))
+ return -1;
+ emit(ARM_LSL_I(r_A, r_A, k), ctx);
+ break;
+ case BPF_ALU | BPF_LSH | BPF_X:
+ update_on_xread(ctx);
+ emit(ARM_LSL_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_ALU | BPF_RSH | BPF_K:
+ if (unlikely(k > 31))
+ return -1;
+ emit(ARM_LSR_I(r_A, r_A, k), ctx);
+ break;
+ case BPF_ALU | BPF_RSH | BPF_X:
+ update_on_xread(ctx);
+ emit(ARM_LSR_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_ALU | BPF_NEG:
+ /* A = -A */
+ emit(ARM_RSB_I(r_A, r_A, 0), ctx);
+ break;
+ case BPF_JMP | BPF_JA:
+ /* pc += K */
+ emit(ARM_B(b_imm(i + k + 1, ctx)), ctx);
+ break;
+ case BPF_JMP | BPF_JEQ | BPF_K:
+ /* pc += (A == K) ? pc->jt : pc->jf */
+ condt = ARM_COND_EQ;
+ goto cmp_imm;
+ case BPF_JMP | BPF_JGT | BPF_K:
+ /* pc += (A > K) ? pc->jt : pc->jf */
+ condt = ARM_COND_HI;
+ goto cmp_imm;
+ case BPF_JMP | BPF_JGE | BPF_K:
+ /* pc += (A >= K) ? pc->jt : pc->jf */
+ condt = ARM_COND_HS;
+cmp_imm:
+ imm12 = imm8m(k);
+ if (imm12 < 0) {
+ emit_mov_i_no8m(r_scratch, k, ctx);
+ emit(ARM_CMP_R(r_A, r_scratch), ctx);
+ } else {
+ emit(ARM_CMP_I(r_A, imm12), ctx);
+ }
+cond_jump:
+ if (inst->jt)
+ _emit(condt, ARM_B(b_imm(i + inst->jt + 1,
+ ctx)), ctx);
+ if (inst->jf)
+ _emit(condt ^ 1, ARM_B(b_imm(i + inst->jf + 1,
+ ctx)), ctx);
+ break;
+ case BPF_JMP | BPF_JEQ | BPF_X:
+ /* pc += (A == X) ? pc->jt : pc->jf */
+ condt = ARM_COND_EQ;
+ goto cmp_x;
+ case BPF_JMP | BPF_JGT | BPF_X:
+ /* pc += (A > X) ? pc->jt : pc->jf */
+ condt = ARM_COND_HI;
+ goto cmp_x;
+ case BPF_JMP | BPF_JGE | BPF_X:
+ /* pc += (A >= X) ? pc->jt : pc->jf */
+ condt = ARM_COND_CS;
+cmp_x:
+ update_on_xread(ctx);
+ emit(ARM_CMP_R(r_A, r_X), ctx);
+ goto cond_jump;
+ case BPF_JMP | BPF_JSET | BPF_K:
+ /* pc += (A & K) ? pc->jt : pc->jf */
+ condt = ARM_COND_NE;
+ /* not set iff all zeroes iff Z==1 iff EQ */
+
+ imm12 = imm8m(k);
+ if (imm12 < 0) {
+ emit_mov_i_no8m(r_scratch, k, ctx);
+ emit(ARM_TST_R(r_A, r_scratch), ctx);
+ } else {
+ emit(ARM_TST_I(r_A, imm12), ctx);
+ }
+ goto cond_jump;
+ case BPF_JMP | BPF_JSET | BPF_X:
+ /* pc += (A & X) ? pc->jt : pc->jf */
+ update_on_xread(ctx);
+ condt = ARM_COND_NE;
+ emit(ARM_TST_R(r_A, r_X), ctx);
+ goto cond_jump;
+ case BPF_RET | BPF_A:
+ emit(ARM_MOV_R(ARM_R0, r_A), ctx);
+ goto b_epilogue;
+ case BPF_RET | BPF_K:
+ if ((k == 0) && (ctx->ret0_fp_idx < 0))
+ ctx->ret0_fp_idx = i;
+ emit_mov_i(ARM_R0, k, ctx);
+b_epilogue:
+ if (i != ctx->skf->len - 1)
+ emit(ARM_B(b_imm(prog->len, ctx)), ctx);
+ break;
+ case BPF_MISC | BPF_TAX:
+ /* X = A */
+ ctx->seen |= SEEN_X;
+ emit(ARM_MOV_R(r_X, r_A), ctx);
+ break;
+ case BPF_MISC | BPF_TXA:
+ /* A = X */
+ update_on_xread(ctx);
+ emit(ARM_MOV_R(r_A, r_X), ctx);
+ break;
+ case BPF_ANC | SKF_AD_PROTOCOL:
+ /* A = ntohs(skb->protocol) */
+ ctx->seen |= SEEN_SKB;
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
+ protocol) != 2);
+ off = offsetof(struct sk_buff, protocol);
+ emit(ARM_LDRH_I(r_scratch, r_skb, off), ctx);
+ emit_swap16(r_A, r_scratch, ctx);
+ break;
+ case BPF_ANC | SKF_AD_CPU:
+ /* r_scratch = current_thread_info() */
+ OP_IMM3(ARM_BIC, r_scratch, ARM_SP, THREAD_SIZE - 1, ctx);
+ /* A = current_thread_info()->cpu */
+ BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, cpu) != 4);
+ off = offsetof(struct thread_info, cpu);
+ emit(ARM_LDR_I(r_A, r_scratch, off), ctx);
+ break;
+ case BPF_ANC | SKF_AD_IFINDEX:
+ /* A = skb->dev->ifindex */
+ ctx->seen |= SEEN_SKB;
+ off = offsetof(struct sk_buff, dev);
+ emit(ARM_LDR_I(r_scratch, r_skb, off), ctx);
+
+ emit(ARM_CMP_I(r_scratch, 0), ctx);
+ emit_err_ret(ARM_COND_EQ, ctx);
+
+ BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
+ ifindex) != 4);
+ off = offsetof(struct net_device, ifindex);
+ emit(ARM_LDR_I(r_A, r_scratch, off), ctx);
+ break;
+ case BPF_ANC | SKF_AD_MARK:
+ ctx->seen |= SEEN_SKB;
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
+ off = offsetof(struct sk_buff, mark);
+ emit(ARM_LDR_I(r_A, r_skb, off), ctx);
+ break;
+ case BPF_ANC | SKF_AD_RXHASH:
+ ctx->seen |= SEEN_SKB;
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4);
+ off = offsetof(struct sk_buff, hash);
+ emit(ARM_LDR_I(r_A, r_skb, off), ctx);
+ break;
+ case BPF_ANC | SKF_AD_VLAN_TAG:
+ case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT:
+ ctx->seen |= SEEN_SKB;
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2);
+ off = offsetof(struct sk_buff, vlan_tci);
+ emit(ARM_LDRH_I(r_A, r_skb, off), ctx);
+ if (code == (BPF_ANC | SKF_AD_VLAN_TAG))
+ OP_IMM3(ARM_AND, r_A, r_A, VLAN_VID_MASK, ctx);
+ else
+ OP_IMM3(ARM_AND, r_A, r_A, VLAN_TAG_PRESENT, ctx);
+ break;
+ case BPF_ANC | SKF_AD_QUEUE:
+ ctx->seen |= SEEN_SKB;
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
+ queue_mapping) != 2);
+ BUILD_BUG_ON(offsetof(struct sk_buff,
+ queue_mapping) > 0xff);
+ off = offsetof(struct sk_buff, queue_mapping);
+ emit(ARM_LDRH_I(r_A, r_skb, off), ctx);
+ break;
+ default:
+ return -1;
+ }
+
+ if (ctx->flags & FLAG_IMM_OVERFLOW)
+ /*
+ * this instruction generated an overflow when
+ * trying to access the literal pool, so
+ * delegate this filter to the kernel interpreter.
+ */
+ return -1;
+ }
+
+ /* compute offsets only during the first pass */
+ if (ctx->target == NULL)
+ ctx->offsets[i] = ctx->idx * 4;
+
+ return 0;
+}
+
+
+void bpf_jit_compile(struct bpf_prog *fp)
+{
+ struct bpf_binary_header *header;
+ struct jit_ctx ctx;
+ unsigned tmp_idx;
+ unsigned alloc_size;
+ u8 *target_ptr;
+
+ if (!bpf_jit_enable)
+ return;
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.skf = fp;
+ ctx.ret0_fp_idx = -1;
+
+ ctx.offsets = kzalloc(4 * (ctx.skf->len + 1), GFP_KERNEL);
+ if (ctx.offsets == NULL)
+ return;
+
+ /* fake pass to fill in the ctx->seen */
+ if (unlikely(build_body(&ctx)))
+ goto out;
+
+ tmp_idx = ctx.idx;
+ build_prologue(&ctx);
+ ctx.prologue_bytes = (ctx.idx - tmp_idx) * 4;
+
+#if __LINUX_ARM_ARCH__ < 7
+ tmp_idx = ctx.idx;
+ build_epilogue(&ctx);
+ ctx.epilogue_bytes = (ctx.idx - tmp_idx) * 4;
+
+ ctx.idx += ctx.imm_count;
+ if (ctx.imm_count) {
+ ctx.imms = kzalloc(4 * ctx.imm_count, GFP_KERNEL);
+ if (ctx.imms == NULL)
+ goto out;
+ }
+#else
+ /* there's nothing after the epilogue on ARMv7 */
+ build_epilogue(&ctx);
+#endif
+ alloc_size = 4 * ctx.idx;
+ header = bpf_jit_binary_alloc(alloc_size, &target_ptr,
+ 4, jit_fill_hole);
+ if (header == NULL)
+ goto out;
+
+ ctx.target = (u32 *) target_ptr;
+ ctx.idx = 0;
+
+ build_prologue(&ctx);
+ if (build_body(&ctx) < 0) {
+#if __LINUX_ARM_ARCH__ < 7
+ if (ctx.imm_count)
+ kfree(ctx.imms);
+#endif
+ bpf_jit_binary_free(header);
+ goto out;
+ }
+ build_epilogue(&ctx);
+
+ flush_icache_range((u32)ctx.target, (u32)(ctx.target + ctx.idx));
+
+#if __LINUX_ARM_ARCH__ < 7
+ if (ctx.imm_count)
+ kfree(ctx.imms);
+#endif
+
+ if (bpf_jit_enable > 1)
+ /* there are 2 passes here */
+ bpf_jit_dump(fp->len, alloc_size, 2, ctx.target);
+
+ set_memory_ro((unsigned long)header, header->pages);
+ fp->bpf_func = (void *)ctx.target;
+ fp->jited = true;
+out:
+ kfree(ctx.offsets);
+ return;
+}
+
+void bpf_jit_free(struct bpf_prog *fp)
+{
+ unsigned long addr = (unsigned long)fp->bpf_func & PAGE_MASK;
+ struct bpf_binary_header *header = (void *)addr;
+
+ if (!fp->jited)
+ goto free_filter;
+
+ set_memory_rw(addr, header->pages);
+ bpf_jit_binary_free(header);
+
+free_filter:
+ bpf_prog_unlock_free(fp);
+}
diff --git a/arch/arm/net/bpf_jit_32.h b/arch/arm/net/bpf_jit_32.h
new file mode 100644
index 000000000..b2d7d9285
--- /dev/null
+++ b/arch/arm/net/bpf_jit_32.h
@@ -0,0 +1,210 @@
+/*
+ * Just-In-Time compiler for BPF filters on 32bit ARM
+ *
+ * Copyright (c) 2011 Mircea Gherzan <mgherzan@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 PFILTER_OPCODES_ARM_H
+#define PFILTER_OPCODES_ARM_H
+
+#define ARM_R0 0
+#define ARM_R1 1
+#define ARM_R2 2
+#define ARM_R3 3
+#define ARM_R4 4
+#define ARM_R5 5
+#define ARM_R6 6
+#define ARM_R7 7
+#define ARM_R8 8
+#define ARM_R9 9
+#define ARM_R10 10
+#define ARM_FP 11
+#define ARM_IP 12
+#define ARM_SP 13
+#define ARM_LR 14
+#define ARM_PC 15
+
+#define ARM_COND_EQ 0x0
+#define ARM_COND_NE 0x1
+#define ARM_COND_CS 0x2
+#define ARM_COND_HS ARM_COND_CS
+#define ARM_COND_CC 0x3
+#define ARM_COND_LO ARM_COND_CC
+#define ARM_COND_MI 0x4
+#define ARM_COND_PL 0x5
+#define ARM_COND_VS 0x6
+#define ARM_COND_VC 0x7
+#define ARM_COND_HI 0x8
+#define ARM_COND_LS 0x9
+#define ARM_COND_GE 0xa
+#define ARM_COND_LT 0xb
+#define ARM_COND_GT 0xc
+#define ARM_COND_LE 0xd
+#define ARM_COND_AL 0xe
+
+/* register shift types */
+#define SRTYPE_LSL 0
+#define SRTYPE_LSR 1
+#define SRTYPE_ASR 2
+#define SRTYPE_ROR 3
+
+#define ARM_INST_ADD_R 0x00800000
+#define ARM_INST_ADD_I 0x02800000
+
+#define ARM_INST_AND_R 0x00000000
+#define ARM_INST_AND_I 0x02000000
+
+#define ARM_INST_BIC_R 0x01c00000
+#define ARM_INST_BIC_I 0x03c00000
+
+#define ARM_INST_B 0x0a000000
+#define ARM_INST_BX 0x012FFF10
+#define ARM_INST_BLX_R 0x012fff30
+
+#define ARM_INST_CMP_R 0x01500000
+#define ARM_INST_CMP_I 0x03500000
+
+#define ARM_INST_EOR_R 0x00200000
+#define ARM_INST_EOR_I 0x02200000
+
+#define ARM_INST_LDRB_I 0x05d00000
+#define ARM_INST_LDRB_R 0x07d00000
+#define ARM_INST_LDRH_I 0x01d000b0
+#define ARM_INST_LDR_I 0x05900000
+
+#define ARM_INST_LDM 0x08900000
+
+#define ARM_INST_LSL_I 0x01a00000
+#define ARM_INST_LSL_R 0x01a00010
+
+#define ARM_INST_LSR_I 0x01a00020
+#define ARM_INST_LSR_R 0x01a00030
+
+#define ARM_INST_MOV_R 0x01a00000
+#define ARM_INST_MOV_I 0x03a00000
+#define ARM_INST_MOVW 0x03000000
+#define ARM_INST_MOVT 0x03400000
+
+#define ARM_INST_MUL 0x00000090
+
+#define ARM_INST_POP 0x08bd0000
+#define ARM_INST_PUSH 0x092d0000
+
+#define ARM_INST_ORR_R 0x01800000
+#define ARM_INST_ORR_I 0x03800000
+
+#define ARM_INST_REV 0x06bf0f30
+#define ARM_INST_REV16 0x06bf0fb0
+
+#define ARM_INST_RSB_I 0x02600000
+
+#define ARM_INST_SUB_R 0x00400000
+#define ARM_INST_SUB_I 0x02400000
+
+#define ARM_INST_STR_I 0x05800000
+
+#define ARM_INST_TST_R 0x01100000
+#define ARM_INST_TST_I 0x03100000
+
+#define ARM_INST_UDIV 0x0730f010
+
+#define ARM_INST_UMULL 0x00800090
+
+/*
+ * Use a suitable undefined instruction to use for ARM/Thumb2 faulting.
+ * We need to be careful not to conflict with those used by other modules
+ * (BUG, kprobes, etc) and the register_undef_hook() system.
+ *
+ * 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 ARMv7-AR, section A5.4
+ * Thumb: 1101 1110 xxxx xxxx ARMv7-M, section A5.2.6
+ */
+#define ARM_INST_UDF 0xe7fddef1
+
+/* register */
+#define _AL3_R(op, rd, rn, rm) ((op ## _R) | (rd) << 12 | (rn) << 16 | (rm))
+/* immediate */
+#define _AL3_I(op, rd, rn, imm) ((op ## _I) | (rd) << 12 | (rn) << 16 | (imm))
+
+#define ARM_ADD_R(rd, rn, rm) _AL3_R(ARM_INST_ADD, rd, rn, rm)
+#define ARM_ADD_I(rd, rn, imm) _AL3_I(ARM_INST_ADD, rd, rn, imm)
+
+#define ARM_AND_R(rd, rn, rm) _AL3_R(ARM_INST_AND, rd, rn, rm)
+#define ARM_AND_I(rd, rn, imm) _AL3_I(ARM_INST_AND, rd, rn, imm)
+
+#define ARM_BIC_R(rd, rn, rm) _AL3_R(ARM_INST_BIC, rd, rn, rm)
+#define ARM_BIC_I(rd, rn, imm) _AL3_I(ARM_INST_BIC, rd, rn, imm)
+
+#define ARM_B(imm24) (ARM_INST_B | ((imm24) & 0xffffff))
+#define ARM_BX(rm) (ARM_INST_BX | (rm))
+#define ARM_BLX_R(rm) (ARM_INST_BLX_R | (rm))
+
+#define ARM_CMP_R(rn, rm) _AL3_R(ARM_INST_CMP, 0, rn, rm)
+#define ARM_CMP_I(rn, imm) _AL3_I(ARM_INST_CMP, 0, rn, imm)
+
+#define ARM_EOR_R(rd, rn, rm) _AL3_R(ARM_INST_EOR, rd, rn, rm)
+#define ARM_EOR_I(rd, rn, imm) _AL3_I(ARM_INST_EOR, rd, rn, imm)
+
+#define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \
+ | (off))
+#define ARM_LDRB_I(rt, rn, off) (ARM_INST_LDRB_I | (rt) << 12 | (rn) << 16 \
+ | (off))
+#define ARM_LDRB_R(rt, rn, rm) (ARM_INST_LDRB_R | (rt) << 12 | (rn) << 16 \
+ | (rm))
+#define ARM_LDRH_I(rt, rn, off) (ARM_INST_LDRH_I | (rt) << 12 | (rn) << 16 \
+ | (((off) & 0xf0) << 4) | ((off) & 0xf))
+
+#define ARM_LDM(rn, regs) (ARM_INST_LDM | (rn) << 16 | (regs))
+
+#define ARM_LSL_R(rd, rn, rm) (_AL3_R(ARM_INST_LSL, rd, 0, rn) | (rm) << 8)
+#define ARM_LSL_I(rd, rn, imm) (_AL3_I(ARM_INST_LSL, rd, 0, rn) | (imm) << 7)
+
+#define ARM_LSR_R(rd, rn, rm) (_AL3_R(ARM_INST_LSR, rd, 0, rn) | (rm) << 8)
+#define ARM_LSR_I(rd, rn, imm) (_AL3_I(ARM_INST_LSR, rd, 0, rn) | (imm) << 7)
+
+#define ARM_MOV_R(rd, rm) _AL3_R(ARM_INST_MOV, rd, 0, rm)
+#define ARM_MOV_I(rd, imm) _AL3_I(ARM_INST_MOV, rd, 0, imm)
+
+#define ARM_MOVW(rd, imm) \
+ (ARM_INST_MOVW | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff))
+
+#define ARM_MOVT(rd, imm) \
+ (ARM_INST_MOVT | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff))
+
+#define ARM_MUL(rd, rm, rn) (ARM_INST_MUL | (rd) << 16 | (rm) << 8 | (rn))
+
+#define ARM_POP(regs) (ARM_INST_POP | (regs))
+#define ARM_PUSH(regs) (ARM_INST_PUSH | (regs))
+
+#define ARM_ORR_R(rd, rn, rm) _AL3_R(ARM_INST_ORR, rd, rn, rm)
+#define ARM_ORR_I(rd, rn, imm) _AL3_I(ARM_INST_ORR, rd, rn, imm)
+#define ARM_ORR_S(rd, rn, rm, type, rs) \
+ (ARM_ORR_R(rd, rn, rm) | (type) << 5 | (rs) << 7)
+
+#define ARM_REV(rd, rm) (ARM_INST_REV | (rd) << 12 | (rm))
+#define ARM_REV16(rd, rm) (ARM_INST_REV16 | (rd) << 12 | (rm))
+
+#define ARM_RSB_I(rd, rn, imm) _AL3_I(ARM_INST_RSB, rd, rn, imm)
+
+#define ARM_SUB_R(rd, rn, rm) _AL3_R(ARM_INST_SUB, rd, rn, rm)
+#define ARM_SUB_I(rd, rn, imm) _AL3_I(ARM_INST_SUB, rd, rn, imm)
+
+#define ARM_STR_I(rt, rn, off) (ARM_INST_STR_I | (rt) << 12 | (rn) << 16 \
+ | (off))
+
+#define ARM_TST_R(rn, rm) _AL3_R(ARM_INST_TST, 0, rn, rm)
+#define ARM_TST_I(rn, imm) _AL3_I(ARM_INST_TST, 0, rn, imm)
+
+#define ARM_UDIV(rd, rn, rm) (ARM_INST_UDIV | (rd) << 16 | (rn) | (rm) << 8)
+
+#define ARM_UMULL(rd_lo, rd_hi, rn, rm) (ARM_INST_UMULL | (rd_hi) << 16 \
+ | (rd_lo) << 12 | (rm) << 8 | rn)
+
+#endif /* PFILTER_OPCODES_ARM_H */
diff --git a/arch/arm/nwfpe/ARM-gcc.h b/arch/arm/nwfpe/ARM-gcc.h
new file mode 100644
index 000000000..436e54aa0
--- /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 000000000..fa8028b1e
--- /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 000000000..deb3a82dd
--- /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 000000000..c51d1386a
--- /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 000000000..71df43547
--- /dev/null
+++ b/arch/arm/nwfpe/entry.S
@@ -0,0 +1,124 @@
+/*
+ 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.
+*/
+#include <asm/assembler.h>
+#include <asm/opcodes.h>
+
+/* 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 arm_check_condition @ check the condition
+ cmp r0, #ARM_OPCODE_CONDTEST_PASS @ condition passed?
+
+ @ if condition code failed to match, next insn
+ bne next @ get the next instruction;
+
+ mov r0, r6 @ prepare for EmulateAll()
+ bl EmulateAll @ emulate the instruction
+ cmp r0, #0 @ was emulation successful
+ reteq 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
+ retne 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 .text.fixup,"ax"
+ .align 2
+.Lfix: ret 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 000000000..65a279ba9
--- /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 000000000..2782ebcc2
--- /dev/null
+++ b/arch/arm/nwfpe/fpa11.c
@@ -0,0 +1,128 @@
+/*
+ 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>
+
+/* 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 000000000..d3a6f9298
--- /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 000000000..ab8d68262
--- /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 000000000..2cebb1529
--- /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 000000000..d31c49f95
--- /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 000000000..31c4eeec1
--- /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 000000000..ec717c190
--- /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)) {
+ pr_err("nwfpe: bad structure size\n");
+ return -EINVAL;
+ }
+
+ if (sizeof(FPREG) != 12) {
+ pr_err("nwfpe: bad register size\n");
+ return -EINVAL;
+ }
+ if (fpe_type[0] && strcmp(fpe_type, "nwfpe"))
+ return 0;
+
+ /* Display title, version and copyright information. */
+ pr_info("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 %pf 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 000000000..5c2e8e485
--- /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 000000000..2c39ad408
--- /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 000000000..ff9834673
--- /dev/null
+++ b/arch/arm/nwfpe/fpopcode.c
@@ -0,0 +1,63 @@
+/*
+ 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 */
+};
+
diff --git a/arch/arm/nwfpe/fpopcode.h b/arch/arm/nwfpe/fpopcode.h
new file mode 100644
index 000000000..78f02dbfa
--- /dev/null
+++ b/arch/arm/nwfpe/fpopcode.h
@@ -0,0 +1,481 @@
+/*
+ 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 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 000000000..bd425dc13
--- /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 000000000..09a4f2dde
--- /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 000000000..c66981d68
--- /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 000000000..cf2a61731
--- /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 000000000..679a0269d
--- /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 000000000..ffa6b4387
--- /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 000000000..df4d243a2
--- /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 000000000..b2215c61c
--- /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 000000000..cc649a1e4
--- /dev/null
+++ b/arch/arm/oprofile/common.c
@@ -0,0 +1,132 @@
+/**
+ * @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
+
+/*
+ * OProfile has a curious naming scheme for the ARM PMUs, but they are
+ * part of the user ABI so we need to map from the perf PMU name for
+ * supported PMUs.
+ */
+static struct op_perf_name {
+ char *perf_name;
+ char *op_name;
+} op_perf_name_map[] = {
+ { "armv5_xscale1", "arm/xscale1" },
+ { "armv5_xscale2", "arm/xscale2" },
+ { "armv6_1136", "arm/armv6" },
+ { "armv6_1156", "arm/armv6" },
+ { "armv6_1176", "arm/armv6" },
+ { "armv6_11mpcore", "arm/mpcore" },
+ { "armv7_cortex_a8", "arm/armv7" },
+ { "armv7_cortex_a9", "arm/armv7-ca9" },
+};
+
+char *op_name_from_perf_id(void)
+{
+ int i;
+ struct op_perf_name names;
+ const char *perf_name = perf_pmu_name();
+
+ for (i = 0; i < ARRAY_SIZE(op_perf_name_map); ++i) {
+ names = op_perf_name_map[i];
+ if (!strcmp(names.perf_name, perf_name))
+ return names.op_name;
+ }
+
+ 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;
+ arm_get_current_stackframe(regs, &frame);
+ 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 000000000..f2af203d6
--- /dev/null
+++ b/arch/arm/plat-iop/Makefile
@@ -0,0 +1,27 @@
+#
+# Makefile for the linux kernel.
+#
+
+# IOP32X
+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) += cp6.o
+obj-$(CONFIG_ARCH_IOP32X) += adma.o
+obj-$(CONFIG_ARCH_IOP32X) += pmu.o
+obj-$(CONFIG_ARCH_IOP32X) += restart.o
+
+# IOP33X
+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) += cp6.o
+obj-$(CONFIG_ARCH_IOP33X) += adma.o
+obj-$(CONFIG_ARCH_IOP33X) += pmu.o
+obj-$(CONFIG_ARCH_IOP33X) += restart.o
+
+# IOP13XX
+obj-$(CONFIG_ARCH_IOP13XX) += cp6.o
+obj-$(CONFIG_ARCH_IOP13XX) += time.o
diff --git a/arch/arm/plat-iop/adma.c b/arch/arm/plat-iop/adma.c
new file mode 100644
index 000000000..a4d1f8de3
--- /dev/null
+++ b/arch/arm/plat-iop/adma.c
@@ -0,0 +1,205 @@
+/*
+ * 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_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_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 000000000..bab73e2c7
--- /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/i2c.c b/arch/arm/plat-iop/i2c.c
new file mode 100644
index 000000000..88215ad03
--- /dev/null
+++ b/arch/arm/plat-iop/i2c.c
@@ -0,0 +1,79 @@
+/*
+ * 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/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/pci.c b/arch/arm/plat-iop/pci.c
new file mode 100644
index 000000000..362474b5c
--- /dev/null
+++ b/arch/arm/plat-iop/pci.c
@@ -0,0 +1,404 @@
+/*
+ * 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 <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;
+}
+
+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(sizeof(struct resource), GFP_KERNEL);
+ if (!res)
+ panic("PCI: unable to alloc resources");
+
+ res->start = IOP3XX_PCI_LOWER_MEM_PA;
+ res->end = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE - 1;
+ res->name = "IOP3XX PCI Memory Space";
+ res->flags = IORESOURCE_MEM;
+ request_resource(&iomem_resource, res);
+
+ /*
+ * Use whatever translation is already setup.
+ */
+ sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - *IOP3XX_OMWTVR0;
+
+ pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
+
+ pci_ioremap_io(0, IOP3XX_PCI_LOWER_IO_PA);
+
+ return 1;
+}
+
+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)
+{
+ pcibios_min_mem = 0;
+
+ 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 000000000..c6d979ace
--- /dev/null
+++ b/arch/arm/plat-iop/pmu.c
@@ -0,0 +1,39 @@
+/*
+ * 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 <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 = "xscale-pmu",
+ .id = -1,
+ .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/restart.c b/arch/arm/plat-iop/restart.c
new file mode 100644
index 000000000..3a4d5e5fd
--- /dev/null
+++ b/arch/arm/plat-iop/restart.c
@@ -0,0 +1,20 @@
+/*
+ * restart.c
+ *
+ * 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>
+#include <asm/system_misc.h>
+#include <mach/hardware.h>
+
+void iop3xx_restart(enum reboot_mode mode, const char *cmd)
+{
+ *IOP3XX_PCSR = 0x30;
+
+ /* Jump into ROM at address 0 */
+ soft_restart(0);
+}
diff --git a/arch/arm/plat-iop/setup.c b/arch/arm/plat-iop/setup.c
new file mode 100644
index 000000000..5b217f460
--- /dev/null
+++ b/arch/arm/plat-iop/setup.c
@@ -0,0 +1,34 @@
+/*
+ * 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,
+ },
+};
+
+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 000000000..6ad65d8ae
--- /dev/null
+++ b/arch/arm/plat-iop/time.c
@@ -0,0 +1,170 @@
+/*
+ * 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/io.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/export.h>
+#include <linux/sched_clock.h>
+#include <mach/hardware.h>
+#include <asm/irq.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,
+};
+
+/*
+ * IOP sched_clock() implementation via its clocksource.
+ */
+static u64 notrace iop_read_sched_clock(void)
+{
+ return 0xffffffffu - read_tcr1();
+}
+
+/*
+ * 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_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;
+
+ sched_clock_register(iop_read_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);
+ iop_clockevent.cpumask = cpumask_of(0);
+ clockevents_config_and_register(&iop_clockevent, tick_rate,
+ 0xf, 0xfffffffe);
+
+ /*
+ * 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-omap/Kconfig b/arch/arm/plat-omap/Kconfig
new file mode 100644
index 000000000..d055db32f
--- /dev/null
+++ b/arch/arm/plat-omap/Kconfig
@@ -0,0 +1,161 @@
+config ARCH_OMAP
+ bool
+
+if ARCH_OMAP
+
+menu "TI OMAP Common Features"
+
+config ARCH_OMAP_OTG
+ bool
+
+comment "OMAP Feature Selections"
+
+config OMAP_DEBUG_DEVICES
+ bool
+ help
+ For debug cards on TI reference boards.
+
+config OMAP_DEBUG_LEDS
+ def_bool y if NEW_LEDS
+ depends on OMAP_DEBUG_DEVICES
+ select LEDS_CLASS
+
+config POWER_AVS_OMAP
+ bool "AVS(Adaptive Voltage Scaling) support for OMAP IP versions 1&2"
+ depends on POWER_AVS && (ARCH_OMAP3 || ARCH_OMAP4) && PM
+ select POWER_SUPPLY
+ help
+ Say Y to enable AVS(Adaptive Voltage Scaling)
+ support on OMAP containing the version 1 or
+ version 2 of the SmartReflex IP.
+ V1 is the 65nm version used in OMAP3430.
+ V2 is the update for the 45nm version of the IP used in OMAP3630
+ and OMAP4430
+
+ Please note, that by default SmartReflex is only
+ initialized and not enabled. To enable the automatic voltage
+ compensation for vdd mpu and vdd core from user space,
+ user must write 1 to
+ /debug/smartreflex/sr_<X>/autocomp,
+ where X is mpu_iva 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 POWER_AVS_OMAP_CLASS3
+ bool "Class 3 mode of Smartreflex Implementation"
+ depends on POWER_AVS_OMAP && 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_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, OMAP4/5 and DRA7XX.
+
+ On OMAP2PLUS this value is only used for CONFIG_HZ and
+ CLOCK_TICK_RATE compile time calculation.
+ The actual timer selection is done in the board file
+ through the (DT_)MACHINE_START structure.
+
+
+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_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_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 000000000..97a50e888
--- /dev/null
+++ b/arch/arm/plat-omap/Makefile
@@ -0,0 +1,16 @@
+#
+# Makefile for the linux kernel.
+#
+
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/plat-omap/include
+
+# Common support
+obj-y := sram.o dma.o counter_32k.o
+
+# omap_device support (OMAP2+ only at the moment)
+
+obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
+obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
+i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o
+obj-y += $(i2c-omap-m) $(i2c-omap-y)
+
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
new file mode 100644
index 000000000..2438b9600
--- /dev/null
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -0,0 +1,117 @@
+/*
+ * 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/clocksource.h>
+#include <linux/sched_clock.h>
+
+#include <asm/mach/time.h>
+
+#include <plat/counter-32k.h>
+
+/* OMAP2_32KSYNCNT_CR_OFF: offset of 32ksync counter register */
+#define OMAP2_32KSYNCNT_REV_OFF 0x0
+#define OMAP2_32KSYNCNT_REV_SCHEME (0x3 << 30)
+#define OMAP2_32KSYNCNT_CR_OFF_LOW 0x10
+#define OMAP2_32KSYNCNT_CR_OFF_HIGH 0x30
+
+/*
+ * 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.
+ */
+static void __iomem *sync32k_cnt_reg;
+
+static u64 notrace omap_32k_read_sched_clock(void)
+{
+ return sync32k_cnt_reg ? readl_relaxed(sync32k_cnt_reg) : 0;
+}
+
+/**
+ * omap_read_persistent_clock64 - 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 timespec64.
+ */
+static struct timespec64 persistent_ts;
+static cycles_t cycles;
+static unsigned int persistent_mult, persistent_shift;
+
+static void omap_read_persistent_clock64(struct timespec64 *ts)
+{
+ unsigned long long nsecs;
+ cycles_t last_cycles;
+
+ last_cycles = cycles;
+ cycles = sync32k_cnt_reg ? readl_relaxed(sync32k_cnt_reg) : 0;
+
+ nsecs = clocksource_cyc2ns(cycles - last_cycles,
+ persistent_mult, persistent_shift);
+
+ timespec64_add_ns(&persistent_ts, nsecs);
+
+ *ts = persistent_ts;
+}
+
+/**
+ * omap_init_clocksource_32k - setup and register counter 32k as a
+ * kernel clocksource
+ * @pbase: base addr of counter_32k module
+ * @size: size of counter_32k to map
+ *
+ * Returns 0 upon success or negative error code upon failure.
+ *
+ */
+int __init omap_init_clocksource_32k(void __iomem *vbase)
+{
+ int ret;
+
+ /*
+ * 32k sync Counter IP register offsets vary between the
+ * highlander version and the legacy ones.
+ * The 'SCHEME' bits(30-31) of the revision register is used
+ * to identify the version.
+ */
+ if (readl_relaxed(vbase + OMAP2_32KSYNCNT_REV_OFF) &
+ OMAP2_32KSYNCNT_REV_SCHEME)
+ sync32k_cnt_reg = vbase + OMAP2_32KSYNCNT_CR_OFF_HIGH;
+ else
+ sync32k_cnt_reg = vbase + OMAP2_32KSYNCNT_CR_OFF_LOW;
+
+ /*
+ * 120000 rough estimate from the calculations in
+ * __clocksource_update_freq_scale.
+ */
+ clocks_calc_mult_shift(&persistent_mult, &persistent_shift,
+ 32768, NSEC_PER_SEC, 120000);
+
+ ret = clocksource_mmio_init(sync32k_cnt_reg, "32k_counter", 32768,
+ 250, 32, clocksource_mmio_readl_up);
+ if (ret) {
+ pr_err("32k_counter: can't register clocksource\n");
+ return ret;
+ }
+
+ sched_clock_register(omap_32k_read_sched_clock, 32, 32768);
+ register_persistent_clock(NULL, omap_read_persistent_clock64);
+ pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n");
+
+ return 0;
+}
diff --git a/arch/arm/plat-omap/debug-leds.c b/arch/arm/plat-omap/debug-leds.c
new file mode 100644
index 000000000..48b69de89
--- /dev/null
+++ b/arch/arm/plat-omap/debug-leds.c
@@ -0,0 +1,174 @@
+/*
+ * linux/arch/arm/plat-omap/debug-leds.c
+ *
+ * Copyright 2011 by Bryan Wu <bryan.wu@canonical.com>
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/io.h>
+#include <linux/platform_data/gpio-omap.h>
+#include <linux/slab.h>
+
+#include <asm/mach-types.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.
+ */
+
+/* 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 ... */
+};
+
+static struct h2p2_dbg_fpga __iomem *fpga;
+
+static u16 fpga_led_state;
+
+struct dbg_led {
+ struct led_classdev cdev;
+ u16 mask;
+};
+
+static const struct {
+ const char *name;
+ const char *trigger;
+} dbg_leds[] = {
+ { "dbg:d4", "heartbeat", },
+ { "dbg:d5", "cpu0", },
+ { "dbg:d6", "default-on", },
+ { "dbg:d7", },
+ { "dbg:d8", },
+ { "dbg:d9", },
+ { "dbg:d10", },
+ { "dbg:d11", },
+ { "dbg:d12", },
+ { "dbg:d13", },
+ { "dbg:d14", },
+ { "dbg:d15", },
+ { "dbg:d16", },
+ { "dbg:d17", },
+ { "dbg:d18", },
+ { "dbg:d19", },
+};
+
+/*
+ * The triggers lines up below will only be used if the
+ * LED triggers are compiled in.
+ */
+static void dbg_led_set(struct led_classdev *cdev,
+ enum led_brightness b)
+{
+ struct dbg_led *led = container_of(cdev, struct dbg_led, cdev);
+ u16 reg;
+
+ reg = readw_relaxed(&fpga->leds);
+ if (b != LED_OFF)
+ reg |= led->mask;
+ else
+ reg &= ~led->mask;
+ writew_relaxed(reg, &fpga->leds);
+}
+
+static enum led_brightness dbg_led_get(struct led_classdev *cdev)
+{
+ struct dbg_led *led = container_of(cdev, struct dbg_led, cdev);
+ u16 reg;
+
+ reg = readw_relaxed(&fpga->leds);
+ return (reg & led->mask) ? LED_FULL : LED_OFF;
+}
+
+static int fpga_probe(struct platform_device *pdev)
+{
+ struct resource *iomem;
+ int i;
+
+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!iomem)
+ return -ENODEV;
+
+ fpga = ioremap(iomem->start, resource_size(iomem));
+ writew_relaxed(0xff, &fpga->leds);
+
+ for (i = 0; i < ARRAY_SIZE(dbg_leds); i++) {
+ struct dbg_led *led;
+
+ led = kzalloc(sizeof(*led), GFP_KERNEL);
+ if (!led)
+ break;
+
+ led->cdev.name = dbg_leds[i].name;
+ led->cdev.brightness_set = dbg_led_set;
+ led->cdev.brightness_get = dbg_led_get;
+ led->cdev.default_trigger = dbg_leds[i].trigger;
+ led->mask = BIT(i);
+
+ if (led_classdev_register(NULL, &led->cdev) < 0) {
+ kfree(led);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int fpga_suspend_noirq(struct device *dev)
+{
+ fpga_led_state = readw_relaxed(&fpga->leds);
+ writew_relaxed(0xff, &fpga->leds);
+
+ return 0;
+}
+
+static int fpga_resume_noirq(struct device *dev)
+{
+ writew_relaxed(~fpga_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/dma.c b/arch/arm/plat-omap/dma.c
new file mode 100644
index 000000000..6416e03b4
--- /dev/null
+++ b/arch/arm/plat-omap/dma.c
@@ -0,0 +1,1466 @@
+/*
+ * 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 <linux/omap-dma.h>
+
+/*
+ * MAX_LOGICAL_DMA_CH_COUNT: the maximum number of logical DMA
+ * channels that an instance of the SDMA IP block can support. Used
+ * to size arrays. (The actual maximum on a particular SoC may be less
+ * than this -- for example, OMAP1 SDMA instances only support 17 logical
+ * DMA channels.)
+ */
+#define MAX_LOGICAL_DMA_CH_COUNT 32
+
+#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 void omap_clear_dma(int lch);
+static int omap_dma_set_prio_lch(int lch, unsigned char read_prio,
+ unsigned char write_prio);
+static int enable_1510_mode;
+static u32 errata;
+
+static struct omap_dma_global_context_registers {
+ u32 dma_irqenable_l0;
+ u32 dma_irqenable_l1;
+ 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 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)
+#define omap_readl(reg) 0
+#define omap_writel(val, reg) do {} while (0)
+#endif
+
+#ifdef CONFIG_ARCH_OMAP1
+void omap_set_dma_priority(int lch, int dst_port, int priority)
+{
+ unsigned long reg;
+ u32 l;
+
+ if (dma_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);
+ }
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2PLUS
+void omap_set_dma_priority(int lch, int dst_port, int priority)
+{
+ u32 ccr;
+
+ ccr = p->dma_read(CCR, lch);
+ if (priority)
+ ccr |= (1 << 6);
+ else
+ ccr &= ~(1 << 6);
+ p->dma_write(ccr, CCR, lch);
+}
+#endif
+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 (dma_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 (dma_omap2plus() && 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_write_mode(int lch, enum omap_dma_write_mode mode)
+{
+ if (dma_omap2plus()) {
+ 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 (dma_omap1() && !dma_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 (dma_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_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 (dma_omap2plus())
+ burst = 0x1;
+ else
+ burst = 0x2;
+ break;
+ case OMAP_DMA_DATA_BURST_8:
+ if (dma_omap2plus()) {
+ burst = 0x2;
+ break;
+ }
+ /*
+ * not supported by current hardware on OMAP1
+ * w |= (0x03 << 7);
+ * fall through
+ */
+ case OMAP_DMA_DATA_BURST_16:
+ if (dma_omap2plus()) {
+ 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 (dma_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_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 (dma_omap2plus())
+ burst = 0x1;
+ else
+ burst = 0x2;
+ break;
+ case OMAP_DMA_DATA_BURST_8:
+ if (dma_omap2plus())
+ burst = 0x2;
+ else
+ burst = 0x3;
+ break;
+ case OMAP_DMA_DATA_BURST_16:
+ if (dma_omap2plus()) {
+ 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)
+{
+ /* Clear CSR */
+ if (dma_omap1())
+ p->dma_read(CSR, lch);
+ else
+ 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 inline void omap_disable_channel_irq(int lch)
+{
+ /* disable channel interrupts */
+ p->dma_write(0, CICR, lch);
+ /* Clear CSR */
+ if (dma_omap1())
+ p->dma_read(CSR, lch);
+ else
+ p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, 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 (dma_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 (dma_omap2plus())
+ 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 */
+ omap_disable_channel_irq(lch);
+
+ if (dma_omap1()) {
+ /* Set the STOP_LNK bit */
+ l |= 1 << 14;
+ }
+
+ if (dma_omap2plus()) {
+ /* 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 (dma_omap1())
+ return;
+
+ spin_lock_irqsave(&dma_chan_lock, flags);
+ /* clear IRQ STATUS */
+ p->dma_write(1 << lch, IRQSTATUS_L0, lch);
+ /* Enable interrupt */
+ 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 (dma_omap1())
+ return;
+
+ spin_lock_irqsave(&dma_chan_lock, flags);
+ /* Disable interrupt */
+ val = p->dma_read(IRQENABLE_L0, lch);
+ val &= ~(1 << lch);
+ p->dma_write(val, IRQENABLE_L0, lch);
+ /* clear IRQ STATUS */
+ p->dma_write(1 << lch, IRQSTATUS_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;
+
+ WARN(strcmp(dev_name, "DMA engine"), "Using deprecated platform DMA API - please update to DMA engine");
+
+ 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;
+ /* Exit after first free channel found */
+ 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 (dma_omap2plus())
+ 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 (dma_omap2plus()) {
+ chan->chain_id = -1;
+ chan->next_linked_ch = -1;
+ }
+#endif
+
+ chan->enabled_irqs = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
+
+ if (dma_omap1())
+ chan->enabled_irqs |= OMAP1_DMA_TOUT_IRQ;
+ else if (dma_omap2plus())
+ chan->enabled_irqs |= OMAP2_DMA_MISALIGNED_ERR_IRQ |
+ OMAP2_DMA_TRANS_ERR_IRQ;
+
+ if (dma_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 (dma_omap1()) {
+ p->dma_write(dev_id, CCR, free_ch);
+ }
+
+ if (dma_omap2plus()) {
+ omap_enable_channel_irq(free_ch);
+ omap2_enable_irq_lch(free_ch);
+ }
+
+ *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;
+ }
+
+ /* Disable interrupt for logical channel */
+ if (dma_omap2plus())
+ omap2_disable_irq_lch(lch);
+
+ /* Disable all DMA interrupts for the channel. */
+ omap_disable_channel_irq(lch);
+
+ /* Make sure the DMA transfer is stopped. */
+ p->dma_write(0, CCR, lch);
+
+ /* Clear registers */
+ if (dma_omap2plus())
+ 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 (dma_omap1()) {
+ 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
+ */
+static 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 (d->dev_caps & IS_RW_PRIORITY)
+ l |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26);
+ else
+ l |= ((read_prio & 0x1) << 6);
+
+ p->dma_write(l, CCR, lch);
+
+ return 0;
+}
+
+
+/*
+ * 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.
+ */
+static void omap_clear_dma(int lch)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ p->clear_dma(lch);
+ local_irq_restore(flags);
+}
+
+void omap_start_dma(int lch)
+{
+ u32 l;
+
+ /*
+ * The CPC/CDAC register needs to be initialized to zero
+ * before starting dma transfer.
+ */
+ if (dma_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[MAX_LOGICAL_DMA_CH_COUNT];
+
+ /* Set the link register of the first channel */
+ enable_lnk(lch);
+
+ memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
+ dma_chan_link_map[lch] = 1;
+
+ 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;
+
+ /*
+ * As dma_write() uses IO accessors which are weakly ordered, there
+ * is no guarantee that data in coherent DMA memory will be visible
+ * to the DMA device. Add a memory barrier here to ensure that any
+ * such data is visible prior to enabling DMA.
+ */
+ mb();
+ 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 */
+ omap_disable_channel_irq(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)
+ pr_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);
+ }
+
+ /*
+ * Ensure that data transferred by DMA is visible to any access
+ * after DMA has been disabled. This is important for coherent
+ * DMA regions.
+ */
+ mb();
+
+ if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
+ int next_lch, cur_lch = lch;
+ char dma_chan_link_map[MAX_LOGICAL_DMA_CH_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 (dma_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 (!dma_omap15xx()) {
+ /*
+ * CDAC == 0 indicates that the DMA transfer on the channel has
+ * not been started (no data has been transferred so far).
+ * Return the programmed source start address in this case.
+ */
+ if (likely(p->dma_read(CDAC, lch)))
+ offset = p->dma_read(CSAC, lch);
+ else
+ offset = p->dma_read(CSSA, lch);
+ }
+
+ if (dma_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 (dma_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 (!dma_omap15xx() && offset == 0) {
+ offset = p->dma_read(CDAC, lch);
+ /*
+ * CDAC == 0 indicates that the DMA transfer on the channel has
+ * not been started (no data has been transferred so far).
+ * Return the programmed destination start address in this case.
+ */
+ if (unlikely(!offset))
+ offset = p->dma_read(CDSA, lch);
+ }
+
+ if (dma_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 (dma_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)) {
+ pr_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);
+
+/*----------------------------------------------------------------------------*/
+
+#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)) {
+ pr_warn("Spurious interrupt from DMA channel %d (CSR %04x)\n",
+ ch, csr);
+ return 0;
+ }
+ if (unlikely(csr & OMAP1_DMA_TOUT_IRQ))
+ pr_warn("DMA timeout with device %d\n", dma_chan[ch].dev_id);
+ if (unlikely(csr & OMAP_DMA_DROP_IRQ))
+ pr_warn("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())
+ pr_warn("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())
+ pr_warn("IRQ %04x for non-allocated DMA channel %d\n",
+ status, ch);
+ return 0;
+ }
+ if (unlikely(status & OMAP_DMA_DROP_IRQ))
+ pr_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,
+};
+
+#else
+static struct irqaction omap24xx_dma_irq;
+#endif
+
+/*----------------------------------------------------------------------------*/
+
+/*
+ * Note that we are currently using only IRQENABLE_L0 and L1.
+ * As the DSP may be using IRQENABLE_L2 and L3, let's not
+ * touch those for now.
+ */
+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_irqenable_l1 =
+ p->dma_read(IRQENABLE_L1, 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);
+ p->dma_write(omap_dma_global_context.dma_irqenable_l1,
+ IRQENABLE_L1, 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);
+}
+
+struct omap_system_dma_plat_info *omap_get_plat_info(void)
+{
+ return p;
+}
+EXPORT_SYMBOL_GPL(omap_get_plat_info);
+
+static int 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 < d->lch_count))
+ d->lch_count = omap_dma_reserve_channels;
+
+ dma_lch_count = d->lch_count;
+ dma_chan_count = dma_lch_count;
+ enable_1510_mode = d->dev_caps & ENABLE_1510_MODE;
+
+ dma_chan = devm_kcalloc(&pdev->dev, dma_lch_count,
+ sizeof(struct omap_dma_lch), GFP_KERNEL);
+ if (!dma_chan) {
+ dev_err(&pdev->dev, "%s: kzalloc fail\n", __func__);
+ return -ENOMEM;
+ }
+
+
+ if (dma_omap2plus()) {
+ 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 (dma_omap2plus())
+ 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 (dma_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 (d->dev_caps & IS_RW_PRIORITY)
+ omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE,
+ DMA_DEFAULT_FIFO_DEPTH, 0);
+
+ if (dma_omap2plus() && !(d->dev_caps & DMA_ENGINE_HANDLE_IRQ)) {
+ 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);
+ ret = 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 on 34xx */
+ if (d->dev_caps & HS_CHANNELS_RESERVED) {
+ pr_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:
+ return ret;
+}
+
+static int omap_system_dma_remove(struct platform_device *pdev)
+{
+ int dma_irq;
+
+ if (dma_omap2plus()) {
+ char irq_name[4];
+ strcpy(irq_name, "0");
+ dma_irq = platform_get_irq_byname(pdev, irq_name);
+ if (dma_irq >= 0)
+ 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));
+ }
+ }
+ 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 000000000..8ca94d379
--- /dev/null
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -0,0 +1,965 @@
+/*
+ * linux/arch/arm/plat-omap/dmtimer.c
+ *
+ * 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>
+ *
+ * dmtimer adaptation to platform_driver.
+ *
+ * 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/clk.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/dmtimer-omap.h>
+
+#include <plat/dmtimer.h>
+
+static u32 omap_reserved_systimers;
+static LIST_HEAD(omap_timer_list);
+static DEFINE_SPINLOCK(dm_timer_lock);
+
+enum {
+ REQUEST_ANY = 0,
+ REQUEST_BY_ID,
+ REQUEST_BY_CAP,
+ REQUEST_BY_NODE,
+};
+
+/**
+ * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
+ * @timer: timer pointer over which read operation to perform
+ * @reg: lowest byte holds the register offset
+ *
+ * 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)
+{
+ WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET);
+ return __omap_dm_timer_read(timer, reg, timer->posted);
+}
+
+/**
+ * omap_dm_timer_write_reg - write timer registers in posted and non-posted mode
+ * @timer: timer pointer over which write operation is to perform
+ * @reg: lowest byte holds the register offset
+ * @value: data to write into the register
+ *
+ * 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)
+{
+ WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET);
+ __omap_dm_timer_write(timer, reg, value, timer->posted);
+}
+
+static void omap_timer_restore_context(struct omap_dm_timer *timer)
+{
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG,
+ timer->context.twer);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG,
+ timer->context.tcrr);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG,
+ timer->context.tldr);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG,
+ timer->context.tmar);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
+ timer->context.tsicr);
+ writel_relaxed(timer->context.tier, timer->irq_ena);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG,
+ timer->context.tclr);
+}
+
+static int omap_dm_timer_reset(struct omap_dm_timer *timer)
+{
+ u32 l, timeout = 100000;
+
+ if (timer->revision != 1)
+ return -EINVAL;
+
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
+
+ do {
+ l = __omap_dm_timer_read(timer,
+ OMAP_TIMER_V1_SYS_STAT_OFFSET, 0);
+ } while (!l && timeout--);
+
+ if (!timeout) {
+ dev_err(&timer->pdev->dev, "Timer failed to reset\n");
+ return -ETIMEDOUT;
+ }
+
+ /* Configure timer for smart-idle mode */
+ l = __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0);
+ l |= 0x2 << 0x3;
+ __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, l, 0);
+
+ timer->posted = 0;
+
+ return 0;
+}
+
+static int omap_dm_timer_prepare(struct omap_dm_timer *timer)
+{
+ int rc;
+
+ /*
+ * FIXME: OMAP1 devices do not use the clock framework for dmtimers so
+ * do not call clk_get() for these devices.
+ */
+ if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
+ timer->fclk = clk_get(&timer->pdev->dev, "fck");
+ if (WARN_ON_ONCE(IS_ERR(timer->fclk))) {
+ dev_err(&timer->pdev->dev, ": No fclk handle.\n");
+ return -EINVAL;
+ }
+ }
+
+ omap_dm_timer_enable(timer);
+
+ if (timer->capability & OMAP_TIMER_NEEDS_RESET) {
+ rc = omap_dm_timer_reset(timer);
+ if (rc) {
+ omap_dm_timer_disable(timer);
+ return rc;
+ }
+ }
+
+ __omap_dm_timer_enable_posted(timer);
+ omap_dm_timer_disable(timer);
+
+ return omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
+}
+
+static inline u32 omap_dm_timer_reserved_systimer(int id)
+{
+ return (omap_reserved_systimers & (1 << (id - 1))) ? 1 : 0;
+}
+
+int omap_dm_timer_reserve_systimer(int id)
+{
+ if (omap_dm_timer_reserved_systimer(id))
+ return -ENODEV;
+
+ omap_reserved_systimers |= (1 << (id - 1));
+
+ return 0;
+}
+
+static struct omap_dm_timer *_omap_dm_timer_request(int req_type, void *data)
+{
+ struct omap_dm_timer *timer = NULL, *t;
+ struct device_node *np = NULL;
+ unsigned long flags;
+ u32 cap = 0;
+ int id = 0;
+
+ switch (req_type) {
+ case REQUEST_BY_ID:
+ id = *(int *)data;
+ break;
+ case REQUEST_BY_CAP:
+ cap = *(u32 *)data;
+ break;
+ case REQUEST_BY_NODE:
+ np = (struct device_node *)data;
+ break;
+ default:
+ /* REQUEST_ANY */
+ break;
+ }
+
+ spin_lock_irqsave(&dm_timer_lock, flags);
+ list_for_each_entry(t, &omap_timer_list, node) {
+ if (t->reserved)
+ continue;
+
+ switch (req_type) {
+ case REQUEST_BY_ID:
+ if (id == t->pdev->id) {
+ timer = t;
+ timer->reserved = 1;
+ goto found;
+ }
+ break;
+ case REQUEST_BY_CAP:
+ if (cap == (t->capability & cap)) {
+ /*
+ * If timer is not NULL, we have already found
+ * one timer but it was not an exact match
+ * because it had more capabilites that what
+ * was required. Therefore, unreserve the last
+ * timer found and see if this one is a better
+ * match.
+ */
+ if (timer)
+ timer->reserved = 0;
+ timer = t;
+ timer->reserved = 1;
+
+ /* Exit loop early if we find an exact match */
+ if (t->capability == cap)
+ goto found;
+ }
+ break;
+ case REQUEST_BY_NODE:
+ if (np == t->pdev->dev.of_node) {
+ timer = t;
+ timer->reserved = 1;
+ goto found;
+ }
+ break;
+ default:
+ /* REQUEST_ANY */
+ timer = t;
+ timer->reserved = 1;
+ goto found;
+ }
+ }
+found:
+ spin_unlock_irqrestore(&dm_timer_lock, flags);
+
+ if (timer && omap_dm_timer_prepare(timer)) {
+ timer->reserved = 0;
+ timer = NULL;
+ }
+
+ if (!timer)
+ pr_debug("%s: timer request failed!\n", __func__);
+
+ return timer;
+}
+
+struct omap_dm_timer *omap_dm_timer_request(void)
+{
+ return _omap_dm_timer_request(REQUEST_ANY, NULL);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_request);
+
+struct omap_dm_timer *omap_dm_timer_request_specific(int id)
+{
+ /* Requesting timer by ID is not supported when device tree is used */
+ if (of_have_populated_dt()) {
+ pr_warn("%s: Please use omap_dm_timer_request_by_cap/node()\n",
+ __func__);
+ return NULL;
+ }
+
+ return _omap_dm_timer_request(REQUEST_BY_ID, &id);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
+
+/**
+ * omap_dm_timer_request_by_cap - Request a timer by capability
+ * @cap: Bit mask of capabilities to match
+ *
+ * Find a timer based upon capabilities bit mask. Callers of this function
+ * should use the definitions found in the plat/dmtimer.h file under the
+ * comment "timer capabilities used in hwmod database". Returns pointer to
+ * timer handle on success and a NULL pointer on failure.
+ */
+struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
+{
+ return _omap_dm_timer_request(REQUEST_BY_CAP, &cap);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap);
+
+/**
+ * omap_dm_timer_request_by_node - Request a timer by device-tree node
+ * @np: Pointer to device-tree timer node
+ *
+ * Request a timer based upon a device node pointer. Returns pointer to
+ * timer handle on success and a NULL pointer on failure.
+ */
+struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
+{
+ if (!np)
+ return NULL;
+
+ return _omap_dm_timer_request(REQUEST_BY_NODE, np);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_node);
+
+int omap_dm_timer_free(struct omap_dm_timer *timer)
+{
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ clk_put(timer->fclk);
+
+ WARN_ON(!timer->reserved);
+ timer->reserved = 0;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_free);
+
+void omap_dm_timer_enable(struct omap_dm_timer *timer)
+{
+ int c;
+
+ pm_runtime_get_sync(&timer->pdev->dev);
+
+ if (!(timer->capability & OMAP_TIMER_ALWON)) {
+ if (timer->get_context_loss_count) {
+ c = timer->get_context_loss_count(&timer->pdev->dev);
+ if (c != timer->ctx_loss_count) {
+ omap_timer_restore_context(timer);
+ timer->ctx_loss_count = c;
+ }
+ } else {
+ omap_timer_restore_context(timer);
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_enable);
+
+void omap_dm_timer_disable(struct omap_dm_timer *timer)
+{
+ pm_runtime_put_sync(&timer->pdev->dev);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_disable);
+
+int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
+{
+ if (timer)
+ return timer->irq;
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq);
+
+#if defined(CONFIG_ARCH_OMAP1)
+#include <mach/hardware.h>
+/**
+ * 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 = 0;
+ struct omap_dm_timer *timer = NULL;
+ unsigned long flags;
+
+ /* 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 */
+ spin_lock_irqsave(&dm_timer_lock, flags);
+ list_for_each_entry(timer, &omap_timer_list, node) {
+ u32 l;
+
+ l = omap_dm_timer_read_reg(timer, 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);
+ }
+ i++;
+ }
+ spin_unlock_irqrestore(&dm_timer_lock, flags);
+
+ return inputmask;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
+
+#else
+
+struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
+{
+ if (timer && !IS_ERR(timer->fclk))
+ return timer->fclk;
+ return NULL;
+}
+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
+
+int omap_dm_timer_trigger(struct omap_dm_timer *timer)
+{
+ if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+ pr_err("%s: timer not available or enabled.\n", __func__);
+ return -EINVAL;
+ }
+
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_trigger);
+
+int omap_dm_timer_start(struct omap_dm_timer *timer)
+{
+ u32 l;
+
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ omap_dm_timer_enable(timer);
+
+ 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);
+ }
+
+ /* Save the context */
+ timer->context.tclr = l;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_start);
+
+int omap_dm_timer_stop(struct omap_dm_timer *timer)
+{
+ unsigned long rate = 0;
+
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ if (!(timer->capability & OMAP_TIMER_NEEDS_RESET))
+ rate = clk_get_rate(timer->fclk);
+
+ __omap_dm_timer_stop(timer, timer->posted, rate);
+
+ /*
+ * Since the register values are computed and written within
+ * __omap_dm_timer_stop, we need to use read to retrieve the
+ * context.
+ */
+ timer->context.tclr =
+ omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+ omap_dm_timer_disable(timer);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
+
+int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
+{
+ int ret;
+ char *parent_name = NULL;
+ struct clk *parent;
+ struct dmtimer_platform_data *pdata;
+
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ pdata = timer->pdev->dev.platform_data;
+
+ if (source < 0 || source >= 3)
+ return -EINVAL;
+
+ /*
+ * FIXME: Used for OMAP1 devices only because they do not currently
+ * use the clock framework to set the parent clock. To be removed
+ * once OMAP1 migrated to using clock framework for dmtimers
+ */
+ if (pdata && pdata->set_timer_src)
+ return pdata->set_timer_src(timer->pdev, source);
+
+ if (IS_ERR(timer->fclk))
+ return -EINVAL;
+
+ switch (source) {
+ case OMAP_TIMER_SRC_SYS_CLK:
+ parent_name = "timer_sys_ck";
+ break;
+
+ case OMAP_TIMER_SRC_32_KHZ:
+ parent_name = "timer_32k_ck";
+ break;
+
+ case OMAP_TIMER_SRC_EXT_CLK:
+ parent_name = "timer_ext_ck";
+ break;
+ }
+
+ parent = clk_get(&timer->pdev->dev, parent_name);
+ if (IS_ERR(parent)) {
+ pr_err("%s: %s not found\n", __func__, parent_name);
+ return -EINVAL;
+ }
+
+ ret = clk_set_parent(timer->fclk, parent);
+ if (ret < 0)
+ pr_err("%s: failed to set %s as parent\n", __func__,
+ parent_name);
+
+ clk_put(parent);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
+
+int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
+ unsigned int load)
+{
+ u32 l;
+
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ omap_dm_timer_enable(timer);
+ 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);
+ /* Save the context */
+ timer->context.tclr = l;
+ timer->context.tldr = load;
+ omap_dm_timer_disable(timer);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_load);
+
+/* Optimized set_load which removes costly spin wait in timer_start */
+int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
+ unsigned int load)
+{
+ u32 l;
+
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ omap_dm_timer_enable(timer);
+
+ 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_load_start(timer, l, load, timer->posted);
+
+ /* Save the context */
+ timer->context.tclr = l;
+ timer->context.tldr = load;
+ timer->context.tcrr = load;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start);
+
+int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
+ unsigned int match)
+{
+ u32 l;
+
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ omap_dm_timer_enable(timer);
+ 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_MATCH_REG, match);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+
+ /* Save the context */
+ timer->context.tclr = l;
+ timer->context.tmar = match;
+ omap_dm_timer_disable(timer);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_match);
+
+int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
+ int toggle, int trigger)
+{
+ u32 l;
+
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ omap_dm_timer_enable(timer);
+ 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);
+
+ /* Save the context */
+ timer->context.tclr = l;
+ omap_dm_timer_disable(timer);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_pwm);
+
+int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
+{
+ u32 l;
+
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ omap_dm_timer_enable(timer);
+ 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);
+
+ /* Save the context */
+ timer->context.tclr = l;
+ omap_dm_timer_disable(timer);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_prescaler);
+
+int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
+ unsigned int value)
+{
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ omap_dm_timer_enable(timer);
+ __omap_dm_timer_int_enable(timer, value);
+
+ /* Save the context */
+ timer->context.tier = value;
+ timer->context.twer = value;
+ omap_dm_timer_disable(timer);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable);
+
+/**
+ * omap_dm_timer_set_int_disable - disable timer interrupts
+ * @timer: pointer to timer handle
+ * @mask: bit mask of interrupts to be disabled
+ *
+ * Disables the specified timer interrupts for a timer.
+ */
+int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
+{
+ u32 l = mask;
+
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ omap_dm_timer_enable(timer);
+
+ if (timer->revision == 1)
+ l = readl_relaxed(timer->irq_ena) & ~mask;
+
+ writel_relaxed(l, timer->irq_dis);
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask;
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, l);
+
+ /* Save the context */
+ timer->context.tier &= ~mask;
+ timer->context.twer &= ~mask;
+ omap_dm_timer_disable(timer);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_disable);
+
+unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
+{
+ unsigned int l;
+
+ if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+ pr_err("%s: timer not available or enabled.\n", __func__);
+ return 0;
+ }
+
+ l = readl_relaxed(timer->irq_stat);
+
+ return l;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_read_status);
+
+int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
+{
+ if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev)))
+ return -EINVAL;
+
+ __omap_dm_timer_write_status(timer, value);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_write_status);
+
+unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
+{
+ if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+ pr_err("%s: timer not iavailable or enabled.\n", __func__);
+ return 0;
+ }
+
+ return __omap_dm_timer_read_counter(timer, timer->posted);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter);
+
+int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
+{
+ if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+ pr_err("%s: timer not available or enabled.\n", __func__);
+ return -EINVAL;
+ }
+
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
+
+ /* Save the context */
+ timer->context.tcrr = value;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_write_counter);
+
+int omap_dm_timers_active(void)
+{
+ struct omap_dm_timer *timer;
+
+ list_for_each_entry(timer, &omap_timer_list, node) {
+ if (!timer->reserved)
+ 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);
+
+static const struct of_device_id omap_timer_match[];
+
+/**
+ * omap_dm_timer_probe - probe function called for every registered device
+ * @pdev: pointer to current timer platform device
+ *
+ * Called by driver framework at the end of device registration for all
+ * timer devices.
+ */
+static int omap_dm_timer_probe(struct platform_device *pdev)
+{
+ unsigned long flags;
+ struct omap_dm_timer *timer;
+ struct resource *mem, *irq;
+ struct device *dev = &pdev->dev;
+ const struct of_device_id *match;
+ const struct dmtimer_platform_data *pdata;
+ int ret;
+
+ match = of_match_device(of_match_ptr(omap_timer_match), dev);
+ pdata = match ? match->data : dev->platform_data;
+
+ if (!pdata && !dev->of_node) {
+ dev_err(dev, "%s: no platform data.\n", __func__);
+ return -ENODEV;
+ }
+
+ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (unlikely(!irq)) {
+ dev_err(dev, "%s: no IRQ resource.\n", __func__);
+ return -ENODEV;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (unlikely(!mem)) {
+ dev_err(dev, "%s: no memory resource.\n", __func__);
+ return -ENODEV;
+ }
+
+ timer = devm_kzalloc(dev, sizeof(struct omap_dm_timer), GFP_KERNEL);
+ if (!timer) {
+ dev_err(dev, "%s: memory alloc failed!\n", __func__);
+ return -ENOMEM;
+ }
+
+ timer->fclk = ERR_PTR(-ENODEV);
+ timer->io_base = devm_ioremap_resource(dev, mem);
+ if (IS_ERR(timer->io_base))
+ return PTR_ERR(timer->io_base);
+
+ if (dev->of_node) {
+ if (of_find_property(dev->of_node, "ti,timer-alwon", NULL))
+ timer->capability |= OMAP_TIMER_ALWON;
+ if (of_find_property(dev->of_node, "ti,timer-dsp", NULL))
+ timer->capability |= OMAP_TIMER_HAS_DSP_IRQ;
+ if (of_find_property(dev->of_node, "ti,timer-pwm", NULL))
+ timer->capability |= OMAP_TIMER_HAS_PWM;
+ if (of_find_property(dev->of_node, "ti,timer-secure", NULL))
+ timer->capability |= OMAP_TIMER_SECURE;
+ } else {
+ timer->id = pdev->id;
+ timer->capability = pdata->timer_capability;
+ timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
+ timer->get_context_loss_count = pdata->get_context_loss_count;
+ }
+
+ if (pdata)
+ timer->errata = pdata->timer_errata;
+
+ timer->irq = irq->start;
+ timer->pdev = pdev;
+
+ /* Skip pm_runtime_enable for OMAP1 */
+ if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
+ pm_runtime_enable(dev);
+ pm_runtime_irq_safe(dev);
+ }
+
+ if (!timer->reserved) {
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ dev_err(dev, "%s: pm_runtime_get_sync failed!\n",
+ __func__);
+ goto err_get_sync;
+ }
+ __omap_dm_timer_init_regs(timer);
+ pm_runtime_put(dev);
+ }
+
+ /* add the timer element to the list */
+ spin_lock_irqsave(&dm_timer_lock, flags);
+ list_add_tail(&timer->node, &omap_timer_list);
+ spin_unlock_irqrestore(&dm_timer_lock, flags);
+
+ dev_dbg(dev, "Device Probed.\n");
+
+ return 0;
+
+err_get_sync:
+ pm_runtime_put_noidle(dev);
+ pm_runtime_disable(dev);
+ return ret;
+}
+
+/**
+ * omap_dm_timer_remove - cleanup a registered timer device
+ * @pdev: pointer to current timer platform device
+ *
+ * Called by driver framework whenever a timer device is unregistered.
+ * In addition to freeing platform resources it also deletes the timer
+ * entry from the local list.
+ */
+static int omap_dm_timer_remove(struct platform_device *pdev)
+{
+ struct omap_dm_timer *timer;
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ spin_lock_irqsave(&dm_timer_lock, flags);
+ list_for_each_entry(timer, &omap_timer_list, node)
+ if (!strcmp(dev_name(&timer->pdev->dev),
+ dev_name(&pdev->dev))) {
+ list_del(&timer->node);
+ ret = 0;
+ break;
+ }
+ spin_unlock_irqrestore(&dm_timer_lock, flags);
+
+ pm_runtime_disable(&pdev->dev);
+
+ return ret;
+}
+
+static const struct dmtimer_platform_data omap3plus_pdata = {
+ .timer_errata = OMAP_TIMER_ERRATA_I103_I767,
+};
+
+static const struct of_device_id omap_timer_match[] = {
+ {
+ .compatible = "ti,omap2420-timer",
+ },
+ {
+ .compatible = "ti,omap3430-timer",
+ .data = &omap3plus_pdata,
+ },
+ {
+ .compatible = "ti,omap4430-timer",
+ .data = &omap3plus_pdata,
+ },
+ {
+ .compatible = "ti,omap5430-timer",
+ .data = &omap3plus_pdata,
+ },
+ {
+ .compatible = "ti,am335x-timer",
+ .data = &omap3plus_pdata,
+ },
+ {
+ .compatible = "ti,am335x-timer-1ms",
+ .data = &omap3plus_pdata,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, omap_timer_match);
+
+static struct platform_driver omap_dm_timer_driver = {
+ .probe = omap_dm_timer_probe,
+ .remove = omap_dm_timer_remove,
+ .driver = {
+ .name = "omap_timer",
+ .of_match_table = of_match_ptr(omap_timer_match),
+ },
+};
+
+early_platform_init("earlytimer", &omap_dm_timer_driver);
+module_platform_driver(omap_dm_timer_driver);
+
+MODULE_DESCRIPTION("OMAP Dual-Mode Timer Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("Texas Instruments Inc");
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
new file mode 100644
index 000000000..58213d971
--- /dev/null
+++ b/arch/arm/plat-omap/i2c.c
@@ -0,0 +1,116 @@
+/*
+ * 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 <plat/i2c.h>
+
+#define OMAP_I2C_MAX_CONTROLLERS 4
+static struct omap_i2c_bus_platform_data i2c_pdata[OMAP_I2C_MAX_CONTROLLERS];
+
+#define OMAP_I2C_CMDLINE_SETUP (BIT(31))
+
+/**
+ * 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 ints[3];
+
+ get_options(str, 3, ints);
+ if (ints[0] < 2 || ints[1] < 1 ||
+ ints[1] > OMAP_I2C_MAX_CONTROLLERS)
+ 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.
+ */
+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(&i2c_pdata[i], i + 1);
+ if (err)
+ goto out;
+ }
+
+out:
+ return err;
+}
+
+/**
+ * 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_MAX_CONTROLLERS);
+
+ 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(&i2c_pdata[bus_id - 1], bus_id);
+}
diff --git a/arch/arm/plat-omap/include/plat/counter-32k.h b/arch/arm/plat-omap/include/plat/counter-32k.h
new file mode 100644
index 000000000..da000d482
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/counter-32k.h
@@ -0,0 +1 @@
+int omap_init_clocksource_32k(void __iomem *vbase);
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 000000000..c9a66bf36
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -0,0 +1,35 @@
+/*
+ * 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/5 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
+
+#ifdef CONFIG_ARCH_OMAP1
+#include <mach/soc.h>
+#endif
+
+#endif
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 000000000..dd79f3005
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -0,0 +1,418 @@
+/*
+ * arch/arm/plat-omap/include/plat/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.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#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
+
+/* posted mode types */
+#define OMAP_TIMER_NONPOSTED 0x00
+#define OMAP_TIMER_POSTED 0x01
+
+/* timer capabilities used in hwmod database */
+#define OMAP_TIMER_SECURE 0x80000000
+#define OMAP_TIMER_ALWON 0x40000000
+#define OMAP_TIMER_HAS_PWM 0x20000000
+#define OMAP_TIMER_NEEDS_RESET 0x10000000
+#define OMAP_TIMER_HAS_DSP_IRQ 0x08000000
+
+/*
+ * timer errata flags
+ *
+ * Errata i103/i767 impacts all OMAP3/4/5 devices including AM33xx. This
+ * errata prevents us from using posted mode on these devices, unless the
+ * timer counter register is never read. For more details please refer to
+ * the OMAP3/4/5 errata documents.
+ */
+#define OMAP_TIMER_ERRATA_I103_I767 0x80000000
+
+struct omap_timer_capability_dev_attr {
+ u32 timer_capability;
+};
+
+struct timer_regs {
+ u32 tidr;
+ u32 tier;
+ u32 twer;
+ u32 tclr;
+ u32 tcrr;
+ u32 tldr;
+ u32 ttrg;
+ u32 twps;
+ u32 tmar;
+ u32 tcar1;
+ u32 tsicr;
+ u32 tcar2;
+ u32 tpir;
+ u32 tnir;
+ u32 tcvr;
+ u32 tocr;
+ u32 towr;
+};
+
+struct omap_dm_timer {
+ int id;
+ int irq;
+ struct clk *fclk;
+
+ void __iomem *io_base;
+ void __iomem *irq_stat; /* TISR/IRQSTATUS interrupt status */
+ void __iomem *irq_ena; /* irq enable */
+ void __iomem *irq_dis; /* irq disable, only on v2 ip */
+ void __iomem *pend; /* write pending */
+ void __iomem *func_base; /* function register base */
+
+ unsigned long rate;
+ unsigned reserved:1;
+ unsigned posted:1;
+ struct timer_regs context;
+ int (*get_context_loss_count)(struct device *);
+ int ctx_loss_count;
+ int revision;
+ u32 capability;
+ u32 errata;
+ struct platform_device *pdev;
+ struct list_head node;
+};
+
+int omap_dm_timer_reserve_systimer(int id);
+struct omap_dm_timer *omap_dm_timer_request(void);
+struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
+struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
+struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np);
+int 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);
+
+int omap_dm_timer_trigger(struct omap_dm_timer *timer);
+int omap_dm_timer_start(struct omap_dm_timer *timer);
+int omap_dm_timer_stop(struct omap_dm_timer *timer);
+
+int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
+int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
+int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
+int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
+int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger);
+int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
+
+int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
+int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask);
+
+unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
+int 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);
+int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value);
+
+int omap_dm_timers_active(void);
+
+/*
+ * Do not use the defines below, they are not needed. They should be only
+ * used by dmtimer.c and sys_timer related code.
+ */
+
+/*
+ * The interrupt registers are different between v1 and v2 ip.
+ * These registers are offsets from timer->iobase.
+ */
+#define OMAP_TIMER_ID_OFFSET 0x00
+#define OMAP_TIMER_OCP_CFG_OFFSET 0x10
+
+#define OMAP_TIMER_V1_SYS_STAT_OFFSET 0x14
+#define OMAP_TIMER_V1_STAT_OFFSET 0x18
+#define OMAP_TIMER_V1_INT_EN_OFFSET 0x1c
+
+#define OMAP_TIMER_V2_IRQSTATUS_RAW 0x24
+#define OMAP_TIMER_V2_IRQSTATUS 0x28
+#define OMAP_TIMER_V2_IRQENABLE_SET 0x2c
+#define OMAP_TIMER_V2_IRQENABLE_CLR 0x30
+
+/*
+ * The functional registers have a different base on v1 and v2 ip.
+ * These registers are offsets from timer->func_base. The func_base
+ * is samae as io_base for v1 and io_base + 0x14 for v2 ip.
+ *
+ */
+#define OMAP_TIMER_V2_FUNC_OFFSET 0x14
+
+#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_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))
+
+static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg,
+ int posted)
+{
+ if (posted)
+ while (readl_relaxed(timer->pend) & (reg >> WPSHIFT))
+ cpu_relax();
+
+ return readl_relaxed(timer->func_base + (reg & 0xff));
+}
+
+static inline void __omap_dm_timer_write(struct omap_dm_timer *timer,
+ u32 reg, u32 val, int posted)
+{
+ if (posted)
+ while (readl_relaxed(timer->pend) & (reg >> WPSHIFT))
+ cpu_relax();
+
+ writel_relaxed(val, timer->func_base + (reg & 0xff));
+}
+
+static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer)
+{
+ u32 tidr;
+
+ /* Assume v1 ip if bits [31:16] are zero */
+ tidr = readl_relaxed(timer->io_base);
+ if (!(tidr >> 16)) {
+ timer->revision = 1;
+ timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET;
+ timer->irq_ena = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET;
+ timer->irq_dis = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET;
+ timer->pend = timer->io_base + _OMAP_TIMER_WRITE_PEND_OFFSET;
+ timer->func_base = timer->io_base;
+ } else {
+ timer->revision = 2;
+ timer->irq_stat = timer->io_base + OMAP_TIMER_V2_IRQSTATUS;
+ timer->irq_ena = timer->io_base + OMAP_TIMER_V2_IRQENABLE_SET;
+ timer->irq_dis = timer->io_base + OMAP_TIMER_V2_IRQENABLE_CLR;
+ timer->pend = timer->io_base +
+ _OMAP_TIMER_WRITE_PEND_OFFSET +
+ OMAP_TIMER_V2_FUNC_OFFSET;
+ timer->func_base = timer->io_base + OMAP_TIMER_V2_FUNC_OFFSET;
+ }
+}
+
+/*
+ * __omap_dm_timer_enable_posted - enables write posted mode
+ * @timer: pointer to timer instance handle
+ *
+ * Enables the write posted mode for the timer. When posted mode is enabled
+ * writes to certain timer registers are immediately acknowledged by the
+ * internal bus and hence prevents stalling the CPU waiting for the write to
+ * complete. Enabling this feature can improve performance for writing to the
+ * timer registers.
+ */
+static inline void __omap_dm_timer_enable_posted(struct omap_dm_timer *timer)
+{
+ if (timer->posted)
+ return;
+
+ if (timer->errata & OMAP_TIMER_ERRATA_I103_I767) {
+ timer->posted = OMAP_TIMER_NONPOSTED;
+ __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG, 0, 0);
+ return;
+ }
+
+ __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG,
+ OMAP_TIMER_CTRL_POSTED, 0);
+ timer->context.tsicr = OMAP_TIMER_CTRL_POSTED;
+ timer->posted = OMAP_TIMER_POSTED;
+}
+
+/**
+ * __omap_dm_timer_override_errata - override errata flags for a timer
+ * @timer: pointer to timer handle
+ * @errata: errata flags to be ignored
+ *
+ * For a given timer, override a timer errata by clearing the flags
+ * specified by the errata argument. A specific erratum should only be
+ * overridden for a timer if the timer is used in such a way the erratum
+ * has no impact.
+ */
+static inline void __omap_dm_timer_override_errata(struct omap_dm_timer *timer,
+ u32 errata)
+{
+ timer->errata &= ~errata;
+}
+
+static inline void __omap_dm_timer_stop(struct omap_dm_timer *timer,
+ int posted, unsigned long rate)
+{
+ u32 l;
+
+ l = __omap_dm_timer_read(timer, OMAP_TIMER_CTRL_REG, posted);
+ if (l & OMAP_TIMER_CTRL_ST) {
+ l &= ~0x1;
+ __omap_dm_timer_write(timer, OMAP_TIMER_CTRL_REG, l, posted);
+#ifdef CONFIG_ARCH_OMAP2PLUS
+ /* Readback to make sure write has completed */
+ __omap_dm_timer_read(timer, OMAP_TIMER_CTRL_REG, posted);
+ /*
+ * Wait for functional clock period x 3.5 to make sure that
+ * timer is stopped
+ */
+ udelay(3500000 / rate + 1);
+#endif
+ }
+
+ /* Ack possibly pending interrupt */
+ writel_relaxed(OMAP_TIMER_INT_OVERFLOW, timer->irq_stat);
+}
+
+static inline void __omap_dm_timer_load_start(struct omap_dm_timer *timer,
+ u32 ctrl, unsigned int load,
+ int posted)
+{
+ __omap_dm_timer_write(timer, OMAP_TIMER_COUNTER_REG, load, posted);
+ __omap_dm_timer_write(timer, OMAP_TIMER_CTRL_REG, ctrl, posted);
+}
+
+static inline void __omap_dm_timer_int_enable(struct omap_dm_timer *timer,
+ unsigned int value)
+{
+ writel_relaxed(value, timer->irq_ena);
+ __omap_dm_timer_write(timer, OMAP_TIMER_WAKEUP_EN_REG, value, 0);
+}
+
+static inline unsigned int
+__omap_dm_timer_read_counter(struct omap_dm_timer *timer, int posted)
+{
+ return __omap_dm_timer_read(timer, OMAP_TIMER_COUNTER_REG, posted);
+}
+
+static inline void __omap_dm_timer_write_status(struct omap_dm_timer *timer,
+ unsigned int value)
+{
+ writel_relaxed(value, timer->irq_stat);
+}
+
+#endif /* __ASM_ARCH_DMTIMER_H */
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 000000000..810629d79
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/i2c.h
@@ -0,0 +1,53 @@
+/*
+ * 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 __PLAT_OMAP_I2C_H
+#define __PLAT_OMAP_I2C_H
+
+struct i2c_board_info;
+struct omap_i2c_bus_platform_data;
+
+int omap_i2c_add_bus(struct omap_i2c_bus_platform_data *i2c_pdata,
+ int bus_id);
+
+#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);
+extern int omap_register_i2c_bus_cmdline(void);
+#else
+static inline int omap_register_i2c_bus(int bus_id, u32 clkrate,
+ struct i2c_board_info const *info,
+ unsigned len)
+{
+ return 0;
+}
+
+static inline int omap_register_i2c_bus_cmdline(void)
+{
+ return 0;
+}
+#endif
+
+struct omap_hwmod;
+int omap_i2c_reset(struct omap_hwmod *oh);
+
+#endif /* __PLAT_OMAP_I2C_H */
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 000000000..ba4525059
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/sram.h
@@ -0,0 +1,16 @@
+int omap_sram_init(void);
+
+void omap_map_sram(unsigned long start, unsigned long size,
+ unsigned long skip, int cached);
+void omap_sram_reset(void);
+
+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; \
+})
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
new file mode 100644
index 000000000..a5bc92d7e
--- /dev/null
+++ b/arch/arm/plat-omap/sram.c
@@ -0,0 +1,98 @@
+/*
+ * 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-2012 Texas Instruments
+ * Added OMAP4/5 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 <asm/fncpy.h>
+#include <asm/tlb.h>
+#include <asm/cacheflush.h>
+
+#include <asm/mach/map.h>
+
+#include <plat/sram.h>
+
+#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
+
+static void __iomem *omap_sram_base;
+static unsigned long omap_sram_skip;
+static unsigned long omap_sram_size;
+static void __iomem *omap_sram_ceil;
+
+/*
+ * 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)
+{
+ unsigned long available, new_ceil = (unsigned long)omap_sram_ceil;
+
+ available = omap_sram_ceil - (omap_sram_base + omap_sram_skip);
+
+ if (size > available) {
+ pr_err("Not enough space in SRAM\n");
+ return NULL;
+ }
+
+ new_ceil -= size;
+ new_ceil = ROUND_DOWN(new_ceil, FNCPY_ALIGN);
+ omap_sram_ceil = IOMEM(new_ceil);
+
+ return (void *)omap_sram_ceil;
+}
+
+/*
+ * The SRAM context is lost during off-idle and stack
+ * needs to be reset.
+ */
+void omap_sram_reset(void)
+{
+ omap_sram_ceil = omap_sram_base + omap_sram_size;
+}
+
+/*
+ * Note that we cannot use ioremap for SRAM, as clock init needs SRAM early.
+ */
+void __init omap_map_sram(unsigned long start, unsigned long size,
+ unsigned long skip, int cached)
+{
+ if (size == 0)
+ return;
+
+ start = ROUND_DOWN(start, PAGE_SIZE);
+ omap_sram_size = size;
+ omap_sram_skip = skip;
+ omap_sram_base = __arm_ioremap_exec(start, size, cached);
+ if (!omap_sram_base) {
+ pr_err("SRAM: Could not map\n");
+ return;
+ }
+
+ omap_sram_reset();
+
+ /*
+ * Looks like we need to preserve some bootloader code at the
+ * beginning of SRAM for jumping to flash for reboot to work...
+ */
+ memset_io(omap_sram_base + omap_sram_skip, 0,
+ omap_sram_size - omap_sram_skip);
+}
diff --git a/arch/arm/plat-orion/Makefile b/arch/arm/plat-orion/Makefile
new file mode 100644
index 000000000..9433605cd
--- /dev/null
+++ b/arch/arm/plat-orion/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux kernel.
+#
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
+
+orion-gpio-$(CONFIG_GPIOLIB) += gpio.o
+obj-$(CONFIG_PLAT_ORION_LEGACY) += irq.o pcie.o time.o common.o mpp.o
+obj-$(CONFIG_PLAT_ORION_LEGACY) += $(orion-gpio-y)
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
new file mode 100644
index 000000000..f5b00f41c
--- /dev/null
+++ b/arch/arm/plat-orion/common.c
@@ -0,0 +1,884 @@
+/*
+ * 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/ata_platform.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/mv643xx_i2c.h>
+#include <net/dsa.h>
+#include <linux/platform_data/dma-mv_xor.h>
+#include <linux/platform_data/usb-ehci-orion.h>
+#include <mach/bridge-regs.h>
+#include <plat/common.h>
+
+/* Create a clkdev entry for a given device/clk */
+void __init orion_clkdev_add(const char *con_id, const char *dev_id,
+ struct clk *clk)
+{
+ struct clk_lookup *cl;
+
+ cl = clkdev_alloc(clk, con_id, dev_id);
+ if (cl)
+ clkdev_add(cl);
+}
+
+/* Create clkdev entries for all orion platforms except kirkwood.
+ Kirkwood has gated clocks for some of its peripherals, so creates
+ its own clkdev entries. For all the other orion devices, create
+ clkdev entries to the tclk. */
+void __init orion_clkdev_init(struct clk *tclk)
+{
+ orion_clkdev_add(NULL, "orion_spi.0", tclk);
+ orion_clkdev_add(NULL, "orion_spi.1", tclk);
+ orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", tclk);
+ orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", tclk);
+ orion_clkdev_add(NULL, MV643XX_ETH_NAME ".2", tclk);
+ orion_clkdev_add(NULL, MV643XX_ETH_NAME ".3", tclk);
+ orion_clkdev_add(NULL, "orion_wdt", tclk);
+ orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".0", tclk);
+}
+
+/* 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 unsigned long __init uart_get_clk_rate(struct clk *clk)
+{
+ clk_prepare_enable(clk);
+ return clk_get_rate(clk);
+}
+
+static void __init uart_complete(
+ struct platform_device *orion_uart,
+ struct plat_serial8250_port *data,
+ struct resource *resources,
+ void __iomem *membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ struct clk *clk)
+{
+ data->mapbase = mapbase;
+ data->membase = membase;
+ data->irq = irq;
+ data->uartclk = uart_get_clk_rate(clk);
+ 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(void __iomem *membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ struct clk *clk)
+{
+ uart_complete(&orion_uart0, orion_uart0_data, orion_uart0_resources,
+ membase, mapbase, irq, clk);
+}
+
+/*****************************************************************************
+ * 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(void __iomem *membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ struct clk *clk)
+{
+ uart_complete(&orion_uart1, orion_uart1_data, orion_uart1_resources,
+ membase, mapbase, irq, clk);
+}
+
+/*****************************************************************************
+ * 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(void __iomem *membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ struct clk *clk)
+{
+ uart_complete(&orion_uart2, orion_uart2_data, orion_uart2_resources,
+ membase, mapbase, irq, clk);
+}
+
+/*****************************************************************************
+ * 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(void __iomem *membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ struct clk *clk)
+{
+ uart_complete(&orion_uart3, orion_uart3_data, orion_uart3_resources,
+ membase, mapbase, irq, clk);
+}
+
+/*****************************************************************************
+ * 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 resource *orion_ge_resource, unsigned long irq,
+ struct platform_device *orion_ge_shared,
+ struct platform_device *orion_ge_mvmdio,
+ struct mv643xx_eth_platform_data *eth_data,
+ struct platform_device *orion_ge)
+{
+ 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);
+ if (orion_ge_mvmdio)
+ platform_device_register(orion_ge_mvmdio);
+ platform_device_register(orion_ge);
+}
+
+/*****************************************************************************
+ * GE00
+ ****************************************************************************/
+static struct mv643xx_eth_shared_platform_data orion_ge00_shared_data;
+
+static struct resource orion_ge00_shared_resources[] = {
+ {
+ .name = "ge00 base",
+ },
+};
+
+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_ge_mvmdio_resources[] = {
+ {
+ .name = "ge00 mvmdio base",
+ }, {
+ .name = "ge00 mvmdio err irq",
+ },
+};
+
+static struct platform_device orion_ge_mvmdio = {
+ .name = "orion-mdio",
+ .id = -1,
+};
+
+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,
+ unsigned long mapbase,
+ unsigned long irq,
+ unsigned long irq_err,
+ unsigned int tx_csum_limit)
+{
+ fill_resources(&orion_ge00_shared, orion_ge00_shared_resources,
+ mapbase + 0x2000, SZ_16K - 1, NO_IRQ);
+ fill_resources(&orion_ge_mvmdio, orion_ge_mvmdio_resources,
+ mapbase + 0x2004, 0x84 - 1, irq_err);
+ orion_ge00_shared_data.tx_csum_limit = tx_csum_limit;
+ ge_complete(&orion_ge00_shared_data,
+ orion_ge00_resources, irq, &orion_ge00_shared,
+ &orion_ge_mvmdio,
+ eth_data, &orion_ge00);
+}
+
+/*****************************************************************************
+ * GE01
+ ****************************************************************************/
+static struct mv643xx_eth_shared_platform_data orion_ge01_shared_data;
+
+static struct resource orion_ge01_shared_resources[] = {
+ {
+ .name = "ge01 base",
+ }
+};
+
+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,
+ unsigned long mapbase,
+ unsigned long irq,
+ unsigned long irq_err,
+ unsigned int tx_csum_limit)
+{
+ fill_resources(&orion_ge01_shared, orion_ge01_shared_resources,
+ mapbase + 0x2000, SZ_16K - 1, NO_IRQ);
+ orion_ge01_shared_data.tx_csum_limit = tx_csum_limit;
+ ge_complete(&orion_ge01_shared_data,
+ orion_ge01_resources, irq, &orion_ge01_shared,
+ NULL,
+ eth_data, &orion_ge01);
+}
+
+/*****************************************************************************
+ * GE10
+ ****************************************************************************/
+static struct mv643xx_eth_shared_platform_data orion_ge10_shared_data;
+
+static struct resource orion_ge10_shared_resources[] = {
+ {
+ .name = "ge10 base",
+ }
+};
+
+static struct platform_device orion_ge10_shared = {
+ .name = MV643XX_ETH_SHARED_NAME,
+ .id = 2,
+ .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 = 2,
+ .num_resources = 1,
+ .resource = orion_ge10_resources,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
+ unsigned long mapbase,
+ unsigned long irq,
+ unsigned long irq_err)
+{
+ fill_resources(&orion_ge10_shared, orion_ge10_shared_resources,
+ mapbase + 0x2000, SZ_16K - 1, NO_IRQ);
+ ge_complete(&orion_ge10_shared_data,
+ orion_ge10_resources, irq, &orion_ge10_shared,
+ NULL,
+ eth_data, &orion_ge10);
+}
+
+/*****************************************************************************
+ * GE11
+ ****************************************************************************/
+static struct mv643xx_eth_shared_platform_data orion_ge11_shared_data;
+
+static struct resource orion_ge11_shared_resources[] = {
+ {
+ .name = "ge11 base",
+ },
+};
+
+static struct platform_device orion_ge11_shared = {
+ .name = MV643XX_ETH_SHARED_NAME,
+ .id = 3,
+ .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 = 3,
+ .num_resources = 1,
+ .resource = orion_ge11_resources,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
+ unsigned long mapbase,
+ unsigned long irq,
+ unsigned long irq_err)
+{
+ fill_resources(&orion_ge11_shared, orion_ge11_shared_resources,
+ mapbase + 0x2000, SZ_16K - 1, NO_IRQ);
+ ge_complete(&orion_ge11_shared_data,
+ orion_ge11_resources, irq, &orion_ge11_shared,
+ NULL,
+ 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].host_dev = &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 resource orion_spi_resources;
+
+static struct platform_device orion_spi = {
+ .name = "orion_spi",
+ .id = 0,
+};
+
+static struct resource orion_spi_1_resources;
+
+static struct platform_device orion_spi_1 = {
+ .name = "orion_spi",
+ .id = 1,
+};
+
+/* 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)
+{
+ 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)
+{
+ fill_resources(&orion_spi_1, &orion_spi_1_resources,
+ mapbase, SZ_512 - 1, NO_IRQ);
+ platform_device_register(&orion_spi_1);
+}
+
+/*****************************************************************************
+ * Watchdog
+ ****************************************************************************/
+static struct resource orion_wdt_resource[] = {
+ DEFINE_RES_MEM(TIMER_PHYS_BASE, 0x04),
+ DEFINE_RES_MEM(RSTOUTn_MASK_PHYS, 0x04),
+};
+
+static struct platform_device orion_wdt_device = {
+ .name = "orion_wdt",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(orion_wdt_resource),
+ .resource = orion_wdt_resource,
+};
+
+void __init orion_wdt_init(void)
+{
+ platform_device_register(&orion_wdt_device);
+}
+
+/*****************************************************************************
+ * XOR
+ ****************************************************************************/
+static u64 orion_xor_dmamask = DMA_BIT_MASK(32);
+
+/*****************************************************************************
+ * XOR0
+ ****************************************************************************/
+static struct resource orion_xor0_shared_resources[] = {
+ {
+ .name = "xor 0 low",
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "xor 0 high",
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "irq channel 0",
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .name = "irq channel 1",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mv_xor_channel_data orion_xor0_channels_data[2];
+
+static struct mv_xor_platform_data orion_xor0_pdata = {
+ .channels = orion_xor0_channels_data,
+};
+
+static struct platform_device orion_xor0_shared = {
+ .name = MV_XOR_NAME,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(orion_xor0_shared_resources),
+ .resource = orion_xor0_shared_resources,
+ .dev = {
+ .dma_mask = &orion_xor_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
+ .platform_data = &orion_xor0_pdata,
+ },
+};
+
+void __init orion_xor0_init(unsigned long mapbase_low,
+ unsigned long mapbase_high,
+ unsigned long irq_0,
+ unsigned long irq_1)
+{
+ 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_xor0_shared_resources[2].start = irq_0;
+ orion_xor0_shared_resources[2].end = irq_0;
+ orion_xor0_shared_resources[3].start = irq_1;
+ orion_xor0_shared_resources[3].end = irq_1;
+
+ dma_cap_set(DMA_MEMCPY, orion_xor0_channels_data[0].cap_mask);
+ dma_cap_set(DMA_XOR, orion_xor0_channels_data[0].cap_mask);
+
+ dma_cap_set(DMA_MEMCPY, orion_xor0_channels_data[1].cap_mask);
+ dma_cap_set(DMA_XOR, orion_xor0_channels_data[1].cap_mask);
+
+ platform_device_register(&orion_xor0_shared);
+}
+
+/*****************************************************************************
+ * XOR1
+ ****************************************************************************/
+static struct resource orion_xor1_shared_resources[] = {
+ {
+ .name = "xor 1 low",
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "xor 1 high",
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "irq channel 0",
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .name = "irq channel 1",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mv_xor_channel_data orion_xor1_channels_data[2];
+
+static struct mv_xor_platform_data orion_xor1_pdata = {
+ .channels = orion_xor1_channels_data,
+};
+
+static struct platform_device orion_xor1_shared = {
+ .name = MV_XOR_NAME,
+ .id = 1,
+ .num_resources = ARRAY_SIZE(orion_xor1_shared_resources),
+ .resource = orion_xor1_shared_resources,
+ .dev = {
+ .dma_mask = &orion_xor_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
+ .platform_data = &orion_xor1_pdata,
+ },
+};
+
+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_xor1_shared_resources[2].start = irq_0;
+ orion_xor1_shared_resources[2].end = irq_0;
+ orion_xor1_shared_resources[3].start = irq_1;
+ orion_xor1_shared_resources[3].end = irq_1;
+
+ dma_cap_set(DMA_MEMCPY, orion_xor1_channels_data[0].cap_mask);
+ dma_cap_set(DMA_XOR, orion_xor1_channels_data[0].cap_mask);
+
+ dma_cap_set(DMA_MEMCPY, orion_xor1_channels_data[1].cap_mask);
+ dma_cap_set(DMA_XOR, orion_xor1_channels_data[1].cap_mask);
+
+ platform_device_register(&orion_xor1_shared);
+}
+
+/*****************************************************************************
+ * 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(unsigned long mapbase,
+ unsigned long irq,
+ enum orion_ehci_phy_ver phy_version)
+{
+ 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(unsigned long mapbase,
+ unsigned long irq)
+{
+ 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(unsigned long mapbase,
+ unsigned long irq)
+{
+ 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,
+ unsigned long mapbase,
+ unsigned long irq)
+{
+ 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 000000000..5168a52a1
--- /dev/null
+++ b/arch/arm/plat-orion/gpio.c
@@ -0,0 +1,628 @@
+/*
+ * 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.
+ */
+
+#define DEBUG
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <plat/orion-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;
+ struct irq_domain *domain;
+};
+
+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;
+}
+
+/*
+ * 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 irq_create_mapping(ochip->domain,
+ 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 & 31, 0);
+ __set_blinking(ochip, pin & 31, blink);
+ spin_unlock_irqrestore(&ochip->lock, flags);
+}
+EXPORT_SYMBOL(orion_gpio_set_blink);
+
+#define ORION_BLINK_HALF_PERIOD 100 /* ms */
+
+int orion_gpio_led_blink_set(struct gpio_desc *desc, int state,
+ unsigned long *delay_on, unsigned long *delay_off)
+{
+ unsigned gpio = desc_to_gpio(desc);
+
+ 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;
+}
+EXPORT_SYMBOL_GPL(orion_gpio_led_blink_set);
+
+
+/*****************************************************************************
+ * 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->hwirq - ochip->secondary_irq_base;
+
+ u = readl(GPIO_IO_CONF(ochip)) & (1 << pin);
+ if (!u) {
+ 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;
+}
+
+static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
+{
+ struct orion_gpio_chip *ochip = irq_get_handler_data(irq);
+ u32 cause, type;
+ int i;
+
+ 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 = irq_get_trigger_type(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);
+ }
+}
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/seq_file.h>
+
+static void orion_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+ struct orion_gpio_chip *ochip =
+ container_of(chip, struct orion_gpio_chip, chip);
+ u32 out, io_conf, blink, in_pol, data_in, cause, edg_msk, lvl_msk;
+ int i;
+
+ out = readl_relaxed(GPIO_OUT(ochip));
+ io_conf = readl_relaxed(GPIO_IO_CONF(ochip));
+ blink = readl_relaxed(GPIO_BLINK_EN(ochip));
+ in_pol = readl_relaxed(GPIO_IN_POL(ochip));
+ data_in = readl_relaxed(GPIO_DATA_IN(ochip));
+ cause = readl_relaxed(GPIO_EDGE_CAUSE(ochip));
+ edg_msk = readl_relaxed(GPIO_EDGE_MASK(ochip));
+ lvl_msk = readl_relaxed(GPIO_LEVEL_MASK(ochip));
+
+ for (i = 0; i < chip->ngpio; i++) {
+ const char *label;
+ u32 msk;
+ bool is_out;
+
+ label = gpiochip_is_requested(chip, i);
+ if (!label)
+ continue;
+
+ msk = 1 << i;
+ is_out = !(io_conf & msk);
+
+ seq_printf(s, " gpio-%-3d (%-20.20s)", chip->base + i, label);
+
+ if (is_out) {
+ seq_printf(s, " out %s %s\n",
+ out & msk ? "hi" : "lo",
+ blink & msk ? "(blink )" : "");
+ continue;
+ }
+
+ seq_printf(s, " in %s (act %s) - IRQ",
+ (data_in ^ in_pol) & msk ? "hi" : "lo",
+ in_pol & msk ? "lo" : "hi");
+ if (!((edg_msk | lvl_msk) & msk)) {
+ seq_printf(s, " disabled\n");
+ continue;
+ }
+ if (edg_msk & msk)
+ seq_printf(s, " edge ");
+ if (lvl_msk & msk)
+ seq_printf(s, " level");
+ seq_printf(s, " (%s)\n", cause & msk ? "pending" : "clear ");
+ }
+}
+#else
+#define orion_gpio_dbg_show NULL
+#endif
+
+static void orion_gpio_unmask_irq(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct irq_chip_type *ct = irq_data_get_chip_type(d);
+ u32 reg_val;
+ u32 mask = d->mask;
+
+ irq_gc_lock(gc);
+ reg_val = irq_reg_readl(gc, ct->regs.mask);
+ reg_val |= mask;
+ irq_reg_writel(gc, reg_val, ct->regs.mask);
+ irq_gc_unlock(gc);
+}
+
+static void orion_gpio_mask_irq(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct irq_chip_type *ct = irq_data_get_chip_type(d);
+ u32 mask = d->mask;
+ u32 reg_val;
+
+ irq_gc_lock(gc);
+ reg_val = irq_reg_readl(gc, ct->regs.mask);
+ reg_val &= ~mask;
+ irq_reg_writel(gc, reg_val, ct->regs.mask);
+ irq_gc_unlock(gc);
+}
+
+void __init orion_gpio_init(struct device_node *np,
+ int gpio_base, int ngpio,
+ void __iomem *base, int mask_offset,
+ int secondary_irq_base,
+ int irqs[4])
+{
+ struct orion_gpio_chip *ochip;
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+ char gc_label[16];
+ int i;
+
+ if (orion_gpio_chip_count == ARRAY_SIZE(orion_gpio_chips))
+ return;
+
+ snprintf(gc_label, sizeof(gc_label), "orion_gpio%d",
+ orion_gpio_chip_count);
+
+ ochip = orion_gpio_chips + orion_gpio_chip_count;
+ ochip->chip.label = kstrdup(gc_label, GFP_KERNEL);
+ 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;
+#ifdef CONFIG_OF
+ ochip->chip.of_node = np;
+#endif
+ ochip->chip.dbg_show = orion_gpio_dbg_show;
+
+ 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);
+
+ /*
+ * Mask and clear GPIO interrupts.
+ */
+ writel(0, GPIO_EDGE_CAUSE(ochip));
+ writel(0, GPIO_EDGE_MASK(ochip));
+ writel(0, GPIO_LEVEL_MASK(ochip));
+
+ /* Setup the interrupt handlers. Each chip can have up to 4
+ * interrupt handlers, with each handler dealing with 8 GPIO
+ * pins. */
+
+ for (i = 0; i < 4; i++) {
+ if (irqs[i]) {
+ irq_set_handler_data(irqs[i], ochip);
+ irq_set_chained_handler(irqs[i], gpio_irq_handler);
+ }
+ }
+
+ 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 = orion_gpio_mask_irq;
+ ct->chip.irq_unmask = orion_gpio_unmask_irq;
+ ct->chip.irq_set_type = gpio_irq_set_type;
+ ct->chip.name = ochip->chip.label;
+
+ 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 = orion_gpio_mask_irq;
+ ct->chip.irq_unmask = orion_gpio_unmask_irq;
+ ct->chip.irq_set_type = gpio_irq_set_type;
+ ct->handler = handle_edge_irq;
+ ct->chip.name = ochip->chip.label;
+
+ irq_setup_generic_chip(gc, IRQ_MSK(ngpio), IRQ_GC_INIT_MASK_CACHE,
+ IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
+
+ /* Setup irq domain on top of the generic chip. */
+ ochip->domain = irq_domain_add_legacy(np,
+ ochip->chip.ngpio,
+ ochip->secondary_irq_base,
+ ochip->secondary_irq_base,
+ &irq_domain_simple_ops,
+ ochip);
+ if (!ochip->domain)
+ panic("%s: couldn't allocate irq domain (DT).\n",
+ ochip->chip.label);
+
+ orion_gpio_chip_count++;
+}
diff --git a/arch/arm/plat-orion/include/plat/addr-map.h b/arch/arm/plat-orion/include/plat/addr-map.h
new file mode 100644
index 000000000..b76c06569
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/addr-map.h
@@ -0,0 +1,54 @@
+/*
+ * arch/arm/plat-orion/include/plat/addr-map.h
+ *
+ * Marvell Orion SoC address map 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_ADDR_MAP_H
+#define __PLAT_ADDR_MAP_H
+
+extern struct mbus_dram_target_info orion_mbus_dram_info;
+
+struct orion_addr_map_cfg {
+ const int num_wins; /* Total number of windows */
+ const int remappable_wins;
+ void __iomem *bridge_virt_base;
+ int hw_io_coherency;
+
+ /* If NULL, the default cpu_win_can_remap will be used, using
+ the value in remappable_wins */
+ int (*cpu_win_can_remap) (const struct orion_addr_map_cfg *cfg,
+ const int win);
+ /* If NULL, the default win_cfg_base will be used, using the
+ value in bridge_virt_base */
+ void __iomem *(*win_cfg_base) (const struct orion_addr_map_cfg *cfg,
+ const int win);
+};
+
+/*
+ * Information needed to setup one address mapping.
+ */
+struct orion_addr_map_info {
+ const int win;
+ const u32 base;
+ const u32 size;
+ const u8 target;
+ const u8 attr;
+ const int remap;
+};
+
+void __init orion_config_wins(struct orion_addr_map_cfg *cfg,
+ const struct orion_addr_map_info *info);
+
+void __init orion_setup_cpu_win(const struct orion_addr_map_cfg *cfg,
+ const int win, const u32 base,
+ const u32 size, const u8 target,
+ const u8 attr, const int remap);
+
+void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
+ const void __iomem *ddr_window_cpu_base);
+#endif
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 000000000..d9a24f605
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/common.h
@@ -0,0 +1,113 @@
+/*
+ * 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>
+#include <linux/platform_data/usb-ehci-orion.h>
+
+struct dsa_platform_data;
+struct mv_sata_platform_data;
+
+void __init orion_uart0_init(void __iomem *membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ struct clk *clk);
+
+void __init orion_uart1_init(void __iomem *membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ struct clk *clk);
+
+void __init orion_uart2_init(void __iomem *membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ struct clk *clk);
+
+void __init orion_uart3_init(void __iomem *membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ struct clk *clk);
+
+void __init orion_rtc_init(unsigned long mapbase,
+ unsigned long irq);
+
+void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
+ unsigned long mapbase,
+ unsigned long irq,
+ unsigned long irq_err,
+ unsigned int tx_csum_limit);
+
+void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
+ unsigned long mapbase,
+ unsigned long irq,
+ unsigned long irq_err,
+ unsigned int tx_csum_limit);
+
+void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
+ unsigned long mapbase,
+ unsigned long irq,
+ unsigned long irq_err);
+
+void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
+ unsigned long mapbase,
+ unsigned long irq,
+ unsigned long irq_err);
+
+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);
+
+void __init orion_spi_1_init(unsigned long mapbase);
+
+void __init orion_wdt_init(void);
+
+void __init orion_xor0_init(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(unsigned long mapbase,
+ unsigned long irq,
+ enum orion_ehci_phy_ver phy_version);
+
+void __init orion_ehci_1_init(unsigned long mapbase,
+ unsigned long irq);
+
+void __init orion_ehci_2_init(unsigned long mapbase,
+ unsigned long irq);
+
+void __init orion_sata_init(struct mv_sata_platform_data *sata_data,
+ unsigned long mapbase,
+ unsigned long irq);
+
+void __init orion_crypto_init(unsigned long mapbase,
+ unsigned long srambase,
+ unsigned long sram_size,
+ unsigned long irq);
+
+void __init orion_clkdev_add(const char *con_id, const char *dev_id,
+ struct clk *clk);
+
+void __init orion_clkdev_init(struct clk *tclk);
+#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 000000000..96be19e9b
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/irq.h
@@ -0,0 +1,15 @@
+/*
+ * 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 000000000..254552fee
--- /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, void __iomem *dev_bus);
+
+#endif
diff --git a/arch/arm/plat-orion/include/plat/orion-gpio.h b/arch/arm/plat-orion/include/plat/orion-gpio.h
new file mode 100644
index 000000000..e856b073a
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/orion-gpio.h
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/plat-orion/include/plat/orion-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 <linux/types.h>
+#include <linux/irqdomain.h>
+
+struct gpio_desc;
+
+/*
+ * Orion-specific GPIO API extensions.
+ */
+void orion_gpio_set_unused(unsigned pin);
+void orion_gpio_set_blink(unsigned pin, int blink);
+int orion_gpio_led_blink_set(struct gpio_desc *desc, int state,
+ unsigned long *delay_on, unsigned long *delay_off);
+
+#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(struct device_node *np,
+ int gpio_base, int ngpio,
+ void __iomem *base, int mask_offset,
+ int secondary_irq_base,
+ int irq[4]);
+
+#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 000000000..fe5b9e862
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/pcie.h
@@ -0,0 +1,34 @@
+/*
+ * 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);
+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 000000000..07527e417
--- /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(void __iomem *timer_base);
+
+void orion_time_init(void __iomem *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 000000000..8c1fc0600
--- /dev/null
+++ b/arch/arm/plat-orion/irq.c
@@ -0,0 +1,40 @@
+/*
+ * 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/irqdomain.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <asm/exception.h>
+#include <plat/irq.h>
+#include <plat/orion-gpio.h>
+#include <mach/bridge-regs.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 000000000..7310bcfb2
--- /dev/null
+++ b/arch/arm/plat-orion/mpp.c
@@ -0,0 +1,78 @@
+/*
+ * 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/orion-gpio.h>
+#include <plat/mpp.h>
+
+/* Address of the ith MPP control register */
+static __init void __iomem *mpp_ctrl_addr(unsigned int i,
+ void __iomem *dev_bus)
+{
+ return dev_bus + (i) * 4;
+}
+
+
+void __init orion_mpp_conf(unsigned int *mpp_list, unsigned int variant_mask,
+ unsigned int mpp_max, void __iomem *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 000000000..8b8c06d2e
--- /dev/null
+++ b/arch/arm/plat-orion/pcie.c
@@ -0,0 +1,288 @@
+/*
+ * 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 <plat/addr-map.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 orion_pcie_dev_id(void __iomem *base)
+{
+ return readl(base + PCIE_DEV_ID_OFF) >> 16;
+}
+
+u32 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)
+{
+ const struct mbus_dram_target_info *dram;
+ u32 size;
+ int i;
+
+ dram = mv_mbus_dram_info();
+
+ /*
+ * 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++) {
+ const 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)
+{
+ u16 cmd;
+ u32 mask;
+
+ /*
+ * Point PCIe unit MBUS decode windows to DRAM space.
+ */
+ orion_pcie_setup_wins(base);
+
+ /*
+ * 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 000000000..261258f71
--- /dev/null
+++ b/arch/arm/plat-orion/time.c
@@ -0,0 +1,226 @@
+/*
+ * 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/timer.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sched_clock.h>
+#include <plat/time.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 u64 notrace orion_read_sched_clock(void)
+{
+ return ~readl(timer_base + TIMER0_VAL_OFF);
+}
+
+/*
+ * 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,
+ .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_TIMER,
+ .handler = orion_timer_interrupt
+};
+
+void __init
+orion_time_set_base(void __iomem *_timer_base)
+{
+ timer_base = _timer_base;
+}
+
+void __init
+orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask,
+ unsigned int irq, unsigned int tclk)
+{
+ u32 u;
+
+ /*
+ * Set SoC-specific data.
+ */
+ bridge_base = _bridge_base;
+ bridge_timer1_clr_mask = _bridge_timer1_clr_mask;
+
+ ticks_per_jiffy = (tclk + HZ/2) / HZ;
+
+ /*
+ * Set scale and timer for sched_clock.
+ */
+ sched_clock_register(orion_read_sched_clock, 32, 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.cpumask = cpumask_of(0);
+ clockevents_config_and_register(&orion_clkevt, tclk, 1, 0xfffffffe);
+}
diff --git a/arch/arm/plat-pxa/Kconfig b/arch/arm/plat-pxa/Kconfig
new file mode 100644
index 000000000..da53395a1
--- /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 000000000..1fc941944
--- /dev/null
+++ b/arch/arm/plat-pxa/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for code common across different PXA processor families
+#
+
+obj-y := dma.o
+
+obj-$(CONFIG_PXA3xx) += mfp.o
+obj-$(CONFIG_ARCH_MMP) += mfp.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 000000000..d92f07f6e
--- /dev/null
+++ b/arch/arm/plat-pxa/dma.c
@@ -0,0 +1,386 @@
+/*
+ * 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/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 chan = (int)s->private;
+ int i;
+ u32 drcmr;
+
+ 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)
+ seq_printf(s, "\tRequester %d (MAPVLD=%d)\n",
+ i, !!(drcmr & DRCMR_MAPVLD));
+ }
+
+ return 0;
+}
+
+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 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);
+
+ seq_printf(s, "DMA channel %d descriptors :\n", chan);
+ 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;
+
+ seq_printf(s, "[%03d] Desc at %08lx(virt %p)\n",
+ i, phys_desc, desc);
+ seq_printf(s, "\tDDADR = %08x\n", desc->ddadr);
+ seq_printf(s, "\tDSADR = %08x\n", desc->dsadr);
+ seq_printf(s, "\tDTADR = %08x\n", desc->dtadr);
+ 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)
+ seq_printf(s, "[%03d] Desc at %08lx ... max display reached\n",
+ i, phys_desc);
+ else
+ 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 0;
+}
+
+static int dbg_show_chan_state(struct seq_file *s, void *p)
+{
+ 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;
+
+ seq_printf(s, "DMA channel %d\n", chan);
+ seq_printf(s, "\tPriority : %s\n", str_prio[dma_channels[chan].prio]);
+ seq_printf(s, "\tUnaligned transfer bit: %s\n",
+ DALGN & (1 << chan) ? "yes" : "no");
+ 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));
+
+ 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);
+ seq_printf(s, "\tDSADR = %08x\n", DSADR(chan));
+ seq_printf(s, "\tDTADR = %08x\n", DTADR(chan));
+ seq_printf(s, "\tDDADR = %08x\n", DDADR(chan));
+
+ return 0;
+}
+
+static int dbg_show_state(struct seq_file *s, void *p)
+{
+ /* basic device status */
+ seq_puts(s, "DMA engine status\n");
+ seq_printf(s, "\tChannel number: %d\n", num_dma_channels);
+
+ return 0;
+}
+
+#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, 0, "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/include/plat/dma.h b/arch/arm/plat-pxa/include/plat/dma.h
new file mode 100644
index 000000000..a7b91dc06
--- /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/mfp.h b/arch/arm/plat-pxa/include/plat/mfp.h
new file mode 100644
index 000000000..10bc4f375
--- /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_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(void __iomem *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_ARCH_MMP */
+
+#endif /* __ASM_PLAT_MFP_H */
diff --git a/arch/arm/plat-pxa/mfp.c b/arch/arm/plat-pxa/mfp.c
new file mode 100644
index 000000000..2c4dbb1f4
--- /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(void __iomem *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 = 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/ssp.c b/arch/arm/plat-pxa/ssp.c
new file mode 100644
index 000000000..ad9529cc4
--- /dev/null
+++ b/arch/arm/plat-pxa/ssp.c
@@ -0,0 +1,292 @@
+/*
+ * 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 <linux/of.h>
+#include <linux/of_device.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);
+
+struct ssp_device *pxa_ssp_request_of(const struct device_node *of_node,
+ const char *label)
+{
+ struct ssp_device *ssp = NULL;
+
+ mutex_lock(&ssp_lock);
+
+ list_for_each_entry(ssp, &ssp_list, node) {
+ if (ssp->of_node == of_node && 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_of);
+
+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);
+
+#ifdef CONFIG_OF
+static const struct of_device_id pxa_ssp_of_ids[] = {
+ { .compatible = "mrvl,pxa25x-ssp", .data = (void *) PXA25x_SSP },
+ { .compatible = "mvrl,pxa25x-nssp", .data = (void *) PXA25x_NSSP },
+ { .compatible = "mrvl,pxa27x-ssp", .data = (void *) PXA27x_SSP },
+ { .compatible = "mrvl,pxa3xx-ssp", .data = (void *) PXA3xx_SSP },
+ { .compatible = "mvrl,pxa168-ssp", .data = (void *) PXA168_SSP },
+ { .compatible = "mrvl,pxa910-ssp", .data = (void *) PXA910_SSP },
+ { .compatible = "mrvl,ce4100-ssp", .data = (void *) CE4100_SSP },
+ { .compatible = "mrvl,lpss-ssp", .data = (void *) LPSS_SSP },
+ { },
+};
+MODULE_DEVICE_TABLE(of, pxa_ssp_of_ids);
+#endif
+
+static int pxa_ssp_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct ssp_device *ssp;
+ struct device *dev = &pdev->dev;
+
+ ssp = devm_kzalloc(dev, sizeof(struct ssp_device), GFP_KERNEL);
+ if (ssp == NULL)
+ return -ENOMEM;
+
+ ssp->pdev = pdev;
+
+ ssp->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(ssp->clk))
+ return PTR_ERR(ssp->clk);
+
+ if (dev->of_node) {
+ struct of_phandle_args dma_spec;
+ struct device_node *np = dev->of_node;
+ int ret;
+
+ /*
+ * FIXME: we should allocate the DMA channel from this
+ * context and pass the channel down to the ssp users.
+ * For now, we lookup the rx and tx indices manually
+ */
+
+ /* rx */
+ ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells",
+ 0, &dma_spec);
+
+ if (ret) {
+ dev_err(dev, "Can't parse dmas property\n");
+ return -ENODEV;
+ }
+ ssp->drcmr_rx = dma_spec.args[0];
+ of_node_put(dma_spec.np);
+
+ /* tx */
+ ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells",
+ 1, &dma_spec);
+ if (ret) {
+ dev_err(dev, "Can't parse dmas property\n");
+ return -ENODEV;
+ }
+ ssp->drcmr_tx = dma_spec.args[0];
+ of_node_put(dma_spec.np);
+ } else {
+ res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+ if (res == NULL) {
+ dev_err(dev, "no SSP RX DRCMR defined\n");
+ return -ENODEV;
+ }
+ ssp->drcmr_rx = res->start;
+
+ res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+ if (res == NULL) {
+ dev_err(dev, "no SSP TX DRCMR defined\n");
+ return -ENODEV;
+ }
+ ssp->drcmr_tx = res->start;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(dev, "no memory resource defined\n");
+ return -ENODEV;
+ }
+
+ res = devm_request_mem_region(dev, res->start, resource_size(res),
+ pdev->name);
+ if (res == NULL) {
+ dev_err(dev, "failed to request memory resource\n");
+ return -EBUSY;
+ }
+
+ ssp->phys_base = res->start;
+
+ ssp->mmio_base = devm_ioremap(dev, res->start, resource_size(res));
+ if (ssp->mmio_base == NULL) {
+ dev_err(dev, "failed to ioremap() registers\n");
+ return -ENODEV;
+ }
+
+ ssp->irq = platform_get_irq(pdev, 0);
+ if (ssp->irq < 0) {
+ dev_err(dev, "no IRQ resource defined\n");
+ return -ENODEV;
+ }
+
+ if (dev->of_node) {
+ const struct of_device_id *id =
+ of_match_device(of_match_ptr(pxa_ssp_of_ids), dev);
+ ssp->type = (int) id->data;
+ } else {
+ const struct platform_device_id *id =
+ platform_get_device_id(pdev);
+ ssp->type = (int) id->driver_data;
+
+ /* 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->of_node = dev->of_node;
+
+ mutex_lock(&ssp_lock);
+ list_add(&ssp->node, &ssp_list);
+ mutex_unlock(&ssp_lock);
+
+ platform_set_drvdata(pdev, ssp);
+
+ return 0;
+}
+
+static int 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 },
+ { "pxa3xx-ssp", PXA3xx_SSP },
+ { "pxa168-ssp", PXA168_SSP },
+ { "pxa910-ssp", PXA910_SSP },
+ { },
+};
+
+static struct platform_driver pxa_ssp_driver = {
+ .probe = pxa_ssp_probe,
+ .remove = pxa_ssp_remove,
+ .driver = {
+ .name = "pxa2xx-ssp",
+ .of_match_table = of_match_ptr(pxa_ssp_of_ids),
+ },
+ .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-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
new file mode 100644
index 000000000..cb8e3d655
--- /dev/null
+++ b/arch/arm/plat-samsung/Kconfig
@@ -0,0 +1,323 @@
+# arch/arm/plat-samsung/Kconfig
+#
+# Copyright 2009 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config PLAT_SAMSUNG
+ bool
+ depends on PLAT_S3C24XX || ARCH_S3C64XX || ARCH_EXYNOS || ARCH_S5PV210
+ default y
+ select GENERIC_IRQ_CHIP
+ select NO_IOPORT_MAP
+ help
+ Base platform code for all Samsung SoC based systems
+
+config SAMSUNG_PM
+ bool
+ depends on PM && (PLAT_S3C24XX || ARCH_S3C64XX)
+ default y
+ help
+ Base platform power management code for samsung code
+
+if PLAT_SAMSUNG
+menu "Samsung Common options"
+
+# boot configurations
+
+comment "Boot options"
+
+config S3C_LOWLEVEL_UART_PORT
+ int "S3C UART to use for low-level messages"
+ depends on ARCH_S3C64XX
+ 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.
+
+config SAMSUNG_ATAGS
+ def_bool n
+ depends on !ARCH_MULTIPLATFORM
+ depends on ATAGS
+ help
+ This option enables ATAGS based boot support code for
+ Samsung platforms, including static platform devices, legacy
+ clock, timer and interrupt initialization, etc.
+
+ Platforms that support only DT based boot need not to select
+ this option.
+
+if SAMSUNG_ATAGS
+
+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_S3C24XX
+ 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_SPI0
+ bool
+ help
+ Compile in platform device definitions for S3C64XX's type
+ SPI controller 0
+
+config S3C64XX_DEV_SPI1
+ bool
+ help
+ Compile in platform device definitions for S3C64XX's type
+ SPI controller 1
+
+config S3C64XX_DEV_SPI2
+ bool
+ help
+ Compile in platform device definitions for S3C64XX's type
+ SPI controller 2
+
+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_S3C24XX
+ help
+ Compile in platform device definition for PWM Timer
+
+config SAMSUNG_DEV_BACKLIGHT
+ bool
+ depends on SAMSUNG_DEV_PWM
+ help
+ Compile in platform device definition LCD backlight with PWM Timer
+
+config S3C24XX_PWM
+ bool "PWM device support"
+ select PWM
+ select PWM_SAMSUNG
+ help
+ Support for exporting the PWM timer blocks via the pwm device
+ system
+
+config S3C_SETUP_CAMIF
+ bool
+ help
+ Compile in common setup code for S3C CAMIF devices
+
+config SAMSUNG_PM_GPIO
+ bool
+ default y if GPIO_SAMSUNG && PM
+ help
+ Include legacy GPIO power management code for platforms not using
+ pinctrl-samsung driver.
+
+endif
+
+config S5P_DEV_MFC
+ bool
+ help
+ Compile in setup memory (init) code for MFC
+
+comment "Power management"
+
+config SAMSUNG_PM_DEBUG
+ bool "Samsung PM Suspend debug"
+ depends on PM && DEBUG_KERNEL
+ depends on DEBUG_EXYNOS_UART || DEBUG_S3C24XX_UART || DEBUG_S3C2410_UART
+ 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
+ select 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>
+
+config SAMSUNG_WDT_RESET
+ bool
+ help
+ Compile support for system restart by triggering watchdog reset.
+ Used on SoCs that do not provide dedicated reset control.
+
+config DEBUG_S3C_UART
+ depends on PLAT_SAMSUNG
+ int
+ default "0" if DEBUG_S3C_UART0
+ default "1" if DEBUG_S3C_UART1
+ default "2" if DEBUG_S3C_UART2
+ default "3" if DEBUG_S3C_UART3
+
+endmenu
+endif
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
new file mode 100644
index 000000000..1a29ab1f4
--- /dev/null
+++ b/arch/arm/plat-samsung/Makefile
@@ -0,0 +1,39 @@
+# arch/arm/plat-samsung/Makefile
+#
+# Copyright 2009 Simtec Electronics
+#
+# Licensed under GPLv2
+
+ccflags-$(CONFIG_ARCH_MULTI_V7) += -I$(srctree)/$(src)/include
+
+# Objects we always build independent of SoC choice
+
+obj-y += init.o cpu.o
+
+# ADC
+
+obj-$(CONFIG_S3C_ADC) += adc.o
+
+# devices
+
+obj-$(CONFIG_SAMSUNG_ATAGS) += platformdata.o
+
+obj-$(CONFIG_SAMSUNG_ATAGS) += devs.o
+obj-$(CONFIG_SAMSUNG_ATAGS) += dev-uart.o
+obj-$(CONFIG_S5P_DEV_MFC) += s5p-dev-mfc.o
+
+obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o
+
+obj-$(CONFIG_S3C_SETUP_CAMIF) += setup-camif.o
+
+# PM support
+
+obj-$(CONFIG_PM_SLEEP) += pm-common.o
+obj-$(CONFIG_EXYNOS_CPU_SUSPEND) += pm-common.o
+obj-$(CONFIG_SAMSUNG_PM) += pm.o
+obj-$(CONFIG_SAMSUNG_PM_GPIO) += pm-gpio.o
+obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o
+obj-$(CONFIG_SAMSUNG_PM_DEBUG) += pm-debug.o
+
+obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o
+obj-$(CONFIG_SAMSUNG_WDT_RESET) += watchdog-reset.o
diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c
new file mode 100644
index 000000000..e2be70df0
--- /dev/null
+++ b/arch/arm/plat-samsung/adc.c
@@ -0,0 +1,525 @@
+/* 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 <linux/regulator/consumer.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_ADCV1, /* S3C24XX */
+ TYPE_ADCV11, /* S3C2443 */
+ TYPE_ADCV12, /* S3C2416, S3C2450 */
+ TYPE_ADCV2, /* S3C64XX */
+ TYPE_ADCV3, /* S5PV210, S5PC110, EXYNOS4210 */
+};
+
+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;
+ struct regulator *vdd;
+};
+
+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);
+ enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data;
+
+ client->select_cb(client, 1);
+
+ if (cpu == TYPE_ADCV1 || cpu == TYPE_ADCV2)
+ con &= ~S3C2410_ADCCON_MUXMASK;
+ con &= ~S3C2410_ADCCON_STDBM;
+ con &= ~S3C2410_ADCCON_STARTMASK;
+
+ if (!client->is_ts) {
+ if (cpu == TYPE_ADCV3)
+ writel(client->channel & 0xf, adc->regs + S5P_ADCMUX);
+ else if (cpu == TYPE_ADCV11 || cpu == TYPE_ADCV12)
+ writel(client->channel & 0xf,
+ adc->regs + S3C2443_ADCMUX);
+ else
+ con |= S3C2410_ADCCON_SELMUX(client->channel);
+ }
+
+ writel(con, adc->regs + S3C2410_ADCCON);
+}
+
+static void s3c_adc_dbgshow(struct adc_device *adc)
+{
+ adc_dbg(adc, "CON=%08x, TSC=%08x, DLY=%08x\n",
+ 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;
+ }
+
+ spin_lock_irqsave(&adc->lock, flags);
+
+ if (client->is_ts && adc->ts_pend) {
+ spin_unlock_irqrestore(&adc->lock, flags);
+ return -EAGAIN;
+ }
+
+ 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_ADCV1 || cpu == TYPE_ADCV11) {
+ data0 &= 0x3ff;
+ data1 &= 0x3ff;
+ } else {
+ /* S3C2416/S3C64XX/S5P ADC resolution is 12-bit */
+ data0 &= 0xfff;
+ data1 &= 0xfff;
+ }
+
+ if (client->convert_cb)
+ (client->convert_cb)(client, data0, data1, &client->nr_samples);
+
+ if (client->nr_samples > 0) {
+ /* fire another conversion for this */
+
+ client->select_cb(client, 1);
+ 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_ADCV2 || cpu == TYPE_ADCV3) {
+ /* 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;
+ enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data;
+ int ret;
+ unsigned tmp;
+
+ adc = devm_kzalloc(dev, 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->vdd = devm_regulator_get(dev, "vdd");
+ if (IS_ERR(adc->vdd)) {
+ dev_err(dev, "operating without regulator \"vdd\" .\n");
+ return PTR_ERR(adc->vdd);
+ }
+
+ adc->irq = platform_get_irq(pdev, 1);
+ if (adc->irq <= 0) {
+ dev_err(dev, "failed to get adc irq\n");
+ return -ENOENT;
+ }
+
+ ret = devm_request_irq(dev, adc->irq, s3c_adc_irq, 0, dev_name(dev),
+ adc);
+ if (ret < 0) {
+ dev_err(dev, "failed to attach adc irq\n");
+ return ret;
+ }
+
+ adc->clk = devm_clk_get(dev, "adc");
+ if (IS_ERR(adc->clk)) {
+ dev_err(dev, "failed to get adc clock\n");
+ return PTR_ERR(adc->clk);
+ }
+
+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ adc->regs = devm_ioremap_resource(dev, regs);
+ if (IS_ERR(adc->regs))
+ return PTR_ERR(adc->regs);
+
+ ret = regulator_enable(adc->vdd);
+ if (ret)
+ return ret;
+
+ clk_enable(adc->clk);
+
+ tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
+
+ /* Enable 12-bit ADC resolution */
+ if (cpu == TYPE_ADCV12)
+ tmp |= S3C2416_ADCCON_RESSEL;
+ if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3)
+ 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;
+}
+
+static int s3c_adc_remove(struct platform_device *pdev)
+{
+ struct adc_device *adc = platform_get_drvdata(pdev);
+
+ clk_disable(adc->clk);
+ regulator_disable(adc->vdd);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c_adc_suspend(struct device *dev)
+{
+ struct platform_device *pdev = container_of(dev,
+ struct platform_device, dev);
+ 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);
+ regulator_disable(adc->vdd);
+
+ return 0;
+}
+
+static int s3c_adc_resume(struct device *dev)
+{
+ struct platform_device *pdev = container_of(dev,
+ struct platform_device, dev);
+ struct adc_device *adc = platform_get_drvdata(pdev);
+ enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data;
+ int ret;
+ unsigned long tmp;
+
+ ret = regulator_enable(adc->vdd);
+ if (ret)
+ return ret;
+ clk_enable(adc->clk);
+ enable_irq(adc->irq);
+
+ tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
+
+ /* Enable 12-bit ADC resolution */
+ if (cpu == TYPE_ADCV12)
+ tmp |= S3C2416_ADCCON_RESSEL;
+ if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3)
+ tmp |= S3C64XX_ADCCON_RESSEL;
+
+ writel(tmp, 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_ADCV1,
+ }, {
+ .name = "s3c2443-adc",
+ .driver_data = TYPE_ADCV11,
+ }, {
+ .name = "s3c2416-adc",
+ .driver_data = TYPE_ADCV12,
+ }, {
+ .name = "s3c64xx-adc",
+ .driver_data = TYPE_ADCV2,
+ }, {
+ .name = "samsung-adc-v3",
+ .driver_data = TYPE_ADCV3,
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, s3c_adc_driver_ids);
+
+static const struct dev_pm_ops adc_pm_ops = {
+ .suspend = s3c_adc_suspend,
+ .resume = s3c_adc_resume,
+};
+
+static struct platform_driver s3c_adc_driver = {
+ .id_table = s3c_adc_driver_ids,
+ .driver = {
+ .name = "s3c-adc",
+ .pm = &adc_pm_ops,
+ },
+ .probe = s3c_adc_probe,
+ .remove = s3c_adc_remove,
+};
+
+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;
+}
+
+module_init(adc_init);
diff --git a/arch/arm/plat-samsung/cpu.c b/arch/arm/plat-samsung/cpu.c
new file mode 100644
index 000000000..71333bb61
--- /dev/null
+++ b/arch/arm/plat-samsung/cpu.c
@@ -0,0 +1,53 @@
+/* linux/arch/arm/plat-samsung/cpu.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung CPU Support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <plat/map-base.h>
+#include <plat/cpu.h>
+
+unsigned long samsung_cpu_id;
+static unsigned int samsung_cpu_rev;
+
+unsigned int samsung_rev(void)
+{
+ return samsung_cpu_rev;
+}
+EXPORT_SYMBOL(samsung_rev);
+
+void __init s3c64xx_init_cpu(void)
+{
+ samsung_cpu_id = __raw_readl(S3C_VA_SYS + 0x118);
+ if (!samsung_cpu_id) {
+ /*
+ * S3C6400 has the ID register in a different place,
+ * and needs a write before it can be read.
+ */
+ __raw_writel(0x0, S3C_VA_SYS + 0xA1C);
+ samsung_cpu_id = __raw_readl(S3C_VA_SYS + 0xA1C);
+ }
+
+ samsung_cpu_rev = 0;
+
+ pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id);
+}
+
+void __init s5p_init_cpu(void __iomem *cpuid_addr)
+{
+ samsung_cpu_id = __raw_readl(cpuid_addr);
+ samsung_cpu_rev = samsung_cpu_id & 0xFF;
+
+ pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id);
+}
diff --git a/arch/arm/plat-samsung/dev-backlight.c b/arch/arm/plat-samsung/dev-backlight.c
new file mode 100644
index 000000000..2157c5b53
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-backlight.c
@@ -0,0 +1,152 @@
+/* linux/arch/arm/plat-samsung/dev-backlight.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Common infrastructure for PWM Backlight for Samsung boards
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/pwm_backlight.h>
+
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/backlight.h>
+
+struct samsung_bl_drvdata {
+ struct platform_pwm_backlight_data plat_data;
+ struct samsung_bl_gpio_info *gpio_info;
+};
+
+static int samsung_bl_init(struct device *dev)
+{
+ int ret = 0;
+ struct platform_pwm_backlight_data *pdata = dev->platform_data;
+ struct samsung_bl_drvdata *drvdata = container_of(pdata,
+ struct samsung_bl_drvdata, plat_data);
+ struct samsung_bl_gpio_info *bl_gpio_info = drvdata->gpio_info;
+
+ ret = gpio_request(bl_gpio_info->no, "Backlight");
+ if (ret) {
+ printk(KERN_ERR "failed to request GPIO for LCD Backlight\n");
+ return ret;
+ }
+
+ /* Configure GPIO pin with specific GPIO function for PWM timer */
+ s3c_gpio_cfgpin(bl_gpio_info->no, bl_gpio_info->func);
+
+ return 0;
+}
+
+static void samsung_bl_exit(struct device *dev)
+{
+ struct platform_pwm_backlight_data *pdata = dev->platform_data;
+ struct samsung_bl_drvdata *drvdata = container_of(pdata,
+ struct samsung_bl_drvdata, plat_data);
+ struct samsung_bl_gpio_info *bl_gpio_info = drvdata->gpio_info;
+
+ s3c_gpio_cfgpin(bl_gpio_info->no, S3C_GPIO_OUTPUT);
+ gpio_free(bl_gpio_info->no);
+}
+
+/* Initialize few important fields of platform_pwm_backlight_data
+ * structure with default values. These fields can be overridden by
+ * board-specific values sent from machine file.
+ * For ease of operation, these fields are initialized with values
+ * used by most samsung boards.
+ * Users has the option of sending info about other parameters
+ * for their specific boards
+ */
+
+static struct samsung_bl_drvdata samsung_dfl_bl_data __initdata = {
+ .plat_data = {
+ .max_brightness = 255,
+ .dft_brightness = 255,
+ .pwm_period_ns = 78770,
+ .enable_gpio = -1,
+ .init = samsung_bl_init,
+ .exit = samsung_bl_exit,
+ },
+};
+
+static struct platform_device samsung_dfl_bl_device __initdata = {
+ .name = "pwm-backlight",
+};
+
+/* samsung_bl_set - Set board specific data (if any) provided by user for
+ * PWM Backlight control and register specific PWM and backlight device.
+ * @gpio_info: structure containing GPIO info for PWM timer
+ * @bl_data: structure containing Backlight control data
+ */
+void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
+ struct platform_pwm_backlight_data *bl_data)
+{
+ int ret = 0;
+ struct platform_device *samsung_bl_device;
+ struct samsung_bl_drvdata *samsung_bl_drvdata;
+ struct platform_pwm_backlight_data *samsung_bl_data;
+
+ samsung_bl_device = kmemdup(&samsung_dfl_bl_device,
+ sizeof(struct platform_device), GFP_KERNEL);
+ if (!samsung_bl_device) {
+ printk(KERN_ERR "%s: no memory for platform dev\n", __func__);
+ return;
+ }
+
+ samsung_bl_drvdata = kmemdup(&samsung_dfl_bl_data,
+ sizeof(samsung_dfl_bl_data), GFP_KERNEL);
+ if (!samsung_bl_drvdata) {
+ printk(KERN_ERR "%s: no memory for platform dev\n", __func__);
+ goto err_data;
+ }
+ samsung_bl_device->dev.platform_data = &samsung_bl_drvdata->plat_data;
+ samsung_bl_drvdata->gpio_info = gpio_info;
+ samsung_bl_data = &samsung_bl_drvdata->plat_data;
+
+ /* Copy board specific data provided by user */
+ samsung_bl_data->pwm_id = bl_data->pwm_id;
+ samsung_bl_device->dev.parent = &samsung_device_pwm.dev;
+
+ if (bl_data->max_brightness)
+ samsung_bl_data->max_brightness = bl_data->max_brightness;
+ if (bl_data->dft_brightness)
+ samsung_bl_data->dft_brightness = bl_data->dft_brightness;
+ if (bl_data->lth_brightness)
+ samsung_bl_data->lth_brightness = bl_data->lth_brightness;
+ if (bl_data->pwm_period_ns)
+ samsung_bl_data->pwm_period_ns = bl_data->pwm_period_ns;
+ if (bl_data->enable_gpio >= 0)
+ samsung_bl_data->enable_gpio = bl_data->enable_gpio;
+ if (bl_data->init)
+ samsung_bl_data->init = bl_data->init;
+ if (bl_data->notify)
+ samsung_bl_data->notify = bl_data->notify;
+ if (bl_data->notify_after)
+ samsung_bl_data->notify_after = bl_data->notify_after;
+ if (bl_data->exit)
+ samsung_bl_data->exit = bl_data->exit;
+ if (bl_data->check_fb)
+ samsung_bl_data->check_fb = bl_data->check_fb;
+
+ /* Register the Backlight dev */
+ ret = platform_device_register(samsung_bl_device);
+ if (ret) {
+ printk(KERN_ERR "failed to register backlight device: %d\n", ret);
+ goto err_plat_reg2;
+ }
+
+ return;
+
+err_plat_reg2:
+ kfree(samsung_bl_data);
+err_data:
+ kfree(samsung_bl_device);
+ return;
+}
diff --git a/arch/arm/plat-samsung/dev-uart.c b/arch/arm/plat-samsung/dev-uart.c
new file mode 100644
index 000000000..592810549
--- /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/devs.c b/arch/arm/plat-samsung/devs.c
new file mode 100644
index 000000000..83c7d154b
--- /dev/null
+++ b/arch/arm/plat-samsung/devs.c
@@ -0,0 +1,1229 @@
+/* linux/arch/arm/plat-samsung/devs.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Base SAMSUNG 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/amba/pl330.h>
+#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/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+#include <linux/fb.h>
+#include <linux/gfp.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mmc/host.h>
+#include <linux/ioport.h>
+#include <linux/sizes.h>
+#include <linux/platform_data/s3c-hsudc.h>
+#include <linux/platform_data/s3c-hsotg.h>
+#include <linux/platform_data/dma-s3c24xx.h>
+
+#include <media/s5p_hdmi.h>
+
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/dma.h>
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/adc.h>
+#include <linux/platform_data/ata-samsung_cf.h>
+#include <plat/fb.h>
+#include <plat/fb-s3c2410.h>
+#include <linux/platform_data/hwmon-s3c.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <plat/keypad.h>
+#include <linux/platform_data/mmc-s3cmci.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <plat/pwm-core.h>
+#include <plat/sdhci.h>
+#include <linux/platform_data/touchscreen-s3c2410.h>
+#include <linux/platform_data/usb-s3c2410_udc.h>
+#include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <plat/usb-phy.h>
+#include <plat/regs-spi.h>
+#include <linux/platform_data/spi-s3c64xx.h>
+
+static u64 samsung_device_dma_mask = DMA_BIT_MASK(32);
+
+/* AC97 */
+#ifdef CONFIG_CPU_S3C2440
+static struct resource s3c_ac97_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2440_PA_AC97, S3C2440_SZ_AC97),
+ [1] = DEFINE_RES_IRQ(IRQ_S3C244X_AC97),
+ [2] = DEFINE_RES_DMA_NAMED(DMACH_PCM_OUT, "PCM out"),
+ [3] = DEFINE_RES_DMA_NAMED(DMACH_PCM_IN, "PCM in"),
+ [4] = DEFINE_RES_DMA_NAMED(DMACH_MIC_IN, "Mic in"),
+};
+
+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 = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+#endif /* CONFIG_CPU_S3C2440 */
+
+/* ADC */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_adc_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C24XX_PA_ADC, S3C24XX_SZ_ADC),
+ [1] = DEFINE_RES_IRQ(IRQ_TC),
+ [2] = DEFINE_RES_IRQ(IRQ_ADC),
+};
+
+struct platform_device s3c_device_adc = {
+ .name = "s3c24xx-adc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_adc_resource),
+ .resource = s3c_adc_resource,
+};
+#endif /* CONFIG_PLAT_S3C24XX */
+
+#if defined(CONFIG_SAMSUNG_DEV_ADC)
+static struct resource s3c_adc_resource[] = {
+ [0] = DEFINE_RES_MEM(SAMSUNG_PA_ADC, SZ_256),
+ [1] = DEFINE_RES_IRQ(IRQ_TC),
+ [2] = DEFINE_RES_IRQ(IRQ_ADC),
+};
+
+struct platform_device s3c_device_adc = {
+ .name = "samsung-adc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_adc_resource),
+ .resource = s3c_adc_resource,
+};
+#endif /* CONFIG_SAMSUNG_DEV_ADC */
+
+/* Camif Controller */
+
+#ifdef CONFIG_CPU_S3C2440
+static struct resource s3c_camif_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2440_PA_CAMIF, S3C2440_SZ_CAMIF),
+ [1] = DEFINE_RES_IRQ(IRQ_S3C2440_CAM_C),
+ [2] = DEFINE_RES_IRQ(IRQ_S3C2440_CAM_P),
+};
+
+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 = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+#endif /* CONFIG_CPU_S3C2440 */
+
+/* FB */
+
+#ifdef CONFIG_S3C_DEV_FB
+static struct resource s3c_fb_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_FB, SZ_16K),
+ [1] = DEFINE_RES_IRQ(IRQ_LCD_VSYNC),
+ [2] = DEFINE_RES_IRQ(IRQ_LCD_FIFO),
+ [3] = DEFINE_RES_IRQ(IRQ_LCD_SYSTEM),
+};
+
+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 = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
+{
+ s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
+ &s3c_device_fb);
+}
+#endif /* CONFIG_S3C_DEV_FB */
+
+/* HWMON */
+
+#ifdef CONFIG_S3C_DEV_HWMON
+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)
+{
+ s3c_set_platdata(pd, sizeof(struct s3c_hwmon_pdata),
+ &s3c_device_hwmon);
+}
+#endif /* CONFIG_S3C_DEV_HWMON */
+
+/* HSMMC */
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static struct resource s3c_hsmmc_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_HSMMC0, SZ_4K),
+ [1] = DEFINE_RES_IRQ(IRQ_HSMMC0),
+};
+
+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),
+};
+
+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 = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s3c_hsmmc0_def_platdata,
+ },
+};
+
+void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+ s3c_sdhci_set_platdata(pd, &s3c_hsmmc0_def_platdata);
+}
+#endif /* CONFIG_S3C_DEV_HSMMC */
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static struct resource s3c_hsmmc1_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_HSMMC1, SZ_4K),
+ [1] = DEFINE_RES_IRQ(IRQ_HSMMC1),
+};
+
+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),
+};
+
+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 = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s3c_hsmmc1_def_platdata,
+ },
+};
+
+void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+ s3c_sdhci_set_platdata(pd, &s3c_hsmmc1_def_platdata);
+}
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+
+/* HSMMC2 */
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static struct resource s3c_hsmmc2_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_HSMMC2, SZ_4K),
+ [1] = DEFINE_RES_IRQ(IRQ_HSMMC2),
+};
+
+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),
+};
+
+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 = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s3c_hsmmc2_def_platdata,
+ },
+};
+
+void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+ s3c_sdhci_set_platdata(pd, &s3c_hsmmc2_def_platdata);
+}
+#endif /* CONFIG_S3C_DEV_HSMMC2 */
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+static struct resource s3c_hsmmc3_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_HSMMC3, SZ_4K),
+ [1] = DEFINE_RES_IRQ(IRQ_HSMMC3),
+};
+
+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),
+};
+
+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 = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s3c_hsmmc3_def_platdata,
+ },
+};
+
+void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+ s3c_sdhci_set_platdata(pd, &s3c_hsmmc3_def_platdata);
+}
+#endif /* CONFIG_S3C_DEV_HSMMC3 */
+
+/* I2C */
+
+static struct resource s3c_i2c0_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_IIC, SZ_4K),
+ [1] = DEFINE_RES_IRQ(IRQ_IIC),
+};
+
+struct platform_device s3c_device_i2c0 = {
+ .name = "s3c2410-i2c",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_i2c0_resource),
+ .resource = s3c_i2c0_resource,
+};
+
+struct s3c2410_platform_i2c default_i2c_data __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_data;
+ pd->bus_num = 0;
+ }
+
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c0);
+
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c0_cfg_gpio;
+}
+
+#ifdef CONFIG_S3C_DEV_I2C1
+static struct resource s3c_i2c1_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_IIC1, SZ_4K),
+ [1] = DEFINE_RES_IRQ(IRQ_IIC1),
+};
+
+struct platform_device s3c_device_i2c1 = {
+ .name = "s3c2410-i2c",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c_i2c1_resource),
+ .resource = s3c_i2c1_resource,
+};
+
+void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 1;
+ }
+
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c1);
+
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c1_cfg_gpio;
+}
+#endif /* CONFIG_S3C_DEV_I2C1 */
+
+#ifdef CONFIG_S3C_DEV_I2C2
+static struct resource s3c_i2c2_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_IIC2, SZ_4K),
+ [1] = DEFINE_RES_IRQ(IRQ_IIC2),
+};
+
+struct platform_device s3c_device_i2c2 = {
+ .name = "s3c2410-i2c",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s3c_i2c2_resource),
+ .resource = s3c_i2c2_resource,
+};
+
+void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 2;
+ }
+
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c2);
+
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c2_cfg_gpio;
+}
+#endif /* CONFIG_S3C_DEV_I2C2 */
+
+#ifdef CONFIG_S3C_DEV_I2C3
+static struct resource s3c_i2c3_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_IIC3, SZ_4K),
+ [1] = DEFINE_RES_IRQ(IRQ_IIC3),
+};
+
+struct platform_device s3c_device_i2c3 = {
+ .name = "s3c2440-i2c",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(s3c_i2c3_resource),
+ .resource = s3c_i2c3_resource,
+};
+
+void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 3;
+ }
+
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c3);
+
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c3_cfg_gpio;
+}
+#endif /*CONFIG_S3C_DEV_I2C3 */
+
+#ifdef CONFIG_S3C_DEV_I2C4
+static struct resource s3c_i2c4_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_IIC4, SZ_4K),
+ [1] = DEFINE_RES_IRQ(IRQ_IIC4),
+};
+
+struct platform_device s3c_device_i2c4 = {
+ .name = "s3c2440-i2c",
+ .id = 4,
+ .num_resources = ARRAY_SIZE(s3c_i2c4_resource),
+ .resource = s3c_i2c4_resource,
+};
+
+void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 4;
+ }
+
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c4);
+
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c4_cfg_gpio;
+}
+#endif /*CONFIG_S3C_DEV_I2C4 */
+
+#ifdef CONFIG_S3C_DEV_I2C5
+static struct resource s3c_i2c5_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_IIC5, SZ_4K),
+ [1] = DEFINE_RES_IRQ(IRQ_IIC5),
+};
+
+struct platform_device s3c_device_i2c5 = {
+ .name = "s3c2440-i2c",
+ .id = 5,
+ .num_resources = ARRAY_SIZE(s3c_i2c5_resource),
+ .resource = s3c_i2c5_resource,
+};
+
+void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 5;
+ }
+
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c5);
+
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c5_cfg_gpio;
+}
+#endif /*CONFIG_S3C_DEV_I2C5 */
+
+#ifdef CONFIG_S3C_DEV_I2C6
+static struct resource s3c_i2c6_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_IIC6, SZ_4K),
+ [1] = DEFINE_RES_IRQ(IRQ_IIC6),
+};
+
+struct platform_device s3c_device_i2c6 = {
+ .name = "s3c2440-i2c",
+ .id = 6,
+ .num_resources = ARRAY_SIZE(s3c_i2c6_resource),
+ .resource = s3c_i2c6_resource,
+};
+
+void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 6;
+ }
+
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c6);
+
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c6_cfg_gpio;
+}
+#endif /* CONFIG_S3C_DEV_I2C6 */
+
+#ifdef CONFIG_S3C_DEV_I2C7
+static struct resource s3c_i2c7_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_IIC7, SZ_4K),
+ [1] = DEFINE_RES_IRQ(IRQ_IIC7),
+};
+
+struct platform_device s3c_device_i2c7 = {
+ .name = "s3c2440-i2c",
+ .id = 7,
+ .num_resources = ARRAY_SIZE(s3c_i2c7_resource),
+ .resource = s3c_i2c7_resource,
+};
+
+void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 7;
+ }
+
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c7);
+
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c7_cfg_gpio;
+}
+#endif /* CONFIG_S3C_DEV_I2C7 */
+
+/* I2S */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_iis_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C24XX_PA_IIS, S3C24XX_SZ_IIS),
+};
+
+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 = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+#endif /* CONFIG_PLAT_S3C24XX */
+
+/* IDE CFCON */
+
+#ifdef CONFIG_SAMSUNG_DEV_IDE
+static struct resource s3c_cfcon_resource[] = {
+ [0] = DEFINE_RES_MEM(SAMSUNG_PA_CFCON, SZ_16K),
+ [1] = DEFINE_RES_IRQ(IRQ_CFCON),
+};
+
+struct platform_device s3c_device_cfcon = {
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_cfcon_resource),
+ .resource = s3c_cfcon_resource,
+};
+
+void __init s3c_ide_set_platdata(struct s3c_ide_platdata *pdata)
+{
+ s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata),
+ &s3c_device_cfcon);
+}
+#endif /* CONFIG_SAMSUNG_DEV_IDE */
+
+/* KEYPAD */
+
+#ifdef CONFIG_SAMSUNG_DEV_KEYPAD
+static struct resource samsung_keypad_resources[] = {
+ [0] = DEFINE_RES_MEM(SAMSUNG_PA_KEYPAD, SZ_32),
+ [1] = DEFINE_RES_IRQ(IRQ_KEYPAD),
+};
+
+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;
+}
+#endif /* CONFIG_SAMSUNG_DEV_KEYPAD */
+
+/* LCD Controller */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_lcd_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C24XX_PA_LCD, S3C24XX_SZ_LCD),
+ [1] = DEFINE_RES_IRQ(IRQ_LCD),
+};
+
+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 = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+
+void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
+{
+ struct s3c2410fb_mach_info *npd;
+
+ npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_lcd);
+ if (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");
+ }
+}
+#endif /* CONFIG_PLAT_S3C24XX */
+
+/* NAND */
+
+#ifdef CONFIG_S3C_DEV_NAND
+static struct resource s3c_nand_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_NAND, SZ_1M),
+};
+
+struct platform_device s3c_device_nand = {
+ .name = "s3c2410-nand",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_nand_resource),
+ .resource = s3c_nand_resource,
+};
+
+/*
+ * 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 = s3c_set_platdata(nand, sizeof(struct s3c2410_platform_nand),
+ &s3c_device_nand);
+ if (!npd)
+ return;
+
+ /* now see if we need to copy any of the nand set data */
+
+ 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++;
+ }
+ }
+}
+#endif /* CONFIG_S3C_DEV_NAND */
+
+/* ONENAND */
+
+#ifdef CONFIG_S3C_DEV_ONENAND
+static struct resource s3c_onenand_resources[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_ONENAND, SZ_1K),
+ [1] = DEFINE_RES_MEM(S3C_PA_ONENAND_BUF, S3C_SZ_ONENAND_BUF),
+ [2] = DEFINE_RES_IRQ(IRQ_ONENAND),
+};
+
+struct platform_device s3c_device_onenand = {
+ .name = "samsung-onenand",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_onenand_resources),
+ .resource = s3c_onenand_resources,
+};
+#endif /* CONFIG_S3C_DEV_ONENAND */
+
+#ifdef CONFIG_S3C64XX_DEV_ONENAND1
+static struct resource s3c64xx_onenand1_resources[] = {
+ [0] = DEFINE_RES_MEM(S3C64XX_PA_ONENAND1, SZ_1K),
+ [1] = DEFINE_RES_MEM(S3C64XX_PA_ONENAND1_BUF, S3C64XX_SZ_ONENAND1_BUF),
+ [2] = DEFINE_RES_IRQ(IRQ_ONENAND1),
+};
+
+struct platform_device s3c64xx_device_onenand1 = {
+ .name = "samsung-onenand",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c64xx_onenand1_resources),
+ .resource = s3c64xx_onenand1_resources,
+};
+
+void __init s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata)
+{
+ s3c_set_platdata(pdata, sizeof(struct onenand_platform_data),
+ &s3c64xx_device_onenand1);
+}
+#endif /* CONFIG_S3C64XX_DEV_ONENAND1 */
+
+/* PWM Timer */
+
+#ifdef CONFIG_SAMSUNG_DEV_PWM
+static struct resource samsung_pwm_resource[] = {
+ DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K),
+};
+
+struct platform_device samsung_device_pwm = {
+ .name = "samsung-pwm",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(samsung_pwm_resource),
+ .resource = samsung_pwm_resource,
+};
+
+void __init samsung_pwm_set_platdata(struct samsung_pwm_variant *pd)
+{
+ samsung_device_pwm.dev.platform_data = pd;
+}
+#endif /* CONFIG_SAMSUNG_DEV_PWM */
+
+/* RTC */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_rtc_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C24XX_PA_RTC, SZ_256),
+ [1] = DEFINE_RES_IRQ(IRQ_RTC),
+ [2] = DEFINE_RES_IRQ(IRQ_TICK),
+};
+
+struct platform_device s3c_device_rtc = {
+ .name = "s3c2410-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_rtc_resource),
+ .resource = s3c_rtc_resource,
+};
+#endif /* CONFIG_PLAT_S3C24XX */
+
+#ifdef CONFIG_S3C_DEV_RTC
+static struct resource s3c_rtc_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_RTC, SZ_256),
+ [1] = DEFINE_RES_IRQ(IRQ_RTC_ALARM),
+ [2] = DEFINE_RES_IRQ(IRQ_RTC_TIC),
+};
+
+struct platform_device s3c_device_rtc = {
+ .name = "s3c64xx-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_rtc_resource),
+ .resource = s3c_rtc_resource,
+};
+#endif /* CONFIG_S3C_DEV_RTC */
+
+/* SDI */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_sdi_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C24XX_PA_SDI, S3C24XX_SZ_SDI),
+ [1] = DEFINE_RES_IRQ(IRQ_SDI),
+};
+
+struct platform_device s3c_device_sdi = {
+ .name = "s3c2410-sdi",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_sdi_resource),
+ .resource = s3c_sdi_resource,
+};
+
+void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata)
+{
+ s3c_set_platdata(pdata, sizeof(struct s3c24xx_mci_pdata),
+ &s3c_device_sdi);
+}
+#endif /* CONFIG_PLAT_S3C24XX */
+
+/* SPI */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_spi0_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI, SZ_32),
+ [1] = DEFINE_RES_IRQ(IRQ_SPI0),
+};
+
+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 = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+
+static struct resource s3c_spi1_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI1, SZ_32),
+ [1] = DEFINE_RES_IRQ(IRQ_SPI1),
+};
+
+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 = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+#endif /* CONFIG_PLAT_S3C24XX */
+
+/* Touchscreen */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_ts_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C24XX_PA_ADC, S3C24XX_SZ_ADC),
+ [1] = DEFINE_RES_IRQ(IRQ_TC),
+};
+
+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,
+};
+
+void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_info)
+{
+ s3c_set_platdata(hard_s3c2410ts_info,
+ sizeof(struct s3c2410_ts_mach_info), &s3c_device_ts);
+}
+#endif /* CONFIG_PLAT_S3C24XX */
+
+#ifdef CONFIG_SAMSUNG_DEV_TS
+static struct resource s3c_ts_resource[] = {
+ [0] = DEFINE_RES_MEM(SAMSUNG_PA_ADC, SZ_256),
+ [1] = DEFINE_RES_IRQ(IRQ_TC),
+};
+
+static struct s3c2410_ts_mach_info default_ts_data __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+};
+
+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)
+{
+ if (!pd)
+ pd = &default_ts_data;
+
+ s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info),
+ &s3c_device_ts);
+}
+#endif /* CONFIG_SAMSUNG_DEV_TS */
+
+/* USB */
+
+#ifdef CONFIG_S3C_DEV_USB_HOST
+static struct resource s3c_usb_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_USBHOST, SZ_256),
+ [1] = DEFINE_RES_IRQ(IRQ_USBH),
+};
+
+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 = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+
+/*
+ * 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)
+{
+ s3c_set_platdata(info, sizeof(struct s3c2410_hcd_info),
+ &s3c_device_ohci);
+}
+#endif /* CONFIG_S3C_DEV_USB_HOST */
+
+/* USB Device (Gadget) */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_usbgadget_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C24XX_PA_USBDEV, S3C24XX_SZ_USBDEV),
+ [1] = DEFINE_RES_IRQ(IRQ_USBD),
+};
+
+struct platform_device s3c_device_usbgadget = {
+ .name = "s3c2410-usbgadget",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_usbgadget_resource),
+ .resource = s3c_usbgadget_resource,
+};
+
+void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)
+{
+ s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usbgadget);
+}
+#endif /* CONFIG_PLAT_S3C24XX */
+
+/* USB HSOTG */
+
+#ifdef CONFIG_S3C_DEV_USB_HSOTG
+static struct resource s3c_usb_hsotg_resources[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_USB_HSOTG, SZ_128K),
+ [1] = DEFINE_RES_IRQ(IRQ_OTG),
+};
+
+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 = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd)
+{
+ struct s3c_hsotg_plat *npd;
+
+ npd = s3c_set_platdata(pd, sizeof(struct s3c_hsotg_plat),
+ &s3c_device_usb_hsotg);
+
+ if (!npd->phy_init)
+ npd->phy_init = s5p_usb_phy_init;
+ if (!npd->phy_exit)
+ npd->phy_exit = s5p_usb_phy_exit;
+}
+#endif /* CONFIG_S3C_DEV_USB_HSOTG */
+
+/* USB High Spped 2.0 Device (Gadget) */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_hsudc_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2416_PA_HSUDC, S3C2416_SZ_HSUDC),
+ [1] = DEFINE_RES_IRQ(IRQ_USBD),
+};
+
+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 = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd)
+{
+ s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usb_hsudc);
+}
+#endif /* CONFIG_PLAT_S3C24XX */
+
+/* WDT */
+
+#ifdef CONFIG_S3C_DEV_WDT
+static struct resource s3c_wdt_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_WDT, SZ_1K),
+ [1] = DEFINE_RES_IRQ(IRQ_WDT),
+};
+
+struct platform_device s3c_device_wdt = {
+ .name = "s3c2410-wdt",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_wdt_resource),
+ .resource = s3c_wdt_resource,
+};
+#endif /* CONFIG_S3C_DEV_WDT */
+
+#ifdef CONFIG_S3C64XX_DEV_SPI0
+static struct resource s3c64xx_spi0_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_SPI0, SZ_256),
+ [1] = DEFINE_RES_DMA(DMACH_SPI0_TX),
+ [2] = DEFINE_RES_DMA(DMACH_SPI0_RX),
+ [3] = DEFINE_RES_IRQ(IRQ_SPI0),
+};
+
+struct platform_device s3c64xx_device_spi0 = {
+ .name = "s3c6410-spi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource),
+ .resource = s3c64xx_spi0_resource,
+ .dev = {
+ .dma_mask = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
+ int num_cs)
+{
+ struct s3c64xx_spi_info pd;
+
+ /* Reject invalid configuration */
+ if (!num_cs || src_clk_nr < 0) {
+ pr_err("%s: Invalid SPI configuration\n", __func__);
+ return;
+ }
+
+ pd.num_cs = num_cs;
+ pd.src_clk_nr = src_clk_nr;
+ pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio;
+#if defined(CONFIG_PL330_DMA)
+ pd.filter = pl330_filter;
+#elif defined(CONFIG_S3C64XX_PL080)
+ pd.filter = pl08x_filter_id;
+#elif defined(CONFIG_S3C24XX_DMAC)
+ pd.filter = s3c24xx_dma_filter;
+#endif
+
+ s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0);
+}
+#endif /* CONFIG_S3C64XX_DEV_SPI0 */
+
+#ifdef CONFIG_S3C64XX_DEV_SPI1
+static struct resource s3c64xx_spi1_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_SPI1, SZ_256),
+ [1] = DEFINE_RES_DMA(DMACH_SPI1_TX),
+ [2] = DEFINE_RES_DMA(DMACH_SPI1_RX),
+ [3] = DEFINE_RES_IRQ(IRQ_SPI1),
+};
+
+struct platform_device s3c64xx_device_spi1 = {
+ .name = "s3c6410-spi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c64xx_spi1_resource),
+ .resource = s3c64xx_spi1_resource,
+ .dev = {
+ .dma_mask = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
+ int num_cs)
+{
+ struct s3c64xx_spi_info pd;
+
+ /* Reject invalid configuration */
+ if (!num_cs || src_clk_nr < 0) {
+ pr_err("%s: Invalid SPI configuration\n", __func__);
+ return;
+ }
+
+ pd.num_cs = num_cs;
+ pd.src_clk_nr = src_clk_nr;
+ pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio;
+#if defined(CONFIG_PL330_DMA)
+ pd.filter = pl330_filter;
+#elif defined(CONFIG_S3C64XX_PL080)
+ pd.filter = pl08x_filter_id;
+#endif
+
+ s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1);
+}
+#endif /* CONFIG_S3C64XX_DEV_SPI1 */
+
+#ifdef CONFIG_S3C64XX_DEV_SPI2
+static struct resource s3c64xx_spi2_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_SPI2, SZ_256),
+ [1] = DEFINE_RES_DMA(DMACH_SPI2_TX),
+ [2] = DEFINE_RES_DMA(DMACH_SPI2_RX),
+ [3] = DEFINE_RES_IRQ(IRQ_SPI2),
+};
+
+struct platform_device s3c64xx_device_spi2 = {
+ .name = "s3c6410-spi",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s3c64xx_spi2_resource),
+ .resource = s3c64xx_spi2_resource,
+ .dev = {
+ .dma_mask = &samsung_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
+ int num_cs)
+{
+ struct s3c64xx_spi_info pd;
+
+ /* Reject invalid configuration */
+ if (!num_cs || src_clk_nr < 0) {
+ pr_err("%s: Invalid SPI configuration\n", __func__);
+ return;
+ }
+
+ pd.num_cs = num_cs;
+ pd.src_clk_nr = src_clk_nr;
+ pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio;
+#if defined(CONFIG_PL330_DMA)
+ pd.filter = pl330_filter;
+#elif defined(CONFIG_S3C64XX_PL080)
+ pd.filter = pl08x_filter_id;
+#endif
+
+ s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2);
+}
+#endif /* CONFIG_S3C64XX_DEV_SPI2 */
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 000000000..a927bee55
--- /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)
+{
+#if defined(CONFIG_SAMSUNG_DEV_ADC) || defined(CONFIG_PLAT_S3C24XX)
+ 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 000000000..2fc893155
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/adc.h
@@ -0,0 +1,36 @@
+/* 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;
+struct platform_device;
+
+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 000000000..f5a4ec714
--- /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/backlight.h b/arch/arm/plat-samsung/include/plat/backlight.h
new file mode 100644
index 000000000..ad530c78f
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/backlight.h
@@ -0,0 +1,26 @@
+/* linux/arch/arm/plat-samsung/include/plat/backlight.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_PLAT_BACKLIGHT_H
+#define __ASM_PLAT_BACKLIGHT_H __FILE__
+
+/* samsung_bl_gpio_info - GPIO info for PWM Backlight control
+ * @no: GPIO number for PWM timer out
+ * @func: Special function of GPIO line for PWM timer
+ */
+struct samsung_bl_gpio_info {
+ int no;
+ int func;
+};
+
+extern void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
+ struct platform_pwm_backlight_data *bl_data);
+
+#endif /* __ASM_PLAT_BACKLIGHT_H */
diff --git a/arch/arm/plat-samsung/include/plat/cpu-freq-core.h b/arch/arm/plat-samsung/include/plat/cpu-freq-core.h
new file mode 100644
index 000000000..317c52303
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/cpu-freq-core.h
@@ -0,0 +1,291 @@
+/* arch/arm/plat-samsung/include/plat/cpu-freq-core.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 clk *mpll;
+ 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.
+ * @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 */
+
+ 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);
+
+#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_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 void s3c2410_iotiming_debugfs(struct seq_file *seq,
+ struct s3c_cpufreq_config *cfg,
+ union s3c_iobank *iob);
+
+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_debugfs NULL
+#define s3c2410_iotiming_calc NULL
+#define s3c2410_iotiming_get NULL
+#define s3c2410_iotiming_set NULL
+#endif /* CONFIG_S3C2410_IOTIMING */
+
+/* S3C2412 compatible routines */
+
+#ifdef CONFIG_S3C2412_IOTIMING
+extern void s3c2412_iotiming_debugfs(struct seq_file *seq,
+ struct s3c_cpufreq_config *cfg,
+ union s3c_iobank *iob);
+
+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);
+#else
+#define s3c2412_iotiming_debugfs NULL
+#define s3c2412_iotiming_calc NULL
+#define s3c2412_iotiming_get NULL
+#define s3c2412_iotiming_set NULL
+#endif /* CONFIG_S3C2412_IOTIMING */
+
+#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_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_ARM_S3C24XX_CPUFREQ_DEBUG */
+
+#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_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_ARM_S3C24XX_CPUFREQ_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].driver_data = index;
+ table[index].frequency = freq;
+ }
+
+ return index + 1;
+}
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 000000000..85517ab96
--- /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_ARM_S3C_CPUFREQ
+#define __init_or_cpufreq
+#else
+#define __init_or_cpufreq __init
+#endif
+
+/* Board functions */
+
+#ifdef CONFIG_ARM_S3C_CPUFREQ
+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_ARM_S3C_CPUFREQ */
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 000000000..61d14f3a0
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -0,0 +1,143 @@
+/* linux/arch/arm/plat-samsung/include/plat/cpu.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for Samsung CPU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* todo - fix when rmk changes iodescs to use `void __iomem *` */
+
+#ifndef __SAMSUNG_PLAT_CPU_H
+#define __SAMSUNG_PLAT_CPU_H
+
+extern unsigned long samsung_cpu_id;
+
+#define S3C2410_CPU_ID 0x32410000
+#define S3C2410_CPU_MASK 0xFFFFFFFF
+
+#define S3C24XX_CPU_ID 0x32400000
+#define S3C24XX_CPU_MASK 0xFFF00000
+
+#define S3C2412_CPU_ID 0x32412000
+#define S3C2412_CPU_MASK 0xFFFFF000
+
+#define S3C6400_CPU_ID 0x36400000
+#define S3C6410_CPU_ID 0x36410000
+#define S3C64XX_CPU_MASK 0xFFFFF000
+
+#define S5PV210_CPU_ID 0x43110000
+#define S5PV210_CPU_MASK 0xFFFFF000
+
+#define IS_SAMSUNG_CPU(name, id, mask) \
+static inline int is_samsung_##name(void) \
+{ \
+ return ((samsung_cpu_id & mask) == (id & mask)); \
+}
+
+IS_SAMSUNG_CPU(s3c2410, S3C2410_CPU_ID, S3C2410_CPU_MASK)
+IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK)
+IS_SAMSUNG_CPU(s3c2412, S3C2412_CPU_ID, S3C2412_CPU_MASK)
+IS_SAMSUNG_CPU(s3c6400, S3C6400_CPU_ID, S3C64XX_CPU_MASK)
+IS_SAMSUNG_CPU(s3c6410, S3C6410_CPU_ID, S3C64XX_CPU_MASK)
+
+#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \
+ defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2440) || \
+ defined(CONFIG_CPU_S3C2442) || defined(CONFIG_CPU_S3C244X) || \
+ defined(CONFIG_CPU_S3C2443)
+# define soc_is_s3c24xx() is_samsung_s3c24xx()
+# define soc_is_s3c2410() is_samsung_s3c2410()
+#else
+# define soc_is_s3c24xx() 0
+# define soc_is_s3c2410() 0
+#endif
+
+#if defined(CONFIG_CPU_S3C2412)
+# define soc_is_s3c2412() is_samsung_s3c2412()
+#else
+# define soc_is_s3c2412() 0
+#endif
+
+#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
+# define soc_is_s3c6400() is_samsung_s3c6400()
+# define soc_is_s3c6410() is_samsung_s3c6410()
+# define soc_is_s3c64xx() (is_samsung_s3c6400() || is_samsung_s3c6410())
+#else
+# define soc_is_s3c6400() 0
+# define soc_is_s3c6410() 0
+# define soc_is_s3c64xx() 0
+#endif
+
+#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
+
+#ifndef KHZ
+#define KHZ (1000)
+#endif
+
+#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_io(struct map_desc *mach_desc, int size);
+
+extern void s3c64xx_init_cpu(void);
+
+extern unsigned int samsung_rev(void);
+
+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);
+
+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;
+
+/* system device subsystems */
+
+extern struct bus_type s3c2410_subsys;
+extern struct bus_type s3c2410a_subsys;
+extern struct bus_type s3c2412_subsys;
+extern struct bus_type s3c2416_subsys;
+extern struct bus_type s3c2440_subsys;
+extern struct bus_type s3c2442_subsys;
+extern struct bus_type s3c2443_subsys;
+extern struct bus_type s3c6410_subsys;
+
+#endif
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 000000000..e23fed311
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -0,0 +1,100 @@
+/* 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 platform_device *s3c24xx_uart_devs[];
+extern struct platform_device *s3c24xx_uart_src[];
+
+extern struct platform_device s3c64xx_device_ac97;
+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_onenand1;
+extern struct platform_device s3c64xx_device_pcm0;
+extern struct platform_device s3c64xx_device_pcm1;
+extern struct platform_device s3c64xx_device_spi0;
+extern struct platform_device s3c64xx_device_spi1;
+extern struct platform_device s3c64xx_device_spi2;
+
+extern struct platform_device s3c_device_adc;
+extern struct platform_device s3c_device_cfcon;
+extern struct platform_device s3c_device_fb;
+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_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_iis;
+extern struct platform_device s3c_device_lcd;
+extern struct platform_device s3c_device_nand;
+extern struct platform_device s3c_device_ohci;
+extern struct platform_device s3c_device_onenand;
+extern struct platform_device s3c_device_rtc;
+extern struct platform_device s3c_device_sdi;
+extern struct platform_device s3c_device_spi0;
+extern struct platform_device s3c_device_spi1;
+extern struct platform_device s3c_device_ts;
+extern struct platform_device s3c_device_timer[];
+extern struct platform_device s3c_device_usbgadget;
+extern struct platform_device s3c_device_usb_hsotg;
+extern struct platform_device s3c_device_usb_hsudc;
+extern struct platform_device s3c_device_wdt;
+
+extern struct platform_device samsung_asoc_idma;
+extern struct platform_device samsung_device_keypad;
+extern struct platform_device samsung_device_pwm;
+
+/* 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/fb-core.h b/arch/arm/plat-samsung/include/plat/fb-core.h
new file mode 100644
index 000000000..bca383efc
--- /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-s3c2410.h b/arch/arm/plat-samsung/include/plat/fb-s3c2410.h
new file mode 100644
index 000000000..4e5d9588b
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/fb-s3c2410.h
@@ -0,0 +1,72 @@
+/* arch/arm/plat-samsung/include/plat/fb-s3c2410.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_PLAT_FB_S3C2410_H
+#define __ASM_PLAT_FB_S3C2410_H __FILE__
+
+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_PLAT_FB_S3C2410_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 000000000..b89f8f208
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/fb.h
@@ -0,0 +1,35 @@
+/* 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__
+
+#include <linux/platform_data/video_s3c.h>
+
+/**
+ * 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);
+
+#endif /* __PLAT_S3C_FB_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 000000000..a181d7ce8
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
@@ -0,0 +1,163 @@
+/* linux/arch/arm/plat-samsung/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>
+ *
+ * Samsung 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 samsung_gpio_do_setcfg(struct samsung_gpio_chip *chip,
+ unsigned int off, unsigned int config)
+{
+ return (chip->config->set_config)(chip, off, config);
+}
+
+static inline unsigned samsung_gpio_do_getcfg(struct samsung_gpio_chip *chip,
+ unsigned int off)
+{
+ return (chip->config->get_config)(chip, off);
+}
+
+static inline int samsung_gpio_do_setpull(struct samsung_gpio_chip *chip,
+ unsigned int off, samsung_gpio_pull_t pull)
+{
+ return (chip->config->set_pull)(chip, off, pull);
+}
+
+static inline samsung_gpio_pull_t samsung_gpio_do_getpull(struct samsung_gpio_chip *chip,
+ unsigned int off)
+{
+ return chip->config->get_pull(chip, off);
+}
+
+/* Pull-{up,down} resistor controls.
+ *
+ * S3C2410,S3C2440 = Pull-UP,
+ * S3C2412,S3C2413 = Pull-Down
+ * S3C6400,S3C6410 = Pull-Both [None,Down,Up,Undef]
+ * S3C2443 = Pull-Both [not same as S3C6400]
+ */
+
+/**
+ * s3c24xx_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 s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip,
+ unsigned int off, samsung_gpio_pull_t pull);
+
+/**
+ * s3c24xx_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 s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
+ unsigned int off, samsung_gpio_pull_t pull);
+
+/**
+ * samsung_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 samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
+ unsigned int off, samsung_gpio_pull_t pull);
+
+/**
+ * samsung_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 samsung_gpio_setpull_upown.
+*/
+extern samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
+ unsigned int off);
+
+/**
+ * s3c24xx_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 s3c24xx_gpio_setpull_1up.
+*/
+extern samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip,
+ unsigned int off);
+
+/**
+ * s3c24xx_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 s3c24xx_gpio_setpull_1down.
+*/
+extern samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip,
+ unsigned int off);
+
+/**
+ * s3c2443_gpio_setpull() - 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 s3c2443_gpio_setpull(struct samsung_gpio_chip *chip,
+ unsigned int off, samsung_gpio_pull_t pull);
+
+/**
+ * s3c2443_gpio_getpull() - 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 samsung_gpio_setpull_upown.
+*/
+extern samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_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 000000000..b5294eff1
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -0,0 +1,182 @@
+/* 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__
+
+#include <linux/types.h>
+
+typedef unsigned int __bitwise__ samsung_gpio_pull_t;
+
+/* forward declaration if gpio-core.h hasn't been included */
+struct samsung_gpio_chip;
+
+/**
+ * struct samsung_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 samsung_gpio_cfgpin
+ * @sa s3c_gpio_getcfg
+ * @sa s3c_gpio_setpull
+ * @sa s3c_gpio_getpull
+ */
+struct samsung_gpio_cfg {
+ unsigned int cfg_eint;
+
+ samsung_gpio_pull_t (*get_pull)(struct samsung_gpio_chip *chip, unsigned offs);
+ int (*set_pull)(struct samsung_gpio_chip *chip, unsigned offs,
+ samsung_gpio_pull_t pull);
+
+ unsigned (*get_config)(struct samsung_gpio_chip *chip, unsigned offs);
+ int (*set_config)(struct samsung_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 samsung_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 samsung_gpio_pull_t)0x00)
+#define S3C_GPIO_PULL_DOWN ((__force samsung_gpio_pull_t)0x01)
+#define S3C_GPIO_PULL_UP ((__force samsung_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, samsung_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 samsung_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, samsung_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);
+}
+
+#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 000000000..6ce11bfdc
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -0,0 +1,145 @@
+/* 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.
+*/
+
+#ifndef __PLAT_SAMSUNG_GPIO_CORE_H
+#define __PLAT_SAMSUNG_GPIO_CORE_H
+
+/* Bring in machine-local definitions, especially S3C_GPIO_END */
+#include <mach/gpio-samsung.h>
+
+#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 samsung_gpio_chip;
+
+/**
+ * struct samsung_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 samsung_gpio_pm {
+ void (*save)(struct samsung_gpio_chip *chip);
+ void (*resume)(struct samsung_gpio_chip *chip);
+};
+
+struct samsung_gpio_cfg;
+
+/**
+ * struct samsung_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.
+ * @bitmap_gpio_int: Bitmap for representing GPIO interrupt or not.
+ *
+ * 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 samsung_gpio_chip {
+ struct gpio_chip chip;
+ struct samsung_gpio_cfg *config;
+ struct samsung_gpio_pm *pm;
+ void __iomem *base;
+ int irq_base;
+ int group;
+ spinlock_t lock;
+#ifdef CONFIG_PM
+ u32 pm_save[4];
+#endif
+ u32 bitmap_gpio_int;
+};
+
+static inline struct samsung_gpio_chip *to_samsung_gpio(struct gpio_chip *gpc)
+{
+ return container_of(gpc, struct samsung_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 samsung_gpio_cfg s3c24xx_gpiocfg_default;
+
+#ifdef CONFIG_S3C_GPIO_TRACK
+extern struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
+
+static inline struct samsung_gpio_chip *samsung_gpiolib_getchip(unsigned int chip)
+{
+ return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL;
+}
+#else
+/* machine specific code should provide samsung_gpiolib_getchip */
+
+extern struct samsung_gpio_chip s3c24xx_gpios[];
+
+static inline struct samsung_gpio_chip *samsung_gpiolib_getchip(unsigned int pin)
+{
+ struct samsung_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;
+}
+
+static inline void s3c_gpiolib_track(struct samsung_gpio_chip *chip) { }
+#endif
+
+#ifdef CONFIG_PM
+extern struct samsung_gpio_pm samsung_gpio_pm_1bit;
+extern struct samsung_gpio_pm samsung_gpio_pm_2bit;
+extern struct samsung_gpio_pm samsung_gpio_pm_4bit;
+#define __gpio_pm(x) x
+#else
+#define samsung_gpio_pm_1bit NULL
+#define samsung_gpio_pm_2bit NULL
+#define samsung_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 samsung_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl)
+#define samsung_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl)
+
+#endif /* __PLAT_SAMSUNG_GPIO_CORE_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 000000000..f182669b8
--- /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/irq-uart.h b/arch/arm/plat-samsung/include/plat/irq-uart.h
new file mode 100644
index 000000000..a9331e49b
--- /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/keypad-core.h b/arch/arm/plat-samsung/include/plat/keypad-core.h
new file mode 100644
index 000000000..d513e1b3a
--- /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 000000000..c81ace332
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/keypad.h
@@ -0,0 +1,31 @@
+/*
+ * 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/samsung-keypad.h>
+
+/**
+ * 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 000000000..3ffac4d2e
--- /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/map-s3c.h b/arch/arm/plat-samsung/include/plat/map-s3c.h
new file mode 100644
index 000000000..c0c70a895
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/map-s3c.h
@@ -0,0 +1,84 @@
+/* linux/arch/arm/plat-samsung/include/plat/map-s3c.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_MAP_S3C_H
+#define __ASM_PLAT_MAP_S3C_H __FILE__
+
+#define S3C24XX_VA_IRQ S3C_VA_IRQ
+#define S3C24XX_VA_MEMCTRL S3C_VA_MEM
+#define S3C24XX_VA_UART S3C_VA_UART
+
+#define S3C24XX_VA_TIMER S3C_VA_TIMER
+#define S3C24XX_VA_CLKPWR S3C_VA_SYS
+#define S3C24XX_VA_WATCHDOG S3C_VA_WATCHDOG
+
+#define S3C2412_VA_SSMC S3C_ADDR_CPU(0x00000000)
+#define S3C2412_VA_EBI S3C_ADDR_CPU(0x00100000)
+
+#define S3C2410_PA_UART (0x50000000)
+#define S3C24XX_PA_UART S3C2410_PA_UART
+
+#ifndef S3C_UART_OFFSET
+#define S3C_UART_OFFSET (0x400)
+#endif
+
+/*
+ * 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_PA_GPIO S3C2410_PA_GPIO
+
+#define S3C24XX_VA_GPIO ((S3C24XX_PA_GPIO - S3C24XX_PA_UART) + S3C24XX_VA_UART)
+#define S3C64XX_VA_GPIO S3C_ADDR_CPU(0x00000000)
+
+#define S3C64XX_VA_MODEM S3C_ADDR_CPU(0x00100000)
+#define S3C64XX_VA_USB_HSPHY S3C_ADDR_CPU(0x00200000)
+
+#define S3C_VA_USB_HSPHY S3C64XX_VA_USB_HSPHY
+
+/*
+ * ISA style IO, for each machine to sort out mappings for,
+ * if it implements it. We reserve two 16M regions for ISA.
+ */
+
+#define S3C2410_ADDR(x) S3C_ADDR(x)
+
+#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
+
+#include <plat/map-s5p.h>
+
+#endif /* __ASM_PLAT_MAP_S3C_H */
diff --git a/arch/arm/plat-samsung/include/plat/map-s5p.h b/arch/arm/plat-samsung/include/plat/map-s5p.h
new file mode 100644
index 000000000..f5cf2bd20
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/map-s5p.h
@@ -0,0 +1,40 @@
+/* linux/arch/arm/plat-samsung/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_DMC0 S3C_ADDR(0x02440000)
+#define S5P_VA_DMC1 S3C_ADDR(0x02480000)
+#define S5P_VA_SROMC S3C_ADDR(0x024C0000)
+
+#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_TWD S5P_VA_COREPERI(0x600)
+
+#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)
+
+#ifndef S3C_UART_OFFSET
+#define S3C_UART_OFFSET (0x400)
+#endif
+
+#include <plat/map-s3c.h>
+
+#endif /* __ASM_PLAT_MAP_S5P_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 000000000..6de20789a
--- /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/onenand-core.h b/arch/arm/plat-samsung/include/plat/onenand-core.h
new file mode 100644
index 000000000..7701cb702
--- /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/pm-common.h b/arch/arm/plat-samsung/include/plat/pm-common.h
new file mode 100644
index 000000000..8705f9e0e
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pm-common.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Tomasz Figa <t.figa@samsung.com>
+ * 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.
+*/
+
+#ifndef __PLAT_SAMSUNG_PM_COMMON_H
+#define __PLAT_SAMSUNG_PM_COMMON_H __FILE__
+
+#include <linux/irq.h>
+
+/* 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) }
+
+/* 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(const struct sleep_save *ptr, int count);
+extern void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count);
+
+/* PM debug functions */
+
+/**
+ * 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;
+};
+
+#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, ...);
+
+/**
+ * s3c_pm_debug_init() - suspend/resume low level debug initialization.
+ * @base: Virtual base of UART to use for suspend/resume debugging.
+ *
+ * This function needs to be called before S3C_PMDBG() can be used, to set up
+ * UART port base address and configuration.
+ */
+extern void s3c_pm_debug_init(void);
+
+#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt)
+
+extern void s3c_pm_save_uarts(void);
+extern void s3c_pm_restore_uarts(void);
+#else
+#define S3C_PMDBG(fmt...) pr_debug(fmt)
+#define s3c_pm_debug_init() do { } while (0)
+
+static inline void s3c_pm_save_uarts(void) { }
+static inline void s3c_pm_restore_uarts(void) { }
+#endif
+
+/* 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
+
+#endif
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 000000000..7f415ce74
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -0,0 +1,121 @@
+/* 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 <plat/pm-common.h>
+
+struct device;
+
+#ifdef CONFIG_SAMSUNG_PM
+
+extern __init int s3c_pm_init(void);
+extern __init int s3c64xx_pm_init(void);
+
+#else
+
+static inline int s3c_pm_init(void)
+{
+ return 0;
+}
+
+static inline int s3c64xx_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;
+#ifdef CONFIG_PM_SLEEP
+extern unsigned long s3c_irqwake_eintallow;
+#else
+#define s3c_irqwake_eintallow 0
+#endif
+
+/* per-cpu sleep functions */
+
+extern void (*pm_cpu_prep)(void);
+extern int (*pm_cpu_sleep)(unsigned long);
+
+/* Flags for PM Control */
+
+extern unsigned long s3c_pm_flags;
+
+/* from sleep.S */
+
+extern int s3c2410_cpu_suspend(unsigned long);
+
+#ifdef CONFIG_PM_SLEEP
+extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
+extern void s3c_cpu_resume(void);
+#else
+#define s3c_irq_wake NULL
+#define s3c_cpu_resume NULL
+#endif
+
+#ifdef CONFIG_SAMSUNG_PM
+extern int s3c_irqext_wake(struct irq_data *data, unsigned int state);
+#else
+#define s3c_irqext_wake NULL
+#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 */
+
+/**
+ * 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);
+
+#ifdef CONFIG_GPIO_SAMSUNG
+/**
+ * samsung_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 samsung_pm_restore_gpios(void);
+
+/**
+ * samsung_pm_save_gpios() - save the state of the GPIOs for restoring after sleep.
+ *
+ * Save the GPIO states for resotration on resume. See samsung_pm_restore_gpios().
+ */
+extern void samsung_pm_save_gpios(void);
+#else
+static inline void samsung_pm_restore_gpios(void) {}
+static inline void samsung_pm_save_gpios(void) {}
+#endif
+
+extern void s3c_pm_save_core(void);
+extern void s3c_pm_restore_core(void);
diff --git a/arch/arm/plat-samsung/include/plat/pwm-core.h b/arch/arm/plat-samsung/include/plat/pwm-core.h
new file mode 100644
index 000000000..5bff1facb
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pwm-core.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Samsung PWM controller platform data helpers.
+ *
+ * This program is free software; you can redistribute it 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_PWM_CORE_H
+#define __ASM_ARCH_PWM_CORE_H __FILE__
+
+#include <clocksource/samsung_pwm.h>
+
+#ifdef CONFIG_SAMSUNG_DEV_PWM
+extern void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd);
+#else
+static inline void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd) { }
+#endif
+
+#endif /* __ASM_ARCH_PWM_CORE_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 000000000..706121001
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-adc.h
@@ -0,0 +1,68 @@
+/* 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 S3C2443_ADCMUX S3C2410_ADCREG(0x18)
+#define S3C64XX_ADCCLRINT S3C2410_ADCREG(0x18)
+#define S5P_ADCMUX S3C2410_ADCREG(0x1C)
+#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 S3C2416_ADCCON_RESSEL (1 << 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 S3C2443_ADCTSC_UD_SEN (1 << 8)
+#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-irqtype.h b/arch/arm/plat-samsung/include/plat/regs-irqtype.h
new file mode 100644
index 000000000..c63cd3fc5
--- /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-spi.h b/arch/arm/plat-samsung/include/plat/regs-spi.h
new file mode 100644
index 000000000..552fe7cfe
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-spi.h
@@ -0,0 +1,48 @@
+/* arch/arm/plat-samsung/include/plat/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 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:1, Slave:0 select */
+#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_SPSTA (0x04)
+
+#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 S3C2410_SPPIN_KEEP (1 << 0) /* Master Out keep */
+
+#define S3C2410_SPPRE (0x0C)
+#define S3C2410_SPTDAT (0x10)
+#define S3C2410_SPRDAT (0x14)
+
+#endif /* __ASM_ARCH_REGS_SPI_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-srom.h b/arch/arm/plat-samsung/include/plat/regs-srom.h
new file mode 100644
index 000000000..9b6729c81
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-srom.h
@@ -0,0 +1,54 @@
+/* linux/arch/arm/plat-samsung/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 __PLAT_SAMSUNG_REGS_SROM_H
+#define __PLAT_SAMSUNG_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 /* __PLAT_SAMSUNG_REGS_SROM_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-udc.h b/arch/arm/plat-samsung/include/plat/regs-udc.h
new file mode 100644
index 000000000..4003d3dab
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-udc.h
@@ -0,0 +1,151 @@
+/* arch/arm/plat-samsung/include/plat/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-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 000000000..fcf279662
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h
@@ -0,0 +1,51 @@
+/* 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 S3C_PHYPWR_NORMAL_MASK (0x19 << 0)
+#define S3C_PHYPWR_OTG_DISABLE (1 << 4)
+#define S3C_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 << 1)
+#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/samsung-time.h b/arch/arm/plat-samsung/include/plat/samsung-time.h
new file mode 100644
index 000000000..209464ade
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/samsung-time.h
@@ -0,0 +1,30 @@
+/* linux/arch/arm/plat-samsung/include/plat/samsung-time.h
+ *
+ * Copyright 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for samsung s3c and 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_SAMSUNG_TIME_H
+#define __ASM_PLAT_SAMSUNG_TIME_H __FILE__
+
+/* SAMSUNG HR-Timer Clock mode */
+enum samsung_timer_mode {
+ SAMSUNG_PWM0,
+ SAMSUNG_PWM1,
+ SAMSUNG_PWM2,
+ SAMSUNG_PWM3,
+ SAMSUNG_PWM4,
+};
+
+extern void __init samsung_set_timer_source(enum samsung_timer_mode event,
+ enum samsung_timer_mode source);
+
+extern void __init samsung_timer_init(void);
+
+#endif /* __ASM_PLAT_SAMSUNG_TIME_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 000000000..2787553c3
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -0,0 +1,166 @@
+/* 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__
+
+#include <linux/platform_data/mmc-sdhci-s3c.h>
+#include <plat/devs.h>
+
+/* s3c_sdhci_set_platdata() - common helper for setting SDHCI platform data
+ * @pd: The default platform data for this device.
+ * @set: Pointer to the platform data to fill in.
+ */
+extern void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd,
+ struct s3c_sdhci_platdata *set);
+
+/**
+ * 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 s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
+
+/* S3C2416 SDHCI setup */
+
+#ifdef CONFIG_S3C2416_SETUP_SDHCI
+static inline void s3c2416_default_sdhci0(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_hsmmc0_def_platdata.cfg_gpio = s3c2416_setup_sdhci0_cfg_gpio;
+#endif /* CONFIG_S3C_DEV_HSMMC */
+}
+
+static inline void s3c2416_default_sdhci1(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_hsmmc1_def_platdata.cfg_gpio = s3c2416_setup_sdhci1_cfg_gpio;
+#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
+static inline void s3c6400_default_sdhci0(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
+#endif
+}
+
+static inline void s3c6400_default_sdhci1(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
+#endif
+}
+
+static inline void s3c6400_default_sdhci2(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
+#endif
+}
+
+static inline void s3c6410_default_sdhci0(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
+#endif
+}
+
+static inline void s3c6410_default_sdhci1(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
+#endif
+}
+
+static inline void s3c6410_default_sdhci2(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
+#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 */
+
+static inline void s3c_sdhci_setname(int id, char *name)
+{
+ switch (id) {
+#ifdef CONFIG_S3C_DEV_HSMMC
+ case 0:
+ s3c_device_hsmmc0.name = name;
+ break;
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ case 1:
+ s3c_device_hsmmc1.name = name;
+ break;
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ case 2:
+ s3c_device_hsmmc2.name = name;
+ break;
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ case 3:
+ s3c_device_hsmmc3.name = name;
+ break;
+#endif
+ default:
+ break;
+ }
+}
+#endif /* __PLAT_S3C_SDHCI_H */
diff --git a/arch/arm/plat-samsung/include/plat/spi-core.h b/arch/arm/plat-samsung/include/plat/spi-core.h
new file mode 100644
index 000000000..0b9428ab3
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/spi-core.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 Heiko Stuebner <heiko@sntech.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 __PLAT_S3C_SPI_CORE_H
+#define __PLAT_S3C_SPI_CORE_H
+
+/* 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 s3c64xx_spi_setname(char *name)
+{
+#ifdef CONFIG_S3C64XX_DEV_SPI0
+ s3c64xx_device_spi0.name = name;
+#endif
+#ifdef CONFIG_S3C64XX_DEV_SPI1
+ s3c64xx_device_spi1.name = name;
+#endif
+#ifdef CONFIG_S3C64XX_DEV_SPI2
+ s3c64xx_device_spi2.name = name;
+#endif
+}
+
+#endif /* __PLAT_S3C_SPI_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/usb-phy.h b/arch/arm/plat-samsung/include/plat/usb-phy.h
new file mode 100644
index 000000000..ab34dfadb
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/usb-phy.h
@@ -0,0 +1,19 @@
+/*
+ * 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_SAMSUNG_USB_PHY_H
+#define __PLAT_SAMSUNG_USB_PHY_H __FILE__
+
+#include <linux/usb/samsung_usb_phy.h>
+
+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_SAMSUNG_USB_PHY_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 000000000..43e4acd2e
--- /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 000000000..0386b8f76
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/watchdog-reset.h
@@ -0,0 +1,20 @@
+/* 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.
+*/
+
+#ifndef __PLAT_SAMSUNG_WATCHDOG_RESET_H
+#define __PLAT_SAMSUNG_WATCHDOG_RESET_H
+
+extern void samsung_wdt_reset(void);
+extern void samsung_wdt_reset_of_init(void);
+extern void samsung_wdt_reset_init(void __iomem *base);
+
+#endif /* __PLAT_SAMSUNG_WATCHDOG_RESET_H */
diff --git a/arch/arm/plat-samsung/init.c b/arch/arm/plat-samsung/init.c
new file mode 100644
index 000000000..11fbbc26e
--- /dev/null
+++ b/arch/arm/plat-samsung/init.c
@@ -0,0 +1,173 @@
+/* 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.
+*/
+
+/*
+ * NOTE: Code in this file is not used on S3C64xx when booting with
+ * Device Tree support.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.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->init == NULL) {
+ printk(KERN_ERR "CPU %s support not enabled\n", cpu->name);
+ panic("Unsupported Samsung CPU");
+ }
+
+ if (cpu->map_io)
+ 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 */
+#if IS_ENABLED(CONFIG_SAMSUNG_ATAGS)
+static int nr_uarts __initdata = 0;
+
+#ifdef CONFIG_SERIAL_SAMSUNG_UARTS
+static struct s3c2410_uartcfg uart_cfgs[CONFIG_SERIAL_SAMSUNG_UARTS];
+#endif
+
+/* 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)
+{
+#ifdef CONFIG_SERIAL_SAMSUNG_UARTS
+ 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;
+#endif
+}
+
+void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ if (cpu == NULL)
+ return;
+
+ if (cpu->init_uarts == NULL && IS_ENABLED(CONFIG_SAMSUNG_ATAGS)) {
+ printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n");
+ } else
+ (cpu->init_uarts)(cfg, no);
+}
+#endif
+
+static int __init s3c_arch_init(void)
+{
+ int ret;
+
+ // do the correct init for cpu
+
+ if (cpu == NULL) {
+ /* Not needed when booting with device tree. */
+ if (of_have_populated_dt())
+ return 0;
+ panic("s3c_arch_init: NULL cpu\n");
+ }
+
+ ret = (cpu->init)();
+ if (ret != 0)
+ return ret;
+#if IS_ENABLED(CONFIG_SAMSUNG_ATAGS)
+ ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
+#endif
+ return ret;
+}
+
+arch_initcall(s3c_arch_init);
diff --git a/arch/arm/plat-samsung/platformdata.c b/arch/arm/plat-samsung/platformdata.c
new file mode 100644
index 000000000..b430e9946
--- /dev/null
+++ b/arch/arm/plat-samsung/platformdata.c
@@ -0,0 +1,60 @@
+/* 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/slab.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <plat/devs.h>
+#include <plat/sdhci.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;
+}
+
+void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd,
+ struct s3c_sdhci_platdata *set)
+{
+ 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->host_caps)
+ set->host_caps |= pd->host_caps;
+ if (pd->host_caps2)
+ set->host_caps2 |= pd->host_caps2;
+ if (pd->pm_caps)
+ set->pm_caps |= pd->pm_caps;
+}
diff --git a/arch/arm/plat-samsung/pm-check.c b/arch/arm/plat-samsung/pm-check.c
new file mode 100644
index 000000000..04aff2c31
--- /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-common.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)resource_size(res);
+
+ 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-common.c b/arch/arm/plat-samsung/pm-common.c
new file mode 100644
index 000000000..515cd5337
--- /dev/null
+++ b/arch/arm/plat-samsung/pm-common.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Tomasz Figa <t.figa@samsung.com>
+ * Copyright (C) 2008 Openmoko, Inc.
+ * Copyright (C) 2004-2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Samsung common power management helper functions.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+
+#include <plat/pm-common.h>
+
+/* 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(const struct sleep_save *ptr, int count)
+{
+ for (; count > 0; count--, ptr++) {
+ pr_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(const struct sleep_save *ptr, int count)
+{
+ for (; count > 0; count--, ptr++)
+ __raw_writel(ptr->val, ptr->reg);
+}
diff --git a/arch/arm/plat-samsung/pm-debug.c b/arch/arm/plat-samsung/pm-debug.c
new file mode 100644
index 000000000..64e15da33
--- /dev/null
+++ b/arch/arm/plat-samsung/pm-debug.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Tomasz Figa <t.figa@samsung.com>
+ * Copyright (C) 2008 Openmoko, Inc.
+ * Copyright (C) 2004-2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Samsung common power management (suspend to RAM) debug 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/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/io.h>
+
+#include <asm/mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/pm-common.h>
+
+#ifdef CONFIG_SAMSUNG_ATAGS
+#include <plat/pm.h>
+#include <mach/pm-core.h>
+#else
+static inline void s3c_pm_debug_init_uart(void) {}
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+ struct pm_uart_save *save) {}
+#endif
+
+static struct pm_uart_save uart_save;
+
+extern void printascii(const char *);
+
+void s3c_pm_dbg(const char *fmt, ...)
+{
+ va_list va;
+ char buff[256];
+
+ va_start(va, fmt);
+ vsnprintf(buff, sizeof(buff), fmt, va);
+ va_end(va);
+
+ printascii(buff);
+}
+
+void s3c_pm_debug_init(void)
+{
+ /* restart uart clocks so we can use them to output */
+ s3c_pm_debug_init_uart();
+}
+
+static inline void __iomem *s3c_pm_uart_base(void)
+{
+ unsigned long paddr;
+ unsigned long vaddr;
+
+ debug_ll_addr(&paddr, &vaddr);
+
+ return (void __iomem *)vaddr;
+}
+
+void s3c_pm_save_uarts(void)
+{
+ void __iomem *regs = s3c_pm_uart_base();
+ struct pm_uart_save *save = &uart_save;
+
+ 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 (!soc_is_s3c2410())
+ save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT);
+
+ S3C_PMDBG("UART[%p]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n",
+ regs, save->ulcon, save->ucon, save->ufcon, save->ubrdiv);
+}
+
+void s3c_pm_restore_uarts(void)
+{
+ void __iomem *regs = s3c_pm_uart_base();
+ struct pm_uart_save *save = &uart_save;
+
+ 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 (!soc_is_s3c2410())
+ __raw_writel(save->udivslot, regs + S3C2443_DIVSLOT);
+}
diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c
new file mode 100644
index 000000000..f9a09262f
--- /dev/null
+++ b/arch/arm/plat-samsung/pm-gpio.c
@@ -0,0 +1,386 @@
+
+/* 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/device.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/gpio-samsung.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 samsung_gpio_pm_1bit_save(struct samsung_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 samsung_gpio_pm_1bit_resume(struct samsung_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 samsung_gpio_pm samsung_gpio_pm_1bit = {
+ .save = samsung_gpio_pm_1bit_save,
+ .resume = samsung_gpio_pm_1bit_resume,
+};
+
+static void samsung_gpio_pm_2bit_save(struct samsung_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;
+}
+
+/**
+ * samsung_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 samsung_gpio_pm_2bit_resume(struct samsung_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 samsung_gpio_pm samsung_gpio_pm_2bit = {
+ .save = samsung_gpio_pm_2bit_save,
+ .resume = samsung_gpio_pm_2bit_resume,
+};
+
+#if defined(CONFIG_ARCH_S3C64XX)
+static void samsung_gpio_pm_4bit_save(struct samsung_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 samsung_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 samsung_gpio_pm_4bit_con(struct samsung_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 = samsung_gpio_pm_4bit_mask(old_gpcon, gps_gpcon);
+
+ gpcon = old_gpcon & ~mask;
+ gpcon |= gps_gpcon & mask;
+
+ __raw_writel(gpcon, con);
+}
+
+static void samsung_gpio_pm_4bit_resume(struct samsung_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);
+
+ samsung_gpio_pm_4bit_con(chip, 0);
+ if (chip->chip.ngpio > 8) {
+ old_gpcon[0] = __raw_readl(base - 4);
+ samsung_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 samsung_gpio_pm samsung_gpio_pm_4bit = {
+ .save = samsung_gpio_pm_4bit_save,
+ .resume = samsung_gpio_pm_4bit_resume,
+};
+#endif /* CONFIG_ARCH_S3C64XX */
+
+/**
+ * samsung_pm_save_gpio() - save gpio chip data for suspend
+ * @ourchip: The chip for suspend.
+ */
+static void samsung_pm_save_gpio(struct samsung_gpio_chip *ourchip)
+{
+ struct samsung_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);
+}
+
+/**
+ * samsung_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 samsung_pm_save_gpios(void)
+{
+ struct samsung_gpio_chip *ourchip;
+ unsigned int gpio_nr;
+
+ for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
+ ourchip = samsung_gpiolib_getchip(gpio_nr);
+ if (!ourchip) {
+ gpio_nr++;
+ continue;
+ }
+
+ samsung_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;
+ }
+}
+
+/**
+ * samsung_pm_resume_gpio() - restore gpio chip data after suspend
+ * @ourchip: The suspended chip.
+ */
+static void samsung_pm_resume_gpio(struct samsung_gpio_chip *ourchip)
+{
+ struct samsung_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 samsung_pm_restore_gpios(void)
+{
+ struct samsung_gpio_chip *ourchip;
+ unsigned int gpio_nr;
+
+ for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
+ ourchip = samsung_gpiolib_getchip(gpio_nr);
+ if (!ourchip) {
+ gpio_nr++;
+ continue;
+ }
+
+ samsung_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 000000000..82777c649
--- /dev/null
+++ b/arch/arm/plat-samsung/pm.c
@@ -0,0 +1,208 @@
+/* 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/of.h>
+#include <linux/serial_s3c.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/suspend.h>
+
+#ifdef CONFIG_SAMSUNG_ATAGS
+#include <mach/map.h>
+#ifndef CONFIG_ARCH_EXYNOS
+#include <mach/regs-clock.h>
+#include <mach/regs-irq.h>
+#endif
+#include <mach/irqs.h>
+#endif
+
+#include <asm/irq.h>
+
+#include <plat/pm.h>
+#include <mach/pm-core.h>
+
+/* for external use */
+
+unsigned long s3c_pm_flags;
+
+/* 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;
+}
+
+void (*pm_cpu_prep)(void);
+int (*pm_cpu_sleep)(unsigned long);
+
+#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)
+{
+ int ret;
+ /* 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 (!of_have_populated_dt() &&
+ !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 */
+
+ if (!of_have_populated_dt()) {
+ samsung_pm_save_gpios();
+ samsung_pm_saved_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();
+
+ /* this will also act as our return point from when
+ * we resume as it saves its own register state and restores it
+ * during the resume. */
+
+ ret = cpu_suspend(0, pm_cpu_sleep);
+ if (ret)
+ return ret;
+
+ /* restore the system state */
+
+ s3c_pm_restore_core();
+ s3c_pm_restore_uarts();
+
+ if (!of_have_populated_dt()) {
+ samsung_pm_restore_gpios();
+ s3c_pm_restored_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/s5p-dev-mfc.c b/arch/arm/plat-samsung/s5p-dev-mfc.c
new file mode 100644
index 000000000..0b04b6b0f
--- /dev/null
+++ b/arch/arm/plat-samsung/s5p-dev-mfc.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2010-2011 Samsung Electronics Co.Ltd
+ *
+ * Base S5P MFC resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/memblock.h>
+#include <linux/ioport.h>
+#include <linux/of_fdt.h>
+#include <linux/of.h>
+
+static struct platform_device s5p_device_mfc_l;
+static struct platform_device s5p_device_mfc_r;
+
+struct s5p_mfc_dt_meminfo {
+ unsigned long loff;
+ unsigned long lsize;
+ unsigned long roff;
+ unsigned long rsize;
+ char *compatible;
+};
+
+struct s5p_mfc_reserved_mem {
+ phys_addr_t base;
+ unsigned long size;
+ struct device *dev;
+};
+
+static struct s5p_mfc_reserved_mem s5p_mfc_mem[2] __initdata;
+
+
+static void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize,
+ phys_addr_t lbase, unsigned int lsize)
+{
+ int i;
+
+ s5p_mfc_mem[0].dev = &s5p_device_mfc_r.dev;
+ s5p_mfc_mem[0].base = rbase;
+ s5p_mfc_mem[0].size = rsize;
+
+ s5p_mfc_mem[1].dev = &s5p_device_mfc_l.dev;
+ s5p_mfc_mem[1].base = lbase;
+ s5p_mfc_mem[1].size = lsize;
+
+ for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) {
+ struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i];
+ if (memblock_remove(area->base, area->size)) {
+ printk(KERN_ERR "Failed to reserve memory for MFC device (%ld bytes at 0x%08lx)\n",
+ area->size, (unsigned long) area->base);
+ area->base = 0;
+ }
+ }
+}
+
+int __init s5p_fdt_alloc_mfc_mem(unsigned long node, const char *uname,
+ int depth, void *data)
+{
+ const __be32 *prop;
+ int len;
+ struct s5p_mfc_dt_meminfo mfc_mem;
+
+ if (!data)
+ return 0;
+
+ if (!of_flat_dt_is_compatible(node, data))
+ return 0;
+
+ prop = of_get_flat_dt_prop(node, "samsung,mfc-l", &len);
+ if (!prop || (len != 2 * sizeof(unsigned long)))
+ return 0;
+
+ mfc_mem.loff = be32_to_cpu(prop[0]);
+ mfc_mem.lsize = be32_to_cpu(prop[1]);
+
+ prop = of_get_flat_dt_prop(node, "samsung,mfc-r", &len);
+ if (!prop || (len != 2 * sizeof(unsigned long)))
+ return 0;
+
+ mfc_mem.roff = be32_to_cpu(prop[0]);
+ mfc_mem.rsize = be32_to_cpu(prop[1]);
+
+ s5p_mfc_reserve_mem(mfc_mem.roff, mfc_mem.rsize,
+ mfc_mem.loff, mfc_mem.lsize);
+
+ return 1;
+}
diff --git a/arch/arm/plat-samsung/setup-camif.c b/arch/arm/plat-samsung/setup-camif.c
new file mode 100644
index 000000000..72d8edb89
--- /dev/null
+++ b/arch/arm/plat-samsung/setup-camif.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2012 Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
+ *
+ * Helper functions for S3C24XX/S3C64XX SoC series CAMIF driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-samsung.h>
+
+/* Number of camera port pins, without FIELD */
+#define S3C_CAMIF_NUM_GPIOS 13
+
+/* Default camera port configuration helpers. */
+
+static void camif_get_gpios(int *gpio_start, int *gpio_reset)
+{
+#ifdef CONFIG_ARCH_S3C24XX
+ *gpio_start = S3C2410_GPJ(0);
+ *gpio_reset = S3C2410_GPJ(12);
+#else
+ /* s3c64xx */
+ *gpio_start = S3C64XX_GPF(0);
+ *gpio_reset = S3C64XX_GPF(3);
+#endif
+}
+
+int s3c_camif_gpio_get(void)
+{
+ int gpio_start, gpio_reset;
+ int ret, i;
+
+ camif_get_gpios(&gpio_start, &gpio_reset);
+
+ for (i = 0; i < S3C_CAMIF_NUM_GPIOS; i++) {
+ int gpio = gpio_start + i;
+
+ if (gpio == gpio_reset)
+ continue;
+
+ ret = gpio_request(gpio, "camif");
+ if (!ret)
+ ret = s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ if (ret) {
+ pr_err("failed to configure GPIO %d\n", gpio);
+ for (--i; i >= 0; i--)
+ gpio_free(gpio--);
+ return ret;
+ }
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+
+ return 0;
+}
+
+void s3c_camif_gpio_put(void)
+{
+ int i, gpio_start, gpio_reset;
+
+ camif_get_gpios(&gpio_start, &gpio_reset);
+
+ for (i = 0; i < S3C_CAMIF_NUM_GPIOS; i++) {
+ int gpio = gpio_start + i;
+ if (gpio != gpio_reset)
+ gpio_free(gpio);
+ }
+}
diff --git a/arch/arm/plat-samsung/wakeup-mask.c b/arch/arm/plat-samsung/wakeup-mask.c
new file mode 100644
index 000000000..20c3d9117
--- /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/device.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-samsung/watchdog-reset.c b/arch/arm/plat-samsung/watchdog-reset.c
new file mode 100644
index 000000000..2ecb50bea
--- /dev/null
+++ b/arch/arm/plat-samsung/watchdog-reset.c
@@ -0,0 +1,97 @@
+/* arch/arm/plat-samsung/watchdog-reset.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Coyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Watchdog reset support for Samsung 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/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#define S3C2410_WTCON 0x00
+#define S3C2410_WTDAT 0x04
+#define S3C2410_WTCNT 0x08
+
+#define S3C2410_WTCON_ENABLE (1 << 5)
+#define S3C2410_WTCON_DIV16 (0 << 3)
+#define S3C2410_WTCON_RSTEN (1 << 0)
+#define S3C2410_WTCON_PRESCALE(x) ((x) << 8)
+
+static void __iomem *wdt_base;
+static struct clk *wdt_clock;
+
+void samsung_wdt_reset(void)
+{
+ if (!wdt_base) {
+ pr_err("%s: wdt reset not initialized\n", __func__);
+ /* delay to allow the serial port to show the message */
+ mdelay(50);
+ return;
+ }
+
+ if (!IS_ERR(wdt_clock))
+ clk_prepare_enable(wdt_clock);
+
+ /* disable watchdog, to be safe */
+ __raw_writel(0, wdt_base + S3C2410_WTCON);
+
+ /* put initial values into count and data */
+ __raw_writel(0x80, wdt_base + S3C2410_WTCNT);
+ __raw_writel(0x80, wdt_base + S3C2410_WTDAT);
+
+ /* set the watchdog to go and reset... */
+ __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV16 |
+ S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x20),
+ wdt_base + S3C2410_WTCON);
+
+ /* wait for reset to assert... */
+ mdelay(500);
+
+ pr_err("Watchdog reset failed to assert reset\n");
+
+ /* delay to allow the serial port to show the message */
+ mdelay(50);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id s3c2410_wdt_match[] = {
+ { .compatible = "samsung,s3c2410-wdt" },
+ {},
+};
+
+void __init samsung_wdt_reset_of_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, s3c2410_wdt_match);
+ if (!np) {
+ pr_err("%s: failed to find watchdog node\n", __func__);
+ return;
+ }
+
+ wdt_base = of_iomap(np, 0);
+ if (!wdt_base) {
+ pr_err("%s: failed to map watchdog registers\n", __func__);
+ return;
+ }
+
+ wdt_clock = of_clk_get(np, 0);
+}
+#endif
+
+void __init samsung_wdt_reset_init(void __iomem *base)
+{
+ wdt_base = base;
+ wdt_clock = clk_get(NULL, "watchdog");
+}
diff --git a/arch/arm/plat-versatile/Kconfig b/arch/arm/plat-versatile/Kconfig
new file mode 100644
index 000000000..49b8ef915
--- /dev/null
+++ b/arch/arm/plat-versatile/Kconfig
@@ -0,0 +1,9 @@
+if PLAT_VERSATILE
+
+config PLAT_VERSATILE_CLOCK
+ bool
+
+config PLAT_VERSATILE_SCHED_CLOCK
+ bool
+
+endif
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile
new file mode 100644
index 000000000..03c4900ac
--- /dev/null
+++ b/arch/arm/plat-versatile/Makefile
@@ -0,0 +1,5 @@
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
+
+obj-$(CONFIG_PLAT_VERSATILE_CLOCK) += clock.o
+obj-$(CONFIG_PLAT_VERSATILE_SCHED_CLOCK) += sched-clock.o
+obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/plat-versatile/clock.c b/arch/arm/plat-versatile/clock.c
new file mode 100644
index 000000000..5c8b6564f
--- /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/headsmp.S b/arch/arm/plat-versatile/headsmp.S
new file mode 100644
index 000000000..40f27e52d
--- /dev/null
+++ b/arch/arm/plat-versatile/headsmp.S
@@ -0,0 +1,41 @@
+/*
+ * 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>
+#include <asm/assembler.h>
+
+/*
+ * 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)
+ ARM_BE8(setend be)
+ mrc p15, 0, r0, c0, c0, 5
+ bic r0, #0xff000000
+ 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
+ENDPROC(versatile_secondary_startup)
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 000000000..3cfb024cc
--- /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/platsmp.h b/arch/arm/plat-versatile/include/plat/platsmp.h
new file mode 100644
index 000000000..50fb83019
--- /dev/null
+++ b/arch/arm/plat-versatile/include/plat/platsmp.h
@@ -0,0 +1,14 @@
+/*
+ * linux/arch/arm/plat-versatile/include/plat/platsmp.h
+ *
+ * Copyright (C) 2011 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.
+ */
+
+extern void versatile_secondary_startup(void);
+extern void versatile_secondary_init(unsigned int cpu);
+extern int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle);
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 000000000..5c3e4fc9f
--- /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/platsmp.c b/arch/arm/plat-versatile/platsmp.c
new file mode 100644
index 000000000..53feb90c8
--- /dev/null
+++ b/arch/arm/plat-versatile/platsmp.c
@@ -0,0 +1,91 @@
+/*
+ * 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/smp_plat.h>
+
+/*
+ * 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();
+ sync_cache_w(&pen_release);
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void versatile_secondary_init(unsigned int cpu)
+{
+ /*
+ * 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 versatile_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_logical_map(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.
+ */
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+ 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 000000000..c966ae90f
--- /dev/null
+++ b/arch/arm/plat-versatile/sched-clock.c
@@ -0,0 +1,41 @@
+/*
+ * 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/kernel.h>
+#include <linux/io.h>
+#include <linux/sched_clock.h>
+
+#include <plat/sched_clock.h>
+
+static void __iomem *ctr;
+
+static u64 notrace versatile_read_sched_clock(void)
+{
+ if (ctr)
+ return readl(ctr);
+
+ return 0;
+}
+
+void __init versatile_sched_clock_init(void __iomem *reg, unsigned long rate)
+{
+ ctr = reg;
+ sched_clock_register(versatile_read_sched_clock, 32, rate);
+}
diff --git a/arch/arm/probes/Makefile b/arch/arm/probes/Makefile
new file mode 100644
index 000000000..aa1f8590d
--- /dev/null
+++ b/arch/arm/probes/Makefile
@@ -0,0 +1,7 @@
+obj-$(CONFIG_UPROBES) += decode.o decode-arm.o uprobes/
+obj-$(CONFIG_KPROBES) += decode.o kprobes/
+ifdef CONFIG_THUMB2_KERNEL
+obj-$(CONFIG_KPROBES) += decode-thumb.o
+else
+obj-$(CONFIG_KPROBES) += decode-arm.o
+endif
diff --git a/arch/arm/probes/decode-arm.c b/arch/arm/probes/decode-arm.c
new file mode 100644
index 000000000..f72c33a2d
--- /dev/null
+++ b/arch/arm/probes/decode-arm.c
@@ -0,0 +1,736 @@
+/*
+ *
+ * arch/arm/probes/decode-arm.c
+ *
+ * Some code moved here from arch/arm/kernel/kprobes-arm.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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/stddef.h>
+#include <linux/ptrace.h>
+
+#include "decode.h"
+#include "decode-arm.h"
+
+#define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
+
+#define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
+
+/*
+ * 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.
+ */
+
+void __kprobes simulate_bbl(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ long iaddr = (long) regs->ARM_pc - 4;
+ int disp = branch_displacement(insn);
+
+ if (insn & (1 << 24))
+ regs->ARM_lr = iaddr + 4;
+
+ regs->ARM_pc = iaddr + 8 + disp;
+}
+
+void __kprobes simulate_blx1(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ long iaddr = (long) regs->ARM_pc - 4;
+ 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;
+}
+
+void __kprobes simulate_blx2bx(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ int rm = insn & 0xf;
+ long rmv = regs->uregs[rm];
+
+ if (insn & (1 << 5))
+ regs->ARM_lr = (long) regs->ARM_pc;
+
+ regs->ARM_pc = rmv & ~0x1;
+ regs->ARM_cpsr &= ~PSR_T_BIT;
+ if (rmv & 0x1)
+ regs->ARM_cpsr |= PSR_T_BIT;
+}
+
+void __kprobes simulate_mrs(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ int rd = (insn >> 12) & 0xf;
+ unsigned long mask = 0xf8ff03df; /* Mask out execution state */
+ regs->uregs[rd] = regs->ARM_cpsr & mask;
+}
+
+void __kprobes simulate_mov_ipsp(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ regs->uregs[12] = regs->uregs[13];
+}
+
+/*
+ * 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 const union decode_item arm_1111_table[] = {
+ /* Unconditional instructions */
+
+ /* memory hint 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx */
+ /* PLDI (immediate) 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx */
+ /* PLDW (immediate) 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx */
+ /* PLD (immediate) 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_SIMULATE (0xfe300000, 0xf4100000, PROBES_PRELOAD_IMM),
+
+ /* memory hint 1111 0110 x001 xxxx xxxx xxxx xxx0 xxxx */
+ /* PLDI (register) 1111 0110 x101 xxxx xxxx xxxx xxx0 xxxx */
+ /* PLDW (register) 1111 0111 x001 xxxx xxxx xxxx xxx0 xxxx */
+ /* PLD (register) 1111 0111 x101 xxxx xxxx xxxx xxx0 xxxx */
+ DECODE_SIMULATE (0xfe300010, 0xf6100000, PROBES_PRELOAD_REG),
+
+ /* BLX (immediate) 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx */
+ DECODE_SIMULATE (0xfe000000, 0xfa000000, PROBES_BRANCH_IMM),
+
+ /* 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 */
+ /* MRRC2 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx */
+ /* 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 */
+
+ /* Other unallocated instructions... */
+ DECODE_END
+};
+
+static const union decode_item arm_cccc_0001_0xx0____0xxx_table[] = {
+ /* Miscellaneous instructions */
+
+ /* MRS cpsr cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */
+ DECODE_SIMULATEX(0x0ff000f0, 0x01000000, PROBES_MRS,
+ REGS(0, NOPC, 0, 0, 0)),
+
+ /* BX cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
+ DECODE_SIMULATE (0x0ff000f0, 0x01200010, PROBES_BRANCH_REG),
+
+ /* BLX (register) cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
+ DECODE_SIMULATEX(0x0ff000f0, 0x01200030, PROBES_BRANCH_REG,
+ REGS(0, 0, 0, 0, NOPC)),
+
+ /* CLZ cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
+ DECODE_EMULATEX (0x0ff000f0, 0x01600010, PROBES_CLZ,
+ REGS(0, NOPC, 0, 0, NOPC)),
+
+ /* QADD cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx */
+ /* QSUB cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx */
+ /* QDADD cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx */
+ /* QDSUB cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx */
+ DECODE_EMULATEX (0x0f9000f0, 0x01000050, PROBES_SATURATING_ARITHMETIC,
+ REGS(NOPC, NOPC, 0, 0, NOPC)),
+
+ /* 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 */
+ /* BKPT 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
+ /* SMC cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */
+ /* And unallocated instructions... */
+ DECODE_END
+};
+
+static const union decode_item arm_cccc_0001_0xx0____1xx0_table[] = {
+ /* Halfword multiply and multiply-accumulate */
+
+ /* SMLALxy cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
+ DECODE_EMULATEX (0x0ff00090, 0x01400080, PROBES_MUL1,
+ REGS(NOPC, NOPC, NOPC, 0, NOPC)),
+
+ /* SMULWy cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
+ DECODE_OR (0x0ff000b0, 0x012000a0),
+ /* SMULxy cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
+ DECODE_EMULATEX (0x0ff00090, 0x01600080, PROBES_MUL2,
+ REGS(NOPC, 0, NOPC, 0, NOPC)),
+
+ /* SMLAxy cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx */
+ DECODE_OR (0x0ff00090, 0x01000080),
+ /* SMLAWy cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx */
+ DECODE_EMULATEX (0x0ff000b0, 0x01200080, PROBES_MUL2,
+ REGS(NOPC, NOPC, NOPC, 0, NOPC)),
+
+ DECODE_END
+};
+
+static const union decode_item arm_cccc_0000_____1001_table[] = {
+ /* Multiply and multiply-accumulate */
+
+ /* MUL cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx */
+ /* MULS cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx */
+ DECODE_EMULATEX (0x0fe000f0, 0x00000090, PROBES_MUL2,
+ REGS(NOPC, 0, NOPC, 0, NOPC)),
+
+ /* MLA cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx */
+ /* MLAS cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx */
+ DECODE_OR (0x0fe000f0, 0x00200090),
+ /* MLS cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx */
+ DECODE_EMULATEX (0x0ff000f0, 0x00600090, PROBES_MUL2,
+ REGS(NOPC, NOPC, NOPC, 0, NOPC)),
+
+ /* UMAAL cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx */
+ DECODE_OR (0x0ff000f0, 0x00400090),
+ /* UMULL cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx */
+ /* UMULLS cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx */
+ /* UMLAL cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx */
+ /* UMLALS cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx */
+ /* SMULL cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx */
+ /* SMULLS cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx */
+ /* SMLAL cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx */
+ /* SMLALS cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx */
+ DECODE_EMULATEX (0x0f8000f0, 0x00800090, PROBES_MUL1,
+ REGS(NOPC, NOPC, NOPC, 0, NOPC)),
+
+ DECODE_END
+};
+
+static const union decode_item arm_cccc_0001_____1001_table[] = {
+ /* Synchronization primitives */
+
+#if __LINUX_ARM_ARCH__ < 6
+ /* Deprecated on ARMv6 and may be UNDEFINED on v7 */
+ /* SMP/SWPB cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */
+ DECODE_EMULATEX (0x0fb000f0, 0x01000090, PROBES_SWP,
+ REGS(NOPC, NOPC, 0, 0, NOPC)),
+#endif
+ /* LDREX/STREX{,D,B,H} cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */
+ /* And unallocated instructions... */
+ DECODE_END
+};
+
+static const union decode_item arm_cccc_000x_____1xx1_table[] = {
+ /* Extra load/store instructions */
+
+ /* STRHT cccc 0000 xx10 xxxx xxxx xxxx 1011 xxxx */
+ /* ??? cccc 0000 xx10 xxxx xxxx xxxx 11x1 xxxx */
+ /* LDRHT cccc 0000 xx11 xxxx xxxx xxxx 1011 xxxx */
+ /* LDRSBT cccc 0000 xx11 xxxx xxxx xxxx 1101 xxxx */
+ /* LDRSHT cccc 0000 xx11 xxxx xxxx xxxx 1111 xxxx */
+ DECODE_REJECT (0x0f200090, 0x00200090),
+
+ /* LDRD/STRD lr,pc,{... cccc 000x x0x0 xxxx 111x xxxx 1101 xxxx */
+ DECODE_REJECT (0x0e10e0d0, 0x0000e0d0),
+
+ /* LDRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx */
+ /* STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx */
+ DECODE_EMULATEX (0x0e5000d0, 0x000000d0, PROBES_LDRSTRD,
+ REGS(NOPCWB, NOPCX, 0, 0, NOPC)),
+
+ /* LDRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx */
+ /* STRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx */
+ DECODE_EMULATEX (0x0e5000d0, 0x004000d0, PROBES_LDRSTRD,
+ REGS(NOPCWB, NOPCX, 0, 0, 0)),
+
+ /* STRH (register) cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx */
+ DECODE_EMULATEX (0x0e5000f0, 0x000000b0, PROBES_STORE_EXTRA,
+ REGS(NOPCWB, NOPC, 0, 0, NOPC)),
+
+ /* LDRH (register) cccc 000x x0x1 xxxx xxxx xxxx 1011 xxxx */
+ /* LDRSB (register) cccc 000x x0x1 xxxx xxxx xxxx 1101 xxxx */
+ /* LDRSH (register) cccc 000x x0x1 xxxx xxxx xxxx 1111 xxxx */
+ DECODE_EMULATEX (0x0e500090, 0x00100090, PROBES_LOAD_EXTRA,
+ REGS(NOPCWB, NOPC, 0, 0, NOPC)),
+
+ /* STRH (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1011 xxxx */
+ DECODE_EMULATEX (0x0e5000f0, 0x004000b0, PROBES_STORE_EXTRA,
+ REGS(NOPCWB, NOPC, 0, 0, 0)),
+
+ /* LDRH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1011 xxxx */
+ /* LDRSB (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1101 xxxx */
+ /* LDRSH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1111 xxxx */
+ DECODE_EMULATEX (0x0e500090, 0x00500090, PROBES_LOAD_EXTRA,
+ REGS(NOPCWB, NOPC, 0, 0, 0)),
+
+ DECODE_END
+};
+
+static const union decode_item arm_cccc_000x_table[] = {
+ /* Data-processing (register) */
+
+ /* <op>S PC, ... cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx */
+ DECODE_REJECT (0x0e10f000, 0x0010f000),
+
+ /* MOV IP, SP 1110 0001 1010 0000 1100 0000 0000 1101 */
+ DECODE_SIMULATE (0xffffffff, 0xe1a0c00d, PROBES_MOV_IP_SP),
+
+ /* TST (register) cccc 0001 0001 xxxx xxxx xxxx xxx0 xxxx */
+ /* TEQ (register) cccc 0001 0011 xxxx xxxx xxxx xxx0 xxxx */
+ /* CMP (register) cccc 0001 0101 xxxx xxxx xxxx xxx0 xxxx */
+ /* CMN (register) cccc 0001 0111 xxxx xxxx xxxx xxx0 xxxx */
+ DECODE_EMULATEX (0x0f900010, 0x01100000, PROBES_DATA_PROCESSING_REG,
+ REGS(ANY, 0, 0, 0, ANY)),
+
+ /* MOV (register) cccc 0001 101x xxxx xxxx xxxx xxx0 xxxx */
+ /* MVN (register) cccc 0001 111x xxxx xxxx xxxx xxx0 xxxx */
+ DECODE_EMULATEX (0x0fa00010, 0x01a00000, PROBES_DATA_PROCESSING_REG,
+ REGS(0, ANY, 0, 0, ANY)),
+
+ /* AND (register) cccc 0000 000x xxxx xxxx xxxx xxx0 xxxx */
+ /* EOR (register) cccc 0000 001x xxxx xxxx xxxx xxx0 xxxx */
+ /* SUB (register) cccc 0000 010x xxxx xxxx xxxx xxx0 xxxx */
+ /* RSB (register) cccc 0000 011x xxxx xxxx xxxx xxx0 xxxx */
+ /* ADD (register) cccc 0000 100x xxxx xxxx xxxx xxx0 xxxx */
+ /* ADC (register) cccc 0000 101x xxxx xxxx xxxx xxx0 xxxx */
+ /* SBC (register) cccc 0000 110x xxxx xxxx xxxx xxx0 xxxx */
+ /* RSC (register) cccc 0000 111x xxxx xxxx xxxx xxx0 xxxx */
+ /* ORR (register) cccc 0001 100x xxxx xxxx xxxx xxx0 xxxx */
+ /* BIC (register) cccc 0001 110x xxxx xxxx xxxx xxx0 xxxx */
+ DECODE_EMULATEX (0x0e000010, 0x00000000, PROBES_DATA_PROCESSING_REG,
+ REGS(ANY, ANY, 0, 0, ANY)),
+
+ /* TST (reg-shift reg) cccc 0001 0001 xxxx xxxx xxxx 0xx1 xxxx */
+ /* TEQ (reg-shift reg) cccc 0001 0011 xxxx xxxx xxxx 0xx1 xxxx */
+ /* CMP (reg-shift reg) cccc 0001 0101 xxxx xxxx xxxx 0xx1 xxxx */
+ /* CMN (reg-shift reg) cccc 0001 0111 xxxx xxxx xxxx 0xx1 xxxx */
+ DECODE_EMULATEX (0x0f900090, 0x01100010, PROBES_DATA_PROCESSING_REG,
+ REGS(NOPC, 0, NOPC, 0, NOPC)),
+
+ /* MOV (reg-shift reg) cccc 0001 101x xxxx xxxx xxxx 0xx1 xxxx */
+ /* MVN (reg-shift reg) cccc 0001 111x xxxx xxxx xxxx 0xx1 xxxx */
+ DECODE_EMULATEX (0x0fa00090, 0x01a00010, PROBES_DATA_PROCESSING_REG,
+ REGS(0, NOPC, NOPC, 0, NOPC)),
+
+ /* AND (reg-shift reg) cccc 0000 000x xxxx xxxx xxxx 0xx1 xxxx */
+ /* EOR (reg-shift reg) cccc 0000 001x xxxx xxxx xxxx 0xx1 xxxx */
+ /* SUB (reg-shift reg) cccc 0000 010x xxxx xxxx xxxx 0xx1 xxxx */
+ /* RSB (reg-shift reg) cccc 0000 011x xxxx xxxx xxxx 0xx1 xxxx */
+ /* ADD (reg-shift reg) cccc 0000 100x xxxx xxxx xxxx 0xx1 xxxx */
+ /* ADC (reg-shift reg) cccc 0000 101x xxxx xxxx xxxx 0xx1 xxxx */
+ /* SBC (reg-shift reg) cccc 0000 110x xxxx xxxx xxxx 0xx1 xxxx */
+ /* RSC (reg-shift reg) cccc 0000 111x xxxx xxxx xxxx 0xx1 xxxx */
+ /* ORR (reg-shift reg) cccc 0001 100x xxxx xxxx xxxx 0xx1 xxxx */
+ /* BIC (reg-shift reg) cccc 0001 110x xxxx xxxx xxxx 0xx1 xxxx */
+ DECODE_EMULATEX (0x0e000090, 0x00000010, PROBES_DATA_PROCESSING_REG,
+ REGS(NOPC, NOPC, NOPC, 0, NOPC)),
+
+ DECODE_END
+};
+
+static const union decode_item arm_cccc_001x_table[] = {
+ /* Data-processing (immediate) */
+
+ /* MOVW cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
+ /* MOVT cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0x0fb00000, 0x03000000, PROBES_MOV_HALFWORD,
+ REGS(0, NOPC, 0, 0, 0)),
+
+ /* YIELD cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
+ DECODE_OR (0x0fff00ff, 0x03200001),
+ /* SEV cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
+ DECODE_EMULATE (0x0fff00ff, 0x03200004, PROBES_SEV),
+ /* 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 */
+ DECODE_SIMULATE (0x0fff00fc, 0x03200000, PROBES_WFE),
+ /* DBG cccc 0011 0010 0000 xxxx xxxx ffff xxxx */
+ /* unallocated hints cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
+ /* MSR (immediate) cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_REJECT (0x0fb00000, 0x03200000),
+
+ /* <op>S PC, ... cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx */
+ DECODE_REJECT (0x0e10f000, 0x0210f000),
+
+ /* TST (immediate) cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx */
+ /* TEQ (immediate) cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx */
+ /* CMP (immediate) cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx */
+ /* CMN (immediate) cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0x0f900000, 0x03100000, PROBES_DATA_PROCESSING_IMM,
+ REGS(ANY, 0, 0, 0, 0)),
+
+ /* MOV (immediate) cccc 0011 101x xxxx xxxx xxxx xxxx xxxx */
+ /* MVN (immediate) cccc 0011 111x xxxx xxxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0x0fa00000, 0x03a00000, PROBES_DATA_PROCESSING_IMM,
+ REGS(0, ANY, 0, 0, 0)),
+
+ /* AND (immediate) cccc 0010 000x xxxx xxxx xxxx xxxx xxxx */
+ /* EOR (immediate) cccc 0010 001x xxxx xxxx xxxx xxxx xxxx */
+ /* SUB (immediate) cccc 0010 010x xxxx xxxx xxxx xxxx xxxx */
+ /* RSB (immediate) cccc 0010 011x xxxx xxxx xxxx xxxx xxxx */
+ /* ADD (immediate) cccc 0010 100x xxxx xxxx xxxx xxxx xxxx */
+ /* ADC (immediate) cccc 0010 101x xxxx xxxx xxxx xxxx xxxx */
+ /* SBC (immediate) cccc 0010 110x xxxx xxxx xxxx xxxx xxxx */
+ /* RSC (immediate) cccc 0010 111x xxxx xxxx xxxx xxxx xxxx */
+ /* ORR (immediate) cccc 0011 100x xxxx xxxx xxxx xxxx xxxx */
+ /* BIC (immediate) cccc 0011 110x xxxx xxxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0x0e000000, 0x02000000, PROBES_DATA_PROCESSING_IMM,
+ REGS(ANY, ANY, 0, 0, 0)),
+
+ DECODE_END
+};
+
+static const union decode_item arm_cccc_0110_____xxx1_table[] = {
+ /* Media instructions */
+
+ /* SEL cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx */
+ DECODE_EMULATEX (0x0ff000f0, 0x068000b0, PROBES_SATURATE,
+ REGS(NOPC, NOPC, 0, 0, NOPC)),
+
+ /* SSAT cccc 0110 101x xxxx xxxx xxxx xx01 xxxx */
+ /* USAT cccc 0110 111x xxxx xxxx xxxx xx01 xxxx */
+ DECODE_OR(0x0fa00030, 0x06a00010),
+ /* SSAT16 cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx */
+ /* USAT16 cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx */
+ DECODE_EMULATEX (0x0fb000f0, 0x06a00030, PROBES_SATURATE,
+ REGS(0, NOPC, 0, 0, NOPC)),
+
+ /* 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 */
+ DECODE_EMULATEX (0x0fb00070, 0x06b00030, PROBES_REV,
+ REGS(0, NOPC, 0, 0, NOPC)),
+
+ /* ??? cccc 0110 0x00 xxxx xxxx xxxx xxx1 xxxx */
+ DECODE_REJECT (0x0fb00010, 0x06000010),
+ /* ??? cccc 0110 0xxx xxxx xxxx xxxx 1011 xxxx */
+ DECODE_REJECT (0x0f8000f0, 0x060000b0),
+ /* ??? cccc 0110 0xxx xxxx xxxx xxxx 1101 xxxx */
+ DECODE_REJECT (0x0f8000f0, 0x060000d0),
+ /* SADD16 cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx */
+ /* SADDSUBX cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx */
+ /* SSUBADDX cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx */
+ /* SSUB16 cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx */
+ /* SADD8 cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx */
+ /* SSUB8 cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx */
+ /* 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 */
+ /* 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 */
+ /* SHSUB8 cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx */
+ /* UADD16 cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx */
+ /* UADDSUBX cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx */
+ /* USUBADDX cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx */
+ /* USUB16 cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx */
+ /* UADD8 cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx */
+ /* USUB8 cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx */
+ /* 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 */
+ /* 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 */
+ /* UHSUB8 cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx */
+ DECODE_EMULATEX (0x0f800010, 0x06000010, PROBES_MMI,
+ REGS(NOPC, NOPC, 0, 0, NOPC)),
+
+ /* PKHBT cccc 0110 1000 xxxx xxxx xxxx x001 xxxx */
+ /* PKHTB cccc 0110 1000 xxxx xxxx xxxx x101 xxxx */
+ DECODE_EMULATEX (0x0ff00030, 0x06800010, PROBES_PACK,
+ REGS(NOPC, NOPC, 0, 0, NOPC)),
+
+ /* ??? cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx */
+ /* ??? cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx */
+ DECODE_REJECT (0x0fb000f0, 0x06900070),
+
+ /* SXTB16 cccc 0110 1000 1111 xxxx xxxx 0111 xxxx */
+ /* SXTB cccc 0110 1010 1111 xxxx xxxx 0111 xxxx */
+ /* SXTH cccc 0110 1011 1111 xxxx xxxx 0111 xxxx */
+ /* UXTB16 cccc 0110 1100 1111 xxxx xxxx 0111 xxxx */
+ /* UXTB cccc 0110 1110 1111 xxxx xxxx 0111 xxxx */
+ /* UXTH cccc 0110 1111 1111 xxxx xxxx 0111 xxxx */
+ DECODE_EMULATEX (0x0f8f00f0, 0x068f0070, PROBES_EXTEND,
+ REGS(0, NOPC, 0, 0, NOPC)),
+
+ /* SXTAB16 cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx */
+ /* SXTAB cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx */
+ /* SXTAH cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx */
+ /* UXTAB16 cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx */
+ /* UXTAB cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx */
+ /* UXTAH cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx */
+ DECODE_EMULATEX (0x0f8000f0, 0x06800070, PROBES_EXTEND_ADD,
+ REGS(NOPCX, NOPC, 0, 0, NOPC)),
+
+ DECODE_END
+};
+
+static const union decode_item arm_cccc_0111_____xxx1_table[] = {
+ /* Media instructions */
+
+ /* UNDEFINED cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */
+ DECODE_REJECT (0x0ff000f0, 0x07f000f0),
+
+ /* SMLALD cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
+ /* SMLSLD cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
+ DECODE_EMULATEX (0x0ff00090, 0x07400010, PROBES_MUL_ADD_LONG,
+ REGS(NOPC, NOPC, NOPC, 0, NOPC)),
+
+ /* SMUAD cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx */
+ /* SMUSD cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx */
+ DECODE_OR (0x0ff0f090, 0x0700f010),
+ /* SMMUL cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx */
+ DECODE_OR (0x0ff0f0d0, 0x0750f010),
+ /* USAD8 cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
+ DECODE_EMULATEX (0x0ff0f0f0, 0x0780f010, PROBES_MUL_ADD,
+ REGS(NOPC, 0, NOPC, 0, NOPC)),
+
+ /* SMLAD cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx */
+ /* SMLSD cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx */
+ DECODE_OR (0x0ff00090, 0x07000010),
+ /* SMMLA cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx */
+ DECODE_OR (0x0ff000d0, 0x07500010),
+ /* USADA8 cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
+ DECODE_EMULATEX (0x0ff000f0, 0x07800010, PROBES_MUL_ADD,
+ REGS(NOPC, NOPCX, NOPC, 0, NOPC)),
+
+ /* SMMLS cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx */
+ DECODE_EMULATEX (0x0ff000d0, 0x075000d0, PROBES_MUL_ADD,
+ REGS(NOPC, NOPC, NOPC, 0, NOPC)),
+
+ /* SBFX cccc 0111 101x xxxx xxxx xxxx x101 xxxx */
+ /* UBFX cccc 0111 111x xxxx xxxx xxxx x101 xxxx */
+ DECODE_EMULATEX (0x0fa00070, 0x07a00050, PROBES_BITFIELD,
+ REGS(0, NOPC, 0, 0, NOPC)),
+
+ /* BFC cccc 0111 110x xxxx xxxx xxxx x001 1111 */
+ DECODE_EMULATEX (0x0fe0007f, 0x07c0001f, PROBES_BITFIELD,
+ REGS(0, NOPC, 0, 0, 0)),
+
+ /* BFI cccc 0111 110x xxxx xxxx xxxx x001 xxxx */
+ DECODE_EMULATEX (0x0fe00070, 0x07c00010, PROBES_BITFIELD,
+ REGS(0, NOPC, 0, 0, NOPCX)),
+
+ DECODE_END
+};
+
+static const union decode_item arm_cccc_01xx_table[] = {
+ /* Load/store word and unsigned byte */
+
+ /* LDRB/STRB pc,[...] cccc 01xx x0xx xxxx xxxx xxxx xxxx xxxx */
+ DECODE_REJECT (0x0c40f000, 0x0440f000),
+
+ /* STRT cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
+ /* LDRT cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */
+ /* STRBT cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
+ /* LDRBT cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_REJECT (0x0d200000, 0x04200000),
+
+ /* STR (immediate) cccc 010x x0x0 xxxx xxxx xxxx xxxx xxxx */
+ /* STRB (immediate) cccc 010x x1x0 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0x0e100000, 0x04000000, PROBES_STORE,
+ REGS(NOPCWB, ANY, 0, 0, 0)),
+
+ /* LDR (immediate) cccc 010x x0x1 xxxx xxxx xxxx xxxx xxxx */
+ /* LDRB (immediate) cccc 010x x1x1 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0x0e100000, 0x04100000, PROBES_LOAD,
+ REGS(NOPCWB, ANY, 0, 0, 0)),
+
+ /* STR (register) cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx */
+ /* STRB (register) cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0x0e100000, 0x06000000, PROBES_STORE,
+ REGS(NOPCWB, ANY, 0, 0, NOPC)),
+
+ /* LDR (register) cccc 011x x0x1 xxxx xxxx xxxx xxxx xxxx */
+ /* LDRB (register) cccc 011x x1x1 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0x0e100000, 0x06100000, PROBES_LOAD,
+ REGS(NOPCWB, ANY, 0, 0, NOPC)),
+
+ DECODE_END
+};
+
+static const union decode_item arm_cccc_100x_table[] = {
+ /* Block data transfer instructions */
+
+ /* LDM cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
+ /* STM cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_CUSTOM (0x0e400000, 0x08000000, PROBES_LDMSTM),
+
+ /* STM (user registers) cccc 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
+ /* LDM (user registers) cccc 100x x1x1 xxxx 0xxx xxxx xxxx xxxx */
+ /* LDM (exception ret) cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */
+ DECODE_END
+};
+
+const union decode_item probes_decode_arm_table[] = {
+ /*
+ * Unconditional instructions
+ * 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_TABLE (0xf0000000, 0xf0000000, arm_1111_table),
+
+ /*
+ * Miscellaneous instructions
+ * cccc 0001 0xx0 xxxx xxxx xxxx 0xxx xxxx
+ */
+ DECODE_TABLE (0x0f900080, 0x01000000, arm_cccc_0001_0xx0____0xxx_table),
+
+ /*
+ * Halfword multiply and multiply-accumulate
+ * cccc 0001 0xx0 xxxx xxxx xxxx 1xx0 xxxx
+ */
+ DECODE_TABLE (0x0f900090, 0x01000080, arm_cccc_0001_0xx0____1xx0_table),
+
+ /*
+ * Multiply and multiply-accumulate
+ * cccc 0000 xxxx xxxx xxxx xxxx 1001 xxxx
+ */
+ DECODE_TABLE (0x0f0000f0, 0x00000090, arm_cccc_0000_____1001_table),
+
+ /*
+ * Synchronization primitives
+ * cccc 0001 xxxx xxxx xxxx xxxx 1001 xxxx
+ */
+ DECODE_TABLE (0x0f0000f0, 0x01000090, arm_cccc_0001_____1001_table),
+
+ /*
+ * Extra load/store instructions
+ * cccc 000x xxxx xxxx xxxx xxxx 1xx1 xxxx
+ */
+ DECODE_TABLE (0x0e000090, 0x00000090, arm_cccc_000x_____1xx1_table),
+
+ /*
+ * Data-processing (register)
+ * cccc 000x xxxx xxxx xxxx xxxx xxx0 xxxx
+ * Data-processing (register-shifted register)
+ * cccc 000x xxxx xxxx xxxx xxxx 0xx1 xxxx
+ */
+ DECODE_TABLE (0x0e000000, 0x00000000, arm_cccc_000x_table),
+
+ /*
+ * Data-processing (immediate)
+ * cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_TABLE (0x0e000000, 0x02000000, arm_cccc_001x_table),
+
+ /*
+ * Media instructions
+ * cccc 011x xxxx xxxx xxxx xxxx xxx1 xxxx
+ */
+ DECODE_TABLE (0x0f000010, 0x06000010, arm_cccc_0110_____xxx1_table),
+ DECODE_TABLE (0x0f000010, 0x07000010, arm_cccc_0111_____xxx1_table),
+
+ /*
+ * Load/store word and unsigned byte
+ * cccc 01xx xxxx xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_TABLE (0x0c000000, 0x04000000, arm_cccc_01xx_table),
+
+ /*
+ * Block data transfer instructions
+ * cccc 100x xxxx xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_TABLE (0x0e000000, 0x08000000, arm_cccc_100x_table),
+
+ /* B cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
+ /* BL cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
+ DECODE_SIMULATE (0x0e000000, 0x0a000000, PROBES_BRANCH),
+
+ /*
+ * Supervisor Call, and coprocessor instructions
+ */
+
+ /* MCRR cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx */
+ /* MRRC cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx */
+ /* 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 */
+ DECODE_REJECT (0x0c000000, 0x0c000000),
+
+ DECODE_END
+};
+#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
+EXPORT_SYMBOL_GPL(probes_decode_arm_table);
+#endif
+
+static void __kprobes arm_singlestep(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ regs->ARM_pc += 4;
+ asi->insn_handler(insn, asi, regs);
+}
+
+/* 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 probes_insn __kprobes
+arm_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+ bool emulate, const union decode_action *actions,
+ const struct decode_checker *checkers[])
+{
+ asi->insn_singlestep = arm_singlestep;
+ asi->insn_check_cc = probes_condition_checks[insn>>28];
+ return probes_decode_insn(insn, asi, probes_decode_arm_table, false,
+ emulate, actions, checkers);
+}
diff --git a/arch/arm/probes/decode-arm.h b/arch/arm/probes/decode-arm.h
new file mode 100644
index 000000000..b3b80f6d4
--- /dev/null
+++ b/arch/arm/probes/decode-arm.h
@@ -0,0 +1,74 @@
+/*
+ * arch/arm/probes/decode-arm.h
+ *
+ * Copyright 2013 Linaro Ltd.
+ * Written by: David A. Long
+ *
+ * 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 _ARM_KERNEL_PROBES_ARM_H
+#define _ARM_KERNEL_PROBES_ARM_H
+
+#include "decode.h"
+
+enum probes_arm_action {
+ PROBES_PRELOAD_IMM,
+ PROBES_PRELOAD_REG,
+ PROBES_BRANCH_IMM,
+ PROBES_BRANCH_REG,
+ PROBES_MRS,
+ PROBES_CLZ,
+ PROBES_SATURATING_ARITHMETIC,
+ PROBES_MUL1,
+ PROBES_MUL2,
+ PROBES_SWP,
+ PROBES_LDRSTRD,
+ PROBES_LOAD,
+ PROBES_STORE,
+ PROBES_LOAD_EXTRA,
+ PROBES_STORE_EXTRA,
+ PROBES_MOV_IP_SP,
+ PROBES_DATA_PROCESSING_REG,
+ PROBES_DATA_PROCESSING_IMM,
+ PROBES_MOV_HALFWORD,
+ PROBES_SEV,
+ PROBES_WFE,
+ PROBES_SATURATE,
+ PROBES_REV,
+ PROBES_MMI,
+ PROBES_PACK,
+ PROBES_EXTEND,
+ PROBES_EXTEND_ADD,
+ PROBES_MUL_ADD_LONG,
+ PROBES_MUL_ADD,
+ PROBES_BITFIELD,
+ PROBES_BRANCH,
+ PROBES_LDMSTM,
+ NUM_PROBES_ARM_ACTIONS
+};
+
+void __kprobes simulate_bbl(probes_opcode_t opcode,
+ struct arch_probes_insn *asi, struct pt_regs *regs);
+void __kprobes simulate_blx1(probes_opcode_t opcode,
+ struct arch_probes_insn *asi, struct pt_regs *regs);
+void __kprobes simulate_blx2bx(probes_opcode_t opcode,
+ struct arch_probes_insn *asi, struct pt_regs *regs);
+void __kprobes simulate_mrs(probes_opcode_t opcode,
+ struct arch_probes_insn *asi, struct pt_regs *regs);
+void __kprobes simulate_mov_ipsp(probes_opcode_t opcode,
+ struct arch_probes_insn *asi, struct pt_regs *regs);
+
+extern const union decode_item probes_decode_arm_table[];
+
+enum probes_insn arm_probes_decode_insn(probes_opcode_t,
+ struct arch_probes_insn *, bool emulate,
+ const union decode_action *actions,
+ const struct decode_checker *checkers[]);
+
+#endif
diff --git a/arch/arm/probes/decode-thumb.c b/arch/arm/probes/decode-thumb.c
new file mode 100644
index 000000000..985e7dd4c
--- /dev/null
+++ b/arch/arm/probes/decode-thumb.c
@@ -0,0 +1,884 @@
+/*
+ * arch/arm/probes/decode-thumb.c
+ *
+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.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/stddef.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "decode.h"
+#include "decode-thumb.h"
+
+
+static const union decode_item t32_table_1110_100x_x0xx[] = {
+ /* Load/store multiple instructions */
+
+ /* Rn is PC 1110 100x x0xx 1111 xxxx xxxx xxxx xxxx */
+ DECODE_REJECT (0xfe4f0000, 0xe80f0000),
+
+ /* SRS 1110 1000 00x0 xxxx xxxx xxxx xxxx xxxx */
+ /* RFE 1110 1000 00x1 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_REJECT (0xffc00000, 0xe8000000),
+ /* SRS 1110 1001 10x0 xxxx xxxx xxxx xxxx xxxx */
+ /* RFE 1110 1001 10x1 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_REJECT (0xffc00000, 0xe9800000),
+
+ /* STM Rn, {...pc} 1110 100x x0x0 xxxx 1xxx xxxx xxxx xxxx */
+ DECODE_REJECT (0xfe508000, 0xe8008000),
+ /* LDM Rn, {...lr,pc} 1110 100x x0x1 xxxx 11xx xxxx xxxx xxxx */
+ DECODE_REJECT (0xfe50c000, 0xe810c000),
+ /* LDM/STM Rn, {...sp} 1110 100x x0xx xxxx xx1x xxxx xxxx xxxx */
+ DECODE_REJECT (0xfe402000, 0xe8002000),
+
+ /* STMIA 1110 1000 10x0 xxxx xxxx xxxx xxxx xxxx */
+ /* LDMIA 1110 1000 10x1 xxxx xxxx xxxx xxxx xxxx */
+ /* STMDB 1110 1001 00x0 xxxx xxxx xxxx xxxx xxxx */
+ /* LDMDB 1110 1001 00x1 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_CUSTOM (0xfe400000, 0xe8000000, PROBES_T32_LDMSTM),
+
+ DECODE_END
+};
+
+static const union decode_item t32_table_1110_100x_x1xx[] = {
+ /* Load/store dual, load/store exclusive, table branch */
+
+ /* STRD (immediate) 1110 1000 x110 xxxx xxxx xxxx xxxx xxxx */
+ /* LDRD (immediate) 1110 1000 x111 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_OR (0xff600000, 0xe8600000),
+ /* STRD (immediate) 1110 1001 x1x0 xxxx xxxx xxxx xxxx xxxx */
+ /* LDRD (immediate) 1110 1001 x1x1 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0xff400000, 0xe9400000, PROBES_T32_LDRDSTRD,
+ REGS(NOPCWB, NOSPPC, NOSPPC, 0, 0)),
+
+ /* TBB 1110 1000 1101 xxxx xxxx xxxx 0000 xxxx */
+ /* TBH 1110 1000 1101 xxxx xxxx xxxx 0001 xxxx */
+ DECODE_SIMULATEX(0xfff000e0, 0xe8d00000, PROBES_T32_TABLE_BRANCH,
+ REGS(NOSP, 0, 0, 0, NOSPPC)),
+
+ /* STREX 1110 1000 0100 xxxx xxxx xxxx xxxx xxxx */
+ /* LDREX 1110 1000 0101 xxxx xxxx xxxx xxxx xxxx */
+ /* STREXB 1110 1000 1100 xxxx xxxx xxxx 0100 xxxx */
+ /* STREXH 1110 1000 1100 xxxx xxxx xxxx 0101 xxxx */
+ /* STREXD 1110 1000 1100 xxxx xxxx xxxx 0111 xxxx */
+ /* LDREXB 1110 1000 1101 xxxx xxxx xxxx 0100 xxxx */
+ /* LDREXH 1110 1000 1101 xxxx xxxx xxxx 0101 xxxx */
+ /* LDREXD 1110 1000 1101 xxxx xxxx xxxx 0111 xxxx */
+ /* And unallocated instructions... */
+ DECODE_END
+};
+
+static const union decode_item t32_table_1110_101x[] = {
+ /* Data-processing (shifted register) */
+
+ /* TST 1110 1010 0001 xxxx xxxx 1111 xxxx xxxx */
+ /* TEQ 1110 1010 1001 xxxx xxxx 1111 xxxx xxxx */
+ DECODE_EMULATEX (0xff700f00, 0xea100f00, PROBES_T32_TST,
+ REGS(NOSPPC, 0, 0, 0, NOSPPC)),
+
+ /* CMN 1110 1011 0001 xxxx xxxx 1111 xxxx xxxx */
+ DECODE_OR (0xfff00f00, 0xeb100f00),
+ /* CMP 1110 1011 1011 xxxx xxxx 1111 xxxx xxxx */
+ DECODE_EMULATEX (0xfff00f00, 0xebb00f00, PROBES_T32_TST,
+ REGS(NOPC, 0, 0, 0, NOSPPC)),
+
+ /* MOV 1110 1010 010x 1111 xxxx xxxx xxxx xxxx */
+ /* MVN 1110 1010 011x 1111 xxxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0xffcf0000, 0xea4f0000, PROBES_T32_MOV,
+ REGS(0, 0, NOSPPC, 0, NOSPPC)),
+
+ /* ??? 1110 1010 101x xxxx xxxx xxxx xxxx xxxx */
+ /* ??? 1110 1010 111x xxxx xxxx xxxx xxxx xxxx */
+ DECODE_REJECT (0xffa00000, 0xeaa00000),
+ /* ??? 1110 1011 001x xxxx xxxx xxxx xxxx xxxx */
+ DECODE_REJECT (0xffe00000, 0xeb200000),
+ /* ??? 1110 1011 100x xxxx xxxx xxxx xxxx xxxx */
+ DECODE_REJECT (0xffe00000, 0xeb800000),
+ /* ??? 1110 1011 111x xxxx xxxx xxxx xxxx xxxx */
+ DECODE_REJECT (0xffe00000, 0xebe00000),
+
+ /* ADD/SUB SP, SP, Rm, LSL #0..3 */
+ /* 1110 1011 x0xx 1101 x000 1101 xx00 xxxx */
+ DECODE_EMULATEX (0xff4f7f30, 0xeb0d0d00, PROBES_T32_ADDSUB,
+ REGS(SP, 0, SP, 0, NOSPPC)),
+
+ /* ADD/SUB SP, SP, Rm, shift */
+ /* 1110 1011 x0xx 1101 xxxx 1101 xxxx xxxx */
+ DECODE_REJECT (0xff4f0f00, 0xeb0d0d00),
+
+ /* ADD/SUB Rd, SP, Rm, shift */
+ /* 1110 1011 x0xx 1101 xxxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0xff4f0000, 0xeb0d0000, PROBES_T32_ADDSUB,
+ REGS(SP, 0, NOPC, 0, NOSPPC)),
+
+ /* AND 1110 1010 000x xxxx xxxx xxxx xxxx xxxx */
+ /* BIC 1110 1010 001x xxxx xxxx xxxx xxxx xxxx */
+ /* ORR 1110 1010 010x xxxx xxxx xxxx xxxx xxxx */
+ /* ORN 1110 1010 011x xxxx xxxx xxxx xxxx xxxx */
+ /* EOR 1110 1010 100x xxxx xxxx xxxx xxxx xxxx */
+ /* PKH 1110 1010 110x xxxx xxxx xxxx xxxx xxxx */
+ /* ADD 1110 1011 000x xxxx xxxx xxxx xxxx xxxx */
+ /* ADC 1110 1011 010x xxxx xxxx xxxx xxxx xxxx */
+ /* SBC 1110 1011 011x xxxx xxxx xxxx xxxx xxxx */
+ /* SUB 1110 1011 101x xxxx xxxx xxxx xxxx xxxx */
+ /* RSB 1110 1011 110x xxxx xxxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0xfe000000, 0xea000000, PROBES_T32_LOGICAL,
+ REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
+
+ DECODE_END
+};
+
+static const union decode_item t32_table_1111_0x0x___0[] = {
+ /* Data-processing (modified immediate) */
+
+ /* TST 1111 0x00 0001 xxxx 0xxx 1111 xxxx xxxx */
+ /* TEQ 1111 0x00 1001 xxxx 0xxx 1111 xxxx xxxx */
+ DECODE_EMULATEX (0xfb708f00, 0xf0100f00, PROBES_T32_TST,
+ REGS(NOSPPC, 0, 0, 0, 0)),
+
+ /* CMN 1111 0x01 0001 xxxx 0xxx 1111 xxxx xxxx */
+ DECODE_OR (0xfbf08f00, 0xf1100f00),
+ /* CMP 1111 0x01 1011 xxxx 0xxx 1111 xxxx xxxx */
+ DECODE_EMULATEX (0xfbf08f00, 0xf1b00f00, PROBES_T32_CMP,
+ REGS(NOPC, 0, 0, 0, 0)),
+
+ /* MOV 1111 0x00 010x 1111 0xxx xxxx xxxx xxxx */
+ /* MVN 1111 0x00 011x 1111 0xxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0xfbcf8000, 0xf04f0000, PROBES_T32_MOV,
+ REGS(0, 0, NOSPPC, 0, 0)),
+
+ /* ??? 1111 0x00 101x xxxx 0xxx xxxx xxxx xxxx */
+ DECODE_REJECT (0xfbe08000, 0xf0a00000),
+ /* ??? 1111 0x00 110x xxxx 0xxx xxxx xxxx xxxx */
+ /* ??? 1111 0x00 111x xxxx 0xxx xxxx xxxx xxxx */
+ DECODE_REJECT (0xfbc08000, 0xf0c00000),
+ /* ??? 1111 0x01 001x xxxx 0xxx xxxx xxxx xxxx */
+ DECODE_REJECT (0xfbe08000, 0xf1200000),
+ /* ??? 1111 0x01 100x xxxx 0xxx xxxx xxxx xxxx */
+ DECODE_REJECT (0xfbe08000, 0xf1800000),
+ /* ??? 1111 0x01 111x xxxx 0xxx xxxx xxxx xxxx */
+ DECODE_REJECT (0xfbe08000, 0xf1e00000),
+
+ /* ADD Rd, SP, #imm 1111 0x01 000x 1101 0xxx xxxx xxxx xxxx */
+ /* SUB Rd, SP, #imm 1111 0x01 101x 1101 0xxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0xfb4f8000, 0xf10d0000, PROBES_T32_ADDSUB,
+ REGS(SP, 0, NOPC, 0, 0)),
+
+ /* AND 1111 0x00 000x xxxx 0xxx xxxx xxxx xxxx */
+ /* BIC 1111 0x00 001x xxxx 0xxx xxxx xxxx xxxx */
+ /* ORR 1111 0x00 010x xxxx 0xxx xxxx xxxx xxxx */
+ /* ORN 1111 0x00 011x xxxx 0xxx xxxx xxxx xxxx */
+ /* EOR 1111 0x00 100x xxxx 0xxx xxxx xxxx xxxx */
+ /* ADD 1111 0x01 000x xxxx 0xxx xxxx xxxx xxxx */
+ /* ADC 1111 0x01 010x xxxx 0xxx xxxx xxxx xxxx */
+ /* SBC 1111 0x01 011x xxxx 0xxx xxxx xxxx xxxx */
+ /* SUB 1111 0x01 101x xxxx 0xxx xxxx xxxx xxxx */
+ /* RSB 1111 0x01 110x xxxx 0xxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0xfa008000, 0xf0000000, PROBES_T32_LOGICAL,
+ REGS(NOSPPC, 0, NOSPPC, 0, 0)),
+
+ DECODE_END
+};
+
+static const union decode_item t32_table_1111_0x1x___0[] = {
+ /* Data-processing (plain binary immediate) */
+
+ /* ADDW Rd, PC, #imm 1111 0x10 0000 1111 0xxx xxxx xxxx xxxx */
+ DECODE_OR (0xfbff8000, 0xf20f0000),
+ /* SUBW Rd, PC, #imm 1111 0x10 1010 1111 0xxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0xfbff8000, 0xf2af0000, PROBES_T32_ADDWSUBW_PC,
+ REGS(PC, 0, NOSPPC, 0, 0)),
+
+ /* ADDW SP, SP, #imm 1111 0x10 0000 1101 0xxx 1101 xxxx xxxx */
+ DECODE_OR (0xfbff8f00, 0xf20d0d00),
+ /* SUBW SP, SP, #imm 1111 0x10 1010 1101 0xxx 1101 xxxx xxxx */
+ DECODE_EMULATEX (0xfbff8f00, 0xf2ad0d00, PROBES_T32_ADDWSUBW,
+ REGS(SP, 0, SP, 0, 0)),
+
+ /* ADDW 1111 0x10 0000 xxxx 0xxx xxxx xxxx xxxx */
+ DECODE_OR (0xfbf08000, 0xf2000000),
+ /* SUBW 1111 0x10 1010 xxxx 0xxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0xfbf08000, 0xf2a00000, PROBES_T32_ADDWSUBW,
+ REGS(NOPCX, 0, NOSPPC, 0, 0)),
+
+ /* MOVW 1111 0x10 0100 xxxx 0xxx xxxx xxxx xxxx */
+ /* MOVT 1111 0x10 1100 xxxx 0xxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0xfb708000, 0xf2400000, PROBES_T32_MOVW,
+ REGS(0, 0, NOSPPC, 0, 0)),
+
+ /* SSAT16 1111 0x11 0010 xxxx 0000 xxxx 00xx xxxx */
+ /* SSAT 1111 0x11 00x0 xxxx 0xxx xxxx xxxx xxxx */
+ /* USAT16 1111 0x11 1010 xxxx 0000 xxxx 00xx xxxx */
+ /* USAT 1111 0x11 10x0 xxxx 0xxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0xfb508000, 0xf3000000, PROBES_T32_SAT,
+ REGS(NOSPPC, 0, NOSPPC, 0, 0)),
+
+ /* SFBX 1111 0x11 0100 xxxx 0xxx xxxx xxxx xxxx */
+ /* UFBX 1111 0x11 1100 xxxx 0xxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0xfb708000, 0xf3400000, PROBES_T32_BITFIELD,
+ REGS(NOSPPC, 0, NOSPPC, 0, 0)),
+
+ /* BFC 1111 0x11 0110 1111 0xxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0xfbff8000, 0xf36f0000, PROBES_T32_BITFIELD,
+ REGS(0, 0, NOSPPC, 0, 0)),
+
+ /* BFI 1111 0x11 0110 xxxx 0xxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0xfbf08000, 0xf3600000, PROBES_T32_BITFIELD,
+ REGS(NOSPPCX, 0, NOSPPC, 0, 0)),
+
+ DECODE_END
+};
+
+static const union decode_item t32_table_1111_0xxx___1[] = {
+ /* Branches and miscellaneous control */
+
+ /* YIELD 1111 0011 1010 xxxx 10x0 x000 0000 0001 */
+ DECODE_OR (0xfff0d7ff, 0xf3a08001),
+ /* SEV 1111 0011 1010 xxxx 10x0 x000 0000 0100 */
+ DECODE_EMULATE (0xfff0d7ff, 0xf3a08004, PROBES_T32_SEV),
+ /* NOP 1111 0011 1010 xxxx 10x0 x000 0000 0000 */
+ /* WFE 1111 0011 1010 xxxx 10x0 x000 0000 0010 */
+ /* WFI 1111 0011 1010 xxxx 10x0 x000 0000 0011 */
+ DECODE_SIMULATE (0xfff0d7fc, 0xf3a08000, PROBES_T32_WFE),
+
+ /* MRS Rd, CPSR 1111 0011 1110 xxxx 10x0 xxxx xxxx xxxx */
+ DECODE_SIMULATEX(0xfff0d000, 0xf3e08000, PROBES_T32_MRS,
+ REGS(0, 0, NOSPPC, 0, 0)),
+
+ /*
+ * Unsupported instructions
+ * 1111 0x11 1xxx xxxx 10x0 xxxx xxxx xxxx
+ *
+ * MSR 1111 0011 100x xxxx 10x0 xxxx xxxx xxxx
+ * DBG hint 1111 0011 1010 xxxx 10x0 x000 1111 xxxx
+ * Unallocated hints 1111 0011 1010 xxxx 10x0 x000 xxxx xxxx
+ * CPS 1111 0011 1010 xxxx 10x0 xxxx xxxx xxxx
+ * CLREX/DSB/DMB/ISB 1111 0011 1011 xxxx 10x0 xxxx xxxx xxxx
+ * BXJ 1111 0011 1100 xxxx 10x0 xxxx xxxx xxxx
+ * SUBS PC,LR,#<imm8> 1111 0011 1101 xxxx 10x0 xxxx xxxx xxxx
+ * MRS Rd, SPSR 1111 0011 1111 xxxx 10x0 xxxx xxxx xxxx
+ * SMC 1111 0111 1111 xxxx 1000 xxxx xxxx xxxx
+ * UNDEFINED 1111 0111 1111 xxxx 1010 xxxx xxxx xxxx
+ * ??? 1111 0111 1xxx xxxx 1010 xxxx xxxx xxxx
+ */
+ DECODE_REJECT (0xfb80d000, 0xf3808000),
+
+ /* Bcc 1111 0xxx xxxx xxxx 10x0 xxxx xxxx xxxx */
+ DECODE_CUSTOM (0xf800d000, 0xf0008000, PROBES_T32_BRANCH_COND),
+
+ /* BLX 1111 0xxx xxxx xxxx 11x0 xxxx xxxx xxx0 */
+ DECODE_OR (0xf800d001, 0xf000c000),
+ /* B 1111 0xxx xxxx xxxx 10x1 xxxx xxxx xxxx */
+ /* BL 1111 0xxx xxxx xxxx 11x1 xxxx xxxx xxxx */
+ DECODE_SIMULATE (0xf8009000, 0xf0009000, PROBES_T32_BRANCH),
+
+ DECODE_END
+};
+
+static const union decode_item t32_table_1111_100x_x0x1__1111[] = {
+ /* Memory hints */
+
+ /* PLD (literal) 1111 1000 x001 1111 1111 xxxx xxxx xxxx */
+ /* PLI (literal) 1111 1001 x001 1111 1111 xxxx xxxx xxxx */
+ DECODE_SIMULATE (0xfe7ff000, 0xf81ff000, PROBES_T32_PLDI),
+
+ /* PLD{W} (immediate) 1111 1000 10x1 xxxx 1111 xxxx xxxx xxxx */
+ DECODE_OR (0xffd0f000, 0xf890f000),
+ /* PLD{W} (immediate) 1111 1000 00x1 xxxx 1111 1100 xxxx xxxx */
+ DECODE_OR (0xffd0ff00, 0xf810fc00),
+ /* PLI (immediate) 1111 1001 1001 xxxx 1111 xxxx xxxx xxxx */
+ DECODE_OR (0xfff0f000, 0xf990f000),
+ /* PLI (immediate) 1111 1001 0001 xxxx 1111 1100 xxxx xxxx */
+ DECODE_SIMULATEX(0xfff0ff00, 0xf910fc00, PROBES_T32_PLDI,
+ REGS(NOPCX, 0, 0, 0, 0)),
+
+ /* PLD{W} (register) 1111 1000 00x1 xxxx 1111 0000 00xx xxxx */
+ DECODE_OR (0xffd0ffc0, 0xf810f000),
+ /* PLI (register) 1111 1001 0001 xxxx 1111 0000 00xx xxxx */
+ DECODE_SIMULATEX(0xfff0ffc0, 0xf910f000, PROBES_T32_PLDI,
+ REGS(NOPCX, 0, 0, 0, NOSPPC)),
+
+ /* Other unallocated instructions... */
+ DECODE_END
+};
+
+static const union decode_item t32_table_1111_100x[] = {
+ /* Store/Load single data item */
+
+ /* ??? 1111 100x x11x xxxx xxxx xxxx xxxx xxxx */
+ DECODE_REJECT (0xfe600000, 0xf8600000),
+
+ /* ??? 1111 1001 0101 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_REJECT (0xfff00000, 0xf9500000),
+
+ /* ??? 1111 100x 0xxx xxxx xxxx 10x0 xxxx xxxx */
+ DECODE_REJECT (0xfe800d00, 0xf8000800),
+
+ /* STRBT 1111 1000 0000 xxxx xxxx 1110 xxxx xxxx */
+ /* STRHT 1111 1000 0010 xxxx xxxx 1110 xxxx xxxx */
+ /* STRT 1111 1000 0100 xxxx xxxx 1110 xxxx xxxx */
+ /* LDRBT 1111 1000 0001 xxxx xxxx 1110 xxxx xxxx */
+ /* LDRSBT 1111 1001 0001 xxxx xxxx 1110 xxxx xxxx */
+ /* LDRHT 1111 1000 0011 xxxx xxxx 1110 xxxx xxxx */
+ /* LDRSHT 1111 1001 0011 xxxx xxxx 1110 xxxx xxxx */
+ /* LDRT 1111 1000 0101 xxxx xxxx 1110 xxxx xxxx */
+ DECODE_REJECT (0xfe800f00, 0xf8000e00),
+
+ /* STR{,B,H} Rn,[PC...] 1111 1000 xxx0 1111 xxxx xxxx xxxx xxxx */
+ DECODE_REJECT (0xff1f0000, 0xf80f0000),
+
+ /* STR{,B,H} PC,[Rn...] 1111 1000 xxx0 xxxx 1111 xxxx xxxx xxxx */
+ DECODE_REJECT (0xff10f000, 0xf800f000),
+
+ /* LDR (literal) 1111 1000 x101 1111 xxxx xxxx xxxx xxxx */
+ DECODE_SIMULATEX(0xff7f0000, 0xf85f0000, PROBES_T32_LDR_LIT,
+ REGS(PC, ANY, 0, 0, 0)),
+
+ /* STR (immediate) 1111 1000 0100 xxxx xxxx 1xxx xxxx xxxx */
+ /* LDR (immediate) 1111 1000 0101 xxxx xxxx 1xxx xxxx xxxx */
+ DECODE_OR (0xffe00800, 0xf8400800),
+ /* STR (immediate) 1111 1000 1100 xxxx xxxx xxxx xxxx xxxx */
+ /* LDR (immediate) 1111 1000 1101 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0xffe00000, 0xf8c00000, PROBES_T32_LDRSTR,
+ REGS(NOPCX, ANY, 0, 0, 0)),
+
+ /* STR (register) 1111 1000 0100 xxxx xxxx 0000 00xx xxxx */
+ /* LDR (register) 1111 1000 0101 xxxx xxxx 0000 00xx xxxx */
+ DECODE_EMULATEX (0xffe00fc0, 0xf8400000, PROBES_T32_LDRSTR,
+ REGS(NOPCX, ANY, 0, 0, NOSPPC)),
+
+ /* LDRB (literal) 1111 1000 x001 1111 xxxx xxxx xxxx xxxx */
+ /* LDRSB (literal) 1111 1001 x001 1111 xxxx xxxx xxxx xxxx */
+ /* LDRH (literal) 1111 1000 x011 1111 xxxx xxxx xxxx xxxx */
+ /* LDRSH (literal) 1111 1001 x011 1111 xxxx xxxx xxxx xxxx */
+ DECODE_SIMULATEX(0xfe5f0000, 0xf81f0000, PROBES_T32_LDR_LIT,
+ REGS(PC, NOSPPCX, 0, 0, 0)),
+
+ /* STRB (immediate) 1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */
+ /* STRH (immediate) 1111 1000 0010 xxxx xxxx 1xxx xxxx xxxx */
+ /* LDRB (immediate) 1111 1000 0001 xxxx xxxx 1xxx xxxx xxxx */
+ /* LDRSB (immediate) 1111 1001 0001 xxxx xxxx 1xxx xxxx xxxx */
+ /* LDRH (immediate) 1111 1000 0011 xxxx xxxx 1xxx xxxx xxxx */
+ /* LDRSH (immediate) 1111 1001 0011 xxxx xxxx 1xxx xxxx xxxx */
+ DECODE_OR (0xfec00800, 0xf8000800),
+ /* STRB (immediate) 1111 1000 1000 xxxx xxxx xxxx xxxx xxxx */
+ /* STRH (immediate) 1111 1000 1010 xxxx xxxx xxxx xxxx xxxx */
+ /* LDRB (immediate) 1111 1000 1001 xxxx xxxx xxxx xxxx xxxx */
+ /* LDRSB (immediate) 1111 1001 1001 xxxx xxxx xxxx xxxx xxxx */
+ /* LDRH (immediate) 1111 1000 1011 xxxx xxxx xxxx xxxx xxxx */
+ /* LDRSH (immediate) 1111 1001 1011 xxxx xxxx xxxx xxxx xxxx */
+ DECODE_EMULATEX (0xfec00000, 0xf8800000, PROBES_T32_LDRSTR,
+ REGS(NOPCX, NOSPPCX, 0, 0, 0)),
+
+ /* STRB (register) 1111 1000 0000 xxxx xxxx 0000 00xx xxxx */
+ /* STRH (register) 1111 1000 0010 xxxx xxxx 0000 00xx xxxx */
+ /* LDRB (register) 1111 1000 0001 xxxx xxxx 0000 00xx xxxx */
+ /* LDRSB (register) 1111 1001 0001 xxxx xxxx 0000 00xx xxxx */
+ /* LDRH (register) 1111 1000 0011 xxxx xxxx 0000 00xx xxxx */
+ /* LDRSH (register) 1111 1001 0011 xxxx xxxx 0000 00xx xxxx */
+ DECODE_EMULATEX (0xfe800fc0, 0xf8000000, PROBES_T32_LDRSTR,
+ REGS(NOPCX, NOSPPCX, 0, 0, NOSPPC)),
+
+ /* Other unallocated instructions... */
+ DECODE_END
+};
+
+static const union decode_item t32_table_1111_1010___1111[] = {
+ /* Data-processing (register) */
+
+ /* ??? 1111 1010 011x xxxx 1111 xxxx 1xxx xxxx */
+ DECODE_REJECT (0xffe0f080, 0xfa60f080),
+
+ /* SXTH 1111 1010 0000 1111 1111 xxxx 1xxx xxxx */
+ /* UXTH 1111 1010 0001 1111 1111 xxxx 1xxx xxxx */
+ /* SXTB16 1111 1010 0010 1111 1111 xxxx 1xxx xxxx */
+ /* UXTB16 1111 1010 0011 1111 1111 xxxx 1xxx xxxx */
+ /* SXTB 1111 1010 0100 1111 1111 xxxx 1xxx xxxx */
+ /* UXTB 1111 1010 0101 1111 1111 xxxx 1xxx xxxx */
+ DECODE_EMULATEX (0xff8ff080, 0xfa0ff080, PROBES_T32_SIGN_EXTEND,
+ REGS(0, 0, NOSPPC, 0, NOSPPC)),
+
+
+ /* ??? 1111 1010 1xxx xxxx 1111 xxxx 0x11 xxxx */
+ DECODE_REJECT (0xff80f0b0, 0xfa80f030),
+ /* ??? 1111 1010 1x11 xxxx 1111 xxxx 0xxx xxxx */
+ DECODE_REJECT (0xffb0f080, 0xfab0f000),
+
+ /* SADD16 1111 1010 1001 xxxx 1111 xxxx 0000 xxxx */
+ /* SASX 1111 1010 1010 xxxx 1111 xxxx 0000 xxxx */
+ /* SSAX 1111 1010 1110 xxxx 1111 xxxx 0000 xxxx */
+ /* SSUB16 1111 1010 1101 xxxx 1111 xxxx 0000 xxxx */
+ /* SADD8 1111 1010 1000 xxxx 1111 xxxx 0000 xxxx */
+ /* SSUB8 1111 1010 1100 xxxx 1111 xxxx 0000 xxxx */
+
+ /* QADD16 1111 1010 1001 xxxx 1111 xxxx 0001 xxxx */
+ /* QASX 1111 1010 1010 xxxx 1111 xxxx 0001 xxxx */
+ /* QSAX 1111 1010 1110 xxxx 1111 xxxx 0001 xxxx */
+ /* QSUB16 1111 1010 1101 xxxx 1111 xxxx 0001 xxxx */
+ /* QADD8 1111 1010 1000 xxxx 1111 xxxx 0001 xxxx */
+ /* QSUB8 1111 1010 1100 xxxx 1111 xxxx 0001 xxxx */
+
+ /* SHADD16 1111 1010 1001 xxxx 1111 xxxx 0010 xxxx */
+ /* SHASX 1111 1010 1010 xxxx 1111 xxxx 0010 xxxx */
+ /* SHSAX 1111 1010 1110 xxxx 1111 xxxx 0010 xxxx */
+ /* SHSUB16 1111 1010 1101 xxxx 1111 xxxx 0010 xxxx */
+ /* SHADD8 1111 1010 1000 xxxx 1111 xxxx 0010 xxxx */
+ /* SHSUB8 1111 1010 1100 xxxx 1111 xxxx 0010 xxxx */
+
+ /* UADD16 1111 1010 1001 xxxx 1111 xxxx 0100 xxxx */
+ /* UASX 1111 1010 1010 xxxx 1111 xxxx 0100 xxxx */
+ /* USAX 1111 1010 1110 xxxx 1111 xxxx 0100 xxxx */
+ /* USUB16 1111 1010 1101 xxxx 1111 xxxx 0100 xxxx */
+ /* UADD8 1111 1010 1000 xxxx 1111 xxxx 0100 xxxx */
+ /* USUB8 1111 1010 1100 xxxx 1111 xxxx 0100 xxxx */
+
+ /* UQADD16 1111 1010 1001 xxxx 1111 xxxx 0101 xxxx */
+ /* UQASX 1111 1010 1010 xxxx 1111 xxxx 0101 xxxx */
+ /* UQSAX 1111 1010 1110 xxxx 1111 xxxx 0101 xxxx */
+ /* UQSUB16 1111 1010 1101 xxxx 1111 xxxx 0101 xxxx */
+ /* UQADD8 1111 1010 1000 xxxx 1111 xxxx 0101 xxxx */
+ /* UQSUB8 1111 1010 1100 xxxx 1111 xxxx 0101 xxxx */
+
+ /* UHADD16 1111 1010 1001 xxxx 1111 xxxx 0110 xxxx */
+ /* UHASX 1111 1010 1010 xxxx 1111 xxxx 0110 xxxx */
+ /* UHSAX 1111 1010 1110 xxxx 1111 xxxx 0110 xxxx */
+ /* UHSUB16 1111 1010 1101 xxxx 1111 xxxx 0110 xxxx */
+ /* UHADD8 1111 1010 1000 xxxx 1111 xxxx 0110 xxxx */
+ /* UHSUB8 1111 1010 1100 xxxx 1111 xxxx 0110 xxxx */
+ DECODE_OR (0xff80f080, 0xfa80f000),
+
+ /* SXTAH 1111 1010 0000 xxxx 1111 xxxx 1xxx xxxx */
+ /* UXTAH 1111 1010 0001 xxxx 1111 xxxx 1xxx xxxx */
+ /* SXTAB16 1111 1010 0010 xxxx 1111 xxxx 1xxx xxxx */
+ /* UXTAB16 1111 1010 0011 xxxx 1111 xxxx 1xxx xxxx */
+ /* SXTAB 1111 1010 0100 xxxx 1111 xxxx 1xxx xxxx */
+ /* UXTAB 1111 1010 0101 xxxx 1111 xxxx 1xxx xxxx */
+ DECODE_OR (0xff80f080, 0xfa00f080),
+
+ /* QADD 1111 1010 1000 xxxx 1111 xxxx 1000 xxxx */
+ /* QDADD 1111 1010 1000 xxxx 1111 xxxx 1001 xxxx */
+ /* QSUB 1111 1010 1000 xxxx 1111 xxxx 1010 xxxx */
+ /* QDSUB 1111 1010 1000 xxxx 1111 xxxx 1011 xxxx */
+ DECODE_OR (0xfff0f0c0, 0xfa80f080),
+
+ /* SEL 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
+ DECODE_OR (0xfff0f0f0, 0xfaa0f080),
+
+ /* LSL 1111 1010 000x xxxx 1111 xxxx 0000 xxxx */
+ /* LSR 1111 1010 001x xxxx 1111 xxxx 0000 xxxx */
+ /* ASR 1111 1010 010x xxxx 1111 xxxx 0000 xxxx */
+ /* ROR 1111 1010 011x xxxx 1111 xxxx 0000 xxxx */
+ DECODE_EMULATEX (0xff80f0f0, 0xfa00f000, PROBES_T32_MEDIA,
+ REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
+
+ /* CLZ 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
+ DECODE_OR (0xfff0f0f0, 0xfab0f080),
+
+ /* REV 1111 1010 1001 xxxx 1111 xxxx 1000 xxxx */
+ /* REV16 1111 1010 1001 xxxx 1111 xxxx 1001 xxxx */
+ /* RBIT 1111 1010 1001 xxxx 1111 xxxx 1010 xxxx */
+ /* REVSH 1111 1010 1001 xxxx 1111 xxxx 1011 xxxx */
+ DECODE_EMULATEX (0xfff0f0c0, 0xfa90f080, PROBES_T32_REVERSE,
+ REGS(NOSPPC, 0, NOSPPC, 0, SAMEAS16)),
+
+ /* Other unallocated instructions... */
+ DECODE_END
+};
+
+static const union decode_item t32_table_1111_1011_0[] = {
+ /* Multiply, multiply accumulate, and absolute difference */
+
+ /* ??? 1111 1011 0000 xxxx 1111 xxxx 0001 xxxx */
+ DECODE_REJECT (0xfff0f0f0, 0xfb00f010),
+ /* ??? 1111 1011 0111 xxxx 1111 xxxx 0001 xxxx */
+ DECODE_REJECT (0xfff0f0f0, 0xfb70f010),
+
+ /* SMULxy 1111 1011 0001 xxxx 1111 xxxx 00xx xxxx */
+ DECODE_OR (0xfff0f0c0, 0xfb10f000),
+ /* MUL 1111 1011 0000 xxxx 1111 xxxx 0000 xxxx */
+ /* SMUAD{X} 1111 1011 0010 xxxx 1111 xxxx 000x xxxx */
+ /* SMULWy 1111 1011 0011 xxxx 1111 xxxx 000x xxxx */
+ /* SMUSD{X} 1111 1011 0100 xxxx 1111 xxxx 000x xxxx */
+ /* SMMUL{R} 1111 1011 0101 xxxx 1111 xxxx 000x xxxx */
+ /* USAD8 1111 1011 0111 xxxx 1111 xxxx 0000 xxxx */
+ DECODE_EMULATEX (0xff80f0e0, 0xfb00f000, PROBES_T32_MUL_ADD,
+ REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
+
+ /* ??? 1111 1011 0111 xxxx xxxx xxxx 0001 xxxx */
+ DECODE_REJECT (0xfff000f0, 0xfb700010),
+
+ /* SMLAxy 1111 1011 0001 xxxx xxxx xxxx 00xx xxxx */
+ DECODE_OR (0xfff000c0, 0xfb100000),
+ /* MLA 1111 1011 0000 xxxx xxxx xxxx 0000 xxxx */
+ /* MLS 1111 1011 0000 xxxx xxxx xxxx 0001 xxxx */
+ /* SMLAD{X} 1111 1011 0010 xxxx xxxx xxxx 000x xxxx */
+ /* SMLAWy 1111 1011 0011 xxxx xxxx xxxx 000x xxxx */
+ /* SMLSD{X} 1111 1011 0100 xxxx xxxx xxxx 000x xxxx */
+ /* SMMLA{R} 1111 1011 0101 xxxx xxxx xxxx 000x xxxx */
+ /* SMMLS{R} 1111 1011 0110 xxxx xxxx xxxx 000x xxxx */
+ /* USADA8 1111 1011 0111 xxxx xxxx xxxx 0000 xxxx */
+ DECODE_EMULATEX (0xff8000c0, 0xfb000000, PROBES_T32_MUL_ADD2,
+ REGS(NOSPPC, NOSPPCX, NOSPPC, 0, NOSPPC)),
+
+ /* Other unallocated instructions... */
+ DECODE_END
+};
+
+static const union decode_item t32_table_1111_1011_1[] = {
+ /* Long multiply, long multiply accumulate, and divide */
+
+ /* UMAAL 1111 1011 1110 xxxx xxxx xxxx 0110 xxxx */
+ DECODE_OR (0xfff000f0, 0xfbe00060),
+ /* SMLALxy 1111 1011 1100 xxxx xxxx xxxx 10xx xxxx */
+ DECODE_OR (0xfff000c0, 0xfbc00080),
+ /* SMLALD{X} 1111 1011 1100 xxxx xxxx xxxx 110x xxxx */
+ /* SMLSLD{X} 1111 1011 1101 xxxx xxxx xxxx 110x xxxx */
+ DECODE_OR (0xffe000e0, 0xfbc000c0),
+ /* SMULL 1111 1011 1000 xxxx xxxx xxxx 0000 xxxx */
+ /* UMULL 1111 1011 1010 xxxx xxxx xxxx 0000 xxxx */
+ /* SMLAL 1111 1011 1100 xxxx xxxx xxxx 0000 xxxx */
+ /* UMLAL 1111 1011 1110 xxxx xxxx xxxx 0000 xxxx */
+ DECODE_EMULATEX (0xff9000f0, 0xfb800000, PROBES_T32_MUL_ADD_LONG,
+ REGS(NOSPPC, NOSPPC, NOSPPC, 0, NOSPPC)),
+
+ /* SDIV 1111 1011 1001 xxxx xxxx xxxx 1111 xxxx */
+ /* UDIV 1111 1011 1011 xxxx xxxx xxxx 1111 xxxx */
+ /* Other unallocated instructions... */
+ DECODE_END
+};
+
+const union decode_item probes_decode_thumb32_table[] = {
+
+ /*
+ * Load/store multiple instructions
+ * 1110 100x x0xx xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_TABLE (0xfe400000, 0xe8000000, t32_table_1110_100x_x0xx),
+
+ /*
+ * Load/store dual, load/store exclusive, table branch
+ * 1110 100x x1xx xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_TABLE (0xfe400000, 0xe8400000, t32_table_1110_100x_x1xx),
+
+ /*
+ * Data-processing (shifted register)
+ * 1110 101x xxxx xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_TABLE (0xfe000000, 0xea000000, t32_table_1110_101x),
+
+ /*
+ * Coprocessor instructions
+ * 1110 11xx xxxx xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_REJECT (0xfc000000, 0xec000000),
+
+ /*
+ * Data-processing (modified immediate)
+ * 1111 0x0x xxxx xxxx 0xxx xxxx xxxx xxxx
+ */
+ DECODE_TABLE (0xfa008000, 0xf0000000, t32_table_1111_0x0x___0),
+
+ /*
+ * Data-processing (plain binary immediate)
+ * 1111 0x1x xxxx xxxx 0xxx xxxx xxxx xxxx
+ */
+ DECODE_TABLE (0xfa008000, 0xf2000000, t32_table_1111_0x1x___0),
+
+ /*
+ * Branches and miscellaneous control
+ * 1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx
+ */
+ DECODE_TABLE (0xf8008000, 0xf0008000, t32_table_1111_0xxx___1),
+
+ /*
+ * Advanced SIMD element or structure load/store instructions
+ * 1111 1001 xxx0 xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_REJECT (0xff100000, 0xf9000000),
+
+ /*
+ * Memory hints
+ * 1111 100x x0x1 xxxx 1111 xxxx xxxx xxxx
+ */
+ DECODE_TABLE (0xfe50f000, 0xf810f000, t32_table_1111_100x_x0x1__1111),
+
+ /*
+ * Store single data item
+ * 1111 1000 xxx0 xxxx xxxx xxxx xxxx xxxx
+ * Load single data items
+ * 1111 100x xxx1 xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_TABLE (0xfe000000, 0xf8000000, t32_table_1111_100x),
+
+ /*
+ * Data-processing (register)
+ * 1111 1010 xxxx xxxx 1111 xxxx xxxx xxxx
+ */
+ DECODE_TABLE (0xff00f000, 0xfa00f000, t32_table_1111_1010___1111),
+
+ /*
+ * Multiply, multiply accumulate, and absolute difference
+ * 1111 1011 0xxx xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_TABLE (0xff800000, 0xfb000000, t32_table_1111_1011_0),
+
+ /*
+ * Long multiply, long multiply accumulate, and divide
+ * 1111 1011 1xxx xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_TABLE (0xff800000, 0xfb800000, t32_table_1111_1011_1),
+
+ /*
+ * Coprocessor instructions
+ * 1111 11xx xxxx xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_END
+};
+#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
+EXPORT_SYMBOL_GPL(probes_decode_thumb32_table);
+#endif
+
+static const union decode_item t16_table_1011[] = {
+ /* Miscellaneous 16-bit instructions */
+
+ /* ADD (SP plus immediate) 1011 0000 0xxx xxxx */
+ /* SUB (SP minus immediate) 1011 0000 1xxx xxxx */
+ DECODE_SIMULATE (0xff00, 0xb000, PROBES_T16_ADD_SP),
+
+ /* CBZ 1011 00x1 xxxx xxxx */
+ /* CBNZ 1011 10x1 xxxx xxxx */
+ DECODE_SIMULATE (0xf500, 0xb100, PROBES_T16_CBZ),
+
+ /* SXTH 1011 0010 00xx xxxx */
+ /* SXTB 1011 0010 01xx xxxx */
+ /* UXTH 1011 0010 10xx xxxx */
+ /* UXTB 1011 0010 11xx xxxx */
+ /* REV 1011 1010 00xx xxxx */
+ /* REV16 1011 1010 01xx xxxx */
+ /* ??? 1011 1010 10xx xxxx */
+ /* REVSH 1011 1010 11xx xxxx */
+ DECODE_REJECT (0xffc0, 0xba80),
+ DECODE_EMULATE (0xf500, 0xb000, PROBES_T16_SIGN_EXTEND),
+
+ /* PUSH 1011 010x xxxx xxxx */
+ DECODE_CUSTOM (0xfe00, 0xb400, PROBES_T16_PUSH),
+ /* POP 1011 110x xxxx xxxx */
+ DECODE_CUSTOM (0xfe00, 0xbc00, PROBES_T16_POP),
+
+ /*
+ * If-Then, and hints
+ * 1011 1111 xxxx xxxx
+ */
+
+ /* YIELD 1011 1111 0001 0000 */
+ DECODE_OR (0xffff, 0xbf10),
+ /* SEV 1011 1111 0100 0000 */
+ DECODE_EMULATE (0xffff, 0xbf40, PROBES_T16_SEV),
+ /* NOP 1011 1111 0000 0000 */
+ /* WFE 1011 1111 0010 0000 */
+ /* WFI 1011 1111 0011 0000 */
+ DECODE_SIMULATE (0xffcf, 0xbf00, PROBES_T16_WFE),
+ /* Unassigned hints 1011 1111 xxxx 0000 */
+ DECODE_REJECT (0xff0f, 0xbf00),
+ /* IT 1011 1111 xxxx xxxx */
+ DECODE_CUSTOM (0xff00, 0xbf00, PROBES_T16_IT),
+
+ /* SETEND 1011 0110 010x xxxx */
+ /* CPS 1011 0110 011x xxxx */
+ /* BKPT 1011 1110 xxxx xxxx */
+ /* And unallocated instructions... */
+ DECODE_END
+};
+
+const union decode_item probes_decode_thumb16_table[] = {
+
+ /*
+ * Shift (immediate), add, subtract, move, and compare
+ * 00xx xxxx xxxx xxxx
+ */
+
+ /* CMP (immediate) 0010 1xxx xxxx xxxx */
+ DECODE_EMULATE (0xf800, 0x2800, PROBES_T16_CMP),
+
+ /* ADD (register) 0001 100x xxxx xxxx */
+ /* SUB (register) 0001 101x xxxx xxxx */
+ /* LSL (immediate) 0000 0xxx xxxx xxxx */
+ /* LSR (immediate) 0000 1xxx xxxx xxxx */
+ /* ASR (immediate) 0001 0xxx xxxx xxxx */
+ /* ADD (immediate, Thumb) 0001 110x xxxx xxxx */
+ /* SUB (immediate, Thumb) 0001 111x xxxx xxxx */
+ /* MOV (immediate) 0010 0xxx xxxx xxxx */
+ /* ADD (immediate, Thumb) 0011 0xxx xxxx xxxx */
+ /* SUB (immediate, Thumb) 0011 1xxx xxxx xxxx */
+ DECODE_EMULATE (0xc000, 0x0000, PROBES_T16_ADDSUB),
+
+ /*
+ * 16-bit Thumb data-processing instructions
+ * 0100 00xx xxxx xxxx
+ */
+
+ /* TST (register) 0100 0010 00xx xxxx */
+ DECODE_EMULATE (0xffc0, 0x4200, PROBES_T16_CMP),
+ /* CMP (register) 0100 0010 10xx xxxx */
+ /* CMN (register) 0100 0010 11xx xxxx */
+ DECODE_EMULATE (0xff80, 0x4280, PROBES_T16_CMP),
+ /* AND (register) 0100 0000 00xx xxxx */
+ /* EOR (register) 0100 0000 01xx xxxx */
+ /* LSL (register) 0100 0000 10xx xxxx */
+ /* LSR (register) 0100 0000 11xx xxxx */
+ /* ASR (register) 0100 0001 00xx xxxx */
+ /* ADC (register) 0100 0001 01xx xxxx */
+ /* SBC (register) 0100 0001 10xx xxxx */
+ /* ROR (register) 0100 0001 11xx xxxx */
+ /* RSB (immediate) 0100 0010 01xx xxxx */
+ /* ORR (register) 0100 0011 00xx xxxx */
+ /* MUL 0100 0011 00xx xxxx */
+ /* BIC (register) 0100 0011 10xx xxxx */
+ /* MVN (register) 0100 0011 10xx xxxx */
+ DECODE_EMULATE (0xfc00, 0x4000, PROBES_T16_LOGICAL),
+
+ /*
+ * Special data instructions and branch and exchange
+ * 0100 01xx xxxx xxxx
+ */
+
+ /* BLX pc 0100 0111 1111 1xxx */
+ DECODE_REJECT (0xfff8, 0x47f8),
+
+ /* BX (register) 0100 0111 0xxx xxxx */
+ /* BLX (register) 0100 0111 1xxx xxxx */
+ DECODE_SIMULATE (0xff00, 0x4700, PROBES_T16_BLX),
+
+ /* ADD pc, pc 0100 0100 1111 1111 */
+ DECODE_REJECT (0xffff, 0x44ff),
+
+ /* ADD (register) 0100 0100 xxxx xxxx */
+ /* CMP (register) 0100 0101 xxxx xxxx */
+ /* MOV (register) 0100 0110 xxxx xxxx */
+ DECODE_CUSTOM (0xfc00, 0x4400, PROBES_T16_HIREGOPS),
+
+ /*
+ * Load from Literal Pool
+ * LDR (literal) 0100 1xxx xxxx xxxx
+ */
+ DECODE_SIMULATE (0xf800, 0x4800, PROBES_T16_LDR_LIT),
+
+ /*
+ * 16-bit Thumb Load/store instructions
+ * 0101 xxxx xxxx xxxx
+ * 011x xxxx xxxx xxxx
+ * 100x xxxx xxxx xxxx
+ */
+
+ /* STR (register) 0101 000x xxxx xxxx */
+ /* STRH (register) 0101 001x xxxx xxxx */
+ /* STRB (register) 0101 010x xxxx xxxx */
+ /* LDRSB (register) 0101 011x xxxx xxxx */
+ /* LDR (register) 0101 100x xxxx xxxx */
+ /* LDRH (register) 0101 101x xxxx xxxx */
+ /* LDRB (register) 0101 110x xxxx xxxx */
+ /* LDRSH (register) 0101 111x xxxx xxxx */
+ /* STR (immediate, Thumb) 0110 0xxx xxxx xxxx */
+ /* LDR (immediate, Thumb) 0110 1xxx xxxx xxxx */
+ /* STRB (immediate, Thumb) 0111 0xxx xxxx xxxx */
+ /* LDRB (immediate, Thumb) 0111 1xxx xxxx xxxx */
+ DECODE_EMULATE (0xc000, 0x4000, PROBES_T16_LDRHSTRH),
+ /* STRH (immediate, Thumb) 1000 0xxx xxxx xxxx */
+ /* LDRH (immediate, Thumb) 1000 1xxx xxxx xxxx */
+ DECODE_EMULATE (0xf000, 0x8000, PROBES_T16_LDRHSTRH),
+ /* STR (immediate, Thumb) 1001 0xxx xxxx xxxx */
+ /* LDR (immediate, Thumb) 1001 1xxx xxxx xxxx */
+ DECODE_SIMULATE (0xf000, 0x9000, PROBES_T16_LDRSTR),
+
+ /*
+ * Generate PC-/SP-relative address
+ * ADR (literal) 1010 0xxx xxxx xxxx
+ * ADD (SP plus immediate) 1010 1xxx xxxx xxxx
+ */
+ DECODE_SIMULATE (0xf000, 0xa000, PROBES_T16_ADR),
+
+ /*
+ * Miscellaneous 16-bit instructions
+ * 1011 xxxx xxxx xxxx
+ */
+ DECODE_TABLE (0xf000, 0xb000, t16_table_1011),
+
+ /* STM 1100 0xxx xxxx xxxx */
+ /* LDM 1100 1xxx xxxx xxxx */
+ DECODE_EMULATE (0xf000, 0xc000, PROBES_T16_LDMSTM),
+
+ /*
+ * Conditional branch, and Supervisor Call
+ */
+
+ /* Permanently UNDEFINED 1101 1110 xxxx xxxx */
+ /* SVC 1101 1111 xxxx xxxx */
+ DECODE_REJECT (0xfe00, 0xde00),
+
+ /* Conditional branch 1101 xxxx xxxx xxxx */
+ DECODE_CUSTOM (0xf000, 0xd000, PROBES_T16_BRANCH_COND),
+
+ /*
+ * Unconditional branch
+ * B 1110 0xxx xxxx xxxx
+ */
+ DECODE_SIMULATE (0xf800, 0xe000, PROBES_T16_BRANCH),
+
+ DECODE_END
+};
+#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
+EXPORT_SYMBOL_GPL(probes_decode_thumb16_table);
+#endif
+
+static unsigned long __kprobes thumb_check_cc(unsigned long cpsr)
+{
+ if (unlikely(in_it_block(cpsr)))
+ return probes_condition_checks[current_cond(cpsr)](cpsr);
+ return true;
+}
+
+static void __kprobes thumb16_singlestep(probes_opcode_t opcode,
+ struct arch_probes_insn *asi,
+ struct pt_regs *regs)
+{
+ regs->ARM_pc += 2;
+ asi->insn_handler(opcode, asi, regs);
+ regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
+}
+
+static void __kprobes thumb32_singlestep(probes_opcode_t opcode,
+ struct arch_probes_insn *asi,
+ struct pt_regs *regs)
+{
+ regs->ARM_pc += 4;
+ asi->insn_handler(opcode, asi, regs);
+ regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
+}
+
+enum probes_insn __kprobes
+thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+ bool emulate, const union decode_action *actions,
+ const struct decode_checker *checkers[])
+{
+ asi->insn_singlestep = thumb16_singlestep;
+ asi->insn_check_cc = thumb_check_cc;
+ return probes_decode_insn(insn, asi, probes_decode_thumb16_table, true,
+ emulate, actions, checkers);
+}
+
+enum probes_insn __kprobes
+thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+ bool emulate, const union decode_action *actions,
+ const struct decode_checker *checkers[])
+{
+ asi->insn_singlestep = thumb32_singlestep;
+ asi->insn_check_cc = thumb_check_cc;
+ return probes_decode_insn(insn, asi, probes_decode_thumb32_table, true,
+ emulate, actions, checkers);
+}
diff --git a/arch/arm/probes/decode-thumb.h b/arch/arm/probes/decode-thumb.h
new file mode 100644
index 000000000..8457add0a
--- /dev/null
+++ b/arch/arm/probes/decode-thumb.h
@@ -0,0 +1,101 @@
+/*
+ * arch/arm/probes/decode-thumb.h
+ *
+ * Copyright 2013 Linaro Ltd.
+ * Written by: David A. Long
+ *
+ * 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 _ARM_KERNEL_PROBES_THUMB_H
+#define _ARM_KERNEL_PROBES_THUMB_H
+
+#include "decode.h"
+
+/*
+ * True if current instruction is in an IT block.
+ */
+#define in_it_block(cpsr) ((cpsr & 0x06000c00) != 0x00000000)
+
+/*
+ * Return the condition code to check for the currently executing instruction.
+ * This is in ITSTATE<7:4> which is in CPSR<15:12> but is only valid if
+ * in_it_block returns true.
+ */
+#define current_cond(cpsr) ((cpsr >> 12) & 0xf)
+
+enum probes_t32_action {
+ PROBES_T32_EMULATE_NONE,
+ PROBES_T32_SIMULATE_NOP,
+ PROBES_T32_LDMSTM,
+ PROBES_T32_LDRDSTRD,
+ PROBES_T32_TABLE_BRANCH,
+ PROBES_T32_TST,
+ PROBES_T32_CMP,
+ PROBES_T32_MOV,
+ PROBES_T32_ADDSUB,
+ PROBES_T32_LOGICAL,
+ PROBES_T32_ADDWSUBW_PC,
+ PROBES_T32_ADDWSUBW,
+ PROBES_T32_MOVW,
+ PROBES_T32_SAT,
+ PROBES_T32_BITFIELD,
+ PROBES_T32_SEV,
+ PROBES_T32_WFE,
+ PROBES_T32_MRS,
+ PROBES_T32_BRANCH_COND,
+ PROBES_T32_BRANCH,
+ PROBES_T32_PLDI,
+ PROBES_T32_LDR_LIT,
+ PROBES_T32_LDRSTR,
+ PROBES_T32_SIGN_EXTEND,
+ PROBES_T32_MEDIA,
+ PROBES_T32_REVERSE,
+ PROBES_T32_MUL_ADD,
+ PROBES_T32_MUL_ADD2,
+ PROBES_T32_MUL_ADD_LONG,
+ NUM_PROBES_T32_ACTIONS
+};
+
+enum probes_t16_action {
+ PROBES_T16_ADD_SP,
+ PROBES_T16_CBZ,
+ PROBES_T16_SIGN_EXTEND,
+ PROBES_T16_PUSH,
+ PROBES_T16_POP,
+ PROBES_T16_SEV,
+ PROBES_T16_WFE,
+ PROBES_T16_IT,
+ PROBES_T16_CMP,
+ PROBES_T16_ADDSUB,
+ PROBES_T16_LOGICAL,
+ PROBES_T16_BLX,
+ PROBES_T16_HIREGOPS,
+ PROBES_T16_LDR_LIT,
+ PROBES_T16_LDRHSTRH,
+ PROBES_T16_LDRSTR,
+ PROBES_T16_ADR,
+ PROBES_T16_LDMSTM,
+ PROBES_T16_BRANCH_COND,
+ PROBES_T16_BRANCH,
+ NUM_PROBES_T16_ACTIONS
+};
+
+extern const union decode_item probes_decode_thumb32_table[];
+extern const union decode_item probes_decode_thumb16_table[];
+
+enum probes_insn __kprobes
+thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+ bool emulate, const union decode_action *actions,
+ const struct decode_checker *checkers[]);
+enum probes_insn __kprobes
+thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+ bool emulate, const union decode_action *actions,
+ const struct decode_checker *checkers[]);
+
+#endif
diff --git a/arch/arm/probes/decode.c b/arch/arm/probes/decode.c
new file mode 100644
index 000000000..880ebe0cd
--- /dev/null
+++ b/arch/arm/probes/decode.c
@@ -0,0 +1,521 @@
+/*
+ * arch/arm/probes/decode.c
+ *
+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
+ *
+ * Some contents moved here from arch/arm/include/asm/kprobes-arm.c which is
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <asm/system_info.h>
+#include <asm/ptrace.h>
+#include <linux/bug.h>
+
+#include "decode.h"
+
+
+#ifndef find_str_pc_offset
+
+/*
+ * 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.
+ */
+
+int str_pc_offset;
+
+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;
+}
+
+#endif /* !find_str_pc_offset */
+
+
+#ifndef test_load_write_pc_interworking
+
+bool load_write_pc_interworks;
+
+void __init test_load_write_pc_interworking(void)
+{
+ int arch = cpu_architecture();
+ BUG_ON(arch == CPU_ARCH_UNKNOWN);
+ load_write_pc_interworks = arch >= CPU_ARCH_ARMv5T;
+}
+
+#endif /* !test_load_write_pc_interworking */
+
+
+#ifndef test_alu_write_pc_interworking
+
+bool alu_write_pc_interworks;
+
+void __init test_alu_write_pc_interworking(void)
+{
+ int arch = cpu_architecture();
+ BUG_ON(arch == CPU_ARCH_UNKNOWN);
+ alu_write_pc_interworks = arch >= CPU_ARCH_ARMv7;
+}
+
+#endif /* !test_alu_write_pc_interworking */
+
+
+void __init arm_probes_decode_init(void)
+{
+ find_str_pc_offset();
+ test_load_write_pc_interworking();
+ test_alu_write_pc_interworking();
+}
+
+
+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;
+}
+
+probes_check_cc * const probes_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
+};
+
+
+void __kprobes probes_simulate_nop(probes_opcode_t opcode,
+ struct arch_probes_insn *asi,
+ struct pt_regs *regs)
+{
+}
+
+void __kprobes probes_emulate_none(probes_opcode_t opcode,
+ struct arch_probes_insn *asi,
+ struct pt_regs *regs)
+{
+ asi->insn_fn();
+}
+
+/*
+ * Prepare an instruction slot to receive an instruction for emulating.
+ * This is done by placing a subroutine return after the location where the
+ * instruction will be placed. We also modify ARM instructions to be
+ * unconditional as the condition code will already be checked before any
+ * emulation handler is called.
+ */
+static probes_opcode_t __kprobes
+prepare_emulated_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+ bool thumb)
+{
+#ifdef CONFIG_THUMB2_KERNEL
+ if (thumb) {
+ u16 *thumb_insn = (u16 *)asi->insn;
+ /* Thumb bx lr */
+ thumb_insn[1] = __opcode_to_mem_thumb16(0x4770);
+ thumb_insn[2] = __opcode_to_mem_thumb16(0x4770);
+ return insn;
+ }
+ asi->insn[1] = __opcode_to_mem_arm(0xe12fff1e); /* ARM bx lr */
+#else
+ asi->insn[1] = __opcode_to_mem_arm(0xe1a0f00e); /* mov pc, lr */
+#endif
+ /* Make an ARM instruction unconditional */
+ if (insn < 0xe0000000)
+ insn = (insn | 0xe0000000) & ~0x10000000;
+ return insn;
+}
+
+/*
+ * Write a (probably modified) instruction into the slot previously prepared by
+ * prepare_emulated_insn
+ */
+static void __kprobes
+set_emulated_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+ bool thumb)
+{
+#ifdef CONFIG_THUMB2_KERNEL
+ if (thumb) {
+ u16 *ip = (u16 *)asi->insn;
+ if (is_wide_instruction(insn))
+ *ip++ = __opcode_to_mem_thumb16(insn >> 16);
+ *ip++ = __opcode_to_mem_thumb16(insn);
+ return;
+ }
+#endif
+ asi->insn[0] = __opcode_to_mem_arm(insn);
+}
+
+/*
+ * When we modify the register numbers encoded in an instruction to be emulated,
+ * the new values come from this define. For ARM and 32-bit Thumb instructions
+ * this gives...
+ *
+ * bit position 16 12 8 4 0
+ * ---------------+---+---+---+---+---+
+ * register r2 r0 r1 -- r3
+ */
+#define INSN_NEW_BITS 0x00020103
+
+/* Each nibble has same value as that at INSN_NEW_BITS bit 16 */
+#define INSN_SAMEAS16_BITS 0x22222222
+
+/*
+ * Validate and modify each of the registers encoded in an instruction.
+ *
+ * Each nibble in regs contains a value from enum decode_reg_type. For each
+ * non-zero value, the corresponding nibble in pinsn is validated and modified
+ * according to the type.
+ */
+static bool __kprobes decode_regs(probes_opcode_t *pinsn, u32 regs, bool modify)
+{
+ probes_opcode_t insn = *pinsn;
+ probes_opcode_t mask = 0xf; /* Start at least significant nibble */
+
+ for (; regs != 0; regs >>= 4, mask <<= 4) {
+
+ probes_opcode_t new_bits = INSN_NEW_BITS;
+
+ switch (regs & 0xf) {
+
+ case REG_TYPE_NONE:
+ /* Nibble not a register, skip to next */
+ continue;
+
+ case REG_TYPE_ANY:
+ /* Any register is allowed */
+ break;
+
+ case REG_TYPE_SAMEAS16:
+ /* Replace register with same as at bit position 16 */
+ new_bits = INSN_SAMEAS16_BITS;
+ break;
+
+ case REG_TYPE_SP:
+ /* Only allow SP (R13) */
+ if ((insn ^ 0xdddddddd) & mask)
+ goto reject;
+ break;
+
+ case REG_TYPE_PC:
+ /* Only allow PC (R15) */
+ if ((insn ^ 0xffffffff) & mask)
+ goto reject;
+ break;
+
+ case REG_TYPE_NOSP:
+ /* Reject SP (R13) */
+ if (((insn ^ 0xdddddddd) & mask) == 0)
+ goto reject;
+ break;
+
+ case REG_TYPE_NOSPPC:
+ case REG_TYPE_NOSPPCX:
+ /* Reject SP and PC (R13 and R15) */
+ if (((insn ^ 0xdddddddd) & 0xdddddddd & mask) == 0)
+ goto reject;
+ break;
+
+ case REG_TYPE_NOPCWB:
+ if (!is_writeback(insn))
+ break; /* No writeback, so any register is OK */
+ /* fall through... */
+ case REG_TYPE_NOPC:
+ case REG_TYPE_NOPCX:
+ /* Reject PC (R15) */
+ if (((insn ^ 0xffffffff) & mask) == 0)
+ goto reject;
+ break;
+ }
+
+ /* Replace value of nibble with new register number... */
+ insn &= ~mask;
+ insn |= new_bits & mask;
+ }
+
+ if (modify)
+ *pinsn = insn;
+
+ return true;
+
+reject:
+ return false;
+}
+
+static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
+ [DECODE_TYPE_TABLE] = sizeof(struct decode_table),
+ [DECODE_TYPE_CUSTOM] = sizeof(struct decode_custom),
+ [DECODE_TYPE_SIMULATE] = sizeof(struct decode_simulate),
+ [DECODE_TYPE_EMULATE] = sizeof(struct decode_emulate),
+ [DECODE_TYPE_OR] = sizeof(struct decode_or),
+ [DECODE_TYPE_REJECT] = sizeof(struct decode_reject)
+};
+
+static int run_checkers(const struct decode_checker *checkers[],
+ int action, probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ const struct decode_checker **p;
+
+ if (!checkers)
+ return INSN_GOOD;
+
+ p = checkers;
+ while (*p != NULL) {
+ int retval;
+ probes_check_t *checker_func = (*p)[action].checker;
+
+ retval = INSN_GOOD;
+ if (checker_func)
+ retval = checker_func(insn, asi, h);
+ if (retval == INSN_REJECTED)
+ return retval;
+ p++;
+ }
+ return INSN_GOOD;
+}
+
+/*
+ * probes_decode_insn operates on data tables in order to decode an ARM
+ * architecture instruction onto which a kprobe has been placed.
+ *
+ * These instruction decoding tables are a concatenation of entries each
+ * of which consist of one of the following structs:
+ *
+ * decode_table
+ * decode_custom
+ * decode_simulate
+ * decode_emulate
+ * decode_or
+ * decode_reject
+ *
+ * Each of these starts with a struct decode_header which has the following
+ * fields:
+ *
+ * type_regs
+ * mask
+ * value
+ *
+ * The least significant DECODE_TYPE_BITS of type_regs contains a value
+ * from enum decode_type, this indicates which of the decode_* structs
+ * the entry contains. The value DECODE_TYPE_END indicates the end of the
+ * table.
+ *
+ * When the table is parsed, each entry is checked in turn to see if it
+ * matches the instruction to be decoded using the test:
+ *
+ * (insn & mask) == value
+ *
+ * If no match is found before the end of the table is reached then decoding
+ * fails with INSN_REJECTED.
+ *
+ * When a match is found, decode_regs() is called to validate and modify each
+ * of the registers encoded in the instruction; the data it uses to do this
+ * is (type_regs >> DECODE_TYPE_BITS). A validation failure will cause decoding
+ * to fail with INSN_REJECTED.
+ *
+ * Once the instruction has passed the above tests, further processing
+ * depends on the type of the table entry's decode struct.
+ *
+ */
+int __kprobes
+probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+ const union decode_item *table, bool thumb,
+ bool emulate, const union decode_action *actions,
+ const struct decode_checker *checkers[])
+{
+ const struct decode_header *h = (struct decode_header *)table;
+ const struct decode_header *next;
+ bool matched = false;
+ /*
+ * @insn can be modified by decode_regs. Save its original
+ * value for checkers.
+ */
+ probes_opcode_t origin_insn = insn;
+
+ /*
+ * stack_space is initialized to 0 here. Checker functions
+ * should update is value if they find this is a stack store
+ * instruction: positive value means bytes of stack usage,
+ * negitive value means unable to determine stack usage
+ * statically. For instruction doesn't store to stack, checker
+ * do nothing with it.
+ */
+ asi->stack_space = 0;
+
+ /*
+ * Similarly to stack_space, register_usage_flags is filled by
+ * checkers. Its default value is set to ~0, which is 'all
+ * registers are used', to prevent any potential optimization.
+ */
+ asi->register_usage_flags = ~0UL;
+
+ if (emulate)
+ insn = prepare_emulated_insn(insn, asi, thumb);
+
+ for (;; h = next) {
+ enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK;
+ u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS;
+
+ if (type == DECODE_TYPE_END)
+ return INSN_REJECTED;
+
+ next = (struct decode_header *)
+ ((uintptr_t)h + decode_struct_sizes[type]);
+
+ if (!matched && (insn & h->mask.bits) != h->value.bits)
+ continue;
+
+ if (!decode_regs(&insn, regs, emulate))
+ return INSN_REJECTED;
+
+ switch (type) {
+
+ case DECODE_TYPE_TABLE: {
+ struct decode_table *d = (struct decode_table *)h;
+ next = (struct decode_header *)d->table.table;
+ break;
+ }
+
+ case DECODE_TYPE_CUSTOM: {
+ int err;
+ struct decode_custom *d = (struct decode_custom *)h;
+ int action = d->decoder.action;
+
+ err = run_checkers(checkers, action, origin_insn, asi, h);
+ if (err == INSN_REJECTED)
+ return INSN_REJECTED;
+ return actions[action].decoder(insn, asi, h);
+ }
+
+ case DECODE_TYPE_SIMULATE: {
+ int err;
+ struct decode_simulate *d = (struct decode_simulate *)h;
+ int action = d->handler.action;
+
+ err = run_checkers(checkers, action, origin_insn, asi, h);
+ if (err == INSN_REJECTED)
+ return INSN_REJECTED;
+ asi->insn_handler = actions[action].handler;
+ return INSN_GOOD_NO_SLOT;
+ }
+
+ case DECODE_TYPE_EMULATE: {
+ int err;
+ struct decode_emulate *d = (struct decode_emulate *)h;
+ int action = d->handler.action;
+
+ err = run_checkers(checkers, action, origin_insn, asi, h);
+ if (err == INSN_REJECTED)
+ return INSN_REJECTED;
+
+ if (!emulate)
+ return actions[action].decoder(insn, asi, h);
+
+ asi->insn_handler = actions[action].handler;
+ set_emulated_insn(insn, asi, thumb);
+ return INSN_GOOD;
+ }
+
+ case DECODE_TYPE_OR:
+ matched = true;
+ break;
+
+ case DECODE_TYPE_REJECT:
+ default:
+ return INSN_REJECTED;
+ }
+ }
+}
diff --git a/arch/arm/probes/decode.h b/arch/arm/probes/decode.h
new file mode 100644
index 000000000..f9b08ba7f
--- /dev/null
+++ b/arch/arm/probes/decode.h
@@ -0,0 +1,416 @@
+/*
+ * arch/arm/probes/decode.h
+ *
+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
+ *
+ * Some contents moved here from arch/arm/include/asm/kprobes.h which is
+ * 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_KERNEL_PROBES_H
+#define _ARM_KERNEL_PROBES_H
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <asm/probes.h>
+
+void __init arm_probes_decode_init(void);
+
+extern probes_check_cc * const probes_condition_checks[16];
+
+#if __LINUX_ARM_ARCH__ >= 7
+
+/* str_pc_offset is architecturally defined from ARMv7 onwards */
+#define str_pc_offset 8
+#define find_str_pc_offset()
+
+#else /* __LINUX_ARM_ARCH__ < 7 */
+
+/* We need a run-time check to determine str_pc_offset */
+extern int str_pc_offset;
+void __init find_str_pc_offset(void);
+
+#endif
+
+
+/*
+ * Update ITSTATE after normal execution of an IT block instruction.
+ *
+ * The 8 IT state bits are split into two parts in CPSR:
+ * ITSTATE<1:0> are in CPSR<26:25>
+ * ITSTATE<7:2> are in CPSR<15:10>
+ */
+static inline unsigned long it_advance(unsigned long cpsr)
+ {
+ if ((cpsr & 0x06000400) == 0) {
+ /* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */
+ cpsr &= ~PSR_IT_MASK;
+ } else {
+ /* We need to shift left ITSTATE<4:0> */
+ const unsigned long mask = 0x06001c00; /* Mask ITSTATE<4:0> */
+ unsigned long it = cpsr & mask;
+ it <<= 1;
+ it |= it >> (27 - 10); /* Carry ITSTATE<2> to correct place */
+ it &= mask;
+ cpsr &= ~mask;
+ cpsr |= it;
+ }
+ return cpsr;
+}
+
+static inline void __kprobes bx_write_pc(long pcv, struct pt_regs *regs)
+{
+ long cpsr = regs->ARM_cpsr;
+ if (pcv & 0x1) {
+ cpsr |= PSR_T_BIT;
+ pcv &= ~0x1;
+ } else {
+ cpsr &= ~PSR_T_BIT;
+ pcv &= ~0x2; /* Avoid UNPREDICTABLE address allignment */
+ }
+ regs->ARM_cpsr = cpsr;
+ regs->ARM_pc = pcv;
+}
+
+
+#if __LINUX_ARM_ARCH__ >= 6
+
+/* Kernels built for >= ARMv6 should never run on <= ARMv5 hardware, so... */
+#define load_write_pc_interworks true
+#define test_load_write_pc_interworking()
+
+#else /* __LINUX_ARM_ARCH__ < 6 */
+
+/* We need run-time testing to determine if load_write_pc() should interwork. */
+extern bool load_write_pc_interworks;
+void __init test_load_write_pc_interworking(void);
+
+#endif
+
+static inline void __kprobes load_write_pc(long pcv, struct pt_regs *regs)
+{
+ if (load_write_pc_interworks)
+ bx_write_pc(pcv, regs);
+ else
+ regs->ARM_pc = pcv;
+}
+
+
+#if __LINUX_ARM_ARCH__ >= 7
+
+#define alu_write_pc_interworks true
+#define test_alu_write_pc_interworking()
+
+#elif __LINUX_ARM_ARCH__ <= 5
+
+/* Kernels built for <= ARMv5 should never run on >= ARMv6 hardware, so... */
+#define alu_write_pc_interworks false
+#define test_alu_write_pc_interworking()
+
+#else /* __LINUX_ARM_ARCH__ == 6 */
+
+/* We could be an ARMv6 binary on ARMv7 hardware so we need a run-time check. */
+extern bool alu_write_pc_interworks;
+void __init test_alu_write_pc_interworking(void);
+
+#endif /* __LINUX_ARM_ARCH__ == 6 */
+
+static inline void __kprobes alu_write_pc(long pcv, struct pt_regs *regs)
+{
+ if (alu_write_pc_interworks)
+ bx_write_pc(pcv, regs);
+ else
+ regs->ARM_pc = pcv;
+}
+
+
+/*
+ * 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)
+
+/*
+ * The following definitions and macros are used to build instruction
+ * decoding tables for use by probes_decode_insn.
+ *
+ * These tables are a concatenation of entries each of which consist of one of
+ * the decode_* structs. All of the fields in every type of decode structure
+ * are of the union type decode_item, therefore the entire decode table can be
+ * viewed as an array of these and declared like:
+ *
+ * static const union decode_item table_name[] = {};
+ *
+ * In order to construct each entry in the table, macros are used to
+ * initialise a number of sequential decode_item values in a layout which
+ * matches the relevant struct. E.g. DECODE_SIMULATE initialise a struct
+ * decode_simulate by initialising four decode_item objects like this...
+ *
+ * {.bits = _type},
+ * {.bits = _mask},
+ * {.bits = _value},
+ * {.action = _handler},
+ *
+ * Initialising a specified member of the union means that the compiler
+ * will produce a warning if the argument is of an incorrect type.
+ *
+ * Below is a list of each of the macros used to initialise entries and a
+ * description of the action performed when that entry is matched to an
+ * instruction. A match is found when (instruction & mask) == value.
+ *
+ * DECODE_TABLE(mask, value, table)
+ * Instruction decoding jumps to parsing the new sub-table 'table'.
+ *
+ * DECODE_CUSTOM(mask, value, decoder)
+ * The value of 'decoder' is used as an index into the array of
+ * action functions, and the retrieved decoder function is invoked
+ * to complete decoding of the instruction.
+ *
+ * DECODE_SIMULATE(mask, value, handler)
+ * The probes instruction handler is set to the value found by
+ * indexing into the action array using the value of 'handler'. This
+ * will be used to simulate the instruction when the probe is hit.
+ * Decoding returns with INSN_GOOD_NO_SLOT.
+ *
+ * DECODE_EMULATE(mask, value, handler)
+ * The probes instruction handler is set to the value found by
+ * indexing into the action array using the value of 'handler'. This
+ * will be used to emulate the instruction when the probe is hit. The
+ * modified instruction (see below) is placed in the probes instruction
+ * slot so it may be called by the emulation code. Decoding returns
+ * with INSN_GOOD.
+ *
+ * DECODE_REJECT(mask, value)
+ * Instruction decoding fails with INSN_REJECTED
+ *
+ * DECODE_OR(mask, value)
+ * This allows the mask/value test of multiple table entries to be
+ * logically ORed. Once an 'or' entry is matched the decoding action to
+ * be performed is that of the next entry which isn't an 'or'. E.g.
+ *
+ * DECODE_OR (mask1, value1)
+ * DECODE_OR (mask2, value2)
+ * DECODE_SIMULATE (mask3, value3, simulation_handler)
+ *
+ * This means that if any of the three mask/value pairs match the
+ * instruction being decoded, then 'simulation_handler' will be used
+ * for it.
+ *
+ * Both the SIMULATE and EMULATE macros have a second form which take an
+ * additional 'regs' argument.
+ *
+ * DECODE_SIMULATEX(mask, value, handler, regs)
+ * DECODE_EMULATEX (mask, value, handler, regs)
+ *
+ * These are used to specify what kind of CPU register is encoded in each of the
+ * least significant 5 nibbles of the instruction being decoded. The regs value
+ * is specified using the REGS macro, this takes any of the REG_TYPE_* values
+ * from enum decode_reg_type as arguments; only the '*' part of the name is
+ * given. E.g.
+ *
+ * REGS(0, ANY, NOPC, 0, ANY)
+ *
+ * This indicates an instruction is encoded like:
+ *
+ * bits 19..16 ignore
+ * bits 15..12 any register allowed here
+ * bits 11.. 8 any register except PC allowed here
+ * bits 7.. 4 ignore
+ * bits 3.. 0 any register allowed here
+ *
+ * This register specification is checked after a decode table entry is found to
+ * match an instruction (through the mask/value test). Any invalid register then
+ * found in the instruction will cause decoding to fail with INSN_REJECTED. In
+ * the above example this would happen if bits 11..8 of the instruction were
+ * 1111, indicating R15 or PC.
+ *
+ * As well as checking for legal combinations of registers, this data is also
+ * used to modify the registers encoded in the instructions so that an
+ * emulation routines can use it. (See decode_regs() and INSN_NEW_BITS.)
+ *
+ * Here is a real example which matches ARM instructions of the form
+ * "AND <Rd>,<Rn>,<Rm>,<shift> <Rs>"
+ *
+ * DECODE_EMULATEX (0x0e000090, 0x00000010, PROBES_DATA_PROCESSING_REG,
+ * REGS(ANY, ANY, NOPC, 0, ANY)),
+ * ^ ^ ^ ^
+ * Rn Rd Rs Rm
+ *
+ * Decoding the instruction "AND R4, R5, R6, ASL R15" will be rejected because
+ * Rs == R15
+ *
+ * Decoding the instruction "AND R4, R5, R6, ASL R7" will be accepted and the
+ * instruction will be modified to "AND R0, R2, R3, ASL R1" and then placed into
+ * the kprobes instruction slot. This can then be called later by the handler
+ * function emulate_rd12rn16rm0rs8_rwflags (a pointer to which is retrieved from
+ * the indicated slot in the action array), in order to simulate the instruction.
+ */
+
+enum decode_type {
+ DECODE_TYPE_END,
+ DECODE_TYPE_TABLE,
+ DECODE_TYPE_CUSTOM,
+ DECODE_TYPE_SIMULATE,
+ DECODE_TYPE_EMULATE,
+ DECODE_TYPE_OR,
+ DECODE_TYPE_REJECT,
+ NUM_DECODE_TYPES /* Must be last enum */
+};
+
+#define DECODE_TYPE_BITS 4
+#define DECODE_TYPE_MASK ((1 << DECODE_TYPE_BITS) - 1)
+
+enum decode_reg_type {
+ REG_TYPE_NONE = 0, /* Not a register, ignore */
+ REG_TYPE_ANY, /* Any register allowed */
+ REG_TYPE_SAMEAS16, /* Register should be same as that at bits 19..16 */
+ REG_TYPE_SP, /* Register must be SP */
+ REG_TYPE_PC, /* Register must be PC */
+ REG_TYPE_NOSP, /* Register must not be SP */
+ REG_TYPE_NOSPPC, /* Register must not be SP or PC */
+ REG_TYPE_NOPC, /* Register must not be PC */
+ REG_TYPE_NOPCWB, /* No PC if load/store write-back flag also set */
+
+ /* The following types are used when the encoding for PC indicates
+ * another instruction form. This distiction only matters for test
+ * case coverage checks.
+ */
+ REG_TYPE_NOPCX, /* Register must not be PC */
+ REG_TYPE_NOSPPCX, /* Register must not be SP or PC */
+
+ /* Alias to allow '0' arg to be used in REGS macro. */
+ REG_TYPE_0 = REG_TYPE_NONE
+};
+
+#define REGS(r16, r12, r8, r4, r0) \
+ (((REG_TYPE_##r16) << 16) + \
+ ((REG_TYPE_##r12) << 12) + \
+ ((REG_TYPE_##r8) << 8) + \
+ ((REG_TYPE_##r4) << 4) + \
+ (REG_TYPE_##r0))
+
+union decode_item {
+ u32 bits;
+ const union decode_item *table;
+ int action;
+};
+
+struct decode_header;
+typedef enum probes_insn (probes_custom_decode_t)(probes_opcode_t,
+ struct arch_probes_insn *,
+ const struct decode_header *);
+
+union decode_action {
+ probes_insn_handler_t *handler;
+ probes_custom_decode_t *decoder;
+};
+
+typedef enum probes_insn (probes_check_t)(probes_opcode_t,
+ struct arch_probes_insn *,
+ const struct decode_header *);
+
+struct decode_checker {
+ probes_check_t *checker;
+};
+
+#define DECODE_END \
+ {.bits = DECODE_TYPE_END}
+
+
+struct decode_header {
+ union decode_item type_regs;
+ union decode_item mask;
+ union decode_item value;
+};
+
+#define DECODE_HEADER(_type, _mask, _value, _regs) \
+ {.bits = (_type) | ((_regs) << DECODE_TYPE_BITS)}, \
+ {.bits = (_mask)}, \
+ {.bits = (_value)}
+
+
+struct decode_table {
+ struct decode_header header;
+ union decode_item table;
+};
+
+#define DECODE_TABLE(_mask, _value, _table) \
+ DECODE_HEADER(DECODE_TYPE_TABLE, _mask, _value, 0), \
+ {.table = (_table)}
+
+
+struct decode_custom {
+ struct decode_header header;
+ union decode_item decoder;
+};
+
+#define DECODE_CUSTOM(_mask, _value, _decoder) \
+ DECODE_HEADER(DECODE_TYPE_CUSTOM, _mask, _value, 0), \
+ {.action = (_decoder)}
+
+
+struct decode_simulate {
+ struct decode_header header;
+ union decode_item handler;
+};
+
+#define DECODE_SIMULATEX(_mask, _value, _handler, _regs) \
+ DECODE_HEADER(DECODE_TYPE_SIMULATE, _mask, _value, _regs), \
+ {.action = (_handler)}
+
+#define DECODE_SIMULATE(_mask, _value, _handler) \
+ DECODE_SIMULATEX(_mask, _value, _handler, 0)
+
+
+struct decode_emulate {
+ struct decode_header header;
+ union decode_item handler;
+};
+
+#define DECODE_EMULATEX(_mask, _value, _handler, _regs) \
+ DECODE_HEADER(DECODE_TYPE_EMULATE, _mask, _value, _regs), \
+ {.action = (_handler)}
+
+#define DECODE_EMULATE(_mask, _value, _handler) \
+ DECODE_EMULATEX(_mask, _value, _handler, 0)
+
+
+struct decode_or {
+ struct decode_header header;
+};
+
+#define DECODE_OR(_mask, _value) \
+ DECODE_HEADER(DECODE_TYPE_OR, _mask, _value, 0)
+
+enum probes_insn {
+ INSN_REJECTED,
+ INSN_GOOD,
+ INSN_GOOD_NO_SLOT
+};
+
+struct decode_reject {
+ struct decode_header header;
+};
+
+#define DECODE_REJECT(_mask, _value) \
+ DECODE_HEADER(DECODE_TYPE_REJECT, _mask, _value, 0)
+
+probes_insn_handler_t probes_simulate_nop;
+probes_insn_handler_t probes_emulate_none;
+
+int __kprobes
+probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+ const union decode_item *table, bool thumb, bool emulate,
+ const union decode_action *actions,
+ const struct decode_checker **checkers);
+
+#endif
diff --git a/arch/arm/probes/kprobes/Makefile b/arch/arm/probes/kprobes/Makefile
new file mode 100644
index 000000000..76a36bf10
--- /dev/null
+++ b/arch/arm/probes/kprobes/Makefile
@@ -0,0 +1,12 @@
+obj-$(CONFIG_KPROBES) += core.o actions-common.o checkers-common.o
+obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o
+test-kprobes-objs := test-core.o
+
+ifdef CONFIG_THUMB2_KERNEL
+obj-$(CONFIG_KPROBES) += actions-thumb.o checkers-thumb.o
+test-kprobes-objs += test-thumb.o
+else
+obj-$(CONFIG_KPROBES) += actions-arm.o checkers-arm.o
+obj-$(CONFIG_OPTPROBES) += opt-arm.o
+test-kprobes-objs += test-arm.o
+endif
diff --git a/arch/arm/probes/kprobes/actions-arm.c b/arch/arm/probes/kprobes/actions-arm.c
new file mode 100644
index 000000000..b9056d649
--- /dev/null
+++ b/arch/arm/probes/kprobes/actions-arm.c
@@ -0,0 +1,344 @@
+/*
+ * arch/arm/probes/kprobes/actions-arm.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>
+#include <linux/ptrace.h>
+
+#include "../decode-arm.h"
+#include "core.h"
+#include "checkers.h"
+
+#if __LINUX_ARM_ARCH__ >= 6
+#define BLX(reg) "blx "reg" \n\t"
+#else
+#define BLX(reg) "mov lr, pc \n\t" \
+ "mov pc, "reg" \n\t"
+#endif
+
+static void __kprobes
+emulate_ldrdstrd(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long pc = regs->ARM_pc + 4;
+ int rt = (insn >> 12) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+ int rm = insn & 0xf;
+
+ register unsigned long rtv asm("r0") = regs->uregs[rt];
+ register unsigned long rt2v asm("r1") = regs->uregs[rt+1];
+ register unsigned long rnv asm("r2") = (rn == 15) ? pc
+ : regs->uregs[rn];
+ register unsigned long rmv asm("r3") = regs->uregs[rm];
+
+ __asm__ __volatile__ (
+ BLX("%[fn]")
+ : "=r" (rtv), "=r" (rt2v), "=r" (rnv)
+ : "0" (rtv), "1" (rt2v), "2" (rnv), "r" (rmv),
+ [fn] "r" (asi->insn_fn)
+ : "lr", "memory", "cc"
+ );
+
+ regs->uregs[rt] = rtv;
+ regs->uregs[rt+1] = rt2v;
+ if (is_writeback(insn))
+ regs->uregs[rn] = rnv;
+}
+
+static void __kprobes
+emulate_ldr(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long pc = regs->ARM_pc + 4;
+ int rt = (insn >> 12) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+ int rm = insn & 0xf;
+
+ register unsigned long rtv asm("r0");
+ register unsigned long rnv asm("r2") = (rn == 15) ? pc
+ : regs->uregs[rn];
+ register unsigned long rmv asm("r3") = regs->uregs[rm];
+
+ __asm__ __volatile__ (
+ BLX("%[fn]")
+ : "=r" (rtv), "=r" (rnv)
+ : "1" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
+ : "lr", "memory", "cc"
+ );
+
+ if (rt == 15)
+ load_write_pc(rtv, regs);
+ else
+ regs->uregs[rt] = rtv;
+
+ if (is_writeback(insn))
+ regs->uregs[rn] = rnv;
+}
+
+static void __kprobes
+emulate_str(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long rtpc = regs->ARM_pc - 4 + str_pc_offset;
+ unsigned long rnpc = regs->ARM_pc + 4;
+ int rt = (insn >> 12) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+ int rm = insn & 0xf;
+
+ register unsigned long rtv asm("r0") = (rt == 15) ? rtpc
+ : regs->uregs[rt];
+ register unsigned long rnv asm("r2") = (rn == 15) ? rnpc
+ : regs->uregs[rn];
+ register unsigned long rmv asm("r3") = regs->uregs[rm];
+
+ __asm__ __volatile__ (
+ BLX("%[fn]")
+ : "=r" (rnv)
+ : "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
+ : "lr", "memory", "cc"
+ );
+
+ if (is_writeback(insn))
+ regs->uregs[rn] = rnv;
+}
+
+static void __kprobes
+emulate_rd12rn16rm0rs8_rwflags(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long pc = regs->ARM_pc + 4;
+ int rd = (insn >> 12) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+ int rm = insn & 0xf;
+ int rs = (insn >> 8) & 0xf;
+
+ register unsigned long rdv asm("r0") = regs->uregs[rd];
+ register unsigned long rnv asm("r2") = (rn == 15) ? pc
+ : regs->uregs[rn];
+ register unsigned long rmv asm("r3") = (rm == 15) ? pc
+ : regs->uregs[rm];
+ register unsigned long rsv asm("r1") = regs->uregs[rs];
+ unsigned long cpsr = regs->ARM_cpsr;
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[cpsr] \n\t"
+ BLX("%[fn]")
+ "mrs %[cpsr], cpsr \n\t"
+ : "=r" (rdv), [cpsr] "=r" (cpsr)
+ : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
+ "1" (cpsr), [fn] "r" (asi->insn_fn)
+ : "lr", "memory", "cc"
+ );
+
+ if (rd == 15)
+ alu_write_pc(rdv, regs);
+ else
+ regs->uregs[rd] = rdv;
+ regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
+}
+
+static void __kprobes
+emulate_rd12rn16rm0_rwflags_nopc(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ int rd = (insn >> 12) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+ int rm = insn & 0xf;
+
+ register unsigned long rdv asm("r0") = regs->uregs[rd];
+ register unsigned long rnv asm("r2") = regs->uregs[rn];
+ register unsigned long rmv asm("r3") = regs->uregs[rm];
+ unsigned long cpsr = regs->ARM_cpsr;
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[cpsr] \n\t"
+ BLX("%[fn]")
+ "mrs %[cpsr], cpsr \n\t"
+ : "=r" (rdv), [cpsr] "=r" (cpsr)
+ : "0" (rdv), "r" (rnv), "r" (rmv),
+ "1" (cpsr), [fn] "r" (asi->insn_fn)
+ : "lr", "memory", "cc"
+ );
+
+ regs->uregs[rd] = rdv;
+ regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
+}
+
+static void __kprobes
+emulate_rd16rn12rm0rs8_rwflags_nopc(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ struct pt_regs *regs)
+{
+ int rd = (insn >> 16) & 0xf;
+ int rn = (insn >> 12) & 0xf;
+ int rm = insn & 0xf;
+ int rs = (insn >> 8) & 0xf;
+
+ register unsigned long rdv asm("r2") = regs->uregs[rd];
+ register unsigned long rnv asm("r0") = regs->uregs[rn];
+ register unsigned long rmv asm("r3") = regs->uregs[rm];
+ register unsigned long rsv asm("r1") = regs->uregs[rs];
+ unsigned long cpsr = regs->ARM_cpsr;
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[cpsr] \n\t"
+ BLX("%[fn]")
+ "mrs %[cpsr], cpsr \n\t"
+ : "=r" (rdv), [cpsr] "=r" (cpsr)
+ : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
+ "1" (cpsr), [fn] "r" (asi->insn_fn)
+ : "lr", "memory", "cc"
+ );
+
+ regs->uregs[rd] = rdv;
+ regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
+}
+
+static void __kprobes
+emulate_rd12rm0_noflags_nopc(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ int rd = (insn >> 12) & 0xf;
+ int rm = insn & 0xf;
+
+ register unsigned long rdv asm("r0") = regs->uregs[rd];
+ register unsigned long rmv asm("r3") = regs->uregs[rm];
+
+ __asm__ __volatile__ (
+ BLX("%[fn]")
+ : "=r" (rdv)
+ : "0" (rdv), "r" (rmv), [fn] "r" (asi->insn_fn)
+ : "lr", "memory", "cc"
+ );
+
+ regs->uregs[rd] = rdv;
+}
+
+static void __kprobes
+emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ struct pt_regs *regs)
+{
+ int rdlo = (insn >> 12) & 0xf;
+ int rdhi = (insn >> 16) & 0xf;
+ int rn = insn & 0xf;
+ int rm = (insn >> 8) & 0xf;
+
+ register unsigned long rdlov asm("r0") = regs->uregs[rdlo];
+ register unsigned long rdhiv asm("r2") = regs->uregs[rdhi];
+ register unsigned long rnv asm("r3") = regs->uregs[rn];
+ register unsigned long rmv asm("r1") = regs->uregs[rm];
+ unsigned long cpsr = regs->ARM_cpsr;
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[cpsr] \n\t"
+ BLX("%[fn]")
+ "mrs %[cpsr], cpsr \n\t"
+ : "=r" (rdlov), "=r" (rdhiv), [cpsr] "=r" (cpsr)
+ : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv),
+ "2" (cpsr), [fn] "r" (asi->insn_fn)
+ : "lr", "memory", "cc"
+ );
+
+ regs->uregs[rdlo] = rdlov;
+ regs->uregs[rdhi] = rdhiv;
+ regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
+}
+
+const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = {
+ [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop},
+ [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
+ [PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
+ [PROBES_MRS] = {.handler = simulate_mrs},
+ [PROBES_BRANCH_REG] = {.handler = simulate_blx2bx},
+ [PROBES_CLZ] = {.handler = emulate_rd12rm0_noflags_nopc},
+ [PROBES_SATURATING_ARITHMETIC] = {
+ .handler = emulate_rd12rn16rm0_rwflags_nopc},
+ [PROBES_MUL1] = {.handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
+ [PROBES_MUL2] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
+ [PROBES_SWP] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
+ [PROBES_LDRSTRD] = {.handler = emulate_ldrdstrd},
+ [PROBES_LOAD_EXTRA] = {.handler = emulate_ldr},
+ [PROBES_LOAD] = {.handler = emulate_ldr},
+ [PROBES_STORE_EXTRA] = {.handler = emulate_str},
+ [PROBES_STORE] = {.handler = emulate_str},
+ [PROBES_MOV_IP_SP] = {.handler = simulate_mov_ipsp},
+ [PROBES_DATA_PROCESSING_REG] = {
+ .handler = emulate_rd12rn16rm0rs8_rwflags},
+ [PROBES_DATA_PROCESSING_IMM] = {
+ .handler = emulate_rd12rn16rm0rs8_rwflags},
+ [PROBES_MOV_HALFWORD] = {.handler = emulate_rd12rm0_noflags_nopc},
+ [PROBES_SEV] = {.handler = probes_emulate_none},
+ [PROBES_WFE] = {.handler = probes_simulate_nop},
+ [PROBES_SATURATE] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
+ [PROBES_REV] = {.handler = emulate_rd12rm0_noflags_nopc},
+ [PROBES_MMI] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
+ [PROBES_PACK] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
+ [PROBES_EXTEND] = {.handler = emulate_rd12rm0_noflags_nopc},
+ [PROBES_EXTEND_ADD] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
+ [PROBES_MUL_ADD_LONG] = {
+ .handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
+ [PROBES_MUL_ADD] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
+ [PROBES_BITFIELD] = {.handler = emulate_rd12rm0_noflags_nopc},
+ [PROBES_BRANCH] = {.handler = simulate_bbl},
+ [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm}
+};
+
+const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker, arm_regs_checker, NULL};
diff --git a/arch/arm/probes/kprobes/actions-common.c b/arch/arm/probes/kprobes/actions-common.c
new file mode 100644
index 000000000..bd20a71cd
--- /dev/null
+++ b/arch/arm/probes/kprobes/actions-common.c
@@ -0,0 +1,171 @@
+/*
+ * arch/arm/probes/kprobes/actions-common.c
+ *
+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
+ *
+ * Some contents moved here from arch/arm/include/asm/kprobes-arm.c which is
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/kprobes.h>
+#include <asm/opcodes.h>
+
+#include "core.h"
+
+
+static void __kprobes simulate_ldm1stm1(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ struct pt_regs *regs)
+{
+ 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(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ struct pt_regs *regs)
+{
+ unsigned long addr = regs->ARM_pc - 4;
+
+ regs->ARM_pc = (long)addr + str_pc_offset;
+ simulate_ldm1stm1(insn, asi, regs);
+ regs->ARM_pc = (long)addr + 4;
+}
+
+static void __kprobes simulate_ldm1_pc(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ struct pt_regs *regs)
+{
+ simulate_ldm1stm1(insn, asi, regs);
+ load_write_pc(regs->ARM_pc, regs);
+}
+
+static void __kprobes
+emulate_generic_r0_12_noflags(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ register void *rregs asm("r1") = regs;
+ register void *rfn asm("lr") = asi->insn_fn;
+
+ __asm__ __volatile__ (
+ "stmdb sp!, {%[regs], r11} \n\t"
+ "ldmia %[regs], {r0-r12} \n\t"
+#if __LINUX_ARM_ARCH__ >= 6
+ "blx %[fn] \n\t"
+#else
+ "str %[fn], [sp, #-4]! \n\t"
+ "adr lr, 1f \n\t"
+ "ldr pc, [sp], #4 \n\t"
+ "1: \n\t"
+#endif
+ "ldr lr, [sp], #4 \n\t" /* lr = regs */
+ "stmia lr, {r0-r12} \n\t"
+ "ldr r11, [sp], #4 \n\t"
+ : [regs] "=r" (rregs), [fn] "=r" (rfn)
+ : "0" (rregs), "1" (rfn)
+ : "r0", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r12", "memory", "cc"
+ );
+}
+
+static void __kprobes
+emulate_generic_r2_14_noflags(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ emulate_generic_r0_12_noflags(insn, asi,
+ (struct pt_regs *)(regs->uregs+2));
+}
+
+static void __kprobes
+emulate_ldm_r3_15(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ emulate_generic_r0_12_noflags(insn, asi,
+ (struct pt_regs *)(regs->uregs+3));
+ load_write_pc(regs->ARM_pc, regs);
+}
+
+enum probes_insn __kprobes
+kprobe_decode_ldmstm(probes_opcode_t insn, struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ probes_insn_handler_t *handler = 0;
+ unsigned reglist = insn & 0xffff;
+ int is_ldm = insn & 0x100000;
+ int rn = (insn >> 16) & 0xf;
+
+ if (rn <= 12 && (reglist & 0xe000) == 0) {
+ /* Instruction only uses registers in the range R0..R12 */
+ handler = emulate_generic_r0_12_noflags;
+
+ } else if (rn >= 2 && (reglist & 0x8003) == 0) {
+ /* Instruction only uses registers in the range R2..R14 */
+ rn -= 2;
+ reglist >>= 2;
+ handler = emulate_generic_r2_14_noflags;
+
+ } else if (rn >= 3 && (reglist & 0x0007) == 0) {
+ /* Instruction only uses registers in the range R3..R15 */
+ if (is_ldm && (reglist & 0x8000)) {
+ rn -= 3;
+ reglist >>= 3;
+ handler = emulate_ldm_r3_15;
+ }
+ }
+
+ if (handler) {
+ /* We can emulate the instruction in (possibly) modified form */
+ asi->insn[0] = __opcode_to_mem_arm((insn & 0xfff00000) |
+ (rn << 16) | reglist);
+ asi->insn_handler = handler;
+ return INSN_GOOD;
+ }
+
+ /* Fallback to slower simulation... */
+ if (reglist & 0x8000)
+ handler = is_ldm ? simulate_ldm1_pc : simulate_stm1_pc;
+ else
+ handler = simulate_ldm1stm1;
+ asi->insn_handler = handler;
+ return INSN_GOOD_NO_SLOT;
+}
+
diff --git a/arch/arm/probes/kprobes/actions-thumb.c b/arch/arm/probes/kprobes/actions-thumb.c
new file mode 100644
index 000000000..07cfd9bef
--- /dev/null
+++ b/arch/arm/probes/kprobes/actions-thumb.c
@@ -0,0 +1,670 @@
+/*
+ * arch/arm/probes/kprobes/actions-thumb.c
+ *
+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.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/types.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+#include <linux/kprobes.h>
+
+#include "../decode-thumb.h"
+#include "core.h"
+#include "checkers.h"
+
+/* These emulation encodings are functionally equivalent... */
+#define t32_emulate_rd8rn16rm0ra12_noflags \
+ t32_emulate_rdlo12rdhi8rn16rm0_noflags
+
+/* t32 thumb actions */
+
+static void __kprobes
+t32_simulate_table_branch(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long pc = regs->ARM_pc;
+ int rn = (insn >> 16) & 0xf;
+ int rm = insn & 0xf;
+
+ unsigned long rnv = (rn == 15) ? pc : regs->uregs[rn];
+ unsigned long rmv = regs->uregs[rm];
+ unsigned int halfwords;
+
+ if (insn & 0x10) /* TBH */
+ halfwords = ((u16 *)rnv)[rmv];
+ else /* TBB */
+ halfwords = ((u8 *)rnv)[rmv];
+
+ regs->ARM_pc = pc + 2 * halfwords;
+}
+
+static void __kprobes
+t32_simulate_mrs(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ int rd = (insn >> 8) & 0xf;
+ unsigned long mask = 0xf8ff03df; /* Mask out execution state */
+ regs->uregs[rd] = regs->ARM_cpsr & mask;
+}
+
+static void __kprobes
+t32_simulate_cond_branch(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long pc = regs->ARM_pc;
+
+ long offset = insn & 0x7ff; /* imm11 */
+ offset += (insn & 0x003f0000) >> 5; /* imm6 */
+ offset += (insn & 0x00002000) << 4; /* J1 */
+ offset += (insn & 0x00000800) << 7; /* J2 */
+ offset -= (insn & 0x04000000) >> 7; /* Apply sign bit */
+
+ regs->ARM_pc = pc + (offset * 2);
+}
+
+static enum probes_insn __kprobes
+t32_decode_cond_branch(probes_opcode_t insn, struct arch_probes_insn *asi,
+ const struct decode_header *d)
+{
+ int cc = (insn >> 22) & 0xf;
+ asi->insn_check_cc = probes_condition_checks[cc];
+ asi->insn_handler = t32_simulate_cond_branch;
+ return INSN_GOOD_NO_SLOT;
+}
+
+static void __kprobes
+t32_simulate_branch(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long pc = regs->ARM_pc;
+
+ long offset = insn & 0x7ff; /* imm11 */
+ offset += (insn & 0x03ff0000) >> 5; /* imm10 */
+ offset += (insn & 0x00002000) << 9; /* J1 */
+ offset += (insn & 0x00000800) << 10; /* J2 */
+ if (insn & 0x04000000)
+ offset -= 0x00800000; /* Apply sign bit */
+ else
+ offset ^= 0x00600000; /* Invert J1 and J2 */
+
+ if (insn & (1 << 14)) {
+ /* BL or BLX */
+ regs->ARM_lr = regs->ARM_pc | 1;
+ if (!(insn & (1 << 12))) {
+ /* BLX so switch to ARM mode */
+ regs->ARM_cpsr &= ~PSR_T_BIT;
+ pc &= ~3;
+ }
+ }
+
+ regs->ARM_pc = pc + (offset * 2);
+}
+
+static void __kprobes
+t32_simulate_ldr_literal(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long addr = regs->ARM_pc & ~3;
+ int rt = (insn >> 12) & 0xf;
+ unsigned long rtv;
+
+ long offset = insn & 0xfff;
+ if (insn & 0x00800000)
+ addr += offset;
+ else
+ addr -= offset;
+
+ if (insn & 0x00400000) {
+ /* LDR */
+ rtv = *(unsigned long *)addr;
+ if (rt == 15) {
+ bx_write_pc(rtv, regs);
+ return;
+ }
+ } else if (insn & 0x00200000) {
+ /* LDRH */
+ if (insn & 0x01000000)
+ rtv = *(s16 *)addr;
+ else
+ rtv = *(u16 *)addr;
+ } else {
+ /* LDRB */
+ if (insn & 0x01000000)
+ rtv = *(s8 *)addr;
+ else
+ rtv = *(u8 *)addr;
+ }
+
+ regs->uregs[rt] = rtv;
+}
+
+static enum probes_insn __kprobes
+t32_decode_ldmstm(probes_opcode_t insn, struct arch_probes_insn *asi,
+ const struct decode_header *d)
+{
+ enum probes_insn ret = kprobe_decode_ldmstm(insn, asi, d);
+
+ /* Fixup modified instruction to have halfwords in correct order...*/
+ insn = __mem_to_opcode_arm(asi->insn[0]);
+ ((u16 *)asi->insn)[0] = __opcode_to_mem_thumb16(insn >> 16);
+ ((u16 *)asi->insn)[1] = __opcode_to_mem_thumb16(insn & 0xffff);
+
+ return ret;
+}
+
+static void __kprobes
+t32_emulate_ldrdstrd(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long pc = regs->ARM_pc & ~3;
+ int rt1 = (insn >> 12) & 0xf;
+ int rt2 = (insn >> 8) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+
+ register unsigned long rt1v asm("r0") = regs->uregs[rt1];
+ register unsigned long rt2v asm("r1") = regs->uregs[rt2];
+ register unsigned long rnv asm("r2") = (rn == 15) ? pc
+ : regs->uregs[rn];
+
+ __asm__ __volatile__ (
+ "blx %[fn]"
+ : "=r" (rt1v), "=r" (rt2v), "=r" (rnv)
+ : "0" (rt1v), "1" (rt2v), "2" (rnv), [fn] "r" (asi->insn_fn)
+ : "lr", "memory", "cc"
+ );
+
+ if (rn != 15)
+ regs->uregs[rn] = rnv; /* Writeback base register */
+ regs->uregs[rt1] = rt1v;
+ regs->uregs[rt2] = rt2v;
+}
+
+static void __kprobes
+t32_emulate_ldrstr(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ int rt = (insn >> 12) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+ int rm = insn & 0xf;
+
+ register unsigned long rtv asm("r0") = regs->uregs[rt];
+ register unsigned long rnv asm("r2") = regs->uregs[rn];
+ register unsigned long rmv asm("r3") = regs->uregs[rm];
+
+ __asm__ __volatile__ (
+ "blx %[fn]"
+ : "=r" (rtv), "=r" (rnv)
+ : "0" (rtv), "1" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
+ : "lr", "memory", "cc"
+ );
+
+ regs->uregs[rn] = rnv; /* Writeback base register */
+ if (rt == 15) /* Can't be true for a STR as they aren't allowed */
+ bx_write_pc(rtv, regs);
+ else
+ regs->uregs[rt] = rtv;
+}
+
+static void __kprobes
+t32_emulate_rd8rn16rm0_rwflags(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ int rd = (insn >> 8) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+ int rm = insn & 0xf;
+
+ register unsigned long rdv asm("r1") = regs->uregs[rd];
+ register unsigned long rnv asm("r2") = regs->uregs[rn];
+ register unsigned long rmv asm("r3") = regs->uregs[rm];
+ unsigned long cpsr = regs->ARM_cpsr;
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[cpsr] \n\t"
+ "blx %[fn] \n\t"
+ "mrs %[cpsr], cpsr \n\t"
+ : "=r" (rdv), [cpsr] "=r" (cpsr)
+ : "0" (rdv), "r" (rnv), "r" (rmv),
+ "1" (cpsr), [fn] "r" (asi->insn_fn)
+ : "lr", "memory", "cc"
+ );
+
+ regs->uregs[rd] = rdv;
+ regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
+}
+
+static void __kprobes
+t32_emulate_rd8pc16_noflags(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long pc = regs->ARM_pc;
+ int rd = (insn >> 8) & 0xf;
+
+ register unsigned long rdv asm("r1") = regs->uregs[rd];
+ register unsigned long rnv asm("r2") = pc & ~3;
+
+ __asm__ __volatile__ (
+ "blx %[fn]"
+ : "=r" (rdv)
+ : "0" (rdv), "r" (rnv), [fn] "r" (asi->insn_fn)
+ : "lr", "memory", "cc"
+ );
+
+ regs->uregs[rd] = rdv;
+}
+
+static void __kprobes
+t32_emulate_rd8rn16_noflags(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ int rd = (insn >> 8) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+
+ register unsigned long rdv asm("r1") = regs->uregs[rd];
+ register unsigned long rnv asm("r2") = regs->uregs[rn];
+
+ __asm__ __volatile__ (
+ "blx %[fn]"
+ : "=r" (rdv)
+ : "0" (rdv), "r" (rnv), [fn] "r" (asi->insn_fn)
+ : "lr", "memory", "cc"
+ );
+
+ regs->uregs[rd] = rdv;
+}
+
+static void __kprobes
+t32_emulate_rdlo12rdhi8rn16rm0_noflags(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ struct pt_regs *regs)
+{
+ int rdlo = (insn >> 12) & 0xf;
+ int rdhi = (insn >> 8) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+ int rm = insn & 0xf;
+
+ register unsigned long rdlov asm("r0") = regs->uregs[rdlo];
+ register unsigned long rdhiv asm("r1") = regs->uregs[rdhi];
+ register unsigned long rnv asm("r2") = regs->uregs[rn];
+ register unsigned long rmv asm("r3") = regs->uregs[rm];
+
+ __asm__ __volatile__ (
+ "blx %[fn]"
+ : "=r" (rdlov), "=r" (rdhiv)
+ : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv),
+ [fn] "r" (asi->insn_fn)
+ : "lr", "memory", "cc"
+ );
+
+ regs->uregs[rdlo] = rdlov;
+ regs->uregs[rdhi] = rdhiv;
+}
+/* t16 thumb actions */
+
+static void __kprobes
+t16_simulate_bxblx(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long pc = regs->ARM_pc + 2;
+ int rm = (insn >> 3) & 0xf;
+ unsigned long rmv = (rm == 15) ? pc : regs->uregs[rm];
+
+ if (insn & (1 << 7)) /* BLX ? */
+ regs->ARM_lr = regs->ARM_pc | 1;
+
+ bx_write_pc(rmv, regs);
+}
+
+static void __kprobes
+t16_simulate_ldr_literal(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long *base = (unsigned long *)((regs->ARM_pc + 2) & ~3);
+ long index = insn & 0xff;
+ int rt = (insn >> 8) & 0x7;
+ regs->uregs[rt] = base[index];
+}
+
+static void __kprobes
+t16_simulate_ldrstr_sp_relative(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long* base = (unsigned long *)regs->ARM_sp;
+ long index = insn & 0xff;
+ int rt = (insn >> 8) & 0x7;
+ if (insn & 0x800) /* LDR */
+ regs->uregs[rt] = base[index];
+ else /* STR */
+ base[index] = regs->uregs[rt];
+}
+
+static void __kprobes
+t16_simulate_reladr(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long base = (insn & 0x800) ? regs->ARM_sp
+ : ((regs->ARM_pc + 2) & ~3);
+ long offset = insn & 0xff;
+ int rt = (insn >> 8) & 0x7;
+ regs->uregs[rt] = base + offset * 4;
+}
+
+static void __kprobes
+t16_simulate_add_sp_imm(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ long imm = insn & 0x7f;
+ if (insn & 0x80) /* SUB */
+ regs->ARM_sp -= imm * 4;
+ else /* ADD */
+ regs->ARM_sp += imm * 4;
+}
+
+static void __kprobes
+t16_simulate_cbz(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ int rn = insn & 0x7;
+ probes_opcode_t nonzero = regs->uregs[rn] ? insn : ~insn;
+ if (nonzero & 0x800) {
+ long i = insn & 0x200;
+ long imm5 = insn & 0xf8;
+ unsigned long pc = regs->ARM_pc + 2;
+ regs->ARM_pc = pc + (i >> 3) + (imm5 >> 2);
+ }
+}
+
+static void __kprobes
+t16_simulate_it(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ /*
+ * The 8 IT state bits are split into two parts in CPSR:
+ * ITSTATE<1:0> are in CPSR<26:25>
+ * ITSTATE<7:2> are in CPSR<15:10>
+ * The new IT state is in the lower byte of insn.
+ */
+ unsigned long cpsr = regs->ARM_cpsr;
+ cpsr &= ~PSR_IT_MASK;
+ cpsr |= (insn & 0xfc) << 8;
+ cpsr |= (insn & 0x03) << 25;
+ regs->ARM_cpsr = cpsr;
+}
+
+static void __kprobes
+t16_singlestep_it(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ regs->ARM_pc += 2;
+ t16_simulate_it(insn, asi, regs);
+}
+
+static enum probes_insn __kprobes
+t16_decode_it(probes_opcode_t insn, struct arch_probes_insn *asi,
+ const struct decode_header *d)
+{
+ asi->insn_singlestep = t16_singlestep_it;
+ return INSN_GOOD_NO_SLOT;
+}
+
+static void __kprobes
+t16_simulate_cond_branch(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long pc = regs->ARM_pc + 2;
+ long offset = insn & 0x7f;
+ offset -= insn & 0x80; /* Apply sign bit */
+ regs->ARM_pc = pc + (offset * 2);
+}
+
+static enum probes_insn __kprobes
+t16_decode_cond_branch(probes_opcode_t insn, struct arch_probes_insn *asi,
+ const struct decode_header *d)
+{
+ int cc = (insn >> 8) & 0xf;
+ asi->insn_check_cc = probes_condition_checks[cc];
+ asi->insn_handler = t16_simulate_cond_branch;
+ return INSN_GOOD_NO_SLOT;
+}
+
+static void __kprobes
+t16_simulate_branch(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long pc = regs->ARM_pc + 2;
+ long offset = insn & 0x3ff;
+ offset -= insn & 0x400; /* Apply sign bit */
+ regs->ARM_pc = pc + (offset * 2);
+}
+
+static unsigned long __kprobes
+t16_emulate_loregs(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long oldcpsr = regs->ARM_cpsr;
+ unsigned long newcpsr;
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[oldcpsr] \n\t"
+ "ldmia %[regs], {r0-r7} \n\t"
+ "blx %[fn] \n\t"
+ "stmia %[regs], {r0-r7} \n\t"
+ "mrs %[newcpsr], cpsr \n\t"
+ : [newcpsr] "=r" (newcpsr)
+ : [oldcpsr] "r" (oldcpsr), [regs] "r" (regs),
+ [fn] "r" (asi->insn_fn)
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "lr", "memory", "cc"
+ );
+
+ return (oldcpsr & ~APSR_MASK) | (newcpsr & APSR_MASK);
+}
+
+static void __kprobes
+t16_emulate_loregs_rwflags(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ regs->ARM_cpsr = t16_emulate_loregs(insn, asi, regs);
+}
+
+static void __kprobes
+t16_emulate_loregs_noitrwflags(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long cpsr = t16_emulate_loregs(insn, asi, regs);
+ if (!in_it_block(cpsr))
+ regs->ARM_cpsr = cpsr;
+}
+
+static void __kprobes
+t16_emulate_hiregs(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ unsigned long pc = regs->ARM_pc + 2;
+ int rdn = (insn & 0x7) | ((insn & 0x80) >> 4);
+ int rm = (insn >> 3) & 0xf;
+
+ register unsigned long rdnv asm("r1");
+ register unsigned long rmv asm("r0");
+ unsigned long cpsr = regs->ARM_cpsr;
+
+ rdnv = (rdn == 15) ? pc : regs->uregs[rdn];
+ rmv = (rm == 15) ? pc : regs->uregs[rm];
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[cpsr] \n\t"
+ "blx %[fn] \n\t"
+ "mrs %[cpsr], cpsr \n\t"
+ : "=r" (rdnv), [cpsr] "=r" (cpsr)
+ : "0" (rdnv), "r" (rmv), "1" (cpsr), [fn] "r" (asi->insn_fn)
+ : "lr", "memory", "cc"
+ );
+
+ if (rdn == 15)
+ rdnv &= ~1;
+
+ regs->uregs[rdn] = rdnv;
+ regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
+}
+
+static enum probes_insn __kprobes
+t16_decode_hiregs(probes_opcode_t insn, struct arch_probes_insn *asi,
+ const struct decode_header *d)
+{
+ insn &= ~0x00ff;
+ insn |= 0x001; /* Set Rdn = R1 and Rm = R0 */
+ ((u16 *)asi->insn)[0] = __opcode_to_mem_thumb16(insn);
+ asi->insn_handler = t16_emulate_hiregs;
+ return INSN_GOOD;
+}
+
+static void __kprobes
+t16_emulate_push(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ __asm__ __volatile__ (
+ "ldr r9, [%[regs], #13*4] \n\t"
+ "ldr r8, [%[regs], #14*4] \n\t"
+ "ldmia %[regs], {r0-r7} \n\t"
+ "blx %[fn] \n\t"
+ "str r9, [%[regs], #13*4] \n\t"
+ :
+ : [regs] "r" (regs), [fn] "r" (asi->insn_fn)
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
+ "lr", "memory", "cc"
+ );
+}
+
+static enum probes_insn __kprobes
+t16_decode_push(probes_opcode_t insn, struct arch_probes_insn *asi,
+ const struct decode_header *d)
+{
+ /*
+ * To simulate a PUSH we use a Thumb-2 "STMDB R9!, {registers}"
+ * and call it with R9=SP and LR in the register list represented
+ * by R8.
+ */
+ /* 1st half STMDB R9!,{} */
+ ((u16 *)asi->insn)[0] = __opcode_to_mem_thumb16(0xe929);
+ /* 2nd half (register list) */
+ ((u16 *)asi->insn)[1] = __opcode_to_mem_thumb16(insn & 0x1ff);
+ asi->insn_handler = t16_emulate_push;
+ return INSN_GOOD;
+}
+
+static void __kprobes
+t16_emulate_pop_nopc(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ __asm__ __volatile__ (
+ "ldr r9, [%[regs], #13*4] \n\t"
+ "ldmia %[regs], {r0-r7} \n\t"
+ "blx %[fn] \n\t"
+ "stmia %[regs], {r0-r7} \n\t"
+ "str r9, [%[regs], #13*4] \n\t"
+ :
+ : [regs] "r" (regs), [fn] "r" (asi->insn_fn)
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9",
+ "lr", "memory", "cc"
+ );
+}
+
+static void __kprobes
+t16_emulate_pop_pc(probes_opcode_t insn,
+ struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+ register unsigned long pc asm("r8");
+
+ __asm__ __volatile__ (
+ "ldr r9, [%[regs], #13*4] \n\t"
+ "ldmia %[regs], {r0-r7} \n\t"
+ "blx %[fn] \n\t"
+ "stmia %[regs], {r0-r7} \n\t"
+ "str r9, [%[regs], #13*4] \n\t"
+ : "=r" (pc)
+ : [regs] "r" (regs), [fn] "r" (asi->insn_fn)
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9",
+ "lr", "memory", "cc"
+ );
+
+ bx_write_pc(pc, regs);
+}
+
+static enum probes_insn __kprobes
+t16_decode_pop(probes_opcode_t insn, struct arch_probes_insn *asi,
+ const struct decode_header *d)
+{
+ /*
+ * To simulate a POP we use a Thumb-2 "LDMDB R9!, {registers}"
+ * and call it with R9=SP and PC in the register list represented
+ * by R8.
+ */
+ /* 1st half LDMIA R9!,{} */
+ ((u16 *)asi->insn)[0] = __opcode_to_mem_thumb16(0xe8b9);
+ /* 2nd half (register list) */
+ ((u16 *)asi->insn)[1] = __opcode_to_mem_thumb16(insn & 0x1ff);
+ asi->insn_handler = insn & 0x100 ? t16_emulate_pop_pc
+ : t16_emulate_pop_nopc;
+ return INSN_GOOD;
+}
+
+const union decode_action kprobes_t16_actions[NUM_PROBES_T16_ACTIONS] = {
+ [PROBES_T16_ADD_SP] = {.handler = t16_simulate_add_sp_imm},
+ [PROBES_T16_CBZ] = {.handler = t16_simulate_cbz},
+ [PROBES_T16_SIGN_EXTEND] = {.handler = t16_emulate_loregs_rwflags},
+ [PROBES_T16_PUSH] = {.decoder = t16_decode_push},
+ [PROBES_T16_POP] = {.decoder = t16_decode_pop},
+ [PROBES_T16_SEV] = {.handler = probes_emulate_none},
+ [PROBES_T16_WFE] = {.handler = probes_simulate_nop},
+ [PROBES_T16_IT] = {.decoder = t16_decode_it},
+ [PROBES_T16_CMP] = {.handler = t16_emulate_loregs_rwflags},
+ [PROBES_T16_ADDSUB] = {.handler = t16_emulate_loregs_noitrwflags},
+ [PROBES_T16_LOGICAL] = {.handler = t16_emulate_loregs_noitrwflags},
+ [PROBES_T16_LDR_LIT] = {.handler = t16_simulate_ldr_literal},
+ [PROBES_T16_BLX] = {.handler = t16_simulate_bxblx},
+ [PROBES_T16_HIREGOPS] = {.decoder = t16_decode_hiregs},
+ [PROBES_T16_LDRHSTRH] = {.handler = t16_emulate_loregs_rwflags},
+ [PROBES_T16_LDRSTR] = {.handler = t16_simulate_ldrstr_sp_relative},
+ [PROBES_T16_ADR] = {.handler = t16_simulate_reladr},
+ [PROBES_T16_LDMSTM] = {.handler = t16_emulate_loregs_rwflags},
+ [PROBES_T16_BRANCH_COND] = {.decoder = t16_decode_cond_branch},
+ [PROBES_T16_BRANCH] = {.handler = t16_simulate_branch},
+};
+
+const union decode_action kprobes_t32_actions[NUM_PROBES_T32_ACTIONS] = {
+ [PROBES_T32_LDMSTM] = {.decoder = t32_decode_ldmstm},
+ [PROBES_T32_LDRDSTRD] = {.handler = t32_emulate_ldrdstrd},
+ [PROBES_T32_TABLE_BRANCH] = {.handler = t32_simulate_table_branch},
+ [PROBES_T32_TST] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+ [PROBES_T32_MOV] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+ [PROBES_T32_ADDSUB] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+ [PROBES_T32_LOGICAL] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+ [PROBES_T32_CMP] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+ [PROBES_T32_ADDWSUBW_PC] = {.handler = t32_emulate_rd8pc16_noflags,},
+ [PROBES_T32_ADDWSUBW] = {.handler = t32_emulate_rd8rn16_noflags},
+ [PROBES_T32_MOVW] = {.handler = t32_emulate_rd8rn16_noflags},
+ [PROBES_T32_SAT] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+ [PROBES_T32_BITFIELD] = {.handler = t32_emulate_rd8rn16_noflags},
+ [PROBES_T32_SEV] = {.handler = probes_emulate_none},
+ [PROBES_T32_WFE] = {.handler = probes_simulate_nop},
+ [PROBES_T32_MRS] = {.handler = t32_simulate_mrs},
+ [PROBES_T32_BRANCH_COND] = {.decoder = t32_decode_cond_branch},
+ [PROBES_T32_BRANCH] = {.handler = t32_simulate_branch},
+ [PROBES_T32_PLDI] = {.handler = probes_simulate_nop},
+ [PROBES_T32_LDR_LIT] = {.handler = t32_simulate_ldr_literal},
+ [PROBES_T32_LDRSTR] = {.handler = t32_emulate_ldrstr},
+ [PROBES_T32_SIGN_EXTEND] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+ [PROBES_T32_MEDIA] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+ [PROBES_T32_REVERSE] = {.handler = t32_emulate_rd8rn16_noflags},
+ [PROBES_T32_MUL_ADD] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+ [PROBES_T32_MUL_ADD2] = {.handler = t32_emulate_rd8rn16rm0ra12_noflags},
+ [PROBES_T32_MUL_ADD_LONG] = {
+ .handler = t32_emulate_rdlo12rdhi8rn16rm0_noflags},
+};
+
+const struct decode_checker *kprobes_t32_checkers[] = {t32_stack_checker, NULL};
+const struct decode_checker *kprobes_t16_checkers[] = {t16_stack_checker, NULL};
diff --git a/arch/arm/probes/kprobes/checkers-arm.c b/arch/arm/probes/kprobes/checkers-arm.c
new file mode 100644
index 000000000..7b9817333
--- /dev/null
+++ b/arch/arm/probes/kprobes/checkers-arm.c
@@ -0,0 +1,192 @@
+/*
+ * arch/arm/probes/kprobes/checkers-arm.c
+ *
+ * Copyright (C) 2014 Huawei 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.
+ */
+
+#include <linux/kernel.h>
+#include "../decode.h"
+#include "../decode-arm.h"
+#include "checkers.h"
+
+static enum probes_insn __kprobes arm_check_stack(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ /*
+ * PROBES_LDRSTRD, PROBES_LDMSTM, PROBES_STORE,
+ * PROBES_STORE_EXTRA may get here. Simply mark all normal
+ * insns as STACK_USE_NONE.
+ */
+ static const union decode_item table[] = {
+ /*
+ * 'STR{,D,B,H}, Rt, [Rn, Rm]' should be marked as UNKNOWN
+ * if Rn or Rm is SP.
+ * x
+ * STR (register) cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx
+ * STRB (register) cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_OR (0x0e10000f, 0x0600000d),
+ DECODE_OR (0x0e1f0000, 0x060d0000),
+
+ /*
+ * x
+ * STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx
+ * STRH (register) cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx
+ */
+ DECODE_OR (0x0e5000bf, 0x000000bd),
+ DECODE_CUSTOM (0x0e5f00b0, 0x000d00b0, STACK_USE_UNKNOWN),
+
+ /*
+ * For PROBES_LDMSTM, only stmdx sp, [...] need to examine
+ *
+ * Bit B/A (bit 24) encodes arithmetic operation order. 1 means
+ * before, 0 means after.
+ * Bit I/D (bit 23) encodes arithmetic operation. 1 means
+ * increment, 0 means decrement.
+ *
+ * So:
+ * B I
+ * / /
+ * A D | Rn |
+ * STMDX SP, [...] cccc 100x 00x0 xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_CUSTOM (0x0edf0000, 0x080d0000, STACK_USE_STMDX),
+
+ /* P U W | Rn | Rt | imm12 |*/
+ /* STR (immediate) cccc 010x x0x0 1101 xxxx xxxx xxxx xxxx */
+ /* STRB (immediate) cccc 010x x1x0 1101 xxxx xxxx xxxx xxxx */
+ /* P U W | Rn | Rt |imm4| |imm4|*/
+ /* STRD (immediate) cccc 000x x1x0 1101 xxxx xxxx 1111 xxxx */
+ /* STRH (immediate) cccc 000x x1x0 1101 xxxx xxxx 1011 xxxx */
+ /*
+ * index = (P == '1'); add = (U == '1').
+ * Above insns with:
+ * index == 0 (str{,d,h} rx, [sp], #+/-imm) or
+ * add == 1 (str{,d,h} rx, [sp, #+<imm>])
+ * should be STACK_USE_NONE.
+ * Only str{,b,d,h} rx,[sp,#-n] (P == 1 and U == 0) are
+ * required to be examined.
+ */
+ /* STR{,B} Rt,[SP,#-n] cccc 0101 0xx0 1101 xxxx xxxx xxxx xxxx */
+ DECODE_CUSTOM (0x0f9f0000, 0x050d0000, STACK_USE_FIXED_XXX),
+
+ /* STR{D,H} Rt,[SP,#-n] cccc 0001 01x0 1101 xxxx xxxx 1x11 xxxx */
+ DECODE_CUSTOM (0x0fdf00b0, 0x014d00b0, STACK_USE_FIXED_X0X),
+
+ /* fall through */
+ DECODE_CUSTOM (0, 0, STACK_USE_NONE),
+ DECODE_END
+ };
+
+ return probes_decode_insn(insn, asi, table, false, false, stack_check_actions, NULL);
+}
+
+const struct decode_checker arm_stack_checker[NUM_PROBES_ARM_ACTIONS] = {
+ [PROBES_LDRSTRD] = {.checker = arm_check_stack},
+ [PROBES_STORE_EXTRA] = {.checker = arm_check_stack},
+ [PROBES_STORE] = {.checker = arm_check_stack},
+ [PROBES_LDMSTM] = {.checker = arm_check_stack},
+};
+
+static enum probes_insn __kprobes arm_check_regs_nouse(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ asi->register_usage_flags = 0;
+ return INSN_GOOD;
+}
+
+static enum probes_insn arm_check_regs_normal(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS;
+ int i;
+
+ asi->register_usage_flags = 0;
+ for (i = 0; i < 5; regs >>= 4, insn >>= 4, i++)
+ if (regs & 0xf)
+ asi->register_usage_flags |= 1 << (insn & 0xf);
+
+ return INSN_GOOD;
+}
+
+
+static enum probes_insn arm_check_regs_ldmstm(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ unsigned int reglist = insn & 0xffff;
+ unsigned int rn = (insn >> 16) & 0xf;
+ asi->register_usage_flags = reglist | (1 << rn);
+ return INSN_GOOD;
+}
+
+static enum probes_insn arm_check_regs_mov_ip_sp(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ /* Instruction is 'mov ip, sp' i.e. 'mov r12, r13' */
+ asi->register_usage_flags = (1 << 12) | (1<< 13);
+ return INSN_GOOD;
+}
+
+/*
+ * | Rn |Rt/d| | Rm |
+ * LDRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx
+ * STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx
+ * | Rn |Rt/d| |imm4L|
+ * LDRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx
+ * STRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx
+ *
+ * Such instructions access Rt/d and its next register, so different
+ * from others, a specific checker is required to handle this extra
+ * implicit register usage.
+ */
+static enum probes_insn arm_check_regs_ldrdstrd(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ int rdt = (insn >> 12) & 0xf;
+ arm_check_regs_normal(insn, asi, h);
+ asi->register_usage_flags |= 1 << (rdt + 1);
+ return INSN_GOOD;
+}
+
+
+const struct decode_checker arm_regs_checker[NUM_PROBES_ARM_ACTIONS] = {
+ [PROBES_MRS] = {.checker = arm_check_regs_normal},
+ [PROBES_SATURATING_ARITHMETIC] = {.checker = arm_check_regs_normal},
+ [PROBES_MUL1] = {.checker = arm_check_regs_normal},
+ [PROBES_MUL2] = {.checker = arm_check_regs_normal},
+ [PROBES_MUL_ADD_LONG] = {.checker = arm_check_regs_normal},
+ [PROBES_MUL_ADD] = {.checker = arm_check_regs_normal},
+ [PROBES_LOAD] = {.checker = arm_check_regs_normal},
+ [PROBES_LOAD_EXTRA] = {.checker = arm_check_regs_normal},
+ [PROBES_STORE] = {.checker = arm_check_regs_normal},
+ [PROBES_STORE_EXTRA] = {.checker = arm_check_regs_normal},
+ [PROBES_DATA_PROCESSING_REG] = {.checker = arm_check_regs_normal},
+ [PROBES_DATA_PROCESSING_IMM] = {.checker = arm_check_regs_normal},
+ [PROBES_SEV] = {.checker = arm_check_regs_nouse},
+ [PROBES_WFE] = {.checker = arm_check_regs_nouse},
+ [PROBES_SATURATE] = {.checker = arm_check_regs_normal},
+ [PROBES_REV] = {.checker = arm_check_regs_normal},
+ [PROBES_MMI] = {.checker = arm_check_regs_normal},
+ [PROBES_PACK] = {.checker = arm_check_regs_normal},
+ [PROBES_EXTEND] = {.checker = arm_check_regs_normal},
+ [PROBES_EXTEND_ADD] = {.checker = arm_check_regs_normal},
+ [PROBES_BITFIELD] = {.checker = arm_check_regs_normal},
+ [PROBES_LDMSTM] = {.checker = arm_check_regs_ldmstm},
+ [PROBES_MOV_IP_SP] = {.checker = arm_check_regs_mov_ip_sp},
+ [PROBES_LDRSTRD] = {.checker = arm_check_regs_ldrdstrd},
+};
diff --git a/arch/arm/probes/kprobes/checkers-common.c b/arch/arm/probes/kprobes/checkers-common.c
new file mode 100644
index 000000000..971119c29
--- /dev/null
+++ b/arch/arm/probes/kprobes/checkers-common.c
@@ -0,0 +1,101 @@
+/*
+ * arch/arm/probes/kprobes/checkers-common.c
+ *
+ * Copyright (C) 2014 Huawei 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.
+ */
+
+#include <linux/kernel.h>
+#include "../decode.h"
+#include "../decode-arm.h"
+#include "checkers.h"
+
+enum probes_insn checker_stack_use_none(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ asi->stack_space = 0;
+ return INSN_GOOD_NO_SLOT;
+}
+
+enum probes_insn checker_stack_use_unknown(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ asi->stack_space = -1;
+ return INSN_GOOD_NO_SLOT;
+}
+
+#ifdef CONFIG_THUMB2_KERNEL
+enum probes_insn checker_stack_use_imm_0xx(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ int imm = insn & 0xff;
+ asi->stack_space = imm;
+ return INSN_GOOD_NO_SLOT;
+}
+
+/*
+ * Different from other insn uses imm8, the real addressing offset of
+ * STRD in T32 encoding should be imm8 * 4. See ARMARM description.
+ */
+enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ int imm = insn & 0xff;
+ asi->stack_space = imm << 2;
+ return INSN_GOOD_NO_SLOT;
+}
+#else
+enum probes_insn checker_stack_use_imm_x0x(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ int imm = ((insn & 0xf00) >> 4) + (insn & 0xf);
+ asi->stack_space = imm;
+ return INSN_GOOD_NO_SLOT;
+}
+#endif
+
+enum probes_insn checker_stack_use_imm_xxx(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ int imm = insn & 0xfff;
+ asi->stack_space = imm;
+ return INSN_GOOD_NO_SLOT;
+}
+
+enum probes_insn checker_stack_use_stmdx(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ unsigned int reglist = insn & 0xffff;
+ int pbit = insn & (1 << 24);
+ asi->stack_space = (hweight32(reglist) - (!pbit ? 1 : 0)) * 4;
+
+ return INSN_GOOD_NO_SLOT;
+}
+
+const union decode_action stack_check_actions[] = {
+ [STACK_USE_NONE] = {.decoder = checker_stack_use_none},
+ [STACK_USE_UNKNOWN] = {.decoder = checker_stack_use_unknown},
+#ifdef CONFIG_THUMB2_KERNEL
+ [STACK_USE_FIXED_0XX] = {.decoder = checker_stack_use_imm_0xx},
+ [STACK_USE_T32STRD] = {.decoder = checker_stack_use_t32strd},
+#else
+ [STACK_USE_FIXED_X0X] = {.decoder = checker_stack_use_imm_x0x},
+#endif
+ [STACK_USE_FIXED_XXX] = {.decoder = checker_stack_use_imm_xxx},
+ [STACK_USE_STMDX] = {.decoder = checker_stack_use_stmdx},
+};
diff --git a/arch/arm/probes/kprobes/checkers-thumb.c b/arch/arm/probes/kprobes/checkers-thumb.c
new file mode 100644
index 000000000..d608e3b90
--- /dev/null
+++ b/arch/arm/probes/kprobes/checkers-thumb.c
@@ -0,0 +1,110 @@
+/*
+ * arch/arm/probes/kprobes/checkers-thumb.c
+ *
+ * Copyright (C) 2014 Huawei 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.
+ */
+
+#include <linux/kernel.h>
+#include "../decode.h"
+#include "../decode-thumb.h"
+#include "checkers.h"
+
+static enum probes_insn __kprobes t32_check_stack(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ /*
+ * PROBES_T32_LDMSTM, PROBES_T32_LDRDSTRD and PROBES_T32_LDRSTR
+ * may get here. Simply mark all normal insns as STACK_USE_NONE.
+ */
+ static const union decode_item table[] = {
+
+ /*
+ * First, filter out all ldr insns to make our life easier.
+ * Following load insns may come here:
+ * LDM, LDRD, LDR.
+ * In T32 encoding, bit 20 is enough for distinguishing
+ * load and store. All load insns have this bit set, when
+ * all store insns have this bit clear.
+ */
+ DECODE_CUSTOM (0x00100000, 0x00100000, STACK_USE_NONE),
+
+ /*
+ * Mark all 'STR{,B,H}, Rt, [Rn, Rm]' as STACK_USE_UNKNOWN
+ * if Rn or Rm is SP. T32 doesn't encode STRD.
+ */
+ /* xx | Rn | Rt | | Rm |*/
+ /* STR (register) 1111 1000 0100 xxxx xxxx 0000 00xx xxxx */
+ /* STRB (register) 1111 1000 0000 xxxx xxxx 0000 00xx xxxx */
+ /* STRH (register) 1111 1000 0010 xxxx xxxx 0000 00xx xxxx */
+ /* INVALID INSN 1111 1000 0110 xxxx xxxx 0000 00xx xxxx */
+ /* By Introducing INVALID INSN, bit 21 and 22 can be ignored. */
+ DECODE_OR (0xff9f0fc0, 0xf80d0000),
+ DECODE_CUSTOM (0xff900fcf, 0xf800000d, STACK_USE_UNKNOWN),
+
+
+ /* xx | Rn | Rt | PUW| imm8 |*/
+ /* STR (imm 8) 1111 1000 0100 1101 xxxx 110x xxxx xxxx */
+ /* STRB (imm 8) 1111 1000 0000 1101 xxxx 110x xxxx xxxx */
+ /* STRH (imm 8) 1111 1000 0010 1101 xxxx 110x xxxx xxxx */
+ /* INVALID INSN 1111 1000 0110 1101 xxxx 110x xxxx xxxx */
+ /* Only consider U == 0 and P == 1: strx rx, [sp, #-<imm>] */
+ DECODE_CUSTOM (0xff9f0e00, 0xf80d0c00, STACK_USE_FIXED_0XX),
+
+ /* For STR{,B,H} (imm 12), offset is always positive, so ignore them. */
+
+ /* P U W | Rn | Rt | Rt2| imm8 |*/
+ /* STRD (immediate) 1110 1001 01x0 1101 xxxx xxxx xxxx xxxx */
+ /*
+ * Only consider U == 0 and P == 1.
+ * Also note that STRD in T32 encoding is special:
+ * imm = ZeroExtend(imm8:'00', 32)
+ */
+ DECODE_CUSTOM (0xffdf0000, 0xe94d0000, STACK_USE_T32STRD),
+
+ /* | Rn | */
+ /* STMDB 1110 1001 00x0 1101 xxxx xxxx xxxx xxxx */
+ DECODE_CUSTOM (0xffdf0000, 0xe90d0000, STACK_USE_STMDX),
+
+ /* fall through */
+ DECODE_CUSTOM (0, 0, STACK_USE_NONE),
+ DECODE_END
+ };
+
+ return probes_decode_insn(insn, asi, table, false, false, stack_check_actions, NULL);
+}
+
+const struct decode_checker t32_stack_checker[NUM_PROBES_T32_ACTIONS] = {
+ [PROBES_T32_LDMSTM] = {.checker = t32_check_stack},
+ [PROBES_T32_LDRDSTRD] = {.checker = t32_check_stack},
+ [PROBES_T32_LDRSTR] = {.checker = t32_check_stack},
+};
+
+/*
+ * See following comments. This insn must be 'push'.
+ */
+static enum probes_insn __kprobes t16_check_stack(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ unsigned int reglist = insn & 0x1ff;
+ asi->stack_space = hweight32(reglist) * 4;
+ return INSN_GOOD;
+}
+
+/*
+ * T16 encoding is simple: only the 'push' insn can need extra stack space.
+ * Other insns, like str, can only use r0-r7 as Rn.
+ */
+const struct decode_checker t16_stack_checker[NUM_PROBES_T16_ACTIONS] = {
+ [PROBES_T16_PUSH] = {.checker = t16_check_stack},
+};
diff --git a/arch/arm/probes/kprobes/checkers.h b/arch/arm/probes/kprobes/checkers.h
new file mode 100644
index 000000000..cf6c9e74d
--- /dev/null
+++ b/arch/arm/probes/kprobes/checkers.h
@@ -0,0 +1,55 @@
+/*
+ * arch/arm/probes/kprobes/checkers.h
+ *
+ * Copyright (C) 2014 Huawei 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_KERNEL_PROBES_CHECKERS_H
+#define _ARM_KERNEL_PROBES_CHECKERS_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include "../decode.h"
+
+extern probes_check_t checker_stack_use_none;
+extern probes_check_t checker_stack_use_unknown;
+#ifdef CONFIG_THUMB2_KERNEL
+extern probes_check_t checker_stack_use_imm_0xx;
+#else
+extern probes_check_t checker_stack_use_imm_x0x;
+#endif
+extern probes_check_t checker_stack_use_imm_xxx;
+extern probes_check_t checker_stack_use_stmdx;
+
+enum {
+ STACK_USE_NONE,
+ STACK_USE_UNKNOWN,
+#ifdef CONFIG_THUMB2_KERNEL
+ STACK_USE_FIXED_0XX,
+ STACK_USE_T32STRD,
+#else
+ STACK_USE_FIXED_X0X,
+#endif
+ STACK_USE_FIXED_XXX,
+ STACK_USE_STMDX,
+ NUM_STACK_USE_TYPES
+};
+
+extern const union decode_action stack_check_actions[];
+
+#ifndef CONFIG_THUMB2_KERNEL
+extern const struct decode_checker arm_stack_checker[];
+extern const struct decode_checker arm_regs_checker[];
+#else
+#endif
+extern const struct decode_checker t32_stack_checker[];
+extern const struct decode_checker t16_stack_checker[];
+#endif
diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.c
new file mode 100644
index 000000000..a4ec240ee
--- /dev/null
+++ b/arch/arm/probes/kprobes/core.c
@@ -0,0 +1,653 @@
+/*
+ * 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/opcodes.h>
+#include <asm/cacheflush.h>
+#include <linux/percpu.h>
+#include <linux/bug.h>
+#include <asm/patch.h>
+
+#include "../decode-arm.h"
+#include "../decode-thumb.h"
+#include "core.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, size) \
+ flush_icache_range((unsigned long)(addr), \
+ (unsigned long)(addr) + \
+ (size))
+
+/* 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;
+ bool thumb;
+ kprobe_decode_insn_t *decode_insn;
+ const union decode_action *actions;
+ int is;
+ const struct decode_checker **checkers;
+
+ if (in_exception_text(addr))
+ return -EINVAL;
+
+#ifdef CONFIG_THUMB2_KERNEL
+ thumb = true;
+ addr &= ~1; /* Bit 0 would normally be set to indicate Thumb code */
+ insn = __mem_to_opcode_thumb16(((u16 *)addr)[0]);
+ if (is_wide_instruction(insn)) {
+ u16 inst2 = __mem_to_opcode_thumb16(((u16 *)addr)[1]);
+ insn = __opcode_thumb32_compose(insn, inst2);
+ decode_insn = thumb32_probes_decode_insn;
+ actions = kprobes_t32_actions;
+ checkers = kprobes_t32_checkers;
+ } else {
+ decode_insn = thumb16_probes_decode_insn;
+ actions = kprobes_t16_actions;
+ checkers = kprobes_t16_checkers;
+ }
+#else /* !CONFIG_THUMB2_KERNEL */
+ thumb = false;
+ if (addr & 0x3)
+ return -EINVAL;
+ insn = __mem_to_opcode_arm(*p->addr);
+ decode_insn = arm_probes_decode_insn;
+ actions = kprobes_arm_actions;
+ checkers = kprobes_arm_checkers;
+#endif
+
+ p->opcode = insn;
+ p->ainsn.insn = tmp_insn;
+
+ switch ((*decode_insn)(insn, &p->ainsn, true, actions, checkers)) {
+ 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,
+ sizeof(p->ainsn.insn[0]) * MAX_INSN_SIZE);
+ p->ainsn.insn_fn = (probes_insn_fn_t *)
+ ((uintptr_t)p->ainsn.insn | thumb);
+ break;
+
+ case INSN_GOOD_NO_SLOT: /* instruction doesn't need insn slot */
+ p->ainsn.insn = NULL;
+ break;
+ }
+
+ /*
+ * Never instrument insn like 'str r0, [sp, +/-r1]'. Also, insn likes
+ * 'str r0, [sp, #-68]' should also be prohibited.
+ * See __und_svc.
+ */
+ if ((p->ainsn.stack_space < 0) ||
+ (p->ainsn.stack_space > MAX_STACK_SIZE))
+ return -EINVAL;
+
+ return 0;
+}
+
+void __kprobes arch_arm_kprobe(struct kprobe *p)
+{
+ unsigned int brkp;
+ void *addr;
+
+ if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
+ /* Remove any Thumb flag */
+ addr = (void *)((uintptr_t)p->addr & ~1);
+
+ if (is_wide_instruction(p->opcode))
+ brkp = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION;
+ else
+ brkp = KPROBE_THUMB16_BREAKPOINT_INSTRUCTION;
+ } else {
+ kprobe_opcode_t insn = p->opcode;
+
+ addr = p->addr;
+ brkp = KPROBE_ARM_BREAKPOINT_INSTRUCTION;
+
+ if (insn >= 0xe0000000)
+ brkp |= 0xe0000000; /* Unconditional instruction */
+ else
+ brkp |= insn & 0xf0000000; /* Copy condition from insn */
+ }
+
+ patch_text(addr, brkp);
+}
+
+/*
+ * 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. It is also needed to atomically set the two half-words of a 32-bit
+ * Thumb breakpoint.
+ */
+struct patch {
+ void *addr;
+ unsigned int insn;
+};
+
+static int __kprobes_remove_breakpoint(void *data)
+{
+ struct patch *p = data;
+ __patch_text(p->addr, p->insn);
+ return 0;
+}
+
+void __kprobes kprobes_remove_breakpoint(void *addr, unsigned int insn)
+{
+ struct patch p = {
+ .addr = addr,
+ .insn = insn,
+ };
+ stop_machine(__kprobes_remove_breakpoint, &p, cpu_online_mask);
+}
+
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
+{
+ kprobes_remove_breakpoint((void *)((uintptr_t)p->addr & ~1),
+ p->opcode);
+}
+
+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)
+{
+ __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
+ kcb->kprobe_status = kcb->prev_kprobe.status;
+}
+
+static void __kprobes set_current_kprobe(struct kprobe *p)
+{
+ __this_cpu_write(current_kprobe, p);
+}
+
+static void __kprobes
+singlestep_skip(struct kprobe *p, struct pt_regs *regs)
+{
+#ifdef CONFIG_THUMB2_KERNEL
+ regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
+ if (is_wide_instruction(p->opcode))
+ regs->ARM_pc += 4;
+ else
+ regs->ARM_pc += 2;
+#else
+ regs->ARM_pc += 4;
+#endif
+}
+
+static inline void __kprobes
+singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb)
+{
+ p->ainsn.insn_singlestep(p->opcode, &p->ainsn, 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;
+
+ kcb = get_kprobe_ctlblk();
+ cur = kprobe_running();
+
+#ifdef CONFIG_THUMB2_KERNEL
+ /*
+ * First look for a probe which was registered using an address with
+ * bit 0 set, this is the usual situation for pointers to Thumb code.
+ * If not found, fallback to looking for one with bit 0 clear.
+ */
+ p = get_kprobe((kprobe_opcode_t *)(regs->ARM_pc | 1));
+ if (!p)
+ p = get_kprobe((kprobe_opcode_t *)regs->ARM_pc);
+
+#else /* ! CONFIG_THUMB2_KERNEL */
+ p = get_kprobe((kprobe_opcode_t *)regs->ARM_pc);
+#endif
+
+ 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 if (p->ainsn.insn_check_cc(regs->ARM_cpsr)) {
+ /* Probe hit and conditional execution check ok. */
+ 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 {
+ /*
+ * Probe hit but conditional execution check failed,
+ * so just skip the instruction and continue as if
+ * nothing had happened.
+ */
+ singlestep_skip(p, regs);
+ }
+ } 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"
+#ifdef CONFIG_THUMB2_KERNEL
+ "bx lr \n\t"
+#else
+ "mov pc, lr \n\t"
+#endif
+ : : : "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 *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, tmp, head, hlist) {
+ if (ri->task != current)
+ /* another task is sharing our hash bucket */
+ continue;
+
+ if (ri->rp && ri->rp->handler) {
+ __this_cpu_write(current_kprobe, &ri->rp->kp);
+ get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
+ ri->rp->handler(ri, regs);
+ __this_cpu_write(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, 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;
+ long cpsr;
+
+ kcb->jprobe_saved_regs = *regs;
+ memcpy(kcb->jprobes_stack, (void *)sp_addr, MIN_STACK_SIZE(sp_addr));
+ regs->ARM_pc = (long)jp->entry;
+
+ cpsr = regs->ARM_cpsr | PSR_I_BIT;
+#ifdef CONFIG_THUMB2_KERNEL
+ /* Set correct Thumb state in cpsr */
+ if (regs->ARM_pc & 1)
+ cpsr |= PSR_T_BIT;
+ else
+ cpsr &= ~PSR_T_BIT;
+#endif
+ regs->ARM_cpsr = cpsr;
+
+ 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.
+ */
+#ifdef CONFIG_THUMB2_KERNEL
+ "sub r0, %0, %1 \n\t"
+ "mov sp, r0 \n\t"
+#else
+ "sub sp, %0, %1 \n\t"
+#endif
+ "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.
+ */
+#ifdef CONFIG_THUMB2_KERNEL
+ "ldr lr, [sp, %2] \n\t" /* lr = saved sp */
+ "ldrd r0, r1, [sp, %5] \n\t" /* r0,r1 = saved lr,pc */
+ "ldr r2, [sp, %4] \n\t" /* r2 = saved psr */
+ "stmdb lr!, {r0, r1, r2} \n\t" /* push saved lr and */
+ /* rfe context */
+ "ldmia sp, {r0 - r12} \n\t"
+ "mov sp, lr \n\t"
+ "ldr lr, [sp], #4 \n\t"
+ "rfeia sp! \n\t"
+#else
+ "ldr r0, [sp, %4] \n\t"
+ "msr cpsr_cxsf, r0 \n\t"
+ "ldmia sp, {r0 - pc} \n\t"
+#endif
+ :
+ : "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)),
+ "J" (offsetof(struct pt_regs, ARM_lr))
+ : "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;
+}
+
+#ifdef CONFIG_THUMB2_KERNEL
+
+static struct undef_hook kprobes_thumb16_break_hook = {
+ .instr_mask = 0xffff,
+ .instr_val = KPROBE_THUMB16_BREAKPOINT_INSTRUCTION,
+ .cpsr_mask = MODE_MASK,
+ .cpsr_val = SVC_MODE,
+ .fn = kprobe_trap_handler,
+};
+
+static struct undef_hook kprobes_thumb32_break_hook = {
+ .instr_mask = 0xffffffff,
+ .instr_val = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION,
+ .cpsr_mask = MODE_MASK,
+ .cpsr_val = SVC_MODE,
+ .fn = kprobe_trap_handler,
+};
+
+#else /* !CONFIG_THUMB2_KERNEL */
+
+static struct undef_hook kprobes_arm_break_hook = {
+ .instr_mask = 0x0fffffff,
+ .instr_val = KPROBE_ARM_BREAKPOINT_INSTRUCTION,
+ .cpsr_mask = MODE_MASK,
+ .cpsr_val = SVC_MODE,
+ .fn = kprobe_trap_handler,
+};
+
+#endif /* !CONFIG_THUMB2_KERNEL */
+
+int __init arch_init_kprobes()
+{
+ arm_probes_decode_init();
+#ifdef CONFIG_THUMB2_KERNEL
+ register_undef_hook(&kprobes_thumb16_break_hook);
+ register_undef_hook(&kprobes_thumb32_break_hook);
+#else
+ register_undef_hook(&kprobes_arm_break_hook);
+#endif
+ return 0;
+}
diff --git a/arch/arm/probes/kprobes/core.h b/arch/arm/probes/kprobes/core.h
new file mode 100644
index 000000000..ec5d1f20a
--- /dev/null
+++ b/arch/arm/probes/kprobes/core.h
@@ -0,0 +1,58 @@
+/*
+ * arch/arm/kernel/kprobes.h
+ *
+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
+ *
+ * Some contents moved here from arch/arm/include/asm/kprobes.h which is
+ * 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_KERNEL_KPROBES_H
+#define _ARM_KERNEL_KPROBES_H
+
+#include <asm/kprobes.h>
+#include "../decode.h"
+
+/*
+ * These undefined instructions must be unique and
+ * reserved solely for kprobes' use.
+ */
+#define KPROBE_ARM_BREAKPOINT_INSTRUCTION 0x07f001f8
+#define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION 0xde18
+#define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION 0xf7f0a018
+
+extern void kprobes_remove_breakpoint(void *addr, unsigned int insn);
+
+enum probes_insn __kprobes
+kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_probes_insn *asi,
+ const struct decode_header *h);
+
+typedef enum probes_insn (kprobe_decode_insn_t)(probes_opcode_t,
+ struct arch_probes_insn *,
+ bool,
+ const union decode_action *,
+ const struct decode_checker *[]);
+
+#ifdef CONFIG_THUMB2_KERNEL
+
+extern const union decode_action kprobes_t32_actions[];
+extern const union decode_action kprobes_t16_actions[];
+extern const struct decode_checker *kprobes_t32_checkers[];
+extern const struct decode_checker *kprobes_t16_checkers[];
+#else /* !CONFIG_THUMB2_KERNEL */
+
+extern const union decode_action kprobes_arm_actions[];
+extern const struct decode_checker *kprobes_arm_checkers[];
+
+#endif
+
+#endif /* _ARM_KERNEL_KPROBES_H */
diff --git a/arch/arm/probes/kprobes/opt-arm.c b/arch/arm/probes/kprobes/opt-arm.c
new file mode 100644
index 000000000..bcdecc254
--- /dev/null
+++ b/arch/arm/probes/kprobes/opt-arm.c
@@ -0,0 +1,370 @@
+/*
+ * Kernel Probes Jump Optimization (Optprobes)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2002, 2004
+ * Copyright (C) Hitachi Ltd., 2012
+ * Copyright (C) Huawei Inc., 2014
+ */
+
+#include <linux/kprobes.h>
+#include <linux/jump_label.h>
+#include <asm/kprobes.h>
+#include <asm/cacheflush.h>
+/* for arm_gen_branch */
+#include <asm/insn.h>
+/* for patch_text */
+#include <asm/patch.h>
+
+#include "core.h"
+
+/*
+ * See register_usage_flags. If the probed instruction doesn't use PC,
+ * we can copy it into template and have it executed directly without
+ * simulation or emulation.
+ */
+#define ARM_REG_PC 15
+#define can_kprobe_direct_exec(m) (!test_bit(ARM_REG_PC, &(m)))
+
+/*
+ * NOTE: the first sub and add instruction will be modified according
+ * to the stack cost of the instruction.
+ */
+asm (
+ ".global optprobe_template_entry\n"
+ "optprobe_template_entry:\n"
+ ".global optprobe_template_sub_sp\n"
+ "optprobe_template_sub_sp:"
+ " sub sp, sp, #0xff\n"
+ " stmia sp, {r0 - r14} \n"
+ ".global optprobe_template_add_sp\n"
+ "optprobe_template_add_sp:"
+ " add r3, sp, #0xff\n"
+ " str r3, [sp, #52]\n"
+ " mrs r4, cpsr\n"
+ " str r4, [sp, #64]\n"
+ " mov r1, sp\n"
+ " ldr r0, 1f\n"
+ " ldr r2, 2f\n"
+ /*
+ * AEABI requires an 8-bytes alignment stack. If
+ * SP % 8 != 0 (SP % 4 == 0 should be ensured),
+ * alloc more bytes here.
+ */
+ " and r4, sp, #4\n"
+ " sub sp, sp, r4\n"
+#if __LINUX_ARM_ARCH__ >= 5
+ " blx r2\n"
+#else
+ " mov lr, pc\n"
+ " mov pc, r2\n"
+#endif
+ " add sp, sp, r4\n"
+ " ldr r1, [sp, #64]\n"
+ " tst r1, #"__stringify(PSR_T_BIT)"\n"
+ " ldrne r2, [sp, #60]\n"
+ " orrne r2, #1\n"
+ " strne r2, [sp, #60] @ set bit0 of PC for thumb\n"
+ " msr cpsr_cxsf, r1\n"
+ ".global optprobe_template_restore_begin\n"
+ "optprobe_template_restore_begin:\n"
+ " ldmia sp, {r0 - r15}\n"
+ ".global optprobe_template_restore_orig_insn\n"
+ "optprobe_template_restore_orig_insn:\n"
+ " nop\n"
+ ".global optprobe_template_restore_end\n"
+ "optprobe_template_restore_end:\n"
+ " nop\n"
+ ".global optprobe_template_val\n"
+ "optprobe_template_val:\n"
+ "1: .long 0\n"
+ ".global optprobe_template_call\n"
+ "optprobe_template_call:\n"
+ "2: .long 0\n"
+ ".global optprobe_template_end\n"
+ "optprobe_template_end:\n");
+
+#define TMPL_VAL_IDX \
+ ((unsigned long *)&optprobe_template_val - (unsigned long *)&optprobe_template_entry)
+#define TMPL_CALL_IDX \
+ ((unsigned long *)&optprobe_template_call - (unsigned long *)&optprobe_template_entry)
+#define TMPL_END_IDX \
+ ((unsigned long *)&optprobe_template_end - (unsigned long *)&optprobe_template_entry)
+#define TMPL_ADD_SP \
+ ((unsigned long *)&optprobe_template_add_sp - (unsigned long *)&optprobe_template_entry)
+#define TMPL_SUB_SP \
+ ((unsigned long *)&optprobe_template_sub_sp - (unsigned long *)&optprobe_template_entry)
+#define TMPL_RESTORE_BEGIN \
+ ((unsigned long *)&optprobe_template_restore_begin - (unsigned long *)&optprobe_template_entry)
+#define TMPL_RESTORE_ORIGN_INSN \
+ ((unsigned long *)&optprobe_template_restore_orig_insn - (unsigned long *)&optprobe_template_entry)
+#define TMPL_RESTORE_END \
+ ((unsigned long *)&optprobe_template_restore_end - (unsigned long *)&optprobe_template_entry)
+
+/*
+ * ARM can always optimize an instruction when using ARM ISA, except
+ * instructions like 'str r0, [sp, r1]' which store to stack and unable
+ * to determine stack space consumption statically.
+ */
+int arch_prepared_optinsn(struct arch_optimized_insn *optinsn)
+{
+ return optinsn->insn != NULL;
+}
+
+/*
+ * In ARM ISA, kprobe opt always replace one instruction (4 bytes
+ * aligned and 4 bytes long). It is impossible to encounter another
+ * kprobe in the address range. So always return 0.
+ */
+int arch_check_optimized_kprobe(struct optimized_kprobe *op)
+{
+ return 0;
+}
+
+/* Caller must ensure addr & 3 == 0 */
+static int can_optimize(struct kprobe *kp)
+{
+ if (kp->ainsn.stack_space < 0)
+ return 0;
+ /*
+ * 255 is the biggest imm can be used in 'sub r0, r0, #<imm>'.
+ * Number larger than 255 needs special encoding.
+ */
+ if (kp->ainsn.stack_space > 255 - sizeof(struct pt_regs))
+ return 0;
+ return 1;
+}
+
+/* Free optimized instruction slot */
+static void
+__arch_remove_optimized_kprobe(struct optimized_kprobe *op, int dirty)
+{
+ if (op->optinsn.insn) {
+ free_optinsn_slot(op->optinsn.insn, dirty);
+ op->optinsn.insn = NULL;
+ }
+}
+
+extern void kprobe_handler(struct pt_regs *regs);
+
+static void
+optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
+{
+ unsigned long flags;
+ struct kprobe *p = &op->kp;
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ /* Save skipped registers */
+ regs->ARM_pc = (unsigned long)op->kp.addr;
+ regs->ARM_ORIG_r0 = ~0UL;
+
+ local_irq_save(flags);
+
+ if (kprobe_running()) {
+ kprobes_inc_nmissed_count(&op->kp);
+ } else {
+ __this_cpu_write(current_kprobe, &op->kp);
+ kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+ opt_pre_handler(&op->kp, regs);
+ __this_cpu_write(current_kprobe, NULL);
+ }
+
+ /*
+ * We singlestep the replaced instruction only when it can't be
+ * executed directly during restore.
+ */
+ if (!p->ainsn.kprobe_direct_exec)
+ op->kp.ainsn.insn_singlestep(p->opcode, &p->ainsn, regs);
+
+ local_irq_restore(flags);
+}
+
+int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig)
+{
+ kprobe_opcode_t *code;
+ unsigned long rel_chk;
+ unsigned long val;
+ unsigned long stack_protect = sizeof(struct pt_regs);
+
+ if (!can_optimize(orig))
+ return -EILSEQ;
+
+ code = get_optinsn_slot();
+ if (!code)
+ return -ENOMEM;
+
+ /*
+ * Verify if the address gap is in 32MiB range, because this uses
+ * a relative jump.
+ *
+ * kprobe opt use a 'b' instruction to branch to optinsn.insn.
+ * According to ARM manual, branch instruction is:
+ *
+ * 31 28 27 24 23 0
+ * +------+---+---+---+---+----------------+
+ * | cond | 1 | 0 | 1 | 0 | imm24 |
+ * +------+---+---+---+---+----------------+
+ *
+ * imm24 is a signed 24 bits integer. The real branch offset is computed
+ * by: imm32 = SignExtend(imm24:'00', 32);
+ *
+ * So the maximum forward branch should be:
+ * (0x007fffff << 2) = 0x01fffffc = 0x1fffffc
+ * The maximum backword branch should be:
+ * (0xff800000 << 2) = 0xfe000000 = -0x2000000
+ *
+ * We can simply check (rel & 0xfe000003):
+ * if rel is positive, (rel & 0xfe000000) shoule be 0
+ * if rel is negitive, (rel & 0xfe000000) should be 0xfe000000
+ * the last '3' is used for alignment checking.
+ */
+ rel_chk = (unsigned long)((long)code -
+ (long)orig->addr + 8) & 0xfe000003;
+
+ if ((rel_chk != 0) && (rel_chk != 0xfe000000)) {
+ /*
+ * Different from x86, we free code buf directly instead of
+ * calling __arch_remove_optimized_kprobe() because
+ * we have not fill any field in op.
+ */
+ free_optinsn_slot(code, 0);
+ return -ERANGE;
+ }
+
+ /* Copy arch-dep-instance from template. */
+ memcpy(code, &optprobe_template_entry,
+ TMPL_END_IDX * sizeof(kprobe_opcode_t));
+
+ /* Adjust buffer according to instruction. */
+ BUG_ON(orig->ainsn.stack_space < 0);
+
+ stack_protect += orig->ainsn.stack_space;
+
+ /* Should have been filtered by can_optimize(). */
+ BUG_ON(stack_protect > 255);
+
+ /* Create a 'sub sp, sp, #<stack_protect>' */
+ code[TMPL_SUB_SP] = __opcode_to_mem_arm(0xe24dd000 | stack_protect);
+ /* Create a 'add r3, sp, #<stack_protect>' */
+ code[TMPL_ADD_SP] = __opcode_to_mem_arm(0xe28d3000 | stack_protect);
+
+ /* Set probe information */
+ val = (unsigned long)op;
+ code[TMPL_VAL_IDX] = val;
+
+ /* Set probe function call */
+ val = (unsigned long)optimized_callback;
+ code[TMPL_CALL_IDX] = val;
+
+ /* If possible, copy insn and have it executed during restore */
+ orig->ainsn.kprobe_direct_exec = false;
+ if (can_kprobe_direct_exec(orig->ainsn.register_usage_flags)) {
+ kprobe_opcode_t final_branch = arm_gen_branch(
+ (unsigned long)(&code[TMPL_RESTORE_END]),
+ (unsigned long)(op->kp.addr) + 4);
+ if (final_branch != 0) {
+ /*
+ * Replace original 'ldmia sp, {r0 - r15}' with
+ * 'ldmia {r0 - r14}', restore all registers except pc.
+ */
+ code[TMPL_RESTORE_BEGIN] = __opcode_to_mem_arm(0xe89d7fff);
+
+ /* The original probed instruction */
+ code[TMPL_RESTORE_ORIGN_INSN] = __opcode_to_mem_arm(orig->opcode);
+
+ /* Jump back to next instruction */
+ code[TMPL_RESTORE_END] = __opcode_to_mem_arm(final_branch);
+ orig->ainsn.kprobe_direct_exec = true;
+ }
+ }
+
+ flush_icache_range((unsigned long)code,
+ (unsigned long)(&code[TMPL_END_IDX]));
+
+ /* Set op->optinsn.insn means prepared. */
+ op->optinsn.insn = code;
+ return 0;
+}
+
+void __kprobes arch_optimize_kprobes(struct list_head *oplist)
+{
+ struct optimized_kprobe *op, *tmp;
+
+ list_for_each_entry_safe(op, tmp, oplist, list) {
+ unsigned long insn;
+ WARN_ON(kprobe_disabled(&op->kp));
+
+ /*
+ * Backup instructions which will be replaced
+ * by jump address
+ */
+ memcpy(op->optinsn.copied_insn, op->kp.addr,
+ RELATIVEJUMP_SIZE);
+
+ insn = arm_gen_branch((unsigned long)op->kp.addr,
+ (unsigned long)op->optinsn.insn);
+ BUG_ON(insn == 0);
+
+ /*
+ * Make it a conditional branch if replaced insn
+ * is consitional
+ */
+ insn = (__mem_to_opcode_arm(
+ op->optinsn.copied_insn[0]) & 0xf0000000) |
+ (insn & 0x0fffffff);
+
+ /*
+ * Similar to __arch_disarm_kprobe, operations which
+ * removing breakpoints must be wrapped by stop_machine
+ * to avoid racing.
+ */
+ kprobes_remove_breakpoint(op->kp.addr, insn);
+
+ list_del_init(&op->list);
+ }
+}
+
+void arch_unoptimize_kprobe(struct optimized_kprobe *op)
+{
+ arch_arm_kprobe(&op->kp);
+}
+
+/*
+ * Recover original instructions and breakpoints from relative jumps.
+ * Caller must call with locking kprobe_mutex.
+ */
+void arch_unoptimize_kprobes(struct list_head *oplist,
+ struct list_head *done_list)
+{
+ struct optimized_kprobe *op, *tmp;
+
+ list_for_each_entry_safe(op, tmp, oplist, list) {
+ arch_unoptimize_kprobe(op);
+ list_move(&op->list, done_list);
+ }
+}
+
+int arch_within_optimized_kprobe(struct optimized_kprobe *op,
+ unsigned long addr)
+{
+ return ((unsigned long)op->kp.addr <= addr &&
+ (unsigned long)op->kp.addr + RELATIVEJUMP_SIZE > addr);
+}
+
+void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
+{
+ __arch_remove_optimized_kprobe(op, 1);
+}
diff --git a/arch/arm/probes/kprobes/test-arm.c b/arch/arm/probes/kprobes/test-arm.c
new file mode 100644
index 000000000..8866aedfd
--- /dev/null
+++ b/arch/arm/probes/kprobes/test-arm.c
@@ -0,0 +1,1366 @@
+/*
+ * arch/arm/kernel/kprobes-test-arm.c
+ *
+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.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/module.h>
+#include <asm/system_info.h>
+#include <asm/opcodes.h>
+#include <asm/probes.h>
+
+#include "test-core.h"
+
+
+#define TEST_ISA "32"
+
+#define TEST_ARM_TO_THUMB_INTERWORK_R(code1, reg, val, code2) \
+ TESTCASE_START(code1 #reg code2) \
+ TEST_ARG_REG(reg, val) \
+ TEST_ARG_REG(14, 99f) \
+ TEST_ARG_END("") \
+ "50: nop \n\t" \
+ "1: "code1 #reg code2" \n\t" \
+ " bx lr \n\t" \
+ ".thumb \n\t" \
+ "3: adr lr, 2f \n\t" \
+ " bx lr \n\t" \
+ ".arm \n\t" \
+ "2: nop \n\t" \
+ TESTCASE_END
+
+#define TEST_ARM_TO_THUMB_INTERWORK_P(code1, reg, val, code2) \
+ TESTCASE_START(code1 #reg code2) \
+ TEST_ARG_PTR(reg, val) \
+ TEST_ARG_REG(14, 99f) \
+ TEST_ARG_MEM(15, 3f+1) \
+ TEST_ARG_END("") \
+ "50: nop \n\t" \
+ "1: "code1 #reg code2" \n\t" \
+ " bx lr \n\t" \
+ ".thumb \n\t" \
+ "3: adr lr, 2f \n\t" \
+ " bx lr \n\t" \
+ ".arm \n\t" \
+ "2: nop \n\t" \
+ TESTCASE_END
+
+
+void kprobe_arm_test_cases(void)
+{
+ kprobe_test_flags = 0;
+
+ TEST_GROUP("Data-processing (register), (register-shifted register), (immediate)")
+
+#define _DATA_PROCESSING_DNM(op,s,val) \
+ TEST_RR( op "eq" s " r0, r",1, VAL1,", r",2, val, "") \
+ TEST_RR( op "ne" s " r1, r",1, VAL1,", r",2, val, ", lsl #3") \
+ TEST_RR( op "cs" s " r2, r",3, VAL1,", r",2, val, ", lsr #4") \
+ TEST_RR( op "cc" s " r3, r",3, VAL1,", r",2, val, ", asr #5") \
+ TEST_RR( op "mi" s " r4, r",5, VAL1,", r",2, N(val),", asr #6") \
+ TEST_RR( op "pl" s " r5, r",5, VAL1,", r",2, val, ", ror #7") \
+ TEST_RR( op "vs" s " r6, r",7, VAL1,", r",2, val, ", rrx") \
+ TEST_R( op "vc" s " r6, r",7, VAL1,", pc, lsl #3") \
+ TEST_R( op "vc" s " r6, r",7, VAL1,", sp, lsr #4") \
+ TEST_R( op "vc" s " r6, pc, r",7, VAL1,", asr #5") \
+ TEST_R( op "vc" s " r6, sp, r",7, VAL1,", ror #6") \
+ TEST_RRR( op "hi" s " r8, r",9, VAL1,", r",14,val, ", lsl r",0, 3,"")\
+ TEST_RRR( op "ls" s " r9, r",9, VAL1,", r",14,val, ", lsr r",7, 4,"")\
+ TEST_RRR( op "ge" s " r10, r",11,VAL1,", r",14,val, ", asr r",7, 5,"")\
+ TEST_RRR( op "lt" s " r11, r",11,VAL1,", r",14,N(val),", asr r",7, 6,"")\
+ TEST_RR( op "gt" s " r12, r13" ", r",14,val, ", ror r",14,7,"")\
+ TEST_RR( op "le" s " r14, r",0, val, ", r13" ", lsl r",14,8,"")\
+ TEST_R( op "eq" s " r0, r",11,VAL1,", #0xf5") \
+ TEST_R( op "ne" s " r11, r",0, VAL1,", #0xf5000000") \
+ TEST_R( op s " r7, r",8, VAL2,", #0x000af000") \
+ TEST( op s " r4, pc" ", #0x00005a00")
+
+#define DATA_PROCESSING_DNM(op,val) \
+ _DATA_PROCESSING_DNM(op,"",val) \
+ _DATA_PROCESSING_DNM(op,"s",val)
+
+#define DATA_PROCESSING_NM(op,val) \
+ TEST_RR( op "ne r",1, VAL1,", r",2, val, "") \
+ TEST_RR( op "eq r",1, VAL1,", r",2, val, ", lsl #3") \
+ TEST_RR( op "cc r",3, VAL1,", r",2, val, ", lsr #4") \
+ TEST_RR( op "cs r",3, VAL1,", r",2, val, ", asr #5") \
+ TEST_RR( op "pl r",5, VAL1,", r",2, N(val),", asr #6") \
+ TEST_RR( op "mi r",5, VAL1,", r",2, val, ", ror #7") \
+ TEST_RR( op "vc r",7, VAL1,", r",2, val, ", rrx") \
+ TEST_R ( op "vs r",7, VAL1,", pc, lsl #3") \
+ TEST_R ( op "vs r",7, VAL1,", sp, lsr #4") \
+ TEST_R( op "vs pc, r",7, VAL1,", asr #5") \
+ TEST_R( op "vs sp, r",7, VAL1,", ror #6") \
+ TEST_RRR( op "ls r",9, VAL1,", r",14,val, ", lsl r",0, 3,"") \
+ TEST_RRR( op "hi r",9, VAL1,", r",14,val, ", lsr r",7, 4,"") \
+ TEST_RRR( op "lt r",11,VAL1,", r",14,val, ", asr r",7, 5,"") \
+ TEST_RRR( op "ge r",11,VAL1,", r",14,N(val),", asr r",7, 6,"") \
+ TEST_RR( op "le r13" ", r",14,val, ", ror r",14,7,"") \
+ TEST_RR( op "gt r",0, val, ", r13" ", lsl r",14,8,"") \
+ TEST_R( op "eq r",11,VAL1,", #0xf5") \
+ TEST_R( op "ne r",0, VAL1,", #0xf5000000") \
+ TEST_R( op " r",8, VAL2,", #0x000af000")
+
+#define _DATA_PROCESSING_DM(op,s,val) \
+ TEST_R( op "eq" s " r0, r",1, val, "") \
+ TEST_R( op "ne" s " r1, r",1, val, ", lsl #3") \
+ TEST_R( op "cs" s " r2, r",3, val, ", lsr #4") \
+ TEST_R( op "cc" s " r3, r",3, val, ", asr #5") \
+ TEST_R( op "mi" s " r4, r",5, N(val),", asr #6") \
+ TEST_R( op "pl" s " r5, r",5, val, ", ror #7") \
+ TEST_R( op "vs" s " r6, r",10,val, ", rrx") \
+ TEST( op "vs" s " r7, pc, lsl #3") \
+ TEST( op "vs" s " r7, sp, lsr #4") \
+ TEST_RR( op "vc" s " r8, r",7, val, ", lsl r",0, 3,"") \
+ TEST_RR( op "hi" s " r9, r",9, val, ", lsr r",7, 4,"") \
+ TEST_RR( op "ls" s " r10, r",9, val, ", asr r",7, 5,"") \
+ TEST_RR( op "ge" s " r11, r",11,N(val),", asr r",7, 6,"") \
+ TEST_RR( op "lt" s " r12, r",11,val, ", ror r",14,7,"") \
+ TEST_R( op "gt" s " r14, r13" ", lsl r",14,8,"") \
+ TEST( op "eq" s " r0, #0xf5") \
+ TEST( op "ne" s " r11, #0xf5000000") \
+ TEST( op s " r7, #0x000af000") \
+ TEST( op s " r4, #0x00005a00")
+
+#define DATA_PROCESSING_DM(op,val) \
+ _DATA_PROCESSING_DM(op,"",val) \
+ _DATA_PROCESSING_DM(op,"s",val)
+
+ DATA_PROCESSING_DNM("and",0xf00f00ff)
+ DATA_PROCESSING_DNM("eor",0xf00f00ff)
+ DATA_PROCESSING_DNM("sub",VAL2)
+ DATA_PROCESSING_DNM("rsb",VAL2)
+ DATA_PROCESSING_DNM("add",VAL2)
+ DATA_PROCESSING_DNM("adc",VAL2)
+ DATA_PROCESSING_DNM("sbc",VAL2)
+ DATA_PROCESSING_DNM("rsc",VAL2)
+ DATA_PROCESSING_NM("tst",0xf00f00ff)
+ DATA_PROCESSING_NM("teq",0xf00f00ff)
+ DATA_PROCESSING_NM("cmp",VAL2)
+ DATA_PROCESSING_NM("cmn",VAL2)
+ DATA_PROCESSING_DNM("orr",0xf00f00ff)
+ DATA_PROCESSING_DM("mov",VAL2)
+ DATA_PROCESSING_DNM("bic",0xf00f00ff)
+ DATA_PROCESSING_DM("mvn",VAL2)
+
+ TEST("mov ip, sp") /* This has special case emulation code */
+
+ TEST_SUPPORTED("mov pc, #0x1000");
+ TEST_SUPPORTED("mov sp, #0x1000");
+ TEST_SUPPORTED("cmp pc, #0x1000");
+ TEST_SUPPORTED("cmp sp, #0x1000");
+
+ /* Data-processing with PC and a shift count in a register */
+ TEST_UNSUPPORTED(__inst_arm(0xe15c0f1e) " @ cmp r12, r14, asl pc")
+ TEST_UNSUPPORTED(__inst_arm(0xe1a0cf1e) " @ mov r12, r14, asl pc")
+ TEST_UNSUPPORTED(__inst_arm(0xe08caf1e) " @ add r10, r12, r14, asl pc")
+ TEST_UNSUPPORTED(__inst_arm(0xe151021f) " @ cmp r1, pc, lsl r2")
+ TEST_UNSUPPORTED(__inst_arm(0xe17f0211) " @ cmn pc, r1, lsl r2")
+ TEST_UNSUPPORTED(__inst_arm(0xe1a0121f) " @ mov r1, pc, lsl r2")
+ TEST_UNSUPPORTED(__inst_arm(0xe1a0f211) " @ mov pc, r1, lsl r2")
+ TEST_UNSUPPORTED(__inst_arm(0xe042131f) " @ sub r1, r2, pc, lsl r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe1cf1312) " @ bic r1, pc, r2, lsl r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe081f312) " @ add pc, r1, r2, lsl r3")
+
+ /* Data-processing with PC as a target and status registers updated */
+ TEST_UNSUPPORTED("movs pc, r1")
+ TEST_UNSUPPORTED("movs pc, r1, lsl r2")
+ TEST_UNSUPPORTED("movs pc, #0x10000")
+ TEST_UNSUPPORTED("adds pc, lr, r1")
+ TEST_UNSUPPORTED("adds pc, lr, r1, lsl r2")
+ TEST_UNSUPPORTED("adds pc, lr, #4")
+
+ /* Data-processing with SP as target */
+ TEST("add sp, sp, #16")
+ TEST("sub sp, sp, #8")
+ TEST("bic sp, sp, #0x20")
+ TEST("orr sp, sp, #0x20")
+ TEST_PR( "add sp, r",10,0,", r",11,4,"")
+ TEST_PRR("add sp, r",10,0,", r",11,4,", asl r",12,1,"")
+ TEST_P( "mov sp, r",10,0,"")
+ TEST_PR( "mov sp, r",10,0,", asl r",12,0,"")
+
+ /* Data-processing with PC as target */
+ TEST_BF( "add pc, pc, #2f-1b-8")
+ TEST_BF_R ("add pc, pc, r",14,2f-1f-8,"")
+ TEST_BF_R ("add pc, r",14,2f-1f-8,", pc")
+ TEST_BF_R ("mov pc, r",0,2f,"")
+ TEST_BF_R ("add pc, pc, r",14,(2f-1f-8)*2,", asr #1")
+ TEST_BB( "sub pc, pc, #1b-2b+8")
+#if __LINUX_ARM_ARCH__ == 6 && !defined(CONFIG_CPU_V7)
+ TEST_BB( "sub pc, pc, #1b-2b+8-2") /* UNPREDICTABLE before and after ARMv6 */
+#endif
+ TEST_BB_R( "sub pc, pc, r",14, 1f-2f+8,"")
+ TEST_BB_R( "rsb pc, r",14,1f-2f+8,", pc")
+ TEST_R( "add pc, pc, r",10,-2,", asl #1")
+#ifdef CONFIG_THUMB2_KERNEL
+ TEST_ARM_TO_THUMB_INTERWORK_R("add pc, pc, r",0,3f-1f-8+1,"")
+ TEST_ARM_TO_THUMB_INTERWORK_R("sub pc, r",0,3f+8+1,", #8")
+#endif
+ TEST_GROUP("Miscellaneous instructions")
+
+ TEST_RMASKED("mrs r",0,~PSR_IGNORE_BITS,", cpsr")
+ TEST_RMASKED("mrspl r",7,~PSR_IGNORE_BITS,", cpsr")
+ TEST_RMASKED("mrs r",14,~PSR_IGNORE_BITS,", cpsr")
+ TEST_UNSUPPORTED(__inst_arm(0xe10ff000) " @ mrs r15, cpsr")
+ TEST_UNSUPPORTED("mrs r0, spsr")
+ TEST_UNSUPPORTED("mrs lr, spsr")
+
+ TEST_UNSUPPORTED("msr cpsr, r0")
+ TEST_UNSUPPORTED("msr cpsr_f, lr")
+ TEST_UNSUPPORTED("msr spsr, r0")
+
+#if __LINUX_ARM_ARCH__ >= 5 || \
+ (__LINUX_ARM_ARCH__ == 4 && !defined(CONFIG_CPU_32v4))
+ TEST_BF_R("bx r",0,2f,"")
+ TEST_BB_R("bx r",7,2f,"")
+ TEST_BF_R("bxeq r",14,2f,"")
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 5
+ TEST_R("clz r0, r",0, 0x0,"")
+ TEST_R("clzeq r7, r",14,0x1,"")
+ TEST_R("clz lr, r",7, 0xffffffff,"")
+ TEST( "clz r4, sp")
+ TEST_UNSUPPORTED(__inst_arm(0x016fff10) " @ clz pc, r0")
+ TEST_UNSUPPORTED(__inst_arm(0x016f0f1f) " @ clz r0, pc")
+
+#if __LINUX_ARM_ARCH__ >= 6
+ TEST_UNSUPPORTED("bxj r0")
+#endif
+
+ TEST_BF_R("blx r",0,2f,"")
+ TEST_BB_R("blx r",7,2f,"")
+ TEST_BF_R("blxeq r",14,2f,"")
+ TEST_UNSUPPORTED(__inst_arm(0x0120003f) " @ blx pc")
+
+ TEST_RR( "qadd r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "qaddvs lr, r",9, VAL2,", r",8, VAL1,"")
+ TEST_R( "qadd lr, r",9, VAL2,", r13")
+ TEST_RR( "qsub r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "qsubvs lr, r",9, VAL2,", r",8, VAL1,"")
+ TEST_R( "qsub lr, r",9, VAL2,", r13")
+ TEST_RR( "qdadd r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "qdaddvs lr, r",9, VAL2,", r",8, VAL1,"")
+ TEST_R( "qdadd lr, r",9, VAL2,", r13")
+ TEST_RR( "qdsub r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "qdsubvs lr, r",9, VAL2,", r",8, VAL1,"")
+ TEST_R( "qdsub lr, r",9, VAL2,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe101f050) " @ qadd pc, r0, r1")
+ TEST_UNSUPPORTED(__inst_arm(0xe121f050) " @ qsub pc, r0, r1")
+ TEST_UNSUPPORTED(__inst_arm(0xe141f050) " @ qdadd pc, r0, r1")
+ TEST_UNSUPPORTED(__inst_arm(0xe161f050) " @ qdsub pc, r0, r1")
+ TEST_UNSUPPORTED(__inst_arm(0xe16f2050) " @ qdsub r2, r0, pc")
+ TEST_UNSUPPORTED(__inst_arm(0xe161205f) " @ qdsub r2, pc, r1")
+
+ TEST_UNSUPPORTED("bkpt 0xffff")
+ TEST_UNSUPPORTED("bkpt 0x0000")
+
+ TEST_UNSUPPORTED(__inst_arm(0xe1600070) " @ smc #0")
+
+ TEST_GROUP("Halfword multiply and multiply-accumulate")
+
+ TEST_RRR( "smlabb r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "smlabbge r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+ TEST_RR( "smlabb lr, r",1, VAL2,", r",2, VAL3,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe10f3281) " @ smlabb pc, r1, r2, r3")
+ TEST_RRR( "smlatb r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "smlatbge r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+ TEST_RR( "smlatb lr, r",1, VAL2,", r",2, VAL3,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe10f32a1) " @ smlatb pc, r1, r2, r3")
+ TEST_RRR( "smlabt r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "smlabtge r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+ TEST_RR( "smlabt lr, r",1, VAL2,", r",2, VAL3,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe10f32c1) " @ smlabt pc, r1, r2, r3")
+ TEST_RRR( "smlatt r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "smlattge r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+ TEST_RR( "smlatt lr, r",1, VAL2,", r",2, VAL3,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe10f32e1) " @ smlatt pc, r1, r2, r3")
+
+ TEST_RRR( "smlawb r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "smlawbge r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+ TEST_RR( "smlawb lr, r",1, VAL2,", r",2, VAL3,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe12f3281) " @ smlawb pc, r1, r2, r3")
+ TEST_RRR( "smlawt r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "smlawtge r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+ TEST_RR( "smlawt lr, r",1, VAL2,", r",2, VAL3,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe12f32c1) " @ smlawt pc, r1, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe12032cf) " @ smlawt r0, pc, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe1203fc1) " @ smlawt r0, r1, pc, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe120f2c1) " @ smlawt r0, r1, r2, pc")
+
+ TEST_RR( "smulwb r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "smulwbge r7, r",8, VAL3,", r",9, VAL1,"")
+ TEST_R( "smulwb lr, r",1, VAL2,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe12f02a1) " @ smulwb pc, r1, r2")
+ TEST_RR( "smulwt r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "smulwtge r7, r",8, VAL3,", r",9, VAL1,"")
+ TEST_R( "smulwt lr, r",1, VAL2,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe12f02e1) " @ smulwt pc, r1, r2")
+
+ TEST_RRRR( "smlalbb r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+ TEST_RRRR( "smlalbble r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+ TEST_RRR( "smlalbb r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe14f1382) " @ smlalbb pc, r1, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe141f382) " @ smlalbb r1, pc, r2, r3")
+ TEST_RRRR( "smlaltb r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+ TEST_RRRR( "smlaltble r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+ TEST_RRR( "smlaltb r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe14f13a2) " @ smlaltb pc, r1, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe141f3a2) " @ smlaltb r1, pc, r2, r3")
+ TEST_RRRR( "smlalbt r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+ TEST_RRRR( "smlalbtle r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+ TEST_RRR( "smlalbt r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe14f13c2) " @ smlalbt pc, r1, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe141f3c2) " @ smlalbt r1, pc, r2, r3")
+ TEST_RRRR( "smlaltt r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+ TEST_RRRR( "smlalttle r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+ TEST_RRR( "smlaltt r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe14f13e2) " @ smlalbb pc, r1, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe140f3e2) " @ smlalbb r0, pc, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe14013ef) " @ smlalbb r0, r1, pc, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe1401fe2) " @ smlalbb r0, r1, r2, pc")
+
+ TEST_RR( "smulbb r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "smulbbge r7, r",8, VAL3,", r",9, VAL1,"")
+ TEST_R( "smulbb lr, r",1, VAL2,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe16f0281) " @ smulbb pc, r1, r2")
+ TEST_RR( "smultb r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "smultbge r7, r",8, VAL3,", r",9, VAL1,"")
+ TEST_R( "smultb lr, r",1, VAL2,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe16f02a1) " @ smultb pc, r1, r2")
+ TEST_RR( "smulbt r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "smulbtge r7, r",8, VAL3,", r",9, VAL1,"")
+ TEST_R( "smulbt lr, r",1, VAL2,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe16f02c1) " @ smultb pc, r1, r2")
+ TEST_RR( "smultt r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "smulttge r7, r",8, VAL3,", r",9, VAL1,"")
+ TEST_R( "smultt lr, r",1, VAL2,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe16f02e1) " @ smultt pc, r1, r2")
+ TEST_UNSUPPORTED(__inst_arm(0xe16002ef) " @ smultt r0, pc, r2")
+ TEST_UNSUPPORTED(__inst_arm(0xe1600fe1) " @ smultt r0, r1, pc")
+#endif
+
+ TEST_GROUP("Multiply and multiply-accumulate")
+
+ TEST_RR( "mul r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "mulls r7, r",8, VAL2,", r",9, VAL2,"")
+ TEST_R( "mul lr, r",4, VAL3,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe00f0291) " @ mul pc, r1, r2")
+ TEST_UNSUPPORTED(__inst_arm(0xe000029f) " @ mul r0, pc, r2")
+ TEST_UNSUPPORTED(__inst_arm(0xe0000f91) " @ mul r0, r1, pc")
+ TEST_RR( "muls r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "mullss r7, r",8, VAL2,", r",9, VAL2,"")
+ TEST_R( "muls lr, r",4, VAL3,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe01f0291) " @ muls pc, r1, r2")
+
+ TEST_RRR( "mla r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "mlahi r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+ TEST_RR( "mla lr, r",1, VAL2,", r",2, VAL3,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe02f3291) " @ mla pc, r1, r2, r3")
+ TEST_RRR( "mlas r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "mlahis r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+ TEST_RR( "mlas lr, r",1, VAL2,", r",2, VAL3,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe03f3291) " @ mlas pc, r1, r2, r3")
+
+#if __LINUX_ARM_ARCH__ >= 6
+ TEST_RR( "umaal r0, r1, r",2, VAL1,", r",3, VAL2,"")
+ TEST_RR( "umaalls r7, r8, r",9, VAL2,", r",10, VAL1,"")
+ TEST_R( "umaal lr, r12, r",11,VAL3,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe041f392) " @ umaal pc, r1, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe04f0392) " @ umaal r0, pc, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe0500090) " @ undef")
+ TEST_UNSUPPORTED(__inst_arm(0xe05fff9f) " @ undef")
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 7
+ TEST_RRR( "mls r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "mlshi r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+ TEST_RR( "mls lr, r",1, VAL2,", r",2, VAL3,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe06f3291) " @ mls pc, r1, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe060329f) " @ mls r0, pc, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe0603f91) " @ mls r0, r1, pc, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe060f291) " @ mls r0, r1, r2, pc")
+#endif
+
+ TEST_UNSUPPORTED(__inst_arm(0xe0700090) " @ undef")
+ TEST_UNSUPPORTED(__inst_arm(0xe07fff9f) " @ undef")
+
+ TEST_RR( "umull r0, r1, r",2, VAL1,", r",3, VAL2,"")
+ TEST_RR( "umullls r7, r8, r",9, VAL2,", r",10, VAL1,"")
+ TEST_R( "umull lr, r12, r",11,VAL3,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe081f392) " @ umull pc, r1, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe08f1392) " @ umull r1, pc, r2, r3")
+ TEST_RR( "umulls r0, r1, r",2, VAL1,", r",3, VAL2,"")
+ TEST_RR( "umulllss r7, r8, r",9, VAL2,", r",10, VAL1,"")
+ TEST_R( "umulls lr, r12, r",11,VAL3,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe091f392) " @ umulls pc, r1, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe09f1392) " @ umulls r1, pc, r2, r3")
+
+ TEST_RRRR( "umlal r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+ TEST_RRRR( "umlalle r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+ TEST_RRR( "umlal r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe0af1392) " @ umlal pc, r1, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe0a1f392) " @ umlal r1, pc, r2, r3")
+ TEST_RRRR( "umlals r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+ TEST_RRRR( "umlalles r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+ TEST_RRR( "umlals r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe0bf1392) " @ umlals pc, r1, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe0b1f392) " @ umlals r1, pc, r2, r3")
+
+ TEST_RR( "smull r0, r1, r",2, VAL1,", r",3, VAL2,"")
+ TEST_RR( "smullls r7, r8, r",9, VAL2,", r",10, VAL1,"")
+ TEST_R( "smull lr, r12, r",11,VAL3,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe0c1f392) " @ smull pc, r1, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe0cf1392) " @ smull r1, pc, r2, r3")
+ TEST_RR( "smulls r0, r1, r",2, VAL1,", r",3, VAL2,"")
+ TEST_RR( "smulllss r7, r8, r",9, VAL2,", r",10, VAL1,"")
+ TEST_R( "smulls lr, r12, r",11,VAL3,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe0d1f392) " @ smulls pc, r1, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe0df1392) " @ smulls r1, pc, r2, r3")
+
+ TEST_RRRR( "smlal r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+ TEST_RRRR( "smlalle r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+ TEST_RRR( "smlal r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe0ef1392) " @ smlal pc, r1, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe0e1f392) " @ smlal r1, pc, r2, r3")
+ TEST_RRRR( "smlals r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+ TEST_RRRR( "smlalles r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+ TEST_RRR( "smlals r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13")
+ TEST_UNSUPPORTED(__inst_arm(0xe0ff1392) " @ smlals pc, r1, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe0f0f392) " @ smlals r0, pc, r2, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe0f0139f) " @ smlals r0, r1, pc, r3")
+ TEST_UNSUPPORTED(__inst_arm(0xe0f01f92) " @ smlals r0, r1, r2, pc")
+
+ TEST_GROUP("Synchronization primitives")
+
+#if __LINUX_ARM_ARCH__ < 6
+ TEST_RP("swp lr, r",7,VAL2,", [r",8,0,"]")
+ TEST_R( "swpvs r0, r",1,VAL1,", [sp]")
+ TEST_RP("swp sp, r",14,VAL2,", [r",12,13*4,"]")
+#else
+ TEST_UNSUPPORTED(__inst_arm(0xe108e097) " @ swp lr, r7, [r8]")
+ TEST_UNSUPPORTED(__inst_arm(0x610d0091) " @ swpvs r0, r1, [sp]")
+ TEST_UNSUPPORTED(__inst_arm(0xe10cd09e) " @ swp sp, r14 [r12]")
+#endif
+ TEST_UNSUPPORTED(__inst_arm(0xe102f091) " @ swp pc, r1, [r2]")
+ TEST_UNSUPPORTED(__inst_arm(0xe102009f) " @ swp r0, pc, [r2]")
+ TEST_UNSUPPORTED(__inst_arm(0xe10f0091) " @ swp r0, r1, [pc]")
+#if __LINUX_ARM_ARCH__ < 6
+ TEST_RP("swpb lr, r",7,VAL2,", [r",8,0,"]")
+ TEST_R( "swpvsb r0, r",1,VAL1,", [sp]")
+#else
+ TEST_UNSUPPORTED(__inst_arm(0xe148e097) " @ swpb lr, r7, [r8]")
+ TEST_UNSUPPORTED(__inst_arm(0x614d0091) " @ swpvsb r0, r1, [sp]")
+#endif
+ TEST_UNSUPPORTED(__inst_arm(0xe142f091) " @ swpb pc, r1, [r2]")
+
+ TEST_UNSUPPORTED(__inst_arm(0xe1100090)) /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe1200090)) /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe1300090)) /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe1500090)) /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe1600090)) /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe1700090)) /* Unallocated space */
+#if __LINUX_ARM_ARCH__ >= 6
+ TEST_UNSUPPORTED("ldrex r2, [sp]")
+#endif
+#if (__LINUX_ARM_ARCH__ >= 7) || defined(CONFIG_CPU_32v6K)
+ TEST_UNSUPPORTED("strexd r0, r2, r3, [sp]")
+ TEST_UNSUPPORTED("ldrexd r2, r3, [sp]")
+ TEST_UNSUPPORTED("strexb r0, r2, [sp]")
+ TEST_UNSUPPORTED("ldrexb r2, [sp]")
+ TEST_UNSUPPORTED("strexh r0, r2, [sp]")
+ TEST_UNSUPPORTED("ldrexh r2, [sp]")
+#endif
+ TEST_GROUP("Extra load/store instructions")
+
+ TEST_RPR( "strh r",0, VAL1,", [r",1, 48,", -r",2, 24,"]")
+ TEST_RPR( "streqh r",14,VAL2,", [r",11,0, ", r",12, 48,"]")
+ TEST_UNSUPPORTED( "streqh r14, [r13, r12]")
+ TEST_UNSUPPORTED( "streqh r14, [r12, r13]")
+ TEST_RPR( "strh r",1, VAL1,", [r",2, 24,", r",3, 48,"]!")
+ TEST_RPR( "strneh r",12,VAL2,", [r",11,48,", -r",10,24,"]!")
+ TEST_RPR( "strh r",2, VAL1,", [r",3, 24,"], r",4, 48,"")
+ TEST_RPR( "strh r",10,VAL2,", [r",9, 48,"], -r",11,24,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe1afc0ba) " @ strh r12, [pc, r10]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe089f0bb) " @ strh pc, [r9], r11")
+ TEST_UNSUPPORTED(__inst_arm(0xe089a0bf) " @ strh r10, [r9], pc")
+
+ TEST_PR( "ldrh r0, [r",0, 48,", -r",2, 24,"]")
+ TEST_PR( "ldrcsh r14, [r",13,0, ", r",12, 48,"]")
+ TEST_PR( "ldrh r1, [r",2, 24,", r",3, 48,"]!")
+ TEST_PR( "ldrcch r12, [r",11,48,", -r",10,24,"]!")
+ TEST_PR( "ldrh r2, [r",3, 24,"], r",4, 48,"")
+ TEST_PR( "ldrh r10, [r",9, 48,"], -r",11,24,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe1bfc0ba) " @ ldrh r12, [pc, r10]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe099f0bb) " @ ldrh pc, [r9], r11")
+ TEST_UNSUPPORTED(__inst_arm(0xe099a0bf) " @ ldrh r10, [r9], pc")
+
+ TEST_RP( "strh r",0, VAL1,", [r",1, 24,", #-2]")
+ TEST_RP( "strmih r",14,VAL2,", [r",13,0, ", #2]")
+ TEST_RP( "strh r",1, VAL1,", [r",2, 24,", #4]!")
+ TEST_RP( "strplh r",12,VAL2,", [r",11,24,", #-4]!")
+ TEST_RP( "strh r",2, VAL1,", [r",3, 24,"], #48")
+ TEST_RP( "strh r",10,VAL2,", [r",9, 64,"], #-48")
+ TEST_RP( "strh r",3, VAL1,", [r",13,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!")
+ TEST_UNSUPPORTED("strh r3, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!")
+ TEST_RP( "strh r",4, VAL1,", [r",14,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe1efc3b0) " @ strh r12, [pc, #48]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe0c9f3b0) " @ strh pc, [r9], #48")
+
+ TEST_P( "ldrh r0, [r",0, 24,", #-2]")
+ TEST_P( "ldrvsh r14, [r",13,0, ", #2]")
+ TEST_P( "ldrh r1, [r",2, 24,", #4]!")
+ TEST_P( "ldrvch r12, [r",11,24,", #-4]!")
+ TEST_P( "ldrh r2, [r",3, 24,"], #48")
+ TEST_P( "ldrh r10, [r",9, 64,"], #-48")
+ TEST( "ldrh r0, [pc, #0]")
+ TEST_UNSUPPORTED(__inst_arm(0xe1ffc3b0) " @ ldrh r12, [pc, #48]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe0d9f3b0) " @ ldrh pc, [r9], #48")
+
+ TEST_PR( "ldrsb r0, [r",0, 48,", -r",2, 24,"]")
+ TEST_PR( "ldrhisb r14, [r",13,0,", r",12, 48,"]")
+ TEST_PR( "ldrsb r1, [r",2, 24,", r",3, 48,"]!")
+ TEST_PR( "ldrlssb r12, [r",11,48,", -r",10,24,"]!")
+ TEST_PR( "ldrsb r2, [r",3, 24,"], r",4, 48,"")
+ TEST_PR( "ldrsb r10, [r",9, 48,"], -r",11,24,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe1bfc0da) " @ ldrsb r12, [pc, r10]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe099f0db) " @ ldrsb pc, [r9], r11")
+
+ TEST_P( "ldrsb r0, [r",0, 24,", #-1]")
+ TEST_P( "ldrgesb r14, [r",13,0, ", #1]")
+ TEST_P( "ldrsb r1, [r",2, 24,", #4]!")
+ TEST_P( "ldrltsb r12, [r",11,24,", #-4]!")
+ TEST_P( "ldrsb r2, [r",3, 24,"], #48")
+ TEST_P( "ldrsb r10, [r",9, 64,"], #-48")
+ TEST( "ldrsb r0, [pc, #0]")
+ TEST_UNSUPPORTED(__inst_arm(0xe1ffc3d0) " @ ldrsb r12, [pc, #48]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe0d9f3d0) " @ ldrsb pc, [r9], #48")
+
+ TEST_PR( "ldrsh r0, [r",0, 48,", -r",2, 24,"]")
+ TEST_PR( "ldrgtsh r14, [r",13,0, ", r",12, 48,"]")
+ TEST_PR( "ldrsh r1, [r",2, 24,", r",3, 48,"]!")
+ TEST_PR( "ldrlesh r12, [r",11,48,", -r",10,24,"]!")
+ TEST_PR( "ldrsh r2, [r",3, 24,"], r",4, 48,"")
+ TEST_PR( "ldrsh r10, [r",9, 48,"], -r",11,24,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe1bfc0fa) " @ ldrsh r12, [pc, r10]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe099f0fb) " @ ldrsh pc, [r9], r11")
+
+ TEST_P( "ldrsh r0, [r",0, 24,", #-1]")
+ TEST_P( "ldreqsh r14, [r",13,0 ,", #1]")
+ TEST_P( "ldrsh r1, [r",2, 24,", #4]!")
+ TEST_P( "ldrnesh r12, [r",11,24,", #-4]!")
+ TEST_P( "ldrsh r2, [r",3, 24,"], #48")
+ TEST_P( "ldrsh r10, [r",9, 64,"], #-48")
+ TEST( "ldrsh r0, [pc, #0]")
+ TEST_UNSUPPORTED(__inst_arm(0xe1ffc3f0) " @ ldrsh r12, [pc, #48]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe0d9f3f0) " @ ldrsh pc, [r9], #48")
+
+#if __LINUX_ARM_ARCH__ >= 7
+ TEST_UNSUPPORTED("strht r1, [r2], r3")
+ TEST_UNSUPPORTED("ldrht r1, [r2], r3")
+ TEST_UNSUPPORTED("strht r1, [r2], #48")
+ TEST_UNSUPPORTED("ldrht r1, [r2], #48")
+ TEST_UNSUPPORTED("ldrsbt r1, [r2], r3")
+ TEST_UNSUPPORTED("ldrsbt r1, [r2], #48")
+ TEST_UNSUPPORTED("ldrsht r1, [r2], r3")
+ TEST_UNSUPPORTED("ldrsht r1, [r2], #48")
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 5
+ TEST_RPR( "strd r",0, VAL1,", [r",1, 48,", -r",2,24,"]")
+ TEST_RPR( "strccd r",8, VAL2,", [r",11,0, ", r",12,48,"]")
+ TEST_UNSUPPORTED( "strccd r8, [r13, r12]")
+ TEST_UNSUPPORTED( "strccd r8, [r12, r13]")
+ TEST_RPR( "strd r",4, VAL1,", [r",2, 24,", r",3, 48,"]!")
+ TEST_RPR( "strcsd r",12,VAL2,", [r",11,48,", -r",10,24,"]!")
+ TEST_RPR( "strd r",2, VAL1,", [r",5, 24,"], r",4,48,"")
+ TEST_RPR( "strd r",10,VAL2,", [r",9, 48,"], -r",7,24,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe1afc0fa) " @ strd r12, [pc, r10]!")
+
+ TEST_PR( "ldrd r0, [r",0, 48,", -r",2,24,"]")
+ TEST_PR( "ldrmid r8, [r",13,0, ", r",12,48,"]")
+ TEST_PR( "ldrd r4, [r",2, 24,", r",3, 48,"]!")
+ TEST_PR( "ldrpld r6, [r",11,48,", -r",10,24,"]!")
+ TEST_PR( "ldrd r2, [r",5, 24,"], r",4,48,"")
+ TEST_PR( "ldrd r10, [r",9,48,"], -r",7,24,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe1afc0da) " @ ldrd r12, [pc, r10]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe089f0db) " @ ldrd pc, [r9], r11")
+ TEST_UNSUPPORTED(__inst_arm(0xe089e0db) " @ ldrd lr, [r9], r11")
+ TEST_UNSUPPORTED(__inst_arm(0xe089c0df) " @ ldrd r12, [r9], pc")
+
+ TEST_RP( "strd r",0, VAL1,", [r",1, 24,", #-8]")
+ TEST_RP( "strvsd r",8, VAL2,", [r",13,0, ", #8]")
+ TEST_RP( "strd r",4, VAL1,", [r",2, 24,", #16]!")
+ TEST_RP( "strvcd r",12,VAL2,", [r",11,24,", #-16]!")
+ TEST_RP( "strd r",2, VAL1,", [r",4, 24,"], #48")
+ TEST_RP( "strd r",10,VAL2,", [r",9, 64,"], #-48")
+ TEST_RP( "strd r",6, VAL1,", [r",13,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!")
+ TEST_UNSUPPORTED("strd r6, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!")
+ TEST_RP( "strd r",4, VAL1,", [r",12,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe1efc3f0) " @ strd r12, [pc, #48]!")
+
+ TEST_P( "ldrd r0, [r",0, 24,", #-8]")
+ TEST_P( "ldrhid r8, [r",13,0, ", #8]")
+ TEST_P( "ldrd r4, [r",2, 24,", #16]!")
+ TEST_P( "ldrlsd r6, [r",11,24,", #-16]!")
+ TEST_P( "ldrd r2, [r",5, 24,"], #48")
+ TEST_P( "ldrd r10, [r",9,6,"], #-48")
+ TEST_UNSUPPORTED(__inst_arm(0xe1efc3d0) " @ ldrd r12, [pc, #48]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe0c9f3d0) " @ ldrd pc, [r9], #48")
+ TEST_UNSUPPORTED(__inst_arm(0xe0c9e3d0) " @ ldrd lr, [r9], #48")
+#endif
+
+ TEST_GROUP("Miscellaneous")
+
+#if __LINUX_ARM_ARCH__ >= 7
+ TEST("movw r0, #0")
+ TEST("movw r0, #0xffff")
+ TEST("movw lr, #0xffff")
+ TEST_UNSUPPORTED(__inst_arm(0xe300f000) " @ movw pc, #0")
+ TEST_R("movt r",0, VAL1,", #0")
+ TEST_R("movt r",0, VAL2,", #0xffff")
+ TEST_R("movt r",14,VAL1,", #0xffff")
+ TEST_UNSUPPORTED(__inst_arm(0xe340f000) " @ movt pc, #0")
+#endif
+
+ TEST_UNSUPPORTED("msr cpsr, 0x13")
+ TEST_UNSUPPORTED("msr cpsr_f, 0xf0000000")
+ TEST_UNSUPPORTED("msr spsr, 0x13")
+
+#if __LINUX_ARM_ARCH__ >= 7
+ TEST_SUPPORTED("yield")
+ TEST("sev")
+ TEST("nop")
+ TEST("wfi")
+ TEST_SUPPORTED("wfe")
+ TEST_UNSUPPORTED("dbg #0")
+#endif
+
+ TEST_GROUP("Load/store word and unsigned byte")
+
+#define LOAD_STORE(byte) \
+ TEST_RP( "str"byte" r",0, VAL1,", [r",1, 24,", #-2]") \
+ TEST_RP( "str"byte" r",14,VAL2,", [r",13,0, ", #2]") \
+ TEST_RP( "str"byte" r",1, VAL1,", [r",2, 24,", #4]!") \
+ TEST_RP( "str"byte" r",12,VAL2,", [r",11,24,", #-4]!") \
+ TEST_RP( "str"byte" r",2, VAL1,", [r",3, 24,"], #48") \
+ TEST_RP( "str"byte" r",10,VAL2,", [r",9, 64,"], #-48") \
+ TEST_RP( "str"byte" r",3, VAL1,", [r",13,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!") \
+ TEST_UNSUPPORTED("str"byte" r3, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!") \
+ TEST_RP( "str"byte" r",4, VAL1,", [r",10,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!") \
+ TEST_RPR("str"byte" r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") \
+ TEST_RPR("str"byte" r",14,VAL2,", [r",11,0, ", r",12, 48,"]") \
+ TEST_UNSUPPORTED("str"byte" r14, [r13, r12]") \
+ TEST_UNSUPPORTED("str"byte" r14, [r12, r13]") \
+ TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") \
+ TEST_RPR("str"byte" r",12,VAL2,", [r",11,48,", -r",10,24,"]!") \
+ TEST_RPR("str"byte" r",2, VAL1,", [r",3, 24,"], r",4, 48,"") \
+ TEST_RPR("str"byte" r",10,VAL2,", [r",9, 48,"], -r",11,24,"") \
+ TEST_RPR("str"byte" r",0, VAL1,", [r",1, 24,", r",2, 32,", asl #1]")\
+ TEST_RPR("str"byte" r",14,VAL2,", [r",11,0, ", r",12, 32,", lsr #2]")\
+ TEST_UNSUPPORTED("str"byte" r14, [r13, r12, lsr #2]") \
+ TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 32,", asr #3]!")\
+ TEST_RPR("str"byte" r",12,VAL2,", [r",11,24,", r",10, 4,", ror #31]!")\
+ TEST_P( "ldr"byte" r0, [r",0, 24,", #-2]") \
+ TEST_P( "ldr"byte" r14, [r",13,0, ", #2]") \
+ TEST_P( "ldr"byte" r1, [r",2, 24,", #4]!") \
+ TEST_P( "ldr"byte" r12, [r",11,24,", #-4]!") \
+ TEST_P( "ldr"byte" r2, [r",3, 24,"], #48") \
+ TEST_P( "ldr"byte" r10, [r",9, 64,"], #-48") \
+ TEST_PR( "ldr"byte" r0, [r",0, 48,", -r",2, 24,"]") \
+ TEST_PR( "ldr"byte" r14, [r",13,0, ", r",12, 48,"]") \
+ TEST_PR( "ldr"byte" r1, [r",2, 24,", r",3, 48,"]!") \
+ TEST_PR( "ldr"byte" r12, [r",11,48,", -r",10,24,"]!") \
+ TEST_PR( "ldr"byte" r2, [r",3, 24,"], r",4, 48,"") \
+ TEST_PR( "ldr"byte" r10, [r",9, 48,"], -r",11,24,"") \
+ TEST_PR( "ldr"byte" r0, [r",0, 24,", r",2, 32,", asl #1]") \
+ TEST_PR( "ldr"byte" r14, [r",13,0, ", r",12, 32,", lsr #2]") \
+ TEST_PR( "ldr"byte" r1, [r",2, 24,", r",3, 32,", asr #3]!") \
+ TEST_PR( "ldr"byte" r12, [r",11,24,", r",10, 4,", ror #31]!") \
+ TEST( "ldr"byte" r0, [pc, #0]") \
+ TEST_R( "ldr"byte" r12, [pc, r",14,0,"]")
+
+ LOAD_STORE("")
+ TEST_P( "str pc, [r",0,0,", #15*4]")
+ TEST_UNSUPPORTED( "str pc, [sp, r2]")
+ TEST_BF( "ldr pc, [sp, #15*4]")
+ TEST_BF_R("ldr pc, [sp, r",2,15*4,"]")
+
+ TEST_P( "str sp, [r",0,0,", #13*4]")
+ TEST_UNSUPPORTED( "str sp, [sp, r2]")
+ TEST_BF( "ldr sp, [sp, #13*4]")
+ TEST_BF_R("ldr sp, [sp, r",2,13*4,"]")
+
+#ifdef CONFIG_THUMB2_KERNEL
+ TEST_ARM_TO_THUMB_INTERWORK_P("ldr pc, [r",0,0,", #15*4]")
+#endif
+ TEST_UNSUPPORTED(__inst_arm(0xe5af6008) " @ str r6, [pc, #8]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe7af6008) " @ str r6, [pc, r8]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe5bf6008) " @ ldr r6, [pc, #8]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe7bf6008) " @ ldr r6, [pc, r8]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe788600f) " @ str r6, [r8, pc]")
+ TEST_UNSUPPORTED(__inst_arm(0xe798600f) " @ ldr r6, [r8, pc]")
+
+ LOAD_STORE("b")
+ TEST_UNSUPPORTED(__inst_arm(0xe5f7f008) " @ ldrb pc, [r7, #8]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe7f7f008) " @ ldrb pc, [r7, r8]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe5ef6008) " @ strb r6, [pc, #8]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe7ef6008) " @ strb r6, [pc, r3]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe5ff6008) " @ ldrb r6, [pc, #8]!")
+ TEST_UNSUPPORTED(__inst_arm(0xe7ff6008) " @ ldrb r6, [pc, r3]!")
+
+ TEST_UNSUPPORTED("ldrt r0, [r1], #4")
+ TEST_UNSUPPORTED("ldrt r1, [r2], r3")
+ TEST_UNSUPPORTED("strt r2, [r3], #4")
+ TEST_UNSUPPORTED("strt r3, [r4], r5")
+ TEST_UNSUPPORTED("ldrbt r4, [r5], #4")
+ TEST_UNSUPPORTED("ldrbt r5, [r6], r7")
+ TEST_UNSUPPORTED("strbt r6, [r7], #4")
+ TEST_UNSUPPORTED("strbt r7, [r8], r9")
+
+#if __LINUX_ARM_ARCH__ >= 7
+ TEST_GROUP("Parallel addition and subtraction, signed")
+
+ TEST_UNSUPPORTED(__inst_arm(0xe6000010) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe60fffff) "") /* Unallocated space */
+
+ TEST_RR( "sadd16 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "sadd16 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe61cff1a) " @ sadd16 pc, r12, r10")
+ TEST_RR( "sasx r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "sasx r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe61cff3a) " @ sasx pc, r12, r10")
+ TEST_RR( "ssax r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "ssax r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe61cff5a) " @ ssax pc, r12, r10")
+ TEST_RR( "ssub16 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "ssub16 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe61cff7a) " @ ssub16 pc, r12, r10")
+ TEST_RR( "sadd8 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "sadd8 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe61cff9a) " @ sadd8 pc, r12, r10")
+ TEST_UNSUPPORTED(__inst_arm(0xe61000b0) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe61fffbf) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe61000d0) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe61fffdf) "") /* Unallocated space */
+ TEST_RR( "ssub8 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "ssub8 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe61cfffa) " @ ssub8 pc, r12, r10")
+
+ TEST_RR( "qadd16 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "qadd16 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe62cff1a) " @ qadd16 pc, r12, r10")
+ TEST_RR( "qasx r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "qasx r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe62cff3a) " @ qasx pc, r12, r10")
+ TEST_RR( "qsax r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "qsax r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe62cff5a) " @ qsax pc, r12, r10")
+ TEST_RR( "qsub16 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "qsub16 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe62cff7a) " @ qsub16 pc, r12, r10")
+ TEST_RR( "qadd8 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "qadd8 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe62cff9a) " @ qadd8 pc, r12, r10")
+ TEST_UNSUPPORTED(__inst_arm(0xe62000b0) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe62fffbf) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe62000d0) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe62fffdf) "") /* Unallocated space */
+ TEST_RR( "qsub8 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "qsub8 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe62cfffa) " @ qsub8 pc, r12, r10")
+
+ TEST_RR( "shadd16 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "shadd16 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe63cff1a) " @ shadd16 pc, r12, r10")
+ TEST_RR( "shasx r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "shasx r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe63cff3a) " @ shasx pc, r12, r10")
+ TEST_RR( "shsax r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "shsax r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe63cff5a) " @ shsax pc, r12, r10")
+ TEST_RR( "shsub16 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "shsub16 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe63cff7a) " @ shsub16 pc, r12, r10")
+ TEST_RR( "shadd8 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "shadd8 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe63cff9a) " @ shadd8 pc, r12, r10")
+ TEST_UNSUPPORTED(__inst_arm(0xe63000b0) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe63fffbf) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe63000d0) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe63fffdf) "") /* Unallocated space */
+ TEST_RR( "shsub8 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "shsub8 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe63cfffa) " @ shsub8 pc, r12, r10")
+
+ TEST_GROUP("Parallel addition and subtraction, unsigned")
+
+ TEST_UNSUPPORTED(__inst_arm(0xe6400010) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe64fffff) "") /* Unallocated space */
+
+ TEST_RR( "uadd16 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uadd16 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe65cff1a) " @ uadd16 pc, r12, r10")
+ TEST_RR( "uasx r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uasx r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe65cff3a) " @ uasx pc, r12, r10")
+ TEST_RR( "usax r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "usax r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe65cff5a) " @ usax pc, r12, r10")
+ TEST_RR( "usub16 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "usub16 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe65cff7a) " @ usub16 pc, r12, r10")
+ TEST_RR( "uadd8 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uadd8 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe65cff9a) " @ uadd8 pc, r12, r10")
+ TEST_UNSUPPORTED(__inst_arm(0xe65000b0) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe65fffbf) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe65000d0) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe65fffdf) "") /* Unallocated space */
+ TEST_RR( "usub8 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "usub8 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe65cfffa) " @ usub8 pc, r12, r10")
+
+ TEST_RR( "uqadd16 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uqadd16 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe66cff1a) " @ uqadd16 pc, r12, r10")
+ TEST_RR( "uqasx r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uqasx r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe66cff3a) " @ uqasx pc, r12, r10")
+ TEST_RR( "uqsax r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uqsax r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe66cff5a) " @ uqsax pc, r12, r10")
+ TEST_RR( "uqsub16 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uqsub16 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe66cff7a) " @ uqsub16 pc, r12, r10")
+ TEST_RR( "uqadd8 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uqadd8 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe66cff9a) " @ uqadd8 pc, r12, r10")
+ TEST_UNSUPPORTED(__inst_arm(0xe66000b0) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe66fffbf) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe66000d0) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe66fffdf) "") /* Unallocated space */
+ TEST_RR( "uqsub8 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uqsub8 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe66cfffa) " @ uqsub8 pc, r12, r10")
+
+ TEST_RR( "uhadd16 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uhadd16 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe67cff1a) " @ uhadd16 pc, r12, r10")
+ TEST_RR( "uhasx r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uhasx r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe67cff3a) " @ uhasx pc, r12, r10")
+ TEST_RR( "uhsax r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uhsax r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe67cff5a) " @ uhsax pc, r12, r10")
+ TEST_RR( "uhsub16 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uhsub16 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe67cff7a) " @ uhsub16 pc, r12, r10")
+ TEST_RR( "uhadd8 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uhadd8 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe67cff9a) " @ uhadd8 pc, r12, r10")
+ TEST_UNSUPPORTED(__inst_arm(0xe67000b0) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe67fffbf) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe67000d0) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe67fffdf) "") /* Unallocated space */
+ TEST_RR( "uhsub8 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uhsub8 r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe67cfffa) " @ uhsub8 pc, r12, r10")
+ TEST_UNSUPPORTED(__inst_arm(0xe67feffa) " @ uhsub8 r14, pc, r10")
+ TEST_UNSUPPORTED(__inst_arm(0xe67cefff) " @ uhsub8 r14, r12, pc")
+#endif /* __LINUX_ARM_ARCH__ >= 7 */
+
+#if __LINUX_ARM_ARCH__ >= 6
+ TEST_GROUP("Packing, unpacking, saturation, and reversal")
+
+ TEST_RR( "pkhbt r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "pkhbt r14,r",12, HH1,", r",10,HH2,", lsl #2")
+ TEST_UNSUPPORTED(__inst_arm(0xe68cf11a) " @ pkhbt pc, r12, r10, lsl #2")
+ TEST_RR( "pkhtb r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "pkhtb r14,r",12, HH1,", r",10,HH2,", asr #2")
+ TEST_UNSUPPORTED(__inst_arm(0xe68cf15a) " @ pkhtb pc, r12, r10, asr #2")
+ TEST_UNSUPPORTED(__inst_arm(0xe68fe15a) " @ pkhtb r14, pc, r10, asr #2")
+ TEST_UNSUPPORTED(__inst_arm(0xe68ce15f) " @ pkhtb r14, r12, pc, asr #2")
+ TEST_UNSUPPORTED(__inst_arm(0xe6900010) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe69fffdf) "") /* Unallocated space */
+
+ TEST_R( "ssat r0, #24, r",0, VAL1,"")
+ TEST_R( "ssat r14, #24, r",12, VAL2,"")
+ TEST_R( "ssat r0, #24, r",0, VAL1,", lsl #8")
+ TEST_R( "ssat r14, #24, r",12, VAL2,", asr #8")
+ TEST_UNSUPPORTED(__inst_arm(0xe6b7f01c) " @ ssat pc, #24, r12")
+
+ TEST_R( "usat r0, #24, r",0, VAL1,"")
+ TEST_R( "usat r14, #24, r",12, VAL2,"")
+ TEST_R( "usat r0, #24, r",0, VAL1,", lsl #8")
+ TEST_R( "usat r14, #24, r",12, VAL2,", asr #8")
+ TEST_UNSUPPORTED(__inst_arm(0xe6f7f01c) " @ usat pc, #24, r12")
+
+ TEST_RR( "sxtab16 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "sxtab16 r14,r",12, HH2,", r",10,HH1,", ror #8")
+ TEST_R( "sxtb16 r8, r",7, HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe68cf47a) " @ sxtab16 pc,r12, r10, ror #8")
+
+ TEST_RR( "sel r0, r",0, VAL1,", r",1, VAL2,"")
+ TEST_RR( "sel r14, r",12,VAL1,", r",10, VAL2,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe68cffba) " @ sel pc, r12, r10")
+ TEST_UNSUPPORTED(__inst_arm(0xe68fefba) " @ sel r14, pc, r10")
+ TEST_UNSUPPORTED(__inst_arm(0xe68cefbf) " @ sel r14, r12, pc")
+
+ TEST_R( "ssat16 r0, #12, r",0, HH1,"")
+ TEST_R( "ssat16 r14, #12, r",12, HH2,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe6abff3c) " @ ssat16 pc, #12, r12")
+
+ TEST_RR( "sxtab r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "sxtab r14,r",12, HH2,", r",10,HH1,", ror #8")
+ TEST_R( "sxtb r8, r",7, HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe6acf47a) " @ sxtab pc,r12, r10, ror #8")
+
+ TEST_R( "rev r0, r",0, VAL1,"")
+ TEST_R( "rev r14, r",12, VAL2,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe6bfff3c) " @ rev pc, r12")
+
+ TEST_RR( "sxtah r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "sxtah r14,r",12, HH2,", r",10,HH1,", ror #8")
+ TEST_R( "sxth r8, r",7, HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe6bcf47a) " @ sxtah pc,r12, r10, ror #8")
+
+ TEST_R( "rev16 r0, r",0, VAL1,"")
+ TEST_R( "rev16 r14, r",12, VAL2,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe6bfffbc) " @ rev16 pc, r12")
+
+ TEST_RR( "uxtab16 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uxtab16 r14,r",12, HH2,", r",10,HH1,", ror #8")
+ TEST_R( "uxtb16 r8, r",7, HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe6ccf47a) " @ uxtab16 pc,r12, r10, ror #8")
+
+ TEST_R( "usat16 r0, #12, r",0, HH1,"")
+ TEST_R( "usat16 r14, #12, r",12, HH2,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe6ecff3c) " @ usat16 pc, #12, r12")
+ TEST_UNSUPPORTED(__inst_arm(0xe6ecef3f) " @ usat16 r14, #12, pc")
+
+ TEST_RR( "uxtab r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uxtab r14,r",12, HH2,", r",10,HH1,", ror #8")
+ TEST_R( "uxtb r8, r",7, HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe6ecf47a) " @ uxtab pc,r12, r10, ror #8")
+
+#if __LINUX_ARM_ARCH__ >= 7
+ TEST_R( "rbit r0, r",0, VAL1,"")
+ TEST_R( "rbit r14, r",12, VAL2,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe6ffff3c) " @ rbit pc, r12")
+#endif
+
+ TEST_RR( "uxtah r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uxtah r14,r",12, HH2,", r",10,HH1,", ror #8")
+ TEST_R( "uxth r8, r",7, HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe6fff077) " @ uxth pc, r7")
+ TEST_UNSUPPORTED(__inst_arm(0xe6ff807f) " @ uxth r8, pc")
+ TEST_UNSUPPORTED(__inst_arm(0xe6fcf47a) " @ uxtah pc, r12, r10, ror #8")
+ TEST_UNSUPPORTED(__inst_arm(0xe6fce47f) " @ uxtah r14, r12, pc, ror #8")
+
+ TEST_R( "revsh r0, r",0, VAL1,"")
+ TEST_R( "revsh r14, r",12, VAL2,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe6ffff3c) " @ revsh pc, r12")
+ TEST_UNSUPPORTED(__inst_arm(0xe6ffef3f) " @ revsh r14, pc")
+
+ TEST_UNSUPPORTED(__inst_arm(0xe6900070) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe69fff7f) "") /* Unallocated space */
+
+ TEST_UNSUPPORTED(__inst_arm(0xe6d00070) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_arm(0xe6dfff7f) "") /* Unallocated space */
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
+
+#if __LINUX_ARM_ARCH__ >= 6
+ TEST_GROUP("Signed multiplies")
+
+ TEST_RRR( "smlad r0, r",0, HH1,", r",1, HH2,", r",2, VAL1,"")
+ TEST_RRR( "smlad r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe70f8a1c) " @ smlad pc, r12, r10, r8")
+ TEST_RRR( "smladx r0, r",0, HH1,", r",1, HH2,", r",2, VAL1,"")
+ TEST_RRR( "smladx r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe70f8a3c) " @ smladx pc, r12, r10, r8")
+
+ TEST_RR( "smuad r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "smuad r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe70ffa1c) " @ smuad pc, r12, r10")
+ TEST_RR( "smuadx r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "smuadx r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe70ffa3c) " @ smuadx pc, r12, r10")
+
+ TEST_RRR( "smlsd r0, r",0, HH1,", r",1, HH2,", r",2, VAL1,"")
+ TEST_RRR( "smlsd r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe70f8a5c) " @ smlsd pc, r12, r10, r8")
+ TEST_RRR( "smlsdx r0, r",0, HH1,", r",1, HH2,", r",2, VAL1,"")
+ TEST_RRR( "smlsdx r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe70f8a7c) " @ smlsdx pc, r12, r10, r8")
+
+ TEST_RR( "smusd r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "smusd r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe70ffa5c) " @ smusd pc, r12, r10")
+ TEST_RR( "smusdx r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "smusdx r14, r",12,HH2,", r",10,HH1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe70ffa7c) " @ smusdx pc, r12, r10")
+
+ TEST_RRRR( "smlald r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2)
+ TEST_RRRR( "smlald r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1)
+ TEST_UNSUPPORTED(__inst_arm(0xe74af819) " @ smlald pc, r10, r9, r8")
+ TEST_UNSUPPORTED(__inst_arm(0xe74fb819) " @ smlald r11, pc, r9, r8")
+ TEST_UNSUPPORTED(__inst_arm(0xe74ab81f) " @ smlald r11, r10, pc, r8")
+ TEST_UNSUPPORTED(__inst_arm(0xe74abf19) " @ smlald r11, r10, r9, pc")
+
+ TEST_RRRR( "smlaldx r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2)
+ TEST_RRRR( "smlaldx r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1)
+ TEST_UNSUPPORTED(__inst_arm(0xe74af839) " @ smlaldx pc, r10, r9, r8")
+ TEST_UNSUPPORTED(__inst_arm(0xe74fb839) " @ smlaldx r11, pc, r9, r8")
+
+ TEST_RRR( "smmla r0, r",0, VAL1,", r",1, VAL2,", r",2, VAL1,"")
+ TEST_RRR( "smmla r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe75f8a1c) " @ smmla pc, r12, r10, r8")
+ TEST_RRR( "smmlar r0, r",0, VAL1,", r",1, VAL2,", r",2, VAL1,"")
+ TEST_RRR( "smmlar r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe75f8a3c) " @ smmlar pc, r12, r10, r8")
+
+ TEST_RR( "smmul r0, r",0, VAL1,", r",1, VAL2,"")
+ TEST_RR( "smmul r14, r",12,VAL2,", r",10,VAL1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe75ffa1c) " @ smmul pc, r12, r10")
+ TEST_RR( "smmulr r0, r",0, VAL1,", r",1, VAL2,"")
+ TEST_RR( "smmulr r14, r",12,VAL2,", r",10,VAL1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe75ffa3c) " @ smmulr pc, r12, r10")
+
+ TEST_RRR( "smmls r0, r",0, VAL1,", r",1, VAL2,", r",2, VAL1,"")
+ TEST_RRR( "smmls r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe75f8adc) " @ smmls pc, r12, r10, r8")
+ TEST_RRR( "smmlsr r0, r",0, VAL1,", r",1, VAL2,", r",2, VAL1,"")
+ TEST_RRR( "smmlsr r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe75f8afc) " @ smmlsr pc, r12, r10, r8")
+ TEST_UNSUPPORTED(__inst_arm(0xe75e8aff) " @ smmlsr r14, pc, r10, r8")
+ TEST_UNSUPPORTED(__inst_arm(0xe75e8ffc) " @ smmlsr r14, r12, pc, r8")
+ TEST_UNSUPPORTED(__inst_arm(0xe75efafc) " @ smmlsr r14, r12, r10, pc")
+
+ TEST_RR( "usad8 r0, r",0, VAL1,", r",1, VAL2,"")
+ TEST_RR( "usad8 r14, r",12,VAL2,", r",10,VAL1,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe75ffa1c) " @ usad8 pc, r12, r10")
+ TEST_UNSUPPORTED(__inst_arm(0xe75efa1f) " @ usad8 r14, pc, r10")
+ TEST_UNSUPPORTED(__inst_arm(0xe75eff1c) " @ usad8 r14, r12, pc")
+
+ TEST_RRR( "usada8 r0, r",0, VAL1,", r",1, VAL2,", r",2, VAL3,"")
+ TEST_RRR( "usada8 r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL3,"")
+ TEST_UNSUPPORTED(__inst_arm(0xe78f8a1c) " @ usada8 pc, r12, r10, r8")
+ TEST_UNSUPPORTED(__inst_arm(0xe78e8a1f) " @ usada8 r14, pc, r10, r8")
+ TEST_UNSUPPORTED(__inst_arm(0xe78e8f1c) " @ usada8 r14, r12, pc, r8")
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
+
+#if __LINUX_ARM_ARCH__ >= 7
+ TEST_GROUP("Bit Field")
+
+ TEST_R( "sbfx r0, r",0 , VAL1,", #0, #31")
+ TEST_R( "sbfxeq r14, r",12, VAL2,", #8, #16")
+ TEST_R( "sbfx r4, r",10, VAL1,", #16, #15")
+ TEST_UNSUPPORTED(__inst_arm(0xe7aff45c) " @ sbfx pc, r12, #8, #16")
+
+ TEST_R( "ubfx r0, r",0 , VAL1,", #0, #31")
+ TEST_R( "ubfxcs r14, r",12, VAL2,", #8, #16")
+ TEST_R( "ubfx r4, r",10, VAL1,", #16, #15")
+ TEST_UNSUPPORTED(__inst_arm(0xe7eff45c) " @ ubfx pc, r12, #8, #16")
+ TEST_UNSUPPORTED(__inst_arm(0xe7efc45f) " @ ubfx r12, pc, #8, #16")
+
+ TEST_R( "bfc r",0, VAL1,", #4, #20")
+ TEST_R( "bfcvs r",14,VAL2,", #4, #20")
+ TEST_R( "bfc r",7, VAL1,", #0, #31")
+ TEST_R( "bfc r",8, VAL2,", #0, #31")
+ TEST_UNSUPPORTED(__inst_arm(0xe7def01f) " @ bfc pc, #0, #31");
+
+ TEST_RR( "bfi r",0, VAL1,", r",0 , VAL2,", #0, #31")
+ TEST_RR( "bfipl r",12,VAL1,", r",14 , VAL2,", #4, #20")
+ TEST_UNSUPPORTED(__inst_arm(0xe7d7f21e) " @ bfi pc, r14, #4, #20")
+
+ TEST_UNSUPPORTED(__inst_arm(0x07f000f0) "") /* Permanently UNDEFINED */
+ TEST_UNSUPPORTED(__inst_arm(0x07ffffff) "") /* Permanently UNDEFINED */
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
+
+ TEST_GROUP("Branch, branch with link, and block data transfer")
+
+ TEST_P( "stmda r",0, 16*4,", {r0}")
+ TEST_P( "stmeqda r",4, 16*4,", {r0-r15}")
+ TEST_P( "stmneda r",8, 16*4,"!, {r8-r15}")
+ TEST_P( "stmda r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+ TEST_P( "stmda r",13,0, "!, {pc}")
+
+ TEST_P( "ldmda r",0, 16*4,", {r0}")
+ TEST_BF_P("ldmcsda r",4, 15*4,", {r0-r15}")
+ TEST_BF_P("ldmccda r",7, 15*4,"!, {r8-r15}")
+ TEST_P( "ldmda r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+ TEST_BF_P("ldmda r",14,15*4,"!, {pc}")
+
+ TEST_P( "stmia r",0, 16*4,", {r0}")
+ TEST_P( "stmmiia r",4, 16*4,", {r0-r15}")
+ TEST_P( "stmplia r",8, 16*4,"!, {r8-r15}")
+ TEST_P( "stmia r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+ TEST_P( "stmia r",14,0, "!, {pc}")
+
+ TEST_P( "ldmia r",0, 16*4,", {r0}")
+ TEST_BF_P("ldmvsia r",4, 0, ", {r0-r15}")
+ TEST_BF_P("ldmvcia r",7, 8*4, "!, {r8-r15}")
+ TEST_P( "ldmia r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+ TEST_BF_P("ldmia r",14,15*4,"!, {pc}")
+
+ TEST_P( "stmdb r",0, 16*4,", {r0}")
+ TEST_P( "stmhidb r",4, 16*4,", {r0-r15}")
+ TEST_P( "stmlsdb r",8, 16*4,"!, {r8-r15}")
+ TEST_P( "stmdb r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+ TEST_P( "stmdb r",13,4, "!, {pc}")
+
+ TEST_P( "ldmdb r",0, 16*4,", {r0}")
+ TEST_BF_P("ldmgedb r",4, 16*4,", {r0-r15}")
+ TEST_BF_P("ldmltdb r",7, 16*4,"!, {r8-r15}")
+ TEST_P( "ldmdb r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+ TEST_BF_P("ldmdb r",14,16*4,"!, {pc}")
+
+ TEST_P( "stmib r",0, 16*4,", {r0}")
+ TEST_P( "stmgtib r",4, 16*4,", {r0-r15}")
+ TEST_P( "stmleib r",8, 16*4,"!, {r8-r15}")
+ TEST_P( "stmib r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+ TEST_P( "stmib r",13,-4, "!, {pc}")
+
+ TEST_P( "ldmib r",0, 16*4,", {r0}")
+ TEST_BF_P("ldmeqib r",4, -4,", {r0-r15}")
+ TEST_BF_P("ldmneib r",7, 7*4,"!, {r8-r15}")
+ TEST_P( "ldmib r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+ TEST_BF_P("ldmib r",14,14*4,"!, {pc}")
+
+ TEST_P( "stmdb r",13,16*4,"!, {r3-r12,lr}")
+ TEST_P( "stmeqdb r",13,16*4,"!, {r3-r12}")
+ TEST_P( "stmnedb r",2, 16*4,", {r3-r12,lr}")
+ TEST_P( "stmdb r",13,16*4,"!, {r2-r12,lr}")
+ TEST_P( "stmdb r",0, 16*4,", {r0-r12}")
+ TEST_P( "stmdb r",0, 16*4,", {r0-r12,lr}")
+
+ TEST_BF_P("ldmia r",13,5*4, "!, {r3-r12,pc}")
+ TEST_P( "ldmccia r",13,5*4, "!, {r3-r12}")
+ TEST_BF_P("ldmcsia r",2, 5*4, "!, {r3-r12,pc}")
+ TEST_BF_P("ldmia r",13,4*4, "!, {r2-r12,pc}")
+ TEST_P( "ldmia r",0, 16*4,", {r0-r12}")
+ TEST_P( "ldmia r",0, 16*4,", {r0-r12,lr}")
+
+#ifdef CONFIG_THUMB2_KERNEL
+ TEST_ARM_TO_THUMB_INTERWORK_P("ldmplia r",0,15*4,", {pc}")
+ TEST_ARM_TO_THUMB_INTERWORK_P("ldmmiia r",13,0,", {r0-r15}")
+#endif
+ TEST_BF("b 2f")
+ TEST_BF("bl 2f")
+ TEST_BB("b 2b")
+ TEST_BB("bl 2b")
+
+ TEST_BF("beq 2f")
+ TEST_BF("bleq 2f")
+ TEST_BB("bne 2b")
+ TEST_BB("blne 2b")
+
+ TEST_BF("bgt 2f")
+ TEST_BF("blgt 2f")
+ TEST_BB("blt 2b")
+ TEST_BB("bllt 2b")
+
+ TEST_GROUP("Supervisor Call, and coprocessor instructions")
+
+ /*
+ * We can't really test these by executing them, so all
+ * we can do is check that probes are, or are not allowed.
+ * At the moment none are allowed...
+ */
+#define TEST_COPROCESSOR(code) TEST_UNSUPPORTED(code)
+
+#define COPROCESSOR_INSTRUCTIONS_ST_LD(two,cc) \
+ TEST_COPROCESSOR("stc"two" 0, cr0, [r13, #4]") \
+ TEST_COPROCESSOR("stc"two" 0, cr0, [r13, #-4]") \
+ TEST_COPROCESSOR("stc"two" 0, cr0, [r13, #4]!") \
+ TEST_COPROCESSOR("stc"two" 0, cr0, [r13, #-4]!") \
+ TEST_COPROCESSOR("stc"two" 0, cr0, [r13], #4") \
+ TEST_COPROCESSOR("stc"two" 0, cr0, [r13], #-4") \
+ TEST_COPROCESSOR("stc"two" 0, cr0, [r13], {1}") \
+ TEST_COPROCESSOR("stc"two"l 0, cr0, [r13, #4]") \
+ TEST_COPROCESSOR("stc"two"l 0, cr0, [r13, #-4]") \
+ TEST_COPROCESSOR("stc"two"l 0, cr0, [r13, #4]!") \
+ TEST_COPROCESSOR("stc"two"l 0, cr0, [r13, #-4]!") \
+ TEST_COPROCESSOR("stc"two"l 0, cr0, [r13], #4") \
+ TEST_COPROCESSOR("stc"two"l 0, cr0, [r13], #-4") \
+ TEST_COPROCESSOR("stc"two"l 0, cr0, [r13], {1}") \
+ TEST_COPROCESSOR("ldc"two" 0, cr0, [r13, #4]") \
+ TEST_COPROCESSOR("ldc"two" 0, cr0, [r13, #-4]") \
+ TEST_COPROCESSOR("ldc"two" 0, cr0, [r13, #4]!") \
+ TEST_COPROCESSOR("ldc"two" 0, cr0, [r13, #-4]!") \
+ TEST_COPROCESSOR("ldc"two" 0, cr0, [r13], #4") \
+ TEST_COPROCESSOR("ldc"two" 0, cr0, [r13], #-4") \
+ TEST_COPROCESSOR("ldc"two" 0, cr0, [r13], {1}") \
+ TEST_COPROCESSOR("ldc"two"l 0, cr0, [r13, #4]") \
+ TEST_COPROCESSOR("ldc"two"l 0, cr0, [r13, #-4]") \
+ TEST_COPROCESSOR("ldc"two"l 0, cr0, [r13, #4]!") \
+ TEST_COPROCESSOR("ldc"two"l 0, cr0, [r13, #-4]!") \
+ TEST_COPROCESSOR("ldc"two"l 0, cr0, [r13], #4") \
+ TEST_COPROCESSOR("ldc"two"l 0, cr0, [r13], #-4") \
+ TEST_COPROCESSOR("ldc"two"l 0, cr0, [r13], {1}") \
+ \
+ TEST_COPROCESSOR( "stc"two" 0, cr0, [r15, #4]") \
+ TEST_COPROCESSOR( "stc"two" 0, cr0, [r15, #-4]") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##daf0001) " @ stc"two" 0, cr0, [r15, #4]!") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##d2f0001) " @ stc"two" 0, cr0, [r15, #-4]!") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##caf0001) " @ stc"two" 0, cr0, [r15], #4") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##c2f0001) " @ stc"two" 0, cr0, [r15], #-4") \
+ TEST_COPROCESSOR( "stc"two" 0, cr0, [r15], {1}") \
+ TEST_COPROCESSOR( "stc"two"l 0, cr0, [r15, #4]") \
+ TEST_COPROCESSOR( "stc"two"l 0, cr0, [r15, #-4]") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##def0001) " @ stc"two"l 0, cr0, [r15, #4]!") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##d6f0001) " @ stc"two"l 0, cr0, [r15, #-4]!") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##cef0001) " @ stc"two"l 0, cr0, [r15], #4") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##c6f0001) " @ stc"two"l 0, cr0, [r15], #-4") \
+ TEST_COPROCESSOR( "stc"two"l 0, cr0, [r15], {1}") \
+ TEST_COPROCESSOR( "ldc"two" 0, cr0, [r15, #4]") \
+ TEST_COPROCESSOR( "ldc"two" 0, cr0, [r15, #-4]") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##dbf0001) " @ ldc"two" 0, cr0, [r15, #4]!") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##d3f0001) " @ ldc"two" 0, cr0, [r15, #-4]!") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##cbf0001) " @ ldc"two" 0, cr0, [r15], #4") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##c3f0001) " @ ldc"two" 0, cr0, [r15], #-4") \
+ TEST_COPROCESSOR( "ldc"two" 0, cr0, [r15], {1}") \
+ TEST_COPROCESSOR( "ldc"two"l 0, cr0, [r15, #4]") \
+ TEST_COPROCESSOR( "ldc"two"l 0, cr0, [r15, #-4]") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##dff0001) " @ ldc"two"l 0, cr0, [r15, #4]!") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##d7f0001) " @ ldc"two"l 0, cr0, [r15, #-4]!") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##cff0001) " @ ldc"two"l 0, cr0, [r15], #4") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##c7f0001) " @ ldc"two"l 0, cr0, [r15], #-4") \
+ TEST_COPROCESSOR( "ldc"two"l 0, cr0, [r15], {1}")
+
+#define COPROCESSOR_INSTRUCTIONS_MC_MR(two,cc) \
+ \
+ TEST_COPROCESSOR( "mcrr"two" 0, 15, r0, r14, cr0") \
+ TEST_COPROCESSOR( "mcrr"two" 15, 0, r14, r0, cr15") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##c4f00f0) " @ mcrr"two" 0, 15, r0, r15, cr0") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##c40ff0f) " @ mcrr"two" 15, 0, r15, r0, cr15") \
+ TEST_COPROCESSOR( "mrrc"two" 0, 15, r0, r14, cr0") \
+ TEST_COPROCESSOR( "mrrc"two" 15, 0, r14, r0, cr15") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##c5f00f0) " @ mrrc"two" 0, 15, r0, r15, cr0") \
+ TEST_UNSUPPORTED(__inst_arm(0x##cc##c50ff0f) " @ mrrc"two" 15, 0, r15, r0, cr15") \
+ TEST_COPROCESSOR( "cdp"two" 15, 15, cr15, cr15, cr15, 7") \
+ TEST_COPROCESSOR( "cdp"two" 0, 0, cr0, cr0, cr0, 0") \
+ TEST_COPROCESSOR( "mcr"two" 15, 7, r15, cr15, cr15, 7") \
+ TEST_COPROCESSOR( "mcr"two" 0, 0, r0, cr0, cr0, 0") \
+ TEST_COPROCESSOR( "mrc"two" 15, 7, r15, cr15, cr15, 7") \
+ TEST_COPROCESSOR( "mrc"two" 0, 0, r0, cr0, cr0, 0")
+
+ COPROCESSOR_INSTRUCTIONS_ST_LD("",e)
+#if __LINUX_ARM_ARCH__ >= 5
+ COPROCESSOR_INSTRUCTIONS_MC_MR("",e)
+#endif
+ TEST_UNSUPPORTED("svc 0")
+ TEST_UNSUPPORTED("svc 0xffffff")
+
+ TEST_UNSUPPORTED("svc 0")
+
+ TEST_GROUP("Unconditional instruction")
+
+#if __LINUX_ARM_ARCH__ >= 6
+ TEST_UNSUPPORTED("srsda sp, 0x13")
+ TEST_UNSUPPORTED("srsdb sp, 0x13")
+ TEST_UNSUPPORTED("srsia sp, 0x13")
+ TEST_UNSUPPORTED("srsib sp, 0x13")
+ TEST_UNSUPPORTED("srsda sp!, 0x13")
+ TEST_UNSUPPORTED("srsdb sp!, 0x13")
+ TEST_UNSUPPORTED("srsia sp!, 0x13")
+ TEST_UNSUPPORTED("srsib sp!, 0x13")
+
+ TEST_UNSUPPORTED("rfeda sp")
+ TEST_UNSUPPORTED("rfedb sp")
+ TEST_UNSUPPORTED("rfeia sp")
+ TEST_UNSUPPORTED("rfeib sp")
+ TEST_UNSUPPORTED("rfeda sp!")
+ TEST_UNSUPPORTED("rfedb sp!")
+ TEST_UNSUPPORTED("rfeia sp!")
+ TEST_UNSUPPORTED("rfeib sp!")
+ TEST_UNSUPPORTED(__inst_arm(0xf81d0a00) " @ rfeda pc")
+ TEST_UNSUPPORTED(__inst_arm(0xf91d0a00) " @ rfedb pc")
+ TEST_UNSUPPORTED(__inst_arm(0xf89d0a00) " @ rfeia pc")
+ TEST_UNSUPPORTED(__inst_arm(0xf99d0a00) " @ rfeib pc")
+ TEST_UNSUPPORTED(__inst_arm(0xf83d0a00) " @ rfeda pc!")
+ TEST_UNSUPPORTED(__inst_arm(0xf93d0a00) " @ rfedb pc!")
+ TEST_UNSUPPORTED(__inst_arm(0xf8bd0a00) " @ rfeia pc!")
+ TEST_UNSUPPORTED(__inst_arm(0xf9bd0a00) " @ rfeib pc!")
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
+
+#if __LINUX_ARM_ARCH__ >= 6
+ TEST_X( "blx __dummy_thumb_subroutine_even",
+ ".thumb \n\t"
+ ".space 4 \n\t"
+ ".type __dummy_thumb_subroutine_even, %%function \n\t"
+ "__dummy_thumb_subroutine_even: \n\t"
+ "mov r0, pc \n\t"
+ "bx lr \n\t"
+ ".arm \n\t"
+ )
+ TEST( "blx __dummy_thumb_subroutine_even")
+
+ TEST_X( "blx __dummy_thumb_subroutine_odd",
+ ".thumb \n\t"
+ ".space 2 \n\t"
+ ".type __dummy_thumb_subroutine_odd, %%function \n\t"
+ "__dummy_thumb_subroutine_odd: \n\t"
+ "mov r0, pc \n\t"
+ "bx lr \n\t"
+ ".arm \n\t"
+ )
+ TEST( "blx __dummy_thumb_subroutine_odd")
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
+
+#if __LINUX_ARM_ARCH__ >= 5
+ COPROCESSOR_INSTRUCTIONS_ST_LD("2",f)
+#endif
+#if __LINUX_ARM_ARCH__ >= 6
+ COPROCESSOR_INSTRUCTIONS_MC_MR("2",f)
+#endif
+
+ TEST_GROUP("Miscellaneous instructions, memory hints, and Advanced SIMD instructions")
+
+#if __LINUX_ARM_ARCH__ >= 6
+ TEST_UNSUPPORTED("cps 0x13")
+ TEST_UNSUPPORTED("cpsie i")
+ TEST_UNSUPPORTED("cpsid i")
+ TEST_UNSUPPORTED("cpsie i,0x13")
+ TEST_UNSUPPORTED("cpsid i,0x13")
+ TEST_UNSUPPORTED("setend le")
+ TEST_UNSUPPORTED("setend be")
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 7
+ TEST_P("pli [r",0,0b,", #16]")
+ TEST( "pli [pc, #0]")
+ TEST_RR("pli [r",12,0b,", r",0, 16,"]")
+ TEST_RR("pli [r",0, 0b,", -r",12,16,", lsl #4]")
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 5
+ TEST_P("pld [r",0,32,", #-16]")
+ TEST( "pld [pc, #0]")
+ TEST_PR("pld [r",7, 24, ", r",0, 16,"]")
+ TEST_PR("pld [r",8, 24, ", -r",12,16,", lsl #4]")
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 7
+ TEST_SUPPORTED( __inst_arm(0xf590f000) " @ pldw [r0, #0]")
+ TEST_SUPPORTED( __inst_arm(0xf797f000) " @ pldw [r7, r0]")
+ TEST_SUPPORTED( __inst_arm(0xf798f18c) " @ pldw [r8, r12, lsl #3]");
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 7
+ TEST_UNSUPPORTED("clrex")
+ TEST_UNSUPPORTED("dsb")
+ TEST_UNSUPPORTED("dmb")
+ TEST_UNSUPPORTED("isb")
+#endif
+
+ verbose("\n");
+}
+
diff --git a/arch/arm/probes/kprobes/test-core.c b/arch/arm/probes/kprobes/test-core.c
new file mode 100644
index 000000000..9775de22e
--- /dev/null
+++ b/arch/arm/probes/kprobes/test-core.c
@@ -0,0 +1,1727 @@
+/*
+ * arch/arm/kernel/kprobes-test.c
+ *
+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.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 file contains test code for ARM kprobes.
+ *
+ * The top level function run_all_tests() executes tests for all of the
+ * supported instruction sets: ARM, 16-bit Thumb, and 32-bit Thumb. These tests
+ * fall into two categories; run_api_tests() checks basic functionality of the
+ * kprobes API, and run_test_cases() is a comprehensive test for kprobes
+ * instruction decoding and simulation.
+ *
+ * run_test_cases() first checks the kprobes decoding table for self consistency
+ * (using table_test()) then executes a series of test cases for each of the CPU
+ * instruction forms. coverage_start() and coverage_end() are used to verify
+ * that these test cases cover all of the possible combinations of instructions
+ * described by the kprobes decoding tables.
+ *
+ * The individual test cases are in kprobes-test-arm.c and kprobes-test-thumb.c
+ * which use the macros defined in kprobes-test.h. The rest of this
+ * documentation will describe the operation of the framework used by these
+ * test cases.
+ */
+
+/*
+ * TESTING METHODOLOGY
+ * -------------------
+ *
+ * The methodology used to test an ARM instruction 'test_insn' is to use
+ * inline assembler like:
+ *
+ * test_before: nop
+ * test_case: test_insn
+ * test_after: nop
+ *
+ * When the test case is run a kprobe is placed of each nop. The
+ * post-handler of the test_before probe is used to modify the saved CPU
+ * register context to that which we require for the test case. The
+ * pre-handler of the of the test_after probe saves a copy of the CPU
+ * register context. In this way we can execute test_insn with a specific
+ * register context and see the results afterwards.
+ *
+ * To actually test the kprobes instruction emulation we perform the above
+ * step a second time but with an additional kprobe on the test_case
+ * instruction itself. If the emulation is accurate then the results seen
+ * by the test_after probe will be identical to the first run which didn't
+ * have a probe on test_case.
+ *
+ * Each test case is run several times with a variety of variations in the
+ * flags value of stored in CPSR, and for Thumb code, different ITState.
+ *
+ * For instructions which can modify PC, a second test_after probe is used
+ * like this:
+ *
+ * test_before: nop
+ * test_case: test_insn
+ * test_after: nop
+ * b test_done
+ * test_after2: nop
+ * test_done:
+ *
+ * The test case is constructed such that test_insn branches to
+ * test_after2, or, if testing a conditional instruction, it may just
+ * continue to test_after. The probes inserted at both locations let us
+ * determine which happened. A similar approach is used for testing
+ * backwards branches...
+ *
+ * b test_before
+ * b test_done @ helps to cope with off by 1 branches
+ * test_after2: nop
+ * b test_done
+ * test_before: nop
+ * test_case: test_insn
+ * test_after: nop
+ * test_done:
+ *
+ * The macros used to generate the assembler instructions describe above
+ * are TEST_INSTRUCTION, TEST_BRANCH_F (branch forwards) and TEST_BRANCH_B
+ * (branch backwards). In these, the local variables numbered 1, 50, 2 and
+ * 99 represent: test_before, test_case, test_after2 and test_done.
+ *
+ * FRAMEWORK
+ * ---------
+ *
+ * Each test case is wrapped between the pair of macros TESTCASE_START and
+ * TESTCASE_END. As well as performing the inline assembler boilerplate,
+ * these call out to the kprobes_test_case_start() and
+ * kprobes_test_case_end() functions which drive the execution of the test
+ * case. The specific arguments to use for each test case are stored as
+ * inline data constructed using the various TEST_ARG_* macros. Putting
+ * this all together, a simple test case may look like:
+ *
+ * TESTCASE_START("Testing mov r0, r7")
+ * TEST_ARG_REG(7, 0x12345678) // Set r7=0x12345678
+ * TEST_ARG_END("")
+ * TEST_INSTRUCTION("mov r0, r7")
+ * TESTCASE_END
+ *
+ * Note, in practice the single convenience macro TEST_R would be used for this
+ * instead.
+ *
+ * The above would expand to assembler looking something like:
+ *
+ * @ TESTCASE_START
+ * bl __kprobes_test_case_start
+ * .pushsection .rodata
+ * "10:
+ * .ascii "mov r0, r7" @ text title for test case
+ * .byte 0
+ * .popsection
+ * @ start of inline data...
+ * .word 10b @ pointer to title in .rodata section
+ *
+ * @ TEST_ARG_REG
+ * .byte ARG_TYPE_REG
+ * .byte 7
+ * .short 0
+ * .word 0x1234567
+ *
+ * @ TEST_ARG_END
+ * .byte ARG_TYPE_END
+ * .byte TEST_ISA @ flags, including ISA being tested
+ * .short 50f-0f @ offset of 'test_before'
+ * .short 2f-0f @ offset of 'test_after2' (if relevent)
+ * .short 99f-0f @ offset of 'test_done'
+ * @ start of test case code...
+ * 0:
+ * .code TEST_ISA @ switch to ISA being tested
+ *
+ * @ TEST_INSTRUCTION
+ * 50: nop @ location for 'test_before' probe
+ * 1: mov r0, r7 @ the test case instruction 'test_insn'
+ * nop @ location for 'test_after' probe
+ *
+ * // TESTCASE_END
+ * 2:
+ * 99: bl __kprobes_test_case_end_##TEST_ISA
+ * .code NONMAL_ISA
+ *
+ * When the above is execute the following happens...
+ *
+ * __kprobes_test_case_start() is an assembler wrapper which sets up space
+ * for a stack buffer and calls the C function kprobes_test_case_start().
+ * This C function will do some initial processing of the inline data and
+ * setup some global state. It then inserts the test_before and test_after
+ * kprobes and returns a value which causes the assembler wrapper to jump
+ * to the start of the test case code, (local label '0').
+ *
+ * When the test case code executes, the test_before probe will be hit and
+ * test_before_post_handler will call setup_test_context(). This fills the
+ * stack buffer and CPU registers with a test pattern and then processes
+ * the test case arguments. In our example there is one TEST_ARG_REG which
+ * indicates that R7 should be loaded with the value 0x12345678.
+ *
+ * When the test_before probe ends, the test case continues and executes
+ * the "mov r0, r7" instruction. It then hits the test_after probe and the
+ * pre-handler for this (test_after_pre_handler) will save a copy of the
+ * CPU register context. This should now have R0 holding the same value as
+ * R7.
+ *
+ * Finally we get to the call to __kprobes_test_case_end_{32,16}. This is
+ * an assembler wrapper which switches back to the ISA used by the test
+ * code and calls the C function kprobes_test_case_end().
+ *
+ * For each run through the test case, test_case_run_count is incremented
+ * by one. For even runs, kprobes_test_case_end() saves a copy of the
+ * register and stack buffer contents from the test case just run. It then
+ * inserts a kprobe on the test case instruction 'test_insn' and returns a
+ * value to cause the test case code to be re-run.
+ *
+ * For odd numbered runs, kprobes_test_case_end() compares the register and
+ * stack buffer contents to those that were saved on the previous even
+ * numbered run (the one without the kprobe on test_insn). These should be
+ * the same if the kprobe instruction simulation routine is correct.
+ *
+ * The pair of test case runs is repeated with different combinations of
+ * flag values in CPSR and, for Thumb, different ITState. This is
+ * controlled by test_context_cpsr().
+ *
+ * BUILDING TEST CASES
+ * -------------------
+ *
+ *
+ * As an aid to building test cases, the stack buffer is initialised with
+ * some special values:
+ *
+ * [SP+13*4] Contains SP+120. This can be used to test instructions
+ * which load a value into SP.
+ *
+ * [SP+15*4] When testing branching instructions using TEST_BRANCH_{F,B},
+ * this holds the target address of the branch, 'test_after2'.
+ * This can be used to test instructions which load a PC value
+ * from memory.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/kprobes.h>
+#include <linux/errno.h>
+#include <linux/stddef.h>
+#include <linux/bug.h>
+#include <asm/opcodes.h>
+
+#include "core.h"
+#include "test-core.h"
+#include "../decode-arm.h"
+#include "../decode-thumb.h"
+
+
+#define BENCHMARKING 1
+
+
+/*
+ * Test basic API
+ */
+
+static bool test_regs_ok;
+static int test_func_instance;
+static int pre_handler_called;
+static int post_handler_called;
+static int jprobe_func_called;
+static int kretprobe_handler_called;
+static int tests_failed;
+
+#define FUNC_ARG1 0x12345678
+#define FUNC_ARG2 0xabcdef
+
+
+#ifndef CONFIG_THUMB2_KERNEL
+
+#define RET(reg) "mov pc, "#reg
+
+long arm_func(long r0, long r1);
+
+static void __used __naked __arm_kprobes_test_func(void)
+{
+ __asm__ __volatile__ (
+ ".arm \n\t"
+ ".type arm_func, %%function \n\t"
+ "arm_func: \n\t"
+ "adds r0, r0, r1 \n\t"
+ "mov pc, lr \n\t"
+ ".code "NORMAL_ISA /* Back to Thumb if necessary */
+ : : : "r0", "r1", "cc"
+ );
+}
+
+#else /* CONFIG_THUMB2_KERNEL */
+
+#define RET(reg) "bx "#reg
+
+long thumb16_func(long r0, long r1);
+long thumb32even_func(long r0, long r1);
+long thumb32odd_func(long r0, long r1);
+
+static void __used __naked __thumb_kprobes_test_funcs(void)
+{
+ __asm__ __volatile__ (
+ ".type thumb16_func, %%function \n\t"
+ "thumb16_func: \n\t"
+ "adds.n r0, r0, r1 \n\t"
+ "bx lr \n\t"
+
+ ".align \n\t"
+ ".type thumb32even_func, %%function \n\t"
+ "thumb32even_func: \n\t"
+ "adds.w r0, r0, r1 \n\t"
+ "bx lr \n\t"
+
+ ".align \n\t"
+ "nop.n \n\t"
+ ".type thumb32odd_func, %%function \n\t"
+ "thumb32odd_func: \n\t"
+ "adds.w r0, r0, r1 \n\t"
+ "bx lr \n\t"
+
+ : : : "r0", "r1", "cc"
+ );
+}
+
+#endif /* CONFIG_THUMB2_KERNEL */
+
+
+static int call_test_func(long (*func)(long, long), bool check_test_regs)
+{
+ long ret;
+
+ ++test_func_instance;
+ test_regs_ok = false;
+
+ ret = (*func)(FUNC_ARG1, FUNC_ARG2);
+ if (ret != FUNC_ARG1 + FUNC_ARG2) {
+ pr_err("FAIL: call_test_func: func returned %lx\n", ret);
+ return false;
+ }
+
+ if (check_test_regs && !test_regs_ok) {
+ pr_err("FAIL: test regs not OK\n");
+ return false;
+ }
+
+ return true;
+}
+
+static int __kprobes pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ pre_handler_called = test_func_instance;
+ if (regs->ARM_r0 == FUNC_ARG1 && regs->ARM_r1 == FUNC_ARG2)
+ test_regs_ok = true;
+ return 0;
+}
+
+static void __kprobes post_handler(struct kprobe *p, struct pt_regs *regs,
+ unsigned long flags)
+{
+ post_handler_called = test_func_instance;
+ if (regs->ARM_r0 != FUNC_ARG1 + FUNC_ARG2 || regs->ARM_r1 != FUNC_ARG2)
+ test_regs_ok = false;
+}
+
+static struct kprobe the_kprobe = {
+ .addr = 0,
+ .pre_handler = pre_handler,
+ .post_handler = post_handler
+};
+
+static int test_kprobe(long (*func)(long, long))
+{
+ int ret;
+
+ the_kprobe.addr = (kprobe_opcode_t *)func;
+ ret = register_kprobe(&the_kprobe);
+ if (ret < 0) {
+ pr_err("FAIL: register_kprobe failed with %d\n", ret);
+ return ret;
+ }
+
+ ret = call_test_func(func, true);
+
+ unregister_kprobe(&the_kprobe);
+ the_kprobe.flags = 0; /* Clear disable flag to allow reuse */
+
+ if (!ret)
+ return -EINVAL;
+ if (pre_handler_called != test_func_instance) {
+ pr_err("FAIL: kprobe pre_handler not called\n");
+ return -EINVAL;
+ }
+ if (post_handler_called != test_func_instance) {
+ pr_err("FAIL: kprobe post_handler not called\n");
+ return -EINVAL;
+ }
+ if (!call_test_func(func, false))
+ return -EINVAL;
+ if (pre_handler_called == test_func_instance ||
+ post_handler_called == test_func_instance) {
+ pr_err("FAIL: probe called after unregistering\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void __kprobes jprobe_func(long r0, long r1)
+{
+ jprobe_func_called = test_func_instance;
+ if (r0 == FUNC_ARG1 && r1 == FUNC_ARG2)
+ test_regs_ok = true;
+ jprobe_return();
+}
+
+static struct jprobe the_jprobe = {
+ .entry = jprobe_func,
+};
+
+static int test_jprobe(long (*func)(long, long))
+{
+ int ret;
+
+ the_jprobe.kp.addr = (kprobe_opcode_t *)func;
+ ret = register_jprobe(&the_jprobe);
+ if (ret < 0) {
+ pr_err("FAIL: register_jprobe failed with %d\n", ret);
+ return ret;
+ }
+
+ ret = call_test_func(func, true);
+
+ unregister_jprobe(&the_jprobe);
+ the_jprobe.kp.flags = 0; /* Clear disable flag to allow reuse */
+
+ if (!ret)
+ return -EINVAL;
+ if (jprobe_func_called != test_func_instance) {
+ pr_err("FAIL: jprobe handler function not called\n");
+ return -EINVAL;
+ }
+ if (!call_test_func(func, false))
+ return -EINVAL;
+ if (jprobe_func_called == test_func_instance) {
+ pr_err("FAIL: probe called after unregistering\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int __kprobes
+kretprobe_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+ kretprobe_handler_called = test_func_instance;
+ if (regs_return_value(regs) == FUNC_ARG1 + FUNC_ARG2)
+ test_regs_ok = true;
+ return 0;
+}
+
+static struct kretprobe the_kretprobe = {
+ .handler = kretprobe_handler,
+};
+
+static int test_kretprobe(long (*func)(long, long))
+{
+ int ret;
+
+ the_kretprobe.kp.addr = (kprobe_opcode_t *)func;
+ ret = register_kretprobe(&the_kretprobe);
+ if (ret < 0) {
+ pr_err("FAIL: register_kretprobe failed with %d\n", ret);
+ return ret;
+ }
+
+ ret = call_test_func(func, true);
+
+ unregister_kretprobe(&the_kretprobe);
+ the_kretprobe.kp.flags = 0; /* Clear disable flag to allow reuse */
+
+ if (!ret)
+ return -EINVAL;
+ if (kretprobe_handler_called != test_func_instance) {
+ pr_err("FAIL: kretprobe handler not called\n");
+ return -EINVAL;
+ }
+ if (!call_test_func(func, false))
+ return -EINVAL;
+ if (jprobe_func_called == test_func_instance) {
+ pr_err("FAIL: kretprobe called after unregistering\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int run_api_tests(long (*func)(long, long))
+{
+ int ret;
+
+ pr_info(" kprobe\n");
+ ret = test_kprobe(func);
+ if (ret < 0)
+ return ret;
+
+ pr_info(" jprobe\n");
+ ret = test_jprobe(func);
+#if defined(CONFIG_THUMB2_KERNEL) && !defined(MODULE)
+ if (ret == -EINVAL) {
+ pr_err("FAIL: Known longtime bug with jprobe on Thumb kernels\n");
+ tests_failed = ret;
+ ret = 0;
+ }
+#endif
+ if (ret < 0)
+ return ret;
+
+ pr_info(" kretprobe\n");
+ ret = test_kretprobe(func);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+
+/*
+ * Benchmarking
+ */
+
+#if BENCHMARKING
+
+static void __naked benchmark_nop(void)
+{
+ __asm__ __volatile__ (
+ "nop \n\t"
+ RET(lr)" \n\t"
+ );
+}
+
+#ifdef CONFIG_THUMB2_KERNEL
+#define wide ".w"
+#else
+#define wide
+#endif
+
+static void __naked benchmark_pushpop1(void)
+{
+ __asm__ __volatile__ (
+ "stmdb"wide" sp!, {r3-r11,lr} \n\t"
+ "ldmia"wide" sp!, {r3-r11,pc}"
+ );
+}
+
+static void __naked benchmark_pushpop2(void)
+{
+ __asm__ __volatile__ (
+ "stmdb"wide" sp!, {r0-r8,lr} \n\t"
+ "ldmia"wide" sp!, {r0-r8,pc}"
+ );
+}
+
+static void __naked benchmark_pushpop3(void)
+{
+ __asm__ __volatile__ (
+ "stmdb"wide" sp!, {r4,lr} \n\t"
+ "ldmia"wide" sp!, {r4,pc}"
+ );
+}
+
+static void __naked benchmark_pushpop4(void)
+{
+ __asm__ __volatile__ (
+ "stmdb"wide" sp!, {r0,lr} \n\t"
+ "ldmia"wide" sp!, {r0,pc}"
+ );
+}
+
+
+#ifdef CONFIG_THUMB2_KERNEL
+
+static void __naked benchmark_pushpop_thumb(void)
+{
+ __asm__ __volatile__ (
+ "push.n {r0-r7,lr} \n\t"
+ "pop.n {r0-r7,pc}"
+ );
+}
+
+#endif
+
+static int __kprobes
+benchmark_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ return 0;
+}
+
+static int benchmark(void(*fn)(void))
+{
+ unsigned n, i, t, t0;
+
+ for (n = 1000; ; n *= 2) {
+ t0 = sched_clock();
+ for (i = n; i > 0; --i)
+ fn();
+ t = sched_clock() - t0;
+ if (t >= 250000000)
+ break; /* Stop once we took more than 0.25 seconds */
+ }
+ return t / n; /* Time for one iteration in nanoseconds */
+};
+
+static int kprobe_benchmark(void(*fn)(void), unsigned offset)
+{
+ struct kprobe k = {
+ .addr = (kprobe_opcode_t *)((uintptr_t)fn + offset),
+ .pre_handler = benchmark_pre_handler,
+ };
+
+ int ret = register_kprobe(&k);
+ if (ret < 0) {
+ pr_err("FAIL: register_kprobe failed with %d\n", ret);
+ return ret;
+ }
+
+ ret = benchmark(fn);
+
+ unregister_kprobe(&k);
+ return ret;
+};
+
+struct benchmarks {
+ void (*fn)(void);
+ unsigned offset;
+ const char *title;
+};
+
+static int run_benchmarks(void)
+{
+ int ret;
+ struct benchmarks list[] = {
+ {&benchmark_nop, 0, "nop"},
+ /*
+ * benchmark_pushpop{1,3} will have the optimised
+ * instruction emulation, whilst benchmark_pushpop{2,4} will
+ * be the equivalent unoptimised instructions.
+ */
+ {&benchmark_pushpop1, 0, "stmdb sp!, {r3-r11,lr}"},
+ {&benchmark_pushpop1, 4, "ldmia sp!, {r3-r11,pc}"},
+ {&benchmark_pushpop2, 0, "stmdb sp!, {r0-r8,lr}"},
+ {&benchmark_pushpop2, 4, "ldmia sp!, {r0-r8,pc}"},
+ {&benchmark_pushpop3, 0, "stmdb sp!, {r4,lr}"},
+ {&benchmark_pushpop3, 4, "ldmia sp!, {r4,pc}"},
+ {&benchmark_pushpop4, 0, "stmdb sp!, {r0,lr}"},
+ {&benchmark_pushpop4, 4, "ldmia sp!, {r0,pc}"},
+#ifdef CONFIG_THUMB2_KERNEL
+ {&benchmark_pushpop_thumb, 0, "push.n {r0-r7,lr}"},
+ {&benchmark_pushpop_thumb, 2, "pop.n {r0-r7,pc}"},
+#endif
+ {0}
+ };
+
+ struct benchmarks *b;
+ for (b = list; b->fn; ++b) {
+ ret = kprobe_benchmark(b->fn, b->offset);
+ if (ret < 0)
+ return ret;
+ pr_info(" %dns for kprobe %s\n", ret, b->title);
+ }
+
+ pr_info("\n");
+ return 0;
+}
+
+#endif /* BENCHMARKING */
+
+
+/*
+ * Decoding table self-consistency tests
+ */
+
+static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
+ [DECODE_TYPE_TABLE] = sizeof(struct decode_table),
+ [DECODE_TYPE_CUSTOM] = sizeof(struct decode_custom),
+ [DECODE_TYPE_SIMULATE] = sizeof(struct decode_simulate),
+ [DECODE_TYPE_EMULATE] = sizeof(struct decode_emulate),
+ [DECODE_TYPE_OR] = sizeof(struct decode_or),
+ [DECODE_TYPE_REJECT] = sizeof(struct decode_reject)
+};
+
+static int table_iter(const union decode_item *table,
+ int (*fn)(const struct decode_header *, void *),
+ void *args)
+{
+ const struct decode_header *h = (struct decode_header *)table;
+ int result;
+
+ for (;;) {
+ enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK;
+
+ if (type == DECODE_TYPE_END)
+ return 0;
+
+ result = fn(h, args);
+ if (result)
+ return result;
+
+ h = (struct decode_header *)
+ ((uintptr_t)h + decode_struct_sizes[type]);
+
+ }
+}
+
+static int table_test_fail(const struct decode_header *h, const char* message)
+{
+
+ pr_err("FAIL: kprobes test failure \"%s\" (mask %08x, value %08x)\n",
+ message, h->mask.bits, h->value.bits);
+ return -EINVAL;
+}
+
+struct table_test_args {
+ const union decode_item *root_table;
+ u32 parent_mask;
+ u32 parent_value;
+};
+
+static int table_test_fn(const struct decode_header *h, void *args)
+{
+ struct table_test_args *a = (struct table_test_args *)args;
+ enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK;
+
+ if (h->value.bits & ~h->mask.bits)
+ return table_test_fail(h, "Match value has bits not in mask");
+
+ if ((h->mask.bits & a->parent_mask) != a->parent_mask)
+ return table_test_fail(h, "Mask has bits not in parent mask");
+
+ if ((h->value.bits ^ a->parent_value) & a->parent_mask)
+ return table_test_fail(h, "Value is inconsistent with parent");
+
+ if (type == DECODE_TYPE_TABLE) {
+ struct decode_table *d = (struct decode_table *)h;
+ struct table_test_args args2 = *a;
+ args2.parent_mask = h->mask.bits;
+ args2.parent_value = h->value.bits;
+ return table_iter(d->table.table, table_test_fn, &args2);
+ }
+
+ return 0;
+}
+
+static int table_test(const union decode_item *table)
+{
+ struct table_test_args args = {
+ .root_table = table,
+ .parent_mask = 0,
+ .parent_value = 0
+ };
+ return table_iter(args.root_table, table_test_fn, &args);
+}
+
+
+/*
+ * Decoding table test coverage analysis
+ *
+ * coverage_start() builds a coverage_table which contains a list of
+ * coverage_entry's to match each entry in the specified kprobes instruction
+ * decoding table.
+ *
+ * When test cases are run, coverage_add() is called to process each case.
+ * This looks up the corresponding entry in the coverage_table and sets it as
+ * being matched, as well as clearing the regs flag appropriate for the test.
+ *
+ * After all test cases have been run, coverage_end() is called to check that
+ * all entries in coverage_table have been matched and that all regs flags are
+ * cleared. I.e. that all possible combinations of instructions described by
+ * the kprobes decoding tables have had a test case executed for them.
+ */
+
+bool coverage_fail;
+
+#define MAX_COVERAGE_ENTRIES 256
+
+struct coverage_entry {
+ const struct decode_header *header;
+ unsigned regs;
+ unsigned nesting;
+ char matched;
+};
+
+struct coverage_table {
+ struct coverage_entry *base;
+ unsigned num_entries;
+ unsigned nesting;
+};
+
+struct coverage_table coverage;
+
+#define COVERAGE_ANY_REG (1<<0)
+#define COVERAGE_SP (1<<1)
+#define COVERAGE_PC (1<<2)
+#define COVERAGE_PCWB (1<<3)
+
+static const char coverage_register_lookup[16] = {
+ [REG_TYPE_ANY] = COVERAGE_ANY_REG | COVERAGE_SP | COVERAGE_PC,
+ [REG_TYPE_SAMEAS16] = COVERAGE_ANY_REG,
+ [REG_TYPE_SP] = COVERAGE_SP,
+ [REG_TYPE_PC] = COVERAGE_PC,
+ [REG_TYPE_NOSP] = COVERAGE_ANY_REG | COVERAGE_SP,
+ [REG_TYPE_NOSPPC] = COVERAGE_ANY_REG | COVERAGE_SP | COVERAGE_PC,
+ [REG_TYPE_NOPC] = COVERAGE_ANY_REG | COVERAGE_PC,
+ [REG_TYPE_NOPCWB] = COVERAGE_ANY_REG | COVERAGE_PC | COVERAGE_PCWB,
+ [REG_TYPE_NOPCX] = COVERAGE_ANY_REG,
+ [REG_TYPE_NOSPPCX] = COVERAGE_ANY_REG | COVERAGE_SP,
+};
+
+unsigned coverage_start_registers(const struct decode_header *h)
+{
+ unsigned regs = 0;
+ int i;
+ for (i = 0; i < 20; i += 4) {
+ int r = (h->type_regs.bits >> (DECODE_TYPE_BITS + i)) & 0xf;
+ regs |= coverage_register_lookup[r] << i;
+ }
+ return regs;
+}
+
+static int coverage_start_fn(const struct decode_header *h, void *args)
+{
+ struct coverage_table *coverage = (struct coverage_table *)args;
+ enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK;
+ struct coverage_entry *entry = coverage->base + coverage->num_entries;
+
+ if (coverage->num_entries == MAX_COVERAGE_ENTRIES - 1) {
+ pr_err("FAIL: Out of space for test coverage data");
+ return -ENOMEM;
+ }
+
+ ++coverage->num_entries;
+
+ entry->header = h;
+ entry->regs = coverage_start_registers(h);
+ entry->nesting = coverage->nesting;
+ entry->matched = false;
+
+ if (type == DECODE_TYPE_TABLE) {
+ struct decode_table *d = (struct decode_table *)h;
+ int ret;
+ ++coverage->nesting;
+ ret = table_iter(d->table.table, coverage_start_fn, coverage);
+ --coverage->nesting;
+ return ret;
+ }
+
+ return 0;
+}
+
+static int coverage_start(const union decode_item *table)
+{
+ coverage.base = kmalloc(MAX_COVERAGE_ENTRIES *
+ sizeof(struct coverage_entry), GFP_KERNEL);
+ coverage.num_entries = 0;
+ coverage.nesting = 0;
+ return table_iter(table, coverage_start_fn, &coverage);
+}
+
+static void
+coverage_add_registers(struct coverage_entry *entry, kprobe_opcode_t insn)
+{
+ int regs = entry->header->type_regs.bits >> DECODE_TYPE_BITS;
+ int i;
+ for (i = 0; i < 20; i += 4) {
+ enum decode_reg_type reg_type = (regs >> i) & 0xf;
+ int reg = (insn >> i) & 0xf;
+ int flag;
+
+ if (!reg_type)
+ continue;
+
+ if (reg == 13)
+ flag = COVERAGE_SP;
+ else if (reg == 15)
+ flag = COVERAGE_PC;
+ else
+ flag = COVERAGE_ANY_REG;
+ entry->regs &= ~(flag << i);
+
+ switch (reg_type) {
+
+ case REG_TYPE_NONE:
+ case REG_TYPE_ANY:
+ case REG_TYPE_SAMEAS16:
+ break;
+
+ case REG_TYPE_SP:
+ if (reg != 13)
+ return;
+ break;
+
+ case REG_TYPE_PC:
+ if (reg != 15)
+ return;
+ break;
+
+ case REG_TYPE_NOSP:
+ if (reg == 13)
+ return;
+ break;
+
+ case REG_TYPE_NOSPPC:
+ case REG_TYPE_NOSPPCX:
+ if (reg == 13 || reg == 15)
+ return;
+ break;
+
+ case REG_TYPE_NOPCWB:
+ if (!is_writeback(insn))
+ break;
+ if (reg == 15) {
+ entry->regs &= ~(COVERAGE_PCWB << i);
+ return;
+ }
+ break;
+
+ case REG_TYPE_NOPC:
+ case REG_TYPE_NOPCX:
+ if (reg == 15)
+ return;
+ break;
+ }
+
+ }
+}
+
+static void coverage_add(kprobe_opcode_t insn)
+{
+ struct coverage_entry *entry = coverage.base;
+ struct coverage_entry *end = coverage.base + coverage.num_entries;
+ bool matched = false;
+ unsigned nesting = 0;
+
+ for (; entry < end; ++entry) {
+ const struct decode_header *h = entry->header;
+ enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK;
+
+ if (entry->nesting > nesting)
+ continue; /* Skip sub-table we didn't match */
+
+ if (entry->nesting < nesting)
+ break; /* End of sub-table we were scanning */
+
+ if (!matched) {
+ if ((insn & h->mask.bits) != h->value.bits)
+ continue;
+ entry->matched = true;
+ }
+
+ switch (type) {
+
+ case DECODE_TYPE_TABLE:
+ ++nesting;
+ break;
+
+ case DECODE_TYPE_CUSTOM:
+ case DECODE_TYPE_SIMULATE:
+ case DECODE_TYPE_EMULATE:
+ coverage_add_registers(entry, insn);
+ return;
+
+ case DECODE_TYPE_OR:
+ matched = true;
+ break;
+
+ case DECODE_TYPE_REJECT:
+ default:
+ return;
+ }
+
+ }
+}
+
+static void coverage_end(void)
+{
+ struct coverage_entry *entry = coverage.base;
+ struct coverage_entry *end = coverage.base + coverage.num_entries;
+
+ for (; entry < end; ++entry) {
+ u32 mask = entry->header->mask.bits;
+ u32 value = entry->header->value.bits;
+
+ if (entry->regs) {
+ pr_err("FAIL: Register test coverage missing for %08x %08x (%05x)\n",
+ mask, value, entry->regs);
+ coverage_fail = true;
+ }
+ if (!entry->matched) {
+ pr_err("FAIL: Test coverage entry missing for %08x %08x\n",
+ mask, value);
+ coverage_fail = true;
+ }
+ }
+
+ kfree(coverage.base);
+}
+
+
+/*
+ * Framework for instruction set test cases
+ */
+
+void __naked __kprobes_test_case_start(void)
+{
+ __asm__ __volatile__ (
+ "stmdb sp!, {r4-r11} \n\t"
+ "sub sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t"
+ "bic r0, lr, #1 @ r0 = inline data \n\t"
+ "mov r1, sp \n\t"
+ "bl kprobes_test_case_start \n\t"
+ RET(r0)" \n\t"
+ );
+}
+
+#ifndef CONFIG_THUMB2_KERNEL
+
+void __naked __kprobes_test_case_end_32(void)
+{
+ __asm__ __volatile__ (
+ "mov r4, lr \n\t"
+ "bl kprobes_test_case_end \n\t"
+ "cmp r0, #0 \n\t"
+ "movne pc, r0 \n\t"
+ "mov r0, r4 \n\t"
+ "add sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t"
+ "ldmia sp!, {r4-r11} \n\t"
+ "mov pc, r0 \n\t"
+ );
+}
+
+#else /* CONFIG_THUMB2_KERNEL */
+
+void __naked __kprobes_test_case_end_16(void)
+{
+ __asm__ __volatile__ (
+ "mov r4, lr \n\t"
+ "bl kprobes_test_case_end \n\t"
+ "cmp r0, #0 \n\t"
+ "bxne r0 \n\t"
+ "mov r0, r4 \n\t"
+ "add sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t"
+ "ldmia sp!, {r4-r11} \n\t"
+ "bx r0 \n\t"
+ );
+}
+
+void __naked __kprobes_test_case_end_32(void)
+{
+ __asm__ __volatile__ (
+ ".arm \n\t"
+ "orr lr, lr, #1 @ will return to Thumb code \n\t"
+ "ldr pc, 1f \n\t"
+ "1: \n\t"
+ ".word __kprobes_test_case_end_16 \n\t"
+ );
+}
+
+#endif
+
+
+int kprobe_test_flags;
+int kprobe_test_cc_position;
+
+static int test_try_count;
+static int test_pass_count;
+static int test_fail_count;
+
+static struct pt_regs initial_regs;
+static struct pt_regs expected_regs;
+static struct pt_regs result_regs;
+
+static u32 expected_memory[TEST_MEMORY_SIZE/sizeof(u32)];
+
+static const char *current_title;
+static struct test_arg *current_args;
+static u32 *current_stack;
+static uintptr_t current_branch_target;
+
+static uintptr_t current_code_start;
+static kprobe_opcode_t current_instruction;
+
+
+#define TEST_CASE_PASSED -1
+#define TEST_CASE_FAILED -2
+
+static int test_case_run_count;
+static bool test_case_is_thumb;
+static int test_instance;
+
+static unsigned long test_check_cc(int cc, unsigned long cpsr)
+{
+ int ret = arm_check_condition(cc << 28, cpsr);
+
+ return (ret != ARM_OPCODE_CONDTEST_FAIL);
+}
+
+static int is_last_scenario;
+static int probe_should_run; /* 0 = no, 1 = yes, -1 = unknown */
+static int memory_needs_checking;
+
+static unsigned long test_context_cpsr(int scenario)
+{
+ unsigned long cpsr;
+
+ probe_should_run = 1;
+
+ /* Default case is that we cycle through 16 combinations of flags */
+ cpsr = (scenario & 0xf) << 28; /* N,Z,C,V flags */
+ cpsr |= (scenario & 0xf) << 16; /* GE flags */
+ cpsr |= (scenario & 0x1) << 27; /* Toggle Q flag */
+
+ if (!test_case_is_thumb) {
+ /* Testing ARM code */
+ int cc = current_instruction >> 28;
+
+ probe_should_run = test_check_cc(cc, cpsr) != 0;
+ if (scenario == 15)
+ is_last_scenario = true;
+
+ } else if (kprobe_test_flags & TEST_FLAG_NO_ITBLOCK) {
+ /* Testing Thumb code without setting ITSTATE */
+ if (kprobe_test_cc_position) {
+ int cc = (current_instruction >> kprobe_test_cc_position) & 0xf;
+ probe_should_run = test_check_cc(cc, cpsr) != 0;
+ }
+
+ if (scenario == 15)
+ is_last_scenario = true;
+
+ } else if (kprobe_test_flags & TEST_FLAG_FULL_ITBLOCK) {
+ /* Testing Thumb code with all combinations of ITSTATE */
+ unsigned x = (scenario >> 4);
+ unsigned cond_base = x % 7; /* ITSTATE<7:5> */
+ unsigned mask = x / 7 + 2; /* ITSTATE<4:0>, bits reversed */
+
+ if (mask > 0x1f) {
+ /* Finish by testing state from instruction 'itt al' */
+ cond_base = 7;
+ mask = 0x4;
+ if ((scenario & 0xf) == 0xf)
+ is_last_scenario = true;
+ }
+
+ cpsr |= cond_base << 13; /* ITSTATE<7:5> */
+ cpsr |= (mask & 0x1) << 12; /* ITSTATE<4> */
+ cpsr |= (mask & 0x2) << 10; /* ITSTATE<3> */
+ cpsr |= (mask & 0x4) << 8; /* ITSTATE<2> */
+ cpsr |= (mask & 0x8) << 23; /* ITSTATE<1> */
+ cpsr |= (mask & 0x10) << 21; /* ITSTATE<0> */
+
+ probe_should_run = test_check_cc((cpsr >> 12) & 0xf, cpsr) != 0;
+
+ } else {
+ /* Testing Thumb code with several combinations of ITSTATE */
+ switch (scenario) {
+ case 16: /* Clear NZCV flags and 'it eq' state (false as Z=0) */
+ cpsr = 0x00000800;
+ probe_should_run = 0;
+ break;
+ case 17: /* Set NZCV flags and 'it vc' state (false as V=1) */
+ cpsr = 0xf0007800;
+ probe_should_run = 0;
+ break;
+ case 18: /* Clear NZCV flags and 'it ls' state (true as C=0) */
+ cpsr = 0x00009800;
+ break;
+ case 19: /* Set NZCV flags and 'it cs' state (true as C=1) */
+ cpsr = 0xf0002800;
+ is_last_scenario = true;
+ break;
+ }
+ }
+
+ return cpsr;
+}
+
+static void setup_test_context(struct pt_regs *regs)
+{
+ int scenario = test_case_run_count>>1;
+ unsigned long val;
+ struct test_arg *args;
+ int i;
+
+ is_last_scenario = false;
+ memory_needs_checking = false;
+
+ /* Initialise test memory on stack */
+ val = (scenario & 1) ? VALM : ~VALM;
+ for (i = 0; i < TEST_MEMORY_SIZE / sizeof(current_stack[0]); ++i)
+ current_stack[i] = val + (i << 8);
+ /* Put target of branch on stack for tests which load PC from memory */
+ if (current_branch_target)
+ current_stack[15] = current_branch_target;
+ /* Put a value for SP on stack for tests which load SP from memory */
+ current_stack[13] = (u32)current_stack + 120;
+
+ /* Initialise register values to their default state */
+ val = (scenario & 2) ? VALR : ~VALR;
+ for (i = 0; i < 13; ++i)
+ regs->uregs[i] = val ^ (i << 8);
+ regs->ARM_lr = val ^ (14 << 8);
+ regs->ARM_cpsr &= ~(APSR_MASK | PSR_IT_MASK);
+ regs->ARM_cpsr |= test_context_cpsr(scenario);
+
+ /* Perform testcase specific register setup */
+ args = current_args;
+ for (; args[0].type != ARG_TYPE_END; ++args)
+ switch (args[0].type) {
+ case ARG_TYPE_REG: {
+ struct test_arg_regptr *arg =
+ (struct test_arg_regptr *)args;
+ regs->uregs[arg->reg] = arg->val;
+ break;
+ }
+ case ARG_TYPE_PTR: {
+ struct test_arg_regptr *arg =
+ (struct test_arg_regptr *)args;
+ regs->uregs[arg->reg] =
+ (unsigned long)current_stack + arg->val;
+ memory_needs_checking = true;
+ /*
+ * Test memory at an address below SP is in danger of
+ * being altered by an interrupt occurring and pushing
+ * data onto the stack. Disable interrupts to stop this.
+ */
+ if (arg->reg == 13)
+ regs->ARM_cpsr |= PSR_I_BIT;
+ break;
+ }
+ case ARG_TYPE_MEM: {
+ struct test_arg_mem *arg = (struct test_arg_mem *)args;
+ current_stack[arg->index] = arg->val;
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+struct test_probe {
+ struct kprobe kprobe;
+ bool registered;
+ int hit;
+};
+
+static void unregister_test_probe(struct test_probe *probe)
+{
+ if (probe->registered) {
+ unregister_kprobe(&probe->kprobe);
+ probe->kprobe.flags = 0; /* Clear disable flag to allow reuse */
+ }
+ probe->registered = false;
+}
+
+static int register_test_probe(struct test_probe *probe)
+{
+ int ret;
+
+ if (probe->registered)
+ BUG();
+
+ ret = register_kprobe(&probe->kprobe);
+ if (ret >= 0) {
+ probe->registered = true;
+ probe->hit = -1;
+ }
+ return ret;
+}
+
+static int __kprobes
+test_before_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ container_of(p, struct test_probe, kprobe)->hit = test_instance;
+ return 0;
+}
+
+static void __kprobes
+test_before_post_handler(struct kprobe *p, struct pt_regs *regs,
+ unsigned long flags)
+{
+ setup_test_context(regs);
+ initial_regs = *regs;
+ initial_regs.ARM_cpsr &= ~PSR_IGNORE_BITS;
+}
+
+static int __kprobes
+test_case_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ container_of(p, struct test_probe, kprobe)->hit = test_instance;
+ return 0;
+}
+
+static int __kprobes
+test_after_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ struct test_arg *args;
+
+ if (container_of(p, struct test_probe, kprobe)->hit == test_instance)
+ return 0; /* Already run for this test instance */
+
+ result_regs = *regs;
+
+ /* Mask out results which are indeterminate */
+ result_regs.ARM_cpsr &= ~PSR_IGNORE_BITS;
+ for (args = current_args; args[0].type != ARG_TYPE_END; ++args)
+ if (args[0].type == ARG_TYPE_REG_MASKED) {
+ struct test_arg_regptr *arg =
+ (struct test_arg_regptr *)args;
+ result_regs.uregs[arg->reg] &= arg->val;
+ }
+
+ /* Undo any changes done to SP by the test case */
+ regs->ARM_sp = (unsigned long)current_stack;
+ /* Enable interrupts in case setup_test_context disabled them */
+ regs->ARM_cpsr &= ~PSR_I_BIT;
+
+ container_of(p, struct test_probe, kprobe)->hit = test_instance;
+ return 0;
+}
+
+static struct test_probe test_before_probe = {
+ .kprobe.pre_handler = test_before_pre_handler,
+ .kprobe.post_handler = test_before_post_handler,
+};
+
+static struct test_probe test_case_probe = {
+ .kprobe.pre_handler = test_case_pre_handler,
+};
+
+static struct test_probe test_after_probe = {
+ .kprobe.pre_handler = test_after_pre_handler,
+};
+
+static struct test_probe test_after2_probe = {
+ .kprobe.pre_handler = test_after_pre_handler,
+};
+
+static void test_case_cleanup(void)
+{
+ unregister_test_probe(&test_before_probe);
+ unregister_test_probe(&test_case_probe);
+ unregister_test_probe(&test_after_probe);
+ unregister_test_probe(&test_after2_probe);
+}
+
+static void print_registers(struct pt_regs *regs)
+{
+ pr_err("r0 %08lx | r1 %08lx | r2 %08lx | r3 %08lx\n",
+ regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, regs->ARM_r3);
+ pr_err("r4 %08lx | r5 %08lx | r6 %08lx | r7 %08lx\n",
+ regs->ARM_r4, regs->ARM_r5, regs->ARM_r6, regs->ARM_r7);
+ pr_err("r8 %08lx | r9 %08lx | r10 %08lx | r11 %08lx\n",
+ regs->ARM_r8, regs->ARM_r9, regs->ARM_r10, regs->ARM_fp);
+ pr_err("r12 %08lx | sp %08lx | lr %08lx | pc %08lx\n",
+ regs->ARM_ip, regs->ARM_sp, regs->ARM_lr, regs->ARM_pc);
+ pr_err("cpsr %08lx\n", regs->ARM_cpsr);
+}
+
+static void print_memory(u32 *mem, size_t size)
+{
+ int i;
+ for (i = 0; i < size / sizeof(u32); i += 4)
+ pr_err("%08x %08x %08x %08x\n", mem[i], mem[i+1],
+ mem[i+2], mem[i+3]);
+}
+
+static size_t expected_memory_size(u32 *sp)
+{
+ size_t size = sizeof(expected_memory);
+ int offset = (uintptr_t)sp - (uintptr_t)current_stack;
+ if (offset > 0)
+ size -= offset;
+ return size;
+}
+
+static void test_case_failed(const char *message)
+{
+ test_case_cleanup();
+
+ pr_err("FAIL: %s\n", message);
+ pr_err("FAIL: Test %s\n", current_title);
+ pr_err("FAIL: Scenario %d\n", test_case_run_count >> 1);
+}
+
+static unsigned long next_instruction(unsigned long pc)
+{
+#ifdef CONFIG_THUMB2_KERNEL
+ if ((pc & 1) &&
+ !is_wide_instruction(__mem_to_opcode_thumb16(*(u16 *)(pc - 1))))
+ return pc + 2;
+ else
+#endif
+ return pc + 4;
+}
+
+static uintptr_t __used kprobes_test_case_start(const char **title, void *stack)
+{
+ struct test_arg *args;
+ struct test_arg_end *end_arg;
+ unsigned long test_code;
+
+ current_title = *title++;
+ args = (struct test_arg *)title;
+ current_args = args;
+ current_stack = stack;
+
+ ++test_try_count;
+
+ while (args->type != ARG_TYPE_END)
+ ++args;
+ end_arg = (struct test_arg_end *)args;
+
+ test_code = (unsigned long)(args + 1); /* Code starts after args */
+
+ test_case_is_thumb = end_arg->flags & ARG_FLAG_THUMB;
+ if (test_case_is_thumb)
+ test_code |= 1;
+
+ current_code_start = test_code;
+
+ current_branch_target = 0;
+ if (end_arg->branch_offset != end_arg->end_offset)
+ current_branch_target = test_code + end_arg->branch_offset;
+
+ test_code += end_arg->code_offset;
+ test_before_probe.kprobe.addr = (kprobe_opcode_t *)test_code;
+
+ test_code = next_instruction(test_code);
+ test_case_probe.kprobe.addr = (kprobe_opcode_t *)test_code;
+
+ if (test_case_is_thumb) {
+ u16 *p = (u16 *)(test_code & ~1);
+ current_instruction = __mem_to_opcode_thumb16(p[0]);
+ if (is_wide_instruction(current_instruction)) {
+ u16 instr2 = __mem_to_opcode_thumb16(p[1]);
+ current_instruction = __opcode_thumb32_compose(current_instruction, instr2);
+ }
+ } else {
+ current_instruction = __mem_to_opcode_arm(*(u32 *)test_code);
+ }
+
+ if (current_title[0] == '.')
+ verbose("%s\n", current_title);
+ else
+ verbose("%s\t@ %0*x\n", current_title,
+ test_case_is_thumb ? 4 : 8,
+ current_instruction);
+
+ test_code = next_instruction(test_code);
+ test_after_probe.kprobe.addr = (kprobe_opcode_t *)test_code;
+
+ if (kprobe_test_flags & TEST_FLAG_NARROW_INSTR) {
+ if (!test_case_is_thumb ||
+ is_wide_instruction(current_instruction)) {
+ test_case_failed("expected 16-bit instruction");
+ goto fail;
+ }
+ } else {
+ if (test_case_is_thumb &&
+ !is_wide_instruction(current_instruction)) {
+ test_case_failed("expected 32-bit instruction");
+ goto fail;
+ }
+ }
+
+ coverage_add(current_instruction);
+
+ if (end_arg->flags & ARG_FLAG_UNSUPPORTED) {
+ if (register_test_probe(&test_case_probe) < 0)
+ goto pass;
+ test_case_failed("registered probe for unsupported instruction");
+ goto fail;
+ }
+
+ if (end_arg->flags & ARG_FLAG_SUPPORTED) {
+ if (register_test_probe(&test_case_probe) >= 0)
+ goto pass;
+ test_case_failed("couldn't register probe for supported instruction");
+ goto fail;
+ }
+
+ if (register_test_probe(&test_before_probe) < 0) {
+ test_case_failed("register test_before_probe failed");
+ goto fail;
+ }
+ if (register_test_probe(&test_after_probe) < 0) {
+ test_case_failed("register test_after_probe failed");
+ goto fail;
+ }
+ if (current_branch_target) {
+ test_after2_probe.kprobe.addr =
+ (kprobe_opcode_t *)current_branch_target;
+ if (register_test_probe(&test_after2_probe) < 0) {
+ test_case_failed("register test_after2_probe failed");
+ goto fail;
+ }
+ }
+
+ /* Start first run of test case */
+ test_case_run_count = 0;
+ ++test_instance;
+ return current_code_start;
+pass:
+ test_case_run_count = TEST_CASE_PASSED;
+ return (uintptr_t)test_after_probe.kprobe.addr;
+fail:
+ test_case_run_count = TEST_CASE_FAILED;
+ return (uintptr_t)test_after_probe.kprobe.addr;
+}
+
+static bool check_test_results(void)
+{
+ size_t mem_size = 0;
+ u32 *mem = 0;
+
+ if (memcmp(&expected_regs, &result_regs, sizeof(expected_regs))) {
+ test_case_failed("registers differ");
+ goto fail;
+ }
+
+ if (memory_needs_checking) {
+ mem = (u32 *)result_regs.ARM_sp;
+ mem_size = expected_memory_size(mem);
+ if (memcmp(expected_memory, mem, mem_size)) {
+ test_case_failed("test memory differs");
+ goto fail;
+ }
+ }
+
+ return true;
+
+fail:
+ pr_err("initial_regs:\n");
+ print_registers(&initial_regs);
+ pr_err("expected_regs:\n");
+ print_registers(&expected_regs);
+ pr_err("result_regs:\n");
+ print_registers(&result_regs);
+
+ if (mem) {
+ pr_err("current_stack=%p\n", current_stack);
+ pr_err("expected_memory:\n");
+ print_memory(expected_memory, mem_size);
+ pr_err("result_memory:\n");
+ print_memory(mem, mem_size);
+ }
+
+ return false;
+}
+
+static uintptr_t __used kprobes_test_case_end(void)
+{
+ if (test_case_run_count < 0) {
+ if (test_case_run_count == TEST_CASE_PASSED)
+ /* kprobes_test_case_start did all the needed testing */
+ goto pass;
+ else
+ /* kprobes_test_case_start failed */
+ goto fail;
+ }
+
+ if (test_before_probe.hit != test_instance) {
+ test_case_failed("test_before_handler not run");
+ goto fail;
+ }
+
+ if (test_after_probe.hit != test_instance &&
+ test_after2_probe.hit != test_instance) {
+ test_case_failed("test_after_handler not run");
+ goto fail;
+ }
+
+ /*
+ * Even numbered test runs ran without a probe on the test case so
+ * we can gather reference results. The subsequent odd numbered run
+ * will have the probe inserted.
+ */
+ if ((test_case_run_count & 1) == 0) {
+ /* Save results from run without probe */
+ u32 *mem = (u32 *)result_regs.ARM_sp;
+ expected_regs = result_regs;
+ memcpy(expected_memory, mem, expected_memory_size(mem));
+
+ /* Insert probe onto test case instruction */
+ if (register_test_probe(&test_case_probe) < 0) {
+ test_case_failed("register test_case_probe failed");
+ goto fail;
+ }
+ } else {
+ /* Check probe ran as expected */
+ if (probe_should_run == 1) {
+ if (test_case_probe.hit != test_instance) {
+ test_case_failed("test_case_handler not run");
+ goto fail;
+ }
+ } else if (probe_should_run == 0) {
+ if (test_case_probe.hit == test_instance) {
+ test_case_failed("test_case_handler ran");
+ goto fail;
+ }
+ }
+
+ /* Remove probe for any subsequent reference run */
+ unregister_test_probe(&test_case_probe);
+
+ if (!check_test_results())
+ goto fail;
+
+ if (is_last_scenario)
+ goto pass;
+ }
+
+ /* Do next test run */
+ ++test_case_run_count;
+ ++test_instance;
+ return current_code_start;
+fail:
+ ++test_fail_count;
+ goto end;
+pass:
+ ++test_pass_count;
+end:
+ test_case_cleanup();
+ return 0;
+}
+
+
+/*
+ * Top level test functions
+ */
+
+static int run_test_cases(void (*tests)(void), const union decode_item *table)
+{
+ int ret;
+
+ pr_info(" Check decoding tables\n");
+ ret = table_test(table);
+ if (ret)
+ return ret;
+
+ pr_info(" Run test cases\n");
+ ret = coverage_start(table);
+ if (ret)
+ return ret;
+
+ tests();
+
+ coverage_end();
+ return 0;
+}
+
+
+static int __init run_all_tests(void)
+{
+ int ret = 0;
+
+ pr_info("Beginning kprobe tests...\n");
+
+#ifndef CONFIG_THUMB2_KERNEL
+
+ pr_info("Probe ARM code\n");
+ ret = run_api_tests(arm_func);
+ if (ret)
+ goto out;
+
+ pr_info("ARM instruction simulation\n");
+ ret = run_test_cases(kprobe_arm_test_cases, probes_decode_arm_table);
+ if (ret)
+ goto out;
+
+#else /* CONFIG_THUMB2_KERNEL */
+
+ pr_info("Probe 16-bit Thumb code\n");
+ ret = run_api_tests(thumb16_func);
+ if (ret)
+ goto out;
+
+ pr_info("Probe 32-bit Thumb code, even halfword\n");
+ ret = run_api_tests(thumb32even_func);
+ if (ret)
+ goto out;
+
+ pr_info("Probe 32-bit Thumb code, odd halfword\n");
+ ret = run_api_tests(thumb32odd_func);
+ if (ret)
+ goto out;
+
+ pr_info("16-bit Thumb instruction simulation\n");
+ ret = run_test_cases(kprobe_thumb16_test_cases,
+ probes_decode_thumb16_table);
+ if (ret)
+ goto out;
+
+ pr_info("32-bit Thumb instruction simulation\n");
+ ret = run_test_cases(kprobe_thumb32_test_cases,
+ probes_decode_thumb32_table);
+ if (ret)
+ goto out;
+#endif
+
+ pr_info("Total instruction simulation tests=%d, pass=%d fail=%d\n",
+ test_try_count, test_pass_count, test_fail_count);
+ if (test_fail_count) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+#if BENCHMARKING
+ pr_info("Benchmarks\n");
+ ret = run_benchmarks();
+ if (ret)
+ goto out;
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 7
+ /* We are able to run all test cases so coverage should be complete */
+ if (coverage_fail) {
+ pr_err("FAIL: Test coverage checks failed\n");
+ ret = -EINVAL;
+ goto out;
+ }
+#endif
+
+out:
+ if (ret == 0)
+ ret = tests_failed;
+ if (ret == 0)
+ pr_info("Finished kprobe tests OK\n");
+ else
+ pr_err("kprobe tests failed\n");
+
+ return ret;
+}
+
+
+/*
+ * Module setup
+ */
+
+#ifdef MODULE
+
+static void __exit kprobe_test_exit(void)
+{
+}
+
+module_init(run_all_tests)
+module_exit(kprobe_test_exit)
+MODULE_LICENSE("GPL");
+
+#else /* !MODULE */
+
+late_initcall(run_all_tests);
+
+#endif
diff --git a/arch/arm/probes/kprobes/test-core.h b/arch/arm/probes/kprobes/test-core.h
new file mode 100644
index 000000000..94285203e
--- /dev/null
+++ b/arch/arm/probes/kprobes/test-core.h
@@ -0,0 +1,458 @@
+/*
+ * arch/arm/probes/kprobes/test-core.h
+ *
+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.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.
+ */
+
+#define VERBOSE 0 /* Set to '1' for more logging of test cases */
+
+#ifdef CONFIG_THUMB2_KERNEL
+#define NORMAL_ISA "16"
+#else
+#define NORMAL_ISA "32"
+#endif
+
+
+/* Flags used in kprobe_test_flags */
+#define TEST_FLAG_NO_ITBLOCK (1<<0)
+#define TEST_FLAG_FULL_ITBLOCK (1<<1)
+#define TEST_FLAG_NARROW_INSTR (1<<2)
+
+extern int kprobe_test_flags;
+extern int kprobe_test_cc_position;
+
+
+#define TEST_MEMORY_SIZE 256
+
+
+/*
+ * Test case structures.
+ *
+ * The arguments given to test cases can be one of three types.
+ *
+ * ARG_TYPE_REG
+ * Load a register with the given value.
+ *
+ * ARG_TYPE_PTR
+ * Load a register with a pointer into the stack buffer (SP + given value).
+ *
+ * ARG_TYPE_MEM
+ * Store the given value into the stack buffer at [SP+index].
+ *
+ */
+
+#define ARG_TYPE_END 0
+#define ARG_TYPE_REG 1
+#define ARG_TYPE_PTR 2
+#define ARG_TYPE_MEM 3
+#define ARG_TYPE_REG_MASKED 4
+
+#define ARG_FLAG_UNSUPPORTED 0x01
+#define ARG_FLAG_SUPPORTED 0x02
+#define ARG_FLAG_THUMB 0x10 /* Must be 16 so TEST_ISA can be used */
+#define ARG_FLAG_ARM 0x20 /* Must be 32 so TEST_ISA can be used */
+
+struct test_arg {
+ u8 type; /* ARG_TYPE_x */
+ u8 _padding[7];
+};
+
+struct test_arg_regptr {
+ u8 type; /* ARG_TYPE_REG or ARG_TYPE_PTR or ARG_TYPE_REG_MASKED */
+ u8 reg;
+ u8 _padding[2];
+ u32 val;
+};
+
+struct test_arg_mem {
+ u8 type; /* ARG_TYPE_MEM */
+ u8 index;
+ u8 _padding[2];
+ u32 val;
+};
+
+struct test_arg_end {
+ u8 type; /* ARG_TYPE_END */
+ u8 flags; /* ARG_FLAG_x */
+ u16 code_offset;
+ u16 branch_offset;
+ u16 end_offset;
+};
+
+
+/*
+ * Building blocks for test cases.
+ *
+ * Each test case is wrapped between TESTCASE_START and TESTCASE_END.
+ *
+ * To specify arguments for a test case the TEST_ARG_{REG,PTR,MEM} macros are
+ * used followed by a terminating TEST_ARG_END.
+ *
+ * After this, the instruction to be tested is defined with TEST_INSTRUCTION.
+ * Or for branches, TEST_BRANCH_B and TEST_BRANCH_F (branch forwards/backwards).
+ *
+ * Some specific test cases may make use of other custom constructs.
+ */
+
+#if VERBOSE
+#define verbose(fmt, ...) pr_info(fmt, ##__VA_ARGS__)
+#else
+#define verbose(fmt, ...)
+#endif
+
+#define TEST_GROUP(title) \
+ verbose("\n"); \
+ verbose(title"\n"); \
+ verbose("---------------------------------------------------------\n");
+
+#define TESTCASE_START(title) \
+ __asm__ __volatile__ ( \
+ "bl __kprobes_test_case_start \n\t" \
+ ".pushsection .rodata \n\t" \
+ "10: \n\t" \
+ /* don't use .asciz here as 'title' may be */ \
+ /* multiple strings to be concatenated. */ \
+ ".ascii "#title" \n\t" \
+ ".byte 0 \n\t" \
+ ".popsection \n\t" \
+ ".word 10b \n\t"
+
+#define TEST_ARG_REG(reg, val) \
+ ".byte "__stringify(ARG_TYPE_REG)" \n\t" \
+ ".byte "#reg" \n\t" \
+ ".short 0 \n\t" \
+ ".word "#val" \n\t"
+
+#define TEST_ARG_PTR(reg, val) \
+ ".byte "__stringify(ARG_TYPE_PTR)" \n\t" \
+ ".byte "#reg" \n\t" \
+ ".short 0 \n\t" \
+ ".word "#val" \n\t"
+
+#define TEST_ARG_MEM(index, val) \
+ ".byte "__stringify(ARG_TYPE_MEM)" \n\t" \
+ ".byte "#index" \n\t" \
+ ".short 0 \n\t" \
+ ".word "#val" \n\t"
+
+#define TEST_ARG_REG_MASKED(reg, val) \
+ ".byte "__stringify(ARG_TYPE_REG_MASKED)" \n\t" \
+ ".byte "#reg" \n\t" \
+ ".short 0 \n\t" \
+ ".word "#val" \n\t"
+
+#define TEST_ARG_END(flags) \
+ ".byte "__stringify(ARG_TYPE_END)" \n\t" \
+ ".byte "TEST_ISA flags" \n\t" \
+ ".short 50f-0f \n\t" \
+ ".short 2f-0f \n\t" \
+ ".short 99f-0f \n\t" \
+ ".code "TEST_ISA" \n\t" \
+ "0: \n\t"
+
+#define TEST_INSTRUCTION(instruction) \
+ "50: nop \n\t" \
+ "1: "instruction" \n\t" \
+ " nop \n\t"
+
+#define TEST_BRANCH_F(instruction) \
+ TEST_INSTRUCTION(instruction) \
+ " b 99f \n\t" \
+ "2: nop \n\t"
+
+#define TEST_BRANCH_B(instruction) \
+ " b 50f \n\t" \
+ " b 99f \n\t" \
+ "2: nop \n\t" \
+ " b 99f \n\t" \
+ TEST_INSTRUCTION(instruction)
+
+#define TEST_BRANCH_FX(instruction, codex) \
+ TEST_INSTRUCTION(instruction) \
+ " b 99f \n\t" \
+ codex" \n\t" \
+ " b 99f \n\t" \
+ "2: nop \n\t"
+
+#define TEST_BRANCH_BX(instruction, codex) \
+ " b 50f \n\t" \
+ " b 99f \n\t" \
+ "2: nop \n\t" \
+ " b 99f \n\t" \
+ codex" \n\t" \
+ TEST_INSTRUCTION(instruction)
+
+#define TESTCASE_END \
+ "2: \n\t" \
+ "99: \n\t" \
+ " bl __kprobes_test_case_end_"TEST_ISA" \n\t" \
+ ".code "NORMAL_ISA" \n\t" \
+ : : \
+ : "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc" \
+ );
+
+
+/*
+ * Macros to define test cases.
+ *
+ * Those of the form TEST_{R,P,M}* can be used to define test cases
+ * which take combinations of the three basic types of arguments. E.g.
+ *
+ * TEST_R One register argument
+ * TEST_RR Two register arguments
+ * TEST_RPR A register, a pointer, then a register argument
+ *
+ * For testing instructions which may branch, there are macros TEST_BF_*
+ * and TEST_BB_* for branching forwards and backwards.
+ *
+ * TEST_SUPPORTED and TEST_UNSUPPORTED don't cause the code to be executed,
+ * the just verify that a kprobe is or is not allowed on the given instruction.
+ */
+
+#define TEST(code) \
+ TESTCASE_START(code) \
+ TEST_ARG_END("") \
+ TEST_INSTRUCTION(code) \
+ TESTCASE_END
+
+#define TEST_UNSUPPORTED(code) \
+ TESTCASE_START(code) \
+ TEST_ARG_END("|"__stringify(ARG_FLAG_UNSUPPORTED)) \
+ TEST_INSTRUCTION(code) \
+ TESTCASE_END
+
+#define TEST_SUPPORTED(code) \
+ TESTCASE_START(code) \
+ TEST_ARG_END("|"__stringify(ARG_FLAG_SUPPORTED)) \
+ TEST_INSTRUCTION(code) \
+ TESTCASE_END
+
+#define TEST_R(code1, reg, val, code2) \
+ TESTCASE_START(code1 #reg code2) \
+ TEST_ARG_REG(reg, val) \
+ TEST_ARG_END("") \
+ TEST_INSTRUCTION(code1 #reg code2) \
+ TESTCASE_END
+
+#define TEST_RR(code1, reg1, val1, code2, reg2, val2, code3) \
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3) \
+ TEST_ARG_REG(reg1, val1) \
+ TEST_ARG_REG(reg2, val2) \
+ TEST_ARG_END("") \
+ TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3) \
+ TESTCASE_END
+
+#define TEST_RRR(code1, reg1, val1, code2, reg2, val2, code3, reg3, val3, code4)\
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3 #reg3 code4) \
+ TEST_ARG_REG(reg1, val1) \
+ TEST_ARG_REG(reg2, val2) \
+ TEST_ARG_REG(reg3, val3) \
+ TEST_ARG_END("") \
+ TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3 #reg3 code4) \
+ TESTCASE_END
+
+#define TEST_RRRR(code1, reg1, val1, code2, reg2, val2, code3, reg3, val3, code4, reg4, val4) \
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3 #reg3 code4 #reg4) \
+ TEST_ARG_REG(reg1, val1) \
+ TEST_ARG_REG(reg2, val2) \
+ TEST_ARG_REG(reg3, val3) \
+ TEST_ARG_REG(reg4, val4) \
+ TEST_ARG_END("") \
+ TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3 #reg3 code4 #reg4) \
+ TESTCASE_END
+
+#define TEST_P(code1, reg1, val1, code2) \
+ TESTCASE_START(code1 #reg1 code2) \
+ TEST_ARG_PTR(reg1, val1) \
+ TEST_ARG_END("") \
+ TEST_INSTRUCTION(code1 #reg1 code2) \
+ TESTCASE_END
+
+#define TEST_PR(code1, reg1, val1, code2, reg2, val2, code3) \
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3) \
+ TEST_ARG_PTR(reg1, val1) \
+ TEST_ARG_REG(reg2, val2) \
+ TEST_ARG_END("") \
+ TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3) \
+ TESTCASE_END
+
+#define TEST_RP(code1, reg1, val1, code2, reg2, val2, code3) \
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3) \
+ TEST_ARG_REG(reg1, val1) \
+ TEST_ARG_PTR(reg2, val2) \
+ TEST_ARG_END("") \
+ TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3) \
+ TESTCASE_END
+
+#define TEST_PRR(code1, reg1, val1, code2, reg2, val2, code3, reg3, val3, code4)\
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3 #reg3 code4) \
+ TEST_ARG_PTR(reg1, val1) \
+ TEST_ARG_REG(reg2, val2) \
+ TEST_ARG_REG(reg3, val3) \
+ TEST_ARG_END("") \
+ TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3 #reg3 code4) \
+ TESTCASE_END
+
+#define TEST_RPR(code1, reg1, val1, code2, reg2, val2, code3, reg3, val3, code4)\
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3 #reg3 code4) \
+ TEST_ARG_REG(reg1, val1) \
+ TEST_ARG_PTR(reg2, val2) \
+ TEST_ARG_REG(reg3, val3) \
+ TEST_ARG_END("") \
+ TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3 #reg3 code4) \
+ TESTCASE_END
+
+#define TEST_RRP(code1, reg1, val1, code2, reg2, val2, code3, reg3, val3, code4)\
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3 #reg3 code4) \
+ TEST_ARG_REG(reg1, val1) \
+ TEST_ARG_REG(reg2, val2) \
+ TEST_ARG_PTR(reg3, val3) \
+ TEST_ARG_END("") \
+ TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3 #reg3 code4) \
+ TESTCASE_END
+
+#define TEST_BF_P(code1, reg1, val1, code2) \
+ TESTCASE_START(code1 #reg1 code2) \
+ TEST_ARG_PTR(reg1, val1) \
+ TEST_ARG_END("") \
+ TEST_BRANCH_F(code1 #reg1 code2) \
+ TESTCASE_END
+
+#define TEST_BF(code) \
+ TESTCASE_START(code) \
+ TEST_ARG_END("") \
+ TEST_BRANCH_F(code) \
+ TESTCASE_END
+
+#define TEST_BB(code) \
+ TESTCASE_START(code) \
+ TEST_ARG_END("") \
+ TEST_BRANCH_B(code) \
+ TESTCASE_END
+
+#define TEST_BF_R(code1, reg, val, code2) \
+ TESTCASE_START(code1 #reg code2) \
+ TEST_ARG_REG(reg, val) \
+ TEST_ARG_END("") \
+ TEST_BRANCH_F(code1 #reg code2) \
+ TESTCASE_END
+
+#define TEST_BB_R(code1, reg, val, code2) \
+ TESTCASE_START(code1 #reg code2) \
+ TEST_ARG_REG(reg, val) \
+ TEST_ARG_END("") \
+ TEST_BRANCH_B(code1 #reg code2) \
+ TESTCASE_END
+
+#define TEST_BF_RR(code1, reg1, val1, code2, reg2, val2, code3) \
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3) \
+ TEST_ARG_REG(reg1, val1) \
+ TEST_ARG_REG(reg2, val2) \
+ TEST_ARG_END("") \
+ TEST_BRANCH_F(code1 #reg1 code2 #reg2 code3) \
+ TESTCASE_END
+
+#define TEST_BF_X(code, codex) \
+ TESTCASE_START(code) \
+ TEST_ARG_END("") \
+ TEST_BRANCH_FX(code, codex) \
+ TESTCASE_END
+
+#define TEST_BB_X(code, codex) \
+ TESTCASE_START(code) \
+ TEST_ARG_END("") \
+ TEST_BRANCH_BX(code, codex) \
+ TESTCASE_END
+
+#define TEST_BF_RX(code1, reg, val, code2, codex) \
+ TESTCASE_START(code1 #reg code2) \
+ TEST_ARG_REG(reg, val) \
+ TEST_ARG_END("") \
+ TEST_BRANCH_FX(code1 #reg code2, codex) \
+ TESTCASE_END
+
+#define TEST_X(code, codex) \
+ TESTCASE_START(code) \
+ TEST_ARG_END("") \
+ TEST_INSTRUCTION(code) \
+ " b 99f \n\t" \
+ " "codex" \n\t" \
+ TESTCASE_END
+
+#define TEST_RX(code1, reg, val, code2, codex) \
+ TESTCASE_START(code1 #reg code2) \
+ TEST_ARG_REG(reg, val) \
+ TEST_ARG_END("") \
+ TEST_INSTRUCTION(code1 __stringify(reg) code2) \
+ " b 99f \n\t" \
+ " "codex" \n\t" \
+ TESTCASE_END
+
+#define TEST_RRX(code1, reg1, val1, code2, reg2, val2, code3, codex) \
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3) \
+ TEST_ARG_REG(reg1, val1) \
+ TEST_ARG_REG(reg2, val2) \
+ TEST_ARG_END("") \
+ TEST_INSTRUCTION(code1 __stringify(reg1) code2 __stringify(reg2) code3) \
+ " b 99f \n\t" \
+ " "codex" \n\t" \
+ TESTCASE_END
+
+#define TEST_RMASKED(code1, reg, mask, code2) \
+ TESTCASE_START(code1 #reg code2) \
+ TEST_ARG_REG_MASKED(reg, mask) \
+ TEST_ARG_END("") \
+ TEST_INSTRUCTION(code1 #reg code2) \
+ TESTCASE_END
+
+/*
+ * We ignore the state of the imprecise abort disable flag (CPSR.A) because this
+ * can change randomly as the kernel doesn't take care to preserve or initialise
+ * this across context switches. Also, with Security Extensions, the flag may
+ * not be under control of the kernel; for this reason we ignore the state of
+ * the FIQ disable flag CPSR.F as well.
+ */
+#define PSR_IGNORE_BITS (PSR_A_BIT | PSR_F_BIT)
+
+
+/*
+ * Macros for defining space directives spread over multiple lines.
+ * These are required so the compiler guesses better the length of inline asm
+ * code and will spill the literal pool early enough to avoid generating PC
+ * relative loads with out of range offsets.
+ */
+#define TWICE(x) x x
+#define SPACE_0x8 TWICE(".space 4\n\t")
+#define SPACE_0x10 TWICE(SPACE_0x8)
+#define SPACE_0x20 TWICE(SPACE_0x10)
+#define SPACE_0x40 TWICE(SPACE_0x20)
+#define SPACE_0x80 TWICE(SPACE_0x40)
+#define SPACE_0x100 TWICE(SPACE_0x80)
+#define SPACE_0x200 TWICE(SPACE_0x100)
+#define SPACE_0x400 TWICE(SPACE_0x200)
+#define SPACE_0x800 TWICE(SPACE_0x400)
+#define SPACE_0x1000 TWICE(SPACE_0x800)
+
+
+/* Various values used in test cases... */
+#define N(val) (val ^ 0xffffffff)
+#define VAL1 0x12345678
+#define VAL2 N(VAL1)
+#define VAL3 0xa5f801
+#define VAL4 N(VAL3)
+#define VALM 0x456789ab
+#define VALR 0xdeaddead
+#define HH1 0x0123fecb
+#define HH2 0xa9874567
+
+
+#ifdef CONFIG_THUMB2_KERNEL
+void kprobe_thumb16_test_cases(void);
+void kprobe_thumb32_test_cases(void);
+#else
+void kprobe_arm_test_cases(void);
+#endif
diff --git a/arch/arm/probes/kprobes/test-thumb.c b/arch/arm/probes/kprobes/test-thumb.c
new file mode 100644
index 000000000..b683b4517
--- /dev/null
+++ b/arch/arm/probes/kprobes/test-thumb.c
@@ -0,0 +1,1200 @@
+/*
+ * arch/arm/probes/kprobes/test-thumb.c
+ *
+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.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/module.h>
+#include <asm/opcodes.h>
+#include <asm/probes.h>
+
+#include "test-core.h"
+
+
+#define TEST_ISA "16"
+
+#define DONT_TEST_IN_ITBLOCK(tests) \
+ kprobe_test_flags |= TEST_FLAG_NO_ITBLOCK; \
+ tests \
+ kprobe_test_flags &= ~TEST_FLAG_NO_ITBLOCK;
+
+#define CONDITION_INSTRUCTIONS(cc_pos, tests) \
+ kprobe_test_cc_position = cc_pos; \
+ DONT_TEST_IN_ITBLOCK(tests) \
+ kprobe_test_cc_position = 0;
+
+#define TEST_ITBLOCK(code) \
+ kprobe_test_flags |= TEST_FLAG_FULL_ITBLOCK; \
+ TESTCASE_START(code) \
+ TEST_ARG_END("") \
+ "50: nop \n\t" \
+ "1: "code" \n\t" \
+ " mov r1, #0x11 \n\t" \
+ " mov r2, #0x22 \n\t" \
+ " mov r3, #0x33 \n\t" \
+ "2: nop \n\t" \
+ TESTCASE_END \
+ kprobe_test_flags &= ~TEST_FLAG_FULL_ITBLOCK;
+
+#define TEST_THUMB_TO_ARM_INTERWORK_P(code1, reg, val, code2) \
+ TESTCASE_START(code1 #reg code2) \
+ TEST_ARG_PTR(reg, val) \
+ TEST_ARG_REG(14, 99f+1) \
+ TEST_ARG_MEM(15, 3f) \
+ TEST_ARG_END("") \
+ " nop \n\t" /* To align 1f */ \
+ "50: nop \n\t" \
+ "1: "code1 #reg code2" \n\t" \
+ " bx lr \n\t" \
+ ".arm \n\t" \
+ "3: adr lr, 2f+1 \n\t" \
+ " bx lr \n\t" \
+ ".thumb \n\t" \
+ "2: nop \n\t" \
+ TESTCASE_END
+
+
+void kprobe_thumb16_test_cases(void)
+{
+ kprobe_test_flags = TEST_FLAG_NARROW_INSTR;
+
+ TEST_GROUP("Shift (immediate), add, subtract, move, and compare")
+
+ TEST_R( "lsls r7, r",0,VAL1,", #5")
+ TEST_R( "lsls r0, r",7,VAL2,", #11")
+ TEST_R( "lsrs r7, r",0,VAL1,", #5")
+ TEST_R( "lsrs r0, r",7,VAL2,", #11")
+ TEST_R( "asrs r7, r",0,VAL1,", #5")
+ TEST_R( "asrs r0, r",7,VAL2,", #11")
+ TEST_RR( "adds r2, r",0,VAL1,", r",7,VAL2,"")
+ TEST_RR( "adds r5, r",7,VAL2,", r",0,VAL2,"")
+ TEST_RR( "subs r2, r",0,VAL1,", r",7,VAL2,"")
+ TEST_RR( "subs r5, r",7,VAL2,", r",0,VAL2,"")
+ TEST_R( "adds r7, r",0,VAL1,", #5")
+ TEST_R( "adds r0, r",7,VAL2,", #2")
+ TEST_R( "subs r7, r",0,VAL1,", #5")
+ TEST_R( "subs r0, r",7,VAL2,", #2")
+ TEST( "movs.n r0, #0x5f")
+ TEST( "movs.n r7, #0xa0")
+ TEST_R( "cmp.n r",0,0x5e, ", #0x5f")
+ TEST_R( "cmp.n r",5,0x15f,", #0x5f")
+ TEST_R( "cmp.n r",7,0xa0, ", #0xa0")
+ TEST_R( "adds.n r",0,VAL1,", #0x5f")
+ TEST_R( "adds.n r",7,VAL2,", #0xa0")
+ TEST_R( "subs.n r",0,VAL1,", #0x5f")
+ TEST_R( "subs.n r",7,VAL2,", #0xa0")
+
+ TEST_GROUP("16-bit Thumb data-processing instructions")
+
+#define DATA_PROCESSING16(op,val) \
+ TEST_RR( op" r",0,VAL1,", r",7,val,"") \
+ TEST_RR( op" r",7,VAL2,", r",0,val,"")
+
+ DATA_PROCESSING16("ands",0xf00f00ff)
+ DATA_PROCESSING16("eors",0xf00f00ff)
+ DATA_PROCESSING16("lsls",11)
+ DATA_PROCESSING16("lsrs",11)
+ DATA_PROCESSING16("asrs",11)
+ DATA_PROCESSING16("adcs",VAL2)
+ DATA_PROCESSING16("sbcs",VAL2)
+ DATA_PROCESSING16("rors",11)
+ DATA_PROCESSING16("tst",0xf00f00ff)
+ TEST_R("rsbs r",0,VAL1,", #0")
+ TEST_R("rsbs r",7,VAL2,", #0")
+ DATA_PROCESSING16("cmp",0xf00f00ff)
+ DATA_PROCESSING16("cmn",0xf00f00ff)
+ DATA_PROCESSING16("orrs",0xf00f00ff)
+ DATA_PROCESSING16("muls",VAL2)
+ DATA_PROCESSING16("bics",0xf00f00ff)
+ DATA_PROCESSING16("mvns",VAL2)
+
+ TEST_GROUP("Special data instructions and branch and exchange")
+
+ TEST_RR( "add r",0, VAL1,", r",7,VAL2,"")
+ TEST_RR( "add r",3, VAL2,", r",8,VAL3,"")
+ TEST_RR( "add r",8, VAL3,", r",0,VAL1,"")
+ TEST_R( "add sp" ", r",8,-8, "")
+ TEST_R( "add r",14,VAL1,", pc")
+ TEST_BF_R("add pc" ", r",0,2f-1f-8,"")
+ TEST_UNSUPPORTED(__inst_thumb16(0x44ff) " @ add pc, pc")
+
+ TEST_RR( "cmp r",3,VAL1,", r",8,VAL2,"")
+ TEST_RR( "cmp r",8,VAL2,", r",0,VAL1,"")
+ TEST_R( "cmp sp" ", r",8,-8, "")
+
+ TEST_R( "mov r0, r",7,VAL2,"")
+ TEST_R( "mov r3, r",8,VAL3,"")
+ TEST_R( "mov r8, r",0,VAL1,"")
+ TEST_P( "mov sp, r",8,-8, "")
+ TEST( "mov lr, pc")
+ TEST_BF_R("mov pc, r",0,2f, "")
+
+ TEST_BF_R("bx r",0, 2f+1,"")
+ TEST_BF_R("bx r",14,2f+1,"")
+ TESTCASE_START("bx pc")
+ TEST_ARG_REG(14, 99f+1)
+ TEST_ARG_END("")
+ " nop \n\t" /* To align the bx pc*/
+ "50: nop \n\t"
+ "1: bx pc \n\t"
+ " bx lr \n\t"
+ ".arm \n\t"
+ " adr lr, 2f+1 \n\t"
+ " bx lr \n\t"
+ ".thumb \n\t"
+ "2: nop \n\t"
+ TESTCASE_END
+
+ TEST_BF_R("blx r",0, 2f+1,"")
+ TEST_BB_R("blx r",14,2f+1,"")
+ TEST_UNSUPPORTED(__inst_thumb16(0x47f8) " @ blx pc")
+
+ TEST_GROUP("Load from Literal Pool")
+
+ TEST_X( "ldr r0, 3f",
+ ".align \n\t"
+ "3: .word "__stringify(VAL1))
+ TEST_X( "ldr r7, 3f",
+ ".space 128 \n\t"
+ ".align \n\t"
+ "3: .word "__stringify(VAL2))
+
+ TEST_GROUP("16-bit Thumb Load/store instructions")
+
+ TEST_RPR("str r",0, VAL1,", [r",1, 24,", r",2, 48,"]")
+ TEST_RPR("str r",7, VAL2,", [r",6, 24,", r",5, 48,"]")
+ TEST_RPR("strh r",0, VAL1,", [r",1, 24,", r",2, 48,"]")
+ TEST_RPR("strh r",7, VAL2,", [r",6, 24,", r",5, 48,"]")
+ TEST_RPR("strb r",0, VAL1,", [r",1, 24,", r",2, 48,"]")
+ TEST_RPR("strb r",7, VAL2,", [r",6, 24,", r",5, 48,"]")
+ TEST_PR( "ldrsb r0, [r",1, 24,", r",2, 48,"]")
+ TEST_PR( "ldrsb r7, [r",6, 24,", r",5, 50,"]")
+ TEST_PR( "ldr r0, [r",1, 24,", r",2, 48,"]")
+ TEST_PR( "ldr r7, [r",6, 24,", r",5, 48,"]")
+ TEST_PR( "ldrh r0, [r",1, 24,", r",2, 48,"]")
+ TEST_PR( "ldrh r7, [r",6, 24,", r",5, 50,"]")
+ TEST_PR( "ldrb r0, [r",1, 24,", r",2, 48,"]")
+ TEST_PR( "ldrb r7, [r",6, 24,", r",5, 50,"]")
+ TEST_PR( "ldrsh r0, [r",1, 24,", r",2, 48,"]")
+ TEST_PR( "ldrsh r7, [r",6, 24,", r",5, 50,"]")
+
+ TEST_RP("str r",0, VAL1,", [r",1, 24,", #120]")
+ TEST_RP("str r",7, VAL2,", [r",6, 24,", #120]")
+ TEST_P( "ldr r0, [r",1, 24,", #120]")
+ TEST_P( "ldr r7, [r",6, 24,", #120]")
+ TEST_RP("strb r",0, VAL1,", [r",1, 24,", #30]")
+ TEST_RP("strb r",7, VAL2,", [r",6, 24,", #30]")
+ TEST_P( "ldrb r0, [r",1, 24,", #30]")
+ TEST_P( "ldrb r7, [r",6, 24,", #30]")
+ TEST_RP("strh r",0, VAL1,", [r",1, 24,", #60]")
+ TEST_RP("strh r",7, VAL2,", [r",6, 24,", #60]")
+ TEST_P( "ldrh r0, [r",1, 24,", #60]")
+ TEST_P( "ldrh r7, [r",6, 24,", #60]")
+
+ TEST_R( "str r",0, VAL1,", [sp, #0]")
+ TEST_R( "str r",7, VAL2,", [sp, #160]")
+ TEST( "ldr r0, [sp, #0]")
+ TEST( "ldr r7, [sp, #160]")
+
+ TEST_RP("str r",0, VAL1,", [r",0, 24,"]")
+ TEST_P( "ldr r0, [r",0, 24,"]")
+
+ TEST_GROUP("Generate PC-/SP-relative address")
+
+ TEST("add r0, pc, #4")
+ TEST("add r7, pc, #1020")
+ TEST("add r0, sp, #4")
+ TEST("add r7, sp, #1020")
+
+ TEST_GROUP("Miscellaneous 16-bit instructions")
+
+ TEST_UNSUPPORTED( "cpsie i")
+ TEST_UNSUPPORTED( "cpsid i")
+ TEST_UNSUPPORTED( "setend le")
+ TEST_UNSUPPORTED( "setend be")
+
+ TEST("add sp, #"__stringify(TEST_MEMORY_SIZE)) /* Assumes TEST_MEMORY_SIZE < 0x400 */
+ TEST("sub sp, #0x7f*4")
+
+DONT_TEST_IN_ITBLOCK(
+ TEST_BF_R( "cbnz r",0,0, ", 2f")
+ TEST_BF_R( "cbz r",2,-1,", 2f")
+ TEST_BF_RX( "cbnz r",4,1, ", 2f", SPACE_0x20)
+ TEST_BF_RX( "cbz r",7,0, ", 2f", SPACE_0x40)
+)
+ TEST_R("sxth r0, r",7, HH1,"")
+ TEST_R("sxth r7, r",0, HH2,"")
+ TEST_R("sxtb r0, r",7, HH1,"")
+ TEST_R("sxtb r7, r",0, HH2,"")
+ TEST_R("uxth r0, r",7, HH1,"")
+ TEST_R("uxth r7, r",0, HH2,"")
+ TEST_R("uxtb r0, r",7, HH1,"")
+ TEST_R("uxtb r7, r",0, HH2,"")
+ TEST_R("rev r0, r",7, VAL1,"")
+ TEST_R("rev r7, r",0, VAL2,"")
+ TEST_R("rev16 r0, r",7, VAL1,"")
+ TEST_R("rev16 r7, r",0, VAL2,"")
+ TEST_UNSUPPORTED(__inst_thumb16(0xba80) "")
+ TEST_UNSUPPORTED(__inst_thumb16(0xbabf) "")
+ TEST_R("revsh r0, r",7, VAL1,"")
+ TEST_R("revsh r7, r",0, VAL2,"")
+
+#define TEST_POPPC(code, offset) \
+ TESTCASE_START(code) \
+ TEST_ARG_PTR(13, offset) \
+ TEST_ARG_END("") \
+ TEST_BRANCH_F(code) \
+ TESTCASE_END
+
+ TEST("push {r0}")
+ TEST("push {r7}")
+ TEST("push {r14}")
+ TEST("push {r0-r7,r14}")
+ TEST("push {r0,r2,r4,r6,r14}")
+ TEST("push {r1,r3,r5,r7}")
+ TEST("pop {r0}")
+ TEST("pop {r7}")
+ TEST("pop {r0,r2,r4,r6}")
+ TEST_POPPC("pop {pc}",15*4)
+ TEST_POPPC("pop {r0-r7,pc}",7*4)
+ TEST_POPPC("pop {r1,r3,r5,r7,pc}",11*4)
+ TEST_THUMB_TO_ARM_INTERWORK_P("pop {pc} @ ",13,15*4,"")
+ TEST_THUMB_TO_ARM_INTERWORK_P("pop {r0-r7,pc} @ ",13,7*4,"")
+
+ TEST_UNSUPPORTED("bkpt.n 0")
+ TEST_UNSUPPORTED("bkpt.n 255")
+
+ TEST_SUPPORTED("yield")
+ TEST("sev")
+ TEST("nop")
+ TEST("wfi")
+ TEST_SUPPORTED("wfe")
+ TEST_UNSUPPORTED(__inst_thumb16(0xbf50) "") /* Unassigned hints */
+ TEST_UNSUPPORTED(__inst_thumb16(0xbff0) "") /* Unassigned hints */
+
+#define TEST_IT(code, code2) \
+ TESTCASE_START(code) \
+ TEST_ARG_END("") \
+ "50: nop \n\t" \
+ "1: "code" \n\t" \
+ " "code2" \n\t" \
+ "2: nop \n\t" \
+ TESTCASE_END
+
+DONT_TEST_IN_ITBLOCK(
+ TEST_IT("it eq","moveq r0,#0")
+ TEST_IT("it vc","movvc r0,#0")
+ TEST_IT("it le","movle r0,#0")
+ TEST_IT("ite eq","moveq r0,#0\n\t movne r1,#1")
+ TEST_IT("itet vc","movvc r0,#0\n\t movvs r1,#1\n\t movvc r2,#2")
+ TEST_IT("itete le","movle r0,#0\n\t movgt r1,#1\n\t movle r2,#2\n\t movgt r3,#3")
+ TEST_IT("itttt le","movle r0,#0\n\t movle r1,#1\n\t movle r2,#2\n\t movle r3,#3")
+ TEST_IT("iteee le","movle r0,#0\n\t movgt r1,#1\n\t movgt r2,#2\n\t movgt r3,#3")
+)
+
+ TEST_GROUP("Load and store multiple")
+
+ TEST_P("ldmia r",4, 16*4,"!, {r0,r7}")
+ TEST_P("ldmia r",7, 16*4,"!, {r0-r6}")
+ TEST_P("stmia r",4, 16*4,"!, {r0,r7}")
+ TEST_P("stmia r",0, 16*4,"!, {r0-r7}")
+
+ TEST_GROUP("Conditional branch and Supervisor Call instructions")
+
+CONDITION_INSTRUCTIONS(8,
+ TEST_BF("beq 2f")
+ TEST_BB("bne 2b")
+ TEST_BF("bgt 2f")
+ TEST_BB("blt 2b")
+)
+ TEST_UNSUPPORTED(__inst_thumb16(0xde00) "")
+ TEST_UNSUPPORTED(__inst_thumb16(0xdeff) "")
+ TEST_UNSUPPORTED("svc #0x00")
+ TEST_UNSUPPORTED("svc #0xff")
+
+ TEST_GROUP("Unconditional branch")
+
+ TEST_BF( "b 2f")
+ TEST_BB( "b 2b")
+ TEST_BF_X("b 2f", SPACE_0x400)
+ TEST_BB_X("b 2b", SPACE_0x400)
+
+ TEST_GROUP("Testing instructions in IT blocks")
+
+ TEST_ITBLOCK("subs.n r0, r0")
+
+ verbose("\n");
+}
+
+
+void kprobe_thumb32_test_cases(void)
+{
+ kprobe_test_flags = 0;
+
+ TEST_GROUP("Load/store multiple")
+
+ TEST_UNSUPPORTED("rfedb sp")
+ TEST_UNSUPPORTED("rfeia sp")
+ TEST_UNSUPPORTED("rfedb sp!")
+ TEST_UNSUPPORTED("rfeia sp!")
+
+ TEST_P( "stmia r",0, 16*4,", {r0,r8}")
+ TEST_P( "stmia r",4, 16*4,", {r0-r12,r14}")
+ TEST_P( "stmia r",7, 16*4,"!, {r8-r12,r14}")
+ TEST_P( "stmia r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+
+ TEST_P( "ldmia r",0, 16*4,", {r0,r8}")
+ TEST_P( "ldmia r",4, 0, ", {r0-r12,r14}")
+ TEST_BF_P("ldmia r",5, 8*4, "!, {r6-r12,r15}")
+ TEST_P( "ldmia r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+ TEST_BF_P("ldmia r",14,14*4,"!, {r4,pc}")
+
+ TEST_P( "stmdb r",0, 16*4,", {r0,r8}")
+ TEST_P( "stmdb r",4, 16*4,", {r0-r12,r14}")
+ TEST_P( "stmdb r",5, 16*4,"!, {r8-r12,r14}")
+ TEST_P( "stmdb r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+
+ TEST_P( "ldmdb r",0, 16*4,", {r0,r8}")
+ TEST_P( "ldmdb r",4, 16*4,", {r0-r12,r14}")
+ TEST_BF_P("ldmdb r",5, 16*4,"!, {r6-r12,r15}")
+ TEST_P( "ldmdb r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+ TEST_BF_P("ldmdb r",14,16*4,"!, {r4,pc}")
+
+ TEST_P( "stmdb r",13,16*4,"!, {r3-r12,lr}")
+ TEST_P( "stmdb r",13,16*4,"!, {r3-r12}")
+ TEST_P( "stmdb r",2, 16*4,", {r3-r12,lr}")
+ TEST_P( "stmdb r",13,16*4,"!, {r2-r12,lr}")
+ TEST_P( "stmdb r",0, 16*4,", {r0-r12}")
+ TEST_P( "stmdb r",0, 16*4,", {r0-r12,lr}")
+
+ TEST_BF_P("ldmia r",13,5*4, "!, {r3-r12,pc}")
+ TEST_P( "ldmia r",13,5*4, "!, {r3-r12}")
+ TEST_BF_P("ldmia r",2, 5*4, "!, {r3-r12,pc}")
+ TEST_BF_P("ldmia r",13,4*4, "!, {r2-r12,pc}")
+ TEST_P( "ldmia r",0, 16*4,", {r0-r12}")
+ TEST_P( "ldmia r",0, 16*4,", {r0-r12,lr}")
+
+ TEST_THUMB_TO_ARM_INTERWORK_P("ldmia r",0,14*4,", {r12,pc}")
+ TEST_THUMB_TO_ARM_INTERWORK_P("ldmia r",13,2*4,", {r0-r12,pc}")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xe88f0101) " @ stmia pc, {r0,r8}")
+ TEST_UNSUPPORTED(__inst_thumb32(0xe92f5f00) " @ stmdb pc!, {r8-r12,r14}")
+ TEST_UNSUPPORTED(__inst_thumb32(0xe8bdc000) " @ ldmia r13!, {r14,pc}")
+ TEST_UNSUPPORTED(__inst_thumb32(0xe93ec000) " @ ldmdb r14!, {r14,pc}")
+ TEST_UNSUPPORTED(__inst_thumb32(0xe8a73f00) " @ stmia r7!, {r8-r12,sp}")
+ TEST_UNSUPPORTED(__inst_thumb32(0xe8a79f00) " @ stmia r7!, {r8-r12,pc}")
+ TEST_UNSUPPORTED(__inst_thumb32(0xe93e2010) " @ ldmdb r14!, {r4,sp}")
+
+ TEST_GROUP("Load/store double or exclusive, table branch")
+
+ TEST_P( "ldrd r0, r1, [r",1, 24,", #-16]")
+ TEST( "ldrd r12, r14, [sp, #16]")
+ TEST_P( "ldrd r1, r0, [r",7, 24,", #-16]!")
+ TEST( "ldrd r14, r12, [sp, #16]!")
+ TEST_P( "ldrd r1, r0, [r",7, 24,"], #16")
+ TEST( "ldrd r7, r8, [sp], #-16")
+
+ TEST_X( "ldrd r12, r14, 3f",
+ ".align 3 \n\t"
+ "3: .word "__stringify(VAL1)" \n\t"
+ " .word "__stringify(VAL2))
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xe9ffec04) " @ ldrd r14, r12, [pc, #16]!")
+ TEST_UNSUPPORTED(__inst_thumb32(0xe8ffec04) " @ ldrd r14, r12, [pc], #16")
+ TEST_UNSUPPORTED(__inst_thumb32(0xe9d4d800) " @ ldrd sp, r8, [r4]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xe9d4f800) " @ ldrd pc, r8, [r4]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xe9d47d00) " @ ldrd r7, sp, [r4]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xe9d47f00) " @ ldrd r7, pc, [r4]")
+
+ TEST_RRP("strd r",0, VAL1,", r",1, VAL2,", [r",1, 24,", #-16]")
+ TEST_RR( "strd r",12,VAL2,", r",14,VAL1,", [sp, #16]")
+ TEST_RRP("strd r",1, VAL1,", r",0, VAL2,", [r",7, 24,", #-16]!")
+ TEST_RR( "strd r",14,VAL2,", r",12,VAL1,", [sp, #16]!")
+ TEST_RRP("strd r",1, VAL1,", r",0, VAL2,", [r",7, 24,"], #16")
+ TEST_RR( "strd r",7, VAL2,", r",8, VAL1,", [sp], #-16")
+ TEST_RRP("strd r",6, VAL1,", r",7, VAL2,", [r",13, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!")
+ TEST_UNSUPPORTED("strd r6, r7, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!")
+ TEST_RRP("strd r",4, VAL1,", r",5, VAL2,", [r",14, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!")
+ TEST_UNSUPPORTED(__inst_thumb32(0xe9efec04) " @ strd r14, r12, [pc, #16]!")
+ TEST_UNSUPPORTED(__inst_thumb32(0xe8efec04) " @ strd r14, r12, [pc], #16")
+
+ TEST_RX("tbb [pc, r",0, (9f-(1f+4)),"]",
+ "9: \n\t"
+ ".byte (2f-1b-4)>>1 \n\t"
+ ".byte (3f-1b-4)>>1 \n\t"
+ "3: mvn r0, r0 \n\t"
+ "2: nop \n\t")
+
+ TEST_RX("tbb [pc, r",4, (9f-(1f+4)+1),"]",
+ "9: \n\t"
+ ".byte (2f-1b-4)>>1 \n\t"
+ ".byte (3f-1b-4)>>1 \n\t"
+ "3: mvn r0, r0 \n\t"
+ "2: nop \n\t")
+
+ TEST_RRX("tbb [r",1,9f,", r",2,0,"]",
+ "9: \n\t"
+ ".byte (2f-1b-4)>>1 \n\t"
+ ".byte (3f-1b-4)>>1 \n\t"
+ "3: mvn r0, r0 \n\t"
+ "2: nop \n\t")
+
+ TEST_RX("tbh [pc, r",7, (9f-(1f+4))>>1,"]",
+ "9: \n\t"
+ ".short (2f-1b-4)>>1 \n\t"
+ ".short (3f-1b-4)>>1 \n\t"
+ "3: mvn r0, r0 \n\t"
+ "2: nop \n\t")
+
+ TEST_RX("tbh [pc, r",12, ((9f-(1f+4))>>1)+1,"]",
+ "9: \n\t"
+ ".short (2f-1b-4)>>1 \n\t"
+ ".short (3f-1b-4)>>1 \n\t"
+ "3: mvn r0, r0 \n\t"
+ "2: nop \n\t")
+
+ TEST_RRX("tbh [r",1,9f, ", r",14,1,"]",
+ "9: \n\t"
+ ".short (2f-1b-4)>>1 \n\t"
+ ".short (3f-1b-4)>>1 \n\t"
+ "3: mvn r0, r0 \n\t"
+ "2: nop \n\t")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xe8d1f01f) " @ tbh [r1, pc]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xe8d1f01d) " @ tbh [r1, sp]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xe8ddf012) " @ tbh [sp, r2]")
+
+ TEST_UNSUPPORTED("strexb r0, r1, [r2]")
+ TEST_UNSUPPORTED("strexh r0, r1, [r2]")
+ TEST_UNSUPPORTED("strexd r0, r1, [r2]")
+ TEST_UNSUPPORTED("ldrexb r0, [r1]")
+ TEST_UNSUPPORTED("ldrexh r0, [r1]")
+ TEST_UNSUPPORTED("ldrexd r0, [r1]")
+
+ TEST_GROUP("Data-processing (shifted register) and (modified immediate)")
+
+#define _DATA_PROCESSING32_DNM(op,s,val) \
+ TEST_RR(op s".w r0, r",1, VAL1,", r",2, val, "") \
+ TEST_RR(op s" r1, r",1, VAL1,", r",2, val, ", lsl #3") \
+ TEST_RR(op s" r2, r",3, VAL1,", r",2, val, ", lsr #4") \
+ TEST_RR(op s" r3, r",3, VAL1,", r",2, val, ", asr #5") \
+ TEST_RR(op s" r4, r",5, VAL1,", r",2, N(val),", asr #6") \
+ TEST_RR(op s" r5, r",5, VAL1,", r",2, val, ", ror #7") \
+ TEST_RR(op s" r8, r",9, VAL1,", r",10,val, ", rrx") \
+ TEST_R( op s" r0, r",11,VAL1,", #0x00010001") \
+ TEST_R( op s" r11, r",0, VAL1,", #0xf5000000") \
+ TEST_R( op s" r7, r",8, VAL2,", #0x000af000")
+
+#define DATA_PROCESSING32_DNM(op,val) \
+ _DATA_PROCESSING32_DNM(op,"",val) \
+ _DATA_PROCESSING32_DNM(op,"s",val)
+
+#define DATA_PROCESSING32_NM(op,val) \
+ TEST_RR(op".w r",1, VAL1,", r",2, val, "") \
+ TEST_RR(op" r",1, VAL1,", r",2, val, ", lsl #3") \
+ TEST_RR(op" r",3, VAL1,", r",2, val, ", lsr #4") \
+ TEST_RR(op" r",3, VAL1,", r",2, val, ", asr #5") \
+ TEST_RR(op" r",5, VAL1,", r",2, N(val),", asr #6") \
+ TEST_RR(op" r",5, VAL1,", r",2, val, ", ror #7") \
+ TEST_RR(op" r",9, VAL1,", r",10,val, ", rrx") \
+ TEST_R( op" r",11,VAL1,", #0x00010001") \
+ TEST_R( op" r",0, VAL1,", #0xf5000000") \
+ TEST_R( op" r",8, VAL2,", #0x000af000")
+
+#define _DATA_PROCESSING32_DM(op,s,val) \
+ TEST_R( op s".w r0, r",14, val, "") \
+ TEST_R( op s" r1, r",12, val, ", lsl #3") \
+ TEST_R( op s" r2, r",11, val, ", lsr #4") \
+ TEST_R( op s" r3, r",10, val, ", asr #5") \
+ TEST_R( op s" r4, r",9, N(val),", asr #6") \
+ TEST_R( op s" r5, r",8, val, ", ror #7") \
+ TEST_R( op s" r8, r",7,val, ", rrx") \
+ TEST( op s" r0, #0x00010001") \
+ TEST( op s" r11, #0xf5000000") \
+ TEST( op s" r7, #0x000af000") \
+ TEST( op s" r4, #0x00005a00")
+
+#define DATA_PROCESSING32_DM(op,val) \
+ _DATA_PROCESSING32_DM(op,"",val) \
+ _DATA_PROCESSING32_DM(op,"s",val)
+
+ DATA_PROCESSING32_DNM("and",0xf00f00ff)
+ DATA_PROCESSING32_NM("tst",0xf00f00ff)
+ DATA_PROCESSING32_DNM("bic",0xf00f00ff)
+ DATA_PROCESSING32_DNM("orr",0xf00f00ff)
+ DATA_PROCESSING32_DM("mov",VAL2)
+ DATA_PROCESSING32_DNM("orn",0xf00f00ff)
+ DATA_PROCESSING32_DM("mvn",VAL2)
+ DATA_PROCESSING32_DNM("eor",0xf00f00ff)
+ DATA_PROCESSING32_NM("teq",0xf00f00ff)
+ DATA_PROCESSING32_DNM("add",VAL2)
+ DATA_PROCESSING32_NM("cmn",VAL2)
+ DATA_PROCESSING32_DNM("adc",VAL2)
+ DATA_PROCESSING32_DNM("sbc",VAL2)
+ DATA_PROCESSING32_DNM("sub",VAL2)
+ DATA_PROCESSING32_NM("cmp",VAL2)
+ DATA_PROCESSING32_DNM("rsb",VAL2)
+
+ TEST_RR("pkhbt r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR("pkhbt r14,r",12, HH1,", r",10,HH2,", lsl #2")
+ TEST_RR("pkhtb r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR("pkhtb r14,r",12, HH1,", r",10,HH2,", asr #2")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xea170f0d) " @ tst.w r7, sp")
+ TEST_UNSUPPORTED(__inst_thumb32(0xea170f0f) " @ tst.w r7, pc")
+ TEST_UNSUPPORTED(__inst_thumb32(0xea1d0f07) " @ tst.w sp, r7")
+ TEST_UNSUPPORTED(__inst_thumb32(0xea1f0f07) " @ tst.w pc, r7")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf01d1f08) " @ tst sp, #0x00080008")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf01f1f08) " @ tst pc, #0x00080008")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xea970f0d) " @ teq.w r7, sp")
+ TEST_UNSUPPORTED(__inst_thumb32(0xea970f0f) " @ teq.w r7, pc")
+ TEST_UNSUPPORTED(__inst_thumb32(0xea9d0f07) " @ teq.w sp, r7")
+ TEST_UNSUPPORTED(__inst_thumb32(0xea9f0f07) " @ teq.w pc, r7")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf09d1f08) " @ tst sp, #0x00080008")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf09f1f08) " @ tst pc, #0x00080008")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb170f0d) " @ cmn.w r7, sp")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb170f0f) " @ cmn.w r7, pc")
+ TEST_P("cmn.w sp, r",7,0,"")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb1f0f07) " @ cmn.w pc, r7")
+ TEST( "cmn sp, #0x00080008")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf11f1f08) " @ cmn pc, #0x00080008")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xebb70f0d) " @ cmp.w r7, sp")
+ TEST_UNSUPPORTED(__inst_thumb32(0xebb70f0f) " @ cmp.w r7, pc")
+ TEST_P("cmp.w sp, r",7,0,"")
+ TEST_UNSUPPORTED(__inst_thumb32(0xebbf0f07) " @ cmp.w pc, r7")
+ TEST( "cmp sp, #0x00080008")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf1bf1f08) " @ cmp pc, #0x00080008")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xea5f070d) " @ movs.w r7, sp")
+ TEST_UNSUPPORTED(__inst_thumb32(0xea5f070f) " @ movs.w r7, pc")
+ TEST_UNSUPPORTED(__inst_thumb32(0xea5f0d07) " @ movs.w sp, r7")
+ TEST_UNSUPPORTED(__inst_thumb32(0xea4f0f07) " @ mov.w pc, r7")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf04f1d08) " @ mov sp, #0x00080008")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf04f1f08) " @ mov pc, #0x00080008")
+
+ TEST_R("add.w r0, sp, r",1, 4,"")
+ TEST_R("adds r0, sp, r",1, 4,", asl #3")
+ TEST_R("add r0, sp, r",1, 4,", asl #4")
+ TEST_R("add r0, sp, r",1, 16,", ror #1")
+ TEST_R("add.w sp, sp, r",1, 4,"")
+ TEST_R("add sp, sp, r",1, 4,", asl #3")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb0d1d01) " @ add sp, sp, r1, asl #4")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb0d0d71) " @ add sp, sp, r1, ror #1")
+ TEST( "add.w r0, sp, #24")
+ TEST( "add.w sp, sp, #24")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb0d0f01) " @ add pc, sp, r1")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb0d000f) " @ add r0, sp, pc")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb0d000d) " @ add r0, sp, sp")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb0d0d0f) " @ add sp, sp, pc")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb0d0d0d) " @ add sp, sp, sp")
+
+ TEST_R("sub.w r0, sp, r",1, 4,"")
+ TEST_R("subs r0, sp, r",1, 4,", asl #3")
+ TEST_R("sub r0, sp, r",1, 4,", asl #4")
+ TEST_R("sub r0, sp, r",1, 16,", ror #1")
+ TEST_R("sub.w sp, sp, r",1, 4,"")
+ TEST_R("sub sp, sp, r",1, 4,", asl #3")
+ TEST_UNSUPPORTED(__inst_thumb32(0xebad1d01) " @ sub sp, sp, r1, asl #4")
+ TEST_UNSUPPORTED(__inst_thumb32(0xebad0d71) " @ sub sp, sp, r1, ror #1")
+ TEST_UNSUPPORTED(__inst_thumb32(0xebad0f01) " @ sub pc, sp, r1")
+ TEST( "sub.w r0, sp, #24")
+ TEST( "sub.w sp, sp, #24")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xea02010f) " @ and r1, r2, pc")
+ TEST_UNSUPPORTED(__inst_thumb32(0xea0f0103) " @ and r1, pc, r3")
+ TEST_UNSUPPORTED(__inst_thumb32(0xea020f03) " @ and pc, r2, r3")
+ TEST_UNSUPPORTED(__inst_thumb32(0xea02010d) " @ and r1, r2, sp")
+ TEST_UNSUPPORTED(__inst_thumb32(0xea0d0103) " @ and r1, sp, r3")
+ TEST_UNSUPPORTED(__inst_thumb32(0xea020d03) " @ and sp, r2, r3")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf00d1108) " @ and r1, sp, #0x00080008")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf00f1108) " @ and r1, pc, #0x00080008")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf0021d08) " @ and sp, r8, #0x00080008")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf0021f08) " @ and pc, r8, #0x00080008")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb02010f) " @ add r1, r2, pc")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb0f0103) " @ add r1, pc, r3")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb020f03) " @ add pc, r2, r3")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb02010d) " @ add r1, r2, sp")
+ TEST_SUPPORTED( __inst_thumb32(0xeb0d0103) " @ add r1, sp, r3")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb020d03) " @ add sp, r2, r3")
+ TEST_SUPPORTED( __inst_thumb32(0xf10d1108) " @ add r1, sp, #0x00080008")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf10d1f08) " @ add pc, sp, #0x00080008")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf10f1108) " @ add r1, pc, #0x00080008")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf1021d08) " @ add sp, r8, #0x00080008")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf1021f08) " @ add pc, r8, #0x00080008")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xeaa00000) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeaf00000) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb200000) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeb800000) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xebe00000) "")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xf0a00000) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf0c00000) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf0f00000) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf1200000) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf1800000) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf1e00000) "")
+
+ TEST_GROUP("Coprocessor instructions")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xec000000) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xeff00000) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xfc000000) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xfff00000) "")
+
+ TEST_GROUP("Data-processing (plain binary immediate)")
+
+ TEST_R("addw r0, r",1, VAL1,", #0x123")
+ TEST( "addw r14, sp, #0xf5a")
+ TEST( "addw sp, sp, #0x20")
+ TEST( "addw r7, pc, #0x888")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf20f1f20) " @ addw pc, pc, #0x120")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf20d1f20) " @ addw pc, sp, #0x120")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf20f1d20) " @ addw sp, pc, #0x120")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf2001d20) " @ addw sp, r0, #0x120")
+
+ TEST_R("subw r0, r",1, VAL1,", #0x123")
+ TEST( "subw r14, sp, #0xf5a")
+ TEST( "subw sp, sp, #0x20")
+ TEST( "subw r7, pc, #0x888")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf2af1f20) " @ subw pc, pc, #0x120")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf2ad1f20) " @ subw pc, sp, #0x120")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf2af1d20) " @ subw sp, pc, #0x120")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf2a01d20) " @ subw sp, r0, #0x120")
+
+ TEST("movw r0, #0")
+ TEST("movw r0, #0xffff")
+ TEST("movw lr, #0xffff")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf2400d00) " @ movw sp, #0")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf2400f00) " @ movw pc, #0")
+
+ TEST_R("movt r",0, VAL1,", #0")
+ TEST_R("movt r",0, VAL2,", #0xffff")
+ TEST_R("movt r",14,VAL1,", #0xffff")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf2c00d00) " @ movt sp, #0")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf2c00f00) " @ movt pc, #0")
+
+ TEST_R( "ssat r0, #24, r",0, VAL1,"")
+ TEST_R( "ssat r14, #24, r",12, VAL2,"")
+ TEST_R( "ssat r0, #24, r",0, VAL1,", lsl #8")
+ TEST_R( "ssat r14, #24, r",12, VAL2,", asr #8")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf30c0d17) " @ ssat sp, #24, r12")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf30c0f17) " @ ssat pc, #24, r12")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf30d0c17) " @ ssat r12, #24, sp")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf30f0c17) " @ ssat r12, #24, pc")
+
+ TEST_R( "usat r0, #24, r",0, VAL1,"")
+ TEST_R( "usat r14, #24, r",12, VAL2,"")
+ TEST_R( "usat r0, #24, r",0, VAL1,", lsl #8")
+ TEST_R( "usat r14, #24, r",12, VAL2,", asr #8")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf38c0d17) " @ usat sp, #24, r12")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf38c0f17) " @ usat pc, #24, r12")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf38d0c17) " @ usat r12, #24, sp")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf38f0c17) " @ usat r12, #24, pc")
+
+ TEST_R( "ssat16 r0, #12, r",0, HH1,"")
+ TEST_R( "ssat16 r14, #12, r",12, HH2,"")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf32c0d0b) " @ ssat16 sp, #12, r12")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf32c0f0b) " @ ssat16 pc, #12, r12")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf32d0c0b) " @ ssat16 r12, #12, sp")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf32f0c0b) " @ ssat16 r12, #12, pc")
+
+ TEST_R( "usat16 r0, #12, r",0, HH1,"")
+ TEST_R( "usat16 r14, #12, r",12, HH2,"")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf3ac0d0b) " @ usat16 sp, #12, r12")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf3ac0f0b) " @ usat16 pc, #12, r12")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf3ad0c0b) " @ usat16 r12, #12, sp")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf3af0c0b) " @ usat16 r12, #12, pc")
+
+ TEST_R( "sbfx r0, r",0 , VAL1,", #0, #31")
+ TEST_R( "sbfx r14, r",12, VAL2,", #8, #16")
+ TEST_R( "sbfx r4, r",10, VAL1,", #16, #15")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf34c2d0f) " @ sbfx sp, r12, #8, #16")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf34c2f0f) " @ sbfx pc, r12, #8, #16")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf34d2c0f) " @ sbfx r12, sp, #8, #16")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf34f2c0f) " @ sbfx r12, pc, #8, #16")
+
+ TEST_R( "ubfx r0, r",0 , VAL1,", #0, #31")
+ TEST_R( "ubfx r14, r",12, VAL2,", #8, #16")
+ TEST_R( "ubfx r4, r",10, VAL1,", #16, #15")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf3cc2d0f) " @ ubfx sp, r12, #8, #16")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf3cc2f0f) " @ ubfx pc, r12, #8, #16")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf3cd2c0f) " @ ubfx r12, sp, #8, #16")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf3cf2c0f) " @ ubfx r12, pc, #8, #16")
+
+ TEST_R( "bfc r",0, VAL1,", #4, #20")
+ TEST_R( "bfc r",14,VAL2,", #4, #20")
+ TEST_R( "bfc r",7, VAL1,", #0, #31")
+ TEST_R( "bfc r",8, VAL2,", #0, #31")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf36f0d1e) " @ bfc sp, #0, #31")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf36f0f1e) " @ bfc pc, #0, #31")
+
+ TEST_RR( "bfi r",0, VAL1,", r",0 , VAL2,", #0, #31")
+ TEST_RR( "bfi r",12,VAL1,", r",14 , VAL2,", #4, #20")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf36e1d17) " @ bfi sp, r14, #4, #20")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf36e1f17) " @ bfi pc, r14, #4, #20")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf36d1e17) " @ bfi r14, sp, #4, #20")
+
+ TEST_GROUP("Branches and miscellaneous control")
+
+CONDITION_INSTRUCTIONS(22,
+ TEST_BF("beq.w 2f")
+ TEST_BB("bne.w 2b")
+ TEST_BF("bgt.w 2f")
+ TEST_BB("blt.w 2b")
+ TEST_BF_X("bpl.w 2f", SPACE_0x1000)
+)
+
+ TEST_UNSUPPORTED("msr cpsr, r0")
+ TEST_UNSUPPORTED("msr cpsr_f, r1")
+ TEST_UNSUPPORTED("msr spsr, r2")
+
+ TEST_UNSUPPORTED("cpsie.w i")
+ TEST_UNSUPPORTED("cpsid.w i")
+ TEST_UNSUPPORTED("cps 0x13")
+
+ TEST_SUPPORTED("yield.w")
+ TEST("sev.w")
+ TEST("nop.w")
+ TEST("wfi.w")
+ TEST_SUPPORTED("wfe.w")
+ TEST_UNSUPPORTED("dbg.w #0")
+
+ TEST_UNSUPPORTED("clrex")
+ TEST_UNSUPPORTED("dsb")
+ TEST_UNSUPPORTED("dmb")
+ TEST_UNSUPPORTED("isb")
+
+ TEST_UNSUPPORTED("bxj r0")
+
+ TEST_UNSUPPORTED("subs pc, lr, #4")
+
+ TEST_RMASKED("mrs r",0,~PSR_IGNORE_BITS,", cpsr")
+ TEST_RMASKED("mrs r",14,~PSR_IGNORE_BITS,", cpsr")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8d00) " @ mrs sp, spsr")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8f00) " @ mrs pc, spsr")
+ TEST_UNSUPPORTED("mrs r0, spsr")
+ TEST_UNSUPPORTED("mrs lr, spsr")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xf7f08000) " @ smc #0")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xf7f0a000) " @ undefeined")
+
+ TEST_BF( "b.w 2f")
+ TEST_BB( "b.w 2b")
+ TEST_BF_X("b.w 2f", SPACE_0x1000)
+
+ TEST_BF( "bl.w 2f")
+ TEST_BB( "bl.w 2b")
+ TEST_BB_X("bl.w 2b", SPACE_0x1000)
+
+ TEST_X( "blx __dummy_arm_subroutine",
+ ".arm \n\t"
+ ".align \n\t"
+ ".type __dummy_arm_subroutine, %%function \n\t"
+ "__dummy_arm_subroutine: \n\t"
+ "mov r0, pc \n\t"
+ "bx lr \n\t"
+ ".thumb \n\t"
+ )
+ TEST( "blx __dummy_arm_subroutine")
+
+ TEST_GROUP("Store single data item")
+
+#define SINGLE_STORE(size) \
+ TEST_RP( "str"size" r",0, VAL1,", [r",11,-1024,", #1024]") \
+ TEST_RP( "str"size" r",14,VAL2,", [r",1, -1024,", #1080]") \
+ TEST_RP( "str"size" r",0, VAL1,", [r",11,256, ", #-120]") \
+ TEST_RP( "str"size" r",14,VAL2,", [r",1, 256, ", #-128]") \
+ TEST_RP( "str"size" r",0, VAL1,", [r",11,24, "], #120") \
+ TEST_RP( "str"size" r",14,VAL2,", [r",1, 24, "], #128") \
+ TEST_RP( "str"size" r",0, VAL1,", [r",11,24, "], #-120") \
+ TEST_RP( "str"size" r",14,VAL2,", [r",1, 24, "], #-128") \
+ TEST_RP( "str"size" r",0, VAL1,", [r",11,24, ", #120]!") \
+ TEST_RP( "str"size" r",14,VAL2,", [r",1, 24, ", #128]!") \
+ TEST_RP( "str"size" r",0, VAL1,", [r",11,256, ", #-120]!") \
+ TEST_RP( "str"size" r",14,VAL2,", [r",1, 256, ", #-128]!") \
+ TEST_RPR("str"size".w r",0, VAL1,", [r",1, 0,", r",2, 4,"]") \
+ TEST_RPR("str"size" r",14,VAL2,", [r",10,0,", r",11,4,", lsl #1]") \
+ TEST_UNSUPPORTED("str"size" r0, [r13, r1]") \
+ TEST_R( "str"size".w r",7, VAL1,", [sp, #24]") \
+ TEST_RP( "str"size".w r",0, VAL2,", [r",0,0, "]") \
+ TEST_RP( "str"size" r",6, VAL1,", [r",13, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!") \
+ TEST_UNSUPPORTED("str"size" r6, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!") \
+ TEST_RP( "str"size" r",4, VAL2,", [r",12, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!") \
+ TEST_UNSUPPORTED("str"size"t r0, [r1, #4]")
+
+ SINGLE_STORE("b")
+ SINGLE_STORE("h")
+ SINGLE_STORE("")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xf801000d) " @ strb r0, [r1, r13]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf821000d) " @ strh r0, [r1, r13]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf841000d) " @ str r0, [r1, r13]")
+
+ TEST("str sp, [sp]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf8cfe000) " @ str r14, [pc]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf8cef000) " @ str pc, [r14]")
+
+ TEST_GROUP("Advanced SIMD element or structure load/store instructions")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xf9000000) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf92fffff) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf9800000) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf9efffff) "")
+
+ TEST_GROUP("Load single data item and memory hints")
+
+#define SINGLE_LOAD(size) \
+ TEST_P( "ldr"size" r0, [r",11,-1024, ", #1024]") \
+ TEST_P( "ldr"size" r14, [r",1, -1024,", #1080]") \
+ TEST_P( "ldr"size" r0, [r",11,256, ", #-120]") \
+ TEST_P( "ldr"size" r14, [r",1, 256, ", #-128]") \
+ TEST_P( "ldr"size" r0, [r",11,24, "], #120") \
+ TEST_P( "ldr"size" r14, [r",1, 24, "], #128") \
+ TEST_P( "ldr"size" r0, [r",11,24, "], #-120") \
+ TEST_P( "ldr"size" r14, [r",1,24, "], #-128") \
+ TEST_P( "ldr"size" r0, [r",11,24, ", #120]!") \
+ TEST_P( "ldr"size" r14, [r",1, 24, ", #128]!") \
+ TEST_P( "ldr"size" r0, [r",11,256, ", #-120]!") \
+ TEST_P( "ldr"size" r14, [r",1, 256, ", #-128]!") \
+ TEST_PR("ldr"size".w r0, [r",1, 0,", r",2, 4,"]") \
+ TEST_PR("ldr"size" r14, [r",10,0,", r",11,4,", lsl #1]") \
+ TEST_X( "ldr"size".w r0, 3f", \
+ ".align 3 \n\t" \
+ "3: .word "__stringify(VAL1)) \
+ TEST_X( "ldr"size".w r14, 3f", \
+ ".align 3 \n\t" \
+ "3: .word "__stringify(VAL2)) \
+ TEST( "ldr"size".w r7, 3b") \
+ TEST( "ldr"size".w r7, [sp, #24]") \
+ TEST_P( "ldr"size".w r0, [r",0,0, "]") \
+ TEST_UNSUPPORTED("ldr"size"t r0, [r1, #4]")
+
+ SINGLE_LOAD("b")
+ SINGLE_LOAD("sb")
+ SINGLE_LOAD("h")
+ SINGLE_LOAD("sh")
+ SINGLE_LOAD("")
+
+ TEST_BF_P("ldr pc, [r",14, 15*4,"]")
+ TEST_P( "ldr sp, [r",14, 13*4,"]")
+ TEST_BF_R("ldr pc, [sp, r",14, 15*4,"]")
+ TEST_R( "ldr sp, [sp, r",14, 13*4,"]")
+ TEST_THUMB_TO_ARM_INTERWORK_P("ldr pc, [r",0,0,", #15*4]")
+ TEST_SUPPORTED("ldr sp, 99f")
+ TEST_SUPPORTED("ldr pc, 99f")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xf854700d) " @ ldr r7, [r4, sp]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf854700f) " @ ldr r7, [r4, pc]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf814700d) " @ ldrb r7, [r4, sp]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf814700f) " @ ldrb r7, [r4, pc]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf89fd004) " @ ldrb sp, 99f")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf814d008) " @ ldrb sp, [r4, r8]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf894d000) " @ ldrb sp, [r4]")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xf8600000) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_thumb32(0xf9ffffff) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_thumb32(0xf9500000) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_thumb32(0xf95fffff) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_thumb32(0xf8000800) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_thumb32(0xf97ffaff) "") /* Unallocated space */
+
+ TEST( "pli [pc, #4]")
+ TEST( "pli [pc, #-4]")
+ TEST( "pld [pc, #4]")
+ TEST( "pld [pc, #-4]")
+
+ TEST_P( "pld [r",0,-1024,", #1024]")
+ TEST( __inst_thumb32(0xf8b0f400) " @ pldw [r0, #1024]")
+ TEST_P( "pli [r",4, 0b,", #1024]")
+ TEST_P( "pld [r",7, 120,", #-120]")
+ TEST( __inst_thumb32(0xf837fc78) " @ pldw [r7, #-120]")
+ TEST_P( "pli [r",11,120,", #-120]")
+ TEST( "pld [sp, #0]")
+
+ TEST_PR("pld [r",7, 24, ", r",0, 16,"]")
+ TEST_PR("pld [r",8, 24, ", r",12,16,", lsl #3]")
+ TEST_SUPPORTED(__inst_thumb32(0xf837f000) " @ pldw [r7, r0]")
+ TEST_SUPPORTED(__inst_thumb32(0xf838f03c) " @ pldw [r8, r12, lsl #3]");
+ TEST_RR("pli [r",12,0b,", r",0, 16,"]")
+ TEST_RR("pli [r",0, 0b,", r",12,16,", lsl #3]")
+ TEST_R( "pld [sp, r",1, 16,"]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf817f00d) " @pld [r7, sp]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf817f00f) " @pld [r7, pc]")
+
+ TEST_GROUP("Data-processing (register)")
+
+#define SHIFTS32(op) \
+ TEST_RR(op" r0, r",1, VAL1,", r",2, 3, "") \
+ TEST_RR(op" r14, r",12,VAL2,", r",11,10,"")
+
+ SHIFTS32("lsl")
+ SHIFTS32("lsls")
+ SHIFTS32("lsr")
+ SHIFTS32("lsrs")
+ SHIFTS32("asr")
+ SHIFTS32("asrs")
+ SHIFTS32("ror")
+ SHIFTS32("rors")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa01ff02) " @ lsl pc, r1, r2")
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa01fd02) " @ lsl sp, r1, r2")
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa0ff002) " @ lsl r0, pc, r2")
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa0df002) " @ lsl r0, sp, r2")
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa01f00f) " @ lsl r0, r1, pc")
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa01f00d) " @ lsl r0, r1, sp")
+
+ TEST_RR( "sxtah r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "sxtah r14,r",12, HH2,", r",10,HH1,", ror #8")
+ TEST_R( "sxth r8, r",7, HH1,"")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa0fff87) " @ sxth pc, r7");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa0ffd87) " @ sxth sp, r7");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa0ff88f) " @ sxth r8, pc");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa0ff88d) " @ sxth r8, sp");
+
+ TEST_RR( "uxtah r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uxtah r14,r",12, HH2,", r",10,HH1,", ror #8")
+ TEST_R( "uxth r8, r",7, HH1,"")
+
+ TEST_RR( "sxtab16 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "sxtab16 r14,r",12, HH2,", r",10,HH1,", ror #8")
+ TEST_R( "sxtb16 r8, r",7, HH1,"")
+
+ TEST_RR( "uxtab16 r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uxtab16 r14,r",12, HH2,", r",10,HH1,", ror #8")
+ TEST_R( "uxtb16 r8, r",7, HH1,"")
+
+ TEST_RR( "sxtab r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "sxtab r14,r",12, HH2,", r",10,HH1,", ror #8")
+ TEST_R( "sxtb r8, r",7, HH1,"")
+
+ TEST_RR( "uxtab r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "uxtab r14,r",12, HH2,", r",10,HH1,", ror #8")
+ TEST_R( "uxtb r8, r",7, HH1,"")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa6000f0) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa7fffff) "")
+
+#define PARALLEL_ADD_SUB(op) \
+ TEST_RR( op"add16 r0, r",0, HH1,", r",1, HH2,"") \
+ TEST_RR( op"add16 r14, r",12,HH2,", r",10,HH1,"") \
+ TEST_RR( op"asx r0, r",0, HH1,", r",1, HH2,"") \
+ TEST_RR( op"asx r14, r",12,HH2,", r",10,HH1,"") \
+ TEST_RR( op"sax r0, r",0, HH1,", r",1, HH2,"") \
+ TEST_RR( op"sax r14, r",12,HH2,", r",10,HH1,"") \
+ TEST_RR( op"sub16 r0, r",0, HH1,", r",1, HH2,"") \
+ TEST_RR( op"sub16 r14, r",12,HH2,", r",10,HH1,"") \
+ TEST_RR( op"add8 r0, r",0, HH1,", r",1, HH2,"") \
+ TEST_RR( op"add8 r14, r",12,HH2,", r",10,HH1,"") \
+ TEST_RR( op"sub8 r0, r",0, HH1,", r",1, HH2,"") \
+ TEST_RR( op"sub8 r14, r",12,HH2,", r",10,HH1,"")
+
+ TEST_GROUP("Parallel addition and subtraction, signed")
+
+ PARALLEL_ADD_SUB("s")
+ PARALLEL_ADD_SUB("q")
+ PARALLEL_ADD_SUB("sh")
+
+ TEST_GROUP("Parallel addition and subtraction, unsigned")
+
+ PARALLEL_ADD_SUB("u")
+ PARALLEL_ADD_SUB("uq")
+ PARALLEL_ADD_SUB("uh")
+
+ TEST_GROUP("Miscellaneous operations")
+
+ TEST_RR("qadd r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR("qadd lr, r",9, VAL2,", r",8, VAL1,"")
+ TEST_RR("qsub r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR("qsub lr, r",9, VAL2,", r",8, VAL1,"")
+ TEST_RR("qdadd r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR("qdadd lr, r",9, VAL2,", r",8, VAL1,"")
+ TEST_RR("qdsub r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR("qdsub lr, r",9, VAL2,", r",8, VAL1,"")
+
+ TEST_R("rev.w r0, r",0, VAL1,"")
+ TEST_R("rev r14, r",12, VAL2,"")
+ TEST_R("rev16.w r0, r",0, VAL1,"")
+ TEST_R("rev16 r14, r",12, VAL2,"")
+ TEST_R("rbit r0, r",0, VAL1,"")
+ TEST_R("rbit r14, r",12, VAL2,"")
+ TEST_R("revsh.w r0, r",0, VAL1,"")
+ TEST_R("revsh r14, r",12, VAL2,"")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa9cff8c) " @ rev pc, r12");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa9cfd8c) " @ rev sp, r12");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa9ffe8f) " @ rev r14, pc");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa9dfe8d) " @ rev r14, sp");
+
+ TEST_RR("sel r0, r",0, VAL1,", r",1, VAL2,"")
+ TEST_RR("sel r14, r",12,VAL1,", r",10, VAL2,"")
+
+ TEST_R("clz r0, r",0, 0x0,"")
+ TEST_R("clz r7, r",14,0x1,"")
+ TEST_R("clz lr, r",7, 0xffffffff,"")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xfa80f030) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_thumb32(0xfaffff7f) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_thumb32(0xfab0f000) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_thumb32(0xfaffff7f) "") /* Unallocated space */
+
+ TEST_GROUP("Multiply, multiply accumulate, and absolute difference operations")
+
+ TEST_RR( "mul r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "mul r7, r",8, VAL2,", r",9, VAL2,"")
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb08ff09) " @ mul pc, r8, r9")
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb08fd09) " @ mul sp, r8, r9")
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb0ff709) " @ mul r7, pc, r9")
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb0df709) " @ mul r7, sp, r9")
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb08f70f) " @ mul r7, r8, pc")
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb08f70d) " @ mul r7, r8, sp")
+
+ TEST_RRR( "mla r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "mla r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb08af09) " @ mla pc, r8, r9, r10");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb08ad09) " @ mla sp, r8, r9, r10");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb0fa709) " @ mla r7, pc, r9, r10");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb0da709) " @ mla r7, sp, r9, r10");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb08a70f) " @ mla r7, r8, pc, r10");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb08a70d) " @ mla r7, r8, sp, r10");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb08d709) " @ mla r7, r8, r9, sp");
+
+ TEST_RRR( "mls r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "mls r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+
+ TEST_RRR( "smlabb r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "smlabb r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+ TEST_RRR( "smlatb r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "smlatb r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+ TEST_RRR( "smlabt r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "smlabt r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+ TEST_RRR( "smlatt r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "smlatt r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+ TEST_RR( "smulbb r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "smulbb r7, r",8, VAL3,", r",9, VAL1,"")
+ TEST_RR( "smultb r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "smultb r7, r",8, VAL3,", r",9, VAL1,"")
+ TEST_RR( "smulbt r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "smulbt r7, r",8, VAL3,", r",9, VAL1,"")
+ TEST_RR( "smultt r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "smultt r7, r",8, VAL3,", r",9, VAL1,"")
+
+ TEST_RRR( "smlad r0, r",0, HH1,", r",1, HH2,", r",2, VAL1,"")
+ TEST_RRR( "smlad r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"")
+ TEST_RRR( "smladx r0, r",0, HH1,", r",1, HH2,", r",2, VAL1,"")
+ TEST_RRR( "smladx r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"")
+ TEST_RR( "smuad r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "smuad r14, r",12,HH2,", r",10,HH1,"")
+ TEST_RR( "smuadx r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "smuadx r14, r",12,HH2,", r",10,HH1,"")
+
+ TEST_RRR( "smlawb r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "smlawb r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+ TEST_RRR( "smlawt r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"")
+ TEST_RRR( "smlawt r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+ TEST_RR( "smulwb r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "smulwb r7, r",8, VAL3,", r",9, VAL1,"")
+ TEST_RR( "smulwt r0, r",1, VAL1,", r",2, VAL2,"")
+ TEST_RR( "smulwt r7, r",8, VAL3,", r",9, VAL1,"")
+
+ TEST_RRR( "smlsd r0, r",0, HH1,", r",1, HH2,", r",2, VAL1,"")
+ TEST_RRR( "smlsd r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"")
+ TEST_RRR( "smlsdx r0, r",0, HH1,", r",1, HH2,", r",2, VAL1,"")
+ TEST_RRR( "smlsdx r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"")
+ TEST_RR( "smusd r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "smusd r14, r",12,HH2,", r",10,HH1,"")
+ TEST_RR( "smusdx r0, r",0, HH1,", r",1, HH2,"")
+ TEST_RR( "smusdx r14, r",12,HH2,", r",10,HH1,"")
+
+ TEST_RRR( "smmla r0, r",0, VAL1,", r",1, VAL2,", r",2, VAL1,"")
+ TEST_RRR( "smmla r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"")
+ TEST_RRR( "smmlar r0, r",0, VAL1,", r",1, VAL2,", r",2, VAL1,"")
+ TEST_RRR( "smmlar r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"")
+ TEST_RR( "smmul r0, r",0, VAL1,", r",1, VAL2,"")
+ TEST_RR( "smmul r14, r",12,VAL2,", r",10,VAL1,"")
+ TEST_RR( "smmulr r0, r",0, VAL1,", r",1, VAL2,"")
+ TEST_RR( "smmulr r14, r",12,VAL2,", r",10,VAL1,"")
+
+ TEST_RRR( "smmls r0, r",0, VAL1,", r",1, VAL2,", r",2, VAL1,"")
+ TEST_RRR( "smmls r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"")
+ TEST_RRR( "smmlsr r0, r",0, VAL1,", r",1, VAL2,", r",2, VAL1,"")
+ TEST_RRR( "smmlsr r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"")
+
+ TEST_RRR( "usada8 r0, r",0, VAL1,", r",1, VAL2,", r",2, VAL3,"")
+ TEST_RRR( "usada8 r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL3,"")
+ TEST_RR( "usad8 r0, r",0, VAL1,", r",1, VAL2,"")
+ TEST_RR( "usad8 r14, r",12,VAL2,", r",10,VAL1,"")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb00f010) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb0fff1f) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb70f010) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb7fff1f) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb700010) "") /* Unallocated space */
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb7fff1f) "") /* Unallocated space */
+
+ TEST_GROUP("Long multiply, long multiply accumulate, and divide")
+
+ TEST_RR( "smull r0, r1, r",2, VAL1,", r",3, VAL2,"")
+ TEST_RR( "smull r7, r8, r",9, VAL2,", r",10, VAL1,"")
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb89f80a) " @ smull pc, r8, r9, r10");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb89d80a) " @ smull sp, r8, r9, r10");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb897f0a) " @ smull r7, pc, r9, r10");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb897d0a) " @ smull r7, sp, r9, r10");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb8f780a) " @ smull r7, r8, pc, r10");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb8d780a) " @ smull r7, r8, sp, r10");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb89780f) " @ smull r7, r8, r9, pc");
+ TEST_UNSUPPORTED(__inst_thumb32(0xfb89780d) " @ smull r7, r8, r9, sp");
+
+ TEST_RR( "umull r0, r1, r",2, VAL1,", r",3, VAL2,"")
+ TEST_RR( "umull r7, r8, r",9, VAL2,", r",10, VAL1,"")
+
+ TEST_RRRR( "smlal r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+ TEST_RRRR( "smlal r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+
+ TEST_RRRR( "smlalbb r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+ TEST_RRRR( "smlalbb r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+ TEST_RRRR( "smlalbt r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+ TEST_RRRR( "smlalbt r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+ TEST_RRRR( "smlaltb r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+ TEST_RRRR( "smlaltb r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+ TEST_RRRR( "smlaltt r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+ TEST_RRRR( "smlaltt r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+
+ TEST_RRRR( "smlald r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2)
+ TEST_RRRR( "smlald r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1)
+ TEST_RRRR( "smlaldx r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2)
+ TEST_RRRR( "smlaldx r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1)
+
+ TEST_RRRR( "smlsld r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2)
+ TEST_RRRR( "smlsld r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1)
+ TEST_RRRR( "smlsldx r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2)
+ TEST_RRRR( "smlsldx r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1)
+
+ TEST_RRRR( "umlal r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+ TEST_RRRR( "umlal r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+ TEST_RRRR( "umaal r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+ TEST_RRRR( "umaal r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+
+ TEST_GROUP("Coprocessor instructions")
+
+ TEST_UNSUPPORTED(__inst_thumb32(0xfc000000) "")
+ TEST_UNSUPPORTED(__inst_thumb32(0xffffffff) "")
+
+ TEST_GROUP("Testing instructions in IT blocks")
+
+ TEST_ITBLOCK("sub.w r0, r0")
+
+ verbose("\n");
+}
+
diff --git a/arch/arm/probes/uprobes/Makefile b/arch/arm/probes/uprobes/Makefile
new file mode 100644
index 000000000..e1dc3d0f6
--- /dev/null
+++ b/arch/arm/probes/uprobes/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_UPROBES) += core.o actions-arm.o
diff --git a/arch/arm/probes/uprobes/actions-arm.c b/arch/arm/probes/uprobes/actions-arm.c
new file mode 100644
index 000000000..76eb44972
--- /dev/null
+++ b/arch/arm/probes/uprobes/actions-arm.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2012 Rabin Vincent <rabin at rab.in>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it 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/stddef.h>
+#include <linux/wait.h>
+#include <linux/uprobes.h>
+#include <linux/module.h>
+
+#include "../decode.h"
+#include "../decode-arm.h"
+#include "core.h"
+
+static int uprobes_substitute_pc(unsigned long *pinsn, u32 oregs)
+{
+ probes_opcode_t insn = __mem_to_opcode_arm(*pinsn);
+ probes_opcode_t temp;
+ probes_opcode_t mask;
+ int freereg;
+ u32 free = 0xffff;
+ u32 regs;
+
+ for (regs = oregs; regs; regs >>= 4, insn >>= 4) {
+ if ((regs & 0xf) == REG_TYPE_NONE)
+ continue;
+
+ free &= ~(1 << (insn & 0xf));
+ }
+
+ /* No PC, no problem */
+ if (free & (1 << 15))
+ return 15;
+
+ if (!free)
+ return -1;
+
+ /*
+ * fls instead of ffs ensures that for "ldrd r0, r1, [pc]" we would
+ * pick LR instead of R1.
+ */
+ freereg = free = fls(free) - 1;
+
+ temp = __mem_to_opcode_arm(*pinsn);
+ insn = temp;
+ regs = oregs;
+ mask = 0xf;
+
+ for (; regs; regs >>= 4, mask <<= 4, free <<= 4, temp >>= 4) {
+ if ((regs & 0xf) == REG_TYPE_NONE)
+ continue;
+
+ if ((temp & 0xf) != 15)
+ continue;
+
+ insn &= ~mask;
+ insn |= free & mask;
+ }
+
+ *pinsn = __opcode_to_mem_arm(insn);
+ return freereg;
+}
+
+static void uprobe_set_pc(struct arch_uprobe *auprobe,
+ struct arch_uprobe_task *autask,
+ struct pt_regs *regs)
+{
+ u32 pcreg = auprobe->pcreg;
+
+ autask->backup = regs->uregs[pcreg];
+ regs->uregs[pcreg] = regs->ARM_pc + 8;
+}
+
+static void uprobe_unset_pc(struct arch_uprobe *auprobe,
+ struct arch_uprobe_task *autask,
+ struct pt_regs *regs)
+{
+ /* PC will be taken care of by common code */
+ regs->uregs[auprobe->pcreg] = autask->backup;
+}
+
+static void uprobe_aluwrite_pc(struct arch_uprobe *auprobe,
+ struct arch_uprobe_task *autask,
+ struct pt_regs *regs)
+{
+ u32 pcreg = auprobe->pcreg;
+
+ alu_write_pc(regs->uregs[pcreg], regs);
+ regs->uregs[pcreg] = autask->backup;
+}
+
+static void uprobe_write_pc(struct arch_uprobe *auprobe,
+ struct arch_uprobe_task *autask,
+ struct pt_regs *regs)
+{
+ u32 pcreg = auprobe->pcreg;
+
+ load_write_pc(regs->uregs[pcreg], regs);
+ regs->uregs[pcreg] = autask->backup;
+}
+
+enum probes_insn
+decode_pc_ro(probes_opcode_t insn, struct arch_probes_insn *asi,
+ const struct decode_header *d)
+{
+ struct arch_uprobe *auprobe = container_of(asi, struct arch_uprobe,
+ asi);
+ struct decode_emulate *decode = (struct decode_emulate *) d;
+ u32 regs = decode->header.type_regs.bits >> DECODE_TYPE_BITS;
+ int reg;
+
+ reg = uprobes_substitute_pc(&auprobe->ixol[0], regs);
+ if (reg == 15)
+ return INSN_GOOD;
+
+ if (reg == -1)
+ return INSN_REJECTED;
+
+ auprobe->pcreg = reg;
+ auprobe->prehandler = uprobe_set_pc;
+ auprobe->posthandler = uprobe_unset_pc;
+
+ return INSN_GOOD;
+}
+
+enum probes_insn
+decode_wb_pc(probes_opcode_t insn, struct arch_probes_insn *asi,
+ const struct decode_header *d, bool alu)
+{
+ struct arch_uprobe *auprobe = container_of(asi, struct arch_uprobe,
+ asi);
+ enum probes_insn ret = decode_pc_ro(insn, asi, d);
+
+ if (((insn >> 12) & 0xf) == 15)
+ auprobe->posthandler = alu ? uprobe_aluwrite_pc
+ : uprobe_write_pc;
+
+ return ret;
+}
+
+enum probes_insn
+decode_rd12rn16rm0rs8_rwflags(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *d)
+{
+ return decode_wb_pc(insn, asi, d, true);
+}
+
+enum probes_insn
+decode_ldr(probes_opcode_t insn, struct arch_probes_insn *asi,
+ const struct decode_header *d)
+{
+ return decode_wb_pc(insn, asi, d, false);
+}
+
+enum probes_insn
+uprobe_decode_ldmstm(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *d)
+{
+ struct arch_uprobe *auprobe = container_of(asi, struct arch_uprobe,
+ asi);
+ unsigned reglist = insn & 0xffff;
+ int rn = (insn >> 16) & 0xf;
+ int lbit = insn & (1 << 20);
+ unsigned used = reglist | (1 << rn);
+
+ if (rn == 15)
+ return INSN_REJECTED;
+
+ if (!(used & (1 << 15)))
+ return INSN_GOOD;
+
+ if (used & (1 << 14))
+ return INSN_REJECTED;
+
+ /* Use LR instead of PC */
+ insn ^= 0xc000;
+
+ auprobe->pcreg = 14;
+ auprobe->ixol[0] = __opcode_to_mem_arm(insn);
+
+ auprobe->prehandler = uprobe_set_pc;
+ if (lbit)
+ auprobe->posthandler = uprobe_write_pc;
+ else
+ auprobe->posthandler = uprobe_unset_pc;
+
+ return INSN_GOOD;
+}
+
+const union decode_action uprobes_probes_actions[] = {
+ [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop},
+ [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
+ [PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
+ [PROBES_MRS] = {.handler = simulate_mrs},
+ [PROBES_BRANCH_REG] = {.handler = simulate_blx2bx},
+ [PROBES_CLZ] = {.handler = probes_simulate_nop},
+ [PROBES_SATURATING_ARITHMETIC] = {.handler = probes_simulate_nop},
+ [PROBES_MUL1] = {.handler = probes_simulate_nop},
+ [PROBES_MUL2] = {.handler = probes_simulate_nop},
+ [PROBES_SWP] = {.handler = probes_simulate_nop},
+ [PROBES_LDRSTRD] = {.decoder = decode_pc_ro},
+ [PROBES_LOAD_EXTRA] = {.decoder = decode_pc_ro},
+ [PROBES_LOAD] = {.decoder = decode_ldr},
+ [PROBES_STORE_EXTRA] = {.decoder = decode_pc_ro},
+ [PROBES_STORE] = {.decoder = decode_pc_ro},
+ [PROBES_MOV_IP_SP] = {.handler = simulate_mov_ipsp},
+ [PROBES_DATA_PROCESSING_REG] = {
+ .decoder = decode_rd12rn16rm0rs8_rwflags},
+ [PROBES_DATA_PROCESSING_IMM] = {
+ .decoder = decode_rd12rn16rm0rs8_rwflags},
+ [PROBES_MOV_HALFWORD] = {.handler = probes_simulate_nop},
+ [PROBES_SEV] = {.handler = probes_simulate_nop},
+ [PROBES_WFE] = {.handler = probes_simulate_nop},
+ [PROBES_SATURATE] = {.handler = probes_simulate_nop},
+ [PROBES_REV] = {.handler = probes_simulate_nop},
+ [PROBES_MMI] = {.handler = probes_simulate_nop},
+ [PROBES_PACK] = {.handler = probes_simulate_nop},
+ [PROBES_EXTEND] = {.handler = probes_simulate_nop},
+ [PROBES_EXTEND_ADD] = {.handler = probes_simulate_nop},
+ [PROBES_MUL_ADD_LONG] = {.handler = probes_simulate_nop},
+ [PROBES_MUL_ADD] = {.handler = probes_simulate_nop},
+ [PROBES_BITFIELD] = {.handler = probes_simulate_nop},
+ [PROBES_BRANCH] = {.handler = simulate_bbl},
+ [PROBES_LDMSTM] = {.decoder = uprobe_decode_ldmstm}
+};
diff --git a/arch/arm/probes/uprobes/core.c b/arch/arm/probes/uprobes/core.c
new file mode 100644
index 000000000..d1329f1ba
--- /dev/null
+++ b/arch/arm/probes/uprobes/core.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2012 Rabin Vincent <rabin at rab.in>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <linux/errno.h>
+#include <linux/highmem.h>
+#include <linux/sched.h>
+#include <linux/uprobes.h>
+#include <linux/notifier.h>
+
+#include <asm/opcodes.h>
+#include <asm/traps.h>
+
+#include "../decode.h"
+#include "../decode-arm.h"
+#include "core.h"
+
+#define UPROBE_TRAP_NR UINT_MAX
+
+bool is_swbp_insn(uprobe_opcode_t *insn)
+{
+ return (__mem_to_opcode_arm(*insn) & 0x0fffffff) ==
+ (UPROBE_SWBP_ARM_INSN & 0x0fffffff);
+}
+
+int set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm,
+ unsigned long vaddr)
+{
+ return uprobe_write_opcode(mm, vaddr,
+ __opcode_to_mem_arm(auprobe->bpinsn));
+}
+
+bool arch_uprobe_ignore(struct arch_uprobe *auprobe, struct pt_regs *regs)
+{
+ if (!auprobe->asi.insn_check_cc(regs->ARM_cpsr)) {
+ regs->ARM_pc += 4;
+ return true;
+ }
+
+ return false;
+}
+
+bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
+{
+ probes_opcode_t opcode;
+
+ if (!auprobe->simulate)
+ return false;
+
+ opcode = __mem_to_opcode_arm(*(unsigned int *) auprobe->insn);
+
+ auprobe->asi.insn_singlestep(opcode, &auprobe->asi, regs);
+
+ return true;
+}
+
+unsigned long
+arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr,
+ struct pt_regs *regs)
+{
+ unsigned long orig_ret_vaddr;
+
+ orig_ret_vaddr = regs->ARM_lr;
+ /* Replace the return addr with trampoline addr */
+ regs->ARM_lr = trampoline_vaddr;
+ return orig_ret_vaddr;
+}
+
+int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,
+ unsigned long addr)
+{
+ unsigned int insn;
+ unsigned int bpinsn;
+ enum probes_insn ret;
+
+ /* Thumb not yet support */
+ if (addr & 0x3)
+ return -EINVAL;
+
+ insn = __mem_to_opcode_arm(*(unsigned int *)auprobe->insn);
+ auprobe->ixol[0] = __opcode_to_mem_arm(insn);
+ auprobe->ixol[1] = __opcode_to_mem_arm(UPROBE_SS_ARM_INSN);
+
+ ret = arm_probes_decode_insn(insn, &auprobe->asi, false,
+ uprobes_probes_actions, NULL);
+ switch (ret) {
+ case INSN_REJECTED:
+ return -EINVAL;
+
+ case INSN_GOOD_NO_SLOT:
+ auprobe->simulate = true;
+ break;
+
+ case INSN_GOOD:
+ default:
+ break;
+ }
+
+ bpinsn = UPROBE_SWBP_ARM_INSN & 0x0fffffff;
+ if (insn >= 0xe0000000)
+ bpinsn |= 0xe0000000; /* Unconditional instruction */
+ else
+ bpinsn |= insn & 0xf0000000; /* Copy condition from insn */
+
+ auprobe->bpinsn = bpinsn;
+
+ return 0;
+}
+
+void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
+ void *src, unsigned long len)
+{
+ void *xol_page_kaddr = kmap_atomic(page);
+ void *dst = xol_page_kaddr + (vaddr & ~PAGE_MASK);
+
+ preempt_disable();
+
+ /* Initialize the slot */
+ memcpy(dst, src, len);
+
+ /* flush caches (dcache/icache) */
+ flush_uprobe_xol_access(page, vaddr, dst, len);
+
+ preempt_enable();
+
+ kunmap_atomic(xol_page_kaddr);
+}
+
+
+int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
+{
+ struct uprobe_task *utask = current->utask;
+
+ if (auprobe->prehandler)
+ auprobe->prehandler(auprobe, &utask->autask, regs);
+
+ utask->autask.saved_trap_no = current->thread.trap_no;
+ current->thread.trap_no = UPROBE_TRAP_NR;
+ regs->ARM_pc = utask->xol_vaddr;
+
+ return 0;
+}
+
+int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
+{
+ struct uprobe_task *utask = current->utask;
+
+ WARN_ON_ONCE(current->thread.trap_no != UPROBE_TRAP_NR);
+
+ current->thread.trap_no = utask->autask.saved_trap_no;
+ regs->ARM_pc = utask->vaddr + 4;
+
+ if (auprobe->posthandler)
+ auprobe->posthandler(auprobe, &utask->autask, regs);
+
+ return 0;
+}
+
+bool arch_uprobe_xol_was_trapped(struct task_struct *t)
+{
+ if (t->thread.trap_no != UPROBE_TRAP_NR)
+ return true;
+
+ return false;
+}
+
+void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
+{
+ struct uprobe_task *utask = current->utask;
+
+ current->thread.trap_no = utask->autask.saved_trap_no;
+ instruction_pointer_set(regs, utask->vaddr);
+}
+
+int arch_uprobe_exception_notify(struct notifier_block *self,
+ unsigned long val, void *data)
+{
+ return NOTIFY_DONE;
+}
+
+static int uprobe_trap_handler(struct pt_regs *regs, unsigned int instr)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ instr &= 0x0fffffff;
+ if (instr == (UPROBE_SWBP_ARM_INSN & 0x0fffffff))
+ uprobe_pre_sstep_notifier(regs);
+ else if (instr == (UPROBE_SS_ARM_INSN & 0x0fffffff))
+ uprobe_post_sstep_notifier(regs);
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)
+{
+ return instruction_pointer(regs);
+}
+
+static struct undef_hook uprobes_arm_break_hook = {
+ .instr_mask = 0x0fffffff,
+ .instr_val = (UPROBE_SWBP_ARM_INSN & 0x0fffffff),
+ .cpsr_mask = MODE_MASK,
+ .cpsr_val = USR_MODE,
+ .fn = uprobe_trap_handler,
+};
+
+static struct undef_hook uprobes_arm_ss_hook = {
+ .instr_mask = 0x0fffffff,
+ .instr_val = (UPROBE_SS_ARM_INSN & 0x0fffffff),
+ .cpsr_mask = MODE_MASK,
+ .cpsr_val = USR_MODE,
+ .fn = uprobe_trap_handler,
+};
+
+static int arch_uprobes_init(void)
+{
+ register_undef_hook(&uprobes_arm_break_hook);
+ register_undef_hook(&uprobes_arm_ss_hook);
+
+ return 0;
+}
+device_initcall(arch_uprobes_init);
diff --git a/arch/arm/probes/uprobes/core.h b/arch/arm/probes/uprobes/core.h
new file mode 100644
index 000000000..1d0c12dfb
--- /dev/null
+++ b/arch/arm/probes/uprobes/core.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 Rabin Vincent <rabin at rab.in>
+ *
+ * This program is free software; you can redistribute 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_KERNEL_UPROBES_H
+#define __ARM_KERNEL_UPROBES_H
+
+enum probes_insn uprobe_decode_ldmstm(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *d);
+
+enum probes_insn decode_ldr(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *d);
+
+enum probes_insn
+decode_rd12rn16rm0rs8_rwflags(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *d);
+
+enum probes_insn
+decode_wb_pc(probes_opcode_t insn, struct arch_probes_insn *asi,
+ const struct decode_header *d, bool alu);
+
+enum probes_insn
+decode_pc_ro(probes_opcode_t insn, struct arch_probes_insn *asi,
+ const struct decode_header *d);
+
+extern const union decode_action uprobes_probes_actions[];
+
+#endif
diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile
new file mode 100644
index 000000000..32d05c821
--- /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
+ @$(kecho) ' 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 000000000..04fef71d7
--- /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 000000000..2ed1b8a92
--- /dev/null
+++ b/arch/arm/tools/mach-types
@@ -0,0 +1,1008 @@
+# 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
+#
+# This is a cut-down version of the file; it contains only machines that
+# are merged into mainline or have been edited in the machine database
+# within the last 12 months. References to machine_is_NAME() do not count!
+#
+# Last update: Fri Mar 22 17:24:50 2013
+#
+# 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
+lite300 MACH_LITE300 LITE300 408
+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
+cm4008 MACH_CM4008 CM4008 624
+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
+cm41xx MACH_CM41XX CM41XX 672
+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
+xboardgp8 MACH_XBOARDGP8 XBOARDGP8 742
+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
+se4200 MACH_SE4200 SE4200 809
+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
+cm4002 MACH_CM4002 CM4002 876
+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
+apf9328 MACH_APF9328 APF9328 906
+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
+im42xx MACH_IM42XX IM42XX 1105
+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
+im4004 MACH_IM4004 IM4004 1400
+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
+sg310 MACH_SG310 SG310 1564
+ts209 MACH_TS209 TS209 1565
+at91cap9adk MACH_AT91CAP9ADK AT91CAP9ADK 1566
+mx31moboard MACH_MX31MOBOARD MX31MOBOARD 1574
+vision_ep9307 MACH_VISION_EP9307 VISION_EP9307 1578
+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
+rsi_ews MACH_RSI_EWS RSI_EWS 1609
+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
+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
+usb_a9g20 MACH_USB_A9G20 USB_A9G20 1841
+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_EUKREA_CPUIMX27 EUKREA_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
+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
+cabespresso MACH_CABESPRESSO CABESPRESSO 2194
+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
+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
+mahimahi MACH_MAHIMAHI MAHIMAHI 2304
+cerebric MACH_CEREBRIC CEREBRIC 2311
+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
+cybook2440 MACH_CYBOOK2440 CYBOOK2440 2466
+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
+capc7117 MACH_CAPC7117 CAPC7117 2612
+icontrol MACH_ICONTROL ICONTROL 2624
+gplugd MACH_GPLUGD GPLUGD 2625
+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
+esata_sheevaplug MACH_ESATA_SHEEVAPLUG ESATA_SHEEVAPLUG 2678
+msm7x30_surf MACH_MSM7X30_SURF MSM7X30_SURF 2679
+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
+cybook_orizon MACH_CYBOOK_ORIZON CYBOOK_ORIZON 2733
+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
+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_CPUIMX25SD EUKREA_CPUIMX25SD 2820
+eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35SD EUKREA_CPUIMX35SD 2821
+eukrea_cpuimx51sd MACH_EUKREA_CPUIMX51SD EUKREA_CPUIMX51SD 2822
+eukrea_cpuimx51 MACH_EUKREA_CPUIMX51 EUKREA_CPUIMX51 2823
+smdkc210 MACH_SMDKC210 SMDKC210 2838
+t5325 MACH_T5325 T5325 2846
+income MACH_INCOME INCOME 2849
+goni MACH_GONI GONI 2862
+bv07 MACH_BV07 BV07 2882
+openrd_ultimate MACH_OPENRD_ULTIMATE OPENRD_ULTIMATE 2884
+devixp MACH_DEVIXP DEVIXP 2885
+miccpt MACH_MICCPT MICCPT 2886
+mic256 MACH_MIC256 MIC256 2887
+u5500 MACH_U5500 U5500 2890
+linkstation_lschl MACH_LINKSTATION_LSCHL LINKSTATION_LSCHL 2913
+smdkv310 MACH_SMDKV310 SMDKV310 2925
+wm8505_7in_netbook MACH_WM8505_7IN_NETBOOK WM8505_7IN_NETBOOK 2928
+craneboard MACH_CRANEBOARD CRANEBOARD 2932
+smdk6450 MACH_SMDK6450 SMDK6450 2938
+brownstone MACH_BROWNSTONE BROWNSTONE 2957
+flexibity MACH_FLEXIBITY FLEXIBITY 2965
+mx50_rdp MACH_MX50_RDP MX50_RDP 2988
+universal_c210 MACH_UNIVERSAL_C210 UNIVERSAL_C210 2989
+real6410 MACH_REAL6410 REAL6410 2990
+dockstar MACH_DOCKSTAR DOCKSTAR 2998
+ti8148evm MACH_TI8148EVM TI8148EVM 3004
+seaboard MACH_SEABOARD SEABOARD 3005
+mx53_ard MACH_MX53_ARD MX53_ARD 3010
+mx53_smd MACH_MX53_SMD MX53_SMD 3011
+msm8x60_rumi3 MACH_MSM8X60_RUMI3 MSM8X60_RUMI3 3016
+msm8x60_ffa MACH_MSM8X60_FFA MSM8X60_FFA 3017
+cm_a510 MACH_CM_A510 CM_A510 3020
+tx28 MACH_TX28 TX28 3043
+pcontrol_g20 MACH_PCONTROL_G20 PCONTROL_G20 3062
+vpr200 MACH_VPR200 VPR200 3087
+torbreck MACH_TORBRECK TORBRECK 3090
+prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103
+paz00 MACH_PAZ00 PAZ00 3128
+acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129
+ag5evm MACH_AG5EVM AG5EVM 3189
+ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206
+wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207
+trimslice MACH_TRIMSLICE TRIMSLICE 3209
+kaen MACH_KAEN KAEN 3217
+nokia_rm680 MACH_NOKIA_RM680 NOKIA_RM680 3220
+msm8960_sim MACH_MSM8960_SIM MSM8960_SIM 3230
+msm8960_rumi3 MACH_MSM8960_RUMI3 MSM8960_RUMI3 3231
+gsia18s MACH_GSIA18S GSIA18S 3234
+mx53_loco MACH_MX53_LOCO MX53_LOCO 3273
+wario MACH_WARIO WARIO 3288
+cm_t3730 MACH_CM_T3730 CM_T3730 3290
+hrefv60 MACH_HREFV60 HREFV60 3293
+armlex4210 MACH_ARMLEX4210 ARMLEX4210 3361
+snowball MACH_SNOWBALL SNOWBALL 3363
+xilinx_ep107 MACH_XILINX_EP107 XILINX_EP107 3378
+nuri MACH_NURI NURI 3379
+origen MACH_ORIGEN ORIGEN 3455
+nspire MACH_NSPIRE NSPIRE 3503
+nokia_rm696 MACH_NOKIA_RM696 NOKIA_RM696 3522
+mikrap_x168 MACH_MIKRAP_X168 MIKRAP_X168 3543
+deto_macarm9 MACH_DETO_MACARM9 DETO_MACARM9 3568
+m28evk MACH_M28EVK M28EVK 3613
+kota2 MACH_KOTA2 KOTA2 3616
+bonito MACH_BONITO BONITO 3623
+omap3_egf MACH_OMAP3_EGF OMAP3_EGF 3637
+smdk4212 MACH_SMDK4212 SMDK4212 3638
+apx4devkit MACH_APX4DEVKIT APX4DEVKIT 3712
+smdk4412 MACH_SMDK4412 SMDK4412 3765
+marzen MACH_MARZEN MARZEN 3790
+krome MACH_KROME KROME 3797
+armadillo800eva MACH_ARMADILLO800EVA ARMADILLO800EVA 3863
+mx53_umobo MACH_MX53_UMOBO MX53_UMOBO 3927
+mt4 MACH_MT4 MT4 3981
+u8520 MACH_U8520 U8520 3990
+chupacabra MACH_CHUPACABRA CHUPACABRA 4098
+scorpion MACH_SCORPION SCORPION 4099
+davinci_he_hmi10 MACH_DAVINCI_HE_HMI10 DAVINCI_HE_HMI10 4100
+topkick MACH_TOPKICK TOPKICK 4101
+m3_auguestrush MACH_M3_AUGUESTRUSH M3_AUGUESTRUSH 4102
+ipc335x MACH_IPC335X IPC335X 4103
+sun4i MACH_SUN4I SUN4I 4104
+imx233_olinuxino MACH_IMX233_OLINUXINO IMX233_OLINUXINO 4105
+k2_wl MACH_K2_WL K2_WL 4106
+k2_ul MACH_K2_UL K2_UL 4107
+k2_cl MACH_K2_CL K2_CL 4108
+minbari_w MACH_MINBARI_W MINBARI_W 4109
+minbari_m MACH_MINBARI_M MINBARI_M 4110
+k035 MACH_K035 K035 4111
+ariel MACH_ARIEL ARIEL 4112
+arielsaarc MACH_ARIELSAARC ARIELSAARC 4113
+arieldkb MACH_ARIELDKB ARIELDKB 4114
+armadillo810 MACH_ARMADILLO810 ARMADILLO810 4115
+tam335x MACH_TAM335X TAM335X 4116
+grouper MACH_GROUPER GROUPER 4117
+mpcsa21_9g20 MACH_MPCSA21_9G20 MPCSA21_9G20 4118
+m6u_cpu MACH_M6U_CPU M6U_CPU 4119
+ginkgo MACH_GINKGO GINKGO 4121
+cgt_qmx6 MACH_CGT_QMX6 CGT_QMX6 4122
+profpga MACH_PROFPGA PROFPGA 4123
+acfx100oc MACH_ACFX100OC ACFX100OC 4124
+acfx100nb MACH_ACFX100NB ACFX100NB 4125
+capricorn MACH_CAPRICORN CAPRICORN 4126
+pisces MACH_PISCES PISCES 4127
+aries MACH_ARIES ARIES 4128
+cancer MACH_CANCER CANCER 4129
+leo MACH_LEO LEO 4130
+virgo MACH_VIRGO VIRGO 4131
+sagittarius MACH_SAGITTARIUS SAGITTARIUS 4132
+devil MACH_DEVIL DEVIL 4133
+ballantines MACH_BALLANTINES BALLANTINES 4134
+omap3_procerusvpu MACH_OMAP3_PROCERUSVPU OMAP3_PROCERUSVPU 4135
+my27 MACH_MY27 MY27 4136
+sun6i MACH_SUN6I SUN6I 4137
+sun5i MACH_SUN5I SUN5I 4138
+mx512_mx MACH_MX512_MX MX512_MX 4139
+kzm9g MACH_KZM9G KZM9G 4140
+vdstbn MACH_VDSTBN VDSTBN 4141
+cfa10036 MACH_CFA10036 CFA10036 4142
+cfa10049 MACH_CFA10049 CFA10049 4143
+pcm051 MACH_PCM051 PCM051 4144
+vybrid_vf7xx MACH_VYBRID_VF7XX VYBRID_VF7XX 4145
+vybrid_vf6xx MACH_VYBRID_VF6XX VYBRID_VF6XX 4146
+vybrid_vf5xx MACH_VYBRID_VF5XX VYBRID_VF5XX 4147
+vybrid_vf4xx MACH_VYBRID_VF4XX VYBRID_VF4XX 4148
+aria_g25 MACH_ARIA_G25 ARIA_G25 4149
+bcm21553 MACH_BCM21553 BCM21553 4150
+smdk5410 MACH_SMDK5410 SMDK5410 4151
+lpc18xx MACH_LPC18XX LPC18XX 4152
+oratisparty MACH_ORATISPARTY ORATISPARTY 4153
+qseven MACH_QSEVEN QSEVEN 4154
+gmv_generic MACH_GMV_GENERIC GMV_GENERIC 4155
+th_link_eth MACH_TH_LINK_ETH TH_LINK_ETH 4156
+tn_muninn MACH_TN_MUNINN TN_MUNINN 4157
+rampage MACH_RAMPAGE RAMPAGE 4158
+visstrim_mv10 MACH_VISSTRIM_MV10 VISSTRIM_MV10 4159
+mx28_wilma MACH_MX28_WILMA MX28_WILMA 4164
+msm8625_ffa MACH_MSM8625_FFA MSM8625_FFA 4166
+vpu101 MACH_VPU101 VPU101 4167
+baileys MACH_BAILEYS BAILEYS 4169
+familybox MACH_FAMILYBOX FAMILYBOX 4170
+ensemble_mx35 MACH_ENSEMBLE_MX35 ENSEMBLE_MX35 4171
+sc_sps_1 MACH_SC_SPS_1 SC_SPS_1 4172
+ucsimply_sam9260 MACH_UCSIMPLY_SAM9260 UCSIMPLY_SAM9260 4173
+unicorn MACH_UNICORN UNICORN 4174
+m9g45a MACH_M9G45A M9G45A 4175
+mtwebif MACH_MTWEBIF MTWEBIF 4176
+playstone MACH_PLAYSTONE PLAYSTONE 4177
+chelsea MACH_CHELSEA CHELSEA 4178
+bayern MACH_BAYERN BAYERN 4179
+mitwo MACH_MITWO MITWO 4180
+mx25_noah MACH_MX25_NOAH MX25_NOAH 4181
+stm_b2020 MACH_STM_B2020 STM_B2020 4182
+annax_src MACH_ANNAX_SRC ANNAX_SRC 4183
+ionics_stratus MACH_IONICS_STRATUS IONICS_STRATUS 4184
+hugo MACH_HUGO HUGO 4185
+em300 MACH_EM300 EM300 4186
+mmp3_qseven MACH_MMP3_QSEVEN MMP3_QSEVEN 4187
+bosphorus2 MACH_BOSPHORUS2 BOSPHORUS2 4188
+tt2200 MACH_TT2200 TT2200 4189
+ocelot3 MACH_OCELOT3 OCELOT3 4190
+tek_cobra MACH_TEK_COBRA TEK_COBRA 4191
+protou MACH_PROTOU PROTOU 4192
+msm8625_evt MACH_MSM8625_EVT MSM8625_EVT 4193
+mx53_sellwood MACH_MX53_SELLWOOD MX53_SELLWOOD 4194
+somiq_am35 MACH_SOMIQ_AM35 SOMIQ_AM35 4195
+somiq_am37 MACH_SOMIQ_AM37 SOMIQ_AM37 4196
+k2_plc_cl MACH_K2_PLC_CL K2_PLC_CL 4197
+tc2 MACH_TC2 TC2 4198
+dulex_j MACH_DULEX_J DULEX_J 4199
+stm_b2044 MACH_STM_B2044 STM_B2044 4200
+deluxe_j MACH_DELUXE_J DELUXE_J 4201
+mango2443 MACH_MANGO2443 MANGO2443 4202
+cp2dcg MACH_CP2DCG CP2DCG 4203
+cp2dtg MACH_CP2DTG CP2DTG 4204
+cp2dug MACH_CP2DUG CP2DUG 4205
+var_som_am33 MACH_VAR_SOM_AM33 VAR_SOM_AM33 4206
+pepper MACH_PEPPER PEPPER 4207
+mango2450 MACH_MANGO2450 MANGO2450 4208
+valente_wx_c9 MACH_VALENTE_WX_C9 VALENTE_WX_C9 4209
+minitv MACH_MINITV MINITV 4210
+u8540 MACH_U8540 U8540 4211
+iv_atlas_i_z7e MACH_IV_ATLAS_I_Z7E IV_ATLAS_I_Z7E 4212
+mach_type_sky MACH_MACH_TYPE_SKY MACH_TYPE_SKY 4214
+bluesky MACH_BLUESKY BLUESKY 4215
+ngrouter MACH_NGROUTER NGROUTER 4216
+mx53_denetim MACH_MX53_DENETIM MX53_DENETIM 4217
+opal MACH_OPAL OPAL 4218
+gnet_us3gref MACH_GNET_US3GREF GNET_US3GREF 4219
+gnet_nc3g MACH_GNET_NC3G GNET_NC3G 4220
+gnet_ge3g MACH_GNET_GE3G GNET_GE3G 4221
+adp2 MACH_ADP2 ADP2 4222
+tqma28 MACH_TQMA28 TQMA28 4223
+kacom3 MACH_KACOM3 KACOM3 4224
+rrhdemo MACH_RRHDEMO RRHDEMO 4225
+protodug MACH_PROTODUG PROTODUG 4226
+lago MACH_LAGO LAGO 4227
+ktt30 MACH_KTT30 KTT30 4228
+ts43xx MACH_TS43XX TS43XX 4229
+mx6q_denso MACH_MX6Q_DENSO MX6Q_DENSO 4230
+comsat_gsmumts8 MACH_COMSAT_GSMUMTS8 COMSAT_GSMUMTS8 4231
+dreamx MACH_DREAMX DREAMX 4232
+thunderstonem MACH_THUNDERSTONEM THUNDERSTONEM 4233
+yoyopad MACH_YOYOPAD YOYOPAD 4234
+yoyopatient MACH_YOYOPATIENT YOYOPATIENT 4235
+a10l MACH_A10L A10L 4236
+mq60 MACH_MQ60 MQ60 4237
+linkstation_lsql MACH_LINKSTATION_LSQL LINKSTATION_LSQL 4238
+am3703gateway MACH_AM3703GATEWAY AM3703GATEWAY 4239
+accipiter MACH_ACCIPITER ACCIPITER 4240
+magnidug MACH_MAGNIDUG MAGNIDUG 4242
+hydra MACH_HYDRA HYDRA 4243
+sun3i MACH_SUN3I SUN3I 4244
+stm_b2078 MACH_STM_B2078 STM_B2078 4245
+at91sam9263deskv2 MACH_AT91SAM9263DESKV2 AT91SAM9263DESKV2 4246
+deluxe_r MACH_DELUXE_R DELUXE_R 4247
+p_98_v MACH_P_98_V P_98_V 4248
+p_98_c MACH_P_98_C P_98_C 4249
+davinci_am18xx_omn MACH_DAVINCI_AM18XX_OMN DAVINCI_AM18XX_OMN 4250
+socfpga_cyclone5 MACH_SOCFPGA_CYCLONE5 SOCFPGA_CYCLONE5 4251
+cabatuin MACH_CABATUIN CABATUIN 4252
+yoyopad_ft MACH_YOYOPAD_FT YOYOPAD_FT 4253
+dan2400evb MACH_DAN2400EVB DAN2400EVB 4254
+dan3400evb MACH_DAN3400EVB DAN3400EVB 4255
+edm_sf_imx6 MACH_EDM_SF_IMX6 EDM_SF_IMX6 4256
+edm_cf_imx6 MACH_EDM_CF_IMX6 EDM_CF_IMX6 4257
+vpos3xx MACH_VPOS3XX VPOS3XX 4258
+vulcano_9x5 MACH_VULCANO_9X5 VULCANO_9X5 4259
+spmp8000 MACH_SPMP8000 SPMP8000 4260
+catalina MACH_CATALINA CATALINA 4261
+rd88f5181l_fe MACH_RD88F5181L_FE RD88F5181L_FE 4262
+mx535_mx MACH_MX535_MX MX535_MX 4263
+armadillo840 MACH_ARMADILLO840 ARMADILLO840 4264
+spc9000baseboard MACH_SPC9000BASEBOARD SPC9000BASEBOARD 4265
+iris MACH_IRIS IRIS 4266
+protodcg MACH_PROTODCG PROTODCG 4267
+palmtree MACH_PALMTREE PALMTREE 4268
+novena MACH_NOVENA NOVENA 4269
+ma_um MACH_MA_UM MA_UM 4270
+ma_am MACH_MA_AM MA_AM 4271
+ems348 MACH_EMS348 EMS348 4272
+cm_fx6 MACH_CM_FX6 CM_FX6 4273
+arndale MACH_ARNDALE ARNDALE 4274
+q5xr5 MACH_Q5XR5 Q5XR5 4275
+willow MACH_WILLOW WILLOW 4276
+omap3621_odyv3 MACH_OMAP3621_ODYV3 OMAP3621_ODYV3 4277
+omapl138_presonus MACH_OMAPL138_PRESONUS OMAPL138_PRESONUS 4278
+dvf99 MACH_DVF99 DVF99 4279
+impression_j MACH_IMPRESSION_J IMPRESSION_J 4280
+qblissa9 MACH_QBLISSA9 QBLISSA9 4281
+robin_heliview10 MACH_ROBIN_HELIVIEW10 ROBIN_HELIVIEW10 4282
+sun7i MACH_SUN7I SUN7I 4283
+mx6q_hdmidongle MACH_MX6Q_HDMIDONGLE MX6Q_HDMIDONGLE 4284
+mx6_sid2 MACH_MX6_SID2 MX6_SID2 4285
+helios_v3 MACH_HELIOS_V3 HELIOS_V3 4286
+helios_v4 MACH_HELIOS_V4 HELIOS_V4 4287
+q7_imx6 MACH_Q7_IMX6 Q7_IMX6 4288
+odroidx MACH_ODROIDX ODROIDX 4289
+robpro MACH_ROBPRO ROBPRO 4290
+research59if_mk1 MACH_RESEARCH59IF_MK1 RESEARCH59IF_MK1 4291
+bobsleigh MACH_BOBSLEIGH BOBSLEIGH 4292
+dcshgwt3 MACH_DCSHGWT3 DCSHGWT3 4293
+gld1018 MACH_GLD1018 GLD1018 4294
+ev10 MACH_EV10 EV10 4295
+nitrogen6x MACH_NITROGEN6X NITROGEN6X 4296
+p_107_bb MACH_P_107_BB P_107_BB 4297
+evita_utl MACH_EVITA_UTL EVITA_UTL 4298
+falconwing MACH_FALCONWING FALCONWING 4299
+dct3 MACH_DCT3 DCT3 4300
+cpx2e_cell MACH_CPX2E_CELL CPX2E_CELL 4301
+amiro MACH_AMIRO AMIRO 4302
+mx6q_brassboard MACH_MX6Q_BRASSBOARD MX6Q_BRASSBOARD 4303
+dalmore MACH_DALMORE DALMORE 4304
+omap3_portal7cp MACH_OMAP3_PORTAL7CP OMAP3_PORTAL7CP 4305
+tegra_pluto MACH_TEGRA_PLUTO TEGRA_PLUTO 4306
+mx6sl_evk MACH_MX6SL_EVK MX6SL_EVK 4307
+m7 MACH_M7 M7 4308
+pxm2 MACH_PXM2 PXM2 4309
+haba_knx_lite MACH_HABA_KNX_LITE HABA_KNX_LITE 4310
+tai MACH_TAI TAI 4311
+prototd MACH_PROTOTD PROTOTD 4312
+dst_tonto MACH_DST_TONTO DST_TONTO 4313
+draco MACH_DRACO DRACO 4314
+dxr2 MACH_DXR2 DXR2 4315
+rut MACH_RUT RUT 4316
+am180x_wsc MACH_AM180X_WSC AM180X_WSC 4317
+deluxe_u MACH_DELUXE_U DELUXE_U 4318
+deluxe_ul MACH_DELUXE_UL DELUXE_UL 4319
+at91sam9260medths MACH_AT91SAM9260MEDTHS AT91SAM9260MEDTHS 4320
+matrix516 MACH_MATRIX516 MATRIX516 4321
+vid401x MACH_VID401X VID401X 4322
+helios_v5 MACH_HELIOS_V5 HELIOS_V5 4323
+playpaq2 MACH_PLAYPAQ2 PLAYPAQ2 4324
+igam MACH_IGAM IGAM 4325
+amico_i MACH_AMICO_I AMICO_I 4326
+amico_e MACH_AMICO_E AMICO_E 4327
+sentient_mm3_ck MACH_SENTIENT_MM3_CK SENTIENT_MM3_CK 4328
+smx6 MACH_SMX6 SMX6 4329
+pango MACH_PANGO PANGO 4330
+ns115_stick MACH_NS115_STICK NS115_STICK 4331
+bctrm3 MACH_BCTRM3 BCTRM3 4332
+doctorws MACH_DOCTORWS DOCTORWS 4333
+m2601 MACH_M2601 M2601 4334
+vgg1111 MACH_VGG1111 VGG1111 4337
+countach MACH_COUNTACH COUNTACH 4338
+visstrim_sm20 MACH_VISSTRIM_SM20 VISSTRIM_SM20 4339
+a639 MACH_A639 A639 4340
+spacemonkey MACH_SPACEMONKEY SPACEMONKEY 4341
+zpdu_stamp MACH_ZPDU_STAMP ZPDU_STAMP 4342
+htc_g7_clone MACH_HTC_G7_CLONE HTC_G7_CLONE 4343
+ft2080_corvus MACH_FT2080_CORVUS FT2080_CORVUS 4344
+fisland MACH_FISLAND FISLAND 4345
+zpdu MACH_ZPDU ZPDU 4346
+urt MACH_URT URT 4347
+conti_ovip MACH_CONTI_OVIP CONTI_OVIP 4348
+omapl138_nagra MACH_OMAPL138_NAGRA OMAPL138_NAGRA 4349
+da850_at3kp1 MACH_DA850_AT3KP1 DA850_AT3KP1 4350
+da850_at3kp2 MACH_DA850_AT3KP2 DA850_AT3KP2 4351
+surma MACH_SURMA SURMA 4352
+stm_b2092 MACH_STM_B2092 STM_B2092 4353
+mx535_ycr MACH_MX535_YCR MX535_YCR 4354
+m7_wl MACH_M7_WL M7_WL 4355
+m7_u MACH_M7_U M7_U 4356
+omap3_stndt_evm MACH_OMAP3_STNDT_EVM OMAP3_STNDT_EVM 4357
+m7_wlv MACH_M7_WLV M7_WLV 4358
+xam3517 MACH_XAM3517 XAM3517 4359
+a220 MACH_A220 A220 4360
+aclima_odie MACH_ACLIMA_ODIE ACLIMA_ODIE 4361
+vibble MACH_VIBBLE VIBBLE 4362
+k2_u MACH_K2_U K2_U 4363
+mx53_egf MACH_MX53_EGF MX53_EGF 4364
+novpek_imx53 MACH_NOVPEK_IMX53 NOVPEK_IMX53 4365
+novpek_imx6x MACH_NOVPEK_IMX6X NOVPEK_IMX6X 4366
+mx25_smartbox MACH_MX25_SMARTBOX MX25_SMARTBOX 4367
+eicg6410 MACH_EICG6410 EICG6410 4368
+picasso_e3 MACH_PICASSO_E3 PICASSO_E3 4369
+motonavigator MACH_MOTONAVIGATOR MOTONAVIGATOR 4370
+varioconnect2 MACH_VARIOCONNECT2 VARIOCONNECT2 4371
+deluxe_tw MACH_DELUXE_TW DELUXE_TW 4372
+kore3 MACH_KORE3 KORE3 4374
+mx6s_drs MACH_MX6S_DRS MX6S_DRS 4375
+cmimx6 MACH_CMIMX6 CMIMX6 4376
+roth MACH_ROTH ROTH 4377
+eq4ux MACH_EQ4UX EQ4UX 4378
+x1plus MACH_X1PLUS X1PLUS 4379
+modimx27 MACH_MODIMX27 MODIMX27 4380
+videon_hduac MACH_VIDEON_HDUAC VIDEON_HDUAC 4381
+blackbird MACH_BLACKBIRD BLACKBIRD 4382
+runmaster MACH_RUNMASTER RUNMASTER 4383
+ceres MACH_CERES CERES 4384
+nad435 MACH_NAD435 NAD435 4385
+ns115_proto_type MACH_NS115_PROTO_TYPE NS115_PROTO_TYPE 4386
+fs20_vcc MACH_FS20_VCC FS20_VCC 4387
+meson6tv_skt MACH_MESON6TV_SKT MESON6TV_SKT 4389
+keystone MACH_KEYSTONE KEYSTONE 4390
+pcm052 MACH_PCM052 PCM052 4391
+qrd_skud_prime MACH_QRD_SKUD_PRIME QRD_SKUD_PRIME 4393
+guf_santaro MACH_GUF_SANTARO GUF_SANTARO 4395
+sheepshead MACH_SHEEPSHEAD SHEEPSHEAD 4396
+mx6_iwg15m_mxm MACH_MX6_IWG15M_MXM MX6_IWG15M_MXM 4397
+mx6_iwg15m_q7 MACH_MX6_IWG15M_Q7 MX6_IWG15M_Q7 4398
+at91sam9263if8mic MACH_AT91SAM9263IF8MIC AT91SAM9263IF8MIC 4399
+marcopolo MACH_MARCOPOLO MARCOPOLO 4401
+mx535_sdcr MACH_MX535_SDCR MX535_SDCR 4402
+mx53_csb2733 MACH_MX53_CSB2733 MX53_CSB2733 4403
+diva MACH_DIVA DIVA 4404
+ncr_7744 MACH_NCR_7744 NCR_7744 4405
+macallan MACH_MACALLAN MACALLAN 4406
+wnr3500 MACH_WNR3500 WNR3500 4407
+pgavrf MACH_PGAVRF PGAVRF 4408
+helios_v6 MACH_HELIOS_V6 HELIOS_V6 4409
+lcct MACH_LCCT LCCT 4410
+csndug MACH_CSNDUG CSNDUG 4411
+wandboard_imx6 MACH_WANDBOARD_IMX6 WANDBOARD_IMX6 4412
+omap4_jet MACH_OMAP4_JET OMAP4_JET 4413
+tegra_roth MACH_TEGRA_ROTH TEGRA_ROTH 4414
+m7dcg MACH_M7DCG M7DCG 4415
+m7dug MACH_M7DUG M7DUG 4416
+m7dtg MACH_M7DTG M7DTG 4417
+ap42x MACH_AP42X AP42X 4418
+var_som_mx6 MACH_VAR_SOM_MX6 VAR_SOM_MX6 4419
+pdlu MACH_PDLU PDLU 4420
+hydrogen MACH_HYDROGEN HYDROGEN 4421
+npa211e MACH_NPA211E NPA211E 4422
+arcadia MACH_ARCADIA ARCADIA 4423
+arcadia_l MACH_ARCADIA_L ARCADIA_L 4424
+msm8930dt MACH_MSM8930DT MSM8930DT 4425
+ktam3874 MACH_KTAM3874 KTAM3874 4426
+cec4 MACH_CEC4 CEC4 4427
+ape6evm MACH_APE6EVM APE6EVM 4428
+tx6 MACH_TX6 TX6 4429
+cfa10037 MACH_CFA10037 CFA10037 4431
+ezp1000 MACH_EZP1000 EZP1000 4433
+wgr826v MACH_WGR826V WGR826V 4434
+exuma MACH_EXUMA EXUMA 4435
+fregate MACH_FREGATE FREGATE 4436
+osirisimx508 MACH_OSIRISIMX508 OSIRISIMX508 4437
+st_exigo MACH_ST_EXIGO ST_EXIGO 4438
+pismo MACH_PISMO PISMO 4439
+atc7 MACH_ATC7 ATC7 4440
+nspireclp MACH_NSPIRECLP NSPIRECLP 4441
+nspiretp MACH_NSPIRETP NSPIRETP 4442
+nspirecx MACH_NSPIRECX NSPIRECX 4443
+maya MACH_MAYA MAYA 4444
+wecct MACH_WECCT WECCT 4445
+m2s MACH_M2S M2S 4446
+msm8625q_evbd MACH_MSM8625Q_EVBD MSM8625Q_EVBD 4447
+tiny210 MACH_TINY210 TINY210 4448
+g3 MACH_G3 G3 4449
+hurricane MACH_HURRICANE HURRICANE 4450
+mx6_pod MACH_MX6_POD MX6_POD 4451
+elondcn MACH_ELONDCN ELONDCN 4452
+cwmx535 MACH_CWMX535 CWMX535 4453
+m7_wlj MACH_M7_WLJ M7_WLJ 4454
+qsp_arm MACH_QSP_ARM QSP_ARM 4455
+msm8625q_skud MACH_MSM8625Q_SKUD MSM8625Q_SKUD 4456
+htcmondrian MACH_HTCMONDRIAN HTCMONDRIAN 4457
+watson_ead MACH_WATSON_EAD WATSON_EAD 4458
+mitwoa MACH_MITWOA MITWOA 4459
+omap3_wolverine MACH_OMAP3_WOLVERINE OMAP3_WOLVERINE 4460
+mapletree MACH_MAPLETREE MAPLETREE 4461
+msm8625_fih_sae MACH_MSM8625_FIH_SAE MSM8625_FIH_SAE 4462
+epc35 MACH_EPC35 EPC35 4463
+smartrtu MACH_SMARTRTU SMARTRTU 4464
+rcm101 MACH_RCM101 RCM101 4465
+amx_imx53_mxx MACH_AMX_IMX53_MXX AMX_IMX53_MXX 4466
+acer_a12 MACH_ACER_A12 ACER_A12 4470
+sbc6x MACH_SBC6X SBC6X 4471
+u2 MACH_U2 U2 4472
+smdk4270 MACH_SMDK4270 SMDK4270 4473
+priscillag MACH_PRISCILLAG PRISCILLAG 4474
+priscillac MACH_PRISCILLAC PRISCILLAC 4475
+priscilla MACH_PRISCILLA PRISCILLA 4476
+innova_shpu_v2 MACH_INNOVA_SHPU_V2 INNOVA_SHPU_V2 4477
+mach_type_dep2410 MACH_MACH_TYPE_DEP2410 MACH_TYPE_DEP2410 4479
+bctre3 MACH_BCTRE3 BCTRE3 4480
+omap_m100 MACH_OMAP_M100 OMAP_M100 4481
+flo MACH_FLO FLO 4482
+nanobone MACH_NANOBONE NANOBONE 4483
+stm_b2105 MACH_STM_B2105 STM_B2105 4484
+omap4_bsc_bap_v3 MACH_OMAP4_BSC_BAP_V3 OMAP4_BSC_BAP_V3 4485
+ss1pam MACH_SS1PAM SS1PAM 4486
+primominiu MACH_PRIMOMINIU PRIMOMINIU 4488
+mrt_35hd_dualnas_e MACH_MRT_35HD_DUALNAS_E MRT_35HD_DUALNAS_E 4489
+kiwi MACH_KIWI KIWI 4490
+hw90496 MACH_HW90496 HW90496 4491
+mep2440 MACH_MEP2440 MEP2440 4492
+colibri_t30 MACH_COLIBRI_T30 COLIBRI_T30 4493
+cwv1 MACH_CWV1 CWV1 4494
+nsa325 MACH_NSA325 NSA325 4495
+dpxmtc MACH_DPXMTC DPXMTC 4497
+tt_stuttgart MACH_TT_STUTTGART TT_STUTTGART 4498
+miranda_apcii MACH_MIRANDA_APCII MIRANDA_APCII 4499
+mx6q_moderox MACH_MX6Q_MODEROX MX6Q_MODEROX 4500
+mudskipper MACH_MUDSKIPPER MUDSKIPPER 4501
+urania MACH_URANIA URANIA 4502
+stm_b2112 MACH_STM_B2112 STM_B2112 4503
+mx6q_ats_phoenix MACH_MX6Q_ATS_PHOENIX MX6Q_ATS_PHOENIX 4505
+stm_b2116 MACH_STM_B2116 STM_B2116 4506
+mythology MACH_MYTHOLOGY MYTHOLOGY 4507
+fc360v1 MACH_FC360V1 FC360V1 4508
+gps_sensor MACH_GPS_SENSOR GPS_SENSOR 4509
+gazelle MACH_GAZELLE GAZELLE 4510
+mpq8064_dma MACH_MPQ8064_DMA MPQ8064_DMA 4511
+wems_asd01 MACH_WEMS_ASD01 WEMS_ASD01 4512
+apalis_t30 MACH_APALIS_T30 APALIS_T30 4513
+armstonea9 MACH_ARMSTONEA9 ARMSTONEA9 4515
+omap_blazetablet MACH_OMAP_BLAZETABLET OMAP_BLAZETABLET 4516
+ar6mxq MACH_AR6MXQ AR6MXQ 4517
+ar6mxs MACH_AR6MXS AR6MXS 4518
+gwventana MACH_GWVENTANA GWVENTANA 4520
+igep0033 MACH_IGEP0033 IGEP0033 4521
+h52c1_concerto MACH_H52C1_CONCERTO H52C1_CONCERTO 4524
+fcmbrd MACH_FCMBRD FCMBRD 4525
+pcaaxs1 MACH_PCAAXS1 PCAAXS1 4526
+ls_orca MACH_LS_ORCA LS_ORCA 4527
+pcm051lb MACH_PCM051LB PCM051LB 4528
+mx6s_lp507_gvci MACH_MX6S_LP507_GVCI MX6S_LP507_GVCI 4529
+dido MACH_DIDO DIDO 4530
+swarco_itc3_9g20 MACH_SWARCO_ITC3_9G20 SWARCO_ITC3_9G20 4531
+robo_roady MACH_ROBO_ROADY ROBO_ROADY 4532
+rskrza1 MACH_RSKRZA1 RSKRZA1 4533
+swarco_sid MACH_SWARCO_SID SWARCO_SID 4534
+mx6_iwg15s_sbc MACH_MX6_IWG15S_SBC MX6_IWG15S_SBC 4535
+mx6q_camaro MACH_MX6Q_CAMARO MX6Q_CAMARO 4536
+hb6mxs MACH_HB6MXS HB6MXS 4537
+lager MACH_LAGER LAGER 4538
+lp8x4x MACH_LP8X4X LP8X4X 4539
+tegratab7 MACH_TEGRATAB7 TEGRATAB7 4540
+andromeda MACH_ANDROMEDA ANDROMEDA 4541
+bootes MACH_BOOTES BOOTES 4542
+nethmi MACH_NETHMI NETHMI 4543
+tegratab MACH_TEGRATAB TEGRATAB 4544
+som5_evb MACH_SOM5_EVB SOM5_EVB 4545
+venaticorum MACH_VENATICORUM VENATICORUM 4546
+stm_b2110 MACH_STM_B2110 STM_B2110 4547
+elux_hathor MACH_ELUX_HATHOR ELUX_HATHOR 4548
+helios_v7 MACH_HELIOS_V7 HELIOS_V7 4549
+xc10v1 MACH_XC10V1 XC10V1 4550
+cp2u MACH_CP2U CP2U 4551
+iap_f MACH_IAP_F IAP_F 4552
+iap_g MACH_IAP_G IAP_G 4553
+aae MACH_AAE AAE 4554
+pegasus MACH_PEGASUS PEGASUS 4555
+cygnus MACH_CYGNUS CYGNUS 4556
+centaurus MACH_CENTAURUS CENTAURUS 4557
+msm8930_qrd8930 MACH_MSM8930_QRD8930 MSM8930_QRD8930 4558
+quby_tim MACH_QUBY_TIM QUBY_TIM 4559
+zedi3250a MACH_ZEDI3250A ZEDI3250A 4560
+grus MACH_GRUS GRUS 4561
+apollo3 MACH_APOLLO3 APOLLO3 4562
+cowon_r7 MACH_COWON_R7 COWON_R7 4563
+tonga3 MACH_TONGA3 TONGA3 4564
+p535 MACH_P535 P535 4565
+sa3874i MACH_SA3874I SA3874I 4566
+mx6_navico_com MACH_MX6_NAVICO_COM MX6_NAVICO_COM 4567
+proxmobil2 MACH_PROXMOBIL2 PROXMOBIL2 4568
+ubinux1 MACH_UBINUX1 UBINUX1 4569
+istos MACH_ISTOS ISTOS 4570
+benvolio4 MACH_BENVOLIO4 BENVOLIO4 4571
+eco5_bx2 MACH_ECO5_BX2 ECO5_BX2 4572
+eukrea_cpuimx28sd MACH_EUKREA_CPUIMX28SD EUKREA_CPUIMX28SD 4573
+domotab MACH_DOMOTAB DOMOTAB 4574
+pfla03 MACH_PFLA03 PFLA03 4575
diff --git a/arch/arm/vdso/.gitignore b/arch/arm/vdso/.gitignore
new file mode 100644
index 000000000..6b47f6e0b
--- /dev/null
+++ b/arch/arm/vdso/.gitignore
@@ -0,0 +1,3 @@
+vdso.lds
+vdso.so.raw
+vdsomunge
diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile
new file mode 100644
index 000000000..8aa791051
--- /dev/null
+++ b/arch/arm/vdso/Makefile
@@ -0,0 +1,74 @@
+hostprogs-y := vdsomunge
+
+obj-vdso := vgettimeofday.o datapage.o
+
+# Build rules
+targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.so.raw vdso.lds
+obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
+
+ccflags-y := -shared -fPIC -fno-common -fno-builtin -fno-stack-protector
+ccflags-y += -nostdlib -Wl,-soname=linux-vdso.so.1 -DDISABLE_BRANCH_PROFILING
+ccflags-y += -Wl,--no-undefined $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
+
+obj-$(CONFIG_VDSO) += vdso.o
+extra-$(CONFIG_VDSO) += vdso.lds
+CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
+
+CFLAGS_REMOVE_vdso.o = -pg
+
+# Force -O2 to avoid libgcc dependencies
+CFLAGS_REMOVE_vgettimeofday.o = -pg -Os
+CFLAGS_vgettimeofday.o = -O2
+
+# Disable gcov profiling for VDSO code
+GCOV_PROFILE := n
+
+# Force dependency
+$(obj)/vdso.o : $(obj)/vdso.so
+
+# Link rule for the .so file
+$(obj)/vdso.so.raw: $(src)/vdso.lds $(obj-vdso) FORCE
+ $(call if_changed,vdsold)
+
+$(obj)/vdso.so.dbg: $(obj)/vdso.so.raw $(obj)/vdsomunge FORCE
+ $(call if_changed,vdsomunge)
+
+# Strip rule for the .so file
+$(obj)/%.so: OBJCOPYFLAGS := -S
+$(obj)/%.so: $(obj)/%.so.dbg FORCE
+ $(call if_changed,objcopy)
+
+# Actual build commands
+quiet_cmd_vdsold = VDSO $@
+ cmd_vdsold = $(CC) $(c_flags) -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) \
+ $(call cc-ldoption, -Wl$(comma)--build-id) \
+ -Wl,-Bsymbolic -Wl,-z,max-page-size=4096 \
+ -Wl,-z,common-page-size=4096 -o $@
+
+quiet_cmd_vdsomunge = MUNGE $@
+ cmd_vdsomunge = $(objtree)/$(obj)/vdsomunge $< $@
+
+#
+# Install the unstripped copy of vdso.so.dbg. If our toolchain
+# supports build-id, install .build-id links as well.
+#
+# Cribbed from arch/x86/vdso/Makefile.
+#
+quiet_cmd_vdso_install = INSTALL $<
+define cmd_vdso_install
+ cp $< "$(MODLIB)/vdso/vdso.so"; \
+ if readelf -n $< | grep -q 'Build ID'; then \
+ buildid=`readelf -n $< |grep 'Build ID' |sed -e 's/^.*Build ID: \(.*\)$$/\1/'`; \
+ first=`echo $$buildid | cut -b-2`; \
+ last=`echo $$buildid | cut -b3-`; \
+ mkdir -p "$(MODLIB)/vdso/.build-id/$$first"; \
+ ln -sf "../../vdso.so" "$(MODLIB)/vdso/.build-id/$$first/$$last.debug"; \
+ fi
+endef
+
+$(MODLIB)/vdso: FORCE
+ @mkdir -p $(MODLIB)/vdso
+
+PHONY += vdso_install
+vdso_install: $(obj)/vdso.so.dbg $(MODLIB)/vdso FORCE
+ $(call cmd,vdso_install)
diff --git a/arch/arm/vdso/datapage.S b/arch/arm/vdso/datapage.S
new file mode 100644
index 000000000..a2e603679
--- /dev/null
+++ b/arch/arm/vdso/datapage.S
@@ -0,0 +1,15 @@
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+
+ .align 2
+.L_vdso_data_ptr:
+ .long _start - . - VDSO_DATA_SIZE
+
+ENTRY(__get_datapage)
+ .fnstart
+ adr r0, .L_vdso_data_ptr
+ ldr r1, [r0]
+ add r0, r0, r1
+ bx lr
+ .fnend
+ENDPROC(__get_datapage)
diff --git a/arch/arm/vdso/vdso.S b/arch/arm/vdso/vdso.S
new file mode 100644
index 000000000..b2b97e3e7
--- /dev/null
+++ b/arch/arm/vdso/vdso.S
@@ -0,0 +1,35 @@
+/*
+ * Adapted from arm64 version.
+ *
+ * Copyright (C) 2012 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/const.h>
+#include <asm/page.h>
+
+ __PAGE_ALIGNED_DATA
+
+ .globl vdso_start, vdso_end
+ .balign PAGE_SIZE
+vdso_start:
+ .incbin "arch/arm/vdso/vdso.so"
+ .balign PAGE_SIZE
+vdso_end:
+
+ .previous
diff --git a/arch/arm/vdso/vdso.lds.S b/arch/arm/vdso/vdso.lds.S
new file mode 100644
index 000000000..89ca89f12
--- /dev/null
+++ b/arch/arm/vdso/vdso.lds.S
@@ -0,0 +1,87 @@
+/*
+ * Adapted from arm64 version.
+ *
+ * GNU linker script for the VDSO library.
+ *
+ * Copyright (C) 2012 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ * Heavily based on the vDSO linker scripts for other archs.
+ */
+
+#include <linux/const.h>
+#include <asm/page.h>
+#include <asm/vdso.h>
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+SECTIONS
+{
+ PROVIDE(_start = .);
+
+ . = SIZEOF_HEADERS;
+
+ .hash : { *(.hash) } :text
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+
+ .note : { *(.note.*) } :text :note
+
+
+ .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
+ .eh_frame : { KEEP (*(.eh_frame)) } :text
+
+ .dynamic : { *(.dynamic) } :text :dynamic
+
+ .rodata : { *(.rodata*) } :text
+
+ .text : { *(.text*) } :text =0xe7f001f2
+
+ .got : { *(.got) }
+ .rel.plt : { *(.rel.plt) }
+
+ /DISCARD/ : {
+ *(.note.GNU-stack)
+ *(.data .data.* .gnu.linkonce.d.* .sdata*)
+ *(.bss .sbss .dynbss .dynsbss)
+ }
+}
+
+/*
+ * We must supply the ELF program headers explicitly to get just one
+ * PT_LOAD segment, and set the flags explicitly to make segments read-only.
+ */
+PHDRS
+{
+ text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
+ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+ note PT_NOTE FLAGS(4); /* PF_R */
+ eh_frame_hdr PT_GNU_EH_FRAME;
+}
+
+VERSION
+{
+ LINUX_2.6 {
+ global:
+ __vdso_clock_gettime;
+ __vdso_gettimeofday;
+ local: *;
+ };
+}
diff --git a/arch/arm/vdso/vdsomunge.c b/arch/arm/vdso/vdsomunge.c
new file mode 100644
index 000000000..aedec81d1
--- /dev/null
+++ b/arch/arm/vdso/vdsomunge.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2015 Mentor Graphics Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * vdsomunge - Host program which produces a shared object
+ * architecturally specified to be usable by both soft- and hard-float
+ * programs.
+ *
+ * The Procedure Call Standard for the ARM Architecture (ARM IHI
+ * 0042E) says:
+ *
+ * 6.4.1 VFP and Base Standard Compatibility
+ *
+ * Code compiled for the VFP calling standard is compatible with
+ * the base standard (and vice-versa) if no floating-point or
+ * containerized vector arguments or results are used.
+ *
+ * And ELF for the ARM Architecture (ARM IHI 0044E) (Table 4-2) says:
+ *
+ * If both EF_ARM_ABI_FLOAT_XXXX bits are clear, conformance to the
+ * base procedure-call standard is implied.
+ *
+ * The VDSO is built with -msoft-float, as with the rest of the ARM
+ * kernel, and uses no floating point arguments or results. The build
+ * process will produce a shared object that may or may not have the
+ * EF_ARM_ABI_FLOAT_SOFT flag set (it seems to depend on the binutils
+ * version; binutils starting with 2.24 appears to set it). The
+ * EF_ARM_ABI_FLOAT_HARD flag should definitely not be set, and this
+ * program will error out if it is.
+ *
+ * If the soft-float flag is set, this program clears it. That's all
+ * it does.
+ */
+
+#include <byteswap.h>
+#include <elf.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define HOST_ORDER ELFDATA2LSB
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define HOST_ORDER ELFDATA2MSB
+#endif
+
+/* Some of the ELF constants we'd like to use were added to <elf.h>
+ * relatively recently.
+ */
+#ifndef EF_ARM_EABI_VER5
+#define EF_ARM_EABI_VER5 0x05000000
+#endif
+
+#ifndef EF_ARM_ABI_FLOAT_SOFT
+#define EF_ARM_ABI_FLOAT_SOFT 0x200
+#endif
+
+#ifndef EF_ARM_ABI_FLOAT_HARD
+#define EF_ARM_ABI_FLOAT_HARD 0x400
+#endif
+
+static int failed;
+static const char *argv0;
+static const char *outfile;
+
+static void fail(const char *fmt, ...)
+{
+ va_list ap;
+
+ failed = 1;
+ fprintf(stderr, "%s: ", argv0);
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ exit(EXIT_FAILURE);
+}
+
+static void cleanup(void)
+{
+ if (failed && outfile != NULL)
+ unlink(outfile);
+}
+
+static Elf32_Word read_elf_word(Elf32_Word word, bool swap)
+{
+ return swap ? bswap_32(word) : word;
+}
+
+static Elf32_Half read_elf_half(Elf32_Half half, bool swap)
+{
+ return swap ? bswap_16(half) : half;
+}
+
+static void write_elf_word(Elf32_Word val, Elf32_Word *dst, bool swap)
+{
+ *dst = swap ? bswap_32(val) : val;
+}
+
+int main(int argc, char **argv)
+{
+ const Elf32_Ehdr *inhdr;
+ bool clear_soft_float;
+ const char *infile;
+ Elf32_Word e_flags;
+ const void *inbuf;
+ struct stat stat;
+ void *outbuf;
+ bool swap;
+ int outfd;
+ int infd;
+
+ atexit(cleanup);
+ argv0 = argv[0];
+
+ if (argc != 3)
+ fail("Usage: %s [infile] [outfile]\n", argv[0]);
+
+ infile = argv[1];
+ outfile = argv[2];
+
+ infd = open(infile, O_RDONLY);
+ if (infd < 0)
+ fail("Cannot open %s: %s\n", infile, strerror(errno));
+
+ if (fstat(infd, &stat) != 0)
+ fail("Failed stat for %s: %s\n", infile, strerror(errno));
+
+ inbuf = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, infd, 0);
+ if (inbuf == MAP_FAILED)
+ fail("Failed to map %s: %s\n", infile, strerror(errno));
+
+ close(infd);
+
+ inhdr = inbuf;
+
+ if (memcmp(&inhdr->e_ident, ELFMAG, SELFMAG) != 0)
+ fail("Not an ELF file\n");
+
+ if (inhdr->e_ident[EI_CLASS] != ELFCLASS32)
+ fail("Unsupported ELF class\n");
+
+ swap = inhdr->e_ident[EI_DATA] != HOST_ORDER;
+
+ if (read_elf_half(inhdr->e_type, swap) != ET_DYN)
+ fail("Not a shared object\n");
+
+ if (read_elf_half(inhdr->e_machine, swap) != EM_ARM)
+ fail("Unsupported architecture %#x\n", inhdr->e_machine);
+
+ e_flags = read_elf_word(inhdr->e_flags, swap);
+
+ if (EF_ARM_EABI_VERSION(e_flags) != EF_ARM_EABI_VER5) {
+ fail("Unsupported EABI version %#x\n",
+ EF_ARM_EABI_VERSION(e_flags));
+ }
+
+ if (e_flags & EF_ARM_ABI_FLOAT_HARD)
+ fail("Unexpected hard-float flag set in e_flags\n");
+
+ clear_soft_float = !!(e_flags & EF_ARM_ABI_FLOAT_SOFT);
+
+ outfd = open(outfile, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+ if (outfd < 0)
+ fail("Cannot open %s: %s\n", outfile, strerror(errno));
+
+ if (ftruncate(outfd, stat.st_size) != 0)
+ fail("Cannot truncate %s: %s\n", outfile, strerror(errno));
+
+ outbuf = mmap(NULL, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,
+ outfd, 0);
+ if (outbuf == MAP_FAILED)
+ fail("Failed to map %s: %s\n", outfile, strerror(errno));
+
+ close(outfd);
+
+ memcpy(outbuf, inbuf, stat.st_size);
+
+ if (clear_soft_float) {
+ Elf32_Ehdr *outhdr;
+
+ outhdr = outbuf;
+ e_flags &= ~EF_ARM_ABI_FLOAT_SOFT;
+ write_elf_word(e_flags, &outhdr->e_flags, swap);
+ }
+
+ if (msync(outbuf, stat.st_size, MS_SYNC) != 0)
+ fail("Failed to sync %s: %s\n", outfile, strerror(errno));
+
+ return EXIT_SUCCESS;
+}
diff --git a/arch/arm/vdso/vgettimeofday.c b/arch/arm/vdso/vgettimeofday.c
new file mode 100644
index 000000000..79214d5ff
--- /dev/null
+++ b/arch/arm/vdso/vgettimeofday.c
@@ -0,0 +1,282 @@
+/*
+ * Copyright 2015 Mentor Graphics Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/compiler.h>
+#include <linux/hrtimer.h>
+#include <linux/time.h>
+#include <asm/arch_timer.h>
+#include <asm/barrier.h>
+#include <asm/bug.h>
+#include <asm/page.h>
+#include <asm/unistd.h>
+#include <asm/vdso_datapage.h>
+
+#ifndef CONFIG_AEABI
+#error This code depends on AEABI system call conventions
+#endif
+
+extern struct vdso_data *__get_datapage(void);
+
+static notrace u32 __vdso_read_begin(const struct vdso_data *vdata)
+{
+ u32 seq;
+repeat:
+ seq = ACCESS_ONCE(vdata->seq_count);
+ if (seq & 1) {
+ cpu_relax();
+ goto repeat;
+ }
+ return seq;
+}
+
+static notrace u32 vdso_read_begin(const struct vdso_data *vdata)
+{
+ u32 seq;
+
+ seq = __vdso_read_begin(vdata);
+
+ smp_rmb(); /* Pairs with smp_wmb in vdso_write_end */
+ return seq;
+}
+
+static notrace int vdso_read_retry(const struct vdso_data *vdata, u32 start)
+{
+ smp_rmb(); /* Pairs with smp_wmb in vdso_write_begin */
+ return vdata->seq_count != start;
+}
+
+static notrace long clock_gettime_fallback(clockid_t _clkid,
+ struct timespec *_ts)
+{
+ register struct timespec *ts asm("r1") = _ts;
+ register clockid_t clkid asm("r0") = _clkid;
+ register long ret asm ("r0");
+ register long nr asm("r7") = __NR_clock_gettime;
+
+ asm volatile(
+ " swi #0\n"
+ : "=r" (ret)
+ : "r" (clkid), "r" (ts), "r" (nr)
+ : "memory");
+
+ return ret;
+}
+
+static notrace int do_realtime_coarse(struct timespec *ts,
+ struct vdso_data *vdata)
+{
+ u32 seq;
+
+ do {
+ seq = vdso_read_begin(vdata);
+
+ ts->tv_sec = vdata->xtime_coarse_sec;
+ ts->tv_nsec = vdata->xtime_coarse_nsec;
+
+ } while (vdso_read_retry(vdata, seq));
+
+ return 0;
+}
+
+static notrace int do_monotonic_coarse(struct timespec *ts,
+ struct vdso_data *vdata)
+{
+ struct timespec tomono;
+ u32 seq;
+
+ do {
+ seq = vdso_read_begin(vdata);
+
+ ts->tv_sec = vdata->xtime_coarse_sec;
+ ts->tv_nsec = vdata->xtime_coarse_nsec;
+
+ tomono.tv_sec = vdata->wtm_clock_sec;
+ tomono.tv_nsec = vdata->wtm_clock_nsec;
+
+ } while (vdso_read_retry(vdata, seq));
+
+ ts->tv_sec += tomono.tv_sec;
+ timespec_add_ns(ts, tomono.tv_nsec);
+
+ return 0;
+}
+
+#ifdef CONFIG_ARM_ARCH_TIMER
+
+static notrace u64 get_ns(struct vdso_data *vdata)
+{
+ u64 cycle_delta;
+ u64 cycle_now;
+ u64 nsec;
+
+ cycle_now = arch_counter_get_cntvct();
+
+ cycle_delta = (cycle_now - vdata->cs_cycle_last) & vdata->cs_mask;
+
+ nsec = (cycle_delta * vdata->cs_mult) + vdata->xtime_clock_snsec;
+ nsec >>= vdata->cs_shift;
+
+ return nsec;
+}
+
+static notrace int do_realtime(struct timespec *ts, struct vdso_data *vdata)
+{
+ u64 nsecs;
+ u32 seq;
+
+ do {
+ seq = vdso_read_begin(vdata);
+
+ if (!vdata->tk_is_cntvct)
+ return -1;
+
+ ts->tv_sec = vdata->xtime_clock_sec;
+ nsecs = get_ns(vdata);
+
+ } while (vdso_read_retry(vdata, seq));
+
+ ts->tv_nsec = 0;
+ timespec_add_ns(ts, nsecs);
+
+ return 0;
+}
+
+static notrace int do_monotonic(struct timespec *ts, struct vdso_data *vdata)
+{
+ struct timespec tomono;
+ u64 nsecs;
+ u32 seq;
+
+ do {
+ seq = vdso_read_begin(vdata);
+
+ if (!vdata->tk_is_cntvct)
+ return -1;
+
+ ts->tv_sec = vdata->xtime_clock_sec;
+ nsecs = get_ns(vdata);
+
+ tomono.tv_sec = vdata->wtm_clock_sec;
+ tomono.tv_nsec = vdata->wtm_clock_nsec;
+
+ } while (vdso_read_retry(vdata, seq));
+
+ ts->tv_sec += tomono.tv_sec;
+ ts->tv_nsec = 0;
+ timespec_add_ns(ts, nsecs + tomono.tv_nsec);
+
+ return 0;
+}
+
+#else /* CONFIG_ARM_ARCH_TIMER */
+
+static notrace int do_realtime(struct timespec *ts, struct vdso_data *vdata)
+{
+ return -1;
+}
+
+static notrace int do_monotonic(struct timespec *ts, struct vdso_data *vdata)
+{
+ return -1;
+}
+
+#endif /* CONFIG_ARM_ARCH_TIMER */
+
+notrace int __vdso_clock_gettime(clockid_t clkid, struct timespec *ts)
+{
+ struct vdso_data *vdata;
+ int ret = -1;
+
+ vdata = __get_datapage();
+
+ switch (clkid) {
+ case CLOCK_REALTIME_COARSE:
+ ret = do_realtime_coarse(ts, vdata);
+ break;
+ case CLOCK_MONOTONIC_COARSE:
+ ret = do_monotonic_coarse(ts, vdata);
+ break;
+ case CLOCK_REALTIME:
+ ret = do_realtime(ts, vdata);
+ break;
+ case CLOCK_MONOTONIC:
+ ret = do_monotonic(ts, vdata);
+ break;
+ default:
+ break;
+ }
+
+ if (ret)
+ ret = clock_gettime_fallback(clkid, ts);
+
+ return ret;
+}
+
+static notrace long gettimeofday_fallback(struct timeval *_tv,
+ struct timezone *_tz)
+{
+ register struct timezone *tz asm("r1") = _tz;
+ register struct timeval *tv asm("r0") = _tv;
+ register long ret asm ("r0");
+ register long nr asm("r7") = __NR_gettimeofday;
+
+ asm volatile(
+ " swi #0\n"
+ : "=r" (ret)
+ : "r" (tv), "r" (tz), "r" (nr)
+ : "memory");
+
+ return ret;
+}
+
+notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+ struct timespec ts;
+ struct vdso_data *vdata;
+ int ret;
+
+ vdata = __get_datapage();
+
+ ret = do_realtime(&ts, vdata);
+ if (ret)
+ return gettimeofday_fallback(tv, tz);
+
+ if (tv) {
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = ts.tv_nsec / 1000;
+ }
+ if (tz) {
+ tz->tz_minuteswest = vdata->tz_minuteswest;
+ tz->tz_dsttime = vdata->tz_dsttime;
+ }
+
+ return ret;
+}
+
+/* Avoid unresolved references emitted by GCC */
+
+void __aeabi_unwind_cpp_pr0(void)
+{
+}
+
+void __aeabi_unwind_cpp_pr1(void)
+{
+}
+
+void __aeabi_unwind_cpp_pr2(void)
+{
+}
diff --git a/arch/arm/vfp/Makefile b/arch/arm/vfp/Makefile
new file mode 100644
index 000000000..a81404c09
--- /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 -mfloat-abi=soft)
+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 000000000..2e78760f3
--- /dev/null
+++ b/arch/arm/vfp/entry.S
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/vfpmacros.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+
+@ VFP entry point.
+@
+@ r0 = instruction opcode (32-bit ARM or two 16-bit Thumb)
+@ r2 = PC value to resume execution after successful emulation
+@ r9 = normal "successful" return address
+@ r10 = this threads thread_info structure
+@ lr = unrecognised instruction return address
+@ IRQs enabled.
+@
+ENTRY(do_vfp)
+ inc_preempt_count r10, r4
+ 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)
+ dec_preempt_count_ti r10, r4
+ ret 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)
+ dec_preempt_count_ti r10, r4
+ ldr r0, VFP_arch_address
+ str r0, [r0] @ set to non-zero value
+ ret 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 000000000..c8c98dd44
--- /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 000000000..423f56dd4
--- /dev/null
+++ b/arch/arm/vfp/vfpdouble.c
@@ -0,0 +1,1206 @@
+/*
+ * 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 (vdn.exponent == 0 && vdn.significand)
+ vfp_double_normalise_denormal(&vdn);
+ 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 000000000..f74a8f7e5
--- /dev/null
+++ b/arch/arm/vfp/vfphw.S
@@ -0,0 +1,323 @@
+/*
+ * 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 <linux/init.h>
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/vfpmacros.h>
+#include <linux/kern_levels.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+
+ .macro DBGSTR, str
+#ifdef DEBUG
+ stmfd sp!, {r0-r3, ip, lr}
+ ldr r0, =1f
+ bl printk
+ ldmfd sp!, {r0-r3, ip, lr}
+
+ .pushsection .rodata, "a"
+1: .ascii KERN_DEBUG "VFP: \str\n"
+ .byte 0
+ .previous
+#endif
+ .endm
+
+ .macro DBGSTR1, str, arg
+#ifdef DEBUG
+ stmfd sp!, {r0-r3, ip, lr}
+ mov r1, \arg
+ ldr r0, =1f
+ bl printk
+ ldmfd sp!, {r0-r3, ip, lr}
+
+ .pushsection .rodata, "a"
+1: .ascii KERN_DEBUG "VFP: \str\n"
+ .byte 0
+ .previous
+#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
+ ldr r0, =1f
+ bl printk
+ ldmfd sp!, {r0-r3, ip, lr}
+
+ .pushsection .rodata, "a"
+1: .ascii KERN_DEBUG "VFP: \str\n"
+ .byte 0
+ .previous
+#endif
+ .endm
+
+
+@ VFP hardware support entry point.
+@
+@ r0 = instruction opcode (32-bit ARM or two 16-bit Thumb)
+@ r2 = PC value to resume execution after successful emulation
+@ r9 = normal "successful" return address
+@ r10 = vfp_state union
+@ r11 = CPU number
+@ lr = unrecognised instruction return address
+@ IRQs enabled.
+ENTRY(vfp_support_entry)
+ DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10
+
+ ldr r3, [sp, #S_PSR] @ Neither lazy restore nor FP exceptions
+ and r3, r3, #MODE_MASK @ are supported in kernel mode
+ teq r3, #USR_MODE
+ bne vfp_kmode_exception @ Returns through lr
+
+ 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?
+#ifndef CONFIG_SMP
+ @ For UP, checking that this thread owns the hw context is
+ @ sufficient to determine that the hardware state is valid.
+ beq vfp_hw_state_valid
+
+ @ On UP, we lazily save the VFP context. As a different
+ @ thread wants ownership of the VFP hardware, save the old
+ @ state if there was a previous (valid) owner.
+
+ VFPFMXR FPEXC, r5 @ enable VFP, disable any pending
+ @ exceptions, so we can get at the
+ @ rest of it
+
+ DBGSTR1 "save old state %p", r4
+ cmp r4, #0 @ if the vfp_current_hw_state is NULL
+ beq vfp_reload_hw @ then the hw state needs reloading
+ 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
+vfp_reload_hw:
+
+#else
+ @ For SMP, if this thread does not own the hw context, then we
+ @ need to reload it. No need to save the old state as on SMP,
+ @ we always save the state when we switch away from a thread.
+ bne vfp_reload_hw
+
+ @ This thread has ownership of the current hardware context.
+ @ However, it may have been migrated to another CPU, in which
+ @ case the saved state is newer than the hardware context.
+ @ Check this by looking at the CPU number which the state was
+ @ last loaded onto.
+ ldr ip, [r10, #VFP_CPU]
+ teq ip, r11
+ beq vfp_hw_state_valid
+
+vfp_reload_hw:
+ @ We're loading this threads state into the VFP hardware. Update
+ @ the CPU number which contains the most up to date VFP context.
+ str r11, [r10, #VFP_CPU]
+
+ VFPFMXR FPEXC, r5 @ enable VFP, disable any pending
+ @ exceptions, so we can get at the
+ @ rest of it
+#endif
+
+ 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 @ Retry current instruction - if Thumb
+ str r2, [sp, #S_PC] @ mode it's two 16-bit instructions,
+ @ else it's one 32-bit instruction, so
+ @ always subtract 4 from the following
+ @ instruction address.
+ dec_preempt_count_ti r10, r4
+ ret 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
+
+ tst r5, #FPSCR_LENGTH_MASK
+ beq skip
+ orr r1, r1, #FPEXC_DEX
+ b process_exception
+skip:
+
+ @ Fall into hand on to next handler - appropriate coproc instr
+ @ not recognised by VFP
+
+ DBGSTR "not VFP"
+ dec_preempt_count_ti r10, r4
+ ret 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
+ ret 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
+ ret \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
+ ret lr
+ .org 1b + 8
+1: mrc p10, 0, r0, c\dr, c0, 4 @ fmrs r0, s1
+ ret 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
+ ret lr
+ .org 1b + 8
+1: mcr p10, 0, r0, c\dr, c0, 4 @ fmsr r0, s1
+ ret 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
+ ret 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
+ ret lr
+ .org 1b + 8
+ .endr
+#endif
+
+ @ virtual register 16 (or 32 if VFPv3) for compare with zero
+ mov r0, #0
+ mov r1, #0
+ ret 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
+ ret 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
+ ret 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 000000000..15b95b5ab
--- /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 000000000..f6e4d56ed
--- /dev/null
+++ b/arch/arm/vfp/vfpmodule.c
@@ -0,0 +1,811 @@
+/*
+ * 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/types.h>
+#include <linux/cpu.h>
+#include <linux/cpu_pm.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 <linux/uaccess.h>
+#include <linux/user.h>
+#include <linux/export.h>
+
+#include <asm/cp15.h>
+#include <asm/cputype.h>
+#include <asm/system_info.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;
+
+/*
+ * Dual-use variable.
+ * Used in startup: set to non-zero if VFP checks fail
+ * After startup, holds VFP architecture
+ */
+unsigned int VFP_arch;
+
+/*
+ * 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.
+ *
+ * For UP, this is sufficient to tell which thread owns the VFP context.
+ * However, for SMP, we also need to check the CPU number stored in the
+ * saved state too to catch migrations.
+ */
+union vfp_state *vfp_current_hw_state[NR_CPUS];
+
+/*
+ * Is 'thread's most up to date state stored in this CPUs hardware?
+ * Must be called from non-preemptible context.
+ */
+static bool vfp_state_in_hw(unsigned int cpu, struct thread_info *thread)
+{
+#ifdef CONFIG_SMP
+ if (thread->vfpstate.hard.cpu != cpu)
+ return false;
+#endif
+ return vfp_current_hw_state[cpu] == &thread->vfpstate;
+}
+
+/*
+ * Force a reload of the VFP context from the thread structure. We do
+ * this by ensuring that access to the VFP hardware is disabled, and
+ * clear vfp_current_hw_state. Must be called from non-preemptible context.
+ */
+static void vfp_force_reload(unsigned int cpu, struct thread_info *thread)
+{
+ if (vfp_state_in_hw(cpu, thread)) {
+ fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
+ vfp_current_hw_state[cpu] = NULL;
+ }
+#ifdef CONFIG_SMP
+ thread->vfpstate.hard.cpu = NR_CPUS;
+#endif
+}
+
+/*
+ * Per-thread VFP initialization.
+ */
+static void vfp_thread_flush(struct thread_info *thread)
+{
+ union vfp_state *vfp = &thread->vfpstate;
+ unsigned int cpu;
+
+ /*
+ * 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.
+ *
+ * Do this first to ensure that preemption won't overwrite our
+ * state saving should access to the VFP be enabled at this point.
+ */
+ cpu = get_cpu();
+ if (vfp_current_hw_state[cpu] == vfp)
+ vfp_current_hw_state[cpu] = NULL;
+ fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
+ put_cpu();
+
+ memset(vfp, 0, sizeof(union vfp_state));
+
+ vfp->hard.fpexc = FPEXC_EN;
+ vfp->hard.fpscr = FPSCR_ROUND_NEAREST;
+#ifdef CONFIG_SMP
+ vfp->hard.cpu = NR_CPUS;
+#endif
+}
+
+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;
+#ifdef CONFIG_SMP
+ thread->vfpstate.hard.cpu = NR_CPUS;
+#endif
+}
+
+/*
+ * 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);
+#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;
+
+ pr_err("VFP: Error: %s\n", reason);
+ pr_err("VFP: EXC 0x%08x SCR 0x%08x INST 0x%08x\n",
+ fmrx(FPEXC), fmrx(FPSCR), inst);
+ for (i = 0; i < 32; i += 2)
+ pr_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)) != (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_CPU_PM
+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) {
+ pr_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]) {
+#ifndef CONFIG_SMP
+ fmxr(FPEXC, fpexc | FPEXC_EN);
+ vfp_save_state(vfp_current_hw_state[ti->cpu], fpexc);
+ fmxr(FPEXC, fpexc);
+#endif
+ }
+
+ /* clear any information we had about last context state */
+ vfp_current_hw_state[ti->cpu] = NULL;
+
+ 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 int vfp_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd,
+ void *v)
+{
+ switch (cmd) {
+ case CPU_PM_ENTER:
+ vfp_pm_suspend();
+ break;
+ case CPU_PM_ENTER_FAILED:
+ case CPU_PM_EXIT:
+ vfp_pm_resume();
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block vfp_cpu_pm_notifier_block = {
+ .notifier_call = vfp_cpu_pm_notifier,
+};
+
+static void vfp_pm_init(void)
+{
+ cpu_pm_register_notifier(&vfp_cpu_pm_notifier_block);
+}
+
+#else
+static inline void vfp_pm_init(void) { }
+#endif /* CONFIG_CPU_PM */
+
+/*
+ * Ensure that the VFP state stored in 'thread->vfpstate' is up to date
+ * with the hardware state.
+ */
+void vfp_sync_hwstate(struct thread_info *thread)
+{
+ unsigned int cpu = get_cpu();
+
+ if (vfp_state_in_hw(cpu, thread)) {
+ 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();
+}
+
+/* Ensure that the thread reloads the hardware VFP state on the next use. */
+void vfp_flush_hwstate(struct thread_info *thread)
+{
+ unsigned int cpu = get_cpu();
+
+ vfp_force_reload(cpu, thread);
+
+ put_cpu();
+}
+
+/*
+ * Save the current VFP state into the provided structures and prepare
+ * for entry into a new function (signal handler).
+ */
+int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp,
+ struct user_vfp_exc __user *ufp_exc)
+{
+ struct thread_info *thread = current_thread_info();
+ struct vfp_hard_struct *hwstate = &thread->vfpstate.hard;
+ int err = 0;
+
+ /* Ensure that the saved hwstate is up-to-date. */
+ vfp_sync_hwstate(thread);
+
+ /*
+ * Copy the floating point registers. There can be unused
+ * registers see asm/hwcap.h for details.
+ */
+ err |= __copy_to_user(&ufp->fpregs, &hwstate->fpregs,
+ sizeof(hwstate->fpregs));
+ /*
+ * Copy the status and control register.
+ */
+ __put_user_error(hwstate->fpscr, &ufp->fpscr, err);
+
+ /*
+ * Copy the exception registers.
+ */
+ __put_user_error(hwstate->fpexc, &ufp_exc->fpexc, err);
+ __put_user_error(hwstate->fpinst, &ufp_exc->fpinst, err);
+ __put_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err);
+
+ if (err)
+ return -EFAULT;
+
+ /* Ensure that VFP is disabled. */
+ vfp_flush_hwstate(thread);
+
+ /*
+ * As per the PCS, clear the length and stride bits for function
+ * entry.
+ */
+ hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK);
+ return 0;
+}
+
+/* Sanitise and restore the current VFP state from the provided structures. */
+int vfp_restore_user_hwstate(struct user_vfp __user *ufp,
+ struct user_vfp_exc __user *ufp_exc)
+{
+ struct thread_info *thread = current_thread_info();
+ struct vfp_hard_struct *hwstate = &thread->vfpstate.hard;
+ unsigned long fpexc;
+ int err = 0;
+
+ /* Disable VFP to avoid corrupting the new thread state. */
+ vfp_flush_hwstate(thread);
+
+ /*
+ * Copy the floating point registers. There can be unused
+ * registers see asm/hwcap.h for details.
+ */
+ err |= __copy_from_user(&hwstate->fpregs, &ufp->fpregs,
+ sizeof(hwstate->fpregs));
+ /*
+ * Copy the status and control register.
+ */
+ __get_user_error(hwstate->fpscr, &ufp->fpscr, err);
+
+ /*
+ * Sanitise and restore the exception registers.
+ */
+ __get_user_error(fpexc, &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);
+ hwstate->fpexc = fpexc;
+
+ __get_user_error(hwstate->fpinst, &ufp_exc->fpinst, err);
+ __get_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err);
+
+ return err ? -EFAULT : 0;
+}
+
+/*
+ * 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)
+ vfp_current_hw_state[(long)hcpu] = NULL;
+ else if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
+ vfp_enable(NULL);
+ return NOTIFY_OK;
+}
+
+void vfp_kmode_exception(void)
+{
+ /*
+ * If we reach this point, a floating point exception has been raised
+ * while running in kernel mode. If the NEON/VFP unit was enabled at the
+ * time, it means a VFP instruction has been issued that requires
+ * software assistance to complete, something which is not currently
+ * supported in kernel mode.
+ * If the NEON/VFP unit was disabled, and the location pointed to below
+ * is properly preceded by a call to kernel_neon_begin(), something has
+ * caused the task to be scheduled out and back in again. In this case,
+ * rebuilding and running with CONFIG_DEBUG_ATOMIC_SLEEP enabled should
+ * be helpful in localizing the problem.
+ */
+ if (fmrx(FPEXC) & FPEXC_EN)
+ pr_crit("BUG: unsupported FP instruction in kernel mode\n");
+ else
+ pr_crit("BUG: FP instruction issued in kernel mode with FP unit disabled\n");
+}
+
+#ifdef CONFIG_KERNEL_MODE_NEON
+
+/*
+ * Kernel-side NEON support functions
+ */
+void kernel_neon_begin(void)
+{
+ struct thread_info *thread = current_thread_info();
+ unsigned int cpu;
+ u32 fpexc;
+
+ /*
+ * Kernel mode NEON is only allowed outside of interrupt context
+ * with preemption disabled. This will make sure that the kernel
+ * mode NEON register contents never need to be preserved.
+ */
+ BUG_ON(in_interrupt());
+ cpu = get_cpu();
+
+ fpexc = fmrx(FPEXC) | FPEXC_EN;
+ fmxr(FPEXC, fpexc);
+
+ /*
+ * Save the userland NEON/VFP state. Under UP,
+ * the owner could be a task other than 'current'
+ */
+ if (vfp_state_in_hw(cpu, thread))
+ vfp_save_state(&thread->vfpstate, fpexc);
+#ifndef CONFIG_SMP
+ else if (vfp_current_hw_state[cpu] != NULL)
+ vfp_save_state(vfp_current_hw_state[cpu], fpexc);
+#endif
+ vfp_current_hw_state[cpu] = NULL;
+}
+EXPORT_SYMBOL(kernel_neon_begin);
+
+void kernel_neon_end(void)
+{
+ /* Disable the NEON/VFP unit. */
+ fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
+ put_cpu();
+}
+EXPORT_SYMBOL(kernel_neon_end);
+
+#endif /* CONFIG_KERNEL_MODE_NEON */
+
+/*
+ * 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;
+
+ pr_info("VFP support v0.3: ");
+ if (VFP_arch) {
+ pr_cont("not present\n");
+ return 0;
+ /* Extract the architecture on CPUID scheme */
+ } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
+ VFP_arch = vfpsid & FPSID_CPUID_ARCH_MASK;
+ VFP_arch >>= FPSID_ARCH_BIT;
+ /*
+ * 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 (IS_ENABLED(CONFIG_NEON) &&
+ (fmrx(MVFR1) & 0x000fff00) == 0x00011100)
+ elf_hwcap |= HWCAP_NEON;
+
+ if (IS_ENABLED(CONFIG_VFPv3)) {
+ u32 mvfr0 = fmrx(MVFR0);
+ if (((mvfr0 & MVFR0_DP_MASK) >> MVFR0_DP_BIT) == 0x2 ||
+ ((mvfr0 & MVFR0_SP_MASK) >> MVFR0_SP_BIT) == 0x2) {
+ elf_hwcap |= HWCAP_VFPv3;
+ /*
+ * Check for VFPv3 D16 and VFPv4 D16. CPUs in
+ * this configuration only have 16 x 64bit
+ * registers.
+ */
+ if ((mvfr0 & MVFR0_A_SIMD_MASK) == 1)
+ /* also v4-D16 */
+ elf_hwcap |= HWCAP_VFPv3D16;
+ else
+ elf_hwcap |= HWCAP_VFPD32;
+ }
+
+ if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000)
+ elf_hwcap |= HWCAP_VFPv4;
+ }
+ /* Extract the architecture version on pre-cpuid scheme */
+ } else {
+ if (vfpsid & FPSID_NODOUBLE) {
+ pr_cont("no double precision support\n");
+ return 0;
+ }
+
+ VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT;
+ }
+
+ hotcpu_notifier(vfp_hotplug, 0);
+
+ 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;
+
+ pr_cont("implementor %02x architecture %d part %02x variant %x rev %x\n",
+ (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT,
+ VFP_arch,
+ (vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT,
+ (vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT,
+ (vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT);
+
+ return 0;
+}
+
+core_initcall(vfp_init);
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c
new file mode 100644
index 000000000..f0465ba0f
--- /dev/null
+++ b/arch/arm/vfp/vfpsingle.c
@@ -0,0 +1,1246 @@
+/*
+ * 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) {
+ pr_warn("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 (vsn.exponent == 0 && vsn.significand)
+ vfp_single_normalise_denormal(&vsn);
+ 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;
+}
diff --git a/arch/arm/xen/Makefile b/arch/arm/xen/Makefile
new file mode 100644
index 000000000..129695234
--- /dev/null
+++ b/arch/arm/xen/Makefile
@@ -0,0 +1 @@
+obj-y := enlighten.o hypercall.o grant-table.o p2m.o mm.o
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
new file mode 100644
index 000000000..7d0f07020
--- /dev/null
+++ b/arch/arm/xen/enlighten.c
@@ -0,0 +1,290 @@
+#include <xen/xen.h>
+#include <xen/events.h>
+#include <xen/grant_table.h>
+#include <xen/hvm.h>
+#include <xen/interface/vcpu.h>
+#include <xen/interface/xen.h>
+#include <xen/interface/memory.h>
+#include <xen/interface/hvm/params.h>
+#include <xen/features.h>
+#include <xen/platform_pci.h>
+#include <xen/xenbus.h>
+#include <xen/page.h>
+#include <xen/interface/sched.h>
+#include <xen/xen-ops.h>
+#include <asm/xen/hypervisor.h>
+#include <asm/xen/hypercall.h>
+#include <asm/system_misc.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/cpuidle.h>
+#include <linux/cpufreq.h>
+#include <linux/cpu.h>
+
+#include <linux/mm.h>
+
+struct start_info _xen_start_info;
+struct start_info *xen_start_info = &_xen_start_info;
+EXPORT_SYMBOL(xen_start_info);
+
+enum xen_domain_type xen_domain_type = XEN_NATIVE;
+EXPORT_SYMBOL(xen_domain_type);
+
+struct shared_info xen_dummy_shared_info;
+struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info;
+
+DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
+static struct vcpu_info __percpu *xen_vcpu_info;
+
+/* These are unused until we support booting "pre-ballooned" */
+unsigned long xen_released_pages;
+struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;
+
+/* TODO: to be removed */
+__read_mostly int xen_have_vector_callback;
+EXPORT_SYMBOL_GPL(xen_have_vector_callback);
+
+int xen_platform_pci_unplug = XEN_UNPLUG_ALL;
+EXPORT_SYMBOL_GPL(xen_platform_pci_unplug);
+
+static __read_mostly int xen_events_irq = -1;
+
+int xen_remap_domain_mfn_array(struct vm_area_struct *vma,
+ unsigned long addr,
+ xen_pfn_t *mfn, int nr,
+ int *err_ptr, pgprot_t prot,
+ unsigned domid,
+ struct page **pages)
+{
+ return xen_xlate_remap_gfn_array(vma, addr, mfn, nr, err_ptr,
+ prot, domid, pages);
+}
+EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_array);
+
+/* Not used by XENFEAT_auto_translated guests. */
+int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
+ unsigned long addr,
+ xen_pfn_t mfn, int nr,
+ pgprot_t prot, unsigned domid,
+ struct page **pages)
+{
+ return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
+
+int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
+ int nr, struct page **pages)
+{
+ return xen_xlate_unmap_gfn_range(vma, nr, pages);
+}
+EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range);
+
+static void xen_percpu_init(void)
+{
+ struct vcpu_register_vcpu_info info;
+ struct vcpu_info *vcpup;
+ int err;
+ int cpu = get_cpu();
+
+ pr_info("Xen: initializing cpu%d\n", cpu);
+ vcpup = per_cpu_ptr(xen_vcpu_info, cpu);
+
+ info.mfn = __pa(vcpup) >> PAGE_SHIFT;
+ info.offset = offset_in_page(vcpup);
+
+ err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info);
+ BUG_ON(err);
+ per_cpu(xen_vcpu, cpu) = vcpup;
+
+ enable_percpu_irq(xen_events_irq, 0);
+ put_cpu();
+}
+
+static void xen_restart(enum reboot_mode reboot_mode, const char *cmd)
+{
+ struct sched_shutdown r = { .reason = SHUTDOWN_reboot };
+ int rc;
+ rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &r);
+ BUG_ON(rc);
+}
+
+static void xen_power_off(void)
+{
+ struct sched_shutdown r = { .reason = SHUTDOWN_poweroff };
+ int rc;
+ rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &r);
+ BUG_ON(rc);
+}
+
+static int xen_cpu_notification(struct notifier_block *self,
+ unsigned long action,
+ void *hcpu)
+{
+ switch (action) {
+ case CPU_STARTING:
+ xen_percpu_init();
+ break;
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block xen_cpu_notifier = {
+ .notifier_call = xen_cpu_notification,
+};
+
+static irqreturn_t xen_arm_callback(int irq, void *arg)
+{
+ xen_hvm_evtchn_do_upcall();
+ return IRQ_HANDLED;
+}
+
+/*
+ * see Documentation/devicetree/bindings/arm/xen.txt for the
+ * documentation of the Xen Device Tree format.
+ */
+#define GRANT_TABLE_PHYSADDR 0
+static int __init xen_guest_init(void)
+{
+ struct xen_add_to_physmap xatp;
+ static struct shared_info *shared_info_page = 0;
+ struct device_node *node;
+ int len;
+ const char *s = NULL;
+ const char *version = NULL;
+ const char *xen_prefix = "xen,xen-";
+ struct resource res;
+ phys_addr_t grant_frames;
+
+ node = of_find_compatible_node(NULL, NULL, "xen,xen");
+ if (!node) {
+ pr_debug("No Xen support\n");
+ return 0;
+ }
+ s = of_get_property(node, "compatible", &len);
+ if (strlen(xen_prefix) + 3 < len &&
+ !strncmp(xen_prefix, s, strlen(xen_prefix)))
+ version = s + strlen(xen_prefix);
+ if (version == NULL) {
+ pr_debug("Xen version not found\n");
+ return 0;
+ }
+ if (of_address_to_resource(node, GRANT_TABLE_PHYSADDR, &res))
+ return 0;
+ grant_frames = res.start;
+ xen_events_irq = irq_of_parse_and_map(node, 0);
+ pr_info("Xen %s support found, events_irq=%d gnttab_frame=%pa\n",
+ version, xen_events_irq, &grant_frames);
+
+ if (xen_events_irq < 0)
+ return -ENODEV;
+
+ xen_domain_type = XEN_HVM_DOMAIN;
+
+ xen_setup_features();
+
+ if (xen_feature(XENFEAT_dom0))
+ xen_start_info->flags |= SIF_INITDOMAIN|SIF_PRIVILEGED;
+ else
+ xen_start_info->flags &= ~(SIF_INITDOMAIN|SIF_PRIVILEGED);
+
+ if (!shared_info_page)
+ shared_info_page = (struct shared_info *)
+ get_zeroed_page(GFP_KERNEL);
+ if (!shared_info_page) {
+ pr_err("not enough memory\n");
+ return -ENOMEM;
+ }
+ xatp.domid = DOMID_SELF;
+ xatp.idx = 0;
+ xatp.space = XENMAPSPACE_shared_info;
+ xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT;
+ if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
+ BUG();
+
+ HYPERVISOR_shared_info = (struct shared_info *)shared_info_page;
+
+ /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info
+ * page, we use it in the event channel upcall and in some pvclock
+ * related functions.
+ * The shared info contains exactly 1 CPU (the boot CPU). The guest
+ * is required to use VCPUOP_register_vcpu_info to place vcpu info
+ * for secondary CPUs as they are brought up.
+ * For uniformity we use VCPUOP_register_vcpu_info even on cpu0.
+ */
+ xen_vcpu_info = __alloc_percpu(sizeof(struct vcpu_info),
+ sizeof(struct vcpu_info));
+ if (xen_vcpu_info == NULL)
+ return -ENOMEM;
+
+ if (gnttab_setup_auto_xlat_frames(grant_frames)) {
+ free_percpu(xen_vcpu_info);
+ return -ENOMEM;
+ }
+ gnttab_init();
+ if (!xen_initial_domain())
+ xenbus_probe(NULL);
+
+ /*
+ * Making sure board specific code will not set up ops for
+ * cpu idle and cpu freq.
+ */
+ disable_cpuidle();
+ disable_cpufreq();
+
+ xen_init_IRQ();
+
+ if (request_percpu_irq(xen_events_irq, xen_arm_callback,
+ "events", &xen_vcpu)) {
+ pr_err("Error request IRQ %d\n", xen_events_irq);
+ return -EINVAL;
+ }
+
+ xen_percpu_init();
+
+ register_cpu_notifier(&xen_cpu_notifier);
+
+ return 0;
+}
+early_initcall(xen_guest_init);
+
+static int __init xen_pm_init(void)
+{
+ if (!xen_domain())
+ return -ENODEV;
+
+ pm_power_off = xen_power_off;
+ arm_pm_restart = xen_restart;
+
+ return 0;
+}
+late_initcall(xen_pm_init);
+
+
+/* empty stubs */
+void xen_arch_pre_suspend(void) { }
+void xen_arch_post_suspend(int suspend_cancelled) { }
+void xen_timer_resume(void) { }
+void xen_arch_resume(void) { }
+void xen_arch_suspend(void) { }
+
+
+/* In the hypervisor.S file. */
+EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_xen_version);
+EXPORT_SYMBOL_GPL(HYPERVISOR_console_io);
+EXPORT_SYMBOL_GPL(HYPERVISOR_sched_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_hvm_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_vcpu_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_tmem_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_multicall);
+EXPORT_SYMBOL_GPL(privcmd_call);
diff --git a/arch/arm/xen/grant-table.c b/arch/arm/xen/grant-table.c
new file mode 100644
index 000000000..e43791829
--- /dev/null
+++ b/arch/arm/xen/grant-table.c
@@ -0,0 +1,51 @@
+/******************************************************************************
+ * grant_table.c
+ * ARM specific part
+ *
+ * Granting foreign access to our memory reservation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <xen/interface/xen.h>
+#include <xen/page.h>
+#include <xen/grant_table.h>
+
+int arch_gnttab_map_shared(xen_pfn_t *frames, unsigned long nr_gframes,
+ unsigned long max_nr_gframes,
+ void **__shared)
+{
+ return -ENOSYS;
+}
+
+void arch_gnttab_unmap(void *shared, unsigned long nr_gframes)
+{
+ return;
+}
+
+int arch_gnttab_init(unsigned long nr_shared)
+{
+ return 0;
+}
diff --git a/arch/arm/xen/hypercall.S b/arch/arm/xen/hypercall.S
new file mode 100644
index 000000000..f00e08075
--- /dev/null
+++ b/arch/arm/xen/hypercall.S
@@ -0,0 +1,105 @@
+/******************************************************************************
+ * hypercall.S
+ *
+ * Xen hypercall wrappers
+ *
+ * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*
+ * The Xen hypercall calling convention is very similar to the ARM
+ * procedure calling convention: the first paramter is passed in r0, the
+ * second in r1, the third in r2 and the fourth in r3. Considering that
+ * Xen hypercalls have 5 arguments at most, the fifth paramter is passed
+ * in r4, differently from the procedure calling convention of using the
+ * stack for that case.
+ *
+ * The hypercall number is passed in r12.
+ *
+ * The return value is in r0.
+ *
+ * The hvc ISS is required to be 0xEA1, that is the Xen specific ARM
+ * hypercall tag.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/opcodes-virt.h>
+#include <xen/interface/xen.h>
+
+
+#define XEN_IMM 0xEA1
+
+#define HYPERCALL_SIMPLE(hypercall) \
+ENTRY(HYPERVISOR_##hypercall) \
+ mov r12, #__HYPERVISOR_##hypercall; \
+ __HVC(XEN_IMM); \
+ ret lr; \
+ENDPROC(HYPERVISOR_##hypercall)
+
+#define HYPERCALL0 HYPERCALL_SIMPLE
+#define HYPERCALL1 HYPERCALL_SIMPLE
+#define HYPERCALL2 HYPERCALL_SIMPLE
+#define HYPERCALL3 HYPERCALL_SIMPLE
+#define HYPERCALL4 HYPERCALL_SIMPLE
+
+#define HYPERCALL5(hypercall) \
+ENTRY(HYPERVISOR_##hypercall) \
+ stmdb sp!, {r4} \
+ ldr r4, [sp, #4] \
+ mov r12, #__HYPERVISOR_##hypercall; \
+ __HVC(XEN_IMM); \
+ ldm sp!, {r4} \
+ ret lr \
+ENDPROC(HYPERVISOR_##hypercall)
+
+ .text
+
+HYPERCALL2(xen_version);
+HYPERCALL3(console_io);
+HYPERCALL3(grant_table_op);
+HYPERCALL2(sched_op);
+HYPERCALL2(event_channel_op);
+HYPERCALL2(hvm_op);
+HYPERCALL2(memory_op);
+HYPERCALL2(physdev_op);
+HYPERCALL3(vcpu_op);
+HYPERCALL1(tmem_op);
+HYPERCALL2(multicall);
+
+ENTRY(privcmd_call)
+ stmdb sp!, {r4}
+ mov r12, r0
+ mov r0, r1
+ mov r1, r2
+ mov r2, r3
+ ldr r3, [sp, #8]
+ ldr r4, [sp, #4]
+ __HVC(XEN_IMM)
+ ldm sp!, {r4}
+ ret lr
+ENDPROC(privcmd_call);
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
new file mode 100644
index 000000000..498325074
--- /dev/null
+++ b/arch/arm/xen/mm.c
@@ -0,0 +1,201 @@
+#include <linux/cpu.h>
+#include <linux/dma-mapping.h>
+#include <linux/bootmem.h>
+#include <linux/gfp.h>
+#include <linux/highmem.h>
+#include <linux/export.h>
+#include <linux/memblock.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include <linux/vmalloc.h>
+#include <linux/swiotlb.h>
+
+#include <xen/xen.h>
+#include <xen/interface/grant_table.h>
+#include <xen/interface/memory.h>
+#include <xen/swiotlb-xen.h>
+
+#include <asm/cacheflush.h>
+#include <asm/xen/page.h>
+#include <asm/xen/hypercall.h>
+#include <asm/xen/interface.h>
+
+unsigned long xen_get_swiotlb_free_pages(unsigned int order)
+{
+ struct memblock_region *reg;
+ gfp_t flags = __GFP_NOWARN;
+
+ for_each_memblock(memory, reg) {
+ if (reg->base < (phys_addr_t)0xffffffff) {
+ flags |= __GFP_DMA;
+ break;
+ }
+ }
+ return __get_free_pages(flags, order);
+}
+
+enum dma_cache_op {
+ DMA_UNMAP,
+ DMA_MAP,
+};
+static bool hypercall_cflush = false;
+
+/* functions called by SWIOTLB */
+
+static void dma_cache_maint(dma_addr_t handle, unsigned long offset,
+ size_t size, enum dma_data_direction dir, enum dma_cache_op op)
+{
+ struct gnttab_cache_flush cflush;
+ unsigned long pfn;
+ size_t left = size;
+
+ pfn = (handle >> PAGE_SHIFT) + offset / PAGE_SIZE;
+ offset %= PAGE_SIZE;
+
+ do {
+ size_t len = left;
+
+ /* buffers in highmem or foreign pages cannot cross page
+ * boundaries */
+ if (len + offset > PAGE_SIZE)
+ len = PAGE_SIZE - offset;
+
+ cflush.op = 0;
+ cflush.a.dev_bus_addr = pfn << PAGE_SHIFT;
+ cflush.offset = offset;
+ cflush.length = len;
+
+ if (op == DMA_UNMAP && dir != DMA_TO_DEVICE)
+ cflush.op = GNTTAB_CACHE_INVAL;
+ if (op == DMA_MAP) {
+ if (dir == DMA_FROM_DEVICE)
+ cflush.op = GNTTAB_CACHE_INVAL;
+ else
+ cflush.op = GNTTAB_CACHE_CLEAN;
+ }
+ if (cflush.op)
+ HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, &cflush, 1);
+
+ offset = 0;
+ pfn++;
+ left -= len;
+ } while (left);
+}
+
+static void __xen_dma_page_dev_to_cpu(struct device *hwdev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+ dma_cache_maint(handle & PAGE_MASK, handle & ~PAGE_MASK, size, dir, DMA_UNMAP);
+}
+
+static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+ dma_cache_maint(handle & PAGE_MASK, handle & ~PAGE_MASK, size, dir, DMA_MAP);
+}
+
+void __xen_dma_map_page(struct device *hwdev, struct page *page,
+ dma_addr_t dev_addr, unsigned long offset, size_t size,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ if (is_device_dma_coherent(hwdev))
+ return;
+ if (dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ return;
+
+ __xen_dma_page_cpu_to_dev(hwdev, dev_addr, size, dir);
+}
+
+void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+
+{
+ if (is_device_dma_coherent(hwdev))
+ return;
+ if (dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ return;
+
+ __xen_dma_page_dev_to_cpu(hwdev, handle, size, dir);
+}
+
+void __xen_dma_sync_single_for_cpu(struct device *hwdev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ if (is_device_dma_coherent(hwdev))
+ return;
+ __xen_dma_page_dev_to_cpu(hwdev, handle, size, dir);
+}
+
+void __xen_dma_sync_single_for_device(struct device *hwdev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ if (is_device_dma_coherent(hwdev))
+ return;
+ __xen_dma_page_cpu_to_dev(hwdev, handle, size, dir);
+}
+
+bool xen_arch_need_swiotlb(struct device *dev,
+ unsigned long pfn,
+ unsigned long mfn)
+{
+ return (!hypercall_cflush && (pfn != mfn) && !is_device_dma_coherent(dev));
+}
+
+int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,
+ unsigned int address_bits,
+ dma_addr_t *dma_handle)
+{
+ if (!xen_initial_domain())
+ return -EINVAL;
+
+ /* we assume that dom0 is mapped 1:1 for now */
+ *dma_handle = pstart;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(xen_create_contiguous_region);
+
+void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order)
+{
+ return;
+}
+EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);
+
+struct dma_map_ops *xen_dma_ops;
+EXPORT_SYMBOL(xen_dma_ops);
+
+static struct dma_map_ops xen_swiotlb_dma_ops = {
+ .mapping_error = xen_swiotlb_dma_mapping_error,
+ .alloc = xen_swiotlb_alloc_coherent,
+ .free = xen_swiotlb_free_coherent,
+ .sync_single_for_cpu = xen_swiotlb_sync_single_for_cpu,
+ .sync_single_for_device = xen_swiotlb_sync_single_for_device,
+ .sync_sg_for_cpu = xen_swiotlb_sync_sg_for_cpu,
+ .sync_sg_for_device = xen_swiotlb_sync_sg_for_device,
+ .map_sg = xen_swiotlb_map_sg_attrs,
+ .unmap_sg = xen_swiotlb_unmap_sg_attrs,
+ .map_page = xen_swiotlb_map_page,
+ .unmap_page = xen_swiotlb_unmap_page,
+ .dma_supported = xen_swiotlb_dma_supported,
+ .set_dma_mask = xen_swiotlb_set_dma_mask,
+};
+
+int __init xen_mm_init(void)
+{
+ struct gnttab_cache_flush cflush;
+ if (!xen_initial_domain())
+ return 0;
+ xen_swiotlb_init(1, false);
+ xen_dma_ops = &xen_swiotlb_dma_ops;
+
+ cflush.op = 0;
+ cflush.a.dev_bus_addr = 0;
+ cflush.offset = 0;
+ cflush.length = 0;
+ if (HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, &cflush, 1) != -ENOSYS)
+ hypercall_cflush = true;
+ return 0;
+}
+arch_initcall(xen_mm_init);
diff --git a/arch/arm/xen/p2m.c b/arch/arm/xen/p2m.c
new file mode 100644
index 000000000..cb7a14c5c
--- /dev/null
+++ b/arch/arm/xen/p2m.c
@@ -0,0 +1,177 @@
+#include <linux/bootmem.h>
+#include <linux/gfp.h>
+#include <linux/export.h>
+#include <linux/rwlock.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include <linux/vmalloc.h>
+#include <linux/swiotlb.h>
+
+#include <xen/xen.h>
+#include <xen/interface/memory.h>
+#include <xen/swiotlb-xen.h>
+
+#include <asm/cacheflush.h>
+#include <asm/xen/page.h>
+#include <asm/xen/hypercall.h>
+#include <asm/xen/interface.h>
+
+struct xen_p2m_entry {
+ unsigned long pfn;
+ unsigned long mfn;
+ unsigned long nr_pages;
+ struct rb_node rbnode_phys;
+};
+
+static rwlock_t p2m_lock;
+struct rb_root phys_to_mach = RB_ROOT;
+EXPORT_SYMBOL_GPL(phys_to_mach);
+
+static int xen_add_phys_to_mach_entry(struct xen_p2m_entry *new)
+{
+ struct rb_node **link = &phys_to_mach.rb_node;
+ struct rb_node *parent = NULL;
+ struct xen_p2m_entry *entry;
+ int rc = 0;
+
+ while (*link) {
+ parent = *link;
+ entry = rb_entry(parent, struct xen_p2m_entry, rbnode_phys);
+
+ if (new->pfn == entry->pfn)
+ goto err_out;
+
+ if (new->pfn < entry->pfn)
+ link = &(*link)->rb_left;
+ else
+ link = &(*link)->rb_right;
+ }
+ rb_link_node(&new->rbnode_phys, parent, link);
+ rb_insert_color(&new->rbnode_phys, &phys_to_mach);
+ goto out;
+
+err_out:
+ rc = -EINVAL;
+ pr_warn("%s: cannot add pfn=%pa -> mfn=%pa: pfn=%pa -> mfn=%pa already exists\n",
+ __func__, &new->pfn, &new->mfn, &entry->pfn, &entry->mfn);
+out:
+ return rc;
+}
+
+unsigned long __pfn_to_mfn(unsigned long pfn)
+{
+ struct rb_node *n = phys_to_mach.rb_node;
+ struct xen_p2m_entry *entry;
+ unsigned long irqflags;
+
+ read_lock_irqsave(&p2m_lock, irqflags);
+ while (n) {
+ entry = rb_entry(n, struct xen_p2m_entry, rbnode_phys);
+ if (entry->pfn <= pfn &&
+ entry->pfn + entry->nr_pages > pfn) {
+ read_unlock_irqrestore(&p2m_lock, irqflags);
+ return entry->mfn + (pfn - entry->pfn);
+ }
+ if (pfn < entry->pfn)
+ n = n->rb_left;
+ else
+ n = n->rb_right;
+ }
+ read_unlock_irqrestore(&p2m_lock, irqflags);
+
+ return INVALID_P2M_ENTRY;
+}
+EXPORT_SYMBOL_GPL(__pfn_to_mfn);
+
+int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
+ struct gnttab_map_grant_ref *kmap_ops,
+ struct page **pages, unsigned int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ if (map_ops[i].status)
+ continue;
+ set_phys_to_machine(map_ops[i].host_addr >> PAGE_SHIFT,
+ map_ops[i].dev_bus_addr >> PAGE_SHIFT);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(set_foreign_p2m_mapping);
+
+int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
+ struct gnttab_unmap_grant_ref *kunmap_ops,
+ struct page **pages, unsigned int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ set_phys_to_machine(unmap_ops[i].host_addr >> PAGE_SHIFT,
+ INVALID_P2M_ENTRY);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(clear_foreign_p2m_mapping);
+
+bool __set_phys_to_machine_multi(unsigned long pfn,
+ unsigned long mfn, unsigned long nr_pages)
+{
+ int rc;
+ unsigned long irqflags;
+ struct xen_p2m_entry *p2m_entry;
+ struct rb_node *n = phys_to_mach.rb_node;
+
+ if (mfn == INVALID_P2M_ENTRY) {
+ write_lock_irqsave(&p2m_lock, irqflags);
+ while (n) {
+ p2m_entry = rb_entry(n, struct xen_p2m_entry, rbnode_phys);
+ if (p2m_entry->pfn <= pfn &&
+ p2m_entry->pfn + p2m_entry->nr_pages > pfn) {
+ rb_erase(&p2m_entry->rbnode_phys, &phys_to_mach);
+ write_unlock_irqrestore(&p2m_lock, irqflags);
+ kfree(p2m_entry);
+ return true;
+ }
+ if (pfn < p2m_entry->pfn)
+ n = n->rb_left;
+ else
+ n = n->rb_right;
+ }
+ write_unlock_irqrestore(&p2m_lock, irqflags);
+ return true;
+ }
+
+ p2m_entry = kzalloc(sizeof(struct xen_p2m_entry), GFP_NOWAIT);
+ if (!p2m_entry) {
+ pr_warn("cannot allocate xen_p2m_entry\n");
+ return false;
+ }
+ p2m_entry->pfn = pfn;
+ p2m_entry->nr_pages = nr_pages;
+ p2m_entry->mfn = mfn;
+
+ write_lock_irqsave(&p2m_lock, irqflags);
+ if ((rc = xen_add_phys_to_mach_entry(p2m_entry)) < 0) {
+ write_unlock_irqrestore(&p2m_lock, irqflags);
+ return false;
+ }
+ write_unlock_irqrestore(&p2m_lock, irqflags);
+ return true;
+}
+EXPORT_SYMBOL_GPL(__set_phys_to_machine_multi);
+
+bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+{
+ return __set_phys_to_machine_multi(pfn, mfn, 1);
+}
+EXPORT_SYMBOL_GPL(__set_phys_to_machine);
+
+static int p2m_init(void)
+{
+ rwlock_init(&p2m_lock);
+ return 0;
+}
+arch_initcall(p2m_init);